aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Biswakalyan Bhuyan 2022-05-28 21:48:23 +0530
committerGravatar Biswakalyan Bhuyan 2022-05-28 21:48:23 +0530
commit76bea95915ee5973a6ccc8a460cb8e248ad7aae6 (patch)
tree67982e32284fe01e5bb74dfa3b4256cd4e0dffd5
downloademacs.d-76bea95915ee5973a6ccc8a460cb8e248ad7aae6.tar.gz
emacs.d-76bea95915ee5973a6ccc8a460cb8e248ad7aae6.tar.bz2
emacs.d-76bea95915ee5973a6ccc8a460cb8e248ad7aae6.zip
my emacs config file
-rw-r--r--README.md1
-rw-r--r--auto-save-list/.saves-1346-satan~0
-rw-r--r--auto-save-list/.saves-18617-satan~0
-rw-r--r--auto-save-list/.saves-23720-satan~0
-rw-r--r--avatar.pngbin0 -> 33674 bytes
-rw-r--r--elpa/archives/gnu/archive-contents3487
-rw-r--r--elpa/archives/gnu/archive-contents.signed1
-rw-r--r--elpa/archives/melpa/archive-contents5177
-rw-r--r--elpa/archives/nongnu/archive-contents1643
-rw-r--r--elpa/archives/nongnu/archive-contents.signed1
-rw-r--r--elpa/bind-key-20210210.1609/bind-key-autoloads.el84
-rw-r--r--elpa/bind-key-20210210.1609/bind-key-pkg.el2
-rw-r--r--elpa/bind-key-20210210.1609/bind-key.el492
-rw-r--r--elpa/bind-key-20210210.1609/bind-key.elcbin0 -> 12291 bytes
-rw-r--r--elpa/company-20220425.1145/company-abbrev.el52
-rw-r--r--elpa/company-20220425.1145/company-abbrev.elcbin0 -> 965 bytes
-rw-r--r--elpa/company-20220425.1145/company-autoloads.el406
-rw-r--r--elpa/company-20220425.1145/company-bbdb.el63
-rw-r--r--elpa/company-20220425.1145/company-bbdb.elcbin0 -> 1473 bytes
-rw-r--r--elpa/company-20220425.1145/company-capf.el257
-rw-r--r--elpa/company-20220425.1145/company-capf.elcbin0 -> 5730 bytes
-rw-r--r--elpa/company-20220425.1145/company-clang.el420
-rw-r--r--elpa/company-20220425.1145/company-clang.elcbin0 -> 15384 bytes
-rw-r--r--elpa/company-20220425.1145/company-cmake.el207
-rw-r--r--elpa/company-20220425.1145/company-cmake.elcbin0 -> 5799 bytes
-rw-r--r--elpa/company-20220425.1145/company-css.el446
-rw-r--r--elpa/company-20220425.1145/company-css.elcbin0 -> 16616 bytes
-rw-r--r--elpa/company-20220425.1145/company-dabbrev-code.el105
-rw-r--r--elpa/company-20220425.1145/company-dabbrev-code.elcbin0 -> 3432 bytes
-rw-r--r--elpa/company-20220425.1145/company-dabbrev.el207
-rw-r--r--elpa/company-20220425.1145/company-dabbrev.elcbin0 -> 6758 bytes
-rw-r--r--elpa/company-20220425.1145/company-elisp.el226
-rw-r--r--elpa/company-20220425.1145/company-elisp.elcbin0 -> 6295 bytes
-rw-r--r--elpa/company-20220425.1145/company-etags.el108
-rw-r--r--elpa/company-20220425.1145/company-etags.elcbin0 -> 2824 bytes
-rw-r--r--elpa/company-20220425.1145/company-files.el161
-rw-r--r--elpa/company-20220425.1145/company-files.elcbin0 -> 4590 bytes
-rw-r--r--elpa/company-20220425.1145/company-gtags.el161
-rw-r--r--elpa/company-20220425.1145/company-gtags.elcbin0 -> 4989 bytes
-rw-r--r--elpa/company-20220425.1145/company-ispell.el83
-rw-r--r--elpa/company-20220425.1145/company-ispell.elcbin0 -> 1711 bytes
-rw-r--r--elpa/company-20220425.1145/company-keywords.el354
-rw-r--r--elpa/company-20220425.1145/company-keywords.elcbin0 -> 19675 bytes
-rw-r--r--elpa/company-20220425.1145/company-nxml.el143
-rw-r--r--elpa/company-20220425.1145/company-nxml.elcbin0 -> 4150 bytes
-rw-r--r--elpa/company-20220425.1145/company-oddmuse.el57
-rw-r--r--elpa/company-20220425.1145/company-oddmuse.elcbin0 -> 1245 bytes
-rw-r--r--elpa/company-20220425.1145/company-pkg.el12
-rw-r--r--elpa/company-20220425.1145/company-semantic.el168
-rw-r--r--elpa/company-20220425.1145/company-semantic.elcbin0 -> 4944 bytes
-rw-r--r--elpa/company-20220425.1145/company-template.el272
-rw-r--r--elpa/company-20220425.1145/company-template.elcbin0 -> 8111 bytes
-rw-r--r--elpa/company-20220425.1145/company-tempo.el71
-rw-r--r--elpa/company-20220425.1145/company-tempo.elcbin0 -> 2079 bytes
-rw-r--r--elpa/company-20220425.1145/company-tng.el196
-rw-r--r--elpa/company-20220425.1145/company-tng.elcbin0 -> 5172 bytes
-rw-r--r--elpa/company-20220425.1145/company-yasnippet.el186
-rw-r--r--elpa/company-20220425.1145/company-yasnippet.elcbin0 -> 4058 bytes
-rw-r--r--elpa/company-20220425.1145/company.el3917
-rw-r--r--elpa/company-20220425.1145/company.elcbin0 -> 131325 bytes
-rw-r--r--elpa/company-20220425.1145/company.info1695
-rw-r--r--elpa/company-20220425.1145/dir18
-rw-r--r--elpa/company-20220425.1145/icons/LICENSE395
-rw-r--r--elpa/company-20220425.1145/icons/attribution.md5
-rw-r--r--elpa/company-20220425.1145/icons/vscode-dark/folder.svg3
-rw-r--r--elpa/company-20220425.1145/icons/vscode-dark/references.svg3
-rw-r--r--elpa/company-20220425.1145/icons/vscode-dark/symbol-array.svg3
-rw-r--r--elpa/company-20220425.1145/icons/vscode-dark/symbol-boolean.svg3
-rw-r--r--elpa/company-20220425.1145/icons/vscode-dark/symbol-class.svg3
-rw-r--r--elpa/company-20220425.1145/icons/vscode-dark/symbol-color.svg3
-rw-r--r--elpa/company-20220425.1145/icons/vscode-dark/symbol-constant.svg4
-rw-r--r--elpa/company-20220425.1145/icons/vscode-dark/symbol-enumerator-member.svg3
-rw-r--r--elpa/company-20220425.1145/icons/vscode-dark/symbol-enumerator.svg3
-rw-r--r--elpa/company-20220425.1145/icons/vscode-dark/symbol-event.svg3
-rw-r--r--elpa/company-20220425.1145/icons/vscode-dark/symbol-field.svg3
-rw-r--r--elpa/company-20220425.1145/icons/vscode-dark/symbol-file.svg3
-rw-r--r--elpa/company-20220425.1145/icons/vscode-dark/symbol-interface.svg3
-rw-r--r--elpa/company-20220425.1145/icons/vscode-dark/symbol-key.svg3
-rw-r--r--elpa/company-20220425.1145/icons/vscode-dark/symbol-keyword.svg3
-rw-r--r--elpa/company-20220425.1145/icons/vscode-dark/symbol-method.svg3
-rw-r--r--elpa/company-20220425.1145/icons/vscode-dark/symbol-misc.svg3
-rw-r--r--elpa/company-20220425.1145/icons/vscode-dark/symbol-namespace.svg3
-rw-r--r--elpa/company-20220425.1145/icons/vscode-dark/symbol-numeric.svg3
-rw-r--r--elpa/company-20220425.1145/icons/vscode-dark/symbol-operator.svg3
-rw-r--r--elpa/company-20220425.1145/icons/vscode-dark/symbol-parameter.svg3
-rw-r--r--elpa/company-20220425.1145/icons/vscode-dark/symbol-property.svg3
-rw-r--r--elpa/company-20220425.1145/icons/vscode-dark/symbol-ruler.svg3
-rw-r--r--elpa/company-20220425.1145/icons/vscode-dark/symbol-snippet.svg3
-rw-r--r--elpa/company-20220425.1145/icons/vscode-dark/symbol-string.svg3
-rw-r--r--elpa/company-20220425.1145/icons/vscode-dark/symbol-structure.svg3
-rw-r--r--elpa/company-20220425.1145/icons/vscode-dark/symbol-variable.svg3
-rw-r--r--elpa/company-20220425.1145/icons/vscode-light/folder.svg3
-rw-r--r--elpa/company-20220425.1145/icons/vscode-light/references.svg10
-rw-r--r--elpa/company-20220425.1145/icons/vscode-light/symbol-array.svg3
-rw-r--r--elpa/company-20220425.1145/icons/vscode-light/symbol-boolean.svg3
-rw-r--r--elpa/company-20220425.1145/icons/vscode-light/symbol-class.svg3
-rw-r--r--elpa/company-20220425.1145/icons/vscode-light/symbol-color.svg3
-rw-r--r--elpa/company-20220425.1145/icons/vscode-light/symbol-constant.svg4
-rw-r--r--elpa/company-20220425.1145/icons/vscode-light/symbol-enumerator-member.svg3
-rw-r--r--elpa/company-20220425.1145/icons/vscode-light/symbol-enumerator.svg3
-rw-r--r--elpa/company-20220425.1145/icons/vscode-light/symbol-event.svg3
-rw-r--r--elpa/company-20220425.1145/icons/vscode-light/symbol-field.svg3
-rw-r--r--elpa/company-20220425.1145/icons/vscode-light/symbol-file.svg3
-rw-r--r--elpa/company-20220425.1145/icons/vscode-light/symbol-interface.svg3
-rw-r--r--elpa/company-20220425.1145/icons/vscode-light/symbol-key.svg3
-rw-r--r--elpa/company-20220425.1145/icons/vscode-light/symbol-keyword.svg3
-rw-r--r--elpa/company-20220425.1145/icons/vscode-light/symbol-method.svg3
-rw-r--r--elpa/company-20220425.1145/icons/vscode-light/symbol-misc.svg3
-rw-r--r--elpa/company-20220425.1145/icons/vscode-light/symbol-namespace.svg10
-rw-r--r--elpa/company-20220425.1145/icons/vscode-light/symbol-numeric.svg3
-rw-r--r--elpa/company-20220425.1145/icons/vscode-light/symbol-operator.svg3
-rw-r--r--elpa/company-20220425.1145/icons/vscode-light/symbol-parameter.svg3
-rw-r--r--elpa/company-20220425.1145/icons/vscode-light/symbol-property.svg3
-rw-r--r--elpa/company-20220425.1145/icons/vscode-light/symbol-ruler.svg3
-rw-r--r--elpa/company-20220425.1145/icons/vscode-light/symbol-snippet.svg3
-rw-r--r--elpa/company-20220425.1145/icons/vscode-light/symbol-string.svg3
-rw-r--r--elpa/company-20220425.1145/icons/vscode-light/symbol-structure.svg3
-rw-r--r--elpa/company-20220425.1145/icons/vscode-light/symbol-variable.svg3
-rwxr-xr-xelpa/company-20220425.1145/images/small/echo-meta.pngbin0 -> 43396 bytes
-rwxr-xr-xelpa/company-20220425.1145/images/small/echo-qa.pngbin0 -> 18377 bytes
-rwxr-xr-xelpa/company-20220425.1145/images/small/echo-strip-qa.pngbin0 -> 21063 bytes
-rwxr-xr-xelpa/company-20220425.1145/images/small/echo-strip.pngbin0 -> 15339 bytes
-rwxr-xr-xelpa/company-20220425.1145/images/small/echo.pngbin0 -> 16360 bytes
-rwxr-xr-xelpa/company-20220425.1145/images/small/preview-dark.pngbin0 -> 5168 bytes
-rwxr-xr-xelpa/company-20220425.1145/images/small/preview-light.pngbin0 -> 5559 bytes
-rwxr-xr-xelpa/company-20220425.1145/images/small/tooltip-annotations.pngbin0 -> 29532 bytes
-rwxr-xr-xelpa/company-20220425.1145/images/small/tooltip-faces-light.pngbin0 -> 14633 bytes
-rwxr-xr-xelpa/company-20220425.1145/images/small/tooltip-filter.pngbin0 -> 29646 bytes
-rwxr-xr-xelpa/company-20220425.1145/images/small/tooltip-flip.pngbin0 -> 33501 bytes
-rwxr-xr-xelpa/company-20220425.1145/images/small/tooltip-icon-bg.pngbin0 -> 25540 bytes
-rwxr-xr-xelpa/company-20220425.1145/images/small/tooltip-icon-face.pngbin0 -> 28233 bytes
-rwxr-xr-xelpa/company-20220425.1145/images/small/tooltip-icons-dot.pngbin0 -> 45177 bytes
-rwxr-xr-xelpa/company-20220425.1145/images/small/tooltip-icons-text.pngbin0 -> 41525 bytes
-rwxr-xr-xelpa/company-20220425.1145/images/small/tooltip-icons-vscode.pngbin0 -> 47354 bytes
-rwxr-xr-xelpa/company-20220425.1145/images/small/tooltip-limit.pngbin0 -> 21246 bytes
-rwxr-xr-xelpa/company-20220425.1145/images/small/tooltip-margin.pngbin0 -> 29931 bytes
-rw-r--r--elpa/company-20220425.1145/images/small/tooltip-minimum-above.pngbin0 -> 42117 bytes
-rw-r--r--elpa/company-20220425.1145/images/small/tooltip-minimum-below.pngbin0 -> 22238 bytes
-rwxr-xr-xelpa/company-20220425.1145/images/small/tooltip-offset-display.pngbin0 -> 28312 bytes
-rwxr-xr-xelpa/company-20220425.1145/images/small/tooltip-qa-faces-light.pngbin0 -> 27127 bytes
-rwxr-xr-xelpa/company-20220425.1145/images/small/tooltip-quick-access.pngbin0 -> 19467 bytes
-rwxr-xr-xelpa/company-20220425.1145/images/small/tooltip-search.pngbin0 -> 45384 bytes
-rw-r--r--elpa/compat-28.1.1.0.signed1
-rw-r--r--elpa/compat-28.1.1.0/NEWS.org40
-rw-r--r--elpa/compat-28.1.1.0/compat-24.el516
-rw-r--r--elpa/compat-28.1.1.0/compat-24.elcbin0 -> 338 bytes
-rw-r--r--elpa/compat-28.1.1.0/compat-25.el317
-rw-r--r--elpa/compat-28.1.1.0/compat-25.elcbin0 -> 4123 bytes
-rw-r--r--elpa/compat-28.1.1.0/compat-26.el623
-rw-r--r--elpa/compat-28.1.1.0/compat-26.elcbin0 -> 5332 bytes
-rw-r--r--elpa/compat-28.1.1.0/compat-27.el642
-rw-r--r--elpa/compat-28.1.1.0/compat-27.elcbin0 -> 8415 bytes
-rw-r--r--elpa/compat-28.1.1.0/compat-28.el835
-rw-r--r--elpa/compat-28.1.1.0/compat-28.elcbin0 -> 1109 bytes
-rw-r--r--elpa/compat-28.1.1.0/compat-autoloads.el35
-rw-r--r--elpa/compat-28.1.1.0/compat-font-lock.el48
-rw-r--r--elpa/compat-28.1.1.0/compat-font-lock.elcbin0 -> 543 bytes
-rw-r--r--elpa/compat-28.1.1.0/compat-help.el57
-rw-r--r--elpa/compat-28.1.1.0/compat-help.elcbin0 -> 926 bytes
-rw-r--r--elpa/compat-28.1.1.0/compat-macs.el367
-rw-r--r--elpa/compat-28.1.1.0/compat-macs.elcbin0 -> 11907 bytes
-rw-r--r--elpa/compat-28.1.1.0/compat-pkg.el2
-rw-r--r--elpa/compat-28.1.1.0/compat.el99
-rw-r--r--elpa/compat-28.1.1.0/compat.elcbin0 -> 15764 bytes
-rw-r--r--elpa/compat-28.1.1.0/compat.info1110
-rw-r--r--elpa/compat-28.1.1.0/dir18
-rw-r--r--elpa/dash-20220417.2250/dash-autoloads.el87
-rw-r--r--elpa/dash-20220417.2250/dash-pkg.el12
-rw-r--r--elpa/dash-20220417.2250/dash.el3570
-rw-r--r--elpa/dash-20220417.2250/dash.elcbin0 -> 137546 bytes
-rw-r--r--elpa/dash-20220417.2250/dash.info4766
-rw-r--r--elpa/dash-20220417.2250/dir18
-rw-r--r--elpa/dashboard-20220409.620/banners/1.txt8
-rw-r--r--elpa/dashboard-20220409.620/banners/2.txt6
-rw-r--r--elpa/dashboard-20220409.620/banners/3.txt8
-rw-r--r--elpa/dashboard-20220409.620/banners/4.txt17
-rw-r--r--elpa/dashboard-20220409.620/banners/emacs.pngbin0 -> 43759 bytes
-rw-r--r--elpa/dashboard-20220409.620/banners/logo.pngbin0 -> 32305 bytes
-rw-r--r--elpa/dashboard-20220409.620/dashboard-autoloads.el39
-rw-r--r--elpa/dashboard-20220409.620/dashboard-pkg.el12
-rw-r--r--elpa/dashboard-20220409.620/dashboard-widgets.el1267
-rw-r--r--elpa/dashboard-20220409.620/dashboard-widgets.elcbin0 -> 51368 bytes
-rw-r--r--elpa/dashboard-20220409.620/dashboard.el472
-rw-r--r--elpa/dashboard-20220409.620/dashboard.elcbin0 -> 16242 bytes
-rw-r--r--elpa/doom-themes-20220504.1557/doom-1337-theme.el216
-rw-r--r--elpa/doom-themes-20220504.1557/doom-Iosvkem-theme.el196
-rw-r--r--elpa/doom-themes-20220504.1557/doom-acario-dark-theme.el252
-rw-r--r--elpa/doom-themes-20220504.1557/doom-acario-light-theme.el250
-rw-r--r--elpa/doom-themes-20220504.1557/doom-ayu-light-theme.el223
-rw-r--r--elpa/doom-themes-20220504.1557/doom-ayu-mirage-theme.el223
-rw-r--r--elpa/doom-themes-20220504.1557/doom-badger-theme.el224
-rw-r--r--elpa/doom-themes-20220504.1557/doom-challenger-deep-theme.el157
-rw-r--r--elpa/doom-themes-20220504.1557/doom-city-lights-theme.el176
-rw-r--r--elpa/doom-themes-20220504.1557/doom-dark+-theme.el186
-rw-r--r--elpa/doom-themes-20220504.1557/doom-dracula-theme.el251
-rw-r--r--elpa/doom-themes-20220504.1557/doom-earl-grey-theme.el584
-rw-r--r--elpa/doom-themes-20220504.1557/doom-ephemeral-theme.el253
-rw-r--r--elpa/doom-themes-20220504.1557/doom-fairy-floss-theme.el184
-rw-r--r--elpa/doom-themes-20220504.1557/doom-flatwhite-theme.el589
-rw-r--r--elpa/doom-themes-20220504.1557/doom-gruvbox-light-theme.el489
-rw-r--r--elpa/doom-themes-20220504.1557/doom-gruvbox-theme.el285
-rw-r--r--elpa/doom-themes-20220504.1557/doom-henna-theme.el270
-rw-r--r--elpa/doom-themes-20220504.1557/doom-homage-black-theme.el210
-rw-r--r--elpa/doom-themes-20220504.1557/doom-homage-white-theme.el214
-rw-r--r--elpa/doom-themes-20220504.1557/doom-horizon-theme.el213
-rw-r--r--elpa/doom-themes-20220504.1557/doom-ir-black-theme.el151
-rw-r--r--elpa/doom-themes-20220504.1557/doom-laserwave-theme.el163
-rw-r--r--elpa/doom-themes-20220504.1557/doom-manegarm-theme.el211
-rw-r--r--elpa/doom-themes-20220504.1557/doom-material-dark-theme.el178
-rw-r--r--elpa/doom-themes-20220504.1557/doom-material-theme.el141
-rw-r--r--elpa/doom-themes-20220504.1557/doom-meltbus-theme.el351
-rw-r--r--elpa/doom-themes-20220504.1557/doom-miramare-theme.el253
-rw-r--r--elpa/doom-themes-20220504.1557/doom-molokai-theme.el201
-rw-r--r--elpa/doom-themes-20220504.1557/doom-monokai-classic-theme.el179
-rw-r--r--elpa/doom-themes-20220504.1557/doom-monokai-machine-theme.el304
-rw-r--r--elpa/doom-themes-20220504.1557/doom-monokai-octagon-theme.el304
-rw-r--r--elpa/doom-themes-20220504.1557/doom-monokai-pro-theme.el146
-rw-r--r--elpa/doom-themes-20220504.1557/doom-monokai-ristretto-theme.el308
-rw-r--r--elpa/doom-themes-20220504.1557/doom-monokai-spectrum-theme.el305
-rw-r--r--elpa/doom-themes-20220504.1557/doom-moonlight-theme.el259
-rw-r--r--elpa/doom-themes-20220504.1557/doom-nord-light-theme.el181
-rw-r--r--elpa/doom-themes-20220504.1557/doom-nord-theme.el183
-rw-r--r--elpa/doom-themes-20220504.1557/doom-nova-theme.el144
-rw-r--r--elpa/doom-themes-20220504.1557/doom-oceanic-next-theme.el170
-rw-r--r--elpa/doom-themes-20220504.1557/doom-old-hope-theme.el210
-rw-r--r--elpa/doom-themes-20220504.1557/doom-one-light-theme.el208
-rw-r--r--elpa/doom-themes-20220504.1557/doom-one-theme.el177
-rw-r--r--elpa/doom-themes-20220504.1557/doom-opera-light-theme.el144
-rw-r--r--elpa/doom-themes-20220504.1557/doom-opera-theme.el141
-rw-r--r--elpa/doom-themes-20220504.1557/doom-outrun-electric-theme.el176
-rw-r--r--elpa/doom-themes-20220504.1557/doom-palenight-theme.el132
-rw-r--r--elpa/doom-themes-20220504.1557/doom-peacock-theme.el174
-rw-r--r--elpa/doom-themes-20220504.1557/doom-plain-dark-theme.el138
-rw-r--r--elpa/doom-themes-20220504.1557/doom-plain-theme.el159
-rw-r--r--elpa/doom-themes-20220504.1557/doom-rouge-theme.el191
-rw-r--r--elpa/doom-themes-20220504.1557/doom-shades-of-purple-theme.el295
-rw-r--r--elpa/doom-themes-20220504.1557/doom-snazzy-theme.el102
-rw-r--r--elpa/doom-themes-20220504.1557/doom-solarized-dark-high-contrast-theme.el232
-rw-r--r--elpa/doom-themes-20220504.1557/doom-solarized-dark-theme.el210
-rw-r--r--elpa/doom-themes-20220504.1557/doom-solarized-light-theme.el216
-rw-r--r--elpa/doom-themes-20220504.1557/doom-sourcerer-theme.el168
-rw-r--r--elpa/doom-themes-20220504.1557/doom-spacegrey-theme.el161
-rw-r--r--elpa/doom-themes-20220504.1557/doom-themes-autoloads.el656
-rw-r--r--elpa/doom-themes-20220504.1557/doom-themes-base.el1537
-rw-r--r--elpa/doom-themes-20220504.1557/doom-themes-base.elcbin0 -> 69233 bytes
-rw-r--r--elpa/doom-themes-20220504.1557/doom-themes-ext-neotree.el384
-rw-r--r--elpa/doom-themes-20220504.1557/doom-themes-ext-org.el138
-rw-r--r--elpa/doom-themes-20220504.1557/doom-themes-ext-org.elcbin0 -> 4055 bytes
-rw-r--r--elpa/doom-themes-20220504.1557/doom-themes-ext-treemacs.el313
-rw-r--r--elpa/doom-themes-20220504.1557/doom-themes-ext-visual-bell.el44
-rw-r--r--elpa/doom-themes-20220504.1557/doom-themes-ext-visual-bell.elcbin0 -> 1021 bytes
-rw-r--r--elpa/doom-themes-20220504.1557/doom-themes-pkg.el13
-rw-r--r--elpa/doom-themes-20220504.1557/doom-themes.el435
-rw-r--r--elpa/doom-themes-20220504.1557/doom-themes.elcbin0 -> 10824 bytes
-rw-r--r--elpa/doom-themes-20220504.1557/doom-tokyo-night-theme.el280
-rw-r--r--elpa/doom-themes-20220504.1557/doom-tomorrow-day-theme.el150
-rw-r--r--elpa/doom-themes-20220504.1557/doom-tomorrow-night-theme.el106
-rw-r--r--elpa/doom-themes-20220504.1557/doom-vibrant-theme.el179
-rw-r--r--elpa/doom-themes-20220504.1557/doom-wilmersdorf-theme.el147
-rw-r--r--elpa/doom-themes-20220504.1557/doom-xcode-theme.el111
-rw-r--r--elpa/doom-themes-20220504.1557/doom-zenburn-theme.el341
-rw-r--r--elpa/emmet-mode-20210820.1124/emmet-mode-autoloads.el94
-rw-r--r--elpa/emmet-mode-20210820.1124/emmet-mode-pkg.el2
-rw-r--r--elpa/emmet-mode-20210820.1124/emmet-mode.el4274
-rw-r--r--elpa/emmet-mode-20210820.1124/emmet-mode.elcbin0 -> 136790 bytes
-rw-r--r--elpa/epl-20180205.2049/epl-autoloads.el22
-rw-r--r--elpa/epl-20180205.2049/epl-pkg.el2
-rw-r--r--elpa/epl-20180205.2049/epl.el712
-rw-r--r--elpa/epl-20180205.2049/epl.elcbin0 -> 32435 bytes
-rw-r--r--elpa/evil-20220503.1314/dir18
-rw-r--r--elpa/evil-20220503.1314/evil-autoloads.el128
-rw-r--r--elpa/evil-20220503.1314/evil-command-window.el189
-rw-r--r--elpa/evil-20220503.1314/evil-command-window.elcbin0 -> 7774 bytes
-rw-r--r--elpa/evil-20220503.1314/evil-commands.el4908
-rw-r--r--elpa/evil-20220503.1314/evil-commands.elcbin0 -> 269601 bytes
-rw-r--r--elpa/evil-20220503.1314/evil-common.el4066
-rw-r--r--elpa/evil-20220503.1314/evil-common.elcbin0 -> 123128 bytes
-rw-r--r--elpa/evil-20220503.1314/evil-core.el1392
-rw-r--r--elpa/evil-20220503.1314/evil-core.elcbin0 -> 45072 bytes
-rw-r--r--elpa/evil-20220503.1314/evil-development.el50
-rw-r--r--elpa/evil-20220503.1314/evil-development.elcbin0 -> 501 bytes
-rw-r--r--elpa/evil-20220503.1314/evil-digraphs.el1729
-rw-r--r--elpa/evil-20220503.1314/evil-digraphs.elcbin0 -> 30531 bytes
-rw-r--r--elpa/evil-20220503.1314/evil-ex.el1195
-rw-r--r--elpa/evil-20220503.1314/evil-ex.elcbin0 -> 33471 bytes
-rw-r--r--elpa/evil-20220503.1314/evil-integration.el511
-rw-r--r--elpa/evil-20220503.1314/evil-integration.elcbin0 -> 32686 bytes
-rw-r--r--elpa/evil-20220503.1314/evil-jumps.el354
-rw-r--r--elpa/evil-20220503.1314/evil-jumps.elcbin0 -> 15927 bytes
-rw-r--r--elpa/evil-20220503.1314/evil-keybindings.el124
-rw-r--r--elpa/evil-20220503.1314/evil-keybindings.elcbin0 -> 3923 bytes
-rw-r--r--elpa/evil-20220503.1314/evil-macros.el817
-rw-r--r--elpa/evil-20220503.1314/evil-macros.elcbin0 -> 21904 bytes
-rw-r--r--elpa/evil-20220503.1314/evil-maps.el643
-rw-r--r--elpa/evil-20220503.1314/evil-maps.elcbin0 -> 24838 bytes
-rw-r--r--elpa/evil-20220503.1314/evil-pkg.el12
-rw-r--r--elpa/evil-20220503.1314/evil-repeat.el646
-rw-r--r--elpa/evil-20220503.1314/evil-repeat.elcbin0 -> 17373 bytes
-rw-r--r--elpa/evil-20220503.1314/evil-search.el1336
-rw-r--r--elpa/evil-20220503.1314/evil-search.elcbin0 -> 41951 bytes
-rw-r--r--elpa/evil-20220503.1314/evil-states.el937
-rw-r--r--elpa/evil-20220503.1314/evil-states.elcbin0 -> 60032 bytes
-rw-r--r--elpa/evil-20220503.1314/evil-types.el460
-rw-r--r--elpa/evil-20220503.1314/evil-types.elcbin0 -> 19552 bytes
-rw-r--r--elpa/evil-20220503.1314/evil-vars.el2100
-rw-r--r--elpa/evil-20220503.1314/evil-vars.elcbin0 -> 72382 bytes
-rw-r--r--elpa/evil-20220503.1314/evil.el158
-rw-r--r--elpa/evil-20220503.1314/evil.elcbin0 -> 610 bytes
-rw-r--r--elpa/evil-20220503.1314/evil.info2235
-rw-r--r--elpa/f-20220405.1534/f-autoloads.el22
-rw-r--r--elpa/f-20220405.1534/f-pkg.el2
-rw-r--r--elpa/f-20220405.1534/f.el599
-rw-r--r--elpa/f-20220405.1534/f.elcbin0 -> 18997 bytes
-rw-r--r--elpa/flycheck-20220504.830/flycheck-autoloads.el310
-rw-r--r--elpa/flycheck-20220504.830/flycheck-buttercup.el157
-rw-r--r--elpa/flycheck-20220504.830/flycheck-ert.el507
-rw-r--r--elpa/flycheck-20220504.830/flycheck-ert.elcbin0 -> 25794 bytes
-rw-r--r--elpa/flycheck-20220504.830/flycheck-pkg.el16
-rw-r--r--elpa/flycheck-20220504.830/flycheck.el12469
-rw-r--r--elpa/flycheck-20220504.830/flycheck.elcbin0 -> 550715 bytes
-rw-r--r--elpa/git-commit-20220429.934/git-commit-autoloads.el33
-rw-r--r--elpa/git-commit-20220429.934/git-commit-pkg.el18
-rw-r--r--elpa/git-commit-20220429.934/git-commit.el1141
-rw-r--r--elpa/git-commit-20220429.934/git-commit.elcbin0 -> 40605 bytes
-rw-r--r--elpa/gnupg/pubring.kbxbin0 -> 2413 bytes
-rw-r--r--elpa/gnupg/pubring.kbx~bin0 -> 1206 bytes
-rw-r--r--elpa/gnupg/trustdb.gpgbin0 -> 1200 bytes
-rw-r--r--elpa/goto-chg-20220107.1733/goto-chg-autoloads.el55
-rw-r--r--elpa/goto-chg-20220107.1733/goto-chg-pkg.el2
-rw-r--r--elpa/goto-chg-20220107.1733/goto-chg.el370
-rw-r--r--elpa/goto-chg-20220107.1733/goto-chg.elcbin0 -> 7443 bytes
-rw-r--r--elpa/ht-20210119.741/ht-autoloads.el22
-rw-r--r--elpa/ht-20210119.741/ht-pkg.el2
-rw-r--r--elpa/ht-20210119.741/ht.el337
-rw-r--r--elpa/ht-20210119.741/ht.elcbin0 -> 13244 bytes
-rw-r--r--elpa/hungry-delete-20210409.1643/hungry-delete-autoloads.el110
-rw-r--r--elpa/hungry-delete-20210409.1643/hungry-delete-pkg.el2
-rw-r--r--elpa/hungry-delete-20210409.1643/hungry-delete.el254
-rw-r--r--elpa/hungry-delete-20210409.1643/hungry-delete.elcbin0 -> 12943 bytes
-rw-r--r--elpa/ido-vertical-mode-20210205.436/ido-vertical-mode-autoloads.el52
-rw-r--r--elpa/ido-vertical-mode-20210205.436/ido-vertical-mode-pkg.el2
-rw-r--r--elpa/ido-vertical-mode-20210205.436/ido-vertical-mode.el397
-rw-r--r--elpa/ido-vertical-mode-20210205.436/ido-vertical-mode.elcbin0 -> 12190 bytes
-rw-r--r--elpa/ivy-20220406.1052/colir.el124
-rw-r--r--elpa/ivy-20220406.1052/colir.elcbin0 -> 3081 bytes
-rw-r--r--elpa/ivy-20220406.1052/dir18
-rw-r--r--elpa/ivy-20220406.1052/elpa.el6
-rw-r--r--elpa/ivy-20220406.1052/elpa.elcbin0 -> 324 bytes
-rw-r--r--elpa/ivy-20220406.1052/ivy-autoloads.el166
-rw-r--r--elpa/ivy-20220406.1052/ivy-faces.el138
-rw-r--r--elpa/ivy-20220406.1052/ivy-faces.elcbin0 -> 3819 bytes
-rw-r--r--elpa/ivy-20220406.1052/ivy-help.org138
-rw-r--r--elpa/ivy-20220406.1052/ivy-overlay.el171
-rw-r--r--elpa/ivy-20220406.1052/ivy-overlay.elcbin0 -> 3933 bytes
-rw-r--r--elpa/ivy-20220406.1052/ivy-pkg.el12
-rw-r--r--elpa/ivy-20220406.1052/ivy.el5412
-rw-r--r--elpa/ivy-20220406.1052/ivy.elcbin0 -> 204966 bytes
-rw-r--r--elpa/ivy-20220406.1052/ivy.info1973
-rw-r--r--elpa/key-chord-20201222.2030/key-chord-autoloads.el97
-rw-r--r--elpa/key-chord-20201222.2030/key-chord-pkg.el2
-rw-r--r--elpa/key-chord-20201222.2030/key-chord.el218
-rw-r--r--elpa/key-chord-20201222.2030/key-chord.elcbin0 -> 8173 bytes
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-actionscript.el134
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-actionscript.elcbin0 -> 4144 bytes
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-ada.el106
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-ada.elcbin0 -> 3158 bytes
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-angular.el101
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-angular.elcbin0 -> 2504 bytes
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-ansible.el186
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-ansible.elcbin0 -> 6453 bytes
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-bash.el90
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-bash.elcbin0 -> 2374 bytes
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-beancount.el71
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-beancount.elcbin0 -> 1461 bytes
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-clangd.el315
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-clangd.elcbin0 -> 10637 bytes
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-clojure.el448
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-clojure.elcbin0 -> 20030 bytes
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-cmake.el43
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-cmake.elcbin0 -> 611 bytes
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-completion.el818
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-completion.elcbin0 -> 27016 bytes
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-crystal.el48
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-crystal.elcbin0 -> 775 bytes
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-csharp.el472
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-csharp.elcbin0 -> 17116 bytes
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-css.el254
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-css.elcbin0 -> 7970 bytes
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-d.el41
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-d.elcbin0 -> 559 bytes
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-dhall.el43
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-dhall.elcbin0 -> 595 bytes
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-diagnostics.el370
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-diagnostics.elcbin0 -> 13707 bytes
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-dired.el178
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-dired.elcbin0 -> 7366 bytes
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-dockerfile.el66
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-dockerfile.elcbin0 -> 1397 bytes
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-elixir.el213
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-elixir.elcbin0 -> 6872 bytes
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-elm.el137
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-elm.elcbin0 -> 4135 bytes
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-emmet.el65
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-emmet.elcbin0 -> 1343 bytes
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-erlang.el67
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-erlang.elcbin0 -> 1470 bytes
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-eslint.el408
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-eslint.elcbin0 -> 15514 bytes
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-fortran.el61
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-fortran.elcbin0 -> 1325 bytes
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-fsharp.el298
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-fsharp.elcbin0 -> 10066 bytes
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-gdscript.el61
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-gdscript.elcbin0 -> 1205 bytes
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-go.el337
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-go.elcbin0 -> 11606 bytes
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-graphql.el73
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-graphql.elcbin0 -> 1880 bytes
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-groovy.el66
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-groovy.elcbin0 -> 1617 bytes
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-hack.el54
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-hack.elcbin0 -> 1073 bytes
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-haxe.el226
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-haxe.elcbin0 -> 6099 bytes
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-headerline.el478
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-headerline.elcbin0 -> 18874 bytes
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-html.el200
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-html.elcbin0 -> 6196 bytes
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-icons.el96
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-icons.elcbin0 -> 2473 bytes
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-ido.el142
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-ido.elcbin0 -> 3004 bytes
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-idris.el67
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-idris.elcbin0 -> 1314 bytes
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-iedit.el149
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-iedit.elcbin0 -> 3638 bytes
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-javascript.el1119
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-javascript.elcbin0 -> 49272 bytes
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-json.el131
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-json.elcbin0 -> 4209 bytes
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-kotlin.el154
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-kotlin.elcbin0 -> 5292 bytes
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-lens.el448
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-lens.elcbin0 -> 16734 bytes
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-lua.el678
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-lua.elcbin0 -> 23134 bytes
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-magik.el124
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-magik.elcbin0 -> 3327 bytes
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-markdown.el103
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-markdown.elcbin0 -> 3160 bytes
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-mode-autoloads.el963
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-mode-pkg.el18
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-mode.el8997
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-mode.elcbin0 -> 451550 bytes
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-modeline.el354
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-modeline.elcbin0 -> 18035 bytes
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-nginx.el53
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-nginx.elcbin0 -> 920 bytes
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-nim.el81
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-nim.elcbin0 -> 1988 bytes
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-nix.el48
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-nix.elcbin0 -> 809 bytes
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-ocaml.el84
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-ocaml.elcbin0 -> 2047 bytes
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-openscad.el49
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-openscad.elcbin0 -> 736 bytes
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-perl.el117
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-perl.elcbin0 -> 3080 bytes
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-perlnavigator.el197
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-perlnavigator.elcbin0 -> 6863 bytes
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-php.el449
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-php.elcbin0 -> 24187 bytes
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-prolog.el55
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-prolog.elcbin0 -> 920 bytes
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-protocol.el783
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-protocol.elcbin0 -> 1049997 bytes
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-purescript.el86
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-purescript.elcbin0 -> 2532 bytes
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-pwsh.el363
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-pwsh.elcbin0 -> 14461 bytes
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-pyls.el504
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-pyls.elcbin0 -> 18483 bytes
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-pylsp.el434
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-pylsp.elcbin0 -> 15858 bytes
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-r.el49
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-r.elcbin0 -> 776 bytes
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-racket.el77
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-racket.elcbin0 -> 1897 bytes
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-remark.el69
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-remark.elcbin0 -> 1637 bytes
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-rf.el147
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-rf.elcbin0 -> 4672 bytes
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-rust.el1203
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-rust.elcbin0 -> 54292 bytes
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-semantic-tokens.el876
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-semantic-tokens.elcbin0 -> 33973 bytes
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-solargraph.el166
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-solargraph.elcbin0 -> 4397 bytes
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-sorbet.el59
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-sorbet.elcbin0 -> 1109 bytes
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-sqls.el191
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-sqls.elcbin0 -> 6037 bytes
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-steep.el73
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-steep.elcbin0 -> 1586 bytes
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-svelte.el307
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-svelte.elcbin0 -> 12295 bytes
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-terraform.el122
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-terraform.elcbin0 -> 2966 bytes
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-tex.el68
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-tex.elcbin0 -> 1393 bytes
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-toml.el172
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-toml.elcbin0 -> 7020 bytes
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-ttcn3.el51
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-ttcn3.elcbin0 -> 824 bytes
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-typeprof.el60
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-typeprof.elcbin0 -> 1138 bytes
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-v.el50
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-v.elcbin0 -> 866 bytes
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-vala.el51
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-vala.elcbin0 -> 941 bytes
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-verilog.el194
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-verilog.elcbin0 -> 6808 bytes
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-vetur.el353
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-vetur.elcbin0 -> 12188 bytes
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-vhdl.el121
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-vhdl.elcbin0 -> 3323 bytes
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-vimscript.el75
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-vimscript.elcbin0 -> 1756 bytes
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-volar.el225
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-volar.elcbin0 -> 7878 bytes
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-xml.el245
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-xml.elcbin0 -> 7980 bytes
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-yaml.el242
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-yaml.elcbin0 -> 7726 bytes
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-zig.el50
-rw-r--r--elpa/lsp-mode-20220505.630/lsp-zig.elcbin0 -> 870 bytes
-rw-r--r--elpa/lsp-mode-20220505.630/lsp.el8
-rw-r--r--elpa/lsp-mode-20220505.630/lsp.elcbin0 -> 153 bytes
-rw-r--r--elpa/lsp-pyright-20220411.1753/lsp-pyright-autoloads.el22
-rw-r--r--elpa/lsp-pyright-20220411.1753/lsp-pyright-pkg.el2
-rw-r--r--elpa/lsp-pyright-20220411.1753/lsp-pyright.el253
-rw-r--r--elpa/lsp-pyright-20220411.1753/lsp-pyright.elcbin0 -> 8813 bytes
-rw-r--r--elpa/lsp-ui-20220425.1046/lsp-ui-autoloads.el80
-rw-r--r--elpa/lsp-ui-20220425.1046/lsp-ui-doc.el1220
-rw-r--r--elpa/lsp-ui-20220425.1046/lsp-ui-doc.elcbin0 -> 48117 bytes
-rw-r--r--elpa/lsp-ui-20220425.1046/lsp-ui-doc.html52
-rw-r--r--elpa/lsp-ui-20220425.1046/lsp-ui-flycheck.el171
-rw-r--r--elpa/lsp-ui-20220425.1046/lsp-ui-flycheck.elcbin0 -> 7448 bytes
-rw-r--r--elpa/lsp-ui-20220425.1046/lsp-ui-imenu.el412
-rw-r--r--elpa/lsp-ui-20220425.1046/lsp-ui-imenu.elcbin0 -> 16330 bytes
-rw-r--r--elpa/lsp-ui-20220425.1046/lsp-ui-peek.el760
-rw-r--r--elpa/lsp-ui-20220425.1046/lsp-ui-peek.elcbin0 -> 29391 bytes
-rw-r--r--elpa/lsp-ui-20220425.1046/lsp-ui-pkg.el15
-rw-r--r--elpa/lsp-ui-20220425.1046/lsp-ui-sideline.el768
-rw-r--r--elpa/lsp-ui-20220425.1046/lsp-ui-sideline.elcbin0 -> 29376 bytes
-rw-r--r--elpa/lsp-ui-20220425.1046/lsp-ui-util.el71
-rw-r--r--elpa/lsp-ui-20220425.1046/lsp-ui-util.elcbin0 -> 1219 bytes
-rw-r--r--elpa/lsp-ui-20220425.1046/lsp-ui.el177
-rw-r--r--elpa/lsp-ui-20220425.1046/lsp-ui.elcbin0 -> 5844 bytes
-rw-r--r--elpa/lsp-ui-20220425.1046/resources/lightbulb.pngbin0 -> 2058 bytes
-rw-r--r--elpa/lv-20200507.1518/lv-autoloads.el22
-rw-r--r--elpa/lv-20200507.1518/lv-pkg.el2
-rw-r--r--elpa/lv-20200507.1518/lv.el150
-rw-r--r--elpa/lv-20200507.1518/lv.elcbin0 -> 3466 bytes
-rw-r--r--elpa/magit-20220503.1245/AUTHORS.md386
-rw-r--r--elpa/magit-20220503.1245/LICENSE674
-rw-r--r--elpa/magit-20220503.1245/dir18
-rw-r--r--elpa/magit-20220503.1245/git-rebase.el848
-rw-r--r--elpa/magit-20220503.1245/git-rebase.elcbin0 -> 28913 bytes
-rw-r--r--elpa/magit-20220503.1245/magit-apply.el806
-rw-r--r--elpa/magit-20220503.1245/magit-apply.elcbin0 -> 137064 bytes
-rw-r--r--elpa/magit-20220503.1245/magit-autoloads.el2601
-rw-r--r--elpa/magit-20220503.1245/magit-autorevert.el261
-rw-r--r--elpa/magit-20220503.1245/magit-autorevert.elcbin0 -> 12593 bytes
-rw-r--r--elpa/magit-20220503.1245/magit-base.el1274
-rw-r--r--elpa/magit-20220503.1245/magit-base.elcbin0 -> 51300 bytes
-rw-r--r--elpa/magit-20220503.1245/magit-bisect.el307
-rw-r--r--elpa/magit-20220503.1245/magit-bisect.elcbin0 -> 19218 bytes
-rw-r--r--elpa/magit-20220503.1245/magit-blame.el984
-rw-r--r--elpa/magit-20220503.1245/magit-blame.elcbin0 -> 40797 bytes
-rw-r--r--elpa/magit-20220503.1245/magit-bookmark.el205
-rw-r--r--elpa/magit-20220503.1245/magit-bookmark.elcbin0 -> 5435 bytes
-rw-r--r--elpa/magit-20220503.1245/magit-branch.el934
-rw-r--r--elpa/magit-20220503.1245/magit-branch.elcbin0 -> 39131 bytes
-rw-r--r--elpa/magit-20220503.1245/magit-bundle.el132
-rw-r--r--elpa/magit-20220503.1245/magit-bundle.elcbin0 -> 5552 bytes
-rw-r--r--elpa/magit-20220503.1245/magit-clone.el327
-rw-r--r--elpa/magit-20220503.1245/magit-clone.elcbin0 -> 13155 bytes
-rw-r--r--elpa/magit-20220503.1245/magit-commit.el717
-rw-r--r--elpa/magit-20220503.1245/magit-commit.elcbin0 -> 29129 bytes
-rw-r--r--elpa/magit-20220503.1245/magit-core.el129
-rw-r--r--elpa/magit-20220503.1245/magit-core.elcbin0 -> 2802 bytes
-rw-r--r--elpa/magit-20220503.1245/magit-diff.el3450
-rw-r--r--elpa/magit-20220503.1245/magit-diff.elcbin0 -> 193078 bytes
-rw-r--r--elpa/magit-20220503.1245/magit-ediff.el483
-rw-r--r--elpa/magit-20220503.1245/magit-ediff.elcbin0 -> 22881 bytes
-rw-r--r--elpa/magit-20220503.1245/magit-extras.el916
-rw-r--r--elpa/magit-20220503.1245/magit-extras.elcbin0 -> 34035 bytes
-rw-r--r--elpa/magit-20220503.1245/magit-fetch.el199
-rw-r--r--elpa/magit-20220503.1245/magit-fetch.elcbin0 -> 7788 bytes
-rw-r--r--elpa/magit-20220503.1245/magit-files.el535
-rw-r--r--elpa/magit-20220503.1245/magit-files.elcbin0 -> 22141 bytes
-rw-r--r--elpa/magit-20220503.1245/magit-git.el2650
-rw-r--r--elpa/magit-20220503.1245/magit-git.elcbin0 -> 106400 bytes
-rw-r--r--elpa/magit-20220503.1245/magit-gitignore.el195
-rw-r--r--elpa/magit-20220503.1245/magit-gitignore.elcbin0 -> 7099 bytes
-rw-r--r--elpa/magit-20220503.1245/magit-log.el1938
-rw-r--r--elpa/magit-20220503.1245/magit-log.elcbin0 -> 106047 bytes
-rw-r--r--elpa/magit-20220503.1245/magit-margin.el239
-rw-r--r--elpa/magit-20220503.1245/magit-margin.elcbin0 -> 8110 bytes
-rw-r--r--elpa/magit-20220503.1245/magit-merge.el318
-rw-r--r--elpa/magit-20220503.1245/magit-merge.elcbin0 -> 14557 bytes
-rw-r--r--elpa/magit-20220503.1245/magit-mode.el1547
-rw-r--r--elpa/magit-20220503.1245/magit-mode.elcbin0 -> 56716 bytes
-rw-r--r--elpa/magit-20220503.1245/magit-notes.el201
-rw-r--r--elpa/magit-20220503.1245/magit-notes.elcbin0 -> 9083 bytes
-rw-r--r--elpa/magit-20220503.1245/magit-obsolete.el111
-rw-r--r--elpa/magit-20220503.1245/magit-obsolete.elcbin0 -> 3850 bytes
-rw-r--r--elpa/magit-20220503.1245/magit-patch.el326
-rw-r--r--elpa/magit-20220503.1245/magit-patch.elcbin0 -> 18239 bytes
-rw-r--r--elpa/magit-20220503.1245/magit-pkg.el19
-rw-r--r--elpa/magit-20220503.1245/magit-process.el1220
-rw-r--r--elpa/magit-20220503.1245/magit-process.elcbin0 -> 48728 bytes
-rw-r--r--elpa/magit-20220503.1245/magit-pull.el165
-rw-r--r--elpa/magit-20220503.1245/magit-pull.elcbin0 -> 6061 bytes
-rw-r--r--elpa/magit-20220503.1245/magit-push.el341
-rw-r--r--elpa/magit-20220503.1245/magit-push.elcbin0 -> 13015 bytes
-rw-r--r--elpa/magit-20220503.1245/magit-reflog.el210
-rw-r--r--elpa/magit-20220503.1245/magit-reflog.elcbin0 -> 9712 bytes
-rw-r--r--elpa/magit-20220503.1245/magit-refs.el774
-rw-r--r--elpa/magit-20220503.1245/magit-refs.elcbin0 -> 40942 bytes
-rw-r--r--elpa/magit-20220503.1245/magit-remote.el368
-rw-r--r--elpa/magit-20220503.1245/magit-remote.elcbin0 -> 15989 bytes
-rw-r--r--elpa/magit-20220503.1245/magit-repos.el543
-rw-r--r--elpa/magit-20220503.1245/magit-repos.elcbin0 -> 21392 bytes
-rw-r--r--elpa/magit-20220503.1245/magit-reset.el134
-rw-r--r--elpa/magit-20220503.1245/magit-reset.elcbin0 -> 5630 bytes
-rw-r--r--elpa/magit-20220503.1245/magit-sequence.el1087
-rw-r--r--elpa/magit-20220503.1245/magit-sequence.elcbin0 -> 54828 bytes
-rw-r--r--elpa/magit-20220503.1245/magit-sparse-checkout.el170
-rw-r--r--elpa/magit-20220503.1245/magit-sparse-checkout.elcbin0 -> 5665 bytes
-rw-r--r--elpa/magit-20220503.1245/magit-stash.el566
-rw-r--r--elpa/magit-20220503.1245/magit-stash.elcbin0 -> 37001 bytes
-rw-r--r--elpa/magit-20220503.1245/magit-status.el833
-rw-r--r--elpa/magit-20220503.1245/magit-status.elcbin0 -> 59672 bytes
-rw-r--r--elpa/magit-20220503.1245/magit-submodule.el719
-rw-r--r--elpa/magit-20220503.1245/magit-submodule.elcbin0 -> 39862 bytes
-rw-r--r--elpa/magit-20220503.1245/magit-subtree.el181
-rw-r--r--elpa/magit-20220503.1245/magit-subtree.elcbin0 -> 9040 bytes
-rw-r--r--elpa/magit-20220503.1245/magit-tag.el236
-rw-r--r--elpa/magit-20220503.1245/magit-tag.elcbin0 -> 8046 bytes
-rw-r--r--elpa/magit-20220503.1245/magit-transient.el220
-rw-r--r--elpa/magit-20220503.1245/magit-transient.elcbin0 -> 10757 bytes
-rw-r--r--elpa/magit-20220503.1245/magit-wip.el453
-rw-r--r--elpa/magit-20220503.1245/magit-wip.elcbin0 -> 31277 bytes
-rw-r--r--elpa/magit-20220503.1245/magit-worktree.el191
-rw-r--r--elpa/magit-20220503.1245/magit-worktree.elcbin0 -> 8770 bytes
-rw-r--r--elpa/magit-20220503.1245/magit.el683
-rw-r--r--elpa/magit-20220503.1245/magit.elcbin0 -> 23135 bytes
-rw-r--r--elpa/magit-20220503.1245/magit.info11220
-rw-r--r--elpa/magit-section-20220502.2245/dir19
-rw-r--r--elpa/magit-section-20220502.2245/magit-section-autoloads.el26
-rw-r--r--elpa/magit-section-20220502.2245/magit-section-pkg.el14
-rw-r--r--elpa/magit-section-20220502.2245/magit-section.el2202
-rw-r--r--elpa/magit-section-20220502.2245/magit-section.elcbin0 -> 80937 bytes
-rw-r--r--elpa/magit-section-20220502.2245/magit-section.info307
-rw-r--r--elpa/markdown-mode-20220406.410/markdown-mode-autoloads.el64
-rw-r--r--elpa/markdown-mode-20220406.410/markdown-mode-pkg.el2
-rw-r--r--elpa/markdown-mode-20220406.410/markdown-mode.el9950
-rw-r--r--elpa/markdown-mode-20220406.410/markdown-mode.elcbin0 -> 335405 bytes
-rw-r--r--elpa/org-bullets-20200317.1740/org-bullets-autoloads.el41
-rw-r--r--elpa/org-bullets-20200317.1740/org-bullets-pkg.el2
-rw-r--r--elpa/org-bullets-20200317.1740/org-bullets.el138
-rw-r--r--elpa/org-bullets-20200317.1740/org-bullets.elcbin0 -> 4284 bytes
-rw-r--r--elpa/pkg-info-20150517.1143/pkg-info-autoloads.el127
-rw-r--r--elpa/pkg-info-20150517.1143/pkg-info-pkg.el2
-rw-r--r--elpa/pkg-info-20150517.1143/pkg-info.el332
-rw-r--r--elpa/pkg-info-20150517.1143/pkg-info.elcbin0 -> 9563 bytes
-rw-r--r--elpa/projectile-20220430.800/projectile-autoloads.el625
-rw-r--r--elpa/projectile-20220430.800/projectile-pkg.el2
-rw-r--r--elpa/projectile-20220430.800/projectile.el5854
-rw-r--r--elpa/projectile-20220430.800/projectile.elcbin0 -> 216786 bytes
-rw-r--r--elpa/s-20210616.619/s-autoloads.el22
-rw-r--r--elpa/s-20210616.619/s-pkg.el2
-rw-r--r--elpa/s-20210616.619/s.el745
-rw-r--r--elpa/s-20210616.619/s.elcbin0 -> 28078 bytes
-rw-r--r--elpa/smex-20151212.2209/smex-autoloads.el29
-rw-r--r--elpa/smex-20151212.2209/smex-pkg.el2
-rw-r--r--elpa/smex-20151212.2209/smex.el485
-rw-r--r--elpa/smex-20151212.2209/smex.elcbin0 -> 12717 bytes
-rw-r--r--elpa/spinner-1.7.4.signed1
-rw-r--r--elpa/spinner-1.7.4/README.org76
-rw-r--r--elpa/spinner-1.7.4/all-spinners.gifbin0 -> 18314 bytes
-rw-r--r--elpa/spinner-1.7.4/some-spinners.gifbin0 -> 1932043 bytes
-rw-r--r--elpa/spinner-1.7.4/spinner-autoloads.el77
-rw-r--r--elpa/spinner-1.7.4/spinner-pkg.el2
-rw-r--r--elpa/spinner-1.7.4/spinner.el340
-rw-r--r--elpa/spinner-1.7.4/spinner.elcbin0 -> 16321 bytes
-rw-r--r--elpa/swiper-20220430.2247/swiper-autoloads.el58
-rw-r--r--elpa/swiper-20220430.2247/swiper-pkg.el2
-rw-r--r--elpa/swiper-20220430.2247/swiper.el1759
-rw-r--r--elpa/swiper-20220430.2247/swiper.elcbin0 -> 51251 bytes
-rw-r--r--elpa/switch-window-20210808.742/switch-window-asciiart.el232
-rw-r--r--elpa/switch-window-20210808.742/switch-window-asciiart.elcbin0 -> 1867 bytes
-rw-r--r--elpa/switch-window-20210808.742/switch-window-autoloads.el119
-rw-r--r--elpa/switch-window-20210808.742/switch-window-mvborder.el72
-rw-r--r--elpa/switch-window-20210808.742/switch-window-mvborder.elcbin0 -> 1848 bytes
-rw-r--r--elpa/switch-window-20210808.742/switch-window-pkg.el13
-rw-r--r--elpa/switch-window-20210808.742/switch-window.el1017
-rw-r--r--elpa/switch-window-20210808.742/switch-window.elcbin0 -> 27773 bytes
-rw-r--r--elpa/transient-20220503.1118/dir18
-rw-r--r--elpa/transient-20220503.1118/transient-autoloads.el80
-rw-r--r--elpa/transient-20220503.1118/transient-pkg.el13
-rw-r--r--elpa/transient-20220503.1118/transient.el4073
-rw-r--r--elpa/transient-20220503.1118/transient.elcbin0 -> 161628 bytes
-rw-r--r--elpa/transient-20220503.1118/transient.info2648
-rw-r--r--elpa/use-package-20210207.1926/dir18
-rw-r--r--elpa/use-package-20210207.1926/use-package-autoloads.el230
-rw-r--r--elpa/use-package-20210207.1926/use-package-bind-key.el172
-rw-r--r--elpa/use-package-20210207.1926/use-package-bind-key.elcbin0 -> 4207 bytes
-rw-r--r--elpa/use-package-20210207.1926/use-package-core.el1633
-rw-r--r--elpa/use-package-20210207.1926/use-package-core.elcbin0 -> 56341 bytes
-rw-r--r--elpa/use-package-20210207.1926/use-package-delight.el91
-rw-r--r--elpa/use-package-20210207.1926/use-package-delight.elcbin0 -> 1523 bytes
-rw-r--r--elpa/use-package-20210207.1926/use-package-diminish.el80
-rw-r--r--elpa/use-package-20210207.1926/use-package-diminish.elcbin0 -> 1398 bytes
-rw-r--r--elpa/use-package-20210207.1926/use-package-ensure.el214
-rw-r--r--elpa/use-package-20210207.1926/use-package-ensure.elcbin0 -> 5051 bytes
-rw-r--r--elpa/use-package-20210207.1926/use-package-jump.el79
-rw-r--r--elpa/use-package-20210207.1926/use-package-jump.elcbin0 -> 1445 bytes
-rw-r--r--elpa/use-package-20210207.1926/use-package-lint.el84
-rw-r--r--elpa/use-package-20210207.1926/use-package-lint.elcbin0 -> 1201 bytes
-rw-r--r--elpa/use-package-20210207.1926/use-package-pkg.el13
-rw-r--r--elpa/use-package-20210207.1926/use-package.el54
-rw-r--r--elpa/use-package-20210207.1926/use-package.elcbin0 -> 394 bytes
-rw-r--r--elpa/use-package-20210207.1926/use-package.info1048
-rw-r--r--elpa/which-key-20220419.227/which-key-autoloads.el216
-rw-r--r--elpa/which-key-20220419.227/which-key-pkg.el2
-rw-r--r--elpa/which-key-20220419.227/which-key.el2711
-rw-r--r--elpa/which-key-20220419.227/which-key.elcbin0 -> 107366 bytes
-rw-r--r--elpa/with-editor-20220503.1124/dir18
-rw-r--r--elpa/with-editor-20220503.1124/with-editor-autoloads.el111
-rw-r--r--elpa/with-editor-20220503.1124/with-editor-pkg.el13
-rw-r--r--elpa/with-editor-20220503.1124/with-editor.el945
-rw-r--r--elpa/with-editor-20220503.1124/with-editor.elcbin0 -> 35375 bytes
-rw-r--r--elpa/with-editor-20220503.1124/with-editor.info382
-rw-r--r--ido.last30
-rw-r--r--init.el157
-rw-r--r--projectile-bookmarks.eld1
-rw-r--r--recentf14
-rw-r--r--smex-items21
-rw-r--r--transient/history.el1
752 files changed, 225591 insertions, 0 deletions
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..8d020c0
--- /dev/null
+++ b/README.md
@@ -0,0 +1 @@
+# My Minimal Emacs config
diff --git a/auto-save-list/.saves-1346-satan~ b/auto-save-list/.saves-1346-satan~
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/auto-save-list/.saves-1346-satan~
diff --git a/auto-save-list/.saves-18617-satan~ b/auto-save-list/.saves-18617-satan~
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/auto-save-list/.saves-18617-satan~
diff --git a/auto-save-list/.saves-23720-satan~ b/auto-save-list/.saves-23720-satan~
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/auto-save-list/.saves-23720-satan~
diff --git a/avatar.png b/avatar.png
new file mode 100644
index 0000000..71dca97
--- /dev/null
+++ b/avatar.png
Binary files differ
diff --git a/elpa/archives/gnu/archive-contents b/elpa/archives/gnu/archive-contents
new file mode 100644
index 0000000..d2915ce
--- /dev/null
+++ b/elpa/archives/gnu/archive-contents
@@ -0,0 +1,3487 @@
+(1
+ (ace-window .
+ [(0 10 0)
+ ((avy
+ (0 5 0)))
+ "Quickly switch windows." tar
+ ((:url . "https://github.com/abo-abo/ace-window")
+ (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com")
+ (:authors
+ ("Oleh Krehel" . "ohwoeowho@gmail.com"))
+ (:keywords "window" "location"))])
+ (ack .
+ [(1 10)
+ nil "interface to ack-like tools" tar
+ ((:url . "https://github.com/leoliu/ack-el")
+ (:maintainer "João Távora" . "joaotavora@gmail.com")
+ (:authors
+ ("Leo Liu" . "sdl.web@gmail.com"))
+ (:keywords "tools" "processes" "convenience"))])
+ (ada-mode .
+ [(7 2 0)
+ ((uniquify-files
+ (1 0 1))
+ (wisi
+ (3 1 5))
+ (emacs
+ (25 3)))
+ "major-mode for editing Ada sources" tar
+ ((:url . "http://www.nongnu.org/ada-mode/")
+ (:keywords "languages" "ada")
+ (:maintainer "Stephen Leake" . "stephen_leake@stephe-leake.org")
+ (:authors
+ ("Stephen Leake" . "stephen_leake@stephe-leake.org")))])
+ (ada-ref-man .
+ [(2020 1)
+ nil "Ada Reference Manual 2012" tar
+ ((:url . "http://stephe-leake.org/ada/arm.html")
+ (:maintainer "Stephen Leake" . "stephen_leake@member.fsf.org")
+ (:authors
+ ("Stephen Leake" . "stephen_leake@member.fsf.org"))
+ (:keywords "languages" "ada"))])
+ (adaptive-wrap .
+ [(0 8)
+ nil "Smart line-wrapping with wrap-prefix" tar
+ ((:maintainer "Stephen Berman" . "stephen.berman@gmx.net")
+ (:authors
+ ("Stephen Berman" . "stephen.berman@gmx.net")
+ ("Stefan Monnier" . "monnier@iro.umontreal.ca"))
+ (:url . "https://elpa.gnu.org/packages/adaptive-wrap.html"))])
+ (adjust-parens .
+ [(3 1)
+ nil "Indent and dedent Lisp code, automatically adjust close parens" tar
+ ((:maintainer "Barry O'Reilly" . "gundaetiapo@gmail.com")
+ (:authors
+ ("Barry O'Reilly" . "gundaetiapo@gmail.com"))
+ (:url . "http://elpa.gnu.org/packages/adjust-parens.html"))])
+ (advice-patch .
+ [(0 1)
+ ((emacs
+ (24 4)))
+ "Use patches to advise the inside of functions" single
+ ((:url . "http://elpa.gnu.org/packages/advice-patch.html")
+ (:authors
+ ("Stefan Monnier" . "monnier@iro.umontreal.ca"))
+ (:maintainer "Stefan Monnier" . "monnier@iro.umontreal.ca"))])
+ (aggressive-completion .
+ [(1 7)
+ ((emacs
+ (27 1)))
+ "Automatic minibuffer completion" tar
+ ((:keywords "minibuffer" "completion")
+ (:maintainer "Tassilo Horn" . "tsdh@gnu.org")
+ (:authors
+ ("Tassilo Horn" . "tsdh@gnu.org"))
+ (:url . "https://elpa.gnu.org/packages/aggressive-completion.html")
+ (:commit . "d92bf2428133b6e261780e16b7030afe91d3668e"))])
+ (aggressive-indent .
+ [(1 10 0)
+ ((emacs
+ (24 3)))
+ "Minor mode to aggressively keep your code always indented" tar
+ ((:url . "https://github.com/Malabarba/aggressive-indent-mode")
+ (:maintainer "Artur Malabarba" . "emacs@endlessparentheses.com")
+ (:authors
+ ("Artur Malabarba" . "emacs@endlessparentheses.com"))
+ (:keywords "indent" "lisp" "maint" "tools"))])
+ (ahungry-theme .
+ [(1 10 0)
+ ((emacs
+ (24)))
+ "Ahungry color theme for Emacs. Make sure to (load-theme 'ahungry)." tar
+ ((:url . "https://github.com/ahungry/color-theme-ahungry")
+ (:maintainer "Matthew Carter" . "m@ahungry.com")
+ (:authors
+ ("Matthew Carter" . "m@ahungry.com"))
+ (:keywords "ahungry" "palette" "color" "theme" "emacs" "color-theme" "deftheme"))])
+ (all .
+ [(1 0)
+ nil "Edit all lines matching a given regexp" single
+ ((:url . "http://elpa.gnu.org/packages/all.html")
+ (:keywords "matching")
+ (:authors
+ ("Per Abrahamsen" . "per.abrahamsen@gmail.com"))
+ (:maintainer "Per Abrahamsen" . "per.abrahamsen@gmail.com"))])
+ (ampc .
+ [(0 2)
+ nil "Asynchronous Music Player Controller" single
+ ((:url . "http://elpa.gnu.org/packages/ampc.html")
+ (:keywords "ampc" "mpc" "mpd")
+ (:authors
+ ("Christopher Schmidt" . "christopher@ch.ristopher.com"))
+ (:maintainer nil . "emacs-devel@gnu.org"))])
+ (arbitools .
+ [(0 977)
+ ((cl-lib
+ (0 5)))
+ "Package for chess tournaments administration" single
+ ((:url . "http://elpa.gnu.org/packages/arbitools.html")
+ (:authors
+ ("David Gonzalez Gandara" . "dggandara@member.fsf.org"))
+ (:maintainer "David Gonzalez Gandara" . "dggandara@member.fsf.org"))])
+ (ascii-art-to-unicode .
+ [(1 13)
+ nil "a small artist adjunct" single
+ ((:keywords "ascii" "unicode" "box-drawing")
+ (:authors
+ ("Thien-Thi Nguyen" . "ttn@gnu.org"))
+ (:maintainer "Thien-Thi Nguyen" . "ttn@gnu.org")
+ (:url . "http://www.gnuvola.org/software/aa2u/"))])
+ (async .
+ [(1 9 5)
+ ((emacs
+ (24 3)))
+ "Asynchronous processing in Emacs" tar
+ ((:url . "https://github.com/jwiegley/emacs-async")
+ (:maintainer "John Wiegley" . "jwiegley@gmail.com")
+ (:authors
+ ("John Wiegley" . "jwiegley@gmail.com"))
+ (:keywords "async"))])
+ (auctex .
+ [(13 1 3)
+ ((emacs
+ (25 1)))
+ "Integrated environment for *TeX*" tar
+ ((:url . "https://www.gnu.org/software/auctex/")
+ (:keywords "tex" "latex" "texinfo" "context" "doctex" "preview-latex")
+ (:maintainer nil . "auctex-devel@gnu.org")
+ (:commit . "b91f15b3a375445985143ed1d6e41490ea62780a"))])
+ (aumix-mode .
+ [(7)
+ nil "run the aumix program in a buffer" single
+ ((:keywords "multimedia" "mixer" "aumix")
+ (:authors
+ ("Kevin Ryde" . "user42_kevin@yahoo.com.au"))
+ (:maintainer "Kevin Ryde" . "user42_kevin@yahoo.com.au")
+ (:url . "http://user42.tuxfamily.org/aumix-mode/index.html"))])
+ (auto-correct .
+ [(1 1 4)
+ nil "Remembers and automatically fixes past corrections" single
+ ((:url . "http://elpa.gnu.org/packages/auto-correct.html")
+ (:keywords "editing")
+ (:authors
+ ("Ian Dunn" . "dunni@gnu.org"))
+ (:maintainer "Ian Dunn" . "dunni@gnu.org"))])
+ (auto-overlays .
+ [(0 10 10)
+ ((cl-lib
+ (0 5)))
+ "Automatic regexp-delimited overlays" tar
+ ((:url . "http://www.dr-qubit.org/tags/computing-code-emacs.html")
+ (:maintainer "Toby Cubitt" . "toby-predictive@dr-qubit.org")
+ (:authors
+ ("Toby Cubitt" . "toby-predictive@dr-qubit.org"))
+ (:keywords "extensions"))])
+ (avy .
+ [(0 5 0)
+ ((emacs
+ (24 1))
+ (cl-lib
+ (0 5)))
+ "Jump to arbitrary positions in visible text and select text quickly." tar
+ ((:url . "https://github.com/abo-abo/avy")
+ (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com")
+ (:authors
+ ("Oleh Krehel" . "ohwoeowho@gmail.com"))
+ (:keywords "point" "location"))])
+ (bbdb .
+ [(3 2 2 2)
+ ((emacs
+ (24))
+ (cl-lib
+ (0 5)))
+ "Big Brother DataBase" tar
+ ((:maintainer "Roland Winkler" . "winkler@gnu.org")
+ (:url . "https://elpa.gnu.org/packages/bbdb.html")
+ (:commit . "715f35b5f53d6bcdcb3754b4f98933df01b57c15"))])
+ (beacon .
+ [(1 3 3)
+ ((seq
+ (2 14)))
+ "Highlight the cursor whenever the window scrolls" single
+ ((:keywords "convenience")
+ (:authors
+ ("Artur Malabarba" . "emacs@endlessparentheses.com"))
+ (:maintainer "Artur Malabarba" . "emacs@endlessparentheses.com")
+ (:url . "https://github.com/Malabarba/beacon"))])
+ (blist .
+ [(0 1)
+ nil "Display bookmarks in an ibuffer way" tar
+ ((:keywords "convenience")
+ (:maintainer "Durand" . "mmemmew@gmail.com")
+ (:authors
+ ("Durand" . "mmemmew@gmail.com"))
+ (:url . "https://elpa.gnu.org/packages/blist.html"))])
+ (bluetooth .
+ [(0 3 1)
+ ((emacs
+ (25 1))
+ (dash
+ (2 18 1)))
+ "A Major mode for Bluetooth devices" tar
+ ((:url . "https://gitlab.com/rstocker/emacs-bluetooth")
+ (:keywords "hardware")
+ (:maintainer "Raffael Stocker" . "r.stocker@mnet-mail.de")
+ (:authors
+ ("Raffael Stocker" . "r.stocker@mnet-mail.de")
+ ("Etienne Prud’homme" . "e.e.f.prudhomme@gmail.com"))
+ (:commit . "84488dfdd2355e512f9e9444a233448221b3d9cc"))])
+ (bnf-mode .
+ [(0 4 5)
+ ((cl-lib
+ (0 5))
+ (emacs
+ (24 3)))
+ "Major mode for editing BNF grammars." tar
+ ((:url . "https://github.com/sergeyklay/bnf-mode")
+ (:maintainer "Serghei Iakovlev" . "egrep@protonmail.ch")
+ (:authors
+ ("Serghei Iakovlev" . "egrep@protonmail.ch"))
+ (:keywords "languages"))])
+ (boxy .
+ [(1 0 5)
+ ((emacs
+ (26 1)))
+ "A boxy layout framework" tar
+ ((:url . "https://gitlab.com/tygrdev/boxy.el")
+ (:keywords "tools")
+ (:maintainer "Tyler Grinn" . "tylergrinn@gmail.com")
+ (:authors
+ ("Tyler Grinn" . "tylergrinn@gmail.com"))
+ (:commit . "3a949d5b14349f33f27bc5041178445a0fedcc6c"))])
+ (boxy-headings .
+ [(2 1 2)
+ ((emacs
+ (26 1))
+ (boxy
+ (1 0))
+ (org
+ (9 3)))
+ "View org files in a boxy diagram" tar
+ ((:url . "https://gitlab.com/tygrdev/boxy-headings")
+ (:keywords "tools")
+ (:maintainer "Tyler Grinn" . "tylergrinn@gmail.com")
+ (:authors
+ ("Tyler Grinn" . "tylergrinn@gmail.com")))])
+ (brief .
+ [(5 87)
+ nil "Brief Editor Emulator (Brief Mode)" tar
+ ((:maintainer "Luke Lee" . "luke.yx.lee@gmail.com")
+ (:authors
+ ("Luke Lee" . "luke.yx.lee@gmail.com"))
+ (:keywords "brief" "emulations" "crisp")
+ (:url . "http://elpa.gnu.org/packages/brief.html"))])
+ (buffer-env .
+ [(0 3)
+ ((emacs
+ (27 1)))
+ "Buffer-local process environments" tar
+ ((:url . "https://github.com/astoff/buffer-env")
+ (:keywords "processes" "tools")
+ (:maintainer "Augusto Stoffel" . "arstoffel@gmail.com")
+ (:authors
+ ("Augusto Stoffel" . "arstoffel@gmail.com"))
+ (:commit . "ba1c9d24d3f1ba58445cbf1f762ba6859b66f6bf"))])
+ (buffer-expose .
+ [(0 4 3)
+ ((emacs
+ (25))
+ (cl-lib
+ (0 5)))
+ "Visual buffer switching using a window grid" single
+ ((:keywords "convenience")
+ (:authors
+ ("Clemens Radermacher" . "clemera@posteo.net"))
+ (:maintainer "Clemens Radermacher" . "clemera@posteo.net")
+ (:url . "https://github.com/clemera/buffer-expose"))])
+ (bug-hunter .
+ [(1 3 1)
+ ((seq
+ (1 3))
+ (cl-lib
+ (0 5)))
+ "Hunt down errors by bisecting elisp files" tar
+ ((:url . "https://github.com/Malabarba/elisp-bug-hunter")
+ (:maintainer "Artur Malabarba" . "emacs@endlessparentheses.com")
+ (:authors
+ ("Artur Malabarba" . "emacs@endlessparentheses.com"))
+ (:keywords "lisp"))])
+ (cape .
+ [(0 7)
+ ((emacs
+ (27 1)))
+ "Completion At Point Extensions" tar
+ ((:url . "https://github.com/minad/cape")
+ (:maintainer "Daniel Mendler" . "mail@daniel-mendler.de")
+ (:authors
+ ("Daniel Mendler" . "mail@daniel-mendler.de"))
+ (:commit . "51b9bf1276445faebfbad636d9b6a39dc57b22bc"))])
+ (capf-autosuggest .
+ [(0 3)
+ ((emacs
+ (25 1)))
+ "History autosuggestions for comint and eshell" tar
+ ((:url . "https://repo.or.cz/emacs-capf-autosuggest.git")
+ (:maintainer "jakanakaevangeli" . "jakanakaevangeli@chiru.no")
+ (:authors
+ ("jakanakaevangeli" . "jakanakaevangeli@chiru.no")))])
+ (caps-lock .
+ [(1 0)
+ nil "Caps-lock as a minor mode" single
+ ((:url . "http://elpa.gnu.org/packages/caps-lock.html")
+ (:authors
+ ("Stefan Monnier" . "monnier@iro.umontreal.ca"))
+ (:maintainer "Stefan Monnier" . "monnier@iro.umontreal.ca"))])
+ (captain .
+ [(1 0 3)
+ nil "CAPiTalization is Automatic IN emacs" single
+ ((:url . "http://elpa.gnu.org/packages/captain.html")
+ (:keywords "editing")
+ (:authors
+ ("Ian Dunn" . "dunni@gnu.org"))
+ (:maintainer "Ian Dunn" . "dunni@gnu.org"))])
+ (chess .
+ [(2 0 5)
+ ((cl-lib
+ (0 5)))
+ "Play chess in GNU Emacs" tar
+ ((:maintainer "Mario Lang" . "mlang@delysid.org")
+ (:authors
+ ("John Wiegley" . "johnw@gnu.org"))
+ (:keywords "games")
+ (:url . "http://elpa.gnu.org/packages/chess.html"))])
+ (cl-generic .
+ [(0 3)
+ nil "Forward cl-generic compatibility for Emacs<25" single
+ ((:url . "http://elpa.gnu.org/packages/cl-generic.html")
+ (:authors
+ ("Stefan Monnier" . "monnier@iro.umontreal.ca"))
+ (:maintainer "Stefan Monnier" . "monnier@iro.umontreal.ca"))])
+ (cl-lib .
+ [(0 7)
+ nil "Forward cl-lib compatibility library for Emacs<24.3" tar
+ ((:maintainer "Stefan Monnier" . "monnier@iro.umontreal.ca")
+ (:authors
+ ("Stefan Monnier" . "monnier@iro.umontreal.ca"))
+ (:url . "https://elpa.gnu.org/packages/cl-lib.html"))])
+ (cl-print .
+ [(1 0)
+ ((emacs
+ (25)))
+ "CL-style generic printing" single
+ ((:url . "http://elpa.gnu.org/packages/cl-print.html")
+ (:authors
+ ("Stefan Monnier" . "monnier@iro.umontreal.ca"))
+ (:maintainer "Stefan Monnier" . "monnier@iro.umontreal.ca"))])
+ (clipboard-collector .
+ [(0 3)
+ ((emacs
+ (25)))
+ "Collect clipboard entries according to regex rules" tar
+ ((:url . "https://github.com/clemera/clipboard-collector")
+ (:maintainer "Clemens Radermacher" . "clemera@posteo.net")
+ (:authors
+ ("Clemens Radermacher" . "clemera@posteo.net"))
+ (:keywords "convenience"))])
+ (cobol-mode .
+ [(1 0 0)
+ ((cl-lib
+ (0 5)))
+ "Mode for editing COBOL code" single
+ ((:url . "http://elpa.gnu.org/packages/cobol-mode.html")
+ (:keywords "languages")
+ (:authors
+ ("Edward Hart" . "edward.dan.hart@gmail.com"))
+ (:maintainer "Edward Hart" . "edward.dan.hart@gmail.com"))])
+ (code-cells .
+ [(0 2)
+ ((emacs
+ (27 1)))
+ "Lightweight notebooks with support for ipynb files" tar
+ ((:url . "https://github.com/astoff/code-cells.el")
+ (:keywords "convenience" "outlines")
+ (:maintainer "Augusto Stoffel" . "arstoffel@gmail.com")
+ (:authors
+ ("Augusto Stoffel" . "arstoffel@gmail.com"))
+ (:commit . "ea7799c447066fee78c4efbafbdaf09520c7109d"))])
+ (coffee-mode .
+ [(0 4 1 1)
+ nil "Major mode for CoffeeScript files" single
+ ((:keywords "coffeescript" "major" "mode")
+ (:authors
+ ("Chris Wanstrath" . "chris@ozmm.org"))
+ (:maintainer "Chris Wanstrath" . "chris@ozmm.org")
+ (:url . "http://github.com/defunkt/coffee-mode"))])
+ (comint-mime .
+ [(0 1)
+ ((emacs
+ (28 1)))
+ "Display content of various MIME types in comint buffers" tar
+ ((:url . "https://github.com/astoff/comint-mime")
+ (:keywords "processes" "multimedia")
+ (:maintainer "Augusto Stoffel" . "arstoffel@gmail.com")
+ (:authors
+ ("Augusto Stoffel" . "arstoffel@gmail.com"))
+ (:commit . "2ac67834d9bb8e6a3521d75b934a4b496a3a0f9d"))])
+ (compact-docstrings .
+ [(0 2)
+ nil "Shrink blank lines in docstrings and doc comments" single
+ ((:keywords "convenience" "faces" "lisp" "maint" "c")
+ (:authors
+ ("Clément Pit-Claudel" . "clement.pitclaudel@live.com"))
+ (:maintainer "Clément Pit-Claudel" . "clement.pitclaudel@live.com")
+ (:url . "https://github.com/cpitclaudel/compact-docstrings"))])
+ (company .
+ [(0 9 13)
+ ((emacs
+ (24 3)))
+ "Modular text completion framework" tar
+ ((:url . "http://company-mode.github.io/")
+ (:maintainer "Dmitry Gutov" . "dgutov@yandex.ru")
+ (:authors
+ ("Nikolaj Schumacher"))
+ (:keywords "abbrev" "convenience" "matching"))])
+ (company-ebdb .
+ [(1 1)
+ ((company
+ (0 9 4))
+ (ebdb
+ (0 2)))
+ "company-mode completion backend for EBDB in message-mode" single
+ ((:url . "http://elpa.gnu.org/packages/company-ebdb.html")
+ (:authors
+ ("Jan Tatarik" . "jan.tatarik@gmail.com"))
+ (:maintainer "Eric Abrahamsen" . "eric@ericabrahamsen.net"))])
+ (company-math .
+ [(1 4)
+ ((company
+ (0 8 0))
+ (math-symbol-lists
+ (1 3)))
+ "Completion backends for unicode math symbols and latex tags" tar
+ ((:url . "https://github.com/vspinu/company-math")
+ (:maintainer "Vitalie Spinu" . "spinuvit@gmail.com")
+ (:authors
+ ("Vitalie Spinu" . "spinuvit@gmail.com"))
+ (:keywords "unicode" "symbols" "completion"))])
+ (company-statistics .
+ [(0 2 3)
+ ((emacs
+ (24 3))
+ (company
+ (0 8 5)))
+ "Sort candidates using completion history" tar
+ ((:url . "https://github.com/company-mode/company-statistics")
+ (:maintainer "Ingo Lohmar" . "i.lohmar@gmail.com")
+ (:authors
+ ("Ingo Lohmar" . "i.lohmar@gmail.com"))
+ (:keywords "abbrev" "convenience" "matching"))])
+ (compat .
+ [(28 1 1 0)
+ ((emacs
+ (24 3))
+ (nadvice
+ (0 3)))
+ "Compatibility Library" tar
+ ((:url . "https://sr.ht/~pkal/compat")
+ (:keywords "lisp")
+ (:maintainer "Compat Development" . "~pkal/compat-devel@lists.sr.ht")
+ (:authors
+ ("Philip Kaludercic" . "philipk@posteo.net"))
+ (:commit . "401df6defaf5ef470a2dc57664b2d258662a5c3d"))])
+ (consult .
+ [(0 17)
+ ((emacs
+ (27 1)))
+ "Consulting completing-read" tar
+ ((:url . "https://github.com/minad/consult")
+ (:maintainer "Daniel Mendler" . "mail@daniel-mendler.de")
+ (:authors
+ ("Daniel Mendler and Consult contributors"))
+ (:commit . "f517b70dd8a3be0b8c883633f2a7721448b40f0f"))])
+ (context-coloring .
+ [(8 1 0)
+ ((emacs
+ (24 3)))
+ "Highlight by scope" tar
+ ((:url . "https://github.com/jacksonrayhamilton/context-coloring")
+ (:maintainer "Jackson Ray Hamilton" . "jackson@jacksonrayhamilton.com")
+ (:authors
+ ("Jackson Ray Hamilton" . "jackson@jacksonrayhamilton.com"))
+ (:keywords "convenience" "faces" "tools"))])
+ (corfu .
+ [(0 22)
+ ((emacs
+ (27 1)))
+ "Completion Overlay Region FUnction" tar
+ ((:url . "https://github.com/minad/corfu")
+ (:maintainer "Daniel Mendler" . "mail@daniel-mendler.de")
+ (:authors
+ ("Daniel Mendler" . "mail@daniel-mendler.de"))
+ (:commit . "8591833f7dc76233dbe94b59c4eea9be6b4540f9"))])
+ (coterm .
+ [(1 5)
+ ((emacs
+ (26 1)))
+ "Terminal emulation for comint" tar
+ ((:url . "https://repo.or.cz/emacs-coterm.git")
+ (:keywords "processes")
+ (:maintainer "jakanakaevangeli" . "jakanakaevangeli@chiru.no")
+ (:authors
+ ("jakanakaevangeli" . "jakanakaevangeli@chiru.no"))
+ (:commit . "ef4b5fb55304266244c87d2c6aaefab58149da62"))])
+ (counsel .
+ [(0 13 4)
+ ((emacs
+ (24 5))
+ (ivy
+ (0 13 4))
+ (swiper
+ (0 13 4)))
+ "Various completion functions using Ivy" tar
+ ((:url . "https://github.com/abo-abo/swiper")
+ (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com")
+ (:authors
+ ("Oleh Krehel" . "ohwoeowho@gmail.com"))
+ (:keywords "convenience" "matching" "tools"))])
+ (cpio-mode .
+ [(0 17)
+ ((emacs
+ (24 5)))
+ "Handle cpio archives in the style of dired." tar
+ ((:maintainer "Douglas Lewan" . "d.lewan2000@gmail.com")
+ (:authors
+ ("Douglas Lewan" . "d.lewan2000@gmail.com"))
+ (:keywords "files")
+ (:url . "http://elpa.gnu.org/packages/cpio-mode.html"))])
+ (crdt .
+ [(0 2 7)
+ nil "Collaborative editing using Conflict-free Replicated Data Types" tar
+ ((:url . "https://code.librehq.com/qhong/crdt.el")
+ (:keywords "collaboration" "crdt")
+ (:maintainer "Qiantan Hong" . "qhong@alum.mit.edu")
+ (:authors
+ ("Qiantan Hong" . "qhong@alum.mit.edu")))])
+ (crisp .
+ [(1 3 6)
+ nil "CRiSP/Brief Emacs emulator" single
+ ((:url . "http://elpa.gnu.org/packages/crisp.html")
+ (:keywords "emulations" "brief" "crisp")
+ (:authors
+ ("Gary D. Foster" . "Gary.Foster@Corp.Sun.COM"))
+ (:maintainer "Luke Lee" . "luke.yx.lee@gmail.com"))])
+ (csharp-mode .
+ [(1 1 1)
+ ((emacs
+ (26 1)))
+ "C# mode derived mode" tar
+ ((:url . "https://github.com/emacs-csharp/csharp-mode")
+ (:keywords "c#" "languages" "oop" "mode")
+ (:maintainer "Jostein Kjønigsen" . "jostein@gmail.com")
+ (:authors
+ ("Theodor Thornhill" . "theo@thornhill.no")))])
+ (csv-mode .
+ [(1 19)
+ ((emacs
+ (24 1))
+ (cl-lib
+ (0 5)))
+ "Major mode for editing comma/char separated values" tar
+ ((:keywords "convenience")
+ (:maintainer nil . "emacs-devel@gnu.org")
+ (:authors
+ ("\"Francis J. Wright\"" . "F.J.Wright@qmul.ac.uk"))
+ (:url . "https://elpa.gnu.org/packages/csv-mode.html")
+ (:commit . "5c19624398bfd6b976cc9876db582e3e23611601"))])
+ (cursory .
+ [(0 1 4)
+ ((emacs
+ (27 1)))
+ "Manage cursor styles using presets" tar
+ ((:url . "https://git.sr.ht/~protesilaos/cursory")
+ (:keywords "convenience" "cursor")
+ (:maintainer "Protesilaos Stavrou" . "info@protesilaos.com")
+ (:authors
+ ("Protesilaos Stavrou" . "info@protesilaos.com"))
+ (:commit . "63c4b42ebe4446484bfb2a81b0b97ff65bcfbb3d"))])
+ (cycle-quotes .
+ [(0 1)
+ nil "Cycle between quote styles" tar
+ ((:maintainer "Simen Heggestøyl" . "simenheg@gmail.com")
+ (:authors
+ ("Simen Heggestøyl" . "simenheg@gmail.com"))
+ (:keywords "convenience")
+ (:url . "http://elpa.gnu.org/packages/cycle-quotes.html"))])
+ (darkroom .
+ [(0 3)
+ ((cl-lib
+ (0 5)))
+ "Remove visual distractions and focus on writing" single
+ ((:url . "http://elpa.gnu.org/packages/darkroom.html")
+ (:keywords "convenience" "emulations")
+ (:authors
+ ("João Távora" . "joaotavora@gmail.com"))
+ (:maintainer "João Távora" . "joaotavora@gmail.com"))])
+ (dash .
+ [(2 19 1)
+ ((emacs
+ (24)))
+ "A modern list library for Emacs" tar
+ ((:url . "https://github.com/magnars/dash.el")
+ (:maintainer "Magnar Sveen" . "magnars@gmail.com")
+ (:authors
+ ("Magnar Sveen" . "magnars@gmail.com"))
+ (:keywords "extensions" "lisp"))])
+ (dbus-codegen .
+ [(0 1)
+ ((cl-lib
+ (0 5)))
+ "Lisp code generation for D-Bus." single
+ ((:url . "http://elpa.gnu.org/packages/dbus-codegen.html")
+ (:keywords "comm" "dbus" "convenience")
+ (:authors
+ ("Daiki Ueno" . "ueno@gnu.org"))
+ (:maintainer nil . "emacs-devel@gnu.org"))])
+ (debbugs .
+ [(0 32)
+ ((emacs
+ (26 1))
+ (soap-client
+ (3 1 5)))
+ "SOAP library to access debbugs servers" tar
+ ((:keywords "comm" "hypermedia")
+ (:maintainer "Michael Albinus" . "michael.albinus@gmx.de")
+ (:authors
+ ("Michael Albinus" . "michael.albinus@gmx.de"))
+ (:url . "https://elpa.gnu.org/packages/debbugs.html")
+ (:commit . "a35646a9798226b8630fbd7a0691edc78ccd92b3"))])
+ (delight .
+ [(1 7)
+ ((cl-lib
+ (0 5))
+ (nadvice
+ (0 3)))
+ "A dimmer switch for your lighter text" single
+ ((:keywords "convenience")
+ (:authors
+ ("Phil Sainty" . "psainty@orcon.net.nz"))
+ (:maintainer "Phil Sainty" . "psainty@orcon.net.nz")
+ (:url . "https://savannah.nongnu.org/projects/delight"))])
+ (devdocs .
+ [(0 4)
+ ((emacs
+ (27 1)))
+ "Emacs viewer for DevDocs" tar
+ ((:url . "https://github.com/astoff/devdocs.el")
+ (:keywords "help")
+ (:maintainer "Augusto Stoffel" . "arstoffel@gmail.com")
+ (:authors
+ ("Augusto Stoffel" . "arstoffel@gmail.com"))
+ (:commit . "cdc1a7cc3f05235883ffb098fe1c5a8963ed06e2"))])
+ (dict-tree .
+ [(0 16)
+ ((trie
+ (0 3))
+ (tNFA
+ (0 1 1))
+ (heap
+ (0 3)))
+ "Dictionary data structure" tar
+ ((:url . "http://www.dr-qubit.org/emacs.php")
+ (:maintainer "Toby Cubitt" . "toby-predictive@dr-qubit.org")
+ (:authors
+ ("Toby Cubitt" . "toby-predictive@dr-qubit.org"))
+ (:keywords "extensions" "matching" "data structures trie" "tree" "dictionary" "completion" "regexp"))])
+ (diff-hl .
+ [(1 8 8)
+ ((cl-lib
+ (0 2))
+ (emacs
+ (24 3)))
+ "Highlight uncommitted changes using VC" tar
+ ((:url . "https://github.com/dgutov/diff-hl")
+ (:maintainer "Dmitry Gutov" . "dgutov@yandex.ru")
+ (:authors
+ ("Dmitry Gutov" . "dgutov@yandex.ru"))
+ (:keywords "vc" "diff"))])
+ (diffview .
+ [(1 0)
+ nil "View diffs in side-by-side format" single
+ ((:keywords "convenience" "diff")
+ (:authors
+ ("Mitchel Humpherys" . "mitch.special@gmail.com"))
+ (:maintainer "Mitchel Humpherys" . "mitch.special@gmail.com")
+ (:url . "https://github.com/mgalgs/diffview-mode"))])
+ (diminish .
+ [(0 46)
+ ((emacs
+ (24 3)))
+ "Diminished modes are minor modes with no modeline display" tar
+ ((:url . "https://github.com/myrjola/diminish.el")
+ (:keywords "extensions" "diminish" "minor" "codeprose")
+ (:maintainer "Martin Yrjölä" . "martin.yrjola@gmail.com")
+ (:authors
+ ("Will Mengarini" . "seldon@eskimo.com"))
+ (:commit . "66b3902401059d161424b1b8d0abc3cb0a7d6df0"))])
+ (dired-du .
+ [(0 5 2)
+ ((emacs
+ (24 4))
+ (cl-lib
+ (0 5)))
+ "Dired with recursive directory sizes" tar
+ ((:maintainer "Tino Calancha" . "tino.calancha@gmail.com")
+ (:authors
+ ("Tino Calancha" . "tino.calancha@gmail.com"))
+ (:keywords "files" "unix" "convenience")
+ (:url . "http://elpa.gnu.org/packages/dired-du.html"))])
+ (dired-git-info .
+ [(0 3 1)
+ ((emacs
+ (25)))
+ "Show git info in dired" single
+ ((:keywords "dired" "files")
+ (:authors
+ ("Clemens Radermacher" . "clemera@posteo.net"))
+ (:maintainer "Clemens Radermacher" . "clemera@posteo.net")
+ (:url . "https://github.com/clemera/dired-git-info"))])
+ (disk-usage .
+ [(1 3 3)
+ ((emacs
+ (26 1)))
+ "Sort and browse disk usage listings" single
+ ((:keywords "files" "convenience" "tools")
+ (:authors
+ ("Pierre Neidhardt" . "mail@ambrevar.xyz"))
+ (:maintainer "Pierre Neidhardt" . "mail@ambrevar.xyz")
+ (:url . "https://gitlab.com/Ambrevar/emacs-disk-usage"))])
+ (dismal .
+ [(1 5 2)
+ ((cl-lib
+ (0))
+ (emacs
+ (24 3)))
+ "Dis Mode Ain't Lotus: Spreadsheet program Emacs" tar
+ ((:maintainer "UnMaintainer" . "emacs-devel@gnu.org")
+ (:authors
+ (nil . "David Fox, fox@cs.nyu.edu")
+ (nil . "Frank E. Ritter, ritter@cs.cmu.edu"))
+ (:url . "https://elpa.gnu.org/packages/dismal.html"))])
+ (djvu .
+ [(1 1 2)
+ nil "Edit and view Djvu files via djvused" tar
+ ((:keywords "files" "wp")
+ (:maintainer "Roland Winkler" . "winkler@gnu.org")
+ (:authors
+ ("Roland Winkler" . "winkler@gnu.org"))
+ (:url . "https://elpa.gnu.org/packages/djvu.html")
+ (:commit . "071c8ab168588897475899c46eaa16e70141db8c"))])
+ (docbook .
+ [(0 1)
+ nil "Info-like viewer for DocBook" single
+ ((:url . "http://elpa.gnu.org/packages/docbook.html")
+ (:keywords "docs" "help")
+ (:authors
+ ("Chong Yidong" . "cyd@gnu.org"))
+ (:maintainer "Chong Yidong" . "cyd@gnu.org"))])
+ (dtache .
+ [(0 6)
+ ((emacs
+ (27 1)))
+ "Run and interact with detached shell commands" tar
+ ((:url . "https://www.gitlab.com/niklaseklund/dtache.git")
+ (:keywords "convenience" "processes")
+ (:maintainer "Niklas Eklund" . "niklas.eklund@posteo.net")
+ (:authors
+ ("Niklas Eklund" . "niklas.eklund@posteo.net"))
+ (:commit . "4ecda689e4ccddc23805a22484c95c4f3f65e3bb"))])
+ (dts-mode .
+ [(1 0)
+ ((emacs
+ (24)))
+ "Major mode for Device Tree source files" tar
+ ((:keywords "languages")
+ (:maintainer "Ben Gamari" . "ben@smart-cactus.org")
+ (:authors
+ ("Ben Gamari" . "ben@smart-cactus.org"))
+ (:url . "https://elpa.gnu.org/packages/dts-mode.html")
+ (:commit . "8413d2dc9b3347831aa9e8c8b2524af3ef005441"))])
+ (easy-escape .
+ [(0 2 1)
+ nil "Improve readability of escape characters in regular expressions" tar
+ ((:url . "https://github.com/cpitclaudel/easy-escape")
+ (:keywords "convenience" "lisp" "tools")
+ (:maintainer "Clément Pit-Claudel" . "clement.pitclaudel@live.com")
+ (:authors
+ ("Clément Pit-Claudel" . "clement.pitclaudel@live.com")))])
+ (easy-kill .
+ [(0 9 5)
+ ((emacs
+ (25))
+ (cl-lib
+ (0 5)))
+ "kill & mark things easily" tar
+ ((:url . "https://github.com/leoliu/easy-kill")
+ (:keywords "killing" "convenience")
+ (:maintainer "Leo Liu" . "sdl.web@gmail.com")
+ (:authors
+ ("Leo Liu" . "sdl.web@gmail.com"))
+ (:commit . "f155d19c528e27f8f6c72f0d75f652edbdcab37f"))])
+ (ebdb .
+ [(0 8 14)
+ ((emacs
+ (25 1))
+ (seq
+ (2 15)))
+ "Contact management package" tar
+ ((:url . "https://github.com/girzel/ebdb")
+ (:keywords "convenience" "mail")
+ (:maintainer "Eric Abrahamsen" . "eric@ericabrahamsen.net")
+ (:authors
+ ("Eric Abrahamsen" . "eric@ericabrahamsen.net"))
+ (:commit . "c98512ebb6984701bbf090f1eabedb120c51e7bd"))])
+ (ebdb-gnorb .
+ [(1 0 2)
+ ((gnorb
+ (1 1 0))
+ (ebdb
+ (0 2)))
+ "Utilities for connecting EBDB to Gnorb" single
+ ((:url . "http://elpa.gnu.org/packages/ebdb-gnorb.html")
+ (:authors
+ ("Eric Abrahamsen" . "eric@ericabrahamsen.net"))
+ (:maintainer "Eric Abrahamsen" . "eric@ericabrahamsen.net"))])
+ (ebdb-i18n-chn .
+ [(1 3 2)
+ ((pyim
+ (1 6 0))
+ (ebdb
+ (0 6 17)))
+ "China-specific internationalization support for EBDB" tar
+ ((:maintainer "Eric Abrahamsen" . "eric@ericabrahamsen.net")
+ (:authors
+ ("Eric Abrahamsen" . "eric@ericabrahamsen.net"))
+ (:url . "https://elpa.gnu.org/packages/ebdb-i18n-chn.html"))])
+ (ediprolog .
+ [(2 1)
+ nil "Emacs Does Interactive Prolog" single
+ ((:keywords "languages" "processes")
+ (:authors
+ ("Markus Triska" . "triska@metalevel.at"))
+ (:maintainer "Markus Triska" . "triska@metalevel.at")
+ (:url . "https://www.metalevel.at/ediprolog/"))])
+ (eev .
+ [(20220416)
+ ((emacs
+ (24 4)))
+ "Support for e-scripts (eepitch blocks, elisp hyperlinks, etc)" tar
+ ((:url . "http://angg.twu.net/#eev")
+ (:keywords "lisp" "e-scripts")
+ (:maintainer "Eduardo Ochs" . "eduardoochs@gmail.com")
+ (:authors
+ ("Eduardo Ochs" . "eduardoochs@gmail.com"))
+ (:commit . "84a0b6e6bb247efcb519c1e32de172aa55e184c7"))])
+ (eglot .
+ [(1 8)
+ ((emacs
+ (26 1))
+ (jsonrpc
+ (1 0 14))
+ (flymake
+ (1 0 9))
+ (project
+ (0 3 0))
+ (xref
+ (1 0 1))
+ (eldoc
+ (1 11 0)))
+ "Client for Language Server Protocol (LSP) servers" tar
+ ((:url . "https://github.com/joaotavora/eglot")
+ (:keywords "convenience" "languages")
+ (:maintainer "João Távora" . "joaotavora@gmail.com")
+ (:authors
+ ("João Távora" . "joaotavora@gmail.com"))
+ (:commit . "132ea08f97f94ad2e050fc8d1628ecb41de7229a"))])
+ (el-search .
+ [(1 12 6 1)
+ ((emacs
+ (25))
+ (stream
+ (2 2 4))
+ (cl-print
+ (1 0)))
+ "Expression based interactive search for Emacs Lisp" tar
+ ((:maintainer "Michael Heerdegen" . "michael_heerdegen@web.de")
+ (:authors
+ ("Michael Heerdegen" . "michael_heerdegen@web.de"))
+ (:keywords "lisp")
+ (:url . "http://elpa.gnu.org/packages/el-search.html"))])
+ (eldoc .
+ [(1 11 1)
+ ((emacs
+ (26 3)))
+ "Show function arglist or variable docstring in echo area" tar
+ ((:keywords "extensions")
+ (:maintainer "Noah Friedman" . "friedman@splode.com")
+ (:authors
+ ("Noah Friedman" . "friedman@splode.com"))
+ (:url . "https://elpa.gnu.org/packages/eldoc.html")
+ (:commit . "45978f97be89ae989ecf9e7129b88592e70a1f24"))])
+ (eldoc-eval .
+ [(0 2)
+ nil "Enable eldoc support when minibuffer is in use." tar
+ ((:maintainer "Thierry Volpiatto" . "thievol@posteo.net")
+ (:authors
+ ("Thierry Volpiatto" . "thievol@posteo.net"))
+ (:url . "https://elpa.gnu.org/packages/eldoc-eval.html")
+ (:commit . "e91800503c90cb75dc70abe42f1d6ae499346cc1"))])
+ (electric-spacing .
+ [(5 0)
+ nil "Insert operators with surrounding spaces smartly" single
+ ((:url . "http://elpa.gnu.org/packages/electric-spacing.html")
+ (:authors
+ ("William Xu" . "william.xwl@gmail.com"))
+ (:maintainer "William Xu" . "william.xwl@gmail.com"))])
+ (elisp-benchmarks .
+ [(1 14)
+ nil "elisp benchmarks collection" tar
+ ((:keywords "languages" "lisp")
+ (:maintainer "Andrea Corallo" . "akrl@sdf.org")
+ (:authors
+ ("Andrea Corallo" . "akrl@sdf.org"))
+ (:url . "https://elpa.gnu.org/packages/elisp-benchmarks.html")
+ (:commit . "70e38dbfa8f4acbdebfd0f417410d99f5031e05f"))])
+ (embark .
+ [(0 16)
+ ((emacs
+ (26 1)))
+ "Conveniently act on minibuffer completions" tar
+ ((:url . "https://github.com/oantolin/embark")
+ (:keywords "convenience")
+ (:maintainer "Omar Antolín Camarena" . "omar@matem.unam.mx")
+ (:authors
+ ("Omar Antolín Camarena" . "omar@matem.unam.mx"))
+ (:commit . "5faf1389162dd64bfe3511dfb8f52c18efb5140b"))])
+ (embark-consult .
+ [(0 5)
+ ((emacs
+ (26 1))
+ (embark
+ (0 12))
+ (consult
+ (0 10)))
+ "Consult integration for Embark" tar
+ ((:url . "https://github.com/oantolin/embark")
+ (:keywords "convenience")
+ (:maintainer "Omar Antolín Camarena" . "omar@matem.unam.mx")
+ (:authors
+ ("Omar Antolín Camarena" . "omar@matem.unam.mx"))
+ (:commit . "5faf1389162dd64bfe3511dfb8f52c18efb5140b"))])
+ (emms .
+ [(10)
+ ((cl-lib
+ (0 5))
+ (nadvice
+ (0 3))
+ (seq
+ (0)))
+ "The Emacs Multimedia System" tar
+ ((:url . "https://www.gnu.org/software/emms/")
+ (:keywords "emms" "mp3" "ogg" "flac" "music" "mpeg" "video" "multimedia")
+ (:maintainer "Yoni Rabkin" . "yrk@gnu.org")
+ (:authors
+ ("Jorgen Schäfer" . "forcer@forcix.cx"))
+ (:commit . "6afe1b26d679357586380ecd69c9795985231013"))])
+ (engrave-faces .
+ [(0 2 0)
+ ((emacs
+ (27 1)))
+ "Convert font-lock faces to other formats" tar
+ ((:url . "https://github.com/tecosaur/engrave-faces")
+ (:maintainer "TEC" . "tec@tecosaur.com")
+ (:authors
+ ("TEC <https://github/tecosaur>"))
+ (:keywords "faces"))])
+ (enwc .
+ [(2 0)
+ ((emacs
+ (25 1)))
+ "The Emacs Network Client" tar
+ ((:url . "https://savannah.nongnu.org/p/enwc")
+ (:maintainer "Ian Dunn" . "dunni@gnu.org")
+ (:authors
+ ("Ian Dunn" . "dunni@gnu.org"))
+ (:keywords "external" "network" "wicd" "manager" "nm"))])
+ (epoch-view .
+ [(0 0 1)
+ nil "Minor mode to visualize epoch timestamps" single
+ ((:url . "http://elpa.gnu.org/packages/epoch-view.html")
+ (:keywords "data" "timestamp" "epoch" "unix")
+ (:authors
+ ("Ted Zlatanov" . "tzz@lifelogs.com"))
+ (:maintainer "Ted Zlatanov" . "tzz@lifelogs.com"))])
+ (erc .
+ [(5 4 1)
+ ((emacs
+ (27 1)))
+ "An Emacs Internet Relay Chat client" tar
+ ((:url . "https://www.gnu.org/software/emacs/erc.html")
+ (:keywords "irc" "chat" "client" "internet")
+ (:maintainer "Amin Bandali" . "bandali@gnu.org")
+ (:authors
+ ("Alexander L. Belikoff" . "alexander@belikoff.net")))])
+ (ergoemacs-mode .
+ [(5 16 10 12)
+ ((emacs
+ (24 1))
+ (undo-tree
+ (0 6 5))
+ (cl-lib
+ (0 5)))
+ "Emacs mode based on common modern interface and ergonomics." tar
+ ((:url . "https://github.com/ergoemacs/ergoemacs-mode")
+ (:maintainer "Matthew L. Fidler" . "matthew.fidler@gmail.com")
+ (:authors
+ ("Xah Lee" . "xah@xahlee.org")
+ ("David Capello" . "davidcapello@gmail.com")
+ ("Matthew L. Fidler" . "matthew.fidler@gmail.com"))
+ (:keywords "convenience"))])
+ (excorporate .
+ [(1 0 0)
+ ((emacs
+ (24 1))
+ (cl-lib
+ (0 6 1))
+ (fsm
+ (0 2 1))
+ (soap-client
+ (3 2 0))
+ (url-http-ntlm
+ (2 0 4))
+ (nadvice
+ (0 3)))
+ "Exchange Web Services (EWS) integration" tar
+ ((:url . "https://www.fitzsim.org/blog/")
+ (:maintainer "Thomas Fitzsimmons" . "fitzsim@fitzsim.org")
+ (:authors
+ ("Thomas Fitzsimmons" . "fitzsim@fitzsim.org"))
+ (:keywords "calendar"))])
+ (expand-region .
+ [(0 11 0)
+ nil "Increase selected region by semantic units." tar
+ ((:url . "https://github.com/magnars/expand-region.el")
+ (:maintainer "Magnar Sveen" . "magnars@gmail.com")
+ (:authors
+ ("Magnar Sveen" . "magnars@gmail.com"))
+ (:keywords "marking" "region"))])
+ (exwm .
+ [(0 26)
+ ((xelb
+ (0 18)))
+ "Emacs X Window Manager" tar
+ ((:url . "https://github.com/ch11ng/exwm")
+ (:keywords "unix")
+ (:maintainer "Adrián Medraño Calvo" . "adrian@medranocalvo.com")
+ (:authors
+ ("Chris Feng" . "chris.w.feng@gmail.com")))])
+ (f90-interface-browser .
+ [(1 1)
+ nil "Parse and browse f90 interfaces" single
+ ((:authors
+ ("Lawrence Mitchell" . "wence@gmx.li"))
+ (:maintainer "Lawrence Mitchell" . "wence@gmx.li")
+ (:url . "http://github.com/wence-/f90-iface/"))])
+ (filladapt .
+ [(2 12 2)
+ ((emacs
+ (24 4)))
+ "Adaptive fill" single
+ ((:url . "http://elpa.gnu.org/packages/filladapt.html")
+ (:authors
+ ("Kyle E. Jones" . "kyle_jones@wonderworks.com"))
+ (:maintainer nil . "emacs-devel@gnu.org"))])
+ (flylisp .
+ [(0 2)
+ ((emacs
+ (24 1))
+ (cl-lib
+ (0 4)))
+ "Color unbalanced parentheses and parentheses inconsistent with indentation" single
+ ((:url . "http://elpa.gnu.org/packages/flylisp.html")
+ (:authors
+ ("Barry O'Reilly" . "gundaetiapo@gmail.com"))
+ (:maintainer "Barry O'Reilly" . "gundaetiapo@gmail.com"))])
+ (flymake .
+ [(1 2 2)
+ ((emacs
+ (26 1))
+ (eldoc
+ (1 1 0))
+ (project
+ (0 7 1)))
+ "A universal on-the-fly syntax checker" tar
+ ((:keywords "c" "languages" "tools")
+ (:maintainer "João Távora" . "joaotavora@gmail.com")
+ (:authors
+ ("Pavel Kobyakov" . "pk_at_work@yahoo.com"))
+ (:url . "https://elpa.gnu.org/packages/flymake.html")
+ (:commit . "31af9bca99fa88350271e1a905c9b435eaec28cf"))])
+ (flymake-proselint .
+ [(0 2 3)
+ ((emacs
+ (26 1)))
+ "Flymake backend for proselint" tar
+ ((:url . "https://github.com/manuel-uberti/flymake-proselint")
+ (:keywords "convenience")
+ (:maintainer "Manuel Uberti" . "manuel.uberti@inventati.org")
+ (:authors
+ ("Manuel Uberti" . "manuel.uberti@inventati.org")))])
+ (fontaine .
+ [(0 1 1)
+ ((emacs
+ (27 1)))
+ "Set font configurations using presets" tar
+ ((:url . "https://git.sr.ht/~protesilaos/fontaine")
+ (:maintainer "Protesilaos Stavrou" . "info@protesilaos.com")
+ (:authors
+ ("Protesilaos Stavrou" . "info@protesilaos.com"))
+ (:commit . "e8e25d681854a97483a5ca3a0c39f04aaa19b1a0"))])
+ (frame-tabs .
+ [(1 1)
+ nil "show buffer tabs in side window" single
+ ((:url . "http://elpa.gnu.org/packages/frame-tabs.html")
+ (:keywords "frames" "tabs")
+ (:authors
+ ("Martin Rudalics" . "rudalics@gmx.at"))
+ (:maintainer "Martin Rudalics" . "rudalics@gmx.at"))])
+ (frog-menu .
+ [(0 2 11)
+ ((emacs
+ (26))
+ (avy
+ (0 4))
+ (posframe
+ (0 4)))
+ "Quickly pick items from ad hoc menus" single
+ ((:keywords "convenience")
+ (:authors
+ ("Clemens Radermacher" . "clemera@posteo.net"))
+ (:maintainer "Clemens Radermacher" . "clemera@posteo.net")
+ (:url . "https://github.com/clemera/frog-menu"))])
+ (fsm .
+ [(0 2 1)
+ ((emacs
+ (24 1))
+ (cl-lib
+ (0 5)))
+ "state machine library" single
+ ((:url . "http://elpa.gnu.org/packages/fsm.html")
+ (:keywords "extensions")
+ (:authors
+ ("Magnus Henoch" . "magnus.henoch@gmail.com"))
+ (:maintainer "Thomas Fitzsimmons" . "fitzsim@fitzsim.org"))])
+ (ftable .
+ [(1 0)
+ ((emacs
+ (26 0)))
+ "Fill a table to fit in n columns" tar
+ ((:url . "https://github.com/casouri/ftable")
+ (:maintainer "Yuan Fu" . "casouri@gmail.com")
+ (:authors
+ ("Yuan Fu" . "casouri@gmail.com"))
+ (:keywords "convenience" "text" "table"))])
+ (gcmh .
+ [(0 2 1)
+ ((emacs
+ (24)))
+ "the Garbage Collector Magic Hack" single
+ ((:keywords "internal")
+ (:authors
+ ("Andrea Corallo" . "akrl@sdf.org"))
+ (:maintainer nil . "akrl@sdf.org")
+ (:url . "https://gitlab.com/koral/gcmh"))])
+ (ggtags .
+ [(0 9 0)
+ ((emacs
+ (25)))
+ "emacs frontend to GNU Global source code tagging system" tar
+ ((:url . "https://github.com/leoliu/ggtags")
+ (:maintainer "Leo Liu" . "sdl.web@gmail.com")
+ (:authors
+ ("Leo Liu" . "sdl.web@gmail.com"))
+ (:keywords "tools" "convenience"))])
+ (gited .
+ [(0 6 0)
+ ((emacs
+ (24 4))
+ (cl-lib
+ (0 5)))
+ "Operate on Git branches like dired" tar
+ ((:maintainer "Tino Calancha" . "tino.calancha@gmail.com")
+ (:authors
+ ("Tino Calancha" . "tino.calancha@gmail.com"))
+ (:keywords "git" "vc" "convenience")
+ (:url . "http://elpa.gnu.org/packages/gited.html"))])
+ (gle-mode .
+ [(1 1)
+ ((cl-lib
+ (0 5)))
+ "Major mode to edit Graphics Layout Engine files" single
+ ((:url . "http://elpa.gnu.org/packages/gle-mode.html")
+ (:authors
+ ("Stefan Monnier" . "monnier@iro.umontreal.ca"))
+ (:maintainer "Stefan Monnier" . "monnier@iro.umontreal.ca"))])
+ (gnome-c-style .
+ [(0 1)
+ nil "minor mode for editing GNOME-style C source code" tar
+ ((:maintainer "Daiki Ueno" . "ueno@gnu.org")
+ (:authors
+ ("Daiki Ueno" . "ueno@gnu.org"))
+ (:keywords "gnome" "c" "coding style")
+ (:url . "http://elpa.gnu.org/packages/gnome-c-style.html"))])
+ (gnorb .
+ [(1 6 10)
+ ((cl-lib
+ (0 5)))
+ "Glue code between Gnus, Org, and BBDB" tar
+ ((:keywords "mail" "org" "gnus" "bbdb" "todo" "task")
+ (:maintainer "Eric Abrahamsen" . "eric@ericabrahamsen.net")
+ (:authors
+ ("Eric Abrahamsen" . "eric@ericabrahamsen.net"))
+ (:url . "https://elpa.gnu.org/packages/gnorb.html"))])
+ (gnu-elpa .
+ [(1 1)
+ nil "Advertize GNU ELPA packages" tar
+ ((:maintainer "Stefan Monnier" . "monnier@iro.umontreal.ca")
+ (:authors
+ ("Stefan Monnier" . "monnier@iro.umontreal.ca"))
+ (:url . "http://elpa.gnu.org/packages/gnu-elpa.html"))])
+ (gnu-elpa-keyring-update .
+ [(2019 3)
+ nil "Update Emacs's GPG keyring for GNU ELPA" tar
+ ((:maintainer "Stefan Monnier" . "monnier@iro.umontreal.ca")
+ (:authors
+ ("Stefan Monnier" . "monnier@iro.umontreal.ca"))
+ (:keywords "maint" "tools")
+ (:url . "http://elpa.gnu.org/packages/gnu-elpa-keyring-update.html"))])
+ (gnugo .
+ [(3 1 2)
+ ((ascii-art-to-unicode
+ (1 5))
+ (xpm
+ (1 0 1))
+ (cl-lib
+ (0 5)))
+ "play GNU Go in a buffer" tar
+ ((:url . "https://www.gnuvola.org/software/gnugo/")
+ (:keywords "games" "processes")
+ (:maintainer "Thien-Thi Nguyen" . "ttn@gnu.org")
+ (:authors
+ ("Thien-Thi Nguyen" . "ttn@gnu.org")))])
+ (gnus-mock .
+ [(0 5)
+ nil "Mock Gnus installation for testing" tar
+ ((:maintainer "Eric Abrahamsen" . "eric@ericabrahamsen.net")
+ (:authors
+ ("Eric Abrahamsen" . "eric@ericabrahamsen.net"))
+ (:url . "https://elpa.gnu.org/packages/gnus-mock.html"))])
+ (gpastel .
+ [(0 5 0)
+ ((emacs
+ (25 1)))
+ "Integrates GPaste with the kill-ring" single
+ ((:keywords "tools")
+ (:authors
+ ("Damien Cassou" . "damien@cassou.me"))
+ (:maintainer "Damien Cassou" . "damien@cassou.me")
+ (:url . "https://gitlab.petton.fr/DamienCassou/desktop-environment"))])
+ (greader .
+ [(0 1)
+ ((emacs
+ (25)))
+ "gnamù reader, a reader with espeak tts" tar
+ ((:maintainer "Michelangelo Rodriguez" . "michelangelo.rodriguez@gmail.com")
+ (:authors
+ ("Michelangelo Rodriguez" . "michelangelo.rodriguez@gmail.com"))
+ (:keywords "tools" "accessibility")
+ (:url . "http://elpa.gnu.org/packages/greader.html"))])
+ (greenbar .
+ [(1 1)
+ nil "Mark comint output with \"greenbar\" background" single
+ ((:url . "http://elpa.gnu.org/packages/greenbar.html")
+ (:keywords "faces" "terminals")
+ (:authors
+ ("Michael R. Mauger" . "michael@mauger.com"))
+ (:maintainer "Michael R. Mauger" . "michael@mauger.com"))])
+ (gtags-mode .
+ [(1 0)
+ ((emacs
+ (28)))
+ "GNU Global integration with xref, project and imenu." tar
+ ((:url . "https://github.com/Ergus/gtags-mode")
+ (:keywords "xref" "project" "imenu" "gtags" "global")
+ (:maintainer "Jimmy Aguilar Mena")
+ (:authors
+ ("Jimmy Aguilar Mena"))
+ (:commit . "f108a46c6c03eb5e18c73a908c655071aa153a14"))])
+ (guess-language .
+ [(0 0 1)
+ ((cl-lib
+ (0 5))
+ (emacs
+ (24))
+ (nadvice
+ (0 1)))
+ "Robust automatic language detection" single
+ ((:authors
+ ("Titus von der Malsburg" . "malsburg@posteo.de"))
+ (:maintainer "Titus von der Malsburg" . "malsburg@posteo.de")
+ (:url . "https://github.com/tmalsburg/guess-language.el"))])
+ (heap .
+ [(0 5)
+ nil "Heap (a.k.a. priority queue) data structure" single
+ ((:keywords "extensions" "data structures" "heap" "priority queue")
+ (:authors
+ ("Toby Cubitt" . "toby-predictive@dr-qubit.org"))
+ (:maintainer "Toby Cubitt" . "toby-predictive@dr-qubit.org")
+ (:url . "http://www.dr-qubit.org/emacs.php"))])
+ (hiddenquote .
+ [(1 1)
+ ((emacs
+ (25 1)))
+ "Major mode for doing hidden quote puzzles" tar
+ ((:url . "http://mauroaranda.com/puzzles/hidden-quote-puzzle/")
+ (:maintainer "Mauro Aranda" . "maurooaranda@gmail.com")
+ (:authors
+ ("Mauro Aranda" . "maurooaranda@gmail.com"))
+ (:keywords "games"))])
+ (highlight-escape-sequences .
+ [(0 4)
+ nil "Highlight escape sequences" single
+ ((:keywords "convenience")
+ (:authors
+ ("Dmitry Gutov" . "dgutov@yandex.ru")
+ ("Pavel Matcula" . "dev.plvlml@gmail.com"))
+ (:maintainer "Dmitry Gutov" . "dgutov@yandex.ru")
+ (:url . "https://github.com/dgutov/highlight-escape-sequences"))])
+ (hook-helpers .
+ [(1 1 1)
+ ((emacs
+ (25 1)))
+ "Anonymous, modifiable hook functions" tar
+ ((:url . "https://savannah.nongnu.org/projects/hook-helpers-el/")
+ (:maintainer "Ian Dunn" . "dunni@gnu.org")
+ (:authors
+ ("Ian Dunn" . "dunni@gnu.org"))
+ (:keywords "development" "hooks"))])
+ (html5-schema .
+ [(0 1)
+ nil "Add HTML5 schemas for use by nXML" tar
+ ((:url . "https://github.com/validator/validator")
+ (:maintainer "Stefan Monnier" . "monnier@iro.umontreal.ca")
+ (:authors
+ ("Stefan Monnier" . "monnier@iro.umontreal.ca"))
+ (:keywords "html" "xml"))])
+ (hydra .
+ [(0 14 0)
+ ((cl-lib
+ (0 5)))
+ "Make bindings that stick around." tar
+ ((:url . "https://github.com/abo-abo/hydra")
+ (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com")
+ (:authors
+ ("Oleh Krehel" . "ohwoeowho@gmail.com"))
+ (:keywords "bindings"))])
+ (hyperbole .
+ [(8 0 0)
+ ((emacs
+ (27 0)))
+ "GNU Hyperbole: The Everyday Hypertextual Information Manager" tar
+ ((:url . "http://www.gnu.org/software/hyperbole")
+ (:keywords "comm" "convenience" "files" "frames" "hypermedia" "languages" "mail" "matching" "mouse" "multimedia" "outlines" "tools" "wp")
+ (:maintainer "Bob Weiner <rsw@gnu.org>, Mats Lidell" . "matsl@gnu.org")
+ (:authors
+ ("Bob Weiner"))
+ (:commit . "4214716e06920a3e10db5811bd22a343ad6435d9"))])
+ (ilist .
+ [(0 1)
+ nil "Display a list in an ibuffer way." tar
+ ((:keywords "convenience")
+ (:maintainer "Durand" . "mmemmew@gmail.com")
+ (:authors
+ ("Durand" . "mmemmew@gmail.com"))
+ (:url . "https://elpa.gnu.org/packages/ilist.html"))])
+ (ioccur .
+ [(2 6)
+ ((emacs
+ (24))
+ (cl-lib
+ (0 5)))
+ "Incremental occur" tar
+ ((:url . "https://github.com/thierryvolpiatto/ioccur")
+ (:maintainer "Thierry Volpiatto" . "thievol@posteo.net")
+ (:authors
+ ("Thierry Volpiatto" . "thievol@posteo.net")))])
+ (isearch-mb .
+ [(0 5)
+ ((emacs
+ (27 1)))
+ "Control isearch from the minibuffer" tar
+ ((:url . "https://github.com/astoff/isearch-mb")
+ (:keywords "matching")
+ (:maintainer "Augusto Stoffel" . "arstoffel@gmail.com")
+ (:authors
+ ("Augusto Stoffel" . "arstoffel@gmail.com"))
+ (:commit . "e70ba8f594afef989006493dd71bd693a29e9f42"))])
+ (iterators .
+ [(0 1 1)
+ ((emacs
+ (25)))
+ "Functions for working with iterators" single
+ ((:url . "http://elpa.gnu.org/packages/iterators.html")
+ (:keywords "extensions" "elisp")
+ (:authors
+ ("Michael Heerdegen" . "michael_heerdegen@web.de"))
+ (:maintainer "Michael Heerdegen" . "michael_heerdegen@web.de"))])
+ (ivy .
+ [(0 13 4)
+ ((emacs
+ (24 5)))
+ "Incremental Vertical completYon" tar
+ ((:url . "https://github.com/abo-abo/swiper")
+ (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com")
+ (:authors
+ ("Oleh Krehel" . "ohwoeowho@gmail.com"))
+ (:keywords "matching"))])
+ (ivy-avy .
+ [(0 13 4)
+ ((emacs
+ (24 5))
+ (ivy
+ (0 13 4))
+ (avy
+ (0 5 0)))
+ "Avy integration for Ivy" tar
+ ((:url . "https://github.com/abo-abo/swiper")
+ (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com")
+ (:authors
+ ("Oleh Krehel" . "ohwoeowho@gmail.com"))
+ (:keywords "convenience"))])
+ (ivy-explorer .
+ [(0 3 2)
+ ((emacs
+ (25))
+ (ivy
+ (0 10 0)))
+ "Dynamic file browsing grid using ivy" single
+ ((:keywords "convenience" "files" "matching")
+ (:authors
+ ("Clemens Radermacher" . "clemera@posteo.net"))
+ (:maintainer "Clemens Radermacher" . "clemera@posteo.net")
+ (:url . "https://github.com/clemera/ivy-explorer"))])
+ (ivy-hydra .
+ [(0 13 5)
+ ((emacs
+ (24 5))
+ (ivy
+ (0 13 4))
+ (hydra
+ (0 14 0)))
+ "Additional key bindings for Ivy" tar
+ ((:url . "https://github.com/abo-abo/swiper")
+ (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com")
+ (:authors
+ ("Oleh Krehel" . "ohwoeowho@gmail.com"))
+ (:keywords "convenience"))])
+ (ivy-posframe .
+ [(0 6 3)
+ ((emacs
+ (26 0))
+ (posframe
+ (1 0 0))
+ (ivy
+ (0 13 0)))
+ "Using posframe to show Ivy" tar
+ ((:url . "https://github.com/tumashu/ivy-posframe")
+ (:keywords "abbrev" "convenience" "matching" "ivy")
+ (:maintainer "Feng Shu" . "tumashu@163.com")
+ (:authors
+ ("Feng Shu" . "tumashu@163.com")
+ ("Naoya Yamashita" . "conao3@gmail.com")))])
+ (javaimp .
+ [(0 8)
+ nil "Add and reorder Java import statements in Maven/Gradle projects" tar
+ ((:keywords "java" "maven" "gradle" "programming")
+ (:maintainer "Filipp Gunbin" . "fgunbin@fastmail.fm")
+ (:authors
+ ("Filipp Gunbin" . "fgunbin@fastmail.fm"))
+ (:url . "https://elpa.gnu.org/packages/javaimp.html"))])
+ (jgraph-mode .
+ [(1 1)
+ ((cl-lib
+ (0 5)))
+ "Major mode for Jgraph files" single
+ ((:url . "http://elpa.gnu.org/packages/jgraph-mode.html")
+ (:keywords "tex" "wp")
+ (:authors
+ ("Stefan Monnier" . "monnier@iro.umontreal.ca"))
+ (:maintainer "Stefan Monnier" . "monnier@iro.umontreal.ca"))])
+ (js2-mode .
+ [(20211229)
+ ((emacs
+ (24 1))
+ (cl-lib
+ (0 5)))
+ "Improved JavaScript editing mode" tar
+ ((:url . "https://github.com/mooz/js2-mode/")
+ (:keywords "languages" "javascript")
+ (:maintainer "Steve Yegge" . "steve.yegge@gmail.com")
+ (:authors
+ ("Steve Yegge" . "steve.yegge@gmail.com")
+ ("mooz" . "stillpedant@gmail.com")
+ ("Dmitry Gutov" . "dgutov@yandex.ru")))])
+ (json-mode .
+ [(0 2)
+ ((emacs
+ (25 1)))
+ "Major mode for editing JSON files" single
+ ((:url . "http://elpa.gnu.org/packages/json-mode.html")
+ (:keywords "data")
+ (:authors
+ ("Simen Heggestøyl" . "simenheg@gmail.com"))
+ (:maintainer "Simen Heggestøyl" . "simenheg@gmail.com"))])
+ (jsonrpc .
+ [(1 0 15)
+ ((emacs
+ (25 2)))
+ "JSON-RPC library" tar
+ ((:keywords "processes" "languages" "extensions")
+ (:maintainer "João Távora" . "joaotavora@gmail.com")
+ (:authors
+ ("João Távora" . "joaotavora@gmail.com"))
+ (:url . "https://elpa.gnu.org/packages/jsonrpc.html")
+ (:commit . "50654cf0b1bf6210fc8f46d8e7ae13bbeeccecb5"))])
+ (jumpc .
+ [(3 0)
+ nil "jump to previous insertion points" single
+ ((:url . "http://elpa.gnu.org/packages/jumpc.html")
+ (:authors
+ ("Ivan Kanis" . "ivan@kanis.fr"))
+ (:maintainer "Ivan Kanis" . "ivan@kanis.fr"))])
+ (kind-icon .
+ [(0 1 5)
+ ((emacs
+ (27 1))
+ (svg-lib
+ (0)))
+ "Completion kind icons" tar
+ ((:url . "https://github.com/jdtsmith/kind-icon")
+ (:keywords "completion")
+ (:maintainer "J.D. Smith" . "jdtsmith@gmail.com")
+ (:authors
+ ("J.D. Smith" . "jdtsmith@gmail.com"))
+ (:commit . "235c3d20d1e667d6ac73e11d55a380e070b7cacf"))])
+ (kiwix .
+ [(1 1 5)
+ ((emacs
+ (25 1))
+ (request
+ (0 3 0)))
+ "Searching offline Wikipedia through Kiwix." tar
+ ((:url . "https://github.com/stardiviner/kiwix.el")
+ (:keywords "kiwix" "wikipedia")
+ (:maintainer "stardiviner" . "numbchild@gmail.com")
+ (:authors
+ ("stardiviner" . "numbchild@gmail.com")))])
+ (kmb .
+ [(0 1)
+ ((emacs
+ (24 1)))
+ "Kill buffers matching a regexp w/o confirmation" single
+ ((:url . "http://elpa.gnu.org/packages/kmb.html")
+ (:keywords "lisp" "convenience")
+ (:authors
+ ("Tino Calancha" . "tino.calancha@gmail.com"))
+ (:maintainer "Tino Calancha" . "tino.calancha@gmail.com"))])
+ (landmark .
+ [(1 0)
+ nil "Neural-network robot that learns landmarks" single
+ ((:url . "http://elpa.gnu.org/packages/landmark.html")
+ (:keywords "games" "neural network" "adaptive search" "chemotaxis")
+ (:authors
+ ("Terrence Brannon" . "metaperl@gmail.com"))
+ (:maintainer nil . "emacs-devel@gnu.org"))])
+ (leaf .
+ [(4 5 5)
+ ((emacs
+ (24 1)))
+ "Simplify your init.el configuration, extended use-package" tar
+ ((:url . "https://github.com/conao3/leaf.el")
+ (:keywords "lisp" "settings")
+ (:maintainer "Naoya Yamashita" . "conao3@gmail.com")
+ (:authors
+ ("Naoya Yamashita" . "conao3@gmail.com"))
+ (:commit . "7cc38f9739eadc569b1179fabe7f7893167105da"))])
+ (let-alist .
+ [(1 0 6)
+ ((emacs
+ (24 1)))
+ "Easily let-bind values of an assoc-list by their names" single
+ ((:url . "http://elpa.gnu.org/packages/let-alist.html")
+ (:keywords "extensions" "lisp")
+ (:authors
+ ("Artur Malabarba" . "emacs@endlessparentheses.com"))
+ (:maintainer "Artur Malabarba" . "emacs@endlessparentheses.com"))])
+ (lex .
+ [(1 1)
+ nil "Lexical analyser construction" tar
+ ((:maintainer "Stefan Monnier" . "monnier@iro.umontreal.ca")
+ (:authors
+ ("Stefan Monnier" . "monnier@iro.umontreal.ca"))
+ (:url . "http://elpa.gnu.org/packages/lex.html"))])
+ (lin .
+ [(0 3 1)
+ ((emacs
+ (27 1)))
+ "Make `hl-line-mode' more suitable for selection UIs" tar
+ ((:url . "https://git.sr.ht/~protesilaos/lin")
+ (:keywords "convenience" "faces" "theme")
+ (:maintainer "Protesilaos Stavrou" . "info@protesilaos.com")
+ (:authors
+ ("Protesilaos Stavrou" . "info@protesilaos.com"))
+ (:commit . "520621e51a6f6882beda4420fa5ccee6682748dd"))])
+ (lmc .
+ [(1 4)
+ ((emacs
+ (24))
+ (cl-lib
+ (0 5)))
+ "Little Man Computer in Elisp" single
+ ((:url . "http://elpa.gnu.org/packages/lmc.html")
+ (:authors
+ ("Stefan Monnier" . "monnier@iro.umontreal.ca"))
+ (:maintainer "Stefan Monnier" . "monnier@iro.umontreal.ca"))])
+ (load-dir .
+ [(0 0 5)
+ ((cl-lib
+ (0 5)))
+ "Load all Emacs Lisp files in a given directory" single
+ ((:url . "http://elpa.gnu.org/packages/load-dir.html")
+ (:keywords "lisp" "files" "convenience")
+ (:maintainer "Teodor Zlatanov" . "tzz@lifelogs.com"))])
+ (load-relative .
+ [(1 3 1)
+ nil "Relative file load (within a multi-file Emacs package)" single
+ ((:keywords "internal")
+ (:authors
+ ("Rocky Bernstein" . "rocky@gnu.org"))
+ (:maintainer "Rocky Bernstein" . "rocky@gnu.org")
+ (:url . "http://github.com/rocky/emacs-load-relative"))])
+ (loc-changes .
+ [(1 2)
+ nil "keep track of positions even after buffer changes" single
+ ((:authors
+ ("Rocky Bernstein" . "rocky@gnu.org"))
+ (:maintainer "Rocky Bernstein" . "rocky@gnu.org")
+ (:url . "http://github.com/rocky/emacs-loc-changes"))])
+ (loccur .
+ [(1 2 4)
+ ((emacs
+ (24 3)))
+ "Perform an occur-like folding in current buffer" single
+ ((:keywords "matching")
+ (:authors
+ ("Alexey Veretennikov" . "alexey.veretennikov@gmail.com"))
+ (:maintainer "Alexey Veretennikov" . "alexey.veretennikov@gmail.com")
+ (:url . "https://github.com/fourier/loccur"))])
+ (logos .
+ [(0 3 2)
+ ((emacs
+ (27 1)))
+ "Simple focus mode and extras" tar
+ ((:url . "https://git.sr.ht/~protesilaos/logos")
+ (:keywords "convenience" "focus" "writing" "presentation" "narrowing")
+ (:maintainer "Protesilaos Stavrou" . "info@protesilaos.com")
+ (:authors
+ ("Protesilaos Stavrou" . "info@protesilaos.com"))
+ (:commit . "dd25e36b64320f2ba9400a3929443aa81085e697"))])
+ (map .
+ [(3 2 1)
+ ((emacs
+ (26)))
+ "Map manipulation functions" tar
+ ((:keywords "extensions" "lisp")
+ (:maintainer nil . "emacs-devel@gnu.org")
+ (:authors
+ ("Nicolas Petton" . "nicolas@petton.fr"))
+ (:url . "https://elpa.gnu.org/packages/map.html")
+ (:commit . "fa92b040c6738de7278605cadeace0c5380a0814"))])
+ (marginalia .
+ [(0 13)
+ ((emacs
+ (26 1)))
+ "Enrich existing commands with completion annotations" tar
+ ((:url . "https://github.com/minad/marginalia")
+ (:maintainer "Omar Antolín Camarena <omar@matem.unam.mx>, Daniel Mendler" . "mail@daniel-mendler.de")
+ (:authors
+ ("Omar Antolín Camarena <omar@matem.unam.mx>, Daniel Mendler" . "mail@daniel-mendler.de"))
+ (:commit . "bd98c02720bc59a5c185c293f60595d06dfd7637"))])
+ (markchars .
+ [(0 2 2)
+ nil "Mark chars fitting certain characteristics" single
+ ((:url . "http://elpa.gnu.org/packages/markchars.html")
+ (:authors
+ ("Lennart Borgman" . "lennart.borgman@gmail.com"))
+ (:maintainer "Lennart Borgman" . "lennart.borgman@gmail.com"))])
+ (math-symbol-lists .
+ [(1 2 1)
+ nil "Lists of Unicode math symbols and latex commands" single
+ ((:keywords "unicode" "symbols" "mathematics")
+ (:authors
+ ("Vitalie Spinu" . "spinuvit@gmail.com"))
+ (:maintainer "Vitalie Spinu" . "spinuvit@gmail.com")
+ (:url . "https://github.com/vspinu/math-symbol-lists"))])
+ (mct .
+ [(0 5 0)
+ ((emacs
+ (27 1)))
+ "Minibuffer and Completions in Tandem" tar
+ ((:url . "https://gitlab.com/protesilaos/mct")
+ (:maintainer "Protesilaos Stavrou" . "info@protesilaos.com")
+ (:authors
+ ("Protesilaos Stavrou" . "info@protesilaos.com"))
+ (:commit . "680d7727216ed05ba58e7d2f04a046d1f27cf3e9"))])
+ (memory-usage .
+ [(0 2)
+ nil "Analyze the memory usage of Emacs in various ways" single
+ ((:url . "http://elpa.gnu.org/packages/memory-usage.html")
+ (:keywords "maint")
+ (:authors
+ ("Stefan Monnier" . "monnier@iro.umontreal.ca"))
+ (:maintainer "Stefan Monnier" . "monnier@iro.umontreal.ca"))])
+ (metar .
+ [(0 3)
+ ((cl-lib
+ (0 5)))
+ "Retrieve and decode METAR weather information" single
+ ((:url . "http://elpa.gnu.org/packages/metar.html")
+ (:keywords "comm")
+ (:authors
+ ("Mario Lang" . "mlang@delysid.org"))
+ (:maintainer "Mario Lang" . "mlang@delysid.org"))])
+ (midi-kbd .
+ [(0 2)
+ ((emacs
+ (25)))
+ "Create keyboard events from Midi input" single
+ ((:url . "http://elpa.gnu.org/packages/midi-kbd.html")
+ (:keywords "convenience" "hardware" "multimedia")
+ (:authors
+ ("David Kastrup" . "dak@gnu.org"))
+ (:maintainer "David Kastrup" . "dak@gnu.org"))])
+ (mines .
+ [(1 6)
+ ((emacs
+ (24 4))
+ (cl-lib
+ (0 5)))
+ "Minesweeper game" tar
+ ((:url . "https://github.com/calancha/Minesweeper")
+ (:maintainer "Tino Calancha" . "tino.calancha@gmail.com")
+ (:authors
+ ("Tino Calancha" . "tino.calancha@gmail.com"))
+ (:keywords "games"))])
+ (minibuffer-line .
+ [(0 1)
+ nil "Display status info in the minibuffer window" single
+ ((:url . "http://elpa.gnu.org/packages/minibuffer-line.html")
+ (:authors
+ ("Stefan Monnier" . "monnier@iro.umontreal.ca"))
+ (:maintainer "Stefan Monnier" . "monnier@iro.umontreal.ca"))])
+ (minimap .
+ [(1 4)
+ nil "Sidebar showing a \"mini-map\" of a buffer" single
+ ((:url . "http://elpa.gnu.org/packages/minimap.html")
+ (:authors
+ ("David Engster" . "deng@randomsample.de"))
+ (:maintainer "David Engster" . "deng@randomsample.de"))])
+ (mmm-mode .
+ [(0 5 8)
+ ((cl-lib
+ (0 2)))
+ "Allow Multiple Major Modes in a buffer" tar
+ ((:url . "https://github.com/purcell/mmm-mode")
+ (:maintainer "Dmitry Gutov" . "dgutov@yandex.ru")
+ (:authors
+ ("Michael Abraham Shulman" . "viritrilbia@gmail.com"))
+ (:keywords "convenience" "faces" "languages" "tools"))])
+ (modus-operandi-theme .
+ [(0 13 2)
+ ((emacs
+ (26 1))
+ (modus-themes
+ (1 2 4)))
+ "Accessible light theme (WCAG AAA) [DEPRECATED]" tar
+ ((:url . "https://gitlab.com/protesilaos/modus-themes")
+ (:maintainer "Protesilaos Stavrou" . "info@protesilaos.com")
+ (:authors
+ ("Protesilaos Stavrou" . "info@protesilaos.com"))
+ (:keywords "faces" "theme" "accessibility"))])
+ (modus-themes .
+ [(2 3 0)
+ ((emacs
+ (27 1)))
+ "Elegant, highly legible and customizable themes" tar
+ ((:url . "https://gitlab.com/protesilaos/modus-themes")
+ (:keywords "faces" "theme" "accessibility")
+ (:maintainer "Protesilaos Stavrou" . "info@protesilaos.com")
+ (:authors
+ ("Protesilaos Stavrou" . "info@protesilaos.com"))
+ (:commit . "7b08e3a8e41db1483322f48305f837e705540249"))])
+ (modus-vivendi-theme .
+ [(0 13 2)
+ ((emacs
+ (26 1))
+ (modus-themes
+ (1 2 4)))
+ "Accessible dark theme (WCAG AAA) [DEPRECATED]" tar
+ ((:url . "https://gitlab.com/protesilaos/modus-themes")
+ (:maintainer "Protesilaos Stavrou" . "info@protesilaos.com")
+ (:authors
+ ("Protesilaos Stavrou" . "info@protesilaos.com"))
+ (:keywords "faces" "theme" "accessibility"))])
+ (multi-mode .
+ [(1 14)
+ nil "support for multiple major modes" tar
+ ((:url . "http://www.loveshack.ukfsn.org/emacs")
+ (:keywords "languages" "extensions" "files")
+ (:maintainer "Dave Love" . "fx@gnu.org")
+ (:authors
+ ("Dave Love" . "fx@gnu.org")))])
+ (multishell .
+ [(1 1 9)
+ ((cl-lib
+ (0 5)))
+ "Easily use multiple shell buffers, local and remote" tar
+ ((:url . "https://github.com/kenmanheimer/EmacsMultishell")
+ (:maintainer "Ken Manheimer" . "ken.manheimer@gmail.com")
+ (:authors
+ ("Ken Manheimer" . "ken.manheimer@gmail.com"))
+ (:keywords "processes"))])
+ (muse .
+ [(3 20 2)
+ nil "Authoring and publishing tool for Emacs" tar
+ ((:url . "http://mwolson.org/projects/EmacsMuse.html")
+ (:maintainer "Michael Olson" . "mwolson@gnu.org")
+ (:authors
+ ("John Wiegley" . "johnw@gnu.org"))
+ (:keywords "hypermedia"))])
+ (myers .
+ [(0 1)
+ ((emacs
+ (25)))
+ "Random-access singly-linked lists" single
+ ((:url . "http://elpa.gnu.org/packages/myers.html")
+ (:keywords "list" "containers")
+ (:authors
+ ("Stefan Monnier" . "monnier@iro.umontreal.ca"))
+ (:maintainer "Stefan Monnier" . "monnier@iro.umontreal.ca"))])
+ (nadvice .
+ [(0 3)
+ nil "Forward compatibility for Emacs-24.4's nadvice" single
+ ((:url . "http://elpa.gnu.org/packages/nadvice.html")
+ (:authors
+ ("Stefan Monnier" . "monnier@iro.umontreal.ca"))
+ (:maintainer "Stefan Monnier" . "monnier@iro.umontreal.ca"))])
+ (nameless .
+ [(1 0 2)
+ ((emacs
+ (24 4)))
+ "Hide package namespace in your emacs-lisp code" single
+ ((:keywords "convenience" "lisp")
+ (:authors
+ ("Artur Malabarba" . "emacs@endlessparentheses.com"))
+ (:maintainer "Artur Malabarba" . "emacs@endlessparentheses.com")
+ (:url . "https://github.com/Malabarba/nameless"))])
+ (names .
+ [(20151201 0)
+ ((emacs
+ (24 1))
+ (cl-lib
+ (0 5))
+ (nadvice
+ (0 3)))
+ "Namespaces for emacs-lisp. Avoid name clobbering without hiding symbols." tar
+ ((:url . "https://github.com/Malabarba/names")
+ (:maintainer "Artur Malabarba" . "emacs@endlessparentheses.com")
+ (:authors
+ ("Artur Malabarba" . "emacs@endlessparentheses.com"))
+ (:keywords "extensions" "lisp"))])
+ (nano-agenda .
+ [(0 2 1)
+ ((emacs
+ (27 1)))
+ "N Λ N O agenda" tar
+ ((:url . "https://github.com/rougier/nano-agenda")
+ (:keywords "convenience" "org-mode" "org-agenda")
+ (:maintainer "Nicolas P. Rougier" . "Nicolas.Rougier@inria.fr"))])
+ (nano-modeline .
+ [(0 6)
+ ((emacs
+ (27 1)))
+ "N Λ N O modeline" tar
+ ((:url . "https://github.com/rougier/nano-modeline")
+ (:keywords "convenience" "mode-line" "header-line")
+ (:maintainer "Nicolas P. Rougier" . "Nicolas.Rougier@inria.fr")
+ (:commit . "1c743a9dbe72a1bdc2196ad43a217060e163c929"))])
+ (nano-theme .
+ [(0 3 1)
+ ((emacs
+ (27 1)))
+ "N Λ N O theme" tar
+ ((:url . "https://github.com/rougier/nano-theme")
+ (:keywords "theme" "dark" "light")
+ (:maintainer "Nicolas P. Rougier" . "Nicolas.Rougier@inria.fr")
+ (:commit . "c4f296d349cf5ef2efd88d68535a4dbf577b9a87"))])
+ (nhexl-mode .
+ [(1 5)
+ ((emacs
+ (24 4))
+ (cl-lib
+ (0 5)))
+ "Minor mode to edit files via hex-dump format" single
+ ((:url . "http://elpa.gnu.org/packages/nhexl-mode.html")
+ (:keywords "data")
+ (:authors
+ ("Stefan Monnier" . "monnier@iro.umontreal.ca"))
+ (:maintainer "Stefan Monnier" . "monnier@iro.umontreal.ca"))])
+ (nlinum .
+ [(1 9)
+ nil "Show line numbers in the margin" single
+ ((:url . "http://elpa.gnu.org/packages/nlinum.html")
+ (:keywords "convenience")
+ (:authors
+ ("Stefan Monnier" . "monnier@iro.umontreal.ca"))
+ (:maintainer "Stefan Monnier" . "monnier@iro.umontreal.ca"))])
+ (notes-mode .
+ [(1 30)
+ nil "Indexing system for on-line note-taking" tar
+ ((:maintainer nil . "<johnh@isi.edu>.")
+ (:authors
+ (nil . "<johnh@isi.edu>."))
+ (:url . "http://elpa.gnu.org/packages/notes-mode.html"))])
+ (ntlm .
+ [(2 1 0)
+ nil "NTLM (NT LanManager) authentication support" single
+ ((:url . "http://elpa.gnu.org/packages/ntlm.html")
+ (:keywords "ntlm" "sasl" "comm")
+ (:authors
+ ("Taro Kawagishi" . "tarok@transpulse.org"))
+ (:maintainer "Thomas Fitzsimmons" . "fitzsim@fitzsim.org"))])
+ (num3-mode .
+ [(1 3)
+ nil "highlight groups of digits in long numbers" single
+ ((:url . "http://elpa.gnu.org/packages/num3-mode.html")
+ (:keywords "faces" "minor-mode")
+ (:authors
+ ("Felix Lee <felix8a@gmail.com>, Michal Nazarewicz" . "mina86@mina86.com"))
+ (:maintainer "Michal Nazarewicz" . "mina86@mina86.com"))])
+ (oauth2 .
+ [(0 16)
+ ((cl-lib
+ (0 5))
+ (nadvice
+ (0 3)))
+ "OAuth 2.0 Authorization Protocol" tar
+ ((:maintainer "Julien Danjou" . "julien@danjou.info")
+ (:authors
+ ("Julien Danjou" . "julien@danjou.info"))
+ (:keywords "comm")
+ (:url . "https://elpa.gnu.org/packages/oauth2.html"))])
+ (ob-haxe .
+ [(1 0)
+ nil "org-babel functions for haxe evaluation" tar
+ ((:url . "https://orgmode.org")
+ (:maintainer "Ian Martins" . "ianxm@jhu.edu")
+ (:authors
+ ("Ian Martins" . "ianxm@jhu.edu"))
+ (:keywords "literate programming" "reproducible research"))])
+ (objed .
+ [(0 8 3)
+ ((emacs
+ (25))
+ (cl-lib
+ (0 5)))
+ "Navigate and edit text objects." tar
+ ((:url . "https://github.com/clemera/objed")
+ (:maintainer "Clemens Radermacher" . "clemera@posteo.net")
+ (:authors
+ ("Clemens Radermacher" . "clemera@posteo.net"))
+ (:keywords "convenience"))])
+ (omn-mode .
+ [(1 2)
+ nil "Support for OWL Manchester Notation" single
+ ((:url . "http://elpa.gnu.org/packages/omn-mode.html")
+ (:authors
+ ("Phillip Lord" . "phillip.lord@newcastle.ac.uk"))
+ (:maintainer "Phillip Lord" . "phillip.lord@newcastle.ac.uk"))])
+ (on-screen .
+ [(1 3 3)
+ ((cl-lib
+ (0)))
+ "guide your eyes while scrolling" single
+ ((:keywords "convenience")
+ (:authors
+ ("Michael Heerdegen" . "michael_heerdegen@web.de"))
+ (:maintainer "Michael Heerdegen" . "michael_heerdegen@web.de")
+ (:url . "https://github.com/michael-heerdegen/on-screen.el"))])
+ (orderless .
+ [(0 7)
+ ((emacs
+ (26 1)))
+ "Completion style for matching regexps in any order" tar
+ ((:url . "https://github.com/oantolin/orderless")
+ (:keywords "extensions")
+ (:maintainer "Omar Antolín Camarena" . "omar@matem.unam.mx")
+ (:authors
+ ("Omar Antolín Camarena" . "omar@matem.unam.mx"))
+ (:commit . "92008e762b30cb445a2227e458cbb9a5e1b1d4e8"))])
+ (org .
+ [(9 5 3)
+ ((emacs
+ (25 1)))
+ "Outline-based notes management and organizer" tar
+ ((:url . "https://orgmode.org")
+ (:keywords "outlines" "hypermedia" "calendar" "wp")
+ (:maintainer "Bastien Guerry" . "bzg@gnu.org")
+ (:authors
+ ("Carsten Dominik" . "carsten.dominik@gmail.com"))
+ (:commit . "69c588947d1be9bca1eb8c773f2a8ff117d264ba"))])
+ (org-edna .
+ [(1 1 2)
+ ((emacs
+ (25 1))
+ (seq
+ (2 19))
+ (org
+ (9 0 5)))
+ "Extensible Dependencies 'N' Actions" tar
+ ((:url . "https://savannah.nongnu.org/projects/org-edna-el/")
+ (:maintainer "Ian Dunn" . "dunni@gnu.org")
+ (:authors
+ ("Ian Dunn" . "dunni@gnu.org"))
+ (:keywords "convenience" "text" "org"))])
+ (org-modern .
+ [(0 3)
+ ((emacs
+ (27 1)))
+ "Modern looks for Org" tar
+ ((:url . "https://github.com/minad/org-modern")
+ (:maintainer "Daniel Mendler" . "mail@daniel-mendler.de")
+ (:authors
+ ("Daniel Mendler" . "mail@daniel-mendler.de"))
+ (:commit . "64fa67a3e4cc7af4084bb879bd8a0e5380333bcf"))])
+ (org-real .
+ [(1 0 4)
+ ((emacs
+ (26 1))
+ (boxy
+ (1 0))
+ (org
+ (9 3)))
+ "Keep track of real things as org-mode links" tar
+ ((:url . "https://gitlab.com/tygrdev/org-real")
+ (:keywords "tools")
+ (:maintainer "Tyler Grinn" . "tylergrinn@gmail.com")
+ (:authors
+ ("Tyler Grinn" . "tylergrinn@gmail.com")))])
+ (org-remark .
+ [(1 0 4)
+ ((emacs
+ (27 1))
+ (org
+ (9 4)))
+ "Highlight & annotate any text files" tar
+ ((:url . "https://github.com/nobiot/org-remark")
+ (:keywords "org-mode" "annotation" "writing" "note-taking" "marginal-notes")
+ (:maintainer "Noboru Ota" . "me@nobiot.com")
+ (:authors
+ ("Noboru Ota" . "me@nobiot.com"))
+ (:commit . "e78cdff25edffc74bfe4c65f3a02777d454f6d96"))])
+ (org-transclusion .
+ [(1 2 0)
+ ((emacs
+ (27 1))
+ (org
+ (9 4)))
+ "Transclude text content via links" tar
+ ((:url . "https://github.com/nobiot/org-transclusion")
+ (:keywords "org-mode" "transclusion" "writing")
+ (:maintainer "Noboru Ota" . "me@nobiot.com")
+ (:authors
+ ("Noboru Ota" . "me@nobiot.com"))
+ (:commit . "2d44c56fb666da2dbb6c988389a21bee5bdd406c"))])
+ (org-translate .
+ [(0 1 4)
+ ((emacs
+ (27 1))
+ (org
+ (9 1)))
+ "Org-based translation environment" tar
+ ((:maintainer "Eric Abrahamsen" . "eric@ericabrahamsen.net")
+ (:authors
+ ("Eric Abrahamsen" . "eric@ericabrahamsen.net"))
+ (:url . "https://elpa.gnu.org/packages/org-translate.html")
+ (:commit . "bdc5d169ef0c502f46aa673918ccf34fcc8415f2"))])
+ (orgalist .
+ [(1 13)
+ ((emacs
+ (24 4)))
+ "Manage Org-like lists in non-Org buffers" single
+ ((:url . "http://elpa.gnu.org/packages/orgalist.html")
+ (:keywords "convenience")
+ (:authors
+ ("Nicolas Goaziou" . "mail@nicolasgoaziou.fr"))
+ (:maintainer "Nicolas Goaziou" . "mail@nicolasgoaziou.fr"))])
+ (osc .
+ [(0 4)
+ nil "Open Sound Control protocol library" tar
+ ((:maintainer "Mario Lang" . "mlang@blind.guru")
+ (:authors
+ ("Mario Lang" . "mlang@blind.guru"))
+ (:keywords "comm" "processes" "multimedia")
+ (:url . "https://elpa.gnu.org/packages/osc.html"))])
+ (osm .
+ [(0 6)
+ ((emacs
+ (27 1)))
+ "OpenStreetMap viewer" tar
+ ((:url . "https://github.com/minad/osm")
+ (:maintainer "Daniel Mendler" . "mail@daniel-mendler.de")
+ (:authors
+ ("Daniel Mendler" . "mail@daniel-mendler.de"))
+ (:commit . "f76decfd0e94d5fc030a1d5c3230c213c87b47ef"))])
+ (other-frame-window .
+ [(1 0 6)
+ ((emacs
+ (24 4)))
+ "Minor mode to enable global prefix keys for other frame/window buffer placement" single
+ ((:url . "http://elpa.gnu.org/packages/other-frame-window.html")
+ (:keywords "frame" "window")
+ (:authors
+ ("Stephen Leake" . "stephen_leake@member.fsf.org"))
+ (:maintainer "Stephen Leake" . "stephen_leake@member.fsf.org"))])
+ (pabbrev .
+ [(4 2 1)
+ nil "Predictive abbreviation expansion" single
+ ((:url . "http://elpa.gnu.org/packages/pabbrev.html")
+ (:authors
+ ("Phillip Lord" . "phillip.lord@newcastle.ac.uk"))
+ (:maintainer "Phillip Lord" . "phillip.lord@newcastle.ac.uk"))])
+ (paced .
+ [(1 1 3)
+ ((emacs
+ (25 1))
+ (async
+ (1 9 1)))
+ "Predictive Abbreviation Completion and Expansion using Dictionaries" tar
+ ((:url . "https://savannah.nongnu.org/projects/paced-el/")
+ (:maintainer "Ian Dunn" . "dunni@gnu.org")
+ (:authors
+ ("Ian Dunn" . "dunni@gnu.org"))
+ (:keywords "convenience" "completion"))])
+ (parsec .
+ [(0 1 3)
+ ((emacs
+ (24))
+ (cl-lib
+ (0 5)))
+ "Parser combinator library" tar
+ ((:url . "https://github.com/cute-jumper/parsec.el")
+ (:maintainer "Junpeng Qiu" . "qjpchmail@gmail.com")
+ (:authors
+ ("Junpeng Qiu" . "qjpchmail@gmail.com"))
+ (:keywords "extensions"))])
+ (parser-generator .
+ [(0 1 5)
+ ((emacs
+ (26)))
+ "Parser Generator library" tar
+ ((:url . "https://github.com/cjohansson/emacs-parser-generator")
+ (:keywords "tools" "convenience")
+ (:maintainer "Christian Johansson" . "christian@cvj.se")
+ (:authors
+ ("Christian Johansson" . "christian@cvj.se"))
+ (:commit . "bf7229332f7040d49fdac56e54da13d73752395d"))])
+ (path-iterator .
+ [(1 0)
+ ((emacs
+ (25 0)))
+ "An iterator for traversing a directory path." tar
+ ((:maintainer "Stephen Leake" . "stephen_leake@stephe-leake.org")
+ (:authors
+ ("Stephen Leake" . "stephen_leake@stephe-leake.org"))
+ (:url . "http://elpa.gnu.org/packages/path-iterator.html"))])
+ (peg .
+ [(1 0)
+ ((emacs
+ (25)))
+ "Parsing Expression Grammars in Emacs Lisp" tar
+ ((:maintainer "Stefan Monnier" . "monnier@iro.umontreal.ca")
+ (:authors
+ ("Helmut Eller" . "eller.helmut@gmail.com"))
+ (:url . "http://elpa.gnu.org/packages/peg.html"))])
+ (persist .
+ [(0 4)
+ nil "Persist Variables between Emacs Sessions" tar
+ ((:maintainer "Phillip Lord" . "phillip.lord@russet.org.uk")
+ (:authors
+ ("Phillip Lord" . "phillip.lord@russet.org.uk"))
+ (:url . "http://elpa.gnu.org/packages/persist.html"))])
+ (phps-mode .
+ [(0 4 20)
+ ((emacs
+ (26)))
+ "Major mode for PHP with code intelligence" tar
+ ((:url . "https://github.com/cjohansson/emacs-phps-mode")
+ (:keywords "tools" "convenience")
+ (:maintainer "Christian Johansson" . "christian@cvj.se")
+ (:authors
+ ("Christian Johansson" . "christian@cvj.se"))
+ (:commit . "3a09d15aa143b175235674f4cd45f92b0b0a6c36"))])
+ (pinentry .
+ [(0 1)
+ nil "GnuPG Pinentry server implementation" single
+ ((:url . "http://elpa.gnu.org/packages/pinentry.html")
+ (:keywords "gnupg")
+ (:authors
+ ("Daiki Ueno" . "ueno@gnu.org"))
+ (:maintainer "Daiki Ueno" . "ueno@gnu.org"))])
+ (poker .
+ [(0 2)
+ nil "Texas hold 'em poker" single
+ ((:url . "http://elpa.gnu.org/packages/poker.html")
+ (:keywords "games")
+ (:authors
+ ("Mario Lang" . "mlang@delysid.org"))
+ (:maintainer "Mario Lang" . "mlang@delysid.org"))])
+ (posframe .
+ [(1 1 7)
+ ((emacs
+ (26 1)))
+ "Pop a posframe (just a frame) at point" tar
+ ((:url . "https://github.com/tumashu/posframe")
+ (:keywords "convenience" "tooltip")
+ (:maintainer "Feng Shu" . "tumashu@163.com")
+ (:authors
+ ("Feng Shu" . "tumashu@163.com"))
+ (:commit . "c91d4d53fa479ceb604071008ce0a901770eff57"))])
+ (project .
+ [(0 8 1)
+ ((emacs
+ (26 1))
+ (xref
+ (1 0 2)))
+ "Operations on the current project" tar
+ ((:url . "https://elpa.gnu.org/packages/project.html")
+ (:commit . "6bf29072e968401f842789c71468e624e5c913a9"))])
+ (psgml .
+ [(1 3 4)
+ nil "SGML-editing mode with parsing support" tar
+ ((:maintainer "Lennart Staflin" . "lstaflin@gmail.com")
+ (:authors
+ ("Lennart Staflin" . "lenst@lysator.liu.se")
+ ("James Clark" . "jjc@clark.com"))
+ (:keywords "languages")
+ (:url . "http://elpa.gnu.org/packages/psgml.html"))])
+ (pspp-mode .
+ [(1 1)
+ nil "Major mode for editing PSPP files" single
+ ((:url . "http://elpa.gnu.org/packages/pspp-mode.html")
+ (:keywords "pspp" "major-mode")
+ (:authors
+ ("Scott Andrew Borton" . "scott@pp.htv.fi"))
+ (:maintainer "John Darrington" . "john@darrington.wattle.id.au"))])
+ (pulsar .
+ [(0 3 1)
+ ((emacs
+ (27 1)))
+ "Pulse highlight on demand or after select functions" tar
+ ((:url . "https://git.sr.ht/~protesilaos/pulsar")
+ (:keywords "convenience" "pulse" "highlight")
+ (:maintainer "Protesilaos Stavrou" . "info@protesilaos.com")
+ (:authors
+ ("Protesilaos Stavrou" . "info@protesilaos.com"))
+ (:commit . "86a7c429c6878287c068106b318889824cad3210"))])
+ (pyim .
+ [(4 2 0)
+ ((emacs
+ (25 1))
+ (async
+ (1 6))
+ (xr
+ (1 13)))
+ "A Chinese input method support quanpin, shuangpin, wubi, cangjie and rime." tar
+ ((:url . "https://github.com/tumashu/pyim")
+ (:keywords "convenience" "chinese" "pinyin" "input-method")
+ (:maintainer "Feng Shu" . "tumashu@163.com")
+ (:authors
+ ("Ye Wenbin" . "wenbinye@163.com")
+ ("Feng Shu" . "tumashu@163.com"))
+ (:commit . "cd1bfd2bbc10fe0ac47d0ec383cde453f6019e6c"))])
+ (pyim-basedict .
+ [(0 5 0)
+ nil "The default pinyin dict of pyim" tar
+ ((:url . "https://github.com/tumashu/pyim-basedict")
+ (:maintainer "Feng Shu" . "tumashu@163.com")
+ (:authors
+ ("Feng Shu" . "tumashu@163.com"))
+ (:keywords "convenience" "chinese" "pinyin" "input-method" "complete"))])
+ (python .
+ [(0 28)
+ ((emacs
+ (24 4))
+ (cl-lib
+ (1 0)))
+ "Python's flying circus support for Emacs" tar
+ ((:url . "https://github.com/fgallina/python.el")
+ (:keywords "languages")
+ (:maintainer nil . "emacs-devel@gnu.org")
+ (:authors
+ ("Fabián E. Gallina" . "fgallina@gnu.org"))
+ (:commit . "b3d0f53b296a0876ec7a55ae840868e65ed54e14"))])
+ (quarter-plane .
+ [(0 1)
+ nil "Minor mode for quarter-plane style editing" single
+ ((:url . "http://elpa.gnu.org/packages/quarter-plane.html")
+ (:keywords "convenience" "wp")
+ (:authors
+ ("Peter J. Weisberg" . "pj@irregularexpressions.net"))
+ (:maintainer "Peter J. Weisberg" . "pj@irregularexpressions.net"))])
+ (queue .
+ [(0 2)
+ nil "Queue data structure" single
+ ((:keywords "extensions" "data structures" "queue")
+ (:authors
+ ("Inge Wallin" . "inge@lysator.liu.se")
+ ("Toby Cubitt" . "toby-predictive@dr-qubit.org"))
+ (:maintainer "Toby Cubitt" . "toby-predictive@dr-qubit.org")
+ (:url . "http://www.dr-qubit.org/emacs.php"))])
+ (rainbow-mode .
+ [(1 0 6)
+ nil "Colorize color names in buffers" tar
+ ((:keywords "faces")
+ (:maintainer "Julien Danjou" . "julien@danjou.info")
+ (:authors
+ ("Julien Danjou" . "julien@danjou.info"))
+ (:url . "https://elpa.gnu.org/packages/rainbow-mode.html")
+ (:commit . "ac68593018ef3555e64ea592d72334f4e3e39209"))])
+ (rbit .
+ [(0 1)
+ nil "Red-black persistent interval trees" single
+ ((:url . "http://elpa.gnu.org/packages/rbit.html")
+ (:keywords "data structures" "binary tree" "intervals")
+ (:authors
+ ("Stefan Monnier" . "monnier@iro.umontreal.ca"))
+ (:maintainer "Stefan Monnier" . "monnier@iro.umontreal.ca"))])
+ (rcirc-color .
+ [(0 4 2)
+ ((emacs
+ (24 4)))
+ "color nicks" tar
+ ((:maintainer "Alex Schroeder" . "alex@gnu.org")
+ (:authors
+ ("Alex Schroeder" . "alex@gnu.org"))
+ (:keywords "comm")
+ (:url . "https://elpa.gnu.org/packages/rcirc-color.html"))])
+ (rcirc-menu .
+ [(1 1)
+ nil "A menu of all your rcirc connections" single
+ ((:url . "http://elpa.gnu.org/packages/rcirc-menu.html")
+ (:keywords "comm")
+ (:authors
+ ("Alex Schroeder" . "alex@gnu.org"))
+ (:maintainer "Alex Schroeder" . "alex@gnu.org"))])
+ (realgud .
+ [(1 5 1)
+ ((load-relative
+ (1 3 1))
+ (loc-changes
+ (1 2))
+ (test-simple
+ (1 3 0))
+ (emacs
+ (25)))
+ "A modular front-end for interacting with external debuggers" tar
+ ((:url . "http://github.com/realgud/realgud/")
+ (:maintainer "Rocky Bernstein" . "rocky@gnu.org")
+ (:authors
+ ("Rocky Bernstein" . "rocky@gnu.org"))
+ (:keywords "debugger" "gdb" "python" "perl" "go" "bash" "zsh" "bashdb" "zshdb" "remake" "trepan" "perldb" "pdb"))])
+ (realgud-ipdb .
+ [(1 0 0)
+ ((realgud
+ (1 5 0))
+ (load-relative
+ (1 3 1))
+ (emacs
+ (25)))
+ "Realgud front-end to ipdb" tar
+ ((:url . "http://github.com/rocky/realgud-ipdb")
+ (:maintainer "Rocky Bernstein" . "rocky@gnu.org")
+ (:authors
+ ("Rocky Bernstein" . "rocky@gnu.org")))])
+ (realgud-jdb .
+ [(1 0 0)
+ ((realgud
+ (1 4 5))
+ (load-relative
+ (1 2))
+ (cl-lib
+ (0 5))
+ (emacs
+ (25)))
+ "Realgud front-end to Java's jdb debugger\"" tar
+ ((:url . "http://github.com/realgud/realgud-jdb")
+ (:maintainer "Rocky Bernstein" . "rocky@gnu.org")
+ (:authors
+ ("Rocky Bernstein" . "rocky@gnu.org")))])
+ (realgud-lldb .
+ [(1 0 2)
+ ((load-relative
+ (1 3 1))
+ (realgud
+ (1 5 0))
+ (emacs
+ (25)))
+ "Realgud front-end to lldb" tar
+ ((:url . "http://github.com/realgud/realgud-lldb")
+ (:maintainer "Rocky Bernstein" . "rocky@gnu.org")
+ (:authors
+ ("Rocky Bernstein" . "rocky@gnu.org")))])
+ (realgud-node-debug .
+ [(1 0 0)
+ ((realgud
+ (1 4 5))
+ (load-relative
+ (1 2))
+ (cl-lib
+ (0 5))
+ (emacs
+ (25)))
+ "Realgud front-end to older \"node debug\"" tar
+ ((:url . "http://github.com/realgud/realgud-node-debug")
+ (:maintainer "Rocky Bernstein" . "rocky@gnu.org")
+ (:authors
+ ("Rocky Bernstein" . "rocky@gnu.org")))])
+ (realgud-node-inspect .
+ [(1 0 0)
+ ((realgud
+ (1 4 5))
+ (load-relative
+ (1 2))
+ (cl-lib
+ (0 5))
+ (emacs
+ (24)))
+ "Realgud front-end to newer \"node inspect\"" tar
+ ((:url . "http://github.com/realgud/realgud-node-inspect")
+ (:maintainer "Rocky Bernstein" . "rocky@gnu.org")
+ (:authors
+ ("Rocky Bernstein" . "rocky@gnu.org")))])
+ (realgud-trepan-ni .
+ [(1 0 1)
+ ((load-relative
+ (1 2))
+ (realgud
+ (1 5 0))
+ (cl-lib
+ (0 5))
+ (emacs
+ (25)))
+ "Realgud front-end to trepan-ni" tar
+ ((:url . "http://github.com/realgud/realgud-trepan-ni")
+ (:maintainer "Rocky Bernstein" . "rocky@gnu.org")
+ (:authors
+ ("Rocky Bernstein" . "rocky@gnu.org")))])
+ (rec-mode .
+ [(1 8 3)
+ ((emacs
+ (25)))
+ "Major mode for viewing/editing rec files" tar
+ ((:url . "https://www.gnu.org/software/recutils/")
+ (:maintainer "Antoine Kalmbach" . "ane@iki.fi")
+ (:authors
+ ("Jose E. Marchesi" . "jemarch@gnu.org"))
+ (:commit . "24adb19f70f682f28d6edac03598b1fee971d599"))])
+ (register-list .
+ [(0 1)
+ nil "Interactively list/edit registers" single
+ ((:url . "http://elpa.gnu.org/packages/register-list.html")
+ (:keywords "register")
+ (:authors
+ ("Bastien Guerry" . "bzg@gnu.org"))
+ (:maintainer "Bastien Guerry" . "bzg@gnu.org"))])
+ (relint .
+ [(1 20)
+ ((xr
+ (1 22))
+ (emacs
+ (26 1)))
+ "Elisp regexp mistake finder" tar
+ ((:url . "https://github.com/mattiase/relint")
+ (:keywords "lisp" "regexps")
+ (:maintainer "Mattias Engdegård" . "mattiase@acm.org")
+ (:authors
+ ("Mattias Engdegård" . "mattiase@acm.org"))
+ (:commit . "5a918af0c99ab83355d4ec73a2fb39e70c173956"))])
+ (repology .
+ [(1 2 3)
+ ((emacs
+ (26 1)))
+ "Repology API access via Elisp" tar
+ ((:keywords "web")
+ (:maintainer "Nicolas Goaziou" . "mail@nicolasgoaziou.fr")
+ (:authors
+ ("Nicolas Goaziou" . "mail@nicolasgoaziou.fr"))
+ (:url . "https://elpa.gnu.org/packages/repology.html")
+ (:commit . "b5829003decbdbe9002e7e1d29f45989a4659927"))])
+ (rich-minority .
+ [(1 0 3)
+ ((cl-lib
+ (0 5)))
+ "Clean-up and Beautify the list of minor-modes." tar
+ ((:url . "https://github.com/Malabarba/rich-minority")
+ (:maintainer "Artur Malabarba" . "emacs@endlessparentheses.com")
+ (:authors
+ ("Artur Malabarba" . "emacs@endlessparentheses.com"))
+ (:keywords "mode-line" "faces"))])
+ (rnc-mode .
+ [(0 2)
+ nil "Emacs mode to edit Relax-NG Compact files" single
+ ((:url . "http://elpa.gnu.org/packages/rnc-mode.html")
+ (:keywords "xml" "relaxng")
+ (:authors
+ ("Stefan Monnier" . "monnier@iro.umontreal.ca"))
+ (:maintainer "Stefan Monnier" . "monnier@iro.umontreal.ca"))])
+ (rt-liberation .
+ [(5)
+ nil "Emacs interface to RT" tar
+ ((:url . "http://www.nongnu.org/rtliber/")
+ (:keywords "rt" "tickets")
+ (:maintainer "Yoni Rabkin" . "yrk@gnu.org")
+ (:authors
+ ("Yoni Rabkin" . "yrk@gnu.org"))
+ (:commit . "b76ae2828b12efc5f45f51ba873489e049a70924"))])
+ (rudel .
+ [(0 3 2)
+ ((emacs
+ (24))
+ (cl-lib
+ (0 5))
+ (cl-generic
+ (0 3))
+ (cl-print
+ (1 0)))
+ "A collaborative editing framework for Emacs" tar
+ ((:url . "http://rudel.sourceforge.net/")
+ (:maintainer "Jan Moringen" . "scymtym@users.sourceforge.net")
+ (:authors
+ ("Jan Moringen" . "scymtym@users.sourceforge.net"))
+ (:keywords "rudel" "collaboration"))])
+ (satchel .
+ [(0 2)
+ ((emacs
+ (27 2))
+ (project
+ (0 8 1)))
+ "A bag for your files, separated by git branches" tar
+ ((:keywords "tools" "languages")
+ (:maintainer "Theodor Thornhill" . "theo@thornhill.no")
+ (:authors
+ ("Theodor Thornhill" . "theo@thornhill.no"))
+ (:url . "https://elpa.gnu.org/packages/satchel.html")
+ (:commit . "6e5613e203f6937202cb5d55249e7e6be939067b"))])
+ (scanner .
+ [(0 2)
+ ((emacs
+ (25 1))
+ (dash
+ (2 12 0)))
+ "Scan documents and images" tar
+ ((:url . "https://gitlab.com/rstocker/scanner.git")
+ (:maintainer "Raffael Stocker" . "r.stocker@mnet-mail.de")
+ (:authors
+ ("Raffael Stocker" . "r.stocker@mnet-mail.de"))
+ (:keywords "hardware" "multimedia"))])
+ (scroll-restore .
+ [(1 0)
+ nil "restore original position after scrolling" single
+ ((:url . "http://elpa.gnu.org/packages/scroll-restore.html")
+ (:keywords "scrolling")
+ (:authors
+ ("Martin Rudalics" . "rudalics@gmx.at"))
+ (:maintainer "Martin Rudalics" . "rudalics@gmx.at"))])
+ (sed-mode .
+ [(1 0)
+ nil "Major mode to edit sed scripts" single
+ ((:url . "http://elpa.gnu.org/packages/sed-mode.html")
+ (:authors
+ ("Stefan Monnier" . "monnier@iro.umontreal.ca"))
+ (:maintainer "Stefan Monnier" . "monnier@iro.umontreal.ca"))])
+ (seq .
+ [(2 23)
+ nil "Sequence manipulation functions" tar
+ ((:keywords "sequences")
+ (:maintainer nil . "emacs-devel@gnu.org")
+ (:authors
+ ("Nicolas Petton" . "nicolas@petton.fr"))
+ (:url . "https://elpa.gnu.org/packages/seq.html"))])
+ (setup .
+ [(1 2 0)
+ ((emacs
+ (26 1)))
+ "Helpful Configuration Macro" tar
+ ((:url . "https://git.sr.ht/~pkal/setup")
+ (:keywords "lisp" "local")
+ (:maintainer "Philip Kaludercic" . "philipk@posteo.net")
+ (:authors
+ ("Philip Kaludercic" . "philipk@posteo.net")))])
+ (shelisp .
+ [(1 0 0)
+ nil "execute elisp in shell" tar
+ ((:keywords "terminals" "lisp" "processes")
+ (:maintainer "Michael R. Mauger" . "michael@mauger.com")
+ (:authors
+ ("Michael R. Mauger" . "michael@mauger.com"))
+ (:url . "https://elpa.gnu.org/packages/shelisp.html"))])
+ (shell-command+ .
+ [(2 3 2)
+ ((emacs
+ (24 1)))
+ "An extended shell-command" tar
+ ((:url . "https://git.sr.ht/~pkal/shell-command-plus")
+ (:keywords "unix" "processes" "convenience")
+ (:maintainer "Philip Kaludercic" . "philipk@posteo.net")
+ (:authors
+ ("Philip Kaludercic" . "philipk@posteo.net")))])
+ (shen-mode .
+ [(0 1)
+ nil "A major mode for editing shen source code" tar
+ ((:maintainer "Eric Schulte" . "schulte.eric@gmail.com")
+ (:authors
+ ("Eric Schulte" . "schulte.eric@gmail.com"))
+ (:keywords "languages" "shen")
+ (:url . "http://elpa.gnu.org/packages/shen-mode.html"))])
+ (sisu-mode .
+ [(7 1 8)
+ nil "Major mode for SiSU markup text" single
+ ((:keywords "text" "syntax" "processes" "tools")
+ (:authors
+ ("Ralph Amissah & Ambrose Kofi Laing"))
+ (:maintainer "Ralph Amissah" . "ralph.amissah@gmail.com")
+ (:url . "http://www.sisudoc.org/"))])
+ (sketch-mode .
+ [(1 0 4)
+ nil "Quickly create svg sketches using keyboard and mouse" tar
+ ((:url . "https://github.com/dalanicolai/sketch-mode")
+ (:keywords "multimedia")
+ (:maintainer "D.L. Nicolai" . "dalanicolai@gmail.com")
+ (:authors
+ ("D.L. Nicolai" . "dalanicolai@gmail.com")))])
+ (slime-volleyball .
+ [(1 2 0)
+ ((cl-lib
+ (0 5)))
+ "An SVG Slime Volleyball Game" tar
+ ((:maintainer "Thomas Fitzsimmons" . "fitzsim@fitzsim.org")
+ (:authors
+ ("Thomas Fitzsimmons" . "fitzsim@fitzsim.org"))
+ (:keywords "games")
+ (:url . "https://elpa.gnu.org/packages/slime-volleyball.html"))])
+ (sm-c-mode .
+ [(1 1)
+ nil "C major mode based on SMIE" single
+ ((:url . "http://elpa.gnu.org/packages/sm-c-mode.html")
+ (:authors
+ ("Stefan Monnier" . "monnier@iro.umontreal.ca"))
+ (:maintainer "Stefan Monnier" . "monnier@iro.umontreal.ca"))])
+ (smalltalk-mode .
+ [(4 0)
+ nil "Major mode for the GNU Smalltalk programming language" tar
+ ((:maintainer "Derek Zhou" . "derek@3qin.us")
+ (:authors
+ ("Steve Byrne"))
+ (:url . "https://elpa.gnu.org/packages/smalltalk-mode.html"))])
+ (smart-yank .
+ [(0 1 1)
+ ((emacs
+ (24)))
+ "A different approach of yank pointer handling" single
+ ((:url . "http://elpa.gnu.org/packages/smart-yank.html")
+ (:keywords "convenience")
+ (:authors
+ ("Michael Heerdegen" . "michael_heerdegen@web.de"))
+ (:maintainer "Michael Heerdegen" . "michael_heerdegen@web.de"))])
+ (sml-mode .
+ [(6 10)
+ ((emacs
+ (24 3))
+ (cl-lib
+ (0 5)))
+ "Major mode for editing (Standard) ML" single
+ ((:url . "http://elpa.gnu.org/packages/sml-mode.html")
+ (:keywords "sml")
+ (:authors
+ ("Lars Bo Nielsen")
+ (" Olin Shivers")
+ (" Fritz Knabe (?)")
+ (" Steven Gilmore (?)")
+ (" Matthew Morley" . "mjm@scs.leeds.ac.uk")
+ (" Matthias Blume" . "blume@cs.princeton.edu")
+ (" (Stefan Monnier)" . "monnier@iro.umontreal.ca"))
+ (:maintainer "Stefan Monnier" . "monnier@iro.umontreal.ca"))])
+ (so-long .
+ [(1 1 2)
+ ((emacs
+ (24 4)))
+ "Say farewell to performance problems with minified code." tar
+ ((:url . "https://savannah.nongnu.org/projects/so-long")
+ (:keywords "convenience")
+ (:maintainer "Phil Sainty" . "psainty@orcon.net.nz")
+ (:authors
+ ("Phil Sainty" . "psainty@orcon.net.nz"))
+ (:commit . "045a4fe94c18cd36ef297e62a80cdff449af3aa5"))])
+ (soap-client .
+ [(3 2 1)
+ ((emacs
+ (24 1))
+ (cl-lib
+ (0 6 1)))
+ "Access SOAP web services" tar
+ ((:url . "https://github.com/alex-hhh/emacs-soap-client")
+ (:keywords "soap" "web-services" "comm" "hypermedia")
+ (:maintainer "Alexandru Harsanyi" . "AlexHarsanyi@gmail.com")
+ (:authors
+ ("Alexandru Harsanyi" . "AlexHarsanyi@gmail.com"))
+ (:commit . "37eef19fd608ca81acb40f974b8d7bbe7fc27127"))])
+ (sokoban .
+ [(1 4 8)
+ ((emacs
+ (23 1))
+ (cl-lib
+ (0 5)))
+ "Implementation of Sokoban for Emacs." tar
+ ((:maintainer "Dieter Deyke" . "dieter.deyke@gmail.com")
+ (:authors
+ ("Glynn Clements" . "glynn.clements@xemacs.org"))
+ (:keywords "games")
+ (:url . "http://elpa.gnu.org/packages/sokoban.html"))])
+ (sotlisp .
+ [(1 6 2)
+ ((emacs
+ (24 1)))
+ "Write lisp at the speed of thought." single
+ ((:keywords "convenience" "lisp")
+ (:authors
+ ("Artur Malabarba" . "emacs@endlessparentheses.com"))
+ (:maintainer "Artur Malabarba" . "emacs@endlessparentheses.com")
+ (:url . "https://github.com/Malabarba/speed-of-thought-lisp"))])
+ (spinner .
+ [(1 7 4)
+ ((emacs
+ (24 3)))
+ "Add spinners and progress-bars to the mode-line for ongoing operations" tar
+ ((:url . "https://github.com/Malabarba/spinner.el")
+ (:maintainer "Artur Malabarba" . "emacs@endlessparentheses.com")
+ (:authors
+ ("Artur Malabarba" . "emacs@endlessparentheses.com"))
+ (:keywords "processes" "mode-line"))])
+ (sql-beeline .
+ [(0 1)
+ nil "Beeline support for sql.el" tar
+ ((:keywords "sql" "hive" "beeline" "hiveserver2")
+ (:maintainer "Filipp Gunbin" . "fgunbin@fastmail.fm")
+ (:authors
+ ("Filipp Gunbin" . "fgunbin@fastmail.fm"))
+ (:url . "https://elpa.gnu.org/packages/sql-beeline.html"))])
+ (sql-cassandra .
+ [(0 2 1)
+ ((emacs
+ (29)))
+ "Cassandra support for sql.el" tar
+ ((:keywords "sql" "cassandra" "cql" "cqlsh")
+ (:maintainer "Filipp Gunbin" . "fgunbin@fastmail.fm")
+ (:authors
+ ("Filipp Gunbin" . "fgunbin@fastmail.fm"))
+ (:url . "https://elpa.gnu.org/packages/sql-cassandra.html")
+ (:commit . "2920f8c64e937904087f3636696501fb1cfe7acc"))])
+ (sql-indent .
+ [(1 6)
+ ((cl-lib
+ (0 5)))
+ "Support for indenting code in SQL files." tar
+ ((:url . "https://github.com/alex-hhh/emacs-sql-indent")
+ (:maintainer "Alex Harsanyi" . "AlexHarsanyi@gmail.com")
+ (:authors
+ ("Alex Harsanyi" . "AlexHarsanyi@gmail.com"))
+ (:keywords "languages" "sql"))])
+ (ssh-deploy .
+ [(3 1 13)
+ ((emacs
+ (25)))
+ "Deployment via Tramp, global or per directory." tar
+ ((:url . "https://github.com/cjohansson/emacs-ssh-deploy")
+ (:maintainer "Christian Johansson" . "christian@cvj.se")
+ (:authors
+ ("Christian Johansson" . "christian@cvj.se"))
+ (:keywords "tools" "convenience"))])
+ (stream .
+ [(2 2 5)
+ ((emacs
+ (25)))
+ "Implementation of streams" tar
+ ((:maintainer nil . "nicolas@petton.fr")
+ (:authors
+ ("Nicolas Petton" . "nicolas@petton.fr"))
+ (:keywords "stream" "laziness" "sequences")
+ (:url . "http://elpa.gnu.org/packages/stream.html"))])
+ (svg .
+ [(1 1)
+ ((emacs
+ (25)))
+ "SVG image creation functions" single
+ ((:url . "http://elpa.gnu.org/packages/svg.html")
+ (:keywords "image")
+ (:authors
+ ("Lars Magne Ingebrigtsen" . "larsi@gnus.org")
+ ("Felix E. Klee" . "felix.klee@inka.de"))
+ (:maintainer "Lars Magne Ingebrigtsen" . "larsi@gnus.org"))])
+ (svg-clock .
+ [(1 2)
+ ((svg
+ (1 0))
+ (emacs
+ (27 0)))
+ "Analog clock using Scalable Vector Graphics" single
+ ((:url . "http://elpa.gnu.org/packages/svg-clock.html")
+ (:keywords "demo" "svg" "clock")
+ (:authors
+ ("Ulf Jasper" . "ulf.jasper@web.de"))
+ (:maintainer "Ulf Jasper" . "ulf.jasper@web.de"))])
+ (svg-lib .
+ [(0 2 5)
+ ((emacs
+ (27 1)))
+ "SVG tags, progress bars & icons" tar
+ ((:url . "https://github.com/rougier/svg-lib")
+ (:keywords "svg" "icons" "tags" "convenience")
+ (:maintainer "Nicolas P. Rougier" . "Nicolas.Rougier@inria.fr")
+ (:commit . "0486c9453449771bc3f5872f70bc5cb23580d0f4"))])
+ (svg-tag-mode .
+ [(0 3 2)
+ ((emacs
+ (27 1))
+ (svg-lib
+ (0 2)))
+ "Replace keywords with SVG tags" tar
+ ((:url . "https://github.com/rougier/svg-tag-mode")
+ (:keywords "convenience")
+ (:maintainer "Nicolas P. Rougier" . "Nicolas.Rougier@inria.fr")
+ (:authors
+ ("Nicolas P. Rougier" . "Nicolas.Rougier@inria.fr")))])
+ (swiper .
+ [(0 13 4)
+ ((emacs
+ (24 5))
+ (ivy
+ (0 13 4)))
+ "Isearch with an overview. Oh, man!" tar
+ ((:url . "https://github.com/abo-abo/swiper")
+ (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com")
+ (:authors
+ ("Oleh Krehel" . "ohwoeowho@gmail.com"))
+ (:keywords "matching"))])
+ (system-packages .
+ [(1 0 11)
+ ((emacs
+ (24 3)))
+ "functions to manage system packages" tar
+ ((:url . "https://gitlab.com/jabranham/system-packages")
+ (:maintainer "J. Alexander Branham" . "alex.branham@gmail.com")
+ (:authors
+ ("J. Alexander Branham" . "alex.branham@gmail.com")))])
+ (tNFA .
+ [(0 1 1)
+ ((queue
+ (0 1)))
+ "Tagged non-deterministic finite-state automata" single
+ ((:keywords "extensions" "matching" "data structures tnfa" "nfa" "dfa" "finite state automata" "automata" "regexp")
+ (:authors
+ ("Toby Cubitt" . "toby-predictive@dr-qubit.org"))
+ (:maintainer "Toby Cubitt" . "toby-predictive@dr-qubit.org")
+ (:url . "http://www.dr-qubit.org/emacs.php"))])
+ (taxy .
+ [(0 9)
+ ((emacs
+ (26 3)))
+ "Programmable taxonomical grouping for arbitrary objects" tar
+ ((:url . "https://github.com/alphapapa/taxy.el")
+ (:keywords "lisp")
+ (:maintainer "Adam Porter" . "adam@alphapapa.net")
+ (:authors
+ ("Adam Porter" . "adam@alphapapa.net"))
+ (:commit . "b209692b632bbe8d7f97ea8a39b0c28c1be3b7ec"))])
+ (taxy-magit-section .
+ [(0 9 1)
+ ((emacs
+ (26 3))
+ (magit-section
+ (3 2 1)))
+ "View Taxy structs in a Magit Section buffer" tar
+ ((:url . "https://github.com/alphapapa/taxy.el")
+ (:keywords "lisp")
+ (:maintainer "Adam Porter" . "adam@alphapapa.net")
+ (:authors
+ ("Adam Porter" . "adam@alphapapa.net"))
+ (:commit . "62624c32d7f58bfa4acc89becc7cc8427d546aab"))])
+ (temp-buffer-browse .
+ [(1 5)
+ ((emacs
+ (24)))
+ "temp buffer browse mode" single
+ ((:url . "http://elpa.gnu.org/packages/temp-buffer-browse.html")
+ (:keywords "convenience")
+ (:authors
+ ("Leo Liu" . "sdl.web@gmail.com"))
+ (:maintainer "Leo Liu" . "sdl.web@gmail.com"))])
+ (tempel .
+ [(0 3)
+ ((emacs
+ (27 1)))
+ "Tempo templates/snippets with in-buffer field editing" tar
+ ((:url . "https://github.com/minad/tempel")
+ (:maintainer "Daniel Mendler" . "mail@daniel-mendler.de")
+ (:authors
+ ("Daniel Mendler" . "mail@daniel-mendler.de"))
+ (:commit . "ee964c24b69579fcd5ec3c7d3d1d84d1ca3d90e4"))])
+ (test-simple .
+ [(1 3 0)
+ ((cl-lib
+ (0)))
+ "Simple Unit Test Framework for Emacs Lisp" single
+ ((:keywords "unit-test")
+ (:authors
+ ("Rocky Bernstein" . "rocky@gnu.org"))
+ (:maintainer "Rocky Bernstein" . "rocky@gnu.org")
+ (:url . "http://github.com/rocky/emacs-test-simple"))])
+ (timerfunctions .
+ [(1 4 2)
+ ((cl-lib
+ (0 5))
+ (emacs
+ (24)))
+ "Enhanced versions of some timer.el functions" single
+ ((:url . "http://elpa.gnu.org/packages/timerfunctions.html")
+ (:authors
+ ("Dave Goel" . "deego3@gmail.com"))
+ (:maintainer "Dave Goel" . "deego3@gmail.com"))])
+ (tiny .
+ [(0 2 1)
+ nil "Quickly generate linear ranges in Emacs" tar
+ ((:url . "https://github.com/abo-abo/tiny")
+ (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com")
+ (:authors
+ ("Oleh Krehel" . "ohwoeowho@gmail.com"))
+ (:keywords "convenience"))])
+ (tmr .
+ [(0 2 3)
+ ((emacs
+ (27 1)))
+ "Set timers using a convenient notation" tar
+ ((:url . "https://git.sr.ht/~protesilaos/tmr")
+ (:keywords "convenience" "timer")
+ (:maintainer "Protesilaos Stavrou" . "info@protesilaos.com")
+ (:authors
+ ("Protesilaos Stavrou" . "info@protesilaos.com"))
+ (:commit . "7157ec61c451e3b97ba6117688d0de52bf294bea"))])
+ (tomelr .
+ [(0 2 5)
+ ((emacs
+ (26 3)))
+ "Convert S-expressions to TOML" tar
+ ((:url . "https://github.com/kaushalmodi/tomelr/")
+ (:keywords "data" "tools" "toml" "serialization" "config")
+ (:maintainer "Kaushal Modi" . "kaushal.modi@gmail.com")
+ (:authors
+ ("Kaushal Modi" . "kaushal.modi@gmail.com"))
+ (:commit . "8fc2257ec072a3fc3316c7f311722db50b37558e"))])
+ (tramp .
+ [(2 5 2 4)
+ ((emacs
+ (25 1)))
+ "Transparent Remote Access, Multiple Protocol" tar
+ ((:url . "https://www.gnu.org/software/tramp/")
+ (:keywords "comm" "processes")
+ (:maintainer "Michael Albinus" . "michael.albinus@gmx.de")
+ (:authors
+ ("Kai Großjohann" . "kai.grossjohann@gmx.net"))
+ (:commit . "8f2578d043d2d633c20a74a8b836920b7d0a3fa0"))])
+ (tramp-nspawn .
+ [(1 0)
+ ((emacs
+ (23)))
+ "Tramp integration for systemd-nspawn containers" tar
+ ((:url . "https://github.com/bjc/tramp-nspawn")
+ (:keywords "tramp" "nspawn" "machinectl" "systemd" "systemd-nspawn")
+ (:maintainer "Brian Cully" . "bjc@kublai.com")
+ (:authors
+ ("Brian Cully" . "bjc@kublai.com"))
+ (:commit . "b8380ee8a7c15ad4b96963d224969fc1a0337180"))])
+ (tramp-theme .
+ [(0 2)
+ ((emacs
+ (24 1)))
+ "Custom theme for remote buffers" single
+ ((:url . "http://elpa.gnu.org/packages/tramp-theme.html")
+ (:keywords "convenience" "faces")
+ (:authors
+ ("Michael Albinus" . "michael.albinus@gmx.de"))
+ (:maintainer "Michael Albinus" . "michael.albinus@gmx.de"))])
+ (transcribe .
+ [(1 5 2)
+ nil "Package for audio transcriptions" single
+ ((:url . "http://elpa.gnu.org/packages/transcribe.html")
+ (:authors
+ ("David Gonzalez Gandara" . "dggandara@member.fsf.org"))
+ (:maintainer "David Gonzalez Gandara" . "dggandara@member.fsf.org"))])
+ (transient .
+ [(0 3 7)
+ ((emacs
+ (25 1)))
+ "Transient commands" tar
+ ((:url . "https://github.com/magit/transient")
+ (:keywords "bindings")
+ (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li")
+ (:authors
+ ("Jonas Bernoulli" . "jonas@bernoul.li")))])
+ (transient-cycles .
+ [(1 0)
+ ((emacs
+ (27 1)))
+ "Define command variants with transient cycling" tar
+ ((:url . "https://git.spwhitton.name/dotfiles/tree/.emacs.d/site-lisp/transient-cycles.el")
+ (:keywords "buffer" "window" "minor-mode" "convenience")
+ (:maintainer "Sean Whitton" . "spwhitton@spwhitton.name")
+ (:authors
+ ("Sean Whitton" . "spwhitton@spwhitton.name"))
+ (:commit . "a5b86dd04e84e7ff1cf8c4062843fccb92991145"))])
+ (trie .
+ [(0 5)
+ ((tNFA
+ (0 1 1))
+ (heap
+ (0 3)))
+ "Trie data structure" tar
+ ((:url . "http://www.dr-qubit.org/emacs.php")
+ (:maintainer "Toby Cubitt" . "toby-predictive@dr-qubit.org")
+ (:authors
+ ("Toby Cubitt" . "toby-predictive@dr-qubit.org"))
+ (:keywords "extensions" "matching" "data structures trie" "ternary search tree" "tree" "completion" "regexp"))])
+ (undo-tree .
+ [(0 8 2)
+ ((queue
+ (0 2))
+ (emacs
+ (24 3)))
+ "Treat undo history as a tree" tar
+ ((:url . "https://www.dr-qubit.org/undo-tree.html")
+ (:keywords "convenience" "files" "undo" "redo" "history" "tree")
+ (:maintainer "Toby Cubitt" . "toby+undo-tree@dr-qubit.org")
+ (:authors
+ ("Toby Cubitt" . "toby+undo-tree@dr-qubit.org"))
+ (:commit . "42aab056e37e033816b2d192f9121b89410b958e"))])
+ (uni-confusables .
+ [(0 3)
+ nil "Unicode confusables table" tar
+ ((:maintainer "Teodor Zlatanov" . "tzz@lifelogs.com")
+ (:url . "https://elpa.gnu.org/packages/uni-confusables.html")
+ (:commit . "393e1adeec5b0eb51f9606983655cfe2272c6e54"))])
+ (uniquify-files .
+ [(1 0 3)
+ ((emacs
+ (25 0)))
+ "Completion style for files, minimizing directories" tar
+ ((:keywords "completion" "table" "uniquify")
+ (:maintainer "Stephen Leake" . "stephen_leake@stephe-leake.org")
+ (:authors
+ ("Stephen Leake" . "stephen_leake@stephe-leake.org"))
+ (:url . "https://elpa.gnu.org/packages/uniquify-files.html"))])
+ (url-http-ntlm .
+ [(2 0 4)
+ ((cl-lib
+ (0 5))
+ (ntlm
+ (2 1 0)))
+ "NTLM authentication for the url library" single
+ ((:keywords "comm" "data" "processes" "hypermedia")
+ (:authors
+ ("Tom Schutzer-Weissmann" . "tom.weissmann@gmail.com"))
+ (:maintainer "Thomas Fitzsimmons" . "fitzsim@fitzsim.org")
+ (:url . "https://code.google.com/p/url-http-ntlm/"))])
+ (validate .
+ [(1 0 4)
+ ((emacs
+ (24 1))
+ (cl-lib
+ (0 5))
+ (seq
+ (2 16)))
+ "Schema validation for Emacs-lisp" single
+ ((:url . "http://elpa.gnu.org/packages/validate.html")
+ (:keywords "lisp")
+ (:authors
+ ("Artur Malabarba" . "emacs@endlessparentheses.com"))
+ (:maintainer "Artur Malabarba" . "emacs@endlessparentheses.com"))])
+ (valign .
+ [(3 1 1)
+ ((emacs
+ (26 0)))
+ "Visually align tables" tar
+ ((:url . "https://github.com/casouri/valign")
+ (:maintainer "Yuan Fu" . "casouri@gmail.com")
+ (:authors
+ ("Yuan Fu" . "casouri@gmail.com"))
+ (:keywords "convenience" "text" "table"))])
+ (vc-backup .
+ [(1 1 0)
+ nil "VC backend for versioned backups" tar
+ ((:url . "https://git.sr.ht/~pkal/vc-backup")
+ (:keywords "vc")
+ (:maintainer "Philip Kaludercic" . "philipk@posteo.net")
+ (:authors
+ ("Philip Kaludercic" . "philipk@posteo.net")))])
+ (vc-got .
+ [(1 1)
+ ((emacs
+ (25 1)))
+ "VC backend for Game of Trees VCS" tar
+ ((:url . "https://git.omarpolo.com/vc-got/")
+ (:keywords "vc" "tools")
+ (:maintainer "Omar Polo" . "op@omarpolo.com")
+ (:authors
+ ("Omar Polo" . "op@omarpolo.com")
+ ("Timo Myyrä" . "timo.myyra@bittivirhe.fi"))
+ (:commit . "86d9909a7e54c02179e40afd05693c00f6689edc"))])
+ (vc-hgcmd .
+ [(1 14 1)
+ ((emacs
+ (25 1)))
+ "VC mercurial backend that uses hg command server" tar
+ ((:url . "https://github.com/muffinmad/emacs-vc-hgcmd")
+ (:keywords "vc")
+ (:maintainer "Andrii Kolomoiets" . "andreyk.mad@gmail.com")
+ (:authors
+ ("Andrii Kolomoiets" . "andreyk.mad@gmail.com")))])
+ (vcard .
+ [(0 2 1)
+ ((emacs
+ (27 1)))
+ "Package for handling vCard files" tar
+ ((:maintainer "Eric Abrahamsen" . "eric@ericabrahamsen.net")
+ (:authors
+ ("Eric Abrahamsen" . "eric@ericabrahamsen.net"))
+ (:url . "https://elpa.gnu.org/packages/vcard.html"))])
+ (vcl-mode .
+ [(1 1)
+ nil "Major mode for Varnish Configuration Language" single
+ ((:url . "http://elpa.gnu.org/packages/vcl-mode.html")
+ (:keywords "varnish" "vcl")
+ (:authors
+ ("Sergey Poznyakoff" . "gray@gnu.org.ua"))
+ (:maintainer "Sergey Poznyakoff" . "gray@gnu.org.ua"))])
+ (vdiff .
+ [(0 2 4)
+ ((emacs
+ (24 4))
+ (hydra
+ (0 13 0)))
+ "A diff tool similar to vimdiff" tar
+ ((:url . "https://github.com/justbur/emacs-vdiff")
+ (:maintainer "Justin Burkett" . "justin@burkett.cc")
+ (:authors
+ ("Justin Burkett" . "justin@burkett.cc"))
+ (:keywords "diff"))])
+ (verilog-mode .
+ [(2021 10 14 127365406)
+ nil "major mode for editing verilog source in Emacs" tar
+ ((:url . "https://www.veripool.org")
+ (:keywords "languages")
+ (:maintainer "Michael McNamara" . "mac@verilog.com")
+ (:authors
+ ("Michael McNamara" . "mac@verilog.com")
+ ("Wilson Snyder" . "wsnyder@wsnyder.org"))
+ (:commit . "86f08fb377e2b8f2df0614c48783bdce347f3758"))])
+ (vertico .
+ [(0 23)
+ ((emacs
+ (27 1)))
+ "VERTical Interactive COmpletion" tar
+ ((:url . "https://github.com/minad/vertico")
+ (:maintainer "Daniel Mendler" . "mail@daniel-mendler.de")
+ (:authors
+ ("Daniel Mendler" . "mail@daniel-mendler.de"))
+ (:commit . "68bb4d67e295bd75b8ef1a6d5ddda26849510fa6"))])
+ (vertico-posframe .
+ [(0 5 4)
+ ((emacs
+ (26 0))
+ (posframe
+ (1 1 4))
+ (vertico
+ (0 13 0)))
+ "Using posframe to show Vertico" tar
+ ((:url . "https://github.com/tumashu/vertico-posframe")
+ (:keywords "abbrev" "convenience" "matching" "vertico")
+ (:maintainer "Feng Shu" . "tumashu@163.com")
+ (:authors
+ ("Feng Shu" . "tumashu@163.com"))
+ (:commit . "7ca364d319e7ba8ccba26a0d57513f3e66f1b05b"))])
+ (vigenere .
+ [(1 0)
+ ((emacs
+ (25 1)))
+ "Run a vigenere cipher on a block of text ;" single
+ ((:keywords "data" "vigenere" "cipher")
+ (:authors
+ ("Ian Dunn" . "dunni@gnu.org"))
+ (:maintainer "Ian Dunn" . "dunni@gnu.org")
+ (:url . "https://elpa.gnu.org/packages/vigenere.html"))])
+ (visual-filename-abbrev .
+ [(1 1)
+ ((emacs
+ (26 1)))
+ "Visually abbreviate filenames" tar
+ ((:maintainer "Tassilo Horn" . "tsdh@gnu.org")
+ (:authors
+ ("Tassilo Horn" . "tsdh@gnu.org"))
+ (:keywords "tools")
+ (:url . "https://elpa.gnu.org/packages/visual-filename-abbrev.html"))])
+ (visual-fill .
+ [(0 1)
+ nil "Auto-refill paragraphs without modifying the buffer" single
+ ((:url . "http://elpa.gnu.org/packages/visual-fill.html")
+ (:authors
+ ("Stefan Monnier" . "monnier@iro.umontreal.ca"))
+ (:maintainer "Stefan Monnier" . "monnier@iro.umontreal.ca"))])
+ (vlf .
+ [(1 7 2)
+ nil "View Large Files" tar
+ ((:url . "https://github.com/m00natic/vlfi")
+ (:maintainer "Andrey Kotlarski" . "m00naticus@gmail.com")
+ (:keywords "large files" "utilities"))])
+ (vundo .
+ [(2 0 0)
+ ((emacs
+ (28 1)))
+ "Visual undo tree" tar
+ ((:url . "https://github.com/casouri/vundo")
+ (:keywords "undo" "text" "editing")
+ (:maintainer "Yuan Fu" . "casouri@gmail.com")
+ (:authors
+ ("Yuan Fu" . "casouri@gmail.com"))
+ (:commit . "10d5debe317b2244d19085151040f955dda4a9ab"))])
+ (wcheck-mode .
+ [(2021)
+ nil "General interface for text checkers" tar
+ ((:url . "https://github.com/tlikonen/wcheck-mode")
+ (:keywords "text" "spell" "check" "languages" "ispell")
+ (:maintainer "Teemu Likonen" . "tlikonen@iki.fi")
+ (:authors
+ ("Teemu Likonen" . "tlikonen@iki.fi")))])
+ (wconf .
+ [(0 2 1)
+ ((emacs
+ (24 4)))
+ "Minimal window layout manager" single
+ ((:keywords "windows" "frames" "layout")
+ (:authors
+ ("Ingo Lohmar" . "i.lohmar@gmail.com"))
+ (:maintainer "Ingo Lohmar" . "i.lohmar@gmail.com")
+ (:url . "https://github.com/ilohmar/wconf"))])
+ (web-server .
+ [(0 1 2)
+ ((emacs
+ (24 3)))
+ "Emacs Web Server" tar
+ ((:url . "https://github.com/eschulte/emacs-web-server")
+ (:maintainer "Eric Schulte" . "schulte.eric@gmail.com")
+ (:authors
+ ("Eric Schulte" . "schulte.eric@gmail.com"))
+ (:keywords "http" "server" "network"))])
+ (webfeeder .
+ [(1 1 2)
+ ((emacs
+ (25 1)))
+ "Build RSS and Atom webfeeds from HTML files" tar
+ ((:url . "https://gitlab.com/Ambrevar/emacs-webfeeder")
+ (:maintainer "Pierre Neidhardt" . "mail@ambrevar.xyz")
+ (:authors
+ ("Pierre Neidhardt" . "mail@ambrevar.xyz"))
+ (:keywords "news" "hypermedia" "blog" "feed" "rss" "atom"))])
+ (websocket .
+ [(1 13 1)
+ ((cl-lib
+ (0 5)))
+ "Emacs WebSocket client and server" tar
+ ((:url . "https://github.com/ahyatt/emacs-websocket")
+ (:maintainer "Andrew Hyatt" . "ahyatt@gmail.com")
+ (:authors
+ ("Andrew Hyatt" . "ahyatt@gmail.com"))
+ (:keywords "communication" "websocket" "server"))])
+ (which-key .
+ [(3 6 0)
+ ((emacs
+ (24 4)))
+ "Display available keybindings in popup" tar
+ ((:url . "https://github.com/justbur/emacs-which-key")
+ (:maintainer "Justin Burkett" . "justin@burkett.cc")
+ (:authors
+ ("Justin Burkett" . "justin@burkett.cc"))
+ (:commit . "1217db8c6356659e67b35dedd9f5f260c06f6e99"))])
+ (windower .
+ [(0 0 1)
+ ((emacs
+ (25)))
+ "Helper functions for window manipulation." single
+ ((:keywords "convenience" "tools")
+ (:authors
+ ("Pierre Neidhardt" . "mail@ambrevar.xyz"))
+ (:maintainer "Pierre Neidhardt" . "mail@ambrevar.xyz")
+ (:url . "https://gitlab.com/ambrevar/windower"))])
+ (windresize .
+ [(0 1)
+ nil "Resize windows interactively" single
+ ((:url . "http://elpa.gnu.org/packages/windresize.html")
+ (:keywords "window")
+ (:authors
+ ("Bastien" . "bzg@gnu.org"))
+ (:maintainer "Bastien" . "bzg@gnu.org"))])
+ (wisi .
+ [(3 1 7)
+ ((emacs
+ (25 3))
+ (seq
+ (2 20)))
+ "Utilities for implementing an indentation/navigation engine using a generalized LALR parser" tar
+ ((:url . "http://stephe-leake.org/ada/wisitoken.html")
+ (:keywords "parser" "indentation" "navigation")
+ (:maintainer "Stephen Leake" . "stephen_leake@stephe-leake.org")
+ (:authors
+ ("Stephen Leake" . "stephen_leake@stephe-leake.org")))])
+ (wisitoken-grammar-mode .
+ [(1 2 0)
+ ((wisi
+ (3 1 1))
+ (emacs
+ (25 0))
+ (mmm-mode
+ (0 5 7)))
+ "Major mode for editing WisiToken grammar files" tar
+ ((:url . "http://www.nongnu.org/ada-mode/")
+ (:maintainer "Stephen Leake" . "stephen_leake@stephe-leake.org")
+ (:authors
+ ("Stephen Leake" . "stephen_leake@stephe-leake.org"))
+ (:keywords "languages"))])
+ (wpuzzle .
+ [(1 1)
+ nil "find as many word in a given time" single
+ ((:url . "http://elpa.gnu.org/packages/wpuzzle.html")
+ (:authors
+ ("Ivan Kanis" . "ivan@kanis.fr"))
+ (:maintainer "Ivan Kanis" . "ivan@kanis.fr"))])
+ (xclip .
+ [(1 11)
+ nil "Copy&paste GUI clipboard from text terminal" tar
+ ((:keywords "convenience" "tools")
+ (:maintainer "Leo Liu" . "sdl.web@gmail.com")
+ (:authors
+ ("Leo Liu" . "sdl.web@gmail.com"))
+ (:url . "https://elpa.gnu.org/packages/xclip.html")
+ (:commit . "5b54645cab438e133e27b4690c57066f8271a992"))])
+ (xelb .
+ [(0 18)
+ ((emacs
+ (24 4))
+ (cl-generic
+ (0 2)))
+ "X protocol Emacs Lisp Binding" tar
+ ((:url . "https://github.com/ch11ng/xelb")
+ (:maintainer "Chris Feng" . "chris.w.feng@gmail.com")
+ (:authors
+ ("Chris Feng" . "chris.w.feng@gmail.com"))
+ (:keywords "unix"))])
+ (xpm .
+ [(1 0 5)
+ ((cl-lib
+ (0 5))
+ (queue
+ (0 2)))
+ "edit XPM images" tar
+ ((:url . "https://www.gnuvola.org/software/xpm/")
+ (:keywords "multimedia" "xpm")
+ (:maintainer "Thien-Thi Nguyen" . "ttn@gnu.org")
+ (:authors
+ ("Thien-Thi Nguyen" . "ttn@gnu.org")))])
+ (xr .
+ [(1 22)
+ ((emacs
+ (26 1)))
+ "Convert string regexp to rx notation" tar
+ ((:url . "https://github.com/mattiase/xr")
+ (:keywords "lisp" "regexps")
+ (:maintainer "Mattias Engdegård" . "mattiase@acm.org")
+ (:authors
+ ("Mattias Engdegård" . "mattiase@acm.org"))
+ (:commit . "a873bbbe9cdf1abab63fc94730966f5a8f9adaa6"))])
+ (xref .
+ [(1 4 1)
+ ((emacs
+ (26 1)))
+ "Cross-referencing commands" tar
+ ((:url . "https://elpa.gnu.org/packages/xref.html")
+ (:commit . "890b08e41580a716c2f0b3f1a40ef9b52a19372c"))])
+ (yasnippet .
+ [(0 14 0)
+ ((cl-lib
+ (0 5)))
+ "Yet another snippet extension for Emacs" tar
+ ((:url . "http://github.com/joaotavora/yasnippet")
+ (:maintainer "Noam Postavsky" . "npostavs@gmail.com")
+ (:keywords "convenience" "emulation"))])
+ (yasnippet-classic-snippets .
+ [(1 0 2)
+ ((yasnippet
+ (0 9 1)))
+ "\"Classic\" yasnippet snippets" tar
+ ((:maintainer "Noam Postavsky" . "npostavs@gmail.com")
+ (:keywords "snippets")
+ (:url . "http://elpa.gnu.org/packages/yasnippet-classic-snippets.html"))])
+ (zones .
+ [(2019 7 13)
+ nil "Zones of text - like multiple regions" single
+ ((:keywords "narrow" "restriction" "widen" "region" "zone")
+ (:authors
+ ("Drew Adams"))
+ (:maintainer "Drew Adams" . "drew.adams@oracle.com")
+ (:url . "https://elpa.gnu.org/packages/zones.html"))])
+ (ztree .
+ [(1 0 6)
+ ((cl-lib
+ (0)))
+ "Text mode directory tree" tar
+ ((:url . "https://github.com/fourier/ztree")
+ (:maintainer "Alexey Veretennikov" . "alexey.veretennikov@gmail.com")
+ (:authors
+ ("Alexey Veretennikov" . "alexey.veretennikov@gmail.com"))
+ (:keywords "files" "tools"))]))
diff --git a/elpa/archives/gnu/archive-contents.signed b/elpa/archives/gnu/archive-contents.signed
new file mode 100644
index 0000000..0460341
--- /dev/null
+++ b/elpa/archives/gnu/archive-contents.signed
@@ -0,0 +1 @@
+Good signature from 066DAFCB81E42C40 GNU ELPA Signing Agent (2019) <elpasign@elpa.gnu.org> (trust undefined) created at 2022-05-05T02:45:02+0530 using RSA \ No newline at end of file
diff --git a/elpa/archives/melpa/archive-contents b/elpa/archives/melpa/archive-contents
new file mode 100644
index 0000000..748d63a
--- /dev/null
+++ b/elpa/archives/melpa/archive-contents
@@ -0,0 +1,5177 @@
+(1
+ (0blayout . [(20190703 527) nil "Layout grouping with ease" single ((:commit . "fd9a8f353dbd45b4628b5f84b8d8c2525ebf571d") (:authors ("Elis \"etu\" Axelsson")) (:maintainer "Elis \"etu\" Axelsson") (:keywords "convenience" "window-management") (:url . "https://github.com/etu/0blayout"))])
+ (0x0 . [(20210701 839) ((emacs (26 1))) "Upload sharing to 0x0.st" single ((:commit . "63cd5eccc85e527f28e1acc89502a53245000428") (:authors ("William Vaughn <https://gitlab.com/willvaughn>")) (:maintainer "William Vaughn" . "vaughnwilld@gmail.com") (:url . "https://gitlab.com/willvaughn/emacs-0x0"))])
+ (0xc . [(20201025 2105) ((emacs (24 4)) (s (1 11 0))) "Base conversion made easy" tar ((:commit . "eec4fb10b9288c0852f751cfb05d638664fa2411") (:authors ("Adam Niederer" . "adam.niederer@gmail.com")) (:maintainer "Adam Niederer" . "adam.niederer@gmail.com") (:keywords "base" "conversion") (:url . "http://github.com/AdamNiederer/0xc"))])
+ (2048-game . [(20200417 259) nil "play 2048 in Emacs" single ((:commit . "aad4a590ea91f9a3256233b9b345e9159c6993f2") (:authors ("Zachary Kanfer" . "zkanfer@gmail.com")) (:maintainer "Zachary Kanfer" . "zkanfer@gmail.com") (:url . "https://hg.sr.ht/~zck/game-2048"))])
+ (2bit . [(20200926 1418) ((emacs (24 3))) "Library for reading data from 2bit files" single ((:commit . "69b4ec1d6d2ad95c9e59dacb43224abbec7a8989") (:authors ("Dave Pearson" . "davep@davep.org")) (:maintainer "Dave Pearson" . "davep@davep.org") (:keywords "files" "data") (:url . "https://github.com/davep/2bit.el"))])
+ (4clojure . [(20210102 459) ((request (0 2 0))) "Open and evaluate 4clojure.com questions." single ((:commit . "6f494d3905284ccdd57aae3d8ac16fc7ab431596") (:authors ("Joshua Hoff")) (:maintainer "Sasha Kovar" . "sasha-git@arcocene.org") (:keywords "languages" "data") (:url . "https://github.com/abend/4clojure.el"))])
+ (750words . [(20210701 1950) ((emacs (24 4))) "Emacs integration and Org exporter for 750words.com" single ((:commit . "0fed7621c04debad64ea6455455494d4e6eb03fa") (:authors ("Diego Zamboni <https://github.com/zzamboni>")) (:maintainer "Diego Zamboni" . "diego@zzamboni.org") (:keywords "files" "org" "writing") (:url . "https://github.com/zzamboni/750words-client"))])
+ (@ . [(20181225 1438) ((emacs (24 3))) "multiple-inheritance prototype-based objects DSL" tar ((:commit . "0a6189f8be42dbbc5d9358cbd447d471236135a2") (:authors ("Christopher Wellons" . "wellons@nullprogram.com")) (:maintainer "Christopher Wellons" . "wellons@nullprogram.com") (:url . "https://github.com/skeeto/at-el"))])
+ (a . [(20210929 1510) ((emacs (25))) "Associative data structure functions" single ((:commit . "93e5ed8c495794d1ba3c04b43041b95ce01079b1") (:authors ("Arne Brasseur" . "arne@arnebrasseur.net")) (:maintainer "Arne Brasseur" . "arne@arnebrasseur.net") (:keywords "lisp") (:url . "https://github.com/plexus/a.el"))])
+ (aa-edit-mode . [(20170119 320) ((emacs (24 3)) (navi2ch (2 0 0))) "Major mode for editing AA(S_JIS Art) and .mlt file" single ((:commit . "1dd801225b7ad3c23ad09698f5e77f0df7012a65") (:authors ("USAMI Kenta" . "tadsan@zonu.me")) (:maintainer "USAMI Kenta" . "tadsan@zonu.me") (:keywords "wp" "text" "shiftjis" "mlt" "yaruo"))])
+ (aas . [(20220426 2058) ((emacs (26 3))) "Snippet expansions mid-typing" single ((:commit . "566944e3b336c29d3ac11cd739a954c9d112f3fb") (:authors ("Yoav Marco" . "yoavm448@gmail.com")) (:maintainer "Yoav Marco" . "yoavm448@gmail.com") (:keywords "abbrev" "tools") (:url . "https://github.com/ymarco/auto-activating-snippets"))])
+ (abc-mode . [(20210508 1552) nil "Major mode for editing abc music files" single ((:commit . "80fa954787b57d14e21e19bd65e52abab1686f4a") (:authors ("Matthew K. Junker" . "junker@alum.mit.edu")) (:maintainer "Matthew K. Junker" . "junker@alum.mit.edu") (:keywords "local" "docs"))])
+ (abgaben . [(20171119 646) ((pdf-tools (0 80)) (f (0 19 0)) (s (1 11 0))) "review and correct assignments received by mail" single ((:commit . "20d14830f07d66e2a04bcad1498a4a6fbf4b4451") (:authors ("Arne Köhn" . "arne@chark.eu")) (:maintainer "Arne Köhn" . "arne@chark.eu") (:keywords "mail" "outlines" "convenience") (:url . "http://arne.chark.eu/"))])
+ (abl-mode . [(20210923 950) nil "Python TDD minor mode" single ((:commit . "0d6aace2ffd184137618a0c6e7f29826cbd8d1f9") (:authors ("Ulas Tuerkmen <ulas.tuerkmen at gmail dot com>")) (:maintainer "Ulas Tuerkmen <ulas.tuerkmen at gmail dot com>") (:url . "http://github.com/afroisalreadyinu/abl-mode"))])
+ (abridge-diff . [(20220419 2358) ((emacs (26 1))) "Abridge long line-based diff hunks, including in magit" single ((:commit . "996d921da0a0ee651b3486c2afe29447f48be50f") (:authors ("J.D. Smith <jdtsmith AT gmail>")) (:maintainer "J.D. Smith <jdtsmith AT gmail>") (:keywords "magit" "diffs" "tools") (:url . "https://github.com/jdtsmith/abridge-diff"))])
+ (abs-mode . [(20220316 921) ((emacs (26 1)) (erlang (2 8)) (maude-mode (0 3)) (flymake (1 0))) "Major mode for the modeling language Abs" single ((:commit . "d860ddbbd7cb93c7a77980c78c1a2a7634ef01e1") (:authors ("Rudi Schlatte" . "rudi@constantly.at")) (:maintainer "Rudi Schlatte" . "rudi@constantly.at") (:keywords "languages") (:url . "https://github.com/abstools/abs-mode"))])
+ (abyss-theme . [(20170808 1345) ((emacs (24))) "A dark theme with contrasting colours." single ((:commit . "18791c6e8d9cc2b4815c9f08627a2e94fc0eeb14") (:authors ("Matt Russell" . "matt@mgrbyte.co.uk")) (:maintainer "Matt Russell" . "matt@mgrbyte.co.uk") (:keywords "theme" "dark" "contrasting colours") (:url . "https://github.com/mgrbyte/emacs-abyss-theme"))])
+ (ac-alchemist . [(20150908 656) ((auto-complete (1 5 0)) (alchemist (1 5 0)) (cl-lib (0 5))) "auto-complete source for alchemist" single ((:commit . "b1891c3d41aed83f61d78a609ea97be5cc2758d9") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-ac-alchemist"))])
+ (ac-c-headers . [(20200816 1007) ((auto-complete (1 3 1))) "auto-complete source for C headers" single ((:commit . "67e1e86a48c9bed57bc7ce5ce2553ad203f5752e") (:authors ("zk_phi")) (:maintainer "zk_phi") (:url . "http://zk-phi.gitub.io/"))])
+ (ac-capf . [(20151101 217) ((auto-complete (1 4)) (cl-lib (0 5))) "auto-complete source with completion-at-point" single ((:commit . "17571dba0a8f98111f2ab758e9bea285b263781b") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-ac-capf"))])
+ (ac-cider . [(20161006 719) ((cider (0 8 0)) (auto-complete (1 4)) (cl-lib (0 3))) "Clojure auto-complete sources using CIDER" single ((:commit . "fa13e067dd9c8c76151c7d140a2803da1d109b84") (:authors ("Alex Yakushev" . "alex@bytopia.org") ("Steve Purcell" . "steve@sanityinc.com") ("Sam Aaron" . "samaaron@gmail.com")) (:maintainer "Alex Yakushev" . "alex@bytopia.org") (:keywords "languages" "clojure" "nrepl" "cider" "compliment") (:url . "https://github.com/clojure-emacs/ac-cider"))])
+ (ac-clang . [(20180710 546) ((emacs (24)) (cl-lib (0 5)) (auto-complete (1 4 0)) (pos-tip (0 4 6)) (yasnippet (0 8 0))) "Auto Completion source by libclang for GNU Emacs" tar ((:commit . "3294b968eb1a8317049190940193f9da47c085ef") (:authors ("yaruopooner [https://github.com/yaruopooner]")) (:maintainer "yaruopooner [https://github.com/yaruopooner]") (:keywords "completion" "convenience" "intellisense") (:url . "https://github.com/yaruopooner/ac-clang"))])
+ (ac-dcd . [(20210428 1556) ((auto-complete (1 3 1)) (flycheck-dmd-dub (0 7))) "Auto Completion source for dcd for GNU Emacs" single ((:commit . "56d9817159acdebdbb3d5499c7e9379d29af0cd4") (:authors (nil . "<atila.neves@gmail.com>")) (:maintainer nil . "<atila.neves@gmail.com>") (:keywords "languages") (:url . "http://github.com/atilaneves/ac-dcd"))])
+ (ac-emacs-eclim . [(20180911 1121) ((eclim (0 3)) (auto-complete (1 5))) "auto-complete source for eclim" single ((:commit . "222ddd48fcf0ee01592dec77c58e0cf3f2ea1100"))])
+ (ac-emmet . [(20131015 1558) ((emmet-mode (1 0 2)) (auto-complete (1 4))) "auto-complete sources for emmet-mode's snippets" single ((:commit . "88f24876ee3b759978d4614a758280b5d512d543") (:authors ("Yasuyuki Oka" . "yasuyk@gmail.com")) (:maintainer "Yasuyuki Oka" . "yasuyk@gmail.com") (:keywords "completion" "convenience" "emmet") (:url . "https://github.com/yasuyk/ac-emmet"))])
+ (ac-emoji . [(20150823 711) ((auto-complete (1 5 0)) (cl-lib (0 5))) "auto-complete source of Emoji" tar ((:commit . "40a639764eb654f1b4bb705c817b66032a26ff2b") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-ac-emoji"))])
+ (ac-etags . [(20161001 1507) ((auto-complete (1 4))) "etags/ctags completion source for auto-complete" single ((:commit . "7983e631c226fe0fa53af3b2d56bf4eca3d785ce") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-ac-etags"))])
+ (ac-geiser . [(20200318 824) ((geiser (0 5)) (auto-complete (1 4))) "Auto-complete backend for geiser" tar ((:commit . "93818c936ee7e2f1ba1b315578bde363a7d43d05"))])
+ (ac-haskell-process . [(20150423 1402) ((auto-complete (1 4)) (haskell-mode (13))) "Haskell auto-complete source which uses the current haskell process" single ((:commit . "0362d4323511107ec70e7165cb612f3ab01b712f") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:keywords "languages"))])
+ (ac-helm . [(20160319 233) ((helm (1 6 3)) (auto-complete (1 4 0)) (popup (0 5 0)) (cl-lib (0 5))) "Helm interface for auto-complete" single ((:commit . "baf2b1e04bcffa835084389c0fab415f26efbf32") (:authors ("rubikitch" . "rubikitch@ruby-lang.org") ("Yasuyuki Oka" . "yasuyk@gmail.com")) (:maintainer "Yasuyuki Oka" . "yasuyk@gmail.com") (:keywords "completion" "convenience" "helm"))])
+ (ac-html . [(20151005 731) ((auto-complete (1 4)) (s (1 9)) (f (0 17)) (dash (2 10))) "auto complete source for html tags and attributes" tar ((:commit . "668154cba123c321d1b07c2dc8b26d14092253b8") (:authors ("Zhang Kai Yu" . "yeannylam@gmail.com")) (:maintainer "Zhang Kai Yu" . "yeannylam@gmail.com") (:keywords "html" "auto-complete" "slim" "haml" "jade") (:url . "https://github.com/cheunghy/ac-html"))])
+ (ac-html-angular . [(20151225 719) ((web-completion-data (0 1))) "auto complete angular15 data for `ac-html' and `company-web'" tar ((:commit . "6bafe09afe03112ca4183d58461c1a6f6c2b3c67") (:authors ("Olexandr Sydorchuk" . "olexandr.syd@gmail.com")) (:maintainer "Olexandr Sydorchuk" . "olexandr.syd@gmail.com") (:keywords "html" "auto-complete" "angular") (:url . "https://github.com/osv/ac-html-bootstrap"))])
+ (ac-html-bootstrap . [(20160302 1701) ((web-completion-data (0 1))) "auto complete bootstrap3/fontawesome classes for `ac-html' and `company-web'" tar ((:commit . "481e6e441cd566554ce71cd8cb28c9e7ebb1c24b") (:authors ("Olexandr Sydorchuk" . "olexandr.syd@gmail.com")) (:maintainer "Olexandr Sydorchuk" . "olexandr.syd@gmail.com") (:keywords "html" "auto-complete" "bootstrap" "cssx") (:url . "https://github.com/osv/ac-html-bootstrap"))])
+ (ac-html-csswatcher . [(20151208 2113) ((web-completion-data (0 1))) "css/less class/id completion with `ac-html' or `company-web'" single ((:commit . "b0f3e7e1a3fe49e88b6eb6432377232fc715f221") (:authors ("Olexandr Sydorchuck " . "olexandr.syd@gmail.com")) (:maintainer "Olexandr Sydorchuck " . "olexandr.syd@gmail.com") (:keywords "html" "css" "less" "auto-complete") (:url . "https://github.com/osv/ac-html-csswatcher"))])
+ (ac-inf-ruby . [(20131115 1150) ((inf-ruby (2 3 2)) (auto-complete (1 4))) "Enable auto-complete in inf-ruby sessions" single ((:commit . "ee53fc9c61950da9a96df3ff5ef186f9a9faf151") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:keywords "languages" "tools"))])
+ (ac-ispell . [(20151101 226) ((auto-complete (1 4)) (cl-lib (0 5))) "ispell completion source for auto-complete" single ((:commit . "22bace7387e9012002a6a444922f75f9913077b0") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-ac-ispell"))])
+ (ac-js2 . [(20190101 933) ((js2-mode (20090723)) (skewer-mode (1 4))) "Auto-complete source for Js2-mode, with navigation" tar ((:commit . "2b56d09a16c1a0ce514cc1b85d64cb1be4502723") (:authors ("Scott Barnett" . "scott.n.barnett@gmail.com")) (:maintainer "Scott Barnett" . "scott.n.barnett@gmail.com") (:url . "https://github.com/ScottyB/ac-js2"))])
+ (ac-math . [(20141116 2127) ((auto-complete (1 4)) (math-symbol-lists (1 0))) "Auto-complete sources for input of mathematical symbols and latex tags" single ((:commit . "c012a8f620a48cb18db7d78995035d65eae28f11") (:authors ("Vitalie Spinu")) (:maintainer "Vitalie Spinu") (:keywords "latex" "auto-complete" "unicode" "symbols") (:url . "https://github.com/vitoshka/ac-math"))])
+ (ac-mozc . [(20150227 1619) ((cl-lib (0 5)) (auto-complete (1 4)) (mozc (0))) "auto-complete sources for Japanese input using Mozc" single ((:commit . "4c6c8be4701010d9362184437c0f783e0335c631") (:authors ("igjit" . "igjit1@gmail.com")) (:maintainer "igjit" . "igjit1@gmail.com") (:url . "https://github.com/igjit/ac-mozc"))])
+ (ac-octave . [(20180406 334) ((auto-complete (1 4 0))) "An auto-complete source for Octave" single ((:commit . "fe0f931f2024f43de3c4fff4b1ace672413adeae") (:authors ("coldnew" . "coldnew.tw@gmail.com")) (:maintainer "coldnew" . "coldnew.tw@gmail.com") (:keywords "octave" "auto-complete" "completion") (:url . "https://github.com/coldnew/ac-octave"))])
+ (ac-php . [(20200916 751) ((ac-php-core (2 0)) (auto-complete (1 4 0)) (yasnippet (0 8 0))) "Auto Completion source for PHP." single ((:commit . "f34e09783b77d1158ea139b7b3d8034bc52b0b9f") (:authors ("jim" . "xcwenn@qq.com")) (:maintainer "jim") (:keywords "completion" "convenience" "intellisense") (:url . "https://github.com/xcwen/ac-php"))])
+ (ac-php-core . [(20220418 419) ((dash (1)) (php-mode (1)) (s (1)) (f (0 17 0)) (popup (0 5 0)) (xcscope (1 0))) "The core library of the ac-php" tar ((:commit . "f34e09783b77d1158ea139b7b3d8034bc52b0b9f") (:authors ("jim" . "xcwenn@qq.com") ("Serghei Iakovlev" . "sadhooklay@gmail.com")) (:maintainer "jim") (:keywords "completion" "convenience" "intellisense") (:url . "https://github.com/xcwen/ac-php"))])
+ (ac-racer . [(20170114 809) ((emacs (24 3)) (auto-complete (1 5 0)) (racer (0 0 2))) "auto-complete source of racer" single ((:commit . "4408c2d652dec0432e20c05e001db8222d778c6b") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-ac-racer"))])
+ (ac-rtags . [(20191222 920) ((auto-complete (1 4 0)) (rtags (2 10))) "auto-complete back-end for RTags" single ((:commit . "db39790fda5c2443bc790b8971ac140914f7e9c2") (:authors ("Jan Erik Hanssen" . "jhanssen@gmail.com") ("Anders Bakken" . "agbakken@gmail.com")) (:maintainer "Jan Erik Hanssen" . "jhanssen@gmail.com") (:url . "https://github.com/Andersbakken/rtags"))])
+ (ac-skk . [(20141230 119) ((auto-complete (1 3 1)) (ddskk (16 0 50)) (tinysegmenter (0)) (cl-lib (0 5))) "auto-complete-mode source for DDSKK a.k.a Japanese input method" single ((:commit . "d25a265930430d080329789fb253d786c01dfa24") (:authors ("lugecy <https://twitter.com/lugecy>")) (:maintainer "myuhe") (:keywords "convenience" "auto-complete") (:url . "https://github.com/myuhe/ac-skk.el"))])
+ (ac-slime . [(20171027 2100) ((auto-complete (1 4)) (slime (2 9)) (cl-lib (0 5))) "An auto-complete source using slime completions" single ((:commit . "6c80cb602ddad46486288f94ad7546396c6e4b1a") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:url . "https://github.com/purcell/ac-slime"))])
+ (ac-sly . [(20170728 1027) ((sly (1 0 0 -3)) (auto-complete (1 4)) (cl-lib (0 5))) "An auto-complete source using sly completions" single ((:commit . "bf69c687c4ecf1994349d20c182e9b567399912e") (:authors ("Damian T. Dobroczy\\'nski" . "qoocku@gmail.com")) (:maintainer "Damian T. Dobroczy\\'nski" . "qoocku@gmail.com") (:url . "https://github.com/qoocku/ac-sly"))])
+ (academic-phrases . [(20180723 1021) ((dash (2 12 0)) (s (1 12 0)) (ht (2 0)) (emacs (24))) "Bypass that mental block when writing your papers." single ((:commit . "25d9cf67feac6359cb213f061735e2679c84187f") (:authors ("Nasser Alshammari" . "designernasser@gmail.com")) (:maintainer "Nasser Alshammari" . "designernasser@gmail.com") (:keywords "academic" "convenience" "papers" "writing" "wp") (:url . "https://github.com/nashamri/academic-phrases"))])
+ (accent . [(20220202 1312) ((emacs (24 3)) (popup (0 5 8))) "Popup for accented characters (diacritics)" single ((:commit . "6b502df6940587dae2dfbd349c22dfd44c803a86") (:authors ("Elia Scotto" . "eliascotto94@gmail.com")) (:maintainer "Elia Scotto" . "eliascotto94@gmail.com") (:keywords "i18n") (:url . "https://github.com/elias94/accent"))])
+ (ace-flyspell . [(20170309 509) ((avy (0 4 0))) "Jump to and correct spelling errors using `ace-jump-mode' and flyspell" single ((:commit . "538d4f8508d305262ba0228dfe7c819fb65b53c9") (:authors ("Junpeng Qiu" . "qjpchmail@gmail.com")) (:maintainer "Junpeng Qiu" . "qjpchmail@gmail.com") (:keywords "extensions") (:url . "https://github.com/cute-jumper/ace-flyspell"))])
+ (ace-isearch . [(20210830 746) ((emacs (24))) "A seamless bridge between isearch, ace-jump-mode, avy, helm-swoop and swiper" single ((:commit . "8439136206a42e41ef95af923e0dc3bbd4fa306c") (:authors ("Akira Tamamori")) (:maintainer "Akira Tamamori") (:url . "https://github.com/tam17aki/ace-isearch"))])
+ (ace-jump-buffer . [(20171031 1550) ((avy (0 4 0)) (dash (2 4 0))) "fast buffer switching extension to `avy'" single ((:commit . "0d335064230caf3efdd5a732e8fbd67e3948ed6a") (:authors ("Justin Talbott" . "justin@waymondo.com")) (:maintainer "Justin Talbott" . "justin@waymondo.com") (:url . "https://github.com/waymondo/ace-jump-buffer"))])
+ (ace-jump-helm-line . [(20160918 1836) ((avy (0 4 0)) (helm (1 6 3))) "Ace-jump to a candidate in helm window" single ((:commit . "1483055255df3f8ae349f7520f05b1e43ea3ed37") (:authors ("Junpeng Qiu" . "qjpchmail@gmail.com")) (:maintainer "Junpeng Qiu" . "qjpchmail@gmail.com") (:keywords "extensions") (:url . "https://github.com/cute-jumper/ace-jump-helm-line"))])
+ (ace-jump-mode . [(20140616 815) nil "a quick cursor location minor mode for emacs" single ((:commit . "8351e2df4fbbeb2a4003f2fb39f46d33803f3dac") (:authors ("winterTTr" . "winterTTr@gmail.com")) (:maintainer "winterTTr" . "winterTTr@gmail.com") (:keywords "motion" "location" "cursor") (:url . "https://github.com/winterTTr/ace-jump-mode/"))])
+ (ace-jump-zap . [(20170717 1849) ((ace-jump-mode (1 0)) (dash (2 10 0))) "Character zapping, `ace-jump-mode` style" single ((:commit . "52b5d4c6c73bd0fc833a0dcb4e803a5287d8cae8") (:authors ("justin talbott" . "justin@waymondo.com")) (:maintainer "justin talbott" . "justin@waymondo.com") (:keywords "convenience" "tools" "extensions") (:url . "https://github.com/waymondo/ace-jump-zap"))])
+ (ace-link . [(20210121 923) ((avy (0 4 0))) "Quickly follow links" single ((:commit . "e1b1c91b280d85fce2194fea861a9ae29e8b03dd") (:authors ("Oleh Krehel" . "ohwoeowho@gmail.com")) (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com") (:keywords "convenience" "links" "avy") (:url . "https://github.com/abo-abo/ace-link"))])
+ (ace-mc . [(20190206 749) ((ace-jump-mode (1 0)) (multiple-cursors (1 0)) (dash (2 10 0))) "Add multiple cursors quickly using ace jump" single ((:commit . "6877880efd99e177e4e9116a364576def3da391b") (:authors ("Josh Moller-Mara" . "jmm@cns.nyu.edu")) (:maintainer "Josh Moller-Mara" . "jmm@cns.nyu.edu") (:keywords "motion" "location" "cursor") (:url . "https://github.com/mm--/ace-mc"))])
+ (ace-pinyin . [(20210827 355) ((avy (0 2 0)) (pinyinlib (0 1 0))) "Jump to Chinese characters using avy or ace-jump-mode" single ((:commit . "47662c0b05775ba353464b44c0f1a037c85e746e") (:authors ("Junpeng Qiu" . "qjpchmail@gmail.com")) (:maintainer "Junpeng Qiu" . "qjpchmail@gmail.com") (:keywords "extensions") (:url . "https://github.com/cute-jumper/ace-pinyin"))])
+ (ace-popup-menu . [(20210608 839) ((emacs (24 3)) (avy-menu (0 1))) "Replace GUI popup menu with something more efficient" single ((:commit . "bc3524eaa28b21725287b59b903c03624cbd5316") (:authors ("Mark Karpov" . "markkarpov92@gmail.com")) (:maintainer "Mark Karpov" . "markkarpov92@gmail.com") (:keywords "convenience" "popup" "menu") (:url . "https://github.com/mrkkrp/ace-popup-menu"))])
+ (ace-window . [(20200606 1259) ((avy (0 5 0))) "Quickly switch windows." single ((:commit . "0577c426a9833ab107bab46c60d1885c611b2fb9") (:authors ("Oleh Krehel" . "ohwoeowho@gmail.com")) (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com") (:keywords "window" "location") (:url . "https://github.com/abo-abo/ace-window"))])
+ (achievements . [(20150531 1317) ((keyfreq (0 0 3))) "Achievements for emacs usage." tar ((:commit . "c8275ee492d56255999d58f2988129ab29145182") (:authors ("Ivan Andrus" . "darthandrus@gmail.com")) (:maintainer "Ivan Andrus" . "darthandrus@gmail.com") (:keywords "games"))])
+ (ack-menu . [(20150504 2022) ((mag-menu (0 1 0))) "A menu-based front-end for ack" single ((:commit . "f77be93a4697926ecf3195a355eb69580f695f4d") (:authors ("Steven Thomas") ("Nikolaj Schumacher")) (:maintainer "Steven Thomas") (:keywords "tools" "matching" "convenience") (:url . "https://github.com/chumpage/ack-menu"))])
+ (acme-theme . [(20210430 302) nil "A color theme based on Acme & Sam from Plan 9" single ((:commit . "7c408d111c5e451ecb8fdd5f76cf7d8074aec793") (:authors ("Ian Y.E. Pan")) (:maintainer "Ian Y.E. Pan") (:url . "https://github.com/ianpan870102/acme-emacs-theme"))])
+ (actionscript-mode . [(20180527 1701) nil "A simple mode for editing Actionscript 3 files" single ((:commit . "75639cc7fe85392b5671a1e94dcedb409a949cae") (:authors ("Austin Haas")) (:maintainer "Austin Haas") (:keywords "language" "modes"))])
+ (activity-watch-mode . [(20220111 1121) ((emacs (25)) (request (0)) (json (0)) (cl-lib (0))) "Automatic time tracking extension." single ((:commit . "789ec3425623e43a29755e8daaa02305df8da8ed") (:authors ("Gabor Torok <gabor@20y.hu>, Alan Hamlett" . "alan@wakatime.com")) (:maintainer "Paul d'Hubert" . "paul.dhubert@ya.ru") (:keywords "calendar" "comm") (:url . "https://github.com/pauldub/activity-watch-mode"))])
+ (adafruit-wisdom . [(20200217 306) ((emacs (25 1)) (request (0 3 1))) "Get/display adafruit.com quotes" single ((:commit . "a9314331ba6ea846be9e1f7bded1e2e0ab70cd8e") (:authors ("Neil Okamoto" . "neil.okamoto+melpa@gmail.com")) (:maintainer "Neil Okamoto" . "neil.okamoto+melpa@gmail.com") (:keywords "games") (:url . "https://github.com/gonewest818/adafruit-wisdom.el"))])
+ (add-hooks . [(20171217 123) nil "Functions for setting multiple hooks" single ((:commit . "1845137703461fc44bd77cf24014ba58f19c369d") (:authors ("Nick McCurdy" . "nick@nickmccurdy.com")) (:maintainer "Nick McCurdy" . "nick@nickmccurdy.com") (:keywords "lisp") (:url . "https://github.com/nickmccurdy/add-hooks"))])
+ (add-node-modules-path . [(20220315 340) ((s (1 12 0))) "Add node_modules to your exec-path" single ((:commit . "63f047fd84b825876152743f66de7ee6f9ed203b") (:authors ("Neri Marschik" . "marschik_neri@cyberagent.co.jp")) (:maintainer "Neri Marschik" . "marschik_neri@cyberagent.co.jp") (:keywords "javascript" "node" "node_modules" "eslint") (:url . "https://github.com/codesuki/add-node-modules-path"))])
+ (addressbook-bookmark . [(20190612 1638) ((emacs (24))) "An address book based on Standard Emacs bookmarks." single ((:commit . "d8e502fc2f3d3ab1508ce9e50ebf8a9addc6e5b3") (:authors ("Thierry Volpiatto" . "thierry.volpiatto@gmail.com")) (:maintainer "Thierry Volpiatto" . "thierry.volpiatto@gmail.com") (:url . "https://github.com/thierryvolpiatto/addressbook-bookmark"))])
+ (ado-mode . [(20220415 1647) ((emacs (25 1))) "Major mode for editing Stata-related files" tar ((:commit . "695ea71cf4d6ae5f0afbc37b6fd08458e5c584c4") (:authors ("Bill Rising" . "brising@alum.mit.edu")) (:maintainer "Bill Rising" . "brising@alum.mit.edu") (:keywords "tools" "languages" "files" "convenience" "stata" "mata" "ado") (:url . "https://github.com/louabill/ado-mode"))])
+ (adoc-mode . [(20160314 2130) ((markup-faces (1 0 0))) "a major-mode for editing AsciiDoc files in Emacs" single ((:commit . "745884359a1b8826ede2c4cfd2f0b5478953ac40") (:authors ("Florian Kaufmann" . "sensorflo@gmail.com")) (:maintainer "Florian Kaufmann" . "sensorflo@gmail.com") (:keywords "wp" "asciidoc") (:url . "https://github.com/sensorflo/adoc-mode/wiki"))])
+ (aes . [(20211204 2348) ((emacs (26 1))) "Implementation of AES" single ((:commit . "c9cd12d6c1dbc18603eb4703276132cea59d5c78") (:authors ("Markus Sauermann" . "emacs-aes@sauermann-consulting.de")) (:maintainer "Markus Sauermann" . "emacs-aes@sauermann-consulting.de") (:keywords "data" "tools") (:url . "https://github.com/Sauermann/emacs-aes"))])
+ (affe . [(20220407 2313) ((emacs (27 1)) (consult (0 16))) "Asynchronous Fuzzy Finder for Emacs" tar ((:commit . "a61d593d0cbff65a93111be96b9f53d3e640cf8d") (:authors ("Daniel Mendler")) (:maintainer "Daniel Mendler") (:url . "https://github.com/minad/affe"))])
+ (afternoon-theme . [(20140104 1859) ((emacs (24 1))) "Dark color theme with a deep blue background" single ((:commit . "89b1d778a1f8b385775c122f2bd1c62f0fbf931a") (:authors ("Ozan Sener" . "ozan@ozansener.com")) (:maintainer "Ozan Sener" . "ozan@ozansener.com") (:keywords "themes") (:url . "http://github.com/osener/emacs-afternoon-theme"))])
+ (ag . [(20201031 2202) ((dash (2 8 0)) (s (1 9 0)) (cl-lib (0 5))) "A front-end for ag ('the silver searcher'), the C ack replacement." single ((:commit . "ed7e32064f92f1315cecbfc43f120bbc7508672c") (:authors ("Wilfred Hughes" . "me@wilfred.me.uk")) (:maintainer "Wilfred Hughes" . "me@wilfred.me.uk") (:url . "https://github.com/Wilfred/ag.el"))])
+ (agda-editor-tactics . [(20211024 2357) ((s (1 12 0)) (dash (2 16 0)) (emacs (27 1)) (org (9 1))) "An editor tactic to produce Σ-types from Agda records" single ((:commit . "c401c0c1ec0ad38bb5ee1636504e0e531b9e34b9") (:authors ("Musa Al-hassy" . "alhassy@gmail.com")) (:maintainer "Musa Al-hassy" . "alhassy@gmail.com") (:keywords "abbrev" "convenience" "languages" "agda" "tools") (:url . "https://github.com/alhassy/next-700-module-systems"))])
+ (aggressive-fill-paragraph . [(20180910 816) ((dash (2 10 0))) "A mode to automatically keep paragraphs filled" single ((:commit . "4a620e62b5e645a48b0a818bf4eb19daea4977df") (:authors ("David Shepherd" . "davidshepherd7@gmail.com")) (:maintainer "David Shepherd" . "davidshepherd7@gmail.com") (:keywords "fill-paragraph" "automatic" "comments") (:url . "https://github.com/davidshepherd7/aggressive-fill-paragraph-mode"))])
+ (aggressive-indent . [(20210701 2224) ((emacs (24 3))) "Minor mode to aggressively keep your code always indented" single ((:commit . "cb416faf61c46977c06cf9d99525b04dc109a33c") (:authors ("Artur Malabarba" . "emacs@endlessparentheses.com")) (:maintainer "Artur Malabarba" . "emacs@endlessparentheses.com") (:keywords "indent" "lisp" "maint" "tools") (:url . "https://github.com/Malabarba/aggressive-indent-mode"))])
+ (agtags . [(20200730 116) ((emacs (25))) "A frontend to GNU Global" tar ((:commit . "d80c6f61dee74040c07b7010d48cab1df13a3abf") (:authors ("Vietor Liu" . "vietor.liu@gmail.com")) (:maintainer "Vietor Liu" . "vietor.liu@gmail.com") (:keywords "tools" "convenience") (:url . "https://github.com/vietor/agtags"))])
+ (ah . [(20201213 218) ((emacs (25 1))) "Additional hooks" single ((:commit . "869219e7853510aeb00af3580aede0e5d49b324a") (:authors ("Takaaki ISHIKAWA <takaxp at ieee dot org>")) (:maintainer "Takaaki ISHIKAWA <takaxp at ieee dot org>") (:keywords "convenience") (:url . "https://github.com/takaxp/ah"))])
+ (ahg . [(20210412 847) nil "Alberto's Emacs interface for Mercurial (Hg)" single ((:commit . "77bc2a628df006dcd2dc359ac12acdf8091a1356") (:authors ("Alberto Griggio" . "agriggio@users.sourceforge.net")) (:maintainer "Alberto Griggio" . "agriggio@users.sourceforge.net") (:url . "https://bitbucket.org/agriggio/ahg"))])
+ (ahk-mode . [(20200412 1832) ((emacs (24 3))) "Major mode for editing AHK (AutoHotkey and AutoHotkey_L)" single ((:commit . "729007b5f22a49f5187ff47fca18c0d674e73047") (:authors ("Rich Alesi")) (:maintainer "Rich Alesi") (:keywords "ahk" "autohotkey" "hotkey" "keyboard shortcut" "automation") (:url . "https://github.com/ralesi/ahk-mode"))])
+ (ahungry-theme . [(20180131 328) ((emacs (24))) "Ahungry color theme for Emacs. Make sure to (load-theme 'ahungry)." single ((:commit . "7d18c85c014671573628686012f3952fcd72c97b") (:authors ("Matthew Carter" . "m@ahungry.com")) (:maintainer "Matthew Carter" . "m@ahungry.com") (:keywords "ahungry" "palette" "color" "theme" "emacs" "color-theme" "deftheme") (:url . "https://github.com/ahungry/color-theme-ahungry"))])
+ (aio . [(20200610 1904) ((emacs (26 1))) "async/await for Emacs Lisp" tar ((:commit . "da93523e235529fa97d6f251319d9e1d6fc24a41") (:authors ("Christopher Wellons" . "wellons@nullprogram.com")) (:maintainer "Christopher Wellons" . "wellons@nullprogram.com") (:url . "https://github.com/skeeto/emacs-aio"))])
+ (airline-themes . [(20211214 1749) ((powerline (2 3))) "vim-airline themes for emacs powerline" tar ((:commit . "6bd102e49a7d87af1a72eb86e953991ff7bc954e") (:authors ("Anthony DiGirolamo" . "anthony.digirolamo@gmail.com")) (:maintainer "Anthony DiGirolamo" . "anthony.digirolamo@gmail.com") (:keywords "evil" "mode-line" "powerline" "airline" "themes") (:url . "http://github.com/AnthonyDiGirolamo/airline-themes"))])
+ (airplay . [(20130212 1226) ((request (20130110 2144)) (simple-httpd (1 4 1)) (deferred (0 3 1))) "Airplay bindings to Emacs" tar ((:commit . "bd690aafcae3a887946e1bba8327597932d964ad") (:authors ("Wataru MIYAGUNI" . "gonngo@gmail.com")) (:maintainer "Wataru MIYAGUNI" . "gonngo@gmail.com") (:keywords "appletv" "airplay") (:url . "https://github.com/gongo/airplay-el"))])
+ (alan-mode . [(20220106 727) ((flycheck (32)) (emacs (25 1)) (s (1 12))) "Major mode for editing Alan files" single ((:commit . "e96b06115f53ef81097f585f627855d97b35b89f") (:authors ("Paul van Dam" . "pvandam@kjerner.com")) (:maintainer "Paul van Dam" . "pvandam@kjerner.com") (:keywords "alan" "languages") (:url . "https://github.com/Kjerner/AlanForEmacs"))])
+ (alarm-clock . [(20191204 716) ((emacs (24 4)) (f (0 17 0))) "Alarm Clock" tar ((:commit . "644f331071f8b09a898fae490541908b5054d2e6") (:authors ("Steve Lemuel" . "wlemuel@hotmail.com")) (:maintainer "Steve Lemuel" . "wlemuel@hotmail.com") (:keywords "calendar" "tools" "convenience") (:url . "https://github.com/wlemuel/alarm-clock"))])
+ (alchemist . [(20180312 1304) ((elixir-mode (2 2 5)) (dash (2 11 0)) (emacs (24 4)) (company (0 8 0)) (pkg-info (0 4)) (s (1 11 0))) "Elixir tooling integration into Emacs" tar ((:commit . "6f99367511ae209f8fe2c990779764bbb4ccb6ed") (:authors ("Samuel Tonini" . "tonini.samuel@gmail.com")) (:maintainer "Samuel Tonini" . "tonini.samuel@gmail.com") (:keywords "languages" "elixir" "elixirc" "mix" "hex" "alchemist") (:url . "http://www.github.com/tonini/alchemist.el"))])
+ (alda-mode . [(20210705 654) ((emacs (24 0))) "An Alda major mode" single ((:commit . "4de011d572e958a377fb16daae05a1b411f0c8ad") (:authors ("Jay Kamat" . "jaygkamat@gmail.com")) (:maintainer "Jay Kamat" . "jaygkamat@gmail.com") (:keywords "alda" "highlight") (:url . "http://gitlab.com/jgkamat/alda-mode"))])
+ (alect-themes . [(20211022 1651) ((emacs (24 0))) "Configurable light, dark and black themes for Emacs 24 or later" tar ((:commit . "89560047934c236d05ea6b911c0c63702a8e06f3") (:authors ("Alex Kost" . "alezost@gmail.com")) (:maintainer "Alex Kost" . "alezost@gmail.com") (:keywords "color" "theme") (:url . "https://github.com/alezost/alect-themes"))])
+ (alectryon . [(20211018 321) ((flycheck (31)) (emacs (25 1))) "Toggle between Coq and reStructuredText" tar ((:commit . "c8ab1ec50f7c62fb42a78c0617624b91ba62a162") (:authors ("Clément Pit-Claudel" . "clement.pitclaudel@live.com")) (:maintainer "Clément Pit-Claudel" . "clement.pitclaudel@live.com") (:keywords "convenience" "languages" "tools") (:url . "https://github.com/cpitclaudel/alectryon"))])
+ (alert . [(20200303 2118) ((gntp (0 1)) (log4e (0 3 0)) (cl-lib (0 5))) "Growl-style notification system for Emacs" single ((:commit . "7046393272686c7a1a9b3e7f7b1d825d2e5250a6") (:authors ("John Wiegley" . "jwiegley@gmail.com")) (:maintainer "John Wiegley" . "jwiegley@gmail.com") (:keywords "notification" "emacs" "message") (:url . "https://github.com/jwiegley/alert"))])
+ (alert-termux . [(20181119 951) ((emacs (24 4))) "alert.el notifications on Termux" single ((:commit . "47c414285c2f5971f3be52aaf0a4066ea6989238") (:authors ("Gergely Polonkai" . "gergely@polonkai.eu")) (:maintainer "Gergely Polonkai" . "gergely@polonkai.eu") (:keywords "terminals") (:url . "https://github.com/gergelypolonkai/alert-termux"))])
+ (alert-toast . [(20220312 229) ((emacs (25 1)) (alert (1 2)) (f (0 20 0)) (s (1 12 0))) "Windows 10 toast notifications" single ((:commit . "ba931529a266537783cfec2a28c2b8c058364ff2") (:authors ("Grzegorz Kowzan" . "grzegorz@kowzan.eu")) (:maintainer "Grzegorz Kowzan" . "grzegorz@kowzan.eu") (:url . "https://github.com/gkowzan/alert-toast"))])
+ (align-cljlet . [(20160112 2101) ((clojure-mode (1 11 5))) "Space align various Clojure forms" single ((:commit . "602d72a7ad52788a0265e3c6da519464a98166b8") (:url . "https://github.com/gstamp/align-cljlet"))])
+ (all-ext . [(20200315 1443) ((emacs (24 4)) (all (1 0))) "M-x all with helm-swoop/anything/multiple-cursors/line-number" single ((:commit . "c865c62506af2c9edc7705a7c24dc8b70d5d4de2") (:authors ("rubikitch" . "rubikitch@ruby-lang.org")) (:maintainer "rubikitch" . "rubikitch@ruby-lang.org") (:keywords "matching" "all" "search" "replace" "anything" "helm" "helm-swoop" "occur") (:url . "https://github.com/rubikitch/all-ext"))])
+ (all-the-icons . [(20220427 1911) ((emacs (24 3))) "A library for inserting Developer icons" tar ((:commit . "68365b48f142d75ef4bdc3a274256d97752e3b65") (:authors ("Dominic Charlesworth" . "dgc336@gmail.com")) (:maintainer "Dominic Charlesworth" . "dgc336@gmail.com") (:keywords "convenient" "lisp") (:url . "https://github.com/domtronn/all-the-icons.el"))])
+ (all-the-icons-completion . [(20220409 1204) ((emacs (26 1)) (all-the-icons (5 0))) "Add icons to completion candidates" single ((:commit . "286e2c064a1298be0d8d4100dc91d7a7a554d04a") (:authors ("Itai Y. Efrat <https://github.com/iyefrat>")) (:maintainer "Itai Y. Efrat" . "itai3397@gmail.com") (:keywords "convenient" "lisp") (:url . "https://github.com/iyefrat/all-the-icons-completion"))])
+ (all-the-icons-dired . [(20220304 1638) ((emacs (24 4)) (all-the-icons (2 2 0))) "Shows icons for each file in dired mode" single ((:commit . "147ed0dfd1034a686795a08dc63e2c293128597e") (:authors ("jtbm37")) (:maintainer "Jimmy Yuen Ho Wong" . "wyuenho@gmail.com") (:keywords "files" "icons" "dired") (:url . "https://github.com/wyuenho/all-the-icons-dired"))])
+ (all-the-icons-gnus . [(20180511 654) ((emacs (24 4)) (dash (2 12 0)) (all-the-icons (3 1 0))) "Shows icons for in Gnus" single ((:commit . "27f78996da0725943bcfb2d18038e6f7bddfa9c7") (:authors ("Nicolas Lamirault" . "nicolas.lamirault@gmail.com")) (:maintainer "Nicolas Lamirault" . "nicolas.lamirault@gmail.com") (:keywords "mail" "tools"))])
+ (all-the-icons-ibuffer . [(20220424 1027) ((emacs (24 4)) (all-the-icons (2 2 0))) "Display icons for all buffers in ibuffer" single ((:commit . "0fcb43eb440e18078c8faf67c27a2189bbb45dfb") (:authors ("Vincent Zhang" . "seagle0128@gmail.com")) (:maintainer "Vincent Zhang" . "seagle0128@gmail.com") (:keywords "convenience" "icons" "ibuffer") (:url . "https://github.com/seagle0128/all-the-icons-ibuffer"))])
+ (all-the-icons-ivy . [(20190508 1803) ((emacs (24 4)) (all-the-icons (2 4 0)) (ivy (0 8 0))) "Shows icons while using ivy and counsel" single ((:commit . "a70cbfa1effe36efc946a823a580cec686d5e88d") (:authors ("asok")) (:maintainer "asok") (:keywords "faces"))])
+ (all-the-icons-ivy-rich . [(20220505 834) ((emacs (25 1)) (ivy-rich (0 1 0)) (all-the-icons (2 2 0))) "Better experience with icons for ivy" single ((:commit . "7c9db258ba7dd0a8c90eb7cebd335961cc45e031") (:authors ("Vincent Zhang" . "seagle0128@gmail.com")) (:maintainer "Vincent Zhang" . "seagle0128@gmail.com") (:keywords "convenience" "icons" "ivy") (:url . "https://github.com/seagle0128/all-the-icons-ivy-rich"))])
+ (almost-mono-themes . [(20220422 1714) ((emacs (24))) "Almost monochromatic color themes" tar ((:commit . "0641bf565c113caef8d5c2a93f38cff32ebb62b7") (:authors ("John Olsson" . "john@cryon.se")) (:maintainer "John Olsson" . "john@cryon.se") (:keywords "faces") (:url . "https://github.com/cryon/almost-mono-themes"))])
+ (alsamixer . [(20191002 1133) nil "Functions to call out to amixer." single ((:commit . "1bdb99e433acd38685f05408562746cfbf2bc820") (:authors ("R.W. van 't Veer")) (:maintainer "R.W. van 't Veer") (:keywords "convenience") (:url . "https://github.com/remvee/alsamixer-el"))])
+ (alt-codes . [(20220212 1526) ((emacs (26 1))) "Insert alt codes using meta key" single ((:commit . "45deed4b9aadcd5e2a5482b0fe5110bb78ba1dd6") (:authors ("Shen, Jen-Chieh" . "jcs090218@gmail.com")) (:maintainer "Shen, Jen-Chieh" . "jcs090218@gmail.com") (:url . "https://github.com/jcs-elpa/alt-codes"))])
+ (amd-mode . [(20180111 1402) ((emacs (25)) (projectile (20161008 47)) (s (1 9 0)) (f (0 16 2)) (seq (2 16)) (makey (0 3)) (js2-mode (20140114)) (js2-refactor (0 6 1))) "Minor mode for handling JavaScript AMD module requirements." single ((:commit . "01fd19e0d635ccaf8e812364d8720733f2e84126") (:authors ("Nicolas Petton" . "petton.nicolas@gmail.com")) (:maintainer "Nicolas Petton" . "petton.nicolas@gmail.com") (:keywords "javascript" "amd" "projectile"))])
+ (ameba . [(20200103 1454) ((emacs (24 4))) "An interface to Crystal Ameba linter" single ((:commit . "0c4925ae0e998818326adcb47ed27ddf9761c7dc") (:authors ("Vitalii Elenhaupt")) (:maintainer "Vitalii Elenhaupt") (:keywords "convenience") (:url . "https://github.com/crystal-ameba/ameba.el"))])
+ (ample-regexps . [(20200508 1021) nil "ample regular expressions for Emacs" tar ((:commit . "153969ce547afe410b8986f01c9ed4087c9cd20b") (:authors ("immerrr" . "immerrr@gmail.com")) (:maintainer "immerrr" . "immerrr@gmail.com") (:keywords "regexps" "extensions" "tools"))])
+ (ample-theme . [(20180207 1745) nil "Calm Dark Theme for Emacs" tar ((:commit . "f5a163626e04abda2d3c168f703c3f330f302a7c") (:authors ("Jordon Biondo" . "jordonbiondo@gmail.com")) (:maintainer "Jordon Biondo" . "jordonbiondo@gmail.com") (:keywords "theme" "dark") (:url . "https://github.com/jordonbiondo/ample-theme"))])
+ (ample-zen-theme . [(20150119 2154) nil "AmpleZen Theme for Emacs 24" single ((:commit . "b277bb7abd4b6624e8d59f02474b79af50a007bd") (:authors ("Michael Wall")) (:maintainer "Michael Wall") (:keywords "theme" "dark" "emacs 24") (:url . "https://github.com/mjwall/ample-zen"))])
+ (amread-mode . [(20220210 1354) ((emacs (24 3)) (cl-lib (0 6 1))) "A minor mode helper user speed-reading" single ((:commit . "a3358645582148e81bff54e18877451b747173bb") (:keywords "wp") (:url . "https://repo.or.cz/amread-mode.git"))])
+ (amsreftex . [(20220115 1838) ((emacs (25 1))) "Add amsrefs bibliography support for reftex" single ((:commit . "facf47b82572e3f62bd8d9b8d4f4d5258f6c8a38") (:authors ("Fran Burstall" . "fran.burstall@gmail.com")) (:maintainer "Fran Burstall" . "fran.burstall@gmail.com") (:keywords "tex") (:url . "https://github.com/franburstall/amsreftex"))])
+ (amx . [(20210305 118) ((emacs (24 4)) (s (0))) "Alternative M-x with extra features." single ((:commit . "37f9c7ae55eb0331b27200fb745206fc58ceffc0") (:authors ("Ryan C. Thompson" . "rct@thompsonclan.org") ("Cornelius Mika" . "cornelius.mika@gmail.com")) (:maintainer "Ryan C. Thompson" . "rct@thompsonclan.org") (:keywords "convenience" "usability" "completion") (:url . "http://github.com/DarwinAwardWinner/amx/"))])
+ (anaconda-mode . [(20211122 817) ((emacs (25 1)) (pythonic (0 1 0)) (dash (2 6 0)) (s (1 9)) (f (0 16 2))) "Code navigation, documentation lookup and completion for Python" tar ((:commit . "cbea0fb3182321d34ff93981c5a59f8dd72d82a5") (:authors ("Artem Malyshev" . "proofit404@gmail.com")) (:maintainer "Artem Malyshev" . "proofit404@gmail.com") (:url . "https://github.com/proofit404/anaconda-mode"))])
+ (anakondo . [(20210221 1727) ((emacs (26 3))) "Adds clj-kondo based Clojure[Script] editing facilities" single ((:commit . "16b0ba14d94a5d7e55655efc9e1d6d069a9306f2") (:authors ("Didier A." . "didibus@users.noreply.github.com")) (:maintainer "Didier A." . "didibus@users.noreply.github.com") (:keywords "clojure" "clojurescript" "cljc" "clj-kondo" "completion" "languages" "tools") (:url . "https://github.com/didibus/anakondo"))])
+ (anaphora . [(20180618 2200) nil "anaphoric macros providing implicit temp variables" single ((:commit . "3b2da3f759b244975852e79721c4a2dbad3905cf") (:authors ("Roland Walker" . "walker@pobox.com")) (:maintainer "Roland Walker" . "walker@pobox.com") (:keywords "extensions") (:url . "http://github.com/rolandwalker/anaphora"))])
+ (ancient-one-dark-theme . [(20211030 1358) ((emacs (24 1))) "A color theme based off uetchy's Ancient One Dark Theme" single ((:commit . "db79f86842c10874ce18c1a1e4496e9d0e28bed9") (:authors ("Daniils Petrovs")) (:maintainer "Daniils Petrovs") (:url . "https://github.com/DaniruKun/ancient-one-dark-emacs-theme"))])
+ (android-env . [(20200722 1403) ((emacs (24 3))) "Helper functions for working in android" single ((:commit . "5c6a6d9449f300eec4f374a5410edc1cbab02e40") (:authors ("Fernando Jascovich")) (:maintainer "Fernando Jascovich") (:keywords "android" "gradle" "java" "tools" "convenience") (:url . "https://github.com/fernando-jascovich/android-env.el"))])
+ (android-mode . [(20190903 811) nil "Minor mode for Android application development" single ((:commit . "d5332e339a1f5e30559a53feffb8442ca79265d6") (:authors ("R.W. van 't Veer")) (:maintainer "R.W. van 't Veer") (:keywords "tools" "processes") (:url . "https://github.com/remvee/android-mode"))])
+ (angry-police-captain . [(20120829 1252) nil "Show quote from http://theangrypolicecaptain.com in the minibuffer" single ((:commit . "d11931c5cb63368dcc4a48797962428cca6d3e9d") (:authors ("Rolando Pereira" . "rolando_pereira@sapo.pt")) (:maintainer "Rolando Pereira" . "rolando_pereira@sapo.pt") (:keywords "games" "web" "fun"))])
+ (angular-mode . [(20151201 2127) nil "Major mode for Angular.js" tar ((:commit . "8720cde86af0f1859ccc8580571e8d0ad1c52cff") (:authors ("Rudolf Olah" . "omouse@gmail.com")) (:maintainer "Rudolf Olah" . "omouse@gmail.com") (:keywords "languages" "javascript") (:url . "https://github.com/omouse/angularjs-mode"))])
+ (angular-snippets . [(20140514 523) ((s (1 4 0)) (dash (1 2 0))) "Yasnippets for AngularJS" tar ((:commit . "af5ae0a4a8603b040446c28afcf6ca01a8b4bd7b") (:authors ("Magnar Sveen" . "magnars@gmail.com")) (:maintainer "Magnar Sveen" . "magnars@gmail.com") (:keywords "snippets"))])
+ (anki-connect . [(20191123 1858) ((emacs (24 3))) "AnkiConnect API" single ((:commit . "1324f0c248aa2c6e73d6cf93fad6119d699f7dae") (:authors ("DarkSun" . "lujun9972@gmail.com")) (:maintainer "DarkSun" . "lujun9972@gmail.com") (:keywords "lisp" "anki") (:url . "https://github.com/lujun9972/anki-connect.el"))])
+ (anki-editor . [(20190922 1223) ((emacs (25)) (request (0 3 0)) (dash (2 12 0))) "Minor mode for making Anki cards with Org" tar ((:commit . "546774a453ef4617b1bcb0d1626e415c67cc88df") (:authors ("Lei Tan")) (:maintainer "Lei Tan") (:url . "https://github.com/louietan/anki-editor"))])
+ (anki-mode . [(20201223 719) ((emacs (24 4)) (dash (2 12 0)) (markdown-mode (2 2)) (s (1 11 0)) (request (0 3 0))) "A major mode for creating anki cards" single ((:commit . "d9b84028cd6a1ae040fb5604080a8b5fa8138562") (:authors ("David Shepherd" . "davidshepherd7@gmail.com")) (:maintainer "David Shepherd" . "davidshepherd7@gmail.com") (:keywords "tools") (:url . "https://github.com/davidshepherd7/anki-mode"))])
+ (anki-vocabulary . [(20200103 325) ((emacs (24 4)) (s (1 0)) (youdao-dictionary (0 4)) (anki-connect (1 0)) (s (1 10))) "Help you to create vocabulary cards in Anki" single ((:commit . "863fe0219577f996ab126f1b7902db3c2cc59b2b") (:authors ("DarkSun" . "lujun9972@gmail.com")) (:maintainer "DarkSun" . "lujun9972@gmail.com") (:keywords "lisp" "anki" "translator" "chinese") (:url . "https://github.com/lujun9972/anki-vocabulary.el"))])
+ (annalist . [(20190929 207) ((emacs (24 4)) (cl-lib (0 5))) "Record and display information such as keybindings" tar ((:commit . "134fa3f0fb91a636a1c005c483516d4b64905a6d") (:authors ("Fox Kiester" . "noct@posteo.net")) (:maintainer "Fox Kiester" . "noct@posteo.net") (:keywords "convenience" "tools" "keybindings" "org") (:url . "https://github.com/noctuid/annalist.el"))])
+ (annotate . [(20220428 1339) nil "annotate files without changing them" single ((:commit . "e982a7b74a681a8c2c823d8dcaafd185ab5f719e") (:authors ("Bastian Bechtold")) (:maintainer "Bastian Bechtold <bastibe.dev@mailbox.org>, cage" . "cage-dev@twistfold.it") (:url . "https://github.com/bastibe/annotate.el"))])
+ (annotate-depth . [(20160520 2040) nil "Annotate buffer if indentation depth is beyond threshold." single ((:commit . "fcb24fa36287250e40d195590c4ca4a8a696277b") (:authors ("Morten Slot Kristensen <msk AT nullpointer DOT dk>")) (:maintainer "Morten Slot Kristensen <msk AT nullpointer DOT dk>") (:keywords "convenience") (:url . "https://github.com/netromdk/annotate-depth"))])
+ (annotation . [(20200914 644) nil "Functions for annotating text with faces and help bubbles" single ((:commit . "7d53667ebfb306732ee9461b150f09ffba6af474") (:url . "https://github.com/agda/agda"))])
+ (annoying-arrows-mode . [(20161024 646) ((cl-lib (0 5))) "Ring the bell if using arrows too much" single ((:commit . "3c42e9807d7696da2da2a21b63beebf9cdb3f5dc") (:authors ("Magnar Sveen" . "magnars@gmail.com")) (:maintainer "Magnar Sveen" . "magnars@gmail.com"))])
+ (ansi . [(20211104 1420) ((emacs (24 1)) (cl-lib (0 6))) "Turn string into ansi strings" single ((:commit . "2367fba7b3b2340364a30cd6de7f3eb6bb9898a3") (:authors ("Johan Andersson" . "johan.rejeep@gmail.com")) (:maintainer "Johan Andersson" . "johan.rejeep@gmail.com") (:keywords "terminals" "color" "ansi") (:url . "http://github.com/rejeep/ansi"))])
+ (ansible . [(20220114 45) ((s (1 9 0)) (f (0 16 2))) "Ansible minor mode" tar ((:commit . "d89ac0ee57742cca0f0e0a3453d9dcc521575690") (:authors ("k1LoW (Kenichirou Oyama), <k1lowxb [at] gmail [dot] com> <k1low [at] 101000lab [dot] org>")) (:maintainer "k1LoW (Kenichirou Oyama), <k1lowxb [at] gmail [dot] com> <k1low [at] 101000lab [dot] org>") (:url . "https://github.com/k1LoW/emacs-ansible"))])
+ (ansible-doc . [(20160924 824) ((emacs (24 3))) "Ansible documentation Minor Mode" single ((:commit . "86083a7bb2ed0468ca64e52076b06441a2f8e9e0") (:authors ("Sebastian Wiesner" . "swiesner@lunaryorn")) (:maintainer "Sebastian Wiesner" . "swiesner@lunaryorn") (:keywords "tools" "help") (:url . "https://github.com/lunaryorn/ansible-doc.el"))])
+ (ansible-vault . [(20211119 1500) ((emacs (24 3))) "Minor mode for editing ansible vault files" single ((:commit . "8da2ad658dbe94c71aad1c75d6fd22888338030c") (:maintainer "Zachary Elliott" . "contact@zell.io") (:keywords "ansible" "ansible-vault" "tools") (:url . "http://github.com/zellio/ansible-vault-mode"))])
+ (ant . [(20160211 1543) nil "helpers for compiling with ant" single ((:commit . "510b5a3f57ee4b2855422d88d359a28922c1ab70") (:keywords "compilation" "ant" "java"))])
+ (anti-zenburn-theme . [(20180712 1838) nil "Low-contrast Zenburn-inverted theme" single ((:commit . "dbafbaa86be67c1d409873f57a5c0bbe1e7ca158") (:authors ("Andrey Kotlarski" . "m00naticus@gmail.com")) (:maintainer "Andrey Kotlarski" . "m00naticus@gmail.com") (:url . "https://github.com/m00natic/anti-zenburn-theme"))])
+ (anx-api . [(20140208 1514) nil "Interact with the AppNexus API from Emacs." single ((:commit . "b2411ebc966ac32c3ffc61bc22bf183834df0fa0") (:authors ("Rich Loveland")) (:maintainer "Rich Loveland") (:keywords "convenience" "json" "rest" "api" "appnexus"))])
+ (anybar . [(20160816 1421) nil "Control AnyBar from Emacs" single ((:commit . "7a0743e0d31bcb36ab1bb2e351f3e7139c422ac5") (:authors ("Christopher Shea" . "cmshea@gmail.com")) (:maintainer "Christopher Shea" . "cmshea@gmail.com") (:keywords "anybar"))])
+ (anyins . [(20131229 1041) nil "Insert content at multiple places from shell command or kill-ring" single ((:commit . "83844c17ac9b5b6c7655ee556b75689e4c8ea663") (:authors ("Anthony HAMON" . "hamon.anth@gmail.com")) (:maintainer "Anthony HAMON" . "hamon.anth@gmail.com") (:keywords "insert" "rectangular") (:url . "http://github.com/antham/anyins"))])
+ (anzu . [(20211002 2255) ((emacs (25 1))) "Show number of matches in mode-line while searching" single ((:commit . "5abb37455ea44fa401d5f4c1bdc58adb2448db67") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Neil Okamoto" . "neil.okamoto+melpa@gmail.com") (:url . "https://github.com/emacsorphanage/anzu"))])
+ (aozora-view . [(20140310 1317) nil "Aozora Bunko text Emacs viewer." tar ((:commit . "b0390616d19e45f15f9a2f5d5688274831e721fd") (:authors ("KAWABATA, Taichi <kawabata.taichi_at_gmail.com>")) (:maintainer "KAWABATA, Taichi <kawabata.taichi_at_gmail.com>") (:keywords "text") (:url . "https://github.com/kawabata/aozora-view"))])
+ (apache-mode . [(20210519 1931) nil "Major mode for editing Apache httpd configuration files" single ((:commit . "f2c11aac2f5fc598123e04f4604bea248689a117") (:authors ("Karl Chen" . "quarl@nospam.quarl.org")) (:maintainer "USAMI Kenta" . "tadsan@zonu.me") (:keywords "languages" "faces") (:url . "https://github.com/emacs-php/apache-mode"))])
+ (apdl-mode . [(20211023 1831) ((emacs (25 1))) "Major mode for the APDL programming language." tar ((:commit . "c55c6468526100ba0da00bff05cfb17cdf8839cf") (:authors ("H. Dieter Wilhelm" . "dieter@duenenhof-wilhelm.de")) (:maintainer "H. Dieter Wilhelm") (:keywords "languages" "convenience" "tools" "ansys" "apdl") (:url . "https://github.com/dieter-wilhelm/apdl-mode"))])
+ (apel . [(20220427 1121) ((emacs (24 5))) "A Portable Emacs Library provides support for portable Emacs Lisp programs" tar ((:commit . "6947dc4605ebbb87762edf7051a78a3f7b5f17c5"))])
+ (apheleia . [(20220501 2151) ((emacs (26))) "Reformat buffer stably" single ((:commit . "50da8cd1a94fbcd6456b2528a9db20a5cfc8ff5f") (:authors ("Radon Rosborough" . "radon.neon@gmail.com")) (:maintainer "Radon Rosborough" . "radon.neon@gmail.com") (:keywords "tools") (:url . "https://github.com/raxod502/apheleia"))])
+ (apib-mode . [(20200101 1017) ((markdown-mode (2 1))) "Major mode for API Blueprint files" single ((:commit . "c6dd05201f6eb9295736d8668a79a7510d11159e") (:authors ("Vilibald Wanča" . "vilibald@wvi.cz")) (:maintainer "Vilibald Wanča" . "vilibald@wvi.cz") (:keywords "tools" "api-blueprint") (:url . "http://github.com/w-vi/apib-mode"))])
+ (apiwrap . [(20180602 2231) ((emacs (25))) "api-wrapping macros" single ((:commit . "a4fb21d96027369307b22439a4a6c765ee272f44") (:authors ("Sean Allred" . "code@seanallred.com")) (:maintainer "Sean Allred" . "code@seanallred.com") (:keywords "tools" "maint" "convenience") (:url . "https://github.com/vermiculus/apiwrap.el"))])
+ (apparmor-mode . [(20220411 648) ((emacs (24 4))) "Major mode for editing AppArmor policy files" single ((:commit . "abc2a6adf563b89daee9f8fa07a71d78957defdb") (:authors ("Alex Murray" . "murray.alex@gmail.com")) (:maintainer "Alex Murray" . "murray.alex@gmail.com") (:url . "https://github.com/alexmurray/apparmor-mode"))])
+ (apples-mode . [(20110121 418) nil "Major mode for editing and executing AppleScript code" tar ((:commit . "83a9ab0d6ba82496e2f7df386909b1a55701fccb") (:authors ("tequilasunset" . "tequilasunset.mac@gmail.com")) (:maintainer "tequilasunset" . "tequilasunset.mac@gmail.com") (:keywords "applescript" "languages"))])
+ (applescript-mode . [(20210802 1715) ((emacs (24 3))) "major mode for editing AppleScript source" single ((:commit . "ea9a32aa33580b0695e7298d56c3d5f050a02b87") (:authors ("sakito" . "sakito@users.sourceforge.jp")) (:maintainer "sakito" . "sakito@users.sourceforge.jp") (:keywords "languages" "tools") (:url . "https://github.com/emacsorphanage/applescript-mode"))])
+ (aproject . [(20220410 541) nil "Basic project framework for Emacs" tar ((:commit . "13e176ee69851403bec6471c5cceed17b7912b6f") (:authors ("Vietor Liu" . "vietor.liu@gmail.com")) (:maintainer "Vietor Liu" . "vietor.liu@gmail.com") (:keywords "environment" "project") (:url . "https://github.com/vietor/aproject"))])
+ (apropospriate-theme . [(20220418 1554) nil "A colorful, low-contrast, light & dark theme set for Emacs with a fun name." tar ((:commit . "52ed4bf4aaa01c527271d71e6ce00f3607839777"))])
+ (apt-sources-list . [(20180527 1241) ((emacs (24 4))) "Mode for editing APT source.list files" single ((:commit . "5289443ceff230dfc8a2c1c6b524c90560eb08a5") (:authors ("Dr. Rafael Sepúlveda" . "drs@gnulinux.org.mx")) (:maintainer "Joe Wreschnig" . "joe.wreschnig@gmail.com") (:url . "https://git.korewanetadesu.com/apt-sources-list.git"))])
+ (aqi . [(20200215 1334) ((emacs (25 1)) (request (0 3)) (let-alist (0 0))) "Air quality data from the World Air Quality Index" single ((:commit . "c107a2e21cd1ac6008d8baaeeedb3fab26583d45") (:authors ("nik gaffney" . "nik@fo.am")) (:maintainer "nik gaffney" . "nik@fo.am") (:keywords "air quality" "aqi" "pollution" "weather" "data") (:url . "https://github.com/zzkt/aqi"))])
+ (arc-dark-theme . [(20190314 1632) ((emacs (24))) "Arc dark theme" single ((:commit . "ee17dcca35dd0304145efc468b3f25af6907a59d") (:authors ("Christopher Fraser" . "cfraz89@gmail.com")) (:maintainer "Christopher Fraser" . "cfraz89@gmail.com") (:keywords "faces" "theme") (:url . "https://github.com/cfraz89/arc-dark-theme"))])
+ (arch-packer . [(20170730 1321) ((emacs (25 1)) (s (1 11 0)) (async (1 9 2)) (dash (2 12 0))) "Arch Linux package management frontend" single ((:commit . "940e96f7d357c6570b675a0f942181c787f1bfd7") (:authors ("Fritz Stelzer" . "brotzeitmacher@gmail.com")) (:maintainer "Fritz Stelzer" . "brotzeitmacher@gmail.com") (:url . "https://github.com/brotzeitmacher/arch-packer"))])
+ (archive-region . [(20200316 1425) ((emacs (24 4))) "Move region to archive file instead of killing" single ((:commit . "53cd2d96ea7c33f320353982b36854f25c900c2e") (:authors ("rubikitch" . "rubikitch@ruby-lang.org")) (:maintainer "rubikitch" . "rubikitch@ruby-lang.org") (:keywords "languages") (:url . "http://www.emacswiki.org/cgi-bin/wiki/download/archive-region.el"))])
+ (archive-rpm . [(20220314 1647) ((emacs (24 4))) "RPM and CPIO support for archive-mode" tar ((:commit . "515d2230352fffcc982ae2e322d95cbee6aca760") (:authors ("Magnus Henoch" . "magnus.henoch@gmail.com")) (:maintainer "Magnus Henoch" . "magnus.henoch@gmail.com") (:keywords "files"))])
+ (arduino-cli-mode . [(20210511 653) ((emacs (25 1))) "Arduino-CLI command wrapper" single ((:commit . "a93de7e8fef202163df4657f2ab522b57f70f202") (:authors ("Love Lagerkvist")) (:maintainer "Love Lagerkvist") (:keywords "processes" "tools") (:url . "https://github.com/motform/arduino-cli-mode"))])
+ (arduino-mode . [(20220210 1355) ((emacs (25 1)) (spinner (1 7 3))) "Major mode for editing Arduino code" tar ((:commit . "652c6a328fa8f2db06534d5f231c6b6933be3edc") (:maintainer "stardiviner" . "numbchild@gmail.com") (:keywords "languages" "arduino") (:url . "https://repo.or.cz/arduino-mode.git"))])
+ (aria2 . [(20190816 25) ((emacs (24 4))) "Control aria2c commandline tool from Emacs" single ((:commit . "32e08d5a8ad2f305578e0f783e087c1d312238c7") (:authors ("Łukasz Gruner" . "lukasz@gruner.lu")) (:maintainer "Łukasz Gruner" . "lukasz@gruner.lu") (:keywords "download" "bittorrent" "aria2") (:url . "https://bitbucket.org/ukaszg/aria2-mode"))])
+ (ariadne . [(20131117 1711) ((bert (0 1))) "Ariadne plugin for Emacs" single ((:commit . "6fe401c7f996bcbc2f685e7971324c6f5e5eaf15") (:authors ("Oleksandr Manzyuk" . "manzyuk@gmail.com")) (:maintainer "Oleksandr Manzyuk" . "manzyuk@gmail.com") (:keywords "comm" "convenience" "processes"))])
+ (arjen-grey-theme . [(20170522 2047) nil "A soothing dark grey theme" single ((:commit . "4cd0be72b65d42390e2105cfdaa408a1ead8d8d1") (:authors ("Arjen Wiersma" . "arjen@wiersma.org")) (:maintainer "Arjen Wiersma" . "arjen@wiersma.org") (:keywords "faces") (:url . "https://github.com/credmp/arjen-grey"))])
+ (artbollocks-mode . [(20170524 422) nil "Improve your writing (especially about art)" single ((:commit . "33a41ca4f8206f57e5498a526d3b0ea18d08bb93") (:authors ("Rob Myers <rob@robmyers.org>, Sacha Chua" . "sacha@sachachua.com")) (:maintainer "Rob Myers <rob@robmyers.org>, Sacha Chua" . "sacha@sachachua.com") (:url . "https://github.com/sachac/artbollocks-mode"))])
+ (arview . [(20160419 2109) nil "extract and view archives in the temporary directory" single ((:commit . "5437b4221b64b238c273a651d4792c577dba6d45") (:authors ("Andrey Fainer" . "fandrey@gmx.com")) (:maintainer "Andrey Fainer" . "fandrey@gmx.com") (:keywords "files") (:url . "https://github.com/afainer/arview"))])
+ (arxiv-mode . [(20220128 920) ((emacs (27 1)) (hydra (0))) "Read and search for articles on arXiv.org" tar ((:commit . "f550583d2da8bd9600bd26bb4028fe22a9744da2") (:authors ("Alex Chen (fizban007)" . "fizban007@gmail.com") ("Simon Lin (Simon-Lin)" . "n.sibetz@gmail.com")) (:maintainer "Alex Chen (fizban007)" . "fizban007@gmail.com") (:keywords "bib" "convenience" "hypermedia") (:url . "https://github.com/fizban007/arxiv-mode"))])
+ (ascii-table . [(20201019 700) ((emacs (24 3)) (cl-lib (0 5))) "Interactive ASCII table" single ((:commit . "4f68ad0b36c365c0652756691ab1703d0d46b4b4") (:authors ("Lassi Kortela" . "lassi@lassi.io")) (:maintainer "Lassi Kortela" . "lassi@lassi.io") (:keywords "help" "tools") (:url . "https://github.com/lassik/emacs-ascii-table"))])
+ (asilea . [(20150105 1525) ((emacs (24)) (cl-lib (0 5))) "Find best compiler options using simulated annealing" single ((:commit . "2aab1cc63b64ef08d12e84fd7ba5c94065f6039f") (:authors ("Fanael Linithien" . "fanael4@gmail.com")) (:maintainer "Fanael Linithien" . "fanael4@gmail.com") (:url . "https://github.com/Fanael/asilea"))])
+ (asm-blox . [(20220124 1430) ((emacs (26 1)) (yaml (0 3 4))) "Programming game involving WAT and YAML" tar ((:commit . "47aa63d320c39f8566a8d95c61f27383f561b001") (:authors ("Zachary Romero")) (:maintainer "Zachary Romero") (:keywords "games") (:url . "https://github.com/zkry/asm-blox"))])
+ (asn1-mode . [(20170729 226) ((emacs (24 3)) (s (1 10 0))) "ASN.1/GDMO mode for GNU Emacs" single ((:commit . "d5d4a8259daf708411699bcea85d322f18beb972") (:authors ("Taichi Kawabata <kawabata.taichi_at_gmail.com>")) (:maintainer "Taichi Kawabata <kawabata.taichi_at_gmail.com>") (:keywords "languages" "processes" "tools") (:url . "https://github.com/kawabata/asn1-mode/"))])
+ (assess . [(20200211 1817) ((emacs (24 4)) (m-buffer (0 15))) "Test support functions" tar ((:commit . "5bac045b273623772b6a2d820997d50f7ab4e466") (:authors ("Phillip Lord" . "phillip.lord@russet.org.uk")) (:maintainer "Phillip Lord" . "phillip.lord@russet.org.uk"))])
+ (astyle . [(20200328 616) ((emacs (24 4)) (reformatter (0 3))) "Astyle formatter functions" single ((:commit . "04ff2941f08c4b731fe6a18ee1697436d1ca1cc0") (:authors ("Petter Storvik")) (:maintainer "Petter Storvik") (:keywords "astyle" "c" "c++" "cpp" "reformatter") (:url . "https://github.com/storvik/emacs-astyle"))])
+ (asx . [(20191024 1100) ((emacs (26 1))) "Ask StackExchange/StackOverflow" single ((:commit . "ec4bf74de602b97df1f306d51acf4cda45184aac") (:authors ("Alex Ragone" . "ragonedk@gmail.com")) (:maintainer "Alex Ragone" . "ragonedk@gmail.com") (:keywords "convenience") (:url . "https://github.com/ragone/asx"))])
+ (async . [(20220318 1342) ((emacs (24 4))) "Asynchronous processing in Emacs" tar ((:commit . "c78bab7506a70a735d2c3deab13fa87bf44a83d3") (:authors ("John Wiegley" . "jwiegley@gmail.com")) (:maintainer "Thierry Volpiatto" . "thievol@posteo.net") (:keywords "async") (:url . "https://github.com/jwiegley/emacs-async"))])
+ (async-await . [(20200117 828) ((emacs (25 1)) (promise (1 1)) (iter2 (0 9 10))) "Async/Await" single ((:commit . "deef2bb343463f5196545f1dd8c2a32d0cb3b146") (:authors ("chuntaro" . "chuntaro@sakura-games.jp")) (:maintainer "chuntaro" . "chuntaro@sakura-games.jp") (:keywords "async" "await" "convenience") (:url . "https://github.com/chuntaro/emacs-async-await"))])
+ (async-backup . [(20220131 1438) ((emacs (24 4))) "Backup on each save without freezing Emacs" single ((:commit . "6ddb39fe77d66cdef48b87cb0d0554ad7d132308") (:authors ("contrapunctus" . "xmpp:contrapunctus@jabjab.de")) (:maintainer "contrapunctus" . "xmpp:contrapunctus@jabjab.de") (:keywords "files") (:url . "https://tildegit.org/contrapunctus/async-backup"))])
+ (atcoder-tools . [(20200109 1236) ((emacs (26)) (f (0 20)) (s (1 12))) "An atcoder-tools client" single ((:commit . "cfe61ed18ea9b3b1bfb6f9e7d80a47599680cd1f") (:authors ("Seong Yong-ju" . "sei40kr@gmail.com")) (:maintainer "Seong Yong-ju" . "sei40kr@gmail.com") (:keywords "extensions" "tools") (:url . "https://github.com/sei40kr/atcoder-tools"))])
+ (atl-long-lines . [(20201026 339) ((emacs (24 3))) "Turn off truncate-lines when the line is long" single ((:commit . "43ca538ecece4e14bb9bcd887854aeb14b3d45f4") (:authors ("Shen, Jen-Chieh" . "jcs090218@gmail.com")) (:maintainer "Shen, Jen-Chieh" . "jcs090218@gmail.com") (:url . "https://github.com/jcs-elpa/atl-long-lines"))])
+ (atl-markup . [(20210731 609) ((emacs (24 3))) "Automatically truncate lines for markup languages" single ((:commit . "e0d11744d9b2bca780322b1b282fb5ffb18cfd75") (:authors ("Shen, Jen-Chieh" . "jcs090218@gmail.com")) (:maintainer "Shen, Jen-Chieh" . "jcs090218@gmail.com") (:url . "https://github.com/jcs-elpa/atl-markup"))])
+ (atom-dark-theme . [(20220114 1902) nil "An Emacs port of the Atom Dark theme from Atom.io." single ((:commit . "2b3c7ad42bbcab3214a131f8957b92e717b36ad3") (:authors ("Jeremy Whitlock" . "jwhitlock@apache.org")) (:maintainer "Jeremy Whitlock" . "jwhitlock@apache.org") (:keywords "themes" "atom" "dark") (:url . "https://github.com/whitlockjc/atom-dark-theme-emacs"))])
+ (atom-one-dark-theme . [(20210128 1640) nil "Atom One Dark color theme" single ((:commit . "b34b62e85593812b55ee552a1cb0eecfb04767bb") (:authors ("Jonathan Chu" . "me@jonathanchu.is")) (:maintainer "Jonathan Chu" . "me@jonathanchu.is") (:url . "https://github.com/jonathanchu/atom-one-dark-theme"))])
+ (atomic-chrome . [(20210221 59) ((emacs (24 4)) (let-alist (1 0 4)) (websocket (1 4))) "Edit Chrome text area with Emacs using Atomic Chrome" single ((:commit . "c73367d8aa660f2b3c3f70ef5c39f5b502d60404") (:authors ("alpha22jp" . "alpha22jp@gmail.com")) (:maintainer "alpha22jp" . "alpha22jp@gmail.com") (:keywords "chrome" "edit" "textarea") (:url . "https://github.com/alpha22jp/atomic-chrome"))])
+ (attrap . [(20220124 1253) ((dash (2 12 0)) (emacs (25 1)) (f (0 19 0)) (flycheck (0 30)) (s (1 11 0))) "ATtempt To Repair At Point" single ((:commit . "19a520ecb99529790906a1fb5599acdf2b4f005f") (:authors ("Jean-Philippe Bernardy" . "jeanphilippe.bernardy@gmail.com")) (:maintainer "Jean-Philippe Bernardy" . "jeanphilippe.bernardy@gmail.com") (:keywords "programming" "tools") (:url . "https://github.com/jyp/attrap"))])
+ (auctex-cluttex . [(20210226 302) ((emacs (24 4)) (auctex (12 2))) "ClutTeX support for AUCTeX" single ((:commit . "9a15742a6de1285831329eac93f9e35752472685") (:authors ("Masahiro Nakamura" . "tsuucat@icloud.com")) (:maintainer "Masahiro Nakamura" . "tsuucat@icloud.com") (:keywords "tex") (:url . "https://github.com/tsuu32/auctex-cluttex"))])
+ (auctex-latexmk . [(20170618 1636) ((auctex (11 87))) "Add LatexMk support to AUCTeX" single ((:commit . "4d353522650d7685acbf1d38f7dbc504f734bd84") (:authors ("Tomoya Tanjo" . "ttanjo@gmail.com")) (:maintainer "Tomoya Tanjo" . "ttanjo@gmail.com") (:keywords "tex") (:url . "https://github.com/tom-tan/auctex-latexmk/"))])
+ (auctex-lua . [(20151121 1610) ((auctex (11 86)) (lua-mode (20130419))) "Lua editing support for AUCTeX" single ((:commit . "799cd8ac10c96991bb63d9aa60528ae5d8c786b5") (:authors ("Sean Allred" . "seallred@smcm.edu")) (:maintainer "Sean Allred" . "seallred@smcm.edu") (:keywords "latex" "lua") (:url . "http://github.com/vermiculus/auctex-lua"))])
+ (audacious . [(20210917 51) ((helm (3 6 2)) (emacs (24 4))) "Emacs interface to control audacious" single ((:commit . "65c37f12a5c774a0ae434beee27ff7737006dd2f") (:authors ("Hitoshi Uchida" . "hitoshi.uchida@gmail.com")) (:maintainer "Hitoshi Uchida" . "hitoshi.uchida@gmail.com") (:url . "https://github.com/shishimaru/audacious.el"))])
+ (audio-notes-mode . [(20170611 2159) nil "Play audio notes synced from somewhere else." single ((:commit . "fa38350829c7e97257efc746a010471d33748a68") (:authors ("Artur Malabarba" . "bruce.connor.am@gmail.com")) (:maintainer "Artur Malabarba" . "bruce.connor.am@gmail.com") (:keywords "hypermedia" "convenience") (:url . "http://github.com/Bruce-Connor/audio-notes-mode"))])
+ (aurel . [(20170114 937) ((emacs (24 3)) (bui (1 1 0)) (dash (2 11 0))) "Search, get info, vote for and download AUR packages" single ((:commit . "fc7ad208f43f8525f84a18941c9b55f956df8961") (:authors ("Alex Kost" . "alezost@gmail.com")) (:maintainer "Alex Kost" . "alezost@gmail.com") (:keywords "tools") (:url . "https://github.com/alezost/aurel"))])
+ (aurora-config-mode . [(20180216 2302) nil "Major mode for Apache Aurora configuration files" single ((:commit . "8273ec7937a21b469b9dbb6c11714255b890f410") (:authors ("Berk D. Demir" . "bdd@mindcast.org")) (:maintainer "Berk D. Demir" . "bdd@mindcast.org") (:keywords "languages" "configuration") (:url . "https://github.com/bdd/aurora-config.el"))])
+ (auth-source-keytar . [(20220222 640) ((emacs (24 4)) (keytar (0 1 2)) (s (1 12 0))) "Integrate auth-source with keytar" single ((:commit . "09dd28d875dfe9d1ca9bb8ab3ee2f6102a00832b") (:authors ("Shen, Jen-Chieh" . "jcs090218@gmail.com")) (:maintainer "Shen, Jen-Chieh" . "jcs090218@gmail.com") (:url . "https://github.com/emacs-grammarly/auth-source-keytar"))])
+ (auth-source-kwallet . [(20210605 1032) ((emacs (24 4))) "KWallet integration for auth-source" single ((:commit . "053ed5e964acaf6f16a1708c36d812eeb7c1817d") (:authors ("Ekaterina Vaartis" . "vaartis@kotobank.ch")) (:maintainer "Ekaterina Vaartis" . "vaartis@kotobank.ch") (:url . "https://github.com/vaartis/auth-source-kwallet"))])
+ (auth-source-xoauth2 . [(20200911 1554) ((emacs (26 1))) "Integrate auth-source with XOAUTH2" single ((:commit . "d3890eaa3a46dc89758ec6b789949e70ae782896") (:authors ("Cesar Crusius" . "ccrusius@google.com")) (:maintainer "Cesar Crusius" . "ccrusius@google.com") (:url . "https://github.com/ccrusius/auth-source-xoauth2"))])
+ (auto-async-byte-compile . [(20160916 454) nil "Automatically byte-compile when saved" single ((:commit . "8681e74ddb8481789c5dbb3cafabb327db4c4484") (:authors ("rubikitch" . "rubikitch@ruby-lang.org")) (:maintainer "rubikitch" . "rubikitch@ruby-lang.org") (:keywords "lisp" "convenience") (:url . "http://www.emacswiki.org/cgi-bin/wiki/download/auto-async-byte-compile.el"))])
+ (auto-auto-indent . [(20131106 1903) ((es-lib (0 1)) (cl-lib (1 0))) "Indents code as you type" single ((:commit . "0139378577f936d34b20276af6f022fb457af490") (:authors ("sabof")) (:maintainer "sabof") (:url . "https://github.com/sabof/auto-auto-indent"))])
+ (auto-compile . [(20220422 1600) ((emacs (25 1)) (compat (28 1 1 0)) (packed (3 0 3))) "Automatically compile Emacs Lisp libraries" single ((:commit . "f19e9fbb8d72a47f0cef049b784e1a492bef9287") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:keywords "compile" "convenience" "lisp") (:url . "https://github.com/emacscollective/auto-compile"))])
+ (auto-complete . [(20220105 439) ((popup (0 5 0)) (cl-lib (0 5))) "Auto Completion for GNU Emacs" tar ((:commit . "d546b18c3e83e38686d9b7316c6c705597e1a8b3") (:authors ("Tomohiro Matsuyama" . "m2ym.pub@gmail.com")) (:maintainer "Jen-Chieh Shen" . "jcs090218@gmail.com") (:keywords "completion" "convenience") (:url . "https://github.com/auto-complete/auto-complete"))])
+ (auto-complete-auctex . [(20140223 1758) ((yasnippet (0 6 1)) (auto-complete (1 4))) "auto-completion for auctex" single ((:commit . "855633f668bcc4b9408396742a7cb84e0c4a2f77") (:authors ("Christopher Monsanto" . "chris@monsan.to")) (:maintainer "Christopher Monsanto" . "chris@monsan.to"))])
+ (auto-complete-c-headers . [(20150912 323) ((auto-complete (1 4))) "An auto-complete source for C/C++ header files" single ((:commit . "52fef720c6f274ad8de52bef39a343421006c511") (:authors ("Masafumi Oyamada" . "stillpedant@gmail.com")) (:maintainer "Masafumi Oyamada" . "stillpedant@gmail.com") (:keywords "c"))])
+ (auto-complete-chunk . [(20140225 946) ((auto-complete (1 4))) "Auto-completion for dot.separated.words." single ((:commit . "a9aa77ffb84a1037984a7ce4dda25074272f13fe") (:authors ("ARAKAKI, Takafumi")) (:maintainer "ARAKAKI, Takafumi") (:url . "https://github.com/tkf/auto-complete-chunk"))])
+ (auto-complete-clang . [(20140409 752) ((auto-complete (1 3 1))) "Auto Completion source for clang for GNU Emacs" single ((:commit . "a195db1d0593b4fb97efe50885e12aa6764d998c") (:authors ("Brian Jiang" . "brianjcj@gmail.com")) (:maintainer "Brian Jiang" . "brianjcj@gmail.com") (:keywords "completion" "convenience") (:url . "https://github.com/brianjcj/auto-complete-clang"))])
+ (auto-complete-clang-async . [(20130526 1514) nil "Auto Completion source for clang for GNU Emacs" single ((:commit . "5d9c5cabbb6b31e0ac3637631c0c8b25184aa8b4") (:keywords "completion" "convenience"))])
+ (auto-complete-distel . [(20180827 1344) ((auto-complete (1 4)) (distel-completion-lib (1 0 0))) "Erlang/distel completion backend for auto-complete-mode" single ((:commit . "acc4c0a5521904203d797fe96b08e5fae4233c7e") (:authors ("Sebastian Weddmark Olsson")) (:maintainer "Sebastian Weddmark Olsson") (:keywords "erlang" "distel" "auto-complete") (:url . "github.com/sebastiw/distel-completion"))])
+ (auto-complete-exuberant-ctags . [(20140320 724) ((auto-complete (1 4 0))) "Exuberant ctags auto-complete.el source" single ((:commit . "ff6121ff8b71beb5aa606d28fd389c484ed49765") (:authors ("Kenichirou Oyama" . "k1lowxb@gmail.com")) (:maintainer "Kenichirou Oyama" . "k1lowxb@gmail.com") (:keywords "anto-complete" "exuberant ctags") (:url . "http://code.101000lab.org"))])
+ (auto-complete-nxml . [(20140221 458) ((auto-complete (1 4))) "do completion by auto-complete.el on nXML-mode" single ((:commit . "ac7b09a23e45f9bd02affb31847263de4180163a") (:authors ("Hiroaki Otsu" . "ootsuhiroaki@gmail.com")) (:maintainer "Hiroaki Otsu" . "ootsuhiroaki@gmail.com") (:keywords "completion" "html" "xml") (:url . "https://github.com/aki2o/auto-complete-nxml"))])
+ (auto-complete-pcmp . [(20140227 651) ((auto-complete (1 4 0)) (log4e (0 2 0)) (yaxception (0 1))) "Provide auto-complete sources using pcomplete results" single ((:commit . "2595d3dab1ef3549271ca922f212928e9d830eec") (:authors ("Hiroaki Otsu" . "ootsuhiroaki@gmail.com")) (:maintainer "Hiroaki Otsu" . "ootsuhiroaki@gmail.com") (:keywords "completion") (:url . "https://github.com/aki2o/auto-complete-pcmp"))])
+ (auto-complete-rst . [(20140225 944) ((auto-complete (1 4))) "Auto-complete extension for ReST and Sphinx" tar ((:commit . "4803ce41a96224e6fa54e6741a5b5f40ebed7351") (:authors ("ARAKAKI, Takafumi")) (:maintainer "ARAKAKI, Takafumi") (:url . "https://github.com/tkf/auto-complete-rst"))])
+ (auto-complete-sage . [(20160514 751) ((auto-complete (1 5 1)) (sage-shell-mode (0 1 0))) "An auto-complete source for sage-shell-mode." single ((:commit . "51b8e3905196d266e1f8aa47881189833151b398") (:authors ("Sho Takemori" . "stakemorii@gmail.com")) (:maintainer "Sho Takemori" . "stakemorii@gmail.com") (:keywords "sage" "math" "auto-complete") (:url . "https://github.com/stakemori/auto-complete-sage"))])
+ (auto-dark . [(20220320 1703) ((emacs (24 4))) "Automatically set the dark-mode theme based on MacOS status" single ((:commit . "c5dd3afa6771f4777db9e427f21bfcbe4883abaf") (:authors ("Rahul M. Juliato") ("Tim Harper <timcharper at gmail dot com>")) (:maintainer "Rahul M. Juliato") (:keywords "tools" "unix" "faces") (:url . "https://github.com/LionyxML/auto-dark-emacs"))])
+ (auto-dictionary . [(20150410 1610) nil "automatic dictionary switcher for flyspell" single ((:commit . "b364e08009fe0062cf0927d8a0582fad5a12b8e7") (:authors ("Nikolaj Schumacher <bugs * nschum de>")) (:maintainer "Nikolaj Schumacher <bugs * nschum de>") (:keywords "wp") (:url . "http://nschum.de/src/emacs/auto-dictionary/"))])
+ (auto-dim-other-buffers . [(20220209 2101) nil "Makes windows without focus less prominent" single ((:commit . "33b5f88b799a17947c266b04ad59462c5aeb4ed7") (:authors ("Michal Nazarewicz" . "mina86@mina86.com")) (:maintainer "Michal Nazarewicz" . "mina86@mina86.com") (:url . "https://github.com/mina86/auto-dim-other-buffers.el"))])
+ (auto-highlight-symbol . [(20220505 505) ((emacs (26 1)) (ht (2 3))) "Automatic highlighting current symbol minor mode" single ((:commit . "3d60d2c64278f9f933ee78299f6decde2254af7e") (:authors ("Mitsuo Saito" . "arch320@NOSPAM.gmail.com")) (:maintainer "Shen, Jen-Chieh" . "jcs090218@gmail.com") (:keywords "highlight" "face" "match" "convenience") (:url . "http://github.com/jcs-elpa/auto-highlight-symbol"))])
+ (auto-indent-mode . [(20211029 11) nil "Auto indent Minor mode" tar ((:commit . "664006b67329a8e27330541547f8c2187dab947c") (:authors ("Matthew L. Fidler, Le Wang & Others")) (:maintainer "Matthew L. Fidler") (:keywords "auto" "indentation") (:url . "https://github.com/mlf176f2/auto-indent-mode.el/"))])
+ (auto-minor-mode . [(20180527 1123) ((emacs (24 4))) "Enable minor modes by file name and contents" single ((:commit . "17cfa1b54800fdef2975c0c0531dad34846a5065") (:authors ("Joe Wreschnig" . "joe.wreschnig@gmail.com")) (:maintainer "Joe Wreschnig" . "joe.wreschnig@gmail.com") (:keywords "convenience") (:url . "https://github.com/joewreschnig/auto-minor-mode"))])
+ (auto-org-md . [(20180213 2343) ((emacs (24 4))) "export a markdown file automatically when you save an org-file" single ((:commit . "9318338bdb7fe8bd698d88f3af89b2d6413efdd2") (:authors ("jamcha" . "jamcha.aa@gmail.com")) (:maintainer "jamcha" . "jamcha.aa@gmail.com") (:keywords "org" "markdown") (:url . "https://github.com/jamcha-aa/auto-org-md"))])
+ (auto-package-update . [(20211108 2025) ((emacs (24 4)) (dash (2 1 0))) "Automatically update Emacs packages." single ((:commit . "ad95435fefe2bb501d1d787b08272f9c1b7df488") (:authors ("Renan Ranelli")) (:maintainer "Renan Ranelli") (:keywords "package" "update") (:url . "http://github.com/rranelli/auto-package-update.el"))])
+ (auto-pause . [(20160426 1216) ((emacs (24 4))) "Run processes which will be paused when Emacs is idle" single ((:commit . "a4d778de774ca3895542cb559a953e0d98657338") (:authors ("DarkSun" . "lujun9972@gmail.com")) (:maintainer "DarkSun" . "lujun9972@gmail.com") (:keywords "convenience" "menu") (:url . "https://github.com/lujun9972/auto-pause"))])
+ (auto-read-only . [(20200827 1754) ((emacs (25 1)) (cl-lib (0 5))) "Automatically make the buffer to read-only" single ((:commit . "db209bf5b7f76f4c3dc4d0892fc6a24430779f29") (:authors ("USAMI Kenta" . "tadsan@zonu.me")) (:maintainer "USAMI Kenta" . "tadsan@zonu.me") (:keywords "files" "convenience") (:url . "https://github.com/zonuexe/auto-read-only.el"))])
+ (auto-rename-tag . [(20210805 1344) ((emacs (24 4))) "Automatically rename paired HTML/XML tag" single ((:commit . "85b02fa6ce76ab872c025a82c2f14614af3d89e1") (:authors ("Shen, Jen-Chieh" . "jcs090218@gmail.com")) (:maintainer "Shen, Jen-Chieh" . "jcs090218@gmail.com") (:url . "https://github.com/jcs-elpa/auto-rename-tag"))])
+ (auto-save-buffers-enhanced . [(20161109 710) nil "Automatically save buffers in a decent way" single ((:commit . "461e8c816c1b7c650be5f209078b381fe55da8c6") (:authors ("Kentaro Kuribayashi" . "kentarok@gmail.com")) (:maintainer "Kentaro Kuribayashi" . "kentarok@gmail.com"))])
+ (auto-shell-command . [(20180817 1502) ((deferred (20130312)) (popwin (20130329))) "Run the shell command asynchronously that you specified when you save the file." single ((:commit . "a8f9213e3c773b5687b81881240e6e648f2f56ba") (:authors ("ongaeshi")) (:maintainer "ongaeshi") (:keywords "shell" "save" "async" "deferred" "auto"))])
+ (auto-sudoedit . [(20220421 1147) ((emacs (26 1)) (f (0 19 0))) "Auto sudo edit by tramp" single ((:commit . "39cb574a4b5ec74ad62857320bf5fec58abe876f") (:authors ("ncaq" . "ncaq@ncaq.net")) (:maintainer "ncaq" . "ncaq@ncaq.net") (:url . "https://github.com/ncaq/auto-sudoedit"))])
+ (auto-virtualenv . [(20211215 907) ((cl-lib (0 5)) (pyvenv (1 9)) (s (1 10 0))) "Auto activate python virtualenvs" single ((:commit . "07064e05feb62277991b8a7c04f7cdad50acaddf") (:authors ("Marcwebbie" . "marcwebbie@gmail.com")) (:maintainer "Marcwebbie" . "marcwebbie@gmail.com") (:keywords "python" "virtualenv" "tools") (:url . "http://github.com/marcwebbie/auto-virtualenv"))])
+ (auto-virtualenvwrapper . [(20200510 1006) ((cl-lib (0 6)) (s (1 10 0)) (virtualenvwrapper (0))) "Lightweight auto activate python virtualenvs" single ((:commit . "30fb54aa3c99f3c614ea9a92669d634df30c9439") (:authors ("Marcwebbie" . "marcwebbie@gmail.com") ("Robert Zaremba" . "robert-zaremba@scale-it.pl")) (:maintainer "Marcwebbie" . "marcwebbie@gmail.com") (:keywords "python" "virtualenv" "tools"))])
+ (auto-yasnippet . [(20191015 942) ((yasnippet (0 13 0))) "Quickly create disposable yasnippets" single ((:commit . "db9e0dd4335b2202cd5dac95bbbc87a1032d9bbe") (:authors ("Oleh Krehel" . "ohwoeowho@gmail.com")) (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com") (:url . "https://github.com/abo-abo/auto-yasnippet"))])
+ (autobookmarks . [(20190919 841) ((dash (2 10 0)) (cl-lib (0 5))) "Save recently visited files and buffers" single ((:commit . "224b24950d3ae57cd16d7417c07fda337fe0ea09") (:authors ("Matúš Goljer" . "matus.goljer@gmail.com")) (:maintainer "Matúš Goljer" . "matus.goljer@gmail.com") (:keywords "files"))])
+ (autobuild . [(20200713 227) ((cl-lib (0 3)) (emacs (26 1))) "Define and execute build rules and compilation pipelines" single ((:commit . "9b068d979bad78aba8e8bef9f9e7c3bfecb34d2d") (:authors ("Ernesto Alfonso")) (:maintainer nil . "(concat \"erjoalgo\" \"@\" \"gmail\" \".com\")") (:keywords "compile" "build" "pipeline" "autobuild" "extensions" "processes" "tools") (:url . "https://github.com/erjoalgo/autobuild"))])
+ (autocrypt . [(20220215 1204) ((emacs (24 3))) "Autocrypt implementation" tar ((:commit . "00b87a82c4561b017052974eecd93c79b6790841") (:authors ("Philip Kaludercic" . "philipk@posteo.net")) (:maintainer "Philip Kaludercic" . "~pkal/public-inbox@lists.sr.ht") (:keywords "comm") (:url . "https://git.sr.ht/~pkal/autocrypt"))])
+ (autodisass-java-bytecode . [(20211005 1920) nil "Automatically disassemble Java bytecode" tar ((:commit . "9eaddd63645e64825b2d07805999c5a645248c53") (:authors ("George Balatsouras <gbalats(at)gmail(dot)com>")) (:maintainer "George Balatsouras <gbalats(at)gmail(dot)com>") (:keywords "convenience" "data" "files"))])
+ (autodisass-llvm-bitcode . [(20150411 125) nil "Automatically disassemble LLVM bitcode" tar ((:commit . "d2579e3a1427af2dc947c343e49eb3434078bf04") (:authors ("George Balatsouras <gbalats(at)gmail(dot)com>")) (:maintainer "George Balatsouras <gbalats(at)gmail(dot)com>") (:keywords "convenience" "data" "files"))])
+ (autotest . [(20190331 2230) nil "ZenTest's autotest integration with emacs." single ((:commit . "09166f32d3ece2b297da036f0abbeba63329580e") (:authors ("Ryan Davis" . "ryand-ruby@zenspider.com")) (:maintainer "Ryan Davis" . "ryand-ruby@zenspider.com") (:keywords "testing" "ruby" "convenience") (:url . "https://github.com/zenspider/elisp/blob/master/autotest.el"))])
+ (autotetris-mode . [(20141114 1646) ((cl-lib (0 5))) "automatically play tetris" single ((:commit . "0c3a746dcc304a67d2a6e7ad4ef93f512486343a") (:authors ("Christopher Wellons" . "wellons@nullprogram.com")) (:maintainer "Christopher Wellons" . "wellons@nullprogram.com") (:url . "https://github.com/skeeto/autotetris-mode"))])
+ (autothemer . [(20220106 416) ((dash (2 10 0)) (emacs (24)) (cl-lib (0 5))) "Conveniently define themes." single ((:commit . "1dbc06ad430c51b5ec1a602a808ee46b9bd4bafa") (:authors ("Sebastian Sturm")) (:maintainer "Sebastian Sturm") (:url . "https://github.com/sebastiansturm/autothemer"))])
+ (autumn-light-theme . [(20150515 1447) nil "A light color theme with muted, autumnal colors." single ((:commit . "1e3b2a43a3001e4a97a5ff073ba3f0d2ea3888f9") (:authors ("Adam Alpern" . "adam.alpern@gmail.com")) (:maintainer "Adam Alpern" . "adam.alpern@gmail.com") (:keywords "color" "theme") (:url . "http://github.com/aalpern/emacs-color-theme-autumn-light"))])
+ (avandu . [(20170101 1903) nil "Gateway to Tiny Tiny RSS" tar ((:commit . "f44588d8e747fa880411cb4542cc39962252b90a") (:authors ("Tom Willemse" . "tom@ryuslash.org")) (:maintainer "Tom Willemse" . "tom@ryuslash.org") (:keywords "net"))])
+ (avk-emacs-themes . [(20210521 1051) nil "Collection of avk themes" tar ((:commit . "7b9b6517873c4d4d73e6e34ca56c54062db60759") (:authors ("Alex V. Koval" . "alex@koval.kharkov.ua")) (:maintainer "Alex V. Koval" . "alex@koval.kharkov.ua") (:keywords "theme") (:url . "https://github.com/avkoval/avk-emacs-themes"))])
+ (avy . [(20220102 805) ((emacs (24 1)) (cl-lib (0 5))) "Jump to arbitrary positions in visible text and select text quickly." single ((:commit . "ba5f035be33693d1a136a5cbeedb24327f551a92") (:authors ("Oleh Krehel" . "ohwoeowho@gmail.com")) (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com") (:keywords "point" "location") (:url . "https://github.com/abo-abo/avy"))])
+ (avy-embark-collect . [(20220221 1638) ((emacs (25 1)) (embark (0 9)) (avy (0 5))) "Use avy to jump to Embark Collect entries" single ((:commit . "80ff7d105afc090817c4162ec021758e586272f2") (:authors ("Omar Antolín Camarena" . "omar@matem.unam.mx")) (:maintainer "Omar Antolín Camarena" . "omar@matem.unam.mx") (:keywords "convenience") (:url . "https://github.com/oantolin/embark"))])
+ (avy-flycheck . [(20160720 1500) ((emacs (24 1)) (flycheck (0 14)) (seq (1 11)) (avy (0 4 0))) "Jump to and fix syntax errors using `flycheck' with `avy' interface" single ((:commit . "5522f3bbbed1801d9278ed696ec0cbba38352985") (:authors ("Xu Ma" . "magicdirac@gmail.com")) (:maintainer "Xu Ma" . "magicdirac@gmail.com") (:keywords "tools" "convenience" "avy" "flycheck") (:url . "https://github.com/magicdirac/avy-flycheck"))])
+ (avy-menu . [(20210321 1732) ((emacs (24 3)) (avy (0 4 0))) "Library providing avy-powered popup menu" single ((:commit . "18bb320f395b7e412f7e377cf4c46d205d4b4e1a") (:authors ("Mark Karpov" . "markkarpov92@gmail.com")) (:maintainer "Mark Karpov" . "markkarpov92@gmail.com") (:keywords "popup" "menu") (:url . "https://github.com/mrkkrp/avy-menu"))])
+ (avy-migemo . [(20180716 1455) ((emacs (24 4)) (avy (0 4 0)) (migemo (1 9))) "avy with migemo" tar ((:commit . "922a6dd82c0bfa316b0fbb56a9d4dd4ffa5707e7") (:authors ("momomo5717")) (:maintainer "momomo5717") (:keywords "avy" "migemo") (:url . "https://github.com/momomo5717/avy-migemo"))])
+ (avy-zap . [(20190801 329) ((avy (0 2 0))) "Zap to char using `avy'" single ((:commit . "7c8d1f40e43d03e2f6c1696bfa547526528ce8cb") (:authors ("Junpeng Qiu" . "qjpchmail@gmail.com")) (:maintainer "Junpeng Qiu" . "qjpchmail@gmail.com") (:keywords "extensions") (:url . "https://github.com/cute-jumper/avy-zap"))])
+ (aws-ec2 . [(20161007 1914) ((emacs (24 4)) (dash (2 12 1)) (tblui (0 1 0))) "Manage AWS EC2 instances" single ((:commit . "5601d4f268fc34b86a02ca90cde7d3771619a368") (:authors ("Yuki Inoue <inouetakahiroki _at_ gmail.com>")) (:maintainer "Yuki Inoue <inouetakahiroki _at_ gmail.com>") (:url . "https://github.com/Yuki-Inoue/aws.el"))])
+ (aws-snippets . [(20191203 1553) ((yasnippet (0 8 0))) "Yasnippets for AWS" tar ((:commit . "557d19a0bc486e0fddb597b2be5087769d9bd47e") (:keywords "snippets"))])
+ (awscli-capf . [(20190930 1517) ((emacs (26))) "Completion at point function for the AWS CLI" single ((:commit . "eadfb26b35802ae8164565581e4a9c4d0280a7b5") (:authors ("Sebastian Monia" . "smonia@outlook.com")) (:maintainer "Sebastian Monia" . "smonia@outlook.com") (:keywords "tools" "convenience" "abbrev") (:url . "https://github.com/sebasmonia/awscli-capf.git"))])
+ (axe . [(20210816 1530) ((emacs (25 1)) (hmac (0 0)) (request (0 3 2)) (s (1 12 0)) (xmlgen (0 5)) (dash (2 17 0)) (mimetypes (1 0))) "AWS Extensions" tar ((:commit . "eb4a5b3b06c3cbed521e2c0e0985941c367f4e74") (:authors ("Craig Niles <niles.c at gmail.com>")) (:maintainer "Craig Niles <niles.c at gmail.com>") (:url . "https://github.com/cniles/axe"))])
+ (axiom-environment . [(20211120 1646) ((emacs (24 2))) "An environment for using Axiom/OpenAxiom/FriCAS" tar ((:commit . "e60de5ed107ffeb530a56d24d04f38988124d12b") (:authors ("Paul Onions" . "paul.onions@acm.org")) (:maintainer "Paul Onions" . "paul.onions@acm.org") (:keywords "axiom" "openaxiom" "fricas"))])
+ (ayu-theme . [(20200521 1157) ((emacs (24 1))) "Ayu theme" tar ((:commit . "ed98a9f41d9f0e08458ee71cc1038f66c50e1979") (:authors ("Tran Anh Vu")) (:maintainer "Tran Anh Vu") (:keywords "lisp" "theme" "emacs") (:url . "https://github.com/vutran1710/Ayu-Theme-Emacs"))])
+ (babel . [(20210612 640) nil "interface to web translation services such as Babelfish" single ((:commit . "946e69c61188bc41793402ac48466d8967ddb43d") (:authors ("Juergen Hoetzel" . "juergen@hoetzel.info") ("Eric Marsden" . "emarsden@laas.fr")) (:maintainer "Juergen Hoetzel" . "juergen@hoetzel.info") (:keywords "translation" "web") (:url . "http://github.com/juergenhoetzel/babel"))])
+ (babel-repl . [(20160504 2201) ((emacs (24))) "Run babel REPL" single ((:commit . "e619c16e349a1ee7bd0ee0d7f3650d33bff73fc3") (:authors ("Hung Phan")) (:maintainer "Hung Phan") (:keywords "babel" "javascript" "es6") (:url . "https://github.com/hung-phan/babel-repl/"))])
+ (back-button . [(20150804 2004) ((nav-flash (1 0 0)) (smartrep (0 0 3)) (ucs-utils (0 7 2)) (list-utils (0 4 2)) (persistent-soft (0 8 8)) (pcache (0 2 3))) "Visual navigation through mark rings" single ((:commit . "98d92984a740acd1547bd7ed05cca0affdb21c3e") (:authors ("Roland Walker" . "walker@pobox.com")) (:maintainer "Roland Walker" . "walker@pobox.com") (:keywords "convenience" "navigation" "interface") (:url . "http://github.com/rolandwalker/back-button"))])
+ (backlight . [(20210513 129) ((emacs (24 3))) "backlight brightness adjustment on GNU/Linux" single ((:commit . "b6826a60440d8bf440618e3cdafb40158de920e6") (:authors ("Michael Schuldt" . "mbschuldt@gmail.com")) (:maintainer "Michael Schuldt" . "mbschuldt@gmail.com") (:keywords "hardware") (:url . "https://github.com/mschuldt/backlight.el"))])
+ (backline . [(20220424 2212) ((emacs (25 1)) (compat (28 1 1 0)) (outline-minor-faces (0 1 2))) "Preserve appearance of outline headings" single ((:commit . "0d44408262080cdf998de5a52516f220e7e7c99a") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:keywords "outlines") (:url . "https://github.com/tarsius/backline"))])
+ (backup-each-save . [(20180227 557) nil "backup each savepoint of a file" single ((:commit . "3c414b9d6b278911c95c5b8b71819e6af6f8a02a") (:authors ("Benjamin Rutt" . "brutt@bloomington.in.us")) (:maintainer "Conor Nash" . "conor@nashcobusinessservicesllc.com"))])
+ (backup-walker . [(20130720 1516) nil "quickly traverse all backups of a file" single ((:commit . "934a4128c122972ac32bb9952addf279a60a94da") (:authors ("Le Wang")) (:maintainer "Le Wang") (:keywords "backup") (:url . "https://github.com/lewang/backup-walker"))])
+ (backward-forward . [(20161229 550) ((emacs (24 5))) "navigation backwards and forwards across marks" single ((:commit . "58489957a62a0da25dfb5df902624d2548d800b4") (:authors ("Currell Berry" . "currellberry@gmail.com")) (:maintainer "Currell Berry" . "currellberry@gmail.com") (:keywords "navigation" "convenience" "backward" "forward") (:url . "https://gitlab.com/vancan1ty/emacs-backward-forward/tree/master"))])
+ (badger-theme . [(20140717 232) nil "A dark theme for Emacs 24." single ((:commit . "493d672d5a5478976da7d5ca752008cc7837c57f") (:authors ("Cody Canning" . "cocanning11@gmail.com")) (:maintainer "Cody Canning" . "cocanning11@gmail.com") (:url . "https://github.com/ccann/badger-theme"))])
+ (badwolf-theme . [(20161004 715) ((emacs (24))) "Bad Wolf color theme" single ((:commit . "ea01a3d9358e968f75e3ed15dec6a2a96ce3d9a1") (:authors ("bkruczyk" . "bartlomiej.kruczyk@gmail.com")) (:maintainer "bkruczyk" . "bartlomiej.kruczyk@gmail.com") (:keywords "themes") (:url . "https://github.com/bkruczyk/badwolf-emacs"))])
+ (baff . [(20200824 1807) ((emacs (24 3)) (f (0 20 0))) "Create a byte array from a file" single ((:commit . "7af72db9c6e542ed2b60952933113d0aa86728cf") (:authors ("Dave Footitt" . "dave.footitt@gmail.com")) (:maintainer "Dave Footitt" . "dave.footitt@gmail.com") (:keywords "convenience" "usability") (:url . "https://github.com/dave-f/baff/"))])
+ (baidu-translate . [(20211130 1235) ((unicode-escape (1 1))) "A plugin using baidu-translate-api" single ((:commit . "16101d5e6ce19bbcc8badf4422a95db457160999") (:authors (nil . "<LiShizhen gsu4017@gmail.com>")) (:maintainer nil . "<LiShizhen gsu4017@gmail.com>") (:keywords "docs") (:url . "https://github.com/liShiZhensPi/baidu-translate"))])
+ (balanced-windows . [(20190903 1120) ((emacs (25))) "Keep windows balanced" single ((:commit . "1da5354ad8a9235d13928e2ee0863f3642ccdd13") (:authors ("wouter bolsterlee" . "wouter@bolsterl.ee")) (:maintainer "wouter bolsterlee" . "wouter@bolsterl.ee") (:keywords "convenience") (:url . "https://github.com/wbolster/emacs-balanced-windows"))])
+ (banner-comment . [(20190606 1809) ((emacs (24 4))) "For producing banner comments." single ((:commit . "35d3315683d3f97605207691b77e9f447af18fe2") (:authors ("James Ferguson" . "james@faff.org")) (:maintainer "James Ferguson" . "james@faff.org") (:keywords "convenience") (:url . "https://github.com/WJCFerguson/banner-comment"))])
+ (bap-mode . [(20200128 1354) nil "Major-mode for BAP's IR" single ((:commit . "8969679f60db0aa918d35f40d959c0a9c723b111") (:authors ("Thomas Barabosch <http://github/tbarabosch>")) (:maintainer "Thomas Barabosch" . "thomas.barabosch@fkie.fraunhofer.de") (:keywords "languages") (:url . "https://github.com/fkie-cad/bap-mode"))])
+ (bar-cursor . [(20201204 2244) nil "package used to switch block cursor to a bar" single ((:commit . "78f195b6db63459033c4f1c7e7add5d82f3ce424") (:authors ("Joe Casadonte" . "emacs@northbound-train.com")) (:maintainer "Andrew Johnson" . "andrew@andrewjamesjohnson.com") (:keywords "files") (:url . "https://github.com/ajsquared/bar-cursor"))])
+ (bart-mode . [(20190601 1004) ((emacs (24 3))) "Real time BART departures info." single ((:commit . "f70b6c42452e47c0c6b3ebd4c90e555a9bedeec7") (:authors ("Michael Schuldt" . "mbschuldt@gmail.com")) (:maintainer "Michael Schuldt" . "mbschuldt@gmail.com") (:keywords "convenience" "transit") (:url . "https://github.com/mschuldt/bart-mode"))])
+ (base16-theme . [(20211225 2032) nil "Collection of themes built on combinations of 16 base colors" tar ((:commit . "ad2fd1137d6ec144f87b26dce15ce5c5d42bde39") (:authors ("Kaleb Elwert" . "belak@coded.io") ("Neil Bhakta")) (:maintainer "Kaleb Elwert" . "belak@coded.io") (:url . "https://github.com/belak/base16-emacs"))])
+ (bash-completion . [(20220328 844) ((emacs (24 3))) "BASH completion for the shell buffer" single ((:commit . "29b5fc860a5b0db9828acfceca09b773fbdb8e8a") (:authors ("Stephane Zermatten" . "szermatt@gmx.net")) (:maintainer "Stephane Zermatten" . "szermatt@gmail.com") (:keywords "shell" "bash" "bash-completion") (:url . "http://github.com/szermatt/emacs-bash-completion"))])
+ (basic-c-compile . [(20170302 1112) ((cl-lib (0 5)) (f (0 19 0))) "Quickly create a Makefile, compile and run C." single ((:commit . "0129786aeee50d7bb0020d9fc2b7508875d403e8") (:authors ("Nick Spain" . "nicholas.spain96@gmail.com")) (:maintainer "Nick Spain" . "nicholas.spain96@gmail.com") (:keywords "c" "makefile" "compilation" "convenience") (:url . "https://github.com/nick96/basic-c-compile"))])
+ (basic-ide . [(20200429 1104) ((emacs (25)) (basic-mode (0 4 2)) (company (0 9 12)) (flycheck (0 22)) (dash (2 12 0)) (f (0 17 0))) "BASIC IDE c64" single ((:commit . "1d026b6ae70db9cde36596dcf46b101058a2e004") (:authors ("Fermin MF" . "fmfs@posteo.net")) (:maintainer "Fermin MF" . "fmfs@posteo.net") (:keywords "languages" "basic") (:url . "https://gitlab.com/sasanidas/emacs-c64-basic-ide"))])
+ (basic-mode . [(20210316 1253) ((seq (2 20)) (emacs (24 3))) "major mode for editing BASIC code" single ((:commit . "eaa5f24d2fb303d9e5d7de2a28c7c18b01532ab6") (:authors ("Johan Dykstrom")) (:maintainer "Johan Dykstrom") (:keywords "basic" "languages") (:url . "https://github.com/dykstrom/basic-mode"))])
+ (basic-theme . [(20160817 827) ((emacs (24))) "Minimalistic light color theme" single ((:commit . "e2a855bd39f4b78296228d4b790f9123156f7d7e") (:authors ("Felix Geller" . "fgeller@gmail.com")) (:maintainer "Felix Geller" . "fgeller@gmail.com") (:keywords "theme" "basic" "minimal" "colors") (:url . "http://github.com/fgeller/basic-theme.el"))])
+ (bats-mode . [(20160514 615) nil "Emacs mode for editing and running Bats tests" single ((:commit . "d519f7c89f5ae17dfc33400596df4564b478315f") (:authors ("Doug MacEachern")) (:maintainer "Doug MacEachern") (:keywords "bats" "tests") (:url . "https://github.com/dougm/bats-mode"))])
+ (battery-notifier . [(20210521 1238) ((alert (1 3))) "Notify when battery capacity is low" single ((:commit . "ae2043db954e131d9de7347ab1a6107fd07e8893") (:authors ("Jason Johnson" . "jason@fullsteamlabs.com")) (:maintainer "Jason Johnson" . "jason@fullsteamlabs.com") (:keywords "hardware" "battery") (:url . "https://github.com/jasonmj/battery-notifier"))])
+ (battle-haxe . [(20210219 354) ((emacs (25)) (company (0 9 9)) (helm (3 0)) (async (1 9 3)) (cl-lib (0 5)) (dash (2 18 0)) (s (1 10 0)) (f (0 19 0))) "A Haxe development system, with code completion and more" single ((:commit . "2f32c81dcecfc68fd410cb9d2aca303d6e3028c7") (:authors ("Alon Tzarafi " . "alontzarafi@gmail.com")) (:maintainer "Alon Tzarafi " . "alontzarafi@gmail.com") (:keywords "programming" "languages" "completion") (:url . "https://github.com/AlonTzarafi/battle-haxe"))])
+ (bazel . [(20220222 1616) ((emacs (26 1))) "Bazel support for Emacs" single ((:commit . "e07a16666154c8ddc65ddaae599d58b25727350d") (:keywords "build tools" "languages") (:url . "https://github.com/bazelbuild/emacs-bazel-mode"))])
+ (bbcode-mode . [(20190304 2122) ((emacs (24)) (cl-lib (0 5))) "Major mode for phpBB posts (BBCode markup)" single ((:commit . "e16619c80ea21154b4a4ccc2e13d0077e97c9caf") (:authors ("Eric James Michael Ritz" . "lobbyjones@gmail.com")) (:maintainer "Lassi Kortela" . "lassi@lassi.io") (:keywords "bbcode" "languages") (:url . "https://github.com/lassik/emacs-bbcode-mode"))])
+ (bbdb . [(20220416 405) nil "The Insidious Big Brother Database for GNU Emacs" tar ((:commit . "ed7648f723d3fd03476b8a007a76e9058f7f7f47") (:maintainer "Roland Winkler" . "winkler@gnu.org"))])
+ (bbdb- . [(20140221 2354) ((bbdb (20140123 1541)) (log4e (0 2 0)) (yaxception (0 1))) "provide interface for more easily search/choice than BBDB." single ((:commit . "2839e84c894de2513af41053e80a277a1b483d22") (:authors ("Hiroaki Otsu" . "ootsuhiroaki@gmail.com")) (:maintainer "Hiroaki Otsu" . "ootsuhiroaki@gmail.com") (:keywords "bbdb" "news" "mail") (:url . "https://github.com/aki2o/bbdb-"))])
+ (bbdb-csv-import . [(20140802 1142) ((pcsv (1 3 3)) (dash (2 5 0)) (bbdb (20140412 1949))) "import csv to bbdb version 3+" single ((:commit . "dc9e722d1c1fcd55b71625ee3f05a4921851d186") (:authors ("Ian Kelling" . "ian@iankelling.org")) (:maintainer "Ian Kelling" . "ian@iankelling.org") (:keywords "csv" "util" "bbdb") (:url . "https://gitlab.com/iankelling/bbdb-csv-import"))])
+ (bbdb-ext . [(20151220 2013) ((bbdb (2 36))) "Extra commands for BBDB" single ((:commit . "fee97b1b3faa83edaea00fbc5ad3cbca5e791a55") (:authors ("Joe Bloggs" . "vapniks@yahoo.com")) (:maintainer "Joe Bloggs" . "vapniks@yahoo.com") (:keywords "extensions") (:url . "https://github.com/vapniks/bbdb-ext"))])
+ (bbdb-vcard . [(20210325 2208) ((bbdb (3 0))) "vCard import/export for BBDB" tar ((:commit . "113c66115ce68316e209f51ebce56de8dded3606") (:authors ("Bert Burgemeister" . "trebbu@googlemail.com") ("Toke Høiland-Jørgensen") ("Kevin Brubeck Unhammer") ("Steve Purcell") ("Vincent Geddes" . "vincent.geddes@gmail.com")) (:maintainer "Bert Burgemeister" . "trebbu@googlemail.com") (:keywords "data" "calendar" "mail" "news") (:url . "https://github.com/tohojo/bbdb-vcard"))])
+ (bbdb2erc . [(20190822 907) ((bbdb (3 0))) "make bbdb show if pal is online with ERC, click i to chat" single ((:commit . "40b89e961762af3e7ade3a1844a9fbcd4084ac65") (:authors ("Kevin Brubeck Unhammer" . "unhammer@fsfe.org")) (:maintainer "Kevin Brubeck Unhammer" . "unhammer@fsfe.org") (:keywords "irc" "contacts" "chat" "client" "internet"))])
+ (bbyac . [(20180206 1441) ((browse-kill-ring (1 3)) (cl-lib (0 5))) "Type a little Bit, and Bang! You Are Completed." tar ((:commit . "9f0de9cad13801891ffb590dc09f51ff9a7cb225") (:authors ("Bao Haojun" . "baohaojun@gmail.com")) (:maintainer "Bao Haojun" . "baohaojun@gmail.com") (:keywords "abbrev") (:url . "https://github.com/baohaojun/bbyac"))])
+ (beacon . [(20190104 1931) ((seq (2 14))) "Highlight the cursor whenever the window scrolls" single ((:commit . "bde78180c678b233c94321394f46a81dc6dce1da") (:authors ("Artur Malabarba" . "emacs@endlessparentheses.com")) (:maintainer "Artur Malabarba" . "emacs@endlessparentheses.com") (:keywords "convenience") (:url . "https://github.com/Malabarba/beacon"))])
+ (beeminder . [(20201227 1533) ((emacs (24 3)) (seq (2 16)) (org (7))) "Emacs interface for Beeminder" tar ((:commit . "161d9c94c594614a01cb08219693d9e000af4f69") (:authors ("Phil Newton" . "phil@sodaware.net")) (:maintainer "Phil Newton" . "phil@sodaware.net") (:keywords "tools" "beeminder") (:url . "http://www.philnewton.net/code/beeminder-el/"))])
+ (beginend . [(20220409 846) ((emacs (25 3))) "Redefine M-< and M-> for some modes" single ((:commit . "bbcfdc0909c20ddee41e95b7ade7de63af73b220") (:url . "https://github.com/DamienCassou/beginend"))])
+ (belarus-holidays . [(20190102 1343) nil "Belarus holidays whith transfers" single ((:commit . "35a18273e19edc3b4c761030ffbd11116483b83e") (:authors ("Yauhen Makei" . "yauhen.makei@gmail.com")) (:maintainer "Yauhen Makei" . "yauhen.makei@gmail.com") (:url . "http://bitbucket.org/EugeneMakei/belarus-holidays.el"))])
+ (benchmark-init . [(20220414 1612) ((emacs (24 3))) "Benchmarks for require and load calls" tar ((:commit . "02435560415bbadbcf5051fb7042880549170e7e") (:authors ("Steve Purcell")) (:maintainer "David Holm" . "dholmster@gmail.com") (:keywords "convenience" "benchmark") (:url . "https://github.com/dholm/benchmark-init-el"))])
+ (benchstat . [(20171014 312) nil "proper benchmarking made simple" single ((:commit . "a5b67cf7972ca2bbc9f5bc6a0f521ab02b76d4f0") (:authors ("Iskander Sharipov" . "quasilyte@gmail.com")) (:maintainer "Iskander Sharipov" . "quasilyte@gmail.com") (:keywords "lisp") (:url . "https://github.com/Quasilyte/benchstat.el"))])
+ (bencoding . [(20200331 1102) ((emacs (25 1))) "Bencoding decoding and encoding" single ((:commit . "1e16ccfd5c6560a83ae2926afe4a5076a541d3d6") (:authors ("Xu Chunyang")) (:maintainer "Xu Chunyang") (:keywords "tools") (:url . "https://github.com/xuchunyang/bencoding.el"))])
+ (berrys-theme . [(20191201 1609) ((emacs (24 1))) "A light, clean and elegant theme" single ((:commit . "888a14206b2fb3dc45b5273aeb05075f3e0b5f60") (:authors ("Slava Buzin" . "v8v.buzin@gmail.com")) (:maintainer "Slava Buzin" . "v8v.buzin@gmail.com") (:url . "https://github.com/vbuzin/berrys-theme"))])
+ (bert . [(20131117 1014) nil "BERT serialization library for Emacs" single ((:commit . "a3eec6980a725aa4abd2019e4c00246450260490") (:authors ("Oleksandr Manzyuk" . "manzyuk@gmail.com")) (:maintainer "Oleksandr Manzyuk" . "manzyuk@gmail.com") (:keywords "comm" "data"))])
+ (better-defaults . [(20220116 2220) ((emacs (25 1))) "Fixing weird quirks and poor defaults" single ((:commit . "20ac176ccdc18ff8cb4a6b37cf1fe90fa7f88335") (:authors ("Phil Hagelberg")) (:maintainer "Phil Hagelberg") (:keywords "convenience") (:url . "https://github.com/technomancy/better-defaults"))])
+ (better-jumper . [(20220110 118) ((emacs (25 1))) "configurable jump list" single ((:commit . "47622213783ece37d5337dc28d33b530540fc319") (:authors ("Bryan Gilbert <http://github/gilbertw1>")) (:maintainer "Bryan Gilbert" . "bryan@bryan.sh") (:keywords "convenience" "jump" "history" "evil") (:url . "https://github.com/gilbertw1/better-jumper"))])
+ (better-scroll . [(20210715 1004) ((emacs (24 3))) "Improve user experience when scrolling window" single ((:commit . "f04dad824b9879f7382f36780a0151e4ef544815") (:authors ("Shen, Jen-Chieh" . "jcs090218@gmail.com")) (:maintainer "Shen, Jen-Chieh" . "jcs090218@gmail.com") (:url . "https://github.com/jcs-elpa/better-scroll"))])
+ (better-shell . [(20191025 1737) ((emacs (24 4))) "Better shell management" single ((:commit . "70c787b981caeef8c5f8012b170eb7b9f167cd13") (:authors ("Russell Black" . "killdash9@github")) (:maintainer "Russell Black" . "killdash9@github") (:keywords "convenience") (:url . "https://github.com/killdash9/better-shell"))])
+ (bf-mode . [(20130403 1442) nil "Browse file persistently on dired" single ((:commit . "7cc4d09aed64d9db6be95646f5f5067de68f8895") (:authors ("isojin")) (:maintainer "myuhe <yuhei.maeda_at_gmail.com>") (:keywords "convenience") (:url . "https://github.com/emacs-jp/bf-mode"))])
+ (bfbuilder . [(20210228 1740) ((cl-lib (0 3)) (emacs (24 4))) "A brainfuck development environment with interactive debugger" single ((:commit . "689f320a9a1326cdeff43b8538e0d739f8519c4b") (:authors ("zk_phi")) (:maintainer "zk_phi") (:url . "http://zk-phi.gitub.io/"))])
+ (bibclean-format . [(20190302 2017) ((emacs (24 3)) (reformatter (0 3))) "Reformat BibTeX and Scribe using bibclean" single ((:commit . "b4003950a925d1c659bc359ab5e88e4441775d77") (:authors ("Peter W. V. Tran-Jørgensen" . "peter.w.v.jorgensen@gmail.com")) (:maintainer "Peter W. V. Tran-Jørgensen" . "peter.w.v.jorgensen@gmail.com") (:keywords "languages") (:url . "https://github.com/peterwvj/bibclean-format"))])
+ (biblio . [(20210418 406) ((emacs (24 3)) (biblio-core (0 2))) "Browse and import bibliographic references from CrossRef, arXiv, DBLP, HAL, Dissemin, and doi.org" tar ((:commit . "517ec18f00f91b61481214b178f7ae0b8fbc499b") (:authors ("Clément Pit-Claudel" . "clement.pitclaudel@live.com")) (:maintainer "Clément Pit-Claudel" . "clement.pitclaudel@live.com") (:keywords "bib" "tex" "convenience" "hypermedia") (:url . "https://github.com/cpitclaudel/biblio.el"))])
+ (biblio-bibsonomy . [(20190105 1200) ((emacs (24 4)) (biblio-core (0 2))) "Lookup bibliographic entries from Bibsonomy" single ((:commit . "778cc944db3c6dababe2e7fec5877fba42e8c00d") (:authors ("Andreas Jansson and contributors")) (:maintainer "Andreas Jansson and contributors") (:keywords "bib" "tex" "bibsonomy") (:url . "http://github.com/andreasjansson/biblio-bibsonomy/"))])
+ (biblio-core . [(20210418 406) ((emacs (24 3)) (let-alist (1 0 4)) (seq (1 11)) (dash (2 12 1))) "A framework for looking up and displaying bibliographic entries" single ((:commit . "517ec18f00f91b61481214b178f7ae0b8fbc499b") (:authors ("Clément Pit-Claudel" . "clement.pitclaudel@live.com")) (:maintainer "Clément Pit-Claudel" . "clement.pitclaudel@live.com") (:keywords "bib" "tex" "convenience" "hypermedia") (:url . "https://github.com/cpitclaudel/biblio.el"))])
+ (bibliothek . [(20190124 1828) ((emacs (24 4)) (pdf-tools (0 70)) (a (0 1 0 -3 4))) "Managing a digital library of PDFs" single ((:commit . "350af0e5d53307c900e4f8b2617f3852f51a74d2") (:authors ("Göktuğ Kayaalp" . "self@gkayaalp.com")) (:maintainer "Göktuğ Kayaalp" . "self@gkayaalp.com") (:keywords "tools") (:url . "https://dev.gkayaalp.com/elisp/index.html#bibliothek-el"))])
+ (bibretrieve . [(20191124 1855) ((auctex (11 87)) (emacs (24 3))) "Retrieve BibTeX entries from the internet" tar ((:commit . "81dc8e0db3629cc180eafb2bc34b60dcd8980316") (:authors ("Antonio Sartori")) (:maintainer "Pavel Zorin-Kranich" . "pzorin@uni-bonn.de") (:keywords "bibtex" "bibliography" "mathscinet" "arxiv" "zbmath") (:url . "https://github.com/pzorin/bibretrieve"))])
+ (bibslurp . [(20151202 2346) ((s (1 6 0)) (dash (1 5 0))) "retrieve BibTeX entries from NASA ADS" single ((:commit . "0116bbb04840d20a6b087e6d9c921bb1c2489a8f") (:keywords "bibliography" "nasa ads") (:url . "https://github.com/mkmcc/bibslurp"))])
+ (bibtex-completion . [(20220404 1608) ((parsebib (1 0)) (s (1 9 0)) (dash (2 6 0)) (f (0 16 2)) (cl-lib (0 5)) (biblio (0 2)) (emacs (26 1))) "A BibTeX backend for completion frameworks" single ((:commit . "ce8c17690ddad73d01531084b282f221f8eb6669") (:authors ("Titus von der Malsburg" . "malsburg@posteo.de") ("Justin Burkett" . "justin@burkett.cc")) (:maintainer "Titus von der Malsburg" . "malsburg@posteo.de") (:url . "https://github.com/tmalsburg/helm-bibtex"))])
+ (bibtex-utils . [(20190703 2117) nil "Provides utilities for extending BibTeX mode" single ((:commit . "26a8f0909b6adbf545a2b5e57ce7f779bf7a65af") (:authors ("Tyler Smith" . "tyler@plantarum.ca")) (:maintainer "Tyler Smith" . "tyler@plantarum.ca") (:keywords "bibtex") (:url . "https://github.com/plantarum/bibtex-utils"))])
+ (bicycle . [(20220422 1600) ((emacs (25 1)) (compat (28 1 1 0))) "Cycle outline and code visibility" single ((:commit . "aad77ba6ce64245570b4baa83b62008522c3ce3a") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:keywords "outlines") (:url . "https://github.com/tarsius/bicycle"))])
+ (bifocal . [(20200325 539) ((emacs (24 4))) "Split-screen scrolling for comint-mode buffers" single ((:commit . "de8d09b08b0b30714c4f9b98c97e9577d47b9be6") (:keywords "frames" "processes") (:url . "https://github.com/riscy/bifocal-mode"))])
+ (binclock . [(20170802 1116) ((cl-lib (0 5))) "Display the current time using a binary clock." single ((:commit . "87042230d7f3fe3e9a77fae0dbab7d8f7e7794ad") (:authors ("Dave Pearson" . "davep@davep.org")) (:maintainer "Dave Pearson" . "davep@davep.org") (:keywords "games" "time" "display") (:url . "https://github.com/davep/binclock.el"))])
+ (bind-chord . [(20171204 2010) ((bind-key (1 0)) (key-chord (0 6))) "key-chord binding helper for use-package-chords" single ((:commit . "a7422fb8ab1baee19adb2717b5b47b9c3812a84c") (:authors ("Justin Talbott" . "justin@waymondo.com")) (:maintainer "Justin Talbott" . "justin@waymondo.com") (:keywords "convenience" "tools" "extensions") (:url . "https://github.com/waymondo/use-package-chords"))])
+ (bind-key . [(20210210 1609) nil "A simple way to manage personal keybindings" single ((:commit . "a7422fb8ab1baee19adb2717b5b47b9c3812a84c") (:authors ("John Wiegley" . "johnw@newartisans.com")) (:maintainer "John Wiegley" . "johnw@newartisans.com") (:keywords "keys" "keybinding" "config" "dotemacs") (:url . "https://github.com/jwiegley/use-package"))])
+ (bind-map . [(20220108 228) ((emacs (24 3))) "Bind personal keymaps in multiple locations" single ((:commit . "510a24138d8de3b8df0783f1ac493a551fc9bd74") (:authors ("Justin Burkett" . "justin@burkett.cc")) (:maintainer "Justin Burkett" . "justin@burkett.cc") (:url . "https://github.com/justbur/emacs-bind-map"))])
+ (binder . [(20220429 2055) ((emacs (24 4)) (seq (2 20))) "Global minor mode to facilitate multi-file writing projects" tar ((:commit . "127463a7cb8cc2fa9904d3feb3fca95d2244ddcc") (:authors ("Paul W. Rankin" . "pwr@bydasein.com")) (:maintainer "Paul W. Rankin" . "pwr@bydasein.com") (:keywords "files" "outlines" "wp" "text") (:url . "https://github.com/rnkn/binder"))])
+ (bing-dict . [(20200216 110) nil "Minimalists' English-Chinese Bing dictionary" tar ((:commit . "1d581aaa9622b34f8fb83af5579fa252aa24cfef") (:authors ("Junpeng Qiu" . "qjpchmail@gmail.com")) (:maintainer "Junpeng Qiu" . "qjpchmail@gmail.com") (:keywords "extensions") (:url . "https://github.com/cute-jumper/bing-dict.el"))])
+ (birds-of-paradise-plus-theme . [(20130419 2129) nil "A brown/orange light-on-dark theme for Emacs 24 (deftheme)." single ((:commit . "bb9f9d4ef7f7872a388ec4eee1253069adcadb6f") (:authors ("Jim Myhrberg" . "contact@jimeh.me")) (:maintainer "Jim Myhrberg" . "contact@jimeh.me") (:keywords "themes") (:url . "https://github.com/jimeh/birds-of-paradise-plus-theme.el"))])
+ (bison-mode . [(20210527 717) nil "Major mode for editing bison, yacc and lex files." single ((:commit . "4f2e20394a475931409618c1635e9c9f1cf07d9c") (:authors ("Eric Beuscher" . "beuscher@eecs.tulane.edu")) (:maintainer "Eric Beuscher" . "beuscher@eecs.tulane.edu") (:keywords "bison-mode" "yacc-mode"))])
+ (bitbake . [(20190107 1155) ((emacs (24 1)) (dash (2 6 0)) (mmm-mode (0 5 4)) (s (1 10 0))) "Running bitbake from emacs" single ((:commit . "ba58bd051457ba0abd2fbc955ea0e75e78ff2c64") (:authors ("Damien Merenne")) (:maintainer "Damien Merenne") (:keywords "convenience") (:url . "https://github.com/canatella/bitbake-el"))])
+ (bitbucket . [(20170405 446) ((emacs (24)) (request (0 1 0)) (s (1 9 0))) "Bitbucket API wrapper" tar ((:commit . "5e663da1bd38a14c1ecf4d66a79d4321ac833bcf") (:authors ("2017 Tjaart van der Walt" . "tjaart@tjaart.co.za")) (:maintainer "2017 Tjaart van der Walt" . "tjaart@tjaart.co.za") (:keywords "bitbucket") (:url . "http://github.com/tjaartvdwalt/bitbucket.el/"))])
+ (bitlbee . [(20151203 0) nil "Help get Bitlbee (http://www.bitlbee.org) up and running." single ((:commit . "3a92a4119e0c007df2c7dcf1b1c3a5f23ee40e05"))])
+ (blackboard-bold-mode . [(20160813 206) ((cl-lib (0 5))) "Easily insert Unicode mathematical double-struck characters" single ((:commit . "5299cb064ba71baa3e331b8560bf8dd38cbbc4ed") (:authors ("Grant Rettke" . "gcr@wisdomandwonder.com")) (:maintainer nil . "<gcr@wisdomandwonder.com>") (:keywords "unicode" "double struck" "blackboard bold" "math" "mathematical") (:url . "https://github.com/grettke/blackboard-bold-mode"))])
+ (blackboard-theme . [(20161216 656) ((emacs (24))) "TextMate Blackboard Theme" single ((:commit . "7a0d79410feb728ff5cce75c140fadc19a3f9a6d") (:authors ("Dong Zheng")) (:maintainer "Dong Zheng") (:url . "https://github.com/don9z/blackboard-theme"))])
+ (blacken . [(20220110 1841) ((emacs (25 2))) "Reformat python buffers using the \"black\" formatter" single ((:commit . "563c744f545552cb92e8e84d5be4e2cdbabc93ca") (:authors ("Artem Malyshev" . "proofit404@gmail.com")) (:maintainer "Artem Malyshev" . "proofit404@gmail.com") (:url . "https://github.com/proofit404/blacken"))])
+ (blackout . [(20200404 1550) ((emacs (26))) "Better mode lighter overriding" single ((:commit . "c221fa2c8a204b4aff2e09c606f59be58b960b97") (:authors ("Radon Rosborough" . "radon.neon@gmail.com")) (:maintainer "Radon Rosborough" . "radon.neon@gmail.com") (:keywords "extensions") (:url . "https://github.com/raxod502/blackout"))])
+ (blamer . [(20220404 1917) ((emacs (27 1))) "Show git blame info about current line" single ((:commit . "f5c0b5ef2ae46062ba13dd03215cdfc49d0fd30b") (:authors ("Artur Yaroshenko" . "artawower@protonmail.com")) (:maintainer "Artur Yaroshenko" . "artawower@protonmail.com") (:url . "https://github.com/artawower/blamer.el"))])
+ (blgrep . [(20150401 1416) ((clmemo (20140321 715))) "Block grep" tar ((:commit . "605beda210610a5829750a987f5fcebea97af546") (:authors ("Masayuki Ataka" . "masayuki.ataka@gmail.com")) (:maintainer "Masayuki Ataka" . "masayuki.ataka@gmail.com") (:keywords "tools" "convenience"))])
+ (blimp . [(20180903 2240) ((emacs (25)) (eimp (1 4 0))) "Bustling Image Manipulation Package" single ((:commit . "39562f02acc1113595cb253a85bb3b9da743ddd2") (:authors ("Sebastian Wålinder" . "s.walinder@gmail.com")) (:maintainer "Sebastian Wålinder" . "s.walinder@gmail.com") (:keywords "multimedia" "unix") (:url . "https://github.com/walseb/blimp"))])
+ (bliss-theme . [(20170808 1307) ((emacs (24 0))) "an Emacs 24 theme based on Bliss (tmTheme)" single ((:commit . "c3cf6d8a666ab26909b7da158f9e94df71a5fbbf") (:authors ("Jason Milkins")) (:maintainer "Jason Milkins") (:url . "https://github.com/emacsfodder/tmtheme-to-deftheme"))])
+ (blitzmax-mode . [(20211128 2028) ((emacs (24 1))) "A major mode for editing BlitzMax source code" single ((:commit . "c9651fa69116b5821cd34fb34eabc3e12ce238e2") (:authors ("Phil Newton")) (:maintainer "Phil Newton") (:keywords "languages" "blitzmax") (:url . "https://www.sodaware.net/dev/tools/blitzmax-mode/"))])
+ (bln-mode . [(20181121 918) nil "binary line navigation minor mode for cursor movement in long lines" single ((:commit . "a601b0bf975dd1432f6552ab6afe3f4f71133b4a") (:authors ("Maarten Grachten")) (:maintainer "Maarten Grachten") (:keywords "motion" "location" "cursor" "convenience") (:url . "https://github.com/mgrachten/bln-mode"))])
+ (block-nav . [(20201005 202) ((emacs (25 1))) "Jump across indentation levels for quick navigation" single ((:commit . "d69acaa3d6c75bf4c518d8ab8896ad63580253fc") (:maintainer "Philip Dumaresq" . "phdumaresq@protonmail.com") (:keywords "convenience") (:url . "https://github.com/nixin72/block-nav.el"))])
+ (blockdiag-mode . [(20160427 524) ((emacs (24 3))) "Major mode for editing blockdiag files" single ((:commit . "f3b21ba433d60327cebd103ae4492200750e24a9") (:authors ("xcezx" . "main.xcezx@gmail.com")) (:maintainer "xcezx" . "main.xcezx@gmail.com") (:url . "https://github.com/xcezx/xdiag-mode"))])
+ (blog-admin . [(20170923 1409) ((ctable (0 1 1)) (s (1 10 0)) (f (0 17 3)) (names (20151201 0)) (cl-lib (0 5))) "Blog admin for emacs with hexo/org-page supported" tar ((:commit . "b5f2e1dad7d68ec903619f7280bb0bcb7e398a1e") (:authors (nil . "code.falling@gmail.com")) (:maintainer nil . "code.falling@gmail.com") (:keywords "tools" "blog" "org" "hexo" "org-page"))])
+ (blog-minimal . [(20181021 849) ((ht (1 5)) (simple-httpd (1 4 6)) (mustache (0 22)) (s (1 11 0)) (org (9 0 3))) "a simple static site generator based on org mode" tar ((:commit . "356c878322258159021eecdd15757e11cf02e335") (:authors ("Thank Fly" . "thiefuniverses@gmail.com")) (:maintainer "Thank Fly" . "thiefuniverses@gmail.com") (:keywords "tools") (:url . "https://github.com/thiefuniverse/blog-minimal"))])
+ (blox . [(20210225 1900) ((emacs (25 1))) "Interaction with Roblox tooling" single ((:commit . "2bf0e618451fb1da11263d8a35ffcd9210590c0a") (:authors ("Kenneth Loeffler" . "kenneth.loeffler@outlook.com")) (:maintainer "Kenneth Loeffler" . "kenneth.loeffler@outlook.com") (:keywords "roblox" "rojo" "tools") (:url . "https://github.com/kennethloeffler/blox"))])
+ (bm . [(20210421 1351) nil "Visible bookmarks in buffer." tar ((:commit . "9a31c61f44e6f1033ca43bd7f3eb33ffdb2ca595") (:authors ("Jo Odland <jo.odland(at)gmail.com>")) (:maintainer "Jo Odland <jo.odland(at)gmail.com>") (:keywords "bookmark" "highlight" "faces" "persistent") (:url . "https://github.com/joodland/bm"))])
+ (bmx-mode . [(20210319 620) ((emacs (25 1)) (cl-lib (0 5)) (company (0 9 4)) (dash (2 13 0)) (s (1 12 0))) "Batch Mode eXtras" single ((:commit . "6f008707efe0bb5646f0c1b0d6f57f0a8800e200") (:authors ("Jostein Kjønigsen" . "jostein@gmail.com")) (:maintainer "Jostein Kjønigsen" . "jostein@gmail.com") (:keywords "c" "convenience" "tools") (:url . "http://github.com/josteink/bmx-mode"))])
+ (bnf-mode . [(20200323 1348) ((cl-lib (0 5)) (emacs (24 3))) "Major mode for editing BNF grammars." tar ((:commit . "d9329dd90e5d4f629295e85898362d9682047898") (:authors ("Serghei Iakovlev" . "egrep@protonmail.ch")) (:maintainer "Serghei Iakovlev" . "egrep@protonmail.ch") (:keywords "languages") (:url . "https://github.com/sergeyklay/bnf-mode"))])
+ (bnfc . [(20160605 1927) ((emacs (24 3))) "Define context-free grammars for the BNFC tool" single ((:commit . "1b58df1dd0cb9b81900632fb2843a03b94f56fdb") (:authors ("Jacob Mitchell" . "jmitchell@member.fsf.org")) (:maintainer "Jacob Mitchell" . "jmitchell@member.fsf.org") (:keywords "languages" "tools") (:url . "https://github.com/jmitchell/bnfc-mode"))])
+ (bog . [(20201030 357) ((cl-lib (0 5))) "Extensions for research notes in Org mode" single ((:commit . "af929c164c4ffaee0c33ba97c06733f0ce9431d4") (:authors ("Kyle Meyer" . "kyle@kyleam.com")) (:maintainer "Kyle Meyer" . "kyle@kyleam.com") (:keywords "bib" "outlines") (:url . "https://github.com/kyleam/bog"))])
+ (bolt-mode . [(20180310 810) ((emacs (24 3))) "Editing support for Bolt language" single ((:commit . "85a5a752bfbebb4aed884326c25db64c000e9934") (:authors ("Mikhail Pontus" . "mpontus@gmail.com")) (:maintainer "Mikhail Pontus" . "mpontus@gmail.com") (:keywords "languages") (:url . "https://github.com/mpontus/bolt-mode"))])
+ (bongo . [(20201002 1020) ((cl-lib (0 5)) (emacs (24 1))) "play music with Emacs" tar ((:commit . "9e9629090262bba6d0003dabe5a375e47a4477f1"))])
+ (bonjourmadame . [(20170919 1134) nil "Say \"Hello ma'am!\"" single ((:commit . "d3df185fce78aefa689fded8e56a654f0fde4ac0"))])
+ (boogie-friends . [(20220419 2240) ((cl-lib (0 5)) (dash (2 10 0)) (flycheck (0 23)) (yasnippet (0 9 0 1)) (company (0 8 12))) "A collection of programming modes for Boogie, Dafny, and Z3 (SMTLIB v2)." tar ((:commit . "d685a52259f50c2db51205ef9cc93f713ae8d8fa") (:authors ("Clément Pit--Claudel" . "clement.pitclaudel@live.com")) (:maintainer "Clément Pit--Claudel" . "clement.pitclaudel@live.com") (:keywords "convenience" "languages") (:url . "https://github.com/boogie-org/boogie-friends/"))])
+ (bookmark-in-project . [(20220401 348) ((emacs (27 1))) "Bookmark access within a project" single ((:commit . "e95aa25b933e705e87b7a9328e89c8cf0898c201") (:authors ("Campbell Barton" . "ideasman42@gmail.com")) (:maintainer "Campbell Barton" . "ideasman42@gmail.com") (:keywords "convenience") (:url . "https://gitlab.com/ideasman42/emacs-bookmark-in-project"))])
+ (bookmark-view . [(20220403 2204) ((emacs (27 1))) "Bookmark views" single ((:commit . "0d40ac67f53b7fa75fe65c38a5ef65701ce4c3da") (:authors ("Daniel Mendler")) (:maintainer "Daniel Mendler") (:url . "https://github.com/minad/bookmark-view"))])
+ (bool-flip . [(20161215 1539) ((emacs (24 3))) "flip the boolean under the point" single ((:commit . "f58a9a7b9ab875bcfbd57c8262697ae404eb4485") (:authors ("Michael Brandt" . "michaelbrandt5@gmail.com")) (:maintainer "Michael Brandt" . "michaelbrandt5@gmail.com") (:keywords "boolean" "convenience" "usability") (:url . "http://github.com/michaeljb/bool-flip/"))])
+ (boon . [(20220502 1850) ((emacs (26 1)) (dash (2 12 0)) (expand-region (0 10 0)) (multiple-cursors (1 3 0))) "Ergonomic Command Mode for Emacs." tar ((:commit . "db7b6083d390e3febf82f9af5782e1a36d30093c"))])
+ (borg . [(20220503 1114) ((emacs (26)) (epkg (3 3 3)) (magit (3 3 0))) "Assimilate Emacs packages as Git submodules" tar ((:commit . "cd1fbd60a2ff62bbfca124ea1e602b14c4aa58e9") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:keywords "tools") (:url . "https://github.com/emacscollective/borg"))])
+ (borland-blue-theme . [(20160117 1321) ((emacs (24 1))) "Blue/yellow theme based on old DOS Borland/Turbo C IDE" single ((:commit . "db74eefebbc89d3c62575f8f50b319e87b4a3470") (:authors ("Alexey Veretennikov <alexey dot veretennikov at gmail dot com>")) (:maintainer "Alexey Veretennikov <alexey dot veretennikov at gmail dot com>") (:keywords "themes") (:url . "http://github.com/fourier/borland-blue-theme"))])
+ (boron-theme . [(20170808 1308) ((emacs (24 0))) "an Emacs 24 theme based on Boron (tmTheme)" single ((:commit . "87ae1a765e07429fec25d2f29b004f84b52d2e0a") (:authors ("Jason Milkins")) (:maintainer "Jason Milkins") (:url . "https://github.com/emacsfodder/tmtheme-to-deftheme"))])
+ (boxquote . [(20220105 1515) ((cl-lib (0 5))) "Quote text with a semi-box." single ((:commit . "67775ce80886b776efedceb31cdbacec1e26678e") (:authors ("Dave Pearson" . "davep@davep.org")) (:maintainer "Dave Pearson" . "davep@davep.org") (:keywords "quoting") (:url . "https://github.com/davep/boxquote.el"))])
+ (bpe . [(20141228 2205) ((emacs (24 1))) "Blog from Org mode to Blogger" single ((:commit . "7b5b25f83506e6c9f4075d3803fa32404943a189") (:authors ("Yuta Yamada <cokesboy\"at\"gmail.com>")) (:maintainer "Yuta Yamada <cokesboy\"at\"gmail.com>") (:keywords "blogger" "blog") (:url . "https://github.com/yuutayamada/bpe"))])
+ (bpftrace-mode . [(20190608 2201) ((emacs (24 0))) "Major mode for editing bpftrace script files" single ((:commit . "181065e1f9ab4ec7096bafffe6818b0d7f5362b1") (:authors ("Jay Kamat" . "jaygkamat@gmail.com")) (:maintainer "Jay Kamat" . "jaygkamat@gmail.com") (:keywords "highlight" "c") (:url . "http://gitlab.com/jgkamat/bpftrace-mode"))])
+ (bpr . [(20180220 1844) ((emacs (24))) "Background Process Runner" tar ((:commit . "7f3c787ed80ac0e83447192ac5450dfa7110ade1") (:authors ("Ilya Babanov" . "ilya-babanov@ya.ru")) (:maintainer "Ilya Babanov" . "ilya-babanov@ya.ru") (:keywords "background" "async" "process" "management") (:url . "https://github.com/ilya-babanov/emacs-bpr"))])
+ (bracketed-paste . [(20160407 2348) ((emacs (24 3))) "bracketed paste mode support within emacs -nw" single ((:commit . "843ce3bbb63d560face889e13a57a2f7543957d5") (:authors ("Takeshi Banse" . "takebi@laafc.net")) (:maintainer "Takeshi Banse" . "takebi@laafc.net") (:keywords "terminals"))])
+ (brainfuck-mode . [(20150113 842) ((langdoc (20130601 1450))) "Brainfuck mode for Emacs" single ((:commit . "36e69552bb3b97a4f888d362c59845651bd0d492") (:authors ("Tomoya Tanjo" . "ttanjo@gmail.com")) (:maintainer "Tomoya Tanjo" . "ttanjo@gmail.com") (:keywords "brainfuck" "langdoc") (:url . "https://github.com/tom-tan/brainfuck-mode/"))])
+ (brazilian-holidays . [(20210302 107) ((emacs (26))) "Brazilian holidays" single ((:commit . "68811fd5f3e9d9c0572995c3ca46ead2c35eb421") (:authors ("Jaguaraquem A. Reinaldo" . "jaguar.adler@gmail.com")) (:maintainer "Jaguaraquem A. Reinaldo" . "jaguar.adler@gmail.com") (:keywords "calendar" "holidays" "brazilian") (:url . "https://github.com/jadler/brazilian-holidays"))])
+ (brf . [(20220104 2222) ((fringe-helper (0 1 1)) (emacs (24 3))) "Brf-mode provides features from the legendary editor Brief" tar ((:commit . "59ec15094917666f253eaf61d17664525a7971f4") (:authors ("Mike Woolley" . "mike@bulsara.com")) (:maintainer "Mike Woolley" . "mike@bulsara.com") (:keywords "brief" "crisp" "emulations") (:url . "https://bitbucket.org/MikeWoolley/brf-mode"))])
+ (brightscript-mode . [(20200321 2126) ((emacs (26 3))) "Major mode for editing Brightscript files" single ((:commit . "71c555c2e254629c365e6fc44c2fc4d5b6d0ae8b") (:authors ("Daniel Mircea" . "daniel@viseztrance.com")) (:maintainer nil . "daniel@viseztrance.com") (:keywords "languages") (:url . "https://github.com/viseztrance/brightscript-mode"))])
+ (broadcast . [(20151205 212) ((emacs (24 4))) "Links buffers together for simultaneous editing." single ((:commit . "f6f9cd2e0e3f8c31d6b8e7446c27eb0e50b25f16") (:authors ("Russell Black" . "killdash9@github")) (:maintainer "Russell Black" . "killdash9@github") (:keywords "convenience" "frames" "link" "cursors") (:url . "https://github.com/killdash9/broadcast.el"))])
+ (browse-at-remote . [(20210603 802) ((f (0 17 2)) (s (1 9 0)) (cl-lib (0 5))) "Open github/gitlab/bitbucket/stash/gist/phab/sourcehut page from Emacs" single ((:commit . "cef26f2c063f2473af42d0e126c8613fe2f709e4") (:authors ("Rustem Muslimov" . "r.muslimov@gmail.com")) (:maintainer "Rustem Muslimov" . "r.muslimov@gmail.com") (:keywords "github" "gitlab" "bitbucket" "gist" "stash" "phabricator" "sourcehut" "pagure") (:url . "https://github.com/rmuslimov/browse-at-remote"))])
+ (browse-kill-ring . [(20220410 1509) nil "interactively insert items from kill-ring" single ((:commit . "6e06736a8245a8cdf436f6585c71439239219836") (:authors ("Colin Walters" . "walters@verbum.org")) (:maintainer "browse-kill-ring" . "browse-kill-ring@tonotdo.com") (:keywords "convenience") (:url . "https://github.com/browse-kill-ring/browse-kill-ring"))])
+ (browse-url-dwim . [(20140731 1922) ((string-utils (0 3 2))) "Context-sensitive external browse URL or Internet search" single ((:commit . "3d611dbb167c286109ac53995ad68286d87aafb9") (:authors ("Roland Walker" . "walker@pobox.com")) (:maintainer "Roland Walker" . "walker@pobox.com") (:keywords "hypermedia") (:url . "http://github.com/rolandwalker/browse-url-dwim"))])
+ (brutalist-theme . [(20181023 1222) nil "Brutalist theme" tar ((:commit . "72adc339c433a98e944cbe76da4c45b9ba4400f5") (:authors ("Gergely Nagy")) (:maintainer "Gergely Nagy") (:url . "https://git.madhouse-project.org/algernon/brutalist-theme.el"))])
+ (bshell . [(20201219 139) ((emacs (26)) (buffer-manage (0 11))) "Manage and track multiple inferior shells" single ((:commit . "469c841f19f28c271b4f172b40f3f9ca830254df") (:authors ("Paul Landes")) (:maintainer "Paul Landes") (:keywords "unix" "interactive" "shell" "management") (:url . "https://github.com/plandes/bshell"))])
+ (btc-ticker . [(20220409 1647) ((json (1 2)) (request (0 2 0))) "Shows latest bitcoin price" single ((:commit . "2ed18ac6338d5fe98c578f0875840af07f0bc42a") (:authors ("Jorge Niedbalski R." . "jnr@metaklass.org")) (:maintainer "Jorge Niedbalski R." . "jnr@metaklass.org") (:keywords "news"))])
+ (bts . [(20151109 1333) ((widget-mvc (0 0 2)) (log4e (0 3 0)) (yaxception (0 3 3)) (dash (2 9 0)) (s (1 9 0)) (pos-tip (0 4 5))) "A unified UI for various bug tracking systems" single ((:commit . "df42d58a36447697f93b56e69f5e700b2baef1f9") (:authors ("Hiroaki Otsu" . "ootsuhiroaki@gmail.com")) (:maintainer "Hiroaki Otsu" . "ootsuhiroaki@gmail.com") (:keywords "convenience") (:url . "https://github.com/aki2o/emacs-bts"))])
+ (bts-github . [(20170401 1249) ((bts (0 0 1)) (gh (0 8 2))) "A plugin of bts.el for GitHub" single ((:commit . "ef2cf9202dc2128e5efdb613bfde9276a8cd95ad") (:authors ("Hiroaki Otsu" . "ootsuhiroaki@gmail.com")) (:maintainer "Hiroaki Otsu" . "ootsuhiroaki@gmail.com") (:keywords "convenience" "git" "github") (:url . "https://github.com/aki2o/emacs-bts-github"))])
+ (bubbleberry-theme . [(20141017 944) ((emacs (24 1))) "A theme based on LightTable for Emacs24" single ((:commit . "22e9adf4586414024e4592972022ec297321b320") (:authors ("Jason Milkins" . "jasonm23@gmail.com") ("Gaurav Giri github.com/grvgr")) (:maintainer "Jason Milkins" . "jasonm23@gmail.com") (:url . "https://github.com/jasonm23/emacs-bubbleberry-theme"))])
+ (buckwalter . [(20191119 1950) nil "Write arabic using Buckwalter transliteration" single ((:commit . "b8c0c2170c7113b515477b1bb39c58d22aad67e1") (:authors ("Joe HAKIM RAHME" . "joehakimrahme@gmail.com")) (:maintainer "Joe HAKIM RAHME" . "joehakimrahme@gmail.com") (:keywords "arabic" "transliteration" "i18n") (:url . "https://github.com/joehakimrahme/buckwalter-arabic"))])
+ (buffer-buttons . [(20150106 1439) nil "Define, save, and load code-safe buttons in files for emacs" single ((:commit . "2feb8494fa7863b98256bc85da670d74a3a8a975") (:authors ("Ryan Pavlik" . "rpavlik@gmail.com")) (:maintainer "Ryan Pavlik" . "rpavlik@gmail.com") (:url . "https://github.com/rpav/buffer-buttons"))])
+ (buffer-env . [(20220504 1643) ((emacs (27 1))) "Buffer-local process environments" single ((:commit . "f213017cc64017a3ed4197a6528272679c0c0612") (:authors ("Augusto Stoffel" . "arstoffel@gmail.com")) (:maintainer "Augusto Stoffel" . "arstoffel@gmail.com") (:keywords "processes" "tools") (:url . "https://github.com/astoff/buffer-env"))])
+ (buffer-flip . [(20180307 2251) nil "Cycle through buffers like Alt-Tab in Windows" single ((:commit . "b8ecbf0251a59c351a3e44607ee502af343da64b") (:authors ("Russell Black" . "killdash9@github")) (:maintainer "Russell Black" . "killdash9@github") (:keywords "convenience") (:url . "https://github.com/killdash9/buffer-flip.el"))])
+ (buffer-manage . [(20211122 1957) ((emacs (26 1)) (choice-program (0 13)) (dash (2 17 0))) "Manage buffers" tar ((:commit . "819bbfd9ae2f028361f484bc3b60d751623a2df5") (:authors ("Paul Landes")) (:maintainer "Paul Landes") (:keywords "internal" "maint") (:url . "https://github.com/plandes/buffer-manage"))])
+ (buffer-move . [(20160615 1803) nil "easily swap buffers" single ((:commit . "cb517ecf8409b5fdcda472d7190c6021f0c49751") (:keywords "lisp" "convenience") (:url . "https://github.com/lukhas/buffer-move"))])
+ (buffer-ring . [(20220120 124) ((emacs (25 1)) (dynaring (0 3)) (s (1 12 0)) (ht (2 0))) "Rings and tori for buffer navigation" single ((:commit . "177d67238c4d126a0270585e21c0f03ae750ca2a") (:authors ("Mike Mattie" . "codermattie@gmail.com") ("Sid Kasivajhula" . "sid@countvajhula.com")) (:maintainer "Sid Kasivajhula" . "sid@countvajhula.com") (:url . "https://github.com/countvajhula/buffer-ring"))])
+ (buffer-sets . [(20170718 340) ((cl-lib (0 5))) "Sets of Buffers for Buffer Management" single ((:commit . "bc84c2f79a33609cccf3c996101125859b2e26ab") (:authors ("Samuel W. Flint" . "swflint@flintfam.org")) (:maintainer "Samuel W. Flint" . "swflint@flintfam.org") (:keywords "buffer-management") (:url . "http://github.com/swflint/buffer-sets"))])
+ (buffer-utils . [(20140512 1400) nil "Buffer-manipulation utility functions" single ((:commit . "685b13457e3a2085b7584e41365d2aa0779a1b6f") (:authors ("Roland Walker" . "walker@pobox.com")) (:maintainer "Roland Walker" . "walker@pobox.com") (:keywords "extensions") (:url . "http://github.com/rolandwalker/buffer-utils"))])
+ (buffer-watcher . [(20170913 839) ((f (0 16 2)) (cl-lib (0 5))) "Easily run shell scripts per filetype/directory when a buffer is saved" single ((:commit . "b32c67c8a5d724257d759f4c903d0dedc32246ef") (:authors ("Nicolas Petton" . "nicolas@petton.fr")) (:maintainer "Nicolas Petton" . "nicolas@petton.fr"))])
+ (buffer-wrap . [(20200924 345) ((emacs (24 4))) "Wrap the beginning and the end of buffer" single ((:commit . "b918ba023212b0e223a7ca7df3a2ec12a7c54206") (:authors ("Shen, Jen-Chieh" . "jcs090218@gmail.com")) (:maintainer "Shen, Jen-Chieh" . "jcs090218@gmail.com") (:url . "https://github.com/jcs-elpa/buffer-wrap"))])
+ (bufler . [(20210907 1145) ((emacs (26 3)) (dash (2 18)) (f (0 17)) (pretty-hydra (0 2 2)) (magit-section (0 1)) (map (2 1))) "Group buffers into workspaces with programmable rules" tar ((:commit . "a68e0eb2719c67ab8a3ad56c4036364061d06004") (:authors ("Adam Porter" . "adam@alphapapa.net")) (:maintainer "Adam Porter" . "adam@alphapapa.net") (:keywords "convenience") (:url . "https://github.com/alphapapa/bufler.el"))])
+ (bufshow . [(20130726 1838) ((emacs (24 1))) "A simple presentation tool for Emacs." single ((:commit . "d60a554e7239e6f7520d9c3436d5ecdbc9cf6957") (:authors ("Peter Jones" . "pjones@pmade.com")) (:maintainer "Peter Jones" . "pjones@pmade.com") (:url . "https://github.com/pjones/bufshow"))])
+ (bug-reference-github . [(20200206 2158) nil "Set `bug-reference-url-format' in Github repos" tar ((:commit . "c9512a010f19633e69f1d4b1597eff7048b21112") (:authors ("Arne Jørgensen" . "arne@arnested.dk")) (:maintainer "Arne Jørgensen" . "arne@arnested.dk") (:keywords "programming" "tools") (:url . "https://github.com/arnested/bug-reference-github"))])
+ (bui . [(20210108 1141) ((emacs (24 3)) (dash (2 11 0))) "Buffer interface library" tar ((:commit . "f3a137628e112a91910fd33c0cff0948fa58d470") (:authors ("Alex Kost" . "alezost@gmail.com")) (:maintainer "Alex Kost" . "alezost@gmail.com") (:keywords "tools") (:url . "https://github.com/alezost/bui.el"))])
+ (build-farm . [(20181218 2002) ((emacs (24 4)) (bui (1 2 1)) (magit-popup (2 1 0))) "Interface for Nix and Guix build farms (Hydra and Cuirass)" tar ((:commit . "5c268a3c235ace0d79ef1ec82c440120317e06f5") (:authors ("Alex Kost" . "alezost@gmail.com")) (:maintainer "Alex Kost" . "alezost@gmail.com") (:keywords "tools") (:url . "https://gitlab.com/alezost-emacs/build-farm"))])
+ (build-helper . [(20161009 1755) ((projectile (0 9 0))) "Utilities to help build code" single ((:commit . "7a6fe71125a26ed1c492dab77cc688a7fe1d68ac") (:authors ("Afonso Bordado" . "afonsobordado@az8.co")) (:maintainer "Afonso Bordado" . "afonsobordado@az8.co") (:keywords "convenience") (:url . "http://github.com/afonso360/build-helper"))])
+ (build-status . [(20190807 1231) ((cl-lib (0 5))) "Mode line build status indicator" single ((:commit . "1a1d2473aa62f2fdda47d8bfeb9fe352d2579b48") (:authors ("Skye Shaw" . "skye.shaw@gmail.com")) (:maintainer "Skye Shaw" . "skye.shaw@gmail.com") (:keywords "mode-line" "ci" "circleci" "travis-ci") (:url . "http://github.com/sshaw/build-status"))])
+ (bundler . [(20200129 1338) ((inf-ruby (2 1)) (cl-lib (0 5))) "Interact with Bundler from Emacs" single ((:commit . "43efb6be4ed118b06d787ce7fbcffd68a31732a7") (:authors ("Tobias Svensson" . "tob@tobiassvensson.co.uk")) (:maintainer "Tobias Svensson" . "tob@tobiassvensson.co.uk") (:keywords "bundler" "ruby") (:url . "http://github.com/endofunky/bundler.el"))])
+ (burly . [(20220413 1529) ((emacs (26 3)) (map (2 1))) "Save and restore frame/window configurations with buffers" tar ((:commit . "96f59fe24fdce14d14f204372f99bf522ab192bf") (:authors ("Adam Porter" . "adam@alphapapa.net")) (:maintainer "Adam Porter" . "adam@alphapapa.net") (:keywords "convenience") (:url . "https://github.com/alphapapa/burly.el"))])
+ (burnt-toast . [(20201113 814) ((emacs (25 1)) (dash (2 10)) (alert (1 2))) "Elisp integration with the BurntToast PowerShell module" tar ((:commit . "eed66036d65b0ee26ce02371d14dce16a360acb4") (:authors ("Sam Cedarbaum" . "scedarbaum@gmail.com")) (:maintainer "Sam Cedarbaum" . "scedarbaum@gmail.com") (:keywords "alert" "notifications" "powershell" "comm") (:url . "https://github.com/cedarbaum/burnt-toast.el"))])
+ (bury-successful-compilation . [(20181106 403) nil "Bury the *compilation* buffer after successful compilation" single ((:commit . "674644c844184605a1bb4f9487a60f7a780a6fe7") (:authors ("Eric Crosson" . "esc@ericcrosson.com")) (:maintainer "Eric Crosson" . "esc@ericcrosson.com") (:keywords "compilation"))])
+ (buster-mode . [(20140928 1213) nil "Minor mode to speed up development when writing tests with Buster.js" single ((:commit . "de6958ef8369400922618b8d1e99abfa91b97ac5") (:keywords "buster" "testing" "javascript"))])
+ (buster-snippets . [(20151125 1010) ((yasnippet (0 8 0))) "Yasnippets for the Buster javascript testing framework" tar ((:commit . "bb8769dae132659858e74d52f3f4e8790399423a") (:authors ("Magnar Sveen" . "magnars@gmail.com")) (:maintainer "Magnar Sveen" . "magnars@gmail.com") (:keywords "snippets"))])
+ (busybee-theme . [(20170719 928) nil "port of vim's mustang theme" single ((:commit . "66b2315b030582d0ebee605cf455d386d8c30fcd") (:authors ("martin haesler")) (:maintainer "martin haesler") (:url . "http://github.com/mswift42/busybee-theme"))])
+ (butler . [(20210928 230) ((deferred (0 3 2)) (json (1 2)) (emacs (24))) "Emacs client for Jenkins" tar ((:commit . "10943ccdf2030187b2f7bd97337d78acb7fd31c9") (:authors ("Ashton Kemerling" . "ashtonkemerling@gmail.com")) (:maintainer "Ashton Kemerling" . "ashtonkemerling@gmail.com") (:keywords "jenkins" "hudson" "ci") (:url . "http://www.github.com/AshtonKem/Butler.git"))])
+ (buttercup . [(20220410 1557) ((emacs (24 3))) "Behavior-Driven Emacs Lisp Testing" tar ((:commit . "ceedad5efa797e860dbb356bc2c3028a4e0321ec") (:authors ("Jorgen Schaefer" . "contact@jorgenschaefer.de")) (:maintainer "Ola Nilsson" . "ola.nilsson@gmail.com") (:url . "https://github.com/jorgenschaefer/emacs-buttercup"))])
+ (buttercup-junit . [(20190802 2258) ((emacs (24 3)) (buttercup (1 15))) "JUnit reporting for Buttercup" single ((:commit . "3ae4f84813c9e04e03a6e703990ca998b62b6deb") (:authors ("Ola Nilsson" . "ola.nilsson@gmail.com")) (:maintainer "Ola Nilsson" . "ola.nilsson@gmail.com") (:keywords "tools" "test" "unittest" "buttercup" "ci") (:url . "https://bitbucket.org/olanilsson/buttercup-junit"))])
+ (button-lock . [(20200309 1323) nil "Clickable text defined by regular expression" single ((:commit . "9afe0f4d05910b0cccc94cb6d4d880119f3b0528") (:authors ("Roland Walker" . "walker@pobox.com")) (:maintainer "Roland Walker" . "walker@pobox.com") (:keywords "mouse" "button" "hypermedia" "extensions") (:url . "http://github.com/rolandwalker/button-lock"))])
+ (buttons . [(20201123 2333) ((cl-lib (0 3))) "Define and visualize hierarchies of keymaps" single ((:commit . "de41b48244574a13000c4289fdb4216a2b0490ff") (:authors ("Ernesto Alfonso")) (:maintainer nil . "(concat \"erjoalgo\" \"@\" \"gmail\" \".com\")") (:keywords "keymap" "template" "snippet") (:url . "http://github.com/erjoalgo/emacs-buttons"))])
+ (c-c-combo . [(20151224 255) nil "Make stuff happen when you reach a target wpm" tar ((:commit . "a261a833499a7fdc29610863b3aafc74818770ba") (:authors ("Diego Berrocal" . "cestdiego@gmail.com")) (:maintainer "Diego Berrocal" . "cestdiego@gmail.com") (:url . "https://www.github.com/CestDiego/c-c-combo.el"))])
+ (c-eldoc . [(20201004 2347) nil "helpful description of the arguments to C functions" single ((:commit . "f4ede1f37f6de583376669735326367d84a0a917") (:authors ("Nathaniel Flath" . "flat0103@gmail.com")) (:maintainer "Nathaniel Flath" . "flat0103@gmail.com") (:url . "http://github.com/nflath/c-eldoc"))])
+ (c-eval . [(20210611 705) ((emacs (24 5))) "Compile and run one-off C code snippets" single ((:commit . "fd129bfcb75475ac6820cc33862bd8efb8097fae") (:authors ("Lassi Kortela" . "lassi@lassi.io")) (:maintainer "Lassi Kortela" . "lassi@lassi.io") (:keywords "c" "languages") (:url . "https://github.com/lassik/emacs-c-eval"))])
+ (c0-mode . [(20151110 1852) nil "Major mode for editing C0 files" tar ((:commit . "c214093c36864d6208fcb9e6a72413ed17ed5d60") (:authors ("Jakob Max Uecker")) (:maintainer "Jakob Max Uecker") (:keywords "c0" "languages") (:url . "http://c0.typesafety.net/"))])
+ (ca65-mode . [(20210218 106) ((emacs (26 1))) "Major mode for ca65 assembly files" single ((:commit . "590d90cc0e1c1864dd7ce03df99b741ba866d52a") (:authors ("Wendel Scardua" . "wendel@scardua.net")) (:maintainer "Wendel Scardua" . "wendel@scardua.net") (:keywords "languages" "assembly" "ca65" "6502") (:url . "https://github.com/wendelscardua/ca65-mode"))])
+ (cabledolphin . [(20160204 938) ((emacs (24 4)) (seq (1 0))) "capture Emacs network traffic" single ((:commit . "fffc192cafa61558e924323d6da8166fe5f2a6f9") (:authors ("Magnus Henoch" . "magnus.henoch@gmail.com")) (:maintainer "Magnus Henoch" . "magnus.henoch@gmail.com") (:keywords "comm"))])
+ (cache . [(20111019 2300) nil "implementation of a hash table whose key-value pairs expire" single ((:commit . "7499586b6c8224df9f5c5bc4dec96b008258d580") (:authors ("Nathaniel Flath")) (:maintainer "Nathaniel Flath"))])
+ (cacoo . [(20120319 2359) ((concurrent (0 3 1))) "Minor mode for Cacoo : http://cacoo.com" tar ((:commit . "c9fa04fbe97639b24698709530361c2bb5f3273c") (:authors ("SAKURAI Masashi <m.sakurai atmark kiwanami.net>")) (:maintainer "SAKURAI Masashi <m.sakurai atmark kiwanami.net>") (:keywords "convenience" "diagram") (:url . "https://github.com/kiwanami/emacs-cacoo/"))])
+ (caddyfile-mode . [(20181204 858) ((emacs (25)) (loop (1 3))) "Major mode for Caddy configuration files" single ((:commit . "976ad0664c3f44bfa11cb9b8787ddfb094d0a666") (:authors ("Thomas Jost" . "schnouki@schnouki.net")) (:maintainer "Thomas Jost" . "schnouki@schnouki.net") (:keywords "languages") (:url . "https://github.com/Schnouki/caddyfile-mode/"))])
+ (cake-inflector . [(20140415 858) ((s (1 9 0))) "Lazy porting CakePHP infrector.php to el" single ((:commit . "a1d338ec4840b1b1bc14f7f9298c07e2c1d2d8fc") (:authors ("k1LoW (Kenichirou Oyama), <k1lowxb [at] gmail [dot] com> <k1low [at] 101000lab [dot] org>")) (:maintainer "k1LoW (Kenichirou Oyama), <k1lowxb [at] gmail [dot] com> <k1low [at] 101000lab [dot] org>") (:url . "https://github.com/k1LoW/emacs-cake-inflector"))])
+ (cakecrumbs . [(20180929 139) ((emacs (24 4))) "Show parents on header for HTML/Jade/Sass/Stylus" single ((:commit . "cf8c1df885eee004602f73c4f841301e200e5850") (:authors ("ono hiroko <kuanyui.github.io>")) (:maintainer "ono hiroko <kuanyui.github.io>") (:keywords "languages" "html" "jade" "pug" "sass" "scss" "stylus") (:url . "https://github.com/kuanyui/cakecrumbs.el"))])
+ (cal-china-x . [(20200924 1837) ((cl-lib (0 5))) "Chinese localization, lunar/horoscope/zodiac info and more..." tar ((:commit . "94005e678a1d2522b7a00299779f40c5c77286b8") (:authors ("William Xu" . "william.xwl@gmail.com")) (:maintainer "William Xu" . "william.xwl@gmail.com") (:url . "https://github.com/xwl/cal-china-x"))])
+ (calc-at-point . [(20210219 1252) ((emacs (26)) (dash (2 18 0))) "Perform calculations at point or over selection" single ((:commit . "0c1a9e94b519b0edb0abcbacdf6101eea2f2a524") (:authors ("Sebastian Wålinder" . "s.walinder@gmail.com")) (:maintainer "Sebastian Wålinder" . "s.walinder@gmail.com") (:keywords "convenience") (:url . "https://github.com/walseb/calc-at-point"))])
+ (calendar-norway . [(20220211 1129) nil "Norwegian calendar" single ((:commit . "0db0ea63365f4ff5f7d18fb8335fa88af194a2cc") (:authors ("Kevin Brubeck Unhammer" . "unhammer@fsfe.org")) (:maintainer "Kevin Brubeck Unhammer" . "unhammer@fsfe.org") (:keywords "calendar" "norwegian" "localization"))])
+ (calfw . [(20180118 45) nil "Calendar view framework on Emacs" single ((:commit . "03abce97620a4a7f7ec5f911e669da9031ab9088") (:authors ("SAKURAI Masashi <m.sakurai at kiwanami.net>")) (:maintainer "SAKURAI Masashi <m.sakurai at kiwanami.net>") (:keywords "calendar") (:url . "https://github.com/kiwanami/emacs-calfw"))])
+ (calfw-cal . [(20170320 1206) nil "calendar view for emacs diary" single ((:commit . "03abce97620a4a7f7ec5f911e669da9031ab9088") (:authors ("SAKURAI Masashi <m.sakurai at kiwanami.net>")) (:maintainer "SAKURAI Masashi <m.sakurai at kiwanami.net>") (:keywords "calendar"))])
+ (calfw-gcal . [(20120111 1000) nil "edit Google calendar for calfw.el." tar ((:commit . "14aab20687d6cc9e6c5ddb9e11984c4e14c3d870") (:authors ("myuhe <yuhei.maeda_at_gmail.com>")) (:maintainer "myuhe") (:keywords "convenience" "calendar" "calfw.el") (:url . "https://github.com/myuhe/calfw-gcal.el"))])
+ (calfw-howm . [(20170704 4) nil "calendar view for howm" single ((:commit . "03abce97620a4a7f7ec5f911e669da9031ab9088") (:authors ("SAKURAI Masashi <m.sakurai at kiwanami.net>")) (:maintainer "SAKURAI Masashi <m.sakurai at kiwanami.net>") (:keywords "calendar"))])
+ (calfw-ical . [(20150703 819) nil "calendar view for ical format" single ((:commit . "03abce97620a4a7f7ec5f911e669da9031ab9088") (:authors ("SAKURAI Masashi <m.sakurai at kiwanami.net>")) (:maintainer "SAKURAI Masashi <m.sakurai at kiwanami.net>") (:keywords "calendar"))])
+ (calfw-org . [(20160303 258) nil "calendar view for org-agenda" single ((:commit . "03abce97620a4a7f7ec5f911e669da9031ab9088") (:authors ("SAKURAI Masashi <m.sakurai at kiwanami.net>")) (:maintainer "SAKURAI Masashi <m.sakurai at kiwanami.net>") (:keywords "calendar" "org"))])
+ (calibredb . [(20220504 516) ((emacs (25 1)) (org (9 3)) (transient (0 1 0)) (s (1 12 0)) (dash (2 17 0)) (request (0 3 3)) (esxml (0 3 7))) "Yet another calibre client" tar ((:commit . "a59e8ab65601e30073fa55bef76e95c964c678d8") (:authors ("Damon Chan" . "elecming@gmail.com")) (:maintainer "Damon Chan" . "elecming@gmail.com") (:keywords "tools") (:url . "https://github.com/chenyanming/calibredb.el"))])
+ (call-graph . [(20220427 2358) ((emacs (25 1)) (hierarchy (0 7 0)) (tree-mode (1 0 0)) (ivy (0 10 0))) "Generate call graph for c/c++ functions" tar ((:commit . "e4726952fced9439c3b1abc2c3fb261c47e034cc") (:authors ("Huming Chen" . "chenhuming@gmail.com")) (:maintainer "Huming Chen" . "chenhuming@gmail.com") (:keywords "programming" "convenience") (:url . "https://github.com/beacoder/call-graph"))])
+ (calmer-forest-theme . [(20130926 510) nil "Darkish theme with green/orange tint" single ((:commit . "87ba7bae389084d13fe3bc34e0c923017eda6ba0") (:authors ("Artur Hefczyc, created 2003-04-18") ("David Caldwell" . "david@porkrind.org")) (:maintainer "Artur Hefczyc, created 2003-04-18") (:url . "https://github.com/caldwell/calmer-forest-theme"))])
+ (camcorder . [(20190317 2138) ((emacs (24)) (names (20150000)) (cl-lib (0 5))) "Record screencasts in gif or other formats." single ((:commit . "b11ca61491a27681bb3131b72b51c105fd996bed") (:authors ("Artur Malabarba" . "bruce.connor.am@gmail.com")) (:maintainer "Artur Malabarba" . "bruce.connor.am@gmail.com") (:keywords "multimedia" "screencast") (:url . "http://github.com/Bruce-Connor/camcorder.el"))])
+ (caml . [(20220503 1742) ((emacs (24 3))) "Caml mode for GNU Emacs" tar ((:commit . "f2f170f46b758341d96385986e8a93b9b4d248f1") (:authors ("Jacques Garrigue" . "garrigue@kurims.kyoto-u.ac.jp") ("Ian T Zimmerman" . "itz@rahul.net") ("Damien Doligez" . "damien.doligez@inria.fr")) (:maintainer "Christophe Troestler" . "Christophe.Troestler@umons.ac.be") (:keywords "ocaml") (:url . "https://github.com/ocaml/caml-mode"))])
+ (cangjie . [(20211201 2307) ((emacs (24 4)) (s (1 12 0)) (dash (2 14 1)) (f (0 2 0))) "Retrieve cangjie code for han characters" tar ((:commit . "87408d79b73a69194842a8848de6d7708e98c3a4") (:keywords "convenience" "writing") (:url . "https://github.com/kisaragi-hiu/cangjie.el"))])
+ (cape . [(20220502 1039) ((emacs (27 1))) "Completion At Point Extensions" tar ((:commit . "d836397d9c025f03125fb4321abd48d557518bb6") (:authors ("Daniel Mendler" . "mail@daniel-mendler.de")) (:maintainer "Daniel Mendler" . "mail@daniel-mendler.de") (:url . "https://github.com/minad/cape"))])
+ (capnp-mode . [(20210707 2310) nil "Major mode for editing Capn' Proto Files" single ((:commit . "02dc92c900babbd232fbcdd14f7ccf44d234ee77") (:authors ("Brian Taylor" . "el.wubo@gmail.com")) (:maintainer "Brian Taylor" . "el.wubo@gmail.com") (:url . "https://github.com/capnproto/capnproto"))])
+ (capture . [(20130828 1644) nil "screencasting with \"avconv\" or \"ffmpeg\"" tar ((:commit . "1bb26060311da76767f70096218313fc93b0c806") (:authors ("Sergey Pashinin <sergey at pashinin dot com>")) (:maintainer "Sergey Pashinin <sergey at pashinin dot com>"))])
+ (carbon-now-sh . [(20201028 950) ((emacs (24 4))) "https://carbon.now.sh integration." single ((:commit . "6444a77a6065803cf97c3321f811bd34a8063d76") (:authors ("Vitalii Elenhaupt")) (:maintainer "Vitalii Elenhaupt") (:keywords "convenience") (:url . "https://github.com/veelenga/carbon-now-sh.el"))])
+ (cargo . [(20220311 827) ((emacs (24 3)) (markdown-mode (2 4))) "Emacs Minor Mode for Cargo, Rust's Package Manager." tar ((:commit . "8335b5577dfa526c645f7c1839c473f99b9ad1a8") (:authors ("Kevin W. van Rooijen")) (:maintainer "Kevin W. van Rooijen") (:keywords "tools"))])
+ (cargo-mode . [(20210605 1003) ((emacs (25 1))) "Cargo Major Mode. Cargo is the Rust package manager" single ((:commit . "b98ea60ddec30eac174012671ee09e125748a193") (:authors ("Ayrat Badykov" . "ayratin555@gmail.com")) (:maintainer "Ayrat Badykov" . "ayratin555@gmail.com") (:keywords "tools") (:url . "https://github.com/ayrat555/cargo-mode"))])
+ (caroline-theme . [(20160318 520) ((emacs (24))) "A trip down to New Orleans..." single ((:commit . "222fd483db304509f9e422dc82883d808e023ceb") (:authors ("Jack Killilea" . "jaaacckz1@gmail.com")) (:maintainer "Jack Killilea" . "jaaacckz1@gmail.com") (:url . "https://github.com/xjackk/carolines-theme"))])
+ (cascading-dir-locals . [(20211013 1955) ((emacs (26 1))) "Apply all (!) .dir-locals.el from root to current directory" single ((:commit . "345d4b70e837d45ee84014684127e7399932d5e6") (:authors ("Fritz Grabo" . "hello@fritzgrabo.com")) (:maintainer "Fritz Grabo" . "hello@fritzgrabo.com") (:keywords "convenience") (:url . "https://github.com/fritzgrabo/cascading-dir-locals"))])
+ (caseformat . [(20160115 1615) ((emacs (24)) (cl-lib (0 5)) (dash (2 12 1)) (s (1 10 0))) "Format based letter case converter" single ((:commit . "75ddb9c64eeb78b46d9e1db99bef8d0fb1e46b99") (:authors ("Hiroki YAMAKAWA" . "s06139@gmail.com")) (:maintainer "Hiroki YAMAKAWA" . "s06139@gmail.com") (:keywords "convenience") (:url . "https://github.com/HKey/caseformat"))])
+ (cask . [(20220504 1421) ((emacs (24 5)) (s (1 8 0)) (f (0 16 0)) (epl (0 5)) (shut-up (0 1 0)) (cl-lib (0 3)) (package-build (0)) (ansi (0 4 1))) "Cask: Project management for package development" tar ((:commit . "2eb520e64c2e1047319761df0bcc6fa5149f8cd6") (:authors ("Johan Andersson" . "johan.rejeep@gmail.com")) (:maintainer "Johan Andersson" . "johan.rejeep@gmail.com") (:keywords "speed" "convenience") (:url . "http://github.com/cask/cask"))])
+ (cask-mode . [(20160410 1449) ((emacs (24 3))) "major mode for editing Cask files" single ((:commit . "be8b69e55916cf2e78886927f58c7c49b969c0b8") (:authors ("Wilfred Hughes" . "me@wilfred.me.uk")) (:maintainer "Wilfred Hughes" . "me@wilfred.me.uk"))])
+ (cask-package-toolset . [(20170921 2256) ((emacs (24)) (cl-lib (0 3)) (s (1 6 1)) (dash (1 8 0)) (f (0 10 0)) (commander (0 2 0)) (ansi (0 1 0)) (shut-up (0 1 0))) "Toolsettize your package" tar ((:commit . "2c74cd827e88c7f8360581a841e45f0b794510e7") (:authors ("Adrien Becchis" . "adriean.khisbe@live.fr")) (:maintainer "Adrien Becchis" . "adriean.khisbe@live.fr") (:keywords "convenience" "tools") (:url . "http://github.com/AdrieanKhisbe/cask-package-toolset.el"))])
+ (caskxy . [(20140513 1539) ((log4e (0 2 0)) (yaxception (0 1))) "Control Cask in Emacs" single ((:commit . "dc18dcab7ed526070ab76de071c9c5272e6ac40e") (:authors ("Hiroaki Otsu" . "ootsuhiroaki@gmail.com")) (:maintainer "Hiroaki Otsu" . "ootsuhiroaki@gmail.com") (:keywords "convenience") (:url . "https://github.com/aki2o/caskxy"))])
+ (catmacs . [(20170826 1157) ((emacs (24))) "Simple CAT interface for Yaesu Transceivers." single ((:commit . "65d3e0563abe6ff9577202cf2278074d4130fbdd") (:authors ("Frank Singleton" . "b17flyboy@gmail.com")) (:maintainer "Frank Singleton" . "b17flyboy@gmail.com") (:keywords "comm" "hardware") (:url . "https://bitbucket.org/pymaximus/catmacs"))])
+ (catppuccin-theme . [(20220330 1021) ((emacs (25 1))) "Catppuccin Theme" single ((:commit . "352ebf62099e95cb4a71060a7d4a228f00358b97") (:authors ("pspiagicw")) (:maintainer "pspiagicw" . "pspiagicw@gmail.com") (:url . "https://github.com/catppuccin/emacs"))])
+ (cbm . [(20171116 1240) ((cl-lib (0 5))) "Switch to similar buffers." single ((:commit . "5b41c936ba9f6d170309a85ffebc9939c1050b31") (:authors ("Lukas Fürmetz" . "fuermetz@mailbox.org")) (:maintainer "Lukas Fürmetz" . "fuermetz@mailbox.org") (:keywords "buffers") (:url . "http://github.com/akermu/cbm.el"))])
+ (cc-cedict . [(20210814 819) ((emacs (26 1))) "Interface to CC-CEDICT (a Chinese-English dictionary)" single ((:commit . "03fbe7d1589d36f627ef9fe7b86f9fe6f623cbb3") (:authors ("Xu Chunyang")) (:maintainer "Xu Chunyang") (:url . "https://github.com/xuchunyang/cc-cedict.el"))])
+ (ccc . [(20210501 820) nil "buffer local cursor color control library" single ((:commit . "c664b26d0861621ac86b5b5f47835dd84f06dc93") (:authors ("Masatake YAMATO" . "masata-y@is.aist-nara.ac.jp")) (:maintainer "SKK Development Team") (:keywords "cursor") (:url . "https://github.com/skk-dev/ddskk"))])
+ (ccls . [(20200820 308) ((emacs (25 1)) (lsp-mode (6 3 1)) (dash (2 14 1))) "ccls client for lsp-mode" tar ((:commit . "675a5704c14a27931e835a431beea3631d92e8e6") (:authors ("Tobias Pisani, Fangrui Song")) (:maintainer "Tobias Pisani, Fangrui Song") (:keywords "languages" "lsp" "c++") (:url . "https://github.com/MaskRay/emacs-ccls"))])
+ (cd-compile . [(20141108 1957) nil "run compile in a specific directory" single ((:commit . "10284ccae86afda4a37b09ba90acd1e2efedec9f") (:authors ("Jamie Nicol" . "jamie@thenicols.net")) (:maintainer "Jamie Nicol" . "jamie@thenicols.net"))])
+ (cdb . [(20200904 1431) nil "constant database (cdb) reader for Emacs Lisp" single ((:commit . "c664b26d0861621ac86b5b5f47835dd84f06dc93") (:authors ("Yusuke Shinyama <yusuke at cs . nyu . edu>")) (:maintainer "SKK Development Team") (:keywords "cdb") (:url . "https://github.com/skk-dev/ddskk"))])
+ (cdlatex . [(20210804 452) nil "Fast input methods for LaTeX environments and math" single ((:commit . "8e963c68531f75e459e8ebe7a34fd3ba9d3729a0") (:authors ("Carsten Dominik" . "carsten.dominik@gmail.com")) (:maintainer "Carsten Dominik" . "carsten.dominik@gmail.com") (:keywords "tex"))])
+ (cdnjs . [(20161031 1522) ((dash (2 13 0)) (deferred (0 4)) (f (0 17 2)) (pkg-info (0 5))) "A front end for http://cdnjs.com" single ((:commit . "ce19880d3ec3d81e6c665d0b1dfea99cc7a3f908") (:authors ("Yasuyuki Oka" . "yasuyk@gmail.com")) (:maintainer "Yasuyuki Oka" . "yasuyk@gmail.com") (:keywords "tools") (:url . "https://github.com/yasuyk/cdnjs.el"))])
+ (cedit . [(20200816 526) nil "paredit-like commands for c-like languages" single ((:commit . "cb38316903e6cfa8b8c978defa7e1dafcd4e0c12") (:authors ("zk_phi")) (:maintainer "zk_phi") (:url . "http://zk-phi.gitub.io/"))])
+ (celery . [(20170225 924) ((emacs (24)) (dash-functional (2 11 0)) (s (1 9 0)) (deferred (0 3 2))) "a minor mode to draw stats from celery and more?" single ((:commit . "51197d74f5eaa8ae09144af7663a2f4277f07d16") (:authors ("ardumont" . "eniotna.t@gmail.com")) (:maintainer "ardumont" . "eniotna.t@gmail.com") (:keywords "celery" "convenience") (:url . "https://github.com/ardumont/emacs-celery"))])
+ (celestial-mode-line . [(20180518 822) ((emacs (24))) "Show lunar phase and sunrise/-set time in modeline" single ((:commit . "3f5794aca99b977f1592cf1ab4516ae7922196a1") (:authors ("Peter" . "craven@gmx.net")) (:maintainer "Peter" . "craven@gmx.net") (:keywords "extensions") (:url . "https://github.com/ecraven/celestial-mode-line"))])
+ (centaur-tabs . [(20220224 808) ((emacs (24 4)) (powerline (2 4)) (cl-lib (0 5))) "Aesthetic, modern looking customizable tabs plugin" tar ((:commit . "f4cef95acbd2eb99c8db3b6cdde74a6e0a966a0a") (:authors ("Emmanuel Bustos" . "ema2159@gmail.com")) (:maintainer "Emmanuel Bustos" . "ema2159@gmail.com") (:url . "https://github.com/ema2159/centaur-tabs"))])
+ (centered-cursor-mode . [(20200507 1529) nil "cursor stays vertically centered" single ((:commit . "4093821cc9759ca5a3c6e527d4cc915fc3a5ad74") (:authors ("André Riemann" . "andre.riemann@web.de")) (:maintainer "André Riemann" . "andre.riemann@web.de") (:keywords "convenience") (:url . "https://github.com/andre-r/centered-cursor-mode.el"))])
+ (centered-window . [(20220125 804) ((emacs (24 4))) "Center the text when there's only one window" single ((:commit . "80965f6c6afe8d918481433984b493de72af5399") (:authors ("Anler Hernández Peral" . "inbox+emacs@anler.me")) (:maintainer "Anler Hernández Peral" . "inbox+emacs@anler.me") (:keywords "faces" "windows") (:url . "https://github.com/anler/centered-window-mode"))])
+ (centimacro . [(20201225 1132) nil "Assign multiple macros as global key bindings" single ((:commit . "0149877584b333c4f1953f0767f0cae23881b0df") (:authors ("Oleh Krehel" . "ohwoeowho@gmail.com")) (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com") (:keywords "macros") (:url . "https://github.com/abo-abo/centimacro"))])
+ (cerbere . [(20181113 1641) ((pkg-info (0 5))) "Unit testing in Emacs for several programming languages" tar ((:commit . "c667c165d9c1657f13d2d46f09ba21b61f9402cc") (:authors ("Nicolas Lamirault" . "nicolas.lamirault@gmail.com")) (:maintainer "Nicolas Lamirault" . "nicolas.lamirault@gmail.com") (:keywords "python" "go" "php" "phpunit" "elisp" "ert" "tests" "tdd") (:url . "https://github.com/nlamirault/cerbere"))])
+ (ceylon-mode . [(20180606 1324) ((emacs (25))) "Major mode for editing Ceylon source code" single ((:commit . "948515672bc596dc118e8e3ede3ede5ec6a3c95a") (:authors ("Lucas Werkmeister" . "mail@lucaswerkmeister.de")) (:maintainer "Lucas Werkmeister" . "mail@lucaswerkmeister.de") (:keywords "languages" "ceylon") (:url . "https://github.com/lucaswerkmeister/ceylon-mode"))])
+ (cfengine-code-style . [(20171115 2108) nil "C code style for CFEngine project." single ((:commit . "9b4331ab42d3e84dea9293ef989ff1b29e97b2b1") (:authors ("Mikhail Gusarov" . "mikhail.gusarov@cfengine.com")) (:maintainer "Mikhail Gusarov" . "mikhail.gusarov@cfengine.com") (:url . "https://github.com/cfengine/core"))])
+ (cff . [(20160118 2018) ((cl-lib (0 5)) (emacs (24))) "Search of the C/C++ file header by the source and vice versa" single ((:commit . "b6ab2a28e64ef06f281ec74cfe3114e450644dfa") (:authors ("Alexey Veretennikov" . "alexey.veretennikov@gmail.com")) (:maintainer "Alexey Veretennikov" . "alexey.veretennikov@gmail.com") (:keywords "find-file") (:url . "https://github.com/fourier/cff"))])
+ (cfml-mode . [(20190617 1130) ((emacs (25))) "Emacs mode for editing CFML files" single ((:commit . "2de315abddb6af088a2346e142cc305889dcd775") (:authors ("Andrew Myers" . "am2605@gmail.com")) (:maintainer "Andrew Myers" . "am2605@gmail.com") (:url . "https://github.com/am2605/cfml-mode"))])
+ (cfn-mode . [(20220221 1029) ((emacs (26 0)) (f (0 20 0)) (s (1 12 0)) (yaml-mode (0 0 13))) "AWS cloudformation mode" tar ((:commit . "4cf56affe3035fda364109836e26499431095185") (:authors ("William Orr" . "will@worrbase.com")) (:maintainer "William Orr" . "will@worrbase.com") (:keywords "convenience" "languages" "tools") (:url . "https://gitlab.com/worr/cfn-mode"))])
+ (cframe . [(20201222 1930) ((emacs (26)) (buffer-manage (0 11)) (dash (2 17 0))) "Customize a frame and fast switch size and positions" single ((:commit . "38544521e82befc06e397123a118dd96dda2c6b6") (:authors ("Paul Landes")) (:maintainer "Paul Landes") (:keywords "frames") (:url . "https://github.com/plandes/cframe"))])
+ (cfrs . [(20220129 1149) ((emacs (26 1)) (dash (2 11 0)) (s (1 10 0)) (posframe (0 6 0))) "Child-frame based read-string" single ((:commit . "f3a21f237b2a54e6b9f8a420a9da42b4f0a63121") (:authors ("Alexander Miller" . "alexanderm@web.de")) (:maintainer "Alexander Miller" . "alexanderm@web.de") (:url . "https://github.com/Alexander-Miller/cfrs"))])
+ (cg . [(20220318 1007) ((emacs (26 1))) "Major mode for editing Constraint Grammar files" single ((:commit . "06011b53bf64d671c74a79757332b9ef13f47f2b") (:authors ("Kevin Brubeck Unhammer" . "unhammer@fsfe.org")) (:maintainer "Kevin Brubeck Unhammer" . "unhammer@fsfe.org") (:keywords "languages") (:url . "https://visl.sdu.dk/constraint_grammar.html"))])
+ (challenger-deep-theme . [(20210120 941) ((emacs (24))) "challenger-deep Theme" single ((:commit . "2a799259406a8b96a688873093ffab6630a3ad3b") (:authors ("MaxSt")) (:maintainer "MaxSt") (:url . "https://github.com/challenger-deep-theme/emacs"))])
+ (change-inner . [(20210126 1456) ((expand-region (0 7))) "Change contents based on semantic units" single ((:commit . "42cad58aed2caec260f8e8ff61f78a7d3db72d1b") (:authors ("Magnar Sveen" . "magnars@gmail.com")) (:maintainer "Magnar Sveen" . "magnars@gmail.com") (:keywords "convenience" "extensions"))])
+ (chapel-mode . [(20210513 457) ((emacs (25 1)) (hydra (0 15 0))) "A major mode for the Chapel programming language" single ((:commit . "39fd24bb7cf44808200354ac0496be4fc4fddd9a") (:keywords "chapel" "chpl" "programming" "languages") (:url . "https://github.com/damon-kwok/chapel-mode"))])
+ (char-menu . [(20210321 1657) ((emacs (24 3)) (avy-menu (0 1))) "Create your own menu for fast insertion of arbitrary symbols" single ((:commit . "16e9ce0380a7661c6dae9ccec1172fe4757df682") (:authors ("Mark Karpov" . "markkarpov92@gmail.com")) (:maintainer "Mark Karpov" . "markkarpov92@gmail.com") (:keywords "convenience" "editing") (:url . "https://github.com/mrkkrp/char-menu"))])
+ (charmap . [(20200616 1418) nil "Unicode table for Emacs" single ((:commit . "a810347b43b024a86167ab9be935dcf56c122743") (:authors ("Anan Mikami" . "lateau@gmail.com")) (:maintainer "Anan Mikami" . "lateau@gmail.com") (:keywords "unicode" "character" "ucs") (:url . "https://github.com/lateau/charmap"))])
+ (chatwork . [(20170511 442) nil "ChatWork client for Emacs" single ((:commit . "fea231d479f06bf40dbfcf45de143eecc9ed744c") (:authors ("Masayuki Ataka" . "masayuki.ataka@gmail.com")) (:maintainer "Masayuki Ataka" . "masayuki.ataka@gmail.com") (:keywords "web") (:url . "https://github.com/ataka/chatwork"))])
+ (cheat-sh . [(20210607 1307) ((emacs (25 1))) "Interact with cheat.sh" single ((:commit . "33bae22feae8d3375739c6bdef08d0dcdf47ee42") (:authors ("Dave Pearson" . "davep@davep.org")) (:maintainer "Dave Pearson" . "davep@davep.org") (:keywords "docs" "help") (:url . "https://github.com/davep/cheat-sh.el"))])
+ (cheatsheet . [(20170126 2150) ((emacs (24)) (cl-lib (0 5))) "create your own cheatsheet" single ((:commit . "e4f8e0110167ea16a17a74517d1f10cb7ff805b8") (:authors ("Shirin Nikita" . "shirin.nikita@gmail.com")) (:maintainer "Shirin Nikita" . "shirin.nikita@gmail.com") (:keywords "convenience" "usability") (:url . "http://github.com/darksmile/cheatsheet/"))])
+ (checkbox . [(20141117 58) ((emacs (24)) (cl-lib (0 5))) "Quick manipulation of textual checkboxes" single ((:commit . "335afa4404adf72973195a580458927004664d98") (:authors ("Cameron Desautels" . "camdez@gmail.com")) (:maintainer "Cameron Desautels" . "camdez@gmail.com") (:keywords "convenience") (:url . "http://github.com/camdez/checkbox.el"))])
+ (chee . [(20171123 2233) ((dash (2 12 1)) (s (1 10 0)) (f (0 18 2))) "Interface to chee using dired and image-dired" tar ((:commit . "669ff9ee429f24c3c2d03b83d9cb9aec5f86bb8b") (:url . "https://github.com/eikek/chee/tree/release/0.3.0/emacs"))])
+ (cheerilee . [(20160313 1835) ((xelb (0 1))) "Toolkit library" tar ((:commit . "41bd81b5b0bb657241ceda5be6af5e07254d7376") (:authors ("Alessio Vanni" . "vannilla@firemail.cc")) (:maintainer "Alessio Vanni" . "vannilla@firemail.cc") (:keywords "multimedia" "tools") (:url . "https://github.com/Vannil/cheerilee.el"))])
+ (chef-mode . [(20180628 1453) nil "minor mode for editing an opscode chef repository" single ((:commit . "048d691cb63981ae235763d4a6ced4af5c729924") (:authors ("Maciej Pasternacki" . "maciej@pasternacki.net")) (:maintainer "Maciej Pasternacki" . "maciej@pasternacki.net") (:keywords "chef" "knife"))])
+ (chembalance . [(20210601 1653) ((emacs (24 4))) "Balance chemical equations" single ((:commit . "ae36c823ca151f1dc6144ec96b2f5e98181c0dbb") (:authors ("Sergi Ruiz Trepat")) (:maintainer "Sergi Ruiz Trepat") (:keywords "convenience" "chemistry") (:url . "https://github.com/sergiruiztrepat/chembalance"))])
+ (chemtable . [(20210713 1551) ((emacs (24 1))) "Periodic table of the elements" single ((:commit . "05fc1449db497e715b33b8e08359fa17c3148c7b") (:authors ("Sergi Ruiz Trepat")) (:maintainer "Sergi Ruiz Trepat") (:keywords "convenience" "chemistry") (:url . "https://github.com/sergiruiztrepat/chemtable"))])
+ (cherry-blossom-theme . [(20150622 342) ((emacs (24 0))) "a soothing color theme for Emacs24." single ((:commit . "eea7653e00f35973857ee23b27bc2fae5e753e50") (:authors ("Ben Yelsey" . "byelsey1@gmail.com")) (:maintainer "Ben Yelsey" . "byelsey1@gmail.com") (:url . "https://github.com/inlinestyle/emacs-cherry-blossom-theme"))])
+ (chezmoi . [(20220310 2014) ((emacs (26 1))) "A package for interacting with chezmoi" tar ((:commit . "781783c483bc8fcdba3a230bb774c3a8a5ebe396") (:authors ("Harrison Pielke-Lombardo")) (:maintainer "Harrison Pielke-Lombardo") (:keywords "vc") (:url . "http://www.github.com/tuh8888/chezmoi.el"))])
+ (chinese-conv . [(20170807 2128) ((cl-lib (0 5))) "Conversion between Chinese Characters with opencc or cconv" single ((:commit . "b56815bbb163d642e97fa73093b5a7e87cc32574") (:authors ("gucong" . "gucong43216@gmail.com")) (:maintainer "gucong" . "gucong43216@gmail.com") (:url . "https://github.com/gucong/emacs-chinese-conv"))])
+ (chinese-number . [(20161008 509) nil "Convert numbers between Arabic and Chinese formats" single ((:commit . "7311c2a0c5eea5f016a90d733dfe75144c302fb2") (:authors (nil . "zhcosin<zhcosin@163.com>")) (:maintainer nil . "zhcosin<zhcosin@163.com>") (:url . "https://github.com/zhcosin/chinese-number"))])
+ (chinese-wbim . [(20190727 854) nil "Enable Wubi Input Method in Emacs." tar ((:commit . "5d496364b0b6bbaaf0f9b37e5a6d260d4994f260") (:authors (nil . "Guanghui Qu<guanghui8827@gmail.com>")) (:maintainer nil . "Guanghui Qu<guanghui8827@gmail.com>") (:keywords "wubi" "input" "method.") (:url . "https://github.com/andyque/chinese-wbim"))])
+ (chinese-word-at-point . [(20170811 941) ((cl-lib (0 5))) "Add `chinese-word' thing to `thing-at-point'" single ((:commit . "8223d7439e005555b86995a005b225ae042f0538") (:authors ("Chunyang Xu" . "xuchunyang56@gmail.com")) (:maintainer "Chunyang Xu" . "xuchunyang56@gmail.com") (:keywords "convenience" "chinese") (:url . "https://github.com/xuchunyang/chinese-word-at-point.el"))])
+ (chinese-yasdcv . [(20171015 144) ((cl-lib (0 5)) (pyim (1 6 0))) "Yet another StarDict frontend" tar ((:commit . "5ab830daf1273d5a5cddcb94b56a9737f12d996f") (:authors ("Feng Shu" . "tumashu@gmail.com")) (:maintainer "Feng Shu" . "tumashu@gmail.com") (:keywords "convenience" "chinese" "dictionary") (:url . "https://github.com/tumashu/chinese-yasdcv"))])
+ (chocolate-theme . [(20210128 1647) ((emacs (24 1)) (autothemer (0 2))) "A dark chocolaty theme" single ((:commit . "ccc05f7ad96d3d1332727689bf6250443adc7ec0") (:url . "http://github.com/SavchenkoValeriy/emacs-chocolate-theme"))])
+ (choice-program . [(20201217 1751) ((emacs (26)) (dash (2 17 0))) "Parameter based program" tar ((:commit . "b8b1b6c5568f8778783454d5747912487c8e69b8") (:authors ("Paul Landes")) (:maintainer "Paul Landes") (:keywords "execution" "processes" "unix" "lisp") (:url . "https://github.com/plandes/choice-program"))])
+ (chronometer . [(20190304 1528) ((emacs (24))) "a [not so] simple chronometer" single ((:commit . "8457b296ef87be339cbe47730b922757d60bdcd5") (:authors ("Marcelo Toledo" . "marcelo@marcelotoledo.com")) (:maintainer "Marcelo Toledo" . "marcelo@marcelotoledo.com") (:keywords "tools" "convenience") (:url . "https://github.com/marcelotoledo/chronometer"))])
+ (chronometrist . [(20220415 1213) ((emacs (27 1)) (dash (2 16 0)) (seq (2 20)) (ts (0 2))) "Friendly and powerful personal time tracker and analyzer" tar ((:commit . "f7b2defceed8bafb87da704ce3e7774f53abf1c4") (:authors ("contrapunctus" . "xmpp:contrapunctus@jabjab.de")) (:maintainer "contrapunctus" . "xmpp:contrapunctus@jabjab.de") (:keywords "calendar") (:url . "https://tildegit.org/contrapunctus/chronometrist"))])
+ (chronometrist-goal . [(20210510 1831) ((emacs (25 1)) (alert (1 2)) (chronometrist (0 7 0))) "Adds support for time goals to Chronometrist" single ((:commit . "6cb939d160f5d5966d7853aa23f3ed7c7ef9df44") (:authors ("contrapunctus" . "xmpp:contrapunctus@jabber.fr")) (:maintainer "contrapunctus" . "xmpp:contrapunctus@jabber.fr") (:keywords "calendar") (:url . "https://tildegit.org/contrapunctus/chronometrist-goal"))])
+ (chronometrist-key-values . [(20220414 726) ((chronometrist (0 7 0))) "add key-values to Chronometrist data" tar ((:commit . "f7b2defceed8bafb87da704ce3e7774f53abf1c4") (:authors ("contrapunctus" . "xmpp:contrapunctus@jabjab.de")) (:maintainer "contrapunctus" . "xmpp:contrapunctus@jabjab.de") (:keywords "calendar") (:url . "https://tildegit.org/contrapunctus/chronometrist"))])
+ (chronometrist-spark . [(20220321 349) ((emacs (25 1)) (chronometrist (0 7 0)) (spark (0 1))) "Show sparklines in Chronometrist buffers" tar ((:commit . "f7b2defceed8bafb87da704ce3e7774f53abf1c4") (:authors ("contrapunctus" . "xmpp:contrapunctus@jabjab.de")) (:maintainer "contrapunctus" . "xmpp:contrapunctus@jabjab.de") (:keywords "calendar") (:url . "https://tildegit.org/contrapunctus/chronometrist"))])
+ (chronos . [(20150602 1529) nil "multiple simultaneous countdown / countup timers" tar ((:commit . "b360d9dae57aa553cf2a14ffa0756a51ad71de09") (:authors ("David Knight" . "dxknight@opmbx.org")) (:maintainer "David Knight" . "dxknight@opmbx.org") (:keywords "calendar") (:url . "http://github.com/dxknight/chronos"))])
+ (chruby . [(20180114 1652) ((cl-lib (0 5))) "Emacs integration for chruby" single ((:commit . "42bc6d521f832eca8e2ba210f30d03ad5529788f") (:authors ("Arne Brasseur" . "arne@arnebrasseur.net")) (:maintainer "Arne Brasseur" . "arne@arnebrasseur.net") (:keywords "languages") (:url . "https://github.com/plexus/chruby.el"))])
+ (chyla-theme . [(20180302 1658) nil "chyla.org - green color theme." single ((:commit . "ae5e7ecace2ab474151eb0ac5ef07fba2dc32f8a") (:authors ("Adam Chyła" . "adam@chyla.org")) (:maintainer "Adam Chyła" . "adam@chyla.org") (:url . "https://github.com/chyla/ChylaThemeForEmacs"))])
+ (cider . [(20220502 903) ((emacs (26)) (clojure-mode (5 14)) (parseedn (1 0 6)) (queue (0 2)) (spinner (1 7)) (seq (2 22)) (sesman (0 3 2))) "Clojure Interactive Development Environment that Rocks" tar ((:commit . "acea8e256d25c0f3b05cf6351b83bbe4543ab0f4") (:authors ("Tim King" . "kingtim@gmail.com") ("Phil Hagelberg" . "technomancy@gmail.com") ("Bozhidar Batsov" . "bozhidar@batsov.dev") ("Artur Malabarba" . "bruce.connor.am@gmail.com") ("Hugo Duncan" . "hugo@hugoduncan.org") ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Bozhidar Batsov" . "bozhidar@batsov.dev") (:keywords "languages" "clojure" "cider") (:url . "http://www.github.com/clojure-emacs/cider"))])
+ (cider-decompile . [(20151122 537) ((cider (0 3 0)) (javap-mode (9))) "decompilation extension for cider" single ((:commit . "5d87035f3c3c14025e8f01c0c53d0ce2c8f56651") (:authors ("Dmitry Bushenko")) (:maintainer "Dmitry Bushenko") (:keywords "languages" "clojure" "cider") (:url . "http://www.github.com/clojure-emacs/cider-decompile"))])
+ (cider-eval-sexp-fu . [(20190311 2152) ((emacs (24)) (eval-sexp-fu (0 5 0))) "Briefly highlights an evaluated sexp." single ((:commit . "7fd229f1441356866aedba611fd0cf4e89b50921") (:authors ("Sylvain Benner" . "sylvain.benner@gmail.com")) (:maintainer "Sylvain Benner" . "sylvain.benner@gmail.com") (:keywords "languages" "clojure" "cider"))])
+ (cider-hydra . [(20190816 1121) ((cider (0 22 0)) (hydra (0 13 0))) "Hydras for CIDER." single ((:commit . "c3b8a15d72dddfbc390ab6a454bd7e4c765a2c95") (:authors ("Tianxiang Xiong" . "tianxiang.xiong@gmail.com")) (:maintainer "Tianxiang Xiong" . "tianxiang.xiong@gmail.com") (:keywords "convenience" "tools") (:url . "https://github.com/clojure-emacs/cider-hydra"))])
+ (ciel . [(20180914 815) ((emacs (24))) "A command that is clone of \"ci\" in vim." single ((:commit . "429773a3c551691a463ecfddd634b8bae2f48503") (:authors ("Takuma Matsushita" . "cs14095@gmail.com")) (:maintainer "Takuma Matsushita" . "cs14095@gmail.com") (:keywords "convinience") (:url . "https://github.com/cs14095/ciel.el"))])
+ (cil-mode . [(20160622 1430) nil "Common Intermediate Language mode" single ((:commit . "a78a88ca9a66a82f069329a96e34b67478ae2d9b") (:authors ("Friedrich von Never" . "friedrich@fornever.me")) (:maintainer "Friedrich von Never" . "friedrich@fornever.me") (:keywords "languages") (:url . "https://github.com/ForNeVeR/cil-mode"))])
+ (cilk-mode . [(20220411 1342) ((emacs (25 1)) (flycheck (32 -4))) "Minor mode for Cilk code editing" single ((:commit . "794821e129ea47b04fdeedc61d9ccb3c4240c72d") (:authors ("Alexandros-Stavros Iliopoulos <https://github.com/ailiop>")) (:maintainer "Alexandros-Stavros Iliopoulos" . "1577182+ailiop@users.noreply.github.com") (:keywords "c" "convenience" "faces" "languages") (:url . "https://github.com/ailiop/cilk-mode"))])
+ (cinspect . [(20150716 233) ((emacs (24)) (cl-lib (0 5)) (deferred (0 3 1)) (python-environment (0 0 2))) "Use cinspect to look at the CPython source of builtins and other C objects!" single ((:commit . "4e199a90f89b335cccda1518aa0963e0a1d4fbab") (:authors ("Ben Yelsey" . "ben.yelsey@gmail.com")) (:maintainer "Ben Yelsey" . "ben.yelsey@gmail.com") (:keywords "python") (:url . "https://github.com/inlinestyle/cinspect-mode"))])
+ (circadian . [(20181024 1256) ((emacs (24 4))) "Theme-switching based on daytime" single ((:commit . "bf5a00ea45c14dfdcda72c5d9f61bcd230c48159") (:authors ("Guido Schmidt")) (:maintainer "Guido Schmidt" . "git@guidoschmidt.cc") (:keywords "themes") (:url . "https://github.com/GuidoSchmidt/circadian"))])
+ (circe . [(20220421 1956) ((emacs (24 5)) (cl-lib (0 5))) "Client for IRC in Emacs" tar ((:commit . "710f057fedae6e9b820cce9336fef24b7d057e4c") (:authors ("Jorgen Schaefer" . "forcer@forcix.cx")) (:maintainer "Jorgen Schaefer" . "forcer@forcix.cx") (:keywords "irc" "chat" "comm") (:url . "https://github.com/emacs-circe/circe"))])
+ (circe-notifications . [(20180102 2318) ((emacs (24 4)) (circe (2 3)) (alert (1 2))) "Add desktop notifications to Circe." single ((:commit . "291149ac12877bbd062da993479d3533a26862b0") (:authors ("Ruben Maher" . "r@rkm.id.au")) (:maintainer "Ruben Maher" . "r@rkm.id.au") (:url . "https://github.com/eqyiel/circe-notifications"))])
+ (circleci-api . [(20210227 1607) ((emacs (27)) (request (0 3 2))) "Bindings for the CircleCI API" single ((:commit . "2e39c5896819bb2063f9d7795c4299f419cf5542") (:authors ("Robin Schroer")) (:maintainer "Robin Schroer") (:url . "https://github.com/sulami/circleci-api"))])
+ (citar . [(20220426 2152) ((emacs (27 1)) (parsebib (3 0)) (org (9 5)) (citeproc (0 9))) "Citation-related commands for org, latex, markdown" tar ((:commit . "b391e6de49e00cffa8f60a089a01d663b627a678") (:authors ("Bruce D'Arcus <https://github.com/bdarcus>")) (:maintainer "Bruce D'Arcus <https://github.com/bdarcus>") (:url . "https://github.com/bdarcus/citar"))])
+ (citeproc . [(20220124 721) ((emacs (25)) (dash (2 13 0)) (s (1 12 0)) (f (0 18 0)) (queue (0 2)) (string-inflection (1 0)) (org (9)) (parsebib (2 4))) "A CSL 1.0.2 Citation Processor" tar ((:commit . "ba49516265fa24b138346c4918d39d19b4de8a62") (:authors ("András Simonyi" . "andras.simonyi@gmail.com")) (:maintainer "András Simonyi" . "andras.simonyi@gmail.com") (:keywords "bib") (:url . "https://github.com/andras-simonyi/citeproc-el"))])
+ (citeproc-org . [(20200915 2009) ((emacs (25 1)) (dash (2 12 0)) (org (9)) (f (0 18 0)) (citeproc (0 1)) (org-ref (1 1 1))) "Render org-mode references in CSL styles" tar ((:commit . "20cd7e817420a3f6e7b82faea901a3c67c6d4d9f") (:authors ("András Simonyi" . "andras.simonyi@gmail.com")) (:maintainer "András Simonyi" . "andras.simonyi@gmail.com") (:keywords "org-ref" "org-mode" "cite" "bib") (:url . "https://github.com/andras-simonyi/citeproc-org"))])
+ (citre . [(20220427 1203) ((emacs (26 1))) "Ctags IDE on the True Editor" tar ((:commit . "87e2cbf3b2ae6d59ec919a2dcb38e56ccfa5ec14") (:authors ("Hao Wang" . "amaikinono@gmail.com")) (:maintainer "Hao Wang" . "amaikinono@gmail.com") (:keywords "convenience" "tools") (:url . "https://github.com/universal-ctags/citre"))])
+ (cl-format . [(20210831 530) nil "CL format routine." tar ((:commit . "ad1a4fb6bc91e65ea90bcf6792cc5a1be5380f9d") (:authors ("Andreas Politz" . "politza@fh-trier.de")) (:maintainer "akater" . "nuclearspace@gmail.com") (:keywords "extensions") (:url . "https://gitlab.com/akater/elisp-cl-format"))])
+ (cl-libify . [(20181130 230) ((emacs (25))) "Update elisp code to use cl-lib instead of cl" single ((:commit . "f215866d7d7c52e84220cd541f40608a5b85abf0") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:keywords "lisp") (:url . "https://github.com/purcell/cl-libify"))])
+ (clang-capf . [(20220122 1219) ((emacs (24 4))) "Completion-at-point backend for c/c++ using clang" single ((:commit . "b1765719288a138e125cc5ce624ef561c80015bf") (:authors ("Philip K. <philipk [at] posteo [dot] net>")) (:maintainer "Philip K. <philipk [at] posteo [dot] net>") (:keywords "c" "abbrev" "convenience") (:url . "https://git.sr.ht/~pkal/clang-capf"))])
+ (clang-format . [(20191106 950) ((cl-lib (0 3))) "Format code using clang-format" single ((:commit . "e48ff8ae18dc7ab6118c1f6752deb48cb1fc83ac") (:keywords "tools" "c"))])
+ (clang-format+ . [(20190824 2216) ((emacs (25 1)) (clang-format (20180406 1514))) "Minor mode for automatic clang-format application" single ((:commit . "ddd4bfe1a13c2fd494ce339a320a51124c1d2f68") (:keywords "c" "c++" "clang-format") (:url . "https://github.com/SavchenkoValeriy/emacs-clang-format-plus"))])
+ (clean-aindent-mode . [(20171017 2043) nil "Simple indent and unindent, trims indent white-space" single ((:commit . "a97bcae8f43a9ff64e95473e4ef0d8bafe829211") (:authors ("peter marinov" . "efravia@gmail.com")) (:maintainer "peter marinov" . "efravia@gmail.com") (:keywords "indentation" "whitespace" "backspace") (:url . "https://github.com/pmarinov/clean-aindent-mode"))])
+ (clean-buffers . [(20160529 2259) ((cl-lib (0 5))) "clean useless buffers" single ((:commit . "1be6c54e3095761b6b64bf749faae3dfce94e72a") (:authors ("DarkSun" . "lujun9972@gmail.com")) (:maintainer "DarkSun" . "lujun9972@gmail.com") (:keywords "convenience" "usability" "buffers"))])
+ (clear-text . [(20160406 2043) nil "Make you use clear text" tar ((:commit . "b50669b6077d6948f72cb3c649281d206e0c2f2b") (:authors ("Chunyang Xu" . "xuchunyang56@gmail.com")) (:maintainer "Chunyang Xu" . "xuchunyang56@gmail.com") (:keywords "convenience") (:url . "https://github.com/xuchunyang/clear-text.el"))])
+ (clevercss . [(20131229 155) nil "A major mode for editing CleverCSS files" single ((:commit . "b8a3c0dd674367c62b1a1ffec84d88fe0c0219bc") (:authors ("Joe Schafer" . "joesmoe10@gmail.com")) (:maintainer "Joe Schafer" . "joesmoe10@gmail.com") (:keywords "languages" "css"))])
+ (clhs . [(20210428 1911) nil "Access the Common Lisp HyperSpec (CLHS)" single ((:commit . "7b106c4fb5a6388ab753f94740f6dfadcdeedcbb") (:maintainer "Sam Steingold" . "sds@gnu.org") (:keywords "lisp" "common lisp" "emacs" "ansi cl" "hyperspec") (:url . "https://gitlab.com/sam-s/clhs"))])
+ (click-mode . [(20180611 44) ((emacs (24))) "Major mode for the Click Modular Router Project" single ((:commit . "b94ea8cce89cf0e753b2ab915202d49ffc470fb6") (:authors ("Brian Malehorn" . "bmalehorn@gmail.com")) (:maintainer "Brian Malehorn" . "bmalehorn@gmail.com") (:keywords "click" "router") (:url . "https://github.com/bmalehorn/click-mode"))])
+ (clingo-mode . [(20220502 2020) ((emacs (24 3))) "A major mode for editing Answer Set Programs" single ((:commit . "cf56ce6b5c50506f6cea27e1dde0441dd8d15ee9") (:authors ("Ivan Uemlianin" . "ivan@llaisdy.com")) (:maintainer "Ivan Uemlianin" . "ivan@llaisdy.com") (:keywords "asp" "clingo" "answer set programs" "potassco" "major mode" "languages") (:url . "https://github.com/llaisdy/clingo-mode"))])
+ (clipetty . [(20200327 2241) ((emacs (25 1))) "Send every kill from a TTY frame to the system clipboard" single ((:commit . "01b39044b9b65fa4ea7d3166f8b1ffab6f740362") (:authors ("Mike Hamrick" . "mikeh@muppetlabs.com")) (:maintainer "Mike Hamrick" . "mikeh@muppetlabs.com") (:keywords "terminals" "convenience") (:url . "https://github.com/spudlyo/clipetty"))])
+ (cliphist . [(20210813 750) ((emacs (25 1))) "paste from clipboard managers" tar ((:commit . "a794c95e2f70a9b042af7bd07e2483fde75f2a2e") (:authors ("Chen Bin <chenbin DOT sh AT gmail DOT com>")) (:maintainer "Chen Bin <chenbin DOT sh AT gmail DOT com>") (:keywords "clipboard" "manager" "history") (:url . "http://github.com/redguardtoo/cliphist"))])
+ (clipmon . [(20180129 1054) nil "Clipboard monitor - watch system clipboard, add changes to kill ring/autoinsert" tar ((:commit . "95dc56c7ed84a654ec90f4740eb6df1050de8cf1") (:authors ("Brian Burns" . "bburns.km@gmail.com")) (:maintainer "Brian Burns" . "bburns.km@gmail.com") (:keywords "convenience") (:url . "https://github.com/bburns/clipmon"))])
+ (clippy . [(20161028 1954) ((pos-tip (1 0))) "Show tooltip with function documentation at point" single ((:commit . "e77f6b63e54d74e243be98accad474e38f7e2a86") (:authors ("Matus Goljer" . "matus.goljer@gmail.com")) (:maintainer "Matus Goljer" . "matus.goljer@gmail.com") (:keywords "docs") (:url . "https://github.com/Fuco1/clippy.el"))])
+ (clips-mode . [(20170909 823) nil "Major mode for editing CLIPS code and REPL" tar ((:commit . "dd38e2822640a38f7d8bfec4f69d8dd24be27074") (:authors ("David E. Young" . "david.young@fnc.fujitsu.com") ("Andrey Kotlarski" . "m00naticus@gmail.com") ("Grant Rettke" . "grettke@acm.org")) (:maintainer "Grant Rettke" . "grettke@acm.org") (:keywords "clips"))])
+ (clj-decompiler . [(20220103 1746) ((emacs (26 1)) (clojure-mode (5 12)) (cider (1 2 0))) "Clojure Java decompiler expansion" single ((:commit . "8c0c53f87e6e33f2be7e7aff6095eb586b50be1a") (:authors ("Ben Sless" . "ben.sless@gmail.com")) (:maintainer "Ben Sless" . "ben.sless@gmail.com") (:keywords "languages" "clojure" "cider" "java" "decompiler") (:url . "https://www.github.com/bsless/clj-decompiler.el"))])
+ (clj-deps-new . [(20220221 2235) ((emacs (25 1)) (transient (0 3 7))) "Create clojure projects from templates" single ((:commit . "183089e6d4ded90efff491916e1c87411ead0461") (:authors ("jpe90" . "eskinjp@gmail.com")) (:maintainer "jpe90" . "eskinjp@gmail.com") (:url . "https://github.com/jpe90/emacs-deps-new"))])
+ (clj-refactor . [(20220315 2251) ((emacs (26 1)) (seq (2 19)) (yasnippet (0 6 1)) (paredit (24)) (multiple-cursors (1 2 2)) (clojure-mode (5 14)) (cider (1 3)) (parseedn (1 0 6)) (inflections (2 3)) (hydra (0 13 2))) "A collection of commands for refactoring Clojure code" tar ((:commit . "f368c56c83843396b160440f472a661a3b639862") (:authors ("Magnar Sveen" . "magnars@gmail.com") ("Lars Andersen" . "expez@expez.com") ("Benedek Fazekas" . "benedek.fazekas@gmail.com") ("Bozhidar Batsov" . "bozhidar@batsov.dev")) (:maintainer "Magnar Sveen" . "magnars@gmail.com") (:keywords "convenience" "clojure" "cider"))])
+ (cljr-helm . [(20160913 828) ((clj-refactor (0 13 0)) (helm-core (1 7 7)) (cl-lib (0 5))) "Wraps clojure refactor commands with helm" single ((:commit . "f2fc7b698a56e4a44d5dfbc6a55d77a93c0fa9a4") (:authors ("Phil Jackson" . "phil@shellarchive.co.uk")) (:maintainer "Phil Jackson" . "phil@shellarchive.co.uk") (:keywords "helm" "clojure" "refactor") (:url . "https://github.com/philjackson/cljr-helm"))])
+ (cljr-ivy . [(20200602 1607) ((clj-refactor (2 5 0)) (ivy (0 13 0)) (emacs (24 3)) (cl-lib (0 6 1))) "Access clojure refactor with ivy completion" single ((:commit . "921ba65d0db7cda4edcd690c708946125b874a70") (:authors ("Wanderson Ferreira" . "iagwanderson@gmail.com")) (:maintainer "Wanderson Ferreira" . "iagwanderson@gmail.com") (:keywords "convenience" "matching") (:url . "https://github.com/wandersoncferreira/cljr-ivy"))])
+ (cljsbuild-mode . [(20160402 1700) nil "A minor mode for the ClojureScript 'lein cljsbuild' command" single ((:commit . "fa2315660cb3ce944b5e16c679dcf5afd6a97f4c") (:keywords "clojure" "clojurescript" "leiningen" "compilation") (:url . "http://github.com/kototama/cljsbuild-mode"))])
+ (clmemo . [(20220204 1345) nil "Change Log MEMO" tar ((:commit . "f695c38c551f72f6ac5e1a82badc540c80d3b33b") (:authors ("Masayuki Ataka" . "masayuki.ataka@gmail.com")) (:maintainer "Masayuki Ataka" . "masayuki.ataka@gmail.com") (:keywords "convenience") (:url . "https://github.com/ataka/clmemo"))])
+ (cloc . [(20170728 1824) ((cl-lib (0 5))) "count lines of code over emacs buffers" single ((:commit . "f30f0472e465cc8d433d2473e9d3b8dfe2c94491") (:authors ("Danny McClanahan" . "danieldmcclanahan@gmail.com")) (:maintainer "Danny McClanahan" . "danieldmcclanahan@gmail.com") (:keywords "cloc" "count" "source" "code" "lines") (:url . "https://github.com/cosmicexplorer/cloc-emacs"))])
+ (clocker . [(20190214 1833) ((projectile (0 11 0)) (dash (2 10)) (spaceline (2 0 1))) "Note taker and clock-in enforcer" single ((:commit . "c4d76968a49287ce3bac0832bb5d5d076054c96f") (:authors ("Roman Gonzalez" . "romanandreg@gmail.com")) (:maintainer "Roman Gonzalez" . "romanandreg@gmail.com") (:keywords "org"))])
+ (clojars . [(20180825 1951) ((request-deferred (0 2 0))) "clojars.org search interface" single ((:commit . "696c5b056e45067512a7d6dcce2515f3c639f61b") (:authors ("Joshua Miller" . "josh@joshmiller.io")) (:maintainer "Joshua Miller" . "josh@joshmiller.io") (:keywords "docs" "help" "tools") (:url . "https://github.com/joshuamiller/clojars.el"))])
+ (clojure-essential-ref . [(20200619 1653) ((emacs (24)) (cider (0 24 0))) "Cider-doc to \"Clojure, The Essential Reference\"" single ((:commit . "13ac560c25f7355fba00d9ca8c9f4ca03e7fd189") (:url . "https://github.com/p3r7/clojure-essential-ref"))])
+ (clojure-essential-ref-nov . [(20200719 608) ((emacs (24)) (dash (2 16 0)) (nov (0 3 1)) (clojure-essential-ref (0 1 0))) "Cider-doc to \"Clojure, The Essential Reference\" (EPUB)" single ((:commit . "13ac560c25f7355fba00d9ca8c9f4ca03e7fd189") (:url . "https://github.com/p3r7/clojure-essential-ref"))])
+ (clojure-mode . [(20220418 2015) ((emacs (25 1))) "Major mode for Clojure code" single ((:commit . "b6f41d74904daa9312648f3a7bea7a72fd8e140b") (:maintainer "Bozhidar Batsov" . "bozhidar@batsov.dev") (:keywords "languages" "clojure" "clojurescript" "lisp") (:url . "http://github.com/clojure-emacs/clojure-mode"))])
+ (clojure-mode-extra-font-locking . [(20211230 817) ((clojure-mode (3 0))) "Extra font-locking for Clojure mode" single ((:commit . "b6f41d74904daa9312648f3a7bea7a72fd8e140b") (:authors ("Bozhidar Batsov" . "bozhidar@batsov.dev")) (:maintainer "Bozhidar Batsov" . "bozhidar@batsov.dev") (:keywords "languages" "lisp") (:url . "http://github.com/clojure-emacs/clojure-mode"))])
+ (clojure-quick-repls . [(20150814 736) ((cider (0 8 1)) (dash (2 9 0))) "Quickly create Clojure and ClojureScript repls for a project." single ((:commit . "730311dd3ac4e0aceb0204f818b422017873467f") (:keywords "languages" "clojure" "cider" "clojurescript") (:url . "https://github.com/symfrog/clojure-quick-repls"))])
+ (clojure-snippets . [(20180314 1308) ((yasnippet (0 10 0))) "Yasnippets for clojure" tar ((:commit . "6068dca90467a0f4ebc2cd39338a173d6f5ddc04") (:authors ("Max Penet" . "m@qbits.cc")) (:maintainer "Max Penet" . "m@qbits.cc") (:keywords "snippets"))])
+ (clomacs . [(20220415 1035) ((emacs (24 3)) (cider (0 22 1)) (s (1 12 0)) (simple-httpd (1 4 6)) (dash (2 19 1))) "Simplifies Emacs Lisp interaction with Clojure." single ((:commit . "9cd7c9fd86bc7bc627a31275d1ef131378b90a49") (:authors ("Kostafey" . "kostafey@gmail.com")) (:maintainer "Kostafey" . "kostafey@gmail.com") (:keywords "clojure" "interaction") (:url . "https://github.com/clojure-emacs/clomacs"))])
+ (closql . [(20220422 1601) ((emacs (25 1)) (compat (28 1 1 0)) (emacsql-sqlite (3 0 0))) "Store EIEIO objects using EmacSQL" single ((:commit . "6f4af0fc87fa0a1734480d6a4b72797c0916bc12") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:keywords "extensions") (:url . "https://github.com/emacscollective/closql"))])
+ (closure-lint-mode . [(20101118 2124) nil "minor mode for the Closure Linter" single ((:commit . "bc3d2fd5c35580bf1b8af43b12484c95a343b4b5") (:authors ("Roman Scherer" . "roman@burningswell.com")) (:maintainer "Roman Scherer" . "roman@burningswell.com") (:keywords "tools" "closure" "javascript" "lint" "flymake") (:url . "https://github.com/r0man/closure-lint-mode"))])
+ (cloud-theme . [(20220205 1336) ((emacs (24))) "A light colored theme" single ((:commit . "16372ea1f527917102ac302afaec3ef09e289d24") (:authors ("Valerii Lysenko" . "vallyscode@gmail.com")) (:maintainer "Valerii Lysenko" . "vallyscode@gmail.com") (:keywords "color" "theme") (:url . "https://github.com/vallyscode/cloud-theme"))])
+ (cloud-to-butt-erc . [(20130627 2308) nil "Replace 'the cloud' with 'my butt'" single ((:commit . "6710c03d1bc91736435cbfe845924940cae34e5c") (:authors ("David Leatherman" . "leathekd@gmail.com")) (:maintainer "David Leatherman" . "leathekd@gmail.com") (:url . "http://www.github.com/leathekd/cloud-to-butt-erc"))])
+ (clues-theme . [(20161213 1127) ((emacs (24 0))) "an Emacs 24 theme which may well be fully awesome..." single ((:commit . "abd61f2b7f3e98de58ca26e6d1230e70c6406cc7") (:authors ("Jason Milkins" . "jasonm23@gmail.com")) (:maintainer "Jason Milkins" . "jasonm23@gmail.com") (:url . "https://github.com/emacsfodder/emacs-clues-theme"))])
+ (cm-mode . [(20170203 2107) ((cl-lib (0 5))) "Minor mode for CriticMarkup" single ((:commit . "276d49c859822265070ae5dfbb403fd7d8d06436") (:authors ("Joost Kremers" . "joostkremers@fastmail.fm")) (:maintainer "Joost Kremers" . "joostkremers@fastmail.fm") (:keywords "text" "markdown"))])
+ (cmake-font-lock . [(20211224 2006) ((cmake-mode (0 0))) "Advanced, type aware, highlight support for CMake" single ((:commit . "0d6111b36a66013aa9b452e664c93308df3b07e1") (:authors ("Anders Lindgren")) (:maintainer "Anders Lindgren") (:keywords "faces" "languages") (:url . "https://github.com/Lindydancer/cmake-font-lock"))])
+ (cmake-ide . [(20210610 1525) ((emacs (24 4)) (cl-lib (0 5)) (seq (1 11)) (levenshtein (0)) (s (1 11 0))) "Calls CMake to find out include paths and other compiler flags" single ((:commit . "28dc4ab5bd01d99553901b4efeb7234280928b18") (:authors ("Atila Neves" . "atila.neves@gmail.com")) (:maintainer "Atila Neves" . "atila.neves@gmail.com") (:keywords "languages") (:url . "http://github.com/atilaneves/cmake-ide"))])
+ (cmake-mode . [(20220322 1258) ((emacs (24 1))) "major-mode for editing CMake sources" single ((:commit . "7d78dcbebbb028c17de38e337942e0df061c6f20"))])
+ (cmake-project . [(20171121 1115) nil "Integrates CMake build process with Emacs" single ((:commit . "a7cf9e4c01c4683e14b6942cc5cc5e8cddc98721") (:authors ("Alexander Lamaison" . "alexander.lamaison@gmail")) (:maintainer "Alexander Lamaison" . "alexander.lamaison@gmail") (:keywords "c" "cmake" "languages" "tools") (:url . "http://github.com/alamaison/emacs-cmake-project"))])
+ (cmd-to-echo . [(20161203 2133) ((emacs (24 4)) (s (1 11 0)) (shell-split-string (20151224 208))) "Show the output of long-running commands in the echo area" single ((:commit . "e0e874fc0e1ad6d291e39ed76023445297ad438a") (:authors ("Tijs Mallaerts" . "tijs.mallaerts@gmail.com")) (:maintainer "Tijs Mallaerts" . "tijs.mallaerts@gmail.com"))])
+ (cmm-mode . [(20150225 746) nil "Major mode for C-- source code" single ((:commit . "c3ad514dff3eb30434f6b20d953276d4c00de1ee"))])
+ (cnfonts . [(20211227 248) ((emacs (24))) "A simple Chinese fonts config tool" tar ((:commit . "7279d4178b4d52ae763d2224140488887ce57261") (:authors ("Feng Shu" . "tumashu@163.com")) (:maintainer "Feng Shu" . "tumashu@163.com") (:keywords "convenience" "chinese" "font") (:url . "https://github.com/tumashu/cnfonts"))])
+ (cobalt . [(20180304 1155) ((emacs (24))) "Easily use the Cobalt.rs static site generator" single ((:commit . "88ef936373a5493183d49ec69ca541bcc749a109") (:authors ("Juan Karlo Licudine" . "accidentalrebel@gmail.com")) (:maintainer "Juan Karlo Licudine" . "accidentalrebel@gmail.com") (:keywords "convenience") (:url . "https://github.com/cobalt-org/cobalt.el"))])
+ (cobra-mode . [(20140116 2116) nil "Major mode for .NET-based Cobra language" single ((:commit . "acd6e53f6286af5176471d01f25257e5ddb6dd01") (:authors ("Taylor \"Nekroze\" Lawson")) (:maintainer "Taylor \"Nekroze\" Lawson") (:keywords "languages") (:url . "http://github.com/Nekroze/cobra-mode"))])
+ (codcut . [(20190915 1009) nil "Share pieces of code to Codcut" single ((:commit . "7ca7db69e8c38ec45eb572ad16ab2b56086f2131") (:authors ("Diego Pasquali" . "hello@dgopsq.space")) (:maintainer "Diego Pasquali" . "hello@dgopsq.space") (:keywords "comm" "tools" "codcut" "share") (:url . "https://github.com/codcut/codcut-emacs"))])
+ (code-archive . [(20190612 308) ((emacs (24 3))) "git supported code archive and reference for org-mode" single ((:commit . "1ad9af6679d0294c3056eab9cad673f29c562721") (:authors ("Michael Schuldt" . "mbschuldt@gmail.com")) (:maintainer "Michael Schuldt" . "mbschuldt@gmail.com") (:url . "https://github.com/mschuldt/code-archive"))])
+ (code-cells . [(20220305 1320) ((emacs (27 1))) "Lightweight notebooks with support for ipynb files" single ((:commit . "8660bdeedee360e5eb632f1eb1356eb09d7dfbee") (:authors ("Augusto Stoffel" . "arstoffel@gmail.com")) (:maintainer "Augusto Stoffel" . "arstoffel@gmail.com") (:keywords "convenience" "outlines") (:url . "https://github.com/astoff/code-cells.el"))])
+ (code-library . [(20160426 1218) ((gist (1 3 1))) "use org-mode to collect code snippets" single ((:commit . "32d59c5c845d6dbdda18f9bd1c03a58d55417fc5") (:authors ("DarkSun" . "lujun9972@gmail.com")) (:maintainer "DarkSun" . "lujun9972@gmail.com") (:keywords "lisp" "code"))])
+ (code-review . [(20220503 1344) ((emacs (25 1)) (closql (1 2 0)) (magit (3 0 0)) (a (1 0 0)) (ghub (3 5 1)) (uuidgen (1 2)) (deferred (0 5 1)) (markdown-mode (2 4)) (forge (0 3 0)) (emojify (1 2))) "Perform code review from Github, Gitlab, and Bitbucket Cloud" tar ((:commit . "d38fbe59304ed31c759ce733cda16f69a8ef2d8c") (:authors ("Wanderson Ferreira <https://github.com/wandersoncferreira>")) (:maintainer "Wanderson Ferreira" . "wand@hey.com") (:keywords "git" "tools" "vc") (:url . "https://github.com/wandersoncferreira/code-review"))])
+ (code-stats . [(20201209 2135) ((emacs (25)) (request (0 3 0))) "Code::Stats plugin" single ((:commit . "9a467dfd6a3cef849468623e1c085cbf59dac154") (:authors ("Xu Chunyang" . "mail@xuchunyang.me")) (:maintainer "Xu Chunyang" . "mail@xuchunyang.me") (:url . "https://github.com/xuchunyang/code-stats-emacs"))])
+ (codebug . [(20140929 2137) nil "Interact with codebug" single ((:commit . "ac0e4331ba94ccb5203fa492570e1ca6b90c3d52") (:authors ("Shane Dowling")) (:maintainer "Shane Dowling") (:url . "http://www.shanedowling.com/"))])
+ (codesearch . [(20181006 1431) ((log4e (0 3 1))) "Core support for managing codesearch tools" tar ((:commit . "f6eb96f034a925444412cfa03e45e0ccbbafe3f2") (:authors ("Austin Bingham" . "austin.bingham@gmail.com") ("Youngjoo Lee" . "youngker@gmail.com")) (:maintainer "Austin Bingham" . "austin.bingham@gmail.com") (:keywords "tools" "development" "search") (:url . "https://github.com/abingham/emacs-codesearch"))])
+ (codic . [(20150926 1127) ((emacs (24)) (cl-lib (0 5))) "Search Codic (codic.jp) naming dictionaries" tar ((:commit . "52bbb6997ef4ab9fb7fea43bbfff7f04671aa557") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-codic"))])
+ (coffee-fof . [(20131012 1230) ((coffee-mode (0 4 1))) "A coffee-mode configuration for `ff-find-other-file'." single ((:commit . "211529594bc074721c6cbc4edb73a63cc05f89ac") (:authors ("Yasuyki Oka" . "yasuyk@gmail.com")) (:maintainer "Yasuyki Oka" . "yasuyk@gmail.com") (:keywords "coffee-mode") (:url . "http://github.com/yasuyk/coffee-fof"))])
+ (coffee-mode . [(20200315 1133) ((emacs (24 3))) "Major mode for CoffeeScript code" single ((:commit . "35a41c7d8233eac0b267d9593e67fb8b6235e134") (:authors ("Chris Wanstrath" . "chris@ozmm.org")) (:maintainer "Chris Wanstrath" . "chris@ozmm.org") (:keywords "coffeescript" "major" "mode") (:url . "http://github.com/defunkt/coffee-mode"))])
+ (coin-ticker . [(20170611 727) ((request (0 3 0)) (emacs (25))) "Show a cryptocurrency price ticker" single ((:commit . "9efab90fe4e6f29464af14e0d8fd1e20c0147b80") (:authors ("Evan Klitzke" . "evan@eklitzke.org")) (:maintainer "Evan Klitzke" . "evan@eklitzke.org") (:keywords "news") (:url . "https://github.com/eklitzke/coin-ticker-mode"))])
+ (colonoscopy-theme . [(20170808 1309) ((emacs (24 0))) "an Emacs 24 theme based on Colonoscopy (tmTheme)" single ((:commit . "64bbb322b13dae91ce9f1e3581f836f94f800ead") (:authors ("Jason Milkins")) (:maintainer "Jason Milkins") (:url . "https://github.com/emacsfodder/tmtheme-to-deftheme"))])
+ (color-identifiers-mode . [(20220327 1143) ((dash (2 5 0)) (emacs (24))) "Color identifiers based on their names" single ((:commit . "6fe76f0c3090f6023da3806e9d760e93810905d4") (:authors ("Ankur Dave" . "ankurdave@gmail.com")) (:maintainer "Ankur Dave" . "ankurdave@gmail.com") (:keywords "faces" "languages") (:url . "https://github.com/ankurdave/color-identifiers-mode"))])
+ (color-moccur . [(20141223 35) nil "multi-buffer occur (grep) mode" single ((:commit . "4f1c59ffd1ccc2ab1a171cd6b721e8cb9e002fb7") (:keywords "convenience") (:url . "http://www.bookshelf.jp/elc/color-moccur.el"))])
+ (color-theme . [(20190220 1115) nil "An OBSOLETE color-theme implementation" tar ((:commit . "3a2f6b615f5e2401e30d93a3e0adc210bbb4b7aa") (:authors ("Jonadab the Unsightly One" . "jonadab@bright.net")) (:maintainer "Xavier Maillard" . "zedek@gnu.org") (:keywords "faces") (:url . "http://www.emacswiki.org/cgi-bin/wiki.pl?ColorTheme"))])
+ (color-theme-approximate . [(20140228 436) nil "Makes Emacs theme works on terminal transparently" single ((:commit . "f54301ca39bc5d2ffb000f233f8114184a3e7d71") (:authors ("Tung Dao" . "me@tungdao.com")) (:maintainer "Tung Dao" . "me@tungdao.com"))])
+ (color-theme-buffer-local . [(20170126 601) ((color-theme (0))) "Install color-themes by buffer." single ((:commit . "e606dec66f16a06140b9aad625a4fd52bca4f936") (:authors ("Victor Borja" . "vic.borja@gmail.com")) (:maintainer "Victor Borja" . "vic.borja@gmail.com") (:keywords "faces") (:url . "http://github.com/vic/color-theme-buffer-local"))])
+ (color-theme-modern . [(20200729 921) ((emacs (24))) "Reimplement colortheme with Emacs 24 theme framework." tar ((:commit . "a996eca37f4df726eec95406deb76b538320771a") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/emacs-jp/replace-colorthemes"))])
+ (color-theme-sanityinc-solarized . [(20200805 603) ((emacs (24 1)) (cl-lib (0 6))) "A version of Ethan Schoonover's Solarized themes" tar ((:commit . "7ef39ac9d99bfb699903cfc3623521c0ceec7b86") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:keywords "faces" "themes") (:url . "https://github.com/purcell/color-theme-sanityinc-solarized"))])
+ (color-theme-sanityinc-tomorrow . [(20220412 1643) nil "A version of Chris Kempson's \"tomorrow\" themes" tar ((:commit . "2b373a767129ed4e8c4d52e0ee827786224d7106") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:keywords "faces" "themes") (:url . "https://github.com/purcell/color-theme-sanityinc-tomorrow"))])
+ (color-theme-x . [(20201204 2245) ((cl-lib (0 5))) "convert color themes to X11 resource settings" single ((:commit . "ec853dd931d625e07116fbc91d8829bd15f90889") (:authors ("Matthew Kennedy" . "mkennedy@killr.ath.cx")) (:maintainer "Andrew Johnson" . "andrew@andrewjamesjohnson.com") (:keywords "convenience" "faces" "frames") (:url . "https://github.com/ajsquared/color-theme-x"))])
+ (colorless-themes . [(20210102 1035) ((emacs (24 1))) "A macro to generate mostly colorless themes" single ((:commit . "c1ed1e12541cf05cc6c558d23c089c07e10b54d7") (:authors ("Thomas Letan" . "contact@thomasletan.fr")) (:maintainer "Thomas Letan" . "contact@thomasletan.fr") (:keywords "faces themes" "faces") (:url . "https://git.sr.ht/~lthms/colorless-themes.el"))])
+ (colormaps . [(20171008 2224) ((emacs (25))) "Hex colormaps" single ((:commit . "19fbb64a6288d505b9cf45c9b5a3eed0bfb135e2") (:authors ("Abhinav Tushar" . "lepisma@fastmail.com")) (:maintainer "Abhinav Tushar" . "lepisma@fastmail.com") (:keywords "tools") (:url . "https://github.com/lepisma/colormaps.el"))])
+ (column-enforce-mode . [(20200605 1933) nil "Highlight text that extends beyond a column" single ((:commit . "14a7622f2268890e33536ccd29510024d51ee96f") (:authors ("Jordon Biondo")) (:maintainer "Jordon Biondo") (:url . "www.github.com/jordonbiondo/column-enforce-mode"))])
+ (com-css-sort . [(20201002 1430) ((emacs (25 1)) (s (1 12 0))) "Common way of sorting the CSS attributes" single ((:commit . "fa85a6b9d852d725730a6ad1cc5afeb4ede93ca7") (:authors ("Shen, Jen-Chieh" . "jcs090218@gmail.com")) (:maintainer "Shen, Jen-Chieh" . "jcs090218@gmail.com") (:url . "https://github.com/jcs090218/com-css-sort"))])
+ (comb . [(20201010 1147) ((emacs (25 1))) "Interactive code auditing and grep tool" tar ((:commit . "31f3e94afb2a7f7d18d30c2468a0c683700f7a66") (:authors ("Andrea Cardaci" . "cyrus.and@gmail.com")) (:maintainer "Andrea Cardaci" . "cyrus.and@gmail.com") (:keywords "matching") (:url . "https://github.com/cyrus-and/comb"))])
+ (comby . [(20200629 140) ((emacs (25 1))) "Emacs comby integration" single ((:commit . "928b8b8959a2556aba5526f2a25801341eb59dc3") (:authors ("Sergey Kostyaev" . "feo.me@ya.ru")) (:maintainer "Sergey Kostyaev" . "feo.me@ya.ru") (:keywords "languages") (:url . "https://github.com/s-kostyaev/comby.el"))])
+ (comint-hyperlink . [(20211026 100) ((emacs (24 3))) "Create hyperlinks in comint for SGR URL control sequences" single ((:commit . "905f2db1f95950899301b9f71faed9e9362cf5dc") (:authors ("Matthew Bauer" . "mjbauer95@gmail.com")) (:maintainer "Matthew Bauer" . "mjbauer95@gmail.com") (:keywords "comint" "shell" "processes" "hypermedia" "terminals") (:url . "https://github.com/matthewbauer/comint-hyperlink"))])
+ (comint-intercept . [(20200106 454) ((emacs (24 3))) "Intercept input in comint-mode" single ((:commit . "3c9a6125e450435b79ab5e6466f830e57c5e0a30") (:authors ("\"Huang, Ying\"" . "huang.ying.caritas@gmail.com")) (:maintainer "\"Huang, Ying\"" . "huang.ying.caritas@gmail.com") (:keywords "processes" "terminals") (:url . "https://github.com/hying-caritas/comint-intercept"))])
+ (command-log-mode . [(20160413 447) nil "log keyboard commands to buffer" single ((:commit . "af600e6b4129c8115f464af576505ea8e789db27") (:authors ("Michael Weber" . "michaelw@foldr.org")) (:maintainer "Michael Weber" . "michaelw@foldr.org") (:keywords "help") (:url . "https://github.com/lewang/command-log-mode"))])
+ (command-queue . [(20160328 1725) ((emacs (24 3))) "shell command queue" single ((:commit . "f327c6f852592229a755ec6de0c62c6aeafd6659") (:authors ("Yuki INOUE <inouetakahiroki at gmail.com>")) (:maintainer "Yuki INOUE <inouetakahiroki at gmail.com>") (:url . "https://github.com/Yuki-Inoue/command-queue"))])
+ (commander . [(20140120 1852) ((s (1 6 0)) (dash (2 0 0)) (cl-lib (0 3)) (f (0 6 1))) "Emacs command line parser" single ((:commit . "9ba1456b0a389a2f7b42b6f42a4208ddd87ce609") (:authors ("Johan Andersson" . "johan.rejeep@gmail.com")) (:maintainer "Johan Andersson" . "johan.rejeep@gmail.com") (:keywords "cli" "argv") (:url . "http://github.com/rejeep/commander.el"))])
+ (comment-dwim-2 . [(20210101 1820) ((emacs (24 4))) "An all-in-one comment command to rule them all" single ((:commit . "7cdafd6d98234a7402865b8abdae54a2f2551c94") (:authors ("Rémy Ferré" . "dev@remyferre.net")) (:maintainer "Rémy Ferré" . "dev@remyferre.net") (:keywords "convenience") (:url . "https://github.com/remyferre/comment-dwim-2"))])
+ (comment-or-uncomment-sexp . [(20190225 1122) ((emacs (24))) "Command for commenting the sexp under point." single ((:commit . "bec730d3fc1e6c17ff1339eb134af16c034a4d95") (:authors ("Artur Malabarba" . "artur@endlessparentheses.com")) (:maintainer "Artur Malabarba" . "artur@endlessparentheses.com") (:keywords "convenience") (:url . "https://github.com/Malabarba/comment-or-uncomment-sexp"))])
+ (comment-tags . [(20170910 1735) ((emacs (24 5))) "Highlight & navigate comment tags like 'TODO'." single ((:commit . "7d914097f0a03484af71e621db533737fc692f58") (:authors ("Vincent Dumas" . "vincekd@gmail.com")) (:maintainer "Vincent Dumas" . "vincekd@gmail.com") (:keywords "convenience" "comments" "tags") (:url . "https://github.com/vincekd/comment-tags"))])
+ (commentary-theme . [(20210714 1757) ((emacs (24))) "A minimal theme with contrasting comments" single ((:commit . "a73e1256f667065933e96bd6032c463cb115201d") (:url . "https://github.com/pzel/commentary-theme"))])
+ (commenter . [(20160219 1627) ((emacs (24 4)) (let-alist (1 0 4))) "multiline-comment support package" single ((:commit . "6d1885419434ba779270c6fda0e30d390bb074bd") (:authors ("Yuta Yamada <cokesboy\"at\"gmail.com>")) (:maintainer "Yuta Yamada <cokesboy\"at\"gmail.com>") (:keywords "comment") (:url . "https://github.com/yuutayamada/commenter"))])
+ (commify . [(20210904 1106) ((s (1 9 0))) "Toggle grouping commas in numbers" single ((:commit . "d6656bd3a909917a51ba033a11d4ab5f5fe55f83") (:authors ("Daniel E. Doherty" . "ded-commify@ddoherty.net")) (:maintainer "Daniel E. Doherty" . "ded-commify@ddoherty.net") (:keywords "convenience" "editing" "numbers" "grouping" "commas") (:url . "https://github.com/ddoherty03/commify"))])
+ (common-lisp-snippets . [(20180226 1523) ((yasnippet (0 8 0))) "Yasnippets for Common Lisp" tar ((:commit . "c82ebf18f4ad49f390dd96ffcc59f8683c1a868b") (:authors ("Mark Karpov" . "markkarpov92@gmail.com")) (:maintainer "Mark Karpov" . "markkarpov92@gmail.com") (:keywords "snippets") (:url . "https://github.com/mrkkrp/common-lisp-snippets"))])
+ (company . [(20220425 1145) ((emacs (25 1))) "Modular text completion framework" tar ((:commit . "d5145006b948f93e673f439a766da01f636d39fc") (:authors ("Nikolaj Schumacher")) (:maintainer "Dmitry Gutov" . "dgutov@yandex.ru") (:keywords "abbrev" "convenience" "matching") (:url . "http://company-mode.github.io/"))])
+ (company-anaconda . [(20200404 1859) ((company (0 8 0)) (anaconda-mode (0 1 1)) (cl-lib (0 5 0)) (dash (2 6 0)) (s (1 9))) "Anaconda backend for company-mode" single ((:commit . "da1566db41a68809ef7f91ebf2de28118067c89b") (:authors ("Artem Malyshev" . "proofit404@gmail.com")) (:maintainer "Artem Malyshev" . "proofit404@gmail.com") (:url . "https://github.com/proofit404/anaconda-mode"))])
+ (company-ansible . [(20200306 1441) ((emacs (24 4)) (company (0 8 12))) "A company back-end for ansible" tar ((:commit . "79dd421b161efa49fbdffad57fa40edb41f484a3") (:authors ("Krzysztof Magosa" . "krzysztof@magosa.pl")) (:maintainer "Krzysztof Magosa" . "krzysztof@magosa.pl") (:keywords "ansible") (:url . "https://github.com/krzysztof-magosa/company-ansible"))])
+ (company-arduino . [(20160306 1739) ((emacs (24 1)) (company (0 8 0)) (irony (0 1 0)) (cl-lib (0 5)) (company-irony (0 1 0)) (company-c-headers (20140930)) (arduino-mode (1 0))) "company-mode for Arduino" single ((:commit . "d7e369702b8eee63e6dfdeba645ce28b6dc66fb1") (:authors ("Yuta Yamada" . "sleepboy.zzz@gmail.com")) (:maintainer "Yuta Yamada" . "sleepboy.zzz@gmail.com") (:keywords "convenience" "development" "company") (:url . "https://github.com/yuutayamada/company-arduino"))])
+ (company-auctex . [(20200529 1835) ((yasnippet (0 8 0)) (company (0 8 0)) (auctex (11 87))) "Company-mode auto-completion for AUCTeX" single ((:commit . "9400a2ec7459dde8cbf1a5d50dfee4e300ed7e18") (:authors ("Christopher Monsanto <chris@monsan.to>, Alexey Romanov" . "alexey.v.romanov@gmail.com")) (:maintainer "Christopher Monsanto <chris@monsan.to>, Alexey Romanov" . "alexey.v.romanov@gmail.com") (:url . "https://github.com/alexeyr/company-auctex/"))])
+ (company-axiom . [(20191027 1928) ((emacs (24)) (company (0 9)) (axiom-environment (20171021))) "A company-mode backend for the axiom-environment system" single ((:commit . "e60de5ed107ffeb530a56d24d04f38988124d12b") (:authors ("Paul Onions" . "paul.onions@acm.org")) (:maintainer "Paul Onions" . "paul.onions@acm.org") (:keywords "axiom" "openaxiom" "fricas" "axiom-environment"))])
+ (company-bibtex . [(20171105 644) ((company (0 9 0)) (cl-lib (0 5)) (parsebib (1 0))) "Company completion for bibtex keys" single ((:commit . "da67faf3a6faba8e7f1b222dedfc5521b02c7655") (:authors ("GB Gardner" . "gbgar@users.noreply.github.com")) (:maintainer "GB Gardner" . "gbgar@users.noreply.github.com") (:keywords "company-mode" "bibtex") (:url . "https://github.com/gbgar/company-bibtex"))])
+ (company-box . [(20211020 2007) ((emacs (26 0 91)) (dash (2 19 0)) (company (0 9 6)) (frame-local (0 0 1))) "Company front-end with icons" tar ((:commit . "f9cbbc7df8efbb56a8d31a5b422d158660d9109e") (:authors ("Sebastien Chapuis" . "sebastien@chapu.is")) (:maintainer "Sebastien Chapuis" . "sebastien@chapu.is") (:keywords "company" "completion" "front-end" "convenience") (:url . "https://github.com/sebastiencs/company-box"))])
+ (company-c-headers . [(20190825 1631) ((emacs (24 1)) (company (0 8))) "Company mode backend for C/C++ header files" single ((:commit . "9d384571b1190e99d0a789e5296176d69a3d0771") (:authors ("Alastair Rankine" . "alastair@girtby.net")) (:maintainer "Alastair Rankine" . "alastair@girtby.net") (:keywords "development" "company"))])
+ (company-cabal . [(20170917 1317) ((cl-lib (0 5)) (company (0 8 0)) (emacs (24))) "company-mode cabal backend" tar ((:commit . "62112a7259e24bd6c08885629a185afe512b7d3d") (:authors ("Iku Iwasa" . "iku.iwasa@gmail.com")) (:maintainer "Iku Iwasa" . "iku.iwasa@gmail.com") (:url . "https://github.com/iquiw/company-cabal"))])
+ (company-coq . [(20220314 526) ((cl-lib (0 5)) (dash (2 12 1)) (yasnippet (0 11 0)) (company (0 8 12)) (company-math (1 1))) "A collection of extensions for Proof General's Coq mode" tar ((:commit . "a6e349e0131f676a885bd14c908fd26054b2df42") (:authors ("Clément Pit-Claudel" . "clement.pitclaudel@live.com")) (:maintainer "Clément Pit-Claudel" . "clement.pitclaudel@live.com") (:keywords "convenience" "languages") (:url . "https://github.com/cpitclaudel/company-coq"))])
+ (company-ctags . [(20211211 338) ((emacs (25 1)) (company (0 9 0))) "Fastest company-mode completion backend for ctags" single ((:commit . "313508ba5d4f1e4b5d5d554faaa74076201c3248") (:authors ("Chen Bin" . "chenbin.sh@gmail.com")) (:maintainer "Chen Bin" . "chenbin.sh@gmail.com") (:keywords "convenience") (:url . "https://github.com/redguardtoo/company-ctags"))])
+ (company-dcd . [(20210307 649) ((company (0 9)) (flycheck-dmd-dub (0 7)) (yasnippet (0 8)) (popwin (0 7)) (cl-lib (0 5)) (ivy (20160804 326))) "Company backend for Dlang using DCD." single ((:commit . "858500115d4f0285f963698ede9492f409a90e52") (:authors ("tsukimizake <shomasd_at_gmail.com>")) (:maintainer "tsukimizake <shomasd_at_gmail.com>") (:keywords "languages") (:url . "http://github.com/tsukimizake/company-dcd"))])
+ (company-dict . [(20190302 5) ((emacs (24 4)) (company (0 8 12)) (parent-mode (2 3))) "A backend that emulates ac-source-dictionary" single ((:commit . "cd7b8394f6014c57897f65d335d6b2bd65dab1f4") (:authors ("Henrik Lissner <http://github/hlissner>")) (:maintainer "Henrik Lissner" . "henrik@lissner.net") (:keywords "company" "dictionary" "ac-source-dictionary") (:url . "https://github.com/hlissner/emacs-company-dict"))])
+ (company-distel . [(20180827 1344) ((distel-completion-lib (1 0 0))) "Erlang/distel completion backend for company-mode" single ((:commit . "acc4c0a5521904203d797fe96b08e5fae4233c7e") (:authors ("Sebastian Weddmark Olsson")) (:maintainer "Sebastian Weddmark Olsson") (:keywords "erlang" "distel" "company") (:url . "github.com/sebastiw/distel-completion"))])
+ (company-emacs-eclim . [(20180911 1121) ((eclim (0 3)) (company (0 7)) (cl-lib (0 5))) "Eclim company backend" single ((:commit . "222ddd48fcf0ee01592dec77c58e0cf3f2ea1100"))])
+ (company-emoji . [(20210427 2151) ((cl-lib (0 5)) (company (0 8 0))) "company-mode backend for emoji" tar ((:commit . "90594eb58b20fb937cfd4e946efcc446ee630e6f") (:authors ("Alex Dunn" . "dunn.alex@gmail.com")) (:maintainer "Alex Dunn" . "dunn.alex@gmail.com") (:keywords "emoji" "company") (:url . "https://github.com/dunn/company-emoji.git"))])
+ (company-emojify . [(20210718 424) ((emacs (26 1)) (company (0 8 0)) (emojify (1 2 1)) (ht (2 0))) "Company completion for Emojify" single ((:commit . "6f095b419468b0443e1dcd8537ef4b84092f155c") (:authors ("Shen, Jen-Chieh" . "jcs090218@gmail.com")) (:maintainer "Shen, Jen-Chieh" . "jcs090218@gmail.com") (:url . "https://github.com/jcs-elpa/company-emojify"))])
+ (company-erlang . [(20170123 538) ((emacs (24 4)) (ivy-erlang-complete (0 1)) (company (0 9 2))) "company backend based on ivy-erlang-complete" single ((:commit . "bc0524a16f17b66c7397690e4ca0e004f09ea6c5") (:authors ("Sergey Kostyaev" . "feo.me@ya.ru")) (:maintainer "Sergey Kostyaev" . "feo.me@ya.ru") (:keywords "tools"))])
+ (company-flow . [(20180225 2159) ((company (0 8 0)) (dash (2 13 0))) "Flow backend for company-mode" single ((:commit . "76ef585c70d2a3206c2eadf24ba61e59124c3a16") (:authors ("Aaron Jensen" . "aaronjensen@gmail.com")) (:maintainer "Aaron Jensen" . "aaronjensen@gmail.com") (:url . "https://github.com/aaronjensen/company-flow"))])
+ (company-flx . [(20180103 518) ((emacs (24)) (company (0 8 12)) (flx (0 5))) "flx based fuzzy matching for company" single ((:commit . "16ca0d2f84e8e768bf2db8c5cfe421230a00bded") (:authors ("PythonNut" . "pythonnut@pythonnut.com")) (:maintainer "PythonNut" . "pythonnut@pythonnut.com") (:keywords "convenience" "company" "fuzzy" "flx") (:url . "https://github.com/PythonNut/company-flx"))])
+ (company-fuzzy . [(20220409 1753) ((emacs (26 1)) (company (0 8 12)) (s (1 12 0)) (ht (2 0))) "Fuzzy matching for `company-mode'" single ((:commit . "e2e8a39976506cbf149f9c62a69c7a438be09579") (:authors ("Shen, Jen-Chieh" . "jcs090218@gmail.com")) (:maintainer "Shen, Jen-Chieh" . "jcs090218@gmail.com") (:url . "https://github.com/jcs-elpa/company-fuzzy"))])
+ (company-ghci . [(20190707 311) ((company (0 8 11)) (haskell-mode (13))) "company backend which uses the current ghci process." single ((:commit . "a1d25652583ab4666c5a78cac18cd8039776b50d") (:authors ("Hector Orellana" . "hofm92@gmail.com")) (:maintainer "Hector Orellana" . "hofm92@gmail.com"))])
+ (company-glsl . [(20210109 1403) ((company (0 9 4)) (glsl-mode (2 4)) (emacs (24 4))) "Support glsl in company-mode" single ((:commit . "3a40501ba831a30a7fd3e8529b20d1305d0454aa") (:authors ("Guido Schmidt" . "git@guidoschmidt.cc")) (:maintainer "Guido Schmidt" . "git@guidoschmidt.cc") (:url . "https://github.com/guidoschmidt/company-glsl"))])
+ (company-go . [(20170825 1643) ((company (0 8 0)) (go-mode (1 0 0))) "company-mode backend for Go (using gocode)" single ((:commit . "31948b463f2fc18f8801e5a8fe511fef300eb3dd") (:authors ("nsf" . "no.smile.face@gmail.com")) (:maintainer "nsf" . "no.smile.face@gmail.com") (:keywords "languages"))])
+ (company-inf-ruby . [(20140805 2054) ((company (0 6 10)) (inf-ruby (2 2 7)) (emacs (24 1))) "company-mode completion back-end for inf-ruby" single ((:commit . "fe3e4863bc971fbb81edad447efad5795ead1b17") (:authors ("Dmitry Gutov" . "dgutov@yandex.ru")) (:maintainer "Dmitry Gutov" . "dgutov@yandex.ru") (:url . "https://github.com/company-mode/company-inf-ruby"))])
+ (company-ipa . [(20210307 1838) ((emacs (24 3)) (company (0 8 12))) "IPA backend for company" single ((:commit . "8634021cac885f53f3274ef6dcce7eab19321046") (:authors ("Matías Guzmán Naranjo" . "mguzmann89@gmail.com")) (:maintainer "Matías Guzmán Naranjo" . "mguzmann89@gmail.com") (:keywords "convenience" "company" "ipa") (:url . "https://github.com/mguzmann/company-ipa"))])
+ (company-irony . [(20190124 2346) ((emacs (24 1)) (company (0 8 0)) (irony (1 1 0)) (cl-lib (0 5))) "company-mode completion back-end for irony-mode" single ((:commit . "b44711dfce445610c1ffaec4951c6ff3882b216a") (:authors ("Guillaume Papin" . "guillaume.papin@epitech.eu")) (:maintainer "Guillaume Papin" . "guillaume.papin@epitech.eu") (:keywords "convenience") (:url . "https://github.com/Sarcasm/company-irony/"))])
+ (company-irony-c-headers . [(20151018 909) ((cl-lib (0 5)) (company (0 9 0)) (irony (0 2 0))) "Company mode backend for C/C++ header files with Irony" single ((:commit . "72c386aeb079fb261d9ec02e39211272f76bbd97") (:authors ("Yutian Li" . "hotpxless@gmail.com")) (:maintainer "Yutian Li" . "hotpxless@gmail.com") (:keywords "c" "company") (:url . "https://github.com/hotpxl/company-irony-c-headers"))])
+ (company-jedi . [(20200324 25) ((emacs (24)) (cl-lib (0 5)) (company (0 8 11)) (jedi-core (0 2 7))) "Company-mode completion back-end for Python JEDI" single ((:commit . "ea22b1f7a980c49aaf2c5e840e4536577f6602f6") (:authors ("Boy" . "boyw165@gmail.com")) (:maintainer "Neil Okamoto" . "neil.okamoto+melpa@gmail.com") (:url . "https://github.com/emacsorphanage/company-jedi"))])
+ (company-lean . [(20210305 1705) ((emacs (24 3)) (dash (2 18 0)) (s (1 10 0)) (f (0 19 0)) (company (0 9 3)) (lean-mode (3 3 0))) "A company backend for lean-mode" single ((:commit . "362bc6fa3efb1874c525ed6b4b6f24f76af22596") (:authors ("Leonardo de Moura" . "leonardo@microsoft.com") ("Soonho Kong " . "soonhok@cs.cmu.edu") ("Gabriel Ebner " . "gebner@gebner.org") ("Sebastian Ullrich" . "sebasti@nullri.ch")) (:maintainer "Sebastian Ullrich" . "sebasti@nullri.ch") (:keywords "languages") (:url . "https://github.com/leanprover/lean-mode"))])
+ (company-ledger . [(20210910 250) ((emacs (24 3)) (company (0 8 0))) "Fuzzy auto-completion for Ledger & friends" single ((:commit . "c6911b7e39b29c0d5f2541392ff485b0f53fd366") (:authors ("Debanjum Singh Solanky <debanjum AT gmail DOT com>")) (:maintainer "Debanjum Singh Solanky <debanjum AT gmail DOT com>") (:keywords "abbrev" "matching" "auto-complete" "beancount" "ledger" "company") (:url . "https://github.com/debanjum/company-ledger"))])
+ (company-lua . [(20171108 2306) ((company (0 8 12)) (s (1 10 0)) (f (0 17 0)) (lua-mode (20151025))) "Company backend for Lua" tar ((:commit . "29f6819de4d691e5fd0b62893a9f4fbc1c6fcb52") (:authors ("Peter Vasil" . "mail@petervasil.net")) (:maintainer "Peter Vasil" . "mail@petervasil.net"))])
+ (company-manually . [(20200709 913) ((emacs (24 3)) (company (0 9 0)) (ivy (0 13 0))) "A company backend that lets you manually build candidates" single ((:commit . "44c7a655e5f2a462835a96d1f0ed2ce434848416") (:authors ("Yanghao Xie")) (:maintainer "Yanghao Xie" . "yhaoxie@gmail.com") (:keywords "convenience" "company-mode" "manually build candidates") (:url . "https://github.com/yanghaoxie/company-manually"))])
+ (company-math . [(20210731 2019) ((company (0 8 0)) (math-symbol-lists (1 3))) "Completion backends for unicode math symbols and latex tags" single ((:commit . "45778f5731c97a21a83e3b965cbde42018709afd") (:authors ("Vitalie Spinu" . "spinuvit@gmail.com")) (:maintainer "Vitalie Spinu" . "spinuvit@gmail.com") (:keywords "unicode" "symbols" "completion") (:url . "https://github.com/vspinu/company-math"))])
+ (company-maxima . [(20210520 2034) ((emacs (25 1)) (maxima (0 6 1)) (seq (2 20)) (company (0 9 13))) "Maxima company integration" single ((:commit . "ce5fd160c193e387d9e2bacdba4065c4b4262cb1") (:authors ("Fermin Munoz")) (:maintainer "Fermin Munoz" . "fmfs@posteo.net") (:keywords "languages" "tools" "convenience") (:url . "https://gitlab.com/sasanidas/maxima"))])
+ (company-nand2tetris . [(20171201 1813) ((nand2tetris (1 1 0)) (company (0 5)) (cl-lib (0 5 0))) "Company backend for nand2tetris major mode" single ((:commit . "33acee34d24b1c6a87db833b7d23449cf858f64f") (:authors ("Diego Berrocal" . "cestdiego@gmail.com")) (:maintainer "Diego Berrocal" . "cestdiego@gmail.com") (:keywords "nand2tetris" "hdl" "company") (:url . "http://www.github.com/CestDiego/nand2tetris.el/"))])
+ (company-native-complete . [(20220103 1622) ((emacs (26 1)) (company (0 9 0)) (native-complete (0 1 0))) "Company completion using native-complete" single ((:commit . "01d8a2048e13f29dd3aa06281ac8cb466caddb64") (:authors ("Troy Hinckley" . "troy.hinckley@gmail.com")) (:maintainer "Troy Hinckley" . "troy.hinckley@gmail.com") (:url . "https://github.com/CeleritasCelery/emacs-native-shell-complete"))])
+ (company-nginx . [(20220210 1411) ((emacs (24)) (cl-lib (0)) (company (0))) "company-mode keywords support for nginx-mode" single ((:commit . "8a9f1a5653fe2d9a5042bfb9377d54f37fcc64c8") (:keywords "company" "nginx") (:url . "https://repo.or.cz/company-nginx.git"))])
+ (company-ngram . [(20170129 1913) ((cl-lib (0 5)) (company (0 8 0))) "N-gram based completion" tar ((:commit . "09a68b802e64799e95f205b438d469bbd78cd2e6") (:authors ("kshramt")) (:maintainer "kshramt") (:url . "https://github.com/kshramt/company-ngram"))])
+ (company-nixos-options . [(20160215 857) ((company (0 8 0)) (nixos-options (0 0 1)) (cl-lib (0 5 0))) "Company Backend for nixos-options" single ((:commit . "053a2d5110ce05b7f99bcc2ac4804b70cbe87916") (:authors ("Diego Berrocal" . "cestdiego@gmail.com") ("Travis B. Hartwell" . "nafai@travishartwell.net")) (:maintainer "Diego Berrocal" . "cestdiego@gmail.com") (:keywords "unix") (:url . "http://www.github.com/travisbhartwell/nix-emacs/"))])
+ (company-org-block . [(20210825 2107) ((emacs (25 1)) (company (0 8 0)) (org (9 2 0))) "Org blocks company backend" single ((:commit . "115af0a3625f4669358eca568466d468cacc78bd") (:authors ("Alvaro Ramirez")) (:maintainer "Alvaro Ramirez") (:url . "https://github.com/xenodium/company-org-block"))])
+ (company-php . [(20211204 558) ((cl-lib (0 5)) (ac-php-core (2 0)) (company (0 9))) "A company back-end for PHP." single ((:commit . "f34e09783b77d1158ea139b7b3d8034bc52b0b9f") (:authors ("jim" . "xcwenn@qq.com")) (:maintainer "jim") (:keywords "completion" "convenience" "intellisense") (:url . "https://github.com/xcwen/ac-php"))])
+ (company-phpactor . [(20200121 1218) ((emacs (24 3)) (company (0 9 6)) (phpactor (0 1 0))) "company-mode backend for Phpactor" single ((:commit . "34195f1533209e2ffd0f898a69c7db2bffd1eabe") (:authors ("Martin Tang" . "martin.tang365@gmail.com") ("Mikael Kermorgant" . "mikael@kgtech.fi")) (:maintainer "Martin Tang" . "martin.tang365@gmail.com") (:keywords "tools" "php") (:url . "https://github.com/emacs-php/phpactor.el"))])
+ (company-plisp . [(20200531 1927) ((emacs (25)) (s (1 2 0)) (company (0 8 12)) (dash (2 12 0)) (cl-lib (0 5))) "Company mode backend for PicoLisp language" tar ((:commit . "fc0b56d2a711340ca3e63119bfe692bb3e8620fb") (:authors ("Fermin MF" . "fmfs@posteo.net")) (:maintainer "Fermin MF" . "fmfs@posteo.net") (:keywords "company" "plisp" "convenience" "auto-completion") (:url . "https://gitlab.com/sasanidas/company-plisp"))])
+ (company-plsense . [(20180118 58) ((company (0 9 3)) (cl-lib (0 5 0)) (dash (2 12 0)) (s (1 12)) (emacs (24))) "Company backend for Perl" single ((:commit . "b48e3181e08ec597269621d621aa06636f02d883") (:authors ("Troy Hinckley" . "troy.hinckley@gmail.com")) (:maintainer "Troy Hinckley" . "troy.hinckley@gmail.com") (:url . "https://github.com/CeleritasCelery/company-plsense"))])
+ (company-pollen . [(20160812 1510) ((company (0 9 0)) (pollen-mode (1 0))) "company-mode completion backend for pollen" single ((:commit . "09a9dc48c468dcd385982b9629f325e70d569faf") (:authors ("Junsong Li <ljs.darkfish AT GMAIL>")) (:maintainer "Junsong Li") (:keywords "languages" "pollen" "pollenpub" "company") (:url . "https://github.com/lijunsong/pollen-mode"))])
+ (company-posframe . [(20220331 2141) ((emacs (26 0)) (company (0 9 0)) (posframe (0 9 0))) "Use a posframe as company candidate menu" single ((:commit . "df0e34f69dc8e9aaa1a6c5e88783898f4ae3f2df") (:authors ("Clément Pit-Claudel, Feng Shu, Lars Andersen" . "expez@expez.com")) (:maintainer "Feng Shu" . "tumashu@163.com") (:keywords "abbrev" "convenience" "matching") (:url . "https://github.com/tumashu/company-posframe"))])
+ (company-prescient . [(20211228 417) ((emacs (25 1)) (prescient (5 2)) (company (0 9 6))) "prescient.el + Company" single ((:commit . "d9b30d741c729a37eb2c6e51d72281c0844780ca") (:authors ("Radon Rosborough" . "radon.neon@gmail.com")) (:maintainer "Radon Rosborough" . "radon.neon@gmail.com") (:keywords "extensions") (:url . "https://github.com/raxod502/prescient.el"))])
+ (company-qml . [(20170428 1708) ((qml-mode (0 1)) (company (0 8 12))) "Company backend for QML files" tar ((:commit . "4af4f32a7ad86d86bb9293fb0b675aec513b5736") (:authors ("Junpeng Qiu" . "qjpchmail@gmail.com")) (:maintainer "Junpeng Qiu" . "qjpchmail@gmail.com") (:keywords "extensions"))])
+ (company-quickhelp . [(20211115 1335) ((emacs (24 3)) (company (0 8 9)) (pos-tip (0 4 6))) "Popup documentation for completion candidates" single ((:commit . "3ca2708b4e5190205aca01d65fe1b391963a53f9") (:authors ("Lars Andersen" . "expez@expez.com")) (:maintainer "Lars Andersen" . "expez@expez.com") (:keywords "company" "popup" "documentation" "quickhelp") (:url . "https://www.github.com/expez/company-quickhelp"))])
+ (company-quickhelp-terminal . [(20210715 1010) ((emacs (24 4)) (company-quickhelp (2 2 0)) (popup (0 5 3))) "Terminal support for `company-quickhelp'" single ((:commit . "75a2f5c7669833646fc653cabd531737b52fb469") (:authors ("Shen, Jen-Chieh" . "jcs090218@gmail.com")) (:maintainer "Shen, Jen-Chieh" . "jcs090218@gmail.com") (:url . "https://github.com/jcs-elpa/company-quickhelp-terminal"))])
+ (company-racer . [(20171205 310) ((emacs (24 4)) (cl-lib (0 5)) (company (0 8 0)) (deferred (0 3 1))) "Company integration for racer" single ((:commit . "a00381c9d416f375f783fcb6ae8d40669ce1f567") (:authors ("Mario Rodas" . "marsam@users.noreply.github.com")) (:maintainer "Mario Rodas" . "marsam@users.noreply.github.com") (:keywords "convenience") (:url . "https://github.com/emacs-pe/company-racer"))])
+ (company-reftex . [(20210418 1316) ((emacs (25 1)) (s (1 12)) (company (0 8))) "Company backend based on RefTeX." single ((:commit . "42eb98c6504e65989635d95ab81b65b9d5798e76") (:authors ("Eivind Fonn" . "evfonn@gmail.com")) (:maintainer "Eivind Fonn" . "evfonn@gmail.com") (:keywords "bib" "tex" "company" "latex" "reftex" "references" "labels" "citations") (:url . "https://github.com/TheBB/company-reftex"))])
+ (company-restclient . [(20190426 1312) ((cl-lib (0 5)) (company (0 8 0)) (emacs (24)) (know-your-http-well (0 2 0)) (restclient (0 0 0))) "company-mode completion back-end for restclient-mode" single ((:commit . "e5a3ec54edb44776738c13e13e34c85b3085277b") (:authors ("Iku Iwasa" . "iku.iwasa@gmail.com")) (:maintainer "Iku Iwasa" . "iku.iwasa@gmail.com") (:url . "https://github.com/iquiw/company-restclient"))])
+ (company-rtags . [(20191222 920) ((emacs (24 3)) (company (0 8 1)) (rtags (2 10))) "RTags back-end for company" single ((:commit . "db39790fda5c2443bc790b8971ac140914f7e9c2") (:authors ("Jan Erik Hanssen" . "jhanssen@gmail.com") ("Anders Bakken" . "agbakken@gmail.com")) (:maintainer "Jan Erik Hanssen" . "jhanssen@gmail.com") (:url . "https://github.com/Andersbakken/rtags"))])
+ (company-shell . [(20211013 1725) ((emacs (24 4)) (company (0 8 12)) (dash (2 12 0)) (cl-lib (0 5))) "Company mode backend for shell functions" single ((:commit . "a77f4de75912aa87314cde92c603b831d5050246") (:authors ("Alexander Miller" . "alexanderm@web.de")) (:maintainer "Alexander Miller" . "alexanderm@web.de") (:keywords "company" "shell" "auto-completion") (:url . "https://github.com/Alexander-Miller/company-shell"))])
+ (company-solidity . [(20181117 1518) ((company (0 9 0)) (cl-lib (0 5 0)) (solidity-mode (0 1 9))) "Company-mode back-end for solidity-mode" single ((:commit . "20fb77e089e10187b37ae1a94153017b82ed2a0a") (:authors ("Samuel Smolkin" . "sam@future-precedent.org")) (:maintainer "Samuel Smolkin" . "sam@future-precedent.org") (:keywords "solidity" "completion" "company") (:url . "https://github.com/ethereum/emacs-solidity"))])
+ (company-sourcekit . [(20210430 2155) ((emacs (24 3)) (company (0 8 12)) (dash (2 18 0)) (sourcekit (0 2 0))) "company-mode completion backend for SourceKit" single ((:commit . "a1860ad4dd3a542acd2fa0dfac2a388cbdf4af0c") (:authors ("Nathan Kot" . "nk@nathankot.com")) (:maintainer "Nathan Kot" . "nk@nathankot.com") (:keywords "abbrev") (:url . "https://github.com/nathankot/company-sourcekit"))])
+ (company-stan . [(20211129 2051) ((emacs (24 3)) (company (0 9 10)) (stan-mode (10 3 0))) "A company-mode completion backend for stan" single ((:commit . "150bbbe5fd3ad2b5a3dbfba9d291e66eeea1a581") (:authors ("Kazuki Yoshida" . "kazukiyoshida@mail.harvard.edu")) (:maintainer "Kazuki Yoshida" . "kazukiyoshida@mail.harvard.edu") (:keywords "languages") (:url . "https://github.com/stan-dev/stan-mode/tree/master/company-stan"))])
+ (company-statistics . [(20170210 1933) ((emacs (24 3)) (company (0 8 5))) "Sort candidates using completion history" single ((:commit . "e62157d43b2c874d2edbd547c3bdfb05d0a7ae5c") (:authors ("Ingo Lohmar" . "i.lohmar@gmail.com")) (:maintainer "Ingo Lohmar" . "i.lohmar@gmail.com") (:keywords "abbrev" "convenience" "matching") (:url . "https://github.com/company-mode/company-statistics"))])
+ (company-suggest . [(20200911 1845) ((company (0 9 0)) (emacs (25 1))) "Company-mode back-end for search engine suggests" single ((:commit . "1c89c9de3852f07ce28b0bedf1fbf56fe6eedcdc") (:authors ("Jürgen Hötzel" . "juergen@archlinux.org")) (:maintainer "Jürgen Hötzel" . "juergen@archlinux.org") (:keywords "completion" "convenience") (:url . "https://github.com/juergenhoetzel/company-suggest"))])
+ (company-tabnine . [(20210310 2247) ((emacs (25)) (company (0 9 3)) (cl-lib (0 5)) (dash (2 16 0)) (s (1 12 0)) (unicode-escape (1 1))) "A company-mode backend for TabNine" single ((:commit . "98e9e8b38b6ca289fbe265b0a7b62c7fe38ed0e2") (:authors ("Tommy Xiang" . "tommyx058@gmail.com")) (:maintainer "Tommy Xiang" . "tommyx058@gmail.com") (:keywords "convenience") (:url . "https://github.com/TommyX12/company-tabnine/"))])
+ (company-terraform . [(20190607 1037) ((emacs (24 4)) (company (0 8 12)) (terraform-mode (0 6))) "A company backend for terraform" tar ((:commit . "2d11a21fee2f298e48968e479ddcaeda4d736e12") (:authors ("Rafał Cieślak" . "rafalcieslak256@gmail.com")) (:maintainer "Rafał Cieślak" . "rafalcieslak256@gmail.com") (:keywords "abbrev" "convenience" "terraform" "company") (:url . "https://github.com/rafalcieslak/emacs-company-terraform"))])
+ (company-try-hard . [(20200417 1603) ((emacs (24 3)) (company (0 8 0)) (dash (2 0))) "get all completions from company backends" single ((:commit . "2b41136b5ed6e02032d99bcdb0599ecf00394fa5") (:authors ("Wilfred Hughes" . "me@wilfred.me.uk")) (:maintainer "Wilfred Hughes" . "me@wilfred.me.uk") (:keywords "matching") (:url . "https://github.com/Wilfred/company-try-hard"))])
+ (company-web . [(20220115 2146) ((company (0 8 0)) (dash (2 8 0)) (cl-lib (0 5 0)) (web-completion-data (0 1 0))) "Company version of ac-html, complete for web,html,emmet,jade,slim modes" tar ((:commit . "863fb84b81ed283474e50330cd8d27b1ca0d74f1") (:authors ("Olexandr Sydorchuk" . "olexandr.syd@gmail.com")) (:maintainer "Olexandr Sydorchuk" . "olexandr.syd@gmail.com") (:keywords "html" "company") (:url . "https://github.com/osv/company-web"))])
+ (company-wordfreq . [(20220405 2000) ((emacs (27 1)) (company (0 9))) "Company backend for human language texts" single ((:commit . "83569cf346c2320ef22f6a858e3424f771c4324e") (:authors ("Johannes Mueller" . "github@johannes-mueller.org")) (:maintainer "Johannes Mueller" . "github@johannes-mueller.org") (:keywords "company" "convenience" "matching") (:url . "https://github.com/johannes-mueller/company-wordfreq.el"))])
+ (company-ycm . [(20140904 1817) ((ycm (0 1))) "company-ycm" single ((:commit . "4da8a14abcd0f4fa3235042ade2e12b5068c0601") (:authors ("Ajay Gopinathan" . "ajay@gopinathan.net")) (:maintainer "Ajay Gopinathan" . "ajay@gopinathan.net") (:keywords "abbrev"))])
+ (company-ycmd . [(20180520 1053) ((ycmd (1 3)) (company (0 9 3)) (deferred (0 5 1)) (s (1 11 0)) (dash (2 13 0)) (let-alist (1 0 5)) (f (0 19 0))) "company-mode backend for ycmd" single ((:commit . "c17ff9e0250a9b39d23af37015a2b300e2f36fed") (:url . "https://github.com/abingham/emacs-ycmd"))])
+ (compdef . [(20200304 611) ((emacs (24 4))) "A local completion definer" single ((:commit . "30fb5846ed851efee641ce8c5d8879ad36cd7ac6") (:authors ("Uros Perisic")) (:maintainer "Uros Perisic") (:keywords "convenience") (:url . "https://gitlab.com/jjzmajic/compdef"))])
+ (competitive-programming-snippets . [(20201115 1702) ((emacs (26)) (yasnippet (0 8 0))) "Competitive Programming snippets for yasnippet" tar ((:commit . "3b43c1aeaa6676d1d3d0c47e78790db9bee150b6") (:authors ("Seong Yong-ju" . "sei40kr@gmail.com")) (:maintainer "Seong Yong-ju" . "sei40kr@gmail.com") (:keywords "tools") (:url . "https://github.com/sei40kr/competitive-programming-snippets"))])
+ (compiler-explorer . [(20210916 1316) ((emacs (26 1)) (request (0 3 0))) "Compiler explorer client (godbolt.org)" single ((:commit . "9ea0cc78ac40f667dfaf9277758a22b9058ca434") (:authors ("Michał Krzywkowski" . "k.michal@zoho.com")) (:maintainer "Michał Krzywkowski" . "k.michal@zoho.com") (:keywords "c" "tools") (:url . "https://github.com/mkcms/compiler-explorer.el"))])
+ (completions-frame . [(20210430 640) ((emacs (26 1))) "Show completions in child frame" single ((:commit . "860e5b97730df7ef5c34584ad164bc69c561db84") (:authors ("Andrii Kolomoiets" . "andreyk.mad@gmail.com")) (:maintainer "Andrii Kolomoiets" . "andreyk.mad@gmail.com") (:keywords "frames") (:url . "https://github.com/muffinmad/emacs-completions-frame"))])
+ (composable . [(20201024 1458) ((emacs (24 4))) "composable editing" tar ((:commit . "6f2efaa7018feb854720cc2518e4274ad708f793") (:authors ("Simon Friis Vindum" . "simon@vindum.io")) (:maintainer "Simon Friis Vindum" . "simon@vindum.io") (:keywords "lisp"))])
+ (composer . [(20200616 1717) ((emacs (24 3)) (s (1 9 0)) (f (0 17)) (seq (1 9)) (php-runtime (0 1 0))) "Interface to PHP Composer" single ((:commit . "7c7f89df226cac69664d7eca5e913b544dc475c5") (:authors ("USAMI Kenta" . "tadsan@zonu.me")) (:maintainer "USAMI Kenta" . "tadsan@zonu.me") (:keywords "tools" "php" "dependency" "manager") (:url . "https://github.com/zonuexe/composer.el"))])
+ (comware-router-mode . [(20220108 2111) ((dash (2 16 0)) (emacs (24 3))) "Major mode for editing Comware configuration files" single ((:commit . "cd8c74653c0e221e3dd1ca540496c4b4c7ee4617") (:authors ("Davide Restivo" . "davide.restivo@yahoo.it")) (:maintainer "Davide Restivo" . "davide.restivo@yahoo.it") (:keywords "convenience" "faces") (:url . "https://github.com/daviderestivo/comware-router-mode"))])
+ (concurrent . [(20161229 330) ((emacs (24 3)) (deferred (0 5 0))) "Concurrent utility functions for emacs lisp" single ((:commit . "2239671d94b38d92e9b28d4e12fd79814cfb9c16") (:authors ("SAKURAI Masashi <m.sakurai at kiwanami.net>")) (:maintainer "SAKURAI Masashi <m.sakurai at kiwanami.net>") (:keywords "deferred" "async" "concurrent") (:url . "https://github.com/kiwanami/emacs-deferred/blob/master/README-concurrent.markdown"))])
+ (conda . [(20220315 1533) ((emacs (24 4)) (pythonic (0 1 0)) (dash (2 13 0)) (s (1 11 0)) (f (0 18 2))) "Work with your conda environments" single ((:commit . "9c28d7a853b4b4bd00215cf7f07856c1563f2ad7") (:authors ("Rami Chowdhury" . "rami.chowdhury@gmail.com")) (:maintainer "Rami Chowdhury" . "rami.chowdhury@gmail.com") (:keywords "python" "environment" "conda") (:url . "http://github.com/necaris/conda.el"))])
+ (config-general-mode . [(20171024 1840) nil "Config::General config file mode" single ((:commit . "b4a8e6ba0bb027a77e4a0f701409f3e57bb2e4c0") (:authors ("T.v.Dein" . "tlinden@cpan.org")) (:maintainer "T.v.Dein" . "tlinden@cpan.org") (:keywords "files") (:url . "https://github.com/tlinden/config-general-mode"))])
+ (config-parser . [(20160426 1219) ((emacs (24 4))) "a library for parsing config file" single ((:commit . "85d559e7889d8f5b98b8794b79426ae25ec3caa5") (:authors ("DarkSun" . "lujun9972@gmail.com")) (:maintainer "DarkSun" . "lujun9972@gmail.com") (:keywords "convenience" "config") (:url . "https://github.com/lujun9972/el-config-parser"))])
+ (conkeror-minor-mode . [(20150114 1604) nil "Mode for editing conkeror javascript files." single ((:commit . "476e81c27b056e21c192391fe674a2bf875466b0") (:authors ("Artur Malabarba" . "bruce.connor.am@gmail.com>")) (:maintainer "Artur Malabarba" . "bruce.connor.am@gmail.com>") (:keywords "programming" "tools") (:url . "http://github.com/Bruce-Connor/conkeror-minor-mode"))])
+ (conllu-mode . [(20200501 2328) ((emacs (25)) (cl-lib (0 5)) (flycheck (30)) (hydra (0 13 0)) (s (1 0))) "editing mode for CoNLL-U files" tar ((:commit . "0db3063572b0de08874822e20570bb153747e6ed") (:authors ("bruno cuconato" . "bcclaro+emacs@gmail.com")) (:maintainer "bruno cuconato" . "bcclaro+emacs@gmail.com") (:keywords "extensions") (:url . "https://github.com/odanoburu/conllu-mode"))])
+ (connection . [(20191111 446) nil "TCP-based client connection" single ((:commit . "bdf0aa7761d1c1a3bc0652b2fdc4a54b3acdb06a") (:authors ("Torsten Hilbrich" . "torsten.hilbrich@gmx.net")) (:maintainer "Torsten Hilbrich" . "torsten.hilbrich@gmx.net") (:keywords "network"))])
+ (constant-theme . [(20180921 1012) ((emacs (24 1))) "A calm, dark, almost monochrome color theme." tar ((:commit . "23543a09729569b566175abe1efbe774048d3fa8") (:authors ("Jannis Pohlmann" . "contact@jannispohlmann.de")) (:maintainer "Jannis Pohlmann" . "contact@jannispohlmann.de") (:keywords "themes") (:url . "https://github.com/jannis/emacs-constant-theme"))])
+ (consult . [(20220503 2229) ((emacs (27 1))) "Consulting completing-read" tar ((:commit . "ea30b4dc8b25b65082ab9a2d56d2c6035d63b31e") (:authors ("Daniel Mendler and Consult contributors")) (:maintainer "Daniel Mendler" . "mail@daniel-mendler.de") (:url . "https://github.com/minad/consult"))])
+ (consult-ag . [(20220419 1721) ((emacs (27 1)) (consult (0 16))) "The silver searcher integration using Consult" single ((:commit . "2460ae6829e86c9f1186a852304d919526838cb8") (:authors ("Kanon Kakuno" . "yadex205@outlook.jp")) (:maintainer "Kanon Kakuno" . "yadex205@outlook.jp") (:url . "https://github.com/yadex205/consult-ag"))])
+ (consult-company . [(20211021 1152) ((emacs (27 1)) (company (0 9)) (consult (0 9))) "Consult frontend for company" single ((:commit . "ef1c553b4a72b23297b55708bf6f6dd1b27cc68e") (:authors ("mohsin kaleem" . "mohkale@kisara.moe")) (:maintainer "mohsin kaleem" . "mohkale@kisara.moe") (:url . "https://github.com/mohkale/consult-company"))])
+ (consult-dir . [(20220505 1037) ((emacs (26 1)) (consult (0 9)) (project (0 6 0))) "Insert paths into the minibuffer prompt" single ((:commit . "eee5beb13112d315fd283573006277d1b7a27843") (:authors ("Karthik Chikmagalur")) (:maintainer "Karthik Chikmagalur" . "karthik.chikmagalur@gmail.com") (:keywords "convenience") (:url . "https://github.com/karthink/consult-dir"))])
+ (consult-eglot . [(20220409 1238) ((emacs (27 1)) (eglot (1 7)) (consult (0 16)) (project (0 3 0))) "A consulting-read interface for eglot" single ((:commit . "0da8801dd8435160ce1f62ad8066bd52e38f5cbd") (:authors ("mohsin kaleem" . "mohkale@kisara.moe")) (:maintainer "Mohsin Kaleem") (:keywords "tools" "completion" "lsp") (:url . "https://github.com/mohkale/consult-eglot"))])
+ (consult-flycheck . [(20220403 1810) ((consult (0 16)) (flycheck (31)) (emacs (27 1))) "Provides the command `consult-flycheck'" single ((:commit . "9b40f136c017fadf6239d7602d16bf73b4ad5198") (:authors ("Daniel Mendler and Consult contributors")) (:maintainer "Daniel Mendler" . "mail@daniel-mendler.de") (:url . "https://github.com/minad/consult"))])
+ (consult-flyspell . [(20220419 2044) ((emacs (25 1)) (consult (0 12))) "Consult integration for flyspell" single ((:commit . "396def174495cc77413e2065ef79658a02490dad") (:authors ("Marco Pawłowski")) (:maintainer "Marco Pawłowski") (:keywords "convenience") (:url . "https://gitlab.com/OlMon/consult-flyspell"))])
+ (consult-ghq . [(20210606 2047) ((emacs (26 1)) (consult (0 8)) (affe (0 1))) "Ghq interface using consult" single ((:commit . "c8619d66bd8f8728e43ed15096078b89eb4d2083") (:authors ("Tomoya Otake" . "tomoya.ton@gmail.com")) (:maintainer "Tomoya Otake" . "tomoya.ton@gmail.com") (:keywords "convenience" "usability" "consult" "ghq") (:url . "https://github.com/tomoya/consult-ghq"))])
+ (consult-ls-git . [(20220501 1823) ((emacs (27 1)) (consult (0 16))) "Consult integration for git" single ((:commit . "f2398b354994e583ad22af324a129cf94d06009e") (:authors ("Robin Joy")) (:maintainer "Robin Joy") (:keywords "convenience") (:url . "https://github.com/rcj/consult-ls-git"))])
+ (consult-lsp . [(20220409 1107) ((emacs (27 1)) (lsp-mode (5 0)) (consult (0 16)) (f (0 20 0))) "LSP-mode Consult integration" single ((:commit . "a8eb3a062feb2715f174500d0624d3a85e000cf7") (:authors ("Gerry Agbobada")) (:maintainer "Gerry Agbobada") (:keywords "tools" "completion" "lsp") (:url . "https://github.com/gagbo/consult-lsp"))])
+ (consult-notmuch . [(20220421 717) ((emacs (26 1)) (consult (0 9)) (notmuch (0 31))) "Notmuch search using consult" single ((:commit . "16eb2c100ca144140f07014c32e99487c6a73e18") (:authors ("Jose A Ortega Ruiz" . "jao@gnu.org")) (:maintainer "Jose A Ortega Ruiz") (:keywords "mail") (:url . "https://codeberg.org/jao/consult-notmuch"))])
+ (consult-org-roam . [(20220426 1628) ((emacs (27 1)) (org-roam (2 2 0)) (consult (0 16))) "Consult integration for org-roam" single ((:commit . "45d18c2b5f378bbcf3d9b61278f5f6c2b92d1be6") (:authors ("jgru <https://github.com/jgru>")) (:maintainer "jgru <https://github.com/jgru>") (:url . "https://github.com/jgru/consult-org-roam"))])
+ (consult-project-extra . [(20220424 1815) ((emacs (27 1)) (consult (0 17)) (project (0 8 1))) "Consult integration for project.el" single ((:commit . "fa882a0bf9b697ebb59d0dfa2ffd81ea6daabf41") (:authors ("Enrique Kessler Martínez")) (:maintainer "Enrique Kessler Martínez") (:keywords "convenience" "project" "management") (:url . "https://github.com/Qkessler/consult-project-extra"))])
+ (consult-projectile . [(20220505 1139) ((emacs (25 1)) (consult (0 12)) (projectile (2 5 0))) "Consult integration for projectile" single ((:commit . "8e618bc62405e345cc59e891f82d8ee45691010a") (:authors ("Marco Pawłowski")) (:maintainer "Marco Pawłowski") (:keywords "convenience") (:url . "https://gitlab.com/OlMon/consult-projectile"))])
+ (consult-recoll . [(20220227 2050) ((emacs (26 1)) (consult (0 9))) "Recoll queries using consult" single ((:commit . "228306eeda8c57db45609ca068f60ee433367c17") (:authors ("Jose A Ortega Ruiz" . "jao@gnu.org")) (:maintainer "Jose A Ortega Ruiz") (:keywords "docs" "convenience") (:url . "https://codeberg.org/jao/consult-recoll"))])
+ (consult-spotify . [(20211114 2258) ((emacs (26 1)) (consult (0 8)) (espotify (0 1))) "Spotify queries using consult" single ((:commit . "ea6d6021e5acc550560325db2f09198839ee702f") (:authors ("Jose A Ortega Ruiz" . "jao@gnu.org")) (:maintainer "Jose A Ortega Ruiz") (:keywords "multimedia") (:url . "https://codeberg.org/jao/espotify"))])
+ (consult-yasnippet . [(20220409 1209) ((emacs (27 1)) (yasnippet (0 14)) (consult (0 16))) "A consulting-read interface for yasnippet" single ((:commit . "cdb256d2c50e4f8473c6052e1009441b65b8f8ab") (:authors ("mohsin kaleem" . "mohkale@kisara.moe")) (:maintainer "mohsin kaleem" . "mohkale@kisara.moe") (:url . "https://github.com/mohkale/consult-yasnippet"))])
+ (contextual . [(20180726 800) ((emacs (24)) (dash (2 12 1)) (cl-lib (0 5))) "Contextual profile management system" single ((:commit . "e3c0de4a2e06757a0e8407c3c6e75930026191e3") (:authors ("Alexander Kahl" . "ak@sodosopa.io")) (:maintainer "Alexander Kahl" . "ak@sodosopa.io") (:keywords "convenience" "tools") (:url . "https://github.com/lshift-de/contextual"))])
+ (contextual-menubar . [(20180205 709) nil "display the menubar only on a graphical display" single ((:commit . "f76f55232ac07df76ef9a334a0c527dfab97c40b") (:authors ("Aaron Jensen" . "aaronjensen@gmail.com")) (:maintainer "Aaron Jensen" . "aaronjensen@gmail.com") (:url . "https://github.com/aaronjensen/contextual-menubar"))])
+ (contrast-color . [(20160903 1807) ((emacs (24 3)) (cl-lib (0 5))) "Pick best contrast color for you" single ((:commit . "c5fb77a211ebbef3185ada37bea7420534c33f94") (:authors ("Yuta Yamada <cokesboy[at]gmail.com>")) (:maintainer "Yuta Yamada <cokesboy[at]gmail.com>") (:keywords "color" "convenience") (:url . "https://github.com/yuutayamada/contrast-color-el"))])
+ (control-mode . [(20160624 1710) nil "A \"control\" mode, similar to vim's \"normal\" mode" single ((:commit . "72d6179b60adc438aada74083b2bf4264b575de3") (:authors ("Stephen Marsh" . "stephen.david.marsh@gmail.com")) (:maintainer "Stephen Marsh" . "stephen.david.marsh@gmail.com") (:keywords "convenience" "emulations") (:url . "https://github.com/stephendavidmarsh/control-mode"))])
+ (conventional-changelog . [(20211212 1158) ((emacs (27)) (transient (0 3 6))) "Conventional Changelog Generator" single ((:commit . "40c2ee58364422b776e81dc153918205bfbeda86") (:authors ("liuyinz" . "liuyinz95@gmail.com")) (:maintainer "liuyinz" . "liuyinz95@gmail.com") (:keywords "tools") (:url . "https://github.com/liuyinz/emacs-conventional-changelog"))])
+ (copy-as-format . [(20190523 258) ((cl-lib (0 5))) "Copy buffer locations as GitHub/Slack/JIRA etc... formatted code" single ((:commit . "a0962b670e26b723ce304b14e3397da453aef84e") (:authors ("Skye Shaw" . "skye.shaw@gmail.com")) (:maintainer "Skye Shaw" . "skye.shaw@gmail.com") (:keywords "github" "slack" "jira" "hipchat" "gitlab" "bitbucket" "org-mode" "pod" "rst" "asciidoc" "tools" "convenience") (:url . "https://github.com/sshaw/copy-as-format"))])
+ (copy-file-on-save . [(20200616 518) ((emacs (24 3)) (cl-lib (0 5)) (f (0 17)) (s (1 7 0))) "Copy file on save, automatic deployment it." single ((:commit . "811c8fe638c5616b6471525421e61a4470be3b52") (:authors ("USAMI Kenta" . "tadsan@zonu.me")) (:maintainer "USAMI Kenta" . "tadsan@zonu.me") (:keywords "files" "comm" "deploy") (:url . "https://github.com/emacs-php/emacs-auto-deployment"))])
+ (copyit . [(20190919 1258) ((emacs (24 3)) (s (1 9 0))) "Copy it, yank anything!" single ((:commit . "c4f2c28e5b6270e8e3364341619f1154bb4e682e") (:authors ("USAMI Kenta" . "tadsan@zonu.me")) (:maintainer "USAMI Kenta" . "tadsan@zonu.me") (:keywords "convenience" "yank" "clipboard") (:url . "https://github.com/zonuexe/emacs-copyit"))])
+ (copyit-pandoc . [(20190919 1258) ((emacs (24 3)) (copyit (0 1 0)) (pandoc (0 0 1))) "Copy it, yank anything!" single ((:commit . "c4f2c28e5b6270e8e3364341619f1154bb4e682e") (:authors ("USAMI Kenta" . "tadsan@zonu.me")) (:maintainer "USAMI Kenta" . "tadsan@zonu.me") (:keywords "convenience" "yank" "clipboard") (:url . "https://github.com/zonuexe/emacs-copyit"))])
+ (coq-commenter . [(20170822 2309) ((dash (2 13 0)) (s (1 11 0)) (cl-lib (0 5))) "Coq commenting minor mode for proof" single ((:commit . "7fe9a2cc0ebdb0b1e54a24eb7971d757fb588ac3") (:authors ("Junyoung Clare Jang" . "jjc9310@gmail.com")) (:maintainer "Junyoung Clare Jang" . "jjc9310@gmail.com") (:keywords "comment" "coq" "proof") (:url . "http://github.com/ailrun/coq-commenter"))])
+ (corfu-doc . [(20220429 1348) ((emacs (26 0)) (corfu (0 16 0))) "Documentation popup for Corfu" single ((:commit . "5a6f4f879de6dc2ca6e22789878d416e88e85905") (:authors ("Yuwei Tian" . "ibluefocus@NOSPAM.gmail.com")) (:maintainer "Yuwei Tian" . "ibluefocus@NOSPAM.gmail.com") (:keywords "corfu" "popup" "documentation" "convenience") (:url . "https://github.com/galeo/corfu-doc"))])
+ (corral . [(20160502 701) nil "Quickly surround text with delimiters" single ((:commit . "e7ab6aa118e46b93d4933d1364bc273f57cd6911") (:authors ("Kevin Liu" . "mail@nivekuil.com")) (:maintainer "Kevin Liu" . "mail@nivekuil.com") (:url . "http://github.com/nivekuil/corral"))])
+ (cort . [(20211020 18) ((emacs (24 1)) (ansi (0 4)) (cl-lib (0 6))) "Simplify extended unit test framework" single ((:commit . "3f64a7b03a4c5b768ec21fd5987acd0d62d16c7b") (:authors ("Naoya Yamashita" . "conao3@gmail.com")) (:maintainer "Naoya Yamashita" . "conao3@gmail.com") (:keywords "test" "lisp") (:url . "https://github.com/conao3/cort.el"))])
+ (cosmo . [(20170922 744) ((emacs (24 4))) "Cosmological Calculator" single ((:commit . "dd83b09a49a2843606b28279b674b2207040b36b") (:authors ("Francesco Montanari" . "fmnt@fmnt.info")) (:maintainer "Francesco Montanari" . "fmnt@fmnt.info") (:keywords "tools") (:url . "https://gitlab.com/montanari/cosmo-el"))])
+ (counsel . [(20220402 953) ((emacs (24 5)) (ivy (0 13 4)) (swiper (0 13 4))) "Various completion functions using Ivy" single ((:commit . "8bf8027e4bd8c093bddb76a813952d2a0dcbf21d") (:authors ("Oleh Krehel" . "ohwoeowho@gmail.com")) (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com") (:keywords "convenience" "matching" "tools") (:url . "https://github.com/abo-abo/swiper"))])
+ (counsel-ag-popup . [(20210121 805) ((emacs (26 1)) (counsel (0 13 0)) (transient (0 3 0))) "Interactive search with counsel-ag" single ((:commit . "41d85fe36edd72da68f5009ad9cf9013cd19960d") (:authors ("Eder Elorriaga" . "gexplorer8@gmail.com")) (:maintainer "Eder Elorriaga" . "gexplorer8@gmail.com") (:keywords "convenience" "matching" "tools") (:url . "https://github.com/gexplorer/counsel-ag-popup"))])
+ (counsel-at-point . [(20220211 548) ((emacs (26 2)) (counsel (0 13 0))) "Context sensitive project search" single ((:commit . "28b26ecac676d6a3942f1b96d2916f4c23d9b3ab") (:authors ("Campbell Barton" . "ideasman42@gmail.com")) (:maintainer "Campbell Barton" . "ideasman42@gmail.com") (:keywords "convenience") (:url . "https://gitlab.com/ideasman42/emacs-counsel-at-point"))])
+ (counsel-bbdb . [(20181128 1320) ((ivy (0 8 0)) (emacs (24 3))) "Quick search&input email from BBDB based on ivy" single ((:commit . "df2890deb73b09f8055243bd91942ea887d9b7a1") (:authors ("Chen Bin <chenbin.sh AT gmail>")) (:maintainer "Chen Bin <chenbin.sh AT gmail>") (:keywords "mail" "abbrev" "convenience" "matching") (:url . "https://github.com/redguard/counsel-bbdb"))])
+ (counsel-chrome-bm . [(20211022 1427) ((emacs (25 1)) (counsel (0 13 0))) "Browse Chrom(e/ium) bookmarks with Ivy" single ((:commit . "72b31889581f20f4037c0361f5259ff3633bc128") (:authors ("BlueBoxWare" . "BlueBoxWare@users.noreply.github.com")) (:maintainer "BlueBoxWare" . "BlueBoxWare@users.noreply.github.com") (:keywords "hypermedia") (:url . "https://github.com/BlueBoxWare/counsel-chrome-bm"))])
+ (counsel-codesearch . [(20180925 803) ((codesearch (1)) (counsel (0 10 0)) (emacs (24)) (ivy (0 10 0))) "Counsel interface for codesearch.el" single ((:commit . "b7989fad3e06f301c31d5e896c42b6cc549a0e0c") (:authors ("Austin Bingham" . "austin.bingham@gmail.com")) (:maintainer "Austin Bingham" . "austin.bingham@gmail.com") (:keywords "tools") (:url . "https://github.com/abingham/emacs-counsel-codesearch"))])
+ (counsel-css . [(20211115 1755) ((emacs (24 4)) (counsel (0 7 0)) (cl-lib (0 5))) "stylesheet-selector-aware swiper" single ((:commit . "8e9c0515fc952452eee786d8ebb43d48ea86c9f8") (:authors ("Henrik Lissner <http://github/hlissner>")) (:maintainer "Henrik Lissner" . "contact@henrik.io") (:keywords "convenience" "tools" "counsel" "swiper" "selector" "css" "less" "scss") (:url . "https://github.com/hlissner/emacs-counsel-css"))])
+ (counsel-dash . [(20200103 1411) ((emacs (24 4)) (dash-docs (1 4 0)) (counsel (0 8 0)) (cl-lib (0 5))) "Browse dash docsets using Ivy" single ((:commit . "370d5f6f14b5294d0eb717f7b2a6a8e93df1ed24") (:authors ("Nathan Kot" . "nk@nathankot.com")) (:maintainer "Nathan Kot" . "nk@nathankot.com") (:keywords "dash" "ivy" "counsel") (:url . "https://github.com/nathankot/counsel-dash"))])
+ (counsel-edit-mode . [(20210824 1504) ((emacs (26 1)) (ht (2 3)) (s (1 12 0)) (counsel (0 10 0))) "Edit results of counsel commands in-place" single ((:commit . "378803ac0040c04762ff001ab1aca7d4325ecf22") (:authors ("Tyler Dodge")) (:maintainer "Tyler Dodge") (:keywords "convenience" "matching") (:url . "https://github.com/tyler-dodge/counsel-edit-mode"))])
+ (counsel-etags . [(20220405 510) ((emacs (25 1)) (counsel (0 13 4))) "Fast and complete Ctags/Etags solution using ivy" single ((:commit . "c74ae94297c4a2dc0b6878c2e9460a4f386158d4") (:authors ("Chen Bin <chenbin dot sh AT gmail dot com>")) (:maintainer "Chen Bin <chenbin dot sh AT gmail dot com>") (:keywords "tools" "convenience") (:url . "http://github.com/redguardtoo/counsel-etags"))])
+ (counsel-fd . [(20210606 1724) ((counsel (0 12 0))) "counsel interface for fd" single ((:commit . "e9513a3c7f6cdbdf038f951e828e631c0455e7d4") (:keywords "tools") (:url . "https://github.com/CsBigDataHub/counsel-fd"))])
+ (counsel-ffdata . [(20191017 1237) ((emacs (25 1)) (counsel (0 11 0)) (emacsql (3 0 0))) "Use ivy to access firefox data" single ((:commit . "88c2348c4039d9e562bd3d9a364708b01037c283") (:authors ("Zhu Zihao" . "all_but_last@163.com")) (:maintainer "Zhu Zihao" . "all_but_last@163.com") (:keywords "convenience" "tools" "matching") (:url . "https://github.com/cireu/counsel-ffdata"))])
+ (counsel-gtags . [(20210222 1803) ((emacs (25 1)) (counsel (0 8 0)) (seq (1 0))) "ivy for GNU global" single ((:commit . "1d52eaeffeb60266434d4f7416a108ca058fde91") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com") ("Felipe Lema" . "felipelema@mortemale.org") ("Jimmy Aguilar Mena" . "spacibba@aol.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/FelipeLema/emacs-counsel-gtags"))])
+ (counsel-jq . [(20210329 749) ((swiper (0 12 0)) (ivy (0 12 0)) (emacs (24 1))) "Live preview of \"jq\" queries using counsel" single ((:commit . "8cadd2e96470402ede4881b4e955872976443689") (:authors ("Alain M. Lafon" . "alain@200ok.ch")) (:maintainer "Alain M. Lafon" . "alain@200ok.ch") (:keywords "convenience" "data" "matching") (:url . "https://github.com/200ok-ch/counsel-jq"))])
+ (counsel-mairix . [(20210422 649) ((emacs (26 3)) (ivy (0 13 1))) "Counsel interface for Mairix" single ((:commit . "39fa2ad10a5f899cb3f3275f9a6ebd166c51216a") (:authors ("Antoine Kalmbach" . "ane@iki.fi")) (:maintainer "Antoine Kalmbach" . "ane@iki.fi") (:keywords "mail") (:url . "https://sr.ht/~ane/counsel-mairix"))])
+ (counsel-notmuch . [(20181203 935) ((emacs (24)) (ivy (0 10 0)) (notmuch (0 21)) (s (1 12 0))) "Search emails in Notmuch asynchronously with Ivy" single ((:commit . "a4a1562935e4180c42524c51609d1283e9be0688") (:authors ("Alexander Fu Xi" . "fuxialexander@gmail.com")) (:maintainer "Alexander Fu Xi" . "fuxialexander@gmail.com") (:keywords "mail") (:url . "https://github.com/fuxialexander/counsel-notmuch"))])
+ (counsel-org-capture-string . [(20200810 1114) ((emacs (25 1)) (ivy (0 13))) "Counsel for org-capture-string" single ((:commit . "dbb7d95f99d7910d76ffc2d024580088a34ec444") (:authors ("Akira Komamura" . "akira.komamura@gmail.com")) (:maintainer "Akira Komamura" . "akira.komamura@gmail.com") (:keywords "outlines") (:url . "https://github.com/akirak/counsel-org-capture-string"))])
+ (counsel-org-clock . [(20200810 1109) ((emacs (25 1)) (ivy (0 10 0)) (dash (2 0))) "Counsel commands for org-clock" single ((:commit . "0f790def6ac2b5a84d01eed47a7ee53619a8f5b9") (:authors ("Akira Komamura" . "akira.komamura@gmail.com")) (:maintainer "Akira Komamura" . "akira.komamura@gmail.com") (:url . "https://github.com/akirak/counsel-org-clock"))])
+ (counsel-osx-app . [(20160821 809) ((ivy (0 8 0)) (emacs (24 3))) "launch osx applications via ivy interface" single ((:commit . "b1c54cbc033c4939966910d85ce035503079e108") (:authors ("Boris Buliga" . "d12frosted@gmail.com")) (:maintainer "Boris Buliga" . "d12frosted@gmail.com") (:url . "https://github.com/d12frosted/counsel-osx-app"))])
+ (counsel-projectile . [(20211004 2003) ((counsel (0 13 4)) (projectile (2 5 0))) "Ivy integration for Projectile" single ((:commit . "40d1e1d4bb70acb00fddd6f4df9778bf2c52734b") (:authors ("Eric Danan")) (:maintainer "Eric Danan") (:keywords "project" "convenience") (:url . "https://github.com/ericdanan/counsel-projectile"))])
+ (counsel-pydoc . [(20171018 2042) ((emacs (24 3)) (ivy (0 9 1))) "run pydoc with counsel" single ((:commit . "1d8ff8ca3b9d69453cde423b1887fbb490a95c9e") (:authors (nil . "Hao Deng(denghao8888@gmail.com)")) (:maintainer nil . "Hao Deng(denghao8888@gmail.com)") (:keywords "completion" "matching") (:url . "https://github.com/co-dh/pydoc_utils"))])
+ (counsel-spotify . [(20200818 2055) ((emacs (25 1)) (ivy (0 13 0))) "Control Spotify search and select music with Ivy" tar ((:commit . "2743ad52a9def53534fd505397fbe1ac49e53015") (:authors ("Lautaro García <https://github.com/Lautaro-Garcia>")) (:maintainer "Lautaro García <https://github.com/Lautaro-Garcia>") (:url . "https://github.com/Lautaro-Garcia/counsel-spotify"))])
+ (counsel-test . [(20190819 1920) ((emacs (25 1)) (ivy (0 11 0)) (s (1 12 0))) "Browse and execute tests with ivy" tar ((:commit . "7fc4e5d0d65c53edbcb4c25917bcf7faaea36ec7") (:keywords "tools" "ivy" "counsel" "testing" "ctest" "pytest") (:url . "http://github.com/xmagpie/counsel-test"))])
+ (counsel-tramp . [(20210518 1153) ((emacs (24 3)) (counsel (0 10))) "Tramp ivy interface for ssh, docker, vagrant" single ((:commit . "76719eebb791920272c69e75e234f05a815bb5c2") (:authors ("Masashı Mıyaura")) (:maintainer "Masashı Mıyaura") (:url . "https://github.com/masasam/emacs-counsel-tramp"))])
+ (counsel-web . [(20210609 2156) ((emacs (25 1)) (counsel (0 13 0)) (request (0 3 0))) "Search the Web using Ivy" single ((:commit . "1359b3b204fcdac7a3d6664c7d540a88b5acecfd") (:authors ("Matthew Sojourner Newton" . "matt@mnewton.com")) (:maintainer "Matthew Sojourner Newton" . "matt@mnewton.com") (:keywords "convenience" "hypermedia") (:url . "https://github.com/mnewt/counsel-web"))])
+ (counsel-world-clock . [(20190709 2211) ((ivy (0 9 0)) (s (1 12 0))) "Display world clock using Ivy." single ((:commit . "674e4c6b82a92ea765af97cc5f017b357284c7dc") (:authors ("Kuang Chen <http://github.com/kchenphy>")) (:maintainer "Kuang Chen <http://github.com/kchenphy>") (:url . "https://github.com/kchenphy/counsel-world-clock"))])
+ (countdown . [(20190626 244) ((emacs (25 1)) (stream (2 2 4))) "Countdown using big LCD-like digits" single ((:commit . "139dea91fc818d65944aca5f16c9626abbdfbf04") (:authors ("Xu Chunyang" . "mail@xuchunyang.me")) (:maintainer "Xu Chunyang" . "mail@xuchunyang.me") (:keywords "tools") (:url . "https://github.com/xuchunyang/countdown.el"))])
+ (cov . [(20220410 2247) ((emacs (24 4)) (f (0 18 2)) (s (1 11 0)) (elquery (0))) "Show coverage stats in the fringe." single ((:commit . "8396fa82a84965cd88fa23f5b361ab80ff28e231") (:authors ("Adam Niederer")) (:maintainer "Adam Niederer") (:keywords "coverage" "gcov" "c") (:url . "https://github.com/AdamNiederer/cov"))])
+ (coverage . [(20191113 1958) ((ov (1 0)) (cl-lib (0 5))) "Code coverage line highlighting" single ((:commit . "6e3c6f2dcb759a76086adeeb1fdfe83e4f082482") (:authors ("Kieran Trezona-le Comte" . "trezona.lecomte@gmail.com")) (:maintainer "Kieran Trezona-le Comte" . "trezona.lecomte@gmail.com") (:keywords "coverage" "metrics" "simplecov" "ruby" "rspec") (:url . "https://github.com/trezona-lecomte/coverage"))])
+ (coverlay . [(20190414 940) ((emacs (24 1)) (cl-lib (0 5))) "Test coverage overlays" single ((:commit . "0beae208d0e7d746a94385428bd61aa5cd7ea828") (:authors ("Takuto Wada <takuto.wada at gmail com>")) (:maintainer "Takuto Wada <takuto.wada at gmail com>") (:keywords "coverage" "overlay") (:url . "https://github.com/twada/coverlay.el"))])
+ (cowsay . [(20210510 1540) ((emacs (24 5))) "Poorly drawn ASCII cartoons saying things" single ((:commit . "683c23afa2a37272be54de822ad19f4e11dd86ba") (:authors ("Lassi Kortela" . "lassi@lassi.io")) (:maintainer "Lassi Kortela" . "lassi@lassi.io") (:keywords "games") (:url . "https://github.com/lassik/emacs-cowsay"))])
+ (cp5022x . [(20120323 2335) nil "cp50220, cp50221, cp50222 coding system" single ((:commit . "ea7327dd75e54539576916f592ae1be98179ae35") (:authors ("ARISAWA Akihiro" . "ari@mbf.ocn.ne.jp")) (:maintainer "ARISAWA Akihiro" . "ari@mbf.ocn.ne.jp") (:keywords "languages" "cp50220" "cp50221" "cp50222" "cp51932" "cp932"))])
+ (cpanfile-mode . [(20161001 710) ((emacs (24 4))) "Major mode for cpanfiles" single ((:commit . "eda675703525198df1f76ddf250bffa40217ec5d") (:authors ("Zak B. Elep" . "zakame@zakame.net")) (:maintainer "Zak B. Elep" . "zakame@zakame.net") (:keywords "perl") (:url . "https://github.com/zakame/cpanfile-mode"))])
+ (cpp-auto-include . [(20210318 2217) ((cl-lib (0 5))) "Insert and delete C++ header files automatically" single ((:commit . "0ce829f27d466c083e78b9fe210dcfa61fb417f4") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/emacsorphanage/cpp-auto-include"))])
+ (cpputils-cmake . [(20181006 328) nil "Easy realtime C++ syntax check and IntelliSense with CMake." single ((:commit . "64b2b05eff5398b4cd522e66efaf14553ab18ff4") (:authors ("Chen Bin" . "chenbin.sh@gmail.com")) (:maintainer "Chen Bin" . "chenbin.sh@gmail.com") (:keywords "cmake" "intellisense" "flymake" "flycheck") (:url . "http://github.com/redguardtoo/cpputils-cmake"))])
+ (cpu-sos . [(20200409 2356) ((emacs (25 1))) "S.O.S. from a CPU in distress" single ((:commit . "1594b76d4ad3a6e3c471d82da366226d156e6226") (:authors ("Bruno Félix Rezende Ribeiro" . "oitofelix@gnu.org")) (:maintainer "Bruno Félix Rezende Ribeiro" . "oitofelix@gnu.org") (:keywords "processes") (:url . "https://github.com/oitofelix/cpu-sos"))])
+ (cql-mode . [(20190315 225) ((emacs (24))) "Major mode for editting CQLs" single ((:commit . "d400c046850d3cf404778b2c47d6be4ff84ca04b") (:authors ("Yuki Inoue <inouetakahiroki at gmail.com>")) (:maintainer "Yuki Inoue <inouetakahiroki at gmail.com>") (:keywords "cql" "cassandra") (:url . "https://github.com/Yuki-Inoue/cql-mode"))])
+ (cquery . [(20190118 542) ((emacs (25 1)) (lsp-mode (3 4)) (dash (0 13))) "cquery client for lsp-mode" tar ((:commit . "555e50984ebda177421fdcdc8c76cb29235d9694") (:authors ("Tobias Pisani")) (:maintainer "Tobias Pisani") (:keywords "languages" "lsp" "c++") (:url . "https://github.com/jacobdufault/cquery"))])
+ (crappy-jsp-mode . [(20140311 931) nil "A pretty crappy major-mode for jsp." single ((:commit . "6c45ab92b452411cc0fab9bcee2f456276b4fc40") (:keywords "jsp" "major" "mode"))])
+ (creamsody-theme . [(20170222 1058) ((autothemer (0 2))) "Straight from the soda fountain." single ((:commit . "32fa3f4e461da92700523b1b20e7b28974c19a26") (:url . "http://github.com/emacsfodder/emacs-theme-creamsody"))])
+ (create-link . [(20211014 1617) ((emacs (25 1))) "Smart format link generator" single ((:commit . "e765b1067ced891a90ba0478af7fe675cff9b713") (:authors ("Kijima Daigo" . "norimaking777@gmail.com")) (:maintainer "Kijima Daigo" . "norimaking777@gmail.com") (:keywords "link" "format" "browser" "convenience") (:url . "https://github.com/kijimaD/create-link"))])
+ (creds . [(20140510 1706) ((s (1 9 0)) (dash (2 5 0))) "A parser credentials file library (not limited to credentials entries)" tar ((:commit . "b059397a7d59481f05fbb1bb9c8d3c2c69226482") (:authors ("Antoine R. Dumont <eniotna.t AT gmail.com>")) (:maintainer "Antoine R. Dumont <eniotna.t AT gmail.com>") (:keywords "credentials") (:url . "https://github.com/ardumont/emacs-creds"))])
+ (creole . [(20140924 1500) ((noflet (0 0 3)) (kv (0 0 17))) "A parser for the Creole Wiki language" single ((:commit . "7d5cffe93857f6c75ca09ac79c0e47b8d4410e53") (:authors ("Nic Ferrier" . "nferrier@ferrier.me.uk")) (:maintainer "Nic Ferrier" . "nferrier@ferrier.me.uk") (:keywords "lisp" "creole" "wiki"))])
+ (creole-mode . [(20130722 50) nil "a markup mode for creole" single ((:commit . "b5e79b2ec5f19fb5aacf689b5febc3e0b61515c4") (:authors ("Nic Ferrier" . "nferrier@ferrier.me.uk")) (:maintainer "Nic Ferrier" . "nferrier@ferrier.me.uk") (:keywords "hypermedia" "wp") (:url . "https://github.com/nicferrier/creole-mode"))])
+ (cricbuzz . [(20180804 2254) ((enlive (0 0 1)) (f (0 19 0)) (dash (2 13 0)) (s (1 11 0))) "Cricket scores from cricbuzz in emacs" single ((:commit . "0b95d45991bbcd2fa58d96ce921f6a57ba42c153") (:authors ("Abhinav Tushar" . "abhinav.tushar.vs@gmail.com")) (:maintainer "Abhinav Tushar" . "abhinav.tushar.vs@gmail.com") (:keywords "cricket" "score") (:url . "https://github.com/lepisma/cricbuzz.el"))])
+ (crm-custom . [(20160117 6) ((cl-lib (0 5))) "Alternate `completing-read-multiple' that uses `completing-read'" single ((:commit . "f1aaccf64306a5f99d9bf7ba815d7ea41c15518d") (:authors ("Ryan C. Thompson" . "rct@thompsonclan.org")) (:maintainer "Ryan C. Thompson" . "rct@thompsonclan.org") (:keywords "completion" "minibuffer" "multiple elements") (:url . "https://github.com/DarwinAwardWinner/crm-custom"))])
+ (crontab-mode . [(20210715 133) ((emacs (24 3))) "Major mode for crontab(5)" single ((:commit . "7412f3df0958812bfcacd5875a409fa795fa8ecc") (:authors ("Mario Rodas" . "marsam@users.noreply.github.com")) (:maintainer "Mario Rodas" . "marsam@users.noreply.github.com") (:keywords "languages") (:url . "https://github.com/emacs-pe/crontab-mode"))])
+ (crossword . [(20210614 633) ((emacs (26 1))) "Download and play crossword puzzles" single ((:commit . "a8594b6e13f5e276aa9bc810ac74a8032bb1f678") (:keywords "games") (:url . "https://github.com/Boruch-Baum/emacs-crossword"))])
+ (crux . [(20210811 436) ((seq (1 11))) "A Collection of Ridiculously Useful eXtensions" single ((:commit . "6bfd212a7f7ae32e455802fde1f9e3f4fba932a0") (:authors ("Bozhidar Batsov" . "bozhidar@batsov.dev")) (:maintainer "Bozhidar Batsov" . "bozhidar@batsov.dev") (:keywords "convenience") (:url . "https://github.com/bbatsov/crux"))])
+ (cryptol-mode . [(20190531 2051) nil "Cryptol major mode for Emacs" single ((:commit . "81ebbde83f7cb75b2dfaefc09de6a1703068c769") (:authors (nil . "Austin Seipp <aseipp [@at] pobox [dot] com>")) (:maintainer nil . "Austin Seipp <aseipp [@at] pobox [dot] com>") (:keywords "cryptol" "cryptography") (:url . "http://github.com/thoughtpolice/cryptol-mode"))])
+ (crystal-mode . [(20220104 2146) ((emacs (24 4))) "Major mode for editing Crystal files" single ((:commit . "96a8058205b24b513d0b9307db32f05e30f9570b") (:keywords "languages" "crystal") (:url . "https://github.com/crystal-lang-tools/emacs-crystal-mode"))])
+ (crystal-playground . [(20180830 501) ((emacs (25)) (crystal-mode (0 1 2))) "Local crystal playground for short code snippets." single ((:commit . "fb3691b1281207b459c5be50015a626f356dc40d") (:authors ("Jason Howell")) (:maintainer "Jason Howell") (:keywords "tools" "crystal") (:url . "https://github.com/jasonrobot/crystal-playground"))])
+ (csgo-conf-mode . [(20161209 1619) nil "CS:GO Configuration files syntax highlighting" single ((:commit . "57e7224f87a3ccc76b5564cc95fa0ff43bb6807c") (:authors ("Guillermo Robles" . "guillerobles1995@gmail.com")) (:maintainer "Guillermo Robles" . "guillerobles1995@gmail.com") (:keywords "languages") (:url . "https://github.com/wynro/emacs-csgo-conf-mode"))])
+ (csharp-mode . [(20211124 1105) ((emacs (26 1))) "C# mode derived mode" tar ((:commit . "fa06dfa206812476217ada6c4178de34ff1efc42") (:authors ("Theodor Thornhill" . "theo@thornhill.no")) (:maintainer "Jostein Kjønigsen" . "jostein@gmail.com") (:keywords "c#" "languages" "oop" "mode") (:url . "https://github.com/emacs-csharp/csharp-mode"))])
+ (csound-mode . [(20211215 1925) ((emacs (25)) (shut-up (0 3 2)) (multi (2 0 1)) (dash (2 16 0)) (highlight (0))) "A major mode for interacting and coding Csound" tar ((:commit . "44c49e5a9262ede4b4477bafb13b42b1ba047b9c") (:authors ("Hlöðver Sigurðsson" . "hlolli@gmail.com")) (:maintainer "Hlöðver Sigurðsson" . "hlolli@gmail.com") (:url . "https://github.com/hlolli/csound-mode"))])
+ (csproj-mode . [(20200801 1732) ((emacs (24))) "Work with .NET project files (csproj, vbproj)" tar ((:commit . "a7f0f4610c976a28c41b9b8299892f88b5d0336c") (:authors ("Omair Majid" . "omair.majid@gmail.com")) (:maintainer "Omair Majid" . "omair.majid@gmail.com") (:keywords "languages" "tools") (:url . "https://github.com/omajid/csproj-mode"))])
+ (css-autoprefixer . [(20180311 1600) ((emacs (24))) "Adds autoprefix to CSS" single ((:commit . "386a5defc8543a3b87820f1761c075c7d1d93b38") (:authors (nil . "Kyung Mo Kweon<kkweon@gmail.com> and contributors")) (:maintainer nil . "Kyung Mo Kweon<kkweon@gmail.com> and contributors") (:keywords "convenience" "usability" "css") (:url . "https://github.com/kkweon/emacs-css-autoprefixer"))])
+ (css-comb . [(20160416 559) nil "Sort CSS properties in a particular order using CSS Comb" single ((:commit . "6fa45e5af8a8bd3af6c1154cde3540e32c4206ee") (:authors ("Charanjit Singh" . "ckhabra@gmail.com")) (:maintainer "Charanjit Singh" . "ckhabra@gmail.com") (:url . "https://github.com/channikhabra/css-comb.el"))])
+ (css-eldoc . [(20220415 1629) nil "an eldoc-mode plugin for CSS source code" tar ((:commit . "73ebf9757a043b56b7d3b5befec5a38e6754b9e5") (:authors ("Zeno Zeng" . "zenoes@qq.com")) (:maintainer "Zeno Zeng" . "zenoes@qq.com"))])
+ (cssh . [(20150810 1709) nil "clusterssh implementation for emacs" single ((:commit . "2fe2754235225a59b63f08b130cfd4352e2e1c3f") (:authors ("Dimitri Fontaine" . "dim@tapoueh.org")) (:maintainer "Dimitri Fontaine" . "dim@tapoueh.org") (:keywords "clusterssh" "ssh" "cssh") (:url . "http://tapoueh.org/emacs/cssh.html"))])
+ (csv . [(20161113 1510) nil "Functions for reading and parsing CSV files." single ((:commit . "aa1dfa1263565d5fac3879c21d8ddf5f8915e411") (:authors ("Ulf Jasper" . "ulf.jasper@web.de")) (:maintainer "Ulf Jasper" . "ulf.jasper@web.de") (:keywords "extensions" "data" "csv"))])
+ (ct . [(20210219 1344) ((emacs (26 1)) (dash (2 18 0)) (hsluv (1 0 0))) "Color Tools - a color api" single ((:commit . "c302ee94feee0c5efc511e8f9fd8cb2f6dfe3490") (:authors ("neeasade")) (:maintainer "neeasade") (:keywords "convenience" "color" "theming" "rgb" "hsv" "hsl" "cie-lab" "background") (:url . "https://github.com/neeasade/ct.el"))])
+ (ctable . [(20210128 629) ((emacs (24 3)) (cl-lib (0 5))) "Table component for Emacs Lisp" single ((:commit . "48b73742757a3ae5736d825fe49e00034cc453b5") (:authors ("SAKURAI Masashi <m.sakurai at kiwanami.net>")) (:maintainer "SAKURAI Masashi <m.sakurai at kiwanami.net>") (:keywords "table") (:url . "https://github.com/kiwanami/emacs-ctable"))])
+ (ctags-update . [(20190609 613) nil "(auto) update TAGS in parent directory using exuberant-ctags" single ((:commit . "67faf248b92388442958a069263c62a345425a1b") (:authors (nil . "Joseph(纪秀峰) jixiuf@gmail.com")) (:maintainer nil . "Joseph(纪秀峰) jixiuf@gmail.com") (:keywords "exuberant-ctags" "etags") (:url . "https://github.com/jixiuf/ctags-update"))])
+ (ctl-mode . [(20151202 1006) nil "Major mode for editing GrADS script files" single ((:commit . "1a13051db21b999c7682a015b33a03096ff9d891") (:authors ("Joe Wielgosz" . "joew@cola.iges.org")) (:maintainer "Joe Wielgosz" . "joew@cola.iges.org") (:keywords "grads" "script" "major-mode"))])
+ (ctrlf . [(20220501 2234) ((emacs (25 1))) "Emacs finally learns how to ctrl+F" single ((:commit . "efe9534747e056b210e359c3abc67ef94a8ea5ad") (:authors ("Radon Rosborough" . "radon.neon@gmail.com")) (:maintainer "Radon Rosborough" . "radon.neon@gmail.com") (:keywords "extensions") (:url . "https://github.com/raxod502/ctrlf"))])
+ (ctrlxo . [(20201021 701) ((emacs (25 1))) "Switch to the most recently used window" single ((:commit . "8ad95a81bd1ece06ebe40e2a83490775db64b419") (:authors ("Andrii Kolomoiets" . "andreyk.mad@gmail.com")) (:maintainer "Andrii Kolomoiets" . "andreyk.mad@gmail.com") (:keywords "frames") (:url . "https://github.com/muffinmad/emacs-ctrlxo"))])
+ (ctune . [(20210205 1428) ((emacs (26 1))) "Tune out CC Mode Noise Macros" tar ((:commit . "3f7abc6e74d4e5954b476ba9a1dc652f96b10c05") (:authors ("Mauro Aranda" . "maurooaranda@gmail.com")) (:maintainer "Mauro Aranda" . "maurooaranda@gmail.com") (:keywords "c" "convenience") (:url . "https://github.com/maurooaranda/ctune"))])
+ (ctxmenu . [(20140303 2142) ((popup (20140205 103)) (log4e (0 2 0)) (yaxception (0 1))) "Provide a context menu like right-click." tar ((:commit . "5c2376859562b98c07c985d2b483658e4c0e888e") (:authors ("Hiroaki Otsu" . "ootsuhiroaki@gmail.com")) (:maintainer "Hiroaki Otsu" . "ootsuhiroaki@gmail.com") (:keywords "popup") (:url . "https://github.com/aki2o/emacs-ctxmenu"))])
+ (cubicaltt . [(20171108 1402) ((emacs (24 1)) (cl-lib (0 5))) "Mode for cubical type theory" single ((:commit . "a5c6f94bfc0da84e214641e0b87aa9649ea114ea") (:keywords "languages") (:url . "https://github.com/mortberg/cubicaltt"))])
+ (cubicle-mode . [(20171009 1957) nil "Major mode for the Cubicle model checker" single ((:commit . "00f09bb2d4bb496549775e770d7ada08bc1e4866") (:authors ("Alain Mebsout")) (:maintainer "Alain Mebsout"))])
+ (cucumber-goto-step . [(20131210 519) ((pcre2el (1 5))) "Jump to cucumber step definition" single ((:commit . "f2713ffb26ebe1b757d1f2ea80e900b55e5895aa") (:authors ("Glen Stampoultzis" . "gstamp@gmail.com")) (:maintainer "Glen Stampoultzis" . "gstamp@gmail.com") (:url . "http://orthogonal.me"))])
+ (cuda-mode . [(20201013 2230) nil "NVIDIA CUDA Major Mode" single ((:commit . "7f593518fd135fc6af994024bcb47986dfa502d2") (:authors ("Jack Morrison" . "jackmorrison1@gmail.com")) (:maintainer "Jack Morrison" . "jackmorrison1@gmail.com") (:keywords "c" "languages"))])
+ (curl-to-elisp . [(20201124 1012) ((emacs (25 1))) "Convert cURL command to Emacs Lisp code" single ((:commit . "63d8d9c6d5efb8af8aa88042bfc0690ba699ef64") (:authors ("Xu Chunyang")) (:maintainer "Xu Chunyang") (:keywords "lisp") (:url . "https://github.com/xuchunyang/curl-to-elisp"))])
+ (currency-convert . [(20210427 2032) ((emacs (24 4))) "Currency converter" single ((:commit . "12805ea66aa8421de5eedda39d23f709de634460") (:authors ("Lassi Kortela" . "lassi@lassi.io")) (:maintainer "Lassi Kortela" . "lassi@lassi.io") (:keywords "comm" "convenience" "i18n") (:url . "https://github.com/lassik/emacs-currency-convert"))])
+ (current-word-highlight . [(20210323 1401) nil "Highlight the current word minor mode" single ((:commit . "d860f4e170ffa4cef840da93647f458cc409d554") (:authors ("Kijima Daigo" . "norimaking777@gmail.com")) (:maintainer "Kijima Daigo" . "norimaking777@gmail.com") (:keywords "highlight" "face" "convenience" "word") (:url . "https://github.com/kijimaD/current-word-highlight"))])
+ (curry-on-theme . [(20210322 1717) ((emacs (24 1))) "A low contrast color theme" single ((:commit . "b53a61d443cc75906d9f97e19f19be71f1e19bc4") (:authors ("Martín Varela" . "martin@varela.fi")) (:maintainer "Martín Varela" . "martin@varela.fi") (:url . "https://github.com/mvarela/Curry-On-Theme"))])
+ (cursor-flash . [(20210722 445) ((emacs (24 3))) "Highlight the cursor on buffer/window-switch" single ((:commit . "6bb54a1e2e1bf9df80926718b1b8b9ee49080484") (:keywords "convenience" "faces" "maint") (:url . "https://github.com/Boruch-Baum/emacs-cursor-flash"))])
+ (cursor-test . [(20131207 1732) ((emacs (24))) "testing library for cursor position in emacs." single ((:commit . "e09956e048b88fd2ee8dd90b5678baed8b04d31b") (:authors ("ainame")) (:maintainer "ainame") (:url . "https://github.com/ainame/cursor-test.el"))])
+ (cwl-mode . [(20210510 1150) ((yaml-mode (0 0 13)) (emacs (24 4))) "A major mode for editing CWL" single ((:commit . "23a333119efaac78453cba95d316109805bd6aec") (:authors ("Tomoya Tanjo" . "ttanjo@gmail.com")) (:maintainer "Tomoya Tanjo" . "ttanjo@gmail.com") (:keywords "languages" "cwl" "common workflow language") (:url . "https://github.com/tom-tan/cwl-mode"))])
+ (cyberpunk-2019-theme . [(20191008 1133) ((emacs (24 1))) "A retina-scorching cyberpunk theme" single ((:commit . "7e40c37210c363b2819fd9bb98a73101d7a3c206") (:authors ("Alex Lynham" . "alex@lynh.am")) (:maintainer "Alex Lynham" . "alex@lynh.am") (:keywords "cyberpunk" "theme" "themes") (:url . "https://github.com/the-frey/cyberpunk-2019"))])
+ (cyberpunk-theme . [(20200601 1632) nil "Cyberpunk Color Theme" single ((:commit . "cbd0d7193e69ff9e98262eb06aee3d27667ff5f5") (:authors ("Nicholas M. Van Horn" . "nvanhorn@protonmail.com")) (:maintainer "Nicholas M. Van Horn" . "nvanhorn@protonmail.com") (:keywords "color" "theme" "cyberpunk") (:url . "https://github.com/n3mo/cyberpunk-theme.el"))])
+ (cycbuf . [(20131203 2037) nil "Cycle buffers, inspired by swbuff.el, swbuff-x.el, and bs.el" single ((:commit . "1079b41c3eb27d65b66d4399959bb6253f84858e") (:authors ("Martin Pohlack martinp (at) gmx.de")) (:maintainer "Martin Pohlack martinp (at) gmx.de") (:keywords "files" "convenience" "buffer switching") (:url . "https://github.com/martinp26/cycbuf"))])
+ (cycle-at-point . [(20220406 1340) ((emacs (28 1)) (recomplete (0 2))) "Cycle (rotate) the thing under the cursor" tar ((:commit . "4637a9288028f3eaa31cfa9658cfe78f423b16cf") (:authors ("Campbell Barton")) (:maintainer "Campbell Barton") (:keywords "convenience") (:url . "https://gitlab.com/ideasman42/emacs-cycle-at-point"))])
+ (cycle-resize . [(20160521 1557) nil "Cycle resize the current window horizontally or vertically" single ((:commit . "7d255d6fe85f12c967a0f7fcfcf18633be194c88") (:authors ("Pierre Lecocq")) (:maintainer "Pierre Lecocq") (:url . "https://github.com/pierre-lecocq/cycle-resize"))])
+ (cycle-themes . [(20150403 309) ((cl-lib (0 5))) "A global minor mode to make switching themes easier" single ((:commit . "6e125d11fdbc6b78fc9f219eb2609a5e29815898") (:keywords "themes" "utility" "global minor mode") (:url . "http://github.com/toroidal-code/cycle-themes.el"))])
+ (cyphejor . [(20210816 1607) ((emacs (24 4))) "Shorten major mode names using user-defined rules" single ((:commit . "576d237a46be79449a22e3a7912a3464d7b0c233") (:authors ("Mark Karpov" . "markkarpov92@gmail.com")) (:maintainer "Mark Karpov" . "markkarpov92@gmail.com") (:keywords "mode-line" "major-mode") (:url . "https://github.com/mrkkrp/cyphejor"))])
+ (cypher-mode . [(20151110 1142) nil "major mode for editing cypher scripts" single ((:commit . "ce8543d7877c736c574a17b49874c9dcdc7a06d6") (:authors ("François-Xavier Bois <fxbois AT Google Mail Service>")) (:maintainer "François-Xavier Bois") (:keywords "cypher" "graph") (:url . "http://github.com/fxbois/cypher-mode"))])
+ (cython-mode . [(20211111 1407) nil "Major mode for editing Cython files" single ((:commit . "04934f5db17ac782de08b8f8595e38b59e445e2b"))])
+ (czech-holidays . [(20160113 1752) nil "Adds a list of Czech public holidays to Emacs calendar" single ((:commit . "d136fa09a152b3cd80db6d55c7b4ddfe07b90fbf") (:authors ("David Chkhikvadze" . "david.chk@outlook.com")) (:maintainer "David Chkhikvadze" . "david.chk@outlook.com") (:keywords "calendar"))])
+ (d-mode . [(20210119 1853) ((emacs (25 1))) "D Programming Language major mode for (X)Emacs" single ((:commit . "199743df55c6bfce3cdb08405bd8519768c8dfa9") (:authors ("William Baxter")) (:maintainer "Russel Winder" . "russel@winder.org.uk") (:keywords "d" "programming" "language" "emacs" "cc-mode"))])
+ (dactyl-mode . [(20140906 1725) nil "Major mode for editing Pentadactyl config files" single ((:commit . "cc55fe6b987271d9647492b8df4c812d884f661f") (:keywords "languages" "vim") (:url . "https://github.com/luxbock/dactyl-mode"))])
+ (dad-joke . [(20170928 658) ((emacs (24))) "Get/display dad jokes" single ((:commit . "bee47e7b746b403228fa7d7361cb095de19ac9ba") (:authors ("Dave Pearson" . "davep@davep.org")) (:maintainer "Dave Pearson" . "davep@davep.org") (:keywords "games") (:url . "https://github.com/davep/dad-joke.el"))])
+ (daemons . [(20211214 1251) ((emacs (25 1))) "UI for managing init system daemons (services)" tar ((:commit . "e18e84ccc13101f1609c213029cf011ae0ad1178") (:authors ("Chris Bowdon")) (:maintainer "Chris Bowdon") (:keywords "unix" "convenience") (:url . "https://github.com/cbowdon/daemons.el"))])
+ (dakrone-light-theme . [(20170808 2140) nil "dakrone's custom light theme" single ((:commit . "06f198dc8b4ca7421990b30a23d89c8e0b8c5de4") (:authors ("Lee Hinman <lee _AT_ writequit.org>")) (:maintainer "Lee Hinman <lee _AT_ writequit.org>") (:keywords "color" "themes" "faces") (:url . "https://github.com/dakrone/dakrone-light-theme"))])
+ (dakrone-theme . [(20170801 1933) nil "dakrone's custom dark theme" single ((:commit . "232ad1be5f3572dcbdf528f1655109aa355a6937") (:authors ("Lee Hinman <lee _AT_ writequit.org>")) (:maintainer "Lee Hinman <lee _AT_ writequit.org>") (:keywords "color" "themes") (:url . "https://github.com/dakrone/dakrone-theme"))])
+ (danneskjold-theme . [(20220316 1101) nil "Beautiful high-contrast Emacs theme." tar ((:commit . "054c0b9bc9cefb53a4065096e66707d20885c461") (:authors ("Dmitry Akatov" . "akatovda@yandex.com")) (:maintainer "Dmitry Akatov" . "akatovda@yandex.com") (:url . "https://github.com/rails-to-cosmos/"))])
+ (dante . [(20220429 1454) ((dash (2 12 0)) (emacs (25 1)) (f (0 19 0)) (flycheck (0 30)) (company (0 9)) (haskell-mode (13 14)) (s (1 11 0)) (lcr (1 0))) "Development mode for Haskell" single ((:commit . "b81081c2eb8dcbd7e67e05cf5e1991df6cf3e57c") (:authors ("Jean-Philippe Bernardy" . "jeanphilippe.bernardy@gmail.com")) (:maintainer "Jean-Philippe Bernardy" . "jeanphilippe.bernardy@gmail.com") (:keywords "haskell" "tools") (:url . "https://github.com/jyp/dante"))])
+ (dap-mode . [(20220504 1410) ((emacs (26 1)) (dash (2 18 0)) (lsp-mode (6 0)) (bui (1 1 0)) (f (0 20 0)) (s (1 12 0)) (lsp-treemacs (0 1)) (posframe (0 7 0)) (ht (2 3))) "Debug Adapter Protocol mode" tar ((:commit . "675d5a8e959ab0f2d1f8261a7cf99e6d8f169118") (:authors ("Ivan Yonchovski" . "yyoncho@gmail.com")) (:maintainer "Ivan Yonchovski" . "yyoncho@gmail.com") (:keywords "languages" "debug") (:url . "https://github.com/emacs-lsp/dap-mode"))])
+ (darcsum . [(20190316 2215) nil "a pcl-cvs like interface for managing darcs patches" single ((:commit . "6a8b690539d133c5e3d17cb23fe4365fbb6fb493") (:authors ("John Wiegley" . "johnw@gnu.org")) (:maintainer "John Wiegley" . "johnw@gnu.org") (:keywords "completion" "convenience" "tools" "vc"))])
+ (darcula-theme . [(20171227 1845) nil "Inspired by IntelliJ's Darcula theme" single ((:commit . "d9b82b58ded9014985be6658f4ab17e26ed9e93e") (:authors ("Sam Halliday" . "Sam.Halliday@gmail.com")) (:maintainer "Sam Halliday" . "Sam.Halliday@gmail.com") (:keywords "faces") (:url . "https://gitlab.com/fommil/emacs-darcula-theme"))])
+ (dark-krystal-theme . [(20170808 1300) ((emacs (24 0))) "an Emacs 24 theme based on Dark Krystal (tmTheme)" single ((:commit . "79084b99665dc9ffb0ec62cc092349a5ecebebbc") (:authors ("Jason Milkins")) (:maintainer "Jason Milkins") (:url . "https://github.com/emacsfodder/tmtheme-to-deftheme"))])
+ (dark-mint-theme . [(20160302 642) nil "dark & minty fresh theme" single ((:commit . "95c30a26de31549cd341184ba9ab2be8fdc67eba"))])
+ (dark-souls . [(20140314 1128) nil "Prepare to die" single ((:commit . "94122b1215423e58dcf18584a2bd022029d54d4b") (:authors ("Tom Jakubowski" . "tom@crystae.net")) (:maintainer "Tom Jakubowski" . "tom@crystae.net") (:keywords "games") (:url . "http://github.com/tomjakubowski/dark-souls.el"))])
+ (darkburn-theme . [(20170423 1652) nil "A not-so-low contrast color theme for Emacs." single ((:commit . "0af794ff7fac19778ac8a7efb92455c6f6c2158f") (:authors ("Jonas Gorauskas" . "jgorauskas@gmail.com")) (:maintainer "Jonas Gorauskas" . "jgorauskas@gmail.com") (:url . "http://github.com/gorauskas/darkburn-theme"))])
+ (darkmine-theme . [(20160406 624) nil "Yet another emacs dark color theme." single ((:commit . "7f7e82ca03bcad52911fa41fb3e204e32d6ee63e") (:authors ("Pierre Lecocq" . "pierre.lecocq@gmail.com")) (:maintainer "Pierre Lecocq" . "pierre.lecocq@gmail.com") (:url . "https://github.com/pierre-lecocq/darkmine-theme"))])
+ (darkokai-theme . [(20200614 1452) nil "A darker variant on Monokai." single ((:commit . "5820aeddfc8c869ba840cc534eba776936656a66") (:url . "http://github.com/sjrmanning/darkokai"))])
+ (darktooth-theme . [(20201215 822) ((autothemer (0 2))) "From the darkness... it watches" single ((:commit . "ec03b30ee7f43f89ca4c382bb3fe4ee560c028a8") (:url . "http://github.com/emacsfodder/emacs-theme-darktooth"))])
+ (dart-mode . [(20220401 0) ((emacs (24 3))) "Major mode for editing Dart files" single ((:commit . "9c846769abd37f7fdc7ba8388d1f3a2b844b75e3") (:authors ("https://github.com/bradyt/dart-mode/issues")) (:maintainer "https://github.com/bradyt/dart-mode/issues") (:keywords "languages") (:url . "https://github.com/bradyt/dart-mode"))])
+ (dart-server . [(20210501 1445) ((emacs (24 5)) (cl-lib (0 5)) (dash (2 10 0)) (flycheck (0 23)) (s (1 10))) "Minor mode for editing Dart files" single ((:commit . "75562baf9a89b7e314bc2f795f6ecdc5d1f2cc8c") (:authors ("Natalie Weizenbaum") ("Brady Trainor" . "mail@bradyt.com")) (:maintainer "Brady Trainor" . "mail@bradyt.com") (:keywords "languages") (:url . "https://github.com/bradyt/dart-server"))])
+ (dash . [(20220417 2250) ((emacs (24))) "A modern list library for Emacs" tar ((:commit . "7fd71338dce041b352f84e7939f6966f4d379459") (:authors ("Magnar Sveen" . "magnars@gmail.com")) (:maintainer "Magnar Sveen" . "magnars@gmail.com") (:keywords "extensions" "lisp") (:url . "https://github.com/magnars/dash.el"))])
+ (dash-alfred . [(20191024 450) ((emacs (25 1))) "Search Dash documentation via Dash-Alfred-Workflow" single ((:commit . "fcd21bd6c7eb5cd31377be970406ff3d2454bd5c") (:authors ("Xu Chunyang")) (:maintainer "Xu Chunyang") (:keywords "docs") (:url . "https://github.com/xuchunyang/dash-alfred.el"))])
+ (dash-at-point . [(20211023 104) nil "Search the word at point with Dash" single ((:commit . "fba1a6f42ea51d05110e12c62bdced664059eb55") (:authors ("Shinji Tanaka" . "shinji.tanaka@gmail.com")) (:maintainer "Shinji Tanaka" . "shinji.tanaka@gmail.com") (:url . "https://github.com/stanaka/dash-at-point"))])
+ (dash-docs . [(20210830 926) ((emacs (24 4)) (cl-lib (0 5)) (async (1 9 3))) "Offline documentation browser using Dash docsets." tar ((:commit . "29848b6b347ac520f7646c200ed2ec36cea3feda") (:authors ("Raimon Grau" . "raimonster@gmail.com") ("Toni Reina " . "areina0@gmail.com") ("Bryan Gilbert" . "bryan@bryan.sh")) (:maintainer "Raimon Grau" . "raimonster@gmail.com") (:keywords "docs") (:url . "http://github.com/areina/helm-dash"))])
+ (dash-functional . [(20210210 1449) ((dash (2 18 0))) "Collection of useful combinators for Emacs Lisp" single ((:commit . "7fd71338dce041b352f84e7939f6966f4d379459") (:authors ("Matus Goljer" . "matus.goljer@gmail.com") ("Magnar Sveen" . "magnars@gmail.com")) (:maintainer "Matus Goljer" . "matus.goljer@gmail.com") (:keywords "extensions" "lisp") (:url . "https://github.com/magnars/dash.el"))])
+ (dashboard . [(20220409 620) ((emacs (26 1))) "A startup screen extracted from Spacemacs" tar ((:commit . "09290bf700cc269ad3c07d9518cd758b90971fcd") (:authors ("Rakan Al-Hneiti" . "rakan.alhneiti@gmail.com")) (:maintainer "Jesús Martínez" . "jesusmartinez93@gmail.com") (:keywords "startup" "screen" "tools" "dashboard") (:url . "https://github.com/emacs-dashboard/emacs-dashboard"))])
+ (dashboard-hackernews . [(20190109 205) ((emacs (24)) (dashboard (1 2 5)) (request (0 3 0))) "Display Hacker News on dashboard" single ((:commit . "b71814716d8f78181b9d1990f06072460de0797e") (:authors ("Hayato KAJIYAMA" . "kaji1216@gmail.com")) (:maintainer "Hayato KAJIYAMA" . "kaji1216@gmail.com") (:url . "https://github.com/hyakt/emacs-dashboard-hackernews"))])
+ (dashboard-ls . [(20220326 628) ((emacs (24 3)) (dashboard (1 2 5))) "Display files/directories in current directory on Dashboard" single ((:commit . "d8c435ac251ec6493da10882cb161c0e9df03b91") (:authors ("Shen, Jen-Chieh" . "jcs090218@gmail.com")) (:maintainer "Shen, Jen-Chieh" . "jcs090218@gmail.com") (:url . "https://github.com/emacs-dashboard/dashboard-ls"))])
+ (dashboard-project-status . [(20190202 1354) ((emacs (24)) (git (0 1 1)) (dashboard (1 2 5))) "Display a git project status in a dashboard widget." single ((:commit . "7675c138e9df8fe2c626e7ba9bbb8b6717671a41") (:authors ("Jason Duncan" . "jasond496@msn.com")) (:maintainer "Jason Duncan" . "jasond496@msn.com") (:url . "https://github.com/functionreturnfunction/dashboard-project-status"))])
+ (date-at-point . [(20150308 1243) nil "Add `date' to `thing-at-point' function" single ((:commit . "38df823d05df08ec0748a4185113fae5f99090e9") (:authors ("Alex Kost" . "alezost@gmail.com")) (:maintainer "Alex Kost" . "alezost@gmail.com") (:keywords "convenience") (:url . "https://github.com/alezost/date-at-point.el"))])
+ (date-field . [(20141129 105) ((dash (2 9 0)) (log4e (0 2 0)) (yaxception (0 3 2))) "Date widget" single ((:commit . "11c9170d1f7b343233f7716d4c0a62be024c1654") (:authors ("Hiroaki Otsu" . "ootsuhiroaki@gmail.com")) (:maintainer "Hiroaki Otsu" . "ootsuhiroaki@gmail.com") (:keywords "widgets") (:url . "https://github.com/aki2o/emacs-date-field"))])
+ (date2name . [(20190630 933) ((emacs (24 4))) "Package to prepend ISO Timestamps to files" single ((:commit . "386dbe73678705d6107cd5c9bdeb4f7c97632360") (:authors ("Max Beutelspacher")) (:maintainer "Max Beutelspacher") (:keywords "files" "convenience") (:url . "https://github.com/DerBeutlin/date2name.el"))])
+ (datetime . [(20211016 1656) ((emacs (24 4)) (extmap (1 1 1))) "Parsing, formatting and matching timestamps" tar ((:commit . "77dc214d9ae853c7206ae95cc92d720445c1eeb4") (:authors ("Paul Pogonyshev" . "pogonyshev@gmail.com")) (:maintainer "Paul Pogonyshev" . "pogonyshev@gmail.com") (:keywords "lisp" "i18n") (:url . "https://github.com/doublep/datetime"))])
+ (datetime-format . [(20160612 1715) nil "Datetime functions" single ((:commit . "e6427538b547cbe02e1bd6ed4b765c73620bdae8") (:authors ("USAMI Kenta" . "tadsan@zonu.me")) (:maintainer "USAMI Kenta" . "tadsan@zonu.me") (:keywords "datetime" "calendar") (:url . "https://github.com/zonuexe/emacs-datetime"))])
+ (datomic-snippets . [(20180817 1045) ((s (1 4 0)) (dash (1 2 0)) (yasnippet (0 6 1))) "Yasnippets for Datomic" tar ((:commit . "4a14228840d5252e13d2bf6209670f26345bbb84") (:authors ("Magnar Sveen" . "magnars@gmail.com")) (:maintainer "Magnar Sveen" . "magnars@gmail.com") (:keywords "snippets"))])
+ (dayone . [(20160105 1240) ((uuid (0 0 3)) (mustache (0 22)) (ht (1 5))) "Utility script for Day One" tar ((:commit . "ab628274f0806451f23bce16f62a6a11cbf91a2b") (:authors ("mori-dev" . "mori.dev.asdf@gmail.com")) (:maintainer "mori-dev" . "mori.dev.asdf@gmail.com") (:keywords "day one" "tools" "convenience") (:url . "https://github.com/mori-dev/emacs-dayone"))])
+ (db . [(20140421 2111) ((kv (0 0 11))) "A database for EmacsLisp" single ((:commit . "b3a423fb8e72f9013009cbe033d654df2ce31438") (:authors ("Nic Ferrier" . "nferrier@ferrier.me.uk")) (:maintainer "Nic Ferrier" . "nferrier@ferrier.me.uk") (:keywords "data" "lisp"))])
+ (db-pg . [(20130131 1902) ((pg (0 12)) (db (0 0 6))) "A PostgreSQL adapter for emacs-db" single ((:commit . "7d5ab86b74b05fe003b3b434d4835f37f3f3eded") (:authors ("Nic Ferrier" . "nic@ferrier.me.uk")) (:maintainer "Nic Ferrier" . "nic@ferrier.me.uk") (:keywords "data" "comm" "database" "postgresql"))])
+ (dbc . [(20201001 1452) ((emacs (24 4)) (cl-lib (0 5)) (ht (2 3))) "Control how to open buffers" single ((:commit . "6728e72f72347d098b7d75ac4c29a7d687cc9ed3") (:authors ("Matsievskiy S.V.")) (:maintainer "Matsievskiy S.V.") (:keywords "convenience") (:url . "https://gitlab.com/matsievskiysv/display-buffer-control"))])
+ (ddskk . [(20220501 2005) ((ccc (1 43)) (cdb (20141201 754))) "Simple Kana to Kanji conversion program." tar ((:commit . "c664b26d0861621ac86b5b5f47835dd84f06dc93"))])
+ (ddskk-posframe . [(20200812 917) ((emacs (26 1)) (posframe (0 4 3)) (ddskk (16 2 50))) "Show Henkan tooltip for ddskk via posframe" single ((:commit . "299493dd951e5a0b43b8213321e3dc0bac10f762") (:authors ("Naoya Yamashita" . "conao3@gmail.com")) (:maintainer "Naoya Yamashita" . "conao3@gmail.com") (:keywords "tooltip" "convenience" "posframe") (:url . "https://github.com/conao3/ddskk-posframe.el"))])
+ (deadgrep . [(20220418 741) ((emacs (25 1)) (dash (2 12 0)) (s (1 11 0)) (spinner (1 7 3))) "fast, friendly searching with ripgrep" single ((:commit . "bd5d00be3637dcd9e0b14966b87e3d8151710db0") (:authors ("Wilfred Hughes" . "me@wilfred.me.uk")) (:maintainer "Wilfred Hughes" . "me@wilfred.me.uk") (:keywords "tools") (:url . "https://github.com/Wilfred/deadgrep"))])
+ (debian-el . [(20211006 1939) nil "Emacs helpers specific to Debian users" tar ((:commit . "a3ef20c269b9192710567571b20718f572942bc4"))])
+ (debpaste . [(20160113 2347) ((xml-rpc (1 6 7))) "Interface for getting/posting/deleting pastes from paste.debian.net" single ((:commit . "6f2a400665062468ebd03a2ce1de2a73d9084958") (:authors ("Alex Kost" . "alezost@gmail.com")) (:maintainer "Alex Kost" . "alezost@gmail.com") (:keywords "paste") (:url . "http://github.com/alezost/debpaste.el"))])
+ (debug-print . [(20140126 19) ((emacs (24))) "A nice printf debugging environment by the way Gauche do" single ((:commit . "d817fd9ea2d3f8d2c1ace4d8af155684f3a99dc5") (:authors ("Ken Okada" . "keno.ss57@gmail.com")) (:maintainer "Ken Okada" . "keno.ss57@gmail.com") (:keywords "extensions" "lisp" "tools" "maint") (:url . "https://github.com/kenoss/debug-print"))])
+ (decide . [(20220319 1927) nil "rolling dice and other random things" single ((:commit . "b4feee9d5ad32c7b73ab3e1da5cfcdab532754c2") (:authors ("Pelle Nilsson" . "perni@lysator.liu.se")) (:maintainer "Pelle Nilsson" . "perni@lysator.liu.se"))])
+ (decl . [(20220102 1310) ((dash (2 5 0)) (emacs (24 3)) (cl-lib (0 3))) "Library for organizing code declaratively" single ((:commit . "9e6e2395e1f739e390697c35a9af99452642869e") (:authors ("Preetpal S. Sohal")) (:maintainer "Preetpal S. Sohal") (:url . "https://github.com/preetpalS/decl.el"))])
+ (declutter . [(20220310 2101) ((emacs (25 1))) "Read html content and (some) paywall sites without clutter" single ((:commit . "8ac50a64dc3a12440d98bc1556b5c7727fdf51ed") (:authors ("Sanel Zukan" . "sanelz@gmail.com")) (:maintainer "Sanel Zukan" . "sanelz@gmail.com") (:keywords "html" "hypermedia" "terminals") (:url . "http://www.github.com/sanel/declutter"))])
+ (dedicated . [(20151202 110) nil "A very simple minor mode for dedicated buffers" single ((:commit . "f47b504c0c56fa5ab9d1028417ca1f65a713a2f0") (:authors ("Eric Crampton" . "eric@atdesk.com")) (:maintainer "Eric Crampton" . "eric@atdesk.com") (:keywords "dedicated" "buffer"))])
+ (dedukti-mode . [(20171103 1212) nil "Major mode for Dedukti files" single ((:commit . "d7c3505a1046187de3c3aeb144455078d514594e") (:authors ("Raphaël Cauderlier")) (:maintainer "Raphaël Cauderlier") (:keywords "languages" "dedukti") (:url . "https://github.com/rafoo/dedukti-mode"))])
+ (default-font-presets . [(20220430 135) ((emacs (26 1))) "Support selecting fonts from a list of presets" single ((:commit . "ea79012408f99bd1ee952f22bee59c22c124fdd6") (:authors ("Campbell Barton" . "ideasman42@gmail.com")) (:maintainer "Campbell Barton" . "ideasman42@gmail.com") (:url . "https://gitlab.com/ideasman42/emacs-default-font-presets"))])
+ (default-text-scale . [(20191226 2234) ((emacs (24))) "Easily adjust the font size in all frames" single ((:commit . "bfc0987c37e93742255d3b23d86c17096fda8e7e") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:keywords "frames" "faces") (:url . "https://github.com/purcell/default-text-scale"))])
+ (deferred . [(20170901 1330) ((emacs (24 4))) "Simple asynchronous functions for emacs lisp" single ((:commit . "2239671d94b38d92e9b28d4e12fd79814cfb9c16") (:authors ("SAKURAI Masashi <m.sakurai at kiwanami.net>")) (:maintainer "SAKURAI Masashi <m.sakurai at kiwanami.net>") (:keywords "deferred" "async") (:url . "https://github.com/kiwanami/emacs-deferred"))])
+ (define-it . [(20220414 932) ((emacs (25 1)) (s (1 12 0)) (request (0 3 0)) (popup (0 5 3)) (pos-tip (0 4 6)) (posframe (1 1 7)) (google-translate (0 11 18)) (wiki-summary (0 1))) "Define, translate, wiki the word" single ((:commit . "51fd884c52faf61339aef3a3429fe91672b3e6a8") (:authors ("Shen, Jen-Chieh" . "jcs090218@gmail.com")) (:maintainer "Shen, Jen-Chieh" . "jcs090218@gmail.com") (:url . "https://github.com/jcs-elpa/define-it"))])
+ (define-word . [(20220104 1848) ((emacs (24 3))) "display the definition of word at point." single ((:commit . "31a8c67405afa99d0e25e7c86a4ee7ef84a808fe") (:authors ("Oleh Krehel" . "ohwoeowho@gmail.com")) (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com") (:keywords "dictionary" "convenience") (:url . "https://github.com/abo-abo/define-word"))])
+ (defproject . [(20151201 2219) ((emacs (24))) "Manager dir-locals and project specific variables" single ((:commit . "674d48a5e34cb4bba76faa38ee901322ec649086") (:authors (nil . "<kotfic@gmail.com>")) (:maintainer nil . "<kotfic@gmail.com>") (:keywords "convenience") (:url . "https://github.com/kotfic/defproject"))])
+ (defrepeater . [(20180830 410) ((emacs (25 2)) (s (1 12 0))) "Easily make commands repeatable" single ((:commit . "9c027a2561fe141dcfb79f75fcaee36cd0386ec1") (:authors ("Adam Porter" . "adam@alphapapa.net")) (:maintainer "Adam Porter" . "adam@alphapapa.net") (:keywords "convenience") (:url . "http://github.com/alphapapa/defrepeater.el"))])
+ (deft . [(20210707 1633) nil "quickly browse, filter, and edit plain text notes" single ((:commit . "28be94d89bff2e1c7edef7244d7c5ba0636b1296") (:authors ("Jason R. Blevins" . "jrblevin@xbeta.org")) (:maintainer "Jason R. Blevins" . "jrblevin@xbeta.org") (:keywords "plain text" "notes" "simplenote" "notational velocity") (:url . "https://jblevins.org/projects/deft/"))])
+ (delim-kill . [(20100517 620) nil "Kill text between delimiters." single ((:commit . "1dbe47344f2d2cbc8c54beedf0cf0bf10fd203c1") (:authors ("Thomas Kappler" . "tkappler@gmail.com")) (:maintainer "Thomas Kappler" . "tkappler@gmail.com") (:keywords "convenience" "languages") (:url . "http://github.com/thomas11/delim-kill/tree/master"))])
+ (demangle-mode . [(20210822 2210) ((cl-lib (0 1)) (emacs (24 3))) "Automatically demangle C++, D, and Rust symbols" single ((:commit . "04f545adab066708d6151f13da65aaf519f8ac4e") (:authors ("Ben Liblit" . "liblit@acm.org")) (:maintainer "Ben Liblit" . "liblit@acm.org") (:keywords "c" "tools") (:url . "https://github.com/liblit/demangle-mode"))])
+ (demap . [(20220322 2309) ((emacs (25 1))) "Detachable minimap package" tar ((:commit . "c42ec4752544f80ca7c172ff65e705a56089bc96") (:authors ("Sawyer Gardner <https://gitlab.com/sawyerjgardner>")) (:maintainer "Sawyer Gardner <https://gitlab.com/sawyerjgardner>") (:keywords "lisp" "tools" "convenience") (:url . "https://gitlab.com/sawyerjgardner/demap.el"))])
+ (demo-it . [(20211221 2152) nil "Create demonstrations" tar ((:commit . "e399fd7ceb73caeae7cb50b247359bafcaee2a3f") (:authors ("Howard Abrams" . "howard.abrams@gmail.com")) (:maintainer "Howard Abrams" . "howard.abrams@gmail.com") (:keywords "demonstration" "presentation" "test"))])
+ (deno-fmt . [(20200520 1838) ((emacs (24))) "Minor mode for using deno fmt on save" single ((:commit . "3b193eef576e2c14fdcf350495955e6e8546dddd") (:authors ("Russell Clarey <http://github/rclarey>")) (:maintainer "Russell Clarey <http://github/rclarey>") (:url . "https://github.com/russell/deno-emacs"))])
+ (describe-hash . [(20200718 1556) nil "Help function for examining a hash map" single ((:commit . "18e69a932d5495c8439571ba8f2d2ee123d434b1") (:url . "https://github.com/Junker/describe-hash"))])
+ (describe-number . [(20151101 55) ((yabin (1 1))) "Describe arbitrarily large number at point." single ((:commit . "40618345a37831804b29589849a785ef5aa5ac24") (:authors ("Morten Slot Kristensen <msk AT nullpointer DOT dk>")) (:maintainer "Morten Slot Kristensen <msk AT nullpointer DOT dk>") (:keywords "describe" "value" "help") (:url . "https://github.com/netromdk/describe-number"))])
+ (desktop+ . [(20170107 2132) ((emacs (24 4)) (dash (2 11 0)) (f (0 17 2))) "Handle special buffers when saving & restoring sessions" single ((:commit . "88055cee526a000056201898499cebbd35e3ea76") (:authors ("François Févotte" . "fevotte@gmail.com")) (:maintainer "François Févotte" . "fevotte@gmail.com") (:url . "https://github.com/ffevotte/desktop-plus"))])
+ (desktop-environment . [(20220425 1834) ((emacs (25 1))) "Helps you control your GNU/Linux computer" single ((:commit . "2863dc3d66aed9052c8af39cc8c8c264be300560") (:authors ("Damien Cassou <damien@cassou.me>, Nicolas Petton" . "nicolas@petton.fr")) (:maintainer "Damien Cassou <damien@cassou.me>, Nicolas Petton" . "nicolas@petton.fr") (:url . "https://gitlab.petton.fr/DamienCassou/desktop-environment"))])
+ (desktop-mail-user-agent . [(20210519 1008) ((emacs (24 3))) "Call OS default mail program to compose mail" single ((:commit . "caac672ef7e4ddced960fa31cef3a6ba5d7ab451") (:authors ("Lassi Kortela" . "lassi@lassi.io")) (:maintainer "Lassi Kortela" . "lassi@lassi.io") (:keywords "mail") (:url . "https://github.com/lassik/emacs-desktop-mail-user-agent"))])
+ (desktop-registry . [(20140119 2143) nil "Keep a central registry of desktop files" single ((:commit . "244c2e7f9f0a1050aa8a47ad0b38f4e4584682dd") (:authors ("Tom Willemse" . "tom@ryuslash.org")) (:maintainer "Tom Willemse" . "tom@ryuslash.org") (:keywords "convenience") (:url . "http://projects.ryuslash.org/desktop-registry/"))])
+ (detour . [(20181122 2138) ((emacs (24 4))) "Take a quick detour and return" single ((:commit . "1ff23c236e18971ed1077840daf047cde79a45ee") (:authors ("Stefan Kamphausen <www.skamphausen.de>")) (:maintainer "Stefan Kamphausen <www.skamphausen.de>") (:keywords "convenience" "abbrev") (:url . "https://github.com/ska2342/detour/"))])
+ (devdocs . [(20220410 1627) ((emacs (27 1))) "Emacs viewer for DevDocs" single ((:commit . "4257e59dafbffb2616d240f84c5c25770ee28cac") (:authors ("Augusto Stoffel" . "arstoffel@gmail.com")) (:maintainer "Augusto Stoffel" . "arstoffel@gmail.com") (:keywords "help") (:url . "https://github.com/astoff/devdocs.el"))])
+ (devdocs-browser . [(20211218 949) ((emacs (27 1))) "Browse devdocs.io documents using EWW" single ((:commit . "a46a2cdb83ed27869befe56fea04914a33252b3a") (:authors ("blahgeek" . "i@blahgeek.com")) (:maintainer "blahgeek" . "i@blahgeek.com") (:keywords "docs" "help" "tools") (:url . "https://github.com/blahgeek/emacs-devdocs-browser"))])
+ (dfmt . [(20170728 1023) nil "Emacs Interface to D indenting/formatting tool dfmt." single ((:commit . "21b9094e907b7ac53f5ecb4ff4539613a9d12434") (:authors ("Per Nordlöw")) (:maintainer "Kirill Babikhin <qsimpleq>") (:keywords "tools" "convenience" "languages" "dlang") (:url . "https://github.com/qsimpleq/elisp-dfmt"))])
+ (dhall-mode . [(20200822 258) ((emacs (24 4)) (reformatter (0 3))) "Major mode for the dhall configuration language" single ((:commit . "ad259c8a2292fb398dff1ce7d25c686edb02945d") (:authors ("Sibi Prabakaran" . "sibi@psibi.in")) (:maintainer "Sibi Prabakaran" . "sibi@psibi.in") (:keywords "languages") (:url . "https://github.com/psibi/dhall-mode"))])
+ (dianyou . [(20210525 1517) ((emacs (24 4))) "Search and analyze mails in Gnus" single ((:commit . "f77d9e76be5d8022fa6ee5426144f13f38dd09f2") (:authors ("Chen Bin <chenbin DOT sh AT gmail DOT com>")) (:maintainer "Chen Bin <chenbin DOT sh AT gmail DOT com>") (:keywords "mail") (:url . "http://github.com/redguardtoo/dianyou"))])
+ (diary-manager . [(20210404 1821) ((emacs (25))) "Simple personal diary" single ((:commit . "0fa122be62dd296cefe23bcf5074cc6159bd9868") (:authors ("Radon Rosborough" . "radon.neon@gmail.com")) (:maintainer "Radon Rosborough" . "radon.neon@gmail.com") (:keywords "extensions") (:url . "https://github.com/raxod502/diary-manager"))])
+ (dic-lookup-w3m . [(20180526 1621) ((w3m (20120723 324)) (stem (20120826))) "look up dictionaries on the Internet" tar ((:commit . "3254ab10cbf0078c7162557dd1f68dac28459cf9") (:authors ("mcprvmec")) (:maintainer "mcprvmec") (:keywords "emacs-w3m" "w3m" "dictionary"))])
+ (dictcc . [(20220219 1302) ((emacs (24 4)) (cl-lib (0 5)) (ivy (0 10 0))) "Look up translations on dict.cc" single ((:commit . "8ecb954fcf193cba138191f8947c8b0b60a1c6c5") (:authors ("Marten Lienen" . "marten.lienen@gmail.com")) (:maintainer "Marten Lienen" . "marten.lienen@gmail.com") (:keywords "convenience"))])
+ (dictionary . [(20201001 1727) ((connection (1 11)) (link (1 11))) "Client for rfc2229 dictionary servers" single ((:commit . "bdf0aa7761d1c1a3bc0652b2fdc4a54b3acdb06a") (:authors ("Torsten Hilbrich" . "torsten.hilbrich@gmx.net")) (:maintainer "Torsten Hilbrich" . "torsten.hilbrich@gmx.net") (:keywords "interface" "dictionary"))])
+ (didyoumean . [(20200905 1843) ((emacs (24 4))) "Did you mean to open another file?" single ((:commit . "ce5edcce160b86e7f6480f0381be785d43f97e19") (:keywords "convenience") (:url . "https://gitlab.com/kisaragi-hiu/didyoumean.el"))])
+ (diff-ansi . [(20220422 647) ((emacs (27 1))) "Display diff's using alternative diffing tools" single ((:commit . "f47e62503d77dbcadb36e9d3d0ede9242536fa89") (:authors ("Campbell Barton" . "ideasman42@gmail.com")) (:maintainer "Campbell Barton" . "ideasman42@gmail.com") (:url . "https://gitlab.com/ideasman42/emacs-diff-ansi"))])
+ (diff-at-point . [(20220211 548) ((emacs (26 2))) "Diff navigation" single ((:commit . "819da8d75762e1fb1a975d78c2b4666506048485") (:authors ("Campbell Barton" . "ideasman42@gmail.com")) (:maintainer "Campbell Barton" . "ideasman42@gmail.com") (:url . "https://gitlab.com/ideasman42/emacs-diff-at-point"))])
+ (diff-hl . [(20220405 2359) ((cl-lib (0 2)) (emacs (25 1))) "Highlight uncommitted changes using VC" tar ((:commit . "9d5dc2ffa1e4c7b43734b03dccb5ae6a80800569") (:authors ("Dmitry Gutov" . "dgutov@yandex.ru")) (:maintainer "Dmitry Gutov" . "dgutov@yandex.ru") (:keywords "vc" "diff") (:url . "https://github.com/dgutov/diff-hl"))])
+ (difflib . [(20210224 2242) ((emacs (24 4)) (cl-generic (0 3)) (ht (2 2)) (s (1 12 0))) "Helpers for computing deltas between sequences." single ((:commit . "646fc4388274fe765bbf4661e17a24e4d081250c") (:authors ("Diego A. Mundo" . "dieggsy@pm.me")) (:maintainer "Diego A. Mundo" . "dieggsy@pm.me") (:keywords "matching" "tools" "string") (:url . "http://github.com/dieggsy/difflib.el"))])
+ (diffpdf . [(20210626 1447) ((emacs (25 1)) (transient (0 3 0))) "Transient diffpdf" single ((:commit . "a5b203b549e373cb9b0ef3f00c0010bd34dd644a") (:authors ("Shuguang Sun" . "shuguang79@qq.com")) (:maintainer "Shuguang Sun" . "shuguang79@qq.com") (:keywords "tools") (:url . "https://github.com/ShuguangSun/diffpdf.el"))])
+ (diffscuss-mode . [(20141014 2357) nil "Major mode for diffscuss files." single ((:commit . "53f2d001bd3a5cb80c6ada16b4e570afd1989a09") (:authors ("Edmund Jorgensen" . "edmund@hut8labs.com")) (:maintainer "Edmund Jorgensen" . "edmund@hut8labs.com") (:keywords "tools"))])
+ (diffsync . [(20220502 1513) ((emacs (25 1))) "Use diff to allow syncing of directories" single ((:commit . "3f8540ef0a677ea8c2b57aaf4a07937512bb148c") (:authors ("Bernhard Rotter" . "bernhard@b-rotter.de")) (:maintainer "Bernhard Rotter" . "bernhard@b-rotter.de") (:keywords "tools") (:url . "https://github.com/ber-ro/diffsync"))])
+ (diffview . [(20220322 2334) nil "View diffs in side-by-side format" single ((:commit . "af2251a01f532efa819d236802cb3d942befe5a1") (:authors ("Mitchel Humpherys" . "mitch.special@gmail.com")) (:maintainer "Mitchel Humpherys" . "mitch.special@gmail.com") (:keywords "convenience" "diff") (:url . "https://github.com/mgalgs/diffview-mode"))])
+ (digistar-mode . [(20210129 1719) nil "major mode for Digistar scripts" single ((:commit . "e12b128023b7696a23545f812877e8c6531d261c") (:authors ("John Foerch" . "jjfoerch@gmail.com")) (:maintainer "John Foerch" . "jjfoerch@gmail.com") (:keywords "languages"))])
+ (digit-groups . [(20200506 37) ((dash (2 11 0))) "Highlight place-value positions in numbers" single ((:commit . "7b81930cad19b8b7913b7eedbcb498964bfdcbdb") (:authors ("Michael D. Adams <http://michaeldadams.org>")) (:maintainer "Michael D. Adams <http://michaeldadams.org>") (:url . "https://github.com/adamsmd/digit-groups/"))])
+ (digitalocean . [(20190607 726) ((request (2 5)) (emacs (24 4))) "Create and manipulate digitalocean droplets" single ((:commit . "6c32d3593286e2a62d9afab0057c829407b0d1e8") (:authors ("Oliver Marks" . "oly@digitaloctave.com")) (:maintainer "Oliver Marks" . "oly@digitaloctave.com") (:keywords "processes" "tools") (:url . "https://github.com/olymk2/emacs-digitalocean"))])
+ (digitalocean-helm . [(20180610 746) ((emacs (24 3)) (helm (2 5)) (digitalocean (0 1))) "Create and manipulate digitalocean droplets" single ((:commit . "b125c9882eded7d73ec109d152b26625f333440b") (:authors ("Oliver Marks" . "oly@digitaloctave.com")) (:maintainer "Oliver Marks" . "oly@digitaloctave.com") (:keywords "processes" "tools") (:url . "https://gitlab.com/olymk2/digitalocean-api"))])
+ (dilbert . [(20211118 1512) ((emacs (26 1)) (enlive (0 0 1)) (dash (2 19 1))) "View Dilbert comics" single ((:commit . "3e9a39717490be4d5c14211a47fcd8588ef668af") (:authors ("Daniils Petrovs" . "thedanpetrov@gmail.com")) (:maintainer "Daniils Petrovs" . "thedanpetrov@gmail.com") (:keywords "multimedia" "news") (:url . "https://github.com/DaniruKun/dilbert-el"))])
+ (dim . [(20160818 949) ((emacs (24 4))) "Change mode-line names of major/minor modes" single ((:commit . "5515f2e8657ef14adcc34aa5b05383a2684328ae") (:authors ("Alex Kost" . "alezost@gmail.com")) (:maintainer "Alex Kost" . "alezost@gmail.com") (:keywords "convenience") (:url . "https://github.com/alezost/dim.el"))])
+ (dim-autoload . [(20220422 1601) ((emacs (25 1)) (compat (28 1 1 0))) "Dim or hide autoload cookie lines" single ((:commit . "09073e6bfd21f3a7f8fcf1e2e7c49994cdee7d2a") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:keywords "convenience") (:url . "https://github.com/tarsius/dim-autoload"))])
+ (dime . [(20210329 604) ((emacs (25 1)) (dylan (3 0))) "Dylan interaction mode" tar ((:commit . "9d2891e3e06405b75072d296f385fa795aeb9835") (:url . "https://opendylan.org/"))])
+ (diminish . [(20220104 1539) ((emacs (24 3))) "Diminished modes are minor modes with no modeline display" single ((:commit . "6b7e837b0cf0129e9d7d6abae48093cf599bb9e8") (:authors ("Will Mengarini" . "seldon@eskimo.com")) (:maintainer "Martin Yrjölä" . "martin.yrjola@gmail.com") (:keywords "extensions" "diminish" "minor" "codeprose") (:url . "https://github.com/myrjola/diminish.el"))])
+ (diminish-buffer . [(20220218 1541) ((emacs (24 4))) "Diminish (hide) buffers from buffer-menu" single ((:commit . "3b3b24eb231af889b0eea50e6e0a20c2bca9c439") (:authors ("Shen, Jen-Chieh" . "jcs090218@gmail.com")) (:maintainer "Shen, Jen-Chieh" . "jcs090218@gmail.com") (:url . "https://github.com/jcs-elpa/diminish-buffer"))])
+ (dimmer . [(20211123 1536) ((emacs (25 1))) "Visually highlight the selected buffer" single ((:commit . "2f915b100044e09dd647b22085e1696249c4b115") (:authors ("Neil Okamoto")) (:maintainer "Neil Okamoto") (:keywords "faces" "editing") (:url . "https://github.com/gonewest818/dimmer.el"))])
+ (dionysos . [(20160810 1056) ((libmpdee (2 1 0)) (alert (1 2)) (s (1 11 0)) (dash (2 12 1)) (pkg-info (0 5 0)) (cl-lib (0 5))) "Dionysos, a music player for Emacs" tar ((:commit . "0aac21caadabc5a7f09e18a9dcb02f3dec26588b") (:authors ("Nicolas Lamirault" . "nicolas.lamirault@gmail.com")) (:maintainer "Nicolas Lamirault" . "nicolas.lamirault@gmail.com") (:keywords "music") (:url . "https://github.com/nlamirault/dionysos"))])
+ (dir-treeview . [(20220505 27) ((emacs (24 4)) (treeview (1 1 0))) "A directory tree browser and simple file manager" tar ((:commit . "fa0b795b36740755ec37f5b41c3a734ad702e5a1") (:authors ("Tilman Rassy" . "tilman.rassy@googlemail.com")) (:maintainer "Tilman Rassy" . "tilman.rassy@googlemail.com") (:keywords "tools" "convenience" "files") (:url . "https://github.com/tilmanrassy/emacs-dir-treeview"))])
+ (dircmp . [(20141204 1756) nil "Compare and sync directories." tar ((:commit . "558ee0b601c2de9d247612085aafe2926f56a09f") (:authors ("Matt McClure -- http://matthewlmcclure.com")) (:maintainer "Matt McClure -- http://matthewlmcclure.com") (:keywords "unix" "tools") (:url . "https://github.com/matthewlmcclure/dircmp-mode"))])
+ (dired-atool . [(20210719 404) ((emacs (24))) "Pack/unpack files with atool on dired." single ((:commit . "01416fd5961b901c50686c91cb59b3833adc831b") (:authors ("Hiroki YAMAKAWA" . "s06139@gmail.com")) (:maintainer "Hiroki YAMAKAWA" . "s06139@gmail.com") (:keywords "files") (:url . "https://github.com/HKey/dired-atool"))])
+ (dired-avfs . [(20161012 1104) ((dash (2 5 0)) (dired-hacks-utils (0 0 1))) "AVFS support for dired" single ((:commit . "7c0ef09d57a80068a11edc74c3568e5ead5cc15a") (:authors ("Matus Goljer" . "matus.goljer@gmail.com")) (:maintainer "Matus Goljer" . "matus.goljer@gmail.com") (:keywords "files"))])
+ (dired-collapse . [(20210403 1230) ((dash (2 10 0)) (f (0 19 0)) (dired-hacks-utils (0 0 1))) "Collapse unique nested paths in dired listing" single ((:commit . "7c0ef09d57a80068a11edc74c3568e5ead5cc15a") (:authors ("Matúš Goljer" . "matus.goljer@gmail.com")) (:maintainer "Matúš Goljer" . "matus.goljer@gmail.com") (:keywords "files"))])
+ (dired-dups . [(20130527 2125) nil "Find duplicate files and display them in a dired buffer" single ((:commit . "694ad128c822c59348ced16c4a0c1356d43da47a") (:authors ("Joe Bloggs" . "vapniks@yahoo.com")) (:maintainer "Joe Bloggs" . "vapniks@yahoo.com") (:keywords "unix") (:url . "https://github.com/vapniks/dired-dups"))])
+ (dired-efap . [(20220421 1535) nil "Edit Filename At Point in a dired buffer" single ((:commit . "360b369cb19998c6730ee1debfbec3edb7f349a9") (:authors ("Juan-Leon Lahoz" . "juanleon1@gmail.com")) (:maintainer "Juan-Leon Lahoz" . "juanleon1@gmail.com") (:keywords "dired" "environment" "files" "renaming") (:url . "https://github.com/juan-leon/dired-efap"))])
+ (dired-explorer . [(20180607 221) ((cl-lib (0 5))) "minor-mode provides Explorer like select file at dired." single ((:commit . "3ade0a31b5340271d05e9bf443f2504960f6c6dd") (:maintainer "jidaikobo-shibata") (:keywords "dired" "explorer"))])
+ (dired-fdclone . [(20220119 717) nil "dired functions and settings to mimic FDclone" single ((:commit . "66e337012e72cebd2485f1efca0b2f78dc9c6252") (:authors ("Akinori MUSHA" . "knu@iDaemons.org")) (:maintainer "Akinori MUSHA" . "knu@iDaemons.org") (:keywords "unix" "directories" "dired") (:url . "https://github.com/knu/dired-fdclone.el"))])
+ (dired-filetype-face . [(20180907 1339) nil "Set different faces for different filetypes in dired" single ((:commit . "7ade7f7e8c2d7518c65f3f0343a10c272da0f47e") (:authors ("纪秀峰 <jixiuf at gmail dot com>")) (:maintainer "纪秀峰 <jixiuf at gmail dot com>") (:keywords "dired" "filetype" "face") (:url . "https://github.com/jixiuf/dired-filetype-face"))])
+ (dired-filter . [(20191105 1404) ((dash (2 10 0)) (dired-hacks-utils (0 0 1)) (f (0 17 0)) (cl-lib (0 3))) "Ibuffer-like filtering for dired" single ((:commit . "7c0ef09d57a80068a11edc74c3568e5ead5cc15a") (:authors ("Matúš Goljer" . "matus.goljer@gmail.com")) (:maintainer "Matúš Goljer" . "matus.goljer@gmail.com") (:keywords "files"))])
+ (dired-git . [(20200527 732) ((emacs (26 1)) (async-await (1 0)) (async (1 9 4)) (all-the-icons (2 2 0)) (ppp (1 0 0))) "Git integration for dired" single ((:commit . "82c93bdb2fe392b122f79d2e425c632f1c69ede3") (:authors ("Naoya Yamashita" . "conao3@gmail.com")) (:maintainer "Naoya Yamashita" . "conao3@gmail.com") (:keywords "tools") (:url . "https://github.com/conao3/dired-git.el"))])
+ (dired-hacks-utils . [(20201005 2318) ((dash (2 5 0))) "Utilities and helpers for dired-hacks collection" single ((:commit . "7c0ef09d57a80068a11edc74c3568e5ead5cc15a") (:authors ("Matúš Goljer" . "matus.goljer@gmail.com")) (:maintainer "Matúš Goljer" . "matus.goljer@gmail.com") (:keywords "files"))])
+ (dired-hide-dotfiles . [(20210222 1919) ((emacs (25 1))) "Hide dotfiles in dired" single ((:commit . "6a379f23f64045f5950d229254ce6f32dbbf5364") (:authors ("Mattias Bengtsson" . "mattias.jc.bengtsson@gmail.com")) (:maintainer "Mattias Bengtsson" . "mattias.jc.bengtsson@gmail.com") (:keywords "files") (:url . "https://github.com/mattiasb/dired-hide-dotfiles"))])
+ (dired-icon . [(20170223 526) ((emacs (24 3))) "A minor mode to display a list of associated icons in dired buffers." tar ((:commit . "f60e10757a5011235b519231ad35974ff25963ed") (:authors ("Hong Xu" . "hong@topbug.net")) (:maintainer "Hong Xu" . "hong@topbug.net") (:keywords "dired" "files") (:url . "https://gitlab.com/xuhdev/dired-icon"))])
+ (dired-imenu . [(20140109 1610) nil "imenu binding for dired mode" single ((:commit . "610e21fe0988c85931d34894d3eee2442c79ab0a") (:authors ("Damien Cassou" . "damien.cassou@gmail.com")) (:maintainer "Damien Cassou" . "damien.cassou@gmail.com") (:keywords "dired" "imenu") (:url . "https://github.com/DamienCassou/dired-imenu"))])
+ (dired-k . [(20211002 2358) ((emacs (24 3))) "Highlight dired by size, date, git status" tar ((:commit . "1ddd8e0ea06f0e25cd5dedb2370cfa0cacfa8c9d") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Neil Okamoto" . "neil.okamoto+melpa@gmail.com") (:url . "https://github.com/emacsorphanage/dired-k"))])
+ (dired-launch . [(20220317 1839) nil "Use dired as a launcher" single ((:commit . "72ebbe2b3d2e04dbfda636fa114d4f47835ce044") (:authors ("David Thompson")) (:maintainer "David Thompson") (:keywords "dired" "launch") (:url . "https://github.com/thomp/dired-launch"))])
+ (dired-lsi . [(20200812 929) ((emacs (26 1))) "Add memo to directory and show it in dired" single ((:commit . "0f4038c8b47f6cfc70f82062800700c14c9912c2") (:authors ("Naoya Yamashita" . "conao3@gmail.com")) (:maintainer "Naoya Yamashita" . "conao3@gmail.com") (:keywords "convenience") (:url . "https://github.com/conao3/dired-lsi.el"))])
+ (dired-narrow . [(20181114 1723) ((dash (2 7 0)) (dired-hacks-utils (0 0 1))) "Live-narrowing of search results for dired" single ((:commit . "7c0ef09d57a80068a11edc74c3568e5ead5cc15a") (:authors ("Matúš Goljer" . "matus.goljer@gmail.com")) (:maintainer "Matúš Goljer" . "matus.goljer@gmail.com") (:keywords "files"))])
+ (dired-open . [(20180922 1113) ((dash (2 5 0)) (dired-hacks-utils (0 0 1))) "Open files from dired using using custom actions" single ((:commit . "7c0ef09d57a80068a11edc74c3568e5ead5cc15a") (:authors ("Matúš Goljer" . "matus.goljer@gmail.com")) (:maintainer "Matúš Goljer" . "matus.goljer@gmail.com") (:keywords "files"))])
+ (dired-posframe . [(20200817 420) ((emacs (26 1)) (posframe (0 7))) "Peep dired items using posframe" single ((:commit . "1a21eb9ad956a0371dd3c9e1bec53407d685f705") (:authors ("Naoya Yamashita" . "conao3@gmail.com")) (:maintainer "Naoya Yamashita" . "conao3@gmail.com") (:keywords "convenience") (:url . "https://github.com/conao3/dired-posframe.el"))])
+ (dired-quick-sort . [(20201221 403) ((hydra (0 13 0)) (emacs (24))) "Persistent quick sorting of dired buffers in various ways." single ((:commit . "69b06f306a5fc2b38e707bae3ff1e35db2b39b6b") (:authors ("Hong Xu" . "hong@topbug.net")) (:maintainer "Hong Xu" . "hong@topbug.net") (:keywords "convenience" "files") (:url . "https://gitlab.com/xuhdev/dired-quick-sort#dired-quick-sort"))])
+ (dired-rainbow . [(20190722 1109) ((dash (2 5 0)) (dired-hacks-utils (0 0 1))) "Extended file highlighting according to its type" single ((:commit . "7c0ef09d57a80068a11edc74c3568e5ead5cc15a") (:authors ("Matus Goljer" . "matus.goljer@gmail.com")) (:maintainer "Matus Goljer" . "matus.goljer@gmail.com") (:keywords "files"))])
+ (dired-ranger . [(20180401 2206) ((dash (2 7 0)) (dired-hacks-utils (0 0 1))) "Implementation of useful ranger features for dired" single ((:commit . "7c0ef09d57a80068a11edc74c3568e5ead5cc15a") (:authors ("Matúš Goljer" . "matus.goljer@gmail.com")) (:maintainer "Matúš Goljer" . "matus.goljer@gmail.com") (:keywords "files"))])
+ (dired-recent . [(20211004 1924) ((emacs (24))) "Dired visited paths history" single ((:commit . "a376f53e42fdca80c3286e8111578c65c64b0711") (:authors ("Wojciech Siewierski <wojciech dot siewierski at onet dot pl>")) (:maintainer "Wojciech Siewierski <wojciech dot siewierski at onet dot pl>") (:keywords "files") (:url . "https://github.com/vifon/dired-recent.el"))])
+ (dired-rifle . [(20210316 1452) nil "Call rifle(1) from dired" single ((:commit . "cc1af692bbac651f5e5111d9ab1c0805989d65e5") (:authors ("Wojciech Siewierski <wojciech dot siewierski at onet dot pl>")) (:maintainer "Wojciech Siewierski <wojciech dot siewierski at onet dot pl>") (:keywords "files" "convenience") (:url . "https://github.com/vifon/dired-rifle.el"))])
+ (dired-rmjunk . [(20191007 1232) nil "A home directory cleanup utility for Dired." single ((:commit . "92af5fcc2bd0bc3826f4ce238a850e9a362533a4") (:authors ("Jakob L. Kreuze" . "zerodaysfordays@sdf.lonestar.org")) (:maintainer "Jakob L. Kreuze" . "zerodaysfordays@sdf.lonestar.org") (:keywords "files" "matching") (:url . "https://git.sr.ht/~jakob/dired-rmjunk"))])
+ (dired-rsync . [(20220313 1533) ((s (1 12 0)) (dash (2 0 0)) (emacs (24))) "Allow rsync from dired buffers" tar ((:commit . "b327971d197e95e9b78e7ef92539bd4196a12797") (:authors ("Alex Bennée" . "alex@bennee.com")) (:maintainer "Alex Bennée" . "alex@bennee.com") (:url . "https://github.com/stsquad/dired-rsync"))])
+ (dired-sidebar . [(20220413 753) ((emacs (25 1)) (dired-subtree (0 0 1))) "Tree browser leveraging dired" single ((:commit . "0521cdc53e4a7ae7ea4728e5ac9f69287528dc56") (:authors ("James Nguyen" . "james@jojojames.com")) (:maintainer "James Nguyen" . "james@jojojames.com") (:keywords "dired" "files" "tools") (:url . "https://github.com/jojojames/dired-sidebar"))])
+ (dired-single . [(20211101 2319) nil "Reuse the current dired buffer to visit a directory" single ((:commit . "b254f9b7bfc96a5eab5760a56811f2872d2c590a") (:keywords "dired" "reuse" "buffer") (:url . "https://github.com/crocket/dired-single"))])
+ (dired-subtree . [(20210105 1127) ((dash (2 5 0)) (dired-hacks-utils (0 0 1))) "Insert subdirectories in a tree-like fashion" single ((:commit . "7c0ef09d57a80068a11edc74c3568e5ead5cc15a") (:authors ("Matúš Goljer" . "matus.goljer@gmail.com")) (:maintainer "Matúš Goljer" . "matus.goljer@gmail.com") (:keywords "files"))])
+ (dired-toggle . [(20190616 303) nil "Show dired as sidebar and will not create new buffers when changing dir" single ((:commit . "7fe5fe35c63d1b0da14d6d6d52bdf6b2a5410ba7") (:authors ("Xu FaSheng <fasheng[AT]fasheng.info>")) (:maintainer "Xu FaSheng") (:keywords "dired" "sidebar") (:url . "https://github.com/fasheng/dired-toggle"))])
+ (dired-toggle-sudo . [(20211216 102) nil "Browse directory with sudo privileges." single ((:commit . "9f86cdf858225b15c20affb97ed105e4109047bf") (:authors ("Sebastien Gross <seb•ɑƬ•chezwam•ɖɵʈ•org>")) (:maintainer "Sebastien Gross <seb•ɑƬ•chezwam•ɖɵʈ•org>") (:keywords "emacs" "dired"))])
+ (dired-view-data . [(20220129 339) ((emacs (26 1)) (ess (18 10 1)) (ess-view-data (1 0))) "View data from dired via ESS and R" single ((:commit . "96d4cb6569fd2be90a516dedd98263374bbc6ead") (:authors ("Shuguang Sun" . "shuguang79@qq.com")) (:maintainer "Shuguang Sun" . "shuguang79@qq.com") (:keywords "tools") (:url . "https://github.com/ShuguangSun/dired-view-data"))])
+ (diredc . [(20220113 332) ((emacs (26 1)) (key-assist (1 0))) "Extensions for dired" single ((:commit . "7ee68f6b1c87f8ab86cf23416472747e88860717") (:keywords "files") (:url . "https://github.com/Boruch-Baum/emacs-diredc"))])
+ (diredfl . [(20220103 1744) ((emacs (24))) "Extra font lock rules for a more colourful dired" single ((:commit . "59f8e5bf5c2991aa54a471f61f14d77976db194a") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:keywords "faces") (:url . "https://github.com/purcell/diredfl"))])
+ (diredful . [(20160529 2017) nil "colorful file names in dired buffers" single ((:commit . "ad328a15c5deffc1021af9b3f19a745dcd8f4415") (:authors ("Thamer Mahmoud" . "thamer.mahmoud@gmail.com")) (:maintainer "Thamer Mahmoud" . "thamer.mahmoud@gmail.com") (:keywords "dired" "colors" "extension" "widget") (:url . "https://github.com/thamer/diredful"))])
+ (direnv . [(20220103 1342) ((emacs (25 1)) (dash (2 12 0))) "direnv integration" single ((:commit . "d71ceb415732c3b76a2948147fa3559622aceba2") (:authors ("wouter bolsterlee" . "wouter@bolsterl.ee")) (:maintainer "wouter bolsterlee" . "wouter@bolsterl.ee") (:keywords "direnv" "environment" "processes" "unix" "tools") (:url . "https://github.com/wbolster/emacs-direnv"))])
+ (direx . [(20170422 1327) nil "Simple Directory Explorer" tar ((:commit . "a79bfdb5980cf6ed7bfb3b41ddc471a7b6c0ede4") (:authors ("Tomohiro Matsuyama" . "m2ym.pub@gmail.com")) (:maintainer "Tomohiro Matsuyama" . "m2ym.pub@gmail.com") (:keywords "convenience"))])
+ (direx-grep . [(20140515 1506) ((direx (0 1 -3))) "Grep node of direx.el using incremental search like anything.el/helm.el" single ((:commit . "1109a512a80b2673a70b18b8568514049017faad") (:authors ("Hiroaki Otsu" . "ootsuhiroaki@gmail.com")) (:maintainer "Hiroaki Otsu" . "ootsuhiroaki@gmail.com") (:keywords "convenience") (:url . "https://github.com/aki2o/direx-grep"))])
+ (dirtree . [(20140129 832) ((tree-mode (1 1 1 1)) (windata (0))) "Directory tree views" single ((:commit . "ba55f1e716e386fdd37cb8e7f48616e405dc7251") (:authors ("Ye Wenbin" . "wenbinye@gmail.com")) (:maintainer "Ye Wenbin" . "wenbinye@gmail.com"))])
+ (dirtree-prosjekt . [(20140129 904) ((prosjekt (0 3)) (dirtree (0 1))) "dirtree integration for prosjekt." single ((:commit . "a864a8be5842223043702395f311e3350c28e9db") (:authors ("Austin Bingham" . "austin.bingham@gmail.com")) (:maintainer "Austin Bingham" . "austin.bingham@gmail.com") (:url . "https://github.com/abingham/prosjekt"))])
+ (dirvish . [(20220504 448) ((emacs (27 1))) "A modern file manager based on dired mode" tar ((:commit . "15981b685cdb4948219a9db2da71ac9f7d60723c") (:authors ("Alex Lu <https://github.com/alexluigit>")) (:maintainer "Alex Lu <https://github.com/alexluigit>") (:keywords "files" "convenience") (:url . "https://github.com/alexluigit/dirvish"))])
+ (disable-mouse . [(20210512 2114) ((emacs (24 1))) "Disable mouse commands globally" single ((:commit . "cae3be9dd012727b40ad3b511731191f79cebe42") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:keywords "mouse") (:url . "https://github.com/purcell/disable-mouse"))])
+ (disaster . [(20171016 2152) nil "Disassemble C/C++ code under cursor in Emacs" single ((:commit . "10a785facc60d89d78e0d5177985ab1af1741bb4") (:authors ("Justine Tunney" . "jtunney@gmail.com")) (:maintainer "Justine Tunney" . "jtunney@gmail.com") (:keywords "tools") (:url . "https://github.com/jart/disaster"))])
+ (discourse . [(20160911 819) ((cl-lib (0 5)) (request (0 2)) (s (1 11 0))) "discourse api" single ((:commit . "a86c7e608851e186fe12e892a573994f08c8e65e") (:authors ("DarkSun" . "lujun9972@gmail.com")) (:maintainer "DarkSun" . "lujun9972@gmail.com") (:keywords "lisp" "discourse") (:url . "https://github.com/lujun9972/discourse-api"))])
+ (discover . [(20140103 2139) ((makey (0 3))) "discover more of Emacs" single ((:commit . "7b0044bbb3b3bd5d811fdfb0f5ac6ec8de1239df") (:authors ("Mickey Petersen" . "mickey@fyeah.org")) (:maintainer "Mickey Petersen" . "mickey@fyeah.org"))])
+ (discover-clj-refactor . [(20150328 1459) ((clj-refactor (0 14 0)) (discover (0 3))) "Adds discover context menu for clj-refactor" single ((:commit . "3fbd5c1162739e606d7cf5d4f5d7426547d99647") (:authors ("Marian Schubert" . "marian.schubert@gmail.com")) (:maintainer "Marian Schubert" . "marian.schubert@gmail.com") (:keywords "clj-refactor" "discover" "convenience"))])
+ (discover-js2-refactor . [(20140129 1552) ((js2-refactor (20131221 501)) (discover (20140103 1339))) "Adds discover context menu for js2-refactor" single ((:commit . "3812abf61f39f3e73a9f3daefa6fed4f21a429ba") (:authors ("Nicolas Petton" . "petton.nicolas@gmail.com")) (:maintainer "Nicolas Petton" . "petton.nicolas@gmail.com") (:keywords "js2-refactor" "discover"))])
+ (discover-my-major . [(20180606 511) ((makey (0 2))) "Discover key bindings and their meaning for the current Emacs major mode" single ((:commit . "c592e5e67454f0d1b68669ac0c270073164b16b3") (:authors ("steckerhalter")) (:maintainer "steckerhalter") (:keywords "discover" "help" "major-mode" "keys") (:url . "https://framagit.org/steckerhalter/discover-my-major"))])
+ (disk . [(20171116 731) nil "simplified find-file, revert-file, save-buffer interface" single ((:commit . "283e54e3be7d08f959076240b2ab324e25632137") (:authors ("Alex Schroeder" . "alex@gnu.org") ("Peter Barabas" . "peter.barabas+disk@gmail.com")) (:maintainer "Alex Schroeder" . "alex@gnu.org") (:keywords "convenience") (:url . "http://www.emacswiki.org/emacs/DiskKey"))])
+ (dispass . [(20140202 1531) ((dash (1 0 0))) "Emacs wrapper for DisPass" single ((:commit . "b6e8f89040ebaaf0e7609b04bc27a8979f0ae861") (:authors ("Tom Willemsen" . "tom@ryuslash.org")) (:maintainer "Tom Willemsen" . "tom@ryuslash.org") (:keywords "processes") (:url . "http://projects.ryuslash.org/dispass.el/"))])
+ (display-theme . [(20140115 1556) ((emacs (24))) "display current theme(s) at mode-line" single ((:commit . "b180b3be7a74ae4799a14e7e4bc2fe10e3ff7a15") (:authors ("KAWABATA, Taichi <kawabata.taichi_at_gmail.com>")) (:maintainer "KAWABATA, Taichi <kawabata.taichi_at_gmail.com>") (:keywords "tools") (:url . "https://github.com/kawabata/emacs-display-theme/"))])
+ (display-wttr . [(20220316 213) ((emacs (27 1))) "Display wttr(weather) in the mode line" single ((:commit . "2cb36df32b0ecf381185126a969b7282af5a0e01") (:authors ("Jose G Perez Taveras" . "josegpt27@gmail.com")) (:maintainer "Jose G Perez Taveras" . "josegpt27@gmail.com") (:url . "https://github.com/josegpt/display-wttr"))])
+ (dispwatch . [(20210305 342) ((emacs (24 4))) "Watch displays for configuration changes" single ((:commit . "03abbac89a9f625aaa1a808dd49ae4906f466421") (:authors ("Mitchell Perilstein" . "mitchell.perilstein@gmail.com")) (:maintainer "Mitchell Perilstein" . "mitchell.perilstein@gmail.com") (:keywords "frames") (:url . "https://github.com/mnp/dispwatch"))])
+ (dist-file-mode . [(20180830 418) ((emacs (24)) (cl-lib (0 5)) (s (1 9 0))) "Dispatch major mode for *.dist files" single ((:commit . "e1ce8f592bc5d4d86d2f09e334728ac0d524c761") (:authors ("USAMI Kenta" . "tadsan@zonu.me")) (:maintainer "USAMI Kenta" . "tadsan@zonu.me") (:keywords "files" "convenience") (:url . "https://github.com/emacs-php/dist-file-mode.el"))])
+ (distel-completion-lib . [(20180827 1344) nil "Completion library for Erlang/Distel" single ((:commit . "acc4c0a5521904203d797fe96b08e5fae4233c7e") (:authors ("Sebastian Weddmark Olsson")) (:maintainer "Sebastian Weddmark Olsson") (:keywords "erlang" "distel" "completion") (:url . "github.com/sebastiw/distel-completion"))])
+ (distinguished-theme . [(20151216 2015) nil "A dark and elegant theme for emacs." single ((:commit . "9b1d25ac59465a5016d187ea84b7614c95a29b3b") (:authors ("Kim Silkebækken" . "kim.silkebaekken@gmail.com")) (:maintainer "Kim Silkebækken" . "kim.silkebaekken@gmail.com") (:url . "https://github.com/Lokaltog/distinguished-theme"))])
+ (ditz-mode . [(20150729 940) nil "Emacs interface to Ditz issue tracking system" single ((:commit . "74b6b93b097d595a001c019e3b762abfc60f821a") (:authors ("Glenn Hutchings" . "zondo42@gmail.com")) (:maintainer "Glenn Hutchings" . "zondo42@gmail.com") (:keywords "tools"))])
+ (dix . [(20220323 1046) ((cl-lib (0 5)) (emacs (26 2))) "Apertium XML editing minor mode" tar ((:commit . "5230c18456ab034f2fb69acdbef62c1abae6a8cf") (:authors ("Kevin Brubeck Unhammer" . "unhammer@fsfe.org")) (:maintainer "Kevin Brubeck Unhammer" . "unhammer@fsfe.org") (:keywords "languages") (:url . "http://wiki.apertium.org/wiki/Emacs"))])
+ (dix-evil . [(20170105 1423) ((dix (0 3 0)) (evil (1 0 7))) "optional evil-integration with dix.el" single ((:commit . "5230c18456ab034f2fb69acdbef62c1abae6a8cf") (:authors ("Kevin Brubeck Unhammer" . "unhammer@fsfe.org")) (:maintainer "Kevin Brubeck Unhammer" . "unhammer@fsfe.org") (:keywords "languages") (:url . "http://wiki.apertium.org/wiki/Emacs"))])
+ (dizzee . [(20171201 916) nil "A more pleasant way to manage your project's subprocesses in Emacs." tar ((:commit . "e3cf1c2ea5d0fc00747524b6f3c5b905d0a8c8e1") (:authors ("David Miller" . "david@deadpansincerity.com")) (:maintainer "David Miller" . "david@deadpansincerity.com") (:keywords "emacs" "processes") (:url . "https://github.com/davidmiller/dizzee"))])
+ (django-commands . [(20220314 1545) ((emacs (25 1))) "Run django commands" single ((:commit . "7510c0f068bf214ad012c203d68e03ff4262efdf") (:authors ("Andrii Kolomoiets" . "andreyk.mad@gmail.com")) (:maintainer "Andrii Kolomoiets" . "andreyk.mad@gmail.com") (:keywords "tools") (:url . "https://github.com/muffinmad/emacs-django-commands"))])
+ (django-manage . [(20160819 212) ((hydra (0 13 2))) "Django minor mode for commanding manage.py" single ((:commit . "876fb2cb627d465adfdc905841279784bcdd7ee8") (:authors ("Daniel Gopar" . "gopardaniel@yahoo.com")) (:maintainer "Daniel Gopar" . "gopardaniel@yahoo.com") (:keywords "languages"))])
+ (django-mode . [(20170522 714) ((projectile (0)) (s (0)) (helm-make (0))) "Major mode for Django web framework." tar ((:commit . "a71b8dd984e7f724b8321246e5c353a4ae5c986e") (:authors ("Greg V" . "floatboth@me.com")) (:maintainer "Greg V" . "floatboth@me.com") (:keywords "languages"))])
+ (django-snippets . [(20131229 1611) ((yasnippet (0 8 0))) "Yasnippets for django" tar ((:commit . "a71b8dd984e7f724b8321246e5c353a4ae5c986e") (:authors ("Yasuyuki Oka" . "yasuyk@gmail.com")) (:maintainer "Yasuyuki Oka" . "yasuyk@gmail.com") (:url . "https://github.com/myfreeweb/django-mode"))])
+ (django-theme . [(20131022 902) nil "Custom face theme for Emacs" single ((:commit . "86c8142b3eb1addd94a43aa6f1d98dab06401af0") (:authors ("Andrzej Sliwa")) (:maintainer "Andrzej Sliwa") (:url . "http://github/anrzejsliwa/django-theme"))])
+ (djangonaut . [(20200503 921) ((emacs (25 2)) (magit-popup (2 6 0)) (pythonic (0 1 0)) (f (0 20 0)) (s (1 12 0))) "Minor mode to interact with Django projects" single ((:commit . "75f642114e3997308a1e7e67c3025738cecee0fe") (:authors ("Artem Malyshev" . "proofit404@gmail.com")) (:maintainer "Artem Malyshev" . "proofit404@gmail.com") (:url . "https://github.com/proofit404/djangonaut"))])
+ (djinni-mode . [(20190303 139) ((emacs (24 4))) "Major-mode for editing Djinni files." single ((:commit . "6f84bc60d078725cc8b922a259ec5f4c7de83681") (:authors ("Daniel Martín" . "mardani29@yahoo.es")) (:maintainer "Daniel Martín" . "mardani29@yahoo.es") (:keywords "languages") (:url . "https://github.com/danielmartin/djinni-mode"))])
+ (dkdo . [(20131110 1119) ((dkmisc (0 50)) (emacs (24 1))) "Do List major mode based on org-mode." tar ((:commit . "fd6bb105e8331fafb6385c5238c988c4c5bbe2da") (:authors ("David Keegan" . "dksw@eircom.net")) (:maintainer "David Keegan" . "dksw@eircom.net") (:keywords "dolist" "task" "productivity") (:url . "https://github.com/davidkeegan/dkdo"))])
+ (dkl . [(20161005 7) nil "Display keyboard layout." tar ((:commit . "6b4584f86037bda3383960c678d51f340229fb91") (:authors ("Alexis" . "flexibeast@gmail.com")) (:maintainer "Alexis" . "flexibeast@gmail.com") (:keywords "input" "keyboard" "layout") (:url . "https://github.com/flexibeast/dkl"))])
+ (dklrt . [(20131110 1341) ((dkmisc (0 50)) (ledger-mode (20130908 1357)) (emacs (24 1))) "Ledger Recurring Transactions." tar ((:commit . "5d6c99f8018335256ab934b4c1049708ae2d48ba") (:authors ("David Keegan" . "dksw@eircom.net")) (:maintainer "David Keegan" . "dksw@eircom.net") (:keywords "ledger" "ledger-cli" "recurring" "periodic" "automatic") (:url . "https://github.com/davidkeegan/dklrt"))])
+ (dkmisc . [(20131110 1115) ((emacs (24 1))) "Miscellaneous functions required by dk* packages." tar ((:commit . "fe3d49c6f8322b6f89466361acd97585bdfe0608") (:authors ("David Keegan" . "dksw@eircom.net")) (:maintainer "David Keegan" . "dksw@eircom.net") (:keywords "utility" "time" "date" "file") (:url . "https://github.com/davidkeegan/dkmisc"))])
+ (dmacro . [(20200803 633) ((emacs (24 1)) (cl-lib (0 6))) "Repeated detection and execution of key operation" single ((:commit . "3480b97aaad9e65fa03c6a9d1a0a8111be1179f8") (:authors ("Toshiyuki Masui" . "masui@ptiecan.com") ("Makoto Owada") ("Eiji Obata") ("Nobuyuki Mine")) (:maintainer "USAMI Kenta" . "tadsan@zonu.me") (:keywords "convenience") (:url . "https://github.com/emacs-jp/dmacro"))])
+ (dmenu . [(20190908 44) ((cl-lib (0 5))) "simulate the dmenu command line program" single ((:commit . "e8cc9b27c79d3ecc252267c082ab8e9c82eab264") (:authors ("DarkSun" . "lujun9972@gmail.com")) (:maintainer "DarkSun" . "lujun9972@gmail.com") (:keywords "convenience" "usability"))])
+ (dna-mode . [(20191001 2108) nil "a major mode for editing dna sequences" tar ((:commit . "7a48393fcf0015eed2368fcb89b3091c9d029dc4") (:authors ("Harley Gorrell" . "harley@panix.com")) (:maintainer "Harley Gorrell" . "harley@panix.com") (:keywords "dna" "emacs" "editing") (:url . "http://www.mahalito.net/~harley/elisp/dna-mode.el"))])
+ (doc-show-inline . [(20220421 122) ((emacs (26 2))) "Show doc-strings found in external files" single ((:commit . "11a29ebfd7939691b34b511082173e4b5d1b9c81") (:authors ("Campbell Barton" . "ideasman42@gmail.com")) (:maintainer "Campbell Barton" . "ideasman42@gmail.com") (:keywords "convenience") (:url . "https://gitlab.com/ideasman42/emacs-doc-show-inline"))])
+ (docbook-snippets . [(20150714 1625) ((yasnippet (0 8 0))) "Yasnippets for DocBook" tar ((:commit . "b06297fdec039a541aaa6312cb328a11062cfab4") (:authors ("Jaromir Hradilek" . "jhradilek@gmail.com")) (:maintainer "Jaromir Hradilek" . "jhradilek@gmail.com") (:keywords "snippets" "docbook") (:url . "https://github.com/jhradilek/emacs-docbook-snippets"))])
+ (docean . [(20180605 1744) ((emacs (24)) (cl-lib (0 5)) (request (0 2 0))) "Interact with DigitalOcean from Emacs." single ((:commit . "bbe2298fd21f7876fc2d5c52a69b931ff59df979") (:authors ("Mario Rodas" . "marsam@users.noreply.github.com")) (:maintainer "Mario Rodas" . "marsam@users.noreply.github.com") (:keywords "convenience") (:url . "https://github.com/emacs-pe/docean.el"))])
+ (docker . [(20220409 1157) ((aio (1 0)) (dash (2 19 1)) (docker-tramp (0 1)) (emacs (26 1)) (json-mode (1 8 0)) (s (1 12 0)) (tablist (1 0)) (transient (0 3 7))) "Interface to Docker" tar ((:commit . "cf137f5b8af7cbda17ef1d09c626db35e0e84078") (:authors ("Philippe Vaucher" . "philippe.vaucher@gmail.com")) (:maintainer "Philippe Vaucher" . "philippe.vaucher@gmail.com") (:keywords "filename" "convenience") (:url . "https://github.com/Silex/docker.el"))])
+ (docker-api . [(20160525 720) ((dash (2 12 1)) (request (0 2 0)) (s (1 11 0))) "Emacs interface to the Docker API" tar ((:commit . "206144346b7fa4165223349cfeb64a75d47ddd1b") (:authors ("Philippe Vaucher" . "philippe.vaucher@gmail.com")) (:maintainer "Philippe Vaucher" . "philippe.vaucher@gmail.com") (:url . "https://github.com/Silex/docker-api.el"))])
+ (docker-cli . [(20190524 1624) nil "Running various commands in docker containers" single ((:commit . "c4b02894466d8642ad3d49df4c4a80e023a672aa") (:authors ("Boško Ivanišević" . "bosko.ivanisevic@gmail.com")) (:maintainer "Boško Ivanišević" . "bosko.ivanisevic@gmail.com") (:keywords "processes") (:url . "https://github.com/bosko/docker-cli"))])
+ (docker-compose-mode . [(20200830 1336) ((emacs (24 3)) (dash (2 12 0)) (yaml-mode (0 0 12))) "Major mode for editing docker-compose files" single ((:commit . "abaa4f3aeb5c62d7d16e186dd7d77f4e846e126a") (:authors ("Ricardo Martins")) (:maintainer "Ricardo Martins") (:keywords "convenience") (:url . "https://github.com/meqif/docker-compose-mode"))])
+ (docker-tramp . [(20220219 420) ((emacs (24)) (cl-lib (0 5))) "TRAMP integration for docker containers" tar ((:commit . "930d7b46c180d8a13240a028c1b40af84f2a3219") (:authors ("Mario Rodas" . "marsam@users.noreply.github.com")) (:maintainer "Mario Rodas" . "marsam@users.noreply.github.com") (:keywords "docker" "convenience") (:url . "https://github.com/emacs-pe/docker-tramp.el"))])
+ (dockerfile-mode . [(20220220 1439) ((emacs (24))) "Major mode for editing Docker's Dockerfiles" single ((:commit . "b63a3d12b7dea0cb9efc7f78d7ad5672ceab2a3f") (:keywords "docker") (:url . "https://github.com/spotify/dockerfile-mode"))])
+ (docopt . [(20220319 1912) ((emacs (26 3)) (dash (2 17 0)) (emacs (26 1)) (f (0 20 0)) (parsec (0 1 3)) (s (1 12 0)) (transient (0 3 0))) "A Docopt implementation in Elisp" tar ((:commit . "a7f5b4a8b1a43552067ce27bce6080a509c92cff") (:authors ("r0man" . "roman@burningswell.com")) (:maintainer "r0man" . "roman@burningswell.com") (:keywords "docopt" "tools" "processes") (:url . "https://github.com/r0man/docopt.el"))])
+ (docstr . [(20220214 1539) ((emacs (24 4)) (s (1 9 0))) "A document string minor mode" tar ((:commit . "bb7485d24a4fb147fc7fc7fcd1e1c7ddd3ff64b5") (:authors ("Shen, Jen-Chieh" . "jcs090218@gmail.com")) (:maintainer "Shen, Jen-Chieh" . "jcs090218@gmail.com") (:url . "https://github.com/jcs-elpa/docstr"))])
+ (doct . [(20220227 205) ((emacs (25 1))) "DOCT: Declarative Org capture templates" single ((:commit . "4033a8fd8681d3989550f7a2532d6b4e3c45bfe8") (:authors ("Nicholas Vollmer" . "progfolio@protonmail.com")) (:maintainer "Nicholas Vollmer" . "progfolio@protonmail.com") (:keywords "org" "convenience") (:url . "https://github.com/progfolio/doct"))])
+ (dogears . [(20210913 1259) ((emacs (26 3)) (map (2 1))) "Never lose your place again" single ((:commit . "c05b69e504a538c9e00fbb0ea86934fafe191d0c") (:authors ("Adam Porter" . "adam@alphapapa.net")) (:maintainer "Adam Porter" . "adam@alphapapa.net") (:keywords "convenience") (:url . "https://github.com/alphapapa/dogears.el"))])
+ (dokuwiki . [(20180102 59) ((emacs (24 3)) (xml-rpc (1 6 8))) "Edit Remote DokuWiki Pages Using XML-RPC" single ((:commit . "594c4d4904dcc2796bbbd2c0845d9e7c09ccf6f7") (:authors ("Juan Karlo Licudine" . "accidentalrebel@gmail.com")) (:maintainer "Juan Karlo Licudine" . "accidentalrebel@gmail.com") (:keywords "convenience") (:url . "http://www.github.com/accidentalrebel/emacs-dokuwiki"))])
+ (dokuwiki-mode . [(20170223 1301) nil "Major mode for DokuWiki document" single ((:commit . "e4e116f6fcc373e3f5937c1a7daa5c2c9c6d3fa1") (:authors ("Tsunenobu Kai" . "kai2nenobu@gmail.com")) (:maintainer "Tsunenobu Kai" . "kai2nenobu@gmail.com") (:keywords "hypermedia" "text" "dokuwiki") (:url . "https://github.com/kai2nenobu/emacs-dokuwiki-mode"))])
+ (dollaro . [(20151123 1302) ((s (1 6 0))) "simple text templates" single ((:commit . "500127f0172ac7a1eec627e026b59136580a74ac") (:authors ("Alessandro Piras" . "laynor@gmail.com")) (:maintainer "Alessandro Piras" . "laynor@gmail.com") (:keywords "tools" "convenience"))])
+ (doneburn-theme . [(20181110 1857) nil "A light theme based on Bozhidar Batsov's Zenburn" single ((:commit . "da4fa915a2a659001eea04498d790cdd8cac1fce") (:authors ("Manuel Uberti" . "manuel.uberti@inventati.org")) (:maintainer "Manuel Uberti" . "manuel.uberti@inventati.org") (:keywords "faces" "themes") (:url . "http://github.com/manuel-uberti/doneburn-emacs"))])
+ (doom . [(20180301 2308) ((cl-lib (0 5))) "DOM implementation and manipulation library" single ((:commit . "e59040aefc92dd9b3134eb623624307fb9e4327b") (:authors ("Alex Schroeder" . "alex@gnu.org") ("Henrik.Motakef" . "elisp@henrik-motakef.de") ("Katherine Whitlock" . "toroidal-code@gmail.com") ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Alex Schroeder") (:keywords "xml" "dom") (:url . "http://www.github.com/kensanata/doom.el/"))])
+ (doom-modeline . [(20220412 853) ((emacs (25 1)) (all-the-icons (2 2 0)) (shrink-path (0 2 0)) (dash (2 11 0))) "A minimal and modern mode-line" tar ((:commit . "85bdd9ed8674710f6b9815e9a1c41ad4b5a45ace") (:authors ("Vincent Zhang" . "seagle0128@gmail.com")) (:maintainer "Vincent Zhang" . "seagle0128@gmail.com") (:keywords "faces" "mode-line") (:url . "https://github.com/seagle0128/doom-modeline"))])
+ (doom-modeline-now-playing . [(20210831 1442) ((emacs (24 4)) (doom-modeline (3 0 0)) (async (1 9 3))) "Segment for Doom Modeline to show playerctl information" single ((:commit . "ef9158dfdf32e8eb789b69e7394d0bddaa68f42c") (:authors ("Ellis Kenyő" . "me@elken.dev")) (:maintainer "Ellis Kenyő" . "me@elken.dev") (:url . "https://github.com/elken/doom-modeline-now-playing"))])
+ (doom-themes . [(20220504 1557) ((emacs (25 1)) (cl-lib (0 5))) "an opinionated pack of modern color-themes" tar ((:commit . "cdbeb346aa19e4129014cb3ebab7e87c66b4a8da") (:authors ("Henrik Lissner" . "contact@henrik.io")) (:maintainer "Henrik Lissner" . "contact@henrik.io") (:keywords "themes" "faces") (:url . "https://github.com/doomemacs/themes"))])
+ (dot-mode . [(20180312 2300) ((emacs (24 3))) "minor mode to repeat typing or commands" single ((:commit . "6ca22b73bcdae2363ee9641b822a60685df16a3e") (:authors ("Robert Wyrick" . "rob@wyrick.org")) (:maintainer "Robert Wyrick" . "rob@wyrick.org") (:keywords "convenience") (:url . "https://github.com/wyrickre/dot-mode"))])
+ (dotenv-mode . [(20191027 2129) ((emacs (24 3))) "Major mode for .env files" single ((:commit . "e3701bf739bde44f6484eb7753deadaf691b73fb") (:authors ("Preetpal S. Sohal")) (:maintainer "Preetpal S. Sohal") (:url . "https://github.com/preetpalS/emacs-dotenv-mode"))])
+ (dotnet . [(20200803 1032) nil "Interact with dotnet CLI tool" single ((:commit . "83ba1305d7895b03f3dffb2d3458b7ec75e6909f") (:authors ("Julien BLANCHARD" . "julien@sideburns.eu")) (:maintainer "Julien BLANCHARD" . "julien@sideburns.eu") (:keywords ".net" "tools") (:url . "https://github.com/julienXX/dotnet.el"))])
+ (double-saber . [(20190325 1917) ((emacs (24 4))) "Narrow and delete in search buffers." single ((:commit . "93d9b1ec833a871bde2fd0f78abc269872808048") (:authors ("Daniel Ting" . "deep.paren.12@gmail.com")) (:maintainer "Daniel Ting" . "deep.paren.12@gmail.com") (:keywords "double-saber" "narrow" "delete" "sort" "tools" "convenience" "matching") (:url . "https://github.com/dp12/double-saber.git"))])
+ (download-region . [(20210306 415) ((cl-lib (0 3))) "Simple in-buffer download manager" single ((:commit . "e0a721858a22896fa1d7f1d5689dd0878dbc58fa") (:authors ("zk_phi")) (:maintainer "zk_phi") (:url . "http://zk-phi.github.io/"))])
+ (downplay-mode . [(20151125 2009) nil "focus attention on a region of the buffer" single ((:commit . "4a2c3addc73c8ca3816345c3c11c08af265baedb") (:authors ("Toby Crawley" . "toby@tcrawley.org")) (:maintainer "Toby Crawley" . "toby@tcrawley.org") (:url . "https://github.com/tobias/downplay-mode/"))])
+ (doxy-graph-mode . [(20210604 723) ((emacs (26 3))) "Links source code editing with doxygen call graphs" single ((:commit . "88af6ef4bc9c8918b66c7774f0a115b2addc310e") (:authors ("Gustavo Puche" . "gustavo.puche@gmail.com")) (:maintainer "Gustavo Puche" . "gustavo.puche@gmail.com") (:keywords "languages" "all") (:url . "https://github.com/gustavopuche/doxy-graph-mode"))])
+ (dpaste . [(20160303 2112) nil "Emacs integration for dpaste.com" single ((:commit . "5ebabb466a6ae70882549855b6b2194fc32189f8") (:authors ("Greg Newman" . "greg@gregnewman.org") ("Guilherme Gondim" . "semente@taurinus.org")) (:maintainer "Greg Newman" . "greg@gregnewman.org") (:keywords "paste" "pastie" "pastebin" "dpaste" "python"))])
+ (dpaste_de . [(20131015 1225) ((web (0 3 7))) "Emacs mode to paste to dpaste.de" single ((:commit . "f0c39e8864299f735642f7d9fa490689398ce39d") (:authors ("Thejaswi Puthraya" . "thejaswi.puthraya@gmail.com")) (:maintainer "Thejaswi Puthraya" . "thejaswi.puthraya@gmail.com") (:keywords "pastebin"))])
+ (dpkg-dev-el . [(20190824 2314) ((debian-el (37))) "Emacs modes for debian packaging" tar ((:commit . "458f5230d02b15c94e94eca1af4eabaec30f45db") (:authors ("Peter S Galbraith" . "psg@debian.org")) (:maintainer "Peter S Galbraith" . "psg@debian.org"))])
+ (dr-racket-like-unicode . [(20200513 1642) ((emacs (24 1))) "DrRacket-style unicode input" single ((:commit . "70bc1caea6b277e49e1cb29e1926a7b0c83c5ebc") (:authors ("David Christiansen" . "david@davidchristiansen.dk")) (:maintainer "David Christiansen" . "david@davidchristiansen.dk") (:keywords "i18n" "tools"))])
+ (dracula-theme . [(20220209 724) ((emacs (24 3))) "Dracula Theme" single ((:commit . "e725c9e790c9e9cdaccdb35faaae9d5cb16ddb89") (:authors ("film42")) (:maintainer "Étienne Deparis" . "etienne@depar.is") (:url . "https://github.com/dracula/emacs"))])
+ (draft-mode . [(20140609 1456) nil "Rough drafting for Emacs." single ((:commit . "4779fb32daf53746459da2def7e08004492d4f18") (:authors ("Eeli Reilin" . "gaudecker@fea.st")) (:maintainer "Eeli Reilin" . "gaudecker@fea.st") (:keywords "draft" "drafting") (:url . "https://github.com/gaudecker/draft-mode"))])
+ (drag-stuff . [(20161108 749) nil "Drag stuff (lines, words, region, etc...) around" tar ((:commit . "6d06d846cd37c052d79acd0f372c13006aa7e7c8") (:authors ("Johan Andersson" . "johan.rejeep@gmail.com")) (:maintainer "Johan Andersson" . "johan.rejeep@gmail.com") (:keywords "speed" "convenience") (:url . "http://github.com/rejeep/drag-stuff"))])
+ (drawille . [(20160418 1838) ((cl-lib (0 5))) "Drawille implementation in elisp" tar ((:commit . "d914845725719d8293e2f0dea3c9c7e0a1e0e62a") (:authors ("Josuah Demangeon" . "josuah.demangeon@gmail.com")) (:maintainer "Josuah Demangeon" . "josuah.demangeon@gmail.com") (:keywords "graphics") (:url . "https://github.com/sshbio/elisp-drawille"))])
+ (dream-theme . [(20210419 605) ((emacs (26 1))) "Maximalist Nordic/Zenburn-inspired color theme" single ((:commit . "0c27f05544b90e41338f79ea923044b358a323c6") (:authors ("Dirk-Jan C. Binnema" . "djcb@djcbsoftware.nl")) (:maintainer "Dirk-Jan C. Binnema" . "djcb@djcbsoftware.nl") (:keywords "faces" "theme") (:url . "https://github.com/djcb/dream-theme"))])
+ (drill-instructor-AZIK-force . [(20151123 514) ((popup (0 5))) "Support AZIK input" tar ((:commit . "008cea202dc31d7d6fb1e7d8e6334d516403b7a5") (:authors ("Yuhei Maeda <yuhei.maeda_at_gmail.com>")) (:maintainer "Yuhei Maeda") (:keywords "convenience") (:url . "https://github.com/myuhe/drill-instructor-AZIK-force.el"))])
+ (drone . [(20161106 918) nil "Launch your drone test suite if drone.yml is present" single ((:commit . "1d4ee037ad3208847a4235426edf0c4a3e7b1899") (:authors ("Oliver Marks" . "oly@digitaloctave.com")) (:maintainer "Oliver Marks" . "oly@digitaloctave.com") (:keywords "drone" "tests" "ci") (:url . "https://github.com/olymk2/emacs-drone"))])
+ (dropbox . [(20220314 1638) ((request (0 3 0)) (json (1 2)) (oauth (1 0 3))) "Emacs backend for dropbox" single ((:commit . "c048faad0be24e8fa31974f08b710a87cf5b668c") (:authors ("Pavel Panchekha" . "me@pavpanchekha.com")) (:maintainer "Pavel Panchekha" . "me@pavpanchekha.com") (:keywords "dropbox"))])
+ (drupal-mode . [(20220125 1044) ((php-mode (1 5 0))) "Advanced minor mode for Drupal development" tar ((:commit . "17927723adc5921e8058f7c29e5e50e88b975639") (:authors ("Arne Jørgensen" . "arne@arnested.dk")) (:maintainer "Arne Jørgensen" . "arne@arnested.dk") (:keywords "programming" "php" "drupal") (:url . "https://github.com/arnested/drupal-mode"))])
+ (drupal-spell . [(20130520 1655) nil "Aspell extra dictionary for Drupal" tar ((:commit . "4087c28c89a884ee050961c57166e6b09085f59d") (:authors ("Arne Jørgensen" . "arne@arnested.dk")) (:maintainer "Arne Jørgensen" . "arne@arnested.dk") (:keywords "wp") (:url . "https://github.com/arnested/drupal-spell"))])
+ (dsvn . [(20190316 2201) nil "Subversion interface" single ((:commit . "c37d2412ba92aad647bcf5aeb151e620e8069f8d") (:authors ("David Kågedal" . "davidk@lysator.liu.se") (" Mattias Engdegård" . "mattiase@acm.org")) (:maintainer "Mattias Engdegård" . "mattiase@acm.org") (:keywords "docs"))])
+ (dtache . [(20220501 931) ((emacs (27 1))) "Run and interact with detached shell commands" tar ((:commit . "9becf3a921a0fde3a6e5d6f30379cf3d9826d565") (:authors ("Niklas Eklund" . "niklas.eklund@posteo.net")) (:maintainer "Niklas Eklund" . "niklas.eklund@posteo.net") (:keywords "convenience" "processes") (:url . "https://www.gitlab.com/niklaseklund/dtache.git"))])
+ (dtb-mode . [(20210105 1132) ((emacs (25))) "Show device tree souce in dtbs" single ((:commit . "7f66de945a0be2be5a26b4619cae097288fb55cd") (:authors ("Schspa Shi" . "schspa@gmail.com")) (:maintainer "Schspa Shi" . "schspa@gmail.com") (:keywords "dtb" "dts" "convenience") (:url . "https://github.com/schspa/dtb-mode"))])
+ (dtk . [(20220309 759) ((emacs (24 4)) (cl-lib (0 6 1)) (dash (2 12 0)) (seq (1 9)) (s (1 9))) "access SWORD content via diatheke" single ((:commit . "56b339bc76926defa775c406113e306ec6d31b36") (:authors ("David Thompson")) (:maintainer "David Thompson") (:keywords "hypermedia") (:url . "https://github.com/dtk01/dtk.el"))])
+ (dtrace-script-mode . [(20150214 623) nil "DTrace code editing commands for Emacs" single ((:commit . "801af1ef16075d31a19830ebb8404bbf3a322f10"))])
+ (dtrt-indent . [(20220226 1354) nil "Adapt to foreign indentation offsets" tar ((:commit . "66fc30af02901db023e464a24d2b5fb3ff472794") (:authors ("Julian Scheid" . "julians37@googlemail.com")) (:maintainer "Reuben Thomas" . "rrt@sc3d.org") (:keywords "convenience" "files" "languages" "c"))])
+ (dts-mode . [(20211202 18) nil "Major mode for Devicetree source code" single ((:commit . "32517e7eeeccc785b7c669fd5e93c5df45597ef1") (:authors ("Ben Gamari" . "ben@smart-cactus.org")) (:maintainer "Ben Gamari" . "ben@smart-cactus.org") (:keywords "languages"))])
+ (ducpel . [(20140702 1154) ((cl-lib (0 5))) "Logic game with sokoban elements" tar ((:commit . "b53b935ab95c02b82ccf38f63c89e39e99477a55") (:authors ("Alex Kost" . "alezost@gmail.com")) (:maintainer "Alex Kost" . "alezost@gmail.com") (:keywords "games") (:url . "https://github.com/alezost/ducpel"))])
+ (dumb-diff . [(20171211 2122) ((emacs (24 3))) "fast arbitrary diffs" single ((:commit . "1a2331d283049b71a07c1b06b1e0627a950d55f4") (:authors ("jack angers")) (:maintainer "jack angers") (:keywords "programming" "diff"))])
+ (dumb-jump . [(20211018 1545) ((emacs (24 3)) (s (1 11 0)) (dash (2 9 0)) (popup (0 5 3))) "Jump to definition for 50+ languages without configuration" single ((:commit . "dbb915441a2b66f2fbb954ff5de2723c5a4771d4") (:authors ("jack angers and contributors")) (:maintainer "jack angers and contributors") (:keywords "programming") (:url . "https://github.com/jacktasia/dumb-jump"))])
+ (dummyparens . [(20141009 1024) nil "parenthesis auto-pairing and wrapping" single ((:commit . "9798ef1d0eaa24e4fe66f8aa6022a8c62714cc89") (:authors ("Sergei Nosov <sergei.nosov [at] gmail.com>")) (:maintainer "Sergei Nosov <sergei.nosov [at] gmail.com>") (:keywords "dummyparens" "auto-pair" "wrapping") (:url . "https://github.com/snosov1/dummyparens"))])
+ (dune . [(20210909 1010) nil "Integration with the dune build system" tar ((:commit . "250db8e884ef4feae8b498f8e95737d07f5ee5ec") (:url . "https://github.com/ocaml/dune"))])
+ (dune-format . [(20210505 108) ((reformatter (0 6)) (emacs (24 1))) "Reformat OCaml's dune files automatically" single ((:commit . "196f16a01f4c855de7becddbc4cfed2f6788693a") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:keywords "languages") (:url . "https://github.com/purcell/emacs-dune-format"))])
+ (duplicate-thing . [(20181031 1500) nil "Duplicate current line & selection" single ((:commit . "9d8fd05e3e5caa35d3f2a0c0032c92f0c0908e21") (:authors ("ongaeshi")) (:maintainer "ongaeshi") (:keywords "convenience" "command" "duplicate" "line" "selection") (:url . "https://github.com/ongaeshi/duplicate-thing"))])
+ (dut-mode . [(20170729 2111) ((emacs (24))) "Major mode for the Dut programming language" single ((:commit . "9235c7acaa6690942e9de8b7acd1e4be0c859dc1") (:authors ("The dut-mode Authors")) (:maintainer "The dut-mode Authors") (:keywords "languages" "gut") (:url . "https://github.com/dut-lang/dut-mode"))])
+ (dw . [(20210331 2246) ((emacs (25 1))) "Diceware passphrase generation commands" single ((:commit . "61c5718ba64ace4c9e29de18aa2690ecc3f0f258") (:authors ("D. Williams" . "d.williams@posteo.net")) (:maintainer "D. Williams" . "d.williams@posteo.net") (:keywords "convenience" "games") (:url . "https://github.com/integral-dw/dw-passphrase-generator"))])
+ (dyalog-mode . [(20210413 810) ((cl-lib (0 2)) (emacs (24 3))) "Major mode for editing Dyalog APL source code" tar ((:commit . "697a84194766708d2607e8ba48a552e383c6523e") (:authors ("Joakim Hårsman" . "joakim.harsman@gmail.com")) (:maintainer "Joakim Hårsman" . "joakim.harsman@gmail.com") (:keywords "languages") (:url . "https://github.com/harsman/dyalog-mode.git"))])
+ (dylan . [(20220115 1804) ((emacs (25 1))) "Dylan editing modes" tar ((:commit . "9d2891e3e06405b75072d296f385fa795aeb9835") (:url . "https://opendylan.org/"))])
+ (dynamic-fonts . [(20140731 1226) ((font-utils (0 7 0)) (persistent-soft (0 8 8)) (pcache (0 2 3))) "Set faces based on available fonts" single ((:commit . "ab0c65accbdb59acaed5b263327e22ec019b3e82") (:authors ("Roland Walker" . "walker@pobox.com")) (:maintainer "Roland Walker" . "walker@pobox.com") (:keywords "faces" "frames") (:url . "http://github.com/rolandwalker/dynamic-fonts"))])
+ (dynamic-graphs . [(20210908 2010) ((emacs (26 1))) "Manipulation with graphviz graphs" single ((:commit . "64ca58dffecdecb636f7fe61c0c86e9c3c64d4dd") (:authors ("Tomas Zellerin" . "tomas@zellerin.cz")) (:maintainer "Tomas Zellerin" . "tomas@zellerin.cz") (:keywords "tools") (:url . "https://github.com/zellerin/dynamic-graphs"))])
+ (dynamic-ruler . [(20160602 808) nil "Displays a dynamic ruler at point." single ((:commit . "c9c0de6fe5721f06b50e01d9b4684b519c71b367") (:authors ("Francesc Rocher" . "francesc.rocher@gmail.com")) (:maintainer "Francesc Rocher" . "francesc.rocher@gmail.com") (:keywords "ruler" "tools" "convenience") (:url . "http://rocher.github.io/dynamic-ruler"))])
+ (dynamic-spaces . [(20171027 1851) nil "When editing, don't move text separated by spaces" single ((:commit . "97ae8480c257ba573ca3d06dbf602f9b23c41d38") (:authors ("Anders Lindgren")) (:maintainer "Anders Lindgren") (:keywords "convenience") (:url . "https://github.com/Lindydancer/dynamic-spaces"))])
+ (dynaring . [(20210924 2026) ((emacs (25 1))) "A dynamically sized ring structure" single ((:commit . "dc9013117bdcdc1b12feebcc58eaf129a6ad3a73") (:authors ("Mike Mattie" . "codermattie@gmail.com") ("Sid Kasivajhula" . "sid@countvajhula.com")) (:maintainer "Sid Kasivajhula" . "sid@countvajhula.com") (:url . "https://github.com/countvajhula/dynaring"))])
+ (dyncloze . [(20210712 145) ((emacs (25 1)) (dash (2 18))) "Language alternatives self-testing" tar ((:commit . "aafc5adc25c7f714b619109bccf92e475d6c84ef") (:authors ("Andrew Hyatt" . "ahyatt@gmail.com")) (:maintainer "Andrew Hyatt" . "ahyatt@gmail.com") (:url . "https://github.com/ahyatt/emacs-dyncloze"))])
+ (e2ansi . [(20190517 1902) ((face-explorer (0 0 4))) "Syntax highlighting support for `less', powered by Emacs." tar ((:commit . "6e1bb4e4e27885d1786db08b091cfa13b184fb54") (:authors ("Anders Lindgren")) (:maintainer "Anders Lindgren") (:keywords "faces" "languages") (:url . "https://github.com/Lindydancer/e2ansi"))])
+ (e2wm . [(20170215 36) ((window-layout (1 4))) "simple window manager for emacs" tar ((:commit . "4353d3394c77a49f8f0291c239858c8c5e877549") (:authors ("SAKURAI Masashi <m.sakurai atmark kiwanami.net>")) (:maintainer "SAKURAI Masashi <m.sakurai atmark kiwanami.net>") (:keywords "tools" "window manager"))])
+ (e2wm-R . [(20151230 926) ((e2wm (1 3)) (inlineR (1 0)) (ess (15 3))) "some e2wm plugin and perspective for GNU R" single ((:commit . "4350601ee1a96bf89777b3f09f1b79b88e2e6e4d") (:authors ("myuhe <yuhei.maeda_at_gmail.com>")) (:maintainer "myuhe") (:keywords "convenience" "e2wm") (:url . "https://github.com/myuhe/e2wm-R.el"))])
+ (e2wm-bookmark . [(20151123 521) ((e2wm (1 2))) "Bookmark plugin for e2wm.el" single ((:commit . "bad816b6d8049984d69bcd277b7d325fb84d55eb") (:authors ("Yuhei Maeda <yuhei.maeda_at_gmail.com>")) (:maintainer "Yuhei Maeda <yuhei.maeda_at_gmail.com>") (:keywords "convenience"))])
+ (e2wm-direx . [(20200805 1414) ((e2wm (1 2)) (direx (0 1 -3))) "Plugin of e2wm.el for direx.el" single ((:commit . "5672bc44d8e5cea6bc3b84c3b58e522050ffae0e") (:authors ("Hiroaki Otsu" . "ootsuhiroaki@gmail.com")) (:maintainer "Hiroaki Otsu" . "ootsuhiroaki@gmail.com") (:keywords "tools" "window manager" "convenience") (:url . "https://github.com/aki2o/e2wm-direx"))])
+ (e2wm-pkgex4pl . [(20140525 1047) ((e2wm (1 2)) (plsense-direx (0 2 0))) "Plugin of e2wm.el for package explorer of Perl" single ((:commit . "7ea994450727190c4f3cb46cb429ba41b692ecc0") (:authors ("Hiroaki Otsu" . "ootsuhiroaki@gmail.com")) (:maintainer "Hiroaki Otsu" . "ootsuhiroaki@gmail.com") (:keywords "tools" "window manager" "perl") (:url . "https://github.com/aki2o/e2wm-pkgex4pl"))])
+ (e2wm-svg-clock . [(20150106 1306) ((e2wm (20130225 1602)) (svg-clock (0 4))) "e2wm plugin for svg-clock" single ((:commit . "d425925e3afffcbe2ff74edc80b714e4319d4c94") (:authors ("Yuhei Maeda <yuhei.maeda_at_gmail.com>")) (:maintainer "Yuhei Maeda") (:keywords "convenience" "e2wm") (:url . "https://github.com/myuhe/e2wm-svg-clock.el"))])
+ (e2wm-sww . [(20200805 1339) ((e2wm (1 2))) "Plugin of e2wm.el to switch plugin quickly" single ((:commit . "8926d0c70be05c7b4ef821e22e411e8813973687") (:authors ("Hiroaki Otsu" . "ootsuhiroaki@gmail.com")) (:maintainer "Hiroaki Otsu" . "ootsuhiroaki@gmail.com") (:keywords "tools" "window manager") (:url . "https://github.com/aki2o/e2wm-sww"))])
+ (e2wm-term . [(20200322 729) ((e2wm (1 2)) (log4e (0 2 0)) (yaxception (0 3 2))) "Perspective of e2wm.el for work in terminal" single ((:commit . "74362d6271e736272df32ea807c5a22e4df54a50") (:authors ("Hiroaki Otsu" . "ootsuhiroaki@gmail.com")) (:maintainer "Hiroaki Otsu" . "ootsuhiroaki@gmail.com") (:keywords "tools" "window manager") (:url . "https://github.com/aki2o/e2wm-term"))])
+ (eacl . [(20220101 1517) ((emacs (25 1))) "Auto-complete lines by grepping project" single ((:commit . "4d9d42fa05e550dbac71a2c93e1da71c48af9449") (:authors ("Chen Bin <chenbin DOT sh AT gmail DOT com>")) (:maintainer "Chen Bin <chenbin DOT sh AT gmail DOT com>") (:keywords "abbrev" "convenience" "matching") (:url . "http://github.com/redguardtoo/eacl"))])
+ (earthfile-mode . [(20210903 230) ((emacs (26))) "Major mode for editing Earthly file" single ((:commit . "0f24876223a358d2718383e9e4975a26cee55f9d") (:authors ("Thanabodee Charoenpiriyakij" . "wingyminus@gmail.com")) (:maintainer "Thanabodee Charoenpiriyakij" . "wingyminus@gmail.com") (:url . "https://github.com/earthly/earthly-mode"))])
+ (easy-after-load . [(20170817 1231) nil "eval-after-load for all files in a directory" single ((:commit . "29e20145da49ac9ea40463c552130777408040de") (:authors ("Kyle Hargraves")) (:maintainer "Kyle Hargraves") (:url . "https://github.com/pd/easy-after-load"))])
+ (easy-escape . [(20210917 1254) nil "Improve readability of escape characters in regular expressions" single ((:commit . "938497a21e65ba6b3ff8ec90e93a6d0ab18dc9b4") (:authors ("Clément Pit-Claudel" . "clement.pitclaudel@live.com")) (:maintainer "Clément Pit-Claudel" . "clement.pitclaudel@live.com") (:keywords "convenience" "lisp" "tools") (:url . "https://github.com/cpitclaudel/easy-escape"))])
+ (easy-hugo . [(20211017 1248) ((emacs (25 1)) (popup (0 5 3)) (request (0 3 0)) (transient (0 3 6))) "Write blogs made with hugo by markdown or org-mode" tar ((:commit . "baead14d7f2fa86e108269932a94bf376de9c2e5") (:authors ("Masashi Miyaura")) (:maintainer "Masashi Miyaura") (:url . "https://github.com/masasam/emacs-easy-hugo"))])
+ (easy-jekyll . [(20211217 2311) ((emacs (25 1)) (request (0 3 0))) "Major mode managing jekyll blogs" single ((:commit . "7f19af310162464956f2bc4c38c6b7e95cb20321") (:authors ("Masashi Miyaura")) (:maintainer "Masashi Miyaura") (:url . "https://github.com/masasam/emacs-easy-jekyll"))])
+ (easy-kill . [(20220311 1506) ((emacs (25)) (cl-lib (0 5))) "kill & mark things easily" single ((:commit . "f9b450a87c41e5ef616df565ed158cb236aa5189") (:authors ("Leo Liu" . "sdl.web@gmail.com")) (:maintainer "Leo Liu" . "sdl.web@gmail.com") (:keywords "killing" "convenience") (:url . "https://github.com/leoliu/easy-kill"))])
+ (easy-kill-extras . [(20210529 945) ((easy-kill (0 9 4))) "Extra functions for easy-kill." tar ((:commit . "74e9d0fcafc38d5f24e6209671a552bc1ba5a867") (:authors ("Akinori MUSHA" . "knu@iDaemons.org")) (:maintainer "Akinori MUSHA" . "knu@iDaemons.org") (:keywords "killing" "convenience") (:url . "https://github.com/knu/easy-kill-extras.el"))])
+ (easy-repeat . [(20150516 848) ((emacs (24 4))) "Repeat easily" single ((:commit . "060f0e6801c82c40c06961dc0528a00e18947a8c") (:authors ("Chunyang Xu" . "xuchunyang56@gmail.com")) (:maintainer "Chunyang Xu" . "xuchunyang56@gmail.com") (:keywords "repeat" "convenience") (:url . "https://github.com/xuchunyang/easy-repeat.el"))])
+ (ebf . [(20210225 1211) ((dash (2 18 0)) (cl-lib (0 5))) "brainfuck language transpiler to Emacs Lisp" tar ((:commit . "6cbeb4d62416f4cfd5be8906667342af8ecc44a6") (:authors ("Alexey Kutepov" . "reximkut@gmail.com")) (:maintainer "Alexey Kutepov" . "reximkut@gmail.com") (:url . "http://github.com/rexim/ebf"))])
+ (ebib . [(20220430 2219) ((parsebib (2 3)) (emacs (26 1))) "a BibTeX database manager" tar ((:commit . "0e243a78f435038dda31953c5b48cbddf2a89e27") (:authors ("Joost Kremers" . "joostkremers@fastmail.fm")) (:maintainer "Joost Kremers" . "joostkremers@fastmail.fm") (:keywords "text" "bibtex") (:url . "http://joostkremers.github.io/ebib/"))])
+ (ebuku . [(20220106 902) ((emacs (25 1))) "Interface to the buku Web bookmark manager" single ((:commit . "5004d377f8c89436c28d4a7ffbef407a2b28861e") (:authors ("Alexis <flexibeast@gmail.com>, Erik Sjöstrand" . "sjostrand.erik@gmail.com")) (:maintainer "Alexis" . "flexibeast@gmail.com") (:keywords "bookmarks" "buku" "data" "web" "www") (:url . "https://github.com/flexibeast/ebuku"))])
+ (ecb . [(20170728 1921) nil "a code browser for Emacs" tar ((:commit . "1330a44cf3c171781083b0b926ab7622f64e6e81") (:authors ("Jesper Nordenberg" . "mayhem@home.se") ("Klaus Berndl" . "klaus.berndl@sdm.de") ("Kevin A. Burton" . "burton@openprivacy.org")) (:maintainer "Klaus Berndl" . "klaus.berndl@sdm.de") (:keywords "browser" "code" "programming" "tools"))])
+ (echo-bar . [(20220222 214) nil "Turn the echo area into a custom status bar" single ((:commit . "06cc8ef88f3b054f676b76815879bd6c71107591") (:authors ("Adam Tillou" . "qaiviq@gmail.com")) (:maintainer "Adam Tillou" . "qaiviq@gmail.com") (:keywords "convenience" "tools") (:url . "https://github.com/qaiviq/echo-bar.el"))])
+ (eclim . [(20181108 1134) ((dash (2 11 0)) (json (1 2)) (popup (0 5 2)) (s (1 9 0)) (cl-lib (0 5)) (yasnippet (0 10 0))) "An interface to the Eclipse IDE." tar ((:commit . "222ddd48fcf0ee01592dec77c58e0cf3f2ea1100"))])
+ (eclipse-theme . [(20191113 1518) nil "Theme based on Eclipse circa 2010" single ((:commit . "dcf97865512ed450f9d5137c1a05e12edb5b7f80") (:authors ("Oleh Krehel" . "ohwoeowho@gmail.com")) (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com") (:keywords "themes") (:url . "https://github.com/abo-abo/eclipse-theme"))])
+ (ecukes . [(20210202 1241) ((commander (0 6 1)) (espuds (0 2 2)) (ansi (0 3 0)) (dash (2 2 0)) (s (1 8 0)) (f (0 11 0))) "Cucumber for Emacs." tar ((:commit . "d173cdf487bc2c62305e2232db96290bc021950f"))])
+ (edbi . [(20160225 141) ((concurrent (0 3 1)) (ctable (0 1 2)) (epc (0 1 1))) "Emacs Database Interface" tar ((:commit . "6f50aaf4bde75255221f2292c7a4ad3fa9d918c0") (:authors ("SAKURAI Masashi <m.sakurai at kiwanami.net>")) (:maintainer "SAKURAI Masashi <m.sakurai at kiwanami.net>") (:keywords "database" "epc") (:url . "https://github.com/kiwanami/emacs-edbi"))])
+ (ede-compdb . [(20150920 2033) ((ede (1 2)) (semantic (2 2)) (cl-lib (0 4))) "Support for compilation database projects in EDE" single ((:commit . "d6d8466cd62876fc90adeff5875a1a584fd846cd") (:authors ("Alastair Rankine" . "alastair@girtby.net")) (:maintainer "Alastair Rankine" . "alastair@girtby.net") (:keywords "development" "ninja" "build" "cedet" "ede"))])
+ (ede-php-autoload . [(20180901 1255) nil "Simple EDE PHP Project" tar ((:commit . "8a4eeeaa93b8d87b65a107c4ebcbeb14528d9449") (:authors ("Steven Rémot" . "steven.remot@gmail.com") ("original code for C++ by Eric M. Ludlam" . "eric@siege-engine.com")) (:maintainer "Steven Rémot" . "steven.remot@gmail.com") (:keywords "php" "project" "ede") (:url . "https://github.com/emacs-php/ede-php-autoload"))])
+ (ede-php-autoload-composer-installers . [(20170221 2026) ((ede-php-autoload (1 0 0)) (f (0 19 0)) (s (1 7 0))) "Composer installers support for ede-php-autoload" single ((:commit . "7840439802c7d11ee086bbf465657f3da12f9f66") (:authors ("Thomas Fini Hansen" . "xen@xen.dk")) (:maintainer "Thomas Fini Hansen" . "xen@xen.dk") (:keywords "programming" "php") (:url . "https://github.com/xendk/ede-php-autoload-composer-installers"))])
+ (ede-php-autoload-drupal . [(20170316 2158) ((ede-php-autoload (1 0 0)) (f (0 19 0)) (s (1 7 0))) "Drupal support for ede-php-autoload" single ((:commit . "54a04241d94fabc4f4d16ae4dc8ba4f0c6e3b435") (:authors ("Thomas Fini Hansen" . "xen@xen.dk")) (:maintainer "Thomas Fini Hansen" . "xen@xen.dk") (:keywords "programming" "php" "drupal"))])
+ (edebug-inline-result . [(20220210 1357) ((emacs (25 1))) "Show Edebug result inline" single ((:commit . "9fb3c48434da24f800833a5ee3419452d5fb83cb") (:keywords "extensions" "lisp" "tools") (:url . "https://repo.or.cz/edebug-inline-result.git"))])
+ (edebug-x . [(20130616 625) nil "Extensions for Edebug" single ((:commit . "a2c2c42553d3bcbd5ac11898554865acbed1bc46") (:authors ("Scott Barnett" . "scott.n.barnett@gmail.com")) (:maintainer "Scott Barnett" . "scott.n.barnett@gmail.com") (:keywords "extensions") (:url . "https://github.com/ScottyB/edebug-x"))])
+ (edit-as-format . [(20220221 1312) ((emacs (26 1)) (edit-indirect (0 1 5))) "Edit document as other format" tar ((:commit . "59c6f439683846d994a7a2110b9b00cc16c08c40") (:authors ("Xiaobing Jing" . "jingxiaobing@gmail.com")) (:maintainer "Xiaobing Jing" . "jingxiaobing@gmail.com") (:keywords "files" "outlines" "convenience") (:url . "https://github.com/etern/edit-as-format"))])
+ (edit-at-point . [(20191013 1218) nil "edit(copy,cut..) current things(word,symbol..) under cursor" single ((:commit . "28c85a65c9c61f2aff50bc5e93f61cde26a5d9c0") (:authors (nil . "<e.enoson@gmail.com>")) (:maintainer nil . "<e.enoson@gmail.com>") (:url . "http://github.com/enoson/edit-at-point.el"))])
+ (edit-chrome-textarea . [(20200324 1513) ((emacs (25 1)) (websocket (1 4))) "Edit Chrome Textarea" single ((:commit . "e9ef6a72bdc6b58f932c51aa161869cee11b4bc9") (:authors ("Xu Chunyang")) (:maintainer "Xu Chunyang") (:keywords "tools") (:url . "https://github.com/xuchunyang/edit-chrome-textarea.el"))])
+ (edit-color-stamp . [(20130529 1733) ((es-lib (0 2)) (cl-lib (1 0))) "Edit a hex color stamp, using a QT or the internal color picker" tar ((:commit . "32dc1ca5bcf3dcf83fad5e39b55dc5b77becb3d3") (:authors ("sabof")) (:maintainer "sabof") (:url . "https://github.com/sabof/edit-color-stamp"))])
+ (edit-indirect . [(20220216 1812) ((emacs (24 3))) "Edit regions in separate buffers" single ((:commit . "e3d86416bcf8ddca951d7d112e57ad30c5f9a081") (:authors ("Fanael Linithien" . "fanael4@gmail.com")) (:maintainer "Fanael Linithien" . "fanael4@gmail.com") (:url . "https://github.com/Fanael/edit-indirect"))])
+ (edit-indirect-region-latex . [(20161129 645) ((emacs (24 3)) (ht (2 2)) (edit-indirect (0 1 4))) "Edit LaTeX regions in separate buffers, e.g. for English grammar checks" single ((:commit . "05043f2c0c9838947d3ca4b51b695deb7c47612e") (:authors ("Hirotaka Niitsuma" . "hirotaka.niitsuma@gmail.com")) (:maintainer "Hirotaka Niitsuma" . "hirotaka.niitsuma@gmail.com") (:url . "https://github.com/niitsuma/edit-indirect-region-latex"))])
+ (edit-list . [(20100930 1443) nil "edit a single list" single ((:commit . "f460d3f9e208a4e606fe6ded307f1b011916ca71") (:authors ("Michael Olson" . "mwolson@gnu.org")) (:maintainer "Michael Olson" . "mwolson@gnu.org") (:url . "http://mwolson.org/static/dist/elisp/edit-list.el"))])
+ (edit-server . [(20181016 1125) nil "server that responds to edit requests from Chrome" single ((:commit . "65a8e434547dcbe1df89dc3fd7aee075f8b06366") (:authors ("Alex Bennée" . "alex@bennee.com")) (:maintainer "Alex Bennée" . "alex@bennee.com") (:url . "https://github.com/stsquad/emacs_chrome"))])
+ (edit-server-htmlize . [(20130329 2248) ((edit-server (1 9))) "(de)HTMLization hooks for edit-server.el" single ((:commit . "e7f8dadfabe869c77ca241cd6fbd4c52bd908392") (:authors ("Roland McGrath" . "roland@hack.frob.com")) (:maintainer "Roland McGrath" . "roland@hack.frob.com") (:url . "https://github.com/frobtech/edit-server-htmlize"))])
+ (editorconfig . [(20220301 332) ((cl-lib (0 5)) (nadvice (0 3)) (emacs (24))) "EditorConfig Emacs Plugin" tar ((:commit . "1f6f16c24fd0030322d59c2853067a6dccc9e736") (:authors ("EditorConfig Team" . "editorconfig@googlegroups.com")) (:maintainer "EditorConfig Team" . "editorconfig@googlegroups.com") (:url . "https://github.com/editorconfig/editorconfig-emacs#readme"))])
+ (editorconfig-charset-extras . [(20180223 457) ((editorconfig (0 6 0))) "Extra EditorConfig Charset Support" single ((:commit . "4f75e175ad15ce2038f926fe4f0e5a0c1d0cbc46") (:authors ("10sr" . "8.slashes@gmail.com")) (:maintainer "10sr" . "8.slashes@gmail.com") (:keywords "tools") (:url . "https://github.com/10sr/editorconfig-charset-extras-el"))])
+ (editorconfig-custom-majormode . [(20180816 244) ((editorconfig (0 6 0))) "Decide major-mode and mmm-mode from EditorConfig" single ((:commit . "13ad1c83f847bedd4b3a19f9df7fd925853b19de") (:authors ("10sr <8slashes+el [at] gmail [dot] com>")) (:maintainer "10sr <8slashes+el [at] gmail [dot] com>") (:keywords "editorconfig" "util") (:url . "https://github.com/10sr/editorconfig-custom-majormode-el"))])
+ (editorconfig-domain-specific . [(20180505 924) ((cl-lib (0 5)) (editorconfig (0 6 0))) "Apply brace style and other \"domain-specific\" EditorConfig properties" single ((:commit . "e9824160fb2e466afa755240ee3ab7cc5657fb04") (:authors ("Lassi Kortela" . "lassi@lassi.io")) (:maintainer "Lassi Kortela" . "lassi@lassi.io") (:keywords "editorconfig" "util") (:url . "https://github.com/lassik/editorconfig-emacs-domain-specific"))])
+ (editorconfig-generate . [(20190513 433) ((emacs (24))) "Generate .editorconfig" single ((:commit . "47a31f928f46d2a0188db8e2cffa5d6354a81573") (:authors ("10sr" . "8.slashes@gmail.com")) (:maintainer "10sr" . "8.slashes@gmail.com") (:keywords "tools") (:url . "https://github.com/10sr/editorconfig-generate-el"))])
+ (edn . [(20160215 1219) ((cl-lib (0 3)) (emacs (24 1)) (peg (0 6))) "Support for reading and writing the edn data format from elisp" single ((:commit . "21e120a6914ee9a694be0a051f9f2af34ef055e4") (:authors ("Lars Andersen" . "expez@expez.com")) (:maintainer "Lars Andersen" . "expez@expez.com") (:keywords "edn" "clojure") (:url . "https://www.github.com/expez/edn.el"))])
+ (ednc . [(20220404 2105) ((emacs (26 1))) "Emacs Desktop Notification Center" single ((:commit . "d1a3c37235dd87e0bce6ffc75f5568218d6d83b4") (:authors ("Simon Nicolussi" . "sinic@sinic.name")) (:maintainer "Simon Nicolussi" . "sinic@sinic.name") (:keywords "unix") (:url . "https://github.com/sinic/ednc"))])
+ (edts . [(20220415 1722) ((auto-complete (20201213 1255)) (auto-highlight-symbol (20211106 638)) (dash (20210609 1330)) (emacs (24 3)) (erlang (20210315 1640)) (f (20191110 1357)) (popup (20210317 138)) (s (20210603 736))) "Erlang Development Tool Suite" tar ((:commit . "5c096ecdf9462b125f2eb4092899ff63636cfc40"))])
+ (edwina . [(20200113 1714) ((emacs (25))) "Dynamic window manager" tar ((:commit . "c5368716a504c93407fd8cb4ef925a8d8eb62698") (:authors ("Alex Griffin" . "a@ajgrf.com")) (:maintainer "Alex Griffin" . "a@ajgrf.com") (:keywords "convenience") (:url . "https://github.com/ajgrf/edwina"))])
+ (efar . [(20211122 1943) ((emacs (26 1))) "FAR-like file manager" single ((:commit . "49dc9b89a8b9bf2523c202ac8830d1245768f3f4") (:authors ("\"Vladimir Suntsov\"" . "vladimir@suntsov.online")) (:maintainer nil . "vladimir@suntsov.online") (:keywords "files") (:url . "https://github.com/suntsov/efar"))])
+ (efire . [(20151009 2031) ((circe (1 2))) "Use campfire from Emacs" single ((:commit . "91a644662afb352475efad0b377713656f131e5c") (:authors ("João Távora" . "joaotavora@gmail.com")) (:maintainer "João Távora" . "joaotavora@gmail.com") (:keywords "convenience" "tools") (:url . "https://github.com/capitaomorte/efire"))])
+ (eg . [(20170830 815) ((cl-lib (0 5)) (emacs (24 3))) "Norton Guide reader" single ((:commit . "1c7f1613d2aaae728ef540305f6ba030616f86bd") (:authors ("Dave Pearson" . "davep@davep.org")) (:maintainer "Dave Pearson" . "davep@davep.org") (:keywords "docs") (:url . "https://github.com/davep/eg.el"))])
+ (egalgo . [(20211105 1657) ((emacs (24 3))) "Genetic algorithm" single ((:commit . "a56a86591351d53ca2add7c651757bfb0064fb22") (:authors ("ROCKTAKEY" . "rocktakey@gmail.com")) (:maintainer "ROCKTAKEY" . "rocktakey@gmail.com") (:keywords "data") (:url . "https://github.com/ROCKTAKEY/egalgo"))])
+ (egg . [(20181126 500) nil "Emacs Got Git - Emacs interface to Git" tar ((:commit . "00e768a78ac3d25f457eed667d02cac568480bf9") (:authors ("Bogolisk" . "bogolisk@gmail.com")) (:maintainer "Bogolisk" . "bogolisk@gmail.com") (:keywords "git" "version control" "release management"))])
+ (egg-timer . [(20200217 1650) ((emacs (25 1))) "Commonly used intervals for setting timers while working" single ((:commit . "e3542aeb80905956b94373a222a9cbac04e6497e") (:authors ("William Carroll" . "wpcarro@gmail.com")) (:maintainer "William Carroll" . "wpcarro@gmail.com") (:url . "https://github.com/wpcarro/egg-timer.el"))])
+ (egison-mode . [(20200107 2333) nil "Egison editing mode" tar ((:commit . "dbb395b41a4e4eb69f3f045cbfbe95a1575ac45b") (:authors ("Satoshi Egi" . "egisatoshi@gmail.com")) (:maintainer "Satoshi Egi" . "egisatoshi@gmail.com") (:url . "https://github.com/egisatoshi/egison3/blob/master/elisp/egison-mode.el"))])
+ (eglot . [(20220503 953) ((emacs (26 1)) (jsonrpc (1 0 14)) (flymake (1 2 1)) (project (0 3 0)) (xref (1 0 1)) (eldoc (1 11 0)) (seq (2 23))) "Client for Language Server Protocol (LSP) servers" single ((:commit . "f8556b7e76ef7086191c469979274e499d992aed") (:authors ("João Távora" . "joaotavora@gmail.com")) (:maintainer "João Távora" . "joaotavora@gmail.com") (:keywords "convenience" "languages") (:url . "https://github.com/joaotavora/eglot"))])
+ (eglot-fsharp . [(20220409 1811) ((emacs (27 1)) (eglot (1 4)) (fsharp-mode (1 10)) (jsonrpc (1 0 14))) "fsharp-mode eglot integration" single ((:commit . "5208b54098c7534f4768b87c5f4c8a01b638737b") (:authors ("Jürgen Hötzel" . "juergen@archlinux.org")) (:maintainer "Jürgen Hötzel" . "juergen@archlinux.org") (:keywords "languages") (:url . "https://github.com/fsharp/emacs-fsharp-mode"))])
+ (eglot-java . [(20220403 1815) ((emacs (26 1)) (eglot (1 0)) (jsonrpc (1 0 0))) "Java extension for the eglot LSP client" single ((:commit . "da76eb69b3f86992d62302649a987f157b7b7371") (:authors ("Yves Zoundi" . "yves_zoundi@hotmail.com")) (:maintainer "Yves Zoundi" . "yves_zoundi@hotmail.com") (:keywords "convenience" "languages") (:url . "https://github.com/yveszoundi/eglot-java"))])
+ (eglot-jl . [(20211208 359) ((emacs (25 1)) (eglot (1 4)) (julia-mode (0 3))) "Julia support for eglot" tar ((:commit . "2e35cf9768d97a0429a72deddbe30d6d7722d454") (:authors ("Adam Beckmeyer" . "adam_git@thebeckmeyers.xyz")) (:maintainer "Adam Beckmeyer" . "adam_git@thebeckmeyers.xyz") (:keywords "convenience" "languages") (:url . "https://github.com/non-Jedi/eglot-jl"))])
+ (ego . [(20200803 1101) ((emacs (24 5)) (ht (1 5)) (mustache (0 22)) (htmlize (1 47)) (org (8 0)) (dash (2 0 0))) "a static site generator based on org mode, forked from org-page." tar ((:commit . "211c4cb2af2582849d9df984fb2346deecaf79be") (:authors ("Feng Shu <tumashu AT 163.com>") ("Kelvin Hu <ini DOT kelvin AT gmail DOT com>") ("Kuangdash <kuangdash AT 163.com>")) (:maintainer "Feng Shu <tumashu AT 163.com>") (:keywords "org-mode" "convenience" "beautify") (:url . "https://github.com/emacs-china/EGO"))])
+ (eide . [(20220316 619) nil "IDE interface" tar ((:commit . "23c78f4850f44d18eef66c694e7e05882d841ba6") (:authors ("Cédric Marie" . "cedric@hjuvi.fr.eu.org")) (:maintainer "Cédric Marie" . "cedric@hjuvi.fr.eu.org") (:url . "https://forge.chapril.org/hjuvi/eide"))])
+ (eimp . [(20120826 2039) nil "Emacs Image Manipulation Package" single ((:commit . "2e7536fe6d8f7faf1bad7a8ae37faba0162c3b4f") (:authors ("Matthew P. Hodges" . "MPHodges@member.fsf.org")) (:maintainer "Nic Ferrier" . "nferrier@ferrier.me.uk") (:keywords "files" "frames"))])
+ (ein . [(20220419 735) ((emacs (25)) (websocket (1 12)) (anaphora (1 0 4)) (request (0 3 3)) (deferred (0 5)) (polymode (0 2 2)) (dash (2 13 0)) (with-editor (0 -1))) "Emacs IPython Notebook" tar ((:commit . "388c8f753cfb99b4f82acbdff26bbe27189d2299") (:keywords "jupyter" "literate programming" "reproducible research") (:url . "https://github.com/dickmao/emacs-ipython-notebook"))])
+ (eink-theme . [(20190219 858) nil "E Ink color theme" single ((:commit . "326b07523dcb076d6209cdbc7fdbb73df296dbdb") (:authors ("Marian Schubert" . "marian.schubert@gmail.com")) (:maintainer "Marian Schubert" . "marian.schubert@gmail.com") (:url . "http://github.com/maio/eink-emacs"))])
+ (ejc-sql . [(20220414 1329) ((emacs (26 3)) (clomacs (0 0 5)) (dash (2 16 0)) (spinner (1 7 3)) (direx (1 0 0))) "Emacs SQL client uses Clojure JDBC." tar ((:commit . "5c6341c751da9c7dbed43eafc8e99f456c1de0d2") (:authors ("Kostafey" . "kostafey@gmail.com")) (:maintainer "Kostafey" . "kostafey@gmail.com") (:keywords "sql" "jdbc") (:url . "https://github.com/kostafey/ejc-sql"))])
+ (ejson-mode . [(20190720 2138) ((emacs (25))) "Major mode for editing ejson files." single ((:commit . "9630dfac9549779711dbe89e621f516bb4b3a354") (:authors ("Dante Catalfamo")) (:maintainer "Dante Catalfamo") (:keywords "convenience" "languages" "tools") (:url . "https://github.com/dantecatalfamo/ejson-mode"))])
+ (el-autoyas . [(20120918 1317) nil "Automatically create Emacs-Lisp Yasnippets" tar ((:commit . "bde0251ecb504f585dfa27c205c8e312655310cc") (:authors ("Matthew L. Fidler")) (:maintainer "Matthew L. Fidler") (:keywords "emacs" "lisp" "mode" "yasnippet") (:url . "https://github.com/mlf176f2/el-autoyas.el"))])
+ (el-fetch . [(20220426 2053) ((emacs (25 1))) "Show system information in Neofetch-like style (eg CPU, RAM)" single ((:commit . "f9d396437ee0cc5362a80b8ce11e15cfe4d2d510") (:authors ("Maciej Barć" . "xgqt@riseup.net")) (:maintainer "Maciej Barć" . "xgqt@riseup.net") (:url . "https://gitlab.com/xgqt/emacs-el-fetch"))])
+ (el-fly-indent-mode . [(20180422 243) ((emacs (25))) "Indent Emacs Lisp on the fly" single ((:commit . "39738c88c01a3a035edffe63400d434edb1e3003") (:authors ("Jiahao Li" . "jiahaowork@gmail.com")) (:maintainer "Jiahao Li" . "jiahaowork@gmail.com") (:keywords "lisp" "languages") (:url . "https://github.com/jiahaowork/el-fly-indent-mode.el"))])
+ (el-get . [(20211224 959) nil "Manage the external elisp bits and pieces you depend upon" tar ((:commit . "9353309744e4f8a7c9b1adf22ec99536fb2146b0") (:authors ("Dimitri Fontaine" . "dim@tapoueh.org")) (:maintainer "Dimitri Fontaine" . "dim@tapoueh.org") (:keywords "emacs" "package" "elisp" "install" "elpa" "git" "git-svn" "bzr" "cvs" "svn" "darcs" "hg" "apt-get" "fink" "pacman" "http" "http-tar" "emacswiki") (:url . "http://www.emacswiki.org/emacs/el-get"))])
+ (el-init . [(20150728 920) ((emacs (24)) (cl-lib (0 5)) (anaphora (1 0 0))) "A loader inspired by init-loader" single ((:commit . "7538e1511ff7ceea2ba65ed4783c57e2f9176ee6") (:authors ("Hiroki YAMAKAWA" . "s06139@gmail.com")) (:maintainer "Hiroki YAMAKAWA" . "s06139@gmail.com") (:url . "https://github.com/HKey/el-init"))])
+ (el-init-viewer . [(20150303 828) ((emacs (24)) (cl-lib (0 5)) (ctable (0 1 2)) (dash (2 10 0)) (anaphora (1 0 0)) (el-init (0 1 4))) "Record viewer for el-init" single ((:commit . "7c0169d356d6c007317e253e5776e1e48a60d6ad") (:authors ("Hiroki YAMAKAWA" . "s06139@gmail.com")) (:maintainer "Hiroki YAMAKAWA" . "s06139@gmail.com") (:url . "https://github.com/HKey/el-init-viewer"))])
+ (el-mock . [(20170824 1954) nil "Tiny Mock and Stub framework in Emacs Lisp" single ((:commit . "6ebfe64410d54b4cf76f655e416d49935d5e2ceb") (:authors ("rubikitch" . "rubikitch@ruby-lang.org")) (:maintainer "Johan Andersson" . "johan.rejeep@gmail.com") (:keywords "lisp" "testing" "unittest") (:url . "http://github.com/rejeep/el-mock.el"))])
+ (el-patch . [(20220417 1946) ((emacs (26))) "Future-proof your Elisp" tar ((:commit . "d4f4574bcf4005f4fbafde8874cb19b907783956") (:authors ("Radon Rosborough" . "radon.neon@gmail.com")) (:maintainer "Radon Rosborough" . "radon.neon@gmail.com") (:keywords "extensions") (:url . "https://github.com/raxod502/el-patch"))])
+ (el-secretario . [(20220422 2005) ((emacs (27 1)) (org-ql (0 6 -1)) (hercules (0 3))) "Unify all your inboxes with the Emacs secretary" tar ((:commit . "c28a4f42829ed1f96a17abb63a8616216db913a5") (:authors ("Leo Okawa Ericson <http://github/Zetagon>")) (:maintainer "Leo" . "github@relevant-information.com") (:keywords "convenience") (:url . "https://git.sr.ht/~zetagon/el-secretario"))])
+ (el-secretario-elfeed . [(20211214 1851) ((emacs (27 1)) (el-secretario (0 0 1)) (elfeed (3 4 1))) "Add notmuch email inboxes to el-secretario" single ((:commit . "c28a4f42829ed1f96a17abb63a8616216db913a5") (:authors ("Leo Okawa Ericson <http://github/Zetagon>")) (:maintainer "Leo" . "github@relevant-information.com") (:keywords "convenience") (:url . "https://git.sr.ht/~zetagon/el-secretario"))])
+ (el-secretario-mu4e . [(20220422 2006) ((emacs (27 1)) (org-ql (0 6 -1)) (el-secretario (0 0 1))) "Add mu4e inboxes to el-secretario" single ((:commit . "c28a4f42829ed1f96a17abb63a8616216db913a5") (:authors ("Leo Okawa Ericson <http://github/Zetagon>")) (:maintainer "Leo" . "github@relevant-information.com") (:keywords "convenience" "mail") (:url . "https://git.sr.ht/~zetagon/el-secretario"))])
+ (el-secretario-notmuch . [(20220426 1905) ((emacs (27 1)) (el-secretario (0 0 1)) (notmuch (0 3 1))) "Add notmuch inboxes to el-secretario" single ((:commit . "c28a4f42829ed1f96a17abb63a8616216db913a5") (:authors ("Leo Okawa Ericson <http://github/Zetagon>")) (:maintainer "Leo" . "github@relevant-information.com") (:keywords "convenience" "mail") (:url . "https://git.sr.ht/~zetagon/el-secretario"))])
+ (el-secretario-org . [(20220411 1419) ((emacs (27 1)) (org-ql (0 6 -1)) (dash (2 18 1)) (el-secretario (0 0 1))) "Create inboxes out of org-mode files for el-secretario" single ((:commit . "c28a4f42829ed1f96a17abb63a8616216db913a5") (:authors ("Leo Okawa Ericson <http://github/Zetagon>")) (:maintainer "Leo" . "github@relevant-information.com") (:keywords "convenience") (:url . "https://git.sr.ht/~zetagon/el-secretario"))])
+ (el-spec . [(20121018 704) nil "ruby's rspec like syntax test frame work" single ((:commit . "1dbc465401d4aea5560318c4f13ff30920a0718d") (:authors ("Yuuki Arisawa" . "yuuki.ari@gmail.com")) (:maintainer "Yuuki Arisawa" . "yuuki.ari@gmail.com") (:keywords "test") (:url . "https://github.com/uk-ar/el-spec"))])
+ (el-spice . [(20201013 1729) nil "Extra spice for emacs lisp programming" tar ((:commit . "a1adde201ee10881b522e67aa2c605378943a28d") (:authors ("Vedang Manerikar" . "vedang.manerikar@gmail.com")) (:maintainer "Vedang Manerikar" . "vedang.manerikar@gmail.com") (:keywords "languages" "extensions") (:url . "https://github.com/vedang/el-spice"))])
+ (el-sprunge . [(20200312 1212) ((web-server (20140105 2246)) (htmlize (20130207 1202)) (emacs (24 3))) "Command line paste server with Emacs highlighting" tar ((:commit . "e4365ea0bdf60969817619376bdcc98003fec33d") (:authors ("Eric Schulte" . "schulte.eric@gmail.com")) (:maintainer "Eric Schulte" . "schulte.eric@gmail.com") (:keywords "http" "html" "server" "sprunge" "paste"))])
+ (el-spy . [(20131226 2008) nil "Mocking framework for Emacs lisp. It also support spy, proxy." single ((:commit . "b1dead9d1877660856ada22d906ac4e54695aec7") (:authors ("Yuuki Arisawa" . "yuuki.ari@gmail.com")) (:maintainer "Yuuki Arisawa" . "yuuki.ari@gmail.com") (:keywords "test") (:url . "https://github.com/uk-ar/el-spy"))])
+ (el2markdown . [(20170630 1858) nil "Convert commentary section of elisp files to markdown." single ((:commit . "368d99313683cd943c99feaffca356be60bdb636") (:authors ("Anders Lindgren")) (:maintainer "Anders Lindgren") (:url . "https://github.com/Lindydancer/el2markdown"))])
+ (el2org . [(20200408 146) ((emacs (25 1))) "Convert elisp file to org file" single ((:commit . "7db77fdd73f378d4e60e34c11bbdf00677adc32c") (:authors ("Feng Shu " . "tumashu@163.com")) (:maintainer "Feng Shu " . "tumashu@163.com") (:keywords "convenience") (:url . "https://github.com/tumashu/el2org"))])
+ (elbank . [(20180316 1343) ((emacs (25)) (seq (2 16))) "Personal finances reporting application" tar ((:commit . "fa9bc7dec0a8fd489e90b9f178719344cc8d315a") (:authors ("Nicolas Petton" . "nicolas@petton.fr")) (:maintainer "Nicolas Petton" . "nicolas@petton.fr") (:keywords "tools" "personal-finances"))])
+ (elcontext . [(20210109 1238) ((ht (2 3)) (hydra (0 14 0)) (emacs (24 3)) (f (0 20 0)) (osx-location (0 4)) (uuidgen (0 3))) "Create context specific actions" tar ((:commit . "2efd3dd8c5176c4f071bb048be6cb069b05d6e9e") (:authors ("Thomas Sojka")) (:maintainer "Thomas Sojka") (:keywords "calendar" "convenience") (:url . "https://github.com/rollacaster/elcontext"))])
+ (elcord . [(20220305 1234) ((emacs (25 1))) "Allows you to integrate Rich Presence from Discord" tar ((:commit . "70fd716e673b724b30b921f4cfa0033f9c02d0f2") (:authors ("heatingdevice") ("Wilfredo Velázquez-Rodríguez" . "zulu.inuoe@gmail.com")) (:maintainer "heatingdevice") (:keywords "games") (:url . "https://github.com/Mstrodl/elcord"))])
+ (elcouch . [(20201108 955) ((emacs (25 1)) (json-mode (1 0 0)) (libelcouch (0 11 0)) (navigel (0 3 0))) "View and manipulate CouchDB databases" single ((:commit . "3d162dda14411349e12509029d2b621c5d1edea2") (:authors ("Damien Cassou" . "damien@cassou.me")) (:maintainer "Damien Cassou" . "damien@cassou.me") (:keywords "data" "tools") (:url . "https://gitlab.petton.fr/DamienCassou/elcouch"))])
+ (eldev . [(20220501 1128) ((emacs (24 4))) "Elisp Development Tool" tar ((:commit . "7275089749779599d87bee878e5103921ea919f9") (:authors ("Paul Pogonyshev" . "pogonyshev@gmail.com")) (:maintainer "Paul Pogonyshev" . "pogonyshev@gmail.com") (:keywords "maint" "tools") (:url . "https://github.com/doublep/eldev"))])
+ (eldoc-box . [(20220505 315) ((emacs (27 1))) "Display documentation in childframe" single ((:commit . "6c3107aa6955b8ada76f73519363224efda097d8") (:authors ("Sebastien Chapuis" . "sebastien@chapu.is")) (:maintainer "Yuan Fu" . "casouri@gmail.com") (:url . "https://github.com/casouri/eldoc-box"))])
+ (eldoc-cmake . [(20190419 2244) ((emacs (25 1))) "Eldoc support for CMake" single ((:commit . "4453c03b5c95ff32842f13db2fc317fb0fe2f79e") (:authors ("Kirill Ignatiev")) (:maintainer "Kirill Ignatiev") (:url . "https://github.com/ikirill/eldoc-cmake"))])
+ (eldoc-eval . [(20220106 1951) nil "Enable eldoc support when minibuffer is in use." single ((:commit . "e91800503c90cb75dc70abe42f1d6ae499346cc1") (:authors ("Thierry Volpiatto" . "thievol@posteo.net")) (:maintainer "Thierry Volpiatto" . "thievol@posteo.net"))])
+ (eldoc-overlay . [(20220210 1358) ((emacs (24 3)) (inline-docs (1 0 1)) (quick-peek (1 0))) "Display eldoc with contextual documentation overlay." single ((:commit . "b96f5864a47407ec608c807e0d890f62b891ee03") (:authors ("stardiviner" . "numbchild@gmail.com")) (:maintainer "stardiviner" . "numbchild@gmail.com") (:keywords "documentation" "eldoc" "overlay") (:url . "https://repo.or.cz/eldoc-overlay.git"))])
+ (eldoc-stan . [(20211129 2051) ((emacs (25)) (stan-mode (10 3 0))) "Eldoc support for stan functions" tar ((:commit . "150bbbe5fd3ad2b5a3dbfba9d291e66eeea1a581") (:authors ("Kazuki Yoshida" . "kazukiyoshida@mail.harvard.edu")) (:maintainer "Kazuki Yoshida" . "kazukiyoshida@mail.harvard.edu") (:keywords "help" "tools") (:url . "https://github.com/stan-dev/stan-mode/tree/master/eldoc-stan"))])
+ (eldoc-toml . [(20211026 1122) ((emacs (24 4))) "TOML table name at point for ElDoc" single ((:commit . "61106be3c3f3a5b293c3f285eec8c6f400142b6d") (:authors ("Maor Kadosh" . "git@avocadosh.xyz")) (:maintainer "Maor Kadosh" . "git@avocadosh.xyz") (:keywords "data") (:url . "https://github.com/it-is-wednesday/eldoc-toml"))])
+ (electric-case . [(20150417 1112) nil "insert camelCase, snake_case words without \"Shift\"ing" single ((:commit . "bac64e772107e3dc721a9819f63b9ebdc28a81f7") (:authors ("zk_phi")) (:maintainer "zk_phi") (:url . "http://hins11.yu-yake.com/"))])
+ (electric-cursor . [(20220108 2052) ((emacs (25 1))) "Change cursor automatically depending on mode" single ((:commit . "92f77b05fec80c5440a8b800b33345dabca13872") (:authors ("Case Duckworth" . "acdw@acdw.net")) (:maintainer "Case Duckworth" . "acdw@acdw.net") (:keywords "terminals" "frames") (:url . "https://github.com/duckwork/electric-cursor"))])
+ (electric-operator . [(20220417 809) ((dash (2 10 0)) (emacs (24 4))) "Automatically add spaces around operators" tar ((:commit . "f567f03da4a55d6eafa0e6e148ca4884d5370498") (:authors ("David Shepherd" . "davidshepherd7@gmail.com")) (:maintainer "David Shepherd" . "davidshepherd7@gmail.com") (:keywords "electric") (:url . "https://github.com/davidshepherd7/electric-operator"))])
+ (electric-spacing . [(20220220 1540) nil "Insert operators with surrounding spaces smartly" tar ((:commit . "c37b2502512dd49a8311d7c34e9bfd1af3d4dbcd") (:authors ("William Xu" . "william.xwl@gmail.com")) (:maintainer "William Xu" . "william.xwl@gmail.com"))])
+ (elegant-agenda-mode . [(20210115 353) ((emacs (26 1))) "An elegant theme for your org-agenda" single ((:commit . "5cbc688584ba103ea3be7d7b30e5d94e52f59eb6") (:authors ("Justin Barclay" . "justinbarclay@gmail.com")) (:maintainer "Justin Barclay" . "justinbarclay@gmail.com") (:keywords "faces") (:url . "https://github.com/justinbarclay/elegant-agenda-mode"))])
+ (elein . [(20120120 1116) nil "running leiningen commands from emacs" single ((:commit . "d4c0c0491dbb7c90e953d7a16172107c37103605") (:authors ("R.W. van 't Veer")) (:maintainer "R.W. van 't Veer") (:keywords "tools" "processes") (:url . "https://github.com/remvee/elein"))])
+ (elescope . [(20210312 1147) ((emacs (25 1)) (ivy (0 10)) (request (0 3)) (seq (2 0))) "Seach and clone projects from the minibuffer" single ((:commit . "36566c8c1f5f993f67eadc85d18539ff375c0f98") (:authors ("Stéphane Maniaci" . "stephane.maniaci@gmail.com")) (:maintainer "Stéphane Maniaci" . "stephane.maniaci@gmail.com") (:keywords "vc") (:url . "https://github.com/freesteph/elescope"))])
+ (elf-mode . [(20161009 748) ((emacs (24 3))) "Show symbols in binaries" single ((:commit . "cd280d683cd3341d8bb31af6db7e3b74a133e6ab") (:authors ("Oleh Krehel" . "ohwoeowho@gmail.com")) (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com") (:keywords "matching") (:url . "https://github.com/abo-abo/elf-mode"))])
+ (elfeed . [(20210822 2129) ((emacs (24 3))) "an Emacs Atom/RSS feed reader" tar ((:commit . "162d7d545ed41c27967d108c04aa31f5a61c8e16") (:authors ("Christopher Wellons" . "wellons@nullprogram.com")) (:maintainer "Christopher Wellons" . "wellons@nullprogram.com") (:url . "https://github.com/skeeto/elfeed"))])
+ (elfeed-autotag . [(20210607 637) ((emacs (27 1)) (elfeed (3 4 1)) (elfeed-protocol (0 8 0)) (org (8 2 7)) (dash (2 10 0)) (s (1 9 0))) "Easy auto-tagging for elfeed" single ((:commit . "bc62c37fb79b720ff8b6d67f04f2268841306dcd") (:authors ("Paul Elms <https://paul.elms.pro>")) (:maintainer "Paul Elms" . "paul@elms.pro") (:keywords "news") (:url . "https://github.com/paulelms/elfeed-autotag"))])
+ (elfeed-dashboard . [(20210727 603) ((emacs (25 1)) (elfeed (3 3 0))) "An extensible frontend for elfeed using org-mode" single ((:commit . "26ff3573efce3cb66c8814854a2983a69683af09") (:authors ("Manoj Kumar Manikchand" . "manojm321@protonmail.com")) (:maintainer "Manoj Kumar Manikchand" . "manojm321@protonmail.com") (:keywords "convenience") (:url . "https://github.com/Manoj321/elfeed-dashboard"))])
+ (elfeed-goodies . [(20220306 2253) ((popwin (1 0 0)) (powerline (2 2)) (elfeed (2 0 0)) (cl-lib (0 5)) (link-hint (0 1))) "Elfeed goodies" tar ((:commit . "6711de66c22360f80fcfd9730293e5f3d419f787") (:authors ("Gergely Nagy")) (:maintainer "Gergely Nagy") (:url . "https://github.com/algernon/elfeed-goodies"))])
+ (elfeed-org . [(20220420 1234) ((elfeed (1 1 1)) (org (8 2 7)) (dash (2 10 0)) (s (1 9 0)) (cl-lib (0 5))) "Configure elfeed with one or more org-mode files" single ((:commit . "e6bf4268485703907a97896fb1080f59977c9e3d") (:authors ("Remy Honig" . "remyhonig@gmail.com")) (:maintainer "Remy Honig" . "remyhonig@gmail.com") (:keywords "news") (:url . "https://github.com/remyhonig/elfeed-org"))])
+ (elfeed-protocol . [(20220419 1358) ((emacs (24 4)) (elfeed (2 1 1)) (cl-lib (0 5))) "Provide fever/newsblur/owncloud/ttrss protocols for elfeed" tar ((:commit . "eaf1329ff221098eb6d4709245010d070c89b173") (:authors ("Xu Fasheng <fasheng[AT]fasheng.info>")) (:maintainer "Xu Fasheng <fasheng[AT]fasheng.info>") (:keywords "news") (:url . "https://github.com/fasheng/elfeed-protocol"))])
+ (elfeed-score . [(20220428 123) ((emacs (26 1)) (elfeed (3 3 0))) "Gnus-style scoring for Elfeed" tar ((:commit . "419de17d681d75789271b8457509fa3f942eab54") (:authors ("Michael Herstine" . "sp1ff@pobox.com")) (:maintainer "Michael Herstine" . "sp1ff@pobox.com") (:keywords "news") (:url . "https://github.com/sp1ff/elfeed-score"))])
+ (elfeed-summary . [(20220504 757) ((emacs (27 1)) (magit-section (3 3 0)) (elfeed (3 4 1))) "Feed summary interface for elfeed" single ((:commit . "55e2f8722bbe7b394e17563f2e13d855e77c4260") (:authors ("Korytov Pavel" . "thexcloud@gmail.com")) (:maintainer "Korytov Pavel" . "thexcloud@gmail.com") (:url . "https://github.com/SqrtMinusOne/elfeed-summary.el"))])
+ (elfeed-web . [(20210226 258) ((simple-httpd (1 5 1)) (elfeed (3 2 0)) (emacs (24 3))) "web interface to Elfeed" tar ((:commit . "162d7d545ed41c27967d108c04aa31f5a61c8e16") (:authors ("Christopher Wellons" . "wellons@nullprogram.com")) (:maintainer "Christopher Wellons" . "wellons@nullprogram.com") (:url . "https://github.com/skeeto/elfeed"))])
+ (elforth . [(20210522 928) ((emacs (26 1))) "Do you have what it takes to hack Emacs Lisp in Forth?" single ((:commit . "2d8540434a28e7edaa04a992c3c362832b2fd61e") (:authors ("Lassi Kortela" . "lassi@lassi.io")) (:maintainer "Lassi Kortela" . "lassi@lassi.io") (:keywords "games") (:url . "https://github.com/lassik/elforth"))])
+ (elgrep . [(20211221 852) ((emacs (26 2)) (async (1 5))) "Searching files for regular expressions" single ((:commit . "f8124c699b6a4abfb471269bc26afbcc8136f476") (:authors ("Tobias Zawada" . "i@tn-home.de")) (:maintainer "Tobias Zawada" . "i@tn-home.de") (:keywords "tools" "matching" "files" "unix") (:url . "https://github.com/TobiasZawada/elgrep"))])
+ (elhome . [(20161025 2042) ((initsplit (20120630))) "A framework for a \"home\" Emacs configuration" tar ((:commit . "e789e806469af3e9705f72298683c21f6c3a516d") (:authors ("Dave Abrahams" . "dave@boostpro.com")) (:maintainer "Demyan Rogozhin" . "demyan.rogozhin@gmail.com") (:keywords "lisp") (:url . "http://github.com/demyanrogozhin/elhome"))])
+ (elisp-def . [(20210126 750) ((dash (2 12 0)) (f (0 19 0)) (s (1 11 0)) (emacs (24 3))) "macro-aware go-to-definition for elisp" single ((:commit . "dfca043ec0cbead67bd9c526cb009daf771d0fa2") (:authors ("Wilfred Hughes" . "me@wilfred.me.uk")) (:maintainer "Wilfred Hughes" . "me@wilfred.me.uk") (:keywords "lisp"))])
+ (elisp-demos . [(20210312 542) ((emacs (24 4))) "Elisp API Demos" tar ((:commit . "924b07d28e4f5b82f0e1377bcde800068f0a6d9d") (:authors ("Xu Chunyang")) (:maintainer "Xu Chunyang") (:keywords "lisp" "docs") (:url . "https://github.com/xuchunyang/elisp-demos"))])
+ (elisp-depend . [(20190325 1114) nil "Parse depend libraries of elisp file." single ((:commit . "6679da9a6be5a845bb4804224c8394a9bc62168f"))])
+ (elisp-depmap . [(20220223 1131) ((emacs (26 1)) (dash (2 17 0))) "Generate an elisp dependency map in graphviz" tar ((:commit . "15909462e3f7daf445d3cecf402ee16c7e3263ed") (:authors ("Mehmet Tekman")) (:maintainer "Mehmet Tekman") (:keywords "outlines") (:url . "https://gitlab.com/mtekman/elisp-depmap.el"))])
+ (elisp-docstring-mode . [(20170304 1615) nil "Major mode for editing elisp docstrings." single ((:commit . "f512e509dd690f65133e55563ebbfd2dede5034f") (:authors ("Matúš Goljer" . "matus.goljer@gmail.com")) (:maintainer "Matúš Goljer" . "matus.goljer@gmail.com") (:keywords "languages"))])
+ (elisp-format . [(20160508 952) nil "Format elisp code" single ((:commit . "03cc293eb2f78ec58fc1d84279af06816a04b979") (:authors (nil . "Andy Stewart lazycat.manatee@gmail.com")) (:maintainer "Yuki Inoue inouetakahiroki _at_ gmail.com") (:url . "https://github.com/Yuki-Inoue/elisp-format"))])
+ (elisp-lint . [(20220419 252) ((emacs (24 4)) (dash (2 15 0)) (package-lint (0 11))) "Basic linting for Emacs Lisp" single ((:commit . "c5765abf75fd1ad22505b349ae1e6be5303426c2") (:authors ("Nikolaj Schumacher <bugs * nschum de>,")) (:maintainer "Neil Okamoto" . "neil.okamoto+melpa@gmail.com") (:keywords "lisp" "maint" "tools") (:url . "http://github.com/gonewest818/elisp-lint/"))])
+ (elisp-refs . [(20220220 2305) ((dash (2 12 0)) (s (1 11 0))) "find callers of elisp functions or macros" single ((:commit . "8f84280997d8b233d66fb9958a34b46078c58b03") (:authors ("Wilfred Hughes" . "me@wilfred.me.uk")) (:maintainer "Wilfred Hughes" . "me@wilfred.me.uk") (:keywords "lisp"))])
+ (elisp-sandbox . [(20131116 1842) nil "Evaluate EmacsLisp expressions in a sandbox" single ((:commit . "d894d68934ef09c42f72ac4e1173a0bedc23f139") (:authors ("Joel McCracken <mccracken.joel@gmail.com>, D. Goel" . "deego@gnufans.org")) (:maintainer "Joel McCracken <mccracken.joel@gmail.com>, D. Goel" . "deego@gnufans.org") (:keywords "lisp") (:url . "https://github.com/joelmccracken/elisp-sandbox"))])
+ (elisp-slime-nav . [(20210510 528) ((emacs (24 1)) (cl-lib (0 2))) "Make M-. and M-, work in elisp like they do in slime" single ((:commit . "8588d80d414aee1fafce5b9da0e913612ee0bcdd") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:keywords "languages" "navigation" "slime" "elisp" "emacs-lisp") (:url . "https://github.com/purcell/elisp-slime-nav"))])
+ (elixir-mode . [(20220314 1302) ((emacs (25))) "Major mode for editing Elixir files" tar ((:commit . "e0d0466d83ec80ddb412bb1473908a21baad1ec3") (:keywords "languages" "elixir") (:url . "https://github.com/elixir-editors/emacs-elixir"))])
+ (elixir-yasnippets . [(20150417 1239) ((yasnippet (0 8 0))) "Yasnippets for Elixir" tar ((:commit . "980ca7626c14ef0573bec0035ec7942796062783") (:authors ("Yinghai Zhao" . "zyinghai@gmail.com")) (:maintainer "Yinghai Zhao" . "zyinghai@gmail.com") (:keywords "snippets"))])
+ (ellocate . [(20200112 1931) ((emacs (25 1)) (s (1 12 0)) (f (0 20 0))) "The locate command reimplemented in Emacs Lisp" single ((:commit . "81405082f68f0577c9f176d3d4f034a7142aba59") (:authors ("Sebastian Wålinder" . "s.walinder@gmail.com")) (:maintainer "Sebastian Wålinder" . "s.walinder@gmail.com") (:keywords "matching") (:url . "https://github.com/walseb/ellocate"))])
+ (elm-mode . [(20220227 931) ((f (0 17)) (s (1 7 0)) (emacs (25 1)) (seq (2 23)) (reformatter (0 3))) "Major mode for Elm" tar ((:commit . "1e277684d8a6681a2410cce2dd589ee30a998369") (:authors ("Joseph Collard")) (:maintainer "Joseph Collard") (:url . "https://github.com/jcollard/elm-mode"))])
+ (elm-test-runner . [(20190105 1923) ((emacs (24 4))) "Enhanced support for running elm-test" single ((:commit . "a31d567a64d86d36e3675347abd696824a731e0c") (:authors ("Juan Edi")) (:maintainer "Juan Edi") (:url . "https://github.com/juanedi/elm-test-runner"))])
+ (elm-yasnippets . [(20160401 524) ((yasnippet (0 8 0))) "Yasnippets for Elm" tar ((:commit . "45a11a0cef0c36633fb3477d3dc4167e82779ba4") (:authors ("Austin Bingham" . "austin.bingham@gmail.com")) (:maintainer "Austin Bingham" . "austin.bingham@gmail.com") (:keywords "snippets"))])
+ (elmacro . [(20210716 639) ((s (1 11 0)) (dash (2 13 0))) "Convert keyboard macros to emacs lisp" single ((:commit . "d2e05012cee4f54fab6d8d8d6aced6e5eeef4f31") (:authors ("Philippe Vaucher" . "philippe.vaucher@gmail.com")) (:maintainer "Philippe Vaucher" . "philippe.vaucher@gmail.com") (:keywords "macro" "elisp" "convenience") (:url . "https://github.com/Silex/elmacro"))])
+ (elmine . [(20200520 1237) ((s (1 10 0))) "Redmine API access via elisp." single ((:commit . "c78cc8705c2dffbf649b858f02b5028225943482") (:authors ("Arthur Andersen" . "leoc.git@gmail.com")) (:maintainer "Arthur Andersen" . "leoc.git@gmail.com") (:keywords "tools") (:url . "http://github.com/leoc/elmine"))])
+ (elmpd . [(20210904 7) ((emacs (25 1))) "A tight, ergonomic, async client library for mpd" single ((:commit . "c9e413fcb6c526c86e1a64d45c7ea94aceca4e6e") (:authors ("Michael Herstine" . "sp1ff@pobox.com")) (:maintainer "Michael Herstine" . "sp1ff@pobox.com") (:keywords "comm") (:url . "https://github.com/sp1ff/elmpd"))])
+ (elnode . [(20190702 1509) ((web (0 1 4)) (dash (1 1 0)) (noflet (0 0 7)) (s (1 5 0)) (creole (0 8 14)) (fakir (0 1 6)) (db (0 0 5)) (kv (0 0 17))) "The Emacs webserver." tar ((:commit . "29ef0f51a65a24fca7fdcdb4140d2e4556e4bb29") (:authors ("Nic Ferrier" . "nferrier@ferrier.me.uk")) (:maintainer "GitHub user \"Jcaw\"") (:keywords "lisp" "http" "hypermedia"))])
+ (elog . [(20160724 2255) ((eieio (1 3))) "logging library extended from logito" single ((:commit . "a67237d9813c7591614d95e2ef31cc5e5ed3f31b") (:authors ("DarkSun" . "lujun9972@gmail.com")) (:maintainer "DarkSun" . "lujun9972@gmail.com") (:keywords "lisp" "tool" "log"))])
+ (elogcat . [(20151121 41) ((s (1 9 0)) (dash (2 10 0))) "logcat interface" single ((:commit . "4f311b7a07565b0d060334bc68edb36f2bff703f") (:authors ("Youngjoo Lee" . "youngker@gmail.com")) (:maintainer "Youngjoo Lee" . "youngker@gmail.com") (:keywords "tools"))])
+ (eloud . [(20190706 1707) ((emacs (24 4))) "A lightweight, interactive screen reader" single ((:commit . "b8f4af1f652268d73281de91fb333b5984970847") (:authors ("Patrick Smyth" . "patricksmyth01@gmail.com")) (:maintainer "Patrick Smyth" . "patricksmyth01@gmail.com") (:keywords "extensions") (:url . "https://github.com/smythp/eloud"))])
+ (elpa-audit . [(20141023 1331) nil "Handy functions for inspecting and comparing package archives" single ((:commit . "727da50e626977351aff2675b6540a36818bbbe6") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:keywords "maint") (:url . "https://github.com/purcell/elpa-audit"))])
+ (elpa-clone . [(20211205 1237) ((emacs (24 4))) "Clone ELPA archive" single ((:commit . "03d8e2af55dfb34ab9da1f9385079a995383b2ea") (:authors ("ZHANG Weiyi" . "dochang@gmail.com")) (:maintainer "ZHANG Weiyi" . "dochang@gmail.com") (:keywords "comm" "elpa" "clone" "mirror") (:url . "https://github.com/dochang/elpa-clone"))])
+ (elpa-deploy . [(20191022 718) ((emacs (24 4)) (f (0 0))) "ELPA deployment library" single ((:commit . "f5126a2da1e0e52981fad9c12028814be80328c2") (:authors ("Bruno Félix Rezende Ribeiro" . "oitofelix@gnu.org")) (:maintainer "Bruno Félix Rezende Ribeiro" . "oitofelix@gnu.org") (:keywords "tools") (:url . "https://github.com/oitofelix/elpa-deploy"))])
+ (elpa-mirror . [(20220123 1237) ((emacs (25 1))) "Create local package repository from installed packages" single ((:commit . "3e0fe0f91d1c5798752c255b89950617f88b8d9e") (:authors ("Chen Bin" . "chenbin.sh@gmail.com")) (:maintainer "Chen Bin" . "chenbin.sh@gmail.com") (:keywords "tools") (:url . "http://github.com/redguardtoo/elpa-mirror"))])
+ (elpher . [(20220503 833) ((emacs (27 1))) "A friendly gopher and gemini client" tar ((:commit . "bf0dd36eb2f5b339c6b561dbe3ee9693565b484b") (:authors ("Tim Vaughan" . "plugd@thelambdalab.xyz")) (:maintainer "Tim Vaughan" . "plugd@thelambdalab.xyz") (:keywords "comm" "gopher") (:url . "https://thelambdalab.xyz/elpher"))])
+ (elpl . [(20220314 1353) ((emacs (24 4))) "Emacs Lisp REPL" single ((:commit . "32eaec0fc7d20b8acbd4d459bfb8f8b72d75bb66") (:authors ("Gong Qijian" . "gongqijian@gmail.com")) (:maintainer "Gong Qijian" . "gongqijian@gmail.com") (:keywords "lisp" "tool") (:url . "https://github.com/twlz0ne/elpl"))])
+ (elpy . [(20220322 41) ((company (0 9 2)) (emacs (24 4)) (highlight-indentation (0 5 0)) (pyvenv (1 3)) (yasnippet (0 8 0)) (s (1 11 0))) "Emacs Python Development Environment" tar ((:commit . "1746e7009000b7635c0ea6f1559018143aa61642") (:authors ("Jorgen Schaefer <contact@jorgenschaefer.de>, Gaby Launay" . "gaby.launay@protonmail.com")) (:maintainer "Jorgen Schaefer <contact@jorgenschaefer.de>, Gaby Launay" . "gaby.launay@protonmail.com") (:keywords "python" "ide" "languages" "tools") (:url . "https://github.com/jorgenschaefer/elpy"))])
+ (elpygen . [(20171225 1736) ((emacs (25)) (yasnippet (0 8 0))) "Generate a Python function/method using a symbol under point" single ((:commit . "21929c997a05968f9eefe52b85a76ceaab3b0d81") (:authors ("Vladimir Kazanov" . "vkazanov@inbox.ru")) (:maintainer "Vladimir Kazanov" . "vkazanov@inbox.ru") (:keywords "python" "languages" "tools") (:url . "https://github.com/vkazanov/elpygen"))])
+ (elquery . [(20220331 143) ((emacs (25 1)) (dash (2 13 0))) "The HTML library for elisp" tar ((:commit . "38f3bd41096cb270919b06095da0b9ac1add4598") (:authors ("Adam Niederer")) (:maintainer "Adam Niederer") (:keywords "html" "hypermedia" "tools" "webscale") (:url . "https://github.com/AdamNiederer/elquery"))])
+ (elsa . [(20220223 2021) ((trinary (1 0 0)) (emacs (25 1)) (seq (0)) (f (0)) (dash (2 14)) (cl-lib (0 3))) "Emacs Lisp Static Analyser" tar ((:commit . "21ed4f46e2d02ffb48b3ae377b0c93732ccf3f4f") (:authors ("Matúš Goljer" . "matus.goljer@gmail.com")) (:maintainer "Matúš Goljer" . "matus.goljer@gmail.com") (:keywords "languages" "lisp"))])
+ (elscreen . [(20181009 451) ((emacs (24))) "Emacs window session manager" tar ((:commit . "cc58337faf5ba1eae7e87f75f6ff3758675688f2") (:authors ("Naoto Morishima" . "naoto@morishima.net")) (:maintainer "Akinori MUSHA" . "knu@iDaemons.org") (:keywords "window" "convenience") (:url . "https://github.com/knu/elscreen"))])
+ (elscreen-buffer-group . [(20200109 2338) ((emacs (24 4)) (elscreen (0)) (cl-lib (0 5))) "elscreen buffer group" single ((:commit . "b48e71d4782adfeb2958f227d78c04164d26e4bd") (:authors ("Jeff Gran" . "jeff@jeffgran.com") ("Author: Ryan C. Thompson")) (:maintainer "Jeff Gran" . "jeff@jeffgran.com") (:keywords "buffer") (:url . "https://github.com/jeffgran/elscreen-buffer-group"))])
+ (elscreen-fr . [(20160920 953) ((elscreen (0)) (seq (1 11))) "Use frame title as screen tab" single ((:commit . "6dc77e1d3f17b3f76da5ccf92b715572aa55fb85") (:authors ("Francesc Rocher" . "francesc.rocher@gmail.com")) (:maintainer "Francesc Rocher" . "francesc.rocher@gmail.com") (:url . "http://github.com/rocher/elscreen-fr"))])
+ (elscreen-mew . [(20160504 1835) ((elscreen (20120413 807))) "ElScreen Add-On for Mew" single ((:commit . "c90a23441d836da14a1cb12788432308ba58e2b6") (:authors ("Takashi Masuda" . "masutaka.net@gmail.com")) (:maintainer "Takashi Masuda" . "masutaka.net@gmail.com") (:url . "https://github.com/masutaka/elscreen-mew"))])
+ (elscreen-multi-term . [(20200417 821) ((emacs (24 4)) (elscreen (1 4 6)) (multi-term (1 3))) "Multi term for elscreen" single ((:commit . "4ea89bae0444d9d4377515929f76cb3e98140f1f") (:authors ("wamei" . "wamei.cho@gmail.com")) (:maintainer "wamei" . "wamei.cho@gmail.com") (:keywords "elscreen" "multi term"))])
+ (elscreen-separate-buffer-list . [(20200807 1324) ((emacs (24 4)) (elscreen (1 4 6))) "Separate buffer list manager for elscreen" single ((:commit . "88d8850108947949431425a2d938a09d941454e8") (:authors ("wamei" . "wamei.cho@gmail.com")) (:maintainer "wamei" . "wamei.cho@gmail.com") (:keywords "elscreen"))])
+ (elscreen-tab . [(20201229 1428) ((emacs (26)) (elscreen (20180321)) (dash (2 14 1))) "minor mode to display tabs of elscreen in a dedicated buffer" tar ((:commit . "5d7a740e47a56365413d75f4f0553de74f5ca198") (:authors ("Aki Syunsuke" . "sunny.day.dev@gmail.com")) (:maintainer "Aki Syunsuke" . "sunny.day.dev@gmail.com") (:keywords "tools" "extensions") (:url . "https://github.com/aki-s/elscreen-tab"))])
+ (elvish-mode . [(20180809 1612) ((emacs (24 3))) "Defines a major mode for Elvish" single ((:commit . "a13fcaf209d803e2e450ca2bf80dea94b40a0141") (:authors ("Adam Schwalm" . "adamschwalm@gmail.com")) (:maintainer "Adam Schwalm" . "adamschwalm@gmail.com") (:url . "https://github.com/ALSchwalm/elvish-mode"))])
+ (elwm . [(20150817 1007) ((dash (1 1 0))) "Minimalistic window manager for emacs" single ((:commit . "c33b183f006ad476c3a44dab316f580f8b369930") (:authors ("Matus Goljer" . "matus.goljer@gmail.com")) (:maintainer "Matus Goljer" . "matus.goljer@gmail.com") (:keywords "docs") (:url . "https://github.com/Fuco1/elwm"))])
+ (elx . [(20220331 2252) ((emacs (25 1))) "extract information from Emacs Lisp libraries" single ((:commit . "ea0b10340b22e8dd0454fe37ba84ff2157fada4f") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:keywords "docs" "libraries" "packages") (:url . "https://github.com/emacscollective/elx"))])
+ (emacs-everywhere . [(20220407 329) ((emacs (26 3))) "System-wide popup windows for quick edits" single ((:commit . "54b9ba1ac0d7f8b644354fd6d27c9e3aff111dcc") (:authors ("TEC <https://github.com/tecosaur>")) (:maintainer "TEC" . "tec@tecosaur.com") (:keywords "conenience" "frames") (:url . "https://github.com/tecosaur/emacs-everywhere"))])
+ (emacsc . [(20220420 1042) nil "helper for emacsc(1)" tar ((:commit . "199c08147ebe98da1004c478c92ba8866950b637") (:authors ("Akinori MUSHA" . "knu@iDaemons.org")) (:maintainer "Akinori MUSHA" . "knu@iDaemons.org") (:keywords "tools") (:url . "https://github.com/knu/emacsc"))])
+ (emacsist-view . [(20160426 1223) nil "Mode for viewing emacsist.com" single ((:commit . "f67761259ed779a9bc95c9a4e0474522990c5c6b") (:authors ("DarkSun" . "lujun9972@gmail.com")) (:maintainer "DarkSun" . "lujun9972@gmail.com") (:keywords "convenience" "usability") (:url . "https://github.com/lujun9972/emacsist-view"))])
+ (emacsql . [(20220408 1614) ((emacs (25 1))) "high-level SQL database front-end" tar ((:commit . "373975cbccf7776af771e23f86043b236a330702") (:authors ("Christopher Wellons" . "wellons@nullprogram.com")) (:maintainer "Christopher Wellons" . "wellons@nullprogram.com") (:url . "https://github.com/skeeto/emacsql"))])
+ (emacsql-mysql . [(20171219 227) ((emacs (25 1)) (emacsql (2 0 0))) "EmacSQL back-end for MySQL" single ((:commit . "373975cbccf7776af771e23f86043b236a330702") (:authors ("Christopher Wellons" . "wellons@nullprogram.com")) (:maintainer "Christopher Wellons" . "wellons@nullprogram.com") (:url . "https://github.com/skeeto/emacsql"))])
+ (emacsql-psql . [(20220101 1820) ((emacs (25 1)) (emacsql (2 0 0))) "EmacSQL back-end for PostgreSQL via psql" tar ((:commit . "373975cbccf7776af771e23f86043b236a330702") (:authors ("Christopher Wellons" . "wellons@nullprogram.com")) (:maintainer "Christopher Wellons" . "wellons@nullprogram.com") (:url . "https://github.com/skeeto/emacsql"))])
+ (emacsql-sqlite . [(20220218 1543) ((emacs (25 1)) (emacsql (2 0 0))) "EmacSQL back-end for SQLite" tar ((:commit . "373975cbccf7776af771e23f86043b236a330702") (:authors ("Christopher Wellons" . "wellons@nullprogram.com")) (:maintainer "Christopher Wellons" . "wellons@nullprogram.com") (:url . "https://github.com/skeeto/emacsql"))])
+ (emacsql-sqlite-builtin . [(20220422 1605) ((emacs (29)) (emacsql (3 0 0)) (emacsql-sqlite (3 0 0))) "EmacSQL back-end for SQLite using builtin support" single ((:commit . "5501f7b7577dc8aa968c0d2183d081f334ad051a") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:keywords "data") (:url . "https://github.com/emacscollective/emacsql-sqlite-builtin"))])
+ (emacsql-sqlite-module . [(20220422 1605) ((emacs (25)) (emacsql (3 0 0)) (emacsql-sqlite (3 0 0)) (sqlite3 (0 15))) "EmacSQL back-end for SQLite using a module" single ((:commit . "5501f7b7577dc8aa968c0d2183d081f334ad051a") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:keywords "data") (:url . "https://github.com/emacscollective/emacsql-sqlite-builtin"))])
+ (emacsql-sqlite3 . [(20220304 1014) ((emacs (26 1)) (emacsql (3 0 0))) "Yet another EmacSQL backend for SQLite" single ((:commit . "2113618732665f2112cb932a66c0e89c404d8777") (:authors ("Zhu Zihao" . "all_but_last@163.com")) (:maintainer "Zhu Zihao" . "all_but_last@163.com") (:keywords "extensions") (:url . "https://github.com/cireu/emacsql-sqlite3"))])
+ (emacsshot . [(20191206 944) ((emacs (24 4))) "Snapshot a frame or window from within" tar ((:commit . "fe958b11056f3c671ebdd604d5aa574323284ca5") (:authors ("Marco Wahl" . "marcowahlsoft@gmail.com")) (:maintainer "Marco Wahl") (:keywords "convenience") (:url . "https://gitlab.com/marcowahl/emacsshot"))])
+ (emamux . [(20200315 1220) ((emacs (24 3))) "Interact with tmux" single ((:commit . "6172131d78038f0b1490e24bac60534bf4ad3b30") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-emamux"))])
+ (emamux-ruby-test . [(20130812 1639) ((emamux (0 1)) (projectile (0 9 1))) "Ruby test with emamux" single ((:commit . "23b73c650573b340351a919da3da416acfc2ac84") (:url . "https://github.com/syohex/emamux-ruby-test"))])
+ (emaps . [(20200508 1759) ((dash (2 17 0)) (emacs (24))) "Utilities for working with keymaps" single ((:commit . "7c561f3ded2015ed3774e5784059d6601082743e") (:authors ("Ben Moon" . "software@guiltydolphin.com")) (:maintainer "Ben Moon" . "software@guiltydolphin.com") (:keywords "convenience" "keyboard" "keymap" "utility") (:url . "https://github.com/GuiltyDolphin/emaps"))])
+ (embark . [(20220505 615) ((emacs (26 1))) "Conveniently act on minibuffer completions" tar ((:commit . "80ff7d105afc090817c4162ec021758e586272f2") (:authors ("Omar Antolín Camarena" . "omar@matem.unam.mx")) (:maintainer "Omar Antolín Camarena" . "omar@matem.unam.mx") (:keywords "convenience") (:url . "https://github.com/oantolin/embark"))])
+ (embark-consult . [(20220503 1817) ((emacs (27 1)) (embark (0 12)) (consult (0 10))) "Consult integration for Embark" single ((:commit . "80ff7d105afc090817c4162ec021758e586272f2") (:authors ("Omar Antolín Camarena" . "omar@matem.unam.mx")) (:maintainer "Omar Antolín Camarena" . "omar@matem.unam.mx") (:keywords "convenience") (:url . "https://github.com/oantolin/embark"))])
+ (ember-mode . [(20200208 1423) ((cl-lib (0 5))) "Ember navigation mode for emacs" single ((:commit . "a587c423041b2fcb065fd5b6a03b2899b764e462") (:authors ("Aad Versteden" . "madnificent@gmail.com")) (:maintainer "Aad Versteden" . "madnificent@gmail.com") (:keywords "ember" "ember.js" "emberjs"))])
+ (ember-yasnippets . [(20160526 1658) ((yasnippet (0 8 0))) "Snippets for Ember.js development" tar ((:commit . "3b5bd01569646237bf1b540d097e12f9118b67f4") (:authors ("Ron White" . "ronco@costite.com")) (:maintainer "Ron White" . "ronco@costite.com") (:keywords "tools" "abbrev" "languages"))])
+ (embrace . [(20171031 1833) ((cl-lib (0 5)) (expand-region (0 10 0))) "Add/Change/Delete pairs based on `expand-region'" single ((:commit . "dd5da196e5bcc5e6d87e1937eca0c21da4334ef2") (:authors ("Junpeng Qiu" . "qjpchmail@gmail.com")) (:maintainer "Junpeng Qiu" . "qjpchmail@gmail.com") (:keywords "extensions"))])
+ (emidje . [(20190209 1726) ((emacs (25)) (cider (0 17 0)) (seq (2 16)) (magit-popup (2 4 0))) "Test runner and report viewer for Midje" single ((:commit . "7e92f053964d925c97dc8cca8d4d70a3030021db") (:authors ("Alan Ghelardi" . "alan.ghelardi@nubank.com.br")) (:maintainer "Alan Ghelardi" . "alan.ghelardi@nubank.com.br") (:keywords "tools") (:url . "https://github.com/nubank/emidje"))])
+ (emmet-mode . [(20210820 1124) nil "Unofficial Emmet's support for emacs" single ((:commit . "6b2e554f7fd27f732810f4b14ea01e3c54b7b3da") (:authors ("Shin Aoyama" . "smihica@gmail.com")) (:maintainer "Shin Aoyama" . "smihica@gmail.com") (:keywords "convenience") (:url . "https://github.com/smihica/emmet-mode"))])
+ (emms . [(20220422 1318) ((cl-lib (0 5)) (nadvice (0 3)) (seq (0))) "The Emacs Multimedia System" tar ((:commit . "22f3d9e5359c565b33f55715f90fbde35e4f675e") (:authors ("Jorgen Schäfer" . "forcer@forcix.cx")) (:maintainer "Yoni Rabkin" . "yrk@gnu.org") (:keywords "emms" "mp3" "ogg" "flac" "music" "mpeg" "video" "multimedia") (:url . "https://www.gnu.org/software/emms/"))])
+ (emms-bilibili . [(20180103 418) ((emacs (25)) (cl-lib (0 5))) "Play Bilibili in EMMS." single ((:commit . "294bca3dfc42fe3a55fb326ab39bc0fcfc8c5090") (:keywords "emms" "bilibili") (:url . "https://github.com/stardiviner/emms-bilibili"))])
+ (emms-info-mediainfo . [(20131223 1300) ((emms (0))) "Info-method for EMMS using medianfo" single ((:commit . "bce16eae9eacd38719fea62a9755225a888da59d") (:authors ("Fabián Ezequiel Gallina" . "fgallina@gnu.org")) (:maintainer "Fabián Ezequiel Gallina" . "fgallina@gnu.org") (:keywords "multimedia" "processes"))])
+ (emms-mark-ext . [(20130529 327) ((emms (3 0))) "Extra functions for emms-mark-mode and emms-tag-edit-mode" single ((:commit . "ec68129e3e9e469e5bf160c6a1b7030e322f3541") (:authors ("Joe Bloggs" . "vapniks@yahoo.com")) (:maintainer "Joe Bloggs" . "vapniks@yahoo.com") (:keywords "convenience" "multimedia") (:url . "https://github.com/vapniks/emms-mark-ext"))])
+ (emms-mode-line-cycle . [(20160221 1120) ((emacs (24)) (emms (4 0))) "Display the emms mode line as a ticker" single ((:commit . "2c2f395e484a1d345050ddd61ff5fab71a92a6bc") (:authors ("momomo5717")) (:maintainer "momomo5717") (:keywords "emms" "mode-line") (:url . "https://github.com/momomo5717/emms-mode-line-cycle"))])
+ (emms-player-mpv-jp-radios . [(20180325 1117) ((emacs (24)) (cl-lib (0 5)) (emms (4 0)) (emms-player-simple-mpv (0 1 7))) "EMMS players and stream lists of Japan radio stations" tar ((:commit . "f6b37f5878c741124d5fca43c5b80af873541edd") (:keywords "emms" "mpv" "radio") (:url . "https://github.com/momomo5717/emms-player-mpv-jp-radios"))])
+ (emms-player-simple-mpv . [(20180316 1549) ((emacs (24)) (cl-lib (0 5)) (emms (4 0))) "An extension of emms-player-simple.el for mpv JSON IPC" tar ((:commit . "101d120ccdee1c2c213fd2f0423c858b21649c00") (:authors ("momomo5717")) (:maintainer "momomo5717") (:keywords "emms" "mpv") (:url . "https://github.com/momomo5717/emms-player-simple-mpv"))])
+ (emms-soundcloud . [(20131221 1145) ((emms (20131016)) (json (1 2))) "EMMS source for Soundcloud audio sharing platform" single ((:commit . "87e5cbf9609d1f26c24dc834fdeb78b33d453c2b") (:authors ("Ozan Sener" . "ozan@ozansener.com")) (:maintainer "Ozan Sener" . "ozan@ozansener.com") (:keywords "emms" "soundcloud") (:url . "http://github.com/osener/emms-soundcloud"))])
+ (emms-state . [(20211023 1942) ((emms (0))) "Display track description and playing time in the mode line" single ((:commit . "cdb3ee85369758727b3c082e4ade1ae2b559b334") (:authors ("Alex Kost" . "alezost@gmail.com")) (:maintainer "Alex Kost" . "alezost@gmail.com") (:keywords "emms") (:url . "https://github.com/alezost/emms-state.el"))])
+ (emoji-cheat-sheet-plus . [(20200202 1404) ((emacs (24)) (helm (1 6 4))) "emoji-cheat-sheet for emacs" tar ((:commit . "ffcc84d7060dfa000148e7f8be4fd6701593a74f") (:authors ("Sylvain Benner (based on the work of Shingo Fukuyama)")) (:maintainer "Sylvain Benner (based on the work of Shingo Fukuyama)") (:keywords "emacs" "emoji") (:url . "https://github.com/syl20bnr/emacs-emoji-cheat-sheet-plus"))])
+ (emoji-display . [(20140117 1013) nil "emoji displaying module" single ((:commit . "bb4217f6400151a9cfa6d4524b8427f01feb5193") (:authors ("Kazuhiro Ito" . "kzhr@d1.dion.ne.jp")) (:maintainer "Kazuhiro Ito" . "kzhr@d1.dion.ne.jp") (:keywords "emoji") (:url . "https://github.com/ikazuhiro/emoji-display"))])
+ (emoji-fontset . [(20160726 1924) nil "Set font face for Emoji." single ((:commit . "8f159e8073b9b57a07a54b549df687424eeb98ee") (:authors ("USAMI Kenta" . "tadsan@zonu.me")) (:maintainer "USAMI Kenta" . "tadsan@zonu.me") (:keywords "emoji" "font" "config"))])
+ (emoji-github . [(20200825 425) ((emacs (24 4)) (emojify (1 0)) (request (0 3 0))) "Display list of GitHub's emoji. (cheat sheet)" single ((:commit . "434ccc9df8eb884f248d5934e7d465348bb203a4") (:authors ("Shen, Jen-Chieh" . "jcs090218@gmail.com")) (:maintainer "Shen, Jen-Chieh" . "jcs090218@gmail.com") (:url . "https://github.com/jcs-elpa/emoji-github"))])
+ (emoji-recall . [(20160723 2208) ((emacs (24))) "How many emoji can you recall from memory?" tar ((:commit . "d9122f8fb1467309260109a1985cd14f18fdf631") (:authors ("DarkSun" . "lujun9972@gmail.com")) (:maintainer "DarkSun" . "lujun9972@gmail.com") (:keywords "game") (:url . "https://github.com/lujun9972/emoji-recall.el"))])
+ (emojify . [(20210108 1111) ((seq (1 11)) (ht (2 0)) (emacs (24 3))) "Display emojis in Emacs" tar ((:commit . "1b726412f19896abf5e4857d4c32220e33400b55") (:authors ("Iqbal Ansari" . "iqbalansari02@yahoo.com")) (:maintainer "Iqbal Ansari" . "iqbalansari02@yahoo.com") (:keywords "multimedia" "convenience") (:url . "https://github.com/iqbalansari/emacs-emojify"))])
+ (emojify-logos . [(20180814 917) ((emojify (0 4))) "Add logos to emojify" tar ((:commit . "a3e78bcbdf863092d4c9b026ac08bf7d1c7c0e8b") (:authors ("mxgoldstein" . "m_goldstein@gmx.net")) (:maintainer "mxgoldstein" . "m_goldstein@gmx.net") (:url . "https://github.com/mxgoldstein/emojify-logos"))])
+ (empos . [(20151011 1916) nil "Locate bibtex citations from within emacs" single ((:commit . "7b99ad30e56937adb7e6349777e5a2045597d564") (:authors ("Dimitris Alikaniotis <da352 [at] cam.ac.uk>")) (:maintainer "Dimitris Alikaniotis <da352 [at] cam.ac.uk>") (:keywords "citations" "reference" "bibtex" "reftex") (:url . "http://github.com/dimalik/empos/"))])
+ (emr . [(20220108 548) ((s (1 3 1)) (dash (1 2 0)) (cl-lib (0 2)) (popup (0 5 0)) (emacs (24 1)) (list-utils (0 3 0)) (paredit (24 0 0)) (projectile (0 9 1)) (clang-format (0 0 1)) (iedit (0 97))) "Emacs refactoring system." tar ((:commit . "cac1b52932926f56d7f6d2923732d20bbd20670d") (:authors ("Chris Barrett" . "chris.d.barrett@me.com")) (:maintainer "Chris Barrett" . "chris.d.barrett@me.com") (:keywords "tools" "convenience" "refactoring") (:url . "https://github.com/Wilfred/emacs-refactor"))])
+ (enclose . [(20121008 1614) nil "Enclose cursor within punctuation pairs." tar ((:commit . "2747653e84af39017f503064bc66ed1812a77259") (:authors ("Johan Andersson" . "johan.rejeep@gmail.com")) (:maintainer "Johan Andersson" . "johan.rejeep@gmail.com") (:keywords "speed" "convenience") (:url . "http://github.com/rejeep/enclose"))])
+ (encourage-mode . [(20151128 905) ((emacs (24 4))) "Encourages you in your work. :D" single ((:commit . "99edacf2d94d168d3da0609860dc7253db7c9815") (:authors ("Patrick Mosby" . "patrick@schreiblogade.de")) (:maintainer "Patrick Mosby" . "patrick@schreiblogade.de") (:keywords "fun") (:url . "https://github.com/halbtuerke/encourage-mode.el"))])
+ (engine-mode . [(20200611 1825) ((cl-lib (0 5))) "Define and query search engines from within Emacs." single ((:commit . "e0910f141f2d37c28936c51c3c8bb8a9ca0c01d1") (:authors ("Harry R. Schwartz" . "hello@harryrschwartz.com")) (:maintainer "Harry R. Schwartz" . "hello@harryrschwartz.com") (:url . "https://github.com/hrs/engine-mode"))])
+ (enh-ruby-mode . [(20220426 1750) ((emacs (24 3))) "Major mode for editing Ruby files" tar ((:commit . "f240ac00ccbbd0916b5e3d272c0064a26f527ef8") (:authors ("Geoff Jacobsen")) (:maintainer "Ryan Davis") (:keywords "languages" "elisp" "ruby") (:url . "http://github.com/zenspider/Enhanced-Ruby-Mode"))])
+ (enlightened-theme . [(20210220 2327) nil "A theme based on enlightened" single ((:commit . "1bfebd8f47e8a8357c9e557cf6e95d7027861e6d") (:url . "https://hg.sr.ht/~slondr/enlightened"))])
+ (enlive . [(20170725 1417) nil "query html document with css selectors" single ((:commit . "604a8ca272b6889f114e2b5a13adb5b1dc4bae86") (:authors ("ZHOU Feng" . "zf.pascal@gmail.com")) (:maintainer "ZHOU Feng" . "zf.pascal@gmail.com") (:keywords "css" "selector" "query") (:url . "http://github.com/zweifisch/enlive"))])
+ (eno . [(20191013 1239) ((dash (2 12 1)) (edit-at-point (1 0))) "Goto/copy/cut any word/symbol/line in view, similar to ace-jump/easymotion" single ((:commit . "c5c6193687c0bede1ddf507c430cf8b0a6d272d9") (:authors (nil . "<e.enoson@gmail.com>")) (:maintainer nil . "<e.enoson@gmail.com>") (:url . "http://github.com/enoson/eno.el"))])
+ (enotify . [(20130407 1348) nil "A networked notification system for emacs" tar ((:commit . "7fd2f48ef4ff32c8f013c634ea2dd6b1d1409f80") (:authors ("Alessandro Piras" . "laynor@gmail.com")) (:maintainer "Alessandro Piras" . "laynor@gmail.com") (:keywords "tools"))])
+ (envrc . [(20220218 1627) ((seq (2)) (emacs (24 4)) (inheritenv (0 1))) "Support for `direnv' that operates buffer-locally" single ((:commit . "4730b31ff1479b6d822ccc7517251dcb52de45b3") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:keywords "processes" "tools") (:url . "https://github.com/purcell/envrc"))])
+ (eopengrok . [(20200205 624) ((s (1 9 0)) (dash (2 10 0)) (magit (2 1 0)) (cl-lib (0 5))) "opengrok interface for emacs" single ((:commit . "6fa16c4ccaaebaef64dca0d3d29904c45fd6597d") (:authors ("Youngjoo Lee" . "youngker@gmail.com")) (:maintainer "Youngjoo Lee" . "youngker@gmail.com") (:keywords "tools"))])
+ (epc . [(20140610 534) ((concurrent (0 3 1)) (ctable (0 1 2))) "A RPC stack for the Emacs Lisp" tar ((:commit . "e1bfa5ca163273859336e3cc89b4b6460f7f8cda") (:authors ("SAKURAI Masashi <m.sakurai at kiwanami.net>")) (:maintainer "SAKURAI Masashi <m.sakurai at kiwanami.net>") (:keywords "lisp" "rpc") (:url . "https://github.com/kiwanami/emacs-epc"))])
+ (epic . [(20170210 23) ((htmlize (1 47))) "Evernote Picker for Cocoa Emacs" single ((:commit . "a41826c330eb0ea061d58a08cc861b0c4ac8ec4e") (:authors ("Yoshinari Nomura" . "nom@quickhack.net")) (:maintainer "Yoshinari Nomura" . "nom@quickhack.net") (:keywords "evernote" "applescript") (:url . "https://github.com/yoshinari-nomura/epic"))])
+ (eping . [(20201027 2149) ((emacs (25 1))) "Ping websites to check internet connectivity" tar ((:commit . "99d3a4b6973d5b09864e0af7425a61f99c19b90a") (:authors ("Sean Hutchings" . "seanhut@yandex.com")) (:maintainer "Sean Hutchings" . "seanhut@yandex.com") (:keywords "comm" "processes" "terminals" "unix") (:url . "https://github.com/sean-hut/eping"))])
+ (epkg . [(20220503 1115) ((emacs (25 1)) (compat (28 1 1 0)) (closql (20210927))) "Browse the Emacsmirror package database" tar ((:commit . "384222d9396f14e6b36a8d67abe6b3ede7418f0b") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:keywords "tools") (:url . "https://github.com/emacscollective/epkg"))])
+ (epkg-marginalia . [(20220424 2211) ((emacs (26)) (compat (28 1 1 0)) (epkg (3 3 1)) (marginalia (0 12))) "Show Epkg information in completion annotations" single ((:commit . "73519c62db12c17804bfbcdfb0a6028389374bec") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:keywords "tools") (:url . "https://github.com/emacscollective/epkg-marginalia"))])
+ (epl . [(20180205 2049) ((cl-lib (0 3))) "Emacs Package Library" single ((:commit . "78ab7a85c08222cd15582a298a364774e3282ce6") (:authors ("Sebastian Wiesner" . "swiesner@lunaryorn.com")) (:maintainer "Johan Andersson" . "johan.rejeep@gmail.com") (:keywords "convenience") (:url . "http://github.com/cask/epl"))])
+ (epm . [(20190509 443) ((emacs (24 3)) (epl (0 8))) "Emacs Package Manager" tar ((:commit . "6375ddbf93c5f25647f6ebb25b54045b3c93a5be") (:authors ("Chunyang Xu" . "xuchunyang.me@gmail.com")) (:maintainer "Chunyang Xu" . "xuchunyang.me@gmail.com") (:url . "https://github.com/xuchunyang/epm"))])
+ (epresent . [(20160411 201) ((org (8)) (cl-lib (0 5))) "Simple presentation mode for Emacs Org-mode" single ((:commit . "6c8abedcf46ff08091fa2bba52eb905c6290057d") (:keywords "gui") (:url . "https://github.com/dakrone/epresent"))])
+ (eproject . [(20180312 1642) ((helm (1 6 4))) "assign files to projects, programatically" tar ((:commit . "068218d2cf2138cb2e8fc29b57e773a0097a7e8b") (:authors ("Jonathan Rockway" . "jon@jrock.us")) (:maintainer "Jonathan Rockway" . "jon@jrock.us") (:keywords "programming" "projects"))])
+ (equake . [(20220424 350) ((emacs (26 1)) (dash (2 14 1))) "Drop-down console for (e)shell & terminal emulation" single ((:commit . "ea5c0570f58b8e62249e001ed434a1056a50abe7") (:authors ("Benjamin Slade" . "slade@lambda-y.net")) (:maintainer "Benjamin Slade" . "slade@lambda-y.net") (:keywords "convenience" "frames" "terminals" "tools" "window-system") (:url . "https://gitlab.com/emacsomancer/equake"))])
+ (eradio . [(20210327 1000) ((emacs (24 1))) "A simple Internet radio player" single ((:commit . "47769986c79def84307921f0277e9bb2714756c2") (:authors ("Olav Fosse" . "mail@olavfosse.no")) (:maintainer "Olav Fosse" . "mail@olavfosse.no") (:url . "https://github.com/fossegrim/eradio"))])
+ (erblint . [(20200622 5) ((emacs (24))) "An interface for checking HTML ERB files using Erblint" single ((:commit . "89af42f776d8dc656104322edaace2ede7499932") (:authors ("Leonardo Santos")) (:maintainer "Leonardo Santos") (:keywords "project" "convenience") (:url . "https://github.com/leodcs/erblint-emacs"))])
+ (erc-colorize . [(20170107 1339) nil "Per user colorization of whole message" single ((:commit . "d026a016dcb9d63d9ac66d30627a92a8f1681bbd") (:authors ("Sylvain Rousseau <thisirs at gmail dot com>")) (:maintainer "Sylvain Rousseau <thisirs at gmail dot com>") (:keywords "erc" "convenience") (:url . "https://github.com/thisirs/erc-colorize.git"))])
+ (erc-crypt . [(20200516 2054) ((cl-lib (0 5))) "Symmetric Encryption for ERC" single ((:commit . "be87248435509f83c56a7f08ac9bcbbd3b20d780") (:authors ("xristos" . "xristos@sdf.org")) (:maintainer "xristos" . "xristos@sdf.org") (:keywords "comm") (:url . "https://github.com/atomontage/erc-crypt"))])
+ (erc-hl-nicks . [(20200317 16) nil "ERC nick highlighter that ignores uniquifying chars when colorizing" single ((:commit . "a67fe361c8f2aa20fc235447fbb898f424b51439") (:authors ("David Leatherman" . "leathekd@gmail.com")) (:maintainer "David Leatherman" . "leathekd@gmail.com") (:url . "http://www.github.com/leathekd/erc-hl-nicks"))])
+ (erc-image . [(20210604 753) nil "Show received image urls in the ERC buffer" single ((:commit . "883084f0801d46a5ccf183e51ae9a734755bbb97") (:authors ("Jon de Andrés Frías" . "jondeandres@gmail.com") ("Raimon Grau Cuscó" . "raimonster@gmail.com")) (:maintainer "Jon de Andrés Frías" . "jondeandres@gmail.com") (:keywords "multimedia"))])
+ (erc-matterircd . [(20210804 504) ((emacs (27 1))) "Integrate matterircd with ERC" single ((:commit . "e3a59267c044474f9ca066d36517e9a3d872759c") (:authors ("Alex Murray" . "murray.alex@gmail.com")) (:maintainer "Alex Murray" . "murray.alex@gmail.com") (:url . "https://github.com/alexmurray/erc-matterircd"))])
+ (erc-scrolltoplace . [(20180608 606) ((emacs (24 0)) (switch-buffer-functions (0 0 1))) "An Erc module to scrolltobottom better with keep-place" single ((:commit . "38cfd0c2e2f5f6533b217189c3afaf6640b5602e") (:authors ("Jay Kamat" . "jaygkamat@gmail.com")) (:maintainer "Jay Kamat" . "jaygkamat@gmail.com") (:keywords "erc" "module" "comm" "scrolltobottom" "keep-place") (:url . "http://gitlab.com/jgkamat/erc-scrolltoplace"))])
+ (erc-social-graph . [(20150508 1204) nil "A social network graph module for ERC." single ((:commit . "e6ef3416a1c5064054bf054d9f0c1c7bf54a9cd0") (:authors ("Vibhav Pant" . "vibhavp@gmail.com")) (:maintainer "Vibhav Pant" . "vibhavp@gmail.com") (:keywords "erc" "graph") (:url . "https://github.com/vibhavp/erc-social-graph"))])
+ (erc-terminal-notifier . [(20140115 1024) nil "OSX notifications via the terminal-notifier gem for Emacs ERC." single ((:commit . "a3dacb935845e4a20031212bbd82b2170f68d2a8") (:authors ("Julien Blanchard" . "julien@sideburns.eu")) (:maintainer "Julien Blanchard" . "julien@sideburns.eu") (:keywords "erc" "terminal-notifier" "nick") (:url . "http://github.com/julienXX/"))])
+ (erc-track-score . [(20130328 1215) nil "Add score support to tracked channel buffers" single ((:commit . "5b27531ea6b1a4c4b703b270dfa9128cb5bfdaa3") (:authors ("Julien Danjou" . "julien@danjou.info")) (:maintainer "Julien Danjou" . "julien@danjou.info") (:url . "http://julien.danjou.info/erc-track-score.html"))])
+ (erc-tweet . [(20150920 1258) nil "shows text of a tweet when an url is posted in erc buffers" single ((:commit . "91fed61e139fa788d66a7358f0d50acc896414b8") (:authors ("Raimon Grau" . "raimonster@gmail.com")) (:maintainer "Raimon Grau" . "raimonster@gmail.com") (:keywords "extensions"))])
+ (erc-twitch . [(20170427 606) ((json (1 3)) (erc (5 0))) "Support for Twitch emotes for ERC." single ((:commit . "53c6af0cb72e56d897d30a40e7e5066668d6b5ec") (:authors ("Vibhav Pant" . "vibhavp@gmail.com")) (:maintainer "Vibhav Pant" . "vibhavp@gmail.com") (:keywords "twitch" "erc" "emotes") (:url . "https://github.com/vibhavp/erc-twitch"))])
+ (erc-view-log . [(20140227 2039) nil "Major mode for viewing ERC logs" single ((:commit . "c5a25f0cbca84ed2e4f72068c02b66bd0ea3b266") (:authors ("Antoine Levitt") ("Thomas Riccardi" . "riccardi.thomas@gmail.com")) (:maintainer "Antoine Levitt") (:keywords "erc" "viewer" "logs" "colors") (:url . "http://github.com/Niluge-KiWi/erc-view-log/raw/master/erc-view-log.el"))])
+ (erc-yank . [(20210220 1815) nil "Automagically create a Gist if pasting more than 5 lines" single ((:commit . "55d96f18c5df9d8fce51fa073d7a12c47a46ac80") (:authors ("John Wiegley" . "jwiegley@gmail.com")) (:maintainer "John Wiegley" . "jwiegley@gmail.com") (:keywords "comm" "erc" "chat" "irc" "yank" "gist") (:url . "https://github.com/jwiegley/erc-yank"))])
+ (erc-youtube . [(20150603 2136) nil "Show info about a YouTube URL in an ERC buffer." single ((:commit . "97054ba8475b442e2aa81e5a291f668b7f28697f") (:authors ("Raimon Grau Cuscó" . "raimonster@gmail.com")) (:maintainer "Raimon Grau Cuscó" . "raimonster@gmail.com") (:keywords "multimedia"))])
+ (erc-yt . [(20150426 1249) ((dash (2 10 0))) "An erc module to display youtube links nicely" single ((:commit . "43e7d49325b17a3217a6ffb4a9daf75c5ff4e6f8") (:authors ("William Stevenson" . "yhvh2000@gmail.com")) (:maintainer "William Stevenson" . "yhvh2000@gmail.com") (:keywords "multimedia"))])
+ (ercn . [(20150523 1503) nil "Flexible ERC notifications" single ((:commit . "79a4df5609046ae2e2e3375998287be6dda80615") (:authors ("David Leatherman" . "leathekd@gmail.com")) (:maintainer "David Leatherman" . "leathekd@gmail.com") (:url . "http://www.github.com/leathekd/ercn"))])
+ (ereader . [(20170810 501) ((emacs (24 4)) (dash (2 12 1)) (s (1 10 0)) (xml+ (0 0 0))) "Major mode for reading ebooks with org-mode integration" tar ((:commit . "f3bbd3f13195f8fba3e3c880aab0e4c60430dcf3") (:authors ("Ben Dean" . "bendean837@gmail.com")) (:maintainer "Ben Dean" . "bendean837@gmail.com") (:keywords "epub" "ebook") (:url . "https://github.com/bddean/emacs-ereader"))])
+ (eredis . [(20181119 131) ((dash (0))) "eredis, a Redis client in emacs lisp" single ((:commit . "bc86b9f63a3e7a5eb263875030d0e15d6f5f6e37") (:authors ("Justin Heyes-Jones" . "justinhj@gmail.com")) (:maintainer "Justin Heyes-Jones" . "justinhj@gmail.com") (:keywords "redis" "api" "tools" "org") (:url . "http://github.com/justinhj/eredis/"))])
+ (erefactor . [(20200513 1252) ((cl-lib (0 3))) "Emacs-Lisp refactoring utilities" single ((:commit . "bfe27a1b8c7cac0fe054e76113e941efa3775fe8") (:authors ("Masahiro Hayashi" . "mhayashi1120@gmail.com")) (:maintainer "Masahiro Hayashi" . "mhayashi1120@gmail.com") (:keywords "extensions" "tools" "maint") (:url . "https://github.com/mhayashi1120/Emacs-erefactor"))])
+ (ergoemacs-mode . [(20220411 338) ((emacs (24 1)) (cl-lib (0 5))) "Emacs mode based on common modern interface and ergonomics." tar ((:commit . "9cd89eef490f6c9f4af273bb3dd2c68d5ed2de61") (:authors ("Xah Lee" . "xah@xahlee.org") ("David Capello" . "davidcapello@gmail.com") ("Matthew L. Fidler" . "matthew.fidler@gmail.com") ("Kim F. Storm" . "storm@cua.dk")) (:maintainer "Matthew L. Fidler" . "matthew.fidler@gmail.com") (:keywords "convenience") (:url . "https://github.com/ergoemacs/ergoemacs-mode"))])
+ (ergoemacs-status . [(20160318 538) ((powerline (2 3)) (mode-icons (0 1 0))) "Adaptive Status Bar / Mode Line" single ((:commit . "d952cc2361adf6eb4d6af60950ad4ab699c81320") (:authors ("Matthew Fidler")) (:maintainer "Matthew Fidler"))])
+ (eri . [(20200914 644) nil "Enhanced relative indentation (eri)" single ((:commit . "7d53667ebfb306732ee9461b150f09ffba6af474") (:url . "https://github.com/agda/agda"))])
+ (erlang . [(20220215 1844) ((emacs (24 1))) "Erlang major mode" tar ((:commit . "48eb132a874816d50e75a6b6f0f5ba29de6ef35d") (:authors ("Anders Lindgren")) (:maintainer "Anders Lindgren") (:keywords "erlang" "languages" "processes"))])
+ (erlstack-mode . [(20210419 1917) ((emacs (25 1)) (dash (2 12 0))) "Minor mode for analysing Erlang stacktraces" single ((:commit . "ca264bca24cdaa8b2bac57882716f03f633e42b0") (:authors ("k32")) (:maintainer "k32") (:keywords "tools" "erlang") (:url . "https://github.com/k32/erlstack-mode"))])
+ (eros . [(20180415 618) ((emacs (24 4))) "Evaluation Result OverlayS for Emacs Lisp" single ((:commit . "dd8910279226259e100dab798b073a52f9b4233a") (:authors ("Tianxiang Xiong" . "tianxiang.xiong@gmail.com")) (:maintainer "Tianxiang Xiong" . "tianxiang.xiong@gmail.com") (:keywords "convenience" "lisp") (:url . "https://github.com/xiongtx/eros"))])
+ (ert-async . [(20200105 1031) ((emacs (24 1))) "Async support for ERT" single ((:commit . "948cf2faa10e085bda3739034ca5ea1912893433") (:authors ("Johan Andersson" . "johan.rejeep@gmail.com")) (:maintainer "Johan Andersson" . "johan.rejeep@gmail.com") (:keywords "lisp" "test") (:url . "http://github.com/rejeep/ert-async.el"))])
+ (ert-expectations . [(20121009 734) nil "The simplest unit test framework in the world" single ((:commit . "aed70e002c4305b66aed7f6d0d48e9addd2dc1e6") (:authors ("rubikitch" . "rubikitch@ruby-lang.org")) (:maintainer "rubikitch" . "rubikitch@ruby-lang.org") (:keywords "test" "unittest" "ert" "expectations") (:url . "http://www.emacswiki.org/emacs/download/ert-expectations.el"))])
+ (ert-junit . [(20190802 2232) ((ert (0)) (emacs (23 4))) "JUnit XML reports from ert results" single ((:commit . "65f91c35b088b87943dbbbe7e1ce354bc9bc0992") (:authors ("Ola Nilsson" . "ola.nilsson@gmail.com")) (:maintainer "Ola Nilsson" . "ola.nilsson@gmail.com") (:keywords "tools" "test" "unittest" "ert") (:url . "http://bitbucket.org/olanilsson/ert-junit"))])
+ (ert-modeline . [(20140115 1015) ((s (1 3 1)) (dash (1 2 0)) (emacs (24 1)) (projectile (0 9 1))) "displays ert test results in the modeline." single ((:commit . "e7be2b81191afb437b70368a819770f8f750e4af") (:authors ("Chris Barrett" . "chris.d.barrett@me.com")) (:maintainer "Chris Barrett" . "chris.d.barrett@me.com") (:keywords "tools" "tests" "convenience"))])
+ (ert-runner . [(20201005 2336) ((s (1 6 1)) (dash (1 8 0)) (f (0 10 0)) (commander (0 2 0)) (ansi (0 1 0)) (shut-up (0 1 0))) "Opinionated Ert testing workflow" tar ((:commit . "80cf4f60ec8c1f04f58054ed8ad2dcfacc17d8b5") (:authors ("Johan Andersson" . "johan.rejeep@gmail.com")) (:maintainer "Johan Andersson" . "johan.rejeep@gmail.com") (:keywords "test") (:url . "http://github.com/rejeep/ert-runner.el"))])
+ (es-lib . [(20141111 1830) ((cl-lib (0 3))) "A collection of emacs utilities" tar ((:commit . "753b27363e39c10edc9e4e452bdbbbe4d190df4a") (:authors ("sabof")) (:maintainer "sabof") (:url . "https://github.com/sabof/es-lib"))])
+ (es-mode . [(20201125 2059) ((dash (2 11 0)) (cl-lib (0 5)) (spark (1 0)) (s (1 11 0)) (request (0 3 0))) "A major mode for editing and executing Elasticsearch queries" tar ((:commit . "cde5cafcbbbd57db6d38ae7452de626305bba68d") (:authors ("Lee Hinman" . "lee@writequit.org")) (:maintainer "Lee Hinman" . "lee@writequit.org") (:keywords "elasticsearch") (:url . "http://www.github.com/dakrone/es-mode"))])
+ (es-windows . [(20140211 904) ((cl-lib (0 3)) (emacs (24))) "Window-management utilities" single ((:commit . "239e30408cb1adb4bc8bd63e2df34711fa910b4f") (:authors ("sabof")) (:maintainer "sabof") (:url . "https://github.com/sabof/es-windows"))])
+ (esa . [(20180403 1525) ((cl-lib (0 5))) "Interface to esa.io" single ((:commit . "417e0ac55abe9b17e0b7165d0df26bc018aff42e") (:authors ("Nab Inno" . "nab@blahfe.com")) (:maintainer "Nab Inno" . "nab@blahfe.com") (:keywords "tools" "esa") (:url . "https://github.com/nabinno/esa.el"))])
+ (esh-autosuggest . [(20210906 1446) ((emacs (24 4)) (company (0 9 4))) "History autosuggestions for eshell" single ((:commit . "bf676b137d35553debe32ff134dbec25f3978ae7") (:authors ("Diego A. Mundo" . "dieggsy@pm.me")) (:maintainer "Diego A. Mundo" . "dieggsy@pm.me") (:keywords "completion" "company" "matching" "convenience" "abbrev") (:url . "http://github.com/dieggsy/esh-autosuggest"))])
+ (esh-buf-stack . [(20140107 1018) nil "Add a buffer stack feature to Eshell" single ((:commit . "ce0ea5aadca3150eaa9d2e6ec20296add4e99176") (:authors ("Tomoya Tanjo" . "ttanjo@gmail.com")) (:maintainer "Tomoya Tanjo" . "ttanjo@gmail.com") (:keywords "eshell" "extensions"))])
+ (esh-help . [(20190905 22) ((dash (1 4 0))) "Add some help functions and support for Eshell" single ((:commit . "417673ed18a983930a66a6692dbfb288a995cb80") (:authors ("Tomoya Tanjo" . "ttanjo@gmail.com")) (:maintainer "Tomoya Tanjo" . "ttanjo@gmail.com") (:keywords "eshell" "extensions") (:url . "https://github.com/tom-tan/esh-help/"))])
+ (eshell-autojump . [(20201117 235) nil "autojump command for Eshell" single ((:commit . "c1056bfc6b46646ae1e606247689fef9aee621af") (:authors ("Alex Schroeder")) (:maintainer "Yen-Chin, Lee" . "coldnew.tw@gmail.com") (:url . "http://github.com/coldnew/eshell-autojump"))])
+ (eshell-bookmark . [(20170922 1514) ((emacs (24 3))) "Integrate bookmarks with eshell." single ((:commit . "99a491c77e27ecc4626bdd4ad453ac71aa2654d4") (:authors ("Matúš Goljer" . "matus.goljer@gmail.com")) (:maintainer "Matúš Goljer" . "matus.goljer@gmail.com") (:keywords "convenience" "files") (:url . "https://github.com/Fuco1/eshell-bookmark"))])
+ (eshell-did-you-mean . [(20211104 237) ((emacs (24 1)) (cl-lib (0 5))) "command not found (\"did you mean…\" feature) in Eshell" single ((:commit . "80cd8c4b186a2fb29621cf634bcf2bcd914f1e3d") (:authors ("Chunyang Xu" . "xuchunyang56@gmail.com")) (:maintainer "Chunyang Xu" . "xuchunyang56@gmail.com") (:keywords "eshell") (:url . "https://github.com/xuchunyang/eshell-did-you-mean"))])
+ (eshell-fixed-prompt . [(20220104 1535) ((emacs (25)) (s (1 11 0))) "Restrict eshell to a single fixed prompt" single ((:commit . "302c241b42764bd6b4ed6d3c6ea360b5a2292fbc") (:authors ("Tijs Mallaerts" . "tijs.mallaerts@gmail.com")) (:maintainer "Tijs Mallaerts" . "tijs.mallaerts@gmail.com"))])
+ (eshell-fringe-status . [(20170117 2316) nil "Show last status in fringe" single ((:commit . "adc6997c68e39c0d52a2af1b2fd5cf2057783797") (:authors ("Tom Willemse" . "tom@ryuslash.org")) (:maintainer "Tom Willemse" . "tom@ryuslash.org") (:url . "http://projects.ryuslash.org/eshell-fringe-status/"))])
+ (eshell-git-prompt . [(20220206 458) ((emacs (24 1)) (cl-lib (0 5)) (dash (2 11 0))) "Some Eshell prompt for Git users" single ((:commit . "1eb1fd56649f291cac482fbf06dd43ef867873bc") (:authors ("Chunyang Xu" . "mail@xuchunyang.me")) (:maintainer "Chunyang Xu" . "mail@xuchunyang.me") (:keywords "eshell" "git") (:url . "https://github.com/xuchunyang/eshell-git-prompt"))])
+ (eshell-info-banner . [(20220402 1721) ((emacs (25 1)) (s (1))) "System information as your Eshell banner" single ((:commit . "53fc69b8712b9869cee49468a6e418d64d2c3ab9") (:authors ("Lucien Cartier-Tilet" . "lucien@phundrak.com")) (:maintainer "Lucien Cartier-Tilet" . "lucien@phundrak.com") (:url . "https://github.com/Phundrak/eshell-info-banner.el"))])
+ (eshell-outline . [(20201121 620) ((emacs (25 1))) "Enhanced outline-mode for Eshell" single ((:commit . "6f917afa5b3d36764d76d7864589094647d8c3b4") (:authors ("Jamie Beardslee" . "jdb@jamzattack.xyz")) (:maintainer "Jamie Beardslee" . "jdb@jamzattack.xyz") (:keywords "unix" "eshell" "outline" "convenience") (:url . "https://git.jamzattack.xyz/eshell-outline"))])
+ (eshell-prompt-extras . [(20210925 110) ((emacs (25))) "Display extra information for your eshell prompt." single ((:commit . "c2078093323206b91a1b1f5786d79faa00b76be7") (:authors ("zwild" . "judezhao@outlook.com")) (:maintainer "Chunyang Xu" . "mail@xuchunyang.me") (:keywords "eshell" "prompt") (:url . "https://github.com/zwild/eshell-prompt-extras"))])
+ (eshell-syntax-highlighting . [(20210429 413) ((emacs (25 1))) "Highlight eshell commands" single ((:commit . "8e3a685fc6d97af79e1046e5b24385786d8e92f6") (:authors ("Alex Kreisher" . "akreisher18@gmail.com")) (:maintainer "Alex Kreisher" . "akreisher18@gmail.com") (:keywords "convenience") (:url . "https://github.com/akreisher/eshell-syntax-highlighting"))])
+ (eshell-toggle . [(20210407 2039) ((emacs (25 1)) (dash (2 11 0))) "Show/hide eshell under active window." single ((:commit . "7160518ca56444fead841b8acff59aeffc7cebb3") (:authors ("Dmitry Cherkassov" . "dcherkassov@gmail.com")) (:maintainer "Dmitry Cherkassov" . "dcherkassov@gmail.com") (:keywords "processes") (:url . "https://github.com/4da/eshell-toggle"))])
+ (eshell-up . [(20170425 1737) ((emacs (24))) "Quickly go to a specific parent directory in eshell" single ((:commit . "ff84e6069b98f2ed00857a0f78bff19d96e4955c") (:authors ("Peter W. V. Tran-Jørgensen" . "peter.w.v.jorgensen@gmail.com")) (:maintainer "Peter W. V. Tran-Jørgensen" . "peter.w.v.jorgensen@gmail.com") (:keywords "eshell") (:url . "https://github.com/peterwvj/eshell-up"))])
+ (eshell-vterm . [(20211024 1443) ((emacs (27 1)) (vterm (0 0 1))) "Vterm for visual commands in eshell" single ((:commit . "f2212dbfa51aa4b67efda55304b2b3811e8e0625") (:authors ("Illia Ostapyshyn" . "ilya.ostapyshyn@gmail.com")) (:maintainer "Illia Ostapyshyn" . "ilya.ostapyshyn@gmail.com") (:keywords "eshell" "vterm" "terminals" "shell" "visual" "tools" "processes") (:url . "https://github.com/iostapyshyn/eshell-vterm"))])
+ (eshell-z . [(20191116 333) ((cl-lib (0 5))) "cd to frequent directory in eshell" single ((:commit . "337cb241e17bd472bd3677ff166a0800f684213c") (:authors ("Chunyang Xu" . "mail@xuchunyang.me")) (:maintainer "Chunyang Xu" . "mail@xuchunyang.me") (:keywords "convenience") (:url . "https://github.com/xuchunyang/eshell-z"))])
+ (eslint-disable-rule . [(20220328 354) ((emacs (27 2))) "Commands to add JS comments disabling eslint rules" tar ((:commit . "7d4cc05d336fbc465f91a87b38bf360efaf76fcf") (:url . "https://github.com/DamienCassou/eslint-disable-rule"))])
+ (eslint-fix . [(20211005 221) nil "Fix JavaScript files using ESLint" single ((:commit . "0435d8e2864bb4f1be59ae548d0068c69fa31c7a") (:authors ("Neri Marschik" . "marschik_neri@cyberagent.co.jp")) (:maintainer "Neri Marschik" . "marschik_neri@cyberagent.co.jp") (:keywords "tools" "javascript" "eslint" "lint" "formatting" "style") (:url . "https://github.com/codesuki/eslint-fix"))])
+ (eslint-rc . [(20220328 800) ((emacs (24 3)) (eslint-fix (0 1 0))) "Use local rc rules with ESLint" single ((:commit . "eb6f3e715792952bc957d5dc8ab1a607f3dbbd55") (:authors ("Joel Bryan Juliano <joelbryan dot juliano at gmail dot com>")) (:maintainer "Joel Bryan Juliano <joelbryan dot juliano at gmail dot com>") (:keywords "convenience" "edit" "js" "ts" "rc" "eslintrc" "eslint-rc" "eslint" "eslint-fix") (:url . "https://github.com/jjuliano/eslint-rc-emacs"))])
+ (eslintd-fix . [(20210731 1649) ((dash (2 12 0)) (emacs (26 3))) "use eslint_d to automatically fix js files" single ((:commit . "3897d8a679a6e98e3f5054aaefe07f6b55f8f128") (:authors ("Aaron Jensen" . "aaronjensen@gmail.com")) (:maintainer "Aaron Jensen" . "aaronjensen@gmail.com") (:url . "https://github.com/aaronjensen/eslintd-fix"))])
+ (esonify . [(20190110 1621) ((deferred (0 3 1)) (cl-lib (0 5))) "Sonify your code" tar ((:commit . "bdc79d4ab2e3c449b5bef46e5cabc552beeed5c6") (:authors ("Oliver Flatt" . "oflatt@gmail.com")) (:maintainer "Oliver Flatt" . "oflatt@gmail.com") (:url . "https://github.com/oflatt/esonify"))])
+ (espotify . [(20220121 2057) ((emacs (26 1))) "Spotify access library" single ((:commit . "ea6d6021e5acc550560325db2f09198839ee702f") (:authors ("Jose A Ortega Ruiz" . "jao@gnu.org")) (:maintainer "Jose A Ortega Ruiz") (:keywords "multimedia") (:url . "https://codeberg.org/jao/espotify"))])
+ (espresso-theme . [(20210505 1957) nil "Espresso Tutti Colori port for Emacs" single ((:commit . "580f673729f02aa07070c5300bedf24733d56e74") (:authors ("Martin Kühl <purl.org/net/mkhl>")) (:maintainer "Martin Kühl <purl.org/net/mkhl>") (:url . "https://github.com/dgutov/espresso-theme"))])
+ (espuds . [(20160905 1300) ((s (1 7 0)) (dash (2 2 0)) (f (0 12 1))) "Ecukes step definitions" single ((:commit . "78fc53feaf77a98d63894cd410faee2a18107b00") (:authors ("Johan Andersson" . "johan.rejeep@gmail.com")) (:maintainer "Johan Andersson" . "johan.rejeep@gmail.com") (:keywords "test") (:url . "http://github.com/ecukes/espuds"))])
+ (espy . [(20200317 2333) ((emacs (24))) "Emacs Simple Password Yielder" single ((:commit . "2c01be937a5e5bde62921684a0b27300705fb4e0") (:authors ("Sebastian Wålinder" . "s.walinder@gmail.com")) (:maintainer "Sebastian Wålinder" . "s.walinder@gmail.com") (:keywords "convenience") (:url . "https://github.com/walseb/espy"))])
+ (esqlite . [(20151206 1206) ((pcsv (1 3 3))) "Manipulate sqlite file from Emacs" single ((:commit . "08a779a821f8d32c1a1985d8d9eb6cf21646ce2e") (:authors ("Masahiro Hayashi" . "mhayashi1120@gmail.com")) (:maintainer "Masahiro Hayashi" . "mhayashi1120@gmail.com") (:keywords "data") (:url . "https://github.com/mhayashi1120/Emacs-esqlite"))])
+ (esqlite-helm . [(20151116 850) ((esqlite (0 2 0)) (helm (20131207 845))) "Define helm source for sqlite database" single ((:commit . "08a779a821f8d32c1a1985d8d9eb6cf21646ce2e") (:authors ("Masahiro Hayashi" . "mhayashi1120@gmail.com")) (:maintainer "Masahiro Hayashi" . "mhayashi1120@gmail.com") (:keywords "data") (:url . "https://github.com/mhayashi1120/Emacs-esqlite"))])
+ (ess . [(20220225 1523) ((emacs (25 1))) "Emacs Speaks Statistics" tar ((:commit . "39eba283000a7b0220303d7c5a4f3ee05efc1e9c") (:authors ("David Smith" . "dsmith@stats.adelaide.edu.au") ("A.J. Rossini" . "blindglobe@gmail.com") ("Richard M. Heiberger" . "rmh@temple.edu") ("Kurt Hornik" . "Kurt.Hornik@R-project.org") ("Martin Maechler" . "maechler@stat.math.ethz.ch") ("Rodney A. Sparapani" . "rsparapa@mcw.edu") ("Stephen Eglen" . "stephen@gnu.org") ("Sebastian P. Luque" . "spluque@gmail.com") ("Henning Redestig" . "henning.red@googlemail.com") ("Vitalie Spinu" . "spinuvit@gmail.com") ("Lionel Henry" . "lionel.hry@gmail.com") ("J. Alexander Branham" . "alex.branham@gmail.com")) (:maintainer "ESS Core Team" . "ESS-core@r-project.org") (:url . "https://ess.r-project.org/"))])
+ (ess-R-data-view . [(20130509 1158) ((ctable (20130313 1743)) (popup (20130324 1305)) (ess (20130225 1754))) "Data viewer for GNU R" single ((:commit . "d6e98d3ae1e2a2ea39a56eebcdb73e99d29562e9") (:authors ("myuhe <yuhei.maeda_at_gmail.com>")) (:maintainer "myuhe") (:keywords "convenience") (:url . "https://github.com/myuhe/ess-R-data-view.el"))])
+ (ess-r-insert-obj . [(20211209 812) ((emacs (26 1)) (ess (18 10 1))) "Insert objects in ESS-R" single ((:commit . "dd367cb918c90ec6d3824da869f7a75bb1ca49b6") (:authors ("Shuguang Sun" . "shuguang79@qq.com")) (:maintainer "Shuguang Sun" . "shuguang79@qq.com") (:keywords "tools") (:url . "https://github.com/ShuguangSun/ess-r-insert-obj"))])
+ (ess-smart-equals . [(20210411 1333) ((emacs (25 1)) (ess (18 10))) "flexible, context-sensitive assignment key for R/S" single ((:commit . "fea9eea4b59c3e9559b379508e3500076ca99ef1") (:authors ("Christopher R. Genovese" . "genovese@cmu.edu")) (:maintainer "Christopher R. Genovese" . "genovese@cmu.edu") (:keywords "r" "s" "ess" "convenience") (:url . "https://github.com/genovese/ess-smart-equals"))])
+ (ess-smart-underscore . [(20190309 101) ((ess (0))) "Ess Smart Underscore" tar ((:commit . "aa871c5b0448515db439ea9bed6a8574e82ddb47") (:authors ("Matthew L. Fidler")) (:maintainer "Matthew Fidler") (:keywords "ess" "underscore") (:url . "http://github.com/mlf176f2/ess-smart-underscore.el"))])
+ (ess-view . [(20181001 1730) ((ess (15)) (s (1 8 0)) (f (0 16 0))) "View R dataframes in a spreadsheet software" single ((:commit . "925cafd876e2cc37bc756bb7fcf3f34534b457e2") (:authors ("Bocci Gionata" . "boccigionata@gmail.com")) (:maintainer "Bocci Gionata" . "boccigionata@gmail.com") (:keywords "extensions" "ess") (:url . "https://github.com/GioBo/ess-view"))])
+ (ess-view-data . [(20220124 1430) ((emacs (26 1)) (ess (18 10 1)) (csv-mode (1 12))) "View Data" single ((:commit . "6277684e06d5c3a2cbd340f656b7ffca4046e45b") (:authors ("Shuguang Sun" . "shuguang79@qq.com")) (:maintainer "Shuguang Sun" . "shuguang79@qq.com") (:keywords "tools") (:url . "https://github.com/ShuguangSun/ess-view-data"))])
+ (esup . [(20220202 2335) ((cl-lib (0 5)) (s (1 2)) (emacs (25 1))) "The Emacs StartUp Profiler (ESUP)" tar ((:commit . "4b49c8d599d4cc0fbf994e9e54a9c78e5ab62a5f") (:authors ("Joe Schafer" . "joe@jschaf.com")) (:maintainer "Serghei Iakovlev" . "egrep@protonmail.ch") (:keywords "convenience" "processes") (:url . "https://github.com/jschaf/esup"))])
+ (esxml . [(20220505 1058) ((emacs (24 1)) (kv (0 0 5)) (cl-lib (0 5))) "Library for working with xml via esxml and sxml" tar ((:commit . "aafc2eced58906678d1e789855893e0f8cd6fc1c") (:authors ("Evan Izaksonas-Smith <izak0002 at umn dot edu>")) (:maintainer "Evan Izaksonas-Smith") (:keywords "tools" "lisp" "comm") (:url . "https://github.com/tali713/esxml"))])
+ (eta . [(20210115 1655) ((emacs (25 1)) (ht (2 2)) (dash (2 17))) "standard and multi dispatch key bind" single ((:commit . "c7540ac50163f368fec1918dfc334304d9b36c51") (:authors ("Chris Zheng")) (:maintainer "Chris Zheng") (:keywords "convenience" "usability") (:url . "https://www.github.com/zcaudate/eta"))])
+ (etable . [(20161028 2009) ((dash (2 9 0)) (interval-list (0 1)) (emacs (24 4))) "Implementation of javax.swing.JTable for Emacs." tar ((:commit . "d502141f0c69bf95256ba5cb9cd15350c7e942d2") (:authors ("Matus Goljer" . "matus.goljer@gmail.com")) (:maintainer "Matus Goljer" . "matus.goljer@gmail.com") (:keywords "convenience") (:url . "https://github.com/Fuco1/ETable"))])
+ (etc-sudoers-mode . [(20201102 1707) ((sudo-edit (0)) (with-editor (0))) "Edit Sudo security policies" single ((:commit . "74c66c58c9578a0d841206d5dec04d81e7b3d741") (:authors ("Peter Oliver" . "git@mavit.org.uk")) (:maintainer "Peter Oliver" . "git@mavit.org.uk") (:keywords "languages") (:url . "https://gitlab.com/mavit/etc-sudoers-mode/"))])
+ (eterm-256color . [(20210224 2241) ((emacs (24 4)) (xterm-color (1 7)) (f (0 19 0))) "Customizable 256 colors for term." tar ((:commit . "c9cfccef03e730f7ab2b407aada3df15ace1fe32") (:authors ("Diego A. Mundo" . "dieggsy@pm.me")) (:maintainer "Diego A. Mundo" . "dieggsy@pm.me") (:keywords "faces") (:url . "http://github.com/dieggsy/eterm-256color"))])
+ (eterm-fn . [(20191010 2331) ((term (0))) "Function keys (F1--F12) for term." tar ((:commit . "66f3b2f6308fa2ac4d8a32be5a7e35a96e08a9ee") (:authors ("Bruno Félix Rezende Ribeiro" . "oitofelix@gnu.org")) (:maintainer "Bruno Félix Rezende Ribeiro" . "oitofelix@gnu.org") (:keywords "terminals") (:url . "https://github.com/oitofelix/eterm-fn"))])
+ (ethan-wspace . [(20201106 2059) nil "whitespace customizations for emacs" single ((:commit . "035c7d698c99e3891a522d6e6f8fde23c6267c15") (:authors ("Ethan Glasser-Camp" . "ethan@betacantrips.com")) (:maintainer "Ethan Glasser-Camp" . "ethan@betacantrips.com") (:keywords "whitespace" "tab" "newline" "trailing" "clean"))])
+ (etherpad . [(20211128 106) ((emacs (26 3)) (request (0 3)) (let-alist (0 0)) (websocket (1 12)) (parsec (0 1)) (0xc (0 1))) "Interface to the Etherpad API" tar ((:commit . "1fae6a03084e0794e09ac036838b53aaae1dbd63") (:authors ("nik gaffney" . "nik@fo.am")) (:maintainer "nik gaffney" . "nik@fo.am") (:keywords "comm" "etherpad" "collaborative editing") (:url . "https://github.com/zzkt/ethermacs"))])
+ (euslisp-mode . [(20170830 1929) ((emacs (24 3)) (s (1 9)) (exec-path-from-shell (0)) (helm-ag (0 58))) "Major mode for Euslisp-formatted text" single ((:commit . "db62a2d148482317794727982576494596365a55") (:authors ("iory" . "ab.ioryz@gmail.com")) (:maintainer "iory" . "ab.ioryz@gmail.com") (:keywords "euslisp" "euslisp" "github") (:url . "https://github.com/iory/euslisp-mode"))])
+ (eval-expr . [(20120619 647) nil "enhanced eval-expression command" single ((:commit . "a0e69e83de41df8dbccefc1962ab4f02206a3328") (:authors ("Noah Friedman" . "friedman@splode.com")) (:maintainer nil . "friedman@splode.com") (:keywords "lisp" "extensions"))])
+ (eval-in-repl . [(20201121 1341) ((dash (0 0 0)) (paredit (0 0 0)) (ace-window (0 0 0))) "Consistent ESS-like eval interface for various REPLs" tar ((:commit . "2abb9ccf6f08ae3a5ab504f0b3fd81ce0345b766") (:authors ("Kazuki YOSHIDA" . "kazukiyoshida@mail.harvard.edu")) (:maintainer "Kazuki YOSHIDA" . "kazukiyoshida@mail.harvard.edu") (:keywords "tools" "convenience") (:url . "https://github.com/kaz-yos/eval-in-repl"))])
+ (eval-sexp-fu . [(20191128 825) ((cl-lib (0))) "Tiny functionality enhancements for evaluating sexps." single ((:commit . "36d2fe3bcf602e15ca10a7f487da103515ef391a") (:authors ("Takeshi Banse" . "takebi@laafc.net")) (:maintainer "Takeshi Banse" . "takebi@laafc.net") (:keywords "lisp" "highlight" "convenience"))])
+ (evalator . [(20160213 128) ((helm-core (1 9 1))) "Package for interactive transformation of data with helm" tar ((:commit . "f30da4da48c0b3f3cfa1fc1c7cfdb53ffe79df36") (:authors ("Sean Irby")) (:maintainer "Sean Irby" . "sean.t.irby@gmail.com") (:keywords "languages" "elisp" "helm") (:url . "http://www.github.com/seanirby/evalator"))])
+ (evalator-clojure . [(20160208 2148) ((cider (0 10 0)) (evalator (1 0 0))) "Clojure evaluation context for evalator via CIDER." tar ((:commit . "caa4e0a137bdfada86593128a654e16aa617ad50") (:authors ("Sean Irby")) (:maintainer "Sean Irby" . "sean.t.irby@gmail.com") (:keywords "languages" "clojure" "cider" "helm") (:url . "http://www.github.com/seanirby/evalator-clojure"))])
+ (eve-mode . [(20170822 2231) ((emacs (25)) (polymode (1 0)) (markdown-mode (2 0))) "Major mode for editing Eve documents." single ((:commit . "a4661114d9c18725691b76321d72167ca5a9070a") (:authors ("Joshua Cole" . "joshuafcole@gmail.com")) (:maintainer "Joshua Cole" . "joshuafcole@gmail.com") (:keywords "languages" "wp" "tools") (:url . "https://github.com/witheve/emacs-eve-mode"))])
+ (everlasting-scratch . [(20220412 921) ((emacs (25 1))) "The *scratch* that lasts forever" single ((:commit . "8706c55f3b7c267c15b8f10170ecec9998b3cc3d") (:authors ("Huming Chen" . "chenhuming@gmail.com")) (:maintainer "Huming Chen" . "chenhuming@gmail.com") (:keywords "convenience" "tool") (:url . "https://github.com/beacoder/everlasting-scratch"))])
+ (evil . [(20220503 1314) ((emacs (24 1)) (goto-chg (1 6)) (cl-lib (0 5))) "Extensible Vi layer for Emacs." tar ((:commit . "6c5079b105b2ccbcfa735fd1b6a19797daa7081d") (:maintainer "Tom Dalziel" . "tom.dalziel@gmail.com") (:keywords "emulation" "vim") (:url . "https://github.com/emacs-evil/evil"))])
+ (evil-anzu . [(20200514 1902) ((evil (1 0 0)) (anzu (0 46))) "anzu for evil-mode" single ((:commit . "d3f6ed4773b48767bd5f4708c7f083336a8a8a86") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com") ("Fredrik Bergroth" . "fbergroth@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-evil-anzu"))])
+ (evil-args . [(20220125 1626) ((evil (1 0 8))) "Motions and text objects for delimited arguments in Evil." single ((:commit . "2671071a4a57eaee7cc8c27b9e4b6fc60fd2ccd3") (:authors ("Connor Smith" . "wconnorsmith@gmail.com")) (:maintainer "Connor Smith" . "wconnorsmith@gmail.com") (:keywords "evil" "vim-emulation") (:url . "http://github.com/wcsmith/evil-args"))])
+ (evil-avy . [(20150908 748) ((emacs (24 1)) (cl-lib (0 5)) (avy (0 3 0)) (evil (1 2 3))) "set-based completion" single ((:commit . "2dd955cc3ecaa7ddeb67b295298abdc6d16dd3a5") (:authors ("Yufan Lou" . "loganlyf@gmail.com")) (:maintainer "Yufan Lou" . "loganlyf@gmail.com") (:keywords "point" "location" "evil" "vim") (:url . "https://github.com/louy2/evil-avy"))])
+ (evil-better-visual-line . [(20200123 2045) ((evil (1 2 13))) "gj and gk visual line mode fix" single ((:commit . "4373f930ab1a8d3a2a90e68540967702313b2ce9") (:authors ("<nuckollsp at gmail.com>")) (:maintainer "<nuckollsp at gmail.com>") (:keywords "evil" "vim" "motion") (:url . "https://github.com/yourfin/evil-better-visual-line"))])
+ (evil-cleverparens . [(20170718 413) ((evil (1 0)) (paredit (1)) (smartparens (1 6 1)) (emacs (24 4)) (dash (2 12 0))) "Evil friendly minor-mode for editing lisp." tar ((:commit . "8c45879d49bfa6d4e414b6c1df700a4a51cbb869") (:authors ("Olli Piepponen" . "opieppo@gmail.com")) (:maintainer "Olli Piepponen" . "opieppo@gmail.com") (:keywords "cleverparens" "parentheses" "evil" "paredit" "smartparens") (:url . "https://github.com/luxbock/evil-cleverparens"))])
+ (evil-colemak-basics . [(20220222 1856) ((emacs (24 3)) (evil (1 2 12)) (evil-snipe (2 0 3))) "Basic Colemak key bindings for evil-mode" single ((:commit . "66648de206a7368013f28c0d053b1b32c3efe6c6") (:authors ("Wouter Bolsterlee" . "wouter@bolsterl.ee")) (:maintainer "Wouter Bolsterlee" . "wouter@bolsterl.ee") (:keywords "convenience" "emulations" "colemak" "evil") (:url . "https://github.com/wbolster/evil-colemak-basics"))])
+ (evil-colemak-minimal . [(20171006 1317) ((emacs (24)) (evil (1 2 12))) "Minimal Colemak key bindings for evil-mode" single ((:commit . "6d98b6da60f414524a0d718f76024c26dce742b3") (:authors ("Bryan Allred" . "bryan@revolvingcow.com")) (:maintainer "Bryan Allred" . "bryan@revolvingcow.com") (:keywords "colemak" "evil") (:url . "https://github.com/bmallred/evil-colemak-minimal"))])
+ (evil-collection . [(20220505 619) ((emacs (25 1)) (evil (1 2 13)) (annalist (1 0))) "A set of keybindings for Evil mode" tar ((:commit . "9707efcae4fc76fa204b1c29565aae35b99b865a") (:authors ("James Nguyen" . "james@jojojames.com")) (:maintainer "James Nguyen" . "james@jojojames.com") (:keywords "evil" "tools") (:url . "https://github.com/emacs-evil/evil-collection"))])
+ (evil-commentary . [(20210210 1702) ((evil (1 0 0))) "Comment stuff out. A port of vim-commentary." tar ((:commit . "2dab6ac34d1617971768ad219d73af48f7473fec") (:authors ("Quang Linh LE" . "linktohack@gmail.com")) (:maintainer "Quang Linh LE" . "linktohack@gmail.com") (:keywords "evil" "comment" "commentary" "evil-commentary") (:url . "http://github.com/linktohack/evil-commentary"))])
+ (evil-dvorak . [(20160416 1841) ((evil (1 0 8))) "evil keybindings for that work with dvorak mode" tar ((:commit . "824f7c56980d72a0ff04c662223540cd66f13754") (:authors ("Joshua Branson")) (:maintainer "Joshua Branson") (:keywords "dvorak" "evil" "vim"))])
+ (evil-easymotion . [(20200424 135) ((emacs (24)) (avy (0 3 0)) (cl-lib (0 5))) "A port of vim's easymotion to emacs" single ((:commit . "f96c2ed38ddc07908db7c3c11bcd6285a3e8c2e9") (:authors ("PythonNut" . "pythonnut@pythonnut.com")) (:maintainer "PythonNut" . "pythonnut@pythonnut.com") (:keywords "convenience" "evil") (:url . "https://github.com/pythonnut/evil-easymotion"))])
+ (evil-ediff . [(20170724 1923) ((evil (1 2 3))) "Make ediff a little evil" single ((:commit . "50d26cb0654fca8f8fd7227410e5cbf0b8f681cf") (:authors ("Justin Burkett" . "justin@burkett.cc")) (:maintainer "Justin Burkett" . "justin@burkett.cc") (:url . "https://github.com/justbur/evil-ediff"))])
+ (evil-embrace . [(20220211 606) ((emacs (24 4)) (embrace (0 1 0)) (evil-surround (0))) "Evil integration of embrace.el" single ((:commit . "7b5a539cfe7db238d860122c793a0cb2d329cc6e") (:authors ("Junpeng Qiu" . "qjpchmail@gmail.com")) (:maintainer "Junpeng Qiu" . "qjpchmail@gmail.com") (:keywords "extensions"))])
+ (evil-escape . [(20180910 1234) ((emacs (24)) (evil (1 0 9)) (cl-lib (0 5))) "No description available." single ((:commit . "f4e9116bfbaac8c9d210c17ad488e0982291245f") (:authors ("Sylvain Benner" . "sylvain.benner@gmail.com")) (:maintainer "Sylvain Benner" . "sylvain.benner@gmail.com") (:keywords "convenience" "editing" "evil") (:url . "https://github.com/syl20bnr/evil-escape"))])
+ (evil-ex-fasd . [(20180903 612) ((emacs (24 4)) (evil (1 1 0)) (fasd (0))) "using fasd right from evil-ex" single ((:commit . "ed8fbbe23a8a268d9dcbf1a6132e928ba2c655c5") (:authors ("Rashawn Zhang" . "namy.19@gmail.com")) (:maintainer "Rashawn Zhang" . "namy.19@gmail.com") (:keywords "tools" "fasd" "evil" "navigation") (:url . "https://github.com/yqrashawn/evil-ex-fasd"))])
+ (evil-ex-shell-command . [(20181226 226) ((emacs (24 4)) (evil (1 1 0))) "invoke shell-command right from evil-ex" single ((:commit . "a6ca6d27c07f6a0807abfb5b8f8865f1d17f54aa") (:authors ("Rashawn Zhang" . "namy.19@gmail.com")) (:maintainer "Rashawn Zhang" . "namy.19@gmail.com") (:keywords "tools" "shell-command" "evil") (:url . "https://github.com/yqrashawn/evil-ex-shell-command"))])
+ (evil-exchange . [(20200118 252) ((evil (1 2 8)) (cl-lib (0 3))) "Exchange text more easily within Evil" single ((:commit . "5f0a2d41434c17c6fb02e4f744043775de1c63a2") (:authors ("Dewdrops" . "v_v_4474@126.com")) (:maintainer "Dewdrops" . "v_v_4474@126.com") (:keywords "evil" "plugin") (:url . "http://github.com/Dewdrops/evil-exchange"))])
+ (evil-expat . [(20190521 714) ((emacs (24 3)) (evil (1 0 0))) "Evil ex commands" single ((:commit . "f4fcd0aa3edc359adb5c986b5dd9188d220d84e2") (:authors ("edkolev" . "evgenysw@gmail.com")) (:maintainer "edkolev" . "evgenysw@gmail.com") (:keywords "emulations" "evil" "vim") (:url . "http://github.com/edkolev/evil-expat"))])
+ (evil-extra-operator . [(20210225 1239) ((evil (1 0 7))) "Evil operator for evaluating codes, taking notes, searching via google, etc." single ((:commit . "fb249889acacc3e28869491195391fa6f617ae56") (:authors ("Dewdrops" . "v_v_4474@126.com")) (:maintainer "Dewdrops" . "v_v_4474@126.com") (:keywords "evil" "plugin") (:url . "http://github.com/Dewdrops/evil-extra-operator"))])
+ (evil-find-char-pinyin . [(20160514 2041) ((evil (1 2 12)) (pinyinlib (0 1 0))) "Evil's f/F/t/T/evil-snipe commands with Pinyin support" single ((:commit . "04e277946d658f1a73c68dcbbadea9c21097a31c") (:authors ("Junpeng Qiu" . "qjpchmail@gmail.com")) (:maintainer "Junpeng Qiu" . "qjpchmail@gmail.com") (:keywords "extensions"))])
+ (evil-fringe-mark . [(20190320 453) ((emacs (24 3)) (evil (1 0 0)) (fringe-helper (0 1 1)) (goto-chg (1 6))) "Display evil-mode marks in the fringe" tar ((:commit . "a1689fddb7ee79aaa720a77aada1208b8afd5c20") (:authors ("Andrew Smith" . "andy.bill.smith@gmail.com")) (:maintainer "Andrew Smith" . "andy.bill.smith@gmail.com") (:url . "https://github.com/Andrew-William-Smith/evil-fringe-mark"))])
+ (evil-god-state . [(20141117 255) ((evil (1 0 8)) (god-mode (2 12 0))) "use god-mode keybindings in evil-mode" single ((:commit . "3d44197dc0a1fb40e7b7ff8717f8a8c339ce1d40") (:authors ("Eric Seidel")) (:maintainer "Eric Seidel") (:keywords "evil" "leader" "god-mode") (:url . "https://github.com/gridaphobe/evil-god-state"))])
+ (evil-goggles . [(20220112 1302) ((emacs (24 4)) (evil (1 0 0))) "Add a visual hint to evil operations" single ((:commit . "8f20a16e74016f37ad76dc4f2230d9b00c6df3c2") (:authors ("edkolev" . "evgenysw@gmail.com")) (:maintainer "edkolev" . "evgenysw@gmail.com") (:keywords "emulations" "evil" "vim" "visual") (:url . "http://github.com/edkolev/evil-goggles"))])
+ (evil-iedit-state . [(20220219 1432) ((evil (1 0 9)) (iedit (0 9 9 9))) "Evil states to interface iedit mode." single ((:commit . "6f7b502447ba35676375169d7707372ebad2791f") (:authors ("Sylvain Benner" . "sylvain.benner@gmail.com")) (:maintainer "Sylvain Benner" . "sylvain.benner@gmail.com") (:keywords "convenience" "editing" "evil" "iedit" "mnemonic") (:url . "https://github.com/syl20bnr/evil-iedit-state"))])
+ (evil-indent-plus . [(20220106 931) ((evil (0)) (cl-lib (0 5))) "Evil textobjects based on indentation" single ((:commit . "b4dacbfdb57f474f798bfbf5026d434d549eb65c") (:authors ("Eivind Fonn" . "evfonn@gmail.com")) (:maintainer "Eivind Fonn" . "evfonn@gmail.com") (:keywords "convenience" "evil") (:url . "http://github.com/TheBB/evil-indent-plus"))])
+ (evil-indent-textobject . [(20130831 2219) ((evil (0))) "evil textobjects based on indentation" single ((:commit . "70a1154a531b7cfdbb9a31d6922482791e20a3a7") (:authors ("Michael Markert" . "markert.michael@gmail.com")) (:maintainer "Michael Markert" . "markert.michael@gmail.com") (:keywords "convenience" "evil") (:url . "http://github.com/cofi/evil-indent-textobject"))])
+ (evil-leader . [(20140606 1243) ((evil (0))) "let there be <leader>" single ((:commit . "39f7014bcf8b36463e0c7512c638bda4bac6c2cf") (:authors ("Michael Markert" . "markert.michael@googlemail.com")) (:maintainer "Michael Markert" . "markert.michael@googlemail.com") (:keywords "evil" "vim-emulation" "leader") (:url . "http://github.com/cofi/evil-leader"))])
+ (evil-ledger . [(20180802 1612) ((emacs (24 4)) (evil (1 2 12)) (ledger-mode (0))) "Make `ledger-mode' more `evil'." single ((:commit . "7a9f9f5d39c42fffdba8004f8982642351f2b233") (:authors ("Aaron Jacobs" . "atheriel@gmail.com")) (:maintainer "Aaron Jacobs" . "atheriel@gmail.com") (:keywords "convenience" "evil" "languages" "ledger" "vim-emulation") (:url . "https://github.com/atheriel/evil-ledger"))])
+ (evil-lion . [(20220317 1030) ((emacs (24 3)) (evil (1 0 0))) "Evil align operator, port of vim-lion" single ((:commit . "4da660e124731ed65e7aaa6c067c30e876619429") (:authors ("edkolev" . "evgenysw@gmail.com")) (:maintainer "edkolev" . "evgenysw@gmail.com") (:keywords "emulations" "evil" "vim") (:url . "http://github.com/edkolev/evil-lion"))])
+ (evil-lisp-state . [(20160404 248) ((evil (1 0 9)) (bind-map (0)) (smartparens (1 6 1))) "An evil state to edit Lisp code" single ((:commit . "3c65fecd9917a41eaf6460f22187e2323821f3ce") (:authors ("Sylvain Benner" . "sylvain.benner@gmail.com")) (:maintainer "Sylvain Benner" . "sylvain.benner@gmail.com") (:keywords "convenience" "editing" "evil" "smartparens" "lisp" "mnemonic") (:url . "https://github.com/syl20bnr/evil-lisp-state"))])
+ (evil-lispy . [(20190502 739) ((lispy (0 26 0)) (evil (1 2 12)) (hydra (0 13 5))) "precision Lisp editing with Evil and Lispy" tar ((:commit . "ed317f7fccbdbeea8aa04a91b1b1f48a0e2ddc4e") (:authors ("Brandon Carrell <brandoncarrell@gmail.com>, Mika Vilpas" . "mika.vilpas@gmail.com")) (:maintainer "Brandon Carrell <brandoncarrell@gmail.com>, Mika Vilpas" . "mika.vilpas@gmail.com") (:keywords "lisp") (:url . "https://github.com/sp3ctum/evil-lispy"))])
+ (evil-mark-replace . [(20200630 940) ((evil (1 14 0))) "replace the thing in marked area" single ((:commit . "d4fec7b10e93cca149163324cd2b2b2dcc211047") (:authors ("Chen Bin <chenbin DOT sh AT gmail DOT com>")) (:maintainer "Chen Bin <chenbin DOT sh AT gmail DOT com>") (:keywords "convenience") (:url . "http://github.com/redguardtoo/evil-mark-replace"))])
+ (evil-matchit . [(20220414 1316) ((evil (1 14 0)) (emacs (25 1))) "Vim matchit ported to Evil" tar ((:commit . "b314e816bacfc01bb7df9b19a06b18638af5cdbe") (:authors ("Chen Bin" . "chenbin.sh@gmail.com")) (:maintainer "Chen Bin" . "chenbin.sh@gmail.com") (:keywords "matchit" "vim" "evil") (:url . "http://github.com/redguardtoo/evil-matchit"))])
+ (evil-mc . [(20220118 122) ((emacs (24 3)) (evil (1 2 14)) (cl-lib (0 5))) "Multiple cursors for evil-mode" tar ((:commit . "63fd2fe0c213a4cc31c464d246f92931c4cb720f") (:authors ("Gabriel Adomnicai" . "gabesoft@gmail.com")) (:maintainer "Gabriel Adomnicai" . "gabesoft@gmail.com") (:keywords "evil" "editing" "multiple-cursors" "vim" "evil-multiple-cursors" "evil-mc" "evil-mc") (:url . "https://github.com/gabesoft/evil-mc"))])
+ (evil-mc-extras . [(20170202 1649) ((emacs (24 3)) (evil (1 2 12)) (cl-lib (0 5)) (evil-mc (0 0 2)) (evil-numbers (0 4))) "Extra functionality for evil-mc" tar ((:commit . "8c1af3232dd1e15b2ea38360b8cd1e857e11c416") (:authors ("Gabriel Adomnicai" . "gabesoft@gmail.com")) (:maintainer "Gabriel Adomnicai" . "gabesoft@gmail.com") (:keywords "evil" "editing" "multiple-cursors" "vim" "evil-multiple-cursors" "evil-mc" "evil-mc-extras") (:url . "https://github.com/gabesoft/evil-mc-extras"))])
+ (evil-mu4e . [(20180613 1039) ((emacs (24 4)) (evil (1 2 10))) "evil-based key bindings for mu4e" single ((:commit . "5b22c1e30246318f233264506272d770f63897ca") (:authors ("Joris Engbers" . "info@jorisengbers.nl")) (:maintainer "Joris Engbers" . "info@jorisengbers.nl") (:url . "https://github.com/JorisE/evil-mu4e"))])
+ (evil-multiedit . [(20211121 1650) ((emacs (25 1)) (evil (1 14 0)) (iedit (0 9 9)) (cl-lib (0 5))) "multiple cursors for evil-mode" single ((:commit . "23b53bc8743fb82a8854ba907b1d277374c93a79") (:authors ("Henrik Lissner <http://github/hlissner>")) (:maintainer "Henrik Lissner" . "contact@henrik.io") (:keywords "multiple cursors" "editing" "iedit") (:url . "https://github.com/hlissner/evil-multiedit"))])
+ (evil-nerd-commenter . [(20220414 1201) ((emacs (25 1))) "Comment/uncomment lines efficiently. Like Nerd Commenter in Vim" tar ((:commit . "95ed1ad2448e7f49f1ee417061b61edbb69a0749") (:authors ("Chen Bin" . "chenbin.sh@gmail.com")) (:maintainer "Chen Bin" . "chenbin.sh@gmail.com") (:keywords "convenience" "evil") (:url . "http://github.com/redguardtoo/evil-nerd-commenter"))])
+ (evil-nl-break-undo . [(20181125 2054) nil "Break evil's undo sequence on CR" single ((:commit . "4a8f2bf99c978a109eeb92965a72a17bedb68762") (:authors ("VanLaser" . "Gabriel.Lazar@com.utcluj.ro")) (:maintainer "VanLaser" . "Gabriel.Lazar@com.utcluj.ro") (:url . "https://github.com/VanLaser/evil-nl-break-undo"))])
+ (evil-numbers . [(20211011 103) ((emacs (24 1)) (evil (1 2 0))) "Increment/decrement numbers like in VIM" single ((:commit . "08f0c1ee93b8a563770eaefaf21ab9087fca7bdb") (:authors ("Michael Markert" . "markert.michael@googlemail.com")) (:maintainer "Julia Path" . "julia@jpath.de") (:keywords "convenience" "tools") (:url . "http://github.com/juliapath/evil-numbers"))])
+ (evil-opener . [(20161207 1810) ((evil (1 2 12)) (opener (0 2 2))) "opening urls as buffers in evil" tar ((:commit . "c384f67278046fdcd220275fdd212ab85672cbeb") (:authors ("Tim Reddehase" . "tr@rightsrestricted.com")) (:maintainer "Tim Reddehase" . "tr@rightsrestricted.com") (:keywords "url" "http" "files") (:url . "https://github.com/0robustus1/opener.el"))])
+ (evil-org . [(20220227 1024) ((emacs (24 4)) (evil (1 0))) "evil keybindings for org-mode" tar ((:commit . "0d10ff7bb9a3a93d25cd91018b17f0a052b335f3") (:maintainer "Somelauw") (:keywords "evil" "vim-emulation" "org-mode" "key-bindings" "presets") (:url . "https://github.com/Somelauw/evil-org-mode.git"))])
+ (evil-owl . [(20210416 1700) ((emacs (25 1)) (evil (1 2 13))) "Preview evil registers and marks before using them" single ((:commit . "a41a6d28e26052b25f3d21da37ccf1d8fde1e6aa") (:authors ("Daniel Phan" . "daniel.phan36@gmail.com")) (:maintainer "Daniel Phan" . "daniel.phan36@gmail.com") (:keywords "emulations" "evil" "visual") (:url . "https://github.com/mamapanda/evil-owl"))])
+ (evil-paredit . [(20150413 2048) ((evil (1 0 9)) (paredit (25 -2))) "Paredit support for evil keybindings" single ((:commit . "e058fbdcf9dbf7ad6cc77f0172d7517ef233d55f") (:authors ("Roman Gonzalez" . "romanandreg@gmail.com")) (:maintainer "Roman Gonzalez" . "romanandreg@gmail.com") (:keywords "paredit" "evil") (:url . "https://github.com/roman/evil-paredit"))])
+ (evil-pinyin . [(20200927 849) ((emacs (25)) (names (0 5)) (evil (1))) "Evil search Chinese characters by pinyin" tar ((:commit . "3e9e501ded86f88e01a4edec5d526ab0fab879d7") (:keywords "extensions") (:url . "https://github.com/laishulu/evil-pinyin"))])
+ (evil-python-movement . [(20180724 1420) ((emacs (25 1)) (cl-lib (0 5)) (dash (2 13 0)) (evil (1 0)) (s (1 12 0))) "Port Neovim's python movement to Evil" single ((:commit . "9936b3b7f8d96415d517c1f3604637889484a637") (:authors ("Felipe Lema <felipelema en mortemale punto org>")) (:maintainer "Felipe Lema <felipelema en mortemale punto org>") (:url . "https://bitbucket.org/FelipeLema/evil-python-movement.el/"))])
+ (evil-quickscope . [(20160202 1924) ((evil (0))) "Highlight unique characters in words for f,F,t,T navigation" single ((:commit . "37a20e4c56c6058abf186ad4013c155e695e876f") (:authors ("Michael Chen" . "blorbx@gmail.com")) (:maintainer "Michael Chen" . "blorbx@gmail.com") (:keywords "faces" "emulation" "vim" "evil") (:url . "http://github.com/blorbx/evil-quickscope"))])
+ (evil-rails . [(20190512 1517) ((evil (1 0)) (projectile-rails (1 0))) "Rails support for Evil Mode" single ((:commit . "b0f1c5de6720714febeb76c4b569b71bb891938c") (:authors ("Antono Vasiljev" . "antono.vasiljev@gmail.com")) (:maintainer "Antono Vasiljev" . "antono.vasiljev@gmail.com") (:keywords "ruby" "rails" "vim" "project" "convenience" "web" "evil" "projectile") (:url . "https://github.com/antono/evil-rails"))])
+ (evil-replace-with-char . [(20180324 2206) ((evil (1 2 13)) (emacs (24))) "replace chars of a text object with a char" single ((:commit . "ed4a12d5bff11163eb03ad2826c52fd30f51a8d3") (:authors ("Filipe Silva" . "filipe.silva@gmail.com")) (:maintainer "Filipe Silva" . "filipe.silva@gmail.com") (:url . "https://github.com/ninrod/evil-replace-with-char"))])
+ (evil-replace-with-register . [(20170713 925) ((evil (1 0 8))) "Port of vim plugin ReplaceWithRegister" single ((:commit . "91cc7bf21a94703c441cc9212214075b226b7f67") (:authors ("Dewdrops" . "v_v_4474@126.com")) (:maintainer "Dewdrops" . "v_v_4474@126.com") (:keywords "evil" "plugin") (:url . "https://github.com/Dewdrops/evil-ReplaceWithRegister"))])
+ (evil-rsi . [(20160221 2104) ((evil (1 0 0))) "Use emacs motion keys in evil, inspired by vim-rsi" single ((:commit . "65ae60866be494e4622fe383e23975e04d2a42a3") (:authors ("Quang Linh LE" . "linktohack@gmail.com")) (:maintainer "Quang Linh LE" . "linktohack@gmail.com") (:keywords "evil" "rsi" "evil-rsi") (:url . "http://github.com/linktohack/evil-rsi"))])
+ (evil-ruby-text-objects . [(20200323 1552) ((emacs (25 1)) (evil (1 2 0))) "Evil text objects for Ruby code" single ((:commit . "32983d91be83ed903b6ef9655e00f69beed2572c") (:authors ("Sergio Gil" . "sgilperez@gmail.com")) (:maintainer "Sergio Gil" . "sgilperez@gmail.com") (:keywords "languages") (:url . "https://github.com/porras/evil-ruby-text-objects"))])
+ (evil-search-highlight-persist . [(20170523 334) ((highlight (0))) "Persistent highlights after search" single ((:commit . "979d2dec58d3b9c5ca5fdf4bb802a0209913794e") (:authors ("Juanjo Alvarez" . "juanjo@juanjoalvarez.net")) (:maintainer "Juanjo Alvarez" . "juanjo@juanjoalvarez.net"))])
+ (evil-smartparens . [(20171210 1513) ((evil (1 0)) (emacs (24 4)) (smartparens (1 10 1))) "Evil support for smartparens" single ((:commit . "026d4a3cfce415a4dfae1457f871b385386e61d3") (:authors ("Lars Andersen" . "expez@expez.com")) (:maintainer "Lars Andersen" . "expez@expez.com") (:keywords "evil" "smartparens") (:url . "https://www.github.com/expez/evil-smartparens"))])
+ (evil-snipe . [(20220428 1432) ((emacs (24 4)) (evil (1 2 12)) (cl-lib (0 5))) "emulate vim-sneak & vim-seek" single ((:commit . "c07788c35cf8cd8e652a494322fdc0643e30a89f") (:authors ("Henrik Lissner <http://github/hlissner>")) (:maintainer "Henrik Lissner" . "contact@henrik.io") (:keywords "emulation" "vim" "evil" "sneak" "seek") (:url . "https://github.com/hlissner/evil-snipe"))])
+ (evil-space . [(20151208 1228) ((evil (1 0 0))) "Repeat motion in Evil. Correct the behaviour of what SPC should do." single ((:commit . "a9c07284d308425deee134c9d88a2d538dd229e6") (:authors ("Quang Linh LE" . "linktohack@gmail.com")) (:maintainer "Quang Linh LE" . "linktohack@gmail.com") (:keywords "space" "repeat" "motion") (:url . "http://github.com/linktohack/evil-space"))])
+ (evil-string-inflection . [(20180313 1755) ((emacs (24)) (evil (1 2 13)) (string-inflection (1 0 6))) "snake_case -> CamelCase -> etc. for text objects" single ((:commit . "d22a90ab807afa7f27f3815b5b5ea47d52d05218") (:authors ("Filipe Silva" . "filipe.silva@gmail.com")) (:maintainer "Filipe Silva" . "filipe.silva@gmail.com") (:url . "https://github.com/ninrod/evil-string-inflection"))])
+ (evil-surround . [(20220504 802) ((evil (1 2 12))) "emulate surround.vim from Vim" single ((:commit . "c9e1449bf3f740b5e9b99e7820df4eca7fc7cf02") (:authors ("Tim Harper <timcharper at gmail dot com>") ("Vegard Øye <vegard_oye at hotmail dot com>")) (:maintainer "Tim Harper <timcharper at gmail dot com>") (:keywords "emulation" "vi" "evil"))])
+ (evil-swap-keys . [(20191105 1426) ((emacs (24 4))) "Intelligently swap keys on text input with evil" single ((:commit . "b5ef105499f998b5667da40da30c073229a213ea") (:authors ("Wouter Bolsterlee" . "wouter@bolsterl.ee")) (:maintainer "Wouter Bolsterlee" . "wouter@bolsterl.ee") (:keywords "convenience" "data" "languages" "tools") (:url . "https://github.com/wbolster/evil-swap-keys"))])
+ (evil-tabs . [(20160217 1520) ((evil (0 0 0)) (elscreen (0 0 0))) "Integrating Vim-style tabs for Evil mode users." single ((:commit . "53d3314a810017b6056ab6796aef671f5ea1c063") (:authors ("Kris Jenkins" . "krisajenkins@gmail.com")) (:maintainer "Kris Jenkins" . "krisajenkins@gmail.com") (:keywords "evil" "tab" "tabs" "vim") (:url . "https://github.com/krisajenkins/evil-tabs"))])
+ (evil-terminal-cursor-changer . [(20220422 255) ((evil (1 0 8))) "Change cursor shape and color by evil state in terminal" single ((:commit . "69d562932f9ab9869ab1ed923e9789cbfa0ff14c") (:authors ("7696122")) (:maintainer "7696122") (:keywords "evil" "terminal" "cursor") (:url . "https://github.com/7696122/evil-terminal-cursor-changer"))])
+ (evil-test-helpers . [(20220425 2132) ((evil (1 15 0))) "unit test helpers for Evil" single ((:commit . "6c5079b105b2ccbcfa735fd1b6a19797daa7081d") (:authors ("Vegard Øye <vegard_oye at hotmail.com>")) (:maintainer "Vegard Øye <vegard_oye at hotmail.com>"))])
+ (evil-tex . [(20220415 842) ((emacs (26 1)) (evil (1 0)) (auctex (11 88))) "Useful features for editing LaTeX in evil-mode" single ((:commit . "26035ec9a09f8b38ce0d495ff788e83ec8b195d5") (:keywords "tex" "emulation" "vi" "evil" "wp") (:url . "https://github.com/iyefrat/evil-tex"))])
+ (evil-text-object-python . [(20191010 1328) ((emacs (25)) (evil (1 2 14)) (dash (2 16 0))) "Python specific evil text objects" single ((:commit . "39d22fc524f0413763f291267eaab7f4e7984318") (:authors ("Wouter Bolsterlee" . "wouter@bolsterl.ee")) (:maintainer "Wouter Bolsterlee" . "wouter@bolsterl.ee") (:keywords "convenience" "languages" "tools") (:url . "https://github.com/wbolster/evil-text-object-python"))])
+ (evil-textobj-anyblock . [(20170905 1907) ((cl-lib (0 5)) (evil (1 1 0))) "Textobject for the closest user-defined blocks." single ((:commit . "ff00980f0634f95bf2ad9956b615a155ea8743be") (:authors ("Fox Kiester" . "noct@openmailbox.org")) (:maintainer "Fox Kiester" . "noct@openmailbox.org") (:keywords "evil") (:url . "https://github.com/noctuid/evil-textobj-anyblock"))])
+ (evil-textobj-column . [(20170905 1905) ((names (0 5)) (emacs (24)) (evil (0))) "Provides column text objects." single ((:commit . "835d7036d0bc9a6e44fc9b7c54ccf2a7c01428cd") (:authors ("Fox Kiester" . "noct@openmailbox.org")) (:maintainer "Fox Kiester" . "noct@openmailbox.org") (:keywords "evil" "column" "text-object") (:url . "https://github.com/noctuid/evil-textobj-column"))])
+ (evil-textobj-entire . [(20150422 1254) ((emacs (24)) (evil (1 0 0))) "text object for entire lines of buffer for evil" single ((:commit . "5b3a98f3a69edc3a788f539f6ffef4a0ef5e853d") (:authors ("supermomonga")) (:maintainer "supermomonga") (:keywords "convenience" "emulations") (:url . "https://github.com/supermomonga/evil-textobj-entire"))])
+ (evil-textobj-line . [(20211101 1429) ((evil (1 0 0))) "Line text object for Evil" single ((:commit . "9eaf9a5485c2b5c05e16552b34632ca520cd681d") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com"))])
+ (evil-textobj-syntax . [(20181210 1213) ((names (0 5)) (emacs (24)) (evil (0))) "Provides syntax text objects." single ((:commit . "2d9ba8c75c754b409aea7469f46a5cfa52a872f3") (:keywords "evil" "syntax" "highlight" "text-object") (:url . "https://github.com/laishulu/evil-textobj-syntax"))])
+ (evil-textobj-tree-sitter . [(20220423 947) ((emacs (25 1)) (evil (1 0 0)) (tree-sitter (0 15 0))) "Provides evil textobjects using tree-sitter" tar ((:commit . "bfdef5a292f7dde36967bb86eb2f7009b03631b1") (:keywords "evil" "tree-sitter" "text-object" "convenience") (:url . "https://github.com/meain/evil-textobj-tree-sitter"))])
+ (evil-traces . [(20191214 558) ((emacs (25 1)) (evil (1 2 13))) "Visual hints for `evil-ex'" single ((:commit . "290b5323542c46af364ec485c8ec9000040acf90") (:authors ("Daniel Phan" . "daniel.phan36@gmail.com")) (:maintainer "Daniel Phan" . "daniel.phan36@gmail.com") (:keywords "emulations" "evil" "visual") (:url . "https://github.com/mamapanda/evil-traces"))])
+ (evil-tree-edit . [(20220425 2355) ((emacs (27 1)) (tree-edit (0 1 0)) (tree-sitter (0 15 0)) (evil (1 0 0)) (avy (0 5 0)) (s (0 0 0))) "Evil structural editing for any language!" tar ((:commit . "eafee31ca4f532a9dbee326d3ec3bdd1e997223b") (:authors ("Ethan Leba" . "ethanleba5@gmail.com")) (:maintainer "Ethan Leba" . "ethanleba5@gmail.com") (:url . "https://github.com/ethan-leba/tree-edit"))])
+ (evil-tutor . [(20150103 650) ((evil (1 0 9))) "Vimtutor adapted to Evil and wrapped in a major-mode" tar ((:commit . "4e124cd3911dc0d1b6817ad2c9e59b4753638f28") (:authors ("Sylvain Benner" . "sylvain.benner@gmail.com")) (:maintainer "Sylvain Benner" . "sylvain.benner@gmail.com") (:keywords "convenience" "editing" "evil") (:url . "https://github.com/syl20bnr/evil-tutor"))])
+ (evil-tutor-ja . [(20160917 132) ((evil (1 0 9)) (evil-tutor (0 1))) "Japanese Vimtutor adapted to Evil and wrapped in a major-mode" tar ((:commit . "99af7d82e02ce3bcdfaff47c5c80b57327a7ea8d") (:authors ("Kenji Miyazaki" . "kenjizmyzk@gmail.com")) (:maintainer "Kenji Miyazaki" . "kenjizmyzk@gmail.com") (:keywords "convenience" "editing" "evil" "japanese") (:url . "https://github.com/kenjimyzk/evil-tutor-ja"))])
+ (evil-vimish-fold . [(20200122 117) ((emacs (24 4)) (evil (1 0 0)) (vimish-fold (0 2 0))) "Integrate vimish-fold with evil" single ((:commit . "b6e0e6b91b8cd047e80debef1a536d9d49eef31a") (:authors ("Alex Murray" . "murray.alex@gmail.com")) (:maintainer "Alex Murray" . "murray.alex@gmail.com") (:url . "https://github.com/alexmurray/evil-vimish-fold"))])
+ (evil-visual-mark-mode . [(20190116 1557) ((evil (1 0 9)) (dash (2 10))) "Display evil marks on buffer" single ((:commit . "ac5997971972a9251f140b5542d82790ca4a43b4") (:authors ("Roman Gonzalez" . "romanandreg@gmail.com")) (:maintainer "Roman Gonzalez" . "romanandreg@gmail.com") (:keywords "evil"))])
+ (evil-visual-replace . [(20171016 613) ((evil (1 0 0))) "search/replace commands for evil visual state, inc. blocks" single ((:commit . "163fc827a1ffc106475da470c37fb26f4cc9b008") (:authors ("Troy Pracy")) (:maintainer "Troy Pracy") (:keywords "evil" "search" "replace" "regexp" "block" "rectangular" "region" "visual") (:url . "https://github.com/troyp/evil-visual-replace"))])
+ (evil-visualstar . [(20160223 48) ((evil (0))) "Starts a * or # search from the visual selection" single ((:commit . "06c053d8f7381f91c53311b1234872ca96ced752") (:authors ("Bailey Ling")) (:maintainer "Bailey Ling") (:keywords "evil" "vim" "visualstar") (:url . "https://github.com/bling/evil-visualstar"))])
+ (evm . [(20141007 1156) ((dash (2 3 0)) (f (0 13 0))) "Emacs Version Manager" single ((:commit . "d0623b2355436a5fd9f7238b419782080c79196b") (:authors ("Johan Andersson" . "johan.rejeep@gmail.com")) (:maintainer "Johan Andersson" . "johan.rejeep@gmail.com") (:url . "http://github.com/rejeep/evm"))])
+ (ewal . [(20200305 230) ((emacs (25 1))) "A pywal-based theme generator" tar ((:commit . "e2a04f5c97b7d5e087af26e646c0b45a24522e56") (:authors ("Uros Perisic")) (:maintainer "Uros Perisic") (:keywords "faces") (:url . "https://gitlab.com/jjzmajic/ewal"))])
+ (ewal-doom-themes . [(20200922 325) ((emacs (25)) (ewal (0 1)) (doom-themes (0 1))) "Dread the colors of darkness" tar ((:commit . "e2a04f5c97b7d5e087af26e646c0b45a24522e56") (:authors ("Uros Perisic")) (:maintainer "Uros Perisic") (:keywords "faces") (:url . "https://gitlab.com/jjzmajic/ewal"))])
+ (ewal-evil-cursors . [(20190911 1315) ((emacs (25)) (ewal (0 1))) "`ewal'-colored evil cursor for Emacs and Spacemacs" single ((:commit . "e2a04f5c97b7d5e087af26e646c0b45a24522e56") (:authors ("Uros Perisic")) (:maintainer "Uros Perisic") (:keywords "faces") (:url . "https://gitlab.com/jjzmajic/ewal"))])
+ (ewal-spacemacs-themes . [(20190911 1305) ((emacs (25)) (ewal (0 1)) (spacemacs-theme (0 1))) "Ride the rainbow spaceship" tar ((:commit . "e2a04f5c97b7d5e087af26e646c0b45a24522e56") (:authors ("Uros Perisic")) (:maintainer "Uros Perisic") (:keywords "faces") (:url . "https://gitlab.com/jjzmajic/ewal"))])
+ (ewmctrl . [(20170922 217) nil "Use `wmctrl' to manage desktop windows via EWMH/NetWM." single ((:commit . "3d0217c4d6cdb5c308b6cb4293574f470d4faacf") (:authors ("Alexis" . "flexibeast@gmail.com") ("Adam Plaice" . "plaice.adam@gmail.com")) (:maintainer "Alexis" . "flexibeast@gmail.com") (:keywords "desktop" "windows" "ewmh" "netwm") (:url . "https://github.com/flexibeast/ewmctrl"))])
+ (eww-lnum . [(20150102 1512) nil "Conkeror-like functionality for eww" single ((:commit . "4b0ecec769919ecb05ca4fb15ec51911ba589929") (:authors ("Andrey Kotlarski" . "m00naticus@gmail.com")) (:maintainer "Andrey Kotlarski" . "m00naticus@gmail.com") (:keywords "eww" "browse" "conkeror") (:url . "https://github.com/m00natic/eww-lnum"))])
+ (exato . [(20180305 1042) ((evil (1 2 13)) (emacs (24))) "EXATO: Evil XML/HTML Attributes Text Object" single ((:commit . "aee7af7b7a0e7551478f453d1de7d5b9cb2e06c4") (:authors ("Filipe Silva" . "filipe.silva@gmail.com")) (:maintainer "Filipe Silva" . "filipe.silva@gmail.com") (:url . "https://github.com/ninrod/exato"))])
+ (exec-path-from-shell . [(20210914 1247) ((emacs (24 1)) (cl-lib (0 6))) "Get environment variables such as $PATH from the shell" single ((:commit . "6336db9be13d46e2d4bc3b50bc37a3fbf30fdc9e") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:keywords "unix" "environment") (:url . "https://github.com/purcell/exec-path-from-shell"))])
+ (execline . [(20190711 2010) ((emacs (26 1)) (s (1 6 0))) "Major mode for editing execline scripts" single ((:commit . "c75dd9b2c54d8e59fc35fd4bd98d8e213948a3f5") (:authors ("Dmitry Bogatov" . "KAction@debian.org")) (:maintainer "Dmitry Bogatov" . "KAction@debian.org") (:keywords "tools" "unix" "languages") (:url . "https://gitlab.com/KAction/emacs-execline"))])
+ (exiftool . [(20190520 1106) ((emacs (25))) "Elisp wrapper around ExifTool" single ((:commit . "fc6713e753380f3034d8df55b7af3a737ea52ab4") (:authors ("Arun I" . "arunisaac@systemreboot.net")) (:maintainer "Arun I" . "arunisaac@systemreboot.net") (:keywords "data") (:url . "https://git.systemreboot.net/exiftool.el"))])
+ (exotica-theme . [(20180212 2329) ((emacs (24))) "A dark theme with vibrant colors" single ((:commit . "ff3ef4f6fa38c93b99becad977c7810c990a4d2f") (:authors ("Bharat Joshi" . "jbharat@outlook.com")) (:maintainer "Bharat Joshi" . "jbharat@outlook.com") (:keywords "faces" "theme" "dark" "vibrant colors") (:url . "https://github.com/jbharat/exotica-theme"))])
+ (expand-line . [(20151006 207) nil "Expand selection by line" single ((:commit . "75a5d0241f35dd0748ab8ecb4ff16891535be372") (:authors ("Kai Yu" . "yeannylam@gmail.com")) (:maintainer "Kai Yu" . "yeannylam@gmail.com"))])
+ (expand-region . [(20210708 1952) nil "Increase selected region by semantic units." tar ((:commit . "7e5bbe2763c12bae3e77fe0c49bcad05ff91dbfe") (:authors ("Magnar Sveen" . "magnars@gmail.com")) (:maintainer "Magnar Sveen" . "magnars@gmail.com") (:keywords "marking" "region"))])
+ (expenses . [(20220318 842) ((emacs (26 1)) (dash (2 19 1)) (ht (2 3))) "Record and view expenses" tar ((:commit . "e668666770858e92de83d8217c7e384de3ba1e34") (:authors ("Md Arif Shaikh" . "arifshaikh.astro@gmail.com")) (:maintainer "Md Arif Shaikh" . "arifshaikh.astro@gmail.com") (:keywords "expense tracking" "convenience") (:url . "https://github.com/md-arif-shaikh/expenses"))])
+ (express . [(20140508 2041) ((string-utils (0 3 2))) "Alternatives to `message'" single ((:commit . "93dae7377eace4a5413ba99aecb6f26f90798725") (:authors ("Roland Walker" . "walker@pobox.com")) (:maintainer "Roland Walker" . "walker@pobox.com") (:keywords "extensions" "message" "interface") (:url . "http://github.com/rolandwalker/express"))])
+ (exsqlaim-mode . [(20170607 1003) ((s (1 10 0))) "Use variables inside sql queries" single ((:commit . "a2e0a62ec8b87193d8eaa695774bfd689324b06c") (:authors ("Ahmad Nazir Raja" . "ahmadnazir@gmail.com")) (:maintainer "Ahmad Nazir Raja" . "ahmadnazir@gmail.com") (:url . "https://github.com/ahmadnazir/exsqlaim-mode"))])
+ (extempore-mode . [(20210512 2350) ((emacs (24 4))) "Emacs major mode for Extempore source files" single ((:commit . "eb2dee8860f3d761e949d7c2ee8e2e469ac1cf51") (:authors ("Ben Swift" . "ben@benswift.me")) (:maintainer "Ben Swift" . "ben@benswift.me") (:keywords "extempore") (:url . "http://github.com/extemporelang/extempore-emacs-mode"))])
+ (extend-dnd . [(20151122 1850) nil "R drag and Drop" tar ((:commit . "80c966c93b82c9bb5c6225a432557c39144fc602") (:authors ("Matthew L. Fidler")) (:maintainer "Matthew L. Fidler") (:keywords "extend" "drag and drop") (:url . "https://github.com/mlf176f2/extend-dnd"))])
+ (extmap . [(20211023 1904) ((emacs (24 1))) "Externally-stored constant mapping for Elisp" single ((:commit . "5875a4ab27831eb81af6246b12a174c765d52a78") (:authors ("Paul Pogonyshev" . "pogonyshev@gmail.com")) (:maintainer "Paul Pogonyshev" . "pogonyshev@gmail.com") (:keywords "lisp") (:url . "https://github.com/doublep/extmap"))])
+ (exunit . [(20211209 1012) ((s (1 11 0)) (emacs (24 3)) (f (0 20 0)) (transient (0 3 6))) "ExUnit test runner" single ((:commit . "0715c2dc2dca0b56c61330eda0690f90cca5f98b") (:authors ("Anantha kumaran" . "ananthakumaran@gmail.com")) (:maintainer "Anantha kumaran" . "ananthakumaran@gmail.com") (:keywords "processes" "elixir" "exunit") (:url . "http://github.com/ananthakumaran/exunit.el"))])
+ (exwm-edit . [(20220414 106) ((emacs (25 1))) "Edit mode for EXWM" single ((:commit . "b5b7e950f57e30befd68d51df34540b70e6ac28f") (:authors ("Ag Ibragimov")) (:maintainer "Ag Ibragimov") (:keywords "convenience") (:url . "https://github.com/agzam/exwm-edit"))])
+ (exwm-firefox-core . [(20190812 2110) ((emacs (24 4)) (exwm (0 16))) "Firefox hotkeys to functions" single ((:commit . "e2fe2a895e8f973307ef52f8c9976b26e701cbd0") (:authors ("Sebastian Wålinder" . "s.walinder@gmail.com")) (:maintainer "Sebastian Wålinder" . "s.walinder@gmail.com") (:keywords "extensions") (:url . "https://github.com/walseb/exwm-firefox-core"))])
+ (exwm-firefox-evil . [(20220318 1958) ((emacs (24 4)) (exwm (0 16)) (evil (1 0 0)) (exwm-firefox-core (1 0))) "evil-mode implementation of exwm-firefox-core" single ((:commit . "a377326e2e4ac386a0abb3fc9b1b356a0d955b61") (:authors ("Sebastian Wålinder" . "s.walinder@gmail.com")) (:maintainer "Sebastian Wålinder" . "s.walinder@gmail.com") (:keywords "extensions") (:url . "https://github.com/walseb/exwm-firefox-evil"))])
+ (exwm-float . [(20210207 2035) ((emacs (25 1)) (xelb (0 18)) (exwm (0 24)) (popwin (1 0 2))) "Convenient modes and bindings for floating EXWM frames" single ((:commit . "eb1b60b4a65e1ca5e323ef68a284ec6af72e637a") (:authors ("Mehmet Tekman")) (:maintainer "Mehmet Tekman") (:keywords "outlines") (:url . "https://gitlab.com/mtekman/exwm-float.el"))])
+ (exwm-mff . [(20210603 1723) ((emacs (25 1))) "Mouse Follows Focus" single ((:commit . "89206f2e3189f589c27c56bd2b6203e906ee7100") (:authors ("Ian Eure" . "public@lowbar.fyi")) (:maintainer "Ian Eure" . "public@lowbar.fyi") (:keywords "unix") (:url . "https://github.com/ieure/exwm-mff"))])
+ (exwm-modeline . [(20220131 1520) ((emacs (27 1)) (exwm (0 26))) "A modeline segment for EXWM workspaces" single ((:commit . "3225ec1803c3da9aee3f53562278c3558c179c26") (:authors ("Korytov Pavel" . "thexcloud@gmail.com")) (:maintainer "Korytov Pavel" . "thexcloud@gmail.com") (:url . "https://github.com/SqrtMinusOne/exwm-modeline"))])
+ (exwm-surf . [(20171204 1140) ((emacs (24 4)) (exwm (0 16))) "Interface for Surf (surf.suckless.org) under exwm" single ((:commit . "6c17e2c1597fe4b7b454a1dac23b9127ac951e94") (:authors ("Peter" . "craven@gmx.net")) (:maintainer "Peter" . "craven@gmx.net") (:keywords "extensions") (:url . "https://github.com/ecraven/exwm-surf"))])
+ (exwm-x . [(20210419 950) ((cl-lib (0 5)) (async (1 6)) (exwm (0 22))) "A derivative wm based on EXWM (emacs x window manager)" tar ((:commit . "2ab026f407b011a8e8380c889990e85e69cb3a4e") (:authors ("Feng Shu" . "tumashu@163.com")) (:maintainer "Feng Shu" . "tumashu@163.com") (:keywords "window-manager" "exwm") (:url . "https://github.com/tumashu/exwm-x"))])
+ (eyebrowse . [(20201107 955) ((dash (2 7 0)) (emacs (24 3 1))) "Easy window config switching" single ((:commit . "f7e129b84183367f54f0d0d3c9db8540f754bd8d") (:authors ("Vasilij Schneidermann" . "mail@vasilij.de")) (:maintainer "Vasilij Schneidermann" . "mail@vasilij.de") (:keywords "convenience") (:url . "https://depp.brause.cc/eyebrowse"))])
+ (eyuml . [(20141028 2227) ((request (0 2 0)) (s (1 8 0))) "Write textual uml diagram from emacs using yuml.me" single ((:commit . "eb29c37316e44a14741f16e894fbcfcb7537dc80") (:authors ("Anthony HAMON" . "hamon.anth@gmail.com")) (:maintainer "Anthony HAMON" . "hamon.anth@gmail.com") (:keywords "uml") (:url . "http://github.com/antham/eyuml"))])
+ (ez-query-replace . [(20210724 2247) ((dash (1 2 0)) (s (1 11 0))) "a smarter context-sensitive query-replace that can be reapplied" single ((:commit . "2b68472f4007a73908c3b242e83ac5a7587967ff") (:authors ("Wilfred Hughes" . "me@wilfred.me.uk")) (:maintainer "Wilfred Hughes" . "me@wilfred.me.uk"))])
+ (eziam-theme . [(20200327 1810) nil "A mostly monochrome theme, inspired by Tao and Leuven, with dark and light versions." tar ((:commit . "d7e517f8e626035df3b63ec6fc07b85d48a996c5"))])
+ (f . [(20220405 1534) ((s (1 7 0)) (dash (2 2 0))) "Modern API for working with files and directories" single ((:commit . "b5cb884b3b4372a6f3d1d4428cf092ca1e5c8044") (:authors ("Johan Andersson" . "johan.rejeep@gmail.com")) (:maintainer "Johan Andersson" . "johan.rejeep@gmail.com") (:keywords "files" "directories") (:url . "http://github.com/rejeep/f.el"))])
+ (f3 . [(20180130 1158) ((emacs (24 3)) (helm (2 8 8)) (cl-lib (0 5))) "a helm interface to find" tar ((:commit . "000009ce4adf7a57eae80512f29c4ec2a1391ce5") (:authors ("Danny McClanahan")) (:maintainer "Danny McClanahan") (:keywords "find" "file" "files" "helm" "fast" "finder") (:url . "https://github.com/cosmicexplorer/f3"))])
+ (fabric . [(20171116 656) nil "Launch Fabric using Emacs" tar ((:commit . "df79be341d0b34ed23850f9894136092fa5fea8c") (:authors ("Nicolas Lamirault" . "nicolas.lamirault@chmouel.com")) (:maintainer "Nicolas Lamirault" . "nicolas.lamirault@chmouel.com") (:keywords "python" "fabric") (:url . "https://github.com/nlamirault/fabric.el"))])
+ (face-explorer . [(20190517 1857) nil "Library and tools for faces and text properties" single ((:commit . "ad1300e13e5643e4c246cabfd91f833d39113052") (:authors ("Anders Lindgren")) (:maintainer "Anders Lindgren") (:keywords "faces") (:url . "https://github.com/Lindydancer/face-explorer"))])
+ (face-shift . [(20210725 2146) ((emacs (24 1))) "Shift the colour of certain faces" single ((:commit . "14dce79fc42116c49eb4c8a4ab7ca3c4bd7cbf6f") (:authors ("Philip Kaludercic" . "philipk@posteo.net")) (:maintainer "Philip Kaludercic" . "philipk@posteo.net") (:keywords "faces") (:url . "https://git.sr.ht/~pkal/face-shift"))])
+ (faceup . [(20170925 1946) nil "Markup language for faces and font-lock regression testing" single ((:commit . "6c92dad56a133e14e7b27831e1bcf9b3a71ff154") (:authors ("Anders Lindgren")) (:maintainer "Anders Lindgren") (:keywords "faces" "languages") (:url . "https://github.com/Lindydancer/faceup"))])
+ (factlog . [(20130210 140) ((deferred (0 3 1))) "File activity logger" single ((:commit . "6503d77ea882c995b051d22e72db336fb28770fc") (:authors ("Takafumi Arakaki <aka.tkf at gmail.com>")) (:maintainer "Takafumi Arakaki <aka.tkf at gmail.com>") (:url . "https://github.com/tkf/factlog"))])
+ (faff-theme . [(20220407 145) nil "Light Emacs color theme on cornsilk3 background" single ((:commit . "f824c3f55ea42d65e0b632879c6948d3eb43b2f3") (:authors ("James Ferguson <(concat \"wjcferguson\" at-sign \"gmail.com\")>")) (:maintainer "James Ferguson <(concat \"wjcferguson\" at-sign \"gmail.com\")>") (:keywords "color" "theme") (:url . "https://github.com/WJCFerguson/emacs-faff-theme"))])
+ (fakir . [(20140729 1652) ((noflet (0 0 8)) (dash (1 3 2)) (kv (0 0 19))) "fakeing bits of Emacs" single ((:commit . "1fca406ad7de80fece6319ff75d4230b648534b0") (:authors ("Nic Ferrier" . "nferrier@ferrier.me.uk")) (:maintainer "Nic Ferrier" . "nferrier@ferrier.me.uk") (:keywords "lisp" "tools") (:url . "http://github.com/nicferrier/emacs-fakir"))])
+ (fancy-battery . [(20150101 1204) ((emacs (24 1))) "Fancy battery display" single ((:commit . "9b88ae77a01aa3edc529840338bcb2db7f445822") (:authors ("Sebastian Wiesner" . "swiesner@lunaryorn.com")) (:maintainer "Sebastian Wiesner" . "swiesner@lunaryorn.com") (:keywords "convenience" "tools" "hardware") (:url . "https://github.com/lunaryorn/fancy-battery.el"))])
+ (fancy-dabbrev . [(20220211 633) ((emacs (25 1)) (popup (0 5 3))) "Like dabbrev-expand with preview and popup menu" single ((:commit . "cf4a2f7e3e43e07ab9aa9db16532a21010e9fc8c") (:authors ("Joel Rosdahl" . "joel@rosdahl.net")) (:maintainer "Joel Rosdahl" . "joel@rosdahl.net") (:url . "https://github.com/jrosdahl/fancy-dabbrev"))])
+ (fancy-narrow . [(20171031 16) nil "narrow-to-region with more eye candy." single ((:commit . "c9b3363752c09045b8ce7a2635afae42d2ae63c7") (:authors ("Artur Malabarba" . "bruce.connor.am@gmail.com")) (:maintainer "Artur Malabarba" . "bruce.connor.am@gmail.com") (:keywords "faces" "convenience") (:url . "http://github.com/Bruce-Connor/fancy-narrow"))])
+ (fantom-theme . [(20200328 604) ((emacs (24 1))) "Dark theme based on Phantom Code for VSCode" single ((:commit . "2c1c7fd53086c2ff86ee0961642c3b58e2343c08") (:authors ("Adam Svanberg")) (:maintainer "Adam Svanberg") (:url . "https://github.com/adsva/fantom-emacs-theme"))])
+ (fanyi . [(20220310 358) ((emacs (27 1)) (s (1 12 0))) "Not only English-Chinese translator" tar ((:commit . "b01cb24209d223ae0e7281c279daab87800ee7f4") (:authors ("Zhiwei Chen" . "condy0919@gmail.com")) (:maintainer "Zhiwei Chen" . "condy0919@gmail.com") (:keywords "convenience" "tools") (:url . "https://github.com/condy0919/fanyi.el"))])
+ (farmhouse-theme . [(20160713 2244) nil "Farmhouse Theme, Emacs edition" tar ((:commit . "7ddc1ff13b4a3d5466bd0d33ecb86100352e83a7"))])
+ (fasd . [(20210104 738) nil "Emacs integration for the command-line productivity booster `fasd'" single ((:commit . "c1d92553f33ebb018135c698db1a6d7f86731a26") (:authors ("steckerhalter")) (:maintainer "steckerhalter") (:keywords "cli" "bash" "zsh" "autojump") (:url . "https://framagit.org/steckerhalter/emacs-fasd"))])
+ (fast-scroll . [(20191016 327) ((emacs (25 1)) (cl-lib (0 6 1))) "Some utilities for faster scrolling over large buffers." single ((:commit . "3f6ca0d5556fe9795b74714304564f2295dcfa24") (:authors ("Matthew Carter" . "m@ahungry.com")) (:maintainer "Matthew Carter" . "m@ahungry.com") (:keywords "ahungry" "convenience" "fast" "scroll" "scrolling") (:url . "https://github.com/ahungry/fast-scroll"))])
+ (fastdef . [(20160713 1329) ((ivy (0 7 0)) (w3m (0 0))) "Insert terminology from Google top search results" single ((:commit . "0696f41dc150d35ce31fe8d2ea74f4173818bb55") (:authors ("Chen Bin <chenin DOT sh AT gmail DOT com>")) (:maintainer "Chen Bin <chenin DOT sh AT gmail DOT com>") (:keywords "terminology" "org-mode" "markdown") (:url . "http://github.com/redguardtoo/fastdef"))])
+ (fastnav . [(20120211 1457) nil "Fast navigation and editing routines." single ((:commit . "1019ba2b61d1a070204099b23da347278a61bc89") (:authors ("Zsolt Terek" . "zsolt@google.com")) (:maintainer "Zsolt Terek" . "zsolt@google.com") (:keywords "nav" "fast" "fastnav" "navigation"))])
+ (faust-mode . [(20201004 1353) nil "Faust syntax colorizer for Emacs." single ((:commit . "2a56cda14b152d5471f21a5d82f23c141dc7134c") (:authors ("rukano" . "rukano@gmail.com")) (:maintainer "Yassin Philip" . "xaccrocheur@gmail.com") (:keywords "languages" "faust") (:url . "https://github.com/rukano/emacs-faust-mode"))])
+ (faustine . [(20171122 1202) ((emacs (24 3)) (faust-mode (0 3))) "Edit, visualize, build and run Faust code" single ((:commit . "07a38963111518f86123802f9d477be0d4689a3f") (:authors ("Yassin Philip" . "xaccrocheur@gmail.com")) (:maintainer "Yassin Philip" . "xaccrocheur@gmail.com") (:keywords "languages" "faust") (:url . "https://bitbucket.org/yphil/faustine"))])
+ (fb2-reader . [(20211214 954) ((emacs (26 2)) (f (0 17)) (s (1 11 0)) (dash (2 12 0)) (visual-fill-column (2 2)) (async (1 9 4))) "Read FB2 and FB2.ZIP documents" single ((:commit . "9dcc0801a7dd302ee0620781ea17868895d3f082") (:authors ("Dmitriy Pshonko" . "jumper047@gmail.com")) (:maintainer "Dmitriy Pshonko" . "jumper047@gmail.com") (:keywords "multimedia" "ebook" "fb2") (:url . "https://github.com/jumper047/fb2-reader"))])
+ (fcitx . [(20190806 1923) nil "Make fcitx better in Emacs" single ((:commit . "12dc2638ddd15c8f6cfaecb20e1f428ab2bb5624") (:authors ("Junpeng Qiu" . "qjpchmail@gmail.com")) (:maintainer "Junpeng Qiu" . "qjpchmail@gmail.com") (:keywords "extensions") (:url . "https://github.com/cute-jumper/fcitx.el"))])
+ (fcopy . [(20150304 1403) nil "Funny Copy, set past point HERE then search copy text" single ((:commit . "e355f6ec889d8ecbdb096019c2dc660b1cec4941") (:authors ("Masayuki Ataka" . "masayuki.ataka@gmail.com")) (:maintainer "Masayuki Ataka" . "masayuki.ataka@gmail.com") (:keywords "convenience") (:url . "https://github.com/ataka/fcopy"))])
+ (fd-dired . [(20210723 549) ((emacs (25))) "find-dired alternative using fd" single ((:commit . "458464771bb220b6eb87ccfd4c985c436e57dc7e") (:authors ("Rashawn Zhang" . "namy.19@gmail.com")) (:maintainer "Rashawn Zhang" . "namy.19@gmail.com") (:keywords "tools" "fd" "find" "dired") (:url . "https://github.com/yqrashawn/fd-dired"))])
+ (feather . [(20200321 1237) ((emacs (26 3)) (async (1 9)) (async-await (1 0)) (ppp (1 0)) (page-break-lines (0 1))) "Parallel thread modern package manager" tar ((:commit . "3f19293dada8bf368e9f86f783610e7ca0a51ecb") (:authors ("Naoya Yamashita" . "conao3@gmail.com")) (:maintainer "Naoya Yamashita" . "conao3@gmail.com") (:keywords "convenience" "package") (:url . "https://github.com/conao3/feather.el"))])
+ (feature-mode . [(20220418 848) nil "Major mode for editing Gherkin (i.e. Cucumber) user stories" tar ((:commit . "e204d9e204b767cf95d6a051ff283f05dc51e9d3") (:authors ("Michael Klishin")) (:maintainer "Michael Klishin") (:url . "https://github.com/michaelklishin/cucumber.el"))])
+ (feebleline . [(20190822 1401) nil "Replace modeline with a slimmer proxy" single ((:commit . "b2f2db25cac77817bf0c49ea2cea6383556faea0") (:authors ("Benjamin Lindqvist" . "benjamin.lindqvist@gmail.com")) (:maintainer "Benjamin Lindqvist" . "benjamin.lindqvist@gmail.com") (:url . "https://github.com/tautologyclub/feebleline"))])
+ (feed-discovery . [(20200714 1118) ((emacs (25 1)) (dash (2 16 0))) "Discover feed url by RSS/Atom autodiscovery" single ((:commit . "12fcd1a28fe7c8c46c74e32f395ec631d45ec739") (:authors ("Hiroki YAMAKAWA" . "s06139@gmail.com")) (:maintainer "Hiroki YAMAKAWA" . "s06139@gmail.com") (:url . "https://github.com/HKey/feed-discovery"))])
+ (fennel-mode . [(20220429 1636) ((emacs (26 1))) "A major-mode for editing Fennel code" tar ((:commit . "90498bd9c8dac2749baaddb605d35370aa79ba15") (:authors ("Phil Hagelberg")) (:maintainer "Phil Hagelberg") (:keywords "languages" "tools") (:url . "https://git.sr.ht/~technomancy/fennel-mode"))])
+ (fetch . [(20131201 730) nil "Fetch and unpack resources" single ((:commit . "3f2793afcbbc32f320e572453166f9354ecc6d06") (:authors ("Christian 'crshd' Brassat" . "christian.brassat@gmail.com")) (:maintainer "Christian 'crshd' Brassat" . "christian.brassat@gmail.com") (:url . "https://github.com/crshd/fetch.el"))])
+ (ffmpeg-player . [(20200720 1028) ((emacs (24 4)) (s (1 12 0)) (f (0 20 0))) "Play video using ffmpeg" single ((:commit . "d81983cf389dd5d2ec6cf9d702ff28ffd1be676b") (:authors ("Shen, Jen-Chieh" . "jcs090218@gmail.com")) (:maintainer "Shen, Jen-Chieh" . "jcs090218@gmail.com") (:url . "https://github.com/jcs-elpa/ffmpeg-player"))])
+ (fic-mode . [(20180603 2035) nil "Show FIXME/TODO/BUG(...) in special face only in comments and strings" single ((:commit . "a05fc36ed54ba0c6dc22ac216a6a72cf191ca13d") (:url . "https://github.com/lewang/fic-mode"))])
+ (fifo-class . [(20160425 558) nil "First in first out abstract class" single ((:commit . "8fe4cf690727f4ac7b67f29c55f845df023c3f21") (:authors ("Mola-T" . "Mola@molamola.xyz")) (:maintainer "Mola-T" . "Mola@molamola.xyz") (:keywords "lisp") (:url . "https://github.com/mola-T/fifo-class"))])
+ (figlet . [(20160218 2237) nil "Annoy people with big, ascii art text" single ((:commit . "19a38783a90e151faf047ff233a21a729db0cea9") (:authors ("Philip Jackson" . "phil@shellarchive.co.uk")) (:maintainer "Philip Jackson" . "phil@shellarchive.co.uk"))])
+ (filelock . [(20180524 2215) ((emacs (24)) (cl-lib (0)) (f (0))) "Functions for manipulating file locks" single ((:commit . "17a5ca6e0dee14d2e7d92c84be91143bca9d9663") (:authors ("Ryan C. Thompson")) (:maintainer "Ryan C. Thompson") (:keywords "extensions" "files" "tools") (:url . "https://github.com/DarwinAwardWinner/emacs-filelock"))])
+ (filetags . [(20190706 804) ((emacs (24 4))) "Package to manage filetags in filename" single ((:commit . "01e6a919507a832ee001a2a0fc257657f8b04b72") (:authors ("Max Beutelspacher")) (:maintainer "Max Beutelspacher") (:keywords "convenience" "files") (:url . "https://github.com/DerBeutlin/filetags.el"))])
+ (filetree . [(20220312 1650) ((dash (2 12 0)) (helm (3 7 0)) (seq (2 23)) (transient (0 3 6))) "File tree view/manipulatation package" single ((:commit . "9125e5b7ebbb99b8c007018fcfd5034e7ac6630d") (:authors ("Ketan Patel" . "knpatel401@gmail.com")) (:maintainer "Ketan Patel" . "knpatel401@gmail.com") (:url . "https://github.com/knpatel401/filetree"))])
+ (fill-column-indicator . [(20200806 2239) nil "Graphically indicate the fill column" single ((:commit . "c35f9de072c241699b57bcb46da84bed5af29cfe") (:authors ("Alp Aker" . "alp.tekin.aker@gmail.com")) (:maintainer "Alp Aker" . "alp.tekin.aker@gmail.com") (:keywords "convenience"))])
+ (fill-function-arguments . [(20201223 819) ((emacs (24 4))) "Convert function arguments to/from single line" single ((:commit . "a0a2f8538c80ac08e497dea784fcb90c93ab465b") (:authors ("David Shepherd" . "davidshepherd7@gmail.com")) (:maintainer "David Shepherd" . "davidshepherd7@gmail.com") (:keywords "convenience") (:url . "https://github.com/davidshepherd7/fill-function-arguments"))])
+ (fill-page . [(20210707 354) ((emacs (24 4))) "Fill buffer so you don't see empty lines at the end" single ((:commit . "02ab2b3854df5515245ca2a924f89bf830f9c4de") (:authors ("Shen, Jen-Chieh" . "jcs090218@gmail.com")) (:maintainer "Shen, Jen-Chieh" . "jcs090218@gmail.com") (:url . "https://github.com/jcs-elpa/fill-page"))])
+ (fillcode . [(20200524 2226) nil "Fill (wrap) function calls and expressions in source code" single ((:commit . "501468082e46bd0975ef4d8765363fd564338099") (:authors ("Ryan Barrett" . "fillcode@ryanb.org")) (:maintainer "Ryan Barrett" . "fillcode@ryanb.org") (:url . "https://snarfed.org/fillcode"))])
+ (filldent . [(20220423 2216) ((emacs (24 1))) "Fill or indent" single ((:commit . "2f32e0cf5e27c613f962fa41bf3427bbdc04e6c0") (:authors ("Case Duckworth" . "acdw@acdw.net")) (:maintainer "Case Duckworth" . "acdw@acdw.net") (:url . "https://github.com/duckwork/filldent.el"))])
+ (finalize . [(20170418 1945) ((emacs (24 1)) (cl-generic (0 3)) (cl-lib (0 3)) (eieio (1 4))) "finalizers for Emacs Lisp" tar ((:commit . "846731531e7d1d80451787992e07bfe7dedbe9ff") (:authors ("Christopher Wellons" . "wellons@nullprogram.com")) (:maintainer "Christopher Wellons" . "wellons@nullprogram.com") (:url . "https://github.com/skeeto/elisp-finalize"))])
+ (find-by-pinyin-dired . [(20180210 218) ((pinyinlib (0 1 0))) "Find file by first PinYin character of Chinese Hanzi" single ((:commit . "3b4781148dddc84a701ad76c0934ed991ecd59d5") (:authors ("Chen Bin" . "chenbin.sh@gmail.com")) (:maintainer "Chen Bin" . "chenbin.sh@gmail.com") (:keywords "hanzi" "chinese" "dired" "find" "file" "pinyin") (:url . "http://github.com/redguardtoo/find-by-pinyin-dired"))])
+ (find-dupes-dired . [(20210426 835) ((emacs (26 1))) "Find dupes and handle in dired" single ((:commit . "904225a3f89bbd3b44ea097a282ec6ca7945f7f1") (:authors ("Shuguang Sun" . "shuguang79@qq.com")) (:maintainer "Shuguang Sun" . "shuguang79@qq.com") (:keywords "tools") (:url . "https://github.com/ShuguangSun/find-dupes-dired"))])
+ (find-file-in-project . [(20220430 107) ((emacs (25 1))) "Find file/directory and review Diff/Patch/Commit efficiently" single ((:commit . "116b976b526680c038109882d5cd2d9f218b62a5") (:authors ("Phil Hagelberg, Doug Alcorn, and Will Farrington")) (:maintainer "Chen Bin" . "chenbin.sh@gmail.com") (:keywords "project" "convenience") (:url . "https://github.com/redguardtoo/find-file-in-project"))])
+ (find-file-in-repository . [(20210301 2202) nil "Quickly find files in a git, mercurial or other repository" single ((:commit . "10f5bd919ce35691addc5ce0d281597a46813a79") (:authors ("Samuel Hoffstaetter" . "samuel@hoffstaetter.com")) (:maintainer "Samuel Hoffstaetter" . "samuel@hoffstaetter.com") (:keywords "files" "convenience" "repository" "project" "source control") (:url . "https://github.com/hoffstaetter/find-file-in-repository"))])
+ (find-file-rg . [(20220314 1540) ((emacs (25 1))) "Find file in project using ripgrep" single ((:commit . "404b1cc97c2f700d3dc1c66b640f96ed5a268dc3") (:authors ("Andrii Kolomoiets" . "andreyk.mad@gmail.com")) (:maintainer "Andrii Kolomoiets" . "andreyk.mad@gmail.com") (:keywords "tools") (:url . "https://github.com/muffinmad/emacs-find-file-rg"))])
+ (find-temp-file . [(20200117 2254) nil "Open quickly a temporary file" single ((:commit . "2bfcdba0d6a8a0e6faa080cb04ff0f7ed06491ba") (:authors ("Sylvain Rousseau <thisirs at gmail dot com>")) (:maintainer "Sylvain Rousseau <thisirs at gmail dot com>") (:keywords "convenience") (:url . "https://github.com/thisirs/find-temp-file.git"))])
+ (find-things-fast . [(20150519 2226) nil "Find things fast, leveraging the power of git" single ((:commit . "efc7c189019ed65430e2f9e910e8e0a5ca9d2d03") (:authors ("Elvio Toccalino and Elliot Glaysher and Phil Hagelberg and Doug Alcorn")) (:maintainer "Elvio Toccalino and Elliot Glaysher and Phil Hagelberg and Doug Alcorn") (:keywords "project" "convenience"))])
+ (findr . [(20130127 2032) nil "Breadth-first file-finding facility for (X)Emacs" single ((:commit . "1ddbc0464bb05dcda392b62666ad17239a2152d3") (:authors ("David Bakhash" . "cadet@bu.edu")) (:maintainer "David Bakhash" . "cadet@bu.edu") (:keywords "files"))])
+ (fingers . [(20160817 829) nil "Modal editing with universal text manipulation helpers." tar ((:commit . "fed0f742afb1d72eaef29d8da394467550a030fa") (:authors ("Felix Geller" . "fgeller@gmail.com")) (:maintainer "Felix Geller" . "fgeller@gmail.com") (:keywords "fingers" "modal" "editing" "workman") (:url . "http://github.com/fgeller/fingers.el"))])
+ (finito . [(20220427 1932) ((emacs (27 1)) (dash (2 17 0)) (request (0 3 2)) (f (0 2 0)) (s (1 12 0)) (transient (0 3 0)) (graphql (0 1 1)) (async (1 9 3))) "View and collect books" tar ((:commit . "a0fe025086046aecf5490c993afe9e716324f7e5") (:authors ("Laurence Warne")) (:maintainer "Laurence Warne") (:keywords "outlines") (:url . "https://github.com/LaurenceWarne/finito.el"))])
+ (fiplr . [(20140724 645) ((grizzl (0 1 0)) (cl-lib (0 1))) "Fuzzy Search for Files in Projects" tar ((:commit . "3f50159fd42125440d5b0eb9d6398560461f030b") (:authors ("Chris Corbyn" . "chris@w3style.co.uk")) (:maintainer "Chris Corbyn" . "chris@w3style.co.uk") (:keywords "convenience" "usability" "project") (:url . "https://github.com/d11wtq/fiplr"))])
+ (fira-code-mode . [(20210702 1631) ((emacs (24 4))) "Minor mode for Fira Code ligatures using prettify-symbols" single ((:commit . "eaff81f867d9c84e25891368f3d0cac7513984e8") (:authors ("Jonathan Ming" . "jming422@gmail.com")) (:maintainer "Jonathan Ming" . "jming422@gmail.com") (:keywords "faces" "ligatures" "fonts" "programming-ligatures") (:url . "https://github.com/jming422/fira-code-mode"))])
+ (firecode-theme . [(20170808 1311) ((emacs (24 0))) "an Emacs 24 theme based on FireCode (tmTheme)" single ((:commit . "8b7b03ecdd41e70dab145b98906017e1392eaef4") (:authors ("Jason Milkins")) (:maintainer "Jason Milkins") (:url . "https://github.com/emacsfodder/tmtheme-to-deftheme"))])
+ (fireplace . [(20200402 2206) nil "A cozy fireplace for emacs" single ((:commit . "f6c23e259349922aae25cf2898ba815a7d8f2527") (:authors ("Johan Sivertsen" . "johanvts@gmail.com")) (:maintainer "Johan Sivertsen" . "johanvts@gmail.com") (:keywords "games") (:url . "https://github.com/johanvts/emacs-fireplace"))])
+ (firestarter . [(20210508 1626) ((emacs (24 1))) "Execute (shell) commands on save" single ((:commit . "76070c9074aa363350abe6ad06143e90b3e12ab1") (:authors ("Vasilij Schneidermann" . "mail@vasilij.de")) (:maintainer "Vasilij Schneidermann" . "mail@vasilij.de") (:keywords "convenience") (:url . "https://depp.brause.cc/firestarter"))])
+ (firrtl-mode . [(20200329 2002) ((emacs (24 3))) "mode for working with FIRRTL files" single ((:commit . "fa40141411a876ce7a1a9d6d3fe47134bc1fa954") (:authors ("Schuyler Eldridge" . "schuyler.eldridge@ibm.com")) (:maintainer "Schuyler Eldridge" . "schuyler.eldridge@ibm.com") (:keywords "languages" "firrtl") (:url . "https://github.com/ibm/firrtl-mode"))])
+ (fish-completion . [(20191103 1210) ((emacs (25 1))) "Fish completion for pcomplete (shell and Eshell)" single ((:commit . "10384881817b5ae38cf6197a077a663420090d2c") (:authors ("Pierre Neidhardt" . "mail@ambrevar.xyz")) (:maintainer "Pierre Neidhardt" . "mail@ambrevar.xyz") (:url . "https://gitlab.com/Ambrevar/emacs-fish-completion"))])
+ (fish-mode . [(20220505 1111) ((emacs (24))) "Major mode for fish shell scripts" single ((:commit . "d04478c0aba018cb789d77d591bfe315cb25132a") (:authors ("Tony Wang" . "wwwjfy@gmail.com")) (:maintainer "Tony Wang" . "wwwjfy@gmail.com") (:keywords "fish" "shell"))])
+ (fit-text-scale . [(20211230 2002) ((emacs (25 1))) "Fit text by scaling" single ((:commit . "c53c8ce606380088643463848a9ee3502b0c64f4") (:authors ("Marco Wahl" . "marcowahlsoft@gmail.com")) (:maintainer "Marco Wahl" . "marcowahlsoft@gmail.com") (:keywords "convenience") (:url . "https://gitlab.com/marcowahl/fit-text-scale"))])
+ (fix-input . [(20210320 1244) ((emacs (24 4))) "Make input methods play nicely with alternative keyboard layout on OS level" single ((:commit . "b611a8b269d28d226ed1e78fcc7a3120df20f74c") (:authors ("Mark Karpov" . "markkarpov92@gmail.com")) (:maintainer "Mark Karpov" . "markkarpov92@gmail.com") (:keywords "input" "method") (:url . "https://github.com/mrkkrp/fix-input"))])
+ (fix-muscle-memory . [(20210702 1755) nil "Simple hacks to fix muscle memory problems" single ((:commit . "b8d4b8025d758762f4459c70c3a7a209ead865ed") (:authors ("Jonathan Arkell" . "jonnay@jonnay.net")) (:maintainer "Jonathan Arkell" . "jonnay@jonnay.net") (:keywords "spelling" "typing"))])
+ (fix-word . [(20210319 1414) ((emacs (24 1)) (cl-lib (0 5))) "Convenient word transformation" single ((:commit . "e967dd4ac98d777deeede8b497d6337634c06df4") (:authors ("Mark Karpov" . "markkarpov92@gmail.com")) (:maintainer "Mark Karpov" . "markkarpov92@gmail.com") (:keywords "word" "convenience") (:url . "https://github.com/mrkkrp/fix-word"))])
+ (fixmee . [(20150223 1355) ((button-lock (1 0 2)) (nav-flash (1 0 0)) (back-button (0 6 0)) (smartrep (0 0 3)) (string-utils (0 3 2)) (tabulated-list (0))) "Quickly navigate to FIXME notices in code" single ((:commit . "5cddb64e0d52635e9a1529d80cb5cefa6f829341") (:authors ("Roland Walker" . "walker@pobox.com")) (:maintainer "Roland Walker" . "walker@pobox.com") (:keywords "navigation" "convenience") (:url . "http://github.com/rolandwalker/fixmee"))])
+ (flame . [(20180303 2016) ((emacs (24))) "automatic generation of flamage, as if we needed more." single ((:commit . "a749b2a77b87e505572d0f1f5d59fac76348bb73") (:authors ("Ian G. Batten" . "batten@uk.ac.bham.multics") ("Noah Friedman" . "friedman@splode.com")) (:maintainer "Noah Friedman" . "friedman@splode.com") (:keywords "games") (:url . "https://github.com/mschuldt/flame"))])
+ (flames-of-freedom . [(20191202 1637) ((emacs (25 1))) "The flames of freedom" single ((:commit . "5e47ff27cfa2f7c06081be2ffefe91a731efd012") (:authors ("Stéphane Champailler" . "schampailler@skynet.be")) (:maintainer "Stéphane Champailler" . "schampailler@skynet.be") (:keywords "multimedia") (:url . "https://github.com/wiz21b/FlamesOfFreedom"))])
+ (flappymacs . [(20171023 1004) nil "flappybird clone for emacs" single ((:commit . "27f3e21acb22f786606481e3f4e5dc1edbaaaed4") (:authors ("Takayuki Sato")) (:maintainer "Takayuki Sato") (:keywords "games") (:url . "https://github.com/taksatou/flappymacs"))])
+ (flash-region . [(20130923 1817) nil "Flash a region" single ((:commit . "261b3597b23cdd40e5c14262a5687bcc6c1d0901") (:authors ("Matus Goljer" . "matus.goljer@gmail.com")) (:maintainer "Matus Goljer" . "matus.goljer@gmail.com") (:keywords "utility"))])
+ (flatbuffers-mode . [(20210710 1004) ((emacs (24 3))) "Major mode for editing flatbuffers" single ((:commit . "8e7783db45a64c9456130fd0c108ac12d45a7789") (:authors ("Asal Mirzaieva" . "asalle.kim@gmail.com")) (:maintainer "Asal Mirzaieva" . "asalle.kim@gmail.com") (:keywords "flatbuffers" "languages") (:url . "https://github.com/Asalle/flatbuffers-mode"))])
+ (flatfluc-theme . [(20210908 1423) ((emacs (26 1))) "Custom merge of flucui and flatui themes" single ((:commit . "33726cd072ad83c6943e1c3b83db2fff60f324ce") (:authors ("Sébastien Le Maguer" . "lemagues@tcd.ie")) (:maintainer "Sébastien Le Maguer" . "lemagues@tcd.ie") (:keywords "lisp") (:url . "https://github.com/seblemaguer/flatfluc-theme"))])
+ (flatland-black-theme . [(20170808 1312) ((emacs (24 0))) "an Emacs 24 theme based on Flatland Black (tmTheme)" single ((:commit . "348c5d5fe615e6ea13cadc17f046e506e789ce07") (:authors ("Jason Milkins")) (:maintainer "Jason Milkins") (:url . "https://github.com/emacsfodder/flatland-black-theme"))])
+ (flatland-theme . [(20171113 1521) nil "A simple theme for Emacs based on the Flatland theme for Sublime Text" single ((:commit . "a98a6f19ad4dff0fa3fad1ea487b7d0ef634a19a") (:authors ("Greg Chapple" . "info@gregchapple.com")) (:maintainer "Greg Chapple" . "info@gregchapple.com") (:url . "http://github.com/gregchapple/flatland-emacs"))])
+ (flatui-dark-theme . [(20170513 1422) ((emacs (24))) "Dark color theme with colors from https://flatuicolors.com/" single ((:commit . "5b959a9f743f891e4660b1b432086417947872ea") (:authors ("Andrew Phillips" . "theasp@gmail.com")) (:maintainer "Andrew Phillips" . "theasp@gmail.com") (:keywords "color" "theme" "dark" "flatui" "faces") (:url . "https://github.com/theasp/flatui-dark-theme"))])
+ (flatui-theme . [(20160619 127) nil "A color theme for Emacs based on flatuicolors.com" single ((:commit . "9c15db5526c15c8dba55023f5698372b19c2a780") (:authors ("John Louis Del Rosario" . "john2x@gmail.com")) (:maintainer "John Louis Del Rosario" . "john2x@gmail.com") (:url . "https://github.com/john2x/flatui-theme.el"))])
+ (flex-autopair . [(20120809 1218) nil "Automatically insert pair braces and quotes, insertion conditions & actions are highly customizable." single ((:commit . "4bb757f2556a4a51828e2fed8fb81e31e83052cb") (:authors ("Yuuki Arisawa" . "yuuki.ari@gmail.com")) (:maintainer "Yuuki Arisawa" . "yuuki.ari@gmail.com") (:keywords "keyboard" "input") (:url . "https://github.com/uk-ar/flex-autopair.el"))])
+ (flex-compile . [(20220205 205) ((emacs (26 1)) (dash (2 17 0)) (buffer-manage (1 1))) "Run, evaluate and compile across many languages" tar ((:commit . "2da0e5e791896810747c710276ff3a1d0465d843") (:authors ("Paul Landes")) (:maintainer "Paul Landes") (:keywords "compilation" "integration" "processes") (:url . "https://github.com/plandes/flex-compile"))])
+ (flex-isearch . [(20170308 2010) nil "Flex matching (like ido) in isearch." single ((:commit . "b1f7e04de762282c276343cc2709af9ff4abc9d2") (:authors ("Jonathan Kotta" . "jpkotta@gmail.com")) (:maintainer "Jonathan Kotta" . "jpkotta@gmail.com") (:keywords "convenience" "search") (:url . "https://bitbucket.org/jpkotta/flex-isearch"))])
+ (flim . [(20220503 1442) ((emacs (24 5)) (apel (10 8)) (oauth2 (0 11))) "A library to provide basic features about message representation or encoding." tar ((:commit . "289e5bbd66f6f14306a6e0b922ee8f26267e2470"))])
+ (flimenu . [(20200810 1510) ((emacs (24 4))) "Flatten imenu automatically" single ((:commit . "4c0ff37cf3bd6c836bd136b5f6c450560a6c92b9") (:authors ("Ivan Malison" . "IvanMalison@gmail.com")) (:maintainer "Ivan Malison" . "IvanMalison@gmail.com") (:keywords "imenu" "browse" "structure" "hook" "mode" "matching" "tools" "convenience" "files") (:url . "https://github.com/IvanMalison/flimenu"))])
+ (fliptext . [(20171124 2056) nil "Input method for flipping characters upside down" single ((:commit . "fd821f645ffebae6ae3894afa7ba7fc06f91afc6") (:authors ("André Riemann" . "andre.riemann@web.de")) (:maintainer "André Riemann" . "andre.riemann@web.de") (:keywords "games" "i18n"))])
+ (floobits . [(20211018 550) ((json (1 2)) (highlight (0))) "Floobits plugin for real-time collaborative editing" tar ((:commit . "93b3317fb6c842efe165e54c8a32bf51d436837d") (:authors ("Matt Kaniaris") ("Geoff Greer")) (:maintainer "Matt Kaniaris") (:keywords "comm" "tools") (:url . "http://github.com/Floobits/floobits-emacs"))])
+ (flow-js2-mode . [(20191213 1004) ((flow-minor-mode (0)) (js2-mode (0)) (emacs (25 1))) "Support for flow annotations in js2-mode" single ((:commit . "7520bdda70287e8d57b3f41033b1e0ca59a3be95") (:authors ("Matúš Goljer" . "matus.goljer@gmail.com")) (:maintainer "Matúš Goljer" . "matus.goljer@gmail.com") (:keywords "languages" "extensions"))])
+ (flow-minor-mode . [(20200905 1730) ((emacs (25 1))) "Flow type mode based on web-mode." single ((:commit . "804217a15a28f6918fba93c91d495ed7d50b0495") (:url . "https://github.com/an-sh/flow-minor-mode"))])
+ (flower . [(20220416 1744) ((emacs (24 4)) (clomacs (0 0 4))) "Emacs task tracker client." tar ((:commit . "047846409867b2dd0ba4e2047a414b498680cd9c") (:authors ("Sergey Sobko" . "flower@tpg.am")) (:maintainer "Sergey Sobko" . "flower@tpg.am") (:keywords "hypermedia" "outlines" "tools" "vc") (:url . "https://github.com/FlowerAutomation/flower"))])
+ (flucui-themes . [(20200815 2103) ((emacs (24))) "Custom theme inspired by the Flat UI palette" tar ((:commit . "6591b5093e6e8f0e720e3995a16a91835b2e7a48") (:authors ("MetroWind" . "chris.corsair@gmail.com")) (:maintainer "MetroWind" . "chris.corsair@gmail.com") (:keywords "lisp") (:url . "https://github.com/MetroWind/flucui-theme"))])
+ (flutter . [(20220502 50) ((emacs (25 1))) "Tools for working with Flutter SDK" tar ((:commit . "e49cbcb70235fa39a7d243521e03ad874451a39a") (:authors ("Aaron Madlon-Kay")) (:maintainer "Aaron Madlon-Kay") (:keywords "languages") (:url . "https://github.com/amake/flutter.el"))])
+ (flutter-l10n-flycheck . [(20220502 50) ((emacs (25 1)) (flycheck (30)) (flutter (0 1 0))) "Flycheck checker for intl_translation" single ((:commit . "e49cbcb70235fa39a7d243521e03ad874451a39a") (:authors ("Aaron Madlon-Kay")) (:maintainer "Aaron Madlon-Kay") (:keywords "languages") (:url . "https://github.com/amake/flutter.el"))])
+ (fluxus-mode . [(20210715 58) ((osc (0 1)) (emacs (24 4))) "Major mode for interfacing with Fluxus" single ((:commit . "a14578640c578a4fd09cb7e25da1e87d637719ae") (:authors ("modula t." . "defaultxr@gmail.com")) (:maintainer "modula t." . "defaultxr@gmail.com") (:keywords "languages") (:url . "https://github.com/defaultxr/fluxus-mode"))])
+ (flx . [(20211101 146) ((cl-lib (0 3))) "fuzzy matching with good sorting" single ((:commit . "e3b3f0533e44c5250ce73d728b59a7e96c692b5d") (:authors ("Le Wang")) (:maintainer "Le Wang") (:url . "https://github.com/lewang/flx"))])
+ (flx-ido . [(20180117 1519) ((flx (0 1)) (cl-lib (0 3))) "flx integration for ido" single ((:commit . "e3b3f0533e44c5250ce73d728b59a7e96c692b5d") (:authors ("Le Wang")) (:maintainer "Le Wang") (:url . "https://github.com/lewang/flx"))])
+ (flx-isearch . [(20191119 515) ((emacs (24)) (flx (20140821)) (cl-lib (0 5))) "Fuzzy incremental searching for emacs" single ((:commit . "a44097fb8f539a193c2f09a37ea52a68f2c51839") (:authors ("PythonNut" . "pythonnut@pythonnut.com")) (:maintainer "PythonNut" . "pythonnut@pythonnut.com") (:keywords "convenience" "search" "flx") (:url . "https://github.com/pythonnut/flx-isearch"))])
+ (flycheck . [(20220504 830) ((dash (2 12 1)) (pkg-info (0 4)) (let-alist (1 0 4)) (seq (1 11)) (emacs (24 3))) "On-the-fly syntax checking" tar ((:commit . "1d7c1b20782ccbaa6f97e37f5e1d0cee3d5eda8a") (:authors ("Sebastian Wiesner" . "swiesner@lunaryorn.com")) (:maintainer "Clément Pit-Claudel" . "clement.pitclaudel@live.com") (:keywords "convenience" "languages" "tools") (:url . "http://www.flycheck.org"))])
+ (flycheck-ameba . [(20191226 1011) ((emacs (24 4)) (flycheck (30))) "Add support for Ameba to Flycheck" single ((:commit . "0c4925ae0e998818326adcb47ed27ddf9761c7dc") (:keywords "tools" "crystal" "ameba") (:url . "https://github.com/crystal-ameba/ameba.el"))])
+ (flycheck-apertium . [(20181211 1038) ((flycheck (0 25))) "Apertium checkers in flycheck" tar ((:commit . "22b60a17836477ac1edd15dc85b14f88ca871ba9") (:authors ("Kevin Brubeck Unhammer" . "unhammer+apertium@mm.st")) (:maintainer "Kevin Brubeck Unhammer" . "unhammer+apertium@mm.st") (:keywords "convenience" "tools" "xml") (:url . "http://wiki.apertium.org/wiki/Emacs"))])
+ (flycheck-aspell . [(20220411 826) ((flycheck (28 0)) (emacs (25 1))) "Aspell checker for flycheck" single ((:commit . "dcf7e6543e4d94d58375e00e4a10db615ef06941") (:authors ("Leo Gaskin" . "leo.gaskin@le0.gs")) (:maintainer "Leo Gaskin" . "leo.gaskin@le0.gs") (:keywords "wp" "flycheck" "spell" "aspell") (:url . "https://github.com/leotaku/flycheck-aspell"))])
+ (flycheck-ats2 . [(20170225 1636) ((emacs (24 1)) (flycheck (0 22))) "Flycheck: ATS2 support" single ((:commit . "9f77add8408462af35bdddf87e37a661880255e3") (:authors ("Mark Laws" . "mdl@60hz.org")) (:maintainer "Mark Laws" . "mdl@60hz.org") (:keywords "convenience" "tools" "languages") (:url . "http://github.com/drvink/flycheck-ats2"))])
+ (flycheck-bashate . [(20200625 642) ((flycheck (0 24)) (emacs (24 4))) "Integrate bashate with flycheck" single ((:commit . "5e673c591d017329d0a07a61dc1223fa98639ee2") (:authors ("Alex Murray" . "murray.alex@gmail.com")) (:maintainer "Alex Murray" . "murray.alex@gmail.com") (:url . "https://github.com/alexmurray/flycheck-bashate"))])
+ (flycheck-cask . [(20200926 1502) ((emacs (24 3)) (flycheck (0 14)) (dash (2 4 0))) "Cask support in Flycheck" single ((:commit . "4b2ede6362ded4a45678dfbef1876faa42edbd58") (:authors ("Sebastian Wiesner" . "swiesner@lunaryorn.com")) (:maintainer "Sebastian Wiesner" . "swiesner@lunaryorn.com") (:keywords "tools" "convenience") (:url . "https://github.com/flycheck/flycheck-cask"))])
+ (flycheck-cfn . [(20220221 1029) ((emacs (26 1)) (flycheck (31))) "Flycheck backend for AWS cloudformation" single ((:commit . "4cf56affe3035fda364109836e26499431095185") (:authors ("William Orr" . "will@worrbase.com")) (:maintainer "William Orr" . "will@worrbase.com") (:keywords "convenience") (:url . "https://gitlab.com/worr/cfn-mode"))])
+ (flycheck-checkbashisms . [(20190403 218) ((emacs (24)) (flycheck (0 25))) "checkbashisms checker for flycheck" single ((:commit . "53598158fa8b74d2e7efea6210edb274e1f0273c") (:authors ("Cuong Le" . "cuong.manhle.vn@gmail.com")) (:maintainer "Cuong Le" . "cuong.manhle.vn@gmail.com") (:keywords "convenience" "tools" "sh" "unix") (:url . "https://github.com/cuonglm/flycheck-checkbashisms"))])
+ (flycheck-checkpatch . [(20170217 1025) ((emacs (25)) (flycheck (30))) "Flycheck support for checkpatch.pl tool" single ((:commit . "6461fc7b0d493eb9863814055f8bce5fa35739de") (:authors ("Alexander Yarygin" . "yarygin.alexander@gmail.com")) (:maintainer "Alexander Yarygin" . "yarygin.alexander@gmail.com") (:url . "https://github.com/zpp0/flycheck-checkpatch"))])
+ (flycheck-clang-analyzer . [(20211214 648) ((flycheck (0 24)) (emacs (24 4))) "Integrate Clang Analyzer with flycheck" single ((:commit . "646d9f3a80046ab231a07526778695d5decad92d") (:authors ("Alex Murray" . "murray.alex@gmail.com")) (:maintainer "Alex Murray" . "murray.alex@gmail.com") (:url . "https://github.com/alexmurray/flycheck-clang-analyzer"))])
+ (flycheck-clang-tidy . [(20201115 1232) ((flycheck (0 30))) "Flycheck syntax checker using clang-tidy" single ((:commit . "f9ae7306bd6ca08b689b36c1e8f6f6b91d61db5f") (:authors (nil . "Sebastian Nagel<sebastian.nagel@ncoding.at>")) (:maintainer "tastytea" . "tastytea@tastytea.de") (:keywords "convenience" "languages" "tools") (:url . "https://github.com/ch1bo/flycheck-clang-tidy"))])
+ (flycheck-clangcheck . [(20150712 710) ((cl-lib (0 5)) (seq (1 7)) (flycheck (0 17))) "A Flycheck checker difinition for ClangCheck." single ((:commit . "24a9424c484420073a24443a829fd5779752362b") (:authors ("kumar8600" . "kumar8600@gmail.com")) (:maintainer "kumar8600" . "kumar8600@gmail.com") (:url . "https://github.com/kumar8600/flycheck-clangcheck"))])
+ (flycheck-clj-kondo . [(20211227 2226) ((emacs (24 3)) (flycheck (0 18))) "Add clj-kondo linter to flycheck" single ((:commit . "35daaccc75b0367844b249a8cb05bf73bcebd52a") (:authors ("Michiel Borkent" . "michielborkent@gmail.com")) (:maintainer "Michiel Borkent" . "michielborkent@gmail.com") (:url . "https://github.com/borkdude/flycheck-clj-kondo"))])
+ (flycheck-clojure . [(20191215 2227) ((cider (0 22 0)) (flycheck (32 -4)) (let-alist (1 0 1)) (emacs (25))) "Flycheck: Clojure support" single ((:commit . "592c4f89efb5112784cbf94c9ea6fdd045771b62") (:authors ("Peter Fraenkel" . "pnf@podsnap.com") ("Sebastian Wiesner" . "swiesner@lunaryorn.com")) (:maintainer "Peter Fraenkel" . "pnf@podsnap.com") (:url . "https://github.com/clojure-emacs/squiggly-clojure"))])
+ (flycheck-clolyze . [(20190422 2134) ((flycheck (0 25)) (emacs (24))) "Add Clolyze to to flycheck" single ((:commit . "c8b27602dd505aeae6486feb6f584754079baf51") (:authors ("Daniel Laps" . "daniel.laps@hhu.de")) (:maintainer "Daniel Laps" . "daniel.laps@hhu.de") (:url . "https://github.com/DLaps/flycheck-clolyze"))])
+ (flycheck-color-mode-line . [(20200528 416) ((flycheck (0 15)) (dash (1 2)) (emacs (24 3))) "Change mode line color with Flycheck status" single ((:commit . "575b604cfe21f65fb07c134392c382c163c87739") (:authors ("Sylvain Benner" . "sylvain.benner@gmail.com")) (:maintainer "Sylvain Benner" . "sylvain.benner@gmail.com") (:keywords "convenience" "language" "tools") (:url . "https://github.com/flycheck/flycheck-color-mode-line"))])
+ (flycheck-coverity . [(20170704 59) ((flycheck (0 24)) (dash (2 12 0)) (emacs (24 4))) "Integrate Coverity with flycheck" single ((:commit . "cb211e3dd50413a5042eb20175be518214591c9d") (:authors ("Alex Murray" . "murray.alex@gmail.com")) (:maintainer "Alex Murray" . "murray.alex@gmail.com") (:url . "https://github.com/alexmurray/flycheck-coverity"))])
+ (flycheck-credo . [(20170526 1545) ((flycheck (29))) "flycheck checker for elixir credo" single ((:commit . "e88f11ead53805c361ec7706e44c3dfee1daa19f") (:authors ("Aaron Jensen" . "aaronjensen@gmail.com")) (:maintainer "Aaron Jensen" . "aaronjensen@gmail.com") (:url . "https://github.com/aaronjensen/flycheck-credo"))])
+ (flycheck-crystal . [(20200805 2344) ((flycheck (30))) "Add support for Crystal to Flycheck" single ((:commit . "96a8058205b24b513d0b9307db32f05e30f9570b") (:keywords "tools" "crystal") (:url . "https://github.com/crystal-lang-tools/emacs-crystal-mode"))])
+ (flycheck-css-colorguard . [(20161031 1122) ((flycheck (0 22)) (emacs (24))) "Detect similar colors in CSS" single ((:commit . "ae94fa0396acd99f9ec36d9572459df793f37fe8") (:authors ("Saša Jovanić" . "info@simplify.ba")) (:maintainer "Saša Jovanić" . "info@simplify.ba") (:keywords "flycheck" "css" "colorguard") (:url . "https://github.com/Simplify/flycheck-css-colorguard/"))])
+ (flycheck-cstyle . [(20160905 2341) ((flycheck (0 24)) (emacs (24 4))) "Integrate cstyle with flycheck" single ((:commit . "207285140a353d08cf1fc450cacab158bc98ba82") (:authors ("Alex Murray" . "murray.alex@gmail.com")) (:maintainer "Alex Murray" . "murray.alex@gmail.com") (:url . "https://github.com/alexmurray/flycheck-cstyle"))])
+ (flycheck-cython . [(20170724 958) ((flycheck (0 25))) "Support Cython in flycheck" single ((:commit . "ecc4454d35ab5317ab66a04406f36f0c1dbc0b76") (:authors ("Lorenzo Bolla" . "lbolla@gmail.com")) (:maintainer "Lorenzo Bolla" . "lbolla@gmail.com"))])
+ (flycheck-d-unittest . [(20160522 417) ((flycheck (0 21 -4 1)) (dash (1 4 0))) "Add D unittest support to flycheck" single ((:commit . "3e614f23cb4a5566fd7988dbcaaf254af81c7718") (:authors ("Tomoya Tanjo" . "ttanjo@gmail.com")) (:maintainer "Tomoya Tanjo" . "ttanjo@gmail.com") (:keywords "flycheck" "d") (:url . "https://github.com/tom-tan/flycheck-d-unittest/"))])
+ (flycheck-dedukti . [(20171103 1212) ((flycheck (0 19)) (dedukti-mode (0 1))) "Flycheck integration of Dedukti" single ((:commit . "3dbff5646355f39d57a3ec514f560a6b0082a1cd") (:authors ("Raphaël Cauderlier")) (:maintainer "Raphaël Cauderlier") (:keywords "convenience" "languages" "tools" "flycheck" "dedukti") (:url . "https://github.com/rafoo/flycheck-dedukti"))])
+ (flycheck-dialyxir . [(20170515 1525) ((flycheck (29))) "flycheck checker for elixir dialyxir" single ((:commit . "adfb73374cb2bee75724822972f405f2ec371199") (:authors ("Aaron Jensen" . "aaronjensen@gmail.com")) (:maintainer "Aaron Jensen" . "aaronjensen@gmail.com") (:url . "https://github.com/aaronjensen/flycheck-dialyxir"))])
+ (flycheck-dialyzer . [(20160326 1430) ((flycheck (0 18))) "Support dialyzer in flycheck" single ((:commit . "a5df0db95ac69f397b5f85d325a6d88cf8974f64") (:authors ("Lorenzo Bolla" . "lbolla@gmail.com")) (:maintainer "Lorenzo Bolla" . "lbolla@gmail.com"))])
+ (flycheck-dmd-dub . [(20210412 1608) ((flycheck (0 24)) (f (0 18 2))) "Sets flycheck-dmd-include-paths from dub package information" single ((:commit . "818bfed45ac8597b6ad568c71eb9428138a125c8") (:authors ("Atila Neves" . "atila.neves@gmail.com")) (:maintainer "Atila Neves" . "atila.neves@gmail.com") (:keywords "languages") (:url . "http://github.com/atilaneves/flycheck-dmd-dub"))])
+ (flycheck-dogma . [(20170125 721) ((flycheck (29))) "flycheck checker for elixir dogma" single ((:commit . "eea1844a81e87e2488b05e703a93272d0fc3bc74") (:authors ("Aaron Jensen" . "aaronjensen@gmail.com")) (:maintainer "Aaron Jensen" . "aaronjensen@gmail.com") (:url . "https://github.com/aaronjensen/flycheck-dogma"))])
+ (flycheck-drstring . [(20200210 1903) ((emacs (25 1)) (flycheck (0 25)) (swift-mode (8 0))) "Doc linting for Swift using DrString" single ((:commit . "d8d5a560e792a6657ef5ac69934c74f1ed51372d") (:authors ("Daniel Martín" . "mardani29@yahoo.es")) (:maintainer "Daniel Martín" . "mardani29@yahoo.es") (:keywords "tools" "flycheck") (:url . "https://github.com/danielmartin/flycheck-drstring"))])
+ (flycheck-dtrace . [(20180903 1630) ((emacs (25 1)) (flycheck (0 22))) "Flycheck: DTrace support" single ((:commit . "951fab3a15c11d92b9fac1ea4791a80dfe034a00") (:authors ("Jürgen Hötzel" . "juergen@hoetzel.info")) (:maintainer "Jürgen Hötzel" . "juergen@hoetzel.info") (:keywords "languages" "convenience" "tools"))])
+ (flycheck-eldev . [(20210305 2231) ((flycheck (32)) (dash (2 17)) (emacs (24 4))) "Eldev support in Flycheck" single ((:commit . "2ed17db874da51fba3d2991a1e05cf375fca9619") (:authors ("Paul Pogonyshev" . "pogonyshev@gmail.com")) (:maintainer "Paul Pogonyshev" . "pogonyshev@gmail.com") (:keywords "tools" "convenience") (:url . "https://github.com/flycheck/flycheck-eldev"))])
+ (flycheck-elixir . [(20210413 612) ((flycheck (0 25))) "Support Elixir in flycheck" single ((:commit . "b57a77a21d6cf9621b3387831cba34135c4fa35d") (:authors ("Lorenzo Bolla" . "lbolla@gmail.com")) (:maintainer "Lorenzo Bolla" . "lbolla@gmail.com"))])
+ (flycheck-elm . [(20181107 146) ((flycheck (0 29 -4)) (emacs (24 4)) (let-alist (1 0 5)) (seq (2 20))) "Flycheck support for the elm language" single ((:commit . "1b60050efd4729bfba548f3e5adbcb58436667cb") (:authors ("Brian Sermons")) (:maintainer "Brian Sermons") (:url . "https://github.com/bsermons/flycheck-elm"))])
+ (flycheck-elsa . [(20200203 1758) ((emacs (25)) (seq (2 0))) "Flycheck for Elsa." tar ((:commit . "911ffb3498e411c538eebce20c6b20b39d725af6") (:authors ("Matúš Goljer" . "matus.goljer@gmail.com")) (:maintainer "Matúš Goljer" . "matus.goljer@gmail.com") (:keywords "convenience") (:url . "https://github.com/emacs-elsa/flycheck-elsa"))])
+ (flycheck-flawfinder . [(20211214 647) ((flycheck (0 24)) (emacs (24 4))) "Integrate flawfinder with flycheck" single ((:commit . "85701b849ea1ed8438ed4b7ae236e99d0f5528c7") (:authors ("Alex Murray" . "murray.alex@gmail.com")) (:maintainer "Alex Murray" . "murray.alex@gmail.com") (:url . "https://github.com/alexmurray/flycheck-flawfinder"))])
+ (flycheck-flow . [(20190304 1459) ((flycheck (0 18)) (json (1 4))) "Support Flow in flycheck" single ((:commit . "9e8e52cfc98af6a23fd906f9cb5d5d470d8cf82d") (:authors ("Lorenzo Bolla" . "lbolla@gmail.com")) (:maintainer "Lorenzo Bolla" . "lbolla@gmail.com"))])
+ (flycheck-ghcmod . [(20150114 632) ((flycheck (0 21 -4 1)) (dash (2 0))) "A flycheck checker for Haskell using ghcmod" single ((:commit . "6bb7b7d879f05bbae54e99eb04806c877adf3ccc") (:authors ("Shen Chao" . "scturtle@gmail.com")) (:maintainer "Shen Chao" . "scturtle@gmail.com") (:keywords "convenience" "languages" "tools") (:url . "https://github.com/scturtle/flycheck-ghcmod"))])
+ (flycheck-golangci-lint . [(20190330 1412) ((emacs (24)) (flycheck (0 22))) "Flycheck checker for golangci-lint" single ((:commit . "8e446c68311048f0b87febf8ef0379e29d358851") (:authors ("Wei Jian Gan" . "weijiangan@outlook.com")) (:maintainer "Wei Jian Gan" . "weijiangan@outlook.com") (:keywords "convenience" "tools" "go") (:url . "https://github.com/weijiangan/flycheck-golangci-lint"))])
+ (flycheck-gometalinter . [(20180424 941) ((emacs (24)) (flycheck (0 22))) "flycheck checker for gometalinter" single ((:commit . "1e3eede14da405b914a7d8b00300846e4393cb83") (:authors ("Diep Pham" . "me@favadi.com")) (:maintainer "Diep Pham" . "me@favadi.com") (:keywords "convenience" "tools" "go") (:url . "https://github.com/favadi/flycheck-gometalinter"))])
+ (flycheck-google-cpplint . [(20210210 300) ((flycheck (0 20 -4 1))) "Help to comply with the Google C++ Style Guide" single ((:commit . "327f1c13e4f404b1bdd25b10f7e7ac7d7e3bdac0") (:authors ("Akiha Senda" . "senda.akiha@gmail.com")) (:maintainer "Jen-Chieh Shen" . "jcs090218@gmail.com") (:keywords "flycheck" "c" "c++") (:url . "https://github.com/flycheck/flycheck-google-cpplint/"))])
+ (flycheck-gradle . [(20190315 234) ((emacs (25 1)) (flycheck (0 25))) "Flycheck extension for Gradle." single ((:commit . "1ca08bbc343362a923cbdc2010f66e41655e92ab") (:maintainer "James Nguyen" . "james@jojojames.com") (:keywords "languages" "gradle") (:url . "https://github.com/jojojames/flycheck-gradle"))])
+ (flycheck-grammalecte . [(20210705 1656) ((emacs (26 1)) (flycheck (26))) "Integrate Grammalecte with Flycheck" tar ((:commit . "59b37e09923290da1c8458e507da43f403f555d2") (:authors ("Guilhem Doulcier" . "guilhem.doulcier@espci.fr") ("Étienne Deparis" . "etienne@depar.is")) (:maintainer "Étienne Deparis" . "etienne@depar.is") (:keywords "i18n" "text") (:url . "https://git.umaneti.net/flycheck-grammalecte/"))])
+ (flycheck-grammarly . [(20220228 731) ((emacs (25 1)) (flycheck (0 14)) (grammarly (0 3 0)) (s (1 12 0))) "Grammarly support for Flycheck" single ((:commit . "6cc8a7553ac84a229090ca8ffa6aa7d34de35cde") (:authors ("Shen, Jen-Chieh" . "jcs090218@gmail.com")) (:maintainer "Shen, Jen-Chieh" . "jcs090218@gmail.com") (:url . "https://github.com/emacs-grammarly/flycheck-grammarly"))])
+ (flycheck-guile . [(20201202 509) ((emacs (24 1)) (flycheck (0 22)) (geiser (0 11))) "A Flycheck checker for GNU Guile" single ((:commit . "e46d6e5453dd7471309fae6549445c48e6d8f340") (:authors ("Ricardo Wurmus" . "rekado@elephly.net")) (:maintainer "Andrew Whatson" . "whatson@gmail.com") (:url . "https://github.com/flatwhatson/flycheck-guile"))])
+ (flycheck-haskell . [(20220426 2358) ((emacs (24 3)) (flycheck (0 25)) (haskell-mode (13 7)) (dash (2 4 0)) (seq (1 11)) (let-alist (1 0 1))) "Flycheck: Automatic Haskell configuration" tar ((:commit . "d92dea78fb8638f7c27a3eb925d84c669fb257dd") (:authors ("Sebastian Wiesner" . "swiesner@lunaryorn.com")) (:maintainer "Sebastian Wiesner" . "swiesner@lunaryorn.com") (:keywords "tools" "convenience") (:url . "https://github.com/flycheck/flycheck-haskell"))])
+ (flycheck-hdevtools . [(20160926 702) ((flycheck (0 21 -4 1)) (dash (2 0))) "A flycheck checker for Haskell using hdevtools" single ((:commit . "8248ebaf8376ee5e37ff47c814a291550a7bdcf2") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:keywords "convenience" "languages" "tools") (:url . "https://github.com/flycheck/flycheck-hdevtools"))])
+ (flycheck-hledger . [(20220323 726) ((emacs (27 1)) (flycheck (31))) "Flycheck module to check hledger journals" single ((:commit . "87b275b9b3d476b5f458e85e760f3f7fa3e66775") (:authors ("Damien Cassou" . "damien@cassou.me")) (:maintainer "Damien Cassou" . "damien@cassou.me") (:url . "https://github.com/DamienCassou/flycheck-hledger/"))])
+ (flycheck-indent . [(20200129 2046) ((emacs (25 1)) (indent-lint (1 0 0)) (flycheck (31))) "Indent-lint frontend for flycheck" single ((:commit . "c55f4ded11e8e50a96f43675a071354a8fb501c3") (:authors ("Naoya Yamashita" . "conao3@gmail.com")) (:maintainer "Naoya Yamashita" . "conao3@gmail.com") (:keywords "tools") (:url . "https://github.com/conao3/indent-lint.el"))])
+ (flycheck-indicator . [(20200331 1142) ((flycheck (0 15))) "A fancy mode line indicator for `flycheck-mode'" single ((:commit . "e00d9a20cbc21d6814c27cc9206296da394478e8") (:authors ("Eder Elorriaga" . "gexplorer8@gmail.com")) (:maintainer "Eder Elorriaga" . "gexplorer8@gmail.com") (:keywords "convenience" "language" "tools") (:url . "https://github.com/gexplorer/flycheck-indicator"))])
+ (flycheck-ini-pyinilint . [(20190312 1931) ((flycheck (31))) "Flycheck integration for PyINILint" single ((:commit . "7febbea9ed407eccc4bfd24ae0d3afd1c19394f7") (:authors ("Daniel J. R. May" . "daniel.may@danieljrmay.com")) (:maintainer "Daniel J. R. May" . "daniel.may@danieljrmay.com") (:keywords "convenience" "files" "tools") (:url . "https://gitlab.com/danieljrmay/flycheck-ini-pyinilint"))])
+ (flycheck-inline . [(20200808 1019) ((emacs (25 1)) (flycheck (32))) "Display Flycheck errors inline" single ((:commit . "8e00b4c5951a9515a450a14aefe92e9f6ddcfbde") (:authors ("fmdkdd")) (:maintainer "fmdkdd") (:keywords "tools" "convenience") (:url . "https://github.com/flycheck/flycheck-inline"))])
+ (flycheck-irony . [(20180604 2152) ((emacs (24 1)) (flycheck (0 22)) (irony (0 2 0))) "Flycheck: C/C++ support via Irony" single ((:commit . "42dbecd4a865cabeb301193bb4d660e26ae3befe") (:authors ("Guillaume Papin" . "guillaume.papin@epitech.eu")) (:maintainer "Guillaume Papin" . "guillaume.papin@epitech.eu") (:keywords "convenience" "tools" "c") (:url . "https://github.com/Sarcasm/flycheck-irony/"))])
+ (flycheck-jest . [(20180411 328) ((emacs (25 1)) (flycheck (0 25))) "Flycheck extension for Jest." single ((:commit . "08f27c5ed97c83c445f99fab58f0b6c826f14449") (:maintainer "James Nguyen" . "james@jojojames.com") (:keywords "languages" "jest") (:url . "https://github.com/jojojames/flycheck-jest"))])
+ (flycheck-joker . [(20200412 2346) ((flycheck (0 18))) "Add Clojure syntax checker (via Joker) to flycheck" single ((:commit . "93576295fef7a749bf779eeece5edd85e21868e2") (:authors ("Roman Bataev" . "roman.bataev@gmail.com")) (:maintainer "Roman Bataev" . "roman.bataev@gmail.com"))])
+ (flycheck-julia . [(20170729 2141) ((emacs (24)) (flycheck (0 22))) "Julia support for Flycheck" single ((:commit . "213b60a5a9a1cb7887260e1d159b5bb27167cbb6") (:authors ("Guido Kraemer" . "guido.kraemer@gmx.de")) (:maintainer "Guido Kraemer" . "guido.kraemer@gmx.de") (:keywords "convenience" "tools" "languages") (:url . "https://github.com/gdkrmr/flycheck-julia"))])
+ (flycheck-keg . [(20200726 218) ((emacs (24 3)) (keg (0 1)) (flycheck (0 1))) "Flycheck for Keg projects" single ((:commit . "944e36144d92a798e1fd0f3d83fc6347d57a976e") (:authors ("Naoya Yamashita" . "conao3@gmail.com")) (:maintainer "Naoya Yamashita" . "conao3@gmail.com") (:keywords "convenience") (:url . "https://github.com/conao3/keg.el"))])
+ (flycheck-kotlin . [(20210406 1148) ((flycheck (0 20))) "Support kotlin in flycheck" single ((:commit . "bf1b398bdde128806a0a7479ebbe369bbaa40dae") (:authors ("Elric Milon" . "whirm_REMOVETHIS__@gmx.com")) (:maintainer "Elric Milon" . "whirm_REMOVETHIS__@gmx.com"))])
+ (flycheck-languagetool . [(20220402 1703) ((emacs (25 1)) (flycheck (0 14))) "Flycheck support for LanguageTool" single ((:commit . "6dc29319973ff86f8f83c988f3e093b28c746aba") (:authors ("Shen, Jen-Chieh" . "jcs090218@gmail.com") ("Peter Oliver" . "git@mavit.org.uk")) (:maintainer "Shen, Jen-Chieh" . "jcs090218@gmail.com") (:url . "https://github.com/emacs-languagetool/flycheck-languagetool"))])
+ (flycheck-ledger . [(20200304 2204) ((emacs (24 1)) (flycheck (0 15))) "Flycheck integration for ledger files" single ((:commit . "628e25ba66604946085571652a94a54f4d1ad96f") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:keywords "convenience" "languages" "tools") (:url . "https://github.com/purcell/flycheck-ledger"))])
+ (flycheck-lilypond . [(20211006 2102) ((emacs (24 3)) (flycheck (0 22))) "LilyPond support in Flycheck" single ((:commit . "78f8c16cd67f9f6d3f1806e1fd403222723ba400") (:authors ("Hinrik Örn Sigurðsson" . "hinrik.sig@gmail.com")) (:maintainer "Hinrik Örn Sigurðsson" . "hinrik.sig@gmail.com") (:keywords "tools" "convenience") (:url . "https://github.com/hinrik/flycheck-lilypond"))])
+ (flycheck-liquidhs . [(20170412 2326) ((flycheck (0 15))) "A flycheck checker for Haskell using liquid (i.e. liquidhaskell)" single ((:commit . "c27252ac24d77f4b6eec76a4ba9cd61761a3fba9") (:authors ("Ranjit Jhala" . "jhala@cs.ucsd.edu")) (:maintainer "Ranjit Jhala" . "jhala@cs.ucsd.edu") (:keywords "convenience" "languages" "tools") (:url . "https://github.com/ucsd-progsys/liquidhaskell/flycheck-liquid.el"))])
+ (flycheck-mercury . [(20181118 1952) ((flycheck (0 22)) (s (1 9 0)) (dash (2 4 0))) "Mercury support in Flycheck" single ((:commit . "b6807a8db70981e21a91a93324c31e49de85c89f") (:authors ("Matthias Güdemann" . "matthias.gudemann@gmail.com")) (:maintainer "Matthias Güdemann" . "matthias.gudemann@gmail.com") (:keywords "convenience" "languages" "tools") (:url . "https://github.com/flycheck/flycheck-mercury"))])
+ (flycheck-mmark . [(20190713 1323) ((emacs (24 4)) (flycheck (0 29))) "Flycheck checker for the MMark markdown processor" single ((:commit . "67d6216229337c9c020a8aecd6ae2417de29b5e8") (:authors ("Mark Karpov" . "markkarpov92@gmail.com")) (:maintainer "Mark Karpov" . "markkarpov92@gmail.com") (:keywords "convenience" "text") (:url . "https://github.com/mmark-md/flycheck-mmark"))])
+ (flycheck-mypy . [(20200113 1336) ((flycheck (0 18))) "Support mypy in flycheck" single ((:commit . "5b4e14ab0cbce2ff35fee7e69b5b95eafd609c80") (:authors ("Lorenzo Bolla" . "lbolla@gmail.com")) (:maintainer "Lorenzo Bolla" . "lbolla@gmail.com"))])
+ (flycheck-nim . [(20190927 1514) ((dash (2 4 0)) (flycheck (0 20))) "Defines a flycheck syntax checker for nim" single ((:commit . "ddfade51001571c2399f78bcc509e0aa8eb752a4") (:authors ("Adam Schwalm" . "adamschwalm@gmail.com")) (:maintainer "Adam Schwalm" . "adamschwalm@gmail.com") (:url . "https://github.com/ALSchwalm/flycheck-nim"))])
+ (flycheck-nimsuggest . [(20171027 2208) ((flycheck (0 23)) (emacs (24 3))) "flycheck backend for Nim using nimsuggest" single ((:commit . "dc9a5de1cb3ee05db5794d824610959a1f603bc9") (:authors ("Yuta Yamada <cokesboy\"at\"gmail.com>")) (:maintainer "Yuta Yamada <cokesboy\"at\"gmail.com>") (:url . "https://github.com/yuutayamada/flycheck-nimsuggest"))])
+ (flycheck-objc-clang . [(20210911 1023) ((emacs (24 4)) (flycheck (26))) "Flycheck: Objective-C support using Clang" single ((:commit . "0a86156fad0d6f02e8e6b4c5594f7173c96d6481") (:authors ("Goichi Hirakawa" . "gooichi@gyazsquare.com")) (:maintainer "Goichi Hirakawa" . "gooichi@gyazsquare.com") (:keywords "convenience" "languages" "tools") (:url . "https://github.com/GyazSquare/flycheck-objc-clang"))])
+ (flycheck-ocaml . [(20170730 2153) ((emacs (24 1)) (flycheck (0 22)) (merlin (3 0 1)) (let-alist (1 0 3))) "Flycheck: OCaml support" single ((:commit . "8707a7bf545a8639a6a5c600a98d9a2ea1487dc9") (:authors ("Sebastian Wiesner" . "swiesner@lunaryorn.com")) (:maintainer "Sebastian Wiesner" . "swiesner@lunaryorn.com") (:keywords "convenience" "tools" "languages") (:url . "https://github.com/flycheck/flycheck-ocaml"))])
+ (flycheck-package . [(20210509 2323) ((emacs (24 1)) (flycheck (0 22)) (package-lint (0 2))) "A Flycheck checker for elisp package authors" single ((:commit . "615c1ed8c6fb7c73abec6aaa73d3fef498d231bc") (:authors ("Steve Purcell" . "steve@sanityinc.com") ("Fanael Linithien" . "fanael4@gmail.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:keywords "lisp") (:url . "https://github.com/purcell/flycheck-package"))])
+ (flycheck-pact . [(20180920 2052) ((emacs (24 3)) (flycheck (0 25)) (pact-mode (0 0 4))) "Flycheck support for pact-mode" single ((:commit . "0e10045064ef89ec8b6f5a473073d47b976a2ca3") (:authors ("Stuart Popejoy")) (:maintainer "Stuart Popejoy" . "stuart@kadena.io") (:keywords "pact" "lisp" "languages" "blockchain" "smartcontracts" "tools" "linting") (:url . "http://github.com/kadena-io/flycheck-pact"))])
+ (flycheck-pest . [(20200317 1503) ((emacs (26 3)) (flycheck (31)) (pest-mode (0 1))) "Flycheck integration for Pest -" single ((:commit . "43447a2c70f98edd1139005e32f437d3f142442b") (:authors ("Naoya Yamashita" . "conao3@gmail.com")) (:maintainer "Naoya Yamashita" . "conao3@gmail.com") (:keywords "convenience" "flycheck") (:url . "https://github.com/ksqsf/pest-mode"))])
+ (flycheck-php-noverify . [(20211005 401) ((flycheck (0 22))) "Flycheck checker for PHP Noverify linter" single ((:commit . "3c5cfa5b790bb7f0a8da7f3caee8e4782b67f8ac") (:url . "https://github.com/Junker/flycheck-php-noverify"))])
+ (flycheck-phpstan . [(20210714 1805) ((emacs (24 3)) (flycheck (26)) (phpstan (0 5 0))) "Flycheck integration for PHPStan" single ((:commit . "0869b152f82a76138daa53e953285936b9d558bd") (:authors ("USAMI Kenta" . "tadsan@zonu.me")) (:maintainer "USAMI Kenta" . "tadsan@zonu.me") (:keywords "tools" "php") (:url . "https://github.com/emacs-php/phpstan.el"))])
+ (flycheck-pkg-config . [(20200409 501) ((dash (2 8 0)) (s (1 9 0)) (flycheck (29))) "configure flycheck using pkg-config" single ((:commit . "b76b24ea1f4800f5fb96ce9c6c4788e0e63133d3") (:authors ("Wilfred Hughes" . "me@wilfred.me.uk")) (:maintainer "Wilfred Hughes" . "me@wilfred.me.uk") (:keywords "flycheck"))])
+ (flycheck-plantuml . [(20171018 111) ((flycheck (0 24)) (emacs (24 4)) (plantuml-mode (1 2 2))) "Integrate plantuml with flycheck" single ((:commit . "183be89e1dbba0b38237dd198dff600e0790309d") (:authors ("Alex Murray" . "murray.alex@gmail.com")) (:maintainer "Alex Murray" . "murray.alex@gmail.com") (:url . "https://github.com/alexmurray/flycheck-plantuml"))])
+ (flycheck-pony . [(20210118 1326) ((flycheck (0 25 1))) "Pony support in Flycheck" single ((:commit . "2d5b72903e69e1e5eec2d03b9006a62fbbf75233") (:keywords "tools" "convenience") (:url . "https://github.com/seantallen/flycheck-pony"))])
+ (flycheck-popup-tip . [(20170812 2351) ((flycheck (0 22)) (popup (0 5)) (emacs (24))) "Display Flycheck error messages using popup.el" single ((:commit . "ef86aad907f27ca076859d8d9416f4f7727619c6") (:authors ("Saša Jovanić" . "sasa@simplify.ba")) (:maintainer "Saša Jovanić" . "sasa@simplify.ba") (:keywords "convenience" "tools" "flycheck" "tooltip") (:url . "https://github.com/flycheck/flycheck-popup-tip/"))])
+ (flycheck-pos-tip . [(20200516 1600) ((emacs (24 1)) (flycheck (0 22)) (pos-tip (0 4 6))) "Display Flycheck errors in GUI tooltips" single ((:commit . "dc57beac0e59669926ad720c7af38b27c3a30467") (:authors ("Akiha Senda" . "senda.akiha@gmail.com") ("Sebastian Wiesner" . "swiesner@lunaryorn.com")) (:maintainer "Sebastian Wiesner" . "swiesner@lunaryorn.com") (:keywords "tools" "convenience") (:url . "https://github.com/flycheck/flycheck-pos-tip"))])
+ (flycheck-posframe . [(20210316 618) ((flycheck (0 24)) (emacs (26)) (posframe (0 7 0))) "Show flycheck error messages using posframe.el" single ((:commit . "8f60c9bf124ab9597d681504a73fdf116a0bde12") (:authors ("Alex Murray" . "murray.alex@gmail.com")) (:maintainer "Alex Murray" . "murray.alex@gmail.com") (:url . "https://github.com/alexmurray/flycheck-posframe"))])
+ (flycheck-projectile . [(20201031 1952) ((emacs (25 1)) (flycheck (31)) (projectile (2 2))) "Project-wide errors" single ((:commit . "ce6e9e8793a55dace13d5fa13badab2dca3b5ddb") (:authors ("Nikita Bloshchanevich" . "nikblos@outlook.com")) (:maintainer "Nikita Bloshchanevich" . "nikblos@outlook.com") (:url . "https://github.com/nbfalcon/flycheck-projectile"))])
+ (flycheck-prospector . [(20180524 450) ((flycheck (0 22))) "Support prospector in flycheck" single ((:commit . "92f2680573290ba4a69a2d6e140f44680efce6a8") (:authors ("Carlos Coelho" . "carlospecter@gmail.com")) (:maintainer "Carlos Coelho" . "carlospecter@gmail.com") (:url . "https://github.com/chocoelho/flycheck-prospector"))])
+ (flycheck-psalm . [(20211002 1555) ((emacs (24 3)) (flycheck (26)) (psalm (0 6 0))) "Flycheck integration for Psalm" single ((:commit . "28d546a79cb865a78b94cd7e929d66d720505faa") (:authors ("USAMI Kenta" . "tadsan@zonu.me")) (:maintainer "USAMI Kenta" . "tadsan@zonu.me") (:keywords "tools" "php") (:url . "https://github.com/emacs-php/psalm.el"))])
+ (flycheck-pycheckers . [(20211122 235) ((flycheck (0 18))) "multiple syntax checker for Python, using Flycheck" tar ((:commit . "56965c0ef5d45bcef90093360718c6967ce4ef39") (:keywords "convenience" "tools" "languages") (:url . "https://github.com/msherry/flycheck-pycheckers"))])
+ (flycheck-pyflakes . [(20170330 2311) ((flycheck (0 18))) "Support pyflakes in flycheck" single ((:commit . "61b045939e3743b2162b7e4e73249c66fc2b8f65") (:authors ("Wilfred Hughes" . "me@wilfred.me.uk")) (:maintainer "Wilfred Hughes" . "me@wilfred.me.uk"))])
+ (flycheck-pyre . [(20190215 1222) ((emacs (24)) (flycheck (29)) (cl-lib (0 6))) "Support Pyre in flycheck" tar ((:commit . "0560122caae207d99d8af1ac2b4e5d6f6a1ce444") (:authors ("Vyacheslav Linnik" . "vyacheslav.linnik@gmail.com")) (:maintainer "Vyacheslav Linnik" . "vyacheslav.linnik@gmail.com") (:url . "https://github.com/linnik/flycheck-pyre"))])
+ (flycheck-raku . [(20220420 732) ((emacs (26 3)) (flycheck (0 22))) "Raku support in Flycheck" single ((:commit . "4da1970a75396aff1957b07f7579c1de6b817e6b") (:authors ("Hinrik Örn Sigurðsson" . "hinrik.sig@gmail.com") ("Johnathon Weare" . "jrweare@gmail.com") ("Siavash Askari Nasr" . "siavash.askari.nasr@gmail.com")) (:maintainer "Hinrik Örn Sigurðsson" . "hinrik.sig@gmail.com") (:keywords "tools" "convenience") (:url . "https://github.com/Raku/flycheck-raku"))])
+ (flycheck-relint . [(20200721 2217) ((emacs (26 1)) (flycheck (0 22)) (relint (1 15))) "A Flycheck checker for elisp regular expressions" single ((:commit . "c66d0c8d2e3a8abb6a3dfda597801e460b2eeb6f") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:keywords "lisp") (:url . "https://github.com/purcell/flycheck-relint"))])
+ (flycheck-rtags . [(20191222 920) ((emacs (24)) (flycheck (0 23)) (rtags (2 10))) "RTags Flycheck integration" single ((:commit . "db39790fda5c2443bc790b8971ac140914f7e9c2") (:authors ("Christian Schwarzgruber" . "c.schwarzgruber.cs@gmail.com")) (:maintainer "Christian Schwarzgruber" . "c.schwarzgruber.cs@gmail.com") (:url . "https://github.com/Andersbakken/rtags"))])
+ (flycheck-rust . [(20190319 1546) ((emacs (24 1)) (flycheck (28)) (dash (2 13 0)) (seq (2 3)) (let-alist (1 0 4))) "Flycheck: Rust additions and Cargo support" single ((:commit . "a139cd53c5062697e9ed94ad80b803c37d999600") (:authors ("Sebastian Wiesner" . "swiesner@lunaryorn.com")) (:maintainer "Sebastian Wiesner" . "swiesner@lunaryorn.com") (:keywords "tools" "convenience") (:url . "https://github.com/flycheck/flycheck-rust"))])
+ (flycheck-stan . [(20211129 2051) ((emacs (25 1)) (flycheck (0 16 0)) (stan-mode (10 3 0))) "Add Stan support for Flycheck" tar ((:commit . "150bbbe5fd3ad2b5a3dbfba9d291e66eeea1a581") (:authors ("Jeffrey Arnold" . "jeffrey.arnold@gmail.com") ("Kazuki Yoshida" . "kazukiyoshida@mail.harvard.edu")) (:maintainer "Kazuki Yoshida" . "kazukiyoshida@mail.harvard.edu") (:keywords "c" "languages") (:url . "https://github.com/stan-dev/stan-mode/tree/master/flycheck-stan"))])
+ (flycheck-status-emoji . [(20180330 2325) ((cl-lib (0 1)) (emacs (24)) (flycheck (0 20)) (let-alist (1 0))) "Show flycheck status using cute, compact emoji" single ((:commit . "4bd113ab42dec9544b66e0a27ed9008ce8148433") (:authors ("Ben Liblit" . "liblit@acm.org")) (:maintainer "Ben Liblit" . "liblit@acm.org") (:keywords "convenience" "languages" "tools") (:url . "https://github.com/liblit/flycheck-status-emoji"))])
+ (flycheck-swift . [(20170129 549) ((emacs (24 4)) (flycheck (0 25))) "Flycheck extension for Apple's Swift." single ((:commit . "4c5ad401252400a78da395fd56a71e67ff8c2761") (:keywords "languages" "swift"))])
+ (flycheck-swift3 . [(20210910 1244) ((emacs (24 4)) (flycheck (26))) "Flycheck: Swift support for Apple swift-mode" single ((:commit . "54193175c87a4c0bbf7ed16a3e76d6daff35c76f") (:authors ("Goichi Hirakawa" . "gooichi@gyazsquare.com")) (:maintainer "Goichi Hirakawa" . "gooichi@gyazsquare.com") (:keywords "convenience" "languages" "tools") (:url . "https://github.com/GyazSquare/flycheck-swift3"))])
+ (flycheck-swiftlint . [(20180830 340) ((emacs (25 1)) (flycheck (0 25))) "Flycheck extension for Swiftlint." single ((:commit . "8861ddbd9c1c2a951630d9ea29162ad0916580cb") (:maintainer "James Nguyen" . "james@jojojames.com") (:keywords "languages" "swiftlint" "swift" "emacs") (:url . "https://github.com/jojojames/flycheck-swiftlint"))])
+ (flycheck-swiftx . [(20200814 845) ((emacs (26 1)) (flycheck (26)) (xcode-project (1 0))) "Flycheck: Swift backend" single ((:commit . "84f42393dea362d3bdfc9253a205a17ec7a12a76") (:authors ("John Buckley" . "john@olivetoast.com")) (:maintainer "John Buckley" . "john@olivetoast.com") (:keywords "convenience" "languages" "tools") (:url . "https://github.com/nhojb/flycheck-swiftx"))])
+ (flycheck-tcl . [(20180327 1259) ((emacs (24 4)) (flycheck (0 22))) "A flycheck checker for Tcl using tclchecker" single ((:commit . "7ca23f4673e178b9f5dcc8a82b86cf05b15d7236") (:authors ("Niels Widger" . "niels.widger@gmail.com")) (:maintainer "Niels Widger" . "niels.widger@gmail.com") (:url . "https://github.com/nwidger/flycheck-tcl"))])
+ (flycheck-tip . [(20171020 1048) ((flycheck (29)) (emacs (24 1)) (popup (0 5 0))) "Show flycheck/flymake errors by tooltip" tar ((:commit . "9b0072d92e6b4a52834bf5a34120a0f5e1c8c2fd") (:authors ("Yuta Yamada <cokesboy\"at\"gmail.com>")) (:maintainer "Yuta Yamada <cokesboy\"at\"gmail.com>") (:keywords "flycheck") (:url . "https://github.com/yuutayamada/flycheck-tip"))])
+ (flycheck-title . [(20210321 558) ((flycheck (30)) (emacs (24))) "show flycheck errors in the frame title" single ((:commit . "74e4375f372f7b9ce0fdfa34dc74a048376679ae") (:authors ("Wilfred Hughes" . "me@wilfred.me.uk")) (:maintainer "Wilfred Hughes" . "me@wilfred.me.uk"))])
+ (flycheck-vale . [(20190609 1533) ((emacs (24 4)) (flycheck (0 22)) (let-alist (1 0 4))) "flycheck integration for vale" single ((:commit . "f08249535348d046d0974b9c20fe1b7dd3cd2660") (:authors ("Austin Bingham" . "austin.bingham@gmail.com")) (:maintainer "Austin Bingham" . "austin.bingham@gmail.com") (:url . "https://github.com/abingham/flycheck-vale"))])
+ (flycheck-vdm . [(20190304 839) ((emacs (24)) (flycheck (32 -4)) (vdm-mode (0 0 4))) "Syntax checking for vdm-mode" single ((:commit . "56336930555df91787f196acac15680498d17d5e") (:authors ("Peter W. V. Tran-Jørgensen" . "peter.w.v.jorgensen@gmail.com")) (:maintainer "Peter W. V. Tran-Jørgensen" . "peter.w.v.jorgensen@gmail.com") (:keywords "languages") (:url . "https://github.com/peterwvj/vdm-mode"))])
+ (flycheck-xcode . [(20180122 651) ((emacs (25 1)) (flycheck (0 25))) "Flycheck extension for Apple's Xcode." single ((:commit . "b76f872c8985801951a095b8b3c1572b94189f9e") (:maintainer "James Nguyen" . "james@jojojames.com") (:keywords "languages" "xcode") (:url . "https://github.com/jojojames/flycheck-xcode"))])
+ (flycheck-yamllint . [(20170325 1735) ((flycheck (30))) "Flycheck integration for YAMLLint" single ((:commit . "1e9fe3b2d3e42d551b94473816a8eeee637b446c") (:authors ("Krzysztof Magosa" . "krzysztof@magosa.pl")) (:maintainer "Krzysztof Magosa" . "krzysztof@magosa.pl") (:keywords "convenience" "languages" "tools") (:url . "https://github.com/krzysztof-magosa/flycheck-yamllint"))])
+ (flycheck-yang . [(20180312 1831) ((yang-mode (0 9 4)) (flycheck (0 18))) "YANG flycheck checker" single ((:commit . "47881fc42ef0163c47064b72b5d6dbef4f83d778") (:authors (nil . "Andrew Fort (@andaru)")) (:maintainer nil . "Andrew Fort (@andaru)"))])
+ (flycheck-ycmd . [(20181016 618) ((emacs (24)) (dash (2 13 0)) (flycheck (0 22)) (ycmd (1 2)) (let-alist (1 0 5))) "flycheck integration for ycmd" single ((:commit . "c17ff9e0250a9b39d23af37015a2b300e2f36fed") (:authors ("Austin Bingham" . "austin.bingham@gmail.com")) (:maintainer "Austin Bingham" . "austin.bingham@gmail.com") (:url . "https://github.com/abingham/emacs-ycmd"))])
+ (flymake-aspell . [(20220411 826) ((emacs (26 1))) "Aspell checker for flymake" single ((:commit . "dcf7e6543e4d94d58375e00e4a10db615ef06941") (:authors ("Leo Gaskin" . "leo.gaskin@le0.gs")) (:maintainer "Leo Gaskin" . "leo.gaskin@le0.gs") (:keywords "wp" "flymake" "spell" "aspell") (:url . "https://github.com/leotaku/flycheck-aspell"))])
+ (flymake-coffee . [(20170723 146) ((flymake-easy (0 1))) "A flymake handler for coffee script" single ((:commit . "dee295acf30820ed15fe0de17137d50bc27fc80c") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:url . "https://github.com/purcell/flymake-coffee"))])
+ (flymake-collection . [(20220410 1343) ((emacs (28 1)) (let-alist (1 0)) (flymake (1 2 1))) "Collection of checkers for flymake, bringing flymake to the level of flycheck" tar ((:commit . "8f36fed9eef834cf94931fc8b813f9ac8db6d2a4") (:authors ("Mohsin Kaleem" . "mohkale@kisara.moe")) (:maintainer "Mohsin Kaleem" . "mohkale@kisara.moe") (:keywords "language" "tools") (:url . "https://github.com/mohkale/flymake-collection"))])
+ (flymake-css . [(20170723 146) ((flymake-easy (0 1))) "Flymake support for css using csslint" single ((:commit . "de090163ba289910ceeb61b13368ce42d0f2dfd8") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:url . "https://github.com/purcell/flymake-css"))])
+ (flymake-cursor . [(20220502 456) ((flymake (0 3))) "Show flymake messages in the minibuffer after delay" single ((:commit . "91025284824b3fef086709702e8a791dbaf2ef4a") (:authors ("Unknown Original Author") ("Dino Chiesa" . "dpchiesa@hotmail.com") ("Sam Graham <libflymake-emacs BLAHBLAH illusori.co.uk>")) (:maintainer "Sam Graham <libflymake-emacs BLAHBLAH illusori.co.uk>") (:keywords "languages" "mode" "flymake") (:url . "https://github.com/flymake/emacs-flymake-cursor"))])
+ (flymake-diagnostic-at-point . [(20180815 1004) ((emacs (26 1)) (popup (0 5 3))) "Display flymake diagnostics at point" single ((:commit . "379616b1c6f5ebeaf08fbe54ae765008a78b3be7") (:authors ("Ricardo Martins" . "ricardo@scarybox.net")) (:maintainer "Ricardo Martins" . "ricardo@scarybox.net") (:keywords "convenience" "languages" "tools") (:url . "https://github.com/meqif/flymake-diagnostic-at-point"))])
+ (flymake-easy . [(20140818 755) nil "Helpers for easily building flymake checkers" single ((:commit . "de41ea49503f71f997e5c359a2ad08df696c0147") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:keywords "convenience" "internal") (:url . "https://github.com/purcell/flymake-easy"))])
+ (flymake-elixir . [(20130810 1417) nil "A flymake handler for elixir-mode .ex files." single ((:commit . "3810566cffe35d04cc3f01e27fe397d68d52f802") (:authors ("Sylvain Benner" . "syl20bnr@gmail.com")) (:maintainer "Sylvain Benner" . "syl20bnr@gmail.com"))])
+ (flymake-eslint . [(20220318 152) ((emacs (26 0))) "A Flymake backend for Javascript using eslint" single ((:commit . "bfcf28259c7d774b259a6ed122f1f0936a5b96b9") (:authors ("Dan Orzechowski")) (:maintainer "Dan Orzechowski") (:url . "https://github.com/orzechowskid/flymake-eslint"))])
+ (flymake-flycheck . [(20220313 924) ((flycheck (31)) (emacs (26 1))) "Use flycheck checkers as flymake backends" single ((:commit . "9040be3763b8f9952dccd9a04be25ac20a0f8745") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:keywords "convenience" "languages" "tools") (:url . "https://github.com/purcell/flymake-flycheck"))])
+ (flymake-gjshint . [(20130327 1232) nil "A flymake handler for javascript using both jshint and gjslint" single ((:commit . "dc957c14cb060819585de8aedb330e24efa4b784") (:authors ("Yasuyuki Oka" . "yasuyk@gmail.com")) (:maintainer "Yasuyuki Oka" . "yasuyk@gmail.com") (:keywords "flymake" "javascript" "jshint" "gjslint"))])
+ (flymake-go . [(20150714 733) nil "A flymake handler for go-mode files" single ((:commit . "ae83761aa908c1a50ff34af04f00dcc46bca2ce9") (:authors ("Michael Fellinger" . "michael@iron.io") ("Robert Zaremba" . "robert.marek.zaremba@wp.eu")) (:maintainer "Michael Fellinger" . "michael@iron.io") (:keywords "go" "flymake") (:url . "https://github.com/robert-zaremba/flymake-go"))])
+ (flymake-go-staticcheck . [(20190708 1325) ((emacs (25))) "Go staticcheck linter for flymake" single ((:commit . "130079fcd29c3e2a72f8325f3041042bcc6286f1") (:authors ("Sergey Kostyaev" . "feo.me@ya.ru")) (:maintainer "Sergey Kostyaev" . "feo.me@ya.ru") (:keywords "languages" "tools") (:url . "https://github.com/s-kostyaev/flymake-go-staticcheck"))])
+ (flymake-golangci . [(20191028 1927) ((flymake-easy (0 1)) (emacs (24))) "A flymake handler for go-mode files using Golang CI lint" single ((:commit . "dfc31a1a6ae3f087b49fe6f5f21b3866780aa91c") (:authors ("Jorge Javier Araya Navarro" . "jorgejavieran@yahoo.com.mx")) (:maintainer "Jorge Javier Araya Navarro" . "jorgejavieran@yahoo.com.mx") (:url . "https://gitlab.com/shackra/flymake-golangci"))])
+ (flymake-gradle . [(20190315 233) ((emacs (26 1))) "Flymake extension for Gradle." single ((:commit . "dbedd29b78d4828ef57d4de20867be5df3eaab99") (:maintainer "James Nguyen" . "james@jojojames.com") (:keywords "languages" "gradle") (:url . "https://github.com/jojojames/flymake-gradle"))])
+ (flymake-grammarly . [(20220222 638) ((emacs (26 1)) (grammarly (0 3 0)) (s (1 12 0))) "Flymake support for Grammarly" single ((:commit . "7764178e6b51ccf0ce984b97385c22b2696d54f0") (:authors ("Shen, Jen-Chieh" . "jcs090218@gmail.com")) (:maintainer "Shen, Jen-Chieh" . "jcs090218@gmail.com") (:url . "https://github.com/emacs-grammarly/flymake-grammarly"))])
+ (flymake-hadolint . [(20220328 823) ((emacs (26 1))) "Flymake backend for hadolint, a Dockerfile linter" single ((:commit . "82a6df7f6cc95e1ab95c5d28f2edcd8c1d4c7382") (:authors ("Taiki Sugawara" . "buzz.taiki@gmail.com")) (:maintainer "Taiki Sugawara" . "buzz.taiki@gmail.com") (:keywords "convenience" "processes" "docker" "flymake") (:url . "https://github.com/buzztaiki/flymake-hadolint"))])
+ (flymake-haml . [(20170723 146) ((flymake-easy (0 1))) "A flymake handler for haml files" single ((:commit . "22a81e8484734552d461e7ae7305664dc244447e") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:url . "https://github.com/purcell/flymake-haml"))])
+ (flymake-haskell-multi . [(20170723 146) ((flymake-easy (0 1))) "Syntax-check haskell-mode using both ghc and hlint" tar ((:commit . "b564a94312259885b1380272eb867bf52a164020") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:url . "https://github.com/purcell/flymake-haskell-multi"))])
+ (flymake-hlint . [(20170723 146) ((flymake-easy (0 1))) "A flymake handler for haskell-mode files using hlint" single ((:commit . "f910736b26784efc9a2fa29503f45c1f1dd0aa38") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:url . "https://github.com/purcell/flymake-hlint"))])
+ (flymake-joker . [(20200315 1429) ((emacs (26 1)) (flymake-quickdef (0 1 1))) "Add Clojure syntax checker (via Joker) to flymake" single ((:commit . "fc132beedac9e6f415b72e578e77318fd13af9ee") (:authors ("Mateusz Probachta" . "mateusz.probachta@gmail.com")) (:maintainer "Mateusz Probachta" . "mateusz.probachta@gmail.com") (:url . "https://github.com/beetleman/flymake-joker"))])
+ (flymake-jshint . [(20140319 2200) ((flymake-easy (0 8))) "making flymake work with JSHint" single ((:commit . "79dd554c227883c487db38ac111306c8d5382c95") (:authors ("Wilfred Hughes" . "me@wilfred.me.uk")) (:maintainer "Wilfred Hughes" . "me@wilfred.me.uk") (:keywords "flymake" "jshint" "javascript"))])
+ (flymake-jslint . [(20170723 146) ((flymake-easy (0 1))) "A flymake handler for javascript using jslint" single ((:commit . "8edb82be605542b0ef62d38d818adcdde335eecb") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:url . "https://github.com/purcell/flymake-jslint"))])
+ (flymake-json . [(20180511 911) ((flymake-easy (0 1))) "A flymake handler for json using jsonlint" single ((:commit . "03b4e5e7ad11938781257a783e717ab95fe65952") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:url . "https://github.com/purcell/flymake-json"))])
+ (flymake-kondor . [(20211026 501) ((emacs (26 1))) "Linter with clj-kondo" single ((:commit . "784e57f36812a37e323409b90b935ef3c6920a22") (:authors ("https://turbocafe.keybase.pub")) (:maintainer "https://turbocafe.keybase.pub") (:url . "https://github.com/turbo-cafe/flymake-kondor"))])
+ (flymake-ktlint . [(20180831 346) ((emacs (26 1))) "Flymake extension for Ktlint." single ((:commit . "56aab6f2d22061999050783dbc3166cdb456d0bb") (:maintainer "James Nguyen" . "james@jojojames.com") (:keywords "languages" "ktlint") (:url . "https://github.com/jojojames/flymake-ktlint"))])
+ (flymake-languagetool . [(20220414 429) ((emacs (27 1)) (s (1 9 0))) "Flymake support for LanguageTool" single ((:commit . "db6abad075734dd01dbbd31cfec7ecb65ba16404") (:url . "https://github.com/emacs-languagetool/flymake-languagetool"))])
+ (flymake-less . [(20151111 738) ((less-css-mode (0 15)) (flymake-easy (0 1))) "Flymake handler for LESS stylesheets (lesscss.org)" single ((:commit . "32d3c28a9a5c52b82d1741ff9d715013b6498421") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:keywords "languages"))])
+ (flymake-lua . [(20170129 154) nil "Flymake for Lua" single ((:commit . "84589f20066921a5b79cf3a1f914a223a2552d2a") (:authors (nil . "Sébastien Roccaserra (format \"<%s%s@%s.%s>\" \"s\" \"roccaserra\" \"yahoo\" \"com\")")) (:maintainer nil . "Sébastien Roccaserra (format \"<%s%s@%s.%s>\" \"s\" \"roccaserra\" \"yahoo\" \"com\")") (:keywords "lua"))])
+ (flymake-markdownlint . [(20220320 1208) ((emacs (27 1))) "Markdown linter with markdownlint" single ((:commit . "59e3520668d9394c573e07b7980a2d48d9f6086c") (:authors ("Martin Kjær Jørgensen" . "mkj@gotu.dk")) (:maintainer "Martin Kjær Jørgensen" . "mkj@gotu.dk") (:url . "https://github.com/shaohme/flymake-markdownlint"))])
+ (flymake-nasm . [(20210310 1540) ((flymake-quickdef (1 0 0)) (emacs (26 1))) "A flymake handler for asm-mode files using nasm" single ((:commit . "27e58d7f3a48ca6fc12238fe6c888a3fdffc3f75") (:authors ("Jürgen Hötzel" . "juergen@hoetzel.info")) (:maintainer "Jürgen Hötzel") (:keywords "tools" "languages") (:url . "http://github.com/juergenhoetzel/flymake-nasm"))])
+ (flymake-perlcritic . [(20120328 814) ((flymake (0 3))) "Flymake handler for Perl to invoke Perl::Critic" tar ((:commit . "ee515ffdeb2a3b1162c82089e94cc31186eb2001") (:authors ("Sam Graham <libflymake-perlcritic-emacs BLAHBLAH illusori.co.uk>")) (:maintainer "Sam Graham <libflymake-perlcritic-emacs BLAHBLAH illusori.co.uk>") (:url . "https://github.com/illusori/emacs-flymake-perlcritic"))])
+ (flymake-pest . [(20200317 1503) ((emacs (26 3)) (pest-mode (0 1))) "A flymake handler for Pest files" single ((:commit . "43447a2c70f98edd1139005e32f437d3f142442b") (:authors ("ksqsf" . "i@ksqsf.moe") ("Naoya Yamashita" . "conao3@gmail.com")) (:maintainer "ksqsf" . "i@ksqsf.moe") (:keywords "languages" "flymake") (:url . "https://github.com/ksqsf/pest-mode"))])
+ (flymake-php . [(20170723 146) ((flymake-easy (0 1))) "A flymake handler for php-mode files" single ((:commit . "c045d01e002ba5e09b05f40e25bf5068d02126bc") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:url . "https://github.com/purcell/flymake-php"))])
+ (flymake-phpcs . [(20140713 631) ((flymake-easy (0 9))) "making flymake work with PHP CodeSniffer" single ((:commit . "2d442cff3408ecf3e576f0f3406fd6f567b16fa7") (:authors ("Akiha Senda")) (:maintainer "Akiha Senda") (:keywords "flymake" "phpcs" "php") (:url . "https://github.com/senda-akiha/flymake-phpcs/"))])
+ (flymake-phpstan . [(20210714 1805) ((emacs (26 1)) (phpstan (0 5 0))) "Flymake backend for PHP using PHPStan" single ((:commit . "0869b152f82a76138daa53e953285936b9d558bd") (:authors ("USAMI Kenta" . "tadsan@zonu.me")) (:maintainer "USAMI Kenta" . "tadsan@zonu.me") (:keywords "tools" "php") (:url . "https://github.com/emacs-php/phpstan.el"))])
+ (flymake-puppet . [(20170801 554) ((flymake-easy (0 9))) "Flymake handler using puppet-lint" single ((:commit . "8a772395f4ccc59d883712ab53a92a17c1d9a429") (:authors ("Ben Prew")) (:maintainer "Ben Prew") (:url . "https://github.com/benprew/flymake-puppet"))])
+ (flymake-python-pyflakes . [(20170723 146) ((flymake-easy (0 8))) "A flymake handler for python-mode files using pyflakes (or flake8)" single ((:commit . "1d65c26bf65a5dcbd29fcd967e2feb90e1e7a33d") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:url . "https://github.com/purcell/flymake-python-pyflakes"))])
+ (flymake-quickdef . [(20200308 2342) ((emacs (26 1))) "Quickly define a new Flymake backend" single ((:commit . "150c5839768a3d32f988f9dc08052978a68f2ad7") (:authors ("Karl Otness")) (:maintainer "Karl Otness") (:keywords "languages" "tools" "convenience" "lisp") (:url . "https://github.com/karlotness/flymake-quickdef"))])
+ (flymake-racket . [(20210105 606) ((emacs (26 1))) "Flymake extension for Racket." single ((:commit . "3d3e5f2a9ab696670f9e52baa4dde7b84b7542df") (:maintainer "James Nguyen" . "james@jojojames.com") (:keywords "languages" "racket" "scheme") (:url . "https://github.com/jojojames/flymake-racket"))])
+ (flymake-rakudo . [(20220424 637) ((emacs (28 1)) (flymake-collection (2 0 0)) (let-alist (1 0))) "Flymake syntax checker for Rakudo" single ((:commit . "f8e3d03a7207876cd891174702efd572d74f2e49") (:authors ("Siavash Askari Nasr" . "ciavash@proton.me")) (:maintainer "Siavash Askari Nasr" . "ciavash@proton.me") (:keywords "language" "tools" "convenience") (:url . "https://github.com/Raku/flymake-rakudo"))])
+ (flymake-ruby . [(20170723 146) ((flymake-easy (0 1))) "A flymake handler for ruby-mode files" single ((:commit . "6c320c6fb686c5223bf975cc35178ad6b195e073") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:url . "https://github.com/purcell/flymake-ruby"))])
+ (flymake-sass . [(20170723 146) ((flymake-easy (0 1))) "Flymake handler for sass and scss files" single ((:commit . "2de28148e92deb93bff3d55fe14e7c67ac476056") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:url . "https://github.com/purcell/flymake-sass"))])
+ (flymake-shell . [(20170723 146) ((flymake-easy (0 1))) "A flymake syntax-checker for shell scripts" single ((:commit . "a16cf453056b9849cc7c912bb127fb0b08fc6dab") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:url . "https://github.com/purcell/flymake-shell"))])
+ (flymake-shellcheck . [(20220308 2218) ((emacs (26))) "A bash/sh Flymake backend powered by ShellCheck" single ((:commit . "688638177b4e23ecc192975e3062274ca904ada1") (:authors ("Federico Tedin" . "federicotedin@gmail.com")) (:maintainer "Federico Tedin" . "federicotedin@gmail.com") (:url . "https://github.com/federicotdn/flymake-shellcheck"))])
+ (flymake-solidity . [(20170805 644) ((flymake-easy (0 10))) "A flymake handler for solidity using solc" single ((:commit . "48bfe9525f764d8a68cc0270905dbf45bfd00bb8") (:authors ("Pascal van Kooten" . "kootenpv@gmail.com")) (:maintainer "Pascal van Kooten" . "kootenpv@gmail.com") (:url . "https://github.com/kootenvp/flymake-solidity"))])
+ (flymake-swi-prolog . [(20220404 950) ((emacs (26 1))) "A Flymake backend for SWI-Prolog" single ((:commit . "ae0e4b706a40b71c007ed6cb0ec5425d49bea4c3") (:authors ("Eshel Yaron")) (:maintainer "Eshel Yaron") (:keywords "languages") (:url . "https://git.sr.ht/~eshel/flymake-swi-prolog"))])
+ (flymake-vala . [(20150326 531) ((flymake-easy (0 1))) "A flymake handler for vala-mode files" single ((:commit . "c3674f461fc84fb0300cd3a562fb903a59782745") (:authors ("Daniel Lawrence" . "dannyla@linux.com")) (:maintainer "Daniel Lawrence" . "dannyla@linux.com") (:keywords "convenience" "vala") (:url . "https://github.com/daniellawrence/flymake-vala"))])
+ (flymake-vnu . [(20181128 216) ((emacs (26 1))) "Flymake extension for the v.Nu HTML validator." single ((:commit . "7c4ab9d12611756ad5a80d866890b2f9b73fb611") (:maintainer "Stefan Kuznetsov" . "skuznetsov@posteo.net") (:keywords "languages") (:url . "https://github.com/theneosloth/flymake-vnu"))])
+ (flymake-yaml . [(20130423 1548) ((flymake-easy (0 1))) "A flymake handler for YAML" single ((:commit . "24cb5b744a1796e554e6dbfc6eeb237d06a00b10") (:authors ("Yasuyuki Oka" . "yasuyk@gmail.com")) (:maintainer "Yasuyuki Oka" . "yasuyk@gmail.com") (:keywords "yaml") (:url . "https://github.com/yasuyk/flymake-yaml"))])
+ (flymake-yamllint . [(20220311 636) ((emacs (26 1))) "YAML linter with yamllint" single ((:commit . "a93bf9a6697566f0e29fb51a87c5cc7b2a972d2d") (:authors ("Martin Kjær Jørgensen" . "mkj@gotu.dk")) (:maintainer "Martin Kjær Jørgensen" . "mkj@gotu.dk") (:url . "https://github.com/shaohme/flymake-yamllint"))])
+ (flymd . [(20160617 1214) ((cl-lib (0 5))) "On the fly markdown preview" tar ((:commit . "84d5a68bcfed4a295952c33ffcd11e880978d9d7") (:authors ("Mola-T" . "Mola@molamola.xyz")) (:maintainer "Mola-T" . "Mola@molamola.xyz") (:keywords "markdown" "convenience") (:url . "https://github.com/mola-T/flymd"))])
+ (flyparens . [(20140723 1846) nil "Check for unbalanced parens on the fly" tar ((:commit . "af9b8cfd647d0e5f97684d613dc2eea7cfc19398") (:authors ("Jisang Yoo")) (:maintainer "Jisang Yoo") (:keywords "faces" "convenience" "lisp" "matching" "parentheses" "parens"))])
+ (flyspell-correct . [(20220131 834) ((emacs (24))) "Correcting words with flyspell via custom interface" tar ((:commit . "e8027a412262bc04056a5b5440efdb7f370c3320") (:authors ("Boris Buliga" . "boris@d12frosted.io")) (:maintainer "Boris Buliga" . "boris@d12frosted.io") (:url . "https://github.com/d12frosted/flyspell-correct"))])
+ (flyspell-correct-avy-menu . [(20210124 1143) ((flyspell-correct (0 6 1)) (avy-menu (0 1 1)) (emacs (24))) "Correcting words with flyspell via avy-menu interface" single ((:commit . "e8027a412262bc04056a5b5440efdb7f370c3320") (:authors ("Boris Buliga" . "boris@d12frosted.io") ("Clemens Radermacher" . "clemera@posteo.net")) (:maintainer "Boris Buliga" . "boris@d12frosted.io") (:url . "https://github.com/d12frosted/flyspell-correct"))])
+ (flyspell-correct-helm . [(20210124 1143) ((flyspell-correct (0 6 1)) (helm (1 9 0)) (emacs (24))) "Correcting words with flyspell via helm interface" single ((:commit . "e8027a412262bc04056a5b5440efdb7f370c3320") (:authors ("Boris Buliga" . "boris@d12frosted.io")) (:maintainer "Boris Buliga" . "boris@d12frosted.io") (:url . "https://github.com/d12frosted/flyspell-correct"))])
+ (flyspell-correct-ivy . [(20210124 1143) ((flyspell-correct (0 6 1)) (ivy (0 8 0)) (emacs (24 4))) "Correcting words with flyspell via ivy interface" single ((:commit . "e8027a412262bc04056a5b5440efdb7f370c3320") (:authors ("Boris Buliga" . "boris@d12frosted.io")) (:maintainer "Boris Buliga" . "boris@d12frosted.io") (:url . "https://github.com/d12frosted/flyspell-correct"))])
+ (flyspell-correct-popup . [(20210124 1143) ((flyspell-correct (0 6 1)) (popup (0 5 3)) (emacs (24))) "Correcting words with flyspell via popup interface" single ((:commit . "e8027a412262bc04056a5b5440efdb7f370c3320") (:authors ("Boris Buliga" . "boris@d12frosted.io")) (:maintainer "Boris Buliga" . "boris@d12frosted.io") (:url . "https://github.com/d12frosted/flyspell-correct"))])
+ (flyspell-lazy . [(20210308 1253) nil "Improve flyspell responsiveness using idle timers" single ((:commit . "0fc5996bcee20b46cbd227ae948d343c3bef7339") (:authors ("Roland Walker" . "walker@pobox.com")) (:maintainer "Roland Walker" . "walker@pobox.com") (:keywords "spelling") (:url . "http://github.com/rolandwalker/flyspell-lazy"))])
+ (flyspell-popup . [(20170529 815) ((popup (0 5 0))) "Correcting words with Flyspell in popup menus" single ((:commit . "29311849bfd253b9b689bf331860b4c4d3bd4dde") (:authors ("Chunyang Xu" . "mail@xuchunyang.me")) (:maintainer "Chunyang Xu" . "mail@xuchunyang.me") (:keywords "convenience") (:url . "https://github.com/xuchunyang/flyspell-popup"))])
+ (fm-bookmarks . [(20170104 1716) ((emacs (24 3)) (cl-lib (0 5))) "Use file manager bookmarks (eg Dolphin, Nautilus, PCManFM) in Dired" single ((:commit . "11dacfd16a926bfecba96a94c6b13e162c7717f7") (:authors ("Ono Hiroko" . "azazabc123@gmail.com")) (:maintainer "Ono Hiroko" . "azazabc123@gmail.com") (:keywords "files" "convenience") (:url . "http://github.com/kuanyui/fm-bookmarks.el"))])
+ (fn . [(20210304 1812) ((emacs (24)) (cl-lib (0 5)) (dash (2 18 0))) "Concise anonymous functions for Emacs Lisp" single ((:commit . "98e3fe1b4785e162d9aca978a2db106baa79260f") (:authors ("Troy Pracy")) (:maintainer "Troy Pracy") (:keywords "functional"))])
+ (focus . [(20191209 2210) ((emacs (24 3)) (cl-lib (0 5))) "Dim the font color of text in surrounding sections" single ((:commit . "5f3f20e7f22fb9fd7c48abce8bd38061d97e4bc0") (:authors ("Lars Tveito" . "larstvei@ifi.uio.no")) (:maintainer "Lars Tveito" . "larstvei@ifi.uio.no") (:url . "http://github.com/larstvei/Focus"))])
+ (focus-autosave-mode . [(20160519 2116) ((emacs (24 4))) "Automatically save files in focus-out-hook." single ((:commit . "2e0844fabb6f0dc9e0f31928e4785febf38b9e35") (:authors ("Wojciech Siewierski" . "wojciech.siewierski@onet.pl")) (:maintainer "Wojciech Siewierski" . "wojciech.siewierski@onet.pl") (:keywords "convenience" "files" "frames" "mouse"))])
+ (foggy-night-theme . [(20190123 1614) ((emacs (24))) "Dark low contrast theme with soft and muted colors." single ((:commit . "14894e06ee5c6e14db36f2cb07387ee971c1736f") (:authors ("Martin Haesler")) (:maintainer "Martin Haesler"))])
+ (fold-dwim . [(20140208 1637) nil "Unified user interface for Emacs folding modes" single ((:commit . "c46f4bb2ce91b4e307136320e72c28dd50b6cd8b") (:authors ("Peter Heslin" . "p.j.heslin@dur.ac.uk")) (:maintainer "Peter Heslin" . "p.j.heslin@dur.ac.uk") (:url . "http://www.dur.ac.uk/p.j.heslin/Software/Emacs"))])
+ (fold-dwim-org . [(20131203 1351) ((fold-dwim (1 2))) "Fold DWIM bound to org key-strokes." single ((:commit . "c09bb2b46d65afbd1d0febc6fded7495be7a3037") (:authors ("Matthew L. Fidler & Shane Celis")) (:maintainer "Matthew L. Fidler") (:keywords "folding" "emacs" "org-mode") (:url . "https://github.com/mlf176f2/fold-dwim-org"))])
+ (fold-this . [(20191107 1816) nil "Just fold this region please" single ((:commit . "c3912c738cf0515f65162479c55999e2992afce5") (:authors ("Magnar Sveen" . "magnars@gmail.com")) (:maintainer "Magnar Sveen" . "magnars@gmail.com") (:keywords "convenience") (:url . "https://github.com/magnars/fold-this.el"))])
+ (folding . [(20220110 1718) nil "A folding-editor-like minor mode." tar ((:commit . "1ce338b991c69358a607c37bfb16ffb7de7e91c4") (:maintainer "Jari Aalto <jari aalto A T cante dt net>") (:keywords "tools"))])
+ (font-lock-profiler . [(20170208 2008) ((emacs (24 3))) "Coverage and timing tool for font-lock keywords." single ((:commit . "6e096458416888a4f63cca0d6bc5965a052753c8") (:authors ("Anders Lindgren")) (:maintainer "Anders Lindgren") (:keywords "faces" "tools") (:url . "https://github.com/Lindydancer/font-lock-profiler"))])
+ (font-lock-studio . [(20170127 2051) ((emacs (24 3))) "interactive debugger for Font Lock keywords." single ((:commit . "12c35967b31233e06946c70627aa3152dacfe261") (:authors ("Anders Lindgren")) (:maintainer "Anders Lindgren") (:keywords "faces" "tools") (:url . "https://github.com/Lindydancer/font-lock-studio"))])
+ (font-utils . [(20210405 1149) ((persistent-soft (0 8 8)) (pcache (0 2 3))) "Utility functions for working with fonts" single ((:commit . "abc572eb0dc30a26584c0058c3fe6c7273a10003") (:authors ("Roland Walker" . "walker@pobox.com")) (:maintainer "Roland Walker" . "walker@pobox.com") (:keywords "extensions") (:url . "http://github.com/rolandwalker/font-utils"))])
+ (fontawesome . [(20170305 1356) ((emacs (24 4))) "fontawesome utility" tar ((:commit . "a5fafe89d4032fd1f0c21b7b04708ef2cce2517b") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-fontawesome"))])
+ (fontify-face . [(20210503 1956) ((emacs (24))) "Fontify symbols representing faces with that face." single ((:commit . "d1386c88ccc77ccfb40b888ff90d6181325d14f8") (:authors ("Matúš Goljer" . "matus.goljer@gmail.com")) (:maintainer "Matúš Goljer" . "matus.goljer@gmail.com") (:keywords "faces") (:url . "https://github.com/Fuco1/fontify-face"))])
+ (fontsloth . [(20211118 2018) ((f (0 20 0)) (logito (0 1)) (pcache (0 5)) (stream (2 2 5)) (emacs (28 0))) "Elisp otf/ttf font loader/renderer" tar ((:commit . "5572a44e14d6c00a628f58cc695c735ef64e0ebd") (:authors ("Jo Gay" . "jo.gay@mailfence.com")) (:maintainer "Jo Gay" . "jo.gay@mailfence.com") (:keywords "data" "font" "rasterization" "ttf" "otf") (:url . "https://github.com/jollm/fontsloth"))])
+ (forecast . [(20191004 1850) ((emacs (24 4))) "Weather forecasts" single ((:commit . "350af0e5d53307c900e4f8b2617f3852f51a74d2") (:authors ("Göktuğ Kayaalp" . "self@gkayaalp.com")) (:maintainer "Göktuğ Kayaalp" . "self@gkayaalp.com") (:keywords "weather" "forecast") (:url . "https://dev.gkayaalp.com/elisp/index.html#forecast-el"))])
+ (foreign-regexp . [(20200325 50) nil "search and replace by foreign regexp." tar ((:commit . "e2dd47f2160cadc194eb156e7c76c3c869e6706e") (:authors ("K-talo Miyazaki <Keitaro dot Miyazaki at gmail dot com>")) (:maintainer "K-talo Miyazaki <Keitaro dot Miyazaki at gmail dot com>") (:keywords "convenience" "emulations" "matching" "tools" "unix" "wp"))])
+ (foreman-mode . [(20170725 1422) ((s (1 9 0)) (dash (2 10 0)) (dash-functional (1 2 0)) (f (0 17 2)) (emacs (24))) "View and manage Procfile-based applications" single ((:commit . "22b3bb13134b617870ed1e888af739f4818be929") (:authors ("ZHOU Feng" . "zf.pascal@gmail.com")) (:maintainer "ZHOU Feng" . "zf.pascal@gmail.com") (:keywords "foreman") (:url . "http://github.com/zweifisch/foreman-mode"))])
+ (forest-blue-theme . [(20160627 842) ((emacs (24))) "Emacs theme with a dark background." single ((:commit . "58096ce1a25615d2bae806c3775bae3e2775019d") (:authors ("olkinn")) (:maintainer "olkinn"))])
+ (forge . [(20220503 1116) ((emacs (25 1)) (compat (28 1 1 0)) (closql (1 2 0)) (dash (2 19 1)) (emacsql-sqlite (3 0 0)) (ghub (3 5 4)) (let-alist (1 0 6)) (magit (3 3 0)) (markdown-mode (2 4)) (transient (0 3 6)) (yaml (0 3 4))) "Access Git forges from Magit." tar ((:commit . "e3afbc9400a8c52100dc022207adbf0198df9639") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:keywords "git" "tools" "vc") (:url . "https://github.com/magit/forge"))])
+ (form-feed . [(20210508 1627) ((emacs (24 1))) "Display ^L glyphs as horizontal lines" single ((:commit . "ac1f0ef30a11979f5dfe12d8c05a666739e486ff") (:authors ("Vasilij Schneidermann" . "mail@vasilij.de")) (:maintainer "Vasilij Schneidermann" . "mail@vasilij.de") (:keywords "faces") (:url . "https://depp.brause.cc/form-feed"))])
+ (format-all . [(20220412 1141) ((emacs (24 4)) (inheritenv (0 1)) (language-id (0 19))) "Auto-format C, C++, JS, Python, Ruby and 50 other languages" single ((:commit . "a07bf109ce8e27458a40420508943f53856549fc") (:authors ("Lassi Kortela" . "lassi@lassi.io")) (:maintainer "Lassi Kortela" . "lassi@lassi.io") (:keywords "languages" "util") (:url . "https://github.com/lassik/emacs-format-all-the-code"))])
+ (format-sql . [(20150422 1333) nil "Use format-sql to make your SQL readable in directly Emacs." single ((:commit . "97f475c245cd6c81a72a265678e2087cee66ac7b") (:authors ("Friedrich Paetzke" . "paetzke@fastmail.fm")) (:maintainer "Friedrich Paetzke" . "paetzke@fastmail.fm") (:url . "https://github.com/paetzke/format-sql.el"))])
+ (format-table . [(20181223 1616) ((emacs (25)) (dash (2 14 1))) "Parse and reformat tabular data." single ((:commit . "dfcae3a867e574577fc09a43b045889ff155b58f") (:authors ("Jason Duncan" . "jasond496@msn.com")) (:maintainer "Jason Duncan" . "jasond496@msn.com") (:keywords "data") (:url . "https://github.com/functionreturnfunction/format-table"))])
+ (forth-mode . [(20220402 2103) nil "Programming language mode for Forth" tar ((:commit . "122a9916c1ad1f1e3f4888951e1ad92a2fc10804") (:authors ("Lars Brinkhoff" . "lars@nocrew.org")) (:maintainer "Lars Brinkhoff" . "lars@nocrew.org") (:keywords "languages" "forth") (:url . "http://github.com/larsbrinkhoff/forth-mode"))])
+ (fortpy . [(20150715 2032) ((epc (0 1 0)) (auto-complete (1 4)) (python-environment (0 0 2)) (pos-tip (0 4 5))) "a Fortran auto-completion for Emacs" tar ((:commit . "c614517e9396ef7a78be3b8786fbf303879cf43b") (:authors ("Conrad Rosenbrock <rosenbrockc at gmail.com>")) (:maintainer "Conrad Rosenbrock <rosenbrockc at gmail.com>"))])
+ (fortune-cookie . [(20181223 842) nil "Print a fortune in your scratch buffer." single ((:commit . "6c1c08f5be83822c0b762872ab25e3dbee96f333") (:authors ("Andrew Schwartzmeyer" . "andrew@schwartzmeyer.com")) (:maintainer "Andrew Schwartzmeyer" . "andrew@schwartzmeyer.com") (:keywords "fortune" "cowsay" "scratch" "startup") (:url . "https://github.com/andschwa/fortune-cookie"))])
+ (fountain-mode . [(20211223 405) ((emacs (24 4)) (seq (2 20))) "Major mode for screenwriting in Fountain markup" tar ((:commit . "fba17c2b316122e26292ba995f1c62191b7b3eb0") (:authors ("Paul W. Rankin" . "pwr@bydasein.com")) (:maintainer "Paul W. Rankin" . "pwr@bydasein.com") (:keywords "wp" "text") (:url . "https://github.com/rnkn/fountain-mode"))])
+ (fraktur-mode . [(20160815 227) ((cl-lib (0 5))) "Easily insert Unicode mathematical Fraktur characters" single ((:commit . "514baf5546aed12a0d9fa0fe66e87cdcc7843b08") (:authors ("Grant Rettke" . "gcr@wisdomandwonder.com")) (:maintainer nil . "<gcr@wisdomandwonder.com>") (:keywords "unicode" "fraktur" "math" "mathematical") (:url . "https://github.com/grettke/fraktur-mode"))])
+ (frame-local . [(20180330 940) ((emacs (25 1))) "Variables local to a frame" single ((:commit . "7ee1106c3bcd4022f48421f8cb1ef4f995da816e") (:authors ("Sebastien Chapuis" . "sebastien@chapu.is")) (:maintainer "Sebastien Chapuis" . "sebastien@chapu.is") (:keywords "frames" "tools" "local" "lisp") (:url . "https://github.com/sebastiencs/frame-local"))])
+ (frame-mode . [(20190710 2030) ((s (1 9 0)) (emacs (24 4))) "Use frames instead of windows" single ((:commit . "ae2366969927c9f89ea07c999bef382b0b47cac1") (:authors ("Ivan Malison" . "IvanMalison@gmail.com")) (:maintainer "Ivan Malison" . "IvanMalison@gmail.com") (:keywords "frames") (:url . "https://github.com/IvanMalison/frame-mode"))])
+ (frame-purpose . [(20211011 1518) ((emacs (25 1)) (dash (2 18))) "Purpose-specific frames" single ((:commit . "7d498147445cc0afb87b922a8225d2e163e5ed5a") (:authors ("Adam Porter" . "adam@alphapapa.net")) (:maintainer "Adam Porter" . "adam@alphapapa.net") (:keywords "buffers" "convenience" "frames") (:url . "http://github.com/alphapapa/frame-purpose.el"))])
+ (frame-tag . [(20170111 6) ((cl-lib (0 5))) "Minor mode that assigns a unique number to each frame for easy switching" single ((:commit . "73d6163568c7d32952175e663318b872f995a4e5") (:authors ("Wong Liang Zan" . "zan@liangzan.net")) (:maintainer "Wong Liang Zan" . "zan@liangzan.net") (:keywords "frame" "movement") (:url . "http://github.com/liangzan/frame-tag.el"))])
+ (frames-only-mode . [(20210107 918) ((emacs (24 4)) (dash (2 13 0)) (s (1 11 0))) "Use frames instead of Emacs windows" single ((:commit . "d3f6647c484656ddabdac5d18546599a03823cd4") (:authors ("David Shepherd" . "davidshepherd7@gmail.com")) (:maintainer "David Shepherd" . "davidshepherd7@gmail.com") (:keywords "frames" "windows") (:url . "https://github.com/davidshepherd7/frames-only-mode"))])
+ (frameshot . [(20220422 1610) ((emacs (25 3)) (compat (28 1 1 0))) "Take screenshots of a frame" single ((:commit . "fa5e2363efabc2e61e79bd66c96e7d1a5c827a0d") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:keywords "multimedia") (:url . "https://github.com/tarsius/frameshot"))])
+ (framesize . [(20131017 2132) ((key-chord (0 5 20080915))) "change the size of frames in Emacs" single ((:commit . "f2dbf5d2513b2bc45f2085370a55c1754b6025da") (:authors ("Nic Ferrier" . "nferrier@ferrier.me.uk")) (:maintainer "Nic Ferrier" . "nferrier@ferrier.me.uk") (:keywords "frames") (:url . "http://github.com/nicferrier/emacs-framesize"))])
+ (frecency . [(20170909 631) ((emacs (25 1)) (a (0 1)) (dash (2 13 0))) "Library for sorting items by frequency and recency of access" single ((:commit . "6d57aee131d96315aedf6cb7d6e5d6d09bf71503") (:authors ("Adam Porter" . "adam@alphapapa.net")) (:maintainer "Adam Porter" . "adam@alphapapa.net") (:keywords "libraries" "recency" "recent" "frequency" "frequent") (:url . "http://github.com/alphapapa/frecency.el"))])
+ (frecentf . [(20210330 1521) ((emacs (26 1)) (frecency (0 1 -1)) (persist (0 4)) (async (1 9 4))) "Pervasive recentf using frecency" single ((:commit . "19e2c48a8b8c8ee8cae5c93b58b57a0aa81a8c46") (:authors ("Felipe Lema" . "felipel@mortemale.org")) (:maintainer "Felipe Lema" . "felipel@mortemale.org") (:keywords "files" "maint") (:url . "https://launchpad.net/frecentf.el"))])
+ (free-keys . [(20211116 1501) ((cl-lib (0 3))) "Show free keybindings for modkeys or prefixes" single ((:commit . "7348ce68192871b8a69b687ec124d9f816d493ca") (:authors ("Matus Goljer" . "matus.goljer@gmail.com")) (:maintainer "Matus Goljer" . "matus.goljer@gmail.com") (:keywords "convenience") (:url . "https://github.com/Fuco1/free-keys"))])
+ (freeradius-mode . [(20190401 1743) ((emacs (24 4))) "major mode for FreeRadius server config files" single ((:commit . "cf8bf0359cf6c77848facbd24b764b3e111b4c2d") (:url . "https://github.com/VersBinarii/freeradius-mode"))])
+ (freeze-it . [(20220301 148) ((emacs (24 4))) "Minor mode to make your previous writing read-only" single ((:commit . "ad92e33a7ebd860905da60d194833516bf61cbf5") (:authors ("Paul W. Rankin" . "pwr@bydasein.com")) (:maintainer "Paul W. Rankin" . "pwr@bydasein.com") (:keywords "wp" "text") (:url . "https://github.com/rnkn/freeze-it"))])
+ (friendly-remote-shell . [(20200527 830) ((emacs (24 1)) (cl-lib (0 6 1)) (with-shell-interpreter (0 2 3)) (friendly-tramp-path (0 1 0)) (friendly-shell (0 2 0))) "Human-friendly remote interactive shells" single ((:commit . "e530e359848e8bdad09d26529f17eb25e5558b3e") (:keywords "processes" "terminals") (:url . "https://github.com/p3r7/friendly-shell"))])
+ (friendly-shell . [(20220309 1711) ((emacs (24 1)) (cl-lib (0 6 1)) (dash (2 17 0)) (with-shell-interpreter (0 2 4))) "Better shell-mode API" single ((:commit . "e530e359848e8bdad09d26529f17eb25e5558b3e") (:keywords "processes" "terminals") (:url . "https://github.com/p3r7/friendly-shell"))])
+ (friendly-shell-command . [(20200527 830) ((emacs (24 1)) (cl-lib (0 6 1)) (dash (2 17 0)) (with-shell-interpreter (0 2 3))) "Better shell-command API" single ((:commit . "e530e359848e8bdad09d26529f17eb25e5558b3e") (:keywords "processes" "terminals") (:url . "https://github.com/p3r7/friendly-shell"))])
+ (friendly-tramp-path . [(20200502 1032) ((cl-lib (0 6 1))) "Human-friendly TRAMP path construction" single ((:commit . "be572b8953b9e5a3a35c30bb64c2936d3e9802ba") (:url . "https://github.com/p3r7/prf-tramp"))])
+ (fringe-current-line . [(20140111 411) nil "show current line on the fringe." single ((:commit . "0ef000bac76abae30601222e6f06c7d133ab4942") (:authors ("Kouhei Yanagita" . "yanagi@shakenbu.org")) (:maintainer "Kouhei Yanagita" . "yanagi@shakenbu.org") (:url . "http://github.com/kyanagi/fringe-current-line/raw/master/fringe-current-line.el"))])
+ (fringe-helper . [(20140620 2109) nil "helper functions for fringe bitmaps" single ((:commit . "ef4a9c023bae18ec1ddd7265f1f2d6d2e775efdd") (:authors ("Nikolaj Schumacher <bugs * nschum de>")) (:maintainer "Nikolaj Schumacher <bugs * nschum de>") (:keywords "lisp") (:url . "http://nschum.de/src/emacs/fringe-helper/"))])
+ (frog-jump-buffer . [(20220414 1935) ((emacs (24)) (avy (0 4 0)) (dash (2 4 0)) (frog-menu (0 2 8))) "The fastest buffer-jumping Emacs lisp package around." single ((:commit . "ff0cfe9cb4a60d855f0754b741a9417ee413dee0") (:authors ("Justin Talbott")) (:maintainer "Justin Talbott") (:keywords "convenience" "tools") (:url . "https://github.com/waymondo/frog-jump-buffer"))])
+ (frontside-javascript . [(20220315 1057) ((emacs (25 1)) (add-node-modules-path (1 2 0)) (company (0 9 2)) (flycheck (20201228 2104)) (js2-mode (20201220)) (js2-refactor (0 9 0)) (rjsx-mode (0 5 0)) (tide (4 0 2)) (web-mode (17)) (lsp-mode (20220124))) "JS development that just work™️" tar ((:commit . "18816534a977fbd28848389b58c22b6538cfdeec") (:authors ("Frontside Engineering" . "engineering@frontside.com")) (:maintainer "Frontside Engineering" . "engineering@frontside.com") (:keywords "files" "tools") (:url . "https://github.com/thefrontside/frontmacs"))])
+ (fsbot-data-browser . [(20160921 1533) nil "browse the fsbot database using tabulated-list-mode" single ((:commit . "6bca4f7de63e31839d2542f6c678b79931dec344") (:authors ("Benaiah Mischenko")) (:maintainer "Benaiah Mischenko") (:keywords "fsbot" "irc" "tabulated-list-mode") (:url . "http://github.com/benaiah/fsbot-data-browser"))])
+ (fsharp-mode . [(20220429 1847) ((emacs (25))) "Support for the F# programming language" tar ((:commit . "5208b54098c7534f4768b87c5f4c8a01b638737b") (:authors ("1993-1997 Xavier Leroy, Jacques Garrigue and Ian T Zimmerman") ("2010-2011 Laurent Le Brun" . "laurent@le-brun.eu") ("2012-2014 Robin Neatherway" . "robin.neatherway@gmail.com") ("2017-2022 Jürgen Hötzel")) (:maintainer "Jürgen Hötzel") (:keywords "languages"))])
+ (fstar-mode . [(20220106 2256) ((emacs (24 3)) (dash (2 11)) (company (0 8 12)) (quick-peek (1 0)) (yasnippet (0 11 0)) (flycheck (30 0)) (company-quickhelp (2 2 0))) "Support for F* programming" tar ((:commit . "c95c2a61a6c42a1fa8bab9a8eb812a41be3e6f69") (:authors ("Clément Pit-Claudel" . "clement.pitclaudel@live.com")) (:maintainer "Clément Pit-Claudel" . "clement.pitclaudel@live.com") (:keywords "convenience" "languages") (:url . "https://github.com/FStarLang/fstar-mode.el"))])
+ (fuel . [(20211221 2127) ((cl-lib (0 2)) (emacs (24 2))) "Major mode for the Factor programming language." tar ((:commit . "b90d529eacb643421991f94288151e72ed573b55"))])
+ (fuff . [(20170202 1503) ((seq (2 3))) "Find files with findutils, recursively" single ((:commit . "278e849913df87bd8756c59382282d87474802c3") (:authors ("Joel Moberg")) (:maintainer "Joel Moberg") (:keywords "files" "project" "convenience") (:url . "https://github.com/joelmo/fuff"))])
+ (full-ack . [(20140223 1732) nil "a front-end for ack" single ((:commit . "761d846e105b150f8e6d13d7a8983f0248313a45") (:authors ("Nikolaj Schumacher <bugs * nschum de>")) (:maintainer "Nikolaj Schumacher <bugs * nschum de>") (:keywords "tools" "matching") (:url . "http://nschum.de/src/emacs/full-ack/"))])
+ (fullframe . [(20210226 1057) ((cl-lib (0 5))) "Generalized automatic execution in a single frame" single ((:commit . "886b831c001b44ec95aec4ff36e8bc1b3003c786") (:authors ("Tom Regner" . "tom@goochesa.de")) (:maintainer "Tom Regner" . "tom@goochesa.de") (:keywords "fullscreen"))])
+ (function-args . [(20211231 1150) ((ivy (0 9 1))) "C++ completion for GNU Emacs" tar ((:commit . "503e78fad9e7741ef4b8f5c24ff70c8909240db2") (:authors ("Oleh Krehel" . "ohwoeowho@gmail.com")) (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com") (:url . "https://github.com/abo-abo/function-args"))])
+ (fuo . [(20190812 927) ((emacs (24 4))) "feeluown client." single ((:commit . "0e4122f94a336a50c02bc96652d25ac3d74bedeb") (:authors ("cosven" . "yinshaowen241@gmail.com")) (:maintainer "cosven" . "yinshaowen241@gmail.com") (:keywords "feeluown" "multimedia" "unix") (:url . "http://github.com/cosven/emacs-fuo"))])
+ (furl . [(20150509 316) nil "Friendly URL retrieval" single ((:commit . "014438271e0ef27333dfcd599cb247f12a20d870") (:authors ("Natalie Weizenbaum" . "nweiz@google.com")) (:maintainer "Natalie Weizenbaum" . "nweiz@google.com"))])
+ (futhark-mode . [(20220425 1144) ((emacs (24 3)) (cl-lib (0 5))) "major mode for editing Futhark source files" tar ((:commit . "7fd0a3c6c96ed8afd0249ab0734d9b63d4fd1cb1") (:keywords "languages") (:url . "https://github.com/diku-dk/futhark-mode"))])
+ (fuz . [(20200104 524) ((emacs (25 1))) "Fast and precise fuzzy scoring/matching utils" tar ((:commit . "fee874aa35d2ee6b12b836290b5c8eaa44175a28") (:authors ("Zhu Zihao" . "all_but_last@163.com")) (:maintainer "Zhu Zihao" . "all_but_last@163.com") (:keywords "lisp") (:url . "https://github.com/cireu/fuz.el"))])
+ (fuzzy . [(20211231 1837) ((emacs (24 3))) "Fuzzy Matching" single ((:commit . "ea361ce0f702c5f92ad4a89017def9c1619a3191") (:authors ("Tomohiro Matsuyama" . "m2ym.pub@gmail.com")) (:maintainer "Tomohiro Matsuyama" . "m2ym.pub@gmail.com") (:keywords "convenience") (:url . "https://github.com/auto-complete/fuzzy-el"))])
+ (fuzzy-finder . [(20210906 217) ((emacs (24 4))) "Fuzzy Finder App Integration" single ((:commit . "915a281fc8e50df84dcc205f9357e8314d60fa54") (:authors ("10sr" . "8.slashes@gmail.com")) (:maintainer "10sr" . "8.slashes@gmail.com") (:keywords "matching") (:url . "https://github.com/10sr/fuzzy-finder-el"))])
+ (fvwm-mode . [(20160411 1138) nil "A major mode for editing Fvwm configuration files" single ((:commit . "6832a1c1f68bf6249c3fd6672ea8e27dc7a5c79e") (:authors ("Bert Geens" . "bert@lair.be")) (:maintainer "Bert Geens" . "bert@lair.be") (:keywords "files") (:url . "https://github.com/theBlackDragon/fvwm-mode"))])
+ (fwb-cmds . [(20220422 1610) ((emacs (25 1)) (compat (28 1 1 0))) "misc frame, window and buffer commands" single ((:commit . "4bd3c23c3dc649ab5412e2bad7eebe3069363190") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:keywords "convenience") (:url . "https://github.com/tarsius/fwb-cmds"))])
+ (fxrd-mode . [(20170728 1801) ((s (1 2))) "Major mode for editing fixed field width files" tar ((:commit . "18a603474abb5a786a8d9f20c283d5f7beed3540") (:authors ("Marc Sherry" . "msherry@gmail.com")) (:maintainer "Marc Sherry" . "msherry@gmail.com") (:keywords "convenience") (:url . "https://github.com/msherry/fxrd-mode"))])
+ (fyure . [(20130216 1314) nil "An interface to fix Japanese hyoki-yure" tar ((:commit . "b6977f1eb148e8b63259f7233b55bb050e44d9b8") (:authors ("Masafumi Oyamada" . "stillpedant@gmail.com")) (:maintainer "Masafumi Oyamada" . "stillpedant@gmail.com") (:keywords "languages"))])
+ (fzf . [(20211228 2005) ((emacs (24 4))) "A front-end for fzf." single ((:commit . "d61cecbdb60b0f10cecd50ff2ae115aeb77f9fdc") (:authors ("Bailey Ling")) (:maintainer "Bailey Ling") (:keywords "fzf" "fuzzy" "search") (:url . "https://github.com/bling/fzf.el"))])
+ (gameoflife . [(20200614 1814) nil "Screensaver running Conway's Game of Life" single ((:commit . "2483f3d98dbcf7f1633f551cc3691f5659b4b942") (:authors ("Anders Lindgren")) (:maintainer "Anders Lindgren") (:keywords "games") (:url . "https://github.com/Lindydancer/gameoflife"))])
+ (gams-ac . [(20180423 926) ((emacs (24)) (auto-complete (1 0)) (gams-mode (4 0))) "auto-complete source file for GAMS mode" single ((:commit . "66d04ff36033f54205c19bc1d893e926d4dbf02e") (:authors ("Shiro Takeda")) (:maintainer "Shiro Takeda") (:keywords "languages" "tools" "gams-mode" "auto-complete") (:url . "https://github.com/ShiroTakeda/gams-ac"))])
+ (gams-mode . [(20220501 1507) ((emacs (24 3))) "Major mode for General Algebraic Modeling System (GAMS)" tar ((:commit . "1964d9a52693f3aa9279eed8864bc317ee5c6dc4") (:authors ("Shiro Takeda")) (:maintainer "Shiro Takeda") (:keywords "languages" "tools" "gams") (:url . "http://shirotakeda.org/en/gams/gams-mode/"))])
+ (gandalf-theme . [(20130809 947) nil "Gandalf color theme" single ((:commit . "4e472fc851431458537d458d09c1f5895e338536") (:authors ("Peter Vasil" . "mail@petervasil.net")) (:maintainer "Peter Vasil" . "mail@petervasil.net") (:keywords "color" "theme"))])
+ (gap-mode . [(20220503 1555) nil "Major mode for editing files in the GAP programing language." tar ((:commit . "99237f714c28981142674e8cfeb155863c834858") (:authors ("Michael Smith" . "smith@pell.anu.edu.au") ("Gary Zablackis") ("Goetz Pfeiffer") ("Ivan Andrus" . "darthandrus@gmail.com")) (:maintainer "Ivan Andrus" . "darthandrus@gmail.com") (:keywords "gap") (:url . "https://gitlab.com/gvol/gap-mode"))])
+ (gather . [(20141230 1338) nil "Gather string in buffer." single ((:commit . "50809fbc22d70a1c724c2dd99ac5a1f818ffeb6b") (:authors ("Masahiro Hayashi" . "mhayashi1120@gmail.com")) (:maintainer "Masahiro Hayashi" . "mhayashi1120@gmail.com") (:keywords "matching" "convenience" "tools") (:url . "https://github.com/mhayashi1120/Emacs-gather/raw/master/gather.el"))])
+ (gcmh . [(20201116 2251) ((emacs (24))) "the Garbage Collector Magic Hack" single ((:commit . "0089f9c3a6d4e9a310d0791cf6fa8f35642ecfd9") (:authors ("Andrea Corallo" . "akrl@sdf.org")) (:maintainer nil . "akrl@sdf.org") (:keywords "internal") (:url . "https://gitlab.com/koral/gcmh"))])
+ (gcode-mode . [(20210522 1025) ((emacs (24 4))) "Simple G-Code major mode" tar ((:commit . "1f83845af4102efc5e5856b55bd5ad165b2f0cdd") (:authors ("Yuri D'Elia" . "wavexx@thregr.org")) (:maintainer "Yuri D'Elia" . "wavexx@thregr.org") (:keywords "gcode" "languages" "highlight" "syntax") (:url . "https://gitlab.com/wavexx/gcode-mode.el"))])
+ (gdscript-mode . [(20210328 2037) ((emacs (26 3))) "Major mode for Godot's GDScript language" tar ((:commit . "4badcf6a0c951daba4d7259db3913b78254c0423") (:authors ("Nathan Lovato <nathan@gdquest.com>, Fabián E. Gallina" . "fgallina@gnu.org")) (:maintainer nil . "nathan@gdquest.com") (:keywords "languages") (:url . "https://github.com/godotengine/emacs-gdscript-mode/"))])
+ (geben . [(20210830 422) ((emacs (24 3)) (cl-lib (0 5))) "DBGp protocol frontend, a script debugger" tar ((:commit . "d3706387ed25b3037338572f3968b4cc2d8825a0") (:authors ("Matthew Carter" . "m@ahungry.com")) (:maintainer "Matthew Carter" . "m@ahungry.com") (:keywords "c" "comm" "tools") (:url . "https://github.com/ahungry/geben"))])
+ (geben-helm-projectile . [(20160611 59) ((emacs (24)) (geben (0 26)) (helm-projectile (0 13 0))) "Integrate helm-projectile with geben" single ((:commit . "31ce0faca5dcc71924884f03fd5a7a25d00ccd9b") (:authors ("Matthew Carter" . "m@ahungry.com")) (:maintainer "Matthew Carter" . "m@ahungry.com") (:keywords "ahungry" "emacs" "geben" "helm" "projectile" "debug") (:url . "https://github.com/ahungry/geben-helm-projectile"))])
+ (geeknote . [(20220213 612) ((emacs (24))) "Use Evernote in Emacs through geeknote" single ((:commit . "ce2738aebeeda35f9d31027e9b7bad0813b975c3") (:authors ("Evan Dale Aromin")) (:maintainer "Evan Dale Aromin") (:keywords "evernote" "geeknote" "note" "emacs-evernote" "evernote-mode") (:url . "http://github.com/avendael/emacs-geeknote"))])
+ (geiser . [(20220423 1805) ((emacs (25 1)) (transient (0 3)) (project (0 8 1))) "GNU Emacs and Scheme talk to each other" tar ((:commit . "1b1fdd2be47fcbadab4b224266d30dee4484a4b0") (:authors ("Jose Antonio Ortega Ruiz" . "jao@gnu.org")) (:maintainer "Jose Antonio Ortega Ruiz" . "jao@gnu.org") (:keywords "languages" "scheme" "geiser") (:url . "https://gitlab.com/emacs-geiser/"))])
+ (geiser-chez . [(20211216 2332) ((emacs (26 1)) (geiser (0 19))) "Chez Scheme's implementation of the geiser protocols" tar ((:commit . "48427d4aecc6fed751d266673f1ce2ad57ddbcfc") (:authors ("Peter" . "craven@gmx.net")) (:maintainer "Jose A Ortega Ruiz" . "jao@gnu.org") (:keywords "languages" "chez" "scheme" "geiser") (:url . "https://gitlab.com/emacs-geiser/chez"))])
+ (geiser-chibi . [(20211204 1938) ((emacs (24 4)) (geiser (0 18))) "Chibi Scheme's implementation of the geiser protocols" tar ((:commit . "5a6a5a580ea45cd4974df21629a8d50cbe3d6e99") (:authors ("Peter" . "craven@gmx.net")) (:maintainer "Jose A Ortega Ruiz" . "jao@gnu.org") (:keywords "languages" "chibi" "scheme" "geiser") (:url . "https://gitlab.com/emacs-geiser/chibi"))])
+ (geiser-chicken . [(20211204 2049) ((emacs (24 4)) (geiser (0 19))) "Chicken's implementation of the geiser protocols" tar ((:commit . "79a9ac78f4df7c9ec1f918313c543c116dbb8b70") (:authors ("Daniel Leslie")) (:maintainer "Daniel Leslie") (:keywords "languages" "chicken" "scheme" "geiser") (:url . "https://gitlab.com/emacs-geiser/chicken"))])
+ (geiser-gambit . [(20220208 1356) ((emacs (26 1)) (geiser (0 18))) "Gambit's implementation of the geiser protocols" tar ((:commit . "381d74ca5059b44fe3d8b5daf42214019c6d1a88") (:authors ("Daniel Leslie")) (:maintainer "Jose A Ortega Ruiz" . "jao@gnu.org") (:keywords "languages" "gambit" "scheme" "geiser") (:url . "https://gitlab.com/emacs-geiser/gambit"))])
+ (geiser-gauche . [(20220503 1700) ((emacs (26 1)) (geiser (0 11 2))) "Gauche scheme support for Geiser" tar ((:commit . "8ff743f6416f00751e24aef8b9791501a40f5421") (:authors ("András Simonyi" . "andras.simonyi@gmail.com")) (:maintainer "András Simonyi" . "andras.simonyi@gmail.com") (:keywords "languages" "gauche" "scheme" "geiser") (:url . "https://gitlab.com/emacs-geiser/gauche"))])
+ (geiser-guile . [(20220323 2352) ((emacs (25 1)) (geiser (0 23 2))) "Guile's implementation of the geiser protocols" tar ((:commit . "c641fcc50b6b86ca95743122b5206cdcd475f96e") (:authors ("Jose Antonio Ortega Ruiz" . "jao@gnu.org")) (:maintainer "Jose Antonio Ortega Ruiz" . "jao@gnu.org") (:keywords "languages" "guile" "scheme" "geiser") (:url . "https://gitlab.com/emacs-geiser/guile"))])
+ (geiser-kawa . [(20210920 1607) ((emacs (26 1)) (geiser (0 16))) "Kawa scheme support for Geiser" tar ((:commit . "5896b19642923f74f718eb68d447560b2d26d797") (:authors ("spellcard199" . "spellcard199@protonmail.com")) (:maintainer "spellcard199" . "spellcard199@protonmail.com") (:keywords "languages" "kawa" "scheme" "geiser") (:url . "https://gitlab.com/emacs-geiser/kawa"))])
+ (geiser-mit . [(20211204 1935) ((emacs (24 4)) (geiser (0 18))) "MIT/GNU Scheme's implementation of the geiser protocols" tar ((:commit . "4e90e9ae815e89f3540fb9644e6016c663ef5765") (:authors ("Peter" . "craven@gmx.net")) (:maintainer "Jose A Ortega Ruiz" . "jao@gnu.org") (:keywords "languages" "mit" "scheme" "geiser") (:url . "https://gitlab.com/emacs-geiser/mit"))])
+ (geiser-racket . [(20210421 125) ((emacs (26 1)) (geiser (0 16))) "Support for Racket in Geiser" tar ((:commit . "22e56ce80389544d3872cf4beb4008fb514b2218") (:authors ("Jose Antonio Ortega Ruiz" . "jao@gnu.org")) (:maintainer "Jose Antonio Ortega Ruiz" . "jao@gnu.org") (:keywords "languages" "racket" "scheme" "geiser") (:url . "https://gitlab.com/emacs-geiser/racket"))])
+ (geiser-stklos . [(20211117 2114) ((emacs (24 4)) (geiser (0 16))) "STklos Scheme implementation of the geiser protocols" single ((:commit . "9db60a7e751c97e30dd528e2a96ff19575b618d2") (:authors ("Jeronimo Pellegrini" . "j_p@aleph0.info")) (:maintainer "Jeronimo Pellegrini" . "j_p@aleph0.info") (:keywords "languages" "stklos" "scheme" "geiser") (:url . "https://gitlab.com/emacs-geiser/stklos"))])
+ (gemini-mode . [(20210909 1442) ((emacs (24 4))) "A simple highlighting package for text/gemini" single ((:commit . "60bd07b3a1e532c950c132673777ceb635c9960d") (:authors ("Jason McBrayer <jmcbray@carcosa.net>, tastytea <tastytea@tastytea.de>, Étienne Deparis" . "etienne@depar.is")) (:maintainer "Jason McBrayer <jmcbray@carcosa.net>, tastytea <tastytea@tastytea.de>, Étienne Deparis" . "etienne@depar.is") (:keywords "languages") (:url . "https://git.carcosa.net/jmcbray/gemini.el"))])
+ (gemini-write . [(20211114 1032) ((emacs (26)) (elpher (2 8 0)) (gemini-mode (1 0 0))) "Elpher for Titan" single ((:commit . "2a7d07d0ce4c5b8750f3ff1182ad94ee616734c8") (:authors ("Alex Schroeder" . "alex@gnu.org")) (:maintainer "Alex Schroeder" . "alex@gnu.org") (:keywords "comm" "gemini") (:url . "https://alexschroeder.ch/cgit/gemini-write"))])
+ (general . [(20211203 120) ((emacs (24 4)) (cl-lib (0 5))) "Convenience wrappers for keybindings." tar ((:commit . "9651024e7f40a8ac5c3f31f8675d3ebe2b667344") (:authors ("Fox Kiester" . "noct@posteo.net")) (:maintainer "Fox Kiester" . "noct@posteo.net") (:keywords "vim" "evil" "leader" "keybindings" "keys") (:url . "https://github.com/noctuid/general.el"))])
+ (genrnc . [(20140612 1237) ((deferred (0 3 1)) (concurrent (0 3)) (log4e (0 2 0)) (yaxception (0 1))) "generate RELAX NG Compact Schema from RELAX NG Schema, XML Schema and DTD." tar ((:commit . "da75b1966a73ad215ec2ced4522c25f4d0bf1f9a") (:authors ("Hiroaki Otsu" . "ootsuhiroaki@gmail.com")) (:maintainer "Hiroaki Otsu" . "ootsuhiroaki@gmail.com") (:keywords "xml") (:url . "https://github.com/aki2o/emacs-genrnc"))])
+ (geoip . [(20200310 911) ((emacs (25 1))) "Find out where an IP address is located via GeoIP2" single ((:commit . "25eb1278788b942c38405c233d3614a1de92ddea") (:authors ("Xu Chunyang")) (:maintainer "Xu Chunyang") (:keywords "tools") (:url . "https://github.com/xuchunyang/geoip.el"))])
+ (geolocation . [(20200317 1559) ((request-deferred (0 3 2)) (deferred (0 5 1)) (emacs (25 1))) "Get your location on Earth" single ((:commit . "bc7848832eb0352e3a71f4b9d89d917fe12d18be") (:authors ("Neil Okamoto" . "neil.okamoto+melpa@gmail.com")) (:maintainer "Neil Okamoto" . "neil.okamoto+melpa@gmail.com") (:keywords "hardware") (:url . "https://github.com/gonewest818/geolocation.el"))])
+ (german-holidays . [(20181213 644) nil "German holidays for Emacs calendar" single ((:commit . "a8462dffccaf2b665f2032e646b5370e993a386a") (:authors ("Sebastian Christ" . "rudolfo.christ@gmail.com")) (:maintainer "Sebastian Christ" . "rudolfo.christ@gmail.com") (:url . "https://github.com/rudolfochrist/german-holidays"))])
+ (germanium . [(20220116 1634) ((emacs (26 1))) "Generate image from source code using germanium" single ((:commit . "54c9a56da1e86941f2580d4838fbb6097f22f349") (:authors ("Masaya Watanabe")) (:maintainer "Masaya Watanabe") (:keywords "convenience") (:url . "https://github.com/matsuyoshi30/germanium-el"))])
+ (gerrit . [(20220413 1219) ((emacs (25 1)) (magit (2 13 1)) (s (1 12 0)) (dash (0 2 15))) "Gerrit client" tar ((:commit . "28280fa7a218cb5150e37050dc80ba9c9884c502") (:authors ("Thomas Hisch" . "t.hisch@gmail.com")) (:maintainer "Thomas Hisch" . "t.hisch@gmail.com") (:keywords "extensions") (:url . "https://github.com/thisch/gerrit.el"))])
+ (gerrit-download . [(20150714 1408) ((emacs (24 0)) (magit (2 1 0))) "Show gerrit reviews in a diff buffer." single ((:commit . "d568acc7c5935188c9bc19ba72719a6092d9f6fd") (:authors ("Chmouel Boudjnah" . "chmouel@chmouel.com")) (:maintainer "Chmouel Boudjnah" . "chmouel@chmouel.com") (:keywords "tools" "gerrit" "git") (:url . "https://github.com/chmouel/gerrit-download.el"))])
+ (gf . [(20181028 1542) ((s (1 0)) (ht (2 0))) "Major mode for editing GF code" single ((:commit . "30b3127f229e0db522c7752f6957ca01b2ea2821") (:authors ("Johan Bockgård" . "bojohan+mail@dd.chalmers.se")) (:maintainer "bruno cuconato" . "bcclaro+emacs@gmail.com") (:keywords "languages") (:url . "https://github.com/GrammaticalFramework/gf-emacs-mode"))])
+ (ggo-mode . [(20210310 1345) nil "Gengetopt major mode" single ((:commit . "6a7617b5af3d13029e4d680a375e8107c40d0fac") (:authors ("Matthew K. Junker" . "junker@alum.mit.edu")) (:maintainer "Matthew K. Junker" . "junker@alum.mit.edu") (:keywords "extensions" "convenience" "local"))])
+ (ggtags . [(20220420 1610) ((emacs (25))) "emacs frontend to GNU Global source code tagging system" single ((:commit . "22d3a3a951cb605d29138f1acee191ef674a4518") (:authors ("Leo Liu" . "sdl.web@gmail.com")) (:maintainer "Leo Liu" . "sdl.web@gmail.com") (:keywords "tools" "convenience") (:url . "https://github.com/leoliu/ggtags"))])
+ (gh . [(20220302 549) ((emacs (25 1)) (pcache (0 4 2)) (logito (0 1)) (marshal (0 9 0)) (cl-lib (0 3))) "A GitHub library for Emacs" tar ((:commit . "27ccc892e94f7e747e5b879eec71119965d9ed6e") (:authors ("Yann Hodique" . "yhodique@gmail.com")) (:maintainer "Yann Hodique" . "yhodique@gmail.com") (:url . "https://github.com/sigma/gh.el"))])
+ (gh-md . [(20220316 1432) ((emacs (24 3))) "Render markdown using the Github api" single ((:commit . "e721fd5e41e682f47f2dd4ce26ef2ba28c7fa0b5") (:authors ("Mario Rodas" . "marsam@users.noreply.github.com")) (:maintainer "Mario Rodas" . "marsam@users.noreply.github.com") (:keywords "convenience") (:url . "https://github.com/emacs-pe/gh-md.el"))])
+ (gh-notify . [(20211126 638) ((emacs (27 1)) (magit (3 0 0)) (forge (0 2 0))) "A veneer for Magit/Forge GitHub notifications" single ((:commit . "aa4d8bc0c56366d437e7c126e7eedc5938109342") (:authors ("Bas Alberts" . "bas@anti.computer") ("xristos" . "xristos@sdf.org")) (:maintainer "Bas Alberts" . "bas@anti.computer") (:keywords "comm") (:url . "https://github.com/anticomputer/gh-notify"))])
+ (ghc-imported-from . [(20141124 1932) ((emacs (24 1))) "Haskell documentation lookup with ghc-imported-from" single ((:commit . "fcff08628a19f5d26151564659218cc677779b79") (:authors ("David Raymond Christiansen" . "david@davidchristiansen.dk")) (:maintainer "David Raymond Christiansen" . "david@davidchristiansen.dk") (:keywords "languages"))])
+ (ghci-completion . [(20151125 1257) ((emacs (24 1)) (cl-lib (0 5))) "Completion for GHCi commands in inferior-haskell buffers" single ((:commit . "c47e23d585d2a3c7b13aac163693fdc4f2bb90e5") (:authors ("Oleksandr Manzyuk" . "manzyuk@gmail.com")) (:maintainer "Oleksandr Manzyuk" . "manzyuk@gmail.com") (:keywords "convenience"))])
+ (gherkin-mode . [(20171224 1353) nil "An emacs major mode for editing gherkin files." single ((:commit . "0313492e7da152f0aa73ddf96c0287ded8f51253") (:authors ("Craig Andera")) (:maintainer "Craig Andera") (:keywords "languages"))])
+ (ghost-blog . [(20171023 742) ((markdown-mode (1 0))) "A package to manage Ghost blog" single ((:commit . "71b358643cc9a2db1bf752281ff94aba9b59e4cc") (:authors ("Javier Aguirre" . "hello@javaguirre.net")) (:maintainer "Javier Aguirre" . "hello@javaguirre.net") (:keywords "ghost" "blog") (:url . "https://github.com/javaguirre/ghost-blog"))])
+ (ghq . [(20210504 902) nil "Ghq interface for emacs" single ((:commit . "582bd6daa505d04c7cc06d6c82ed8aee0624bfbe") (:authors ("Roman Coedo" . "romancoedo@gmail.com")) (:maintainer "Roman Coedo" . "romancoedo@gmail.com") (:keywords "ghq"))])
+ (ghub . [(20220429 1708) ((emacs (25 1)) (compat (28 1 1 0)) (let-alist (1 0 6)) (treepy (0 1 1))) "Client libraries for Git forge APIs." tar ((:commit . "f3a26544575303e86b423a3406656f0e5a576d67") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:keywords "tools") (:url . "https://github.com/magit/ghub"))])
+ (ghub+ . [(20191229 1748) ((emacs (25)) (ghub (2 0)) (apiwrap (0 5))) "a thick GitHub API client built on ghub" single ((:commit . "b1adef2402d7599911d4dd447a987a0cea04e6fe") (:authors ("Sean Allred" . "code@seanallred.com")) (:maintainer "Sean Allred" . "code@seanallred.com") (:keywords "extensions" "multimedia" "tools") (:url . "https://github.com/vermiculus/ghub-plus"))])
+ (gif-screencast . [(20210401 656) ((emacs (25 1))) "One-frame-per-action GIF recording" single ((:commit . "5517a557a17d8016c9e26b0acb74197550f829b9") (:authors ("Pierre Neidhardt" . "mail@ambrevar.xyz")) (:maintainer "Pierre Neidhardt" . "mail@ambrevar.xyz") (:keywords "multimedia" "screencast") (:url . "https://gitlab.com/ambrevar/emacs-gif-screencast"))])
+ (gift-mode . [(20210528 1459) nil "major mode for editing GIFT format quizzes" single ((:commit . "c93354e8fe1173b22f398f17b127875807f15b87") (:authors ("Christophe Rhodes" . "christophe@rhodes.io")) (:maintainer "Christophe Rhodes" . "christophe@rhodes.io") (:url . "https://github.com/csrhodes/gift-mode"))])
+ (gildas-mode . [(20181022 649) ((polymode (0 1 5)) (emacs (25))) "Major mode for Gildas" single ((:commit . "d0c9e997e2aa0bcd9b8b7db082d69100448cb1b2") (:authors ("Sébastien Maret" . "sebastien.maret@icloud.com")) (:maintainer "Sébastien Maret" . "sebastien.maret@icloud.com") (:keywords "languages" "gildas") (:url . "https://github.com/smaret/gildas-mode"))])
+ (gist . [(20171128 406) ((emacs (24 1)) (gh (0 10 0))) "Emacs integration for gist.github.com" single ((:commit . "314fe6ab80fae35b95f0734eceb82f72813b6f41") (:authors ("Yann Hodique" . "yann.hodique@gmail.com")) (:maintainer "Yann Hodique" . "yann.hodique@gmail.com") (:keywords "tools") (:url . "https://github.com/defunkt/gist.el"))])
+ (git . [(20140128 1041) ((s (1 7 0)) (dash (2 2 0)) (f (0 10 0))) "An Elisp API for programmatically using Git" single ((:commit . "a3396a7027a7d986598c6a2d6d5599bac918f3da") (:authors ("Johan Andersson" . "johan.rejeep@gmail.com")) (:maintainer "Johan Andersson" . "johan.rejeep@gmail.com") (:keywords "git") (:url . "http://github.com/rejeep/git.el"))])
+ (git-annex . [(20190625 2118) nil "Mode for easy editing of git-annex'd files" single ((:commit . "1324d3f23c534fe79391a2c256bb8803054e383b") (:authors ("John Wiegley" . "jwiegley@gmail.com")) (:maintainer "John Wiegley" . "jwiegley@gmail.com") (:keywords "files" "data" "git" "annex") (:url . "https://github.com/jwiegley/git-annex-el"))])
+ (git-assembler-mode . [(20210207 1545) ((emacs (24 4))) "git-assembler major mode" single ((:commit . "1243bdc1a9cdc79802ece05c90731ee14e4f92c9") (:authors ("Yuri D'Elia" . "wavexx@thregr.org")) (:maintainer "Yuri D'Elia" . "wavexx@thregr.org") (:keywords "git" "git-assembler" "languages" "highlight" "syntax") (:url . "https://gitlab.com/wavexx/git-assembler-mode.el"))])
+ (git-attr . [(20180925 2003) ((emacs (24 3))) "Git attributes of buffer file" tar ((:commit . "50df0630eba2a931146f676d349b29bde6b6b37b") (:authors ("Arne Jørgensen" . "arne@arnested.dk")) (:maintainer "Arne Jørgensen" . "arne@arnested.dk") (:keywords "vc") (:url . "https://github.com/arnested/emacs-git-attr"))])
+ (git-auto-commit-mode . [(20200828 653) nil "Emacs Minor mode to automatically commit and push" single ((:commit . "a6b6e0fa183be381463e2b44ef128db1b6c4234b") (:authors ("Tom Willemse" . "tom@ryuslash.org")) (:maintainer "Tom Willemse" . "tom@ryuslash.org") (:keywords "vc") (:url . "https://github.com/ryuslash/git-auto-commit-mode"))])
+ (git-backup . [(20191209 2144) ((emacs (24 3)) (s (1 8 0))) "Backup each file change using git" single ((:commit . "67e38c659c918e98642171ba3f385a15182347f4") (:authors ("Anthony HAMON" . "hamon.anth@gmail.com")) (:maintainer "Anthony HAMON" . "hamon.anth@gmail.com") (:keywords "backup" "files" "tools" "git") (:url . "http://github.com/antham/git-backup"))])
+ (git-backup-ivy . [(20220412 1914) ((ivy (0 12 0)) (git-backup (0 0 1)) (emacs (25 1))) "An ivy interface to git-backup" single ((:commit . "c53e1bc800963c0d826226c37c22e36f2353c70d") (:authors ("Sebastian Wålinder" . "s.walinder@gmail.com")) (:maintainer "Sebastian Wålinder" . "s.walinder@gmail.com") (:keywords "backup" "convenience" "files" "tools" "vc") (:url . "https://github.com/walseb/git-backup-ivy"))])
+ (git-blamed . [(20161028 1926) nil "Minor mode for incremental blame for Git" single ((:commit . "cef196abf398e2dd11f775d1e6cd8690567408aa") (:keywords "git" "version control" "release management"))])
+ (git-command . [(20191028 333) ((term-run (0 1 4)) (with-editor (2 3 1))) "A Git Command-Line interface" single ((:commit . "a773d40da39dfb1c6ecf2b0758aa370ddea8f06d") (:authors ("10sr <8slashes+el [at] gmail [dot] com>")) (:maintainer "10sr <8slashes+el [at] gmail [dot] com>") (:keywords "utility" "git") (:url . "https://github.com/10sr/git-command-el"))])
+ (git-commit . [(20220429 934) ((emacs (25 1)) (compat (28 1 1 0)) (transient (20210920)) (with-editor (20211001))) "Edit Git commit messages." tar ((:commit . "476383fc8fb0f6ea4c6fc29d7057a1b5b5f95bd8") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li") ("Sebastian Wiesner" . "lunaryorn@gmail.com") ("Florian Ragwitz" . "rafl@debian.org") ("Marius Vollmer" . "marius.vollmer@gmail.com")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:keywords "git" "tools" "vc") (:url . "https://github.com/magit/magit"))])
+ (git-commit-insert-issue . [(20210107 2018) ((emacs (25)) (projectile (0)) (s (0)) (ghub (0)) (bitbucket (0))) "Get issues list when typing \"Fixes #\"" single ((:commit . "6cfb8b4b5b23ae881cf3d005da4d7f60d91cd2cd") (:authors ("Vindarel")) (:maintainer "Vindarel") (:keywords "tools" "vc" "github" "gitlab" "bitbucket" "commit" "issues") (:url . "https://gitlab.com/emacs-stuff/git-commit-insert-issue/"))])
+ (git-dwim . [(20170126 1214) nil "Context-aware git commands such as branch handling" single ((:commit . "485c732130686c2f28a026e385366006435394b9") (:authors ("rubikitch" . "rubikitch@ruby-lang.org")) (:maintainer "rubikitch" . "rubikitch@ruby-lang.org") (:keywords "git" "tools" "convenience") (:url . "http://www.emacswiki.org/cgi-bin/wiki/download/git-dwim.el"))])
+ (git-grep . [(20200920 1751) ((projectile (0 10 0))) "Search tools using git grep" single ((:commit . "12ff6045e9b6aa42f98abd4ddc44d670268a0849") (:authors ("Sam Kleinman")) (:maintainer "tychoish" . "garen@tychoish.com") (:keywords "matching" "files" "grep" "search" "using" "git-grep") (:url . "https://github.com/tychoish/git-grep.el"))])
+ (git-gutter . [(20220423 1704) ((emacs (25 1))) "Port of Sublime Text plugin GitGutter" single ((:commit . "a50672b62a678922b8c0cab95225d520f493439b") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Neil Okamoto" . "neil.okamoto+melpa@gmail.com") (:url . "https://github.com/emacsorphanage/git-gutter"))])
+ (git-gutter+ . [(20151204 1723) ((git-commit (0)) (dash (0))) "Manage Git hunks straight from the buffer" single ((:commit . "b7726997806d9a2da9fe84ff00ecf21d62b6f975") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:keywords "git" "vc") (:url . "https://github.com/nonsequitur/git-gutter-plus"))])
+ (git-gutter-fringe . [(20211003 2228) ((git-gutter (0 88)) (fringe-helper (0 1 1)) (cl-lib (0 5)) (emacs (24))) "Fringe version of git-gutter.el" single ((:commit . "648cb5b57faec55711803cdc9434e55a733c3eba") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Neil Okamoto" . "neil.okamoto+melpa@gmail.com") (:url . "https://github.com/emacsorphanage/git-gutter-fringe"))])
+ (git-gutter-fringe+ . [(20140729 1103) ((git-gutter+ (0 1)) (fringe-helper (1 0 1))) "Fringe version of git-gutter+.el" single ((:commit . "7a2f49d2455a3a872e90e5f7dd4e6b27f1d96cfc") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/nonsequitur/git-gutter-fringe-plus"))])
+ (git-identity . [(20220402 708) ((emacs (25 1)) (dash (2 10)) (hydra (0 14)) (f (0 20))) "Identity management for (ma)git" single ((:commit . "e7da2b3e3a5a790311431e3263b00df41d335136") (:authors ("Akira Komamura" . "akira.komamura@gmail.com")) (:maintainer "Akira Komamura" . "akira.komamura@gmail.com") (:keywords "git" "vc" "convenience") (:url . "https://github.com/akirak/git-identity.el"))])
+ (git-io . [(20180317 1752) ((emacs (24 4))) "git.io integration" single ((:commit . "48753acba73b48b997bb678fb5e2a938ae63b5d6") (:authors ("Tejas Bubane" . "tejasbubane@gmail.com")) (:maintainer "Tejas Bubane" . "tejasbubane@gmail.com") (:keywords "convenience" "files") (:url . "https://github.com/tejasbubane/emacs-git-io"))])
+ (git-lens . [(20190319 1342) ((emacs (24 4))) "Show new, deleted or modified files in branch" single ((:commit . "f6cc0a37c9c5c422c49c32650e70bc4721707985") (:authors ("Peter Stiernström" . "peter@stiernstrom.se")) (:maintainer "Peter Stiernström" . "peter@stiernstrom.se") (:keywords "vc" "convenience") (:url . "https://github.com/pidu/git-lens"))])
+ (git-link . [(20220406 2328) ((emacs (24 3))) "Get the GitHub/Bitbucket/GitLab URL for a buffer location" single ((:commit . "0197c9812417e18df2c7b5cd5c0084271c2f3286") (:authors ("Skye Shaw" . "skye.shaw@gmail.com")) (:maintainer "Skye Shaw" . "skye.shaw@gmail.com") (:keywords "git" "vc" "github" "bitbucket" "gitlab" "sourcehut" "aws" "azure" "convenience") (:url . "http://github.com/sshaw/git-link"))])
+ (git-messenger . [(20201202 1637) ((emacs (24 3)) (popup (0 5 3))) "Popup last commit of current line" single ((:commit . "eade986ef529aa2dac6944ad61b18de55cee0b76") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Neil Okamoto") (:url . "https://github.com/emacsorphanage/git-messenger"))])
+ (git-modes . [(20220422 1611) ((emacs (25 1))) "Major modes for editing Git configuration files" tar ((:commit . "96abfb732d695cbd2075ba701254651a7b28d693") (:authors ("Sebastian Wiesner" . "lunaryorn@gmail.com") ("Rüdiger Sonderfeld" . "ruediger@c-plusplus.net") ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:keywords "convenience" "vc" "git") (:url . "https://github.com/magit/git-modes"))])
+ (git-msg-prefix . [(20191031 1304) ((emacs (24)) (s (1 10 0)) (dash (2 9 0))) "Insert commit message prefix (issue number)" single ((:commit . "43f6b31c1090371260a2f15b2117a7666920bee7") (:authors ("Raimon Grau" . "raimonster@gmail.com")) (:maintainer "Raimon Grau" . "raimonster@gmail.com") (:keywords "vc" "tools") (:url . "http://github.com/kidd/git-msg-prefix.el"))])
+ (git-ps1-mode . [(20200113 704) nil "Global minor-mode to print __git_ps1 in mode-line" single ((:commit . "6762a309bd593d26258dfbf43e7bc21254a70fbf") (:authors ("10sr <8slashes+el [at] gmail [dot] com>")) (:maintainer "10sr <8slashes+el [at] gmail [dot] com>") (:keywords "utility" "mode-line" "git") (:url . "https://github.com/10sr/git-ps1-mode-el"))])
+ (git-time-metric . [(20181116 2011) nil "Provide function to record time with gtm ( git time metric )" single ((:commit . "287108ed1d6885dc795eb3bad4476aa08c626186") (:authors ("Anton Sivolapov" . "anton.sivolapov@gmail.com")) (:maintainer "Anton Sivolapov" . "anton.sivolapov@gmail.com") (:keywords "tools" "gtm" "productivity" "time") (:url . "https://github.com/c301/gtm-emacs-plugin"))])
+ (git-timemachine . [(20220324 1057) ((emacs (24 3)) (transient (0 1 0))) "Walk through git revisions of a file" single ((:commit . "ca09684e94767cc0b2339b77b778b4de4f9d104f") (:authors ("Peter Stiernström" . "peter@stiernstrom.se")) (:maintainer "Peter Stiernström" . "peter@stiernstrom.se") (:keywords "vc") (:url . "https://gitlab.com/pidu/git-timemachine"))])
+ (git-walktree . [(20191101 302) ((emacs (26 1)) (git (0 1 1)) (cl-lib (0 5))) "Browse Git tree and blob objects" tar ((:commit . "162d9073286c256502df4baa9845790b9f4c2f05") (:authors ("10sr <8.slashes [at] gmail [dot] com>")) (:maintainer "10sr <8.slashes [at] gmail [dot] com>") (:keywords "vc" "utility" "git") (:url . "https://github.com/10sr/git-walktree-el"))])
+ (git-wip-timemachine . [(20150408 1006) ((s (1 9 0))) "Walk through git-wip revisions of a file" single ((:commit . "ed4c7931a5f5233bf3e358b1e81647d063526460") (:authors ("Tim Krones" . "t.krones@gmx.net")) (:maintainer "Tim Krones" . "t.krones@gmx.net") (:keywords "git") (:url . "https://github.com/itsjeyd/git-wip-timemachine"))])
+ (gitconfig . [(20130718 935) nil "Emacs lisp interface to work with git-config variables" single ((:commit . "7612a37ca14009cac8fb8d6b6f54adad739a5741") (:authors ("Samuel Tonini")) (:maintainer "Samuel Tonini") (:keywords "git" "gitconfig" "git-config"))])
+ (github-browse-file . [(20160205 1427) ((cl-lib (0 5))) "View the file you're editing on GitHub" single ((:commit . "9742a5183af853788c6ecb83fb7ee0b00d1675ac") (:authors ("Ozan Sener" . "ozan@ozansener.com")) (:maintainer "Ozan Sener" . "ozan@ozansener.com") (:keywords "convenience" "vc" "git" "github") (:url . "https://github.com/osener/github-browse-file"))])
+ (github-clone . [(20210108 1920) ((gh (1 0 1)) (magit (3 0 0)) (emacs (25 1))) "Fork and clone github repos" single ((:commit . "9e40d6d3c6128407d7456bf71c95ad1fbb473b2a") (:authors ("Charles L.G. Comstock" . "dgtized@gmail.com")) (:maintainer "Charles L.G. Comstock" . "dgtized@gmail.com") (:keywords "vc" "tools") (:url . "https://github.com/dgtized/github-clone.el"))])
+ (github-dark-vscode-theme . [(20220313 2033) ((emacs (24 1))) "The GitHub Dark Theme from Visual Studio Code" single ((:commit . "785d2192d7cd30fb7d9c6cd660133a4002f598cc") (:authors ("Justintime50")) (:maintainer "Justintime50") (:keywords "faces") (:url . "https://github.com/justintime50/github-dark-vscode-emacs-theme"))])
+ (github-elpa . [(20200129 417) ((package-build (1 0)) (commander (0 7 0)) (git (0 1 1))) "Build and publish ELPA repositories with GitHub Pages" tar ((:commit . "04a55c723ffcd84dd35e5438e7e2b9f1cce08d42") (:authors (nil . "10sr<8slashes+el@gmail.com>")) (:maintainer nil . "10sr<8slashes+el@gmail.com>") (:url . "https://github.com/10sr/github-elpa"))])
+ (github-explorer . [(20220305 1450) ((emacs (25)) (graphql (0))) "Explore a GitHub repository on the fly" single ((:commit . "49e5c350169b556deaabdcb67e9440bd4d5b4f8b") (:authors ("Giap Tran" . "txgvnn@gmail.com")) (:maintainer "Giap Tran" . "txgvnn@gmail.com") (:keywords "comm") (:url . "https://github.com/TxGVNN/github-explorer"))])
+ (github-linguist . [(20220418 22) ((emacs (27 1)) (project (0 8)) (async (1 9)) (map (3))) "Run GitHub Linguist on projects to collect information" single ((:commit . "e1055cba19d82620a735e8e40d094b538e1f4d94") (:authors ("Akira Komamura" . "akira.komamura@gmail.com")) (:maintainer "Akira Komamura" . "akira.komamura@gmail.com") (:keywords "processes") (:url . "https://github.com/akirak/github-linguist.el"))])
+ (github-modern-theme . [(20171109 1251) nil "The GitHub color theme for Emacs." single ((:commit . "a7e7b8e5e9c122138e79e837caf9b7299e748d44") (:authors ("Philip Arvidsson" . "philip@philiparvidsson.com")) (:maintainer "Philip Arvidsson" . "philip@philiparvidsson.com") (:url . "https://github.com/philiparvidsson/GitHub-Theme-for-Emacs"))])
+ (github-notifier . [(20180421 316) ((emacs (24))) "Displays your GitHub notifications unread count in mode-line" single ((:commit . "274f3812926ea371346f639fcee98066f6e8c96f") (:authors ("Chunyang Xu" . "mail@xuchunyang.me")) (:maintainer "Chunyang Xu" . "mail@xuchunyang.me") (:keywords "github" "mode-line") (:url . "https://github.com/xuchunyang/github-notifier.el"))])
+ (github-pullrequest . [(20170116 616) ((emacs (24 4)) (request (0 2 0)) (dash (2 11 0)) (magit (2 10 0))) "Create and fetch Github Pull requests with ease" single ((:commit . "6ae5c38b0fc15b638b5ba4490112d9822ce5e267") (:authors ("Jakob Lind" . "karl.jakob.lind@gmail.com")) (:maintainer "Jakob Lind" . "karl.jakob.lind@gmail.com") (:keywords "tools") (:url . "https://github.com/jakoblind/github-pullrequest"))])
+ (github-review . [(20211029 243) ((emacs (25 1)) (s (1 12 0)) (ghub (2 0)) (dash (2 11 0)) (deferred (0 5 1)) (a (0 1 1))) "GitHub based code review" single ((:commit . "725fbc7b385228f53a7ddc46a92c1276bab4aea8") (:authors ("Laurent Charignon" . "l.charignon@gmail.com")) (:maintainer "Laurent Charignon" . "l.charignon@gmail.com") (:keywords "git" "tools" "vc" "github") (:url . "https://github.com/charignon/github-review"))])
+ (github-search . [(20190624 436) ((magit (0 8 1)) (gh (1 0 0))) "Clone repositories by searching github" single ((:commit . "b73efaf19491010522b09db35bb0f1bad1620e63") (:authors ("Ivan Malison" . "IvanMalison@gmail.com")) (:maintainer "Ivan Malison" . "IvanMalison@gmail.com") (:keywords "github" "search" "clone" "api" "gh" "magit" "vc" "tools") (:url . "https://github.com/IvanMalison/github-search"))])
+ (github-stars . [(20190517 1319) ((emacs (25 1)) (ghub (2 0 0))) "Browse your Github Stars" single ((:commit . "a9f25ab2487c886f5d50d26693d49856bd51383b") (:authors ("Xu Chunyang" . "mail@xuchunyang.me")) (:maintainer "Xu Chunyang" . "mail@xuchunyang.me") (:keywords "tools") (:url . "https://github.com/xuchunyang/github-stars.el"))])
+ (github-theme . [(20170630 2201) nil "The GitHub color theme for Emacs." single ((:commit . "29f00a51d949a248a5f6355a97131e216747c797") (:authors ("Philip Arvidsson" . "philip@philiparvidsson.com")) (:maintainer "Philip Arvidsson" . "philip@philiparvidsson.com") (:url . "https://github.com/philiparvidsson/GitHub-Theme-for-Emacs"))])
+ (gitignore-snippets . [(20201118 1551) ((emacs (26)) (yasnippet (0 8 0))) "Gitignore.io templates for Yasnippet" tar ((:commit . "0de6945ff0fc6943eebcf92d1cbb66b6a1d8fa60") (:authors ("Seong Yong-ju" . "sei40kr@gmail.com")) (:maintainer "Seong Yong-ju" . "sei40kr@gmail.com") (:keywords "tools") (:url . "https://github.com/sei40kr/gitignore-snippets"))])
+ (gitignore-templates . [(20210814 144) ((emacs (24 3))) "Create .gitignore using GitHub or gitignore.io API" single ((:commit . "d28cd1cec00242b688861648d36d086818b06099") (:authors ("Xu Chunyang")) (:maintainer "Xu Chunyang") (:keywords "tools") (:url . "https://github.com/xuchunyang/gitignore-templates.el"))])
+ (gitlab . [(20180312 1647) ((s (1 9 0)) (dash (2 9 0)) (pkg-info (0 5 0)) (request (0 1 0))) "Emacs client for Gitlab" tar ((:commit . "8c2324c02119500f094c2f92dfaba4c9977ce1ba") (:authors ("Nicolas Lamirault" . "nicolas.lamirault@gmail.com")) (:maintainer "Nicolas Lamirault" . "nicolas.lamirault@gmail.com") (:keywords "gitlab") (:url . "https://github.com/nlamirault/emacs-gitlab"))])
+ (gitlab-ci-mode . [(20191022 2017) ((emacs (25 1)) (yaml-mode (0 0 12))) "Mode for editing GitLab CI files" single ((:commit . "c861dc5fa17d380d5c3aca99dc3bbec5eee623bc") (:authors ("Joe Wreschnig")) (:maintainer "Joe Wreschnig") (:keywords "tools" "vc") (:url . "https://gitlab.com/joewreschnig/gitlab-ci-mode/"))])
+ (gitlab-ci-mode-flycheck . [(20190323 1829) ((emacs (25)) (flycheck (31)) (gitlab-ci-mode (1))) "Flycheck support for ‘gitlab-ci-mode’" single ((:commit . "eba81cfb7224fd1fa4e4da90d11729cc7ea12f72") (:authors ("Joe Wreschnig")) (:maintainer "Joe Wreschnig") (:keywords "tools" "vc" "convenience") (:url . "https://gitlab.com/joewreschnig/gitlab-ci-mode-flycheck/"))])
+ (gitlab-pipeline . [(20210601 1339) ((emacs (25 1)) (ghub (3 3 0))) "Get infomation about Gitlab pipelines" single ((:commit . "2404f9cf0a064aabea975adada250895c385e057") (:authors ("Giap Tran" . "txgvnn@gmail.com")) (:maintainer "Giap Tran" . "txgvnn@gmail.com") (:keywords "comm" "tools" "git") (:url . "https://github.com/TxGVNN/gitlab-pipeline"))])
+ (gitlab-snip-helm . [(20200427 2014) ((emacs (25)) (dash (2 12 0)) (helm (3 2))) "Gitlab snippets api helm package" single ((:commit . "782df679e33646db29e07508311bc8e8624b484e") (:authors ("Fermin MF" . "fmfs@posteo.net")) (:maintainer "Fermin MF" . "fmfs@posteo.net") (:keywords "tools" "files" "convenience") (:url . "https://gitlab.com/sasanidas/gitlab-snip-helm"))])
+ (gitolite-clone . [(20160609 2355) ((dash (2 10 0)) (s (1 9 0)) (pcache (0 3 1)) (emacs (24))) "Clone gitolite repositories from a completing list" single ((:commit . "d8a4c2875c984e51137c980b5773f42703602721") (:authors ("Ivan Malison" . "IvanMalison@gmail.com")) (:maintainer "Ivan Malison" . "IvanMalison@gmail.com") (:keywords "gitolite" "clone" "git") (:url . "https://github.com/IvanMalison/gitolite-clone"))])
+ (gitpatch . [(20170722 410) ((emacs (24 3))) "Git-format patch toolkit" single ((:commit . "577d5adf65c8133caa325c10e89e1e2fc323c907") (:authors ("Feng Shu" . "tumashu@163.com")) (:maintainer "Feng Shu" . "tumashu@163.com") (:keywords "convenience") (:url . "https://github.com/tumashu/gitpatch"))])
+ (gitter . [(20220316 138) ((emacs (24 4)) (let-alist (1 0 4))) "An Emacs Gitter client" single ((:commit . "49327c91eb50cfea633af8fd32b0643691d75cb7") (:authors ("Chunyang Xu" . "mail@xuchunyang.me")) (:maintainer "Chunyang Xu" . "mail@xuchunyang.me") (:keywords "gitter" "chat" "client" "internet") (:url . "https://github.com/xuchunyang/gitter.el"))])
+ (gkroam . [(20220326 521) ((emacs (26 3)) (db (0 0 6)) (company (0 9 10))) "A lightweight org-mode Roam Research replica" single ((:commit . "38f517ac2894b16e6cf983b93ee96762fffa152a") (:authors ("Kinney Zhang" . "kinneyzhang666@gmail.com")) (:maintainer "Kinney Zhang" . "kinneyzhang666@gmail.com") (:keywords "org" "convenience") (:url . "https://github.com/Kinneyzhang/gkroam"))])
+ (gl-conf-mode . [(20170714 1310) ((emacs (24 3))) "Mode for editing gitolite config files" single ((:commit . "9136a9b737e0a5b6471a91571d104c487c43f35b") (:authors ("Luis Lloret")) (:maintainer "Luis Lloret") (:keywords "git" "gitolite" "languages") (:url . "https://github.com/llloret/gitolite-emacs"))])
+ (global-tags . [(20211120 347) ((emacs (26 1)) (async (1 9 4)) (project (0 5 2)) (ht (2 3))) "Elisp API and editor integration for GNU global" single ((:commit . "aaa37da4c538f35a90149ef4ad3d8b0922af54ab") (:authors ("Felipe Lema" . "felipelema@mortemale.org")) (:maintainer "Felipe Lema" . "felipelema@mortemale.org") (:keywords "convenience" "matching" "tools") (:url . "https://launchpad.net/global-tags.el"))])
+ (glsl-mode . [(20210808 1945) nil "major mode for Open GLSL shader files" single ((:commit . "9b2e5f28e489a1f73c4aed734105618ac0dc0c43") (:keywords "languages" "opengl" "gpu" "spir-v" "vulkan") (:url . "https://github.com/jimhourihan/glsl-mode"))])
+ (gmail-message-mode . [(20160627 1847) ((ham-mode (1 0))) "A major-mode for editing gmail messages using markdown syntax." single ((:commit . "ec36672a9dc93c09ebe2f77597b498d11883d008") (:authors ("Artur Malabarba" . "bruce.connor.am@gmail.com")) (:maintainer "Artur Malabarba" . "bruce.connor.am@gmail.com") (:keywords "mail" "convenience" "emulation") (:url . "http://github.com/Bruce-Connor/gmail-message-mode"))])
+ (gmail2bbdb . [(20170423 1144) nil "import email and name into bbdb from vcard." single ((:commit . "a84fa385cfaec7fc5f1518c368e52722da139f99") (:authors ("Chen Bin" . "chenbin.sh@gmail.com")) (:maintainer "Chen Bin" . "chenbin.sh@gmail.com") (:keywords "vcard" "bbdb" "email" "contact" "gmail") (:url . "http://github.com/redguardtoo/gmail2bbdb"))])
+ (gmpl-mode . [(20220121 631) ((emacs (24))) "Major mode for editing GMPL(MathProg) files" single ((:commit . "97b103eea8b18f7e27b0f0be6cb4809a4156c032") (:authors ("Junpeng Qiu" . "qjpchmail@gmail.com")) (:maintainer "Junpeng Qiu" . "qjpchmail@gmail.com") (:keywords "extensions"))])
+ (gmsh-mode . [(20211204 826) ((emacs (26 1))) "Highlight GMSH mesh generator script syntax" single ((:commit . "2b7c573f378f7e9210400115d4d9dfd879f8a4ad") (:authors ("Matsievskiy S.V.")) (:maintainer "Matsievskiy S.V.") (:keywords "languages") (:url . "https://gitlab.com/matsievskiysv/gmsh-mode"))])
+ (gn-mode . [(20190428 1812) ((emacs (24)) (cl-lib (0 5))) "major mode for editing GN (generate ninja) files" single ((:commit . "fcf8e1e500d953364e97e7ebc5708a2c00fa3cd2") (:authors ("Emily Backes" . "lucca@accela.net")) (:maintainer "Emily Backes" . "lucca@accela.net") (:keywords "data") (:url . "http://github.com/lashtear/gn-mode"))])
+ (gnome-calendar . [(20161110 1256) nil "Integration with the GNOME Shell calendar" single ((:commit . "489f9f15f7bb35696b1cc19db75b554ae8328df2") (:authors ("Nicolas Petton" . "nicolas@petton.fr")) (:maintainer "Nicolas Petton" . "nicolas@petton.fr") (:keywords "gnome" "calendar"))])
+ (gnome-screencast . [(20210125 2001) ((emacs (25))) "Use Gnome screen recording functionality using elisp" single ((:commit . "6450ee470e84ff14a15c5c3c0489c79ff593f165") (:authors ("Jürgen Hötzel" . "juergen@hoetzel.info")) (:maintainer "Jürgen Hötzel" . "juergen@hoetzel.info") (:keywords "tools" "multimedia") (:url . "https://github.com/juergenhoetzel/emacs-gnome-screencast"))])
+ (gnomenm . [(20150316 1918) ((s (1 9 0)) (dash (2 3 0)) (kv (0 0 19))) "Emacs interface to Gnome nmcli command" single ((:commit . "9065cda44ffc9e06239b8189a0154d31314c3b4d") (:authors ("Nic Ferrier" . "nferrier@ferrier.me.uk")) (:maintainer "Nic Ferrier" . "nferrier@ferrier.me.uk") (:keywords "processes" "hardware") (:url . "http://github.com/nicferrier/emacs-nm"))])
+ (gntp . [(20141025 250) nil "Growl Notification Protocol for Emacs" single ((:commit . "767571135e2c0985944017dc59b0be79af222ef5") (:authors ("Engelke Eschner" . "tekai@gmx.li")) (:maintainer "Engelke Eschner" . "tekai@gmx.li"))])
+ (gnu-apl-mode . [(20220404 341) ((emacs (27))) "Integrate GNU APL with Emacs" tar ((:commit . "c8695b0d55b5167263a843252ffd21a589018427") (:authors ("Elias Mårtenson" . "lokedhs@gmail.com")) (:maintainer "Elias Mårtenson" . "lokedhs@gmail.com") (:keywords "languages") (:url . "http://www.gnu.org/software/apl/"))])
+ (gnu-indent . [(20220330 422) ((emacs (27 2))) "Indent your code with GNU Indent" single ((:commit . "cd5dc79ac65c24e9e775bd2582ad620e316f2182") (:authors ("Akib Azmain Turja" . "akib@disroot.org")) (:maintainer "Akib Azmain Turja" . "akib@disroot.org") (:keywords "tools" "c") (:url . "https://codeberg.org/akib/emacs-gnu-indent"))])
+ (gnuplot . [(20220102 1637) ((emacs (24 3))) "Major-mode and interactive frontend for gnuplot" tar ((:commit . "57be3c7addec31e226a5a27aa553e996f9c684e3") (:authors ("Jon Oddie") ("Bruce Ravel") ("Phil Type")) (:maintainer "Bruce Ravel" . "bruceravel1@gmail.com") (:keywords "data" "gnuplot" "plotting") (:url . "https://github.com/emacsorphanage/gnuplot"))])
+ (gnuplot-mode . [(20171013 1616) nil "Major mode for editing gnuplot scripts" single ((:commit . "601f6392986f0cba332c87678d31ae0d0a496ce7") (:keywords "gnuplot" "plotting") (:url . "https://github.com/mkmcc/gnuplot-mode"))])
+ (gnus-alias . [(20150316 42) nil "an alternative to gnus-posting-styles" single ((:commit . "9447d3ccb4c0e75d0468899cccff7aa249657bac") (:authors ("Joe Casadonte" . "emacs@northbound-train.com")) (:maintainer "Mark A. Hershberger" . "mah@everybody.org") (:keywords "personality" "identity" "news" "mail" "gnus"))])
+ (gnus-desktop-notify . [(20180623 1538) ((gnus (1 0))) "Gnus Desktop Notification global minor mode" single ((:commit . "b438feb59136621a8ab979f0e2784f7002398d06") (:authors ("Yuri D'Elia <wavexx AT thregr.org>")) (:maintainer "Yuri D'Elia <wavexx AT thregr.org>") (:url . "http://www.thregr.org/~wavexx/software/gnus-desktop-notify.el/"))])
+ (gnus-notes . [(20210207 1010) ((emacs (27 1)) (bbdb (3 1)) (helm (3 1)) (hydra (0 13 0)) (org (8 3)) (s (0 0)) (lv (0 0)) (async (1 9 1))) "Keep handy notes of read Gnus articles with helm and org" tar ((:commit . "1457bba34b40d5197aa14dbf0856925f83025ae1") (:authors ("Deus Max" . "deusmax@gmx.com")) (:maintainer "Deus Max" . "deusmax@gmx.com") (:keywords "convenience" "mail" "bbdb" "gnus" "helm" "org" "hydra") (:url . "https://github.com/deusmax/gnus-notes"))])
+ (gnus-recent . [(20220324 2011) ((emacs (25 3 2))) "Article breadcrumbs for Gnus" single ((:commit . "a0ace8ea6e62a6b79a18149fbd560c6948a8103b") (:authors ("Kevin Brubeck Unhammer" . "unhammer@fsfe.org")) (:maintainer "Kevin Brubeck Unhammer" . "unhammer@fsfe.org") (:keywords "convenience" "mail") (:url . "https://github.com/unhammer/gnus-recent"))])
+ (gnus-select-account . [(20170722 511) nil "Select an account before writing a mail in gnus" single ((:commit . "ddc8c135eeaf90f5b6692a033af2badae36e68ce") (:authors ("Feng Shu " . "tumashu@163.com")) (:maintainer "Feng Shu " . "tumashu@163.com") (:keywords "convenience") (:url . "https://github.com/tumashu/gnus-select-account"))])
+ (gnus-summary-ext . [(20180113 1316) nil "Extra limit and process mark commands for the gnus summary buffer" single ((:commit . "025fd853fe9280ae696a89ec2c2cac9befd010aa") (:authors ("Joe Bloggs" . "vapniks@yahoo.com")) (:maintainer "Joe Bloggs" . "vapniks@yahoo.com") (:keywords "comm") (:url . "https://github.com/vapniks/gnus-summary-ext"))])
+ (gnus-summary-repo . [(20190617 1419) ((emacs (25))) "Import and export files between IMAP and local by using GNUS" single ((:commit . "1341b68dfda952a95f5d9b4cb7d427716dafa310") (:authors ("Giap Tran" . "txgvnn@gmail.com")) (:maintainer "Giap Tran" . "txgvnn@gmail.com") (:keywords "gnus" "repository") (:url . "https://github.com/TxGVNN/gnus-summary-repo"))])
+ (gnus-x-gm-raw . [(20140610 731) ((log4e (0 2 0)) (yaxception (0 1))) "Search mail of Gmail using X-GM-RAW as web interface" single ((:commit . "978bdfcecc8844465b71641c2e909fcdc66b22be") (:authors ("Hiroaki Otsu" . "ootsuhiroaki@gmail.com")) (:maintainer "Hiroaki Otsu" . "ootsuhiroaki@gmail.com") (:keywords "gnus") (:url . "https://github.com/aki2o/gnus-x-gm-raw"))])
+ (go . [(20220414 1956) ((emacs (24))) "Play GO, translate and transfer between GO back ends" tar ((:commit . "79690579496b0df85a1c94199aca968371b58b3c") (:authors ("Eric Schulte" . "schulte.eric@gmail.com")) (:maintainer "Eric Schulte" . "schulte.eric@gmail.com") (:keywords "game" "go" "sgf") (:url . "http://eschulte.github.io/el-go/"))])
+ (go-add-tags . [(20161123 1227) ((emacs (24 3)) (s (1 11 0))) "Add field tags for struct fields" single ((:commit . "54879945e46a0884c5f93d7fd6c866a9cdf401ac") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-go-add-tags"))])
+ (go-autocomplete . [(20170626 1023) ((auto-complete (1 4 0))) "auto-complete-mode backend for go-mode" single ((:commit . "5327738ec1be51061a3f31010c89bdd4924ca496") (:authors ("Mikhail" . "tensai@cirno.in")) (:maintainer "Mikhail" . "tensai@cirno.in") (:keywords "languages"))])
+ (go-complete . [(20190409 516) ((go-mode (0)) (cl-lib (0 5))) "Native code completion for Go" single ((:commit . "056294014f37a1004958ec17ebd6748deed63502") (:authors ("Vibhav Pant" . "vibhavp@gmail.com")) (:maintainer "Vibhav Pant" . "vibhavp@gmail.com") (:keywords "go" "golang" "completion") (:url . "https://github.com/vibhavp/go-complete"))])
+ (go-direx . [(20150316 143) ((direx (1 0 0)) (cl-lib (0 5))) "Tree style source code viewer for Go language" single ((:commit . "8f2206469328ee932c7f1892f5e1fb02dec98432") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-go-direx"))])
+ (go-dlv . [(20220126 1436) ((go-mode (1 3 1))) "Go Delve - Debug Go programs interactively with the GUD." single ((:commit . "0a296bc3b7b4dcf0c140a78c5ca3e1a8c6b7ea1a") (:authors ("Marko Bencun" . "mbencun@gmail.com")) (:maintainer "Marko Bencun" . "mbencun@gmail.com") (:keywords "go" "debug" "debugger" "delve" "interactive" "gud") (:url . "https://github.com/benma/go-dlv.el/"))])
+ (go-eldoc . [(20170305 1427) ((emacs (24 3)) (go-mode (1 0 0))) "eldoc for go-mode" single ((:commit . "cbbd2ea1e94a36004432a9ac61414cb5a95a39bd") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-go-eldoc"))])
+ (go-errcheck . [(20160723 43) nil "errcheck integration for go-mode" single ((:commit . "9db21eccecedc2490793f176246094167164af31") (:authors ("Dominik Honnef" . "dominikh@fork-bomb.org")) (:maintainer "Dominik Honnef" . "dominikh@fork-bomb.org"))])
+ (go-expr-completion . [(20200817 1750) ((emacs (24 1))) "Complement the return values for Go" single ((:commit . "66bba78f52a732b978848e3a4c99fa2afeb6c25f") (:authors ("Ryo Fujimoto" . "fujimisakri@gmail.com")) (:maintainer "Ryo Fujimoto" . "fujimisakri@gmail.com") (:url . "https://github.com/fujimisakari/emacs-go-expr-completion"))])
+ (go-fill-struct . [(20171225 331) ((emacs (24))) "Fill struct for golang." single ((:commit . "a613d0b378473eef39e8fd5724abe790aea84321") (:authors ("Sergey Kostyaev" . "feo.me@ya.ru")) (:maintainer "Sergey Kostyaev" . "feo.me@ya.ru") (:keywords "tools") (:url . "https://github.com/s-kostyaev/go-fill-struct"))])
+ (go-gen-test . [(20210816 1215) ((emacs (24 3)) (s (1 12))) "Generate tests for go code with gotests" single ((:commit . "35df36dcd555233ee1a618c0f6a58ce6db4154d9") (:authors ("Sergey Kostyaev" . "feo.me@ya.ru")) (:maintainer "Sergey Kostyaev" . "feo.me@ya.ru") (:keywords "languages") (:url . "https://github.com/s-kostyaev/go-gen-test"))])
+ (go-gopath . [(20160705 1034) ((cl-lib (0 5))) "Will guess GOPATH using gb and projectile." single ((:commit . "5172fc53f21edbf9347d5ee7d1d745da1ec88a15") (:authors ("Andrew Kirilenko" . "andrew.kirilenko.main@gmail.com")) (:maintainer "Andrew Kirilenko" . "andrew.kirilenko.main@gmail.com") (:url . "http://github.com/iced/go-gopath/"))])
+ (go-guru . [(20181012 330) ((go-mode (1 3 1)) (cl-lib (0 5))) "Integration of the Go 'guru' analysis tool into Emacs." single ((:commit . "fa2693278637f56759480d2bf203bb8aad107230") (:keywords "tools"))])
+ (go-imenu . [(20181029 1029) ((emacs (24 3))) "Enhance imenu for go language" single ((:commit . "4f3f334ed0b6f6afaca6b9775636a52ad3843053") (:authors ("Brantou" . "brantou89@gmail.com")) (:maintainer "Brantou" . "brantou89@gmail.com") (:keywords "tools") (:url . "https://github.com/brantou/go-imenu.el"))])
+ (go-impl . [(20210621 743) ((emacs (24 3)) (go-mode (1 3 0))) "impl integration for go-mode" single ((:commit . "1eebba6ccd02d11a5a82ad4540a8d562797bc3b3") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-go-impl"))])
+ (go-imports . [(20190715 1647) nil "Insert go import statement given package name" tar ((:commit . "55681e815da93b6f927213c4aa352ae33db97c37") (:authors ("Yaz Saito")) (:maintainer "Yaz Saito") (:keywords "tools" "go" "import") (:url . "https://github.com/yasushi-saito/go-imports"))])
+ (go-mode . [(20220114 2239) ((emacs (26 1))) "Major mode for the Go programming language" single ((:commit . "fa2693278637f56759480d2bf203bb8aad107230") (:authors ("The go-mode Authors")) (:maintainer "The go-mode Authors") (:keywords "languages" "go") (:url . "https://github.com/dominikh/go-mode.el"))])
+ (go-noisegate . [(20200502 703) ((emacs (24 4))) "Run Golang tests with Noise Gate" single ((:commit . "e3fc198c234131c94f7d307b7f7c6ef623fb93b7") (:authors ("The Noise Gate Authors")) (:maintainer "The Noise Gate Authors") (:keywords "languages" "go" "test") (:url . "https://github.com/go-noisegate/go-noisegate.el"))])
+ (go-playground . [(20220106 1618) ((emacs (24)) (go-mode (1 4 0)) (gotest (0 13 0))) "Local Golang playground for short snippets." single ((:commit . "9ee7dcc7f78be67cc391f13efa6570c2baac0204") (:authors ("Alexander I.Grafov" . "grafov@gmail.com")) (:maintainer "Alexander I.Grafov" . "grafov@gmail.com") (:keywords "tools" "golang") (:url . "https://github.com/grafov/go-playground"))])
+ (go-playground-cli . [(20160503 914) ((emacs (24)) (request (0 2 0)) (deferred (0 3 2)) (names (20151201 404)) (s (1 10 0)) (f (0 17 2)) (let-alist (1 0 4)) (cl-lib (0 5))) "Go Playground client tool" single ((:commit . "60beebd98e3930641d41cee0189c579626f223bc") (:authors ("KOBAYASHI Shigeru (kosh)" . "shigeru.kb@gmail.com")) (:maintainer "KOBAYASHI Shigeru (kosh)" . "shigeru.kb@gmail.com") (:url . "https://github.com/kosh04/go-playground-cli"))])
+ (go-projectile . [(20200609 131) ((projectile (0 10 0)) (go-mode (0)) (go-eldoc (0 16)) (go-rename (0)) (go-guru (0)) (dash (2 17 0))) "Go add-ons for Projectile" single ((:commit . "ad4ca3b5695a0e31e95e3cc4ccab498f87d68303") (:authors ("Doug MacEachern" . "dougm@vmware.com")) (:maintainer "Doug MacEachern" . "dougm@vmware.com") (:keywords "project" "convenience") (:url . "https://github.com/dougm/go-projectile"))])
+ (go-rename . [(20190805 2101) ((go-mode (1 3 1))) "Integration of the 'gorename' tool into Emacs." single ((:commit . "fa2693278637f56759480d2bf203bb8aad107230") (:keywords "tools"))])
+ (go-scratch . [(20150810 440) ((go-mode (1 3 1)) (emacs (24))) "*scratch* buffer for Go" single ((:commit . "3f68cbcce04f59eb8e83af109164731ec0454be0") (:authors ("Emanuel Evans" . "mail@emanuel.industries")) (:maintainer "Emanuel Evans" . "mail@emanuel.industries") (:keywords "languages" "go"))])
+ (go-snippets . [(20180113 611) ((yasnippet (0 8 0))) "Yasnippets for go" tar ((:commit . "d437df148879566ffe7f2e503a3cf2602aa9fb28") (:keywords "snippets"))])
+ (go-stacktracer . [(20150430 2142) nil "parse Go stack traces" single ((:commit . "a2ac6d801b389f80ca4e2fcc1ab44513a9e55976") (:authors ("Samer Masterson" . "samer@samertm.com")) (:maintainer "Samer Masterson" . "samer@samertm.com") (:keywords "tools") (:url . "https://github.com/samertm/go-stacktracer.el"))])
+ (go-tag . [(20180227 411) ((emacs (24 0)) (go-mode (1 5 0))) "Edit Golang struct field tag" single ((:commit . "59b243f2fa079d9de9d56f6e2d94397e9560310a") (:authors ("Brantou" . "brantou89@gmail.com")) (:maintainer "Brantou" . "brantou89@gmail.com") (:keywords "tools") (:url . "https://github.com/brantou/emacs-go-tag"))])
+ (go-translate . [(20220404 1240) ((emacs (27 1))) "Translation framework supports multiple engines such as Google/Bing/DeepL" tar ((:commit . "b0898e6cd647e38e6f70e6cd121b789610573237") (:authors ("lorniu" . "lorniu@gmail.com")) (:maintainer "lorniu" . "lorniu@gmail.com") (:keywords "convenience") (:url . "https://github.com/lorniu/go-translate"))])
+ (gobgen . [(20161020 1523) ((emacs (24 4))) "Generate GObject descendants using a detailed form" single ((:commit . "ed2c2b0d217deae293096f3cf14aa492791ddd4f") (:authors ("Gergely Polonkai" . "gergely@polonkai.eu")) (:maintainer "Gergely Polonkai" . "gergely@polonkai.eu") (:keywords "gobject" "glib" "gtk" "helper" "utilities"))])
+ (god-mode . [(20210102 515) ((emacs (25 1))) "Minor mode for God-like command entering" tar ((:commit . "fac7d26ecde1be5b0bf6bd6e0ec5b4895be13906") (:authors ("Chris Done" . "chrisdone@gmail.com")) (:maintainer "Chris Done" . "chrisdone@gmail.com") (:url . "https://github.com/emacsorphanage/god-mode"))])
+ (godoctor . [(20180710 2152) nil "Frontend for godoctor" single ((:commit . "4b45ff3d0572f0e84056e4c3ba91fcc178199859") (:authors ("Sangho Na" . "microamp@protonmail.com")) (:maintainer "Sangho Na" . "microamp@protonmail.com") (:keywords "go" "golang" "refactoring") (:url . "https://github.com/microamp/godoctor.el"))])
+ (goggles . [(20220403 1812) ((emacs (27 1))) "Pulse modified regions" single ((:commit . "6941fd5bc19c0a2789dda38334d2be582ed34e5a") (:authors ("Daniel Mendler")) (:maintainer "Daniel Mendler") (:url . "https://github.com/minad/goggles"))])
+ (gold-mode . [(20140607 206) ((sws-mode (0))) "Major mode for editing .gold files" single ((:commit . "6d3aa59602b1b835495271c8c9741ac344c2eab1") (:authors ("Yuta Yamada <cokesboy\"at\"gmail.com>")) (:maintainer "Yuta Yamada <cokesboy\"at\"gmail.com>") (:keywords "golang" "template" "gold") (:url . "https://github.com/yuutayamada/gold-mode-el"))])
+ (golden-ratio . [(20191028 1732) nil "Automatic resizing of Emacs windows to the golden ratio" single ((:commit . "007911d8a431b72670f5fe5f0e5b4380c2777a31") (:authors ("Roman Gonzalez" . "romanandreg@gmail.com")) (:maintainer "Roman Gonzalez" . "romanandreg@gmail.com") (:keywords "window" "resizing"))])
+ (golden-ratio-scroll-screen . [(20200419 451) nil "Scroll half screen down or up, and highlight current line" single ((:commit . "1b6ff0e3e8822423335d3f7d88c1fcb4cf43ce42") (:authors ("纪秀峰 <jixiuf at gmail dot com>")) (:maintainer "纪秀峰 <jixiuf at gmail dot com>") (:keywords "scroll" "screen" "highlight") (:url . "https://github.com/jixiuf/golden-ratio-scroll-screen"))])
+ (goldendict . [(20220210 1401) ((emacs (24 4)) (cl-lib (0 5))) "query word smartly with goldendict.el" single ((:commit . "f3fbe658a8d31dc1bd0ca69e4d2ebaab59e92791") (:keywords "dict" "goldendict") (:url . "https://repo.or.cz/goldendict.el.git"))])
+ (golint . [(20180221 2015) nil "lint for the Go source code" single ((:commit . "6edffad5e6160f5949cdefc81710b2706fbcd4f6") (:url . "https://github.com/golang/lint"))])
+ (gom-mode . [(20131008 253) nil "Major mode for Gomfile" single ((:commit . "972e33df1d38ff323bc97de87477305826013701") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-gom-mode"))])
+ (gomacro-mode . [(20200326 1103) ((emacs (24 4)) (go-mode (1 5 0))) "Gomacro mode and Go REPL integration" single ((:commit . "3112e56d2d5e645a3e0fd877f3e810dbccbf989f") (:authors ("Petter Storvik")) (:maintainer "Petter Storvik") (:keywords "gomacro" "repl" "languages" "tools" "processes") (:url . "https://github.com/storvik/gomacro-mode"))])
+ (good-scroll . [(20211101 942) ((emacs (27 1))) "Good pixel line scrolling" tar ((:commit . "a7ffd5c0e5935cebd545a0570f64949077f71ee3") (:authors ("Benjamin Levy" . "blevy@protonmail.com")) (:maintainer "Benjamin Levy" . "blevy@protonmail.com") (:url . "https://github.com/io12/good-scroll.el"))])
+ (google . [(20140416 1748) nil "Emacs interface to the Google API" single ((:commit . "3b3189a8b201c8d36fed6e61496274e530dd40bd") (:authors ("Edward O'Connor" . "ted@oconnor.cx")) (:maintainer "Edward O'Connor" . "ted@oconnor.cx") (:keywords "comm" "processes" "tools"))])
+ (google-c-style . [(20220210 1659) nil "Google's C/C++ style for c-mode" single ((:commit . "992ad03d50b8c67635208616cf1dbfab29dc6d3f") (:keywords "c" "tools"))])
+ (google-contacts . [(20201012 1056) ((oauth2 (0 10)) (cl-lib (0 5))) "Support for Google Contacts in Emacs" tar ((:commit . "8923c238fe0906184d2254b33ba72792ed12cd47") (:authors ("Julien Danjou" . "julien@danjou.info")) (:maintainer "Julien Danjou" . "julien@danjou.info") (:keywords "comm") (:url . "https://github.com/jd/google-contacts.el"))])
+ (google-maps . [(20181121 1532) ((emacs (24 3))) "Access Google Maps from Emacs" tar ((:commit . "2eb16ff609f5a9f8d02c15238a111fbb7db6c146") (:authors ("Julien Danjou" . "julien@danjou.info")) (:maintainer "Julien Danjou" . "julien@danjou.info") (:keywords "comm") (:url . "https://julien.danjou.info/projects/emacs-packages#google-maps"))])
+ (google-this . [(20170810 1215) ((emacs (24 1))) "A set of functions and bindings to google under point." single ((:commit . "8a2e3ca5da6a8c89bfe99a21486c6c7db125dc84") (:authors ("Artur Malabarba" . "bruce.connor.am@gmail.com")) (:maintainer "Artur Malabarba" . "bruce.connor.am@gmail.com") (:keywords "convenience" "hypermedia") (:url . "http://github.com/Malabarba/emacs-google-this"))])
+ (google-translate . [(20210406 1138) nil "Emacs interface to Google Translate." tar ((:commit . "0f7f48a09bca064999ecea03102a7c96f52cbd1b") (:authors ("Oleksandr Manzyuk" . "manzyuk@gmail.com")) (:maintainer "Andrey Tykhonov" . "atykhonov@gmail.com") (:keywords "convenience") (:url . "https://github.com/atykhonov/google-translate"))])
+ (goose-theme . [(20160828 1245) ((emacs (24 1))) "A gray color theme" single ((:commit . "acd017b50ab25a75fd1331eb3de66467e2042e9c") (:authors ("Stephen Whipple" . "shw@wicdmedia.org")) (:maintainer "Stephen Whipple" . "shw@wicdmedia.org") (:url . "https://github.com/thwg/goose-theme"))])
+ (gore-mode . [(20151123 1927) ((go-mode (1 0 0))) "Simple mode for gore, a command-line evaluator for golang." single ((:commit . "94d7f3e99104e06167967c98fdc201049c433c2d") (:authors ("Sergey Pashaev" . "sergey.pashaev@gmail.com")) (:maintainer "Sergey Pashaev" . "sergey.pashaev@gmail.com") (:keywords "go" "repl"))])
+ (gorepl-mode . [(20170905 945) ((emacs (24)) (s (1 11 0)) (f (0 19 0)) (hydra (0 13 0))) "Go REPL Interactive Development in top of Gore" single ((:commit . "6a73bf352e8d893f89cad36c958c4db2b5e35e07") (:authors ("Manuel Alonso" . "manuteali@gmail.com")) (:maintainer "Manuel Alonso" . "manuteali@gmail.com") (:keywords "languages" "go" "golang" "gorepl") (:url . "http://www.github.com/manute/gorepl-mode"))])
+ (gotest . [(20220209 1739) ((emacs (24 3)) (s (1 11 0)) (f (0 19 0)) (go-mode (1 5 0))) "Launch GO unit tests" single ((:commit . "78be56c0f210224b1e3a7d58239e2a32f8f84bf4") (:authors ("Nicolas Lamirault" . "nicolas.lamirault@gmail.com")) (:maintainer "Nicolas Lamirault" . "nicolas.lamirault@gmail.com") (:keywords "languages" "go" "tests") (:url . "https://github.com/nlamirault/gotest.el"))])
+ (gotham-theme . [(20220107 1730) ((emacs (24 1))) "A very dark Emacs color theme" single ((:commit . "4b8214df0851bb69b44c3e864568b7e0030a95d2") (:authors ("Vasilij Schneidermann" . "mail@vasilij.de")) (:maintainer "Vasilij Schneidermann" . "mail@vasilij.de") (:url . "https://depp.brause.cc/gotham-theme"))])
+ (goto-char-preview . [(20210323 332) ((emacs (24 3))) "Preview character when executing `goto-char` command" single ((:commit . "ea845966423ce90526d717bb27d0022101c75796") (:authors ("Shen, Jen-Chieh" . "jcs090218@gmail.com")) (:maintainer "Shen, Jen-Chieh" . "jcs090218@gmail.com") (:url . "https://github.com/jcs-elpa/goto-char-preview"))])
+ (goto-chg . [(20220107 1733) ((emacs (24 1))) "Go to last change" single ((:commit . "278cd3e6d5107693aa2bb33189ca503f22f227d0") (:authors ("David Andersson <l.david.andersson(at)sverige.nu>")) (:maintainer "Vasilij Schneidermann" . "mail@vasilij.de") (:keywords "convenience" "matching") (:url . "https://github.com/emacs-evil/goto-chg"))])
+ (goto-last-change . [(20150109 1823) nil "Move point through buffer-undo-list positions" single ((:commit . "58b0928bc255b47aad318cd183a5dce8f62199cc") (:authors ("Kevin Rodgers" . "ihs_4664@yahoo.com")) (:maintainer "Kevin Rodgers" . "ihs_4664@yahoo.com") (:keywords "convenience") (:url . "https://github.com/camdez/goto-last-change.el"))])
+ (goto-last-point . [(20190525 1855) ((emacs (24 3))) "Record and jump to the last point in the buffer." single ((:commit . "7ea191df18ff4774cf1dc568e1726143dd54ea02") (:authors ("Manuel Uberti" . "manuel.uberti@inventati.org")) (:maintainer "Manuel Uberti" . "manuel.uberti@inventati.org") (:keywords "convenience") (:url . "https://github.com/manuel-uberti/goto-last-point"))])
+ (goto-line-preview . [(20210323 422) ((emacs (25))) "Preview line when executing `goto-line` command" single ((:commit . "d4db955860de830ebc067b065cba16a776717e76") (:authors ("Shen, Jen-Chieh" . "jcs090218@gmail.com")) (:maintainer "Shen, Jen-Chieh" . "jcs090218@gmail.com") (:url . "https://github.com/jcs-elpa/goto-line-preview"))])
+ (govc . [(20191213 2131) ((emacs (24 3)) (dash (1 5 0)) (s (1 9 0)) (magit-popup (2 0 50)) (json-mode (1 6 0))) "Interface to govc for managing VMware ESXi and vCenter" single ((:commit . "be5528b51ec58f28601350e466e662727cf6c7c4") (:authors ("The govc developers")) (:maintainer "The govc developers") (:keywords "convenience") (:url . "https://github.com/vmware/govmomi/tree/master/govc/emacs"))])
+ (govet . [(20170808 1724) nil "linter/problem finder for the Go source code" single ((:commit . "1c05817cf8b96589076c7ac4e52ee58a860a0cbf") (:url . "https://godoc.org/golang.org/x/tools/cmd/vet"))])
+ (gpastel . [(20181229 1404) ((emacs (25 1))) "Integrates GPaste with the kill-ring" single ((:commit . "d5fc55bc825203f998537c5834718e665bb87c29") (:authors ("Damien Cassou" . "damien@cassou.me")) (:maintainer "Damien Cassou" . "damien@cassou.me") (:keywords "tools") (:url . "https://gitlab.petton.fr/DamienCassou/desktop-environment"))])
+ (grab-mac-link . [(20210511 1303) ((emacs (24))) "Grab link from Mac Apps and insert it into Emacs" single ((:commit . "2c722016ca01bd4265d57c4a7d55712c94cf4ea5") (:authors ("Xu Chunyang")) (:maintainer "Xu Chunyang") (:keywords "mac" "hyperlink") (:url . "https://github.com/xuchunyang/grab-mac-link.el"))])
+ (grab-x-link . [(20191113 848) ((emacs (24)) (cl-lib (0 5))) "Grab links from X11 apps and insert into Emacs" single ((:commit . "d898db46e4864118359fdedfe915e180de3fe290") (:authors ("Xu Chunyang" . "mail@xuchunyang.me")) (:maintainer "Xu Chunyang" . "mail@xuchunyang.me") (:keywords "hyperlink") (:url . "https://github.com/xuchunyang/grab-x-link"))])
+ (gradle-mode . [(20150313 1905) ((s (1 8 0))) "Gradle integration with Emacs' compile" single ((:commit . "e4d665d5784ecda7ddfba015f07c69be3cfc45f2") (:authors ("Daniel Mijares" . "daniel.j.mijares@gmail.com")) (:maintainer "Daniel Mijares" . "daniel.j.mijares@gmail.com") (:keywords "gradle") (:url . "http://github.com/jacobono/emacs-gradle-mode"))])
+ (grails . [(20220407 1847) ((emacs (24))) "Minor mode for Grails projects" single ((:commit . "350869ecc4f429fc4e26f826d6050d068e724c5d") (:url . "https://github.com/lifeisfoo/emacs-grails"))])
+ (grails-mode . [(20220407 1954) nil "minor-mode that adds some Grails project management to a grails project" single ((:commit . "29210e5a969c02169b68e04f2e28e3bf2fc13363") (:authors ("Jim Morris" . "morris@wolfman.com")) (:maintainer "Russel Winder" . "russel@winder.org.uk") (:keywords "languages") (:url . "http://blog.wolfman.com"))])
+ (grails-projectile-mode . [(20160327 1324) ((projectile (0 10 0)) (emacs (24)) (cl-lib (0 5))) "Grails mode with Projectile for projects management." tar ((:commit . "8efca50ce92b556fe9d467b157d7aec635bcc017") (:authors ("Yves Zoundi" . "rimerosolutions@gmail.com")) (:maintainer "Yves Zoundi") (:keywords "grails" "projectile") (:url . "https://github.com/yveszoundi/grails-projectile-mode"))])
+ (grammarly . [(20220222 638) ((emacs (24 4)) (s (1 12 0)) (request (0 3 0)) (websocket (1 6))) "Grammarly API interface" single ((:commit . "1d616a446c64dfe7d85f80cd38ce2a1e2a3b0f34") (:authors ("Shen, Jen-Chieh" . "jcs090218@gmail.com")) (:maintainer "Shen, Jen-Chieh" . "jcs090218@gmail.com") (:url . "https://github.com/emacs-grammarly/grammarly"))])
+ (grandshell-theme . [(20180606 517) nil "Dark color theme for Emacs > 24 with intensive colors." tar ((:commit . "0ed8e4273607dd4fcaa742b4097259233b09eda6") (:authors ("steckerhalter")) (:maintainer "steckerhalter") (:keywords "color" "theme" "grand" "shell" "faces") (:url . "https://framagit.org/steckerhalter/grandshell-theme"))])
+ (graphene . [(20180529 1112) ((dash (2 10 0)) (exec-path-from-shell (1 9)) (ppd-sr-speedbar (0 0 6)) (sr-speedbar (20140505)) (ido-completing-read+ (4 3)) (smex (3 0)) (web-mode (11 2)) (smartparens (1 8 0)) (graphene-meta-theme (0 0 2)) (flycheck (0 23)) (company (0 8 12))) "Friendly Emacs defaults" tar ((:commit . "cc8477fcfb7771ea4e5bbaf3c01f9e679234c1c1") (:authors ("Robert Dallas Gray" . "mail@robertdallasgray.com")) (:maintainer "Robert Dallas Gray" . "mail@robertdallasgray.com") (:keywords "defaults") (:url . "https://github.com/rdallasgray/graphene"))])
+ (graphene-meta-theme . [(20161204 1607) nil "Integrated theming for common packages" single ((:commit . "62cc73fee31f1bd9474027b83a249feee050271e") (:authors ("Robert Dallas Gray" . "mail@robertdallasgray.com")) (:maintainer "Robert Dallas Gray" . "mail@robertdallasgray.com") (:keywords "defaults") (:url . "https://github.com/rdallasgray/graphene"))])
+ (graphql . [(20180912 31) ((emacs (25))) "GraphQL utilities" single ((:commit . "5ca5f50b5e6f3883f1138453a356d59a1c002120") (:authors ("Sean Allred" . "code@seanallred.com")) (:maintainer "Sean Allred" . "code@seanallred.com") (:keywords "hypermedia" "tools" "lisp") (:url . "https://github.com/vermiculus/graphql.el"))])
+ (graphql-doc . [(20210808 8) ((emacs (26 1)) (request (0 3 2)) (promise (1 1))) "GraphQL Documentation Explorer" single ((:commit . "6ba7961fc9c5c9818bd60abce6ba9dfef2dad452") (:authors ("Ian Fitzpatrick")) (:maintainer "Ian Fitzpatrick") (:url . "https://github.com/ifitzpatrick/graphql-doc.el"))])
+ (graphql-mode . [(20211127 1023) ((emacs (24 3))) "Major mode for editing GraphQL schemas" single ((:commit . "9740e4027bd9313697d5cac5caaa5b15626ab1da") (:authors ("David Vazquez Pua" . "davazp@gmail.com")) (:maintainer "David Vazquez Pua" . "davazp@gmail.com") (:keywords "languages") (:url . "https://github.com/davazp/graphql-mode"))])
+ (graphviz-dot-mode . [(20220309 1336) ((emacs (25 0))) "Mode for the dot-language used by graphviz (att)." tar ((:commit . "6e96a89762760935a7dff6b18393396f6498f976") (:maintainer "Pieter Pareit" . "pieter.pareit@gmail.com") (:keywords "mode" "dot" "dot-language" "dotlanguage" "graphviz" "graphs" "att") (:url . "https://ppareit.github.io/graphviz-dot-mode/"))])
+ (grapnel . [(20131001 1534) nil "HTTP request lib with flexible callback dispatch" single ((:commit . "fbd0f9a51139973d35e4014855964fa435e8ecaf") (:authors ("David Leatherman" . "leathekd@gmail.com")) (:maintainer "David Leatherman" . "leathekd@gmail.com") (:url . "http://www.github.com/leathekd/grapnel"))])
+ (grass-mode . [(20170503 1500) ((cl-lib (0 2)) (dash (2 8 0))) "Provides Emacs modes for interacting with the GRASS GIS program" single ((:commit . "8a7e9dcb2295eef1ec25d886b05e09c876bd8398") (:authors ("Tyler Smith" . "tyler@plantarum.ca")) (:maintainer "Tyler Smith" . "tyler@plantarum.ca") (:keywords "grass" "gis"))])
+ (grayscale-theme . [(20171005 802) nil "A simple grayscale theme" single ((:commit . "53ad50e10e68f2f076ebfc96e10ecef7a932d38d") (:authors ("Kaleb Elwert" . "belak@coded.io")) (:maintainer "Kaleb Elwert" . "belak@coded.io") (:keywords "lisp") (:url . "https://github.com/belak/emacs-grayscale-theme"))])
+ (greek-polytonic . [(20190303 1358) ((emacs (24))) "Quail package for inputting polytonic Greek" single ((:commit . "114cba0f57cc077871693c799b807df2292341ec") (:authors ("Johannes Choo" . "jhanschoo@gmail.com")) (:maintainer "Johannes Choo" . "jhanschoo@gmail.com") (:keywords "i18n" "multilingual" "input method" "greek") (:url . "https://github.com/jhanschoo/greek-polytonic"))])
+ (green-is-the-new-black-theme . [(20210203 1511) nil "A cool and minimalist green blackened theme engine" single ((:commit . "09f6908064dd1854379a072d7cdd706959256299") (:authors ("Fred Campos" . "fred.tecnologia@gmail.com")) (:maintainer "Fred Campos" . "fred.tecnologia@gmail.com") (:keywords "faces" "themes") (:url . "https://github.com/fredcamps/green-is-the-new-black-emacs"))])
+ (green-phosphor-theme . [(20150515 1447) nil "A light color theme with muted, autumnal colors." single ((:commit . "fa42f598626adfdc5450e5c380fa2d5df6110f28") (:authors ("Adam Alpern" . "adam.alpern@gmail.com")) (:maintainer "Adam Alpern" . "adam.alpern@gmail.com") (:keywords "color" "theme") (:url . "http://github.com/aalpern/emacs-color-theme-green-phosphor"))])
+ (green-screen-theme . [(20180816 1502) nil "A nice color theme for those who miss green CRTs" single ((:commit . "774e8f6c033786406267f71ec07319d906a30b75") (:authors ("Ricardo Banffy" . "rbanffy@gmail.com")) (:maintainer "Ricardo Banffy" . "rbanffy@gmail.com") (:keywords "faces" "theme") (:url . "https://github.com/rbanffy/green-screen-emacs"))])
+ (gregorio-mode . [(20170705 1451) nil "Gregorio Mode for .gabc files" single ((:commit . "736fd3d05fb67f707cca1a7ce24e3ee7ca5e9567") (:authors ("Fr. John Jenkins" . "jenkins@sspx.ng")) (:maintainer "Fr. John Jenkins" . "jenkins@sspx.ng") (:keywords "gregorio" "chant") (:url . "https://jsrjenkins.github.io/gregorio-mode/"))])
+ (grep-a-lot . [(20210618 1420) nil "manages multiple search results buffers for grep.el" single ((:commit . "223819dbea049bdeb5f97f9849fce139a5f16a75") (:authors ("Avi Rozen" . "avi.rozen@gmail.com")) (:maintainer "Avi Rozen" . "avi.rozen@gmail.com") (:keywords "tools" "convenience" "search") (:url . "https://github.com/ZungBang/emacs-grep-a-lot"))])
+ (greymatters-theme . [(20150621 1123) ((emacs (24))) "Emacs 24 theme with a light background." single ((:commit . "a7220a8c6cf18ccae2b76946b6f01188a7c9d5d1") (:authors ("Martin Haesler")) (:maintainer "Martin Haesler"))])
+ (grip-mode . [(20220430 1545) ((emacs (24 4))) "Instant GitHub-flavored Markdown/Org preview using grip." single ((:commit . "7fa9e9e6b650f7a6c026b7e24c2af171e8818667") (:authors ("Vincent Zhang" . "seagle0128@gmail.com")) (:maintainer "Vincent Zhang" . "seagle0128@gmail.com") (:keywords "convenience" "markdown" "preview") (:url . "https://github.com/seagle0128/grip-mode"))])
+ (grizzl . [(20160818 737) ((cl-lib (0 5)) (emacs (24 3))) "Fast fuzzy search index for Emacs." single ((:commit . "1e917253ce2b846f0272b8356fad3dbff9cd513a") (:authors ("Chris Corbyn" . "chris@w3style.co.uk")) (:maintainer "Bozhidar Batsov" . "bozhidar@batsov.com") (:keywords "convenience" "usability") (:url . "https://github.com/grizzl/grizzl"))])
+ (groovy-imports . [(20210505 1807) ((emacs (24 4)) (s (1 10 0)) (pcache (0 3 2))) "Code for dealing with Groovy imports" single ((:commit . "a60c3202973e3185091db623d960f71840a22205") (:authors ("Miro Bezjak")) (:maintainer "Miro Bezjak") (:keywords "groovy") (:url . "http://www.github.com/mbezjak/emacs-groovy-imports"))])
+ (groovy-mode . [(20220212 646) ((s (1 12 0)) (emacs (24 3)) (dash (2 13 0))) "Major mode for Groovy source files" tar ((:commit . "29210e5a969c02169b68e04f2e28e3bf2fc13363") (:authors ("Russel Winder" . "russel@winder.org.uk") ("Jim Morris" . "morris@wolfman.com") ("Wilfred Hughes" . "me@wilfred.me.uk")) (:maintainer "Russel Winder" . "russel@winder.org.uk") (:keywords "languages"))])
+ (gruber-darker-theme . [(20220107 1815) nil "Gruber Darker color theme for Emacs 24." single ((:commit . "72278089c440d45c00fb8afcd53af82fd30f451b") (:authors ("Alexey Kutepov" . "reximkut@gmail.com")) (:maintainer "Alexey Kutepov" . "reximkut@gmail.com") (:url . "http://github.com/rexim/gruber-darker-theme"))])
+ (grugru . [(20211119 815) ((emacs (24 4))) "Rotate text at point" tar ((:commit . "ac92a8d54efe000557564a9b01a426f34cc01dfa") (:authors ("ROCKTAKEY" . "rocktakey@gmail.com")) (:maintainer "ROCKTAKEY" . "rocktakey@gmail.com") (:keywords "convenience" "abbrev" "tools") (:url . "https://github.com/ROCKTAKEY/grugru"))])
+ (grunt . [(20160316 1528) ((dash (2 9 0)) (ansi-color (3 4 2)) (emacs (24 3))) "Some glue to stick Emacs and Gruntfiles together" single ((:commit . "4c269e2738658643ec2ed9ef61a2a3d71b08d304") (:authors ("Daniel Gempesaw" . "dgempesaw@sharecare.com")) (:maintainer "Daniel Gempesaw" . "dgempesaw@sharecare.com") (:keywords "convenience" "grunt") (:url . "https://github.com/gempesaw/grunt.el"))])
+ (gruvbox-theme . [(20220101 1208) ((autothemer (0 2))) "A retro-groove colour theme for Emacs" tar ((:commit . "921bfd7a2f5174b68682b04e6010b156bbfe6c70") (:authors ("Jason Milkins" . "jasonm23@gmail.com")) (:maintainer "Jason Milkins" . "jasonm23@gmail.com") (:url . "http://github.com/greduan/emacs-theme-gruvbox"))])
+ (gs-mode . [(20151202 1006) nil "Major mode for editing GrADS script files" single ((:commit . "1a13051db21b999c7682a015b33a03096ff9d891") (:authors ("Joe Wielgosz" . "joew@cola.iges.org")) (:maintainer "Joe Wielgosz" . "joew@cola.iges.org") (:keywords "grads" "script" "major-mode"))])
+ (gscholar-bibtex . [(20190130 555) nil "Retrieve BibTeX from Google Scholar and other online sources(ACM, IEEE, DBLP)" single ((:commit . "3b651e3de116860eb1f1aef9b547a561784871fe") (:authors ("Junpeng Qiu" . "qjpchmail@gmail.com")) (:maintainer "Junpeng Qiu" . "qjpchmail@gmail.com") (:keywords "extensions"))])
+ (gsettings . [(20210407 2045) ((emacs (24 3)) (dash (2 16 0)) (gvariant (1 0 0)) (s (1 12 0))) "GSettings (Gnome) helpers" single ((:commit . "9f9fb1fe946bbba46307c26355f355225ea7262a") (:authors ("wouter bolsterlee" . "wouter@bolsterl.ee")) (:maintainer "wouter bolsterlee" . "wouter@bolsterl.ee") (:keywords "languages") (:url . "https://github.com/wbolster/emacs-gsettings"))])
+ (gsnip . [(20220206 1526) ((emacs (26)) (aio (1 0)) (log4e (0 3 3))) "A gitlab snippet client" single ((:commit . "4d473b726b3f3b6bb7d1b5f66a9d368588ce0f86") (:authors ("Wang Kai" . "kaiwkx@gmail.com")) (:maintainer "Wang Kai" . "kaiwkx@gmail.com") (:keywords "extensions" "tools") (:url . "https://github.com/kaiwk/gitlab-snippet"))])
+ (gtk-pomodoro-indicator . [(20191007 1500) nil "A pomodoro indicator for the GTK tray" tar ((:commit . "338e6dca6d749cfc85195907bba593f9f6855715") (:authors ("Oleh Krehel" . "ohwoeowho@gmail.com")) (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com") (:keywords "convenience" "pomodoro") (:url . "https://github.com/abo-abo/gtk-pomodoro-indicator"))])
+ (gtk-variant . [(20200416 2136) ((emacs (25 1))) "Set the GTK theme variant (titlebar color)" single ((:commit . "e0653e4a654b7800dc15f7e1a06a956b77d2aabe") (:authors ("Paul Oppenheimer")) (:maintainer "Paul Oppenheimer") (:keywords "frames" "gtk" "titlebar") (:url . "https://github.com/bepvte/gtk-variant.el"))])
+ (guess-language . [(20220408 1545) ((cl-lib (0 5)) (emacs (24))) "Robust automatic language detection" tar ((:commit . "b1fc363ca2c30b8a8ddaf2e366bca7770c8cfbec") (:authors ("Titus von der Malsburg" . "malsburg@posteo.de")) (:maintainer "Titus von der Malsburg" . "malsburg@posteo.de") (:keywords "wp") (:url . "https://github.com/tmalsburg/guess-language.el"))])
+ (guide-key . [(20150108 635) ((dash (2 10 0)) (popwin (0 3 0)) (s (1 9 0))) "Guide the following key bindings automatically and dynamically" single ((:commit . "8f8b839f42edd53af13d588254f07727108ae312") (:authors ("Tsunenobu Kai" . "kai2nenobu@gmail.com")) (:maintainer "Tsunenobu Kai" . "kai2nenobu@gmail.com") (:keywords "help" "convenience") (:url . "https://github.com/kai2nenobu/guide-key"))])
+ (guide-key-tip . [(20161011 823) ((guide-key (1 2 3)) (pos-tip (0 4 5))) "Show guide-key.el hints using pos-tip.el" single ((:commit . "02c5d4b0b65f3e91be5a47f0ff1ae5e86e00c64e") (:authors ("Hiroaki Otsu" . "ootsuhiroaki@gmail.com")) (:maintainer "Hiroaki Otsu" . "ootsuhiroaki@gmail.com") (:keywords "help" "convenience" "tooltip") (:url . "https://github.com/aki2o/guide-key-tip"))])
+ (guix . [(20210608 1653) ((emacs (24 3)) (dash (2 11 0)) (geiser (0 8)) (bui (1 2 0)) (magit-popup (2 1 0)) (edit-indirect (0 1 4))) "Interface for GNU Guix" tar ((:commit . "c9aef52121b458297e70bb50f49f7276b4a8d759") (:authors ("Alex Kost" . "alezost@gmail.com")) (:maintainer "Alex Kost" . "alezost@gmail.com") (:keywords "tools") (:url . "https://emacs-guix.gitlab.io/website/"))])
+ (gulp-task-runner . [(20170718 2041) nil "Gulp task runner" single ((:commit . "877990e956b1d71e2d9c7c3e5a129ad199b9debb") (:authors ("Nicolas Petton" . "nicolas@petton.fr")) (:maintainer "Nicolas Petton" . "nicolas@petton.fr") (:keywords "convenience" "javascript"))])
+ (gumshoe . [(20211229 152) ((emacs (25 1))) "Scoped spatial and temporal POINT movement tracking" tar ((:commit . "2366f1c65cdcf09c6b98ca466110842cd88c9db3") (:authors ("overdr0ne")) (:maintainer "overdr0ne") (:keywords "tools") (:url . "https://github.com/Overdr0ne/gumshoe"))])
+ (guru-mode . [(20211025 1157) nil "Become an Emacs guru" single ((:commit . "a3370e547eab260d24774cd50ccbe865373c8631") (:authors ("Bozhidar Batsov" . "bozhidar@batsov.dev")) (:maintainer "Bozhidar Batsov" . "bozhidar@batsov.dev") (:keywords "convenience") (:url . "https://github.com/bbatsov/guru-mode"))])
+ (gvariant . [(20210507 1310) ((emacs (24)) (parsec (0 1 4))) "GVariant (GLib) helpers" single ((:commit . "f2e87076845800cbaaeed67f175ad4e4a9c01e37") (:authors ("wouter bolsterlee" . "wouter@bolsterl.ee")) (:maintainer "wouter bolsterlee" . "wouter@bolsterl.ee") (:keywords "languages") (:url . "https://github.com/wbolster/emacs-gvariant"))])
+ (gvpr-mode . [(20201007 2054) nil "A major mode offering basic syntax coloring for gvpr scripts." single ((:commit . "ef6ec2d4a4c9de68078c94a0e43b05bf77ec4674") (:authors ("Rod Waldhoff" . "r.waldhoff@gmail.com")) (:maintainer "Rod Waldhoff" . "r.waldhoff@gmail.com") (:keywords "graphviz" "gv" "dot" "gvpr" "graph") (:url . "https://raw.github.com/rodw/gvpr-lib/master/extra/gvpr-mode.el"))])
+ (gxref . [(20170411 1753) ((emacs (25))) "xref backend using GNU Global." single ((:commit . "380b02c3c3c2586c828456716eef6a6392bb043b") (:authors ("Dedi Hirschfeld")) (:maintainer "Dedi Hirschfeld") (:keywords "xref" "global" "tools") (:url . "https://github.com/dedi/gxref"))])
+ (habamax-theme . [(20181001 850) ((emacs (24))) "Boring white background color that gets the job done." single ((:commit . "6e86a1b23b6e2aaf40d4374b5673da00a28be447") (:authors ("Maxim Kim" . "habamax@gmail.com")) (:maintainer "Maxim Kim" . "habamax@gmail.com") (:url . "https://github.com/habamax/habamax-theme"))])
+ (habitica . [(20220215 1758) ((org (8 3 5)) (emacs (24 3))) "Interface for habitica.com" single ((:commit . "9e1fde7f359f7f6a6976b857fbbdbc8dd4fd3327") (:authors ("Adrien Brochard")) (:maintainer "Adrien Brochard") (:keywords "habitica" "todo") (:url . "https://github.com/abrochard/emacs-habitica"))])
+ (hack-mode . [(20211224 19) ((emacs (25 1)) (s (1 11 0))) "Major mode for the Hack programming language" single ((:commit . "a522f61c088ee2a13ab17f289a3131329e59badf") (:authors ("John Allen <jallen@fb.com>, Wilfred Hughes" . "me@wilfred.me.uk")) (:maintainer "John Allen <jallen@fb.com>, Wilfred Hughes" . "me@wilfred.me.uk") (:url . "https://github.com/hhvm/hack-mode"))])
+ (hacker-typer . [(20170206 1520) ((emacs (24))) "Pretend to write code like a pro" tar ((:commit . "d5a23714a4ccc5071580622f278597d5973f40bd") (:authors ("Diego A. Mundo" . "diegoamundo@gmail.com")) (:maintainer "Diego A. Mundo" . "diegoamundo@gmail.com") (:keywords "hacker" "typer" "multimedia" "games") (:url . "http://github.com/therockmandolinist/emacs-hacker-typer"))])
+ (hackernews . [(20210226 1226) nil "Hacker News Client for Emacs" single ((:commit . "ccfa75c0b3d67201cdf0f2324f311544ade498db") (:authors ("Lincoln de Sousa" . "lincoln@comum.org")) (:maintainer "Basil L. Contovounesios" . "contovob@tcd.ie") (:keywords "comm" "hypermedia" "news") (:url . "https://github.com/clarete/hackernews.el"))])
+ (hal-mode . [(20160704 1746) nil "Major mode for editing HAL files" single ((:commit . "cd2f66f219ee520198d4586fb6b169cef7ad3f21") (:authors ("Alexander Rössler")) (:maintainer "Alexander Rössler") (:keywords "language") (:url . "https://github.com/strahlex/hal-mode/"))])
+ (ham-mode . [(20150811 1306) ((html-to-markdown (1 2)) (markdown-mode (2 0))) "Html As Markdown. Transparently edit an html file using markdown" single ((:commit . "3a141986a21c2aa6eefb428983352abb8b7907d2") (:authors ("Artur Malabarba" . "bruce.connor.am@gmail.com")) (:maintainer "Artur Malabarba" . "bruce.connor.am@gmail.com") (:keywords "convenience" "emulation" "wp") (:url . "http://github.com/Bruce-Connor/ham-mode"))])
+ (hamburg-theme . [(20160123 740) ((emacs (24))) "Color Theme with a dark blue background." single ((:commit . "aacefdf1501d97a5afc0e63c8ead4b2463323028") (:authors ("Martin Haesler")) (:maintainer "Martin Haesler"))])
+ (hamburger-menu . [(20160825 2031) ((emacs (24 5))) "Mode line hamburger menu" single ((:commit . "3568159c693c30bed7f61580e4f3b6241253ad4e") (:authors ("Iain Nicol")) (:maintainer "Iain Nicol") (:keywords "hamburger" "menu") (:url . "https://gitlab.com/iain/hamburger-menu-mode"))])
+ (haml-mode . [(20190219 2102) ((emacs (24)) (cl-lib (0 5))) "Major mode for editing Haml files" single ((:commit . "bf5b6c11b1206759d2b28af48765e04882dd1fc4") (:authors ("Natalie Weizenbaum")) (:maintainer "Natalie Weizenbaum") (:keywords "markup" "languages" "html") (:url . "https://github.com/nex3/haml-mode"))])
+ (hamlet-mode . [(20131208 724) ((cl-lib (0 3)) (dash (2 3 0)) (s (1 7 0))) "Hamlet editing mode" single ((:commit . "7362b955e556a3d007fa06945a27e5b99349527d") (:authors (nil . "Kata <lightquake@amateurtopologist.com")) (:maintainer nil . "Kata <lightquake@amateurtopologist.com") (:keywords "wp" "languages" "comm") (:url . "https://github.com/lightquake/hamlet-mode"))])
+ (handle . [(20191029 856) ((emacs (25 1)) (parent-mode (2 3))) "A handle for major-mode generic functions." single ((:commit . "e27b2d0b229923f81a2c8afa3e9c65ae9e84a0da") (:authors ("Uros Perisic")) (:maintainer "Uros Perisic") (:keywords "convenience") (:url . "https://gitlab.com/jjzmajic/handle"))])
+ (handlebars-mode . [(20150211 1749) nil "A major mode for editing Handlebars files." single ((:commit . "81f6b73fea8f397807781a1b51568397af21a6ef") (:authors ("Tony Gentilcore") ("Chris Wanstrath") ("Daniel Hackney") ("Daniel Evans")) (:maintainer "Tony Gentilcore"))])
+ (handlebars-sgml-mode . [(20130623 2333) nil "Add Handlebars contextual indenting support to sgml-mode" single ((:commit . "c76df93a9a8c1b1b3efdcc4add32bf93304192a4") (:authors ("Geoff Jacobsen" . "geoffjacobsen@gmail.com")) (:maintainer "Geoff Jacobsen" . "geoffjacobsen@gmail.com") (:url . "http://github.com/jacott/handlebars-sgml-mode"))])
+ (handoff . [(20150917 600) nil "Get your hand off that mouse, damn it!" single ((:commit . "75dc7a7e352f38679f65d0ca80ad158798e168bd") (:authors ("Johan Andersson" . "johan.rejeep@gmail.com")) (:maintainer "Johan Andersson" . "johan.rejeep@gmail.com") (:url . "http://github.com/rejeep/handoff.el"))])
+ (hardcore-mode . [(20151114 701) nil "Disable arrow keys + optionally backspace and return" single ((:commit . "b1dda19692b4a7a58a689e81784a9b35be39e70d") (:authors ("Magnar Sveen" . "magnars@gmail.com")) (:maintainer "Magnar Sveen" . "magnars@gmail.com"))])
+ (hardhat . [(20210515 1422) ((emacs (24 3)) (ignoramus (0 7 0))) "Protect against clobbering user-writable files" single ((:commit . "908cb130be3d56921a3687a00b974ba5eef3a11f") (:authors ("Roland Walker" . "walker@pobox.com")) (:maintainer "Roland Walker" . "walker@pobox.com") (:keywords "convenience") (:url . "http://github.com/rolandwalker/hardhat"))])
+ (harpoon . [(20220402 446) ((emacs (27 2)) (f (0 20 0)) (hydra (0 14 0)) (project (0 8 1))) "Bookmarks on steroids" single ((:commit . "a23571eaab94fb2da0569ed5ab3c1b469f123b97") (:authors ("Otávio Schwanck" . "otavioschwanck@gmail.com")) (:maintainer "Otávio Schwanck" . "otavioschwanck@gmail.com") (:keywords "tools" "languages") (:url . "https://github.com/otavioschwanck/harpoon.el"))])
+ (harvest . [(20170822 1746) ((swiper (0 7 0)) (hydra (0 13 0)) (s (1 11 0))) "Harvest integration" single ((:commit . "7acbc0564b250521b67131ee2a0a92720239454f") (:authors ("Kosta Harlan" . "kosta@kostaharlan.net")) (:maintainer "Kosta Harlan" . "kosta@kostaharlan.net") (:keywords "harvest") (:url . "https://github.com/kostajh/harvest.el"))])
+ (haskell-emacs . [(20160904 2026) nil "Write emacs extensions in haskell" tar ((:commit . "a2c6a079175904689eed7c6c200754bfa85d1ed9") (:authors ("Florian Knupfer")) (:maintainer "Florian Knupfer") (:keywords "haskell" "emacs" "ffi") (:url . "https://github.com/knupfer/haskell-emacs"))])
+ (haskell-emacs-base . [(20150714 1559) ((haskell-emacs (2 4 0))) "Haskell functions from Prelude" tar ((:commit . "a2c6a079175904689eed7c6c200754bfa85d1ed9") (:authors ("Florian Knupfer")) (:maintainer "Florian Knupfer") (:keywords "haskell" "emacs" "ffi") (:url . "https://github.com/knupfer/haskell-emacs/modules/base"))])
+ (haskell-emacs-text . [(20150713 1416) ((haskell-emacs (2 4 0))) "Haskell functions from Data.Text" tar ((:commit . "a2c6a079175904689eed7c6c200754bfa85d1ed9") (:authors ("Florian Knupfer")) (:maintainer "Florian Knupfer") (:keywords "haskell" "emacs" "ffi") (:url . "https://github.com/knupfer/haskell-emacs/modules/text"))])
+ (haskell-mode . [(20220331 1645) ((emacs (25 1))) "A Haskell editing mode" tar ((:commit . "4ec2aa32b1772e629a6a2b47b84048e1990d6728") (:authors ("1992 Simon Marlow") ("1997-1998 Graeme E Moss" . "gem@cs.york.ac.uk") ("Tommy Thorn" . "thorn@irisa.fr") ("2001-2002 Reuben Thomas (>=v1.4)") ("2003 Dave Love" . "fx@gnu.org") ("2016 Arthur Fayzrakhmanov")) (:maintainer "1992 Simon Marlow") (:keywords "faces" "files" "haskell") (:url . "https://github.com/haskell/haskell-mode"))])
+ (haskell-snippets . [(20210228 344) ((cl-lib (0 5)) (yasnippet (0 8 0))) "Yasnippets for Haskell" tar ((:commit . "1c29c4a68ce89848b8d371c6510d1de3b586c8b3") (:authors ("Luke Hoersten" . "luke@hoersten.org")) (:maintainer "Luke Hoersten" . "luke@hoersten.org") (:keywords "snippets" "haskell") (:url . "https://github.com/haskell/haskell-snippets"))])
+ (haskell-tab-indent . [(20200513 1950) nil "tab-based indentation for haskell-mode" single ((:commit . "3239e814d6999f31ad845cc58df53395ad299059") (:authors ("Sean Whitton" . "spwhitton@spwhitton.name")) (:maintainer "Sean Whitton" . "spwhitton@spwhitton.name") (:keywords "indentation" "haskell") (:url . "https://spwhitton.name/tech/code/haskell-tab-indent/"))])
+ (hasklig-mode . [(20211017 1730) ((emacs (25))) "Hasklig ligatures" single ((:commit . "d708937592f9e2d28ae5622086b9c24d60cd8ac2") (:authors ("Daniel Mendler")) (:maintainer "Daniel Mendler") (:url . "https://github.com/minad/hasklig-mode"))])
+ (hass . [(20220402 1326) ((emacs (25 1)) (request (0 3 3))) "Interact with Home Assistant" tar ((:commit . "c6bded14ae4b68194bd9e35428e9973ca144569b") (:authors ("Ben Whitley")) (:maintainer "Ben Whitley") (:url . "https://github.com/purplg/hass"))])
+ (haste . [(20141030 2034) ((json (1 2))) "Emacs client for hastebin (http://hastebin.com/about.md)" single ((:commit . "22d05aacc3296ab50a7361222ab139fb4d447c25") (:authors ("Ric Lister")) (:maintainer "Ric Lister") (:url . "http://github.com/rlister/emacs-haste-client"))])
+ (haxe-imports . [(20170330 2304) ((emacs (24 4)) (s (1 10 0)) (pcache (0 3 1))) "Code for dealing with Haxe imports" single ((:commit . "f104a641f3dfe698359d9aca1f28d9383cf43e04") (:authors ("Juan Karlo Licudine" . "karlo@accidentalrebel.com")) (:maintainer "Juan Karlo Licudine" . "karlo@accidentalrebel.com") (:keywords "haxe") (:url . "http://www.github.com/accidentalrebel/emacs-haxe-imports"))])
+ (haxe-mode . [(20210108 1835) nil "Major mode for editing Haxe files" single ((:commit . "6641a0d7c00ce633887baf3f8c594d9a8a504e9b") (:authors ("Jens Peter Secher (original)")) (:maintainer "Jen-Chieh Shen" . "jcs090218@gmail.com") (:url . "https://github.com/emacsorphanage/haxe-mode"))])
+ (haxor-mode . [(20160618 1129) ((emacs (24 0))) "Major mode for editing Haxor Assembly Files" single ((:commit . "6fa25a8e6b6a59481bc0354c2fe1e0ed53cbdc91") (:authors ("Krzysztof Magosa" . "krzysztof@magosa.pl")) (:maintainer "Krzysztof Magosa" . "krzysztof@magosa.pl") (:keywords "haxor") (:url . "https://github.com/krzysztof-magosa/haxor-mode"))])
+ (hayoo . [(20140831 1221) ((emacs (24)) (json (1 3))) "Query hayoo and show results in a tabulated buffer." single ((:commit . "3ca2fb0c4d5f337d0410c21b2702dd147014e984") (:authors ("Marko Bencun" . "mbencun@gmail.com")) (:maintainer "Marko Bencun" . "mbencun@gmail.com") (:keywords "hayoo" "haskell") (:url . "https://github.com/benma/hayoo.el/"))])
+ (hc-zenburn-theme . [(20150928 1633) nil "An higher contrast version of the Zenburn theme." single ((:commit . "fd0024a5191cdce204d91c8f1db99ba31640f6e9") (:authors ("Nantas Nardelli" . "nantas.nardelli@gmail.com")) (:maintainer "Nantas Nardelli" . "nantas.nardelli@gmail.com") (:url . "https:github.com/edran/hc-zenburn-emacs"))])
+ (hcl-mode . [(20200315 2129) ((emacs (24 3))) "Major mode for Hashicorp" single ((:commit . "e4d9eef631e8a386341ae8f94f7c2579586e65b5") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:url . "https://github.com/purcell/emacs-hcl-mode"))])
+ (headlong . [(20150417 1526) nil "reckless completion" single ((:commit . "f6830f87f236eee88263cb6976125f72422abe72") (:authors ("Oleh Krehel" . "ohwoeowho@gmail.com")) (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com") (:keywords "completion") (:url . "https://github.com/abo-abo/headlong"))])
+ (heaven-and-hell . [(20190713 1830) ((emacs (24 4))) "easy toggle light/dark themes" single ((:commit . "e1febfd60d060c110a1e43c5f093cd8537251308") (:authors ("Valentin Ignatev" . "valentignatev@gmail.com")) (:maintainer "Valentin Ignatev" . "valentignatev@gmail.com") (:keywords "faces") (:url . "https://github.com/valignatev/heaven-and-hell"))])
+ (helm . [(20220504 827) ((helm-core (3 8 4)) (popup (0 5 3))) "Helm is an Emacs incremental and narrowing framework" tar ((:commit . "a23bf2fa7b5553d2a3a8d61efa504416f876ec20") (:authors ("Thierry Volpiatto" . "thierry.volpiatto@gmail.com")) (:maintainer "Thierry Volpiatto" . "thierry.volpiatto@gmail.com") (:url . "https://emacs-helm.github.io/helm/"))])
+ (helm-R . [(20120820 14) ((helm (20120517)) (ess (20120509))) "helm-sources and some utilities for GNU R." single ((:commit . "b0eb9d5f6a483a9dbe6eb6cf1f2024d4f5938bc2") (:authors ("myuhe <yuhei.maeda_at_gmail.com>")) (:maintainer "myuhe") (:keywords "convenience") (:url . "https://github.com/myuhe/helm-R.el"))])
+ (helm-ack . [(20141030 1226) ((helm (1 0)) (cl-lib (0 5))) "Ack command with helm interface" single ((:commit . "889bc225318d14c6e3be80e73b1d9d6fb30e48c3") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-helm-ack"))])
+ (helm-ad . [(20151209 1015) ((dash (2 8 0)) (helm (1 6 2))) "helm source for Active Directory" single ((:commit . "8ac044705d8620ee354a9cfa8cc1b865e83c0d55") (:authors ("Takahiro Noda" . "takahiro.noda+github@gmail.com")) (:maintainer "Takahiro Noda" . "takahiro.noda+github@gmail.com") (:keywords "comm"))])
+ (helm-ag . [(20210702 845) ((emacs (25 1)) (helm (2 0))) "The silver searcher with helm interface" single ((:commit . "9820ba1893c8a7e31e756c891f9b4cf0eff1e50b") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-helm-ag"))])
+ (helm-ag-r . [(20131123 1531) ((helm (1 0))) "Search something by ag and display by helm" single ((:commit . "67de4ebafe9b088db950eefa5ef590a6d78b4ac8") (:authors ("Yuta Yamada <cokesboy\"at\"gmail.com>")) (:maintainer "Yuta Yamada <cokesboy\"at\"gmail.com>") (:keywords "searching") (:url . "https://github.com/yuutayamada/helm-ag-r"))])
+ (helm-apt . [(20210324 1929) ((helm (3 6)) (emacs (25 1))) "Helm interface for Debian/Ubuntu packages (apt-*)" single ((:commit . "c952b5dc26015bc9c947973df99246212d276b63") (:authors ("Thierry Volpiatto" . "thierry.volpiatto@gmail.com")) (:maintainer "Thierry Volpiatto" . "thierry.volpiatto@gmail.com") (:url . "https://github.com/emacs-helm/helm-apt"))])
+ (helm-atoms . [(20201013 1723) ((emacs (25 1)) (helm (2 0))) "Reverse variable lookup using Helm" single ((:commit . "7e6f91a16f556c96ae1b0d1f965ea56861bb6372") (:authors ("Dante Catalfamo")) (:maintainer "Dante Catalfamo") (:keywords "help" "lisp" "maint" "helm" "tools" "matching") (:url . "https://github.com/dantecatalfamo/helm-atoms"))])
+ (helm-aws . [(20180514 1032) ((helm (1 5 3)) (cl-lib (0 5)) (s (1 9 0))) "Manage AWS EC2 server instances directly from Emacs" single ((:commit . "b36c744b3f00f458635a91d1f5158fccbb5baef6") (:authors ("istib")) (:maintainer "istib") (:url . "https://github.com/istib/helm-aws"))])
+ (helm-backup . [(20180911 614) ((helm (1 5 5)) (s (1 8 0)) (cl-lib (0))) "Backup each file change using git" single ((:commit . "691fe542f38fc7c8cca409997f6a0ff5d76ad6c2") (:authors ("Anthony HAMON" . "hamon.anth@gmail.com")) (:maintainer "Anthony HAMON" . "hamon.anth@gmail.com") (:keywords "backup" "convenience" "files" "tools" "vc") (:url . "http://github.com/antham/helm-backup"))])
+ (helm-bbdb . [(20190728 1325) ((emacs (24 3)) (helm (1 5)) (bbdb (3 1 2))) "Helm interface for bbdb" single ((:commit . "db69114ff1af8bf48b5a222242e3a8dd6e101e67") (:url . "https://github.com/emacs-helm/helm-bbdb"))])
+ (helm-bibtex . [(20210725 1510) ((bibtex-completion (1 0 0)) (helm (1 5 5)) (cl-lib (0 5)) (emacs (24 1))) "A bibliography manager based on Helm" single ((:commit . "ce8c17690ddad73d01531084b282f221f8eb6669") (:authors ("Titus von der Malsburg" . "malsburg@posteo.de")) (:maintainer "Titus von der Malsburg" . "malsburg@posteo.de") (:url . "https://github.com/tmalsburg/helm-bibtex"))])
+ (helm-bibtexkey . [(20140214 1504) ((helm (1 5 8))) "Bibtexkey source for helm" tar ((:commit . "aa1637ea5c8c5f1817e480fc2a3750cafab3d99f") (:authors ("TAKAGI Kentaro <kentaro0910_at_gmail.com>")) (:maintainer "TAKAGI Kentaro <kentaro0910_at_gmail.com>") (:keywords "bib" "tex") (:url . "https://github.com/kenbeese/helm-bibtexkey"))])
+ (helm-bind-key . [(20141109 515) ((bind-key (1 0)) (helm (1 6 4))) "helm-source for for bind-key." single ((:commit . "9da6ad8b7530e72fb4ac67be8c6a482898dddc25") (:authors ("Yuhei Maeda <yuhei.maeda_at_gmail.com>")) (:maintainer "myuhe") (:keywords "convenience" "emulation"))])
+ (helm-bitbucket . [(20190422 1102) ((emacs (24)) (helm-core (3 0))) "Search Bitbucket with Helm" single ((:commit . "c722016622ad019202419cca60c3be3c53e56130") (:authors ("Peter Urbak" . "tolowercase@gmail.com")) (:maintainer "Peter Urbak" . "tolowercase@gmail.com") (:keywords "matching") (:url . "https://github.com/dragonwasrobot/helm-bitbucket"))])
+ (helm-bm . [(20160321 1331) ((bm (1 0)) (cl-lib (0 5)) (helm (1 9 3)) (s (1 11 0))) "helm sources for bm.el" single ((:commit . "d66341f5646c23178d4d8bffb6cfebe3fb73f1d7") (:authors ("Yasuyuki Oka" . "yasuyk@gmail.com")) (:maintainer "Yasuyuki Oka" . "yasuyk@gmail.com") (:keywords "helm" "bookmark") (:url . "https://github.com/yasuyk/helm-bm"))])
+ (helm-books . [(20170325 631) ((helm (1 7 7))) "Helm interface for searching books" single ((:commit . "625aadec1541a5ca36951e4ce1301f4b6fe2bf3f") (:authors ("grugrut" . "grugruglut+github@gmail.com")) (:maintainer "grugrut" . "grugruglut+github@gmail.com") (:url . "https://github.com/grugrut/helm-books"))])
+ (helm-bufler . [(20210708 2217) ((emacs (26 3)) (bufler (0 2 -1)) (helm (1 9 4))) "Helm source for Bufler" single ((:commit . "a68e0eb2719c67ab8a3ad56c4036364061d06004") (:authors ("Adam Porter" . "adam@alphapapa.net")) (:maintainer "Adam Porter" . "adam@alphapapa.net") (:keywords "convenience") (:url . "https://github.com/alphapapa/bufler.el"))])
+ (helm-bundle-show . [(20190526 1401) ((emacs (24)) (helm (1 8 0))) "Bundle show with helm interface" single ((:commit . "70f1ca7d1847c7d5cd5a3e488562cd4a295b809f") (:authors ("Takashi Masuda" . "masutaka.net@gmail.com")) (:maintainer "Takashi Masuda" . "masutaka.net@gmail.com") (:url . "https://github.com/masutaka/emacs-helm-bundle-show"))])
+ (helm-c-moccur . [(20151230 924) ((helm (20120811)) (color-moccur (2 71))) "helm source for color-moccur.el" single ((:commit . "b0a906f85fa352db091f88b91a9c510de607dfe9") (:authors ("Kenji.I (Kenji Imakado)" . "ken.imakaado@gmail.com")) (:maintainer "Kenji.I (Kenji Imakado)" . "ken.imakaado@gmail.com") (:keywords "convenience" "emulation"))])
+ (helm-c-yasnippet . [(20210330 16) ((emacs (25 1)) (helm (1 7 7)) (yasnippet (0 8 0))) "helm source for yasnippet.el" single ((:commit . "e214eec8b2875d8a7cd09006dfb6a8e15e9e4079") (:authors ("Kenji.I (Kenji Imakado)" . "ken.imakaado@gmail.com")) (:maintainer "Kenji.I (Kenji Imakado)" . "ken.imakaado@gmail.com") (:keywords "convenience" "emulation"))])
+ (helm-catkin . [(20190425 1520) ((emacs (24 3)) (helm (0)) (xterm-color (0))) "Package for compile ROS workspaces with catkin-tools" single ((:commit . "d33c71cecd35616dfa7c3b81d8f51c128405977f") (:authors ("Thore Goll" . "thoregoll@googlemail.com")) (:maintainer "Thore Goll" . "thoregoll@googlemail.com") (:keywords "catkin" "helm" "build" "tools" "ros") (:url . "https://github.com/gollth/helm-catkin"))])
+ (helm-charinfo . [(20170810 1231) ((emacs (24)) (helm (1 7 0)) (cl-lib (0 5))) "A helm source for character information" single ((:commit . "91798a49dc115342a7e01e48b264e9a0bf5ea414") (:authors ("Christian Wittern" . "cwittern@gmail.com")) (:maintainer "Christian Wittern" . "cwittern@gmail.com") (:keywords "convenience") (:url . "https://github.com/cwittern/helm-charinfo"))])
+ (helm-chrome . [(20160719 520) ((helm (1 5)) (cl-lib (0 3)) (emacs (24))) "Helm interface for Chrome bookmarks" single ((:commit . "fd630ace4b4b4f33355a973743bbfe0c90ce4830") (:authors ("KAWABATA, Taichi <kawabata.taichi_at_gmail.com>")) (:maintainer "KAWABATA, Taichi <kawabata.taichi_at_gmail.com>") (:keywords "tools") (:url . "https://github.com/kawabata/helm-chrome"))])
+ (helm-chrome-control . [(20190707 1807) ((emacs (25 1)) (helm-core (3 0))) "Control Chrome tabs with Helm (macOS only)" tar ((:commit . "e6758763099959e961e218bb1122526323f7ee5e") (:authors ("Xu Chunyang")) (:maintainer "Xu Chunyang") (:url . "https://github.com/xuchunyang/helm-chrome-control"))])
+ (helm-chrome-history . [(20191031 1233) ((emacs (25 1)) (helm-core (3 0))) "Browse Chrome History with Helm" single ((:commit . "f9002d4c12df65a99830376b126dbbeae3ef2148") (:authors ("Xu Chunyang" . "mail@xuchunyang.me")) (:maintainer "Xu Chunyang" . "mail@xuchunyang.me") (:keywords "tools") (:url . "https://github.com/xuchunyang/helm-chrome-history"))])
+ (helm-chronos . [(20150528 2036) ((chronos (1 2)) (helm (1 7 1))) "helm interface for chronos timers" tar ((:commit . "a14fc3d65dd96ce6616234b3f7b8b08b4c1817ef") (:authors ("David Knight" . "dxknight@opmbx.org")) (:maintainer "David Knight" . "dxknight@opmbx.org") (:keywords "calendar") (:url . "http://github.com/dxknight/helm-chronos"))])
+ (helm-cider . [(20220102 1626) ((emacs (26)) (cider (1 0)) (helm-core (2 8))) "Helm interface to CIDER" tar ((:commit . "00809e45de919c82753f332f29358f0ddbf21936") (:authors ("Tianxiang Xiong" . "tianxiang.xiong@gmail.com")) (:maintainer "Tianxiang Xiong" . "tianxiang.xiong@gmail.com") (:keywords "cider" "clojure" "helm" "languages") (:url . "https://github.com/clojure-emacs/helm-cider"))])
+ (helm-cider-history . [(20150719 2120) ((helm (1 4 0)) (cider (0 9 0))) "Helm interface for cider history" single ((:commit . "c391fcb2e162a02001605a0b9449783575a831fd") (:authors ("Andreas Klein" . "git@kungi.org")) (:maintainer "Andreas Klein" . "git@kungi.org") (:keywords "convenience") (:url . "https://github.com/Kungi/helm-cider-history"))])
+ (helm-circe . [(20160207 652) ((emacs (24)) (helm (0 0)) (circe (0 0)) (cl-lib (0 5))) "helm circe buffer management." single ((:commit . "9091651d9fdd8d49d8ff6f9dcf3a2ae416c9f15a") (:authors ("Les Harris" . "les@lesharris.com")) (:maintainer "Les Harris" . "les@lesharris.com") (:keywords "helm" "circe") (:url . "https://github.com/lesharris/helm-circe"))])
+ (helm-clojuredocs . [(20160405 723) ((edn (1 1 2)) (helm (1 5 7))) "search for help in clojuredocs.org" single ((:commit . "5a7f0f2cb401be0b09e73262a1c18265ab9a3cea") (:authors ("Michal Buczko" . "michal.buczko@gmail.com")) (:maintainer "Michal Buczko" . "michal.buczko@gmail.com") (:keywords "helm" "clojure") (:url . "https://github.com/mbuczko/helm-clojuredocs"))])
+ (helm-cmd-t . [(20170125 1459) nil "cmd-t style completion" tar ((:commit . "7fa3d4a9f7271512e54c5de999079b27c9eec6bf") (:authors ("Le Wang")) (:maintainer "Le Wang") (:keywords "helm" "project-management" "completion" "convenience" "cmd-t" "textmate") (:url . "https://github.com/lewang/helm-cmd-t"))])
+ (helm-codesearch . [(20190412 1153) ((emacs (25 1)) (s (1 11 0)) (dash (2 12 0)) (helm (1 7 7)) (cl-lib (0 5))) "helm interface for codesearch" single ((:commit . "72f1d1de746115ab7e861178b49fa3c0b6b58d90") (:authors ("Youngjoo Lee" . "youngker@gmail.com")) (:maintainer "Youngjoo Lee" . "youngker@gmail.com") (:keywords "tools"))])
+ (helm-commandlinefu . [(20150611 545) ((emacs (24 1)) (helm (1 7 0)) (json (1 3)) (let-alist (1 0 3))) "Search and browse commandlinefu.com from helm" single ((:commit . "9ee7e018c5db23ae9c8d1c8fa969876f15b7280d") (:authors ("Chunyang Xu" . "xuchunyang56@gmail.com")) (:maintainer "Chunyang Xu" . "xuchunyang56@gmail.com") (:keywords "commandlinefu.com") (:url . "https://github.com/xuchunyang/helm-commandlinefu"))])
+ (helm-company . [(20190812 1429) ((helm (1 5 9)) (company (0 6 13))) "Helm interface for company-mode" single ((:commit . "6eb5c2d730a60e394e005b47c1db018697094dde") (:authors ("Yasuyuki Oka" . "yasuyk@gmail.com")) (:maintainer "Daniel Ralston" . "Sodel-the-Vociferous@users.noreply.github.com") (:url . "https://github.com/Sodel-the-Vociferous/helm-company"))])
+ (helm-core . [(20220503 622) ((emacs (25 1)) (async (1 9 4))) "Development files for Helm" tar ((:commit . "a23bf2fa7b5553d2a3a8d61efa504416f876ec20") (:authors ("Thierry Volpiatto" . "thierry.volpiatto@gmail.com")) (:maintainer "Thierry Volpiatto" . "thierry.volpiatto@gmail.com") (:url . "https://emacs-helm.github.io/helm/"))])
+ (helm-cscope . [(20190615 41) ((xcscope (1 0)) (helm (1 6 7)) (cl-lib (0 5)) (emacs (24 1))) "Helm interface for xcscope.el." single ((:commit . "af1d9e7f4460a88d7400b5a74d5da68084089ac1") (:authors ("alpha22jp" . "alpha22jp@gmail.com")) (:maintainer "alpha22jp" . "alpha22jp@gmail.com") (:keywords "cscope" "helm") (:url . "https://github.com/alpha22jp/helm-cscope.el"))])
+ (helm-css-scss . [(20191230 1549) ((emacs (24 3)) (helm (1 0))) "CSS/SCSS/LESS Selectors with helm interface" single ((:commit . "48b996f73af1fef8d6e88a1c545d98f8c50b0cf3") (:authors ("Shingo Fukuyama - http://fukuyama.co")) (:maintainer "Shingo Fukuyama - http://fukuyama.co") (:keywords "convenience" "scss" "css" "less" "selector" "helm") (:url . "https://github.com/ShingoFukuyama/helm-css-scss"))])
+ (helm-ctest . [(20191031 1435) ((s (1 9 0)) (dash (2 11 0)) (helm-core (1 7 4))) "Run ctest from within emacs" single ((:commit . "2a29cfb4ec583da247fa2ae7bac88790b1223e40") (:authors ("Dan LaManna" . "me@danlamanna.com")) (:maintainer "Dan LaManna" . "me@danlamanna.com") (:keywords "helm" "ctest"))])
+ (helm-dash . [(20190527 1118) ((emacs (24 4)) (dash-docs (1 4 0)) (helm (1 9 2)) (cl-lib (0 5))) "Offline documentation browser for +150 APIs using Dash docsets." single ((:commit . "7f853bd34da666f0e9a883011c80f451b06f6c59") (:authors ("Raimon Grau" . "raimonster@gmail.com") ("Toni Reina " . "areina0@gmail.com") ("Bryan Gilbert" . "bryan@bryan.sh")) (:maintainer "Raimon Grau" . "raimonster@gmail.com") (:keywords "docs") (:url . "https://github.com/dash-docs-el/helm-dash"))])
+ (helm-descbinds . [(20190501 935) ((helm (1 5))) "A convenient `describe-bindings' with `helm'" single ((:commit . "b72515982396b6e336ad7beb6767e95a80fca192") (:authors ("Taiki SUGAWARA" . "buzz.taiki@gmail.com")) (:maintainer "Taiki SUGAWARA" . "buzz.taiki@gmail.com") (:keywords "helm" "help") (:url . "https://github.com/emacs-helm/helm-descbinds"))])
+ (helm-describe-modes . [(20160212 518) ((helm (1 9)) (cl-lib (0 5)) (emacs (24 1))) "Helm interface to major and minor modes." single ((:commit . "11fb36af119b784539d31c6160002de1957408aa") (:authors ("Tianxiang Xiong" . "tianxiang.xiong@gmail.com")) (:maintainer "Tianxiang Xiong" . "tianxiang.xiong@gmail.com") (:keywords "docs" "convenience") (:url . "https://github.com/emacs-helm/helm-describe-modes"))])
+ (helm-dictionary . [(20220319 955) ((helm (1 5 5))) "Helm source for looking up dictionaries" single ((:commit . "69f1e5bf03d67c9e5cb0065e702e8c311ac9d3db") (:authors ("Titus von der Malsburg" . "malsburg@posteo.de") ("Michael Heerdegen" . "michael_heerdegen@web.de")) (:maintainer "Titus von der Malsburg" . "malsburg@posteo.de") (:url . "https://github.com/emacs-helm/helm-dictionary"))])
+ (helm-directory . [(20170706 402) ((emacs (24 4)) (helm (2 0))) "selecting directory before select the file" single ((:commit . "51bd7cd6e40a84a7efda894283ec76a0107830ad") (:authors ("Masashı Mıyaura")) (:maintainer "Masashı Mıyaura") (:url . "https://github.com/masasam/emacs-helm-directory"))])
+ (helm-dired-history . [(20170524 1046) ((helm (1 9 8)) (cl-lib (0 5))) "Show dired history with helm.el support." single ((:commit . "06654656d3ad502742056d9030dd59e0da984764") (:authors ("Joseph(纪秀峰)" . "jixiuf@gmail.com")) (:maintainer "Joseph(纪秀峰)" . "jixiuf@gmail.com") (:keywords "helm" "dired history") (:url . "https://github.com/jixiuf/helm-dired-history"))])
+ (helm-dired-recent-dirs . [(20131228 1414) ((helm (1 0))) "Show recent dirs with helm.el support." single ((:commit . "3bcd125b44f5a707588ae3868777d91192351523") (:authors ("Akisute" . "akisute3@gmail.com")) (:maintainer "Akisute" . "akisute3@gmail.com") (:keywords "helm" "dired" "zsh"))])
+ (helm-dirset . [(20151209 12) ((f (0 16 2)) (helm (1 6 1)) (s (1 9 0)) (cl-lib (0 5))) "helm sources for multi directories" single ((:commit . "eb30810cd26e1ee73d84a863e6b2667700e9aead") (:authors ("k1LoW (Kenichirou Oyama), <k1lowxb [at] gmail [dot] com> <k1low [at] 101000lab [dot] org>")) (:maintainer "k1LoW (Kenichirou Oyama), <k1lowxb [at] gmail [dot] com> <k1low [at] 101000lab [dot] org>") (:keywords "files" "directories") (:url . "http://101000lab.org"))])
+ (helm-dogears . [(20210822 2106) ((emacs (26 3)) (dogears (0 1 -1)) (helm (3 6))) "Helm source for Dogears" single ((:commit . "c05b69e504a538c9e00fbb0ea86934fafe191d0c") (:authors ("Adam Porter" . "adam@alphapapa.net")) (:maintainer "Adam Porter" . "adam@alphapapa.net") (:keywords "convenience") (:url . "https://github.com/alphapapa/dogears.el"))])
+ (helm-emmet . [(20160713 1231) ((helm (1 0)) (emmet-mode (1 0 2))) "helm sources for emmet-mode's snippets" single ((:commit . "f0364e736b10cf44232053a78de04133a88185ae") (:authors ("Yasuyuki Oka" . "yasuyk@gmail.com")) (:maintainer "Yasuyuki Oka" . "yasuyk@gmail.com") (:keywords "convenience" "helm" "emmet") (:url . "https://github.com/yasuyk/helm-emmet"))])
+ (helm-emms . [(20220314 1633) ((helm (1 5)) (emms (6 0)) (cl-lib (0 5)) (emacs (24 1))) "Emms for Helm." single ((:commit . "aefa44ab77808626c4951be2df49a2eab7820805") (:authors ("Thierry Volpiatto" . "thierry.volpiatto@gmail.com")) (:maintainer "Thierry Volpiatto" . "thierry.volpiatto@gmail.com") (:keywords "multimedia" "emms") (:url . "https://github.com/emacs-helm/helm-emms"))])
+ (helm-esa . [(20190721 1429) ((emacs (26 2)) (helm (3 2)) (request (0 3 0))) "Esa with helm interface" single ((:commit . "d93b4af404346870cb2cf9c257d055332ef3f577") (:authors ("Takashi Masuda" . "masutaka.net@gmail.com")) (:maintainer "Takashi Masuda" . "masutaka.net@gmail.com") (:url . "https://github.com/masutaka/emacs-helm-esa"))])
+ (helm-etags-plus . [(20201003 1424) ((helm (1 7 8))) "Another Etags helm.el interface" single ((:commit . "52598fe69636add4b62cd9873041de5c6db9b7ac") (:authors ("纪秀峰(Joseph)" . "jixiuf@gmail.com")) (:maintainer "纪秀峰(Joseph)" . "jixiuf@gmail.com") (:keywords "helm" "etags") (:url . "https://github.com/jixiuf/helm-etags-plus"))])
+ (helm-evil-markers . [(20200506 715) ((emacs (25 1)) (helm (2 0 0)) (evil (1 2 10))) "Show evil markers with helm" single ((:commit . "0245f0c268e0eaec85df51ab2deba7ac961f6770") (:authors ("Bill Xue")) (:maintainer "Bill Xue") (:keywords "extensions") (:url . "https://github.com/xueeinstein/helm-evil-markers"))])
+ (helm-eww . [(20190315 907) ((emacs (24 4)) (helm (2 8 6)) (seq (1 8))) "Helm UI wrapper for EWW." single ((:commit . "76ba59fda8dd6f32a1bc7c6df0b43c6f76169911") (:authors ("Pierre Neidhardt" . "mail@ambrevar.xyz")) (:maintainer "Pierre Neidhardt" . "mail@ambrevar.xyz") (:keywords "helm" "packages") (:url . "https://github.com/emacs-helm/helm-eww"))])
+ (helm-ext . [(20200722 107) ((emacs (24 4)) (helm (2 5 3))) "A few extensions to Helm" tar ((:commit . "c30f7772ec577a5ce1de3215f0507826e0725a69") (:authors ("Junpeng Qiu" . "qjpchmail@gmail.com")) (:maintainer "Junpeng Qiu" . "qjpchmail@gmail.com") (:keywords "extensions"))])
+ (helm-exwm . [(20210215 858) ((emacs (25 2)) (helm (2 8 5)) (exwm (0 15))) "Helm for EXWM buffers" single ((:commit . "5b35a42ff10fbcbf673268987df700ea6b6288e8") (:authors ("Pierre Neidhardt" . "mail@ambrevar.xyz")) (:maintainer "Pierre Neidhardt" . "mail@ambrevar.xyz") (:keywords "helm" "exwm") (:url . "https://github.com/emacs-helm/helm-exwm"))])
+ (helm-file-preview . [(20200927 528) ((emacs (25 1)) (helm (2 0))) "Preview the current helm file selection" single ((:commit . "f9ffd81c3b7fa3e5f79f511a6c2226b5e99b73e6") (:authors ("Shen, Jen-Chieh" . "jcs090218@gmail.com")) (:maintainer "Shen, Jen-Chieh" . "jcs090218@gmail.com") (:url . "https://github.com/jcs-elpa/helm-file-preview"))])
+ (helm-filesets . [(20140929 1835) ((helm (1 6 3)) (filesets+ (0))) "A helm source for emacs filesets" single ((:commit . "b352910af4c3099267a8aa0169c7f743b35bb1fa") (:authors ("Graham Clark" . "grclark@gmail.com")) (:maintainer "Graham Clark" . "grclark@gmail.com") (:keywords "filesets") (:url . "https://github.com/gcla/helm-filesets"))])
+ (helm-firefox . [(20220420 1346) ((helm (1 5)) (cl-lib (0 5)) (emacs (24 1))) "Firefox bookmarks" single ((:commit . "571cf8dfcbe43d91f9890eebefc88d7572c62e75") (:url . "https://github.com/emacs-helm/helm-firefox"))])
+ (helm-fish-completion . [(20200908 1504) ((emacs (25)) (helm (3)) (fish-completion (1 2))) "Helm interface for fish completion" single ((:commit . "2a2001b3a876da3c468ffec8935572509c485aac") (:authors ("Pierre Neidhardt" . "mail@ambrevar.xyz")) (:maintainer "Pierre Neidhardt" . "mail@ambrevar.xyz") (:url . "https://github.com/emacs-helm/helm-fish-completion"))])
+ (helm-flx . [(20220402 21) ((emacs (24 4)) (helm (1 7 9)) (flx (0 5))) "Sort helm candidates by flx score" single ((:commit . "27dd9e3ce385a3ca15092150e65781de14b5b00b") (:authors ("Jonathan Hayase" . "jonathan.hayase@gmail.com")) (:maintainer "Jonathan Hayase" . "jonathan.hayase@gmail.com") (:keywords "convenience" "helm" "fuzzy" "flx") (:url . "https://github.com/PythonNut/helm-flx"))])
+ (helm-flycheck . [(20160710 829) ((dash (2 12 1)) (flycheck (28)) (helm-core (1 9 8))) "Show flycheck errors with helm" single ((:commit . "3cf7d3bb194acacc6395f88360588013d92675d6") (:authors ("Yasuyuki Oka" . "yasuyk@gmail.com")) (:maintainer "Yasuyuki Oka" . "yasuyk@gmail.com") (:keywords "helm" "flycheck") (:url . "https://github.com/yasuyk/helm-flycheck"))])
+ (helm-flymake . [(20160610 2) ((helm (1 0))) "helm interface for flymake" single ((:commit . "72cf18a1a1f843db9bb5d58301739ea9ccb1655b") (:authors ("Akira Tamamori" . "tamamori5917@gmail.com")) (:maintainer "Akira Tamamori" . "tamamori5917@gmail.com") (:url . "https://github.com/tam17aki"))])
+ (helm-flyspell . [(20170210 1901) ((helm (1 6 5))) "Helm extension for correcting words with flyspell" single ((:commit . "8d4d947c687cb650cb149aa2271ad5201ea92594") (:authors ("Andrzej Pronobis")) (:maintainer "Andrzej Pronobis") (:keywords "convenience") (:url . "https://github.com/pronobis/helm-flyspell"))])
+ (helm-frame . [(20180604 1005) ((emacs (24 4))) "open helm buffers in a dedicated frame" single ((:commit . "485e2a534b0de5e8dbeb144a9a60ceca00215a4a") (:authors ("chee" . "chee@snake.dog")) (:maintainer "chee" . "chee@snake.dog") (:keywords "lisp" "helm" "popup" "frame"))])
+ (helm-fuz . [(20200812 1222) ((emacs (25 1)) (fuz (1 4 0)) (helm (3 6))) "Integrate Helm and Fuz" single ((:commit . "fee874aa35d2ee6b12b836290b5c8eaa44175a28") (:authors ("Zhu Zihao" . "all_but_last@163.com")) (:maintainer "Zhu Zihao" . "all_but_last@163.com") (:keywords "convenience") (:url . "https://github.com/cireu/fuz.el"))])
+ (helm-fuzzier . [(20160605 2145) ((emacs (24 3)) (helm (1 7 0))) "Better fuzzy matching for Helm" single ((:commit . "8798dcf3583b863df5b9dea7fe3b0179ba1c35bc") (:authors ("Ephram Perdition")) (:maintainer "Ephram Perdition") (:keywords "convenience" "helm" "fuzzy") (:url . "http://github.com/EphramPerdition/helm-fuzzier"))])
+ (helm-fuzzy . [(20200927 532) ((emacs (24 4)) (helm (1 7 9)) (flx (0 5))) "Fuzzy matching for helm source" single ((:commit . "dd092e8eea5257d49bbdf694df4fefd86252e54b") (:authors ("Shen, Jen-Chieh" . "jcs090218@gmail.com")) (:maintainer "Shen, Jen-Chieh" . "jcs090218@gmail.com") (:url . "https://github.com/jcs-elpa/helm-fuzzy"))])
+ (helm-fuzzy-find . [(20171106 400) ((emacs (24 1)) (helm (1 7 0))) "Find file using Fuzzy Search" single ((:commit . "de2abbf7ca13609587325bacd4a1ed4376b5c927") (:authors ("Chunyang Xu" . "xuchunyang56@gmail.com")) (:maintainer "Chunyang Xu" . "xuchunyang56@gmail.com") (:keywords "helm" "fuzzy" "find" "file") (:url . "https://github.com/xuchunyang/helm-fuzzy-find"))])
+ (helm-ghq . [(20210724 744) ((emacs (24)) (helm (3 8 0))) "Ghq with helm interface" single ((:commit . "7b47ac91e42762f2ecbbceeaadc05b86c9fe5f14") (:authors ("Takashi Masuda" . "masutaka.net@gmail.com")) (:maintainer "Takashi Masuda" . "masutaka.net@gmail.com") (:url . "https://github.com/masutaka/emacs-helm-ghq"))])
+ (helm-ghs . [(20170715 541) ((emacs (24)) (helm (2 2 0))) "ghs with helm interface" single ((:commit . "17a70bf16255d90d67c8350e88200ec8bfd47563") (:authors ("iory" . "ab.ioryz@gmail.com")) (:maintainer "iory" . "ab.ioryz@gmail.com") (:url . "https://github.com/iory/emacs-helm-ghs"))])
+ (helm-git . [(20120630 2103) nil "Helm extension for Git." single ((:commit . "cb96a52b5aecadd3c27aba7749d14e43ab128d55") (:authors ("Marian Schubert" . "marian.schubert@gmail.com")) (:maintainer "Marian Schubert" . "marian.schubert@gmail.com") (:keywords "helm" "git") (:url . "https://github.com/maio/helm-git"))])
+ (helm-git-files . [(20141212 1317) ((helm (1 5 9))) "helm for git files" single ((:commit . "43193960774069369ac6964bbf7c026900206fa8") (:authors ("INA Lintaro <tarao.gnn at gmail.com>") ("TAKAGI Kentaro <kentaro0910_at_gmail.com>")) (:maintainer "INA Lintaro <tarao.gnn at gmail.com>") (:keywords "helm" "git"))])
+ (helm-git-grep . [(20170614 1411) ((helm-core (2 2 0))) "helm for git grep, an incremental git-grep(1)" single ((:commit . "744cea07dba6e6a5effbdba83f1b786c78fd86d3") (:authors ("mechairoi")) (:maintainer "Yasuyuki Oka" . "yasuyk@gmail.com") (:url . "https://github.com/yasuyk/helm-git-grep"))])
+ (helm-github-stars . [(20190428 1047) ((helm (1 6 8)) (emacs (24 4))) "Helm interface for your github's stars" single ((:commit . "c891690218b0d8b957ea6cb45b1b6cffd15a6950") (:authors ("Sliim" . "sliim@mailoo.org") ("xuchunyang" . "xuchunyang56@gmail.com")) (:maintainer "Sliim" . "sliim@mailoo.org") (:keywords "helm" "github" "stars") (:url . "https://github.com/Sliim/helm-github-stars"))])
+ (helm-gitignore . [(20170211 8) ((gitignore-mode (1 1 0)) (helm (1 7 0)) (request (0 1 0)) (cl-lib (0 5))) "Generate .gitignore files with gitignore.io." single ((:commit . "2a2e7da7855a6db0ab3bb6a6a087863d7abd4391") (:authors ("Juan Placencia")) (:maintainer "Juan Placencia") (:keywords "helm" "gitignore" "gitignore.io") (:url . "https://github.com/jupl/helm-gitignore"))])
+ (helm-gitlab . [(20180312 1647) ((s (1 9 0)) (dash (2 9 0)) (helm (1 0)) (gitlab (0 8 0))) "Helm interface to Gitlab" single ((:commit . "8c2324c02119500f094c2f92dfaba4c9977ce1ba") (:authors ("Nicolas Lamirault" . "nicolas.lamirault@gmail.com")) (:maintainer "Nicolas Lamirault" . "nicolas.lamirault@gmail.com") (:keywords "gitlab" "helm") (:url . "https://github.com/nlamirault/emacs-gitlab"))])
+ (helm-go-package . [(20161103 153) ((emacs (24 4)) (helm-core (2 2 1)) (go-mode (1 4 0)) (deferred (0 4 0))) "helm sources for Go programming language's package" single ((:commit . "e42c563936c205ceedb930a687c11b4bb56447bc") (:authors ("Yasuyuki Oka" . "yasuyk@gmail.com")) (:maintainer "Yasuyuki Oka" . "yasuyk@gmail.com") (:url . "https://github.com/yasuyk/helm-go-package"))])
+ (helm-google . [(20210527 900) ((helm (0))) "Emacs Helm Interface for quick Google searches" single ((:commit . "27834161391c350ef790062391cb7eab1d59fb62") (:authors ("steckerhalter")) (:maintainer "steckerhalter") (:keywords "helm" "google" "search" "browse" "searx") (:url . "https://framagit.org/steckerhalter/helm-google"))])
+ (helm-grepint . [(20200811 1616) ((helm (2 9 7)) (emacs (24 4))) "Generic helm interface to grep" single ((:commit . "9aec98428823b749eb14d2c8512b46b59ca9f8ca") (:authors ("Kalle Kankare" . "kalle.kankare@iki.fi")) (:maintainer "Kalle Kankare" . "kalle.kankare@iki.fi") (:keywords "grep" "grepping" "searching" "helm" "tools" "convenience") (:url . "https://github.com/kopoli/helm-grepint"))])
+ (helm-growthforecast . [(20140120 344) ((helm (1 5 9))) "helm extensions for growthforecast." single ((:commit . "0f94ac090d6c354058ad89a86e5c18385c136d9b") (:authors ("Daichi Hirata" . "daichi.hirat@gmail.com")) (:maintainer "Daichi Hirata" . "daichi.hirat@gmail.com") (:url . "https://github.com/daic-h/helm-growthforecast"))])
+ (helm-gtags . [(20200602 1610) ((emacs (24 4)) (helm (2 0))) "GNU GLOBAL helm interface" single ((:commit . "6285c083d885ea8e110868c6a5b9df69c3f3c4af") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-helm-gtags"))])
+ (helm-hatena-bookmark . [(20210724 732) ((emacs (24)) (helm (2 8 2))) "Hatena::Bookmark with helm interface" single ((:commit . "a6a2b37370ac84ca2cae5ef65b2b144a010b1584") (:authors ("Takashi Masuda" . "masutaka.net@gmail.com")) (:maintainer "Takashi Masuda" . "masutaka.net@gmail.com") (:url . "https://github.com/masutaka/emacs-helm-hatena-bookmark"))])
+ (helm-hayoo . [(20151014 651) ((helm (1 6 0)) (json (1 2)) (haskell-mode (13 7))) "Source and configured helm for searching hayoo" single ((:commit . "dd4c0c8c87521026edf1b808c4de01fa19b7c693") (:authors ("Markus Hauck" . "markus1189@gmail.com")) (:maintainer "Markus Hauck" . "markus1189@gmail.com") (:keywords "helm"))])
+ (helm-helm-commands . [(20130902 1748) ((helm (1 5 4))) "List all helm commands with helm" single ((:commit . "3a05aa19c976501343ad9ae630a36810921a85f6") (:authors ("Joe Bloggs" . "vapniks@yahoo.com")) (:maintainer "Joe Bloggs" . "vapniks@yahoo.com") (:keywords "convenience") (:url . "https://github.com/vapniks/helm-helm-commands"))])
+ (helm-hoogle . [(20161027 534) ((helm (1 6 2)) (emacs (24 4))) "Use helm to navigate query results from Hoogle" single ((:commit . "73969a9d46d2121a849a01a9f7ed3636d01f7bbc") (:authors ("John Wiegley" . "jwiegley@gmail.com")) (:maintainer "John Wiegley" . "jwiegley@gmail.com") (:keywords "haskell" "programming" "hoogle") (:url . "https://github.com/jwiegley/haskell-config"))])
+ (helm-hunks . [(20171217 1933) ((emacs (24 4)) (helm (1 9 8))) "A helm interface for git hunks - browsing, staging, unstaging and killing" single ((:commit . "6392bf716f618eac23ce81140aceb0dfacb9c6d0") (:authors ("@torgeir")) (:maintainer "@torgeir") (:keywords "helm" "git" "hunks" "vc"))])
+ (helm-icons . [(20210330 1216) ((emacs (25 1)) (dash (2 14 1)) (f (0 20 0)) (treemacs (2 7))) "Helm icons" single ((:commit . "8d2f5e705c8b78a390677cf242024739c932fc95") (:authors ("Ivan Yonchovski" . "yyoncho@gmail.com")) (:maintainer "Ivan Yonchovski" . "yyoncho@gmail.com") (:keywords "convenience") (:url . "https://github.com/yyoncho/helm-icons"))])
+ (helm-idris . [(20141202 1757) ((helm (0 0 0)) (idris-mode (0 9 14))) "A Helm datasource for Idris documentation, queried from the compiler" single ((:commit . "a2f45d6817974f318b55ad9b7fd19d5df132d47e") (:authors ("David Raymond Christiansen" . "david@davidchristiansen.dk")) (:maintainer "David Raymond Christiansen" . "david@davidchristiansen.dk") (:keywords "languages" "helm"))])
+ (helm-img . [(20151224 2321) ((helm (1 7 7)) (cl-lib (0 5))) "Utilities for making image sources for helm." tar ((:commit . "aa3f8a5dce8d0413bf07584f07153a39015c2bfc") (:authors ("Sho Matsumoto <l3msh0_at_gmail.com>")) (:maintainer "l3msh0") (:keywords "convenience") (:url . "https://github.com/l3msh0/helm-img"))])
+ (helm-img-tiqav . [(20151224 2322) ((helm-img (0 0 1))) "An helm-source for joking." single ((:commit . "33a7e9508bc8f37d53320b56c92b53d321a57bb0") (:authors ("Sho Matsumoto <l3msh0_at_gmail.com>")) (:maintainer "l3msh0") (:keywords "convenience") (:url . "https://github.com/l3msh0/helm-img"))])
+ (helm-ispell . [(20151231 853) ((helm-core (1 7 7))) "ispell-complete-word with helm interface" single ((:commit . "cb735695ab3a0e66c123c2f3f3e8911fb1c2d5fc") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-helm-ispell"))])
+ (helm-itunes . [(20151013 648) ((helm (1 6 1))) "Play local iTunes and Spotify tracks" single ((:commit . "966de755a5aadbe02311a6cef77bd4790e84c263") (:authors ("Adam Schwartz" . "adam@adamschwartz.io")) (:maintainer "Adam Schwartz" . "adam@adamschwartz.io") (:url . "https://github.com/daschwa/helm-itunes"))])
+ (helm-j-cheatsheet . [(20170217 829) ((helm (1 5 3))) "Quick J reference for Emacs" single ((:commit . "6c47e7162b9ba2de4b41221d01180146973d860b") (:authors ("Oleh Krehel" . "ohwoeowho@gmail.com")) (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com") (:url . "https://github.com/abo-abo/helm-j-cheatsheet"))])
+ (helm-jira . [(20180802 815) ((emacs (25)) (cl-lib (0 5)) (helm (1 9 9))) "Helm bindings for JIRA/Bitbucket/stash" single ((:commit . "75d6ed5bd7a041fa8c1adb21cbbbe57b5a7c7cc7") (:authors ("Roman Decker <roman dot decker at gmail dot com>")) (:maintainer "Roman Decker <roman dot decker at gmail dot com>") (:keywords "tools" "helm" "jira" "bitbucket" "stash") (:url . "https://github.com/DeX3/helm-jira"))])
+ (helm-js-codemod . [(20190921 942) ((emacs (24 4)) (helm-core (1 9 8)) (js-codemod (1 0 0))) "A helm interface for running js-codemods" single ((:commit . "29b1b3c441f0d7e450a3c65b5ff9e72023dc6314") (:authors (nil . "Torgeir Thoresen <@torgeir>")) (:maintainer nil . "Torgeir Thoresen <@torgeir>") (:keywords "helm" "js" "codemod" "region"))])
+ (helm-jstack . [(20150603 422) ((emacs (24)) (helm (1 7 0)) (cl-lib (0 5))) "Helm interface to Jps & Jstack for Java/JVM processes" single ((:commit . "2064f7215dcf4ccbd6a7b8784223251507746da4") (:authors ("Raghav Kumar Gautam" . "rgautam@apache.com")) (:maintainer "Raghav Kumar Gautam" . "rgautam@apache.com") (:keywords "java" "jps" "jstack" "jvm" "emacs" "elisp" "helm"))])
+ (helm-kythe . [(20170709 726) ((emacs (25)) (dash (2 12 0)) (helm (2 0))) "Google Kythe helm interface" single ((:commit . "eabbef4948f8ec7c7b2fac498e9145dfdb10ca82") (:authors ("Fangrui Song" . "i@maskray.me")) (:maintainer "Fangrui Song" . "i@maskray.me") (:url . "https://github.com/MaskRay/emacs-helm-kythe"))])
+ (helm-lastpass . [(20180722 806) ((emacs (25 1)) (helm (2 0)) (csv (2 1))) "Helm interface of LastPass" single ((:commit . "82e1ffb6ae77d9d9e29c398eb013cd20ce963f77") (:authors ("Xu Chunyang" . "mail@xuchunyang.me")) (:maintainer "Xu Chunyang" . "mail@xuchunyang.me") (:url . "https://github.com/xuchunyang/helm-lastpass"))])
+ (helm-lean . [(20210305 1705) ((emacs (24 3)) (dash (2 18 0)) (helm (2 8 0)) (lean-mode (3 3 0))) "Helm interfaces for lean-mode" single ((:commit . "362bc6fa3efb1874c525ed6b4b6f24f76af22596") (:authors ("Leonardo de Moura" . "leonardo@microsoft.com") ("Soonho Kong " . "soonhok@cs.cmu.edu") ("Gabriel Ebner " . "gebner@gebner.org") ("Sebastian Ullrich" . "sebasti@nullri.ch")) (:maintainer "Sebastian Ullrich" . "sebasti@nullri.ch") (:keywords "languages") (:url . "https://github.com/leanprover/lean-mode"))])
+ (helm-lib-babel . [(20180510 1324) ((cl-lib (0 5)) (helm (1 9 2)) (emacs (24 4))) "helm insertion of babel function references" single ((:commit . "41bc0cdea8a604c6c8dc83ed5066644d33688fad") (:authors ("Derek Feichtinger" . "dfeich@gmail.com")) (:maintainer "Derek Feichtinger" . "dfeich@gmail.com") (:keywords "convenience") (:url . "https://github.com/dfeich/helm-lib-babel.el"))])
+ (helm-lines . [(20220103 1909) ((emacs (24 4)) (helm (1 9 8))) "A helm interface for completing by lines" single ((:commit . "f5ad178818d223f32a0bf60d370b50c01df5f3da") (:authors ("@torgeir")) (:maintainer "@torgeir") (:keywords "files" "helm" "rg" "ag" "pt" "vc" "git" "lines" "complete" "tools" "languages") (:url . "https://github.com/torgeir/helm-lines.el/"))])
+ (helm-lobsters . [(20150213 1546) ((helm (1 0)) (cl-lib (0 5))) "helm front-end for lobste.rs" single ((:commit . "53c5b42baf72776dcba891fc3d7cd7d47721e9b0") (:authors ("Julien BLANCHARD" . "julien@sideburns.eu")) (:maintainer "Julien BLANCHARD" . "julien@sideburns.eu") (:url . "https://github.com/julienXX/helm-lobste.rs"))])
+ (helm-ls-git . [(20220418 657) ((helm (1 7 8))) "list git files." single ((:commit . "c6494a462e605d6fd16c9355e32685c3e0085589"))])
+ (helm-ls-hg . [(20150909 543) ((helm (1 7 8))) "List hg files in hg project." single ((:commit . "61b91a22fcfb62d0fc56e361ec01ce96973c7165"))])
+ (helm-ls-svn . [(20190316 2203) ((emacs (24 1)) (helm (1 7 0)) (cl-lib (0 5))) "helm extension to list svn files" single ((:commit . "a6043e1187282f649e2cb9f0e722a42daf41294b") (:authors ("Chunyang Xu" . "chunyang@macports.org")) (:maintainer "Chunyang Xu" . "chunyang@macports.org") (:keywords "helm" "svn") (:url . "https://svn.macports.org/repository/macports/users/chunyang/helm-ls-svn.el/helm-ls-svn.el"))])
+ (helm-lsp . [(20210419 2014) ((emacs (25 1)) (dash (2 14 1)) (lsp-mode (5 0)) (helm (2 0))) "LSP helm integration" single ((:commit . "c2c6974dadfac459b1a69a1217441283874cea92") (:authors ("Ivan Yonchovski" . "yyoncho@gmail.com")) (:maintainer "Ivan Yonchovski" . "yyoncho@gmail.com") (:keywords "languages" "debug") (:url . "https://github.com/yyoncho/helm-lsp"))])
+ (helm-lxc . [(20200323 816) ((emacs (25)) (cl-lib (0 5)) (helm (2 9 4)) (lxc-tramp (0 2 0))) "Helm interface to manage LXC containers" single ((:commit . "37fe2d7ed97967edf59a3b68b1434910516ae24f") (:authors ("montag451")) (:maintainer "montag451") (:keywords "helm" "lxc" "convenience") (:url . "https://github.com/montag451/helm-lxc"))])
+ (helm-make . [(20200620 27) nil "Select a Makefile target with helm" single ((:commit . "ebd71e85046d59b37f6a96535e01993b6962c559") (:authors ("Oleh Krehel" . "ohwoeowho@gmail.com")) (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com") (:keywords "makefile") (:url . "https://github.com/abo-abo/helm-make"))])
+ (helm-migemo . [(20151010 356) ((emacs (24 4)) (helm-core (1 7 8)) (migemo (1 9)) (cl-lib (0 5))) "Migemo plug-in for helm" single ((:commit . "66c6a19d07c6a385daefd2090d0709d26b608b4e") (:authors ("rubikitch" . "rubikitch@ruby-lang.org")) (:maintainer "Yuhei Maeda <yuhei.maeda_at_gmail.com>") (:keywords "matching" "convenience" "tools" "i18n") (:url . "https://github.com/emacs-jp/helm-migemo"))])
+ (helm-mode-manager . [(20210108 2330) ((helm (1 5 3))) "Select and toggle major and minor modes with helm" single ((:commit . "7df8ed3ddd46a0402838b748d317c01454346164") (:authors ("istib")) (:maintainer "istib") (:url . "https://github.com/istib/helm-mode-manager"))])
+ (helm-mt . [(20160918 452) ((emacs (24)) (helm (0 0)) (multi-term (0 0)) (cl-lib (0 5))) "helm multi-term management" single ((:commit . "d2bff4100118483bc398c56d0ff095294209265b") (:authors ("Didier Deshommes" . "dfdeshom@gmail.com")) (:maintainer "Didier Deshommes" . "dfdeshom@gmail.com") (:keywords "helm" "multi-term") (:url . "https://github.com/dfdeshom/helm-mt"))])
+ (helm-mu . [(20210816 913) ((helm (1 5 5))) "Helm sources for searching emails and contacts" single ((:commit . "b85019d01815a4b58d6016c3a30fefa60d8363f2") (:authors ("Titus von der Malsburg" . "malsburg@posteo.de")) (:maintainer "Titus von der Malsburg" . "malsburg@posteo.de") (:url . "https://github.com/emacs-helm/helm-mu"))])
+ (helm-navi . [(20201220 1823) ((emacs (24 4)) (helm (1 9 4)) (helm-org (1 0)) (navi-mode (2 0)) (s (1 10 0))) "Helm for navi-mode" single ((:commit . "c5666cc171288d1fa892900ee66fba2a1c892c81") (:authors ("Adam Porter" . "adam@alphapapa.net")) (:maintainer "Adam Porter" . "adam@alphapapa.net") (:keywords "navigation" "outlines") (:url . "http://github.com/emacs-helm/helm-navi"))])
+ (helm-nixos-options . [(20151013 2309) ((nixos-options (0 0 1)) (helm (1 5 6))) "Helm Interface for nixos-options" single ((:commit . "053a2d5110ce05b7f99bcc2ac4804b70cbe87916") (:authors ("Diego Berrocal" . "cestdiego@gmail.com") ("Travis B. Hartwell" . "nafai@travishartwell.net")) (:maintainer "Diego Berrocal" . "cestdiego@gmail.com") (:keywords "unix") (:url . "http://www.github.com/travisbhartwell/nix-emacs/"))])
+ (helm-notmuch . [(20190320 1048) ((helm (1 9 3)) (notmuch (0 21))) "Search emails with Notmuch and Helm" single ((:commit . "97a01497e079a7b6505987e9feba6b603bbec288") (:authors ("Chunyang Xu" . "mail@xuchunyang.me")) (:maintainer "Chunyang Xu" . "mail@xuchunyang.me") (:keywords "mail") (:url . "https://github.com/emacs-helm/helm-notmuch"))])
+ (helm-open-github . [(20170220 159) ((emacs (24 4)) (helm-core (1 7 7)) (gh (0 8 2))) "Utilities of Opening Github Page" single ((:commit . "2f03d97552a1233db7694116d5f80ecde7612756") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-helm-open-github"))])
+ (helm-org . [(20210324 1927) ((helm (3 3)) (emacs (24 4))) "Helm for org headlines and keywords completion" single ((:commit . "d67186d3a64e610c03a5f3d583488f018fb032e4") (:authors ("Thierry Volpiatto" . "thierry.volpiatto@gmail.com")) (:maintainer "Thierry Volpiatto" . "thierry.volpiatto@gmail.com") (:url . "https://github.com/emacs-helm/helm-org"))])
+ (helm-org-multi-wiki . [(20210228 1853) ((emacs (26 1)) (org (9 3)) (org-multi-wiki (0 4)) (org-ql (0 5)) (dash (2 18)) (helm-org-ql (0 5)) (helm (3 5))) "Helm interface to org-multi-wiki" single ((:commit . "bf8039aadddaf02569fab473f766071ef7e63563") (:authors ("Akira Komamura" . "akira.komamura@gmail.com")) (:maintainer "Akira Komamura" . "akira.komamura@gmail.com") (:keywords "org" "outlines") (:url . "https://github.com/akirak/org-multi-wiki"))])
+ (helm-org-ql . [(20220318 1529) ((emacs (26 1)) (dash (2 18 1)) (s (1 12 0)) (helm-org (1 0)) (org-ql (0 6 -1))) "Helm support for org-ql" single ((:commit . "46f523d94a376b168176c75bbd0e3e0d00e61170") (:authors ("Adam Porter" . "adam@alphapapa.net")) (:maintainer "Adam Porter" . "adam@alphapapa.net") (:url . "https://github.com/alphapapa/org-ql"))])
+ (helm-org-recent-headings . [(20211011 1519) ((emacs (26 1)) (org (9 0 5)) (dash (2 18 0)) (helm (1 9 4)) (org-recent-headings (0 2 -1)) (s (1 12 0))) "Helm source for org-recent-headings" single ((:commit . "97418d581ea030f0718794e50b005e9bae44582e") (:authors ("Adam Porter" . "adam@alphapapa.net")) (:maintainer "Adam Porter" . "adam@alphapapa.net") (:keywords "hypermedia" "outlines" "org") (:url . "http://github.com/alphapapa/org-recent-headings"))])
+ (helm-org-rifle . [(20200512 1943) ((emacs (24 4)) (dash (2 12)) (f (0 18 1)) (helm (1 9 4)) (s (1 10 0))) "Rifle through your Org files" single ((:commit . "5e13a0e59606b40088927870dab116a8eab8e66c") (:authors ("Adam Porter" . "adam@alphapapa.net")) (:maintainer "Adam Porter" . "adam@alphapapa.net") (:keywords "hypermedia" "outlines") (:url . "http://github.com/alphapapa/helm-org-rifle"))])
+ (helm-orgcard . [(20151001 1524) ((helm-core (1 7 7))) "browse the orgcard by helm" single ((:commit . "9655ac340d1ccc5f3d1c0f7c49be8dd3556d4d0d") (:authors ("Yuhei Maeda <yuhei.maeda_at_gmail.com>")) (:maintainer "Yuhei Maeda") (:keywords "convenience" "helm" "org") (:url . "https://github.com/emacs-jp/helm-orgcard"))])
+ (helm-osx-app . [(20190717 958) ((emacs (25 1)) (helm-core (3 0))) "Launch macOS apps with helm" single ((:commit . "634ed5d721a20af265825a018e9df3ee6640daee") (:authors ("Xu Chunyang")) (:maintainer "Xu Chunyang") (:url . "https://github.com/xuchunyang/helm-osx-app"))])
+ (helm-pages . [(20161121 226) ((helm (1 6 5)) (emacs (24)) (cl-lib (0 5))) "Pages in current buffer as Helm datasource" single ((:commit . "51dcb9374d1df9feaae85e60cfb39b970554ecba") (:authors ("David Christiansen" . "david@davidchristiansen.dk")) (:maintainer "David Christiansen" . "david@davidchristiansen.dk") (:keywords "convenience" "helm" "outlines"))])
+ (helm-pass . [(20210221 1655) ((emacs (25)) (helm (0)) (password-store (0)) (auth-source-pass (4 0 0))) "helm interface of pass, the standard Unix password manager" single ((:commit . "4ce46f1801f2e76e53482c65aa0619d427a3fbf9") (:authors ("J. Alexander Branham" . "branham@utexas.edu")) (:maintainer "Pierre Neidhardt" . "mail@ambrevar.xyz") (:url . "https://github.com/emacs-helm/helm-pass"))])
+ (helm-perldoc . [(20200315 1716) ((helm-core (2 0)) (deferred (0 3 1)) (emacs (24 4))) "perldoc with helm interface" tar ((:commit . "6f3526f07f3df3059dbde779f8e681f5f1fee6ea") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-helm-perldoc"))])
+ (helm-perspeen . [(20170228 1345) ((perspeen (0 1 0)) (helm (2 5 0))) "Helm interface for perspeen." single ((:commit . "7fe2922d85608bfa9e18269fc44181428b8849ff") (:authors ("Yoshinobu Fujimoto")) (:maintainer "Yoshinobu Fujimoto") (:keywords "projects" "lisp") (:url . "https://github.com/jimo1001/helm-perspeen"))])
+ (helm-phpunit . [(20160513 853) ((helm (1 9 5)) (phpunit (0 7 0))) "Helm integration for phpunit.el" single ((:commit . "739f26204ad2ba76c25f45e8eab1e5216f7c3518") (:authors ("Eric Hansen" . "hansen.c.eric@gmail.com")) (:maintainer "Eric Hansen" . "hansen.c.eric@gmail.com") (:keywords "phpunit" "helm" "php") (:url . "https://github.com/eric-hansen/phpunit-helm"))])
+ (helm-posframe . [(20211103 236) ((emacs (26 0)) (posframe (1 0 0)) (helm (0 1))) "Using posframe to show helm window" single ((:commit . "87461b52b6f3f378c63642a33f584d4a4ba28351") (:authors ("Feng Shu")) (:maintainer "Feng Shu" . "tumashu@163.com") (:keywords "abbrev" "convenience" "matching" "helm") (:url . "https://github.com/tumashu/helm-posframe"))])
+ (helm-proc . [(20161006 305) ((helm (1 6 0))) "Helm interface for managing system processes" tar ((:commit . "576d31c2d74ba3897d56e2acd2b0993f52c2547c") (:authors ("Markus Hauck" . "markus1189@gmail.com")) (:maintainer "Markus Hauck" . "markus1189@gmail.com") (:keywords "helm"))])
+ (helm-project-persist . [(20151210 1543) ((helm (1 5 2)) (project-persist (0 1 4))) "Helm integration for project-persist package" single ((:commit . "357950fbac18090985a750e40d5d8b10ee9dcd53") (:authors ("Sliim" . "sliim@mailoo.org")) (:maintainer "Sliim" . "sliim@mailoo.org") (:keywords "project-persist" "project" "helm"))])
+ (helm-projectile . [(20201217 908) ((helm (1 9 9)) (projectile (2 2 0)) (cl-lib (0 3))) "Helm integration for Projectile" single ((:commit . "58123f14c392021714fc5d23b9f95c7f95ce07f1") (:authors ("Bozhidar Batsov")) (:maintainer "Bozhidar Batsov") (:keywords "project" "convenience") (:url . "https://github.com/bbatsov/helm-projectile"))])
+ (helm-prosjekt . [(20140129 717) ((prosjekt (0 3)) (helm (1 5 9))) "Helm integration for prosjekt." single ((:commit . "a864a8be5842223043702395f311e3350c28e9db") (:authors ("Sohail Somani" . "sohail@taggedtype.net")) (:maintainer "Sohail Somani" . "sohail@taggedtype.net") (:url . "https://github.com/abingham/prosjekt"))])
+ (helm-pt . [(20160214 2342) ((helm (1 5 6))) "Helm interface to the platinum searcher" tar ((:commit . "8acc52911dad1ed0c3975f134a468762afe0b76b") (:authors ("Rich Alesi")) (:maintainer "Rich Alesi") (:url . "https://github.com/ralesi/helm-pt"))])
+ (helm-purpose . [(20170114 1636) ((emacs (24)) (helm (1 9 2)) (window-purpose (1 4))) "Helm Interface for Purpose" single ((:commit . "9ff4c21c1e9ebc7afb851b738f815df7343bb287") (:authors ("Bar Magal (2016)")) (:maintainer "Bar Magal (2016)") (:url . "https://github.com/bmag/helm-purpose"))])
+ (helm-pydoc . [(20160918 542) ((helm-core (2 0)) (emacs (24 4))) "pydoc with helm interface" tar ((:commit . "85480a29b56dacde425655bc8f5a597c785afdf5") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-helm-pydoc"))])
+ (helm-qiita . [(20190526 1359) ((emacs (24)) (helm (2 8 2))) "Qiita with helm interface" single ((:commit . "5f82010c595f8e122aa3f68148ba8d8ccb1333d8") (:authors ("Takashi Masuda" . "masutaka.net@gmail.com")) (:maintainer "Takashi Masuda" . "masutaka.net@gmail.com") (:url . "https://github.com/masutaka/emacs-helm-qiita"))])
+ (helm-rage . [(20180118 1532) ((helm (1 9 8)) (emacs (24 4)) (dash (2 13 0)) (s (1 11 0))) "Helm command for rage characters." tar ((:commit . "5d0aefb53d859186181d4bdcfeff7d315339c7b8") (:keywords "helm" "rage" "meme") (:url . "https://github.com/bomgar/helm-rage"))])
+ (helm-rails . [(20130424 1519) ((helm (1 5 1)) (inflections (1 1))) "Helm extension for Rails projects." single ((:commit . "506d9948d45dfbc575c9c4c0d102c1ad2f511e82") (:authors ("Adam Sokolnicki" . "adam.sokolnicki@gmail.com")) (:maintainer "Adam Sokolnicki" . "adam.sokolnicki@gmail.com") (:keywords "helm" "rails" "git") (:url . "https://github.com/asok/helm-rails"))])
+ (helm-rb . [(20131123 1639) ((helm (1 0)) (helm-ag-r (20131123))) "Search Ruby's method by ag and display helm" tar ((:commit . "4949d646420a9849af234dacdd8eb34a77c662fd") (:authors ("Yuta Yamada <cokesboy\"at\"gmail.com>")) (:maintainer "Yuta Yamada <cokesboy\"at\"gmail.com>") (:keywords "searching" "ruby") (:url . "https://github.com/yuutayamada/helm-rb"))])
+ (helm-rdefs . [(20161130 536) ((emacs (24)) (helm (1 6 4))) "rdefs with helm interface" single ((:commit . "cd3a6b3af3015ee58ef30cb7c81c79ebe5fc867b") (:authors ("Hiroshi Saito" . "monodie@gmail.com")) (:maintainer "Hiroshi Saito" . "monodie@gmail.com") (:keywords "matching" "tools") (:url . "https://github.com/saidie/helm-rdefs"))])
+ (helm-recoll . [(20200805 1235) ((helm (3 3)) (emacs (24 4))) "helm interface for the recoll desktop search tool." single ((:commit . "c021a3b5e8c010bdad062cceb80fb49788f89e9f") (:authors ("Thierry Volpiatto <thierry.volpiatto at gmail.com>")) (:maintainer "Thierry Volpiatto <thierry.volpiatto at gmail.com>") (:keywords "convenience") (:url . "https://github.com/emacs-helm/helm-recoll"))])
+ (helm-rg . [(20200721 725) ((emacs (25)) (cl-lib (0 5)) (dash (2 13 0)) (helm (2 8 8))) "a helm interface to ripgrep" single ((:commit . "ee0a3c09da0c843715344919400ab0a0190cc9dc") (:authors ("Danny McClanahan")) (:maintainer "Danny McClanahan") (:keywords "find" "file" "files" "helm" "fast" "rg" "ripgrep" "grep" "search" "match") (:url . "https://github.com/cosmicexplorer/helm-rg"))])
+ (helm-rhythmbox . [(20160524 1158) ((helm (1 5 0)) (cl-lib (0 5))) "control Rhythmbox's play queue via Helm" single ((:commit . "c92e1ded34ddd4e62e7e9a558259c232e05193fa") (:authors ("Thomas Winant" . "dewinant@gmail.com")) (:maintainer "Thomas Winant" . "dewinant@gmail.com") (:url . "https://github.com/mrBliss/helm-rhythmbox"))])
+ (helm-robe . [(20151209 355) ((helm (1 7 7))) "completing read function for robe" single ((:commit . "6e69543b4ee76c5f8f3f2510c76e6d9aed17a370") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-helm-robe"))])
+ (helm-ros . [(20160812 1752) ((helm (1 9 9)) (xterm-color (1 0)) (cl-lib (0 5))) "Interfaces ROS with helm" single ((:commit . "92b0b215f6a017f0f57f1af15466cc0b2a5a0135") (:authors ("David Landry" . "davidlandry93@gmail.com")) (:maintainer "David Landry" . "davidlandry93@gmail.com") (:keywords "helm" "ros") (:url . "https://www.github.com/davidlandry93/helm-ros"))])
+ (helm-rtags . [(20191222 920) ((helm (2 0)) (rtags (2 10))) "A front-end for rtags" single ((:commit . "db39790fda5c2443bc790b8971ac140914f7e9c2") (:authors ("Jan Erik Hanssen" . "jhanssen@gmail.com") ("Anders Bakken" . "agbakken@gmail.com")) (:maintainer "Jan Erik Hanssen" . "jhanssen@gmail.com") (:url . "https://github.com/Andersbakken/rtags"))])
+ (helm-rubygems-local . [(20130712 111) ((helm (1 5 3))) "Installed local rubygems find-file for helm" single ((:commit . "289cb33d41c703af9791d6da46b55f070013c2e3") (:authors ("hadashiA" . "dev@hadashikick.jp")) (:maintainer "hadashiA" . "dev@hadashikick.jp") (:url . "https://github.com/f-kubotar/helm-rubygems-local"))])
+ (helm-rubygems-org . [(20140826 1156) ((emacs (24)) (helm (1 6 3)) (cl-lib (0 5))) "Use helm to search rubygems.org" single ((:commit . "6aaed984f698cbdf9f9aceb0221404563e28764d") (:authors ("Chad Albers" . "calbers@neomantic.com")) (:maintainer "Chad Albers" . "calbers@neomantic.com") (:keywords "ruby" "rubygems" "gemfile" "helm") (:url . "https://github.com/neomantic/helm-rubygems-org"))])
+ (helm-safari . [(20160404 324) ((helm (1 9 1)) (emacs (24))) "Browse your Safari bookmarks and history" single ((:commit . "664c7f4488829228eed7e90cd53002e14bec555b") (:authors ("Chunyang Xu" . "xuchunyang56@gmail.com")) (:maintainer "Chunyang Xu" . "xuchunyang56@gmail.com") (:keywords "tools") (:url . "https://github.com/xuchunyang/helm-safari"))])
+ (helm-sage . [(20160514 745) ((cl-lib (0 5)) (helm (1 5 6)) (sage-shell-mode (0 1 0))) "A helm extension for sage-shell-mode." single ((:commit . "f14e9281d8f2162df7d8f9c2ad9ad1248a24803b") (:authors ("Sho Takemori" . "stakemorii@gmail.com")) (:maintainer "Sho Takemori" . "stakemorii@gmail.com") (:keywords "sage" "math" "helm") (:url . "https://github.com/stakemori/helm-sage"))])
+ (helm-searcher . [(20210221 923) ((emacs (25 1)) (helm (2 0)) (searcher (0 1 8)) (s (1 12 0)) (f (0 20 0))) "Helm interface to use searcher" single ((:commit . "fcb4aa5a36ee4555e46756704da50ccf7f13c21d") (:authors ("Shen, Jen-Chieh" . "jcs090218@gmail.com")) (:maintainer "Shen, Jen-Chieh" . "jcs090218@gmail.com") (:url . "https://github.com/emacs-helm/helm-searcher"))])
+ (helm-selected . [(20171223 210) ((emacs (24 4)) (helm (2 8 6)) (selected (1 1))) "helm extension for selected.el" single ((:commit . "a9c769998bc56373d19f0ec9cbbbb4bd89a43c2d") (:authors ("Takaaki ISHIKAWA <takaxp at ieee dot org>")) (:maintainer "Takaaki ISHIKAWA <takaxp at ieee dot org>") (:keywords "extensions" "convenience") (:url . "https://github.com/takaxp/helm-selected"))])
+ (helm-selector . [(20210125 857) ((emacs (26 1)) (helm (3))) "Helm buffer selector" tar ((:commit . "4da4711c4cfd14527abe20d66787beeb49171b26") (:authors ("Pierre Neidhardt" . "mail@ambrevar.xyz")) (:maintainer "Pierre Neidhardt" . "mail@ambrevar.xyz") (:url . "https://github.com/emacs-helm/helm-selector"))])
+ (helm-sheet . [(20130630 1239) ((helm (1 0))) "helm sources for sheet" single ((:commit . "d360b68d0ddb09aa1854e7b2f3cb39caeee26463") (:authors ("Yasuyuki Oka" . "yasuyk@gmail.com")) (:maintainer "Yasuyuki Oka" . "yasuyk@gmail.com") (:keywords "helm" "sheet") (:url . "https://github.com/yasuyk/helm-sheet"))])
+ (helm-shell-history . [(20210214 948) ((helm (3 7)) (emacs (24 3))) "Find shell history from helm" single ((:commit . "0c861f3db721e54053fc65f5651cf548cc1cb600") (:authors ("Yuta Yamada <cokesboy\"at\"gmail.com>")) (:maintainer "Yuta Yamada <cokesboy\"at\"gmail.com>") (:keywords "helm" "terminals" "shell") (:url . "https://github.com/yuutayamada/helm-shell-history"))])
+ (helm-slime . [(20191016 1601) ((emacs (25)) (helm (3 2)) (slime (2 18)) (cl-lib (0 5))) "helm-sources and some utilities for SLIME." single ((:commit . "7886cc49906a87ebd73be3b71f5dd6b1433a9b7b") (:authors ("Takeshi Banse" . "takebi@laafc.net")) (:maintainer "Takeshi Banse" . "takebi@laafc.net") (:keywords "convenience" "helm" "slime") (:url . "https://github.com/emacs-helm/helm-slime"))])
+ (helm-sly . [(20210205 1424) ((emacs (25 1)) (helm (3 2)) (cl-lib (0 5)) (sly (0 0))) "Helm sources and some utilities for SLY." single ((:commit . "3691626c80620e992a338c3222283d9149f1ecb5") (:authors ("Pierre Neidhardt" . "mail@ambrevar.xyz")) (:maintainer "Pierre Neidhardt" . "mail@ambrevar.xyz") (:keywords "convenience" "helm" "sly" "lisp") (:url . "https://github.com/emacs-helm/helm-sly"))])
+ (helm-smex . [(20171004 2008) ((emacs (24)) (smex (3 0)) (helm (1 7 7))) "Helm interface for smex" single ((:commit . "2269375dfa452b88b5170d1a5d5849ebb2c1e413") (:authors ("Peter Vasil" . "mail@petervasil.net")) (:maintainer "Peter Vasil" . "mail@petervasil.net") (:keywords "convenience"))])
+ (helm-spaces . [(20161001 1409) ((helm-core (2 2)) (spaces (0 1 0))) "helm sources for spaces" single ((:commit . "877e2b5178926308d6a7c2a37477bb12c33a96d4") (:authors ("Yasuyuki Oka" . "yasuyk@gmail.com")) (:maintainer "Yasuyuki Oka" . "yasuyk@gmail.com") (:keywords "helm" "frames" "convenience") (:url . "https://github.com/yasuyk/helm-spaces"))])
+ (helm-spotify . [(20160905 2147) ((helm (0 0 0)) (multi (2 0 0))) "Control Spotify with Helm." single ((:commit . "f7a62d1ff88e3127de9be7cd3e818b0a92268ab3") (:authors ("Kris Jenkins" . "krisajenkins@gmail.com")) (:maintainer "Kris Jenkins" . "krisajenkins@gmail.com") (:keywords "helm" "spotify") (:url . "https://github.com/krisajenkins/helm-spotify"))])
+ (helm-spotify-plus . [(20190913 2236) ((emacs (24 4)) (helm (2 0 0)) (multi (2 0 1))) "Control Spotify search and select music with Helm." single ((:commit . "c3922ec368250965e483876cde5880d88a40a71b") (:authors ("Wanderson Ferreira <https://github.com/wandersoncferreira> and Luis Moneda <https://github.com/lgmoneda>")) (:maintainer "Wanderson Ferreira <https://github.com/wandersoncferreira> and Luis Moneda <https://github.com/lgmoneda>") (:url . "https://github.com/wandersoncferreira/helm-spotify-plus"))])
+ (helm-sql-connect . [(20170319 1251) ((helm (0 0 0))) "Choose a database to connect to via Helm." single ((:commit . "5aead55b6f8636140945714d8c332b287ab9ef10") (:authors ("Eric Hansen" . "hansen.c.eric@gmail.com")) (:maintainer "Eric Hansen" . "hansen.c.eric@gmail.com") (:keywords "tools" "convenience" "comm") (:url . "https://github.com/eric-hansen/helm-sql-connect"))])
+ (helm-switch-shell . [(20210713 1440) ((emacs (25 1)) (helm (2 8 8))) "A Helm source for switching between shell buffers" single ((:commit . "8d7ba1d99ff12a8f1d6ce3b9684ae8aebf494cf3") (:authors ("James N. V. Cash" . "james.cash@occasionallycogent.com")) (:maintainer "James N. V. Cash" . "james.cash@occasionallycogent.com") (:keywords "matching" "processes" "terminals" "tools") (:url . "https://github.com/jamesnvc/helm-switch-shell"))])
+ (helm-switch-to-repl . [(20210206 844) ((emacs (26 1)) (helm (3))) "Helm action to switch directory in REPLs" single ((:commit . "f0e732e7217fc0373b0805245fa15920cf676619") (:authors ("Pierre Neidhardt" . "mail@ambrevar.xyz")) (:maintainer "Pierre Neidhardt" . "mail@ambrevar.xyz") (:url . "https://github.com/emacs-helm/helm-switch-to-repl"))])
+ (helm-swoop . [(20210426 547) ((emacs (25 1)) (helm (3 6))) "Efficiently hopping squeezed lines powered by helm interface" single ((:commit . "1b3285791f1dc1fde548fe67aec07214d698fd57") (:authors ("Shingo Fukuyama - http://fukuyama.co")) (:maintainer "Shingo Fukuyama - http://fukuyama.co") (:keywords "convenience" "helm" "swoop" "inner" "buffer" "search") (:url . "https://github.com/emacsorphanage/helm-swoop"))])
+ (helm-system-packages . [(20210628 1727) ((emacs (24 4)) (helm (2 8 7)) (seq (1 8))) "Helm UI wrapper for system package managers." tar ((:commit . "a16bb1c3708416984106a98353700d456414b6a1") (:authors ("Pierre Neidhardt" . "mail@ambrevar.xyz")) (:maintainer "Pierre Neidhardt" . "mail@ambrevar.xyz") (:keywords "helm" "packages") (:url . "https://github.com/emacs-helm/helm-system-packages"))])
+ (helm-systemd . [(20210105 542) ((emacs (24 4)) (helm (1 9 2)) (with-editor (2 5 0))) "helm's systemd interface" single ((:commit . "8b26ab2d3a5b08c1e03c9312818512d7492bbc9a") (:authors (nil . "<lompik@oriontabArch>")) (:maintainer nil . "<lompik@oriontabArch>") (:keywords "convenience"))])
+ (helm-tail . [(20181124 439) ((emacs (25 1)) (helm (2 7 0))) "Read recent output from various sources" single ((:commit . "1f5a6355aa3bdb00b9b0bc93db29c17f0d6701e3") (:authors ("Akira Komamura" . "akira.komamura@gmail.com")) (:maintainer "Akira Komamura" . "akira.komamura@gmail.com") (:keywords "maint" "tools") (:url . "https://github.com/akirak/helm-tail"))])
+ (helm-taskswitch . [(20190304 1414) ((emacs (24)) (helm (3 0))) "Use helm to switch windows and buffers" single ((:commit . "59f7cb99defa6e6bf6e7d599559fa8d5786cf8a9") (:authors ("Brian Caruso" . "briancaruso@gmail.com")) (:maintainer "Brian Caruso" . "briancaruso@gmail.com") (:keywords "frames") (:url . "https://github.com/bdc34/helm-taskswitch"))])
+ (helm-themes . [(20200323 712) ((helm-core (2 0)) (emacs (24 4))) "Color theme selection with helm interface" single ((:commit . "b6bd3379b98d306935731e9632907387b078e000") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-helm-themes"))])
+ (helm-tramp . [(20190616 125) ((emacs (24 3)) (helm (2 0))) "Tramp helm interface for ssh, docker, vagrant" single ((:commit . "55e56975fe1456591a293bf60c183c3dda9f788f") (:authors ("Masashı Mıyaura")) (:maintainer "Masashı Mıyaura") (:url . "https://github.com/masasam/emacs-helm-tramp"))])
+ (helm-tree-sitter . [(20220328 1345) ((emacs (25 1)) (helm (3 6 2)) (tree-sitter (0 16 1))) "Helm interface for tree-sitter" tar ((:commit . "ef5209bd1deb56d6cab7a26e6d55615161f2115a") (:authors ("Giedrius Jonikas" . "giedriusj1@gmail.com")) (:maintainer "Giedrius Jonikas" . "giedriusj1@gmail.com") (:url . "https://github.com/Giedriusj1/helm-tree-sitter"))])
+ (helm-twitch . [(20220420 1625) ((dash (2 11 0)) (helm (1 5)) (emacs (24)) (twitch-api (20210809 1641)) (streamlink (20210811 1429))) "Navigate Twitch.tv via `helm'" single ((:commit . "27fbec24cc250d508cd2f4286da16262752908eb") (:authors ("Aaron Jacobs" . "atheriel@gmail.com")) (:maintainer "Aaron Jacobs" . "atheriel@gmail.com") (:keywords "helm" "twitch" "games") (:url . "https://github.com/BenediktBroich/helm-twitch"))])
+ (helm-unicode . [(20180608 1407) ((helm (1 9 8)) (emacs (24 4))) "Helm command for unicode characters." single ((:commit . "fbeb0c5e741a6f462520884b744d43a9acbe1d34"))])
+ (helm-w32-launcher . [(20141223 2014) ((emacs (24)) (helm (1 6 5)) (cl-lib (0 5))) "Start Menu entry launcher using Helm" tar ((:commit . "3e59ad62b89dd21d334af0203d445a83eb25dc5b") (:authors ("Fanael Linithien" . "fanael4@gmail.com")) (:maintainer "Fanael Linithien" . "fanael4@gmail.com") (:url . "https://github.com/Fanael/helm-w32-launcher"))])
+ (helm-w3m . [(20210315 723) ((helm (1 5)) (w3m (0 0)) (cl-lib (0 5)) (emacs (24 1))) "W3m bookmark - helm interface." single ((:commit . "0a25a2b1df9bc660a90d633beb301b3815556e4e"))])
+ (helm-wikipedia . [(20210525 717) ((helm (3 6)) (emacs (25 1))) "Wikipedia suggestions" single ((:commit . "c242c74efaeda2ffbafd281ee6bceae1a42507bb") (:url . "https://github.com/emacs-helm/helm-wikipedia"))])
+ (helm-wordnet . [(20160128 1507) ((emacs (24)) (helm (1 7 0)) (cl-lib (0 5))) "Helm interface to local wordnet dictionary" single ((:commit . "a36dbc6fcb570b812870bc1e190f203e0a0042fc") (:authors ("Raghav Kumar Gautam" . "rgautam@apache.com")) (:maintainer "Raghav Kumar Gautam" . "rgautam@apache.com") (:keywords "dictionary" "wordnet" "emacs" "elisp" "helm") (:url . "https://github.com/raghavgautam/helm-wordnet"))])
+ (helm-xcdoc . [(20160116 1018) ((helm (1 5)) (emacs (24 4))) "Search Xcode Document by docsetutil and eww with helm interface" single ((:commit . "a85612149a6d8e18ab309b3db2d222ce39c42049") (:authors ("Ryo Fujimoto" . "fujimisakri@gmail.com")) (:maintainer "Ryo Fujimoto" . "fujimisakri@gmail.com") (:url . "https://github.com/fujimisakari/emacs-helm-xcdoc"))])
+ (helm-xref . [(20211017 1334) ((emacs (25 1)) (helm (1 9 4))) "Helm interface for xref results" single ((:commit . "ea0e4ed8a9baf236e4085cbc7178241f109a53fa") (:authors ("Fritz Stelzer" . "brotzeitmacher@gmail.com")) (:maintainer "Fritz Stelzer" . "brotzeitmacher@gmail.com") (:url . "https://github.com/brotzeit/helm-xref"))])
+ (helm-youtube . [(20190101 1733) ((request (0 2 0)) (helm (2 3 1)) (cl-lib (0 5))) "Query YouTube and play videos in your browser" single ((:commit . "e7272f1648c7fa836ea5ac1a61770b4931ab4709") (:authors ("Maximilian Roquemore" . "maximus12793@gmail.com")) (:maintainer "Maximilian Roquemore" . "maximus12793@gmail.com") (:keywords "youtube" "multimedia") (:url . "https://github.com/maximus12793/helm-youtube"))])
+ (helm-z . [(20171204 325) ((helm (1 0))) "Show z directory list with helm.el support." single ((:commit . "37212220bebea8b9c238cb1bbacd8332b7f26c03") (:authors ("yynozk" . "yynozk@gmail.com")) (:maintainer "yynozk" . "yynozk@gmail.com") (:url . "https://github.com/yynozk/helm-z"))])
+ (helm-zhihu-daily . [(20160625 1145) ((helm (1 0)) (cl-lib (0 5)) (emacs (24 4))) "Helm interface for 知乎日报 (http://daily.zhihu.com)" single ((:commit . "be27dcc6be1eb97663b65581a9a5c0fc81cfaba7") (:authors ("Chunyang Xu" . "xuchunyang56@gmail.com")) (:maintainer "Chunyang Xu" . "xuchunyang56@gmail.com") (:url . "https://github.com/xuchunyang/helm-zhihu-daily"))])
+ (help-find . [(20210826 928) ((emacs (25 2)) (dash (2 12))) "Additional help functions for working with keymaps" single ((:commit . "576d6505b9e42f50f121b1a6a675f17f03a04406") (:authors ("Duncan Burke" . "duncankburke@gmail.com")) (:maintainer "Duncan Burke" . "duncankburke@gmail.com") (:keywords "help") (:url . "https://github.com/duncanburke/help-find"))])
+ (help-find-org-mode . [(20181204 234) ((emacs (24 4))) "Advise help to find org source over tangled code" single ((:commit . "aeda7f92c086dab9d8dfcd580fe80b332887a548") (:authors ("Eric Crosson" . "eric.s.crosson@utexas.com")) (:maintainer "Eric Crosson" . "eric.s.crosson@utexas.com") (:keywords "convenience") (:url . "https://github.com/EricCrosson/help-find-org-mode"))])
+ (helpful . [(20220412 421) ((emacs (25)) (dash (2 18 0)) (s (1 11 0)) (f (0 20 0)) (elisp-refs (1 2))) "A better *help* buffer" single ((:commit . "c2729a236a84a1fbd3d184c163fbd10e0fd62077") (:authors ("Wilfred Hughes" . "me@wilfred.me.uk")) (:maintainer "Wilfred Hughes" . "me@wilfred.me.uk") (:keywords "help" "lisp") (:url . "https://github.com/Wilfred/helpful"))])
+ (hemera-theme . [(20180916 924) ((emacs (24))) "Light theme" single ((:commit . "b67c902b210b37b00cac68726822404543147ba8") (:authors ("Guido Schmidt")) (:maintainer "Guido Schmidt" . "guido.schmidt.2912@gmail.com") (:keywords "themes" "light-theme") (:url . "https://github.com/GuidoSchmidt/emacs-hemera-theme"))])
+ (hemisu-theme . [(20130508 1844) nil "Hemisu for Emacs." tar ((:commit . "5c206561aa2c844ecdf3e3b672c3235e559ddd7f") (:authors ("Andrzej Sliwa")) (:maintainer "Andrzej Sliwa") (:url . "http://github/anrzejsliwa/django-theme"))])
+ (hercules . [(20200420 747) ((emacs (24 4)) (which-key (3 3 2))) "An auto-magical, which-key-based hydra banisher." single ((:commit . "557da39878d0637395fdded91243b340c37eff7b") (:authors ("Uros Perisic")) (:maintainer "Uros Perisic") (:keywords "convenience") (:url . "https://gitlab.com/jjzmajic/hercules"))])
+ (heroku-theme . [(20150523 219) nil "Heroku color theme" single ((:commit . "8083643fe92ec3a1c3eb82f1b8dc2236c9c9691d") (:authors ("Jonathan Chu" . "me@jonathanchu.is")) (:maintainer "Jonathan Chu" . "me@jonathanchu.is") (:url . "https://github.com/jonathanchu/color-theme-heroku"))])
+ (hexo . [(20200416 1410) ((emacs (24 3))) "Major mode & tools for Hexo" single ((:commit . "d600b6c2d51959f1331c8abf3953365544322afa") (:authors ("Ono Hiroko (kuanyui)" . "azazabc123@gmail.com")) (:maintainer "Ono Hiroko (kuanyui)" . "azazabc123@gmail.com") (:keywords "tools" "hexo") (:url . "https://github.com/kuanyui/hexo.el"))])
+ (hfst-mode . [(20160708 1202) nil "major mode for editing HFST files" single ((:commit . "ac1bb9dd92545d3e7fdc05c83996c227cc15c6b8") (:authors ("Kevin Brubeck Unhammer" . "unhammer@fsfe.org")) (:maintainer "Kevin Brubeck Unhammer" . "unhammer@fsfe.org") (:keywords "languages") (:url . "http://wiki.apertium.org/wiki/Emacs"))])
+ (hg-histedit . [(20210302 2334) ((emacs (25 1)) (with-editor (2 8 3))) "Edit HG histedit files" single ((:commit . "a05149483b9c5f7848ece0ba6028c900595a6a25") (:authors ("James Nguyen" . "james@jojojames.com")) (:maintainer "James Nguyen" . "james@jojojames.com") (:keywords "mercurial" "hg" "emacs" "tools") (:url . "https://github.com/jojojames/hg-histedit"))])
+ (hgignore-mode . [(20210314 431) nil "a major mode for editing hgignore files" single ((:commit . "2c5aa4c238848f5b4f2955afcfb5f21ea513653b") (:authors ("Omair Majid" . "omair.majid@gmail.com")) (:maintainer "Omair Majid" . "omair.majid@gmail.com") (:keywords "convenience" "vc" "hg") (:url . "http://github.com/omajid/hgignore-mode"))])
+ (hgrc-mode . [(20150409 2043) nil "major mode for editing hgrc files" single ((:commit . "314e8320b82cc1ce74b1bd372f296252e7a23090") (:authors ("Omair Majid" . "omair.majid@gmail.com")) (:maintainer "Omair Majid" . "omair.majid@gmail.com") (:keywords "convenience" "vc" "hg") (:url . "http://github.com/omajid/hgrc-mode"))])
+ (hi2 . [(20141005 1931) nil "indentation module for Haskell Mode" single ((:commit . "c9d199727b5cdcb9e36a972b38131ce4611fd6c8") (:authors ("Gergely Risko" . "gergely@risko.hu")) (:maintainer "Gergely Risko" . "gergely@risko.hu") (:keywords "indentation" "haskell") (:url . "https://github.com/errge/hi2"))])
+ (hiccup-cli . [(20210208 652) ((emacs (26 1))) "Convert HTML to Hiccup syntax" single ((:commit . "b56ae0d5cd5ce3ef24ed13be5103e231c91ef4e2") (:authors ("Kevin W. van Rooijen")) (:maintainer "Kevin W. van Rooijen") (:keywords "tools") (:url . "https://github.com/kwrooijen/hiccup-cli"))])
+ (hide-lines . [(20210513 1636) nil "Commands for hiding lines based on a regexp" single ((:commit . "f0828c15e50db5eddb905de783e7683b04d1eca3") (:authors ("Mark Hulme-Jones <ture at plig cucumber dot net>")) (:maintainer "Joe Bloggs" . "vapniks@yahoo.com") (:keywords "convenience") (:url . "https://github.com/vapniks/hide-lines"))])
+ (hide-mode-line . [(20211112 1400) ((emacs (24 4))) "minor mode that hides/masks your modeline" single ((:commit . "bc5d293576c5e08c29e694078b96a5ed85631942") (:authors ("Henrik Lissner <http://github/hlissner>")) (:maintainer "Henrik Lissner" . "git@henrik.io") (:keywords "frames" "mode-line") (:url . "https://github.com/hlissner/emacs-hide-mode-line"))])
+ (hidepw . [(20200326 112) nil "Minor mode to hide passwords" single ((:commit . "73f099da79d73fe4087472df3469d8b9b20a59f2") (:authors ("Chris Forno" . "jekor@jekor.com")) (:maintainer "Chris Forno" . "jekor@jekor.com") (:keywords "hide" "hidden" "password" "faces") (:url . "https://github.com/jekor/hidepw"))])
+ (hideshow-org . [(20120223 2250) nil "Provides org-mode like hide and show for hideshow.el" single ((:commit . "16419e52e6cdd2f46f755144c0ab11ce00d1a626") (:authors ("Shane Celis <shane (at) gnufoo (dot) org>")) (:maintainer "Shane Celis <shane (at) gnufoo (dot) org>") (:keywords "c" "c++" "java" "lisp" "tools" "editing" "comments" "blocks" "hiding" "outlines" "org-mode"))])
+ (hierarchy . [(20190425 842) ((emacs (25 1))) "Library to create and display hierarchy structures" single ((:commit . "fed505b8e71bf51772887c8a94bb57f5b8838b63") (:authors ("Damien Cassou" . "damien@cassou.me")) (:maintainer "Damien Cassou" . "damien@cassou.me") (:url . "https://github.com/DamienCassou/hierarchy"))])
+ (highlight . [(20210318 2248) nil "Highlighting commands." single ((:commit . "28557cb8d99b96eb509aaec1334c7cdda162517f") (:authors ("Drew Adams")) (:maintainer nil . "Drew Adams (concat \"drew.adams\" \"@\" \"oracle\" \".com\")") (:keywords "faces" "help" "local") (:url . "https://www.emacswiki.org/emacs/download/highlight.el"))])
+ (highlight-blocks . [(20190318 1557) ((emacs (24))) "Highlight the blocks point is in" single ((:commit . "33cf3d36662faa36c86c8d53e4d5a3922efa3eb8") (:authors ("Fanael Linithien" . "fanael4@gmail.com")) (:maintainer "Fanael Linithien" . "fanael4@gmail.com") (:url . "https://github.com/Fanael/highlight-blocks"))])
+ (highlight-context-line . [(20181122 2203) nil "Improve orientation when scrolling" single ((:commit . "6b334e8207c780835a05b6909b4d826898c33d26") (:authors ("Stefan Kamphausen <www.skamphausen.de>")) (:maintainer "Stefan Kamphausen <www.skamphausen.de>") (:keywords "faces" "services" "user") (:url . "https://github.com/ska2342/highlight-context-line/"))])
+ (highlight-defined . [(20210411 222) ((emacs (24))) "Syntax highlighting of known Elisp symbols" single ((:commit . "4420bdda419875dacb065468aafe273b2022580e") (:authors ("Fanael Linithien" . "fanael4@gmail.com")) (:maintainer "Fanael Linithien" . "fanael4@gmail.com") (:url . "https://github.com/Fanael/highlight-defined"))])
+ (highlight-doxygen . [(20200520 1713) nil "Highlight Doxygen comments" single ((:commit . "eec4874e2e89d4eb39091aad89a67dff8f8ec84c") (:authors ("Anders Lindgren")) (:maintainer "Anders Lindgren") (:keywords "faces") (:url . "https://github.com/Lindydancer/highlight-doxygen"))])
+ (highlight-escape-sequences . [(20201214 1730) nil "Highlight escape sequences" single ((:commit . "fae976568c04b6fe8a9f2d854c8fe23b357a6878") (:authors ("Dmitry Gutov" . "dgutov@yandex.ru") ("Pavel Matcula" . "dev.plvlml@gmail.com")) (:maintainer "Dmitry Gutov" . "dgutov@yandex.ru") (:keywords "convenience") (:url . "https://github.com/dgutov/highlight-escape-sequences"))])
+ (highlight-function-calls . [(20170908 500) ((emacs (24 4))) "Highlight function/macro calls" single ((:commit . "f7a1eaf95fc64cc0db4d0567f9ff79ec4ae04787") (:authors ("Adam Porter" . "adam@alphapapa.net")) (:maintainer "Adam Porter" . "adam@alphapapa.net") (:keywords "faces" "highlighting") (:url . "http://github.com/alphapapa/highlight-function-calls"))])
+ (highlight-indent-guides . [(20200820 2328) ((emacs (24 1))) "Minor mode to highlight indentation" single ((:commit . "cf352c85cd15dd18aa096ba9d9ab9b7ab493e8f6") (:authors ("DarthFennec" . "darthfennec@derpymail.org")) (:maintainer "DarthFennec" . "darthfennec@derpymail.org") (:url . "https://github.com/DarthFennec/highlight-indent-guides"))])
+ (highlight-indentation . [(20210221 1418) nil "Minor modes for highlighting indentation" single ((:commit . "d88db4248882da2d4316e76ed673b4ac1fa99ce3") (:authors ("Anton Johansson" . "anton.johansson@gmail.com")) (:maintainer "Anton Johansson" . "anton.johansson@gmail.com") (:url . "https://github.com/antonj/Highlight-Indentation-for-Emacs"))])
+ (highlight-leading-spaces . [(20151216 1222) ((emacs (24 4))) "Highlight leading spaces" single ((:commit . "840db19d863dd97993fd9f893f5be501627b6354") (:authors ("Thomas Winant" . "dewinant@gmail.com")) (:maintainer "Thomas Winant" . "dewinant@gmail.com") (:url . "https://github.com/mrBliss/highlight-leading-spaces"))])
+ (highlight-numbers . [(20181013 1744) ((emacs (24)) (parent-mode (2 0))) "Highlight numbers in source code" single ((:commit . "8b4744c7f46c72b1d3d599d4fb75ef8183dee307") (:authors ("Fanael Linithien" . "fanael4@gmail.com")) (:maintainer "Fanael Linithien" . "fanael4@gmail.com") (:url . "https://github.com/Fanael/highlight-numbers"))])
+ (highlight-operators . [(20170213 2220) nil "a face for operators in programming modes" single ((:commit . "7696b43419505d6e3511ad2781f9f1dd3c55ef8c") (:authors ("Jonathan Kotta" . "jpkotta@gmail.com")) (:maintainer "Jonathan Kotta" . "jpkotta@gmail.com"))])
+ (highlight-parentheses . [(20220408 845) ((emacs (24 3))) "Highlight surrounding parentheses" single ((:commit . "438a1cb2563e2a2496be4678cc0df8d5b22caf5d") (:authors ("Nikolaj Schumacher <bugs * nschum de>")) (:maintainer "Tassilo Horn" . "tsdh@gnu.org") (:keywords "faces" "matching") (:url . "https://sr.ht/~tsdh/highlight-parentheses.el/"))])
+ (highlight-quoted . [(20140916 1822) ((emacs (24))) "Highlight Lisp quotes and quoted symbols" single ((:commit . "24103478158cd19fbcfb4339a3f1fa1f054f1469") (:authors ("Fanael Linithien" . "fanael4@gmail.com")) (:maintainer "Fanael Linithien" . "fanael4@gmail.com") (:url . "https://github.com/Fanael/highlight-quoted"))])
+ (highlight-refontification . [(20170211 2024) nil "Visualize font-lock refontification." single ((:commit . "32632897d88c4611fadb08517ca00ef5cbc989b6") (:authors ("Anders Lindgren")) (:maintainer "Anders Lindgren") (:keywords "faces" "tools") (:url . "https://github.com/Lindydancer/highlight-refontification"))])
+ (highlight-stages . [(20210306 418) nil "highlight staged (quasi-quoted) expressions" single ((:commit . "95daa710f3d8fc83f42c5da38003fc71ae0da1fc") (:authors ("zk_phi")) (:maintainer "zk_phi") (:url . "http://hins11.yu-yake.com/"))])
+ (highlight-symbol . [(20160102 2009) nil "automatic and manual symbol highlighting" single ((:commit . "7a789c779648c55b16e43278e51be5898c121b3a") (:authors ("Nikolaj Schumacher <bugs * nschum de>")) (:maintainer "Nikolaj Schumacher <bugs * nschum de>") (:keywords "faces" "matching") (:url . "http://nschum.de/src/emacs/highlight-symbol/"))])
+ (highlight-thing . [(20181229 1301) nil "Minimalistic minor mode to highlight current thing under point." single ((:commit . "561d08a26f78f18d405d4f371f1c813db094e2f3") (:authors ("Felix Geller" . "fgeller@gmail.com")) (:maintainer "Felix Geller" . "fgeller@gmail.com") (:keywords "highlight" "thing" "symbol") (:url . "https://github.com/fgeller/highlight-thing.el"))])
+ (highlight-unique-symbol . [(20130612 542) ((deferred (0 3 2))) "highlight symbols which not appear in the repository" single ((:commit . "4141bf86a94e30d94d9af9c29d40b16886226e1c") (:authors ("hitode909" . "hitode909@gmail.com")) (:maintainer "hitode909" . "hitode909@gmail.com") (:url . "https://github.com/hitode909/emacs-highlight-unique-symbol"))])
+ (highlight2clipboard . [(20151020 1840) ((htmlize (1 47))) "Copy text to clipboard with highlighting." tar ((:commit . "6ce58a060d9c5843ccb8c79ec2bba7858c68ac15") (:authors ("Anders Lindgren")) (:maintainer "Anders Lindgren") (:keywords "tools"))])
+ (hindent . [(20210201 148) ((cl-lib (0 5))) "Indent haskell code using the \"hindent\" program" single ((:commit . "f7e7b12fd119e91c795cbe21bebf7b5af5d273b8") (:authors ("Chris Done" . "chrisdone@gmail.com")) (:maintainer "Chris Done" . "chrisdone@gmail.com") (:url . "https://github.com/chrisdone/hindent"))])
+ (hippie-exp-ext . [(20160502 2326) nil "Extension of hippie-expand" single ((:commit . "4eda13f90da51ab217d024701f4c30f91ffcb90e") (:authors ("rubikitch" . "rubikitch@ruby-lang.org")) (:maintainer "rubikitch" . "rubikitch@ruby-lang.org") (:keywords "abbrev" "convenience" "completions" "hippie-expand") (:url . "http://www.emacswiki.org/emacs/download/hippie-exp-ext.el"))])
+ (hippie-expand-slime . [(20170723 146) nil "Hook slime's completion into hippie-expand" single ((:commit . "39bbae94896a62854d31754debdfae71d35fec62") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:url . "https://github.com/purcell/hippie-expand-slime"))])
+ (hippie-namespace . [(20140508 2041) nil "Special treatment for namespace prefixes in hippie-expand" single ((:commit . "d0d0f15c67ab8bef5e9d1e29a89ecd3613a60b49") (:authors ("Roland Walker" . "walker@pobox.com")) (:maintainer "Roland Walker" . "walker@pobox.com") (:keywords "convenience" "lisp" "tools" "completion") (:url . "http://github.com/rolandwalker/hippie-namespace"))])
+ (historian . [(20200203 1927) ((emacs (24 4))) "Persistently store selected minibuffer candidates" single ((:commit . "852cb4e72c0f78c8dbb2c972bdcb4e7b0108ff4c") (:authors ("PythonNut" . "pythonnut@pythonnut.com")) (:maintainer "PythonNut" . "pythonnut@pythonnut.com") (:keywords "convenience") (:url . "https://github.com/PythonNut/historian.el"))])
+ (history . [(20160821 1602) ((emacs (24 3))) "History utility for source code navigation" tar ((:commit . "5317663fb45bbd5e96d258cb0807dcc266ce67ff") (:authors ("boyw165")) (:maintainer "boyw165") (:url . "https://github.com/boyw165/history"))])
+ (historyf . [(20151124 159) nil "file history library like browser" single ((:commit . "196c058ceb092fdd56b0e4ce85b7e714d6f72224") (:authors ("k1LoW (Kenichirou Oyama), <k1lowxb [at] gmail [dot] com> <k1low [at] 101000lab [dot] org>")) (:maintainer "k1LoW (Kenichirou Oyama), <k1lowxb [at] gmail [dot] com> <k1low [at] 101000lab [dot] org>") (:url . "https://github.com/k1LoW/emacs-historyf"))])
+ (hive . [(20131217 1512) ((sql (3 0))) "Hive SQL mode extension" single ((:commit . "11b5172e081ad8079fc78758bef6f306f82ae32b") (:authors ("Roman Scherer" . "roman@burningswell.com")) (:maintainer "Roman Scherer" . "roman@burningswell.com") (:keywords "sql" "hive"))])
+ (hiwin . [(20150825 827) nil "Visible active window mode." single ((:commit . "6ee8ed051405653bd9b7332d7e9fbb591d954051") (:authors ("k.sugita")) (:maintainer "k.sugita") (:keywords "faces" "editing" "emulating"))])
+ (hl-anything . [(20160422 1708) ((emacs (24 3))) "Highlight symbols, selections, enclosing parens and more." tar ((:commit . "8696bc55a8cba408f0fc83a907a9ec529d79e558") (:authors ("boyw165")) (:maintainer "boyw165"))])
+ (hl-block-mode . [(20220211 548) ((emacs (26 1))) "Highlighting nested blocks" single ((:commit . "3dd29cfbf24fec16eaf3d47936338adb6b34f5c8") (:authors ("Campbell Barton" . "ideasman42@gmail.com")) (:maintainer "Campbell Barton" . "ideasman42@gmail.com") (:url . "https://gitlab.com/ideasman42/emacs-hl-block-mode"))])
+ (hl-fill-column . [(20200607 757) ((names (0 5)) (emacs (24))) "Highlight fill column." single ((:commit . "5782a91ba0182c4e562fa0db6379ff9dd472856b") (:keywords "fill column" "faces") (:url . "https://github.com/laishulu/hl-fill-column"))])
+ (hl-indent . [(20170429 2104) ((emacs (24)) (cl-lib (0 5))) "Highlight irregular indentation." single ((:commit . "bdb2e0177a7c8b29af26998e688b856adc6ded93") (:authors ("Kirill Ignatiev <github.com/ikirill>")) (:maintainer "Kirill Ignatiev <github.com/ikirill>") (:keywords "convenience" "faces") (:url . "https://github.com/ikirill/hl-indent"))])
+ (hl-prog-extra . [(20220504 607) ((emacs (26 2))) "Customizable highlighting for source-code" tar ((:commit . "cc09c1eb9460c1aa54ab1fc77331eae40cf7c3a3") (:authors ("Campbell Barton" . "ideasman42@gmail.com")) (:maintainer "Campbell Barton" . "ideasman42@gmail.com") (:keywords "convenience") (:url . "https://gitlab.com/ideasman42/emacs-hl-prog-extra"))])
+ (hl-sentence . [(20171018 1519) nil "highlight a sentence based on customizable face" single ((:commit . "86ae38d3103bd20da5485cbdd59dfbd396c45ee4") (:authors ("Donald Ephraim Curtis" . "dcurtis@milkbox.net")) (:maintainer "Donald Ephraim Curtis" . "dcurtis@milkbox.net") (:keywords "highlighting") (:url . "http://github.com/milkypostman/hl-sentence"))])
+ (hl-todo . [(20220422 1611) ((emacs (25 1)) (compat (28 1 1 0))) "Highlight TODO and similar keywords" single ((:commit . "6769accd7003ba5a0376d2c5cef0fcffce8f45be") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:keywords "convenience") (:url . "https://github.com/tarsius/hl-todo"))])
+ (hledger-mode . [(20210706 1225) ((emacs (24 4)) (popup (0 5 3)) (async (1 9)) (htmlize (1 47))) "A mode for writing journal entries for hledger." tar ((:commit . "9ac07ff0adbce6a402c17e789b1750f9da0d22f4") (:authors ("Narendra Joshi" . "narendraj9@gmail.com")) (:maintainer "Narendra Joshi" . "narendraj9@gmail.com") (:keywords "data") (:url . "https://github.com/narendraj9/hledger-mode.git"))])
+ (hlint-refactor . [(20190115 900) nil "Apply HLint suggestions" single ((:commit . "c4307f86aad6d02e32e9b30cb6edc115584c791c") (:keywords "haskell" "refactor") (:url . "https://github.com/mpickering/hlint-refactor-mode"))])
+ (hlinum . [(20180422 412) ((cl-lib (0 2))) "Extension for linum.el to highlight current line number" single ((:commit . "5646d9c0b9e7598b20b2004eab5439fdc6dbeda5") (:authors ("Tomoya Tanjo" . "ttanjo@gmail.com")) (:maintainer "Tomoya Tanjo" . "ttanjo@gmail.com") (:keywords "convenience" "extensions") (:url . "https://github.com/tom-tan/hlinum-mode/"))])
+ (hmac . [(20201004 1819) ((emacs (25 1))) "Hash-based message authentication code" single ((:commit . "f2b99a9a10becfff207cf9418c6dce78364b1a4b") (:authors ("Sean McAfee")) (:maintainer "Sean McAfee") (:url . "https://github.com/grimnebulin/emacs-hmac"))])
+ (hnreader . [(20220103 1909) ((emacs (25 1)) (promise (1 1)) (request (0 3 0)) (org (9 2))) "A hackernews reader" single ((:commit . "e17006072b0cd06ab7ff32c6187e9565131a78b2") (:authors ("Thanh Vuong" . "thanhvg@gmail.com")) (:maintainer "Thanh Vuong" . "thanhvg@gmail.com") (:url . "https://github.com/thanhvg/emacs-hnreader/"))])
+ (hoa-mode . [(20200610 1339) nil "Major mode for the HOA format" single ((:commit . "18f5c981e256f867f29a93376ccdc04717b159cd") (:authors ("Alexandre Duret-Lutz" . "adl@lrde.epita.fr")) (:maintainer "Alexandre Duret-Lutz" . "adl@lrde.epita.fr") (:keywords "major-mode" "automata" "convenience") (:url . "https://gitlab.lrde.epita.fr/spot/emacs-modes"))])
+ (holiday-pascha-etc . [(20160822 58) nil "Eastern Christian analog to holiday-easter-etc" single ((:commit . "eb198656f63cb8679fb0e3a8248782df071a0f3c") (:authors ("Mark A. Hershberger" . "mah@everybody.org")) (:maintainer "Mark A. Hershberger" . "mah@everybody.org") (:url . "http://github.com/hexmode/holiday-pascha-etc"))])
+ (holy-books . [(20211025 127) ((s (1 12 0)) (dash (2 16 0)) (emacs (27 1)) (org (9 1))) "Org-mode links/tooltips/lookups for Quran & Bible" single ((:commit . "02c2956d36631d3d8c8b4bacdcf0a5cdd1f3136d") (:authors ("Musa Al-hassy" . "alhassy@gmail.com")) (:maintainer "Musa Al-hassy" . "alhassy@gmail.com") (:keywords "quran" "bible" "links" "tooltips" "convenience" "comm" "hypermedia") (:url . "https://alhassy.github.io/holy-books/"))])
+ (home-end . [(20180817 855) ((emacs (24 3)) (keypress-multi-event (1 0))) "Smart multi-purpose home / end keys" single ((:commit . "fbddad2c1268720ce17662a232b48f666e489526") (:authors ("Boruch Baum" . "boruch_baum@gmx.com")) (:maintainer "Boruch Baum" . "boruch_baum@gmx.com") (:keywords "abbrev" "convenience" "wp" "keyboard") (:url . "https://www.github.com/Boruch_Baum/emacs-home-end"))])
+ (homebrew-mode . [(20210919 331) ((emacs (24 4)) (inf-ruby (2 4 0)) (dash (1 2 0))) "minor mode for editing Homebrew formulae" single ((:commit . "8c630c6f768b942a86a10750f720abc64a817cd0") (:authors ("Alex Dunn" . "dunn.alex@gmail.com")) (:maintainer "Alex Dunn" . "dunn.alex@gmail.com") (:keywords "homebrew" "brew" "ruby") (:url . "https://github.com/dunn/homebrew-mode"))])
+ (honcho . [(20190623 2120) ((emacs (25 1)) (sudo-edit (0 1))) "Run and manage long-running services" single ((:commit . "d5e6206dd23ff9305d976c52845c750a064aca4b") (:authors ("Mario Rodas" . "marsam@users.noreply.github.com")) (:maintainer "Mario Rodas" . "marsam@users.noreply.github.com") (:keywords "convenience") (:url . "https://github.com/emacs-pe/honcho.el"))])
+ (hookify . [(20141216 2209) ((s (1 9 0)) (dash (1 5 0))) "Interactive commands to create temporary hooks" single ((:commit . "21baae7393b07257de5796402fde0ca72fb00d77") (:authors ("Philippe Vaucher" . "philippe.vaucher@gmail.com")) (:maintainer "Philippe Vaucher" . "philippe.vaucher@gmail.com") (:keywords "hook" "convenience") (:url . "https://github.com/Silex/hookify"))])
+ (horizon-theme . [(20200720 1832) ((emacs (24 3))) "A beautifully warm dual theme" single ((:commit . "9595549c514a9376c61d5d303405f6a6982e9e46") (:url . "https://github.com/aodhneine/horizon-theme.el"))])
+ (horoscope . [(20180409 641) ((emacs (24))) "generate horoscopes." single ((:commit . "f4c683e991adce0a8f9023f15050f306f9b9a9ed") (:authors ("Bob Manson" . "manson@cygnus.com")) (:maintainer "Noah Friedman" . "friedman@prep.ai.mit.edu") (:keywords "extensions" "games") (:url . "https://github.com/mschuldt/horoscope.el"))])
+ (hotfuzz . [(20210924 936) ((emacs (27 1))) "Fuzzy completion style" single ((:commit . "95a1be449624aa2b25128b900b6211034d0e17bb") (:authors ("Axel Forsman" . "axelsfor@gmail.com")) (:maintainer "Axel Forsman" . "axelsfor@gmail.com") (:keywords "matching") (:url . "https://github.com/axelf4/hotfuzz"))])
+ (hound . [(20200122 1700) ((request (0 2 0)) (cl-lib (0 5))) "Display hound search results in a compilation window" single ((:commit . "35e2cdc81fcc904b450a7ef3ec00fd25df6a4431") (:authors ("Ryan Young")) (:maintainer "Ryan Young"))])
+ (hover . [(20220129 1935) ((emacs (25 2)) (dash (2 14 1))) "Package to use hover with flutter" single ((:commit . "4ca0638a14a8b304ac2b46e7b342b8d8732ad199") (:authors ("Eric Dallo")) (:maintainer "Eric Dallo") (:keywords "hover" "flutter" "mobile" "tools") (:url . "https://github.com/ericdallo/hover.el"))])
+ (howdoi . [(20150204 43) nil "Instant coding answers via Emacs." tar ((:commit . "5fbf7069ee160c597a328e5ce5fb32920e1ca88f") (:authors ("Andrey Tykhonov <atykhonov at gmail.com>")) (:maintainer "Andrey Tykhonov" . "atykhonov@gmail.com") (:keywords "howdoi" "convenience") (:url . "https://github.com/atykhonov/emacs-howdoi/"))])
+ (howdoyou . [(20210909 2000) ((emacs (25 1)) (promise (1 1)) (request (0 3 3)) (org (9 2))) "A stackoverflow and its sisters' sites reader" single ((:commit . "a01971a7279c8a031de78513c004d7a09d293712") (:authors ("Thanh Vuong" . "thanhvg@gmail.com")) (:maintainer "Thanh Vuong" . "thanhvg@gmail.com") (:url . "https://github.com/thanhvg/howdoyou/"))])
+ (howm . [(20211230 1221) ((cl-lib (0 5))) "Wiki-like note-taking tool" tar ((:commit . "c381e50f0c771c38306bda37bd972a37a36a5db5") (:authors ("HIRAOKA Kazuyuki" . "khi@users.osdn.me")) (:maintainer "HIRAOKA Kazuyuki" . "khi@users.osdn.me") (:url . "https://howm.osdn.jp"))])
+ (hsluv . [(20181127 1206) ((seq (2 20))) "hsluv color space conversions" single ((:commit . "c3bc5228e30d66e7dee9ff1a0694c2b976862fc0") (:authors ("Geert Vermeiren")) (:maintainer "Geert Vermeiren") (:keywords "color" "hsluv") (:url . "https://github.com/hsluv/hsluv-emacs"))])
+ (ht . [(20210119 741) ((dash (2 12 0))) "The missing hash table library for Emacs" single ((:commit . "c4c1be487d6ecb353d07881526db05d7fc90ea87") (:authors ("Wilfred Hughes" . "me@wilfred.me.uk")) (:maintainer "Wilfred Hughes" . "me@wilfred.me.uk") (:keywords "hash table" "hash map" "hash"))])
+ (html-check-frag . [(20201106 1748) ((emacs (24 3))) "Check html-fragments" single ((:commit . "b9d1f2003a126c2e8b6d469964ec2278ad55c9df") (:authors ("Tobias.Zawada" . "i@tn-home.de")) (:maintainer "Tobias.Zawada" . "i@tn-home.de") (:keywords "html"))])
+ (html-script-src . [(20120403 1815) nil "Insert <script src=\"..\"> for popular JavaScript libraries" single ((:commit . "66460f8ab1b24656e6f3ce5bd50cff6a81be8422") (:authors ("Johan Andersson" . "johan.rejeep@gmail.com")) (:maintainer "Johan Andersson" . "johan.rejeep@gmail.com") (:keywords "tools" "convenience") (:url . "http://github.com/rejeep/html-script-src"))])
+ (html-to-hiccup . [(20211129 944) ((emacs (25 1)) (dash (2 13 0)) (s (1 10 0))) "Convert HTML to Hiccup syntax" single ((:commit . "97ecc8cce11f577ad4406da0367aa5eeec1bd8c6") (:authors ("Arne Brasseur" . "arne@arnebrasseur.net")) (:maintainer "Arne Brasseur" . "arne@arnebrasseur.net") (:keywords "html" "hiccup" "clojure") (:url . "https://github.com/plexus/html-to-hiccup"))])
+ (html-to-markdown . [(20151105 840) ((cl-lib (0 5))) "HTML to Markdown converter written in Emacs-lisp." single ((:commit . "60c5498c801be186478cf7c05be05b4430c4a144") (:authors ("Artur Malabarba" . "bruce.connor.am@gmail.com")) (:maintainer "Artur Malabarba" . "bruce.connor.am@gmail.com") (:keywords "tools" "wp" "languages") (:url . "http://github.com/Bruce-Connor/html-to-markdown"))])
+ (html2org . [(20170418 501) ((emacs (24 4))) "Convert html to org format text" single ((:commit . "6904aed40259ad8afccff079ebd8a07bff319ebc") (:authors ("DarkSun" . "lujun9972@gmail.com")) (:maintainer "DarkSun" . "lujun9972@gmail.com") (:keywords "convenience" "html" "org") (:url . "http://github.com/lujun9972/html2org.el"))])
+ (htmlize . [(20210825 2150) nil "Convert buffer text and decorations to HTML." single ((:commit . "dd27bc3f26efd728f2b1f01f9e4ac4f61f2ffbf9") (:authors ("Hrvoje Niksic" . "hniksic@gmail.com")) (:maintainer "Hrvoje Niksic" . "hniksic@gmail.com") (:keywords "hypermedia" "extensions") (:url . "https://github.com/hniksic/emacs-htmlize"))])
+ (htmltagwrap . [(20200929 559) ((emacs (24 4))) "Wraps a chunk of HTML code in tags" single ((:commit . "049efcadbd9b51a601cca60fc78616bcef0799ae") (:authors ("Shen, Jen-Chieh" . "jcs090218@gmail.com")) (:maintainer "Shen, Jen-Chieh" . "jcs090218@gmail.com") (:url . "https://github.com/jcs-elpa/htmltagwrap"))])
+ (http . [(20201010 920) ((emacs (24 4)) (request (0 2 0)) (edit-indirect (0 1 4))) "Yet another HTTP client" single ((:commit . "5fdceed1fbf36e274e578e349a53ce922c574774") (:authors ("Mario Rodas" . "marsam@users.noreply.github.com")) (:maintainer "Mario Rodas" . "marsam@users.noreply.github.com") (:keywords "convenience") (:url . "https://github.com/emacs-pe/http.el"))])
+ (http-post-simple . [(20170715 940) nil "HTTP POST requests using the url library" single ((:commit . "f53697fca278c741051aeb668b00466b5e0fd3fe") (:authors ("Tom Schutzer-Weissmann")) (:maintainer "Tom Schutzer-Weissmann") (:keywords "comm" "data" "processes" "hypermedia"))])
+ (http-twiddle . [(20160801 1911) nil "send & twiddle & resend HTTP requests" single ((:commit . "4d0c73b7dcbde8b483d4f3a75c49c74d2fe3ca45") (:authors ("Luke Gorrie" . "luke@synap.se")) (:maintainer "Hasan Veldstra" . "h@vidiowiki.com") (:keywords "http" "rest" "soap") (:url . "https://github.com/hassy/http-twiddle/blob/master/http-twiddle.el"))])
+ (httpcode . [(20121002 345) nil "explains the meaning of an HTTP status code" single ((:commit . "a45e735082b09477cd704a99294d336cdbeb12ba") (:authors ("Ruslan Spivak" . "ruslan.spivak@gmail.com")) (:maintainer "Ruslan Spivak" . "ruslan.spivak@gmail.com") (:url . "http://github.com/rspivak/httpcode.el"))])
+ (httprepl . [(20141101 1734) ((s (1 9 0)) (dash (2 5 0)) (emacs (24))) "An HTTP REPL" single ((:commit . "cfa3693267a8ed1c96a86a126823f37dbfe077d8") (:authors ("Greg Sexton" . "gregsexton@gmail.com")) (:maintainer "Greg Sexton" . "gregsexton@gmail.com") (:keywords "http" "repl") (:url . "https://github.com/gregsexton/httprepl.el"))])
+ (huecycle . [(20210830 340) ((emacs (27 1))) "Idle color animation" single ((:commit . "a05e32351dcff3e61b5f15800556adfe1939c112") (:authors ("Phillip O'Reggio <https://github.com/pnor>")) (:maintainer "Phillip O'Reggio") (:keywords "faces") (:url . "https://github.com/pnor/huecycle"))])
+ (hugsql-ghosts . [(20211124 1646) ((s (1 9 0)) (dash (2 10 0)) (cider (0 14 0))) "Display hugsql defqueries in clojure code as an overlay" single ((:commit . "7cd242cc2e70ac48959c42be725c81d7fe00b314") (:authors ("Roland Kaercher" . "roland.kaercher@gmail.com")) (:maintainer "Roland Kaercher" . "roland.kaercher@gmail.com") (:url . "https://github.com/rkaercher/hugsql-ghosts"))])
+ (humanoid-themes . [(20220305 930) ((emacs (24 3))) "Color themes with a dark and light variant" tar ((:commit . "5828705bcc3eab9af9dd36fd7dc96d48c3020d85") (:authors ("Thomas Friese")) (:maintainer "Thomas Friese") (:keywords "faces" "color" "theme") (:url . "https://github.com/humanoid-colors/emacs-humanoid-themes"))])
+ (hungarian-holidays . [(20161020 1138) nil "Adds a list of Hungarian public holidays to Emacs calendar" single ((:commit . "653108769279499d84a79267c90e640d98823872") (:authors ("Gergely Polonkai" . "gergely@polonkai.eu")) (:maintainer "Gergely Polonkai" . "gergely@polonkai.eu") (:keywords "calendar"))])
+ (hungry-delete . [(20210409 1643) nil "hungry delete minor mode" single ((:commit . "d919e555e5c13a2edf4570f3ceec84f0ade71657") (:authors ("Nathaniel Flath" . "flat0103@gmail.com")) (:maintainer "Nathaniel Flath" . "flat0103@gmail.com") (:url . "http://github.com/nflath/hungry-delete"))])
+ (hy-mode . [(20211016 2011) ((dash (2 18 0)) (s (1 11 0)) (emacs (24))) "Major mode for Hylang" tar ((:commit . "df814865a1faa8414dacdbb35b2a9029995312ec") (:keywords "languages" "lisp" "python") (:url . "http://github.com/hylang/hy-mode"))])
+ (hyai . [(20170301 1447) ((cl-lib (0 5)) (emacs (24))) "Haskell Yet Another Indentation" single ((:commit . "9efad2ac6a57059b3be624588f649e276a96fdd4") (:authors ("Iku Iwasa" . "iku.iwasa@gmail.com")) (:maintainer "Iku Iwasa" . "iku.iwasa@gmail.com") (:url . "https://github.com/iquiw/hyai"))])
+ (hybrid-reverse-theme . [(20210806 1955) ((emacs (24 1))) "Emacs theme with material color scheme" single ((:commit . "cb784a69e60938efe14b48130558f1bb1af92d3c") (:authors ("Riyyi")) (:maintainer "Riyyi") (:keywords "faces" "theme") (:url . "https://github.com/riyyi/emacs-hybrid-reverse"))])
+ (hydandata-light-theme . [(20190809 1925) nil "A light color theme that is easy on your eyes" single ((:commit . "180c3797fa7ef3e4bb679baaf5b492c33bbb9b8b") (:authors ("David Chkhikvadze" . "david@chkhd.net")) (:maintainer "David Chkhikvadze" . "david@chkhd.net") (:keywords "color-theme" "theme") (:url . "https://github.com/chkhd/hydandata-light-theme"))])
+ (hyde . [(20160508 308) nil "Major mode to help create and manage Jekyll blogs" tar ((:commit . "a8cd6ed00ecd8d7de0ded2f4867015b412b15b76"))])
+ (hydra . [(20220102 803) ((cl-lib (0 5)) (lv (0))) "Make bindings that stick around." tar ((:commit . "9e9e00cb240ea1903ffd36a54956b3902c379d29") (:authors ("Oleh Krehel" . "ohwoeowho@gmail.com")) (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com") (:keywords "bindings") (:url . "https://github.com/abo-abo/hydra"))])
+ (hyperkitty . [(20220226 1951) ((request (0 3 2)) (emacs (25 1))) "Emacs interface for Hyperkitty archives" single ((:commit . "2c1d22ff017d096c359aa151e6a29f7214a58118") (:authors ("Abhilash Raj" . "maxking@asynchronous.in")) (:maintainer "Abhilash Raj" . "maxking@asynchronous.in") (:keywords "mail" "hyperkitty" "mailman") (:url . "https://github.com/maxking/hyperkitty.el"))])
+ (hyperlist-mode . [(20200515 2209) ((emacs (24))) "A major-mode for viewing Hyperlists" single ((:commit . "374cdc04761df23e7a50ca276319ba9745cda9d7") (:authors ("Wojciech Siewierski")) (:maintainer "Wojciech Siewierski") (:keywords "outlines") (:url . "https://github.com/vifon/hyperlist-mode"))])
+ (hyperspace . [(20210603 1825) ((emacs (25)) (s (1 12 0))) "Get there from here" single ((:commit . "c4c363c140250ba6b775516082063878975a6154") (:authors ("Ian Eure" . "ian@retrospec.tv")) (:maintainer "Ian Eure" . "ian@retrospec.tv") (:keywords "tools" "convenience") (:url . "https://github.com/ieure/hyperspace-el"))])
+ (i-ching . [(20211112 1528) ((emacs (25 1)) (request (0 3))) "The Book of Changes" tar ((:commit . "992f53ae2bd572b89bc642ca70b8bdaa5eb2553f") (:authors ("nik gaffney" . "nik@fo.am")) (:maintainer "nik gaffney" . "nik@fo.am") (:keywords "games" "divination" "stochastism" "cleromancy" "change") (:url . "https://github.com/zzkt/i-ching"))])
+ (i2b2-mode . [(20140710 104) nil "Highlights corresponding PHI data in the text portion of an i2b2 XML Document." single ((:commit . "db10efcfc8bed369a516bbf7526ede41f98cb95a") (:authors ("Dan LaManna" . "dan.lamanna@gmail.com")) (:maintainer "Dan LaManna" . "dan.lamanna@gmail.com") (:keywords "xml" "phi" "i2b2" "deidi2b2"))])
+ (i3wm . [(20170822 1438) nil "i3wm integration library" single ((:commit . "71391dc61063fee77ad174f3b2ca25c60b41009e") (:authors ("Samuel W. Flint" . "swflint@flintfam.org")) (:maintainer "Samuel W. Flint" . "swflint@flintfam.org") (:keywords "convenience" "extensions") (:url . "https://git.flintfam.org/swf-projects/emacs-i3"))])
+ (i3wm-config-mode . [(20201105 2022) ((emacs (24 1))) "Better syntax highlighting for i3wm's config file" single ((:commit . "c70bdc1367e461299e13a4797bc9d9d950184edd") (:authors ("Alexander Miller" . "alexanderm@web.de")) (:maintainer "Alexander Miller" . "alexanderm@web.de") (:keywords "faces" "languages" "i3wm" "font-lock") (:url . "https://github.com/Alexander-Miller/i3wm-Config-Mode"))])
+ (ialign . [(20200711 1117) ((emacs (24 4))) "visual align-regexp" single ((:commit . "eca40b8b59ea713dba21b18f5b047a6c086b91dc") (:authors ("Michał Krzywkowski" . "k.michal@zoho.com")) (:maintainer "Michał Krzywkowski" . "k.michal@zoho.com") (:keywords "tools" "editing" "align" "interactive") (:url . "https://github.com/mkcms/interactive-align"))])
+ (iasm-mode . [(20171023 1422) nil "interactive assembly major mode." single ((:commit . "abbec7f308f9ce97beeb57e459fff35f559b4c18") (:authors ("Rémi Attab" . "remi.attab@gmail.com")) (:maintainer "Rémi Attab" . "remi.attab@gmail.com") (:keywords ":" "tools") (:url . "https://github.com/RAttab/iasm-mode"))])
+ (ibuffer-git . [(20110508 731) nil "show git status in ibuffer column" single ((:commit . "d326319c05ddb8280885b31f9094040c1b365876") (:authors ("Jonathan Rockway" . "jon@jrock.us")) (:maintainer "Jonathan Rockway" . "jon@jrock.us") (:keywords "convenience"))])
+ (ibuffer-project . [(20220321 1312) ((emacs (25 1))) "Group ibuffer's list by project or any function" single ((:commit . "bfc0ec1f27b02b8ab816dcfd9073e5d78dae1aed") (:authors ("Andrii Kolomoiets" . "andreyk.mad@gmail.com")) (:maintainer "Andrii Kolomoiets" . "andreyk.mad@gmail.com") (:keywords "tools") (:url . "https://github.com/muffinmad/emacs-ibuffer-project"))])
+ (ibuffer-projectile . [(20200805 604) ((projectile (0 11 0)) (emacs (24 1))) "Group ibuffer's list by projectile root" single ((:commit . "ecbe482804a217b1471593f6c7a8b3d64f3cdc47") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:keywords "convenience") (:url . "https://github.com/purcell/ibuffer-projectile"))])
+ (ibuffer-rcirc . [(20150215 2118) ((cl-lib (0 2))) "Ibuffer integration for rcirc" single ((:commit . "8a4409b1c679d65c819dee4085faf929840e79f8") (:authors ("Fabián Ezequiel Gallina" . "fgallina@gnu.org")) (:maintainer "Fabián Ezequiel Gallina" . "fgallina@gnu.org") (:keywords "buffer" "convenience" "comm") (:url . "https://github.com/fgallina/ibuffer-rcirc"))])
+ (ibuffer-sidebar . [(20210508 836) ((emacs (25 1))) "Sidebar for `ibuffer'" single ((:commit . "fb685e1e43db979e25713081d8ae4073453bbd5e") (:authors ("James Nguyen" . "james@jojojames.com")) (:maintainer "James Nguyen" . "james@jojojames.com") (:keywords "ibuffer" "files" "tools") (:url . "https://github.com/jojojames/ibuffer-sidebar"))])
+ (ibuffer-tramp . [(20151118 1739) nil "Group ibuffer's list by TRAMP connection" single ((:commit . "bcad0bda3a67f55d1be936bf8fa9ef735fe1e3f3") (:authors ("Svend Sorensen" . "svend@ciffer.net")) (:maintainer "Svend Sorensen" . "svend@ciffer.net") (:keywords "convenience") (:url . "http://github.com/svend/ibuffer-tramp"))])
+ (ibuffer-vc . [(20200805 604) ((emacs (24 1)) (cl-lib (0 2))) "Group ibuffer's list by VC project, or show VC status" single ((:commit . "5fa6aea09bc67f71ea743302d609f459967b1e81") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:keywords "convenience") (:url . "https://github.com/purcell/ibuffer-vc"))])
+ (iceberg-theme . [(20200812 943) ((emacs (26 1)) (solarized-theme (1 3))) "Well-designed, eye-friendly, dark blue color scheme" single ((:commit . "183b41eae07d94d4a8f299306078410bddc41d34") (:authors ("Naoya Yamashita" . "conao3@gmail.com")) (:maintainer "Naoya Yamashita" . "conao3@gmail.com") (:keywords "convenience") (:url . "https://github.com/conao3/iceberg-theme.el"))])
+ (icomplete-vertical . [(20220418 2119) ((emacs (26 1))) "Display icomplete candidates vertically" tar ((:commit . "f5775d535630199703c936380d210d38249b342c") (:authors ("Omar Antolín Camarena" . "omar@matem.unam.mx")) (:maintainer "Omar Antolín Camarena" . "omar@matem.unam.mx") (:keywords "convenience" "completion") (:url . "https://github.com/oantolin/icomplete-vertical"))])
+ (icsql . [(20210612 1340) ((emacs (26)) (choice-program (0 13)) (buffer-manage (0 12))) "Interactive iSQL iteraface to ciSQL" single ((:commit . "4521e9d2debef7687bfd26a664479f0c46688a36") (:authors ("Paul Landes")) (:maintainer "Paul Landes") (:keywords "isql" "sql" "rdbms" "data") (:url . "https://github.com/plandes/icsql"))])
+ (id-manager . [(20170320 1246) nil "id-password management" single ((:commit . "14ebc35db298aac4dedc8aa188bc46bacab81f3b") (:authors ("SAKURAI Masashi <m.sakurai atmark kiwanami.net>")) (:maintainer "SAKURAI Masashi <m.sakurai atmark kiwanami.net>") (:keywords "password" "convenience"))])
+ (idea-darkula-theme . [(20160416 2303) ((emacs (24 1))) "Color theme based on IntelliJ IDEA Darkula color theme" single ((:commit . "52602d9b91883e1f297d000951aeed48bf60176e") (:authors ("Alexey Veretennikov <alexey dot veretennikov at gmail dot com>")) (:maintainer "Alexey Veretennikov <alexey dot veretennikov at gmail dot com>") (:keywords "themes") (:url . "http://github.com/fourier/idea-darkula-theme"))])
+ (identica-mode . [(20130204 2253) nil "Major mode API client for status.net open microblogging" tar ((:commit . "cf9183ee11ac922e85c7c908f04e2d00b03111b3") (:authors ("Gabriel Saldana" . "gsaldana@gmail.com")) (:maintainer "Gabriel Saldana" . "gsaldana@gmail.com") (:keywords "identica" "web") (:url . "http://blog.gabrielsaldana.org/identica-mode-for-emacs/"))])
+ (idle-highlight-in-visible-buffers-mode . [(20181027 1531) nil "highlight the word the point is on" single ((:commit . "8d8de309d5bd4b035c01bf7f0cfc6e079c79d898") (:authors ("Ignacy Moryc")) (:maintainer "Ignacy Moryc") (:keywords "convenience") (:url . "https://github.com/ignacy/idle-highlight-in-visible-buffers"))])
+ (idle-highlight-mode . [(20220211 548) ((emacs (27 1))) "Highlight the word the point is on" single ((:commit . "0a24f8e402383b0da1f956d946781317fba14bbc") (:authors ("Phil Hagelberg, Cornelius Mika, Campbell Barton")) (:maintainer "Phil Hagelberg, Cornelius Mika, Campbell Barton") (:keywords "convenience") (:url . "https://gitlab.com/ideasman42/emacs-idle-highlight-mode"))])
+ (idle-org-agenda . [(20190106 1844) nil "Shows your agenda when editor is idle." single ((:commit . "8e6052fc4923c30132052d67d794b76c92851c20") (:authors ("John Wiegley" . "jwiegley@gmail.com")) (:maintainer "Enis Özgen" . "mail@enisozgen.com") (:keywords "org" "org-mode" "org-agenda" "calendar") (:url . "https://github.com/enisozgen/idle-org-agenda"))])
+ (idle-require . [(20090715 2203) nil "load elisp libraries while Emacs is idle" single ((:commit . "33592bb098223b4432d7a35a1d65ab83f47c1ec1") (:authors ("Nikolaj Schumacher <bugs * nschum de>")) (:maintainer "Nikolaj Schumacher <bugs * nschum de>") (:keywords "internal") (:url . "http://nschum.de/src/emacs/idle-require/"))])
+ (ido-at-point . [(20151021 757) ((emacs (24))) "ido-style completion-at-point" single ((:commit . "e5907bbe8a3d148d07698b76bd994dc3076e16ee") (:authors ("katspaugh")) (:maintainer "katspaugh") (:keywords "convenience" "abbrev") (:url . "https://github.com/katspaugh/ido-at-point"))])
+ (ido-complete-space-or-hyphen . [(20210206 1505) nil "Allow spaces to also match hyphens in ido" single ((:commit . "d1244243e042b8d5b6b991db752a17a44ea169bc") (:authors ("Ryan C. Thompson" . "rct@thompsonclan.org") ("Ian Yang <me (at) iany.me>")) (:maintainer "Ryan C. Thompson" . "rct@thompsonclan.org") (:keywords "ido" "completion" "convenience") (:url . "https://github.com/DarwinAwardWinner/ido-complete-space-or-hyphen"))])
+ (ido-completing-read+ . [(20210529 1318) ((emacs (24 4)) (seq (0 5)) (memoize (1 1))) "A completing-read-function using ido" single ((:commit . "49e7967ea8c0ab0a206b40d70fc19be115083fa1") (:authors ("Ryan C. Thompson" . "rct@thompsonclan.org")) (:maintainer "Ryan C. Thompson" . "rct@thompsonclan.org") (:keywords "ido" "completion" "convenience") (:url . "https://github.com/DarwinAwardWinner/ido-completing-read-plus"))])
+ (ido-exit-target . [(20170717 1851) ((emacs (24 4))) "Commands and keys for selecting other window and frame targets within ido" single ((:commit . "e56fc6928649c87ccf39d56d84ab53ebaced1f73") (:authors ("justin talbott" . "justin@waymondo.com")) (:maintainer "justin talbott" . "justin@waymondo.com") (:keywords "convenience" "tools" "extensions") (:url . "https://github.com/waymondo/ido-exit-target"))])
+ (ido-flex-with-migemo . [(20190408 350) ((flx-ido (0 6 1)) (migemo (1 9 1)) (emacs (24 4))) "use ido with flex and migemo" single ((:commit . "da64f2fe3849492d35e155d81a817308a4853473") (:authors ("ROCKTAKEY " . "rocktakey@gmail.com")) (:maintainer "ROCKTAKEY " . "rocktakey@gmail.com") (:keywords "matching") (:url . "https://github.com/ROCKTAKEY/ido-flex-with-migemo"))])
+ (ido-gnus . [(20140216 1646) ((gnus (5 13))) "Access gnus groups or servers using ido" single ((:commit . "f5fe3f6aa8086f675ba216abace9e3d5f2e3a089") (:authors ("Joe Bloggs" . "vapniks@yahoo.com")) (:maintainer "Joe Bloggs" . "vapniks@yahoo.com") (:keywords "comm") (:url . "https://github.com/vapniks/ido-gnus"))])
+ (ido-grid-mode . [(20160122 1139) ((emacs (24 4))) "Display ido-prospects in the minibuffer in a grid." single ((:commit . "7cfca3988a6dc3ad18e28abe114218095ff2366f") (:authors ("Tom Hinton")) (:maintainer "Tom Hinton" . "t@larkery.com") (:keywords "convenience") (:url . "https://github.com/larkery/ido-grid-mode.el"))])
+ (ido-hacks . [(20190206 2153) nil "Put more IDO in your IDO" single ((:commit . "d2153a3e8d23436ee07ecae2a106f434361a10c5") (:authors ("Andreas Politz")) (:maintainer "Scott Jaderholm" . "jaderholm@gmail.com") (:keywords "convenience"))])
+ (ido-load-library . [(20140611 1600) ((persistent-soft (0 8 8)) (pcache (0 2 3))) "Load-library alternative using ido-completing-read" single ((:commit . "e03b55957c93aa1a7dd190e173e16ec59dbb2ba7") (:authors ("Roland Walker" . "walker@pobox.com")) (:maintainer "Roland Walker" . "walker@pobox.com") (:keywords "maint" "completion") (:url . "http://github.com/rolandwalker/ido-load-library"))])
+ (ido-migemo . [(20191017 1919) ((migemo (1 9 1))) "Migemo plug-in for Ido" single ((:commit . "09a2cc175b500cab7655a25ffc982e78d46ca669") (:authors ("myuhe <yuhei.maeda_at_gmail.com>")) (:maintainer "myuhe") (:keywords "files") (:url . "https://github.com/myuhe/ido-migemo.el"))])
+ (ido-occasional . [(20150214 1248) ((emacs (24 1))) "Use ido where you choose." single ((:commit . "d405f1795e1e0c63be411ee2825184738d29c33a") (:authors ("Oleh Krehel" . "ohwoeowho@gmail.com")) (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com") (:keywords "completion") (:url . "https://github.com/abo-abo/ido-occasional"))])
+ (ido-select-window . [(20131220 2047) ((emacs (24 1))) "Select a window using ido and buffer names" single ((:commit . "a64707d8d154664d50d12e26417d586e4c3dd78b") (:authors ("Peter Jones" . "pjones@devalot.com")) (:maintainer "Peter Jones" . "pjones@devalot.com") (:url . "https://github.com/pjones/ido-select-window"))])
+ (ido-skk . [(20151111 950) ((emacs (24 4)) (ddskk (20150912 1820))) "ido interface for skk henkan" single ((:commit . "89a2e62799bff2841ff634517c86084c4ce69246") (:authors ("tsukimizake <shomasd_at_gmail.com>")) (:maintainer "tsukimizake <shomasd_at_gmail.com>") (:keywords "languages") (:url . "https://github.com/tsukimizake/ido-skk"))])
+ (ido-sort-mtime . [(20171121 859) nil "Sort Ido's file list by modification time" single ((:commit . "f638ff0c922af862f5211779f2311a27fde428eb") (:authors ("Paweł Kraśnicki")) (:maintainer "Paweł Kraśnicki") (:keywords "convenience" "files"))])
+ (ido-springboard . [(20170106 755) nil "Temporarily change default-directory for one command" single ((:commit . "687d1e5898a880878995dc9bffe93b4598366203") (:authors ("John Wiegley" . "jwiegley@gmail.com")) (:maintainer "John Wiegley" . "jwiegley@gmail.com") (:keywords "ido") (:url . "https://github.com/jwiegley/springboard"))])
+ (ido-vertical-mode . [(20210205 436) ((emacs (24 4))) "Makes ido-mode display vertically" single ((:commit . "b1659e967da0687abceca733b389ace24004fa66") (:authors ("Steven Degutis")) (:maintainer "Christopher Reichert" . "creichert07@gmail.com") (:keywords "convenience") (:url . "https://github.com/creichert/ido-vertical-mode.el"))])
+ (ido-yes-or-no . [(20161108 2351) ((ido-completing-read+ (0))) "Use Ido to answer yes-or-no questions" single ((:commit . "c55383b1fce5879e87e7ca6809fc60534508e182") (:authors ("Ryan C. Thompson")) (:maintainer "Ryan C. Thompson") (:keywords "convenience" "completion" "ido") (:url . "https://github.com/DarwinAwardWinner/ido-yes-or-no"))])
+ (idomenu . [(20141123 2120) nil "imenu tag selection a la ido" single ((:commit . "4b0152d606360c70204fb4c27f68de79ca885386") (:authors ("Georg Brandl" . "georg@python.org")) (:maintainer "Georg Brandl" . "georg@python.org"))])
+ (idris-mode . [(20220105 1300) ((emacs (24)) (prop-menu (0 1)) (cl-lib (0 5))) "Major mode for editing Idris code" tar ((:commit . "65d6db1b7574ceccd3d97eee3790c2f74aa9724d") (:keywords "languages") (:url . "https://github.com/idris-hackers/idris-mode"))])
+ (ids-edit . [(20170818 1502) ((emacs (24 3))) "IDS (Ideographic Description Sequence) editing tool" tar ((:commit . "8562a6cbfb3f2d44bc6f62ab15081a80f8fee502") (:authors ("KAWABATA, Taichi <kawabata.taichi_at_gmail.com>")) (:maintainer "KAWABATA, Taichi <kawabata.taichi_at_gmail.com>") (:keywords "i18n" "wp") (:url . "http://github.com/kawabata/ids-edit"))])
+ (iedit . [(20220216 717) nil "Edit multiple regions in the same way simultaneously." tar ((:commit . "27c61866b1b9b8d77629ac702e5f48e67dfe0d3b") (:authors ("Victor Ren" . "victorhge@gmail.com")) (:maintainer "Victor Ren" . "victorhge@gmail.com") (:keywords "occurrence" "region" "simultaneous" "refactoring") (:url . "https://github.com/victorhge/iedit"))])
+ (ietf-docs . [(20190420 851) nil "Fetch, Cache and Load IETF documents" single ((:commit . "ae157549eae5ec78dcbf215c2f48cb662b73abd0") (:authors ("Christian E. Hopps" . "chopps@gmail.com")) (:maintainer "Christian E. Hopps" . "chopps@gmail.com") (:keywords "ietf" "rfc") (:url . "https://github.com/choppsv1/ietf-docs"))])
+ (iflipb . [(20210907 1717) nil "Interactively flip between recently visited buffers" single ((:commit . "2854e73cebb463007b686a784b66242999c3366b") (:authors ("Joel Rosdahl" . "joel@rosdahl.net")) (:maintainer "Joel Rosdahl" . "joel@rosdahl.net") (:url . "https://github.com/jrosdahl/iflipb"))])
+ (ignoramus . [(20210515 1422) ((emacs (24 3))) "Ignore backups, build files, et al." single ((:commit . "e509e134eeb81617414e5381b610108c967dbc45") (:authors ("Roland Walker" . "walker@pobox.com")) (:maintainer "Roland Walker" . "walker@pobox.com") (:keywords "convenience" "tools") (:url . "http://github.com/rolandwalker/ignoramus"))])
+ (igv . [(20141210 1227) nil "Control Integrative Genomic Viewer within Emacs" single ((:commit . "47ac6ceede252f451348a2c696398c0cb5279555") (:authors ("Stefano Barbi" . "stefanobarbi@gmail.com")) (:maintainer "Stefano Barbi" . "stefanobarbi@gmail.com"))])
+ (image+ . [(20150707 1616) ((cl-lib (0 3))) "Image manipulate extensions for Emacs" single ((:commit . "6834d0c09bb4df9ecc0d7a559bd7827fed48fffc") (:authors ("Masahiro Hayashi" . "mhayashi1120@gmail.com")) (:maintainer "Masahiro Hayashi" . "mhayashi1120@gmail.com") (:keywords "multimedia" "extensions") (:url . "https://github.com/mhayashi1120/Emacs-imagex"))])
+ (image-archive . [(20150621 132) ((emacs (24)) (cl-lib (0 5))) "Image thumbnails in archive file with non-blocking" single ((:commit . "8d29535bd832329ffeeac780aae7aa8919af1175") (:authors ("Masahiro Hayashi" . "mhayashi1120@gmail.com")) (:maintainer "Masahiro Hayashi" . "mhayashi1120@gmail.com") (:keywords "multimedia") (:url . "https://github.com/mhayashi1120/Emacs-image-archive"))])
+ (image-dired+ . [(20150430 544) ((cl-lib (0 3))) "Image-dired extensions" single ((:commit . "b68094625d963056ad64e0e44af0e2266b2eadc7") (:authors ("Masahiro Hayashi" . "mhayashi1120@gmail.com")) (:maintainer "Masahiro Hayashi" . "mhayashi1120@gmail.com") (:keywords "extensions" "multimedia") (:url . "https://github.com/mhayashi1120/Emacs-image-diredx"))])
+ (imakado . [(20141024 923) nil "imakado's usefull macros and functions" single ((:commit . "00a1e7eea2cb9e9066343a23927d6c747707902f") (:authors ("imakado <ken.imakado_at_gmail.com>")) (:maintainer "imakado") (:keywords "convenience") (:url . "https://github.com/imakado/emacs-imakado"))])
+ (imake . [(20220422 1611) ((emacs (25 1)) (compat (28 1 1 0))) "Simple, opinionated make target runner" single ((:commit . "51aeac9f3a24f23d063f591066675d1d70dcea09") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:keywords "convenience") (:url . "https://github.com/tarsius/imake"))])
+ (imapfilter . [(20180318 2027) nil "run the imapfilter executable" single ((:commit . "79bbbe918319bc1e8f42a0bef53dc7c77fe868ea") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:keywords "mail") (:url . "https://github.com/tarsius/imapfilter"))])
+ (imbot . [(20210423 731) ((emacs (25 1))) "Automatic system input method switcher" tar ((:commit . "a90183954522876ebbf1ce96d88b80e6a31b9d34") (:keywords "convenience") (:url . "https://github.com/QiangF/imbot"))])
+ (imenu-anywhere . [(20210201 1704) ((cl-lib (0 5)) (emacs (25))) "ido/ivy/helm imenu across same mode/project/etc buffers" single ((:commit . "06ec33d79e33edf01b9118aead1eabeae8ee08b1") (:authors ("Vitalie Spinu <spinuvit.list[ aaattt ]gmail[ dot ]com>")) (:maintainer "Vitalie Spinu <spinuvit.list[ aaattt ]gmail[ dot ]com>") (:keywords "ido" "imenu" "tags") (:url . "https://github.com/vitoshka/imenu-anywhere"))])
+ (imenu-extra . [(20201229 1035) ((emacs (25 1))) "Add extra items into existing imenu items" single ((:commit . "a8d867e7cc446afcd4dc71d4f528e58d639840e1") (:authors ("Chen Bin <chenbin DOT sh AT gmail DOT com>")) (:maintainer "Chen Bin <chenbin DOT sh AT gmail DOT com>") (:keywords "convenience") (:url . "https://github.com/redguardtoo/imenu-extra"))])
+ (imenu-list . [(20210420 1200) ((emacs (24 3))) "Show imenu entries in a separate buffer" single ((:commit . "76f2335ee6f2f066d87fe4e4729219d70c9bc70d") (:authors ("Bar Magal (2015)")) (:maintainer "Bar Magal (2015)") (:url . "https://github.com/bmag/imenu-list"))])
+ (imenus . [(20200730 855) ((cl-lib (0 5))) "Imenu for multiple buffers and without subgroups" single ((:commit . "90200f5f22377903b405082eabe185447968f3e2") (:authors ("Alex Kost" . "alezost@gmail.com")) (:maintainer "Alex Kost" . "alezost@gmail.com") (:keywords "tools" "convenience") (:url . "https://github.com/alezost/imenus.el"))])
+ (imgbb . [(20180609 1649) ((emacs (24)) (request (0 3 0))) "Simple image upload client for imgbb.com" single ((:commit . "a524a46263835aa474f908827ebab4e8fa586001") (:authors ("Peter" . "craven@gmx.net")) (:maintainer "Peter" . "craven@gmx.net") (:keywords "extensions") (:url . "https://github.com/ecraven/imgbb.el"))])
+ (immaterial-theme . [(20220214 1859) ((emacs (25))) "A flexible theme based on material design principles" tar ((:commit . "ca82a1700cf7834b55ada36e53811f6effde6283") (:authors ("Peter Gardfjäll")) (:maintainer "Peter Gardfjäll") (:keywords "themes") (:url . "https://github.com/petergardfjall/emacs-immaterial-theme"))])
+ (immortal-scratch . [(20160517 2118) nil "respawn the scratch buffer when it's killed" single ((:commit . "faeab0ad6c33c74c0cbd1dfcebffaa0690de40c6") (:authors ("Jonathan Kotta" . "jpkotta@gmail.com")) (:maintainer "Jonathan Kotta" . "jpkotta@gmail.com"))])
+ (immutant-server . [(20140311 2208) nil "Run your Immutant server in Emacs" single ((:commit . "2a21e65588acb6a976f2998e30b21fdabdba4dbb") (:authors ("David Leatherman" . "leathekd@gmail.com")) (:maintainer "David Leatherman" . "leathekd@gmail.com") (:url . "http://www.github.com/leathekd/immutant-server.el"))])
+ (impatient-mode . [(20200723 2117) ((emacs (24 3)) (simple-httpd (1 5 0)) (htmlize (1 40))) "Serve buffers live over HTTP" tar ((:commit . "479a2412596ff1dbdddeb7bdbba45482ce5b230c") (:authors ("Brian Taylor" . "el.wubo@gmail.com")) (:maintainer "Brian Taylor" . "el.wubo@gmail.com") (:url . "https://github.com/netguy204/imp.el"))])
+ (impatient-showdown . [(20200914 221) ((emacs (24 3)) (impatient-mode (1 1))) "Preview markdown buffer live over HTTP using showdown" tar ((:commit . "6825147ebacb1d738b1c96baf0534a5ed3e6b289") (:authors ("Shen, Jen-Chieh" . "jcs090218@gmail.com")) (:maintainer "Shen, Jen-Chieh" . "jcs090218@gmail.com") (:url . "https://github.com/jcs-elpa/impatient-showdown"))])
+ (import-js . [(20220215 1948) ((grizzl (0 1 0)) (emacs (24))) "Import Javascript dependencies" single ((:commit . "d2bbb53f96395415f9f01de4fa88d82c1f59ba63") (:authors ("Kevin Kehl" . "kevin.kehl@gmail.com")) (:maintainer "Kevin Kehl" . "kevin.kehl@gmail.com") (:keywords "javascript") (:url . "http://github.com/Galooshi/emacs-import-js/"))])
+ (import-popwin . [(20170218 1407) ((emacs (24 3)) (popwin (0 6))) "popwin buffer near by import statements with popwin" single ((:commit . "bb05a9e226f8c63fe7b18a3e92010357049ab5ba") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-import-popwin"))])
+ (importmagic . [(20180520 303) ((f (0 11 0)) (epc (0 1 0)) (emacs (24 3))) "Fix Python imports using importmagic." tar ((:commit . "701dfcca5f3ab42be0f26a8d381d7116c79be850") (:authors ("Nicolás Salas V." . "nikosalas@gmail.com")) (:maintainer "Nicolás Salas V." . "nikosalas@gmail.com") (:keywords "languages" "convenience") (:url . "https://github.com/anachronic/importmagic.el"))])
+ (impostman . [(20220102 1856) ((emacs (27 1))) "Import Postman collections" single ((:commit . "5b122f3d5a3421aa2d89bdc9dc4aafaf19cf85d4") (:authors ("Sébastien Helleu" . "flashcode@flashtux.org")) (:maintainer "Sébastien Helleu" . "flashcode@flashtux.org") (:keywords "tools") (:url . "https://github.com/flashcode/impostman"))])
+ (indent-control . [(20220227 653) ((emacs (26 1))) "Management for indentation level" single ((:commit . "6fb6c9326077105febe2cd9c77b683b7c310cf03") (:authors ("Shen, Jen-Chieh" . "jcs090218@gmail.com")) (:maintainer "Shen, Jen-Chieh" . "jcs090218@gmail.com") (:url . "https://github.com/jcs-elpa/indent-control"))])
+ (indent-guide . [(20210115 400) nil "show vertical lines to guide indentation" single ((:commit . "d388c3387781a370ca13233ff445d03f3c5cf12f") (:authors ("zk_phi")) (:maintainer "zk_phi") (:url . "http://hins11.yu-yake.com/"))])
+ (indent-info . [(20210111 745) ((emacs (24 3))) "Show indentation information in status bar" single ((:commit . "05a787afeb9946714d8b0c724868195a678db49e") (:authors ("Terje Larsen" . "terlar@gmail.com")) (:maintainer "Terje Larsen" . "terlar@gmail.com") (:keywords "convenience" "tools") (:url . "https://github.com/terlar/indent-info.el"))])
+ (indent-lint . [(20200812 949) ((emacs (25 1)) (async-await (1 0)) (async (1 9 4))) "Async indentation checker" single ((:commit . "c55f4ded11e8e50a96f43675a071354a8fb501c3") (:authors ("Naoya Yamashita" . "conao3@gmail.com")) (:maintainer "Naoya Yamashita" . "conao3@gmail.com") (:keywords "tools") (:url . "https://github.com/conao3/indent-lint.el"))])
+ (indent-tools . [(20210622 1207) ((s (0)) (hydra (0)) (yafolding (0))) "Indent, navigate (and more) by blocks of indentation: yaml, python etc." tar ((:commit . "c731f05fa3950e2e8580ec61b88abbc705639830") (:authors ("vindarel" . "vindarel@mailz.org")) (:maintainer "vindarel" . "vindarel@mailz.org") (:keywords "indentation" "movements" "navigation" "kill" "fold" "yaml" "python") (:url . "https://gitlab.com/emacs-stuff/indent-tools/"))])
+ (indian-ext . [(20190424 1547) ((emacs (24))) "Extension to Indian language utilities" single ((:commit . "c941cde1205642c6b933ae6abbc47d199f609df0") (:authors ("Patrick McAllister" . "pma@rdorte.org")) (:maintainer "Patrick McAllister" . "pma@rdorte.org") (:keywords "i18n" "tools" "wp" "indian" "devanagari" "encoding") (:url . "https://github.com/paddymcall/indian-ext"))])
+ (indicators . [(20161211 1126) ((dash (2 13 0)) (cl-lib (0 5 0))) "Display the buffer relative location of line in the fringe." single ((:commit . "f62a1201f21453e3aca93f48483e65ae8251432e") (:authors ("Matus Goljer" . "matus.goljer@gmail.com")) (:maintainer "Matus Goljer" . "matus.goljer@gmail.com") (:keywords "fringe" "frames") (:url . "https://github.com/Fuco1/indicators.el"))])
+ (indium . [(20210309 1210) ((emacs (25)) (seq (2 16)) (js2-mode (20140114)) (js2-refactor (0 9 0)) (company (0 9 0)) (json-process-client (0 2 0))) "JavaScript Awesome Development Environment" tar ((:commit . "8499e156bf7286846c3a2bf8c9e0c4d4f24b224c") (:authors ("Nicolas Petton" . "nicolas@petton.fr")) (:maintainer "Nicolas Petton" . "nicolas@petton.fr") (:keywords "tools" "javascript") (:url . "https://github.com/NicolasPetton/indium"))])
+ (indy . [(20190807 625) nil "A minor mode and EDSL to manage your mode's indentation rules." single ((:commit . "abc5bee424780ad2de5520f8fefbf8e120c0d9ed") (:authors ("Kevin W. van Rooijen" . "kevin.van.rooijen@attichacker.com")) (:maintainer "Kevin W. van Rooijen" . "kevin.van.rooijen@attichacker.com") (:keywords "convenience" "matching" "tools"))])
+ (inf-clojure . [(20220421 559) ((emacs (25 1)) (clojure-mode (5 11))) "Run an external Clojure process in an Emacs buffer" single ((:commit . "abeab8d6d4cb3bdded5e9083776aab0c06cbdf57") (:keywords "processes" "clojure") (:url . "http://github.com/clojure-emacs/inf-clojure"))])
+ (inf-crystal . [(20180119 211) ((emacs (24 3)) (crystal-mode (0 1 0))) "Run a Inferior-Crystal process in a buffer" single ((:commit . "02007b2a2a3bea44902d7c83c4acba1e39d278e3") (:authors ("Brantou" . "brantou89@gmail.com")) (:maintainer "Brantou" . "brantou89@gmail.com") (:keywords "languages" "crystal") (:url . "https://github.com/brantou/inf-crystal.el"))])
+ (inf-elixir . [(20211202 210) ((emacs (25 1))) "Run an interactive Elixir shell" single ((:commit . "acb948ca41a862c8c9b3f61ad576dec2c30d0052") (:authors ("Jonathan Arnett" . "jonathan.arnett@protonmail.com")) (:maintainer "Jonathan Arnett" . "jonathan.arnett@protonmail.com") (:keywords "languages" "processes" "tools") (:url . "https://github.com/J3RN/inf-elixir"))])
+ (inf-mongo . [(20180408 1338) nil "Run a MongoDB shell process in a buffer" single ((:commit . "2e498d1c88bd1904eeec18ed06b1a0cf8bdc2a92") (:authors ("Tobias Svensson")) (:maintainer "Tobias Svensson") (:keywords "databases" "mongodb") (:url . "http://github.com/endofunky/inf-mongo"))])
+ (inf-ruby . [(20220228 208) ((emacs (24 3))) "Run a Ruby process in a buffer" single ((:commit . "dbf4386bac12f1733257db6105e3f1fca05ffb79") (:authors ("Yukihiro Matsumoto") ("Nobuyoshi Nakada") ("Cornelius Mika" . "cornelius.mika@gmail.com") ("Dmitry Gutov" . "dgutov@yandex.ru") ("Kyle Hargraves" . "pd@krh.me")) (:maintainer "Yukihiro Matsumoto") (:keywords "languages" "ruby") (:url . "http://github.com/nonsequitur/inf-ruby"))])
+ (inflections . [(20210110 2237) ((cl-lib (0 5)) (emacs (24))) "convert english words between singular and plural" single ((:commit . "55caa66a7cc6e0b1a76143fd40eff38416928941") (:authors ("Dmitry Galinsky, Howard Yeh")) (:maintainer "Dmitry Galinsky, Howard Yeh") (:keywords "languages" "tools" "wp") (:url . "https://github.com/eschulte/jump.el"))])
+ (info-beamer . [(20210427 1033) ((emacs (24 4))) "Utilities for working with info-beamer" single ((:commit . "6b4cc29f1aec72d8e23b2c25a99cdd84e6cdc92b") (:authors ("Daniel Kraus" . "daniel@kraus.my")) (:maintainer "Daniel Kraus" . "daniel@kraus.my") (:keywords "tools" "processes" "comm") (:url . "https://github.com/dakra/info-beamer.el"))])
+ (info-buffer . [(20170112 1422) nil "Display info topics in separate buffers" single ((:commit . "d35dad6e766c6e2ddb8dc6acb4ce5b6e10fbcaa7") (:authors ("Lluís Vilanova" . "vilanova@ac.upc.edu")) (:maintainer "Lluís Vilanova" . "vilanova@ac.upc.edu") (:keywords "docs" "info") (:url . "http://www.github.com/llvilanova/info-buffer"))])
+ (info-colors . [(20200125 1447) ((emacs (24)) (cl-lib (0 5))) "Extra colors for Info-mode" single ((:commit . "47ee73cc19b1049eef32c9f3e264ea7ef2aaf8a5") (:authors ("Tuấn-Anh Nguyễn" . "ubolonton@gmail.com")) (:maintainer "Tuấn-Anh Nguyễn" . "ubolonton@gmail.com") (:keywords "faces") (:url . "https://github.com/ubolonton/info-colors"))])
+ (info-rename-buffer . [(20200328 1450) ((emacs (24 3))) "Rename Info buffers to match manuals" single ((:commit . "87fb263b18717538fd04878e3358e1e720415db8") (:authors ("Bruno Félix Rezende Ribeiro" . "oitofelix@gnu.org")) (:maintainer "Bruno Félix Rezende Ribeiro" . "oitofelix@gnu.org") (:keywords "help") (:url . "https://github.com/oitofelix/info-rename-buffer"))])
+ (inform . [(20200723 500) ((emacs (25 1))) "Symbol links in Info buffers to their help documentation." tar ((:commit . "8ff0a19a9f40cfa8283da8ed73de94c35a327423") (:authors ("H. Dieter Wilhelm" . "dieter@duenenhof-wilhelm.de")) (:maintainer "H. Dieter Wilhelm") (:keywords "help" "docs" "convenience") (:url . "https://github.com/dieter-wilhelm/inform"))])
+ (inform7 . [(20200430 1539) ((emacs (24 3)) (s (1 12 0))) "Major mode for working with Inform 7 files" single ((:commit . "a409bbc6f04264f7f00616a995fa6ecf59d33d0d") (:authors ("Ben Moon" . "software@guiltydolphin.com")) (:maintainer "Ben Moon" . "software@guiltydolphin.com") (:keywords "languages") (:url . "https://github.com/GuiltyDolphin/inform7-mode"))])
+ (inherit-local . [(20170409 1649) ((emacs (24 3))) "Inherited buffer-local variables" single ((:commit . "b1f4ff9c41f9d64e4adaf5adcc280b82f084cdc7") (:authors ("Shea Levy")) (:maintainer "Shea Levy") (:url . "https://github.com/shlevy/inherit-local/tree-master/"))])
+ (inheritenv . [(20210204 354) ((emacs (24 4))) "Make temp buffers inherit buffer-local environment variables" single ((:commit . "c2c879acf89682559b157fb069e1da008f4912ea") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:keywords "unix") (:url . "https://github.com/purcell/inheritenv"))])
+ (ini-mode . [(20170424 909) nil "Major mode for Windows-style ini files." single ((:commit . "2194cfa2fd13196a37350ec20b3f00dcf6162b7c") (:authors ("Anders Lindgren")) (:maintainer "Anders Lindgren") (:keywords "languages" "faces") (:url . "https://github.com/Lindydancer/ini-mode"))])
+ (init-loader . [(20210703 902) ((cl-lib (0 5))) "Loader for configuration files" single ((:commit . "ecab5a66b40227c4173992adfa5cfeae09f1657e") (:authors ("IMAKADO" . "ken.imakado@gmail.com")) (:maintainer "IMAKADO" . "ken.imakado@gmail.com") (:url . "https://github.com/emacs-jp/init-loader/"))])
+ (init-open-recentf . [(20220220 2004) ((emacs (24 4))) "Invoke a command immediately after startup" single ((:commit . "51463effe54ca9390ec339b9678968f35a40dbfd") (:authors ("USAMI Kenta" . "tadsan@zonu.me")) (:maintainer "USAMI Kenta" . "tadsan@zonu.me") (:keywords "files" "recentf" "after-init-hook") (:url . "https://github.com/zonuexe/init-open-recentf.el"))])
+ (initsplit . [(20160919 1818) nil "code to split customizations into different files" single ((:commit . "c941d436eb2b10b01c76a582c5a2b23fb30751aa") (:authors ("John Wiegley <johnw@gnu.org>, Dave Abrahams" . "dave@boostpro.com")) (:maintainer "John Wiegley <johnw@gnu.org>, Dave Abrahams" . "dave@boostpro.com") (:keywords "lisp") (:url . "http://www.gci-net.com/users/j/johnw/emacs.html"))])
+ (ink-mode . [(20201105 2242) ((emacs (26 1))) "Major mode for writing interactive fiction in Ink" tar ((:commit . "63c7ef39acf434a1682951bcf352e8fe1e1ac6d9") (:authors ("Erik Sjöstrand") ("Damien Picard")) (:maintainer "Damien Picard") (:keywords "languages" "wp" "hypermedia") (:url . "https://github.com/Kungsgeten/ink-mode"))])
+ (inkpot-theme . [(20220429 359) ((emacs (24 1))) "A port of vim's inkpot theme" single ((:commit . "0b7e425e82053b2f230060595df252994cd6d9eb") (:authors ("Sarah Iovan" . "sarah@hwaetageek.com") ("Campbell Barton" . "ideasman42@gmail.com")) (:maintainer "Sarah Iovan" . "sarah@hwaetageek.com") (:url . "https://gitlab.com/ideasman42/emacs-inkpot-theme"))])
+ (inline-crypt . [(20170824 900) nil "Simple inline encryption via openssl" tar ((:commit . "281385b383f850fd2e895926b1cef804dd052633") (:authors ("Daniel Ralston" . "Wubbulous@gmail.com")) (:maintainer "Daniel Ralston" . "Wubbulous@gmail.com") (:keywords "crypt") (:url . "https://github.com/Sodel-the-Vociferous/inline-crypt-el"))])
+ (inline-docs . [(20220210 1402) ((emacs (24 3))) "Show inline contextual docs." single ((:commit . "cda596d9ff4c2aa5035692a97c430f6589eafbb1") (:authors ("stardiviner" . "numbchild@gmail.com")) (:maintainer "stardiviner" . "numbchild@gmail.com") (:keywords "inline" "docs" "overlay") (:url . "https://repo.or.cz/inline-docs.git"))])
+ (inlineR . [(20191017 1920) nil "insert Tag for inline image of R graphics" single ((:commit . "bf6450a3540aa3538546d312324c41befd0a4e54") (:authors ("myuhe <yuhei.maeda_at_gmail.com>")) (:maintainer "myuhe") (:keywords "convenience" "iimage.el" "cacoo.el") (:url . "https://github.com/myuhe/inlineR.el"))])
+ (insert-char-preview . [(20201023 2108) ((emacs (24 1))) "Insert Unicode char" single ((:commit . "0e4a62b5407fb1bed8920a4c13cf9a91065e15ad") (:authors ("Matsievskiy S.V.")) (:maintainer "Matsievskiy S.V.") (:keywords "convenience") (:url . "https://gitlab.com/matsievskiysv/insert-char-preview"))])
+ (insert-esv . [(20201201 722) ((emacs (24 3)) (request (0 3 2))) "Insert ESV Bible passages" single ((:commit . "067bdd92ab2fccdfdee3d8707aa570527c74fd6a") (:authors ("Sam (sam030820)")) (:maintainer "Sam (sam030820)") (:keywords "convenience") (:url . "https://github.com/sam030820/insert-esv/"))])
+ (insert-kaomoji . [(20220215 1204) ((emacs (24 4))) "Easily insert kaomojis" tar ((:commit . "974bb7dc02059253e032c501b2c3c0ece448d472") (:authors ("Philip Kaludercic" . "philipk@posteo.net")) (:maintainer "Philip Kaludercic" . "~pkal/public-inbox@lists.sr.ht") (:keywords "wp") (:url . "https://git.sr.ht/~pkal/insert-kaomoji"))])
+ (insert-shebang . [(20201203 1648) nil "Insert shebang line automatically." single ((:commit . "cc8cea997a8523bce9f303de993af3a73eb0d2e2") (:authors ("Sachin Patil" . "iclcoolster@gmail.com")) (:maintainer "Sachin Patil" . "iclcoolster@gmail.com") (:keywords "shebang" "tool" "convenience") (:url . "https://gitlab.com/psachin/insert-shebang"))])
+ (insfactor . [(20141117 2) nil "Client for a Clojure project with insfactor in it" single ((:commit . "7ef5446cebb08a17d4106d2e6f3c053e49e1e829") (:authors ("John D. Hume" . "duelin.markers@gmail.com")) (:maintainer "John D. Hume" . "duelin.markers@gmail.com") (:keywords "clojure") (:url . "http://github.com/duelinmarkers/insfactor.el"))])
+ (instapaper . [(20110419 1355) nil "No description available." single ((:commit . "f21531bcb935e7e9b9e8df83dd0e0838adbf9b1b") (:authors ("Jason F. McBrayer" . "jmcbray@carcosa.net")) (:maintainer "Jason F. McBrayer" . "jmcbray@carcosa.net") (:url . "htts://bitbucket.org/jfm/emacs-instapaper"))])
+ (intel-hex-mode . [(20180423 31) nil "Mode for Intel Hex files." single ((:commit . "e83c94e1c31a8435a88b3ae395f2bc842ef83217") (:maintainer "Michael Schuldt" . "mbschuldt@gmail.com") (:keywords "tools" "hex") (:url . "https://github.com/mschuldt/intel-hex-mode"))])
+ (intellij-theme . [(20171017 1415) nil "Inspired by IntelliJ's default theme" single ((:commit . "1bbfff8e6742d18e9b77ed796f44da3b7bd10606") (:authors ("Vladimir Polushin" . "vovapolu@gmail.com")) (:maintainer "Vladimir Polushin" . "vovapolu@gmail.com") (:keywords "faces"))])
+ (interaction-log . [(20160305 1301) ((cl-lib (0))) "exhaustive log of interactions with Emacs" single ((:commit . "a49a06746d4df6bcfceec3c48dece065d635f9f9") (:authors ("Michael Heerdegen" . "michael_heerdegen@web.de")) (:maintainer "Michael Heerdegen" . "michael_heerdegen@web.de") (:keywords "convenience") (:url . "https://github.com/michael-heerdegen/interaction-log.el"))])
+ (interval-list . [(20150327 1718) ((dash (2 4 0)) (cl-lib (0 5)) (emacs (24 4))) "Interval list data structure for 1D selections" single ((:commit . "38af7ecf0a493ad8f487074938a2a115f3531177") (:authors ("Matus Goljer" . "matus.goljer@gmail.com")) (:maintainer "Matus Goljer" . "matus.goljer@gmail.com") (:keywords "extensions" "data structure") (:url . "https://github.com/Fuco1/interval-list"))])
+ (interval-tree . [(20130325 1407) ((dash (1 1 0))) "Interval tree data structure for 1D range queries" single ((:commit . "301302f480617091cf3ab6989caac385d52543dc") (:authors ("Matus Goljer" . "matus.goljer@gmail.com")) (:maintainer "Matus Goljer" . "matus.goljer@gmail.com") (:keywords "extensions" "data structure") (:url . "https://github.com/Fuco1/interval-tree"))])
+ (inverse-acme-theme . [(20210204 1640) ((autothemer (0 2)) (cl-lib (0 5))) "A theme that looks like an inverse of Acme's color scheme." single ((:commit . "79008920ce7923312ada6f95a3ec1f96ce513c0b") (:authors ("Dylan Johnson")) (:maintainer "Dylan Johnson") (:url . "http://github.com/dcjohnson/inverse-acme-theme"))])
+ (io-mode . [(20161004 756) nil "Major mode to edit Io language files in Emacs" single ((:commit . "fd65ae769093defcf554d6d637eba6e6dfc29f56") (:authors ("Sergei Lebedev" . "superbobry@gmail.com")) (:maintainer "Sergei Lebedev" . "superbobry@gmail.com") (:keywords "languages" "io") (:url . "https://github.com/superbobry/io-mode"))])
+ (io-mode-inf . [(20140128 1934) nil "Interaction with an Io interpreter." single ((:commit . "6dd2bac3fd87484bb7d97e135b06c29d70b444b6") (:keywords "io" "languages") (:url . "https://github.com/slackorama/io-emacs"))])
+ (iodine-theme . [(20151031 1639) ((emacs (24))) "A light emacs color theme" single ((:commit . "02fb780e1d8d8a6b9c709bfac399abe1665c6999") (:authors ("Srđan Panić" . "srdja.panic@gmail.com")) (:maintainer "Srđan Panić" . "srdja.panic@gmail.com") (:keywords "themes") (:url . "https://github.com/srdja/iodine-theme"))])
+ (ipcalc . [(20210903 958) ((cl-lib (0 5))) "IP subnet calculator" single ((:commit . "8d5af5b8e075f204c1e265174c96587886831996") (:authors ("\"Aleksandar Simic\"" . "asimic@gmail.com")) (:maintainer "\"Aleksandar Simic\"" . "asimic@gmail.com") (:keywords "networking" "tools") (:url . "http://github.com/dotemacs/ipcalc.el"))])
+ (iplayer . [(20161120 2120) nil "Browse and download BBC TV/radio shows" single ((:commit . "b788fffa4b36bbd558047ffa6be51b1f0f462f23") (:authors ("Christophe Rhodes" . "csr21@cantab.net")) (:maintainer "Christophe Rhodes" . "csr21@cantab.net") (:keywords "multimedia" "bbc") (:url . "https://github.com/csrhodes/iplayer-el"))])
+ (ipretty . [(20180606 522) nil "Interactive Emacs Lisp pretty-printing" single ((:commit . "042f5cc4e6f81d59115e8335c582bb5c571c2585") (:authors ("steckerhalter")) (:maintainer "steckerhalter") (:keywords "pretty-print" "elisp" "buffer") (:url . "https://framagit.org/steckerhalter/ipretty"))])
+ (ipython-shell-send . [(20190220 2246) ((emacs (24))) "Send code (including magics) to ipython shell" single ((:commit . "0faed86faff02a361f23ce5fc923d0e9b09bb2da") (:authors ("Jack Kamm" . "jackkamm@gmail.com")) (:maintainer "Jack Kamm" . "jackkamm@gmail.com") (:keywords "tools" "processes") (:url . "https://github.com/jackkamm/ipython-shell-send-el"))])
+ (iqa . [(20200520 1137) ((emacs (24 3))) "Init file(and directory) Quick Access" single ((:commit . "c1077aca6553cb2011f21b178e10271a17fe4f58") (:url . "https://github.com/a13/iqa.el"))])
+ (ir-black-theme . [(20130303 755) nil "Port of ir-black theme" single ((:commit . "36e930d107604b5763c80294a6f92aaa02e6c272") (:authors ("Jon-Michael Deldin" . "dev@jmdeldin.com")) (:maintainer "Jon-Michael Deldin" . "dev@jmdeldin.com") (:keywords "faces"))])
+ (iregister . [(20150515 2107) nil "Interactive register commands for Emacs." tar ((:commit . "6a48c66187289de5f300492be11c83e98410c018") (:authors ("Andrey Tykhonov" . "atykhonov@gmail.com")) (:maintainer "Andrey Tykhonov" . "atykhonov@gmail.com") (:keywords "convenience") (:url . "https://github.com/atykhonov/iregister.el"))])
+ (irony . [(20220110 849) ((cl-lib (0 5)) (json (1 2))) "C/C++ minor mode powered by libclang" tar ((:commit . "870d1576fb279bb93f776a71e65f45283c423a9e") (:authors ("Guillaume Papin" . "guillaume.papin@epitech.eu")) (:maintainer "Guillaume Papin" . "guillaume.papin@epitech.eu") (:keywords "c" "convenience" "tools") (:url . "https://github.com/Sarcasm/irony-mode"))])
+ (irony-eldoc . [(20200622 2214) ((emacs (24)) (cl-lib (0 5)) (irony (0 1))) "irony-mode support for eldoc-mode" single ((:commit . "73e79a89fad982a2ba072f2fcc1b4e41f0aa2978") (:authors ("Kirill Ignatiev <github.com/ikirill>")) (:maintainer "Kirill Ignatiev <github.com/ikirill>") (:keywords "c" "c++" "objc" "convenience" "tools") (:url . "https://github.com/ikirill/irony-eldoc"))])
+ (iscroll . [(20210128 1938) ((emacs (26 0))) "Smooth scrolling over images" single ((:commit . "d6e11066169d232fe23c2867d44c012722ddfc5a") (:authors ("Yuan Fu" . "casouri@gmail.com")) (:maintainer "Yuan Fu" . "casouri@gmail.com") (:keywords "convenience" "image") (:url . "https://github.com/casouri/iscroll"))])
+ (isearch-dabbrev . [(20141224 622) ((cl-lib (0 5))) "Use dabbrev in isearch" single ((:commit . "1efe7abba4923015cbc2462395deaec5446a9cc8") (:authors ("Dewdrops" . "v_v_4474@126.com")) (:maintainer "Dewdrops" . "v_v_4474@126.com") (:keywords "dabbrev" "isearch") (:url . "https://github.com/Dewdrops/isearch-dabbrev"))])
+ (isearch-project . [(20210715 1041) ((emacs (26 1)) (f (0 20 0))) "Incremental search through the whole project" single ((:commit . "e6c9d5e19533eda6b74505a86198416eeecb915a") (:authors ("Shen, Jen-Chieh" . "jcs090218@gmail.com")) (:maintainer "Shen, Jen-Chieh" . "jcs090218@gmail.com") (:url . "https://github.com/jcs-elpa/isearch-project"))])
+ (isearch-symbol-at-point . [(20130728 2221) nil "Use isearch to search for the symbol at point" single ((:commit . "51a1029bec1ec414885f9edb7e5947603dffdab2") (:authors ("atom smith")) (:maintainer "atom smith") (:keywords "isearch") (:url . "https://github.com/re5et/isearch-symbol-at-point"))])
+ (isend-mode . [(20210106 1506) nil "Interactively send parts of an Emacs buffer to an interpreter" single ((:commit . "ea855f63be7febc15bd08aec6229fab9407734fb") (:authors ("François Févotte" . "fevotte@gmail.com")) (:maintainer "François Févotte" . "fevotte@gmail.com") (:url . "https://github.com/ffevotte/isend-mode.el"))])
+ (isgd . [(20150414 936) nil "Shorten URLs using the isgd.com shortener service" single ((:commit . "764306dadd5a9213799081a48aba22f7c75cca9a") (:authors ("Chmouel Boudjnah" . "chmouel@chmouel.com")) (:maintainer "Chmouel Boudjnah" . "chmouel@chmouel.com") (:url . "https://github.com/chmouel/isgd.el"))])
+ (isortify . [(20190315 2004) ((emacs (25)) (pythonic (0 1 0))) "(automatically) format python buffers using isort." single ((:commit . "ae7fb7163ce075209543f72953c9f431d103f6a3") (:authors ("Artem Malyshev" . "proofit404@gmail.com")) (:maintainer "Artem Malyshev" . "proofit404@gmail.com") (:url . "https://github.com/proofit404/isortify"))])
+ (ispc-mode . [(20201215 852) nil "Syntax coloring for ispc programs" single ((:commit . "722fdc45da2714f8fe0757968589cdb5ccacc8a0") (:authors ("Philip Munksgaard" . "philip@munksgaard.me")) (:maintainer "Philip Munksgaard" . "philip@munksgaard.me") (:keywords "c" "ispc") (:url . "https://github.com/Munksgaard/ispc-mode"))])
+ (iss-mode . [(20141001 1913) nil "Mode for InnoSetup install scripts" single ((:commit . "3b517aff31529bab33f8d7b562bd17aff0107fd1") (:authors ("Stefan Reichoer," . "stefan@xsteve.at")) (:maintainer "Stefan Reichoer," . "stefan@xsteve.at"))])
+ (itail . [(20171112 804) nil "An interactive tail mode" single ((:commit . "6e43c20da03be3b9c6ece93b7dc3495975ec1888") (:authors ("atom smith")) (:maintainer "atom smith") (:keywords "tail") (:url . "https://github.com/re5et/itail"))])
+ (itasca . [(20170601 1622) ((emacs (24 3))) "Major modes for Itasca software data files." tar ((:commit . "3d15dd1b70d6db69b0f4758a3e28b8b506cc84ca") (:authors ("Jason Furtney" . "jkfurtney@gmail.com")) (:maintainer "Jason Furtney" . "jkfurtney@gmail.com") (:keywords "itasca" "flac" "3dec" "udec" "flac3d" "pfc" "pfc2d" "pfc3d" "fish") (:url . "http://github.com/jkfurtney/itasca-emacs/"))])
+ (iter2 . [(20220501 1542) ((emacs (25 1))) "Reimplementation of Elisp generators" single ((:commit . "1abca3665ecfa6b016311906560f8be4fbb3e3db") (:authors ("Paul Pogonyshev" . "pogonyshev@gmail.com")) (:maintainer "Paul Pogonyshev" . "pogonyshev@gmail.com") (:keywords "elisp" "extensions") (:url . "https://github.com/doublep/iter2"))])
+ (iterator . [(20210109 1859) ((emacs (24)) (cl-lib (0 5))) "A library to create and use elisp iterators objects." single ((:commit . "b514d4d1d0167e5973afbc93a34070d1aa967d82") (:authors ("Thierry Volpiatto <thierry dot volpiatto at gmail dot com>")) (:maintainer "Thierry Volpiatto <thierry dot volpiatto at gmail dot com>") (:url . "https://github.com/thierryvolpiatto/iterator"))])
+ (ivariants . [(20170823 224) ((emacs (24 3)) (ivs-edit (1 0))) "Ideographic variants editor and browser" tar ((:commit . "ca0b74d32b5d2d77a45cc6ad6edc00be0ee85284") (:authors ("KAWABATA, Taichi <kawabata.taichi_at_gmail.com>")) (:maintainer "KAWABATA, Taichi <kawabata.taichi_at_gmail.com>") (:keywords "i18n" "languages") (:url . "http://github.com/kawabata/ivariants"))])
+ (ivs-edit . [(20170818 1441) ((emacs (24 3)) (dash (2 6 0)) (cl-lib (1 0))) "IVS (Ideographic Variation Sequence) editing tool" tar ((:commit . "5db39c234aa7393b591168a4fd0a9a4cbbca347d") (:authors ("KAWABATA, Taichi <kawabata.taichi_at_gmail.com>")) (:maintainer "KAWABATA, Taichi <kawabata.taichi_at_gmail.com>") (:keywords "text") (:url . "http://github.com/kawabata/ivs-edit"))])
+ (ivy . [(20220406 1052) ((emacs (24 5))) "Incremental Vertical completYon" tar ((:commit . "8bf8027e4bd8c093bddb76a813952d2a0dcbf21d") (:authors ("Oleh Krehel" . "ohwoeowho@gmail.com")) (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com") (:keywords "matching") (:url . "https://github.com/abo-abo/swiper"))])
+ (ivy-avy . [(20211021 1602) ((emacs (24 5)) (ivy (0 13 4)) (avy (0 5 0))) "Avy integration for Ivy" single ((:commit . "8bf8027e4bd8c093bddb76a813952d2a0dcbf21d") (:authors ("Oleh Krehel" . "ohwoeowho@gmail.com")) (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com") (:keywords "convenience") (:url . "https://github.com/abo-abo/swiper"))])
+ (ivy-bibtex . [(20210927 1205) ((bibtex-completion (1 0 0)) (ivy (0 13 0)) (cl-lib (0 5))) "A bibliography manager based on Ivy" single ((:commit . "ce8c17690ddad73d01531084b282f221f8eb6669") (:authors ("Justin Burkett" . "justin@burkett.cc")) (:maintainer "Titus von der Malsburg" . "malsburg@posteo.de") (:url . "https://github.com/tmalsburg/helm-bibtex"))])
+ (ivy-clipmenu . [(20220202 2122) ((emacs (26 1)) (f (0 20 0)) (s (1 12 0)) (dash (2 16 0)) (ivy (0 13 0))) "Ivy client for clipmenu" single ((:commit . "7c200cd4732821187084fad23547ee3f58365062") (:authors ("William Carroll" . "wpcarro@gmail.com")) (:maintainer "William Carroll" . "wpcarro@gmail.com") (:url . "https://github.com/wpcarro/ivy-clipmenu.el"))])
+ (ivy-clojuredocs . [(20201129 2355) ((edn (1 1 2)) (ivy (0 12 0)) (emacs (24 4))) "Search for help in clojuredocs.org" single ((:commit . "8b6de19b3578c72d2b88f898e2290d94c04350f9") (:authors ("Wanderson Ferreira" . "iagwanderson@gmail.com")) (:maintainer "Wanderson Ferreira" . "iagwanderson@gmail.com") (:keywords "matching") (:url . "https://github.com/wandersoncferreira/ivy-clojuredocs"))])
+ (ivy-dired-history . [(20210715 48) ((ivy (0 9 0)) (counsel (0 9 0)) (cl-lib (0 5))) "use ivy to open recent directories" single ((:commit . "dba848929cb063a5536cb442c70be1099e2f5baa") (:authors ("纪秀峰" . "jixiuf@gmail.com")) (:maintainer "纪秀峰" . "jixiuf@gmail.com") (:url . "https://github.com/jixiuf/ivy-dired-history"))])
+ (ivy-emms . [(20210817 1300) ((ivy (0 13 0)) (emms (0 0)) (emacs (24 4))) "Ivy interface to emms tracks" single ((:commit . "dfde98c3bdad8136709eac8382ba048fafdcc6ac") (:authors ("Fran Burstall" . "fran.burstall@gmail.com")) (:maintainer "Fran Burstall" . "fran.burstall@gmail.com") (:keywords "multimedia") (:url . "https://github.com/franburstall/ivy-emms"))])
+ (ivy-emoji . [(20200316 2351) ((emacs (26 1)) (ivy (0 13 0))) "Insert emojis with ivy" single ((:commit . "a1b7d32048278afd9b06536a8af96f533639d146") (:authors ("Gabriele Bozzola" . "sbozzolator@gmail.com")) (:maintainer "Gabriele Bozzola" . "sbozzolator@gmail.com") (:keywords "emoji" "ivy" "convenience") (:url . "https://github.com/sbozzolo/ivy-emoji.git"))])
+ (ivy-erlang-complete . [(20211019 447) ((async (1 9)) (counsel (0 13 4)) (ivy (0 13 4)) (erlang (19 2)) (emacs (25 1))) "Erlang context sensitive completion at point using ivy. It also support xref and eldoc." tar ((:commit . "6913f6ef7c942a5a2c42bc17635d09c91353e7ca") (:authors ("Sergey Kostyaev" . "feo.me@ya.ru")) (:maintainer "Sergey Kostyaev" . "feo.me@ya.ru") (:keywords "languages" "tools"))])
+ (ivy-explorer . [(20190909 1921) ((emacs (25)) (ivy (0 10 0))) "Dynamic file browsing grid using ivy" single ((:commit . "a413966cfbcecacc082d99297fa1abde0c10d3f3") (:authors ("Clemens Radermacher" . "clemera@posteo.net")) (:maintainer "Clemens Radermacher" . "clemera@posteo.net") (:keywords "convenience" "files" "matching") (:url . "https://github.com/clemera/ivy-explorer"))])
+ (ivy-file-preview . [(20210124 1639) ((emacs (25 1)) (ivy (0 8 0)) (s (1 12 0)) (f (0 20 0))) "Preview the current ivy file selection" single ((:commit . "942b2565097c97c1afc4fa395fac5788eabc730b") (:authors ("Shen, Jen-Chieh" . "jcs090218@gmail.com")) (:maintainer "Shen, Jen-Chieh" . "jcs090218@gmail.com") (:url . "https://github.com/jcs-elpa/ivy-file-preview"))])
+ (ivy-fuz . [(20191222 946) ((emacs (25 1)) (fuz (1 3 0)) (ivy (0 13 0))) "Integration between fuz and ivy." single ((:commit . "f171ac73422a4bae1503d63d804e691482ed35b2") (:authors ("Zhu Zihao" . "all_but_last@163.com")) (:maintainer "Philippe Vaucher" . "philippe.vaucher@gmail.com") (:keywords "convenience") (:url . "https://github.com/Silex/ivy-fuz.el"))])
+ (ivy-gitlab . [(20181228 826) ((s (1 9 0)) (dash (2 9 0)) (ivy (0 8 0)) (gitlab (0 8))) "Ivy interface to Gitlab" single ((:commit . "8c2324c02119500f094c2f92dfaba4c9977ce1ba") (:authors ("Nicolas Lamirault" . "nicolas.lamirault@gmail.com")) (:maintainer "Nicolas Lamirault" . "nicolas.lamirault@gmail.com") (:keywords "gitlab" "ivy") (:url . "https://github.com/nlamirault/emacs-gitlab"))])
+ (ivy-historian . [(20210714 56) ((emacs (24 4)) (historian (20170111)) (ivy (0 8 0)) (flx (0 6 1))) "Persistently store selected minibuffer candidates" single ((:commit . "852cb4e72c0f78c8dbb2c972bdcb4e7b0108ff4c") (:authors ("PythonNut" . "pythonnut@pythonnut.com")) (:maintainer "PythonNut" . "pythonnut@pythonnut.com") (:keywords "convenience" "ivy") (:url . "https://github.com/PythonNut/historian.el"))])
+ (ivy-hydra . [(20220402 1348) ((emacs (24 5)) (ivy (0 13 4)) (hydra (0 14 0))) "Additional key bindings for Ivy" single ((:commit . "8bf8027e4bd8c093bddb76a813952d2a0dcbf21d") (:authors ("Oleh Krehel" . "ohwoeowho@gmail.com")) (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com") (:keywords "convenience") (:url . "https://github.com/abo-abo/swiper"))])
+ (ivy-lobsters . [(20200818 1406) ((ivy (0 8 0)) (cl-lib (0 5))) "Browse lobste.rs stories with ivy." single ((:commit . "3f7f90751d15ebcf91253ef3cda18c0aa7d856ff") (:authors ("Julien Blanchard <https://github.com/julienXX>")) (:maintainer "Julien Blanchard <https://github.com/julienXX>") (:url . "https://github.com/julienXX/ivy-lobsters"))])
+ (ivy-migemo . [(20220309 605) ((emacs (24 3)) (ivy (0 13 0)) (migemo (1 9 2)) (nadvice (0 3))) "Use migemo on ivy" single ((:commit . "f31a2b314b81e328ce0222d8796b808230ddaa0e") (:authors ("ROCKTAKEY" . "rocktakey@gmail.com")) (:maintainer "ROCKTAKEY" . "rocktakey@gmail.com") (:keywords "matching") (:url . "https://github.com/ROCKTAKEY/ivy-migemo"))])
+ (ivy-mpdel . [(20190428 920) ((emacs (25 1)) (ivy (0 10 0)) (libmpdel (1 0 0)) (mpdel (1 0 0))) "Ivy interface to navigate MPD" single ((:commit . "a42dcc943914c71975c115195d38c739f25e475c") (:authors ("Damien Cassou" . "damien@cassou.me")) (:maintainer "Damien Cassou" . "damien@cassou.me") (:keywords "multimedia") (:url . "https://gitlab.petton.fr/mpdel/ivy-mpdel"))])
+ (ivy-omni-org . [(20200810 1050) ((emacs (25 1)) (ivy (0 13)) (dash (2 12))) "Browse anything in Org mode" single ((:commit . "a6b284f65b229d9b118b4316c2f6377de93400b1") (:authors ("Akira Komamura" . "akira.komamura@gmail.com")) (:maintainer "Akira Komamura" . "akira.komamura@gmail.com") (:keywords "outlines") (:url . "https://github.com/akirak/ivy-omni-org"))])
+ (ivy-pass . [(20170812 1955) ((emacs (24)) (ivy (0 8 0)) (password-store (1 6 5))) "ivy interface for pass" single ((:commit . "5b523de1151f2109fdd6a8114d0af12eef83d3c5") (:authors ("ecraven")) (:maintainer "ecraven") (:keywords "pass" "password" "convenience" "data") (:url . "https://github.com/ecraven/ivy-pass/"))])
+ (ivy-phpunit . [(20180219 915) ((ivy (0 10 0)) (phpunit (0 7 0)) (emacs (25))) "Ivy integration for phpunit.el" single ((:commit . "ffedb0138d36564e8e36a28fd9bc71ea8944681f") (:authors ("12pt")) (:maintainer "12pt") (:keywords "convenience" "tools" "ivy" "phpunit" "php") (:url . "https://github.com/12pt/ivy-phpunit"))])
+ (ivy-posframe . [(20211217 234) ((emacs (26 0)) (posframe (1 0 0)) (ivy (0 13 0))) "Using posframe to show Ivy" single ((:commit . "533a8e368fcabfd534761a5c685ce713376fa594") (:authors ("Feng Shu" . "tumashu@163.com") ("Naoya Yamashita" . "conao3@gmail.com")) (:maintainer "Feng Shu" . "tumashu@163.com") (:keywords "abbrev" "convenience" "matching" "ivy") (:url . "https://github.com/tumashu/ivy-posframe"))])
+ (ivy-prescient . [(20220501 2235) ((emacs (25 1)) (prescient (5 2)) (ivy (0 11 0))) "prescient.el + Ivy" single ((:commit . "d9b30d741c729a37eb2c6e51d72281c0844780ca") (:authors ("Radon Rosborough" . "radon.neon@gmail.com")) (:maintainer "Radon Rosborough" . "radon.neon@gmail.com") (:keywords "extensions") (:url . "https://github.com/raxod502/prescient.el"))])
+ (ivy-purpose . [(20160724 1003) ((emacs (24)) (ivy (0 8)) (window-purpose (1 5))) "Ivy Interface for Purpose" single ((:commit . "0495f2f3aed64d7e0028125e76a9a68f8fc4107e") (:authors ("Bar Magal (2016)")) (:maintainer "Bar Magal (2016)") (:url . "https://github.com/bmag/ivy-purpose"))])
+ (ivy-rich . [(20210409 931) ((emacs (25 1)) (ivy (0 13 0))) "More friendly display transformer for ivy" single ((:commit . "600b8183ed0be8668dcc548cc2c8cb94b001363b") (:authors ("Yevgnen Koh" . "wherejoystarts@gmail.com")) (:maintainer "Yevgnen Koh" . "wherejoystarts@gmail.com") (:keywords "convenience" "ivy") (:url . "https://github.com/Yevgnen/ivy-rich"))])
+ (ivy-rtags . [(20191222 920) ((ivy (0 7 0)) (rtags (2 10))) "RTags completion back-end for ivy" single ((:commit . "db39790fda5c2443bc790b8971ac140914f7e9c2") (:authors ("Jan Erik Hanssen" . "jhanssen@gmail.com") ("Anders Bakken" . "agbakken@gmail.com")) (:maintainer "Jan Erik Hanssen" . "jhanssen@gmail.com") (:url . "https://github.com/Andersbakken/rtags"))])
+ (ivy-searcher . [(20210221 923) ((emacs (25 1)) (ivy (0 8 0)) (searcher (0 1 8)) (s (1 12 0)) (f (0 20 0))) "Ivy interface to use searcher" single ((:commit . "17a93eadb8a681d878e1d66b90073ed1be2e1dc2") (:authors ("Shen, Jen-Chieh" . "jcs090218@gmail.com")) (:maintainer "Shen, Jen-Chieh" . "jcs090218@gmail.com") (:url . "https://github.com/jcs-elpa/ivy-searcher"))])
+ (ivy-spotify . [(20210329 312) ((emacs (26 1)) (espotify (0 1)) (ivy (0 13 1))) "Search spotify with ivy" single ((:commit . "ea6d6021e5acc550560325db2f09198839ee702f") (:authors ("Jose A Ortega Ruiz" . "jao@gnu.org")) (:maintainer "Jose A Ortega Ruiz") (:keywords "multimedia") (:url . "https://codeberg.org/jao/espotify"))])
+ (ivy-todo . [(20200323 2005) ((ivy (0 8 0)) (emacs (25))) "Manage org-mode TODOs with ivy" single ((:commit . "d74501cd334b7d709659946c5e02b21cfd5507de") (:authors ("Erik Sjöstrand" . "sjostrand.erik@gmail.com")) (:maintainer "Erik Sjöstrand" . "sjostrand.erik@gmail.com") (:keywords "convenience") (:url . "https://github.com/Kungsgeten/ivy-todo"))])
+ (ivy-xcdoc . [(20160917 1055) ((ivy (0 8 0)) (emacs (24 4))) "Search Xcode documents with ivy interface." single ((:commit . "5ea22af36c4c2737fb0bec53432c233482d8b314") (:authors ("C.T.Chen" . "chenct@7adybird.com")) (:maintainer "C.T.Chen" . "chenct@7adybird.com") (:keywords "ivy" "xcode" "xcdoc") (:url . "https://github.com/hex2010/emacs-ivy-xcdoc"))])
+ (ivy-xref . [(20211008 1103) ((emacs (25 1)) (ivy (0 10 0))) "Ivy interface for xref results" single ((:commit . "a82e8e117d2dd62c28b6a3e3d6e4cfb11c0bda38") (:authors ("Alex Murray" . "murray.alex@gmail.com")) (:maintainer "Alex Murray" . "murray.alex@gmail.com") (:url . "https://github.com/alexmurray/ivy-xref"))])
+ (ivy-yasnippet . [(20200704 700) ((emacs (24 1)) (cl-lib (0 6)) (ivy (0 10 0)) (yasnippet (0 12 2)) (dash (2 14 1))) "Preview yasnippets with ivy" single ((:commit . "83402d91b4eba5307f71884a72df8e11cc6a994e") (:authors ("Michał Krzywkowski" . "k.michal@zoho.com")) (:maintainer "Michał Krzywkowski" . "k.michal@zoho.com") (:keywords "convenience") (:url . "https://github.com/mkcms/ivy-yasnippet"))])
+ (ivy-ycmd . [(20180909 1225) ((ycmd (1 3)) (emacs (24)) (ivy (0 10 0)) (dash (2 14 1))) "Ivy interface to ycmd" single ((:commit . "25bfee8f676e4ecbb645e4f30b47083410a00c58") (:authors ("Austin Bingham" . "austin.bingham@gmail.com")) (:maintainer "Austin Bingham" . "austin.bingham@gmail.com") (:keywords "tools") (:url . "https://github.com/abingham/emacs-ivy-ycmd"))])
+ (ivy-youtube . [(20181126 1039) ((request (0 2 0)) (ivy (0 8 0)) (cl-lib (0 5))) "Query YouTube and play videos in your browser" single ((:commit . "273788e0d22a06cca1050eb1205d3fbc2245d001") (:authors ("Brunno dos Santos")) (:maintainer "Brunno dos Santos") (:keywords "youtube" "multimedia" "mpv" "vlc") (:url . "https://github.com/squiter/ivy-youtube"))])
+ (ix . [(20131027 1629) ((grapnel (0 5 3))) "Emacs client for http://ix.io pastebin" single ((:commit . "aea4c54a5cc5a6f26637353c16a3a0e70fc76963") (:authors ("Abhishek L" . "abhishekl.2006@gmail.com")) (:maintainer "Abhishek L" . "abhishekl.2006@gmail.com") (:url . "http://www.github.com/theanalyst/ix.el"))])
+ (j-mode . [(20171224 1856) nil "Major mode for editing J programs" tar ((:commit . "e8725ac8af95498faabb2ca3ab3bd809a8f148e6") (:keywords "j" "languages") (:url . "http://github.com/zellio/j-mode"))])
+ (jabber . [(20180927 2325) ((fsm (0 2)) (srv (0 2))) "A Jabber client for Emacs." tar ((:commit . "fff33826f42e040dad7ef64ea312d85215d3b0a1"))])
+ (jabber-otr . [(20150918 1144) ((emacs (24)) (jabber (0 8 92))) "Off-The-Record messaging for jabber.el" tar ((:commit . "2692b1530234e0ba9a0d6c1eaa1cbe8679f193c0") (:authors ("Magnus Henoch" . "magnus.henoch@gmail.com")) (:maintainer "Magnus Henoch" . "magnus.henoch@gmail.com") (:keywords "comm") (:url . "https://github.com/legoscia/emacs-jabber-otr/"))])
+ (jack-connect . [(20220201 1417) nil "Manage jack connections within Emacs" single ((:commit . "1acaebfe8f37f0194e95c3e812c9515a6f688eee") (:authors ("Stefano Barbi" . "stefanobarbi@gmail.com")) (:maintainer "Stefano Barbi" . "stefanobarbi@gmail.com"))])
+ (jade-mode . [(20210908 2121) nil "Major mode for editing .jade files" single ((:commit . "1ad7c51f3c6a6ae64550d9510c5e4e8470014375") (:authors ("Brian M. Carlson and other contributors")) (:maintainer "Brian M. Carlson and other contributors") (:keywords "languages") (:url . "https://github.com/brianc/jade-mode"))])
+ (jammer . [(20210508 1633) ((emacs (24 1))) "Punish yourself for using Emacs inefficiently" single ((:commit . "a780e4c2adb2e85a4daadcefd1a2b189d761872f") (:authors ("Vasilij Schneidermann" . "mail@vasilij.de")) (:maintainer "Vasilij Schneidermann" . "mail@vasilij.de") (:keywords "games") (:url . "https://depp.brause.cc/jammer"))])
+ (janet-mode . [(20210924 44) ((emacs (24 3))) "Defines a major mode for Janet" single ((:commit . "9e3254a0249d720d5fa5603f1f8c3ed0612695af") (:authors ("Adam Schwalm" . "adamschwalm@gmail.com")) (:maintainer "Adam Schwalm" . "adamschwalm@gmail.com") (:url . "https://github.com/ALSchwalm/janet-mode"))])
+ (japanese-holidays . [(20201229 755) ((emacs (24 1)) (cl-lib (0 3))) "Calendar functions for the Japanese calendar" single ((:commit . "324b6bf2f55ec050bef49e001caedaabaf4fa35d") (:authors ("Takashi Hattori" . "hattori@sfc.keio.ac.jp") ("Hiroya Murata" . "lapis-lazuli@pop06.odn.ne.jp")) (:maintainer "Takashi Hattori" . "hattori@sfc.keio.ac.jp") (:keywords "calendar") (:url . "https://github.com/emacs-jp/japanese-holidays"))])
+ (jape-mode . [(20140903 1506) nil "An Emacs editing mode mode for GATE's JAPE files" single ((:commit . "85b9182850707b5d107391f6caee5bd401507a7d") (:keywords "languages" "jape" "gate") (:url . "http://github.com/tanzoniteblack/jape-mode"))])
+ (jar-manifest-mode . [(20160501 26) nil "Major mode to edit JAR manifest files" single ((:commit . "270dae14c481300f75ed96dad3a5ae42ca928a1d") (:authors ("Omair Majid" . "omair.majid@gmail.com")) (:maintainer "Omair Majid" . "omair.majid@gmail.com") (:keywords "convenience" "languages") (:url . "http://github.com/omajid/jar-manifest-mode"))])
+ (jasminejs-mode . [(20150527 5) nil "A minor mode for manipulating jasmine test files" tar ((:commit . "9f8044bf81ab5b4841a30b0bd099916e1b7ff54a") (:authors ("Eric Stolten" . "stoltene2@gmail.com")) (:maintainer "Eric Stolten" . "stoltene2@gmail.com") (:keywords "javascript" "jasmine") (:url . "https://github.com/stoltene2/jasminejs-mode"))])
+ (jastadd-ast-mode . [(20200926 1820) ((emacs (25))) "Major mode for editing JastAdd AST files" single ((:commit . "b7a0e32b669e726c8ccc348dd6b18ad4a7c70e1b") (:authors ("Rudi Schlatte" . "rudi@constantly.at")) (:maintainer "Rudi Schlatte" . "rudi@constantly.at") (:keywords "languages") (:url . "https://github.com/rudi/jastadd-ast-mode"))])
+ (java-imports . [(20211006 2153) ((emacs (24 4)) (s (1 10 0)) (pcache (0 3 2))) "Code for dealing with Java imports" single ((:commit . "7535a36d85497448a6e83579b822beaca7251ccb") (:authors ("Lee Hinman" . "lee@writequit.org")) (:maintainer "Lee Hinman" . "lee@writequit.org") (:keywords "java" "kotlin") (:url . "http://www.github.com/dakrone/emacs-java-imports"))])
+ (java-snippets . [(20160627 252) ((yasnippet (0 8 0))) "Yasnippets for Java" tar ((:commit . "6d0e2768823be27dbe07448f4cb244cd657a7136") (:authors ("Takayoshi Kimura")) (:maintainer "Takayoshi Kimura") (:url . "https://github.com/nekop/yasnippet-java-mode"))])
+ (javadoc-lookup . [(20160214 31) ((cl-lib (0 3))) "Javadoc Emacs integration with Maven" tar ((:commit . "507a2dd443d60b537b8f779c1847e2cd0ccd1382") (:authors ("Christopher Wellons" . "wellons@nullprogram.com")) (:maintainer "Christopher Wellons" . "wellons@nullprogram.com") (:url . "https://github.com/skeeto/javadoc-lookup"))])
+ (javap-mode . [(20120223 2208) nil "Javap major mode" single ((:commit . "864c1130e204b2072e1d19cd027b6fce8ebe6629") (:url . "http://github.com/hiredman/javap-mode"))])
+ (jaword . [(20210306 420) ((tinysegmenter (0 1)) (emacs (25 1))) "Minor-mode for handling Japanese words better" single ((:commit . "783544a265f91b2e568b52311afb36e3691d5ad3") (:authors ("zk_phi")) (:maintainer "zk_phi") (:url . "http://zk-phi.github.io/"))])
+ (jazz-theme . [(20201026 1027) nil "A warm color theme for Emacs 24+." single ((:commit . "0b5bfe7a30590326bdf38120fb4bc25fff21a509") (:authors ("Roman Parykin" . "donderom@ymail.com")) (:maintainer "Roman Parykin" . "donderom@ymail.com") (:url . "https://github.com/donderom/jazz-theme"))])
+ (jbeans-theme . [(20200924 1946) ((emacs (24))) "Jbeans theme for GNU Emacs 24 (deftheme)" single ((:commit . "a63916a928324c42bfbe3016972c2ecff598b1ae") (:authors ("Adam Olsen" . "arolsen@gmail.com")) (:maintainer "Adam Olsen" . "arolsen@gmail.com") (:url . "https://github.com/synic/jbeans-emacs"))])
+ (jdecomp . [(20170224 2200) ((emacs (24 5))) "Interface to Java decompilers" single ((:commit . "692866abc83deedce62be8d6040cf24dda7fb7a8") (:authors ("Tianxiang Xiong" . "tianxiang.xiong@gmail.com")) (:maintainer "Tianxiang Xiong" . "tianxiang.xiong@gmail.com") (:keywords "decompile" "java" "languages" "tools") (:url . "https://github.com/xiongtx/jdecomp"))])
+ (jdee . [(20191102 1426) ((emacs (24 3)) (flycheck (30)) (memoize (1 0 1)) (dash (2 13 0)) (s (1 12 0))) "Java Development Environment for Emacs" tar ((:commit . "b510a29f1fc1bea218a6230fb219922775687c78") (:authors ("Paul Kinnucan" . "pkinnucan@attbi.com")) (:maintainer "Paul Landes") (:keywords "java" "tools") (:url . "http://github.com/jdee-emacs/jdee"))])
+ (jedi . [(20191011 1750) ((emacs (24)) (jedi-core (0 2 2)) (auto-complete (1 4))) "a Python auto-completion for Emacs" single ((:commit . "81c5a42b83f3a3c9d062b487f48009def11310f8") (:authors ("Takafumi Arakaki <aka.tkf at gmail.com>")) (:maintainer "Takafumi Arakaki <aka.tkf at gmail.com>"))])
+ (jedi-core . [(20210503 1315) ((emacs (24)) (epc (0 1 0)) (python-environment (0 0 2)) (cl-lib (0 5))) "Common code of jedi.el and company-jedi.el" tar ((:commit . "81c5a42b83f3a3c9d062b487f48009def11310f8") (:authors ("Takafumi Arakaki <aka.tkf at gmail.com>")) (:maintainer "Takafumi Arakaki <aka.tkf at gmail.com>"))])
+ (jedi-direx . [(20140310 936) ((jedi (0 1 2)) (direx (0 1 -3))) "Tree style source code viewer for Python buffer" single ((:commit . "7a2e677400717ed12b959cb5988e7b3fb1c12117") (:authors ("Takafumi Arakaki <aka.tkf at gmail.com>")) (:maintainer "Takafumi Arakaki <aka.tkf at gmail.com>"))])
+ (jeison . [(20190721 1651) ((emacs (25 1)) (dash (2 16 0))) "A library for declarative JSON parsing" single ((:commit . "66e276c1f2f08ca54d2cd60f2c9f974c662aae8b") (:keywords "lisp" "json" "data-types") (:url . "http://github.com/SavchenkoValeriy/jeison"))])
+ (jekyll-modes . [(20141117 1314) ((polymode (0 2))) "Major modes (markdown and HTML) for authoring Jekyll content" single ((:commit . "7cb10b50fd2883e3f7b10fdfd98f19f2f0b2381c") (:authors ("Fredrik Appelberg" . "fredrik@milgrim.local")) (:maintainer "Fredrik Appelberg" . "fredrik@milgrim.local") (:keywords "docs") (:url . "https://github.com/fred-o/jekyll-modes"))])
+ (jemdoc-mode . [(20170704 2027) ((emacs (24 3))) "Major mode for editing jemdoc files" single ((:commit . "529b4d4681e1198b9892f340fdd6c3f1592a047a") (:authors ("Dimitar Dimitrov" . "mail.mitko@gmail.com")) (:maintainer "Dimitar Dimitrov" . "mail.mitko@gmail.com") (:keywords "convenience" "usability") (:url . "https://github.com/drdv/jemdoc-mode"))])
+ (jenkins . [(20200524 2016) ((dash (2 12)) (emacs (24 3)) (json (1 4))) "Minimalistic Jenkins client for Emacs" single ((:commit . "bd06cdc57c0cb9217d773eeba06ecc998f10033b") (:authors ("Rustem Muslimov" . "r.muslimov@gmail.com")) (:maintainer "Rustem Muslimov" . "r.muslimov@gmail.com") (:keywords "jenkins" "convenience"))])
+ (jenkins-watch . [(20121004 2326) nil "Watch continuous integration build status" single ((:commit . "37b84dfbd98240a57ff798e1ff8bc7dba2913577") (:authors ("Andrew Taylor" . "ataylor@redtoad.ca")) (:maintainer "Andrew Taylor" . "ataylor@redtoad.ca") (:url . "https://github.com/ataylor284/jenkins-watch"))])
+ (jenkinsfile-mode . [(20220428 1113) ((emacs (24)) (groovy-mode (2 0))) "Major mode for editing Jenkins declarative pipeline syntax" single ((:commit . "fa5545be1329df3067dcfd81749bbd99df070d6b") (:url . "https://github.com/john2x/jenkinsfile-mode"))])
+ (jest . [(20220114 213) ((emacs (24 4)) (dash (2 18 0)) (magit-popup (2 12 0)) (projectile (0 14 0)) (s (1 12 0)) (js2-mode (20180301)) (cl-lib (0 6 1))) "helpers to run jest" single ((:commit . "760a783a190afb23e12cf3cf3d8949e9a53c7c79") (:authors ("Edmund Miller" . "edmund.a.miller@gmail.com")) (:maintainer "Edmund Miller" . "edmund.a.miller@gmail.com") (:keywords "jest" "javascript" "testing") (:url . "https://github.com/emiller88/emacs-jest/"))])
+ (jest-test-mode . [(20220131 304) ((emacs (25 1))) "Minor mode for running Node.js tests using jest" single ((:commit . "e08326a467ccb1ec9ddf99c1f5d53f55c50e52b4") (:authors ("Raymond Huang" . "rymndhng@gmail.com")) (:maintainer "Raymond Huang" . "rymndhng@gmail.com") (:url . "https://github.com/rymndhng/jest-test-mode.el"))])
+ (jetbrains . [(20180301 502) ((emacs (24 3)) (cl-lib (0 5)) (f (0 17))) "JetBrains IDE bridge" single ((:commit . "56f71a17d455581c10d48f6dbb31d9e2126227bf") (:authors ("USAMI Kenta" . "tadsan@zonu.me")) (:maintainer "USAMI Kenta" . "tadsan@zonu.me") (:keywords "tools" "php") (:url . "https://github.com/emacs-php/jetbrains.el"))])
+ (jetbrains-darcula-theme . [(20210602 1430) nil "A complete port of the default JetBrains Darcula theme" single ((:commit . "296e3ca6e0341d9882f4771131a386fe2991e913") (:authors ("Ian Y.E. Pan")) (:maintainer "Ian Y.E. Pan") (:url . "https://github.com/ianpan870102/jetbrains-darcula-emacs-theme"))])
+ (jg-quicknav . [(20170809 130) ((s (1 9 0)) (cl-lib (0 5))) "Quickly navigate the file system to find a file." single ((:commit . "c8d53e774d63e68a944092c08a026b57da741038") (:authors ("Jeff Gran" . "jeff@jeffgran.com")) (:maintainer "Jeff Gran" . "jeff@jeffgran.com") (:keywords "navigation") (:url . "https://github.com/jeffgran/jg-quicknav"))])
+ (jinja2-mode . [(20220117 807) nil "A major mode for jinja2" single ((:commit . "03e5430a7efe1d163a16beaf3c82c5fd2c2caee1") (:authors ("Florian Mounier aka paradoxxxzero")) (:maintainer "Florian Mounier aka paradoxxxzero"))])
+ (jira-markup-mode . [(20150601 2109) nil "Emacs Major mode for JIRA-markup-formatted text files" single ((:commit . "4fc534c47df26a2f402bf835ebe2ed89474a4062") (:authors ("Matthias Nuessler" . "m.nuessler@web.de>")) (:maintainer "Matthias Nuessler" . "m.nuessler@web.de>") (:keywords "jira" "markup") (:url . "https://github.com/mnuessler/jira-markup-mode"))])
+ (jiralib2 . [(20200520 2031) ((emacs (25)) (request (0 3)) (dash (2 14 1))) "JIRA REST API bindings to Elisp" single ((:commit . "c21c4e759eff549dbda11099f2f680b78d7f5a01") (:authors ("Henrik Nyman" . "h@nyymanni.com")) (:maintainer "Henrik Nyman" . "h@nyymanni.com") (:keywords "comm" "jira" "rest" "api") (:url . "https://github.com/nyyManni/jiralib2"))])
+ (jist . [(20161229 1721) ((emacs (24 4)) (dash (2 12 0)) (seq (1 11)) (let-alist (1 0 4)) (magit (2 1 0)) (request (0 2 0))) "Gist integration" single ((:commit . "da0692452e312a99bb27d8708504b521798aca48") (:authors ("Mario Rodas" . "marsam@users.noreply.github.com")) (:maintainer "Mario Rodas" . "marsam@users.noreply.github.com") (:keywords "convenience") (:url . "https://github.com/emacs-pe/jist.el"))])
+ (jknav . [(20121006 2025) nil "Automatically enable j/k keys for line-based navigation" single ((:commit . "861245715c728503dad6573278fdd75c271dbf8b") (:authors ("Aaron Culich" . "aculich@gmail.com")) (:maintainer "Aaron Culich" . "aculich@gmail.com") (:keywords "keyboard" "navigation"))])
+ (jmt-mode . [(20220312 1945) ((emacs (24 4))) "Java Mode Tamed" single ((:commit . "44280538a2b780536c56ee2a51b7a5b03d376a2e") (:authors ("Michael Allan" . "mike@reluk.ca")) (:maintainer "Michael Allan" . "mike@reluk.ca") (:keywords "c" "languages") (:url . "http://reluk.ca/project/Java/Emacs/"))])
+ (jonprl-mode . [(20160819 59) ((emacs (24 3)) (cl-lib (0 5)) (yasnippet (0 8 0))) "A major mode for editing JonPRL files" tar ((:commit . "6059bb64891fae45827174e044d6a87ac07172d8") (:authors ("David Raymond Christiansen" . "david@davidchristiansen.dk")) (:maintainer "David Raymond Christiansen" . "david@davidchristiansen.dk") (:keywords "languages"))])
+ (journalctl-mode . [(20201217 1625) ((emacs (24 1))) "Sample major mode for viewing output journalctl" single ((:commit . "c5bca1a5f42d2fe2a00fdf52fe480137ace971d3") (:authors ("Sebastian Meisel" . "sebastian.meisel@gmail.com")) (:maintainer "Sebastian Meisel" . "sebastian.meisel@gmail.com") (:keywords "unix") (:url . "https://github.com/SebastianMeisel/journalctl-mode"))])
+ (jpop . [(20170410 1250) ((emacs (24)) (dash (2 11 0)) (cl-lib (0 5))) "Lightweight project caching and navigation framework" tar ((:commit . "7628b03260be96576b34459d45959ee77d8b2110") (:authors ("Dom Charlesworth" . "dgc336@gmail.com")) (:maintainer "Dom Charlesworth" . "dgc336@gmail.com") (:keywords "project" "convenience") (:url . "https://github.com/domtronn/jpop.el"))])
+ (jq-format . [(20190428 1434) ((emacs (24)) (reformatter (0 3))) "Reformat JSON and JSONLines using jq" single ((:commit . "47e1c5adb89b37b4d53fe01302d8c675913c20e7") (:authors ("wouter bolsterlee" . "wouter@bolsterl.ee")) (:maintainer "wouter bolsterlee" . "wouter@bolsterl.ee") (:keywords "languages") (:url . "https://github.com/wbolster/emacs-jq-format"))])
+ (jq-mode . [(20200604 833) ((emacs (25 1))) "Edit jq scripts." tar ((:commit . "1af31ba701cf844f938f840ed78867c9a28174b6") (:authors ("Bjarte Johansen <Bjarte dot Johansen at gmail dot com>")) (:maintainer "Bjarte Johansen <Bjarte dot Johansen at gmail dot com>") (:url . "https://github.com/ljos/jq-mode"))])
+ (jquery-doc . [(20150812 758) nil "jQuery api documentation interface for emacs" tar ((:commit . "24032284919b942ec27707d929bdd8bf48420062") (:authors ("Anantha kumaran" . "ananthakumaran@gmail.com")) (:maintainer "Anantha kumaran" . "ananthakumaran@gmail.com") (:keywords "docs" "jquery"))])
+ (js-auto-beautify . [(20161031 509) ((web-beautify (0 3 1)) (web-mode (14 0 27))) "auto format you js/jsx file" single ((:commit . "180d15af7b5dfaab4ee1954cca2fdc797932f9de") (:authors (nil . "quanwei9958@126.com")) (:maintainer nil . "quanwei9958@126.com"))])
+ (js-auto-format-mode . [(20180807 1352) ((emacs (24))) "Minor mode for auto-formatting JavaScript code" single ((:commit . "b8b4e3e54118b38fd6003cb97e1ff6e456a24f26") (:authors ("Masafumi Koba" . "ybiquitous@gmail.com")) (:maintainer "Masafumi Koba" . "ybiquitous@gmail.com") (:keywords "languages") (:url . "https://github.com/ybiquitous/js-auto-format-mode"))])
+ (js-codemod . [(20190921 941) ((emacs (24 4))) "Run js-codemod on current sentence or selected region" tar ((:commit . "056bdf3e5e0c807b8cf17edb5834179a90fb722b") (:authors (nil . "Torgeir Thoresen <@torgeir>")) (:maintainer nil . "Torgeir Thoresen <@torgeir>") (:keywords "js" "codemod" "region"))])
+ (js-comint . [(20200117 615) ((emacs (24 3))) "JavaScript interpreter in window." single ((:commit . "7920252e88eb610add7c9760f7016bb9b884307a") (:authors ("Paul Huff" . "paul.huff@gmail.com")) (:maintainer "Chen Bin <chenbin.sh AT gmail DOT com>") (:keywords "javascript" "node" "inferior-mode" "convenience") (:url . "https://github.com/redguardtoo/js-comint"))])
+ (js-doc . [(20160715 434) nil "Insert JsDoc style comment easily" single ((:commit . "f0606e89d5aa89146f96edb38cf69af0068a9d1e") (:authors ("mooz" . "stillpedant@gmail.com")) (:maintainer "mooz" . "stillpedant@gmail.com") (:keywords "document" "comment") (:url . "https://github.com/mooz/js-doc"))])
+ (js-format . [(20170119 102) ((emacs (24 1)) (js2-mode (20101228))) "Format or transform code style using NodeJS server with different javascript formatter" tar ((:commit . "544bda9be72b74ec2d442543ba60cff727d96669") (:authors ("James Yang" . "jamesyang999@gmail.com")) (:maintainer "James Yang" . "jamesyang999@gmail.com") (:keywords "js" "javascript" "format" "standard" "jsbeautify" "esformatter" "airbnb") (:url . "http://github.com/futurist/js-format.el"))])
+ (js-import . [(20210105 829) ((emacs (24 4)) (f (0 19 0)) (projectile (0 14 0)) (dash (2 13 0))) "Import Javascript files from your current project or dependencies" single ((:commit . "941091b3ab074c482a5920194d61f50e9b50d503") (:authors ("Jakob Lind" . "karl.jakob.lind@gmail.com")) (:maintainer "Jakob Lind" . "karl.jakob.lind@gmail.com") (:keywords "tools") (:url . "https://github.com/jakoblind/js-import"))])
+ (js-react-redux-yasnippets . [(20200316 1144) ((emacs (24 3)) (yasnippet (0 8 0))) "JavaScript,React,Redux yasnippets" tar ((:commit . "9f509043f01fa59bff4daf31b2e95d63f8deab4a") (:authors ("sooqua")) (:maintainer "sooqua") (:keywords "convenience" "snippets") (:url . "https://github.com/sooqua/js-react-redux-yasnippets"))])
+ (js2-closure . [(20170816 1918) ((js2-mode (20150909))) "Google Closure dependency manager" single ((:commit . "f59db386d7d0693935d0bf52babcd2c203c06d04") (:authors ("Justine Tunney" . "jart@google.com")) (:maintainer "Justine Tunney" . "jart@google.com") (:keywords "javascript" "closure") (:url . "http://github.com/jart/js2-closure"))])
+ (js2-highlight-vars . [(20170418 1829) ((emacs (24 4)) (js2-mode (20150908))) "highlight occurrences of the variable under cursor" single ((:commit . "e3bb177e50f76b272e8073a94d4f46be6512a163") (:authors ("Mihai Bazon" . "mihai.bazon@gmail.com")) (:maintainer "Mihai Bazon" . "mihai.bazon@gmail.com") (:url . "http://mihai.bazon.net/projects/editing-javascript-with-emacs-js2-mode/js2-highlight-vars-mode"))])
+ (js2-mode . [(20220402 2211) ((emacs (24 1)) (cl-lib (0 5))) "Improved JavaScript editing mode" tar ((:commit . "fed41615b26404e0bfd7e4f64643981ca798a34b") (:authors ("Steve Yegge" . "steve.yegge@gmail.com") ("mooz" . "stillpedant@gmail.com") ("Dmitry Gutov" . "dgutov@yandex.ru")) (:maintainer "Steve Yegge" . "steve.yegge@gmail.com") (:keywords "languages" "javascript") (:url . "https://github.com/mooz/js2-mode/"))])
+ (js2-refactor . [(20210306 2003) ((js2-mode (20101228)) (s (1 9 0)) (multiple-cursors (1 0 0)) (dash (1 0 0)) (s (1 0 0)) (yasnippet (0 9 0 1))) "A JavaScript refactoring library for emacs." tar ((:commit . "a0977c4ce1918cc266db9d6cd7a2ab63f3a76b9a") (:authors ("Magnar Sveen" . "magnars@gmail.com") ("Nicolas Petton" . "nicolas@petton.fr")) (:maintainer "Magnar Sveen" . "magnars@gmail.com") (:keywords "conveniences"))])
+ (js2hl . [(20201119 816) ((emacs (25 1)) (js2-mode (20190219))) "Highlight/rename things using js2-mode parser" single ((:commit . "ab01c290860ab0d8f43afcf1f7466fdced24e123") (:authors ("Chen Bin <chenbin DOT sh AT gmail DOT com>")) (:maintainer "Chen Bin <chenbin DOT sh AT gmail DOT com>") (:keywords "convenience") (:url . "https://github.com/redguardtoo/js2hl"))])
+ (js3-mode . [(20160515 1550) nil "An improved JavaScript editing mode" tar ((:commit . "229aeb374f1b1f3ee5c59b8ba3eebb6385c232cb") (:authors ("Thom Blake" . "webmaster@thomblake.com")) (:maintainer "Thom Blake" . "webmaster@thomblake.com") (:keywords "javascript" "languages"))])
+ (jscs . [(20151015 1749) ((emacs (24 1)) (cl-lib (0 5))) "Consistent JavaScript editing using JSCS" single ((:commit . "9d39d0f2355e69a020bf76242504f3a33e013ccf") (:authors ("papaeye" . "papaeye@gmail.com")) (:maintainer "papaeye" . "papaeye@gmail.com") (:keywords "languages" "convenience") (:url . "https://github.com/papaeye/emacs-jscs"))])
+ (jsfmt . [(20180920 1008) nil "Interface to jsfmt command for javascript files" single ((:commit . "ca141a135c7700eaedef92561d334e1fb7dc28a1") (:authors ("Brett Langdon" . "brett@blangdon.com")) (:maintainer "Brett Langdon" . "brett@blangdon.com") (:url . "https://github.com/brettlangdon/jsfmt.el"))])
+ (json-mode . [(20211011 630) ((json-snatcher (1 0 0)) (emacs (24 4))) "Major mode for editing JSON files." single ((:commit . "eedb4560034f795a7950fa07016bd4347c368873") (:authors ("Josh Johnston")) (:maintainer "Josh Johnston") (:url . "https://github.com/joshwnj/json-mode"))])
+ (json-navigator . [(20191213 755) ((emacs (25 1)) (hierarchy (0 6 0))) "View and navigate JSON structures" single ((:commit . "afd902e0b5cde37fad4786515a695d17f1625286") (:authors ("Damien Cassou" . "damien@cassou.me")) (:maintainer "Damien Cassou" . "damien@cassou.me") (:url . "https://github.com/DamienCassou/json-navigator"))])
+ (json-par . [(20220122 352) ((emacs (24 4)) (json-mode (1 7 0))) "Minor mode for structural editing of JSON" tar ((:commit . "962e5a2221136aa07f512834925c381cfeed2d92") (:authors ("taku0 (http://github.com/taku0)")) (:maintainer "taku0 (http://github.com/taku0)") (:keywords "abbrev" "convenience" "files") (:url . "https://github.com/taku0/json-par"))])
+ (json-process-client . [(20210525 733) ((emacs (25 1))) "Interact with a TCP process using JSON" single ((:commit . "373b2cc7e3d26dc00594e0b2c1bb66815aad2826") (:authors ("Nicolas Petton" . "nicolas@petton.fr") ("Damien Cassou" . "damien@cassou.me")) (:maintainer "Nicolas Petton" . "nicolas@petton.fr") (:url . "https://gitlab.petton.fr/nico/json-process-client"))])
+ (json-reformat . [(20160212 853) nil "Reformatting tool for JSON" single ((:commit . "8eb6668ed447988aea06467ba8f42e1f2178246f") (:authors ("Wataru MIYAGUNI" . "gonngo@gmail.com")) (:maintainer "Wataru MIYAGUNI" . "gonngo@gmail.com") (:keywords "json") (:url . "https://github.com/gongo/json-reformat"))])
+ (json-rpc . [(20200417 1629) ((emacs (24 1)) (cl-lib (0 5))) "JSON-RPC library" single ((:commit . "81a5a520072e20d18aeab2aac4d66c046b031e56") (:authors ("Christopher Wellons" . "wellons@nullprogram.com")) (:maintainer "Christopher Wellons" . "wellons@nullprogram.com") (:url . "https://github.com/skeeto/elisp-json-rpc"))])
+ (json-rpc-server . [(20220205 1503) ((emacs (26))) "Server-side JSON-RPC library." single ((:commit . "9bf7efd5c69f429acbac41f33a1c9fdaddcb9914") (:authors ("GitHub user \"Jcaw\"")) (:maintainer "GitHub user \"Jcaw\"") (:keywords "tools" "comm" "json" "rpc") (:url . "https://github.com/jcaw/json-rpc-server.el"))])
+ (json-snatcher . [(20200916 1717) ((emacs (24))) "Grabs the path to JSON values in a JSON file" single ((:commit . "b28d1c0670636da6db508d03872d96ffddbc10f2") (:authors ("Sterling Graham" . "sterlingrgraham@gmail.com")) (:maintainer "Sterling Graham" . "sterlingrgraham@gmail.com") (:url . "http://github.com/sterlingg/json-snatcher"))])
+ (jsonl . [(20190623 509) ((emacs (25))) "Utility functions for working with line-delimited JSON" single ((:commit . "3dd0b7bb2b4bce9f9de7367941f0cc78f82049c9") (:authors ("Erik Anderson" . "erik@ebpa.link")) (:maintainer "Erik Anderson" . "erik@ebpa.link") (:keywords "tools") (:url . "https://github.com/ebpa/jsonl.el"))])
+ (jsonnet-mode . [(20220121 2109) ((emacs (24)) (dash (2 17 0))) "Major mode for editing jsonnet files" single ((:commit . "7c9961b084b1ea352555317076bc27a512dd341f") (:authors ("Nick Lanham")) (:maintainer "Nick Lanham") (:keywords "languages") (:url . "https://github.com/mgyucht/jsonnet-mode"))])
+ (jss . [(20130508 1423) ((emacs (24 1)) (websocket (0)) (js2-mode (0))) "An emacs interface to webkit and mozilla debuggers" tar ((:commit . "41749257aecf13c7bd6ed489b5ab3304d06e40bc") (:authors ("Marco Baringer" . "mb@bese.it")) (:maintainer "Marco Baringer" . "mb@bese.it") (:keywords "languages"))])
+ (jst . [(20150604 1138) ((s (1 9)) (f (0 17)) (dash (2 10)) (pcache (0 3)) (emacs (24 4))) "JS test mode" single ((:commit . "2a3fd16c992f7790dc67134ef06a814c3d20579c") (:authors ("Cheung Hoi Yu" . "yeannylam@gmail.com")) (:maintainer "Cheung Hoi Yu" . "yeannylam@gmail.com") (:keywords "js" "javascript" "jasmine" "coffee" "coffeescript") (:url . "https://github.com/cheunghy/jst-mode"))])
+ (jtags . [(20160211 2029) nil "enhanced tags functionality for Java development" tar ((:commit . "b50daa48510f71e74ce0ec2eb85030896a79cf96") (:authors ("Alexander Baltatzis" . "alexander@baltatzis.com") ("Johan Dykstrom" . "jody4711-sf@yahoo.se")) (:maintainer "Johan Dykstrom" . "jody4711-sf@yahoo.se") (:keywords "languages" "tools") (:url . "http://jtags.sourceforge.net"))])
+ (julia-formatter . [(20220106 1414) ((emacs (27 1))) "Use JuliaFormatter.jl for julia code" single ((:commit . "a86a526a4e5755eaa67b2d9c040c5679d6f04bf4") (:authors ("Felipe Lema" . "felipe.lema@mortemale.org")) (:maintainer "Felipe Lema" . "felipe.lema@mortemale.org") (:keywords "convenience" "tools") (:url . "https://codeberg.org/FelipeLema/julia-formatter.el"))])
+ (julia-mode . [(20220418 809) ((emacs (24 3))) "Major mode for editing Julia source code" tar ((:commit . "adf4029be778c5983c436873b8a78bc72a6b09f8") (:keywords "languages") (:url . "https://github.com/JuliaEditorSupport/julia-emacs"))])
+ (julia-repl . [(20220428 541) ((emacs (25 1)) (s (1 12))) "A minor mode for a Julia REPL" single ((:commit . "2342003662071cf7b256f0a7cd8f545bcffaf22a") (:authors ("Tamas Papp" . "tkpapp@gmail.com")) (:maintainer "Tamas Papp" . "tkpapp@gmail.com") (:keywords "languages") (:url . "https://github.com/tpapp/julia-repl"))])
+ (julia-shell . [(20161125 1910) ((julia-mode (0 3))) "Major mode for an inferior Julia shell" tar ((:commit . "583a0b2ca20461ab4356929fd0f2212c22341b69") (:authors ("Dennis Ogbe" . "dogbe@purdue.edu")) (:maintainer "Dennis Ogbe" . "dogbe@purdue.edu"))])
+ (julia-snail . [(20220420 455) ((emacs (26 2)) (dash (2 16 0)) (julia-mode (0 3)) (s (1 12 0)) (spinner (1 7 3)) (vterm (0 0 1))) "Julia Snail" tar ((:commit . "d72afe0e06909ee5a66ca7d60eef4111f62da234") (:url . "https://github.com/gcv/julia-snail"))])
+ (julia-vterm . [(20220503 7) ((emacs (25 1)) (vterm (0 0 1))) "A mode for Julia REPL using vterm" single ((:commit . "443924f6eb77d64a20b4b34a99d3c7d2d54f73a8") (:authors ("Shigeaki Nishina")) (:maintainer "Shigeaki Nishina") (:keywords "languages" "julia") (:url . "https://github.com/shg/julia-vterm.el"))])
+ (jumblr . [(20170727 2043) ((s (1 8 0)) (dash (2 2 0))) "an anagram game for emacs" tar ((:commit . "34533dfb9db8538c005f4eaffafeff7ed193729f") (:keywords "anagram" "word game" "games") (:url . "https://github.com/mkmcc/jumblr"))])
+ (jump . [(20161127 128) ((findr (0 7)) (inflections (2 4)) (cl-lib (0 5))) "build functions which contextually jump between files" single ((:commit . "55caa66a7cc6e0b1a76143fd40eff38416928941") (:authors ("Eric Schulte")) (:maintainer "Eric Schulte") (:keywords "project" "convenience" "navigation") (:url . "http://github.com/eschulte/jump.el"))])
+ (jump-char . [(20180601 1348) nil "navigation by char" single ((:commit . "1e31a3c687f2b3c71bbfab881c6d75915534bb9e") (:authors ("Le Wang")) (:maintainer "Le Wang") (:url . "https://github.com/lewang/jump-char"))])
+ (jump-to-line . [(20130122 1653) nil "Jump to line number at point." single ((:commit . "01ef8c3529d85e6c59cc20840acbc4a8e8325bc8") (:authors ("ongaeshi")) (:maintainer "ongaeshi") (:keywords "jump" "line" "back" "file" "ruby" "csharp" "python" "perl"))])
+ (jump-tree . [(20171014 1551) nil "Treat position history as a tree" tar ((:commit . "282267dc6305889e31d46b405b7ad4dfe5923b66") (:authors ("Wen Yang" . "yangwen0228@foxmail.com")) (:maintainer "Wen Yang" . "yangwen0228@foxmail.com") (:keywords "convenience" "position" "jump" "tree") (:url . "https://github.com/yangwen0228/jump-tree"))])
+ (jumplist . [(20151120 345) ((cl-lib (0 5))) "Jump like vim jumplist or ex jumplist" single ((:commit . "c482d137d95bc5e1bcd790cdbde25b7f729b2502") (:authors ("ganmacs <ganmacs_at_gmail.com>")) (:maintainer "ganmacs <ganmacs_at_gmail.com>") (:keywords "jumplist" "vim") (:url . "https://github.com/ganmacs/jumplist"))])
+ (jupyter . [(20220419 1852) ((emacs (26)) (zmq (0 10 3)) (cl-lib (0 5)) (simple-httpd (1 5 0)) (websocket (1 9))) "Jupyter" tar ((:commit . "7d20c0aee2f9c896215f35232905b23532ef04c5") (:authors ("Nathaniel Nicandro" . "nathanielnicandro@gmail.com")) (:maintainer "Nathaniel Nicandro" . "nathanielnicandro@gmail.com") (:url . "https://github.com/dzop/emacs-jupyter"))])
+ (just-mode . [(20220401 1814) ((emacs (26 1))) "Justfile editing mode" single ((:commit . "35f1bd4748cd3e960e6930b34310e5506212b304") (:authors ("Leon Barrett" . "leon@barrettnexus.com")) (:maintainer "Leon Barrett" . "leon@barrettnexus.com") (:keywords "files" "languages" "tools") (:url . "https://github.com/leon-barrett/just-mode.el"))])
+ (justl . [(20220312 1104) ((transient (0 1 0)) (emacs (25 3)) (xterm-color (2 0)) (s (1 2 0)) (f (0 20 0))) "Major mode for driving just files" single ((:commit . "9f77366aaf2227bb0cbd3cdc0f78088032f2e873") (:authors ("Sibi Prabakaran")) (:maintainer "Sibi Prabakaran") (:keywords "just" "justfile" "tools" "processes") (:url . "https://github.com/psibi/justl.el"))])
+ (jvm-mode . [(20150422 708) ((dash (2 6 0)) (emacs (24))) "Monitor and manage your JVMs" single ((:commit . "3355dbaf5b0185aadfbad24160399abb32c5bea0") (:authors ("Martin Trojer" . "martin.trojer@gmail.com")) (:maintainer "Martin Trojer" . "martin.trojer@gmail.com") (:keywords "convenience") (:url . "https://github.com/martintrojer/jvm-mode.el"))])
+ (k8s-mode . [(20211121 518) ((emacs (24 3)) (yaml-mode (0 0 10))) "Major mode for Kubernetes configuration file" tar ((:commit . "083bcffbfeeaf5e79015a012b4dbf2f283a493ab") (:authors ("Giap Tran" . "txgvnn@gmail.com")) (:maintainer "Giap Tran" . "txgvnn@gmail.com") (:url . "https://github.com/TxGVNN/emacs-k8s-mode"))])
+ (kaesar . [(20160128 1008) ((cl-lib (0 3))) "Another AES algorithm encrypt/decrypt string with password." single ((:commit . "d087075cb1a46c2c85cd075220e09b2eaef9b86e") (:authors ("Masahiro Hayashi" . "mhayashi1120@gmail.com")) (:maintainer "Masahiro Hayashi" . "mhayashi1120@gmail.com") (:keywords "data") (:url . "https://github.com/mhayashi1120/Emacs-kaesar"))])
+ (kaesar-file . [(20160128 1008) ((kaesar (0 1 1))) "Encrypt/Decrypt file by AES with password." single ((:commit . "d087075cb1a46c2c85cd075220e09b2eaef9b86e") (:authors ("Masahiro Hayashi" . "mhayashi1120@gmail.com")) (:maintainer "Masahiro Hayashi" . "mhayashi1120@gmail.com") (:keywords "data" "files") (:url . "https://github.com/mhayashi1120/Emacs-kaesar"))])
+ (kaesar-mode . [(20160128 1008) ((kaesar (0 1 4)) (cl-lib (0 3))) "Encrypt/Decrypt buffer by AES with password." single ((:commit . "d087075cb1a46c2c85cd075220e09b2eaef9b86e") (:authors ("Masahiro Hayashi" . "mhayashi1120@gmail.com")) (:maintainer "Masahiro Hayashi" . "mhayashi1120@gmail.com") (:keywords "data" "convenience") (:url . "https://github.com/mhayashi1120/Emacs-kaesar"))])
+ (kakapo-mode . [(20171004 451) ((cl-lib (0 5))) "TABS (hard or soft) for indentation (leading whitespace), and SPACES for alignment." single ((:commit . "292e07203c676361a1d918deb5acf2123cd70eaf") (:keywords "indentation") (:url . "https://github.com/listx/kakapo-mode"))])
+ (kakoune . [(20210220 1858) ((ryo-modal (0 45)) (multiple-cursors (1 4)) (expand-region (0 11 0)) (emacs (25 1))) "A simulation, but not emulation, of kakoune" tar ((:commit . "d81bd00323ba10343a28bc855ee5ddbd09b7d2a5") (:authors ("Joseph Morag" . "jm4157@columbia.edu")) (:maintainer "Joseph Morag" . "jm4157@columbia.edu") (:url . "https://github.com/jmorag/kakoune.el"))])
+ (kaleidoscope . [(20170808 817) ((s (1 11 0))) "Controlling Kaleidoscope-powered devices." single ((:commit . "af4034dcace867c4ede0bce744d5cb888c318f23") (:authors ("Gergely Nagy")) (:maintainer "Gergely Nagy") (:url . "https://github.com/algernon/kaleidoscope.el"))])
+ (kaleidoscope-evil-state-flash . [(20170728 1020) ((evil (1 2 12)) (kaleidoscope (0 1 0)) (s (1 11 0))) "Flash keyboard LEDs when changing Evil state" single ((:commit . "af4034dcace867c4ede0bce744d5cb888c318f23") (:authors ("Gergely Nagy")) (:maintainer "Gergely Nagy") (:url . "https://github.com/algernon/kaleidoscope.el"))])
+ (kana . [(20210531 1427) ((emacs (24 4)) (dash (2 17 0))) "Learn Japanese hiragana and katakana" single ((:commit . "d3d550aad67ef8625b3860598bf3622f5b2a7d32") (:authors ("Damon Chan" . "elecming@gmail.com")) (:maintainer "Damon Chan" . "elecming@gmail.com") (:keywords "tools") (:url . "https://github.com/chenyanming/kana"))])
+ (kanban . [(20170418 810) nil "Parse org-todo headlines to use org-tables as Kanban tables" single ((:commit . "fcf0173ce0144e59de97ba8a7808192620e5f8f4") (:authors ("Arne Babenhauserheide" . "arne_bab@web.de")) (:maintainer "Arne Babenhauserheide" . "arne_bab@web.de") (:keywords "outlines" "convenience"))])
+ (kanji-mode . [(20160826 1139) nil "View stroke order for kanji characters at cursor" tar ((:commit . "eda4f8666486689d36317db7dbda54fb73d3e3d2") (:authors ("Wojciech Gac" . "wojciech.s.gac@gmail.com")) (:maintainer "Wojciech Gac" . "wojciech.s.gac@gmail.com") (:url . "http://github.com/wsgac/kanji-mode "))])
+ (kaocha-runner . [(20190904 1950) ((emacs (26)) (s (1 4 0)) (cider (0 21 0)) (parseedn (0 1 0))) "A package for running Kaocha tests via CIDER." single ((:commit . "755b0dfb3bd676c769c4b4aeb81c2cd5828bd207") (:authors ("Magnar Sveen" . "magnars@gmail.com")) (:maintainer "Magnar Sveen" . "magnars@gmail.com") (:url . "https://github.com/magnars/kaocha-runner.el"))])
+ (kaolin-themes . [(20220422 1305) ((emacs (25 1)) (autothemer (0 2 2)) (cl-lib (0 6))) "A set of eye pleasing themes" tar ((:commit . "51b1f719bc300a4f684b6dc7511dfb044f75f575") (:authors ("Ogden Webb" . "ogdenwebb@gmail.com")) (:maintainer "Ogden Webb" . "ogdenwebb@gmail.com") (:keywords "dark" "light" "teal" "blue" "violet" "purple" "brown" "theme" "faces") (:url . "https://github.com/ogdenwebb/emacs-kaolin-themes"))])
+ (kaomoji . [(20171227 440) ((emacs (24 3)) (helm-core (1 9 1))) "Input kaomoji superb easily" tar ((:commit . "90a1490743b2a30762f5454c9d9309018eff83dd") (:authors ("Ono Hiroko" . "azazabc123@gmail.com")) (:maintainer "Ono Hiroko" . "azazabc123@gmail.com") (:keywords "tools" "fun") (:url . "https://github.com/kuanyui/kaomoji.el"))])
+ (kapacitor . [(20190414 1908) ((emacs (25 1)) (magit (2 13 0)) (magit-popup (2 12 4))) "Main file for kapacitor-mode" single ((:commit . "e3300d8b4017a2f66b0d929cb85bcc7ee2612072") (:authors ("Manoj Kumar Manikchand" . "manojm.321@gmail.com")) (:maintainer "Manoj Kumar Manikchand" . "manojm.321@gmail.com") (:keywords "kapacitor" "emacs" "magit" "tools") (:url . "http://github.com/Manoj321/kapacitor-el"))])
+ (karma . [(20160220 1245) ((pkg-info (0 4)) (emacs (24))) "Karma Test Runner Emacs Integration" single ((:commit . "31d3e7708246183d7ed0686be92bf23140af348c") (:authors ("Samuel Tonini")) (:maintainer "Samuel Tonini") (:keywords "language" "javascript" "js" "karma" "testing") (:url . "http://github.com/tonini/karma.el"))])
+ (kconfig-mode . [(20211018 2142) ((emacs (24 3))) "Major mode for editing Kconfig files" single ((:commit . "241436a507782d18f09dab7d1f373ddea60fad3d") (:authors ("Dela Anthonio" . "dell.anthonio@gmail.com")) (:maintainer "Dela Anthonio" . "dell.anthonio@gmail.com") (:keywords "kconfig" "languages" "linux" "kernel") (:url . "https://github.com/delaanthonio/kconfig-mode"))])
+ (kdeconnect . [(20210519 2016) nil "An interface for KDE Connect" single ((:commit . "4977af8cb5fdc21da770f3ee43ad7823f2937da3") (:authors ("Carl Lieberman" . "dev@carl.ac")) (:maintainer "Carl Lieberman" . "dev@carl.ac") (:keywords "kdeconnect" "android"))])
+ (keepass-mode . [(20211030 948) ((emacs (27))) "Mode to open Keepass DB" single ((:commit . "be190a86fd82337fe5280c1833f92d1f9997bced") (:authors ("Ignasi Fosch" . "natx@y10k.ws")) (:maintainer "Ignasi Fosch" . "natx@y10k.ws") (:keywords "data" "files" "tools") (:url . "https://github.com/ifosch/keepass-mode"))])
+ (keg . [(20220309 647) ((emacs (24 1))) "Modern Elisp package development system" tar ((:commit . "944e36144d92a798e1fd0f3d83fc6347d57a976e") (:authors ("Naoya Yamashita" . "conao3@gmail.com")) (:maintainer "Naoya Yamashita" . "conao3@gmail.com") (:keywords "convenience") (:url . "https://github.com/conao3/keg.el"))])
+ (keg-mode . [(20220307 829) ((emacs (24 4))) "Major mode for editing Keg files" single ((:commit . "944e36144d92a798e1fd0f3d83fc6347d57a976e") (:authors ("Naoya Yamashita" . "conao3@gmail.com")) (:maintainer "Naoya Yamashita" . "conao3@gmail.com") (:keywords "convenience") (:url . "https://github.com/conao3/keg.el"))])
+ (kerl . [(20150424 2005) nil "Emacs integration for kerl" single ((:commit . "1732ee26213f021bf040919c45ad276aafcaae14") (:authors ("Correl Roush" . "correl@gmail.com")) (:maintainer "Correl Roush" . "correl@gmail.com") (:keywords "tools") (:url . "http://github.com/correl/kerl.el/"))])
+ (key-assist . [(20210722 758) ((emacs (24 3))) "Minibuffer keybinding cheatsheet and launcher" single ((:commit . "8e5cd089e0b2fedec57c55eeff74cdb6121441aa") (:authors ("Boruch Baum" . "boruch_baum@gmx.com")) (:maintainer "Boruch Baum" . "boruch_baum@gmx.com") (:keywords "abbrev" "convenience" "docs" "help") (:url . "https://github.com/Boruch-Baum/emacs-key-assist"))])
+ (key-chord . [(20201222 2030) ((emacs (24))) "map pairs of simultaneously pressed keys to commands" single ((:commit . "7f7fd7c5bd2b996fa054779357e1566f7989e07d") (:authors ("David Andersson <l.david.andersson(at)sverige.nu>")) (:maintainer "David Andersson <l.david.andersson(at)sverige.nu>") (:keywords "keyboard" "chord" "input"))])
+ (key-combo . [(20150324 1439) nil "map key sequence to commands" single ((:commit . "2fb5c65bc82d5bd2964e2b163822429ab45d90a1") (:authors ("Yuuki Arisawa" . "yuuki.ari@gmail.com")) (:maintainer "Vitalie Spinu" . "spinuvit@gmail.com") (:keywords "keyboard" "input") (:url . "https://github.com/uk-ar/key-combo"))])
+ (key-intercept . [(20140211 749) nil "Intercept prefix keys" single ((:commit . "d9a60edb4ce893f2d3d94f242164fdcc62d43cf2") (:authors ("INA Lintaro <tarao.gnn at gmail.com>")) (:maintainer "INA Lintaro <tarao.gnn at gmail.com>") (:keywords "keyboard") (:url . "http://github.com/tarao/key-intercept-el"))])
+ (key-leap . [(20160831 1447) ((emacs (24 3))) "Leap between lines by typing keywords" single ((:commit . "b3f6ef15c8a13870475d5af159fa24b30f97dea0") (:authors ("Martin Rykfors" . "martinrykfors@gmail.com")) (:maintainer "Martin Rykfors" . "martinrykfors@gmail.com") (:keywords "point" "convenience") (:url . "https://github.com/MartinRykfors/key-leap"))])
+ (key-quiz . [(20200226 2129) ((emacs (26))) "Emacs Keys Quiz" single ((:commit . "6d31fcf78a1ab1841f735dfb5cbd2bf6b2ed25db") (:authors ("Federico Tedin" . "federicotedin@gmail.com")) (:maintainer "Federico Tedin" . "federicotedin@gmail.com") (:keywords "games") (:url . "https://github.com/federicotdn/key-quiz"))])
+ (key-seq . [(20150907 756) ((key-chord (0 6))) "map pairs of sequentially pressed keys to commands" single ((:commit . "e29b083a6427d061638749194fc249ef69ad2cc0") (:authors ("Vyacheslav Levit" . "dev@vlevit.org")) (:maintainer "Vyacheslav Levit" . "dev@vlevit.org") (:keywords "convenience" "keyboard" "keybindings") (:url . "http://github.com/vlevit/key-seq.el"))])
+ (keycast . [(20220422 1611) ((emacs (25 3)) (compat (28 1 1 0))) "Show current command and its binding" single ((:commit . "0c37db482ca98e729430121209d70dd093082a5e") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:keywords "multimedia") (:url . "https://github.com/tarsius/keycast"))])
+ (keychain-environment . [(20180318 2223) nil "load keychain environment variables" single ((:commit . "d3643196de6dc79ea77f9f4805028350fd76100b") (:authors ("Paul Tipper <bluefoo at googlemail dot com>")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:keywords "gnupg" "pgp" "ssh") (:url . "https://github.com/tarsius/keychain-environment"))])
+ (keydef . [(20090428 1931) nil "a simpler way to define keys, with kbd syntax" single ((:commit . "dff2be9f58d12d8c6a490ad0c1b2b10b55528dc0") (:authors ("Michael John Downes" . "mjd@ams.org")) (:maintainer "Michael John Downes" . "mjd@ams.org") (:keywords "convenience" "lisp" "customization" "keyboard" "keys"))])
+ (keyfreq . [(20210630 1318) ((cl-lib (0 5))) "track command frequencies" single ((:commit . "7bb36e910ae04ff1dce387e3ce73b669d299680b") (:authors ("Ryan Yeske, Michal Nazarewicz (mina86/AT/mina86.com)")) (:maintainer "David Capello, Xah lee"))])
+ (keymap-utils . [(20220422 1612) ((emacs (25 1)) (compat (28 1 1 0))) "Keymap utilities" single ((:commit . "0fd91fef890fb4c18c552e5ecaddd53c9bdac2bd") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:keywords "convenience" "extensions") (:url . "https://github.com/tarsius/keymap-utils"))])
+ (keypress-multi-event . [(20190109 530) ((emacs (24 3))) "Perform different actions for the same keypress." single ((:commit . "f7041deccd9d03066c2fe41c3443c42a4713ac02") (:authors ("Boruch Baum" . "boruch_baum@gmx.com")) (:maintainer "Boruch Baum" . "boruch_baum@gmx.com") (:keywords "abbrev" "convenience" "wp" "keyboard") (:url . "https://www.github.com/Boruch_Baum/emacs-keypress-multi-event"))])
+ (keypression . [(20200819 534) ((emacs (26 3))) "Keystroke visualizer" single ((:commit . "9427241f3fa539e4b5ad7581a05eb7e49f2cf518") (:authors ("chuntaro" . "chuntaro@sakura-games.jp")) (:maintainer "chuntaro" . "chuntaro@sakura-games.jp") (:keywords "key" "screencast" "tools") (:url . "https://github.com/chuntaro/emacs-keypression"))])
+ (keyset . [(20150220 530) ((dash (2 8 0)) (cl-lib (0 5))) "A small library for structuring key bindings." single ((:commit . "45ce83c4b56f064874256db37e697a63b2c69e65") (:authors ("Hiroki YAMAKAWA" . "s06139@gmail.com")) (:maintainer "Hiroki YAMAKAWA" . "s06139@gmail.com") (:url . "https://github.com/HKey/keyset"))])
+ (keystore-mode . [(20190409 1946) ((emacs (24 3)) (origami (1 0)) (s (1 12 0)) (seq (2 20))) "A major mode for viewing and managing (java) keystores" tar ((:commit . "43bd5926348298d077c7221f37902c990df3f951") (:authors ("Peterpaul Taekele Klein Haneveld" . "pp.kleinhaneveld@gmail.com")) (:maintainer "Peterpaul Taekele Klein Haneveld" . "pp.kleinhaneveld@gmail.com") (:keywords "tools") (:url . "https://github.com/peterpaul/keystore-mode"))])
+ (keyswap . [(20160813 957) ((emacs (24 3))) "swap bindings between key pairs" single ((:commit . "cd682a7c4a8d64d6bae6a005db5045232e5e7b95") (:authors ("Matthew Malcomson" . "hardenedapple@gmail.com")) (:maintainer "Matthew Malcomson" . "hardenedapple@gmail.com") (:keywords "convenience") (:url . "http://github.com/hardenedapple/keyswap.el"))])
+ (keytar . [(20220222 639) ((emacs (24 4))) "Emacs Lisp interface for node-keytar" single ((:commit . "5236c2aa6a4f2deeb0421c7d1c315ed9e6b6222a") (:authors ("Shen, Jen-Chieh" . "jcs090218@gmail.com")) (:maintainer "Shen, Jen-Chieh" . "jcs090218@gmail.com") (:url . "https://github.com/emacs-grammarly/keytar"))])
+ (keyword-search . [(20180424 1102) nil "browser keyword search from Emacs" tar ((:commit . "f8475ecaddb8804a9be6bee47678207c86ac8dee") (:maintainer "Jens Petersen") (:keywords "web" "search" "keyword") (:url . "https://github.com/juhp/keyword-search"))])
+ (kfg . [(20140909 538) ((f (0 17 1))) "an emacs configuration system" single ((:commit . "d2c9dd26618fb2f7bf1e7b6eae193b1cceba3c97") (:authors ("Austin Bingham" . "austin.bingham@gmail.com")) (:maintainer "Austin Bingham" . "austin.bingham@gmail.com") (:url . "https://github.com/abingham/kfg"))])
+ (khalel . [(20211114 1233) ((emacs (27 1))) "Import, edit and create calendar events through khal" single ((:commit . "a0503498ae43a50157549c661381d94578ad2bd7") (:authors ("Hanno Perrey <http://gitlab.com/hperrey>")) (:maintainer "Hanno Perrey" . "hanno@hoowl.se") (:keywords "event" "calendar" "ics" "khal") (:url . "https://gitlab.com/hperrey/khalel"))])
+ (khardel . [(20220223 934) ((emacs (27 1)) (yaml-mode (0 0 13))) "Integrate with khard" tar ((:commit . "1436ec5ef1b5b26104a4735ee64c0afe148700de") (:authors ("Damien Cassou" . "damien@cassou.me")) (:maintainer "Damien Cassou" . "damien@cassou.me") (:url . "https://github.com/DamienCassou/khardel"))])
+ (kibit-helper . [(20150508 1533) ((s (0 8)) (emacs (24))) "Conveniently use the Kibit Leiningen plugin from Emacs" single ((:commit . "16bdfff785ee05d8e74a5780f6808506d990cef7") (:authors ("Jonas Enlund") ("James Elliott" . "james@brunchboy.com")) (:maintainer "Jonas Enlund") (:keywords "languages" "clojure" "kibit") (:url . "http://www.github.com/brunchboy/kibit-helper"))])
+ (kill-or-bury-alive . [(20210320 1231) ((emacs (24 4)) (cl-lib (0 5))) "Precise control over buffer killing in Emacs" single ((:commit . "534300796d5dc528462e2d5deb4c7a8932936909") (:authors ("Mark Karpov" . "markkarpov92@gmail.com")) (:maintainer "Mark Karpov" . "markkarpov92@gmail.com") (:keywords "buffer" "killing" "convenience") (:url . "https://github.com/mrkkrp/kill-or-bury-alive"))])
+ (kill-ring-search . [(20140422 1555) nil "incremental search for the kill ring" single ((:commit . "23535b4a01a1cb1574604e36c49614e84e85c883") (:authors ("Nikolaj Schumacher <bugs * nschum de>")) (:maintainer "Nikolaj Schumacher <bugs * nschum de>") (:keywords "convenience" "matching") (:url . "http://nschum.de/src/emacs/kill-ring-search/"))])
+ (killer . [(20190128 10) nil "kill and delete text" single ((:commit . "ace0547944933440384ceeb5876b1f68c082d540") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:keywords "convenience") (:url . "http://github.com/tarsius/killer"))])
+ (kite . [(20130201 1938) ((json (1 2)) (websocket (0 93 1))) "WebKit inspector front-end" tar ((:commit . "7ed74d1147a6ddd152d3da65dc30df3517d53144") (:authors ("Julian Scheid" . "julians37@gmail.com")) (:maintainer "Julian Scheid" . "julians37@gmail.com") (:keywords "tools"))])
+ (kite-mini . [(20160508 1106) ((dash (2 11 0)) (websocket (1 5))) "Remotely evaluate JavaScript in the WebKit debugger" tar ((:commit . "a68619dbc109c7989f3448426d8c1ee9e797c11f") (:authors ("Tung Dao" . "me@tungdao.com")) (:maintainer "Tung Dao" . "me@tungdao.com") (:keywords "webkit") (:url . "https://github.com/tungd/kite-mini.el"))])
+ (kivy-mode . [(20210318 2106) nil "Emacs major mode for editing Kivy files" single ((:commit . "93ccd2058c1980207848810942dbb1a6d9edebe9") (:authors ("Dean Serenevy" . "dean@serenevy.net")) (:maintainer "Dean Serenevy" . "dean@serenevy.net"))])
+ (kiwix . [(20220316 847) ((emacs (25 1)) (request (0 3 0))) "Searching offline Wikipedia through Kiwix." tar ((:commit . "444f686a7f75db788d54f544b923a3532732eb8b") (:authors ("stardiviner" . "numbchild@gmail.com")) (:maintainer "stardiviner" . "numbchild@gmail.com") (:keywords "kiwix" "wikipedia") (:url . "https://repo.or.cz/kiwix.el.git"))])
+ (kixtart-mode . [(20150611 1604) ((emacs (24))) "major mode for Kixtart scripting files" single ((:commit . "1c2356797e7b766bbaaa2b341176a8b10499cd79") (:authors ("Ryrun <https://github.com/ryrun>")) (:maintainer "Ryrun <https://github.com/ryrun>") (:keywords "languages") (:url . "https://github.com/ryrun/kixtart-mode"))])
+ (klere-theme . [(20210320 1912) ((emacs (24))) "A dark theme with lambent color highlights and incremental grays" single ((:commit . "f9eacacc00455e6c42961ec41f24f864c2a05ace") (:authors ("Wamm K. D." . "jaft.r@outlook.com")) (:maintainer "Wamm K. D." . "jaft.r@outlook.com") (:url . "https://codeberg.org/WammKD/emacs-klere-theme"))])
+ (kmacro-x . [(20220323 2215) ((emacs (27 2))) "Keyboard macro helpers and extensions" single ((:commit . "429abd82c97031948b7681197551bb77708bd174") (:authors ("Wojciech Siewierski")) (:maintainer "Wojciech Siewierski") (:keywords "convenience") (:url . "https://github.com/vifon/kmacro-x.el"))])
+ (know-your-http-well . [(20160208 2304) nil "Look up the meaning of HTTP headers, methods, relations, status codes" tar ((:commit . "3cc5ab6d2764ab7aacb1b6e026abaccbeb6c37f2"))])
+ (kodi-remote . [(20190622 1325) ((request (0 2 0)) (let-alist (1 0 4)) (json (1 4)) (cl-lib (0 5)) (f (20190109 906))) "Remote Control for Kodi" single ((:commit . "f5e932036c16e2b61a63020e006fc601e38d181e") (:authors ("Stefan Huchler" . "stefan.huchler@mail.de")) (:maintainer "Stefan Huchler" . "stefan.huchler@mail.de") (:keywords "kodi" "tools" "convinience") (:url . "http://github.com/spiderbit/kodi-remote.el"))])
+ (kolon-mode . [(20140122 1134) nil "Syntax highlighting for Text::Xslate's Kolon syntax" single ((:commit . "5af0955e280ae991862189ebecd3937c5fc8fb9f") (:authors ("Sam Tran")) (:maintainer "Sam Tran") (:keywords "xslate" "perl") (:url . "https://github.com/samvtran/kolon-mode"))])
+ (kooten-theme . [(20161023 905) ((emacs (24 1))) "Dark color theme" single ((:commit . "d10197b4dd7af02cd14aeab2573c273a294798c3") (:authors ("Pascal van Kooten" . "kootenpv@gmail.com")) (:maintainer "Pascal van Kooten" . "kootenpv@gmail.com") (:keywords "themes") (:url . "http://github.com/kootenpv/emacs-kooten-theme"))])
+ (korean-holidays . [(20190102 1558) nil "Korean holidays for calendar." single ((:commit . "3f90ed86f46f8e5533f23baa40e2513ac497ca2b") (:authors ("SeungKi Kim" . "tttuuu888@gmail.com")) (:maintainer "SeungKi Kim" . "tttuuu888@gmail.com") (:keywords "calendar") (:url . "https://github.com/tttuuu888/korean-holidays"))])
+ (kosmos-theme . [(20170502 1850) ((emacs (24))) "Black and lightgray theme with not so much syntax highlighting." single ((:commit . "616456d2376a75dc31190ad65137d179fbad4336") (:authors ("Maxim Kim" . "habamax@gmail.com")) (:maintainer "Maxim Kim" . "habamax@gmail.com") (:url . "https://github.com/habamax/kosmos-theme"))])
+ (kotlin-mode . [(20210917 1911) ((emacs (24 3))) "Major mode for kotlin" tar ((:commit . "3e0c34087ba4965a8bf08d3f27325f0a1e631bfb") (:authors ("Shodai Yokoyama" . "quantumcars@gmail.com")) (:maintainer "Shodai Yokoyama" . "quantumcars@gmail.com") (:keywords "languages"))])
+ (kpm-list . [(20170924 1352) nil "An emacs buffer list that tries to intelligently group together buffers." single ((:commit . "e0f5112e5ce8ec1b603f4428fa51681c68bb28f5") (:authors ("Kevin Mahoney")) (:maintainer "Kevin Mahoney") (:url . "https://github.com/KMahoney/kpm-list/"))])
+ (kroman . [(20150827 2340) nil "Korean hangul romanization" single ((:commit . "90402b6ae40383e75d8ba97d66eee93eebf40f70") (:authors ("Zhang Kai Yu" . "yeannylam@gmail.com")) (:maintainer "Zhang Kai Yu" . "yeannylam@gmail.com") (:keywords "korean" "roman"))])
+ (ksp-cfg-mode . [(20190414 2348) ((emacs (24)) (cl-lib (0 5))) "major mode for editing KSP CFG files" single ((:commit . "faec8bd8456c67276d065eb68c88a30efcef59ef") (:authors ("Emily Backes" . "lucca@accela.net")) (:maintainer "Emily Backes" . "lucca@accela.net") (:keywords "data") (:url . "http://github.com/lashtear/ksp-cfg-mode"))])
+ (kubectx-mode . [(20200116 1918) ((emacs (24))) "Change kubectl context/namespace and show in mode line" single ((:commit . "f08687ae5403eb18bbeffc6dafdfde469bdb9a36") (:authors ("Terje Sannum" . "terje@offpiste.org")) (:maintainer "Terje Sannum" . "terje@offpiste.org") (:keywords "tools" "kubernetes") (:url . "https://github.com/terjesannum/emacs-kubectx-mode"))])
+ (kubedoc . [(20220401 1113) ((emacs (27 1))) "Kubernetes API Documentation" single ((:commit . "f8503f121e38f0ff9343544a5c912e50b25efd4c") (:authors ("Dean Lindqvist Todevski <https://github.com/r0bobo>")) (:maintainer "Dean Lindqvist Todevski") (:keywords "docs" "help" "k8s" "kubernetes" "tools") (:url . "https://github.com/r0bobo/kubedoc.el/"))])
+ (kubel . [(20220426 1722) ((transient (0 1 0)) (emacs (25 3)) (dash (2 12 0)) (s (1 2 0)) (yaml-mode (0 0 14))) "Control Kubernetes with limited permissions" single ((:commit . "dea03843dc7b152cdfb84c14e076cf79a721a87f") (:authors ("Adrien Brochard")) (:maintainer "Adrien Brochard") (:keywords "kubernetes" "k8s" "tools" "processes") (:url . "https://github.com/abrochard/kubel"))])
+ (kubel-evil . [(20220318 2124) ((kubel (1 0)) (evil (1 0)) (emacs (25 3))) "extension for kubel to provide evil keybindings" single ((:commit . "dea03843dc7b152cdfb84c14e076cf79a721a87f") (:authors ("Marcel Patzwahl")) (:maintainer "Marcel Patzwahl") (:keywords "kubernetes" "k8s" "tools" "processes" "evil" "keybindings") (:url . "https://github.com/abrochard/kubel"))])
+ (kubernetes . [(20220331 1314) ((emacs (25 1)) (dash (2 12 0)) (magit-section (3 1 1)) (magit-popup (2 13 0)) (with-editor (3 0 4)) (request (0 3 2)) (s (1 12 0)) (transient (0 3 0))) "Magit-like porcelain for Kubernetes" tar ((:commit . "e0d0cd6b949802fe63ff8940cc743cc7efedb089") (:authors ("Chris Barrett" . "chris+emacs@walrus.cool")) (:maintainer "Chris Barrett" . "chris+emacs@walrus.cool") (:keywords "kubernetes") (:url . "https://github.com/kubernetes-el/kubernetes-el"))])
+ (kubernetes-evil . [(20211225 300) ((kubernetes (0 17 0)) (evil (1 2 12))) "Kubernetes keybindings for evil-mode." single ((:commit . "e0d0cd6b949802fe63ff8940cc743cc7efedb089") (:authors ("Chris Barrett" . "chris+emacs@walrus.cool")) (:maintainer "Chris Barrett" . "chris+emacs@walrus.cool"))])
+ (kubernetes-helm . [(20210902 2232) ((yaml-mode (0 0 13)) (emacs (25 3))) "extension for helm, the package manager for kubernetes" single ((:commit . "95cf92600436f67bd7bfe650763e68635f5ecc8e") (:authors ("Adrien Brochard")) (:maintainer "Adrien Brochard") (:keywords "kubernetes" "helm" "k8s" "tools" "processes") (:url . "https://github.com/abrochard/kubernetes-helm"))])
+ (kubernetes-tramp . [(20181228 922) ((emacs (24)) (cl-lib (0 5))) "TRAMP integration for kubernetes containers" single ((:commit . "8713571b66940f8f3f496b55baa23cdf1df7a869") (:authors ("Giovanni Ruggiero" . "giovanni.ruggiero+github@gmail.com")) (:maintainer "Giovanni Ruggiero" . "giovanni.ruggiero+github@gmail.com") (:keywords "kubernetes" "convenience") (:url . "https://github.com/gruggiero/kubernetes-tramp"))])
+ (kurecolor . [(20200113 2027) ((emacs (24 1)) (s (1 0))) "color editing goodies for Emacs" single ((:commit . "3fc84840cbbd75e646cafa2fd3a00004b55e37ec") (:authors ("Jason Milkins" . "jasonm23@gmail.com")) (:maintainer "Jason Milkins" . "jasonm23@gmail.com"))])
+ (kuronami-theme . [(20220309 604) ((emacs (24 1))) "A deep blue theme with cool autumnal colors" single ((:commit . "910e8fa56a0cfe89dae888522f9fec4045d017fb") (:authors ("Eric Chung <>")) (:maintainer "Eric Chung <>") (:url . "https://github.com/super3ggo/kuronami"))])
+ (kv . [(20140108 1534) nil "key/value data structure functions" single ((:commit . "721148475bce38a70e0b678ba8aa923652e8900e") (:authors ("Nic Ferrier" . "nferrier@ferrier.me.uk")) (:maintainer "Nic Ferrier" . "nferrier@ferrier.me.uk") (:keywords "lisp"))])
+ (kwin . [(20220120 2125) nil "communicatewith the KWin window manager" single ((:commit . "20fac6508e5535a26df783ba05f04d1800b7382c") (:authors ("Simon Hafner")) (:maintainer "Simon Hafner") (:url . "http://github.com/reactormonk/kwin-minor-mode"))])
+ (l . [(20220422 1612) ((seq (2 20))) "Compact syntax for short lambda" single ((:commit . "c2466e52702a189fcc1ecad25cc1ad9f203f6627") (:keywords "extensions") (:url . "https://git.sr.ht/~tarsius/l"))])
+ (laas . [(20220301 1629) ((emacs (26 3)) (auctex (11 88)) (aas (1 1)) (yasnippet (0 14))) "A bundle of as-you-type LaTeX snippets" tar ((:commit . "b372f9a44bea03cce09b20cd2409e3ae3fa2d651") (:maintainer "Yoav Marco" . "yoavm448@gmail.com") (:keywords "tools" "tex") (:url . "https://github.com/tecosaur/LaTeX-auto-activating-snippets"))])
+ (lab-themes . [(20200815 2104) ((emacs (24))) "A custom theme carefully constructed in the LAB space" tar ((:commit . "9d7deb9635959d3a50ccb1082eb1207275f4b3e8") (:authors ("MetroWind" . "chris.corsair@gmail.com")) (:maintainer "MetroWind" . "chris.corsair@gmail.com") (:keywords "lisp") (:url . "https://github.com/MetroWind/lab-theme"))])
+ (labburn-theme . [(20200822 2153) nil "A lab color space zenburn theme." single ((:commit . "4ef2892f56c973907361bc91495d14204744f678") (:authors ("Johannes Goslar")) (:maintainer "Johannes Goslar") (:keywords "theme" "zenburn") (:url . "https://github.com/ksjogo/labburn-theme"))])
+ (lacquer . [(20220321 720) ((emacs (25 2))) "Switch theme/font by selecting from a cache" tar ((:commit . "0d7d09f7fe22fb0241e91228ce44568ed3e3e798") (:authors ("dingansich_kum0" . "zy.hua1122@outlook.com")) (:maintainer "dingansich_kum0" . "zy.hua1122@outlook.com") (:keywords "tools") (:url . "https://github.com/dingansichKum0/lacquer"))])
+ (laguna-theme . [(20220419 1459) nil "An updated blue-green Laguna Theme." single ((:commit . "48d14ffad6f0ffb4bd60c341e618c47ddbb7a2d8") (:authors ("Henry Newcomer" . "a.cliche.email@gmail.com")) (:maintainer "Henry Newcomer" . "a.cliche.email@gmail.com") (:url . "https://github.com/HenryNewcomer/laguna-theme"))])
+ (lakota-input . [(20200823 2146) nil "Input modes for Lakota language orthographies" single ((:commit . "b74b9de284a0404a120bb15340def4dd2f9a4779") (:authors ("Grant Shangreaux" . "shshoshin@protonmail.com")) (:maintainer "Grant Shangreaux" . "shshoshin@protonmail.com") (:url . "https://git.sr.ht/~shoshin/lakota-input.git"))])
+ (lambdapi-mode . [(20220106 1308) ((emacs (26 1)) (eglot (1 5)) (math-symbol-lists (1 2 1)) (highlight (20190710 1527))) "A major mode for editing Lambdapi source code" tar ((:commit . "d264cd8ed859635dc0f71e1d9213a911b46939b6") (:maintainer "Deducteam" . "dedukti-dev@inria.fr") (:keywords "languages") (:url . "https://github.com/Deducteam/lambdapi"))])
+ (lammps-mode . [(20180801 1319) ((emacs (24 4))) "basic syntax highlighting for LAMMPS files" single ((:commit . "a5b68d7a59975770b56ee8f6e66fa4f703a72ffe") (:authors ("Aidan Thompson <athomps at sandia.gov>")) (:maintainer "Rohit Goswami <r95g10 at gmail.com>") (:keywords "languages" "faces") (:url . "https://github.com/lammps/lammps/tree/master/tools/emacs"))])
+ (lang-refactor-perl . [(20131122 2127) nil "Simple refactorings, primarily for Perl" single ((:commit . "691bd69639de6b7af357e3b7143563ececd9c497") (:authors (nil . "Johan Lindstrom <buzzwordninja not_this_bit@googlemail.com>")) (:maintainer nil . "Johan Lindstrom <buzzwordninja not_this_bit@googlemail.com>") (:keywords "languages" "refactoring" "perl") (:url . "https://github.com/jplindstrom/emacs-lang-refactor-perl"))])
+ (langdoc . [(20150218 645) ((cl-lib (0 2))) "Help to define help document mode for various languages" single ((:commit . "2c7223bacb116992d700ecb19a60df5c09c63424") (:authors ("Tomoya Tanjo" . "ttanjo@gmail.com")) (:maintainer "Tomoya Tanjo" . "ttanjo@gmail.com") (:keywords "convenience" "eldoc") (:url . "https://github.com/tom-tan/langdoc/"))])
+ (langtool . [(20200529 230) ((cl-lib (0 3))) "Grammar check utility using LanguageTool" single ((:commit . "8276eccc5587bc12fd205ee58a7a982f0a136e41") (:authors ("Masahiro Hayashi" . "mhayashi1120@gmail.com")) (:maintainer "Masahiro Hayashi" . "mhayashi1120@gmail.com") (:keywords "docs") (:url . "https://github.com/mhayashi1120/Emacs-langtool"))])
+ (langtool-ignore-fonts . [(20210526 2340) ((emacs (25 1)) (langtool (2 2 1))) "Force langtool to ignore certain fonts" single ((:commit . "c3291c85b733b9047653cbb1f525655394610bdb") (:authors ("Christopher Lloyd" . "cjl8zf@virginia.edu")) (:maintainer "Christopher Lloyd" . "cjl8zf@virginia.edu") (:url . "https://github.com/cjl8zf/langtool-ignore-fonts"))])
+ (language-detection . [(20161123 1813) ((emacs (24)) (cl-lib (0 5))) "Automatic language detection from code snippets" single ((:commit . "54a6ecf55304fba7d215ef38a4ec96daff2f35a4") (:authors ("Andreas Jansson" . "andreas@jansson.me.uk")) (:maintainer "Andreas Jansson" . "andreas@jansson.me.uk") (:url . "https://github.com/andreasjansson/language-detection.el"))])
+ (language-id . [(20220411 1932) ((emacs (24 3))) "Library to work with programming language identifiers" single ((:commit . "5325af36d9cd726de47a698ac159fce59f3fd6d9") (:authors ("Lassi Kortela" . "lassi@lassi.io")) (:maintainer "Lassi Kortela" . "lassi@lassi.io") (:keywords "languages" "util") (:url . "https://github.com/lassik/emacs-language-id"))])
+ (languagetool . [(20220127 2215) ((emacs (27 0)) (request (0 3 2))) "LanguageTool integration for grammar and spell check" tar ((:commit . "ea50c120ee3418489b43d51ed750288791d6eb95") (:authors ("Joar Buitrago" . "jebuitragoc@unal.edu.co")) (:maintainer "Joar Buitrago" . "jebuitragoc@unal.edu.co") (:keywords "grammar" "text" "docs" "tools" "convenience" "checker") (:url . "https://github.com/PillFall/Emacs-LanguageTool.el"))])
+ (lastfm . [(20211018 838) ((emacs (26 1)) (request (0 3 0)) (anaphora (1 0 4)) (memoize (1 1)) (elquery (0 1 0)) (s (1 12 0))) "Last.fm API for Emacs Lisp" single ((:commit . "b4b19f0aadc5087febeeb3f59944a89c4cdcf325") (:authors ("Mihai Olteanu" . "mihai_olteanu@fastmail.fm")) (:maintainer "Mihai Olteanu" . "mihai_olteanu@fastmail.fm") (:keywords "multimedia" "api") (:url . "https://github.com/mihaiolteanu/lastfm.el/"))])
+ (lastpass . [(20201229 2109) ((emacs (24 4)) (seq (1 9)) (cl-lib (0 5))) "LastPass command wrapper" single ((:commit . "2366de7824b6c5f8e9ec6811d219dc06794e8630") (:authors ("Petter Storvik")) (:maintainer "Petter Storvik") (:keywords "extensions" "processes" "lpass" "lastpass") (:url . "https://github.com/storvik/emacs-lastpass"))])
+ (latex-extra . [(20170817 147) ((auctex (11 86 1)) (cl-lib (0 5))) "Adds several useful functionalities to LaTeX-mode." single ((:commit . "82d99b8b0c2db20e5270749582e03bcc2443ffb5") (:authors ("Artur Malabarba" . "artur@endlessparentheses.com")) (:maintainer "Artur Malabarba" . "artur@endlessparentheses.com") (:keywords "tex") (:url . "http://github.com/Malabarba/latex-extra"))])
+ (latex-math-preview . [(20211228 641) nil "preview LaTeX mathematical expressions." single ((:commit . "1c082179493eed3ce8bc255f87791eb4acb1fbdb") (:authors ("Takayuki YAMAGUCHI" . "d@ytak.info")) (:maintainer "Takayuki YAMAGUCHI" . "d@ytak.info") (:keywords "latex" "tex") (:url . "https://gitlab.com/latex-math-preview/latex-math-preview"))])
+ (latex-pretty-symbols . [(20151112 1044) nil "Display many latex symbols as their unicode counterparts" single ((:commit . "83d5888147bb734a94dfd4847a11e975a7d86ba8") (:authors ("Erik Parmann" . "eparmann@gmail.com") ("Pål Drange")) (:maintainer "Erik Parmann" . "eparmann@gmail.com") (:keywords "convenience" "display") (:url . "https://bitbucket.org/mortiferus/latex-pretty-symbols.el"))])
+ (latex-preview-pane . [(20181008 1822) nil "Makes LaTeX editing less painful by providing a updatable preview pane" tar ((:commit . "5297668a89996b50b2b62f99cba01cc544dbed2e") (:authors ("John L. Singleton" . "jsinglet@gmail.com")) (:maintainer "John L. Singleton" . "jsinglet@gmail.com") (:keywords "latex" "preview") (:url . "http://www.emacswiki.org/emacs/LaTeXPreviewPane"))])
+ (latex-unicode-math-mode . [(20170123 1816) nil "Input method for Unicode math symbols" tar ((:commit . "eb4a5c9f9b00a58d2ca80f90782a851f4c8497b8") (:authors ("Christoph Dittmann" . "github@christoph-d.de")) (:maintainer "Christoph Dittmann" . "github@christoph-d.de") (:url . "https://github.com/Christoph-D/latex-unicode-math-mode"))])
+ (latexdiff . [(20190827 1651) ((emacs (24 4))) "Latexdiff integration in Emacs" single ((:commit . "56d0b240867527d1b43d3ddec14059361929b971") (:authors ("Launay Gaby" . "gaby.launay@tutanota.com")) (:maintainer "Launay Gaby" . "gaby.launay@tutanota.com") (:keywords "tex" "vc" "tools" "git" "helm") (:url . "http://github.com/galaunay/latexdiff.el"))])
+ (launch . [(20130619 2204) nil "launch files with OS-standard associated applications." single ((:commit . "e7c3b573fc05fe4d3d322389079909311542e799") (:authors ("Simon Law" . "sfllaw@sfllaw.ca")) (:maintainer "Simon Law" . "sfllaw@sfllaw.ca") (:keywords "convenience" "processes") (:url . "https://github.com/sfllaw/emacs-launch"))])
+ (launch-mode . [(20170106 512) ((emacs (24 4))) "Major mode for launch-formatted text" tar ((:commit . "25ebd4ba77afcbe729901eb74923dbe9ae81c313") (:authors ("iory" . "ab.ioryz@gmail.com")) (:maintainer "iory" . "ab.ioryz@gmail.com") (:url . "https://github.com/iory/launch-mode"))])
+ (launchctl . [(20210611 2243) ((emacs (24 1))) "Interface to launchctl on Mac OS X." single ((:commit . "c9b7e93f5ec6fa504dfb03d60571cf3e5dc38e12") (:authors ("Peking Duck <github.com/pekingduck>")) (:maintainer "Peking Duck <github.com/pekingduck>") (:keywords "tools" "convenience") (:url . "http://github.com/pekingduck/launchctl-el"))])
+ (lavender-theme . [(20170808 1313) ((emacs (24 0))) "an Emacs 24 theme based on Lavender (tmTheme)" single ((:commit . "ef5e959b95d7fb8152137bc186c4c24e986c1e3c") (:authors ("Jason Milkins")) (:maintainer "Jason Milkins") (:url . "https://github.com/emacsfodder/tmtheme-to-deftheme"))])
+ (lavenderless-theme . [(20201222 1627) ((colorless-themes (0 2))) "A mostly colorless version of lavender-theme" single ((:commit . "c1ed1e12541cf05cc6c558d23c089c07e10b54d7") (:authors ("Thomas Letan" . "lthms@soap.coffee")) (:maintainer "Thomas Letan" . "lthms@soap.coffee") (:keywords "faces" "theme") (:url . "https://git.sr.ht/~lthms/colorless-themes.el"))])
+ (lcb-mode . [(20160816 540) ((emacs (24))) "LiveCode Builder major mode" single ((:commit . "be0768e9aa6f9b8e76f2230f4f7f4d152a766b9a") (:authors ("Peter TB Brett" . "peter@peter-b.co.uk")) (:maintainer "Peter TB Brett" . "peter@peter-b.co.uk") (:keywords "languages") (:url . "https://github.com/peter-b/lcb-mode"))])
+ (lcr . [(20210102 853) ((dash (2 12 0)) (emacs (25 1))) "lightweight coroutines" single ((:commit . "493424dab9f374c5521dca8714481b70cb3c3cfd") (:authors ("Jean-Philippe Bernardy" . "jeanphilippe.bernardy@gmail.com")) (:maintainer "Jean-Philippe Bernardy" . "jeanphilippe.bernardy@gmail.com") (:keywords "tools") (:url . "https://github.com/jyp/lcr"))])
+ (leaf . [(20211226 1633) ((emacs (24 1))) "Simplify your init.el configuration, extended use-package" single ((:commit . "9eb18e8c9c375aa0158fbd06ea906bfbf54408fe") (:authors ("Naoya Yamashita" . "conao3@gmail.com")) (:maintainer "Naoya Yamashita" . "conao3@gmail.com") (:keywords "lisp" "settings") (:url . "https://github.com/conao3/leaf.el"))])
+ (leaf-convert . [(20210816 1103) ((emacs (26 1)) (leaf (3 6 0)) (leaf-keywords (1 1 0)) (ppp (2 1))) "Convert many format to leaf format" single ((:commit . "da86654f1021445cc42c1a5a9195f15097352209") (:authors ("Naoya Yamashita" . "conao3@gmail.com")) (:maintainer "Naoya Yamashita" . "conao3@gmail.com") (:keywords "tools") (:url . "https://github.com/conao3/leaf-convert.el"))])
+ (leaf-defaults . [(20210301 118) ((emacs (26 1)) (leaf (4 1)) (leaf-keywords (1 1))) "Awesome leaf config collections" tar ((:commit . "96ce39d4f16736f1e654e24eac16a2603976c724") (:authors ("Naoya Yamashita" . "conao3@gmail.com")) (:maintainer "Naoya Yamashita" . "conao3@gmail.com") (:keywords "convenience") (:url . "https://github.com/conao3/leaf-defaults.el"))])
+ (leaf-keywords . [(20210816 1107) ((emacs (24 4)) (leaf (3 5 0))) "Additional leaf.el keywords for external packages" single ((:commit . "849b579f87c263e2f1d7fb7eda93b6ce441f217e") (:authors ("Naoya Yamashita" . "conao3@gmail.com")) (:maintainer "Naoya Yamashita" . "conao3@gmail.com") (:keywords "lisp" "settings") (:url . "https://github.com/conao3/leaf-keywords.el"))])
+ (leaf-manager . [(20211225 624) ((emacs (26 1)) (leaf (4 1)) (leaf-convert (1 0)) (ppp (2 1))) "Configuration manager for leaf based init.el" single ((:commit . "a9fb7fda1432d0cf6bd8546d98a11b3fbe1d84e6") (:authors ("Naoya Yamashita" . "conao3@gmail.com")) (:maintainer "Naoya Yamashita" . "conao3@gmail.com") (:keywords "convenience" "leaf") (:url . "https://github.com/conao3/leaf-manager.el"))])
+ (leaf-tree . [(20211105 19) ((emacs (25 1)) (imenu-list (0 8))) "Interactive side-bar feature for init.el using leaf" single ((:commit . "89c3b8842df067bba67663d309f43aa311acdccd") (:authors ("Naoya Yamashita" . "conao3@gmail.com")) (:maintainer "Naoya Yamashita" . "conao3@gmail.com") (:keywords "convenience" "leaf") (:url . "https://github.com/conao3/leaf-tree.el"))])
+ (lean-mode . [(20220501 1007) ((emacs (24 3)) (dash (2 18 0)) (s (1 10 0)) (f (0 19 0)) (flycheck (30))) "A major mode for the Lean 3 language" tar ((:commit . "362bc6fa3efb1874c525ed6b4b6f24f76af22596") (:authors ("Leonardo de Moura" . "leonardo@microsoft.com") ("Soonho Kong " . "soonhok@cs.cmu.edu") ("Gabriel Ebner " . "gebner@gebner.org") ("Sebastian Ullrich" . "sebasti@nullri.ch")) (:maintainer "Sebastian Ullrich" . "sebasti@nullri.ch") (:keywords "languages") (:url . "https://github.com/leanprover/lean-mode"))])
+ (leanote . [(20161223 139) ((emacs (24 4)) (cl-lib (0 5)) (request (0 2)) (let-alist (1 0 3)) (pcache (0 4 0)) (s (1 10 0)) (async (1 9))) "A minor mode writing markdown leanote" single ((:commit . "d499e7b59bb1f1a2fabc0e4c26fb101ed62ebc7b") (:authors ("Aborn Jiang" . "aborn.jiang@gmail.com")) (:maintainer "Aborn Jiang" . "aborn.jiang@gmail.com") (:keywords "leanote" "note" "markdown") (:url . "https://github.com/aborn/leanote-emacs"))])
+ (learn-ocaml . [(20211003 1412) ((emacs (25 1))) "Emacs frontend for learn-ocaml" single ((:commit . "ac6ef9cbd39f7d9ac0019e28da09aad5bc2cfae5") (:url . "https://github.com/pfitaxel/learn-ocaml.el"))])
+ (ledger-import . [(20210419 818) ((emacs (25 1)) (ledger-mode (3 1 1))) "Fetch OFX files from bank and push them to Ledger" single ((:commit . "f77adf79ce67524c3e08546448ac88ea1a665b64") (:authors ("Damien Cassou" . "damien@cassou.me")) (:maintainer "Damien Cassou" . "damien@cassou.me") (:url . "https://gitlab.petton.fr/mpdel/libmpdel"))])
+ (ledger-mode . [(20220307 854) ((emacs (25 1))) "Helper code for use with the \"ledger\" command-line tool" tar ((:commit . "11e850395448ee7012dba16bd6df103f5552ebfb"))])
+ (leerzeichen . [(20170422 1313) nil "Minor mode to display whitespace characters." single ((:commit . "5acf9855ecb2b2cd5da4402bb48df149e7525cc5") (:authors ("Felix Geller" . "fgeller@gmail.com")) (:maintainer "Felix Geller" . "fgeller@gmail.com") (:keywords "whitespace" "characters") (:url . "http://github.com/fgeller/leerzeichen.el"))])
+ (leetcode . [(20220503 534) ((emacs (26 1)) (dash (2 16 0)) (graphql (0 1 1)) (spinner (1 7 3)) (aio (1 0)) (log4e (0 3 3))) "An leetcode client" single ((:commit . "682f7a44d0bea0daf6f9a2888fa7f905d3a0cd70") (:authors ("Wang Kai" . "kaiwkx@gmail.com")) (:maintainer "Wang Kai" . "kaiwkx@gmail.com") (:keywords "extensions" "tools") (:url . "https://github.com/kaiwk/leetcode.el"))])
+ (legalese . [(20200119 2248) nil "Add legalese to your program files" single ((:commit . "e465471d2d5a62d35073d93e0f8d40387a82e302") (:authors ("Jorgen Schaefer" . "forcer@forcix.cx")) (:maintainer "Jorgen Schaefer" . "forcer@forcix.cx") (:keywords "convenience") (:url . "https://github.com/jorgenschaefer/legalese"))])
+ (lemon-mode . [(20130216 1304) nil "A major mode for editing lemon grammar files" single ((:commit . "155bfced6c9afc8072a0133d3d1baa54c6d67430") (:authors ("mooz" . "stillpedant@gmail.com")) (:maintainer "mooz" . "stillpedant@gmail.com") (:keywords "lemon"))])
+ (lentic . [(20210727 1247) ((emacs (24 4)) (m-buffer (0 13)) (dash (2 5 0)) (f (0 17 2)) (s (1 9 0))) "One buffer as a view of another" tar ((:commit . "36861bdf9c1d88492648da553f66529e3a879880") (:authors ("Phillip Lord" . "phillip.lord@russet.org.uk")) (:maintainer "Phillip Lord" . "phillip.lord@russet.org.uk"))])
+ (lentic-server . [(20160717 2052) ((lentic (0 8)) (web-server (0 1 1))) "Web Server for Emacs Literate Source" single ((:commit . "8e809fafbb27a98f815b544d9d9ee15843eb6a36") (:authors ("Phillip Lord" . "phillip.lord@newcastle.ac.uk")) (:maintainer "Phillip Lord" . "phillip.lord@newcastle.ac.uk"))])
+ (leo . [(20220111 1045) ((emacs (27 1))) "Interface for dict.leo.org" tar ((:commit . "12c7133c826925e088e0ddb2ae46f51bf3111af1") (:authors ("M.T. Enders <michael AT michael-enders.com>") ("Marty Hiatt <martianhiatus AT riseup.net>")) (:maintainer "M.T. Enders <michael AT michael-enders.com>") (:keywords "convenience" "translate") (:url . "https://github.com/mtenders/emacs-leo"))])
+ (less-css-mode . [(20161001 453) nil "Major mode for editing LESS CSS files (lesscss.org)" single ((:commit . "c7fa3d56d83206b28657f2e56439dc62280a2bf2") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:keywords "less" "css" "mode") (:url . "https://github.com/purcell/less-css-mode"))])
+ (letcheck . [(20160202 1948) nil "Check the erroneous assignments in let forms" single ((:commit . "edf188ca2f85349e971b83f164c6484264e79426") (:authors ("Matus Goljer" . "matus.goljer@gmail.com")) (:maintainer "Matus Goljer" . "matus.goljer@gmail.com") (:keywords "convenience") (:url . "https://github.com/Fuco1/letcheck"))])
+ (letterbox-mode . [(20170702 125) ((emacs (24 3))) "hide sensitive text on a buffer" single ((:commit . "88c67a51d67216d569a28e8423200883fde096dd") (:authors ("Fernando Leboran" . "f.leboran@gmail.com")) (:maintainer "Fernando Leboran" . "f.leboran@gmail.com") (:keywords "password" "convenience") (:url . "http://github.com/pacha64/letterbox-mode"))])
+ (leuven-theme . [(20220203 947) nil "Awesome Emacs color theme on white background" tar ((:commit . "d7dd9188a65e2ab7cf73c2e575a830baae38cb0c") (:authors ("Fabrice Niessen <(concat \"fniessen\" at-sign \"pirilampo.org\")>")) (:maintainer "Fabrice Niessen <(concat \"fniessen\" at-sign \"pirilampo.org\")>") (:keywords "color" "theme") (:url . "https://github.com/fniessen/emacs-leuven-theme"))])
+ (levenshtein . [(20090830 1040) nil "Edit distance between two strings." single ((:commit . "070925197ebf6b704e6e00c4f2d2ec783f3df38c") (:authors ("Aaron S. Hawley <ashawley at uvm dot edu>,") ("Art Taylor")) (:maintainer "Aaron S. Hawley <ashawley at uvm dot edu>,") (:keywords "lisp"))])
+ (lexbind-mode . [(20141027 1429) nil "Puts the value of lexical-binding in the mode line" single ((:commit . "fa0a6848c1cfd3fbf45db43dc2deef16377d887d") (:authors ("Andrew Kirkpatrick" . "ubermonk@gmail.com")) (:maintainer "Andrew Kirkpatrick" . "ubermonk@gmail.com") (:keywords "convenience" "lisp") (:url . "https://github.com/spacebat/lexbind-mode"))])
+ (lexic . [(20220501 1432) ((emacs (26 3))) "A major mode to find out more about words" single ((:commit . "f9b3de4d9c2dd1ce5022383e1a504b87bf7d1b09") (:authors ("pluskid" . "pluskid@gmail.com") ("gucong" . "gucong43216@gmail.com") ("TEC" . "tec@tecosaur.com")) (:maintainer "TEC" . "tec@tecosaur.com") (:url . "https://github.com/tecosaur/lexic"))])
+ (lf . [(20210808 1921) ((s (1 12 0)) (dash (2 16 0)) (emacs (27 1))) "A Language Features library for Emacs Lisp" single ((:commit . "35db92ca765a0544721fdeea036d77b7d192d083") (:authors ("Musa Al-hassy" . "alhassy@gmail.com")) (:maintainer "Musa Al-hassy" . "alhassy@gmail.com") (:keywords "convenience" "programming") (:url . "https://alhassy.github.io/lf.el/"))])
+ (lfe-mode . [(20220102 1653) nil "Lisp Flavoured Erlang mode" tar ((:commit . "6e1e42768d40528e7a13f7cebf0a56cffbeda3c6"))])
+ (libbcel . [(20191203 654) ((emacs (26 1)) (request (0 3 1))) "Library to connect to basecamp 3 API" tar ((:commit . "df466d31544c53d8550f9c08e58b70adc559c48c") (:authors ("Damien Cassou" . "damien@cassou.me")) (:maintainer "Damien Cassou" . "damien@cassou.me") (:url . "https://gitlab.petton.fr/bcel/libbcel"))])
+ (libelcouch . [(20200923 1836) ((emacs (26 1)) (request (0 3 0))) "Communication with CouchDB" single ((:commit . "5ae35266c9a2eb33f0c708bc8c0687339cee9133") (:authors ("Damien Cassou" . "damien@cassou.me")) (:maintainer "Damien Cassou" . "damien@cassou.me") (:keywords "tools") (:url . "https://gitlab.petton.fr/elcouch/libelcouch/"))])
+ (liberime . [(20211203 244) ((emacs (25 1))) "Rime elisp binding" tar ((:commit . "79b709debe036f98d74ac129934e59c4d08c1dd5") (:authors ("A.I.")) (:maintainer "A.I.") (:keywords "convenience" "chinese" "input-method" "rime") (:url . "https://github.com/merrickluo/liberime"))])
+ (libgit . [(20210620 2017) ((emacs (25 1))) "Thin bindings to libgit2." tar ((:commit . "77bd28aeaa2a49962e8f714741f5a69b656a2183") (:authors ("Eivind Fonn" . "evfonn@gmail.com")) (:maintainer "Eivind Fonn" . "evfonn@gmail.com") (:keywords "git" "vc") (:url . "https://github.com/magit/libegit2"))])
+ (liblouis . [(20220426 657) ((emacs (26 1))) "Mode for editing liblouis braille translation tables" single ((:commit . "a341a0c434cdbe7f46956c8db13203c3fc941a34") (:authors ("Christian Egli" . "christian.egli@sbs.ch")) (:maintainer "Christian Egli" . "christian.egli@sbs.ch") (:keywords "languages") (:url . "https://github.com/liblouis/liblouis-mode"))])
+ (libmpdee . [(20160117 2301) nil "Client end library for mpd, a music playing daemon" single ((:commit . "a6ca3b7d6687f3ba60996b9b5044ad1d3b228290") (:authors ("Ramkumar R. Aiyengar" . "andyetitmoves@gmail.com")) (:maintainer "Ramkumar R. Aiyengar" . "andyetitmoves@gmail.com") (:keywords "music" "mpd"))])
+ (libmpdel . [(20210627 755) ((emacs (25 1))) "Communication with an MPD server" tar ((:commit . "e4ae63dd002fe07835c3c8a35b20b6e8347f8e84") (:authors ("Damien Cassou" . "damien@cassou.me")) (:maintainer "Damien Cassou" . "damien@cassou.me") (:keywords "multimedia") (:url . "https://gitea.petton.fr/mpdel/libmpdel"))])
+ (librera-sync . [(20210827 2300) ((emacs (26 1)) (f (0 17))) "Sync document's position with Librera Reader for Android" tar ((:commit . "b6b97adc08c26b1595249e1c129793100f4ca26e") (:authors ("Dmitriy Pshonko" . "jumper047@gmail.com")) (:maintainer "Dmitriy Pshonko" . "jumper047@gmail.com") (:keywords "multimedia" "sync") (:url . "https://github.com/jumper047/librera-sync"))])
+ (lice . [(20220312 2215) nil "License And Header Template" tar ((:commit . "0b69ba54057146f1473e85c0760029e584e3eb13") (:authors ("Taiki Sugawara" . "buzz.taiki@gmail.com")) (:maintainer "Taiki Sugawara" . "buzz.taiki@gmail.com") (:keywords "template" "license" "tools") (:url . "https://github.com/buzztaiki/lice-el"))])
+ (license-snippets . [(20201117 1619) ((emacs (26)) (yasnippet (0 8 0))) "LICENSE templates for yasnippet" tar ((:commit . "a729748b7d7f38a916fe61f23db6e7446c0a5e8f") (:authors ("Seong Yong-ju" . "sei40kr@gmail.com")) (:maintainer "Seong Yong-ju" . "sei40kr@gmail.com") (:keywords "tools") (:url . "https://github.com/sei40kr/license-snippets"))])
+ (license-templates . [(20200906 2047) ((emacs (24 3)) (request (0 3 0))) "Create LICENSE using GitHub API" single ((:commit . "e03f4a30c4abf354fb961babe4dce1dfa733aa82") (:authors ("Shen, Jen-Chieh" . "jcs090218@gmail.com")) (:maintainer "Shen, Jen-Chieh" . "jcs090218@gmail.com") (:url . "https://github.com/jcs-elpa/license-templates"))])
+ (light-soap-theme . [(20150607 1445) ((emacs (24))) "Emacs 24 theme with a light background." single ((:commit . "76a787bd40c6b567ae68ced7f5d9f9f10725e00d"))])
+ (ligo-mode . [(20220209 755) ((emacs (27 1))) "A major mode for editing LIGO source code" single ((:commit . "3c0eb84597bba6f3cfd7a83c4d75b4233123e065") (:authors ("LigoLang SASU")) (:maintainer "LigoLang SASU") (:keywords "languages") (:url . "https://gitlab.com/ligolang/ligo/-/tree/dev/tools/emacs"))])
+ (line-reminder . [(20220502 1210) ((emacs (25 1)) (indicators (0 0 4)) (fringe-helper (1 0 1)) (ov (1 0 6)) (ht (2 0))) "Line annotation for changed and saved lines" single ((:commit . "41bc1b7f0e9dd150b99aeb47c4c9874d7c6c2d9b") (:authors ("Shen, Jen-Chieh" . "jcs090218@gmail.com")) (:maintainer "Shen, Jen-Chieh" . "jcs090218@gmail.com") (:url . "https://github.com/emacs-vs/line-reminder"))])
+ (line-up-words . [(20180219 1024) nil "Align words in an intelligent way" single ((:commit . "254ee815eb3fe77edea7c9da6f6f3839163735f3") (:url . "https://github.com/janestreet/line-up-words"))])
+ (lines-at-once . [(20180422 247) ((emacs (25))) "Insert and edit multiple lines at once" single ((:commit . "31bce4b79fe16251b7cf118f0d343b0b46f72360") (:authors ("Jiahao Li" . "jiahaowork@gmail.com")) (:maintainer "Jiahao Li" . "jiahaowork@gmail.com") (:keywords "abbrev" "tools") (:url . "https://github.com/jiahaowork/lines-at-once.el"))])
+ (lingr . [(20100807 1731) nil "Lingr Client for GNU Emacs" single ((:commit . "4215a8704492d3c860097cbe2649936c22c196df") (:authors ("lugecy" . "lugecy@gmail.com")) (:maintainer "lugecy" . "lugecy@gmail.com") (:keywords "chat" "client" "internet") (:url . "http://github.com/lugecy/lingr-el"))])
+ (linguistic . [(20181129 2116) nil "A package for basic linguistic analysis." tar ((:commit . "23e47e98cdb09ee61883669b6d8a11bf6449862c") (:authors ("Andrew Favia <drewlinguistics01 at gmail dot com>")) (:maintainer "Andrew Favia <drewlinguistics01 at gmail dot com>") (:keywords "linguistics" "text analysis" "matching") (:url . "https://github.com/andcarnivorous/linguistic"))])
+ (link . [(20191111 446) nil "Hypertext links in text buffers" single ((:commit . "bdf0aa7761d1c1a3bc0652b2fdc4a54b3acdb06a") (:authors ("Torsten Hilbrich" . "torsten.hilbrich@gmx.net")) (:maintainer "Torsten Hilbrich" . "torsten.hilbrich@gmx.net") (:keywords "interface" "hypermedia"))])
+ (link-hint . [(20220414 56) ((avy (0 4 0)) (emacs (24 4))) "Use avy to open, copy, etc. visible links" single ((:commit . "a24546e0dee901bce94e3a11c20b1ed12a22b9c6") (:authors ("Fox Kiester" . "noct@posteo.net")) (:maintainer "Fox Kiester" . "noct@posteo.net") (:keywords "convenience" "url" "avy" "link" "links" "hyperlink") (:url . "https://github.com/noctuid/link-hint.el"))])
+ (linkode . [(20200607 2152) nil "Generate a linkode snippet with region/buffer content" single ((:commit . "675e612e30b74764c57de4117d950ea803b15f74") (:authors ("Erick Navarro" . "erick@navarro.io")) (:maintainer "Erick Navarro" . "erick@navarro.io") (:url . "https://github.com/erickgnavar/linkode.el"))])
+ (linphone . [(20130524 1109) nil "Emacs interface to Linphone" tar ((:commit . "99af3db941b7f4e5272bb48bff96c1ce4ceac302") (:authors ("Yoni Rabkin" . "yonirabkin@member.fsf.org")) (:maintainer "Yoni Rabkin" . "yonirabkin@member.fsf.org") (:keywords "comm") (:url . "https://github.com/zabbal/emacs-linphone"))])
+ (linum-off . [(20160217 2137) nil "Provides an interface for turning line-numbering off" single ((:commit . "116e66ac259b183e0763b85616888316ab196822") (:authors ("Matthew L. Fidler, Florian Adamsky (see wiki)")) (:maintainer "Matthew L. Fidler") (:keywords "line" "numbering") (:url . "http://www.emacswiki.org/emacs/auto-indent-mode.el "))])
+ (linum-relative . [(20180124 1047) nil "display relative line number in emacs." single ((:commit . "c74a6981b688a5e1e6b8e0809363963ff558ce4d") (:authors ("coldnew" . "coldnew.tw@gmail.com")) (:maintainer "coldnew" . "coldnew.tw@gmail.com") (:keywords "converience") (:url . "http://github.com/coldnew/linum-relative"))])
+ (liquid-types . [(20151202 735) ((flycheck (0 13)) (dash (1 2)) (emacs (24 1)) (popup (0 5 2)) (pos-tip (0 5 0)) (flycheck-liquidhs (0 0 1)) (button-lock (1 0 2))) "show inferred liquid-types" single ((:commit . "cc4bacbbf204ef9cf0756f78dfebee2c6ae14d7b") (:authors ("Ranjit Jhala" . "jhala@cs.ucsd.edu")) (:maintainer "Ranjit Jhala" . "jhala@cs.ucsd.edu"))])
+ (liquidmetal . [(20211004 1429) ((emacs (24 4))) "A mimetic poly-alloy of the Quicksilver scoring algorithm" single ((:commit . "22dd4c3ea4c0d2bd82270e2fb272317d0bc87752") (:authors ("Shen, Jen-Chieh" . "jcs090218@gmail.com")) (:maintainer "Shen, Jen-Chieh" . "jcs090218@gmail.com") (:url . "https://github.com/jcs-elpa/liquidmetal"))])
+ (liso-theme . [(20160410 2029) nil "Eclectic Dark Theme for GNU Emacs" single ((:commit . "844688245eb860d23043455e165ee24503454c81") (:authors ("Vlad Piersec" . "vlad.piersec@gmail.com")) (:maintainer "Vlad Piersec" . "vlad.piersec@gmail.com") (:keywords "theme" "themes") (:url . "https://github.com/caisah/liso-theme"))])
+ (lisp-butt-mode . [(20210215 2206) ((emacs (25))) "Slim Lisp Butts" single ((:commit . "7330f08dd85ee715096f3596df516877894c6c2f") (:authors ("Marco Wahl" . "marcowahlsoft@gmail.com")) (:maintainer "Marco Wahl" . "marcowahlsoft@gmail.com") (:keywords "lisp") (:url . "https://gitlab.com/marcowahl/lisp-butt-mode"))])
+ (lisp-extra-font-lock . [(20181008 1921) nil "Highlight bound variables and quoted exprs." single ((:commit . "4605eccbe1a7fcbd3cacf5b71249435413b4db4f") (:authors ("Anders Lindgren")) (:maintainer "Anders Lindgren") (:keywords "languages" "faces") (:url . "https://github.com/Lindydancer/lisp-extra-font-lock"))])
+ (lisp-local . [(20210605 1347) ((emacs (24 3))) "Allow different Lisp indentation in each buffer" single ((:commit . "22e221c9330d2b5dc07e8b2caa34c83ac7c20b0d") (:authors ("Lassi Kortela" . "lassi@lassi.io")) (:maintainer "Lassi Kortela" . "lassi@lassi.io") (:keywords "languages" "lisp") (:url . "https://github.com/lispunion/emacs-lisp-local"))])
+ (lispxmp . [(20170926 23) nil "Automagic emacs lisp code annotation" single ((:commit . "7ad077b4ee91ce8a42f84eeddb9fc7ea4eac7814") (:authors ("rubikitch" . "rubikitch@ruby-lang.org")) (:maintainer "rubikitch" . "rubikitch@ruby-lang.org") (:keywords "lisp" "convenience") (:url . "http://www.emacswiki.org/cgi-bin/wiki/download/lispxmp.el"))])
+ (lispy . [(20220209 1138) ((emacs (24 3)) (ace-window (0 9 0)) (iedit (0 9 9)) (swiper (0 13 4)) (hydra (0 14 0)) (zoutline (0 1 0))) "vi-like Paredit" tar ((:commit . "df1b7e614fb0f73646755343e8892ddda310f427") (:authors ("Oleh Krehel" . "ohwoeowho@gmail.com")) (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com") (:keywords "lisp") (:url . "https://github.com/abo-abo/lispy"))])
+ (lispyville . [(20210702 2031) ((lispy (0)) (evil (1 2 12)) (cl-lib (0 5)) (emacs (24 4))) "A minor mode for integrating evil with lispy." single ((:commit . "9c14bed0359f659e246d345c706f895737c3d172") (:authors ("Fox Kiester" . "noct@posteo.net")) (:maintainer "Fox Kiester" . "noct@posteo.net") (:keywords "vim" "evil" "lispy" "lisp" "parentheses") (:url . "https://github.com/noctuid/lispyville"))])
+ (list-environment . [(20210930 1439) nil "A tabulated process environment editor" single ((:commit . "0a72a5a9c1abc090b25202a0387e3f766994b053") (:authors ("Charles L.G. Comstock" . "dgtized@gmail.com")) (:maintainer "Charles L.G. Comstock" . "dgtized@gmail.com") (:keywords "processes" "unix"))])
+ (list-packages-ext . [(20151115 1716) ((s (1 6 0)) (ht (1 5 0)) (persistent-soft (0 8 6))) "Extras for list-packages" single ((:commit . "b4dd644e4369c9aa66f5bb8895ea49ebbfd0a27a") (:authors ("Alessandro Piras" . "laynor@gmail.com")) (:maintainer "Alessandro Piras" . "laynor@gmail.com") (:keywords "convenience" "tools"))])
+ (list-unicode-display . [(20181121 2316) ((emacs (24 3))) "Search for and list unicode characters by name" single ((:commit . "0ecc2402b258990e7a0cf7e60847712c69444070") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:keywords "convenience"))])
+ (list-utils . [(20210111 1522) nil "List-manipulation utility functions" single ((:commit . "ca9654cd1418e874c876c6b3b7d4cd8339bfde77") (:authors ("Roland Walker" . "walker@pobox.com")) (:maintainer "Roland Walker" . "walker@pobox.com") (:keywords "extensions") (:url . "http://github.com/rolandwalker/list-utils"))])
+ (lister . [(20220118 1322) ((emacs (26 1))) "Yet another list printer" tar ((:commit . "51581b53ecf8e68d67a2d85dde539533aa7199ee") (:authors (nil . "<joerg@joergvolbers.de>")) (:maintainer nil . "<joerg@joergvolbers.de>") (:keywords "lisp") (:url . "https://github.com/publicimageltd/lister"))])
+ (lit-mode . [(20141123 1736) nil "Major mode for lit" single ((:commit . "c61c403afc8333a5649c5421ab1a6341dc1c7d92") (:authors ("Hector A Escobedo" . "ninjahector.escobedo@gmail.com")) (:maintainer "Hector A Escobedo" . "ninjahector.escobedo@gmail.com") (:keywords "languages" "tools"))])
+ (litable . [(20200130 1329) ((dash (2 6 0))) "dynamic evaluation replacement with emacs" single ((:commit . "02247ca284cbc79f3afb783d62ed092bfc5b8d83") (:authors ("Matus Goljer" . "matus.goljer@gmail.com")) (:maintainer "Matus Goljer" . "matus.goljer@gmail.com") (:keywords "lisp"))])
+ (litanize . [(20200211 621) ((emacs (24 1)) (enlive (0 0 1)) (s (1 12 0))) "Generate \"Latour Litanies\"" single ((:commit . "ba73259e35b4649884ba56542d3a55f43bd3b80b") (:authors ("nik gaffney" . "nik@fo.am")) (:maintainer "nik gaffney" . "nik@fo.am") (:keywords "tools" "latour litany" "alien phenomenology" "ontography" "metaphorism" "carpentry") (:url . "https://github.com/zzkt/litanizer"))])
+ (litecoin-ticker . [(20160612 11) ((json (1 2))) "litecoin price in modeline" single ((:commit . "3d8047c736e4ee0b8638953f8cc63eaefad34106") (:authors ("Zhe Lei")) (:maintainer "Zhe Lei"))])
+ (literal-string . [(20191023 733) ((emacs (25)) (edit-indirect (0 1 5))) "edit string literals in a dedicated buffer" single ((:commit . "afffa86e626798ee9f9188ea3be2d5ee6ad17c39") (:authors ("Joost Diepenmaat" . "joost@zeekat.nl")) (:maintainer "Joost Diepenmaat" . "joost@zeekat.nl") (:keywords "lisp" "tools" "docs") (:url . "https://github.com/joodie/literal-string-mode/"))])
+ (literate-calc-mode . [(20220215 1814) ((emacs (25 1)) (s (1 12 0))) "Inline results from calc" single ((:commit . "f5133e65d8ffdab918cdfc269ac0c067a0de5e9b") (:authors ("Robin Schroer")) (:maintainer "Robin Schroer") (:keywords "calc" "languages" "tools") (:url . "https://github.com/sulami/literate-calc-mode.el"))])
+ (literate-coffee-mode . [(20170211 1515) ((coffee-mode (0 5 0))) "major-mode for Literate CoffeeScript" single ((:commit . "55ce0305495f4a38c8063c4bd63deb1e1252373d") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-literate-coffee-mode"))])
+ (literate-elisp . [(20220322 133) ((emacs (26 1))) "Load Emacs Lisp code blocks from Org files" single ((:commit . "dc4f9d64a8483aa6e394178087c589cdefc571e2") (:authors ("Jingtao Xu" . "jingtaozf@gmail.com")) (:maintainer "Jingtao Xu" . "jingtaozf@gmail.com") (:keywords "lisp" "docs" "extensions" "tools") (:url . "https://github.com/jingtaozf/literate-elisp"))])
+ (literate-starter-kit . [(20150730 1854) ((emacs (24 3))) "A literate starter kit to configure Emacs using Org-mode files." tar ((:commit . "6dce1d01781966c14558aa553cfc85008c06e115"))])
+ (litex-mode . [(20220415 1704) ((cl-lib (0 5)) (emacs (24 1))) "Minor mode for converting lisp to LaTeX" tar ((:commit . "5d5750af2990c050c8d36baa4b8e7a45850d5a6a") (:authors ("Gaurav Atreya" . "allmanpride@gmail.com")) (:maintainer "Gaurav Atreya" . "allmanpride@gmail.com") (:keywords "calculator" "lisp" "latex") (:url . "https://github.com/Atreyagaurav/litex-mode"))])
+ (live-code-talks . [(20180907 1647) ((emacs (24)) (cl-lib (0 5)) (narrowed-page-navigation (0 1))) "Support for slides with live code in them" single ((:commit . "97f16a9ee4e6ff3e0f9291eaead772c66e3e12ae") (:authors ("David Raymond Christiansen" . "david@davidchristiansen.dk")) (:maintainer "David Raymond Christiansen" . "david@davidchristiansen.dk") (:keywords "docs" "multimedia"))])
+ (live-preview . [(20201010 1948) ((emacs (24 4))) "Live preview by any shell command while editing" single ((:commit . "603a4a1759fbec92e7a1cabc249517c78e59ce7e") (:authors ("Lassi Kortela" . "lassi@lassi.io")) (:maintainer "Lassi Kortela" . "lassi@lassi.io") (:keywords "languages" "util") (:url . "https://github.com/lassik/emacs-live-preview"))])
+ (live-py-mode . [(20220404 0) ((emacs (24 3))) "Live Coding in Python" tar ((:commit . "b10020b0414f15990f4139c363910b58c7ca0852") (:authors ("Don Kirkby http://donkirkby.github.io")) (:maintainer "Don Kirkby http://donkirkby.github.io") (:keywords "live" "coding") (:url . "http://donkirkby.github.io/live-py-plugin/"))])
+ (lively . [(20171005 754) nil "interactively updating text" single ((:commit . "348675828c6a81bfa1ac311ca465aad813542c1b") (:authors ("Luke Gorrie" . "luke@bup.co.nz")) (:maintainer "Steve Purcell" . "steve@sanityinc.com"))])
+ (livereload . [(20170629 650) ((emacs (25)) (websocket (1 8))) "Livereload server" tar ((:commit . "1e501d7e46dbd476c2c7cc9d20b5ac9d41fb1955") (:authors ("João Távora" . "joaotavora@gmail.com")) (:maintainer "João Távora" . "joaotavora@gmail.com") (:keywords "convenience"))])
+ (livescript-mode . [(20140613 421) nil "Major mode for editing LiveScript files" single ((:commit . "90a918d9686e256e6d4d439cc20f24dad8d3b804") (:authors ("Hisamatsu Yasuyuki" . "yas@null.net")) (:maintainer "Hisamatsu Yasuyuki" . "yas@null.net") (:keywords "languages" "livescript") (:url . "https://github.com/yhisamatsu/livescript-mode"))])
+ (livid-mode . [(20131116 1344) ((skewer-mode (1 5 3)) (s (1 8 0))) "Live browser eval of JavaScript every time a buffer changes" single ((:commit . "dfe5212fa64738bc4138bfebf349fbc8bc237c26") (:authors ("Murphy McMahon")) (:maintainer "Murphy McMahon") (:url . "https://github.com/pandeiro/livid-mode"))])
+ (ll-debug . [(20211002 1031) ((emacs (24 3))) "Low level debug tools" single ((:commit . "a2cfeab46e5100c348b35987fae34f9ea76d7c0b") (:authors ("Claus Brunzema" . "mail@cbrunzema.de")) (:maintainer "Claus Brunzema" . "mail@cbrunzema.de") (:keywords "abbrev" "convenience" "tools" "c" "lisp") (:url . "https://github.com/replrep/ll-debug"))])
+ (llama . [(20220428 1405) ((seq (2 20))) "Anonymous function literals" single ((:commit . "adc5d169fad53d6d11000a72dc95f8489a8c7534") (:keywords "extensions") (:url . "https://git.sr.ht/~tarsius/llama"))])
+ (lms . [(20210820 2200) ((emacs (25 1))) "Squeezebox / Logitech Media Server frontend" single ((:commit . "05c8fd16ff94590393b6b0a9cb193ec9572a9c97") (:authors ("Iñigo Serna" . "inigoserna@gmx.com")) (:maintainer "Iñigo Serna" . "inigoserna@gmx.com") (:keywords "multimedia") (:url . "https://hg.serna.eu/emacs/lms"))])
+ (load-bash-alias . [(20220108 2103) ((emacs (24 1)) (seq (2 16))) "Convert bash aliases into eshell ones" single ((:commit . "968f037eff48ceca15fd135738051c48ab14cfd6") (:authors ("Davide Restivo" . "davide.restivo@yahoo.it")) (:maintainer "Davide Restivo" . "davide.restivo@yahoo.it") (:keywords "emacs" "bash" "eshell" "alias") (:url . "https://github.com/daviderestivo/load-bash-alias"))])
+ (load-env-vars . [(20180511 2210) ((emacs (24))) "Load environment variables from files" single ((:commit . "3808520efaf9492033f6e11a9bffd68eabf02a0f") (:authors ("Jorge Dias" . "jorge@mrdias.com")) (:maintainer "Jorge Dias" . "jorge@mrdias.com") (:keywords "lisp") (:url . "https://github.com/diasjorge/emacs-load-env-vars"))])
+ (load-relative . [(20201130 2202) nil "Relative file load (within a multi-file Emacs package)" tar ((:commit . "ff2a827144353d29d70392fd95c14c15df207011") (:authors ("Rocky Bernstein" . "rocky@gnu.org")) (:maintainer "Rocky Bernstein" . "rocky@gnu.org") (:keywords "internal") (:url . "https://github.com/rocky/emacs-load-relative"))])
+ (load-theme-buffer-local . [(20120702 2036) nil "Install emacs24 color themes by buffer." single ((:commit . "e606dec66f16a06140b9aad625a4fd52bca4f936") (:authors ("Victor Borja" . "vic.borja@gmail.com")) (:maintainer "Victor Borja" . "vic.borja@gmail.com") (:keywords "faces") (:url . "http://github.com/vic/color-theme-buffer-local"))])
+ (loc-changes . [(20200722 1111) nil "keep track of positions even after buffer changes" single ((:commit . "0a55bcba684f78417e831eef2cc32da24a207f29") (:authors ("Rocky Bernstein" . "rocky@gnu.org")) (:maintainer "Rocky Bernstein" . "rocky@gnu.org") (:url . "https://github.com/rocky/emacs-loc-changes"))])
+ (loccur . [(20210224 2041) ((emacs (25 1))) "Perform an occur-like folding in current buffer" single ((:commit . "01b7afa62589432a98171074abb8c5a1e089034a") (:authors ("Alexey Veretennikov" . "alexey.veretennikov@gmail.com")) (:maintainer "Alexey Veretennikov" . "alexey.veretennikov@gmail.com") (:keywords "matching") (:url . "https://github.com/fourier/loccur"))])
+ (lockfile-mode . [(20170625 507) nil "Major mode for .lock files" single ((:commit . "fcfef88460cb3cd67c4d83a1801d0326d282feac") (:authors ("Preetpal S. Sohal")) (:maintainer "Preetpal S. Sohal") (:url . "https://github.com/preetpalS/emacs-lockfile-mode"))])
+ (lodgeit . [(20190802 1308) nil "Paste to a lodgeit powered pastebin" single ((:commit . "442637194d48a7105b7747b8d98772f5899f9e21") (:authors ("Eric Larson" . "eric@ionrock.org")) (:maintainer "Eric Larson" . "eric@ionrock.org") (:keywords "pastebin" "lodgeit") (:url . "https://github.com/ionrock/lodgeit-el"))])
+ (log4e . [(20211019 948) nil "provide logging framework for elisp" single ((:commit . "737d275eac28dbdfb0b26d28e99da148bfce9d16") (:authors ("Hiroaki Otsu" . "ootsuhiroaki@gmail.com")) (:maintainer "Hiroaki Otsu" . "ootsuhiroaki@gmail.com") (:keywords "log") (:url . "https://github.com/aki2o/log4e"))])
+ (log4j-mode . [(20160108 1918) nil "major mode for viewing log files" single ((:commit . "26171b1e723502055e085393b0ecdcb6db406010") (:authors ("Johan Dykstrom" . "jody4711-sf@yahoo.se")) (:maintainer "Johan Dykstrom" . "jody4711-sf@yahoo.se") (:keywords "tools") (:url . "http://log4j-mode.sourceforge.net"))])
+ (logalimacs . [(20131021 1829) ((popwin (0 6 2)) (popup (0 5 0)) (stem (20130120))) "Front-end to logaling-command for Ruby gems" single ((:commit . "8286e39502250fc6c3c6656a7f46a8eee8e9a713") (:authors ("Yuta Yamada <cokesboy\"at\"gmail.com>")) (:maintainer "Yuta Yamada <cokesboy\"at\"gmail.com>") (:keywords "translation" "logaling-command") (:url . "https://github.com/logaling/logalimacs"))])
+ (logito . [(20201226 534) ((emacs (25 1))) "logging library for Emacs" single ((:commit . "d5934ce10ba3a70d3fcfb94d742ce3b9136ce124") (:authors ("Yann Hodique" . "yann.hodique@gmail.com")) (:maintainer "Yann Hodique" . "yann.hodique@gmail.com") (:keywords "lisp" "extensions"))])
+ (logms . [(20210721 349) ((emacs (27 1)) (f (0 20 0)) (s (1 9 0)) (ht (2 3))) "Log message with clickable links to context" single ((:commit . "b3366ec866b6e3b5c608fee23e86eb832d132ef8") (:authors ("Shen, Jen-Chieh" . "jcs090218@gmail.com")) (:maintainer "Shen, Jen-Chieh" . "jcs090218@gmail.com") (:url . "https://github.com/jcs-elpa/logms"))])
+ (lognav-mode . [(20220410 1344) ((emacs (24 3))) "Navigate Log Error Messages" single ((:commit . "100541ec31468b771073a7d2ad4512c1dcb1eb07") (:authors ("Shawn Ellis" . "shawn.ellis17@gmail.com")) (:maintainer "Shawn Ellis" . "shawn.ellis17@gmail.com") (:keywords "log" "error" "lognav-mode" "convenience") (:url . "https://hg.osdn.net/view/lognav-mode/lognav-mode"))])
+ (logpad . [(20201113 917) nil "Simulate Windows Notepad for logging." single ((:commit . "166543873e665936b468d9f120155cce515da3f8") (:authors ("Sven Knurr" . "git@tuxproject.de")) (:maintainer "Sven Knurr" . "git@tuxproject.de") (:keywords "files" "outlines" "notepad") (:url . "https://github.com/dertuxmalwieder/logpad.el"))])
+ (logstash-conf . [(20210123 1949) nil "basic mode for editing logstash configuration" single ((:commit . "ebc4731c45709ad1e0526f4f4164020ae83cbeff") (:authors ("Wilfred Hughes" . "me@wilfred.me.uk")) (:maintainer "Wilfred Hughes" . "me@wilfred.me.uk"))])
+ (logview . [(20201014 2033) ((emacs (24 4)) (datetime (0 6 1)) (extmap (1 0))) "Major mode for viewing log files" single ((:commit . "5a543c53d04d32f0adcc023253888198e0b69589") (:authors ("Paul Pogonyshev" . "pogonyshev@gmail.com")) (:maintainer "Paul Pogonyshev" . "pogonyshev@gmail.com") (:keywords "files" "tools") (:url . "https://github.com/doublep/logview"))])
+ (lol-data-dragon . [(20200705 1822) ((emacs (25 1))) "Browse Champions of League of Legends on Data Dragon" single ((:commit . "0deec9867bd7ba96220ee2968a9b2a94fd474431") (:authors ("Xu Chunyang")) (:maintainer "Xu Chunyang") (:keywords "games" "hypermedia") (:url . "https://github.com/xuchunyang/lol-data-dragon.el"))])
+ (lolcat . [(20190527 1145) ((emacs (24 3))) "Rainbows and unicorns!" single ((:commit . "4855e587a3b9681c077dac4b9f166dd860f439a4") (:authors ("Xu Chunyang" . "mail@xuchunyang.me")) (:maintainer "Xu Chunyang" . "mail@xuchunyang.me") (:url . "https://github.com/xuchunyang/lolcat.el"))])
+ (lolcode-mode . [(20111002 847) nil "Major mode for editing LOLCODE" single ((:commit . "1914f1ba87587ecf5f175eeb2144c28e9f039317") (:authors ("Bodil Stokke" . "lolcode@bodil.tv")) (:maintainer "Bodil Stokke" . "lolcode@bodil.tv") (:keywords "lolcode" "major" "mode") (:url . "http://github.com/bodil/lolcode-mode"))])
+ (look-dired . [(20160729 2323) ((look-mode (1 0))) "Extensions to look-mode for dired buffers" single ((:commit . "9bfa4e5e6f3810705b6426c88493ea0bf6b15640") (:authors ("Joe Bloggs" . "vapniks@yahoo.com")) (:maintainer "Joe Bloggs" . "vapniks@yahoo.com") (:keywords "convenience") (:url . "https://github.com/vapniks/look-dired"))])
+ (look-mode . [(20220313 2103) nil "quick file viewer for image and text file browsing" single ((:commit . "4ab32794b07f77b1d243dc07239c417f20cab7b8") (:authors ("Peter H. Mao <peter.mao@gmail.com>" . "petermao@jpl.nasa.gov")) (:maintainer "Peter H. Mao <peter.mao@gmail.com>" . "petermao@jpl.nasa.gov"))])
+ (loop . [(20160813 1407) nil "friendly imperative loop structures" single ((:commit . "9db6372791bbd0cf3fa907ed0ae3e6b7bcf6cc57") (:authors ("Wilfred Hughes" . "me@wilfred.me.uk")) (:maintainer "Wilfred Hughes" . "me@wilfred.me.uk") (:keywords "loop" "while" "for each" "break" "continue"))])
+ (loophole . [(20220311 1130) ((emacs (27 1))) "Manage temporary key bindings" single ((:commit . "bd93fcd42fc2db76bf6bc3fbb4eb7401444bd04d") (:authors ("0x60DF" . "0x60df@gmail.com")) (:maintainer "0x60DF" . "0x60df@gmail.com") (:keywords "convenience") (:url . "https://github.com/0x60df/loophole"))])
+ (loopy . [(20220503 2340) ((emacs (27 1)) (map (3 0)) (seq (2 22))) "A looping macro" tar ((:commit . "9db4f2f2a2c4f4ef5fd4e80cb6dfe00306aa9d8c") (:authors ("Earl Hyatt")) (:maintainer "Earl Hyatt") (:keywords "extensions") (:url . "https://github.com/okamsn/loopy"))])
+ (loopy-dash . [(20220330 127) ((emacs (25 1)) (loopy (0 10 1)) (dash (2 19))) "Dash destructuring for `loopy'" single ((:commit . "9db4f2f2a2c4f4ef5fd4e80cb6dfe00306aa9d8c") (:authors ("Earl Hyatt")) (:maintainer "Earl Hyatt") (:keywords "extensions") (:url . "https://github.com/okamsn/loopy"))])
+ (lorem-ipsum . [(20190819 2042) nil "Insert dummy pseudo Latin text." single ((:commit . "da75c155da327c7a7aedb80f5cfe409984787049") (:authors ("Jean-Philippe Theberge" . "jphil21@sourceforge.net")) (:maintainer "Joe Schafer" . "joe@jschaf.com") (:keywords "tools" "language" "convenience"))])
+ (lox-mode . [(20200619 1700) ((emacs (24 3))) "Major mode for the Lox programming language" single ((:commit . "b6935b3f5b131d2c1c7685cf6464274f7cd64943") (:authors ("Timmy Jose" . "zoltan.jose@gmail.com")) (:maintainer "Timmy Jose" . "zoltan.jose@gmail.com") (:keywords "languages" "lox") (:url . "https://github.com/timmyjose-projects/lox-mode"))])
+ (lpy . [(20201027 1425) ((emacs (25 1)) (lispy (0 27 0))) "A lispy interface to Python" tar ((:commit . "076ce9acb68f6ac1b39127b634a91ffd865d13d8") (:authors ("Oleh Krehel" . "ohwoeowho@gmail.com")) (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com") (:keywords "python" "lisp") (:url . "https://github.com/abo-abo/lpy"))])
+ (lsp-dart . [(20220430 1535) ((emacs (26 3)) (lsp-treemacs (0 3)) (lsp-mode (7 0 1)) (dap-mode (0 6)) (f (0 20 0)) (dash (2 14 1)) (dart-mode (1 0 5))) "Dart support lsp-mode" tar ((:commit . "7ca60ce9a703ad7a950dcd5ec36ef4251f57d207") (:keywords "languages" "extensions") (:url . "https://emacs-lsp.github.io/lsp-dart"))])
+ (lsp-docker . [(20220501 1056) ((emacs (26 1)) (dash (2 14 1)) (lsp-mode (6 2 1)) (f (0 20 0)) (yaml (0 2 0)) (ht (2 0))) "LSP Docker integration" single ((:commit . "c57863609abfb93fccabf81dc3112ac38f93c4a2") (:authors ("Ivan Yonchovski" . "yyoncho@gmail.com")) (:maintainer "Ivan Yonchovski" . "yyoncho@gmail.com") (:keywords "languages" "langserver") (:url . "https://github.com/emacs-lsp/lsp-docker"))])
+ (lsp-focus . [(20200906 1917) ((emacs (26 1)) (focus (0 1 1)) (lsp-mode (6 1))) "focus.el support for lsp-mode" single ((:commit . "d01f0af156e4e78dcb9fa8e080a652cf8f221d30") (:authors ("Vibhav Pant")) (:maintainer "Vibhav Pant") (:keywords "languages" "lsp-mode") (:url . "https://github.com/emacs-lsp/lsp-focus"))])
+ (lsp-grammarly . [(20220222 638) ((emacs (27 1)) (lsp-mode (6 1)) (grammarly (0 3 0)) (request (0 3 0)) (s (1 12 0)) (ht (2 3))) "LSP Clients for Grammarly" single ((:commit . "1e2aff23dfaf419bfae66718761a0eddbd6f613e") (:authors ("Shen, Jen-Chieh" . "jcs090218@gmail.com")) (:maintainer "Shen, Jen-Chieh" . "jcs090218@gmail.com") (:url . "https://github.com/emacs-grammarly/lsp-grammarly"))])
+ (lsp-haskell . [(20220307 2312) ((emacs (24 3)) (lsp-mode (3 0))) "Haskell support for lsp-mode" single ((:commit . "daa51072e1718ca075987901fccbbc2357bca1fc") (:keywords "haskell") (:url . "https://github.com/emacs-lsp/lsp-haskell"))])
+ (lsp-intellij . [(20180831 2051) ((emacs (25 1)) (lsp-mode (4 1))) "intellij lsp client" single ((:commit . "cf30f0ac63bd0140e758840b8ab070e8313697b2") (:authors ("Ruin0x11" . "ipickering2@gmail.com")) (:maintainer "Ruin0x11" . "ipickering2@gmail.com") (:keywords "languages" "processes" "tools") (:url . "https://github.com/Ruin0x11/lsp-intellij"))])
+ (lsp-ivy . [(20210904 2043) ((emacs (25 1)) (dash (2 14 1)) (lsp-mode (6 2 1)) (ivy (0 13 0))) "LSP ivy integration" single ((:commit . "3e87441a625d65ced5a208a0b0442d573596ffa3") (:keywords "languages" "debug") (:url . "https://github.com/emacs-lsp/lsp-ivy"))])
+ (lsp-java . [(20220325 547) ((emacs (25 1)) (lsp-mode (6 0)) (markdown-mode (2 3)) (dash (2 18 0)) (f (0 20 0)) (ht (2 0)) (request (0 3 0)) (treemacs (2 5)) (dap-mode (0 5))) "Java support for lsp-mode" tar ((:commit . "39ca56e24d6f9db2c9d889f79808713e4afde027") (:keywords "languague" "tools") (:url . "https://github.com/emacs-lsp/lsp-java"))])
+ (lsp-javacomp . [(20190124 1755) ((emacs (25 1)) (lsp-mode (3 0)) (s (1 2 0))) "Provide Java IDE features powered by JavaComp." single ((:commit . "82aa4ad6ca03a74565c35e855b318b1887bcd89b") (:keywords "java" "tools" "lsp") (:url . "https://github.com/tigersoldier/lsp-javacomp"))])
+ (lsp-jedi . [(20220430 18) ((emacs (25 1)) (lsp-mode (6 0))) "Lsp client plugin for Python Jedi Language Server" single ((:commit . "5e3eb3e160c2d38b8bd2b5cd3b86fa4f823f9330") (:authors ("Fred Campos" . "fred.tecnologia@gmail.com")) (:maintainer "Fred Campos") (:keywords "language-server" "tools" "python" "jedi" "ide") (:url . "http://github.com/fredcamps/lsp-jedi"))])
+ (lsp-julia . [(20211229 1534) ((emacs (25 1)) (lsp-mode (6 3)) (julia-mode (0 3))) "Julia support for lsp-mode" tar ((:commit . "d6688bb131ff4a5a0201f6d3826ef0b018265389") (:authors ("Martin Wolke" . "vibhavp@gmail.com") ("Adam Beckmeyer" . "adam_git@thebeckmeyers.xyz") ("Guido Kraemer" . "gdkrmr@users.noreply.github.com")) (:maintainer "Guido Kraemer" . "gdkrmr@users.noreply.github.com") (:keywords "languages" "tools") (:url . "https://github.com/gdkrmr/lsp-julia"))])
+ (lsp-latex . [(20210815 1426) ((emacs (25 1)) (lsp-mode (6 0))) "LSP-mode client for LaTeX, on texlab" single ((:commit . "3f6b2ac9585682828eef81f895757f74cfba7309") (:authors ("ROCKTAKEY" . "rocktakey@gmail.com")) (:maintainer "ROCKTAKEY" . "rocktakey@gmail.com") (:keywords "languages" "tex") (:url . "https://github.com/ROCKTAKEY/lsp-latex"))])
+ (lsp-ltex . [(20220222 656) ((emacs (26 1)) (lsp-mode (6 1))) "LSP Clients for LTEX" single ((:commit . "e13bedf0032d376e1e28026abda5970bbbdb636d") (:authors ("Shen, Jen-Chieh" . "jcs090218@gmail.com")) (:maintainer "Shen, Jen-Chieh" . "jcs090218@gmail.com") (:url . "https://github.com/emacs-languagetool/lsp-ltex"))])
+ (lsp-metals . [(20220330 1958) ((emacs (26 1)) (scala-mode (1 1)) (lsp-mode (7 0)) (lsp-treemacs (0 2)) (dap-mode (0 3)) (dash (2 18 0)) (f (0 20 0)) (ht (2 0)) (treemacs (2 5))) "Scala Client settings" tar ((:commit . "b7f77de69431786c54e9a57845e4f2d75fbee053") (:authors ("Ross A. Baker" . "ross@rossabaker.com") ("Evgeny Kurnevsky" . "kurnevsky@gmail.com")) (:maintainer "Ross A. Baker" . "ross@rossabaker.com") (:keywords "languages" "extensions") (:url . "https://github.com/emacs-lsp/lsp-metals"))])
+ (lsp-mode . [(20220505 630) ((emacs (26 1)) (dash (2 18 0)) (f (0 20 0)) (ht (2 3)) (spinner (1 7 3)) (markdown-mode (2 3)) (lv (0))) "LSP mode" tar ((:commit . "6327359f3b5e19aeaa1c9ee6bd9b80b51f95f843") (:authors ("Vibhav Pant, Fangrui Song, Ivan Yonchovski")) (:maintainer "Vibhav Pant, Fangrui Song, Ivan Yonchovski") (:keywords "languages") (:url . "https://github.com/emacs-lsp/lsp-mode"))])
+ (lsp-mssql . [(20191204 1150) ((emacs (25 1)) (lsp-mode (6 2)) (dash (2 14 1)) (f (0 20 0)) (ht (2 0)) (lsp-treemacs (0 1))) "MSSQL LSP bindings" tar ((:commit . "8d5d4d4a7f72b4cae89a48ea8618f3ef28bcb121") (:authors ("Ivan Yonchovski" . "yyoncho@gmail.com")) (:maintainer "Ivan Yonchovski" . "yyoncho@gmail.com") (:keywords "data" "languages") (:url . "https://github.com/emacs-lsp/lsp-mssql"))])
+ (lsp-origami . [(20211016 1045) ((origami (1 0)) (lsp-mode (6 1))) "origami.el support for lsp-mode" single ((:commit . "7df9c91a309aa4229bec41f109920b37c4197618") (:authors ("Vibhav Pant")) (:maintainer "Vibhav Pant") (:keywords "languages" "lsp-mode") (:url . "https://github.com/emacs-lsp/lsp-origami"))])
+ (lsp-p4 . [(20190127 1049) ((lsp-mode (3 0))) "P4 support for lsp-mode" tar ((:commit . "669460d93b87fb876df11b2b68229677e7ad1a26") (:authors ("Dmitri Makarov")) (:maintainer "Dmitri Makarov") (:keywords "lsp" "p4") (:url . "https://github.com/dmakarov/p4ls"))])
+ (lsp-pascal . [(20200422 1610) ((emacs (24 4)) (lsp-mode (6 3))) "LSP client for Pascal" single ((:commit . "b132bdf66748e4abe0d4140f6d061b1ccd56082a") (:authors ("Arjan Adriaanse" . "arjan@adriaan.se")) (:maintainer "Arjan Adriaanse" . "arjan@adriaan.se") (:keywords "languages" "tools") (:url . "https://github.com/arjanadriaanse/lsp-pascal"))])
+ (lsp-pyre . [(20190406 335) ((lsp-mode (6 0))) "lsp-mode client for python using pyre" single ((:commit . "e177b8f5efd1a955b5753aeb5d1894e6d21be35a") (:authors ("John Allen" . "oss@porcnick.com")) (:maintainer "John Allen" . "oss@porcnick.com") (:url . "https://github.com/jra3/lsp-pyre"))])
+ (lsp-pyright . [(20220411 1753) ((emacs (26 1)) (lsp-mode (7 0)) (dash (2 18 0)) (ht (2 0))) "Python LSP client using Pyright" single ((:commit . "ab7369d96f4d7d058d0e06e743f86fda8ecc191c") (:authors ("Arif Rezai, Vincent Zhang, Andrew Christianson")) (:maintainer "Arif Rezai, Vincent Zhang, Andrew Christianson") (:keywords "languages" "tools" "lsp") (:url . "https://github.com/emacs-lsp/lsp-pyright"))])
+ (lsp-python-ms . [(20211204 1209) ((emacs (25 1)) (lsp-mode (6 1))) "The lsp-mode client for Microsoft python-language-server" single ((:commit . "f8e7c4bcaefbc3fd96e1ca53d17589be0403b828") (:authors ("Charl Botha")) (:maintainer "Andrew Christianson, Vincent Zhang") (:keywords "languages" "tools") (:url . "https://github.com/emacs-lsp/lsp-python-ms"))])
+ (lsp-rescript . [(20220314 1957) ((lsp-mode (7 0 1)) (emacs (25 1)) (rescript-mode (0 1))) "LSP client configuration for lsp-mode and rescript-vscode" single ((:commit . "7baf9adf10234cf964feefae99050268e9bc5681") (:authors ("John Lee")) (:maintainer "John Lee") (:keywords "languages") (:url . "https://github.com/jjlee/lsp-rescript"))])
+ (lsp-sonarlint . [(20210820 2044) ((emacs (25)) (dash (2 12 0)) (lsp-mode (6 3)) (ht (2 3))) "Emacs Sonarlint lsp client" tar ((:commit . "3af97828f9c08d782fb2086e3a73bda5759e6788") (:authors ("Fermin MF" . "fmfs@posteo.net")) (:maintainer "Fermin MF" . "fmfs@posteo.net") (:keywords "languages" "tools" "php" "javascript" "xml" "ruby" "html" "scala" "java" "python") (:url . "https://github.com/emacs-lsp/lsp-sonarlint"))])
+ (lsp-sourcekit . [(20210905 2017) ((emacs (25 1)) (lsp-mode (5))) "sourcekit-lsp client for lsp-mode" single ((:commit . "97ff36b228a61e69734c7180f33cc6951b1a600f") (:authors ("Daniel Martín")) (:maintainer "Daniel Martín") (:keywords "languages" "lsp" "swift" "objective-c" "c++") (:url . "https://github.com/emacs-lsp/lsp-sourcekit"))])
+ (lsp-tailwindcss . [(20211211 248) ((lsp-mode (7 1)) (emacs (26 1))) "A lsp-mode client for tailwindcss" single ((:commit . "8c04fc4ac6f5eb8053ecdaaedffa35e0f7a5b865") (:authors ("A.I." . "merrick@luois.me")) (:maintainer "A.I." . "merrick@luois.me") (:keywords "language" "tools") (:url . "https://github.com/merrickluo/lsp-tailwindcss"))])
+ (lsp-treemacs . [(20220502 459) ((emacs (26 1)) (dash (2 18 0)) (f (0 20 0)) (ht (2 0)) (treemacs (2 5)) (lsp-mode (6 0))) "LSP treemacs" tar ((:commit . "9859326df6b8e8c954a3c227e53b6878e54aaae8") (:authors ("Ivan Yonchovski")) (:maintainer "Ivan Yonchovski") (:keywords "languages") (:url . "https://github.com/emacs-lsp/lsp-treemacs"))])
+ (lsp-ui . [(20220425 1046) ((emacs (26 1)) (dash (2 18 0)) (lsp-mode (6 0)) (markdown-mode (2 3))) "UI modules for lsp-mode" tar ((:commit . "6cd0409de6ca59c02d752b8e543bb5eaa61357e4") (:authors ("Sebastien Chapuis <sebastien@chapu.is>, Fangrui Song" . "i@maskray.me")) (:maintainer "Sebastien Chapuis <sebastien@chapu.is>, Fangrui Song" . "i@maskray.me") (:keywords "languages" "tools") (:url . "https://github.com/emacs-lsp/lsp-ui"))])
+ (lua-mode . [(20210809 1320) ((emacs (24 3))) "a major-mode for editing Lua scripts" single ((:commit . "5a9bee8d5fc978dc64fcb677167417010321ba65") (:authors ("2011-2013 immerrr" . "immerrr+lua@gmail.com") ("2010-2011 Reuben Thomas" . "rrt@sc3d.org") ("2006 Juergen Hoetzel" . "juergen@hoetzel.info") ("2004 various (support for Lua 5 and byte compilation)") ("2001 Christian Vogler" . "cvogler@gradient.cis.upenn.edu") ("1997 Bret Mogilefsky" . "mogul-lua@gelatinous.com") ("tcl-mode by Gregor Schmid" . "schmid@fb3-s7.math.tu-berlin.de") ("with tons of assistance from") ("Paul Du Bois" . "pld-lua@gelatinous.com") ("Aaron Smith" . "aaron-lua@gelatinous.com")) (:maintainer "2011-2013 immerrr" . "immerrr+lua@gmail.com") (:keywords "languages" "processes" "tools") (:url . "https://immerrr.github.io/lua-mode"))])
+ (luarocks . [(20170430 2305) ((emacs (24)) (cl-lib (0 5))) "luarocks tools" single ((:commit . "cee27ba0716edf338077387969883226dd2b7484") (:authors ("Mario Rodas" . "marsam@users.noreply.github.com")) (:maintainer "Mario Rodas" . "marsam@users.noreply.github.com") (:keywords "convenience") (:url . "https://github.com/emacs-pe/luarocks.el"))])
+ (lush-theme . [(20180816 2200) ((emacs (24))) "A dark theme with lush colors" single ((:commit . "645e1959143532df8f7ef90e1184e9556df18af7") (:authors ("Andre Richter" . "andre.o.richter@gmail.com")) (:maintainer "Andre Richter" . "andre.o.richter@gmail.com") (:keywords "theme" "dark" "strong colors") (:url . "https://github.com/andre-richter/emacs-lush-theme"))])
+ (lusty-explorer . [(20200602 228) ((emacs (25 1))) "Dynamic filesystem explorer and buffer switcher" single ((:commit . "a746514ccd8df71fc920ba8ad0aa8dca58702631") (:keywords "convenience" "files" "matching" "tools") (:url . "https://github.com/sjbach/lusty-emacs"))])
+ (lux-mode . [(20220328 1301) ((emacs (24 3))) "Major mode for editing lux files" single ((:commit . "924dcda3e4212c0b28e8ce140b9d8e9a1117c5ef") (:authors ("Håkan Mattsson")) (:maintainer "Håkan Mattsson") (:url . "https://github.com/hawk/lux"))])
+ (lv . [(20200507 1518) nil "Other echo area" single ((:commit . "9e9e00cb240ea1903ffd36a54956b3902c379d29") (:authors ("Oleh Krehel")) (:maintainer "Oleh Krehel"))])
+ (lxc . [(20140410 2022) nil "lxc integration with Emacs" single ((:commit . "88bed56c954d1edd9ff5ce0ced2c02dcf9f71835") (:authors ("Nic Ferrier" . "nferrier@ferrier.me.uk")) (:maintainer "Nic Ferrier" . "nferrier@ferrier.me.uk") (:keywords "processes") (:url . "https://github.com/nicferrier/emacs-lxc"))])
+ (lxc-tramp . [(20200414 1445) ((emacs (24)) (cl-lib (0 6))) "TRAMP integration for LXC containers" single ((:commit . "1585e55a5deb89e2f4e30a0ad9e0f121d1e0ebcb") (:authors ("montag451")) (:maintainer "montag451") (:keywords "lxc" "convenience") (:url . "https://github.com/montag451/lxc-tramp"))])
+ (lxd-tramp . [(20181023 7) ((emacs (24 4)) (cl-lib (0 6))) "TRAMP integration for LXD containers" single ((:commit . "f335c76245f62b02cf67a9376eca6f3863c8a75a") (:authors ("Yc.S" . "onixie@gmail.com")) (:maintainer "Yc.S" . "onixie@gmail.com") (:keywords "lxd" "lxc" "convenience") (:url . "https://github.com/onixie/lxd-tramp.git"))])
+ (lyrics . [(20220206 116) ((emacs (25 1)) (seq (2 15))) "Show lyrics" single ((:commit . "c3d42f1e039941f32f49252e1b1610de337b4470") (:authors ("Mario Rodas" . "marsam@users.noreply.github.com")) (:maintainer "Mario Rodas" . "marsam@users.noreply.github.com") (:keywords "convenience") (:url . "https://github.com/emacs-pe/lyrics.el"))])
+ (lyrics-fetcher . [(20220207 1326) ((emacs (27)) (emms (7 5)) (f (0 20 0)) (request (0 3 2))) "Fetch song lyrics and album covers" tar ((:commit . "06bd0293dfa759df48faefd73be60d43d1febd17") (:authors ("Korytov Pavel" . "thexcloud@gmail.com")) (:maintainer "Korytov Pavel" . "thexcloud@gmail.com") (:url . "https://github.com/SqrtMinusOne/lyrics-fetcher.el"))])
+ (m-buffer . [(20170407 2141) ((seq (2 14))) "List-Oriented, Functional Buffer Manipulation" tar ((:commit . "8681342aaffa187e5c54945ab91b812965a96d19") (:authors ("Phillip Lord" . "phillip.lord@russet.org.uk")) (:maintainer "Phillip Lord" . "phillip.lord@russet.rg.uk"))])
+ (mac-pseudo-daemon . [(20200215 513) ((cl-lib (0 1))) "Daemon mode that plays nice with Mac OS." single ((:commit . "94240ebb716f11af8427b6295c3f44c0c43419d3") (:authors ("Ryan C. Thompson")) (:maintainer "Ryan C. Thompson") (:keywords "convenience" "osx" "mac") (:url . "https://github.com/DarwinAwardWinner/osx-pseudo-daemon"))])
+ (maces-game . [(20170903 1551) ((dash (2 12 0)) (cl-lib (0 5)) (emacs (24))) "another anagram game." tar ((:commit . "c0fb795f5642467ea528d2f04d904547e8a77ecd") (:authors ("Pawel Bokota" . "pawelb.lnx@gmail.com")) (:maintainer "Pawel Bokota" . "pawelb.lnx@gmail.com") (:keywords "games" "word games" "anagram") (:url . "https://github.com/pawelbx/anagram-game"))])
+ (macports . [(20220505 1059) ((emacs (25 1)) (transient (0 1 0))) "A porcelain for MacPorts" tar ((:commit . "f3b42ef6be07c72d0d678ecbca51bd3d42646f21") (:authors ("Aaron Madlon-Kay")) (:maintainer "Aaron Madlon-Kay") (:keywords "convenience") (:url . "https://github.com/amake/macports.el"))])
+ (macro-math . [(20130328 1604) nil "in-buffer mathematical operations" single ((:commit . "216e59371e9ee39c34117ba79b9acd78bb415750") (:authors ("Nikolaj Schumacher <bugs * nschum de>")) (:maintainer "Nikolaj Schumacher <bugs * nschum de>") (:keywords "convenience") (:url . "http://nschum.de/src/emacs/macro-math/"))])
+ (macrostep . [(20161120 2106) ((cl-lib (0 5))) "interactive macro expander" tar ((:commit . "424e3734a1ee526a1bd7b5c3cd1d3ef19d184267") (:authors ("joddie" . "j.j.oddie@gmail.com")) (:maintainer "joddie" . "j.j.oddie@gmail.com") (:keywords "lisp" "languages" "macro" "debugging") (:url . "https://github.com/joddie/macrostep"))])
+ (macrostep-geiser . [(20210717 801) ((emacs (24 4)) (macrostep (0 9)) (geiser (0 12))) "Macrostep for `geiser'" single ((:commit . "f6a2d5bb96ade4f23df557649af87ebd0cc45125") (:authors ("Nikita Bloshchanevich")) (:maintainer "Nikita Bloshchanevich") (:keywords "languages" "scheme") (:url . "https://github.com/nbfalcon/macrostep-geiser"))])
+ (madhat2r-theme . [(20170203 30) ((emacs (24))) "dark color theme that is easy on the eyes" single ((:commit . "6b387f09de055cfcc15d74981cd4f32f8f9a7323") (:authors ("Micah Duke")) (:maintainer "Micah Duke") (:keywords "color" "theme") (:url . "https://github.com/madhat2r/madhat2r-theme"))])
+ (mag-menu . [(20150505 1850) ((splitter (0 1 0))) "Intuitive keyboard-centric menu system" single ((:commit . "9b9277021cd09fb1dba64b1d2a00705d20914bd6") (:authors ("Steven Thomas")) (:maintainer "Steven Thomas") (:keywords "convenience") (:url . "https://github.com/chumpage/mag-menu"))])
+ (magic-filetype . [(20180219 1552) ((emacs (24)) (s (1 9 0))) "Enhance filetype major mode" single ((:commit . "019494add5ff02dd36cb3f500142fc51125522cc") (:authors ("USAMI Kenta" . "tadsan@zonu.me")) (:maintainer "USAMI Kenta" . "tadsan@zonu.me") (:keywords "emulations" "vim" "ft" "file" "magic-mode") (:url . "https://github.com/zonuexe/magic-filetype.el"))])
+ (magic-latex-buffer . [(20210306 422) ((cl-lib (0 5)) (emacs (25 1))) "Magically enhance LaTeX-mode font-locking for semi-WYSIWYG editing" single ((:commit . "903ec91872760e47c0e5715795f8465173615098") (:authors ("zk_phi")) (:maintainer "zk_phi") (:url . "http://zk-phi.github.io/"))])
+ (magik-mode . [(20220422 837) nil "mode for editing Magik + some utils." tar ((:commit . "af1b83786c95d448dcb4df5406eb1cdba975abf5") (:keywords "languages") (:url . "http://github.com/roadrunner1776/magik"))])
+ (magit . [(20220503 1245) ((emacs (25 1)) (compat (28 1 1 0)) (dash (20210826)) (git-commit (20220222)) (magit-section (20220325)) (transient (20220325)) (with-editor (20220318))) "A Git porcelain inside Emacs." tar ((:commit . "476383fc8fb0f6ea4c6fc29d7057a1b5b5f95bd8") (:authors ("Marius Vollmer" . "marius.vollmer@gmail.com") ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:keywords "git" "tools" "vc") (:url . "https://github.com/magit/magit"))])
+ (magit-annex . [(20220302 1725) ((cl-lib (0 3)) (magit (3 0 0))) "Control git-annex from Magit" single ((:commit . "efe484644666c6b7c544b0fb7b87e30703fa9425") (:authors ("Kyle Meyer" . "kyle@kyleam.com") ("Rémi Vanicat" . "vanicat@debian.org")) (:maintainer "Kyle Meyer" . "kyle@kyleam.com") (:keywords "vc" "tools") (:url . "https://github.com/magit/magit-annex"))])
+ (magit-circleci . [(20191209 2113) ((dash (2 16 0)) (transient (0 1 0)) (magit (2 90 0)) (emacs (25 3))) "CircleCI integration for Magit" single ((:commit . "2d4bdacf498ed3ff7d2c3574d346b2d24cbb12da") (:authors ("Adrien Brochard")) (:maintainer "Adrien Brochard") (:keywords "circleci" "continuous" "integration" "magit" "vc" "tools") (:url . "https://github.com/abrochard/magit-circleci"))])
+ (magit-commit-mark . [(20220422 705) ((emacs (28 1)) (magit (3 3 0))) "Support marking commits as read" single ((:commit . "2a4d08ac816734fc8195f86f685443e58e63da06") (:authors ("Campbell Barton" . "ideasman42@gmail.com")) (:maintainer "Campbell Barton" . "ideasman42@gmail.com") (:url . "https://gitlab.com/ideasman42/emacs-magit-commit-mark"))])
+ (magit-delta . [(20220125 50) ((emacs (25 1)) (magit (20200426)) (xterm-color (2 0))) "Use Delta when displaying diffs in Magit" single ((:commit . "5fc7dbddcfacfe46d3fd876172ad02a9ab6ac616") (:authors ("Dan Davison" . "dandavison7@gmail.com")) (:maintainer "Dan Davison" . "dandavison7@gmail.com") (:url . "https://github.com/dandavison/magit-delta"))])
+ (magit-diff-flycheck . [(20190524 551) ((magit (2)) (flycheck (31)) (seq (2)) (emacs (25 1))) "Report errors in diffs" single ((:commit . "28acf74f59e385865746cccf4b1e4c4025ae9433") (:authors ("Alex Ragone" . "ragonedk@gmail.com")) (:maintainer "Alex Ragone" . "ragonedk@gmail.com") (:keywords "convenience" "matching") (:url . "https://github.com/ragone/magit-diff-flycheck"))])
+ (magit-filenotify . [(20151116 2340) ((magit (1 3 0)) (emacs (24 4))) "Refresh status buffer when git tree changes" single ((:commit . "c0865b3c41af20b6cd89de23d3b0beb54c8401a4") (:authors ("Rüdiger Sonderfeld" . "ruediger@c-plusplus.de")) (:maintainer "Rüdiger Sonderfeld" . "ruediger@c-plusplus.de") (:keywords "tools"))])
+ (magit-find-file . [(20150702 830) ((magit (2 1 0)) (dash (2 8 0))) "completing-read over all files in Git" single ((:commit . "c3ea91bab37d10a814a829728ec972811f728d60") (:authors ("Bradley Wright" . "brad@intranation.com")) (:maintainer "Bradley Wright" . "brad@intranation.com") (:keywords "git") (:url . "https://github.com/bradleywright/magit-find-file.el"))])
+ (magit-gerrit . [(20210831 1453) ((emacs (25 1)) (magit (2 90 1)) (transient (0 3 0))) "Magit plugin for Gerrit Code Review" single ((:commit . "9104713f6ea918e9faaf25f2cc182c65029db936") (:authors ("Brian Fransioli" . "assem@terranpro.org")) (:maintainer "Brian Fransioli" . "assem@terranpro.org") (:url . "https://github.com/emacsorphanage/magit-gerrit"))])
+ (magit-gh-pulls . [(20191230 1944) ((emacs (24 4)) (gh (0 9 1)) (magit (2 12 0)) (pcache (0 2 3)) (s (1 6 1))) "GitHub pull requests extension for Magit" single ((:commit . "57f3a5158bbc7bfd169ee136fde351cce999e0ca") (:authors ("Yann Hodique" . "yann.hodique@gmail.com")) (:maintainer "Yann Hodique" . "yann.hodique@gmail.com") (:keywords "git" "tools") (:url . "https://github.com/sigma/magit-gh-pulls"))])
+ (magit-gitflow . [(20170929 824) ((magit (2 1 0)) (magit-popup (2 2 0))) "gitflow extension for magit" single ((:commit . "cc41b561ec6eea947fe9a176349fb4f771ed865b") (:authors ("Jan Tatarik" . "Jan.Tatarik@gmail.com")) (:maintainer "Jan Tatarik" . "Jan.Tatarik@gmail.com") (:keywords "vc" "tools") (:url . "https://github.com/jtatarik/magit-gitflow"))])
+ (magit-imerge . [(20220306 2311) ((emacs (25 1)) (magit (3 0 0))) "Magit extension for git-imerge" single ((:commit . "37bca48218dc32cad964e01e0f9936a90f634fba") (:authors ("Kyle Meyer" . "kyle@kyleam.com")) (:maintainer "Kyle Meyer" . "kyle@kyleam.com") (:keywords "vc" "tools") (:url . "https://github.com/magit/magit-imerge"))])
+ (magit-lfs . [(20220314 1957) ((emacs (24 4)) (magit (2 10 3)) (dash (2 13 0))) "Magit plugin for Git LFS" single ((:commit . "8ebe246f20f4ab5c9f191c38137833c7f01a0432") (:authors ("Junyoung/Clare Jang" . "jjc9310@gmail.com")) (:maintainer "Junyoung/Clare Jang" . "jjc9310@gmail.com") (:keywords "magit" "git" "lfs" "tools" "vc") (:url . "https://github.com/ailrun/magit-lfs"))])
+ (magit-libgit . [(20220429 1720) ((emacs (25 1)) (compat (28 1 1 0)) (libgit (0)) (magit (20211004))) "(POC) Teach Magit to use Libgit2." tar ((:commit . "476383fc8fb0f6ea4c6fc29d7057a1b5b5f95bd8") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:keywords "git" "tools" "vc") (:url . "https://github.com/magit/magit"))])
+ (magit-org-todos . [(20180709 1950) ((magit (2 0 0)) (emacs (24))) "Add local todo items to the magit status buffer" single ((:commit . "9ffa3efb098434d837cab4bacd1601fdfc6fe999") (:authors ("Daniel Ma")) (:maintainer "Daniel Ma") (:keywords "org-mode" "magit" "tools") (:url . "http://github.com/danielma/magit-org-todos"))])
+ (magit-patch-changelog . [(20220313 1229) ((emacs (25 1)) (magit (3 3 0))) "Generate a patch according to emacs-mirror/CONTRIBUTE" single ((:commit . "96936d2bd92c8bbf87f65bc293f3246014bc2764") (:keywords "git" "tools" "vc") (:url . "https://github.com/dickmao/magit-patch-changelog"))])
+ (magit-popup . [(20200719 1015) ((emacs (24 4)) (dash (2 13 0))) "Define prefix-infix-suffix command combos" tar ((:commit . "d8585fa39f88956963d877b921322530257ba9f5") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:keywords "bindings") (:url . "https://github.com/magit/magit-popup"))])
+ (magit-rbr . [(20181009 2016) ((magit (2 13 0)) (emacs (24 3))) "Support for git rbr in Magit" single ((:commit . "029203b3e48537205052a058e964f058cd802c3c") (:authors ("Anatoly Fayngelerin" . "fanatoly+magitrbr@gmail.com")) (:maintainer "Anatoly Fayngelerin" . "fanatoly+magitrbr@gmail.com") (:keywords "git" "magit" "rbr" "tools") (:url . "https://github.com/fanatoly/magit-rbr"))])
+ (magit-reviewboard . [(20200727 1748) ((emacs (25 2)) (magit (2 13 0)) (s (1 12 0)) (request (0 3 0))) "Show open Reviewboard reviews in Magit" single ((:commit . "aceedff88921f1dfef8a6b2fb18fe316fb7223a8") (:authors ("Jules Tamagnan" . "jtamagnan@gmail.com")) (:maintainer "Jules Tamagnan" . "jtamagnan@gmail.com") (:keywords "magit" "vc") (:url . "http://github.com/jtamagnan/magit-reviewboard"))])
+ (magit-section . [(20220502 2245) ((emacs (25 1)) (compat (28 1 1 0)) (dash (20210826))) "Sections for read-only buffers." tar ((:commit . "476383fc8fb0f6ea4c6fc29d7057a1b5b5f95bd8") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:keywords "tools") (:url . "https://github.com/magit/magit"))])
+ (magit-svn . [(20210426 2114) ((emacs (25 1)) (magit (2 90 1)) (transient (0 3 2))) "Git-Svn extension for Magit" single ((:commit . "350493217afdb7637564e089f475909adecd9208") (:authors ("Phil Jackson" . "phil@shellarchive.co.uk")) (:maintainer "Phil Jackson" . "phil@shellarchive.co.uk") (:keywords "vc" "tools"))])
+ (magit-tbdiff . [(20220306 2311) ((emacs (25 1)) (magit (3 0 0))) "Magit extension for range diffs" single ((:commit . "ae9345d867539a4c5c635be04df2e26468444da8") (:authors ("Kyle Meyer" . "kyle@kyleam.com")) (:maintainer "Kyle Meyer" . "kyle@kyleam.com") (:keywords "vc" "tools") (:url . "https://github.com/magit/magit-tbdiff"))])
+ (magit-todos . [(20220326 519) ((emacs (25 2)) (async (1 9 2)) (dash (2 13 0)) (f (0 17 2)) (hl-todo (1 9 0)) (magit (2 13 0)) (pcre2el (1 8)) (s (1 12 0)) (transient (0 2 0))) "Show source file TODOs in Magit" single ((:commit . "67fd80c2f10aec4d5b2a24b5d3d53c08cc1f05dc") (:authors ("Adam Porter" . "adam@alphapapa.net")) (:maintainer "Adam Porter" . "adam@alphapapa.net") (:keywords "magit" "vc") (:url . "http://github.com/alphapapa/magit-todos"))])
+ (magit-topgit . [(20160313 1954) ((emacs (24 4)) (magit (2 1 0))) "TopGit extension for Magit" single ((:commit . "11489ea798bc88d0ea5244bbf725285eedfefbef") (:authors ("Yann Hodique" . "yann.hodique@gmail.com")) (:maintainer "Robin Green" . "greenrd@greenrd.org") (:keywords "vc" "tools"))])
+ (magit-vcsh . [(20190817 2014) ((magit (2 90 1)) (vcsh (0 4)) (emacs (24 4))) "Magit vcsh integration" single ((:commit . "fcff128cdbe3ef547dc64f2496cb6405b8ee21ca") (:authors ("Štěpán Němec" . "stepnem@gmail.com")) (:maintainer "Štěpán Němec" . "stepnem@gmail.com") (:keywords "vc" "files" "magit") (:url . "https://gitlab.com/stepnem/magit-vcsh-el"))])
+ (magithub . [(20220315 117) ((emacs (25)) (magit (2 12)) (s (1 12 0)) (ghub+ (0 3)) (git-commit (2 12)) (markdown-mode (2 3))) "Magit interfaces for GitHub" tar ((:commit . "dd62c7057155c0a334e6d9087779a2923d2300b8") (:authors ("Sean Allred" . "code@seanallred.com")) (:maintainer "Sean Allred" . "code@seanallred.com") (:keywords "git" "tools" "vc") (:url . "https://github.com/vermiculus/magithub"))])
+ (magma-mode . [(20211018 917) ((emacs (24 3)) (cl-lib (0 3)) (dash (2 6 0)) (f (0 17 1))) "Mode for editing Magma source code" tar ((:commit . "dd784445bc8cddf4a3ebe0f60009bed1f722f597") (:url . "https://github.com/ThibautVerron/magma-mode"))])
+ (magnatune . [(20151030 1935) ((dash (2 9 0)) (s (1 9 0))) "browse magnatune's music catalog" tar ((:commit . "605b01505ba30589c77ebb4c96834b5072ccbdd4"))])
+ (magrant . [(20210706 1438) ((emacs (25 1)) (dash (2 17 0)) (s (1 12 0)) (tablist (0 70)) (transient (0 2 0)) (friendly-shell-command (0 2 3))) "Transient Interface to Vagrant" tar ((:commit . "6309c001355126e3ade79493479b517925943d17") (:keywords "processes" "terminals") (:url . "https://github.com/p3r7/magrant"))])
+ (majapahit-theme . [(20160817 1848) nil "Color theme with a dark and light versions" tar ((:commit . "77c96df7619666b2102d90d452eeadf04adc89a6"))])
+ (major-mode-hydra . [(20210221 834) ((dash (2 18 0)) (pretty-hydra (0 2 2)) (emacs (25))) "Major mode keybindings managed by Hydra" single ((:commit . "84c1929a5153be169ca5c36737439d51dffde505") (:authors ("Jerry Peng" . "pr2jerry@gmail.com")) (:maintainer "Jerry Peng" . "pr2jerry@gmail.com") (:url . "https://github.com/jerrypnz/major-mode-hydra.el"))])
+ (major-mode-icons . [(20220210 1404) ((emacs (24 3)) (powerline (2 4)) (all-the-icons (2 3 0))) "display icon for major-mode on mode-line." tar ((:commit . "b0214e0af13cd3691c4d28f03e3108bd98ec7a85") (:keywords "frames" "multimedia") (:url . "https://repo.or.cz/major-mode-icons.git"))])
+ (make-color . [(20140625 1150) nil "Alternative to picking color - update fg/bg color by pressing r/g/b/... keys" single ((:commit . "5ca1383ca9228bca82120b238bdc119f302b75c0") (:authors ("Alex Kost" . "alezost@gmail.com")) (:maintainer "Alex Kost" . "alezost@gmail.com") (:keywords "color") (:url . "https://github.com/alezost/make-color.el"))])
+ (make-it-so . [(20190625 1036) ((swiper (0 8 0)) (emacs (24))) "Transform files with Makefile recipes." tar ((:commit . "b73dfb640588123c9eece230ad72b37604f5c126") (:authors ("Oleh Krehel" . "ohwoeowho@gmail.com")) (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com") (:keywords "make" "dired") (:url . "https://github.com/abo-abo/make-it-so"))])
+ (makefile-executor . [(20201119 1500) ((emacs (24 3)) (dash (2 11 0)) (f (0 11 0)) (s (1 10 0))) "Commands for conveniently running makefile targets" single ((:commit . "d0a34c355fb80a8616ae7ed5eebbda8507aa14ac") (:authors ("Lowe Thiderman" . "lowe.thiderman@gmail.com")) (:maintainer "Lowe Thiderman" . "lowe.thiderman@gmail.com") (:keywords "processes") (:url . "https://github.com/thiderman/makefile-executor.el"))])
+ (makey . [(20131231 1430) ((cl-lib (0 2))) "interactive commandline mode" single ((:commit . "c0b6bd5956744dd64052e54574e35d39f7c9d75b") (:authors ("Mickey Petersen" . "mickey@masteringemacs.org")) (:maintainer "Mickey Petersen" . "mickey@masteringemacs.org"))])
+ (malinka . [(20171202 1021) ((s (1 9 0)) (dash (2 4 0)) (f (0 11 0)) (cl-lib (0 3)) (rtags (0 0)) (projectile (0 11 0))) "A C/C++ project configuration package for Emacs" single ((:commit . "d4aa517c7a9022eae16c758c7efdb3a0403542d7") (:authors ("Lefteris Karapetsas" . "lefteris@refu.co")) (:maintainer "Lefteris Karapetsas" . "lefteris@refu.co") (:keywords "c" "c++" "project-management") (:url . "https://github.com/LefterisJP/malinka"))])
+ (mallard-mode . [(20131204 425) nil "Major mode for editing Mallard files" tar ((:commit . "c48170c1ace4959abcc5fb1df0d4cb149cff44c1") (:authors ("Jaromir Hradilek" . "jhradilek@gmail.com")) (:maintainer "Jaromir Hradilek" . "jhradilek@gmail.com") (:keywords "xml" "mallard") (:url . "https://github.com/jhradilek/emacs-mallard-mode"))])
+ (mallard-snippets . [(20131023 1851) ((yasnippet (0 8 0)) (mallard-mode (0 1 1))) "Yasnippets for Mallard" tar ((:commit . "70c5293f10722f2ace73bdf74d9a18f95b040edc") (:authors ("Jaromir Hradilek" . "jhradilek@gmail.com")) (:maintainer "Jaromir Hradilek" . "jhradilek@gmail.com") (:keywords "snippets" "mallard") (:url . "https://github.com/jhradilek/emacs-mallard-snippets"))])
+ (malyon . [(20161208 2125) ((cl-lib (0 5))) "mode to execute Z-code files version 3, 5, 8" single ((:commit . "0d9882650720b4a791556f5e2d917388965d6fc0") (:authors ("Peter Ilberg <peter.ilberg@gmail.com>, Christopher Madsen <cjm@cjmweb.net>, Erik Selberg" . "erik@selberg.org")) (:maintainer "Christopher Madsen <cjm@cjmweb.net>, Erik Selberg" . "erik@selberg.org") (:keywords "games" "emulations") (:url . "https://github.com/speedenator/malyon"))])
+ (man-commands . [(20151221 2221) ((cl-lib (0 5))) "Add interactive commands for every manpages installed in your computer." single ((:commit . "f4ba0c3790855d7544dff92d470d212f24de1d9d") (:authors ("Nathaniel Flath" . "nflath@gmail.com")) (:maintainer "Nathaniel Flath" . "nflath@gmail.com") (:url . "http://github.com/nflath/man-commands"))])
+ (manage-minor-mode . [(20210108 1832) ((emacs (24 3))) "Manage your minor-modes easily" single ((:commit . "e1af20253fbc5a91034ccd01cf00141130c11863") (:authors ("Shingo Fukuyama - http://fukuyama.co")) (:maintainer "Jen-Chieh Shen" . "jcs090218@gmail.com") (:keywords "tools" "minor-mode" "manage" "emacs") (:url . "https://github.com/ShingoFukuyama/manage-minor-mode"))])
+ (manage-minor-mode-table . [(20200717 809) ((emacs (25 1)) (manage-minor-mode (1 1))) "Manage minor-modes in table" single ((:commit . "e4c38aeb8ef6a85d8c082ad683720e5a4174aa79") (:authors ("Shen, Jen-Chieh" . "jcs090218@gmail.com")) (:maintainer "Shen, Jen-Chieh" . "jcs090218@gmail.com") (:url . "https://github.com/jcs-elpa/manage-minor-mode-table"))])
+ (mandm-theme . [(20220426 1131) nil "An M&M color theme." single ((:commit . "4991bbc4b17308f5dc53742dc528cbfdc467ee01") (:authors ("Christian Hopps" . "chopps@gmail.com")) (:maintainer "Christian Hopps" . "chopps@gmail.com") (:url . "https://github.com/choppsv1/emacs-mandm-theme.git"))])
+ (mandoku . [(20180403 1106) ((org (8)) (github-clone (20150705 1705))) "A tool to access repositories of premodern Chinese texts" tar ((:commit . "d65dbaa329ecf931f4142be72862972ea6a24e63") (:authors ("Christian Wittern" . "cwittern@gmail.com")) (:maintainer "Christian Wittern" . "cwittern@gmail.com") (:keywords "convenience") (:url . "http://www.mandoku.org"))])
+ (mandoku-tls . [(20171118 240) ((emacs (24 4)) (mandoku (20170301)) (github-clone (0 2)) (hydra (0 13 6)) (helm (1 7 0)) (org (9 0)) (helm-charinfo (20170601))) "A tool to access the TLS database" single ((:commit . "ffeebf5bd451ac1806ddfe1744fbbd036a56f902") (:authors ("Christian Wittern" . "cwittern@gmail.com")) (:maintainer "Christian Wittern" . "cwittern@gmail.com") (:keywords "convenience") (:url . "https://github.com/mandoku/mandoku-tls"))])
+ (map-progress . [(20190128 16) ((cl-lib (0 6 1))) "mapping macros that report progress" single ((:commit . "1fb916159cd054c233ce3c80d9d01adfae640297") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:keywords "convenience") (:url . "https://github.com/tarsius/map-progress"))])
+ (map-regexp . [(20190128 18) ((cl-lib (0 6 1))) "map over matches of a regular expression" single ((:commit . "ae2d1c22f786ad987aef3e319925e80160a887a0") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:keywords "convenience") (:url . "https://github.com/tarsius/map-regexp"))])
+ (marcopolo . [(20160421 1004) ((s (1 9 0)) (dash (2 9 0)) (pkg-info (0 5 0)) (request (0 1 0))) "Emacs client to the Docker HUB/Registry API" tar ((:commit . "9193aabdf12223087b5ed58f1507d5d8a24a4381") (:authors ("Nicolas Lamirault" . "nicolas.lamirault@gmail.com")) (:maintainer "Nicolas Lamirault" . "nicolas.lamirault@gmail.com") (:keywords "docker") (:url . "https://github.com/nlamirault/marcopolo"))])
+ (marginalia . [(20220426 449) ((emacs (27 1))) "Enrich existing commands with completion annotations" single ((:commit . "26f2bd9ee7b63bcad6604108e2f565b34bc6083b") (:authors ("Omar Antolín Camarena <omar@matem.unam.mx>, Daniel Mendler" . "mail@daniel-mendler.de")) (:maintainer "Omar Antolín Camarena <omar@matem.unam.mx>, Daniel Mendler" . "mail@daniel-mendler.de") (:url . "https://github.com/minad/marginalia"))])
+ (mark-multiple . [(20121118 1554) nil "Sorta lets you mark several regions at once." tar ((:commit . "f6a53c7c5283d640ae718f4548b0fda78877a375") (:authors ("Magnar Sveen" . "magnars@gmail.com")) (:maintainer "Magnar Sveen" . "magnars@gmail.com") (:keywords "marking" "library"))])
+ (mark-thing-at . [(20201219 231) ((emacs (26)) (choice-program (0 13))) "Mark a pattern at the current point" single ((:commit . "a622d128afc8d2d67de897666a1e2eccba8d7818") (:authors ("Paul Landes")) (:maintainer "Paul Landes") (:keywords "mark" "point" "lisp") (:url . "https://github.com/plandes/mark-thing-at"))])
+ (mark-tools . [(20130614 1025) nil "Some simple tools to access the mark-ring in Emacs" single ((:commit . "a11b61effa90bd0abc876d12573674d36fc17f0c") (:authors ("Alex Bennée" . "alex@bennee.com")) (:maintainer "Alex Bennée" . "alex@bennee.com") (:url . "https://github.com/stsquad/emacs-mark-tools"))])
+ (markdown-changelog . [(20200120 2253) ((emacs (26)) (dash (2 13 0))) "Maintain changelog entries" single ((:commit . "1a2c3a4c3e4196f2b5dbb145b01b4bc435a93a96") (:authors ("Paul Landes")) (:maintainer "Paul Landes") (:keywords "markdown" "changelog" "files") (:url . "https://github.com/plandes/markdown-changelog"))])
+ (markdown-mode . [(20220406 410) ((emacs (26 1))) "Major mode for Markdown-formatted text" single ((:commit . "d2a3d5b8625a7c6be21f19f9146745cd5c791a6a") (:authors ("Jason R. Blevins" . "jblevins@xbeta.org")) (:maintainer "Jason R. Blevins" . "jblevins@xbeta.org") (:keywords "markdown" "github flavored markdown" "itex") (:url . "https://jblevins.org/projects/markdown-mode/"))])
+ (markdown-preview-eww . [(20160111 1502) ((emacs (24 4))) "Realtime preview by eww" single ((:commit . "5853f836425c877c8a956501f0adda137ef1d3b7") (:authors ("niku" . "niku@niku.name")) (:maintainer "niku" . "niku@niku.name") (:url . "https://github.com/niku/markdown-preview-eww"))])
+ (markdown-preview-mode . [(20210516 936) ((emacs (24 4)) (websocket (1 6)) (markdown-mode (2 0)) (cl-lib (0 5)) (web-server (0 1 1))) "markdown realtime preview minor mode." tar ((:commit . "dde87b96de9e81dd01d174da67ef68687b3a5eb5") (:authors ("Igor Shymko" . "igor.shimko@gmail.com")) (:maintainer "Igor Shymko" . "igor.shimko@gmail.com") (:keywords "markdown" "gfm" "convenience") (:url . "https://github.com/ancane/markdown-preview-mode"))])
+ (markdown-toc . [(20210905 738) ((s (1 9 0)) (dash (2 11 0)) (markdown-mode (2 1))) "A simple TOC generator for markdown file" tar ((:commit . "3d724e518a897343b5ede0b976d6fb46c46bcc01") (:authors (nil . "Antoine R. Dumont (@ardumont)")) (:maintainer nil . "Antoine R. Dumont (@ardumont)") (:keywords "markdown" "toc" "tools") (:url . "http://github.com/ardumont/markdown-toc"))])
+ (markdownfmt . [(20160609 1241) ((emacs (24))) "Format markdown using markdownfmt" single ((:commit . "187a74eb4fd9e8520ce08da42d1d292b9af7f2b7") (:authors ("Nicolas Lamirault" . "nicolas.lamirault@gmail.com")) (:maintainer "Nicolas Lamirault" . "nicolas.lamirault@gmail.com") (:keywords "markdown") (:url . "https://github.com/nlamirault/emacs-markdownfmt"))])
+ (markless . [(20190306 1002) ((emacs (24 4))) "Major mode for Markless documents" single ((:commit . "75fdef45df96978e9326ea4d9bf4e534a250c4c0") (:authors ("Nicolas Hafner" . "shinmera@tymoon.eu")) (:maintainer "Nicolas Hafner" . "shinmera@tymoon.eu") (:keywords "languages" "wp") (:url . "http://github.com/shirakumo/markless.el/"))])
+ (markup . [(20170420 1129) ((cl-lib (0 5))) "Simple markup generation helpers." single ((:commit . "876da2d3f23473475bb0fd0a1480ae11d2671291") (:authors ("Arthur Leonard Andersen" . "leoc.git@gmail.com")) (:maintainer "Arthur Leonard Andersen" . "leoc.git@gmail.com") (:keywords "convenience" "markup" "html") (:url . "http://github.com/leoc/markup.el"))])
+ (markup-faces . [(20141110 817) nil "collection of faces for markup language modes" single ((:commit . "98a807ed82473eb41c6a201ed7ef816d6bcd67b0") (:authors ("Florian Kaufmann" . "sensorflo@gmail.com")) (:maintainer "Florian Kaufmann" . "sensorflo@gmail.com") (:keywords "wp" "faces") (:url . "https://github.com/sensorflo/markup-faces"))])
+ (marmalade-client . [(20141231 2007) ((web (0 5 2)) (kv (0 0 19)) (gh (0 8 0))) "client for marmalade API from emacs" tar ((:commit . "f315dea57e4fbebd9ee0668c0bafd4c45c7b754a") (:authors ("Nic Ferrier" . "nferrier@ferrier.me.uk")) (:maintainer "Nic Ferrier" . "nferrier@ferrier.me.uk") (:keywords "lisp") (:url . "https://github.com/nicferrier/emacs-marmalade-upload"))])
+ (marquee-header . [(20200720 1034) ((emacs (25 1))) "Code interface for displaying marquee in header" single ((:commit . "c36dcf8c282f547da5b3666f025a3000b5dbd1d9") (:authors ("Shen, Jen-Chieh" . "jcs090218@gmail.com")) (:maintainer "Shen, Jen-Chieh" . "jcs090218@gmail.com") (:url . "https://github.com/jcs-elpa/marquee-header"))])
+ (marshal . [(20201223 1853) ((emacs (25 1)) (ht (2 0))) "eieio extension for automatic (un)marshalling" single ((:commit . "490496d974d03906f784707ecc2e0ac36ed84b96") (:authors ("Yann Hodique" . "yann.hodique@gmail.com")) (:maintainer "Yann Hodique" . "yann.hodique@gmail.com") (:keywords "extensions") (:url . "https://github.com/sigma/marshal.el"))])
+ (maruo-macro-mode . [(20160616 1349) ((emacs (24 3))) "Major mode for editing Hidemaru/Maruo macro script" single ((:commit . "8fc9a38ad051eafa8eb94038711acc52c5d1d8d5") (:authors ("USAMI Kenta" . "tadsan@zonu.me")) (:maintainer "USAMI Kenta" . "tadsan@zonu.me") (:keywords "programming" "editor" "macro"))])
+ (masm-mode . [(20200308 1450) ((emacs (25 1))) "MASM x86 and x64 assembly major mode" single ((:commit . "626b9255c2bb967a53d1d50be0b98a1bcae3250c") (:authors ("YiGeeker" . "zyfchinese@yeah.net")) (:maintainer "YiGeeker" . "zyfchinese@yeah.net") (:keywords "languages") (:url . "https://github.com/YiGeeker/masm-mode"))])
+ (mastodon . [(20220405 1531) ((emacs (27 1)) (request (0 3 2)) (seq (1 0))) "Client for Mastodon" tar ((:commit . "b3649a12a398537ade7136d704f2f05ccc856e23") (:authors ("Johnson Denen" . "johnson.denen@gmail.com")) (:maintainer "Marty Hiatt" . "martianhiatus@riseup.net") (:url . "https://codeberg.org/martianh/mastodon.el"))])
+ (material-theme . [(20210904 1226) ((emacs (24 1))) "A Theme based on the colors of the Google Material Design" tar ((:commit . "6823009bc92f82aa3a90e27e1009f7da8e87b648") (:authors ("Christoph Paulik" . "cpaulik@gmail.com")) (:maintainer "Christoph Paulik" . "cpaulik@gmail.com") (:keywords "themes") (:url . "http://github.com/cpaulik/emacs-material-theme"))])
+ (math-preview . [(20211221 1611) ((emacs (26 1)) (dash (2 18 0)) (s (1 12 0))) "Preview TeX math equations inline" single ((:commit . "75dd44ad8dcfa12fe03f8e65babe0ea04e1a7d1a") (:authors ("Matsievskiy S.V.")) (:maintainer "Matsievskiy S.V.") (:keywords "convenience") (:url . "https://gitlab.com/matsievskiysv/math-preview"))])
+ (math-symbol-lists . [(20200131 2338) nil "Lists of Unicode math symbols and latex commands" tar ((:commit . "590d9f09f8ad9aab747b97f077396a2035dcf50f") (:authors ("Vitalie Spinu" . "spinuvit@gmail.com")) (:maintainer "Vitalie Spinu" . "spinuvit@gmail.com") (:keywords "unicode" "symbols" "mathematics") (:url . "https://github.com/vspinu/math-symbol-lists"))])
+ (math-symbols . [(20201005 2313) nil "Math Symbol Input methods and conversion tools" tar ((:commit . "091b81cb40ceaff97614999ffe85b572ace182f0") (:authors ("KAWABATA, Taichi <kawabata.taichi_at_gmail.com>")) (:maintainer "KAWABATA, Taichi <kawabata.taichi_at_gmail.com>") (:keywords "i18n" "languages" "tex") (:url . "https://github.com/kawabata/math-symbols"))])
+ (matlab-mode . [(20220412 913) nil "Major mode for MATLAB(R) dot-m files" tar ((:commit . "5069e3ca0034e0da64eb9b3cd426f52992938d06"))])
+ (maude-mode . [(20220419 1454) ((emacs (25))) "Emacs mode for the programming language Maude" single ((:commit . "68de3c11ae16c409afa74516aaf465996d1a9e59") (:authors ("Ellef Gjelstad <ellefg+maude*ifi.uio.no>")) (:maintainer "Rudi Schlatte" . "rudi@constantly.at") (:keywords "languages" "maude") (:url . "https://github.com/rudi/abs-mode"))])
+ (maven-test-mode . [(20141220 557) ((s (1 9)) (emacs (24))) "Utilities for navigating test files and running maven test tasks." single ((:commit . "a19151861df2ad8ae4880a2e7c86ddf848cb569a") (:authors ("Renan Ranelli")) (:maintainer "Renan Ranelli") (:keywords "java" "maven" "test") (:url . "http://github.com/rranelli/maven-test-mode"))])
+ (maxframe . [(20170120 1705) nil "maximize the emacs frame based on display size" single ((:commit . "f7048ce95443f2c06cb6b140814451e3a037103a") (:authors ("Ryan McGeary")) (:maintainer "Ryan McGeary") (:keywords "display" "frame" "window" "maximize"))])
+ (maxima . [(20210526 1525) ((emacs (25 1)) (s (1 11 0)) (test-simple (1 3 0))) "Major mode for Maxima" tar ((:commit . "ce5fd160c193e387d9e2bacdba4065c4b4262cb1") (:authors ("William F. Schelter") ("Jay Belanger") ("Fermin Munoz")) (:maintainer "Fermin Munoz" . "fmfs@posteo.net") (:keywords "maxima" "tools" "math") (:url . "https://gitlab.com/sasanidas/maxima"))])
+ (mb-url . [(20211205 1100) ((emacs (25))) "Multiple Backends for Emacs URL package" tar ((:commit . "09f32af1a58d0b042b699c76d2b30e9226508f5e") (:authors ("ZHANG Weiyi" . "dochang@gmail.com")) (:maintainer "ZHANG Weiyi" . "dochang@gmail.com") (:keywords "comm" "data" "processes" "hypermedia") (:url . "https://github.com/dochang/mb-url"))])
+ (mbe . [(20151126 1134) ((emacs (24)) (cl-lib (0 5))) "Macros by Example" single ((:commit . "bb10aa8f26bb7e9b1d5746934c94edb00402940c") (:authors ("Ian Price" . "ianprice90@googlemail.com")) (:maintainer "Ian Price" . "ianprice90@googlemail.com") (:keywords "tools" "macros") (:url . "https://github.com/ijp/mbe.el"))])
+ (mbo70s-theme . [(20170808 1315) ((emacs (24 0))) "70s style palette, with similarities to mbo theme" single ((:commit . "bed3db8965708ed4e9482b224a9b084765c052f2") (:authors ("Jason Milkins")) (:maintainer "Jason Milkins") (:url . "https://github.com/emacsfodder/tmtheme-to-deftheme"))])
+ (mbsync . [(20200128 1053) nil "run mbsync to fetch mails" single ((:commit . "d3c81da81ce5b154c0d048047a47277338721a70") (:authors ("Dimitri Fontaine" . "dim@tapoueh.org")) (:maintainer "Dimitri Fontaine" . "dim@tapoueh.org") (:url . "https://github.com/dimitri/mbsync-el"))])
+ (mc-calc . [(20200420 1836) ((emacs (24 4)) (multiple-cursors (1 2 1))) "Combine multiple-cursors and calc" single ((:commit . "74a046a5728919a4d1135ca62738326b0dde278c") (:authors (nil . "Frank Roland hatheroldev@fgmail.com>")) (:maintainer nil . "Frank Roland hatheroldev@fgmail.com>") (:keywords "convenience") (:url . "https://github.com/hatheroldev/mc-calc"))])
+ (mc-extras . [(20181109 1735) ((multiple-cursors (1 2 1))) "Extra functions for multiple-cursors mode." tar ((:commit . "053abc52181b8718559d7361a587bbb795faf164") (:authors ("Akinori MUSHA" . "knu@iDaemons.org")) (:maintainer "Akinori MUSHA" . "knu@iDaemons.org") (:keywords "editing" "cursors") (:url . "https://github.com/knu/mc-extras.el"))])
+ (md-readme . [(20191112 1943) nil "Markdown-formatted READMEs for your ELisp" tar ((:commit . "ca99f44de11fab18d1f50d4b1722f2ceee3c814d") (:authors ("Thomas Kappler" . "tkappler@gmail.com")) (:maintainer "Thomas Kappler" . "tkappler@gmail.com") (:keywords "lisp" "help" "readme" "markdown" "header" "documentation" "github") (:url . "http://github.com/thomas11/md-readme/tree/master"))])
+ (md4rd . [(20220105 1558) ((emacs (25 1)) (hierarchy (0 7 0)) (request (0 3 0)) (cl-lib (0 6 1)) (dash (2 12 0)) (s (1 12 0)) (tree-mode (1 0 0))) "Mode for reddit (browse it)." single ((:commit . "6aa4fd6339d7fac78ce57e5d8821cd7009d21172") (:authors ("Matthew Carter" . "m@ahungry.com")) (:maintainer "Matthew Carter" . "m@ahungry.com") (:keywords "ahungry" "reddit" "browse" "news") (:url . "https://github.com/ahungry/md4rd"))])
+ (mediawiki . [(20200718 1529) nil "mediawiki frontend" single ((:commit . "932497604fd417964e4f04614e28d96f4eee028e") (:authors ("Mark A. Hershberger" . "mah@everybody.org")) (:maintainer "Mark A. Hershberger" . "mah@everybody.org") (:keywords "mediawiki" "wikipedia" "network" "wiki") (:url . "https://github.com/hexmode/mediawiki-el"))])
+ (meghanada . [(20220101 501) ((emacs (24 3)) (yasnippet (0 6 1)) (company (0 9 0)) (flycheck (0 23))) "A better java development mode" tar ((:commit . "59c46cabb7eee715fe810ce59424934a1286df84") (:authors ("Yutaka Matsubara" . "yutaka.matsubara@gmail.com")) (:maintainer "Yutaka Matsubara" . "yutaka.matsubara@gmail.com") (:keywords "languages" "java") (:url . "https://github.com/mopemope/meghanada-emacs"))])
+ (mellow-theme . [(20170808 1317) ((emacs (24 0))) "an Emacs 24 theme based on Mellow (tmTheme)" single ((:commit . "2bdf18f05f5212b6f269d9a94afe2cf201766891") (:authors ("Jason Milkins")) (:maintainer "Jason Milkins") (:url . "https://github.com/emacsfodder/tmtheme-to-deftheme"))])
+ (melpa-upstream-visit . [(20130720 1033) ((s (1 6 0))) "A set of kludges to visit a melpa-hosted package's homepage" single ((:commit . "7310c74fdead3c0f86ad6eff76cf989e63f70f66") (:authors ("Alessandro Piras" . "laynor@gmail.com")) (:maintainer "Alessandro Piras" . "laynor@gmail.com") (:keywords "convenience"))])
+ (memento-mori . [(20190628 2147) ((emacs (24)) (cl-lib (0 5))) "Reminder of mortality" single ((:commit . "b99c5ff526079fc5a1e1be097534855da176bc2b") (:authors ("Lassi Kortela" . "lassi@lassi.io")) (:maintainer "Lassi Kortela" . "lassi@lassi.io") (:keywords "help") (:url . "https://github.com/lassik/emacs-memento-mori"))])
+ (memoize . [(20200103 2036) nil "Memoization functions" single ((:commit . "51b075935ca7070f62fae1d69fe0ff7d8fa56fdd") (:authors ("Christopher Wellons" . "mosquitopsu@gmail.com")) (:maintainer "Christopher Wellons" . "mosquitopsu@gmail.com") (:url . "https://github.com/skeeto/emacs-memoize"))])
+ (memolist . [(20150804 1721) ((markdown-mode (22 0)) (ag (0 45))) "memolist.el is Emacs port of memolist.vim." single ((:commit . "c437a32d3955f859d9bbcbadf0911bbe27d877ff") (:authors ("mikanfactory <k952i4j14x17_at_gmail.com>")) (:maintainer "mikanfactory") (:keywords "markdown" "memo") (:url . "http://github.com/mikanfactory/emacs-memolist"))])
+ (mentor . [(20220113 2136) ((emacs (25 1)) (xml-rpc (1 6 15)) (seq (1 11)) (async (1 9 3))) "Frontend for the rTorrent bittorrent client" tar ((:commit . "afab3a14a4bfb5117f8e25417fdf151611b3df0b") (:authors ("Stefan Kangas" . "stefankangas@gmail.com")) (:maintainer "Stefan Kangas" . "stefankangas@gmail.com") (:keywords "comm" "processes" "bittorrent") (:url . "https://github.com/skangas/mentor"))])
+ (meow . [(20220501 1918) ((emacs (27 1))) "Yet Another modal editing" tar ((:commit . "72d6ff36b62a57aa9c9dbfbd44cdb3002a0e940a") (:authors ("Shi Tianshu")) (:maintainer "Shi Tianshu") (:keywords "convenience" "modal-editing") (:url . "https://www.github.com/DogLooksGood/meow"))])
+ (merlin . [(20220502 811) ((emacs (25 1))) "Mode for Merlin, an assistant for OCaml" tar ((:commit . "49324b4fdc14987164ed7a3a8c3681df5b4866ee") (:authors ("Frédéric Bour <frederic.bour(_)lakaban.net>")) (:maintainer "Frédéric Bour <frederic.bour(_)lakaban.net>") (:keywords "ocaml" "languages") (:url . "https://github.com/ocaml/merlin"))])
+ (merlin-ac . [(20210615 1208) ((emacs (25 1)) (merlin (3)) (auto-complete (1 5))) "Merlin and auto-complete integration." single ((:commit . "49324b4fdc14987164ed7a3a8c3681df5b4866ee") (:authors ("Simon Castellan <simon.castellan(_)iuwt.fr>") ("Frédéric Bour <frederic.bour(_)lakaban.net>") ("Thomas Refis <thomas.refis(_)gmail.com>")) (:maintainer "Simon Castellan <simon.castellan(_)iuwt.fr>") (:keywords "ocaml" "languages") (:url . "http://github.com/ocaml/merlin"))])
+ (merlin-company . [(20210615 1208) ((emacs (25 1)) (merlin (3)) (company (0 9))) "Merlin and company mode integration." single ((:commit . "49324b4fdc14987164ed7a3a8c3681df5b4866ee") (:authors ("Simon Castellan <simon.castellan(_)iuwt.fr>") ("Frédéric Bour <frederic.bour(_)lakaban.net>") ("Thomas Refis <thomas.refis(_)gmail.com>")) (:maintainer "Simon Castellan <simon.castellan(_)iuwt.fr>") (:keywords "ocaml" "languages") (:url . "http://github.com/ocaml/merlin"))])
+ (merlin-eldoc . [(20190830 517) ((emacs (24 4)) (merlin (3 0))) "eldoc for OCaml and Reason" single ((:commit . "db7fab1eddfe34781b7e79694f8923b285698032") (:authors ("Louis Roché" . "louis@louisroche.net")) (:maintainer "Louis Roché" . "louis@louisroche.net") (:keywords "merlin" "ocaml" "languages" "eldoc") (:url . "https://github.com/khady/merlin-eldoc"))])
+ (merlin-iedit . [(20220330 1736) ((emacs (25 1)) (merlin (3)) (iedit (0 9))) "Merlin and iedit integration." single ((:commit . "49324b4fdc14987164ed7a3a8c3681df5b4866ee") (:authors ("Simon Castellan <simon.castellan(_)iuwt.fr>") ("Frédéric Bour <frederic.bour(_)lakaban.net>") ("Thomas Refis <thomas.refis(_)gmail.com>")) (:maintainer "Simon Castellan <simon.castellan(_)iuwt.fr>") (:keywords "ocaml" "languages") (:url . "http://github.com/ocaml/merlin"))])
+ (mermaid-mode . [(20220426 1631) ((f (0 20 0)) (emacs (25 3))) "major mode for working with mermaid graphs" single ((:commit . "1a6526bc68561b7da6a612152b842a41ffb0aa09") (:authors ("Adrien Brochard")) (:maintainer "Adrien Brochard") (:keywords "mermaid" "graphs" "tools" "processes") (:url . "https://github.com/abrochard/mermaid-mode"))])
+ (meson-mode . [(20210820 905) ((emacs (26 1))) "Major mode for the Meson build system files" tar ((:commit . "1a2e2abb098c9288c2cdb3affbad76edd98abf59") (:authors ("Michal Sojka" . "sojkam1@fel.cvut.cz")) (:maintainer "Michal Sojka" . "sojkam1@fel.cvut.cz") (:keywords "languages" "tools") (:url . "https://github.com/wentasah/meson-mode"))])
+ (message-attachment-reminder . [(20200428 124) ((emacs (24 1))) "Remind if missing attachment" single ((:commit . "ce506b27b15cc39a47c58ff795026eaea8632e2f") (:authors ("Alex Murray" . "murray.alex@gmail.com")) (:maintainer "Alex Murray" . "murray.alex@gmail.com") (:url . "https://github.com/alexmurray/message-attachment-reminder"))])
+ (message-view-patch . [(20210904 2227) ((emacs (24 4)) (magit (3 0 0))) "Colorize patch-like emails in mu4e" single ((:commit . "40bc2e554fc1d0b6f0c403192c0a3ceaa019a78d") (:authors ("Sean Farley")) (:maintainer "Sean Farley") (:keywords "extensions" "mu4e" "gnus") (:url . "https://github.com/seanfarley/message-view-patch"))])
+ (messages-are-flowing . [(20191029 954) nil "visible indication when composing \"flowed\" emails" single ((:commit . "d582a564a63b7b90764ffc5c618bc5300225d0ab") (:authors ("Magnus Henoch" . "magnus.henoch@gmail.com")) (:maintainer "Magnus Henoch" . "magnus.henoch@gmail.com") (:keywords "mail"))])
+ (meta-presenter . [(20210714 1658) nil "A simple multi-file presentation tool for Emacs" single ((:commit . "4ab48dacea245b223a0ffd2723ece746bd61c0af") (:authors ("Mohammed Ismail Ansari" . "team.terminal@gmail.com")) (:maintainer "Mohammed Ismail Ansari" . "team.terminal@gmail.com") (:keywords "productivity" "presentation") (:url . "http://ismail.teamfluxion.com"))])
+ (metal-archives . [(20210223 1638) ((emacs (26 3)) (alert (1 2)) (ht (2 3)) (request (0 2 2))) "List future releases using Metal-Archives API" single ((:commit . "a218d63b990365edeef6a2394f72d1f2286aeeae") (:authors ("Sébastien Le Maguer" . "lemagues@tcd.ie")) (:maintainer "Sébastien Le Maguer" . "lemagues@tcd.ie") (:keywords "lisp" "calendar") (:url . "https://github.com/seblemaguer/metal-archives.el"))])
+ (metal-archives-shopping-list . [(20201229 949) ((emacs (26 3)) (org-ml (5 5 2)) (alert (1 2)) (ht (2 3)) (metal-archives (0 1))) "Add shopping list generation support to metal-archives" single ((:commit . "a218d63b990365edeef6a2394f72d1f2286aeeae") (:authors ("Sébastien Le Maguer" . "lemagues@tcd.ie")) (:maintainer "Sébastien Le Maguer" . "lemagues@tcd.ie") (:keywords "org" "calendar") (:url . "https://github.com/seblemaguer/metal-archives.el"))])
+ (metalheart-theme . [(20160710 641) ((emacs (24))) "Low-contrast theme with a dark blue-green background." single ((:commit . "ec98ea2c11dc1213dae8cbe1fe0cee73ca138bb2") (:authors ("Martin Haesler")) (:maintainer "Martin Haesler"))])
+ (metamorph . [(20220328 129) ((emacs (26 1))) "Transform your buffers with lisp" single ((:commit . "3633e32a9601c491df32d6c2212dbe63dc6484f4") (:authors ("Adam Niederer" . "adam.niederer@gmail.com")) (:maintainer "Adam Niederer" . "adam.niederer@gmail.com") (:keywords "metaprogramming" "wp") (:url . "http://github.com/AdamNiederer/metamorph"))])
+ (metascript-mode . [(20150709 57) ((emacs (24 3))) "Major mode for the Metascript programming language" single ((:commit . "edb361c7b0e5de231e5334a17b90652fb1df78f9") (:keywords "languages" "metascript" "mjs") (:url . "http://github.com/metascript/metascript-mode"))])
+ (metaweblog . [(20210422 326) ((emacs (26 3))) "An XML-RPC MetaWeblog and WordPress API client." single ((:commit . "68695ed0e012379556d57f9564ac5ad8cd68fbb8") (:authors ("Puneeth Chaganti" . "punchagan+org2blog@gmail.com")) (:maintainer "Grant Rettke" . "grant@wisdomandwonder.com") (:keywords "comm") (:url . "https://github.com/org2blog/org2blog"))])
+ (metrics-tracker . [(20211026 1347) ((emacs (24 4)) (seq (2 3))) "Generate reports of personal metrics from diary entries" single ((:commit . "115f6de4a01b9e10936b7e6d1fdadd3770bae391") (:authors ("Ian Martins" . "ianxm@jhu.edu")) (:maintainer "Ian Martins" . "ianxm@jhu.edu") (:keywords "calendar") (:url . "https://github.com/ianxm/emacs-tracker"))])
+ (metronome . [(20220210 147) ((emacs (25 1))) "A simple metronome" tar ((:commit . "1e1bd5234f3ecfb608041d423be7412c461ad3c2") (:authors ("Jonathan Gregory <jgrg at autistici dot org>")) (:maintainer "Jonathan Gregory <jgrg at autistici dot org>") (:url . "https://gitlab.com/jagrg/metronome"))])
+ (mew . [(20210625 240) nil "Messaging in the Emacs World" tar ((:commit . "fc4bca6d95d8b8d5e169ecf1433d968c2eec299d") (:authors ("Kazu Yamamoto" . "Kazu@Mew.org")) (:maintainer "Kazu Yamamoto" . "Kazu@Mew.org"))])
+ (mexican-holidays . [(20210604 1421) nil "Mexico holidays for Emacs calendar." single ((:commit . "8e28907ea69f2c0ed9aad9f3b99664ca147379d0") (:authors ("Saúl Gutiérrez" . "me@sggc.me")) (:maintainer "Saúl Gutiérrez" . "me@sggc.me") (:keywords "calendar") (:url . "https://github.com/sggutier/mexican-holidays"))])
+ (meyvn . [(20211025 106) ((emacs (25 1)) (cider (0 23)) (projectile (2 1)) (s (1 12)) (dash (2 17)) (parseedn (0 1 0)) (geiser (0 12))) "Meyvn client" single ((:commit . "80ece19a6ce6fd3dac374911edb9734286978450") (:authors ("Daniel Szmulewicz" . "daniel.szmulewicz@gmail.com")) (:maintainer "Daniel Szmulewicz" . "daniel.szmulewicz@gmail.com") (:url . "https://github.com/danielsz/meyvn-el"))])
+ (mgmtconfig-mode . [(20210131 2152) ((emacs (24 3))) "mgmt configuration management language" single ((:commit . "b26f842de19a31c36fb5149f292b9117dbf4bed7") (:authors ("Peter Oliver" . "mgmtconfig@mavit.org.uk")) (:maintainer "Mgmt contributors <https://github.com/purpleidea/mgmt>") (:keywords "languages") (:url . "https://github.com/purpleidea/mgmt/misc/emacs"))])
+ (mhc . [(20201227 406) ((calfw (20150703))) "Message Harmonized Calendaring system." tar ((:commit . "67f9596dcd43b7ece3ab6e7a6ce8dc18a4851fe8") (:authors ("Yoshinari Nomura" . "nom@quickhack.net")) (:maintainer "Yoshinari Nomura" . "nom@quickhack.net") (:keywords "calendar") (:url . "http://www.quickhack.net/mhc"))])
+ (mic-paren . [(20170731 1907) nil "advanced highlighting of matching parentheses" single ((:commit . "d0410c7d805c9aaf51a1bcefaaef092bed5824c4") (:authors ("Mikael Sjödin" . "mic@docs.uu.se") ("Klaus Berndl " . "berndl@sdm.de") ("Jonathan Kotta" . "jpkotta@gmail.com")) (:maintainer "ttn") (:keywords "languages" "faces" "parenthesis" "matching"))])
+ (micgoline . [(20160415 326) ((emacs (24 3)) (powerline (2 3))) "powerline mode, color schemes from microsoft and google's logo." single ((:commit . "837504263bb1711203b0f7efecd6b7b5f272fae0") (:authors ("yzprofile" . "yzprofiles@gmail.com")) (:maintainer "yzprofile" . "yzprofiles@gmail.com") (:keywords "mode-line" "powerline" "theme") (:url . "https://github.com/yzprofile/micgoline"))])
+ (midje-mode . [(20170809 403) ((cider (0 1 4)) (clojure-mode (1 0))) "Minor mode for running Midje tests in emacs" tar ((:commit . "10ad5b6084cd03d5cd268b486a7c3c246d85535f"))])
+ (migemo . [(20200913 12) ((cl-lib (0 5))) "Japanese incremental search through dynamic pattern expansion" single ((:commit . "f756cba3d5268968da361463c2e29b3a659a3de7") (:authors ("Satoru Takabayashi" . "satoru-t@is.aist-nara.ac.jp")) (:maintainer "Satoru Takabayashi" . "satoru-t@is.aist-nara.ac.jp") (:url . "https://github.com/emacs-jp/migemo"))])
+ (milkode . [(20140927 529) nil "Command line search and direct jump with Milkode" single ((:commit . "ba97e2aeefa1d9d0b3835bf08edd0de248b0c513") (:authors ("ongaeshi")) (:maintainer "ongaeshi") (:keywords "milkode" "search" "grep" "jump" "keyword"))])
+ (mimetypes . [(20201115 1605) ((emacs (25 1))) "Guess a file's mimetype by extension" single ((:commit . "1663054ce266ed25e47ec707c19f619d33225903") (:authors ("Craig Niles <niles.c at gmail.com>")) (:maintainer "Craig Niles <niles.c at gmail.com>") (:url . "https://github.com/cniles/emacs-mimetypes"))])
+ (minesweeper . [(20200416 2342) nil "play minesweeper in Emacs" single ((:commit . "d4248e3c9b3e9e7277cb9e6d081330611898f334") (:authors ("Zachary Kanfer" . "zkanfer@gmail.com")) (:maintainer "Zachary Kanfer" . "zkanfer@gmail.com") (:keywords "game" "fun" "minesweeper" "inane" "diversion") (:url . "https://hg.sr.ht/~zck/minesweeper"))])
+ (mingus . [(20190106 1443) ((libmpdee (2 1))) "MPD Interface" tar ((:commit . "4223be618f57f10f18114a74393a71955b568884") (:authors ("Niels Giesen <pft on #emacs>")) (:maintainer "Niels Giesen <pft on #emacs>") (:keywords "multimedia" "elisp" "music" "mpd") (:url . "https://github.com/pft/mingus"))])
+ (mini-frame . [(20210710 1941) ((emacs (26 1))) "Show minibuffer in child frame on read-from-minibuffer" single ((:commit . "57a049b9e1ea4a9b65e82fc10c8c7e70a042f636") (:authors ("Andrii Kolomoiets" . "andreyk.mad@gmail.com")) (:maintainer "Andrii Kolomoiets" . "andreyk.mad@gmail.com") (:keywords "frames") (:url . "https://github.com/muffinmad/emacs-mini-frame"))])
+ (mini-header-line . [(20170621 1221) ((emacs (24 4))) "a minimal header-line" single ((:commit . "73b6724e0a26c4528d93768191c8aa59e6bce2e5") (:authors ("Johannes Goslar")) (:maintainer "Johannes Goslar") (:keywords "header-line" "mode-line") (:url . "https://github.com/ksjogo/mini-header-line"))])
+ (mini-modeline . [(20211130 604) ((emacs (25 1)) (dash (2 12 0))) "Display modeline in minibuffer" single ((:commit . "434b98b22c69c8b3b08e9c267c935591c49a8301") (:authors ("Kien Nguyen" . "kien.n.quang@gmail.com")) (:maintainer "Kien Nguyen" . "kien.n.quang@gmail.com") (:keywords "convenience" "tools") (:url . "https://github.com/kiennq/emacs-mini-modeline"))])
+ (minibuf-isearch . [(20151226 1943) nil "incremental search on minibuffer history" single ((:commit . "2846c6ac369ee623dad4cd3c8a7a6d9078965516") (:authors ("Keiichiro Nagano" . "knagano@sodan.org") ("Hideyuki SHIRAI " . "shirai@meadowy.org")) (:maintainer "Keiichiro Nagano" . "knagano@sodan.org") (:keywords "minibuffer" "history" "incremental search"))])
+ (minibuffer-complete-cycle . [(20130813 1645) nil "Cycle through the *Completions* buffer" single ((:commit . "3df80135887d0169e02294a948711f6dfeca4a6f") (:authors ("Akinori MUSHA" . "knu@iDaemons.org") ("Kevin Rodgers" . "ihs_4664@yahoo.com")) (:maintainer "Akinori MUSHA" . "knu@iDaemons.org") (:keywords "completion") (:url . "https://github.com/knu/minibuffer-complete-cycle"))])
+ (minibuffer-cua . [(20130906 1134) nil "Make CUA mode's S-up/S-down work in minibuffer" single ((:commit . "adc4979a64f8b36e05960e9afa0746dfa9e2e4c7") (:authors ("Akinori MUSHA" . "knu@iDaemons.org")) (:maintainer "Akinori MUSHA" . "knu@iDaemons.org") (:keywords "completion" "editing") (:url . "https://github.com/knu/minibuffer-cua.el"))])
+ (minibuffer-modifier-keys . [(20210823 713) ((emacs (24 3))) "Use spacebar as a modifier key in the minibuffer" single ((:commit . "38da548225f51ca7bca22d3e9b0de78e3b9e6cdd") (:authors ("SpringHan")) (:maintainer "SpringHan") (:keywords "tools") (:url . "https://github.com/SpringHan/minibuffer-modifier-keys.git"))])
+ (miniedit . [(20100419 1745) nil "Enhanced editing for minibuffer fields." single ((:commit . "e12bf659c3eb92dd8a4cb77642dc0865c54667a3"))])
+ (minimal-session-saver . [(20140508 2041) nil "Very lean session saver" single ((:commit . "cf654ac549850746dc21091746e4bcc1aef7668e") (:authors ("Roland Walker" . "walker@pobox.com")) (:maintainer "Roland Walker" . "walker@pobox.com") (:keywords "tools" "frames" "project") (:url . "http://github.com/rolandwalker/minimal-session-saver"))])
+ (minimal-theme . [(20190113 2132) nil "A light/dark minimalistic Emacs 24 theme." tar ((:commit . "221b43aad320d226863892dfe4d85465e8eb81ce") (:authors ("Anler Hp <anler86 [at] gmail.com>")) (:maintainer "Anler Hp <anler86 [at] gmail.com>") (:keywords "color" "theme" "minimal") (:url . "http://github.com/ikame/minimal-theme"))])
+ (minions . [(20220422 1615) ((emacs (25 2)) (compat (28 1 1 0))) "A minor-mode menu for the mode line" single ((:commit . "b0427eea174adb494efc9fa212c22021861d3f76") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:keywords "convenience") (:url . "https://github.com/tarsius/minions"))])
+ (minitest . [(20200506 308) ((dash (1 0 0))) "An Emacs mode for ruby minitest files" tar ((:commit . "ddd152c990a528ad09a696bfad23afa4330ea4d7") (:authors ("Arthur Neves")) (:maintainer "Arthur Neves") (:url . "https://github.com/arthurnn/minitest-emacs"))])
+ (minizinc-mode . [(20180201 1450) ((emacs (24 1))) "Major mode for MiniZinc code" single ((:commit . "2512521ba7f8e263a06db88df663fc6b3cca7e16") (:keywords "languages" "minizinc") (:url . "http://github.com/m00nlight/minizinc-mode"))])
+ (minor-mode-hack . [(20170926 34) nil "Change priority of minor-mode keymaps" single ((:commit . "9688994e23ccb2de568225ef125b41c46e5667c3") (:authors ("rubikitch" . "rubikitch@ruby-lang.org")) (:maintainer "rubikitch" . "rubikitch@ruby-lang.org") (:keywords "lisp") (:url . "http://www.emacswiki.org/cgi-bin/wiki/download/minor-mode-hack.el"))])
+ (minsk-theme . [(20200306 1220) ((emacs (24))) "Minsk, a theme in deep muted greens" single ((:commit . "e4dcdec3a4472a507d6b249ae2194dacaa885ecb") (:authors ("Jean Lo" . "jlpaca@users.noreply.github.com")) (:maintainer "Jean Lo" . "jlpaca@users.noreply.github.com") (:keywords "theme" "faces") (:url . "https://github.com/jlpaca/minsk-theme"))])
+ (mip-mode . [(20151127 617) nil "virtual projects for emacs." single ((:commit . "7c88c383b4c7ed0a4c1dc397735f365c1fcb461c") (:authors ("Eeli Reilin" . "gaudecker@fea.st")) (:maintainer "Eeli Reilin" . "gaudecker@fea.st") (:keywords "workspaces" "workspace" "project" "projects" "mip-mode"))])
+ (mips-mode . [(20211114 1645) nil "Major-mode for MIPS assembly" single ((:commit . "5676174bea9a5780ddd33d2d8111b8678dfa4e99") (:authors ("Henrik Lissner <http://github/hlissner>")) (:maintainer "Henrik Lissner" . "contact@henrik.io") (:keywords "languages" "mips" "assembly") (:url . "https://github.com/hlissner/emacs-mips-mode"))])
+ (mix . [(20210605 1015) ((emacs (25 1))) "Mix Major Mode. Build Elixir using Mix" single ((:commit . "bfe61ed4e7dd8cfc0bb2603fbac3eb44b32438bf") (:authors ("Ayrat Badykov" . "ayratin555@gmail.com")) (:maintainer "Ayrat Badykov" . "ayratin555@gmail.com") (:keywords "tools") (:url . "https://github.com/ayrat555/mix.el"))])
+ (mixed-pitch . [(20210304 1900) ((emacs (24 3))) "Use a variable pitch, keeping fixed pitch where it's sensible" single ((:commit . "519e05f74825abf04b7d2e0e38ec040d013a125a") (:authors ("J. Alexander Branham" . "branham@utexas.edu")) (:maintainer "J. Alexander Branham" . "branham@utexas.edu") (:url . "https://gitlab.com/jabranham/mixed-pitch"))])
+ (mkdown . [(20140517 1418) ((markdown-mode (2 0))) "Pretty Markdown previews based on mkdown.com" tar ((:commit . "8e23de82719af6c5b53b52b3308a02b3a1fb872e") (:authors ("Andrew Tulloch")) (:maintainer "Andrew Tulloch") (:keywords "markdown") (:url . "https://github.com/ajtulloch/mkdown.el"))])
+ (mlscroll . [(20210601 2158) ((emacs (27 1))) "A scroll bar for the modeline" single ((:commit . "a9f2abd32f2517392a396d61e558bea3c887b5b6") (:authors ("J.D. Smith")) (:maintainer "J.D. Smith") (:keywords "convenience") (:url . "https://github.com/jdtsmith/mlscroll"))])
+ (mmm-jinja2 . [(20170313 1420) ((mmm-mode (0 5 4))) "MMM submode class for Jinja2 Templates" single ((:commit . "0bdcb5c7547cbf353f960c36ca4090520f6fc3c3") (:authors ("Ben Hayden" . "hayden767@gmail.com")) (:maintainer "Ben Hayden" . "hayden767@gmail.com") (:url . "https://github.com/glynnforrest/mmm-jinja2"))])
+ (mmm-mode . [(20200908 2236) ((cl-lib (0 2))) "Allow Multiple Major Modes in a buffer" tar ((:commit . "0d00cdf4d02cc166304f6967a20fa22e2eaf208b") (:authors ("Michael Abraham Shulman" . "viritrilbia@gmail.com")) (:maintainer "Dmitry Gutov" . "dgutov@yandex.ru") (:keywords "convenience" "faces" "languages" "tools") (:url . "https://github.com/purcell/mmm-mode"))])
+ (mmt . [(20210321 1829) ((emacs (24 5)) (cl-lib (0 3))) "Missing macro tools for Emacs Lisp" single ((:commit . "e5cd2b4d0967758471fd2753f78120bdeb93a781") (:authors ("Mark Karpov" . "markkarpov92@gmail.com")) (:maintainer "Mark Karpov" . "markkarpov92@gmail.com") (:keywords "macro" "emacs-lisp") (:url . "https://github.com/mrkkrp/mmt"))])
+ (mo-git-blame . [(20160129 1759) nil "An interactive, iterative 'git blame' mode for Emacs" single ((:commit . "254a675eb794cdbbdef9fa2b4b7bb510b70089c0") (:authors ("Moritz Bunkus" . "moritz@bunkus.org")) (:maintainer "Moritz Bunkus" . "moritz@bunkus.org") (:keywords "tools"))])
+ (mo-vi-ment-mode . [(20181217 206) nil "Provide vi-like cursor movement that's easy on the fingers" single ((:commit . "e8b525ffc5faa31d36ecc5496b40f0f5c3603c08") (:authors ("Ajay MT" . "ajay.tatachar@gmail.com")) (:maintainer "Ajay MT" . "ajay.tatachar@gmail.com") (:keywords "convenience"))])
+ (mobdebug-mode . [(20140110 346) ((lua-mode (20130419)) (emacs (24))) "Major mode for MobDebug" single ((:commit . "e1d483bc4e341c762bc5c0a8c52306a8d01ea0da") (:authors ("Shihpin Tseng" . "deftsp@gmail.com")) (:maintainer "Shihpin Tseng" . "deftsp@gmail.com") (:url . "https://github.com/deftsp/mobdebug-mode"))])
+ (mocha . [(20200729 1130) ((js2-mode (20150909)) (f (0 18))) "Run Mocha or Jasmine tests" single ((:commit . "6a72fa20e7be6e55c09b1bc9887ee09c5df28e45") (:authors ("Al Scott")) (:maintainer "Al Scott") (:keywords "javascript" "mocha" "jasmine") (:url . "http://github.com/scottaj/mocha.el"))])
+ (mocha-snippets . [(20190417 1931) ((yasnippet (0 8 0))) "Yasnippets for the Mocha JS Testing Framework" tar ((:commit . "44998ea42136a6912ce80061909db1c4c77c8ed8") (:authors ("Charles Lowell" . "cowboyd@frontside.io")) (:maintainer "Charles Lowell" . "cowboyd@frontside.io") (:keywords "test" "javascript"))])
+ (mocker . [(20210115 157) ((emacs (25 1))) "mocking framework for emacs" single ((:commit . "5b01b3cc51388faf1ba823683c3600790099c84c") (:authors ("Yann Hodique" . "yann.hodique@gmail.com")) (:maintainer "Yann Hodique" . "yann.hodique@gmail.com") (:keywords "lisp" "testing"))])
+ (modalka . [(20210318 1748) ((emacs (24 4))) "Modal editing your way" single ((:commit . "3d7f652d06c8e39cfe252ece804868a20730df07") (:authors ("Mark Karpov" . "markkarpov92@gmail.com")) (:maintainer "Mark Karpov" . "markkarpov92@gmail.com") (:keywords "modal" "editing") (:url . "https://github.com/mrkkrp/modalka"))])
+ (mode-icons . [(20200920 2031) ((emacs (24)) (cl-lib (0 5))) "Show icons for modes" tar ((:commit . "a5f978e84e07a1d79c6c8e35043ac93d8e5d50ed") (:authors ("Tom Willemse" . "tom@ryuslash.org")) (:maintainer "Tom Willemse" . "tom@ryuslash.org") (:keywords "multimedia") (:url . "http://ryuslash.org/projects/mode-icons.html"))])
+ (mode-line-bell . [(20181029 516) nil "Flash the mode line instead of ringing the bell" single ((:commit . "26ac7d97abdeb762ceaeab6b892f3ed7e3412494") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:keywords "convenience"))])
+ (mode-line-debug . [(20220422 1615) ((emacs (25 1)) (compat (28 1 1 0))) "Show status of debug-on-error in mode-line" single ((:commit . "d33e76efac6978c755bb5e0ced061b0063a6dff9") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:keywords "convenience" "lisp") (:url . "https://github.com/tarsius/mode-line-debug"))])
+ (mode-line-idle . [(20220406 2322) ((emacs (28 1))) "Evaluate mode line content when idle" single ((:commit . "6ff3eb73586e9f3d6197447290aa92fd49f467e8") (:authors ("Campbell Barton" . "ideasman42@gmail.com")) (:maintainer "Campbell Barton" . "ideasman42@gmail.com") (:url . "https://gitlab.com/ideasman42/emacs-mode-line-idle"))])
+ (modern-cpp-font-lock . [(20210405 1155) nil "Font-locking for \"Modern C++\"" single ((:commit . "43c6b68ff58fccdf9deef11674a172e4eaa8455c") (:authors ("Ludwig PACIFICI" . "ludwig@lud.cc")) (:maintainer "Ludwig PACIFICI" . "ludwig@lud.cc") (:keywords "languages" "c++" "cpp" "font-lock") (:url . "https://github.com/ludwigpacifici/modern-cpp-font-lock"))])
+ (modern-fringes . [(20220401 202) nil "Replaces default fringe bitmaps with better looking ones" single ((:commit . "98473694a33922cfdddb18b4791028e4854b53b5") (:authors ("Quen Jankosky" . "quen.jankosky@gmail.com")) (:maintainer "Quen Jankosky" . "quen.jankosky@gmail.com") (:keywords "themes" "fringes" "convenience") (:url . "http://github.com/specialbomb/emacs-modern-fringes"))])
+ (modern-sh . [(20211101 1001) ((emacs (25 1)) (hydra (0 15 0)) (eval-in-repl (0 9 7))) "Minor mode for editing shell script" single ((:commit . "8ebebe77304aa8170f7af809e7564c79d3bd45da") (:keywords "languages" "programming") (:url . "https://github.com/damon-kwok/modern-sh"))])
+ (modtime-skip-mode . [(20140128 2201) nil "Minor mode for disabling modtime and supersession checks on files." single ((:commit . "c0e49523aa26b2263a8693691ac775988015f592") (:authors ("Jordon Biondo" . "biondoj@mail.gvsu.edu")) (:maintainer "Jordon Biondo" . "biondoj@mail.gvsu.edu") (:url . "http://www.github.com/jordonbiondo/modtime-skip-mode"))])
+ (modular-config . [(20210726 1614) ((emacs (25 1))) "Organize your config into small and loadable modules" single ((:commit . "2bd77193fa3a7ec0541db284b4034821a8f59fea") (:authors ("Sidharth Arya" . "sidhartharya10@gmail.com")) (:maintainer "Sidharth Arya" . "sidhartharya10@gmail.com") (:keywords "startup" "lisp" "tools") (:url . "https://github.com/SidharthArya/modular-config.el"))])
+ (modus-themes . [(20220505 737) ((emacs (27 1))) "Elegant, highly legible and customizable themes" tar ((:commit . "842c672a81cf976b47f0fb6ae13bcf13ee774024") (:authors ("Protesilaos Stavrou" . "info@protesilaos.com")) (:maintainer "Protesilaos Stavrou" . "info@protesilaos.com") (:keywords "faces" "theme" "accessibility") (:url . "https://git.sr.ht/~protesilaos/modus-themes"))])
+ (moe-theme . [(20220111 1220) nil "A colorful eye-candy theme. Moe, moe, kyun!" tar ((:commit . "edf3fe47fb986e283e3b04cba443dcb39fe8720e") (:authors ("kuanyui" . "azazabc123@gmail.com")) (:maintainer "kuanyui" . "azazabc123@gmail.com") (:keywords "themes") (:url . "https://github.com/kuanyui/moe-theme.el"))])
+ (molar-mass . [(20210519 1342) ((emacs (24 3))) "Calculates molar mass of a molecule" single ((:commit . "838db1486a2dc5a3774eb195d62fbcdef71a63f7") (:authors ("Sergi Ruiz Trepat")) (:maintainer "Sergi Ruiz Trepat") (:keywords "convenience" "chemistry") (:url . "https://github.com/sergiruiztrepat/molar-mass.el"))])
+ (molecule . [(20180527 743) ((emacs (25 1))) "Simple wrapper for molecule" single ((:commit . "2ef72b81d9aa24ea782b71a061a3abdad6cae162") (:authors (": drymer <drymer [ AT ] autistici.org>")) (:maintainer ": drymer <drymer [ AT ] autistici.org>") (:keywords ":" "languages" "terminals") (:url . "https://git.daemons.it/drymer/molecule.el"))])
+ (molokai-theme . [(20220106 1520) nil "molokai theme with Emacs theme engine" single ((:commit . "cc53e997e7eff93b58ad16a376a292c1dd66044b") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/alloy-d/color-theme-molokai"))])
+ (mongo . [(20150315 1219) nil "MongoDB driver for Emacs Lisp" tar ((:commit . "595529ddd70ecb9fab8b11daad2c3929941099d6") (:authors ("Tomohiro Matsuyama" . "m2ym.pub@gmail.com")) (:maintainer "Tomohiro Matsuyama" . "m2ym.pub@gmail.com") (:keywords "convenience"))])
+ (monitor . [(20161018 1144) ((dash (2 13 0))) "Utilities for monitoring expressions." tar ((:commit . "63f4643a0ee81616dbb692b8b03bae21df2283e2") (:authors ("Ben Moon" . "software@guiltydolphin.com")) (:maintainer "Ben Moon" . "software@guiltydolphin.com") (:keywords "lisp" "monitor" "utility") (:url . "https://github.com/guiltydolphin/monitor"))])
+ (monkeytype . [(20210110 513) ((emacs (25 1)) (scrollable-quick-peek (0 1 0))) "Mode for speed typing" single ((:commit . "f64b1580f8516ddbf5f71688fb9ace2cd1631b41") (:authors ("Pablo Barrantes" . "xjpablobrx@gmail.com")) (:maintainer "Pablo Barrantes" . "xjpablobrx@gmail.com") (:keywords "games") (:url . "https://github.com/jpablobr/emacs-monkeytype"))])
+ (monky . [(20210417 12) nil "Control Hg from Emacs." tar ((:commit . "72c7cd21b7b995c476e938fd0b92a494aa25c3a7") (:authors ("Anantha kumaran" . "ananthakumaran@gmail.com")) (:maintainer "Anantha kumaran" . "ananthakumaran@gmail.com") (:keywords "tools") (:url . "http://github.com/ananthakumaran/monky"))])
+ (monochrome-theme . [(20140326 1050) nil "A dark Emacs 24 theme for your focused hacking sessions" tar ((:commit . "bfca67fe7365310bc47ae9ca96c417caada54896") (:authors ("Xavier Noria" . "fxn@hashref.com")) (:maintainer "Xavier Noria" . "fxn@hashref.com"))])
+ (monokai-alt-theme . [(20170630 2048) ((emacs (24))) "Theme with a dark background. Based on sublime monokai theme." single ((:commit . "f342b6afc31f929be0626eca2d696ee9fab78011") (:authors ("Dmytro Koval")) (:maintainer "Dmytro Koval") (:url . "https://github.com/dawidof/emacs-monokai-theme"))])
+ (monokai-pro-theme . [(20210206 1820) nil "A simple theme based on the Monokai Pro Sublime color schemes" tar ((:commit . "d0489741a80d818713c290a1a4bdd985877228bb") (:authors ("Kaleb Elwert" . "belak@coded.io")) (:maintainer "Kaleb Elwert" . "belak@coded.io") (:url . "https://github.com/belak/emacs-monokai-pro-theme"))])
+ (monokai-theme . [(20220117 1244) nil "A fruity color theme for Emacs." single ((:commit . "4a09c59f948ba5b602b6f395e667f53224fd75a2") (:authors ("Kelvin Smith" . "oneKelvinSmith@gmail.com")) (:maintainer "Kelvin Smith" . "oneKelvinSmith@gmail.com") (:url . "http://github.com/oneKelvinSmith/monokai-emacs"))])
+ (monotropic-theme . [(20211116 1328) ((emacs (24))) "Monotropic Theme" single ((:commit . "f32a04b5bfee9cbcce4b223f17228d1142a28211") (:authors ("caffo")) (:maintainer "caffo") (:url . "https://github.com/caffo/monotropic-theme"))])
+ (monroe . [(20210824 2348) nil "Yet another client for nREPL" single ((:commit . "d140512781bda5160b4786f591694a569639b9ad") (:authors ("Sanel Zukan" . "sanelz@gmail.com")) (:maintainer "Sanel Zukan" . "sanelz@gmail.com") (:keywords "languages" "clojure" "nrepl" "lisp") (:url . "http://www.github.com/sanel/monroe"))])
+ (mood-line . [(20211003 2113) ((emacs (25 1))) "A minimal mode-line inspired by doom-modeline" single ((:commit . "ef1c752679a8f92faa7b4828adbbb300b6942f22") (:authors ("Jessie Hildebrandt <jessieh.net>")) (:maintainer "Jessie Hildebrandt <jessieh.net>") (:keywords "mode-line" "faces") (:url . "https://gitlab.com/jessieh/mood-line"))])
+ (mood-one-theme . [(20210221 18) ((emacs (24 4))) "A dark color scheme inspired by the Doom One theme." single ((:commit . "42e402a89473458f55a71c5bbe785575e9a927ba") (:authors ("Jessie Hildebrandt <jessieh.net>")) (:maintainer "Jessie Hildebrandt <jessieh.net>") (:keywords "mode-line" "faces") (:url . "https://gitlab.com/jessieh/mood-one-theme"))])
+ (moody . [(20220422 1616) ((emacs (25 3)) (compat (28 1 1 0))) "Tabs and ribbons for the mode line" single ((:commit . "ac647781d2d66d57c84a64dfd33b463b4a99b257") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:keywords "faces") (:url . "https://github.com/tarsius/moody"))])
+ (moom . [(20210324 825) ((emacs (25 1))) "Commands to control frame position and size" tar ((:commit . "f94cf84138a81212ffe856599834f7824a1b6e95") (:authors ("Takaaki ISHIKAWA <takaxp at ieee dot org>")) (:maintainer "Takaaki ISHIKAWA <takaxp at ieee dot org>") (:keywords "frames" "faces" "convenience") (:url . "https://github.com/takaxp/Moom"))])
+ (moonscript . [(20170831 2226) ((cl-lib (0 5)) (emacs (24))) "Major mode for editing MoonScript code" tar ((:commit . "56f90471e2ced2b0a177aed4d8c2f854797e9cc7") (:authors ("@GriffinSchneider, @k2052, @EmacsFodder")) (:maintainer "@GriffinSchneider, @k2052, @EmacsFodder"))])
+ (moonshot . [(20210627 2244) ((emacs (25 1)) (cl-lib (0 5)) (f (0 18)) (s (1 11 0)) (projectile (2 0 0)) (counsel (0 11 0)) (realgud (1 5 1)) (seq (2 20)) (levenshtein (1 0))) "Run executable file, debug and build commands on project" single ((:commit . "ec37a12825888047a90d9ee8131aa4bea348edf7") (:authors ("Jong-Hyouk Yun" . "ageldama@gmail.com")) (:maintainer "Jong-Hyouk Yun" . "ageldama@gmail.com") (:keywords "convenience" "files" "processes" "tools" "unix") (:url . "https://github.com/ageldama/moonshot"))])
+ (morganey-mode . [(20170118 934) ((emacs (24 4))) "Major mode for editing Morganey files" single ((:commit . "5cf3870432a2aeb69d373abe63b3be1f325f6d21") (:authors ("Alexey Kutepov" . "reximkut@gmail.com")) (:maintainer "Alexey Kutepov" . "reximkut@gmail.com") (:url . "https://github.com/morganey-lang/morganey-mode"))])
+ (morgentau-theme . [(20220319 1049) ((emacs (24))) "Tango-based custom theme" single ((:commit . "a8da5640b4a9b72a3136901d0a1a03071d9fcb00") (:authors ("Benjamin Vincent Schulenburg")) (:maintainer "Benjamin Vincent Schulenburg") (:keywords "theme" "dark" "faces") (:url . "https://github.com/Melchizedek6809/morgentau-theme"))])
+ (morlock . [(20220422 1616) ((emacs (25 1)) (compat (28 1 1 0))) "More font-lock keywords for elisp" single ((:commit . "b699497363c60bddc18393f68e3c9185e5fbb589") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:keywords "convenience") (:url . "https://github.com/tarsius/morlock"))])
+ (mosey . [(20180614 1649) ((emacs (24 4))) "Mosey around your buffers" single ((:commit . "2e3ac9d334fa2937ed5267193dfd25d8e1f14dc2") (:authors ("Adam Porter" . "adam@alphapapa.net")) (:maintainer "Adam Porter" . "adam@alphapapa.net") (:keywords "convenience") (:url . "http://github.com/alphapapa/mosey.el"))])
+ (most-used-words . [(20200808 931) ((emacs (24 3))) "Display most used words in buffer" single ((:commit . "f712879493660c3c3ee3793470b8f8939b79c2b0") (:authors ("Udyant Wig" . "udyant.wig@gmail.com")) (:maintainer "Udyant Wig" . "udyant.wig@gmail.com") (:keywords "convenience" "wp") (:url . "https://github.com/udyantw/most-used-words"))])
+ (mote-mode . [(20160123 29) ((ruby-mode (1 1))) "Mote minor mode" single ((:commit . "666c6641addbd3b337a7aa01fd2742ded2f41b83") (:authors ("Leandro López (inkel)" . "inkel.ar@gmail.com")) (:maintainer "Leandro López (inkel)" . "inkel.ar@gmail.com") (:url . "http://inkel.github.com/mote-mode/"))])
+ (motion-mode . [(20140920 156) ((flymake-easy (0 7)) (flymake-cursor (1 0 2))) "major mode for RubyMotion enviroment" tar ((:commit . "4c94180e3ecea611a61240a0c0cd48f1032c4a55") (:authors ("Satoshi Namai")) (:maintainer "Satoshi Namai") (:url . "https://github.com/ainame/motion-mode"))])
+ (move-dup . [(20210127 1938) ((emacs (25 1))) "Eclipse-like moving and duplicating lines or rectangles" single ((:commit . "5906503e0b9b832b1d5062c9cd27cf72a2ce4817") (:authors ("Jimmy Yuen Ho Wong" . "wyuenho@gmail.com")) (:maintainer "Jimmy Yuen Ho Wong" . "wyuenho@gmail.com") (:keywords "convenience" "text" "edit") (:url . "https://github.com/wyuenho/move-dup"))])
+ (move-text . [(20170909 330) nil "Move current line or region with M-up or M-down." single ((:commit . "bfc255110ad05732a43cf25d6a0e3b4a6710b58c") (:authors ("Jason Milkins" . "jasonm23@gmail.com")) (:maintainer "Jason Milkins" . "jasonm23@gmail.com") (:keywords "edit") (:url . "https://github.com/emacsfodder/move-text"))])
+ (mowedline . [(20161122 235) nil "elisp utilities for using mowedline" single ((:commit . "6121b7d4aacd18f7b24da226e61dbae054e50a7c") (:authors ("John Foerch" . "jjfoerch@earthlink.net")) (:maintainer "John Foerch" . "jjfoerch@earthlink.net"))])
+ (mozc . [(20210306 1053) nil "minor mode to input Japanese with Mozc" single ((:commit . "4c5d516fdff227039305eef3411f12bac9f02246") (:keywords "mule" "multilingual" "input method"))])
+ (mozc-cand-posframe . [(20200208 750) ((emacs (26 1)) (posframe (0 5 0)) (mozc (20180101 800)) (s (1 12))) "Posframe frontend for mozc.el" single ((:commit . "1d07d5055381008ccbb29b97315d140e09a7ee95") (:authors ("Akira Komamura" . "akira.komamura@gmail.com")) (:maintainer "Akira Komamura" . "akira.komamura@gmail.com") (:keywords "i18n" "tooltip") (:url . "https://github.com/akirak/mozc-posframe"))])
+ (mozc-im . [(20160412 22) ((mozc (0))) "Mozc with input-method-function interface." single ((:commit . "df614a1076c28a11551fb3e822868bae47e855a5") (:authors ("Daisuke Kobayashi" . "d5884jp@gmail.com")) (:maintainer "Daisuke Kobayashi" . "d5884jp@gmail.com") (:keywords "i18n" "extentions"))])
+ (mozc-popup . [(20150224 34) ((popup (0 5 2)) (mozc (0))) "Mozc with popup" single ((:commit . "f0684b875a7427ec08f8df13939a486e5d5cf420") (:authors ("Daisuke Kobayashi" . "d5884jp@gmail.com")) (:maintainer "Daisuke Kobayashi" . "d5884jp@gmail.com") (:keywords "i18n" "extentions"))])
+ (mozc-temp . [(20160228 840) ((emacs (24)) (dash (2 10 0)) (mozc (0))) "Use mozc temporarily" single ((:commit . "90a6eb1db8fa1283b944432cfb83739286b37f92") (:authors ("Hiroki YAMAKAWA" . "s06139@gmail.com")) (:maintainer "Hiroki YAMAKAWA" . "s06139@gmail.com") (:url . "https://github.com/HKey/mozc-temp"))])
+ (mpages . [(20150710 1404) nil "An Emacs buffer for quickly writing your Morning Pages" single ((:commit . "39a72a0931ab1cdbfdf0ab9f412dc12d43a3829f") (:authors ("Sean Levin")) (:maintainer "Sean Levin") (:url . "https://github.com/slevin/mpages"))])
+ (mpdel . [(20210107 1303) ((emacs (25 1)) (libmpdel (1 2 0)) (navigel (0 7 0))) "Play and control your MPD music" tar ((:commit . "6682446c6263a79e79c55cf32c0efb066245feec") (:authors ("Damien Cassou" . "damien@cassou.me")) (:maintainer "Damien Cassou" . "damien@cassou.me") (:keywords "multimedia") (:url . "https://gitea.petton.fr/mpdel/mpdel"))])
+ (mpdmacs . [(20210904 35) ((emacs (25 1)) (elmpd (0 1))) "A lightweight MPD client" single ((:commit . "334b066dc5bb82d9ccb6cc30d63afed0f7610fe8") (:authors ("Michael Herstine" . "sp1ff@pobox.com")) (:maintainer "Michael Herstine" . "sp1ff@pobox.com") (:keywords "comm") (:url . "https://github.com/sp1ff/mpdmacs"))])
+ (mpmc-queue . [(20180303 2029) ((emacs (26 0)) (queue (0 2 0))) "a multiple-producer-multiple-consumer queue" single ((:commit . "df07d6bef7468edb1d73ef73b8331b94d0e5d0ca") (:authors ("Sho Mizoe" . "sho.mizoe@gmail.com")) (:maintainer "Sho Mizoe" . "sho.mizoe@gmail.com") (:keywords "lisp" "async") (:url . "https://github.com/smizoe/mpmc-queue"))])
+ (mpv . [(20211228 2043) ((cl-lib (0 5)) (emacs (25 1)) (json (1 3)) (org (8 0))) "control mpv for easy note-taking" single ((:commit . "4fd8baa508dbc1a6b42b4e40292c0dbb0f19c9b9") (:authors ("Johann Klähn" . "johann@jklaehn.de")) (:maintainer "Johann Klähn" . "johann@jklaehn.de") (:keywords "tools" "multimedia") (:url . "https://github.com/kljohann/mpv.el"))])
+ (mqr . [(20180527 1204) ((emacs (24 4))) "Multi-dimensional query and replace" single ((:commit . "4ade19d4620b8b61340290bf63fa56d5e493859f") (:authors ("Tino Calancha" . "tino.calancha@gmail.com")) (:maintainer "Tino Calancha" . "tino.calancha@gmail.com") (:keywords "convenience" "extensions" "lisp") (:url . "https://github.com/calancha/multi-replace"))])
+ (mqtt-mode . [(20180611 1735) ((emacs (25)) (dash (2 12 0))) "client for interaction with MQTT servers" single ((:commit . "613e70e9b9940e635e779994b5c83f86eb62c8e6") (:authors ("Andreas Müller" . "code@0x7.ch")) (:maintainer "Andreas Müller" . "code@0x7.ch") (:keywords "tools") (:url . "https://github.com/andrmuel/mqtt-mode"))])
+ (msgpack . [(20200323 515) ((emacs (25 1))) "Read and write MessagePack object" single ((:commit . "90e3086f259549b1667a3c5b9aa2d70aaeaa4d3d") (:authors ("Xu Chunyang")) (:maintainer "Xu Chunyang") (:keywords "lisp") (:url . "https://github.com/xuchunyang/msgpack.el"))])
+ (msvc . [(20210503 1856) ((emacs (24)) (cl-lib (0 5)) (cedet (1 0)) (ac-clang (2 0 0))) "Microsoft Visual C/C++ mode" tar ((:commit . "122dc9cb7f145f12dac7b117a48fceb38b279432") (:authors ("yaruopooner [https://github.com/yaruopooner]")) (:maintainer "yaruopooner [https://github.com/yaruopooner]") (:keywords "languages" "completion" "syntax check" "mode" "intellisense") (:url . "https://github.com/yaruopooner/msvc"))])
+ (mtg-deck-mode . [(20180613 2010) ((emacs (25 1))) "Major mode to edit MTG decks" tar ((:commit . "8265b8ed17fcd4406760c19aa6ee9c76068b1ab0") (:authors ("Mattias Bengtsson" . "mattias.jc.bengtsson@gmail.com")) (:maintainer "Mattias Bengtsson" . "mattias.jc.bengtsson@gmail.com") (:keywords "data" "mtg" "magic") (:url . "https://github.com/mattiasb/mtg-deck-mode"))])
+ (mu-cite . [(20190803 439) ((flim (1 14 9))) "A library to provide MIME features." tar ((:commit . "b2c83bbce4646d100b942f0f0de0877a8d47298c") (:authors ("MORIOKA Tomohiko" . "tomo@m17n.org") ("Shuhei KOBAYASHI" . "shuhei@aqua.ocn.ne.jp")) (:maintainer "Katsumi Yamaoka" . "yamaoka@jpl.org") (:keywords "mail" "news" "citation"))])
+ (mu2tex . [(20200512 704) nil "Convert plain text molecule names and units to TeX" single ((:commit . "4b84cdac955cb36a8c44a2be48f3310252e3d3ad") (:authors ("Carsten Dominik" . "carsten.dominik@gmail.com")) (:maintainer "Carsten Dominik" . "carsten.dominik@gmail.com") (:keywords "tex") (:url . "https://github.com/cdominik/mu2tex"))])
+ (mu4e-alert . [(20220416 1840) ((alert (1 2)) (s (1 10 0)) (ht (2 0)) (emacs (24 4))) "Desktop notification for mu4e" single ((:commit . "b34d0ea7b75709cc25d842a783cebea855dc9f7d") (:authors ("Iqbal Ansari" . "iqbalansari02@yahoo.com")) (:maintainer "Mikhail Rudenko" . "mike.rudenko@gmail.com") (:keywords "mail" "convenience") (:url . "https://github.com/iqbalansari/mu4e-alert"))])
+ (mu4e-column-faces . [(20210927 1759) ((emacs (25 3))) "Faces for individual mu4e columns" single ((:commit . "b76a5989cafe88a263688488854187a015beef41") (:authors ("Alexander Miller" . "alexanderm@web.de")) (:maintainer "Alexander Miller" . "alexanderm@web.de") (:url . "https://github.com/Alexander-Miller/mu4e-column-faces"))])
+ (mu4e-conversation . [(20190609 812) ((emacs (25 1))) "Show a complete thread in a single buffer" single ((:commit . "ccf85002b18fee54051dbfaf8d3931ca2a07db24") (:authors ("Pierre Neidhardt" . "mail@ambrevar.xyz")) (:maintainer "Pierre Neidhardt" . "mail@ambrevar.xyz") (:keywords "mail" "convenience" "mu4e") (:url . "https://gitlab.com/Ambrevar/mu4e-conversation"))])
+ (mu4e-jump-to-list . [(20211030 2307) ((emacs (24 4)) (cl-lib (0 5))) "mu4e jump-to-list extension" single ((:commit . "4d362a668be4ae624ee96bf7806b25505b4bdf5c") (:authors ("Yuri D'Elia" . "wavexx@thregr.org")) (:maintainer "Yuri D'Elia" . "wavexx@thregr.org") (:keywords "mu4e" "mail" "convenience") (:url . "https://gitlab.com/wavexx/mu4e-jump-to-list.el"))])
+ (mu4e-maildirs-extension . [(20201028 921) ((dash (0 0 0))) "Show mu4e maildirs summary in mu4e-main-view" single ((:commit . "1167bc6e08996f866e73e9a02f563fd21ac317fd") (:authors ("Andreu Gil Pàmies" . "agpchil@gmail.com")) (:maintainer "Andreu Gil Pàmies" . "agpchil@gmail.com") (:url . "http://github.com/agpchil/mu4e-maildirs-extension"))])
+ (mu4e-marker-icons . [(20220225 1137) ((emacs (26 1)) (all-the-icons (4 0 0))) "Display icons for mu4e markers" single ((:commit . "66674ee00dbf953e7d8c1696fb12e9b5b4b272bd") (:keywords "mail") (:url . "https://repo.or.cz/mu4e-marker-icons.git"))])
+ (mu4e-overview . [(20200824 1549) ((emacs (26))) "Show overview of maildir" single ((:commit . "7daaa35a6d78feb83167e780a9c23da719c9051b") (:authors ("Michał Krzywkowski" . "k.michal@zoho.com")) (:maintainer "Michał Krzywkowski" . "k.michal@zoho.com") (:keywords "mail" "tools") (:url . "https://github.com/mkcms/mu4e-overview"))])
+ (mu4e-query-fragments . [(20211030 2307) ((emacs (24 4))) "mu4e query fragments extension" single ((:commit . "8d93ede3772353e2dbc307de03e06e37ea6a0b6c") (:authors ("Yuri D'Elia" . "wavexx@thregr.org")) (:maintainer "Yuri D'Elia" . "wavexx@thregr.org") (:keywords "mu4e" "mail" "convenience") (:url . "https://gitlab.com/wavexx/mu4e-query-fragments.el"))])
+ (mu4e-views . [(20220214 358) ((emacs (26 1)) (xwidgets-reuse (0 2)) (ht (2 2)) (esxml (20210323 1102))) "View emails in mu4e using xwidget-webkit" single ((:commit . "fa47f35e56edcc84f00d622e415ae970cc5df0dd") (:authors ("Boris Glavic" . "lordpretzel@gmail.com")) (:maintainer "Boris Glavic" . "lordpretzel@gmail.com") (:keywords "mail") (:url . "https://github.com/lordpretzel/mu4e-views"))])
+ (muban . [(20180415 1219) ((emacs (25))) "Lightweight template expansion tool" single ((:commit . "fd052645bcaa3cca8cede1c587a0b05ab5bd66b2") (:authors ("Jiahao Li" . "jiahaowork@gmail.com")) (:maintainer "Jiahao Li" . "jiahaowork@gmail.com") (:keywords "abbrev" "tools") (:url . "https://github.com/jiahaowork/muban.el"))])
+ (mugur . [(20210719 722) ((emacs (26 1)) (s (1 12 0)) (anaphora (1 0 4)) (dash (2 18 1)) (cl-lib (1 0))) "Configurator for QMK compatible keyboards" single ((:commit . "267e0594790a5f34e474a5b480015f0f216a6865") (:authors ("Mihai Olteanu" . "mihai_olteanu@fastmail.fm")) (:maintainer "Mihai Olteanu" . "mihai_olteanu@fastmail.fm") (:keywords "multimedia") (:url . "https://github.com/mihaiolteanu/mugur"))])
+ (multi . [(20131013 1544) ((emacs (24))) "Clojure-style multi-methods for emacs lisp" single ((:commit . "0987ab71692717ed457cb3984de184db9185806d") (:authors ("Christina Whyte" . "kurisu.whyte@gmail.com")) (:maintainer "Christina Whyte" . "kurisu.whyte@gmail.com") (:keywords "multimethod" "generic" "predicate" "dispatch") (:url . "http://github.com/kurisuwhyte/emacs-multi"))])
+ (multi-compile . [(20211113 2119) ((emacs (24 4)) (dash (2 12 1))) "Multi target interface to compile." single ((:commit . "5e1e63b6ae4bd94aab5902b14b2bf4238e502cfb") (:authors ("Kvashnin Vladimir" . "reangd@gmail.com")) (:maintainer "Kvashnin Vladimir" . "reangd@gmail.com") (:keywords "tools" "compile" "build") (:url . "https://github.com/ReanGD/emacs-multi-compile"))])
+ (multi-line . [(20220112 1744) ((emacs (24 3)) (s (1 9 0)) (cl-lib (0 5)) (dash (2 12 0)) (shut-up (0 3 2))) "multi-line statements" tar ((:commit . "625c608443f98bb34b4d5600d52c198509fb64d0") (:authors ("Ivan Malison" . "IvanMalison@gmail.com")) (:maintainer "Ivan Malison" . "IvanMalison@gmail.com") (:keywords "multi" "line" "length" "whitespace" "programming" "tools" "convenience" "files") (:url . "https://github.com/IvanMalison/multi-line"))])
+ (multi-project . [(20220415 2334) ((emacs (25))) "Find files, compile, and search for multiple projects." single ((:commit . "d51551296425b1febd102a38a46f2d3dc4548559") (:authors ("Shawn Ellis" . "shawn.ellis17@gmail.com")) (:maintainer "Shawn Ellis" . "shawn.ellis17@gmail.com") (:keywords "convenience" "project" "management") (:url . "https://hg.osdn.net/view/multi-project/multi-project"))])
+ (multi-run . [(20210108 336) ((emacs (24)) (window-layout (1 4))) "Efficiently manage multiple remote nodes" tar ((:commit . "13d4d923535b5e8482b13ff76185203075fb26a3") (:authors ("Sagar Jha")) (:maintainer "Sagar Jha") (:keywords "multiple shells" "multi-run" "remote nodes") (:url . "https://www.github.com/sagarjha/multi-run"))])
+ (multi-term . [(20200514 428) nil "Managing multiple terminal buffers in Emacs." single ((:commit . "017c77c550115936860e2ea71b88e585371475d5") (:authors ("Andy Stewart" . "lazycat.manatee@gmail.com")) (:maintainer "Andy Stewart" . "lazycat.manatee@gmail.com") (:keywords "term" "terminal" "multiple buffer") (:url . "http://www.emacswiki.org/emacs/download/multi-term.el"))])
+ (multi-vterm . [(20210727 1050) ((emacs (26 3)) (vterm (0 0)) (project (0 3 0))) "Like multi-term.el but for vterm" single ((:commit . "a3df7218c1ecadef779e2c47815201052283f9ea") (:keywords "terminals" "processes") (:url . "https://github.com/suonlight/multi-libvterm"))])
+ (multi-web-mode . [(20130824 354) nil "multiple major mode support for web editing" tar ((:commit . "ad1c8d1c870334052d244c7ae3636cb7b9357b7c") (:authors ("Fabián E. Gallina" . "fabian@anue.biz")) (:maintainer "Fabián E. Gallina" . "fabian@anue.biz") (:keywords "convenience" "languages" "wp") (:url . "https://github.com/fgallina/multi-web-mode"))])
+ (multicolumn . [(20150202 2251) nil "Creating and managing multiple side-by-side windows." single ((:commit . "c7a3afecd470859b2e60aa7c554d6e4d436df7fa") (:authors ("Anders Lindgren")) (:maintainer "Anders Lindgren") (:url . "https://github.com/Lindydancer/multicolumn"))])
+ (multifiles . [(20130615 2133) nil "View and edit parts of multiple files in one buffer" single ((:commit . "dddfe64b8e1c1cd1f9ccc1f03405477fc0d53897") (:authors ("Magnar Sveen" . "magnars@gmail.com")) (:maintainer "Magnar Sveen" . "magnars@gmail.com") (:keywords "multiple" "files"))])
+ (multiple-cursors . [(20220328 1724) ((cl-lib (0 5))) "Multiple cursors for Emacs." tar ((:commit . "aae47aebc0ae829211fa1e923232715d8e327b36") (:authors ("Magnar Sveen" . "magnars@gmail.com")) (:maintainer "Magnar Sveen" . "magnars@gmail.com") (:keywords "editing" "cursors") (:url . "https://github.com/magnars/multiple-cursors.el"))])
+ (multistate . [(20210124 2014) ((emacs (25 1)) (ht (2 3))) "Multistate mode" single ((:commit . "a7ab9dc7aac0b6d6d2f872de4e0d1b8550834a9b") (:authors ("Matsievskiy S.V.")) (:maintainer "Matsievskiy S.V.") (:keywords "convenience") (:url . "https://gitlab.com/matsievskiysv/multistate"))])
+ (multitran . [(20211027 1833) ((emacs (24)) (cl-lib (0 5))) "Interface to multitran" single ((:commit . "910f4c929e1d9c1844ddc467f72eef2e03aa3f97") (:authors ("Zajcev Evgeny" . "zevlg@yandex.ru")) (:maintainer "Zajcev Evgeny" . "zevlg@yandex.ru") (:keywords "dictionary" "hypermedia"))])
+ (mustache . [(20210224 710) ((ht (0 9)) (s (1 3 0)) (dash (1 2 0))) "Mustache templating library in emacs lisp" single ((:commit . "6fcb31f5075edc5fc70c63426b2aef91352ca80f") (:authors ("Wilfred Hughes" . "me@wilfred.me.uk")) (:maintainer "Wilfred Hughes" . "me@wilfred.me.uk") (:keywords "convenience" "mustache" "template") (:url . "https://github.com/Wilfred/mustache.el"))])
+ (mustache-mode . [(20141024 1432) nil "A major mode for editing Mustache files." single ((:commit . "bf9897eb287ca47ced65d7d4e07ea61ea0aec39f") (:authors ("Tony Gentilcore") ("Chris Wanstrath") ("Daniel Hackney")) (:maintainer "Tony Gentilcore"))])
+ (mustang-theme . [(20170719 946) nil "port of vim's mustang theme" single ((:commit . "dda6d04803f1c9b196b620ef564e7768fee15de2") (:authors ("martin haesler")) (:maintainer "martin haesler") (:url . "http://github.com/mswift42/mustang-theme"))])
+ (mustard-theme . [(20170808 1319) ((emacs (24 0))) "an Emacs 24 theme based on Mustard (tmTheme)" single ((:commit . "3b15d992c79590d7ea2503004e2a863b57e274b5") (:authors ("Jason Milkins")) (:maintainer "Jason Milkins") (:url . "https://github.com/emacsfodder/tmtheme-to-deftheme"))])
+ (mutant . [(20160124 1353) ((emacs (24 4)) (dash (2 1 0))) "An interface for the Mutant testing tool" single ((:commit . "de9cdefe48c880128a8f62c6699d7416e9c8ced1") (:authors ("Pedro Lambert")) (:maintainer "Pedro Lambert") (:keywords "mutant" "testing") (:url . "http://github.com/p-lambert/mutant.el"))])
+ (mutt-mode . [(20191102 2330) ((emacs (24))) "major mode for editing mutt configuration" single ((:commit . "1d495de49e6f536459b00d5396a2f5ce5ad4757b") (:authors ("Felix Weilbach" . "felix.weilbach@t-online.de")) (:maintainer "Felix Weilbach" . "felix.weilbach@t-online.de") (:keywords "languages") (:url . "https://gitlab.com/flexw/mutt-mode"))])
+ (mvn . [(20181002 1617) nil "helpers for compiling with maven" single ((:commit . "223723d9ceeb2878b884e83abb8ca74ad2e42081") (:authors ("Andrew Gwozdziewycz" . "git@apgwoz.com")) (:maintainer "Andrew Gwozdziewycz" . "git@apgwoz.com") (:keywords "compilation" "maven" "java") (:url . "https://github.com/apgwoz/mvn-el"))])
+ (mw-thesaurus . [(20210224 449) ((emacs (25)) (request (0 3 0)) (dash (2 16 0))) "Merriam-Webster Thesaurus" single ((:commit . "96f02694bc28f31c2a280a05d47e6ff589f525f3") (:authors ("Ag Ibragimov")) (:maintainer "Ag Ibragimov") (:keywords "wp" "matching") (:url . "https://github.com/agzam/mw-thesaurus.el"))])
+ (mwim . [(20181110 1900) nil "Switch between the beginning/end of line or code" single ((:commit . "b4f3edb4c0fb8f8b71cecbf8095c2c25a8ffbf85") (:authors ("Alex Kost" . "alezost@gmail.com")) (:maintainer "Alex Kost" . "alezost@gmail.com") (:keywords "convenience") (:url . "https://github.com/alezost/mwim.el"))])
+ (mxf-view . [(20180501 740) ((emacs (25))) "Simple MXF viewer" single ((:commit . "6ca3cc93d995fac5fc4d72275e1e984e9857ffcb") (:authors ("Tomotaka SUWA" . "tomotaka.suwa@gmail.com")) (:maintainer "Tomotaka SUWA" . "tomotaka.suwa@gmail.com") (:keywords "data" "multimedia") (:url . "https://github.com/t-suwa/mxf-view"))])
+ (myanmar-input-methods . [(20160106 1537) nil "Emacs Input Method for Myanmar" single ((:commit . "9d4e0d6358c61bde7a2274e430ef71683faea32e") (:authors ("Ye Lin Kyaw" . "yelinkyaw@gmail.com")) (:maintainer "Ye Lin Kyaw" . "yelinkyaw@gmail.com") (:keywords "myanmar" "unicode" "keyboard") (:url . "http://github.com/yelinkyaw/emacs-myanmar-input-methods"))])
+ (mybigword . [(20201030 1253) ((emacs (25 1))) "Vocabulary builder using Zipf to extract English big words" tar ((:commit . "4c1386252444df2ade734e02078069a06f3f0f97") (:authors ("Chen Bin <chenbin DOT sh AT gmail.com>")) (:maintainer "Chen Bin <chenbin DOT sh AT gmail.com>") (:keywords "convenience") (:url . "https://github.com/redguardtoo/mybigword"))])
+ (mykie . [(20150808 2205) ((emacs (24 3)) (cl-lib (0 5))) "Command multiplexer: Register multiple functions to a keybind" tar ((:commit . "7676f0e883af1d1054e404e97691f3c13aba196f") (:authors ("Yuta Yamada <cokesboy\"at\"gmail.com>")) (:maintainer "Yuta Yamada <cokesboy\"at\"gmail.com>") (:keywords "emacs" "configuration" "keybind") (:url . "https://github.com/yuutayamada/mykie-el"))])
+ (mynt-mode . [(20150512 2049) ((virtualenvwrapper (20131514))) "Minor mode to work with the mynt static site generator" single ((:commit . "23d4489167bfa899634548cb41ed32fdeb3600c9") (:authors ("Christian Brassat")) (:maintainer "Christian Brassat") (:keywords "convenience") (:url . "https://github.com/crshd/mynt-mode"))])
+ (myrddin-mode . [(20191225 2120) ((emacs (24 3))) "Major mode for editing Myrddin source files" single ((:commit . "51c0a2cb9dfc9526cd47e71313f5a745c99cadcc") (:authors ("Jakob L. Kreuze" . "zerodaysfordays@sdf.lonestar.org")) (:maintainer "Jakob L. Kreuze" . "zerodaysfordays@sdf.lonestar.org") (:keywords "languages") (:url . "https://git.sr.ht/~jakob/myrddin-mode"))])
+ (mysql-to-org . [(20210622 447) ((emacs (24 3)) (s (1 11 0))) "Minor mode to output the results of mysql queries to org tables" single ((:commit . "c5eefc71200f2e1d0d67a13ed897b3cdfa835117") (:authors ("Tijs Mallaerts" . "tijs.mallaerts@gmail.com")) (:maintainer "Tijs Mallaerts" . "tijs.mallaerts@gmail.com"))])
+ (myterminal-controls . [(20210904 516) ((emacs (24)) (cl-lib (0 5))) "Quick toggle controls at a key-stroke" single ((:commit . "c635868e13ee898ec77925d98b36421640e22aa4") (:authors ("Mohammed Ismail Ansari" . "team.terminal@gmail.com")) (:maintainer "Mohammed Ismail Ansari" . "team.terminal@gmail.com") (:keywords "convenience" "shortcuts") (:url . "http://ismail.teamfluxion.com"))])
+ (n4js . [(20150714 231) ((emacs (24)) (cypher-mode (0))) "Neo4j Shell" single ((:commit . "3991ed8975151d5e8d568e952362df810f7ffab7") (:authors ("TruongTx" . "me@truongtx.me")) (:maintainer "TruongTx" . "me@truongtx.me") (:keywords "neo4j" "shell" "comint") (:url . "https://github.com/tmtxt/n4js.el"))])
+ (name-this-color . [(20151014 2030) ((emacs (24)) (cl-lib (0 5)) (dash (2 11 0))) "Match RGB codes to names easily and precisely" single ((:commit . "e37cd1291d5d68d4c8d6386eab9cb9d94fd3bcfa") (:keywords "lisp" "color" "hex" "rgb" "shade" "name") (:url . "https://github.com/knl/name-this-color.el"))])
+ (named-timer . [(20181120 2224) ((emacs (24 4))) "Simplified timer management for Emacs Lisp" single ((:commit . "d8baeada19b56176c66aed5fa220751e3de11cb8") (:authors ("Ryan C. Thompson")) (:maintainer "Ryan C. Thompson") (:keywords "tools") (:url . "https://github.com/DarwinAwardWinner/emacs-named-timer"))])
+ (nameframe . [(20171107 56) nil "Manage frames by name." single ((:commit . "aafb8c5c5fbe0510e2f5d5b6b6b5dd0b73abe5d8") (:authors ("John Del Rosario" . "john2x@gmail.com")) (:maintainer "John Del Rosario" . "john2x@gmail.com") (:url . "https://github.com/john2x/nameframe"))])
+ (nameframe-perspective . [(20170406 119) ((nameframe (0 4 1 -2)) (perspective (1 12))) "Nameframe integration with perspective.el" single ((:commit . "aafb8c5c5fbe0510e2f5d5b6b6b5dd0b73abe5d8") (:authors ("John Del Rosario" . "john2x@gmail.com")) (:maintainer "John Del Rosario" . "john2x@gmail.com") (:url . "https://github.com/john2x/nameframe"))])
+ (nameframe-projectile . [(20160928 403) ((nameframe (0 4 1 -2)) (projectile (0 13 0))) "Nameframe integration with Projectile" single ((:commit . "aafb8c5c5fbe0510e2f5d5b6b6b5dd0b73abe5d8") (:authors ("John Del Rosario" . "john2x@gmail.com")) (:maintainer "John Del Rosario" . "john2x@gmail.com") (:url . "https://github.com/john2x/nameframe"))])
+ (nameless . [(20190429 1202) ((emacs (24 4))) "Hide package namespace in your emacs-lisp code" single ((:commit . "a3a1ce3ec0c5724bcbfe553d831bd4f6b3fe863a") (:authors ("Artur Malabarba" . "emacs@endlessparentheses.com")) (:maintainer "Artur Malabarba" . "emacs@endlessparentheses.com") (:keywords "convenience" "lisp") (:url . "https://github.com/Malabarba/nameless"))])
+ (names . [(20180321 1155) ((emacs (24 1)) (cl-lib (0 5))) "Namespaces for emacs-lisp. Avoid name clobbering without hiding symbols." tar ((:commit . "d8baba5360e5253938a25d3e005455b6d2d86971") (:authors ("Artur Malabarba" . "emacs@endlessparentheses.com")) (:maintainer "Artur Malabarba" . "emacs@endlessparentheses.com") (:keywords "extensions" "lisp") (:url . "https://github.com/Malabarba/names"))])
+ (namespaces . [(20130326 2250) nil "An implementation of namespaces for Elisp, with an emphasis on immutabilty." single ((:commit . "3d02525d9b9a5ae6e7be3adefd880121436e6270") (:authors ("Chris Barrett")) (:maintainer "Chris Barrett") (:url . "https://github.com/chrisbarrett/elisp-namespaces"))])
+ (nand2tetris . [(20171201 1813) ((emacs (24))) "Major mode for HDL files in the nand2tetris course" tar ((:commit . "33acee34d24b1c6a87db833b7d23449cf858f64f") (:authors ("Diego Berrocal" . "cestdiego@gmail.com")) (:maintainer "Diego Berrocal" . "cestdiego@gmail.com") (:keywords "nand2tetris" "hdl") (:url . "http://www.github.com/CestDiego/nand2tetris.el/"))])
+ (nand2tetris-assembler . [(20171201 1813) ((nand2tetris (1 1 0))) "Assembler For the Nand2tetris Course" single ((:commit . "33acee34d24b1c6a87db833b7d23449cf858f64f") (:authors ("Diego Berrocal" . "cestdiego@gmail.com")) (:maintainer "Diego Berrocal" . "cestdiego@gmail.com") (:keywords "nand2tetris-assembler" "hdl") (:url . "http://www.github.com/CestDiego/nand2tetris-assembler.el/"))])
+ (nanowrimo . [(20151105 228) nil "Track progress for nanowrimo" single ((:commit . "b1d41458926ccb39cefbb1bb74aefe4f02fd349f") (:authors ("Ivan Andrus <darthandrus at gmail.com>")) (:maintainer "Ivan Andrus <darthandrus at gmail.com>") (:url . "https://bitbucket.org/gvol/nanowrimo-mode"))])
+ (naquadah-theme . [(20190225 1427) nil "A theme based on Tango color set" single ((:commit . "430c3b7bd51922cb616b3f60301f4e2604816ed8"))])
+ (narrow-reindent . [(20150722 1906) ((emacs (24 4))) "Defines a minor mode to left-align narrowed regions." single ((:commit . "87466aac4dbeb79597124dd077bf5c704872fd3d") (:authors ("J David Smith" . "emallson@atlanis.net")) (:maintainer "J David Smith" . "emallson@atlanis.net") (:url . "https://github.com/emallson/narrow-reindent.el"))])
+ (narrowed-page-navigation . [(20150109 519) ((emacs (24)) (cl-lib (0 5))) "A minor mode for showing one page at a time" single ((:commit . "b215adbac4873f56fbab65772062f0f5be8058a1") (:authors ("David Raymond Christiansen" . "david@davidchristiansen.dk")) (:maintainer "David Raymond Christiansen" . "david@davidchristiansen.dk") (:keywords "outlines"))])
+ (narumi . [(20220228 243) ((emacs (26 1))) "A dashboard that displays a ramdom sampled image" single ((:commit . "5bfb114adc0e6a2d5aebcd6335d1e6850e3f9722") (:url . "https://github.com/nryotaro/narumi"))])
+ (nash-mode . [(20160830 1212) nil "Nash major mode" single ((:commit . "2cd96535eb7d669a94306183e95ee37333872c1a") (:authors ("Tiago Natel de Moura")) (:maintainer "Tiago Natel de Moura") (:keywords "nash" "languages") (:url . "https://github.com/tiago4orion/nash-mode.el"))])
+ (nasm-mode . [(20190410 342) ((emacs (24 3))) "NASM x86 assembly major mode" single ((:commit . "65ca6546fc395711fac5b3b4299e76c2303d43a8") (:authors ("Christopher Wellons" . "wellons@nullprogram.com")) (:maintainer "Christopher Wellons" . "wellons@nullprogram.com") (:url . "https://github.com/skeeto/nasm-mode"))])
+ (native-complete . [(20220124 1806) ((emacs (26 1))) "Shell completion using native complete mechanisms" single ((:commit . "01d8a2048e13f29dd3aa06281ac8cb466caddb64") (:authors ("Troy Hinckley" . "troy.hinckley@gmail.com")) (:maintainer "Troy Hinckley" . "troy.hinckley@gmail.com") (:url . "https://github.com/CeleritasCelery/emacs-native-shell-complete"))])
+ (nav . [(20120507 707) nil "Emacs mode for filesystem navigation" tar ((:commit . "c5eb234c063f435dbdcd1f8bdc46cfc68c973ebe") (:authors ("Issac Trotts" . "issactrotts@google.com")) (:maintainer "Issac Trotts" . "issactrotts@google.com"))])
+ (nav-flash . [(20210906 1942) nil "Briefly highlight the current line" single ((:commit . "2e31f32085757e1dfdd8ec78e9940fd1c88750de") (:authors ("Roland Walker" . "walker@pobox.com")) (:maintainer "Roland Walker" . "walker@pobox.com") (:keywords "extensions" "navigation" "interface") (:url . "http://github.com/rolandwalker/nav-flash"))])
+ (navi-mode . [(20201220 1727) ((outshine (2 0)) (outorg (2 0))) "major-mode for easy buffer-navigation" single ((:commit . "cf97e1e338815ad3a4d0bbbf4ff6dd1a4e322ca8") (:maintainer "Adam Porter" . "adam@alphapapa.net") (:url . "https://github.com/alphapapa/navi"))])
+ (navi2ch . [(20200130 36) nil "Navigator for 2ch for Emacsen" tar ((:commit . "7811dba052f679bd920a1f648d621a6fecace10f") (:authors ("Taiki SUGAWARA" . "taiki@users.sourceforge.net")) (:maintainer "Taiki SUGAWARA" . "taiki@users.sourceforge.net") (:keywords "network" "2ch"))])
+ (navigel . [(20200202 1214) ((emacs (25 1)) (tablist (1 0))) "Facilitate the creation of tabulated-list based UIs" single ((:commit . "0a2d624d6b49f8363badc5ba8699b7028ef85632") (:authors ("Damien Cassou" . "damien@cassou.me")) (:maintainer "Damien Cassou" . "damien@cassou.me") (:url . "https://gitlab.petton.fr/DamienCassou/navigel"))])
+ (navorski . [(20141203 1824) ((s (1 9 0)) (dash (1 5 0)) (multi-term (0 8 14))) "Helping you live in the terminal, like Viktor did." single ((:commit . "698c1c62da70164aebe9a7a5d034778fbc30ea5b") (:authors ("Roman Gonzalez <romanandreg@gmail.com>, Tavis Rudd" . "tavis@birdseye-sw.com")) (:maintainer "Roman Gonzalez" . "romanandreg@gmail.com") (:keywords "terminal"))])
+ (naysayer-theme . [(20200405 123) ((emacs (24))) "The naysayer color theme" single ((:commit . "9d0bef898f31368cd30e063d53d443dee29683b0") (:authors ("Nick Aversano" . "nickav@users.noreply.github.com")) (:maintainer "Nick Aversano" . "nickav@users.noreply.github.com") (:url . "https://github.com/nickav/naysayer-theme.el"))])
+ (ncl-mode . [(20180129 703) ((emacs (24))) "Major Mode for editing NCL scripts and other goodies" tar ((:commit . "602292712a9e6b7e7c25155978999e77d06b7338") (:authors ("Yagnesh Raghava Yakkala" . "hi@yagnesh.org")) (:maintainer "Yagnesh Raghava Yakkala" . "hi@yagnesh.org") (:keywords "ncl" "major mode" "ncl-mode" "atmospheric science.") (:url . "https://github.com/yyr/ncl-mode"))])
+ (nclip . [(20130617 2015) nil "Network (HTTP) Clipboard" tar ((:commit . "af88e38b1f04be02bf2e57affc662dbd0f828e67") (:authors ("Marian Schubert" . "marian.schubert@gmail.com")) (:maintainer "Marian Schubert" . "marian.schubert@gmail.com") (:keywords "nclip" "clipboard" "network") (:url . "http://www.github.com/maio/nclip.el"))])
+ (neato-graph-bar . [(20181130 1649) ((emacs (24 3))) "Neat-o graph bars CPU/memory etc." single ((:commit . "a7ae35afd67911e8924f36e646bce0d3e3c1bbe6") (:authors ("Robert Cochran" . "robert-git@cochranmail.com")) (:maintainer "Robert Cochran" . "robert-git@cochranmail.com") (:url . "https://gitlab.com/RobertCochran/neato-graph-bar"))])
+ (neil . [(20220501 2053) ((emacs (27 1))) "companion for Babashka Neil" single ((:commit . "239c16655431b27ee558bf250bece4f4b10a0e83") (:authors ("Ag Ibragimov" . "agzam.ibragimov@gmail.com")) (:maintainer "Ag Ibragimov" . "agzam.ibragimov@gmail.com") (:keywords "convenience" "tools") (:url . "https://github.com/babashka/neil"))])
+ (nemerle . [(20161029 2023) nil "major mode for editing nemerle programs" single ((:commit . "db4bc9078f1b6238da32df1519c1957e74b6834a") (:authors ("Jacek Sliwerski (rzyjontko)" . "rzyj@o2.pl")) (:maintainer "Jacek Sliwerski (rzyjontko)" . "rzyj@o2.pl") (:keywords "nemerle" "mode" "languages"))])
+ (neon-mode . [(20180406 1156) nil "Simple major mode for editing neon files" single ((:commit . "99d15e46beaf1e7d71e39a00cce810df1f33229d") (:authors ("Matúš Goljer" . "matus.goljer@gmail.com")) (:maintainer "Matúš Goljer" . "matus.goljer@gmail.com") (:keywords "conf"))])
+ (neotree . [(20200324 1946) ((cl-lib (0 5))) "A tree plugin like NerdTree for Vim" tar ((:commit . "98fe21334affaffe2334bf7c987edaf1980d2d0b") (:authors ("jaypei" . "jaypei97159@gmail.com")) (:maintainer "jaypei" . "jaypei97159@gmail.com") (:url . "https://github.com/jaypei/emacs-neotree"))])
+ (nerdtab . [(20180811 339) ((emacs (24 5))) "Keyboard-oriented tabs" single ((:commit . "74ccc14d7956712e477a34b4a733284e8b3832a6") (:authors ("Yuan Fu" . "casouri@gmail.com")) (:maintainer "Yuan Fu" . "casouri@gmail.com") (:keywords "convenience") (:url . "https://github.com/casouri/nerdtab"))])
+ (netease-cloud-music . [(20220305 1224) ((emacs (27 1)) (request (0 3 3))) "Netease Cloud Music client" tar ((:commit . "f238d1d45bbeee32e0a8d169f39de4360be908f4") (:authors ("SpringHan")) (:maintainer "SpringHan") (:keywords "multimedia") (:url . "https://github.com/SpringHan/netease-cloud-music.git"))])
+ (netease-music . [(20210411 603) ((names (0 5)) (emacs (25))) "listen netease music" single ((:commit . "db7f1eef2d8544983509db679be1cbe6a5678071") (:authors ("hiro方圆" . "wfy11235813@gmail.com")) (:maintainer "hiro方圆" . "wfy11235813@gmail.com") (:keywords "multimedia" "chinese" "music") (:url . "https://github.com/nicehiro/netease-music"))])
+ (netherlands-holidays . [(20150202 1617) nil "Netherlands holidays for Emacs calendar." single ((:commit . "26236178cdd650df9958bf5a086e184096559f00") (:authors ("Oleh Krehel" . "ohwoeowho@gmail.com")) (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com") (:keywords "calendar") (:url . "https://github.com/abo-abo/netherlands-holidays"))])
+ (netrunner . [(20160910 2332) ((popup (0 5 3)) (company (0 9 0)) (helm (1 9 5))) "Create Android: Netrunner decklists using Company, Helm and org-mode" single ((:commit . "c64672992175c8c1073c0f56c2e471839db71a0f") (:authors ("Erik Sjöstrand")) (:maintainer "Erik Sjöstrand") (:keywords "games") (:url . "http://github.com/Kungsgeten/netrunner"))])
+ (network-watch . [(20171123 1146) ((emacs (24 3))) "Support for intermittent network connectivity" single ((:commit . "958dd0d419e4f9402648a86b754091ba346e01b8") (:authors ("Juan Amiguet Vercher" . "jamiguet@gmail.com")) (:maintainer "Juan Amiguet Vercher" . "jamiguet@gmail.com") (:keywords "unix" "tools" "hardware" "lisp") (:url . "https://github.com/jamiguet/network-watch"))])
+ (neuron-mode . [(20210227 1737) ((emacs (26 3)) (f (0 20 0)) (s (1 12 0)) (markdown-mode (2 3)) (company (0 9 13))) "Major mode for editing zettelkasten notes using neuron" single ((:commit . "a968a923aad07ab15fb35deb79ac95581a427b4c") (:authors ("felko <http://github/felko>")) (:maintainer "felko <http://github/felko>") (:keywords "outlines") (:url . "https://github.com/felko/neuron-mode"))])
+ (never-comment . [(20140104 2207) nil "Never blocks are comment" single ((:commit . "74ded8f1e7f23240f5f6032d0451fb0a51733bc4") (:authors ("Scott Frazer")) (:maintainer "Toon Claes") (:url . "http://stackoverflow.com/a/4554658/89376"))])
+ (newlisp-mode . [(20160226 1545) nil "newLISP editing mode for Emacs" single ((:commit . "ac23be40c81a360988ab803d365f1510733f6db4") (:authors ("KOBAYASHI Shigeru <shigeru.kb[at]gmail.com>")) (:maintainer "KOBAYASHI Shigeru <shigeru.kb[at]gmail.com>") (:keywords "language" "lisp" "newlisp") (:url . "https://github.com/kosh04/newlisp-mode"))])
+ (newspeak-mode . [(20211011 1425) ((emacs (24 3))) "Major mode for the Newspeak programming language" single ((:commit . "7ae89edd0f72c2dc005933fada5ddaf48ec97dd6") (:authors ("Daniel Szmulewicz")) (:maintainer "Daniel Szmulewicz" . "daniel.szmulewicz@gmail.com") (:url . "https://github.com/danielsz/newspeak-mode"))])
+ (nexus . [(20210903 1743) nil "REST Client for Nexus Maven Repository servers" tar ((:commit . "9603fd3d8ef34d4b3dcad3292c4ac743500d4946") (:authors ("Juergen Hoetzel" . "juergen@archlinux.org")) (:maintainer "Juergen Hoetzel" . "juergen@archlinux.org") (:keywords "comm"))])
+ (ng2-mode . [(20201203 1925) ((typescript-mode (0 1))) "Major modes for editing Angular 2" tar ((:commit . "d341f177c6e4fb9d99b8639943ab5fc9184e2715") (:authors ("Adam Niederer" . "adam.niederer@gmail.com")) (:maintainer "Adam Niederer" . "adam.niederer@gmail.com") (:keywords "typescript" "angular" "angular2" "template") (:url . "http://github.com/AdamNiederer/ng2-mode"))])
+ (nginx-mode . [(20170612 437) nil "major mode for editing nginx config files" single ((:commit . "6e9d96f58eddd69f62f7fd443d9b9753e16e0e96") (:authors ("Andrew J Cosgriff" . "andrew@cosgriff.name")) (:maintainer "Andrew J Cosgriff" . "andrew@cosgriff.name") (:keywords "languages" "nginx"))])
+ (niceify-info . [(20160416 1244) nil "improve usability of Info pages" single ((:commit . "38df5062bc3b99d1074cab3e788b5ed66732111c"))])
+ (niconama . [(20170910 1501) ((emacs (24)) (request (20170131 1747)) (cl-lib (0 5))) "Tools for Niconico Live Broadcast" single ((:commit . "96e7553e50e6bf7b58aac50f52c9b0b8edb41c56") (:keywords "comm") (:url . "https://github.com/NOBUTOKA/niconama.el"))])
+ (night-owl-theme . [(20200622 1943) ((emacs (24))) "A color theme for the night owls out there" single ((:commit . "4b9b5cb4fead9c5f145ba399d172c7e6bf577121") (:authors ("Aaron Jensen" . "aaronjensen@gmail.com")) (:maintainer "Aaron Jensen" . "aaronjensen@gmail.com") (:url . "http://github.com/aaronjensen/night-owl-theme"))])
+ (nikki . [(20210227 1707) ((emacs (24 3))) "A simple diary mode" single ((:commit . "b2ea20d04a061df88d72bd8dd0412a6e7876458d") (:authors ("Taiki Harada" . "thdev994@gmail.com")) (:maintainer "Taiki Harada" . "thdev994@gmail.com") (:keywords "convenience") (:url . "https://github.com/th994/nikki"))])
+ (nikola . [(20170703 2021) ((async (1 5)) (emacs (24 3))) "Simple wrapper for nikola" single ((:commit . "964715ac30943c9d6976999cad208dc60d09def0") (:authors (": drymer <drymer [ AT ] autistici.org>")) (:maintainer ": drymer <drymer [ AT ] autistici.org>") (:keywords ":" "nikola") (:url . ": https://git.daemons.it/drymer/nikola.el"))])
+ (nim-mode . [(20211102 917) ((emacs (24 4)) (epc (0 1 1)) (let-alist (1 0 1)) (commenter (0 5 1)) (flycheck-nimsuggest (0 8 1))) "A major mode for the Nim programming language" tar ((:commit . "744e076f0bea1c5ddc49f92397d9aa98ffa7eff8") (:authors ("Simon Hafner")) (:maintainer "Simon Hafner" . "hafnersimon@gmail.com") (:keywords "nim" "languages"))])
+ (nimbus-theme . [(20220106 2017) ((emacs (24 1))) "An awesome dark theme" single ((:commit . "f9bcec4ce0f6cd656a56034ace7811dea769a7bb") (:authors ("Marcin Swieczkowski" . "marcin.swieczkowski@gmail.com") ("See README.md for full list of contributors.")) (:maintainer "Marcin Swieczkowski" . "marcin.swieczkowski@gmail.com") (:keywords "faces") (:url . "https://github.com/m-cat/nimbus-theme"))])
+ (ninja-mode . [(20181024 1439) ((emacs (24))) "Major mode for editing .ninja files" single ((:commit . "7905dee5ac62f7a1e0dfec4d936b97d96c7566d7"))])
+ (nix-buffer . [(20180212 1518) ((f (0 17 3)) (emacs (24 4))) "Set up buffer environments with nix" single ((:commit . "db57cda36e7477bdc7ef5a136357b971b1d4d099") (:authors ("Shea Levy")) (:maintainer "Shea Levy") (:url . "https://github.com/shlevy/nix-buffer/tree/master/"))])
+ (nix-env-install . [(20200812 1305) ((emacs (25 1))) "Install packages using nix-env" single ((:commit . "79c34bc117ba1cebeb67fab32c364951d2ec37a0") (:authors ("Akira Komamura" . "akira.komamura@gmail.com")) (:maintainer "Akira Komamura" . "akira.komamura@gmail.com") (:keywords "processes" "tools") (:url . "https://github.com/akirak/nix-env-install"))])
+ (nix-haskell-mode . [(20190615 135) ((emacs (25)) (haskell-mode (16 0)) (nix-mode (1 3 0))) "haskell-mode integrations for Nix" single ((:commit . "68efbcbf949a706ecca6409506968ed2ef928a20") (:authors ("Matthew Bauer" . "mjbauer95@gmail.com")) (:maintainer "Matthew Bauer" . "mjbauer95@gmail.com") (:keywords "nix" "haskell" "languages" "processes") (:url . "https://github.com/matthewbauer/nix-haskell"))])
+ (nix-mode . [(20220422 451) ((emacs (25 1)) (magit-section (0)) (transient (0 3))) "Major mode for editing .nix files" tar ((:commit . "66206cab276c0f4d1c84e77ba2a67ed6a46b2d9c") (:maintainer "Matthew Bauer" . "mjbauer95@gmail.com") (:keywords "nix" "languages" "tools" "unix") (:url . "https://github.com/NixOS/nix-mode"))])
+ (nix-modeline . [(20210405 742) ((emacs (25 1))) "Info about in-progress Nix evaluations on your modeline" single ((:commit . "ecda866b960321bb82deac26af45918e172ef0ba") (:authors ("Jordan Mulcahey" . "snhjordy@gmail.com")) (:maintainer "Jordan Mulcahey" . "snhjordy@gmail.com") (:keywords "processes" "unix" "tools") (:url . "https://github.com/ocelot-project/nix-modeline"))])
+ (nix-sandbox . [(20210325 1622) ((dash (2 12 1)) (s (1 10 0))) "Utility functions to work with nix-shell sandboxes" single ((:commit . "053a2d5110ce05b7f99bcc2ac4804b70cbe87916") (:authors ("Sven Keidel" . "svenkeidel@gmail.com")) (:maintainer "Sven Keidel" . "svenkeidel@gmail.com") (:url . "https://github.com/travisbhartwell/nix-emacs"))])
+ (nix-update . [(20190124 1935) ((emacs (25))) "Update \"fetch\" blocks in .nix expressions" single ((:commit . "fc6c39c2da3fcfa62f4796816c084a6389c8b6e7") (:authors ("John Wiegley" . "johnw@newartisans.com")) (:maintainer "John Wiegley" . "johnw@newartisans.com") (:keywords "nix") (:url . "https://github.com/jwiegley/nix-update-el"))])
+ (nixos-options . [(20160209 1841) ((emacs (24))) "Interface for browsing and completing NixOS options." single ((:commit . "053a2d5110ce05b7f99bcc2ac4804b70cbe87916") (:authors ("Diego Berrocal" . "cestdiego@gmail.com") ("Travis B. Hartwell" . "nafai@travishartwell.net")) (:maintainer "Diego Berrocal" . "cestdiego@gmail.com") (:keywords "unix") (:url . "http://www.github.com/travisbhartwell/nix-emacs/"))])
+ (nixpkgs-fmt . [(20200327 2302) ((emacs (24)) (reformatter (0 3))) "Reformat Nix using nixpkgs-fmt" single ((:commit . "487b8e26c1ea816894c590790978762daf2ee339") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:keywords "languages") (:url . "https://github.com/purcell/emacs-nixpkgs-fmt"))])
+ (nlinum-hl . [(20211112 1241) ((emacs (24 4)) (nlinum (1 7)) (cl-lib (0 5))) "heal nlinum's line numbers" single ((:commit . "22f8d75ecdaab67e0d6d0d2da4766358456ca4f5") (:authors ("Henrik Lissner <http://github/hlissner>")) (:maintainer "Henrik Lissner" . "git@henrik.io") (:keywords "nlinum" "highlight" "current" "line" "faces") (:url . "https://github.com/hlissner/emacs-nlinum-hl"))])
+ (nlinum-relative . [(20160526 708) ((emacs (24 4)) (nlinum (1 5))) "Relative line number with nlinum" single ((:commit . "5b9950c97ba79a6f0683e38b13da23f39e01031c") (:authors ("codefalling" . "code.falling@gmail.com")) (:maintainer "codefalling" . "code.falling@gmail.com") (:keywords "convenience"))])
+ (nndiscourse . [(20220210 1529) ((emacs (25 1)) (dash (2 18 1)) (anaphora (1 0 4)) (rbenv (0 0 3)) (json-rpc (0 0 1))) "Gnus backend for Discourse" tar ((:commit . "1b7d7bfc99b104b7c4948af9f3394b416105e9d9") (:keywords "news") (:url . "https://github.com/dickmao/nndiscourse"))])
+ (nnhackernews . [(20220107 1537) ((emacs (25 2)) (request (0 3 3)) (dash (2 18 1)) (anaphora (1 0 4))) "Gnus backend for Hacker News" single ((:commit . "6748065db2f12ae6ea07058e7d643f586fb4b3bc") (:keywords "news") (:url . "https://github.com/dickmao/nnhackernews"))])
+ (nnir-est . [(20180710 2103) nil "Gnus nnir interface for HyperEstraier" single ((:commit . "6d0d5c8e33f4e4ccbc22350324c0990d2676fb5a") (:authors ("KAWABATA, Taichi <kawabata.taichi_at_gmail.com>")) (:maintainer "KAWABATA, Taichi <kawabata.taichi_at_gmail.com>") (:keywords "mail") (:url . "https://github.com/kawabata/nnir-est"))])
+ (nnreddit . [(20220423 2302) ((emacs (25 1)) (request (0 3 3)) (anaphora (1 0 4)) (dash (2 18 1)) (json-rpc (0 0 1)) (virtualenvwrapper (20151123)) (s (1 6 1))) "Gnus Backend For Reddit" tar ((:commit . "8f247dce12bd10de37f0903f3027a1ddbc318eff") (:keywords "news") (:url . "https://github.com/dickmao/nnreddit"))])
+ (nntwitter . [(20220213 1654) ((emacs (25 1)) (dash (20190401)) (anaphora (20180618)) (request (20190819))) "Gnus Backend For Twitter" tar ((:commit . "354781f9d2da04649823a6923ad372d801f10ca7") (:keywords "news") (:url . "https://github.com/dickmao/nntwitter"))])
+ (no-emoji . [(20180515 1837) ((emacs (24))) "Show :emoji-name: instead of emoji characters" single ((:commit . "ebceeab50dbfe4d60235180a57633745dbc18c77") (:authors ("Peter" . "craven@gmx.net")) (:maintainer "Peter" . "craven@gmx.net") (:keywords "extensions") (:url . "https://github.com/ecraven/no-emoji"))])
+ (no-littering . [(20220503 1654) ((emacs (25 1)) (compat (28 1 1 0))) "Help keeping ~/.emacs.d clean" single ((:commit . "27c713964c2b605931cdd691dc010de415b71d81") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:keywords "convenience") (:url . "https://github.com/emacscollective/no-littering"))])
+ (no-spam . [(20190724 1854) ((emacs (25 1))) "Add repeat delays to commands" single ((:commit . "860860e4a0d59bd15c8e092dc42f5f7f769a428e") (:authors ("Daniel Phan" . "daniel.phan36@gmail.com")) (:maintainer "Daniel Phan" . "daniel.phan36@gmail.com") (:keywords "keyboard" "tools") (:url . "https://github.com/mamapanda/no-spam"))])
+ (noaa . [(20220504 1857) ((emacs (27 1)) (request (0 2 0)) (dash (2 14 1))) "Get NOAA weather data" single ((:commit . "c1f24d46e08972b2be3912e41337eb630514ac06") (:authors ("David Thompson")) (:maintainer "David Thompson") (:keywords "calendar") (:url . "https://github.com/thomp/noaa"))])
+ (noccur . [(20191015 719) nil "Run multi-occur on project/dired files" single ((:commit . "fa91647a305e89561d3dbe53da002fff49abe0bb") (:authors ("Nicolas Petton" . "petton.nicolas@gmail.com")) (:maintainer "Nicolas Petton" . "petton.nicolas@gmail.com") (:keywords "convenience"))])
+ (nocomments-mode . [(20170213 2037) nil "Minor mode that makes comments invisible." single ((:commit . "5a41a20cc44dfe4a9ea584354ed6dbc15dd92f46") (:authors ("Anders Lindgren")) (:maintainer "Anders Lindgren") (:url . "https://github.com/Lindydancer/nocomments-mode"))])
+ (noctilux-theme . [(20161113 1442) ((emacs (24))) "Dark theme inspired by LightTable" single ((:commit . "a3265a1be7f4d73f44acce6d968ca6f7add1f2ca") (:authors ("Simon Manning" . "simon@ecksdee.org")) (:maintainer "Simon Manning" . "simon@ecksdee.org") (:url . "https://github.com/sjrmanning/noctilux-theme"))])
+ (node-resolver . [(20140930 1723) ((cl-lib (0 5))) "hook to install node modules in background" single ((:commit . "ef9d0486907a746a80b02ffc6208a09c168a9f7c") (:authors ("Dave Justice")) (:maintainer "Dave Justice") (:keywords "convenience" "nodejs" "javascript" "npm") (:url . "https://github.com/meandavejustice/node-resolver.el"))])
+ (nodejs-repl . [(20200802 1310) nil "Run Node.js REPL" single ((:commit . "3b841055cad00f442e4a9159b1056f59411b6646") (:authors ("Takeshi Arabiki")) (:maintainer "Takeshi Arabiki"))])
+ (nodemcu-mode . [(20180501 2225) ((emacs (25))) "Minor mode for NodeMCU" single ((:commit . "8effd9f3df40b6b92a2f05e4d54750b624afc4a7") (:authors ("Andreas Müller" . "code@0x7.ch")) (:maintainer "Andreas Müller" . "code@0x7.ch") (:keywords "tools") (:url . "https://github.com/andrmuel/nodemcu-mode"))])
+ (noflet . [(20141102 1454) nil "locally override functions" single ((:commit . "7ae84dc3257637af7334101456dafe1759c6b68a") (:authors ("Nic Ferrier" . "nferrier@ferrier.me.uk")) (:maintainer "Nic Ferrier" . "nferrier@ferrier.me.uk") (:keywords "lisp") (:url . "https://github.com/nicferrier/emacs-noflet"))])
+ (nofrils-acme-theme . [(20180620 1248) ((emacs (24))) "Port of \"No Frils Acme\" Vim theme." tar ((:commit . "98ad7bfaff1d85b33dc162645670285b067c6f92") (:authors ("Eric Sessoms" . "esessoms@protonmail.com")) (:maintainer "Eric Sessoms" . "esessoms@protonmail.com") (:url . "https://gitlab.com/esessoms/nofrils-theme"))])
+ (nord-theme . [(20200620 1122) ((emacs (24))) "An arctic, north-bluish clean and elegant theme" single ((:commit . "4f5b64605709d5803285953026137e905756c35f") (:authors ("Arctic Ice Studio" . "development@arcticicestudio.com")) (:maintainer "Arctic Ice Studio" . "development@arcticicestudio.com") (:url . "https://github.com/arcticicestudio/nord-emacs"))])
+ (nordless-theme . [(20201222 1627) ((colorless-themes (0 2))) "A mostly colorless version of nord-theme" single ((:commit . "c1ed1e12541cf05cc6c558d23c089c07e10b54d7") (:authors ("Thomas Letan" . "lthms@soap.coffee")) (:maintainer "Thomas Letan" . "lthms@soap.coffee") (:keywords "faces" "theme") (:url . "https://git.sr.ht/~lthms/colorless-themes.el"))])
+ (norns . [(20220422 2152) ((emacs (27 1)) (dash (2 17 0)) (s (1 12 0)) (f (0 20 0)) (request (0 3 2)) (websocket (1 13))) "Interactive development environment for monome norns" single ((:commit . "0eb487e15cf4aaaa30efde9068e205f014fd1dd2") (:keywords "processes" "terminals") (:url . "https://github.com/p3r7/norns.el"))])
+ (northcode-theme . [(20180423 1649) ((emacs (24))) "A dark theme focused on blue and orange colors." single ((:commit . "4d3750461ba25ec45321318b5f1af4e8fdf16147") (:authors ("Andreas Larsen" . "andreas@northcode.no")) (:maintainer "Andreas Larsen" . "andreas@northcode.no") (:url . "https://github.com/Northcode/northcode-theme.el"))])
+ (nothing-theme . [(20200504 402) ((emacs (24 1))) "Monochrome theme" single ((:commit . "d2514bb9707f66dda0d60f40f465e79914c50946") (:authors ("Jared Gorski," . "jaredgorski6@gmail.com")) (:maintainer "Jared Gorski," . "jaredgorski6@gmail.com") (:url . "https://github.com/jaredgorski/nothing.el"))])
+ (notink-theme . [(20220114 1955) ((emacs (26 1))) "A custom theme inspired by e-ink displays" single ((:commit . "6115857fe75c1adbbce4165a2b77a11a271aaf31") (:authors ("MetroWind" . "chris.corsair@gmail.com")) (:maintainer "MetroWind" . "chris.corsair@gmail.com") (:keywords "faces") (:url . "https://github.com/MetroWind/notink-theme"))])
+ (notmuch . [(20220226 1200) nil "run notmuch within emacs" tar ((:commit . "37492858b61907e4728b2e68e67238c68e9a0d49") (:url . "https://notmuchmail.org"))])
+ (notmuch-addr . [(20220422 1618) ((emacs (27 1)) (compat (28 1 1 0)) (notmuch (0 32))) "An alternative to notmuch-address.el" single ((:commit . "2e479851b5cb2d25c31f21b400cfd34777348874") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:keywords "mail") (:url . "https://git.sr.ht/~tarsius/notmuch-addr"))])
+ (notmuch-bookmarks . [(20200322 1925) ((seq (2 20)) (emacs (26 1)) (notmuch (0 29 3))) "Add bookmark handling for notmuch buffers" single ((:commit . "ec8edfdbd1ac475530591d73a570ded5c18ed86a") (:authors ("Jörg Volbers" . "joerg@joergvolbers.de")) (:maintainer "Jörg Volbers" . "joerg@joergvolbers.de") (:keywords "mail") (:url . "https://github.com/publicimageltd/notmuch-bookmarks"))])
+ (notmuch-labeler . [(20131230 1719) ((notmuch (0))) "Improve notmuch way of displaying labels" tar ((:commit . "d65d1129555d368243df4770ecc1e7ccb88efc58") (:authors ("Damien Cassou" . "damien.cassou@gmail.com")) (:maintainer "Damien Cassou" . "damien.cassou@gmail.com") (:keywords "emacs" "package" "elisp" "notmuch" "emails") (:url . "https://github.com/DamienCassou/notmuch-labeler"))])
+ (notmuch-maildir . [(20220422 1621) ((emacs (26 1)) (compat (28 1 1 0)) (notmuch (0 30))) "Visualize maildirs as a tree" single ((:commit . "f0dcfd755fe9e58652f0569e3c8641d38cd6dd4c") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:keywords "mail") (:url . "https://git.sr.ht/~tarsius/notmuch-maildir"))])
+ (notmuch-transient . [(20220503 1117) ((emacs (27 1)) (compat (28 1 1 0)) (notmuch (0 31 4))) "Command dispatchers for Notmuch" single ((:commit . "341fe7f05efe68460451bd5cb7151ca6d8b8cfc8") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:keywords "mail") (:url . "https://git.sr.ht/~tarsius/notmuch-transient"))])
+ (nov . [(20220428 1417) ((esxml (0 3 6)) (emacs (25 1))) "Featureful EPUB reader mode" single ((:commit . "8f5b42e9d9f304b422c1a7918b43ee323a7d3532") (:authors ("Vasilij Schneidermann" . "mail@vasilij.de")) (:maintainer "Vasilij Schneidermann" . "mail@vasilij.de") (:keywords "hypermedia" "multimedia" "epub") (:url . "https://depp.brause.cc/nov.el"))])
+ (nova-theme . [(20210512 1802) ((emacs (24 3))) "A dark, pastel color theme" single ((:commit . "1498f756a4c1c9ea9740cd3208f74d071283b930") (:authors ("Muir Manders" . "muir+emacs@mnd.rs")) (:maintainer "Muir Manders" . "muir+emacs@mnd.rs") (:keywords "theme" "dark" "nova" "pastel" "faces") (:url . "https://github.com/muirmanders/emacs-nova-theme"))])
+ (noxml-fold . [(20170823 1357) nil "Fold away XML things." single ((:commit . "46c7f6a008672213238a9f8d7a416ce80916aa62") (:authors ("Patrick McAllister" . "pma@rdorte.org")) (:maintainer "Patrick McAllister" . "pma@rdorte.org") (:keywords "xml" "folding") (:url . "https://github.com/paddymcall/noxml-fold"))])
+ (npm . [(20220428 839) ((emacs (25 1)) (transient (0 1 0)) (jest (20200625))) "Run your npm workflows" tar ((:commit . "6eb0a58274870dd75bf848cf5a916a9f2c6ddae5") (:authors ("Shane Kennedy")) (:maintainer "Shane Kennedy") (:keywords "tools") (:url . "https://github.com/shaneikennedy/npm.el"))])
+ (npm-mode . [(20190616 2025) ((emacs (24 1))) "minor mode for working with npm projects" single ((:commit . "3ee7c0bad5b7a041d4739ef3aaa06a3dc764e5eb") (:authors ("Allen Gooch" . "allen.gooch@gmail.com")) (:maintainer "Allen Gooch" . "allen.gooch@gmail.com") (:keywords "convenience" "project" "javascript" "node" "npm") (:url . "https://github.com/mojochao/npm-mode"))])
+ (nrepl-eval-sexp-fu . [(20201007 2311) ((highlight (0 0 0)) (smartparens (0 0 0)) (thingatpt (0 0 0))) "Tiny functionality enhancements for evaluating sexps." single ((:commit . "2d6ad728b1ba290974a2ae1f232a5a96810a135b") (:authors ("Takeshi Banse" . "takebi@laafc.net")) (:maintainer "Takeshi Banse" . "takebi@laafc.net") (:keywords "lisp" "highlight" "convenience"))])
+ (nrepl-sync . [(20140807 1554) ((cider (0 6))) "connect to nrepl port and eval .sync.clj." single ((:commit . "bab53a2361526d63a24cda176d07a1247bf5b399") (:authors ("Phillip Lord" . "phillip.lord@newcastle.ac.uk")) (:maintainer "Phillip Lord" . "phillip.lord@newcastle.ac.uk") (:url . "https://github.com/phillord/lein-sync"))])
+ (ns-auto-titlebar . [(20181022 2154) ((emacs (24 4))) "Set the MacOS transparent titlebar to match theme" single ((:commit . "60273e764bf8d95abc40dd2fdc23af87ea9ee33b") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:keywords "frames") (:url . "https://github.com/purcell/ns-auto-titlebar"))])
+ (nsis-mode . [(20190615 1827) nil "NSIS-mode" tar ((:commit . "0a2e6ece2fe682dced4d31688b38bb472a877cdf") (:authors ("Matthew L. Fidler")) (:maintainer "Matthew L. Fidler") (:keywords "nsis") (:url . "http://github.com/mlf176f2/nsis-mode"))])
+ (nswbuff . [(20220426 2050) ((emacs (25 1))) "Quick switching between buffers." single ((:commit . "7633674c89e3dbfc0c07cd7fd8b1d206ed4859d3") (:authors ("David Ponce" . "david@dponce.com") ("Kahlil (Kal) HODGSON" . "dorge@tpg.com.au") ("Joost Kremers" . "joostkremers@fastmail.fm")) (:maintainer "Joost Kremers" . "joostkremers@fastmail.fm") (:keywords "extensions" "convenience") (:url . "https://github.com/joostkremers/nswbuff"))])
+ (nu-mode . [(20190404 2032) ((undo-tree (0 6 5)) (ace-window (0)) (lv (0)) (avy (0)) (which-key (0)) (transpose-frame (0))) "Modern Emacs Prompts Based Keybinding." tar ((:commit . "d5fb4d26d1b0bb383ea2827cc5af5dfb2a269d2b"))])
+ (nubox . [(20170619 910) nil "Nubox color theme (dark, light and tty versions)" tar ((:commit . "1ccb8035ae42727ba6bdd5c1106fbceddeeed370") (:authors ("Martijn Terpstra" . "bigmartijn@gmail.com")) (:maintainer "Martijn Terpstra" . "bigmartijn@gmail.com") (:keywords "faces"))])
+ (number . [(20170901 1312) nil "Working with numbers at point." single ((:commit . "bbc278d34dbcca83e70e3be855ec98b23debfb99"))])
+ (number-lock . [(20160830 200) nil "Enter symbols on your number keys without pressing shift" single ((:commit . "74417b1238953bf485961a0dd7d20f5c36ae25ea") (:authors ("Liu233w" . "wwwlsmcom@outlook.com")) (:maintainer "Liu233w" . "wwwlsmcom@outlook.com") (:keywords "convenience") (:url . "https://github.com/Liu233w/number-lock.el"))])
+ (numbers . [(20170802 1134) ((emacs (24))) "Display information and trivia about numbers" single ((:commit . "dd02508b788a13b7d4dbcc4923fa23134b783ab3") (:authors ("Dave Pearson" . "davep@davep.org")) (:maintainer "Dave Pearson" . "davep@davep.org") (:keywords "games" "trivia" "maths" "numbers") (:url . "https://github.com/davep/numbers.el"))])
+ (numbex . [(20220504 1329) ((emacs (26 1))) "Manage numbered examples" single ((:commit . "55d4977c74ca33d1ad4c10fea7369f4bcdfd3f86") (:authors ("Enrico Flor" . "enrico@eflor.net")) (:maintainer "Enrico Flor" . "enrico@eflor.net") (:url . "https://github.com/enricoflor/numbex"))])
+ (nummm-mode . [(20131117 1014) nil "Display the number of minor modes instead of their names" single ((:commit . "81951e12032274543c5f7a585b29bd93961e94e4") (:authors ("Andreu Gil" . "agpchil@gmail.com")) (:maintainer "Andreu Gil" . "agpchil@gmail.com") (:url . "http://github.com/agpchil/nummm-mode"))])
+ (numpydoc . [(20220304 1546) ((emacs (25 1)) (s (1 12 0)) (dash (2 18 0))) "NumPy style docstring insertion" single ((:commit . "1b8c5ef3301fed5e5c1941817dbb7435188ff417") (:authors ("Doug Davis" . "ddavis@ddavis.io")) (:maintainer "Doug Davis" . "ddavis@ddavis.io") (:keywords "convenience") (:url . "https://github.com/douglasdavis/numpydoc.el"))])
+ (nv-delete-back . [(20170224 1249) ((emacs (24))) "backward delete like modern text editors" single ((:commit . "b17cb826f14c18c2875d112574edb5e4f46f5296") (:authors ("Nicolas Vaughan <n.vaughan [at] oxon.org>")) (:maintainer "Nicolas Vaughan <n.vaughan [at] oxon.org>") (:keywords "lisp"))])
+ (nvm . [(20210826 1000) ((s (1 8 0)) (dash (2 18 0)) (f (0 14 0))) "Manage Node versions within Emacs" single ((:commit . "c214762fd6f539ec3e1fd8198cefbdb4b428b19c") (:authors ("Johan Andersson" . "johan.rejeep@gmail.com")) (:maintainer "Johan Andersson" . "johan.rejeep@gmail.com") (:keywords "node" "nvm") (:url . "http://github.com/rejeep/nvm.el"))])
+ (nxml-uxml . [(20220130 1405) ((emacs (25))) "MicroXML support for nXML" single ((:commit . "94440741f7e8b83504d53991f26f63b4855cce27") (:authors ("Daphne Preston-Kendal")) (:maintainer "Daphne Preston-Kendal") (:keywords "languages" "xml" "microxml") (:url . "https://gitlab.com/dpk/nxml-uxml"))])
+ (nyan-mode . [(20220408 2334) ((emacs (24 1))) "Nyan Cat shows position in current buffer in mode-line" tar ((:commit . "09904af23adb839c6a9c1175349a1fb67f5b4370") (:authors ("Jacek \"TeMPOraL\" Zlydach" . "temporal.pl@gmail.com")) (:maintainer "Jacek \"TeMPOraL\" Zlydach" . "temporal.pl@gmail.com") (:keywords "convenience" "games" "mouse" "multimedia") (:url . "https://github.com/TeMPOraL/nyan-mode/"))])
+ (nyx-theme . [(20170910 1307) ((emacs (24))) "Dark theme" single ((:commit . "afe2b8c3b5421b4c292d182dcf77079b278e93d8") (:authors ("Guido Schmidt")) (:maintainer "Guido Schmidt" . "guido.schmidt.2912@gmail.com") (:keywords "themes" "dark-theme") (:url . "https://github.com/GuidoSchmidt/emacs-nyx-theme"))])
+ (nz-holidays . [(20190415 703) nil "New Zealand public holidays for calendar." single ((:commit . "afc875cf40789fa45a4a811685b0a7c4f239392f") (:authors ("Sod Oscarfono" . "sod@oscarfono.com")) (:maintainer "Sod Oscarfono" . "sod@oscarfono.com") (:keywords "calendar") (:url . "https://github.com/techquila/nz-holidays"))])
+ (oauth . [(20130128 151) nil "Oauth library." tar ((:commit . "ee4744ad76a1560281b0c4944575a3bd598c6458") (:authors ("Peter Sanford <peter AT petersdanceparty.com>")) (:maintainer "Peter Sanford <peter AT petersdanceparty.com>") (:keywords "comm"))])
+ (oauth2-request . [(20210215 657) ((emacs (26 1)) (oauth2 (0 14)) (request (0 3))) "OAuth2 request package interface" single ((:commit . "86ff048635e002b00e23d6bed2ec6f36c17bca8e") (:authors ("Naoya Yamashita" . "conao3@gmail.com")) (:maintainer "Naoya Yamashita" . "conao3@gmail.com") (:keywords "convenience") (:url . "https://github.com/conao3/oauth2-request.el"))])
+ (ob-ada-spark . [(20220401 926) ((emacs (26 1)) (f (0 20 0))) "Babel functions for Ada & SPARK" single ((:commit . "1213b877bc893ac5990a20052ea2bf2d8f086260") (:authors ("Francesc Rocher")) (:maintainer "Francesc Rocher") (:keywords "languages" "tools" "outlines") (:url . "https://github.com/rocher/ob-ada-spark"))])
+ (ob-applescript . [(20190709 1607) nil "Org-babel functions for AppleScript" single ((:commit . "2b07b77b75bd02f2102f62e6d52ffdd0f921439a") (:authors ("Stig Brautaset")) (:maintainer "Stig Brautaset") (:keywords "literate programming" "reproducible research" "mac") (:url . "http://github.com/stig/ob-applescript.el"))])
+ (ob-async . [(20210428 2052) ((async (1 9)) (org (9 0 1)) (emacs (24 4)) (dash (2 14 1))) "Asynchronous org-babel src block execution" single ((:commit . "9aac486073f5c356ada20e716571be33a350a982") (:authors ("Andrew Stahlman" . "andrewstahlman@gmail.com")) (:maintainer "Andrew Stahlman" . "andrewstahlman@gmail.com") (:keywords "tools") (:url . "https://github.com/astahlman/ob-async"))])
+ (ob-axiom . [(20190623 2052) ((emacs (24 2)) (axiom-environment (20171021))) "An org-babel backend for the axiom-environment system" single ((:commit . "e60de5ed107ffeb530a56d24d04f38988124d12b") (:authors ("Paul Onions")) (:maintainer "Paul Onions") (:keywords "axiom" "openaxiom" "fricas"))])
+ (ob-bitfield . [(20220401 600) ((emacs (24 4))) "Babel Functions for bitfield" single ((:commit . "28e01448ee66b8b6858294cad1b7dae0b9a85e6a") (:authors ("Gulshan Singh")) (:maintainer "Gulshan Singh") (:url . "https://github.com/gsingh93/ob-bitfield"))])
+ (ob-blockdiag . [(20210412 1541) nil "org-babel functions for blockdiag evaluation" single ((:commit . "c3794bf7bdb8fdb3db90db41619dda4e7d3dd7b9") (:authors ("Dmitry Moskowski")) (:maintainer "Dmitry Moskowski") (:keywords "tools" "convenience") (:url . "https://github.com/corpix/ob-blockdiag.el"))])
+ (ob-browser . [(20170720 1918) ((org (8))) "Render HTML in org-mode blocks." tar ((:commit . "a347d9df1c87b7eb660be8723982c7ad2563631a") (:authors ("Kris Jenkins" . "krisajenkins@gmail.com")) (:maintainer "Kris Jenkins" . "krisajenkins@gmail.com") (:keywords "org" "babel" "browser" "phantomjs") (:url . "https://github.com/krisajenkins/ob-browser"))])
+ (ob-cfengine3 . [(20191011 1721) nil "Org Babel functions for CFEngine 3" single ((:commit . "195ba4694a0ec18d3fb89342e8e0988b382a5b1a") (:authors ("Nick Anderson" . "nick@cmdln.org")) (:maintainer "Nick Anderson" . "nick@cmdln.org") (:keywords "tools" "convenience") (:url . "https://github.com/nickanderson/ob-cfengine3"))])
+ (ob-clojurescript . [(20180406 1828) ((emacs (24 4)) (org (9 0))) "org-babel functions for ClojureScript evaluation" single ((:commit . "17ee1558aa94c7b0246fd03f684884122806cfe7") (:authors ("Larry Staton Jr.")) (:maintainer "Larry Staton Jr.") (:keywords "literate programming" "reproducible research") (:url . "https://gitlab.com/statonjr/ob-clojurescript"))])
+ (ob-coffee . [(20170725 1424) ((org (8))) "org-babel functions for coffee-script evaluation" tar ((:commit . "7f0b330273e8af7777de87a75fe52a89798e4548") (:authors ("ZHOU Feng" . "zf.pascal@gmail.com")) (:maintainer "ZHOU Feng" . "zf.pascal@gmail.com") (:keywords "org" "babel" "coffee-script") (:url . "http://github.com/zweifisch/ob-coffee"))])
+ (ob-coffeescript . [(20180126 719) ((emacs (24 4))) "org-babel functions for coffee-script evaluation, and fully implementation!" single ((:commit . "5a5bb04aea9c2a6eab5b05f90f5c7cb6de7b4261") (:authors ("Brantou" . "brantou89@gmail.com")) (:maintainer "Brantou" . "brantou89@gmail.com") (:keywords "coffee-script" "literate programming" "reproducible research") (:url . "https://github.com/brantou/ob-coffeescript"))])
+ (ob-compile . [(20220413 228) ((emacs (24 4))) "Run compile by org-babel" single ((:commit . "eb4fca6dc728cdc1e73d5d7ca8cad0f4cb1ad36a") (:authors ("Giap Tran" . "txgvnn@gmail.com")) (:maintainer "Giap Tran" . "txgvnn@gmail.com") (:keywords "literate programming" "reproducible" "processes") (:url . "https://github.com/TxGVNN/ob-compile"))])
+ (ob-crystal . [(20180126 718) ((emacs (24 3))) "org-babel functions for Crystal evaluation" tar ((:commit . "d84c1adee4b269cdba06a97caedb8071561a09af") (:authors ("Brantou" . "brantou89@gmail.com")) (:maintainer "Brantou" . "brantou89@gmail.com") (:keywords "crystal" "literate programming" "reproducible research") (:url . "https://github.com/brantou/ob-crystal"))])
+ (ob-cypher . [(20200521 936) ((s (1 9 0)) (cypher-mode (0 0 6)) (dash (2 10 0)) (dash-functional (1 2 0))) "query neo4j using cypher in org-mode blocks" single ((:commit . "da9f97339474a48d759fc128cee610c0bc9ae6c0") (:authors ("ZHOU Feng" . "zf.pascal@gmail.com")) (:maintainer "ZHOU Feng" . "zf.pascal@gmail.com") (:keywords "org" "babel" "cypher" "neo4j") (:url . "http://github.com/zweifisch/ob-cypher"))])
+ (ob-dao . [(20170816 1558) ((org (8))) "Org Babel Functions for Dao" single ((:commit . "fa92f62a63c684d689f57e790e5dd614c5bba270") (:authors ("Chunyang Xu" . "mail@xuchunyang.me")) (:maintainer "Chunyang Xu" . "mail@xuchunyang.me") (:keywords "literate programming" "reproducible research" "org" "babel" "dao") (:url . "https://github.com/xuchunyang/ob-dao"))])
+ (ob-dart . [(20170106 1624) nil "org-babel functions for Dart evaluation" single ((:commit . "04d63b922a5469506560ca0c00678e57131e0269") (:authors ("Milan Zimmermann")) (:maintainer "Milan Zimmermann") (:keywords "literate programming" "reproducible research" "emacs" "org" "babel" "dart") (:url . "http://github.org/mzimmerm/ob-dart"))])
+ (ob-deno . [(20201019 101) ((emacs (26 1))) "Babel Functions for Javascript/TypeScript with Deno" single ((:commit . "f1129d20fe9931f1c0b62c4af781f5489abd957f") (:authors ("HIGASHI Taiju")) (:maintainer "HIGASHI Taiju") (:keywords "literate programming" "reproducible research" "javascript" "typescript" "tools") (:url . "https://github.com/taiju/ob-deno"))])
+ (ob-diagrams . [(20160407 1237) nil "org-babel functions for diagrams evaluation" single ((:commit . "ed6649616325ca5b2d2109f74aded8bcb8aa5186") (:authors ("Daniel Bergey")) (:maintainer "Daniel Bergey") (:keywords "literate programming" "reproducible research") (:url . "http://orgmode.org"))])
+ (ob-dsq . [(20220425 716) ((emacs (27 1))) "Babel functions for the `dsq` CLI tool by Multiprocess Labs" single ((:commit . "b8dbf53e5d9ed359fbf69e9d14adf68a7c08af10") (:authors ("Fritz Grabo" . "hello@fritzgrabo.com")) (:maintainer "Fritz Grabo" . "hello@fritzgrabo.com") (:keywords "data" "tools") (:url . "https://github.com/fritzgrabo/ob-dsq"))])
+ (ob-elixir . [(20170725 1419) ((org (8))) "org-babel functions for elixir evaluation" single ((:commit . "8990a8178b2f7bd93504a9ab136622aab6e82e32") (:authors ("ZHOU Feng" . "zf.pascal@gmail.com")) (:maintainer "ZHOU Feng" . "zf.pascal@gmail.com") (:keywords "org" "babel" "elixir") (:url . "http://github.com/zweifisch/ob-elixir"))])
+ (ob-elm . [(20200528 1857) ((emacs (26 1)) (org (9 3))) "Org-babel functions for elm evaluation" single ((:commit . "d3a9fbc2f56416894c9aed65ea9a20cc1d98f15d") (:authors ("Bonface M. K.")) (:maintainer "Bonface M. K.") (:keywords "languages" "tools") (:url . "https://www.bonfacemunyoki.com"))])
+ (ob-elvish . [(20180427 1900) nil "org-babel functions for Elvish shell" single ((:commit . "369181ceae1190bf971c71aebf9fc6133bd98c39") (:authors ("Diego Zamboni" . "diego@zzamboni.org")) (:maintainer "Diego Zamboni" . "diego@zzamboni.org") (:keywords "literate programming" "elvish" "shell" "languages" "processes" "tools") (:url . "https://github.com/zzamboni/ob-elvish"))])
+ (ob-ess-julia . [(20210414 1444) ((ess (20201004 1522)) (julia-mode (0 4))) "Org babel support for Julia language" tar ((:commit . "147e9e7fe55c41dd77171417e92af40db3530b84") (:authors ("Frédéric Santos")) (:maintainer "Frédéric Santos") (:keywords "languages") (:url . "https://github.com/frederic-santos/ob-ess-julia"))])
+ (ob-fsharp . [(20170618 1429) ((emacs (25)) (fsharp-mode (1 9 8))) "Org-Babel F#" single ((:commit . "0b2fdd9bb4f38af8b5cf4914627af52f5b43d9f7") (:authors ("Jürgen Hötzel" . "juergen@archlinux.org")) (:maintainer "Jürgen Hötzel" . "juergen@archlinux.org") (:keywords "literate programming" "reproducible research") (:url . "https://github.com/juergenhoetzel/ob-fsharp"))])
+ (ob-go . [(20190201 2040) nil "org-babel functions for go evaluation" tar ((:commit . "2067ed55f4c1d33a43cb3f6948609d240a8915f5") (:authors ("K. Adam Christensen")) (:maintainer "K. Adam Christensen") (:keywords "golang" "go" "literate programming" "reproducible research") (:url . "http://orgmode.org"))])
+ (ob-graphql . [(20201222 1515) ((emacs (24 4)) (graphql-mode (20191024 1221)) (request (0 3 2))) "Org-Babel execution backend for GraphQL source blocks" single ((:commit . "7c35419f9eec5dc44967cbcfa13c7135b9a96bfc") (:authors ("Jeremy Dormitzer" . "jeremy.dormitzer@gmail.com")) (:maintainer "Jeremy Dormitzer" . "jeremy.dormitzer@gmail.com") (:url . "https://github.com/jdormit/ob-graphql"))])
+ (ob-html-chrome . [(20181219 1042) ((emacs (24 4)) (f (0 20 0)) (s (1 7 0))) "HTML code blocks converted to PNG using Chrome" single ((:commit . "7af6e4a24ed0aaf67751bdf752c7ca0ba02bb8d4") (:authors (nil . "Nik Clayton nik@ngo.org.uk")) (:maintainer nil . "Nik Clayton nik@ngo.org.uk") (:keywords "languages" "org" "org-babel" "chrome" "html") (:url . "http://github.com/nikclayton/ob-html-chrome"))])
+ (ob-http . [(20180707 1448) ((s (1 9 0)) (cl-lib (0 5))) "http request in org-mode babel" tar ((:commit . "b1428ea2a63bcb510e7382a1bf5fe82b19c104a7") (:authors ("ZHOU Feng" . "zf.pascal@gmail.com")) (:maintainer "ZHOU Feng" . "zf.pascal@gmail.com") (:url . "http://github.com/zweifisch/ob-http"))])
+ (ob-hy . [(20180702 540) ((emacs (24 4))) "org-babel functions for Hy-lang evaluation" tar ((:commit . "a42ecaf440adc03e279afe43ee5ef6093ddd542a") (:authors ("Brantou" . "brantou89@gmail.com")) (:maintainer "Brantou" . "brantou89@gmail.com") (:keywords "hy" "literate programming" "reproducible research") (:url . "https://github.com/brantou/ob-hy"))])
+ (ob-ipython . [(20180224 953) ((s (1 9 0)) (dash (2 10 0)) (dash-functional (1 2 0)) (f (0 17 2)) (emacs (24))) "org-babel functions for IPython evaluation" tar ((:commit . "7147455230841744fb5b95dcbe03320313a77124") (:authors ("Greg Sexton" . "gregsexton@gmail.com")) (:maintainer "Greg Sexton" . "gregsexton@gmail.com") (:keywords "literate programming" "reproducible research") (:url . "http://www.gregsexton.org"))])
+ (ob-julia-vterm . [(20210418 2306) ((emacs (26 1)) (julia-vterm (0 10))) "Babel Functions for Julia in VTerm" single ((:commit . "e04ee53d67cbd715c2d84fe5bc367526edfadc74") (:authors ("Shigeaki Nishina")) (:maintainer "Shigeaki Nishina") (:keywords "julia" "org" "outlines" "literate programming" "reproducible research") (:url . "https://github.com/shg/ob-julia-vterm.el"))])
+ (ob-kotlin . [(20180823 1321) ((org (8))) "org-babel functions for kotlin evaluation" single ((:commit . "96e420cbd2e9ea8a77043e5dcaebdfc6da17492a") (:authors ("ZHOU Feng" . "zf.pascal@gmail.com")) (:maintainer "ZHOU Feng" . "zf.pascal@gmail.com") (:keywords "org" "babel" "kotlin") (:url . "http://github.com/zweifisch/ob-kotlin"))])
+ (ob-latex-as-png . [(20200629 1013) ((emacs (26 1)) (org (9 1))) "Org-babel functions for latex-as-png evaluation" single ((:commit . "a20e3fedbac4034de4ab01436673a0f8845de1df") (:authors ("Musa Al-hassy" . "alhassy@gmail.com")) (:maintainer "Musa Al-hassy" . "alhassy@gmail.com") (:keywords "literate programming" "reproducible research" "org" "convenience") (:url . "https://github.com/alhassy/ob-latex-as-png"))])
+ (ob-lfe . [(20170725 1420) ((org (8))) "org-babel functions for lfe evaluation" single ((:commit . "f7780f58e650b4d29dfd834c662b1d354b620a8e") (:authors ("ZHOU Feng" . "zf.pascal@gmail.com")) (:maintainer "ZHOU Feng" . "zf.pascal@gmail.com") (:keywords "org" "babel" "lfe" "lisp" "erlang") (:url . "http://github.com/zweifisch/ob-lfe"))])
+ (ob-mermaid . [(20200320 1504) nil "org-babel support for mermaid evaluation" single ((:commit . "b4ce25699e3ebff054f523375d1cf5a17bd0dbaf") (:authors ("Alexei Nunez" . "alexeirnunez@gmail.com")) (:maintainer "Alexei Nunez" . "alexeirnunez@gmail.com") (:keywords "lisp") (:url . "https://github.com/arnm/ob-mermaid"))])
+ (ob-ml-marklogic . [(20190312 1314) nil "org-babel functions for MarkLogic evaluation" tar ((:commit . "d5660ad14f29e17cd26ae92eeb585b24030e9570") (:authors ("Norman Walsh" . "ndw@nwalsh.com")) (:maintainer "Norman Walsh" . "ndw@nwalsh.com") (:keywords "marklogic" "xquery" "javascript" "sparql") (:url . "http://github.com/ndw/ob-ml-marklogic"))])
+ (ob-mongo . [(20170720 1919) ((org (8))) "Execute mongodb queries within org-mode blocks." single ((:commit . "371bf19c7c10eab2f86424f8db8ab685997eb5aa") (:authors ("Kris Jenkins" . "krisajenkins@gmail.com")) (:maintainer "Kris Jenkins" . "krisajenkins@gmail.com") (:keywords "org" "babel" "mongo" "mongodb") (:url . "https://github.com/krisajenkins/ob-mongo"))])
+ (ob-napkin . [(20200816 1245) ((emacs (26 1))) "Babel functions for Napkin" single ((:commit . "7af5e8af08da8455c489909afbd9528a61f570e7") (:authors ("Hans Jang")) (:maintainer "Hans Jang") (:keywords "tools" "literate programming" "reproducible research" "napkin" "plantuml") (:url . "https://github.com/pinetr2e/ob-napkin"))])
+ (ob-nim . [(20210601 1807) ((cl-lib (0 5))) "Babel Functions for nim" single ((:commit . "6fd060a3ecd38be37e4ec2261cd65760a3c35a91") (:authors ("Lompik")) (:maintainer "Lompik") (:keywords "literate programming" "reproducible research"))])
+ (ob-php . [(20220221 1254) ((org (8))) "Execute PHP within org-mode source blocks." single ((:commit . "6ebf7799e9ded1d5114094f46785960a50000614") (:authors ("stardiviner" . "numbchild@gmail.com")) (:maintainer "stardiviner" . "numbchild@gmail.com") (:keywords "org" "babel" "php") (:url . "https://repo.or.cz/ob-php.git"))])
+ (ob-powershell . [(20220314 1359) ((emacs (26 1))) "Run Powershell from org mode source blocks" single ((:commit . "f351429590ed68b26a9c8f9847066ca4205e524b") (:authors ("Rob Kiggen" . "robby.kiggen@essential-it.be")) (:maintainer "Mois Moshev" . "mois.moshev@bottleshipvfx.com") (:keywords "powershell" "shell" "execute" "outlines" "processes") (:url . "https://github.com/rkiggen/ob-powershell"))])
+ (ob-prolog . [(20190410 2130) nil "org-babel functions for prolog evaluation." single ((:commit . "331899cfe345c934026c70b78352d320f7d8e239") (:authors ("Bjarte Johansen")) (:maintainer "Bjarte Johansen") (:keywords "literate programming" "reproducible research") (:url . "https://github.com/ljos/ob-prolog"))])
+ (ob-redis . [(20220221 1249) ((org (8))) "Execute Redis queries within org-mode blocks." single ((:commit . "44c83636ccbea0b3e9838b0180471905c30224c5") (:authors ("stardiviner" . "numbchild@gmail.com")) (:maintainer "stardiviner" . "numbchild@gmail.com") (:keywords "org" "babel" "redis") (:url . "https://repo.or.cz/ob-redis.git"))])
+ (ob-restclient . [(20220202 1609) ((restclient (0))) "org-babel functions for restclient-mode" single ((:commit . "586f1fa07f76aaca13cb3f86945759f4b9fb8db7") (:authors ("Alf Lervåg")) (:maintainer "Alf Lervåg") (:keywords "literate programming" "reproducible research") (:url . "https://github.com/alf/ob-restclient.el"))])
+ (ob-reticulate . [(20210214 2229) ((org (9 4)) (emacs (24 4))) "Babel Functions for reticulate" single ((:commit . "8109fb02fb6339b1cf9290df29fc0c1109a33c04") (:authors ("Jack Kamm")) (:maintainer "Jack Kamm") (:keywords "literate programming" "reproducible research" "r" "python" "statistics" "languages" "outlines" "processes") (:url . "https://github.com/jackkamm/ob-reticulate"))])
+ (ob-rust . [(20210204 244) nil "Org-babel functions for Rust" tar ((:commit . "30fe7e7181f44443d02e905dda77f83ec4944e76") (:authors ("Mican Zhang")) (:maintainer "Mican Zhang") (:keywords "rust" "languages" "org" "babel") (:url . "https://github.com/micanzhang/ob-rust"))])
+ (ob-sagemath . [(20191106 828) ((sage-shell-mode (0 0 8)) (s (1 8 0)) (emacs (24))) "org-babel functions for SageMath evaluation" tar ((:commit . "79645bce0c25a650bae61e550434bed836995dce") (:authors ("Sho Takemori" . "stakemorii@gmail.com")) (:maintainer "Sho Takemori" . "stakemorii@gmail.com") (:keywords "sagemath" "org-babel") (:url . "https://github.com/stakemori/ob-sagemath"))])
+ (ob-smiles . [(20220221 1255) ((smiles-mode (0 0 1)) (org (8))) "Org-mode Babel support for SMILES." single ((:commit . "d178f3d4a7e3c1ca9910f0a063d2a3cfd97d8609") (:authors (nil . "John Kitchin [jkitchin@andrew.cmu.edu]")) (:maintainer nil . "stardiviner [numbchild@gmail.com]") (:keywords "org" "babel" "smiles") (:url . "https://repo.or.cz/ob-smiles.git"))])
+ (ob-sml . [(20130829 1843) ((sml-mode (6 4))) "org-babel functions for template evaluation" single ((:commit . "958165c92b6cff6cada5c85c8ae5887806b8451b") (:authors ("David Nolen")) (:maintainer "David Nolen") (:keywords "literate programming" "reproducible research") (:url . "http://orgmode.org"))])
+ (ob-solidity . [(20220213 1910) ((emacs (24 4)) (solidity-mode (0 1 10))) "Org-babel functions for solidity evaluation" single ((:commit . "7e3e6cb2d7ec9269514e80248c7ec85c04dbbf89") (:authors ("hrkrshnn")) (:maintainer "hrkrshnn") (:keywords "solidity" "literate programming" "reproducible research" "languages") (:url . "https://github.com/hrkrshnn/ob-solidity"))])
+ (ob-spice . [(20220210 1415) ((spice-mode (0 0 1)) (org (8))) "org-babel functions for spice evaluation" single ((:commit . "6dc2c6b9391ea8dd8123224f6c282b673b89dc94") (:authors ("Tiago Oliveira Weber")) (:maintainer "stardiviner" . "numbchild@gmail.com") (:url . "https://repo.or.cz/ob-spice.git"))])
+ (ob-sql-mode . [(20190421 1539) ((emacs (24 4))) "SQL code blocks evaluated by sql-mode" single ((:commit . "b31a016585324ad91f1742ff6205bcb76f3ece6e") (:authors (nil . "Nik Clayton nik@google.com")) (:maintainer nil . "Nik Clayton nik@google.com") (:keywords "languages" "org" "org-babel" "sql") (:url . "http://github.com/nikclayton/ob-sql-mode"))])
+ (ob-svgbob . [(20190911 300) ((emacs (24))) "Babel Functions for svgbob" single ((:commit . "5747f96fb4fdb8711546b3313df9412177eb3c1a") (:authors ("Marcio Giaxa" . "i@mgxm.me")) (:maintainer "Marcio Giaxa" . "i@mgxm.me") (:keywords "tools" "files") (:url . "https://github.com/mgxm/ob-svgbob"))])
+ (ob-swift . [(20170921 1325) ((org (8))) "org-babel functions for swift evaluation" single ((:commit . "ed478ddbbe41ce5373efde06b4dd0c3663c9055f") (:authors ("Feng Zhou" . "zf.pascal@gmail.com")) (:maintainer "Feng Zhou" . "zf.pascal@gmail.com") (:keywords "org" "babel" "swift") (:url . "http://github.com/zweifisch/ob-swift"))])
+ (ob-swiftui . [(20210618 856) ((emacs (25 1)) (swift-mode (8 2 0)) (org (9 2 0))) "Org babel functions for SwiftUI evaluation" single ((:commit . "31cfe991eb171bb0d2f53cf621be1b9d91573ac3") (:authors ("Alvaro Ramirez")) (:maintainer "Alvaro Ramirez") (:url . "https://github.com/xenodium/ob-swiftui"))])
+ (ob-tmux . [(20190708 1202) ((emacs (25 1)) (seq (2 3)) (s (1 9 0))) "Babel Support for Interactive Terminal" single ((:commit . "3687ed7b874bdfe14617f5d14492887cb0836a85") (:authors ("Allard Hendriksen")) (:maintainer "Allard Hendriksen") (:keywords "literate programming" "interactive shell" "tmux") (:url . "https://github.com/ahendriksen/ob-tmux"))])
+ (ob-translate . [(20170720 1919) ((google-translate (0 11)) (org (8))) "Translation of text blocks in org-mode." single ((:commit . "9d9054a51bafd5a29a8135964069b4fa3a80b169") (:authors ("Kris Jenkins" . "krisajenkins@gmail.com")) (:maintainer "Kris Jenkins" . "krisajenkins@gmail.com") (:keywords "org" "babel" "translate" "translation") (:url . "https://github.com/krisajenkins/ob-translate"))])
+ (ob-typescript . [(20190910 946) ((emacs (24)) (org (8 0))) "org-babel functions for typescript evaluation" single ((:commit . "0b2766b9d136cd6d81f4c15f1ad4b28542f484b9") (:authors ("KURASHIKI Satoru")) (:maintainer "KURASHIKI Satoru") (:keywords "literate programming" "reproducible research" "typescript") (:url . "https://github.com/lurdan/ob-typescript"))])
+ (ob-uart . [(20170521 858) nil "org-babel support for UART communication" single ((:commit . "90daeac90a9e75c20cdcf71234c67b812110c50e") (:authors ("Andreas Müller")) (:maintainer "Andreas Müller") (:keywords "tools" "comm" "org-mode" "uart" "literate programming" "reproducible development") (:url . "https://www.0x7.ch"))])
+ (oberon . [(20120715 909) nil "Major mode for editing Oberon/Oberon-2 program texts" single ((:commit . "fb57d18ce13835a8a69b6bafecdd9193ca9a59a3") (:authors ("Karl Landström" . "karl@karllandstrom.se")) (:maintainer "Karl Landström" . "karl@karllandstrom.se") (:keywords "oberon" "oberon-2" "languages" "oop"))])
+ (obfusurl . [(20170809 1524) ((cl-lib (0 5))) "Obfuscate URLs so they aren't spoilers" single ((:commit . "7a5a41905000ce2ec1fd72509a5567e5fd9f47e5") (:authors ("Dave Pearson" . "davep@davep.org")) (:maintainer "Dave Pearson" . "davep@davep.org") (:keywords "convenience" "web" "text") (:url . "https://github.com/davep/obfusurl.el"))])
+ (objc-font-lock . [(20141021 1822) nil "Highlight Objective-C method calls." single ((:commit . "34b457d577f97ca94b8792d025f9a909c7610612") (:authors ("Anders Lindgren")) (:maintainer "Anders Lindgren") (:keywords "languages" "faces") (:url . "https://github.com/Lindydancer/objc-font-lock"))])
+ (objed . [(20200911 1435) ((emacs (25)) (cl-lib (0 5))) "Navigate and edit text objects." tar ((:commit . "70f9fb5e0aa1627b0afc7c6b3d0aea9bac70a210") (:authors ("Clemens Radermacher" . "clemera@posteo.net")) (:maintainer "Clemens Radermacher" . "clemera@posteo.net") (:keywords "convenience") (:url . "https://github.com/clemera/objed"))])
+ (oblivion-theme . [(20220429 116) ((emacs (24 1))) "A port of GEdit oblivion theme" single ((:commit . "37e562b92cebafbc38ea817ac7bdf7b41576eeca") (:authors ("Campbell Barton" . "ideasman42@gmail.com")) (:maintainer "Campbell Barton" . "ideasman42@gmail.com") (:url . "https://gitlab.com/ideasman42/emacs-oblivion-theme"))])
+ (obsidian-theme . [(20170719 948) nil "port of the eclipse obsidian theme" single ((:commit . "f45efb2ebe9942466c1db6abbe2d0e6847b785ea") (:authors ("martin haesler")) (:maintainer "martin haesler") (:url . "http://github.com/mswift42/obsidian-theme"))])
+ (ocamlformat . [(20220307 1315) ((emacs (24 3))) "Utility functions to format ocaml code" single ((:commit . "c490e5b7c4b5f5e5848a5cbdb1e669588dfeaae3") (:keywords "languages" "ocaml") (:url . "https://github.com/ocaml-ppx/ocamlformat"))])
+ (occidental-theme . [(20130312 1958) nil "Custom theme for faces based on Adwaita" single ((:commit . "fd2db7256d4f78c43d99c3cddb1c39106d479816") (:authors ("William Stevenson" . "yhvh2000@gmail.com") ("Erik Timan" . "dev@timan.info")) (:maintainer "William Stevenson" . "yhvh2000@gmail.com") (:url . "http://github.com/olcai/occidental-theme"))])
+ (occur-context-resize . [(20210121 50) nil "dynamically resize context around matches in occur-mode" single ((:commit . "9d62a5b5c39ab7921dfc12dd0ab139b38dd16582") (:authors ("Charles L.G. Comstock" . "dgtized@gmail.com")) (:maintainer "Charles L.G. Comstock" . "dgtized@gmail.com") (:keywords "matching") (:url . "https://github.com/dgtized/occur-context-resize.el"))])
+ (occur-x . [(20130610 1343) nil "Extra functionality for occur" single ((:commit . "352f5fab207d8a1d3dd048073ff127a83e97c82b") (:authors ("Juan-Leon Lahoz" . "juanleon1@gmail.com")) (:maintainer "Juan-Leon Lahoz" . "juanleon1@gmail.com") (:keywords "occur" "search" "convenience"))])
+ (oceanic-theme . [(20161015 819) nil "Oceanic theme." single ((:commit . "a92ee9b470843c923e6cdcafdd65106ff994d04d") (:authors ("Tengfei Guo")) (:maintainer "Tengfei Guo") (:keywords "oceanic" "color" "theme") (:url . "https://github.com/terry3/oceanic-theme"))])
+ (ocodo-svg-modelines . [(20150516 1419) ((svg-mode-line-themes (0))) "A collection of beautiful SVG modelines" tar ((:commit . "c7b0789a177219f117c4de5659ecfa8622958c40") (:authors ("ocodo" . "what.is.ocodo@gmail.com")) (:maintainer "ocodo" . "what.is.ocodo@gmail.com") (:url . "https://github.com/ocodo/ocodo-svg-modelines"))])
+ (ocp-indent . [(20211019 907) nil "automatic indentation with ocp-indent" single ((:commit . "7c4d434132cebc15a8213c8be9e7323692eb0a2b") (:keywords "ocaml" "languages") (:url . "http://www.typerex.org/ocp-indent.html"))])
+ (octicons . [(20151101 340) ((cl-lib (0 5))) "octicons utility" tar ((:commit . "a61e561966ffd8faa3b48ce5b3a4eec10c59708b") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-octicons"))])
+ (octo-mode . [(20161008 1229) ((emacs (24))) "Major mode for Octo assembly language" single ((:commit . "bd4db7e5e3275b24c74e6a23c11d04f54e9feca5") (:authors ("John Olsson" . "john@cryon.se")) (:maintainer "John Olsson" . "john@cryon.se") (:keywords "languages") (:url . "https://github.com/cryon/octo-mode"))])
+ (octopress . [(20190123 107) nil "A lightweight wrapper for Jekyll and Octopress." tar ((:commit . "f2c92d5420f14fc9167c7de1873836510e652de2") (:authors ("Aaron Bieber" . "aaron@aaronbieber.com")) (:maintainer "Aaron Bieber" . "aaron@aaronbieber.com") (:keywords "octopress" "blog") (:url . "https://github.com/aaronbieber/octopress.el"))])
+ (oer-reveal . [(20220402 1505) ((emacs (24 4)) (org-re-reveal (3 1 0))) "OER with reveal.js, plugins, and org-re-reveal" tar ((:commit . "df7180a8d75dedb2fd8878843a3d3cc654be508d") (:authors ("Jens Lechtenbörger")) (:maintainer "Jens Lechtenbörger") (:keywords "hypermedia" "tools" "slideshow" "presentation" "oer") (:url . "https://gitlab.com/oer/oer-reveal"))])
+ (offlineimap . [(20150916 1158) nil "Run OfflineIMAP from Emacs" single ((:commit . "cc3e067e6237a1eb7b21c575a41683b1febb47f1") (:authors ("Julien Danjou" . "julien@danjou.info")) (:maintainer "Julien Danjou" . "julien@danjou.info") (:url . "http://julien.danjou.info/offlineimap-el.html"))])
+ (oj . [(20200811 517) ((emacs (26 1)) (quickrun (2 2))) "Competitive programming tools client for AtCoder, Codeforces" single ((:commit . "2dd65324ac9833e07eaed5fb04acebafc6d5cbd2") (:authors ("Naoya Yamashita" . "conao3@gmail.com")) (:maintainer "Naoya Yamashita" . "conao3@gmail.com") (:keywords "convenience") (:url . "https://github.com/conao3/oj.el"))])
+ (ol-notmuch . [(20220428 1337) ((emacs (25 1)) (compat (28 1 1 0)) (notmuch (0 32)) (org (9 4 5))) "Links to notmuch messages" single ((:commit . "744399e054ef3a19f66418fdb98ef9ad139cc3b5") (:authors ("Matthieu Lemerre" . "racin@free.fr")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:keywords "hypermedia" "mail") (:url . "https://git.sr.ht/~tarsius/ol-notmuch"))])
+ (olc . [(20200818 1221) ((emacs (25 1))) "Open location code library" tar ((:commit . "d2dc62dbc3cf6460cc12bd96857a988bc80ac37e") (:authors ("David Byers" . "david.byers@liu.se")) (:maintainer "David Byers" . "david.byers@liu.se") (:keywords "extensions" "lisp") (:url . "https://gitlab.liu.se/davby02/olc"))])
+ (old-norse-input . [(20170816 1842) ((emacs (24))) "An input method for Old Norse" single ((:commit . "c2e21ee72c3768e9152aff6baf12a19cde1d0c53") (:authors ("David Christiansen" . "david@davidchristiansen.dk")) (:maintainer "David Christiansen" . "david@davidchristiansen.dk") (:keywords "languages") (:url . "https://github.com/david-christiansen/emacs-old-norse-input"))])
+ (oldlace-theme . [(20150705 1300) ((emacs (24))) "Emacs 24 theme with an 'oldlace' background." single ((:commit . "5c6f437203b0783b36a7aff4a578de4a0c8c4ee6") (:authors ("martin haesler")) (:maintainer "martin haesler"))])
+ (olivetti . [(20220330 635) ((emacs (24 4))) "Minor mode for a nice writing environment" single ((:commit . "8d287a80c5e3d72ac01b56c8afe60b01f18500b4") (:authors ("Paul W. Rankin" . "pwr@bydasein.com")) (:maintainer "Paul W. Rankin" . "pwr@bydasein.com") (:keywords "wp" "text") (:url . "https://github.com/rnkn/olivetti"))])
+ (om-mode . [(20140915 2110) nil "Insert Om component template with life cycle." single ((:commit . "cdc0c2912321f8438b0f3449ba8aca50ec150bba") (:authors ("Daniel Szmulewicz" . "daniel.szmulewicz@gmail.com")) (:maintainer "Daniel Szmulewicz" . "daniel.szmulewicz@gmail.com") (:keywords "clojurescript"))])
+ (omni-kill . [(20171016 2140) nil "Kill all the things" single ((:commit . "904549c8fd6ac3cf22b5d7111ca8944e179cffea") (:authors ("Adrien Becchis" . "adriean.khisbe@live.fr")) (:maintainer "Adrien Becchis" . "adriean.khisbe@live.fr") (:keywords "convenience" "editing" "tools"))])
+ (omni-log . [(20200304 2229) ((emacs (24)) (ht (2 0)) (s (1 6 1)) (dash (2 13 0))) "Logging utilities" tar ((:commit . "0a240660ccdd0b6588b4e3c322743b5ab1161338") (:authors ("Adrien Becchis" . "adriean.khisbe@live.fr")) (:maintainer "Adrien Becchis" . "adriean.khisbe@live.fr") (:keywords "convenience" "languages" "tools") (:url . "https://github.com/AdrieanKhisbe/omni-log.el"))])
+ (omni-quotes . [(20200304 2341) ((dash (2 8)) (omni-log (0 4 0)) (f (0 19 0)) (s (1 11 0)) (ht (2 1))) "Random quotes displayer" tar ((:commit . "cfc7b7f01628a5d57384820d1096de4541e67cdf") (:authors ("Adrien Becchis" . "adriean.khisbe@live.fr")) (:maintainer "Adrien Becchis" . "adriean.khisbe@live.fr") (:keywords "convenience") (:url . "https://github.com/AdrieanKhisbe/omni-quotes.el"))])
+ (omni-scratch . [(20171009 2151) nil "Easy and mode-specific draft buffers" single ((:commit . "9eee3161e5cb6df58618548a2173f4da7d194814") (:authors ("Adrien Becchis" . "adriean.khisbe@live.fr")) (:maintainer "Adrien Becchis" . "adriean.khisbe@live.fr") (:keywords "convenience" "languages" "tools") (:url . "https://github.com/AdrieanKhisbe/omni-scratch.el"))])
+ (omni-tags . [(20170426 2109) ((pcre2el (1 7)) (cl-lib (0 5))) "Highlight and Actions for 'Tags'" tar ((:commit . "8f0f6c302fab900b7681e5c039f90850cbbabd33") (:authors ("Adrien Becchis" . "adriean.khisbe@live.fr")) (:maintainer "Adrien Becchis" . "adriean.khisbe@live.fr") (:keywords "convenience") (:url . "http://github.com/AdrieanKhisbe/omni-tags.el"))])
+ (omnibox . [(20180423 49) ((emacs (26 1)) (dash (2 13)) (frame-local (0 0 1))) "Selection package" single ((:commit . "8ee75c71c20c438ebc43ba24ef6f543633d118f3") (:authors ("Sebastien Chapuis" . "sebastien@chapu.is")) (:maintainer "Sebastien Chapuis" . "sebastien@chapu.is") (:keywords "completion" "selection" "convenience" "frames") (:url . "https://github.com/sebastiencs/omnibox"))])
+ (omnisharp . [(20210725 1955) ((emacs (24 4)) (flycheck (30)) (dash (2 12 0)) (auto-complete (1 4)) (popup (0 5 1)) (csharp-mode (0 8 7)) (cl-lib (0 5)) (s (1 10 0)) (f (0 19 0))) "Omnicompletion (intellisense) and more for C#" tar ((:commit . "e276ff140666057c6d6848f9cfc84a82e3a7650c") (:authors ("Mika Vilpas and others")) (:maintainer "Mika Vilpas and others") (:keywords "languages" "csharp" "c#" "ide" "auto-complete" "intellisense") (:url . "https://github.com/Omnisharp/omnisharp-emacs"))])
+ (omtose-phellack-theme . [(20161111 2120) nil "A dark theme, with cold bluish touch." tar ((:commit . "66f99633e199e65bd28641626435e8e59246529a"))])
+ (on-parens . [(20210928 1913) ((dash (2 10 0)) (emacs (24)) (evil (1 1 6)) (smartparens (1 6 3))) "smartparens wrapper to fit with evil-mode/vim normal-state" single ((:commit . "b8ee8cea45c9b34820fcb951f522f13e3736d216") (:authors ("William G Hatch")) (:maintainer "William G Hatch") (:keywords "evil" "smartparens"))])
+ (on-screen . [(20160302 950) ((cl-lib (0))) "guide your eyes while scrolling" single ((:commit . "206468aa4de299ad26c2db12b757f5ad7290912f") (:authors ("Michael Heerdegen" . "michael_heerdegen@web.de")) (:maintainer "Michael Heerdegen" . "michael_heerdegen@web.de") (:keywords "convenience") (:url . "https://github.com/michael-heerdegen/on-screen.el"))])
+ (one-themes . [(20200720 1444) ((emacs (24))) "One Colorscheme" tar ((:commit . "0e77d31f9fc0cd55f3d92ec0db79513d616b2efd") (:authors ("Balaji Sivaraman" . "balaji@balajisivaraman.com")) (:maintainer "Balaji Sivaraman" . "balaji@balajisivaraman.com") (:url . "http://github.com/balajisivaraman/emacs-one-themes"))])
+ (one-time-pad-encrypt . [(20160329 1513) nil "One time pad encryption within file" single ((:commit . "87cc1f124024ce3d277299ca0ac703f182937d9f") (:authors ("Garvin Guan" . "garvin.guan@gmail.com")) (:maintainer "Garvin Guan" . "garvin.guan@gmail.com") (:keywords "convenience") (:url . "https://github.com/garvinguan/emacs-one-time-pad/"))])
+ (opam . [(20150719 1220) ((emacs (24 1))) "OPAM tools" single ((:commit . "4d589de5765728f56af7078fae328b6792de8600") (:authors ("Sebastian Wiesner" . "swiesner@lunaryorn.com")) (:maintainer "Sebastian Wiesner" . "swiesner@lunaryorn.com") (:keywords "convenience") (:url . "https://github.com/lunaryorn/opam.el"))])
+ (open-in-msvs . [(20170123 2228) nil "Open current file:line:column in Microsoft Visual Studio" tar ((:commit . "e0d071c83188ad5db8f3297d6ce784b4ed554a04") (:authors ("Evgeny Panasyuk")) (:maintainer "Evgeny Panasyuk") (:keywords "convenience" "usability" "integration" "visual studio" "msvs" "ide") (:url . "https://github.com/evgeny-panasyuk/open-in-msvs"))])
+ (open-junk-file . [(20161210 1114) nil "Open a junk (memo) file to try-and-error" single ((:commit . "558bec7372b0fed4c4cb6074ab906535fae615bd") (:authors ("rubikitch" . "rubikitch@ruby-lang.org")) (:maintainer "rubikitch" . "rubikitch@ruby-lang.org") (:keywords "convenience" "tools") (:url . "http://www.emacswiki.org/cgi-bin/wiki/download/open-junk-file.el"))])
+ (opencc . [(20170722 816) ((emacs (24 4))) "中文简繁转换 <-> 中文簡繁轉換 (Convert Chinese with OpenCC)" single ((:commit . "8c539f72669ba9a99d8b5198db5ea930897ad1b9") (:authors ("徐春阳" . "mail@xuchunyang.me")) (:maintainer "徐春阳" . "mail@xuchunyang.me") (:keywords "chinese") (:url . "https://github.com/xuchunyang/emacs-opencc"))])
+ (opencl-mode . [(20201025 1656) nil "Syntax coloring for opencl kernels" single ((:commit . "15091eff92c33ee0d1ece40eb99299ef79fee92d") (:authors ("Salmane Bah" . "salmane.bah@u-bordeaux.fr")) (:maintainer "Salmane Bah" . "salmane.bah@u-bordeaux.fr") (:keywords "c" "opencl") (:url . "https://github.com/salmanebah/opencl-mode"))])
+ (opener . [(20161207 1810) ((request (0 2 0)) (emacs (24)) (cl-lib (0 5))) "opening urls as buffers" tar ((:commit . "c384f67278046fdcd220275fdd212ab85672cbeb") (:authors ("Tim Reddehase" . "tr@rightsrestricted.com")) (:maintainer "Tim Reddehase" . "tr@rightsrestricted.com") (:keywords "url" "http" "files") (:url . "https://github.com/0robustus1/opener.el"))])
+ (openfoam . [(20210516 1015) ((emacs (25 1))) "OpenFOAM files and directories" single ((:commit . "e2c899009a9df412bf9f360492b1072eb6f1513f") (:authors ("Ralph Schleicher" . "rs@ralph-schleicher.de")) (:maintainer "Ralph Schleicher" . "rs@ralph-schleicher.de") (:keywords "languages") (:url . "https://github.com/ralph-schleicher/emacs-openfoam"))])
+ (opensource . [(20160926 1616) ((s (1 11 0)) (dash (2 12 1)) (pkg-info (0 6 0)) (request (0 2 0))) "Client for Opensource API" tar ((:commit . "4c15049079878fcd386cca5dba20b99296a1de84") (:authors ("Nicolas Lamirault" . "nicolas.lamirault@gmail.com")) (:maintainer "Nicolas Lamirault" . "nicolas.lamirault@gmail.com") (:keywords "opensource") (:url . "https://github.com/OpenSourceOrg/el-opensourceorg"))])
+ (openstack-cgit-browse-file . [(20130819 927) nil "Browse the current file in OpenStack cgit" single ((:commit . "244219288b9aef41155044697bb114b7af83ab8f") (:authors ("Chmouel Boudjnah" . "chmouel@chmouel.com")) (:maintainer "Chmouel Boudjnah" . "chmouel@chmouel.com") (:keywords "convenience" "vc" "git" "cgit" "gerrit" "openstack") (:url . "https://github.com/chmouel/openstack-cgit-browse-file"))])
+ (openwith . [(20120531 2136) nil "Open files with external programs" single ((:commit . "1dc89670822966fab6e656f6519fdd7f01e8301a") (:authors ("Markus Triska" . "markus.triska@gmx.at")) (:maintainer "Markus Triska" . "markus.triska@gmx.at") (:keywords "files" "processes") (:url . "https://bitbucket.org/jpkotta/openwith"))])
+ (operate-on-number . [(20150707 623) nil "Operate on number at point with arithmetic functions" single ((:commit . "ceb3be565a29326c1098244fac0c50606723a56e") (:authors ("Akinori MUSHA" . "knu@iDaemons.org")) (:maintainer "Akinori MUSHA" . "knu@iDaemons.org") (:keywords "editing") (:url . "https://github.com/knu/operate-on-number.el"))])
+ (orca . [(20210828 1639) ((emacs (24 3)) (zoutline (0 1 0))) "Org Capture" single ((:commit . "47c03af0c1df2b679d800f3708d675a4c2a3e722") (:authors ("Oleh Krehel" . "ohwoeowho@gmail.com")) (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com") (:keywords "org" "convenience") (:url . "https://github.com/abo-abo/orca"))])
+ (orderless . [(20220418 2119) ((emacs (26 1))) "Completion style for matching regexps in any order" tar ((:commit . "75eeae21971d86b51a712ed8ecd6434463b2d866") (:authors ("Omar Antolín Camarena" . "omar@matem.unam.mx")) (:maintainer "Omar Antolín Camarena" . "omar@matem.unam.mx") (:keywords "extensions") (:url . "https://github.com/oantolin/orderless"))])
+ (ordinal . [(20210519 1442) ((emacs (24 3))) "Convert number to ordinal number notation" single ((:commit . "a7f378306290b6807fb6b87cee3ef79b31cec711") (:authors ("USAMI Kenta" . "tadsan@zonu.me")) (:maintainer "USAMI Kenta" . "tadsan@zonu.me") (:keywords "lisp") (:url . "https://github.com/zonuexe/ordinal.el"))])
+ (org-ac . [(20170401 1307) ((auto-complete-pcmp (0 0 1)) (log4e (0 2 0)) (yaxception (0 1))) "Some auto-complete sources for org-mode" single ((:commit . "41e3ef8e4039619d0370c23c66730b3b2e9e32ed") (:authors ("Hiroaki Otsu" . "ootsuhiroaki@gmail.com")) (:maintainer "Hiroaki Otsu" . "ootsuhiroaki@gmail.com") (:keywords "org" "completion") (:url . "https://github.com/aki2o/org-ac"))])
+ (org-agenda-property . [(20140626 2116) ((emacs (24 2))) "Display org properties in the agenda buffer." single ((:commit . "3b469f3e93de0036547f3631cd0366d53f7584c8") (:authors ("Artur Malabarba" . "bruce.connor.am@gmail.com")) (:maintainer "Artur Malabarba" . "bruce.connor.am@gmail.com") (:keywords "calendar") (:url . "http://github.com/Bruce-Connor/org-agenda-property"))])
+ (org-alert . [(20210922 125) ((org (9 0)) (alert (1 2))) "Notify org deadlines via notify-send" single ((:commit . "c039d0121d21e4558c0f5433135c839679b556d7") (:authors ("Stephen Pegoraro" . "spegoraro@tutive.com")) (:maintainer "Stephen Pegoraro" . "spegoraro@tutive.com") (:keywords "org" "org-mode" "notify" "notifications" "calendar") (:url . "https://github.com/spegoraro/org-alert"))])
+ (org-analyzer . [(20191001 1717) nil "org-analyzer is a tool that extracts time tracking data from org files." tar ((:commit . "19da62aa4dcf1090be8f574f6f2d4c7e116163a8") (:authors ("Robert Krahn" . "robert@kra.hn")) (:maintainer "Robert Krahn" . "robert@kra.hn") (:keywords "calendar") (:url . "https://github.com/rksm/clj-org-analyzer"))])
+ (org-anki . [(20220302 1706) ((emacs (27 1)) (request (0 3 2)) (dash (2 17)) (promise (1 1))) "Synchronize org-mode entries to Anki" single ((:commit . "c1790b1cdd2e5733cf64c7507a89da0b6179cf7d") (:authors ("Markus Läll" . "markus.l2ll@gmail.com")) (:maintainer "Markus Läll" . "markus.l2ll@gmail.com") (:keywords "outlines" "flashcards" "memory") (:url . "https://github.com/eyeinsky/org-anki"))])
+ (org-appear . [(20220405 1146) ((emacs (25 1)) (org (9 3))) "Auto-toggle Org elements" single ((:commit . "8dd1e564153d8007ebc4bb4e14250bde84e26a34") (:authors ("Alice Istleyeva" . "awth13@gmail.com")) (:maintainer "Alice Istleyeva" . "awth13@gmail.com") (:url . "https://github.com/awth13/org-appear"))])
+ (org-arbeitszeit . [(20220328 1951) ((emacs (27 1))) "Calculate your worktime" single ((:commit . "60e6adfe457bcc4ee47e3e5805b6b40544f98ee0") (:authors ("Benjamin Kästner" . "benjamin.kaestner@gmail.com")) (:maintainer "Benjamin Kästner" . "benjamin.kaestner@gmail.com") (:keywords "tools" "org" "calendar" "convenience") (:url . "https://github.com/bkaestner/org-arbeitszeit"))])
+ (org-attach-screenshot . [(20210221 1336) ((emacs (24 3))) "Screenshots integrated with org attachment dirs" single ((:commit . "55fa23e69c8ac4c40f8600300301a9cdc5c6732f") (:authors ("Derek Feichtinger" . "derek.feichtinger@psi.ch")) (:maintainer "Derek Feichtinger" . "derek.feichtinger@psi.ch") (:keywords "org" "multimedia") (:url . "https://github.com/dfeich/org-screenshot"))])
+ (org-auto-expand . [(20210923 243) ((emacs (26 1))) "Automatically expand certain headings" single ((:commit . "edc27b155befab5626dcf6ceec7938126f7e31d4") (:authors ("Adam Porter" . "adam@alphapapa.net")) (:maintainer "Adam Porter" . "adam@alphapapa.net") (:keywords "convenience" "outlines" "org") (:url . "https://github.com/alphapapa/org-auto-expand"))])
+ (org-auto-tangle . [(20211115 543) ((emacs (24 1)) (async (1 9 3))) "Automatically and Asynchronously tangles org files on save" single ((:commit . "5d9f2734c96166722c5057f3a2641ff8e08184cc") (:authors ("Yilkal Argaw")) (:maintainer "Yilkal Argaw") (:keywords "outlines") (:url . "https://github.com/yilkalargaw/org-auto-tangle"))])
+ (org-autolist . [(20211225 658) nil "Improved list management in org-mode" single ((:commit . "48666001f9ae1fdf9e295410d5a494e79284e2f7") (:authors ("Calvin Young")) (:maintainer "Calvin Young") (:keywords "lists" "checklists" "org-mode") (:url . "https://github.com/calvinwyoung/org-autolist"))])
+ (org-babel-eval-in-repl . [(20201206 1540) ((eval-in-repl (0 9 2)) (matlab-mode (3 3 6)) (ess (16 10)) (emacs (24))) "Eval org-mode babel code blocks in various REPLs." tar ((:commit . "3591f062873de2d64cc6f83b3555d030506e6ee7") (:authors ("Takeshi Teshima" . "diadochos.developer@gmail.com")) (:maintainer "Takeshi Teshima" . "diadochos.developer@gmail.com") (:keywords "literate programming" "reproducible research" "async execution") (:url . "https://github.com/diadochos/org-babel-eval-in-repl"))])
+ (org-beautify-theme . [(20170908 2218) nil "A sub-theme to make org-mode more beautiful." single ((:commit . "df6a1114fda313e1689363e196c8284fbe2a2738") (:authors ("Jonathan Arkell" . "jonnay@jonnay.net")) (:maintainer "Jonathan Arkell" . "jonnay@jonnay.net") (:keywords "org" "theme"))])
+ (org-board . [(20200619 1016) nil "bookmarking and web archival system for Org mode." single ((:commit . "1393bd46d11a81328ed4fb8471831415a3efe224") (:authors ("Charles A. Roelli " . "charles@aurox.ch")) (:maintainer "Charles A. Roelli " . "charles@aurox.ch") (:keywords "org" "bookmarks" "archives") (:url . "https://github.com/scallywag/org-board"))])
+ (org-bookmark-heading . [(20200103 514) ((emacs (24 4)) (f (0 17 2))) "Emacs bookmark support for org-mode" single ((:commit . "38a2813f72ff65f3ae91e2ebb23e0bbb42a8d1df") (:authors ("Adam Porter" . "adam@alphapapa.net")) (:maintainer "Adam Porter" . "adam@alphapapa.net") (:keywords "hypermedia" "outlines") (:url . "http://github.com/alphapapa/org-bookmark-heading"))])
+ (org-books . [(20210408 1913) ((enlive (0 0 1)) (s (1 11 0)) (helm (2 9 2)) (helm-org (1 0)) (dash (2 14 1)) (org (9 3)) (emacs (25))) "Reading list management with Org mode and helm" single ((:commit . "9f4ec4a981bfc5eebff993c3ad49a4bed26aebd1") (:authors ("Abhinav Tushar" . "abhinav@lepisma.xyz")) (:maintainer "Abhinav Tushar" . "abhinav@lepisma.xyz") (:keywords "outlines") (:url . "https://github.com/lepisma/org-books"))])
+ (org-brain . [(20210706 1519) ((emacs (25 1)) (org (9 2))) "Org-mode concept mapping" single ((:commit . "46ca9f766322cff31279ecdf02251ff24a0e9431") (:authors ("Erik Sjöstrand" . "sjostrand.erik@gmail.com")) (:maintainer "Erik Sjöstrand" . "sjostrand.erik@gmail.com") (:keywords "outlines" "hypermedia") (:url . "http://github.com/Kungsgeten/org-brain"))])
+ (org-bullets . [(20200317 1740) nil "Show bullets in org-mode as UTF-8 characters" single ((:commit . "767f55feb58b840a5a04eabfc3fbbf0d257c4792") (:authors ("sabof")) (:maintainer "D. Williams" . "d.williams@posteo.net") (:url . "https://github.com/integral-dw/org-bullets"))])
+ (org-caldav . [(20200510 2030) ((org (7))) "Sync org files with external calendar through CalDAV" single ((:commit . "8569941a0a5a9393ba51afc8923fd7b77b73fa7a") (:authors ("David Engster" . "deng@randomsample.de")) (:maintainer "David Engster" . "deng@randomsample.de") (:keywords "calendar" "caldav"))])
+ (org-capture-pop-frame . [(20160518 1008) ((emacs (24 4))) "Run org-capture in a new pop frame" single ((:commit . "b16fd712de62cf0d1f9befd03be6ab5983cb3301") (:authors ("Feng Shu" . "tumashu@163.com")) (:maintainer "Feng Shu" . "tumashu@163.com") (:url . "https://github.com/tumashu/org-capture-pop-frame.git"))])
+ (org-category-capture . [(20220114 730) ((org (9 0 0)) (emacs (24))) "Contextualy capture of org-mode TODOs." single ((:commit . "642b39c698db00bc535c1c2335f425fb9f4855a9") (:authors ("Ivan Malison" . "IvanMalison@gmail.com")) (:maintainer "Ivan Malison" . "IvanMalison@gmail.com") (:keywords "org-mode" "todo" "tools" "outlines") (:url . "https://github.com/IvanMalison/org-projectile"))])
+ (org-chef . [(20220422 300) ((org (0)) (emacs (24))) "Cookbook and recipe management with org-mode." tar ((:commit . "6a786e77e67a715b3cd4f5128b59d501614928af") (:authors ("Calvin Beck" . "hobbes@ualberta.ca")) (:maintainer "Calvin Beck" . "hobbes@ualberta.ca") (:keywords "convenience" "abbrev" "outlines" "org" "food" "recipes" "cooking") (:url . "https://github.com/Chobbes/org-chef"))])
+ (org-cliplink . [(20201126 1020) ((emacs (24 4))) "insert org-mode links from the clipboard" tar ((:commit . "13e0940b65d22bec34e2de4bc8cba1412a7abfbc") (:authors ("Alexey Kutepov" . "reximkut@gmail.com")) (:maintainer "Alexey Kutepov" . "reximkut@gmail.com") (:url . "http://github.com/rexim/org-cliplink"))])
+ (org-clock-convenience . [(20220503 530) ((org (8)) (emacs (24 3))) "Convenience functions for org time tracking" single ((:commit . "988d4e3c9f0ae6df098b0ab1985b79eed2c5b808") (:authors ("Derek Feichtinger <dfeich.gmail.com>")) (:maintainer "Derek Feichtinger <dfeich.gmail.com>") (:keywords "convenience") (:url . "https://github.com/dfeich/org-clock-convenience"))])
+ (org-clock-csv . [(20201222 1506) ((org (8 3)) (s (1 0))) "Export `org-mode' clock entries to CSV format." single ((:commit . "af94b58c2e179a5bcc938f339e93de0eee3da99c") (:authors ("Aaron Jacobs" . "atheriel@gmail.com")) (:maintainer "Aaron Jacobs" . "atheriel@gmail.com") (:keywords "calendar" "data" "org") (:url . "https://github.com/atheriel/org-clock-csv"))])
+ (org-clock-reminder . [(20211010 2139) ((emacs (26 1))) "Notifications that remind you about clocked-in tasks" tar ((:commit . "9f9b88348ffbc6628f2286dcb4c064b520d0a638") (:authors ("Nikolay Brovko" . "i@nickey.ru")) (:maintainer "Nikolay Brovko" . "i@nickey.ru") (:keywords "calendar" "convenience") (:url . "https://github.com/inickey/org-clock-reminder"))])
+ (org-clock-split . [(20200331 526) ((emacs (24))) "Split clock entries" single ((:commit . "39e1d2912a7a7223e2356a5fc4dff03507ae084d") (:authors ("Justin Taft <https://github.com/justintaft>")) (:maintainer "Justin Taft <https://github.com/justintaft>") (:keywords "calendar") (:url . "https://github.com/justintaft/emacs-org-clock-split"))])
+ (org-clock-today . [(20191204 1558) ((emacs (25))) "Show total clocked time of the current day in the mode line" single ((:commit . "e326a45b60e0fd4ca057f1d1dc3e99a516a5aa2f") (:authors ("Tijs Mallaerts" . "tijs.mallaerts@gmail.com")) (:maintainer "Tijs Mallaerts" . "tijs.mallaerts@gmail.com") (:url . "https://github.com/mallt/org-clock-today-mode"))])
+ (org-commentary . [(20160802 637) ((dash (2 0)) (emacs (24 4)) (org (8 0))) "generate or update conventional library headers using Org mode files" tar ((:commit . "821ccb994811359c42f4e3d459e0e88849d42b75") (:authors ("Sergei Maximov" . "s.b.maximov@gmail.com")) (:maintainer "Sergei Maximov" . "s.b.maximov@gmail.com") (:keywords "convenience" "docs" "tools") (:url . "https://github.com/smaximov/org-commentary"))])
+ (org-context . [(20210216 1526) nil "Contextual capture and agenda commands for Org-mode" single ((:commit . "a08f1f607f819791b9b95ad4f91c5eaa9fdbb091") (:authors ("Sylvain Rousseau <thisirs at gmail dot com>")) (:maintainer "Sylvain Rousseau <thisirs at gmail dot com>") (:keywords "org" "capture" "agenda" "convenience") (:url . "https://github.com/thisirs/org-context"))])
+ (org-cua-dwim . [(20120203 534) nil "Org-mode and Cua mode compatibility layer" single ((:commit . "a55d6c7009fc0b22f1110c07de629acc955c85e4") (:authors ("Matthew L. Fidler")) (:maintainer "Matthew L. Fidler") (:keywords "org-mode" "cua-mode"))])
+ (org-d20 . [(20210212 139) ((s (1 11 0)) (seq (2 19)) (dash (2 12 0)) (emacs (24))) "minor mode for d20 tabletop roleplaying games" single ((:commit . "e6149dcfbb6302d10109dd792fd0ffae7bfe2595") (:authors ("Sean Whitton" . "spwhitton@spwhitton.name")) (:maintainer "Sean Whitton" . "spwhitton@spwhitton.name") (:keywords "outlines" "games") (:url . "https://spwhitton.name/tech/code/org-d20/"))])
+ (org-dashboard . [(20171223 1924) ((cl-lib (0 5))) "Visually summarize progress in org files" single ((:commit . "02c0699771d199075a286e4502340ca6e7c9e831") (:authors ("Massimiliano Mirra" . "hyperstruct@gmail.com")) (:maintainer "Massimiliano Mirra" . "hyperstruct@gmail.com") (:keywords "outlines" "calendar") (:url . "http://github.com/bard/org-dashboard"))])
+ (org-doing . [(20161017 1620) nil "Keep track of what you're doing" tar ((:commit . "07ddbfc238cba31e4990c9b52e9a2757b39111da") (:authors ("Rudolf Olah")) (:maintainer "Rudolf Olah") (:keywords "tools" "org") (:url . "https://github.com/omouse/org-doing"))])
+ (org-dotemacs . [(20211126 2038) ((org (7 9 3)) (cl-lib (0 5))) "Store your emacs config as an org file, and choose which bits to load." single ((:commit . "598759f4a139f94da62836e8f8064da6377536b2") (:authors ("Joe Bloggs" . "vapniks@yahoo.com")) (:maintainer "Joe Bloggs" . "vapniks@yahoo.com") (:keywords "local") (:url . "https://github.com/vapniks/org-dotemacs"))])
+ (org-download . [(20210118 958) ((emacs (24 3)) (async (1 2))) "Image drag-and-drop for Org-mode." single ((:commit . "947ca223643d28e189480e607df68449c15786cb") (:authors ("Oleh Krehel")) (:maintainer "Oleh Krehel") (:keywords "multimedia" "images" "screenshots" "download") (:url . "https://github.com/abo-abo/org-download"))])
+ (org-dp . [(20180311 923) ((cl-lib (0 5))) "Declarative Local Programming with Org Elements" tar ((:commit . "e720f1c155a795a5b65a04790ad195c413449716") (:authors ("Thorsten Jolitz <tjolitz AT gmail DOT com>")) (:maintainer "Thorsten Jolitz <tjolitz AT gmail DOT com>") (:url . "https://github.com/tj64/org-dp"))])
+ (org-drill . [(20210427 2003) ((emacs (25 3)) (seq (2 14)) (org (9 3)) (persist (0 3))) "Self-testing using spaced repetition" single ((:commit . "bf8fe812d44a3ce3e84361fb39b8ef28ca10fd0c") (:authors ("Paul Sexton" . "eeeickythump@gmail.com")) (:maintainer "Phillip Lord" . "phillip.lord@russet.org.uk") (:keywords "games" "outlines" "multimedia") (:url . "https://gitlab.com/phillord/org-drill/issues"))])
+ (org-drill-table . [(20180115 1009) ((s (1 7 0)) (dash (2 2 0)) (cl-lib (0 3)) (org (8 2)) (emacs (24 1))) "Generate drill cards from org tables" single ((:commit . "2729aaa42c1e2720d9bf7bcc125e92dcf48b7f7d") (:authors ("Chris Barrett" . "chris.d.barrett@me.com")) (:maintainer "Chris Barrett" . "chris.d.barrett@me.com"))])
+ (org-dropbox . [(20150114 509) ((dash (2 2)) (names (20150000)) (emacs (24))) "move Dropbox notes from phone into org-mode datetree" single ((:commit . "75dab6d6f0438a7a8a18ccf3a5d55f50bf531f6e") (:authors ("Heikki Lehvaslaiho" . "heikki.lehvaslaiho@gmail.com")) (:maintainer "Heikki Lehvaslaiho" . "heikki.lehvaslaiho@gmail.com") (:keywords "dropbox" "android" "notes" "org-mode") (:url . "https://github.com/heikkil/org-dropbox"))])
+ (org-easy-img-insert . [(20160915 2008) ((emacs (24 4))) "An easier way to add images from the web in org mode" single ((:commit . "9f8aaa7f68ff1f0d8d7b1e9b618abb15002f971e") (:authors ("Tashrif Sanil" . "tashrifsanil@kloke-source.com")) (:maintainer "Tashrif Sanil" . "tashrifsanil@kloke-source.com") (:keywords "convenience" "hypermedia" "files") (:url . "https://github.com/tashrifsanil/org-easy-img-insert"))])
+ (org-edit-latex . [(20170908 1522) ((emacs (24 4)) (auctex (11 90))) "Edit embedded LaTeX in a dedicated buffer" single ((:commit . "1f228310ef2f3f2959a527f6d99e42ce977384c8") (:authors ("James Wong" . "jianwang.academic@gmail.com")) (:maintainer "James Wong" . "jianwang.academic@gmail.com") (:keywords "org" "latex") (:url . "https://github.com/et2010/org-edit-latex"))])
+ (org-ehtml . [(20220216 2054) ((web-server (20140109 2200)) (emacs (24 3))) "Export Org-mode files as editable web pages" tar ((:commit . "419932d6dbce193b0d90b1ccf9bf643169d21f52") (:authors ("Eric Schulte" . "schulte.eric@gmail.com")) (:maintainer "Eric Schulte" . "schulte.eric@gmail.com") (:keywords "org" "web-server" "javascript" "html"))])
+ (org-elisp-help . [(20161122 55) ((cl-lib (0 5)) (org (9 0))) "org links to emacs-lisp documentation" single ((:commit . "3e33ab1a2933dd7f2782ef91d667a37f12d633ab") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:keywords "org" "remember" "lisp") (:url . "https://github.com/tarsius/org-elisp-help"))])
+ (org-elp . [(20210329 1535) ((emacs (27 1))) "Preview latex equations in org mode while editing" single ((:commit . "36b5ab2ed3fa3b5917f058e3acf8dff2df69efae") (:authors ("Yilun Guan")) (:maintainer "Yilun Guan") (:keywords "lisp" "tex" "org") (:url . "https://github.com/guanyilun/org-elp"))])
+ (org-emms . [(20181010 1114) ((emacs (24))) "Play multimedia files from org-mode" single ((:commit . "07a8917f3d628c32e5de1dbd118ac08203772533") (:authors ("Jonathan Gregory <jgrg at autistici dot org>")) (:maintainer "Jonathan Gregory <jgrg at autistici dot org>") (:keywords "multimedia") (:url . "https://gitlab.com/jagrg/org-emms"))])
+ (org-evil . [(20210809 1724) ((dash (2 19 0)) (evil (0)) (org (9 4 4))) "Evil extensions for Org." tar ((:commit . "981b0931d043d3b0eb61fcab6258b5a88cc74d15") (:authors ("Ben Moon" . "software@guiltydolphin.com")) (:maintainer "Ben Moon" . "software@guiltydolphin.com") (:keywords "convenience" "evil" "org") (:url . "https://github.com/guiltydolphin/org-evil"))])
+ (org-fancy-priorities . [(20210830 1657) nil "Display org priorities as custom strings" single ((:commit . "7f677c6c14ecf05eab8e0efbfe7f1b00ae68eb1d") (:authors ("Harry Bournis" . "harrybournis@gmail.com")) (:maintainer "Harry Bournis" . "harrybournis@gmail.com") (:keywords "convenience" "faces" "outlines") (:url . "https://github.com/harrybournis/org-fancy-priorities"))])
+ (org-fragtog . [(20220110 2211) ((emacs (27 1))) "Auto-toggle Org LaTeX fragments" single ((:commit . "680606189d5d28039e6f9301b55ec80517a24005") (:authors ("Benjamin Levy" . "blevy@protonmail.com")) (:maintainer "Benjamin Levy" . "blevy@protonmail.com") (:url . "https://github.com/io12/org-fragtog"))])
+ (org-gamedb . [(20210525 2338) ((emacs (25 1))) "Track video games in org-mode with giantbomb.com's API" single ((:commit . "f283b6f6a7e8ad090405be57202caa3d3c424447") (:authors ("repelliuss <https://github.com/repelliuss>")) (:maintainer "repelliuss" . "repelliuss@gmail.com") (:keywords "outlines" "org" "games" "convenience" "api") (:url . "https://github.com/repelliuss/org-gamedb"))])
+ (org-gcal . [(20220324 1852) ((request (20190901)) (request-deferred (20181129)) (alert (0)) (persist (0)) (emacs (26)) (org (9 3))) "Org sync with Google Calendar" tar ((:commit . "554c48fb57dc46877202028019197b0699961ca0") (:authors ("myuhe <yuhei.maeda_at_gmail.com>")) (:maintainer "Raimon Grau" . "raimonster@gmail.com") (:keywords "convenience") (:url . "https://github.com/kidd/org-gcal.el"))])
+ (org-generate . [(20200815 736) ((emacs (26 1)) (org (9 3)) (mustache (0 23))) "Generate template files/folders from org document" single ((:commit . "98825efb73c4537f05f653ce40e639a220d2ee5d") (:authors ("Naoya Yamashita" . "conao3@gmail.com")) (:maintainer "Naoya Yamashita" . "conao3@gmail.com") (:keywords "convenience") (:url . "https://github.com/conao3/org-generate.el"))])
+ (org-gnome . [(20150614 1457) ((alert (1 2)) (telepathy (0 1)) (gnome-calendar (0 1))) "Orgmode integration with the GNOME desktop" single ((:commit . "122e14cf6f8104150a65246a9a7c10e1d7939862") (:authors ("Nicolas Petton" . "petton.nicolas@gmail.com")) (:maintainer "Nicolas Petton" . "petton.nicolas@gmail.com") (:keywords "org" "gnome"))])
+ (org-grep . [(20151202 1229) ((cl-lib (0 5))) "Kind of M-x rgrep adapted for Org mode." single ((:commit . "5bdd04c0f53b8a3d656f36ea17bba3df7f0cb684") (:authors ("François Pinard" . "pinard@iro.umontreal.ca")) (:maintainer "François Pinard" . "pinard@iro.umontreal.ca") (:url . "https://github.com/pinard/org-grep"))])
+ (org-gtd . [(20220213 41) ((emacs (27 1)) (org-edna (1 1 2)) (f (0 20 0)) (org (9 3 1)) (org-agenda-property (1 3 1)) (transient (0 3 7))) "An implementation of GTD." tar ((:commit . "4e0fcf9a440e463d395f8f37efe8f1e691ed07dc") (:authors ("Aldric Giacomoni" . "trevoke@gmail.com")) (:maintainer "Aldric Giacomoni" . "trevoke@gmail.com") (:url . "https://github.com/Trevoke/org-gtd.el"))])
+ (org-id-cleanup . [(20220228 1653) ((org (9 3)) (dash (2 12)) (emacs (26 3))) "Interactively find, present and maybe clean up unused IDs of org-id" single ((:commit . "b6bf79465cd31d66b547704903b8ba5fcd6dd108") (:authors ("Marc Ihm" . "marc@ihm.name")) (:maintainer "Marc Ihm" . "marc@ihm.name") (:url . "https://github.com/marcIhm/org-id-cleanup"))])
+ (org-if . [(20150920 1513) nil "Interactive Fiction Authoring System for Org-Mode." tar ((:commit . "fab602cc1bbee7a4e99c0083e129219d3f9ed2e8") (:authors ("Philip Woods" . "elzairthesorcerer@gmail.com")) (:maintainer "Philip Woods" . "elzairthesorcerer@gmail.com") (:keywords "if" "org-if" "org org-mode"))])
+ (org-index . [(20220228 1651) ((org (9 3)) (dash (2 12)) (s (1 12)) (emacs (26 3))) "A personal adaptive index for org" single ((:commit . "9671cf059b681fac39ce910dd8847b5c7bfad170") (:authors ("Marc Ihm" . "1@2484.de")) (:maintainer "Marc Ihm" . "1@2484.de") (:url . "https://github.com/marcIhm/org-index"))])
+ (org-inline-anim . [(20211101 413) ((emacs (25 3)) (org (9 4))) "Inline playback of animated GIF/PNG for Org" single ((:commit . "ea7feb924c991f3a2cdc4a70fb176eaceae87938") (:authors ("Shigeaki Nishina")) (:maintainer "Shigeaki Nishina") (:keywords "org" "outlines" "hypermedia" "multimedia") (:url . "https://github.com/shg/org-inline-anim.el"))])
+ (org-inline-pdf . [(20220429 1012) ((emacs (25 1)) (org (9 4))) "Inline PDF previewing for Org" single ((:commit . "b790818ecbb85cd6dee44754935eb12153a79679") (:authors ("Shigeaki Nishina")) (:maintainer "Shigeaki Nishina") (:keywords "org" "outlines" "hypermedia") (:url . "https://github.com/shg/org-inline-pdf.el"))])
+ (org-iv . [(20171001 1022) ((impatient-mode (1 0 0)) (org (8 0)) (cl-lib (0 5))) "a tool used to view html (in browser) generated by org-file once the org-file changes" tar ((:commit . "7f2bb1b32647655fd9d6684f6f09dcc66b61b0cd") (:authors ("kuangdash" . "kuangdash@163.com")) (:maintainer "kuangdash" . "kuangdash@163.com") (:url . "https://github.com/kuangdash/org-iv"))])
+ (org-jira . [(20220328 407) ((emacs (24 5)) (cl-lib (0 5)) (request (0 2 0)) (dash (2 14 1))) "Syncing between Jira and Org-mode." tar ((:commit . "502de6d31d0b2fd8480787461b7167d5dd3b088a") (:maintainer "Matthew Carter" . "m@ahungry.com") (:keywords "ahungry" "jira" "org" "bug" "tracker") (:url . "https://github.com/ahungry/org-jira"))])
+ (org-journal . [(20220408 629) ((emacs (25 1)) (org (9 1))) "a simple org-mode based journaling mode" single ((:commit . "839a2e19865a03bec30ef32431f981f33880a754") (:authors ("Bastian Bechtold") ("Christian Schwarzgruber")) (:maintainer "Bastian Bechtold") (:url . "http://github.com/bastibe/org-journal"))])
+ (org-journal-list . [(20190221 2052) ((emacs (25))) "Org mode Journal List" single ((:commit . "2b26d00181bb49bff64b31ad020490acd1b6ae02") (:authors ("Huy Tran" . "huytd189@gmail.com")) (:maintainer "Huy Tran" . "huytd189@gmail.com") (:url . "https://github.com/huytd/org-journal-list"))])
+ (org-journal-tags . [(20220416 1507) ((emacs (27 1)) (org-journal (2 1 2)) (magit-section (3 3 0)) (transient (0 3 7))) "Tagging and querying system of org-journal" single ((:commit . "ca6327161f4994ea0e98d7c6c3f662222e2650bf") (:authors ("Korytov Pavel" . "thexcloud@gmail.com")) (:maintainer "Korytov Pavel" . "thexcloud@gmail.com") (:url . "https://github.com/SqrtMinusOne/org-journal-tags"))])
+ (org-kanban . [(20220218 1845) ((s (0)) (dash (2 17 0)) (emacs (24 4)) (org (9 1))) "kanban dynamic block for org-mode." single ((:commit . "5310e208d151f460f9b7e3961b4796842e91a3ae") (:authors ("Christian Köstlin" . "christian.koestlin@gmail.com")) (:maintainer "Christian Köstlin" . "christian.koestlin@gmail.com") (:keywords "org-mode" "org" "kanban" "tools") (:url . "http://github.com/gizmomogwai/org-kanban"))])
+ (org-kindle . [(20220210 1408) ((emacs (25)) (cl-lib (0 5)) (seq (2 20))) "Send org link file to ebook reader." single ((:commit . "fadcfd62e254d0c45e87d63128a82a08ae21869a") (:keywords "org" "link" "ebook" "kindle" "epub" "azw3" "mobi") (:url . "https://repo.or.cz/org-kindle.git"))])
+ (org-latex-impatient . [(20210409 2251) ((emacs (26)) (s (1 8 0)) (posframe (0 8 0)) (org (9 3)) (dash (2 17 0))) "Preview org-latex Fragments Instantly via MathJax" single ((:commit . "832bbb9bbdee8b58170c984ead487f3ad612820c") (:authors ("Sheng Yang" . "styang@fastmail.com")) (:maintainer "Sheng Yang" . "styang@fastmail.com") (:keywords "tex" "tools") (:url . "https://github.com/yangsheng6810/org-latex-instant-preview"))])
+ (org-link-beautify . [(20220503 458) ((emacs (27 1)) (all-the-icons (4 0 0))) "Beautify Org Links" single ((:commit . "b20e296b497360de12d5d973aa273cab70c77126") (:keywords "hypermedia") (:url . "https://repo.or.cz/org-link-beautify.git"))])
+ (org-link-travis . [(20140405 2327) ((org (7))) "Insert/Export the link of Travis CI on org-mode" single ((:commit . "596615ad8373d9090bd4138da683524f0ad0bda5") (:authors ("Hiroaki Otsu" . "ootsuhiroaki@gmail.com")) (:maintainer "Hiroaki Otsu" . "ootsuhiroaki@gmail.com") (:keywords "org") (:url . "https://github.com/aki2o/org-link-travis"))])
+ (org-linkotron . [(20200112 2235) ((emacs (26 1)) (org (9 3))) "Org-mode link selector" tar ((:commit . "d0adc5247b205bc73d2f1a83d4a512d2be541eb5") (:authors ("Per Weijnitz" . "per.weijnitz@gmail.com")) (:maintainer "Per Weijnitz" . "per.weijnitz@gmail.com") (:keywords "hypermedia" "org") (:url . "https://gitlab.com/perweij/org-linkotron"))])
+ (org-listcruncher . [(20210706 1741) ((seq (2 3)) (emacs (26 1))) "Planning tool - Parse Org mode lists into table" single ((:commit . "075e0e6d36eb50406a608bc8a2f0dd359ec63938") (:authors ("Derek Feichtinger" . "dfeich@gmail.com")) (:maintainer "Derek Feichtinger" . "dfeich@gmail.com") (:keywords "convenience") (:url . "https://github.com/dfeich/org-listcruncher"))])
+ (org-make-toc . [(20200409 1436) ((emacs (26 1)) (dash (2 12)) (s (1 10 0)) (org (9 0))) "Automatic tables of contents for Org files" single ((:commit . "26fbd6a7e1e7f8e473fe3a5f74faec715c3a05aa") (:authors ("Adam Porter" . "adam@alphapapa.net")) (:maintainer "Adam Porter" . "adam@alphapapa.net") (:keywords "org" "convenience") (:url . "http://github.com/alphapapa/org-make-toc"))])
+ (org-mime . [(20220204 42) ((emacs (25 1))) "org html export for text/html MIME emails" single ((:commit . "a7bf07316f93015e4f853ea0fc5b8d05b4a7695d") (:authors ("Eric Schulte")) (:maintainer "Chen Bin (redguardtoo)") (:keywords "mime" "mail" "email" "html") (:url . "http://github.com/org-mime/org-mime"))])
+ (org-mind-map . [(20180826 2340) ((emacs (24)) (dash (1 8 0)) (org (8 2 10))) "Creates a directed graph from org-mode files" single ((:commit . "95347b2f9291f5c5eb6ebac8e726c03634c61de3") (:authors ("Ted Wiles" . "theodore.wiles@gmail.com")) (:maintainer "Ted Wiles" . "theodore.wiles@gmail.com") (:keywords "orgmode" "extensions" "graphviz" "dot") (:url . "https://github.com/theodorewiles/org-mind-map"))])
+ (org-ml . [(20211231 700) ((emacs (26 1)) (org (9 3)) (dash (2 17)) (s (1 12))) "Functional Org Mode API" tar ((:commit . "3974435bbf72722801f7ed78855381d77a773162") (:authors ("Nathan Dwarshuis" . "ndwar@yavin4.ch")) (:maintainer "Nathan Dwarshuis" . "ndwar@yavin4.ch") (:keywords "org-mode" "outlines") (:url . "https://github.com/ndwarshuis/org-ml"))])
+ (org-mobile-sync . [(20180606 524) ((emacs (24 3 50)) (org (8 0))) "automatically sync org-mobile on changes" single ((:commit . "06764b943a528827df1e2acc6bc7806cc2c1351f") (:authors ("steckerhalter")) (:maintainer "steckerhalter") (:keywords "org-mode" "org" "mobile" "sync" "todo") (:url . "https://framagit.org/steckerhalter/org-mobile-sync"))])
+ (org-modern . [(20220422 940) ((emacs (27 1))) "Modern looks for Org" single ((:commit . "ff1046705b3950b7a49da50bc34c11da86c6226d") (:authors ("Daniel Mendler" . "mail@daniel-mendler.de")) (:maintainer "Daniel Mendler" . "mail@daniel-mendler.de") (:url . "https://github.com/minad/org-modern"))])
+ (org-movies . [(20210920 101) ((emacs (26 1)) (org (9 0)) (request (0 3 0))) "Manage watchlist with Org mode" single ((:commit . "e96fecaffa2924de64a507aa31d2934e667ee1ea") (:authors ("Anh T Nguyen")) (:maintainer "Anh T Nguyen") (:keywords "hypermedia" "outlines" "org") (:url . "https://github.com/teeann/org-movies"))])
+ (org-mru-clock . [(20211029 1147) ((emacs (26 1))) "Clock in/out of tasks with completion and persistent history" single ((:commit . "a74322f0cfd6e52151f9bb8d4f90833330f69120") (:authors ("Kevin Brubeck Unhammer" . "unhammer@fsfe.org")) (:maintainer "Kevin Brubeck Unhammer" . "unhammer@fsfe.org") (:keywords "convenience" "calendar") (:url . "https://github.com/unhammer/org-mru-clock"))])
+ (org-msg . [(20220331 1707) ((emacs (24 4)) (htmlize (1 54))) "Org mode to send and reply to email in HTML." single ((:commit . "60e22e446325a9b3387396459d98be7c1c52579d") (:authors ("Jérémy Compostella" . "jeremy.compostella@gmail.com")) (:maintainer "Jérémy Compostella" . "jeremy.compostella@gmail.com") (:keywords "extensions" "mail") (:url . "https://github.com/jeremy-compostella/org-msg"))])
+ (org-multi-wiki . [(20210324 1820) ((emacs (26 1)) (dash (2 12)) (s (1 12)) (org-ql (0 5)) (org (9 3))) "Multiple wikis based on Org mode" single ((:commit . "bf8039aadddaf02569fab473f766071ef7e63563") (:authors ("Akira Komamura" . "akira.komamura@gmail.com")) (:maintainer "Akira Komamura" . "akira.komamura@gmail.com") (:keywords "org" "outlines" "files") (:url . "https://github.com/akirak/org-multi-wiki"))])
+ (org-multiple-keymap . [(20191017 1920) ((org (8 2 4)) (emacs (24)) (cl-lib (0 5))) "Set keymap to elements, such as timestamp and priority." single ((:commit . "4eb8aa0aada012b2346cc7f0c55e07783141a2c3") (:authors ("myuhe <yuhei.maeda_at_gmail.com>")) (:maintainer "myuhe") (:keywords "convenience" "org-mode") (:url . "https://github.com/myuhe/org-multiple-keymap.el"))])
+ (org-notebook . [(20170322 452) ((emacs (24)) (org (8)) (cl-lib (0 5))) "Ease the use of org-mode as a notebook" single ((:commit . "86042d866bf441e2c9bb51f995e5994141b78517") (:authors ("Paul Elder" . "paul.elder@amanokami.net")) (:maintainer "Paul Elder" . "paul.elder@amanokami.net") (:keywords "convenience" "tools"))])
+ (org-noter . [(20191020 1212) ((emacs (24 4)) (cl-lib (0 6)) (org (9 0))) "A synchronized, Org-mode, document annotator" single ((:commit . "9ead81d42dd4dd5074782d239b2efddf9b8b7b3d") (:authors (nil . "Gonçalo Santos (aka. weirdNox@GitHub)")) (:maintainer nil . "Gonçalo Santos (aka. weirdNox@GitHub)") (:keywords "lisp" "pdf" "interleave" "annotate" "external" "sync" "notes" "documents" "org-mode") (:url . "https://github.com/weirdNox/org-noter"))])
+ (org-noter-pdftools . [(20220320 300) ((emacs (26 1)) (org (9 4)) (pdf-tools (0 8)) (org-pdftools (1 0)) (org-noter (1 4 1))) "Integration between org-pdftools and org-noter" single ((:commit . "967f48fb5038bba32915ee9da8dc4e8b10ba3376") (:authors ("Alexander Fu Xi" . "fuxialexander@gmail.com")) (:maintainer "Alexander Fu Xi" . "fuxialexnader@gmail.com") (:keywords "convenience") (:url . "https://github.com/fuxialexander/org-pdftools"))])
+ (org-notifications . [(20210918 1827) ((emacs (25 1)) (org (9 0)) (sound-wav (0 2)) (alert (1 2)) (seq (2 21))) "Creates notifications for org-mode entries" tar ((:commit . "b8032f8adfbeb328962a5657c6dd173e64cc76e5") (:authors ("doppelc")) (:maintainer "doppelc") (:keywords "outlines") (:url . "https://github.com/doppelc/org-notifications"))])
+ (org-octopress . [(20170821 415) ((org (9 0)) (orglue (0 1)) (ctable (0 1 1))) "Compose octopress articles using org-mode." tar ((:commit . "38598ef98d04076a8eb78d549907ddfde8d3a652") (:authors ("Yoshinari Nomura" . "nom@quickhack.net")) (:maintainer "Yoshinari Nomura" . "nom@quickhack.net") (:keywords "org" "jekyll" "octopress" "blog"))])
+ (org-onenote . [(20171008 500) ((oauth2 (0 11)) (request (0 2 0)) (org (8 2 10))) "export org-mode document to onenote." single ((:commit . "5ce5cf4edb143180e0b185ac26826d39ae5bc929") (:authors ("Frei Zhang" . "ifree0@gmail.com")) (:maintainer "Frei Zhang" . "ifree0@gmail.com") (:keywords "tools" "docs" "org-mode" "onenote") (:url . "https://github.com/ifree/org-onenote"))])
+ (org-outline-numbering . [(20180705 1501) ((emacs (24)) (org (8 3)) (cl-lib (0 6)) (ov (1 0 6))) "Show outline numbering as overlays in org-mode" single ((:commit . "22014917dd7e751c46fa13e1e836c2d0265ce82f") (:authors ("Anders Johansson")) (:maintainer "Anders Johansson") (:keywords "wp" "convenience") (:url . "https://gitlab.com/andersjohansson/org-outline-numbering"))])
+ (org-outlook . [(20160705 1338) nil "Outlook org" tar ((:commit . "ec32d8d9d8ffd17e6de4de0b52fc3f5ad9b4cc0d") (:authors ("Matthew L. Fidler")) (:maintainer "Matthew L. Fidler") (:keywords "org-outlook") (:url . "https://github.com/mlf176f2/org-outlook.el"))])
+ (org-page . [(20170807 224) ((ht (1 5)) (simple-httpd (1 4 6)) (mustache (0 22)) (htmlize (1 47)) (org (8 0)) (dash (2 0 0)) (cl-lib (0 5)) (git (0 1 1))) "a static site generator based on org mode" tar ((:commit . "b25c3ef41da233306c157634c1f0b019d8b6adc0") (:authors ("Kelvin Hu <ini DOT kelvin AT gmail DOT com>")) (:maintainer "Kelvin Hu <ini DOT kelvin AT gmail DOT com>") (:keywords "org-mode" "convenience" "beautify") (:url . "https://github.com/kelvinh/org-page"))])
+ (org-parser . [(20200417 301) ((emacs (25 1)) (dash (2 12 0)) (ht (2 1))) "parse org files into structured datatypes." single ((:commit . "fd4cb7035ff649378cc968b1ec2c386b5c565706") (:keywords "files" "outlines" "tools") (:url . "https://hg.sr.ht/~zck/org-parser"))])
+ (org-pdftools . [(20220320 301) ((emacs (26 1)) (org (9 3 6)) (pdf-tools (0 8)) (org-noter (1 4 1))) "Support for links to documents in pdfview mode" single ((:commit . "967f48fb5038bba32915ee9da8dc4e8b10ba3376") (:authors ("Alexander Fu Xi" . "fuxialexander@gmail.com")) (:maintainer "Alexander Fu Xi" . "fuxialexnader@gmail.com") (:keywords "convenience") (:url . "https://github.com/fuxialexander/org-pdftools"))])
+ (org-picklink . [(20210210 516) ((emacs (24 4))) "Pick a headline link from org-agenda" single ((:commit . "bfdc22b436482752be41c5d6f6f37dca76b1c7c3") (:authors ("Feng Shu" . "tumashu@163.com")) (:maintainer "Feng Shu" . "tumashu@163.com") (:keywords "convenience") (:url . "https://github.com/tumashu/org-picklink"))])
+ (org-pivotal . [(20210705 408) ((a (0 1 1)) (dash (2 18 0)) (emacs (26 1)) (request (0 3 0))) "Sync Pivotal Tracker to org buffer" tar ((:commit . "6403cefb8440567fc593a8d267536138cd6165e2") (:authors ("Huy Duong" . "qhuyduong@hotmail.com")) (:maintainer "Huy Duong" . "qhuyduong@hotmail.com") (:url . "https://github.com/org-pivotal/org-pivotal"))])
+ (org-pomodoro . [(20220318 1618) ((alert (0 5 10)) (cl-lib (0 5))) "Pomodoro implementation for org-mode." tar ((:commit . "3f5bcfb80d61556d35fc29e5ddb09750df962cc6") (:authors ("Arthur Leonard Andersen" . "leoc.git@gmail.com")) (:maintainer "Arthur Leonard Andersen" . "leoc.git@gmail.com") (:url . "https://github.com/lolownia/org-pomodoro"))])
+ (org-present . [(20220108 1802) ((org (7))) "Minimalist presentation minor-mode for Emacs org-mode." single ((:commit . "c0f1f36b2384b58b00a2000f2e30895a6230bb6b") (:authors ("Ric Lister")) (:maintainer "Ric Lister") (:url . "https://github.com/rlister/org-present"))])
+ (org-pretty-tags . [(20211228 1546) ((emacs (25))) "Surrogates for tags" single ((:commit . "e127a1e08df8273b909a99594ffaad84960ff212") (:authors ("Marco Wahl" . "marcowahlsoft@gmail.com")) (:maintainer "Marco Wahl" . "marcowahlsoft@gmail.com") (:keywords "reading" "outlines") (:url . "https://gitlab.com/marcowahl/org-pretty-tags"))])
+ (org-preview-html . [(20220228 414) ((emacs (25 1)) (org (8 0))) "Automatically preview org-exported HTML files within Emacs" single ((:commit . "cb85524d5090b8189e965cc49d65be04650c17c4") (:authors ("Jake B" . "jakebox0@protonmail.com")) (:maintainer "Jake B" . "jakebox0@protonmail.com") (:keywords "org" "convenience" "outlines") (:url . "https://github.com/jakebox/org-preview-html"))])
+ (org-projectile . [(20220114 730) ((projectile (0 11 0)) (dash (2 10 0)) (emacs (24)) (s (1 9 0)) (org-category-capture (0 0 0))) "Repository todo management for org-mode" single ((:commit . "642b39c698db00bc535c1c2335f425fb9f4855a9") (:authors ("Ivan Malison" . "IvanMalison@gmail.com")) (:maintainer "Ivan Malison" . "IvanMalison@gmail.com") (:keywords "org-mode" "projectile" "todo" "tools" "outlines") (:url . "https://github.com/IvanMalison/org-projectile"))])
+ (org-projectile-helm . [(20180601 1822) ((org-projectile (1 0 0)) (helm (2 3 1)) (emacs (25))) "helm functions for org-projectile" single ((:commit . "642b39c698db00bc535c1c2335f425fb9f4855a9") (:authors ("Ivan Malison" . "IvanMalison@gmail.com")) (:maintainer "Ivan Malison" . "IvanMalison@gmail.com") (:keywords "org" "projectile" "todo" "helm" "outlines") (:url . "https://github.com/IvanMalison/org-projectile"))])
+ (org-protocol-jekyll . [(20170328 1639) ((cl-lib (0 5))) "Jekyll's handler for org-protocol" single ((:commit . "dec064a42d6dfe81dfde7ba59ece5ca103ac6334") (:authors ("Vladimir S. Ivanov" . "ivvl82@gmail.com")) (:maintainer "Vladimir S. Ivanov" . "ivvl82@gmail.com"))])
+ (org-ql . [(20220318 1534) ((emacs (26 1)) (dash (2 18 1)) (f (0 17 2)) (map (2 1)) (org (9 0)) (org-super-agenda (1 2)) (ov (1 0 6)) (peg (1 0)) (s (1 12 0)) (transient (0 1)) (ts (0 2 -1))) "Org Query Language, search command, and agenda-like view" tar ((:commit . "46f523d94a376b168176c75bbd0e3e0d00e61170") (:authors ("Adam Porter" . "adam@alphapapa.net")) (:maintainer "Adam Porter" . "adam@alphapapa.net") (:keywords "hypermedia" "outlines" "org" "agenda") (:url . "https://github.com/alphapapa/org-ql"))])
+ (org-radiobutton . [(20210519 1225) ((dash (2 13 0)) (emacs (24))) "Radiobutton for org-mode lists." single ((:commit . "86d7581202a37d2004589b8c8e9d8638806c6bcc") (:authors ("Matúš Goljer" . "matus.goljer@gmail.com")) (:maintainer "Matúš Goljer" . "matus.goljer@gmail.com") (:keywords "outlines") (:url . "https://github.com/Fuco1/org-radiobutton"))])
+ (org-random-todo . [(20190214 2057) ((emacs (24 3)) (alert (1 3))) "show a random TODO (with alert) every so often" single ((:commit . "a019c7186ec60c8c7c3657914cdce029811cf4e0") (:authors ("Kevin Brubeck Unhammer" . "unhammer@fsfe.org")) (:maintainer "Kevin Brubeck Unhammer" . "unhammer@fsfe.org") (:keywords "org" "todo" "notification" "calendar") (:url . "https://github.com/unhammer/org-random-todo"))])
+ (org-randomnote . [(20200110 1407) ((f (0 19 0)) (dash (2 12 0)) (org (0))) "Find a random note in your Org-Mode files" single ((:commit . "ea8cf4385970637efffff8f79e14576ba6d7ad13") (:authors ("Michael Fogleman" . "michaelwfogleman@gmail.com")) (:maintainer "Michael Fogleman" . "michaelwfogleman@gmail.com") (:url . "http://github.com/mwfogleman/org-randomnote"))])
+ (org-re-reveal . [(20220402 1456) ((emacs (24 4)) (org (8 3)) (htmlize (1 34))) "Org export to reveal.js presentations" tar ((:commit . "c787ebf93d51b63b8726df241e3e2fcda35d4ae1") (:keywords "tools" "outlines" "hypermedia" "slideshow" "presentation" "oer") (:url . "https://gitlab.com/oer/org-re-reveal"))])
+ (org-re-reveal-citeproc . [(20211028 1328) ((emacs (25 1)) (org (9 5)) (citeproc (0 9)) (org-re-reveal (3 0 0))) "Citations and bibliography for org-re-reveal" tar ((:commit . "faa9ea387917b20bd1499ad90199ff3d417c00c2") (:authors ("Jens Lechtenbörger")) (:maintainer "Jens Lechtenbörger") (:keywords "hypermedia" "tools" "slideshow" "presentation" "bibliography") (:url . "https://gitlab.com/oer/org-re-reveal-citeproc"))])
+ (org-re-reveal-ref . [(20211029 551) ((emacs (25 1)) (org-ref (1 1 1)) (org-re-reveal (0 9 3))) "Citations and bibliography for org-re-reveal" tar ((:commit . "ea9661864d5fbef87b12b78f516c13a40c683f24") (:authors ("Jens Lechtenbörger")) (:maintainer "Jens Lechtenbörger") (:keywords "hypermedia" "tools" "slideshow" "presentation" "bibliography") (:url . "https://gitlab.com/oer/org-re-reveal-ref"))])
+ (org-recent-headings . [(20211011 1519) ((emacs (26 1)) (org (9 0 5)) (dash (2 18 0)) (frecency (0 1)) (s (1 12 0))) "Jump to recently used Org headings" single ((:commit . "97418d581ea030f0718794e50b005e9bae44582e") (:authors ("Adam Porter" . "adam@alphapapa.net")) (:maintainer "Adam Porter" . "adam@alphapapa.net") (:keywords "hypermedia" "outlines" "org") (:url . "http://github.com/alphapapa/org-recent-headings"))])
+ (org-recur . [(20211007 238) ((emacs (24)) (org (9 0))) "Recurring org-mode tasks" single ((:commit . "2bdf71d79f11afa3777c6542f84cef4ad3fce916") (:authors ("Marcin Swieczkowski" . "marcin.swieczkowski@gmail.com")) (:maintainer "Marcin Swieczkowski" . "marcin.swieczkowski@gmail.com") (:url . "https://github.com/m-cat/org-recur"))])
+ (org-redmine . [(20160711 1114) nil "Redmine tools using Emacs OrgMode" single ((:commit . "e77d013bc3784947c46a5c53f03cd7d3c68552fc") (:authors ("Wataru MIYAGUNI" . "gonngo@gmail.com")) (:maintainer "Wataru MIYAGUNI" . "gonngo@gmail.com") (:keywords "redmine" "org") (:url . "https://github.com/gongo/org-redmine"))])
+ (org-ref . [(20220429 1110) ((org (9 4)) (dash (0)) (s (0)) (f (0)) (htmlize (0)) (hydra (0)) (avy (0)) (parsebib (0)) (bibtex-completion (0)) (citeproc (0))) "citations, cross-references and bibliographies in org-mode" tar ((:commit . "f2ebc18c36c106e94810d5a1b15b108811a87283") (:authors ("John Kitchin" . "jkitchin@andrew.cmu.edu")) (:maintainer "John Kitchin" . "jkitchin@andrew.cmu.edu") (:keywords "org-mode" "cite" "ref" "label") (:url . "https://github.com/jkitchin/org-ref"))])
+ (org-ref-prettify . [(20220112 1746) ((emacs (24 3)) (org-ref (3 0)) (bibtex-completion (1 0 0))) "Prettify org-ref citation links" single ((:commit . "cbf9a709a10304981c38eba1149def17151aca3c") (:authors ("Alex Kost" . "alezost@gmail.com") ("Vitus Schäfftlein" . "vitusschaefftlein@live.de")) (:maintainer "Alex Kost" . "alezost@gmail.com") (:keywords "convenience") (:url . "https://github.com/alezost/org-ref-prettify.el"))])
+ (org-repo-todo . [(20171228 119) nil "Simple repository todo management with org-mode" single ((:commit . "f73ebd91399c5760ad52c6ad9033de1066042003") (:authors ("justin talbott" . "justin@waymondo.com")) (:maintainer "justin talbott" . "justin@waymondo.com") (:keywords "convenience") (:url . "https://github.com/waymondo/org-repo-todo"))])
+ (org-reverse-datetree . [(20220310 1646) ((emacs (26 1)) (dash (2 12)) (org (9 3))) "Create reverse date trees in org-mode" single ((:commit . "9ebd42b521e7adf26a35cbb17144113a83f73264") (:authors ("Akira Komamura" . "akira.komamura@gmail.com")) (:maintainer "Akira Komamura" . "akira.komamura@gmail.com") (:keywords "outlines") (:url . "https://github.com/akirak/org-reverse-datetree"))])
+ (org-review . [(20220411 1205) nil "schedule reviews for Org entries" single ((:commit . "466f7d8f183f226f1e665cf806cb094471903d9c") (:authors ("Alan Schmitt" . "alan.schmitt@polytechnique.org")) (:maintainer "Alan Schmitt" . "alan.schmitt@polytechnique.org") (:keywords "org" "review") (:url . "https://github.com/brabalan/org-review"))])
+ (org-rich-yank . [(20220227 2154) ((emacs (24 4))) "Paste with org-mode markup and link to source" single ((:commit . "4bcd030f0d736d77c647955739b61fae541417e9") (:authors ("Kevin Brubeck Unhammer" . "unhammer@fsfe.org")) (:maintainer "Kevin Brubeck Unhammer" . "unhammer@fsfe.org") (:keywords "convenience" "hypermedia" "org") (:url . "https://github.com/unhammer/org-rich-yank"))])
+ (org-roam . [(20220504 106) ((emacs (26 1)) (dash (2 13)) (org (9 4)) (emacsql (3 0 0)) (emacsql-sqlite (1 0 0)) (magit-section (3 0 0))) "A database abstraction layer for Org-mode" tar ((:commit . "007e76725cdee4b16c003aec096e2dd7ab399b56") (:authors ("Jethro Kuan" . "jethrokuan95@gmail.com")) (:maintainer "Jethro Kuan" . "jethrokuan95@gmail.com") (:keywords "org-mode" "roam" "convenience") (:url . "https://github.com/org-roam/org-roam"))])
+ (org-roam-bibtex . [(20220213 1609) ((emacs (27 1)) (org-roam (2 2 0)) (bibtex-completion (2 0 0))) "Org Roam meets BibTeX" tar ((:commit . "efdac6fe4134c33f50b06a0a6d192003d0e5094c") (:authors ("Mykhailo Shevchuk" . "mail@mshevchuk.com") ("Leo Vivier" . "leo.vivier+dev@gmail.com")) (:maintainer "Mykhailo Shevchuk" . "mail@mshevchuk.com") (:keywords "bib" "hypermedia" "outlines" "wp") (:url . "https://github.com/org-roam/org-roam-bibtex"))])
+ (org-roam-timestamps . [(20220111 1755) ((emacs (26 1)) (org-roam (2 0 0))) "Keep track of modification times for org-roam" single ((:commit . "604fdad0feb61419751d3d6b828cc443a99f418f") (:authors ("Thomas F. K. Jorna <https://github.com/thomas>")) (:maintainer "Thomas F. K. Jorna" . "jorna@jtrialerror.com") (:keywords "calendar" "outlines" "files") (:url . "https://github.com/ThomasFKJorna/org-roam-timestamps/"))])
+ (org-roam-ui . [(20220225 2151) ((emacs (27 1)) (org-roam (2 0 0)) (simple-httpd (20191103 1446)) (websocket (1 13))) "User Interface for Org-roam" tar ((:commit . "9474a254390b1e42488a1801fed5826b32a8030b") (:authors ("Kirill Rogovoy, Thomas Jorna")) (:maintainer "Kirill Rogovoy, Thomas Jorna") (:keywords "files" "outlines") (:url . "https://github.com/org-roam/org-roam-ui"))])
+ (org-ros . [(20220320 1705) ((emacs (24 1))) "Rahul's Org-Mode Screenshot" single ((:commit . "70e0f33ee027ca1dce68351ad14a9e47a452fc17") (:authors ("Rahul Martim Juliato" . "rahul.juliato@gmail.com")) (:maintainer "Rahul Martim Juliato" . "rahul.juliato@gmail.com") (:url . "https://github.com/LionyxML/ros"))])
+ (org-rtm . [(20160214 1236) ((rtm (0 1))) "Simple import/export from rememberthemilk to org-mode" single ((:commit . "adc42ad1fbe92ab447ccc9553780f4456f2508d2") (:authors ("Philipp Middendorf" . "pmidden@secure.mailbox.org")) (:maintainer "Philipp Middendorf" . "pmidden@secure.mailbox.org") (:keywords "outlines" "data") (:url . "https://github.com/pmiddend/org-rtm"))])
+ (org-runbook . [(20220107 451) nil "Org mode for runbooks" tar ((:commit . "dd11d253d3ee94b70f0d2cc74c6e85c6f5ac189d") (:authors ("Tyler Dodge")) (:maintainer "Tyler Dodge") (:keywords "convenience" "processes" "terminals" "files") (:url . "https://github.com/tyler-dodge/org-runbook"))])
+ (org-scrum . [(20200131 1129) ((emacs (24 5)) (org (8 2)) (seq (2 3)) (cl-lib (1 0))) "org mode extensions for scrum planning and reporting" single ((:commit . "f7a46bc4bc85305f0c2b72565170ea0e007c42fd") (:authors ("Ian Martins" . "ianxm@jhu.edu")) (:maintainer "Ian Martins" . "ianxm@jhu.edu") (:url . "https://github.com/ianxm/emacs-scrum"))])
+ (org-seek . [(20161217 502) ((emacs (24 3)) (ag (0 48))) "Searching Org-mode files with search tools." single ((:commit . "1f51e6634e3b9a6a29d335d0d14370a6ffef2265") (:authors ("stardiviner" . "numbchild@gmail.com")) (:maintainer "stardiviner" . "numbchild@gmail.com") (:keywords "org" "search" "ag" "pt") (:url . "https://github.com/stardiviner/org-seek.el"))])
+ (org-shoplist . [(20210629 2157) ((emacs (25))) "Eat the world" single ((:commit . "71ea7643e66c97d21df49fb8b600578ca0464f83") (:authors ("lordnik22")) (:maintainer "lordnik22") (:keywords "extensions" "matching") (:url . "https://github.com/lordnik22"))])
+ (org-sidebar . [(20210912 1321) ((emacs (26 1)) (s (1 10 0)) (dash (2 18)) (org (9 0)) (org-ql (0 2)) (org-super-agenda (1 0))) "Helpful sidebar for Org buffers" single ((:commit . "288703b897449f5110c9c76e78eb9a928ffc0dcd") (:authors ("Adam Porter" . "adam@alphapapa.net")) (:maintainer "Adam Porter" . "adam@alphapapa.net") (:keywords "hypermedia" "outlines" "org" "agenda") (:url . "https://github.com/alphapapa/org-sidebar"))])
+ (org-snooze . [(20181229 1424) ((emacs (24 4))) "Snooze your code, doc and feed" single ((:commit . "8799adc14a20f3489063d279ff69312de3180bf9") (:authors ("Bill Xue")) (:maintainer "Bill Xue") (:keywords "extensions") (:url . "https://github.com/xueeinstein/org-snooze.el"))])
+ (org-special-block-extras . [(20220326 1432) ((s (1 12 0)) (dash (2 18 1)) (emacs (27 1)) (org (9 1)) (lf (1 0)) (dad-joke (1 4)) (seq (2 0)) (lolcat (0))) "30 new custom blocks & 34 link types for Org-mode" single ((:commit . "2e397dac372ff75ea6ee6eed9ae3a0540a082af8") (:authors ("Musa Al-hassy" . "alhassy@gmail.com")) (:maintainer "Musa Al-hassy" . "alhassy@gmail.com") (:keywords "org" "blocks" "colors" "convenience") (:url . "https://alhassy.github.io/org-special-block-extras"))])
+ (org-sql . [(20210404 1839) ((emacs (27 1)) (s (1 12)) (f (0 20 0)) (dash (2 17)) (org-ml (5 6 1))) "Org-Mode SQL converter" single ((:commit . "71b6e01ff94be4c68cfeb17a34518bf1f118cf95") (:authors ("Nathan Dwarshuis" . "natedwarshuis@gmail.com")) (:maintainer "Nathan Dwarshuis" . "natedwarshuis@gmail.com") (:keywords "org-mode" "data") (:url . "https://github.com/ndwarshuis/org-sql"))])
+ (org-starter . [(20220326 1106) ((emacs (25 1)) (dash (2 18))) "A basic configuration framework for org mode" single ((:commit . "cd9c5c0402de941299d1c8901f26a8f24d755022") (:authors ("Akira Komamura" . "akira.komamura@gmail.com")) (:maintainer "Akira Komamura" . "akira.komamura@gmail.com") (:url . "https://github.com/akirak/org-starter"))])
+ (org-starter-swiper . [(20201202 144) ((emacs (25 1)) (swiper (0 11)) (org-starter (0 2 4))) "Swiper for org-starter" single ((:commit . "cd9c5c0402de941299d1c8901f26a8f24d755022") (:authors ("Akira Komamura" . "akira.komamura@gmail.com")) (:maintainer "Akira Komamura" . "akira.komamura@gmail.com") (:url . "https://github.com/akirak/org-starter"))])
+ (org-static-blog . [(20220505 620) ((emacs (24 3))) "a simple org-mode based static blog generator" single ((:commit . "61a3ab0e2e8e1ac0ef8772e89ae320c07142f7f5") (:authors ("Bastian Bechtold")) (:maintainer "Bastian Bechtold") (:url . "https://github.com/bastibe/org-static-blog"))])
+ (org-sticky-header . [(20201223 143) ((emacs (24 4)) (org (8 3 5))) "Show off-screen Org heading at top of window" single ((:commit . "79136b8c54c48547ba8a07a72a9790cb8e23ecbd") (:authors ("Adam Porter" . "adam@alphapapa.net")) (:maintainer "Adam Porter" . "adam@alphapapa.net") (:keywords "hypermedia" "outlines" "org") (:url . "http://github.com/alphapapa/org-sticky-header"))])
+ (org-super-agenda . [(20210928 916) ((emacs (26 1)) (s (1 10 0)) (dash (2 13)) (org (9 0)) (ht (2 2)) (ts (0 2))) "Supercharge your agenda" tar ((:commit . "3108bc3f725818f0e868520d2c243abe9acbef4e") (:authors ("Adam Porter" . "adam@alphapapa.net")) (:maintainer "Adam Porter" . "adam@alphapapa.net") (:keywords "hypermedia" "outlines" "org" "agenda") (:url . "http://github.com/alphapapa/org-super-agenda"))])
+ (org-superstar . [(20210915 1934) ((org (9 1 9)) (emacs (26 1))) "Prettify headings and plain lists in Org mode" single ((:commit . "03be6c0a3081c46a59b108deb8479ee24a6d86c0") (:authors ("D. Williams" . "d.williams@posteo.net")) (:maintainer "D. Williams" . "d.williams@posteo.net") (:keywords "faces" "outlines") (:url . "https://github.com/integral-dw/org-superstar-mode"))])
+ (org-sync . [(20181204 23) ((cl-lib (0 5)) (org (8 2)) (emacs (24))) "Synchronize Org documents with External Issue Trackers" tar ((:commit . "e34a385fa9e658c8341a0a6e6bc3472d4d536bb8") (:authors ("Aurelien Aptel <aurelien dot aptel at gmail dot com>")) (:maintainer "Andrei Beliankou" . "arbox@yandex.ru") (:keywords "org" "synchronization" "issue tracking" "github" "redmine") (:url . "https://github.com/arbox/org-sync"))])
+ (org-sync-snippets . [(20210111 1726) ((org (8 3 5)) (emacs (24 3)) (f (0 17 3))) "Export snippets to org-mode and vice versa" single ((:commit . "88f995dea188b8a645a3388c42b62a2bb88953d3") (:authors ("Adrien Brochard")) (:maintainer "Adrien Brochard") (:keywords "snippet" "org-mode" "yasnippet" "tools") (:url . "https://github.com/abrochard/org-sync-snippets"))])
+ (org-table-color . [(20220311 1927) ((emacs (26 1))) "Add color to your org-mode table cells" single ((:commit . "2022f301ef323953c3a0e087a1b601da85e06da1") (:authors ("Colin Woodbury" . "colin@fosskers.ca")) (:maintainer "Colin Woodbury" . "colin@fosskers.ca") (:keywords "data" "faces" "lisp") (:url . "https://github.com/fosskers/org-table-color"))])
+ (org-table-comment . [(20120209 1851) nil "Org table comment modes." single ((:commit . "33b9966c33ecbc3e27cca67c2f2cdea04364d74e") (:authors ("Matthew L. Fidler <matthew dot fidler at gmail . com>")) (:maintainer "Matthew L. Fidler") (:keywords "org-mode" "orgtbl") (:url . "http://github.com/mlf176f2/org-table-comment.el"))])
+ (org-table-sticky-header . [(20190924 506) ((org (8 2 10)) (emacs (24 4))) "Sticky header for org-mode tables" single ((:commit . "b65442857128ab04724aaa301e60aa874a31a798") (:authors ("Junpeng Qiu" . "qjpchmail@gmail.com")) (:maintainer "Junpeng Qiu" . "qjpchmail@gmail.com") (:keywords "extensions"))])
+ (org-tag-beautify . [(20220427 1552) ((emacs (26 1)) (org-pretty-tags (0 2 2)) (all-the-icons (4 0 0))) "Beautify Org Mode tags" single ((:commit . "88fde267441118836a5c4ed28bb5958fca37a800") (:keywords "hypermedia") (:url . "https://repo.or.cz/org-tag-beautify.git"))])
+ (org-tanglesync . [(20200127 1616) ((emacs (24 4))) "Syncing org src blocks with tangled external files" single ((:commit . "af83a73ae542d5cb3c9d433cbf2ce1d4f4259117") (:authors ("Mehmet Tekman")) (:maintainer "Mehmet Tekman") (:keywords "outlines") (:url . "https://github.com/mtekman/org-tanglesync.el"))])
+ (org-tfl . [(20170923 1218) ((org (0 16 2)) (cl-lib (0 5)) (emacs (24 1))) "Transport for London meets Orgmode" tar ((:commit . "f0d7d39106a1de5457f5160cddd98ab892b61066") (:authors ("storax (David Zuber), <zuber [dot] david [at] gmx [dot] de>")) (:maintainer "storax (David Zuber), <zuber [dot] david [at] gmx [dot] de>") (:keywords "org" "tfl") (:url . "https://github.com/storax/org-tfl"))])
+ (org-themis . [(20160122 404) ((cl-lib (0 4))) "Experimental project management mode for org-mode" single ((:commit . "78aadbbe22b1993be5c4accd0d3f91a4e85c9a3c") (:maintainer "Zachary Elliott" . "contact@zell.io") (:keywords "org-mode" "elisp" "project") (:url . "http://github.com/zellio/org-themis"))])
+ (org-time-budgets . [(20200715 1016) ((alert (0 5 10)) (cl-lib (0 5))) "Define time budgets and display clocked time." single ((:commit . "1d6bfc323013bbf725167842d9e097fad805de03") (:authors ("Arthur Leonard Andersen" . "leoc.git@gmail.com")) (:maintainer "Arthur Leonard Andersen" . "leoc.git@gmail.com"))])
+ (org-timeline . [(20211110 1952) ((dash (2 13 0)) (emacs (24 3))) "Add graphical view of agenda to agenda buffer." single ((:commit . "2b300abc8adc9955418fa2334f55e0610bff79f5") (:authors ("Matúš Goljer" . "matus.goljer@gmail.com")) (:maintainer "Matúš Goljer" . "matus.goljer@gmail.com") (:keywords "calendar") (:url . "https://github.com/Fuco1/org-timeline/"))])
+ (org-toodledo . [(20150301 1113) ((request-deferred (0 2 0)) (emacs (24)) (cl-lib (0 5))) "Toodledo integration for Emacs Org mode" tar ((:commit . "2c91a92bd07ae4a546771b018a6faa0e06399968") (:authors ("Christopher J. White" . "emacs@grierwhite.com")) (:maintainer "Christopher J. White" . "emacs@grierwhite.com") (:keywords "outlines" "data"))])
+ (org-tracktable . [(20161118 1329) ((emacs (24)) (cl-lib (0 5))) "Track your writing progress in an org-table" single ((:commit . "8e0e60a582a034bd66d5efb72d513140b7d4d90a") (:authors ("tty-tourist" . "andreasrasholm@protonmail.com")) (:maintainer "tty-tourist" . "andreasrasholm@protonmail.com") (:keywords "org" "writing") (:url . "https://github.com/tty-tourist/org-tracktable"))])
+ (org-transform-tree-table . [(20200413 1959) ((dash (2 10 0)) (s (1 3 0))) "Transform org-mode tree with properties to a table, and the other way around" single ((:commit . "d84e7fb87bf2d5fc2be252500de0cddf20facf4f") (:authors (nil . "Johan Lindstrom <buzzwordninja not_this_bit@googlemail.com>")) (:maintainer nil . "Johan Lindstrom <buzzwordninja not_this_bit@googlemail.com>") (:keywords "org-mode" "table" "org-table" "tree" "csv" "convert") (:url . "https://github.com/jplindstrom/emacs-org-transform-tree-table"))])
+ (org-tree-slide . [(20220112 142) ((emacs (24 4))) "A presentation tool for org-mode" single ((:commit . "3faa042393ebfe5699a3bffce775f039d7416ceb") (:authors ("Takaaki ISHIKAWA <takaxp at ieee dot org>")) (:maintainer "Takaaki ISHIKAWA <takaxp at ieee dot org>") (:keywords "convenience" "org-mode" "presentation" "narrowing") (:url . "https://github.com/takaxp/org-tree-slide"))])
+ (org-tree-slide-pauses . [(20201215 146) ((emacs (24 5)) (org-tree-slide (2 8 4))) "Bring the pause command from Beamer to org-tree-slide" single ((:commit . "f02af7102e9ecef7c3dac0d376d85bbb8c4de4cc") (:authors ("cnngimenez")) (:maintainer "cnngimenez") (:keywords "convenience" "org-mode" "presentation") (:url . "https://github.com/cnngimenez/org-tree-slide-pauses"))])
+ (org-treescope . [(20200503 1609) ((emacs (24 3)) (org (9 2 3)) (org-ql (0 5 -1)) (dash (2 17 0))) "Time scoping sparse trees within org" tar ((:commit . "905029a9e2ce6ed325bb8e10f59dc589c181d148") (:authors ("Mehmet Tekman")) (:maintainer "Mehmet Tekman") (:keywords "outlines") (:url . "https://github.com/mtekman/org-treescope.el"))])
+ (org-treeusage . [(20200418 1904) ((emacs (26 1)) (dash (2 17 0)) (org (9 1 6))) "Examine the usage of org headings in a tree-like manner" tar ((:commit . "fe4323bc500e2d949848c75e8f59340971b35562") (:authors ("Mehmet Tekman")) (:maintainer "Mehmet Tekman") (:keywords "outlines") (:url . "https://github.com/mtekman/org-treeusage.el"))])
+ (org-trello . [(20210314 1901) ((emacs (24 3)) (request-deferred (0 2 0)) (deferred (0 4 0)) (s (1 11 0)) (dash (2 18 0))) "Minor mode to synchronize org-mode buffer and trello board" tar ((:commit . "fc63ed580101e6160edfb6f43215fb3200ce1ea7") (:authors ("Antoine R. Dumont (@ardumont)" . "antoine.romain.dumont@gmail.com")) (:maintainer "Antoine R. Dumont (@ardumont)" . "antoine.romain.dumont@gmail.com") (:keywords "org-mode" "trello" "sync" "org-trello") (:url . "https://github.com/org-trello/org-trello"))])
+ (org-variable-pitch . [(20220220 1757) ((emacs (25))) "Minor mode for variable pitch text in org mode." single ((:commit . "350af0e5d53307c900e4f8b2617f3852f51a74d2") (:authors ("Göktuğ Kayaalp" . "self@gkayaalp.com")) (:maintainer "Göktuğ Kayaalp" . "self@gkayaalp.com") (:keywords "faces") (:url . "https://dev.gkayaalp.com/elisp/index.html#ovp"))])
+ (org-vcard . [(20220206 1209) nil "org-mode support for vCard export and import." tar ((:commit . "bdaebcb4ef44c155a92d9c89a21a1d29019ee026") (:authors ("Alexis" . "flexibeast@gmail.com") ("Will Dey" . "will123dey@gmail.com")) (:maintainer "Alexis" . "flexibeast@gmail.com") (:keywords "outlines" "org" "vcard") (:url . "https://github.com/flexibeast/org-vcard"))])
+ (org-view-mode . [(20220218 2106) ((emacs (25 1))) "Read-only viewer with less markup clutter in org mode files" single ((:commit . "88321917b095a8cbabfa8327c915bd46eb741750") (:authors ("Arthur Miller" . "arthur.miller@live.com")) (:maintainer "Arthur Miller" . "arthur.miller@live.com") (:keywords "convenience" "outlines" "tools") (:url . "https://github.com/amno1/org-view-mode"))])
+ (org-visibility . [(20220404 1502) ((emacs (27 1))) "Persistent org tree visibility" single ((:commit . "a3aef6573d23309f9a6f340b41fa103cca3c79a6") (:authors ("Kyle W T Sherman" . "kylewsherman@gmail.com")) (:maintainer "Kyle W T Sherman" . "kylewsherman@gmail.com") (:keywords "outlines" "convenience") (:url . "https://github.com/nullman/emacs-org-visibility"))])
+ (org-wc . [(20200731 2244) nil "Count words in org mode trees." single ((:commit . "dbbf794e4ec6c4080d945f43338185e34a4a582d") (:authors ("Simon Guest")) (:maintainer "Simon Guest"))])
+ (org-web-tools . [(20201212 1058) ((emacs (25 1)) (org (9 0)) (dash (2 12)) (esxml (0 3 4)) (s (1 10 0)) (request (0 3 0))) "Display and capture web content with Org-mode" tar ((:commit . "b94a07add8558ef7b0666173dbb8a2554f1d41a6") (:authors ("Adam Porter" . "adam@alphapapa.net")) (:maintainer "Adam Porter" . "adam@alphapapa.net") (:keywords "hypermedia" "outlines" "org" "web") (:url . "http://github.com/alphapapa/org-web-tools"))])
+ (org-wild-notifier . [(20220402 2331) ((alert (1 2)) (async (1 9 3)) (dash (2 18 0)) (emacs (24 4))) "Customizable org-agenda notifications" single ((:commit . "4b1d874aafdee90815136c308f1f3bd3577971ec") (:authors ("Artem Khramov" . "akhramov+emacs@pm.me")) (:maintainer "Artem Khramov" . "akhramov+emacs@pm.me") (:keywords "notification" "alert" "org" "org-agenda" "agenda") (:url . "https://github.com/akhramov/org-wild-notifier.el"))])
+ (org-working-set . [(20220414 1402) ((org (9 3)) (dash (2 12)) (s (1 12)) (emacs (26 3))) "Manage and visit a small set of org-nodes." single ((:commit . "6af54ed3a5d9bf90629223157803c42f5d3b152c") (:authors ("Marc Ihm" . "1@2484.de")) (:maintainer "Marc Ihm" . "1@2484.de") (:url . "https://github.com/marcIhm/org-working-set"))])
+ (org-wunderlist . [(20191017 1917) ((request-deferred (0 2 0)) (alert (1 1)) (emacs (24)) (cl-lib (0 5)) (org (8 2 4)) (s (1 9 0))) "Org sync with Wunderlist" single ((:commit . "1a084bb49be4b5a1066db9cd9b7da2f8efab293f") (:authors ("myuhe <yuhei.maeda_at_gmail.com>")) (:maintainer "myuhe") (:keywords "convenience") (:url . "https://github.com/myuhe/org-wunderlist.el"))])
+ (org-zettelkasten . [(20220503 1357) ((emacs (24 3)) (org (9 0))) "Helper functions to use Zettelkasten in org-mode" single ((:commit . "603a5b692a08340c1865a6f73cacf57c4fd64cb2") (:authors ("Yann Herklotz" . "yann@ymhg.org")) (:maintainer "Yann Herklotz" . "yann@ymhg.org") (:keywords "files" "hypermedia" "org" "notes") (:url . "https://github.com/ymherklotz/emacs-zettelkasten"))])
+ (org2blog . [(20210929 17) ((htmlize (1 54)) (hydra (0 15 0)) (xml-rpc (1 6 12)) (metaweblog (1 1 1))) "Blog from Org mode to WordPress" tar ((:commit . "68695ed0e012379556d57f9564ac5ad8cd68fbb8") (:authors ("Puneeth Chaganti" . "punchagan+org2blog@gmail.com")) (:maintainer "Grant Rettke" . "grant@wisdomandwonder.com") (:keywords "comm" "convenience" "outlines" "wp") (:url . "https://github.com/org2blog/org2blog"))])
+ (org2ctex . [(20200331 550) ((emacs (24 4))) "Export org to ctex (a latex macro for Chinese)" single ((:commit . "2e40aa5e78b0562516f46f689e7b74cdf451cc2a") (:authors ("Feng Shu" . "tumashu@163.com")) (:maintainer "Feng Shu" . "tumashu@163.com") (:url . "https://github.com/tumashu/org2ctex"))])
+ (org2elcomment . [(20170324 945) ((org (8 3 4))) "Convert Org file to Elisp comments" single ((:commit . "c88a75d9587c484ead18f7adf08592b09c1cceb0") (:authors ("Junpeng Qiu" . "qjpchmail@gmail.com")) (:maintainer "Junpeng Qiu" . "qjpchmail@gmail.com") (:keywords "extensions"))])
+ (org2issue . [(20190531 941) ((org (8 0)) (emacs (24 4)) (ox-gfm (0 1)) (gh (0 1)) (s (20160405 920))) "export org to github issue" single ((:commit . "910b98c858762fd14b11d261626c5e979dde0833") (:authors ("DarkSun" . "lujun9972@gmail.com")) (:maintainer "DarkSun" . "lujun9972@gmail.com") (:keywords "convenience" "github" "org") (:url . "https://github.com/lujun9972/org2issue"))])
+ (org2jekyll . [(20210829 1113) ((dash (2 18 0)) (s (1 9 0))) "Minor mode to publish org-mode post to jekyll without specific yaml" tar ((:commit . "32f6cfc7265cf24ebb5361264e8c1b61a07e74df") (:authors ("Antoine R. Dumont (@ardumont)" . "antoine.romain.dumont@gmail.com")) (:maintainer "Antoine R. Dumont (@ardumont)" . "antoine.romain.dumont@gmail.com") (:keywords "org-mode" "jekyll" "blog" "publish") (:url . "https://github.com/ardumont/org2jekyll"))])
+ (org2web . [(20210203 324) ((cl-lib (1 0)) (ht (1 5)) (mustache (0 22)) (htmlize (1 47)) (org (8 0)) (dash (2 0 0)) (el2org (0 10)) (simple-httpd (0 1))) "A static site generator based on org mode." tar ((:commit . "6f5c5f0cc5c877ac3a383782bbe8751264d807b6") (:authors ("Feng Shu <tumashu AT 163.com>") ("Jorge Javier Araya Navarro <elcorreo AT deshackra.com>") ("Kelvin Hu <ini DOT kelvin AT gmail DOT com>")) (:maintainer "Feng Shu <tumashu AT 163.com>") (:keywords "org-mode" "convenience" "beautify") (:url . "https://github.com/tumashu/org2web"))])
+ (organic-green-theme . [(20201216 2240) nil "Low-contrast green color theme." single ((:commit . "0ed99a9c0cf14be0a1f491518821f0e9b7e88b88"))])
+ (organize-imports-java . [(20210715 1155) ((emacs (25 1)) (f (0 20 0)) (s (1 12 0)) (dash (2 14 1)) (ht (2 2))) "Automatically organize imports in Java code" tar ((:commit . "6fe53900ead434f3e18e63e9d22a8fa8380ccb37") (:authors ("Shen, Jen-Chieh" . "jcs090218@gmail.com")) (:maintainer "Shen, Jen-Chieh" . "jcs090218@gmail.com") (:url . "https://github.com/jcs-elpa/organize-imports-java"))])
+ (orgbox . [(20180827 218) ((org (8 0)) (cl-lib (0 5))) "Mailbox-like task scheduling Org." single ((:commit . "3982f56efd67ec016389cad82ce5a44f619b36a9") (:authors ("Yasuhito Takamiya" . "yasuhito@gmail.com")) (:maintainer "Yasuhito Takamiya" . "yasuhito@gmail.com") (:keywords "org") (:url . "https://github.com/yasuhito/orgbox"))])
+ (orgit . [(20220425 1157) ((emacs (25 1)) (compat (28 1 1 0)) (magit (3 0)) (org (9 4))) "Support for Org links to Magit buffers" single ((:commit . "6dc4d4bfffd6c11550952203a51346b13e120165") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:keywords "hypermedia" "vc") (:url . "https://github.com/magit/orgit"))])
+ (orgit-forge . [(20220422 1625) ((emacs (25 1)) (compat (28 1 1 0)) (forge (0 3)) (magit (3 3)) (org (9 5)) (orgit (1 8))) "Org links to Forge issue buffers" single ((:commit . "72285807707a802ebe7f3c6149de9a78a022b17e") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:keywords "hypermedia" "vc") (:url . "https://github.com/magit/orgit-forge"))])
+ (orglink . [(20220422 1626) ((emacs (25 1)) (compat (28 1 1 0)) (org (9 5)) (seq (2 23))) "Use Org Mode links in other modes" single ((:commit . "36129691e60e992f31065be4c26d58645b83b033") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:keywords "hypermedia") (:url . "https://github.com/tarsius/orglink"))])
+ (orglue . [(20200411 311) ((org (9 3)) (epic (0 2))) "more functionality to org-mode." tar ((:commit . "9d5a8e24be9acb8c55bb4d6aa8b98e30e2677401") (:authors ("Yoshinari Nomura" . "nom@quickhack.net")) (:maintainer "Yoshinari Nomura" . "nom@quickhack.net") (:keywords "org"))])
+ (orgnav . [(20170608 1713) ((helm (2 7 0)) (s (1 11 0)) (dash (1 11 0)) (emacs (24))) "Org tree navigation using helm" tar ((:commit . "9e2cac9c1a67af5f0080e60022e821bf7b70312d") (:authors ("Facet Framer" . "facet@facetframer.com")) (:maintainer "Facet Framer" . "facet@facetframer.com") (:keywords "convenience" "outlines") (:url . "http://github.com/facetframer/orgnav"))])
+ (orgstrap . [(20211126 2201) ((emacs (24 4))) "Bootstrap an Org file using file local variables" single ((:commit . "bc981b957967be8d872c08be9ba7f2dbde5caf1d") (:authors ("Tom Gillespie")) (:maintainer "Tom Gillespie") (:keywords "lisp" "org" "org-mode" "bootstrap") (:url . "https://github.com/tgbugs/orgstrap"))])
+ (orgtbl-aggregate . [(20220127 1502) nil "Create an aggregated Org table from another one" single ((:commit . "36d7aec5549655174467db45d1dba6647b9e19b1") (:keywords "org" "table" "aggregation" "filtering"))])
+ (orgtbl-ascii-plot . [(20200411 711) nil "ascii-art bar plots in org-mode tables" single ((:commit . "59618630205fc8c0fcc74fb34c4581d9712a5181") (:authors ("Thierry Banel tbanelwebmin at free dot fr") ("Michael Brand")) (:maintainer "Thierry Banel tbanelwebmin at free dot fr") (:keywords "org" "table" "ascii" "plot"))])
+ (orgtbl-join . [(20220127 1516) ((cl-lib (0 5))) "join columns from another table" single ((:commit . "f5254db6ae78e30c2786c53991e98e86ed344ac6") (:authors ("Thierry Banel tbanelwebmin at free dot fr")) (:maintainer "Thierry Banel tbanelwebmin at free dot fr") (:keywords "org" "table" "join" "filtering"))])
+ (orgtbl-show-header . [(20141023 837) nil "Show the header of the current column in the minibuffer" single ((:commit . "112d54a44682f065318ed0c9c89a8f5b8907342a") (:authors ("Damien Cassou" . "damien.cassou@gmail.com")) (:maintainer "Damien Cassou" . "damien.cassou@gmail.com"))])
+ (origami . [(20200331 1019) ((s (1 9 0)) (dash (2 5 0)) (emacs (24)) (cl-lib (0 5))) "Flexible text folding" tar ((:commit . "e558710a975e8511b9386edc81cd6bdd0a5bda74") (:authors ("Greg Sexton" . "gregsexton@gmail.com")) (:maintainer "Greg Sexton" . "gregsexton@gmail.com") (:keywords "folding") (:url . "https://github.com/gregsexton/origami.el"))])
+ (origami-predef . [(20200615 1044) ((emacs (24 3)) (origami (1 0))) "Apply folding when finding (opening) files" single ((:commit . "cc363f4b2fd20021ab330fc989369e2658457f93") (:authors ("Álvaro González Sotillo" . "alvarogonzalezsotillo@gmail.com")) (:maintainer "Álvaro González Sotillo" . "alvarogonzalezsotillo@gmail.com") (:keywords "convenience" "folding") (:url . "https://github.com/alvarogonzalezsotillo/origami-predef"))])
+ (ormolu . [(20211020 2229) ((emacs (24)) (reformatter (0 4))) "Format Haskell source code using the \"ormolu\" program" single ((:commit . "1941a8ce48027b5670d226bacc2fa10b00774b3a") (:authors ("Vasiliy Yorkin" . "vasiliy.yorkin@gmail.com")) (:maintainer "Vasiliy Yorkin") (:keywords "files" "tools") (:url . "https://github.com/vyorkin/ormolu.el"))])
+ (orthodox-christian-new-calendar-holidays . [(20210830 1657) nil "Feasts (NS)" single ((:commit . "6869024ecd45eefd0ec648979c6a59d7c79770e0") (:authors ("Carson Chittom" . "carson@wistly.net")) (:maintainer "Carson Chittom" . "carson@wistly.net") (:keywords "calendar") (:url . "https://github.com/cmchittom/orthodox-christian-new-calendar-holidays"))])
+ (osa . [(20200522 2103) ((emacs (25 1))) "OSA (JavaScript / AppleScript) bridge" tar ((:commit . "615ca9eef4131a23d9971691fa0d0f20fe59d01b") (:authors ("xristos" . "xristos@sdf.org")) (:maintainer "xristos" . "xristos@sdf.org") (:keywords "extensions") (:url . "https://github.com/atomontage/osa"))])
+ (osa-chrome . [(20201122 1639) ((emacs (25 1)) (osa (1 0))) "Google Chrome remote tab control" tar ((:commit . "9148e21cf2e91b357f5ea3a349975e8b89c8d5e4") (:authors ("xristos" . "xristos@sdf.org")) (:maintainer "xristos" . "xristos@sdf.org") (:keywords "comm") (:url . "https://github.com/atomontage/osa-chrome"))])
+ (osm . [(20220403 904) ((emacs (27 1))) "OpenStreetMap viewer" tar ((:commit . "414ef21b474ddfa5679824c026e1156dbd025c7b") (:authors ("Daniel Mendler" . "mail@daniel-mendler.de")) (:maintainer "Daniel Mendler" . "mail@daniel-mendler.de") (:url . "https://github.com/minad/osm"))])
+ (osx-browse . [(20140508 2041) ((string-utils (0 3 2)) (browse-url-dwim (0 6 6))) "Web browsing helpers for OS X" single ((:commit . "44ded7cc3a7ee426c1c3257fae534c121f7e752e") (:authors ("Roland Walker" . "walker@pobox.com")) (:maintainer "Roland Walker" . "walker@pobox.com") (:keywords "hypermedia" "external") (:url . "http://github.com/rolandwalker/osx-browse"))])
+ (osx-clipboard . [(20141012 717) nil "Use the OS X clipboard from terminal Emacs" single ((:commit . "e46dd31327a3f92f77b013b4c9b1e5fdd0e5c73d") (:authors ("Jon Oddie <jonxfield at gmail.com>")) (:maintainer "Jon Oddie <jonxfield at gmail.com>") (:url . "https://github.com/joddie/osx-clipboard-mode"))])
+ (osx-dictionary . [(20210703 1152) ((cl-lib (0 5))) "Interface for OSX Dictionary.app" tar ((:commit . "1a4479d9f44ef1e6e5f7643c172c32f6fe6cce21") (:authors ("Chunyang Xu" . "mail@xuchunyang.me")) (:maintainer "Chunyang Xu" . "mail@xuchunyang.me") (:keywords "mac" "dictionary") (:url . "https://github.com/xuchunyang/osx-dictionary.el"))])
+ (osx-lib . [(20211206 619) ((emacs (24 4))) "Basic functions for Apple/OSX" single ((:commit . "7afdb57edd5725e8a66f841a90fa571a4cbb81e7") (:authors ("Raghav Kumar Gautam" . "raghav@apache.org")) (:maintainer "Raghav Kumar Gautam" . "raghav@apache.org") (:keywords "apple" "applescript" "osx" "finder" "emacs" "elisp" "vpn" "speech") (:url . "https://github.com/raghavgautam/osx-lib"))])
+ (osx-location . [(20200304 2209) ((emacs (24 1))) "Watch and respond to changes in geographical location on OS X" tar ((:commit . "18fcc306caa575c5afdeaf091aa1a9b003daa52a") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:keywords "convenience" "calendar") (:url . "https://github.com/purcell/osx-location"))])
+ (osx-org-clock-menubar . [(20150205 2111) nil "simple menubar integration for org-clock" tar ((:commit . "9964d2a97cc2fb6570dc4116da44f73bd8eb7cb3") (:authors ("Jordon Biondo" . "jordonbiondo@gmail.com")) (:maintainer "Jordon Biondo" . "jordonbiondo@gmail.com") (:keywords "org" "osx") (:url . "https://github.com/jordonbiondo/osx-org-clock-menubar"))])
+ (osx-plist . [(20200212 1724) ((emacs (25 1))) "Apple plist file parser" single ((:commit . "46d52aa186ea50a35c1780977bf0aa261bd53922") (:authors ("Theresa O'Connor" . "tess@oconnor.cx")) (:maintainer "Neil Okamoto" . "neil.okamoto+melpa@gmail.com") (:keywords "convenience") (:url . "https://github.com/gonewest818/osx-plist"))])
+ (osx-pseudo-daemon . [(20200215 513) nil "Daemon mode that plays nice with OSX." single ((:commit . "94240ebb716f11af8427b6295c3f44c0c43419d3") (:authors ("Ryan C. Thompson")) (:maintainer "Ryan C. Thompson") (:keywords "convenience" "osx") (:url . "https://github.com/DarwinAwardWinner/osx-pseudo-daemon"))])
+ (osx-trash . [(20210419 2229) ((emacs (24 1))) "System trash for OS X" tar ((:commit . "af74a2055a15bf4182d8196600f7decd66eec634") (:authors ("Sebastian Wiesner" . "swiesner@lunaryorn.com")) (:maintainer "Sebastian Wiesner" . "swiesner@lunaryorn.com") (:keywords "files" "convenience" "tools" "unix") (:url . "https://github.com/lunaryorn/osx-trash.el"))])
+ (otama . [(20160404 1032) nil "Org-table Manipulator" single ((:commit . "c114fd8006762f891bc120a7c0ea213872e7ab31") (:authors ("Yoshinari Nomura" . "nom@quickhack.net")) (:maintainer "Yoshinari Nomura" . "nom@quickhack.net") (:keywords "database" "org-mode"))])
+ (other-emacs-eval . [(20180408 1348) ((emacs (25 1)) (async (1 9 2))) "Evaluate the Emacs Lisp expression in other Emacs" single ((:commit . "8ace5acafef65daabf0c6619eff60733d7f5d792") (:authors ("Xu Chunyang" . "mail@xuchunyang.me")) (:maintainer "Xu Chunyang" . "mail@xuchunyang.me") (:keywords "tools") (:url . "https://github.com/xuchunyang/other-emacs-eval"))])
+ (outline-magic . [(20180619 1819) nil "outline mode extensions for Emacs" single ((:commit . "2a5f07417b696cf7541d435c43bafcc64817636b") (:authors ("Carsten Dominik" . "dominik@science.uva.nl")) (:maintainer "Thorsten Jolitz <tjolitz AT gmail DOT com>") (:keywords "outlines"))])
+ (outline-minor-faces . [(20220424 1803) ((emacs (25 1)) (compat (28 1 1 0))) "Headings faces for outline-minor-mode" single ((:commit . "e92af60c68c4cb05db84c13bb71becaca90763d7") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:keywords "faces" "outlines") (:url . "https://github.com/tarsius/outline-minor-faces"))])
+ (outline-toc . [(20200401 1208) nil "Sidebar showing a \"table of contents\"." single ((:commit . "81d373633b40628cc3a6b6fb534fd7730076bcdb") (:authors ("Austin Bingham" . "austin.bingham@gmail.com")) (:maintainer "Austin Bingham" . "austin.bingham@gmail.com") (:keywords "convenience" "outlines") (:url . "https://github.com/abingham/outline-toc.el"))])
+ (outlook . [(20180428 1430) ((emacs (24 4))) "send emails in MS Outlook style" tar ((:commit . "359683aff91b38bd1398a6ed4058a06f09a02d65") (:authors ("Andrew Savonichev")) (:maintainer "Andrew Savonichev") (:keywords "mail") (:url . "https://github.com/asavonic/outlook.el"))])
+ (outorg . [(20190720 2002) ((emacs (24 4))) "Org-style comment editing" single ((:commit . "ef0f86f4b893b30be8bcf8b43a5ec357a6c70f07") (:maintainer "Adam Porter" . "adam@alphapapa.net") (:url . "https://github.com/alphapapa/outorg"))])
+ (outrespace . [(20220218 1936) ((emacs (24 4))) "Some c++ namespace utility functions" single ((:commit . "4b6f8a103b2ce76bb0638eac9356c462402b0665") (:authors ("Dan Harms" . "danielrharms@gmail.com")) (:maintainer "Dan Harms" . "danielrharms@gmail.com") (:keywords "tools" "c++" "namespace") (:url . "https://github.com/articuluxe/outrespace.git"))])
+ (outshine . [(20220326 540) ((outorg (2 0)) (cl-lib (0 5))) "outline with outshine outshines outline" tar ((:commit . "bf1eed10dd7a89b63d0fc014944033db397c1e23") (:authors ("Thorsten Jolitz")) (:maintainer "Thibault Polge" . "thibault@thb.lt") (:keywords "convenience" "outlines" "org") (:url . "https://github.com/alphapapa/outshine"))])
+ (ov . [(20200326 1042) ((emacs (24 3))) "Overlay library for Emacs Lisp" single ((:commit . "c5b9aa4e1b00d702eb2caedd61c69a22a5fa1fab") (:authors ("Shingo Fukuyama - http://fukuyama.co")) (:maintainer "Shingo Fukuyama - http://fukuyama.co") (:keywords "convenience" "overlay") (:url . "https://github.com/ShingoFukuyama/ov.el"))])
+ (overcast-theme . [(20200425 1601) ((emacs (24))) "A dark but vibrant color theme for Emacs" single ((:commit . "e02b835a08919ead079d7221d513348ac02ba92e") (:authors ("Mohammed Ismail Ansari" . "team.terminal@gmail.com")) (:maintainer "Mohammed Ismail Ansari" . "team.terminal@gmail.com") (:keywords "theme") (:url . "http://ismail.teamfluxion.com"))])
+ (overseer . [(20180226 619) ((emacs (24)) (dash (2 10 0)) (pkg-info (0 4)) (f (0 18 1))) "Ert-runner Integration Into Emacs" single ((:commit . "02d49f582e80e36b4334c9187801c5ecfb027789") (:authors ("Samuel Tonini" . "tonini.samuel@gmail.com")) (:maintainer "Samuel Tonini" . "tonini.samuel@gmail.com") (:url . "http://www.github.com/tonini/overseer.el"))])
+ (ovpn-mode . [(20210403 440) ((emacs (25)) (cl-lib (0 5))) "an openvpn management mode" single ((:commit . "4492098c771d094dd0661a5bc6906f65fb530825") (:authors ("Bas Alberts" . "bas@anti.computer")) (:maintainer "Bas Alberts" . "bas@anti.computer") (:keywords "comm") (:url . "https://github.com/anticomputer/ovpn-mode"))])
+ (owcmd . [(20200517 2039) ((emacs (26 3))) "Run a single command in the other window" single ((:commit . "05fb8f8f81838b5888fdec8b3947096dd2222e61") (:authors ("Jacob First" . "jacob.first@member.fsf.org")) (:maintainer "Jacob First" . "jacob.first@member.fsf.org") (:keywords "convenience") (:url . "https://github.com/fishyfriend/owcmd"))])
+ (owdriver . [(20200410 1901) ((smartrep (0 0 3)) (log4e (0 2 0)) (yaxception (0 2 0))) "Quickly perform various actions on other windows" single ((:commit . "3c52a7b11c8275fdb2e4cf98f68f2a48ad09a3ae") (:authors ("Hiroaki Otsu" . "ootsuhiroaki@gmail.com")) (:maintainer "Hiroaki Otsu" . "ootsuhiroaki@gmail.com") (:keywords "convenience") (:url . "https://github.com/aki2o/owdriver"))])
+ (ox-750words . [(20210701 1950) ((emacs (24 4)) (750words (0 0 1))) "Org mode exporter for 750words.com" single ((:commit . "0fed7621c04debad64ea6455455494d4e6eb03fa") (:authors ("Diego Zamboni <https://github.com/zzamboni>")) (:maintainer "Diego Zamboni" . "diego@zzamboni.org") (:keywords "files" "org" "writing") (:url . "https://github.com/zzamboni/750words-client"))])
+ (ox-asciidoc . [(20220428 740) ((org (8 1))) "AsciiDoc Back-End for Org Export Engine" single ((:commit . "c8bc184f9088b76fdf1ce20e6e5d0a1588e1b327") (:authors ("Yasushi SHOJI" . "yasushi.shoji@gmail.com")) (:maintainer "Yasushi SHOJI" . "yasushi.shoji@gmail.com") (:keywords "org" "asciidoc") (:url . "https://github.com/yashi/org-asciidoc"))])
+ (ox-bb . [(20210222 2002) ((emacs (24 4)) (org (8 0))) "BBCode Back-End for Org Export Engine" single ((:commit . "545d2e1547fdc48a5757152d19233effa11d9ee2") (:authors ("Christian Garbs" . "mitch@cgarbs.de")) (:maintainer "Christian Garbs" . "mitch@cgarbs.de") (:keywords "bbcode" "org" "export" "outlines") (:url . "https://github.com/mmitch/ox-bb"))])
+ (ox-bibtex-chinese . [(20170723 309) ((emacs (24 4))) "Let ox-bibtex work well for Chinese users" tar ((:commit . "2ad2364399229144110db7ef6365ad0461d6a38c") (:authors ("Feng Shu" . "tumashu@163.com")) (:maintainer "Feng Shu" . "tumashu@163.com") (:url . "https://github.com/tumashu/ox-bibtex-chinese.git"))])
+ (ox-clip . [(20220117 1909) ((org (8 2)) (htmlize (0))) "Cross-platform formatted copying for org-mode" single ((:commit . "ff117cf3c619eef12eccc0ccbfa3f11adb73ea68") (:authors ("John Kitchin" . "jkitchin@andrew.cmu.edu")) (:maintainer "John Kitchin" . "jkitchin@andrew.cmu.edu") (:keywords "org-mode") (:url . "https://github.com/jkitchin/ox-clip"))])
+ (ox-epub . [(20181101 1854) ((emacs (24 3)) (org (9))) "Export org mode projects to EPUB" single ((:commit . "c9629ef4b4bc40d51afefd8c0bb2c683931e6409") (:authors ("Mark Meyer" . "mark@ofosos.org")) (:maintainer "Mark Meyer" . "mark@ofosos.org") (:keywords "hypermedia") (:url . "http://github.com/ofosos/org-epub"))])
+ (ox-gemini . [(20220418 1433) ((emacs (26 1))) "Output gemini formatted documents from org-mode" single ((:commit . "168f820ea401fb813435a3a55af295873a4c110b") (:authors ("Justin Abrahms" . "justin@abrah.ms")) (:maintainer "Justin Abrahms" . "justin@abrah.ms") (:keywords "lisp" "gemini") (:url . "https://git.sr.ht/~abrahms/ox-gemini"))])
+ (ox-gfm . [(20170628 2102) nil "Github Flavored Markdown Back-End for Org Export Engine" single ((:commit . "99f93011b069e02b37c9660b8fcb45dab086a07f") (:authors ("Lars Tveito")) (:maintainer "Lars Tveito") (:keywords "org" "wp" "markdown" "github"))])
+ (ox-gist . [(20220410 2034) ((emacs (26 1)) (gist (1 4 0)) (s (1 12 0))) "Export Org mode buffers and subtrees to GitHub gists" single ((:commit . "e9f1f11af0e97fee30c2b15b56c236b1f4e1f400") (:authors ("Puneeth Chaganti" . "punchagan+emacs@muse-amuse.in")) (:maintainer "Puneeth Chaganti" . "punchagan+emacs@muse-amuse.in") (:keywords "org" "lisp" "gist" "github") (:url . "https://github.com/punchagan/org2gist/"))])
+ (ox-haunt . [(20200202 229) ((emacs (24 3)) (org (9 0))) "Haunt-flavored HTML backend for the Org export engine" single ((:commit . "f3c8fda6fee78f45a259e5d218a519dfd11c00c7") (:authors ("Jakob L. Kreuze" . "zerodaysfordays@sdf.lonestar.org")) (:maintainer "Jakob L. Kreuze" . "zerodaysfordays@sdf.lonestar.org") (:keywords "convenience" "hypermedia" "wp") (:url . "https://git.sr.ht/~jakob/ox-haunt"))])
+ (ox-html5slide . [(20131228 606) ((org (8 0))) "Export org-mode to HTML5 slide." single ((:commit . "4703dfbd9d79161509def673d2c1e118d722a58f") (:authors ("coldnew" . "coldnew.tw@gmail.com")) (:maintainer "coldnew" . "coldnew.tw@gmail.com") (:keywords "html" "presentation") (:url . "http://github.com/coldnew/org-html5slide"))])
+ (ox-hugo . [(20220504 2117) ((emacs (24 4)) (org (9 0)) (tomelr (0 2 5))) "Hugo Markdown Back-End for Org Export Engine" tar ((:commit . "4fc594eda0d0cb41cc3b634b43fbd055db7ae67e") (:authors ("Kaushal Modi" . "kaushal.modi@gmail.com") ("Matt Price" . "moptop99@gmail.com")) (:maintainer "Kaushal Modi" . "kaushal.modi@gmail.com") (:keywords "org" "markdown" "docs") (:url . "https://ox-hugo.scripter.co"))])
+ (ox-impress-js . [(20150412 1716) ((org (8))) "impress.js Back-End for Org Export Engine" tar ((:commit . "91c6d2af6af308ade352a03355c4fb551b238c6b") (:authors ("Takumi Kinjo <takumi dot kinjo at gmail dot org>")) (:maintainer "Takumi Kinjo <takumi dot kinjo at gmail dot org>") (:keywords "outlines" "hypermedia" "calendar" "wp") (:url . "https://github.com/kinjo/org-impress-js.el"))])
+ (ox-ioslide . [(20161015 1338) ((emacs (24 1)) (org (8 0)) (cl-lib (0 5)) (f (0 17 2)) (makey (0 3))) "Export org-mode to Google I/O HTML5 slide." tar ((:commit . "6555680be5364c8ddd2bf446865cb1a82adb6b9e") (:authors ("coldnew" . "coldnew.tw@gmail.com")) (:maintainer "coldnew" . "coldnew.tw@gmail.com") (:keywords "html" "presentation") (:url . "http://github.com/coldnew/org-ioslide"))])
+ (ox-jekyll-md . [(20211222 1718) nil "Export Jekyll on Markdown articles using org-mode." single ((:commit . "26edb3f4575bcb0f1a2aed56237cd89694284449") (:authors ("Elsa Gonsiorowski" . "gonsie@me.com")) (:maintainer "Elsa Gonsiorowski" . "gonsie@me.com") (:keywords "org" "jekyll"))])
+ (ox-jira . [(20220423 1403) ((org (8 3))) "JIRA Backend for Org Export Engine" single ((:commit . "00184f8fdef02a3a359a253712e8769cbfbea3ba") (:authors ("Stig Brautaset" . "stig@brautaset.org")) (:maintainer "Stig Brautaset" . "stig@brautaset.org") (:keywords "outlines" "hypermedia" "wp") (:url . "https://github.com/stig/ox-jira.el"))])
+ (ox-json . [(20210928 347) ((emacs (24)) (org (9 2)) (s (1 12))) "JSON export backend for Org mode" single ((:commit . "fc6b2594706c44d266d0863c323b1b58ab9d18ba") (:authors ("Jared Lumpe" . "mjlumpe@gmail.com")) (:maintainer "Jared Lumpe" . "mjlumpe@gmail.com") (:keywords "outlines") (:url . "https://github.com/jlumpe/ox-json"))])
+ (ox-latex-subfigure . [(20200326 919) ((emacs (24 4)) (org (9 0))) "Subfigure for latex export" single ((:commit . "c4487689309dddff3228603754b69ab381cfa5dc") (:authors ("Quang Linh LE" . "linktohack@gmail.com")) (:maintainer "Quang Linh LE" . "linktohack@gmail.com") (:keywords "convenience" "ox" "latex" "subfigure" "org" "org-mode") (:url . "http://github.com/linktohack/ox-latex-subfigure"))])
+ (ox-leanpub . [(20201129 2027) ((org (9 1)) (ox-gfm (1 0)) (emacs (26 1)) (s (1 12 0))) "Export Org documents to Leanpub book format" tar ((:commit . "4adf97dd195f0a777b952b97888b77cdd9479629") (:authors ("Diego Zamboni" . "diego@zzamboni.org")) (:maintainer "Diego Zamboni" . "diego@zzamboni.org") (:keywords "files" "org" "leanpub") (:url . "https://gitlab.com/zzamboni/ox-leanpub"))])
+ (ox-mdx-deck . [(20181115 1847) ((emacs (24)) (ox-hugo (0 7))) "org-mode to mdx-deck exporter" single ((:commit . "2e46ac76f7ac279c371474cbbf39634bbe40f4c7") (:authors ("Joshua Wolfe")) (:maintainer "Joshua Wolfe") (:keywords "lisp" "org" "ox" "mdx" "deck") (:url . "https://github.com/WolfeCub/ox-mdx-deck/"))])
+ (ox-mediawiki . [(20180105 2154) ((cl-lib (0 5)) (s (1 9 0))) "Mediawiki Back-End for Org Export Engine" single ((:commit . "a9327150293e370e500ba55bddfe5fc435c6bf9b") (:authors ("Tom Alexander" . "tomalexander@paphus.com")) (:maintainer "Tom Alexander" . "tomalexander@paphus.com") (:keywords "org" "wp" "mediawiki") (:url . "https://github.com/tomalexander/orgmode-mediawiki"))])
+ (ox-minutes . [(20180202 1734) ((emacs (24 4))) "Plain text backend for Org for Meeting Minutes" single ((:commit . "27c29f3fdb9181322ae56f8bace8d95e621230e5") (:authors ("Kaushal Modi" . "kaushal.modi@gmail.com")) (:maintainer "Kaushal Modi" . "kaushal.modi@gmail.com") (:keywords "org" "exporter" "notes") (:url . "https://github.com/kaushalmodi/ox-minutes"))])
+ (ox-nikola . [(20151114 1116) ((emacs (24 4)) (org (8 2 4)) (ox-rst (0 2))) "Export Nikola articles using org-mode." single ((:commit . "5bcbc1a38f6619f62294194f13ca0cd4ca14dd48") (:authors ("IGARASHI Masanao" . "syoux2@gmail.com")) (:maintainer "IGARASHI Masanao" . "syoux2@gmail.com") (:keywords "org" "nikola") (:url . "https://github.com/masayuko/ox-nikola"))])
+ (ox-pandoc . [(20220419 750) ((org (8 2)) (emacs (24 4)) (dash (2 8)) (ht (2 0))) "An Org-mode exporter using pandoc" single ((:commit . "0a35d0fbfa56bdd9ec5ba5bac2fe002b61c05c52") (:authors ("KAWABATA, Taichi" . "kawabata.taichi@gmail.com") ("FENTON, Alex" . "a-fent@github")) (:maintainer "FENTON, Alex" . "a-fent@github") (:keywords "tools") (:url . "https://github.com/a-fent/ox-pandoc"))])
+ (ox-pukiwiki . [(20150124 1716) ((org (8 1))) "Pukiwiki Back-End for Org Export Engine" single ((:commit . "bdbde2c294f5d3de11f08a3fe19f01175d2e011a") (:authors ("Yasushi SHOJI" . "yasushi.shoji@gmail.com")) (:maintainer "Yasushi SHOJI" . "yasushi.shoji@gmail.com") (:keywords "org" "pukiwiki") (:url . "https://github.com/yashi/org-pukiwiki"))])
+ (ox-qmd . [(20210826 1425) ((emacs (24 4))) "Qiita Markdown Back-End for Org Export Engine" single ((:commit . "ccabf6bd79ed87dd3bd57993321ee6d93c1818be") (:authors ("0x60DF" . "0x60DF@gmail.com")) (:maintainer "0x60DF" . "0x60DF@gmail.com") (:keywords "wp") (:url . "https://github.com/0x60df/ox-qmd"))])
+ (ox-report . [(20211226 2004) ((emacs (24 4)) (org-msg (3 9))) "Export your org file to minutes report PDF file" single ((:commit . "c6d8c2f4a0d762ea1732ffdb7bec2ba98aeecdd9") (:authors ("Matthias David" . "matthias@gnu.re")) (:maintainer "Matthias David" . "matthias@gnu.re") (:keywords "org" "outlines" "report" "exporter" "meeting" "minutes") (:url . "https://github.com/DarkBuffalo/ox-report"))])
+ (ox-reveal . [(20220410 1533) ((org (8 3))) "reveal.js Presentation Back-End for Org Export Engine" single ((:commit . "862b41df7734f57019543f6bd82ff7dad7183358") (:authors ("Yujie Wen <yjwen.ty at gmail dot com>")) (:maintainer "Yujie Wen <yjwen.ty at gmail dot com>") (:keywords "outlines" "hypermedia" "slideshow" "presentation"))])
+ (ox-review . [(20220502 1146) ((emacs (26 1)) (org (9))) "Re:VIEW Back-End for Org Export Engine" single ((:commit . "4abb1aa4665d246a38a9a53e5b365b3e57ec6d85") (:authors ("Masashi Fujimoto")) (:maintainer "Masashi Fujimoto") (:keywords "outlines" "hypermedia") (:url . "https://github.com/masfj/ox-review"))])
+ (ox-rfc . [(20220206 1046) ((emacs (24 3)) (org (8 3))) "RFC Back-End for Org Export Engine" single ((:commit . "0849028a2e4a274bfb0fc85d9538203ddf72a9e8") (:authors ("Christian Hopps" . "chopps@devhopps.com")) (:maintainer "Christian Hopps" . "chopps@devhopps.com") (:keywords "org" "rfc" "wp" "xml") (:url . "https://github.com/choppsv1/org-rfc-export"))])
+ (ox-rst . [(20200815 1511) ((emacs (25 1)) (org (8 3))) "Export reStructuredText using org-mode." single ((:commit . "99fa790da55b57a3f2e9aa187493ba434a64250e") (:authors ("Masanao Igarashi" . "syoux2@gmail.com")) (:maintainer "Masanao Igarashi" . "syoux2@gmail.com") (:keywords "org" "rst" "rest" "restructuredtext") (:url . "https://github.com/msnoigrs/ox-rst"))])
+ (ox-slack . [(20200108 1546) ((emacs (24)) (org (9 1 4)) (ox-gfm (1 0))) "Slack Exporter for org-mode" single ((:commit . "bd797dcc58851d5051dc3516c317706967a44721") (:authors ("Matt Price")) (:maintainer "Matt Price") (:keywords "org" "slack" "outlines") (:url . "https://github.com/titaniumbones/ox-slack"))])
+ (ox-spectacle . [(20181211 953) ((org (8 3))) "spectacle.js Presentation Back-End for Org Export Engine" single ((:commit . "9d3ec9a6326289074d8620e97d65e3105307ff51") (:authors ("imfine" . "lorniu@gmail.com")) (:maintainer "imfine" . "lorniu@gmail.com") (:keywords "presentation"))])
+ (ox-ssh . [(20210917 1517) ((emacs (24 4))) "SSH Config Backend for Org Export Engine" single ((:commit . "be3b39160da6ae37b1f1cd175ed854ac41d1cb63") (:authors ("Dante Catalfamo")) (:maintainer "Dante Catalfamo") (:keywords "outlines" "org" "ssh") (:url . "https://github.com/dantecatalfamo/ox-ssh"))])
+ (ox-textile . [(20210919 1738) ((org (8 1))) "Textile Back-End for Org Export Engine" single ((:commit . "5f2f61f572c24d702e922845c11a4c3da38ab261") (:authors ("Yasushi SHOJI" . "yasushi.shoji@gmail.com")) (:maintainer "Yasushi SHOJI" . "yasushi.shoji@gmail.com") (:keywords "org" "textile") (:url . "https://github.com/yashi/org-textile"))])
+ (ox-tiddly . [(20200927 857) ((org (8)) (emacs (24 4))) "Org TiddlyWiki exporter" single ((:commit . "3377d8732aa916e736ce5822c7a9a4fbdc894e37") (:authors ("Derek Feichtinger" . "derek.feichtinger@psi.ch")) (:maintainer "Derek Feichtinger" . "derek.feichtinger@psi.ch") (:keywords "org") (:url . "https://github.com/dfeich/org8-wikiexporters"))])
+ (ox-timeline . [(20220321 2115) ((emacs (24 4))) "HTML Timeline Back-End for Org Export Engine" single ((:commit . "b28bd4ccd5fa114c0f51b9766f0b9be7fe05fdd8") (:authors ("Joel Bryan Juliano <joelbryan dot juliano at gmail dot com>")) (:maintainer "Joel Bryan Juliano <joelbryan dot juliano at gmail dot com>") (:keywords "simple timeline" "timeline" "hypermedia" "html timeline") (:url . "https://github.com/jjuliano/org-simple-timeline"))])
+ (ox-trac . [(20171026 1823) ((org (9 0))) "Org Export Backend to Trac WikiFormat" single ((:commit . "03cc31efb1aa06991918f1071e250a9d58f96cfb") (:authors ("Brian J. Carlson <hacker (at) abutilize (dot) com>")) (:maintainer "Brian J. Carlson <hacker (at) abutilize (dot) com>") (:keywords "org-mode" "trac") (:url . "https://github.com/JalapenoGremlin/ox-trac"))])
+ (ox-tufte . [(20160926 1607) ((org (8 2)) (emacs (24))) "Tufte HTML org-mode export backend" single ((:commit . "49d7ea78fde063b407ce6fa57739f90c83500682") (:authors ("M. Lee Hinman")) (:maintainer "M. Lee Hinman") (:keywords "org" "tufte" "html") (:url . "https://github.com/dakrone/ox-tufte"))])
+ (ox-twbs . [(20200628 1949) nil "Bootstrap compatible HTML Back-End for Org" single ((:commit . "e8a27dc78b7be494d9918f26db7a3bbb6b45020b") (:authors ("Carsten Dominik <carsten at orgmode dot org>") ("Jambunathan K <kjambunathan at gmail dot com>") ("Brandon van Beekum <marsmining at gmail dot com>")) (:maintainer "Carsten Dominik <carsten at orgmode dot org>") (:keywords "org" "html" "publish" "twitter" "bootstrap") (:url . "https://github.com/marsmining/ox-twbs"))])
+ (ox-twiki . [(20200927 857) ((org (8)) (emacs (24 4))) "Org Twiki and Foswiki export" single ((:commit . "3377d8732aa916e736ce5822c7a9a4fbdc894e37") (:authors ("Derek Feichtinger" . "derek.feichtinger@psi.ch")) (:maintainer "Derek Feichtinger" . "derek.feichtinger@psi.ch") (:keywords "org") (:url . "https://github.com/dfeich/org8-wikiexporters"))])
+ (ox-wk . [(20191231 2058) ((emacs (24 4)) (org (8 3))) "Wiki Back-End for Org Export Engine" single ((:commit . "d34d1b72e4e940745a377bfa745dfb618900a09e") (:authors ("Vilibald Wanča" . "vilibald@wvi.cz")) (:maintainer "Vilibald Wanča" . "vilibald@wvi.cz") (:keywords "org" "wp" "wiki") (:url . "https://github.com/w-vi/ox-wk.el"))])
+ (ox-yaow . [(20220103 2307) ((emacs (27)) (f (0 2 0)) (s (1 12 0)) (dash (2 17 0))) "Generate html pages from org files" single ((:commit . "378eb55e39cbc06ead0f0c399351612dca22d716") (:authors ("Laurence Warne")) (:maintainer "Laurence Warne") (:keywords "outlines" "hypermedia") (:url . "https://github.com/LaurenceWarne/ox-yaow.el"))])
+ (ox-zenn . [(20200924 1607) ((emacs (27 1)) (org (9 0))) "Zenn flavored markdown backend for org export engine" single ((:commit . "b53bd82116c9f7dbb5b476d2cfcc8ed0f3bc9c78") (:authors ("Naoya Yamashita" . "conao3@gmail.com")) (:maintainer "Naoya Yamashita" . "conao3@gmail.com") (:keywords "convenience") (:url . "https://github.com/conao3/ox-zenn.el"))])
+ (p4 . [(20150721 1937) nil "Simple Perforce-Emacs Integration" single ((:commit . "eff047caa75dbe4965defca9d1212454cdb755d5") (:authors ("Gareth Rees" . "gdr@garethrees.org")) (:maintainer "Gareth Rees" . "gdr@garethrees.org") (:url . "https://github.com/gareth-rees/p4.el"))])
+ (pabbrev . [(20160320 2101) nil "Predictive abbreviation expansion" single ((:commit . "56400d5d256b42ffe45c229ea9827f026b650cf5") (:authors ("Phillip Lord" . "phillip.lord@newcastle.ac.uk")) (:maintainer "Phillip Lord" . "phillip.lord@newcastle.ac.uk"))])
+ (pacfiles-mode . [(20200915 1815) ((emacs (26)) (cl-lib (0 5))) "pacnew and pacsave merging tool" tar ((:commit . "8d06f64abc98c3f3338560c8d6eb47719e034069") (:authors ("Carlos G. Cordero <http://github/UndeadKernel>")) (:maintainer "Carlos G. Cordero" . "pacfiles@binarycharly.com") (:keywords "files" "pacman" "arch" "pacnew" "pacsave" "update" "linux") (:url . "https://github.com/UndeadKernel/pacfiles-mode"))])
+ (pack . [(20191017 456) ((emacs (24)) (cl-lib (0 5))) "Pack and unpack archive files" single ((:commit . "85cd856fdc00a2365e88b50373b99f1b3d2227be") (:authors ("10sr" . "8.slashes@gmail.com")) (:maintainer "10sr" . "8.slashes@gmail.com") (:keywords "files" "dired") (:url . "https://github.com/10sr/pack-el"))])
+ (package+ . [(20210124 640) ((emacs (24 3))) "Extensions for the package library." tar ((:commit . "079da78f3be8364e964f5861a5f433ad61b6f654") (:authors ("Ryan Davis" . "ryand-ruby@zenspider.com")) (:maintainer "Ryan Davis" . "ryand-ruby@zenspider.com") (:keywords "extensions" "tools") (:url . "https://github.com/zenspider/package"))])
+ (package-build . [(20220210 1334) ((cl-lib (0 5)) (emacs (25 1))) "Tools for assembling a package archive" tar ((:commit . "032e9bd086029b2fdff09c3c2e606e29682e1fb1") (:authors ("Donald Ephraim Curtis" . "dcurtis@milkbox.net")) (:maintainer "Donald Ephraim Curtis" . "dcurtis@milkbox.net") (:keywords "tools") (:url . "https://github.com/melpa/package-build"))])
+ (package-filter . [(20161122 719) nil "package archive whitelist and blacklist" single ((:commit . "bc73b41aea1d65ca44ef1593ca13126df9bbb39e") (:authors ("Donald Ephraim Curtis" . "dcurtis@milkbox.net")) (:maintainer "Donald Ephraim Curtis" . "dcurtis@milkbox.net") (:url . "https://github.com/milkypostman/package-filter"))])
+ (package-lint . [(20220412 1648) ((cl-lib (0 5)) (emacs (24 1)) (let-alist (1 0 6))) "A linting library for elisp package authors" tar ((:commit . "80a9d9815ab2919c992ad29ae4846443dec43a35") (:authors ("Steve Purcell" . "steve@sanityinc.com") ("Fanael Linithien" . "fanael4@gmail.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:keywords "lisp") (:url . "https://github.com/purcell/package-lint"))])
+ (package-lint-flymake . [(20210530 319) ((emacs (26 1)) (package-lint (0 5))) "A package-lint Flymake backend" single ((:commit . "80a9d9815ab2919c992ad29ae4846443dec43a35") (:url . "https://github.com/purcell/package-lint"))])
+ (package-loading-notifier . [(20220130 318) ((emacs (25))) "Notify a package is being loaded" single ((:commit . "bc06ba97a0537aa202f277e5597ac96ca39307ab") (:authors ("SeungKi Kim" . "tttuuu888@gmail.com")) (:maintainer "SeungKi Kim" . "tttuuu888@gmail.com") (:keywords "convenience" "faces" "config" "startup") (:url . "https://github.com/tttuuu888/package-loading-notifier"))])
+ (package-safe-delete . [(20150116 1607) ((emacs (24)) (epl (0 7 -4))) "Safely delete package.el packages" single ((:commit . "138171e4fc03c0ef05a8260cbb5cd2e114c1c194") (:authors ("Fanael Linithien" . "fanael4@gmail.com")) (:maintainer "Fanael Linithien" . "fanael4@gmail.com") (:url . "https://github.com/Fanael/package-safe-delete"))])
+ (package-utils . [(20210221 822) ((restart-emacs (0 1 1))) "Extensions for package.el" single ((:commit . "6a26accfdf9c0f1cbceb09d970bf9c25a72f562a") (:authors ("Philippe Vaucher" . "philippe.vaucher@gmail.com")) (:maintainer "Philippe Vaucher" . "philippe.vaucher@gmail.com") (:keywords "package" "convenience") (:url . "https://github.com/Silex/package-utils"))])
+ (packed . [(20220422 1626) ((emacs (25 1)) (compat (28 1 1 0))) "Package manager agnostic Emacs Lisp package utilities" single ((:commit . "3489c97340434096f24c64a33feea22e19c18a2c") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:keywords "lisp") (:url . "https://github.com/emacscollective/packed"))])
+ (pacmacs . [(20220106 2248) ((emacs (24 4)) (dash (2 18 0)) (cl-lib (0 5)) (f (0 18 0))) "Pacman for Emacs" tar ((:commit . "25a8c30210f6bd94634a7ff743a2f8be391ed3b3") (:authors ("Codingteam" . "codingteam@conference.jabber.ru")) (:maintainer "Alexey Kutepov" . "reximkut@gmail.com") (:url . "http://github.com/codingteam/pacmacs.el"))])
+ (pact-mode . [(20201219 2223) ((emacs (24 3))) "Mode for Pact, a LISPlike smart contract language." single ((:commit . "f48a4faf5f8f8435423bda3888eca6ee67ee13a9") (:authors ("Stuart Popejoy")) (:maintainer "Stuart Popejoy" . "stuart@kadena.io") (:keywords "pact" "lisp" "languages" "blockchain" "smartcontracts" "tools" "mode") (:url . "https://github.com/kadena-io/pact-mode"))])
+ (paganini-theme . [(20180815 1921) ((emacs (24 0))) "A colorful, dark and warm theme." single ((:commit . "255c5a2a8abee9c5935465ec42b9c3604c178c3c") (:authors ("Onur Temizkan")) (:maintainer "Onur Temizkan") (:url . "https://github.com/onurtemizkan/paganini"))])
+ (page-break-lines . [(20210104 2224) ((emacs (24 4))) "Display ^L page breaks as tidy horizontal lines" single ((:commit . "cc283621c64e4f1133a63e0945658a4abecf42ef") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:keywords "convenience" "faces") (:url . "https://github.com/purcell/page-break-lines"))])
+ (pager . [(20151202 120) nil "windows-scroll commands" single ((:commit . "5c791ed23f1136e04040d6f4bc9b4ca5b6dc919f") (:authors (nil . "Mikael Sjödin -- mic@docs.uu.se")) (:maintainer nil . "Mikael Sjödin -- mic@docs.uu.se"))])
+ (pager-default-keybindings . [(20130719 2057) ((pager (1 0))) "Add the default keybindings suggested for pager.el" single ((:commit . "dbbd49c2ac5906d1dabf9e9c832bfebc1ab405b3") (:authors ("Nathaniel Flath" . "nflath@gmail.com")) (:maintainer "Nathaniel Flath" . "nflath@gmail.com") (:url . "http://github.com/nflath/pager-default-keybindings"))])
+ (paimon . [(20220326 2051) ((aio (1 0)) (closql (1 2 0)) (emacs (27 1)) (emacsql (3 0 0)) (emacsql-sqlite (3 0 0)) (f (0 20 0)) (ht (2 4)) (transient (0 3 7)) (request (0 3 3))) "A major mode for Splunk" tar ((:commit . "01675ff30ce0f29ad81f9275b4fc0797c0a7073f") (:authors ("r0man" . "roman@burningswell.com")) (:maintainer "r0man" . "roman@burningswell.com") (:keywords "paimon" "search" "tools") (:url . "https://github.com/r0man/paimon.el"))])
+ (pair-tree . [(20211219 1816) ((emacs (27 1)) (dash (2 17 0))) "Visualize a list" single ((:commit . "6fe6143954bb4025ce6b05aad41e777fcbf413d9") (:authors ("Zainab Ali <zainab @kebab-ca.se>")) (:maintainer "Zainab Ali <zainab @kebab-ca.se>") (:keywords "lisp" "tools") (:url . "https://github.com/zainab-ali/pair-tree"))])
+ (palimpsest . [(20200804 2308) nil "Various deletion strategies when editing" single ((:commit . "f474b3ad706373d9953abdc401d683a2a023d28e") (:authors ("Daniel Szmulewicz" . "daniel.szmulewicz@gmail.com")) (:maintainer "Daniel Szmulewicz" . "daniel.szmulewicz@gmail.com"))])
+ (pallet . [(20150512 702) ((dash (2 10 0)) (s (1 9 0)) (f (0 17 1)) (cask (0 7))) "A package management tool for Emacs, using Cask." tar ((:commit . "b8d0df1883224a371ac0a3bc9b9c1c4dc61e6ac0") (:authors ("Robert Dallas Gray")) (:maintainer "Robert Dallas Gray") (:keywords "elpa" "package") (:url . "https://github.com/rdallasgray/pallet"))])
+ (pamparam . [(20210105 1513) ((emacs (26 1)) (lispy (0 27 0)) (worf (0 1 0)) (ivy-posframe (0 5 5))) "Simple and fast flashcards." tar ((:commit . "0ba91149095bee8c43688c68f83f4d365fbe6771") (:authors ("Oleh Krehel" . "ohwoeowho@gmail.com")) (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com") (:keywords "outlines" "hypermedia" "flashcards" "memory") (:url . "https://github.com/abo-abo/pamparam"))])
+ (panda . [(20200715 338) ((emacs (25))) "Client for Bamboo's REST API." single ((:commit . "44beb80ac991e58231c05dc4afa1646fa768d573") (:authors ("Sebastian Monia" . "smonia@outlook.com")) (:maintainer "Sebastian Monia" . "smonia@outlook.com") (:keywords "maint" "tool") (:url . "https://github.com/sebasmonia/panda"))])
+ (panda-theme . [(20181128 1738) ((emacs (24))) "Panda Theme" single ((:commit . "60aa47c7a930377807da0d601351ad91e8ca446a") (:authors ("jamiecollinson" . "jamiecollinson@gmail.com")) (:maintainer "jamiecollinson" . "jamiecollinson@gmail.com") (:url . "https://github.com/jamiecollinson/emacs-panda-theme"))])
+ (pandoc . [(20161128 1157) ((emacs (24 4))) "Pandoc interface" single ((:commit . "198d262d09e30448f1672338b0b5a81cf75e1eaa") (:authors ("USAMI Kenta" . "tadsan@zonu.me")) (:maintainer "USAMI Kenta" . "tadsan@zonu.me") (:keywords "hypermedia" "documentation" "markup" "converter") (:url . "https://github.com/zonuexe/pandoc.el"))])
+ (pandoc-mode . [(20211208 2229) ((hydra (0 10 0)) (dash (2 10 0))) "Minor mode for interacting with Pandoc" tar ((:commit . "c1429887287b7ee9601196e26f97c908b6e4f5c0") (:authors ("Joost Kremers" . "joostkremers@fastmail.fm")) (:maintainer "Joost Kremers" . "joostkremers@fastmail.fm") (:keywords "text" "pandoc") (:url . "http://joostkremers.github.io/pandoc-mode/"))])
+ (pangu-spacing . [(20190823 401) nil "Minor-mode to add space between Chinese and English characters." single ((:commit . "f92898949ba3bf991fd229416f3bbb54e9c6c223") (:authors ("coldnew" . "coldnew.tw@gmail.com")) (:maintainer "coldnew" . "coldnew.tw@gmail.com") (:url . "http://github.com/coldnew/pangu-spacing"))])
+ (paper-theme . [(20200510 5) ((emacs (24))) "A minimal Emacs colour theme." single ((:commit . "350af0e5d53307c900e4f8b2617f3852f51a74d2") (:authors ("Göktuğ Kayaalp")) (:maintainer "Göktuğ Kayaalp") (:keywords "theme" "paper") (:url . "https://dev.gkayaalp.com/elisp/index.html#paper"))])
+ (paperless . [(20201130 1241) ((emacs (24 4)) (f (0 11 0)) (s (1 10 0)) (cl-lib (0 6 1))) "A major mode for sorting and filing PDF documents." tar ((:commit . "2db39586a2914f78f345379511d0e8cea4c96b86") (:authors ("Anthony Green" . "green@moxielogic.com")) (:maintainer "Anthony Green" . "green@moxielogic.com") (:keywords "pdf" "convenience") (:url . "http://github.com/atgreen/paperless"))])
+ (paradox . [(20191011 1111) ((emacs (24 4)) (seq (1 7)) (let-alist (1 0 3)) (spinner (1 7 3)) (hydra (0 13 2))) "A modern Packages Menu. Colored, with package ratings, and customizable." tar ((:commit . "339fe3518d1d102b2295670340e75caf4f01a29a") (:authors ("Artur Malabarba" . "emacs@endlessparentheses.com")) (:maintainer "Artur Malabarba" . "emacs@endlessparentheses.com") (:keywords "package" "packages") (:url . "https://github.com/Malabarba/paradox"))])
+ (parchment-theme . [(20200910 2310) ((autothemer (0 2))) "Light theme inspired by Acme and Leuven" single ((:commit . "95e8248edbdb01fedc7db4472bcce90d2d872106") (:authors ("Alex Griffin" . "a@ajgrf.com")) (:maintainer "Alex Griffin" . "a@ajgrf.com") (:url . "https://github.com/ajgrf/parchment"))])
+ (paredit . [(20191121 2328) nil "minor mode for editing parentheses" single ((:commit . "8330a41e8188fe18d3fa805bb9aa529f015318e8") (:authors ("Taylor R. Campbell" . "campbell+paredit@mumble.net")) (:maintainer "Taylor R. Campbell" . "campbell+paredit@mumble.net") (:keywords "lisp"))])
+ (paredit-everywhere . [(20210510 531) ((paredit (22))) "Enable some paredit features in non-lisp buffers" single ((:commit . "b81e5d5356c85001a71640941b469aea9cf2e309") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:keywords "languages" "convenience"))])
+ (paredit-menu . [(20160128 1733) ((paredit (25))) "Adds a menu to paredit.el as memory aid" single ((:commit . "cc0ae85bd819f9ebfa4f2a419ab3b2d70e39c9c8") (:authors ("Phillip Lord" . "phillip.lord@newcastle.ac.uk")) (:maintainer "Phillip Lord" . "phillip.lord@newcastle.ac.uk") (:keywords "paredit"))])
+ (paren-completer . [(20160501 1052) ((emacs (24 3))) "Automatically, language agnostically, fill in delimiters." single ((:commit . "74183a8e13fa1266271bdcbcb4bfb29a4f915f0a") (:authors ("Matthew Bregg")) (:maintainer "Matthew Bregg") (:keywords "convenience") (:url . "https://github.com/MatthewBregg/paren-completer"))])
+ (paren-face . [(20220422 1627) ((emacs (25 1)) (compat (28 1 1 0))) "A face for parentheses in lisp modes" single ((:commit . "5dc2c2e06152dc51f7395073569f448a8f94d296") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:keywords "faces" "lisp") (:url . "https://github.com/tarsius/paren-face"))])
+ (parent-mode . [(20150824 2300) nil "get major mode's parent modes" single ((:commit . "db692cf08deff2f0e973e6e86e26662b44813d1b") (:authors ("Fanael Linithien" . "fanael4@gmail.com")) (:maintainer "Fanael Linithien" . "fanael4@gmail.com") (:url . "https://github.com/Fanael/parent-mode"))])
+ (parinfer-rust-mode . [(20210413 2) ((emacs (26 1))) "An interface for the parinfer-rust library" tar ((:commit . "c2c1bbec6cc7dad4f546868aa07609b8d58a78f8") (:authors ("Justin Barclay" . "justinbarclay@gmail.com")) (:maintainer "Justin Barclay" . "justinbarclay@gmail.com") (:keywords "lisp" "tools") (:url . "https://github.com/justinbarclay/parinfer-rust-mode"))])
+ (parrot . [(20220101 518) ((emacs (24 1))) "Party Parrot rotates gracefully in mode-line." tar ((:commit . "1d381f24d74242018e306d1a0c891bed9a465ac3") (:authors ("Daniel Ting" . "deep.paren.12@gmail.com")) (:maintainer "Daniel Ting" . "deep.paren.12@gmail.com") (:keywords "party" "parrot" "rotate" "sirocco" "kakapo" "games") (:url . "https://github.com/dp12/parrot.git"))])
+ (parse-csv . [(20160512 1723) nil "Parse strings with CSV fields into s-expressions" single ((:commit . "96bef1ffbc89ea12d13311c9fa239c5c3e864890") (:authors ("Edward Marco Baringer (Common Lisp)") ("Matt Curtis" . "matt.r.curtis@gmail.com")) (:maintainer "Matt Curtis" . "matt.r.curtis@gmail.com") (:keywords "csv") (:url . "https://github.com/mrc/el-csv"))])
+ (parse-it . [(20220214 1531) ((emacs (25 1)) (s (1 12 0))) "Basic Parser in Emacs Lisp" tar ((:commit . "c2bdc5ee1d1f029886245f9a5c409e47c1db2cb8") (:authors ("Shen, Jen-Chieh" . "jcs090218@gmail.com")) (:maintainer "Shen, Jen-Chieh" . "jcs090218@gmail.com") (:url . "https://github.com/jcs-elpa/parse-it"))])
+ (parsebib . [(20220426 2049) ((emacs (25 1))) "A library for parsing bib files" single ((:commit . "dd4c5540fa6c2cd990cba324741d7abbc8ed2f23") (:authors ("Joost Kremers" . "joostkremers@fastmail.fm")) (:maintainer "Joost Kremers" . "joostkremers@fastmail.fm") (:keywords "text" "bibtex") (:url . "https://github.com/joostkremers/parsebib"))])
+ (parsec . [(20180730 16) ((emacs (24)) (cl-lib (0 5))) "Parser combinator library" single ((:commit . "2cbbbc2254aa7bcaa4fb5e07c8c1bf2f381dba26") (:authors ("Junpeng Qiu" . "qjpchmail@gmail.com")) (:maintainer "Junpeng Qiu" . "qjpchmail@gmail.com") (:keywords "extensions") (:url . "https://github.com/cute-jumper/parsec.el"))])
+ (parseclj . [(20220422 936) ((emacs (25))) "Clojure/EDN parser" tar ((:commit . "4d0e780e00f1828b00c43099e6eebc6582998f72") (:authors ("Arne Brasseur" . "arne@arnebrasseur.net")) (:maintainer "Arne Brasseur" . "arne@arnebrasseur.net") (:keywords "lisp" "clojure" "edn" "parser"))])
+ (parseedn . [(20220422 936) ((emacs (26)) (parseclj (1 1 0)) (map (2))) "Clojure/EDN parser" single ((:commit . "dce2eed418ad21acf3d2d6d75c37dfa679b22359") (:authors ("Arne Brasseur" . "arne@arnebrasseur.net")) (:maintainer "Arne Brasseur" . "arne@arnebrasseur.net") (:keywords "lisp" "clojure" "edn" "parser"))])
+ (pasp-mode . [(20180404 1700) ((emacs (24 3))) "- A major mode for editing Answer Set Programs." single ((:commit . "59385eb0e8ebcfc8c11dd811fb145d4b0fa3cc92") (:authors ("Henrik Jürges" . "juerges.henrik@gmail.com")) (:maintainer "Henrik Jürges" . "juerges.henrik@gmail.com") (:keywords "asp" "pasp" "answer set programs" "potassco answer set programs" "major mode" "languages") (:url . "https://github.com/santifa/pasp-mode"))])
+ (pass . [(20210203 810) ((emacs (25)) (password-store (2 1 0)) (password-store-otp (0 1 5)) (f (0 17))) "Major mode for password-store.el" single ((:commit . "5651da53137db9adcb125b4897c2fe27eeb4368d") (:authors ("Nicolas Petton" . "petton.nicolas@gmail.com") ("Damien Cassou" . "damien@cassou.me")) (:maintainer "Nicolas Petton" . "petton.nicolas@gmail.com") (:keywords "password-store" "password" "keychain"))])
+ (passmm . [(20210109 8) ((emacs (24 4)) (password-store (0))) "A minor mode for pass (Password Store)." single ((:commit . "d78d1bf4f397180d2256248df589f33aafb4c8b4") (:authors ("Peter Jones" . "pjones@devalot.com")) (:maintainer "Peter Jones" . "pjones@devalot.com") (:url . "https://github.com/pjones/passmm"))])
+ (password-generator . [(20210425 2227) nil "Password generator for humans. Good, Bad, Phonetic passwords included." single ((:commit . "c1da9790d594bc745cdbcc8003153e408aa92a5f") (:authors ("Vandrlexay")) (:maintainer "Vandrlexay") (:url . "http://github.com/vandrlexay/emacs-password-genarator"))])
+ (password-mode . [(20220222 1757) ((emacs (25 1))) "Hide password text using overlays" single ((:commit . "456a01e959140cb070e77bce5032a6885c7b7ae0") (:authors ("Jürgen Hötzel" . "juergen@archlinux.org")) (:maintainer "Jürgen Hötzel" . "juergen@archlinux.org") (:keywords "docs" "password" "passphrase") (:url . "https://github.com/juergenhoetzel/password-mode"))])
+ (password-store . [(20220306 2230) ((emacs (25)) (s (1 9 0)) (with-editor (2 5 11)) (auth-source-pass (5 0 0))) "Password store (pass) support" single ((:commit . "c4d8a1d815e79ddd89a85d3e36a41d29f0475771") (:authors ("Svend Sorensen" . "svend@svends.net")) (:maintainer "Tino Calancha" . "tino.calancha@gmail.com") (:keywords "tools" "pass" "password" "password-store") (:url . "https://www.passwordstore.org/"))])
+ (password-store-otp . [(20220128 1320) ((emacs (25)) (s (1 9 0)) (password-store (0 1))) "Password store (pass) OTP extension support" single ((:commit . "be3a00a981921ed1b2f78012944dc25eb5a0beca") (:authors ("Daniel Barreto")) (:maintainer "Daniel Barreto") (:keywords "tools" "pass") (:url . "https://github.com/volrath/password-store-otp.el"))])
+ (password-vault . [(20220321 1521) ((cl-lib (0 2)) (emacs (24))) "A Password manager for Emacs." single ((:commit . "763750e2fbdd3bc96dfd256215b5e49394b7bef3") (:authors ("Javier \"PuercoPop\" Olaechea" . "pirata@gmail.com")) (:maintainer "Javier \"PuercoPop\" Olaechea" . "pirata@gmail.com") (:keywords "password" "productivity") (:url . "http://github.com/PuercoPop/password-vault"))])
+ (paste-of-code . [(20170709 2355) ((emacs (24 3)) (request (0 2 0))) "paste code on https://paste.ofcode.org" single ((:commit . "92d258e8ec98598d847ecab82903f9224c7c2050") (:authors ("Bernhard Specht" . "bernhard@specht.net")) (:maintainer "Bernhard Specht" . "bernhard@specht.net") (:keywords "lisp"))])
+ (pastebin . [(20101125 2002) nil "A simple interface to the www.pastebin.com webservice" single ((:commit . "8e9a829298ce0f747ab80758aa26caeb2af6cb30"))])
+ (pastehub . [(20140615 620) nil "A client for the PasteHub cloud service" single ((:commit . "37b045c67659c078f1517d0fbd5282dab58dca23") (:authors ("Kiyoka Nishiyama")) (:maintainer "Kiyoka Nishiyama") (:url . "https://github.com/kiyoka/pastehub"))])
+ (pastelmac-theme . [(20151031 236) ((emacs (24 1))) "a soothing theme with a pastel color palette" single ((:commit . "bead21741e3f46f6506e8aef4469d4240a819389") (:authors ("Brian Mastenbrook" . "brian@mastenbrook.net")) (:maintainer "Brian Mastenbrook" . "brian@mastenbrook.net") (:keywords "themes") (:url . "https://github.com/bmastenbrook/pastelmac-theme-el"))])
+ (pastery . [(20171114 349) ((emacs (24 4)) (request (0 2 0))) "paste snippets to pastery.net." tar ((:commit . "4493be98b743b4d062cb4e00760125e394a55022") (:authors ("Bruno Dias" . "dias.h.bruno@gmail.com")) (:maintainer "Bruno Dias" . "dias.h.bruno@gmail.com") (:keywords "tools") (:url . "https://github.com/diasbruno/pastery.el"))])
+ (path-headerline-mode . [(20140423 1332) nil "Displaying file path on headerline." single ((:commit . "b5b2725c6a8b1cb592fc242b7dbbd54b4dff2e69") (:authors ("7696122")) (:maintainer "7696122") (:keywords "headerline") (:url . "https://github.com/7696122/path-headerline-mode"))])
+ (path-helper . [(20181208 2229) ((emacs (24))) "Set PATH environment variables from config files" single ((:commit . "34538affb3f341b3c56a875bb094ddb2b859a8ef") (:authors ("Arnaud Rouanet" . "arnaud@rouanet.org")) (:maintainer "Arnaud Rouanet" . "arnaud@rouanet.org") (:keywords "tools" "unix") (:url . "https://github.com/arouanet/path-helper"))])
+ (pathify . [(20160423 846) nil "Symlink your scripts into a PATH directory" single ((:commit . "401b184c743694a60b3bc4273fc43de05cd5ac4b") (:authors ("Alex Kost" . "alezost@gmail.com")) (:maintainer "Alex Kost" . "alezost@gmail.com") (:keywords "convenience") (:url . "https://gitlab.com/alezost-emacs/pathify"))])
+ (paxedit . [(20160730 1727) ((cl-lib (0 5)) (paredit (23))) "Structured, Context Driven LISP Editing and Refactoring" single ((:commit . "09f3d5aeb108937a801e77ef413e29eaa4ecc4be") (:authors ("Mustafa Shameem")) (:maintainer "Mustafa Shameem") (:keywords "lisp" "refactoring" "context") (:url . "https://github.com/promethial/paxedit"))])
+ (pbcopy . [(20150225 459) nil "Emacs Interface to pbcopy" single ((:commit . "338f7245746b5de1bb96c5cc2b32bfd9b5d83272") (:authors ("Daniel Nelson")) (:maintainer "Daniel Nelson") (:keywords "mac" "osx" "pbcopy") (:url . "https://github.com/jkp/pbcopy.el"))])
+ (pc-bufsw . [(20201011 1918) nil "PC style quick buffer switcher" single ((:commit . "a7295e4813d636d5a20605d134acd42e4e4fe8fa") (:authors ("Igor Bukanov" . "igor@mir2.org")) (:maintainer "Igor Bukanov" . "igor@mir2.org") (:keywords "buffer") (:url . "https://github.com/ibukanov/pc-bufsw"))])
+ (pcache . [(20201226 634) ((emacs (25 1))) "persistent caching for Emacs." single ((:commit . "893d2a637423bae2cc5e72c559e3a9d1518797c9") (:authors ("Yann Hodique" . "yann.hodique@gmail.com")) (:maintainer "Yann Hodique" . "yann.hodique@gmail.com") (:keywords "extensions"))])
+ (pcap-mode . [(20161025 1448) ((emacs (24 3))) "Major mode for working with PCAP files" single ((:commit . "52780669af0ade136f84d73f21b4dbb7ab655416") (:authors ("Aaron Conole" . "aconole@bytheb.org")) (:maintainer "Aaron Conole" . "aconole@bytheb.org") (:keywords "pcap" "packets" "tcpdump" "wireshark" "tshark"))])
+ (pcmpl-args . [(20220131 2316) ((emacs (25 1))) "Enhanced shell command completion" single ((:commit . "94a19b693a226aa11b15627e01f9f4c9af752bab") (:authors ("Jonathan Waltman" . "jonathan.waltman@gmail.com")) (:maintainer "Jonathan Waltman" . "jonathan.waltman@gmail.com") (:keywords "abbrev" "completion" "convenience" "processes" "terminals" "unix") (:url . "https://github.com/JonWaltman/pcmpl-args.el"))])
+ (pcmpl-git . [(20170121 59) nil "pcomplete for git" tar ((:commit . "9472ac70baeda025ef7becd1cf141d72aec93f32") (:authors ("Leo Liu" . "sdl.web@gmail.com")) (:maintainer "Leo Liu" . "sdl.web@gmail.com") (:keywords "tools"))])
+ (pcmpl-homebrew . [(20200911 742) nil "pcomplete for homebrew" single ((:commit . "a2044042dd498abad1dc06162a8ee0d70314ca40") (:authors ("zwild" . "judezhao@outlook.com")) (:maintainer "zwild" . "judezhao@outlook.com") (:keywords "pcomplete" "homebrew" "tools" "cask" "services"))])
+ (pcmpl-pip . [(20181229 1420) ((s (1 12 0)) (f (0 19 0)) (seq (2 15))) "pcomplete for pip" single ((:commit . "bc79228674ad5c1bc458c90dd8839790fb0a09e8") (:authors ("zwild" . "judezhao@outlook.com")) (:maintainer "zwild" . "judezhao@outlook.com") (:keywords "pcomplete" "pip" "python" "tools"))])
+ (pcomplete-extension . [(20190928 519) ((emacs (24)) (cl-lib (0 5))) "additional completion for pcomplete" single ((:commit . "bc5eb204fee659e0980056009409b44bc7655716") (:authors ("Thierry Volpiatto" . "thierry.volpiatto@gmail.com")) (:maintainer "Thierry Volpiatto" . "thierry.volpiatto@gmail.com") (:url . "https://github.com/thierryvolpiatto/pcomplete-extension"))])
+ (pcre2el . [(20161120 2103) ((emacs (24)) (cl-lib (0 3))) "regexp syntax converter" single ((:commit . "0b5b2a2c173aab3fd14aac6cf5e90ad3bf58fa7d") (:authors ("joddie <jonxfield at gmail.com>")) (:maintainer "joddie <jonxfield at gmail.com>") (:url . "https://github.com/joddie/pcre2el"))])
+ (pcsv . [(20150220 1131) nil "Parser of csv" single ((:commit . "798e0933f8d0818beb17aebf3b1056bbf74e03d0") (:authors ("Masahiro Hayashi" . "mhayashi1120@gmail.com")) (:maintainer "Masahiro Hayashi" . "mhayashi1120@gmail.com") (:keywords "data") (:url . "https://github.com/mhayashi1120/Emacs-pcsv/raw/master/pcsv.el"))])
+ (pdb-capf . [(20200419 1237) ((emacs (25 1))) "Completion-at-point function for python debugger" single ((:commit . "2f4099aa1330f87df4e9cd526de057ee9b71de6c") (:authors ("Andrii Kolomoiets" . "andreyk.mad@gmail.com")) (:maintainer "Andrii Kolomoiets" . "andreyk.mad@gmail.com") (:keywords "languages" "abbrev" "convenience") (:url . "https://github.com/muffinmad/emacs-pdb-capf"))])
+ (pdb-mode . [(20150128 1751) nil "Major mode for editing Protein Data Bank files" single ((:commit . "855fb18ebb73b5df30c8d7677c2bcd0f361b138a") (:authors (nil . "charles.bond@uwa.edu.au")) (:maintainer nil . "aix.bing@gmail.com") (:keywords "data" "pdb") (:url . "http://bondxray.org/software/pdb-mode/"))])
+ (pdf-tools . [(20220426 2203) ((emacs (24 3)) (nadvice (0 3)) (tablist (1 0)) (let-alist (1 0 4))) "Support library for PDF documents" tar ((:commit . "3ae9ba9ab9aaa03d1193667cb025a786bef9fe9a") (:authors ("Andreas Politz" . "mail@andreas-politz.de")) (:maintainer "Vedang Manerikar" . "vedang.manerikar@gmail.com") (:keywords "files" "multimedia") (:url . "http://github.com/vedang/pdf-tools/"))])
+ (pdf-view-restore . [(20190904 1708) ((pdf-tools (0 90)) (emacs (26 0))) "Support for opening last known pdf position in pdfview mode" single ((:commit . "5a1947c01a3edecc9e0fe7629041a2f53e0610c9") (:authors ("Kevin Kim" . "kevinkim1991@gmail.com")) (:maintainer "Kevin Kim" . "kevinkim1991@gmail.com") (:keywords "files" "convenience") (:url . "https://github.com/007kevin/pdf-view-restore"))])
+ (pdfgrep . [(20210203 1730) ((emacs (24 4))) "run `pdfgrep' and display the results." single ((:commit . "a4ca0a1e6521de93f28bb6736a5344b4974d144c") (:authors ("Jérémy Compostella" . "jeremy.compostella@gmail.com")) (:maintainer "Jérémy Compostella" . "jeremy.compostella@gmail.com") (:keywords "extensions" "mail" "pdf" "grep") (:url . "https://github.com/jeremy-compostella/pdfgrep"))])
+ (peacock-theme . [(20170808 1320) ((emacs (24 0))) "an Emacs 24 theme based on Peacock (tmTheme)" single ((:commit . "9e46fbfb562b6e26c6e3d6d618b044b3694da4c8") (:authors ("Jason Milkins")) (:maintainer "Jason Milkins") (:url . "https://github.com/emacsfodder/tmtheme-to-deftheme"))])
+ (peek-mode . [(20130620 1946) ((elnode (0 9 8 1))) "Serve buffers live over HTTP with elnode backend" tar ((:commit . "55a7dd011375330c7d57322257a5167516702c71") (:authors ("Erik Iverson" . "erik@sigmafield.org")) (:maintainer "Erik Iverson" . "erik@sigmafield.org") (:url . "https://github.com/erikriverson/peek-mode"))])
+ (peep-dired . [(20160321 2237) nil "Peep at files in another window from dired buffers" single ((:commit . "29f6e7058f635b0084880a1f890a6c92501e8c29") (:authors ("Adam Sokolnicki" . "adam.sokolnicki@gmail.com")) (:maintainer "Adam Sokolnicki" . "adam.sokolnicki@gmail.com") (:keywords "files" "convenience"))])
+ (peertube . [(20210101 1007) ((emacs (25 1)) (transmission (0 12 1))) "Query and download PeerTube videos" single ((:commit . "bb529db154596e86327829edbd7144b67cf72255") (:authors ("yoctocell" . "public@yoctocell.xyz")) (:maintainer "yoctocell" . "public@yoctocell.xyz") (:keywords "peertube" "multimedia") (:url . "https://git.sr.ht/~yoctocell/peertube"))])
+ (pelican-mode . [(20190124 2336) ((emacs (25))) "Minor mode for editing Pelican sites" single ((:commit . "65d7caf5d926599a5007eb7bc279215908aa5252") (:authors ("Joe Wreschnig" . "joe.wreschnig@gmail.com")) (:maintainer "Joe Wreschnig" . "joe.wreschnig@gmail.com") (:keywords "convenience" "editing") (:url . "https://git.korewanetadesu.com/pelican-mode.git"))])
+ (pepita . [(20200228 2257) ((emacs (25)) (csv (2 1))) "Run Splunk search commands, export results to CSV/HTML/JSON" single ((:commit . "c72c4a6f1e47ed5fe5103e0eaadad5a76deeec30") (:authors ("Sebastian Monia" . "smonia@outlook.com")) (:maintainer "Sebastian Monia" . "smonia@outlook.com") (:keywords "tools" "convenience" "matching") (:url . "https://github.com/sebasmonia/pepita.git"))])
+ (perfect-margin . [(20220426 1701) ((emacs (24 0)) (cl-lib (0 5))) "auto center windows, work with minimap and/or linum-mode" single ((:commit . "d5cb5f075264ff2e625099aebca3151f4f35019a") (:authors ("Randall Wang" . "randall.wjz@gmail.com")) (:maintainer "Randall Wang" . "randall.wjz@gmail.com") (:keywords "convenience" "frames") (:url . "https://github.com/mpwang/perfect-margin"))])
+ (perlbrew . [(20161109 709) nil "A perlbrew wrapper for Emacs" single ((:commit . "3a3406c3307c92aa30f9400d430925c434a3b6f0") (:authors ("Kentaro Kuribayashi" . "kentarok@gmail.com")) (:maintainer "Kentaro Kuribayashi" . "kentarok@gmail.com") (:keywords "emacs" "perl"))])
+ (persistent-overlays . [(20161128 700) nil "Minor mode to store selected overlays to be loaded later" tar ((:commit . "f563c8b966edc78c9d806661c4eb80e4781c4eab") (:authors ("Michael Neilly" . "mneilly@yahoo.com")) (:maintainer "Michael Neilly" . "mneilly@yahoo.com") (:keywords "overlays" "persistent") (:url . "https://github.com/mneilly/Emacs-Persistent-Overlays"))])
+ (persistent-scratch . [(20220218 810) ((emacs (24))) "Preserve the scratch buffer across Emacs sessions" single ((:commit . "4e159967801b75d07303221c4e5a2b89039c6a11") (:authors ("Fanael Linithien" . "fanael4@gmail.com")) (:maintainer "Fanael Linithien" . "fanael4@gmail.com") (:url . "https://github.com/Fanael/persistent-scratch"))])
+ (persistent-soft . [(20150223 1853) ((pcache (0 3 1)) (list-utils (0 4 2))) "Persistent storage, returning nil on failure" single ((:commit . "a1e0ddf2a12a6f18cab565dee250f070384cbe02") (:authors ("Roland Walker" . "walker@pobox.com")) (:maintainer "Roland Walker" . "walker@pobox.com") (:keywords "data" "extensions") (:url . "http://github.com/rolandwalker/persistent-soft"))])
+ (persp-fr . [(20191108 754) ((emacs (25 1)) (persp-mode (2 9 6)) (dash (2 13 0))) "In persp-mode, show perspective list in the GUI window title" single ((:commit . "1adbb6a9f9a4db580a9b7ed8b4091738e01345e6") (:authors ("Francesc Rocher" . "francesc.rocher@gmail.com")) (:maintainer "Francesc Rocher" . "francesc.rocher@gmail.com") (:keywords "perspectives" "workspace" "windows" "convenience") (:url . "http://github.com/rocher/persp-fr"))])
+ (persp-mode . [(20220206 1742) ((emacs (24 3))) "windows/buffers sets shared among frames + save/load." single ((:commit . "7a594a3d8f1c4ba9234dcd831a589e87f3f4ae86") (:authors ("Constantin Kulikov (Bad_ptr)" . "zxnotdead@gmail.com")) (:maintainer "Constantin Kulikov (Bad_ptr)" . "zxnotdead@gmail.com") (:keywords "perspectives" "session" "workspace" "persistence" "windows" "buffers" "convenience") (:url . "https://github.com/Bad-ptr/persp-mode.el"))])
+ (persp-mode-project-bridge . [(20220115 602) ((emacs (27 1)) (persp-mode (2 9))) "Integration of persp-mode + project.el" single ((:commit . "cacc22942ca5dffdfc3d16cf88576ce0bd9e3a68") (:authors ("Constantin Kulikov (Bad_ptr)" . "zxnotdead@gmail.com") ("Siavash Askari Nasr" . "siavash.askari.nasr@gmail.com")) (:maintainer "Siavash Askari Nasr" . "siavash.askari.nasr@gmail.com") (:keywords "vc" "persp-mode" "perspective" "project" "project.el") (:url . "https://github.com/CIAvash/persp-mode-project-bridge"))])
+ (persp-mode-projectile-bridge . [(20170315 1120) ((persp-mode (2 9)) (projectile (0 13 0)) (cl-lib (0 5))) "persp-mode + projectile integration." single ((:commit . "f6453cd7b8b4352c06e771706f2c5b7e2cdff1ce") (:authors ("Constantin Kulikov (Bad_ptr)" . "zxnotdead@gmail.com")) (:maintainer "Constantin Kulikov (Bad_ptr)" . "zxnotdead@gmail.com") (:keywords "persp-mode" "projectile") (:url . "https://github.com/Bad-ptr/persp-mode-projectile-bridge.el"))])
+ (persp-projectile . [(20210618 708) ((perspective (1 9)) (projectile (2 4)) (cl-lib (0 3))) "Perspective integration with Projectile" single ((:commit . "4e374d7650c7e041df5af5ac280a44d4a4ec705a") (:authors ("Daniel Wu")) (:maintainer "Daniel Wu") (:keywords "project" "convenience"))])
+ (perspective . [(20220420 1550) ((emacs (24 4)) (cl-lib (0 5))) "switch between named \"perspectives\" of the editor" single ((:commit . "4e38680793585a907ae46b148697030c2b552a00") (:authors ("Natalie Weizenbaum" . "nex342@gmail.com")) (:maintainer "Natalie Weizenbaum" . "nex342@gmail.com") (:keywords "workspace" "convenience" "frames") (:url . "http://github.com/nex3/perspective-el"))])
+ (perspective-exwm . [(20220125 1939) ((emacs (27 1)) (burly (0 2 -1)) (exwm (0 26)) (perspective (2 17))) "Better integration for perspective.el and EXWM" single ((:commit . "8afdbf894a888854ce9dfbe0ad2a5dc41f75ecb8") (:authors ("Korytov Pavel" . "thexcloud@gmail.com")) (:maintainer "Korytov Pavel" . "thexcloud@gmail.com") (:url . "https://github.com/SqrtMinusOne/perspective-exwm.el"))])
+ (perspeen . [(20171203 1021) ((emacs (25 0)) (powerline (2 4))) "An package for multi-workspace" tar ((:commit . "edb70c530bda50ff3d1756e32a703d5fef5e5480") (:authors ("Peng Li" . "seudut@gmail.com")) (:maintainer "Peng Li" . "seudut@gmail.com") (:keywords "lisp") (:url . "https://github.com/seudut/perspeen"))])
+ (pest-mode . [(20200321 504) ((emacs (26 3))) "Major mode for editing Pest files" single ((:commit . "43447a2c70f98edd1139005e32f437d3f142442b") (:authors ("ksqsf" . "i@ksqsf.moe")) (:maintainer "ksqsf" . "i@ksqsf.moe") (:keywords "languages") (:url . "https://github.com/ksqsf/pest-mode"))])
+ (pfuture . [(20220425 1242) ((emacs (25 2))) "a simple wrapper around asynchronous processes" single ((:commit . "f9e67bd7edbd5b4e033efd82c0acc4a85ff860a8") (:authors ("Alexander Miller" . "alexanderm@web.de")) (:maintainer "Alexander Miller" . "alexanderm@web.de") (:url . "https://github.com/Alexander-Miller/pfuture"))])
+ (pg . [(20130731 2142) nil "Emacs Lisp interface to the PostgreSQL RDBMS" single ((:commit . "4f6516ec3946d95dcef49abb6703cc89ecb5183d") (:authors ("Eric Marsden" . "emarsden@laas.fr")) (:maintainer "Helmut Eller" . "heller@common-lisp.net") (:keywords "data" "comm" "database" "postgresql"))])
+ (pgdevenv . [(20150105 2236) nil "Manage your PostgreSQL development envs" tar ((:commit . "7f1d5bc734750aca98cf67a9491cdbd5615fd132") (:authors ("Dimitri Fontaine" . "dim@tapoueh.org")) (:maintainer "Dimitri Fontaine" . "dim@tapoueh.org") (:keywords "emacs" "postgresql" "development" "environment" "shell" "debug" "gdb"))])
+ (ph . [(20161029 1522) ((emacs (24 3))) "A global minor mode for managing multiple projects." tar ((:commit . "ed80dad9211583ed0db633448b3624c99b7fac23") (:authors ("Alexander Gromnitsky" . "alexander.gromnitsky@gmail.com")) (:maintainer "Alexander Gromnitsky" . "alexander.gromnitsky@gmail.com"))])
+ (phabricator . [(20160510 1425) ((emacs (24 4)) (dash (1 0)) (projectile (0 13 0)) (s (1 10 0)) (f (0 17 2))) "Phabricator/Arcanist helpers for Emacs." single ((:commit . "d09d6f059aea92d3b11c68664a5e80c901182ab8") (:authors ("Andrew Tulloch")) (:maintainer "Andrew Tulloch") (:keywords "phabricator" "arcanist" "diffusion") (:url . "https://github.com/ajtulloch/phabricator.el"))])
+ (phan . [(20200805 356) ((emacs (24)) (composer (0 0 8)) (f (0 17))) "Utility functions for Phan (PHP static analizer)" single ((:commit . "b7d523630bb072c4dbcfa9995dc734b25b72a69f") (:authors ("USAMI Kenta" . "tadsan@pixiv.com")) (:maintainer "USAMI Kenta" . "tadsan@pixiv.com") (:keywords "tools" "php") (:url . "https://github.com/emacs-php/phan.el"))])
+ (phi-autopair . [(20210306 424) ((paredit (20))) "another simple-minded autopair implementation" single ((:commit . "6a67c37d31a3ff9261fc9f812547a0c86721fc90") (:authors ("zk_phi")) (:maintainer "zk_phi") (:url . "http://zk-phi.gitub.io/"))])
+ (phi-grep . [(20210306 425) ((cl-lib (0 1)) (emacs (26 1))) "Interactively-editable recursive grep implementation in elisp" single ((:commit . "7e2804c7ab4e875c7511917692c4b192662aa1ae") (:authors ("zk_phi")) (:maintainer "zk_phi") (:url . "http://github.com/zk-phi/phi-grep"))])
+ (phi-rectangle . [(20200911 204) nil "another rectangle-mark command (rewrite of rect-mark)" single ((:commit . "43ee8aea9998b34a9fdb28d7da2e4f75e4154030") (:authors ("zk_phi")) (:maintainer "zk_phi") (:url . "http://zk-phi.github.io/"))])
+ (phi-search . [(20200510 906) nil "another incremental search & replace, compatible with \"multiple-cursors\"" tar ((:commit . "c34f5800968922d1f9e7b10092b8705d6640ad18") (:authors ("zk_phi")) (:maintainer "zk_phi") (:url . "http://hins11.yu-yake.com/"))])
+ (phi-search-dired . [(20200816 1542) ((phi-search (2 2 0))) "interactive filtering for dired powered by phi-search" single ((:commit . "f014a9fb0b6a94af2df0e22f91ef79ce6996afd7") (:authors ("zk_phi")) (:maintainer "zk_phi") (:url . "http://hins11.yu-yake.com/"))])
+ (phi-search-mc . [(20160324 1503) ((phi-search (2 0 0)) (multiple-cursors (1 2 1))) "multiple-cursors extension for phi-search" single ((:commit . "7aa671910f766437089aec26c3aa7814222d1356") (:authors ("Akinori MUSHA" . "knu@iDaemons.org")) (:maintainer "Akinori MUSHA" . "knu@iDaemons.org") (:keywords "search" "cursors") (:url . "https://github.com/knu/phi-search-mc.el"))])
+ (phi-search-migemo . [(20170618 921) ((phi-search (2 2 0)) (migemo (1 9 1))) "migemo extension for phi-search" single ((:commit . "308909ebfc8003d16673f97ca9eb26a667b72969") (:authors ("zk_phi")) (:maintainer "zk_phi") (:url . "http://hins11.yu-yake.com/"))])
+ (phoenix-dark-mono-theme . [(20170729 1406) nil "Monochromatic version of the Phoenix theme" single ((:commit . "a54f515d162148bcb38676980bc2316adb3d7b8b") (:authors ("J Irving" . "j@lollyshouse.ca")) (:maintainer "J Irving" . "j@lollyshouse.ca") (:url . "http://github.com/j0ni/phoenix-dark-mono"))])
+ (phoenix-dark-pink-theme . [(20190821 48) nil "Originally a port of the Sublime Text 2 theme" single ((:commit . "ddd98a45775be105984ec598384e68df3d3e8046") (:authors ("J Irving" . "j@lollyshouse.ca")) (:maintainer "J Irving" . "j@lollyshouse.ca") (:url . "http://github.com/j0ni/phoenix-dark-pink"))])
+ (php-boris . [(20130527 821) nil "Run boris php REPL" single ((:commit . "f2faebf610c917f7091f7ec0cd97645629c4f819") (:authors ("Tom Regner")) (:maintainer "Tom Regner" . "tom@goochesa.de") (:keywords "php" "commint" "repl" "boris"))])
+ (php-boris-minor-mode . [(20140209 1835) ((php-boris (0 0 1)) (highlight (0))) "a minor mode to evaluate PHP code in the Boris repl" single ((:commit . "c70e176dd6545f2d42ca3427e87b469635616d8a") (:authors ("steckerhalter")) (:maintainer "steckerhalter") (:keywords "php" "repl" "eval") (:url . "https://github.com/steckerhalter/php-boris-minor-mode"))])
+ (php-cs-fixer . [(20210923 718) ((cl-lib (0 5))) "php-cs-fixer wrapper." single ((:commit . "7e12a1af5d65cd8a801eeb5564c6268a4e190c0c") (:authors ("Philippe Ivaldi for OVYA")) (:maintainer "Philippe Ivaldi for OVYA") (:keywords "languages" "php") (:url . "https://github.com/OVYA/php-cs-fixer"))])
+ (php-eldoc . [(20140202 1941) nil "eldoc backend for php" tar ((:commit . "df05064146b884d9081e10657e32dc480f070cfe") (:authors ("sabof")) (:maintainer "sabof") (:url . "https://github.com/sabof/php-eldoc"))])
+ (php-mode . [(20220120 1959) ((emacs (25 2))) "Major mode for editing PHP code" tar ((:commit . "4503672471b8fdaaea6c454344817a119c87fcc6") (:authors ("Eric James Michael Ritz")) (:maintainer "USAMI Kenta" . "tadsan@zonu.me") (:keywords "languages" "php") (:url . "https://github.com/emacs-php/php-mode"))])
+ (php-quickhelp . [(20210819 2025) ((emacs (25 1))) "Quickhelp at point for php" single ((:commit . "d5e11b7a6bad64550521e8822139a33218b8c9bb") (:authors ("Vincenzo Pupillo")) (:maintainer "Vincenzo Pupillo") (:url . "https://github.com/vpxyz/php-quickhelp"))])
+ (php-refactor-mode . [(20171124 635) nil "Minor mode to quickly and safely perform common refactorings" single ((:commit . "7a794b0618df2882b1bd586fdd698dba0bc5130d") (:authors ("Matthew M. Keeler" . "keelerm84@gmail.com")) (:maintainer "Matthew M. Keeler" . "keelerm84@gmail.com") (:keywords "php" "refactor") (:url . "https://github.com/keelerm84/php-refactor-mode.el"))])
+ (php-runtime . [(20181212 1825) ((emacs (25)) (cl-lib (0 5)) (f (0 20)) (s (1 7))) "Language binding bridge to PHP" single ((:commit . "017e0e70f07d6b25e37d5c5f4d271a914b677631") (:authors ("USAMI Kenta" . "tadsan@zonu.me")) (:maintainer "USAMI Kenta" . "tadsan@zonu.me") (:keywords "processes" "php") (:url . "https://github.com/emacs-php/php-runtime.el"))])
+ (php-scratch . [(20210706 459) ((emacs (24 3)) (s (1 11 0)) (php-mode (1 17 0))) "A scratch buffer to interactively evaluate php code" single ((:commit . "b6bfd279da8a8ac7fc30459485956f3fd5d02573") (:authors ("Tijs Mallaerts" . "tijs.mallaerts@gmail.com")) (:maintainer "Tijs Mallaerts" . "tijs.mallaerts@gmail.com") (:url . "https://github.com/mallt/php-scratch"))])
+ (phpactor . [(20220310 1511) ((emacs (25 1)) (f (0 17)) (php-runtime (0 2)) (composer (0 2 0)) (async (1 9 3))) "Interface to Phpactor" tar ((:commit . "34195f1533209e2ffd0f898a69c7db2bffd1eabe") (:authors ("USAMI Kenta" . "tadsan@zonu.me") ("Mikael Kermorgant" . "mikael@kgtech.fi")) (:maintainer "USAMI Kenta" . "tadsan@zonu.me") (:keywords "tools" "php") (:url . "https://github.com/emacs-php/phpactor.el"))])
+ (phpstan . [(20210714 1805) ((emacs (24 3)) (php-mode (1 22 3))) "Interface to PHPStan" single ((:commit . "0869b152f82a76138daa53e953285936b9d558bd") (:authors ("USAMI Kenta" . "tadsan@zonu.me")) (:maintainer "USAMI Kenta" . "tadsan@zonu.me") (:keywords "tools" "php") (:url . "https://github.com/emacs-php/phpstan.el"))])
+ (phpt-mode . [(20190512 1809) ((emacs (25)) (polymode (0 1 5)) (php-mode (1 21 2))) "Major mode for editing PHPT test code" single ((:commit . "deb386f1a81003074c476f15e1975d445ff6df01") (:authors ("USAMI Kenta" . "tadsan@zonu.me")) (:maintainer "USAMI Kenta" . "tadsan@zonu.me") (:keywords "languages" "php") (:url . "https://github.com/emacs-php/phpt-mode"))])
+ (phpunit . [(20180829 1438) ((s (1 12 0)) (f (0 19 0)) (pkg-info (0 6)) (cl-lib (0 5)) (emacs (24 3))) "Launch PHP unit tests using phpunit" tar ((:commit . "fe6bc91c3bd8b329c6d26ad883a025f06b5121ee") (:authors ("Nicolas Lamirault" . "nicolas.lamirault@gmail.com") ("Eric Hansen" . "hansen.c.eric@gmail.com")) (:maintainer "Nicolas Lamirault" . "nicolas.lamirault@gmail.com") (:keywords "tools" "php" "tests" "phpunit") (:url . "https://github.com/nlamirault/phpunit.el"))])
+ (pianobar . [(20201002 1756) nil "thin wrapper for Pianobar, a Pandora Radio client" single ((:commit . "d708417608df4f09ee565fddaad03dfe181829a8") (:authors ("Aaron Griffith" . "aargri@gmail.com")) (:maintainer "Aaron Griffith" . "aargri@gmail.com") (:url . "http://github.com/agrif/pianobar.el"))])
+ (pickle . [(20190923 354) ((emacs (25 1)) (cl-lib (0 6 1))) "Major mode for editing cucumber gherkin files." single ((:commit . "3a0a717f2a24827667f34bc53830a3b81cd57460") (:authors ("Matthew Carter" . "m@ahungry.com")) (:maintainer "Matthew Carter" . "m@ahungry.com") (:keywords "ahungry" "languages" "cucumber" "gherkin") (:url . "https://github.com/ahungry/pickle-mode"))])
+ (picpocket . [(20210806 1135) ((emacs (25 1))) "Image viewer" single ((:commit . "7e30e96c26b1ff0d374612534c3e09d309426252") (:authors ("Johan Claesson" . "johanwclaesson@gmail.com")) (:maintainer "Johan Claesson" . "johanwclaesson@gmail.com") (:keywords "multimedia") (:url . "https://github.com/johanclaesson/picpocket"))])
+ (pig-mode . [(20180520 1400) nil "Major mode for Pig files" single ((:commit . "4c6c6e1b1bb719d8adc6c47cc24665f6fe558959") (:maintainer "David A. Shamma"))])
+ (pig-snippets . [(20130913 624) ((yasnippet (0 8 0))) "Snippets for pig-mode" tar ((:commit . "4c6c6e1b1bb719d8adc6c47cc24665f6fe558959") (:authors ("Peter Vasil" . "mail@petervasil.net")) (:maintainer "Peter Vasil" . "mail@petervasil.net") (:keywords "snippets") (:url . "https://github.com/motus/pig-mode"))])
+ (pikchr-mode . [(20210324 2125) ((emacs (27 1))) "A major mode for the pikchr diagram markup language" single ((:commit . "5d424c5c97ac854cc44c369e654e4f906fcae3c8") (:authors ("Johann Klähn" . "johann@jklaehn.de")) (:maintainer "Johann Klähn" . "johann@jklaehn.de") (:keywords "languages") (:url . "https://github.com/kljohann/pikchr-mode"))])
+ (pillar . [(20141112 1811) ((makey (0 3))) "Major mode for editing Pillar files" tar ((:commit . "13a7f676544cc66005ccd8e6fc1c25e4ccd6f909") (:authors ("Damien Cassou" . "damien.cassou@gmail.com")) (:maintainer "Damien Cassou" . "damien.cassou@gmail.com") (:keywords "markup" "major-mode") (:url . "http://github.com/DamienCassou/pillar-mode"))])
+ (pinboard . [(20200630 1544) ((emacs (25 1)) (cl-lib (0 5))) "A pinboard.in client" single ((:commit . "d426f9d2ebec5f907c8a89d6b38ccbcb13750d4f") (:authors ("Dave Pearson" . "davep@davep.org")) (:maintainer "Dave Pearson" . "davep@davep.org") (:keywords "hypermedia" "bookmarking" "reading" "pinboard") (:url . "https://github.com/davep/pinboard.el"))])
+ (pinboard-api . [(20140324 1148) nil "Rudimentary http://pinboard.in integration" single ((:commit . "b7b5214d0c35178f8dca08cf22d6ef3c21f0fce4") (:authors ("Danie Roux" . "danie@danieroux.com")) (:maintainer "Danie Roux" . "danie@danieroux.com") (:keywords "pinboard" "www") (:url . "https://github.com/danieroux/pinboard-api-el"))])
+ (pinboard-popular . [(20180511 1726) ((loop (1 4))) "Displays links from the pinboard.in popular page." single ((:commit . "c0bc76cd35f8ecf34723c64a702b82eec2751318") (:keywords "pinboard") (:url . "https://github.com/asimpson/pinboard-popular"))])
+ (pine-script-mode . [(20210629 1257) ((emacs (24))) "Trading View Pine Script major mode" single ((:commit . "d8ce5dc595a053e80debf6c1e330995c739a8b05") (:authors ("Eric Crosson" . "eric.s.crosson@utexas.edu")) (:maintainer "Eric Crosson" . "eric.s.crosson@utexas.edu") (:keywords "extensions") (:url . "https://github.com/ericcrosson/pine-script-mode"))])
+ (pinot . [(20140211 2026) nil "Emacs interface to pinot-search" tar ((:commit . "67fda555a155b22bb2ce44ba618b4bd6fc5f144a") (:authors ("Takafumi Arakaki <aka.tkf at gmail.com>")) (:maintainer "Takafumi Arakaki <aka.tkf at gmail.com>"))])
+ (pinyin . [(20180620 1241) ((cl-lib (0 5)) (emacs (24))) "Convert Hanzi to Pinyin (汉字转拼音)" tar ((:commit . "e5508e5aa1ad4cfa05a7f4d299e5a155b288ec4c") (:authors ("Xu Chunyang" . "mail@xuchunyang.me")) (:maintainer "Xu Chunyang" . "mail@xuchunyang.me") (:keywords "extensions") (:url . "https://github.com/xuchunyang/pinyin.el"))])
+ (pinyin-search . [(20160515 358) ((pinyinlib (0 1 0))) "Search Chinese by Pinyin" single ((:commit . "2e877a76851009d41bde66eb33182a03a7f04262") (:authors ("Chunyang Xu" . "xuchunyang56@gmail.com")) (:maintainer "Chunyang Xu" . "xuchunyang56@gmail.com") (:keywords "chinese" "search") (:url . "https://github.com/xuchunyang/pinyin-search.el"))])
+ (pinyinlib . [(20200911 1723) nil "Convert first letter of Pinyin to Simplified/Traditional Chinese characters" single ((:commit . "1772c79b6f319b26b6a394a8dda065be3ea4498d") (:authors ("Junpeng Qiu" . "qjpchmail@gmail.com")) (:maintainer "Junpeng Qiu" . "qjpchmail@gmail.com") (:keywords "extensions"))])
+ (pip-requirements . [(20181027 1629) ((dash (2 8 0))) "A major mode for editing pip requirements files." single ((:commit . "216cd1690f80cc965d4ae47b8753fc185f778ff6") (:authors ("Wilfred Hughes" . "me@wilfred.me.uk")) (:maintainer "Wilfred Hughes" . "me@wilfred.me.uk"))])
+ (pipenv . [(20210127 1444) ((emacs (25 1)) (s (1 12 0)) (pyvenv (1 20))) "A Pipenv porcelain" single ((:commit . "8f50c68d415307a2cbc65cc4df20df18e1776e9b") (:authors ("Paul Walsh" . "paulywalsh@gmail.com")) (:maintainer "Paul Walsh" . "paulywalsh@gmail.com") (:url . "https://github.com/pwalsh/pipenv.el"))])
+ (pippel . [(20220416 1743) ((emacs (25 1)) (s (1 11 0)) (dash (2 12 0))) "Frontend to python package manager pip" tar ((:commit . "cb194952ee150e77601d3233dabdb521b976ee79") (:authors ("Fritz Stelzer" . "brotzeitmacher@gmail.com")) (:maintainer "Arif Er" . "arifer612@protonmail.me") (:url . "https://github.com/arifer612/pippel"))])
+ (pixie-mode . [(20180626 541) ((clojure-mode (3 0 1)) (inf-clojure (1 0 0))) "Major mode for Pixie-lang" single ((:commit . "a40c2632cfbe948852a5cdcfd44e6a65db11834d") (:authors ("John Walker" . "john.lou.walker@gmail.com")) (:maintainer "John Walker" . "john.lou.walker@gmail.com") (:url . "https://github.com/johnwalker/pixie-mode"))])
+ (pixiv-novel-mode . [(20160220 1421) nil "Major mode for pixiv novel" single ((:commit . "0d1ca524d92b91f20a7105402a773bc21779b434") (:authors ("USAMI Kenta" . "tadsan@zonu.me")) (:maintainer "USAMI Kenta" . "tadsan@zonu.me") (:keywords "novel" "pixiv"))])
+ (pkg-info . [(20150517 1143) ((epl (0 8))) "Information about packages" single ((:commit . "76ba7415480687d05a4353b27fea2ae02b8d9d61") (:authors ("Sebastian Wiesner" . "swiesner@lunaryorn.com")) (:maintainer "Sebastian Wiesner" . "swiesner@lunaryorn.com") (:keywords "convenience") (:url . "https://github.com/lunaryorn/pkg-info.el"))])
+ (pkg-overview . [(20210802 1509) ((emacs (24 3))) "Make org documentation from elisp source file" single ((:commit . "9b2e416758a6c107bb8cc670ec4d2627f82d5590") (:authors ("Boruch Baum" . "boruch_baum@gmx.com")) (:maintainer "Boruch Baum" . "boruch_baum@gmx.com") (:keywords "docs" "help" "lisp" "maint" "outlines" "tools") (:url . "https://github.com/Boruch-Baum/emacs-pkg-overview"))])
+ (pkgbuild-mode . [(20220428 556) ((emacs (26 1))) "Interface to the ArchLinux package manager" single ((:commit . "8faee70e4640bd6ec1857651ec64e139e4dc2833") (:authors ("Juergen Hoetzel" . "juergen@hoetzel.info")) (:maintainer "Juergen Hoetzel" . "juergen@hoetzel.info") (:keywords "languages") (:url . "https://github.com/juergenhoetzel/pkgbuild-mode"))])
+ (plain-org-wiki . [(20201217 1027) ((emacs (24 3)) (ivy (0 12 0))) "Simple jump-to-org-files in a directory package" single ((:commit . "faeeb54ca808bbf0f4380a938e75805b7a78dbf7") (:authors ("Oleh Krehel" . "ohwoeowho@gmail.com")) (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com") (:keywords "convenience") (:url . "https://github.com/abo-abo/plain-org-wiki"))])
+ (plain-theme . [(20171124 410) ((emacs (24))) "Plain theme without syntax highlighting" single ((:commit . "48b37b9b19d8f1e0accbf930f30b5346cf7959fe"))])
+ (plan9-theme . [(20180804 1441) nil "A color theme for Emacs based on Plan9" single ((:commit . "c2da2fcb241e9800d931a1ff19ecd9fd84d30382") (:authors ("John Louis Del Rosario" . "john2x@gmail.com")) (:maintainer "John Louis Del Rosario" . "john2x@gmail.com") (:url . "https://github.com/john2x/plan9-theme.el"))])
+ (planemo-mode . [(20201216 1122) ((emacs (27 1)) (dash (2 17 0))) "Minor mode for editing Galaxy XML files" single ((:commit . "9a981f79a2727f87689ae5a07368c41d35902a67") (:authors ("Mehmet Tekman")) (:maintainer "Mehmet Tekman") (:keywords "outlines") (:url . "https://gitlab.com/mtekman/planemo-mode.el"))])
+ (planet-theme . [(20161031 217) ((emacs (24))) "A dark theme inspired by Gmail's 'Planets' theme of yore" single ((:commit . "b0a310ff36565fe22224c407cf59569986698a32") (:authors ("Charlie McMackin" . "charlie.mac@gmail.com")) (:maintainer "Charlie McMackin" . "charlie.mac@gmail.com") (:keywords "themes") (:url . "https://github.com/cmack/emacs-planet-theme"))])
+ (plantuml-mode . [(20191102 2056) ((dash (2 0 0)) (emacs (25 0))) "Major mode for PlantUML" single ((:commit . "ea45a13707abd2a70df183f1aec6447197fc9ccc") (:authors ("Zhang Weize (zwz)")) (:maintainer "Carlo Sciolla (skuro)") (:keywords "uml" "plantuml" "ascii"))])
+ (plaster . [(20180127 2050) ((emacs (24 3))) "Pasting to a plaster host with buffers." single ((:commit . "4d18c8bc3322668ac1695e25c556bda6771af1d5") (:authors ("Nicolas Hafner" . "shinmera@tymoon.eu")) (:maintainer "Nicolas Hafner" . "shinmera@tymoon.eu") (:keywords "convenience" "paste service") (:url . "http://github.com/shirakumo/plaster/"))])
+ (platformio-mode . [(20210511 957) ((emacs (25 1)) (async (1 9 0)) (projectile (0 13 0))) "PlatformIO integration" single ((:commit . "f4fd8932995a8aed80eab14e54232010c2889012") (:authors ("Zach Massia" . "zmassia@gmail.com") ("Dante Catalfamo" . "dante@lambda.cx")) (:maintainer "Zach Massia" . "zmassia@gmail.com") (:url . "https://github.com/zachmassia/platformio-mode"))])
+ (play-crystal . [(20180114 1024) ((emacs (24 4)) (dash (2 12 0)) (request (0 2 0))) "https://play.crystal-lang.org integration." single ((:commit . "0b4810a9025213bd11dbcbfd38b3ca928829e0a5") (:authors ("Vitalii Elenhaupt")) (:maintainer "Vitalii Elenhaupt") (:keywords "convenience") (:url . "https://github.com/veelenga/play-crystal.el"))])
+ (play-routes-mode . [(20170426 733) nil "Play Framework Routes File Support" single ((:commit . "22d7b87e0eaf0330f2b2283872f8dc08a3258771") (:authors ("M.Riehl <max@flatmap.ninja>, P.Haun" . "bomgar85@googlemail.com")) (:maintainer "M.Riehl <max@flatmap.ninja>, P.Haun" . "bomgar85@googlemail.com") (:keywords "play" "scala") (:url . "https://github.com/brocode/play-routes-mode/"))])
+ (playerctl . [(20211014 856) nil "Control your music player (e.g. Spotify) with playerctl" single ((:commit . "4c3a6132616fd28f902590bf6e63332e6055492b") (:authors ("Thomas Luquet" . "thomas@luquet.net")) (:maintainer "Thomas Luquet" . "thomas@luquet.net") (:keywords "multimedia" "playerctl" "music") (:url . "https://github.com/thomasluquet/playerctl.el"))])
+ (playground . [(20200812 1336) ((emacs (24 4))) "Manage sandboxes for alternative configurations" single ((:commit . "77d2faab0bc3f6e1f2c65c66644c52167304610d") (:authors ("Akira Komamura" . "akira.komamura@gmail.com")) (:maintainer "Akira Komamura" . "akira.komamura@gmail.com") (:keywords "maint") (:url . "https://github.com/akirak/emacs-playground"))])
+ (playonline . [(20200317 642) ((emacs (24 4)) (dash (2 1)) (request (0 2))) "Play code with online playgrounds" single ((:commit . "c75da1fdc1dfbd5d9aa274dc4e90ff631ea08e70") (:authors ("Gong Qijian" . "gongqijian@gmail.com")) (:maintainer "Gong Qijian" . "gongqijian@gmail.com") (:keywords "tools") (:url . "https://github.com/twlz0ne/playonline.el"))])
+ (plenv . [(20130707 616) nil "A plenv wrapper for Emacs" single ((:commit . "ee937d0f3a1a7ba2d035f45be896d3ed8fefaee2") (:authors ("Kenta Sato" . "karupa@cpan.org")) (:maintainer "Kenta Sato" . "karupa@cpan.org") (:keywords "emacs" "perl"))])
+ (plim-mode . [(20140813 13) nil "Major mode for editing Plim files" single ((:commit . "92e39190286f172567ceb02c80e1df3b81abfa2d") (:authors ("Dong Weiming")) (:maintainer "Dong Weiming") (:keywords "markup" "language") (:url . "http://github.com/dongweiming/plim-mode"))])
+ (plisp-mode . [(20200427 405) nil "Major mode for PicoLisp programming." tar ((:commit . "59e682d77569b04e9fc80af9c4b05e4a997dbcec") (:authors ("Alexis" . "flexibeast@gmail.com")) (:maintainer "Alexis" . "flexibeast@gmail.com") (:keywords "picolisp" "lisp" "programming") (:url . "https://github.com/flexibeast/plisp-mode"))])
+ (plsense . [(20151104 1445) ((auto-complete (1 4 0)) (log4e (0 2 0)) (yaxception (0 2 0))) "provide interface for PlSense that is a development tool for Perl." single ((:commit . "d50f9dccc98f42bdb42f1d1c8142246e03879218") (:authors ("Hiroaki Otsu" . "ootsuhiroaki@gmail.com")) (:maintainer "Hiroaki Otsu" . "ootsuhiroaki@gmail.com") (:keywords "perl" "completion") (:url . "https://github.com/aki2o/emacs-plsense"))])
+ (plsense-direx . [(20140520 2008) ((direx (0 1 -3)) (plsense (0 3 2)) (log4e (0 2 0)) (yaxception (0 3 2))) "Perl Package Explorer" single ((:commit . "8a2f465264c74e04524cc789cdad0190ace43f6c") (:authors ("Hiroaki Otsu" . "ootsuhiroaki@gmail.com")) (:maintainer "Hiroaki Otsu" . "ootsuhiroaki@gmail.com") (:keywords "perl" "convenience") (:url . "https://github.com/aki2o/plsense-direx"))])
+ (plur . [(20160504 924) ((emacs (24 4))) "Easily search and replace multiple variants of a word" single ((:commit . "5bdd3b9a2f0624414bd596e798644713cd1545f0") (:authors ("Chunyang Xu" . "xuchunyang.me@gmail.com")) (:maintainer "Chunyang Xu" . "xuchunyang.me@gmail.com") (:url . "https://github.com/xuchunyang/plur"))])
+ (pmdm . [(20191101 2346) nil "poor man's desktop-mode alternative." single ((:commit . "1f30adce8a23da94b3c2460b7248d5910592d8af") (:authors ("Iñigo Serna" . "inigoserna@gmx.com")) (:maintainer "Iñigo Serna" . "inigoserna@gmx.com") (:url . "https://hg.serna.eu/emacs/pmdm"))])
+ (pnpm-mode . [(20200527 557) ((emacs (24 1))) "Minor mode for working with pnpm projects" single ((:commit . "391207e6505948b0d0cb57b802ee4885e3292c21") (:authors ("Rajasegar Chandran" . "rajasegar.c@gmail.com")) (:maintainer "Rajasegar Chandran" . "rajasegar.c@gmail.com") (:keywords "convenience" "project" "javascript" "node" "npm" "pnpm") (:url . "https://github.com/rajasegar/pnpm-mode"))])
+ (po-mode . [(20200606 1404) nil "major mode for GNU gettext PO files" tar ((:commit . "25eb1bdca30ed25d2e5d51b9feeb28a3faff51ec") (:keywords "i18n" "gettext"))])
+ (pocket-api . [(20180403 109) ((emacs (24 4)) (request (0 2))) "another pocket api" single ((:commit . "3eb9430b9db90bc02e736e433eb86389f7655189") (:authors ("DarkSun" . "lujun9972@gmail.com")) (:maintainer "DarkSun" . "lujun9972@gmail.com") (:keywords "convenience" "pocket") (:url . "https://github.com/lujun9972/pocket-api.el"))])
+ (pocket-lib . [(20190720 1957) ((emacs (25 1)) (request (0 2)) (dash (2 13 0)) (kv (0 0 19)) (s (1 12 0))) "Library for accessing getpocket.com API" single ((:commit . "f794e3e619e1f6cad25bbfd5fe019a7e62820bf4") (:authors ("Adam Porter" . "adam@alphapapa.net")) (:maintainer "Adam Porter" . "adam@alphapapa.net") (:keywords "pocket") (:url . "https://github.com/alphapapa/pocket-lib.el"))])
+ (pocket-mode . [(20171201 1315) ((emacs (24 4)) (pocket-api (0 1))) "Manage your pocket" single ((:commit . "229de7d35b7e5605797591c46aa8200d7efc363c") (:authors ("DarkSun" . "lujun9972@gmail.com")) (:maintainer "DarkSun" . "lujun9972@gmail.com") (:keywords "convenience" "pocket"))])
+ (pocket-reader . [(20210824 658) ((emacs (25 1)) (dash (2 13 0)) (kv (0 0 19)) (pocket-lib (0 1)) (s (1 10)) (ov (1 0 6)) (rainbow-identifiers (0 2 2)) (org-web-tools (0 1)) (ht (2 2))) "Client for Pocket reading list" single ((:commit . "0a177d4a3b4b2532be7f0775e5cc41e6382a45d4") (:authors ("Adam Porter" . "adam@alphapapa.net")) (:maintainer "Adam Porter" . "adam@alphapapa.net") (:keywords "pocket") (:url . "https://github.com/alphapapa/pocket-reader.el"))])
+ (podcaster . [(20200607 1054) ((cl-lib (0 5))) "Podcast client" single ((:commit . "7a21173da0c57e6aa41dbdc33383047386b35eb5") (:authors ("DarkSun" . "lujun9972@gmail.com")) (:maintainer "DarkSun" . "lujun9972@gmail.com") (:url . "https://github.com/lujun9972/podcaster"))])
+ (poe-lootfilter-mode . [(20190330 1117) ((emacs (24 3))) "Major mode for editing Path of Exile lootfilters" single ((:commit . "5ef06684cb2b17b090ee1f303c2b789fa71bc106") (:authors ("Jeremiah Dodds" . "jeremiah.dodds@gmail.com")) (:maintainer "Jeremiah Dodds" . "jeremiah.dodds@gmail.com") (:keywords "languages" "games") (:url . "https://github.com/jdodds/poe-lootfilter-mode"))])
+ (poet-client . [(20190403 708) ((emacs (24 4)) (request (0 3 0))) "Client for po.et network api" single ((:commit . "38a9635cab4799224153f89ff47cf1b060fb3939") (:authors ("W.Yahia")) (:maintainer "W.Yahia") (:url . "https://github.com/wailo/emacs-poet"))])
+ (poet-theme . [(20200606 2343) ((emacs (24 1))) "A theme for prose" tar ((:commit . "16eb694f0755c04c4db98614d0eca1199fddad70") (:authors ("Kunal Bhalla" . "bhalla.kunal@gmail.com")) (:maintainer "Kunal Bhalla" . "bhalla.kunal@gmail.com") (:keywords "faces" "theme" "prose") (:url . "https://github.com/kunalb/poet/"))])
+ (poetry . [(20211016 834) ((transient (0 2 0)) (pyvenv (1 2)) (emacs (25 1))) "Interface to Poetry" single ((:commit . "5b9ef569d629d79820e73b5380e54e443ba90616") (:authors ("Gaby Launay" . "gaby.launay@protonmail.com")) (:maintainer "Gaby Launay" . "gaby.launay@protonmail.com") (:keywords "python" "tools") (:url . "https://github.com/galaunay/poetry.el"))])
+ (point-pos . [(20170421 1632) nil "Save and restore point positions" single ((:commit . "442bccb40791832cbc2d6f5c8f53be745aea2b73") (:authors ("Alex Kost" . "alezost@gmail.com")) (:maintainer "Alex Kost" . "alezost@gmail.com") (:keywords "tools" "convenience") (:url . "https://github.com/alezost/point-pos.el"))])
+ (point-stack . [(20200427 107) nil "Back and forward navigation through buffer locations" single ((:commit . "cddcea2c91038710c245819b3cda2dd739726134") (:authors ("Matt Harrison" . "matthewharrison@gmail.com") ("Dmitry Gutov" . "dgutov@yandex.ru")) (:maintainer "Matt Harrison" . "matthewharrison@gmail.com"))])
+ (poke-line . [(20201023 247) ((emacs (24 3))) "Minor mode to show position in a buffer using a Pokemon" tar ((:commit . "8d484dbaa1215d902fbd1e3c9163b39a43ec532a") (:authors ("Ryan Miller" . "ryan@devopsmachine.com")) (:maintainer "Ryan Miller" . "ryan@devopsmachine.com") (:keywords "pokemon" "fun" "mode-line" "mouse") (:url . "https://github.com/RyanMillerC/poke-line/"))])
+ (pollen-mode . [(20210120 422) ((emacs (24 3)) (cl-lib (0 5))) "major mode for editing pollen files" single ((:commit . "09a9dc48c468dcd385982b9629f325e70d569faf") (:authors ("Junsong Li <ljs.darkfish AT GMAIL>")) (:maintainer "Junsong Li") (:keywords "languages" "pollen" "pollenpub") (:url . "https://github.com/lijunsong/pollen-mode"))])
+ (poly-R . [(20210930 1921) ((emacs (25)) (polymode (0 2 2)) (poly-markdown (0 2 2)) (poly-noweb (0 2 2))) "Various polymodes for R language" single ((:commit . "e4a39caaf48e1c2e5afab3865644267b10610537") (:authors ("Vitalie Spinu")) (:maintainer "Vitalie Spinu") (:keywords "languages" "multi-modes") (:url . "https://github.com/polymode/poly-R"))])
+ (poly-ansible . [(20220113 1656) ((ansible (0 2)) (ansible-doc (0 4)) (jinja2-mode (0 2)) (polymode (0 1 5)) (yaml-mode (0 0 13))) "Polymode for Ansible: Jinja2 in YAML" tar ((:commit . "6d74fe80b7e61a35aa0fa36a520eaf5c9c027c51") (:authors ("Peter Oliver" . "poly-ansible@mavit.org.uk")) (:maintainer "Peter Oliver" . "poly-ansible@mavit.org.uk") (:keywords "languages") (:url . "https://gitlab.com/mavit/poly-ansible/"))])
+ (poly-erb . [(20200316 1314) ((emacs (25)) (polymode (0 2 2))) "Polymode for erb" single ((:commit . "56c744b8d87d8cbe0aba2696d4e8525afc4aa0e8") (:authors ("Siavash Sajjadi and Vitalie Spinu")) (:maintainer "Vitalie Spinu") (:keywords "emacs") (:url . "https://github.com/polymode/poly-erb"))])
+ (poly-markdown . [(20220117 2351) ((emacs (25)) (polymode (0 2 2)) (markdown-mode (2 3))) "Polymode for markdown-mode" single ((:commit . "d4ca396ec4a7d674ef0d671a6896f929ce5b504c") (:authors ("Vitalie Spinu")) (:maintainer "Vitalie Spinu") (:keywords "emacs") (:url . "https://github.com/polymode/poly-markdown"))])
+ (poly-noweb . [(20200316 1315) ((emacs (25)) (polymode (0 2 2))) "Polymode for noweb" single ((:commit . "3b0cd36ca9a707e8a09337a3468fa85d81fc461c") (:authors ("Vitalie Spinu")) (:maintainer "Vitalie Spinu") (:keywords "languages" "multi-modes") (:url . "https://github.com/polymode/poly-noweb"))])
+ (poly-org . [(20220201 1514) ((emacs (25)) (polymode (0 2 2))) "Polymode for org-mode" single ((:commit . "01fd0f4b7eaeabf070af831f4825993210f64f2e") (:authors ("Vitalie Spinu")) (:maintainer "Vitalie Spinu") (:keywords "languages" "multi-modes") (:url . "https://github.com/polymode/poly-org"))])
+ (poly-rst . [(20210418 1009) ((emacs (25)) (polymode (0 2 2))) "poly-rst-mode polymode" single ((:commit . "e71f2ae6a00683cdb8006f953e5db0673043e144") (:authors ("Gustaf Waldemarson, Vitalie Spinu")) (:maintainer "Gustaf Waldemarson, Vitalie Spinu") (:keywords "languages" "multi-modes") (:url . "https://github.com/polymode/poly-rst"))])
+ (poly-ruby . [(20180905 929) ((emacs (25)) (polymode (0 1 2))) "Provides poly-ruby-mode" single ((:commit . "794ebb926ace23e9c1398da934701951432dcea2") (:authors ("Akinori MUSHA" . "knu@iDaemons.org")) (:maintainer "Akinori MUSHA" . "knu@iDaemons.org") (:keywords "languages") (:url . "https://github.com/knu/poly-ruby.el"))])
+ (poly-slim . [(20200316 1316) ((emacs (25)) (polymode (0 2 2)) (slim-mode (1 1))) "Polymodes for slim" single ((:commit . "9e9b5164c68955974fd5f5d220aec5af9b5ba3ae") (:authors ("Siavash Sajjadi and Vitalie Spinu")) (:maintainer "Vitalie Spinu") (:keywords "emacs") (:url . "https://github.com/polymode/poly-slim"))])
+ (poly-wdl . [(20190712 529) ((emacs (25)) (polymode (0 2)) (wdl-mode (20170709))) "Polymode for WDL" single ((:commit . "963faa828d15d49cee5a63f619c3c30e162c2d0f") (:authors ("Jean Monlong" . "jean.monlong@gmail.com")) (:maintainer "Jean Monlong" . "jean.monlong@gmail.com") (:keywords "languages") (:url . "https://github.com/jmonlong/poly-wdl"))])
+ (polybar-sesman . [(20210901 1336) ((emacs (25 1)) (dash (2 19 1)) (sesman (0 3 0))) "Display active sesman connections in polybar" single ((:commit . "5175b8d641aad9576519717f69f858621892d5c7") (:authors ("Mark Dawson" . "markgdawson@gmail.com")) (:maintainer "Mark Dawson" . "markgdawson@gmail.com") (:keywords "project" "convenience") (:url . "https://github.com/markgdawson/polybar-sesman.el"))])
+ (polymode . [(20220322 824) ((emacs (25))) "Extensible framework for multiple major modes" tar ((:commit . "2094c92403fe395dfb2b8b2521da1012a966e9ab") (:authors ("Vitalie Spinu")) (:maintainer "Vitalie Spinu") (:keywords "languages" "multi-modes" "processes") (:url . "https://github.com/polymode/polymode"))])
+ (pomidor . [(20210111 919) ((emacs (24 3)) (alert (1 2)) (dash (2 17 0))) "Simple and cool pomodoro timer" tar ((:commit . "52134701fa76b12252b06c9d6fd4e8665596a95a") (:authors ("TatriX" . "tatrics@gmail.com")) (:maintainer "TatriX" . "tatrics@gmail.com") (:keywords "tools" "time" "applications" "pomodoro technique") (:url . "https://github.com/TatriX/pomidor"))])
+ (pomm . [(20220315 2038) ((emacs (27 1)) (alert (1 2)) (seq (2 22)) (transient (0 3 0))) "Yet another Pomodoro timer implementation" tar ((:commit . "2a2673bdc8e2c2af99040b14e97b39271806bf79") (:authors ("Korytov Pavel" . "thexcloud@gmail.com")) (:maintainer "Korytov Pavel" . "thexcloud@gmail.com") (:url . "https://github.com/SqrtMinusOne/pomm.el"))])
+ (pomodoro . [(20210225 2018) nil "A timer for the Pomodoro Technique" single ((:commit . "ed888b24d0b89a5dec6f5278b1064c530c827321") (:authors ("David Kerschner" . "dkerschner@gmail.com")) (:maintainer "David Kerschner" . "dkerschner@gmail.com"))])
+ (pony-mode . [(20170807 1522) nil "Minor mode for working with Django Projects" tar ((:commit . "760684d30b6c234d1b88c9a4673a808f36f7f341") (:authors ("David Miller" . "david@deadpansincerity.com")) (:maintainer "David Miller" . "david@deadpansincerity.com") (:keywords "python" "django") (:url . "https://github.com/davidmiller/pony-mode"))])
+ (pony-snippets . [(20200418 354) ((yasnippet (0 8 0))) "Yasnippets for Pony" tar ((:commit . "81a1348f81b0d8a3097d1ca3f2fb2f57964d56d6") (:keywords "snippets" "pony") (:url . "https://github.com/seantallen/pony-snippets"))])
+ (ponylang-mode . [(20211015 331) ((emacs (25 1)) (dash (2 17 0)) (hydra (0 15 0)) (hl-todo (3 1 2)) (yafolding (0 4 1)) (yasnippet (0 14 0)) (company-ctags (0 0 4)) (rainbow-delimiters (2 1 4)) (fill-column-indicator (1 90))) "A major mode for the Pony programming language" single ((:commit . "4bdffa94cd89da91b75e9edc56e9e2197ce072a3") (:keywords "languages" "programming") (:url . "https://github.com/ponylang/ponylang-mode"))])
+ (pophint . [(20200420 1429) ((log4e (0 3 3)) (yaxception (0 3))) "Provide navigation using pop-up tips, like Firefox's Vimperator Hint Mode" tar ((:commit . "5e13da4578ae7ba00e6f7bae31eb546d713cc19d") (:authors ("Hiroaki Otsu" . "ootsuhiroaki@gmail.com")) (:maintainer "Hiroaki Otsu" . "ootsuhiroaki@gmail.com") (:keywords "popup") (:url . "https://github.com/aki2o/emacs-pophint"))])
+ (poporg . [(20170403 751) nil "Pop a comment or string to an empty buffer for text editing" single ((:commit . "2c58d68c81ecca4140bf179f19ed153ec804b65a") (:authors ("François Pinard" . "pinard@iro.umontreal.ca") ("Joseph Rabinoff" . "rabinoff@post.harvard.edu")) (:maintainer "Joseph Rabinoff" . "rabinoff@post.harvard.edu") (:keywords "outlines" "tools") (:url . "https://github.com/QBobWatson/poporg"))])
+ (popper . [(20220406 336) ((emacs (26 1))) "Summon and dismiss buffers as popups" tar ((:commit . "6599c9b5a12b411c6cf1536bf200ae233fa24389") (:authors ("Karthik Chikmagalur" . "karthik.chikmagalur@gmail.com")) (:maintainer "Karthik Chikmagalur" . "karthik.chikmagalur@gmail.com") (:keywords "convenience") (:url . "https://github.com/karthink/popper"))])
+ (popup . [(20211231 1823) ((emacs (24 3))) "Visual Popup User Interface" single ((:commit . "3bf430270c74dad830ab9d776aab23cbf3ea3953") (:authors ("Tomohiro Matsuyama" . "m2ym.pub@gmail.com")) (:maintainer "Shen, Jen-Chieh" . "jcs090218@gmail.com") (:keywords "lisp") (:url . "https://github.com/auto-complete/popup-el"))])
+ (popup-complete . [(20141109 308) ((popup (0 5 0))) "completion with popup" single ((:commit . "caa655a6d8472e9a4bfa1311126d90d7d1b07fca") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-popup-complete"))])
+ (popup-edit-menu . [(20170404 1425) ((emacs (24))) "a popup context edit menu package" single ((:commit . "925600a6e29183841199e866cf55e566a6a1b002") (:authors ("Debugfan Chin" . "debugfanchin@gmail.com")) (:maintainer "Debugfan Chin" . "debugfanchin@gmail.com") (:keywords "lisp" "pop-up" "context" "edit" "menu"))])
+ (popup-imenu . [(20210404 1153) ((dash (2 12 1)) (popup (0 5 3)) (flx-ido (0 6 1))) "imenu index popup" single ((:commit . "b00c4d503cbbaf01c136b1647329e6a6257d012c") (:authors ("Igor Shymko" . "igor.shimko@gmail.com")) (:maintainer "Igor Shymko" . "igor.shimko@gmail.com") (:keywords "popup" "imenu") (:url . "https://github.com/ancane/popup-imenu"))])
+ (popup-kill-ring . [(20131020 1854) ((popup (0 4)) (pos-tip (0 4))) "interactively insert item from kill-ring" single ((:commit . "5773dfadc104a906c088a3ec62e8cdd3e01e57fa") (:authors ("khiker" . "khiker.mail+elisp@gmail.com")) (:maintainer "khiker" . "khiker.mail+elisp@gmail.com") (:keywords "popup" "kill-ring" "pos-tip") (:url . "https://github.com/waymondo/popup-kill-ring"))])
+ (popup-switcher . [(20210402 1208) ((cl-lib (0 3)) (popup (0 5 3)) (dash (2 10 0))) "switch to other buffers and files via popup." single ((:commit . "94e01b9ea7970e86ed0f2fbeaa8cd320b60ae821") (:authors ("Kostafey" . "kostafey@gmail.com")) (:maintainer "Kostafey" . "kostafey@gmail.com") (:keywords "popup" "switch" "buffers" "functions") (:url . "https://github.com/kostafey/popup-switcher"))])
+ (popwin . [(20210215 1849) ((emacs (24 3))) "Popup Window Manager" single ((:commit . "f90f3a09622993bf34704bb11c24984f6b1f10e2") (:authors ("Tomohiro Matsuyama" . "m2ym.pub@gmail.com")) (:maintainer "Tomohiro Matsuyama" . "m2ym.pub@gmail.com") (:keywords "convenience") (:url . "https://github.com/emacsorphanage/popwin"))])
+ (portage-navi . [(20141208 1355) ((concurrent (0 3 1)) (ctable (0 1 2))) "portage viewer" single ((:commit . "8016c3e99fe6cef101d479a3d69185796b22ca2f") (:authors ("<m.sakurai at kiwanami.net>")) (:maintainer "<m.sakurai at kiwanami.net>") (:keywords "tools" "gentoo") (:url . "https://github.com/kiwanami/emacs-portage-navi"))])
+ (porthole . [(20200404 1454) ((emacs (26)) (web-server (0 1 2)) (f (0 19 0)) (json-rpc-server (0 1 2))) "RPC Servers in Emacs" single ((:commit . "21af54b2fc9fd8876664c8e6c2ff2e4ffbbad249") (:authors ("GitHub user \"Jcaw\"")) (:maintainer "GitHub user \"Jcaw\"") (:keywords "comm" "rpc" "http" "json") (:url . "https://github.com/jcaw/porthole"))])
+ (pos-tip . [(20191227 1356) nil "Show tooltip at point" single ((:commit . "179cc126b363f72ca12fab1e0dc462ce0ee79742") (:authors ("S. Irie")) (:maintainer "S. Irie") (:keywords "tooltip"))])
+ (posframe . [(20220124 859) ((emacs (26 1))) "Pop a posframe (just a frame) at point" tar ((:commit . "c91d4d53fa479ceb604071008ce0a901770eff57") (:authors ("Feng Shu" . "tumashu@163.com")) (:maintainer "Feng Shu" . "tumashu@163.com") (:keywords "convenience" "tooltip") (:url . "https://github.com/tumashu/posframe"))])
+ (posix-manual . [(20200301 1103) ((emacs (24))) "POSIX manual page lookup" tar ((:commit . "ebaacd7266ae7a66605317f57b9f42e9cfb2ce1e") (:authors ("Lassi Kortela" . "lassi@lassi.io")) (:maintainer "Lassi Kortela" . "lassi@lassi.io") (:keywords "languages" "util") (:url . "https://github.com/lassik/emacs-posix-manual"))])
+ (postcss-sorting . [(20180211 956) ((emacs (24))) "postcss-sorting interface" single ((:commit . "deb0c935d2904c11a965758a9aee5a0e905f21fc") (:authors ("Peiwen Lu" . "hi@peiwen.lu")) (:maintainer "Peiwen Lu" . "hi@peiwen.lu") (:url . "https://github.com/P233/postcss-sorting.el"))])
+ (pov-mode . [(20161115 743) nil "Major mode for editing POV-Ray scene files." tar ((:commit . "9fc1db3aab7c27155674dd1a87ec62606035d074") (:authors ("Peter Boettcher" . "pwb@andrew.cmu.edu")) (:maintainer "Marco Pessotto" . "melmothx@gmail.com") (:keywords "pov" "povray"))])
+ (pow . [(20140420 806) ((emacs (24)) (cl-lib (0 5))) "pow (http://pow.cx/) manager for emacs" tar ((:commit . "ea83986b8ca8e27cb996290d6463b111ec0966ce") (:authors ("yukihiro hara" . "yukihr@gmail.com")) (:maintainer "yukihiro hara" . "yukihr@gmail.com") (:keywords "develop" "web" "pow") (:url . "http://github.com/yukihr/emacs-pow"))])
+ (powerline . [(20220122 1904) ((cl-lib (0 2))) "Rewrite of Powerline" tar ((:commit . "566c77844f053cb39fa7acdfbc143a855450f0b5") (:authors ("Donald Ephraim Curtis" . "dcurtis@milkbox.net")) (:maintainer "Donald Ephraim Curtis" . "dcurtis@milkbox.net") (:keywords "mode-line") (:url . "http://github.com/milkypostman/powerline/"))])
+ (powerline-evil . [(20190603 340) ((evil (1 0 8)) (powerline (2 3))) "Utilities for better Evil support for Powerline" tar ((:commit . "b77e2cf571e9990734f2b30d826f3a362b559fd1") (:authors ("Chris Johnson" . "chris@christophermjohnson.net")) (:maintainer "Chris Johnson" . "chris@christophermjohnson.net") (:keywords "evil" "mode-line" "powerline") (:url . "http://github.com/johnson-christopher/powerline-evil/"))])
+ (powershell . [(20220402 643) ((emacs (24))) "Mode for editing PowerShell scripts" single ((:commit . "77b27faf8a292f1dc9f54c872241dc53b6791bf1") (:authors ("Frédéric Perrin <frederic (dot) perrin (arobas) resel (dot) fr>")) (:maintainer "Frédéric Perrin <frederic (dot) perrin (arobas) resel (dot) fr>") (:keywords "powershell" "languages") (:url . "http://github.com/jschaf/powershell.el"))])
+ (powerthesaurus . [(20220414 1453) ((emacs (24)) (request (0 3 0)) (s (1 12 0))) "Powerthesaurus integration" single ((:commit . "88bc5229cba1604c8f74db0a1456d99259d538cc") (:keywords "convenience" "writing") (:url . "http://github.com/SavchenkoValeriy/emacs-powerthesaurus"))])
+ (ppd-sr-speedbar . [(20151108 1224) ((sr-speedbar (20140914 2339)) (project-persist-drawer (0 0 4))) "Sr Speedbar adaptor for project-persist-drawer." tar ((:commit . "d88d7f63f695824c435dd996405454d1e46d2aa3") (:authors ("Robert Dallas Gray")) (:maintainer "Robert Dallas Gray") (:keywords "projects" "drawer") (:url . "https://github.com/rdallasgrayppd-sr-speedbar"))])
+ (ppp . [(20220211 1529) ((emacs (25 1))) "Extended pretty printer for Emacs Lisp" single ((:commit . "d5d854c3006dfd268e62c7f91c2aad6f86a505b5") (:authors ("Naoya Yamashita" . "conao3@gmail.com")) (:maintainer "Naoya Yamashita" . "conao3@gmail.com") (:keywords "tools") (:url . "https://github.com/conao3/ppp.el"))])
+ (pr-review . [(20220412 440) ((emacs (27 1)) (magit-section (3 2)) (magit (3 2)) (markdown-mode (2 5)) (ghub (3 5))) "Review github PR" tar ((:commit . "cfc5643c4ab66f17a31d82418465ae434486d8db") (:authors ("Yikai Zhao" . "yikai@z1k.dev")) (:maintainer "Yikai Zhao" . "yikai@z1k.dev") (:keywords "tools") (:url . "https://github.com/blahgeek/emacs-pr-review"))])
+ (prassee-theme . [(20180709 1004) ((emacs (24))) "A high contrast color theme for Emacs." single ((:commit . "81126f69cdbaab836c00ae7a49aaf89d4229fde1") (:authors ("Prassee " . "prassee.sathian@gmail.com")) (:maintainer "Prassee " . "prassee.sathian@gmail.com") (:keywords "dark" "high-contrast" "faces") (:url . "https://github.com/prassee/prassee-emacs-theme"))])
+ (prefab . [(20220403 1026) ((emacs (27 1)) (f (0 2 0)) (transient (0 3 7))) "Integration for project generation tools like cookiecutter" single ((:commit . "ffcf9c640c8c458a58b752ef2608e07a929a1104") (:authors ("Laurence Warne")) (:maintainer "Laurence Warne") (:url . "https://github.com/laurencewarne/prefab.el"))])
+ (preproc-font-lock . [(20151107 2018) nil "Highlight C-style preprocessor directives." single ((:commit . "565fda9f5fdeb0598986174a07e9fb09f7604397") (:authors ("Anders Lindgren")) (:maintainer "Anders Lindgren") (:keywords "c" "languages" "faces") (:url . "https://github.com/Lindydancer/preproc-font-lock"))])
+ (prescient . [(20211228 417) ((emacs (25 1))) "Better sorting and filtering" single ((:commit . "d9b30d741c729a37eb2c6e51d72281c0844780ca") (:authors ("Radon Rosborough" . "radon.neon@gmail.com")) (:maintainer "Radon Rosborough" . "radon.neon@gmail.com") (:keywords "extensions") (:url . "https://github.com/raxod502/prescient.el"))])
+ (preseed-generic-mode . [(20180210 500) nil "Debian preseed file major mode" single ((:commit . "3aa8806c4a659064baa01751400c53fbaf847f66") (:authors ("Tong Sun" . "suntong@users.sourceforge.net")) (:maintainer "Tong Sun" . "suntong@users.sourceforge.net") (:url . "https://github.com/suntong/preseed-generic-mode"))])
+ (presentation . [(20180427 224) ((emacs (24 4)) (cl-lib (0 5))) "Display large character for presentation" single ((:commit . "f53f67aeab97e8eea6d1f12df5f7ce3b1b03b879") (:authors ("USAMI Kenta" . "tadsan@zonu.me")) (:maintainer "USAMI Kenta" . "tadsan@zonu.me") (:keywords "environment" "faces" "frames") (:url . "https://github.com/zonuexe/emacs-presentation-mode"))])
+ (prettier . [(20211018 955) ((emacs (26 1)) (iter2 (0 9)) (nvm (0 2))) "Code formatting with Prettier" tar ((:commit . "485417c0677255249e944b1174225547e4c61c00") (:authors ("Julian Scheid" . "julians37@gmail.com")) (:maintainer "Julian Scheid" . "julians37@gmail.com") (:keywords "convenience" "languages" "files") (:url . "https://github.com/jscheid/prettier.el"))])
+ (prettier-js . [(20180109 726) nil "Minor mode to format JS code on file save" single ((:commit . "e9b73e81d3e1642aec682195f127a42dfb0b5774") (:authors ("James Long and contributors")) (:maintainer "James Long and contributors") (:keywords "convenience" "wp" "edit" "js") (:url . "https://github.com/prettier/prettier-emacs"))])
+ (prettier-rc . [(20220330 145) ((emacs (24 3)) (prettier-js (0 1 0))) "Use local rc rules with prettier" single ((:commit . "99e40a9783299e41911f6b37156626d53e43809e") (:authors ("Joel Bryan Juliano <joelbryan dot juliano at gmail dot com>")) (:maintainer "Joel Bryan Juliano <joelbryan dot juliano at gmail dot com>") (:keywords "convenience" "edit" "js" "ts" "rc" "prettierrc" "prettier-rc" "prettier" "prettier-js") (:url . "https://github.com/jjuliano/prettier-rc-emacs"))])
+ (prettify-greek . [(20160603 908) nil "Greek letters for prettify-symbols" single ((:commit . "698d07a6ffe85f6fb53f3bfec4f49380c25cfd90") (:keywords "faces") (:url . "https://gitlab.com/fommil/emacs-prettify-greek"))])
+ (prettify-math . [(20220101 549) ((emacs (27 1)) (dash (2 19 0)) (s (1 12 0)) (jsonrpc (1 0 9))) "Prettify math formula" tar ((:commit . "5bdb9a8af7593d3a38492a618aedc545278fe8a1") (:authors ("Shaq Xu" . "shaqxu@163.com")) (:maintainer "Shaq Xu" . "shaqxu@163.com") (:keywords "math" "asciimath" "tex" "latex" "prettify" "mathjax") (:url . "https://github.com/shaqxu/prettify-math"))])
+ (pretty-hydra . [(20210221 834) ((hydra (0 15 0)) (s (1 12 0)) (dash (2 18 0)) (emacs (24))) "A macro for creating nice-looking hydras" single ((:commit . "84c1929a5153be169ca5c36737439d51dffde505") (:authors ("Jerry Peng" . "pr2jerry@gmail.com")) (:maintainer "Jerry Peng" . "pr2jerry@gmail.com") (:url . "https://github.com/jerrypnz/major-mode-hydra.el"))])
+ (pretty-mode . [(20190615 2045) nil "Redisplay parts of the buffer as pretty Unicode symbols." single ((:commit . "5154355e90fdd70d3647257280a89eeb725ef084") (:authors ("Arthur Danskin" . "arthurdanskin@gmail.com")) (:maintainer "Grant Rettke" . "grant@wisdomandwonder.com") (:keywords "pretty" "unicode" "symbols") (:url . "https://github.com/akatov/pretty-mode"))])
+ (pretty-sha-path . [(20141105 1826) nil "Prettify Guix/Nix store paths" single ((:commit . "a2b43dd9de423a38d67cda2e3bd9412f7d363257") (:authors ("Alex Kost" . "alezost@gmail.com")) (:maintainer "Alex Kost" . "alezost@gmail.com") (:keywords "faces" "convenience") (:url . "https://gitorious.org/alezost-emacs/pretty-sha-path"))])
+ (pretty-speedbar . [(20220303 1726) ((emacs (27 1))) "Make speedbar pretty" single ((:commit . "56dc9f114fcc55843e182cde1fc9d7a14c261c6a") (:authors ("Kristle Chester" . "kcyarn7@gmail.com")) (:maintainer "Kristle Chester" . "kcyarn7@gmail.com") (:keywords "file" "tags" "tools") (:url . "https://github.com/kcyarn/pretty-speedbar"))])
+ (pretty-symbols . [(20140814 959) nil "Draw tokens as Unicode glyphs." single ((:commit . "582cbe51ecfe1cc0a5b185bc06113c8a661e3956") (:authors ("David Röthlisberger" . "david@rothlis.net")) (:maintainer "David Röthlisberger" . "david@rothlis.net") (:keywords "faces") (:url . "http://github.com/drothlis/pretty-symbols"))])
+ (preview-dvisvgm . [(20211225 635) ((emacs (27 1)) (auctex (13 0 12))) "SVG output for LaTeX preview" single ((:commit . "630e2f008c4a6c67a01824b7ad6b844977b28f87") (:authors ("Tobias Zawada" . "i@tn-home.de")) (:maintainer "Tobias Zawada" . "i@tn-home.de") (:keywords "tex") (:url . "https://github.com/TobiasZawada/preview-dvisvgm"))])
+ (prism . [(20210804 417) ((emacs (26 1)) (dash (2 14 1))) "Customizable, depth-based syntax coloring" single ((:commit . "b0cbdaf4916c1cf348a8f0e4f6158e040a627562") (:authors ("Adam Porter" . "adam@alphapapa.net")) (:maintainer "Adam Porter" . "adam@alphapapa.net") (:keywords "faces" "lisp") (:url . "https://github.com/alphapapa/prism.el"))])
+ (private . [(20150122 157) ((aes (0 6))) "take care of your private configuration files." single ((:commit . "9266d01c095895cc3ee9de95bc20511e88353755") (:authors ("Cheung Mou Wai" . "yeannylam@gmail.com")) (:maintainer "Cheung Mou Wai" . "yeannylam@gmail.com") (:keywords "private" "configuration" "backup" "recover") (:url . "https://github.com/cheunghy/private"))])
+ (private-comments-mode . [(20220330 1316) ((emacs (27 1))) "Minor mode for masukomi/private_comments" single ((:commit . "57eb1ba3812e44344b7d5336c3a3ad14a28e4f9e") (:keywords "tools") (:url . "https://github.com/masukomi/private-comments-mode"))])
+ (private-diary . [(20151216 1657) ((emacs (24 0))) "maintain a private diary in Emacs" single ((:commit . "0c86fb6150ad8ed14f94def3504f5a68f4147283") (:authors ("James P. Ascher" . "jpa4q@virginia.edu")) (:maintainer "James P. Ascher" . "jpa4q@virginia.edu") (:keywords "diary" "encryption") (:url . "https://github.com/cacology/private-diary"))])
+ (proc-net . [(20130322 12) nil "network process tools" single ((:commit . "10861112a1f3994c8e6374d6c5bb5d734cfeaf73") (:authors ("Nic Ferrier" . "nferrier@ferrier.me.uk")) (:maintainer "Nic Ferrier" . "nferrier@ferrier.me.uk") (:keywords "processes") (:url . "http://github.com/nicferrier/emacs-procnet"))])
+ (proced-narrow . [(20190911 1818) ((seq (2 20)) (emacs (24))) "Live-narrowing of search results for proced." single ((:commit . "0e2a4dfb072eb0369d0020b429e820ae620d325e") (:authors ("Travis Jeffery" . "tj@travisjeffery.com")) (:maintainer "Travis Jeffery" . "tj@travisjeffery.com") (:keywords "processes" "proced") (:url . "https://github.com/travisjeffery/proced-narrow"))])
+ (processing-mode . [(20171022 2302) nil "Major mode for Processing 2.0" single ((:commit . "448aba82970c98322629eaf2746e73be6c30c98e") (:authors ("Peter Vasil" . "mail@petervasil.net")) (:maintainer "Peter Vasil" . "mail@petervasil.net") (:keywords "languages" "snippets") (:url . "https://github.com/ptrv/processing2-emacs"))])
+ (processing-snippets . [(20140426 1428) ((yasnippet (0 8 0))) "Snippets for processing-mode" tar ((:commit . "448aba82970c98322629eaf2746e73be6c30c98e") (:authors ("Peter Vasil" . "mail@petervasil.net")) (:maintainer "Peter Vasil" . "mail@petervasil.net") (:keywords "snippets") (:url . "https://github.com/ptrv/processing2-emacs"))])
+ (prodigy . [(20210116 816) ((s (1 8 0)) (dash (2 4 0)) (f (0 14 0)) (emacs (24))) "Manage external services from within Emacs" single ((:commit . "168f5ace1671876d8c3bd350c0853bd0196bddda") (:authors ("Johan Andersson" . "johan.rejeep@gmail.com")) (:maintainer "Johan Andersson" . "johan.rejeep@gmail.com") (:url . "http://github.com/rejeep/prodigy.el"))])
+ (professional-theme . [(20150315 1100) nil "Emacs port of Vim's professional theme" single ((:commit . "0927d1474049a193f9f366bde5eb1887b9ba20ed") (:authors ("Juanjo Alvarez" . "juanjo@juanjoalvarez.net")) (:maintainer "Juanjo Alvarez" . "juanjo@juanjoalvarez.net") (:keywords "theme" "light" "professional") (:url . "https://github.com/juanjux/emacs-professional-theme"))])
+ (prog-fill . [(20180607 132) ((emacs (25 1)) (cl-lib (0 6 1))) "Smartly format lines to use vertical space." single ((:commit . "3fbf7da6dd826e95c9077d659566ee29814a31d8") (:authors ("Matthew Carter" . "m@ahungry.com")) (:maintainer "Matthew Carter" . "m@ahungry.com") (:keywords "ahungry" "convenience" "c" "formatting" "editing") (:url . "https://github.com/ahungry/prog-fill"))])
+ (prognth . [(20130920 1759) nil "Extend prog1 to arbitrary index" single ((:commit . "2f1ca4d34b1fd581163e1df122c85418137e8e62") (:authors ("Matus Goljer" . "matus.goljer@gmail.com")) (:maintainer "Matus Goljer" . "matus.goljer@gmail.com") (:keywords "lisp"))])
+ (programmer-dvorak . [(20150427 137) nil "Input method for Programmer Dvorak." single ((:commit . "3288a8f058eca4cab390a564babbbcb17cfa0350") (:authors ("Chenyun Yang" . "yangchenyun@gmail.com")) (:maintainer "Chenyun Yang" . "yangchenyun@gmail.com") (:keywords "dvorak" "programmer-dvorak" "input-method") (:url . "https://github.com/yangchenyun/programmer-dvorak"))])
+ (project-abbrev . [(20210715 1213) ((emacs (25 1))) "Customize abbreviation expansion in the project" single ((:commit . "d47f08f64cce595cbd4e9fbe3544986b3c4cee83") (:authors ("Shen, Jen-Chieh" . "jcs090218@gmail.com")) (:maintainer "Shen, Jen-Chieh" . "jcs090218@gmail.com") (:url . "https://github.com/jcs-elpa/project-abbrev"))])
+ (project-explorer . [(20150504 14) ((cl-lib (0 3)) (es-lib (0 3)) (es-windows (0 1)) (emacs (24))) "A project explorer sidebar" single ((:commit . "589a09008706f5f4ef91393dc4306eede0d15ca9") (:authors ("sabof")) (:maintainer "sabof") (:url . "https://github.com/sabof/project-explorer"))])
+ (project-mode-line-tag . [(20211013 1954) ((emacs (25 1))) "Display a buffer's project in its mode line" single ((:commit . "69d44e5495185587ee8577f8b9d616063d6bd7f8") (:authors ("Fritz Grabo" . "hello@fritzgrabo.com")) (:maintainer "Fritz Grabo" . "hello@fritzgrabo.com") (:keywords "convenience") (:url . "https://github.com/fritzgrabo/project-mode-line-tag"))])
+ (project-persist . [(20180906 1302) nil "A minor mode to allow loading and saving of project settings." tar ((:commit . "26d9435bef44da2a1b0892eba822f9f487b98eec") (:authors ("Robert Dallas Gray")) (:maintainer "Robert Dallas Gray") (:keywords "project" "persistence") (:url . "https://github.com/rdallasgray/project-persist"))])
+ (project-persist-drawer . [(20151108 1222) ((project-persist (0 3))) "Use a project drawer with project-persist." tar ((:commit . "35bbe132a4fab6a0fec15ce6c0fd2fe6a4aa9626") (:authors ("Robert Dallas Gray" . "mail@robertdallasgray.com")) (:maintainer "Robert Dallas Gray" . "mail@robertdallasgray.com") (:keywords "defaults") (:url . "https://github.com/rdallasgray/project-persist-drawer.git"))])
+ (project-shells . [(20210625 647) ((emacs (24 3)) (seq (2 19))) "Manage the shell buffers of each project" single ((:commit . "900369828f1a213c60a2207a71d46bc43fd5405c") (:authors ("\"Huang, Ying\"" . "huang.ying.caritas@gmail.com")) (:maintainer "\"Huang, Ying\"" . "huang.ying.caritas@gmail.com") (:keywords "processes" "terminals") (:url . "https://github.com/hying-caritas/project-shells"))])
+ (project-tab-groups . [(20220331 918) ((emacs (28))) "Support a \"one tab group per project\" workflow" single ((:commit . "837267a23fa57199599b96af94c2db2e80a859d3") (:authors ("Fritz Grabo" . "hello@fritzgrabo.com")) (:maintainer "Fritz Grabo" . "hello@fritzgrabo.com") (:keywords "convenience") (:url . "https://github.com/fritzgrabo/project-tab-groups"))])
+ (projectile . [(20220430 800) ((emacs (25 1))) "Manage and navigate projects in Emacs easily" single ((:commit . "a4f86f981c84a546530d5904253fa266431ef806") (:authors ("Bozhidar Batsov" . "bozhidar@batsov.dev")) (:maintainer "Bozhidar Batsov" . "bozhidar@batsov.dev") (:keywords "project" "convenience") (:url . "https://github.com/bbatsov/projectile"))])
+ (projectile-codesearch . [(20180508 1522) ((codesearch (20171122 431)) (projectile (20150405 126))) "Integration of codesearch into projectile" single ((:commit . "f6eb96f034a925444412cfa03e45e0ccbbafe3f2") (:authors ("Austin Bingham" . "austin.bingham@gmail.com")) (:maintainer "Austin Bingham" . "austin.bingham@gmail.com") (:keywords "tools" "development" "search") (:url . "https://github.com/abingham/emacs-codesearch"))])
+ (projectile-git-autofetch . [(20200820 2028) ((emacs (25 1)) (projectile (0 14 0))) "automatically fetch git repositories" single ((:commit . "423ed5fa6508c4edc0a837bb585c7e77e99876be") (:authors ("Andreas Müller" . "code@0x7.ch")) (:maintainer "Andreas Müller" . "code@0x7.ch") (:keywords "tools" "vc") (:url . "https://github.com/andrmuel/projectile-git-autofetch"))])
+ (projectile-rails . [(20220403 1621) ((emacs (25 1)) (projectile (0 12 0)) (inflections (1 1)) (inf-ruby (2 2 6)) (f (0 13 0)) (rake (0 3 2)) (dash (2 18 1))) "Minor mode for Rails projects based on projectile-mode" single ((:commit . "2a0107e83d8320507e288c853e0762bec110cd15") (:authors ("Adam Sokolnicki" . "adam.sokolnicki@gmail.com")) (:maintainer "Adam Sokolnicki" . "adam.sokolnicki@gmail.com") (:keywords "rails" "projectile") (:url . "https://github.com/asok/projectile-rails"))])
+ (projectile-ripgrep . [(20180914 1500) ((ripgrep (0 3 0)) (projectile (0 14 0))) "Run ripgrep with Projectile" single ((:commit . "4ed5c741233a81d96115f556784269042070901e") (:authors ("Nicolas Lamirault" . "nicolas.lamirault@gmail.com")) (:maintainer "Nicolas Lamirault" . "nicolas.lamirault@gmail.com") (:keywords "ripgrep" "projectile") (:url . "https://github.com/nlamirault/ripgrep.el"))])
+ (projectile-sift . [(20160107 1015) ((sift (0 2 0)) (projectile (0 13 0))) "Run a sift with Projectile" single ((:commit . "cdddba2d183146c340915003f1b5d09d13712c22") (:authors ("Nicolas Lamirault" . "nicolas.lamirault@gmail.com")) (:maintainer "Nicolas Lamirault" . "nicolas.lamirault@gmail.com") (:keywords "sift" "projectile") (:url . "https://github.com/nlamirault/sift.el"))])
+ (projectile-speedbar . [(20190807 2010) ((projectile (0 11 0)) (sr-speedbar (0))) "projectile integration for speedbar" single ((:commit . "93320e467ee78772065e599a5dba94889a77db22") (:authors ("Anshul Verma" . "anshul.verma86@gmail.com")) (:maintainer "Anshul Verma" . "anshul.verma86@gmail.com") (:keywords "project" "convenience" "speedbar" "projectile") (:url . "https://github.com/anshulverma/projectile-speedbar"))])
+ (projectile-trailblazer . [(20170928 1624) ((emacs (24 4)) (projectile (0 12 0)) (inflections (1 1)) (inf-ruby (2 2 6)) (f (0 13 0)) (rake (0 3 2))) "Minor mode for Rails projects using trailblazer" single ((:commit . "a37a4f7b7f727d98e4c74c0256e059e84263553d") (:authors ("Michael Dahl" . "michael.dahl84@gmail.com")) (:maintainer "Michael Dahl" . "michael.dahl84@gmail.com") (:keywords "rails" "projectile" "trailblazer" "languages") (:url . "https://github.com/micdahl/projectile-trailblazer"))])
+ (projectile-variable . [(20170208 1718) ((emacs (24)) (cl-lib (0 5))) "Store project local variables." single ((:commit . "8d348ac70bdd6dc320c13a12941b32b38140e264") (:authors ("USAMI Kenta" . "tadsan@zonu.me")) (:maintainer "USAMI Kenta" . "tadsan@zonu.me") (:keywords "project" "convenience") (:url . "https://github.com/zonuexe/projectile-variable"))])
+ (projector . [(20211112 1514) ((alert (1 1)) (cl-lib (0 5))) "Lightweight library for managing project-aware shell and command buffers" single ((:commit . "1d0f2d307591ea50888d31dcae7e463e2ada1316") (:authors ("Justin Talbott" . "justin@waymondo.com")) (:maintainer "Justin Talbott" . "justin@waymondo.com") (:url . "https://github.com/waymondo/projector.el"))])
+ (projekt . [(20150324 848) ((emacs (24))) "some kind of staging for CVS" single ((:commit . "a65e554e5d8b0def08c5d06f3fe34fec40bebd83") (:authors ("Engelke Eschner" . "tekai@gmx.li")) (:maintainer "Engelke Eschner" . "tekai@gmx.li"))])
+ (projmake-mode . [(20161031 1715) ((dash (20150611 922)) (indicators (20130217 1405))) "Project oriented automatic builder and error highlighter, flymake for projects" tar ((:commit . "a897701f7e8f8cc11459ed44eb0e454db2a460c1"))])
+ (promise . [(20210307 727) ((emacs (25 1))) "Promises/A+" tar ((:commit . "cec51feb5f957e8febe6325335cf57dc2db6be30") (:authors ("chuntaro" . "chuntaro@sakura-games.jp")) (:maintainer "chuntaro" . "chuntaro@sakura-games.jp") (:keywords "async" "promise" "convenience") (:url . "https://github.com/chuntaro/emacs-promise"))])
+ (prompt-text . [(20190408 310) nil "Configure your minibuffer prompt" single ((:commit . "f51cf3d7f08ab8946e9869f7de2082536e45cc22") (:authors ("10sr <8slashes+el [at] gmail [dot] com>")) (:maintainer "10sr <8slashes+el [at] gmail [dot] com>") (:keywords "utility" "minibuffer") (:url . "https://github.com/10sr/prompt-text-el"))])
+ (prompts . [(20160916 1041) ((dash (2 13 0))) "utilities for working with text prompts." single ((:commit . "1cd5e732ff2a86b47836eb7252e5b59cd4b6ab26") (:authors ("Ben Moon" . "guiltydolphin@gmail.com")) (:maintainer "Ben Moon" . "guiltydolphin@gmail.com") (:keywords "input" "minibuffer") (:url . "https://github.com/guiltydolphin/prompts.el"))])
+ (pronto . [(20200218 1633) ((emacs (24))) "Compilation mode for pronto stylechecks" single ((:commit . "c2a2ec718c08de1fd2e681970456786cf4eac8fe") (:authors ("Julian Rubisch" . "julian@julianrubisch.at")) (:maintainer "Julian Rubisch" . "julian@julianrubisch.at") (:keywords "processes" "tools") (:url . "https://github.com/julianrubisch/pronto.el"))])
+ (proof-general . [(20220329 655) ((emacs (25 1))) "A generic Emacs interface for proof assistants" tar ((:commit . "a894bcc5f915f1c76a2a83c12c12ea3497542426") (:url . "https://proofgeneral.github.io/"))])
+ (prop-menu . [(20150728 1118) ((emacs (24 3)) (cl-lib (0 5))) "Create and display a context menu based on text and overlay properties" single ((:commit . "50b102c1c0935fd3e0c465feed7f27d66b21cdf3") (:authors ("David Christiansen" . "david@davidchristiansen.dk")) (:maintainer "David Christiansen" . "david@davidchristiansen.dk") (:keywords "convenience") (:url . "https://github.com/david-christiansen/prop-menu-el"))])
+ (propfont-mixed . [(20150113 2211) ((emacs (24)) (cl-lib (0 5))) "Use proportional fonts with space-based indentation." single ((:commit . "0b461ef4754a469610dba71874a34b6da42176bf") (:authors ("Kirill Ignatiev <github.com/ikirill>")) (:maintainer "Kirill Ignatiev <github.com/ikirill>") (:keywords "faces") (:url . "https://github.com/ikirill/propfont-mixed"))])
+ (proportional . [(20200309 1556) ((emacs (25 1))) "use a proportional font everywhere" single ((:commit . "0e4537af7ba2bc9dbb449c38350bce012b382f51") (:authors ("Johannes Goslar")) (:maintainer "Johannes Goslar") (:keywords "faces") (:url . "https://github.com/ksjogo/proportional"))])
+ (prosjekt . [(20151127 1416) ((dash (2 8 0))) "a software project tool for emacs" tar ((:commit . "a864a8be5842223043702395f311e3350c28e9db") (:authors ("Austin Bingham" . "austin.bingham@gmail.com")) (:maintainer "Austin Bingham" . "austin.bingham@gmail.com") (:url . "https://github.com/abingham/prosjekt"))])
+ (protobuf-mode . [(20220303 1716) nil "major mode for editing protocol buffers." single ((:commit . "67823fe8dc7d57ca33689817c233dcf4f177fa4b") (:authors ("Alexandre Vassalotti" . "alexandre@peadrop.com")) (:maintainer "Alexandre Vassalotti" . "alexandre@peadrop.com") (:keywords "google" "protobuf" "languages"))])
+ (protocols . [(20170802 1132) ((cl-lib (0 5))) "Protocol database access functions." single ((:commit . "d0f7c4acb05465f1a0d4be54363bbd2802647e77") (:authors ("Dave Pearson" . "davep@davep.org")) (:maintainer "Dave Pearson" . "davep@davep.org") (:keywords "convenience" "net" "protocols") (:url . "https://github.com/davep/protocols.el"))])
+ (proxy-mode . [(20220210 1410) ((emacs (25))) "A minor mode to toggle proxy." single ((:commit . "620e48c6afaf760d0ee9f5bdf583fd91cd9d0ec6") (:keywords "comm" "proxy") (:url . "https://repo.or.cz/proxy-mode.git"))])
+ (psalm . [(20211002 1552) ((emacs (24 3)) (php-mode (1 22 3))) "Interface to Psalm" single ((:commit . "28d546a79cb865a78b94cd7e929d66d720505faa") (:authors ("USAMI Kenta" . "tadsan@zonu.me")) (:maintainer "USAMI Kenta" . "tadsan@zonu.me") (:keywords "tools" "php") (:url . "https://github.com/emacs-php/psalm.el"))])
+ (psc-ide . [(20210219 2247) ((emacs (25)) (dash (2 18 0)) (company (0 8 7)) (s (1 10 0)) (flycheck (0 24)) (let-alist (1 0 4)) (seq (1 11))) "Minor mode for PureScript's IDE server." tar ((:commit . "ce97d719458ea099b40c02f05b6609601c727e66") (:authors ("Erik Post" . "erik@shinsetsu.nl") ("Dmitry Bushenko" . "d.bushenko@gmail.com") ("Christoph Hegemann" . "christoph.hegemann1337@gmail.com") ("Brian Sermons")) (:maintainer "Erik Post" . "erik@shinsetsu.nl") (:keywords "languages") (:url . "https://github.com/purescript-emacs/psc-ide-emacs"))])
+ (psci . [(20191025 830) ((emacs (24 4)) (purescript-mode (13 10)) (dash (2 9 0))) "Major mode for purescript repl psci" tar ((:commit . "95fb5d14033add8fe9c8c6b4379758beb88af1d0") (:authors ("Antoine R. Dumont <eniotna.t AT gmail.com>")) (:maintainer "Antoine R. Dumont <eniotna.t AT gmail.com>") (:keywords "languages" "purescript" "psci" "repl") (:url . "https://github.com/purescript-emacs/emacs-psci"))])
+ (psession . [(20220318 1129) ((emacs (24)) (cl-lib (0 5)) (async (1 9 3))) "Persistent save of elisp objects." single ((:commit . "328c64804c4c9e15b373c7ba3bc82bfdfb27971a") (:authors ("Thierry Volpiatto" . "thierry.volpiatto@gmail.com")) (:maintainer "Thierry Volpiatto" . "thierry.volpiatto@gmail.com") (:url . "https://github.com/thierryvolpiatto/psession"))])
+ (psysh . [(20190709 106) ((emacs (24 3)) (s (1 9 0)) (f (0 17)) (php-runtime (0 2))) "PsySH, PHP interactive shell (REPL)" single ((:commit . "21250984ad8137aa3440ac12e52475ef03f19fcb") (:authors ("USAMI Kenta" . "tadsan@zonu.me")) (:maintainer "USAMI Kenta" . "tadsan@zonu.me") (:keywords "processes" "php") (:url . "https://github.com/zonuexe/psysh.el"))])
+ (pt . [(20161226 1959) nil "A front-end for pt, The Platinum Searcher." single ((:commit . "6d99b2aaded3ece3db19a20f4b8f1d4abe382622") (:authors ("Bailey Ling")) (:maintainer "Bailey Ling") (:keywords "pt" "ack" "ag" "grep" "search") (:url . "https://github.com/bling/pt.el"))])
+ (ptemplate . [(20210324 1446) ((emacs (25 1)) (yasnippet (0 13 0))) "Project templates" single ((:commit . "b81cc7be8865745c3a60177a244d2a69729ab21b") (:authors ("Nikita Bloshchanevich" . "nikblos@outlook.com")) (:maintainer "Nikita Bloshchanevich" . "nikblos@outlook.com") (:url . "https://github.com/nbfalcon/ptemplate"))])
+ (ptemplate-templates . [(20210324 1443) ((emacs (25 1)) (ptemplate (2 0 0))) "Official templates" tar ((:commit . "3788387973dde3101f9a3f2064572be033c59ad6") (:authors ("Nikita Bloshchanevich" . "nikblos@outlook.com")) (:maintainer "Nikita Bloshchanevich" . "nikblos@outlook.com") (:url . "https://github.com/nbfalcon/ptemplate-templates"))])
+ (pubmed . [(20210927 1933) ((emacs (25 1)) (deferred (0 5 1)) (esxml (0 3 4)) (s (1 12 0)) (unidecode (0 2))) "Interface to PubMed" tar ((:commit . "e1ac5433daf966cf7c5e9178b037191e1eb3e4bd") (:authors ("Folkert van der Beek" . "folkertvanderbeek@gmail.com")) (:maintainer "Folkert van der Beek" . "folkertvanderbeek@gmail.com") (:keywords "pubmed" "hypermedia") (:url . "https://gitlab.com/fvdbeek/emacs-pubmed"))])
+ (pug-mode . [(20211114 1645) ((emacs (24 4)) (cl-lib (0 5))) "Major mode for jade/pug template files" single ((:commit . "73f8c2f95eba695f701df20c8436f49abadebdc1") (:authors ("Nathan Weizenbaum")) (:maintainer "Henrik Lissner" . "contact@henrik.io") (:keywords "markup" "language" "jade" "pug") (:url . "https://github.com/hlissner/emacs-pug-mode"))])
+ (pulseaudio-control . [(20220418 742) nil "Use `pactl' to manage PulseAudio volumes." single ((:commit . "22f54ae7282b37eaec0231a21e60213a5dbc7172") (:authors ("Alexis" . "flexibeast@gmail.com") ("Ellington Santos" . "ellingtonsantos@gmail.com") ("Sergey Trofimov" . "sarg@sarg.org.ru")) (:maintainer "Alexis" . "flexibeast@gmail.com") (:keywords "multimedia" "hardware" "sound" "pulseaudio") (:url . "https://github.com/flexibeast/pulseaudio-control"))])
+ (punctuality-logger . [(20141120 2031) nil "Punctuality logger for Emacs" single ((:commit . "e09e5dd37bc92289fa2f7dc44aed51a7b5e04bb0") (:authors ("Philip Woods" . "elzairthesorcerer@gmail.com")) (:maintainer "Philip Woods" . "elzairthesorcerer@gmail.com") (:keywords "reminder" "calendar") (:url . "https://gitlab.com/elzair/punctuality-logger"))])
+ (pungi . [(20150222 1246) ((jedi (0 2 0 -3 2)) (pyvenv (1 5))) "Integrates jedi with virtualenv and buildout python environments" single ((:commit . "a2d4d439ea371be0b064a12248288903b8a521a0") (:authors ("Matthew Russell" . "matthew.russell@horizon5.org")) (:maintainer "Matthew Russell" . "matthew.russell@horizon5.org") (:keywords "convenience"))])
+ (puni . [(20220405 1808) ((emacs (26 1))) "Parentheses Universalistic" single ((:commit . "bb9b1e271b51b3dfae984da15f0e40f5be5b2473") (:authors ("Hao Wang" . "amaikinono@gmail.com")) (:maintainer "Hao Wang" . "amaikinono@gmail.com") (:keywords "convenience" "lisp" "tools") (:url . "https://github.com/AmaiKinono/puni"))])
+ (punpun-theme . [(20210508 1635) ((emacs (24 1))) "A bleak theme" tar ((:commit . "7026684cd568cb691af3ced5de14c375fe6f5a1a"))])
+ (puppet-mode . [(20210305 645) ((emacs (24 1)) (pkg-info (0 4))) "Major mode for Puppet manifests" single ((:commit . "71bcd383f20a457e8ad34e0e08ec47f8e1b64263") (:authors ("Vox Pupuli" . "voxpupuli@groups.io") ("Bozhidar Batsov" . "bozhidar@batsov.com") ("Sebastian Wiesner" . "swiesner@lunaryorn.com") ("Russ Allbery" . "rra@stanford.edu")) (:maintainer "Vox Pupuli" . "voxpupuli@groups.io") (:keywords "languages") (:url . "https://github.com/voxpupuli/puppet-mode"))])
+ (purescript-mode . [(20210109 244) ((emacs (25 1))) "A PureScript editing mode" tar ((:commit . "9c37067e611b5253a095f03245c247aa97bd7614") (:authors ("1992 Simon Marlow") ("1997-1998 Graeme E Moss" . "gem@cs.york.ac.uk") ("Tommy Thorn" . "thorn@irisa.fr") ("2001-2002 Reuben Thomas (>=v1.4)") ("2003 Dave Love" . "fx@gnu.org") ("2014 Tim Dysinger" . "tim@dysinger.net")) (:maintainer "1992 Simon Marlow") (:keywords "faces" "files" "purescript") (:url . "https://github.com/purescript-emacs/purescript-mode"))])
+ (purp-theme . [(20210912 1940) nil "A dark color theme with few colors" tar ((:commit . "8d3510e1ed995b8323cd5205626ddde6386a76ca") (:authors ("Vincent Foley" . "vfoley@gmail.com")) (:maintainer "Vincent Foley" . "vfoley@gmail.com") (:keywords "faces") (:url . "https://github.com/gnuvince/purp"))])
+ (purple-haze-theme . [(20141015 229) ((emacs (24 0))) "an overtly purple color theme for Emacs24." single ((:commit . "3e245cbef7cd09e6b3ee124963e372a04e9a6485") (:authors ("Jason Milkins" . "jasonm23@gmail.com")) (:maintainer "Jason Milkins" . "jasonm23@gmail.com") (:url . "https://github.com/jasonm23/emacs-purple-haze-theme"))])
+ (purty-mode . [(20131004 2259) nil "Safely pretty-print greek letters, mathematical symbols, or anything else." single ((:commit . "8eef77317a3bab07ade212353a50fbd3f20f365a") (:authors ("James Atwood" . "jatwood@cs.umass.edu")) (:maintainer "James Atwood" . "jatwood@cs.umass.edu"))])
+ (pushbullet . [(20140809 1232) ((grapnel (0 5 2)) (json (1 2))) "Emacs client for the PushBullet Android app" single ((:commit . "73c59a0f1dc04875b3e5a2c8afbc26c32128e445") (:authors ("Abhishek L" . "abhishek.lekshmanan@gmail.com")) (:maintainer "Abhishek L" . "abhishek.lekshmanan@gmail.com") (:keywords "convenience") (:url . "http://www.github.com/theanalyst/revolver"))])
+ (pushover . [(20170818 2103) ((cl-lib (0 5))) "Pushover API Access" single ((:commit . "bbe3ac8df3c532a72da4552615af960b8a577588") (:authors ("Samuel W. Flint" . "swflint@flintfam.org")) (:maintainer "Samuel W. Flint" . "swflint@flintfam.org") (:keywords "notifications") (:url . "http://github.com/swflint/pushover.el"))])
+ (px . [(20170317 2330) nil "preview inline latex in any mode" single ((:commit . "0c52f7933eab3ca1642ab0df151db9950430c9e2") (:authors ("Aurélien Aptel" . "aurelien.aptel@gmail.com")) (:maintainer "Aurélien Aptel" . "aurelien.aptel@gmail.com") (:url . "http://github.com/aaptel/preview-latex"))])
+ (py-autopep8 . [(20220502 310) ((emacs (26 1))) "Use autopep8 to beautify a Python buffer" single ((:commit . "89c9ed8de2deab6bb891ae25c85cc6498e60b90a") (:authors ("Friedrich Paetzk" . "f.paetzke@gmail.com")) (:maintainer "Friedrich Paetzk" . "f.paetzke@gmail.com") (:keywords "convenience") (:url . "https://github.com/ideasman42/emacs-py-autopep8"))])
+ (py-gnitset . [(20170821 1732) nil "Run your Python tests any way you'd like" single ((:commit . "1e993cc29cbc31e06fe1e335dec198e21972fa55") (:authors ("Brandon W Maister" . "quodlibetor@gmail.com")) (:maintainer "Brandon W Maister" . "quodlibetor@gmail.com") (:url . "https://www.github.com/quodlibetor/py-gnitset"))])
+ (py-import-check . [(20130802 1111) nil "Finds the unused python imports using importchecker" single ((:commit . "9787f87745a4234cd9bed711860b707902bc8ae4") (:authors ("Sibi" . "sibi@psibi.in")) (:maintainer "Sibi" . "sibi@psibi.in") (:keywords "python" "import" "check") (:url . "https://github.com/psibi/emacs-py-import-check"))])
+ (py-isort . [(20160925 1018) nil "Use isort to sort the imports in a Python buffer" single ((:commit . "e67306f459c47c53a65604e4eea88a3914596560") (:authors ("Friedrich Paetzke" . "paetzke@fastmail.fm")) (:maintainer "Friedrich Paetzke" . "paetzke@fastmail.fm") (:url . "http://paetzke.me/project/py-isort.el"))])
+ (py-smart-operator . [(20170531 1209) ((s (1 9 0))) "smart-operator for python-mode" single ((:commit . "0c8a66faca4b35158d0b5885472cb75286039167") (:authors ("Rustem Muslimov" . "r.muslimov@gmail.com")) (:maintainer "Rustem Muslimov" . "r.muslimov@gmail.com") (:keywords "python" "convenience" "smart-operator"))])
+ (py-test . [(20151117 622) ((dash (2 9 0)) (f (0 17)) (emacs (24 4))) "A test runner for Python code." single ((:commit . "3b2a0bdaacb54df6f2bee8317423e5c0d159d5cf") (:authors ("Bogdan Paul Popa" . "popa.bogdanp@gmail.com")) (:maintainer "Bogdan Paul Popa" . "popa.bogdanp@gmail.com") (:keywords "python" "testing" "py.test") (:url . "https://github.com/Bogdanp/py-test.el"))])
+ (py-yapf . [(20160925 1122) nil "Use yapf to beautify a Python buffer" single ((:commit . "a878304202ad827a1f3de3dce1badd9ca8731146") (:authors ("Friedrich Paetzke" . "f.paetzke@gmail.com")) (:maintainer "Friedrich Paetzke" . "f.paetzke@gmail.com") (:url . "https://github.com/paetzke/py-yapf.el"))])
+ (pycarddavel . [(20150831 1216) ((helm (1 7 0)) (emacs (24 0))) "Integrate pycarddav" single ((:commit . "a6d81ee4eb8309cd82f6082aeca68c5a015702a3") (:authors ("Damien Cassou" . "damien@cassou.me")) (:maintainer "Damien Cassou" . "damien@cassou.me") (:keywords "helm" "pyccarddav" "carddav" "message" "mu4e" "contacts"))])
+ (pycoverage . [(20200513 2047) ((emacs (24 3))) "Support for coverage stats on Python 2.X and 3" tar ((:commit . "3c69ed312121368f1b24cc04d54a29ce4ed4f743") (:authors ("matt harrison")) (:maintainer "matt harrison") (:keywords "project" "convenience") (:url . "https://github.com/mattharrison/pycoverage.el"))])
+ (pydoc . [(20211119 2211) nil "functional, syntax highlighted pydoc navigation" single ((:commit . "3aaffe41e1c5a9d53fbc1de02686c386fd002890") (:authors ("John Kitchin" . "jkitchin@andrew.cmu.edu")) (:maintainer "Brian J. Lopes" . "statmobile@gmail.com") (:keywords "pydoc" "python") (:url . "https://github.com/statmobile/pydoc"))])
+ (pyenv-mode . [(20200518 1521) ((pythonic (0 1 0))) "Integrate pyenv with python-mode" single ((:commit . "b818901b8eac0e260ced66a6a5acabdbf6f5ba99") (:authors ("Artem Malyshev" . "proofit404@gmail.com")) (:maintainer "Artem Malyshev" . "proofit404@gmail.com") (:url . "https://github.com/proofit404/pyenv-mode"))])
+ (pyenv-mode-auto . [(20180620 1252) ((pyenv-mode (0 1 0)) (s (1 11 0)) (f (0 17 0))) "Automatically activates pyenv version if .python-version file exists." single ((:commit . "347b94cd5ad22e33cc41be661c102d4548767858") (:authors ("Sviatoslav Bulbakha" . "mail@ssbb.me")) (:maintainer "Sviatoslav Bulbakha" . "mail@ssbb.me") (:keywords "python" "pyenv") (:url . "https://github.com/ssbb/pyenv-mode-auto"))])
+ (pygen . [(20161121 506) ((elpy (1 12 0)) (python-mode (6 2 2)) (dash (2 13 0))) "Python code generation using Elpy and Python-mode." single ((:commit . "9019ff44ba49d7295b1476530feab91fdadb084b") (:authors ("Jack Crawley <http://www.github.com/jackcrawley>")) (:maintainer "Jack Crawley <http://www.github.com/jackcrawley>") (:keywords "python" "code generation") (:url . "https://github.com/JackCrawley/pygen/"))])
+ (pygn-mode . [(20211021 2325) ((emacs (26 1)) (tree-sitter (0 15 2)) (tree-sitter-langs (0 10 7)) (uci-mode (0 5 4)) (nav-flash (1 0 0)) (ivy (0 10 0))) "Major-mode for chess PGN files, powered by Python" tar ((:commit . "eb1da7e3eb5f5754b60d404b0e341206eebe19ca") (:authors ("Dodge Coates and Roland Walker")) (:maintainer "Dodge Coates and Roland Walker") (:keywords "data" "games" "chess") (:url . "https://github.com/dwcoates/pygn-mode"))])
+ (pyim . [(20220505 643) ((emacs (25 1)) (async (1 6)) (xr (1 13))) "A Chinese input method support quanpin, shuangpin, wubi, cangjie and rime." tar ((:commit . "34a1140ddb824b1be727fdf994c3680b07990af4") (:authors ("Ye Wenbin" . "wenbinye@163.com") ("Feng Shu" . "tumashu@163.com")) (:maintainer "Feng Shu" . "tumashu@163.com") (:keywords "convenience" "chinese" "pinyin" "input-method") (:url . "https://github.com/tumashu/pyim"))])
+ (pyim-basedict . [(20210517 43) nil "The default pinyin dict of pyim" tar ((:commit . "86f6de3e3a1523eb278bd3afe7c4ceba2a0e2972") (:authors ("Feng Shu" . "tumashu@163.com")) (:maintainer "Feng Shu" . "tumashu@163.com") (:keywords "convenience" "chinese" "pinyin" "input-method" "complete") (:url . "https://github.com/tumashu/pyim-basedict"))])
+ (pyim-cangjiedict . [(20210617 934) ((pyim (3 7))) "Some cangjie dicts for pyim" tar ((:commit . "d17e3d32a6480939b350a91a915ebe8e6efad819") (:authors ("Yuanchen Xie" . "yuanchen.gm@gmail.com")) (:maintainer "Yuanchen Xie" . "yuanchen.gm@gmail.com") (:keywords "convenience" "chinese" "pinyin" "input-method" "complete") (:url . "https://github.com/p1uxtar/pyim-cangjiedict"))])
+ (pyim-smzmdict . [(20210505 1445) ((pyim (3 7))) "Sanma(triple) Zhengma dict for pyim" tar ((:commit . "fcddbde17a04d174c7353548056524687f7be8d2") (:authors ("Yue Shi (Zhizhi)")) (:maintainer "Yuanchen Xie") (:keywords "convenience" "i18n" "pyim" "chinese" "zhengma") (:url . "https://github.com/p1uxtar/pyim-smzmdict"))])
+ (pyim-wbdict . [(20210902 1714) ((pyim (3 7))) "Some wubi dicts for pyim" tar ((:commit . "4db1ca7fee75bd3aa394d620e5af2f42b3caf3c4") (:authors ("Feng Shu" . "tumashu@163.com")) (:maintainer "Feng Shu" . "tumashu@163.com") (:keywords "convenience" "chinese" "pinyin" "input-method" "complete") (:url . "https://github.com/tumashu/pyim-wbdict"))])
+ (pyimport . [(20180308 1752) ((dash (2 8 0)) (s (1 9 0)) (shut-up (0 3 2))) "Manage Python imports!" single ((:commit . "a6f63cf7ed93f0c0f7c207e6595813966f8852b9") (:authors ("Wilfred Hughes" . "me@wilfred.me.uk")) (:maintainer "Wilfred Hughes" . "me@wilfred.me.uk"))])
+ (pyimpsort . [(20160130 453) ((emacs (24 3))) "Sort python imports." tar ((:commit . "d5c61d70896b642646dfd3c809c06174ae086c1a") (:authors ("Mario Rodas" . "marsam@users.noreply.github.com")) (:maintainer "Mario Rodas" . "marsam@users.noreply.github.com") (:keywords "convenience") (:url . "https://github.com/emacs-pe/pyimpsort.el"))])
+ (pyinspect . [(20211102 1415) ((emacs (27 1))) "Python object inspector" tar ((:commit . "36cf624236c8b4cce852dd52b64d058d4d4a32fd") (:authors ("Maor Kadosh" . "git@avocadosh.xyz")) (:maintainer "Maor Kadosh" . "git@avocadosh.xyz") (:keywords "tools") (:url . "https://github.com/it-is-wednesday/pyinspect.el"))])
+ (pylint . [(20210411 1931) nil "minor mode for running `pylint'" single ((:commit . "12648fde32b7ed976666e5ff5b35171c0bd50150") (:authors ("Ian Eure" . "ian.eure@gmail.com")) (:maintainer "Jonathan Kotta" . "jpkotta@gmail.com") (:keywords "languages" "python"))])
+ (pynt . [(20180710 726) ((emacs (24 4)) (ein (0 13 1)) (epc (0 1 1)) (deferred (0 5 1))) "Generate and scroll EIN buffers from python code" single ((:commit . "86cf9ce78d34f92bfd0764c9cbb75427ebd429e6") (:authors ("Edward Banner" . "edward.banner@gmail.com")) (:maintainer "Edward Banner" . "edward.banner@gmail.com") (:keywords "convenience") (:url . "https://github.com/ebanner/pynt"))])
+ (pyramid . [(20210427 1032) ((emacs (25 2)) (pythonic (0 1 1)) (tablist (0 70))) "Minor mode for working with pyramid projects" tar ((:commit . "66f54f4a9cc9fa81edf768ab433d5b3c5517363c") (:authors ("Daniel Kraus" . "daniel@kraus.my")) (:maintainer "Daniel Kraus" . "daniel@kraus.my") (:keywords "python" "pyramid" "pylons" "convenience" "tools" "processes") (:url . "https://github.com/dakra/pyramid.el"))])
+ (pytest . [(20200330 41) ((s (1 9 0))) "Easy Python test running in Emacs" single ((:commit . "6934047242db79b1c53e9fe3e0734cc9719ed1c4") (:keywords "pytest" "python" "testing") (:url . "https://github.com/ionrock/pytest-el"))])
+ (pytest-pdb-break . [(20200804 848) ((emacs (25))) "A pytest PDB launcher" tar ((:commit . "fe4a43299a926223634c3b104b751397bb818019") (:authors ("Jane Soko" . "poppyschmo@protonmail.com")) (:maintainer "Jane Soko" . "poppyschmo@protonmail.com") (:keywords "languages" "tools") (:url . "https://github.com/poppyschmo/pytest-pdb-break"))])
+ (python-black . [(20211217 2037) ((emacs (25)) (dash (2 16 0)) (reformatter (0 3))) "Reformat Python using python-black" single ((:commit . "cc6919e758b5845b201e1cb08a9b5d9a2598a7f1") (:authors ("wouter bolsterlee" . "wouter@bolsterl.ee")) (:maintainer "wouter bolsterlee" . "wouter@bolsterl.ee") (:keywords "languages") (:url . "https://github.com/wbolster/emacs-python-black"))])
+ (python-cell . [(20220105 2315) ((emacs (25 1))) "Support for MATLAB-like cells in python mode" single ((:commit . "9a111dcee0cbb5922662bfecb37b6983b740950a") (:authors ("Thomas Hisch" . "t.hisch@gmail.com")) (:maintainer "Thomas Hisch" . "t.hisch@gmail.com") (:keywords "extensions" "python" "matlab" "cell") (:url . "https://github.com/thisch/python-cell.el"))])
+ (python-coverage . [(20211224 1420) ((emacs (25 1)) (dash (2 18 0)) (s (1 12 0)) (xml+ (1))) "Show Python coverage via overlays or Flycheck" single ((:commit . "a341615af03dbe3ce0ac9b63cf43dc01c1ae5ebe") (:authors ("wouter bolsterlee" . "wouter@bolsterl.ee")) (:maintainer "wouter bolsterlee" . "wouter@bolsterl.ee") (:keywords "languages" "processes" "tools") (:url . "https://github.com/wbolster/emacs-python-coverage"))])
+ (python-django . [(20150822 404) nil "A Jazzy package for managing Django projects" single ((:commit . "fc54ad74f0309670359b939f64d0f1fff68aeac4") (:authors ("Fabián E. Gallina" . "fabian@anue.biz")) (:maintainer "FSF") (:keywords "languages") (:url . "https://github.com/fgallina/python-django.el"))])
+ (python-docstring . [(20220308 22) nil "Smart Python docstring formatting" tar ((:commit . "01d0470498d08ce9d99dd4ce709c567229f857d2"))])
+ (python-environment . [(20150310 853) ((deferred (0 3 1))) "virtualenv API for Emacs Lisp" tar ((:commit . "401006584e32864a10c69d29f14414828909362e") (:authors ("Takafumi Arakaki <aka.tkf at gmail.com>")) (:maintainer "Takafumi Arakaki <aka.tkf at gmail.com>") (:keywords "applications" "tools"))])
+ (python-info . [(20151228 1852) nil "Python info manual for Emacs" tar ((:commit . "306f15441b54b25757cdfd3b327b84024ea21ed7"))])
+ (python-insert-docstring . [(20211127 1232) ((emacs (25 1))) "Python Google docstring inserter" single ((:commit . "cd6419b74c99c06d5c48c1b289572acce1fd193b") (:authors ("Marco Vocialta" . "macurovc@tutanota.com")) (:maintainer "Marco Vocialta" . "macurovc@tutanota.com") (:url . "https://github.com/macurovc/insert-docstring"))])
+ (python-isort . [(20210603 2153) ((emacs (26)) (reformatter (0 6))) "Reformat python-mode buffer with isort" single ((:commit . "339814df22b87eebca02137e581f65d6283fce97") (:authors ("Jimmy Yuen Ho Wong" . "wyuenho@gmail.com")) (:maintainer "Jimmy Yuen Ho Wong" . "wyuenho@gmail.com") (:keywords "languages") (:url . "https://github.com/wyuenho/emacs-python-isort"))])
+ (python-mls . [(20220128 1953) ((emacs (27 1))) "Multi-line shell for (i)Python" single ((:commit . "97e58c6b785f7096c0e02f6c1d12b008cc0219c1") (:authors ("J.D. Smith")) (:maintainer "J.D. Smith") (:keywords "languages" "processes") (:url . "https://github.com/jdtsmith/python-mls"))])
+ (python-mode . [(20220504 1829) nil "Python major mode" tar ((:commit . "f633c00233104d506fe2801d00f1430110ca5cdc") (:authors ("2015-2021 https://gitlab.com/groups/python-mode-devs") ("2003-2014 https://launchpad.net/python-mode") ("1995-2002 Barry A. Warsaw") ("1992-1994 Tim Peters")) (:maintainer nil . "python-mode@python.org") (:keywords "languages" "processes" "python" "oop") (:url . "https://gitlab.com/groups/python-mode-devs"))])
+ (python-pytest . [(20220502 1237) ((emacs (24 4)) (dash (2 18 0)) (transient (0 3 7)) (projectile (0 14 0)) (s (1 12 0))) "helpers to run pytest" single ((:commit . "5e72c343cb81866358e4437390c5eb84c3203440") (:authors ("wouter bolsterlee" . "wouter@bolsterl.ee")) (:maintainer "wouter bolsterlee" . "wouter@bolsterl.ee") (:keywords "pytest" "test" "python" "languages" "processes" "tools") (:url . "https://github.com/wbolster/emacs-python-pytest"))])
+ (python-switch-quotes . [(20161228 809) ((emacs (24 3))) "cycle between ' and \" quotes in python strings" single ((:commit . "93f1e9b40e061a6cea480139e8b1362b6404abd0") (:authors ("Vladimir Lagunov" . "lagunov.vladimir@gmail.com")) (:maintainer "Vladimir Lagunov" . "lagunov.vladimir@gmail.com") (:keywords "python" "tools" "convenience") (:url . "https://github.com/werehuman/python-switch-quotes"))])
+ (python-test . [(20181018 29) ((emacs (25 1))) "Python testing integration" single ((:commit . "f899975b133539e19ba822e4b0bfd1a28572967e") (:authors ("Mario Rodas" . "marsam@users.noreply.github.com")) (:maintainer "Mario Rodas" . "marsam@users.noreply.github.com") (:keywords "convenience" "tools" "processes") (:url . "https://github.com/emacs-pe/python-test.el"))])
+ (python-x . [(20190611 1303) ((python (0 24)) (folding (0)) (cl-lib (0 5))) "python.el extras for interactive evaluation" tar ((:commit . "b1f8eaccee210d7c0580dba6dc9bd361fcf3765d") (:authors ("Yuri D'Elia" . "wavexx@thregr.org")) (:maintainer "Yuri D'Elia" . "wavexx@thregr.org"))])
+ (pythonic . [(20210122 1247) ((emacs (25 1)) (s (1 9)) (f (0 17 2))) "Utility functions for writing pythonic emacs package." single ((:commit . "fe75bc17baae314bf8f5e0b12aad3fccfc6c5397") (:authors ("Artem Malyshev" . "proofit404@gmail.com")) (:maintainer "Artem Malyshev" . "proofit404@gmail.com") (:url . "https://github.com/proofit404/pythonic"))])
+ (pyvenv . [(20211014 707) nil "Python virtual environment interface" single ((:commit . "31ea715f2164dd611e7fc77b26390ef3ca93509b") (:authors ("Jorgen Schaefer" . "contact@jorgenschaefer.de")) (:maintainer "Jorgen Schaefer" . "contact@jorgenschaefer.de") (:keywords "python" "virtualenv" "tools") (:url . "http://github.com/jorgenschaefer/pyvenv"))])
+ (pyvenv-auto . [(20220315 1606) ((emacs (26 3)) (pyvenv (1 21))) "Automatically switch Python venvs" single ((:commit . "59ece8554bf249f30984c81c103a5704d2fb27bf") (:url . "https://github.com/nryotaro/pyvenv-auto"))])
+ (q-mode . [(20220306 1629) ((emacs (24))) "A q editing mode" single ((:commit . "3eac36d23131088e32057716a3241407fa8dc041") (:keywords "faces" "files" "q") (:url . "https://github.com/psaris/q-mode"))])
+ (qml-mode . [(20161016 31) nil "Major mode for editing QT Declarative (QML) code." single ((:commit . "6c5f33ba88ae010bf201a80ee8095e20a724558c") (:authors ("Yen-Chin Lee" . "coldnew.tw@gmail.com")) (:maintainer "Yen-Chin Lee" . "coldnew.tw@gmail.com") (:keywords "qml" "qt" "qt declarative") (:url . "https://github.com/coldnew/qml-mode"))])
+ (qrencode . [(20211010 1334) ((emacs (25 1))) "QRCode encoder" single ((:commit . "fe3a99ff8cbddcf5391458f356cecf2e8c3a2b84") (:authors ("Rüdiger Sonderfeld" . "ruediger@c-plusplus.net")) (:maintainer "Rüdiger Sonderfeld" . "ruediger@c-plusplus.net") (:keywords "qrcode" "comm") (:url . "https://github.com/ruediger/qrencode-el"))])
+ (qt-pro-mode . [(20170604 1841) ((emacs (24))) "Qt Pro/Pri major mode" single ((:commit . "7a2da323de834294b413cbbb3c92f42f54913643") (:authors ("Todd Neal" . "tolchz@gmail.com")) (:maintainer "Todd Neal" . "tolchz@gmail.com") (:keywords "extensions"))])
+ (qtcreator-theme . [(20201215 1523) ((emacs (24 3))) "A color theme that mimics Qt Creator IDE" single ((:commit . "515532b05063898459157d2ba5c10ec0d5a4b1bd") (:authors ("Lesley Lai" . "lesley@lesleylai.info")) (:maintainer "Lesley Lai" . "lesley@lesleylai.info") (:keywords "theme" "light" "faces") (:url . "https://github.com/LesleyLai/emacs-qtcreator-theme"))])
+ (quack . [(20181106 1301) nil "enhanced support for editing and running Scheme code" single ((:commit . "2146805ce2b5a9b155d73929986f11e713787e26"))])
+ (quarto-mode . [(20220405 1556) ((emacs (25 1)) (polymode (0 2 2)) (poly-markdown (0 2 2)) (markdown-mode (2 3)) (request (0 3 2))) "A (poly)mode for https://quarto.org" single ((:commit . "2a199735866dc34126a061c6f2990378b381e687") (:authors ("Carlos Scheidegger")) (:maintainer "Carlos Scheidegger") (:keywords "languages" "multi-modes") (:url . "https://github.com/quarto-dev/quarto-emacs"))])
+ (quasi-monochrome-theme . [(20200415 705) nil "Quasi Monochrome theme" tar ((:commit . "b38d71860fdea945e10e8a766ac9dfa1410ade67") (:authors ("Lorenzo Bolla" . "lbolla@gmail.com")) (:maintainer "Lorenzo Bolla" . "lbolla@gmail.com") (:keywords "color-theme" "monochrome" "high contrast") (:url . "https://github.com/lbolla/emacs-quasi-monochrome"))])
+ (quelpa . [(20211228 248) ((emacs (25 1))) "Emacs Lisp packages built directly from source" tar ((:commit . "54fc5b951f103fadba25dde38274964737815883") (:authors ("steckerhalter")) (:maintainer "steckerhalter") (:keywords "tools" "package" "management" "build" "source" "elpa") (:url . "https://github.com/quelpa/quelpa"))])
+ (quelpa-leaf . [(20210124 348) ((emacs (25 1)) (quelpa (1 0)) (leaf (4 1 0))) "Quelpa handler for leaf" single ((:commit . "e220893d29a095234076be1b255fade11f6410b8") (:authors ("Shen, Jen-Chieh" . "jcs090218@gmail.com")) (:maintainer "Shen, Jen-Chieh" . "jcs090218@gmail.com") (:url . "https://github.com/quelpa/quelpa-leaf"))])
+ (quelpa-use-package . [(20201022 746) ((emacs (25 1)) (quelpa (1 0)) (use-package (2))) "quelpa handler for use-package" single ((:commit . "d985c0326b66aa19581918deccdc5edcacccf953") (:authors ("steckerhalter")) (:maintainer "steckerhalter") (:keywords "package" "management" "elpa" "use-package") (:url . "https://github.com/quelpa/quelpa-use-package"))])
+ (quick-buffer-switch . [(20201027 2307) nil "Quick switch to file or dir buffers." single ((:commit . "da82555f286588f171eed1de151325bbdd8cbd91") (:authors ("Sebastien Gross <seb•ɑƬ•chezwam•ɖɵʈ•org>")) (:maintainer "Sebastien Gross <seb•ɑƬ•chezwam•ɖɵʈ•org>") (:keywords "emacs" "configuration"))])
+ (quick-peek . [(20200130 2059) ((emacs (24 3))) "Inline quick-peek windows" single ((:commit . "03a276086795faad46a142454fc3e28cab058b70") (:authors ("Clément Pit-Claudel" . "clement.pitclaudel@live.com")) (:maintainer "Clément Pit-Claudel" . "clement.pitclaudel@live.com") (:keywords "tools" "help" "doc" "convenience"))])
+ (quick-preview . [(20191017 1920) nil "quick preview using GNOME sushi, gloobus or quick look" single ((:commit . "a312ab5539b9a362da9d305e4da814e17c5721c9") (:authors ("myuhe <yuhei.maeda_at_gmail.com>")) (:maintainer "myuhe") (:keywords "files" "hypermedia") (:url . "https://github.com/myuhe/quick-preview.el"))])
+ (quick-shell-keybind . [(20171023 613) ((emacs (24))) "Interactively bind a key to shell commands" single ((:commit . "5f4541a5a5554d108bf16b5fd1713e962161ca1b") (:authors ("eyeinsky" . "eyeinsky9@gmail.com")) (:maintainer "eyeinsky" . "eyeinsky9@gmail.com") (:keywords "maint" "convenience" "processes") (:url . "https://github.com/eyeinsky/quick-shell-keybind"))])
+ (quickref . [(20170817 1232) ((dash (1 0 3)) (s (1 0 0))) "Display relevant notes-to-self in the echo area" single ((:commit . "f368c8b8219bb90498c5ab84e26f00eedaa234cf") (:authors ("Kyle Hargraves")) (:maintainer "Kyle Hargraves") (:url . "https://github.com/pd/quickref.el"))])
+ (quickrun . [(20210904 1553) ((emacs (24 3))) "Run commands quickly" single ((:commit . "30e9a1333fe4a83424385df53ddaf7016df3679d") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-quickrun"))])
+ (quiet . [(20200211 721) nil "Disconnect from the online world for a while" single ((:commit . "f8a4ef0be086f97e7fb631df7060f29cc4025b98") (:authors ("nik gaffney" . "nik@fo.am")) (:maintainer "nik gaffney" . "nik@fo.am") (:keywords "convenience" "quiet" "distraction" "network" "detachment" "offline") (:url . "https://github.com/zzkt/quiet"))])
+ (quilt . [(20190828 506) ((emacs (26 0))) "Minor mode for working with files in quilt" single ((:commit . "b56a1f1acc46cdf8655710e4c8f24f5f31f22c6a") (:authors ("Matt Mackall" . "mpm@selenic.com")) (:maintainer "Jan Stranik" . "jan@stranik.org") (:keywords "extensions") (:url . "https://github.com/jstranik/emacs-quilt"))])
+ (quiz . [(20190525 1206) ((cl-lib (0 5)) (emacs (25))) "Multiple choice quiz game" single ((:commit . "570bf53926d89282cdb9653bd5aa8fe968f92bbd") (:authors ("Dave Pearson" . "davep@davep.org")) (:maintainer "Dave Pearson" . "davep@davep.org") (:keywords "games" "trivia" "quiz") (:url . "https://github.com/davep/quiz.el"))])
+ (r-autoyas . [(20140101 1510) ((ess (0)) (yasnippet (0 8 0))) "Provides automatically created yasnippets for R function argument lists." tar ((:commit . "b4020ee7f5f895e0065b8b26da8a49c51432d530") (:authors ("Sven Hartenstein & Matthew Fidler")) (:maintainer "Matthew Fidler") (:keywords "r" "yasnippet") (:url . "https://github.com/mlf176f2/r-autoyas.el"))])
+ (racer . [(20210307 243) ((emacs (25 1)) (rust-mode (0 2 0)) (dash (2 13 0)) (s (1 10 0)) (f (0 18 2)) (pos-tip (0 4 6))) "code completion, goto-definition and docs browsing for Rust via racer" single ((:commit . "1e63e98626737ea9b662d4a9b1ffd6842b1c648c") (:authors ("Phil Dawes")) (:maintainer "Phil Dawes") (:keywords "abbrev" "convenience" "matching" "rust" "tools") (:url . "https://github.com/racer-rust/emacs-racer"))])
+ (racket-mode . [(20220505 1350) ((emacs (25 1))) "Racket editing, REPL, and more" tar ((:commit . "fbb4a4664e2cc2b5d21eee62735f73b7f0272e60") (:authors ("Greg Hendershott")) (:maintainer "Greg Hendershott") (:url . "https://www.racket-mode.com/"))])
+ (rails-i18n . [(20220126 1643) ((emacs (27 2)) (yaml (0 1 0)) (dash (2 19 1))) "Seach and insert i18n on ruby code" single ((:commit . "8e87e4e48e31902b8259ded28a208c2e7efea6e9") (:authors ("Otávio Schwanck dos Santos" . "otavioschwanck@gmail.com")) (:maintainer "Otávio Schwanck dos Santos" . "otavioschwanck@gmail.com") (:keywords "tools" "languages") (:url . "https://github.com/otavioschwanck/rails-i18n.el"))])
+ (rails-log-mode . [(20140408 425) nil "Major mode for viewing Rails log files" single ((:commit . "ff440003ad7d47cb0ac3300f2a632f4cfd36a446") (:authors ("Anantha kumaran" . "ananthakumaran@gmail.com")) (:maintainer "Anantha kumaran" . "ananthakumaran@gmail.com") (:keywords "rails" "log"))])
+ (rails-routes . [(20220126 1631) ((emacs (27 2)) (inflections (1 1))) "Search for and insert rails routes" single ((:commit . "eab995a9297ca5bd9bd4f4c2737f2fecfc36def0") (:authors ("Otávio Schwanck" . "otavioschwanck@gmail.com")) (:maintainer "Otávio Schwanck" . "otavioschwanck@gmail.com") (:keywords "tools" "languages") (:url . "https://github.com/otavioschwanck/rails-routes"))])
+ (railscasts-reloaded-theme . [(20190308 759) nil "Railscasts Reloaded color theme" single ((:commit . "1c3850568e60a555d59cbb57bf2b6aa06e99d454") (:authors ("George Thomas" . "iamgeorgethomas@gmail.com")) (:maintainer "George Thomas" . "iamgeorgethomas@gmail.com") (:url . "https://github.com/thegeorgeous/railscasts-reloaded-theme"))])
+ (railscasts-theme . [(20150219 1525) nil "Railscasts color theme for GNU Emacs." single ((:commit . "1340c3f6c2717761cab95617cf8dcbd962b1095b") (:authors ("Oleg Shaldybin")) (:maintainer "Oleg Shaldybin") (:keywords "railscasts" "color" "theme") (:url . "https://github.com/mikenichols/railscasts-theme"))])
+ (rainbow-blocks . [(20210715 1518) nil "Block syntax highlighting for lisp code" single ((:commit . "83c4d6e77a1e25d3d2d124a4e90d5b084f3e15a5") (:authors ("istib")) (:maintainer "istib") (:url . "https://github.com/istib/rainbow-blocks"))])
+ (rainbow-delimiters . [(20210515 1254) nil "Highlight brackets according to their depth" single ((:commit . "a32b39bdfe6c61c322c37226d66e1b6d4f107ed0") (:authors ("Jeremy Rayman" . "opensource@jeremyrayman.com") ("Fanael Linithien" . "fanael4@gmail.com")) (:maintainer "Fanael Linithien" . "fanael4@gmail.com") (:keywords "faces" "convenience" "lisp" "tools") (:url . "https://github.com/Fanael/rainbow-delimiters"))])
+ (rainbow-fart . [(20220427 2227) ((emacs (25 1)) (flycheck (32 -4))) "Checks the keywords of code to play suitable sounds" tar ((:commit . "6504424707b6e9101dfbd9fdd4b7b963b9a4f323") (:keywords "tools") (:url . "https://repo.or.cz/emacs-rainbow-fart.git"))])
+ (rainbow-identifiers . [(20141102 1526) ((emacs (24))) "Highlight identifiers according to their names" single ((:commit . "19fbfded1baa98d12335f26f6d7b20e5ae44ce2e") (:authors ("Fanael Linithien" . "fanael4@gmail.com")) (:maintainer "Fanael Linithien" . "fanael4@gmail.com") (:url . "https://github.com/Fanael/rainbow-identifiers"))])
+ (rake . [(20220211 827) ((f (0 13 0)) (dash (1 5 0)) (cl-lib (0 5))) "Run rake commands" single ((:commit . "452ea0caca33376487103c64177c295ed2960cca") (:authors ("Adam Sokolnicki" . "adam.sokolnicki@gmail.com")) (:maintainer "Adam Sokolnicki" . "adam.sokolnicki@gmail.com") (:keywords "rake" "ruby") (:url . "https://github.com/asok/rake.el"))])
+ (raku-mode . [(20210927 1227) ((emacs (24 4))) "Major mode for editing Raku code" tar ((:commit . "977b14a7c1295ebf2aad2f807d3f8e7c27aeb47f") (:authors ("Hinrik Örn Sigurðsson" . "hinrik.sig@gmail.com")) (:maintainer "Hinrik Örn Sigurðsson" . "hinrik.sig@gmail.com") (:keywords "languages") (:url . "https://github.com/hinrik/perl6-mode"))])
+ (rally-mode . [(20161114 354) ((popwin (1 0 0))) "a mode to interact with the Rally Software web site." single ((:commit . "0f5e09a6abe2de7613f174b4f54863df93343134") (:authors ("Sean LeBlanc" . "seanleblanc@gmail.com")) (:maintainer "Sean LeBlanc" . "seanleblanc@gmail.com") (:keywords "rally" "ca" "agile") (:url . "https://pragcraft.wordpress.com/"))])
+ (rand-theme . [(20151219 2335) ((cl-lib (0 5))) "Random Emacs theme at start-up!" single ((:commit . "65a00e5c5150f857aa96803b68f50bc8da0215b7") (:authors ("Daniel Gopar")) (:maintainer "Daniel Gopar") (:url . "https://github.com/gopar/rand-theme"))])
+ (random-splash-image . [(20151003 130) nil "Randomly sets splash image to *GNU Emacs* buffer on startup." single ((:commit . "53a39ebfd8ac6be066a652a508a717870f94218a") (:authors ("kakakaya <kakakaya AT gmail.com>")) (:maintainer "kakakaya <kakakaya AT gmail.com>") (:keywords "games") (:url . "https://github.com/kakakaya/random-splash-image"))])
+ (ranger . [(20210125 330) ((emacs (24 4))) "Make dired more like ranger" single ((:commit . "2498519cb21dcd5791d240607a72a204d1761668") (:authors ("Rich Alesi <https://github.com/ralesi>")) (:maintainer "Rich Alesi <https://github.com/ralesi>") (:keywords "files" "convenience" "dired") (:url . "https://github.com/ralesi/ranger"))])
+ (rase . [(20120928 2045) nil "Run At Sun Event daemon" single ((:commit . "59b5f7e8102570b65040e8d55781c7ea28de7338") (:authors ("Andrey Kotlarski" . "m00naticus@gmail.com")) (:maintainer "Andrey Kotlarski" . "m00naticus@gmail.com") (:keywords "solar" "sunrise" "sunset" "midday" "midnight") (:url . "https://github.com/m00natic/rase/"))])
+ (rats . [(20170818 1013) ((s (1 10 0)) (go-mode (1 3 1)) (cl-lib (0 5))) "Rapid testing suite for Go" single ((:commit . "a6d55aebcc54f669c6c6ffedf84364c4097903cc") (:authors ("Antoine Kalmbach" . "ane@iki.fi")) (:maintainer "Antoine Kalmbach" . "ane@iki.fi") (:keywords "go"))])
+ (rbenv . [(20141120 749) nil "Emacs integration for rbenv" single ((:commit . "2ea1a5bdc1266caef1dd77700f2c8f42429b03f1") (:authors ("Yves Senn" . "yves.senn@gmail.com")) (:maintainer "Yves Senn" . "yves.senn@gmail.com") (:keywords "ruby" "rbenv") (:url . "https://github.com/senny/rbenv.el"))])
+ (rbs-mode . [(20210430 135) ((emacs (24 5))) "A major mode for RBS" single ((:commit . "fd766a943d5f1f0624e10ffce096b9aaba14a5f4") (:authors ("Masafumi Koba")) (:maintainer "Masafumi Koba") (:keywords "languages") (:url . "https://github.com/ybiquitous/rbs-mode"))])
+ (rbt . [(20170202 2302) ((popup (0 5 3)) (magit (20160128 1201))) "Integrate reviewboard with emacs." single ((:commit . "32bfba9062a014e375451cf4203c29535b5efc1e") (:authors ("Joe Heyming" . "joeheyming@gmail.com")) (:maintainer "Joe Heyming" . "joeheyming@gmail.com") (:keywords "reviewboard" "rbt"))])
+ (rbtagger . [(20211026 2318) ((emacs (25 1))) "Ruby tagging tools" tar ((:commit . "351c4006ddacc2f66e6ff8c79d981613e9a8bd22") (:authors ("Thiago Araújo" . "thiagoaraujos@gmail.com")) (:maintainer "Thiago Araújo" . "thiagoaraujos@gmail.com") (:keywords "languages" "tools") (:url . "https://www.github.com/thiagoa/rbtagger"))])
+ (rc-mode . [(20160913 1918) nil "Major mode for the Plan9 rc shell" single ((:commit . "fe2e0570bf9c19a292e16b18fd4b0a256df5d93f") (:authors ("Jordan Brown")) (:maintainer "Jordan Brown") (:keywords "rc" "plan9" "shell") (:url . "https://github.com/mrhmouse/rc-mode.el"))])
+ (rcirc-alert . [(20141127 1047) nil "Configurable alert messages on top of RCIRC" tar ((:commit . "0adf8ff9c47023fec578f678424be62b0f49057f") (:maintainer "Cayetano Santos") (:keywords "lisp" "rcirc" "irc" "alert" "awesome"))])
+ (rcirc-alertify . [(20140407 119) ((alert (20140406 1353))) "Cross platform notifications for rcirc" single ((:commit . "ea5cafc55893f375eccbe013d12dbaa94bf6e259") (:authors ("Fabián Ezequiel Gallina" . "fgallina@gnu.org")) (:maintainer "Fabián Ezequiel Gallina" . "fgallina@gnu.org") (:keywords "comm" "convenience"))])
+ (rcirc-groups . [(20170731 2101) nil "an emacs buffer in rcirc-groups major mode" single ((:commit . "b68ece9d219b909244d4e3c0d8bf6a746d6fead7") (:authors ("Dimitri Fontaine" . "dim@tapoueh.org")) (:maintainer "Dimitri Fontaine" . "dim@tapoueh.org") (:keywords "comm" "convenience") (:url . "http://tapoueh.org/emacs/rcirc-groups.html"))])
+ (rcirc-notify . [(20150219 2204) nil "libnotify popups" single ((:commit . "841a7b5a6cdb0c11a812df924d2c6a7d364fd455") (:authors ("Will Farrington, Alex Schroeder <alex@gnu.org>, Nic Ferrier" . "nferrier@ferrier.me.uk")) (:maintainer "Nic Ferrier" . "nferrier@ferrier.me.uk") (:keywords "lisp" "rcirc" "irc" "notify" "growl"))])
+ (rcirc-styles . [(20210414 1712) ((cl-lib (0 5))) "support mIRC-style color and attribute codes" single ((:commit . "dd06ec5fa455131788bbc885fcfaaec16b08f13b"))])
+ (rdf-prefix . [(20211209 1952) nil "Prefix lookup for RDF" single ((:commit . "fa4b64bc3e0c1d5b8eed20df8d2daf0dffff2332") (:authors ("Simen Heggestøyl" . "simenheg@gmail.com")) (:maintainer "Simen Heggestøyl" . "simenheg@gmail.com") (:keywords "convenience" "abbrev") (:url . "https://github.com/simenheg/rdf-prefix"))])
+ (rdxmk . [(20170630 134) nil "A small set of tools for redox developments" tar ((:commit . "e78749fb29738365ffa4d863ffabeb969ebb0bcf") (:authors ("Jacob Salzberg" . "jsalzbergedu@yahoo.com")) (:maintainer "Jacob Salzberg" . "jsalzbergedu@yahoo.com") (:keywords "redox" "convenience" "tools") (:url . "https://github.com/jsalzbergedu/rdxmk"))])
+ (react-snippets . [(20210430 1510) ((yasnippet (0 7 0))) "Yasnippets for React" tar ((:commit . "969c21734dab638057fe9e284f6a51edcc3407c9") (:authors ("John Mastro" . "john.b.mastro@gmail.com")) (:maintainer "John Mastro" . "john.b.mastro@gmail.com") (:keywords "snippets"))])
+ (read-aloud . [(20160923 500) ((emacs (24 4))) "A simple interface to TTS engines" single ((:commit . "c662366226abfb07204ab442b4f853ed85438d8a") (:authors ("Alexander Gromnitsky" . "alexander.gromnitsky@gmail.com")) (:maintainer "Alexander Gromnitsky" . "alexander.gromnitsky@gmail.com") (:keywords "multimedia") (:url . "https://github.com/gromnitsky/read-aloud.el"))])
+ (read-only-cfg . [(20210717 205) ((emacs (24 3))) "Make files read-only based on user config" single ((:commit . "a4e50d4fbf48970e98b2464e13f46e51a4c43c37") (:authors ("pfchen" . "pfchen31@gmail.com")) (:maintainer "pfchen" . "pfchen31@gmail.com") (:keywords "tools" "convenience") (:url . "https://github.com/pfchen/read-only-cfg"))])
+ (readline-complete . [(20150708 1437) nil "offers completions in shell mode" single ((:commit . "30c020c37b2741160cc37e656e13c85d826a0ebf") (:authors ("Christopher Monsanto" . "chris@monsan.to")) (:maintainer "Christopher Monsanto" . "chris@monsan.to"))])
+ (real-auto-save . [(20200505 1537) ((emacs (24 4))) "Automatically save your buffers/files at regular intervals" single ((:commit . "481a2d1460ab5a9b6df3721dda76ad515923bfd1") (:authors ("Chaoji Li <lichaoji AT gmail DOT com>") ("Anand Reddy Pandikunta <anand21nanda AT gmail DOT com>")) (:maintainer "Chaoji Li <lichaoji AT gmail DOT com>") (:url . "https://github.com/ChillarAnand/real-auto-save"))])
+ (realgud . [(20211107 2210) ((load-relative (1 3 1)) (loc-changes (1 2)) (test-simple (1 3 0)) (emacs (25))) "A modular front-end for interacting with external debuggers" tar ((:commit . "3c88611c4ed59069093187c2a039b8d05cbe53e8") (:authors ("Rocky Bernstein" . "rocky@gnu.org")) (:maintainer "Rocky Bernstein" . "rocky@gnu.org") (:keywords "debugger" "gdb" "python" "perl" "go" "bash" "zsh" "bashdb" "zshdb" "remake" "trepan" "perldb" "pdb") (:url . "https://github.com/realgud/realgud/"))])
+ (realgud-byebug . [(20190520 1140) ((realgud (1 4 5)) (load-relative (1 2)) (cl-lib (0 5)) (emacs (24))) "Realgud front-end to the Ruby byebug debugger" tar ((:commit . "f8f20b92c6b13f75cc9797921c0e28d3def48b1c") (:authors ("Rocky Bernstein")) (:maintainer "Rocky Bernstein") (:url . "http://github.com/rocky/realgud-byebug"))])
+ (realgud-ipdb . [(20200722 1116) ((realgud (1 5 0)) (load-relative (1 3 1)) (emacs (25))) "Realgud front-end to ipdb" tar ((:commit . "f18f907aa4ddd3e59dc19ca296d4ee2dc5e436b0") (:authors ("Rocky Bernstein" . "rocky@gnu.org")) (:maintainer "Rocky Bernstein" . "rocky@gnu.org") (:url . "https://github.com/realgud/realgud-ipdb"))])
+ (realgud-jdb . [(20200722 1120) ((realgud (1 5 0)) (load-relative (1 3 1)) (emacs (25))) "Realgud front-end to Java's jdb debugger\"" tar ((:commit . "1c183b2f8aae0de60942ea01444b896bf182c66a") (:authors ("Rocky Bernstein" . "rocky@gnu.org")) (:maintainer "Rocky Bernstein" . "rocky@gnu.org") (:url . "https://github.com/realgud/realgud-jdb"))])
+ (realgud-lldb . [(20220419 2006) ((load-relative (1 3 1)) (realgud (1 5 0)) (emacs (25))) "Realgud front-end to lldb" tar ((:commit . "19a2c0a8b228af543338f3a8e51141a9e23484a5") (:authors ("Rocky Bernstein" . "rocky@gnu.org")) (:maintainer "Rocky Bernstein" . "rocky@gnu.org") (:url . "http://github.com/realgud/realgud-lldb"))])
+ (realgud-node-debug . [(20190525 1634) ((realgud (1 4 5)) (load-relative (1 2)) (cl-lib (0 5)) (emacs (25))) "Realgud front-end to older \"node debug\"" tar ((:commit . "72e786359ce9dace1796b0d81a00e9340e9c90ad") (:authors ("Rocky Bernstein" . "rocky@gnu.org")) (:maintainer "Rocky Bernstein" . "rocky@gnu.org") (:url . "http://github.com/realgud/realgud-node-debug"))])
+ (realgud-node-inspect . [(20190523 1251) ((realgud (1 4 5)) (load-relative (1 2)) (cl-lib (0 5)) (emacs (24))) "Realgud front-end to newer \"node inspect\"" tar ((:commit . "c3ed48cf3bc2b28f9fd23bcf60ea13a3cf019fc8") (:authors ("Rocky Bernstein" . "rocky@gnu.org")) (:maintainer "Rocky Bernstein" . "rocky@gnu.org") (:url . "http://github.com/realgud/realgud-node-inspect"))])
+ (realgud-old-debuggers . [(20190520 1150) ((realgud (1 4 5)) (load-relative (1 2)) (cl-lib (0 5)) (emacs (24))) "Realgud front-end to older lesser-used debuggers" tar ((:commit . "0fad38283e885c452160232e01adf3f6ae51983b") (:authors ("Rocky Bernstein")) (:maintainer "Rocky Bernstein") (:url . "http://github.com/rocky/realgud-old-debuggers"))])
+ (realgud-pry . [(20201011 1815) ((realgud (1 4 5)) (load-relative (1 2)) (cl-lib (0 5)) (emacs (25))) "Realgud front-end to the Ruby pry debugger" tar ((:commit . "264ca6811b0bef5de4decc54acfeacf0bce2f51f") (:authors ("Rocky Bernstein")) (:maintainer "Rocky Bernstein") (:url . "http://github.com/rocky/realgud-pry"))])
+ (realgud-rdb2 . [(20190520 1146) ((realgud (1 4 5)) (load-relative (1 2)) (cl-lib (0 5)) (emacs (24))) "Realgud front-end for interacting with Ruby debugger2" tar ((:commit . "3594aa74f7afda3c3251bb2af7fe0e8ec6d621ae") (:authors ("Rocky Bernstein")) (:maintainer "Rocky Bernstein") (:url . "http://github.com/rocky/realgud-ruby-debugger2"))])
+ (realgud-trepan-ni . [(20210513 2237) ((load-relative (1 2)) (realgud (1 5 0)) (emacs (25))) "Realgud front-end to trepan-ni" tar ((:commit . "0ec088ea343835e24ae73da09bea96bfb02a3130") (:authors ("Rocky Bernstein" . "rocky@gnu.org")) (:maintainer "Rocky Bernstein" . "rocky@gnu.org") (:url . "https://github.com/realgud/realgud-trepan-ni"))])
+ (reaper . [(20220426 2048) ((emacs (26 2))) "Interact with Harvest time tracking app" single ((:commit . "2cfe54e9f5470415ab5f59d3c0829bfce41525ad") (:authors ("Thomas Fini Hansen" . "xen@xen.dk")) (:maintainer "Thomas Fini Hansen" . "xen@xen.dk") (:keywords "tools") (:url . "https://github.com/xendk/reaper"))])
+ (reason-mode . [(20200929 1606) ((emacs (24 3))) "A major mode for editing ReasonML" tar ((:commit . "5690544a7091630e0ea0023bbbd57a733cea8bde") (:authors ("Mozilla")) (:maintainer "Mozilla") (:keywords "languages" "ocaml") (:url . "https://github.com/reasonml-editor/reason-mode"))])
+ (reazon . [(20211229 1733) ((emacs (26))) "miniKanren for Emacs" tar ((:commit . "f31c8b2e911c5885551d063c0a2b5de49a646eb1") (:authors ("Nick Drozd" . "nicholasdrozd@gmail.com")) (:maintainer "Nick Drozd" . "nicholasdrozd@gmail.com") (:keywords "languages" "extensions" "lisp") (:url . "https://github.com/nickdrozd/reazon"))])
+ (rebecca-theme . [(20180324 821) ((emacs (24))) "Rebecca Purple Theme" single ((:commit . "4b8b5aae9099185e07c2b4cac4943c7f66a3f003") (:authors ("vic" . "vborja@apache.org")) (:maintainer "vic" . "vborja@apache.org") (:keywords "theme" "dark") (:url . "https://github.com/vic/rebecca-theme"))])
+ (rebox2 . [(20121113 1300) nil "Handling of comment boxes in various styles." single ((:commit . "00634eca420cc48657b81e40e599ff8548083985") (:authors ("François Pinard") ("Le Wang")) (:maintainer "Le Wang (lewang.emacs!!!gmayo.com remove exclamations, correct host, hint: google mail)") (:url . "https://github.com/lewang/rebox2"))])
+ (recentf-ext . [(20170926 35) nil "Recentf extensions" single ((:commit . "450de5f8544ed6414e88d4924d7daa5caa55b7fe") (:authors ("rubikitch" . "rubikitch@ruby-lang.org")) (:maintainer "rubikitch" . "rubikitch@ruby-lang.org") (:keywords "convenience" "files") (:url . "http://www.emacswiki.org/cgi-bin/wiki/download/recentf-ext.el"))])
+ (recentf-remove-sudo-tramp-prefix . [(20210509 43) ((emacs (24 4))) "Normalise recentf history" single ((:commit . "c462344739867f35d39c8794c358b4c4b5af7dcc") (:authors ("ncaq" . "ncaq@ncaq.net")) (:maintainer "ncaq" . "ncaq@ncaq.net") (:url . "https://github.com/ncaq/recentf-remove-sudo-tramp-prefix"))])
+ (recently . [(20210930 159) ((cl-lib (0 5)) (emacs (24))) "Track recently opened files to visit them again" single ((:commit . "94b31f6bf1dab6af942948fec975e37424938a62") (:authors ("10sr <8.slashes [at] gmail [dot] com>")) (:maintainer "10sr <8.slashes [at] gmail [dot] com>") (:keywords "utility" "files") (:url . "https://github.com/10sr/recently-el"))])
+ (recompile-on-save . [(20151126 1446) ((dash (1 1 0)) (cl-lib (0 5))) "Trigger recompilation on file save." single ((:commit . "92e11446869d878803d4f3dec5d2101380c12bb2") (:authors ("Marian Schubert" . "marian.schubert@gmail.com")) (:maintainer "Marian Schubert" . "marian.schubert@gmail.com") (:keywords "convenience" "files" "processes" "tools") (:url . "https://github.com/maio/recompile-on-save.el"))])
+ (recomplete . [(20220211 548) ((emacs (26 1))) "Immediately (re)complete actions" single ((:commit . "d0d380929460ff35534900e34ababad43d23c966") (:authors ("Campbell Barton" . "ideasman42@gmail.com")) (:maintainer "Campbell Barton" . "ideasman42@gmail.com") (:url . "https://gitlab.com/ideasman42/emacs-recomplete"))])
+ (recover-buffers . [(20171009 437) nil "revisit all buffers from an auto-save file" tar ((:commit . "81a5cb53099955ebc2a411a44cba5a394ee3f2d1") (:authors ("era eriksson <http://www.iki.fi/era>")) (:maintainer "era eriksson <http://www.iki.fi/era>"))])
+ (rect+ . [(20150621 44) nil "Extensions to rect.el" single ((:commit . "299b742faa0bc4448e0d5fe9cb98ab1eb93b8dcc") (:authors ("Masahiro Hayashi" . "mhayashi1120@gmail.com")) (:maintainer "Masahiro Hayashi" . "mhayashi1120@gmail.com") (:keywords "extensions" "data" "tools") (:url . "https://github.com/mhayashi1120/Emacs-rectplus"))])
+ (rectangle-utils . [(20190411 1757) ((emacs (24)) (cl-lib (0 5))) "Some useful rectangle functions." single ((:commit . "46f7e73340fee40c1ab9a4e766a08ae3fce83ebe") (:authors ("Thierry Volpiatto" . "thierry.volpiatto@gmail.com")) (:maintainer "Thierry Volpiatto" . "thierry.volpiatto@gmail.com") (:url . "https://github.com/thierryvolpiatto/rectangle-utils"))])
+ (recur . [(20211108 219) ((emacs (24 3))) "Tail call optimization" single ((:commit . "627d88f2695336245527fcc77f5728575ecf742b") (:authors ("ROCKTAKEY" . "rocktakey@gmail.com")) (:maintainer "ROCKTAKEY" . "rocktakey@gmail.com") (:keywords "lisp") (:url . "https://github.com/ROCKTAKEY/recur"))])
+ (recursion-indicator . [(20220403 1812) ((emacs (27 1))) "Recursion indicator" single ((:commit . "63d946c5cb11b81184151f1385efed325f6cac2d") (:authors ("Daniel Mendler")) (:maintainer "Daniel Mendler") (:url . "https://github.com/minad/recursion-indicator"))])
+ (recursive-narrow . [(20190306 1521) nil "narrow-to-region that operates recursively" single ((:commit . "5e3e2067d5a148d7e64e64e0355d3b6860e4c259") (:authors ("Nathaniel Flath" . "flat0103@gmail.com")) (:maintainer "Nathaniel Flath" . "flat0103@gmail.com") (:url . "http://github.com/nflath/recursive-narrow"))])
+ (redacted . [(20220108 1037) ((emacs (25 1))) "Obscure text in buffer" single ((:commit . "c4ea6cbffda9c67af112f25b2db2843aa4abce85") (:authors ("Benjamin Kästner" . "benjamin.kaestner@gmail.com")) (:maintainer "Benjamin Kästner" . "benjamin.kaestner@gmail.com") (:keywords "games") (:url . "https://github.com/bkaestner/redacted.el"))])
+ (reddigg . [(20220312 1339) ((emacs (26 3)) (promise (1 1)) (ht (2 3)) (request (0 3 0)) (org (9 2))) "A reader for redditt" single ((:commit . "911a1c6310b42226392fd03dc1746a4c6fc4eb95") (:authors ("Thanh Vuong" . "thanhvg@gmail.com")) (:maintainer "Thanh Vuong" . "thanhvg@gmail.com") (:url . "https://github.com/thanhvg/emacs-reddigg"))])
+ (redis . [(20220429 1758) ((emacs (24)) (cl-lib (0 5))) "Redis integration" single ((:commit . "a6ad30d6a43b7be083c13f8725b45571d623001a") (:authors ("Mario Rodas" . "marsam@users.noreply.github.com")) (:maintainer "Mario Rodas" . "marsam@users.noreply.github.com") (:keywords "convenience") (:url . "https://github.com/emacs-pe/redis.el"))])
+ (redpen-paragraph . [(20160625 1050) ((emacs (24)) (cl-lib (0 5)) (json (1 4))) "RedPen interface." single ((:commit . "0062f326106ce8be3c9b7d3fa0e88ed2c7bbfa5e") (:authors ("karronoli")) (:maintainer "karronoli") (:keywords "document" "proofreading" "help") (:url . "https://github.com/karronoli/redpen-paragraph.el"))])
+ (redprl . [(20180418 1434) ((emacs (24 3))) "Major mode for editing RedPRL proofs and interacting with RedPRL" single ((:commit . "c72190de76f7ed1cfbe1d2046c96e99ac5022b0c") (:authors ("Jonathan Sterling" . "jon@jonmsterling.com")) (:maintainer "Jonathan Sterling" . "jon@jonmsterling.com") (:keywords "languages"))])
+ (redshank . [(20180730 407) ((paredit (21))) "Common Lisp Editing Extensions" tar ((:commit . "d059c5841044aa163664f8bf87c1d981bf0a04fe") (:authors ("Michael Weber" . "michaelw@foldr.org")) (:maintainer "Michael Weber" . "michaelw@foldr.org") (:keywords "languages" "lisp"))])
+ (redtick . [(20180424 2136) ((emacs (24 4))) "Smallest pomodoro timer (1 char)" tar ((:commit . "94b4cd43ac20c64dcac96edac2c1a3b9fcc59bb9") (:authors ("F. Febles")) (:maintainer "F. Febles") (:keywords "calendar") (:url . "http://github.com/ferfebles/redtick"))])
+ (redtt . [(20181121 21) ((emacs (25 3))) "Major mode for editing redtt proofs" single ((:commit . "ae76658873a647eb43d8cf84365a9d68e9a3273c") (:authors ("Jonathan Sterling" . "jon@jonmsterling.com")) (:maintainer "Jonathan Sterling" . "jon@jonmsterling.com") (:keywords "languages") (:url . "http://github.com/RedPRL/redtt"))])
+ (refine . [(20200507 731) ((emacs (24 3)) (s (1 11 0)) (dash (2 12 0)) (list-utils (0 4 4)) (loop (1 2))) "interactive value editing" single ((:commit . "d72fa50910b86217a35bb1b7e56adea206052021") (:authors ("Wilfred Hughes" . "me@wilfred.me.uk")) (:maintainer "Wilfred Hughes" . "me@wilfred.me.uk") (:keywords "convenience"))])
+ (reformatter . [(20210831 1405) ((emacs (24 3))) "Define commands which run reformatters on the current buffer" single ((:commit . "452a99b556ebf1953f92fe3e16c20d10d1fed466") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:keywords "convenience" "tools") (:url . "https://github.com/purcell/emacs-reformatter"))])
+ (regex-dsl . [(20220125 506) nil "lisp syntax for regexps" single ((:commit . "8802555ecdab8b50bb64181798497c10cdb5034b") (:authors ("Aliaksey Kandratsenka" . "alk@tut.by")) (:maintainer "Aliaksey Kandratsenka" . "alk@tut.by"))])
+ (regex-tool . [(20170104 1918) nil "A regular expression evaluation tool for programmers" single ((:commit . "0b4a0111143c88ef94bec56624cb2e00c1a054e6") (:authors ("John Wiegley" . "johnw@newartisans.com")) (:maintainer "John Wiegley" . "johnw@newartisans.com") (:keywords "regex" "languages" "programming" "development") (:url . "http://www.newartisans.com/"))])
+ (region-bindings-mode . [(20140407 2214) nil "Enable custom bindings when mark is active." single ((:commit . "3fa5dbdbd7c000bebff6d9d14a4be326ec24b6fc") (:authors ("Fabián E. Gallina" . "fabian@anue.biz")) (:maintainer "Fabián E. Gallina" . "fabian@anue.biz") (:keywords "convenience") (:url . "https://github.com/fgallina/region-bindings-mode"))])
+ (region-convert . [(20210519 1655) ((emacs (24 3))) "Convert string in region by Lisp function" single ((:commit . "cb3ab0417d7b74e5edd34bf23a70737fc7bf1d3a") (:authors ("USAMI Kenta" . "tadsan@zonu.me")) (:maintainer "USAMI Kenta" . "tadsan@zonu.me") (:keywords "region" "convenience") (:url . "https://github.com/zonuexe/right-click-context"))])
+ (region-occurrences-highlighter . [(20200815 1555) ((emacs (24))) "Mark occurrences of current region (selection)." single ((:commit . "07e2201db7a88b246a63e868e711749e1465d3d6") (:authors ("Álvaro González Sotillo" . "alvarogonzalezsotillo@gmail.com")) (:maintainer "Álvaro González Sotillo" . "alvarogonzalezsotillo@gmail.com") (:keywords "convenience") (:url . "https://github.com/alvarogonzalezsotillo/region-occurrences-highlighter"))])
+ (region-state . [(20181205 1746) nil "Show the number of chars/lines or rows/columns in the region" single ((:commit . "8c636b655eef45e0015684699737d31e15450000") (:authors ("Chunyang Xu" . "mail@xuchunyang.me")) (:maintainer "Chunyang Xu" . "mail@xuchunyang.me") (:keywords "convenience") (:url . "https://github.com/xuchunyang/region-state.el"))])
+ (register-channel . [(20210120 1618) nil "Jump around fast using registers" single ((:commit . "ed7f563e92170b758dc878fcb5df88d46d5d44cc") (:authors ("Yang Zhao" . "YangZhao11@users.noreply.github.com")) (:maintainer "Yang Zhao" . "YangZhao11@users.noreply.github.com") (:keywords "convenience"))])
+ (register-quicknav . [(20200524 2006) ((emacs (25 3))) "Quickly jump to next/previous register" single ((:commit . "c15ea92b0946c28b3f14986d42b15b0b534aa6a2") (:authors ("tastytea" . "tastytea@tastytea.de")) (:maintainer "tastytea" . "tastytea@tastytea.de") (:keywords "convenience") (:url . "https://schlomp.space/tastytea/register-quicknav"))])
+ (rego-mode . [(20201102 1420) ((emacs (24 4)) (reformatter (0 3))) "A major mode for rego language" single ((:commit . "be110e6cef5d34eef0529a8739c68e619cf15310") (:authors ("Sibi Prabakaran" . "sibi@psibi.in")) (:maintainer "Sibi Prabakaran" . "sibi@psibi.in") (:keywords "languages") (:url . "https://github.com/psibi/rego-mode"))])
+ (related . [(20190327 1024) ((cl-lib (0 5))) "Switch back and forth between similarly named buffers." single ((:commit . "546c7e811b290470288b617f2c27106bd83ccd33") (:authors ("Julien Montmartin")) (:maintainer "Julien Montmartin") (:keywords "file" "buffer" "switch" "selection" "matching" "convenience") (:url . "https://github.com/julien-montmartin/related"))])
+ (remark-mode . [(20210504 1238) ((emacs (25 1)) (markdown-mode (2 0))) "Major mode for the remark slideshow tool" tar ((:commit . "9f15285445fdb53e720ffe72f5cf05231d340906") (:authors ("@torgeir")) (:maintainer "@torgeir") (:keywords "remark" "slideshow" "markdown" "hot reload"))])
+ (remember-last-theme . [(20170619 2133) ((emacs (24 4))) "Remember the last used theme between sessions." single ((:commit . "0973f1aa6b96355fa376fffe8b45733b6e963c51") (:authors ("Anler Hernández Peral" . "inbox+emacs@anler.me")) (:maintainer "Anler Hernández Peral" . "inbox+emacs@anler.me") (:keywords "convenience" "faces") (:url . "https://github.com/anler/remember-last-theme"))])
+ (remind-bindings . [(20200820 1723) ((emacs (25 1)) (omni-quotes (0 5)) (popwin (1 0)) (map (2 0))) "Reminders for your init bindings" single ((:commit . "c9a327bfd3c68a0c41b5b64df491bdee4c73ca39") (:authors ("Mehmet Tekman")) (:maintainer "Mehmet Tekman") (:keywords "outlines") (:url . "https://github.com/mtekman/remind-bindings.el"))])
+ (renpy . [(20200607 135) nil "silly walks for Renpy" single ((:commit . "f2f95a72a8c842f229f80999132e8ea8ee73f6fc") (:authors ("PyTom" . "pytom@bishoujo.us")) (:maintainer "Dave Love" . "fx@gnu.org") (:keywords "languages") (:url . "https://github.com/billywade/renpy-mode"))])
+ (repeatable-motion . [(20170620 1848) ((emacs (24))) "Make repeatable versions of motions" tar ((:commit . "f29effdc4121c2dc7e3fec9b3a62debce29cda9d") (:authors ("William Hatch" . "willghatch@gmail.com")) (:maintainer "William Hatch" . "willghatch@gmail.com") (:keywords "motion" "repeatable") (:url . "https://github.com/willghatch/emacs-repeatable-motion"))])
+ (repeater . [(20180418 1212) ((emacs (24 4))) "Repeat recent repeated commands" single ((:commit . "854b874542b186b2408cbc58ad0591fe8eb70b6c") (:authors ("Xu Chunyang" . "mail@xuchunyang.me")) (:maintainer "Xu Chunyang" . "mail@xuchunyang.me") (:keywords "convenience") (:url . "https://github.com/xuchunyang/repeater"))])
+ (repl-toggle . [(20210226 1055) ((fullframe (0 0 5))) "Switch to/from repl buffer for current major-mode" single ((:commit . "7028ae65f136215f8e07a43afc33a6b99fe82857") (:authors ("Tom Regner" . "tom@goochesa.de")) (:maintainer "Tom Regner" . "tom@goochesa.de") (:keywords "repl" "buffers" "toggle"))])
+ (replace-from-region . [(20170227 2316) nil "Replace commands whose query is from region" single ((:commit . "dc9318b9b2822da7b00ecc34d1dc965c8f96c9bb") (:authors ("rubikitch" . "rubikitch@ruby-lang.org")) (:maintainer "rubikitch" . "rubikitch@ruby-lang.org") (:keywords "replace" "search" "region") (:url . "http://www.emacswiki.org/emacs/download/replace-from-region.el"))])
+ (replace-pairs . [(20160207 1251) ((emacs (24 4))) "Query-replace pairs of things" single ((:commit . "acfb254dddffcee4250092fab9394ef2b42ffbc0") (:authors ("David Shepherd" . "davidshepherd7@gmail.com")) (:maintainer "David Shepherd" . "davidshepherd7@gmail.com") (:url . "https://github.com/davidshepherd7/replace-pairs"))])
+ (replace-symbol . [(20160518 12) nil "Rename symbols in expressions or buffers" single ((:commit . "baf949e528aee1881f455f9c84e67718bedcb3f6") (:authors ("Brian Mastenbrook" . "brian@mastenbrook.net")) (:maintainer "Brian Mastenbrook" . "brian@mastenbrook.net") (:url . "https://github.com/bmastenbrook/replace-symbol-el"))])
+ (replace-with-inflections . [(20180831 635) ((cl-lib (0 5)) (string-inflection (1 0 10)) (inflections (1 1))) "Inflection aware `query-replace'" single ((:commit . "d9201e047856492f282da65459b28aba25998dbb") (:authors ("Akinori MUSHA" . "knu@iDaemons.org")) (:maintainer "Akinori MUSHA" . "knu@iDaemons.org") (:keywords "matching") (:url . "https://github.com/knu/replace-with-inflections.el"))])
+ (repo . [(20191201 38) ((emacs (24 3))) "Running repo from Emacs" single ((:commit . "7b3ce731f1209d74113cb65a2d6aa6f54ce8ed27") (:authors ("Damien Merenne")) (:maintainer "Damien Merenne") (:keywords "convenience") (:url . "https://github.com/canatella/repo-el"))])
+ (req-package . [(20180605 1141) ((use-package (1 0)) (dash (2 7 0)) (log4e (0 2 0)) (ht (0))) "A use-package wrapper for package runtime dependencies management" tar ((:commit . "a77da72931914ac5f3f64dc61fe9dc3522b2817e") (:authors ("Edward Knyshov" . "edvorg@gmail.com")) (:maintainer "Edward Knyshov" . "edvorg@gmail.com") (:keywords "dotemacs" "startup" "speed" "config" "package") (:url . "https://github.com/edvorg/req-package"))])
+ (request . [(20211107 1907) ((emacs (24 4))) "Compatible layer for URL request" single ((:commit . "c769cf33f2ac0a1a9798b508935c4b260e856ab5") (:authors ("Takafumi Arakaki <aka.tkf at gmail.com>")) (:maintainer "Takafumi Arakaki <aka.tkf at gmail.com>") (:url . "https://github.com/tkf/emacs-request"))])
+ (request-deferred . [(20210214 37) ((emacs (24 1)) (deferred (0 3 1)) (request (0 3))) "Wrap request.el by deferred" single ((:commit . "c769cf33f2ac0a1a9798b508935c4b260e856ab5") (:authors ("Takafumi Arakaki <aka.tkf at gmail.com>")) (:maintainer "Takafumi Arakaki <aka.tkf at gmail.com>") (:url . "https://github.com/tkf/emacs-request"))])
+ (requirejs . [(20151204 719) ((js2-mode (20150713)) (popup (0 5 3)) (s (1 9 0)) (cl-lib (0 5)) (yasnippet (20151011 1823))) "Requirejs import manipulation and source traversal." tar ((:commit . "4ea2a5fcbc76e4cbb6a7461e6f05f019b75865b1") (:authors ("Joe Heyming" . "joeheyming@gmail.com")) (:maintainer "Joe Heyming" . "joeheyming@gmail.com") (:keywords "javascript" "requirejs") (:url . "https://github.com/joeheyming/requirejs-emacs"))])
+ (requirejs-mode . [(20130215 2104) nil "Improved AMD module management" single ((:commit . "bbb0c09f8eb2d6a33c17319be8137f68bb16bc92") (:authors ("Marc-Olivier Ricard" . "marco.ricard@gmail.com")) (:maintainer "Marc-Olivier Ricard" . "marco.ricard@gmail.com") (:keywords "javascript" "amd" "requirejs"))])
+ (rescript-mode . [(20210902 2140) ((emacs (26 1))) "A major mode for editing ReScript" tar ((:commit . "350d717f5c2564817179c4b6b1c615b10fd062e8") (:authors ("Karl Landstrom" . "karl.landstrom@brgeight.se") ("Daniel Colascione" . "dancol@dancol.org") ("John Lee" . "jjl@pobox.com")) (:maintainer "John Lee" . "jjl@pobox.com") (:keywords "languages" "rescript") (:url . "https://github.com/jjlee/rescript-mode"))])
+ (resize-window . [(20180918 538) ((emacs (24)) (cl-lib (0 5))) "easily resize windows" single ((:commit . "72018aa4d2401b60120588199d4cedd0dc1fbcfb") (:authors ("Dan Sutton " . "danielsutton01@gmail.com")) (:maintainer "Dan Sutton " . "danielsutton01@gmail.com") (:keywords "window" "resize") (:url . "https://github.com/dpsutton/resize-mode"))])
+ (restart-emacs . [(20201127 1425) nil "Restart emacs from within emacs" single ((:commit . "1607da2bc657fe05ae01f7fdf26f716eafead02c") (:authors ("Iqbal Ansari" . "iqbalansari02@yahoo.com")) (:maintainer "Iqbal Ansari" . "iqbalansari02@yahoo.com") (:keywords "convenience") (:url . "https://github.com/iqbalansari/restart-emacs"))])
+ (restclient . [(20220101 1239) nil "An interactive HTTP client for Emacs" single ((:commit . "ae79e7dd283890072da69b8f48aeec1afd0d9442") (:authors ("Pavel Kurnosov" . "pashky@gmail.com")) (:maintainer "Pavel Kurnosov" . "pashky@gmail.com") (:keywords "http"))])
+ (restclient-helm . [(20170314 1554) ((restclient (0)) (helm (1 9 4))) "helm interface for restclient.el" single ((:commit . "ae79e7dd283890072da69b8f48aeec1afd0d9442") (:authors ("Pavel Kurnosov" . "pashky@gmail.com")) (:maintainer "Pavel Kurnosov" . "pashky@gmail.com") (:keywords "http" "helm"))])
+ (restclient-jq . [(20220426 1734) ((restclient (20200502 831)) (jq-mode (0 4 1)) (emacs (24 4))) "Support for setting restclient vars from jq expressions" single ((:commit . "ae79e7dd283890072da69b8f48aeec1afd0d9442") (:authors ("Cameron Dorrat" . "cdorrat@gmail.com")) (:maintainer "Cameron Dorrat" . "cdorrat@gmail.com") (:keywords "tools" "comm" "http" "jq") (:url . "https://github.com/pashky/restclient.el"))])
+ (restclient-test . [(20210422 1815) ((emacs (26 1)) (restclient (0))) "Run tests with restclient.el" single ((:commit . "3c6661d087526510a04ea9de421c5869a1a1d061") (:authors ("Simen Heggestøyl" . "simenheg@runbox.com")) (:maintainer "Simen Heggestøyl" . "simenheg@runbox.com") (:url . "https://github.com/simenheg/restclient-test.el"))])
+ (retrie . [(20200519 551) ((emacs (24 5))) "Refactoring Haskell code with retrie" single ((:commit . "976d6f01a3e214917f16b82e750d825cb9bfcc59") (:authors ("Junyoung Clare Jang" . "jjc9310@gmail.com")) (:maintainer "Junyoung Clare Jang" . "jjc9310@gmail.com") (:keywords "files" "languages" "tools") (:url . "https://github.com/Ailrun/emacs-retrie"))])
+ (revbufs . [(20200907 2223) nil "Reverts all out-of-date buffers safely" single ((:commit . "df3c02d3063951582c693ae12547993cec8256e2") (:authors ("Neil Van Dyke" . "neil@neilvandyke.org")) (:maintainer "Sam Kleinman" . "sam@tychoish.com") (:keywords "convenience" "buffers") (:url . "http://www.neilvandyke.org/revbufs/"))])
+ (reveal-in-folder . [(20220110 1821) ((emacs (24 3)) (f (0 20 0)) (s (1 12 0))) "Reveal current file in folder" single ((:commit . "dd72004f6f7b0d554dbd979f22a31c350e211089") (:authors ("Shen, Jen-Chieh" . "jcs090218@gmail.com")) (:maintainer "Shen, Jen-Chieh" . "jcs090218@gmail.com") (:url . "https://github.com/jcs-elpa/reveal-in-folder"))])
+ (reveal-in-osx-finder . [(20150802 1657) nil "Reveal file associated with buffer in OS X Finder" single ((:commit . "5710e5936e47139a610ec9a06899f72e77ddc7bc") (:authors ("Kazuki YOSHIDA")) (:maintainer "Kazuki YOSHIDA") (:keywords "os x" "finder") (:url . "https://github.com/kaz-yos/reveal-in-osx-finder"))])
+ (reverse-im . [(20220309 1919) ((emacs (25 1)) (seq (2 23))) "Reverse mapping for non-default system layouts" single ((:commit . "50b8376f152916bc200635a112db9439bc3cc9b5") (:keywords "i18n") (:url . "https://github.com/a13/reverse-im.el"))])
+ (reverse-theme . [(20141205 145) nil "Reverse theme for Emacs" single ((:commit . "8319d0d5342890a3530ffa4daafdb7c35feda1ca") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-reverse-theme"))])
+ (revert-buffer-all . [(20220211 548) ((emacs (24 3))) "Revert all open buffers" single ((:commit . "0343c04a4408ff6cb3c8a9dff7d1ffee8256aa70") (:authors ("Campbell Barton" . "ideasman42@gmail.com")) (:maintainer "Campbell Barton" . "ideasman42@gmail.com") (:url . "https://gitlab.com/ideasman42/emacs-buffer-revert-all"))])
+ (review-mode . [(20220215 842) nil "major mode for ReVIEW" single ((:commit . "f08ef20d9ff4f03a00a8c24dae9ce416da0d9d1c") (:authors ("Kenshi Muto" . "kmuto@kmuto.jp")) (:maintainer "Kenshi Muto" . "kmuto@kmuto.jp") (:url . "https://github.com/kmuto/review-el"))])
+ (reykjavik-theme . [(20201219 947) ((emacs (24))) "Theme with a dark background." single ((:commit . "f6d8e83946633603234cd1dac725e17447f40bce") (:authors ("martin haesler")) (:maintainer "martin haesler"))])
+ (rfc-mode . [(20210615 1721) ((emacs (25 1))) "RFC document browser and viewer" single ((:commit . "3ef663203b157e7c5b2cd3c425ec8fbe7977a24c") (:authors ("Nicolas Martyanoff" . "khaelin@gmail.com")) (:maintainer "Nicolas Martyanoff" . "khaelin@gmail.com") (:url . "https://github.com/galdor/rfc-mode"))])
+ (rg . [(20220427 1613) ((emacs (25 1)) (transient (0 3 0)) (wgrep (2 1 10))) "A search tool based on ripgrep" tar ((:commit . "a6411f98a695d8b3ef0db156d41b2a62ca36ee7a") (:authors ("David Landell" . "david.landell@sunnyhill.email") ("Roland McGrath" . "roland@gnu.org")) (:maintainer "David Landell" . "david.landell@sunnyhill.email") (:keywords "matching" "tools") (:url . "https://github.com/dajva/rg.el"))])
+ (rhq . [(20220329 1027) ((emacs (24 4))) "Client for rhq" single ((:commit . "46a3108436cc4a2c5343b010f2086088d7b9682b") (:authors ("ROCKTAKEY" . "rocktakey@gmail.com")) (:maintainer "ROCKTAKEY" . "rocktakey@gmail.com") (:keywords "tools" "extensions") (:url . "https://github.com/ROCKTAKEY/rhq"))])
+ (rhtml-mode . [(20130422 1311) nil "major mode for editing RHTML files" tar ((:commit . "a6d71b38a3db867ccf82999c99805db1a3a33c33"))])
+ (rib-mode . [(20170726 1448) ((emacs (24))) "RenderMan® Interface Bytestream (RIB) Major Mode" single ((:commit . "97470158784c3c212e22e2c20b8471ee65ba59af") (:authors ("Remik Ziemlinski and Daniel Blezek" . "daniel.blezek@gmail.com")) (:maintainer "Remik Ziemlinski and Daniel Blezek" . "daniel.blezek@gmail.com") (:url . "https://github.com/blezek/rib-mode"))])
+ (rich-minority . [(20190419 1136) ((cl-lib (0 5))) "Clean-up and Beautify the list of minor-modes." single ((:commit . "a03e693f6f9232cf75363aaaf1cb041f21675c19") (:authors ("Artur Malabarba" . "emacs@endlessparentheses.com")) (:maintainer "Artur Malabarba" . "emacs@endlessparentheses.com") (:keywords "mode-line" "faces") (:url . "https://github.com/Malabarba/rich-minority"))])
+ (right-click-context . [(20210519 1713) ((emacs (24 3)) (popup (0 5)) (ordinal (0 0 1))) "Right Click Context menu" single ((:commit . "c3c9d36ffbc9fb2bc7c2c4b75291dbcdb1c5f531") (:authors ("USAMI Kenta" . "tadsan@zonu.me")) (:maintainer "USAMI Kenta" . "tadsan@zonu.me") (:keywords "mouse" "menu" "rightclick") (:url . "https://github.com/zonuexe/right-click-context"))])
+ (rigid-tabs . [(20220416 2123) ((emacs (24 3))) "Fix TAB alignment in diff buffers" single ((:commit . "872a10c8751574c9610cba1800f541a6eda24997") (:authors ("Yuri D'Elia" . "wavexx@thregr.org")) (:maintainer "Yuri D'Elia" . "wavexx@thregr.org") (:keywords "diff" "whitespace" "version control" "magit") (:url . "https://gitlab.com/wavexx/rigid-tabs.el"))])
+ (rii . [(20210317 1330) ((emacs (24 3))) "Reversible input interface for multiple input" single ((:commit . "d0cc3599129db735c23abe74d0876286a2fd6b6a") (:authors ("ROCKTAKEY" . "rocktakey@gmail.com")) (:maintainer "ROCKTAKEY" . "rocktakey@gmail.com") (:keywords "extensions" "tools") (:url . "https://github.com/ROCKTAKEY/rii"))])
+ (rime . [(20220421 1811) ((emacs (26 3)) (dash (2 17 0)) (cl-lib (0 6 1)) (popup (0 5 3)) (posframe (0 1 0))) "Rime input method" tar ((:commit . "e6a89e9fa9eabc32063bffb2eacfcece46f7a049") (:authors ("Shi Tianshu")) (:maintainer "Shi Tianshu") (:keywords "convenience" "input-method") (:url . "https://www.github.com/DogLooksGood/emacs-rime"))])
+ (rimero-theme . [(20180901 1348) ((emacs (24))) "Theme with a dark background suitable for UI and terminal usage." single ((:commit . "a2e706c2b34f749019979a133f08a2d94a1104b3") (:authors ("Yves Zoundi" . "yveszoundi@users.sf.net")) (:maintainer "Yves Zoundi" . "yveszoundi@users.sf.net") (:keywords "faces" "theme" "dark" "light colors") (:url . "https://github.com/yveszoundi/emacs-rimero-theme"))])
+ (rinari . [(20150709 640) ((ruby-mode (1 0)) (inf-ruby (2 2 5)) (ruby-compilation (0 16)) (jump (2 0))) "Rinari Is Not A Rails IDE" single ((:commit . "134438af8fbdfa9c8077267c768d273a9792b484") (:authors ("Phil Hagelberg, Eric Schulte, Steve Purcell")) (:maintainer "Phil Hagelberg, Eric Schulte, Steve Purcell") (:keywords "ruby" "rails" "project" "convenience" "web") (:url . "https://github.com/eschulte/rinari"))])
+ (rings . [(20160531 2027) nil "Buffer rings. Like tabs, but better." single ((:commit . "3590b222eb80652cbd27866f066bd3571d86edfc") (:authors ("Konrad Scorciapino")) (:maintainer "Konrad Scorciapino") (:keywords "utilities" "productivity") (:url . "http://github.com/konr/rings"))])
+ (ripgrep . [(20220309 1746) nil "Front-end for ripgrep, a command line search tool" single ((:commit . "4ed5c741233a81d96115f556784269042070901e") (:authors ("Nicolas Lamirault" . "nicolas.lamirault@gmail.com")) (:maintainer "Nicolas Lamirault" . "nicolas.lamirault@gmail.com") (:keywords "ripgrep" "ack" "pt" "ag" "sift" "grep" "search") (:url . "https://github.com/nlamirault/ripgrep.el"))])
+ (riscv-mode . [(20170804 1521) ((emacs (24 4))) "Major-mode for RISC V assembly" single ((:commit . "99febf97d1fa9441e8dada94fe30c2aa439c9749") (:authors ("Adam Niederer <https://github.com/AdamNiederer>")) (:maintainer "Adam Niederer") (:keywords "riscv" "assembly") (:url . "https://github.com/AdamNiederer/riscv-mode"))])
+ (rivet-mode . [(20201013 1905) ((emacs (24)) (web-mode (16))) "A minor mode for editing Apache Rivet files" single ((:commit . "3dd4fc28f29e4d4f43a881ed5816dea41a912419") (:authors ("Jade Michael Thornton")) (:maintainer "Jade Michael Thornton") (:url . "https://gitlab.com/thornjad/rivet-mode"))])
+ (rjsx-mode . [(20200120 1446) ((emacs (24 4)) (js2-mode (20170504))) "Real support for JSX" single ((:commit . "b697fe4d92cc84fa99a7bcb476f815935ea0d919") (:authors ("Felipe Ochoa" . "felipe@fov.space")) (:maintainer "Felipe Ochoa" . "felipe@fov.space") (:keywords "languages") (:url . "https://github.com/felipeochoa/rjsx-mode/"))])
+ (rmsbolt . [(20220503 1708) ((emacs (25 1))) "A compiler output viewer" tar ((:commit . "de28f7903a3b895c3bf9628ac6d4db4378748fa8") (:authors ("Jay Kamat" . "jaygkamat@gmail.com")) (:maintainer "Jay Kamat" . "jaygkamat@gmail.com") (:keywords "compilation" "tools") (:url . "http://gitlab.com/jgkamat/rmsbolt"))])
+ (robe . [(20211208 205) ((inf-ruby (2 5 1)) (emacs (25 1))) "Code navigation, documentation lookup and completion for Ruby" tar ((:commit . "11207bd549a5a78e3a4d70265c3715990dcdab71") (:authors ("Dmitry Gutov")) (:maintainer "Dmitry Gutov") (:keywords "ruby" "convenience" "rails") (:url . "https://github.com/dgutov/robe"))])
+ (robot-mode . [(20210425 1925) ((emacs (26 1))) "Major-mode for Robot Framework files" single ((:commit . "e7e9c4d4750d048ad771fa735621ad813fa9c128") (:authors ("Kalle Kankare" . "kalle.kankare@iki.fi")) (:maintainer "Kalle Kankare" . "kalle.kankare@iki.fi") (:keywords "languages" "files") (:url . "https://github.com/kopoli/robot-mode"))])
+ (robots-txt-mode . [(20190812 1858) nil "Major mode for editing robots.txt" single ((:commit . "8bf67285a25a6756607354d184e36583f2847e7d") (:authors ("USAMI Kenta" . "tadsan@zonu.me")) (:maintainer "USAMI Kenta" . "tadsan@zonu.me") (:keywords "languages" "comm" "web") (:url . "https://github.com/emacs-php/robots-txt-mode"))])
+ (roguel-ike . [(20160120 302) ((popup (0 5 0))) "A coffee-break roguelike" tar ((:commit . "706dcb0687e8016d7d776f9d9e5ace9fdbbca43c") (:authors ("Steven Rémot")) (:maintainer "Steven Rémot"))])
+ (ron-mode . [(20200830 1554) ((emacs (24 5 1))) "Rusty Object Notation mode" single ((:commit . "c5e0454b9916d6b73adc15dab8abbb0b0a68ea22") (:authors ("Daniel Hutzley" . "endergeryt@gmail.com")) (:maintainer "Daniel Hutzley" . "endergeryt@gmail.com") (:keywords "languages") (:url . "https://chiselapp.com/user/Hutzdog/repository/ron-mode/home"))])
+ (rope-read-mode . [(20211228 1126) ((emacs (24))) "Rearrange lines to read text smoothly" single ((:commit . "6aad44e006a2999980c138f608d28c8ecab92b35") (:authors ("Marco Wahl" . "marcowahlsoft@gmail.com")) (:maintainer "Marco Wahl" . "marcowahlsoft@gmail.com") (:keywords "reading" "convenience" "chill") (:url . "https://gitlab.com/marcowahl/rope-read-mode"))])
+ (ros . [(20220314 2026) ((emacs (25 1))) "Package to write code for ROS systems" single ((:commit . "5e2bcd808f301b1a92cd583f2799d520bd802480") (:authors ("Max Beutelspacher <https://github.com/mtb>")) (:maintainer "Max Beutelspacher" . "max@beutelspacher.eu") (:keywords "convenience" "tools") (:url . "https://github.com/DerBeutlin/ros.el"))])
+ (rotate . [(20210126 637) nil "Rotate the layout of emacs" single ((:commit . "4e9ac3ff800880bd9b705794ef0f7c99d72900a6") (:authors ("daichi.hirata <hirata.daichi at gmail.com>")) (:maintainer "daichi.hirata <hirata.daichi at gmail.com>") (:keywords "window" "layout") (:url . "https://github.com/daichirata/emacs-rotate"))])
+ (roy-mode . [(20121208 1158) nil "Roy major mode" single ((:commit . "0416f561edbc6b4a29fced8be84d2527a9613d65") (:authors ("Georgii Leontiev")) (:maintainer "Georgii Leontiev") (:keywords "extensions") (:url . "https://github.com/folone/roy-mode"))])
+ (rpm-spec-mode . [(20160710 1136) nil "RPM spec file editing commands for Emacs/XEmacs" single ((:commit . "c1c38050c48ea330c7cea632b8785d66daeefb2b") (:authors ("Stig Bjørlykke," . "stig@bjorlykke.org")) (:maintainer "Stig Bjørlykke," . "stig@bjorlykke.org") (:keywords "unix" "languages"))])
+ (rpn-calc . [(20210306 426) ((popup (0 4))) "quick RPN calculator for hackers" single ((:commit . "320123ede874a8fc6cde542baa0d106950318071") (:authors ("zk_phi")) (:maintainer "zk_phi") (:url . "https://github.com/zk-phi/rpn-calc"))])
+ (rspec-mode . [(20220401 306) ((ruby-mode (1 0)) (cl-lib (0 4))) "Enhance ruby-mode for RSpec" tar ((:commit . "a54ac64097b6ccc6acc52a8b077ceb63766fc4d1") (:authors ("Peter Williams, et al.")) (:maintainer "Peter Williams, et al.") (:keywords "rspec" "ruby") (:url . "http://github.com/pezra/rspec-mode"))])
+ (rsync-mode . [(20210911 0) ((emacs (27 1)) (spinner (1 7 1))) "Rsync projects to remote machines" single ((:commit . "2bc76aa8c2d82bb08ef70e23813a653d66bf3195") (:authors ("Ryan Pilgrim" . "ryan.z.pilgrim@gmail.com")) (:maintainer "Ryan Pilgrim" . "ryan.z.pilgrim@gmail.com") (:keywords "comm") (:url . "https://github.com/r-zip/rsync-mode.el"))])
+ (rtags . [(20210313 1541) ((emacs (24 3))) "A front-end for rtags" single ((:commit . "db39790fda5c2443bc790b8971ac140914f7e9c2") (:authors ("Jan Erik Hanssen" . "jhanssen@gmail.com") ("Anders Bakken" . "agbakken@gmail.com")) (:maintainer "Jan Erik Hanssen" . "jhanssen@gmail.com") (:url . "https://github.com/Andersbakken/rtags"))])
+ (rtags-xref . [(20210721 2314) ((emacs (25 1)) (rtags (2 37))) "RTags backend for xref.el" single ((:commit . "db39790fda5c2443bc790b8971ac140914f7e9c2") (:authors ("Jörg Walter")) (:maintainer "RTags Team") (:url . "https://github.com/Andersbakken/rtags"))])
+ (rtm . [(20180329 1508) ((cl-lib (1 0))) "An elisp implementation of the Remember The Milk API" single ((:commit . "3e3d09387cb84801343ecca8fb02e82f213e7bbe") (:authors ("Friedrich Delgado Friedrichs" . "frie...@nomaden.org")) (:maintainer "Friedrich Delgado Friedrichs" . "frie...@nomaden.org") (:keywords "remember" "the" "milk" "productivity" "todo") (:url . "https://github.com/pmiddend/emacs-rtm"))])
+ (rubik . [(20180222 2014) ((cl-lib (1 0)) (emacs (25 3))) "Rubik's Cube" single ((:commit . "c8dab1726463dbc9042a0b00186e4a8df02eb868") (:authors ("Ivan 'Kurvivor' Truskov" . "trus19@gmail.com")) (:maintainer "Ivan 'Kurvivor' Truskov" . "trus19@gmail.com") (:keywords "games") (:url . "https://github.com/Kurvivor19/rubik-mode"))])
+ (rubocop . [(20210309 1241) ((emacs (24))) "An Emacs interface for RuboCop" single ((:commit . "f5fd18aa810c3d3269188cbbd731ddc09006f8f5") (:authors ("Bozhidar Batsov")) (:maintainer "Bozhidar Batsov") (:keywords "project" "convenience") (:url . "https://github.com/rubocop/rubocop-emacs"))])
+ (rubocopfmt . [(20200713 1144) ((cl-lib (0 5))) "Minor-mode to format Ruby code with RuboCop on save" single ((:commit . "b84810105940aa5e0bde20c9a89359c95c9b6917") (:authors ("Jim Myhrberg")) (:maintainer "Jim Myhrberg") (:keywords "convenience" "wp" "edit" "ruby" "rubocop") (:url . "https://github.com/jimeh/rubocopfmt.el"))])
+ (ruby-compilation . [(20150709 640) ((inf-ruby (2 2 1))) "run a ruby process in a compilation buffer" single ((:commit . "134438af8fbdfa9c8077267c768d273a9792b484") (:authors ("Eric Schulte")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:keywords "test" "convenience") (:url . "https://github.com/eschulte/rinari"))])
+ (ruby-electric . [(20200328 1528) nil "Minor mode for electrically editing ruby code" single ((:commit . "f2323cd9b5df3b34aa9810ba8109502824925d23") (:maintainer "Akinori MUSHA" . "knu@iDaemons.org") (:keywords "languages" "ruby") (:url . "https://github.com/ruby/elisp-ruby-electric"))])
+ (ruby-end . [(20141215 1223) nil "Automatic insertion of end blocks for Ruby" single ((:commit . "a136f75abb6d5577ce40d61dfeb778c2e9bb09c0") (:authors ("Johan Andersson" . "johan.rejeep@gmail.com")) (:maintainer "Johan Andersson" . "johan.rejeep@gmail.com") (:keywords "speed" "convenience" "ruby") (:url . "http://github.com/rejeep/ruby-end"))])
+ (ruby-extra-highlight . [(20171106 1933) nil "Highlight Ruby parameters." single ((:commit . "83942d18eae361998d24c1c523b308eea821f048") (:authors ("Anders Lindgren")) (:maintainer "Anders Lindgren") (:keywords "languages" "faces") (:url . "https://github.com/Lindydancer/ruby-extra-highlight"))])
+ (ruby-factory . [(20160102 721) ((inflections (1 1))) "Minor mode for Ruby test object generation libraries" tar ((:commit . "2bb7ccc2fccb5257376a989aa395bc7b9eb1d55d") (:authors ("Skye Shaw" . "skye.shaw@gmail.com")) (:maintainer "Skye Shaw" . "skye.shaw@gmail.com") (:keywords "ruby" "rails" "convenience") (:url . "http://github.com/sshaw/ruby-factory-mode"))])
+ (ruby-hash-syntax . [(20210106 224) ((emacs (24 1))) "Toggle ruby hash syntax between => and 1.9+ styles" single ((:commit . "d458fb5891e0da85271b1cba3ee0ee69ea66a374") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:keywords "languages") (:url . "https://github.com/purcell/ruby-hash-syntax"))])
+ (ruby-interpolation . [(20131112 1652) nil "Ruby string interpolation helpers" single ((:commit . "1978e337601222cedf00e117bf4b5cac15d1f203") (:authors ("Arthur Leonard Andersen" . "leoc.git@gmail.com")) (:maintainer "Arthur Leonard Andersen" . "leoc.git@gmail.com") (:url . "http://github.com/leoc/ruby-interpolation.el"))])
+ (ruby-json-to-hash . [(20211108 351) ((emacs (27 2)) (smartparens (1 11 0)) (string-inflection (1 0 16))) "Convert JSON to Hash and play with the keys" single ((:commit . "383b22bb2e007289ac0dba146787d02ff99d4415") (:authors ("Otávio Schwanck dos Santos" . "otavioschwanck@gmail.com")) (:maintainer "Otávio Schwanck dos Santos" . "otavioschwanck@gmail.com") (:keywords "tools" "languages") (:url . "https://github.com/otavioschwanck/ruby-json-to-hash.el"))])
+ (ruby-refactor . [(20160214 1650) ((ruby-mode (1 2))) "A minor mode which presents various Ruby refactoring helpers." single ((:commit . "e6b7125878a08518bffec6942df0c606f748e9ee") (:keywords "refactor" "ruby") (:url . "https://github.com/ajvargo/ruby-refactor"))])
+ (ruby-test-mode . [(20210205 1107) ((ruby-mode (1 0)) (pcre2el (1 8))) "Minor mode for Behaviour and Test Driven" single ((:commit . "d66db4aca6e6a246f65f7195ecfbc7581d35fb7a") (:authors ("Roman Scherer" . "roman.scherer@gmx.de") ("Caspar Florian Ebeling" . "florian.ebeling@gmail.com")) (:maintainer "Roman Scherer" . "roman.scherer@burningswell.com") (:keywords "ruby" "unit" "test" "rspec" "tools") (:url . "https://github.com/ruby-test-mode/ruby-test-mode"))])
+ (ruby-tools . [(20151209 1615) nil "Collection of handy functions for ruby-mode." tar ((:commit . "6b97066b58a4f82eb2ecea6434a0a7e981aa4c18") (:authors ("Johan Andersson" . "johan.rejeep@gmail.com")) (:maintainer "Johan Andersson" . "johan.rejeep@gmail.com") (:keywords "speed" "convenience" "ruby") (:url . "http://github.com/rejeep/ruby-tools"))])
+ (rufo . [(20170718 1416) ((emacs (24 3))) "use rufo to automatically format ruby files" single ((:commit . "020b02ed6e9ab49e79d2ddf63e4ee2684c1728f4") (:authors ("Daniel Ma" . "danielhgma@gmail.com")) (:maintainer "Daniel Ma" . "danielhgma@gmail.com") (:url . "https://github.com/danielma/rufo.el"))])
+ (ruled-switch-buffer . [(20211205 635) ((emacs (24 3))) "Rule based buffer switching" single ((:commit . "4ae1a722750f7ecb4db93c062ffdbe353e706bf0") (:authors ("Kazuki Nishikawa" . "kzkn@hey.com")) (:maintainer "Kazuki Nishikawa" . "kzkn@hey.com") (:keywords "convenience") (:url . "https://github.com/kzkn/ruled-switch-buffer"))])
+ (rum-mode . [(20180127 22) ((emacs (24))) "Major mode for Rum programming language" single ((:commit . "b69a3866e0299cae8c9c805d644e69b2c17b64de") (:keywords "rum" "languages" "lisp") (:url . "https://github.com/rumlang/rum-mode"))])
+ (run-command . [(20210529 1505) ((emacs (27 1))) "Run an external command from a context-dependent list" single ((:commit . "ce2d69feeffb9ef9815ef5b5e32f236763197a10") (:authors ("Massimiliano Mirra" . "hyperstruct@gmail.com")) (:maintainer "Massimiliano Mirra" . "hyperstruct@gmail.com") (:keywords "processes") (:url . "https://github.com/bard/emacs-run-command"))])
+ (run-command-recipes . [(20220301 2010) ((emacs (25 1)) (dash (2 18 0)) (f (0 20 0)) (run-command (0 1 0)) (s (1 12 0))) "This is collection of recipes to `run-command'" tar ((:commit . "02a4d366e309b7dd6a45f8a94669a25d6fe80ea1") (:authors ("semenInRussia" . "hrams205@gmail.com")) (:maintainer "semenInRussia" . "hrams205@gmail.com") (:keywords "extensions" "run-command") (:url . "https://github.com/semenInRussia/emacs-run-command-recipes"))])
+ (run-stuff . [(20220211 548) ((emacs (25 1))) "Context based command execution" single ((:commit . "3723346dc6d867bdc3fd86ca11c32efc43704d7c") (:authors ("Campbell Barton" . "ideasman42@gmail.com")) (:maintainer "Campbell Barton" . "ideasman42@gmail.com") (:keywords "files" "lisp" "files" "convenience" "hypermedia") (:url . "https://gitlab.com/ideasman42/emacs-run-stuff"))])
+ (runner . [(20160524 743) nil "Improved \"open with\" suggestions for dired" single ((:commit . "a211d57ddc600410d07a8b534920ba905b093d87") (:authors ("Thamer Mahmoud" . "thamer.mahmoud@gmail.com")) (:maintainer "Thamer Mahmoud" . "thamer.mahmoud@gmail.com") (:keywords "shell command" "dired" "file extension" "open with") (:url . "https://github.com/thamer/runner"))])
+ (runtests . [(20150807 831) nil "Run unit tests from Emacs" single ((:commit . "ed90249f24cc48290018df48b9b9b7172440be3e") (:authors ("Sune Simonsen" . "sune@we-knowhow.dk")) (:maintainer "Sune Simonsen" . "sune@we-knowhow.dk") (:keywords "test") (:url . "https://github.com/sunesimonsen/emacs-runtests"))])
+ (russian-holidays . [(20170109 2140) nil "Russian holidays for the calendar" single ((:commit . "b285a30f29d85c48e3ea4eb93972d34a090c167b") (:authors ("Alexander I.Grafov" . "siberian@laika.name")) (:maintainer "Alexander I.Grafov" . "siberian@laika.name") (:url . "https://github.com/grafov/russian-holidays"))])
+ (rust-auto-use . [(20200608 1359) nil "Utility to automatically insert Rust use statements" single ((:commit . "d5205f7b9b9eae0f7d0893f87d3391464719f9c0") (:authors ("Rotem Yaari" . "rotemy@MBP.local")) (:maintainer "Rotem Yaari" . "rotemy@MBP.local") (:keywords "languages"))])
+ (rust-mode . [(20220217 2009) ((emacs (25 1))) "A major-mode for editing Rust source code" tar ((:commit . "d17be3051b22a06d7742178cd1367aed61807a66") (:authors ("Mozilla")) (:maintainer "Mozilla") (:keywords "languages") (:url . "https://github.com/rust-lang/rust-mode"))])
+ (rust-playground . [(20200116 1043) ((emacs (24 3))) "Local Rust playground for short code snippets." single ((:commit . "5a117781dcb66065bea7830dd73618008fc34949") (:authors ("Alexander I.Grafov" . "grafov@gmail.com")) (:maintainer "Alexander I.Grafov" . "grafov@gmail.com") (:keywords "tools" "rust") (:url . "https://github.com/grafov/rust-playground"))])
+ (rustic . [(20220427 1413) ((emacs (26 1)) (rust-mode (1 0 3)) (dash (2 13 0)) (f (0 18 2)) (let-alist (1 0 4)) (markdown-mode (2 3)) (project (0 3 0)) (s (1 10 0)) (seq (2 3)) (spinner (1 7 3)) (xterm-color (1 6))) "Rust development environment" tar ((:commit . "8c214efb72be9731cd7d613c07672515a0f70664") (:authors ("Mozilla")) (:maintainer "Mozilla") (:keywords "languages"))])
+ (rutils . [(20210805 608) ((emacs (26 1)) (ess (18 10 1)) (transient (0 3 0))) "R utilities with transient" tar ((:commit . "e216db63a2ccd50fe5c80679fc5b929dd2c114e8") (:authors ("Shuguang Sun" . "shuguang79@qq.com")) (:maintainer "Shuguang Sun" . "shuguang79@qq.com") (:keywords "convenience") (:url . "https://github.com/ShuguangSun/rutils.el"))])
+ (rvm . [(20201222 17) nil "Emacs integration for rvm" single ((:commit . "c1f2642434b0f68d9baa0687127079ecd884ba12") (:authors ("Yves Senn" . "yves.senn@gmx.ch")) (:maintainer "Yves Senn" . "yves.senn@gmx.ch") (:keywords "ruby" "rvm") (:url . "http://www.emacswiki.org/emacs/RvmEl"))])
+ (ryo-modal . [(20220103 940) ((emacs (25 1))) "Roll your own modal mode" single ((:commit . "0a61eed4d2917422d6401b6abe2037c26dab658a") (:authors ("Erik Sjöstrand" . "sjostrand.erik@gmail.com")) (:maintainer "Erik Sjöstrand" . "sjostrand.erik@gmail.com") (:keywords "convenience" "modal" "keys") (:url . "http://github.com/Kungsgeten/ryo-modal"))])
+ (s . [(20210616 619) nil "The long lost Emacs string manipulation library." single ((:commit . "08661efb075d1c6b4fa812184c1e5e90c08795a9") (:authors ("Magnar Sveen" . "magnars@gmail.com")) (:maintainer "Magnar Sveen" . "magnars@gmail.com") (:keywords "strings"))])
+ (s-buffer . [(20130605 2124) ((s (1 6 0)) (noflet (0 0 3))) "s operations for buffers" single ((:commit . "f95d234282377f00a2c3a9846681080cb95bb1df") (:authors ("Nic Ferrier" . "nferrier@ferrier.me.uk")) (:maintainer "Nic Ferrier" . "nferrier@ferrier.me.uk") (:keywords "lisp") (:url . "http://github.com/nicferrier/emacs-s-buffer"))])
+ (s12cpuv2-mode . [(20171013 2051) ((emacs (24 3))) "Major-mode for S12CPUV2 assembly" single ((:commit . "b17d4cf848dec1e20e66458e5c7ff77a2c051a8c") (:authors ("Adam Niederer" . "adam.niederer@gmail.com")) (:maintainer "Adam Niederer" . "adam.niederer@gmail.com") (:keywords "s12cpuv2" "assembly" "languages") (:url . "https://github.com/AdamNiederer/s12cpuv2-mode"))])
+ (s3ed . [(20200929 1317) ((emacs (25 1)) (dash (2 17 0)) (s (1 12 0))) "Tramp-like access to s3" tar ((:commit . "2234444ead6c4c6fc3fea548958b36d2c29a9938") (:authors ("Matt Usifer" . "mattusifer@gmail.com")) (:maintainer "Matt Usifer" . "mattusifer@gmail.com") (:keywords "s3" "tools") (:url . "https://github.com/mattusifer/s3ed"))])
+ (sackspace . [(20130719 956) nil "A better backspace" single ((:commit . "fd0480eaaf6d3d11fd30ac5feb2da2f4f7572708") (:authors ("Michael Markert" . "markert.michael@googlemail.com")) (:maintainer "Michael Markert" . "markert.michael@googlemail.com") (:keywords "delete" "convenience") (:url . "http://github.com/cofi/sackspace.el"))])
+ (sage-shell-mode . [(20201225 1011) ((cl-lib (0 6 1)) (emacs (24 4)) (let-alist (1 0 5)) (deferred (0 5 1))) "A front-end for Sage Math" tar ((:commit . "7fc47d5eab0efac009d5a9316e3dfa223595ab5a") (:authors ("Sho Takemori" . "stakemorii@gmail.com")) (:maintainer "Sho Takemori" . "stakemorii@gmail.com") (:keywords "sage" "math") (:url . "https://github.com/sagemath/sage-shell-mode"))])
+ (sailfish-scratchbox . [(20171202 1332) nil "Sailfish OS scratchbox inside the emacs." single ((:commit . "65c6b04abadd2cdeb4cc2dc2a8b96b06e0f27ed8") (:authors ("V. V. Polevoy" . "fx@thefx.co")) (:maintainer "V. V. Polevoy" . "fx@thefx.co") (:keywords "sb2" "mb2" "building" "scratchbox" "sailfish") (:url . "https://github.com/vityafx/sailfish-scratchbox.el"))])
+ (salesforce-utils . [(20160814 154) ((cl-lib (0 5))) "simple utilities for Salesforce" single ((:commit . "73328baf0fb94ac0d0de645a8f6d42e5ae27f773") (:authors ("Sean McAfee")) (:maintainer "Sean McAfee") (:url . "https://github.com/grimnebulin/emacs-salesforce"))])
+ (salt-mode . [(20200210 1200) ((emacs (24 4)) (yaml-mode (0 0 12)) (mmm-mode (0 5 4)) (mmm-jinja2 (0 1))) "Major mode for Salt States" single ((:commit . "c46b24e7fdf4a46df5507dc9c533bbc0064a46fa") (:authors ("Ben Hayden" . "hayden767@gmail.com")) (:maintainer "Glynn Forrest" . "me@glynnforrest.com") (:keywords "languages") (:url . "https://github.com/glynnforrest/salt-mode"))])
+ (sane-term . [(20181130 101) ((emacs (24 1))) "Multi Term is crazy. This is not." single ((:commit . "369178c2dd0348250c2ec0019567688376c637f7") (:authors ("Adam Patterson" . "adam@adamrt.com")) (:maintainer "Adam Patterson" . "adam@adamrt.com") (:url . "http://github.com/adamrt/sane-term"))])
+ (sass-mode . [(20190502 53) ((haml-mode (3 0 15)) (cl-lib (0 5))) "Major mode for editing Sass files" single ((:commit . "247a0d4b509f10b28e4687cd8763492bca03599b") (:authors ("Natalie Weizenbaum")) (:maintainer "Natalie Weizenbaum") (:keywords "markup" "language" "css") (:url . "http://github.com/nex3/haml/tree/master"))])
+ (sauron . [(20201015 836) nil "Track (erc/org/dbus/...) events and react to them." tar ((:commit . "5daade4836da5b1b2ab26d84128d6c38328a5d52") (:authors ("Dirk-Jan C. Binnema" . "djcb@djcbsoftware.nl")) (:maintainer "Dirk-Jan C. Binnema" . "djcb@djcbsoftware.nl") (:keywords "comm" "frames"))])
+ (save-load-path . [(20140206 1214) nil "save load-path and reuse it to test" single ((:commit . "6cb763a37e2b8af505bff2bcd11fd49c9ea04d66") (:authors ("rubikitch" . "rubikitch@ruby-lang.org")) (:maintainer "rubikitch" . "rubikitch@ruby-lang.org") (:keywords "lisp") (:url . "http://www.emacswiki.org/cgi-bin/wiki/download/save-load-path.el"))])
+ (save-visited-files . [(20200212 414) nil "save opened files across sessions" single ((:commit . "8203a05a322324ec17b14437c8dfb38efdb53241") (:authors ("Nathaniel Flath" . "nflath@gmail.com")) (:maintainer "Nathaniel Flath" . "nflath@gmail.com") (:url . "http://github.com/nflath/save-visited-files"))])
+ (savekill . [(20140418 229) nil "Save kill ring to disk" single ((:commit . "67fc94e3d8fe8ce3ca16f90518f6a46479b63e34") (:authors ("rubikitch" . "rubikitch@ruby-lang.org")) (:maintainer "rubikitch" . "rubikitch@ruby-lang.org") (:keywords "tools") (:url . "http://www.emacswiki.org/cgi-bin/wiki/download/savekill.el"))])
+ (saveplace-pdf-view . [(20210217 1312) ((emacs (24 1))) "Save place in pdf-view buffers" single ((:commit . "54ed966b842501c3c092dbf57b372e37b033c578") (:authors ("Nicolai Singh <nicolaisingh at pm.me>")) (:maintainer "Nicolai Singh <nicolaisingh at pm.me>") (:keywords "files" "convenience") (:url . "https://github.com/nicolaisingh/saveplace-pdf-view"))])
+ (say-what-im-doing . [(20160706 1931) nil "dictate what you're doing with text to speech" single ((:commit . "5b2ce6783b02805bcac1107a149bfba3852cd9d5") (:authors ("Benaiah Mischenko")) (:maintainer "Benaiah Mischenko") (:keywords "text to speech" "dumb" "funny") (:url . "http://github.com/benaiah/say-what-im-doing"))])
+ (sayid . [(20220101 1357) ((cider (0 21 0))) "sayid nREPL middleware client" single ((:commit . "879aff586336a0ec4d46c0ed4720fb1de22082bd") (:authors ("Bill Piel" . "bill@billpiel.com")) (:maintainer "Bozhidar Batsov" . "bozhidar@batsov.dev") (:keywords "clojure" "cider" "debugger") (:url . "https://github.com/clojure-emacs/sayid"))])
+ (sbt-mode . [(20211203 1148) ((emacs (24 4))) "Interactive support for sbt projects" tar ((:commit . "9fe1e8807c22cc1dc56a6233e000969518907f4d") (:keywords "languages") (:url . "https://github.com/hvesalai/emacs-sbt-mode"))])
+ (scad-mode . [(20200830 301) nil "A major mode for editing OpenSCAD code" single ((:commit . "841808390d8d063c62c60cb70fa02064be2255d6") (:authors ("Len Trigg, Łukasz Stelmach")) (:maintainer "Len Trigg" . "lenbok@gmail.com") (:keywords "languages") (:url . "https://raw.github.com/openscad/openscad/master/contrib/scad-mode.el"))])
+ (scad-preview . [(20211212 1128) ((scad-mode (91 0)) (emacs (24 4))) "Preview SCAD models in real-time within Emacs" single ((:commit . "c5449b26c63f3e0a695905a7e4e84f8d844f761b") (:authors ("zk_phi")) (:maintainer "zk_phi") (:url . "https://zk-phi.github.io/"))])
+ (scala-mode . [(20210414 1126) nil "Major mode for editing Scala" tar ((:commit . "598cb680f321d9609295aa9b4679040cc703b602") (:keywords "languages") (:url . "https://github.com/hvesalai/emacs-scala-mode"))])
+ (scf-mode . [(20151122 248) nil "shorten file-names in compilation type buffers" single ((:commit . "dbfcdcd89034f208d65e181af58e0d73ad09f8b2") (:authors ("Le Wang")) (:maintainer "Le Wang") (:keywords "compilation") (:url . "https://github.com/lewang/scf-mode"))])
+ (scheme-complete . [(20201112 442) nil "Smart auto completion for Scheme in Emacs" single ((:commit . "b9a1448c4696f117d9ea4e59b6162dc31112e71a") (:authors ("Alex Shinn")) (:maintainer "Alex Shinn"))])
+ (schrute . [(20170521 1840) ((emacs (24 3))) "Help you remember there is a better way to do something." single ((:commit . "59faa6c4232ae183cea93237301acad8c0763997") (:authors ("Jorge Araya Navarro" . "elcorreo@deshackra.com")) (:maintainer "Jorge Araya Navarro" . "elcorreo@deshackra.com") (:keywords "convenience") (:url . "https://bitbucket.org/shackra/dwight-k.-schrute"))])
+ (scihub . [(20220423 421) ((emacs (27 1))) "Sci-Hub integration" single ((:commit . "57333c849bcd4953663cbf7c271e9f3a62179765") (:authors ("Mario Rodas" . "marsam@users.noreply.github.com")) (:maintainer "Mario Rodas" . "marsam@users.noreply.github.com") (:keywords "convenience") (:url . "https://github.com/emacs-pe/scihub.el"))])
+ (scion . [(20130315 1255) nil "Haskell Minor Mode for Interacting with the Scion Library" single ((:commit . "99b4589175665687181a932cd836850205625f71") (:url . "https://code.google.com/p/scion-lib/"))])
+ (sclang-extensions . [(20160509 338) ((auto-complete (1 4 0)) (s (1 3 1)) (dash (1 2 0)) (emacs (24 1))) "Extensions for the SuperCollider Emacs mode." tar ((:commit . "e9cc79732f16fdb582129303110c163dcc0d6da0") (:authors ("Chris Barrett" . "chris.d.barrett@me.com")) (:maintainer "Chris Barrett" . "chris.d.barrett@me.com") (:keywords "sclang" "supercollider" "languages" "tools"))])
+ (sclang-snippets . [(20130513 751) ((yasnippet (0 8 0))) "Snippets for the SuperCollider Emacs mode" tar ((:commit . "c840a416b96f83bdd70491e3d1fbe2f1ae8b3f58") (:authors ("ptrv" . "mail@petervasil.net")) (:maintainer "ptrv" . "mail@petervasil.net") (:keywords "snippets"))])
+ (scpaste . [(20210223 1902) ((htmlize (1 39))) "Paste to the web via scp." single ((:commit . "4ec352fb9fe261ffb8b78449dea986dc34d337b3") (:authors ("Phil Hagelberg")) (:maintainer "Phil Hagelberg") (:keywords "convenience" "hypermedia") (:url . "https://git.sr.ht/~technomancy/scpaste"))])
+ (scratch . [(20220319 1705) ((emacs (25 1))) "Mode-specific scratch buffers" single ((:commit . "f000648c9663833a76a8de9b1e78c99a9d698e48") (:authors ("Ian Eure" . "ian.eure@gmail.com")) (:maintainer "Ian Eure" . "ian.eure@gmail.com") (:keywords "convenience" "tools" "files") (:url . "https://github.com/ieure/scratch-el"))])
+ (scratch-comment . [(20200812 1025) ((emacs (26 1))) "Insert Elisp result as comment in scratch buffer" single ((:commit . "cf3e967b4def1308b6ef1cfeedd2cf15ee6e226c") (:authors ("Naoya Yamashita" . "conao3@gmail.com")) (:maintainer "Naoya Yamashita" . "conao3@gmail.com") (:keywords "convenience") (:url . "https://github.com/conao3/scratch-comment.el"))])
+ (scratch-ext . [(20140104 516) nil "Extensions for *scratch*" single ((:commit . "388c53cddd0466b451264894667ed64a6947ad67") (:authors ("Kouhei Yanagita" . "yanagi@shakenbu.org")) (:maintainer "Kouhei Yanagita" . "yanagi@shakenbu.org") (:url . "https://github.com/kyanagi/scratch-ext-el"))])
+ (scratch-log . [(20141115 743) nil "Utility for *scratch* buffer." single ((:commit . "1168f7f16d36ca0f4ddf2bb98881f8db62cc5dc0") (:authors ("kmori" . "morihenotegami@gmail.com")) (:maintainer "kmori" . "morihenotegami@gmail.com"))])
+ (scratch-message . [(20211221 1527) nil "Changing message in your scratch buffer" single ((:commit . "efb2db33e52e5d4a4f1bafbd8b459a3b91c3c87a") (:authors ("Sylvain Rousseau <thisirs at gmail dot com>")) (:maintainer "Sylvain Rousseau <thisirs at gmail dot com>") (:keywords "util" "scratch") (:url . "https://github.com/thisirs/scratch-message.git"))])
+ (scratch-palette . [(20210306 427) ((popwin (0 7 0 -3))) "make scratch buffer for each files" single ((:commit . "e4642ed8a2b744ba48a8e11ca83861f8e4b9c5b3") (:authors ("zk_phi")) (:maintainer "zk_phi") (:url . "http://zk-phi.gitub.io/"))])
+ (scratch-pop . [(20200910 226) nil "Generate, popup (& optionally backup) scratch buffer(s)." single ((:commit . "cbe842fd78e4b742ece9fc493ebf43e69d872866") (:authors ("zk_phi")) (:maintainer "zk_phi") (:url . "http://hins11.yu-yake.com/"))])
+ (scratches . [(20151006 416) ((dash (2 11 0)) (f (0 17 0))) "Multiple scratches in any language" single ((:commit . "9441afe6396ca38f08029123fab5d87429cbf315") (:authors ("Zhang Kai Yu" . "yeannylam@gmail.com")) (:maintainer "Zhang Kai Yu" . "yeannylam@gmail.com") (:keywords "scratch"))])
+ (scribble-mode . [(20190912 200) ((emacs (24))) "Major mode for editing Scribble documents" single ((:commit . "5c3ea3cc9bbad585476eee41ea76dc056c2012bb") (:authors ("Mario Rodas" . "marsam@users.noreply.github.com")) (:maintainer "Mario Rodas" . "marsam@users.noreply.github.com") (:keywords "convenience") (:url . "https://github.com/emacs-pe/scribble-mode"))])
+ (scroll-on-drag . [(20220211 548) ((emacs (26 2))) "Interactive scrolling" single ((:commit . "d93b69eed6947cabdfde53dfbcf4bd919cb1f154") (:authors ("Campbell Barton" . "ideasman42@gmail.com")) (:maintainer "Campbell Barton" . "ideasman42@gmail.com") (:url . "https://gitlab.com/ideasman42/emacs-scroll-on-drag"))])
+ (scroll-on-jump . [(20220211 548) ((emacs (26 2))) "Scroll when jumping to a new point" single ((:commit . "99386fc01b3c7bc2e75458efca408a23220a5f87") (:authors ("Campbell Barton" . "ideasman42@gmail.com")) (:maintainer "Campbell Barton" . "ideasman42@gmail.com") (:url . "https://gitlab.com/ideasman42/emacs-scroll-on-jump"))])
+ (scrollable-quick-peek . [(20201224 329) ((quick-peek (1 0)) (emacs (24 4))) "Display scrollable overlays" single ((:commit . "3e3492145a61831661d6e97fdcb47b5b66c73287") (:authors ("Pablo Barrantes" . "xjpablobrx@gmail.com")) (:maintainer "Pablo Barrantes" . "xjpablobrx@gmail.com") (:keywords "convenience" "extensions" "help" "tools") (:url . "https://github.com/jpablobr/scrollable-quick-peek"))])
+ (scrollkeeper . [(20190109 629) ((emacs (25 1))) "Custom scrolling commands with visual guidelines" single ((:commit . "3c4ac6b6b44686d31c260ee0b19daaee59bdccd6") (:authors ("Adam Porter" . "adam@alphapapa.net")) (:maintainer "Adam Porter" . "adam@alphapapa.net") (:keywords "convenience") (:url . "https://github.com/alphapapa/scrollkeeper.el"))])
+ (scrooge . [(20180630 1022) ((emacs (24)) (cl-lib (0 5)) (dash (2 13 0)) (thrift (0 9 3))) "Major mode for Twitter Scrooge files" single ((:commit . "0a8c58e9e6708abe4ef7e415bc1e0472318bb1b0") (:authors ("Daniel McClanahan" . "danieldmcclanahan@gmail.com")) (:maintainer "Daniel McClanahan" . "danieldmcclanahan@gmail.com") (:keywords "scrooge" "thrift"))])
+ (scss-mode . [(20180123 1708) nil "Major mode for editing SCSS files" single ((:commit . "cf58dbec5394280503eb5502938f3b5445d1b53d") (:authors ("Anton Johansson" . "anton.johansson@gmail.com")) (:maintainer "Anton Johansson" . "anton.johansson@gmail.com") (:keywords "scss" "css" "mode") (:url . "https://github.com/antonj/scss-mode"))])
+ (sculpture-themes . [(20220406 2330) ((emacs (26 1))) "Themes with vivid colors" tar ((:commit . "a21871b75cc7cb575ceb43640d039307fbb412e1") (:authors ("t-e-r-m" . "newenewen@tutanota.com")) (:maintainer "t-e-r-m" . "newenewen@tutanota.com") (:url . "https://github.com/t-e-r-m/sculpture-theme"))])
+ (sdcv . [(20220210 1412) ((emacs (24 3)) (popup (0 5 3)) (showtip (0 1)) (pos-tip (0 4 6)) (cl-lib (0 3))) "Interface for sdcv (StartDict console version)." single ((:commit . "98e239c7380c63282845d5bc55ea6d605f5a33b8") (:authors ("Andy Stewart" . "lazycat.manatee@gmail.com")) (:maintainer "Andy Stewart" . "lazycat.manatee@gmail.com") (:keywords "startdict" "sdcv") (:url . "https://repo.or.cz/sdcv.el.git"))])
+ (sdlang-mode . [(20161201 711) ((emacs (24 3))) "Major mode for Simple Declarative Language files." single ((:commit . "7fdcf4ead88d451c0a4a6425b2e730818eaf610e") (:authors ("Vladimir Panteleev")) (:maintainer "Vladimir Panteleev") (:keywords "languages") (:url . "https://github.com/CyberShadow/sdlang-mode"))])
+ (search-web . [(20150312 1103) nil "Post web search queries using `browse-url'." single ((:commit . "c4ae86ac1acfc572b81f3d78764bd9a54034c331") (:authors ("Tomoya Otake" . "tomoya.ton@gmail.com")) (:maintainer "Tomoya Otake" . "tomoya.ton@gmail.com"))])
+ (searcher . [(20210124 1524) ((emacs (25 1)) (dash (2 10)) (f (0 20 0))) "Searcher in pure elisp" single ((:commit . "26ecae6a6d028fcbffc576a69ef8f787646bc12a") (:authors ("Shen, Jen-Chieh" . "jcs090218@gmail.com")) (:maintainer "Shen, Jen-Chieh" . "jcs090218@gmail.com") (:url . "https://github.com/jcs-elpa/searcher"))])
+ (searchq . [(20150829 1211) ((emacs (24 3))) "Framework of queued search tasks using GREP, ACK, AG and more." tar ((:commit . "dd510d55ad66a82c6ef022cfe7c4a73ad5365f82") (:authors ("boyw165")) (:maintainer "boyw165"))])
+ (secretaria . [(20191128 250) ((emacs (24 4)) (alert (1 2)) (s (1 12)) (f (0 20 0)) (org (9))) "A personal assistant based on org-mode" single ((:commit . "03986130a2ada1fa952d45e83536729f20230fcf") (:authors ("Jorge Araya Navarro" . "jorge@esavara.cr")) (:maintainer "Jorge Araya Navarro" . "jorge@esavara.cr") (:keywords "org" "convenience") (:url . "https://gitlab.com/shackra/secretaria"))])
+ (see-mode . [(20180511 41) ((emacs (24 4)) (language-detection (0 1 0))) "Edit string in a separate buffer" single ((:commit . "b6e72ea90105b03816c334be9e43bb41dcc79abf") (:authors ("Marcelo Muñoz" . "ma.munoz.araya@gmail.com")) (:maintainer "Marcelo Muñoz" . "ma.munoz.araya@gmail.com") (:keywords "convenience") (:url . "https://github.com/marcelino-m/see-mode"))])
+ (seeing-is-believing . [(20170214 1320) nil "minor mode for running the seeing-is-believing ruby gem" single ((:commit . "fbbe246c0fda87bb26227bb826eebadb418a220f") (:authors ("John Cinnamond")) (:maintainer "John Cinnamond"))])
+ (seen-mode . [(20210311 1935) ((emacs (24 4))) "A syntax highlighting package for text/kepago" single ((:commit . "57c960d76ad3dc551ac5a57ebe8682ef9fdc6d31") (:authors ("Filipe da Silva Santos" . "contact@shiori.com.br")) (:maintainer "Filipe da Silva Santos" . "contact@shiori.com.br") (:keywords "languages") (:url . "https://git.sr.ht/~shiorid/seen.el"))])
+ (seethru . [(20150218 1829) ((shadchen (1 4))) "Easily change Emacs' transparency" single ((:commit . "d87e231f99313bea75b1e69e48c0f32968c82060") (:authors ("Benaiah Mischenko" . "benaiah@mischenko.com")) (:maintainer "Benaiah Mischenko" . "benaiah@mischenko.com") (:keywords "lisp" "tools" "alpha" "transparency") (:url . "http://github.com/benaiah/seethru"))])
+ (sekka . [(20170803 1247) ((cl-lib (0 3)) (concurrent (0 3 1)) (popup (0 5 2))) "A client for Sekka IME server" single ((:commit . "61840b57d9ae32bf8e297b175942590a1319c7e7") (:authors ("Kiyoka Nishiyama" . "kiyoka@sumibi.org")) (:maintainer "Kiyoka Nishiyama" . "kiyoka@sumibi.org") (:keywords "ime" "skk" "japanese") (:url . "https://github.com/kiyoka/sekka"))])
+ (select-themes . [(20160221 106) nil "Color theme selection with completing-read" single ((:commit . "236f54287519a3ea6dd7b3992d053e4f4ff5d0fe") (:authors ("Jason Milkins" . "jasonm23@gmail.com")) (:maintainer "Jason Milkins" . "jasonm23@gmail.com") (:url . "https://github.com/jasonm23/emacs-select-themes"))])
+ (selected . [(20200528 606) nil "Keymap for when region is active" single ((:commit . "3043fd2609f7e71d809763ae6e8dd4b6c904e63d") (:authors ("Erik Sjöstrand")) (:maintainer "Erik Sjöstrand") (:keywords "convenience") (:url . "http://github.com/Kungsgeten/selected.el"))])
+ (selectric-mode . [(20200209 2107) nil "IBM Selectric mode for Emacs" tar ((:commit . "1840de71f7414b7cd6ce425747c8e26a413233aa") (:authors ("Ricardo Bánffy" . "rbanffy@gmail.com")) (:maintainer "Ricardo Banffy" . "rbanffy@gmail.com") (:keywords "multimedia" "convenience" "typewriter" "selectric") (:url . "https://github.com/rbanffy/selectric-mode"))])
+ (selectrum . [(20220323 10) ((emacs (26 1))) "Easily select item from list" single ((:commit . "7da932eeb89f1aa8060a73ddd040f95bbb127343") (:authors ("Radon Rosborough" . "radon.neon@gmail.com")) (:maintainer "Radon Rosborough" . "radon.neon@gmail.com") (:keywords "extensions") (:url . "https://github.com/raxod502/selectrum"))])
+ (selectrum-prescient . [(20211228 417) ((emacs (25 1)) (prescient (5 2)) (selectrum (3 1))) "Selectrum integration" single ((:commit . "d9b30d741c729a37eb2c6e51d72281c0844780ca") (:authors ("Radon Rosborough" . "radon.neon@gmail.com")) (:maintainer "Radon Rosborough" . "radon.neon@gmail.com") (:keywords "extensions") (:url . "https://github.com/raxod502/prescient.el"))])
+ (semaphore . [(20190607 1949) ((emacs (26))) "Semaphore based on condition variables" single ((:commit . "a069b69018b96d284ce7553cd63350a88ea3679c") (:authors ("Herwig Hochleitner" . "herwig@bendlas.net")) (:maintainer "Herwig Hochleitner" . "herwig@bendlas.net") (:keywords "processes" "unix") (:url . "http://github.com/webnf/semaphore.el"))])
+ (semaphore-promise . [(20190607 2115) ((emacs (26)) (semaphore (1)) (promise (1))) "semaphore integration with promise" single ((:commit . "a069b69018b96d284ce7553cd63350a88ea3679c") (:authors ("Herwig Hochleitner" . "herwig@bendlas.net")) (:maintainer "Herwig Hochleitner" . "herwig@bendlas.net") (:keywords "processes" "unix") (:url . "http://github.com/webnf/semaphore.el"))])
+ (semi . [(20220503 1449) ((emacs (24 5)) (apel (10 8)) (flim (1 14 9))) "A library to provide MIME features." tar ((:commit . "b1c245b81715b0430f7593cee2339e6264104f3d"))])
+ (seml-mode . [(20200812 1027) ((emacs (25 1)) (impatient-mode (1 1)) (htmlize (1 5)) (web-mode (16 0))) "Major-mode for SEML, S-Expression Markup Language, file" single ((:commit . "7a9a8305f7b54ee59e4c29b33ef5fd4058ba4219") (:authors ("Naoya Yamashita" . "conao3@gmail.com")) (:maintainer "Naoya Yamashita" . "conao3@gmail.com") (:keywords "lisp" "html") (:url . "https://github.com/conao3/seml-mode.el"))])
+ (sendto . [(20160425 1250) ((emacs (24 4))) "send the region content to a function" single ((:commit . "076b81d7a53f75b0a59b0ef3448f35570567054c") (:authors ("DarkSun" . "lujun9972@gmail.com")) (:maintainer "DarkSun" . "lujun9972@gmail.com") (:keywords "convenience" "region") (:url . "https://github.com/lujun9972/sendto.el"))])
+ (sensei . [(20220502 2012) ((emacs (27 1)) (projectile (2 5 0)) (request (0 3 2))) "A client for sensei" single ((:commit . "1294a96f544fd1be9ddaea3a85369fcf437403e9") (:authors ("Arnaud Bailly" . "arnaud@pankzsoft.com")) (:maintainer "Arnaud Bailly" . "arnaud@pankzsoft.com") (:keywords "hypermedia") (:url . "https://abailly.github.io/sensei"))])
+ (sensitive . [(20170818 1251) ((emacs (24)) (sequences (0 1 0))) "A dead simple way to load sensitive information" single ((:commit . "69dd6125a41d8b55f4b6ba61daa4d1aa1f716fa8") (:authors ("Tim Visher" . "tim.visher@gmail.com")) (:maintainer "Tim Visher" . "tim.visher@gmail.com") (:keywords "convenience"))])
+ (sentence-navigation . [(20180408 1619) ((ample-regexps (0 1)) (cl-lib (0 5)) (emacs (24 4))) "Commands to navigate one-spaced sentences." single ((:commit . "7c5d2edeaed01196aec25031782e89adeaa089f0") (:authors ("Fox Kiester" . "noct@openmailbox.org")) (:maintainer "Fox Kiester" . "noct@openmailbox.org") (:keywords "sentence" "evil") (:url . "https://github.com/noctuid/emacs-sentence-navigation"))])
+ (seoul256-theme . [(20180505 757) ((emacs (24 3))) "Low-contrast color scheme based on Seoul Colors." single ((:commit . "d28a9de73a5ffb1a1c9492db75a5c1efe5e9815f") (:authors ("Anand Iyer" . "anand.ucb@gmail.com")) (:maintainer "Anand Iyer" . "anand.ucb@gmail.com") (:keywords "theme") (:url . "http://github.com/anandpiyer/seoul256-emacs"))])
+ (separedit . [(20220501 1539) ((emacs (25 1)) (dash (2 18)) (edit-indirect (0 1 5))) "Edit comment/string/docstring/code block in separate buffer" single ((:commit . "454c9a3561acca3d57cce6ddb356f686b3d8cbee") (:authors ("Gong Qijian" . "gongqijian@gmail.com")) (:maintainer "Gong Qijian" . "gongqijian@gmail.com") (:keywords "tools" "languages" "docs") (:url . "https://github.com/twlz0ne/separedit.el"))])
+ (sequed . [(20220115 743) ((emacs (25 2))) "Major mode for FASTA format DNA alignments" single ((:commit . "3137bc32c8a6a84dbdb61b4ee029b0e382939adb") (:authors ("Bruce Rannala" . "brannala@ucdavis.edu")) (:maintainer "Bruce Rannala" . "brannala@ucdavis.edu") (:url . "https://github.com/brannala/sequed"))])
+ (sequences . [(20170818 1252) ((emacs (24))) "Ports of some Clojure sequence functions." single ((:commit . "564ebbd93b0beea4e75acfbf824350e90b5d5738") (:authors ("Tim Visher" . "tim.visher@gmail.com")) (:maintainer "Tim Visher" . "tim.visher@gmail.com") (:keywords "convenience"))])
+ (sequential-command . [(20170926 40) nil "Many commands into one command" tar ((:commit . "a48cbcbe273b33edd3ae56e68f44b4100fa3a48a") (:authors ("rubikitch" . "rubikitch@ruby-lang.org")) (:maintainer "rubikitch" . "rubikitch@ruby-lang.org") (:keywords "convenience" "lisp") (:url . "http://www.emacswiki.org/cgi-bin/wiki/download/sequential-command.el"))])
+ (seriestracker . [(20220212 304) ((dash (2 12 1)) (transient (0 3 2)) (emacs (27 1))) "Series tracker" single ((:commit . "4706db081bd214b272e0bcaabb66887e4b5b0968") (:authors ("Maxime Wack <contact at maximewack dot com>")) (:maintainer "Maxime Wack <contact at maximewack dot com>") (:keywords "multimedia") (:url . "https://www.github.com/MaximeWack/seriesTracker"))])
+ (servant . [(20140216 1219) ((s (1 8 0)) (dash (2 2 0)) (f (0 11 0)) (ansi (0 3 0)) (commander (0 5 0)) (epl (0 2)) (shut-up (0 2 1)) (web-server (0 0 1))) "ELPA server written in Emacs Lisp" tar ((:commit . "4d2aa8250b54b28e6e7ee4cd5ebd98a33db2c134") (:authors ("Johan Andersson" . "johan.rejeep@gmail.com") ("Sebastian Wiesner" . "lunaryorn@gmail.com")) (:maintainer "Johan Andersson" . "johan.rejeep@gmail.com") (:keywords "elpa" "server") (:url . "http://github.com/rejeep/servant.el"))])
+ (serverspec . [(20150623 1155) ((dash (2 6 0)) (s (1 9 0)) (f (0 16 2)) (helm (1 6 1))) "Serverspec minor mode" tar ((:commit . "b6dfe82af9869438de5e5d860ced196641f372c0") (:authors ("k1LoW (Kenichirou Oyama), <k1lowxb [at] gmail [dot] com> <k1low [at] 101000lab [dot] org>")) (:maintainer "k1LoW (Kenichirou Oyama), <k1lowxb [at] gmail [dot] com> <k1low [at] 101000lab [dot] org>") (:url . "http://101000lab.org"))])
+ (services . [(20170802 1130) ((cl-lib (0 5))) "Services database access functions." single ((:commit . "04c7986041a33dfa0b0ae57c7d6fbd600548c596") (:authors ("Dave Pearson" . "davep@davep.org")) (:maintainer "Dave Pearson" . "davep@davep.org") (:keywords "convenience" "net" "services") (:url . "https://github.com/davep/services.el"))])
+ (sesman . [(20210901 1134) ((emacs (25))) "Generic Session Manager" tar ((:commit . "e0f555f963c9f02f8e4a50e06fc353eb4c15ee77") (:authors ("Vitalie Spinu")) (:maintainer "Vitalie Spinu") (:keywords "process") (:url . "https://github.com/vspinu/sesman"))])
+ (session . [(20120511 0) nil "use variables, registers and buffer places across sessions" single ((:commit . "19ea0806873daac3539a4b956e15655e99e3dd6c") (:authors ("Christoph Wedler" . "wedler@users.sourceforge.net")) (:maintainer "Christoph Wedler" . "wedler@users.sourceforge.net") (:keywords "session" "session management" "desktop" "data" "tools") (:url . "http://emacs-session.sourceforge.net/"))])
+ (session-async . [(20220302 2008) ((emacs (27 1)) (jsonrpc (1 0 9))) "Asynchronous processing in a forked process session" single ((:commit . "427238bdfde880106dd39cf5845b559975e52f4f") (:authors ("Felipe Lema" . "felipelema@mortemale.org")) (:maintainer "Felipe Lema" . "felipelema@mortemale.org") (:keywords "async" "comm" "data" "files" "internal" "maint" "processes" "tools") (:url . "https://codeberg.org/FelipeLema/session-async.el"))])
+ (seti-theme . [(20190201 1848) nil "A dark colored theme, inspired by Seti Atom Theme" single ((:commit . "9d76db0b91d4f574dd96ac80fad41da35bffa109") (:authors ("Vlad Piersec" . "vlad.piersec@gmail.com")) (:maintainer "Vlad Piersec" . "vlad.piersec@gmail.com") (:keywords "themes") (:url . "https://github.com/caisah/seti-theme"))])
+ (sexp-diff . [(20200314 2018) ((emacs (25))) "Diff sexps based on Levenshtein-like edit distance" single ((:commit . "7e8c988bea2af209e17b70fa51316ade55529acb") (:authors ("Xu Chunyang")) (:maintainer "Xu Chunyang") (:keywords "lisp") (:url . "https://github.com/xuchunyang/sexp-diff.el"))])
+ (sexp-move . [(20150915 1730) nil "Improved S-Expression Movement" single ((:commit . "117f7a91ab7c25e438413753e916570122011ce7") (:authors ("Philip Woods" . "elzairthesorcerer@gmail.com")) (:maintainer "Philip Woods" . "elzairthesorcerer@gmail.com") (:keywords "sexp") (:url . "https://gitlab.com/elzair/sexp-move"))])
+ (sexy-monochrome-theme . [(20200115 2146) nil "A sexy dark Emacs >= 24 theme for your sexy code" single ((:commit . "f3ad07d60c966ef34cb11026eaba053e114bb8f1") (:authors ("Volodymyr Yevtushenko" . "voloyev@vivaldi.net")) (:maintainer "Volodymyr Yevtushenko" . "voloyev@vivaldi.net") (:keywords "themes") (:url . "https://github.com/voloyev/sexy-monochrome-theme"))])
+ (sfz-mode . [(20200716 1023) ((emacs (25 1))) "Major mode for SFZ files" single ((:commit . "aaf31d1b68817251affed7da719dfcb2acd4b51a") (:authors ("Jean Pierre Cimalando" . "jp-dev@inbox.ru")) (:maintainer "Jean Pierre Cimalando" . "jp-dev@inbox.ru") (:keywords "languages") (:url . "https://github.com/sfztools/emacs-sfz-mode"))])
+ (shackle . [(20211118 1129) ((emacs (24 3)) (cl-lib (0 5))) "Enforce rules for popups" single ((:commit . "f1467db75a8fa5d51c676181fb308ccbf7b05e6f") (:authors ("Vasilij Schneidermann" . "mail@vasilij.de")) (:maintainer "Vasilij Schneidermann" . "mail@vasilij.de") (:keywords "convenience") (:url . "https://depp.brause.cc/shackle"))])
+ (shadchen . [(20141102 1839) nil "pattern matching for elisp" single ((:commit . "35f2b9c304eec990c16efbd557198289dc7cbb1f") (:authors ("Vincent Toups")) (:maintainer "Vincent Toups"))])
+ (shader-mode . [(20180518 1157) ((emacs (24))) "Major mode for shader" single ((:commit . "d7dc8d0d6fe8914e8b6d5cf2081ad61e6952359c") (:authors ("midnightSuyama" . "midnightSuyama@gmail.com")) (:maintainer "midnightSuyama" . "midnightSuyama@gmail.com") (:url . "https://github.com/midnightSuyama/shader-mode"))])
+ (shades-of-purple-theme . [(20210506 1448) nil "A theme with bold shades of purple" single ((:commit . "e9d2ac081ae657b1ad6a30b9f53e8572479deb80") (:authors ("Arturo Vergara" . "hello@dead.computer")) (:maintainer "Arturo Vergara" . "hello@dead.computer") (:url . "https://github.com/arturovm/shades-of-purple-emacs"))])
+ (shadowenv . [(20210512 1625) ((emacs (24 3))) "Shadowenv integration." single ((:commit . "dbcef650b906fec62608d5e4e3075bf251e675e1") (:authors ("Dante Catalfamo" . "dante.catalfamo@shopify.com")) (:maintainer "Dante Catalfamo" . "dante.catalfamo@shopify.com") (:keywords "shadowenv" "tools") (:url . "https://github.com/Shopify/shadowenv.el"))])
+ (shakespeare-mode . [(20180704 2138) nil "A major mode for editing Shakespearean templates." single ((:commit . "c442eeea9d585e1b1fbb8813e33d47feec348a57") (:authors ("Cody Reichert")) (:maintainer "Cody Reichert") (:keywords "shakespeare" "hamlet" "lucius" "julius" "mode") (:url . "http://github.com/CodyReichert/shakespeare-mode"))])
+ (shampoo . [(20131230 1019) nil "A remote Smalltalk development mode" tar ((:commit . "bc193c39636c30182159c5c91c37a9a4cb50fedf"))])
+ (shanty-themes . [(20220405 1126) ((emacs (27 2))) "The themes for digital workers" tar ((:commit . "55b6a2653e43187559ff8b5103bcb9dc54e68ab6") (:authors ("Philip Gaber" . "phga@posteo.de")) (:maintainer "Philip Gaber" . "phga@posteo.de") (:keywords "faces" "theme" "blue" "yellow" "gold" "dark" "light") (:url . "https://github.com/qhga/shanty-themes"))])
+ (share2computer . [(20200316 31) ((emacs (25 1))) "Elisp helper of android ShareToComputer" single ((:commit . "15da47625a800e3310b8dc714bd4e41e32966d6a") (:authors ("Feng Shu" . "tumashu@163.com")) (:maintainer "Feng Shu" . "tumashu@163.com") (:keywords "convenience" "comm") (:url . "https://github.com/tumashu/share2computer"))])
+ (sharper . [(20220321 422) ((emacs (27 1)) (transient (0 2 0))) "A dotnet CLI wrapper, using Transient" single ((:commit . "96edd4a1dbc267afdff0cb97298d1b05b7c2080c") (:authors ("Sebastian Monia" . "smonia@outlook.com")) (:maintainer "Sebastian Monia" . "smonia@outlook.com") (:keywords "maint" "tool") (:url . "https://github.com/sebasmonia/sharper"))])
+ (shell-current-directory . [(20140101 2354) nil "create new shell based on buffer directory" single ((:commit . "bf843771bf9a4aa05e054ade799eb8862f3be89a") (:authors ("Daniel Polani")) (:maintainer "Daniel Polani") (:keywords "shell" "comint"))])
+ (shell-here . [(20220102 1703) nil "Open a shell relative to the working directory" single ((:commit . "eeb437ff26d62a5009046b1b3b4503b768e3131a") (:authors ("Ian Eure" . "ian.eure@gmail.com")) (:maintainer "Ian Eure" . "ian.eure@gmail.com") (:keywords "unix" "tools" "processes"))])
+ (shell-history . [(20100505 839) nil "integration with shell history" single ((:commit . "ee371a81f2d2bf5a308344078329ca1e9b5ed38c") (:authors ("rubikitch" . "rubikitch@ruby-lang.org")) (:maintainer "rubikitch" . "rubikitch@ruby-lang.org") (:keywords "processes" "convenience") (:url . "http://www.emacswiki.org/cgi-bin/wiki/download/shell-history.el"))])
+ (shell-pop . [(20200315 1139) ((emacs (24)) (cl-lib (0 5))) "helps you to use shell easily on Emacs. Only one key action to work." single ((:commit . "4b4394037940a890a313d715d203d9ead2d156a6") (:authors ("Kazuo YAGI" . "kazuo.yagi@gmail.com")) (:maintainer "Kazuo YAGI" . "kazuo.yagi@gmail.com") (:keywords "shell" "terminal" "tools") (:url . "http://github.com/kyagi/shell-pop-el"))])
+ (shell-split-string . [(20151224 1008) nil "Split strings using shell-like syntax" single ((:commit . "19f6f999c33cc66a4c91bacdcc3697c25d97bf5a") (:authors ("10sr <8.slashes+el [at] gmail [dot] com>")) (:maintainer "10sr <8.slashes+el [at] gmail [dot] com>") (:keywords "utility" "library" "shell" "string") (:url . "https://github.com/10sr/shell-split-string-el"))])
+ (shell-switcher . [(20210509 1045) ((emacs (24))) "Provide fast switching between shell buffers." tar ((:commit . "ed74b20fa12935be0068765f5bc8de97b92a8020") (:authors ("Damien Cassou" . "damien.cassou@gmail.com")) (:maintainer "Damien Cassou" . "damien.cassou@gmail.com") (:keywords "emacs" "package" "elisp" "shell" "eshell" "term" "switcher") (:url . "https://github.com/DamienCassou/shell-switcher"))])
+ (shell-toggle . [(20150226 1411) nil "Toggle to and from the shell buffer" single ((:commit . "0d01bd9a780fdb7fe6609c552523f4498649a3b9") (:authors ("Mikael Sjödin" . "mic@docs.uu.se") ("Matthieu Moy") ("Akinori MUSHA" . "knu@iDaemons.org")) (:maintainer "Mikael Sjödin" . "mic@docs.uu.se") (:keywords "processes") (:url . "https://github.com/knu/shell-toggle.el"))])
+ (shellcop . [(20220414 530) ((emacs (25 1))) "Analyze info&error in shell-mode" single ((:commit . "327f5ac43e5d543149a772aef06cdb616477eb43") (:authors ("Chen Bin" . "chenbin.sh@gmail.com")) (:maintainer "Chen Bin" . "chenbin.sh@gmail.com") (:keywords "unix" "tools") (:url . "https://github.com/redguardtoo/shellcop"))])
+ (shelldoc . [(20200513 1206) ((cl-lib (0 3)) (s (1 9 0))) "shell command editing support with man page." single ((:commit . "fa69f67b6229fad3f31d936955ca8d1982009b77") (:authors ("Masahiro Hayashi" . "mhayashi1120@gmail.com")) (:maintainer "Masahiro Hayashi" . "mhayashi1120@gmail.com") (:keywords "applications") (:url . "http://github.com/mhayashi1120/Emacs-shelldoc"))])
+ (shelldon . [(20220325 1305) ((emacs (27 1))) "An enhanced shell interface" single ((:commit . "8d073ce580e7782ed863fc6e19dc33b4f73c0d79") (:authors ("overdr0ne" . "scmorris.dev@gmail.com")) (:maintainer "overdr0ne" . "scmorris.dev@gmail.com") (:keywords "tools" "convenience") (:url . "https://github.com/Overdr0ne/shelldon"))])
+ (shelltest-mode . [(20180501 141) nil "Major mode for shelltestrunner" single ((:commit . "5fea8c9394380e822971a171905b6b5ab9be812d") (:authors ("Dustin Fechner" . "dfe@rtrn.io")) (:maintainer "Dustin Fechner" . "dfe@rtrn.io") (:keywords "languages") (:url . "https://github.com/rtrn/shelltest-mode"))])
+ (shen-elisp . [(20210530 349) ((emacs (24 4))) "Shen implementation in Elisp" tar ((:commit . "dabb829d0d86f454ceb3b0846cdfc11af1f91cc7") (:authors ("Aditya Siram" . "aditya.siram@gmail.com")) (:maintainer "Aditya Siram" . "aditya.siram@gmail.com") (:url . "https://github.com/deech/shen-elisp"))])
+ (shenshou . [(20220324 1137) ((emacs (25 1))) "Download subtitles from opensubtitles.org" single ((:commit . "bc16a637edaaca831a5147b6f479ba1dbdc02454") (:authors ("Chen Bin <chenbin DOT sh AT gmail DOT com>")) (:maintainer "Chen Bin <chenbin DOT sh AT gmail DOT com>") (:keywords "convenience" "tools") (:url . "http://github.com/redguardtoo/shenshou"))])
+ (shfmt . [(20210803 222) ((emacs (24)) (reformatter (0 3))) "Reformat shell scripts using shfmt" single ((:commit . "ceb1ed4df3d7e198e4c5af0c2fd44c4d9d65832e") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:keywords "languages") (:url . "https://github.com/purcell/emacs-shfmt"))])
+ (shift-number . [(20170301 1459) nil "Increase/decrease the number at point" single ((:commit . "cd099a5582fc996b800ac7607f6c38a004ce9740") (:authors ("Alex Kost" . "alezost@gmail.com")) (:maintainer "Alex Kost" . "alezost@gmail.com") (:keywords "convenience") (:url . "https://github.com/alezost/shift-number.el"))])
+ (shift-text . [(20130831 1655) ((cl-lib (1 0)) (es-lib (0 3))) "Move the region in 4 directions, in a way similar to Eclipse's" single ((:commit . "1be9cbf994000022172ceb746fe1d597f57ea8ba") (:authors ("sabof")) (:maintainer "sabof") (:url . "https://github.com/sabof/shift-text"))])
+ (shimbun . [(20220426 715) nil "interfacing with web newspapers" tar ((:commit . "2420e7fb0d11372f1fa898a3b996bf2ce00fe66a") (:authors ("TSUCHIYA Masatoshi" . "tsuchiya@namazu.org") ("Akihiro Arisawa " . "ari@mbf.sphere.ne.jp") ("Yuuichi Teranishi " . "teranisi@gohome.org") ("Katsumi Yamaoka " . "yamaoka@jpl.org")) (:maintainer "TSUCHIYA Masatoshi" . "tsuchiya@namazu.org") (:keywords "news"))])
+ (shm . [(20180327 57) nil "Structured Haskell Mode" tar ((:commit . "7f9df73f45d107017c18ce4835bbc190dfe6782e") (:authors ("Chris Done" . "chrisdone@gmail.com")) (:maintainer "Chris Done" . "chrisdone@gmail.com") (:keywords "development" "haskell" "structured"))])
+ (shoulda . [(20140616 1833) ((cl-lib (0 5))) "Shoulda test support for ruby" single ((:commit . "fbe8eb8efc6cfcca1713283a290882cfcdc8725e") (:authors ("Marcwebbie" . "marcwebbie@gmail.com")) (:maintainer "Marcwebbie" . "marcwebbie@gmail.com") (:keywords "ruby" "tests" "shoulda"))])
+ (show-css . [(20160210 1408) ((doom (1 3)) (s (1 10 0))) "Show the css of the html attribute the cursor is on" tar ((:commit . "771daeddd4df7a7c10f66419a837145649bab63b") (:authors ("Sheldon McGrandle" . "developer@rednemesis.com")) (:maintainer "Sheldon McGrandle" . "developer@rednemesis.com") (:keywords "hypermedia") (:url . "https://github.com/smmcg/showcss-mode"))])
+ (show-eol . [(20210715 1227) ((emacs (24 4))) "Show end of line symbol in buffer" single ((:commit . "09aaba23300b9fa3cfd15ceb0e62da4a3d53e7e5") (:authors ("Shen, Jen-Chieh" . "jcs090218@gmail.com")) (:maintainer "Shen, Jen-Chieh" . "jcs090218@gmail.com") (:url . "https://github.com/jcs-elpa/show-eol"))])
+ (show-font-mode . [(20201225 2217) ((emacs (25 1))) "Show font at point on mode line" single ((:commit . "8503be7966d3bd8316039b5f49d3c37c7b97d10c") (:authors ("Melissa Boiko" . "melissa@namakajiri.net")) (:maintainer "Melissa Boiko" . "melissa@namakajiri.net") (:keywords "faces" "i18n" "unicode" "fonts" "fontsets") (:url . "https://github.com/melissaboiko/show-font-mode"))])
+ (showtip . [(20090830 1040) nil "Show tip at cursor" single ((:commit . "930da302809a4257e8d69425455b29e1cc91949b") (:authors ("Ye Wenbin" . "wenbinye@gmail.com")) (:maintainer "Ye Wenbin" . "wenbinye@gmail.com") (:keywords "help"))])
+ (shpec-mode . [(20150530 922) nil "Minor mode for shpec specification" single ((:commit . "146adc8281d0f115df39a3a3f982ac59ab61b754") (:authors ("AdrieanKhisbe" . "adriean.khisbe@live.fr")) (:maintainer "AdrieanKhisbe" . "adriean.khisbe@live.fr") (:keywords "languages" "tools") (:url . "http://github.com/shpec/shpec-mode"))])
+ (shr-tag-pre-highlight . [(20200626 1047) ((emacs (25 1)) (language-detection (0 1 0))) "Syntax highlighting code block in HTML" single ((:commit . "931c447bc0d6c134ddc9657c664eeee33afbc54d") (:authors ("Chunyang Xu" . "mail@xuchunyang.me")) (:maintainer "Chunyang Xu" . "mail@xuchunyang.me") (:keywords "html") (:url . "https://github.com/xuchunyang/shr-tag-pre-highlight.el"))])
+ (shrface . [(20210829 1013) ((emacs (25 1)) (org (9 0)) (language-detection (0 1 0))) "Extend shr/eww with org features and analysis capability" single ((:commit . "b8a23e097b25d6c7754f9aaf4de89259f8a0b17d") (:authors ("Damon Chan" . "elecming@gmail.com")) (:maintainer "Damon Chan" . "elecming@gmail.com") (:keywords "faces") (:url . "https://github.com/chenyanming/shrface"))])
+ (shrink-path . [(20190208 1335) ((emacs (24)) (s (1 6 1)) (dash (1 8 0)) (f (0 10 0))) "fish-style path" single ((:commit . "c14882c8599aec79a6e8ef2d06454254bb3e1e41") (:authors ("Benjamin Andresen")) (:maintainer "Benjamin Andresen") (:url . "https://gitlab.com/bennya/shrink-path.el"))])
+ (shrink-whitespace . [(20181003 321) nil "Whitespace removal DWIM key" single ((:commit . "0407b89c142bd17e65edb666f35e2c6755bd0867") (:authors ("Jean-Christophe Petkovich" . "jcpetkovich@gmail.com")) (:maintainer "Jean-Christophe Petkovich" . "jcpetkovich@gmail.com") (:keywords "convenience") (:url . "https://gitlab.com/jcpetkovich/shrink-whitespace.el"))])
+ (shroud . [(20210220 1952) ((emacs (25)) (epg (1 0 0)) (s (1 6 0)) (bui (1 2 0)) (dash (2 18 0))) "Shroud secrets" tar ((:commit . "2e6ff2bab4a1e798c090c9d7fbd90b7f3463d5c5") (:authors ("Amar Singh" . "nly@disroot.org")) (:maintainer "Amar Singh" . "nly@disroot.org") (:keywords "tools" "password") (:url . "https://github.com/o-nly/emacs-shroud"))])
+ (shut-up . [(20210403 1249) ((cl-lib (0 3)) (emacs (24))) "Shut up would you!" single ((:commit . "ff6f06f3b080ee833a25a22da8cb5b96e911dc77") (:authors ("Johan Andersson" . "johan.rejeep@gmail.com")) (:maintainer "Johan Andersson" . "johan.rejeep@gmail.com") (:url . "http://github.com/rejeep/shut-up.el"))])
+ (shx . [(20201121 1824) ((emacs (24 4))) "Extras for the comint-mode shell" single ((:commit . "09ae2124369ded4f38459d2456f72536d172227a") (:keywords "terminals" "processes" "comint" "shell" "repl") (:url . "https://github.com/riscy/shx-for-emacs"))])
+ (sibilant-mode . [(20151119 2145) nil "Support for the Sibilant programming language" single ((:commit . "bc1b5d8cd597918bafc9b2880ee49024740e54ab") (:authors ("Jacob Rothstein" . "hi@jbr.me")) (:maintainer "Jacob Rothstein" . "hi@jbr.me") (:keywords "languages") (:url . "http://sibilantjs.info"))])
+ (sicp . [(20200512 1137) nil "Structure and Interpretation of Computer Programs in info format" tar ((:commit . "4002d83083d520c6b5ede2df36cc2cee885d450a") (:authors ("Hal Abelson") ("Jerry Sussman") ("Julie Sussman")) (:maintainer "Hal Abelson") (:url . "https://mitpress.mit.edu/sicp"))])
+ (side-hustle . [(20210627 701) ((emacs (24 4)) (seq (2 20))) "Hustle through Imenu in a side window" single ((:commit . "1f4cd5e7cfbabb00c6d87e913770f21e3d16c957") (:authors ("Paul W. Rankin" . "pwr@bydasein.com")) (:maintainer "Paul W. Rankin" . "pwr@bydasein.com") (:keywords "convenience") (:url . "https://github.com/rnkn/side-hustle"))])
+ (side-notes . [(20210709 1403) ((emacs (24 4))) "Easy access to a directory notes file" single ((:commit . "41fe8544661a772f764a0924e04080f258053955") (:authors ("Paul W. Rankin" . "pwr@bydasein.com")) (:maintainer "Paul W. Rankin" . "pwr@bydasein.com") (:keywords "convenience") (:url . "https://github.com/rnkn/side-notes"))])
+ (sidecar-locals . [(20220421 145) ((emacs (27 1))) "A flexible alternative to built-in dir-locals" single ((:commit . "6a5fe7da992f057232bd5a57d275d9ff6311864f") (:authors ("Campbell Barton" . "ideasman42@gmail.com")) (:maintainer "Campbell Barton" . "ideasman42@gmail.com") (:keywords "convenience") (:url . "https://gitlab.com/ideasman42/emacs-sidecar-locals"))])
+ (sift . [(20200421 1423) nil "Front-end for sift, a fast and powerful grep alternative" single ((:commit . "cdddba2d183146c340915003f1b5d09d13712c22") (:authors ("Nicolas Lamirault" . "nicolas.lamirault@gmail.com")) (:maintainer "Nicolas Lamirault" . "nicolas.lamirault@gmail.com") (:keywords "sift" "ack" "pt" "ag" "grep" "search") (:url . "https://github.com/nlamirault/sift.el"))])
+ (signal . [(20160816 1438) ((emacs (24)) (cl-lib (0 5))) "Advanced hook" single ((:commit . "aa58327e2297df921d72a0370468b48663efd438") (:authors ("Mola-T" . "Mola@molamola.xyz")) (:maintainer "Mola-T" . "Mola@molamola.xyz") (:keywords "internal" "lisp" "processes" "tools") (:url . "https://github.com/mola-T/signal"))])
+ (silkworm-theme . [(20210215 1120) ((emacs (24))) "Light theme with pleasant, low contrast colors." single ((:commit . "ff80e9294da0fb093e15097ac62153ef4a64a889") (:authors ("Martin Haesler")) (:maintainer "Martin Haesler"))])
+ (simp . [(20180607 254) nil "Simple project definition, chiefly for file finding, and grepping" tar ((:commit . "d4d4b8547055347828bedccbeffdb4fd2d5a5d34") (:authors ("atom smith")) (:maintainer "atom smith") (:keywords "project" "grep" "find") (:url . "https://github.com/re5et/simp"))])
+ (simple-bookmarks . [(20190204 1426) ((cl-lib (0 5))) "Bookmark / functioncall manager" tar ((:commit . "54e8d771bcdb0eb235b31c0aa9642171369500e5") (:authors ("Julian T. Knabenschuh" . "jtkdevelopments@gmail.com")) (:maintainer "Julian T. Knabenschuh" . "jtkdevelopments@gmail.com") (:keywords "bookmark" "functioncall") (:url . "https://github.com/jtkDvlp/simple-bookmarks"))])
+ (simple-call-tree . [(20210625 2001) ((emacs (24 3)) (anaphora (1 0 0))) "analyze source code based on font-lock text-properties" single ((:commit . "26de24bcde0eae911a0185bb5a6b74b9864fcfc3") (:authors ("Joe Bloggs" . "vapniks@yahoo.com")) (:maintainer "Joe Bloggs" . "vapniks@yahoo.com") (:keywords "programming") (:url . "http://www.emacswiki.org/emacs/download/simple-call-tree.el"))])
+ (simple-httpd . [(20191103 1446) ((cl-lib (0 3))) "pure elisp HTTP server" single ((:commit . "22ce66ea43e0eadb9ec1d691a35d9695fc29cee6") (:authors ("Christopher Wellons" . "wellons@nullprogram.com")) (:maintainer "Christopher Wellons" . "wellons@nullprogram.com") (:url . "https://github.com/skeeto/emacs-http-server"))])
+ (simple-indentation . [(20220215 1745) ((emacs (24 3)) (dash (2 18 0)) (s (1 12 0))) "Simplify writing indentation functions, alternative to SMIE" tar ((:commit . "e7c8238af9e1a6b1fc4dab8014d779ac178fc249") (:authors ("Semen Khramtsov" . "hrams205@gmail.com")) (:maintainer "Semen Khramtsov" . "hrams205@gmail.com") (:url . "https://github.com/semenInRussia/simple-indentation.el"))])
+ (simple-modeline . [(20210312 1048) ((emacs (26 1))) "A simple mode-line configuration for Emacs" tar ((:commit . "119d8224a8ae0ee17b09ac1fed6cdb9cb1d048fd") (:authors ("Eder Elorriaga" . "gexplorer8@gmail.com")) (:maintainer "Eder Elorriaga" . "gexplorer8@gmail.com") (:keywords "mode-line" "faces") (:url . "https://github.com/gexplorer/simple-modeline"))])
+ (simple-mpc . [(20220216 102) ((s (1 10 0))) "provides a simple interface to mpc" tar ((:commit . "57ee14ada8aec477ddde5e4f632c8d3d99a66535") (:authors ("Joren Van Onder" . "joren@jvo.sh")) (:maintainer "Joren Van Onder" . "joren@jvo.sh") (:keywords "multimedia" "mpd" "mpc") (:url . "https://github.com/jorenvo/simple-mpc"))])
+ (simple-paren . [(20220207 2007) ((emacs (24)) (cl-lib (0 5))) "Non-electrical insert paired delimiter, wrap" single ((:commit . "a454901635dfe4142d8c4f0153e737ddc778d708") (:authors ("Andreas Röhler, Steve Purcell")) (:maintainer "Andreas Röhler, Steve Purcell") (:keywords "convenience") (:url . "https://github.com/andreas-roehler/simple-paren"))])
+ (simple-rtm . [(20160222 1534) ((rtm (0 1)) (dash (2 0 0))) "Interactive Emacs mode for Remember The Milk" single ((:commit . "8c7cd96cf66ef112be5c363e3378e304f8f83999") (:authors ("Moritz Bunkus" . "morit@bunkus.org")) (:maintainer "Moritz Bunkus" . "morit@bunkus.org") (:keywords "remember" "the" "milk" "productivity" "todo"))])
+ (simple-screen . [(20200926 109) nil "Simple screen configuration manager" single ((:commit . "3ce535755986f7c25890d11e42fa621a3a069a4f") (:authors ("Tadashi Watanabe" . "wac@umiushi.org")) (:maintainer "Tadashi Watanabe" . "wac@umiushi.org") (:keywords "tools") (:url . "https://github.com/wachikun/simple-screen"))])
+ (simpleclip . [(20210406 1221) nil "Simplified access to the system clipboard" single ((:commit . "67c8c17adbbe6d9407a5ce4159d097a8b8bf6adb") (:authors ("Roland Walker" . "walker@pobox.com")) (:maintainer "Roland Walker" . "walker@pobox.com") (:keywords "convenience") (:url . "http://github.com/rolandwalker/simpleclip"))])
+ (simplenote . [(20141118 1440) nil "Interact with simple-note.appspot.com" single ((:commit . "e836fcdb5a6497a9ffd6bceddd19b4bc52189078") (:authors ("Konstantinos Efstathiou" . "konstantinos@efstathiou.gr")) (:maintainer "Konstantinos Efstathiou" . "konstantinos@efstathiou.gr") (:keywords "simplenote"))])
+ (simplenote2 . [(20190321 933) ((request-deferred (0 2 0)) (uuidgen (20140918)) (unicode-escape (1 1))) "Interact with app.simplenote.com" tar ((:commit . "760ffecda63bd218876b623f46d332e3ef079be6") (:authors ("alpha22jp" . "alpha22jp@gmail.com")) (:maintainer "alpha22jp" . "alpha22jp@gmail.com") (:keywords "simplenote"))])
+ (simplezen . [(20130421 1000) ((s (1 4 0)) (dash (1 1 0))) "A simple subset of zencoding-mode for Emacs." single ((:commit . "119fdf2c6890a0c56045ae72cf4fce0071a81481") (:authors ("Magnar Sveen" . "magnars@gmail.com")) (:maintainer "Magnar Sveen" . "magnars@gmail.com"))])
+ (simplicity-theme . [(20220217 1928) ((emacs (24 1))) "A minimalist dark theme" single ((:commit . "2a0aaf19cf1e99c50df0d2e6225a2d2931a203d2") (:authors ("Matthieu Petiteau" . "mpetiteau.pro@gmail.com")) (:maintainer "Matthieu Petiteau" . "mpetiteau.pro@gmail.com") (:keywords "faces" "theme" "minimal") (:url . "http://github.com/smallwat3r/emacs-simplicity-theme"))])
+ (siri-shortcuts . [(20211229 1833) ((emacs (25 2))) "Interact with Siri Shortcuts" single ((:commit . "190f242f71e071adfd89fa1f2f6ea22b62afd133") (:authors ("Daniils Petrovs" . "thedanpetrov@gmail.com")) (:maintainer "Daniils Petrovs" . "thedanpetrov@gmail.com") (:keywords "convenience" "multimedia") (:url . "https://github.com/DaniruKun/siri-shortcuts.el"))])
+ (sis . [(20220504 1316) ((emacs (25 1)) (terminal-focus-reporting (0 0))) "Less manual switch for native or OS input source (input method)." single ((:commit . "a72e09246bc5be7a164932c51e7dd2a5d2d97858") (:keywords "convenience") (:url . "https://github.com/laishulu/emacs-smart-input-source"))])
+ (skeletor . [(20210129 239) ((s (1 7 0)) (f (0 14 0)) (dash (2 2 0)) (cl-lib (0 3)) (let-alist (1 0 3)) (emacs (24 1))) "Provides project skeletons for Emacs" tar ((:commit . "f6e560a0bfe459e0b8a268047920ce1148f2ebf6") (:authors ("Chris Barrett" . "chris.d.barrett@me.com")) (:maintainer "Chris Barrett" . "chris.d.barrett@me.com"))])
+ (skerrick . [(20220306 2139) ((emacs (27 1)) (request (0 3 2))) "REPL-driven development for NodeJS" single ((:commit . "fc88e82aa4b0a71b1fbe0217df4020538ebd8cd5") (:authors ("Rafael Nicdao <https://github.com/anonimitoraf>")) (:maintainer "Rafael Nicdao" . "nicdaoraf@gmail.com") (:keywords "languages" "javascript" "js" "repl" "repl-driven") (:url . "https://github.com/anonimitoraf/skerrick"))])
+ (sketch-themes . [(20220404 1741) ((emacs (26 1))) "Sketch color themes" tar ((:commit . "8a609ec8fbf12231ba67aab9fcbb6b3ad0420359") (:authors ("Daw-Ran Liou" . "hi@dawranliou.com")) (:maintainer "Daw-Ran Liou" . "hi@dawranliou.com") (:keywords "faces") (:url . "https://github.com/dawranliou/sketch-themes/"))])
+ (skewer-less . [(20210510 532) ((skewer-mode (1 5 3))) "Skewer support for live LESS stylesheet updates" single ((:commit . "baa973581c2ab7326db65803df97d1a7382b6564") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:keywords "languages" "tools"))])
+ (skewer-mode . [(20200304 1142) ((simple-httpd (1 4 0)) (js2-mode (20090723)) (emacs (24))) "live browser JavaScript, CSS, and HTML interaction" tar ((:commit . "e5bed351939c92a1f788f78398583c2f83f1bb3c") (:authors ("Christopher Wellons" . "wellons@nullprogram.com")) (:maintainer "Christopher Wellons" . "wellons@nullprogram.com") (:url . "https://github.com/skeeto/skewer-mode"))])
+ (skewer-reload-stylesheets . [(20160725 1220) ((skewer-mode (1 5 3))) "live-edit CSS, SCSS, Less, and friends." tar ((:commit . "b9cc5635230ac3c0603a6da690c6e632d0a7490a") (:authors ("Nate Eagleson" . "nate@nateeag.com")) (:maintainer "Nate Eagleson" . "nate@nateeag.com"))])
+ (skype . [(20160711 824) nil "skype UI for emacs users.." tar ((:commit . "8e3b33e620ed355522aa36434ff41e3ced080629") (:authors ("SAKURAI Masashi" . "m.sakurai@kiwanami.net")) (:maintainer "SAKURAI Masashi" . "m.sakurai@kiwanami.net") (:keywords "skype" "chat"))])
+ (sl . [(20161217 1404) ((cl-lib (0 5))) "An Emacs clone of sl(1)" tar ((:commit . "fceb2ae12a3065b2a265b921baca0891c5ea54dc") (:authors ("Chunyang Xu" . "mail@xuchunyang.me")) (:maintainer "Chunyang Xu" . "mail@xuchunyang.me") (:url . "https://github.com/xuchunyang/sl.el"))])
+ (slack . [(20211129 310) ((websocket (1 8)) (request (0 2 0)) (oauth2 (0 10)) (circe (2 2)) (alert (1 2)) (emojify (0 2))) "Slack client for Emacs" tar ((:commit . "ff46d88726482211e3ac3d0b9c95dd4fdffe11c2") (:authors ("yuya.minami" . "yuya.minami@yuyaminami-no-MacBook-Pro.local")) (:maintainer "yuya.minami" . "yuya.minami@yuyaminami-no-MacBook-Pro.local") (:keywords "tools") (:url . "https://github.com/yuya373/emacs-slack"))])
+ (slideview . [(20150324 2240) ((cl-lib (0 3))) "File slideshow" single ((:commit . "b6d170bda139aedf81b47dc55cbd1a3af512fb4c") (:authors ("Masahiro Hayashi" . "mhayashi1120@gmail.com")) (:maintainer "Masahiro Hayashi" . "mhayashi1120@gmail.com") (:keywords "files") (:url . "https://github.com/mhayashi1120/Emacs-slideview"))])
+ (slim-mode . [(20170728 1348) nil "Major mode for editing Slim files" single ((:commit . "3636d18ab1c8b316eea71c4732eb44743e2ded87") (:authors ("Nathan Weizenbaum")) (:maintainer "Nathan Weizenbaum") (:keywords "markup" "language") (:url . "http://github.com/slim-template/emacs-slim"))])
+ (slime . [(20220302 1215) ((cl-lib (0 5)) (macrostep (0 9))) "Superior Lisp Interaction Mode for Emacs" tar ((:commit . "6ef28864d4a6b4d9390dbd0cac64f2a56582682d") (:keywords "languages" "lisp" "slime") (:url . "https://github.com/slime/slime"))])
+ (slime-company . [(20210124 1627) ((emacs (24 4)) (slime (2 13)) (company (0 9 0))) "slime completion backend for company mode" single ((:commit . "f20ecc4104d4c35052696e7e760109fb02060e72") (:authors ("Ole Arndt" . "anwyn@sugarshark.com")) (:maintainer "Ole Arndt" . "anwyn@sugarshark.com") (:keywords "convenience" "lisp" "abbrev"))])
+ (slime-docker . [(20210426 1422) ((emacs (24 4)) (slime (2 16)) (docker-tramp (0 1))) "Integration of SLIME with Docker containers" tar ((:commit . "c7d073720f2bd8e9f72a20309fff2afa4c4e798d") (:keywords "docker" "lisp" "slime") (:url . "https://gitlab.common-lisp.net/cl-docker-images/slime-docker"))])
+ (slime-repl-ansi-color . [(20200712 1226) ((emacs (24)) (slime (2 3 1))) "Turn on ANSI colors in REPL output;" single ((:commit . "e38c7958d9657e41c426b4e96938b3f604238795") (:authors ("Max Mikhanosha" . "max@openchat.com")) (:maintainer "Augustin Fabre" . "augustin@augfab.fr") (:keywords "lisp") (:url . "https://gitlab.com/augfab/slime-repl-ansi-color"))])
+ (slime-theme . [(20170808 1322) ((emacs (24 0))) "an Emacs 24 theme based on Slime (tmTheme)" single ((:commit . "8e5880ac69e0b6a079103001cc3a90bdb688998f") (:authors ("Jason Milkins")) (:maintainer "Jason Milkins") (:url . "https://github.com/emacsfodder/tmtheme-to-deftheme"))])
+ (slime-volleyball . [(20190701 1624) nil "An SVG Slime Volleyball Game" tar ((:commit . "f36a84f3c503c46ba0d011874d387a34b01c6bf6") (:authors ("Thomas Fitzsimmons" . "fitzsim@fitzsim.org")) (:maintainer "Thomas Fitzsimmons" . "fitzsim@fitzsim.org") (:keywords "games"))])
+ (slirm . [(20160201 1425) ((emacs (24 4))) "Systematic Literature Review Mode for Emacs." single ((:commit . "9adfbe1fc67580e7d0d90f7e927a25d63a797464") (:authors ("Florian Biermann" . "fbie@itu.dk")) (:maintainer "Florian Biermann" . "fbie@itu.dk") (:url . "http://github.com/fbie/slirm"))])
+ (slovak-holidays . [(20211018 1754) nil "Adds a list of slovak holidays to Emacs calendar" single ((:commit . "bedd26dd45ca497c0028a11e94a905560fcdb2f1") (:authors ("Matúš Goljer" . "matus.goljer@gmail.com")) (:maintainer "Matúš Goljer" . "matus.goljer@gmail.com") (:keywords "calendar"))])
+ (slow-keys . [(20180831 459) ((emacs (24 1))) "Slow keys mode to avoid RSI" single ((:commit . "b93ad77f9fc1d14e080d7d64864fc9cb222248b6") (:authors ("Manuel Uberti" . "manuel.uberti@inventati.org")) (:maintainer "Manuel Uberti" . "manuel.uberti@inventati.org") (:keywords "convenience") (:url . "https://github.com/manuel-uberti/slow-keys"))])
+ (slstats . [(20170823 849) ((cl-lib (0 5)) (emacs (24))) "Acquire and display stats about Second Life" single ((:commit . "e9696066abf3f2b7b818a57c062530dfd9377033") (:authors ("Dave Pearson" . "davep@davep.org")) (:maintainer "Dave Pearson" . "davep@davep.org") (:keywords "games") (:url . "https://github.com/davep/slstats.el"))])
+ (slurm-mode . [(20210519 1109) nil "Interaction with the SLURM job scheduling system" tar ((:commit . "589826fbb07f625b23c322df1cc16377c4fe6f66") (:url . "https://github.com/ffevotte/slurm.el"))])
+ (sly . [(20220302 1053) ((emacs (24 3))) "Sylvester the Cat's Common Lisp IDE" tar ((:commit . "4513c382f07a2a2cedb3c046231b69eae2f5e6f0") (:keywords "languages" "lisp" "sly") (:url . "https://github.com/joaotavora/sly"))])
+ (sly-asdf . [(20220117 714) ((emacs (24 3)) (sly (1 0 0 -2 2)) (popup (0 5 3))) "ASDF system support for SLY" tar ((:commit . "89fff94868f01d000b8bb4dd9d7e4d6389e61259") (:maintainer "Matt George" . "mmge93@gmail.com") (:keywords "languages" "lisp" "sly" "asdf") (:url . "https://github.com/mmgeorge/sly-asdf"))])
+ (sly-hello-world . [(20200225 1755) ((sly (1 0 0 -2 2))) "A template SLY contrib" tar ((:commit . "d25acc1220a3ce066bd9908251c2f0f88b1781e9") (:authors ("João Távora" . "joaotavora@gmail.com")) (:maintainer "João Távora" . "joaotavora@gmail.com") (:keywords "languages" "lisp" "sly") (:url . "https://github.com/capitaomorte/sly-hello-world"))])
+ (sly-macrostep . [(20191211 1630) ((sly (1 0 0 -2 2)) (macrostep (0 9))) "fancy macro-expansion via macrostep.el" tar ((:commit . "5113e4e926cd752b1d0bcc1508b3ebad5def5fad") (:keywords "languages" "lisp" "sly") (:url . "https://github.com/capitaomorte/sly-macrostep"))])
+ (sly-named-readtables . [(20191013 2138) ((sly (1 0 0 -2 2))) "Support named readtables in Common Lisp files" tar ((:commit . "a5a42674ccffa97ccd5e4e9742beaf3ea719931f") (:authors ("João Távora" . "joaotavora@gmail.com")) (:maintainer "João Távora" . "joaotavora@gmail.com") (:keywords "languages" "lisp" "sly") (:url . "https://github.com/capitaomorte/sly-named-readtables"))])
+ (sly-quicklisp . [(20211206 948) ((sly (1 0 0 -2 2))) "Quicklisp support for SLY" tar ((:commit . "34c73d43dd9066262387c626c17a9b486db07b2d") (:authors ("João Távora" . "joaotavora@gmail.com")) (:maintainer "João Távora" . "joaotavora@gmail.com") (:keywords "languages" "lisp" "sly") (:url . "https://github.com/capitaomorte/sly-quicklisp"))])
+ (sly-repl-ansi-color . [(20171020 1516) ((sly (0)) (cl-lib (0 5))) "Add ANSI colors support to the sly mrepl." single ((:commit . "b9cd52d1cf927bf7e08582d46ab0bcf1d4fb5048") (:authors ("Javier \"PuercoPop\" Olaechea" . "pirata@gmail.com") ("Max Mikhanosha")) (:maintainer "Javier \"PuercoPop\" Olaechea" . "pirata@gmail.com") (:keywords "sly") (:url . "https://github.com/PuercoPop/sly-repl-ansi-color"))])
+ (smart-backspace . [(20171014 526) nil "intellj like backspace" single ((:commit . "a10ec44ff325ec8c4c98b1a6e44e89e60a9aa4ac") (:authors ("Takeshi Tsukamoto" . "t.t.itm.0403@gmail.com")) (:maintainer "Takeshi Tsukamoto" . "t.t.itm.0403@gmail.com") (:url . "https://github.com/itome/smart-backspace"))])
+ (smart-comment . [(20160322 1839) nil "smarter commenting" single ((:commit . "17ddbd83205818763e6d68aa7a1aa9aaf414cbd4") (:authors ("Simon Friis Vindum" . "simon@vindum.io")) (:maintainer "Simon Friis Vindum" . "simon@vindum.io") (:keywords "lisp"))])
+ (smart-compile . [(20211127 1702) nil "an interface to `compile'" single ((:commit . "df771e8cf0f7d5ed455c74bf7d9c1e366f47922f") (:authors ("Seiji Zenitani" . "zenitani@gmail.com")) (:maintainer "Seiji Zenitani" . "zenitani@gmail.com") (:keywords "tools" "unix"))])
+ (smart-cursor-color . [(20201207 2228) nil "Change cursor color dynamically" single ((:commit . "d532f0b27e37cbd3bfc0be09d0b54aa38f1648f1") (:authors ("7696122")) (:maintainer "7696122") (:keywords "cursor" "color" "face") (:url . "https://github.com/7696122/smart-cursor-color/"))])
+ (smart-dash . [(20210427 1709) nil "Smart-Dash minor mode" single ((:commit . "bc740889dd81e7dc8a90a33d1f075f21aba9b2d3") (:authors ("Dennis Lambe Jr." . "malsyned@malsyned.net")) (:maintainer "Dennis Lambe Jr." . "malsyned@malsyned.net"))])
+ (smart-forward . [(20140430 713) ((expand-region (0 8 0))) "Semantic navigation" single ((:commit . "7b6dbfdbd4b646376a567c70e1a161545431b72b") (:authors ("Magnar Sveen" . "magnars@gmail.com")) (:maintainer "Magnar Sveen" . "magnars@gmail.com") (:keywords "navigation"))])
+ (smart-hungry-delete . [(20211020 1822) ((emacs (24 3))) "smart hungry deletion of whitespace" single ((:commit . "78acd1f16fb99b66a6c9bd605a988c3c74280577") (:authors ("Hauke Rehfeld" . "emacs@haukerehfeld.de")) (:maintainer "Hauke Rehfeld" . "emacs@haukerehfeld.de") (:keywords "convenience") (:url . "https://github.com/hrehfeld/emacs-smart-hungry-delete"))])
+ (smart-indent-rigidly . [(20141206 15) nil "Smart rigid indenting" single ((:commit . "323d1fe4d0b81e598249aad01bc44adb180ece0e") (:authors ("atom smith")) (:maintainer "atom smith") (:keywords "indenting" "coffee-mode" "haml-mode" "sass-mode") (:url . "https://github.com/re5et/smart-indent-rigidly"))])
+ (smart-jump . [(20210304 844) ((emacs (25 1))) "Smart go to definition." tar ((:commit . "3392eb35e3cde37e6f5f2a48dc0db15ca535143c") (:authors ("James Nguyen" . "james@jojojames.com")) (:maintainer "James Nguyen" . "james@jojojames.com") (:keywords "tools") (:url . "https://github.com/jojojames/smart-jump"))])
+ (smart-mark . [(20150912 210) nil "Restore point after C-g when mark" single ((:commit . "04b522a23e3aae8381c6a976fc978532fcb2e7d0") (:authors ("Kai Yu" . "yeannylam@gmail.com")) (:maintainer "Kai Yu" . "yeannylam@gmail.com") (:keywords "mark" "restore"))])
+ (smart-mode-line . [(20211005 233) ((emacs (24 3)) (rich-minority (0 1 1))) "A color coded smart mode-line." tar ((:commit . "abcb0ab6f7110a03d6c7428bae67cf8731496433") (:authors ("Artur Malabarba" . "emacs@endlessparentheses.com")) (:maintainer "Artur Malabarba" . "emacs@endlessparentheses.com") (:keywords "mode-line" "faces" "themes") (:url . "http://github.com/Malabarba/smart-mode-line"))])
+ (smart-mode-line-atom-one-dark-theme . [(20220108 2110) ((emacs (24 3)) (smart-mode-line (2 10))) "Atom-one-dark theme for smart-mode-line" single ((:commit . "8ce6cca51b19395ccdd8f33a54419fa539f837f0") (:authors ("Davide Restivo" . "davide.restivo@yahoo.it")) (:maintainer "Davide Restivo" . "davide.restivo@yahoo.it") (:keywords "mode-line" "themes" "faces") (:url . "https://github.com/daviderestivo/smart-mode-line-atom-one-dark-theme"))])
+ (smart-mode-line-powerline-theme . [(20160706 38) ((emacs (24 3)) (powerline (2 2)) (smart-mode-line (2 5))) "smart-mode-line theme that mimics the powerline appearance." tar ((:commit . "abcb0ab6f7110a03d6c7428bae67cf8731496433") (:authors ("Artur Malabarba" . "bruce.connor.am@gmail.com")) (:maintainer "Artur Malabarba" . "bruce.connor.am@gmail.com") (:keywords "mode-line" "faces" "themes") (:url . "http://github.com/Bruce-Connor/smart-mode-line"))])
+ (smart-newline . [(20131208 340) nil "Provide smart newline for one keybind." single ((:commit . "0553a9e4be7188352de1a28f2eddfd28e7436f94") (:authors ("Satoshi Namai")) (:maintainer "Satoshi Namai"))])
+ (smart-region . [(20150903 1403) ((emacs (24 4)) (expand-region (0 10 0)) (multiple-cursors (1 3 0)) (cl-lib (0 5))) "Smartly select region, rectangle, multi cursors" single ((:commit . "5a8017fd8e8dc3483865951c4942cab3f96f69f6") (:authors ("Yuuki Arisawa" . "yuuki.ari@gmail.com")) (:maintainer "Yuuki Arisawa" . "yuuki.ari@gmail.com") (:keywords "marking" "region") (:url . "https://github.com/uk-ar/smart-region"))])
+ (smart-semicolon . [(20200909 1412) ((emacs (26))) "Insert semicolon smartly" single ((:commit . "2c140accd576062f69dbe7db1d43ba038b347b9b") (:authors ("Iku Iwasa" . "iku.iwasa@gmail.com")) (:maintainer "Iku Iwasa" . "iku.iwasa@gmail.com") (:url . "https://github.com/iquiw/smart-semicolon"))])
+ (smart-shift . [(20150203 725) nil "Smart shift text left/right." single ((:commit . "a26ab2b240137e62ec4bce1698ed9c5f7b6d13ae") (:authors ("Bin Huang" . "huangbin88@foxmail.com")) (:maintainer "Bin Huang" . "huangbin88@foxmail.com") (:keywords "convenience" "tools") (:url . "https://github.com/hbin/smart-shift"))])
+ (smart-tab . [(20210530 1743) ((emacs (24 3))) "Intelligent tab completion and indentation" single ((:commit . "2f1b4073904805c8454ebc9bc967b23836a2d577") (:authors ("John SJ Anderson" . "john@genehack.org") ("Sebastien Rocca Serra" . "sroccaserra@gmail.com") ("Daniel Hackney" . "dan@haxney.org")) (:maintainer "John SJ Anderson" . "john@genehack.org") (:keywords "extensions") (:url . "https://git.genehack.net/genehack/smart-tab"))])
+ (smart-tabs-mode . [(20200907 2025) nil "Intelligently indent with tabs, align with spaces!" single ((:commit . "1044c17e42479de943e69cdeb85e4d05ad9cca8c") (:authors ("John Croisant" . "jacius@gmail.com") ("Alan Pearce" . "alan@alanpearce.co.uk") ("Daniel Dehennin" . "daniel.dehennin@baby-gnu.org") ("Matt Renaud" . "mrenaud92@gmail.com")) (:maintainer "Joel C. Salomon" . "joelcsalomon@gmail.com") (:keywords "languages") (:url . "http://www.emacswiki.org/emacs/SmartTabs"))])
+ (smart-window . [(20160717 130) ((cl-lib (0 5))) "vim-like window controlling plugin" single ((:commit . "5996461b7cbc5ab4509ac48537916eb29a8e4c16") (:authors ("Felix Chern" . "idryman@gmail.com")) (:maintainer "Felix Chern" . "idryman@gmail.com") (:keywords "window") (:url . "https://github.com/dryman/smart-window.el"))])
+ (smartparens . [(20220204 1134) ((dash (2 13 0)) (cl-lib (0 3))) "Automatic insertion, wrapping and paredit-like navigation with user defined pairs." tar ((:commit . "37f77bf2e2199be9fe27e981317b02cfd0e8c70e") (:authors ("Matus Goljer" . "matus.goljer@gmail.com")) (:maintainer "Matus Goljer" . "matus.goljer@gmail.com") (:keywords "abbrev" "convenience" "editing") (:url . "https://github.com/Fuco1/smartparens"))])
+ (smartrep . [(20150509 230) nil "Support sequential operation which omitted prefix keys." single ((:commit . "f0ff5a6d7b8603603598ae3045c98b011e58d86e") (:authors ("myuhe <yuhei.maeda_at_gmail.com>")) (:maintainer "myuhe") (:keywords "convenience") (:url . "https://github.com/myuhe/smartrep.el"))])
+ (smartscan . [(20170211 2033) nil "Jumps between other symbols found at point" single ((:commit . "234e077145710a174c20742de792b97ed2f965f6") (:authors ("Mickey Petersen" . "mickey@masteringemacs.org")) (:maintainer "Mickey Petersen" . "mickey@masteringemacs.org") (:keywords "extensions"))])
+ (smarty-mode . [(20100703 1158) nil "major mode for editing smarty templates" single ((:commit . "3dfdfe1571f5e9ef55a29c51e5a80046d4cb7568") (:maintainer "Benj Carson") (:keywords "smarty" "php" "languages" "templates") (:url . "none yet"))])
+ (smbc . [(20171229 1808) nil "View SMBC from Emacs" single ((:commit . "10538e3d575ba6ef3c94d555af2744b42dfd36c7") (:authors ("Saksham Sharma" . "saksham0808@gmail.com")) (:maintainer "Saksham Sharma" . "saksham0808@gmail.com") (:keywords "smbc" "webcomic") (:url . "https://github.com/sakshamsharma/emacs-smbc"))])
+ (smblog . [(20200424 938) ((emacs (24 3))) "samba log viewer" single ((:commit . "fc949cff7051b31f0dbc7169774144533a27b92f") (:authors ("Aurélien Aptel" . "aaptel@suse.com")) (:maintainer "Aurélien Aptel" . "aaptel@suse.com") (:url . "http://github.com/aaptel/smblog-mode"))])
+ (smeargle . [(20200323 533) ((emacs (24 3))) "Highlighting region by last updated time" single ((:commit . "afe34e7e3ce811d44880bca11f9fe1e3d91e272f") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Neil Okamoto" . "neil.okamoto+melpa@gmail.com") (:url . "https://github.com/emacsorphanage/smeargle"))])
+ (smex . [(20151212 2209) ((emacs (24))) "M-x interface with Ido-style fuzzy matching." single ((:commit . "55aaebe3d793c2c990b39a302eb26c184281c42c") (:authors ("Cornelius Mika" . "cornelius.mika@gmail.com")) (:maintainer "Cornelius Mika" . "cornelius.mika@gmail.com") (:keywords "convenience" "usability") (:url . "http://github.com/nonsequitur/smex/"))])
+ (smiles-mode . [(20220210 1413) nil "Major mode for SMILES." single ((:commit . "950a8b3224f8f069c82faeb0282d041f872d5550") (:authors (nil . "John Kitchin [jkitchin@andrew.cmu.edu]")) (:maintainer nil . "John Kitchin [jkitchin@andrew.cmu.edu]") (:keywords "smiles") (:url . "https://repo.or.cz/smiles-mode.git"))])
+ (smithers . [(20210531 2232) ((emacs (26 1)) (dash (2 17 0)) (org (9 4 5))) "A startup message featuring Mr C.M. Burns" tar ((:commit . "db9ed12a8d2c131b6d37b4e7aff01b8e3cec81a6") (:authors ("Mehmet Tekman")) (:maintainer "Mehmet Tekman") (:keywords "games") (:url . "https://gitlab.com/mtekman/smithers.el"))])
+ (sml-basis . [(20210518 2040) ((emacs (24 5))) "Standard ML Basis Library lookup" tar ((:commit . "c048d575e30a20ec825fd0c5eb9c8a4428a43298") (:authors ("Lassi Kortela" . "lassi@lassi.io")) (:maintainer "Lassi Kortela" . "lassi@lassi.io") (:keywords "languages" "util") (:url . "https://github.com/lassik/emacs-sml-basis"))])
+ (sml-modeline . [(20170614 2111) nil "Show position in a scrollbar like way in mode-line" single ((:commit . "d2f9f70174c4cf68c67eb3bb8088235735e34d9a") (:authors ("Lennart Borgman (lennart O borgman A gmail O com)")) (:maintainer "Lennart Borgman (lennart O borgman A gmail O com)") (:url . "http://bazaar.launchpad.net/~nxhtml/nxhtml/main/annotate/head%3A/util/sml-modeline.el"))])
+ (smmry . [(20161024 901) nil "SMMRY client" single ((:commit . "986a1b0aec8ab1ef17dbfb7886f47e5558cf738a") (:authors ("james sangho nah" . "microamp@protonmail.com")) (:maintainer "james sangho nah" . "microamp@protonmail.com") (:keywords "api" "smmry") (:url . "https://github.com/microamp/smmry.el"))])
+ (smog . [(20220405 251) ((emacs (24 1)) (org (8 1))) "Analyse the writing style, word use and readability of prose" single ((:commit . "28b053198ff9c1b142789614d85d7d762d9b0fa3") (:authors ("nik gaffney" . "nik@fo.am")) (:maintainer "nik gaffney" . "nik@fo.am") (:keywords "tools" "style" "readability" "prose") (:url . "https://github.com/zzkt/smog"))])
+ (smooth-scroll . [(20130322 414) nil "Minor mode for smooth scrolling and in-place scrolling." single ((:commit . "02320f28abb5cae28b3a18f6b9ce93129bdbfc45") (:authors ("K-talo Miyazaki <Keitaro dot Miyazaki at gmail dot com>")) (:maintainer "K-talo Miyazaki <Keitaro dot Miyazaki at gmail dot com>") (:keywords "convenience" "emulations" "frames") (:url . "http://www.emacswiki.org/emacs/download/smooth-scroll.el"))])
+ (smooth-scrolling . [(20161002 1949) nil "Make emacs scroll smoothly" single ((:commit . "2462c13640aa4c75ab3ddad443fedc29acf68f84") (:authors ("Adam Spiers" . "emacs-ss@adamspiers.org") ("Jeremy Bondeson" . "jbondeson@gmail.com") ("Ryan C. Thompson" . "rct+github@thompsonclan.org")) (:maintainer "Adam Spiers" . "emacs-ss@adamspiers.org") (:keywords "convenience") (:url . "http://github.com/aspiers/smooth-scrolling/"))])
+ (smotitah . [(20150218 1030) nil "Modular emacs configuration framework" tar ((:commit . "f9ab562128a5460549d016913533778e8c94bcf3") (:authors ("Alessandro Piras" . "laynor@gmail.com")) (:maintainer "Alessandro Piras" . "laynor@gmail.com") (:keywords "configuration"))])
+ (smtpmail-multi . [(20160218 2349) nil "Use different smtp servers for sending mail" single ((:commit . "83fa9d7a02e000be95cb282c8b48446646896ea1") (:authors ("Joe Bloggs" . "vapniks@yahoo.com")) (:maintainer "Joe Bloggs" . "vapniks@yahoo.com") (:keywords "comm") (:url . "https://github.com/vapniks/smtpmail-multi"))])
+ (smudge . [(20210326 2222) ((emacs (27 1)) (simple-httpd (1 5)) (request (0 3)) (oauth2 (0 16))) "Control the Spotify app" tar ((:commit . "9e3488f485b7d7f3c97ebaad34ed552bb0cc228a") (:keywords "multimedia" "music" "spotify" "smudge") (:url . "https://github.com/danielfm/smudge"))])
+ (smyx-theme . [(20141127 828) nil "smyx Color Theme" single ((:commit . "6263f6b401bbabaed388c8efcfc0be2e58c51401") (:authors ("Uriel G Maldonado" . "uriel781@gmail.com")) (:maintainer "Uriel G Maldonado" . "uriel781@gmail.com") (:keywords "color" "theme" "smyx"))])
+ (snakemake-mode . [(20220223 218) ((emacs (26 1)) (transient (0 3 0))) "Major mode for editing Snakemake files" tar ((:commit . "0dfeaff6079558c39081c2c078c41369da01903b") (:authors ("Kyle Meyer" . "kyle@kyleam.com")) (:maintainer "Kyle Meyer" . "kyle@kyleam.com") (:keywords "tools") (:url . "https://git.kyleam.com/snakemake-mode/about"))])
+ (snapshot-timemachine . [(20161221 929) ((emacs (24 4))) "Step through (Btrfs, ZFS, ...) snapshots of files" single ((:commit . "99efcebab309b11ed512a8dc62555d3834df5efb") (:authors ("Thomas Winant" . "dewinant@gmail.com")) (:maintainer "Thomas Winant" . "dewinant@gmail.com") (:url . "https://github.com/mrBliss/snapshot-timemachine"))])
+ (snapshot-timemachine-rsnapshot . [(20170324 1213) ((snapshot-timemachine (20160222 132)) (seq (2 19))) "rsnapshot backend for snapshot-timemachine" single ((:commit . "72b0b700d80f1a0442e62bbbb6a0c8c59182f97f") (:authors ("Nicolas Petton" . "nicolas@petton.fr")) (:maintainer "Nicolas Petton" . "nicolas@petton.fr"))])
+ (snazzy-theme . [(20170823 1832) ((emacs (24)) (base16-theme (2 1))) "An elegant syntax theme with bright colors" single ((:commit . "57a1763b49b4a776084c16bc70c219246fa5b412") (:keywords "faces" "theme" "color" "snazzy") (:url . "https://github.com/weijiangan/emacs-snazzy/"))])
+ (sniem . [(20220404 307) ((emacs (27 1)) (s (2 12 0)) (dash (1 12 0))) "Hands-eased united editing method" tar ((:commit . "afe4286dec79ef45a42a343033f69d90dd308535") (:authors ("SpringHan")) (:maintainer "SpringHan") (:keywords "convenience" "united-editing-method") (:url . "https://github.com/SpringHan/sniem.git"))])
+ (snitch . [(20210202 1730) ((emacs (27 1))) "An Emacs firewall" tar ((:commit . "3b3e7f1bf612c4624764d1ec4b1a96e4d2850b05") (:authors ("Trevor Bentley" . "snitch.el@x.mrmekon.com")) (:maintainer "Trevor Bentley" . "snitch.el@x.mrmekon.com") (:keywords "processes" "comm") (:url . "https://github.com/mrmekon/snitch-el"))])
+ (snoopy . [(20171008 2004) ((emacs (24)) (cl-lib (0 6))) "minor mode for number row unshifted character insertion" single ((:commit . "ec4123bdebfe0bb7bf4feaac2dc02b59caffe386") (:authors ("António Nuno Monteiro" . "anmonteiro@gmail.com")) (:maintainer "António Nuno Monteiro" . "anmonteiro@gmail.com") (:keywords "lisp"))])
+ (snow . [(20210813 1902) ((emacs (26 3))) "Let it snow in Emacs!" single ((:commit . "4cd41a703b730a6b59827853f06b98d91405df5a") (:authors ("Adam Porter" . "adam@alphapapa.net")) (:maintainer "Adam Porter" . "adam@alphapapa.net") (:keywords "games") (:url . "https://github.com/alphapapa/snow.el"))])
+ (soar-mode . [(20190503 1843) nil "A major mode for the Soar language" single ((:commit . "13b6fca62ea6574d230516fddf359a61f6558ecd") (:keywords "languages" "soar") (:url . "https://github.com/adeschamps/soar-mode"))])
+ (soccer . [(20211207 1623) ((emacs (26 1)) (dash (2 19 1))) "Fixtures, results, table etc for soccer" tar ((:commit . "b5ba10fe43e43fa40617e2936572add10c72b865") (:authors ("Md Arif Shaikh" . "arifshaikh.astro@gmail.com")) (:maintainer "Md Arif Shaikh" . "arifshaikh.astro@gmail.com") (:keywords "games" "soccer" "football") (:url . "https://github.com/md-arif-shaikh/soccer"))])
+ (socyl . [(20170212 642) ((s (1 11 0)) (dash (2 12 0)) (pkg-info (0 5 0)) (cl-lib (0 5))) "Frontend for several search tools" tar ((:commit . "1ef2da42f66f3ab31a34131e51648f352416f0ba") (:authors ("Nicolas Lamirault" . "nicolas.lamirault@gmail.com")) (:maintainer "Nicolas Lamirault" . "nicolas.lamirault@gmail.com") (:keywords "ripgrep" "sift" "ack" "pt" "ag" "grep" "search") (:url . "https://github.com/nlamirault/socyl"))])
+ (soft-charcoal-theme . [(20140420 1643) nil "Dark charcoal theme with soft colors" single ((:commit . "5607ab977fae6638e78b1495e02da8955c9ba19f") (:authors ("Martin Haesler")) (:maintainer "Martin Haesler") (:url . "http://github.com/mswift42/soft-charcoal-theme"))])
+ (soft-morning-theme . [(20150918 2041) nil "Emacs24 theme with a light background." single ((:commit . "c0f9c70c97ef2be2a093cf839c4bfe27740a111c") (:authors ("Martin Haesler")) (:maintainer "Martin Haesler") (:url . "http://github.com/mswift42/soft-morning-theme"))])
+ (soft-stone-theme . [(20140614 835) ((emacs (24))) "Emacs 24 theme with a light background." single ((:commit . "fb475514cfb02cf30ce358a61c48e46614344d48") (:authors ("Martin Haesler")) (:maintainer "Martin Haesler") (:url . "http://github.com/mswift42/soft-stone-theme"))])
+ (solaire-mode . [(20211213 102) ((emacs (25 1)) (cl-lib (0 5))) "make certain buffers grossly incandescent" single ((:commit . "8af65fbdc50b25ed3214da949b8a484527c7cc14") (:authors ("Henrik Lissner <http://github/hlissner>")) (:maintainer "Henrik Lissner" . "contact@henrik.io") (:keywords "dim" "bright" "window" "buffer" "faces") (:url . "https://github.com/hlissner/emacs-solaire-mode"))])
+ (solarized-theme . [(20220324 445) ((emacs (24 1))) "The Solarized color theme" tar ((:commit . "86e5f94ea033c8b2a21084774063a493b62a4e81") (:authors ("Bozhidar Batsov" . "bozhidar@batsov.dev")) (:maintainer "Bozhidar Batsov" . "bozhidar@batsov.dev") (:keywords "convenience" "themes" "solarized") (:url . "http://github.com/bbatsov/solarized-emacs"))])
+ (solidity-flycheck . [(20210411 758) ((flycheck (32 -4)) (solidity-mode (0 1 9)) (dash (2 17 0))) "Flycheck integration for solidity emacs mode" single ((:commit . "20fb77e089e10187b37ae1a94153017b82ed2a0a") (:authors ("Lefteris Karapetsas " . "lefteris@refu.co")) (:maintainer "Lefteris Karapetsas " . "lefteris@refu.co") (:keywords "languages" "solidity" "flycheck"))])
+ (solidity-mode . [(20220308 1517) nil "Major mode for ethereum's solidity language" tar ((:commit . "20fb77e089e10187b37ae1a94153017b82ed2a0a") (:authors ("Lefteris Karapetsas " . "lefteris@refu.co")) (:maintainer "Lefteris Karapetsas " . "lefteris@refu.co") (:keywords "languages" "solidity"))])
+ (solo-jazz-theme . [(20220117 2009) ((emacs (24 1))) "The Solo-Jazz color theme" single ((:commit . "51d63d8a2c855f4ea79eef9fc9c8a5c9702642c4") (:authors ("Carl Steib")) (:maintainer "Carl Steib") (:url . "https://github.com/cstby/solo-jazz-emacs-theme"))])
+ (somafm . [(20220402 2131) ((emacs (26 1)) (dash (2 12 0)) (request (0 3 2)) (cl-lib (0 6 1))) "A simple soma.fm interface" single ((:commit . "90b661fb1abc652feb6508eb61735919d02e9687") (:authors ("Arte Ebrahimi <>")) (:maintainer "Arte Ebrahimi <>") (:keywords "multimedia") (:url . "https://github.com/artenator/somafm.el"))])
+ (sonic-pi . [(20211214 1242) ((cl-lib (0 5)) (osc (0 1)) (dash (2 2 0)) (emacs (24)) (highlight (0))) "A Emacs client for SonicPi" tar ((:commit . "9ae16d0fd4cba77ae0bedac83f2cb46569be6ade") (:authors ("Joseph Wilk" . "joe@josephwilk.net")) (:maintainer "Joseph Wilk" . "joe@josephwilk.net") (:keywords "sonicpi" "ruby") (:url . "http://www.github.com/repl-electric/sonic-pi.el"))])
+ (soothe-theme . [(20141027 1441) ((emacs (24 1))) "a dark colorful theme for Emacs24." single ((:commit . "0786fe70c6c1b4ddcfb932fdc6862b9611cfc09b") (:authors ("Jason Milkins" . "jasonm23@gmail.com")) (:maintainer "Jason Milkins" . "jasonm23@gmail.com") (:url . "https://github.com/jasonm23/emacs-soothe-theme"))])
+ (sorcery-theme . [(20210101 1352) ((autothemer (0 2))) "A D&D (Dark and Dusty) Theme" single ((:commit . "5a1c4445b9e6e09589a299a9962a6973272a0c2f") (:authors ("Maxime Tréca" . "maxime@gmail.com")) (:maintainer "Maxime Tréca" . "maxime@gmail.com") (:url . "http://github.com/vxid/emacs-theme-sorcery"))])
+ (soria-theme . [(20220127 1004) ((emacs (25 1))) "A xoria256 theme with some colors from openSUSE" tar ((:commit . "2db1859743fe9fc58eab4e6f6c1e37825ad7b69c") (:authors ("Miquel Sabaté Solà" . "mikisabate@gmail.com")) (:maintainer "Miquel Sabaté Solà" . "mikisabate@gmail.com") (:keywords "faces") (:url . "https://github.com/mssola/soria"))])
+ (sort-words . [(20160929 1335) nil "Sort words in a selected region" single ((:commit . "7b6e108f80237363faf7ec28b2c58dec270b8601") (:authors ("\"Aleksandar Simic\"" . "asimic@gmail.com")) (:maintainer "\"Aleksandar Simic\"" . "asimic@gmail.com") (:keywords "tools") (:url . "http://github.org/dotemacs/sort-words.el"))])
+ (sotclojure . [(20170922 8) ((emacs (24 1)) (clojure-mode (4 0 0)) (cider (0 8)) (sotlisp (1 3))) "Write clojure at the speed of thought." tar ((:commit . "a480c887b53cb007b7b099c5ffcab89b9e59d7bc") (:authors ("Artur Malabarba" . "emacs@endlessparentheses.com")) (:maintainer "Artur Malabarba" . "emacs@endlessparentheses.com") (:keywords "convenience" "clojure") (:url . "https://github.com/Malabarba/speed-of-thought-clojure"))])
+ (sotlisp . [(20190211 2026) ((emacs (24 1))) "Write lisp at the speed of thought." single ((:commit . "ed2356a325c7a4a88ec1bd31381c8666e8997e97") (:authors ("Artur Malabarba" . "emacs@endlessparentheses.com")) (:maintainer "Artur Malabarba" . "emacs@endlessparentheses.com") (:keywords "convenience" "lisp") (:url . "https://github.com/Malabarba/speed-of-thought-lisp"))])
+ (sound-wav . [(20200323 728) ((deferred (0 3 1)) (cl-lib (0 5))) "Play wav file" single ((:commit . "112450888f3f90f0f2a0e43e49eb5a7e49b1b6db") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-sound-wav"))])
+ (soundcloud . [(20150502 326) ((emms (20131016)) (json (1 2)) (deferred (0 3 1)) (string-utils (0 3 2)) (request (20140316 417)) (request-deferred (20130526 1015))) "a SoundCloud client for Emacs" single ((:commit . "f998d4276ea90258909c698f6a5a51fccb667c08") (:authors ("Travis Thieman" . "travis.thieman@gmail.com")) (:maintainer "Travis Thieman" . "travis.thieman@gmail.com") (:keywords "soundcloud" "music" "audio"))])
+ (soundklaus . [(20191220 2112) ((dash (2 12 1)) (emacs (24)) (emms (4 0)) (s (1 11 0)) (pkg-info (0 4)) (cl-lib (0 5)) (request (0 2 0))) "Play music on SoundCloud with Emacs via EMMS" tar ((:commit . "15ce6e7f24a45e4f202d83cca9fa3bfdd94ca592") (:authors ("r0man" . "roman@burningswell.com")) (:maintainer "r0man" . "roman@burningswell.com") (:keywords "soundcloud" "music" "emms") (:url . "https://github.com/r0man/soundklaus.el"))])
+ (sourcekit . [(20210430 2155) ((emacs (24 3)) (dash (2 18 0)) (request (0 2 0))) "Library to interact with sourcekittendaemon" single ((:commit . "a1860ad4dd3a542acd2fa0dfac2a388cbdf4af0c") (:authors ("Nathan Kot" . "nk@nathankot.com")) (:maintainer "Nathan Kot" . "nk@nathankot.com") (:keywords "tools" "processes") (:url . "https://github.com/nathankot/company-sourcekit"))])
+ (sourcemap . [(20200315 1037) ((emacs (24 3))) "Sourcemap parser" single ((:commit . "bb2a56b2feb62b0c77d7f03ef2acd94f91be6b3f") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-sourcemap"))])
+ (sourcerer-theme . [(20161014 1625) nil "A version of sourcerer by xero" single ((:commit . "c7f8e665d53bb48fb72f95f706710d53d24bd407") (:authors ("Bryan Gilbert" . "gilbertw1@gmail.com")) (:maintainer "Bryan Gilbert" . "gilbertw1@gmail.com") (:keywords "themes") (:url . "http://github.com/gilbertw1/sourcerer-emacs"))])
+ (space-theming . [(20200502 1032) ((emacs (24))) "Easilly override theme faces" single ((:commit . "31dca6954df643255175f7df68a86892aa3c71a7") (:keywords "faces") (:url . "https://github.com/p3r7/space-theming"))])
+ (spacebar . [(20190719 334) ((eyebrowse (0 7 7)) (emacs (25 4 0))) "Workspaces Bar" single ((:commit . "2b2cd0e786877273103f048e62a06b0027deca2d") (:authors ("Matthias Margush" . "matthias.margush@gmail.com")) (:maintainer "Matthias Margush" . "matthias.margush@gmail.com") (:keywords "convenience") (:url . "https://github.com/matthias-margush/spacebar"))])
+ (spacegray-theme . [(20150719 1931) ((emacs (24 1))) "A Hyperminimal UI Theme" single ((:commit . "9826265c2bceb2ebc1c5e16a45021da0253ace97") (:authors ("Bruce Williams" . "brwcodes@gmail.com")) (:maintainer "Bruce Williams" . "brwcodes@gmail.com") (:keywords "themes") (:url . "http://github.com/bruce/emacs-spacegray-theme"))])
+ (spaceline . [(20211120 1636) ((emacs (24 4)) (cl-lib (0 5)) (powerline (2 3)) (dash (2 11 0)) (s (1 10 0))) "Modeline configuration library for powerline" tar ((:commit . "9a81afa52738544ad5e8b71308a37422ca7e25ba") (:authors ("Eivind Fonn" . "evfonn@gmail.com")) (:maintainer "Eivind Fonn" . "evfonn@gmail.com") (:keywords "mode-line" "powerline" "spacemacs") (:url . "https://github.com/TheBB/spaceline"))])
+ (spaceline-all-the-icons . [(20190325 1602) ((emacs (24 4)) (all-the-icons (2 6 0)) (spaceline (2 0 0)) (memoize (1 0 1))) "A Spaceline theme using All The Icons" tar ((:commit . "5afd48c10f1bd42d9b9648c5e64596b72f3e9042") (:authors ("Dominic Charlesworth" . "dgc336@gmail.com")) (:maintainer "Dominic Charlesworth" . "dgc336@gmail.com") (:keywords "convenience" "lisp" "tools") (:url . "https://github.com/domtronn/spaceline-all-the-icons.el"))])
+ (spacemacs-theme . [(20220430 2248) nil "Color theme with a dark and light versions" tar ((:commit . "bd376f705d6eb7afd9a1dfa0c1bd407e869d1e9f"))])
+ (spaces . [(20170809 2208) nil "Create and switch between named window configurations." single ((:commit . "6bdb51e9a346907d60a9625f6180bddd06be6674") (:authors ("Steven Thomas")) (:maintainer "Steven Thomas") (:keywords "frames" "convenience") (:url . "https://github.com/chumpage/chumpy-windows"))])
+ (spark . [(20211021 1832) ((emacs (24 3))) "sparkline generation" single ((:commit . "c9af24a169b1f1aeba175f1f8d51abda113639af") (:authors ("Alvin Francis Dumalus")) (:maintainer "Alvin Francis Dumalus") (:keywords "lisp" "data") (:url . "https://github.com/alvinfrancis/spark"))])
+ (sparkline . [(20150101 1319) ((cl-lib (0 3))) "Make sparkline images from a list of numbers" single ((:commit . "a2b5d817d272d6363b67ed8f8cc75499a19fa8d2") (:authors ("Willem Rein Oudshoorn" . "woudshoo@xs4all.nl")) (:maintainer "Willem Rein Oudshoorn" . "woudshoo@xs4all.nl") (:keywords "extensions"))])
+ (sparql-mode . [(20210701 1202) ((cl-lib (0 5)) (emacs (24 3))) "Edit and interactively evaluate SPARQL queries." tar ((:commit . "ceb370b3879841f8809cc3f9b1b87e898f10562f") (:authors ("Craig Andera <candera at wangdera dot com>")) (:maintainer "Bjarte Johansen <Bjarte dot Johansen at gmail dot com>") (:url . "https://github.com/ljos/sparql-mode"))])
+ (spatial-navigate . [(20220211 548) ((emacs (26 2))) "Directional navigation between white-space blocks" single ((:commit . "0365544483f957db79b8e617fb0bd8160134a655") (:authors ("Campbell Barton" . "ideasman42@gmail.com")) (:maintainer "Campbell Barton" . "ideasman42@gmail.com") (:url . "https://gitlab.com/ideasman42/emacs-spatial-navigate"))])
+ (spdx . [(20220429 126) ((emacs (24 4))) "Insert SPDX license and copyright headers" tar ((:commit . "1405b4f050f8181b8bcbe2951760e6c5b68b08c7") (:authors ("Zhiwei Chen" . "condy0919@gmail.com")) (:maintainer "Zhiwei Chen" . "condy0919@gmail.com") (:keywords "license" "tools") (:url . "https://github.com/condy0919/spdx.el"))])
+ (speech-tagger . [(20170728 1829) ((cl-lib (0 5))) "tag parts of speech using coreNLP" tar ((:commit . "61955b40d4e8b09e66a3e8033e82893f81657c06") (:authors ("Danny McClanahan" . "danieldmcclanahan@gmail.com")) (:maintainer "Danny McClanahan" . "danieldmcclanahan@gmail.com") (:keywords "speech" "tag" "nlp" "language" "corenlp" "parsing" "natural") (:url . "https://github.com/cosmicexplorer/speech-tagger"))])
+ (speechd-el . [(20211231 758) nil "Client to speech synthesizers and Braille displays." tar ((:commit . "a4be22b5b62a6be1e749df6f64b06e16a6b09790") (:authors ("Milan Zamazal" . "pdm@zamazal.org")) (:maintainer "Milan Zamazal" . "pdm@zamazal.org"))])
+ (speed-type . [(20191204 1107) ((emacs (24 3)) (cl-lib (0 3))) "Practice touch and speed typing" single ((:commit . "5ef695f7159aa1f20c7c9e55f0c39bcdacce8d21") (:authors ("Gunther Hagleitner")) (:maintainer "Julien Pagès" . "j.parkouss@gmail.com") (:keywords "games") (:url . "https://github.com/parkouss/speed-type"))])
+ (speedbar-git-respect . [(20200901 246) ((f (0 8 0)) (emacs (25 1))) "Particular respect git repo in speedbar" single ((:commit . "dd8f0849fc1dd21b42380e1a8c28a9a29acd9511") (:authors ("Muromi Ukari" . "chendianbuji@gmail.com")) (:maintainer "Muromi Ukari" . "chendianbuji@gmail.com") (:url . "https://github.com/ukari/speedbar-git-respect"))])
+ (speeddating . [(20180319 723) ((emacs (25))) "Increase date and time at point" single ((:commit . "df69db0560f19636a66a74f3d88c793bbb18b21e") (:authors ("Xu Chunyang" . "mail@xuchunyang.me")) (:maintainer "Xu Chunyang" . "mail@xuchunyang.me") (:keywords "date" "time") (:url . "https://github.com/xuchunyang/emacs-speeddating"))])
+ (spell-fu . [(20220213 1215) ((emacs (26 2))) "Fast & light spelling highlighter" single ((:commit . "8185467b24f05bceb428a0e9909651ec083cc54e") (:authors ("Campbell Barton" . "ideasman42@gmail.com")) (:maintainer "Campbell Barton" . "ideasman42@gmail.com") (:keywords "convenience") (:url . "https://gitlab.com/ideasman42/emacs-spell-fu"))])
+ (sphinx-doc . [(20210213 1250) ((s (1 9 0)) (cl-lib (0 5)) (dash (2 10 0))) "Sphinx friendly docstrings for Python functions" single ((:commit . "1eda612a44ef027e5229895daa77db99a21b8801") (:authors ("Vineet Naik" . "naikvin@gmail.com")) (:maintainer "Vineet Naik" . "naikvin@gmail.com") (:keywords "sphinx" "python") (:url . "https://github.com/naiquevin/sphinx-doc.el"))])
+ (sphinx-frontend . [(20161025 758) nil "Launch build process for rst documents via sphinx." single ((:commit . "0cbb03361c245382d3e679dded30c4fc1713c252") (:authors ("Kostafey" . "kostafey@gmail.com")) (:maintainer "Kostafey" . "kostafey@gmail.com") (:keywords "compile" "sphinx" "restructuredtext") (:url . "https://github.com/kostafey/sphinx-frontend"))])
+ (sphinx-mode . [(20220417 1552) ((f (0 20 0)) (dash (2 14 1))) "Minor mode providing sphinx support." tar ((:commit . "77ca51adf9ee877f3a8f43e744f59e650772f121") (:authors ("Matúš Goljer" . "matus.goljer@gmail.com")) (:maintainer "Matúš Goljer" . "matus.goljer@gmail.com") (:keywords "languages"))])
+ (spice-mode . [(20220210 1414) ((emacs (24 3))) "Major mode for SPICE" single ((:commit . "f55c2b6dd35caace0ec7250b5c7b5d119235a23d") (:authors ("Geert A. M. Van der Plas" . "geert_vanderplas@email.com") ("Emmanuel Rouat" . "emmanuel.rouat@wanadoo.fr") ("Carlin J. Vieri, MIT AI Lab" . "cvieri@ai.mit.edu")) (:maintainer "Geert A. M. Van der Plas" . "geert_vanderplas@email.com") (:keywords "spice" "spice2g6" "spice3" "eldo" "hspice" "layla" "mondriaan" "fasthenry" "cdl" "spectre compatibility" "netlist editing") (:url . "https://repo.or.cz/spice-mode.git"))])
+ (spiral . [(20180223 1140) ((emacs (25 1)) (a (0 1 0 -3 4)) (avy (0 4 0)) (clojure-mode (5 6 0)) (highlight (0)) (treepy (1 0 0))) "Clojure IDE based on UNREPL" tar ((:commit . "907b9792467139a942ba7b07ca0276b90770baf9") (:authors ("Daniel Barreto" . "daniel@barreto.tech")) (:maintainer "Daniel Barreto" . "daniel@barreto.tech") (:keywords "languages" "clojure") (:url . "https://github.com/Unrepl/spiral"))])
+ (splitjoin . [(20150505 1432) ((cl-lib (0 5))) "Transition between multiline and single-line code" single ((:commit . "e2945ee269e6e90f0243d6f2a33e067bb0a2873c") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-splitjoin"))])
+ (splitter . [(20170809 2208) nil "Manage window splits" single ((:commit . "6bdb51e9a346907d60a9625f6180bddd06be6674") (:authors ("Steven Thomas")) (:maintainer "Steven Thomas") (:keywords "frames" "convenience") (:url . "https://github.com/chumpage/chumpy-windows"))])
+ (spotify . [(20200615 1418) ((cl-lib (0 5))) "Control the spotify application from emacs" single ((:commit . "7e28ef0b4519c6a46fce6a89c0ff1ed775eda71a") (:authors ("R.W. van 't Veer")) (:maintainer "R.W. van 't Veer") (:keywords "convenience") (:url . "https://github.com/remvee/spotify-el"))])
+ (spotlight . [(20200109 2137) ((emacs (24 1)) (swiper (0 6 0)) (counsel (0 6 0))) "search files with Mac OS X spotlight" single ((:commit . "ea71f4fd380c51e50c47bb25855af4f40e4d8da0") (:authors ("Ben Maughan" . "benmaughan@gmail.com")) (:maintainer "Ben Maughan" . "benmaughan@gmail.com") (:keywords "search" "external") (:url . "http://www.pragmaticemacs.com"))])
+ (spray . [(20160304 2220) nil "a speed reading mode" single ((:commit . "74d9dcfa2e8b38f96a43de9ab0eb13364300cb46") (:authors ("Ian Kelling" . "ian@iankelling.org")) (:maintainer "Ian Kelling" . "ian@iankelling.org") (:keywords "convenience") (:url . "https://github.com/ian-kelling/spray"))])
+ (springboard . [(20170106 755) ((helm (1 6 9))) "Temporarily change default-directory for one command" single ((:commit . "687d1e5898a880878995dc9bffe93b4598366203") (:authors ("John Wiegley" . "jwiegley@gmail.com")) (:maintainer "John Wiegley" . "jwiegley@gmail.com") (:keywords "helm") (:url . "https://github.com/jwiegley/springboard"))])
+ (sprintly-mode . [(20121006 534) ((furl (0 0 2))) "Major mode for dealing with sprint.ly" single ((:commit . "6695892bae5860b5268bf3ae62be990ee9b63c11") (:authors ("Justin Lilly" . "justin@justinlilly.com")) (:maintainer "Justin Lilly" . "justin@justinlilly.com") (:url . "https://github.com/sprintly/sprintly-mode"))])
+ (sproto-mode . [(20151115 1805) nil "Major mode for editing sproto." single ((:commit . "0583a88273204dccd884b7edaa3590cefd31e7f7") (:authors ("m2q1n9")) (:maintainer "m2q1n9") (:keywords "sproto"))])
+ (sprunge . [(20160301 243) ((request (0 2 0)) (cl-lib (0 5))) "Upload pastes to sprunge.us" single ((:commit . "0fd386b8b29c4175022a04ad70ea5643185b6726") (:authors ("Tom Jakubowski")) (:maintainer "Tom Jakubowski") (:keywords "tools"))])
+ (spu . [(20161214 324) ((emacs (24 4)) (signal (1 0)) (timp (1 2 0))) "Silently upgrade package in the background" tar ((:commit . "41eec86b595816e3852e8ad1a8e07e51a27fd065") (:authors ("Mola-T" . "Mola@molamola.xyz")) (:maintainer "Mola-T" . "Mola@molamola.xyz") (:keywords "convenience" "package") (:url . "https://github.com/mola-T/spu"))])
+ (sql-clickhouse . [(20191209 1443) ((emacs (24))) "support ClickHouse as SQL interpreter" single ((:commit . "8403a4a5d332dbb6459b7fbce6ea95c36d390a5b") (:authors ("Robert Schwarz" . "mail@rschwarz.net")) (:maintainer "Robert Schwarz" . "mail@rschwarz.net") (:url . "https://github.com/leethargo/sql-clickhouse"))])
+ (sql-impala . [(20181218 410) nil "comint support for Cloudera Impala" single ((:commit . "466e7c0c789ec3e5e8a276c8f6754f91bb584c3e") (:authors ("Jason Terk" . "jason@goterkyourself.com")) (:maintainer "Jason Terk" . "jason@goterkyourself.com") (:keywords "sql" "impala") (:url . "https://github.com/jterk/sql-impala"))])
+ (sql-presto . [(20190113 1742) ((emacs (24 4))) "No description available." single ((:commit . "bcda455e300a1af75c7bb805882329bc844703b2") (:authors ("Katherine Cox-Buday" . "cox.katherine.e@gmail.com")) (:maintainer "Katherine Cox-Buday" . "cox.katherine.e@gmail.com") (:keywords "sql" "presto" "database"))])
+ (sql-sqlline . [(20201102 1508) ((emacs (24 4))) "Adds SQLLine support to SQLi mode" single ((:commit . "38baf140cae26f9d93fc45d5eaff7d5c7f050bff") (:authors ("Matteo Redaelli" . "matteo.redaelli@gmail.com")) (:maintainer "Matteo Redaelli" . "matteo.redaelli@gmail.com") (:keywords "languages") (:url . "https://gitlab.com/matteoredaelli/sql-sqlline"))])
+ (sqlformat . [(20210305 209) ((emacs (24 3)) (reformatter (0 3))) "Reformat SQL using sqlformat or pgformatter" single ((:commit . "5d3f776c7eaac0c353ad184b54ef17b2ebc58015") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:keywords "languages") (:url . "https://github.com/purcell/sqlformat"))])
+ (sqlite . [(20201227 1822) ((emacs (24 5))) "Use sqlite via ELisp" single ((:commit . "f3da716302c929b9df4ba0c281968f72a9d1d188") (:authors ("cnngimenez")) (:maintainer "cnngimenez") (:keywords "extensions" "lisp" "sqlite") (:url . "https://gitlab.com/cnngimenez/sqlite.el"))])
+ (sqlite3 . [(20220501 1217) ((emacs (25 1))) "Direct access to the core SQLite3 API" tar ((:commit . "68eda59d5f3d29d0a64d6256d58b8c1f93ba3583") (:authors ("Y. N. Lo" . "gordonynlo@yahoo.com")) (:maintainer "Y. N. Lo" . "gordonynlo@yahoo.com") (:keywords "comm" "data" "sql") (:url . "https://github.com/pekingduck/emacs-sqlite3-api"))])
+ (sqlup-mode . [(20170610 1537) nil "Upcase SQL words for you" single ((:commit . "3f9df9c88d6a7f9b1ae907e401cad8d3d7d63bbf") (:authors ("Aldric Giacomoni" . "trevoke@gmail.com")) (:maintainer "Aldric Giacomoni" . "trevoke@gmail.com") (:keywords "sql" "tools" "redis" "upcase") (:url . "https://github.com/trevoke/sqlup-mode.el"))])
+ (sr-speedbar . [(20161025 831) nil "Same frame speedbar" single ((:commit . "77a83fb50f763a465c021eca7343243f465b4a47") (:authors ("Sebastian Rose" . "sebastian_rose@gmx.de")) (:maintainer "Sebastian Rose" . "sebastian_rose@gmx.de") (:keywords "speedbar" "sr-speedbar.el") (:url . "http://www.emacswiki.org/emacs/download/sr-speedbar.el"))])
+ (srcery-theme . [(20210601 1247) ((emacs (24))) "Dark color theme" single ((:commit . "58dd21cd63e4a2eed15e0082c2547069363f107b") (:authors ("Daniel Berg")) (:maintainer "Daniel Berg") (:keywords "faces") (:url . "https://github.com/srcery-colors/srcery-emacs"))])
+ (srefactor . [(20180703 1810) ((emacs (24 4))) "A refactoring tool based on Semantic parser framework" tar ((:commit . "6f2c97d17fb70f4ca2112f5a2b99a8ec162004f5") (:authors ("Tu, Do Hoang" . "tuhdo1710@gmail.com")) (:maintainer "Tu, Do Hoang") (:keywords "c" "languages" "tools") (:url . "https://github.com/tuhdo/semantic-refactor"))])
+ (srfi . [(20220406 1831) ((emacs (25 1))) "Scheme Requests for Implementation browser" tar ((:commit . "dbcdc58d3ea9e0767b24bb0f05fc8de8849889fe") (:authors ("Lassi Kortela" . "lassi@lassi.io")) (:maintainer "Lassi Kortela" . "lassi@lassi.io") (:keywords "languages" "util") (:url . "https://github.com/srfi-explorations/emacs-srfi"))])
+ (srv . [(20180715 1959) ((emacs (24 3))) "perform SRV DNS requests" single ((:commit . "714387d5a5cf34d8d8cd96bdb1f9cb8ded823ff7") (:authors ("Magnus Henoch" . "magnus.henoch@gmail.com")) (:maintainer "Magnus Henoch" . "magnus.henoch@gmail.com") (:keywords "comm") (:url . "https://github.com/legoscia/srv.el"))])
+ (ssass-mode . [(20200211 132) ((emacs (24 3))) "Edit Sass without a Turing Machine" single ((:commit . "96f557887ad97a0066a60c54f92b7234b8407016") (:authors ("Adam Niederer" . "adam.niederer@gmail.com")) (:maintainer "Adam Niederer" . "adam.niederer@gmail.com") (:keywords "languages" "sass") (:url . "http://github.com/AdamNiederer/ssass-mode"))])
+ (ssh . [(20120904 2042) nil "Support for remote logins using ssh." single ((:commit . "812e27409d01c38d74906a1816640506d6e7e3ef") (:authors ("Noah Friedman" . "friedman@splode.com")) (:maintainer "Ian Eure" . "ian.eure@gmail.com") (:keywords "unix" "comm"))])
+ (ssh-agency . [(20200329 1558) ((emacs (24 4)) (dash (2 10 0))) "manage ssh-agent from Emacs" single ((:commit . "a5377e4317365a3d5442e06d5c255d4a7c7618db") (:authors ("Noam Postavsky" . "npostavs@user.sourceforge.net")) (:maintainer "Noam Postavsky" . "npostavs@user.sourceforge.net") (:url . "https://github.com/magit/ssh-agency"))])
+ (ssh-config-mode . [(20211003 2330) nil "Mode for fontification of ~/.ssh/config" tar ((:commit . "d560a0876a93ad4130baf33dae1b9405ad37a405") (:authors ("Harley Gorrell" . "harley@panix.com")) (:maintainer "Harley Gorrell" . "harley@panix.com") (:keywords "ssh" "config" "emacs") (:url . "https://github.com/jhgorrell/ssh-config-mode-el"))])
+ (ssh-deploy . [(20220126 658) ((emacs (25))) "Deployment via Tramp, global or per directory." tar ((:commit . "9311f9b4f8d25ce54fb7da9bf59d955fed366a4d") (:authors ("Christian Johansson" . "christian@cvj.se")) (:maintainer "Christian Johansson" . "christian@cvj.se") (:keywords "tools" "convenience") (:url . "https://github.com/cjohansson/emacs-ssh-deploy"))])
+ (ssh-tunnels . [(20220410 1424) ((cl-lib (0 5)) (emacs (24))) "Manage SSH tunnels" tar ((:commit . "a74488a71c2827dcaf42d9381d0d974aca96e27f") (:authors ("death <github.com/death>")) (:maintainer "death <github.com/death>") (:keywords "tools" "convenience") (:url . "http://github.com/death/ssh-tunnels"))])
+ (stack-mode . [(20150923 1523) ((haskell-mode (13 14)) (cl-lib (0 5)) (flycheck (0 23))) "A minor mode enabling various features based on stack-ide." tar ((:commit . "f3481e239dde9817152ec00e32bfc3ebf5aaf2cb") (:keywords "haskell" "stack") (:url . "https://github.com/commercialhaskell/stack-ide"))])
+ (stan-mode . [(20211129 2051) ((emacs (24 4))) "Major mode for editing Stan files" tar ((:commit . "150bbbe5fd3ad2b5a3dbfba9d291e66eeea1a581") (:authors ("Jeffrey Arnold" . "jeffrey.arnold@gmail.com") ("Daniel Lee" . "bearlee@alum.mit.edu") ("Kazuki Yoshida" . "kazukiyoshida@mail.harvard.edu")) (:maintainer "Kazuki Yoshida" . "kazukiyoshida@mail.harvard.edu") (:keywords "languages" "c") (:url . "https://github.com/stan-dev/stan-mode/tree/master/stan-mode"))])
+ (stan-snippets . [(20211129 2051) ((emacs (24 3)) (stan-mode (10 3 0)) (yasnippet (0 8 0))) "Yasnippets for Stan" tar ((:commit . "150bbbe5fd3ad2b5a3dbfba9d291e66eeea1a581") (:authors ("Jeffrey Arnold" . "jeffrey.arnold@gmail.com") ("Kazuki Yoshida" . "kazukiyoshida@mail.harvard.edu")) (:maintainer "Kazuki Yoshida" . "kazukiyoshida@mail.harvard.edu") (:keywords "languages" "tools") (:url . "https://github.com/stan-dev/stan-mode/tree/master/stan-snippets"))])
+ (standard-dirs . [(20200621 1603) ((emacs (26 1)) (f (0 20 0)) (s (1 7 0))) "Platform-specific paths for config, cache, and other data" single ((:commit . "92460e21f964cb7495d974c42acd0b726af3fbcb") (:authors ("Joseph M LaFreniere" . "joseph@lafreniere.xyz")) (:maintainer "Joseph M LaFreniere" . "joseph@lafreniere.xyz") (:keywords "files") (:url . "https://github.com/lafrenierejm/standard-dirs.el"))])
+ (standoff-mode . [(20210810 1814) nil "Create stand-off markup, also called external markup." tar ((:commit . "aa5bac257ebefd91f4b5dd787a835407bddd6fb2") (:authors ("Christian Lück" . "christian.lueck@ruhr-uni-bochum.de")) (:maintainer "Christian Lück" . "christian.lueck@ruhr-uni-bochum.de") (:keywords "text" "annotations" "ner" "humanities") (:url . "https://github.com/lueck/standoff-mode"))])
+ (starlit-theme . [(20220412 1312) ((emacs (25 1))) "Deep blue dark theme with bright colors from the starlit sky" single ((:commit . "bc4b501d195b5bf7e4d03395e7d42e9336fa9f93") (:authors ("Jonas Jelten" . "jj@sft.lol")) (:maintainer "Jonas Jelten" . "jj@sft.lol") (:keywords "faces") (:url . "https://github.com/SFTtech/starlit-emacs"))])
+ (start-menu . [(20160426 1225) ((cl-lib (0 5)) (config-parser (0 1))) "start-menu for executing external program like in windows" single ((:commit . "f7d33fed7ad2dc61156f1c1cff9e1805366fbd69") (:authors ("DarkSun" . "lujun9972@gmail.com")) (:maintainer "DarkSun" . "lujun9972@gmail.com") (:keywords "convenience" "menu") (:url . "https://github.com/lujun9972/el-start-menu"))])
+ (stash . [(20151117 1427) nil "lightweight persistent caching" single ((:commit . "c2e494d20c752b80ebbdffbf66687b3cdfc425ad") (:authors ("Sean Allred" . "code@seanallred.com")) (:maintainer "Sean Allred" . "code@seanallred.com") (:keywords "extensions" "data" "internal" "lisp") (:url . "https://www.github.com/vermiculus/stash.el/"))])
+ (state . [(20200727 1227) ((emacs (24))) "Quick navigation between workspaces" single ((:commit . "8cd9210f17c1b134274a7352b996839aed9a7d8c") (:authors ("Sylvain Rousseau <thisirs at gmail dot com>")) (:maintainer "Sylvain Rousseau <thisirs at gmail dot com>") (:keywords "convenience" "workspaces") (:url . "https://github.com/thisirs/state.git"))])
+ (status . [(20151230 1408) nil "This package adds support for status icons to Emacs." tar ((:commit . "b62c74bf272566f82a68622f29fb9edafea0f241") (:authors ("Tom Tromey" . "tom@tromey.com")) (:maintainer "Tom Tromey" . "tom@tromey.com") (:keywords "frames" "multimedia"))])
+ (steam . [(20220218 1707) ((cl-lib (0 5))) "Organize and launch Steam games" single ((:commit . "20aa58c5ccd85f6c4f288a14e79adc66e691cd23") (:authors ("Erik Sjöstrand")) (:maintainer "Erik Sjöstrand") (:keywords "games") (:url . "http://github.com/Kungsgeten/steam.el"))])
+ (stem . [(20131102 1109) nil "Routines for stemming" single ((:commit . "d74e6611d6ba5025e0276a2cc7c8a90f46bfa9ac") (:authors ("Tsuchiya Masatoshi" . "tsuchiya@pine.kuee.kyoto-u.ac.jp")) (:maintainer "Tsuchiya Masatoshi" . "tsuchiya@pine.kuee.kyoto-u.ac.jp") (:keywords "stemming") (:url . "https://github.com/yuutayamada/stem"))])
+ (stem-english . [(20180109 358) ((emacs (24 3))) "- routines for stemming English word" single ((:commit . "c9fc4c6ed6bf82382e479dae80912f4ae17d31f4") (:authors ("Tsuchiya Masatoshi" . "tsuchiya@pine.kuee.kyoto-u.ac.jp")) (:maintainer "KAWABATA, Taichi <kawabata.taichi_at_gmail.com>") (:keywords "text") (:url . "http://github.com/kawabata/stem-english"))])
+ (stem-reading-mode . [(20220418 1136) ((emacs (25 1))) "Highlight word stems for speed-reading" single ((:commit . "a8bacd80fab6013c09e4e8d337fd88267cbe2ff8") (:authors ("Yuri D'Elia" . "wavexx@thregr.org")) (:maintainer "Yuri D'Elia" . "wavexx@thregr.org") (:keywords "convenience" "wp") (:url . "https://gitlab.com/wavexx/stem-reading-mode.el"))])
+ (stgit . [(20200606 1308) nil "major mode for StGit interaction" single ((:commit . "03fc757c4255bfd445cdbc2a62ca3b02a65beba5") (:authors ("David Kågedal" . "davidk@lysator.liu.se")) (:maintainer "David Kågedal" . "davidk@lysator.liu.se") (:url . "http://stacked-git.github.io"))])
+ (sticky . [(20170926 36) nil "Sticky key for capital letters" single ((:commit . "fec4e1af38f17f5cd80eca361d8e8ef8772db366") (:authors ("rubikitch" . "rubikitch@ruby-lang.org")) (:maintainer "rubikitch" . "rubikitch@ruby-lang.org") (:keywords "convenience") (:url . "http://www.emacswiki.org/cgi-bin/wiki/download/sticky.el"))])
+ (stickyfunc-enhance . [(20150429 1814) ((emacs (24 3))) "An enhancement to stock `semantic-stickyfunc-mode'" single ((:commit . "13bdba51fcd83ccbc3267959d23afc94d458dcb0") (:authors ("Tu, Do Hoang" . "tuhdo1710@gmail.com")) (:maintainer "Tu, Do Hoang") (:keywords "c" "languages" "tools") (:url . "https://github.com/tuhdo/semantic-stickyfunc-enhance"))])
+ (stimmung-themes . [(20220502 850) ((emacs (25))) "Themes tuned to inner harmonies" tar ((:commit . "c516bcc077ffc334006e77c608b068eb2f11e845") (:authors ("Love Lagerkvist")) (:maintainer "Love Lagerkvist") (:keywords "faces") (:url . "https://github.com/motform/stimmung-themes"))])
+ (stock-ticker . [(20150204 1052) ((s (1 9 0)) (request (0 2 0))) "Show stock prices in mode line" single ((:commit . "f2e564142c9de84232839a5b01979cf95b04d6a9") (:authors ("Gunther Hagleitner")) (:maintainer "Gunther Hagleitner") (:keywords "comms") (:url . "https://github.com/hagleitn/stock-ticker"))])
+ (stock-tracker . [(20220430 1144) ((emacs (27 1)) (dash (2 16 0)) (async (1 9 5))) "Track stock price" single ((:commit . "58018a1747273df23dec08ec5d318da1960428c1") (:authors ("Huming Chen" . "chenhuming@gmail.com")) (:maintainer "Huming Chen" . "chenhuming@gmail.com") (:keywords "convenience" "stock" "finance") (:url . "https://github.com/beacoder/stock-tracker"))])
+ (strace-mode . [(20171116 2039) nil "strace output syntax highlighting" single ((:commit . "2901baa968d5180ab985ac40ca22cc20914d01f5") (:authors ("Preston Moore" . "prestonkmoore@gmail.com")) (:maintainer "Preston Moore" . "prestonkmoore@gmail.com") (:keywords "languages"))])
+ (streak . [(20220311 1929) ((emacs (27 1))) "Track a daily streak in your Mode Line" single ((:commit . "b2206de2fe43f97e754bbcb0abe9b078a419e787") (:authors ("Colin Woodbury <https://www.fosskers.ca>")) (:maintainer "Colin Woodbury" . "colin@fosskers.ca") (:keywords "calendar") (:url . "https://github.com/fosskers/streak"))])
+ (streamlink . [(20210811 1429) ((s (1 12 0))) "A major mode for streamlink output" single ((:commit . "c265dc61c02ad29ec01dfd8b5cbe3bac60fbf097") (:keywords "multimedia" "streamlink") (:url . "https://github.com/BenediktBroich/streamlink"))])
+ (strie . [(20160211 2222) ((cl-lib (0 5))) "A simple trie data structure implementation" single ((:commit . "eb7efb0cccc127c414f6a64db11454869d9c10a8") (:authors ("James Atwood" . "jatwood@cs.umass.edu")) (:maintainer "James Atwood" . "jatwood@cs.umass.edu"))])
+ (string-edit . [(20210405 1836) ((dash (1 2 0))) "Avoid escape nightmares by editing string in separate buffer" single ((:commit . "0e225df6f8740467231c787a50025e4552b3eddb") (:authors ("Magnar Sveen" . "magnars@gmail.com")) (:maintainer "Magnar Sveen" . "magnars@gmail.com"))])
+ (string-inflection . [(20210918 419) nil "underscore -> UPCASE -> CamelCase -> lowerCamelCase conversion of names" single ((:commit . "fd7926ac17293e9124b31f706a4e8f38f6a9b855") (:authors ("akicho8" . "akicho8@gmail.com")) (:maintainer "akicho8" . "akicho8@gmail.com") (:keywords "elisp"))])
+ (string-utils . [(20140508 2041) ((list-utils (0 4 2))) "String-manipulation utilities" single ((:commit . "c2232d691617973ecf12a970c6008a161c21da14") (:authors ("Roland Walker" . "walker@pobox.com")) (:maintainer "Roland Walker" . "walker@pobox.com") (:keywords "extensions") (:url . "http://github.com/rolandwalker/string-utils"))])
+ (stripe-buffer . [(20141208 1508) ((cl-lib (1 0))) "Use a different background for even and odd lines" single ((:commit . "c252080f55cb78c951b19ebab9687f6d00237baf") (:authors ("Andy Stewart" . "lazycat.manatee@gmail.com")) (:maintainer "sabof" . "esabof@gmail.com") (:url . "https://github.com/sabof/stripe-buffer"))])
+ (stripes . [(20220310 2237) ((emacs (24 3))) "highlight alternating lines differently" single ((:commit . "618e40e0a9cf80decea32c8daecb1c9f6eae2991") (:authors ("Michael Schierl" . "schierlm-public@gmx.de") ("Štěpán Němec" . "stepnem@gmail.com")) (:maintainer "Štěpán Němec" . "stepnem@gmail.com") (:keywords "convenience" "faces") (:url . "https://gitlab.com/stepnem/stripes-el"))])
+ (stumpwm-mode . [(20140131 216) nil "special lisp mode for evaluating code into running stumpwm" single ((:commit . "61a7cf27e49e0779a53c018b2342f5f1c5cc70b4") (:maintainer "Shawn Betts") (:keywords "comm" "lisp" "tools"))])
+ (stupid-indent-mode . [(20170525 1117) nil "Plain stupid indentation minor mode" single ((:commit . "3295e7de5e2cfddc3bf0e462e852bf58972f5d70") (:authors ("Mihai Bazon" . "mihai.bazon@gmail.com")) (:maintainer "Mihai Bazon" . "mihai.bazon@gmail.com"))])
+ (stylefmt . [(20161025 824) nil "Stylefmt interface" single ((:commit . "7a38f26bf8ff947215f34f0a064c7ca80575ccbc") (:authors ("κeen")) (:maintainer "κeen") (:keywords "style" "code" "formatter") (:url . "https://github.com/KeenS/stylefmt.el"))])
+ (stylus-mode . [(20211019 2113) nil "Major mode for editing .styl files" single ((:commit . "1ad7c51f3c6a6ae64550d9510c5e4e8470014375") (:authors ("Brian M. Carlson and other contributors")) (:maintainer "Brian M. Carlson and other contributors") (:keywords "languages") (:url . "https://github.com/brianc/jade-mode"))])
+ (su . [(20210721 1816) ((emacs (26 1))) "Automatically read and write files using su or sudo" single ((:commit . "1ecf7a7bbf9d88708eb2215e940753f8d6bccc92") (:authors ("PythonNut" . "pythonnut@pythonnut.com")) (:maintainer "PythonNut" . "pythonnut@pythonnut.com") (:keywords "convenience" "helm" "fuzzy" "flx") (:url . "https://github.com/PythonNut/su.el"))])
+ (subatomic-theme . [(20220128 1615) nil "Low contrast bluish color theme" single ((:commit . "9d0ac6aa5272d0285965a48505eb35658c5472b0") (:authors ("John Olsson" . "john@cryon.se")) (:maintainer "John Olsson" . "john@cryon.se") (:keywords "color-theme" "blue" "low contrast") (:url . "https://github.com/cryon/subatomic"))])
+ (subatomic256-theme . [(20130621 210) nil "Fork of subatomic-theme for terminals." single ((:commit . "326177d6f99cd2b1d30df695e67ee3bc441cd96f") (:authors ("John Olsson" . "john@cryon.se")) (:maintainer "John Olsson" . "john@cryon.se") (:url . "https://github.com/cryon/subatomic256"))])
+ (subemacs . [(20170401 934) nil "Evaluating expressions in a fresh Emacs subprocess" single ((:commit . "18d53939fec8968c08dfc5aff7240ca07efb1aac") (:authors ("Klaus-Dieter Bauer" . "bauer.klaus.dieter@gmail.com")) (:maintainer "Klaus-Dieter Bauer" . "bauer.klaus.dieter@gmail.com") (:keywords "extensions" "lisp" "multiprocessing") (:url . "https://github.com/kbauer/subemacs"))])
+ (sublime-themes . [(20170606 1844) nil "A collection of themes based on Sublime Text" tar ((:commit . "60ee40af82eb55b79d5ed4026f1911326311603f") (:authors ("Owain Lewis" . "owain@owainlewis.com")) (:maintainer "Owain Lewis" . "owain@owainlewis.com") (:keywords "faces"))])
+ (sublimity . [(20200905 1730) ((emacs (26 1))) "smooth-scrolling, minimap and distraction-free mode" tar ((:commit . "8e2ffc4d62194106130014531e7b54fc9b4b9e6c") (:authors ("zk_phi")) (:maintainer "zk_phi") (:url . "https://github.com/zk-phi/sublimity"))])
+ (subsonic . [(20220403 1208) ((emacs (27 1)) (transient (0 2))) "Browse and play music from subsonic servers with mpv" single ((:commit . "e9acece0f840bc6ea096ae56e77573939a2c510c") (:authors ("Alex McGrath" . "amk@amk.ie")) (:maintainer "Alex McGrath" . "amk@amk.ie") (:keywords "multimedia") (:url . "https://git.sr.ht/~amk/subsonic.el"))])
+ (sudo-edit . [(20210706 534) ((emacs (24)) (cl-lib (0 5))) "Open files as another user" single ((:commit . "23b78a39053088839f281bc0c3134203d7e04e50") (:authors ("Nathaniel Flath" . "flat0103@gmail.com")) (:maintainer "Nathaniel Flath" . "flat0103@gmail.com") (:keywords "convenience") (:url . "https://github.com/nflath/sudo-edit"))])
+ (sudo-ext . [(20170126 1214) nil "sudo support" single ((:commit . "9d4580f304121ce7b8104bd4bd3b64e4dfa3c9b3") (:authors ("rubikitch" . "rubikitch@ruby-lang.org")) (:maintainer "rubikitch" . "rubikitch@ruby-lang.org") (:keywords "unix") (:url . "http://www.emacswiki.org/cgi-bin/wiki/download/sudo-ext.el"))])
+ (sudo-utils . [(20210119 1930) ((emacs (25 1))) "Sudo utilities" single ((:commit . "089f7833fa256f293284a6286bf9cb2b78eff40d") (:authors ("Alpha Catharsis" . "alpha.catharsis@gmail.com")) (:maintainer "Alpha Catharsis" . "alpha.catharsis@gmail.com") (:keywords "processes" "unix") (:url . "https://github.com/alpha-catharsis/sudo-utils"))])
+ (sudoku . [(20191015 1315) ((emacs (24 4))) "Simple sudoku game, can download puzzles" single ((:commit . "b1924fd244a5fa284de9d67b66fbd69164b37318") (:authors ("Zajcev Evgeny" . "zevlg@yandex.ru")) (:maintainer "Zajcev Evgeny" . "zevlg@yandex.ru") (:keywords "games"))])
+ (suggest . [(20190807 851) ((emacs (24 4)) (loop (1 3)) (dash (2 13 0)) (s (1 11 0)) (f (0 18 2)) (spinner (1 7 3))) "suggest elisp functions that give the output requested" tar ((:commit . "7b1c7fd38cd9389e58f672bfe58d9e88aeb898c7") (:authors ("Wilfred Hughes" . "me@wilfred.me.uk")) (:maintainer "Wilfred Hughes" . "me@wilfred.me.uk") (:keywords "convenience") (:url . "https://github.com/Wilfred/suggest.el"))])
+ (suggestion-box . [(20170830 807) ((emacs (25 1)) (popup (0 5 3))) "show tooltip on the cursor" single ((:commit . "50af0776c8caf3c79c4d37fd51cbf304ea34b68e") (:authors ("Yuta Yamada <cokesboy\"at\"gmail.com>")) (:maintainer "Yuta Yamada <cokesboy\"at\"gmail.com>") (:keywords "convenience"))])
+ (sunburn-theme . [(20201216 1539) ((emacs (24))) "A low contrast color theme" single ((:commit . "6b5c14c76dcdfdb099102ef7a388b2f0c6f1951d") (:authors ("Martín Varela" . "martin@varela.fi")) (:maintainer "Martín Varela" . "martin@varela.fi") (:url . "http://github.com/mvarela/Sunburn-Theme"))])
+ (sunny-day-theme . [(20140413 2125) nil "Emacs24 theme with a light background." single ((:commit . "420e0a6eb33fcc9b75c2c9e88ab60a975d782a00") (:authors ("Martin Haesler")) (:maintainer "Martin Haesler") (:url . "http://github.com/mswift42/sunny-day-theme"))])
+ (sunshine . [(20200306 1711) ((cl-lib (0 5))) "Provide weather and forecast information." single ((:commit . "88256223539edcfe57017778a997a474c9c022f6") (:authors ("Aaron Bieber" . "aaron@aaronbieber.com")) (:maintainer "Aaron Bieber" . "aaron@aaronbieber.com") (:keywords "tools" "weather") (:url . "https://github.com/aaronbieber/sunshine.el"))])
+ (suomalainen-kalenteri . [(20220101 718) nil "Finnish national and Christian holidays for calendar" tar ((:commit . "30103e6c6fa5dcbae70a636b007afdaad2fbcac0") (:authors ("Teemu Likonen" . "tlikonen@iki.fi")) (:maintainer "Teemu Likonen" . "tlikonen@iki.fi") (:keywords "calendar" "holidays" "finnish") (:url . "https://github.com/tlikonen/suomalainen-kalenteri"))])
+ (super-save . [(20220426 1056) ((emacs (24 4))) "Auto-save buffers, based on your activity." single ((:commit . "71c26cbd47d993fff37e572523ea79c9c49f5caf") (:authors ("Bozhidar Batsov" . "bozhidar@batsov.com")) (:maintainer "Bozhidar Batsov" . "bozhidar@batsov.com") (:keywords "convenience") (:url . "https://github.com/bbatsov/super-save"))])
+ (supergenpass . [(20130329 548) nil "SuperGenPass for Emacs" single ((:commit . "549072ef7b5b82913cadd4758e8a0a9926f0a04a") (:authors ("Jaime Fournier" . "jaimef@linbsd.org")) (:maintainer "Jaime Fournier" . "jaimef@linbsd.org") (:keywords "supergenpass"))])
+ (suscolors-theme . [(20190713 1009) nil "Colorful theme, inspired by Gruvbox." single ((:commit . "b4a979ee23e26e255b9a63525b0a28e810fab9ae") (:url . "https://github.com/TheSuspiciousWombat/SusColors-emacs"))])
+ (sv-kalender-namnsdagar . [(20190421 1521) nil "Swedish celebrated name of the day" single ((:commit . "fff970f49c77abfc69e37817f25a939818420971") (:authors ("Mats Lidell" . "mats.lidell@lidells.se")) (:maintainer "Mats Lidell" . "mats.lidell@lidells.se") (:keywords "calendar" "swedish" "localization") (:url . "https://github.com/matsl/sv-kalender-namnsdagar"))])
+ (svelte-mode . [(20211016 652) ((emacs (26 1))) "Emacs major mode for Svelte" single ((:commit . "6a1d4274af7f4c0f271f77bd96678c3dd1fa68e1") (:authors ("Leaf" . "leafvocation@gmail.com")) (:maintainer "Leaf" . "leafvocation@gmail.com") (:keywords "wp" "languages") (:url . "https://github.com/leafOfTree/svelte-mode"))])
+ (svg-mode-line-themes . [(20150425 2006) ((xmlgen (0 4))) "SVG-based themes for mode-line" tar ((:commit . "80a0e01839cafbd66899202e7764c33231974259") (:authors ("sabof")) (:maintainer "sabof") (:url . "https://github.com/sabof/svg-mode-line-themes"))])
+ (svg-tag-mode . [(20211229 920) ((emacs (27 1)) (svg-lib (0 2))) "Replace keywords with SVG tags" single ((:commit . "07640c97a1dcc305010a384fffdaa7788c342da7") (:authors ("Nicolas P. Rougier" . "Nicolas.Rougier@inria.fr")) (:maintainer "Nicolas P. Rougier" . "Nicolas.Rougier@inria.fr") (:keywords "convenience") (:url . "https://github.com/rougier/svg-tag-mode"))])
+ (svnwrapper . [(20180414 1843) ((e2ansi (0 1 1))) "Highlighting and paging for shell command `svn'" tar ((:commit . "de5069f5784e5d9e87a0af0159ba5f28a3716583") (:authors ("Anders Lindgren")) (:maintainer "Anders Lindgren") (:keywords "faces") (:url . "https://github.com/Lindydancer/svnwrapper"))])
+ (swagger-to-org . [(20160611 56) ((emacs (24)) (cl-lib (0 5)) (json (1 4))) "Convert a swagger.json file into an org-mode file" single ((:commit . "181357c71ea24bede263f5706d8781ad65e16877") (:authors ("Matthew Carter" . "m@ahungry.com")) (:maintainer "Matthew Carter" . "m@ahungry.com") (:keywords "ahungry" "emacs" "swagger" "openapi" "orgmode" "org" "export") (:url . "https://github.com/ahungry/swagger-to-org"))])
+ (swap-buffers . [(20150506 2139) nil "The quickest way to swap buffers between windows. Based on switch-window package." single ((:commit . "46ab31359b70d935add6c6e9533443116dc51103") (:authors ("Evgeniy Kazakov" . "evgeniy.kazakov@gmail.com")) (:maintainer "Evgeniy Kazakov" . "evgeniy.kazakov@gmail.com") (:keywords "window" "swap" "buffer" "exchange") (:url . "https://github.com/ekazakov/swap-buffers"))])
+ (swap-regions . [(20180915 1346) ((emacs (24 3))) "Swap text in two regions" single ((:commit . "f4fd9880cf690e003fcde88dcf2b46adbbbb03cd") (:authors ("Xu Chunyang" . "mail@xuchunyang.me")) (:maintainer "Xu Chunyang" . "mail@xuchunyang.me") (:keywords "convenience") (:url . "https://github.com/xuchunyang/swap-regions.el"))])
+ (sway . [(20211109 1601) ((emacs (27 1)) (dash (2 18 1))) "Communication with the Sway window manager" single ((:commit . "d84adab82ca5f84847702671dd60c0377c82ccd9") (:authors ("Thibault Polge" . "thibault@thb.lt")) (:maintainer "Thibault Polge" . "thibault@thb.lt") (:keywords "frames") (:url . "https://github.com/thblt/sway.el"))])
+ (sweet-theme . [(20200708 1202) ((emacs (24 1))) "Sweet-looking theme" single ((:commit . "78f741806ecebe01224bf54d09ad80e306652508") (:authors ("2bruh4me")) (:maintainer "2bruh4me") (:keywords "faces") (:url . "https://github.com/2bruh4me/sweet-theme"))])
+ (sweetgreen . [(20180605 335) ((dash (2 12 1)) (helm (1 5 6)) (request (0 2 0)) (cl-lib (0 5))) "Order Salads from sweetgreen.com" single ((:commit . "e933fe466b5ef0e976967e203f88bd7a012469d1") (:authors ("Diego Berrocal" . "cestdiego@gmail.com")) (:maintainer "Diego Berrocal" . "cestdiego@gmail.com") (:keywords "salad" "food" "sweetgreen" "request") (:url . "https://www.github.com/CestDiego/sweetgreen.el"))])
+ (swift-helpful . [(20220402 1433) ((emacs (25 1)) (dash (2 12 0)) (lsp-mode (6 0)) (swift-mode (8 0 0))) "Show documentation for Swift programs." tar ((:commit . "fe5c4a97fabbc89bd4761cfe4f8f8ce6f6d89703") (:authors ("Daniel Martín" . "mardani29@yahoo.es")) (:maintainer "Daniel Martín" . "mardani29@yahoo.es") (:keywords "help" "swift") (:url . "https://github.com/danielmartin/swift-helpful"))])
+ (swift-mode . [(20220313 542) ((emacs (24 4)) (seq (2 3))) "Major-mode for Apple's Swift programming language" tar ((:commit . "0d1ef0ef183398143b13fb8c76c1284df0d5e616") (:authors ("taku0 (http://github.com/taku0)") ("Chris Barrett" . "chris.d.barrett@me.com") ("Bozhidar Batsov" . "bozhidar@batsov.com") ("Arthur Evstifeev" . "lod@pisem.net")) (:maintainer "taku0 (http://github.com/taku0)") (:keywords "languages" "swift") (:url . "https://github.com/swift-emacs/swift-mode"))])
+ (swift-playground-mode . [(20190717 2223) ((emacs (24 4)) (seq (2 2 0))) "Run Apple's playgrounds in Swift buffers" tar ((:commit . "111cde906508824ee11d774b908df867142a8aec") (:keywords "languages" "swift") (:url . "https://gitlab.com/michael.sanders/swift-playground-mode"))])
+ (swift3-mode . [(20160918 1250) ((emacs (24 4))) "Major-mode for Apple's Swift programming language." tar ((:commit . "4e51265c6905e17d8910e35b0b37cf51e20ecdfe") (:keywords "languages" "swift") (:url . "https://github.com/taku0/swift3-mode"))])
+ (swiper . [(20220430 2247) ((emacs (24 5)) (ivy (0 13 4))) "Isearch with an overview. Oh, man!" single ((:commit . "8bf8027e4bd8c093bddb76a813952d2a0dcbf21d") (:authors ("Oleh Krehel" . "ohwoeowho@gmail.com")) (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com") (:keywords "matching") (:url . "https://github.com/abo-abo/swiper"))])
+ (swiper-helm . [(20180131 1744) ((emacs (24 1)) (swiper (0 1 0)) (helm (1 5 3))) "Helm version of Swiper." single ((:commit . "93fb6db87bc6a5967898b5fd3286954cc72a0008") (:authors ("Oleh Krehel" . "ohwoeowho@gmail.com")) (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com") (:keywords "matching") (:url . "https://github.com/abo-abo/swiper-helm"))])
+ (swiss-holidays . [(20200526 822) nil "Swiss holidays for the calendar" single ((:commit . "0995c9685033a09466f5b2dceb7316362bde997a") (:authors ("Christian Egli" . "christian.egli@alumni.ethz.ch")) (:maintainer "Christian Egli" . "christian.egli@alumni.ethz.ch") (:keywords "calendar") (:url . "https://github.com/egli/swiss-holidays"))])
+ (switch-buffer-functions . [(20200127 409) nil "Hook run when current buffer changed" single ((:commit . "95a846baa93bac4c3b3c028b9d53507f1042b23a") (:authors ("10sr <8slashes+el [at] gmail [dot] com>")) (:maintainer "10sr <8slashes+el [at] gmail [dot] com>") (:keywords "hook" "utility") (:url . "https://github.com/10sr/switch-buffer-functions-el"))])
+ (switch-window . [(20210808 742) ((emacs (24))) "A *visual* way to switch window" tar ((:commit . "8d9fe251d8d38b223d643df975876356ddfc1b98") (:authors ("Dimitri Fontaine" . "dim@tapoueh.org") ("Feng Shu" . "tumashu@163.com")) (:maintainer "Dimitri Fontaine" . "dim@tapoueh.org") (:keywords "convenience") (:url . "https://github.com/dimitri/switch-window"))])
+ (swoop . [(20200618 905) ((emacs (24 3)) (ht (2 0)) (pcre2el (1 5)) (async (1 1))) "Peculiar buffer navigation" tar ((:commit . "0c737a961970a2e61735545320367bafaa8dfc49") (:authors ("Shingo Fukuyama - http://fukuyama.co")) (:maintainer "Shingo Fukuyama - http://fukuyama.co") (:keywords "tools" "swoop" "inner" "buffer" "search" "navigation") (:url . "https://github.com/ShingoFukuyama/emacs-swoop"))])
+ (sws-mode . [(20210908 2121) nil "(S)ignificant (W)hite(S)pace mode" single ((:commit . "1ad7c51f3c6a6ae64550d9510c5e4e8470014375") (:authors ("Brian M. Carlson and other contributors")) (:maintainer "Brian M. Carlson and other contributors") (:keywords "languages") (:url . "https://github.com/brianc/jade-mode"))])
+ (sx . [(20191229 1746) ((emacs (24 1)) (cl-lib (0 5)) (json (1 3)) (markdown-mode (2 0)) (let-alist (1 0 3))) "StackExchange client. Ask and answer questions on Stack Overflow, Super User, and the likes" tar ((:commit . "e9d1093c97507a6d7b4f4710ef65200dae725e5f") (:authors ("Sean Allred" . "code@seanallred.com")) (:maintainer "Sean Allred" . "code@seanallred.com") (:keywords "help" "hypermedia" "tools") (:url . "https://github.com/vermiculus/sx.el/"))])
+ (sxiv . [(20210514 918) ((dash (2 16 0)) (emacs (25 1))) "Run the sxiv image viewer" single ((:commit . "028409c3a9ff7ba33a1cc2158abfc1793ed50717") (:authors ("contrapunctus" . "xmpp:contrapunctus@jabber.fr")) (:maintainer "contrapunctus" . "xmpp:contrapunctus@jabber.fr") (:keywords "multimedia") (:url . "https://gitlab.com/contrapunctus/sxiv.el"))])
+ (symbol-navigation-hydra . [(20211010 2353) ((auto-highlight-symbol (1 61)) (hydra (0 15 0)) (emacs (24 4)) (multiple-cursors (1 4 0))) "A symbol-aware, range-aware hydra" single ((:commit . "5675976cad4cbeee30f43e6c4b28c2e5904575a5") (:authors ("Brett Wines" . "bgwines@cs.stanford.edu")) (:maintainer "Brett Wines" . "bgwines@cs.stanford.edu") (:keywords "highlight" "face" "match" "convenience" "hydra" "symbol") (:url . "https://github.com/bgwines/symbol-navigation-hydra"))])
+ (symbol-overlay . [(20220304 917) ((emacs (24 3)) (seq (2 2))) "Highlight symbols with keymap-enabled overlays" single ((:commit . "c439b73a5f9713bb3dce98986b589bb901e22130") (:authors ("wolray" . "wolray@foxmail.com")) (:maintainer "wolray" . "wolray@foxmail.com") (:keywords "faces" "matching") (:url . "https://github.com/wolray/symbol-overlay/"))])
+ (symbolist . [(20211107 1615) ((emacs (24 5))) "List and interactively unbind Emacs Lisp symbols" single ((:commit . "92b712734941a45da7d47fd61b95e4013ff53481") (:authors ("Lassi Kortela" . "lassi@lassi.io")) (:maintainer "Lassi Kortela" . "lassi@lassi.io") (:keywords "lisp" "maint") (:url . "https://github.com/lassik/emacs-symbolist"))])
+ (symbolword-mode . [(20180401 1427) ((emacs (24)) (f (0 19 0))) "modify word split" single ((:commit . "c254ec56e83a5d9de04df0856248723cf6d4be50") (:authors ("ncaq" . "ncaq@ncaq.net")) (:maintainer "ncaq" . "ncaq@ncaq.net") (:url . "https://github.com/ncaq/symbolword-mode"))])
+ (symex . [(20220323 1808) ((emacs (25 1)) (lispy (0 26 0)) (paredit (24)) (evil-cleverparens (20170718 413)) (evil (1 2 14)) (evil-surround (1 0 4)) (hydra (0 15 0)) (seq (2 22)) (undo-tree (0 7 5))) "An evil way to edit Lisp symbolic expressions as trees" tar ((:commit . "8ab435c2866869977c92ad64c3706f626acfb4d3") (:authors ("Siddhartha Kasivajhula" . "sid@countvajhula.com")) (:maintainer "Siddhartha Kasivajhula" . "sid@countvajhula.com") (:keywords "lisp" "convenience" "languages") (:url . "https://github.com/countvajhula/symex.el"))])
+ (symon . [(20170224 833) nil "tiny graphical system monitor" single ((:commit . "8dd8b6df49b03cd7d31b85aedbe9dd08fb922335") (:authors ("zk_phi")) (:maintainer "zk_phi") (:url . "http://hins11.yu-yake.com/"))])
+ (symon-lingr . [(20150719 1342) ((symon (1 1 2)) (cl-lib (0 5))) "A notification-based Lingr client powered by symon.el" single ((:commit . "056d1a473e36992ff5881e5ce6fdc331cead975f") (:authors ("zk_phi")) (:maintainer "zk_phi") (:url . "http://hins11.yu-yake.com/"))])
+ (sync-recentf . [(20160326 2001) nil "Synchronize the recent files list between Emacs instances" single ((:commit . "0052561d5c5b5c2684faedc3eead776aec06c3ed") (:authors ("François Févotte" . "fevotte@gmail.com")) (:maintainer "François Févotte" . "fevotte@gmail.com") (:keywords "recentf") (:url . "https://github.com/ffevotte/sync-recentf"))])
+ (synonymous . [(20180325 1817) ((emacs (24)) (cl-lib (0 5)) (request (0 2 0))) "A thesaurus at your fingertips" single ((:commit . "2cb9a674d84fddf3f1b00c9d6b13a853576acb87") (:authors ("Katherine Whitlock" . "toroidalcode@gmail.com") ("Snippets adapted from FlySpell, authored by Manuel Serrano" . "Manuel.Serrano@inria.fr")) (:maintainer "Katherine Whitlock" . "toroidalcode@gmail.com") (:keywords "utility") (:url . "http://github.com/toroidal-code/synonymous.el"))])
+ (synosaurus . [(20191125 552) ((cl-lib (0 5))) "An extensible thesaurus supporting lookup and substitution." tar ((:commit . "14d34fc92a77c3a916b4d58400424c44ae99cd81") (:authors ("Hans-Peter Deifel" . "hpd@hpdeifel.de")) (:maintainer "Hans-Peter Deifel" . "hpd@hpdeifel.de") (:keywords "wp"))])
+ (synquid . [(20160930 1550) ((flycheck (27)) (emacs (24 3))) "Major mode for editing Synquid files" single ((:commit . "28701ce1a15437202f53ab93a14bcba1de83fd2c") (:authors ("Clément Pit-Claudel" . "clement.pitclaudel@live.com")) (:maintainer "Clément Pit-Claudel" . "clement.pitclaudel@live.com") (:keywords "languages") (:url . "https://github.com/cpitclaudel/synquid-mode"))])
+ (syntactic-close . [(20210105 1400) ((emacs (24)) (cl-lib (0 5))) "Insert closing delimiter" single ((:commit . "ffe8b28907973fda775254432f88b55c92b5ae1f") (:authors ("Emacs User Group Berlin" . "emacs-berlin@emacs-berlin.org")) (:maintainer "Emacs User Group Berlin" . "emacs-berlin@emacs-berlin.org") (:keywords "languages" "convenience") (:url . "https://github.com/emacs-berlin/syntactic-close"))])
+ (syntactic-sugar . [(20140508 2041) nil "Effect-free forms such as if/then/else" single ((:commit . "7ddc4502c831abe1c4ad4c7d1ca628a2c9e13968") (:authors ("Roland Walker" . "walker@pobox.com")) (:maintainer "Roland Walker" . "walker@pobox.com") (:keywords "extensions") (:url . "http://github.com/rolandwalker/syntactic-sugar"))])
+ (syntax-subword . [(20160205 2154) nil "make operations on words more fine-grained" single ((:commit . "9aa9b3f846bfe2474370642458a693ac4760d9fe") (:authors ("Jonathan Kotta" . "jpkotta@gmail.com")) (:maintainer "Jonathan Kotta" . "jpkotta@gmail.com"))])
+ (syntree . [(20220122 2341) ((emacs (27 1)) (transient (0 3 7))) "Draw plain text constituency trees" single ((:commit . "45d010b071c32cab4a3a5d336d6c01cde49657f8") (:authors ("Enrico Flor" . "enrico@eflor.net")) (:maintainer "Enrico Flor" . "enrico@eflor.net") (:url . "https://github.com/enricoflor/syntree"))])
+ (sysctl . [(20200615 1824) ((emacs (26))) "Manage sysctl though org-mode" single ((:commit . "d8c2e18de1d7a3b2999a4d5054c0bbf30cb10fed") (:authors ("Dante Catalfamo")) (:maintainer "Dante Catalfamo") (:keywords "sysctl" "tools" "unix") (:url . "https://github.com/dantecatalfamo/sysctl.el"))])
+ (syslog-mode . [(20210910 1952) ((hide-lines (20130623)) (ov (20150311)) (hsluv (20181127))) "Major-mode for viewing log files & strace output" tar ((:commit . "072664784dae41a573a9de8d178bf577b7526b82") (:authors ("Harley Gorrell" . "harley@panix.com")) (:maintainer "Joe Bloggs" . "vapniks@yahoo.com") (:keywords "unix") (:url . "https://github.com/vapniks/syslog-mode"))])
+ (system-packages . [(20220409 1023) ((emacs (24 3))) "functions to manage system packages" single ((:commit . "c087d2c6e598f85fc2760324dce20104ea442fa3") (:authors ("J. Alexander Branham" . "alex.branham@gmail.com")) (:maintainer "J. Alexander Branham" . "alex.branham@gmail.com") (:url . "https://gitlab.com/jabranham/system-packages"))])
+ (system-specific-settings . [(20140818 1457) nil "Apply settings only on certain systems" single ((:commit . "0050d85b2175095aa5ecf580a2fe43c069b0eef3") (:authors ("Ryan C. Thompson")) (:maintainer "Ryan C. Thompson") (:keywords "configuration") (:url . "https://github.com/DarwinAwardWinner/emacs-system-specific-settings"))])
+ (systemd . [(20210209 2052) ((emacs (24 4))) "Major mode for editing systemd units" tar ((:commit . "b6ae63a236605b1c5e1069f7d3afe06ae32a7bae") (:authors ("Mark Oteiza" . "mvoteiza@udel.edu")) (:maintainer "Mark Oteiza" . "mvoteiza@udel.edu") (:keywords "tools" "unix"))])
+ (systemtap-mode . [(20151122 1940) nil "A mode for SystemTap" single ((:commit . "1a968c2b1f3a054bebf91ac49739d3a81ce050a9") (:maintainer nil . "ruediger@c-plusplus.de") (:keywords "tools" "languages") (:url . "https://github.com/ruediger/systemtap-mode"))])
+ (ta . [(20160619 1645) ((emacs (24 3)) (cl-lib (0 5))) "A tool to deal with Chinese homophonic characters" single ((:commit . "668ad41e71f374f8c32c8d0532f3d8485b355d35") (:authors ("kuanyui" . "azazabc123@gmail.com")) (:maintainer "kuanyui" . "azazabc123@gmail.com") (:keywords "tools") (:url . "http://github.com/kuanyui/ta.el"))])
+ (tab-bar-echo-area . [(20211013 1942) ((emacs (27 1))) "Display tab names of the tab bar in the echo area" single ((:commit . "d0d51ecbc5929eb7752b387c5bdfe4d879e78224") (:authors ("Fritz Grabo" . "hello@fritzgrabo.com")) (:maintainer "Fritz Grabo" . "hello@fritzgrabo.com") (:keywords "convenience") (:url . "https://github.com/fritzgrabo/tab-bar-echo-area"))])
+ (tab-bar-groups . [(20211013 2012) ((emacs (27 1)) (s (1 12 0))) "Tab groups for the tab bar" single ((:commit . "a0389d87d2e793055dd74ae85b4593aa1d2720fd") (:authors ("Fritz Grabo" . "hello@fritzgrabo.com")) (:maintainer "Fritz Grabo" . "hello@fritzgrabo.com") (:keywords "convenience") (:url . "https://github.com/fritzgrabo/tab-bar-groups"))])
+ (tab-bar-lost-commands . [(20211013 1945) ((emacs (27 1))) "The \"lost commands\" of the tab bar" single ((:commit . "989e03dc3d1057264b21b9a5d241fcba86cd297a") (:authors ("Fritz Grabo" . "hello@fritzgrabo.com")) (:maintainer "Fritz Grabo" . "hello@fritzgrabo.com") (:keywords "convenience") (:url . "https://github.com/fritzgrabo/tab-bar-lost-commands"))])
+ (tab-group . [(20140306 1450) nil "Grouped tabs and their tabbar" single ((:commit . "5a290ec2608e4100fb188fd60ecb77affcc3465b") (:authors ("INA Lintaro <tarao.gnn at gmail.com>")) (:maintainer "INA Lintaro <tarao.gnn at gmail.com>") (:keywords "convenience" "tabs") (:url . "http://github.com/tarao/tab-group-el"))])
+ (tab-jump-out . [(20151006 130) ((dash (2 10)) (emacs (24 4))) "Use tab to jump out of delimiter pairs." single ((:commit . "1c3fec1826d2891177ea78e4e7cce1dc67e83e51") (:authors ("Zhang Kai Yu" . "yeannylam@gmail.com")) (:maintainer "Zhang Kai Yu" . "yeannylam@gmail.com") (:keywords "tab" "editing"))])
+ (tabbar . [(20180726 1735) nil "Display a tab bar in the header line" tar ((:commit . "82bbda31cbe8ef367dd6501c3aa14b7f2c835910") (:authors ("David Ponce" . "david@dponce.com")) (:maintainer "David Ponce" . "david@dponce.com") (:keywords "convenience"))])
+ (tabbar-ruler . [(20160802 307) ((tabbar (2 0 1)) (powerline (2 3)) (mode-icons (0 4 0)) (cl-lib (0 5))) "Pretty tabbar, autohide, use both tabbar/ruler" tar ((:commit . "535568189aa12a3eff7f977d2783e57b6a65ab6a") (:authors ("Matthew Fidler, Ta Quang Trung, Nathaniel Cunningham")) (:maintainer "Matthew L. Fidler") (:keywords "tabbar" "ruler mode" "menu" "tool bar.") (:url . "http://github.com/mlf176f2/tabbar-ruler.el"))])
+ (tablist . [(20200427 2205) ((emacs (24 3))) "Extended tabulated-list-mode" tar ((:commit . "faab7a035ef2258cc4ea2182f67e3aedab7e2af9") (:authors ("Andreas Politz" . "politza@fh-trier.de")) (:maintainer "Andreas Politz" . "politza@fh-trier.de") (:keywords "extensions" "lisp"))])
+ (tabspaces . [(20220504 1751) ((emacs (27 1)) (project (0 8 1))) "Leverage tab-bar and project for buffer-isolated workspaces" single ((:commit . "d8c9e06b4260c970b5a26e14c11d5e396dfc1de1") (:authors ("Colin McLear" . "mclear@fastmail.com")) (:maintainer "Colin McLear") (:keywords "convenience" "frames") (:url . "https://github.com/mclear-tools/tabspaces"))])
+ (tabula-rasa . [(20141216 547) ((emacs (24 4))) "Distraction free writing mode" single ((:commit . "e85fff9de18dc31bc6a7aca726e34a95cc5459f5") (:authors ("Ido Magal" . "misc@satans.church")) (:maintainer "Ido Magal" . "misc@satans.church") (:keywords "distraction free" "writing") (:url . "https://github.com/idomagal/Tabula-Rasa/blob/master/tabula-rasa.el"))])
+ (tagedit . [(20161121 855) ((s (1 3 1)) (dash (1 0 3))) "Some paredit-like features for html-mode" single ((:commit . "b3a70101a0dcf85498c92b7fcfa7fdbac869746c") (:authors ("Magnar Sveen" . "magnars@gmail.com")) (:maintainer "Magnar Sveen" . "magnars@gmail.com") (:keywords "convenience"))])
+ (take-off . [(20140531 917) ((emacs (24 3)) (web-server (0 1 0))) "Emacs remote web access" tar ((:commit . "aa9ea45566fc74febbb6ee9c409ecc4b59246215") (:authors ("Thomas Burette" . "burettethomas@gmail.com")) (:maintainer "Thomas Burette" . "burettethomas@gmail.com") (:url . "https://github.com/tburette/take-off"))])
+ (talonscript-mode . [(20220204 1441) ((emacs (24 3))) "Major mode for Talon Voice's .talon files" single ((:commit . "b6eb61f56349e0d47276270163ec611c2d5b188e") (:authors ("Jcaw" . "toastedjcaw@gmail.com")) (:maintainer "Jcaw" . "toastedjcaw@gmail.com") (:keywords "languages") (:url . "https://github.com/jcaw/talonscript-mode"))])
+ (tango-2-theme . [(20120312 2025) nil "Tango 2 color theme for GNU Emacs 24" single ((:commit . "64e44c98e41ebbe3b827d54280e3b9615787daaa") (:authors ("Nick Parker")) (:maintainer "Nick Parker"))])
+ (tango-plus-theme . [(20211222 1100) nil "A color theme based on the tango palette" single ((:commit . "774b03f932bbc336ce5f943af175d5faa651f2e0") (:authors ("Titus von der Malsburg" . "malsburg@posteo.de")) (:maintainer "Titus von der Malsburg" . "malsburg@posteo.de") (:url . "https://github.com/tmalsburg/tango-plus-theme"))])
+ (tangotango-theme . [(20220106 1039) nil "Tango Palette color theme for Emacs 24." single ((:commit . "9509035842c5ea44f594879199a74c9fc6d2a368") (:authors ("Julien Barnier")) (:maintainer "Julien Barnier") (:keywords "tango" "palette" "color" "theme" "emacs") (:url . "https://github.com/juba/color-theme-tangotango"))])
+ (tao-theme . [(20220414 354) nil "This package provides two parametrized uncoloured color themes for Emacs: tao-yin and tao-yang." tar ((:commit . "d6fe980783e22df310df1ae51ac249c28c83ac53") (:authors ("Peter Kosov" . "11111000000@email.com")) (:maintainer "Peter Kosov" . "11111000000@email.com") (:url . "http://github.com/11111000000/tao-theme-emacs"))])
+ (taskpaper-mode . [(20220410 1953) nil "Major mode for working with TaskPaper files" single ((:commit . "12c2f7e01a0e5cc9a57c9d8a8f3fecc8f8ddecb2") (:authors ("Dmitry Safronov" . "saf.dmitry@gmail.com")) (:maintainer "Dmitry Safronov" . "saf.dmitry@gmail.com") (:keywords "outlines" "notetaking" "task management" "productivity" "taskpaper") (:url . "https://github.com/saf-dmitry/taskpaper-mode"))])
+ (taskrunner . [(20190916 1608) ((emacs (25 1)) (projectile (2 0 0)) (async (1 9 3))) "Retrieve build system/taskrunner tasks" tar ((:commit . "716323aff410b4d864d137c9ebe4bbb5b8587f5e") (:authors ("Yavor Konstantinov <ykonstantinov1 AT gmail DOT com>")) (:maintainer "Yavor Konstantinov <ykonstantinov1 AT gmail DOT com>") (:keywords "build-system" "taskrunner" "build" "task-runner" "tasks" "convenience") (:url . "https://github.com/emacs-taskrunner/emacs-taskrunner"))])
+ (tawny-mode . [(20191108 1346) ((cider (0 12)) (emacs (25))) "Ontology Editing with Tawny-OWL" single ((:commit . "82f343bac637e62f31152d72086c7facd4dfea27") (:authors ("Phillip Lord" . "phillip.lord@newcastle.ac.uk")) (:maintainer "Phillip Lord" . "phillip.lord@newcastle.ac.uk"))])
+ (tblui . [(20161007 1912) ((dash (2 12 1)) (magit-popup (2 6 0)) (tablist (0 70)) (cl-lib (0 5))) "Define tabulated list UI easily" single ((:commit . "bb29323bb3e27093d50cb42db3a9329a096b6e4d") (:authors ("Yuki Inoue <inouetakahiroki _at_ gmail.com>")) (:maintainer "Yuki Inoue <inouetakahiroki _at_ gmail.com>") (:url . "https://github.com/Yuki-Inoue/tblui.el"))])
+ (tbx2org . [(20140224 1559) ((dash (2 5 0)) (s (1 8 0)) (cl-lib (0 4))) "Tinderbox to org-mode conversion" single ((:commit . "08e9816ba6066f56936050b58d07ceb2187ae6f7") (:authors ("istib")) (:maintainer "istib") (:keywords "org-mode") (:url . "https://github.com/istib/tbx2org"))])
+ (tc . [(20220122 1443) nil "a Japanese input method with T-Code on Emacs" tar ((:commit . "d0adf22f5aed4d9608778108b60a06c9ea58b289") (:authors ("Kaoru Maeda" . "maeda@src.ricoh.co.jp") ("Yasushi Saito" . "yasushi@cs.washington.edu") ("KITAJIMA Akira" . "kitajima@isc.osakac.ac.jp")) (:maintainer "KITAJIMA Akira"))])
+ (tco . [(20191129 2040) ((dash (1 2 0)) (emacs (24 3))) "Tail-call optimisation for Emacs lisp" single ((:commit . "d82478d56568f60b3a82fd010b3ca0bab2ef5dc9") (:authors ("Wilfred Hughes" . "me@wilfred.me.uk")) (:maintainer "Wilfred Hughes" . "me@wilfred.me.uk") (:url . "https://github.com/Wilfred/tco.el"))])
+ (tea-time . [(20120331 820) nil "Simple timer package, useful to make perfect tea." single ((:commit . "1f6cf0bdd27c5eb3508989c5095427781f858eca") (:authors ("konsty" . "antipin.konstantin@googlemail.com")) (:maintainer "Gabriel Saldana" . "gsaldana@gmail.com") (:keywords "timer" "tea-time"))])
+ (teacode-expand . [(20181231 640) ((emacs (24 4))) "Expansion of text by TeaCode program." single ((:commit . "2122e4b32ed4edd2d7ebc0ff8ebf407e29d6e910") (:authors ("Richard Guay" . "raguay@customct.com")) (:maintainer "Richard Guay" . "raguay@customct.com") (:keywords "lisp") (:url . "https://github.com/raguay/TeaCode-Expand"))])
+ (teco . [(20200707 2309) nil "Teco interpreter" single ((:commit . "61caf8f419659a0567a269f290c90427a215d77b") (:authors ("Dale R. Worley" . "worley@alum.mit.edu")) (:maintainer "Mark T. Kennedy" . "mtk@acm.org") (:keywords "convenience" "emulations" "files") (:url . "https://github.com/mtk/teco.git"))])
+ (telega . [(20220503 349) ((emacs (26 1)) (visual-fill-column (1 9)) (rainbow-identifiers (0 2 2))) "Telegram client (unofficial)" tar ((:commit . "29010616931f52e3a5aa9d155c14873c09c7306b") (:authors ("Zajcev Evgeny" . "zevlg@yandex.ru")) (:maintainer "Zajcev Evgeny" . "zevlg@yandex.ru") (:keywords "comm") (:url . "https://github.com/zevlg/telega.el"))])
+ (telepathy . [(20131209 1258) nil "Access Telepathy from Emacs" single ((:commit . "211d785b02a29ddc254422fdcc3db45262582f8c") (:authors ("Nicolas Petton" . "petton.nicolas@gmail.com")) (:maintainer "Nicolas Petton" . "petton.nicolas@gmail.com") (:keywords "telepathy" "tools"))])
+ (telephone-line . [(20220424 400) ((emacs (24 4)) (cl-lib (0 5)) (cl-generic (0 2)) (seq (1 8))) "Rewrite of Powerline" tar ((:commit . "6f3455a365912e8f0c45a2240ea79507dee45ade") (:authors ("Daniel Bordak" . "dbordak@fastmail.fm")) (:maintainer "Daniel Bordak" . "dbordak@fastmail.fm") (:keywords "mode-line") (:url . "https://github.com/dbordak/telephone-line"))])
+ (teletext . [(20211203 1111) ((emacs (24 3))) "Teletext broadcast viewer" single ((:commit . "6b003e9dab9bd0c27d188a81f5fff740d66a2282") (:authors ("Lassi Kortela" . "lassi@lassi.io")) (:maintainer "Lassi Kortela" . "lassi@lassi.io") (:keywords "comm" "help" "hypermedia") (:url . "https://github.com/lassik/emacs-teletext"))])
+ (teletext-yle . [(20210927 825) ((emacs (24 3)) (teletext (0 1))) "Teletext provider for Finnish national network YLE" single ((:commit . "9c8f4b503923c4ec688e2dcc9dff62d71bc55933") (:authors ("Lassi Kortela" . "lassi@lassi.io")) (:maintainer "Lassi Kortela" . "lassi@lassi.io") (:keywords "comm" "help" "hypermedia") (:url . "https://github.com/lassik/emacs-teletext-yle"))])
+ (tempel . [(20220430 1020) ((emacs (27 1))) "Tempo templates/snippets with in-buffer field editing" single ((:commit . "1ce581e30455b113d9c8358e79952134ca2e0356") (:authors ("Daniel Mendler" . "mail@daniel-mendler.de")) (:maintainer "Daniel Mendler" . "mail@daniel-mendler.de") (:url . "https://github.com/minad/tempel"))])
+ (template-overlays . [(20180706 1132) ((emacs (24 4)) (ov (1 0 6))) "Display template regions using overlays" single ((:commit . "d32db58c044b2aca3720879003f55b1d57208b07") (:authors ("Mariano Montone" . "marianomontone@gmail.com")) (:maintainer "Mariano Montone" . "marianomontone@gmail.com") (:keywords "faces" "convenience" "templates" "overlays") (:url . "http://www.github.com/mmontone/template-overlays"))])
+ (templatel . [(20210902 228) ((emacs (25 1))) "Templating language;" single ((:commit . "b52349948b6927f7a5da4e54a89e01c794f2095a") (:authors ("Lincoln Clarete" . "lincoln@clarete.li")) (:maintainer "Lincoln Clarete" . "lincoln@clarete.li") (:url . "https://clarete.li/templatel"))])
+ (temporary-persistent . [(20200201 1719) ((emacs (24 3)) (names (20151201 0)) (dash (2 12 1)) (s (1 10 0))) "Keep temp notes buffers persistent" single ((:commit . "0080879b0257d350aeba1c4d6901613d7dc534de") (:authors ("Kostafey" . "kostafey@gmail.com")) (:maintainer "Kostafey" . "kostafey@gmail.com") (:keywords "temp" "buffers" "notes") (:url . "https://github.com/kostafey/temporary-persistent"))])
+ (ten-hundred-mode . [(20161028 2236) ((cl-lib (0 5))) "use only the ten hundred most usual words" tar ((:commit . "bdcfda49b1819e82d61fe90947e50bb948cf7933"))])
+ (term+ . [(20170509 17) ((emacs (24)) (cl-lib (0 5))) "term-mode enhancement" tar ((:commit . "c3c9239b339c127231860de43abfa08c44c0201a") (:authors ("INA Lintaro <tarao.gnn at gmail.com>")) (:maintainer "INA Lintaro <tarao.gnn at gmail.com>") (:keywords "terminal" "emulation") (:url . "https://github.com/tarao/term-plus-el"))])
+ (term+key-intercept . [(20140211 750) ((term+ (0 1)) (key-intercept (0 1))) "term+ intercept key mapping" single ((:commit . "fd0771fd66b8c7a909aaac972194485c79ba48c4") (:authors ("INA Lintaro <tarao.gnn at gmail.com>")) (:maintainer "INA Lintaro <tarao.gnn at gmail.com>") (:keywords "terminal" "emulation") (:url . "http://github.com/tarao/term+-el"))])
+ (term+mux . [(20140211 749) ((term+ (0 1)) (tab-group (0 1))) "term+ terminal multiplexer and session management" single ((:commit . "81b60e80cf008472bfd7fad9233af2ef722c208a") (:authors ("INA Lintaro <tarao.gnn at gmail.com>")) (:maintainer "INA Lintaro <tarao.gnn at gmail.com>") (:keywords "terminal" "emulation") (:url . "http://github.com/tarao/term+-el"))])
+ (term-alert . [(20210414 1638) ((emacs (24 0)) (term-cmd (1 1)) (alert (1 1)) (f (0 18 2))) "Notifications when commands complete in term.el." tar ((:commit . "ca1b48ad911bc972b049f48fe0531e702dbc553c") (:authors ("Callie Cameron" . "cjcameron7@gmail.com")) (:maintainer "Callie Cameron" . "cjcameron7@gmail.com") (:keywords "notifications" "processes") (:url . "https://github.com/calliecameron/term-alert"))])
+ (term-cmd . [(20210417 1447) ((emacs (27 2)) (dash (2 12 0)) (f (0 18 2))) "Send commands from programs running in term.el." tar ((:commit . "281b9a6d864ca85dc1451dc46baca98f48dc3f60") (:authors ("Callie Cameron" . "cjcameron7@gmail.com")) (:maintainer "Callie Cameron" . "cjcameron7@gmail.com") (:keywords "processes") (:url . "https://github.com/calliecameron/term-cmd"))])
+ (term-manager . [(20190610 2032) ((dash (2 12 0)) (emacs (24 4))) "Contextual terminal management" tar ((:commit . "eea7894350a4f31e1df0c666d3fb0bac822d34d2") (:authors ("Ivan Malison" . "IvanMalison@gmail.com")) (:maintainer "Ivan Malison" . "IvanMalison@gmail.com") (:keywords "terminals" "tools") (:url . "https://www.github.com/IvanMalison/term-manager"))])
+ (term-projectile . [(20190307 400) ((emacs (24)) (term-manager (0 1 0)) (projectile (0 13 0))) "projectile terminal management" single ((:commit . "eea7894350a4f31e1df0c666d3fb0bac822d34d2") (:authors ("Ivan Malison" . "IvanMalison@gmail.com")) (:maintainer "Ivan Malison" . "IvanMalison@gmail.com") (:keywords "projectile" "tools" "terminals" "vc") (:url . "https://www.github.com/IvanMalison/term-manager"))])
+ (term-run . [(20200128 702) nil "Run arbitrary command in terminal buffer" single ((:commit . "0fd135d55fcf864598b1fb8dd880833a1a322910") (:authors ("10sr <8slashes+el [at] gmail [dot] com>")) (:maintainer "10sr <8slashes+el [at] gmail [dot] com>") (:keywords "utility" "shell" "command" "term-mode") (:url . "https://github.com/10sr/term-run-el"))])
+ (termbright-theme . [(20151031 235) ((emacs (24 1))) "a more usable theme for white-on-black terminals" single ((:commit . "bec6ab14336c0611e85f45486276004f16d20607") (:authors ("Brian Mastenbrook" . "brian@mastenbrook.net")) (:maintainer "Brian Mastenbrook" . "brian@mastenbrook.net") (:keywords "themes") (:url . "https://github.com/bmastenbrook/termbright-theme-el"))])
+ (terminal-focus-reporting . [(20180830 719) ((emacs (24 4))) "Minor mode for terminal focus reporting." single ((:commit . "6b1dbb2e96b3ff680dbe88153c4c569adbbd64ce") (:authors ("Vitalii Elenhaupt")) (:maintainer "Vitalii Elenhaupt") (:keywords "convenience") (:url . "https://github.com/veelenga/terminal-focus-reporting.el"))])
+ (terminal-here . [(20210605 1453) ((emacs (25 1))) "Run an external terminal in current directory" single ((:commit . "e0e89344624fadf080f6770132ebdd7991355fdd") (:authors ("David Shepherd" . "davidshepherd7@gmail.com")) (:maintainer "David Shepherd" . "davidshepherd7@gmail.com") (:keywords "tools" "frames") (:url . "https://github.com/davidshepherd7/terminal-here"))])
+ (terminal-toggle . [(20190226 1510) ((emacs (24)) (popwin (1 0 0))) "simple pop-up terminal" single ((:commit . "f824d634aef3600cb7a8e2ddf9e8444c6607c160") (:authors ("Mehmet Tekman")) (:maintainer "Mehmet Tekman") (:keywords "outlines") (:url . "https://github.com/mtekman/terminal-toggle.el"))])
+ (tern . [(20181108 722) ((json (1 2)) (cl-lib (0 5)) (emacs (24))) "Tern-powered JavaScript integration" single ((:commit . "ef50c6f0269a6fd9ce742d0a87647d60a0ef850f") (:authors ("Marijn Haverbeke")) (:maintainer "Marijn Haverbeke") (:url . "http://ternjs.net/"))])
+ (tern-auto-complete . [(20170521 1935) ((tern (0 0 1)) (auto-complete (1 4)) (cl-lib (0 5)) (emacs (24))) "Tern Completion by auto-complete.el" single ((:commit . "ef50c6f0269a6fd9ce742d0a87647d60a0ef850f") (:authors ("<m.sakurai at kiwanami.net>")) (:maintainer "<m.sakurai at kiwanami.net>"))])
+ (tern-context-coloring . [(20161218 747) ((emacs (24 3)) (context-coloring (8 1 0)) (tern (0 0 1))) "Use Tern for context coloring" single ((:commit . "3a8e979d6cc83aabcb3dda3f5f31a6422532efba") (:authors ("Jackson Ray Hamilton" . "jackson@jacksonrayhamilton.com")) (:maintainer "Jackson Ray Hamilton" . "jackson@jacksonrayhamilton.com") (:keywords "convenience" "faces" "tools") (:url . "https://github.com/jacksonrayhamilton/tern-context-coloring"))])
+ (terraform-doc . [(20211003 1333) ((emacs (24 4))) "Look up terraform documentation on the fly" single ((:commit . "16179e57ce290190c222b27961900657a1981330") (:authors ("Giap Tran" . "txgvnn@gmail.com")) (:maintainer "Giap Tran" . "txgvnn@gmail.com") (:keywords "comm") (:url . "https://github.com/TxGVNN/terraform-doc"))])
+ (terraform-mode . [(20210621 1953) ((emacs (24 3)) (hcl-mode (0 3)) (dash (2 17 0))) "Major mode for terraform configuration file" single ((:commit . "e560caaa9d9a11b0868adf6d9dcae5ebb5055730") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-terraform-mode"))])
+ (test-c . [(20180423 1720) ((emacs (24 3))) "quickly test c code" single ((:commit . "761a576f62c7021ba941f178f153c51289df1553") (:authors ("Aurélien Aptel" . "aurelien.aptel@gmail.com")) (:maintainer "Aurélien Aptel" . "aurelien.aptel@gmail.com") (:url . "http://github.com/aaptel/test-c"))])
+ (test-case-mode . [(20130525 1434) ((fringe-helper (0 1 1))) "unit test front-end" single ((:commit . "6074df10ebc97ddfcc228c71c73db179e672dac3") (:authors ("Nikolaj Schumacher <bugs * nschum de>")) (:maintainer "Nikolaj Schumacher <bugs * nschum de>") (:keywords "tools") (:url . "http://nschum.de/src/emacs/test-case-mode/"))])
+ (test-kitchen . [(20171129 2035) nil "Run test-kitchen inside of emacs" single ((:commit . "0fc0ca4808425f03fbeb8125246043723e2a179a") (:authors ("JJ Asghar")) (:maintainer "JJ Asghar") (:keywords "chef" "ruby" "test-kitchen") (:url . "http://github.com/jjasghar/test-kitchen-el"))])
+ (test-simple . [(20200722 1121) ((cl-lib (0))) "Simple Unit Test Framework for Emacs Lisp" single ((:commit . "ce6de04636e8d19ec84a475c03c0142b20a63de0") (:authors ("Rocky Bernstein" . "rocky@gnu.org")) (:maintainer "Rocky Bernstein" . "rocky@gnu.org") (:keywords "unit-test") (:url . "https://github.com/rocky/emacs-test-simple"))])
+ (tex-smart-umlauts . [(20190316 2215) nil "Smart umlaut conversion for TeX." single ((:commit . "f15ed781b1fb38bf3e46c481dd602c3999920b99") (:authors ("Frank Fischer <frank-fischer at shadow-soft.de>")) (:maintainer "Frank Fischer <frank-fischer at shadow-soft.de>") (:keywords "tex" "wp") (:url . "http://hub.darcs.net/lyro/tex-smart-umlauts"))])
+ (texfrag . [(20200716 1331) ((emacs (25)) (auctex (11 90 2))) "preview LaTeX fragments in alien major modes" single ((:commit . "a5f59e0c5f43578f139a2943bd08e5b3140f4c2b") (:authors ("Tobias Zawada" . "i@tn-home.de")) (:maintainer "Tobias Zawada" . "i@tn-home.de") (:keywords "tex" "languages" "wp") (:url . "https://github.com/TobiasZawada/texfrag"))])
+ (text-categories . [(20220411 2150) ((emacs (26 2))) "Assign text categories to a buffer for mass deletion" single ((:commit . "44cf654a4da7907fb53c8783f1eefa69fce00b43") (:authors ("Dionisios Spiliopoulos" . "dennisspiliopoylos@gmail.com")) (:maintainer "Dionisios Spiliopoulos" . "dennisspiliopoylos@gmail.com") (:keywords "lisp") (:url . "https://github.com/Dspil/text-categories"))])
+ (textile-mode . [(20210912 906) nil "Textile markup editing major mode" single ((:commit . "a49d9bf42166584cca395a92311e9d0a199efc46") (:authors ("Julien Barnier" . "julien@nozav.org")) (:maintainer "Julien Barnier" . "julien@nozav.org") (:keywords "wp" "languages") (:url . "https://github.com/juba/textile-mode"))])
+ (textmate . [(20110816 2146) nil "TextMate minor mode for Emacs" single ((:commit . "350918b070148f0ace6d9d3cd4ebcaf15c1a8781") (:authors ("Chris Wanstrath" . "chris@ozmm.org")) (:maintainer "Chris Wanstrath" . "chris@ozmm.org") (:keywords "textmate" "osx" "mac"))])
+ (textmate-to-yas . [(20160409 1708) nil "Import Textmate macros into yasnippet syntax" tar ((:commit . "be3a768b7ac4c2e24b9d4aa6e9ac1d916cdc5a73") (:authors ("Matthew L. Fidler")) (:maintainer "Matthew L. Fidler") (:keywords "yasnippet" "textmate") (:url . "https://github.com/mlf176f2/textmate-to-yas.el/"))])
+ (textsize . [(20220427 1445) ((emacs (26 1))) "Configure frame text size automatically" single ((:commit . "df91392c3c928d7841631f5809716b9cf0f7309e") (:authors ("James Ferguson" . "james@faff.org")) (:maintainer "James Ferguson" . "james@faff.org") (:keywords "convenience") (:url . "https://github.com/WJCFerguson/textsize"))])
+ (textx-mode . [(20170516 911) ((emacs (24 3))) "Major mode for editing TextX files" single ((:commit . "72f9f0c5855b382024f0da8f56833c22a70a5cb3") (:authors ("Novak Boškov" . "gnovak.boskov@gmail.com")) (:maintainer "Novak Boškov" . "gnovak.boskov@gmail.com") (:keywords "textx") (:url . "https://github.com/novakboskov/textx-mode"))])
+ (tf2-conf-mode . [(20161209 1620) nil "TF2 Configuration files syntax highlighting" single ((:commit . "536950f64c071ffd8495fb2c7ac7c63a11e25f93") (:authors ("Guillermo Robles" . "guillerobles1995@gmail.com")) (:maintainer "Guillermo Robles" . "guillerobles1995@gmail.com") (:keywords "languages") (:url . "https://github.com/wynro/emacs-tf2-conf-mode"))])
+ (tfsmacs . [(20180911 2114) ((emacs (25)) (tablist (0 70))) "MS TFS source control interaction." single ((:commit . "6865d7bf772a6ecabacc868e45a0f5a5e197e1a5") (:authors ("Dino Chiesa <dpchiesa@outlook.com>, Sebastian Monia" . "smonia@outlook.com")) (:maintainer "Dino Chiesa <dpchiesa@outlook.com>, Sebastian Monia" . "smonia@outlook.com") (:keywords "tfs" "vc") (:url . "http://github.com/sebasmonia/tfsmacs/"))])
+ (the-matrix-theme . [(20220503 1325) ((emacs (26 1))) "Green-on-black dark theme inspired by \"The Matrix\" movie" single ((:commit . "f2f69c3aa9c76dc3c27e9bf3c965e66f8b7f61cc") (:authors ("Dan Dee" . "monkeyjunglejuice@pm.me")) (:maintainer "Dan Dee" . "monkeyjunglejuice@pm.me") (:keywords "faces" "theme") (:url . "https://github.com/monkeyjunglejuice/matrix-emacs-theme"))])
+ (theme-anchor . [(20220204 321) ((emacs (26))) "Apply theme in current buffer only" single ((:commit . "c6f715d4ccd30e83922e39cab856578ce19224bb") (:authors ("Liāu, Kiong-Gē" . "gliao.tw@pm.me")) (:maintainer "Liāu, Kiong-Gē" . "gliao.tw@pm.me") (:keywords "extensions" "lisp" "theme") (:url . "https://github.com/GongYiLiao/theme-anchor"))])
+ (theme-changer . [(20201226 2256) nil "Sunrise/Sunset Theme Changer for Emacs" single ((:commit . "57b8c579f134374a45bec9043feff6b29bb4f108") (:authors ("Joshua B. Griffith" . "josh.griffith@gmail.com")) (:maintainer "Joshua B. Griffith" . "josh.griffith@gmail.com") (:keywords "color-theme" "deftheme" "solar" "sunrise" "sunset") (:url . "https://github.com/hadronzoo/theme-changer"))])
+ (theme-looper . [(20210827 424) ((emacs (24)) (cl-lib (0 5))) "A package for switching themes in Emacs interactively" single ((:commit . "e6e8efd740df0b68db89805ba72492818dba61ab") (:authors ("Mohammed Ismail Ansari" . "team.terminal@gmail.com")) (:maintainer "Mohammed Ismail Ansari" . "team.terminal@gmail.com") (:keywords "convenience" "color-themes") (:url . "http://ismail.teamfluxion.com"))])
+ (theme-magic . [(20190711 2034) ((emacs (25)) (seq (1 8))) "Apply your Emacs theme to the rest of Linux" tar ((:commit . "844c4311bd26ebafd4b6a1d72ddcc65d87f074e3") (:authors ("GitHub user \"jcaw\"" . "40725916+jcaw@users.noreply.github.com")) (:maintainer "GitHub user \"jcaw\"" . "40725916+jcaw@users.noreply.github.com") (:keywords "unix" "faces" "terminals" "extensions") (:url . "https://github.com/jcaw/theme-magic.el"))])
+ (therapy . [(20151113 1953) ((emacs (24))) "Hooks for managing multiple Python major versions" single ((:commit . "775a92bb7b6b0fcc5b38c0b5198a9d0a1bef788a") (:authors ("Austin Bingham" . "austin.bingham@gmail.com")) (:maintainer "Austin Bingham" . "austin.bingham@gmail.com") (:url . "https://github.com/abingham/therapy"))])
+ (thingopt . [(20160520 2318) nil "Thing at Point optional utilities" single ((:commit . "5679815852652479f3b3c9f3a98affc927384b2c") (:authors ("Tomohiro Matsuyama" . "m2ym.pub@gmail.com")) (:maintainer "Tomohiro Matsuyama" . "m2ym.pub@gmail.com") (:keywords "convenience"))])
+ (thinks . [(20170802 1128) ((cl-lib (0 5))) "Insert text in a think bubble." single ((:commit . "c02f236abc8c2025d9f01460b09b89ebdc96e28d") (:authors ("Dave Pearson" . "davep@davep.org")) (:maintainer "Dave Pearson" . "davep@davep.org") (:keywords "convenience" "quoting") (:url . "https://github.com/davep/thinks.el"))])
+ (thread-dump . [(20170816 1850) nil "Java thread dump viewer" single ((:commit . "204c9600242756d4b514bb5ff6293e052bf4b49d") (:authors ("Dmitry Neverov")) (:maintainer "Dmitry Neverov") (:url . "http://github.com/nd/thread-dump.el"))])
+ (threes . [(20160820 1242) ((emacs (24)) (seq (1 11))) "A clone of Threes (a tiny puzzle game)" single ((:commit . "6981acb30b856c77cba6aba63fefbf102cbdfbb2") (:authors ("Chunyang Xu" . "xuchunyang.me@gmail.com")) (:maintainer "Chunyang Xu" . "xuchunyang.me@gmail.com") (:keywords "games") (:url . "https://github.com/xuchunyang/threes.el"))])
+ (thrift . [(20200212 1903) ((emacs (24))) "major mode for fbthrift and Apache Thrift files" single ((:commit . "49c95dae7f759f72328b932a256b3621ce20e2c8") (:keywords "languages"))])
+ (thumb-through . [(20120119 534) nil "Plain text reader of HTML documents" single ((:commit . "08d8fb720f93c6172653e035191a8fa9c3305e63") (:keywords "html"))])
+ (tickscript-mode . [(20171219 203) ((emacs (24 1))) "A major mode for Tickscript files" single ((:commit . "f0579f38ff14954df5002ce30ae6d4a2c978d461") (:authors ("Marc Sherry" . "msherry@gmail.com")) (:maintainer "Marc Sherry" . "msherry@gmail.com") (:keywords "languages") (:url . "https://github.com/msherry/tickscript-mode"))])
+ (tidal . [(20210211 1531) ((haskell-mode (16)) (emacs (24))) "Interact with TidalCycles for live coding patterns" single ((:commit . "39389e4080144c6734dbe3020cc35185f025ebf0") (:authors (nil . "alex@slab.org")) (:maintainer nil . "alex@slab.org") (:keywords "tools") (:url . "https://github.com/tidalcycles/Tidal"))])
+ (tide . [(20220429 1501) ((emacs (25 1)) (dash (2 10 0)) (s (1 11 0)) (flycheck (27)) (typescript-mode (0 1)) (cl-lib (0 5))) "Typescript Interactive Development Environment" tar ((:commit . "83c34c636f47cb0c10c7d1a728fa308bfec40890") (:authors ("Anantha kumaran" . "ananthakumaran@gmail.com")) (:maintainer "Anantha kumaran" . "ananthakumaran@gmail.com") (:keywords "typescript") (:url . "http://github.com/ananthakumaran/tide"))])
+ (tikz . [(20210927 1704) ((emacs (24 1))) "A minor mode to edit TikZ pictures" tar ((:commit . "f9ea0793affa34be29e1861bfa559fd248b7d22e") (:authors ("Emilio Torres-Manzanera" . "torres@uniovi.es")) (:maintainer "Emilio Torres-Manzanera" . "torres@uniovi.es") (:keywords "tex") (:url . "https://github.com/emiliotorres/tikz"))])
+ (tile . [(20161225 357) ((emacs (25 1)) (s (1 9 0)) (dash (2 12 0)) (stream (2 2 3))) "Tile windows with layouts" single ((:commit . "22660f21f6e95de5aba55cd5d293d4841e9a4661") (:authors ("Ivan Malison" . "IvanMalison@gmail.com")) (:maintainer "Ivan Malison" . "IvanMalison@gmail.com") (:keywords "tile" "tiling" "window" "manager" "dynamic" "frames") (:url . "https://github.com/IvanMalison/tile"))])
+ (time-ext . [(20170126 1215) nil "more function for time/date" single ((:commit . "d128becf660fe3f30178eb1b05cd266741f4784a") (:authors ("rubikitch" . "rubikitch@ruby-lang.org")) (:maintainer "rubikitch" . "rubikitch@ruby-lang.org") (:keywords "lisp") (:url . "http://www.emacswiki.org/cgi-bin/wiki/download/time-ext.el"))])
+ (timecop . [(20160520 1052) ((cl-lib (0 5)) (datetime-format (0 0 1))) "Freeze Time for testing" single ((:commit . "e6427538b547cbe02e1bd6ed4b765c73620bdae8") (:authors ("USAMI Kenta" . "tadsan@zonu.me")) (:maintainer "USAMI Kenta" . "tadsan@zonu.me") (:keywords "datetime" "testing") (:url . "https://github.com/zonuexe/emacs-datetime"))])
+ (timer-revert . [(20150122 2032) nil "minor mode to revert buffer for a given time interval." tar ((:commit . "615c91dec8b440d2b9b7c725dd733d7432564e45") (:authors ("Yagnesh Raghava Yakkala. http://yagnesh.org")) (:maintainer nil . "hi@yagnesh.org") (:keywords "timer" "revert" "auto-revert.") (:url . "http://github.com/yyr/timer-revert"))])
+ (timesheet . [(20191024 151) ((s (1)) (org (7)) (auctex (11))) "Timesheet management add-on for org-mode" tar ((:commit . "5098dc87d3d4f289b6c1b6532070dacbfe6de9fd") (:authors ("Tom Marble")) (:maintainer "Tom Marble") (:keywords "org" "timesheet") (:url . "https://github.com/tmarble/timesheet.el"))])
+ (timonier . [(20170411 800) ((emacs (24 4)) (s (1 11 0)) (f (0 19 0)) (dash (2 12 0)) (pkg-info (0 5 0)) (hydra (0 13 6)) (request (0 2 0)) (all-the-icons (2 0 0))) "Manage Kubernetes Applications" tar ((:commit . "0a150ea87bf695b43cf1740dfd7e553e0ae7601c") (:authors ("Nicolas Lamirault" . "nicolas.lamirault@gmail.com")) (:maintainer "Nicolas Lamirault" . "nicolas.lamirault@gmail.com") (:keywords "kubernetes" "docker") (:url . "https://github.com/nlamirault/timonier"))])
+ (timp . [(20160618 803) ((emacs (24 4)) (cl-lib (0 5)) (fifo-class (1 0)) (signal (1 0))) "Multithreading library" tar ((:commit . "66b21934b1eb8ee428c06dd64b3562ad44776a35") (:authors ("Mola-T" . "Mola@molamola.xyz")) (:maintainer "Mola-T" . "Mola@molamola.xyz") (:keywords "internal" "lisp" "processes" "tools") (:url . "https://github.com/mola-T/timp"))])
+ (timu-spacegrey-theme . [(20220501 1509) ((emacs (25 1))) "Color theme inspired by the Spacegray theme in Sublime Text" single ((:commit . "1318c58a118c6c5a95a82e71da5eda6bfcf8f143") (:authors ("Aimé Bertrand" . "aime.bertrand@macowners.club")) (:maintainer "Aimé Bertrand" . "aime.bertrand@macowners.club") (:keywords "faces" "themes") (:url . "https://gitlab.com/aimebertrand/timu-spacegrey-theme"))])
+ (tinkerer . [(20200914 1756) ((s (1 2 0))) "Elisp wrapper for Tinkerer Blogging Engine." single ((:commit . "7cedeb264a44cd62bcd9c778dca52316d09e07e5") (:authors ("Yagnesh Raghava Yakkala" . "hi@yagnesh.org")) (:maintainer "Yagnesh Raghava Yakkala" . "hi@yagnesh.org") (:keywords "tinkerer" "blog" "wrapper") (:url . "https://github.com/yyr/tinkerer.el"))])
+ (tiny . [(20190722 1212) nil "Quickly generate linear ranges in Emacs" single ((:commit . "fd8a6b0b0c564d8242259e20e557ee6041f40908") (:authors ("Oleh Krehel" . "ohwoeowho@gmail.com")) (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com") (:keywords "convenience") (:url . "https://github.com/abo-abo/tiny"))])
+ (tiny-menu . [(20161213 1235) ((emacs (24 4))) "Display tiny menus." single ((:commit . "05563b94537b6eb22aeddedef2a6e59e3f88d073") (:authors ("Aaron Bieber" . "aaron@aaronbieber.com")) (:maintainer "Aaron Bieber" . "aaron@aaronbieber.com") (:keywords "menu" "tools") (:url . "https://github.com/aaronbieber/tiny-menu.el"))])
+ (tinypng . [(20200306 911) ((emacs (25 1))) "Compress PNG and JPEG with TinyPNG.com API" single ((:commit . "f7632e073ce13ef5ce30ae5584cb482a8bb9ffff") (:authors ("Xu Chunyang" . "mail@xuchunyang.me")) (:maintainer "Xu Chunyang" . "mail@xuchunyang.me") (:keywords "multimedia") (:url . "https://github.com/xuchunyang/tinypng.el"))])
+ (tinysegmenter . [(20141124 1013) ((cl-lib (0 5))) "Super compact Japanese tokenizer in Javascript ported to emacs lisp" single ((:commit . "872134704bd25c13a4c59552433da4c6881b5230") (:authors ("lugecy" . "lugecy@gmail.com")) (:maintainer "myuhe") (:keywords "convenience") (:url . "https://github.com/myuhe/tinysegmenter.el"))])
+ (titlecase . [(20220503 1344) ((emacs (25 1))) "Title-case phrases" tar ((:commit . "dafaa6ca09fdf1ae8413159cae2b5d74e9713440") (:authors ("Case Duckworth" . "acdw@acdw.net")) (:maintainer "Case Duckworth" . "acdw@acdw.net") (:url . "https://github.com/duckwork/titlecase.el"))])
+ (tj3-mode . [(20180519 1228) nil "major mode for editing TaskJuggler 3 files" single ((:commit . "1d98eb23f1606392f34ef1b80517cfc940fb9950") (:authors ("Christophe Rhodes" . "christophe@rhodes.io")) (:maintainer "Christophe Rhodes" . "christophe@rhodes.io") (:url . "https://github.com/csrhodes/tj3-mode"))])
+ (tldr . [(20210921 1715) ((emacs (24 3))) "tldr client for Emacs" single ((:commit . "d3fd2a809a266c005915026799121c78e8b358f0") (:authors ("Ono Hiroko" . "azazabc123@gmail.com")) (:maintainer "Ono Hiroko" . "azazabc123@gmail.com") (:keywords "tools" "docs") (:url . "https://github.com/kuanyui/tldr.el"))])
+ (tmmofl . [(20121025 1101) nil "Calls functions dependant on font lock highlighting at point" single ((:commit . "532aa6978e994e2b069ffe37aaf9a0011a07dadc") (:authors ("Phillip Lord" . "p.lord@hgmp.mrc.ac.uk")) (:maintainer "Phillip Lord" . "p.lord@hgmp.mrc.ac.uk") (:keywords "minor mode" "font lock" "toggling."))])
+ (tmux-pane . [(20200730 520) ((names (0 5)) (emacs (24)) (s (0))) "Provide integration between emacs window and tmux pane" single ((:commit . "92f67c6d270c7c923edcde81a235ed0b49a61a70") (:keywords "convenience" "terminals" "tmux" "window" "pane" "navigation" "integration") (:url . "https://github.com/laishulu/emacs-tmux-pane"))])
+ (toc-mode . [(20211229 1334) ((emacs (26 1))) "Manage outlines/table of contents of pdf and djvu documents" single ((:commit . "4c9ce0f54d1e3e0c7c75c7f3c2d9a4d50287ca18") (:authors ("Daniel Laurens Nicolai" . "dalanicolai@gmail.com")) (:maintainer "Daniel Laurens Nicolai" . "dalanicolai@gmail.com") (:keywords "tools" "outlines" "convenience") (:url . "https://github.com/dalanicolai/toc-mode"))])
+ (toc-org . [(20220110 1452) nil "add table of contents to org-mode files (formerly, org-toc)" single ((:commit . "bf2e4b358efbd860ecafe6e74776de0885d9d100") (:authors ("Sergei Nosov <sergei.nosov [at] gmail.com>")) (:maintainer "Sergei Nosov <sergei.nosov [at] gmail.com>") (:keywords "org-mode" "org-toc" "toc-org" "org" "toc" "table" "of" "contents") (:url . "https://github.com/snosov1/toc-org"))])
+ (todoist . [(20220412 2337) ((dash (2 15 0)) (transient (0 1 0)) (org (8 3 5)) (emacs (25 3))) "Extension for interacting and managing todoist tasks" single ((:commit . "f6906be346073f082a6d1f9ae14932ec2bfd99f5") (:authors ("Adrien Brochard")) (:maintainer "Adrien Brochard") (:keywords "todoist" "task" "todo" "comm") (:url . "https://github.com/abrochard/emacs-todoist"))])
+ (todotxt . [(20220204 1903) nil "A major mode for editing todo.txt files" single ((:commit . "ddb25fb931b4bbc1af14c4c712d412af454794c4") (:authors ("Rick Dillon" . "rpdillon@killring.org")) (:maintainer "Rick Dillon" . "rpdillon@killring.org") (:keywords "todo.txt" "todotxt" "todotxt.el") (:url . "https://github.com/rpdillon/todotxt.el"))])
+ (todotxt-mode . [(20200228 952) nil "Major mode for editing todo.txt files" single ((:commit . "8b616ce1cf3e18a60757450a0acf22996abb9b79") (:authors ("Adolfo Villafiorita" . "adolfo.villafiorita@me.com")) (:maintainer "Adolfo Villafiorita" . "adolfo.villafiorita@me.com") (:keywords "wp" "files"))])
+ (togetherly . [(20170426 616) ((cl-lib (0 3))) "allow multiple clients to edit a single buffer online" single ((:commit . "a6491bd5dd84f2aded0cd112ff06ae76ff78dfeb") (:authors ("zk_phi")) (:maintainer "zk_phi") (:url . "http://hins11.yu-yake.com/"))])
+ (toggle . [(20180316 3) ((cl-lib (0 5))) "quickly open corresponding file (eg test vs impl)." single ((:commit . "09166f32d3ece2b297da036f0abbeba63329580e") (:authors ("Ryan Davis" . "ryand-ruby@zenspider.com")) (:maintainer "Ryan Davis" . "ryand-ruby@zenspider.com") (:keywords "files" "extensions" "convenience"))])
+ (toggle-quotes . [(20140710 926) nil "Toggle between single and double quoted string" single ((:commit . "33abc221d6887f0518337851318065cd86c34b03") (:authors ("Jim Tian" . "tianjin.sc@gmail.com")) (:maintainer "Jim Tian" . "tianjin.sc@gmail.com") (:keywords "convenience" "quotes") (:url . "https://github.com/toctan/toggle-quotes.el"))])
+ (toggle-test . [(20140723 537) nil "Toggle between source and test files in various programming languages" single ((:commit . "e969321f274903d705995a7d0345a257576ec5ff") (:authors ("Raghunandan Rao" . "r.raghunandan@gmail.com")) (:maintainer "Raghunandan Rao" . "r.raghunandan@gmail.com") (:keywords "tdd" "test" "toggle" "productivity") (:url . "https://github.com/rags/toggle-test"))])
+ (toggle-window . [(20141207 1548) nil "toggle current window size between half and full" single ((:commit . "e82c60e543933880402ede11e9423e48a17dde53") (:authors ("Kenny Liu")) (:maintainer "Kenny Liu") (:keywords "hide" "window") (:url . "https://github.com/deadghost/toggle-window"))])
+ (tok-theme . [(20220505 1155) ((emacs (26 1))) "Minimal theme with dark and yellow color scheme" single ((:commit . "118565dab2d3cf1b083d666bc19ed1b063035732") (:authors ("Topi Kettunen" . "topi@topikettunen.com")) (:maintainer "Topi Kettunen" . "topi@topikettunen.com") (:url . "https://github.com/topikettunen/tok-theme"))])
+ (tokei . [(20220422 2234) ((emacs (27 1)) (magit-section (3 3 0))) "Display codebase statistics" single ((:commit . "181021cd881eecd604a546d4a717866a81c7a511") (:authors ("Daniel Nagy <https://github.com/nagy>")) (:maintainer "Daniel Nagy" . "danielnagy@posteo.de") (:url . "https://github.com/nagy/tokei.el"))])
+ (tomatinho . [(20180621 1748) nil "Simple and beautiful pomodoro timer" tar ((:commit . "b53354b9b9f496c0388d6a573b06b7d6fc53d0bd") (:authors ("Konrad Scorciapino" . "scorciapino@gmail.com")) (:maintainer "Konrad Scorciapino" . "scorciapino@gmail.com") (:keywords "time" "productivity" "pomodoro technique"))])
+ (toml . [(20130903 1255) nil "TOML (Tom's Obvious, Minimal Language) parser" single ((:commit . "994644f9e68c383071eeee23389a7989b228c2d2") (:authors ("Wataru MIYAGUNI" . "gonngo@gmail.com")) (:maintainer "Wataru MIYAGUNI" . "gonngo@gmail.com") (:keywords "toml" "parser") (:url . "https://github.com/gongo/emacs-toml"))])
+ (toml-mode . [(20161107 1800) ((emacs (24)) (cl-lib (0 5))) "Major mode for editing TOML files" single ((:commit . "f6c61817b00f9c4a3cab1bae9c309e0fc45cdd06") (:authors ("Felix Chern" . "idryman@gmail.com")) (:maintainer "Felix Chern" . "idryman@gmail.com") (:keywords "data" "toml") (:url . "https://github.com/dryman/toml-mode.el"))])
+ (tommyh-theme . [(20131004 2330) nil "A bright, bold-colored theme for emacs" single ((:commit . "46d1c69ee0a1ca7c67b569b891a2f28fed89e7d5") (:authors ("William Glass" . "william.glass@gmail.com")) (:maintainer "William Glass" . "william.glass@gmail.com"))])
+ (tongbu . [(20200414 507) ((emacs (25 1)) (web-server (0 1 2))) "A web server to share text or files between two devices" single ((:commit . "6f6e5c5446f0c5735357ab520b249ab97295653e") (:authors ("Xu Chunyang")) (:maintainer "Xu Chunyang") (:keywords "tools") (:url . "https://github.com/xuchunyang/tongbu.el"))])
+ (topspace . [(20220504 2220) ((emacs (25 1))) "Scroll down & recenter top lines / get upper margins/padding" single ((:commit . "cbd1f7e8dad4284455488f759946d2f38deff2c6") (:authors ("Trevor Edwin Pogue" . "trevor.pogue@gmail.com")) (:maintainer "Trevor Edwin Pogue" . "trevor.pogue@gmail.com") (:keywords "convenience" "scrolling" "center" "cursor" "margin" "padding") (:url . "https://github.com/trevorpogue/topspace"))])
+ (topsy . [(20210831 133) ((emacs (26 3))) "Simple sticky header" single ((:commit . "8ae0976dfdbe4461c33ed44cf1dedc2c903b0bb0") (:authors ("Adam Porter" . "adam@alphapapa.net")) (:maintainer "Adam Porter" . "adam@alphapapa.net") (:keywords "convenience") (:url . "https://github.com/alphapapa/topsy.el"))])
+ (tornado-template-mode . [(20141128 1008) nil "A major mode for editing tornado templates" single ((:commit . "667c0663dbbd279b6c345446b9f2bc50eb52b747") (:authors ("Florian Mounier aka paradoxxxzero")) (:maintainer "Florian Mounier aka paradoxxxzero"))])
+ (torus . [(20190325 753) ((emacs (26))) "A buffer groups manager" single ((:commit . "b309da8c2eaee573a2e2572f25a08ce5da9e9990") (:authors ("Chimay")) (:maintainer "Chimay") (:keywords "files" "buffers" "groups" "persistent" "history" "layout" "tabs") (:url . "https://github.com/chimay/torus"))])
+ (total-lines . [(20171227 1239) ((emacs (24 3))) "Keep track of a buffer's total number of lines" single ((:commit . "473fa74a5416697ecd938866518bcad423f8fda6") (:authors ("Hinrik Örn Sigurðsson")) (:maintainer "Hinrik Örn Sigurðsson") (:keywords "convenience" "mode-line") (:url . "https://github.com/hinrik/total-lines"))])
+ (totd . [(20150519 1440) ((s (1 9 0)) (cl-lib (0 5))) "Display a random daily emacs command." single ((:commit . "ca47b618ea8290776cdb5b0f1c2c335691f69660") (:authors ("Erik Hetzner" . "egh@e6h.org")) (:maintainer "Erik Hetzner" . "egh@e6h.org") (:keywords "help"))])
+ (totp . [(20211018 1743) ((emacs (27 1))) "Time-based One-time Password (TOTP)" tar ((:commit . "680b2c969823b91e0b35afbe2a35a610cb2fa26a") (:authors ("Jürgen Hötzel" . "juergen@hoetzel.info")) (:maintainer "Jürgen Hötzel" . "juergen@hoetzel.info") (:keywords "tools" "pass" "password") (:url . "https://github.com/juergenhoetzel/emacs-totp"))])
+ (tox . [(20160810 1555) nil "Launch current python test with tox" single ((:commit . "7655eb254038d5e34433e8a9d66b3ffc9c72e40c") (:authors ("Chmouel Boudjnah" . "chmouel@chmouel.com")) (:maintainer "Chmouel Boudjnah" . "chmouel@chmouel.com") (:keywords "convenience" "tox" "python" "tests") (:url . "https://github.com/chmouel/tox.el"))])
+ (toxi-theme . [(20160424 2126) ((emacs (24))) "A dark color theme by toxi" single ((:commit . "90c8828b91025adf5adc96011a35d25682991b8a") (:authors ("Karsten Schmidt" . "info@postspectacular.com")) (:maintainer "Karsten Schmidt" . "info@postspectacular.com") (:url . "http://bitbucket.org/postspectacular/toxi-theme/"))])
+ (tql-mode . [(20170724 254) ((emacs (24))) "TQL mode" single ((:commit . "488add79eb3fc8ec02aedaa997fe1ed9e5c3e638") (:authors ("Sean McLaughlin" . "seanmcl@gmail.com")) (:maintainer "Sean McLaughlin" . "seanmcl@gmail.com") (:keywords "languages" "tql"))])
+ (tr-ime . [(20211120 718) ((emacs (27 1)) (w32-ime (0 0 1))) "Emulator of IME patch for Windows" tar ((:commit . "e6313639afb51d91efcc417bd0c81afd13bb079c") (:authors ("Masamichi Hosoda" . "trueroad@trueroad.jp")) (:maintainer "Masamichi Hosoda" . "trueroad@trueroad.jp") (:url . "https://github.com/trueroad/tr-emacs-ime-module"))])
+ (traad . [(20180730 48) ((dash (2 13 0)) (deferred (0 3 2)) (popup (0 5 0)) (request (0 2 0)) (request-deferred (0 2 0)) (virtualenvwrapper (20151123)) (f (0 20 0)) (bind-map (1 1 1))) "emacs interface to the traad refactoring server." single ((:commit . "98e23363b7e8a590a2f55976123a8c3da75c87a5") (:authors ("Austin Bingham" . "austin.bingham@gmail.com")) (:maintainer "Austin Bingham" . "austin.bingham@gmail.com") (:url . "https://github.com/abingham/traad"))])
+ (tracking . [(20210713 1609) nil "Buffer modification tracking" tar ((:commit . "710f057fedae6e9b820cce9336fef24b7d057e4c") (:authors ("Jorgen Schaefer" . "forcer@forcix.cx")) (:maintainer "Jorgen Schaefer" . "forcer@forcix.cx") (:url . "https://github.com/emacs-circe/circe/wiki/Tracking"))])
+ (tracwiki-mode . [(20150119 1621) ((xml-rpc (1 6 8))) "Emacs Major mode for working with Trac" single ((:commit . "6a620444d59b438f42383b48cd4c19c03105dba6") (:authors ("Matthew Erickson" . "peawee@peawee.net")) (:maintainer "Matthew Erickson" . "peawee@peawee.net") (:keywords "trac" "wiki" "tickets"))])
+ (tramp-auto-auth . [(20191027 1419) ((emacs (24 4)) (tramp (0 0))) "TRAMP automatic authentication library" single ((:commit . "f15a12dfab651aff60f4a9d70f868030a12344ac") (:authors ("Bruno Félix Rezende Ribeiro" . "oitofelix@gnu.org")) (:maintainer "Bruno Félix Rezende Ribeiro" . "oitofelix@gnu.org") (:keywords "comm" "processes") (:url . "https://github.com/oitofelix/tramp-auto-auth"))])
+ (tramp-hdfs . [(20210526 339) ((emacs (24 4))) "Tramp extension to access hadoop/hdfs file system in Emacs" single ((:commit . "aa93bdbb3d5619c262ce53af1981edcd2a0705e5") (:authors ("Raghav Kumar Gautam" . "raghav@apache.org")) (:maintainer "Raghav Kumar Gautam" . "raghav@apache.org") (:keywords "tramp" "emacs" "hdfs" "hadoop" "webhdfs" "rest"))])
+ (tramp-term . [(20220412 1546) nil "Automatic setup of directory tracking in ssh sessions" single ((:commit . "e2e5375a444d4eb5d144bef12e066c02befd1352") (:authors ("Randy Morris" . "randy.morris@archlinux.us")) (:maintainer "Randy Morris" . "randy.morris@archlinux.us") (:keywords "comm" "terminals") (:url . "https://github.com/randymorris/tramp-term.el"))])
+ (transfer-sh . [(20200601 1708) ((emacs (24 3)) (async (1 0))) "Simple interface for sending buffer contents to transfer.sh" single ((:commit . "0621a66d00ec91a209a542c10b158095088bd44d") (:keywords "comm" "convenience" "files") (:url . "https://gitlab.com/tuedachu/transfer-sh.el"))])
+ (transient . [(20220503 1118) ((emacs (25 1)) (compat (28 1 1 0))) "Transient commands" tar ((:commit . "8c62d0d223e90f53b29c439ba2f86b6e721d8209") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:keywords "extensions") (:url . "https://github.com/magit/transient"))])
+ (transient-dwim . [(20220425 1331) ((emacs (26 1)) (transient (0 1))) "Useful preset transient commands" single ((:commit . "7b6e70fb49b9d18106748202011863ebc39b864a") (:authors ("Naoya Yamashita" . "conao3@gmail.com")) (:maintainer "Naoya Yamashita" . "conao3@gmail.com") (:keywords "tools") (:url . "https://github.com/conao3/transient-dwim.el"))])
+ (transient-posframe . [(20210102 130) ((emacs (26 0)) (posframe (0 4 3)) (transient (0 2 0))) "Using posframe to show transient" single ((:commit . "dcd898d1d35183a7d4f2c8f0ebcb43b4f8e70ebe") (:authors ("Yanghao Xie")) (:maintainer "Yanghao Xie" . "yhaoxie@gmail.com") (:keywords "convenience" "bindings" "tooltip") (:url . "https://github.com/yanghaoxie/transient-posframe"))])
+ (translate-mode . [(20220402 853) ((emacs (24 3))) "Paragraph-oriented side-by-side doc translation workflow" single ((:commit . "fb73b3d928a8011a21402e2c14aa4aab56bd05ae") (:authors ("Ray Wang" . "rayw.public@gmail.com")) (:maintainer "Ray Wang" . "rayw.public@gmail.com") (:keywords "translate" "convenience" "editing") (:url . "https://github.com/rayw000/translate-mode"))])
+ (transmission . [(20210705 2152) ((emacs (24 4)) (let-alist (1 0 5))) "Interface to a Transmission session" single ((:commit . "a03a6f5c7b133e0a37896b6d993dd6d6d4532cc2") (:authors ("Mark Oteiza" . "mvoteiza@udel.edu")) (:maintainer "Mark Oteiza" . "mvoteiza@udel.edu") (:keywords "comm" "tools"))])
+ (transpose-frame . [(20200307 2119) nil "Transpose windows arrangement in a frame" single ((:commit . "12e523d70ff78cc8868097b56120848befab5dbc") (:authors ("S. Irie")) (:maintainer "S. Irie") (:keywords "window"))])
+ (transpose-mark . [(20150405 716) nil "Transpose data using the Emacs mark" single ((:commit . "667327602004794de97214cf336ac61650ef75b7") (:authors ("Kevin W. van Rooijen" . "kevin.van.rooijen@attichacker.com")) (:maintainer "Kevin W. van Rooijen" . "kevin.van.rooijen@attichacker.com") (:keywords "transpose" "convenience"))])
+ (transwin . [(20200910 1636) ((emacs (24 3))) "Make window/frame transparent" single ((:commit . "1e151e5fc841688f1c4d68e9acc0f7b410cd754c") (:authors ("Shen, Jen-Chieh" . "jcs090218@gmail.com")) (:maintainer "Shen, Jen-Chieh" . "jcs090218@gmail.com") (:url . "https://github.com/jcs-elpa/transwin"))])
+ (trashed . [(20220106 1358) ((emacs (25 1))) "Viewing/editing system trash can" single ((:commit . "ddf5830730544435a068f2dc9ac75a81ea69df1d") (:authors ("Shingo Tanaka" . "shingo.fg8@gmail.com")) (:maintainer "Shingo Tanaka" . "shingo.fg8@gmail.com") (:keywords "files" "convenience" "unix") (:url . "https://github.com/shingo256/trashed"))])
+ (travis . [(20150825 1138) ((s (1 9 0)) (dash (2 9 0)) (pkg-info (0 5 0)) (request (0 1 0))) "Emacs client for Travis" tar ((:commit . "754ef07c17fed17ab03664ad11e2b0b2ef5e78ed") (:authors ("Nicolas Lamirault" . "nicolas.lamirault@gmail.com")) (:maintainer "Nicolas Lamirault" . "nicolas.lamirault@gmail.com") (:keywords "travis") (:url . "https://github.com/nlamirault/emacs-travis"))])
+ (tray . [(20220422 1628) ((emacs (27 1)) (compat (28 1 1 0)) (transient (0 3 0))) "Various transient menus" single ((:commit . "7c70d499d08321337f860a3cd59cba7296cfcace") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:keywords "convenience") (:url . "https://git.sr.ht/~tarsius/tray"))])
+ (tree-edit . [(20220407 1629) ((emacs (27 1)) (tree-sitter (0 15 0)) (tsc (0 15 0)) (tree-sitter-langs (0 10 0)) (dash (2 19)) (reazon (0 4 0)) (s (0 0 0))) "A library for structural refactoring and editing" tar ((:commit . "eafee31ca4f532a9dbee326d3ec3bdd1e997223b") (:authors ("Ethan Leba" . "ethanleba5@gmail.com")) (:maintainer "Ethan Leba" . "ethanleba5@gmail.com") (:url . "https://github.com/ethan-leba/tree-edit"))])
+ (tree-mode . [(20151104 1331) nil "A mode to manage tree widgets" single ((:commit . "b06078826d5875d74b0e7b7ac47b0d0917610534") (:authors (nil . "wenbinye@163.com")) (:maintainer nil . "wenbinye@163.com") (:keywords "help" "convenience" "widget"))])
+ (tree-sitter . [(20220212 1632) ((emacs (25 1)) (tsc (0 18 0))) "Incremental parsing system" tar ((:commit . "3cfab8a0e945db9b3df84437f27945746a43cc71") (:authors ("Tuấn-Anh Nguyễn" . "ubolonton@gmail.com")) (:maintainer "Tuấn-Anh Nguyễn" . "ubolonton@gmail.com") (:keywords "languages" "tools" "parsers" "tree-sitter") (:url . "https://github.com/emacs-tree-sitter/elisp-tree-sitter"))])
+ (tree-sitter-indent . [(20220411 1439) ((emacs (26 1)) (tree-sitter (0 12 1)) (seq (2 20))) "Provide indentation with a Tree-sitter backend" single ((:commit . "4ef246db3e4ff99f672fe5e4b416c890f885c09e") (:authors ("Felipe Lema" . "felipelema@mortemale.org")) (:maintainer "Felipe Lema" . "felipelema@mortemale.org") (:keywords "convenience" "internal") (:url . "https://codeberg.org/FelipeLema/tree-sitter-indent.el"))])
+ (tree-sitter-langs . [(20220328 1344) ((emacs (25 1)) (tree-sitter (0 15 0))) "Grammar bundle for tree-sitter" tar ((:commit . "0dd5e56e2f5646aa51ed0fc9eb869a8f7090228a") (:authors ("Tuấn-Anh Nguyễn" . "ubolonton@gmail.com")) (:maintainer "Tuấn-Anh Nguyễn" . "ubolonton@gmail.com") (:keywords "languages" "tools" "parsers" "tree-sitter") (:url . "https://github.com/emacs-tree-sitter/tree-sitter-langs"))])
+ (treefactor . [(20200516 1631) ((emacs (26 1)) (dash (2 16 0)) (f (0 20 0)) (org (9 2 6)) (avy (0 5 0))) "Restructure your messy Org documents" single ((:commit . "75357757022a4399ab772ff0d92065bd114dabe9") (:authors ("Leo Littlebook" . "Leo.Littlebook@gmail.com")) (:maintainer "Leo Littlebook" . "Leo.Littlebook@gmail.com") (:keywords "outlines" "files" "convenience") (:url . "https://github.com/cyberthal/treefactor"))])
+ (treemacs . [(20220505 1120) ((emacs (26 1)) (cl-lib (0 5)) (dash (2 11 0)) (s (1 12 0)) (ace-window (0 9 0)) (pfuture (1 7)) (hydra (0 13 2)) (ht (2 2)) (cfrs (1 3 2))) "A tree style file explorer package" tar ((:commit . "eb6e530e856cccdaf34dc1ae8fc87090383c7f59") (:authors ("Alexander Miller" . "alexanderm@web.de")) (:maintainer "Alexander Miller" . "alexanderm@web.de") (:url . "https://github.com/Alexander-Miller/treemacs"))])
+ (treemacs-all-the-icons . [(20220425 1124) ((emacs (26 1)) (all-the-icons (4 0 1)) (treemacs (0 0))) "all-the-icons integration for treemacs" single ((:commit . "eb6e530e856cccdaf34dc1ae8fc87090383c7f59") (:authors ("Eric Dallo" . "ercdll1337@gmail.com")) (:maintainer "Eric Dallo" . "ercdll1337@gmail.com") (:url . "https://github.com/Alexander-Miller/treemacs"))])
+ (treemacs-evil . [(20220427 1331) ((emacs (26 1)) (evil (1 2 12)) (treemacs (0 0))) "Evil mode integration for treemacs" single ((:commit . "eb6e530e856cccdaf34dc1ae8fc87090383c7f59") (:authors ("Alexander Miller" . "alexanderm@web.de")) (:maintainer "Alexander Miller" . "alexanderm@web.de") (:url . "https://github.com/Alexander-Miller/treemacs"))])
+ (treemacs-icons-dired . [(20211229 1448) ((treemacs (0 0)) (emacs (26 1))) "Treemacs icons for dired" single ((:commit . "eb6e530e856cccdaf34dc1ae8fc87090383c7f59") (:authors ("Alexander Miller" . "alexanderm@web.de")) (:maintainer "Alexander Miller" . "alexanderm@web.de") (:url . "https://github.com/Alexander-Miller/treemacs"))])
+ (treemacs-magit . [(20220502 1310) ((emacs (26 1)) (treemacs (0 0)) (pfuture (1 3)) (magit (2 90 0))) "Magit integration for treemacs" single ((:commit . "eb6e530e856cccdaf34dc1ae8fc87090383c7f59") (:authors ("Alexander Miller" . "alexanderm@web.de")) (:maintainer "Alexander Miller" . "alexanderm@web.de") (:url . "https://github.com/Alexander-Miller/treemacs"))])
+ (treemacs-persp . [(20220209 2117) ((emacs (26 1)) (treemacs (0 0)) (persp-mode (2 9 7)) (dash (2 11 0))) "Persp-mode integration for treemacs" single ((:commit . "eb6e530e856cccdaf34dc1ae8fc87090383c7f59") (:authors ("Alexander Miller" . "alexanderm@web.de")) (:maintainer "Alexander Miller" . "alexanderm@web.de") (:url . "https://github.com/Alexander-Miller/treemacs"))])
+ (treemacs-perspective . [(20220209 2117) ((emacs (26 1)) (treemacs (0 0)) (perspective (2 8)) (dash (2 11 0))) "Perspective integration for treemacs" single ((:commit . "eb6e530e856cccdaf34dc1ae8fc87090383c7f59") (:authors ("Alexander Miller" . "alexanderm@web.de") ("Jason Dufair" . "jase@dufair.org")) (:maintainer "Alexander Miller" . "alexanderm@web.de") (:url . "https://github.com/Alexander-Miller/treemacs"))])
+ (treemacs-projectile . [(20211223 1454) ((emacs (26 1)) (projectile (0 14 0)) (treemacs (0 0))) "Projectile integration for treemacs" single ((:commit . "eb6e530e856cccdaf34dc1ae8fc87090383c7f59") (:authors ("Alexander Miller" . "alexanderm@web.de")) (:maintainer "Alexander Miller" . "alexanderm@web.de") (:url . "https://github.com/Alexander-Miller/treemacs"))])
+ (treemacs-tab-bar . [(20220221 2038) ((emacs (27 1)) (treemacs (0 0)) (dash (2 11 0))) "Tab bar integration for treemacs" single ((:commit . "eb6e530e856cccdaf34dc1ae8fc87090383c7f59") (:authors ("Alexander Miller" . "alexanderm@web.de") ("Jason Dufair" . "jase@dufair.org") ("Aaron Jensen" . "aaronjensen@gmail.com")) (:maintainer "Alexander Miller" . "alexanderm@web.de") (:url . "https://github.com/Alexander-Miller/treemacs"))])
+ (treepy . [(20191108 2217) ((emacs (25 1))) "Generic tree traversal tools" single ((:commit . "3ac940e97f3d03e48ca9d7fcd74916a9b01c72f3") (:authors ("Daniel Barreto" . "daniel.barreto.n@gmail.com")) (:maintainer "Daniel Barreto" . "daniel.barreto.n@gmail.com") (:keywords "lisp" "maint" "tools") (:url . "https://github.com/volrath/treepy.el"))])
+ (treeview . [(20210723 2256) ((emacs (24 4))) "A generic tree navigation library" single ((:commit . "09c8c1d045c7c8eace61b10b6df9d2f9079de78e") (:authors ("Tilman Rassy" . "tilman.rassy@googlemail.com")) (:maintainer "Tilman Rassy" . "tilman.rassy@googlemail.com") (:keywords "lisp" "tools" "internal" "convenience") (:url . "https://github.com/tilmanrassy/emacs-treeview"))])
+ (trident-mode . [(20190410 2036) ((emacs (24)) (slime (20130526)) (skewer-mode (1 5 0)) (dash (1 0 3))) "Live Parenscript interaction" single ((:commit . "109a1bc10bd0c4b47679a6ca5c4cd27c7c8d4ccb") (:authors ("John Mastro" . "john.b.mastro@gmail.com")) (:maintainer "John Mastro" . "john.b.mastro@gmail.com") (:keywords "languages" "lisp" "processes" "tools") (:url . "https://github.com/johnmastro/trident-mode.el"))])
+ (trinary . [(20180904 2313) ((emacs (24))) "Trinary logic." single ((:commit . "f7cbd4f9283dbb0528445a3ea6d3b291d97065f6") (:authors ("Matúš Goljer" . "matus.goljer@gmail.com")) (:maintainer "Matúš Goljer" . "matus.goljer@gmail.com") (:keywords "languages") (:url . "https://github.com/Fuco1/trinary-logic"))])
+ (tron-legacy-theme . [(20220312 1645) nil "An original retro-futuristic theme inspired by Tron: Legacy" single ((:commit . "d775d9f348a942230ea57b6520e1eb56a5d67569") (:authors ("Ian Y.E. Pan")) (:maintainer "Ian Y.E. Pan") (:url . "https://github.com/ianpan870102/tron-legacy-emacs-theme"))])
+ (trr . [(20191019 1403) nil "a type-writing training program on GNU Emacs." tar ((:commit . "f841173e11213ac6916b2d3394b28fb202543871") (:authors ("YAMAMOTO Hirotaka" . "ymmt@is.s.u-tokyo.ac.jp") ("KATO Kenji" . "kato@suri.co.jp") (" *Original Author") ("INAMURA You" . "inamura@icot.or.jp") (" *Original Author")) (:maintainer "YAMAMOTO Hirotaka" . "ymmt@is.s.u-tokyo.ac.jp") (:keywords "games" "faces"))])
+ (truthy . [(20140508 2041) ((list-utils (0 4 2))) "Test the content of a value" single ((:commit . "8ed8d07772aa8457554547eb17e264b5df2b4a69") (:authors ("Roland Walker" . "walker@pobox.com")) (:maintainer "Roland Walker" . "walker@pobox.com") (:keywords "extensions") (:url . "http://github.com/rolandwalker/truthy"))])
+ (try . [(20181204 236) ((emacs (24))) "Try out Emacs packages." single ((:commit . "8831ded1784df43a2bd56c25ad3d0650cdb9df1d") (:authors ("Lars Tveito" . "larstvei@ifi.uio.no")) (:maintainer "Lars Tveito" . "larstvei@ifi.uio.no") (:keywords "packages") (:url . "http://github.com/larstvei/try"))])
+ (ts . [(20210813 1617) ((emacs (26 1)) (dash (2 14 1)) (s (1 12 0))) "Timestamp and date/time library" single ((:commit . "3fee71ceefac71ba55eb34829d7e94bb3df37cee") (:authors ("Adam Porter" . "adam@alphapapa.net")) (:maintainer "Adam Porter" . "adam@alphapapa.net") (:keywords "calendar" "lisp") (:url . "http://github.com/alphapapa/ts.el"))])
+ (ts-comint . [(20181219 719) nil "Run a Typescript interpreter in an inferior process window." single ((:commit . "786b88fffc553e122868a1c4883f14136a040df6") (:authors ("Paul Huff" . "paul.huff@gmail.com")) (:maintainer "Paul Huff" . "paul.huff@gmail.com") (:keywords "typescript" "node" "inferior-mode" "convenience") (:url . "https://github.com/josteink/ts-comint"))])
+ (tsc . [(20220212 1632) ((emacs (25 1))) "Core Tree-sitter APIs" tar ((:commit . "3cfab8a0e945db9b3df84437f27945746a43cc71") (:authors ("Tuấn-Anh Nguyễn" . "ubolonton@gmail.com") ("Jorge Javier Araya Navarro" . "jorgejavieran@yahoo.com.mx")) (:maintainer "Tuấn-Anh Nguyễn" . "ubolonton@gmail.com") (:keywords "languages" "tools" "parsers" "dynamic-modules" "tree-sitter") (:url . "https://github.com/emacs-tree-sitter/elisp-tree-sitter"))])
+ (tss . [(20150913 1408) ((auto-complete (1 4 0)) (json-mode (1 1 0)) (log4e (0 2 0)) (yaxception (0 1))) "provide a interface for auto-complete.el/flymake.el on typescript-mode." tar ((:commit . "81ac6351a2ae258fd0ebf916dae9bd5a179fefd0") (:authors ("Hiroaki Otsu" . "ootsuhiroaki@gmail.com")) (:maintainer "Hiroaki Otsu" . "ootsuhiroaki@gmail.com") (:keywords "typescript" "completion") (:url . "https://github.com/aki2o/emacs-tss"))])
+ (tt-mode . [(20130804 1110) nil "Emacs major mode for editing Template Toolkit files." single ((:commit . "85ed3832e7eef391f7879d9990d59c7a3493c15e") (:authors ("Dave Cross" . "dave@dave.org.uk")) (:maintainer "Dave Cross" . "dave@dave.org.uk"))])
+ (tuareg . [(20220104 2039) ((emacs (24 4)) (caml (4 8))) "OCaml mode" tar ((:commit . "04f5ab6be9ae1c594bab359819dbaf708ae57fda") (:authors ("Albert Cohen" . "Albert.Cohen@inria.fr") ("Sam Steingold" . "sds@gnu.org") ("Christophe Troestler" . "Christophe.Troestler@umons.ac.be") ("Till Varoquaux" . "till@pps.jussieu.fr") ("Sean McLaughlin" . "seanmcl@gmail.com") ("Stefan Monnier" . "monnier@iro.umontreal.ca")) (:maintainer "Christophe Troestler" . "Christophe.Troestler@umons.ac.be") (:keywords "ocaml" "languages") (:url . "https://github.com/ocaml/tuareg"))])
+ (tubestatus . [(20220303 1736) ((emacs (26 1)) (request (0 3 2))) "Get the London Tube service status" single ((:commit . "c81373f1bc32cbd2e2d642ee10ee1cb31915acb0") (:authors ("Matthieu Petiteau" . "matt@smallwat3r.com")) (:maintainer "Matthieu Petiteau" . "matt@smallwat3r.com") (:url . "https://github.com/smallwat3r/tubestatus.el"))])
+ (tumble . [(20160112 729) ((http-post-simple (0)) (cl-lib (0 5))) "an Tumblr mode for Emacs" single ((:commit . "e8fd7643cccf2b6ea4170f0c5f1f87d007e7fa00") (:authors ("Federico Builes" . "federico.builes@gmail.com")) (:maintainer "Federico Builes" . "federico.builes@gmail.com") (:keywords "tumblr"))])
+ (tumblesocks . [(20191014 356) ((htmlize (1 39)) (oauth (1 0 3)) (markdown-mode (1 8 1))) "An Emacs tumblr client." tar ((:commit . "0e4c3847e31a59d405b9927107a23dde9531d744") (:authors ("gcr" . "gcr@sneakygcr.net")) (:maintainer "gcr" . "gcr@sneakygcr.net") (:url . "http://github.com/gcr/tumblesocks"))])
+ (turing-machine . [(20180222 438) ((emacs (24 4))) "Single-tape Turing machine simulator" single ((:commit . "fa60b76a5bac1f54b7a1b3dc55aae7602c7e385b") (:authors ("Diego A. Mundo" . "diegoamundo@gmail.com")) (:maintainer "Diego A. Mundo" . "diegoamundo@gmail.com") (:keywords "turing" "machine" "simulation") (:url . "http://github.com/therockmandolinist/turing-machine"))])
+ (turkish . [(20170910 1511) nil "Convert to Turkish characters on-the-fly" single ((:commit . "9831a316c176bb21a1b91226323ea4133163e00c") (:authors ("Deniz Yüret")) (:maintainer "Emre Sevinç" . "emre.sevinc@gmail.com") (:keywords "turkish" "languages" "automatic" "conversion") (:url . "http://www.denizyuret.com/2006/11/emacs-turkish-mode.html"))])
+ (turnip . [(20150309 629) ((dash (2 6 0)) (s (1 9 0))) "Interacting with tmux from Emacs" single ((:commit . "2fd32562fc6fc1cda6d91aa939cfb29f9b16e9de") (:authors ("Johann Klähn" . "kljohann@gmail.com")) (:maintainer "Johann Klähn" . "kljohann@gmail.com") (:keywords "terminals" "tools"))])
+ (twig-mode . [(20130220 1850) nil "A major mode for twig" single ((:commit . "2849f273a4855d3314a9c0cc84134f5b28ad5ea6") (:authors ("Bojan Matic aka moljac024")) (:maintainer "Bojan Matic aka moljac024"))])
+ (twilight-anti-bright-theme . [(20160622 848) nil "A soothing Emacs 24 light-on-dark theme" single ((:commit . "523b95fcdbf4a6a6483af314ad05354a3d80f23f") (:authors ("Jim Myhrberg" . "contact@jimeh.me")) (:maintainer "Jim Myhrberg" . "contact@jimeh.me") (:keywords "themes") (:url . "https://github.com/jimeh/twilight-anti-bright-theme.el"))])
+ (twilight-bright-theme . [(20130605 843) nil "A Emacs 24 faces port of the TextMate theme" single ((:commit . "322157cb2f3bf7920ecd209dafc31bc1c7959f49") (:authors ("Jim Myhrberg" . "contact@jimeh.me")) (:maintainer "Jim Myhrberg" . "contact@jimeh.me") (:keywords "themes") (:url . "https://github.com/jimeh/twilight-bright-theme.el"))])
+ (twilight-theme . [(20120412 1303) nil "Twilight theme for GNU Emacs 24 (deftheme)" single ((:commit . "77c4741cb3dcf16e53d06d6c2ffdc660c40afb5b") (:authors ("Nick Parker" . "nickp@developernotes.com")) (:maintainer "Nick Parker" . "nickp@developernotes.com"))])
+ (twitch-api . [(20220420 1547) ((emacs (27 1)) (dash (2 19 0))) "An elisp interface for the Twitch.tv API" single ((:commit . "181681097d1fc8d7b78928f8a5b38c61d0e20ef5") (:keywords "multimedia" "twitch-api") (:url . "https://github.com/BenediktBroich/twitch-api"))])
+ (twittering-mode . [(20181121 1402) nil "Major mode for Twitter" single ((:commit . "114891e8fdb4f06b1326a6cf795e49c205cf9e29") (:authors ("Tadashi MATSUO" . "tad@mymail.twin.ne.jp") ("Y. Hayamizu" . "y.hayamizu@gmail.com") ("Tsuyoshi CHO" . "Tsuyoshi.CHO+develop@Gmail.com") ("Alberto Garcia" . "agarcia@igalia.com") ("Xavier Maillard" . "xavier@maillard.im")) (:maintainer "Tadashi MATSUO" . "tad@mymail.twin.ne.jp") (:keywords "twitter" "web") (:url . "http://twmode.sf.net/"))])
+ (typescript-mode . [(20220223 1506) ((emacs (24 3))) "Major mode for editing typescript" tar ((:commit . "188350c222e68bb5c73a914738223a8c73299cfc") (:keywords "typescript" "languages") (:url . "http://github.com/ananthakumaran/typescript.el"))])
+ (typing . [(20180830 2203) nil "The Typing Of Emacs" single ((:commit . "a2ef25dde2d8eb91bd9c0c6164cb5208208647fa") (:authors ("Alex Schroeder" . "alex@gnu.org")) (:maintainer "Alex Schroeder" . "alex@gnu.org") (:keywords "games") (:url . "http://www.emacswiki.org/emacs/TypingOfEmacs"))])
+ (typing-game . [(20160426 1220) nil "a simple typing game" single ((:commit . "616435a5270274f4c7b698697674dbb2039049a4") (:authors ("DarkSun" . "lujun9972@gmail.com")) (:maintainer "DarkSun" . "lujun9972@gmail.com") (:keywords "lisp" "game"))])
+ (typit . [(20220106 1722) ((emacs (24 4)) (f (0 18)) (mmt (0 1 1))) "Typing game similar to tests on 10 fast fingers" tar ((:commit . "61dba759f8178550bc067a360c42ce1089e99a66") (:authors ("Mark Karpov" . "markkarpov92@gmail.com")) (:maintainer "Mark Karpov" . "markkarpov92@gmail.com") (:keywords "games") (:url . "https://github.com/mrkkrp/typit"))])
+ (typo . [(20200706 1714) nil "Minor mode for typographic editing" single ((:commit . "173ebe4fc7ac38f344b16e6eaf41f79e38f20d57") (:authors ("Jorgen Schaefer" . "forcer@forcix.cx")) (:maintainer "Jorgen Schaefer" . "forcer@forcix.cx") (:keywords "convenience" "wp") (:url . "https://github.com/jorgenschaefer/typoel"))])
+ (typo-suggest . [(20200830 1143) ((emacs (24 3)) (helm (3 0)) (company (0 9 10)) (s (1 12 0)) (dash (2 13 0))) "Don't make typos with the help of helm and company" single ((:commit . "3014d18ae2f0b6b857bb613f373e034c743f4d2e") (:authors ("Kadir Can Çetin" . "kadircancetin@gmail.com")) (:maintainer "Kadir Can Çetin" . "kadircancetin@gmail.com") (:keywords "convenience" "wp") (:url . "https://github.com/kadircancetin/typo-suggest"))])
+ (tzc . [(20220126 604) ((emacs (27 1))) "Converts time between different time zones" single ((:commit . "3af821d2125a67786f93d50d532a71f681f381cc") (:authors ("Md Arif Shaikh" . "arifshaikh.astro@gmail.com")) (:maintainer "Md Arif Shaikh" . "arifshaikh.astro@gmail.com") (:keywords "convenience") (:url . "https://github.com/md-arif-shaikh/tzc"))])
+ (ubuntu-theme . [(20150805 1506) nil "A theme inspired by the default terminal colors in Ubuntu" single ((:commit . "88b0eefc75d4cbcde103057e1c5968d4c3052f69") (:authors ("Francesc Rocher" . "francesc.rocher@gmail.com")) (:maintainer "Francesc Rocher" . "francesc.rocher@gmail.com") (:url . "http://github.com/rocher/ubuntu-theme"))])
+ (uci-mode . [(20210626 1956) ((emacs (25 1))) "Major-mode for chess engine interaction" single ((:commit . "2cdf4de5af96d56108a0a5716416ef3c8ac7bb7c") (:authors ("Dodge Coates and Roland Walker")) (:maintainer "Dodge Coates and Roland Walker") (:keywords "data" "games" "chess") (:url . "https://github.com/dwcoates/uci-mode"))])
+ (ucs-utils . [(20150826 1414) ((persistent-soft (0 8 8)) (pcache (0 2 3)) (list-utils (0 4 2))) "Utilities for Unicode characters" tar ((:commit . "cbfd42f822bf5717934fa2d92060e6e24a813433") (:authors ("Roland Walker" . "walker@pobox.com")) (:maintainer "Roland Walker" . "walker@pobox.com") (:keywords "i18n" "extensions") (:url . "http://github.com/rolandwalker/ucs-utils"))])
+ (udev-mode . [(20200702 1536) ((emacs (24))) "Major mode for editing udev rules files" single ((:commit . "5ca236980662141518603672ebdbdf863756da5a") (:authors ("Benjamin Staffin" . "benley@gmail.com")) (:maintainer "Benjamin Staffin" . "benley@gmail.com") (:keywords "languages" "unix") (:url . "https://github.com/benley/emacs-udev-mode"))])
+ (ue . [(20210929 1258) ((emacs (26 1)) (projectile (2 5 0))) "Minor mode for Unreal Engine projects" tar ((:commit . "7819d5b78e5b52a09b36c634ce404dc8bc3711ef") (:authors ("Oleksandr Manenko" . "seidfzehsd@use.startmail.com")) (:maintainer "Oleksandr Manenko" . "seidfzehsd@use.startmail.com") (:keywords "unreal engine" "languages" "tools") (:url . "https://gitlab.com/unrealemacs/ue.el"))])
+ (uimage . [(20160901 1221) nil "An iimage like mode with the ability to display url images" single ((:commit . "9893d09160ef7e8c0ecdcd74fca99ffeb5f9d70d") (:authors ("DarkSun" . "lujun9972@gmail.com")) (:maintainer "DarkSun" . "lujun9972@gmail.com") (:keywords "lisp" "url" "image"))])
+ (ujelly-theme . [(20180214 1624) nil "Ujelly theme for GNU Emacs 24 (deftheme)" single ((:commit . "bf724ce7806a738d2043544061e5f9bbfc56e674") (:authors ("Mark Tran" . "mark.tran@gmail.com")) (:maintainer "Mark Tran" . "mark.tran@gmail.com") (:url . "http://github.com/marktran/color-theme-ujelly"))])
+ (ukrainian-holidays . [(20130720 1349) nil "Ukrainian holidays for Emacs calendar." single ((:commit . "e52b0c92843e9f4d0415a7ba3b8559785497d23d") (:authors ("Oleh Krehel" . "ohwoeowho@gmail.com")) (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com") (:url . "https://github.com/abo-abo/ukrainian-holidays"))])
+ (uml-mode . [(20200129 1147) ((emacs (24 4)) (seq (0))) "Minor mode for ascii uml sequence diagrams" single ((:commit . "4c37ac1c4424b2313cd8f16ba48a98a4cc214200") (:authors ("Ian Martins" . "ianxm@jhu.edu")) (:maintainer "Ian Martins" . "ianxm@jhu.edu") (:keywords "docs") (:url . "http://github.com/ianxm/emacs-uml"))])
+ (uncrustify-mode . [(20130707 1359) nil "Minor mode to automatically uncrustify." single ((:commit . "73893d000361e95784911e5ec268ad0ab2a1473c") (:authors ("Tabito Ohtani" . "koko1000ban@gmail.com")) (:maintainer "Tabito Ohtani" . "koko1000ban@gmail.com") (:keywords "uncrustify"))])
+ (undercover . [(20210602 2119) ((emacs (24)) (dash (2 0 0)) (shut-up (0 3 2))) "Test coverage library for Emacs Lisp" single ((:commit . "1d3587f1fad66a747688f36636b67b33b73447d3") (:authors ("Sviridov Alexander" . "sviridov.vmi@gmail.com")) (:maintainer "Sviridov Alexander" . "sviridov.vmi@gmail.com") (:keywords "lisp" "tests" "coverage" "tools") (:url . "https://github.com/sviridov/undercover.el"))])
+ (underline-with-char . [(20191128 2309) ((emacs (24))) "Underline with a char" single ((:commit . "36577e72aa4fbfa7f1abad01842359209f543751") (:maintainer nil . "marcowahlsoft@gmail.com") (:keywords "convenience") (:url . "https://gitlab.com/marcowahl/underline-with-char"))])
+ (undersea-theme . [(20200719 618) ((emacs (24 3))) "Theme styled after undersea imagery" single ((:commit . "b7b5bffe242fd15b9eb8fe5cb7c9b45e474babbc") (:authors ("Shen, Jen-Chieh" . "jcs090218@gmail.com")) (:maintainer "Shen, Jen-Chieh" . "jcs090218@gmail.com") (:url . "https://github.com/jcs-elpa/undersea-theme"))])
+ (underwater-theme . [(20131118 2) nil "A gentle, deep blue color theme" single ((:commit . "4eb9ef014f580adc135d91d1cd68d37a310640b6") (:authors ("Jon-Michael Deldin" . "dev@jmdeldin.com")) (:maintainer "Jon-Michael Deldin" . "dev@jmdeldin.com") (:keywords "faces"))])
+ (undo-fu . [(20220412 2337) ((emacs (25 1))) "Undo helper with redo" single ((:commit . "f9c39c248cb965cd3c7cb3c8e15a4eee71921f8c") (:authors ("Campbell Barton" . "ideasman42@gmail.com")) (:maintainer "Campbell Barton" . "ideasman42@gmail.com") (:url . "https://gitlab.com/ideasman42/emacs-undo-fu"))])
+ (undo-fu-session . [(20220428 200) ((emacs (28 1))) "Persistent undo, available between sessions" single ((:commit . "3e54374b3749e4885dc0de900f3d7a83b72536e1") (:authors ("Campbell Barton" . "ideasman42@gmail.com")) (:maintainer "Campbell Barton" . "ideasman42@gmail.com") (:keywords "convenience") (:url . "https://gitlab.com/ideasman42/emacs-undo-fu-session"))])
+ (undo-propose . [(20210207 45) ((emacs (24 3))) "Simple and safe undo navigation" single ((:commit . "91a1dfe516d90dab69c368f6669bacb2458ec5e9") (:authors ("Jack Kamm")) (:maintainer "Jack Kamm") (:keywords "convenience" "files" "undo" "redo" "history") (:url . "https://github.com/jackkamm/undo-propose.el"))])
+ (undohist . [(20220219 634) ((cl-lib (1 0))) "Persistent undo history for GNU Emacs" single ((:commit . "ec95d5038425bca375865803701c971a9c748114") (:authors ("MATSUYAMA Tomohiro" . "m2ym.pub@gmail.com")) (:maintainer "MATSUYAMA Tomohiro" . "m2ym.pub@gmail.com") (:keywords "convenience"))])
+ (unfill . [(20210106 220) ((emacs (24 1))) "Do the opposite of fill-paragraph or fill-region" single ((:commit . "cd354ea1a74338760ac6f5872d573e3ecb6b4bd2") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:keywords "convenience") (:url . "https://github.com/purcell/unfill"))])
+ (unicad . [(20200914 1500) ((emacs (24)) (nadvice (0 3))) "An elisp port of Mozilla Universal Charset Auto Detector" single ((:commit . "a5fd4e326a0607acc3776c11f41826e60b6486c6") (:authors ("Qichen Huang" . "unicad.el@gmail.com")) (:maintainer "Qichen Huang" . "unicad.el@gmail.com") (:keywords "i18n") (:url . "https://github.com/ukari/unicad"))])
+ (unicode-emoticons . [(20150204 1108) nil "Shortcuts for common unicode emoticons" single ((:commit . "fb18631f342b0243cf77cf59ed2067c47aae5233") (:authors ("Gunther Hagleitner")) (:maintainer "Gunther Hagleitner") (:keywords "games" "entertainment" "comms") (:url . "https://github.com/hagleitn/unicode-emoticons"))])
+ (unicode-enbox . [(20140508 2041) ((string-utils (0 3 2)) (ucs-utils (0 7 6)) (list-utils (0 4 2)) (persistent-soft (0 8 8)) (pcache (0 2 3))) "Surround a string with box-drawing characters" single ((:commit . "77074fac1994a4236f111d6a1d0cf79ea3fca151") (:authors ("Roland Walker" . "walker@pobox.com")) (:maintainer "Roland Walker" . "walker@pobox.com") (:keywords "extensions" "interface") (:url . "http://github.com/rolandwalker/unicode-enbox"))])
+ (unicode-escape . [(20160614 1234) ((emacs (24)) (names (20151201 0)) (dash (2 12 1))) "Escape/Unescape unicode notations" single ((:commit . "fc69ec780d9e54c364a9252bd0cf1d2507f3fab7") (:authors ("KOBAYASHI Shigeru (kosh)" . "shigeru.kb@gmail.com")) (:maintainer "KOBAYASHI Shigeru (kosh)" . "shigeru.kb@gmail.com") (:keywords "i18n" "unicode") (:url . "https://github.com/kosh04/unicode-escape.el"))])
+ (unicode-fonts . [(20200803 1335) ((font-utils (0 7 8)) (ucs-utils (0 8 2)) (list-utils (0 4 2)) (persistent-soft (0 8 10)) (pcache (0 3 1))) "Configure Unicode fonts" single ((:commit . "47f2397ade28eba621baa865fd69e4efb71407a5") (:authors ("Roland Walker" . "walker@pobox.com")) (:maintainer "Roland Walker" . "walker@pobox.com") (:keywords "i18n" "faces" "frames" "wp" "interface") (:url . "http://github.com/rolandwalker/unicode-fonts"))])
+ (unicode-math-input . [(20220302 1231) ((emacs (25))) "Insert Unicode math symbols using TeX notation" single ((:commit . "06bf37d649fc3b41fcd5fa29c0b0eda555aaf8bb") (:authors ("Augusto Stoffel")) (:maintainer "Augusto Stoffel") (:url . "https://github.com/astoff/unicode-math-input.el"))])
+ (unicode-progress-reporter . [(20140508 2041) ((emacs (24 1 0)) (ucs-utils (0 7 6)) (list-utils (0 4 2)) (persistent-soft (0 8 8)) (pcache (0 2 3))) "Progress-reporter with fancy characters" single ((:commit . "5e66724fd7d15743213b082474d798117b194494") (:authors ("Roland Walker" . "walker@pobox.com")) (:maintainer "Roland Walker" . "walker@pobox.com") (:keywords "interface") (:url . "http://github.com/rolandwalker/unicode-progress-reporter"))])
+ (unicode-troll-stopper . [(20190209 411) nil "Minor mode for Highlighting Unicode homoglyphs" single ((:commit . "5e8be35a7bf6382384a701663f7438ee27e4b67c") (:authors ("Cam Saül" . "cammsaul@gmail.com")) (:maintainer "Cam Saül" . "cammsaul@gmail.com") (:keywords "unicode") (:url . "https://github.com/camsaul/emacs-unicode-troll-stopper"))])
+ (unicode-whitespace . [(20140508 2041) ((ucs-utils (0 7 6)) (list-utils (0 4 2)) (persistent-soft (0 8 8)) (pcache (0 2 3))) "teach whitespace-mode about fancy characters" single ((:commit . "a18c6b38d78b94f2eb1dcc4cb4fa91b6a17efabe") (:authors ("Roland Walker" . "walker@pobox.com")) (:maintainer "Roland Walker" . "walker@pobox.com") (:keywords "faces" "wp" "interface") (:url . "http://github.com/rolandwalker/unicode-whitespace"))])
+ (unidecode . [(20201213 1449) nil "Transliterate Unicode to ASCII" tar ((:commit . "525b51b38f5b0435642005957740fe22ecb2a53c") (:authors ("sindikat <sindikat at mail36 dot net>")) (:maintainer "John Mastro" . "john.b.mastro@gmail.com"))])
+ (unifdef . [(20200517 514) nil "Delete code guarded by processor directives" single ((:commit . "7a4b76f664c4375e3d98e8af0a29270752c13701") (:authors ("Anders Lindgren")) (:maintainer "Anders Lindgren") (:keywords "convenience" "languages") (:url . "https://github.com/Lindydancer/unifdef"))])
+ (unify-opening . [(20171122 2012) ((emacs (24 4))) "Unify the mechanism to open files" single ((:commit . "502469ddba6d8d52159f53976265f7d956b6b17c") (:authors ("Damien Cassou" . "damien.cassou@gmail.com")) (:maintainer "Damien Cassou" . "damien.cassou@gmail.com") (:url . "https://github.com/DamienCassou/unify-opening"))])
+ (unipoint . [(20140113 2224) nil "a simple way to insert unicode characters by TeX name" single ((:commit . "5da04aebac35a5c9e1d8704f2231808d42f4b36a") (:authors ("Andrew Gwozdziewycz" . "git@apgwoz.com")) (:maintainer "Andrew Gwozdziewycz" . "git@apgwoz.com") (:url . "https://github.com/apgwoz/unipoint"))])
+ (unison . [(20160704 740) ((emacs (24 1))) "sync with Unison" single ((:commit . "a78a04c0d1398d00f75a1bd4799622a65bcb0f28") (:authors ("Kevin Brubeck Unhammer" . "unhammer@fsfe.org")) (:maintainer "Kevin Brubeck Unhammer" . "unhammer@fsfe.org") (:keywords "sync") (:url . "http://github.com/unhammer/unison.el"))])
+ (unison-mode . [(20160513 1501) nil "Syntax highlighting for unison file synchronization program" single ((:commit . "0bd6a65c0d12f87fcf7bdff15fe54444959b93bf") (:authors ("Karl Fogelmark" . "karlfogel@gmail.com")) (:maintainer "Karl Fogelmark" . "karlfogel@gmail.com") (:keywords "symchronization" "unison") (:url . "https://github.com/impaktor/unison-mode"))])
+ (unisonlang-mode . [(20200803 808) ((emacs (25 1))) "Simple major mode for editing Unison" single ((:commit . "2b794adbe0b2a4edd40f350173a32b80bd2c5896") (:authors ("Dario Oddenino")) (:maintainer "Dario Oddenino") (:keywords "languages") (:url . "https://github.com/dariooddenino/unison-mode-emacs"))])
+ (universal-emotions-emoticons . [(20180729 1941) ((emacs (24 4))) "Emoticons For The Six Universal Expressions" single ((:commit . "9cedd09ee65cb9fa71f27b0ab46a8353bdc00902") (:authors ("Grant Rettke" . "gcr@wisdomandwonder.com")) (:maintainer nil . "<gcr@wisdomandwonder.com>") (:keywords "convenience" "docs" "languages") (:url . "https://github.com/grettke/universal-emotions-emoticons"))])
+ (unkillable-scratch . [(20190309 17) ((emacs (24))) "Disallow the \\*scratch\\* buffer from being killed" single ((:commit . "b24c2a760529833f230c14cb02ff6e7ec92288ab") (:authors ("Eric Crosson" . "eric.s.crosson@utexas.com")) (:maintainer "Eric Crosson" . "eric.s.crosson@utexas.com") (:keywords "convenience") (:url . "https://github.com/EricCrosson/unkillable-scratch"))])
+ (unmodified-buffer . [(20220129 2013) ((emacs (24 1))) "Auto revert modified buffer state" single ((:commit . "9095a3f870aa570804a11d75aba0952294199715") (:authors ("Arthur Colombini Gusmao")) (:maintainer "Arthur Colombini Gusmao") (:url . "https://github.com/arthurcgusmao/unmodified-buffer"))])
+ (unobtrusive-magit-theme . [(20200411 1349) ((emacs (24 1))) "An unobtrusive Magit theme" single ((:commit . "aede357009655d19d4468320b2b61b0f26a47593") (:authors ("Thomas A. Brown" . "tabsoftwareconsulting@gmail.com")) (:maintainer "Thomas A. Brown" . "tabsoftwareconsulting@gmail.com") (:keywords "faces" "vc" "magit") (:url . "https://github.com/tee3/unobtrusive-magit-theme"))])
+ (untappd . [(20210815 1544) ((emacs (26 1)) (request (0 3 2)) (emojify (1 2 1))) "Display your latest Untappd feed" single ((:commit . "493d1776d6456b00bf017e71fac9b0721d8cc912") (:authors ("Matthieu Petiteau" . "matt@smallwat3r.com")) (:maintainer "Matthieu Petiteau" . "matt@smallwat3r.com") (:url . "https://github.com/smallwat3r/untappd.el"))])
+ (untitled-new-buffer . [(20161212 1508) ((emacs (24 4)) (magic-filetype (0 2 0))) "Open untitled new buffer like other text editors." single ((:commit . "4eabc6937b0e83062ffce9de0d42110224063a6c") (:authors ("USAMI Kenta" . "tadsan@zonu.me")) (:maintainer "USAMI Kenta" . "tadsan@zonu.me") (:keywords "files" "convenience") (:url . "https://github.com/zonuexe/untitled-new-buffer.el"))])
+ (upbo . [(20180422 822) ((dash (2 12 0)) (emacs (24 4))) "Karma Test Runner Integration" single ((:commit . "1e4b1e7f44f242a6cdcce0c157d07efe667b7bef") (:authors ("Sungho Kim(shiren)")) (:maintainer "Sungho Kim(shiren)") (:keywords "javascript" "js" "test" "karma") (:url . "http://github.com/shiren"))])
+ (uptimes . [(20191121 1030) ((cl-lib (0 5)) (emacs (24))) "Track and display Emacs session uptimes." single ((:commit . "29ae6585eeed5a00719b2e52f5ae1082087c1778") (:authors ("Dave Pearson" . "davep@davep.org")) (:maintainer "Dave Pearson" . "davep@davep.org") (:keywords "processes" "uptime") (:url . "https://github.com/davep/uptimes.el"))])
+ (url-shortener . [(20170805 242) nil "shorten long url and expand tinyurl" single ((:commit . "06db8270213b9e352d6c335b0663059a1353d05e") (:authors ("Yu Yang" . "yy2012cn@NOSPAM.gmail.com")) (:maintainer "Yu Yang" . "yy2012cn@NOSPAM.gmail.com") (:url . "https://github.com/yuyang0/url-shortener"))])
+ (urlenc . [(20140116 1456) nil "URL encoding/decoding utility for Emacs." single ((:commit . "835a6dcb783bbe84714bae87a3464aa0b128bfac") (:authors ("Taiki SUGAWARA" . "buzz.taiki@gmail.com")) (:maintainer "Taiki SUGAWARA" . "buzz.taiki@gmail.com") (:keywords "url") (:url . "https://github.com/buzztaiki/urlenc-el"))])
+ (urscript-mode . [(20190219 1604) ((emacs (24 4))) "major mode for editing URScript." single ((:commit . "b341f96b129ead8fb74d680cb4f546985bf110a9") (:authors ("Guido Schmidt" . "git@guidoschmidt.cc")) (:maintainer "Guido Schmidt" . "git@guidoschmidt.cc") (:keywords "languages") (:url . "https://github.com/guidoschmidt/urscript-mode"))])
+ (usage-memo . [(20170926 37) nil "integration of Emacs help system and memo" single ((:commit . "88e15a9942a3e0a6e36e9c3e51e3edb746067b1a") (:authors ("rubikitch" . "rubikitch@ruby-lang.org")) (:maintainer "rubikitch" . "rubikitch@ruby-lang.org") (:keywords "convenience" "languages" "lisp" "help" "tools" "docs") (:url . "http://www.emacswiki.org/cgi-bin/wiki/download/usage-memo.el"))])
+ (use-package . [(20210207 1926) ((emacs (24 3)) (bind-key (2 4))) "A configuration macro for simplifying your .emacs" tar ((:commit . "a7422fb8ab1baee19adb2717b5b47b9c3812a84c") (:authors ("John Wiegley" . "johnw@newartisans.com")) (:maintainer "John Wiegley" . "johnw@newartisans.com") (:keywords "dotemacs" "startup" "speed" "config" "package") (:url . "https://github.com/jwiegley/use-package"))])
+ (use-package-chords . [(20181024 2322) ((use-package (2 1)) (bind-key (1 0)) (bind-chord (0 2)) (key-chord (0 6))) "key-chord keyword for use-package" single ((:commit . "a7422fb8ab1baee19adb2717b5b47b9c3812a84c") (:authors ("Justin Talbott" . "justin@waymondo.com")) (:maintainer "Justin Talbott" . "justin@waymondo.com") (:keywords "convenience" "tools" "extensions") (:url . "https://github.com/waymondo/use-package-chords"))])
+ (use-package-el-get . [(20180131 505) ((use-package (1 0))) "el-get support for use package" single ((:commit . "cba87c4e9a3a66b7c10962e3aefdf11c83d737bc") (:authors ("Edward Knyshov" . "edvorg@gmail.com")) (:maintainer "Edward Knyshov" . "edvorg@gmail.com") (:keywords "dotemacs" "startup" "speed" "config" "package" "tools") (:url . "https://github.com/edvorg/use-package-el-get"))])
+ (use-package-ensure-system-package . [(20180913 1501) ((use-package (2 1)) (system-packages (1 0 4))) "auto install system packages" single ((:commit . "a7422fb8ab1baee19adb2717b5b47b9c3812a84c") (:authors ("Justin Talbott" . "justin@waymondo.com")) (:maintainer "Justin Talbott" . "justin@waymondo.com") (:keywords "convenience" "tools" "extensions") (:url . "https://github.com/waymondo/use-package-ensure-system-package"))])
+ (use-package-hydra . [(20181228 745) ((emacs (24 3)) (use-package (2 4))) "Adds :hydra keyword to use-package macro" single ((:commit . "8cd55a1128fbdf6327bb38a199d206225896d146") (:authors ("Toon Claes" . "toon@iotcl.com")) (:maintainer "Toon Claes" . "toon@iotcl.com") (:keywords "convenience" "extensions" "tools") (:url . "https://gitlab.com/to1ne/use-package-hydra"))])
+ (use-proxy . [(20201209 853) ((exec-path-from-shell (1 12)) (emacs (26 2))) "Enable/Disable proxies respecting your HTTP/HTTPS env" single ((:commit . "b2995563f41c162a082cd4823a499887f807176e") (:authors ("Ray Wang" . "ray.hackmylife@gmail.com")) (:maintainer "Ray Wang" . "ray.hackmylife@gmail.com") (:keywords "proxy" "comm") (:url . "https://github.com/rayw000/use-proxy"))])
+ (use-ttf . [(20220220 150) ((emacs (24 4))) "Keep font consistency across different OSs" single ((:commit . "0cb20745e3889f4eb8ea49c4a748f34f9ddf1fa6") (:authors ("Shen, Jen-Chieh" . "jcs090218@gmail.com")) (:maintainer "Shen, Jen-Chieh" . "jcs090218@gmail.com") (:url . "https://github.com/jcs-elpa/use-ttf"))])
+ (utimeclock . [(20220425 939) ((emacs (24 4))) "Simple utility for manual time tracking" single ((:commit . "cfd5109e004d3e2522f5e758b3ff7238fcf385d6") (:authors ("Campbell Barton" . "ideasman42@gmail.com")) (:maintainer "Campbell Barton" . "ideasman42@gmail.com") (:url . "https://codeberg.org/ideasman42/emacs-utimeclock"))])
+ (utop . [(20210607 1941) ((emacs (24)) (tuareg (2 2 0))) "Universal toplevel for OCaml" single ((:commit . "42614160c20764b443d082083740e8dcc6cf2f78") (:authors ("Jeremie Dimino" . "jeremie@dimino.org")) (:maintainer "Jeremie Dimino" . "jeremie@dimino.org") (:keywords "ocaml" "languages") (:url . "https://github.com/diml/utop"))])
+ (uuid . [(20120910 851) nil "UUID's for EmacsLisp" single ((:commit . "1519bfeb0e31602b840bc8dd35d7c7e732c159fe") (:authors ("James Mastros")) (:maintainer "Nic Ferrier" . "nferrier@ferrier.me.uk") (:keywords "lisp"))])
+ (uuidgen . [(20220405 1345) nil "Provides various UUID generating functions" single ((:commit . "7b728c1d92e196c3acf87a004949335cfc18eab3") (:authors ("Kan-Ru Chen" . "kanru@kanru.info")) (:maintainer "Kan-Ru Chen" . "kanru@kanru.info") (:keywords "extensions" "lisp" "tools"))])
+ (uwu-theme . [(20220411 1904) ((emacs (24 1))) "An awesome dark color scheme" single ((:commit . "feef3e73dbcb3fbba431c62a99a3333959f6158e") (:authors ("Kevin Borling")) (:maintainer "Kevin Borling") (:keywords "custom themes" "dark" "faces") (:url . "https://github.com/kborling/uwu-theme"))])
+ (uxntal-mode . [(20220502 154) ((emacs (27 1))) "Major mode for Uxntal assembly" single ((:commit . "39cde87b15a98e0612e30b80e0676211236ac3e7") (:authors ("d_m" . "d_m@plastic-idolatry.com")) (:maintainer "d_m" . "d_m@plastic-idolatry.com") (:url . "https://github.com/non/uxntal-mode"))])
+ (v-mode . [(20220104 142) ((emacs (25 1)) (dash (2 17 0)) (hydra (0 15 0))) "A major mode for the V programming language" single ((:commit . "a701f4cedfff91cf4bcd17c9a2cd16a49f942743") (:keywords "languages" "programming") (:url . "https://github.com/damon-kwok/v-mode"))])
+ (v2ex-mode . [(20160720 345) ((cl-lib (0 5)) (request (0 2)) (let-alist (1 0 3))) "Major mode for visit http://v2ex.com/ site." single ((:commit . "b7d19bb594b43ea3824a6f215dd1e5d1d4c0e8ad") (:authors ("Aborn Jiang" . "aborn.jiang@gmail.com")) (:maintainer "Aborn Jiang" . "aborn.jiang@gmail.com") (:keywords "v2ex" "v2ex.com") (:url . "https://github.com/aborn/v2ex-mode"))])
+ (vagrant . [(20211206 1634) nil "Manage a vagrant box from emacs" single ((:commit . "a232b7385178d5b029ccc5274dfa9b56e5ba43a1") (:authors ("Robert Crim" . "rob@servermilk.com")) (:maintainer "Robert Crim" . "rob@servermilk.com") (:keywords "vagrant" "chef") (:url . "https://github.com/ottbot/vagrant.el"))])
+ (vagrant-tramp . [(20210217 704) ((dash (2 12 0))) "Vagrant method for TRAMP" tar ((:commit . "5f00b42a0c023c461cef7af4de7652d90c788b4d") (:authors ("Doug MacEachern" . "dougm@vmware.com") ("Ryan Prior " . "ryanprior@gmail.com")) (:maintainer "Doug MacEachern" . "dougm@vmware.com") (:keywords "vagrant") (:url . "https://github.com/dougm/vagrant-tramp"))])
+ (vala-mode . [(20201218 2109) nil "Vala mode derived mode" single ((:commit . "d696a8177e94c81ea557ad364a3b3dcc3abbc50f") (:authors ("2005 Dylan R. E. Moonfire") (" 2008 Étienne BERSAC")) (:maintainer "Étienne BERSAC" . "bersace03@laposte.net") (:keywords "vala" "languages" "oop"))])
+ (vala-snippets . [(20150429 352) ((yasnippet (0 8 0))) "Yasnippets for Vala" tar ((:commit . "671439501060449bd100b9fffd524a86064fbfbb") (:authors ("Daniel Gopar")) (:maintainer "Daniel Gopar") (:url . "https://github.com/gopar/vala-snippets"))])
+ (vale-mode . [(20190725 125) ((emacs (25))) "Major mode for writing Vale vaf files" single ((:commit . "48bbc4b4ee5bf0b1b73e52705c0fbc112b255cd0") (:authors ("Jay Bosamiya" . "jaybosamiya@gmail.com")) (:maintainer "Jay Bosamiya" . "jaybosamiya@gmail.com") (:keywords "convenience" "languages") (:url . "https://github.com/jaybosamiya/vale-mode.el"))])
+ (validate-html . [(20210420 2344) ((emacs (25 1))) "Compilation mode for W3C HTML Validator" single ((:commit . "748e874d50c3a95c61590ae293778e26de05c5f9") (:authors ("Arthur A. Gleckler" . "melpa4aag@speechcode.com")) (:maintainer "Arthur A. Gleckler" . "melpa4aag@speechcode.com") (:keywords "languages" "tools") (:url . "https://github.com/arthurgleckler/validate-html"))])
+ (vampyricdark-theme . [(20220405 2235) ((emacs (25 1))) "VampyricDark Theme" single ((:commit . "7b9ac67efd38466765b85b1dd131d6b64d8f71f9") (:url . "https://github.com/VampyricDark/emacs"))])
+ (vbasense . [(20140221 2353) ((auto-complete (1 4 0)) (log4e (0 2 0)) (yaxception (0 1))) "provide a environment like Visual Basic Editor." tar ((:commit . "8c61a492d7c15218ae1a96e2aebfe6f78bfff6db") (:authors ("Hiroaki Otsu" . "ootsuhiroaki@gmail.com")) (:maintainer "Hiroaki Otsu" . "ootsuhiroaki@gmail.com") (:keywords "vba" "completion") (:url . "https://github.com/aki2o/emacs-vbasense"))])
+ (vc-auto-commit . [(20210216 1517) nil "Auto-committing feature for your repository" tar ((:commit . "56f478016a541b395092a9d3cdc0da84a37b30a1") (:authors ("Sylvain Rousseau <thisirs at gmail dot com>")) (:maintainer "Sylvain Rousseau <thisirs at gmail dot com>") (:keywords "vc" "convenience") (:url . "http://github.com/thisirs/vc-auto-commit.git"))])
+ (vc-check-status . [(20210216 1525) nil "Warn you when quitting emacs and leaving repo dirty." tar ((:commit . "d95ef8f0799cd3dd83726ffa9b01b076f378ce34") (:authors ("Sylvain Rousseau <thisirs at gmail dot com>")) (:maintainer "Sylvain Rousseau <thisirs at gmail dot com>") (:keywords "vc" "convenience") (:url . "https://github.com/thisirs/vc-check-status"))])
+ (vc-darcs . [(20220406 659) ((emacs (24))) "a VC backend for darcs" single ((:commit . "56426a235b742618b48fad8538777a9b3ffb7240") (:authors ("Jorgen Schaefer" . "forcer@forcix.cx") ("Juliusz Chroboczek" . "jch@pps.univ-paris-diderot.fr")) (:maintainer "Libor Čapák" . "capak@inputwish.com") (:keywords "vc"))])
+ (vc-defer . [(20201116 701) ((emacs (25 1))) "Defer non-essential vc.el work" single ((:commit . "aeafc419c1788b3ac4f0590c635374eefd7c220c") (:authors ("Matt Armstrong" . "marmstrong@google.com")) (:maintainer "Tom Fitzhenry" . "tomfitzhenry@google.com") (:keywords "vc" "tools") (:url . "https://github.com/google/vc-defer"))])
+ (vc-fossil . [(20210928 737) nil "VC backend for the fossil sofware configuraiton management system" single ((:commit . "7815c30d739a01e1100961abb3f2b93e0ea9920f") (:authors ("Venkat Iyer" . "venkat@comit.com")) (:maintainer "Alfred M. Szmidt" . "ams@gnu.org"))])
+ (vc-hgcmd . [(20211021 1704) ((emacs (25 1))) "VC mercurial backend that uses hg command server" single ((:commit . "d044448965d31ca8214f8bca48487e4d9b9d9a0f") (:authors ("Andrii Kolomoiets" . "andreyk.mad@gmail.com")) (:maintainer "Andrii Kolomoiets" . "andreyk.mad@gmail.com") (:keywords "vc") (:url . "https://github.com/muffinmad/emacs-vc-hgcmd"))])
+ (vc-msg . [(20211224 1354) ((emacs (24 4)) (popup (0 5 0))) "Show commit information of current line" tar ((:commit . "3ad560afc1e0610acd1ce4b9509aedae66276b91") (:authors ("Chen Bin <chenbin DOT sh AT gmail DOT com>")) (:maintainer "Chen Bin <chenbin DOT sh AT gmail DOT com>") (:keywords "git" "vc" "svn" "hg" "messenger") (:url . "http://github.com/redguardtoo/vc-msg"))])
+ (vc-osc . [(20190402 2349) nil "non-resident support for osc version-control" single ((:commit . "bf5a515ed85f7d7cdfe66ed5bf4ef7554f8561e5") (:authors ("Adam Spiers (see vc.el for full credits)")) (:maintainer "Adam Spiers" . "aspiers@suse.com"))])
+ (vcomp . [(20190128 20) nil "compare version strings" single ((:commit . "f839b3b3257a564b19d7f9557dc8bcbbe0b95842") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:keywords "versions") (:url . "https://github.com/tarsius/vcomp"))])
+ (vcsh . [(20200226 1339) ((emacs (25 1))) "vcsh integration" single ((:commit . "7e376436b8f450a5571e19246136ccf77bbdd4f1") (:authors ("Štěpán Němec" . "stepnem@gmail.com")) (:maintainer "Štěpán Němec" . "stepnem@gmail.com") (:keywords "vc" "files") (:url . "https://gitlab.com/stepnem/vcsh-el"))])
+ (vdf-mode . [(20210303 714) ((emacs (24 3))) "Major mode for editing Valve VDF files." single ((:commit . "0910d4f847e9c817eb8da5434b3879048ec4ac92") (:authors ("Philipp Middendorf")) (:maintainer "Philipp Middendorf") (:url . "https://github.com/plapadoo/vdf-mode"))])
+ (vdiff . [(20210426 155) ((emacs (24 4)) (hydra (0 13 0))) "A diff tool similar to vimdiff" single ((:commit . "84b8243d9f5d8082b05794dbc998d43dbdd7676a") (:authors ("Justin Burkett" . "justin@burkett.cc")) (:maintainer "Justin Burkett" . "justin@burkett.cc") (:keywords "diff") (:url . "https://github.com/justbur/emacs-vdiff"))])
+ (vdiff-magit . [(20210908 135) ((emacs (24 4)) (vdiff (0 3)) (magit (2 10 0)) (transient (0 1 0))) "magit integration for vdiff" single ((:commit . "d3a39c3f8cb7ad9a6a769ce45f633b613b067490") (:authors ("Justin Burkett" . "justin@burkett.cc")) (:maintainer "Justin Burkett" . "justin@burkett.cc") (:keywords "diff") (:url . "https://github.com/justbur/emacs-vdiff-magit"))])
+ (vdirel . [(20220412 646) ((emacs (24 4)) (org-vcard (0 1 0)) (helm (1 7 0)) (seq (1 11))) "Manipulate vdir (i.e., vCard) repositories" single ((:commit . "4eebcf91bdb9ee10fbbba198c4995ae070442f26") (:authors ("Damien Cassou" . "damien@cassou.me")) (:maintainer "Damien Cassou" . "damien@cassou.me") (:url . "https://github.com/DamienCassou/vdirel"))])
+ (vdm-comint . [(20181127 2023) ((emacs (25)) (vdm-mode (0 0 4))) "REPL support for vdm-mode" single ((:commit . "56336930555df91787f196acac15680498d17d5e") (:authors ("Peter W. V. Tran-Jørgensen" . "peter.w.v.jorgensen@gmail.com")) (:maintainer "Peter W. V. Tran-Jørgensen" . "peter.w.v.jorgensen@gmail.com") (:keywords "languages") (:url . "https://github.com/peterwvj/vdm-mode"))])
+ (vdm-mode . [(20190328 1408) ((emacs (25))) "Major mode for the Vienna Development Method" tar ((:commit . "56336930555df91787f196acac15680498d17d5e") (:authors ("Peter W. V. Tran-Jørgensen" . "peter.w.v.jorgensen@gmail.com")) (:maintainer "Peter W. V. Tran-Jørgensen" . "peter.w.v.jorgensen@gmail.com") (:keywords "languages") (:url . "https://github.com/peterwvj/vdm-mode"))])
+ (vdm-snippets . [(20190313 1122) ((emacs (24)) (yasnippet (0 13 0))) "YASnippets for VDM mode" tar ((:commit . "56336930555df91787f196acac15680498d17d5e") (:authors ("Peter W. V. Tran-Jørgensen" . "peter.w.v.jorgensen@gmail.com")) (:maintainer "Peter W. V. Tran-Jørgensen" . "peter.w.v.jorgensen@gmail.com") (:keywords "languages") (:url . "https://github.com/peterwvj/vdm-mode"))])
+ (vector-utils . [(20140508 2041) nil "Vector-manipulation utility functions" single ((:commit . "c38ca1c6a23b2b51a6ac36c2c64e50e21cbe9d21") (:authors ("Roland Walker" . "walker@pobox.com")) (:maintainer "Roland Walker" . "walker@pobox.com") (:keywords "extensions") (:url . "http://github.com/rolandwalker/vector-utils"))])
+ (vega-view . [(20210401 1115) ((emacs (25)) (cider (0 24 0)) (parseedn (0 1))) "Vega visualization viewer" single ((:commit . "3793025a523a86acc6255b4183b12ebfc95e1116") (:authors ("Jack Rusher" . "jack@appliedscience.studio")) (:maintainer "Jack Rusher" . "jack@appliedscience.studio") (:keywords "multimedia") (:url . "https://www.github.com/applied-science/emacs-vega-view"))])
+ (verb . [(20220214 943) ((emacs (25 1))) "Organize and send HTTP requests" tar ((:commit . "f6fd85d913c39603695e52d258d02e6030e3d42d") (:authors ("Federico Tedin" . "federicotedin@gmail.com")) (:maintainer "Federico Tedin" . "federicotedin@gmail.com") (:keywords "tools") (:url . "https://github.com/federicotdn/verb"))])
+ (veri-kompass . [(20200213 934) ((emacs (25)) (cl-lib (0 5)) (org (8 2 0))) "verilog codebase navigation facility" single ((:commit . "271903cdf92db05898ee7cffb65641f30fa08280") (:maintainer nil . "andrea_corallo@yahoo.it") (:keywords "languages" "extensions" "verilog" "hardware" "rtl") (:url . "https://gitlab.com/koral/veri-kompass"))])
+ (verify-url . [(20160426 1228) ((cl-lib (0 5))) "find out invalid urls in the buffer or region" single ((:commit . "d6f3623cda8cd526a2d198619b137059cb1ba1ab") (:authors ("DarkSun" . "lujun9972@gmail.com")) (:maintainer "DarkSun" . "lujun9972@gmail.com") (:keywords "convenience" "usability" "url") (:url . "https://github.com/lujun9972/verify-url"))])
+ (verona-mode . [(20200823 536) ((emacs (25 1)) (dash (2 17 0)) (hydra (0 15 0))) "A major mode for the Verona programming language" single ((:commit . "72dd31ef847344d79409503f3c42169041eb3da4") (:keywords "languages" "programming") (:url . "https://github.com/damon-kwok/verona-mode"))])
+ (versuri . [(20211104 1301) ((emacs (26 1)) (dash (2 16 0)) (request (0 3 0)) (anaphora (1 0 4)) (esxml (0 1 0)) (s (1 12 0)) (esqlite (0 3 1))) "The lyrics package" single ((:commit . "c8ea562304194f3379ed8f9c6a785ce8ee72898e") (:authors ("Mihai Olteanu" . "mihai_olteanu@fastmail.fm")) (:maintainer "Mihai Olteanu" . "mihai_olteanu@fastmail.fm") (:keywords "multimedia") (:url . "https://github.com/mihaiolteanu/versuri/"))])
+ (vertica . [(20131217 1511) ((sql (3 0))) "Vertica SQL mode extension" single ((:commit . "3c9647b425c5c13c30bf0cba483646af18196588") (:authors ("Roman Scherer" . "roman@burningswell.com")) (:maintainer "Roman Scherer" . "roman@burningswell.com") (:keywords "sql" "vertica"))])
+ (vertica-snippets . [(20200423 1200) ((yasnippet (0 6 1))) "Yasnippets for Vertica" tar ((:commit . "6ced718d9120878878700592fab430a8542b748f") (:authors ("Andreas Gerler" . "baron@bundesbrandschatzamt.de")) (:maintainer "Andreas Gerler" . "baron@bundesbrandschatzamt.de") (:keywords "convenience" "snippets") (:url . "https://github.com/baron42bba/vertica-snippets"))])
+ (vertigo . [(20211224 1256) ((dash (2 11 0))) "Jump across lines using the home row." single ((:commit . "280b30518529242ee36cd436bd2349c34c35abb0") (:authors ("Fox Kiester" . "noct@posteo.net")) (:maintainer "Fox Kiester" . "noct@posteo.net") (:keywords "vim" "vertigo") (:url . "https://github.com/noctuid/vertigo.el"))])
+ (vhdl-capf . [(20160221 1734) nil "Completion at point function (capf) for vhdl-mode." single ((:commit . "290abe217050f33532bc9ccb04f894123402f414") (:authors ("sh-ow" . "sh-ow@users.noreply.github.com")) (:maintainer "sh-ow" . "sh-ow@users.noreply.github.com") (:keywords "convenience" "usability" "vhdl" "completion") (:url . "https://github.com/sh-ow/vhdl-capf"))])
+ (vhdl-tools . [(20200330 1819) ((ggtags (0 9 0)) (emacs (26 2)) (helm-rg (0 1)) (outshine (3 1 -1))) "Utilities for navigating vhdl sources" single ((:commit . "b5d1eec90bb43ba10178219245afbddb6601e85b") (:authors ("Cayetano Santos")) (:maintainer "Cayetano Santos") (:keywords "convenience" "languages" "vhdl") (:url . "https://gitlab.com/emacs-elisp/vhdl-tools/-/wikis/home"))])
+ (vi-tilde-fringe . [(20141028 242) ((emacs (24))) "Displays tildes in the fringe on empty lines a la Vi." single ((:commit . "f1597a8d54535bb1d84b442577b2024e6f910308") (:authors ("Sylvain Benner" . "sylvain.benner@gmail.com")) (:maintainer "Sylvain Benner" . "sylvain.benner@gmail.com") (:keywords "emulation") (:url . "https://github.com/syl20bnr/vi-tilde-fringe"))])
+ (viewer . [(20170107 202) nil "View-mode extension" single ((:commit . "6c8db025bf4021428f7f2c3ef9d74fb13f5d267a") (:authors ("rubikitch" . "rubikitch@ruby-lang.org")) (:maintainer "rubikitch" . "rubikitch@ruby-lang.org") (:keywords "view" "extensions") (:url . "http://github.com/rubikitch/viewer/"))])
+ (viking-mode . [(20160705 2027) nil "kill first, ask later" single ((:commit . "c76aa265d13ad91d6890d242e142d05e31f0340b") (:authors ("T.v.Dein" . "tlinden@cpan.org")) (:maintainer "T.v.Dein" . "tlinden@cpan.org") (:keywords "kill" "delete") (:url . "https://github.com/tlinden/viking-mode"))])
+ (vim-empty-lines-mode . [(20150111 426) ((emacs (23))) "Vim-like empty line indicator at end of files." single ((:commit . "d4a5034ca8ea0c962ad6e92c86c0fa2a74d2964b") (:authors ("Jonne Mickelin" . "jonne@ljhms.com")) (:maintainer "Jonne Mickelin" . "jonne@ljhms.com") (:keywords "emulations") (:url . "https://github.com/jmickelin/vim-empty-lines-mode"))])
+ (vim-region . [(20140329 1624) ((expand-region (20140127))) "Select region as vim" single ((:commit . "7c4a99ce3678fee40c83ab88e8ad075d2a935fdf") (:authors ("ongaeshi" . "ongaeshi0621@gmail.com")) (:maintainer "ongaeshi" . "ongaeshi0621@gmail.com") (:url . "https://github.com/ongaeshi/emacs-vim-region"))])
+ (vimgolf . [(20200205 1420) nil "VimGolf interface for the One True Editor" single ((:commit . "f565447ed294898588a19438d56c116555d8c628") (:authors ("Tim Visher" . "tim.visher@gmail.com")) (:maintainer "Tim Visher" . "tim.visher@gmail.com") (:keywords "games" "vimgolf" "vim") (:url . "https://github.com/timvisher/vimgolf.el"))])
+ (vimish-fold . [(20201205 1156) ((emacs (24 4)) (cl-lib (0 5)) (f (0 18 0))) "Fold text like in Vim" single ((:commit . "a6501cbfe3db791f9ca17fd986c7202a87f3adb8") (:authors ("Mark Karpov" . "markkarpov92@gmail.com")) (:maintainer "Mark Karpov" . "markkarpov92@gmail.com") (:keywords "convenience") (:url . "https://github.com/mrkkrp/vimish-fold"))])
+ (vimrc-mode . [(20181116 1919) nil "Major mode for vimrc files" single ((:commit . "13bc150a870d5d4a95f1111e4740e2b22813c30e") (:keywords "languages" "vim") (:url . "https://github.com/mcandre/vimrc-mode"))])
+ (virtual-auto-fill . [(20200906 2038) ((emacs (25 2)) (adaptive-wrap (0 7)) (visual-fill-column (1 9))) "Readably display text without adding line breaks" single ((:commit . "ac8bf947a1f87efe8967cb18166178f5fd93a8e1") (:authors ("Luis Gerhorst" . "virtual-auto-fill@luisgerhorst.de")) (:maintainer "Luis Gerhorst" . "virtual-auto-fill@luisgerhorst.de") (:keywords "convenience" "mail" "outlines" "files" "wp") (:url . "https://github.com/luisgerhorst/virtual-auto-fill"))])
+ (virtual-comment . [(20220405 229) ((emacs (26 1))) "Virtual Comments" single ((:commit . "d1f08e8bec3b52818d44ff06f719950b89204126") (:authors ("Thanh Vuong" . "thanhvg@gmail.com")) (:maintainer "Thanh Vuong" . "thanhvg@gmail.com") (:url . "https://github.com/thanhvg/emacs-virtual-comment"))])
+ (virtualenv . [(20140220 2301) nil "Virtualenv for Python" single ((:commit . "276c0f4d6493b402dc4d22ecdf17b2b072e911b3") (:authors ("Aaron Culich" . "aculich@gmail.com")) (:maintainer "Aaron Culich" . "aculich@gmail.com") (:keywords "python" "virtualenv"))])
+ (virtualenvwrapper . [(20190223 1919) ((dash (1 5 0)) (s (1 6 1))) "a featureful virtualenv tool for Emacs" single ((:commit . "c7e84505db4142fd1beebf38ffe37c3f42444ca3") (:authors ("James J Porter" . "porterjamesj@gmail.com")) (:maintainer "James J Porter" . "porterjamesj@gmail.com") (:keywords "python" "virtualenv" "virtualenvwrapper") (:url . "http://github.com/porterjamesj/virtualenvwrapper.el"))])
+ (visible-mark . [(20150624 450) nil "Make marks visible." single ((:commit . "a584db9bc88953b23a9648b3e14ade90767207f8") (:authors ("Ian Kelling" . "ian@iankelling.org")) (:maintainer "Ian Kelling" . "ian@iankelling.org") (:keywords "marking" "color" "faces") (:url . "https://gitlab.com/iankelling/visible-mark"))])
+ (visual-ascii-mode . [(20150129 1046) nil "Visualize ascii code (small integer) on buffer." single ((:commit . "99285a099a17472ddd9f1b4f74e9d092dd8c5947") (:authors ("Dewdrops" . "v_v_4474@126.com")) (:maintainer "Dewdrops" . "v_v_4474@126.com") (:keywords "presentation") (:url . "https://github.com/Dewdrops/visual-ascii-mode"))])
+ (visual-fill-column . [(20220426 2045) ((emacs (25 1))) "fill-column for visual-line-mode" single ((:commit . "cdfe574a51c4fc3519536fa3b169b01d5482d5df") (:authors ("Joost Kremers" . "joostkremers@fastmail.fm")) (:maintainer "Joost Kremers" . "joostkremers@fastmail.fm") (:url . "https://codeberg.org/joostkremers/visual-fill-column"))])
+ (visual-regexp . [(20210502 2019) ((cl-lib (0 2))) "A regexp/replace command for Emacs with interactive visual feedback" single ((:commit . "48457d42a5e0fe10fa3a9c15854f1f127ade09b5") (:authors ("Marko Bencun" . "mbencun@gmail.com")) (:maintainer "Marko Bencun" . "mbencun@gmail.com") (:keywords "regexp" "replace" "visual" "feedback") (:url . "https://github.com/benma/visual-regexp.el/"))])
+ (visual-regexp-steroids . [(20170222 253) ((visual-regexp (1 1))) "Extends visual-regexp to support other regexp engines" tar ((:commit . "a6420b25ec0fbba43bf57875827092e1196d8a9e") (:authors ("Marko Bencun" . "mbencun@gmail.com")) (:maintainer "Marko Bencun" . "mbencun@gmail.com") (:keywords "external" "foreign" "regexp" "replace" "python" "visual" "feedback") (:url . "https://github.com/benma/visual-regexp-steroids.el/"))])
+ (vlc . [(20200328 1143) ((emacs (25 1))) "VideoLAN VLC Media Player Control" single ((:commit . "932840f874e7510ee86e796bb5dc20d44514e31a") (:authors ("Xu Chunyang")) (:maintainer "Xu Chunyang") (:keywords "tools") (:url . "https://github.com/xuchunyang/vlc.el"))])
+ (vlf . [(20191126 2250) nil "View Large Files" tar ((:commit . "cc02f2533782d6b9b628cec7e2dcf25b2d05a27c") (:maintainer "Andrey Kotlarski" . "m00naticus@gmail.com") (:keywords "large files" "utilities") (:url . "https://github.com/m00natic/vlfi"))])
+ (vline . [(20210805 1528) ((emacs (24 3))) "Column highlighting (vertical line displaying) mode" single ((:commit . "f5d7b5743dceca75b81c8c95287cd5b0341debf9") (:authors ("Taiki SUGAWARA" . "buzz.taiki@gmail.com")) (:maintainer "Taiki SUGAWARA" . "buzz.taiki@gmail.com") (:keywords "faces" "editing" "emulating") (:url . "https://www.emacswiki.org/emacs/VlineMode"))])
+ (vmd-mode . [(20210524 27) ((emacs (24 3))) "Fast Github-flavored Markdown preview using a vmd subprocess." single ((:commit . "b2bdf2ab54f8fc37780e6b473e4ad69c0e9ff4a6") (:authors ("Blake Miller" . "blak3mill3r@gmail.com")) (:maintainer "Blake Miller" . "blak3mill3r@gmail.com") (:keywords "markdown" "preview" "live" "vmd") (:url . "https://github.com/blak3mill3r/vmd-mode"))])
+ (voca-builder . [(20161101 1645) ((popup (0 5 2))) "Helps you build up your vocabulary" single ((:commit . "51573beec8cd8308477b0faf453aad93e17f57c5") (:authors ("Yi Tang" . "yi.tang.uk@me.com")) (:maintainer "Yi Tang" . "yi.tang.uk@me.com") (:keywords "english" "vocabulary") (:url . "https://github.com/yitang/voca-builder"))])
+ (volatile-highlights . [(20160612 155) nil "Minor mode for visual feedback on some operations." single ((:commit . "9a20091f0ce7fc0a6b3e641a6a46d5f3ac4d8392") (:authors ("K-talo Miyazaki <Keitaro dot Miyazaki at gmail dot com>")) (:maintainer "K-talo Miyazaki <Keitaro dot Miyazaki at gmail dot com>") (:keywords "emulations" "convenience" "wp") (:url . "http://www.emacswiki.org/emacs/download/volatile-highlights.el"))])
+ (volume . [(20201002 1022) nil "tweak your sound card volume from Emacs" single ((:commit . "afb75a5f7fe41eb28c8dbb1378e80d103eea05c7") (:authors ("Daniel Brockman" . "daniel@brockman.se")) (:maintainer "Daniel Brockman" . "daniel@brockman.se") (:url . "http://www.brockman.se/software/volume-el/"))])
+ (vs-dark-theme . [(20220414 930) ((emacs (24 1))) "Visual Studio IDE dark theme" single ((:commit . "f5eb6387506b22ba7e21b4e335e689cf6768f18b") (:authors ("Jen-Chieh Shen")) (:maintainer "Jen-Chieh Shen") (:url . "https://github.com/emacs-vs/vs-dark-theme"))])
+ (vs-light-theme . [(20220414 931) ((emacs (24 1))) "Visual Studio IDE light theme" single ((:commit . "d585d0a3b87461b01dfad4ceaa7831668c6021d8") (:authors ("Jen-Chieh Shen")) (:maintainer "Jen-Chieh Shen") (:url . "https://github.com/emacs-vs/vs-light-theme"))])
+ (vscdark-theme . [(20191212 107) ((emacs (24 1))) "VS Code Dark+ like theme" single ((:commit . "8eba74059e8a9db974e4056ee024e52fe54da485") (:authors ("Alexander L. Belikoff")) (:maintainer "Alexander L. Belikoff") (:url . "https://github.com/abelikoff/vscdark-theme"))])
+ (vscode-dark-plus-theme . [(20220320 530) nil "Default Visual Studio Code Dark+ theme" single ((:commit . "cec18a9d816fef372a4e70f6ad1e16a42aa93b06") (:authors ("Ian Y.E. Pan")) (:maintainer "Ian Y.E. Pan") (:url . "https://github.com/ianpan870102/vscode-dark-plus-emacs-theme"))])
+ (vscode-icon . [(20201214 2227) ((emacs (25 1))) "Utility package to provide Vscode style icons" tar ((:commit . "909151c8105861aa300f5601e333909d36d0ebf5") (:authors ("James Nguyen" . "james@jojojames.com")) (:maintainer "James Nguyen" . "james@jojojames.com") (:keywords "files" "tools") (:url . "https://github.com/jojojames/vscode-icon-emacs"))])
+ (vterm . [(20220429 21) ((emacs (25 1))) "Fully-featured terminal emulator" tar ((:commit . "b44723552f86407d528c4a6c8057382c061b008e") (:authors ("Lukas Fürmetz" . "fuermetz@mailbox.org")) (:maintainer "Lukas Fürmetz" . "fuermetz@mailbox.org") (:keywords "terminals") (:url . "https://github.com/akermu/emacs-libvterm"))])
+ (vterm-toggle . [(20220416 1034) ((emacs (25 1)) (vterm (0 0 1))) "Toggles between the vterm buffer and other buffers." single ((:commit . "644e9df9f741c3338c248291799375a1778eb98b") (:authors (nil . "jixiuf jixiuf@qq.com")) (:maintainer nil . "jixiuf jixiuf@qq.com") (:keywords "vterm" "terminals") (:url . "https://github.com/jixiuf/vterm-toggle"))])
+ (vtm . [(20200921 338) nil "Manages vterm buffers with configuration files" tar ((:commit . "d770fd8cff7c24688199392ad93c01485c6a9569") (:keywords "convenience") (:url . "https://github.com/laishulu/emacs-vterm-manager"))])
+ (vue-html-mode . [(20180428 2035) nil "Major mode for editing Vue.js templates" single ((:commit . "1514939804bad558584feeb6298b38d22eadf64e") (:authors ("Adam Niederer" . "adam.niederer@gmail.com")) (:maintainer "Adam Niederer" . "adam.niederer@gmail.com") (:keywords "languages" "vue" "template") (:url . "http://github.com/AdamNiederer/vue-html-mode"))])
+ (vue-mode . [(20190415 231) ((mmm-mode (0 5 5)) (vue-html-mode (0 2)) (ssass-mode (0 2)) (edit-indirect (0 1 4))) "Major mode for vue component based on mmm-mode" single ((:commit . "031edd1f97db6e7d8d6c295c0e6d58dd128b9e71") (:authors ("codefalling" . "code.falling@gmail.com")) (:maintainer "codefalling" . "code.falling@gmail.com") (:keywords "languages"))])
+ (vuiet . [(20220218 1024) ((emacs (26 1)) (lastfm (1 1)) (versuri (1 0)) (s (1 12 0)) (bind-key (2 4)) (mpv (0 1 0))) "The music player and explorer for Emacs" single ((:commit . "aed3272b95fc73fd78712ff7dcfc05916f382fed") (:authors ("Mihai Olteanu" . "mihai_olteanu@fastmail.fm")) (:maintainer "Mihai Olteanu" . "mihai_olteanu@fastmail.fm") (:keywords "multimedia") (:url . "https://github.com/mihaiolteanu/vuiet"))])
+ (vulpea . [(20220204 936) ((emacs (27 2)) (org (9 4 4)) (org-roam (2 0 0)) (s (1 12))) "A collection of org-roam note-taking functions" tar ((:commit . "ba44342aea6a81c7b7ca6fcaae9a537701789b5e") (:authors ("Boris Buliga" . "boris@d12frosted.io")) (:maintainer "Boris Buliga" . "boris@d12frosted.io") (:url . "https://github.com/d12frosted/vulpea"))])
+ (vunit-mode . [(20220316 1812) ((hydra (0 14 0)) (emacs (24 3))) "VUnit Runner Interface" single ((:commit . "5643460a7011d6bc13c2d4762f329d19f6c7d46b") (:authors ("Lukas Lichtl" . "support@embed-me.com")) (:maintainer "Lukas Lichtl" . "support@embed-me.com") (:keywords "vunit" "python" "tools") (:url . "https://github.com/embed-me"))])
+ (vyper-mode . [(20180707 1935) ((emacs (24 3))) "Major mode for the Vyper programming language" single ((:commit . "323dfddfc38f0b11697e9ebaf04d1b53297e54e5") (:authors ("Alex Stokes" . "r.alex.stokes@gmail.com")) (:maintainer "Alex Stokes" . "r.alex.stokes@gmail.com") (:keywords "languages") (:url . "https://github.com/ralexstokes/vyper-mode"))])
+ (w32-browser . [(20170101 1954) nil "Run Windows application associated with a file." single ((:commit . "e5c60eafd8f8d3546a0fa295ad5af2414d36b4e6") (:authors ("Emacs Wiki, Drew Adams")) (:maintainer nil . "Drew Adams (concat \"drew.adams\" \"@\" \"oracle\" \".com\")") (:keywords "mouse" "dired" "w32" "explorer") (:url . "http://www.emacswiki.org/w32-browser.el"))])
+ (w32-ime . [(20201107 143) ((emacs (24 4))) "Windows IME UI/UX controler" single ((:commit . "9c62273dce0ba685a591577885b1e216ba832ec1") (:authors ("H.Miyashita") ("MIYOSHI Masanori") ("KOBAYASHI Yasuhiro") ("NTEmacsJP") ("ksugita (gnupack)") ("rzl24ozi") ("TANE") ("Masamichi Hosoda" . "trueroad@trueroad.jp") ("Naoya Yamashita" . "conao3@gmail.com")) (:maintainer "Masamichi Hosoda" . "trueroad@trueroad.jp") (:url . "https://github.com/trueroad/w32-ime.el"))])
+ (w3m . [(20220426 717) nil "an Emacs interface to w3m" tar ((:commit . "2420e7fb0d11372f1fa898a3b996bf2ce00fe66a") (:keywords "w3m" "www" "hypermedia"))])
+ (wacspace . [(20180311 2350) ((dash (1 2 0)) (cl-lib (0 2))) "The WACky WorkSPACE manager for emACS" tar ((:commit . "54d19aab6fd2bc5945b7ffc58104e695064927e2") (:authors ("Emanuel Evans" . "emanuel.evans@gmail.com")) (:maintainer "Emanuel Evans" . "emanuel.evans@gmail.com") (:keywords "workspace") (:url . "http://github.com/shosti/wacspace.el"))])
+ (waf-mode . [(20170403 1940) nil "Waf integration for Emacs" single ((:commit . "20c75eabd1d54fbce8e0dbef785c9fb68577ee4f") (:authors ("Denys Valchuk" . "dvalchuk@gmail.com")) (:maintainer "Denys Valchuk" . "dvalchuk@gmail.com") (:url . "https://bitbucket.org/dvalchuk/waf-mode"))])
+ (waher-theme . [(20141115 1230) ((emacs (24 1))) "Emacs 24 theme based on waher for st2 by dduckster" single ((:commit . "60d31519fcfd8e797723d47961b255ae2f2e2c0a") (:authors ("Jasonm23" . "jasonm23@gmail.com")) (:maintainer "Jasonm23" . "jasonm23@gmail.com") (:url . "https://github.com/jasonm23/emacs-waher-theme"))])
+ (wakatime-mode . [(20211104 1455) nil "Automatic time tracking extension for WakaTime" single ((:commit . "a53c0e819258ea9dbea3ad64b16e4c6c6201f5a5") (:authors ("Gabor Torok" . "gabor@20y.hu")) (:maintainer "Alan Hamlett" . "alan@wakatime.com") (:keywords "calendar" "comm"))])
+ (wakib-keys . [(20220211 1304) ((emacs (24 4))) "Minor Mode for Modern Keybindings" single ((:commit . "ed86134f91c532a38d2739dd15ea6cec879cbd8a") (:authors ("Abdulla Bubshait")) (:maintainer "Abdulla Bubshait") (:keywords "convenience" "keybindings" "keys") (:url . "https://github.com/darkstego/wakib-keys/"))])
+ (wal-mode . [(20220409 1214) ((emacs (25 1))) "A major mode for the WAL programming language" single ((:commit . "1daaf882824e8483419dc999c2d5507ad30cc929") (:authors ("Lucas Klemmer" . "lucas.klemmer@jku.at")) (:maintainer "Lucas Klemmer" . "lucas.klemmer@jku.at") (:keywords "languages") (:url . "https://github.com/LucasKl/wal-major-mode"))])
+ (walkclj . [(20220422 854) ((emacs (25)) (parseclj (0 1 0)) (treepy (0 1 0))) "Manipulate Clojure parse trees" single ((:commit . "ce4e7713d801b03f94f5da9898fce09718380ed4") (:authors ("Arne Brasseur")) (:maintainer "Arne Brasseur") (:keywords "languages") (:url . "https://github.com/plexus/walkclj"))])
+ (walkman . [(20220318 2122) ((transient (0 1 0)) (org (8 3 5)) (json-mode (1 6 0)) (emacs (26 3))) "Write HTTP requests in Org mode" single ((:commit . "3118dd4f493caffcc2849058833572dfc0c0e0a9") (:authors ("Adrien Brochard")) (:maintainer "Adrien Brochard") (:keywords "walkman" "http" "curl" "org" "comm") (:url . "https://github.com/abrochard/walkman"))])
+ (wallpaper . [(20201019 2123) ((emacs (25 1))) "Setting the wallpaper" single ((:commit . "cc0101726dd2fa2b4eda06924c7abfae54f663e2") (:authors ("Farlado" . "farlado@sdf.org")) (:maintainer "Farlado" . "farlado@sdf.org") (:keywords "unix" "wallpaper" "extensions") (:url . "https://github.com/farlado/emacs-wallpaper"))])
+ (wallpreview . [(20220220 427) ((emacs (24 4))) "Set wallpapers with image-dired" single ((:commit . "b1b8f19ae82b344a9577cea7b883ad513ec52222") (:url . "https://github.com/nryotaro/wallpreview"))])
+ (wand . [(20210511 725) ((dash (2 15 0)) (s (0 1 1))) "Magic wand for Emacs - Select and execute" tar ((:commit . "08c3d9156517a31dd98ea64bfc269fae730b643c") (:authors ("Ha-Duong Nguyen <cmpitgATgmail>")) (:maintainer "Ha-Duong Nguyen <cmpitgATgmail>") (:keywords "extensions" "tools") (:url . "https://github.com/cmpitg/wand"))])
+ (wandbox . [(20170603 1231) ((emacs (24)) (request (0 3 0)) (s (1 10 0))) "Wandbox client" tar ((:commit . "e002fe41f2cd9b4ce2b1dc80b83301176e9117f1") (:authors ("KOBAYASHI Shigeru (kosh)" . "shigeru.kb@gmail.com")) (:maintainer "KOBAYASHI Shigeru (kosh)" . "shigeru.kb@gmail.com") (:keywords "tools") (:url . "https://github.com/kosh04/emacs-wandbox"))])
+ (wanderlust . [(20220429 549) ((emacs (24 5)) (apel (10 8)) (flim (1 14 9)) (semi (1 14 7))) "Yet Another Message Interface on Emacsen" tar ((:commit . "a341b43e5e5fc97a14d1c9fc7d8e92490a8b7a0a"))])
+ (warm-night-theme . [(20161101 1428) ((emacs (24))) "Emacs 24 theme with a dark background." single ((:commit . "020f084d23409b5035150508ba6e57c2509edd64") (:authors ("martin haesler")) (:maintainer "martin haesler"))])
+ (watch-buffer . [(20120331 2044) nil "run a shell command when saving a buffer" single ((:commit . "761fd7252e6d7bf5148283c2a7ee935f087d9427") (:authors ("Michael Steger" . "mjsteger1@gmail.com")) (:maintainer "Michael Steger" . "mjsteger1@gmail.com") (:keywords "automation" "convenience") (:url . "https://github.com/mjsteger/watch-buffer"))])
+ (wavefront-obj-mode . [(20170808 1716) nil "Major mode for Wavefront obj files" single ((:commit . "34027915de6496460d8e68b5991dd24d47d54859") (:authors ("Sasha Kovar" . "sasha-emacs@arcocene.org")) (:maintainer "Sasha Kovar" . "sasha-emacs@arcocene.org") (:url . "http://github.com/abend/wavefront-obj-mode"))])
+ (wc-goal-mode . [(20140829 1359) nil "Running word count with goals (minor mode)" single ((:commit . "bf21ab9c5a449bcc20dd207a4915dcec218d2699") (:authors ("Benjamin Beckwith")) (:maintainer "Benjamin Beckwith") (:url . "https://github.com/bnbeckwith/wc-goal-mode"))])
+ (wc-mode . [(20210418 47) ((emacs (24 1))) "Running word count with goals (minor mode)" single ((:commit . "63be1433b8a63cdc3239cc751e36360429c42b51") (:authors ("Benjamin Beckwith")) (:maintainer "Benjamin Beckwith") (:url . "https://github.com/bnbeckwith/wc-mode"))])
+ (wdl-mode . [(20180831 1946) nil "WDL (Workflow Definition Language) major mode" single ((:commit . "cef86e5afc136ae5ad9324cd6e6d6f860b889bcf") (:authors ("Xiaowei Zhan" . "zhanxw@gmail.com")) (:maintainer "Xiaowei Zhan" . "zhanxw@gmail.com") (:keywords "languages") (:url . "http://github.com/zhanxw/wdl-mode"))])
+ (weak-ref . [(20200217 2200) ((emacs (24 3))) "Weak references for Emacs Lisp" single ((:commit . "24e8c37da6465e65ce9f866267bd3fa53c8899c6") (:authors ("Christopher Wellons" . "wellons@nullprogram.com")) (:maintainer "Christopher Wellons" . "wellons@nullprogram.com") (:url . "https://github.com/skeeto/elisp-weak-ref"))])
+ (weather-metno . [(20150901 107) ((emacs (24)) (cl-lib (0 3))) "Weather data from met.no in Emacs" tar ((:commit . "bfc7137095e0ee71aad70ac46f2af677f3c051b6") (:authors ("Rüdiger Sonderfeld" . "ruediger@c-plusplus.de")) (:maintainer "Rüdiger Sonderfeld" . "ruediger@c-plusplus.de") (:keywords "comm") (:url . "https://github.com/ruediger/weather-metno-el"))])
+ (web . [(20141231 2001) ((dash (2 9 0)) (s (1 5 0))) "useful HTTP client" single ((:commit . "483188dac4bc6b409b985c9dae45f3324a425efd") (:authors ("Nic Ferrier" . "nferrier@ferrier.me.uk")) (:maintainer "Nic Ferrier" . "nferrier@ferrier.me.uk") (:keywords "lisp" "http" "hypermedia") (:url . "http://github.com/nicferrier/emacs-web"))])
+ (web-beautify . [(20161115 2247) nil "Format HTML, CSS and JavaScript/JSON" single ((:commit . "e1b45321d8c11b404b12c8e55afe55eaa7c84ee9") (:authors ("Yasuyuki Oka" . "yasuyk@gmail.com")) (:maintainer "Yasuyuki Oka" . "yasuyk@gmail.com") (:url . "https://github.com/yasuyk/web-beautify"))])
+ (web-completion-data . [(20160318 848) nil "Shared completion data for ac-html and company-web" tar ((:commit . "c272c94e8a71b779c29653a532f619acad433a4f") (:authors ("Olexandr Sydorchuk" . "olexandr.syd@gmail.com")) (:maintainer "Olexandr Sydorchuk" . "olexandr.syd@gmail.com") (:keywords "html" "auto-complete" "company") (:url . "https://github.com/osv/web-completion-data"))])
+ (web-mode . [(20220319 653) ((emacs (23 1))) "major mode for editing web templates" single ((:commit . "efa853e5cfff8e0bcacbda9d1c6696b33da91b03") (:authors ("François-Xavier Bois")) (:maintainer "François-Xavier Bois" . "fxbois@gmail.com") (:keywords "languages") (:url . "https://web-mode.org"))])
+ (web-mode-edit-element . [(20190531 852) ((emacs (24 4)) (web-mode (14))) "Helper-functions for attribute- and element-handling" tar ((:commit . "ad5d7e4dc2420bdd00ce65d9adffbd38a5904afa") (:authors ("Julian T. Knabenschuh" . "jtkdevelopments@gmail.com")) (:maintainer "Julian T. Knabenschuh" . "jtkdevelopments@gmail.com") (:keywords "languages" "convenience") (:url . "https://github.com/jtkDvlp/web-mode-edit-element"))])
+ (web-narrow-mode . [(20170407 210) ((web-mode (14 0 27))) "quick narrow code block in web-mode" single ((:commit . "73bdcb7d0701abe65dab4fc295d944885e05ae33") (:authors ("Qquanwei" . "quanwei9958@126.com")) (:maintainer "Johan Andersson" . "quanwei9958@126.com") (:keywords "web-mode" "react" "narrow" "web") (:url . "https://github.com/Qquanwei/web-narrow-mode"))])
+ (web-search . [(20190620 602) ((emacs (24 3))) "Open a web search" tar ((:commit . "a22cbdc663a1895d5a5b69de91e1e3b9eb64b92f") (:authors ("Xu Chunyang" . "mail@xuchunyang.me")) (:maintainer "Xu Chunyang" . "mail@xuchunyang.me") (:keywords "web" "search") (:url . "https://github.com/xuchunyang/web-search.el"))])
+ (web-server . [(20210708 2242) ((emacs (24 1)) (cl-lib (0 6))) "Emacs Web Server" tar ((:commit . "6357a1c2d1718778503f7ee0909585094117525b") (:authors ("Eric Schulte" . "schulte.eric@gmail.com")) (:maintainer "Eric Schulte" . "schulte.eric@gmail.com") (:keywords "http" "server" "network") (:url . "https://github.com/eschulte/emacs-web-server"))])
+ (webkit-color-picker . [(20180325 736) ((emacs (26 0)) (posframe (0 1 0))) "Insert and adjust colors using Webkit Widgets" tar ((:commit . "765cac80144cad4bc0bf59025ea0199f0486f737") (:authors ("Ozan Sener" . "hi@ozan.email")) (:maintainer "Ozan Sener" . "hi@ozan.email") (:keywords "tools") (:url . "https://github.com/osener/emacs-webkit-color-picker"))])
+ (weblio . [(20210718 1410) ((request (0 3 3)) (emacs (25 1))) "Look up Japanese words on Weblio.jp" single ((:commit . "2b4b0c206440b5c63960214feacfceb0c26231c7") (:authors ("Simon Zelazny")) (:maintainer "Simon Zelazny") (:keywords "langauges" "i18n") (:url . "https://github.com/pzel/weblio"))])
+ (weblogger . [(20110926 1618) ((xml-rpc (1 6 8))) "Weblog maintenance via XML-RPC APIs" single ((:commit . "b3dd4aead9d3a87e6d85e7fef4f4f3bd40d87b53") (:keywords "weblog" "blogger" "cms" "movable" "type" "openweblog" "blog") (:url . "http://launchpad.net/weblogger-el"))])
+ (weblorg . [(20220312 2008) ((templatel (0 1 6)) (emacs (26 1))) "Static Site Generator for org-mode" tar ((:commit . "b2bb79ed2c532cad5b03455d8cae887ddb803db3") (:authors ("Lincoln Clarete" . "lincoln@clarete.li")) (:maintainer "Lincoln Clarete" . "lincoln@clarete.li") (:url . "https://emacs.love/weblorg"))])
+ (webpaste . [(20211211 658) ((emacs (24 4)) (request (0 2 0)) (cl-lib (0 5))) "Paste to pastebin-like services" single ((:commit . "78272662e6992b8614e79a571ff2395fa9630357") (:authors ("Elis \"etu\" Hirwing" . "elis@hirwing.se")) (:maintainer "Elis \"etu\" Hirwing" . "elis@hirwing.se") (:keywords "convenience" "comm" "paste") (:url . "https://github.com/etu/webpaste.el"))])
+ (websocket . [(20210110 17) ((cl-lib (0 5))) "Emacs WebSocket client and server" single ((:commit . "82b370602fa0158670b1c6c769f223159affce9b") (:authors ("Andrew Hyatt" . "ahyatt@gmail.com")) (:maintainer "Andrew Hyatt" . "ahyatt@gmail.com") (:keywords "communication" "websocket" "server") (:url . "https://github.com/ahyatt/emacs-websocket"))])
+ (wedge-ws . [(20140714 2149) nil "Wedge whitespace between columns in text" single ((:commit . "4669115f02d9c6fee067cc5369bb38c0f9db88b2") (:authors ("Anders Eurenius" . "aes@spotify.com")) (:maintainer "Anders Eurenius" . "aes@spotify.com") (:keywords "formatting" "indentation"))])
+ (weechat . [(20190520 1551) ((s (1 3 1)) (cl-lib (0 2)) (emacs (24)) (tracking (1 2))) "Chat via WeeChat's relay protocol in Emacs" tar ((:commit . "d9a13306ea8be27367f92e9202d116a88fa1f441") (:authors ("Moritz Ulrich" . "moritz@tarn-vedra.de") ("Rüdiger Sonderfeld" . "ruediger@c-plusplus.de") ("Aristid Breitkreuz" . "aristidb@gmail.com")) (:maintainer "Moritz Ulrich" . "moritz@tarn-vedra.de") (:keywords "irc" "chat" "network" "weechat") (:url . "https://github.com/the-kenny/weechat.el"))])
+ (weechat-alert . [(20160416 1248) ((weechat (0 3 1)) (cl-lib (0 5)) (alert (1 2))) "Weechat notifier using alerts" single ((:commit . "a8fd557c8f335322f132c1c6c08b6741d6394e2e") (:authors ("Andreas Klein" . "git@kungi.org")) (:maintainer "Andreas Klein" . "git@kungi.org") (:keywords "irc" "chat" "network" "weechat") (:url . "https://github.com/kungi/weechat-alert"))])
+ (weibo . [(20150307 2242) ((cl-lib (0 5))) "Weibo client for Emacs" tar ((:commit . "a8abb50b7602fe15fe2bc6400ac29780e956b390") (:authors ("Austin" . "austiny.cn@gmail.com")) (:maintainer "Austin" . "austiny.cn@gmail.com") (:keywords "weibo") (:url . "https://github.com/austin-----/weibo.emacs"))])
+ (weyland-yutani-theme . [(20210802 2251) ((emacs (24 1))) "Emacs theme based off Alien movie franchise" single ((:commit . "e89a63a62e071180c9cdd9067679fadc3f7bf796") (:authors ("Joe Staursky")) (:maintainer "Joe Staursky") (:url . "https://github.com/jstaursky/weyland-yutani-theme"))])
+ (wgrep . [(20210322 2207) nil "Writable grep buffer and apply the changes to files" single ((:commit . "f9687c28bbc2e84f87a479b6ce04407bb97cfb23") (:authors ("Masahiro Hayashi" . "mhayashi1120@gmail.com")) (:maintainer "Masahiro Hayashi" . "mhayashi1120@gmail.com") (:keywords "grep" "edit" "extensions") (:url . "http://github.com/mhayashi1120/Emacs-wgrep/raw/master/wgrep.el"))])
+ (wgrep-ack . [(20200128 109) ((wgrep (2 1 1))) "Writable ack-and-a-half buffer and apply the changes to files" single ((:commit . "f9687c28bbc2e84f87a479b6ce04407bb97cfb23") (:authors ("Masahiro Hayashi" . "mhayashi1120@gmail.com")) (:maintainer "Masahiro Hayashi" . "mhayashi1120@gmail.com") (:keywords "grep" "edit" "extensions") (:url . "http://github.com/mhayashi1120/Emacs-wgrep/raw/master/wgrep-ack.el"))])
+ (wgrep-ag . [(20200217 1028) ((wgrep (2 3 2))) "Writable ag buffer and apply the changes to files" single ((:commit . "f9687c28bbc2e84f87a479b6ce04407bb97cfb23") (:authors ("Masahiro Hayashi" . "mhayashi1120@gmail.com")) (:maintainer "Masahiro Hayashi" . "mhayashi1120@gmail.com") (:keywords "grep" "edit" "extensions") (:url . "http://github.com/mhayashi1120/Emacs-wgrep/raw/master/wgrep-ag.el"))])
+ (wgrep-helm . [(20210322 2148) ((wgrep (2 1 1))) "Writable helm-grep-mode buffer and apply the changes to files" single ((:commit . "f9687c28bbc2e84f87a479b6ce04407bb97cfb23") (:authors ("Masahiro Hayashi" . "mhayashi1120@gmail.com")) (:maintainer "Masahiro Hayashi" . "mhayashi1120@gmail.com") (:keywords "grep" "edit" "extensions") (:url . "http://github.com/mhayashi1120/Emacs-wgrep/raw/master/wgrep-helm.el"))])
+ (wgrep-pt . [(20200128 109) ((wgrep (2 1 5))) "Writable pt buffer and apply the changes to files" single ((:commit . "f9687c28bbc2e84f87a479b6ce04407bb97cfb23") (:authors ("Masahiro Hayashi <mhayashi1120@gmail.com>, Bailey Ling" . "bling@live.ca")) (:maintainer "Masahiro Hayashi <mhayashi1120@gmail.com>, Bailey Ling" . "bling@live.ca") (:keywords "grep" "edit" "extensions") (:url . "http://github.com/mhayashi1120/Emacs-wgrep/raw/master/wgrep-pt.el"))])
+ (what-the-commit . [(20150901 1316) nil "Random commit message generator" single ((:commit . "868c80a1b8614bcbd2225cd0290142c72f2a7956") (:authors ("Dan Barbarito" . "dan@barbarito.me")) (:maintainer "Dan Barbarito" . "dan@barbarito.me") (:keywords "git" "commit" "message") (:url . "http://barbarito.me/"))])
+ (which-key . [(20220419 227) ((emacs (24 4))) "Display available keybindings in popup" single ((:commit . "129f4ebfc74f207ac82978f6d90d8b4bb1a55cf9") (:authors ("Justin Burkett" . "justin@burkett.cc")) (:maintainer "Justin Burkett" . "justin@burkett.cc") (:url . "https://github.com/justbur/emacs-which-key"))])
+ (which-key-posframe . [(20210615 944) ((emacs (26 0)) (posframe (0 4 3)) (which-key (3 3 2))) "Using posframe to show which-key" single ((:commit . "90e85d74899fc23d95798048cc0bbdb4bab9c1b7") (:authors ("Yanghao Xie")) (:maintainer "Yanghao Xie" . "yhaoxie@gmail.com") (:keywords "convenience" "bindings" "tooltip") (:url . "https://github.com/yanghaoxie/which-key-posframe"))])
+ (whiley-mode . [(20220501 2219) ((emacs (24 1))) "Major mode for Whiley language" single ((:commit . "69eb67cf41dad029f1456079aea62a4b61ca9b46") (:authors ("David J. Pearce" . "dave01001110@gmail.com")) (:maintainer "David J. Pearce" . "dave01001110@gmail.com") (:keywords "languages") (:url . "http://github.com/Whiley/WhileyEmacsMode"))])
+ (whitaker . [(20210203 1149) ((emacs (25))) "Comint interface for Whitaker's Words" single ((:commit . "a6fda24ccb69a18c0706633326d5cc4fcfaed83a") (:authors ("Matus Goljer" . "matus.goljer@gmail.com")) (:maintainer "Matus Goljer" . "matus.goljer@gmail.com") (:keywords "processes"))])
+ (white-sand-theme . [(20210131 813) ((emacs (24))) "Emacs theme with a light background." single ((:commit . "729dd52cc1936250183d6761eed406c4be514a71") (:authors ("Martin Haesler")) (:maintainer "Martin Haesler"))])
+ (white-theme . [(20160917 1743) ((emacs (24))) "Minimalistic light color theme inspired by basic-theme" single ((:commit . "e9e6d5b9d43da6eb15e86f5fbc8b1ba83abe8c78") (:authors ("Anler Hernandez Peral" . "inbox@anler.me")) (:maintainer "Anler Hernandez Peral" . "inbox@anler.me") (:keywords "color" "theme" "minimal" "basic" "simple" "white") (:url . "http://github.com/anler/white-theme.el"))])
+ (whitespace-cleanup-mode . [(20210510 533) ((emacs (24 1))) "Intelligently call whitespace-cleanup on save" single ((:commit . "b2e35321f03914cae90be4f942d911b7e7175899") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:keywords "convenience") (:url . "https://github.com/purcell/whitespace-cleanup-mode"))])
+ (whizzml-mode . [(20201013 239) ((emacs (24 4))) "Programming mode for editing WhizzML files" tar ((:commit . "3dce3be0c32b9b2d259e462b4b27c530af47466a") (:authors ("Jose Antonio Ortega Ruiz" . "jao@bigml.com")) (:maintainer "Jose Antonio Ortega Ruiz" . "jao@bigml.com") (:keywords "languages" "lisp"))])
+ (whois . [(20211104 812) ((emacs (24))) "Syntax highlighted domain name queries using system whois" single ((:commit . "f22244202fdac5064d5eff95c6f35ae887b01142") (:authors ("Lassi Kortela" . "lassi@lassi.io")) (:maintainer "Lassi Kortela" . "lassi@lassi.io") (:keywords "network" "comm") (:url . "https://github.com/lassik/emacs-whois"))])
+ (whole-line-or-region . [(20201214 650) ((emacs (24 1)) (cl-lib (0 6))) "Operate on current line if region undefined" single ((:commit . "500ad90695e8a5a0cefabb7500158eab0835a0ce") (:authors ("Joe Casadonte" . "emacs@northbound-train.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:keywords "convenience" "wp") (:url . "https://github.com/purcell/whole-line-or-region"))])
+ (why-this . [(20220429 1227) ((emacs (27 2))) "Why is this line here? Ask version control" single ((:commit . "b69263c66b63680e1db81f6da98de00c230c7384") (:authors ("Akib Azmain Turja" . "akib@disroot.org")) (:maintainer "Akib Azmain Turja" . "akib@disroot.org") (:keywords "tools" "convenience" "vc") (:url . "https://codeberg.org/akib/emacs-why-this"))])
+ (wide-column . [(20170925 1613) nil "Calls functions dependant on column position." single ((:commit . "ce9ef4675485a7bea381077866368ef875226b10") (:authors ("Phillip Lord" . "p.lord@russet.org.uk")) (:maintainer "Phillip Lord" . "p.lord@russet.org.uk") (:keywords "minor mode" "cursor colour" "column width"))])
+ (widget-mvc . [(20150102 406) nil "MVC framework for the emacs widgets" single ((:commit . "ff5a85880df7b87f9f480fe3c28438a0712b7b87") (:authors ("SAKURAI Masashi <m.sakurai at kiwanami.net>")) (:maintainer "SAKURAI Masashi <m.sakurai at kiwanami.net>") (:keywords "lisp" "widget"))])
+ (wiki-nav . [(20200309 1323) ((button-lock (1 0 2)) (nav-flash (1 0 0))) "Simple file navigation using [[WikiStrings]]" single ((:commit . "9afe0f4d05910b0cccc94cb6d4d880119f3b0528") (:authors ("Roland Walker" . "walker@pobox.com")) (:maintainer "Roland Walker" . "walker@pobox.com") (:keywords "mouse" "button" "hypermedia" "navigation") (:url . "http://github.com/rolandwalker/button-lock"))])
+ (wiki-summary . [(20181010 1824) ((emacs (24))) "View Wikipedia summaries in Emacs easily." single ((:commit . "fa41ab6e50b3b80e54148af9d4bac18fd0405000") (:authors ("Danny Gratzer")) (:maintainer "Danny Gratzer") (:keywords "wikipedia" "utility") (:url . "https://github.com/jozefg/wiki-summary.el"))])
+ (wikinfo . [(20220121 2017) ((emacs (27 1))) "Scrape Wikipedia Infoboxes" single ((:commit . "b149228023d4abb29555ce69877df521887cafe9") (:authors ("Nicholas Vollmer" . "progfolio@protonmail.com")) (:maintainer "Nicholas Vollmer" . "progfolio@protonmail.com") (:keywords "org" "convenience") (:url . "https://github.com/progfolio/wikinfo"))])
+ (wikinforg . [(20220322 946) ((emacs (27 1)) (wikinfo (0 0 0)) (org (9 3))) "Org-mode wikinfo integration" single ((:commit . "9a5bfe36d59dc845b8da1951bed327f3a9071534") (:authors ("Nicholas Vollmer" . "progfolio@protonmail.com")) (:maintainer "Nicholas Vollmer" . "progfolio@protonmail.com") (:keywords "org" "convenience") (:url . "https://github.com/progfolio/wikinforg"))])
+ (wilt . [(20180220 854) ((emacs (24 3)) (dash (2 12 0)) (s (1 10 0))) "An extensions for calculating WILT in a buffer." single ((:commit . "04dbe37fa35d0b24c791421785d2c97a8cbfe2cc") (:authors ("Austin Bingham" . "austin@sixty-north.com")) (:maintainer "Austin Bingham" . "austin@sixty-north.com") (:url . "https://github.com/sixty-north/emacs-wilt"))])
+ (win-switch . [(20161009 1627) nil "fast, dynamic bindings for window-switching/resizing" single ((:commit . "954eb5e4c5737f0c06368c42a7f1c3dd374d782f") (:authors ("Christopher Genovese" . "genovese@cmu.edu")) (:maintainer "Christopher R. Genovese" . "genovese@cmu.edu") (:keywords "window" "switch" "key bindings" "ergonomic" "efficient") (:url . "http://www.stat.cmu.edu/~genovese/emacs/win-switch/"))])
+ (windata . [(20090830 1040) nil "convert window configuration to list" single ((:commit . "a723fc446ceaec23d5f29ecc8245d94c99d91625") (:authors (nil . "wenbinye@gmail.com")) (:maintainer nil . "wenbinye@gmail.com") (:keywords "convenience" "frames"))])
+ (window-end-visible . [(20140508 2041) nil "Find the last visible point in a window" single ((:commit . "525500fb2ebc08f3f9ea493972e5f2e1d79f89ef") (:authors ("Roland Walker" . "walker@pobox.com")) (:maintainer "Roland Walker" . "walker@pobox.com") (:keywords "extensions") (:url . "http://github.com/rolandwalker/window-end-visible"))])
+ (window-jump . [(20170809 2208) nil "Move left/right/up/down through your windows." single ((:commit . "6bdb51e9a346907d60a9625f6180bddd06be6674") (:authors ("Steven Thomas")) (:maintainer "Steven Thomas") (:keywords "frames" "convenience") (:url . "https://github.com/chumpage/chumpy-windows"))])
+ (window-layout . [(20170215 33) nil "window layout manager" single ((:commit . "cd2e4f967b610c2bbef53182829e47250d027056") (:authors ("SAKURAI Masashi <m.sakurai atmark kiwanami.net>")) (:maintainer "SAKURAI Masashi <m.sakurai atmark kiwanami.net>") (:keywords "window" "layout"))])
+ (window-number . [(20170801 151) nil "Select windows by numbers." single ((:commit . "d41722de646ffeb3f70d26e4a86a5a1ba5c6be87") (:authors ("Johann \"Myrkraverk\" Oskarsson" . "myrkraverk@users.sourceforge.net")) (:maintainer "Nik Nyby" . "niknyby@riseup.net") (:keywords "windows") (:url . "https://github.com/nikolas/window-number"))])
+ (window-numbering . [(20160809 1810) nil "Numbered window shortcuts" single ((:commit . "10809b3993a97c7b544240bf5d7ce9b1110a1b89") (:authors ("Nikolaj Schumacher <bugs * nschum de>")) (:maintainer "Nikolaj Schumacher <bugs * nschum de>") (:keywords "faces" "matching") (:url . "http://nschum.de/src/emacs/window-numbering-mode/"))])
+ (window-purpose . [(20210628 715) ((emacs (24 4)) (let-alist (1 0 3)) (imenu-list (0 1))) "Purpose-based window management for Emacs" tar ((:commit . "bb462f12f836414425edac32ebd069b4fd5b98d4") (:authors ("Bar Magal")) (:maintainer "Bar Magal") (:keywords "frames") (:url . "https://github.com/bmag/emacs-purpose"))])
+ (winds . [(20201121 123) ((emacs (25 1))) "Window configuration switcher grouped by workspaces" single ((:commit . "5827e890059d0ce67ebb4779da63c15afccf0973") (:authors ("Javier A. Pollak" . "javi.po.123@gmail.com")) (:maintainer "Javier A. Pollak" . "javi.po.123@gmail.com") (:keywords "convenience") (:url . "https://github.com/Javyre/winds.el"))])
+ (windsize . [(20181029 2257) nil "Simple, intuitive window resizing" single ((:commit . "62c2846bbe95b0a73e996c75e4a644d05f57aaaa") (:authors ("Chris Perkins" . "chrisperkins99@gmail.com")) (:maintainer "Chris Perkins" . "chrisperkins99@gmail.com") (:keywords "window" "resizing" "convenience") (:url . "http://github.com/grammati/windsize"))])
+ (windswap . [(20200722 411) ((emacs (24 3))) "Like windmove, but swaps buffers while moving point" single ((:commit . "1a334f6543e0a30c55ea1e6071e9732d948f9e4b") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:keywords "frames" "convenience") (:url . "https://github.com/purcell/windswap"))])
+ (windwow . [(20170816 148) ((dash (2 11 0)) (cl-lib (0 6 1)) (emacs (24))) "simple workspace management" single ((:commit . "77bad26f651744b68d31b389389147014d250f23") (:authors ("Viju Mathew" . "viju.jm@gmail.com")) (:maintainer "Viju Mathew" . "viju.jm@gmail.com") (:keywords "frames") (:url . "github.com/vijumathew/windwow"))])
+ (winnow . [(20210105 1919) ((emacs (24))) "winnow ag/grep results by matching/excluding lines" single ((:commit . "761b15bc31696a4f80c5fd508c84b1f5b4190ec2") (:authors ("Charles L.G. Comstock" . "dgtized@gmail.com")) (:maintainer "Charles L.G. Comstock" . "dgtized@gmail.com") (:keywords "matching") (:url . "https://github.com/dgtized/winnow.el"))])
+ (winpoint . [(20131023 1713) nil "Remember buffer positions per-window, not per buffer" single ((:commit . "e6050093c076308184566fa1d1012423d6934773") (:authors ("Jorgen Schaefer" . "forcer@forcix.cx")) (:maintainer "Jorgen Schaefer" . "forcer@forcix.cx") (:keywords "convenience") (:url . "https://github.com/jorgenschaefer/winpoint"))])
+ (winring . [(20180530 18) nil "Window configuration rings" single ((:commit . "f2d072bd446b73e93b127523f19ea82b99b9267f") (:authors ("1997-2018 Barry A. Warsaw")) (:maintainer "1997-2018 Barry A. Warsaw") (:keywords "frames" "tools") (:url . "https://gitlab.com/warsaw/winring"))])
+ (winum . [(20190911 1607) ((cl-lib (0 5)) (dash (2 13 0))) "Navigate windows and frames using numbers." single ((:commit . "c5455e866e8a5f7eab6a7263e2057aff5f1118b9") (:authors ("Thomas de Beauchêne" . "thomas.de.beauchene@gmail.com")) (:maintainer "Thomas de Beauchêne" . "thomas.de.beauchene@gmail.com") (:keywords "convenience" "frames" "windows" "multi-screen") (:url . "http://github.com/deb0ch/winum.el"))])
+ (wisp-mode . [(20220208 636) ((emacs (24 4))) "Tools for wisp: the Whitespace-to-Lisp preprocessor" single ((:commit . "d266109b95e73281ae3aa1ed9a023346b6d39d28") (:authors ("Arne Babenhauserheide" . "arne_bab@web.de")) (:maintainer "Arne Babenhauserheide" . "arne_bab@web.de") (:keywords "languages" "lisp" "scheme") (:url . "http://www.draketo.de/english/wisp"))])
+ (wispjs-mode . [(20170720 1919) ((clojure-mode (0))) "Major mode for Wisp code." single ((:commit . "60f9f5fd9d1556e2d008939f67eb1b1d0f325fa8") (:authors ("Kris Jenkins" . "krisajenkins@gmail.com")) (:maintainer "Kris Jenkins" . "krisajenkins@gmail.com") (:url . "https://github.com/krisajenkins/wispjs-mode"))])
+ (with-editor . [(20220503 1124) ((emacs (25 1)) (compat (28 1 1 0))) "Use the Emacsclient as $EDITOR" tar ((:commit . "48996e3116dadee06c8c68b1a0fe6ad8fd5317e0") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:keywords "processes" "terminals") (:url . "https://github.com/magit/with-editor"))])
+ (with-emacs . [(20200210 1543) ((emacs (24 4))) "Evaluate Emacs Lisp expressions in a separate Emacs process" single ((:commit . "9f99bec56f87e53deb9f33b364eda77677a17eb9") (:authors ("Gong Qijian" . "gongqijian@gmail.com")) (:maintainer "Gong Qijian" . "gongqijian@gmail.com") (:keywords "tools") (:url . "https://github.com/twlz0ne/with-emacs.el"))])
+ (with-namespace . [(20130407 1822) ((dash (1 1 0)) (loop (1 1))) "interoperable elisp namespaces" single ((:commit . "8ac52da3a09cf46087720e30cf730d00f140cde6") (:authors ("Wilfred Hughes" . "me@wilfred.me.uk")) (:maintainer "Wilfred Hughes" . "me@wilfred.me.uk") (:keywords "namespaces"))])
+ (with-proxy . [(20200510 414) ((emacs (24 4))) "Evaluate expressions with proxy" single ((:commit . "93b1ed2f3060f305009fa71f4fb5bb10173a10e3") (:authors ("Gong Qijian" . "gongqijian@gmail.com")) (:maintainer "Gong Qijian" . "gongqijian@gmail.com") (:keywords "comm") (:url . "https://github.com/twlz0ne/with-proxy.el"))])
+ (with-shell-interpreter . [(20200828 1217) ((emacs (25 1)) (cl-lib (0 6 1))) "Helper for shell command APIs" single ((:commit . "3fd1ea892e44f7fe6f86df2b5c0a0a1e0f3913fa") (:keywords "processes" "terminals") (:url . "https://github.com/p3r7/with-shell-interpreter"))])
+ (with-simulated-input . [(20210527 2320) ((emacs (24 4))) "A macro to simulate user input non-interactively" single ((:commit . "0f43fe46d4ab098c18a90b9df18cb96bab8e4a35") (:authors ("Ryan C. Thompson" . "rct@thompsonclan.org") ("Nikita Bloshchanevich" . "nikblos@outlook.com")) (:maintainer "Ryan C Thompson" . "rct@thompsonclan.org") (:keywords "lisp" "tools" "extensions") (:url . "https://github.com/DarwinAwardWinner/with-simulated-input"))])
+ (with-venv . [(20210925 2336) ((cl-lib (0 5)) (emacs (24 4))) "Execute with Python virtual environment activated" single ((:commit . "4a59ef8251f10ea772d4f504beeab08edf1f223e") (:authors ("10sr <8.slashes [at] gmail [dot] com>")) (:maintainer "10sr <8.slashes [at] gmail [dot] com>") (:keywords "processes" "python" "venv") (:url . "https://github.com/10sr/with-venv-el"))])
+ (wn-mode . [(20151110 552) ((emacs (24))) "numeric window switching shortcuts" single ((:commit . "f05c3151523e529af5a0a3fa8c948b61fb369f6e") (:authors ("Anonymous")) (:maintainer "Luís Oliveira" . "luismbo@gmail.com") (:keywords "buffers" "windows" "switching-windows") (:url . "https://github.com/luismbo/wn-mode"))])
+ (wolfram . [(20190805 1007) nil "Wolfram Alpha Integration" single ((:commit . "a172712d5045834f5434cca2843a7c3506805db8") (:authors ("Hans Sjunnesson" . "hans.sjunnesson@gmail.com")) (:maintainer "Hans Sjunnesson" . "hans.sjunnesson@gmail.com") (:keywords "math"))])
+ (wolfram-mode . [(20180307 13) ((emacs (24 3))) "Mathematica editing and inferior mode." single ((:commit . "be680190cac6ccf579dbce107deaae495928d1b3") (:authors ("Daichi Mochihashi <daichi at cslab.kecl.ntt.co.jp>")) (:maintainer "Daichi Mochihashi <daichi at cslab.kecl.ntt.co.jp>") (:keywords "languages" "processes" "tools") (:url . "https://github.com/kawabata/wolfram-mode/"))])
+ (wonderland . [(20130913 119) ((dash (2 0 0)) (dash-functional (1 0 0)) (multi (2 0 0)) (emacs (24))) "declarative configuration for Emacsen" single ((:commit . "89d274ad694b0e748efdac23ccd60b7d8b73d7c6") (:authors ("Christina Whyte" . "kurisu.whyte@gmail.com")) (:maintainer "Christina Whyte" . "kurisu.whyte@gmail.com") (:keywords "configuration" "profile" "wonderland") (:url . "http://github.com/kurisuwhyte/emacs-wonderland"))])
+ (wordel . [(20220225 1907) ((emacs (27 1))) "An Elisp implementation of \"Wordle\" (aka \"Lingo\")" tar ((:commit . "5a1f9a45c3d1fa58c3de5183c4456572ae861d49") (:authors ("Nicholas Vollmer" . "iarchivedmywholelife@gmail.com")) (:maintainer "Nicholas Vollmer" . "iarchivedmywholelife@gmail.com") (:keywords "games") (:url . "https://github.com/progfolio/wordel"))])
+ (wordgen . [(20170803 1820) ((emacs (24)) (cl-lib (0 5))) "Random word generator" single ((:commit . "aacad928ae99a953e034a831dfd0ebdf7d52ac1d") (:authors ("Fanael Linithien" . "fanael4@gmail.com")) (:maintainer "Fanael Linithien" . "fanael4@gmail.com") (:url . "https://github.com/Fanael/wordgen.el"))])
+ (wordnut . [(20180313 443) ((emacs (24 4))) "Major mode interface to WordNet" tar ((:commit . "feac531404041855312c1a046bde7ea18c674915"))])
+ (wordreference . [(20220504 2021) ((emacs (27 1)) (s (1 12 0))) "Interface for wordreference.com" single ((:commit . "30d2ddb9a0a4ad0223bae81ba56d65b620dccf0b") (:authors ("Marty Hiatt <martianhiatus AT riseup.net>")) (:maintainer "Marty Hiatt <martianhiatus AT riseup.net>") (:keywords "convenience" "translate") (:url . "https://codeberg.org/martianh/wordreference.el"))])
+ (wordsmith-mode . [(20210715 1517) nil "Syntax analysis and NLP text-processing in Emacs (OSX-only)" single ((:commit . "5d40ceaa2b8d41ab3634ca377ceb6a74deeb2287") (:authors ("istib" . "istib@thebati.net")) (:maintainer "istib" . "istib@thebati.net"))])
+ (worf . [(20220102 835) ((swiper (0 11 0)) (ace-link (0 1 0)) (hydra (0 13 0)) (zoutline (0 1 0))) "A warrior does not press so many keys! (in org-mode)" tar ((:commit . "8681241e118585824cd256e5b026978bf06c7e58") (:authors ("Oleh Krehel" . "ohwoeowho@gmail.com")) (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com") (:keywords "lisp") (:url . "https://github.com/abo-abo/worf"))])
+ (workgroups . [(20110726 1641) nil "workgroups for windows (for Emacs)" single ((:commit . "9572b3492ee09054dc329f64ed846c962b395e39") (:authors ("tlh" . "thunkout@gmail.com")) (:maintainer "tlh" . "thunkout@gmail.com") (:keywords "session" "management" "window-configuration" "persistence"))])
+ (workgroups2 . [(20220423 1150) ((emacs (25 1))) "save&load multiple named workspaces (or \"workgroups\")" tar ((:commit . "ccd6948c92ea21d0dec56dff029b3f46df408de5") (:authors ("Sergey Pashinin <sergey at pashinin dot com>")) (:maintainer "Sergey Pashinin <sergey at pashinin dot com>") (:keywords "session" "management" "window-configuration" "persistence") (:url . "https://github.com/pashinin/workgroups2"))])
+ (workroom . [(20220501 1500) ((emacs (27 2))) "Named rooms for work without irrelevant distracting buffers" single ((:commit . "001fe2777f49ac73b6ab24401094a1c3c5efc887") (:authors ("Akib Azmain Turja" . "akib@disroot.org")) (:maintainer "Akib Azmain Turja" . "akib@disroot.org") (:keywords "tools" "convenience") (:url . "https://codeberg.org/akib/emacs-workroom"))])
+ (world-time-mode . [(20140627 807) nil "show whole days of world-time diffs" single ((:commit . "ce7a3b45c87eb24cfe61eee453175d64f741d7cc") (:authors ("Nic Ferrier" . "nferrier@ferrier.me.uk")) (:maintainer "Nic Ferrier" . "nferrier@ferrier.me.uk") (:keywords "tools" "calendar"))])
+ (wotd . [(20170328 1948) ((emacs (24 4)) (org (8 2 10))) "Fetch word-of-the-day from multiple online sources" single ((:commit . "d2937a3d91e014f8028a1f33d21c18cc0b065a64") (:authors ("Junpeng Qiu" . "qjpchmail@gmail.com")) (:maintainer "Junpeng Qiu" . "qjpchmail@gmail.com") (:keywords "extensions"))])
+ (wrap-region . [(20140117 720) ((dash (1 0 3))) "Wrap text with punctation or tag" single ((:commit . "fbae9b0f106187af19823f1a6260b5c68b7252e6") (:authors ("Johan Andersson" . "johan.rejeep@gmail.com")) (:maintainer "Johan Andersson" . "johan.rejeep@gmail.com") (:keywords "speed" "convenience") (:url . "http://github.com/rejeep/wrap-region"))])
+ (writefreely . [(20190628 1606) ((emacs (24 3)) (org (9 0)) (ox-gfm (0 0)) (request (0 3))) "Push your Org files as markdown to a writefreely instance" single ((:commit . "83a487e48e0d8342c372deb74d04c0b43474268c") (:authors ("Daniel Gomez <d.gomez at posteo dot org>")) (:maintainer "Daniel Gomez <d.gomez at posteo dot org>") (:keywords "convenience") (:url . "https://github.com/dangom/writefreely.el"))])
+ (writegood-mode . [(20210418 110) nil "Polish up poor writing on the fly" single ((:commit . "ed42d918d98826ad88928b7af9f2597502afc6b0") (:authors ("Benjamin Beckwith")) (:maintainer "Benjamin Beckwith") (:keywords "writing" "weasel-words" "grammar") (:url . "http://github.com/bnbeckwith/writegood-mode"))])
+ (writeroom-mode . [(20220426 2046) ((emacs (25 1)) (visual-fill-column (2 2))) "Minor mode for distraction-free writing" tar ((:commit . "a736205c194d7525feb1e1f10f4186c7b2b62bef") (:authors ("Joost Kremers" . "joostkremers@fastmail.fm")) (:maintainer "Joost Kremers" . "joostkremers@fastmail.fm") (:keywords "text") (:url . "https://github.com/joostkremers/writeroom-mode"))])
+ (ws-butler . [(20201117 1528) nil "Unobtrusively remove trailing whitespace." single ((:commit . "e3a38d93e01014cd47bf5af4924459bd145fd7c4") (:authors ("Le Wang")) (:maintainer "Le Wang") (:url . "https://github.com/lewang/ws-butler"))])
+ (wsd-mode . [(20191031 1211) nil "Emacs major-mode for www.websequencediagrams.com" tar ((:commit . "53330a2a43c4875f8682457df1a869a4c9028660") (:authors ("Jostein Kjønigsen" . "jostein@gmail.com")) (:maintainer "Jostein Kjønigsen" . "jostein@gmail.com") (:keywords "wsd" "diagrams" "design" "process" "modelling" "uml") (:url . "https://github.com/josteink/wsd-mode"))])
+ (wttrin . [(20170614 1206) ((emacs (24 4)) (xterm-color (1 0))) "Emacs frontend for weather web service wttr.in" single ((:commit . "df5427ce2a5ad4dab652dbb1c4a1834d7ddc2abc") (:authors ("Carl X. Su" . "bcbcarl@gmail.com") ("ono hiroko (kuanyui)" . "azazabc123@gmail.com")) (:maintainer "Carl X. Su" . "bcbcarl@gmail.com") (:keywords "comm" "weather" "wttrin") (:url . "https://github.com/bcbcarl/emacs-wttrin"))])
+ (wucuo . [(20211201 1214) ((emacs (25 1))) "Fastest solution to spell check camel case code or plain text" tar ((:commit . "09fc58a02621b6c9615f8289c457e30ca6f63bcb") (:authors ("Chen Bin <chenbin DOT sh AT gmail DOT com>")) (:maintainer "Chen Bin <chenbin DOT sh AT gmail DOT com>") (:keywords "convenience") (:url . "http://github.com/redguardtoo/wucuo"))])
+ (wwg . [(20210614 1527) ((emacs (25 1))) "Writer word goals" single ((:commit . "46c8a7c71275ced2c662c1222d4b85319f80dd83") (:authors (nil . "Andrea andrea-dev@hotmail.com>")) (:maintainer nil . "Andrea andrea-dev@hotmail.com>") (:keywords "wp") (:url . "https://github.com/ag91/writer-word-goals"))])
+ (wwtime . [(20151122 1610) nil "Insert a time of day with appropriate world-wide localization" single ((:commit . "d04d8fa814b5d3644efaeb28f25520ada69acbbd") (:authors ("Norman Walsh" . "ndw@nwalsh.com")) (:maintainer "Norman Walsh" . "ndw@nwalsh.com") (:keywords "time"))])
+ (www-synonyms . [(20170128 2251) ((request (0 2 0)) (cl-lib (0 5))) "insert synonym for a word" single ((:commit . "7e37ea35064ff31c9945f0198a653647d408c936") (:authors ("Bernhard Specht" . "bernhard@specht.net")) (:maintainer "Bernhard Specht" . "bernhard@specht.net") (:keywords "lisp"))])
+ (x-path-walker . [(20201220 628) ((helm-core (1 9 2))) "Navigation feature for JSON/XML/HTML based on path (imenu like)" tar ((:commit . "e553968b6ddebe39ea00904a2e9ff4cff6096985") (:authors (nil . "<lompik@ArchOrion>")) (:maintainer nil . "<lompik@ArchOrion>") (:keywords "convenience"))])
+ (x509-mode . [(20210407 627) ((emacs (24 1)) (cl-lib (0 5))) "View certificates, CRLs and keys using OpenSSL." tar ((:commit . "470769edba111aed8eabce58a3f2a02da0767624") (:authors ("Fredrik Axelsson" . "f.axelsson@gmai.com")) (:maintainer "Fredrik Axelsson" . "f.axelsson@gmai.com") (:url . "https://github.com/jobbflykt/x509-mode"))])
+ (x86-lookup . [(20210412 2022) ((emacs (24 3)) (cl-lib (0 3))) "jump to x86 instruction documentation" single ((:commit . "1573d61cc4457737b94624598a891c837fb52c16") (:authors ("Christopher Wellons" . "wellons@nullprogram.com")) (:maintainer "Christopher Wellons" . "wellons@nullprogram.com") (:url . "https://github.com/skeeto/x86-lookup"))])
+ (xbm-life . [(20210508 1640) ((emacs (24 1))) "A XBM version of Conway's Game of Life" single ((:commit . "ec6abb0182068294a379cb49ad5346b1d757457d") (:authors ("Vasilij Schneidermann" . "mail@vasilij.de")) (:maintainer "Vasilij Schneidermann" . "mail@vasilij.de") (:keywords "games") (:url . "https://depp.brause.cc/xbm-life"))])
+ (xcode-mode . [(20160907 1208) ((emacs (24 4)) (s (1 10 0)) (dash (2 11 0)) (multiple-cursors (1 0 0))) "A minor mode for emacs to perform Xcode like actions." single ((:commit . "2ae4f512d6c601ea39d5ab785c2b5288eac24b59") (:authors ("Nickolas Lanasa" . "nick@nytekproductions.com")) (:maintainer "Nickolas Lanasa" . "nick@nytekproductions.com") (:keywords "conveniences"))])
+ (xcode-project . [(20200810 2010) ((emacs (25))) "A package for reading Xcode project files." tar ((:commit . "11743f0a2212c840a108e1b905b1f20afcff8156") (:authors ("John Buckley" . "john@olivetoast.com")) (:maintainer "John Buckley" . "john@olivetoast.com") (:keywords "languages" "tools") (:url . "https://github.com/nhojb/xcode-project.git"))])
+ (xcscope . [(20210719 828) nil "cscope interface for (X)Emacs" single ((:commit . "d228d7593d762e457340f678d14b663ef66d7cee") (:authors ("Darryl Okahata" . "darrylo@sonic.net") ("Dima Kogan" . "dima@secretsauce.net")) (:maintainer "Dima Kogan" . "dima@secretsauce.net") (:keywords "languages" "c") (:url . "https://github.com/dkogan/xcscope.el"))])
+ (xenops . [(20220421 1320) ((emacs (26 1)) (aio (1 0)) (auctex (12 2 0)) (avy (0 5 0)) (dash (2 18 0)) (f (0 20 0)) (s (1 12 0))) "A LaTeX editing environment for mathematical documents" tar ((:commit . "a2c685b3bb2257da49af771caa02325aa41fa699") (:authors ("Dan Davison" . "dandavison7@gmail.com")) (:maintainer "Dan Davison" . "dandavison7@gmail.com") (:url . "https://github.com/dandavison/xenops"))])
+ (xhair . [(20210801 222) ((emacs (24 3)) (vline (1 0))) "Highlight the current line and column" single ((:commit . "c7bd7c501c3545aa99dadac386c882fe7c5edd9c") (:keywords "convenience" "faces" "maint") (:url . "https://github.com/Boruch-Baum/emacs-xhair"))])
+ (xkcd . [(20220503 1109) ((json (1 3))) "View xkcd from Emacs" single ((:commit . "80011da2e7def8f65233d4e0d790ca60d287081d") (:authors ("Vibhav Pant" . "vibhavp@gmail.com")) (:maintainer "Vibhav Pant" . "vibhavp@gmail.com") (:keywords "xkcd" "webcomic") (:url . "https://github.com/vibhavp/emacs-xkcd"))])
+ (xmind-org . [(20201202 1605) ((emacs (27 1)) (org-ml (5 3)) (dash (2 12))) "Import XMind mindmaps into Org" single ((:commit . "ee09e382b3fefb67ccf3cd4db96a8dd2acc34045") (:authors ("Akira Komamura" . "akira.komamura@gmail.com")) (:maintainer "Akira Komamura" . "akira.komamura@gmail.com") (:keywords "outlines" "wp" "files") (:url . "https://github.com/akirak/xmind-org-el"))])
+ (xml+ . [(20170727 2351) ((emacs (24 4)) (dash (2 12 0))) "Utilities for xml and html trees" single ((:commit . "232fa863c08fc159b21dd58c39ea45dce3334895") (:authors ("Ben Dean" . "bendean837@gmail.com")) (:maintainer "Ben Dean" . "bendean837@gmail.com") (:keywords "xml" "html") (:url . "https://github.com/bddean/xml-plus"))])
+ (xml-format . [(20191011 1148) ((emacs (25)) (reformatter (0 4))) "XML reformatter using xmllint" single ((:commit . "2861c4e33e18b077112efa072316b031bca4236c") (:authors ("wouter bolsterlee" . "wouter@bolsterl.ee")) (:maintainer "wouter bolsterlee" . "wouter@bolsterl.ee") (:keywords "languages") (:url . "https://github.com/wbolster/emacs-xml-format"))])
+ (xml-quotes . [(20200301 1222) nil "read quotations from an XML document" tar ((:commit . "8fc21e43b45f9a50b24642412f05afcc3a316a1f") (:authors ("Norman Walsh" . "ndw@nwalsh.com")) (:maintainer "Norman Walsh" . "ndw@nwalsh.com") (:keywords "xml" "quotations") (:url . "https://github.com/ndw/xml-quotes"))])
+ (xml-rpc . [(20200907 42) nil "An elisp implementation of clientside XML-RPC" single ((:commit . "b8c9c3147095983d45532627171c2b2ad422ef10") (:maintainer "Mark A. Hershberger" . "mah@everybody.org") (:keywords "xml" "rpc" "network") (:url . "http://github.com/xml-rpc-el/xml-rpc-el"))])
+ (xmlgen . [(20170411 1317) nil "A DSL for generating XML." single ((:commit . "dba66681f0c5e621a9e70e8afb34903c9ffe93c4") (:authors ("Philip Jackson" . "phil@shellarchive.co.uk")) (:maintainer "Philip Jackson" . "phil@shellarchive.co.uk"))])
+ (xmlunicode . [(20210829 1631) nil "Unicode support for XML" tar ((:commit . "6e91a39114ae6ec98b26c9670db916a02c721b1f") (:authors ("Norman Walsh" . "ndw@nwalsh.com")) (:maintainer "Norman Walsh" . "ndw@nwalsh.com") (:keywords "utf-8" "unicode" "xml" "characters"))])
+ (xo . [(20160403 646) nil "XO linter integration with compilation mode" single ((:commit . "72fcd867cfa332fdb82f732925cf8977e690af78") (:authors ("J.A" . "jer.github@gmail.com")) (:maintainer "J.A" . "jer.github@gmail.com") (:keywords "processes"))])
+ (xonsh-mode . [(20201020 52) ((emacs (24 3))) "Major mode for editing xonshrc files" single ((:commit . "7fa581524533a9b6b770426e4445e571a69e469d") (:authors ("Sean Farley" . "sean@farley.io")) (:maintainer "Sean Farley" . "sean@farley.io") (:keywords "languages") (:url . "https://github.com/seanfarley/xonsh-mode"))])
+ (xquery-mode . [(20170214 1119) ((cl-lib (0 5))) "A simple mode for editing xquery programs" single ((:commit . "1b655ccf83d02a7bd473d2cf02359ed60bdf7369") (:url . "https://github.com/xquery-mode/xquery-mode"))])
+ (xquery-tool . [(20200907 811) nil "A simple interface to saxonb's xquery." single ((:commit . "885184298ce1b6eb5d18922ea331623973082a15") (:authors ("Patrick McAllister" . "pma@rdorte.org")) (:maintainer "Patrick McAllister" . "pma@rdorte.org") (:keywords "xml" "xquery" "emacs") (:url . "https://github.com/paddymcall/xquery-tool.el"))])
+ (xref-js2 . [(20210310 1238) ((emacs (25 1)) (js2-mode (20150909))) "Jump to references/definitions using ag & js2-mode's AST" single ((:commit . "fd6b723e7f1f9793d189a815e1904364dc026b03") (:authors ("Nicolas Petton" . "nicolas@petton.fr")) (:maintainer "Nicolas Petton" . "nicolas@petton.fr") (:keywords "javascript" "convenience" "tools") (:url . "https://github.com/NicolasPetton/xref-js2"))])
+ (xref-rst . [(20220406 2311) ((emacs (28 1))) "Lookup reStructuredText symbols" single ((:commit . "7964709276ff033cd138efabfafb4f2179e75c22") (:authors ("Campbell Barton" . "ideasman42@gmail.com")) (:maintainer "Campbell Barton" . "ideasman42@gmail.com") (:url . "https://gitlab.com/ideasman42/emacs-xref-rst"))])
+ (xresources-theme . [(20190108 1851) nil "Use your .Xresources as your emacs theme" single ((:commit . "5239acb51aa2dfa89a207e57012108d8fcf60562") (:authors ("Marten Lienen" . "marten.lienen@gmail.com")) (:maintainer "Marten Lienen" . "marten.lienen@gmail.com") (:keywords "xresources" "theme"))])
+ (xterm-color . [(20200605 2017) ((emacs (24 4))) "ANSI, XTERM 256 and Truecolor support" single ((:commit . "1a4012854c69a5cdaeb5a73d2ad705011892fca3") (:authors ("xristos" . "xristos@sdf.org")) (:maintainer "xristos" . "xristos@sdf.org") (:keywords "faces") (:url . "https://github.com/atomontage/xterm-color"))])
+ (xterm-keybinder . [(20160523 56) ((emacs (24 3)) (cl-lib (0 5)) (let-alist (1 0 1))) "Let you extra keybinds in xterm/urxvt" tar ((:commit . "b29c4f700b0fa0c9f627f6725b36462b8fab06d6") (:authors ("Yuta Yamada <cokesboy\"at\"gmail.com>")) (:maintainer "Yuta Yamada <cokesboy\"at\"gmail.com>") (:keywords "convenient"))])
+ (xtest . [(20141214 1706) ((cl-lib (0 5))) "Simple Testing with Emacs & ERT" single ((:commit . "2c2bdf32667506dd9ddf6eb311832add616bdf1c") (:authors ("Mustafa Shameem")) (:maintainer "Mustafa Shameem") (:keywords "testing" "ert") (:url . "https://github.com/promethial/xtest"))])
+ (xwidgete . [(20171118 2116) ((emacs (25))) "enhances usability of current xwidget browser" single ((:commit . "e4e8410fe32176df85b46234717824519443fb04") (:authors ("Tu, Do Hoang" . "tuhdo1710@gmail.com")) (:maintainer "Tu, Do Hoang") (:keywords "xwidgete" "tools") (:url . "https://github.com/tuhdo/xwidgete"))])
+ (xwidgets-reuse . [(20200817 147) ((emacs (26 1))) "Reuse xwidgets sessions to reduce resource consumption" single ((:commit . "5d56472dda53e43e0a11edcd373b44c0dbab47ce") (:authors ("Boris Glavic" . "lordpretzel@gmail.com")) (:maintainer "Boris Glavic" . "lordpretzel@gmail.com") (:keywords "hypermedia") (:url . "https://github.com/lordpretzel/xwidgets-reuse"))])
+ (xwiki-mode . [(20211112 511) ((emacs (27 1))) "Major mode for xwiki-formatted text" single ((:commit . "580e65296ca0ffb20270610ef16bfeb8850fc7c8") (:authors ("Ackerley Tng" . "ackerleytng@gmail.com")) (:maintainer "Ackerley Tng" . "ackerleytng@gmail.com") (:keywords "languages" "convenience" "tools") (:url . "https://github.com/ackerleytng/xwiki-mode"))])
+ (xwwp . [(20200917 643) ((emacs (26 1))) "Enhance xwidget webkit browser" tar ((:commit . "f67e070a6e1b233e60274deb717274b000923231") (:authors ("Damien Merenne")) (:maintainer "Damien Merenne") (:keywords "convenience") (:url . "https://github.com/canatella/xwwp"))])
+ (xwwp-follow-link-helm . [(20200917 642) ((emacs (26 1)) (xwwp (0 1))) "Link navigation in `xwidget-webkit' sessions using `helm'" single ((:commit . "f67e070a6e1b233e60274deb717274b000923231") (:authors ("Damien Merenne")) (:maintainer "Damien Merenne") (:keywords "convenience") (:url . "https://github.com/canatella/xwwp"))])
+ (xwwp-follow-link-ivy . [(20200917 642) ((emacs (26 1)) (xwwp (0 1))) "Link navigation in `xwidget-webkit' sessions using `ivy'" single ((:commit . "f67e070a6e1b233e60274deb717274b000923231") (:authors ("Damien Merenne")) (:maintainer "Damien Merenne") (:keywords "convenience") (:url . "https://github.com/canatella/xwwp"))])
+ (yabin . [(20140206 351) nil "Yet Another Bignum package (A thin wrapper of calc.el)." single ((:commit . "db8c404507560ef9147fcce2b94cd706fbfa03b5") (:authors ("Daisuke Kobayashi" . "d5884jp@gmail.com")) (:maintainer "Daisuke Kobayashi" . "d5884jp@gmail.com") (:keywords "data"))])
+ (yafolding . [(20200119 1353) nil "Folding code blocks based on indentation" single ((:commit . "4c1888ae45f9241516519ae0ae3a899f2efa05ba") (:authors ("Zeno Zeng" . "zenoofzeng@gmail.com")) (:maintainer "Zeno Zeng" . "zenoofzeng@gmail.com") (:keywords "folding"))])
+ (yagist . [(20160418 508) ((cl-lib (0 3))) "Yet Another Emacs integration for gist.github.com" single ((:commit . "dcdbd84f348414815d02f3da8a6ee0ac271632d4") (:maintainer "Masahiro Hayashi" . "mhayashi1120@gmail.com") (:keywords "tools") (:url . "https://github.com/mhayashi1120/yagist.el"))])
+ (yahtzee . [(20220221 803) ((emacs (24 3))) "The yahtzee game" single ((:commit . "9b42ba4612d3043464414c08a3d60f6ad594566c") (:authors ("Dimitar Dimitrov" . "mail.mitko@gmail.com")) (:maintainer "Dimitar Dimitrov" . "mail.mitko@gmail.com") (:keywords "games") (:url . "https://github.com/drdv/yahtzee"))])
+ (yalinum . [(20130217 1043) nil "yet another display line numbers." single ((:commit . "d3e0cbe3f4f5ca311e3298e684901d6fea3ad973") (:authors ("tm8st" . "tm8st@hotmail.co.jp")) (:maintainer "tm8st" . "tm8st@hotmail.co.jp") (:keywords "convenience" "tools"))])
+ (yaml . [(20220311 332) ((emacs (25 1))) "YAML parser for Elisp" single ((:commit . "34c300b08579b72c7c92aefee1f4b500913f0c85") (:authors ("Zachary Romero" . "zkry@posteo.org")) (:maintainer "Zachary Romero" . "zkry@posteo.org") (:keywords "tools") (:url . "https://github.com/zkry/yaml.el"))])
+ (yaml-imenu . [(20220406 1703) ((emacs (24 4)) (yaml-mode (0))) "Enhancement of the imenu support in yaml-mode." tar ((:commit . "c1fbba8b03a7bef4fc2b87404914fa9c6eb67b55") (:authors ("Akinori MUSHA" . "knu@iDaemons.org")) (:maintainer "Akinori MUSHA" . "knu@iDaemons.org") (:keywords "outlining" "convenience" "imenu") (:url . "https://github.com/knu/yaml-imenu.el"))])
+ (yaml-mode . [(20220104 1503) ((emacs (24 1))) "Major mode for editing YAML files" single ((:commit . "535273d5a1eb76999d20afbcf4d9f056d8ffd2da") (:authors ("Yoshiki Kurihara" . "clouder@gmail.com") ("Marshall T. Vandegrift" . "llasram@gmail.com")) (:maintainer "Vasilij Schneidermann" . "mail@vasilij.de") (:keywords "data" "yaml") (:url . "https://github.com/yoshiki/yaml-mode"))])
+ (yaml-tomato . [(20151123 753) ((s (1 9))) "copy or show the yaml path currently under cursor." single ((:commit . "f9df1c9bdfcec629b03031b2d2032f9dc533cb14") (:authors ("qrczeno")) (:maintainer "qrczeno") (:keywords "yaml"))])
+ (yang-mode . [(20190507 724) nil "major mode for editing YANG files" single ((:commit . "4b4ab4d4a79d37d6c31c6ea7cccbc425e0b1eded") (:authors ("Martin Bjorklund" . "mbj4668@gmail.com")) (:maintainer "Martin Bjorklund" . "mbj4668@gmail.com"))])
+ (yankpad . [(20220201 2104) ((emacs (25 1))) "Paste snippets from an org-mode file" single ((:commit . "927e6d26956ac7219b8a69d641acf486854fba16") (:authors ("Erik Sjöstrand")) (:maintainer "Erik Sjöstrand") (:keywords "abbrev" "convenience") (:url . "http://github.com/Kungsgeten/yankpad"))])
+ (yapfify . [(20210914 634) nil "(automatically) format python buffers using YAPF." single ((:commit . "c9347e3b1dec5fc8d34883e206fcdc8500d22368") (:authors ("Joris Engbers" . "info@jorisengbers.nl")) (:maintainer "Joris Engbers" . "info@jorisengbers.nl") (:url . "https://github.com/JorisE/yapfify"))])
+ (yara-mode . [(20220317 935) ((emacs (24))) "Major mode for editing yara rule file" single ((:commit . "4c959b300ce52665c92e04e524dda5ed051c34f3") (:authors (nil . "binjo.cn@gmail.com")) (:maintainer nil . "binjo.cn@gmail.com") (:keywords "yara") (:url . "not distributed yet"))])
+ (yard-mode . [(20170817 1237) nil "Minor mode for Ruby YARD comments" single ((:commit . "ba74a47463b0320ae152bd42a7dd7aeecd7b5748") (:authors ("Kyle Hargraves")) (:maintainer "Kyle Hargraves") (:url . "https://github.com/pd/yard-mode.el"))])
+ (yari . [(20151128 739) nil "Yet Another RI interface for Emacs" single ((:commit . "a2cb9656ee5dfe1fc2ee3854f3079a1c8e85dbe9") (:authors ("Aleksei Gusev" . "aleksei.gusev@gmail.com")) (:maintainer "Aleksei Gusev" . "aleksei.gusev@gmail.com") (:keywords "tools"))])
+ (yarn-mode . [(20200208 2332) ((emacs (24 3))) "Major mode for yarn.lock files." single ((:commit . "8239d4dc7d8a52fa1e3fa81bd32c904a359fcfc1") (:authors ("Nicolás Salas V." . "nikosalas@gmail.com")) (:maintainer "Nicolás Salas V." . "nikosalas@gmail.com") (:keywords "convenience") (:url . "https://github.com/anachronic/yarn-mode"))])
+ (yascroll . [(20220212 1742) ((emacs (26 1))) "Yet Another Scroll Bar Mode" single ((:commit . "25f6bf7415f6821a4097037a8decd03813d08722") (:authors ("Tomohiro Matsuyama" . "m2ym.pub@gmail.com")) (:maintainer "Shen, Jen-Chieh" . "jcs090218@gmail.com") (:keywords "convenience") (:url . "https://github.com/emacsorphanage/yascroll"))])
+ (yasnippet . [(20200604 246) ((cl-lib (0 5))) "Yet another snippet extension for Emacs" single ((:commit . "5cbdbf0d2015540c59ed8ee0fcf4788effdf75b6") (:maintainer "Noam Postavsky" . "npostavs@gmail.com") (:keywords "convenience" "emulation") (:url . "http://github.com/joaotavora/yasnippet"))])
+ (yasnippet-lean . [(20220105 2251) ((yasnippet (0 8 0))) "Collection of snippets for the Lean prover" tar ((:commit . "c75485757cc8675ad4f36c1eb028d9d54dc21733") (:maintainer "Simon Hudon" . "simon.hudon@gmail.com") (:keywords "convenience" "snippets" "leanprover") (:url . "https://github.com/leanprover-community/yasnippet-lean"))])
+ (yasnippet-snippets . [(20220401 1534) ((yasnippet (0 8 0))) "Collection of yasnippet snippets" tar ((:commit . "c5bf4c4085aa61b9c07563de89f7aacc2a357db5") (:authors ("Andrea Crotti" . "andrea.crotti.0@gmail.com")) (:maintainer "Andrea Crotti" . "andrea.crotti.0@gmail.com") (:keywords "snippets") (:url . "https://github.com/AndreaCrotti/yasnippet-snippets"))])
+ (yatemplate . [(20211115 1208) ((yasnippet (0 8 1)) (emacs (24 3))) "File templates with yasnippet" single ((:commit . "275745ce1482edc08efb0b7807bc86d832bcc734") (:authors ("Wieland Hoffmann" . "themineo+yatemplate@gmail.com")) (:maintainer "Wieland Hoffmann" . "themineo+yatemplate@gmail.com") (:keywords "files" "convenience") (:url . "https://github.com/mineo/yatemplate"))])
+ (yatex . [(20211203 2212) nil "Yet Another tex-mode for emacs //野鳥//" tar ((:commit . "907de32064c99c25fb49072438be7c1034892af3"))])
+ (yaxception . [(20150105 1452) nil "Provide framework about exception like Java for Elisp" single ((:commit . "4e94cf3e0b9b5631b0e90eb4b7de597ee7185875") (:authors ("Hiroaki Otsu" . "ootsuhiroaki@gmail.com")) (:maintainer "Hiroaki Otsu" . "ootsuhiroaki@gmail.com") (:keywords "exception" "error" "signal") (:url . "https://github.com/aki2o/yaxception"))])
+ (ycm . [(20150822 1836) nil "Emacs client for the YouCompleteMe auto-completion server." single ((:commit . "4da8a14abcd0f4fa3235042ade2e12b5068c0601") (:authors ("Ajay Gopinathan" . "ajay@gopinathan.net")) (:maintainer "Ajay Gopinathan" . "ajay@gopinathan.net") (:keywords "c" "abbrev"))])
+ (ycmd . [(20190416 807) ((emacs (24 4)) (dash (2 13 0)) (s (1 11 0)) (deferred (0 5 1)) (cl-lib (0 6 1)) (let-alist (1 0 5)) (request (0 3 0)) (request-deferred (0 3 0)) (pkg-info (0 6))) "emacs bindings to the ycmd completion server" tar ((:commit . "c17ff9e0250a9b39d23af37015a2b300e2f36fed") (:url . "https://github.com/abingham/emacs-ycmd"))])
+ (ydk-mode . [(20170113 921) nil "Language support for Yu-Gi-Oh! deck files" single ((:commit . "f3f125b29408e0b0a34fec27dcb7c02c5dbfd04e") (:authors ("Jackson Ray Hamilton" . "jackson@jacksonrayhamilton.com")) (:maintainer "Jackson Ray Hamilton" . "jackson@jacksonrayhamilton.com") (:keywords "faces" "games" "languages" "ydk" "yugioh" "yu-gi-oh") (:url . "https://github.com/jacksonrayhamilton/ydk-mode"))])
+ (yequake . [(20200219 2323) ((emacs (25 2)) (dash (2 14 1))) "Drop-down frames, like Yakuake" single ((:commit . "d18166e597414350117d0b82a29e509fc53c636d") (:authors ("Adam Porter" . "adam@alphapapa.net")) (:maintainer "Adam Porter" . "adam@alphapapa.net") (:keywords "convenience" "window-system" "frames") (:url . "http://github.com/alphapapa/yequake"))])
+ (yesql-ghosts . [(20150220 1237) ((s (1 9 0)) (dash (2 10 0)) (cider (0 8 0))) "Display ghostly yesql defqueries inline" single ((:commit . "8f1faf0137b85a5072d13e1240a463d9a35ce2bb") (:authors ("Magnar Sveen" . "magnars@gmail.com")) (:maintainer "Magnar Sveen" . "magnars@gmail.com"))])
+ (yesterbox . [(20200327 52) ((emacs (24 3))) "Count number of inbox messages by day" single ((:commit . "10591342f1759e25756f5865371a53c132d8b0a0") (:authors ("Stephen J. Eglen" . "sje30@cam.ac.uk")) (:maintainer "Stephen J. Eglen" . "sje30@cam.ac.uk") (:keywords "mail") (:url . "http://github.com/sje30/yesterbox"))])
+ (ynab . [(20200607 2008) ((emacs (26 3)) (cl-lib (0 5)) (ts (0 2))) "Major mode for YNAB (you need a budget)" single ((:commit . "2c6beb4d2c4996017f6b3c62c26db52a61e5c479") (:authors ("Jim Anders <https://github.com/janders223>")) (:maintainer "Jim Anders" . "jimanders223@gmail.com") (:keywords "ynab" "budget" "convenience") (:url . "https://github.com/janders223/ynab.el"))])
+ (yoficator . [(20190509 1620) nil "Interactively yoficate Russian texts" tar ((:commit . "fa914f9648515bca54b5e558ca57d2b65fa57491") (:authors ("Eugene Minkovskii" . "emin@mccme.ru") ("Alexander Krotov" . "ilabdsf@gmail.com")) (:maintainer "Eugene Minkovskii" . "emin@mccme.ru") (:url . "https://gitlab.com/link2xt/yoficator"))])
+ (yoshi-theme . [(20211031 456) nil "Theme named after my cat" single ((:commit . "787bb0a13c6e1b28e904e1b7f18564d5e97c9c93") (:authors ("Tom Willemse" . "tom@ryuslash.org")) (:maintainer "Tom Willemse" . "tom@ryuslash.org") (:keywords "faces") (:url . "http://projects.ryuslash.org/yoshi-theme/"))])
+ (youdao-dictionary . [(20200722 1705) ((popup (0 5 0)) (pos-tip (0 4 6)) (chinese-word-at-point (0 2)) (names (0 5)) (emacs (24))) "Youdao Dictionary interface for Emacs" single ((:commit . "8a4815a43565b9bfd257246e4895b8bfafb9d573") (:authors ("Chunyang Xu" . "xuchunyang56@gmail.com")) (:maintainer "Chunyang Xu" . "xuchunyang56@gmail.com") (:keywords "convenience" "chinese" "dictionary") (:url . "https://github.com/xuchunyang/youdao-dictionary.el"))])
+ (ytdious . [(20210228 2111) ((emacs (25 3))) "Query / Preview YouTube via Invidious" single ((:commit . "941460b51e43ef6764e15e2b9c4af54c3e56115f") (:authors ("Stefan Huchler") ("Gabriele Rastello")) (:maintainer "Stefan Huchler") (:keywords "youtube" "matching" "multimedia") (:url . "https://github.com/spiderbit/ytdious"))])
+ (ytdl . [(20210506 914) ((emacs (26 1)) (async (1 9 4)) (transient (0 2 0)) (dash (2 17 0))) "Emacs Interface for youtube-dl" single ((:commit . "23da64f5c38b8cb83dbbadf704171b86cc0fa937") (:authors ("Arnaud Hoffmann" . "tuedachu@gmail.com")) (:maintainer "Arnaud Hoffmann" . "tuedachu@gmail.com") (:keywords "comm" "multimedia") (:url . "https://gitlab.com/tuedachu/ytdl"))])
+ (ytel . [(20200725 1056) ((emacs (25 3))) "Query YouTube via Invidious" single ((:commit . "d40bc7ead8d4d7e4d16b03b66a93d63bef51cc5f") (:authors ("Gabriele Rastello")) (:maintainer "Gabriele Rastello") (:keywords "youtube" "matching" "multimedia") (:url . "https://github.com/grastello/ytel"))])
+ (z3-mode . [(20211116 138) ((flycheck (0 23)) (emacs (24))) "A z3/SMTLIBv2 interactive development environment" single ((:commit . "0356cbe1e1e2b780ba0ddb4aaa055fa246a67931") (:authors ("Zephyr Pellerin" . "zephyr.pellerin@gmail.com")) (:maintainer "Zephyr Pellerin" . "zephyr.pellerin@gmail.com") (:keywords "z3" "yices" "mathsat" "smt" "beaver") (:url . "https://github.com/zv/z3-mode"))])
+ (zeal-at-point . [(20180131 2354) nil "Search the word at point with Zeal" single ((:commit . "0fc3263f44e95acd3e9d91057677621ce4d297ee") (:authors ("Jinzhu" . "wosmvp@gmail.com")) (:maintainer "Jinzhu" . "wosmvp@gmail.com") (:url . "https://github.com/jinzhu/zeal-at-point"))])
+ (zel . [(20171014 832) ((emacs (25)) (frecency (0 1))) "Access frecent files easily" single ((:commit . "9dae2d212224d1deae1f62561fa8e4d689fd09f2") (:authors ("Sebastian Christ" . "rudolfo.christ@gmail.com")) (:maintainer "Sebastian Christ" . "rudolfo.christ@gmail.com") (:keywords "convenience" "files" "matching") (:url . "https://github.com/rudolfochrist/zel"))])
+ (zen-and-art-theme . [(20120622 1437) nil "zen and art color theme for GNU Emacs 24" single ((:commit . "a7226cbce0bca2501d69a620cb2aeabfc396c232") (:authors ("Nick Parker")) (:maintainer "Nick Parker"))])
+ (zen-mode . [(20200609 822) ((emacs (24 3))) "A major mode for the Zen programming language" single ((:commit . "c1b1806358f3cce6c04b30699987d82dc7d42559") (:authors ("Andrea Orru <andreaorru1991@gmail.com>, Andrew Kelley <superjoe30@gmail.com>, kristopher tate <kt@connectfree.co.jp>, Yoshitaka Takemoto" . "yt.3b8@connectfree.co.jp")) (:maintainer "Andrea Orru <andreaorru1991@gmail.com>, Andrew Kelley <superjoe30@gmail.com>, kristopher tate <kt@connectfree.co.jp>, Yoshitaka Takemoto" . "yt.3b8@connectfree.co.jp") (:keywords "zen" "languages") (:url . "https://github.com/zenlang/zen-mode"))])
+ (zenburn-theme . [(20220412 2023) nil "A low contrast color theme for Emacs." single ((:commit . "89c0e39317850d5ccf14dcbbaff06b0a193454a6") (:authors ("Bozhidar Batsov" . "bozhidar@batsov.com")) (:maintainer "Bozhidar Batsov" . "bozhidar@batsov.com") (:url . "http://github.com/bbatsov/zenburn-emacs"))])
+ (zencoding-mode . [(20140213 822) nil "Unfold CSS-selector-like expressions to markup" single ((:commit . "58e42af182c98cb9941d27cd042d227fbf4e146c") (:authors ("Chris Done" . "chrisdone@gmail.com")) (:maintainer "Chris Done" . "chrisdone@gmail.com") (:keywords "convenience") (:url . "https://github.com/rooney/zencoding"))])
+ (zenity-color-picker . [(20160302 1154) ((emacs (24 4))) "Insert and adjust colors using Zenity" single ((:commit . "4f4f46676a461ebc881487fb70c8c181e323db5e") (:authors ("Samuel Laurén" . "samuel.lauren@iki.fi")) (:maintainer "Samuel Laurén" . "samuel.lauren@iki.fi") (:keywords "colors") (:url . "https://bitbucket.org/Soft/zenity-color-picker.el"))])
+ (zeno-theme . [(20211205 2148) ((emacs (24))) "A dark theme using different shades of blue" single ((:commit . "70fa7b7442f24ea25eab538b5a22da690745fef5") (:authors ("Bharat Joshi" . "jbharat@outlook.com")) (:maintainer "Bharat Joshi" . "jbharat@outlook.com") (:keywords "faces" "theme" "dark" "blue") (:url . "https://github.com/jbharat/zeno-theme"))])
+ (zenscript-mode . [(20210102 1350) ((emacs (25 1))) "Major mode for ZenScript" tar ((:commit . "c33b4525502459fe60dd76b383e19919d450aeb8") (:url . "https://github.com/eutropius225/zenscript-mode"))])
+ (zephir-mode . [(20200417 830) ((cl-lib (0 5)) (pkg-info (0 4)) (emacs (25 1))) "Major mode for editing Zephir code" tar ((:commit . "4e9618b77dff67c1c7b6fff78605a62311db88b8") (:authors ("Serghei Iakovlev" . "egrep@protonmail.ch")) (:maintainer "Serghei Iakovlev" . "egrep@protonmail.ch") (:keywords "languages") (:url . "https://github.com/zephir-lang/zephir-mode"))])
+ (zero-input . [(20200405 1220) ((emacs (24 3)) (s (1 2 0))) "Zero Chinese input method framework" single ((:commit . "729da9f4b99acb744ee6974ed7f3d4e252fd19da") (:url . "https://gitlab.emacsos.com/sylecn/zero-el"))])
+ (zerodark-theme . [(20211115 841) ((all-the-icons (2 0 0))) "A dark, medium contrast theme for Emacs" single ((:commit . "b463528704f6eb00684c0ee003fbd8e42901cde0") (:authors ("Nicolas Petton" . "nicolas@petton.fr")) (:maintainer "Nicolas Petton" . "nicolas@petton.fr") (:keywords "themes") (:url . "https://github.com/NicolasPetton/zerodark-theme"))])
+ (zetteldeft . [(20220429 2057) ((emacs (25 1)) (deft (0 8)) (ace-window (0 7 0))) "Turn deft into a zettelkasten system" tar ((:commit . "86dd346be4bdddd6ac8d47503355fea350098271") (:authors ("EFLS <Elias Storms>")) (:maintainer "EFLS <Elias Storms>") (:keywords "deft" "zettelkasten" "zetteldeft" "wp" "files") (:url . "https://efls.github.io/zetteldeft/"))])
+ (zettelkasten . [(20210830 1025) ((emacs (25 1)) (s (1 10 0))) "Helper functions to organise notes in a Zettelkasten style" single ((:commit . "603a5b692a08340c1865a6f73cacf57c4fd64cb2") (:authors ("Yann Herklotz" . "yann@ymhg.org")) (:maintainer "Yann Herklotz" . "yann@ymhg.org") (:keywords "files" "hypermedia" "notes") (:url . "https://github.com/ymherklotz/emacs-zettelkasten"))])
+ (zetz-mode . [(20200823 536) ((emacs (25 1)) (dash (2 17 0)) (hydra (0 15 0))) "A major mode for the ZetZ programming language" single ((:commit . "04da33f4ffa9db5b3556f423276f4fd1db13ec67") (:keywords "languages" "programming") (:url . "https://github.com/damon-kwok/zetz-mode"))])
+ (zig-mode . [(20211227 1108) ((emacs (24 3))) "A major mode for the Zig programming language" single ((:commit . "aa20d630b8c413dab8d6bd120ec3ed5db5c9da70") (:authors ("Andrea Orru <andreaorru1991@gmail.com>, Andrew Kelley" . "superjoe30@gmail.com")) (:maintainer "Andrea Orru <andreaorru1991@gmail.com>, Andrew Kelley" . "superjoe30@gmail.com") (:keywords "zig" "languages") (:url . "https://github.com/zig-lang/zig-mode"))])
+ (zim-wiki-mode . [(20211117 2000) ((emacs (25 1)) (helm-ag (0 58)) (helm-projectile (0 14 0)) (dokuwiki-mode (0 1 1)) (link-hint (0 1)) (pretty-hydra (0 2 2))) "Zim Desktop Wiki edit mode" single ((:commit . "aa906931f22c34d77c65bed31121edfef714e4e2") (:authors ("Will Foran" . "willforan+zim-wiki-mode@gmail.com")) (:maintainer "Will Foran" . "willforan+zim-wiki-mode@gmail.com") (:keywords "outlines") (:url . "https://github.com/WillForan/zim-wiki-mode"))])
+ (zimports . [(20211011 2059) ((emacs (26 1)) (projectile (2 1 0))) "Reformat python imports with zimports" single ((:commit . "76cf76bdc871cb0454a6fc555aeb1aa94f1b6e57") (:url . "https://github.com/schmir/zimports.el"))])
+ (zk . [(20220423 944) ((emacs (24 4))) "Functions for working with Zettelkasten-style linked notes" single ((:commit . "d6d7713cfac073940dcd96b55c18830a64d4ccca") (:authors ("Grant Rosson <https://github.com/localauthor>")) (:maintainer "Grant Rosson <https://github.com/localauthor>") (:url . "https://github.com/localauthor/zk"))])
+ (zk-index . [(20220505 1403) ((emacs (26 1)) (zk (0 3))) "Index and Desktop for zk" single ((:commit . "d6d7713cfac073940dcd96b55c18830a64d4ccca") (:authors ("Grant Rosson <https://github.com/localauthor>")) (:maintainer "Grant Rosson <https://github.com/localauthor>") (:url . "https://github.com/localauthor/zk"))])
+ (zlc . [(20151011 157) nil "Provides zsh like completion system to Emacs" single ((:commit . "4dd2ba267ecdeac845a7cbb3147294ee7daa25f4") (:authors ("mooz" . "stillpedant@gmail.com")) (:maintainer "mooz" . "stillpedant@gmail.com") (:keywords "matching" "convenience"))])
+ (zmq . [(20210613 343) ((cl-lib (0 5)) (emacs (26))) "ZMQ bindings in elisp" tar ((:commit . "38dc6c4119aee57666caf8f97c8a3d7f678823e0") (:authors ("Nathaniel Nicandro" . "nathanielnicandro@gmail.com")) (:maintainer "Nathaniel Nicandro" . "nathanielnicandro@gmail.com") (:keywords "comm") (:url . "https://github.com/nnicandro/emacs-zmq"))])
+ (znc . [(20210803 159) ((cl-lib (0 2))) "ZNC + ERC" single ((:commit . "6f0949c393b7778a96033716787d152ada32f705") (:authors ("Yaroslav Shirokov")) (:maintainer "Yaroslav Shirokov") (:url . "https://github.com/sshirokov/ZNC.el"))])
+ (zombie . [(20141222 1616) nil "major mode for editing ZOMBIE programs" single ((:commit . "ff8cd1b4cdbb4b0b9b8fd1ec8f6fb93eba249345") (:authors ("zk_phi")) (:maintainer "zk_phi") (:url . "http://hins11.yu-yake.com/"))])
+ (zombie-trellys-mode . [(20150304 1448) ((emacs (24)) (cl-lib (0 5)) (haskell-mode (1 5))) "A minor mode for interaction with Zombie Trellys" single ((:commit . "7f0c45fdda3a44c3b6d1762d116abb1421b8fba2") (:authors ("David Raymond Christiansen" . "david@davidchristiansen.dk")) (:maintainer "David Raymond Christiansen" . "david@davidchristiansen.dk") (:keywords "languages"))])
+ (zone-nyan . [(20210508 1642) ((emacs (24 3)) (esxml (0 3 1))) "Zone out with nyan cat" single ((:commit . "38b6e9f1f5871e9166b00a1db44680caa56773be") (:authors ("Vasilij Schneidermann" . "mail@vasilij.de")) (:maintainer "Vasilij Schneidermann" . "mail@vasilij.de") (:keywords "games") (:url . "https://depp.brause.cc/zone-nyan"))])
+ (zone-rainbow . [(20160120 1334) ((emacs (24 3))) "Zone out with rainbow." single ((:commit . "2ba4f1a87c69c4712124ebf12c1f3ea171e1af36") (:authors ("KAWABATA, Taichi <kawabata.taichi_at_gmail.com>")) (:maintainer "KAWABATA, Taichi <kawabata.taichi_at_gmail.com>") (:keywords "games") (:url . "https://github.com/kawabata/zone-rainbow"))])
+ (zone-select . [(20160118 1419) ((emacs (24 3)) (dash (2 8))) "Select zone programs." single ((:commit . "bf30da12f1625fe6563448fccf3c506acad10af7") (:authors ("KAWABATA, Taichi <kawabata.taichi_at_gmail.com>")) (:maintainer "KAWABATA, Taichi <kawabata.taichi_at_gmail.com>") (:keywords "games") (:url . "https://github.com/kawabata/zone-select"))])
+ (zone-sl . [(20160201 1210) ((emacs (24 3))) "Zone out with steam locomotives." single ((:commit . "7ec22e3661c6348382f9fc39a9d0063dbd2352ff") (:authors ("KAWABATA, Taichi <kawabata.taichi_at_gmail.com>")) (:maintainer "KAWABATA, Taichi <kawabata.taichi_at_gmail.com>") (:keywords "games") (:url . "https://github.com/kawabata/zone-sl"))])
+ (zoom . [(20220411 1126) ((emacs (24 4))) "Fixed and automatic balanced window layout" single ((:commit . "2104abb074682db79b9ff3a748e8e2e760a4d8cf") (:authors ("Andrea Cardaci" . "cyrus.and@gmail.com")) (:maintainer "Andrea Cardaci" . "cyrus.and@gmail.com") (:keywords "frames") (:url . "https://github.com/cyrus-and/zoom"))])
+ (zoom-window . [(20201205 1038) ((emacs (24 3))) "Zoom window like tmux" single ((:commit . "402f85f5d7d18e26289adcd452d42c73dc1df580") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-zoom-window"))])
+ (zop-to-char . [(20160212 1554) ((cl-lib (0 5))) "A replacement of zap-to-char." single ((:commit . "00152aa666354b27e56e20565f186b363afa0dce") (:authors ("Thierry Volpiatto" . "thierry.volpiatto@gmail.com")) (:maintainer "Thierry Volpiatto" . "thierry.volpiatto@gmail.com") (:url . "https://github.com/thierryvolpiatto/zop-to-char"))])
+ (zotelo . [(20160602 949) ((cl-lib (0 5))) "Manage Zotero collections from emacs" single ((:commit . "d9dc089b9adfcc70a63f2a84269a12eb7cb4c748") (:authors ("Spinu Vitalie")) (:maintainer "Spinu Vitalie") (:keywords "zotero" "emacs" "reftex" "bibtex" "mozrepl" "bibliography manager") (:url . "https://github.com/vitoshka/zotelo"))])
+ (zotero . [(20211008 2207) ((emacs (27 1)) (ht (2 2)) (oauth (1 0 4)) (s (1 12 0))) "Library for the Zotero API" tar ((:commit . "811bd1f14b38c3dde3f80cd8a13490c9900de888") (:authors ("Folkert van der Beek" . "folkertvanderbeek@gmail.com")) (:maintainer "Folkert van der Beek" . "folkertvanderbeek@gmail.com") (:keywords "zotero" "hypermedia") (:url . "https://gitlab.com/fvdbeek/emacs-zotero"))])
+ (zotxt . [(20210908 402) ((request (0 3 2)) (deferred (0 5 1))) "Tools to integrate emacs with Zotero via the zotxt plugin." tar ((:commit . "96a132d6b39f6bc19a58913b761d42efc198f8a4") (:authors ("Erik Hetzner" . "egh@e6h.org")) (:maintainer "Erik Hetzner" . "egh@e6h.org") (:keywords "bib"))])
+ (zoutline . [(20220102 835) nil "Simple outline library." single ((:commit . "32857c6c4b9b0bcbed14d825a10b91a98d5fed0a") (:authors ("Oleh Krehel" . "ohwoeowho@gmail.com")) (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com") (:keywords "outline") (:url . "https://github.com/abo-abo/zoutline"))])
+ (zoxide . [(20220302 522) ((emacs (25 1))) "Find file by zoxide" single ((:commit . "2133eb000b5239b08a1c2532629a19a19f8e6309") (:authors ("Ruoyu Feng" . "emacs@vonfry.name")) (:maintainer "Ruoyu Feng" . "emacs@vonfry.name") (:keywords "converience" "matching") (:url . "https://gitlab.com/Vonfry/zoxide.el"))])
+ (zpl-mode . [(20180906 1059) ((emacs (24 3))) "ZIMPL major mode" single ((:commit . "35e7e23c6baf31b5e65dd7405c8ab9b13c70637e") (:url . "https://github.com/ax487/zpl-mode.git"))])
+ (zpresent . [(20200417 309) ((emacs (25 1)) (org-parser (0 4)) (dash (2 12 0)) (request (0 3 0))) "Simple presentation mode based on org files." single ((:commit . "406967322b7692492a5942d901335d626cace4d0") (:keywords "comm") (:url . "https://hg.sr.ht/~zck/zpresent"))])
+ (zprint-format . [(20210602 146) ((emacs (24)) (reformatter (0 3))) "Reformat Clojure code using zprint" single ((:commit . "6051a5709ea6182974d7239f26e04c9731e04447") (:authors ("Derek Passen" . "dpassen1@gmail.com")) (:maintainer "Derek Passen" . "dpassen1@gmail.com") (:keywords "clojure" "zprint" "tools" "languages") (:url . "http://www.github.com/dpassen/zprint-format"))])
+ (zprint-mode . [(20200731 1238) ((emacs (24 3))) "Reformat Clojure(Script) code using zprint" tar ((:commit . "b9b72b4918156f2f44aa544be9e19ea391937c2a") (:authors ("Paulus Esterhazy" . "pesterhazy@gmail.com")) (:maintainer "Paulus Esterhazy" . "pesterhazy@gmail.com") (:keywords "tools") (:url . "https://github.com/pesterhazy/zprint-mode.el"))])
+ (ztree . [(20210415 1947) ((cl-lib (0))) "Text mode directory tree" tar ((:commit . "f05677f9696e573c8c607e8876fb4a0cccbc491f") (:authors ("Alexey Veretennikov" . "alexey.veretennikov@gmail.com")) (:maintainer "Alexey Veretennikov" . "alexey.veretennikov@gmail.com") (:keywords "files" "tools") (:url . "https://github.com/fourier/ztree"))])
+ (zweilight-theme . [(20170113 605) nil "A dark color theme for Emacs." single ((:commit . "7f45ab9e23164d65538edb2beb9692ecdc24c31e") (:authors ("Philip Arvidsson" . "contact@philiparvidsson.com")) (:maintainer "Philip Arvidsson" . "contact@philiparvidsson.com") (:url . "http://github.com/philiparvidsson/zweilight-emacs"))])
+ (zygospore . [(20140703 852) nil "reversible C-x 1 (delete-other-windows)" single ((:commit . "1af5ee663f5a7aa08d96a77cacff834dcdf55ea8") (:authors ("Louis Kottmann" . "louis.kottmann@gmail.com")) (:maintainer "Louis Kottmann" . "louis.kottmann@gmail.com") (:url . "https://github.com/louiskottmann/zygospore.el"))])
+ (zzz-to-char . [(20210321 1707) ((emacs (24 4)) (cl-lib (0 5)) (avy (0 3 0))) "Fancy version of `zap-to-char' command" single ((:commit . "fa87da4ac95a1d7fe8aa9198c5568debee8d5627") (:authors ("Mark Karpov" . "markkarpov92@gmail.com")) (:maintainer "Mark Karpov" . "markkarpov92@gmail.com") (:keywords "convenience") (:url . "https://github.com/mrkkrp/zzz-to-char"))])) \ No newline at end of file
diff --git a/elpa/archives/nongnu/archive-contents b/elpa/archives/nongnu/archive-contents
new file mode 100644
index 0000000..7ab8258
--- /dev/null
+++ b/elpa/archives/nongnu/archive-contents
@@ -0,0 +1,1643 @@
+(1
+ (afternoon-theme .
+ [(0 1)
+ ((emacs
+ (24 1)))
+ "Dark color theme with a deep blue background" tar
+ ((:url . "http://github.com/osener/emacs-afternoon-theme")
+ (:keywords "themes")
+ (:maintainer "Ozan Sener" . "ozan@ozansener.com")
+ (:authors
+ ("Ozan Sener" . "ozan@ozansener.com")))])
+ (alect-themes .
+ [(0 10)
+ ((emacs
+ (24 0)))
+ "Configurable light, dark and black themes for Emacs 24 or later" tar
+ ((:url . "https://github.com/alezost/alect-themes")
+ (:keywords "color" "theme")
+ (:maintainer "Alex Kost" . "alezost@gmail.com")
+ (:authors
+ ("Alex Kost" . "alezost@gmail.com")))])
+ (ample-theme .
+ [(0 3 0)
+ nil "Calm Dark Theme for Emacs" tar
+ ((:url . "https://github.com/jordonbiondo/ample-theme")
+ (:keywords "theme" "dark")
+ (:maintainer "Jordon Biondo" . "jordonbiondo@gmail.com")
+ (:authors
+ ("Jordon Biondo" . "jordonbiondo@gmail.com")))])
+ (annotate .
+ [(1 5 4)
+ nil "annotate files without changing them" tar
+ ((:url . "https://github.com/bastibe/annotate.el")
+ (:maintainer "Bastian Bechtold <bastibe.dev@mailbox.org>, cage" . "cage-dev@twistfold.it")
+ (:authors
+ ("Bastian Bechtold"))
+ (:commit . "c00b6f49f779dc5caac7b37d1e35f87891e015d4"))])
+ (anti-zenburn-theme .
+ [(2 5 1)
+ nil "Low-contrast Zenburn-inverted theme" tar
+ ((:url . "https://github.com/m00natic/anti-zenburn-theme")
+ (:maintainer "Andrey Kotlarski" . "m00naticus@gmail.com")
+ (:authors
+ ("Andrey Kotlarski" . "m00naticus@gmail.com")))])
+ (anzu .
+ [(0 64)
+ ((emacs
+ (25 1)))
+ "Show number of matches in mode-line while searching" tar
+ ((:url . "https://github.com/emacsorphanage/anzu")
+ (:maintainer "Neil Okamoto" . "neil.okamoto+melpa@gmail.com")
+ (:authors
+ ("Syohei YOSHIDA" . "syohex@gmail.com")))])
+ (apache-mode .
+ [(2 2 0)
+ nil "Major mode for editing Apache httpd configuration files" tar
+ ((:url . "https://github.com/emacs-php/apache-mode")
+ (:maintainer "USAMI Kenta" . "tadsan@zonu.me")
+ (:authors
+ ("Karl Chen" . "quarl@nospam.quarl.org"))
+ (:keywords "languages" "faces"))])
+ (apropospriate-theme .
+ [(0 1 1)
+ nil "A light & dark theme set for Emacs." tar
+ ((:url . "http://github.com/waymondo/apropospriate-theme")
+ (:maintainer "Justin Talbott" . "justin@waymondo.com")
+ (:authors
+ ("Justin Talbott" . "justin@waymondo.com")))])
+ (arduino-mode .
+ [(1 3 0)
+ ((emacs
+ (25 1))
+ (spinner
+ (1 7 3)))
+ "Major mode for editing Arduino code" tar
+ ((:url . "https://github.com/stardiviner/arduino-mode")
+ (:maintainer "stardiviner" . "numbchild@gmail.com")
+ (:keywords "languages" "arduino"))])
+ (autothemer .
+ [(0 2 3)
+ ((dash
+ (2 10 0))
+ (emacs
+ (24))
+ (cl-lib
+ (0 5)))
+ "Conveniently define themes." tar
+ ((:url . "https://github.com/sebastiansturm/autothemer")
+ (:maintainer "Sebastian Sturm")
+ (:authors
+ ("Sebastian Sturm")))])
+ (better-jumper .
+ [(1 0 1)
+ ((emacs
+ (25 1)))
+ "configurable jump list" tar
+ ((:url . "https://github.com/gilbertw1/better-jumper")
+ (:keywords "convenience" "jump" "history" "evil")
+ (:maintainer "Bryan Gilbert" . "bryan@bryan.sh")
+ (:authors
+ ("Bryan Gilbert <http://github/gilbertw1>")))])
+ (bind-map .
+ [(1 1 2)
+ ((emacs
+ (24 3)))
+ "Bind personal keymaps in multiple locations" tar
+ ((:url . "https://github.com/justbur/emacs-bind-map")
+ (:maintainer "Justin Burkett" . "justin@burkett.cc")
+ (:authors
+ ("Justin Burkett" . "justin@burkett.cc"))
+ (:commit . "6977e0fec5c4a3c62a10503798c2a15194167046"))])
+ (bison-mode .
+ [(0 4)
+ nil "Major mode for editing bison, yacc and lex files." tar
+ ((:maintainer "Eric Beuscher" . "beuscher@eecs.tulane.edu")
+ (:authors
+ ("Eric Beuscher" . "beuscher@eecs.tulane.edu"))
+ (:keywords "bison-mode" "yacc-mode")
+ (:url . "https://elpa.nongnu.org/nongnu/bison-mode.html"))])
+ (boxquote .
+ [(2 2)
+ ((cl-lib
+ (0 5)))
+ "Quote text with a semi-box." tar
+ ((:url . "https://github.com/davep/boxquote.el")
+ (:keywords "quoting")
+ (:maintainer "Dave Pearson" . "davep@davep.org")
+ (:authors
+ ("Dave Pearson" . "davep@davep.org")))])
+ (buttercup .
+ [(1 25)
+ ((emacs
+ (24 3)))
+ "Behavior-Driven Emacs Lisp Testing" tar
+ ((:url . "https://github.com/jorgenschaefer/emacs-buttercup")
+ (:maintainer "Ola Nilsson" . "ola.nilsson@gmail.com")
+ (:authors
+ ("Jorgen Schaefer" . "contact@jorgenschaefer.de"))
+ (:commit . "ba62f80555d46faf49dc451c0ad20f39f6a170ab"))])
+ (caml .
+ [(4 9)
+ ((emacs
+ (24 3)))
+ "Caml mode for GNU Emacs" tar
+ ((:url . "https://github.com/ocaml/caml-mode")
+ (:maintainer "Christophe Troestler" . "Christophe.Troestler@umons.ac.be")
+ (:authors
+ ("Jacques Garrigue" . "garrigue@kurims.kyoto-u.ac.jp")
+ ("Ian T Zimmerman" . "itz@rahul.net")
+ ("Damien Doligez" . "damien.doligez@inria.fr"))
+ (:keywords "ocaml"))])
+ (cider .
+ [(1 4 0)
+ ((emacs
+ (26))
+ (clojure-mode
+ (5 14))
+ (parseedn
+ (1 0 6))
+ (queue
+ (0 2))
+ (spinner
+ (1 7))
+ (seq
+ (2 22))
+ (sesman
+ (0 3 2)))
+ "Clojure Interactive Development Environment that Rocks" tar
+ ((:url . "http://www.github.com/clojure-emacs/cider")
+ (:keywords "languages" "clojure" "cider")
+ (:maintainer "Bozhidar Batsov" . "bozhidar@batsov.dev")
+ (:authors
+ ("Tim King" . "kingtim@gmail.com")
+ ("Phil Hagelberg" . "technomancy@gmail.com")
+ ("Bozhidar Batsov" . "bozhidar@batsov.dev")
+ ("Artur Malabarba" . "bruce.connor.am@gmail.com")
+ ("Hugo Duncan" . "hugo@hugoduncan.org")
+ ("Steve Purcell" . "steve@sanityinc.com"))
+ (:commit . "b2cee7fc301735b403920583cc2c23dcf70990a3"))])
+ (clojure-mode .
+ [(5 14 0)
+ ((emacs
+ (25 1)))
+ "Major mode for Clojure code" tar
+ ((:url . "http://github.com/clojure-emacs/clojure-mode")
+ (:keywords "languages" "clojure" "clojurescript" "lisp")
+ (:maintainer "Bozhidar Batsov" . "bozhidar@batsov.dev")
+ (:commit . "b7d08b87f6a116ff47b33ee857926b60c66c3ab7"))])
+ (coffee-mode .
+ [(0 6 3)
+ ((emacs
+ (24 3)))
+ "Major mode for CoffeeScript code" tar
+ ((:url . "http://github.com/defunkt/coffee-mode")
+ (:keywords "coffeescript" "major" "mode")
+ (:maintainer "Chris Wanstrath" . "chris@ozmm.org")
+ (:authors
+ ("Chris Wanstrath" . "chris@ozmm.org"))
+ (:commit . "adfb7ae73d6ee2ef790c780dd3c967e62930e94a"))])
+ (color-theme-tangotango .
+ [(0 0 6)
+ ((color-theme
+ (6 6 1)))
+ "Tango Palette color theme for Emacs." tar
+ ((:url . "https://github.com/juba/color-theme-tangotango")
+ (:keywords "tango" "palette" "color" "theme" "emacs")
+ (:maintainer "Julien Barnier")
+ (:authors
+ ("Julien Barnier")))])
+ (crux .
+ [(0 4 0)
+ ((seq
+ (1 11)))
+ "A Collection of Ridiculously Useful eXtensions" tar
+ ((:url . "https://github.com/bbatsov/crux")
+ (:maintainer "Bozhidar Batsov" . "bozhidar@batsov.dev")
+ (:authors
+ ("Bozhidar Batsov" . "bozhidar@batsov.dev"))
+ (:keywords "convenience"))])
+ (cyberpunk-theme .
+ [(1 22)
+ nil "Cyberpunk Color Theme" tar
+ ((:url . "https://github.com/n3mo/cyberpunk-theme.el")
+ (:keywords "color" "theme" "cyberpunk")
+ (:maintainer "Nicholas M. Van Horn" . "nvanhorn@protonmail.com")
+ (:authors
+ ("Nicholas M. Van Horn" . "nvanhorn@protonmail.com")))])
+ (d-mode .
+ [(202003130913)
+ ((emacs
+ (25 1)))
+ "D Programming Language major mode for (X)Emacs" tar
+ ((:maintainer "Russel Winder" . "russel@winder.org.uk")
+ (:authors
+ ("William Baxter"))
+ (:keywords "d" "programming" "language" "emacs" "cc-mode")
+ (:url . "https://elpa.nongnu.org/nongnu/d-mode.html"))])
+ (dart-mode .
+ [(1 0 7)
+ ((emacs
+ (24 3)))
+ "Major mode for editing Dart files" tar
+ ((:url . "https://github.com/bradyt/dart-mode")
+ (:maintainer "https://github.com/bradyt/dart-mode/issues")
+ (:authors
+ ("https://github.com/bradyt/dart-mode/issues"))
+ (:keywords "languages"))])
+ (dockerfile-mode .
+ [(1 5)
+ ((emacs
+ (24)))
+ "Major mode for editing Docker's Dockerfiles" tar
+ ((:url . "https://github.com/spotify/dockerfile-mode")
+ (:keywords "docker")
+ (:commit . "628315e2e4ab2f269548126444234caa057b2c75"))])
+ (dracula-theme .
+ [(1 7 0)
+ ((emacs
+ (24 3)))
+ "Dracula Theme" tar
+ ((:url . "https://github.com/dracula/emacs")
+ (:maintainer "Étienne Deparis" . "etienne@depar.is")
+ (:authors
+ ("film42")))])
+ (drupal-mode .
+ [(0 7 4)
+ ((php-mode
+ (1 5 0)))
+ "Advanced minor mode for Drupal development" tar
+ ((:url . "https://github.com/arnested/drupal-mode")
+ (:keywords "programming" "php" "drupal")
+ (:maintainer "Arne Jørgensen" . "arne@arnested.dk")
+ (:authors
+ ("Arne Jørgensen" . "arne@arnested.dk"))
+ (:commit . "ed90b0c4d808365e9ae9f16cc8a96eff17815621"))])
+ (editorconfig .
+ [(0 8 2)
+ ((cl-lib
+ (0 5))
+ (nadvice
+ (0 3))
+ (emacs
+ (24)))
+ "EditorConfig Emacs Plugin" tar
+ ((:url . "https://github.com/editorconfig/editorconfig-emacs#readme")
+ (:maintainer "EditorConfig Team" . "editorconfig@googlegroups.com")
+ (:authors
+ ("EditorConfig Team" . "editorconfig@googlegroups.com")))])
+ (elixir-mode .
+ [(2 4 0)
+ ((emacs
+ (25)))
+ "Major mode for editing Elixir files" tar
+ ((:url . "https://github.com/elixir-editors/emacs-elixir")
+ (:keywords "languages" "elixir")
+ (:commit . "1d94b525ddcc995b5a979de7b050c2309648ca6f"))])
+ (elpher .
+ [(3 4 1)
+ ((emacs
+ (27 1)))
+ "A friendly gopher and gemini client" tar
+ ((:url . "https://thelambdalab.xyz/elpher")
+ (:keywords "comm" "gopher")
+ (:maintainer "Tim Vaughan" . "plugd@thelambdalab.xyz")
+ (:authors
+ ("Tim Vaughan" . "plugd@thelambdalab.xyz"))
+ (:commit . "bf0dd36eb2f5b339c6b561dbe3ee9693565b484b"))])
+ (evil .
+ [(1 15 0)
+ nil "extensible vi layer" tar
+ ((:url . "https://github.com/emacs-evil/evil")
+ (:keywords "emulation" "vim")
+ (:maintainer "Tom Dalziel" . "tom.dalziel@gmail.com")
+ (:commit . "008a6cdb12f15e748979a7d1c2f26c34c84dedbf"))])
+ (evil-anzu .
+ [(0 2)
+ ((evil
+ (1 0 0))
+ (anzu
+ (0 46)))
+ "anzu for evil-mode" tar
+ ((:url . "https://github.com/syohex/emacs-evil-anzu")
+ (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com")
+ (:authors
+ ("Syohei YOSHIDA" . "syohex@gmail.com")
+ ("Fredrik Bergroth" . "fbergroth@gmail.com")))])
+ (evil-args .
+ [(1 1)
+ ((evil
+ (1 0 8)))
+ "Motions and text objects for delimited arguments in Evil." tar
+ ((:url . "http://github.com/wcsmith/evil-args")
+ (:keywords "evil" "vim-emulation")
+ (:maintainer "Connor Smith" . "wconnorsmith@gmail.com")
+ (:authors
+ ("Connor Smith" . "wconnorsmith@gmail.com"))
+ (:commit . "2671071a4a57eaee7cc8c27b9e4b6fc60fd2ccd3"))])
+ (evil-exchange .
+ [(0 41)
+ ((evil
+ (1 2 8))
+ (cl-lib
+ (0 3)))
+ "Exchange text more easily within Evil" tar
+ ((:url . "http://github.com/Dewdrops/evil-exchange")
+ (:keywords "evil" "plugin")
+ (:maintainer "Dewdrops" . "v_v_4474@126.com")
+ (:authors
+ ("Dewdrops" . "v_v_4474@126.com")))])
+ (evil-goggles .
+ [(0 0 2)
+ ((emacs
+ (24 4))
+ (evil
+ (1 0 0)))
+ "Add a visual hint to evil operations" tar
+ ((:url . "http://github.com/edkolev/evil-goggles")
+ (:keywords "emulations" "evil" "vim" "visual")
+ (:maintainer "edkolev" . "evgenysw@gmail.com")
+ (:authors
+ ("edkolev" . "evgenysw@gmail.com"))
+ (:commit . "7801d9204cd57d5aec11ef43b15357a431cf025c"))])
+ (evil-indent-plus .
+ [(1 0 1)
+ ((evil
+ (0))
+ (cl-lib
+ (0 5)))
+ "Evil textobjects based on indentation" tar
+ ((:url . "http://github.com/TheBB/evil-indent-plus")
+ (:keywords "convenience" "evil")
+ (:maintainer "Eivind Fonn" . "evfonn@gmail.com")
+ (:authors
+ ("Eivind Fonn" . "evfonn@gmail.com")))])
+ (evil-lisp-state .
+ [(8 2)
+ ((evil
+ (1 0 9))
+ (bind-map
+ (0))
+ (smartparens
+ (1 6 1)))
+ "An evil state to edit Lisp code" tar
+ ((:url . "https://github.com/syl20bnr/evil-lisp-state")
+ (:keywords "convenience" "editing" "evil" "smartparens" "lisp" "mnemonic")
+ (:maintainer "Sylvain Benner" . "sylvain.benner@gmail.com")
+ (:authors
+ ("Sylvain Benner" . "sylvain.benner@gmail.com")))])
+ (evil-matchit .
+ [(2 4 4)
+ ((evil
+ (1 14 0))
+ (emacs
+ (25 1)))
+ "Vim matchit ported to Evil" tar
+ ((:url . "http://github.com/redguardtoo/evil-matchit")
+ (:keywords "matchit" "vim" "evil")
+ (:maintainer "Chen Bin" . "chenbin.sh@gmail.com")
+ (:authors
+ ("Chen Bin" . "chenbin.sh@gmail.com"))
+ (:commit . "b314e816bacfc01bb7df9b19a06b18638af5cdbe"))])
+ (evil-nerd-commenter .
+ [(3 5 7)
+ ((emacs
+ (25 1)))
+ "Comment/uncomment lines efficiently. Like Nerd Commenter in Vim" tar
+ ((:url . "http://github.com/redguardtoo/evil-nerd-commenter")
+ (:keywords "convenience" "evil")
+ (:maintainer "Chen Bin" . "chenbin.sh@gmail.com")
+ (:authors
+ ("Chen Bin" . "chenbin.sh@gmail.com"))
+ (:commit . "29ced6fda6a76771a8a054ef55c13a1330793d4d"))])
+ (evil-numbers .
+ [(0 6)
+ ((emacs
+ (24 1))
+ (evil
+ (1 2 0)))
+ "Increment/decrement numbers like in VIM" tar
+ ((:url . "http://github.com/juliapath/evil-numbers")
+ (:keywords "convenience" "tools")
+ (:maintainer "Julia Path" . "julia@jpath.de")
+ (:authors
+ ("Michael Markert" . "markert.michael@googlemail.com")))])
+ (evil-visualstar .
+ [(0 2 0)
+ ((evil
+ (0)))
+ "Starts a * or # search from the visual selection" tar
+ ((:url . "https://github.com/bling/evil-visualstar")
+ (:keywords "evil" "vim" "visualstar")
+ (:maintainer "Bailey Ling")
+ (:authors
+ ("Bailey Ling")))])
+ (flymake-kondor .
+ [(0 1 3)
+ ((emacs
+ (26 1)))
+ "Linter with clj-kondo" tar
+ ((:url . "https://github.com/turbo-cafe/flymake-kondor")
+ (:maintainer "https://turbocafe.keybase.pub")
+ (:authors
+ ("https://turbocafe.keybase.pub")))])
+ (forth-mode .
+ [(0 2)
+ nil "Programming language mode for Forth" tar
+ ((:url . "http://github.com/larsbrinkhoff/forth-mode")
+ (:keywords "languages" "forth")
+ (:maintainer "Lars Brinkhoff" . "lars@nocrew.org")
+ (:authors
+ ("Lars Brinkhoff" . "lars@nocrew.org"))
+ (:commit . "38d5152011ee67e0cff9d4a5ddfb1f908e5be013"))])
+ (free-keys .
+ [(1 0)
+ ((cl-lib
+ (0 3)))
+ "Show free keybindings for modkeys or prefixes" tar
+ ((:url . "https://github.com/Fuco1/free-keys")
+ (:keywords "convenience")
+ (:maintainer "Matus Goljer" . "matus.goljer@gmail.com")
+ (:authors
+ ("Matus Goljer" . "matus.goljer@gmail.com"))
+ (:commit . "6f9172376af4d399c7853cbdfdd7425348a878f9"))])
+ (geiser .
+ [(0 23 2)
+ ((emacs
+ (25 1))
+ (transient
+ (0 3))
+ (project
+ (0 8 1)))
+ "GNU Emacs and Scheme talk to each other" tar
+ ((:url . "https://gitlab.com/emacs-geiser/")
+ (:keywords "languages" "scheme" "geiser")
+ (:maintainer "Jose Antonio Ortega Ruiz" . "jao@gnu.org")
+ (:authors
+ ("Jose Antonio Ortega Ruiz" . "jao@gnu.org"))
+ (:commit . "bc0dde310492de733f9ec528d7aeddd57093d05e"))])
+ (geiser-chez .
+ [(0 17)
+ ((emacs
+ (26 1))
+ (geiser
+ (0 19)))
+ "Chez Scheme's implementation of the geiser protocols" tar
+ ((:url . "https://gitlab.com/emacs-geiser/chez")
+ (:keywords "languages" "chez" "scheme" "geiser")
+ (:maintainer "Jose A Ortega Ruiz" . "jao@gnu.org")
+ (:authors
+ ("Peter" . "craven@gmx.net")))])
+ (geiser-chibi .
+ [(0 17)
+ ((emacs
+ (24 4))
+ (geiser
+ (0 18)))
+ "Chibi Scheme's implementation of the geiser protocols" tar
+ ((:url . "https://gitlab.com/emacs-geiser/chibi")
+ (:keywords "languages" "chibi" "scheme" "geiser")
+ (:maintainer "Jose A Ortega Ruiz" . "jao@gnu.org")
+ (:authors
+ ("Peter" . "craven@gmx.net")))])
+ (geiser-chicken .
+ [(0 17)
+ ((emacs
+ (24 4))
+ (geiser
+ (0 19)))
+ "Chicken's implementation of the geiser protocols" tar
+ ((:url . "https://gitlab.com/emacs-geiser/chicken")
+ (:keywords "languages" "chicken" "scheme" "geiser")
+ (:maintainer "Daniel Leslie")
+ (:authors
+ ("Daniel Leslie")))])
+ (geiser-gambit .
+ [(0 18 1)
+ ((emacs
+ (26 1))
+ (geiser
+ (0 18)))
+ "Gambit's implementation of the geiser protocols" tar
+ ((:url . "https://gitlab.com/emacs-geiser/gambit")
+ (:keywords "languages" "gambit" "scheme" "geiser")
+ (:maintainer "Jose A Ortega Ruiz" . "jao@gnu.org")
+ (:authors
+ ("Daniel Leslie"))
+ (:commit . "381d74ca5059b44fe3d8b5daf42214019c6d1a88"))])
+ (geiser-gauche .
+ [(0 0 2)
+ ((emacs
+ (26 1))
+ (geiser
+ (0 11 2)))
+ "Gauche scheme support for Geiser" tar
+ ((:url . "https://gitlab.com/emacs-geiser/gauche")
+ (:maintainer "András Simonyi" . "andras.simonyi@gmail.com")
+ (:authors
+ ("András Simonyi" . "andras.simonyi@gmail.com"))
+ (:keywords "languages" "gauche" "scheme" "geiser"))])
+ (geiser-guile .
+ [(0 23 2)
+ ((emacs
+ (25 1))
+ (geiser
+ (0 23 2)))
+ "Guile's implementation of the geiser protocols" tar
+ ((:url . "https://gitlab.com/emacs-geiser/guile")
+ (:keywords "languages" "guile" "scheme" "geiser")
+ (:maintainer "Jose Antonio Ortega Ruiz" . "jao@gnu.org")
+ (:authors
+ ("Jose Antonio Ortega Ruiz" . "jao@gnu.org"))
+ (:commit . "c641fcc50b6b86ca95743122b5206cdcd475f96e"))])
+ (geiser-kawa .
+ [(0 0 1)
+ ((emacs
+ (26 1))
+ (geiser
+ (0 16)))
+ "Kawa scheme support for Geiser" tar
+ ((:url . "https://gitlab.com/emacs-geiser/kawa")
+ (:maintainer "spellcard199" . "spellcard199@protonmail.com")
+ (:authors
+ ("spellcard199" . "spellcard199@protonmail.com"))
+ (:keywords "languages" "kawa" "scheme" "geiser"))])
+ (geiser-mit .
+ [(0 15)
+ ((emacs
+ (24 4))
+ (geiser
+ (0 18)))
+ "MIT/GNU Scheme's implementation of the geiser protocols" tar
+ ((:url . "https://gitlab.com/emacs-geiser/mit")
+ (:keywords "languages" "mit" "scheme" "geiser")
+ (:maintainer "Jose A Ortega Ruiz" . "jao@gnu.org")
+ (:authors
+ ("Peter" . "craven@gmx.net")))])
+ (geiser-racket .
+ [(0 16)
+ ((emacs
+ (26 1))
+ (geiser
+ (0 16)))
+ "Support for Racket in Geiser" tar
+ ((:url . "https://gitlab.com/emacs-geiser/racket")
+ (:maintainer "Jose Antonio Ortega Ruiz" . "jao@gnu.org")
+ (:authors
+ ("Jose Antonio Ortega Ruiz" . "jao@gnu.org"))
+ (:keywords "languages" "racket" "scheme" "geiser"))])
+ (geiser-stklos .
+ [(1 4)
+ ((emacs
+ (24 4))
+ (geiser
+ (0 16)))
+ "STklos Scheme implementation of the geiser protocols" tar
+ ((:url . "https://gitlab.com/emacs-geiser/stklos")
+ (:keywords "languages" "stklos" "scheme" "geiser")
+ (:maintainer "Jeronimo Pellegrini" . "j_p@aleph0.info")
+ (:authors
+ ("Jeronimo Pellegrini" . "j_p@aleph0.info")))])
+ (git-commit .
+ [(3 3 0)
+ ((emacs
+ (25 1))
+ (dash
+ (2 19 1))
+ (transient
+ (0 3 6))
+ (with-editor
+ (3 0 5)))
+ "Edit Git commit messages" tar
+ ((:url . "https://github.com/magit/magit")
+ (:keywords "git" "tools" "vc")
+ (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li")
+ (:authors
+ ("Jonas Bernoulli" . "jonas@bernoul.li")
+ ("Sebastian Wiesner" . "lunaryorn@gmail.com")
+ ("Florian Ragwitz" . "rafl@debian.org")
+ ("Marius Vollmer" . "marius.vollmer@gmail.com")))])
+ (git-modes .
+ [(1 4 0)
+ ((emacs
+ (24 3)))
+ "Major modes for editing Git configuration files" tar
+ ((:url . "https://github.com/magit/git-modes")
+ (:keywords "convenience" "vc" "git")
+ (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li")
+ (:authors
+ ("Sebastian Wiesner" . "lunaryorn@gmail.com")
+ ("Rüdiger Sonderfeld" . "ruediger@c-plusplus.net")
+ ("Jonas Bernoulli" . "jonas@bernoul.li")))])
+ (gnu-apl-mode .
+ [(1 5 1)
+ nil "Emacs mode for GNU APL" tar
+ ((:url . "http://www.gnu.org/software/apl/")
+ (:keywords "languages")
+ (:maintainer "Elias Mårtenson" . "lokedhs@gmail.com")
+ (:authors
+ ("Elias Mårtenson" . "lokedhs@gmail.com"))
+ (:commit . "deabf59d2375d4662221f8222e28caeb1be96428"))])
+ (gnuplot .
+ [(0 8 0)
+ ((emacs
+ (24 3)))
+ "Major-mode and interactive frontend for gnuplot" tar
+ ((:url . "https://github.com/emacsorphanage/gnuplot")
+ (:maintainer "Bruce Ravel" . "bruceravel1@gmail.com")
+ (:authors
+ ("Jon Oddie")
+ ("Bruce Ravel")
+ ("Phil Type"))
+ (:keywords "data" "gnuplot" "plotting"))])
+ (go-mode .
+ [(1 6 0)
+ ((emacs
+ (26 1)))
+ "Major mode for the Go programming language" tar
+ ((:url . "https://github.com/dominikh/go-mode.el")
+ (:keywords "languages" "go")
+ (:maintainer "The go-mode Authors")
+ (:authors
+ ("The go-mode Authors"))
+ (:commit . "3273fcece5d9ab7edd4f15b2d6bce61f4e5a0666"))])
+ (gotham-theme .
+ [(1 1 9)
+ ((emacs
+ (24 1)))
+ "A very dark Emacs color theme" tar
+ ((:url . "https://depp.brause.cc/gotham-theme")
+ (:maintainer "Vasilij Schneidermann" . "mail@vasilij.de")
+ (:authors
+ ("Vasilij Schneidermann" . "mail@vasilij.de")))])
+ (goto-chg .
+ [(1 7 5)
+ ((emacs
+ (24 1)))
+ "Go to last change" tar
+ ((:url . "https://github.com/emacs-evil/goto-chg")
+ (:keywords "convenience" "matching")
+ (:maintainer "Vasilij Schneidermann" . "mail@vasilij.de")
+ (:authors
+ ("David Andersson <l.david.andersson(at)sverige.nu>")))])
+ (graphql-mode .
+ [(1 0 0)
+ ((emacs
+ (24 3)))
+ "Major mode for editing GraphQL schemas" tar
+ ((:url . "https://github.com/davazp/graphql-mode")
+ (:keywords "languages")
+ (:maintainer "David Vazquez Pua" . "davazp@gmail.com")
+ (:authors
+ ("David Vazquez Pua" . "davazp@gmail.com"))
+ (:commit . "fe8d7e2db5581cd0cb7a69563bc44f0669f76322"))])
+ (gruvbox-theme .
+ [(1 26 0)
+ ((autothemer
+ (0 2)))
+ "A retro-groove colour theme for Emacs" tar
+ ((:url . "http://github.com/greduan/emacs-theme-gruvbox")
+ (:maintainer "Jason Milkins" . "jasonm23@gmail.com")
+ (:authors
+ ("Jason Milkins" . "jasonm23@gmail.com")))])
+ (guru-mode .
+ [(1 0)
+ nil "Become an Emacs guru" tar
+ ((:url . "https://github.com/bbatsov/guru-mode")
+ (:maintainer "Bozhidar Batsov")
+ (:authors
+ ("Bozhidar Batsov"))
+ (:keywords "convenience"))])
+ (haml-mode .
+ [(3 1 10)
+ ((emacs
+ (24))
+ (cl-lib
+ (0 5)))
+ "Major mode for editing Haml files" tar
+ ((:url . "https://github.com/nex3/haml-mode")
+ (:keywords "markup" "languages" "html")
+ (:maintainer "Natalie Weizenbaum")
+ (:authors
+ ("Natalie Weizenbaum")))])
+ (haskell-mode .
+ [(4 7 1)
+ nil "A Haskell editing mode" tar
+ ((:url . "https://github.com/haskell/haskell-mode")
+ (:maintainer "1992 Simon Marlow")
+ (:authors
+ ("1992 Simon Marlow")
+ ("1997-1998 Graeme E Moss" . "gem@cs.york.ac.uk")
+ ("Tommy Thorn" . "thorn@irisa.fr")
+ ("2001-2002 Reuben Thomas (>=v1.4)")
+ ("2003 Dave Love" . "fx@gnu.org")
+ ("2016 Arthur Fayzrakhmanov"))
+ (:keywords "faces" "files" "haskell"))])
+ (haskell-tng-mode .
+ [(0 0 1)
+ ((emacs
+ (27 1))
+ (popup
+ (0 5 3)))
+ "Major mode for editing Haskell" tar
+ ((:url . "https://gitlab.com/tseenshe/haskell-tng-mode")
+ (:keywords "languages"))])
+ (helm .
+ [(3 8 5)
+ ((helm-core
+ (3 8 4))
+ (popup
+ (0 5 3)))
+ "Helm is an Emacs incremental and narrowing framework" tar
+ ((:url . "https://emacs-helm.github.io/helm/")
+ (:maintainer "Thierry Volpiatto" . "thierry.volpiatto@gmail.com")
+ (:authors
+ ("Thierry Volpiatto" . "thierry.volpiatto@gmail.com"))
+ (:commit . "5e035c9193bf1e1d4bb709794a154957544dcfc7"))])
+ (helm-core .
+ [(3 8 5)
+ ((emacs
+ (25 1))
+ (async
+ (1 9 4)))
+ "Development files for Helm" tar
+ ((:url . "https://emacs-helm.github.io/helm/")
+ (:maintainer "Thierry Volpiatto" . "thierry.volpiatto@gmail.com")
+ (:authors
+ ("Thierry Volpiatto" . "thierry.volpiatto@gmail.com"))
+ (:commit . "5e035c9193bf1e1d4bb709794a154957544dcfc7"))])
+ (highlight-parentheses .
+ [(2 1 1)
+ ((emacs
+ (24 3)))
+ "Highlight surrounding parentheses" tar
+ ((:url . "https://sr.ht/~tsdh/highlight-parentheses.el/")
+ (:keywords "faces" "matching")
+ (:maintainer "Tassilo Horn" . "tsdh@gnu.org")
+ (:authors
+ ("Nikolaj Schumacher <bugs * nschum de>"))
+ (:commit . "438a1cb2563e2a2496be4678cc0df8d5b22caf5d"))])
+ (htmlize .
+ [(1 57)
+ nil "Convert buffer text and decorations to HTML." tar
+ ((:url . "https://github.com/hniksic/emacs-htmlize")
+ (:maintainer "Hrvoje Niksic" . "hniksic@gmail.com")
+ (:authors
+ ("Hrvoje Niksic" . "hniksic@gmail.com"))
+ (:keywords "hypermedia" "extensions"))])
+ (idris-mode .
+ [(1 1 0)
+ ((emacs
+ (24))
+ (prop-menu
+ (0 1))
+ (cl-lib
+ (0 5)))
+ "Major mode for editing Idris code" tar
+ ((:url . "https://github.com/idris-hackers/idris-mode")
+ (:keywords "languages"))])
+ (iedit .
+ [(0 9 9 9 9)
+ nil "Edit multiple regions in the same way simultaneously." tar
+ ((:url . "https://github.com/victorhge/iedit")
+ (:keywords "occurrence" "region" "simultaneous" "refactoring")
+ (:maintainer "Victor Ren" . "victorhge@gmail.com")
+ (:authors
+ ("Victor Ren" . "victorhge@gmail.com"))
+ (:commit . "699e179dac18c78698cba1a2052bee6f0bbc6bf7"))])
+ (inf-clojure .
+ [(3 1 0)
+ ((emacs
+ (25 1))
+ (clojure-mode
+ (5 11)))
+ "Run an external Clojure process in an Emacs buffer" tar
+ ((:url . "http://github.com/clojure-emacs/inf-clojure")
+ (:keywords "processes" "clojure"))])
+ (j-mode .
+ [(1 1 1)
+ nil "Major mode for editing J programs" tar
+ ((:url . "http://github.com/zellio/j-mode")
+ (:keywords "j" "languages"))])
+ (jade-mode .
+ [(1 0 1)
+ nil "Major mode for editing .jade files" tar
+ ((:url . "https://github.com/brianc/jade-mode")
+ (:keywords "languages")
+ (:maintainer "Brian M. Carlson and other contributors")
+ (:authors
+ ("Brian M. Carlson and other contributors"))
+ (:commit . "dad17dc86c93401646802a639a98dd2ec875db6f"))])
+ (jinja2-mode .
+ [(0 3)
+ nil "A major mode for jinja2" tar
+ ((:maintainer "Florian Mounier aka paradoxxxzero")
+ (:authors
+ ("Florian Mounier aka paradoxxxzero"))
+ (:url . "https://elpa.nongnu.org/nongnu/jinja2-mode.html")
+ (:commit . "a598357069a68b0ac2bf128c19edd8e899084cdc"))])
+ (julia-mode .
+ [(0 4)
+ ((emacs
+ (24 3)))
+ "Major mode for editing Julia source code" tar
+ ((:url . "https://github.com/JuliaEditorSupport/julia-emacs")
+ (:keywords "languages"))])
+ (keycast .
+ [(1 2 0)
+ ((emacs
+ (25 3)))
+ "Show current command and its key in the mode line" tar
+ ((:url . "https://github.com/tarsius/keycast")
+ (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li")
+ (:authors
+ ("Jonas Bernoulli" . "jonas@bernoul.li"))
+ (:commit . "98c2dda1a2ca0fc95f7425847a36abad5b31a4c7"))])
+ (kotlin-mode .
+ [(1 0 0)
+ ((emacs
+ (24 3)))
+ "Major mode for kotlin" tar
+ ((:keywords "languages")
+ (:maintainer "Shodai Yokoyama" . "quantumcars@gmail.com")
+ (:authors
+ ("Shodai Yokoyama" . "quantumcars@gmail.com"))
+ (:url . "https://elpa.nongnu.org/nongnu/kotlin-mode.html")
+ (:commit . "b9d03a769b91c6b15e99a9cadb8b1618e5205595"))])
+ (lua-mode .
+ [(20210802)
+ ((emacs
+ (24 3)))
+ "a major-mode for editing Lua scripts" tar
+ ((:url . "http://immerrr.github.com/lua-mode")
+ (:maintainer "2011-2013 immerrr" . "immerrr+lua@gmail.com")
+ (:authors
+ ("2011-2013 immerrr" . "immerrr+lua@gmail.com")
+ ("2010-2011 Reuben Thomas" . "rrt@sc3d.org")
+ ("2006 Juergen Hoetzel" . "juergen@hoetzel.info")
+ ("2004 various (support for Lua 5 and byte compilation)")
+ ("2001 Christian Vogler" . "cvogler@gradient.cis.upenn.edu")
+ ("1997 Bret Mogilefsky" . "mogul-lua@gelatinous.com")
+ ("tcl-mode by Gregor Schmid" . "schmid@fb3-s7.math.tu-berlin.de")
+ ("with tons of assistance from")
+ ("Paul Du Bois" . "pld-lua@gelatinous.com")
+ ("Aaron Smith" . "aaron-lua@gelatinous.com"))
+ (:keywords "languages" "processes" "tools"))])
+ (macrostep .
+ [(0 9)
+ ((cl-lib
+ (0 5)))
+ "interactive macro expander" tar
+ ((:url . "https://github.com/joddie/macrostep")
+ (:maintainer "joddie" . "j.j.oddie@gmail.com")
+ (:authors
+ ("joddie" . "j.j.oddie@gmail.com"))
+ (:keywords "lisp" "languages" "macro" "debugging"))])
+ (magit .
+ [(3 3 0)
+ ((emacs
+ (25 1))
+ (dash
+ (2 19 1))
+ (git-commit
+ (3 3 0))
+ (magit-section
+ (3 3 0))
+ (transient
+ (0 3 6))
+ (with-editor
+ (3 0 5)))
+ "A Git porcelain inside Emacs" tar
+ ((:url . "https://github.com/magit/magit")
+ (:keywords "git" "tools" "vc")
+ (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li")
+ (:authors
+ ("Marius Vollmer" . "marius.vollmer@gmail.com")
+ ("Jonas Bernoulli" . "jonas@bernoul.li")))])
+ (magit-section .
+ [(3 3 0)
+ ((emacs
+ (25 1))
+ (dash
+ (2 19 1)))
+ "Sections for read-only buffers" tar
+ ((:url . "https://github.com/magit/magit")
+ (:keywords "tools")
+ (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li")
+ (:authors
+ ("Jonas Bernoulli" . "jonas@bernoul.li")))])
+ (markdown-mode .
+ [(2 5)
+ ((emacs
+ (25 1)))
+ "Major mode for Markdown-formatted text" tar
+ ((:url . "https://jblevins.org/projects/markdown-mode/")
+ (:keywords "markdown" "github flavored markdown" "itex")
+ (:maintainer "Jason R. Blevins" . "jblevins@xbeta.org")
+ (:authors
+ ("Jason R. Blevins" . "jblevins@xbeta.org"))
+ (:commit . "eecf2f20b097f9e6a0eaf938af967122fbec35dd"))])
+ (material-theme .
+ [(2015)
+ ((emacs
+ (24 1)))
+ "A Theme based on the colors of the Google Material Design" tar
+ ((:url . "http://github.com/cpaulik/emacs-material-theme")
+ (:keywords "themes")
+ (:maintainer "Christoph Paulik" . "cpaulik@gmail.com")
+ (:authors
+ ("Christoph Paulik" . "cpaulik@gmail.com")))])
+ (mentor .
+ [(0 3 5)
+ ((emacs
+ (25 1))
+ (xml-rpc
+ (1 6 15))
+ (seq
+ (1 11))
+ (cl-lib
+ (0 5))
+ (async
+ (1 9 3)))
+ "Frontend for the rTorrent bittorrent client" tar
+ ((:keywords "comm" "processes" "bittorrent")
+ (:maintainer "Stefan Kangas" . "stefankangas@gmail.com")
+ (:authors
+ ("Stefan Kangas" . "stefankangas@gmail.com"))
+ (:url . "https://elpa.nongnu.org/nongnu/mentor.html"))])
+ (moe-theme .
+ [(1 0 2)
+ nil "A colorful eye-candy theme. Moe, moe, kyun!" tar
+ ((:url . "https://github.com/kuanyui/moe-theme.el")
+ (:keywords "themes")
+ (:maintainer "kuanyui" . "azazabc123@gmail.com")
+ (:authors
+ ("kuanyui" . "azazabc123@gmail.com")))])
+ (monokai-theme .
+ [(3 5 3)
+ nil "A fruity color theme for Emacs." tar
+ ((:url . "http://github.com/oneKelvinSmith/monokai-emacs")
+ (:maintainer "Kelvin Smith" . "oneKelvinSmith@gmail.com")
+ (:authors
+ ("Kelvin Smith" . "oneKelvinSmith@gmail.com")))])
+ (mpv .
+ [(0 2 0)
+ ((cl-lib
+ (0 5))
+ (emacs
+ (25 1))
+ (json
+ (1 3))
+ (org
+ (8 0)))
+ "control mpv for easy note-taking" tar
+ ((:url . "https://github.com/kljohann/mpv.el")
+ (:keywords "tools" "multimedia")
+ (:maintainer "Johann Klähn" . "johann@jklaehn.de")
+ (:authors
+ ("Johann Klähn" . "johann@jklaehn.de")))])
+ (multiple-cursors .
+ [(1 4 0)
+ nil "Multiple cursors for emacs." tar
+ ((:url . "https://github.com/magnars/multiple-cursors.el")
+ (:maintainer "Magnar Sveen" . "magnars@gmail.com")
+ (:authors
+ ("Magnar Sveen" . "magnars@gmail.com"))
+ (:keywords "editing" "cursors"))])
+ (nasm-mode .
+ [(1 1 1)
+ ((emacs
+ (24 3)))
+ "NASM x86 assembly major mode" tar
+ ((:url . "https://github.com/skeeto/nasm-mode")
+ (:maintainer "Christopher Wellons" . "wellons@nullprogram.com")
+ (:authors
+ ("Christopher Wellons" . "wellons@nullprogram.com")))])
+ (nginx-mode .
+ [(1 1 9)
+ nil "major mode for editing nginx config files" tar
+ ((:maintainer "Andrew J Cosgriff" . "andrew@cosgriff.name")
+ (:authors
+ ("Andrew J Cosgriff" . "andrew@cosgriff.name"))
+ (:keywords "languages" "nginx")
+ (:url . "https://elpa.nongnu.org/nongnu/nginx-mode.html"))])
+ (nix-mode .
+ [(1 4 4)
+ ((emacs
+ (25 1))
+ (magit-section
+ (0))
+ (transient
+ (0 3)))
+ "Major mode for editing .nix files" tar
+ ((:url . "https://github.com/NixOS/nix-mode")
+ (:keywords "nix" "languages" "tools" "unix")
+ (:maintainer "Matthew Bauer" . "mjbauer95@gmail.com")
+ (:commit . "e4e604ae3ac91748c4e7d51a591cb9ee60961b7c"))])
+ (org-contrib .
+ [(0 3)
+ ((emacs
+ (25 1))
+ (org
+ (9 4 6)))
+ "Unmaintained add-ons for Org-mode" tar
+ ((:url . "https://git.sr.ht/~bzg/org-contrib")
+ (:keywords "org")
+ (:maintainer "Bastien Guerry" . "bzg@gnu.org")
+ (:authors
+ ("Bastien Guerry" . "bzg@gnu.org")))])
+ (org-drill .
+ [(2 7 0)
+ ((emacs
+ (25 3))
+ (seq
+ (2 14))
+ (org
+ (9 3))
+ (persist
+ (0 3)))
+ "Self-testing using spaced repetition" tar
+ ((:url . "https://gitlab.com/phillord/org-drill/issues")
+ (:keywords "games" "outlines" "multimedia")
+ (:maintainer "Phillip Lord" . "phillip.lord@russet.org.uk")
+ (:authors
+ ("Paul Sexton" . "eeeickythump@gmail.com"))
+ (:commit . "4c114489e682e514e79701045d541ab6f3dc3fb4"))])
+ (org-journal .
+ [(2 1 2)
+ ((emacs
+ (25 1))
+ (org
+ (9 1)))
+ "a simple org-mode based journaling mode" tar
+ ((:url . "http://github.com/bastibe/org-journal")
+ (:maintainer "Bastian Bechtold")
+ (:authors
+ ("Bastian Bechtold")
+ ("Christian Schwarzgruber")))])
+ (org-mime .
+ [(0 2 6)
+ ((emacs
+ (25 1)))
+ "org html export for text/html MIME emails" tar
+ ((:url . "http://github.com/org-mime/org-mime")
+ (:keywords "mime" "mail" "email" "html")
+ (:maintainer "Chen Bin (redguardtoo)")
+ (:authors
+ ("Eric Schulte"))
+ (:commit . "3f1f3a38429da17811f61a7a5685224d79de9594"))])
+ (org-present .
+ [(0 1)
+ ((org
+ (7)))
+ "Minimalist presentation minor-mode for Emacs org-mode." tar
+ ((:url . "https://github.com/rlister/org-present")
+ (:maintainer "Ric Lister")
+ (:authors
+ ("Ric Lister")))])
+ (org-superstar .
+ [(1 5 1)
+ ((org
+ (9 1 9))
+ (emacs
+ (26 1)))
+ "Prettify headings and plain lists in Org mode" tar
+ ((:url . "https://github.com/integral-dw/org-superstar-mode")
+ (:keywords "faces" "outlines")
+ (:maintainer "D. Williams" . "d.williams@posteo.net")
+ (:authors
+ ("D. Williams" . "d.williams@posteo.net")))])
+ (org-tree-slide .
+ [(2 8 18)
+ ((emacs
+ (24 4)))
+ "A presentation tool for org-mode" tar
+ ((:url . "https://github.com/takaxp/org-tree-slide")
+ (:keywords "convenience" "org-mode" "presentation" "narrowing")
+ (:maintainer "Takaaki ISHIKAWA <takaxp at ieee dot org>")
+ (:authors
+ ("Takaaki ISHIKAWA <takaxp at ieee dot org>"))
+ (:commit . "1fb3ecb637d0baff40dff7965dcac63b9674377b"))])
+ (orgit .
+ [(1 8 0)
+ ((emacs
+ (25 1))
+ (magit
+ (3 0))
+ (org
+ (9 4)))
+ "support for Org links to Magit buffers" tar
+ ((:url . "https://github.com/magit/orgit")
+ (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li")
+ (:authors
+ ("Jonas Bernoulli" . "jonas@bernoul.li"))
+ (:commit . "0b49d7a869b8fef3537a75df4db693ca3e3935a3"))])
+ (pacmacs .
+ [(0 1 1)
+ ((emacs
+ (24 4))
+ (dash
+ (2 18 0)))
+ "Pacman for Emacs" tar
+ ((:url . "http://github.com/codingteam/pacmacs.el")
+ (:maintainer "Alexey Kutepov" . "reximkut@gmail.com")
+ (:authors
+ ("Codingteam" . "codingteam@conference.jabber.ru"))
+ (:commit . "071d008ebd734f469b87597cbdd34139a92e5308"))])
+ (parseclj .
+ [(1 1 0)
+ ((emacs
+ (25)))
+ "Clojure/EDN parser" tar
+ ((:keywords "lisp" "clojure" "edn" "parser")
+ (:maintainer "Arne Brasseur" . "arne@arnebrasseur.net")
+ (:authors
+ ("Arne Brasseur" . "arne@arnebrasseur.net"))
+ (:url . "https://elpa.nongnu.org/nongnu/parseclj.html")
+ (:commit . "90595049634549e6d8872f719b13e9555897d17b"))])
+ (parseedn .
+ [(1 1 0)
+ ((emacs
+ (26))
+ (parseclj
+ (1 1 0))
+ (map
+ (2)))
+ "Clojure/EDN parser" tar
+ ((:keywords "lisp" "clojure" "edn" "parser")
+ (:maintainer "Arne Brasseur" . "arne@arnebrasseur.net")
+ (:authors
+ ("Arne Brasseur" . "arne@arnebrasseur.net"))
+ (:url . "https://elpa.nongnu.org/nongnu/parseedn.html")
+ (:commit . "ea7b5281ec80aca0bd1cc93a348aebb302497339"))])
+ (pcmpl-args .
+ [(0 1 3)
+ ((emacs
+ (25 1)))
+ "Enhanced shell command completion" tar
+ ((:url . "https://github.com/JonWaltman/pcmpl-args.el")
+ (:keywords "abbrev" "completion" "convenience" "processes" "terminals" "unix")
+ (:maintainer "Jonathan Waltman" . "jonathan.waltman@gmail.com")
+ (:authors
+ ("Jonathan Waltman" . "jonathan.waltman@gmail.com"))
+ (:commit . "5f2943fd70d94065496c52d21f05eb89028637cc"))])
+ (pdf-tools .
+ [(1 0)
+ ((emacs
+ (24 3))
+ (tablist
+ (1 0))
+ (let-alist
+ (1 0 4)))
+ "Support library for PDF documents" tar
+ ((:url . "http://github.com/vedang/pdf-tools/")
+ (:keywords "files" "multimedia")
+ (:maintainer "Andreas Politz" . "politza@fh-trier.de")
+ (:authors
+ ("Andreas Politz" . "politza@fh-trier.de")))])
+ (php-mode .
+ [(1 24 0)
+ ((emacs
+ (25 2)))
+ "Major mode for editing PHP code" tar
+ ((:url . "https://github.com/emacs-php/php-mode")
+ (:maintainer "USAMI Kenta" . "tadsan@zonu.me")
+ (:authors
+ ("Eric James Michael Ritz"))
+ (:keywords "languages" "php"))])
+ (popup .
+ [(0 5 9)
+ ((emacs
+ (24 3)))
+ "Visual Popup User Interface" tar
+ ((:url . "https://github.com/auto-complete/popup-el")
+ (:keywords "lisp")
+ (:maintainer "Shen, Jen-Chieh" . "jcs090218@gmail.com")
+ (:authors
+ ("Tomohiro Matsuyama" . "m2ym.pub@gmail.com")))])
+ (projectile .
+ [(2 5 0)
+ ((emacs
+ (25 1)))
+ "Manage and navigate projects in Emacs easily" tar
+ ((:url . "https://github.com/bbatsov/projectile")
+ (:maintainer "Bozhidar Batsov" . "bozhidar@batsov.dev")
+ (:authors
+ ("Bozhidar Batsov" . "bozhidar@batsov.dev"))
+ (:keywords "project" "convenience"))])
+ (prop-menu .
+ [(0 1 2)
+ ((emacs
+ (24 3))
+ (cl-lib
+ (0 5)))
+ "Create and display a context menu based on text and overlay properties" tar
+ ((:url . "https://github.com/david-christiansen/prop-menu-el")
+ (:maintainer "David Christiansen" . "david@davidchristiansen.dk")
+ (:authors
+ ("David Christiansen" . "david@davidchristiansen.dk"))
+ (:keywords "convenience"))])
+ (rainbow-delimiters .
+ [(2 1 5)
+ nil "Highlight brackets according to their depth" tar
+ ((:url . "https://github.com/Fanael/rainbow-delimiters")
+ (:keywords "faces" "convenience" "lisp" "tools")
+ (:maintainer "Fanael Linithien" . "fanael4@gmail.com")
+ (:authors
+ ("Jeremy Rayman" . "opensource@jeremyrayman.com")
+ ("Fanael Linithien" . "fanael4@gmail.com")))])
+ (raku-mode .
+ [(0 2 1)
+ ((emacs
+ (24 4)))
+ "Major mode for editing Raku code" tar
+ ((:url . "https://github.com/hinrik/perl6-mode")
+ (:keywords "languages")
+ (:maintainer "Hinrik Örn Sigurðsson" . "hinrik.sig@gmail.com")
+ (:authors
+ ("Hinrik Örn Sigurðsson" . "hinrik.sig@gmail.com"))
+ (:commit . "4ee9045eeb90f7831d7c0ee2e4adfcd957f712be"))])
+ (request .
+ [(0 3 3)
+ ((emacs
+ (24 4)))
+ "Compatible layer for URL request in Emacs" tar
+ ((:url . "https://github.com/tkf/emacs-request")
+ (:maintainer "Takafumi Arakaki <aka.tkf at gmail.com>")
+ (:authors
+ ("Takafumi Arakaki <aka.tkf at gmail.com>")))])
+ (rubocop .
+ [(0 6 0)
+ ((emacs
+ (24)))
+ "An Emacs interface for RuboCop" tar
+ ((:url . "https://github.com/rubocop/rubocop-emacs")
+ (:maintainer "Bozhidar Batsov")
+ (:authors
+ ("Bozhidar Batsov"))
+ (:keywords "project" "convenience"))])
+ (rust-mode .
+ [(1 0 4)
+ ((emacs
+ (25 1)))
+ "A major-mode for editing Rust source code" tar
+ ((:url . "https://github.com/rust-lang/rust-mode")
+ (:keywords "languages")
+ (:maintainer "Mozilla")
+ (:authors
+ ("Mozilla"))
+ (:commit . "e35a1800fc0f9ed178539d6fb82ed885c1014fb5"))])
+ (sass-mode .
+ [(3 0 16)
+ ((haml-mode
+ (3 0 15))
+ (cl-lib
+ (0 5)))
+ "Major mode for editing Sass files" tar
+ ((:url . "http://github.com/nex3/haml/tree/master")
+ (:maintainer "Natalie Weizenbaum")
+ (:authors
+ ("Natalie Weizenbaum"))
+ (:keywords "markup" "language" "css"))])
+ (scala-mode .
+ [(0 23)
+ nil "Major mode for editing Scala" tar
+ ((:url . "https://github.com/hvesalai/emacs-scala-mode")
+ (:keywords "languages"))])
+ (sesman .
+ [(0 3 2)
+ ((emacs
+ (25)))
+ "Generic Session Manager" tar
+ ((:url . "https://github.com/vspinu/sesman")
+ (:keywords "process")
+ (:maintainer "Vitalie Spinu")
+ (:authors
+ ("Vitalie Spinu")))])
+ (shellcop .
+ [(0 0 9)
+ ((emacs
+ (25 1)))
+ "Analyze info&error in shell-mode" tar
+ ((:url . "https://github.com/redguardtoo/shellcop")
+ (:keywords "unix" "tools")
+ (:maintainer "Chen Bin" . "chenbin.sh@gmail.com")
+ (:authors
+ ("Chen Bin" . "chenbin.sh@gmail.com"))
+ (:commit . "327f5ac43e5d543149a772aef06cdb616477eb43"))])
+ (slime .
+ [(2 26 1)
+ ((cl-lib
+ (0 5))
+ (macrostep
+ (0 9)))
+ "Superior Lisp Interaction Mode for Emacs" tar
+ ((:url . "https://github.com/slime/slime")
+ (:keywords "languages" "lisp" "slime"))])
+ (sly .
+ [(1 0 43)
+ ((emacs
+ (24 3)))
+ "Sylvester the Cat's Common Lisp IDE" tar
+ ((:url . "https://github.com/joaotavora/sly")
+ (:keywords "languages" "lisp" "sly"))])
+ (smartparens .
+ [(4 7 1)
+ nil "Automatic insertion, wrapping and paredit-like navigation with user defined pairs." tar
+ ((:url . "https://github.com/Fuco1/smartparens")
+ (:maintainer "Matus Goljer" . "matus.goljer@gmail.com")
+ (:authors
+ ("Matus Goljer" . "matus.goljer@gmail.com"))
+ (:keywords "abbrev" "convenience" "editing"))])
+ (solarized-theme .
+ [(1 3 0)
+ ((emacs
+ (24 1)))
+ "The Solarized color theme" tar
+ ((:url . "http://github.com/bbatsov/solarized-emacs")
+ (:keywords "convenience" "themes" "solarized")
+ (:maintainer "Bozhidar Batsov" . "bozhidar@batsov.dev")
+ (:authors
+ ("Bozhidar Batsov" . "bozhidar@batsov.dev")))])
+ (spacemacs-theme .
+ [(0 2)
+ ((emacs
+ (24)))
+ "Color theme with a dark and light versions." tar
+ ((:url . "https://github.com/nashamri/spacemacs-theme")
+ (:keywords "color" "theme")
+ (:maintainer "Nasser Alshammari")
+ (:authors
+ ("Nasser Alshammari"))
+ (:commit . "4857e6eb7ea20be3a2631beee42d0644dff7eb1b"))])
+ (stylus-mode .
+ [(1 0 1)
+ nil "Major mode for editing .styl files" tar
+ ((:url . "https://github.com/brianc/jade-mode")
+ (:keywords "languages")
+ (:maintainer "Brian M. Carlson and other contributors")
+ (:authors
+ ("Brian M. Carlson and other contributors"))
+ (:commit . "dad17dc86c93401646802a639a98dd2ec875db6f"))])
+ (subatomic-theme .
+ [(1 8 2)
+ nil "Low contrast bluish color theme" tar
+ ((:url . "https://github.com/cryon/subatomic")
+ (:keywords "color-theme" "blue" "low contrast")
+ (:maintainer "John Olsson" . "john@cryon.se")
+ (:authors
+ ("John Olsson" . "john@cryon.se"))
+ (:commit . "2d5acd143a153e16372d59000e57d76291ab81dd"))])
+ (subed .
+ [(1 0 5)
+ ((emacs
+ (25 1)))
+ "A major mode for editing subtitles" tar
+ ((:url . "https://github.com/sachac/subed")
+ (:keywords "convenience" "files" "hypermedia" "multimedia")
+ (:maintainer "Sacha Chua" . "sacha@sachachua.com")
+ (:authors
+ ("Random User"))
+ (:commit . "7a0c36c808e107b5851ba48ec3825dfa3c1a902e"))])
+ (swift-mode .
+ [(8 4 2)
+ ((emacs
+ (24 4))
+ (seq
+ (2 3)))
+ "Major-mode for Apple's Swift programming language" tar
+ ((:url . "https://github.com/swift-emacs/swift-mode")
+ (:keywords "languages" "swift")
+ (:maintainer "taku0 (http://github.com/taku0)")
+ (:authors
+ ("taku0 (http://github.com/taku0)")
+ ("Chris Barrett" . "chris.d.barrett@me.com")
+ ("Bozhidar Batsov" . "bozhidar@batsov.com")
+ ("Arthur Evstifeev" . "lod@pisem.net")))])
+ (systemd .
+ [(1 6)
+ ((emacs
+ (24 4)))
+ "Major mode for editing systemd units" tar
+ ((:maintainer "Mark Oteiza" . "mvoteiza@udel.edu")
+ (:authors
+ ("Mark Oteiza" . "mvoteiza@udel.edu"))
+ (:keywords "tools" "unix")
+ (:url . "https://elpa.nongnu.org/nongnu/systemd.html"))])
+ (tablist .
+ [(1 0)
+ ((emacs
+ (24 3)))
+ "Extended tabulated-list-mode" tar
+ ((:keywords "extensions" "lisp")
+ (:maintainer "Andreas Politz" . "politza@fh-trier.de")
+ (:authors
+ ("Andreas Politz" . "politza@fh-trier.de"))
+ (:url . "https://elpa.nongnu.org/nongnu/tablist.html"))])
+ (tangotango-theme .
+ [(0 0 7)
+ nil "Tango Palette color theme for Emacs 24." tar
+ ((:url . "https://github.com/juba/color-theme-tangotango")
+ (:keywords "tango" "palette" "color" "theme" "emacs")
+ (:maintainer "Julien Barnier")
+ (:authors
+ ("Julien Barnier")))])
+ (telephone-line .
+ [(0 5)
+ ((emacs
+ (24 4))
+ (cl-lib
+ (0 5))
+ (cl-generic
+ (0 2))
+ (seq
+ (1 8)))
+ "Rewrite of Powerline" tar
+ ((:url . "https://github.com/dbordak/telephone-line")
+ (:keywords "mode-line")
+ (:maintainer "Daniel Bordak" . "dbordak@fastmail.fm")
+ (:authors
+ ("Daniel Bordak" . "dbordak@fastmail.fm")))])
+ (textile-mode .
+ [(1 0 0)
+ nil "Textile markup editing major mode" tar
+ ((:url . "https://github.com/juba/textile-mode")
+ (:keywords "wp" "languages")
+ (:maintainer "Julien Barnier" . "julien@nozav.org")
+ (:authors
+ ("Julien Barnier" . "julien@nozav.org"))
+ (:commit . "16ac26b5b4c9bb5c7a3c7aed6c6b3a6c5fb8c62c"))])
+ (toc-org .
+ [(1 1)
+ nil "add table of contents to org-mode files (formerly, org-toc)" tar
+ ((:url . "https://github.com/snosov1/toc-org")
+ (:keywords "org-mode" "org-toc" "toc-org" "org" "toc" "table" "of" "contents")
+ (:maintainer "Sergei Nosov <sergei.nosov [at] gmail.com>")
+ (:authors
+ ("Sergei Nosov <sergei.nosov [at] gmail.com>")))])
+ (tuareg .
+ [(2 3 0)
+ ((caml
+ (3 12 0 1))
+ (emacs
+ (24 4)))
+ "OCaml mode for Emacs." tar
+ ((:url . "https://github.com/ocaml/tuareg")
+ (:maintainer "Albert Cohen" . "Albert.Cohen@inria.fr")
+ (:authors
+ ("Albert Cohen" . "Albert.Cohen@inria.fr")
+ ("Sam Steingold" . "sds@gnu.org")
+ ("Christophe Troestler" . "Christophe.Troestler@umons.ac.be")
+ ("Till Varoquaux" . "till@pps.jussieu.fr")
+ ("Sean McLaughlin" . "seanmcl@gmail.com")
+ ("Stefan Monnier" . "monnier@iro.umontreal.ca"))
+ (:keywords "ocaml" "languages"))])
+ (typescript-mode .
+ [(0 4)
+ ((emacs
+ (24 3)))
+ "Major mode for editing typescript" tar
+ ((:url . "http://github.com/ananthakumaran/typescript.el")
+ (:keywords "typescript" "languages")
+ (:commit . "2a58631230fe2d176352af262a0efdecc21f90ac"))])
+ (ujelly-theme .
+ [(1 2 9)
+ nil "Ujelly theme for GNU Emacs 24 (deftheme)" tar
+ ((:url . "http://github.com/marktran/color-theme-ujelly")
+ (:maintainer "Mark Tran" . "mark.tran@gmail.com")
+ (:authors
+ ("Mark Tran" . "mark.tran@gmail.com")))])
+ (vc-fossil .
+ [(20210928)
+ nil "VC backend for the fossil sofware configuraiton management system" tar
+ ((:maintainer "Alfred M. Szmidt" . "ams@gnu.org")
+ (:authors
+ ("Venkat Iyer" . "venkat@comit.com"))
+ (:url . "https://elpa.nongnu.org/nongnu/vc-fossil.html"))])
+ (visual-fill-column .
+ [(2 4)
+ ((emacs
+ (25 1)))
+ "fill-column for visual-line-mode" tar
+ ((:url . "https://codeberg.org/joostkremers/visual-fill-column")
+ (:maintainer "Joost Kremers" . "joostkremers@fastmail.fm")
+ (:authors
+ ("Joost Kremers" . "joostkremers@fastmail.fm")))])
+ (web-mode .
+ [(17 2 0)
+ ((emacs
+ (23 1)))
+ "major mode for editing web templates" tar
+ ((:url . "https://web-mode.org")
+ (:keywords "languages")
+ (:maintainer "François-Xavier Bois" . "fxbois@gmail.com")
+ (:authors
+ ("François-Xavier Bois"))
+ (:commit . "f70277774a725e177774cc81ecbd228792cd6656"))])
+ (webpaste .
+ [(3 2 2)
+ ((emacs
+ (24 4))
+ (request
+ (0 2 0))
+ (cl-lib
+ (0 5)))
+ "Paste to pastebin-like services" tar
+ ((:url . "https://github.com/etu/webpaste.el")
+ (:keywords "convenience" "comm" "paste")
+ (:maintainer "Elis \"etu\" Hirwing" . "elis@hirwing.se")
+ (:authors
+ ("Elis \"etu\" Hirwing" . "elis@hirwing.se")))])
+ (wgrep .
+ [(2 3 3)
+ nil "Writable grep buffer and apply the changes to files" tar
+ ((:url . "http://github.com/mhayashi1120/Emacs-wgrep/raw/master/wgrep.el")
+ (:maintainer "Masahiro Hayashi" . "mhayashi1120@gmail.com")
+ (:authors
+ ("Masahiro Hayashi" . "mhayashi1120@gmail.com"))
+ (:keywords "grep" "edit" "extensions"))])
+ (with-editor .
+ [(3 2 0)
+ ((emacs
+ (24 4)))
+ "Use the Emacsclient as $EDITOR" tar
+ ((:url . "https://github.com/magit/with-editor")
+ (:keywords "tools")
+ (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li")
+ (:authors
+ ("Jonas Bernoulli" . "jonas@bernoul.li"))
+ (:commit . "a762199d9bb8ee60311eaabf791b3dd64140effd"))])
+ (with-simulated-input .
+ [(3 0)
+ ((emacs
+ (24 4)))
+ "A macro to simulate user input non-interactively" tar
+ ((:url . "https://github.com/DarwinAwardWinner/with-simulated-input")
+ (:keywords "lisp" "tools" "extensions")
+ (:maintainer "Ryan C Thompson" . "rct@thompsonclan.org")
+ (:authors
+ ("Ryan C. Thompson" . "rct@thompsonclan.org")
+ ("Nikita Bloshchanevich" . "nikblos@outlook.com"))
+ (:commit . "07bdfbe9ab9eab4a04ad02e98b011649a4f4e6a2"))])
+ (ws-butler .
+ [(0 6)
+ nil "Unobtrusively remove trailing whitespace." tar
+ ((:url . "https://github.com/lewang/ws-butler")
+ (:maintainer "Le Wang")
+ (:authors
+ ("Le Wang")))])
+ (xah-fly-keys .
+ [(17 7 20220429090059)
+ ((emacs
+ (24 1)))
+ "ergonomic modal keybinding minor mode." tar
+ ((:url . "http://xahlee.info/emacs/misc/ergoemacs_vi_mode.html")
+ (:keywords "convenience" "emulations" "vim" "ergoemacs")
+ (:maintainer "Xah Lee" . "xah@xahlee.org")
+ (:authors
+ ("Xah Lee ( http://xahlee.info/ )"))
+ (:commit . "e4db51a90d13eb886b88bbba6a71846653a76e47"))])
+ (xml-rpc .
+ [(1 6 15)
+ nil "An elisp implementation of clientside XML-RPC" tar
+ ((:url . "http://github.com/xml-rpc-el/xml-rpc-el")
+ (:keywords "xml" "rpc" "network")
+ (:maintainer "Mark A. Hershberger" . "mah@everybody.org"))])
+ (yaml-mode .
+ [(0 0 15)
+ ((emacs
+ (24 1)))
+ "Major mode for editing YAML files" tar
+ ((:url . "https://github.com/yoshiki/yaml-mode")
+ (:maintainer "Vasilij Schneidermann" . "mail@vasilij.de")
+ (:authors
+ ("Yoshiki Kurihara" . "clouder@gmail.com")
+ ("Marshall T. Vandegrift" . "llasram@gmail.com"))
+ (:keywords "data" "yaml"))])
+ (yasnippet-snippets .
+ [(1 0)
+ ((yasnippet
+ (0 8 0)))
+ "Collection of yasnippet snippets" tar
+ ((:url . "https://github.com/AndreaCrotti/yasnippet-snippets")
+ (:maintainer "Andrea Crotti" . "andrea.crotti.0@gmail.com")
+ (:authors
+ ("Andrea Crotti" . "andrea.crotti.0@gmail.com"))
+ (:keywords "snippets"))])
+ (zenburn-theme .
+ [(2 7 0)
+ nil "A low contrast color theme for Emacs." tar
+ ((:url . "http://github.com/bbatsov/zenburn-emacs")
+ (:maintainer "Bozhidar Batsov" . "bozhidar@batsov.com")
+ (:authors
+ ("Bozhidar Batsov" . "bozhidar@batsov.com")))])
+ (zig-mode .
+ [(0 0 8)
+ ((emacs
+ (24 3)))
+ "A major mode for the Zig programming language" tar
+ ((:url . "https://github.com/zig-lang/zig-mode")
+ (:maintainer "Andrea Orru <andreaorru1991@gmail.com>, Andrew Kelley" . "superjoe30@gmail.com")
+ (:authors
+ ("Andrea Orru <andreaorru1991@gmail.com>, Andrew Kelley" . "superjoe30@gmail.com"))
+ (:keywords "zig" "languages"))]))
diff --git a/elpa/archives/nongnu/archive-contents.signed b/elpa/archives/nongnu/archive-contents.signed
new file mode 100644
index 0000000..6f187af
--- /dev/null
+++ b/elpa/archives/nongnu/archive-contents.signed
@@ -0,0 +1 @@
+Good signature from 066DAFCB81E42C40 GNU ELPA Signing Agent (2019) <elpasign@elpa.gnu.org> (trust undefined) created at 2022-05-03T14:45:04+0530 using RSA \ No newline at end of file
diff --git a/elpa/bind-key-20210210.1609/bind-key-autoloads.el b/elpa/bind-key-20210210.1609/bind-key-autoloads.el
new file mode 100644
index 0000000..843664d
--- /dev/null
+++ b/elpa/bind-key-20210210.1609/bind-key-autoloads.el
@@ -0,0 +1,84 @@
+;;; bind-key-autoloads.el --- automatically extracted autoloads -*- lexical-binding: t -*-
+;;
+;;; Code:
+
+(add-to-list 'load-path (directory-file-name
+ (or (file-name-directory #$) (car load-path))))
+
+
+;;;### (autoloads nil "bind-key" "bind-key.el" (0 0 0 0))
+;;; Generated autoloads from bind-key.el
+
+(autoload 'bind-key "bind-key" "\
+Bind KEY-NAME to COMMAND in KEYMAP (`global-map' if not passed).
+
+KEY-NAME may be a vector, in which case it is passed straight to
+`define-key'. Or it may be a string to be interpreted as
+spelled-out keystrokes, e.g., \"C-c C-z\". See documentation of
+`edmacro-mode' for details.
+
+COMMAND must be an interactive function or lambda form.
+
+KEYMAP, if present, should be a keymap variable or symbol.
+For example:
+
+ (bind-key \"M-h\" #'some-interactive-function my-mode-map)
+
+ (bind-key \"M-h\" #'some-interactive-function 'my-mode-map)
+
+If PREDICATE is non-nil, it is a form evaluated to determine when
+a key should be bound. It must return non-nil in such cases.
+Emacs can evaluate this form at any time that it does redisplay
+or operates on menu data structures, so you should write it so it
+can safely be called at any time.
+
+\(fn KEY-NAME COMMAND &optional KEYMAP PREDICATE)" nil t)
+
+(autoload 'unbind-key "bind-key" "\
+Unbind the given KEY-NAME, within the KEYMAP (if specified).
+See `bind-key' for more details.
+
+\(fn KEY-NAME &optional KEYMAP)" nil t)
+
+(autoload 'bind-key* "bind-key" "\
+Similar to `bind-key', but overrides any mode-specific bindings.
+
+\(fn KEY-NAME COMMAND &optional PREDICATE)" nil t)
+
+(autoload 'bind-keys "bind-key" "\
+Bind multiple keys at once.
+
+Accepts keyword arguments:
+:map MAP - a keymap into which the keybindings should be
+ added
+:prefix KEY - prefix key for these bindings
+:prefix-map MAP - name of the prefix map that should be created
+ for these bindings
+:prefix-docstring STR - docstring for the prefix-map variable
+:menu-name NAME - optional menu string for prefix map
+:filter FORM - optional form to determine when bindings apply
+
+The rest of the arguments are conses of keybinding string and a
+function symbol (unquoted).
+
+\(fn &rest ARGS)" nil t)
+
+(autoload 'bind-keys* "bind-key" "\
+
+
+\(fn &rest ARGS)" nil t)
+
+(autoload 'describe-personal-keybindings "bind-key" "\
+Display all the personal keybindings defined by `bind-key'." t nil)
+
+(register-definition-prefixes "bind-key" '("bind-key" "compare-keybindings" "get-binding-description" "override-global-m" "personal-keybindings"))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; coding: utf-8
+;; End:
+;;; bind-key-autoloads.el ends here
diff --git a/elpa/bind-key-20210210.1609/bind-key-pkg.el b/elpa/bind-key-20210210.1609/bind-key-pkg.el
new file mode 100644
index 0000000..bf10ec7
--- /dev/null
+++ b/elpa/bind-key-20210210.1609/bind-key-pkg.el
@@ -0,0 +1,2 @@
+;;; Generated package description from bind-key.el -*- no-byte-compile: t -*-
+(define-package "bind-key" "20210210.1609" "A simple way to manage personal keybindings" 'nil :commit "a7422fb8ab1baee19adb2717b5b47b9c3812a84c" :authors '(("John Wiegley" . "johnw@newartisans.com")) :maintainer '("John Wiegley" . "johnw@newartisans.com") :keywords '("keys" "keybinding" "config" "dotemacs") :url "https://github.com/jwiegley/use-package")
diff --git a/elpa/bind-key-20210210.1609/bind-key.el b/elpa/bind-key-20210210.1609/bind-key.el
new file mode 100644
index 0000000..78c6478
--- /dev/null
+++ b/elpa/bind-key-20210210.1609/bind-key.el
@@ -0,0 +1,492 @@
+;;; bind-key.el --- A simple way to manage personal keybindings
+
+;; Copyright (c) 2012-2017 John Wiegley
+
+;; Author: John Wiegley <johnw@newartisans.com>
+;; Maintainer: John Wiegley <johnw@newartisans.com>
+;; Created: 16 Jun 2012
+;; Modified: 29 Nov 2017
+;; Version: 2.4
+;; Package-Version: 20210210.1609
+;; Package-Commit: a7422fb8ab1baee19adb2717b5b47b9c3812a84c
+;; Keywords: keys keybinding config dotemacs
+;; URL: https://github.com/jwiegley/use-package
+
+;; 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 gnu emacs; see the file copying. if not, write to the
+;; free software foundation, inc., 59 temple place - suite 330,
+;; boston, ma 02111-1307, usa.
+
+;;; Commentary:
+
+;; If you have lots of keybindings set in your .emacs file, it can be hard to
+;; know which ones you haven't set yet, and which may now be overriding some
+;; new default in a new emacs version. This module aims to solve that
+;; problem.
+;;
+;; Bind keys as follows in your .emacs:
+;;
+;; (require 'bind-key)
+;;
+;; (bind-key "C-c x" 'my-ctrl-c-x-command)
+;;
+;; If the keybinding argument is a vector, it is passed straight to
+;; `define-key', so remapping a key with `[remap COMMAND]' works as
+;; expected:
+;;
+;; (bind-key [remap original-ctrl-c-x-command] 'my-ctrl-c-x-command)
+;;
+;; If you want the keybinding to override all minor modes that may also bind
+;; the same key, use the `bind-key*' form:
+;;
+;; (bind-key* "<C-return>" 'other-window)
+;;
+;; If you want to rebind a key only in a particular keymap, use:
+;;
+;; (bind-key "C-c x" 'my-ctrl-c-x-command some-other-mode-map)
+;;
+;; To unbind a key within a keymap (for example, to stop your favorite major
+;; mode from changing a binding that you don't want to override everywhere),
+;; use `unbind-key':
+;;
+;; (unbind-key "C-c x" some-other-mode-map)
+;;
+;; To bind multiple keys at once, or set up a prefix map, a `bind-keys' macro
+;; is provided. It accepts keyword arguments, please see its documentation
+;; for a detailed description.
+;;
+;; To add keys into a specific map, use :map argument
+;;
+;; (bind-keys :map dired-mode-map
+;; ("o" . dired-omit-mode)
+;; ("a" . some-custom-dired-function))
+;;
+;; To set up a prefix map, use `:prefix-map' and `:prefix' arguments (both are
+;; required)
+;;
+;; (bind-keys :prefix-map my-customize-prefix-map
+;; :prefix "C-c c"
+;; ("f" . customize-face)
+;; ("v" . customize-variable))
+;;
+;; You can combine all the keywords together. Additionally,
+;; `:prefix-docstring' can be specified to set documentation of created
+;; `:prefix-map' variable.
+;;
+;; To bind multiple keys in a `bind-key*' way (to be sure that your bindings
+;; will not be overridden by other modes), you may use `bind-keys*' macro:
+;;
+;; (bind-keys*
+;; ("C-o" . other-window)
+;; ("C-M-n" . forward-page)
+;; ("C-M-p" . backward-page))
+;;
+;; After Emacs loads, you can see a summary of all your personal keybindings
+;; currently in effect with this command:
+;;
+;; M-x describe-personal-keybindings
+;;
+;; This display will tell you if you've overridden a default keybinding, and
+;; what the default was. Also, it will tell you if the key was rebound after
+;; your binding it with `bind-key', and what it was rebound it to.
+
+;;; Code:
+
+(require 'cl-lib)
+(require 'easy-mmode)
+
+(defgroup bind-key nil
+ "A simple way to manage personal keybindings"
+ :group 'emacs)
+
+(defcustom bind-key-column-widths '(18 . 40)
+ "Width of columns in `describe-personal-keybindings'."
+ :type '(cons integer integer)
+ :group 'bind-key)
+
+(defcustom bind-key-segregation-regexp
+ "\\`\\(\\(C-[chx] \\|M-[gso] \\)\\([CM]-\\)?\\|.+-\\)"
+ "Regular expression used to divide key sets in the output from
+\\[describe-personal-keybindings]."
+ :type 'regexp
+ :group 'bind-key)
+
+(defcustom bind-key-describe-special-forms nil
+ "If non-nil, extract docstrings from lambdas, closures and keymaps if possible."
+ :type 'boolean
+ :group 'bind-key)
+
+;; Create override-global-mode to force key remappings
+
+(defvar override-global-map (make-keymap)
+ "override-global-mode keymap")
+
+(define-minor-mode override-global-mode
+ "A minor mode so that keymap settings override other modes."
+ t "")
+
+;; the keymaps in `emulation-mode-map-alists' take precedence over
+;; `minor-mode-map-alist'
+(add-to-list 'emulation-mode-map-alists
+ `((override-global-mode . ,override-global-map)))
+
+(defvar personal-keybindings nil
+ "List of bindings performed by `bind-key'.
+
+Elements have the form ((KEY . [MAP]) CMD ORIGINAL-CMD)")
+
+;;;###autoload
+(defmacro bind-key (key-name command &optional keymap predicate)
+ "Bind KEY-NAME to COMMAND in KEYMAP (`global-map' if not passed).
+
+KEY-NAME may be a vector, in which case it is passed straight to
+`define-key'. Or it may be a string to be interpreted as
+spelled-out keystrokes, e.g., \"C-c C-z\". See documentation of
+`edmacro-mode' for details.
+
+COMMAND must be an interactive function or lambda form.
+
+KEYMAP, if present, should be a keymap variable or symbol.
+For example:
+
+ (bind-key \"M-h\" #'some-interactive-function my-mode-map)
+
+ (bind-key \"M-h\" #'some-interactive-function 'my-mode-map)
+
+If PREDICATE is non-nil, it is a form evaluated to determine when
+a key should be bound. It must return non-nil in such cases.
+Emacs can evaluate this form at any time that it does redisplay
+or operates on menu data structures, so you should write it so it
+can safely be called at any time."
+ (let ((namevar (make-symbol "name"))
+ (keyvar (make-symbol "key"))
+ (kmapvar (make-symbol "kmap"))
+ (kdescvar (make-symbol "kdesc"))
+ (bindingvar (make-symbol "binding")))
+ `(let* ((,namevar ,key-name)
+ (,keyvar (if (vectorp ,namevar) ,namevar
+ (read-kbd-macro ,namevar)))
+ (,kmapvar (or (if (and ,keymap (symbolp ,keymap))
+ (symbol-value ,keymap) ,keymap)
+ global-map))
+ (,kdescvar (cons (if (stringp ,namevar) ,namevar
+ (key-description ,namevar))
+ (if (symbolp ,keymap) ,keymap (quote ,keymap))))
+ (,bindingvar (lookup-key ,kmapvar ,keyvar)))
+ (let ((entry (assoc ,kdescvar personal-keybindings))
+ (details (list ,command
+ (unless (numberp ,bindingvar)
+ ,bindingvar))))
+ (if entry
+ (setcdr entry details)
+ (add-to-list 'personal-keybindings (cons ,kdescvar details))))
+ ,(if predicate
+ `(define-key ,kmapvar ,keyvar
+ '(menu-item "" nil :filter (lambda (&optional _)
+ (when ,predicate
+ ,command))))
+ `(define-key ,kmapvar ,keyvar ,command)))))
+
+;;;###autoload
+(defmacro unbind-key (key-name &optional keymap)
+ "Unbind the given KEY-NAME, within the KEYMAP (if specified).
+See `bind-key' for more details."
+ (let ((namevar (make-symbol "name"))
+ (kdescvar (make-symbol "kdesc")))
+ `(let* ((,namevar ,key-name)
+ (,kdescvar (cons (if (stringp ,namevar) ,namevar
+ (key-description ,namevar))
+ (if (symbolp ,keymap) ,keymap (quote ,keymap)))))
+ (bind-key--remove (if (vectorp ,namevar) ,namevar
+ (read-kbd-macro ,namevar))
+ (or (if (and ,keymap (symbolp ,keymap))
+ (symbol-value ,keymap) ,keymap)
+ global-map))
+ (setq personal-keybindings
+ (cl-delete-if (lambda (k) (equal (car k) ,kdescvar))
+ personal-keybindings))
+ nil)))
+
+(defun bind-key--remove (key keymap)
+ "Remove KEY from KEYMAP.
+
+In contrast to `define-key', this function removes the binding from the keymap."
+ (define-key keymap key nil)
+ ;; Split M-key in ESC key
+ (setq key (mapcan (lambda (k)
+ (if (and (integerp k) (/= (logand k ?\M-\0) 0))
+ (list ?\e (logxor k ?\M-\0))
+ (list k)))
+ key))
+ ;; Delete single keys directly
+ (if (= (length key) 1)
+ (delete key keymap)
+ ;; Lookup submap and delete key from there
+ (let* ((prefix (vconcat (butlast key)))
+ (submap (lookup-key keymap prefix)))
+ (unless (keymapp submap)
+ (error "Not a keymap for %s" key))
+ (when (symbolp submap)
+ (setq submap (symbol-function submap)))
+ (delete (last key) submap)
+ ;; Delete submap if it is empty
+ (when (= 1 (length submap))
+ (bind-key--remove prefix keymap)))))
+
+;;;###autoload
+(defmacro bind-key* (key-name command &optional predicate)
+ "Similar to `bind-key', but overrides any mode-specific bindings."
+ `(bind-key ,key-name ,command override-global-map ,predicate))
+
+(defun bind-keys-form (args keymap)
+ "Bind multiple keys at once.
+
+Accepts keyword arguments:
+:map MAP - a keymap into which the keybindings should be
+ added
+:prefix KEY - prefix key for these bindings
+:prefix-map MAP - name of the prefix map that should be created
+ for these bindings
+:prefix-docstring STR - docstring for the prefix-map variable
+:menu-name NAME - optional menu string for prefix map
+:filter FORM - optional form to determine when bindings apply
+
+The rest of the arguments are conses of keybinding string and a
+function symbol (unquoted)."
+ (let (map
+ doc
+ prefix-map
+ prefix
+ filter
+ menu-name
+ pkg)
+
+ ;; Process any initial keyword arguments
+ (let ((cont t))
+ (while (and cont args)
+ (if (cond ((and (eq :map (car args))
+ (not prefix-map))
+ (setq map (cadr args)))
+ ((eq :prefix-docstring (car args))
+ (setq doc (cadr args)))
+ ((and (eq :prefix-map (car args))
+ (not (memq map '(global-map
+ override-global-map))))
+ (setq prefix-map (cadr args)))
+ ((eq :prefix (car args))
+ (setq prefix (cadr args)))
+ ((eq :filter (car args))
+ (setq filter (cadr args)) t)
+ ((eq :menu-name (car args))
+ (setq menu-name (cadr args)))
+ ((eq :package (car args))
+ (setq pkg (cadr args))))
+ (setq args (cddr args))
+ (setq cont nil))))
+
+ (when (or (and prefix-map (not prefix))
+ (and prefix (not prefix-map)))
+ (error "Both :prefix-map and :prefix must be supplied"))
+
+ (when (and menu-name (not prefix))
+ (error "If :menu-name is supplied, :prefix must be too"))
+
+ (unless map (setq map keymap))
+
+ ;; Process key binding arguments
+ (let (first next)
+ (while args
+ (if (keywordp (car args))
+ (progn
+ (setq next args)
+ (setq args nil))
+ (if first
+ (nconc first (list (car args)))
+ (setq first (list (car args))))
+ (setq args (cdr args))))
+
+ (cl-flet
+ ((wrap (map bindings)
+ (if (and map pkg (not (memq map '(global-map
+ override-global-map))))
+ `((if (boundp ',map)
+ ,(macroexp-progn bindings)
+ (eval-after-load
+ ,(if (symbolp pkg) `',pkg pkg)
+ ',(macroexp-progn bindings))))
+ bindings)))
+
+ (append
+ (when prefix-map
+ `((defvar ,prefix-map)
+ ,@(when doc `((put ',prefix-map 'variable-documentation ,doc)))
+ ,@(if menu-name
+ `((define-prefix-command ',prefix-map nil ,menu-name))
+ `((define-prefix-command ',prefix-map)))
+ ,@(if (and map (not (eq map 'global-map)))
+ (wrap map `((bind-key ,prefix ',prefix-map ,map ,filter)))
+ `((bind-key ,prefix ',prefix-map nil ,filter)))))
+ (wrap map
+ (cl-mapcan
+ (lambda (form)
+ (let ((fun (and (cdr form) (list 'function (cdr form)))))
+ (if prefix-map
+ `((bind-key ,(car form) ,fun ,prefix-map ,filter))
+ (if (and map (not (eq map 'global-map)))
+ `((bind-key ,(car form) ,fun ,map ,filter))
+ `((bind-key ,(car form) ,fun nil ,filter))))))
+ first))
+ (when next
+ (bind-keys-form (if pkg
+ (cons :package (cons pkg next))
+ next) map)))))))
+
+;;;###autoload
+(defmacro bind-keys (&rest args)
+ "Bind multiple keys at once.
+
+Accepts keyword arguments:
+:map MAP - a keymap into which the keybindings should be
+ added
+:prefix KEY - prefix key for these bindings
+:prefix-map MAP - name of the prefix map that should be created
+ for these bindings
+:prefix-docstring STR - docstring for the prefix-map variable
+:menu-name NAME - optional menu string for prefix map
+:filter FORM - optional form to determine when bindings apply
+
+The rest of the arguments are conses of keybinding string and a
+function symbol (unquoted)."
+ (macroexp-progn (bind-keys-form args nil)))
+
+;;;###autoload
+(defmacro bind-keys* (&rest args)
+ (macroexp-progn (bind-keys-form args 'override-global-map)))
+
+(defun get-binding-description (elem)
+ (cond
+ ((listp elem)
+ (cond
+ ((memq (car elem) '(lambda function))
+ (if (and bind-key-describe-special-forms
+ (stringp (nth 2 elem)))
+ (nth 2 elem)
+ "#<lambda>"))
+ ((eq 'closure (car elem))
+ (if (and bind-key-describe-special-forms
+ (stringp (nth 3 elem)))
+ (nth 3 elem)
+ "#<closure>"))
+ ((eq 'keymap (car elem))
+ "#<keymap>")
+ (t
+ elem)))
+ ;; must be a symbol, non-symbol keymap case covered above
+ ((and bind-key-describe-special-forms (keymapp elem))
+ (let ((doc (get elem 'variable-documentation)))
+ (if (stringp doc) doc elem)))
+ ((symbolp elem)
+ elem)
+ (t
+ "#<byte-compiled lambda>")))
+
+(defun compare-keybindings (l r)
+ (let* ((regex bind-key-segregation-regexp)
+ (lgroup (and (string-match regex (caar l))
+ (match-string 0 (caar l))))
+ (rgroup (and (string-match regex (caar r))
+ (match-string 0 (caar r))))
+ (lkeymap (cdar l))
+ (rkeymap (cdar r)))
+ (cond
+ ((and (null lkeymap) rkeymap)
+ (cons t t))
+ ((and lkeymap (null rkeymap))
+ (cons nil t))
+ ((and lkeymap rkeymap
+ (not (string= (symbol-name lkeymap) (symbol-name rkeymap))))
+ (cons (string< (symbol-name lkeymap) (symbol-name rkeymap)) t))
+ ((and (null lgroup) rgroup)
+ (cons t t))
+ ((and lgroup (null rgroup))
+ (cons nil t))
+ ((and lgroup rgroup)
+ (if (string= lgroup rgroup)
+ (cons (string< (caar l) (caar r)) nil)
+ (cons (string< lgroup rgroup) t)))
+ (t
+ (cons (string< (caar l) (caar r)) nil)))))
+
+;;;###autoload
+(defun describe-personal-keybindings ()
+ "Display all the personal keybindings defined by `bind-key'."
+ (interactive)
+ (with-output-to-temp-buffer "*Personal Keybindings*"
+ (princ (format (concat "Key name%s Command%s Comments\n%s %s "
+ "---------------------\n")
+ (make-string (- (car bind-key-column-widths) 9) ? )
+ (make-string (- (cdr bind-key-column-widths) 8) ? )
+ (make-string (1- (car bind-key-column-widths)) ?-)
+ (make-string (1- (cdr bind-key-column-widths)) ?-)))
+ (let (last-binding)
+ (dolist (binding
+ (setq personal-keybindings
+ (sort personal-keybindings
+ (lambda (l r)
+ (car (compare-keybindings l r))))))
+
+ (if (not (eq (cdar last-binding) (cdar binding)))
+ (princ (format "\n\n%s: %s\n%s\n\n"
+ (cdar binding) (caar binding)
+ (make-string (+ 21 (car bind-key-column-widths)
+ (cdr bind-key-column-widths)) ?-)))
+ (if (and last-binding
+ (cdr (compare-keybindings last-binding binding)))
+ (princ "\n")))
+
+ (let* ((key-name (caar binding))
+ (at-present (lookup-key (or (symbol-value (cdar binding))
+ (current-global-map))
+ (read-kbd-macro key-name)))
+ (command (nth 1 binding))
+ (was-command (nth 2 binding))
+ (command-desc (get-binding-description command))
+ (was-command-desc (and was-command
+ (get-binding-description was-command)))
+ (at-present-desc (get-binding-description at-present))
+ )
+ (let ((line
+ (format
+ (format "%%-%ds%%-%ds%%s\n" (car bind-key-column-widths)
+ (cdr bind-key-column-widths))
+ key-name (format "`%s\'" command-desc)
+ (if (string= command-desc at-present-desc)
+ (if (or (null was-command)
+ (string= command-desc was-command-desc))
+ ""
+ (format "was `%s\'" was-command-desc))
+ (format "[now: `%s\']" at-present)))))
+ (princ (if (string-match "[ \t]+\n" line)
+ (replace-match "\n" t t line)
+ line))))
+
+ (setq last-binding binding)))))
+
+(provide 'bind-key)
+
+;; Local Variables:
+;; outline-regexp: ";;;\\(;* [^\s\t\n]\\|###autoload\\)\\|("
+;; indent-tabs-mode: nil
+;; End:
+
+;;; bind-key.el ends here
diff --git a/elpa/bind-key-20210210.1609/bind-key.elc b/elpa/bind-key-20210210.1609/bind-key.elc
new file mode 100644
index 0000000..4e0ac1e
--- /dev/null
+++ b/elpa/bind-key-20210210.1609/bind-key.elc
Binary files differ
diff --git a/elpa/company-20220425.1145/company-abbrev.el b/elpa/company-20220425.1145/company-abbrev.el
new file mode 100644
index 0000000..b8f81c4
--- /dev/null
+++ b/elpa/company-20220425.1145/company-abbrev.el
@@ -0,0 +1,52 @@
+;;; company-abbrev.el --- company-mode completion backend for abbrev
+
+;; Copyright (C) 2009-2011, 2013-2015, 2021 Free Software Foundation, Inc.
+
+;; Author: Nikolaj Schumacher
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs 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.
+
+;; GNU Emacs 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 GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
+
+
+;;; Commentary:
+;;
+
+;;; Code:
+
+(require 'company)
+(require 'cl-lib)
+(require 'abbrev)
+
+(defun company-abbrev-insert (match)
+ "Replace MATCH with the expanded abbrev."
+ (expand-abbrev))
+
+;;;###autoload
+(defun company-abbrev (command &optional arg &rest ignored)
+ "`company-mode' completion backend for abbrev."
+ (interactive (list 'interactive))
+ (cl-case command
+ (interactive (company-begin-backend 'company-abbrev
+ 'company-abbrev-insert))
+ (prefix (company-grab-symbol))
+ (candidates (nconc
+ (delete "" (all-completions arg global-abbrev-table))
+ (delete "" (all-completions arg local-abbrev-table))))
+ (kind 'snippet)
+ (meta (abbrev-expansion arg))
+ (post-completion (expand-abbrev))))
+
+(provide 'company-abbrev)
+;;; company-abbrev.el ends here
diff --git a/elpa/company-20220425.1145/company-abbrev.elc b/elpa/company-20220425.1145/company-abbrev.elc
new file mode 100644
index 0000000..c1dc26c
--- /dev/null
+++ b/elpa/company-20220425.1145/company-abbrev.elc
Binary files differ
diff --git a/elpa/company-20220425.1145/company-autoloads.el b/elpa/company-20220425.1145/company-autoloads.el
new file mode 100644
index 0000000..12a2167
--- /dev/null
+++ b/elpa/company-20220425.1145/company-autoloads.el
@@ -0,0 +1,406 @@
+;;; company-autoloads.el --- automatically extracted autoloads -*- lexical-binding: t -*-
+;;
+;;; Code:
+
+(add-to-list 'load-path (directory-file-name
+ (or (file-name-directory #$) (car load-path))))
+
+
+;;;### (autoloads nil "company" "company.el" (0 0 0 0))
+;;; Generated autoloads from company.el
+
+(autoload 'company-mode "company" "\
+\"complete anything\"; is an in-buffer completion framework.
+Completion starts automatically, depending on the values
+`company-idle-delay' and `company-minimum-prefix-length'.
+
+This is a minor mode. If called interactively, toggle the
+`Company mode' mode. If the prefix argument is positive, enable
+the mode, and if it is zero or negative, disable the mode.
+
+If called from Lisp, toggle the mode if ARG is `toggle'. Enable
+the mode if ARG is nil, omitted, or is a positive number.
+Disable the mode if ARG is a negative number.
+
+To check whether the minor mode is enabled in the current buffer,
+evaluate `company-mode'.
+
+The mode's hook is called both when the mode is enabled and when
+it is disabled.
+
+Completion can be controlled with the commands:
+`company-complete-common', `company-complete-selection', `company-complete',
+`company-select-next', `company-select-previous'. If these commands are
+called before `company-idle-delay', completion will also start.
+
+Completions can be searched with `company-search-candidates' or
+`company-filter-candidates'. These can be used while completion is
+inactive, as well.
+
+The completion data is retrieved using `company-backends' and displayed
+using `company-frontends'. If you want to start a specific backend, call
+it interactively or use `company-begin-backend'.
+
+By default, the completions list is sorted alphabetically, unless the
+backend chooses otherwise, or `company-transformers' changes it later.
+
+regular keymap (`company-mode-map'):
+
+\\{company-mode-map}
+keymap during active completions (`company-active-map'):
+
+\\{company-active-map}
+
+\(fn &optional ARG)" t nil)
+
+(put 'global-company-mode 'globalized-minor-mode t)
+
+(defvar global-company-mode nil "\
+Non-nil if Global Company mode is enabled.
+See the `global-company-mode' command
+for a description of this minor mode.
+Setting this variable directly does not take effect;
+either customize it (see the info node `Easy Customization')
+or call the function `global-company-mode'.")
+
+(custom-autoload 'global-company-mode "company" nil)
+
+(autoload 'global-company-mode "company" "\
+Toggle Company mode in all buffers.
+With prefix ARG, enable Global Company mode if ARG is positive;
+otherwise, disable it.
+
+If called from Lisp, toggle the mode if ARG is `toggle'.
+Enable the mode if ARG is nil, omitted, or is a positive number.
+Disable the mode if ARG is a negative number.
+
+Company mode is enabled in all buffers where `company-mode-on' would
+do it.
+
+See `company-mode' for more information on Company mode.
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'company-manual-begin "company" nil t nil)
+
+(autoload 'company-complete "company" "\
+Insert the common part of all candidates or the current selection.
+The first time this is called, the common part is inserted, the second
+time, or when the selection has been changed, the selected candidate is
+inserted." t nil)
+
+(register-definition-prefixes "company" '("company-"))
+
+;;;***
+
+;;;### (autoloads nil "company-abbrev" "company-abbrev.el" (0 0 0
+;;;;;; 0))
+;;; Generated autoloads from company-abbrev.el
+
+(autoload 'company-abbrev "company-abbrev" "\
+`company-mode' completion backend for abbrev.
+
+\(fn COMMAND &optional ARG &rest IGNORED)" t nil)
+
+(register-definition-prefixes "company-abbrev" '("company-abbrev-insert"))
+
+;;;***
+
+;;;### (autoloads nil "company-bbdb" "company-bbdb.el" (0 0 0 0))
+;;; Generated autoloads from company-bbdb.el
+
+(autoload 'company-bbdb "company-bbdb" "\
+`company-mode' completion backend for BBDB.
+
+\(fn COMMAND &optional ARG &rest IGNORE)" t nil)
+
+(register-definition-prefixes "company-bbdb" '("company-bbdb-"))
+
+;;;***
+
+;;;### (autoloads nil "company-capf" "company-capf.el" (0 0 0 0))
+;;; Generated autoloads from company-capf.el
+
+(register-definition-prefixes "company-capf" '("company-"))
+
+;;;***
+
+;;;### (autoloads nil "company-clang" "company-clang.el" (0 0 0 0))
+;;; Generated autoloads from company-clang.el
+
+(register-definition-prefixes "company-clang" '("company-clang"))
+
+;;;***
+
+;;;### (autoloads nil "company-cmake" "company-cmake.el" (0 0 0 0))
+;;; Generated autoloads from company-cmake.el
+
+(register-definition-prefixes "company-cmake" '("company-cmake"))
+
+;;;***
+
+;;;### (autoloads nil "company-css" "company-css.el" (0 0 0 0))
+;;; Generated autoloads from company-css.el
+
+(autoload 'company-css "company-css" "\
+`company-mode' completion backend for `css-mode'.
+
+\(fn COMMAND &optional ARG &rest IGNORED)" t nil)
+
+(register-definition-prefixes "company-css" '("company-css-"))
+
+;;;***
+
+;;;### (autoloads nil "company-dabbrev" "company-dabbrev.el" (0 0
+;;;;;; 0 0))
+;;; Generated autoloads from company-dabbrev.el
+
+(autoload 'company-dabbrev "company-dabbrev" "\
+dabbrev-like `company-mode' completion backend.
+
+\(fn COMMAND &optional ARG &rest IGNORED)" t nil)
+
+(register-definition-prefixes "company-dabbrev" '("company-dabbrev-"))
+
+;;;***
+
+;;;### (autoloads nil "company-dabbrev-code" "company-dabbrev-code.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from company-dabbrev-code.el
+
+(autoload 'company-dabbrev-code "company-dabbrev-code" "\
+dabbrev-like `company-mode' backend for code.
+The backend looks for all symbols in the current buffer that aren't in
+comments or strings.
+
+\(fn COMMAND &optional ARG &rest IGNORED)" t nil)
+
+(register-definition-prefixes "company-dabbrev-code" '("company-dabbrev-code-"))
+
+;;;***
+
+;;;### (autoloads nil "company-elisp" "company-elisp.el" (0 0 0 0))
+;;; Generated autoloads from company-elisp.el
+
+(autoload 'company-elisp "company-elisp" "\
+`company-mode' completion backend for Emacs Lisp.
+
+\(fn COMMAND &optional ARG &rest IGNORED)" t nil)
+
+(register-definition-prefixes "company-elisp" '("company-elisp-"))
+
+;;;***
+
+;;;### (autoloads nil "company-etags" "company-etags.el" (0 0 0 0))
+;;; Generated autoloads from company-etags.el
+
+(autoload 'company-etags "company-etags" "\
+`company-mode' completion backend for etags.
+
+\(fn COMMAND &optional ARG &rest IGNORED)" t nil)
+
+(register-definition-prefixes "company-etags" '("company-etags-"))
+
+;;;***
+
+;;;### (autoloads nil "company-files" "company-files.el" (0 0 0 0))
+;;; Generated autoloads from company-files.el
+
+(autoload 'company-files "company-files" "\
+`company-mode' completion backend existing file names.
+Completions works for proper absolute and relative files paths.
+File paths with spaces are only supported inside strings.
+
+\(fn COMMAND &optional ARG &rest IGNORED)" t nil)
+
+(register-definition-prefixes "company-files" '("company-file"))
+
+;;;***
+
+;;;### (autoloads nil "company-gtags" "company-gtags.el" (0 0 0 0))
+;;; Generated autoloads from company-gtags.el
+
+(autoload 'company-gtags "company-gtags" "\
+`company-mode' completion backend for GNU Global.
+
+\(fn COMMAND &optional ARG &rest IGNORED)" t nil)
+
+(register-definition-prefixes "company-gtags" '("company-gtags-"))
+
+;;;***
+
+;;;### (autoloads nil "company-ispell" "company-ispell.el" (0 0 0
+;;;;;; 0))
+;;; Generated autoloads from company-ispell.el
+
+(autoload 'company-ispell "company-ispell" "\
+`company-mode' completion backend using Ispell.
+
+\(fn COMMAND &optional ARG &rest IGNORED)" t nil)
+
+(register-definition-prefixes "company-ispell" '("company-ispell-"))
+
+;;;***
+
+;;;### (autoloads nil "company-keywords" "company-keywords.el" (0
+;;;;;; 0 0 0))
+;;; Generated autoloads from company-keywords.el
+
+(autoload 'company-keywords "company-keywords" "\
+`company-mode' backend for programming language keywords.
+
+\(fn COMMAND &optional ARG &rest IGNORED)" t nil)
+
+(register-definition-prefixes "company-keywords" '("company-keywords-"))
+
+;;;***
+
+;;;### (autoloads nil "company-nxml" "company-nxml.el" (0 0 0 0))
+;;; Generated autoloads from company-nxml.el
+
+(autoload 'company-nxml "company-nxml" "\
+`company-mode' completion backend for `nxml-mode'.
+
+\(fn COMMAND &optional ARG &rest IGNORED)" t nil)
+
+(register-definition-prefixes "company-nxml" '("company-nxml-"))
+
+;;;***
+
+;;;### (autoloads nil "company-oddmuse" "company-oddmuse.el" (0 0
+;;;;;; 0 0))
+;;; Generated autoloads from company-oddmuse.el
+
+(autoload 'company-oddmuse "company-oddmuse" "\
+`company-mode' completion backend for `oddmuse-mode'.
+
+\(fn COMMAND &optional ARG &rest IGNORED)" t nil)
+
+(register-definition-prefixes "company-oddmuse" '("company-oddmuse-"))
+
+;;;***
+
+;;;### (autoloads nil "company-semantic" "company-semantic.el" (0
+;;;;;; 0 0 0))
+;;; Generated autoloads from company-semantic.el
+
+(autoload 'company-semantic "company-semantic" "\
+`company-mode' completion backend using CEDET Semantic.
+
+\(fn COMMAND &optional ARG &rest IGNORED)" t nil)
+
+(register-definition-prefixes "company-semantic" '("company-semantic-"))
+
+;;;***
+
+;;;### (autoloads nil "company-template" "company-template.el" (0
+;;;;;; 0 0 0))
+;;; Generated autoloads from company-template.el
+
+(register-definition-prefixes "company-template" '("company-template-"))
+
+;;;***
+
+;;;### (autoloads nil "company-tempo" "company-tempo.el" (0 0 0 0))
+;;; Generated autoloads from company-tempo.el
+
+(autoload 'company-tempo "company-tempo" "\
+`company-mode' completion backend for tempo.
+
+\(fn COMMAND &optional ARG &rest IGNORED)" t nil)
+
+(register-definition-prefixes "company-tempo" '("company-tempo-"))
+
+;;;***
+
+;;;### (autoloads nil "company-tng" "company-tng.el" (0 0 0 0))
+;;; Generated autoloads from company-tng.el
+
+(autoload 'company-tng-frontend "company-tng" "\
+When the user changes the selection at least once, this
+frontend will display the candidate in the buffer as if it's
+already there and any key outside of `company-active-map' will
+confirm the selection and finish the completion.
+
+\(fn COMMAND)" nil nil)
+
+(define-obsolete-function-alias 'company-tng-configure-default 'company-tng-mode "0.9.14" "\
+Applies the default configuration to enable company-tng.")
+
+(defvar company-tng-mode nil "\
+Non-nil if Company-Tng mode is enabled.
+See the `company-tng-mode' command
+for a description of this minor mode.
+Setting this variable directly does not take effect;
+either customize it (see the info node `Easy Customization')
+or call the function `company-tng-mode'.")
+
+(custom-autoload 'company-tng-mode "company-tng" nil)
+
+(autoload 'company-tng-mode "company-tng" "\
+This minor mode enables `company-tng-frontend'.
+
+This is a minor mode. If called interactively, toggle the
+`Company-Tng mode' mode. If the prefix argument is positive,
+enable the mode, and if it is zero or negative, disable the mode.
+
+If called from Lisp, toggle the mode if ARG is `toggle'. Enable
+the mode if ARG is nil, omitted, or is a positive number.
+Disable the mode if ARG is a negative number.
+
+To check whether the minor mode is enabled in the current buffer,
+evaluate `(default-value \\='company-tng-mode)'.
+
+The mode's hook is called both when the mode is enabled and when
+it is disabled.
+
+\(fn &optional ARG)" t nil)
+
+(register-definition-prefixes "company-tng" '("company-tng-"))
+
+;;;***
+
+;;;### (autoloads nil "company-yasnippet" "company-yasnippet.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from company-yasnippet.el
+
+(autoload 'company-yasnippet "company-yasnippet" "\
+`company-mode' backend for `yasnippet'.
+
+This backend should be used with care, because as long as there are
+snippets defined for the current major mode, this backend will always
+shadow backends that come after it. Recommended usages:
+
+* In a buffer-local value of `company-backends', grouped with a backend or
+ several that provide actual text completions.
+
+ (add-hook \\='js-mode-hook
+ (lambda ()
+ (set (make-local-variable \\='company-backends)
+ \\='((company-dabbrev-code company-yasnippet)))))
+
+* After keyword `:with', grouped with other backends.
+
+ (push \\='(company-semantic :with company-yasnippet) company-backends)
+
+* Not in `company-backends', just bound to a key.
+
+ (global-set-key (kbd \"C-c y\") \\='company-yasnippet)
+
+\(fn COMMAND &optional ARG &rest IGNORE)" t nil)
+
+(register-definition-prefixes "company-yasnippet" '("company-yasnippet-"))
+
+;;;***
+
+;;;### (autoloads nil nil ("company-pkg.el") (0 0 0 0))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; coding: utf-8
+;; End:
+;;; company-autoloads.el ends here
diff --git a/elpa/company-20220425.1145/company-bbdb.el b/elpa/company-20220425.1145/company-bbdb.el
new file mode 100644
index 0000000..1016e2a
--- /dev/null
+++ b/elpa/company-20220425.1145/company-bbdb.el
@@ -0,0 +1,63 @@
+;;; company-bbdb.el --- company-mode completion backend for BBDB in message-mode
+
+;; Copyright (C) 2013-2016, 2020 Free Software Foundation, Inc.
+
+;; Author: Jan Tatarik <jan.tatarik@gmail.com>
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs 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.
+
+;; GNU Emacs 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 GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
+
+(require 'company)
+(require 'cl-lib)
+
+(declare-function bbdb-record-get-field "bbdb")
+(declare-function bbdb-records "bbdb")
+(declare-function bbdb-dwim-mail "bbdb-com")
+(declare-function bbdb-search "bbdb-com")
+
+(defgroup company-bbdb nil
+ "Completion backend for BBDB."
+ :group 'company)
+
+(defcustom company-bbdb-modes '(message-mode)
+ "Major modes in which `company-bbdb' may complete."
+ :type '(repeat (symbol :tag "Major mode"))
+ :package-version '(company . "0.8.8"))
+
+(defun company-bbdb--candidates (arg)
+ (cl-mapcan (lambda (record)
+ (mapcar (lambda (mail) (bbdb-dwim-mail record mail))
+ (bbdb-record-get-field record 'mail)))
+ (eval '(bbdb-search (bbdb-records) arg nil arg))))
+
+;;;###autoload
+(defun company-bbdb (command &optional arg &rest ignore)
+ "`company-mode' completion backend for BBDB."
+ (interactive (list 'interactive))
+ (cl-case command
+ (interactive (company-begin-backend 'company-bbdb))
+ (prefix (and (memq major-mode company-bbdb-modes)
+ (featurep 'bbdb-com)
+ (let ((case-fold-search t))
+ (looking-back
+ "^\\([^ :]*-\\)?\\(To\\|B?Cc\\|From\\):.*? *\\([^,;]*\\)"
+ (line-beginning-position)))
+ (match-string-no-properties 3)))
+ (candidates (company-bbdb--candidates arg))
+ (sorted t)
+ (no-cache t)))
+
+(provide 'company-bbdb)
+;;; company-bbdb.el ends here
diff --git a/elpa/company-20220425.1145/company-bbdb.elc b/elpa/company-20220425.1145/company-bbdb.elc
new file mode 100644
index 0000000..c6b92c0
--- /dev/null
+++ b/elpa/company-20220425.1145/company-bbdb.elc
Binary files differ
diff --git a/elpa/company-20220425.1145/company-capf.el b/elpa/company-20220425.1145/company-capf.el
new file mode 100644
index 0000000..a279188
--- /dev/null
+++ b/elpa/company-20220425.1145/company-capf.el
@@ -0,0 +1,257 @@
+;;; company-capf.el --- company-mode completion-at-point-functions backend -*- lexical-binding: t -*-
+
+;; Copyright (C) 2013-2021 Free Software Foundation, Inc.
+
+;; Author: Stefan Monnier <monnier@iro.umontreal.ca>
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs 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.
+
+;; GNU Emacs 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 GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
+
+
+;;; Commentary:
+;;
+;; The CAPF back-end provides a bridge to the standard
+;; completion-at-point-functions facility, and thus can support any major mode
+;; that defines a proper completion function, including emacs-lisp-mode,
+;; css-mode and nxml-mode.
+
+;;; Code:
+
+(require 'company)
+(require 'cl-lib)
+
+;; Amortizes several calls to a c-a-p-f from the same position.
+(defvar company--capf-cache nil)
+
+;; FIXME: Provide a way to save this info once in Company itself
+;; (https://github.com/company-mode/company-mode/pull/845).
+(defvar-local company-capf--current-completion-data nil
+ "Value last returned by `company-capf' when called with `candidates'.
+For most properties/actions, this is just what we need: the exact values
+that accompanied the completion table that's currently is use.
+
+`company-capf', however, could be called at some different positions during
+a completion session (most importantly, by `company-sort-by-occurrence'),
+so we can't just use the preceding variable instead.")
+
+(defun company--capf-data ()
+ (let ((cache company--capf-cache))
+ (if (and (equal (current-buffer) (car cache))
+ (equal (point) (car (setq cache (cdr cache))))
+ (equal (buffer-chars-modified-tick) (car (setq cache (cdr cache)))))
+ (cadr cache)
+ (let ((data (company--capf-data-real)))
+ (setq company--capf-cache
+ (list (current-buffer) (point) (buffer-chars-modified-tick) data))
+ data))))
+
+(defun company--contains (elt lst)
+ (when-let ((cur (car lst)))
+ (cond
+ ((symbolp cur)
+ (or (eq elt cur)
+ (company--contains elt (cdr lst))))
+ ((listp cur)
+ (or (company--contains elt cur)
+ (company--contains elt (cdr lst)))))))
+
+(defun company--capf-data-real ()
+ (cl-letf* (((default-value 'completion-at-point-functions)
+ (if (company--contains 'company-etags company-backends)
+ ;; Ignore tags-completion-at-point-function because it subverts
+ ;; company-etags in the default value of company-backends, where
+ ;; the latter comes later.
+ (remove 'tags-completion-at-point-function
+ (default-value 'completion-at-point-functions))
+ (default-value 'completion-at-point-functions)))
+ (completion-at-point-functions (company--capf-workaround))
+ (data (run-hook-wrapped 'completion-at-point-functions
+ ;; Ignore misbehaving functions.
+ #'company--capf-wrapper 'optimist)))
+ (when (and (consp (cdr data)) (integer-or-marker-p (nth 1 data))) data)))
+
+(defun company--capf-wrapper (fun which)
+ (let ((buffer-read-only t)
+ (inhibit-read-only nil)
+ (completion-in-region-function
+ (lambda (beg end coll pred)
+ (throw 'company--illegal-completion-in-region
+ (list fun beg end coll :predicate pred)))))
+ (catch 'company--illegal-completion-in-region
+ (condition-case nil
+ (completion--capf-wrapper fun which)
+ (buffer-read-only nil)))))
+
+(declare-function python-shell-get-process "python")
+
+(defun company--capf-workaround ()
+ ;; For http://debbugs.gnu.org/cgi/bugreport.cgi?bug=18067
+ (if (or (not (listp completion-at-point-functions))
+ (not (memq 'python-completion-complete-at-point completion-at-point-functions))
+ (python-shell-get-process))
+ completion-at-point-functions
+ (remq 'python-completion-complete-at-point completion-at-point-functions)))
+
+(defun company-capf--save-current-data (data)
+ (setq company-capf--current-completion-data data)
+ (add-hook 'company-after-completion-hook
+ #'company-capf--clear-current-data nil t))
+
+(defun company-capf--clear-current-data (_ignored)
+ (setq company-capf--current-completion-data nil))
+
+(defvar-local company-capf--sorted nil)
+
+(defun company-capf (command &optional arg &rest _args)
+ "`company-mode' backend using `completion-at-point-functions'."
+ (interactive (list 'interactive))
+ (pcase command
+ (`interactive (company-begin-backend 'company-capf))
+ (`prefix
+ (let ((res (company--capf-data)))
+ (when res
+ (let ((length (plist-get (nthcdr 4 res) :company-prefix-length))
+ (prefix (buffer-substring-no-properties (nth 1 res) (point))))
+ (cond
+ ((> (nth 2 res) (point)) 'stop)
+ (length (cons prefix length))
+ (t prefix))))))
+ (`candidates
+ (company-capf--candidates arg))
+ (`sorted
+ company-capf--sorted)
+ (`match
+ ;; Ask the for the `:company-match' function. If that doesn't help,
+ ;; fallback to sniffing for face changes to get a suitable value.
+ (let ((f (plist-get (nthcdr 4 company-capf--current-completion-data)
+ :company-match)))
+ (if f (funcall f arg)
+ (let* ((match-start nil) (pos -1)
+ (prop-value nil) (faces nil)
+ (has-face-p nil) chunks
+ (limit (length arg)))
+ (while (< pos limit)
+ (setq pos
+ (if (< pos 0) 0 (next-property-change pos arg limit)))
+ (setq prop-value (or
+ (get-text-property pos 'face arg)
+ (get-text-property pos 'font-lock-face arg))
+ faces (if (listp prop-value) prop-value (list prop-value))
+ has-face-p (memq 'completions-common-part faces))
+ (cond ((and (not match-start) has-face-p)
+ (setq match-start pos))
+ ((and match-start (not has-face-p))
+ (push (cons match-start pos) chunks)
+ (setq match-start nil))))
+ (nreverse chunks)))))
+ (`duplicates t)
+ (`no-cache t) ;Not much can be done here, as long as we handle
+ ;non-prefix matches.
+ (`meta
+ (let ((f (plist-get (nthcdr 4 company-capf--current-completion-data)
+ :company-docsig)))
+ (when f (funcall f arg))))
+ (`doc-buffer
+ (let ((f (plist-get (nthcdr 4 company-capf--current-completion-data)
+ :company-doc-buffer)))
+ (when f (funcall f arg))))
+ (`location
+ (let ((f (plist-get (nthcdr 4 company-capf--current-completion-data)
+ :company-location)))
+ (when f (funcall f arg))))
+ (`annotation
+ (company-capf--annotation arg))
+ (`kind
+ (let ((f (plist-get (nthcdr 4 company-capf--current-completion-data)
+ :company-kind)))
+ (when f (funcall f arg))))
+ (`deprecated
+ (let ((f (plist-get (nthcdr 4 company-capf--current-completion-data)
+ :company-deprecated)))
+ (when f (funcall f arg))))
+ (`require-match
+ (plist-get (nthcdr 4 (company--capf-data)) :company-require-match))
+ (`init nil) ;Don't bother: plenty of other ways to initialize the code.
+ (`post-completion
+ (company--capf-post-completion arg))
+ ))
+
+(defun company-capf--annotation (arg)
+ (let* ((f (or (plist-get (nthcdr 4 company-capf--current-completion-data)
+ :annotation-function)
+ ;; FIXME: Add a test.
+ (cdr (assq 'annotation-function
+ (completion-metadata
+ (buffer-substring (nth 1 company-capf--current-completion-data)
+ (nth 2 company-capf--current-completion-data))
+ (nth 3 company-capf--current-completion-data)
+ (plist-get (nthcdr 4 company-capf--current-completion-data)
+ :predicate))))))
+ (annotation (when f (funcall f arg))))
+ (if (and company-format-margin-function
+ (equal annotation " <f>") ; elisp-completion-at-point, pre-icons
+ (plist-get (nthcdr 4 company-capf--current-completion-data)
+ :company-kind))
+ nil
+ annotation)))
+
+(defun company-capf--candidates (input)
+ (let ((res (company--capf-data)))
+ (company-capf--save-current-data res)
+ (when res
+ (let* ((table (nth 3 res))
+ (pred (plist-get (nthcdr 4 res) :predicate))
+ (meta (completion-metadata
+ (buffer-substring (nth 1 res) (nth 2 res))
+ table pred))
+ (candidates (completion-all-completions input table pred
+ (length input)
+ meta))
+ (sortfun (cdr (assq 'display-sort-function meta)))
+ (last (last candidates))
+ (base-size (and (numberp (cdr last)) (cdr last))))
+ (when base-size
+ (setcdr last nil))
+ (setq company-capf--sorted (functionp sortfun))
+ (when sortfun
+ (setq candidates (funcall sortfun candidates)))
+ (if (not (zerop (or base-size 0)))
+ (let ((before (substring input 0 base-size)))
+ (mapcar (lambda (candidate)
+ (concat before candidate))
+ candidates))
+ candidates)))))
+
+(defun company--capf-post-completion (arg)
+ (let* ((res company-capf--current-completion-data)
+ (exit-function (plist-get (nthcdr 4 res) :exit-function))
+ (table (nth 3 res)))
+ (if exit-function
+ ;; We can more or less know when the user is done with completion,
+ ;; so we do something different than `completion--done'.
+ (funcall exit-function arg
+ ;; FIXME: Should probably use an additional heuristic:
+ ;; completion-at-point doesn't know when the user picked a
+ ;; particular candidate explicitly (it only checks whether
+ ;; further completions exist). Whereas company user can press
+ ;; RET (or use implicit completion with company-tng).
+ (if (= (car (completion-boundaries arg table nil ""))
+ (length arg))
+ 'sole
+ 'finished)))))
+
+(provide 'company-capf)
+
+;;; company-capf.el ends here
diff --git a/elpa/company-20220425.1145/company-capf.elc b/elpa/company-20220425.1145/company-capf.elc
new file mode 100644
index 0000000..c4fdc73
--- /dev/null
+++ b/elpa/company-20220425.1145/company-capf.elc
Binary files differ
diff --git a/elpa/company-20220425.1145/company-clang.el b/elpa/company-20220425.1145/company-clang.el
new file mode 100644
index 0000000..5d8ca5a
--- /dev/null
+++ b/elpa/company-20220425.1145/company-clang.el
@@ -0,0 +1,420 @@
+;;; company-clang.el --- company-mode completion backend for Clang -*- lexical-binding: t -*-
+
+;; Copyright (C) 2009-2011, 2013-2021 Free Software Foundation, Inc.
+
+;; Author: Nikolaj Schumacher
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs 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.
+
+;; GNU Emacs 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 GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
+
+
+;;; Commentary:
+;;
+
+;;; Code:
+
+(require 'company)
+(require 'company-template)
+(require 'cl-lib)
+
+(defgroup company-clang nil
+ "Completion backend for Clang."
+ :group 'company)
+
+(defcustom company-clang-executable
+ (executable-find "clang")
+ "Location of clang executable."
+ :type 'file)
+
+(defcustom company-clang-begin-after-member-access t
+ "When non-nil, start automatic completion after member access operators.
+
+Automatic completion starts whenever the current symbol is preceded by
+\".\", \"->\" or \"::\", ignoring `company-minimum-prefix-length'.
+
+If `company-begin-commands' is a list, it should include `c-electric-lt-gt'
+and `c-electric-colon', for automatic completion right after \">\" and
+\":\"."
+ :type 'boolean)
+
+(defcustom company-clang-use-compile-flags-txt nil
+ "When non-nil, use flags from compile_flags.txt if present.
+
+The lines from that files will be appended to `company-clang-arguments'.
+
+And if such file is found, Clang is called from the directory containing
+it. That allows the flags use relative file names within the project."
+ :type 'boolean
+ :safe 'booleanp)
+
+(defcustom company-clang-arguments nil
+ "A list of additional arguments to pass to clang when completing.
+Prefix files (-include ...) can be selected with `company-clang-set-prefix'
+or automatically through a custom `company-clang-prefix-guesser'."
+ :type '(repeat (string :tag "Argument")))
+
+(defcustom company-clang-prefix-guesser 'company-clang-guess-prefix
+ "A function to determine the prefix file for the current buffer."
+ :type '(function :tag "Guesser function" nil))
+
+(defvar company-clang-modes '(c-mode c++-mode objc-mode)
+ "Major modes which clang may complete.")
+
+(defcustom company-clang-insert-arguments t
+ "When non-nil, insert function arguments as a template after completion."
+ :type 'boolean
+ :package-version '(company . "0.8.0"))
+
+;; prefix ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defvar company-clang--prefix nil)
+
+(defsubst company-clang--guess-pch-file (file)
+ (let ((dir (directory-file-name (file-name-directory file))))
+ (when (equal (file-name-nondirectory dir) "Classes")
+ (setq dir (file-name-directory dir)))
+ (car (directory-files dir t "\\([^.]h\\|[^h]\\).pch\\'" t))))
+
+(defsubst company-clang--file-substring (file beg end)
+ (with-temp-buffer
+ (insert-file-contents-literally file nil beg end)
+ (buffer-string)))
+
+(defun company-clang-guess-prefix ()
+ "Try to guess the prefix file for the current buffer."
+ ;; Prefixes seem to be called .pch. Pre-compiled headers do, too.
+ ;; So we look at the magic number to rule them out.
+ (let* ((file (company-clang--guess-pch-file buffer-file-name))
+ (magic-number (and file (company-clang--file-substring file 0 4))))
+ (unless (member magic-number '("CPCH" "gpch"))
+ file)))
+
+(defun company-clang-set-prefix (&optional prefix)
+ "Use PREFIX as a prefix (-include ...) file for clang completion."
+ (interactive (let ((def (funcall company-clang-prefix-guesser)))
+ (unless (stringp def)
+ (setq def default-directory))
+ (list (read-file-name "Prefix file: "
+ (when def (file-name-directory def))
+ def t (when def (file-name-nondirectory def))))))
+ ;; TODO: pre-compile?
+ (setq company-clang--prefix (and (stringp prefix)
+ (file-regular-p prefix)
+ prefix)))
+
+;; Clean-up on exit.
+(add-hook 'kill-emacs-hook 'company-clang-set-prefix)
+
+;; parsing ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; TODO: Handle Pattern (syntactic hints would be neat).
+;; Do we ever see OVERLOAD (or OVERRIDE)?
+(defconst company-clang--completion-pattern
+ "^COMPLETION: \\_<\\(%s[a-zA-Z0-9_:]*\\)\\(?:\\(?: (InBase)\\)? : \\(.*\\)$\\)?$")
+
+(defconst company-clang--error-buffer-name "*clang-error*")
+
+(defun company-clang--lang-option ()
+ (if (eq major-mode 'objc-mode)
+ (if (string= "m" (file-name-extension buffer-file-name))
+ "objective-c" "objective-c++")
+ (substring (symbol-name major-mode) 0 -5)))
+
+(defun company-clang--parse-output (prefix _objc)
+ (goto-char (point-min))
+ (let ((pattern (format company-clang--completion-pattern
+ (regexp-quote prefix)))
+ (case-fold-search nil)
+ (results (make-hash-table :test 'equal :size (/ (point-max) 100)))
+ lines match)
+ (while (re-search-forward pattern nil t)
+ (setq match (match-string-no-properties 1))
+ (unless (equal match "Pattern")
+ (save-match-data
+ (when (string-match ":" match)
+ (setq match (substring match 0 (match-beginning 0)))))
+ (let ((meta (match-string-no-properties 2)))
+ ;; Avoiding duplicates:
+ ;; https://github.com/company-mode/company-mode/issues/841
+ (cond
+ ;; Either meta != completion (not a macro)
+ ((not (equal match meta))
+ (puthash match meta results))
+ ;; Or it's the first time we see this completion
+ ((eq (gethash match results 'none) 'none)
+ (puthash match nil results))))))
+ (maphash
+ (lambda (match meta)
+ (when meta
+ (put-text-property 0 1 'meta (company-clang--strip-formatting meta) match))
+ (push match lines))
+ results)
+ lines))
+
+(defun company-clang--meta (candidate)
+ (get-text-property 0 'meta candidate))
+
+(defun company-clang--annotation (candidate)
+ (let ((ann (company-clang--annotation-1 candidate)))
+ (if (not (and ann (string-prefix-p "(*)" ann)))
+ ann
+ (with-temp-buffer
+ (insert ann)
+ (search-backward ")")
+ (let ((pt (1+ (point))))
+ (re-search-forward ".\\_>" nil t)
+ (delete-region pt (point)))
+ (buffer-string)))))
+
+(defun company-clang--annotation-1 (candidate)
+ (let ((meta (company-clang--meta candidate)))
+ (cond
+ ((null meta) nil)
+ ((string-match "[^:]:[^:]" meta)
+ (substring meta (1+ (match-beginning 0))))
+ ((string-match "(anonymous)" meta) nil)
+ ((string-match "\\((.*)[ a-z]*\\'\\)" meta)
+ (let ((paren (match-beginning 1)))
+ (if (not (eq (aref meta (1- paren)) ?>))
+ (match-string 1 meta)
+ (with-temp-buffer
+ (insert meta)
+ (goto-char paren)
+ (substring meta (1- (search-backward "<"))))))))))
+
+(defun company-clang--strip-formatting (text)
+ (replace-regexp-in-string
+ "#]" " "
+ (replace-regexp-in-string "[<{[]#\\|#[>}]" "" text t)
+ t))
+
+(defun company-clang--handle-error (res args)
+ (goto-char (point-min))
+ (let* ((buf (get-buffer-create company-clang--error-buffer-name))
+ (cmd (concat company-clang-executable " " (mapconcat 'identity args " ")))
+ (pattern (format company-clang--completion-pattern ""))
+ (message-truncate-lines t)
+ (err (if (and (re-search-forward pattern nil t)
+ ;; Something in the Windows build?
+ ;; Looks like Clang doesn't always include the error text
+ ;; before completions (even if exited with error).
+ (> (match-beginning 0) (point-min)))
+ (buffer-substring-no-properties (point-min)
+ (1- (match-beginning 0)))
+ ;; Warn the user more aggressively if no match was found.
+ (message "clang failed with error %d: %s" res cmd)
+ (buffer-string))))
+
+ (with-current-buffer buf
+ (let ((inhibit-read-only t))
+ (erase-buffer)
+ (insert (current-time-string)
+ (format "\nclang failed with error %d:\n" res)
+ cmd "\n\n")
+ (insert err)
+ (setq buffer-read-only t)
+ (goto-char (point-min))))))
+
+(defun company-clang--start-process (prefix callback &rest args)
+ (let* ((objc (derived-mode-p 'objc-mode))
+ (buf (get-buffer-create "*clang-output*"))
+ ;; Looks unnecessary in Emacs 25.1 and later.
+ ;; (Inconclusive, needs more testing):
+ ;; https://github.com/company-mode/company-mode/pull/288#issuecomment-72491808
+ (process-adaptive-read-buffering nil)
+ (existing-process (get-buffer-process buf)))
+ (when existing-process
+ (kill-process existing-process))
+ (with-current-buffer buf
+ (erase-buffer)
+ (setq buffer-undo-list t))
+ (let* ((process-connection-type nil)
+ (process (apply #'start-file-process "company-clang" buf
+ company-clang-executable args)))
+ (set-process-sentinel
+ process
+ (lambda (proc status)
+ (unless (string-match-p "hangup\\|killed" status)
+ (funcall
+ callback
+ (let ((res (process-exit-status proc)))
+ (with-current-buffer buf
+ (unless (eq 0 res)
+ (company-clang--handle-error res args))
+ ;; Still try to get any useful input.
+ (company-clang--parse-output prefix objc)))))))
+ (unless (company-clang--auto-save-p)
+ (send-region process (point-min) (point-max))
+ (send-string process "\n")
+ (process-send-eof process)))))
+
+(defsubst company-clang--build-location (pos)
+ (save-excursion
+ (goto-char pos)
+ (format "%s:%d:%d"
+ (if (company-clang--auto-save-p) buffer-file-name "-")
+ (line-number-at-pos)
+ (1+ (length
+ (encode-coding-region
+ (line-beginning-position)
+ (point)
+ 'utf-8
+ t))))))
+
+(defsubst company-clang--build-complete-args (pos)
+ (append '("-fsyntax-only" "-Xclang" "-code-completion-macros")
+ (unless (company-clang--auto-save-p)
+ (list "-x" (company-clang--lang-option)))
+ (company-clang--arguments)
+ (when (stringp company-clang--prefix)
+ (list "-include" (expand-file-name company-clang--prefix)))
+ (list "-Xclang" (format "-code-completion-at=%s"
+ (company-clang--build-location pos)))
+ (list (if (company-clang--auto-save-p) buffer-file-name "-"))))
+
+(defun company-clang--arguments ()
+ (let ((fname "compile_flags.txt")
+ (args company-clang-arguments)
+ current-dir-rel)
+ (when company-clang-use-compile-flags-txt
+ (let ((dir (locate-dominating-file default-directory fname)))
+ (when dir
+ (setq current-dir-rel (file-relative-name default-directory dir))
+ (setq default-directory dir)
+ (with-temp-buffer
+ (insert-file-contents fname)
+ (setq args
+ (append
+ args
+ (split-string (buffer-substring-no-properties
+ (point-min) (point-max))
+ "[\n\r]+"
+ t
+ "[ \t]+"))))
+ (unless (equal current-dir-rel "./")
+ (push (format "-I%s" current-dir-rel) args)))))
+ args))
+
+(defun company-clang--candidates (prefix callback)
+ (and (company-clang--auto-save-p)
+ (buffer-modified-p)
+ (basic-save-buffer))
+ (when (null company-clang--prefix)
+ (company-clang-set-prefix (or (funcall company-clang-prefix-guesser)
+ 'none)))
+ (let ((default-directory default-directory))
+ (apply 'company-clang--start-process
+ prefix
+ callback
+ (company-clang--build-complete-args
+ (if (company-clang--check-version 4.0 9.0)
+ (point)
+ (- (point) (length prefix)))))))
+
+(defun company-clang--prefix ()
+ (if company-clang-begin-after-member-access
+ (company-grab-symbol-cons "\\.\\|->\\|::" 2)
+ (company-grab-symbol)))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defconst company-clang-required-version 1.1)
+
+(defvar company-clang--version nil)
+
+(defun company-clang--auto-save-p ()
+ (not
+ (company-clang--check-version 2.9 3.1)))
+
+(defun company-clang--check-version (min apple-min)
+ (pcase-exhaustive company-clang--version
+ (`(apple . ,ver) (>= ver apple-min))
+ (`(normal . ,ver) (>= ver min))))
+
+(defsubst company-clang-version ()
+ "Return the version of `company-clang-executable'."
+ (with-temp-buffer
+ (call-process company-clang-executable nil t nil "--version")
+ (goto-char (point-min))
+ (if (re-search-forward
+ "\\(clang\\|Apple LLVM\\|bcc32x\\|bcc64\\) version \\([0-9.]+\\)" nil t)
+ (cons
+ (if (equal (match-string-no-properties 1) "Apple LLVM")
+ 'apple
+ 'normal)
+ (string-to-number (match-string-no-properties 2)))
+ 0)))
+
+(defun company-clang (command &optional arg &rest ignored)
+ "`company-mode' completion backend for Clang.
+Clang is a parser for C and ObjC. Clang version 1.1 or newer is required.
+
+Additional command line arguments can be specified in
+`company-clang-arguments'. Prefix files (-include ...) can be selected
+with `company-clang-set-prefix' or automatically through a custom
+`company-clang-prefix-guesser'.
+
+With Clang versions before 2.9, we have to save the buffer before
+performing completion. With Clang 2.9 and later, buffer contents are
+passed via standard input."
+ (interactive (list 'interactive))
+ (cl-case command
+ (interactive (company-begin-backend 'company-clang))
+ (init (when (memq major-mode company-clang-modes)
+ (unless company-clang-executable
+ (error "Company found no clang executable"))
+ (setq company-clang--version (company-clang-version))
+ (unless (company-clang--check-version
+ company-clang-required-version
+ company-clang-required-version)
+ (error "Company requires clang version %s"
+ company-clang-required-version))))
+ (prefix (and (memq major-mode company-clang-modes)
+ buffer-file-name
+ company-clang-executable
+ (not (company-in-string-or-comment))
+ (or (company-clang--prefix) 'stop)))
+ (candidates (cons :async
+ (lambda (cb) (company-clang--candidates arg cb))))
+ (meta (company-clang--meta arg))
+ (kind (company-clang--kind arg))
+ (annotation (company-clang--annotation arg))
+ (post-completion (let ((anno (company-clang--annotation arg)))
+ (when (and company-clang-insert-arguments anno)
+ (insert anno)
+ (if (string-match "\\`:[^:]" anno)
+ (company-template-objc-templatify anno)
+ (company-template-c-like-templatify
+ (concat arg anno))))))))
+
+(defun company-clang--kind (arg)
+ ;; XXX: Not very precise.
+ ;; E.g. it will say that an arg-less ObjC method is a variable (perhaps we
+ ;; could look around for brackets, etc, if there any actual users who's
+ ;; bothered by it).
+ ;; And we can't distinguish between local vars and struct fields.
+ ;; Or between keywords and macros.
+ (let ((meta (company-clang--meta arg)))
+ (cond
+ ((null meta) 'keyword)
+ ((string-match "(" meta)
+ (if (string-match-p (format "\\`%s *\\'" (regexp-quote arg))
+ (substring meta 0 (match-beginning 0)))
+ 'keyword ; Also macro, actually (no return type).
+ 'function))
+ (t 'variable))))
+
+(provide 'company-clang)
+;;; company-clang.el ends here
diff --git a/elpa/company-20220425.1145/company-clang.elc b/elpa/company-20220425.1145/company-clang.elc
new file mode 100644
index 0000000..1bab4d7
--- /dev/null
+++ b/elpa/company-20220425.1145/company-clang.elc
Binary files differ
diff --git a/elpa/company-20220425.1145/company-cmake.el b/elpa/company-20220425.1145/company-cmake.el
new file mode 100644
index 0000000..a072be1
--- /dev/null
+++ b/elpa/company-20220425.1145/company-cmake.el
@@ -0,0 +1,207 @@
+;;; company-cmake.el --- company-mode completion backend for CMake
+
+;; Copyright (C) 2013-2015, 2017-2018, 2020 Free Software Foundation, Inc.
+
+;; Author: Chen Bin <chenbin DOT sh AT gmail>
+;; Version: 0.2
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;
+;; company-cmake offers completions for module names, variable names and
+;; commands used by CMake. And their descriptions.
+
+;;; Code:
+
+(require 'company)
+(require 'cl-lib)
+
+(defgroup company-cmake nil
+ "Completion backend for CMake."
+ :group 'company)
+
+(defcustom company-cmake-executable
+ (executable-find "cmake")
+ "Location of cmake executable."
+ :type 'file)
+
+(defvar company-cmake-executable-arguments
+ '("--help-command-list"
+ "--help-module-list"
+ "--help-property-list"
+ "--help-variable-list")
+ "The arguments we pass to cmake, separately.
+They affect which types of symbols we get completion candidates for.")
+
+(defvar company-cmake--completion-pattern
+ "^\\(%s[a-zA-Z0-9_<>]%s\\)$"
+ "Regexp to match the candidates.")
+
+(defvar company-cmake-modes '(cmake-mode)
+ "Major modes in which cmake may complete.")
+
+(defvar company-cmake--candidates-cache nil
+ "Cache for the raw candidates.")
+
+(defvar company-cmake--meta-command-cache nil
+ "Cache for command arguments to retrieve descriptions for the candidates.")
+
+(defun company-cmake--replace-tags (rlt)
+ (setq rlt (replace-regexp-in-string
+ "\\(.*?\\(IS_GNU\\)?\\)<LANG>\\(.*\\)"
+ (lambda (_match)
+ (mapconcat 'identity
+ (if (match-beginning 2)
+ '("\\1CXX\\3" "\\1C\\3" "\\1G77\\3")
+ '("\\1CXX\\3" "\\1C\\3" "\\1Fortran\\3"))
+ "\n"))
+ rlt t))
+ (setq rlt (replace-regexp-in-string
+ "\\(.*\\)<CONFIG>\\(.*\\)"
+ (mapconcat 'identity '("\\1DEBUG\\2" "\\1RELEASE\\2"
+ "\\1RELWITHDEBINFO\\2" "\\1MINSIZEREL\\2")
+ "\n")
+ rlt))
+ rlt)
+
+(defun company-cmake--fill-candidates-cache (arg)
+ "Fill candidates cache if needed."
+ (let (rlt)
+ (unless company-cmake--candidates-cache
+ (setq company-cmake--candidates-cache (make-hash-table :test 'equal)))
+
+ ;; If hash is empty, fill it.
+ (unless (gethash arg company-cmake--candidates-cache)
+ (with-temp-buffer
+ (let ((res (call-process company-cmake-executable nil t nil arg)))
+ (unless (zerop res)
+ (message "cmake executable exited with error=%d" res)))
+ (setq rlt (buffer-string)))
+ (setq rlt (company-cmake--replace-tags rlt))
+ (puthash arg rlt company-cmake--candidates-cache))
+ ))
+
+(defun company-cmake--parse (prefix content cmd)
+ (let ((start 0)
+ (pattern (format company-cmake--completion-pattern
+ (regexp-quote prefix)
+ (if (zerop (length prefix)) "+" "*")))
+ (lines (split-string content "\n"))
+ match
+ rlt)
+ (dolist (line lines)
+ (when (string-match pattern line)
+ (let ((match (match-string 1 line)))
+ (when match
+ (puthash match cmd company-cmake--meta-command-cache)
+ (push match rlt)))))
+ rlt))
+
+(defun company-cmake--candidates (prefix)
+ (let (results
+ cmd-opts
+ str)
+
+ (unless company-cmake--meta-command-cache
+ (setq company-cmake--meta-command-cache (make-hash-table :test 'equal)))
+
+ (dolist (arg company-cmake-executable-arguments)
+ (company-cmake--fill-candidates-cache arg)
+ (setq cmd-opts (replace-regexp-in-string "-list$" "" arg) )
+
+ (setq str (gethash arg company-cmake--candidates-cache))
+ (when str
+ (setq results (nconc results
+ (company-cmake--parse prefix str cmd-opts)))))
+ results))
+
+(defun company-cmake--unexpand-candidate (candidate)
+ (cond
+ ((string-match "^CMAKE_\\(C\\|CXX\\|Fortran\\)\\(_.*\\)$" candidate)
+ (setq candidate (concat "CMAKE_<LANG>" (match-string 2 candidate))))
+
+ ;; C flags
+ ((string-match "^\\(.*_\\)IS_GNU\\(C\\|CXX\\|G77\\)$" candidate)
+ (setq candidate (concat (match-string 1 candidate) "IS_GNU<LANG>")))
+
+ ;; C flags
+ ((string-match "^\\(.*_\\)OVERRIDE_\\(C\\|CXX\\|Fortran\\)$" candidate)
+ (setq candidate (concat (match-string 1 candidate) "OVERRIDE_<LANG>")))
+
+ ((string-match "^\\(.*\\)\\(_DEBUG\\|_RELEASE\\|_RELWITHDEBINFO\\|_MINSIZEREL\\)\\(.*\\)$" candidate)
+ (setq candidate (concat (match-string 1 candidate)
+ "_<CONFIG>"
+ (match-string 3 candidate)))))
+ candidate)
+
+(defun company-cmake--meta (candidate)
+ (let ((cmd-opts (gethash candidate company-cmake--meta-command-cache))
+ result)
+ (setq candidate (company-cmake--unexpand-candidate candidate))
+
+ ;; Don't cache the documentation of every candidate (command)
+ ;; Cache in this case will cost too much memory.
+ (with-temp-buffer
+ (call-process company-cmake-executable nil t nil cmd-opts candidate)
+ ;; Go to the third line, trim it and return the result.
+ ;; Tested with cmake 2.8.9.
+ (goto-char (point-min))
+ (forward-line 2)
+ (setq result (buffer-substring-no-properties (line-beginning-position)
+ (line-end-position)))
+ (setq result (replace-regexp-in-string "^[ \t\n\r]+" "" result))
+ result)))
+
+(defun company-cmake--doc-buffer (candidate)
+ (let ((cmd-opts (gethash candidate company-cmake--meta-command-cache)))
+
+ (setq candidate (company-cmake--unexpand-candidate candidate))
+ (with-temp-buffer
+ (call-process company-cmake-executable nil t nil cmd-opts candidate)
+ ;; Go to the third line, trim it and return the doc buffer.
+ ;; Tested with cmake 2.8.9.
+ (goto-char (point-min))
+ (forward-line 2)
+ (company-doc-buffer
+ (buffer-substring-no-properties (line-beginning-position)
+ (point-max))))))
+
+(defun company-cmake-prefix-dollar-brace-p ()
+ "Test if the current symbol follows ${."
+ (save-excursion
+ (skip-syntax-backward "w_")
+ (and (eq (char-before (point)) ?\{)
+ (eq (char-before (1- (point))) ?$))))
+
+(defun company-cmake (command &optional arg &rest ignored)
+ "`company-mode' completion backend for CMake.
+CMake is a cross-platform, open-source make system."
+ (interactive (list 'interactive))
+ (cl-case command
+ (interactive (company-begin-backend 'company-cmake))
+ (init (when (memq major-mode company-cmake-modes)
+ (unless company-cmake-executable
+ (error "Company found no cmake executable"))))
+ (prefix (and (memq major-mode company-cmake-modes)
+ (or (not (company-in-string-or-comment))
+ (company-cmake-prefix-dollar-brace-p))
+ (company-grab-symbol)))
+ (candidates (company-cmake--candidates arg))
+ (meta (company-cmake--meta arg))
+ (doc-buffer (company-cmake--doc-buffer arg))
+ ))
+
+(provide 'company-cmake)
+;;; company-cmake.el ends here
diff --git a/elpa/company-20220425.1145/company-cmake.elc b/elpa/company-20220425.1145/company-cmake.elc
new file mode 100644
index 0000000..3f035bd
--- /dev/null
+++ b/elpa/company-20220425.1145/company-cmake.elc
Binary files differ
diff --git a/elpa/company-20220425.1145/company-css.el b/elpa/company-20220425.1145/company-css.el
new file mode 100644
index 0000000..f5ac7c7
--- /dev/null
+++ b/elpa/company-20220425.1145/company-css.el
@@ -0,0 +1,446 @@
+;;; company-css.el --- company-mode completion backend for css-mode -*- lexical-binding: t -*-
+
+;; Copyright (C) 2009-2011, 2013-2015, 2018 Free Software Foundation, Inc.
+
+;; Author: Nikolaj Schumacher
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs 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.
+
+;; GNU Emacs 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 GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;
+;; In Emacs >= 26, company-capf is used instead.
+
+;;; Code:
+
+(require 'company)
+(require 'cl-lib)
+
+(declare-function web-mode-language-at-pos "web-mode" (&optional pos))
+
+(defconst company-css-property-alist
+ ;; see http://www.w3.org/TR/CSS21/propidx.html
+ '(("azimuth" angle "left-side" "far-left" "left" "center-left" "center"
+ "center-right" "right" "far-right" "right-side" "behind" "leftwards"
+ "rightwards")
+ ("background" background-color background-image background-repeat
+ background-attachment background-position
+ background-clip background-origin background-size)
+ ("background-attachment" "scroll" "fixed")
+ ("background-color" color "transparent")
+ ("background-image" uri "none")
+ ("background-position" percentage length "left" "center" "right" percentage
+ length "top" "center" "bottom" "left" "center" "right" "top" "center"
+ "bottom")
+ ("background-repeat" "repeat" "repeat-x" "repeat-y" "no-repeat")
+ ("border" border-width border-style border-color)
+ ("border-bottom" border)
+ ("border-bottom-color" border-color)
+ ("border-bottom-style" border-style)
+ ("border-bottom-width" border-width)
+ ("border-collapse" "collapse" "separate")
+ ("border-color" color "transparent")
+ ("border-left" border)
+ ("border-left-color" border-color)
+ ("border-left-style" border-style)
+ ("border-left-width" border-width)
+ ("border-right" border)
+ ("border-right-color" border-color)
+ ("border-right-style" border-style)
+ ("border-right-width" border-width)
+ ("border-spacing" length length)
+ ("border-style" border-style)
+ ("border-top" border)
+ ("border-top-color" border-color)
+ ("border-top-style" border-style)
+ ("border-top-width" border-width)
+ ("border-width" border-width)
+ ("bottom" length percentage "auto")
+ ("caption-side" "top" "bottom")
+ ("clear" "none" "left" "right" "both")
+ ("clip" shape "auto")
+ ("color" color)
+ ("content" "normal" "none" string uri counter "attr()" "open-quote"
+ "close-quote" "no-open-quote" "no-close-quote")
+ ("counter-increment" identifier integer "none")
+ ("counter-reset" identifier integer "none")
+ ("cue" cue-before cue-after)
+ ("cue-after" uri "none")
+ ("cue-before" uri "none")
+ ("cursor" uri "*" "auto" "crosshair" "default" "pointer" "move" "e-resize"
+ "ne-resize" "nw-resize" "n-resize" "se-resize" "sw-resize" "s-resize"
+ "w-resize" "text" "wait" "help" "progress")
+ ("direction" "ltr" "rtl")
+ ("display" "inline" "block" "list-item" "run-in" "inline-block" "table"
+ "inline-table" "table-row-group" "table-header-group" "table-footer-group"
+ "table-row" "table-column-group" "table-column" "table-cell"
+ "table-caption" "none")
+ ("elevation" angle "below" "level" "above" "higher" "lower")
+ ("empty-cells" "show" "hide")
+ ("float" "left" "right" "none")
+ ("font" font-style font-weight font-size "/" line-height
+ font-family "caption" "icon" "menu" "message-box" "small-caption"
+ "status-bar" "normal" "small-caps"
+ ;; CSS3
+ font-stretch)
+ ("font-family" family-name generic-family)
+ ("font-size" absolute-size relative-size length percentage)
+ ("font-style" "normal" "italic" "oblique")
+ ("font-weight" "normal" "bold" "bolder" "lighter" "100" "200" "300" "400"
+ "500" "600" "700" "800" "900")
+ ("height" length percentage "auto")
+ ("left" length percentage "auto")
+ ("letter-spacing" "normal" length)
+ ("line-height" "normal" number length percentage)
+ ("list-style" list-style-type list-style-position list-style-image)
+ ("list-style-image" uri "none")
+ ("list-style-position" "inside" "outside")
+ ("list-style-type" "disc" "circle" "square" "decimal" "decimal-leading-zero"
+ "lower-roman" "upper-roman" "lower-greek" "lower-latin" "upper-latin"
+ "armenian" "georgian" "lower-alpha" "upper-alpha" "none")
+ ("margin" margin-width)
+ ("margin-bottom" margin-width)
+ ("margin-left" margin-width)
+ ("margin-right" margin-width)
+ ("margin-top" margin-width)
+ ("max-height" length percentage "none")
+ ("max-width" length percentage "none")
+ ("min-height" length percentage)
+ ("min-width" length percentage)
+ ("orphans" integer)
+ ("outline" outline-color outline-style outline-width)
+ ("outline-color" color "invert")
+ ("outline-style" border-style)
+ ("outline-width" border-width)
+ ("overflow" "visible" "hidden" "scroll" "auto"
+ ;; CSS3:
+ "no-display" "no-content")
+ ("padding" padding-width)
+ ("padding-bottom" padding-width)
+ ("padding-left" padding-width)
+ ("padding-right" padding-width)
+ ("padding-top" padding-width)
+ ("page-break-after" "auto" "always" "avoid" "left" "right")
+ ("page-break-before" "auto" "always" "avoid" "left" "right")
+ ("page-break-inside" "avoid" "auto")
+ ("pause" time percentage)
+ ("pause-after" time percentage)
+ ("pause-before" time percentage)
+ ("pitch" frequency "x-low" "low" "medium" "high" "x-high")
+ ("pitch-range" number)
+ ("play-during" uri "mix" "repeat" "auto" "none")
+ ("position" "static" "relative" "absolute" "fixed")
+ ("quotes" string string "none")
+ ("richness" number)
+ ("right" length percentage "auto")
+ ("speak" "normal" "none" "spell-out")
+ ("speak-header" "once" "always")
+ ("speak-numeral" "digits" "continuous")
+ ("speak-punctuation" "code" "none")
+ ("speech-rate" number "x-slow" "slow" "medium" "fast" "x-fast" "faster"
+ "slower")
+ ("stress" number)
+ ("table-layout" "auto" "fixed")
+ ("text-align" "left" "right" "center" "justify")
+ ("text-indent" length percentage)
+ ("text-transform" "capitalize" "uppercase" "lowercase" "none")
+ ("top" length percentage "auto")
+ ("unicode-bidi" "normal" "embed" "bidi-override")
+ ("vertical-align" "baseline" "sub" "super" "top" "text-top" "middle"
+ "bottom" "text-bottom" percentage length)
+ ("visibility" "visible" "hidden" "collapse")
+ ("voice-family" specific-voice generic-voice "*" specific-voice
+ generic-voice)
+ ("volume" number percentage "silent" "x-soft" "soft" "medium" "loud"
+ "x-loud")
+ ("white-space" "normal" "pre" "nowrap" "pre-wrap" "pre-line")
+ ("widows" integer)
+ ("width" length percentage "auto")
+ ("word-spacing" "normal" length)
+ ("z-index" "auto" integer)
+ ;; CSS3
+ ("align-content" align-stretch "space-between" "space-around")
+ ("align-items" align-stretch "baseline")
+ ("align-self" align-items "auto")
+ ("animation" animation-name animation-duration animation-timing-function
+ animation-delay animation-iteration-count animation-direction
+ animation-fill-mode)
+ ("animation-delay" time)
+ ("animation-direction" "normal" "reverse" "alternate" "alternate-reverse")
+ ("animation-duration" time)
+ ("animation-fill-mode" "none" "forwards" "backwards" "both")
+ ("animation-iteration-count" integer "infinite")
+ ("animation-name" "none")
+ ("animation-play-state" "paused" "running")
+ ("animation-timing-function" transition-timing-function
+ "step-start" "step-end" "steps(,)")
+ ("backface-visibility" "visible" "hidden")
+ ("background-clip" background-origin)
+ ("background-origin" "border-box" "padding-box" "content-box")
+ ("background-size" length percentage "auto" "cover" "contain")
+ ("border-image" border-image-outset border-image-repeat border-image-source
+ border-image-slice border-image-width)
+ ("border-image-outset" length)
+ ("border-image-repeat" "stretch" "repeat" "round" "space")
+ ("border-image-source" uri "none")
+ ("border-image-slice" length)
+ ("border-image-width" length percentage)
+ ("border-radius" length)
+ ("border-top-left-radius" length)
+ ("border-top-right-radius" length)
+ ("border-bottom-left-radius" length)
+ ("border-bottom-right-radius" length)
+ ("box-decoration-break" "slice" "clone")
+ ("box-shadow" length color)
+ ("box-sizing" "content-box" "border-box")
+ ("break-after" "auto" "always" "avoid" "left" "right" "page" "column"
+ "avoid-page" "avoid-column")
+ ("break-before" break-after)
+ ("break-inside" "avoid" "auto")
+ ("columns" column-width column-count)
+ ("column-count" integer)
+ ("column-fill" "auto" "balance")
+ ("column-gap" length "normal")
+ ("column-rule" column-rule-width column-rule-style column-rule-color)
+ ("column-rule-color" color)
+ ("column-rule-style" border-style)
+ ("column-rule-width" border-width)
+ ("column-span" "all" "none")
+ ("column-width" length "auto")
+ ("filter" url "blur()" "brightness()" "contrast()" "drop-shadow()"
+ "grayscale()" "hue-rotate()" "invert()" "opacity()" "saturate()" "sepia()")
+ ("flex" flex-grow flex-shrink flex-basis)
+ ("flex-basis" percentage length "auto")
+ ("flex-direction" "row" "row-reverse" "column" "column-reverse")
+ ("flex-flow" flex-direction flex-wrap)
+ ("flex-grow" number)
+ ("flex-shrink" number)
+ ("flex-wrap" "nowrap" "wrap" "wrap-reverse")
+ ("font-feature-setting" normal string number)
+ ("font-kerning" "auto" "normal" "none")
+ ("font-language-override" "normal" string)
+ ("font-size-adjust" "none" number)
+ ("font-stretch" "normal" "ultra-condensed" "extra-condensed" "condensed"
+ "semi-condensed" "semi-expanded" "expanded" "extra-expanded" "ultra-expanded")
+ ("font-synthesis" "none" "weight" "style")
+ ("font-variant" font-variant-alternates font-variant-caps
+ font-variant-east-asian font-variant-ligatures font-variant-numeric
+ font-variant-position)
+ ("font-variant-alternates" "normal" "historical-forms" "stylistic()"
+ "styleset()" "character-variant()" "swash()" "ornaments()" "annotation()")
+ ("font-variant-caps" "normal" "small-caps" "all-small-caps" "petite-caps"
+ "all-petite-caps" "unicase" "titling-caps")
+ ("font-variant-east-asian" "jis78" "jis83" "jis90" "jis04" "simplified"
+ "traditional" "full-width" "proportional-width" "ruby")
+ ("font-variant-ligatures" "normal" "none" "common-ligatures"
+ "no-common-ligatures" "discretionary-ligatures" "no-discretionary-ligatures"
+ "historical-ligatures" "no-historical-ligatures" "contextual" "no-contextual")
+ ("font-variant-numeric" "normal" "ordinal" "slashed-zero"
+ "lining-nums" "oldstyle-nums" "proportional-nums" "tabular-nums"
+ "diagonal-fractions" "stacked-fractions")
+ ("font-variant-position" "normal" "sub" "super")
+ ("hyphens" "none" "manual" "auto")
+ ("justify-content" align-common "space-between" "space-around")
+ ("line-break" "auto" "loose" "normal" "strict")
+ ("marquee-direction" "forward" "reverse")
+ ("marquee-play-count" integer "infinite")
+ ("marquee-speed" "slow" "normal" "fast")
+ ("marquee-style" "scroll" "slide" "alternate")
+ ("opacity" number)
+ ("order" number)
+ ("outline-offset" length)
+ ("overflow-x" overflow)
+ ("overflow-y" overflow)
+ ("overflow-style" "auto" "marquee-line" "marquee-block")
+ ("overflow-wrap" "normal" "break-word")
+ ("perspective" "none" length)
+ ("perspective-origin" percentage length "left" "center" "right" "top" "bottom")
+ ("resize" "none" "both" "horizontal" "vertical")
+ ("tab-size" integer length)
+ ("text-align-last" "auto" "start" "end" "left" "right" "center" "justify")
+ ("text-decoration" text-decoration-color text-decoration-line text-decoration-style)
+ ("text-decoration-color" color)
+ ("text-decoration-line" "none" "underline" "overline" "line-through" "blink")
+ ("text-decoration-style" "solid" "double" "dotted" "dashed" "wavy")
+ ("text-overflow" "clip" "ellipsis")
+ ("text-shadow" color length)
+ ("text-underline-position" "auto" "under" "left" "right")
+ ("transform" "matrix(,,,,,)" "translate(,)" "translateX()" "translateY()"
+ "scale()" "scaleX()" "scaleY()" "rotate()" "skewX()" "skewY()" "none")
+ ("transform-origin" perspective-origin)
+ ("transform-style" "flat" "preserve-3d")
+ ("transition" transition-property transition-duration
+ transition-timing-function transition-delay)
+ ("transition-delay" time)
+ ("transition-duration" time)
+ ("transition-timing-function"
+ "ease" "linear" "ease-in" "ease-out" "ease-in-out" "cubic-bezier(,,,)")
+ ("transition-property" "none" "all" identifier)
+ ("word-wrap" overflow-wrap)
+ ("word-break" "normal" "break-all" "keep-all"))
+ "A list of CSS properties and their possible values.")
+
+(defconst company-css-value-classes
+ '((absolute-size "xx-small" "x-small" "small" "medium" "large" "x-large"
+ "xx-large")
+ (align-common "flex-start" "flex-end" "center")
+ (align-stretch align-common "stretch")
+ (border-style "none" "hidden" "dotted" "dashed" "solid" "double" "groove"
+ "ridge" "inset" "outset")
+ (border-width "thick" "medium" "thin")
+ (color "aqua" "black" "blue" "fuchsia" "gray" "green" "lime" "maroon" "navy"
+ "olive" "orange" "purple" "red" "silver" "teal" "white" "yellow")
+ (counter "counter(,)")
+ (family-name "Courier" "Helvetica" "Times")
+ (generic-family "serif" "sans-serif" "cursive" "fantasy" "monospace")
+ (generic-voice "male" "female" "child")
+ (margin-width "auto") ;; length percentage
+ (relative-size "larger" "smaller")
+ (shape "rect(,,,)")
+ (uri "url()"))
+ "A list of CSS property value classes and their contents.")
+;; missing, because not completable
+;; <angle><frequency><identifier><integer><length><number><padding-width>
+;; <percentage><specific-voice><string><time><uri>
+
+(defconst company-css-html-tags
+ '("a" "abbr" "acronym" "address" "applet" "area" "b" "base" "basefont" "bdo"
+ "big" "blockquote" "body" "br" "button" "caption" "center" "cite" "code"
+ "col" "colgroup" "dd" "del" "dfn" "dir" "div" "dl" "dt" "em" "fieldset"
+ "font" "form" "frame" "frameset" "h1" "h2" "h3" "h4" "h5" "h6" "head" "hr"
+ "html" "i" "iframe" "img" "input" "ins" "isindex" "kbd" "label" "legend"
+ "li" "link" "map" "menu" "meta" "noframes" "noscript" "object" "ol"
+ "optgroup" "option" "p" "param" "pre" "q" "s" "samp" "script" "select"
+ "small" "span" "strike" "strong" "style" "sub" "sup" "table" "tbody" "td"
+ "textarea" "tfoot" "th" "thead" "title" "tr" "tt" "u" "ul" "var"
+ ;; HTML5
+ "section" "article" "aside" "header" "footer" "nav" "figure" "figcaption"
+ "time" "mark" "main")
+ "A list of HTML tags for use in CSS completion.")
+
+(defconst company-css-pseudo-classes
+ '("active" "after" "before" "first" "first-child" "first-letter" "first-line"
+ "focus" "hover" "lang" "left" "link" "right" "visited")
+ "Identifiers for CSS pseudo-elements and pseudo-classes.")
+
+(defconst company-css-property-cache (make-hash-table :size 115 :test 'equal))
+
+(defun company-css-property-values (attribute)
+ "Access the `company-css-property-alist' cached and flattened."
+ (or (gethash attribute company-css-property-cache)
+ (let (results)
+ (dolist (value (cdr (assoc attribute company-css-property-alist)))
+ (if (symbolp value)
+ (dolist (child (or (cdr (assoc value company-css-value-classes))
+ (company-css-property-values
+ (symbol-name value))))
+ (push child results))
+ (push value results)))
+ (setq results (sort results 'string<))
+ (puthash attribute
+ (if (fboundp 'delete-consecutive-dups)
+ (delete-consecutive-dups results)
+ (delete-dups results))
+ company-css-property-cache)
+ results)))
+
+;;; bracket detection
+
+(defconst company-css-braces-syntax-table
+ (let ((table (make-syntax-table)))
+ (setf (aref table ?{) '(4 . 125))
+ (setf (aref table ?}) '(5 . 123))
+ table)
+ "A syntax table giving { and } paren syntax.")
+
+(defun company-css-inside-braces-p ()
+ "Return non-nil, if point is within matched { and }."
+ (ignore-errors
+ (with-syntax-table company-css-braces-syntax-table
+ (let ((parse-sexp-ignore-comments t))
+ (scan-lists (point) -1 1)))))
+
+;;; tags
+(defconst company-css-tag-regexp
+ (concat "\\(?:\\`\\|}\\)[[:space:]]*"
+ ;; multiple
+ "\\(?:"
+ ;; previous tags:
+ "\\(?:#\\|\\_<[[:alpha:]]\\)[[:alnum:]-#]*\\(?:\\[[^]]*\\]\\)?"
+ ;; space or selectors
+ "\\(?:[[:space:]]+\\|[[:space:]]*[+,>][[:space:]]*\\)"
+ "\\)*"
+ "\\(\\(?:#\\|\\_<[[:alpha:]]\\)\\(?:[[:alnum:]-#]*\\_>\\)?\\_>\\|\\)"
+ "\\=")
+ "A regular expression matching CSS tags.")
+
+;;; pseudo id
+(defconst company-css-pseudo-regexp
+ (concat "\\(?:\\`\\|}\\)[[:space:]]*"
+ ;; multiple
+ "\\(?:"
+ ;; previous tags:
+ "\\(?:#\\|\\_<[[:alpha:]]\\)[[:alnum:]-#]*\\(?:\\[[^]]*\\]\\)?"
+ ;; space or delimiters
+ "\\(?:[[:space:]]+\\|[[:space:]]*[+,>][[:space:]]*\\)"
+ "\\)*"
+ "\\(?:\\(?:\\#\\|\\_<[[:alpha:]]\\)[[:alnum:]-#]*\\):"
+ "\\([[:alpha:]-]+\\_>\\|\\)\\_>\\=")
+ "A regular expression matching CSS pseudo classes.")
+
+;;; properties
+
+(defun company-css-grab-property ()
+ "Return the CSS property before point, if any.
+Returns \"\" if no property found, but feasible at this position."
+ (when (company-css-inside-braces-p)
+ (company-grab-symbol)))
+
+;;; values
+(defconst company-css-property-value-regexp
+ "\\_<\\([[:alpha:]-]+\\):\\(?:[^{};]*[[:space:]]+\\)?\\([^{};]*\\_>\\|\\)\\="
+ "A regular expression matching CSS tags.")
+
+;;;###autoload
+(defun company-css (command &optional arg &rest ignored)
+ "`company-mode' completion backend for `css-mode'."
+ (interactive (list 'interactive))
+ (cl-case command
+ (interactive (company-begin-backend 'company-css))
+ (prefix (and (or (derived-mode-p 'css-mode)
+ (and (derived-mode-p 'web-mode)
+ (string= (web-mode-language-at-pos) "css")))
+ (or (company-grab company-css-tag-regexp 1)
+ (company-grab company-css-pseudo-regexp 1)
+ (company-grab company-css-property-value-regexp 2
+ (line-beginning-position))
+ (company-css-grab-property))))
+ (candidates
+ (cond
+ ((company-grab company-css-tag-regexp 1)
+ (all-completions arg company-css-html-tags))
+ ((company-grab company-css-pseudo-regexp 1)
+ (all-completions arg company-css-pseudo-classes))
+ ((company-grab company-css-property-value-regexp 2
+ (line-beginning-position))
+ (all-completions arg
+ (company-css-property-values
+ (company-grab company-css-property-value-regexp 1))))
+ ((company-css-grab-property)
+ (all-completions arg company-css-property-alist))))
+ (sorted t)))
+
+(provide 'company-css)
+;;; company-css.el ends here
diff --git a/elpa/company-20220425.1145/company-css.elc b/elpa/company-20220425.1145/company-css.elc
new file mode 100644
index 0000000..7f78053
--- /dev/null
+++ b/elpa/company-20220425.1145/company-css.elc
Binary files differ
diff --git a/elpa/company-20220425.1145/company-dabbrev-code.el b/elpa/company-20220425.1145/company-dabbrev-code.el
new file mode 100644
index 0000000..e1d2bf0
--- /dev/null
+++ b/elpa/company-20220425.1145/company-dabbrev-code.el
@@ -0,0 +1,105 @@
+;;; company-dabbrev-code.el --- dabbrev-like company-mode backend for code -*- lexical-binding: t -*-
+
+;; Copyright (C) 2009-2011, 2013-2016, 2021 Free Software Foundation, Inc.
+
+;; Author: Nikolaj Schumacher
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs 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.
+
+;; GNU Emacs 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 GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
+
+
+;;; Commentary:
+;;
+
+;;; Code:
+
+(require 'company)
+(require 'company-dabbrev)
+(require 'cl-lib)
+
+(defgroup company-dabbrev-code nil
+ "dabbrev-like completion backend for code."
+ :group 'company)
+
+(defcustom company-dabbrev-code-modes
+ '(prog-mode
+ batch-file-mode csharp-mode css-mode erlang-mode haskell-mode jde-mode
+ lua-mode python-mode)
+ "Modes that use `company-dabbrev-code'.
+In all these modes (and their derivatives) `company-dabbrev-code' will
+complete only symbols, not text in comments or strings. In other modes
+`company-dabbrev-code' will pass control to other backends
+\(e.g. `company-dabbrev'\). Value t means complete in all modes."
+ :type '(choice (repeat :tag "Some modes" (symbol :tag "Major mode"))
+ (const :tag "All modes" t)))
+
+(defcustom company-dabbrev-code-other-buffers t
+ "Determines whether `company-dabbrev-code' should search other buffers.
+If `all', search all other buffers, except the ignored ones. If t, search
+buffers with the same major mode. If `code', search all buffers with major
+modes in `company-dabbrev-code-modes', or derived from one of them. See
+also `company-dabbrev-code-time-limit'."
+ :type '(choice (const :tag "Off" nil)
+ (const :tag "Same major mode" t)
+ (const :tag "Code major modes" code)
+ (const :tag "All" all)))
+
+(defcustom company-dabbrev-code-time-limit .1
+ "Determines how long `company-dabbrev-code' should look for matches."
+ :type '(choice (const :tag "Off" nil)
+ (number :tag "Seconds")))
+
+(defcustom company-dabbrev-code-everywhere nil
+ "Non-nil to offer completions in comments and strings."
+ :type 'boolean)
+
+(defcustom company-dabbrev-code-ignore-case nil
+ "Non-nil to ignore case when collecting completion candidates."
+ :type 'boolean)
+
+(defun company-dabbrev-code--make-regexp (prefix)
+ (concat "\\_<" (if (equal prefix "")
+ "\\([a-zA-Z]\\|\\s_\\)"
+ (regexp-quote prefix))
+ "\\(\\sw\\|\\s_\\)*\\_>"))
+
+;;;###autoload
+(defun company-dabbrev-code (command &optional arg &rest ignored)
+ "dabbrev-like `company-mode' backend for code.
+The backend looks for all symbols in the current buffer that aren't in
+comments or strings."
+ (interactive (list 'interactive))
+ (cl-case command
+ (interactive (company-begin-backend 'company-dabbrev-code))
+ (prefix (and (or (eq t company-dabbrev-code-modes)
+ (apply #'derived-mode-p company-dabbrev-code-modes))
+ (or company-dabbrev-code-everywhere
+ (not (company-in-string-or-comment)))
+ (or (company-grab-symbol) 'stop)))
+ (candidates (let ((case-fold-search company-dabbrev-code-ignore-case))
+ (company-dabbrev--search
+ (company-dabbrev-code--make-regexp arg)
+ company-dabbrev-code-time-limit
+ (pcase company-dabbrev-code-other-buffers
+ (`t (list major-mode))
+ (`code company-dabbrev-code-modes)
+ (`all `all))
+ (not company-dabbrev-code-everywhere))))
+ (kind 'text)
+ (ignore-case company-dabbrev-code-ignore-case)
+ (duplicates t)))
+
+(provide 'company-dabbrev-code)
+;;; company-dabbrev-code.el ends here
diff --git a/elpa/company-20220425.1145/company-dabbrev-code.elc b/elpa/company-20220425.1145/company-dabbrev-code.elc
new file mode 100644
index 0000000..e1a9112
--- /dev/null
+++ b/elpa/company-20220425.1145/company-dabbrev-code.elc
Binary files differ
diff --git a/elpa/company-20220425.1145/company-dabbrev.el b/elpa/company-20220425.1145/company-dabbrev.el
new file mode 100644
index 0000000..3b8268c
--- /dev/null
+++ b/elpa/company-20220425.1145/company-dabbrev.el
@@ -0,0 +1,207 @@
+;;; company-dabbrev.el --- dabbrev-like company-mode completion backend -*- lexical-binding: t -*-
+
+;; Copyright (C) 2009-2011, 2013-2018, 2021 Free Software Foundation, Inc.
+
+;; Author: Nikolaj Schumacher
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs 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.
+
+;; GNU Emacs 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 GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
+
+
+;;; Commentary:
+;;
+
+;;; Code:
+
+(require 'company)
+(require 'cl-lib)
+
+(defgroup company-dabbrev nil
+ "dabbrev-like completion backend."
+ :group 'company)
+
+(defcustom company-dabbrev-other-buffers 'all
+ "Determines whether `company-dabbrev' should search other buffers.
+If `all', search all other buffers, except the ignored ones. If t, search
+buffers with the same major mode. See also `company-dabbrev-time-limit'."
+ :type '(choice (const :tag "Off" nil)
+ (const :tag "Same major mode" t)
+ (const :tag "All" all)))
+
+(defcustom company-dabbrev-ignore-buffers "\\`[ *]"
+ "Regexp matching the names of buffers to ignore.
+Or a function that returns non-nil for such buffers."
+ :type '(choice (regexp :tag "Regexp")
+ (function :tag "Predicate"))
+ :package-version '(company . "0.9.0"))
+
+(defcustom company-dabbrev-time-limit .1
+ "Determines how many seconds `company-dabbrev' should look for matches."
+ :type '(choice (const :tag "Off" nil)
+ (number :tag "Seconds")))
+
+(defcustom company-dabbrev-char-regexp "\\sw"
+ "A regular expression matching the characters `company-dabbrev' looks for."
+ :type 'regexp)
+
+(defcustom company-dabbrev-ignore-case 'keep-prefix
+ "Non-nil to ignore case when collecting completion candidates.
+When it's `keep-prefix', the text before point will remain unchanged after
+candidate is inserted, even some of its characters have different case."
+ :type '(choice
+ (const :tag "Don't ignore case" nil)
+ (const :tag "Ignore case" t)
+ (const :tag "Keep case before point" keep-prefix)))
+
+(defcustom company-dabbrev-downcase 'case-replace
+ "Whether to downcase the returned candidates.
+
+The value of nil means keep them as-is.
+`case-replace' means use the value of `case-replace'.
+Any other value means downcase.
+
+If you set this value to nil, you may also want to set
+`company-dabbrev-ignore-case' to any value other than `keep-prefix'."
+ :type '(choice
+ (const :tag "Keep as-is" nil)
+ (const :tag "Downcase" t)
+ (const :tag "Use case-replace" case-replace)))
+
+(defcustom company-dabbrev-minimum-length 4
+ "The minimum length for the completion candidate to be included.
+This variable affects both `company-dabbrev' and `company-dabbrev-code'."
+ :type 'integer
+ :package-version '(company . "0.8.3"))
+
+(defcustom company-dabbrev-ignore-invisible nil
+ "Non-nil to skip invisible text."
+ :type 'boolean
+ :package-version '(company . "0.9.0"))
+
+(defmacro company-dabbrev--time-limit-while (test start limit freq &rest body)
+ (declare (indent 3) (debug t))
+ `(let ((company-time-limit-while-counter 0))
+ (catch 'done
+ (while ,test
+ ,@body
+ (and ,limit
+ (= (cl-incf company-time-limit-while-counter) ,freq)
+ (setq company-time-limit-while-counter 0)
+ (> (float-time (time-since ,start)) ,limit)
+ (throw 'done 'company-time-out))))))
+
+(defun company-dabbrev--make-regexp ()
+ (concat "\\(?:" company-dabbrev-char-regexp "\\)+"))
+
+(defun company-dabbrev--search-buffer (regexp pos symbols start limit
+ ignore-comments)
+ (save-excursion
+ (cl-labels ((maybe-collect-match
+ ()
+ (let ((match (match-string-no-properties 0)))
+ (when (and (>= (length match) company-dabbrev-minimum-length)
+ (not (and company-dabbrev-ignore-invisible
+ (invisible-p (match-beginning 0)))))
+ (push match symbols)))))
+ (goto-char (if pos (1- pos) (point-min)))
+ ;; Search before pos.
+ (let ((tmp-end (point)))
+ (company-dabbrev--time-limit-while (and (not (input-pending-p))
+ (> tmp-end (point-min)))
+ start limit 1
+ (ignore-errors
+ (forward-char -10000))
+ (forward-line 0)
+ (save-excursion
+ ;; Before, we used backward search, but it matches non-greedily, and
+ ;; that forced us to use the "beginning/end of word" anchors in
+ ;; `company-dabbrev--make-regexp'. It's also about 2x slower.
+ (while (and (not (input-pending-p))
+ (re-search-forward regexp tmp-end t))
+ (if (and ignore-comments (save-match-data (company-in-string-or-comment)))
+ (re-search-forward "\\s>\\|\\s!\\|\\s\"" tmp-end t)
+ (maybe-collect-match))))
+ (setq tmp-end (point))))
+ (goto-char (or pos (point-min)))
+ ;; Search after pos.
+ (company-dabbrev--time-limit-while (and (not (input-pending-p))
+ (re-search-forward regexp nil t))
+ start limit 25
+ (if (and ignore-comments (save-match-data (company-in-string-or-comment)))
+ (re-search-forward "\\s>\\|\\s!\\|\\s\"" nil t)
+ (maybe-collect-match)))
+ symbols)))
+
+(defun company-dabbrev--search (regexp &optional limit other-buffer-modes
+ ignore-comments)
+ (let* ((start (current-time))
+ (symbols (company-dabbrev--search-buffer regexp (point) nil start limit
+ ignore-comments)))
+ (when other-buffer-modes
+ (cl-dolist (buffer (delq (current-buffer) (buffer-list)))
+ (unless (if (stringp company-dabbrev-ignore-buffers)
+ (string-match-p company-dabbrev-ignore-buffers
+ (buffer-name buffer))
+ (funcall company-dabbrev-ignore-buffers buffer))
+ (with-current-buffer buffer
+ (when (or (eq other-buffer-modes 'all)
+ (apply #'derived-mode-p other-buffer-modes))
+ (setq symbols
+ (company-dabbrev--search-buffer regexp nil symbols start
+ limit ignore-comments)))))
+ (and limit
+ (> (float-time (time-since start)) limit)
+ (cl-return))))
+ symbols))
+
+(defun company-dabbrev--prefix ()
+ ;; Not in the middle of a word.
+ (unless (looking-at company-dabbrev-char-regexp)
+ ;; Emacs can't do greedy backward-search.
+ (company-grab-line (format "\\(?:^\\| \\)[^ ]*?\\(\\(?:%s\\)*\\)"
+ company-dabbrev-char-regexp)
+ 1)))
+
+(defun company-dabbrev--filter (prefix candidates)
+ (let ((completion-ignore-case company-dabbrev-ignore-case))
+ (all-completions prefix candidates)))
+
+;;;###autoload
+(defun company-dabbrev (command &optional arg &rest ignored)
+ "dabbrev-like `company-mode' completion backend."
+ (interactive (list 'interactive))
+ (cl-case command
+ (interactive (company-begin-backend 'company-dabbrev))
+ (prefix (company-dabbrev--prefix))
+ (candidates
+ (let* ((case-fold-search company-dabbrev-ignore-case)
+ (words (company-dabbrev--search (company-dabbrev--make-regexp)
+ company-dabbrev-time-limit
+ (pcase company-dabbrev-other-buffers
+ (`t (list major-mode))
+ (`all `all))))
+ (downcase-p (if (eq company-dabbrev-downcase 'case-replace)
+ case-replace
+ company-dabbrev-downcase)))
+ (setq words (company-dabbrev--filter arg words))
+ (if downcase-p
+ (mapcar 'downcase words)
+ words)))
+ (kind 'text)
+ (ignore-case company-dabbrev-ignore-case)
+ (duplicates t)))
+
+(provide 'company-dabbrev)
+;;; company-dabbrev.el ends here
diff --git a/elpa/company-20220425.1145/company-dabbrev.elc b/elpa/company-20220425.1145/company-dabbrev.elc
new file mode 100644
index 0000000..5da697c
--- /dev/null
+++ b/elpa/company-20220425.1145/company-dabbrev.elc
Binary files differ
diff --git a/elpa/company-20220425.1145/company-elisp.el b/elpa/company-20220425.1145/company-elisp.el
new file mode 100644
index 0000000..23fe6af
--- /dev/null
+++ b/elpa/company-20220425.1145/company-elisp.el
@@ -0,0 +1,226 @@
+;;; company-elisp.el --- company-mode completion backend for Emacs Lisp -*- lexical-binding: t -*-
+
+;; Copyright (C) 2009-2015, 2017, 2020 Free Software Foundation, Inc.
+
+;; Author: Nikolaj Schumacher
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs 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.
+
+;; GNU Emacs 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 GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
+
+
+;;; Commentary:
+;;
+;; In newer versions of Emacs, company-capf is used instead.
+
+;;; Code:
+
+(require 'company)
+(require 'cl-lib)
+(require 'help-mode)
+(require 'find-func)
+
+(defgroup company-elisp nil
+ "Completion backend for Emacs Lisp."
+ :group 'company)
+
+(defcustom company-elisp-detect-function-context t
+ "If enabled, offer Lisp functions only in appropriate contexts.
+Functions are offered for completion only after \\=' and \(."
+ :type '(choice (const :tag "Off" nil)
+ (const :tag "On" t)))
+
+(defcustom company-elisp-show-locals-first t
+ "If enabled, locally bound variables and functions are displayed
+first in the candidates list."
+ :type '(choice (const :tag "Off" nil)
+ (const :tag "On" t)))
+
+(defun company-elisp--prefix ()
+ (let ((prefix (company-grab-symbol)))
+ (if prefix
+ (when (if (company-in-string-or-comment)
+ (= (char-before (- (point) (length prefix))) ?`)
+ (company-elisp--should-complete))
+ prefix)
+ 'stop)))
+
+(defun company-elisp--predicate (symbol)
+ (or (boundp symbol)
+ (fboundp symbol)
+ (facep symbol)
+ (featurep symbol)))
+
+(defun company-elisp--fns-regexp (&rest names)
+ (concat "\\_<\\(?:cl-\\)?" (regexp-opt names) "\\*?\\_>"))
+
+(defvar company-elisp-parse-limit 30)
+(defvar company-elisp-parse-depth 100)
+
+(defvar company-elisp-defun-names '("defun" "defmacro" "defsubst"))
+
+(defvar company-elisp-var-binding-regexp
+ (apply #'company-elisp--fns-regexp "let" "lambda" "lexical-let"
+ company-elisp-defun-names)
+ "Regular expression matching head of a multiple variable bindings form.")
+
+(defvar company-elisp-var-binding-regexp-1
+ (company-elisp--fns-regexp "dolist" "dotimes")
+ "Regular expression matching head of a form with one variable binding.")
+
+(defvar company-elisp-fun-binding-regexp
+ (company-elisp--fns-regexp "flet" "labels")
+ "Regular expression matching head of a function bindings form.")
+
+(defvar company-elisp-defuns-regexp
+ (concat "([ \t\n]*"
+ (apply #'company-elisp--fns-regexp company-elisp-defun-names)))
+
+(defun company-elisp--should-complete ()
+ (let ((start (point))
+ (depth (car (syntax-ppss))))
+ (not
+ (when (> depth 0)
+ (save-excursion
+ (up-list (- depth))
+ (when (looking-at company-elisp-defuns-regexp)
+ (forward-char)
+ (forward-sexp 1)
+ (unless (= (point) start)
+ (condition-case nil
+ (let ((args-end (scan-sexps (point) 2)))
+ (or (null args-end)
+ (> args-end start)))
+ (scan-error
+ t)))))))))
+
+(defun company-elisp--locals (prefix functions-p)
+ (let ((regexp (concat "[ \t\n]*\\(\\_<" (regexp-quote prefix)
+ "\\(?:\\sw\\|\\s_\\)*\\_>\\)"))
+ (pos (point))
+ res)
+ (condition-case nil
+ (save-excursion
+ (dotimes (_ company-elisp-parse-depth)
+ (up-list -1)
+ (save-excursion
+ (when (eq (char-after) ?\()
+ (forward-char 1)
+ (when (ignore-errors
+ (save-excursion (forward-list)
+ (<= (point) pos)))
+ (skip-chars-forward " \t\n")
+ (cond
+ ((looking-at (if functions-p
+ company-elisp-fun-binding-regexp
+ company-elisp-var-binding-regexp))
+ (down-list 1)
+ (condition-case nil
+ (dotimes (_ company-elisp-parse-limit)
+ (save-excursion
+ (when (looking-at "[ \t\n]*(")
+ (down-list 1))
+ (when (looking-at regexp)
+ (cl-pushnew (match-string-no-properties 1) res)))
+ (forward-sexp))
+ (scan-error nil)))
+ ((unless functions-p
+ (looking-at company-elisp-var-binding-regexp-1))
+ (down-list 1)
+ (when (looking-at regexp)
+ (cl-pushnew (match-string-no-properties 1) res)))))))))
+ (scan-error nil))
+ res))
+
+(defun company-elisp-candidates (prefix)
+ (let* ((predicate (company-elisp--candidates-predicate prefix))
+ (locals (company-elisp--locals prefix (eq predicate 'fboundp)))
+ (globals (company-elisp--globals prefix predicate))
+ (locals (cl-loop for local in locals
+ when (not (member local globals))
+ collect local)))
+ (if company-elisp-show-locals-first
+ (append (sort locals 'string<)
+ (sort globals 'string<))
+ (append locals globals))))
+
+(defun company-elisp--globals (prefix predicate)
+ (all-completions prefix obarray predicate))
+
+(defun company-elisp--candidates-predicate (prefix)
+ (let* ((completion-ignore-case nil)
+ (beg (- (point) (length prefix)))
+ (before (char-before beg)))
+ (if (and company-elisp-detect-function-context
+ (not (memq before '(?' ?`))))
+ (if (and (eq before ?\()
+ (not
+ (save-excursion
+ (ignore-errors
+ (goto-char (1- beg))
+ (or (company-elisp--before-binding-varlist-p)
+ (progn
+ (up-list -1)
+ (company-elisp--before-binding-varlist-p)))))))
+ 'fboundp
+ 'boundp)
+ 'company-elisp--predicate)))
+
+(defun company-elisp--before-binding-varlist-p ()
+ (save-excursion
+ (and (prog1 (search-backward "(")
+ (forward-char 1))
+ (looking-at company-elisp-var-binding-regexp))))
+
+(defun company-elisp--doc (symbol)
+ (let* ((symbol (intern symbol))
+ (doc (if (fboundp symbol)
+ (documentation symbol t)
+ (documentation-property symbol 'variable-documentation t))))
+ (and (stringp doc)
+ (string-match ".*$" doc)
+ (match-string 0 doc))))
+
+;;;###autoload
+(defun company-elisp (command &optional arg &rest ignored)
+ "`company-mode' completion backend for Emacs Lisp."
+ (interactive (list 'interactive))
+ (cl-case command
+ (interactive (company-begin-backend 'company-elisp))
+ (prefix (and (derived-mode-p 'emacs-lisp-mode 'inferior-emacs-lisp-mode)
+ (company-elisp--prefix)))
+ (candidates (company-elisp-candidates arg))
+ (sorted company-elisp-show-locals-first)
+ (meta (company-elisp--doc arg))
+ (doc-buffer (let ((symbol (intern arg)))
+ (save-window-excursion
+ (ignore-errors
+ (cond
+ ((fboundp symbol) (describe-function symbol))
+ ((boundp symbol) (describe-variable symbol))
+ ((featurep symbol) (describe-package symbol))
+ ((facep symbol) (describe-face symbol))
+ (t (signal 'user-error nil)))
+ (help-buffer)))))
+ (location (let ((sym (intern arg)))
+ (cond
+ ((fboundp sym) (find-definition-noselect sym nil))
+ ((boundp sym) (find-definition-noselect sym 'defvar))
+ ((featurep sym) (cons (find-file-noselect (find-library-name
+ (symbol-name sym)))
+ 0))
+ ((facep sym) (find-definition-noselect sym 'defface)))))))
+
+(provide 'company-elisp)
+;;; company-elisp.el ends here
diff --git a/elpa/company-20220425.1145/company-elisp.elc b/elpa/company-20220425.1145/company-elisp.elc
new file mode 100644
index 0000000..b30bb9d
--- /dev/null
+++ b/elpa/company-20220425.1145/company-elisp.elc
Binary files differ
diff --git a/elpa/company-20220425.1145/company-etags.el b/elpa/company-20220425.1145/company-etags.el
new file mode 100644
index 0000000..0bd093a
--- /dev/null
+++ b/elpa/company-20220425.1145/company-etags.el
@@ -0,0 +1,108 @@
+;;; company-etags.el --- company-mode completion backend for etags
+
+;; Copyright (C) 2009-2011, 2013-2015, 2018-2019 Free Software Foundation, Inc.
+
+;; Author: Nikolaj Schumacher
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs 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.
+
+;; GNU Emacs 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 GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
+
+
+;;; Commentary:
+;;
+
+;;; Code:
+
+(require 'company)
+(require 'cl-lib)
+(require 'etags)
+
+(defgroup company-etags nil
+ "Completion backend for etags."
+ :group 'company)
+
+(defcustom company-etags-use-main-table-list t
+ "Always search `tags-table-list' if set.
+If this is disabled, `company-etags' will try to find the one table for each
+buffer automatically."
+ :type '(choice (const :tag "off" nil)
+ (const :tag "on" t)))
+
+(defcustom company-etags-ignore-case nil
+ "Non-nil to ignore case in completion candidates."
+ :type 'boolean
+ :package-version '(company . "0.7.3"))
+
+(defcustom company-etags-everywhere nil
+ "Non-nil to offer completions in comments and strings.
+Set it to t or to a list of major modes."
+ :type '(choice (const :tag "Off" nil)
+ (const :tag "Any supported mode" t)
+ (repeat :tag "Some major modes"
+ (symbol :tag "Major mode")))
+ :package-version '(company . "0.9.0"))
+
+(defvar company-etags-modes '(prog-mode c-mode objc-mode c++-mode java-mode
+ jde-mode pascal-mode perl-mode python-mode))
+
+(defvar-local company-etags-buffer-table 'unknown)
+
+(defun company-etags-find-table ()
+ (let ((file (expand-file-name
+ "TAGS"
+ (locate-dominating-file (or buffer-file-name
+ default-directory)
+ "TAGS"))))
+ (when (and file (file-regular-p file))
+ (list file))))
+
+(defun company-etags-buffer-table ()
+ (or (and company-etags-use-main-table-list tags-table-list)
+ (if (eq company-etags-buffer-table 'unknown)
+ (setq company-etags-buffer-table (company-etags-find-table))
+ company-etags-buffer-table)))
+
+(defun company-etags--candidates (prefix)
+ (let ((tags-table-list (company-etags-buffer-table))
+ (tags-file-name tags-file-name)
+ (completion-ignore-case company-etags-ignore-case))
+ (and (or tags-file-name tags-table-list)
+ (fboundp 'tags-completion-table)
+ (save-excursion
+ (visit-tags-table-buffer)
+ (all-completions prefix (tags-completion-table))))))
+
+;;;###autoload
+(defun company-etags (command &optional arg &rest ignored)
+ "`company-mode' completion backend for etags."
+ (interactive (list 'interactive))
+ (cl-case command
+ (interactive (company-begin-backend 'company-etags))
+ (prefix (and (apply #'derived-mode-p company-etags-modes)
+ (or (eq t company-etags-everywhere)
+ (apply #'derived-mode-p company-etags-everywhere)
+ (not (company-in-string-or-comment)))
+ (company-etags-buffer-table)
+ (or (company-grab-symbol) 'stop)))
+ (candidates (company-etags--candidates arg))
+ (location (let ((tags-table-list (company-etags-buffer-table)))
+ (when (fboundp 'find-tag-noselect)
+ (save-excursion
+ (let ((buffer (find-tag-noselect arg)))
+ (cons buffer (with-current-buffer buffer (point))))))))
+ (ignore-case company-etags-ignore-case)))
+
+(provide 'company-etags)
+;;; company-etags.el ends here
diff --git a/elpa/company-20220425.1145/company-etags.elc b/elpa/company-20220425.1145/company-etags.elc
new file mode 100644
index 0000000..dfcf1e0
--- /dev/null
+++ b/elpa/company-20220425.1145/company-etags.elc
Binary files differ
diff --git a/elpa/company-20220425.1145/company-files.el b/elpa/company-20220425.1145/company-files.el
new file mode 100644
index 0000000..0eb6cfe
--- /dev/null
+++ b/elpa/company-20220425.1145/company-files.el
@@ -0,0 +1,161 @@
+;;; company-files.el --- company-mode completion backend for file names
+
+;; Copyright (C) 2009-2011, 2013-2021 Free Software Foundation, Inc.
+
+;; Author: Nikolaj Schumacher
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs 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.
+
+;; GNU Emacs 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 GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
+
+
+;;; Commentary:
+;;
+
+;;; Code:
+
+(require 'company)
+(require 'cl-lib)
+
+(defgroup company-files nil
+ "Completion backend for file names."
+ :group 'company)
+
+(defcustom company-files-exclusions nil
+ "A list of file name extensions and directory names to ignore.
+The values should use the same format as `completion-ignored-extensions'."
+ :type '(repeat (string :tag "File extension or directory name"))
+ :package-version '(company . "0.9.1"))
+
+(defcustom company-files-chop-trailing-slash t
+ "Non-nil to remove the trailing slash after inserting directory name.
+
+This way it's easy to continue completion by typing `/' again.
+
+Set this to nil to disable that behavior."
+ :type 'boolean)
+
+(defun company-files--directory-files (dir prefix)
+ ;; Don't use directory-files. It produces directories without trailing /.
+ (condition-case err
+ (let ((comp (sort (file-name-all-completions prefix dir)
+ (lambda (s1 s2) (string-lessp (downcase s1) (downcase s2))))))
+ (when company-files-exclusions
+ (setq comp (company-files--exclusions-filtered comp)))
+ (if (equal prefix "")
+ (delete "../" (delete "./" comp))
+ comp))
+ (file-error nil)))
+
+(defun company-files--exclusions-filtered (completions)
+ (let* ((dir-exclusions (cl-remove-if-not #'company-files--trailing-slash-p
+ company-files-exclusions))
+ (file-exclusions (cl-set-difference company-files-exclusions
+ dir-exclusions)))
+ (cl-loop for c in completions
+ unless (if (company-files--trailing-slash-p c)
+ (member c dir-exclusions)
+ (cl-find-if (lambda (exclusion)
+ (string-suffix-p exclusion c))
+ file-exclusions))
+ collect c)))
+
+(defvar company-files--regexps
+ (let* ((root (if (eq system-type 'windows-nt)
+ "[a-zA-Z]:/"
+ "/"))
+ (begin (concat "\\(?:\\.\\{1,2\\}/\\|~/\\|" root "\\)")))
+ (list (concat "\"\\(" begin "[^\"\n]*\\)")
+ (concat "\'\\(" begin "[^\'\n]*\\)")
+ (concat "\\(?:[ \t=\[]\\|^\\)\\(" begin "[^ \t\n]*\\)"))))
+
+(defun company-files--grab-existing-name ()
+ ;; Grab the file name.
+ ;; When surrounded with quotes, it can include spaces.
+ (let (file dir)
+ (and (cl-dolist (regexp company-files--regexps)
+ (when (setq file (company-grab-line regexp 1))
+ (cl-return file)))
+ (company-files--connected-p file)
+ (setq dir (file-name-directory file))
+ (not (string-match "//" dir))
+ (file-exists-p dir)
+ file)))
+
+(defun company-files--connected-p (file)
+ (or (not (file-remote-p file))
+ (file-remote-p file nil t)))
+
+(defun company-files--trailing-slash-p (file)
+ ;; `file-directory-p' is very expensive on remotes. We are relying on
+ ;; `file-name-all-completions' returning directories with trailing / instead.
+ (let ((len (length file)))
+ (and (> len 0) (eq (aref file (1- len)) ?/))))
+
+(defvar company-files--completion-cache nil)
+
+(defun company-files--complete (prefix)
+ (let* ((dir (file-name-directory prefix))
+ (file (file-name-nondirectory prefix))
+ (key (list file
+ (expand-file-name dir)
+ (nth 5 (file-attributes dir))))
+ (completion-ignore-case read-file-name-completion-ignore-case))
+ (unless (company-file--keys-match-p key (car company-files--completion-cache))
+ (let* ((candidates (mapcar (lambda (f) (concat dir f))
+ (company-files--directory-files dir file)))
+ (directories (unless (file-remote-p dir)
+ (cl-remove-if-not (lambda (f)
+ (and (company-files--trailing-slash-p f)
+ (not (file-remote-p f))
+ (company-files--connected-p f)))
+ candidates)))
+ (children (and directories
+ (cl-mapcan (lambda (d)
+ (mapcar (lambda (c) (concat d c))
+ (company-files--directory-files d "")))
+ directories))))
+ (setq company-files--completion-cache
+ (cons key (append candidates children)))))
+ (all-completions prefix
+ (cdr company-files--completion-cache))))
+
+(defun company-file--keys-match-p (new old)
+ (and (equal (cdr old) (cdr new))
+ (string-prefix-p (car old) (car new))))
+
+(defun company-files--post-completion (arg)
+ (when (and company-files-chop-trailing-slash
+ (company-files--trailing-slash-p arg))
+ (delete-char -1)))
+
+;;;###autoload
+(defun company-files (command &optional arg &rest ignored)
+ "`company-mode' completion backend existing file names.
+Completions works for proper absolute and relative files paths.
+File paths with spaces are only supported inside strings."
+ (interactive (list 'interactive))
+ (cl-case command
+ (interactive (company-begin-backend 'company-files))
+ (prefix (company-files--grab-existing-name))
+ (candidates (company-files--complete arg))
+ (location (cons (dired-noselect
+ (file-name-directory (directory-file-name arg))) 1))
+ (post-completion (company-files--post-completion arg))
+ (kind (if (string-suffix-p "/" arg) 'folder 'file))
+ (sorted t)
+ (no-cache t)))
+
+(provide 'company-files)
+;;; company-files.el ends here
diff --git a/elpa/company-20220425.1145/company-files.elc b/elpa/company-20220425.1145/company-files.elc
new file mode 100644
index 0000000..9fbbc3a
--- /dev/null
+++ b/elpa/company-20220425.1145/company-files.elc
Binary files differ
diff --git a/elpa/company-20220425.1145/company-gtags.el b/elpa/company-20220425.1145/company-gtags.el
new file mode 100644
index 0000000..8c08c83
--- /dev/null
+++ b/elpa/company-20220425.1145/company-gtags.el
@@ -0,0 +1,161 @@
+;;; company-gtags.el --- company-mode completion backend for GNU Global
+
+;; Copyright (C) 2009-2011, 2013-2021 Free Software Foundation, Inc.
+
+;; Author: Nikolaj Schumacher
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs 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.
+
+;; GNU Emacs 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 GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
+
+
+;;; Commentary:
+;;
+
+;;; Code:
+
+(require 'company)
+(require 'company-template)
+(require 'cl-lib)
+
+(defgroup company-gtags nil
+ "Completion backend for GNU Global."
+ :group 'company)
+
+(define-obsolete-variable-alias
+ 'company-gtags-gnu-global-program-name
+ 'company-gtags-executable "earlier")
+
+(defcustom company-gtags-executable
+ (executable-find "global")
+ "Location of GNU global executable."
+ :type 'string)
+
+(defcustom company-gtags-insert-arguments t
+ "When non-nil, insert function arguments as a template after completion."
+ :type 'boolean
+ :package-version '(company . "0.8.1"))
+
+(defvar-local company-gtags--tags-available-p 'unknown)
+(defvar-local company-gtags--executable 'unknown)
+
+(defcustom company-gtags-modes '(prog-mode jde-mode)
+ "Modes that use `company-gtags'.
+In all these modes (and their derivatives) `company-gtags' will perform
+completion."
+ :type '(repeat (symbol :tag "Major mode"))
+ :package-version '(company . "0.8.4"))
+
+(defun company-gtags--tags-available-p ()
+ (if (eq company-gtags--tags-available-p 'unknown)
+ (setq company-gtags--tags-available-p
+ (locate-dominating-file buffer-file-name "GTAGS"))
+ company-gtags--tags-available-p))
+
+;; Avoid byte-compilation warnings on Emacs < 27.
+(declare-function with-connection-local-variables "files-x")
+(declare-function connection-local-set-profile-variables "files-x")
+(declare-function connection-local-set-profiles "files-x")
+
+(defun company-gtags--executable ()
+ (cond
+ ((not (eq company-gtags--executable 'unknown)) ;; the value is already cached
+ company-gtags--executable)
+ ((and (version<= "27" emacs-version) ;; can search remotely to set
+ (file-remote-p default-directory))
+
+ (with-connection-local-variables
+ (if (boundp 'company-gtags--executable-connection)
+ (setq-local company-gtags--executable ;; use if defined as connection-local
+ company-gtags--executable-connection)
+
+ ;; Else search and set as connection local for next uses.
+ (setq-local company-gtags--executable
+ (with-no-warnings (executable-find "global" t)))
+ (let* ((host (file-remote-p default-directory 'host))
+ (symvars (intern (concat host "-vars")))) ;; profile name
+
+ (connection-local-set-profile-variables
+ symvars
+ `((company-gtags--executable-connection . ,company-gtags--executable)))
+
+ (connection-local-set-profiles `(:machine ,host) symvars))
+ company-gtags--executable)))
+ (t ;; use default value (searched locally)
+ company-gtags-executable)))
+
+(defun company-gtags--fetch-tags (prefix)
+ (with-temp-buffer
+ (let (tags)
+ ;; For some reason Global v 6.6.3 is prone to returning exit status 1
+ ;; even on successful searches when '-T' is used.
+ (when (/= 3 (process-file (company-gtags--executable) nil
+ ;; "-T" goes through all the tag files listed in GTAGSLIBPATH
+ (list (current-buffer) nil) nil "-xGqT" (concat "^" prefix)))
+ (goto-char (point-min))
+ (cl-loop while
+ (re-search-forward (concat
+ "^"
+ "\\([^ ]*\\)" ;; completion
+ "[ \t]+\\([[:digit:]]+\\)" ;; linum
+ "[ \t]+\\([^ \t]+\\)" ;; file
+ "[ \t]+\\(.*\\)" ;; definition
+ "$"
+ ) nil t)
+ collect
+ (propertize (match-string 1)
+ 'meta (match-string 4)
+ 'location (cons (expand-file-name (match-string 3))
+ (string-to-number (match-string 2)))
+ ))))))
+
+(defun company-gtags--annotation (arg)
+ (let ((meta (get-text-property 0 'meta arg)))
+ (when (string-match (concat (regexp-quote arg) " *(") meta)
+ (with-temp-buffer
+ (let ((start (match-end 0)))
+ (insert meta)
+ (goto-char start)
+ (condition-case nil
+ (forward-sexp)
+ (scan-error
+ (goto-char (point-max))))
+ (buffer-substring-no-properties
+ start (point)))))))
+
+;;;###autoload
+(defun company-gtags (command &optional arg &rest ignored)
+ "`company-mode' completion backend for GNU Global."
+ (interactive (list 'interactive))
+ (cl-case command
+ (interactive (company-begin-backend 'company-gtags))
+ (prefix (and (company-gtags--executable)
+ buffer-file-name
+ (apply #'derived-mode-p company-gtags-modes)
+ (not (company-in-string-or-comment))
+ (company-gtags--tags-available-p)
+ (or (company-grab-symbol) 'stop)))
+ (candidates (company-gtags--fetch-tags arg))
+ (sorted t)
+ (duplicates t)
+ (annotation (company-gtags--annotation arg))
+ (meta (get-text-property 0 'meta arg))
+ (location (get-text-property 0 'location arg))
+ (post-completion (let ((anno (company-gtags--annotation arg)))
+ (when (and company-gtags-insert-arguments anno)
+ (insert anno)
+ (company-template-c-like-templatify anno))))))
+
+(provide 'company-gtags)
+;;; company-gtags.el ends here
diff --git a/elpa/company-20220425.1145/company-gtags.elc b/elpa/company-20220425.1145/company-gtags.elc
new file mode 100644
index 0000000..f1c0e7f
--- /dev/null
+++ b/elpa/company-20220425.1145/company-gtags.elc
Binary files differ
diff --git a/elpa/company-20220425.1145/company-ispell.el b/elpa/company-20220425.1145/company-ispell.el
new file mode 100644
index 0000000..3cb7c5d
--- /dev/null
+++ b/elpa/company-20220425.1145/company-ispell.el
@@ -0,0 +1,83 @@
+;;; company-ispell.el --- company-mode completion backend using Ispell
+
+;; Copyright (C) 2009-2011, 2013-2016, 2018, 2021 Free Software Foundation, Inc.
+
+;; Author: Nikolaj Schumacher
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs 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.
+
+;; GNU Emacs 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 GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
+
+
+;;; Commentary:
+;;
+
+;;; Code:
+
+(require 'company)
+(require 'cl-lib)
+(require 'ispell)
+
+(defgroup company-ispell nil
+ "Completion backend using Ispell."
+ :group 'company)
+
+(defcustom company-ispell-dictionary nil
+ "Dictionary to use for `company-ispell'.
+If nil, use `ispell-complete-word-dict'."
+ :type '(choice (const :tag "default (nil)" nil)
+ (file :tag "dictionary" t)))
+
+(defvar company-ispell-available 'unknown)
+
+(defalias 'company-ispell--lookup-words
+ (if (fboundp 'ispell-lookup-words)
+ 'ispell-lookup-words
+ 'lookup-words))
+
+(defun company-ispell-available ()
+ (when (eq company-ispell-available 'unknown)
+ (condition-case err
+ (progn
+ (company-ispell--lookup-words "WHATEVER")
+ (setq company-ispell-available t))
+ (error
+ (message "Company-Ispell: %s" (error-message-string err))
+ (setq company-ispell-available nil))))
+ company-ispell-available)
+
+;;;###autoload
+(defun company-ispell (command &optional arg &rest ignored)
+ "`company-mode' completion backend using Ispell."
+ (interactive (list 'interactive))
+ (cl-case command
+ (interactive (company-begin-backend 'company-ispell))
+ (prefix (when (company-ispell-available)
+ (company-grab-word)))
+ (candidates
+ (let ((words (company-ispell--lookup-words
+ arg
+ (or company-ispell-dictionary ispell-complete-word-dict)))
+ (completion-ignore-case t))
+ (if (string= arg "")
+ ;; Small optimization.
+ words
+ ;; Work around issue #284.
+ (all-completions arg words))))
+ (kind 'text)
+ (sorted t)
+ (ignore-case 'keep-prefix)))
+
+(provide 'company-ispell)
+;;; company-ispell.el ends here
diff --git a/elpa/company-20220425.1145/company-ispell.elc b/elpa/company-20220425.1145/company-ispell.elc
new file mode 100644
index 0000000..44d058a
--- /dev/null
+++ b/elpa/company-20220425.1145/company-ispell.elc
Binary files differ
diff --git a/elpa/company-20220425.1145/company-keywords.el b/elpa/company-20220425.1145/company-keywords.el
new file mode 100644
index 0000000..0065afb
--- /dev/null
+++ b/elpa/company-20220425.1145/company-keywords.el
@@ -0,0 +1,354 @@
+;;; company-keywords.el --- A company backend for programming language keywords
+
+;; Copyright (C) 2009-2011, 2013-2018, 2020-2021 Free Software Foundation, Inc.
+
+;; Author: Nikolaj Schumacher
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs 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.
+
+;; GNU Emacs 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 GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
+
+
+;;; Commentary:
+;;
+
+;;; Code:
+
+(require 'company)
+(require 'cl-lib)
+(eval-when-compile (require 'make-mode))
+
+(defgroup company-keywords nil
+ "Completion backend for keywords."
+ :group 'company)
+
+(defcustom company-keywords-ignore-case nil
+ "Non-nil to ignore case in completion candidates."
+ :type 'boolean)
+
+(defun company-keywords-upper-lower (&rest lst)
+ ;; Upcase order is different for _.
+ (nconc (sort (mapcar 'upcase lst) 'string<) lst))
+
+(defvar company-keywords-alist
+ ;; Please contribute corrections or additions.
+ `((c++-mode
+ ;; from https://en.cppreference.com/w/cpp/keyword
+ "alignas" "alignof" "and" "and_eq" "asm" "atomic_cancel" "atomic_commit"
+ "atomic_noexcept" "auto" "bitand" "bitor" "bool" "break" "case" "catch"
+ "char" "char16_t" "char32_t" "char8_t" "class" "co_await" "co_return"
+ "co_yield" "compl" "concept" "const" "const_cast" "consteval" "constexpr"
+ "constinit" "continue" "decltype" "default" "delete" "do" "double"
+ "dynamic_cast" "else" "enum" "explicit" "export" "extern" "false" "final"
+ "float" "for" "friend" "goto" "if" "import" "inline" "int" "long" "module"
+ "mutable" "namespace" "new" "noexcept" "not" "not_eq" "nullptr" "operator"
+ "or" "or_eq" "override" "private" "protected" "public" "reflexpr" "register"
+ "reinterpret_cast" "requires" "return" "short" "signed" "sizeof" "static"
+ "static_assert" "static_cast" "struct" "switch" "synchronized" "template"
+ "this" "thread_local" "throw" "true" "try" "typedef" "typeid" "typename"
+ "union" "unsigned" "using" "virtual" "void" "volatile" "wchar_t" "while"
+ "xor" "xor_eq")
+ (c-mode
+ ;; from https://en.cppreference.com/w/c/keyword
+ "_Alignas" "_Alignof" "_Atomic" "_Bool" "_Complex" "_Generic" "_Imaginary"
+ "_Noreturn" "_Static_assert" "_Thread_local"
+ "auto" "break" "case" "char" "const" "continue" "default" "do"
+ "double" "else" "enum" "extern" "float" "for" "goto" "if" "inline"
+ "int" "long" "register" "restrict" "return" "short" "signed" "sizeof"
+ "static" "struct" "switch" "typedef" "union" "unsigned" "void" "volatile"
+ "while")
+ (csharp-mode
+ "abstract" "add" "alias" "as" "base" "bool" "break" "byte" "case"
+ "catch" "char" "checked" "class" "const" "continue" "decimal" "default"
+ "delegate" "do" "double" "else" "enum" "event" "explicit" "extern"
+ "false" "finally" "fixed" "float" "for" "foreach" "get" "global" "goto"
+ "if" "implicit" "in" "int" "interface" "internal" "is" "lock" "long"
+ "namespace" "new" "null" "object" "operator" "out" "override" "params"
+ "partial" "private" "protected" "public" "readonly" "ref" "remove"
+ "return" "sbyte" "sealed" "set" "short" "sizeof" "stackalloc" "static"
+ "string" "struct" "switch" "this" "throw" "true" "try" "typeof" "uint"
+ "ulong" "unchecked" "unsafe" "ushort" "using" "value" "var" "virtual"
+ "void" "volatile" "where" "while" "yield")
+ (d-mode
+ ;; from http://www.digitalmars.com/d/2.0/lex.html
+ "abstract" "alias" "align" "asm"
+ "assert" "auto" "body" "bool" "break" "byte" "case" "cast" "catch"
+ "cdouble" "cent" "cfloat" "char" "class" "const" "continue" "creal"
+ "dchar" "debug" "default" "delegate" "delete" "deprecated" "do"
+ "double" "else" "enum" "export" "extern" "false" "final" "finally"
+ "float" "for" "foreach" "foreach_reverse" "function" "goto" "idouble"
+ "if" "ifloat" "import" "in" "inout" "int" "interface" "invariant"
+ "ireal" "is" "lazy" "long" "macro" "mixin" "module" "new" "nothrow"
+ "null" "out" "override" "package" "pragma" "private" "protected"
+ "public" "pure" "real" "ref" "return" "scope" "short" "static" "struct"
+ "super" "switch" "synchronized" "template" "this" "throw" "true" "try"
+ "typedef" "typeid" "typeof" "ubyte" "ucent" "uint" "ulong" "union"
+ "unittest" "ushort" "version" "void" "volatile" "wchar" "while" "with")
+ (f90-mode .
+ ;; from f90.el
+ ;; ".AND." ".GE." ".GT." ".LT." ".LE." ".NE." ".OR." ".TRUE." ".FALSE."
+ ,(company-keywords-upper-lower
+ "abs" "abstract" "achar" "acos" "adjustl" "adjustr" "aimag" "aint"
+ "align" "all" "all_prefix" "all_scatter" "all_suffix" "allocatable"
+ "allocate" "allocated" "and" "anint" "any" "any_prefix" "any_scatter"
+ "any_suffix" "asin" "assign" "assignment" "associate" "associated"
+ "asynchronous" "atan" "atan2" "backspace" "bind" "bit_size" "block"
+ "btest" "c_alert" "c_associated" "c_backspace" "c_bool"
+ "c_carriage_return" "c_char" "c_double" "c_double_complex" "c_f_pointer"
+ "c_f_procpointer" "c_float" "c_float_complex" "c_form_feed" "c_funloc"
+ "c_funptr" "c_horizontal_tab" "c_int" "c_int16_t" "c_int32_t" "c_int64_t"
+ "c_int8_t" "c_int_fast16_t" "c_int_fast32_t" "c_int_fast64_t"
+ "c_int_fast8_t" "c_int_least16_t" "c_int_least32_t" "c_int_least64_t"
+ "c_int_least8_t" "c_intmax_t" "c_intptr_t" "c_loc" "c_long"
+ "c_long_double" "c_long_double_complex" "c_long_long" "c_new_line"
+ "c_null_char" "c_null_funptr" "c_null_ptr" "c_ptr" "c_short"
+ "c_signed_char" "c_size_t" "c_vertical_tab" "call" "case" "ceiling"
+ "char" "character" "character_storage_size" "class" "close" "cmplx"
+ "command_argument_count" "common" "complex" "conjg" "contains" "continue"
+ "copy_prefix" "copy_scatter" "copy_suffix" "cos" "cosh" "count"
+ "count_prefix" "count_scatter" "count_suffix" "cpu_time" "cshift"
+ "cycle" "cyclic" "data" "date_and_time" "dble" "deallocate" "deferred"
+ "digits" "dim" "dimension" "distribute" "do" "dot_product" "double"
+ "dprod" "dynamic" "elemental" "else" "elseif" "elsewhere" "end" "enddo"
+ "endfile" "endif" "entry" "enum" "enumerator" "eoshift" "epsilon" "eq"
+ "equivalence" "eqv" "error_unit" "exit" "exp" "exponent" "extends"
+ "extends_type_of" "external" "extrinsic" "false" "file_storage_size"
+ "final" "floor" "flush" "forall" "format" "fraction" "function" "ge"
+ "generic" "get_command" "get_command_argument" "get_environment_variable"
+ "goto" "grade_down" "grade_up" "gt" "hpf_alignment" "hpf_distribution"
+ "hpf_template" "huge" "iachar" "iall" "iall_prefix" "iall_scatter"
+ "iall_suffix" "iand" "iany" "iany_prefix" "iany_scatter" "iany_suffix"
+ "ibclr" "ibits" "ibset" "ichar" "ieee_arithmetic" "ieee_exceptions"
+ "ieee_features" "ieee_get_underflow_mode" "ieee_set_underflow_mode"
+ "ieee_support_underflow_control" "ieor" "if" "ilen" "implicit"
+ "import" "include" "independent" "index" "inherit" "input_unit"
+ "inquire" "int" "integer" "intent" "interface" "intrinsic" "ior"
+ "iostat_end" "iostat_eor" "iparity" "iparity_prefix" "iparity_scatter"
+ "iparity_suffix" "ishft" "ishftc" "iso_c_binding" "iso_fortran_env"
+ "kind" "lbound" "le" "leadz" "len" "len_trim" "lge" "lgt" "lle" "llt"
+ "log" "log10" "logical" "lt" "matmul" "max" "maxexponent" "maxloc"
+ "maxval" "maxval_prefix" "maxval_scatter" "maxval_suffix" "merge"
+ "min" "minexponent" "minloc" "minval" "minval_prefix" "minval_scatter"
+ "minval_suffix" "mod" "module" "modulo" "move_alloc" "mvbits" "namelist"
+ "ne" "nearest" "neqv" "new" "new_line" "nint" "non_intrinsic"
+ "non_overridable" "none" "nopass" "not" "null" "nullify"
+ "number_of_processors" "numeric_storage_size" "only" "onto" "open"
+ "operator" "optional" "or" "output_unit" "pack" "parameter" "parity"
+ "parity_prefix" "parity_scatter" "parity_suffix" "pass" "pause"
+ "pointer" "popcnt" "poppar" "precision" "present" "print" "private"
+ "procedure" "processors" "processors_shape" "product" "product_prefix"
+ "product_scatter" "product_suffix" "program" "protected" "public"
+ "pure" "radix" "random_number" "random_seed" "range" "read" "real"
+ "realign" "recursive" "redistribute" "repeat" "reshape" "result"
+ "return" "rewind" "rrspacing" "same_type_as" "save" "scale" "scan"
+ "select" "selected_char_kind" "selected_int_kind" "selected_real_kind"
+ "sequence" "set_exponent" "shape" "sign" "sin" "sinh" "size" "spacing"
+ "spread" "sqrt" "stop" "subroutine" "sum" "sum_prefix" "sum_scatter"
+ "sum_suffix" "system_clock" "tan" "tanh" "target" "template" "then"
+ "tiny" "transfer" "transpose" "trim" "true" "type" "ubound" "unpack"
+ "use" "value" "verify" "volatile" "wait" "where" "while" "with" "write"))
+ (go-mode
+ ;; 1. Keywords ref: https://golang.org/ref/spec#Keywords
+ ;; 2. Builtin functions and types ref: https://golang.org/pkg/builtin/
+ "append" "bool" "break" "byte" "cap" "case" "chan" "close" "complex" "complex128"
+ "complex64" "const" "continue" "copy" "default" "defer" "delete" "else" "error"
+ "fallthrough" "false" "float32" "float64" "for" "func" "go" "goto" "if" "imag"
+ "import" "int" "int16" "int32" "int64" "int8" "interface" "len" "make"
+ "map" "new" "nil" "package" "panic" "print" "println" "range" "real" "recover"
+ "return" "rune" "select" "string" "struct" "switch" "true" "type" "uint" "uint16"
+ "uint32" "uint64" "uint8" "uintptr" "var")
+ (java-mode
+ "abstract" "assert" "boolean" "break" "byte" "case" "catch" "char" "class"
+ "continue" "default" "do" "double" "else" "enum" "extends" "final"
+ "finally" "float" "for" "if" "implements" "import" "instanceof" "int"
+ "interface" "long" "native" "new" "package" "private" "protected" "public"
+ "return" "short" "static" "strictfp" "super" "switch" "synchronized"
+ "this" "throw" "throws" "transient" "try" "void" "volatile" "while")
+ (javascript-mode
+ ;; https://tc39.github.io/ecma262/ + async, static and undefined
+ "async" "await" "break" "case" "catch" "class" "const" "continue"
+ "debugger" "default" "delete" "do" "else" "enum" "export" "extends" "false"
+ "finally" "for" "function" "if" "import" "in" "instanceof" "let" "new"
+ "null" "return" "static" "super" "switch" "this" "throw" "true" "try"
+ "typeof" "undefined" "var" "void" "while" "with" "yield")
+ (kotlin-mode
+ "abstract" "annotation" "as" "break" "by" "catch" "class" "companion"
+ "const" "constructor" "continue" "data" "do" "else" "enum" "false" "final"
+ "finally" "for" "fun" "if" "import" "in" "init" "inner" "interface"
+ "internal" "is" "lateinit" "nested" "null" "object" "open" "out" "override"
+ "package" "private" "protected" "public" "return" "super" "this" "throw"
+ "trait" "true" "try" "typealias" "val" "var" "when" "while")
+ (lua-mode
+ ;; https://www.lua.org/manual/5.3/manual.html
+ "and" "break" "do" "else" "elseif" "end" "false" "for" "function" "goto" "if"
+ "in" "local" "nil" "not" "or" "repeat" "return" "then" "true" "until" "while")
+ (objc-mode
+ "@catch" "@class" "@encode" "@end" "@finally" "@implementation"
+ "@interface" "@private" "@protected" "@protocol" "@public"
+ "@selector" "@synchronized" "@throw" "@try" "alloc" "autorelease"
+ "bycopy" "byref" "in" "inout" "oneway" "out" "release" "retain")
+ (perl-mode
+ ;; from cperl.el
+ "AUTOLOAD" "BEGIN" "CHECK" "CORE" "DESTROY" "END" "INIT" "__END__"
+ "__FILE__" "__LINE__" "abs" "accept" "alarm" "and" "atan2" "bind"
+ "binmode" "bless" "caller" "chdir" "chmod" "chomp" "chop" "chown" "chr"
+ "chroot" "close" "closedir" "cmp" "connect" "continue" "cos"
+ "crypt" "dbmclose" "dbmopen" "defined" "delete" "die" "do" "dump" "each"
+ "else" "elsif" "endgrent" "endhostent" "endnetent" "endprotoent"
+ "endpwent" "endservent" "eof" "eq" "eval" "exec" "exists" "exit" "exp"
+ "fcntl" "fileno" "flock" "for" "foreach" "fork" "format" "formline"
+ "ge" "getc" "getgrent" "getgrgid" "getgrnam" "gethostbyaddr"
+ "gethostbyname" "gethostent" "getlogin" "getnetbyaddr" "getnetbyname"
+ "getnetent" "getpeername" "getpgrp" "getppid" "getpriority"
+ "getprotobyname" "getprotobynumber" "getprotoent" "getpwent" "getpwnam"
+ "getpwuid" "getservbyname" "getservbyport" "getservent" "getsockname"
+ "getsockopt" "glob" "gmtime" "goto" "grep" "gt" "hex" "if" "index" "int"
+ "ioctl" "join" "keys" "kill" "last" "lc" "lcfirst" "le" "length"
+ "link" "listen" "local" "localtime" "lock" "log" "lstat" "lt" "map"
+ "mkdir" "msgctl" "msgget" "msgrcv" "msgsnd" "my" "ne" "next" "no"
+ "not" "oct" "open" "opendir" "or" "ord" "our" "pack" "package" "pipe"
+ "pop" "pos" "print" "printf" "push" "q" "qq" "quotemeta" "qw" "qx"
+ "rand" "read" "readdir" "readline" "readlink" "readpipe" "recv" "redo"
+ "ref" "rename" "require" "reset" "return" "reverse" "rewinddir" "rindex"
+ "rmdir" "scalar" "seek" "seekdir" "select" "semctl" "semget" "semop"
+ "send" "setgrent" "sethostent" "setnetent" "setpgrp" "setpriority"
+ "setprotoent" "setpwent" "setservent" "setsockopt" "shift" "shmctl"
+ "shmget" "shmread" "shmwrite" "shutdown" "sin" "sleep" "socket"
+ "socketpair" "sort" "splice" "split" "sprintf" "sqrt" "srand" "stat"
+ "study" "sub" "substr" "symlink" "syscall" "sysopen" "sysread" "system"
+ "syswrite" "tell" "telldir" "tie" "time" "times" "tr" "truncate" "uc"
+ "ucfirst" "umask" "undef" "unless" "unlink" "unpack" "unshift" "untie"
+ "until" "use" "utime" "values" "vec" "wait" "waitpid"
+ "wantarray" "warn" "while" "write" "x" "xor" "y")
+ (php-mode ;; https://www.php.net/manual/reserved.php
+ "Closure" "Error" "Exception" "Generator" "Throwable"
+ "__CLASS__" "__DIR__" "__FILE__" "__FUNCTION__" "__LINE__" "__METHOD__"
+ "__NAMESPACE__" "__TRAIT__"
+ "abstract" "and" "array" "as" "bool" "break" "callable" "case" "catch"
+ "class" "clone" "const" "continue" "declare" "default" "die" "do" "echo"
+ "else" "elseif" "empty" "enddeclare" "endfor" "endforeach" "endif"
+ "endswitch" "endwhile" "enum" "eval" "exit" "extends" "false" "final" "finally"
+ "float" "fn" "for" "foreach" "function" "global" "goto" "if"
+ "implements" "include" "include_once" "instanceof" "insteadof" "interface"
+ "isset" "iterable" "list" "match" "namespace" "new" "null" "object" "or"
+ "print" "private" "protected" "public" "readonly" "require" "require_once"
+ "return" "self" "static" "string" "switch" "this" "throw" "trait" "true"
+ "try" "unset" "use" "var" "void" "while" "xor" "yield" "yield from")
+ (python-mode
+ ;; https://docs.python.org/3/reference/lexical_analysis.html#keywords
+ "False" "None" "True" "and" "as" "assert" "break" "class" "continue" "def"
+ "del" "elif" "else" "except" "exec" "finally" "for" "from" "global" "if"
+ "import" "in" "is" "lambda" "nonlocal" "not" "or" "pass" "print" "raise"
+ "return" "try" "while" "with" "yield")
+ (ruby-mode
+ "BEGIN" "END" "alias" "and" "begin" "break" "case" "class" "def" "defined?"
+ "do" "else" "elsif" "end" "ensure" "false" "for" "if" "in" "module"
+ "next" "nil" "not" "or" "redo" "rescue" "retry" "return" "self" "super"
+ "then" "true" "undef" "unless" "until" "when" "while" "yield")
+ ;; From https://doc.rust-lang.org/grammar.html#keywords
+ ;; but excluding unused reserved words: https://www.reddit.com/r/rust/comments/34fq0k/is_there_a_good_list_of_rusts_keywords/cqucvnj
+ (rust-mode
+ "Self"
+ "as" "box" "break" "const" "continue" "crate" "else" "enum" "extern"
+ "false" "fn" "for" "if" "impl" "in" "let" "loop" "macro" "match" "mod"
+ "move" "mut" "pub" "ref" "return" "self" "static" "struct" "super"
+ "trait" "true" "type" "unsafe" "use" "where" "while")
+ (scala-mode
+ "abstract" "case" "catch" "class" "def" "do" "else" "extends" "false"
+ "final" "finally" "for" "forSome" "if" "implicit" "import" "lazy" "match"
+ "new" "null" "object" "override" "package" "private" "protected"
+ "return" "sealed" "super" "this" "throw" "trait" "true" "try" "type" "val"
+ "var" "while" "with" "yield")
+ (swift-mode
+ "Protocol" "Self" "Type" "and" "as" "assignment" "associatedtype"
+ "associativity" "available" "break" "case" "catch" "class" "column" "continue"
+ "convenience" "default" "defer" "deinit" "didSet" "do" "dynamic" "dynamicType"
+ "else" "elseif" "endif" "enum" "extension" "fallthrough" "false" "file"
+ "fileprivate" "final" "for" "func" "function" "get" "guard" "higherThan" "if"
+ "import" "in" "indirect" "infix" "init" "inout" "internal" "is" "lazy" "left"
+ "let" "line" "lowerThan" "mutating" "nil" "none" "nonmutating" "open"
+ "operator" "optional" "override" "postfix" "precedence" "precedencegroup"
+ "prefix" "private" "protocol" "public" "repeat" "required" "rethrows" "return"
+ "right" "selector" "self" "set" "static" "struct" "subscript" "super" "switch"
+ "throw" "throws" "true" "try" "typealias" "unowned" "var" "weak" "where"
+ "while" "willSet")
+ (julia-mode
+ "abstract" "break" "case" "catch" "const" "continue" "do" "else" "elseif"
+ "end" "eval" "export" "false" "finally" "for" "function" "global" "if"
+ "ifelse" "immutable" "import" "importall" "in" "let" "macro" "module"
+ "otherwise" "quote" "return" "switch" "throw" "true" "try" "type"
+ "typealias" "using" "while"
+ )
+ ;; From https://github.com/apache/thrift/blob/master/contrib/thrift.el
+ (thrift-mode
+ "binary" "bool" "byte" "const" "double" "enum" "exception" "extends"
+ "i16" "i32" "i64" "include" "list" "map" "oneway" "optional" "required"
+ "service" "set" "string" "struct" "throws" "typedef" "void"
+ )
+ ;; aliases
+ (js2-mode . javascript-mode)
+ (js2-jsx-mode . javascript-mode)
+ (espresso-mode . javascript-mode)
+ (js-mode . javascript-mode)
+ (js-jsx-mode . javascript-mode)
+ (rjsx-mode . javascript-mode)
+ (cperl-mode . perl-mode)
+ (jde-mode . java-mode)
+ (ess-julia-mode . julia-mode)
+ (phps-mode . php-mode)
+ (enh-ruby-mode . ruby-mode))
+ "Alist mapping major-modes to sorted keywords for `company-keywords'.")
+
+(with-eval-after-load 'make-mode
+ (mapc
+ (lambda (mode-stmnts)
+ (setf (alist-get (car mode-stmnts) company-keywords-alist)
+ (cl-remove-duplicates
+ (sort (append makefile-special-targets-list
+ (cl-mapcan #'identity
+ (mapcar
+ #'split-string
+ (cl-remove-if-not
+ #'stringp
+ (symbol-value (cdr mode-stmnts))))))
+ #'string<)
+ :test #'string=)))
+ '((makefile-automake-mode . makefile-automake-statements)
+ (makefile-gmake-mode . makefile-gmake-statements)
+ (makefile-makepp-mode . makefile-makepp-statements)
+ (makefile-bsdmake-mode . makefile-bsdmake-statements)
+ (makefile-imake-mode . makefile-statements)
+ (makefile-mode . makefile-statements))))
+
+;;;###autoload
+(defun company-keywords (command &optional arg &rest ignored)
+ "`company-mode' backend for programming language keywords."
+ (interactive (list 'interactive))
+ (cl-case command
+ (interactive (company-begin-backend 'company-keywords))
+ (prefix (and (assq major-mode company-keywords-alist)
+ (not (company-in-string-or-comment))
+ (or (company-grab-symbol) 'stop)))
+ (candidates
+ (let ((completion-ignore-case company-keywords-ignore-case)
+ (symbols (cdr (assq major-mode company-keywords-alist))))
+ (all-completions arg (if (consp symbols)
+ symbols
+ (cdr (assq symbols company-keywords-alist))))))
+ (kind 'keyword)
+ (sorted t)
+ (ignore-case company-keywords-ignore-case)))
+
+(provide 'company-keywords)
+;;; company-keywords.el ends here
diff --git a/elpa/company-20220425.1145/company-keywords.elc b/elpa/company-20220425.1145/company-keywords.elc
new file mode 100644
index 0000000..26903f1
--- /dev/null
+++ b/elpa/company-20220425.1145/company-keywords.elc
Binary files differ
diff --git a/elpa/company-20220425.1145/company-nxml.el b/elpa/company-20220425.1145/company-nxml.el
new file mode 100644
index 0000000..c72685c
--- /dev/null
+++ b/elpa/company-20220425.1145/company-nxml.el
@@ -0,0 +1,143 @@
+;;; company-nxml.el --- company-mode completion backend for nxml-mode
+
+;; Copyright (C) 2009-2011, 2013-2015, 2017-2018 Free Software Foundation, Inc.
+
+;; Author: Nikolaj Schumacher
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs 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.
+
+;; GNU Emacs 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 GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
+
+
+;;; Commentary:
+;;
+;; In Emacs >= 26, company-capf is used instead.
+
+;;; Code:
+
+(require 'company)
+(require 'cl-lib)
+
+(defvar rng-open-elements)
+(defvar rng-validate-mode)
+(defvar rng-in-attribute-regex)
+(defvar rng-in-attribute-value-regex)
+(declare-function rng-set-state-after "rng-nxml")
+(declare-function rng-match-possible-start-tag-names "rng-match")
+(declare-function rng-adjust-state-for-attribute "rng-nxml")
+(declare-function rng-match-possible-attribute-names "rng-match")
+(declare-function rng-adjust-state-for-attribute-value "rng-nxml")
+(declare-function rng-match-possible-value-strings "rng-match")
+
+(defconst company-nxml-token-regexp
+ "\\(?:[_[:alpha:]][-._[:alnum:]]*\\_>\\)")
+
+(defvar company-nxml-in-attribute-value-regexp
+ (replace-regexp-in-string "w" company-nxml-token-regexp
+ "<w\\(?::w\\)?\
+\\(?:[ \t\r\n]+w\\(?::w\\)?[ \t\r\n]*=\
+\[ \t\r\n]*\\(?:\"[^\"]*\"\\|'[^']*'\\)\\)*\
+\[ \t\r\n]+\\(w\\(:w\\)?\\)[ \t\r\n]*=[ \t\r\n]*\
+\\(\"\\([^\"]*\\>\\)\\|'\\([^']*\\>\\)\\)\\="
+ t t))
+
+(defvar company-nxml-in-tag-name-regexp
+ (replace-regexp-in-string "w" company-nxml-token-regexp
+ "<\\(/?w\\(?::w?\\)?\\)?\\=" t t))
+
+(defun company-nxml-all-completions (prefix alist)
+ (let ((candidates (mapcar 'cdr alist))
+ (case-fold-search nil)
+ filtered)
+ (when (cdar rng-open-elements)
+ (push (concat "/" (cdar rng-open-elements)) candidates))
+ (setq candidates (sort (all-completions prefix candidates) 'string<))
+ (while candidates
+ (unless (equal (car candidates) (car filtered))
+ (push (car candidates) filtered))
+ (pop candidates))
+ (nreverse filtered)))
+
+(defmacro company-nxml-prepared (&rest body)
+ (declare (indent 0) (debug t))
+ `(let ((lt-pos (save-excursion (search-backward "<" nil t)))
+ xmltok-dtd)
+ (when (and lt-pos (= (rng-set-state-after lt-pos) lt-pos))
+ ,@body)))
+
+(defun company-nxml-tag (command &optional arg &rest ignored)
+ (cl-case command
+ (prefix (and (derived-mode-p 'nxml-mode)
+ rng-validate-mode
+ (company-grab company-nxml-in-tag-name-regexp 1)))
+ (candidates (company-nxml-prepared
+ (company-nxml-all-completions
+ arg (rng-match-possible-start-tag-names))))
+ (sorted t)))
+
+(defun company-nxml-attribute (command &optional arg &rest ignored)
+ (cl-case command
+ (prefix (and (derived-mode-p 'nxml-mode)
+ rng-validate-mode
+ (memq (char-after) '(?\ ?\t ?\n)) ;; outside word
+ (company-grab rng-in-attribute-regex 1)))
+ (candidates (company-nxml-prepared
+ (and (rng-adjust-state-for-attribute
+ lt-pos (- (point) (length arg)))
+ (company-nxml-all-completions
+ arg (rng-match-possible-attribute-names)))))
+ (sorted t)))
+
+(defun company-nxml-attribute-value (command &optional arg &rest ignored)
+ (cl-case command
+ (prefix (and (derived-mode-p 'nxml-mode)
+ rng-validate-mode
+ (and (memq (char-after) '(?' ?\" ?\ ?\t ?\n)) ;; outside word
+ (looking-back company-nxml-in-attribute-value-regexp nil)
+ (or (match-string-no-properties 4)
+ (match-string-no-properties 5)
+ ""))))
+ (candidates (company-nxml-prepared
+ (let (attr-start attr-end colon)
+ (and (looking-back rng-in-attribute-value-regex lt-pos)
+ (setq colon (match-beginning 2)
+ attr-start (match-beginning 1)
+ attr-end (match-end 1))
+ (rng-adjust-state-for-attribute lt-pos attr-start)
+ (rng-adjust-state-for-attribute-value
+ attr-start colon attr-end)
+ (all-completions
+ arg (rng-match-possible-value-strings))))))))
+
+;;;###autoload
+(defun company-nxml (command &optional arg &rest ignored)
+ "`company-mode' completion backend for `nxml-mode'."
+ (interactive (list 'interactive))
+ (cl-case command
+ (interactive (company-begin-backend 'company-nxml))
+ (prefix (or (company-nxml-tag 'prefix)
+ (company-nxml-attribute 'prefix)
+ (company-nxml-attribute-value 'prefix)))
+ (candidates (cond
+ ((company-nxml-tag 'prefix)
+ (company-nxml-tag 'candidates arg))
+ ((company-nxml-attribute 'prefix)
+ (company-nxml-attribute 'candidates arg))
+ ((company-nxml-attribute-value 'prefix)
+ (sort (company-nxml-attribute-value 'candidates arg)
+ 'string<))))
+ (sorted t)))
+
+(provide 'company-nxml)
+;;; company-nxml.el ends here
diff --git a/elpa/company-20220425.1145/company-nxml.elc b/elpa/company-20220425.1145/company-nxml.elc
new file mode 100644
index 0000000..5558bee
--- /dev/null
+++ b/elpa/company-20220425.1145/company-nxml.elc
Binary files differ
diff --git a/elpa/company-20220425.1145/company-oddmuse.el b/elpa/company-20220425.1145/company-oddmuse.el
new file mode 100644
index 0000000..5b9780b
--- /dev/null
+++ b/elpa/company-20220425.1145/company-oddmuse.el
@@ -0,0 +1,57 @@
+;;; company-oddmuse.el --- company-mode completion backend for oddmuse-mode
+
+;; Copyright (C) 2009-2011, 2013-2016 Free Software Foundation, Inc.
+
+;; Author: Nikolaj Schumacher
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs 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.
+
+;; GNU Emacs 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 GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
+
+
+;;; Commentary:
+;;
+
+;;; Code:
+
+(require 'company)
+(require 'cl-lib)
+(eval-when-compile (require 'yaoddmuse nil t))
+(eval-when-compile (require 'oddmuse nil t))
+
+(defvar company-oddmuse-link-regexp
+ "\\(\\<[A-Z][[:alnum:]]*\\>\\)\\|\\[\\[\\([[:alnum:]]+\\>\\|\\)")
+
+(defun company-oddmuse-get-page-table ()
+ (cl-case major-mode
+ (yaoddmuse-mode (with-no-warnings
+ (yaoddmuse-get-pagename-table yaoddmuse-wikiname)))
+ (oddmuse-mode (with-no-warnings
+ (oddmuse-make-completion-table oddmuse-wiki)))))
+
+;;;###autoload
+(defun company-oddmuse (command &optional arg &rest ignored)
+ "`company-mode' completion backend for `oddmuse-mode'."
+ (interactive (list 'interactive))
+ (cl-case command
+ (interactive (company-begin-backend 'company-oddmuse))
+ (prefix (let ((case-fold-search nil))
+ (and (memq major-mode '(oddmuse-mode yaoddmuse-mode))
+ (looking-back company-oddmuse-link-regexp (point-at-bol))
+ (or (match-string 1)
+ (match-string 2)))))
+ (candidates (all-completions arg (company-oddmuse-get-page-table)))))
+
+(provide 'company-oddmuse)
+;;; company-oddmuse.el ends here
diff --git a/elpa/company-20220425.1145/company-oddmuse.elc b/elpa/company-20220425.1145/company-oddmuse.elc
new file mode 100644
index 0000000..0c873a9
--- /dev/null
+++ b/elpa/company-20220425.1145/company-oddmuse.elc
Binary files differ
diff --git a/elpa/company-20220425.1145/company-pkg.el b/elpa/company-20220425.1145/company-pkg.el
new file mode 100644
index 0000000..b3d2554
--- /dev/null
+++ b/elpa/company-20220425.1145/company-pkg.el
@@ -0,0 +1,12 @@
+(define-package "company" "20220425.1145" "Modular text completion framework"
+ '((emacs "25.1"))
+ :commit "d5145006b948f93e673f439a766da01f636d39fc" :authors
+ '(("Nikolaj Schumacher"))
+ :maintainer
+ '("Dmitry Gutov" . "dgutov@yandex.ru")
+ :keywords
+ '("abbrev" "convenience" "matching")
+ :url "http://company-mode.github.io/")
+;; Local Variables:
+;; no-byte-compile: t
+;; End:
diff --git a/elpa/company-20220425.1145/company-semantic.el b/elpa/company-20220425.1145/company-semantic.el
new file mode 100644
index 0000000..cd56764
--- /dev/null
+++ b/elpa/company-20220425.1145/company-semantic.el
@@ -0,0 +1,168 @@
+;;; company-semantic.el --- company-mode completion backend using Semantic
+
+;; Copyright (C) 2009-2011, 2013-2018 Free Software Foundation, Inc.
+
+;; Author: Nikolaj Schumacher
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs 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.
+
+;; GNU Emacs 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 GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
+
+
+;;; Commentary:
+;;
+
+;;; Code:
+
+(require 'company)
+(require 'company-template)
+(require 'cl-lib)
+
+(defvar semantic-idle-summary-function)
+(declare-function semantic-documentation-for-tag "semantic/doc" )
+(declare-function semantic-analyze-current-context "semantic/analyze")
+(declare-function semantic-analyze-possible-completions "semantic/complete")
+(declare-function semantic-analyze-find-tags-by-prefix "semantic/analyze/fcn")
+(declare-function semantic-tag-class "semantic/tag")
+(declare-function semantic-tag-name "semantic/tag")
+(declare-function semantic-tag-start "semantic/tag")
+(declare-function semantic-tag-buffer "semantic/tag")
+(declare-function semantic-active-p "semantic")
+(declare-function semantic-format-tag-prototype "semantic/format")
+
+(defgroup company-semantic nil
+ "Completion backend using Semantic."
+ :group 'company)
+
+(defcustom company-semantic-metadata-function 'company-semantic-summary-and-doc
+ "The function turning a semantic tag into doc information."
+ :type 'function)
+
+(defcustom company-semantic-begin-after-member-access t
+ "When non-nil, automatic completion will start whenever the current
+symbol is preceded by \".\", \"->\" or \"::\", ignoring
+`company-minimum-prefix-length'.
+
+If `company-begin-commands' is a list, it should include `c-electric-lt-gt'
+and `c-electric-colon', for automatic completion right after \">\" and
+\":\"."
+ :type 'boolean)
+
+(defcustom company-semantic-insert-arguments t
+ "When non-nil, insert function arguments as a template after completion."
+ :type 'boolean
+ :package-version '(company . "0.9.0"))
+
+(defvar company-semantic-modes '(c-mode c++-mode jde-mode java-mode))
+
+(defvar-local company-semantic--current-tags nil
+ "Tags for the current context.")
+
+(defun company-semantic-documentation-for-tag (tag)
+ (when (semantic-tag-buffer tag)
+ ;; When TAG's buffer is unknown, the function below raises an error.
+ (semantic-documentation-for-tag tag)))
+
+(defun company-semantic-doc-or-summary (tag)
+ (or (company-semantic-documentation-for-tag tag)
+ (and (require 'semantic-idle nil t)
+ (require 'semantic/idle nil t)
+ (funcall semantic-idle-summary-function tag nil t))))
+
+(defun company-semantic-summary-and-doc (tag)
+ (let ((doc (company-semantic-documentation-for-tag tag))
+ (summary (funcall semantic-idle-summary-function tag nil t)))
+ (and (stringp doc)
+ (string-match "\n*\\(.*\\)$" doc)
+ (setq doc (match-string 1 doc)))
+ (concat summary
+ (when doc
+ (if (< (+ (length doc) (length summary) 4) (window-width))
+ " -- "
+ "\n"))
+ doc)))
+
+(defun company-semantic-doc-buffer (tag)
+ (let ((doc (company-semantic-documentation-for-tag tag)))
+ (when doc
+ (company-doc-buffer
+ (concat (funcall semantic-idle-summary-function tag nil t)
+ "\n"
+ doc)))))
+
+(defsubst company-semantic-completions (prefix)
+ (ignore-errors
+ (let ((completion-ignore-case nil)
+ (context (semantic-analyze-current-context)))
+ (setq company-semantic--current-tags
+ (semantic-analyze-possible-completions context 'no-unique))
+ (all-completions prefix company-semantic--current-tags))))
+
+(defun company-semantic-completions-raw (prefix)
+ (setq company-semantic--current-tags nil)
+ (dolist (tag (semantic-analyze-find-tags-by-prefix prefix))
+ (unless (eq (semantic-tag-class tag) 'include)
+ (push tag company-semantic--current-tags)))
+ (delete "" (mapcar 'semantic-tag-name company-semantic--current-tags)))
+
+(defun company-semantic-annotation (argument tags)
+ (let* ((tag (assq argument tags))
+ (kind (when tag (elt tag 1))))
+ (cl-case kind
+ (function (let* ((prototype (semantic-format-tag-prototype tag nil nil))
+ (par-pos (string-match "(" prototype)))
+ (when par-pos (substring prototype par-pos)))))))
+
+(defun company-semantic--prefix ()
+ (if company-semantic-begin-after-member-access
+ (company-grab-symbol-cons "\\.\\|->\\|::" 2)
+ (company-grab-symbol)))
+
+;;;###autoload
+(defun company-semantic (command &optional arg &rest ignored)
+ "`company-mode' completion backend using CEDET Semantic."
+ (interactive (list 'interactive))
+ (cl-case command
+ (interactive (company-begin-backend 'company-semantic))
+ (prefix (and (featurep 'semantic)
+ (semantic-active-p)
+ (memq major-mode company-semantic-modes)
+ (not (company-in-string-or-comment))
+ (or (company-semantic--prefix) 'stop)))
+ (candidates (if (and (equal arg "")
+ (not (looking-back "->\\|\\.\\|::" (- (point) 2))))
+ (company-semantic-completions-raw arg)
+ (company-semantic-completions arg)))
+ (meta (funcall company-semantic-metadata-function
+ (assoc arg company-semantic--current-tags)))
+ (annotation (company-semantic-annotation arg
+ company-semantic--current-tags))
+ (doc-buffer (company-semantic-doc-buffer
+ (assoc arg company-semantic--current-tags)))
+ ;; Because "" is an empty context and doesn't return local variables.
+ (no-cache (equal arg ""))
+ (duplicates t)
+ (location (let ((tag (assoc arg company-semantic--current-tags)))
+ (when (buffer-live-p (semantic-tag-buffer tag))
+ (cons (semantic-tag-buffer tag)
+ (semantic-tag-start tag)))))
+ (post-completion (let ((anno (company-semantic-annotation
+ arg company-semantic--current-tags)))
+ (when (and company-semantic-insert-arguments anno)
+ (insert anno)
+ (company-template-c-like-templatify (concat arg anno)))
+ ))))
+
+(provide 'company-semantic)
+;;; company-semantic.el ends here
diff --git a/elpa/company-20220425.1145/company-semantic.elc b/elpa/company-20220425.1145/company-semantic.elc
new file mode 100644
index 0000000..19db9d3
--- /dev/null
+++ b/elpa/company-20220425.1145/company-semantic.elc
Binary files differ
diff --git a/elpa/company-20220425.1145/company-template.el b/elpa/company-20220425.1145/company-template.el
new file mode 100644
index 0000000..57d5d48
--- /dev/null
+++ b/elpa/company-20220425.1145/company-template.el
@@ -0,0 +1,272 @@
+;;; company-template.el --- utility library for template expansion
+
+;; Copyright (C) 2009-2010, 2013-2017, 2019 Free Software Foundation, Inc.
+
+;; Author: Nikolaj Schumacher
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs 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.
+
+;; GNU Emacs 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 GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Code:
+
+(require 'cl-lib)
+
+(defface company-template-field
+ '((((background dark)) (:background "yellow" :foreground "black"))
+ (((background light)) (:background "orange" :foreground "black")))
+ "Face used for editable text in template fields."
+ :group 'company-faces)
+
+(defvar company-template-forward-field-item
+ '(menu-item "" company-template-forward-field
+ :filter company-template--keymap-filter))
+
+(defvar company-template-nav-map
+ (let ((keymap (make-sparse-keymap)))
+ (define-key keymap [tab] company-template-forward-field-item)
+ (define-key keymap (kbd "TAB") company-template-forward-field-item)
+ keymap))
+
+(defvar company-template-clear-field-item
+ '(menu-item "" company-template-clear-field
+ :filter company-template--keymap-filter))
+
+(defvar company-template-field-map
+ (let ((keymap (make-sparse-keymap)))
+ (set-keymap-parent keymap company-template-nav-map)
+ (define-key keymap (kbd "C-d") company-template-clear-field-item)
+ keymap))
+
+(defvar-local company-template--buffer-templates nil)
+
+;; interactive ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defun company-template-templates-at (pos)
+ (let (os)
+ (dolist (o (overlays-at pos))
+ ;; FIXME: Always return the whole list of templates?
+ ;; We remove templates not at point after every command.
+ (when (memq o company-template--buffer-templates)
+ (push o os)))
+ os))
+
+(defun company-template-move-to-first (templ)
+ (interactive)
+ (goto-char (overlay-start templ))
+ (company-template-forward-field))
+
+(defun company-template-forward-field ()
+ (interactive)
+ (let ((start (point))
+ (next-field-start (company-template-find-next-field)))
+ (push-mark)
+ (goto-char next-field-start)
+ (company-template-remove-field (company-template-field-at start))))
+
+(defun company-template-clear-field ()
+ "Clear the field at point."
+ (interactive)
+ (let ((ovl (company-template-field-at (point))))
+ (when ovl
+ (company-template-remove-field ovl t)
+ (let ((after-clear-fn
+ (overlay-get ovl 'company-template-after-clear)))
+ (when (functionp after-clear-fn)
+ (funcall after-clear-fn))))))
+
+(defun company-template--keymap-filter (cmd)
+ (unless (run-hook-with-args-until-success 'yas-keymap-disable-hook)
+ cmd))
+
+(defun company-template--after-clear-c-like-field ()
+ "Function that can be called after deleting a field of a c-like template.
+For c-like templates it is set as `after-post-fn' property on fields in
+`company-template-add-field'. If there is a next field, delete everything
+from point to it. If there is no field after point, remove preceding comma
+if present."
+ (let* ((pos (point))
+ (next-field-start (company-template-find-next-field))
+ (last-field-p (not (company-template-field-at next-field-start))))
+ (cond ((and (not last-field-p)
+ (< pos next-field-start)
+ (string-match "^[ ]*,+[ ]*$" (buffer-substring-no-properties
+ pos next-field-start)))
+ (delete-region pos next-field-start))
+ ((and last-field-p
+ (looking-back ",+[ ]*" (line-beginning-position)))
+ (delete-region (match-beginning 0) pos)))))
+
+(defun company-template-find-next-field ()
+ (let* ((start (point))
+ (templates (company-template-templates-at start))
+ (minimum (apply 'max (mapcar 'overlay-end templates)))
+ (fields (cl-loop for templ in templates
+ append (overlay-get templ 'company-template-fields))))
+ (dolist (pos (mapcar 'overlay-start fields) minimum)
+ (and pos
+ (> pos start)
+ (< pos minimum)
+ (setq minimum pos)))))
+
+(defun company-template-field-at (&optional point)
+ (cl-loop for ovl in (overlays-at (or point (point)))
+ when (overlay-get ovl 'company-template-parent)
+ return ovl))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defun company-template-declare-template (beg end)
+ (let ((ov (make-overlay beg end)))
+ ;; (overlay-put ov 'face 'highlight)
+ (overlay-put ov 'keymap company-template-nav-map)
+ (overlay-put ov 'priority 101)
+ (overlay-put ov 'evaporate t)
+ (push ov company-template--buffer-templates)
+ (add-hook 'post-command-hook 'company-template-post-command nil t)
+ ov))
+
+(defun company-template-remove-template (templ)
+ (mapc 'company-template-remove-field
+ (overlay-get templ 'company-template-fields))
+ (setq company-template--buffer-templates
+ (delq templ company-template--buffer-templates))
+ (delete-overlay templ))
+
+(defun company-template-add-field (templ beg end &optional display after-clear-fn)
+ "Add new field to template TEMPL spanning from BEG to END.
+When DISPLAY is non-nil, set the respective property on the overlay.
+Leave point at the end of the field.
+AFTER-CLEAR-FN is a function that can be used to apply custom behavior
+after deleting a field in `company-template-remove-field'."
+ (cl-assert templ)
+ (when (> end (overlay-end templ))
+ (move-overlay templ (overlay-start templ) end))
+ (let ((ov (make-overlay beg end))
+ (siblings (overlay-get templ 'company-template-fields)))
+ ;; (overlay-put ov 'evaporate t)
+ (overlay-put ov 'intangible t)
+ (overlay-put ov 'face 'company-template-field)
+ (when display
+ (overlay-put ov 'display display))
+ (overlay-put ov 'company-template-parent templ)
+ (overlay-put ov 'insert-in-front-hooks '(company-template-insert-hook))
+ (when after-clear-fn
+ (overlay-put ov 'company-template-after-clear after-clear-fn))
+ (overlay-put ov 'keymap company-template-field-map)
+ (overlay-put ov 'priority 101)
+ (push ov siblings)
+ (overlay-put templ 'company-template-fields siblings)))
+
+(defun company-template-remove-field (ovl &optional clear)
+ (when (overlayp ovl)
+ (when (overlay-buffer ovl)
+ (when clear
+ (delete-region (overlay-start ovl) (overlay-end ovl)))
+ (delete-overlay ovl))
+ (let* ((templ (overlay-get ovl 'company-template-parent))
+ (siblings (overlay-get templ 'company-template-fields)))
+ (setq siblings (delq ovl siblings))
+ (overlay-put templ 'company-template-fields siblings))))
+
+(defun company-template-clean-up (&optional pos)
+ "Clean up all templates that don't contain POS."
+ (let ((local-ovs (overlays-at (or pos (point)))))
+ (dolist (templ company-template--buffer-templates)
+ (unless (memq templ local-ovs)
+ (company-template-remove-template templ)))))
+
+;; hooks ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defun company-template-insert-hook (ovl after-p &rest _ignore)
+ "Called when a snippet input prompt is modified."
+ (unless after-p
+ (company-template-remove-field ovl t)))
+
+(defun company-template-post-command ()
+ (company-template-clean-up)
+ (unless company-template--buffer-templates
+ (remove-hook 'post-command-hook 'company-template-post-command t)))
+
+;; common ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defun company-template-c-like-templatify (call)
+ (let* ((end (point-marker))
+ (beg (- (point) (length call)))
+ (templ (company-template-declare-template beg end))
+ paren-open paren-close)
+ (with-syntax-table (make-syntax-table (syntax-table))
+ (modify-syntax-entry ?< "(")
+ (modify-syntax-entry ?> ")")
+ (when (search-backward ")" beg t)
+ (setq paren-close (point-marker))
+ (forward-char 1)
+ (delete-region (point) end)
+ (backward-sexp)
+ (forward-char 1)
+ (setq paren-open (point-marker)))
+ (when (search-backward ">" beg t)
+ (let ((angle-close (point-marker)))
+ (forward-char 1)
+ (backward-sexp)
+ (forward-char)
+ (company-template--c-like-args templ angle-close)))
+ (when (looking-back "\\((\\*)\\)(" (line-beginning-position))
+ (delete-region (match-beginning 1) (match-end 1)))
+ (when paren-open
+ (goto-char paren-open)
+ (company-template--c-like-args templ paren-close)))
+ (if (overlay-get templ 'company-template-fields)
+ (company-template-move-to-first templ)
+ (company-template-remove-template templ)
+ (goto-char end))))
+
+(defun company-template--c-like-args (templ end)
+ (let ((last-pos (point)))
+ (while (re-search-forward "\\([^,]+\\),?" end 'move)
+ (when (zerop (car (parse-partial-sexp last-pos (point))))
+ (company-template-add-field templ last-pos (match-end 1) nil
+ #'company-template--after-clear-c-like-field)
+ (skip-chars-forward " ")
+ (setq last-pos (point))))))
+
+;; objc ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defun company-template-objc-templatify (selector)
+ (let* ((end (point-marker))
+ (beg (- (point) (length selector) 1))
+ (templ (company-template-declare-template beg end))
+ (cnt 0))
+ (save-excursion
+ (goto-char beg)
+ (catch 'stop
+ (while (search-forward ":" end t)
+ (if (looking-at "\\(([^)]*)\\) ?")
+ (company-template-add-field templ (point) (match-end 1))
+ ;; Not sure which conditions this case manifests under, but
+ ;; apparently it did before, when I wrote the first test for this
+ ;; function. FIXME: Revisit it.
+ (company-template-add-field templ (point)
+ (progn
+ (insert (format "arg%d" cnt))
+ (point)))
+ (when (< (point) end)
+ (insert " "))
+ (cl-incf cnt))
+ (when (>= (point) end)
+ (throw 'stop t)))))
+ (company-template-move-to-first templ)))
+
+(provide 'company-template)
+;;; company-template.el ends here
diff --git a/elpa/company-20220425.1145/company-template.elc b/elpa/company-20220425.1145/company-template.elc
new file mode 100644
index 0000000..5d2affd
--- /dev/null
+++ b/elpa/company-20220425.1145/company-template.elc
Binary files differ
diff --git a/elpa/company-20220425.1145/company-tempo.el b/elpa/company-20220425.1145/company-tempo.el
new file mode 100644
index 0000000..ccf44e8
--- /dev/null
+++ b/elpa/company-20220425.1145/company-tempo.el
@@ -0,0 +1,71 @@
+;;; company-tempo.el --- company-mode completion backend for tempo
+
+;; Copyright (C) 2009-2011, 2013-2016 Free Software Foundation, Inc.
+
+;; Author: Nikolaj Schumacher
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs 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.
+
+;; GNU Emacs 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 GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
+
+
+;;; Commentary:
+;;
+
+;;; Code:
+
+(require 'company)
+(require 'cl-lib)
+(require 'tempo)
+
+(defgroup company-tempo nil
+ "Tempo completion backend."
+ :group 'company)
+
+(defcustom company-tempo-expand nil
+ "Whether to expand a tempo tag after completion."
+ :type '(choice (const :tag "Off" nil)
+ (const :tag "On" t)))
+
+(defsubst company-tempo-lookup (match)
+ (cdr (assoc match (tempo-build-collection))))
+
+(defun company-tempo-insert (match)
+ "Replace MATCH with the expanded tempo template."
+ (search-backward match)
+ (goto-char (match-beginning 0))
+ (replace-match "")
+ (call-interactively (company-tempo-lookup match)))
+
+(defsubst company-tempo-meta (match)
+ (let ((templ (company-tempo-lookup match))
+ doc)
+ (and templ
+ (setq doc (documentation templ t))
+ (car (split-string doc "\n" t)))))
+
+;;;###autoload
+(defun company-tempo (command &optional arg &rest ignored)
+ "`company-mode' completion backend for tempo."
+ (interactive (list 'interactive))
+ (cl-case command
+ (interactive (company-begin-backend 'company-tempo))
+ (prefix (or (car (tempo-find-match-string tempo-match-finder)) ""))
+ (candidates (all-completions arg (tempo-build-collection)))
+ (meta (company-tempo-meta arg))
+ (post-completion (when company-tempo-expand (company-tempo-insert arg)))
+ (sorted t)))
+
+(provide 'company-tempo)
+;;; company-tempo.el ends here
diff --git a/elpa/company-20220425.1145/company-tempo.elc b/elpa/company-20220425.1145/company-tempo.elc
new file mode 100644
index 0000000..11f2d87
--- /dev/null
+++ b/elpa/company-20220425.1145/company-tempo.elc
Binary files differ
diff --git a/elpa/company-20220425.1145/company-tng.el b/elpa/company-20220425.1145/company-tng.el
new file mode 100644
index 0000000..55124a3
--- /dev/null
+++ b/elpa/company-20220425.1145/company-tng.el
@@ -0,0 +1,196 @@
+;;; company-tng.el --- company-mode configuration for single-button interaction
+
+;; Copyright (C) 2017-2021 Free Software Foundation, Inc.
+
+;; Author: Nikita Leshenko
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs 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.
+
+;; GNU Emacs 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 GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
+
+
+;;; Commentary:
+;;
+;; company-tng (Tab and Go) allows you to perform completion using just TAB.
+;; Pressing it will both select the next completion candidate in the list and
+;; insert it into the buffer (or make it look like it's inserted, in fact).
+;;
+;; It cycles the candidates like `yank-pop' or `dabbrev-expand' or Vim:
+;; Pressing TAB selects the first item in the completion menu and inserts it in
+;; the buffer. Pressing TAB again selects the second item and replaces the
+;; "inserted" item with the second one. This can continue as long as the user
+;; wishes to cycle through the menu. You can also press S-TAB to select the
+;; previous candidate, of course.
+;;
+;; The benefits are that you only have to use one shortcut key and there is no
+;; need to confirm the entry.
+;;
+;; Usage:
+;;
+;; Enable `company-tng-mode' with:
+;;
+;; (add-hook 'after-init-hook 'company-tng-mode)
+;;
+;; in your init script. It will set up the required frontend, as well as make a
+;; number of recommended configuration changes described below.
+;;
+;; To avoid these changes, if you want to tweak everything yourself, customize
+;;`company-tng-auto-configure' to nil.
+;;
+;; We recommend to bind TAB to `company-select-next', S-TAB to
+;; `company-select-previous', and unbind RET and other now-unnecessary
+;; keys from `company-active-map':
+;;
+;; (define-key company-active-map (kbd "TAB") 'company-select-next)
+;; (define-key company-active-map (kbd "<backtab>") 'company-select-previous)
+;; (define-key company-active-map (kbd "RET") nil)
+;;
+;; Note that it's not necessary to rebind keys to use this frontend,
+;; you can use the arrow keys or M-n/M-p to select and insert
+;; candidates. You also need to decide which keys to unbind, depending
+;; on whether you want them to do the Company action or the default
+;; Emacs action (for example C-s or C-w).
+;;
+;; We recommend to disable `company-require-match' to allow free typing at any
+;; point.
+;;
+;; By default, company-tng doesn't work well with backends that insert function
+;; arguments into the buffer and (optionally) expand them into a snippet
+;; (usually performed in `post-completion' using yasnippet or company-template).
+;; In company-tng, completion candidates
+;; are inserted into the buffer as the user selects them and the completion is
+;; finished implicitly when the user continues typing after selecting a
+;; candidate. Modifying the buffer (by expanding a snippet) when the user
+;; continues typing would be surprising and undesirable, since the candidate was
+;; already inserted into the buffer.
+;;
+;; For this reason `company-tng-mode' by default disables arguments insertion
+;; for a number of popular backends. If the backend you are using is not among
+;; them, you might have to configure it not to do that yourself.
+;;
+;; YASnippet and company-tng both use TAB, which causes conflicts. The
+;; recommended way to use YASnippet with company-tng is to choose a different
+;; key for expanding a snippet and moving to the next snippet field:
+;;
+;; (define-key yas-minor-mode-map "\C-j" 'yas-expand)
+;; (define-key yas-keymap "\C-j" 'yas-next-field-or-maybe-expand)
+;; (dolist (keymap (list yas-minor-mode-map yas-keymap))
+;; (define-key keymap (kbd "TAB") nil)
+;; (define-key keymap [(tab)] nil))
+
+;;; Code:
+
+(require 'company)
+(require 'cl-lib)
+
+(defvar-local company-tng--overlay nil)
+
+;;;###autoload
+(defun company-tng-frontend (command)
+ "When the user changes the selection at least once, this
+frontend will display the candidate in the buffer as if it's
+already there and any key outside of `company-active-map' will
+confirm the selection and finish the completion."
+ (cl-case command
+ (show
+ (let ((ov (make-overlay (point) (point))))
+ (setq company-tng--overlay ov)
+ (overlay-put ov 'priority 2)))
+ (update
+ (let* ((ov company-tng--overlay)
+ (selected (and company-selection
+ (nth company-selection company-candidates)))
+ (prefix (length company-prefix)))
+ (move-overlay ov (- (point) prefix) (point))
+ (overlay-put ov
+ (if (= prefix 0) 'after-string 'display)
+ selected)))
+ (hide
+ (when company-tng--overlay
+ (delete-overlay company-tng--overlay)
+ (kill-local-variable 'company-tng--overlay)))
+ (pre-command
+ (when (and company-selection
+ (not (company--company-command-p (this-command-keys))))
+ (company--unread-this-command-keys)
+ (setq this-command 'company-complete-selection)))))
+
+(defvar company-clang-insert-arguments)
+(defvar company-semantic-insert-arguments)
+(defvar company-rtags-insert-arguments)
+(defvar lsp-enable-snippet)
+
+(defgroup company-tng nil
+ "Company Tab and Go."
+ :group 'company)
+
+(defcustom company-tng-auto-configure t
+ "Automatically apply default configure when enable `company-tng-mode'."
+ :type 'boolean)
+
+;;;###autoload
+(define-obsolete-function-alias 'company-tng-configure-default 'company-tng-mode "0.9.14"
+ "Applies the default configuration to enable company-tng.")
+
+(declare-function eglot--snippet-expansion-fn "eglot")
+
+(defvar company-tng-map
+ (let ((keymap (make-sparse-keymap)))
+ (set-keymap-parent keymap company-active-map)
+ (define-key keymap [return] nil)
+ (define-key keymap (kbd "RET") nil)
+ (define-key keymap [tab] 'company-select-next)
+ (define-key keymap (kbd "TAB") 'company-select-next)
+ (define-key keymap [backtab] 'company-select-previous)
+ (define-key keymap (kbd "S-TAB") 'company-select-previous)
+ keymap))
+
+;;;###autoload
+(define-minor-mode company-tng-mode
+ "This minor mode enables `company-tng-frontend'."
+ :init-value nil
+ :global t
+ (cond
+ (company-tng-mode
+ (setq company-frontends
+ (add-to-list 'company-frontends 'company-tng-frontend))
+ (when company-tng-auto-configure
+ (setq company-frontends '(company-tng-frontend
+ company-pseudo-tooltip-frontend
+ company-echo-metadata-frontend))
+ (setq company-require-match nil
+ company-clang-insert-arguments nil
+ company-semantic-insert-arguments nil
+ company-rtags-insert-arguments nil
+ lsp-enable-snippet nil)
+ (advice-add #'eglot--snippet-expansion-fn :override #'ignore)
+ (setq company-active-map company-tng-map))
+ (setq company-selection-default nil))
+ (t
+ (setq company-frontends
+ '(company-pseudo-tooltip-unless-just-one-frontend
+ company-preview-if-just-one-frontend
+ company-echo-metadata-frontend))
+ (when company-tng-auto-configure
+ (setq company-require-match 'company-explicit-action-p
+ company-clang-insert-arguments t
+ company-semantic-insert-arguments t
+ company-rtags-insert-arguments t
+ lsp-enable-snippet t)
+ (advice-remove #'eglot--snippet-expansion-fn #'ignore)
+ (setq company-active-map (keymap-parent company-tng-map)))
+ (setq company-selection-default 0))))
+
+(provide 'company-tng)
+;;; company-tng.el ends here
diff --git a/elpa/company-20220425.1145/company-tng.elc b/elpa/company-20220425.1145/company-tng.elc
new file mode 100644
index 0000000..a9d81d9
--- /dev/null
+++ b/elpa/company-20220425.1145/company-tng.elc
Binary files differ
diff --git a/elpa/company-20220425.1145/company-yasnippet.el b/elpa/company-20220425.1145/company-yasnippet.el
new file mode 100644
index 0000000..4769516
--- /dev/null
+++ b/elpa/company-20220425.1145/company-yasnippet.el
@@ -0,0 +1,186 @@
+;;; company-yasnippet.el --- company-mode completion backend for Yasnippet
+
+;; Copyright (C) 2014-2015, 2020-2021 Free Software Foundation, Inc.
+
+;; Author: Dmitry Gutov
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs 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.
+
+;; GNU Emacs 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 GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
+
+
+;;; Commentary:
+;;
+
+;;; Code:
+
+(require 'company)
+(require 'cl-lib)
+
+(declare-function yas--table-hash "yasnippet")
+(declare-function yas--get-snippet-tables "yasnippet")
+(declare-function yas-expand-snippet "yasnippet")
+(declare-function yas--template-content "yasnippet")
+(declare-function yas--template-expand-env "yasnippet")
+(declare-function yas--warning "yasnippet")
+(declare-function yas-minor-mode "yasnippet")
+(declare-function yas--require-template-specific-condition-p "yasnippet")
+(declare-function yas--template-can-expand-p "yasnippet")
+(declare-function yas--template-condition "yasnippet")
+
+(defvar company-yasnippet-annotation-fn
+ (lambda (name)
+ (concat
+ (unless company-tooltip-align-annotations " -> ")
+ name))
+ "Function to format completion annotation.
+It has to accept one argument: the snippet's name.")
+
+(defun company-yasnippet--key-prefixes ()
+ ;; Mostly copied from `yas--templates-for-key-at-point'.
+ (defvar yas-key-syntaxes)
+ (save-excursion
+ (let ((original (point))
+ (methods yas-key-syntaxes)
+ prefixes
+ method)
+ (while methods
+ (unless (eq method (car methods))
+ (goto-char original))
+ (setq method (car methods))
+ (cond ((stringp method)
+ (skip-syntax-backward method)
+ (setq methods (cdr methods)))
+ ((functionp method)
+ (unless (eq (funcall method original)
+ 'again)
+ (setq methods (cdr methods))))
+ (t
+ (setq methods (cdr methods))
+ (yas--warning "Invalid element `%s' in `yas-key-syntaxes'" method)))
+ (let ((prefix (buffer-substring-no-properties (point) original)))
+ (unless (equal prefix (car prefixes))
+ (push prefix prefixes))))
+ prefixes)))
+
+(defun company-yasnippet--candidates (prefix)
+ ;; Process the prefixes in reverse: unlike Yasnippet, we look for prefix
+ ;; matches, so the longest prefix with any matches should be the most useful.
+ (cl-loop with tables = (yas--get-snippet-tables)
+ for key-prefix in (company-yasnippet--key-prefixes)
+ ;; Only consider keys at least as long as the symbol at point.
+ when (>= (length key-prefix) (length prefix))
+ thereis (company-yasnippet--completions-for-prefix prefix
+ key-prefix
+ tables)))
+
+(defun company-yasnippet--completions-for-prefix (prefix key-prefix tables)
+ (cl-mapcan
+ (lambda (table)
+ (let ((keyhash (yas--table-hash table))
+ (requirement (yas--require-template-specific-condition-p))
+ res)
+ (when keyhash
+ (maphash
+ (lambda (key value)
+ (when (and (stringp key)
+ (string-prefix-p key-prefix key))
+ (maphash
+ (lambda (name template)
+ (when (yas--template-can-expand-p
+ (yas--template-condition template) requirement)
+ (push
+ (propertize key
+ 'yas-annotation name
+ 'yas-template template
+ 'yas-prefix-offset (- (length key-prefix)
+ (length prefix)))
+ res)))
+ value)))
+ keyhash))
+ res))
+ tables))
+
+(defun company-yasnippet--doc (arg)
+ (let ((template (get-text-property 0 'yas-template arg))
+ (mode major-mode)
+ (file-name (buffer-file-name)))
+ (defvar yas-prompt-functions)
+ (with-current-buffer (company-doc-buffer)
+ (let ((buffer-file-name file-name))
+ (yas-minor-mode 1)
+ (setq-local yas-prompt-functions '(yas-no-prompt))
+ (condition-case error
+ (yas-expand-snippet (yas--template-content template))
+ (error
+ (message "%s" (error-message-string error))))
+ (delay-mode-hooks
+ (let ((inhibit-message t))
+ (if (eq mode 'web-mode)
+ (progn
+ (setq mode 'html-mode)
+ (funcall mode))
+ (funcall mode)))
+ (ignore-errors (font-lock-ensure))))
+ (current-buffer))))
+
+;;;###autoload
+(defun company-yasnippet (command &optional arg &rest ignore)
+ "`company-mode' backend for `yasnippet'.
+
+This backend should be used with care, because as long as there are
+snippets defined for the current major mode, this backend will always
+shadow backends that come after it. Recommended usages:
+
+* In a buffer-local value of `company-backends', grouped with a backend or
+ several that provide actual text completions.
+
+ (add-hook \\='js-mode-hook
+ (lambda ()
+ (set (make-local-variable \\='company-backends)
+ \\='((company-dabbrev-code company-yasnippet)))))
+
+* After keyword `:with', grouped with other backends.
+
+ (push \\='(company-semantic :with company-yasnippet) company-backends)
+
+* Not in `company-backends', just bound to a key.
+
+ (global-set-key (kbd \"C-c y\") \\='company-yasnippet)
+"
+ (interactive (list 'interactive))
+ (cl-case command
+ (interactive (company-begin-backend 'company-yasnippet))
+ (prefix
+ ;; Should probably use `yas--current-key', but that's bound to be slower.
+ ;; How many trigger keys start with non-symbol characters anyway?
+ (and (bound-and-true-p yas-minor-mode)
+ (company-grab-symbol)))
+ (annotation
+ (funcall company-yasnippet-annotation-fn
+ (get-text-property 0 'yas-annotation arg)))
+ (candidates (company-yasnippet--candidates arg))
+ (doc-buffer (company-yasnippet--doc arg))
+ (no-cache t)
+ (kind 'snippet)
+ (post-completion
+ (let ((template (get-text-property 0 'yas-template arg))
+ (prefix-offset (get-text-property 0 'yas-prefix-offset arg)))
+ (yas-expand-snippet (yas--template-content template)
+ (- (point) (length arg) prefix-offset)
+ (point)
+ (yas--template-expand-env template))))))
+
+(provide 'company-yasnippet)
+;;; company-yasnippet.el ends here
diff --git a/elpa/company-20220425.1145/company-yasnippet.elc b/elpa/company-20220425.1145/company-yasnippet.elc
new file mode 100644
index 0000000..0c5db6a
--- /dev/null
+++ b/elpa/company-20220425.1145/company-yasnippet.elc
Binary files differ
diff --git a/elpa/company-20220425.1145/company.el b/elpa/company-20220425.1145/company.el
new file mode 100644
index 0000000..4c58707
--- /dev/null
+++ b/elpa/company-20220425.1145/company.el
@@ -0,0 +1,3917 @@
+;;; company.el --- Modular text completion framework -*- lexical-binding: t -*-
+
+;; Copyright (C) 2009-2022 Free Software Foundation, Inc.
+
+;; Author: Nikolaj Schumacher
+;; Maintainer: Dmitry Gutov <dgutov@yandex.ru>
+;; URL: http://company-mode.github.io/
+;; Version: 0.9.13
+;; Keywords: abbrev, convenience, matching
+;; Package-Requires: ((emacs "25.1"))
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs 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.
+
+;; GNU Emacs 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 GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;
+;; Company is a modular completion framework. Modules for retrieving completion
+;; candidates are called backends, modules for displaying them are frontends.
+;;
+;; Company comes with many backends, e.g. `company-etags'. These are
+;; distributed in separate files and can be used individually.
+;;
+;; Enable `company-mode' in all buffers with M-x global-company-mode. For
+;; further information look at the documentation for `company-mode' (C-h f
+;; company-mode RET).
+;;
+;; If you want to start a specific backend, call it interactively or use
+;; `company-begin-backend'. For example:
+;; M-x company-abbrev will prompt for and insert an abbrev.
+;;
+;; To write your own backend, look at the documentation for `company-backends'.
+;; Here is a simple example completing "foo":
+;;
+;; (defun company-my-backend (command &optional arg &rest ignored)
+;; (interactive (list 'interactive))
+;; (pcase command
+;; (`interactive (company-begin-backend 'company-my-backend))
+;; (`prefix (company-grab-symbol))
+;; (`candidates (list "foobar" "foobaz" "foobarbaz"))
+;; (`meta (format "This value is named %s" arg))))
+;;
+;; Sometimes it is a good idea to mix several backends together, for example to
+;; enrich gtags with dabbrev-code results (to emulate local variables). To do
+;; this, add a list with both backends as an element in `company-backends'.
+;;
+;;; Change Log:
+;;
+;; See NEWS.md in the repository.
+
+;;; Code:
+
+(require 'cl-lib)
+(require 'subr-x)
+(require 'pcase)
+
+(defgroup company nil
+ "Extensible inline text completion mechanism."
+ :group 'abbrev
+ :group 'convenience
+ :group 'matching
+ :link '(custom-manual "(company) Top"))
+
+(defgroup company-faces nil
+ "Faces used by Company."
+ :group 'company
+ :group 'faces)
+
+(defface company-tooltip
+ '((((class color) (min-colors 88) (background light))
+ (:foreground "black" :background "cornsilk"))
+ (((class color) (min-colors 88) (background dark))
+ (:background "gray26"))
+ (t (:foreground "black" :background "yellow")))
+ "Face used for the tooltip.")
+
+(defface company-tooltip-selection
+ '((((class color) (min-colors 88) (background light))
+ (:background "light blue"))
+ (((class color) (min-colors 88) (background dark))
+ (:background "gray31"))
+ (t (:background "green")))
+ "Face used for the selection in the tooltip.")
+
+(defface company-tooltip-deprecated
+ '((t (:strike-through t)))
+ "Face used for the deprecated items.")
+
+(defface company-tooltip-search
+ '((default :inherit highlight))
+ "Face used for the search string in the tooltip.")
+
+(defface company-tooltip-search-selection
+ '((default :inherit highlight))
+ "Face used for the search string inside the selection in the tooltip.")
+
+(defface company-tooltip-mouse
+ '((default :inherit highlight))
+ "Face used for the tooltip item under the mouse.")
+
+(defface company-tooltip-common
+ '((((background light))
+ :foreground "darkred")
+ (((background dark))
+ :foreground "pale turquoise"))
+ "Face used for the common completion in the tooltip.")
+
+(defface company-tooltip-common-selection
+ '((default :inherit company-tooltip-common))
+ "Face used for the selected common completion in the tooltip.")
+
+(defface company-tooltip-annotation
+ '((((background light))
+ :foreground "firebrick4")
+ (((background dark))
+ :foreground "LightCyan3"))
+ "Face used for the completion annotation in the tooltip.")
+
+(defface company-tooltip-annotation-selection
+ '((default :inherit company-tooltip-annotation))
+ "Face used for the selected completion annotation in the tooltip.")
+
+(defface company-tooltip-quick-access
+ '((default :inherit company-tooltip-annotation))
+ "Face used for the quick-access hints shown in the tooltip."
+ :package-version '(company . "0.9.14"))
+
+(defface company-tooltip-quick-access-selection
+ '((default :inherit company-tooltip-annotation-selection))
+ "Face used for the selected quick-access hints shown in the tooltip."
+ :package-version '(company . "0.9.14"))
+
+(define-obsolete-face-alias
+ 'company-scrollbar-fg
+ 'company-tooltip-scrollbar-thumb
+ "0.9.14")
+
+(defface company-tooltip-scrollbar-thumb
+ '((((background light))
+ :background "darkred")
+ (((background dark))
+ :background "gray33"))
+ "Face used for the tooltip scrollbar thumb (bar).")
+
+(define-obsolete-face-alias
+ 'company-scrollbar-bg
+ 'company-tooltip-scrollbar-track
+ "0.9.14")
+
+(defface company-tooltip-scrollbar-track
+ '((((background light))
+ :background "wheat")
+ (((background dark))
+ :background "gray28"))
+ "Face used for the tooltip scrollbar track (trough).")
+
+(defface company-preview
+ '((default :inherit (company-tooltip-selection company-tooltip)))
+ "Face used for the completion preview.")
+
+(defface company-preview-common
+ '((default :inherit company-tooltip-common-selection))
+ "Face used for the common part of the completion preview.")
+
+(defface company-preview-search
+ '((default :inherit company-tooltip-common-selection))
+ "Face used for the search string in the completion preview.")
+
+(defface company-echo nil
+ "Face used for completions in the echo area.")
+
+(defface company-echo-common
+ '((((background light)) (:foreground "firebrick4"))
+ (((background dark)) (:foreground "firebrick1")))
+ "Face used for the common part of completions in the echo area.")
+
+;; Too lazy to re-add :group to all defcustoms down below.
+(setcdr (assoc load-file-name custom-current-group-alist)
+ 'company)
+
+(defun company-frontends-set (variable value)
+ ;; Uniquify.
+ (let ((value (delete-dups (copy-sequence value))))
+ (and (or (and (memq 'company-pseudo-tooltip-unless-just-one-frontend value)
+ (memq 'company-pseudo-tooltip-frontend value))
+ (and (memq 'company-pseudo-tooltip-unless-just-one-frontend-with-delay value)
+ (memq 'company-pseudo-tooltip-frontend value))
+ (and (memq 'company-pseudo-tooltip-unless-just-one-frontend-with-delay value)
+ (memq 'company-pseudo-tooltip-unless-just-one-frontend value)))
+ (user-error "Pseudo tooltip frontend cannot be used more than once"))
+ (and (or (and (memq 'company-preview-if-just-one-frontend value)
+ (memq 'company-preview-frontend value))
+ (and (memq 'company-preview-if-just-one-frontend value)
+ (memq 'company-preview-common-frontend value))
+ (and (memq 'company-preview-frontend value)
+ (memq 'company-preview-common-frontend value))
+ )
+ (user-error "Preview frontend cannot be used twice"))
+ (and (memq 'company-echo value)
+ (memq 'company-echo-metadata-frontend value)
+ (user-error "Echo area cannot be used twice"))
+ ;; Preview must come last.
+ (dolist (f '(company-preview-if-just-one-frontend company-preview-frontend company-preview-common-frontend))
+ (when (cdr (memq f value))
+ (setq value (append (delq f value) (list f)))))
+ (set variable value)))
+
+(defcustom company-frontends '(company-pseudo-tooltip-unless-just-one-frontend
+ company-preview-if-just-one-frontend
+ company-echo-metadata-frontend)
+ "The list of active frontends (visualizations).
+Each frontend is a function that takes one argument. It is called with
+one of the following arguments:
+
+`show': When the visualization should start.
+
+`hide': When the visualization should end.
+
+`update': When the data has been updated.
+
+`pre-command': Before every command that is executed while the
+visualization is active.
+
+`post-command': After every command that is executed while the
+visualization is active.
+
+`unhide': When an asynchronous backend is waiting for its completions.
+Only needed in frontends which hide their visualizations in `pre-command'
+for technical reasons.
+
+The visualized data is stored in `company-prefix', `company-candidates',
+`company-common', `company-selection', `company-point' and
+`company-search-string'."
+ :set 'company-frontends-set
+ :type '(repeat (choice (const :tag "echo" company-echo-frontend)
+ (const :tag "echo, strip common"
+ company-echo-strip-common-frontend)
+ (const :tag "show echo meta-data in echo"
+ company-echo-metadata-frontend)
+ (const :tag "pseudo tooltip"
+ company-pseudo-tooltip-frontend)
+ (const :tag "pseudo tooltip, multiple only"
+ company-pseudo-tooltip-unless-just-one-frontend)
+ (const :tag "pseudo tooltip, multiple only, delayed"
+ company-pseudo-tooltip-unless-just-one-frontend-with-delay)
+ (const :tag "preview" company-preview-frontend)
+ (const :tag "preview, unique only"
+ company-preview-if-just-one-frontend)
+ (const :tag "preview, common"
+ company-preview-common-frontend)
+ (function :tag "custom function" nil))))
+
+(defcustom company-tooltip-limit 10
+ "The maximum number of candidates in the tooltip."
+ :type 'integer)
+
+(defcustom company-tooltip-minimum 6
+ "Ensure visibility of this number of candidates.
+When that many lines are not available between point and the bottom of the
+window, display the tooltip above point."
+ :type 'integer)
+
+(defcustom company-tooltip-minimum-width 0
+ "The minimum width of the tooltip's inner area.
+This doesn't include the margins and the scroll bar."
+ :type 'integer
+ :package-version '(company . "0.8.0"))
+
+(defcustom company-tooltip-maximum-width most-positive-fixnum
+ "The maximum width of the tooltip's inner area.
+This doesn't include the margins and the scroll bar."
+ :type 'integer
+ :package-version '(company . "0.9.5"))
+
+(defcustom company-tooltip-width-grow-only nil
+ "When non-nil, the tooltip width is not allowed to decrease."
+ :type 'boolean
+ :package-version '(company . "0.9.14"))
+
+(defcustom company-tooltip-margin 1
+ "Width of margin columns to show around the toolip."
+ :type 'integer)
+
+(defcustom company-tooltip-offset-display 'scrollbar
+ "Method using which the tooltip displays scrolling position.
+`scrollbar' means draw a scrollbar to the right of the items.
+`lines' means wrap items in lines with \"before\" and \"after\" counters."
+ :type '(choice (const :tag "Scrollbar" scrollbar)
+ (const :tag "Two lines" lines)))
+
+(defcustom company-tooltip-align-annotations nil
+ "When non-nil, align annotations to the right tooltip border."
+ :type 'boolean
+ :package-version '(company . "0.7.1"))
+
+(defcustom company-tooltip-flip-when-above nil
+ "Whether to flip the tooltip when it's above the current line."
+ :type 'boolean
+ :package-version '(company . "0.8.1"))
+
+(defvar company-safe-backends
+ '((company-abbrev . "Abbrev")
+ (company-bbdb . "BBDB")
+ (company-capf . "completion-at-point-functions")
+ (company-clang . "Clang")
+ (company-cmake . "CMake")
+ (company-css . "CSS (obsolete backend)")
+ (company-dabbrev . "dabbrev for plain text")
+ (company-dabbrev-code . "dabbrev for code")
+ (company-elisp . "Emacs Lisp (obsolete backend)")
+ (company-etags . "etags")
+ (company-files . "Files")
+ (company-gtags . "GNU Global")
+ (company-ispell . "Ispell")
+ (company-keywords . "Programming language keywords")
+ (company-nxml . "nxml (obsolete backend)")
+ (company-oddmuse . "Oddmuse")
+ (company-semantic . "Semantic")
+ (company-tempo . "Tempo templates")))
+(put 'company-safe-backends 'risky-local-variable t)
+
+(defun company-safe-backends-p (backends)
+ (and (consp backends)
+ (not (cl-dolist (backend backends)
+ (unless (if (consp backend)
+ (company-safe-backends-p backend)
+ (assq backend company-safe-backends))
+ (cl-return t))))))
+
+(defcustom company-backends `(company-bbdb
+ ,@(unless (version<= "26" emacs-version)
+ (list 'company-nxml))
+ ,@(unless (version<= "26" emacs-version)
+ (list 'company-css))
+ company-semantic
+ company-cmake
+ company-capf
+ company-clang
+ company-files
+ (company-dabbrev-code company-gtags company-etags
+ company-keywords)
+ company-oddmuse company-dabbrev)
+ "The list of active backends (completion engines).
+
+Only one backend is used at a time. The choice depends on the order of
+the items in this list, and on the values they return in response to the
+`prefix' command (see below). But a backend can also be a \"grouped\"
+one (see below).
+
+`company-begin-backend' can be used to start a specific backend,
+`company-other-backend' will skip to the next matching backend in the list.
+
+Each backend is a function that takes a variable number of arguments.
+The first argument is the command requested from the backend. It is one
+of the following:
+
+`prefix': The backend should return the text to be completed. It must be
+text immediately before point. Returning nil from this command passes
+control to the next backend. The function should return `stop' if it
+should complete but cannot (e.g. when in the middle of a symbol).
+Instead of a string, the backend may return a cons (PREFIX . LENGTH)
+where LENGTH is a number used in place of PREFIX's length when
+comparing against `company-minimum-prefix-length'. LENGTH can also
+be just t, and in the latter case the test automatically succeeds.
+
+`candidates': The second argument is the prefix to be completed. The
+return value should be a list of candidates that match the prefix.
+
+Non-prefix matches are also supported (candidates that don't start with the
+prefix, but match it in some backend-defined way). Backends that use this
+feature must disable cache (return t to `no-cache') and might also want to
+respond to `match'.
+
+Optional commands
+=================
+
+`sorted': Return t here to indicate that the candidates are sorted and will
+not need to be sorted again.
+
+`duplicates': If non-nil, company will take care of removing duplicates
+from the list.
+
+`no-cache': Usually company doesn't ask for candidates again as completion
+progresses, unless the backend returns t for this command. The second
+argument is the latest prefix.
+
+`ignore-case': Return t here if the backend returns case-insensitive
+matches. This value is used to determine the longest common prefix (as
+used in `company-complete-common'), and to filter completions when fetching
+them from cache.
+
+`meta': The second argument is a completion candidate. Return a (short)
+documentation string for it.
+
+`doc-buffer': The second argument is a completion candidate. Return a
+buffer with documentation for it. Preferably use `company-doc-buffer'. If
+not all buffer contents pertain to this candidate, return a cons of buffer
+and window start position.
+
+`location': The second argument is a completion candidate. Return a cons
+of buffer and buffer location, or of file and line number where the
+completion candidate was defined.
+
+`annotation': The second argument is a completion candidate. Return a
+string to be displayed inline with the candidate in the popup. If
+duplicates are removed by company, candidates with equal string values will
+be kept if they have different annotations. For that to work properly,
+backends should store the related information on candidates using text
+properties.
+
+`deprecated': The second argument is a completion candidate. Return
+non-nil if the completion candidate is deprecated.
+
+`match': The second argument is a completion candidate. Return a positive
+integer, the index after the end of text matching `prefix' within the
+candidate string. Alternatively, return a list of (CHUNK-START
+. CHUNK-END) elements, where CHUNK-START and CHUNK-END are indexes within
+the candidate string. The corresponding regions are be used when rendering
+the popup. This command only makes sense for backends that provide
+non-prefix completion.
+
+`require-match': If this returns t, the user is not allowed to enter
+anything not offered as a candidate. Please don't use that value in normal
+backends. The default value nil gives the user that choice with
+`company-require-match'. Return value `never' overrides that option the
+other way around (using that value will indicate that the returned set of
+completions is often incomplete, so this behavior will not be useful).
+
+`init': Called once for each buffer. The backend can check for external
+programs and files and load any required libraries. Raising an error here
+will show up in message log once, and the backend will not be used for
+completion.
+
+`post-completion': Called after a completion candidate has been inserted
+into the buffer. The second argument is the candidate. Can be used to
+modify it, e.g. to expand a snippet.
+
+`kind': The second argument is a completion candidate. Return a symbol
+describing the kind of the candidate. Refer to `company-vscode-icons-mapping'
+for the possible values.
+
+The backend should return nil for all commands it does not support or
+does not know about. It should also be callable interactively and use
+`company-begin-backend' to start itself in that case.
+
+Grouped backends
+================
+
+An element of `company-backends' can also be a list of backends. The
+completions from backends in such groups are merged, but only from those
+backends which return the same `prefix'.
+
+If a backend command takes a candidate as an argument (e.g. `meta'), the
+call is dispatched to the backend the candidate came from. In other
+cases (except for `duplicates' and `sorted'), the first non-nil value among
+all the backends is returned.
+
+The group can also contain keywords. Currently, `:with' and `:separate'
+keywords are defined. If the group contains keyword `:with', the backends
+listed after this keyword are ignored for the purpose of the `prefix'
+command. If the group contains keyword `:separate', the candidates that
+come from different backends are sorted separately in the combined list.
+
+Asynchronous backends
+=====================
+
+The return value of each command can also be a cons (:async . FETCHER)
+where FETCHER is a function of one argument, CALLBACK. When the data
+arrives, FETCHER must call CALLBACK and pass it the appropriate return
+value, as described above. That call must happen in the same buffer as
+where completion was initiated.
+
+True asynchronous operation is only supported for command `candidates', and
+only during idle completion. Other commands will block the user interface,
+even if the backend uses the asynchronous calling convention."
+ :type `(repeat
+ (choice
+ :tag "backend"
+ ,@(mapcar (lambda (b) `(const :tag ,(cdr b) ,(car b)))
+ company-safe-backends)
+ (symbol :tag "User defined")
+ (repeat :tag "Merged backends"
+ (choice :tag "backend"
+ ,@(mapcar (lambda (b)
+ `(const :tag ,(cdr b) ,(car b)))
+ company-safe-backends)
+ (const :tag "With" :with)
+ (symbol :tag "User defined"))))))
+
+(put 'company-backends 'safe-local-variable 'company-safe-backends-p)
+
+(defcustom company-transformers nil
+ "Functions to change the list of candidates received from backends.
+
+Each function gets called with the return value of the previous one.
+The first one gets passed the list of candidates, already sorted and
+without duplicates."
+ :type '(choice
+ (const :tag "None" nil)
+ (const :tag "Sort by occurrence" (company-sort-by-occurrence))
+ (const :tag "Sort by backend importance"
+ (company-sort-by-backend-importance))
+ (const :tag "Prefer case sensitive prefix"
+ (company-sort-prefer-same-case-prefix))
+ (repeat :tag "User defined" (function))))
+
+(defcustom company-completion-started-hook nil
+ "Hook run when company starts completing.
+The hook is called with one argument that is non-nil if the completion was
+started manually."
+ :type 'hook)
+
+(defcustom company-completion-cancelled-hook nil
+ "Hook run when company cancels completing.
+The hook is called with one argument that is non-nil if the completion was
+aborted manually."
+ :type 'hook)
+
+(defcustom company-completion-finished-hook nil
+ "Hook run when company successfully completes.
+The hook is called with the selected candidate as an argument.
+
+If you indend to use it to post-process candidates from a specific
+backend, consider using the `post-completion' command instead."
+ :type 'hook)
+
+(defcustom company-after-completion-hook nil
+ "Hook run at the end of completion, successful or not.
+The hook is called with one argument which is either a string or a symbol."
+ :type 'hook)
+
+(defcustom company-minimum-prefix-length 3
+ "The minimum prefix length for idle completion."
+ :type '(integer :tag "prefix length"))
+
+(defcustom company-abort-manual-when-too-short nil
+ "If enabled, cancel a manually started completion when the prefix gets
+shorter than both `company-minimum-prefix-length' and the length of the
+prefix it was started from."
+ :type 'boolean
+ :package-version '(company . "0.8.0"))
+
+(defcustom company-abort-on-unique-match t
+ "If non-nil, typing a full unique match aborts completion.
+
+You can still invoke `company-complete' manually to run the
+`post-completion' handler, though.
+
+If it's nil, completion will remain active until you type a prefix that
+doesn't match anything or finish it manually, e.g. with RET."
+ :type 'boolean)
+
+(defcustom company-require-match 'company-explicit-action-p
+ "If enabled, disallow non-matching input.
+This can be a function do determine if a match is required.
+
+This can be overridden by the backend, if it returns t or `never' to
+`require-match'. `company-insertion-on-trigger' also takes precedence over
+this."
+ :type '(choice (const :tag "Off" nil)
+ (function :tag "Predicate function")
+ (const :tag "On, if user interaction took place"
+ 'company-explicit-action-p)
+ (const :tag "On" t)))
+
+(define-obsolete-variable-alias
+ 'company-auto-complete
+ 'company-insertion-on-trigger
+ "0.9.14")
+
+(define-obsolete-variable-alias
+ 'company-auto-commit
+ 'company-insertion-on-trigger
+ "0.9.14")
+
+(defcustom company-insertion-on-trigger nil
+ "If enabled, allow triggering insertion of the selected candidate.
+This can also be a predicate function, for example,
+`company-explicit-action-p'.
+
+See `company-insertion-triggers' for more details on how to define
+triggers."
+ :type '(choice (const :tag "Off" nil)
+ (function :tag "Predicate function")
+ (const :tag "On, if user interaction took place"
+ 'company-explicit-action-p)
+ (const :tag "On" t))
+ :package-version '(company . "0.9.14"))
+
+(define-obsolete-variable-alias
+ 'company-auto-complete-chars
+ 'company-insertion-triggers
+ "0.9.14")
+
+(define-obsolete-variable-alias
+ 'company-auto-commit-chars
+ 'company-insertion-triggers
+ "0.9.14")
+
+(defcustom company-insertion-triggers '(?\ ?\) ?.)
+ "Determine triggers for `company-insertion-on-trigger'.
+
+If this is a string, then each character in it can trigger insertion of the
+selected candidate. If it is a list of syntax description characters (see
+`modify-syntax-entry'), then characters with any of those syntaxes can act
+as triggers.
+
+This can also be a function, which is called with the new input. To
+trigger insertion, the function should return a non-nil value.
+
+Note that a character that is part of a valid completion never triggers
+insertion."
+ :type '(choice (string :tag "Characters")
+ (set :tag "Syntax"
+ (const :tag "Whitespace" ?\ )
+ (const :tag "Symbol" ?_)
+ (const :tag "Opening parentheses" ?\()
+ (const :tag "Closing parentheses" ?\))
+ (const :tag "Word constituent" ?w)
+ (const :tag "Punctuation." ?.)
+ (const :tag "String quote." ?\")
+ (const :tag "Paired delimiter." ?$)
+ (const :tag "Expression quote or prefix operator." ?\')
+ (const :tag "Comment starter." ?<)
+ (const :tag "Comment ender." ?>)
+ (const :tag "Character-quote." ?/)
+ (const :tag "Generic string fence." ?|)
+ (const :tag "Generic comment fence." ?!))
+ (function :tag "Predicate function"))
+ :package-version '(company . "0.9.14"))
+
+(defcustom company-idle-delay .2
+ "The idle delay in seconds until completion starts automatically.
+The prefix still has to satisfy `company-minimum-prefix-length' before that
+happens. The value of nil means no idle completion."
+ :type '(choice (const :tag "never (nil)" nil)
+ (const :tag "immediate (0)" 0)
+ (function :tag "Predicate function")
+ (number :tag "seconds")))
+
+(defcustom company-tooltip-idle-delay .5
+ "The idle delay in seconds until tooltip is shown when using
+`company-pseudo-tooltip-unless-just-one-frontend-with-delay'."
+ :type '(choice (const :tag "never (nil)" nil)
+ (const :tag "immediate (0)" 0)
+ (number :tag "seconds")))
+
+(defcustom company-begin-commands '(self-insert-command
+ org-self-insert-command
+ orgtbl-self-insert-command
+ c-scope-operator
+ c-electric-colon
+ c-electric-lt-gt
+ c-electric-slash)
+ "A list of commands after which idle completion is allowed.
+If this is t, it can show completions after any command except a few from a
+pre-defined list. See `company-idle-delay'.
+
+Alternatively, any command with a non-nil `company-begin' property is
+treated as if it was on this list."
+ :type '(choice (const :tag "Any command" t)
+ (const :tag "Self insert command" '(self-insert-command))
+ (repeat :tag "Commands" function))
+ :package-version '(company . "0.8.4"))
+
+(defcustom company-continue-commands '(not save-buffer save-some-buffers
+ save-buffers-kill-terminal
+ save-buffers-kill-emacs
+ completion-at-point)
+ "A list of commands that are allowed during completion.
+If this is t, or if `company-begin-commands' is t, any command is allowed.
+Otherwise, the value must be a list of symbols. If it starts with `not',
+the cdr is the list of commands that abort completion. Otherwise, all
+commands except those in that list, or in `company-begin-commands', or
+commands in the `company-' namespace, abort completion."
+ :type '(choice (const :tag "Any command" t)
+ (cons :tag "Any except"
+ (const not)
+ (repeat :tag "Commands" function))
+ (repeat :tag "Commands" function)))
+
+(defun company-custom--set-quick-access (option value)
+ "Re-bind quick-access key sequences on OPTION VALUE change."
+ (when (boundp 'company-active-map)
+ (company-keymap--unbind-quick-access company-active-map))
+ (when (boundp 'company-search-map)
+ (company-keymap--unbind-quick-access company-search-map))
+ (custom-set-default option value)
+ (when (boundp 'company-active-map)
+ (company-keymap--bind-quick-access company-active-map))
+ (when (boundp 'company-search-map)
+ (company-keymap--bind-quick-access company-search-map)))
+
+(defcustom company-quick-access-keys '("1" "2" "3" "4" "5" "6" "7" "8" "9" "0")
+ "Character strings used as a part of quick-access key sequences.
+To change this value without Customize interface, use `customize-set-variable'.
+
+To change the quick-access key sequences modifier, customize
+`company-quick-access-modifier'.
+
+If `company-show-quick-access' is non-nil, show quick-access hints
+beside the candidates."
+ :set #'company-custom--set-quick-access
+ :type '(choice
+ (const :tag "Digits" ("1" "2" "3" "4" "5" "6" "7" "8" "9" "0"))
+ (const :tag "QWERTY home row" ("a" "s" "d" "f" "g" "h" "j" "k" "l" ";"))
+ ;; TODO un-comment on removal of `M-n' `company--select-next-and-warn'.
+ ;; (const :tag "Dvorak home row" ("a" "o" "e" "u" "i" "d" "h" "t" "n" "s"))
+ (repeat :tag "User defined" string))
+ :package-version '(company . "0.9.14"))
+
+(defcustom company-quick-access-modifier 'meta
+ "Modifier key used for quick-access keys sequences.
+To change this value without Customize interface, use `customize-set-variable'.
+See `company-quick-access-keys' for more details."
+ :set #'company-custom--set-quick-access
+ :type '(choice (const :tag "Meta key" meta)
+ (const :tag "Super key" super)
+ (const :tag "Hyper key" hyper)
+ (const :tag "Control key" control))
+ :package-version '(company . "0.9.14"))
+
+(defun company-keymap--quick-access-modifier ()
+ "Return string representation of the `company-quick-access-modifier'."
+ (if-let ((modifier (assoc-default company-quick-access-modifier
+ '((meta . "M")
+ (super . "s")
+ (hyper . "H")
+ (control . "C")))))
+ modifier
+ (warn "company-quick-access-modifier value unknown: %S"
+ company-quick-access-modifier)
+ "M"))
+
+(defun company-keymap--unbind-quick-access (keymap)
+ (let ((modifier (company-keymap--quick-access-modifier)))
+ (dolist (key company-quick-access-keys)
+ (let ((key-seq (company-keymap--kbd-quick-access modifier key)))
+ (when (equal (lookup-key keymap key-seq) 'company-complete-quick-access)
+ (define-key keymap key-seq nil))))))
+
+(defun company-keymap--bind-quick-access (keymap)
+ (let ((modifier (company-keymap--quick-access-modifier)))
+ (dolist (key company-quick-access-keys)
+ (let ((key-seq (company-keymap--kbd-quick-access modifier key)))
+ (if (lookup-key keymap key-seq)
+ (warn "Key sequence %s already bound" (key-description key-seq))
+ (define-key keymap key-seq #'company-complete-quick-access))))))
+
+(defun company-keymap--kbd-quick-access (modifier key)
+ (kbd (format "%s-%s" modifier key)))
+
+(define-obsolete-variable-alias
+ 'company-show-numbers
+ 'company-show-quick-access
+ "0.9.14")
+
+(defcustom company-show-quick-access nil
+ "If non-nil, show quick-access hints beside the candidates.
+
+For a tooltip frontend, non-nil value enables a column with the hints
+on the right side of the tooltip, unless the configured value is `left'.
+
+To change the quick-access key bindings, customize `company-quick-access-keys'
+and `company-quick-access-modifier'.
+
+To change the shown quick-access hints, customize
+`company-quick-access-hint-function'."
+ :type '(choice (const :tag "off" nil)
+ (const :tag "left" left)
+ (const :tag "on" t)))
+
+(defcustom company-show-numbers-function nil
+ "Function called to get quick-access numbers for the first ten candidates.
+
+The function receives the candidate number (starting from 1) and should
+return a string prefixed with one space."
+ :type 'function)
+(make-obsolete-variable
+ 'company-show-numbers-function
+ "use `company-quick-access-hint-function' instead,
+but adjust the expected values appropriately."
+ "0.9.14")
+
+(defcustom company-quick-access-hint-function #'company-quick-access-hint-key
+ "Function called to get quick-access hints for the candidates.
+
+The function receives a candidate's 0-based number
+and should return a string.
+See `company-show-quick-access' for more details."
+ :type 'function)
+
+(defun company-quick-access-hint-key (candidate)
+ "Return a quick-access key for the CANDIDATE number.
+This is a default value of `company-quick-access-hint-function'."
+ (if company-show-numbers-function
+ (funcall company-show-numbers-function (1+ candidate))
+ (format "%s"
+ (if (< candidate (length company-quick-access-keys))
+ (nth candidate company-quick-access-keys)
+ ""))))
+
+(defcustom company-selection-wrap-around nil
+ "If enabled, selecting item before first or after last wraps around."
+ :type '(choice (const :tag "off" nil)
+ (const :tag "on" t)))
+
+(defcustom company-async-redisplay-delay 0.005
+ "Delay before redisplay when fetching candidates asynchronously.
+
+You might want to set this to a higher value if your backends respond
+quickly, to avoid redisplaying twice per each typed character."
+ :type 'number)
+
+(defvar company-async-wait 0.03
+ "Pause between checks to see if the value's been set when turning an
+asynchronous call into synchronous.")
+
+(defvar company-async-timeout 2
+ "Maximum wait time for a value to be set during asynchronous call.")
+
+;;; mode ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defvar company-mode-map (make-sparse-keymap)
+ "Keymap used by `company-mode'.")
+
+(defvar company-active-map
+ (let ((keymap (make-sparse-keymap)))
+ (define-key keymap "\e\e\e" 'company-abort)
+ (define-key keymap "\C-g" 'company-abort)
+ (define-key keymap (kbd "M-n") 'company--select-next-and-warn)
+ (define-key keymap (kbd "M-p") 'company--select-previous-and-warn)
+ (define-key keymap (kbd "C-n") 'company-select-next-or-abort)
+ (define-key keymap (kbd "C-p") 'company-select-previous-or-abort)
+ (define-key keymap (kbd "<down>") 'company-select-next-or-abort)
+ (define-key keymap (kbd "<up>") 'company-select-previous-or-abort)
+ (define-key keymap [remap scroll-up-command] 'company-next-page)
+ (define-key keymap [remap scroll-down-command] 'company-previous-page)
+ (define-key keymap [down-mouse-1] 'ignore)
+ (define-key keymap [down-mouse-3] 'ignore)
+ (define-key keymap [mouse-1] 'company-complete-mouse)
+ (define-key keymap [mouse-3] 'company-select-mouse)
+ (define-key keymap [up-mouse-1] 'ignore)
+ (define-key keymap [up-mouse-3] 'ignore)
+ (define-key keymap [return] 'company-complete-selection)
+ (define-key keymap (kbd "RET") 'company-complete-selection)
+ (define-key keymap [tab] 'company-complete-common)
+ (define-key keymap (kbd "TAB") 'company-complete-common)
+ (define-key keymap (kbd "<f1>") 'company-show-doc-buffer)
+ (define-key keymap (kbd "C-h") 'company-show-doc-buffer)
+ (define-key keymap "\C-w" 'company-show-location)
+ (define-key keymap "\C-s" 'company-search-candidates)
+ (define-key keymap "\C-\M-s" 'company-filter-candidates)
+ (company-keymap--bind-quick-access keymap)
+ keymap)
+ "Keymap that is enabled during an active completion.")
+
+(defvar company--disabled-backends nil)
+
+(defun company--select-next-and-warn (&optional arg)
+ (interactive "p")
+ (company--warn-changed-binding)
+ (company-select-next arg))
+
+(defun company--select-previous-and-warn (&optional arg)
+ (interactive "p")
+ (company--warn-changed-binding)
+ (company-select-previous arg))
+
+(defun company--warn-changed-binding ()
+ (interactive)
+ (run-with-idle-timer
+ 0.01 nil
+ (lambda ()
+ (message "Warning: default bindings are being changed to C-n and C-p"))))
+
+(defun company-init-backend (backend)
+ (and (symbolp backend)
+ (not (fboundp backend))
+ (ignore-errors (require backend nil t)))
+ (cond
+ ((symbolp backend)
+ (condition-case err
+ (progn
+ (funcall backend 'init)
+ (put backend 'company-init t))
+ (error
+ (put backend 'company-init 'failed)
+ (unless (memq backend company--disabled-backends)
+ (message "Company backend '%s' could not be initialized:\n%s"
+ backend (error-message-string err)))
+ (cl-pushnew backend company--disabled-backends)
+ nil)))
+ ;; No initialization for lambdas.
+ ((functionp backend) t)
+ (t ;; Must be a list.
+ (cl-dolist (b backend)
+ (unless (keywordp b)
+ (company-init-backend b))))))
+
+(defun company--maybe-init-backend (backend)
+ (or (not (symbolp backend))
+ (eq t (get backend 'company-init))
+ (unless (get backend 'company-init)
+ (company-init-backend backend))))
+
+(defcustom company-lighter-base "company"
+ "Base string to use for the `company-mode' lighter."
+ :type 'string
+ :package-version '(company . "0.8.10"))
+
+(defvar company-lighter '(" "
+ (company-candidates
+ (:eval
+ (if (consp company-backend)
+ (when company-selection
+ (company--group-lighter (nth company-selection
+ company-candidates)
+ company-lighter-base))
+ (symbol-name company-backend)))
+ company-lighter-base))
+ "Mode line lighter for Company.
+
+The value of this variable is a mode line template as in
+`mode-line-format'.")
+
+(put 'company-lighter 'risky-local-variable t)
+
+;;;###autoload
+(define-minor-mode company-mode
+ "\"complete anything\"; is an in-buffer completion framework.
+Completion starts automatically, depending on the values
+`company-idle-delay' and `company-minimum-prefix-length'.
+
+Completion can be controlled with the commands:
+`company-complete-common', `company-complete-selection', `company-complete',
+`company-select-next', `company-select-previous'. If these commands are
+called before `company-idle-delay', completion will also start.
+
+Completions can be searched with `company-search-candidates' or
+`company-filter-candidates'. These can be used while completion is
+inactive, as well.
+
+The completion data is retrieved using `company-backends' and displayed
+using `company-frontends'. If you want to start a specific backend, call
+it interactively or use `company-begin-backend'.
+
+By default, the completions list is sorted alphabetically, unless the
+backend chooses otherwise, or `company-transformers' changes it later.
+
+regular keymap (`company-mode-map'):
+
+\\{company-mode-map}
+keymap during active completions (`company-active-map'):
+
+\\{company-active-map}"
+ :lighter company-lighter
+ (if company-mode
+ (progn
+ (add-hook 'pre-command-hook 'company-pre-command nil t)
+ (add-hook 'post-command-hook 'company-post-command nil t)
+ (add-hook 'yas-keymap-disable-hook 'company--active-p nil t)
+ (mapc 'company-init-backend company-backends))
+ (remove-hook 'pre-command-hook 'company-pre-command t)
+ (remove-hook 'post-command-hook 'company-post-command t)
+ (remove-hook 'yas-keymap-disable-hook 'company--active-p t)
+ (company-cancel)
+ (kill-local-variable 'company-point)))
+
+(defcustom company-global-modes t
+ "Modes for which `company-mode' mode is turned on by `global-company-mode'.
+If nil, means no modes. If t, then all major modes have it turned on.
+If a list, it should be a list of `major-mode' symbol names for which
+`company-mode' should be automatically turned on. The sense of the list is
+negated if it begins with `not'. For example:
+ (c-mode c++-mode)
+means that `company-mode' is turned on for buffers in C and C++ modes only.
+ (not message-mode)
+means that `company-mode' is always turned on except in `message-mode' buffers."
+ :type '(choice (const :tag "none" nil)
+ (const :tag "all" t)
+ (set :menu-tag "mode specific" :tag "modes"
+ :value (not)
+ (const :tag "Except" not)
+ (repeat :inline t (symbol :tag "mode")))))
+
+;;;###autoload
+(define-globalized-minor-mode global-company-mode company-mode company-mode-on)
+
+(defun company-mode-on ()
+ (when (and (not (or noninteractive (eq (aref (buffer-name) 0) ?\s)))
+ (cond ((eq company-global-modes t)
+ t)
+ ((eq (car-safe company-global-modes) 'not)
+ (not (memq major-mode (cdr company-global-modes))))
+ (t (memq major-mode company-global-modes))))
+ (company-mode 1)))
+
+(defsubst company-assert-enabled ()
+ (unless company-mode
+ (company-uninstall-map)
+ (user-error "Company not enabled")))
+
+;;; keymaps ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defvar-local company-my-keymap nil)
+
+(defvar company-emulation-alist '((t . nil)))
+
+(defun company-enable-overriding-keymap (keymap)
+ (company-uninstall-map)
+ (setq company-my-keymap keymap))
+
+(defun company-ensure-emulation-alist ()
+ (unless (eq 'company-emulation-alist (car emulation-mode-map-alists))
+ (setq emulation-mode-map-alists
+ (cons 'company-emulation-alist
+ (delq 'company-emulation-alist emulation-mode-map-alists)))))
+
+(defun company-install-map ()
+ (unless (or (cdar company-emulation-alist)
+ (null company-my-keymap))
+ (setf (cdar company-emulation-alist) company-my-keymap)))
+
+(defun company-uninstall-map ()
+ (setf (cdar company-emulation-alist) nil))
+
+(defun company--company-command-p (keys)
+ "Checks if the keys are part of company's overriding keymap"
+ (or (equal [company-dummy-event] keys)
+ (commandp (lookup-key company-my-keymap keys))))
+
+;; To avoid warnings in Emacs < 26.
+(declare-function line-number-display-width "indent.c")
+
+(defun company--posn-col-row (posn)
+ (let ((col (car (posn-col-row posn)))
+ ;; `posn-col-row' doesn't work well with lines of different height.
+ ;; `posn-actual-col-row' doesn't handle multiple-width characters.
+ (row (cdr (or (posn-actual-col-row posn)
+ ;; When position is non-visible for some reason.
+ (posn-col-row posn)))))
+ (when (bound-and-true-p display-line-numbers)
+ (cl-decf col (+ 2 (line-number-display-width))))
+ (cons (+ col (window-hscroll)) row)))
+
+(defun company--col-row (&optional pos)
+ (company--posn-col-row (posn-at-point pos)))
+
+(defun company--row (&optional pos)
+ (cdr (company--col-row pos)))
+
+;;; backends ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defvar-local company-backend nil)
+
+(defun company-grab (regexp &optional expression limit)
+ (when (looking-back regexp limit)
+ (or (match-string-no-properties (or expression 0)) "")))
+
+(defun company-grab-line (regexp &optional expression)
+ "Return a match string for REGEXP if it matches text before point.
+If EXPRESSION is non-nil, return the match string for the respective
+parenthesized expression in REGEXP.
+Matching is limited to the current line."
+ (let ((inhibit-field-text-motion t))
+ (company-grab regexp expression (point-at-bol))))
+
+(defun company-grab-symbol ()
+ "If point is at the end of a symbol, return it.
+Otherwise, if point is not inside a symbol, return an empty string."
+ (if (looking-at "\\_>")
+ (buffer-substring (point) (save-excursion (skip-syntax-backward "w_")
+ (point)))
+ (unless (and (char-after) (memq (char-syntax (char-after)) '(?w ?_)))
+ "")))
+
+(defun company-grab-word ()
+ "If point is at the end of a word, return it.
+Otherwise, if point is not inside a symbol, return an empty string."
+ (if (looking-at "\\>")
+ (buffer-substring (point) (save-excursion (skip-syntax-backward "w")
+ (point)))
+ (unless (and (char-after) (eq (char-syntax (char-after)) ?w))
+ "")))
+
+(defun company-grab-symbol-cons (idle-begin-after-re &optional max-len)
+ "Return a string SYMBOL or a cons (SYMBOL . t).
+SYMBOL is as returned by `company-grab-symbol'. If the text before point
+matches IDLE-BEGIN-AFTER-RE, return it wrapped in a cons."
+ (let ((symbol (company-grab-symbol)))
+ (when symbol
+ (save-excursion
+ (forward-char (- (length symbol)))
+ (if (looking-back idle-begin-after-re (if max-len
+ (- (point) max-len)
+ (line-beginning-position)))
+ (cons symbol t)
+ symbol)))))
+
+(defun company-in-string-or-comment ()
+ "Return non-nil if point is within a string or comment."
+ (let ((ppss (syntax-ppss)))
+ (or (car (setq ppss (nthcdr 3 ppss)))
+ (car (setq ppss (cdr ppss)))
+ (nth 3 ppss))))
+
+(defun company-call-backend (&rest args)
+ (company--force-sync #'company-call-backend-raw args company-backend))
+
+(defun company--force-sync (fun args backend)
+ (let ((value (apply fun args)))
+ (if (not (eq (car-safe value) :async))
+ value
+ (let ((res 'trash)
+ (start (time-to-seconds)))
+ (funcall (cdr value)
+ (lambda (result) (setq res result)))
+ (while (eq res 'trash)
+ (if (> (- (time-to-seconds) start) company-async-timeout)
+ (error "Company: backend %s async timeout with args %s"
+ backend args)
+ ;; XXX: Reusing the trick from company--fetch-candidates here
+ ;; doesn't work well: sit-for isn't a good fit when we want to
+ ;; ignore pending input (results in too many calls).
+ ;; FIXME: We should deal with this by standardizing on a kind of
+ ;; Future object that knows how to sync itself. In most cases (but
+ ;; not all), by calling accept-process-output, probably.
+ (sleep-for company-async-wait)))
+ res))))
+
+(defun company-call-backend-raw (&rest args)
+ (condition-case-unless-debug err
+ (if (functionp company-backend)
+ (apply company-backend args)
+ (apply #'company--multi-backend-adapter company-backend args))
+ (user-error (user-error
+ "Company: backend %s user-error: %s"
+ company-backend (error-message-string err)))
+ (error (error "Company: backend %s error \"%s\" with args %s"
+ company-backend (error-message-string err) args))))
+
+(defun company--multi-backend-adapter (backends command &rest args)
+ (let ((backends (cl-loop for b in backends
+ when (or (keywordp b)
+ (company--maybe-init-backend b))
+ collect b))
+ (separate (memq :separate backends)))
+
+ (when (eq command 'prefix)
+ (setq backends (butlast backends (length (member :with backends)))))
+
+ (setq backends (cl-delete-if #'keywordp backends))
+
+ (pcase command
+ (`candidates
+ (company--multi-backend-adapter-candidates backends (car args) separate))
+ (`sorted separate)
+ (`duplicates (not separate))
+ ((or `prefix `ignore-case `no-cache `require-match)
+ (let (value)
+ (cl-dolist (backend backends)
+ (when (setq value (company--force-sync
+ backend (cons command args) backend))
+ (when (and (eq command 'ignore-case)
+ (eq value 'keep-prefix))
+ (setq value t))
+ (cl-return value)))))
+ (_
+ (let ((arg (car args)))
+ (when (> (length arg) 0)
+ (let ((backend (or (get-text-property 0 'company-backend arg)
+ (car backends))))
+ (apply backend command args))))))))
+
+(defun company--multi-backend-adapter-candidates (backends prefix separate)
+ (let ((pairs (cl-loop for backend in backends
+ when (equal (company--prefix-str
+ (let ((company-backend backend))
+ (company-call-backend 'prefix)))
+ prefix)
+ collect (cons (funcall backend 'candidates prefix)
+ (company--multi-candidates-mapper
+ backend
+ separate
+ ;; Small perf optimization: don't tag the
+ ;; candidates received from the first
+ ;; backend in the group.
+ (not (eq backend (car backends))))))))
+ (company--merge-async pairs (lambda (values) (apply #'append values)))))
+
+(defun company--multi-candidates-mapper (backend separate tag)
+ (lambda (candidates)
+ (when separate
+ (let ((company-backend backend))
+ (setq candidates
+ (company--preprocess-candidates candidates))))
+ (when tag
+ (setq candidates
+ (mapcar
+ (lambda (str)
+ (propertize str 'company-backend backend))
+ candidates)))
+ candidates))
+
+(defun company--merge-async (pairs merger)
+ (let ((async (cl-loop for pair in pairs
+ thereis
+ (eq :async (car-safe (car pair))))))
+ (if (not async)
+ (funcall merger (cl-loop for (val . mapper) in pairs
+ collect (funcall mapper val)))
+ (cons
+ :async
+ (lambda (callback)
+ (let* (lst
+ (pending (mapcar #'car pairs))
+ (finisher (lambda ()
+ (unless pending
+ (funcall callback
+ (funcall merger
+ (nreverse lst)))))))
+ (dolist (pair pairs)
+ (push nil lst)
+ (let* ((cell lst)
+ (val (car pair))
+ (mapper (cdr pair))
+ (this-finisher (lambda (res)
+ (setq pending (delq val pending))
+ (setcar cell (funcall mapper res))
+ (funcall finisher))))
+ (if (not (eq :async (car-safe val)))
+ (funcall this-finisher val)
+ (let ((fetcher (cdr val)))
+ (funcall fetcher this-finisher)))))))))))
+
+(defun company--prefix-str (prefix)
+ (or (car-safe prefix) prefix))
+
+;;; completion mechanism ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defvar-local company-prefix nil)
+
+(defvar-local company-candidates nil)
+
+(defvar-local company-candidates-length nil)
+
+(defvar-local company-candidates-cache nil)
+
+(defvar-local company-candidates-predicate nil)
+
+(defvar-local company-common nil)
+
+(defvar company-selection-default 0
+ "The default value for `company-selection'.")
+(defvar-local company-selection company-selection-default)
+
+(defvar-local company-selection-changed nil)
+
+(defvar-local company--manual-action nil
+ "Non-nil, if manual completion took place.")
+
+(defvar-local company--manual-prefix nil)
+
+(defvar-local company--point-max nil)
+
+(defvar-local company-point nil)
+
+(defvar company-timer nil)
+(defvar company-tooltip-timer nil)
+
+(defsubst company-strip-prefix (str)
+ (substring str (length company-prefix)))
+
+(defun company--insert-candidate (candidate)
+ (when (> (length candidate) 0)
+ (setq candidate (substring-no-properties candidate))
+ ;; XXX: Return value we check here is subject to change.
+ (if (eq (company-call-backend 'ignore-case) 'keep-prefix)
+ (insert (company-strip-prefix candidate))
+ (unless (equal company-prefix candidate)
+ (delete-region (- (point) (length company-prefix)) (point))
+ (insert candidate)))))
+
+(defmacro company-with-candidate-inserted (candidate &rest body)
+ "Evaluate BODY with CANDIDATE temporarily inserted.
+This is a tool for backends that need candidates inserted before they
+can retrieve meta-data for them."
+ (declare (indent 1))
+ `(let ((inhibit-modification-hooks t)
+ (inhibit-point-motion-hooks t)
+ (modified-p (buffer-modified-p)))
+ (company--insert-candidate ,candidate)
+ (unwind-protect
+ (progn ,@body)
+ (delete-region company-point (point))
+ (set-buffer-modified-p modified-p))))
+
+(defun company-explicit-action-p ()
+ "Return whether explicit completion action was taken by the user."
+ (or company--manual-action
+ company-selection-changed))
+
+(defun company-reformat (candidate)
+ ;; company-ispell needs this, because the results are always lower-case
+ ;; It's mory efficient to fix it only when they are displayed.
+ ;; FIXME: Adopt the current text's capitalization instead?
+ (if (eq (company-call-backend 'ignore-case) 'keep-prefix)
+ (let ((prefix (company--clean-string company-prefix)))
+ (concat prefix (substring candidate (length prefix))))
+ candidate))
+
+(defun company--should-complete ()
+ (and (eq company-idle-delay 'now)
+ (not (or buffer-read-only
+ overriding-local-map))
+ ;; Check if in the middle of entering a key combination.
+ (or (equal (this-command-keys-vector) [])
+ (not (keymapp (key-binding (this-command-keys-vector)))))
+ (not (and transient-mark-mode mark-active))))
+
+(defun company--should-continue ()
+ (or (eq t company-begin-commands)
+ (eq t company-continue-commands)
+ (if (eq 'not (car company-continue-commands))
+ (not (memq this-command (cdr company-continue-commands)))
+ (or (memq this-command company-begin-commands)
+ (memq this-command company-continue-commands)
+ (and (symbolp this-command)
+ (string-match-p "\\`company-" (symbol-name this-command)))))))
+
+(defun company-call-frontends (command)
+ (cl-loop for frontend in company-frontends collect
+ (condition-case-unless-debug err
+ (funcall frontend command)
+ (error (error "Company: frontend %s error \"%s\" on command %s"
+ frontend (error-message-string err) command)))))
+
+(defun company-set-selection (selection &optional force-update)
+ "Set SELECTION for company candidates.
+This will update `company-selection' and related variable.
+Only update when the current selection is changed, but optionally always
+update if FORCE-UPDATE."
+ (when selection
+ (let* ((offset (if company-selection-default 0 1))
+ (company-candidates-length
+ (+ company-candidates-length offset)))
+ (setq selection (+ selection offset))
+ (setq selection
+ (if company-selection-wrap-around
+ (mod selection company-candidates-length)
+ (max 0 (min (1- company-candidates-length) selection))))
+ (setq selection (unless (< selection offset)
+ (- selection offset)))))
+ (when (or force-update (not (equal selection company-selection)))
+ (setq company-selection selection
+ company-selection-changed t)
+ (company-call-frontends 'update)))
+
+(defun company--group-lighter (candidate base)
+ (let ((backend (or (get-text-property 0 'company-backend candidate)
+ (cl-some (lambda (x) (and (not (keywordp x)) x))
+ company-backend))))
+ (when (and backend (symbolp backend))
+ (let ((name (replace-regexp-in-string "company-\\|-company" ""
+ (symbol-name backend))))
+ (format "%s-<%s>" base name)))))
+
+(defun company-update-candidates (candidates)
+ (setq company-candidates-length (length candidates))
+ (if company-selection-changed
+ ;; Try to restore the selection
+ (let ((selected (and company-selection
+ (nth company-selection company-candidates))))
+ (setq company-candidates candidates)
+ (when selected
+ (setq company-selection 0)
+ (catch 'found
+ (while candidates
+ (let ((candidate (pop candidates)))
+ (when (and (string= candidate selected)
+ (equal (company-call-backend 'annotation candidate)
+ (company-call-backend 'annotation selected)))
+ (throw 'found t)))
+ (cl-incf company-selection))
+ (setq company-selection company-selection-default
+ company-selection-changed nil))))
+ (setq company-selection company-selection-default
+ company-candidates candidates))
+ ;; Calculate common.
+ (let ((completion-ignore-case (company-call-backend 'ignore-case)))
+ ;; We want to support non-prefix completion, so filtering is the
+ ;; responsibility of each respective backend, not ours.
+ ;; On the other hand, we don't want to replace non-prefix input in
+ ;; `company-complete-common', unless there's only one candidate.
+ (setq company-common
+ (if (cdr company-candidates)
+ (let ((common (try-completion "" company-candidates)))
+ (when (string-prefix-p company-prefix common
+ completion-ignore-case)
+ common))
+ (car company-candidates)))))
+
+(defun company-calculate-candidates (prefix ignore-case)
+ (let ((candidates (cdr (assoc prefix company-candidates-cache))))
+ (or candidates
+ (when company-candidates-cache
+ (let ((len (length prefix))
+ (completion-ignore-case ignore-case)
+ prev)
+ (cl-dotimes (i (1+ len))
+ (when (setq prev (cdr (assoc (substring prefix 0 (- len i))
+ company-candidates-cache)))
+ (setq candidates (all-completions prefix prev))
+ (cl-return t)))))
+ ;; No cache match, call the backend.
+ (let ((refresh-timer (run-with-timer company-async-redisplay-delay
+ nil #'company--sneaky-refresh)))
+ (setq candidates (company--preprocess-candidates
+ (company--fetch-candidates prefix)))
+ ;; If the backend is synchronous, no chance for the timer to run.
+ (cancel-timer refresh-timer)
+ ;; Save in cache.
+ (push (cons prefix candidates) company-candidates-cache)))
+ ;; Only now apply the predicate and transformers.
+ (company--postprocess-candidates candidates)))
+
+(defun company--unique-match-p (candidates prefix ignore-case)
+ (and candidates
+ (not (cdr candidates))
+ (eq t (compare-strings (car candidates) nil nil
+ prefix nil nil ignore-case))))
+
+(defun company--fetch-candidates (prefix)
+ (let* ((non-essential (not (company-explicit-action-p)))
+ (inhibit-redisplay t)
+ (c (if (or company-selection-changed
+ ;; FIXME: This is not ideal, but we have not managed to deal
+ ;; with these situations in a better way yet.
+ (company-require-match-p))
+ (company-call-backend 'candidates prefix)
+ (company-call-backend-raw 'candidates prefix))))
+ (if (not (eq (car c) :async))
+ c
+ (let ((res 'none))
+ (funcall
+ (cdr c)
+ (lambda (candidates)
+ (when (eq res 'none)
+ (push 'company-foo unread-command-events))
+ (setq res candidates)))
+ (if (company--flyspell-workaround-p)
+ (while (and (eq res 'none)
+ (not (input-pending-p)))
+ (sleep-for company-async-wait))
+ (while (and (eq res 'none)
+ (sit-for 0.5 t))))
+ (while (member (car unread-command-events)
+ '(company-foo (t . company-foo)))
+ (pop unread-command-events))
+ (prog1
+ (and (consp res) res)
+ (setq res 'exited))))))
+
+(defun company--sneaky-refresh ()
+ (when company-candidates (company-call-frontends 'unhide))
+ (let (inhibit-redisplay)
+ (redisplay))
+ (when company-candidates (company-call-frontends 'pre-command)))
+
+(defun company--flyspell-workaround-p ()
+ ;; https://debbugs.gnu.org/23980
+ (and (bound-and-true-p flyspell-mode)
+ (version< emacs-version "27")))
+
+(defun company--preprocess-candidates (candidates)
+ (cl-assert (cl-every #'stringp candidates))
+ (unless (company-call-backend 'sorted)
+ (setq candidates (sort candidates 'string<)))
+ (when (company-call-backend 'duplicates)
+ (company--strip-duplicates candidates))
+ candidates)
+
+(defun company--postprocess-candidates (candidates)
+ (when (or company-candidates-predicate company-transformers)
+ (setq candidates (copy-sequence candidates)))
+ (when company-candidates-predicate
+ (setq candidates (cl-delete-if-not company-candidates-predicate candidates)))
+ (company--transform-candidates candidates))
+
+(defun company--strip-duplicates (candidates)
+ (let ((c2 candidates)
+ (extras 'unk))
+ (while c2
+ (setcdr c2
+ (let ((str (pop c2)))
+ (while (let ((str2 (car c2)))
+ (if (not (equal str str2))
+ (progn
+ (setq extras 'unk)
+ nil)
+ (when (eq extras 'unk)
+ (setq extras (list (cons (company-call-backend
+ 'annotation str)
+ (company-call-backend
+ 'kind str)))))
+ (let ((extra2 (cons (company-call-backend
+ 'annotation str2)
+ (company-call-backend
+ 'kind str2))))
+ (if (member extra2 extras)
+ t
+ (push extra2 extras)
+ nil))))
+ (pop c2))
+ c2)))))
+
+(defun company--transform-candidates (candidates)
+ (let ((c candidates))
+ (dolist (tr company-transformers)
+ (setq c (funcall tr c)))
+ c))
+
+(defcustom company-occurrence-weight-function
+ #'company-occurrence-prefer-closest-above
+ "Function to weigh matches in `company-sort-by-occurrence'.
+It's called with three arguments: cursor position, the beginning and the
+end of the match."
+ :type '(choice
+ (const :tag "First above point, then below point"
+ company-occurrence-prefer-closest-above)
+ (const :tag "Prefer closest in any direction"
+ company-occurrence-prefer-any-closest)))
+
+(defvar company-vscode-icons-mapping
+ '((array . "symbol-array.svg")
+ (boolean . "symbol-boolean.svg")
+ (class . "symbol-class.svg")
+ (color . "symbol-color.svg")
+ (constant . "symbol-constant.svg")
+ (constructor . "symbol-method.svg")
+ (enum-member . "symbol-enumerator-member.svg")
+ (enum . "symbol-enumerator.svg")
+ (event . "symbol-event.svg")
+ (field . "symbol-field.svg")
+ (file . "symbol-file.svg")
+ (folder . "folder.svg")
+ (interface . "symbol-interface.svg")
+ (keyword . "symbol-keyword.svg")
+ (method . "symbol-method.svg")
+ (function . "symbol-method.svg")
+ (module . "symbol-namespace.svg")
+ (numeric . "symbol-numeric.svg")
+ (operator . "symbol-operator.svg")
+ (property . "symbol-property.svg")
+ (reference . "references.svg")
+ (snippet . "symbol-snippet.svg")
+ (string . "symbol-string.svg")
+ (struct . "symbol-structure.svg")
+ (text . "symbol-key.svg")
+ (type-parameter . "symbol-parameter.svg")
+ (unit . "symbol-ruler.svg")
+ (value . "symbol-enumerator.svg")
+ (variable . "symbol-variable.svg")
+ (t . "symbol-misc.svg")))
+
+(defconst company-icons-root
+ (file-name-as-directory
+ (expand-file-name "icons"
+ (file-name-directory (or load-file-name buffer-file-name)))))
+
+(defcustom company-icon-size '(auto-scale . 16)
+ "Size of icons indicating completion kind in the popup."
+ :type '(choice (integer :tag "Size in pixels" :value 16)
+ (cons :tag "Size in pixels, scaled 2x on HiDPI screens"
+ (const auto-scale)
+ (integer :value 16))))
+
+(defcustom company-icon-margin 2
+ "Width of the margin that shows the icons, in characters."
+ :type 'integer)
+
+(defun company--render-icons-margin (icon-mapping root-dir candidate selected)
+ (if-let ((ws (window-system))
+ (candidate candidate)
+ (kind (company-call-backend 'kind candidate))
+ (icon-file (or (alist-get kind icon-mapping)
+ (alist-get t icon-mapping))))
+ (let* ((bkg (face-attribute (if selected
+ 'company-tooltip-selection
+ 'company-tooltip)
+ :background))
+ (dfw (default-font-width))
+ (icon-size (cond
+ ((integerp company-icon-size)
+ company-icon-size)
+ ;; XXX: Also consider smooth scaling, e.g. using
+ ;; (aref (font-info (face-font 'default)) 2)
+ ((and (consp company-icon-size)
+ (eq 'auto-scale (car company-icon-size)))
+ (let ((base-size (cdr company-icon-size))
+ (dfh (default-font-height)))
+ (min
+ (if (> dfh (* 2 base-size))
+ (* 2 base-size)
+ base-size)
+ (* company-icon-margin dfw))))))
+ (spec (list 'image
+ :file (expand-file-name icon-file root-dir)
+ :type 'svg
+ :width icon-size
+ :height icon-size
+ :ascent 'center
+ :background (unless (eq bkg 'unspecified)
+ bkg)))
+ (spacer-px-width (- (* company-icon-margin dfw) icon-size)))
+ (concat
+ (propertize " " 'display spec)
+ (propertize (company-space-string (1- company-icon-margin))
+ 'display `(space . (:width (,spacer-px-width))))))
+ nil))
+
+(defun company-vscode-dark-icons-margin (candidate selected)
+ "Margin function which returns icons from vscode's dark theme."
+ (company--render-icons-margin company-vscode-icons-mapping
+ (expand-file-name "vscode-dark" company-icons-root)
+ candidate
+ selected))
+
+(defun company-vscode-light-icons-margin (candidate selected)
+ "Margin function which returns icons from vscode's light theme."
+ (company--render-icons-margin company-vscode-icons-mapping
+ (expand-file-name "vscode-light" company-icons-root)
+ candidate
+ selected))
+
+(defcustom company-text-icons-mapping
+ '((array "a" font-lock-type-face)
+ (boolean "b" font-lock-builtin-face)
+ (class "c" font-lock-type-face)
+ (color "#" success)
+ (constant "c" font-lock-constant-face)
+ (constructor "c" font-lock-function-name-face)
+ (enum-member "e" font-lock-builtin-face)
+ (enum "e" font-lock-builtin-face)
+ (field "f" font-lock-variable-name-face)
+ (file "f" font-lock-string-face)
+ (folder "d" font-lock-doc-face)
+ (interface "i" font-lock-type-face)
+ (keyword "k" font-lock-keyword-face)
+ (method "m" font-lock-function-name-face)
+ (function "f" font-lock-function-name-face)
+ (module "{" font-lock-type-face)
+ (numeric "n" font-lock-builtin-face)
+ (operator "o" font-lock-comment-delimiter-face)
+ (property "p" font-lock-variable-name-face)
+ (reference "r" font-lock-doc-face)
+ (snippet "S" font-lock-string-face)
+ (string "s" font-lock-string-face)
+ (struct "%" font-lock-variable-name-face)
+ (text "w" shadow)
+ (type-parameter "p" font-lock-type-face)
+ (unit "u" shadow)
+ (value "v" font-lock-builtin-face)
+ (variable "v" font-lock-variable-name-face)
+ (t "." shadow))
+ "Mapping of the text icons.
+The format should be an alist of (KIND . CONF) where CONF is a list of the
+form (ICON FG BG) which is used to propertize the icon to be shown for a
+candidate of kind KIND. FG can either be color string or a face from which
+we can get a color string (using the :foreground face-property). BG must be
+of the same form as FG or a cons cell of (BG . BG-WHEN-SELECTED) which each
+should be of the same form as FG.
+
+The only mandatory element in CONF is ICON, you can omit both the FG and BG
+fields without issue.
+
+When BG is omitted and `company-text-icons-add-background' is non-nil, a BG
+color is generated using a gradient between the active tooltip color and
+the FG color."
+ :type 'list)
+
+(defcustom company-text-face-extra-attributes '(:weight bold)
+ "Additional attributes to add to text/dot icons faces.
+If non-nil, an anonymous face is generated.
+
+Affects `company-text-icons-margin' and `company-dot-icons-margin'."
+ :type 'list)
+
+(defcustom company-text-icons-format " %s "
+ "Format string for printing the text icons."
+ :type 'string)
+
+(defcustom company-text-icons-add-background nil
+ "Generate a background color for text/dot icons when none is given.
+See `company-text-icons-mapping'."
+ :type 'boolean)
+
+(defun company-text-icons-margin (candidate selected)
+ "Margin function which returns unicode icons."
+ (when-let ((candidate candidate)
+ (kind (company-call-backend 'kind candidate))
+ (conf (or (alist-get kind company-text-icons-mapping)
+ (alist-get t company-text-icons-mapping))))
+ (cl-destructuring-bind (icon &optional fg bg) conf
+ (propertize
+ (format company-text-icons-format icon)
+ 'face
+ (company-text-icons--face fg bg selected)))))
+
+(declare-function color-rgb-to-hex "color")
+(declare-function color-gradient "color")
+
+(defun company-text-icons--extract-property (face property)
+ "Try to extract PROPERTY from FACE.
+If FACE isn't a valid face return FACE as is. If FACE doesn't have
+PROPERTY return nil."
+ (if (facep face)
+ (let ((value (face-attribute face property)))
+ (unless (eq value 'unspecified)
+ value))
+ face))
+
+(defun company-text-icons--face (fg bg selected)
+ (let ((fg-color (company-text-icons--extract-property fg :foreground)))
+ `(,@company-text-face-extra-attributes
+ ,@(and fg-color
+ (list :foreground fg-color))
+ ,@(let* ((bg-is-cons (consp bg))
+ (bg (if bg-is-cons (if selected (cdr bg) (car bg)) bg))
+ (bg-color (company-text-icons--extract-property bg :background))
+ (tooltip-bg-color (company-text-icons--extract-property
+ (if selected
+ 'company-tooltip-selection
+ 'company-tooltip)
+ :background)))
+ (cond
+ ((and company-text-icons-add-background selected
+ (not bg-is-cons) bg-color tooltip-bg-color)
+ ;; Adjust the coloring of the background when *selected* but user hasn't
+ ;; specified an alternate background color for selected item icons.
+ (list :background
+ (apply #'color-rgb-to-hex
+ (nth 0 (color-gradient (color-name-to-rgb tooltip-bg-color)
+ (color-name-to-rgb bg-color)
+ 2)))))
+ (bg
+ ;; When background is configured we use it as is, even if it doesn't
+ ;; constrast well with other candidates when selected.
+ (and bg-color
+ (list :background bg-color)))
+ ((and company-text-icons-add-background fg-color tooltip-bg-color)
+ ;; Lastly attempt to generate a background from the foreground.
+ (list :background
+ (apply #'color-rgb-to-hex
+ (nth 0 (color-gradient (color-name-to-rgb tooltip-bg-color)
+ (color-name-to-rgb fg-color)
+ 10))))))))))
+
+(defcustom company-dot-icons-format "● "
+ "Format string for `company-dot-icons-margin'."
+ :type 'string)
+
+(defun company-dot-icons-margin (candidate selected)
+ "Margin function that uses a colored dot to display completion kind."
+ (when-let ((kind (company-call-backend 'kind candidate))
+ (conf (or (assoc-default kind company-text-icons-mapping)
+ (assoc-default t company-text-icons-mapping))))
+ (cl-destructuring-bind (_icon &optional fg bg) conf
+ (propertize company-dot-icons-format
+ 'face
+ (company-text-icons--face fg bg selected)))))
+
+(defun company-detect-icons-margin (candidate selected)
+ "Margin function which picks the appropriate icon set automatically."
+ (if (and (display-graphic-p)
+ (image-type-available-p 'svg))
+ (cl-case (frame-parameter nil 'background-mode)
+ ('light (company-vscode-light-icons-margin candidate selected))
+ (t (company-vscode-dark-icons-margin candidate selected)))
+ (company-text-icons-margin candidate selected)))
+
+(defcustom company-format-margin-function #'company-detect-icons-margin
+ "Function to format the margin.
+It accepts 2 params `candidate' and `selected' and can be used for
+inserting prefix/image before the completion items. Typically, the
+functions call the backends with `kind' and then insert the appropriate
+image for the returned kind image. Function is called with (nil nil) to get
+the default margin."
+ :type '(choice
+ (const :tag "Disabled" nil)
+ (const :tag "Detect icons theme base on conditions" company-detect-icons-margin)
+ (const :tag "Text characters as icons" company-text-icons-margin)
+ (const :tag "Colored dots as icons" company-dot-icons-margin)
+ (const :tag "VScode dark icons theme" company-vscode-dark-icons-margin)
+ (const :tag "VScode light icons theme" company-vscode-light-icons-margin)
+ (function :tag "Custom icon function.")))
+
+(defun company-occurrence-prefer-closest-above (pos match-beg match-end)
+ "Give priority to the matches above point, then those below point."
+ (if (< match-beg pos)
+ (- pos match-end)
+ (- match-beg (window-start))))
+
+(defun company-occurrence-prefer-any-closest (pos _match-beg match-end)
+ "Give priority to the matches closest to the point."
+ (abs (- pos match-end)))
+
+(defun company-sort-by-occurrence (candidates)
+ "Sort CANDIDATES according to their occurrences.
+Searches for each in the currently visible part of the current buffer and
+prioritizes the matches according to `company-occurrence-weight-function'.
+The rest of the list is appended unchanged.
+Keywords and function definition names are ignored."
+ (let* ((w-start (window-start))
+ (w-end (window-end))
+ (start-point (point))
+ occurs
+ (noccurs
+ (save-excursion
+ (cl-delete-if
+ (lambda (candidate)
+ (goto-char w-start)
+ (when (and (not (equal candidate ""))
+ (search-forward candidate w-end t)
+ ;; ^^^ optimize for large lists where most elements
+ ;; won't have a match.
+ (catch 'done
+ (goto-char (1- start-point))
+ (while (search-backward candidate w-start t)
+ (when (save-match-data
+ (company--occurrence-predicate))
+ (throw 'done t)))
+ (goto-char start-point)
+ (while (search-forward candidate w-end t)
+ (when (save-match-data
+ (company--occurrence-predicate))
+ (throw 'done t)))))
+ (push
+ (cons candidate
+ (funcall company-occurrence-weight-function
+ start-point
+ (match-beginning 0)
+ (match-end 0)))
+ occurs)
+ t))
+ candidates))))
+ (nconc
+ (mapcar #'car (sort occurs (lambda (e1 e2) (<= (cdr e1) (cdr e2)))))
+ noccurs)))
+
+(defun company--occurrence-predicate ()
+ (defvar comint-last-prompt)
+ (let ((beg (match-beginning 0))
+ (end (match-end 0))
+ (comint-last-prompt (bound-and-true-p comint-last-prompt)))
+ (save-excursion
+ (goto-char end)
+ ;; Workaround for python-shell-completion-at-point's behavior:
+ ;; https://github.com/company-mode/company-mode/issues/759
+ ;; https://github.com/company-mode/company-mode/issues/549
+ (when (derived-mode-p 'inferior-python-mode)
+ (let ((lbp (line-beginning-position)))
+ (setq comint-last-prompt (cons lbp lbp))))
+ (and (not (memq (get-text-property (1- (point)) 'face)
+ '(font-lock-function-name-face
+ font-lock-keyword-face)))
+ (let ((prefix (company--prefix-str
+ (company-call-backend 'prefix))))
+ (and (stringp prefix)
+ (= (length prefix) (- end beg))))))))
+
+(defun company-sort-by-backend-importance (candidates)
+ "Sort CANDIDATES as two priority groups.
+If `company-backend' is a function, do nothing. If it's a list, move
+candidates from backends before keyword `:with' to the front. Candidates
+from the rest of the backends in the group, if any, will be left at the end."
+ (if (functionp company-backend)
+ candidates
+ (let ((low-priority (cdr (memq :with company-backend))))
+ (if (null low-priority)
+ candidates
+ (sort candidates
+ (lambda (c1 c2)
+ (and
+ (let ((b2 (get-text-property 0 'company-backend c2)))
+ (and b2 (memq b2 low-priority)))
+ (let ((b1 (get-text-property 0 'company-backend c1)))
+ (or (not b1) (not (memq b1 low-priority)))))))))))
+
+(defun company-sort-prefer-same-case-prefix (candidates)
+ "Prefer CANDIDATES with the exact same prefix.
+If a backend returns case insensitive matches, candidates with the an exact
+prefix match (same case) will be prioritized."
+ (cl-loop for candidate in candidates
+ if (string-prefix-p company-prefix candidate)
+ collect candidate into same-case
+ else collect candidate into other-case
+ finally return (append same-case other-case)))
+
+(defun company-idle-begin (buf win tick pos)
+ (and (eq buf (current-buffer))
+ (eq win (selected-window))
+ (eq tick (buffer-chars-modified-tick))
+ (eq pos (point))
+ (let ((non-essential t))
+ (when (company-auto-begin)
+ (let ((this-command 'company-idle-begin))
+ (company-post-command))))))
+
+(defun company-auto-begin ()
+ (and company-mode
+ (not company-candidates)
+ (let ((company-idle-delay 'now))
+ (condition-case-unless-debug err
+ (let ((inhibit-quit nil))
+ (company--perform)
+ ;; Return non-nil if active.
+ company-candidates)
+ (error (message "Company: An error occurred in auto-begin")
+ (message "%s" (error-message-string err))
+ (company-cancel))
+ (quit (company-cancel))))))
+
+;;;###autoload
+(defun company-manual-begin ()
+ (interactive)
+ (company-assert-enabled)
+ (setq company--manual-action t)
+ (unwind-protect
+ (let ((company-minimum-prefix-length 0))
+ (or company-candidates
+ (company-auto-begin)))
+ (unless company-candidates
+ (setq company--manual-action nil))))
+
+(defun company-other-backend (&optional backward)
+ (interactive (list current-prefix-arg))
+ (company-assert-enabled)
+ (let* ((after (if company-backend
+ (cdr (member company-backend company-backends))
+ company-backends))
+ (before (cdr (member company-backend (reverse company-backends))))
+ (next (if backward
+ (append before (reverse after))
+ (append after (reverse before)))))
+ (company-cancel)
+ (cl-dolist (backend next)
+ (when (ignore-errors (company-begin-backend backend))
+ (cl-return t))))
+ (unless company-candidates
+ (user-error "No other backend")))
+
+(defun company-require-match-p ()
+ (let ((backend-value (company-call-backend 'require-match)))
+ (or (eq backend-value t)
+ (and (not (eq backend-value 'never))
+ (if (functionp company-require-match)
+ (funcall company-require-match)
+ (eq company-require-match t))))))
+
+(defun company-insertion-on-trigger-p (input)
+ "Return non-nil if INPUT should trigger insertion.
+For more details see `company-insertion-on-trigger' and
+`company-insertion-triggers'."
+ (and (if (functionp company-insertion-on-trigger)
+ (funcall company-insertion-on-trigger)
+ company-insertion-on-trigger)
+ (if (functionp company-insertion-triggers)
+ (funcall company-insertion-triggers input)
+ (if (consp company-insertion-triggers)
+ (memq (char-syntax (string-to-char input))
+ company-insertion-triggers)
+ (string-match (regexp-quote (substring input 0 1))
+ company-insertion-triggers)))))
+
+(defun company--incremental-p ()
+ (and (> (point) company-point)
+ (> (point-max) company--point-max)
+ (not (eq this-command 'backward-delete-char-untabify))
+ (equal (buffer-substring (- company-point (length company-prefix))
+ company-point)
+ company-prefix)))
+
+(defun company--continue-failed (new-prefix)
+ (cond
+ ((and (or (not (company-require-match-p))
+ ;; Don't require match if the new prefix
+ ;; doesn't continue the old one, and the latter was a match.
+ (not (stringp new-prefix))
+ (<= (length new-prefix) (length company-prefix)))
+ (member company-prefix company-candidates))
+ ;; Last input was a success,
+ ;; but we're treating it as an abort + input anyway,
+ ;; like the `unique' case below.
+ (company-cancel 'non-unique))
+ ((company-require-match-p)
+ ;; Wrong incremental input, but required match.
+ (delete-char (- company-point (point)))
+ (ding)
+ (message "Matching input is required")
+ company-candidates)
+ (t (company-cancel))))
+
+(defun company--good-prefix-p (prefix)
+ (and (stringp (company--prefix-str prefix)) ;excludes 'stop
+ (or (eq (cdr-safe prefix) t)
+ (let ((len (or (cdr-safe prefix) (length prefix))))
+ (if company--manual-prefix
+ (or (not company-abort-manual-when-too-short)
+ ;; Must not be less than minimum or initial length.
+ (>= len (min company-minimum-prefix-length
+ (length company--manual-prefix))))
+ (>= len company-minimum-prefix-length))))))
+
+(defun company--continue ()
+ (when (company-call-backend 'no-cache company-prefix)
+ ;; Don't complete existing candidates, fetch new ones.
+ (setq company-candidates-cache nil))
+ (let* ((new-prefix (company-call-backend 'prefix))
+ (ignore-case (company-call-backend 'ignore-case))
+ (c (when (and (company--good-prefix-p new-prefix)
+ (setq new-prefix (company--prefix-str new-prefix))
+ (= (- (point) (length new-prefix))
+ (- company-point (length company-prefix))))
+ (company-calculate-candidates new-prefix ignore-case))))
+ (cond
+ ((and company-abort-on-unique-match
+ (company--unique-match-p c new-prefix ignore-case))
+ ;; Handle it like completion was aborted, to differentiate from user
+ ;; calling one of Company's commands to insert the candidate,
+ ;; not to trigger template expansion, etc.
+ (company-cancel 'unique))
+ ((consp c)
+ ;; incremental match
+ (setq company-prefix new-prefix)
+ (company-update-candidates c)
+ c)
+ ((and (characterp last-command-event)
+ (company-insertion-on-trigger-p (string last-command-event)))
+ ;; Insertion on trigger.
+ (save-excursion
+ (goto-char company-point)
+ (company-complete-selection)
+ nil))
+ ((not (company--incremental-p))
+ (company-cancel))
+ (t (company--continue-failed new-prefix)))))
+
+(defun company--begin-new ()
+ (let (prefix c)
+ (cl-dolist (backend (if company-backend
+ ;; prefer manual override
+ (list company-backend)
+ company-backends))
+ (setq prefix
+ (if (or (symbolp backend)
+ (functionp backend))
+ (when (company--maybe-init-backend backend)
+ (let ((company-backend backend))
+ (company-call-backend 'prefix)))
+ (company--multi-backend-adapter backend 'prefix)))
+ (when prefix
+ (when (company--good-prefix-p prefix)
+ (let ((ignore-case (company-call-backend 'ignore-case)))
+ (setq company-prefix (company--prefix-str prefix)
+ company-backend backend
+ c (company-calculate-candidates company-prefix ignore-case))
+ (cond
+ ((and company-abort-on-unique-match
+ (company--unique-match-p c company-prefix ignore-case)
+ (if company--manual-action
+ ;; If `company-manual-begin' was called, the user
+ ;; really wants something to happen. Otherwise...
+ (ignore (message "Sole completion"))
+ t))
+ ;; ...abort and run the hooks, e.g. to clear the cache.
+ (company-cancel 'unique))
+ ((null c)
+ (when company--manual-action
+ (message "No completion found")))
+ (t ;; We got completions!
+ (when company--manual-action
+ (setq company--manual-prefix prefix))
+ (company-update-candidates c)
+ (run-hook-with-args 'company-completion-started-hook
+ (company-explicit-action-p))
+ (company-call-frontends 'show)))))
+ (cl-return c)))))
+
+(defun company--perform ()
+ (cond
+ (company-candidates
+ (company--continue))
+ ((company--should-complete)
+ (company--begin-new)))
+ (if (not company-candidates)
+ (setq company-backend nil)
+ (setq company-point (point)
+ company--point-max (point-max))
+ (company-ensure-emulation-alist)
+ (company-enable-overriding-keymap company-active-map)
+ (company-call-frontends 'update)))
+
+(defun company-cancel (&optional result)
+ (let ((prefix company-prefix)
+ (backend company-backend))
+ (setq company-backend nil
+ company-prefix nil
+ company-candidates nil
+ company-candidates-length nil
+ company-candidates-cache nil
+ company-candidates-predicate nil
+ company-common nil
+ company-selection company-selection-default
+ company-selection-changed nil
+ company--manual-action nil
+ company--manual-prefix nil
+ company--point-max nil
+ company-point nil)
+ (when company-timer
+ (cancel-timer company-timer))
+ (company-echo-cancel t)
+ (company-search-mode 0)
+ (company-call-frontends 'hide)
+ (company-enable-overriding-keymap nil)
+ (when prefix
+ (if (stringp result)
+ (let ((company-backend backend))
+ (run-hook-with-args 'company-completion-finished-hook result)
+ (company-call-backend 'post-completion result))
+ (run-hook-with-args 'company-completion-cancelled-hook result))
+ (run-hook-with-args 'company-after-completion-hook result)))
+ ;; Make return value explicit.
+ nil)
+
+(defun company-abort ()
+ (interactive)
+ (company-cancel 'abort))
+
+(defun company-finish (result)
+ (company--insert-candidate result)
+ (company-cancel result))
+
+(defsubst company-keep (command)
+ (and (symbolp command) (get command 'company-keep)))
+
+(defun company--active-p ()
+ company-candidates)
+
+(defun company-pre-command ()
+ (company--electric-restore-window-configuration)
+ (unless (company-keep this-command)
+ (condition-case-unless-debug err
+ (when company-candidates
+ (company-call-frontends 'pre-command)
+ (unless (company--should-continue)
+ (company-abort)))
+ (error (message "Company: An error occurred in pre-command")
+ (message "%s" (error-message-string err))
+ (company-cancel))))
+ (when company-timer
+ (cancel-timer company-timer)
+ (setq company-timer nil))
+ (company-echo-cancel t)
+ (company-uninstall-map))
+
+(defun company-post-command ()
+ (when (and company-candidates
+ (null this-command))
+ ;; Happens when the user presses `C-g' while inside
+ ;; `flyspell-post-command-hook', for example.
+ ;; Or any other `post-command-hook' function that can call `sit-for',
+ ;; or any quittable timer function.
+ (company-abort)
+ (setq this-command 'company-abort))
+ (unless (company-keep this-command)
+ (condition-case-unless-debug err
+ (progn
+ (unless (equal (point) company-point)
+ (let (company-idle-delay) ; Against misbehavior while debugging.
+ (company--perform)))
+ (if company-candidates
+ (company-call-frontends 'post-command)
+ (let ((delay (company--idle-delay)))
+ (and (numberp delay)
+ (not defining-kbd-macro)
+ (company--should-begin)
+ (setq company-timer
+ (run-with-timer delay nil
+ 'company-idle-begin
+ (current-buffer) (selected-window)
+ (buffer-chars-modified-tick) (point)))))))
+ (error (message "Company: An error occurred in post-command")
+ (message "%s" (error-message-string err))
+ (company-cancel))))
+ (company-install-map))
+
+(defun company--idle-delay ()
+ (let ((delay
+ (if (functionp company-idle-delay)
+ (funcall company-idle-delay)
+ company-idle-delay)))
+ (if (memql delay '(t 0 0.0))
+ 0.01
+ delay)))
+
+(defvar company--begin-inhibit-commands '(company-abort
+ company-complete-mouse
+ company-complete
+ company-complete-common
+ company-complete-selection
+ company-complete-tooltip-row)
+ "List of commands after which idle completion is (still) disabled when
+`company-begin-commands' is t.")
+
+(defun company--should-begin ()
+ (if (eq t company-begin-commands)
+ (not (memq this-command company--begin-inhibit-commands))
+ (or
+ (memq this-command company-begin-commands)
+ (and (symbolp this-command) (get this-command 'company-begin)))))
+
+;;; search ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defcustom company-search-regexp-function #'regexp-quote
+ "Function to construct the search regexp from input.
+It's called with one argument, the current search input. It must return
+either a regexp without groups, or one where groups don't intersect and
+each one wraps a part of the input string."
+ :type '(choice
+ (const :tag "Exact match" regexp-quote)
+ (const :tag "Words separated with spaces" company-search-words-regexp)
+ (const :tag "Words separated with spaces, in any order"
+ company-search-words-in-any-order-regexp)
+ (const :tag "All characters in given order, with anything in between"
+ company-search-flex-regexp)))
+
+(defvar-local company-search-string "")
+
+(defvar company-search-lighter '(" "
+ (company-search-filtering "Filter" "Search")
+ ": \""
+ company-search-string
+ "\""))
+
+(defvar-local company-search-filtering nil
+ "Non-nil to filter the completion candidates by the search string")
+
+(defvar-local company--search-old-selection 0)
+
+(defvar-local company--search-old-changed nil)
+
+(defun company-search-words-regexp (input)
+ (mapconcat (lambda (word) (format "\\(%s\\)" (regexp-quote word)))
+ (split-string input " +" t) ".*"))
+
+(defun company-search-words-in-any-order-regexp (input)
+ (let* ((words (mapcar (lambda (word) (format "\\(%s\\)" (regexp-quote word)))
+ (split-string input " +" t)))
+ (permutations (company--permutations words)))
+ (mapconcat (lambda (words)
+ (mapconcat #'identity words ".*"))
+ permutations
+ "\\|")))
+
+(defun company-search-flex-regexp (input)
+ (if (zerop (length input))
+ ""
+ (concat (regexp-quote (string (aref input 0)))
+ (mapconcat (lambda (c)
+ (concat "[^" (string c) "]*"
+ (regexp-quote (string c))))
+ (substring input 1) ""))))
+
+(defun company--permutations (lst)
+ (if (not lst)
+ '(nil)
+ ;; FIXME: Replace with `mapcan' in Emacs 26.
+ (cl-mapcan
+ (lambda (e)
+ (mapcar (lambda (perm) (cons e perm))
+ (company--permutations (cl-remove e lst :count 1))))
+ lst)))
+
+(defun company--search (text lines)
+ (let ((re (funcall company-search-regexp-function text))
+ (i 0))
+ (cl-dolist (line lines)
+ (when (string-match-p re line)
+ (cl-return i))
+ (cl-incf i))))
+
+(defun company-search-printing-char ()
+ (interactive)
+ (company--search-assert-enabled)
+ (let* ((event-type (event-basic-type last-command-event))
+ (event-string (if (characterp event-type)
+ (string last-command-event)
+ ;; Handle key press on the keypad.
+ (let ((name (symbol-name event-type)))
+ (if (string-match "kp-\\([0-9]\\)" name)
+ (match-string 1 name)
+ (error "Unexpected printing char input")))))
+ (ss (concat company-search-string event-string)))
+ (when company-search-filtering
+ (company--search-update-predicate ss))
+ (company--search-update-string ss)))
+
+(defun company--search-update-predicate (ss)
+ (let* ((re (funcall company-search-regexp-function ss))
+ (company-candidates-predicate
+ (and (not (string= re ""))
+ company-search-filtering
+ (lambda (candidate) (string-match re candidate))))
+ (cc (company-calculate-candidates company-prefix
+ (company-call-backend 'ignore-case))))
+ (unless cc (user-error "No match"))
+ (company-update-candidates cc)))
+
+(defun company--search-update-string (new)
+ (let* ((selection (or company-selection 0))
+ (pos (company--search new (nthcdr selection company-candidates))))
+ (if (null pos)
+ (ding)
+ (setq company-search-string new)
+ (company-set-selection (+ selection pos) t))))
+
+(defun company--search-assert-input ()
+ (company--search-assert-enabled)
+ (when (string= company-search-string "")
+ (user-error "Empty search string")))
+
+(defun company-search-repeat-forward ()
+ "Repeat the incremental search in completion candidates forward."
+ (interactive)
+ (company--search-assert-input)
+ (let* ((selection (or company-selection 0))
+ (pos (company--search company-search-string
+ (cdr (nthcdr selection company-candidates)))))
+ (if (null pos)
+ (ding)
+ (company-set-selection (+ selection pos 1) t))))
+
+(defun company-search-repeat-backward ()
+ "Repeat the incremental search in completion candidates backwards."
+ (interactive)
+ (company--search-assert-input)
+ (let* ((selection (or company-selection 0))
+ (pos (company--search company-search-string
+ (nthcdr (- company-candidates-length
+ selection)
+ (reverse company-candidates)))))
+ (if (null pos)
+ (ding)
+ (company-set-selection (- selection pos 1) t))))
+
+(defun company-search-toggle-filtering ()
+ "Toggle `company-search-filtering'."
+ (interactive)
+ (company--search-assert-enabled)
+ (setq company-search-filtering (not company-search-filtering))
+ (let ((ss company-search-string))
+ (company--search-update-predicate ss)
+ (company--search-update-string ss)))
+
+(defun company-search-abort ()
+ "Abort searching the completion candidates."
+ (interactive)
+ (company--search-assert-enabled)
+ (company-search-mode 0)
+ (company-set-selection company--search-old-selection t)
+ (setq company-selection-changed company--search-old-changed))
+
+(defun company-search-other-char ()
+ (interactive)
+ (company--search-assert-enabled)
+ (company-search-mode 0)
+ (company--unread-this-command-keys))
+
+(defun company-search-delete-char ()
+ (interactive)
+ (company--search-assert-enabled)
+ (if (string= company-search-string "")
+ (ding)
+ (let ((ss (substring company-search-string 0 -1)))
+ (when company-search-filtering
+ (company--search-update-predicate ss))
+ (company--search-update-string ss))))
+
+(defvar company-search-map
+ (let ((i 0)
+ (keymap (make-keymap)))
+ (if (fboundp 'max-char)
+ (set-char-table-range (nth 1 keymap) (cons #x100 (max-char))
+ 'company-search-printing-char)
+ (with-no-warnings
+ ;; obsolete in Emacs 23
+ (let ((l (generic-character-list))
+ (table (nth 1 keymap)))
+ (while l
+ (set-char-table-default table (car l) 'company-search-printing-char)
+ (setq l (cdr l))))))
+ (define-key keymap [t] 'company-search-other-char)
+ (while (< i ?\s)
+ (define-key keymap (make-string 1 i) 'company-search-other-char)
+ (cl-incf i))
+ (while (< i 256)
+ (define-key keymap (vector i) 'company-search-printing-char)
+ (cl-incf i))
+ (dotimes (i 10)
+ (define-key keymap (kbd (format "<kp-%d>" i)) 'company-search-printing-char))
+ (let ((meta-map (make-sparse-keymap)))
+ (define-key keymap (char-to-string meta-prefix-char) meta-map)
+ (define-key keymap [escape] meta-map))
+ (define-key keymap (vector meta-prefix-char t) 'company-search-other-char)
+ (define-key keymap (kbd "C-n") 'company-select-next-or-abort)
+ (define-key keymap (kbd "C-p") 'company-select-previous-or-abort)
+ (define-key keymap (kbd "M-n") 'company--select-next-and-warn)
+ (define-key keymap (kbd "M-p") 'company--select-previous-and-warn)
+ (define-key keymap (kbd "<down>") 'company-select-next-or-abort)
+ (define-key keymap (kbd "<up>") 'company-select-previous-or-abort)
+ (define-key keymap "\e\e\e" 'company-search-other-char)
+ (define-key keymap [escape escape escape] 'company-search-other-char)
+ (define-key keymap (kbd "DEL") 'company-search-delete-char)
+ (define-key keymap [backspace] 'company-search-delete-char)
+ (define-key keymap "\C-g" 'company-search-abort)
+ (define-key keymap "\C-s" 'company-search-repeat-forward)
+ (define-key keymap "\C-r" 'company-search-repeat-backward)
+ (define-key keymap "\C-o" 'company-search-toggle-filtering)
+ (company-keymap--bind-quick-access keymap)
+ keymap)
+ "Keymap used for incrementally searching the completion candidates.")
+
+(define-minor-mode company-search-mode
+ "Search mode for completion candidates.
+Don't start this directly, use `company-search-candidates' or
+`company-filter-candidates'."
+ :lighter company-search-lighter
+ (if company-search-mode
+ (if (company-manual-begin)
+ (progn
+ (setq company--search-old-selection company-selection
+ company--search-old-changed company-selection-changed)
+ (company-call-frontends 'update)
+ (company-enable-overriding-keymap company-search-map))
+ (setq company-search-mode nil))
+ (kill-local-variable 'company-search-string)
+ (kill-local-variable 'company-search-filtering)
+ (kill-local-variable 'company--search-old-selection)
+ (kill-local-variable 'company--search-old-changed)
+ (when company-backend
+ (company--search-update-predicate "")
+ (company-call-frontends 'update))
+ (company-enable-overriding-keymap company-active-map)))
+
+(defun company--search-assert-enabled ()
+ (company-assert-enabled)
+ (unless company-search-mode
+ (company-uninstall-map)
+ (user-error "Company not in search mode")))
+
+(defun company-search-candidates ()
+ "Start searching the completion candidates incrementally.
+
+\\<company-search-map>Search can be controlled with the commands:
+- `company-search-repeat-forward' (\\[company-search-repeat-forward])
+- `company-search-repeat-backward' (\\[company-search-repeat-backward])
+- `company-search-abort' (\\[company-search-abort])
+- `company-search-delete-char' (\\[company-search-delete-char])
+
+Regular characters are appended to the search string.
+
+Customize `company-search-regexp-function' to change how the input
+is interpreted when searching.
+
+The command `company-search-toggle-filtering' (\\[company-search-toggle-filtering])
+uses the search string to filter the completion candidates."
+ (interactive)
+ (company-search-mode 1))
+
+(defun company-filter-candidates ()
+ "Start filtering the completion candidates incrementally.
+This works the same way as `company-search-candidates' immediately
+followed by `company-search-toggle-filtering'."
+ (interactive)
+ (company-search-mode 1)
+ (setq company-search-filtering t))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defun company-select-next (&optional arg)
+ "Select the next candidate in the list.
+
+With ARG, move by that many elements.
+When `company-selection-default' is nil, add a special pseudo candidates
+meant for no selection."
+ (interactive "p")
+ (when (company-manual-begin)
+ (let ((selection (+ (or arg 1)
+ (or company-selection
+ company-selection-default
+ -1))))
+ (company-set-selection selection))))
+
+(defun company-select-previous (&optional arg)
+ "Select the previous candidate in the list.
+
+With ARG, move by that many elements."
+ (interactive "p")
+ (company-select-next (if arg (- arg) -1)))
+
+(defun company-select-next-or-abort (&optional arg)
+ "Select the next candidate if more than one, else abort
+and invoke the normal binding.
+
+With ARG, move by that many elements."
+ (interactive "p")
+ (if (or (not company-selection)
+ (> company-candidates-length 1))
+ (company-select-next arg)
+ (company-abort)
+ (company--unread-this-command-keys)))
+
+(defun company-select-previous-or-abort (&optional arg)
+ "Select the previous candidate if more than one, else abort
+and invoke the normal binding.
+
+With ARG, move by that many elements."
+ (interactive "p")
+ (if (> company-candidates-length 1)
+ (company-select-previous arg)
+ (company-abort)
+ (company--unread-this-command-keys)))
+
+(defun company-select-first ()
+ "Select the first completion candidate."
+ (interactive)
+ (company-set-selection 0))
+
+(defun company-select-last ()
+ "Select the last completion candidate."
+ (interactive)
+ (company-set-selection (1- company-candidates-length)))
+
+(defun company-next-page ()
+ "Select the candidate one page further."
+ (interactive)
+ (when (company-manual-begin)
+ (if (and company-selection-wrap-around
+ (= company-selection (1- company-candidates-length)))
+ (company-set-selection 0)
+ (let (company-selection-wrap-around)
+ (company-set-selection (+ company-selection
+ company-tooltip-limit))))))
+
+(defun company-previous-page ()
+ "Select the candidate one page earlier."
+ (interactive)
+ (when (company-manual-begin)
+ (if (and company-selection-wrap-around
+ (zerop company-selection))
+ (company-set-selection (1- company-candidates-length))
+ (let (company-selection-wrap-around)
+ (company-set-selection (- company-selection
+ company-tooltip-limit))))))
+
+(defun company--event-col-row (event)
+ (company--posn-col-row (event-start event)))
+
+(defvar company-mouse-event nil
+ "Holds the mouse event from `company-select-mouse'.
+For use in the `select-mouse' frontend action. `let'-bound.")
+
+(defun company-select-mouse (event)
+ "Select the candidate picked by the mouse."
+ (interactive "e")
+ (or (let ((company-mouse-event event))
+ (cl-some #'identity (company-call-frontends 'select-mouse)))
+ (progn
+ (company-abort)
+ (company--unread-this-command-keys)
+ nil)))
+
+(defun company-complete-mouse (event)
+ "Insert the candidate picked by the mouse."
+ (interactive "e")
+ (when (company-select-mouse event)
+ (company-complete-selection)))
+
+(defun company-complete-selection ()
+ "Insert the selected candidate."
+ (interactive)
+ (when (and (company-manual-begin) company-selection)
+ (let ((result (nth company-selection company-candidates)))
+ (company-finish result))))
+
+(defun company-complete-common ()
+ "Insert the common part of all candidates."
+ (interactive)
+ (when (company-manual-begin)
+ (if (and (not (cdr company-candidates))
+ (equal company-common (car company-candidates)))
+ (company-complete-selection)
+ (company--insert-candidate company-common))))
+
+(defun company-complete-common-or-cycle (&optional arg)
+ "Insert the common part of all candidates, or select the next one.
+
+With ARG, move by that many elements."
+ (interactive "p")
+ (when (company-manual-begin)
+ (let ((tick (buffer-chars-modified-tick)))
+ (call-interactively 'company-complete-common)
+ (when (eq tick (buffer-chars-modified-tick))
+ (let ((company-selection-wrap-around t)
+ (current-prefix-arg arg))
+ (call-interactively 'company-select-next))))))
+
+(defun company-complete-common-or-show-delayed-tooltip ()
+ "Insert the common part of all candidates, or show a tooltip."
+ (interactive)
+ (when (company-manual-begin)
+ (let ((tick (buffer-chars-modified-tick)))
+ (call-interactively 'company-complete-common)
+ (when (eq tick (buffer-chars-modified-tick))
+ (let ((company-tooltip-idle-delay 0.0))
+ (company-complete)
+ (and company-candidates
+ (company-call-frontends 'post-command)))))))
+
+(defun company-indent-or-complete-common (arg)
+ "Indent the current line or region, or complete the common part."
+ (interactive "P")
+ (cond
+ ((use-region-p)
+ (indent-region (region-beginning) (region-end)))
+ ((memq indent-line-function
+ '(indent-relative indent-relative-maybe))
+ (company-complete-common))
+ ((let ((old-point (point))
+ (old-tick (buffer-chars-modified-tick))
+ (tab-always-indent t))
+ (indent-for-tab-command arg)
+ (when (and (eq old-point (point))
+ (eq old-tick (buffer-chars-modified-tick)))
+ (company-complete-common))))))
+
+(defun company-select-next-if-tooltip-visible-or-complete-selection ()
+ "Insert selection if appropriate, or select the next candidate.
+Insert selection if only preview is showing or only one candidate,
+otherwise select the next candidate."
+ (interactive)
+ (if (and (company-tooltip-visible-p) (> company-candidates-length 1))
+ (call-interactively 'company-select-next)
+ (call-interactively 'company-complete-selection)))
+
+;;;###autoload
+(defun company-complete ()
+ "Insert the common part of all candidates or the current selection.
+The first time this is called, the common part is inserted, the second
+time, or when the selection has been changed, the selected candidate is
+inserted."
+ (interactive)
+ (when (company-manual-begin)
+ (if (or company-selection-changed
+ (and (eq real-last-command 'company-complete)
+ (eq last-command 'company-complete-common)))
+ (call-interactively 'company-complete-selection)
+ (call-interactively 'company-complete-common)
+ (when company-candidates
+ (setq this-command 'company-complete-common)))))
+
+(define-obsolete-function-alias
+ 'company-complete-number
+ 'company-complete-tooltip-row
+ "0.9.14")
+
+(defun company-complete-tooltip-row (number)
+ "Insert a candidate visible on the tooltip's row NUMBER.
+
+Inserts one of the first ten candidates,
+numbered according to the current scrolling position starting with 1.
+
+When called interactively, uses the last typed digit, stripping the
+modifiers and translating 0 into 10, so `M-1' inserts the first visible
+candidate, and `M-0' insert to 10th one.
+
+To show hint numbers beside the candidates, enable `company-show-quick-access'."
+ (interactive
+ (list (let* ((type (event-basic-type last-command-event))
+ (char (if (characterp type)
+ ;; Number on the main row.
+ type
+ ;; Keypad number, if bound directly.
+ (car (last (string-to-list (symbol-name type))))))
+ (number (- char ?0)))
+ (if (zerop number) 10 number))))
+ (company--complete-nth (1- number)))
+
+(defun company-complete-quick-access (row)
+ "Insert a candidate visible on a ROW matched by a quick-access key binding.
+See `company-quick-access-keys' for more details."
+ (interactive
+ (list (let* ((event-type (event-basic-type last-command-event))
+ (event-string (if (characterp event-type)
+ (string event-type)
+ (error "Unexpected input"))))
+ (cl-position event-string company-quick-access-keys :test 'equal))))
+ (when row
+ (company--complete-nth row)))
+
+(defvar-local company-tooltip-offset 0
+ "Current scrolling state of the tooltip.
+Represented by the index of the first visible completion candidate
+from the candidates list.")
+
+(defun company--complete-nth (row)
+ "Insert a candidate visible on the tooltip's zero-based ROW."
+ (when (company-manual-begin)
+ (and (or (< row 0) (>= row (- company-candidates-length
+ company-tooltip-offset)))
+ (user-error "No candidate on the row number %d" row))
+ (company-finish (nth (+ row company-tooltip-offset)
+ company-candidates))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defconst company-space-strings-limit 100)
+
+(defconst company-space-strings
+ (let (lst)
+ (dotimes (i company-space-strings-limit)
+ (push (make-string (- company-space-strings-limit 1 i) ?\ ) lst))
+ (apply 'vector lst)))
+
+(defun company-space-string (len)
+ (if (< len company-space-strings-limit)
+ (aref company-space-strings len)
+ (make-string len ?\ )))
+
+(defun company-safe-substring (str from &optional to)
+ (let ((bis buffer-invisibility-spec))
+ (if (> from (string-width str))
+ ""
+ (with-temp-buffer
+ (setq buffer-invisibility-spec bis)
+ (insert str)
+ (move-to-column from)
+ (let ((beg (point)))
+ (if to
+ (progn
+ (move-to-column to)
+ (concat (buffer-substring beg (point))
+ (let ((padding (- to (current-column))))
+ (when (> padding 0)
+ (company-space-string padding)))))
+ (buffer-substring beg (point-max))))))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defvar-local company-last-metadata nil)
+
+(defun company-fetch-metadata ()
+ (let ((selected (nth (or company-selection 0) company-candidates)))
+ (unless (eq selected (car company-last-metadata))
+ (setq company-last-metadata
+ (cons selected (company-call-backend 'meta selected))))
+ (cdr company-last-metadata)))
+
+(defun company-doc-buffer (&optional string)
+ (with-current-buffer (get-buffer-create "*company-documentation*")
+ (erase-buffer)
+ (fundamental-mode)
+ (when string
+ (save-excursion
+ (insert string)
+ (visual-line-mode)))
+ (current-buffer)))
+
+(defvar company--electric-saved-window-configuration nil)
+
+(defvar company--electric-commands
+ '(scroll-other-window scroll-other-window-down mwheel-scroll)
+ "List of Commands that won't break out of electric commands.")
+
+(defun company--electric-restore-window-configuration ()
+ "Restore window configuration (after electric commands)."
+ (when (and company--electric-saved-window-configuration
+ (not (memq this-command company--electric-commands)))
+ (set-window-configuration company--electric-saved-window-configuration)
+ (setq company--electric-saved-window-configuration nil)))
+
+(defmacro company--electric-do (&rest body)
+ (declare (indent 0) (debug t))
+ `(when (company-manual-begin)
+ (cl-assert (null company--electric-saved-window-configuration))
+ (setq company--electric-saved-window-configuration (current-window-configuration))
+ (let ((height (window-height))
+ (row (company--row)))
+ ,@body
+ (and (< (window-height) height)
+ (< (- (window-height) row 2) company-tooltip-limit)
+ (recenter (- (window-height) row 2))))))
+
+(defun company--unread-this-command-keys ()
+ (when (> (length (this-command-keys)) 0)
+ (setq unread-command-events (nconc
+ (listify-key-sequence (this-command-keys))
+ unread-command-events))
+ (clear-this-command-keys t)))
+
+(defun company-show-doc-buffer ()
+ "Temporarily show the documentation buffer for the selection."
+ (interactive)
+ (let ((other-window-scroll-buffer)
+ (selection (or company-selection 0)))
+ (company--electric-do
+ (let* ((selected (nth selection company-candidates))
+ (doc-buffer (or (company-call-backend 'doc-buffer selected)
+ (user-error "No documentation available")))
+ start)
+ (when (consp doc-buffer)
+ (setq start (cdr doc-buffer)
+ doc-buffer (car doc-buffer)))
+ (setq other-window-scroll-buffer (get-buffer doc-buffer))
+ (let ((win (display-buffer doc-buffer t)))
+ (set-window-start win (if start start (point-min))))))))
+(put 'company-show-doc-buffer 'company-keep t)
+
+(defun company-show-location ()
+ "Temporarily display a buffer showing the selected candidate in context."
+ (interactive)
+ (let (other-window-scroll-buffer)
+ (company--electric-do
+ (let* ((selected (nth company-selection company-candidates))
+ (location (company-call-backend 'location selected))
+ (pos (or (cdr location) (user-error "No location available")))
+ (buffer (or (and (bufferp (car location)) (car location))
+ (find-file-noselect (car location) t))))
+ (setq other-window-scroll-buffer (get-buffer buffer))
+ (with-selected-window (display-buffer buffer t)
+ (save-restriction
+ (widen)
+ (if (bufferp (car location))
+ (goto-char pos)
+ (goto-char (point-min))
+ (forward-line (1- pos))))
+ (set-window-start nil (point)))))))
+(put 'company-show-location 'company-keep t)
+
+;;; package functions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defvar-local company-callback nil)
+
+(defun company-remove-callback (&optional ignored)
+ (remove-hook 'company-completion-finished-hook company-callback t)
+ (remove-hook 'company-completion-cancelled-hook 'company-remove-callback t)
+ (remove-hook 'company-completion-finished-hook 'company-remove-callback t))
+
+(defun company-begin-backend (backend &optional callback)
+ "Start a completion at point using BACKEND."
+ (interactive (let ((val (completing-read "Company backend: "
+ obarray
+ 'functionp nil "company-")))
+ (when val
+ (list (intern val)))))
+ (when (setq company-callback callback)
+ (add-hook 'company-completion-finished-hook company-callback nil t))
+ (add-hook 'company-completion-cancelled-hook 'company-remove-callback nil t)
+ (add-hook 'company-completion-finished-hook 'company-remove-callback nil t)
+ (setq company-backend backend)
+ ;; Return non-nil if active.
+ (or (company-manual-begin)
+ (user-error "Cannot complete at point")))
+
+(defun company-begin-with (candidates
+ &optional prefix-length require-match callback)
+ "Start a completion at point.
+CANDIDATES is the list of candidates to use and PREFIX-LENGTH is the length
+of the prefix that already is in the buffer before point.
+It defaults to 0.
+
+CALLBACK is a function called with the selected result if the user
+successfully completes the input.
+
+Example: \(company-begin-with \\='\(\"foo\" \"foobar\" \"foobarbaz\"\)\)"
+ (let ((begin-marker (copy-marker (point) t)))
+ (company-begin-backend
+ (lambda (command &optional arg &rest ignored)
+ (pcase command
+ (`prefix
+ (when (equal (point) (marker-position begin-marker))
+ (buffer-substring (- (point) (or prefix-length 0)) (point))))
+ (`candidates
+ (all-completions arg candidates))
+ (`require-match
+ require-match)))
+ callback)))
+
+(declare-function find-library-name "find-func")
+(declare-function lm-version "lisp-mnt")
+
+(defun company-version (&optional show-version)
+ "Get the Company version as string.
+
+If SHOW-VERSION is non-nil, show the version in the echo area."
+ (interactive (list t))
+ (with-temp-buffer
+ (require 'find-func)
+ (insert-file-contents (find-library-name "company"))
+ (require 'lisp-mnt)
+ (if show-version
+ (message "Company version: %s" (lm-version))
+ (lm-version))))
+
+(defun company-diag ()
+ "Pop a buffer with information about completions at point."
+ (interactive)
+ (let* ((bb company-backends)
+ (mode (symbol-name major-mode))
+ backend
+ (prefix (cl-loop for b in bb
+ thereis (let ((company-backend b))
+ (setq backend b)
+ (company-call-backend 'prefix))))
+ (c-a-p-f completion-at-point-functions)
+ cc annotations)
+ (when (or (stringp prefix) (consp prefix))
+ (let ((company-backend backend))
+ (condition-case nil
+ (setq cc (company-call-backend 'candidates (company--prefix-str prefix))
+ annotations
+ (mapcar
+ (lambda (c) (cons c (company-call-backend 'annotation c)))
+ cc))
+ (error (setq annotations 'error)))))
+ (pop-to-buffer (get-buffer-create "*company-diag*"))
+ (setq buffer-read-only nil)
+ (erase-buffer)
+ (insert (format "Emacs %s (%s) of %s on %s"
+ emacs-version system-configuration
+ (format-time-string "%Y-%m-%d" emacs-build-time)
+ emacs-build-system))
+ (insert "\nCompany " (company-version) "\n\n")
+ (insert "company-backends: " (pp-to-string bb))
+ (insert "\n")
+ (insert "Used backend: " (pp-to-string backend))
+ (insert "\n")
+ (when (if (listp backend)
+ (memq 'company-capf backend)
+ (eq backend 'company-capf))
+ (insert "Value of c-a-p-f: "
+ (pp-to-string c-a-p-f)))
+ (insert "Major mode: " mode)
+ (insert "\n")
+ (insert "Prefix: " (pp-to-string prefix))
+ (insert "\n")
+ (insert "Completions:")
+ (unless cc (insert " none"))
+ (if (eq annotations 'error)
+ (insert "(error fetching)")
+ (save-excursion
+ (dolist (c annotations)
+ (insert "\n " (prin1-to-string (car c)))
+ (when (cdr c)
+ (insert " " (prin1-to-string (cdr c)))))))
+ (special-mode)))
+
+;;; pseudo-tooltip ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defvar-local company--tooltip-current-width 0)
+
+(defun company-tooltip--lines-update-offset (selection num-lines limit)
+ (cl-decf limit 2)
+ (setq company-tooltip-offset
+ (max (min selection company-tooltip-offset)
+ (- selection -1 limit)))
+
+ (when (<= company-tooltip-offset 1)
+ (cl-incf limit)
+ (setq company-tooltip-offset 0))
+
+ (when (>= company-tooltip-offset (- num-lines limit 1))
+ (cl-incf limit)
+ (when (= selection (1- num-lines))
+ (cl-decf company-tooltip-offset)
+ (when (<= company-tooltip-offset 1)
+ (setq company-tooltip-offset 0)
+ (cl-incf limit))))
+
+ limit)
+
+(defun company-tooltip--simple-update-offset (selection _num-lines limit)
+ (setq company-tooltip-offset
+ (if (< selection company-tooltip-offset)
+ selection
+ (max company-tooltip-offset
+ (- selection limit -1)))))
+
+;;; propertize
+
+(defun company-round-tab (arg)
+ (* (/ (+ arg tab-width) tab-width) tab-width))
+
+(defun company-plainify (str)
+ (let ((prefix (get-text-property 0 'line-prefix str)))
+ (when prefix ; Keep the original value unmodified, for no special reason.
+ (setq str (concat prefix str))
+ (remove-text-properties 0 (length str) '(line-prefix) str)))
+ (let* ((pieces (split-string str "\t"))
+ (copy pieces))
+ (while (cdr copy)
+ (setcar copy (company-safe-substring
+ (car copy) 0 (company-round-tab (string-width (car copy)))))
+ (pop copy))
+ (apply 'concat pieces)))
+
+(defun company--common-or-matches (value)
+ (let ((matches (company-call-backend 'match value)))
+ (when (and matches
+ company-common
+ (listp matches)
+ (= 1 (length matches))
+ (= 0 (caar matches))
+ (> (length company-common) (cdar matches)))
+ (setq matches nil))
+ (when (integerp matches)
+ (setq matches `((0 . ,matches))))
+ (or matches
+ (and company-common `((0 . ,(length company-common))))
+ nil)))
+
+(defun company-fill-propertize (value annotation width selected left right)
+ (let* ((margin (length left))
+ (company-common (and company-common (company--clean-string company-common)))
+ (common (company--common-or-matches value))
+ (_ (setq value (company-reformat (company--pre-render value))
+ annotation (and annotation (company--pre-render annotation t))))
+ (ann-ralign company-tooltip-align-annotations)
+ (ann-truncate (< width
+ (+ (length value) (length annotation)
+ (if ann-ralign 1 0))))
+ (ann-start (+ margin
+ (if ann-ralign
+ (if ann-truncate
+ (1+ (length value))
+ (- width (length annotation)))
+ (length value))))
+ (ann-end (min (+ ann-start (length annotation)) (+ margin width)))
+ (line (concat left
+ (if (or ann-truncate (not ann-ralign))
+ (company-safe-substring
+ (concat value
+ (when (and annotation ann-ralign) " ")
+ annotation)
+ 0 width)
+ (concat
+ (company-safe-substring value 0
+ (- width (length annotation)))
+ annotation))
+ right)))
+ (setq width (+ width margin (length right)))
+
+ (font-lock-append-text-property 0 width 'mouse-face
+ 'company-tooltip-mouse
+ line)
+ (when (< ann-start ann-end)
+ (add-face-text-property ann-start ann-end
+ (if selected
+ 'company-tooltip-annotation-selection
+ 'company-tooltip-annotation)
+ t line))
+ (cl-loop
+ with width = (- width (length right))
+ for (comp-beg . comp-end) in common
+ for inline-beg = (+ margin comp-beg)
+ for inline-end = (min (+ margin comp-end) width)
+ when (< inline-beg width)
+ do (add-face-text-property inline-beg inline-end
+ (if selected
+ 'company-tooltip-common-selection
+ 'company-tooltip-common)
+ nil line))
+ (when (let ((re (funcall company-search-regexp-function
+ company-search-string)))
+ (and (not (string= re ""))
+ (string-match re value)))
+ (pcase-dolist (`(,mbeg . ,mend) (company--search-chunks))
+ (let ((beg (+ margin mbeg))
+ (end (+ margin mend))
+ (width (- width (length right))))
+ (when (< beg width)
+ (add-face-text-property beg (min end width)
+ (if selected
+ 'company-tooltip-search-selection
+ 'company-tooltip-search)
+ nil line)))))
+ (when selected
+ (add-face-text-property 0 width 'company-tooltip-selection t line))
+
+ (when (company-call-backend 'deprecated value)
+ (add-face-text-property margin
+ (min
+ (+ margin (length value))
+ (- width (length right)))
+ 'company-tooltip-deprecated t line))
+
+ (add-face-text-property 0 width 'company-tooltip t line)
+ line))
+
+(defun company--search-chunks ()
+ (let ((md (match-data t))
+ res)
+ (if (<= (length md) 2)
+ (push (cons (nth 0 md) (nth 1 md)) res)
+ (while (setq md (nthcdr 2 md))
+ (when (car md)
+ (push (cons (car md) (cadr md)) res))))
+ res))
+
+(defun company--pre-render (str &optional annotation-p)
+ (or (company-call-backend 'pre-render str annotation-p)
+ (progn
+ (when (or (text-property-not-all 0 (length str) 'face nil str)
+ (text-property-not-all 0 (length str) 'mouse-face nil str))
+ (setq str (copy-sequence str))
+ (remove-text-properties 0 (length str)
+ '(face nil font-lock-face nil mouse-face nil)
+ str))
+ str)))
+
+(defun company--clean-string (str)
+ (replace-regexp-in-string
+ "\\([^[:graph:] ]\\)\\|\\(\ufeff\\)\\|[[:multibyte:]]"
+ (lambda (match)
+ (cond
+ ((match-beginning 1)
+ ;; FIXME: Better char for 'non-printable'?
+ ;; We shouldn't get any of these, but sometimes we might.
+ ;; The official "replacement character" is not supported by some fonts.
+ ;;"\ufffd"
+ "?"
+ )
+ ((match-beginning 2)
+ ;; Zero-width non-breakable space.
+ "")
+ ((> (string-width match) 1)
+ (concat
+ (make-string (1- (string-width match)) ?\ufeff)
+ match))
+ (t match)))
+ str))
+
+;;; replace
+
+(defun company-buffer-lines (beg end)
+ (goto-char beg)
+ (let (lines lines-moved)
+ (while (and (not (eobp)) ; http://debbugs.gnu.org/19553
+ (> (setq lines-moved (vertical-motion 1)) 0)
+ (<= (point) end))
+ (let ((bound (min end (point))))
+ ;; A visual line can contain several physical lines (e.g. with outline's
+ ;; folding overlay). Take only the first one.
+ (push (buffer-substring beg
+ (save-excursion
+ (goto-char beg)
+ (re-search-forward "$" bound 'move)
+ (point)))
+ lines))
+ ;; One physical line can be displayed as several visual ones as well:
+ ;; add empty strings to the list, to even the count.
+ (dotimes (_ (1- lines-moved))
+ (push "" lines))
+ (setq beg (point)))
+ (unless (eq beg end)
+ (push (buffer-substring beg end) lines))
+ (nreverse lines)))
+
+(defun company-modify-line (old new offset)
+ (concat (company-safe-substring old 0 offset)
+ new
+ (company-safe-substring old (+ offset (length new)))))
+
+(defun company--show-numbers (numbered)
+ (format " %s" (if (<= numbered 10)
+ (mod numbered 10)
+ " ")))
+(make-obsolete
+ 'company--show-numbers
+ "use `company-quick-access-hint-key' instead,
+but adjust the expected values appropriately."
+ "0.9.14")
+
+(defsubst company--window-height ()
+ (if (fboundp 'window-screen-lines)
+ (floor (window-screen-lines))
+ (window-body-height)))
+
+(defun company--window-width ()
+ (let ((ww (window-body-width)))
+ ;; Account for the line continuation column.
+ (when (zerop (cadr (window-fringes)))
+ (cl-decf ww))
+ (when (bound-and-true-p display-line-numbers)
+ (cl-decf ww (+ 2 (line-number-display-width))))
+ ;; whitespace-mode with newline-mark
+ (when (and buffer-display-table
+ (aref buffer-display-table ?\n))
+ (cl-decf ww (1- (length (aref buffer-display-table ?\n)))))
+ ww))
+
+(defun company--face-attribute (face attr)
+ ;; Like `face-attribute', but accounts for faces that have been remapped to
+ ;; another face, a list of faces, or a face spec.
+ (cond ((null face) nil)
+ ((symbolp face)
+ (let ((remap (cdr (assq face face-remapping-alist))))
+ (if remap
+ (company--face-attribute
+ ;; Faces can be remapped to their unremapped selves, but that
+ ;; would cause us infinite recursion.
+ (if (listp remap) (remq face remap) remap)
+ attr)
+ (face-attribute face attr nil t))))
+ ((keywordp (car-safe face))
+ (or (plist-get face attr)
+ (company--face-attribute (plist-get face :inherit) attr)))
+ ((listp face)
+ (cl-find-if #'stringp
+ (mapcar (lambda (f) (company--face-attribute f attr))
+ face)))))
+
+(defun company--replacement-string (lines column-offset old column nl &optional align-top)
+ (cl-decf column column-offset)
+
+ (when (< column 0) (setq column 0))
+
+ (when (and align-top company-tooltip-flip-when-above)
+ (setq lines (reverse lines)))
+
+ (let ((width (length (car lines)))
+ (remaining-cols (- (+ (company--window-width) (window-hscroll))
+ column)))
+ (when (> width remaining-cols)
+ (cl-decf column (- width remaining-cols))))
+
+ (let (new)
+ (when align-top
+ ;; untouched lines first
+ (dotimes (_ (- (length old) (length lines)))
+ (push (pop old) new)))
+ ;; length into old lines.
+ (while old
+ (push (company-modify-line (pop old) (pop lines) column)
+ new))
+ ;; Append whole new lines.
+ (while lines
+ (push (concat (company-space-string column) (pop lines))
+ new))
+
+ ;; XXX: Also see branch 'more-precise-extend'.
+ (let* ((nl-face `(,@(when (version<= "27" emacs-version)
+ '(:extend t))
+ :inverse-video nil
+ :background ,(or (company--face-attribute 'default :background)
+ (face-attribute 'default :background nil t))))
+ (str (apply #'concat
+ (when nl " \n")
+ (cl-mapcan
+ ;; https://debbugs.gnu.org/cgi/bugreport.cgi?bug=42552#23
+ (lambda (line) (list line (propertize "\n" 'face nl-face)))
+ (nreverse new)))))
+ ;; https://debbugs.gnu.org/38563
+ (add-face-text-property 0 (length str) 'default t str)
+ (when nl (put-text-property 0 1 'cursor t str))
+ str)))
+
+(defun company--create-lines (selection limit)
+ (let ((len company-candidates-length)
+ (window-width (company--window-width))
+ left-margins
+ left-margin-size
+ lines
+ width
+ lines-copy
+ items
+ previous
+ remainder
+ scrollbar-bounds)
+
+ ;; Maybe clear old offset.
+ (when (< len (+ company-tooltip-offset limit))
+ (setq company-tooltip-offset 0))
+
+ (let ((selection (or selection 0)))
+ ;; Scroll to offset.
+ (if (eq company-tooltip-offset-display 'lines)
+ (setq limit (company-tooltip--lines-update-offset selection len limit))
+ (company-tooltip--simple-update-offset selection len limit))
+
+ (cond
+ ((eq company-tooltip-offset-display 'scrollbar)
+ (setq scrollbar-bounds (company--scrollbar-bounds company-tooltip-offset
+ limit len)))
+ ((eq company-tooltip-offset-display 'lines)
+ (when (> company-tooltip-offset 0)
+ (setq previous (format "...(%d)" company-tooltip-offset)))
+ (setq remainder (- len limit company-tooltip-offset)
+ remainder (when (> remainder 0)
+ (setq remainder (format "...(%d)" remainder)))))))
+
+ (when selection
+ (cl-decf selection company-tooltip-offset))
+
+ (setq width (max (length previous) (length remainder))
+ lines (nthcdr company-tooltip-offset company-candidates)
+ len (min limit len)
+ lines-copy lines)
+
+ (when scrollbar-bounds (cl-decf window-width))
+
+ (when company-format-margin-function
+ (let ((lines-copy lines-copy)
+ res)
+ (dotimes (i len)
+ (push (funcall company-format-margin-function
+ (pop lines-copy)
+ (equal selection i))
+ res))
+ (setq left-margins (nreverse res))))
+
+ ;; XXX: format-function outputting shorter strings than the
+ ;; default margin is not supported (yet?).
+ (setq left-margin-size (apply #'max company-tooltip-margin
+ (mapcar #'length left-margins)))
+
+ (cl-decf window-width company-tooltip-margin)
+ (cl-decf window-width left-margin-size)
+
+ (dotimes (_ len)
+ (let* ((value (pop lines-copy))
+ (annotation (company-call-backend 'annotation value))
+ (left (or (pop left-margins)
+ (company-space-string left-margin-size))))
+ (setq value (company--clean-string value))
+ (when annotation
+ (setq annotation (company--clean-string annotation))
+ (when company-tooltip-align-annotations
+ ;; `lisp-completion-at-point' adds a space.
+ (setq annotation (string-trim-left annotation))))
+ (push (list value annotation left) items)
+ (setq width (max (+ (length value)
+ (if (and annotation company-tooltip-align-annotations)
+ (1+ (length annotation))
+ (length annotation)))
+ width))))
+
+ (setq width (min window-width
+ company-tooltip-maximum-width
+ (max company-tooltip-minimum-width
+ (if company-show-quick-access
+ (+ 2 width)
+ width))))
+
+ (when company-tooltip-width-grow-only
+ (setq width (max company--tooltip-current-width width))
+ (setq company--tooltip-current-width width))
+
+ (let ((items (nreverse items))
+ (row (if company-show-quick-access 0 99999))
+ new)
+ (when previous
+ (push (company--scrollpos-line previous width left-margin-size) new))
+
+ (dotimes (i len)
+ (let* ((item (pop items))
+ (str (car item))
+ (annotation (cadr item))
+ (left (nth 2 item))
+ (right (company-space-string company-tooltip-margin))
+ (width width)
+ (selected (equal selection i)))
+ (when company-show-quick-access
+ (let ((quick-access (gv-ref (if (eq company-show-quick-access 'left)
+ left right)))
+ (qa-hint (company-tooltip--format-quick-access-hint
+ row selected)))
+ (cl-decf width (string-width qa-hint))
+ (setf (gv-deref quick-access)
+ (concat qa-hint (gv-deref quick-access))))
+ (cl-incf row))
+ (push (concat
+ (company-fill-propertize str annotation
+ width selected
+ left
+ right)
+ (when scrollbar-bounds
+ (company--scrollbar i scrollbar-bounds)))
+ new)))
+
+ (when remainder
+ (push (company--scrollpos-line remainder width left-margin-size) new))
+
+ (cons
+ left-margin-size
+ (nreverse new)))))
+
+(defun company--scrollbar-bounds (offset limit length)
+ (when (> length limit)
+ (let* ((size (ceiling (* limit (float limit)) length))
+ (lower (floor (* limit (float offset)) length))
+ (upper (+ lower size -1)))
+ (cons lower upper))))
+
+(defun company--scrollbar (i bounds)
+ (propertize " " 'face
+ (if (and (>= i (car bounds)) (<= i (cdr bounds)))
+ 'company-tooltip-scrollbar-thumb
+ 'company-tooltip-scrollbar-track)))
+
+(defun company--scrollpos-line (text width fancy-margin-width)
+ (propertize (concat (company-space-string company-tooltip-margin)
+ (company-safe-substring text 0 width)
+ (company-space-string fancy-margin-width))
+ 'face 'company-tooltip))
+
+(defun company-tooltip--format-quick-access-hint (row selected)
+ "Format a quick-access hint for outputting on a tooltip's ROW.
+Value of SELECTED determines the added face."
+ (propertize (format "%2s" (funcall company-quick-access-hint-function row))
+ 'face
+ (if selected
+ 'company-tooltip-quick-access-selection
+ 'company-tooltip-quick-access)))
+
+;; show
+
+(defvar-local company-pseudo-tooltip-overlay nil)
+
+(defun company--inside-tooltip-p (event-col-row row height)
+ (let* ((ovl company-pseudo-tooltip-overlay)
+ (column (overlay-get ovl 'company-column))
+ (width (overlay-get ovl 'company-width))
+ (evt-col (car event-col-row))
+ (evt-row (cdr event-col-row)))
+ (and (>= evt-col column)
+ (< evt-col (+ column width))
+ (if (> height 0)
+ (and (> evt-row row)
+ (<= evt-row (+ row height) ))
+ (and (< evt-row row)
+ (>= evt-row (+ row height)))))))
+
+(defun company--pseudo-tooltip-height ()
+ "Calculate the appropriate tooltip height.
+Returns a negative number if the tooltip should be displayed above point."
+ (let* ((lines (company--row))
+ (below (- (company--window-height) 1 lines)))
+ (if (and (< below (min company-tooltip-minimum company-candidates-length))
+ (> lines below))
+ (- (max 3 (min company-tooltip-limit lines)))
+ (max 3 (min company-tooltip-limit below)))))
+
+(defun company-pseudo-tooltip-show (row column selection)
+ (company-pseudo-tooltip-hide)
+
+ (let* ((height (company--pseudo-tooltip-height))
+ above)
+
+ (when (< height 0)
+ (setq row (+ row height -1)
+ above t))
+
+ ;; This can happen in Emacs versions which allow arbitrary scrolling,
+ ;; such as Yamamoto's Mac Port.
+ (unless (pos-visible-in-window-p (window-start))
+ (cl-decf row))
+
+ (let (nl beg end ov args)
+ (save-excursion
+ (setq nl (< (move-to-window-line row) row)
+ beg (point)
+ end (save-excursion
+ (move-to-window-line (+ row (abs height)))
+ (point))
+ ov (make-overlay beg end nil t)
+ args (list (mapcar 'company-plainify
+ (company-buffer-lines beg end))
+ column nl above)))
+
+ (setq company-pseudo-tooltip-overlay ov)
+ (overlay-put ov 'company-replacement-args args)
+
+ (let* ((lines-and-offset (company--create-lines selection (abs height)))
+ (lines (cdr lines-and-offset))
+ (column-offset (car lines-and-offset)))
+ (overlay-put ov 'company-display
+ (apply 'company--replacement-string
+ lines column-offset args))
+ (overlay-put ov 'company-width (string-width (car lines))))
+
+ (overlay-put ov 'company-column column)
+ (overlay-put ov 'company-height height))))
+
+(defun company-pseudo-tooltip-show-at-point (pos column-offset)
+ (let* ((col-row (company--col-row pos))
+ (col (- (car col-row) column-offset)))
+ (when (< col 0) (setq col 0))
+ (company-pseudo-tooltip-show (1+ (cdr col-row)) col company-selection)))
+
+(defun company-pseudo-tooltip-edit (selection)
+ (let* ((height (overlay-get company-pseudo-tooltip-overlay 'company-height))
+ (lines-and-offset (company--create-lines selection (abs height)))
+ (lines (cdr lines-and-offset))
+ (column-offset (car lines-and-offset)))
+ (overlay-put company-pseudo-tooltip-overlay 'company-width
+ (string-width (car lines)))
+ (overlay-put company-pseudo-tooltip-overlay 'company-display
+ (apply 'company--replacement-string
+ lines column-offset
+ (overlay-get company-pseudo-tooltip-overlay
+ 'company-replacement-args)))))
+
+(defun company-pseudo-tooltip-hide ()
+ (when company-pseudo-tooltip-overlay
+ (delete-overlay company-pseudo-tooltip-overlay)
+ (setq company-pseudo-tooltip-overlay nil)))
+
+(defun company-pseudo-tooltip-hide-temporarily ()
+ (when (overlayp company-pseudo-tooltip-overlay)
+ (overlay-put company-pseudo-tooltip-overlay 'invisible nil)
+ (overlay-put company-pseudo-tooltip-overlay 'line-prefix nil)
+ (overlay-put company-pseudo-tooltip-overlay 'before-string nil)
+ (overlay-put company-pseudo-tooltip-overlay 'display nil)
+ (overlay-put company-pseudo-tooltip-overlay 'face nil)))
+
+(defun company-pseudo-tooltip-unhide ()
+ (when company-pseudo-tooltip-overlay
+ (let* ((ov company-pseudo-tooltip-overlay)
+ (disp (overlay-get ov 'company-display)))
+ ;; Beat outline's folding overlays.
+ ;; And Flymake (53). And Flycheck (110).
+ (overlay-put ov 'priority 111)
+ ;; visual-line-mode
+ (when (and (memq (char-before (overlay-start ov)) '(?\s ?\t))
+ ;; not eob
+ (not (nth 2 (overlay-get ov 'company-replacement-args))))
+ (setq disp (concat "\n" disp)))
+ ;; No (extra) prefix for the first line.
+ (overlay-put ov 'line-prefix "")
+ (overlay-put ov 'before-string disp)
+ ;; `display' is better than `invisible':
+ ;; https://debbugs.gnu.org/18285
+ ;; https://debbugs.gnu.org/20847
+ ;; https://debbugs.gnu.org/42521
+ (overlay-put ov 'display "")
+ (overlay-put ov 'window (selected-window)))))
+
+(defun company-pseudo-tooltip-guard ()
+ (list
+ (save-excursion (beginning-of-visual-line))
+ (window-width)
+ (let ((ov company-pseudo-tooltip-overlay)
+ (overhang (save-excursion (end-of-visual-line)
+ (- (line-end-position) (point)))))
+ (when (>= (overlay-get ov 'company-height) 0)
+ (cons
+ (buffer-substring-no-properties (point) (overlay-start ov))
+ (when (>= overhang 0) overhang))))))
+
+(defun company-pseudo-tooltip-frontend (command)
+ "`company-mode' frontend similar to a tooltip but based on overlays."
+ (cl-case command
+ (pre-command (company-pseudo-tooltip-hide-temporarily))
+ (unhide
+ (let ((ov company-pseudo-tooltip-overlay))
+ (when (> (overlay-get ov 'company-height) 0)
+ ;; Sleight of hand: if the current line wraps, we adjust the
+ ;; start of the overlay so that the popup does not zig-zag,
+ ;; but don't update the popup's background. This seems just
+ ;; non-annoying enough to avoid the work required for the latter.
+ (save-excursion
+ (vertical-motion 1)
+ (unless (= (point) (overlay-start ov))
+ (move-overlay ov (point) (overlay-end ov))))))
+ (company-pseudo-tooltip-unhide))
+ (post-command
+ (unless (when (overlayp company-pseudo-tooltip-overlay)
+ (let* ((ov company-pseudo-tooltip-overlay)
+ (old-height (overlay-get ov 'company-height))
+ (new-height (company--pseudo-tooltip-height)))
+ (and
+ (>= (* old-height new-height) 0)
+ (>= (abs old-height) (abs new-height))
+ (equal (company-pseudo-tooltip-guard)
+ (overlay-get ov 'company-guard)))))
+ ;; Redraw needed.
+ (company-pseudo-tooltip-show-at-point (point) (length company-prefix))
+ (overlay-put company-pseudo-tooltip-overlay
+ 'company-guard (company-pseudo-tooltip-guard)))
+ (company-pseudo-tooltip-unhide))
+ (show (setq company--tooltip-current-width 0))
+ (hide (company-pseudo-tooltip-hide)
+ (setq company-tooltip-offset 0))
+ (update (when (overlayp company-pseudo-tooltip-overlay)
+ (company-pseudo-tooltip-edit company-selection)))
+ (select-mouse
+ (let ((event-col-row (company--event-col-row company-mouse-event))
+ (ovl-row (company--row))
+ (ovl-height (and company-pseudo-tooltip-overlay
+ (min (overlay-get company-pseudo-tooltip-overlay
+ 'company-height)
+ company-candidates-length))))
+ (cond ((and ovl-height
+ (company--inside-tooltip-p event-col-row ovl-row ovl-height))
+ (company-set-selection (+ (cdr event-col-row)
+ (1- company-tooltip-offset)
+ (if (and (eq company-tooltip-offset-display 'lines)
+ (not (zerop company-tooltip-offset)))
+ -1 0)
+ (- ovl-row)
+ (if (< ovl-height 0)
+ (- 1 ovl-height)
+ 0)))
+ t))))))
+
+(defun company-pseudo-tooltip-unless-just-one-frontend (command)
+ "`company-pseudo-tooltip-frontend', but not shown for single candidates."
+ (unless (and (memq command '(post-command unhide))
+ (company--show-inline-p))
+ (company-pseudo-tooltip-frontend command)))
+
+(defun company-pseudo-tooltip--ujofwd-on-timer (command)
+ (when company-candidates
+ (company-pseudo-tooltip-unless-just-one-frontend-with-delay command)))
+
+(defun company-pseudo-tooltip-unless-just-one-frontend-with-delay (command)
+ "`compandy-pseudo-tooltip-frontend', but shown after a delay.
+Delay is determined by `company-tooltip-idle-delay'."
+ (defvar company-preview-overlay)
+ (when (and (memq command '(pre-command hide))
+ company-tooltip-timer)
+ (cancel-timer company-tooltip-timer)
+ (setq company-tooltip-timer nil))
+ (cl-case command
+ (post-command
+ (if (or company-tooltip-timer
+ (overlayp company-pseudo-tooltip-overlay))
+ (if (not (overlayp company-preview-overlay))
+ (company-pseudo-tooltip-unless-just-one-frontend command)
+ (let (company-tooltip-timer)
+ (company-call-frontends 'pre-command))
+ (company-call-frontends 'post-command))
+ (setq company-tooltip-timer
+ (run-with-timer company-tooltip-idle-delay nil
+ 'company-pseudo-tooltip--ujofwd-on-timer
+ 'post-command))))
+ (unhide
+ (when (overlayp company-pseudo-tooltip-overlay)
+ (company-pseudo-tooltip-unless-just-one-frontend command)))
+ (t
+ (company-pseudo-tooltip-unless-just-one-frontend command))))
+
+;;; overlay ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defvar-local company-preview-overlay nil)
+
+(defun company-preview-show-at-point (pos completion)
+ (company-preview-hide)
+
+ (let* ((company-common (and company-common
+ (string-prefix-p company-prefix company-common)
+ company-common))
+ (common (company--common-or-matches completion)))
+ (setq completion (copy-sequence (company--pre-render completion)))
+ (add-face-text-property 0 (length completion) 'company-preview
+ nil completion)
+
+ (cl-loop for (beg . end) in common
+ do (add-face-text-property beg end 'company-preview-common
+ nil completion))
+
+ ;; Add search string
+ (and (string-match (funcall company-search-regexp-function
+ company-search-string)
+ completion)
+ (pcase-dolist (`(,mbeg . ,mend) (company--search-chunks))
+ (add-face-text-property mbeg mend 'company-preview-search
+ nil completion)))
+
+ (setq completion (if (string-prefix-p company-prefix completion
+ (eq (company-call-backend 'ignore-case)
+ 'keep-prefix))
+ (company-strip-prefix completion)
+ completion))
+
+ (and (equal pos (point))
+ (not (equal completion ""))
+ (add-text-properties 0 1 '(cursor 1) completion))
+
+ (let* ((beg pos)
+ (pto company-pseudo-tooltip-overlay)
+ (ptf-workaround (and
+ pto
+ (char-before pos)
+ (eq pos (overlay-start pto)))))
+ ;; Try to accommodate for the pseudo-tooltip overlay,
+ ;; which may start at the same position if it's at eol.
+ (when ptf-workaround
+ (cl-decf beg)
+ (setq completion (concat (buffer-substring beg pos) completion)))
+
+ (setq company-preview-overlay (make-overlay beg pos))
+
+ (let ((ov company-preview-overlay))
+ (overlay-put ov (if ptf-workaround 'display 'after-string)
+ completion)
+ (overlay-put ov 'window (selected-window))))))
+
+(defun company-preview-hide ()
+ (when company-preview-overlay
+ (delete-overlay company-preview-overlay)
+ (setq company-preview-overlay nil)))
+
+(defun company-preview-frontend (command)
+ "`company-mode' frontend showing the selection as if it had been inserted."
+ (pcase command
+ (`pre-command (company-preview-hide))
+ (`unhide
+ (when company-selection
+ (let* ((current (nth company-selection company-candidates))
+ (company-prefix (if (equal current company-prefix)
+ ;; Would be more accurate to compare lengths,
+ ;; but this is shorter.
+ current
+ (buffer-substring
+ (- company-point (length company-prefix))
+ (point)))))
+ (company-preview-show-at-point (point) current))))
+ (`post-command
+ (when company-selection
+ (company-preview-show-at-point (point)
+ (nth company-selection company-candidates))))
+ (`hide (company-preview-hide))))
+
+(defun company-preview-if-just-one-frontend (command)
+ "`company-preview-frontend', but only shown for single candidates."
+ (when (or (not (memq command '(post-command unhide)))
+ (company--show-inline-p))
+ (company-preview-frontend command)))
+
+(defun company--show-inline-p ()
+ (and (not (cdr company-candidates))
+ company-common
+ (not (eq t (compare-strings company-prefix nil nil
+ (car company-candidates) nil nil
+ t)))
+ (or (eq (company-call-backend 'ignore-case) 'keep-prefix)
+ (string-prefix-p company-prefix company-common))))
+
+(defun company-tooltip-visible-p ()
+ "Returns whether the tooltip is visible."
+ (when (overlayp company-pseudo-tooltip-overlay)
+ (not (overlay-get company-pseudo-tooltip-overlay 'invisible))))
+
+(defun company-preview-common--show-p ()
+ "Returns whether the preview of common can be showed or not"
+ (and company-common
+ (or (eq (company-call-backend 'ignore-case) 'keep-prefix)
+ (string-prefix-p company-prefix company-common))))
+
+(defun company-preview-common-frontend (command)
+ "`company-mode' frontend preview the common part of candidates."
+ (when (or (not (memq command '(post-command unhide)))
+ (company-preview-common--show-p))
+ (pcase command
+ (`pre-command (company-preview-hide))
+ ((or 'post-command 'unhide)
+ (company-preview-show-at-point (point) company-common))
+ (`hide (company-preview-hide)))))
+
+;;; echo ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defvar-local company-echo-last-msg nil)
+
+(defvar company-echo-timer nil)
+
+(defvar company-echo-delay .01)
+
+(defcustom company-echo-truncate-lines t
+ "Whether frontend messages written to the echo area should be truncated."
+ :type 'boolean
+ :package-version '(company . "0.9.3"))
+
+(defun company-echo-show (&optional getter)
+ (when getter
+ (setq company-echo-last-msg (funcall getter)))
+ (let ((message-log-max nil)
+ (message-truncate-lines company-echo-truncate-lines))
+ (if company-echo-last-msg
+ (message "%s" company-echo-last-msg)
+ (message ""))))
+
+(defun company-echo-show-soon (&optional getter delay)
+ (company-echo-cancel)
+ (setq company-echo-timer (run-with-timer (or delay company-echo-delay)
+ nil
+ 'company-echo-show getter)))
+
+(defun company-echo-cancel (&optional unset)
+ (when company-echo-timer
+ (cancel-timer company-echo-timer))
+ (when unset
+ (setq company-echo-timer nil)))
+
+(defun company-echo-format ()
+ (let ((selection (or company-selection 0)))
+ (let ((limit (window-body-width (minibuffer-window)))
+ (len -1)
+ (candidates (nthcdr selection company-candidates))
+ (numbered (if company-show-quick-access selection 99999))
+ (qa-keys-len (length company-quick-access-keys))
+ comp msg)
+
+ (while candidates
+ (setq comp (propertize
+ (company-reformat (company--clean-string (pop candidates)))
+ 'face
+ 'company-echo)
+ len (+ len 1 (length comp)))
+ (let ((beg 0)
+ (end (string-width (or company-common ""))))
+ (when (< numbered qa-keys-len)
+ (let ((qa-hint
+ (format "%s: " (funcall
+ company-quick-access-hint-function
+ numbered))))
+ (setq beg (string-width qa-hint)
+ end (+ beg end))
+ (cl-incf len beg)
+ (setq comp (propertize (concat qa-hint comp) 'face 'company-echo)))
+ (cl-incf numbered))
+ ;; FIXME: Add support for the `match' backend action, and thus,
+ ;; non-prefix matches.
+ (add-text-properties beg end '(face company-echo-common) comp))
+ (if (>= len limit)
+ (setq candidates nil)
+ (push comp msg)))
+
+ (mapconcat 'identity (nreverse msg) " "))))
+
+(defun company-echo-strip-common-format ()
+ (let ((selection (or company-selection 0)))
+ (let ((limit (window-body-width (minibuffer-window)))
+ (len (+ (length company-prefix) 2))
+ (candidates (nthcdr selection company-candidates))
+ (numbered (if company-show-quick-access selection 99999))
+ (qa-keys-len (length company-quick-access-keys))
+ comp msg)
+
+ (while candidates
+ (setq comp (company-strip-prefix (pop candidates))
+ len (+ len 2 (length comp)))
+ (when (< numbered qa-keys-len)
+ (let ((qa-hint (format " (%s)"
+ (funcall company-quick-access-hint-function
+ numbered))))
+ (setq comp (concat comp qa-hint))
+ (cl-incf len (string-width qa-hint)))
+ (cl-incf numbered))
+ (if (>= len limit)
+ (setq candidates nil)
+ (push (propertize comp 'face 'company-echo) msg)))
+
+ (concat (propertize company-prefix 'face 'company-echo-common) "{"
+ (mapconcat 'identity (nreverse msg) ", ")
+ "}"))))
+
+(defun company-echo-hide ()
+ (unless (equal company-echo-last-msg "")
+ (setq company-echo-last-msg "")
+ (company-echo-show)))
+
+(defun company-echo-frontend (command)
+ "`company-mode' frontend showing the candidates in the echo area."
+ (pcase command
+ (`post-command (company-echo-show-soon 'company-echo-format 0))
+ (`hide (company-echo-hide))))
+
+(defun company-echo-strip-common-frontend (command)
+ "`company-mode' frontend showing the candidates in the echo area."
+ (pcase command
+ (`post-command (company-echo-show-soon 'company-echo-strip-common-format 0))
+ (`hide (company-echo-hide))))
+
+(defun company-echo-metadata-frontend (command)
+ "`company-mode' frontend showing the documentation in the echo area."
+ (pcase command
+ (`post-command (company-echo-show-soon 'company-fetch-metadata))
+ (`unhide (company-echo-show))
+ (`hide (company-echo-hide))))
+
+(provide 'company)
+;;; company.el ends here
diff --git a/elpa/company-20220425.1145/company.elc b/elpa/company-20220425.1145/company.elc
new file mode 100644
index 0000000..a27cb89
--- /dev/null
+++ b/elpa/company-20220425.1145/company.elc
Binary files differ
diff --git a/elpa/company-20220425.1145/company.info b/elpa/company-20220425.1145/company.info
new file mode 100644
index 0000000..c01ccb5
--- /dev/null
+++ b/elpa/company-20220425.1145/company.info
@@ -0,0 +1,1695 @@
+This is company.info, produced by makeinfo version 6.7 from
+company.texi.
+
+This user manual is for Company version 0.9.14snapshot (8 January 2022).
+
+Copyright © 2021-2022 Free Software Foundation, Inc.
+
+ Permission is granted to copy, distribute and/or modify this
+ document under the terms of the GNU Free Documentation License,
+ Version 1.3 or any later version published by the Free Software
+ Foundation.
+INFO-DIR-SECTION Emacs misc features
+START-INFO-DIR-ENTRY
+* Company: (company). A modular text completion framework.
+END-INFO-DIR-ENTRY
+
+
+File: company.info, Node: Top, Next: Overview, Up: (dir)
+
+Company
+*******
+
+Company is a modular text completion framework for GNU Emacs.
+
+The goal of this document is to lay out the foundational knowledge of
+the package, so that the readers of the manual could competently start
+adapting Company to their needs and preferences.
+
+This user manual is for Company version 0.9.14snapshot (8 January 2022).
+
+Copyright © 2021-2022 Free Software Foundation, Inc.
+
+ Permission is granted to copy, distribute and/or modify this
+ document under the terms of the GNU Free Documentation License,
+ Version 1.3 or any later version published by the Free Software
+ Foundation.
+
+* Menu:
+
+* Overview:: Terminology and Structure
+* Getting Started:: Quick Start Guide
+* Customization:: User Options
+* Frontends:: Frontends Usage Instructions
+* Backends:: Backends Usage Instructions
+* Troubleshooting:: When Something Goes Wrong
+* Index::
+
+— The Detailed Node Listing —
+
+Overview
+
+* Terminology::
+* Structure::
+
+Getting Started
+
+* Installation::
+* Initial Setup::
+* Usage Basics::
+* Commands::
+
+Customization
+
+* Customization Interface::
+* Configuration File::
+
+Frontends
+
+* Tooltip Frontends::
+* Preview Frontends::
+* Echo Frontends::
+* Candidates Search::
+* Filter Candidates::
+* Quick Access a Candidate::
+
+Backends
+
+* Backends Usage Basics::
+* Grouped Backends::
+* Package Backends::
+* Candidates Post-Processing::
+
+
+
+File: company.info, Node: Overview, Next: Getting Started, Prev: Top, Up: Top
+
+1 Overview
+**********
+
+“Company” is a modular text completion framework for GNU Emacs.
+
+In other words, it is a package for retrieving, manipulating, and
+displaying text completion candidates. It aims to assist developers,
+writers, and scientists during code and text writing.
+
+* Menu:
+
+* Terminology::
+* Structure::
+
+
+File: company.info, Node: Terminology, Next: Structure, Up: Overview
+
+1.1 Terminology
+===============
+
+“Completion” is an act of intelligibly guessing possible variants of
+words based on already typed characters. To “complete” a word means to
+insert a correctly guessed variant into the buffer.
+
+Consequently, the “candidates” are the aforementioned guessed variants
+of words. Each of the candidates has the potential to be chosen for
+successful completion. And each of the candidates contains the
+initially typed characters: either only at the beginning (so-called
+“prefix matches”), or also inside (“non-prefix matches”) of a candidate
+(1).
+
+The package’s name “Company” is based on the combination of the two
+words: ‘Complete’ and ‘Anything’. These words reflect the package’s
+commitment to handling completion candidates and its extensible nature
+allowing it to cover a wide range of usage scenarios.
+
+ ---------- Footnotes ----------
+
+ (1) A good starting point to learn about types of matches is to play
+with the Emacs’s user option ‘completion-styles’. For illustrations on
+how Company visualizes the matches, *note Frontends::.
+
+
+File: company.info, Node: Structure, Prev: Terminology, Up: Overview
+
+1.2 Structure
+=============
+
+The Company is easily extensible because its significant building blocks
+are pluggable modules: backends (*note Backends::) and frontends (*note
+Frontends::).
+
+The “backends” are responsible for retrieving completion candidates;
+which are then outputted by the “frontends”. For an easy and quick
+initial setup, Company is supplied with the preconfigured sets of the
+backends and frontends. The default behavior of the modules can be
+adjusted per particular needs, goals, and preferences. It is also
+typical to utilize backends from a variety of third-party libraries
+(https://github.com/company-mode/company-mode/wiki/Third-Party-Packages),
+developed to be pluggable with Company.
+
+But Company consists not only of the backends and frontends.
+
+A core of the package plays the role of a controller, connecting the
+modules, making them work together; and exposing configurations and
+commands for a user to operate with. For more details, *note
+Customization:: and *note Commands::.
+
+Also, Company is bundled with an alternative workflow configuration
+“company-tng” — defining ‘company-tng-frontend’, ‘company-tng-mode’, and
+‘company-tng-map’ — that allows performing completion with just <TAB>.
+To enable this configuration, add the following line to the Emacs
+initialization file (*note (emacs)Init File::):
+
+ (add-hook 'after-init-hook 'company-tng-mode)
+
+
+File: company.info, Node: Getting Started, Next: Customization, Prev: Overview, Up: Top
+
+2 Getting Started
+*****************
+
+This chapter provides basic instructions for Company setup and usage.
+
+* Menu:
+
+* Installation::
+* Initial Setup::
+* Usage Basics::
+* Commands::
+
+
+File: company.info, Node: Installation, Next: Initial Setup, Up: Getting Started
+
+2.1 Installation
+================
+
+Company package is distributed via commonly used package archives in a
+form of both stable and development releases. To install Company, type
+‘M-x package-install <RET> company <RET>’.
+
+For more details on Emacs package archives, *note (emacs)Packages::.
+
+
+File: company.info, Node: Initial Setup, Next: Usage Basics, Prev: Installation, Up: Getting Started
+
+2.2 Initial Setup
+=================
+
+The package Company provides a minor mode “company-mode”.
+
+To activate the _company-mode_, execute the command ‘M-x company-mode’
+that toggles the mode on and off. When it is switched on, the mode line
+(*note (emacs)Mode line::) should indicate its presence with an
+indicator ‘company’.
+
+After _company-mode_ had been enabled, the package auto-starts
+suggesting completion candidates. The candidates are retrieved and
+shown according to the typed characters and the default (until a user
+specifies otherwise) configurations.
+
+To have Company always enabled for the following sessions, add the line
+‘(global-company-mode)’ to the Emacs configuration file
+(*note (emacs)Init File::).
+
+
+File: company.info, Node: Usage Basics, Next: Commands, Prev: Initial Setup, Up: Getting Started
+
+2.3 Usage Basics
+================
+
+By default — having _company-mode_ enabled (*note Initial Setup::) — a
+tooltip with completion candidates is shown when a user types in a few
+characters.
+
+To initiate completion manually, use the command ‘M-x company-complete’.
+
+To select next or previous of the shown completion candidates, use
+respectively key bindings ‘C-n’ and ‘C-p’, then do one of the following:
+
+ • Hit <RET> to choose a selected candidate for completion.
+
+ • Hit <TAB> to complete with the “common part”: characters present at
+ the beginning of all the candidates.
+
+ • Hit ‘C-g’ to stop activity of Company.
+
+
+File: company.info, Node: Commands, Prev: Usage Basics, Up: Getting Started
+
+2.4 Commands
+============
+
+Under the hood, mentioned in the previous section keys are bound to the
+commands of the out-of-the-box Company.
+
+‘C-n’
+‘M-n’
+ Select the next candidate (‘company-select-next-or-abort’,
+ ‘company-select-next’).
+
+‘C-p’
+‘M-p’
+ Select the previous candidate (‘company-select-previous-or-abort’,
+ ‘company-select-previous’).
+
+‘RET’
+‘<return>’
+ Insert the selected candidate (‘company-complete-selection’).
+
+‘TAB’
+‘<tab>’
+ Insert the common part of all the candidates
+ (‘company-complete-common’).
+
+‘C-g’
+‘<ESC ESC ESC>’
+ Cancel _company-mode_ activity (‘company-abort’).
+
+‘C-h’
+‘<f1>’
+ Display a buffer with the documentation for the selected candidate
+ (‘company-show-doc-buffer’).
+
+‘C-w’
+ Display a buffer with the definition of the selected candidate
+ (‘company-show-location’).
+
+The full list of the default key bindings is stored in the variables
+‘company-active-map’ and ‘company-search-map’ (1).
+
+Moreover, Company is bundled with a number of convenience commands that
+do not have default key bindings defined. The following examples
+illustrate how to assign key bindings to such commands.
+
+ (global-set-key (kbd "<tab>") #'company-indent-or-complete-common)
+
+ (with-eval-after-load 'company
+ (define-key company-active-map (kbd "M-/") #'company-complete))
+
+ (with-eval-after-load 'company
+ (define-key company-active-map
+ (kbd "TAB")
+ #'company-complete-common-or-cycle)
+ (define-key company-active-map
+ (kbd "<backtab>")
+ (lambda ()
+ (interactive)
+ (company-complete-common-or-cycle -1))))
+
+In the same manner, an additional key can be assigned to a command or a
+command can be unbound from a key. For instance:
+
+ (with-eval-after-load 'company
+ (define-key company-active-map (kbd "M-.") #'company-show-location)
+ (define-key company-active-map (kbd "RET") nil))
+
+ ---------- Footnotes ----------
+
+ (1) For a more user-friendly output of the pre-defined key bindings,
+utilize ‘M-x describe-keymap <RET> company-active-map’ or
+‘C-h f <RET> company-mode’.
+
+
+File: company.info, Node: Customization, Next: Frontends, Prev: Getting Started, Up: Top
+
+3 Customization
+***************
+
+Emacs provides two equally acceptable ways for user preferences
+configuration: via customization interface (for more details, *note
+(emacs)Easy Customization::) and a configuration file
+(*note (emacs)Init File::). Naturally, Company can be configured by
+both of these approaches.
+
+* Menu:
+
+* Customization Interface::
+* Configuration File::
+
+
+File: company.info, Node: Customization Interface, Next: Configuration File, Up: Customization
+
+3.1 Customization Interface
+===========================
+
+In order to employ the customization interface, run
+‘M-x customize-group <RET> company’.
+
+This interface outputs all the options available for user customization,
+so you may find it beneficial to review this list even if you are going
+to configure Company with the configuration file.
+
+For instructions on how to change the settings, *note (emacs)Changing a
+Variable::.
+
+
+File: company.info, Node: Configuration File, Prev: Customization Interface, Up: Customization
+
+3.2 Configuration File
+======================
+
+Company is a customization-rich package. This section lists some of the
+core settings that influence the overall behavior of the _company-mode_.
+
+ -- User Option: company-minimum-prefix-length
+ This is one of the values (together with ‘company-idle-delay’),
+ based on which Company auto-stars looking up completion candidates.
+ This option configures how many characters have to be typed in by a
+ user before candidates start to be collected and displayed. An
+ often choice nowadays is to configure this option to a lower number
+ than the default value of ‘3’.
+
+ -- User Option: company-idle-delay
+ This is the second of the options that configure Company’s
+ auto-start behavior (together with
+ ‘company-minimum-prefix-length’). The value of this option defines
+ how fast Company is going to react to the typed input, such that
+ setting ‘company-idle-delay’ to ‘0’ makes Company react
+ immediately, ‘nil’ disables auto-starting, and a larger value
+ postpones completion auto-start for that number of seconds. For an
+ even fancier setup, set this option value to a predicate function,
+ as shown in the following example:
+
+ (setq company-idle-delay
+ (lambda () (if (company-in-string-or-comment) nil 0.3)))
+
+ -- User Option: company-global-modes
+ This option allows to specify in which major modes _company-mode_
+ can be enabled by ‘(global-company-mode)’. *Note Initial Setup::.
+ The default value of ‘t’ enables Company in all major modes.
+ Setting ‘company-global-modes’ to ‘nil’ equal in action to toggling
+ off _global-company-mode_. Providing a list of major modes results
+ in having _company-mode_ enabled in the listed modes only. For the
+ opposite result, provide a list of major modes with ‘not’ being the
+ first element of the list, as shown in the following example:
+
+ (setq company-global-modes '(not erc-mode message-mode eshell-mode))
+
+ -- User Option: company-selection-wrap-around
+ Enable this option to loop (cycle) the candidates’ selection: after
+ selecting the last candidate on the list, a command to select the
+ next candidate does so with the first candidate. By default, this
+ option is disabled, which means the selection of the next candidate
+ stops on the last item. The selection of the previous candidate is
+ influenced by this option similarly.
+
+ -- User Option: company-require-match
+ To allow typing in characters that don’t match the candidates, set
+ the value of this option to ‘nil’. For an opposite behavior (that
+ is, to disallow non-matching input), set it to ‘t’. By default,
+ Company is configured to require a matching input only if a user
+ manually enables completion or selects a candidate; by having the
+ option configured to call the function ‘company-explicit-action-p’.
+
+ -- User Option: company-lighter-base
+ This user options allows to configure a string indicator of the
+ enabled _company-mode_ in the mode line. The default value is
+ ‘company’.
+
+ -- User Option: company-insertion-on-trigger
+ One more pair of the user options may instruct Company to complete
+ with the selected candidate by typing one of the
+ ‘company-insertion-triggers’. The user option
+ ‘company-insertion-on-trigger’ can be enabled or disabled by
+ setting its value to one of: ‘nil’, ‘t’, or a predicate function
+ name. *note Predicate: (eintr)Wrong Type of Argument.
+
+ -- User Option: company-insertion-triggers
+ This option has an effect only when ‘company-insertion-on-trigger’
+ is enabled. The value can be one of: a string of characters, a
+ list of syntax description characters (*note (elisp)Syntax Class
+ Table::), or a predicate function. By default, this user option is
+ set to the list of the syntax characters: ‘(?\ ?\) ?.)’, which
+ translates to the whitespaces, close parenthesis, and punctuation.
+ It is safe to configure the value to a character that can
+ potentially be part of a valid completion; in this case, Company
+ does not treat such characters as triggers.
+
+Hooks
+-----
+
+Company exposes the following life-cycle hooks:
+
+ -- User Option: company-completion-started-hook
+
+ -- User Option: company-completion-cancelled-hook
+
+ -- User Option: company-completion-finished-hook
+
+ -- User Option: company-after-completion-hook
+
+
+File: company.info, Node: Frontends, Next: Backends, Prev: Customization, Up: Top
+
+4 Frontends
+***********
+
+Company is packaged with several frontends and provides a predefined set
+of enabled frontends. A list of the enabled frontends can be changed by
+configuring the user option ‘company-frontends’.
+
+Each frontend is simply a function that receives a command and acts
+accordingly to it: outputs candidates, hides its output, refreshes
+displayed data, and so on.
+
+All of the Company frontends can be categorized by the type of the
+output into the three groups: “tooltip-”, “preview-”, and “echo-”
+frontends. We overview these groups in the first sections of this
+chapter. The sections that follow are dedicated to the ways the
+displayed candidates can be searched, filtered, and quick-accessed.
+
+* Menu:
+
+* Tooltip Frontends::
+* Preview Frontends::
+* Echo Frontends::
+* Candidates Search::
+* Filter Candidates::
+* Quick Access a Candidate::
+
+
+File: company.info, Node: Tooltip Frontends, Next: Preview Frontends, Up: Frontends
+
+4.1 Tooltip Frontends
+=====================
+
+This group of frontends displays completion candidates in an overlayed
+tooltip (aka pop-up). Company provides three _tooltip frontends_,
+listed below.
+
+ -- Function: company-pseudo-tooltip-unless-just-one-frontend
+ This is one of the default frontends. It starts displaying a
+ tooltip only if more than one completion candidate is available,
+ which nicely combines — and it is done so by default — with
+ ‘company-preview-if-just-one-frontend’, *note Preview Frontends::.
+
+ -- Function: company-pseudo-tooltip-frontend
+ This frontend outputs a tooltip for any number of completion
+ candidates.
+
+ -- Function: company-pseudo-tooltip-unless-just-one-frontend-with-delay
+ This is a peculiar frontend, that displays a tooltip only if more
+ than one candidate is available, and only after a delay. The delay
+ can be configured with the user option
+ ‘company-tooltip-idle-delay’. A typical use case for plugging in
+ this frontend would be displaying a tooltip only on a manual
+ request (when needed), as shown in the following example:
+
+ (setq company-idle-delay 0
+ company-tooltip-idle-delay 10
+ company-require-match nil
+ company-frontends
+ '(company-pseudo-tooltip-unless-just-one-frontend-with-delay
+ company-preview-frontend
+ company-echo-metadata-frontend)
+ company-backends '(company-capf))
+
+ (global-set-key (kbd "<tab>")
+ (lambda ()
+ (interactive)
+ (let ((company-tooltip-idle-delay 0.0))
+ (company-complete)
+ (and company-candidates
+ (company-call-frontends 'post-command)))))
+
+User Options
+------------
+
+To change the _tooltip frontends_ configuration, adjust the following
+user options.
+
+ -- User Option: company-tooltip-align-annotations
+ An “annotation” is a string that carries additional information
+ about a candidate; such as a data type, function arguments, or
+ whatever a backend appoints to be a valuable piece of information
+ about a candidate. By default, the annotations are shown right
+ beside the candidates. Setting the option value to ‘t’ aligns
+ annotations to the right side of the tooltip.
+
+ (setq company-tooltip-align-annotations t)
+
+
+
+ -- User Option: company-tooltip-limit
+ Controls the maximum number of the candidates shown simultaneously
+ in the tooltip (the default value is ‘10’). When the number of the
+ available candidates is larger than this option’s value, Company
+ paginates the results.
+
+ (setq company-tooltip-limit 4)
+
+
+
+ -- User Option: company-tooltip-offset-display
+ Use this option to choose in which way to output paginated results.
+ The default value is ‘scrollbar’. Another supported value is
+ ‘lines’; choose it to show the quantity of the candidates not
+ displayed by the current tooltip page.
+
+ (setq company-tooltip-offset-display 'lines)
+
+
+
+ -- User Option: company-tooltip-minimum
+ This user option acts only when a tooltip is shown close to the
+ bottom of a window. It guarantees visibility of this number of
+ completion candidates below point. When the number of lines
+ between point and the bottom of a window is less than
+ ‘company-tooltip-minimum’ value, the tooltip is displayed above
+ point.
+
+ (setq company-tooltip-minimum 4)
+
+
+
+
+
+
+ -- User Option: company-tooltip-flip-when-above
+ This is one of the fancy features Company has to suggest. When
+ this setting is enabled, no matter if a tooltip is shown above or
+ below point, the candidates are always listed starting near point.
+ (Putting it differently, the candidates are mirrored horizontally
+ if a tooltip changes its position, instead of being commonly listed
+ top-to-bottom.)
+
+ (setq company-tooltip-flip-when-above t)
+
+
+
+ -- User Option: company-tooltip-minimum-width
+ Sets the minimum width of a tooltip, excluding the margins and the
+ scroll bar. Changing this value especially makes sense if a user
+ navigates between tooltip pages. Keeping this value at the default
+ ‘0’ allows Company to always adapt the width of the tooltip to the
+ longest shown candidate. Enlarging ‘company-tooltip-minimum-width’
+ prevents possible significant shifts in the width of the tooltip
+ when navigating to the next/previous tooltip page. (For an
+ alternate solution, see ‘company-tooltip-width-grow-only’.)
+
+ -- User Option: company-tooltip-width-grow-only
+ This is another way to restrict auto-adaptation of the tooltip
+ width (another is by adjusting ‘company-tooltip-minimum-width’
+ value) when navigating between the tooltip pages.
+
+ -- User Option: company-tooltip-maximum-width
+ This user option controls the maximum width of the tooltip inner
+ area. By default, its value is pseudo-limitless, potentially
+ permitting the output of extremely long candidates. But if long
+ lines become an issue, set this option to a smaller number, such as
+ ‘60’ or ‘70’.
+
+ -- User Option: company-tooltip-margin
+ Controls the width of the “margin” on the sides of the tooltip
+ inner area. If ‘company-format-margin-function’ is set,
+ ‘company-tooltip-margin’ defines only the right margin.
+
+ (setq company-tooltip-margin 3)
+
+
+
+Candidates Icons
+----------------
+
+An “icon” is an image or a text that represents a candidate’s kind; it
+is displayed in front of a candidate. The term “kind” here stands for a
+high-level category a candidate fits into. (Such as ‘array’,
+‘function’, ‘file’, ‘string’, ‘color’, etc. For an extended list of the
+possible _kinds_, see the user option ‘company-text-icons-mapping’ or
+the variable ‘company-vscode-icons-mapping’.)
+
+ -- User Option: company-format-margin-function
+ Allows setting a function to format the left margin of a tooltip
+ inner area; namely, to output candidate’s _icons_. The predefined
+ formatting functions are listed below. A user may also set this
+ option to a custom function. To disable left margin formatting,
+ set the value of the option to ‘nil’ (this way control over the
+ size of the left margin returns to the user option
+ ‘company-tooltip-margin’).
+
+ -- Function: company-vscode-dark-icons-margin
+ -- Function: company-vscode-light-icons-margin
+ These functions utilize VSCode dark and light theme icon sets (1).
+ The related two user options are ‘company-icon-size’ and
+ ‘company-icon-margin’.
+
+
+
+ -- Function: company-text-icons-margin
+ This function produces letters and symbols formatted according to
+ the ‘company-text-icons-format’. The rest of the user options
+ affecting this function behavior are listed below.
+
+
+
+ -- Function: company-dot-icons-margin
+ This function produces a colored Unicode symbol of a circle
+ formatted according to the ‘company-dot-icons-format’. Other user
+ options that affect the resulting output are listed below.
+
+
+
+The following user options influence appearance of the _text_ and _dot_
+_icons_.
+
+ -- User Option: company-text-icons-mapping
+ Lists candidates’ _kinds_ with their corresponding _icons_
+ configurations.
+
+ -- User Option: company-text-face-extra-attributes
+ A list of face attributes to be applied to the _icons_.
+
+ (setq company-text-face-extra-attributes
+ '(:weight bold :slant italic))
+
+
+
+ -- User Option: company-text-icons-add-background
+ If this option is enabled, when an _icon_ doesn’t have a background
+ configured by ‘company-text-icons-mapping’, then a generated
+ background is applied.
+
+ (setq company-text-icons-add-background t)
+
+
+
+ -- Function: company-detect-icons-margin
+ This is the default margin formatting function, that applies one of
+ the ‘company-vscode-*-icons-margin’ functions if ‘vscode’ icons set
+ is supported; otherwise applies a ‘company-text-icons-margin’
+ function.
+
+Faces
+-----
+
+Out-of-the-box Company defines and configures distinguished faces (*note
+(emacs)Faces::) for light and dark themes. Moreover, some of the
+built-in and third-party themes fine-tune Company to fit their palettes.
+That is why there’s often no real need to make such adjustments on a
+user side. However, this chapter presents some hints on where to start
+customizing Company interface.
+
+Namely, the look of a tooltip is controlled by the ‘company-tooltip*’
+named faces.
+
+The following example hints how a user may approach tooltip faces
+customization:
+
+ (custom-set-faces
+ '(company-tooltip
+ ((t (:background "ivory" :foreground "MistyRose3"))))
+ '(company-tooltip-selection
+ ((t (:background "LemonChiffon1" :foreground "MistyRose4"))))
+ '(company-tooltip-common ((t (:weight bold :foreground "pink1"))))
+ '(company-scrollbar-fg ((t (:background "ivory3"))))
+ '(company-scrollbar-bg ((t (:background "ivory2"))))
+ '(company-tooltip-annotation ((t (:foreground "MistyRose2")))))
+
+
+
+ ---------- Footnotes ----------
+
+ (1) SVG images support has to be enabled in Emacs for these icons set
+to be used. The supported images types can be checked with ‘C-h v
+image-types’. Before compiling Emacs, make sure ‘librsvg’ is installed
+on your system.
+
+
+File: company.info, Node: Preview Frontends, Next: Echo Frontends, Prev: Tooltip Frontends, Up: Frontends
+
+4.2 Preview Frontends
+=====================
+
+Frontends in this group output a completion candidate or a common part
+of the candidates temporarily inline, as if a word had already been
+completed (1).
+
+ -- Function: company-preview-if-just-one-frontend
+ This is one of the frontends enabled by default. This frontend
+ outputs a preview if only one completion candidate is available; it
+ is a good suit to be combined with
+ ‘company-pseudo-tooltip-unless-just-one-frontend’, *note Tooltip
+ Frontends::.
+
+ -- Function: company-preview-frontend
+ This frontend outputs the first of the available completion
+ candidates inline for a preview.
+
+ -- Function: company-preview-common-frontend
+ As the name of this frontend suggests, it outputs for a preview
+ only a common part of the candidates.
+
+The look of the preview is controlled by the following faces:
+‘company-preview’, ‘company-preview-common’, and
+‘company-preview-search’.
+
+
+
+
+
+
+ ---------- Footnotes ----------
+
+ (1) The candidates retrieved according to ‘non-prefix’ matches (*note
+Terminology::) may be shown in full after point.
+
+
+File: company.info, Node: Echo Frontends, Next: Candidates Search, Prev: Preview Frontends, Up: Frontends
+
+4.3 Echo Frontends
+==================
+
+The frontends listed in this section display information in the Emacs’s
+echo area, *note (emacs)Echo Area::.
+
+ -- Function: company-echo-metadata-frontend
+ This frontend is a part of the predefined frontends set. Its
+ responsibility is to output a short documentation string for a
+ completion candidate in the echo area.
+
+
+
+
+The last pair of the built-in frontends isn’t that commonly used and not
+as full-featured as the previously reviewed _tooltip-_ and _preview-_
+frontends, but still, feel free to play with them and have some fun!
+
+ -- Function: company-echo-frontend
+ This frontend outputs all the available completion candidates in
+ the echo area.
+
+
+
+ -- Function: company-echo-strip-common-frontend
+ It acts similarly to the previous frontend but outputs a common
+ part of the candidates once for all of them.
+
+
+
+ -- User Option: company-echo-truncate-lines
+ This is the only _echo frontends_ targeted setting. When enabled,
+ the output is truncated to fit the echo area. This setting is set
+ to ‘t’ by default.
+
+To apply visual changes to the output of these frontends, configure the
+faces ‘company-echo’ and ‘company-echo-common’.
+
+
+File: company.info, Node: Candidates Search, Next: Filter Candidates, Prev: Echo Frontends, Up: Frontends
+
+4.4 Candidates Search
+=====================
+
+By default, when _company-mode_ is in action, a key binding ‘C-s’ starts
+looking for matches to additionally typed characters among the displayed
+candidates. When a search is initiated, an indicator
+‘Search: CHARACTERS’ is shown in the Emacs’s mode line.
+
+To quit the search mode, hit ‘C-g’.
+
+ -- User Option: company-search-regexp-function
+ The value of this user option must be a function that interprets
+ the search input. By default it is set to the function
+ ‘regexp-quote’, with looks for an exact match. Company defines
+ several more functions suitable for this option. They are listed
+ below.
+
+ -- Function: company-search-words-regexp
+ Searches for words separated with spaces in the given order.
+
+ -- Function: company-search-words-in-any-order-regexp
+ Searches for words separated with spaces in any order.
+
+ -- Function: company-search-flex-regexp
+ Searches for characters in the given order, with anything in
+ between.
+
+Search matches are distinguished by the ‘company-tooltip-search’ and
+‘company-tooltip-search-selection’ faces.
+
+
+
+
+File: company.info, Node: Filter Candidates, Next: Quick Access a Candidate, Prev: Candidates Search, Up: Frontends
+
+4.5 Filter Candidates
+=====================
+
+Candidates filtering is started by typing the default key binding
+‘C-M-s’. Filtering acts on a par with the search (*note Candidates
+Search::), indicating its activation by the text ‘Filter: CHARACTERS’ in
+the mode line and influencing the displayed candidates. The difference
+is that the filtering, as its name suggests, keeps displaying only the
+matching candidates (in addition to distinguishing the matches with a
+face).
+
+To quit the filtering, hit ‘C-g’. To toggle between search and filter
+states, use key binding ‘C-o’.
+
+
+
+
+File: company.info, Node: Quick Access a Candidate, Prev: Filter Candidates, Up: Frontends
+
+4.6 Quick Access a Candidate
+============================
+
+Company provides a way to choose a candidate for completion without
+having to navigate to that candidate: by hitting one of the quick-access
+keys. By default, quick-access key bindings utilize a modifier <META>
+and one of the digits, such that pressing ‘M-1’ completes with the first
+candidate on the list and ‘M-0’ with the tenth candidate.
+
+If ‘company-show-quick-access’ is enabled, _tooltip-_ and _echo-_
+frontends show quick-access hints.
+
+ (setq company-show-quick-access 'left)
+
+
+
+
+
+
+
+
+
+To customize the key bindings, either do it via Customization Interface
+(*note Customization Interface::) or use the following approach:
+
+ (custom-set-variables
+ '(company-quick-access-keys '("a" "o" "e" "u" "i"))
+ '(company-quick-access-modifier 'super))
+
+A modifier should be one of ‘meta’, ‘super’, ‘hyper’, ‘ control’.
+
+The following example applies a bit of customization and demonstrates
+how to change quick-access hints faces.
+
+ (setq company-show-quick-access t)
+
+ (custom-set-faces
+ '(company-tooltip-quick-access ((t (:foreground "pink1"))))
+ '(company-tooltip-quick-access-selection
+ ((t (:foreground "pink1" :slant italic)))))
+
+
+
+
+File: company.info, Node: Backends, Next: Troubleshooting, Prev: Frontends, Up: Top
+
+5 Backends
+**********
+
+We can metaphorically say that each backend is like an engine. (The
+reality is even better since backends are just functions.) Fueling such
+an engine with a command causes the production of material for Company
+to move further on. Typically, moving on means outputting that material
+to a user via one or several configured frontends, *note Frontends::.
+
+Just like Company provides a preconfigured list of the enabled
+frontends, it also defines a list of the backends to rely on by default.
+This list is stored in the user option ‘company-backends’. The
+docstring of this variable has been a source of valuable information for
+years. That’s why we’re going to stick to a tradition and suggest
+reading the output of ‘C-h v company-backends’ for insightful details
+about backends. Nevertheless, the fundamental concepts are described in
+this user manual too.
+
+* Menu:
+
+* Backends Usage Basics::
+* Grouped Backends::
+* Package Backends::
+* Candidates Post-Processing::
+
+
+File: company.info, Node: Backends Usage Basics, Next: Grouped Backends, Up: Backends
+
+5.1 Backends Usage Basics
+=========================
+
+One of the significant concepts to understand about Company is that the
+package relies on one backend at a time (1). The backends are invoked
+one by one, in the sequential order of the items on the
+‘company-backends’ list.
+
+The name of the currently active backend is shown in the mode line and
+in the output of the command ‘M-x company-diag’.
+
+In most cases (mainly to exclude false-positive results), the next
+backend is not invoked automatically. For the purpose of invoking the
+next backend, use the command ‘company-other-backend’: either by calling
+it with ‘M-x’ or by binding the command to the keys of your choice, such
+as:
+
+ (global-set-key (kbd "C-c C-/") #'company-other-backend)
+
+It is also possible to specifically start a backend with the command
+‘M-x company-begin-backend’ or by calling a backend by its name, for
+instance: ‘M-x company-capf’. As usual for Emacs, such backends calls
+can be assigned to key bindings, for example:
+
+ (global-set-key (kbd "C-c y") 'company-yasnippet)
+
+ ---------- Footnotes ----------
+
+ (1) The grouped backends act as one complex backend. *Note Grouped
+Backends::.
+
+
+File: company.info, Node: Grouped Backends, Next: Package Backends, Prev: Backends Usage Basics, Up: Backends
+
+5.2 Grouped Backends
+====================
+
+In many cases, it can be desirable to receive candidates from several
+backends simultaneously. This can be achieved by configuring “grouped
+backends”: a sub-list of backends in the ‘company-backends’ list, that
+is handled specifically by Company.
+
+The most important part of this handling is the merge of the completion
+candidates from the grouped backends. (But only from the backends that
+return the same _prefix_ value, see ‘C-h v company-backends’ for more
+details.)
+
+To keep the candidates organized in accordance with the grouped backends
+order, add the keyword ‘:separate’ to the list of the grouped backends.
+The following example illustrates this.
+
+ (defun my-text-mode-hook ()
+ (setq-local company-backends
+ '((company-dabbrev company-ispell :separate)
+ company-files)))
+
+ (add-hook 'text-mode-hook #'my-text-mode-hook)
+
+Another keyword ‘:with’ helps to make sure the results from major/minor
+mode agnostic backends (such as _company-yasnippet_,
+_company-dabbrev-code_) are returned without preventing results from
+context-aware backends (such as _company-capf_ or _company-clang_). For
+this feature to work, put backends dependent on a mode at the beginning
+of the grouped backends list, then put a keyword ‘:with’, and only then
+put context agnostic backend(s), as shown in the following concise
+example:
+
+ (setq company-backends '((company-capf :with company-yasnippet)))
+
+
+File: company.info, Node: Package Backends, Next: Candidates Post-Processing, Prev: Grouped Backends, Up: Backends
+
+5.3 Package Backends
+====================
+
+The following sections give a short overview of the commonly used
+backends bundled with Company. Each section is devoted to one of the
+roughly outlined groups of the backends.
+
+Some of the backends expose user options for customization; a few of
+these options are introduced below. For those who would like to fetch
+the full list of a backend’s user options, we suggest doing one of the
+following:
+
+ • Execute command ‘M-x customize-group <RET> <backend-name>’.
+
+ • Open the source file of the backend and run
+ ‘M-x occur <RET> ^(defcustom’.
+
+ − Optionally, search for the matches with
+ ‘M-x isearch <RET> (defcustom’.
+
+* Menu:
+
+* Code Completion::
+* Text Completion::
+* File Name Completion::
+* Template Expansion::
+
+
+File: company.info, Node: Code Completion, Next: Text Completion, Up: Package Backends
+
+5.3.1 Code Completion
+---------------------
+
+ -- Function: company-capf
+ In the Emacs’s world, the current tendency is to have the
+ completion logic provided by ‘completion-at-point-functions’ (CAPF)
+ implementations. [Among the other things, this is what the popular
+ packages that support language server protocol (LSP) also rely on.]
+
+ Since _company-capf_ works as a bridge to the standard CAPF
+ facility, it is probably the most often used and recommended
+ backend nowadays, including for Emacs Lisp coding.
+
+ Just to illustrate, the following minimal backends setup
+
+ (setq company-backends '((company-capf company-dabbrev-code)))
+
+ might cover a large number of basic use cases, especially so in
+ major modes that have CAPF support implemented.
+
+ For more details on CAPF, *note (elisp)Completion in Buffers::.
+
+ -- Function: company-dabbrev-code
+ This backend works similarly to the built-in Emacs package
+ _dabbrev_, searching for completion candidates inside the contents
+ of the open buffer(s). Internally, its based on the backend
+ _company-dabbrev_ (*note Text Completion::).
+
+ -- Function: company-keywords
+ This backend provides completions for many of the widely spread
+ programming languages _keywords_: words bearing specific meaning in
+ a language.
+
+ -- Function: company-clang
+ As the name suggests, use this backend to get completions from
+ _Clang_ compiler; that is, for the languages in the _C_ language
+ family: _C_, _C++_, _Objective-C_.
+
+ -- Function: company-semantic
+ This backend relies on a built-in Emacs package that provides
+ language-aware editing commands based on source code parsers, *note
+ (emacs)Semantic::. Having enabled _semantic-mode_ makes it to be
+ used by the CAPF mechanism (*note (emacs)Symbol Completion::),
+ hence a user may consider enabling _company-capf_ backend instead.
+
+ -- Function: company-etags
+ This backend works on top of a built-in Emacs package _etags_,
+ *note (emacs)Tags Tables::. Similarly to aforementioned _Semantic_
+ usage, tags-based completions now are a part of the Emacs’ CAPF
+ facility, therefore a user may consider switching to _company-capf_
+ backend.
+
+
+File: company.info, Node: Text Completion, Next: File Name Completion, Prev: Code Completion, Up: Package Backends
+
+5.3.2 Text Completion
+---------------------
+
+ -- Function: company-dabbrev
+ This backend works similarly to the built-in Emacs package
+ _dabbrev_, searching for completion candidates inside the contents
+ of the open buffer(s). It is one of the often used backends, and
+ it has several interesting options for configuration. Let’s review
+ a few of them.
+
+ -- User Option: company-dabbrev-minimum-length
+ This option sets the minimum length of a completion candidate
+ to collect from the text. The default value of ‘4’ is
+ intended to prevent potential performance issues. But in many
+ scenarios, it may be acceptable to lower this value. Note
+ that this option also affects the behavior of the
+ _company-dabbrev-code_ backend.
+
+ (setq company-dabbrev-minimum-length 2)
+
+ -- User Option: company-dabbrev-other-buffers
+ By default, _company-dabbrev_ collects completion candidates
+ from all not ignored buffers (see more on that below). This
+ behavior can be changed to collecting candidates from the
+ current buffer only (by setting the value to ‘nil’) or from
+ the buffers with the same major mode:
+
+ (setq company-dabbrev-other-buffers t)
+
+ -- User Option: company-dabbrev-ignore-buffers
+ The value of this option should be a regexp or a predicate
+ function that can be used to match a buffer name. The matched
+ buffers are omitted from the search for completion candidates.
+
+ The last two options described here relate to handling uppercase
+ and lowercase letters in completion candidates. The illustrative
+ examples given below can be reproduced in the ‘*scratch*’ buffer,
+ with the word ‘Enjoy’ typed in, and with this initial setup:
+
+ (setq-local company-backends '(company-dabbrev)
+ company-dabbrev-other-buffers nil
+ company-dabbrev-ignore-case nil
+ company-dabbrev-downcase nil)
+
+ -- User Option: company-dabbrev-ignore-case
+ This user option controls whether the case is ignored when
+ collecting completion candidates. When the option is set to
+ ‘nil’, ‘Enjoy’ is suggested as a completion candidate for the
+ typed ‘Enj’ letters, but not for ‘enj’. When the option is
+ set to ‘t’, ‘Enjoy’ is suggested as a candidate for both ‘Enj’
+ and ‘enj’ input; note that ‘enj’ prefix is “overwritten” by
+ completing with the ‘Enjoy’ candidate. The third, default,
+ type of behavior solves this issue, keeping the case of the
+ typed prefix (and still collecting candidates
+ case-insensitively):
+
+ (setq company-dabbrev-ignore-case 'keep-prefix)
+
+ Now we can type ‘enj’, complete it with the suggested ‘Enjoy’,
+ and _enjoy_ the result.
+
+ -- User Option: company-dabbrev-downcase
+ This user option controls whether completion candidates are
+ down-cased before their display. When the option is set to
+ ‘nil’, no transformation is performed; in the environment
+ described above, typing ‘Enj’ results in the candidate ‘Enjoy’
+ being suggested. When the option is set to ‘t’, the
+ down-cased candidate ‘enjoy’ is suggested. By default, this
+ option is set to ‘case-replace’, meaning taking a value of the
+ Emacs’s variable ‘case-replace’ (‘t’ is the current default).
+
+
+ -- Function: company-ispell
+ This backend returns completion candidates collected by _Ispell_, a
+ built-in Emacs package that performs spell-checking. *Note
+ Checking and Correcting Spelling: (emacs)Spelling. Note that
+ _Ispell_ uses only one dictionary at a time (combining several
+ dictionaries into one file is an accepted practice). By default,
+ _company-ispell_ suggests candidates from a dictionary specified by
+ the Emacs’s setting ‘ispell-complete-word-dict’.
+
+ -- User Option: company-ispell-dictionary
+ Optionally, set a file path for _company-ispell_ to use
+ another dictionary.
+
+
+File: company.info, Node: File Name Completion, Next: Template Expansion, Prev: Text Completion, Up: Package Backends
+
+5.3.3 File Name Completion
+--------------------------
+
+ -- Function: company-files
+ This backend can be used to retrieve completion candidates for the
+ absolute and relative paths in the directory structure of an
+ operating system. The behavior of the _company-files_ backend can
+ be adjusted with the two user options.
+
+ -- User Option: company-files-exclusions
+ It may be desirable to exclude directories or files from the
+ list of suggested completion candidates. For example,
+ someone’s setup might look this way:
+
+ (setq company-files-exclusions '(".git/" ".DS_Store"))
+
+ -- User Option: company-files-chop-trailing-slash
+ This setting is enabled by default, which results in stripping
+ off a trailing slash from an inserted directory name. On
+ typing a trailing slash, the process of completion gets
+ started again, from inside the just inserted directory.
+
+ Setting ‘company-files-chop-trailing-slash’ to ‘nil’ makes
+ directory names to be inserted as is, with a trailing slash.
+ In this case, the completion process can be continued, for
+ example, either by explicitly calling _company-files_ backend
+ (*note Backends Usage Basics::) or by starting typing a name
+ of a file/directory known to be located under the inserted
+ directory.
+
+
+File: company.info, Node: Template Expansion, Prev: File Name Completion, Up: Package Backends
+
+5.3.4 Template Expansion
+------------------------
+
+ -- Function: company-abbrev
+ This is a completion backend for a built-in word abbreviation mode
+ (*note (emacs)Abbrevs::), that allows completing abbreviations with
+ their expansions.
+
+ -- Function: company-tempo
+ A backend for users of Tempo
+ (https://www.lysator.liu.se/~davidk/elisp/), one more built-in
+ Emacs package for creating and inserting (expanding) templates.
+
+ -- Function: company-yasnippet
+ Used as a completion backend for the popular third-party template
+ system YASnippet (https://github.com/joaotavora/yasnippet).
+
+
+File: company.info, Node: Candidates Post-Processing, Prev: Package Backends, Up: Backends
+
+5.4 Candidates Post-Processing
+==============================
+
+A list of completion candidates, supplied by a backend, can be
+additionally manipulated (reorganized, reduced, sorted, etc) before its
+output. This is done by adding a processing function name to the user
+option ‘company-transformers’ list, for example:
+
+ (setq company-transformers '(delete-consecutive-dups
+ company-sort-by-occurrence))
+
+Company is bundled with several such transformer functions. They are
+listed below.
+
+ -- Function: company-sort-by-occurrence
+ Sorts candidates using ‘company-occurrence-weight-function’
+ algorithm.
+
+ -- User Option: company-occurrence-weight-function
+ Can be set to one of ‘company-occurrence-prefer-closest-above’
+ (default) or ‘company-occurrence-prefer-any-closest’. This user
+ option defines the behavior of the ‘company-sort-by-occurrence’
+ transformer function.
+
+ -- Function: company-sort-by-backend-importance
+ Sorts candidates as two priority groups, differentiated by the
+ keyword ‘:with’ (*note Grouped Backends::). Backends positioned in
+ the backends list before the keyword ‘:with’ are treated as more
+ important.
+
+ -- Function: company-sort-prefer-same-case-prefix
+ Gives preference to the candidates that match the prefix
+ case-insensitively.
+
+
+File: company.info, Node: Troubleshooting, Next: Index, Prev: Backends, Up: Top
+
+6 Troubleshooting
+*****************
+
+If something goes wrong, the first thing we recommend doing is to
+execute command ‘M-x company-diag’ and thoroughly study its output.
+
+This command outputs important details about the internal workings of
+Company at the moment of the ‘company-diag’ command execution, including
+a responsible backend and a list of completion candidates provided by
+it.
+
+Based on the value of the ‘Used backend’ in the output of the command
+‘M-x company-diag’, these possible actions may follow:
+
+ • If the used backend does not belong to the Company package, report
+ the issue to the corresponding third-party package maintainer(s).
+
+ • If the used backend is ‘company-capf’, then take a look at the line
+ starting with ‘Value of c-a-p-f:’. The issue could have been
+ caused by a function listed there. To identify to which package it
+ belongs, type ‘M-x find-function <RET> <function-name> <RET>’.
+
+If the aforementioned steps didn’t help to find the cause of the issue,
+then file a bug report to
+the Company Issue Tracker (https://github.com/company-mode/company-mode/issues),
+attaching the following information:
+
+ 1. Output of the ‘M-x company-diag’.
+
+ 2. The exact error message: you can find it in the ‘*Messages*’
+ buffer.
+
+ 3. The steps to reproduce the behavior. Ideally, if you can, starting
+ with a bare Emacs session: ‘emacs -Q’.
+
+ 4. The backtrace of the error, which you can get by running the
+ command: ‘M-x toggle-debug-on-error’ before reproducing the error.
+
+
+File: company.info, Node: Index, Prev: Troubleshooting, Up: Top
+
+Index
+*****
+
+* Menu:
+
+* Key Index::
+* Variable Index::
+* Function Index::
+* Concept Index::
+
+
+File: company.info, Node: Key Index, Next: Variable Index, Up: Index
+
+Key Index
+=========
+
+
+* Menu:
+
+* C-g: Usage Basics. (line 20)
+* C-g <1>: Commands. (line 30)
+* C-g <2>: Candidates Search. (line 11)
+* C-g <3>: Filter Candidates. (line 14)
+* C-h: Commands. (line 34)
+* C-M-s: Filter Candidates. (line 6)
+* C-n: Usage Basics. (line 12)
+* C-n <1>: Commands. (line 11)
+* C-o: Filter Candidates. (line 14)
+* C-p: Usage Basics. (line 12)
+* C-p <1>: Commands. (line 16)
+* C-s: Candidates Search. (line 6)
+* C-w: Commands. (line 39)
+* M-<digit>: Quick Access a Candidate.
+ (line 6)
+* RET: Usage Basics. (line 15)
+* RET <1>: Commands. (line 21)
+* TAB: Usage Basics. (line 17)
+* TAB <1>: Commands. (line 25)
+
+
+File: company.info, Node: Variable Index, Next: Function Index, Prev: Key Index, Up: Index
+
+Variable Index
+==============
+
+
+* Menu:
+
+* company-after-completion-hook: Configuration File. (line 94)
+* company-backends: Backends. (line 12)
+* company-backends <1>: Backends Usage Basics.
+ (line 6)
+* company-backends <2>: Grouped Backends. (line 6)
+* company-completion-cancelled-hook: Configuration File. (line 90)
+* company-completion-finished-hook: Configuration File. (line 92)
+* company-completion-started-hook: Configuration File. (line 88)
+* company-dabbrev-downcase: Text Completion. (line 64)
+* company-dabbrev-ignore-buffers: Text Completion. (line 32)
+* company-dabbrev-ignore-case: Text Completion. (line 47)
+* company-dabbrev-minimum-length: Text Completion. (line 13)
+* company-dabbrev-other-buffers: Text Completion. (line 23)
+* company-dot-icons-format: Tooltip Frontends. (line 179)
+* company-echo-truncate-lines: Echo Frontends. (line 33)
+* company-files-chop-trailing-slash: File Name Completion.
+ (line 19)
+* company-files-exclusions: File Name Completion.
+ (line 12)
+* company-format-margin-function: Tooltip Frontends. (line 153)
+* company-frontends: Frontends. (line 6)
+* company-global-modes: Configuration File. (line 31)
+* company-icon-margin: Tooltip Frontends. (line 164)
+* company-icon-size: Tooltip Frontends. (line 164)
+* company-idle-delay: Configuration File. (line 17)
+* company-insertion-on-trigger: Configuration File. (line 64)
+* company-insertion-triggers: Configuration File. (line 72)
+* company-ispell-dictionary: Text Completion. (line 84)
+* company-lighter-base: Configuration File. (line 59)
+* company-minimum-prefix-length: Configuration File. (line 9)
+* company-mode: Initial Setup. (line 6)
+* company-occurrence-weight-function: Candidates Post-Processing.
+ (line 21)
+* company-require-match: Configuration File. (line 51)
+* company-search-regexp-function: Candidates Search. (line 13)
+* company-selection-wrap-around: Configuration File. (line 43)
+* company-show-quick-access: Quick Access a Candidate.
+ (line 14)
+* company-text-face-extra-attributes: Tooltip Frontends. (line 192)
+* company-text-icons-add-background: Tooltip Frontends. (line 200)
+* company-text-icons-format: Tooltip Frontends. (line 171)
+* company-text-icons-mapping: Tooltip Frontends. (line 188)
+* company-tooltip-align-annotations: Tooltip Frontends. (line 52)
+* company-tooltip-flip-when-above: Tooltip Frontends. (line 99)
+* company-tooltip-idle-delay: Tooltip Frontends. (line 22)
+* company-tooltip-limit: Tooltip Frontends. (line 64)
+* company-tooltip-margin: Tooltip Frontends. (line 133)
+* company-tooltip-maximum-width: Tooltip Frontends. (line 126)
+* company-tooltip-minimum: Tooltip Frontends. (line 84)
+* company-tooltip-minimum-width: Tooltip Frontends. (line 111)
+* company-tooltip-offset-display: Tooltip Frontends. (line 74)
+* company-tooltip-width-grow-only: Tooltip Frontends. (line 121)
+* company-transformers: Candidates Post-Processing.
+ (line 6)
+
+
+File: company.info, Node: Function Index, Next: Concept Index, Prev: Variable Index, Up: Index
+
+Function Index
+==============
+
+
+* Menu:
+
+* company-abbrev: Template Expansion. (line 6)
+* company-abort: Commands. (line 30)
+* company-begin-backend: Backends Usage Basics.
+ (line 23)
+* company-capf: Code Completion. (line 6)
+* company-clang: Code Completion. (line 36)
+* company-complete: Usage Basics. (line 10)
+* company-complete-common: Commands. (line 25)
+* company-complete-selection: Commands. (line 21)
+* company-dabbrev: Text Completion. (line 6)
+* company-dabbrev-code: Code Completion. (line 25)
+* company-detect-icons-margin: Tooltip Frontends. (line 209)
+* company-diag: Backends Usage Basics.
+ (line 11)
+* company-diag <1>: Troubleshooting. (line 6)
+* company-dot-icons-margin: Tooltip Frontends. (line 178)
+* company-echo-frontend: Echo Frontends. (line 21)
+* company-echo-metadata-frontend: Echo Frontends. (line 9)
+* company-echo-strip-common-frontend: Echo Frontends. (line 27)
+* company-etags: Code Completion. (line 48)
+* company-files: File Name Completion.
+ (line 6)
+* company-ispell: Text Completion. (line 75)
+* company-keywords: Code Completion. (line 31)
+* company-mode: Initial Setup. (line 6)
+* company-other-backend: Backends Usage Basics.
+ (line 14)
+* company-preview-common-frontend: Preview Frontends. (line 21)
+* company-preview-frontend: Preview Frontends. (line 17)
+* company-preview-if-just-one-frontend: Preview Frontends. (line 10)
+* company-pseudo-tooltip-frontend: Tooltip Frontends. (line 17)
+* company-pseudo-tooltip-unless-just-one-frontend: Tooltip Frontends.
+ (line 11)
+* company-pseudo-tooltip-unless-just-one-frontend-with-delay: Tooltip Frontends.
+ (line 21)
+* company-search-flex-regexp: Candidates Search. (line 26)
+* company-search-words-in-any-order-regexp: Candidates Search.
+ (line 23)
+* company-search-words-regexp: Candidates Search. (line 20)
+* company-select-next: Commands. (line 11)
+* company-select-next-or-abort: Commands. (line 11)
+* company-select-previous: Commands. (line 16)
+* company-select-previous-or-abort: Commands. (line 16)
+* company-semantic: Code Completion. (line 41)
+* company-show-doc-buffer: Commands. (line 34)
+* company-show-location: Commands. (line 39)
+* company-sort-by-backend-importance: Candidates Post-Processing.
+ (line 28)
+* company-sort-by-occurrence: Candidates Post-Processing.
+ (line 17)
+* company-sort-prefer-same-case-prefix: Candidates Post-Processing.
+ (line 34)
+* company-tempo: Template Expansion. (line 11)
+* company-text-icons-margin: Tooltip Frontends. (line 170)
+* company-tng-frontend: Structure. (line 26)
+* company-tng-mode: Structure. (line 26)
+* company-vscode-dark-icons-margin: Tooltip Frontends. (line 162)
+* company-vscode-light-icons-margin: Tooltip Frontends. (line 163)
+* company-yasnippet: Template Expansion. (line 16)
+* global-company-mode: Initial Setup. (line 18)
+
+
+File: company.info, Node: Concept Index, Prev: Function Index, Up: Index
+
+Concept Index
+=============
+
+
+* Menu:
+
+* abbrev: Template Expansion. (line 6)
+* abort: Usage Basics. (line 20)
+* abort <1>: Commands. (line 30)
+* activate: Initial Setup. (line 8)
+* active backend: Backends Usage Basics.
+ (line 11)
+* active backend <1>: Troubleshooting. (line 15)
+* annotation: Tooltip Frontends. (line 53)
+* auto-start: Initial Setup. (line 13)
+* backend: Structure. (line 6)
+* backend <1>: Structure. (line 10)
+* backend <2>: Backends Usage Basics.
+ (line 11)
+* backend <3>: Backends Usage Basics.
+ (line 14)
+* backend <4>: Troubleshooting. (line 15)
+* backends: Backends. (line 6)
+* backends <1>: Backends Usage Basics.
+ (line 6)
+* backends <2>: Grouped Backends. (line 6)
+* backends <3>: Package Backends. (line 6)
+* basics: Usage Basics. (line 6)
+* bug: Troubleshooting. (line 6)
+* bug <1>: Troubleshooting. (line 27)
+* bundled backends: Package Backends. (line 6)
+* cancel: Usage Basics. (line 20)
+* cancel <1>: Commands. (line 30)
+* candidate: Terminology. (line 10)
+* candidate <1>: Usage Basics. (line 12)
+* candidate <2>: Usage Basics. (line 15)
+* candidate <3>: Preview Frontends. (line 6)
+* color: Tooltip Frontends. (line 219)
+* color <1>: Quick Access a Candidate.
+ (line 37)
+* common part: Usage Basics. (line 17)
+* common part <1>: Commands. (line 25)
+* common part <2>: Preview Frontends. (line 6)
+* company-echo: Echo Frontends. (line 6)
+* company-preview: Preview Frontends. (line 6)
+* company-tng: Structure. (line 26)
+* company-tooltip: Tooltip Frontends. (line 219)
+* company-tooltip-search: Candidates Search. (line 6)
+* complete: Terminology. (line 6)
+* complete <1>: Usage Basics. (line 12)
+* complete <2>: Usage Basics. (line 15)
+* complete <3>: Usage Basics. (line 17)
+* complete <4>: Commands. (line 21)
+* complete <5>: Preview Frontends. (line 6)
+* completion: Terminology. (line 6)
+* completion <1>: Usage Basics. (line 12)
+* completion <2>: Usage Basics. (line 15)
+* completion <3>: Usage Basics. (line 17)
+* configure: Customization. (line 6)
+* configure <1>: Customization Interface.
+ (line 6)
+* configure <2>: Configuration File. (line 6)
+* configure <3>: Tooltip Frontends. (line 49)
+* configure <4>: Tooltip Frontends. (line 219)
+* configure <5>: Preview Frontends. (line 25)
+* configure <6>: Echo Frontends. (line 38)
+* configure <7>: Candidates Search. (line 30)
+* configure <8>: Quick Access a Candidate.
+ (line 28)
+* configure <9>: Quick Access a Candidate.
+ (line 37)
+* custom: Customization. (line 6)
+* custom <1>: Customization Interface.
+ (line 6)
+* custom <2>: Configuration File. (line 6)
+* custom <3>: Tooltip Frontends. (line 49)
+* custom <4>: Tooltip Frontends. (line 219)
+* custom <5>: Preview Frontends. (line 25)
+* custom <6>: Echo Frontends. (line 38)
+* custom <7>: Candidates Search. (line 30)
+* custom <8>: Quick Access a Candidate.
+ (line 28)
+* custom <9>: Quick Access a Candidate.
+ (line 37)
+* definition: Commands. (line 39)
+* distribution: Installation. (line 6)
+* doc: Commands. (line 34)
+* duplicate: Candidates Post-Processing.
+ (line 6)
+* echo: Echo Frontends. (line 6)
+* enable: Initial Setup. (line 8)
+* error: Troubleshooting. (line 6)
+* error <1>: Troubleshooting. (line 27)
+* expansion: Template Expansion. (line 6)
+* extensible: Structure. (line 6)
+* face: Tooltip Frontends. (line 219)
+* face <1>: Preview Frontends. (line 6)
+* face <2>: Preview Frontends. (line 25)
+* face <3>: Echo Frontends. (line 6)
+* face <4>: Echo Frontends. (line 38)
+* face <5>: Candidates Search. (line 6)
+* face <6>: Candidates Search. (line 30)
+* face <7>: Filter Candidates. (line 6)
+* face <8>: Quick Access a Candidate.
+ (line 37)
+* filter: Filter Candidates. (line 6)
+* finish: Usage Basics. (line 20)
+* finish <1>: Commands. (line 30)
+* font: Tooltip Frontends. (line 219)
+* font <1>: Quick Access a Candidate.
+ (line 37)
+* frontend: Structure. (line 6)
+* frontend <1>: Structure. (line 10)
+* frontends: Frontends. (line 6)
+* grouped backends: Grouped Backends. (line 6)
+* icon: Tooltip Frontends. (line 145)
+* install: Installation. (line 6)
+* interface: Tooltip Frontends. (line 49)
+* interface <1>: Tooltip Frontends. (line 219)
+* interface <2>: Preview Frontends. (line 25)
+* interface <3>: Echo Frontends. (line 38)
+* interface <4>: Candidates Search. (line 30)
+* interface <5>: Quick Access a Candidate.
+ (line 37)
+* intro: Initial Setup. (line 6)
+* issue: Troubleshooting. (line 6)
+* issue tracker: Troubleshooting. (line 27)
+* kind: Tooltip Frontends. (line 145)
+* location: Commands. (line 39)
+* manual: Initial Setup. (line 8)
+* manual <1>: Usage Basics. (line 10)
+* margin: Tooltip Frontends. (line 134)
+* margin <1>: Tooltip Frontends. (line 154)
+* minor-mode: Initial Setup. (line 6)
+* module: Structure. (line 6)
+* module <1>: Structure. (line 10)
+* navigate: Usage Basics. (line 12)
+* next backend: Backends Usage Basics.
+ (line 14)
+* non-prefix matches: Terminology. (line 10)
+* package: Installation. (line 6)
+* package backends: Package Backends. (line 6)
+* pluggable: Structure. (line 6)
+* pop-up: Tooltip Frontends. (line 6)
+* prefix matches: Terminology. (line 10)
+* preview: Preview Frontends. (line 6)
+* quick start: Initial Setup. (line 6)
+* quick-access: Quick Access a Candidate.
+ (line 6)
+* quit: Usage Basics. (line 20)
+* quit <1>: Commands. (line 30)
+* search: Candidates Search. (line 6)
+* select: Usage Basics. (line 12)
+* select <1>: Commands. (line 11)
+* select <2>: Commands. (line 16)
+* snippet: Template Expansion. (line 6)
+* sort: Candidates Post-Processing.
+ (line 6)
+* stop: Usage Basics. (line 20)
+* stop <1>: Commands. (line 30)
+* TAB: Structure. (line 26)
+* Tab and Go: Structure. (line 26)
+* template: Template Expansion. (line 6)
+* third-party: Structure. (line 10)
+* third-party <1>: Troubleshooting. (line 18)
+* tooltip: Tooltip Frontends. (line 6)
+* troubleshoot: Troubleshooting. (line 6)
+* usage: Usage Basics. (line 6)
+
+
+
+Tag Table:
+Node: Top572
+Node: Overview2000
+Node: Terminology2408
+Ref: Terminology-Footnote-13395
+Node: Structure3601
+Node: Getting Started5097
+Node: Installation5375
+Node: Initial Setup5758
+Node: Usage Basics6604
+Node: Commands7367
+Ref: Commands-Footnote-19585
+Node: Customization9752
+Node: Customization Interface10224
+Node: Configuration File10757
+Node: Frontends15423
+Node: Tooltip Frontends16392
+Ref: Tooltip Frontends-Footnote-126761
+Node: Preview Frontends26998
+Ref: Preview Frontends-Footnote-128254
+Node: Echo Frontends28381
+Node: Candidates Search29914
+Node: Filter Candidates31248
+Node: Quick Access a Candidate32028
+Node: Backends33646
+Node: Backends Usage Basics34744
+Ref: Backends Usage Basics-Footnote-135959
+Node: Grouped Backends36043
+Node: Package Backends37672
+Node: Code Completion38601
+Node: Text Completion40970
+Node: File Name Completion45404
+Node: Template Expansion46952
+Node: Candidates Post-Processing47671
+Node: Troubleshooting49148
+Node: Index50821
+Node: Key Index50984
+Node: Variable Index52483
+Node: Function Index56533
+Node: Concept Index61014
+
+End Tag Table
+
+
+Local Variables:
+coding: utf-8
+End:
diff --git a/elpa/company-20220425.1145/dir b/elpa/company-20220425.1145/dir
new file mode 100644
index 0000000..a7ea2be
--- /dev/null
+++ b/elpa/company-20220425.1145/dir
@@ -0,0 +1,18 @@
+This is the file .../info/dir, which contains the
+topmost node of the Info hierarchy, called (dir)Top.
+The first time you invoke Info you start off looking at this node.
+
+File: dir, Node: Top This is the top of the INFO tree
+
+ This (the Directory node) gives a menu of major topics.
+ Typing "q" exits, "H" lists all Info commands, "d" returns here,
+ "h" gives a primer for first-timers,
+ "mEmacs<Return>" visits the Emacs manual, etc.
+
+ In Emacs, you can click mouse button 2 on a menu item or cross reference
+ to select it.
+
+* Menu:
+
+Emacs misc features
+* Company: (company). A modular text completion framework.
diff --git a/elpa/company-20220425.1145/icons/LICENSE b/elpa/company-20220425.1145/icons/LICENSE
new file mode 100644
index 0000000..52bd145
--- /dev/null
+++ b/elpa/company-20220425.1145/icons/LICENSE
@@ -0,0 +1,395 @@
+Attribution 4.0 International
+
+=======================================================================
+
+Creative Commons Corporation ("Creative Commons") is not a law firm and
+does not provide legal services or legal advice. Distribution of
+Creative Commons public licenses does not create a lawyer-client or
+other relationship. Creative Commons makes its licenses and related
+information available on an "as-is" basis. Creative Commons gives no
+warranties regarding its licenses, any material licensed under their
+terms and conditions, or any related information. Creative Commons
+disclaims all liability for damages resulting from their use to the
+fullest extent possible.
+
+Using Creative Commons Public Licenses
+
+Creative Commons public licenses provide a standard set of terms and
+conditions that creators and other rights holders may use to share
+original works of authorship and other material subject to copyright
+and certain other rights specified in the public license below. The
+following considerations are for informational purposes only, are not
+exhaustive, and do not form part of our licenses.
+
+ Considerations for licensors: Our public licenses are
+ intended for use by those authorized to give the public
+ permission to use material in ways otherwise restricted by
+ copyright and certain other rights. Our licenses are
+ irrevocable. Licensors should read and understand the terms
+ and conditions of the license they choose before applying it.
+ Licensors should also secure all rights necessary before
+ applying our licenses so that the public can reuse the
+ material as expected. Licensors should clearly mark any
+ material not subject to the license. This includes other CC-
+ licensed material, or material used under an exception or
+ limitation to copyright. More considerations for licensors:
+ wiki.creativecommons.org/Considerations_for_licensors
+
+ Considerations for the public: By using one of our public
+ licenses, a licensor grants the public permission to use the
+ licensed material under specified terms and conditions. If
+ the licensor's permission is not necessary for any reason--for
+ example, because of any applicable exception or limitation to
+ copyright--then that use is not regulated by the license. Our
+ licenses grant only permissions under copyright and certain
+ other rights that a licensor has authority to grant. Use of
+ the licensed material may still be restricted for other
+ reasons, including because others have copyright or other
+ rights in the material. A licensor may make special requests,
+ such as asking that all changes be marked or described.
+ Although not required by our licenses, you are encouraged to
+ respect those requests where reasonable. More_considerations
+ for the public:
+ wiki.creativecommons.org/Considerations_for_licensees
+
+=======================================================================
+
+Creative Commons Attribution 4.0 International Public License
+
+By exercising the Licensed Rights (defined below), You accept and agree
+to be bound by the terms and conditions of this Creative Commons
+Attribution 4.0 International Public License ("Public License"). To the
+extent this Public License may be interpreted as a contract, You are
+granted the Licensed Rights in consideration of Your acceptance of
+these terms and conditions, and the Licensor grants You such rights in
+consideration of benefits the Licensor receives from making the
+Licensed Material available under these terms and conditions.
+
+
+Section 1 -- Definitions.
+
+ a. Adapted Material means material subject to Copyright and Similar
+ Rights that is derived from or based upon the Licensed Material
+ and in which the Licensed Material is translated, altered,
+ arranged, transformed, or otherwise modified in a manner requiring
+ permission under the Copyright and Similar Rights held by the
+ Licensor. For purposes of this Public License, where the Licensed
+ Material is a musical work, performance, or sound recording,
+ Adapted Material is always produced where the Licensed Material is
+ synched in timed relation with a moving image.
+
+ b. Adapter's License means the license You apply to Your Copyright
+ and Similar Rights in Your contributions to Adapted Material in
+ accordance with the terms and conditions of this Public License.
+
+ c. Copyright and Similar Rights means copyright and/or similar rights
+ closely related to copyright including, without limitation,
+ performance, broadcast, sound recording, and Sui Generis Database
+ Rights, without regard to how the rights are labeled or
+ categorized. For purposes of this Public License, the rights
+ specified in Section 2(b)(1)-(2) are not Copyright and Similar
+ Rights.
+
+ d. Effective Technological Measures means those measures that, in the
+ absence of proper authority, may not be circumvented under laws
+ fulfilling obligations under Article 11 of the WIPO Copyright
+ Treaty adopted on December 20, 1996, and/or similar international
+ agreements.
+
+ e. Exceptions and Limitations means fair use, fair dealing, and/or
+ any other exception or limitation to Copyright and Similar Rights
+ that applies to Your use of the Licensed Material.
+
+ f. Licensed Material means the artistic or literary work, database,
+ or other material to which the Licensor applied this Public
+ License.
+
+ g. Licensed Rights means the rights granted to You subject to the
+ terms and conditions of this Public License, which are limited to
+ all Copyright and Similar Rights that apply to Your use of the
+ Licensed Material and that the Licensor has authority to license.
+
+ h. Licensor means the individual(s) or entity(ies) granting rights
+ under this Public License.
+
+ i. Share means to provide material to the public by any means or
+ process that requires permission under the Licensed Rights, such
+ as reproduction, public display, public performance, distribution,
+ dissemination, communication, or importation, and to make material
+ available to the public including in ways that members of the
+ public may access the material from a place and at a time
+ individually chosen by them.
+
+ j. Sui Generis Database Rights means rights other than copyright
+ resulting from Directive 96/9/EC of the European Parliament and of
+ the Council of 11 March 1996 on the legal protection of databases,
+ as amended and/or succeeded, as well as other essentially
+ equivalent rights anywhere in the world.
+
+ k. You means the individual or entity exercising the Licensed Rights
+ under this Public License. Your has a corresponding meaning.
+
+
+Section 2 -- Scope.
+
+ a. License grant.
+
+ 1. Subject to the terms and conditions of this Public License,
+ the Licensor hereby grants You a worldwide, royalty-free,
+ non-sublicensable, non-exclusive, irrevocable license to
+ exercise the Licensed Rights in the Licensed Material to:
+
+ a. reproduce and Share the Licensed Material, in whole or
+ in part; and
+
+ b. produce, reproduce, and Share Adapted Material.
+
+ 2. Exceptions and Limitations. For the avoidance of doubt, where
+ Exceptions and Limitations apply to Your use, this Public
+ License does not apply, and You do not need to comply with
+ its terms and conditions.
+
+ 3. Term. The term of this Public License is specified in Section
+ 6(a).
+
+ 4. Media and formats; technical modifications allowed. The
+ Licensor authorizes You to exercise the Licensed Rights in
+ all media and formats whether now known or hereafter created,
+ and to make technical modifications necessary to do so. The
+ Licensor waives and/or agrees not to assert any right or
+ authority to forbid You from making technical modifications
+ necessary to exercise the Licensed Rights, including
+ technical modifications necessary to circumvent Effective
+ Technological Measures. For purposes of this Public License,
+ simply making modifications authorized by this Section 2(a)
+ (4) never produces Adapted Material.
+
+ 5. Downstream recipients.
+
+ a. Offer from the Licensor -- Licensed Material. Every
+ recipient of the Licensed Material automatically
+ receives an offer from the Licensor to exercise the
+ Licensed Rights under the terms and conditions of this
+ Public License.
+
+ b. No downstream restrictions. You may not offer or impose
+ any additional or different terms or conditions on, or
+ apply any Effective Technological Measures to, the
+ Licensed Material if doing so restricts exercise of the
+ Licensed Rights by any recipient of the Licensed
+ Material.
+
+ 6. No endorsement. Nothing in this Public License constitutes or
+ may be construed as permission to assert or imply that You
+ are, or that Your use of the Licensed Material is, connected
+ with, or sponsored, endorsed, or granted official status by,
+ the Licensor or others designated to receive attribution as
+ provided in Section 3(a)(1)(A)(i).
+
+ b. Other rights.
+
+ 1. Moral rights, such as the right of integrity, are not
+ licensed under this Public License, nor are publicity,
+ privacy, and/or other similar personality rights; however, to
+ the extent possible, the Licensor waives and/or agrees not to
+ assert any such rights held by the Licensor to the limited
+ extent necessary to allow You to exercise the Licensed
+ Rights, but not otherwise.
+
+ 2. Patent and trademark rights are not licensed under this
+ Public License.
+
+ 3. To the extent possible, the Licensor waives any right to
+ collect royalties from You for the exercise of the Licensed
+ Rights, whether directly or through a collecting society
+ under any voluntary or waivable statutory or compulsory
+ licensing scheme. In all other cases the Licensor expressly
+ reserves any right to collect such royalties.
+
+
+Section 3 -- License Conditions.
+
+Your exercise of the Licensed Rights is expressly made subject to the
+following conditions.
+
+ a. Attribution.
+
+ 1. If You Share the Licensed Material (including in modified
+ form), You must:
+
+ a. retain the following if it is supplied by the Licensor
+ with the Licensed Material:
+
+ i. identification of the creator(s) of the Licensed
+ Material and any others designated to receive
+ attribution, in any reasonable manner requested by
+ the Licensor (including by pseudonym if
+ designated);
+
+ ii. a copyright notice;
+
+ iii. a notice that refers to this Public License;
+
+ iv. a notice that refers to the disclaimer of
+ warranties;
+
+ v. a URI or hyperlink to the Licensed Material to the
+ extent reasonably practicable;
+
+ b. indicate if You modified the Licensed Material and
+ retain an indication of any previous modifications; and
+
+ c. indicate the Licensed Material is licensed under this
+ Public License, and include the text of, or the URI or
+ hyperlink to, this Public License.
+
+ 2. You may satisfy the conditions in Section 3(a)(1) in any
+ reasonable manner based on the medium, means, and context in
+ which You Share the Licensed Material. For example, it may be
+ reasonable to satisfy the conditions by providing a URI or
+ hyperlink to a resource that includes the required
+ information.
+
+ 3. If requested by the Licensor, You must remove any of the
+ information required by Section 3(a)(1)(A) to the extent
+ reasonably practicable.
+
+ 4. If You Share Adapted Material You produce, the Adapter's
+ License You apply must not prevent recipients of the Adapted
+ Material from complying with this Public License.
+
+
+Section 4 -- Sui Generis Database Rights.
+
+Where the Licensed Rights include Sui Generis Database Rights that
+apply to Your use of the Licensed Material:
+
+ a. for the avoidance of doubt, Section 2(a)(1) grants You the right
+ to extract, reuse, reproduce, and Share all or a substantial
+ portion of the contents of the database;
+
+ b. if You include all or a substantial portion of the database
+ contents in a database in which You have Sui Generis Database
+ Rights, then the database in which You have Sui Generis Database
+ Rights (but not its individual contents) is Adapted Material; and
+
+ c. You must comply with the conditions in Section 3(a) if You Share
+ all or a substantial portion of the contents of the database.
+
+For the avoidance of doubt, this Section 4 supplements and does not
+replace Your obligations under this Public License where the Licensed
+Rights include other Copyright and Similar Rights.
+
+
+Section 5 -- Disclaimer of Warranties and Limitation of Liability.
+
+ a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE
+ EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS
+ AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF
+ ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS,
+ IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION,
+ WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS,
+ ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT
+ KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT
+ ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU.
+
+ b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE
+ TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION,
+ NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT,
+ INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES,
+ COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR
+ USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN
+ ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR
+ DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR
+ IN PART, THIS LIMITATION MAY NOT APPLY TO YOU.
+
+ c. The disclaimer of warranties and limitation of liability provided
+ above shall be interpreted in a manner that, to the extent
+ possible, most closely approximates an absolute disclaimer and
+ waiver of all liability.
+
+
+Section 6 -- Term and Termination.
+
+ a. This Public License applies for the term of the Copyright and
+ Similar Rights licensed here. However, if You fail to comply with
+ this Public License, then Your rights under this Public License
+ terminate automatically.
+
+ b. Where Your right to use the Licensed Material has terminated under
+ Section 6(a), it reinstates:
+
+ 1. automatically as of the date the violation is cured, provided
+ it is cured within 30 days of Your discovery of the
+ violation; or
+
+ 2. upon express reinstatement by the Licensor.
+
+ For the avoidance of doubt, this Section 6(b) does not affect any
+ right the Licensor may have to seek remedies for Your violations
+ of this Public License.
+
+ c. For the avoidance of doubt, the Licensor may also offer the
+ Licensed Material under separate terms or conditions or stop
+ distributing the Licensed Material at any time; however, doing so
+ will not terminate this Public License.
+
+ d. Sections 1, 5, 6, 7, and 8 survive termination of this Public
+ License.
+
+
+Section 7 -- Other Terms and Conditions.
+
+ a. The Licensor shall not be bound by any additional or different
+ terms or conditions communicated by You unless expressly agreed.
+
+ b. Any arrangements, understandings, or agreements regarding the
+ Licensed Material not stated herein are separate from and
+ independent of the terms and conditions of this Public License.
+
+
+Section 8 -- Interpretation.
+
+ a. For the avoidance of doubt, this Public License does not, and
+ shall not be interpreted to, reduce, limit, restrict, or impose
+ conditions on any use of the Licensed Material that could lawfully
+ be made without permission under this Public License.
+
+ b. To the extent possible, if any provision of this Public License is
+ deemed unenforceable, it shall be automatically reformed to the
+ minimum extent necessary to make it enforceable. If the provision
+ cannot be reformed, it shall be severed from this Public License
+ without affecting the enforceability of the remaining terms and
+ conditions.
+
+ c. No term or condition of this Public License will be waived and no
+ failure to comply consented to unless expressly agreed to by the
+ Licensor.
+
+ d. Nothing in this Public License constitutes or may be interpreted
+ as a limitation upon, or waiver of, any privileges and immunities
+ that apply to the Licensor or You, including from the legal
+ processes of any jurisdiction or authority.
+
+
+=======================================================================
+
+Creative Commons is not a party to its public
+licenses. Notwithstanding, Creative Commons may elect to apply one of
+its public licenses to material it publishes and in those instances
+will be considered the “Licensor.” The text of the Creative Commons
+public licenses is dedicated to the public domain under the CC0 Public
+Domain Dedication. Except for the limited purpose of indicating that
+material is shared under a Creative Commons public license or as
+otherwise permitted by the Creative Commons policies published at
+creativecommons.org/policies, Creative Commons does not authorize the
+use of the trademark "Creative Commons" or any other trademark or logo
+of Creative Commons without its prior written consent including,
+without limitation, in connection with any unauthorized modifications
+to any of its public licenses or any other arrangements,
+understandings, or agreements concerning use of licensed material. For
+the avoidance of doubt, this paragraph does not form part of the
+public licenses.
+
+Creative Commons may be contacted at creativecommons.org. \ No newline at end of file
diff --git a/elpa/company-20220425.1145/icons/attribution.md b/elpa/company-20220425.1145/icons/attribution.md
new file mode 100644
index 0000000..33513fc
--- /dev/null
+++ b/elpa/company-20220425.1145/icons/attribution.md
@@ -0,0 +1,5 @@
+The icons in this directory have been made by "Microsoft and any contributors",
+see the [development repository](https://github.com/microsoft/vscode-icons/).
+
+They are distributed under Creative Commons Attribution 4.0 International Public
+License, see the LICENSE file in this directory.
diff --git a/elpa/company-20220425.1145/icons/vscode-dark/folder.svg b/elpa/company-20220425.1145/icons/vscode-dark/folder.svg
new file mode 100644
index 0000000..7387525
--- /dev/null
+++ b/elpa/company-20220425.1145/icons/vscode-dark/folder.svg
@@ -0,0 +1,3 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M14.5 3H7.70996L6.85999 2.15002L6.51001 2H1.51001L1.01001 2.5V6.5V13.5L1.51001 14H14.51L15.01 13.5V9V3.5L14.5 3ZM13.99 11.49V13H1.98999V11.49V7.48999V7H6.47998L6.82996 6.84998L7.68994 5.98999H14V7.48999L13.99 11.49ZM13.99 5H7.48999L7.14001 5.15002L6.28003 6.01001H2V3.01001H6.29004L7.14001 3.85999L7.5 4.01001H14L13.99 5Z" fill="#C5C5C5"/>
+</svg> \ No newline at end of file
diff --git a/elpa/company-20220425.1145/icons/vscode-dark/references.svg b/elpa/company-20220425.1145/icons/vscode-dark/references.svg
new file mode 100644
index 0000000..9e4c78e
--- /dev/null
+++ b/elpa/company-20220425.1145/icons/vscode-dark/references.svg
@@ -0,0 +1,3 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M11.1052 4.5613L7.67505 7.98827L6.54072 6.86834L8.61098 4.78848H3.81131C3.17483 4.78848 2.56442 5.04132 2.11436 5.49138C1.6643 5.94144 1.41147 6.55184 1.41147 7.18832C1.41147 7.8248 1.6643 8.43521 2.11436 8.88527C2.56442 9.33532 3.17483 9.58816 3.81131 9.58816H4.70085V11.1881H3.8209C2.7921 11.142 1.8207 10.7009 1.10896 9.95661C0.397222 9.21231 0 8.22216 0 7.19232C0 6.16249 0.397222 5.17234 1.10896 4.42803C1.8207 3.68373 2.7921 3.24263 3.8209 3.19659H8.62058L6.54072 1.13112L7.67505 0L11.1052 3.43177V4.5613ZM16.6201 24H7.0207L6.22075 23.2V10.4121L7.0207 9.61215H16.6201L17.42 10.4121V23.2L16.6201 24ZM7.82064 22.4001H15.8201V11.212H7.82064V22.4001ZM13.4203 1.6015H23.0196L23.8196 2.40145V15.1878L23.0196 15.9877H19.0199V14.3878H22.2197V3.20139H14.2202V7.98828H12.6203V2.40145L13.4203 1.6015ZM14.2202 12.7879H9.42053V14.3878H14.2202V12.7879ZM9.42053 15.9877H14.2202V17.5876H9.42053V15.9877ZM14.2202 19.1875H9.42053V20.7874H14.2202V19.1875ZM15.8201 4.78848H20.6198V6.38838H15.8201V4.78848ZM20.6198 11.188H19.0199V12.7879H20.6198V11.188ZM17.2824 8.01228V7.98828H20.6198V9.58817H18.8583L17.2824 8.01228Z" fill="#C5C5C5"/>
+</svg>
diff --git a/elpa/company-20220425.1145/icons/vscode-dark/symbol-array.svg b/elpa/company-20220425.1145/icons/vscode-dark/symbol-array.svg
new file mode 100644
index 0000000..e92131d
--- /dev/null
+++ b/elpa/company-20220425.1145/icons/vscode-dark/symbol-array.svg
@@ -0,0 +1,3 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M1.5 2L1 2.5V13.5L1.5 14H4V13H2V3H4V2H1.5ZM14.5 14L15 13.5L15 2.5L14.5 2H12V3L14 3L14 13H12V14H14.5Z" fill="#C5C5C5"/>
+</svg>
diff --git a/elpa/company-20220425.1145/icons/vscode-dark/symbol-boolean.svg b/elpa/company-20220425.1145/icons/vscode-dark/symbol-boolean.svg
new file mode 100644
index 0000000..e009568
--- /dev/null
+++ b/elpa/company-20220425.1145/icons/vscode-dark/symbol-boolean.svg
@@ -0,0 +1,3 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M1 3.5L1.5 3H14.5L15 3.5L15 12.5L14.5 13H1.5L1 12.5V3.5ZM14 4H8L8 7.49297L7.89793 7.49285L7.5 7.49225V7.49237L3.92614 7.48807L6.01638 5.39784L5.30927 4.69073L2.35356 7.64645L2.35356 8.35355L5.30927 11.3093L6.01638 10.6022L3.90228 8.48807L7.8976 8.49285L8 8.493V7.50702L11.9073 7.51222L9.79289 5.39784L10.5 4.69073L13.4557 7.64645V8.35355L10.5 11.3093L9.79289 10.6022L11.8828 8.51222L8 8.50702V12H14V4Z" fill="#C5C5C5"/>
+</svg>
diff --git a/elpa/company-20220425.1145/icons/vscode-dark/symbol-class.svg b/elpa/company-20220425.1145/icons/vscode-dark/symbol-class.svg
new file mode 100644
index 0000000..b35a6bb
--- /dev/null
+++ b/elpa/company-20220425.1145/icons/vscode-dark/symbol-class.svg
@@ -0,0 +1,3 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M11.34 9.70998H12.05L14.72 7.04005V6.32997L13.38 5.00001H12.68L10.86 6.81007H5.86V5.56007L7.71999 3.70997V3L5.71998 1H5.00001L1 5.00001V5.70997L3 7.70998H3.71003L4.84998 6.56007V12.35L5.34998 12.85H10V13.37L11.33 14.71H12.04L14.7101 12.0401V11.33L13.37 10H12.67L10.81 11.85H5.81001V7.84999H10V8.32997L11.34 9.70998ZM13.0301 6.06007L13.66 6.68995L11.66 8.68996L11.0301 8.06007L13.0301 6.06007ZM13.0301 11.0601L13.66 11.69L11.66 13.69L11.0301 13.0601L13.0301 11.0601ZM3.34998 6.65004L2.06 5.34998L5.34998 2.06006L6.65004 3.34998L3.34998 6.65004Z" fill="#EE9D28"/>
+</svg>
diff --git a/elpa/company-20220425.1145/icons/vscode-dark/symbol-color.svg b/elpa/company-20220425.1145/icons/vscode-dark/symbol-color.svg
new file mode 100644
index 0000000..91469f9
--- /dev/null
+++ b/elpa/company-20220425.1145/icons/vscode-dark/symbol-color.svg
@@ -0,0 +1,3 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M8 1.00305C6.14348 1.00305 4.36299 1.74059 3.05023 3.05334C1.73748 4.3661 1 6.14654 1 8.00305V8.43311C1.09 9.94311 2.91 10.2231 4 9.13306C4.35648 8.81625 4.82054 8.64759 5.29724 8.66162C5.77395 8.67565 6.22729 8.87127 6.56451 9.2085C6.90174 9.54572 7.09736 9.99912 7.11139 10.4758C7.12542 10.9525 6.95682 11.4166 6.64001 11.7731C5.54001 12.9331 5.85 14.843 7.44 14.973H8.03998C9.89649 14.973 11.677 14.2356 12.9897 12.9229C14.3025 11.6101 15.04 9.82954 15.04 7.97302C15.04 6.11651 14.3025 4.33607 12.9897 3.02332C11.677 1.71056 9.89649 0.973022 8.03998 0.973022L8 1.00305ZM8 14.0031H7.47998C7.34751 13.9989 7.22047 13.9495 7.12 13.863C7.04052 13.7807 6.98815 13.6761 6.96997 13.5631C6.9381 13.3682 6.95328 13.1684 7.01416 12.9806C7.07504 12.7927 7.17989 12.6222 7.32001 12.483C7.84048 11.9474 8.13165 11.2299 8.13165 10.483C8.13165 9.73615 7.84048 9.0187 7.32001 8.48303C7.05348 8.21635 6.73699 8.00481 6.38867 7.86047C6.04036 7.71614 5.66702 7.64185 5.28998 7.64185C4.91294 7.64185 4.5396 7.71614 4.19128 7.86047C3.84297 8.00481 3.52654 8.21635 3.26001 8.48303C3.15068 8.61081 3.01089 8.709 2.85358 8.76843C2.69626 8.82786 2.52649 8.84657 2.35999 8.823C2.27593 8.80694 2.19903 8.76498 2.14001 8.703C2.07131 8.6224 2.03556 8.5189 2.03998 8.41309V8.04309C2.03998 6.8564 2.39192 5.69629 3.05121 4.70959C3.7105 3.7229 4.64754 2.95388 5.7439 2.49976C6.84025 2.04563 8.04669 1.92681 9.21057 2.15833C10.3745 2.38984 11.4435 2.9613 12.2827 3.80042C13.1218 4.63953 13.6932 5.70867 13.9247 6.87256C14.1562 8.03644 14.0374 9.24275 13.5833 10.3391C13.1291 11.4355 12.3601 12.3726 11.3734 13.0319C10.3867 13.6911 9.22667 14.0431 8.03998 14.0431L8 14.0031ZM9 3.99683C9 4.54911 8.55228 4.99683 8 4.99683C7.44771 4.99683 7 4.54911 7 3.99683C7 3.44454 7.44771 2.99683 8 2.99683C8.55228 2.99683 9 3.44454 9 3.99683ZM12 11.0037C12 11.5559 11.5523 12.0037 11 12.0037C10.4477 12.0037 10 11.5559 10 11.0037C10 10.4514 10.4477 10.0037 11 10.0037C11.5523 10.0037 12 10.4514 12 11.0037ZM5 6.00415C5.55229 6.00415 6 5.55644 6 5.00415C6 4.45187 5.55229 4.00415 5 4.00415C4.44772 4.00415 4 4.45187 4 5.00415C4 5.55644 4.44772 6.00415 5 6.00415ZM12 5.00415C12 5.55644 11.5523 6.00415 11 6.00415C10.4477 6.00415 10 5.55644 10 5.00415C10 4.45187 10.4477 4.00415 11 4.00415C11.5523 4.00415 12 4.45187 12 5.00415ZM13.0001 7.99939C13.0001 8.55167 12.5524 8.99939 12.0001 8.99939C11.4478 8.99939 11.0001 8.55167 11.0001 7.99939C11.0001 7.4471 11.4478 6.99939 12.0001 6.99939C12.5524 6.99939 13.0001 7.4471 13.0001 7.99939Z" fill="#C5C5C5"/>
+</svg>
diff --git a/elpa/company-20220425.1145/icons/vscode-dark/symbol-constant.svg b/elpa/company-20220425.1145/icons/vscode-dark/symbol-constant.svg
new file mode 100644
index 0000000..0e90eca
--- /dev/null
+++ b/elpa/company-20220425.1145/icons/vscode-dark/symbol-constant.svg
@@ -0,0 +1,4 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M4 6H12V7H4V6ZM12 9H4V10H12V9Z" fill="#C5C5C5"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M1 4L2 3H14L15 4V12L14 13H2L1 12V4ZM2 4V12H14V4H2Z" fill="#C5C5C5"/>
+</svg>
diff --git a/elpa/company-20220425.1145/icons/vscode-dark/symbol-enumerator-member.svg b/elpa/company-20220425.1145/icons/vscode-dark/symbol-enumerator-member.svg
new file mode 100644
index 0000000..53735c1
--- /dev/null
+++ b/elpa/company-20220425.1145/icons/vscode-dark/symbol-enumerator-member.svg
@@ -0,0 +1,3 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M7 3L8 2H14L15 3V8L14 9H10V8H14V3H8V6H7V3ZM9 9V8L8 7H7H2L1 8V13L2 14H8L9 13V9ZM8 8V9V13H2V8H7H8ZM9.41421 7L9 6.58579V6H13V7H9.41421ZM9 4H13V5H9V4ZM7 10H3V11H7V10Z" fill="#75BEFF"/>
+</svg>
diff --git a/elpa/company-20220425.1145/icons/vscode-dark/symbol-enumerator.svg b/elpa/company-20220425.1145/icons/vscode-dark/symbol-enumerator.svg
new file mode 100644
index 0000000..2197f66
--- /dev/null
+++ b/elpa/company-20220425.1145/icons/vscode-dark/symbol-enumerator.svg
@@ -0,0 +1,3 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M14 2H8L7 3V6H8V3H14V8H10V9H14L15 8V3L14 2ZM9 6H13V7H9.41L9 6.59V6ZM7 7H2L1 8V13L2 14H8L9 13V8L8 7H7ZM8 13H2V8H8V9V13ZM3 9H7V10H3V9ZM3 11H7V12H3V11ZM9 4H13V5H9V4Z" fill="#EE9D28"/>
+</svg>
diff --git a/elpa/company-20220425.1145/icons/vscode-dark/symbol-event.svg b/elpa/company-20220425.1145/icons/vscode-dark/symbol-event.svg
new file mode 100644
index 0000000..051bef3
--- /dev/null
+++ b/elpa/company-20220425.1145/icons/vscode-dark/symbol-event.svg
@@ -0,0 +1,3 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M7.41354 1.55996L8.31152 1H11.6056L12.424 2.57465L10.2356 6H12.0174L12.7363 7.69512L5.61943 15L4.01675 13.837L6.11943 10H4.89798L4 8.55996L7.41354 1.55996ZM7.78033 9L4.90054 14.3049L12.0174 7H8.31152L11.6056 2H8.31152L4.89798 9H7.78033Z" fill="#EE9D28"/>
+</svg>
diff --git a/elpa/company-20220425.1145/icons/vscode-dark/symbol-field.svg b/elpa/company-20220425.1145/icons/vscode-dark/symbol-field.svg
new file mode 100644
index 0000000..f7b9e28
--- /dev/null
+++ b/elpa/company-20220425.1145/icons/vscode-dark/symbol-field.svg
@@ -0,0 +1,3 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M14.45 4.5L9.44995 2H8.55005L1.55005 5.5L1 6.39001V10.89L1.55005 11.79L6.55005 14.29H7.44995L14.45 10.79L15 9.89001V5.39001L14.45 4.5ZM6.44995 13.14L1.94995 10.89V7.17004L6.44995 9.17004V13.14ZM6.94995 8.33997L2.29004 6.22998L8.94995 2.89001L13.62 5.22998L6.94995 8.33997ZM13.95 9.89001L7.44995 13.14V9.20996L13.95 6.20996V9.89001Z" fill="#75BEFF"/>
+</svg>
diff --git a/elpa/company-20220425.1145/icons/vscode-dark/symbol-file.svg b/elpa/company-20220425.1145/icons/vscode-dark/symbol-file.svg
new file mode 100644
index 0000000..c9b6a03
--- /dev/null
+++ b/elpa/company-20220425.1145/icons/vscode-dark/symbol-file.svg
@@ -0,0 +1,3 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M13.85 4.44L10.57 1.14L10.22 1H2.5L2 1.5V14.5L2.5 15H13.5L14 14.5V4.8L13.85 4.44ZM13 5H10V2L13 5ZM3 14V2H9V5.5L9.5 6H13V14H3Z" fill="#C5C5C5"/>
+</svg> \ No newline at end of file
diff --git a/elpa/company-20220425.1145/icons/vscode-dark/symbol-interface.svg b/elpa/company-20220425.1145/icons/vscode-dark/symbol-interface.svg
new file mode 100644
index 0000000..b8ff0ab
--- /dev/null
+++ b/elpa/company-20220425.1145/icons/vscode-dark/symbol-interface.svg
@@ -0,0 +1,3 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M11.4965 4C10.655 3.9989 9.84136 4.30189 9.20557 4.85315C8.56977 5.40442 8.15465 6.16684 8.0365 7H4.9364C4.8147 6.52867 4.52533 6.11794 4.12244 5.84473C3.71955 5.57152 3.23083 5.45466 2.74792 5.51599C2.26502 5.57733 1.82106 5.81261 1.49927 6.17786C1.17747 6.54311 1 7.01322 1 7.5C1 7.98679 1.17747 8.45689 1.49927 8.82215C1.82106 9.1874 2.26502 9.42267 2.74792 9.48401C3.23083 9.54535 3.71955 9.42848 4.12244 9.15528C4.52533 8.88207 4.8147 8.47133 4.9364 8H8.0365C8.13236 8.66418 8.41717 9.28683 8.85693 9.7937C9.2967 10.3006 9.87284 10.6703 10.5168 10.8589C11.1609 11.0475 11.8455 11.047 12.4893 10.8574C13.133 10.6679 13.7087 10.2973 14.1477 9.7898C14.5867 9.28227 14.8706 8.65919 14.9655 7.99488C15.0603 7.33056 14.9621 6.65298 14.6827 6.04285C14.4034 5.43272 13.9545 4.91578 13.3895 4.55359C12.8246 4.19141 12.1675 3.99922 11.4965 4V4ZM11.4965 10C11.002 10 10.5187 9.85332 10.1075 9.57862C9.69642 9.30391 9.37599 8.91348 9.18677 8.45667C8.99755 7.99985 8.94809 7.49728 9.04456 7.01233C9.14102 6.52738 9.37901 6.08181 9.72864 5.73218C10.0783 5.38255 10.5238 5.14456 11.0088 5.0481C11.4937 4.95164 11.9963 5.00109 12.4531 5.19031C12.9099 5.37953 13.3004 5.69996 13.5751 6.11109C13.8498 6.52221 13.9965 7.00555 13.9965 7.5C13.9965 8.16304 13.7331 8.79898 13.2643 9.26783C12.7954 9.73667 12.1595 10 11.4965 10V10Z" fill="#75BEFF"/>
+</svg>
diff --git a/elpa/company-20220425.1145/icons/vscode-dark/symbol-key.svg b/elpa/company-20220425.1145/icons/vscode-dark/symbol-key.svg
new file mode 100644
index 0000000..80fb9d6
--- /dev/null
+++ b/elpa/company-20220425.1145/icons/vscode-dark/symbol-key.svg
@@ -0,0 +1,3 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M7.22289 10.933C7.54863 11.1254 7.92163 11.2231 8.29989 11.215C8.63777 11.2218 8.97254 11.1492 9.27721 11.003C9.58188 10.8567 9.84792 10.6409 10.0539 10.373C10.5091 9.76519 10.7402 9.01867 10.7079 8.25998C10.7412 7.58622 10.5374 6.9221 10.1319 6.38298C9.93575 6.14161 9.68577 5.94957 9.402 5.82228C9.11824 5.69498 8.80858 5.63597 8.49789 5.64997C8.07522 5.64699 7.65994 5.76085 7.29789 5.97898C7.18304 6.04807 7.0749 6.12775 6.97489 6.21698V3.47498H5.98389V11.1H6.97889V10.756C7.05516 10.8217 7.13677 10.8809 7.22289 10.933ZM7.84981 6.70006C8.03598 6.62105 8.23807 6.58677 8.43989 6.59998C8.61257 6.59452 8.78404 6.63054 8.93994 6.70501C9.09583 6.77948 9.23161 6.89023 9.33589 7.02798C9.59253 7.39053 9.7184 7.82951 9.69289 8.27297C9.71972 8.79748 9.57969 9.31701 9.29289 9.75698C9.18822 9.91527 9.04546 10.0447 8.87773 10.1335C8.70999 10.2223 8.52264 10.2675 8.33289 10.265C8.14934 10.2732 7.9663 10.24 7.79734 10.1678C7.62838 10.0956 7.47784 9.98628 7.35689 9.84797C7.10152 9.55957 6.96501 9.18506 6.97489 8.79998V8.19998C6.96299 7.78332 7.10263 7.3765 7.36789 7.05498C7.49858 6.90064 7.66364 6.77908 7.84981 6.70006ZM3.28902 5.67499C2.97011 5.67933 2.65388 5.734 2.35202 5.83699C2.06417 5.92293 1.79347 6.05828 1.55202 6.23699L1.45202 6.31399V7.51399L1.87502 7.15499C2.24579 6.80478 2.73133 6.60146 3.24102 6.58299C3.36593 6.57164 3.4917 6.59147 3.60706 6.64068C3.72243 6.6899 3.82377 6.76697 3.90202 6.86499C4.0522 7.0971 4.13239 7.36754 4.13302 7.64399L2.90002 7.82499C2.39435 7.87781 1.91525 8.07772 1.52202 8.39999C1.36697 8.55181 1.24339 8.73271 1.15835 8.93235C1.07331 9.13199 1.02848 9.34644 1.02644 9.56343C1.0244 9.78042 1.06517 9.99568 1.14644 10.1969C1.2277 10.3981 1.34786 10.5813 1.50002 10.736C1.6687 10.8904 1.86622 11.01 2.08125 11.0879C2.29627 11.1659 2.52456 11.2005 2.75302 11.19C3.147 11.1931 3.53278 11.0774 3.86002 10.858C3.96153 10.7897 4.0572 10.7131 4.14602 10.629V11.073H5.08702V7.71499C5.12137 7.17422 4.9543 6.63988 4.61802 6.21499C4.44979 6.03285 4.24348 5.89003 4.01378 5.7967C3.78407 5.70336 3.53661 5.66181 3.28902 5.67499ZM4.14602 8.71599C4.16564 9.13435 4.02592 9.54459 3.75502 9.864C3.63689 10.0005 3.48998 10.1092 3.32486 10.1821C3.15973 10.2551 2.98049 10.2906 2.80002 10.286C2.69049 10.2945 2.58035 10.2812 2.47599 10.2469C2.37163 10.2125 2.27511 10.1579 2.19202 10.086C2.06079 9.93455 1.98856 9.74088 1.98856 9.54049C1.98856 9.34011 2.06079 9.14644 2.19202 8.99499C2.47322 8.82131 2.79233 8.71837 3.12202 8.69499L4.14202 8.54699L4.14602 8.71599ZM12.4588 11.0325C12.766 11.1638 13.0983 11.2261 13.4322 11.215C13.927 11.227 14.4153 11.1006 14.8422 10.85L14.9652 10.775L14.9782 10.768V9.61504L14.5322 9.93504C14.216 10.1592 13.8356 10.2747 13.4482 10.264C13.2497 10.2719 13.052 10.2342 12.8703 10.1538C12.6886 10.0733 12.5278 9.95232 12.4002 9.80004C12.1144 9.42453 11.9725 8.95911 12.0002 8.48804C11.9737 7.98732 12.1352 7.49475 12.4532 7.10704C12.5934 6.94105 12.7695 6.80914 12.9682 6.7213C13.167 6.63346 13.3831 6.592 13.6002 6.60004C13.9439 6.59844 14.2808 6.69525 14.5712 6.87904L15.0002 7.14404V5.97004L14.8312 5.89704C14.4626 5.73432 14.0641 5.6502 13.6612 5.65004C13.2999 5.63991 12.9406 5.70762 12.6078 5.84859C12.2749 5.98956 11.9763 6.20048 11.7322 6.46704C11.2261 7.02683 10.9581 7.76186 10.9852 8.51604C10.9567 9.22346 11.1955 9.91569 11.6542 10.455C11.8769 10.704 12.1516 10.9012 12.4588 11.0325Z" fill="#C5C5C5"/>
+</svg>
diff --git a/elpa/company-20220425.1145/icons/vscode-dark/symbol-keyword.svg b/elpa/company-20220425.1145/icons/vscode-dark/symbol-keyword.svg
new file mode 100644
index 0000000..70ba6ea
--- /dev/null
+++ b/elpa/company-20220425.1145/icons/vscode-dark/symbol-keyword.svg
@@ -0,0 +1,3 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M15 4H10V3H15V4ZM14 7H12V8H14V7ZM10 7H1V8H10V7ZM12 13H1V14H12V13ZM7 10H1V11H7V10ZM15 10H10V11H15V10ZM8 2V5H1V2H8ZM7 3H2V4H7V3Z" fill="#C5C5C5"/>
+</svg>
diff --git a/elpa/company-20220425.1145/icons/vscode-dark/symbol-method.svg b/elpa/company-20220425.1145/icons/vscode-dark/symbol-method.svg
new file mode 100644
index 0000000..cccf5a0
--- /dev/null
+++ b/elpa/company-20220425.1145/icons/vscode-dark/symbol-method.svg
@@ -0,0 +1,3 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M13.51 4L8.51001 1H7.51001L2.51001 4L2.02002 4.85999V10.86L2.51001 11.71L7.51001 14.71H8.51001L13.51 11.71L14 10.86V4.85999L13.51 4ZM7.51001 13.5601L3.01001 10.86V5.69995L7.51001 8.15002V13.5601ZM3.27002 4.69995L8.01001 1.85999L12.75 4.69995L8.01001 7.29004L3.27002 4.69995ZM13.01 10.86L8.51001 13.5601V8.15002L13.01 5.69995V10.86Z" fill="#B180D7"/>
+</svg>
diff --git a/elpa/company-20220425.1145/icons/vscode-dark/symbol-misc.svg b/elpa/company-20220425.1145/icons/vscode-dark/symbol-misc.svg
new file mode 100644
index 0000000..8880923
--- /dev/null
+++ b/elpa/company-20220425.1145/icons/vscode-dark/symbol-misc.svg
@@ -0,0 +1,3 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M4 2H12V6C12.3415 6.03511 12.6774 6.11234 13 6.22998V1H3V9.47998L4 7.72998V2ZM6.14001 10L5 8L4 9.75L3.29004 11L1 15H9L6.70996 11L6.14001 10ZM2.71997 14L4.43994 11L5 10L5.56006 11L7.28003 14H2.71997ZM9.55552 7.58984C10.1311 7.20526 10.8077 7 11.5 7C12.4282 7 13.3185 7.36877 13.9748 8.02515C14.6312 8.68152 15 9.57174 15 10.5C15 11.1922 14.7947 11.8689 14.4101 12.4445C14.0256 13.02 13.4789 13.4686 12.8393 13.7335C12.1998 13.9984 11.4961 14.0678 10.8171 13.9327C10.1382 13.7977 9.51461 13.4643 9.02513 12.9749C8.53564 12.4854 8.20229 11.8618 8.06724 11.1829C7.93219 10.5039 8.00155 9.80019 8.26646 9.16064C8.53137 8.5211 8.97995 7.97443 9.55552 7.58984ZM10.1111 12.5786C10.5222 12.8533 11.0055 13 11.5 13C12.163 13 12.799 12.7367 13.2678 12.2678C13.7366 11.799 14 11.163 14 10.5C14 10.0055 13.8533 9.52221 13.5786 9.11108C13.3039 8.69996 12.9135 8.37953 12.4566 8.19031C11.9998 8.00109 11.4973 7.95163 11.0123 8.0481C10.5274 8.14456 10.0818 8.38255 9.73216 8.73218C9.38253 9.08181 9.14454 9.52738 9.04808 10.0123C8.95161 10.4973 9.00107 10.9998 9.19029 11.4567C9.37951 11.9135 9.69994 12.3039 10.1111 12.5786Z" fill="#C5C5C5"/>
+</svg>
diff --git a/elpa/company-20220425.1145/icons/vscode-dark/symbol-namespace.svg b/elpa/company-20220425.1145/icons/vscode-dark/symbol-namespace.svg
new file mode 100644
index 0000000..9a725bb
--- /dev/null
+++ b/elpa/company-20220425.1145/icons/vscode-dark/symbol-namespace.svg
@@ -0,0 +1,3 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M6 2.98361V2.97184V2H5.91083C5.59743 2 5.29407 2.06161 5.00128 2.18473C4.70818 2.30798 4.44942 2.48474 4.22578 2.71498C4.00311 2.94422 3.83792 3.19498 3.73282 3.46766L3.73233 3.46898C3.63382 3.7352 3.56814 4.01201 3.53533 4.29917L3.53519 4.30053C3.50678 4.5805 3.4987 4.86844 3.51084 5.16428C3.52272 5.45379 3.52866 5.74329 3.52866 6.03279C3.52866 6.23556 3.48974 6.42594 3.412 6.60507L3.4116 6.60601C3.33687 6.78296 3.23423 6.93866 3.10317 7.07359C2.97644 7.20405 2.82466 7.31055 2.64672 7.3925C2.4706 7.46954 2.28497 7.5082 2.08917 7.5082H2V7.6V8.4V8.4918H2.08917C2.28465 8.4918 2.47001 8.53238 2.64601 8.61334L2.64742 8.61396C2.82457 8.69157 2.97577 8.79762 3.10221 8.93161L3.10412 8.93352C3.23428 9.0637 3.33659 9.21871 3.41129 9.39942L3.41201 9.40108C3.48986 9.58047 3.52866 9.76883 3.52866 9.96721C3.52866 10.2567 3.52272 10.5462 3.51084 10.8357C3.4987 11.1316 3.50677 11.4215 3.53516 11.7055L3.53535 11.7072C3.56819 11.9903 3.63387 12.265 3.73232 12.531L3.73283 12.5323C3.83793 12.805 4.00311 13.0558 4.22578 13.285C4.44942 13.5153 4.70818 13.692 5.00128 13.8153C5.29407 13.9384 5.59743 14 5.91083 14H6V13.2V13.0164H5.91083C5.71095 13.0164 5.52346 12.9777 5.34763 12.9008C5.17396 12.8191 5.02194 12.7126 4.89086 12.5818C4.76386 12.4469 4.66104 12.2911 4.58223 12.1137C4.50838 11.9346 4.47134 11.744 4.47134 11.541C4.47134 11.3127 4.4753 11.0885 4.48321 10.8686C4.49125 10.6411 4.49127 10.4195 4.48324 10.2039C4.47914 9.98246 4.46084 9.76883 4.42823 9.56312C4.39513 9.35024 4.33921 9.14757 4.26039 8.95536C4.18091 8.76157 4.07258 8.57746 3.93616 8.40298C3.82345 8.25881 3.68538 8.12462 3.52283 8C3.68538 7.87538 3.82345 7.74119 3.93616 7.59702C4.07258 7.42254 4.18091 7.23843 4.26039 7.04464C4.33913 6.85263 4.39513 6.65175 4.42826 6.44285C4.46082 6.2333 4.47914 6.01973 4.48324 5.80219C4.49127 5.58262 4.49125 5.36105 4.48321 5.13749C4.4753 4.9134 4.47134 4.68725 4.47134 4.45902C4.47134 4.26019 4.50833 4.07152 4.58238 3.89205C4.66135 3.71034 4.76421 3.55475 4.89086 3.42437C5.02193 3.28942 5.17461 3.18275 5.34802 3.10513C5.5238 3.02427 5.71113 2.98361 5.91083 2.98361H6ZM10 13.0164V13.0282V14H10.0892C10.4026 14 10.7059 13.9384 10.9987 13.8153C11.2918 13.692 11.5506 13.5153 11.7742 13.285C11.9969 13.0558 12.1621 12.805 12.2672 12.5323L12.2677 12.531C12.3662 12.2648 12.4319 11.988 12.4647 11.7008L12.4648 11.6995C12.4932 11.4195 12.5013 11.1316 12.4892 10.8357C12.4773 10.5462 12.4713 10.2567 12.4713 9.96721C12.4713 9.76444 12.5103 9.57406 12.588 9.39493L12.5884 9.39399C12.6631 9.21704 12.7658 9.06134 12.8968 8.92642C13.0236 8.79595 13.1753 8.68945 13.3533 8.6075C13.5294 8.53046 13.715 8.4918 13.9108 8.4918H14V8.4V7.6V7.5082H13.9108C13.7153 7.5082 13.53 7.46762 13.354 7.38666L13.3526 7.38604C13.1754 7.30844 13.0242 7.20238 12.8978 7.06839L12.8959 7.06648C12.7657 6.9363 12.6634 6.78129 12.5887 6.60058L12.588 6.59892C12.5101 6.41953 12.4713 6.23117 12.4713 6.03279C12.4713 5.74329 12.4773 5.45379 12.4892 5.16428C12.5013 4.86842 12.4932 4.57848 12.4648 4.29454L12.4646 4.29285C12.4318 4.00971 12.3661 3.73502 12.2677 3.46897L12.2672 3.46766C12.1621 3.19499 11.9969 2.94422 11.7742 2.71498C11.5506 2.48474 11.2918 2.30798 10.9987 2.18473C10.7059 2.06161 10.4026 2 10.0892 2H10V2.8V2.98361H10.0892C10.2891 2.98361 10.4765 3.0223 10.6524 3.09917C10.826 3.18092 10.9781 3.28736 11.1091 3.41823C11.2361 3.55305 11.339 3.70889 11.4178 3.88628C11.4916 4.0654 11.5287 4.25596 11.5287 4.45902C11.5287 4.68727 11.5247 4.91145 11.5168 5.13142C11.5088 5.35894 11.5087 5.58049 11.5168 5.79605C11.5209 6.01754 11.5392 6.23117 11.5718 6.43688C11.6049 6.64976 11.6608 6.85243 11.7396 7.04464C11.8191 7.23843 11.9274 7.42254 12.0638 7.59702C12.1765 7.74119 12.3146 7.87538 12.4772 8C12.3146 8.12462 12.1765 8.25881 12.0638 8.40298C11.9274 8.57746 11.8191 8.76157 11.7396 8.95536C11.6609 9.14737 11.6049 9.34825 11.5717 9.55715C11.5392 9.7667 11.5209 9.98027 11.5168 10.1978C11.5087 10.4174 11.5087 10.6389 11.5168 10.8625C11.5247 11.0866 11.5287 11.3128 11.5287 11.541C11.5287 11.7398 11.4917 11.9285 11.4176 12.1079C11.3386 12.2897 11.2358 12.4452 11.1091 12.5756C10.9781 12.7106 10.8254 12.8173 10.652 12.8949C10.4762 12.9757 10.2889 13.0164 10.0892 13.0164H10Z" fill="#C5C5C5"/>
+</svg>
diff --git a/elpa/company-20220425.1145/icons/vscode-dark/symbol-numeric.svg b/elpa/company-20220425.1145/icons/vscode-dark/symbol-numeric.svg
new file mode 100644
index 0000000..a1573df
--- /dev/null
+++ b/elpa/company-20220425.1145/icons/vscode-dark/symbol-numeric.svg
@@ -0,0 +1,3 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M11 1V5H15V6H11L11 10H15V11H11V15H10V11H6V15H5L5 11H1V10H5L5 6H1V5H5L5 1H6V5H10V1H11ZM6 6L6 10H10L10 6H6Z" fill="#C5C5C5"/>
+</svg>
diff --git a/elpa/company-20220425.1145/icons/vscode-dark/symbol-operator.svg b/elpa/company-20220425.1145/icons/vscode-dark/symbol-operator.svg
new file mode 100644
index 0000000..957f5f4
--- /dev/null
+++ b/elpa/company-20220425.1145/icons/vscode-dark/symbol-operator.svg
@@ -0,0 +1,3 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M2.87289 1.10023C3.20768 1.23579 3.47545 1.498 3.61802 1.82988C3.69032 1.99959 3.72675 2.18242 3.72502 2.36688C3.72617 2.54999 3.68975 2.7314 3.61802 2.89988C3.51299 3.14567 3.33782 3.35503 3.11442 3.50177C2.89102 3.64851 2.6293 3.72612 2.36202 3.72488C2.17924 3.72592 1.99818 3.68951 1.83002 3.61788C1.58298 3.51406 1.37227 3.33932 1.22453 3.11575C1.0768 2.89219 0.998666 2.62984 1.00002 2.36188C0.99913 2.17921 1.03519 1.99825 1.10602 1.82988C1.24337 1.50314 1.50328 1.24323 1.83002 1.10588C2.16332 0.966692 2.53809 0.964661 2.87289 1.10023ZM2.57502 2.86488C2.7054 2.80913 2.80927 2.70526 2.86502 2.57488C2.8929 2.50838 2.90718 2.43698 2.90702 2.36488C2.90813 2.2654 2.88215 2.1675 2.83185 2.08167C2.78156 1.99584 2.70884 1.92531 2.62151 1.87767C2.53418 1.83002 2.43553 1.80705 2.33614 1.81121C2.23674 1.81537 2.14035 1.8465 2.05731 1.90128C1.97426 1.95606 1.9077 2.03241 1.86475 2.12215C1.8218 2.21188 1.80409 2.31161 1.81352 2.41065C1.82294 2.50968 1.85915 2.60428 1.91825 2.6843C1.97736 2.76433 2.05713 2.82675 2.14902 2.86488C2.28549 2.92089 2.43854 2.92089 2.57502 2.86488ZM6.42995 1.1095L1.10967 6.42977L1.79557 7.11567L7.11584 1.7954L6.42995 1.1095ZM11.5 8.99999H12.5V11.5H15V12.5H12.5V15H11.5V12.5H9V11.5H11.5V8.99999ZM5.76777 9.52509L6.47487 10.2322L4.70711 12L6.47487 13.7677L5.76777 14.4748L4 12.7071L2.23223 14.4748L1.52513 13.7677L3.29289 12L1.52513 10.2322L2.23223 9.52509L4 11.2929L5.76777 9.52509ZM7.11802 5.32988C7.01442 5.08268 6.83973 4.87183 6.61612 4.72406C6.3925 4.57629 6.13004 4.49826 5.86202 4.49988C5.67935 4.49899 5.49839 4.53505 5.33002 4.60588C5.00328 4.74323 4.74337 5.00314 4.60602 5.32988C4.53588 5.49478 4.49897 5.67191 4.49741 5.8511C4.49586 6.0303 4.52967 6.20804 4.59693 6.37414C4.66419 6.54024 4.76356 6.69143 4.88936 6.81906C5.01516 6.94669 5.1649 7.04823 5.33002 7.11788C5.49867 7.18848 5.67968 7.22484 5.86252 7.22484C6.04535 7.22484 6.22636 7.18848 6.39502 7.11788C6.64201 7.01388 6.8527 6.83913 7.00058 6.61563C7.14845 6.39213 7.22689 6.12987 7.22602 5.86188C7.22655 5.67905 7.1898 5.49803 7.11802 5.32988ZM6.36502 6.07488C6.33766 6.13937 6.29829 6.19808 6.24902 6.24788C6.19908 6.29724 6.14042 6.33691 6.07602 6.36488C6.00854 6.39297 5.93611 6.40725 5.86302 6.40688C5.78991 6.40744 5.71744 6.39315 5.65002 6.36488C5.58541 6.33729 5.52668 6.29757 5.47702 6.24788C5.42691 6.19856 5.38713 6.13975 5.36002 6.07488C5.30401 5.9384 5.30401 5.78536 5.36002 5.64888C5.41536 5.51846 5.51941 5.41477 5.65002 5.35988C5.71737 5.33126 5.78984 5.31663 5.86302 5.31688C5.93618 5.31685 6.0086 5.33147 6.07602 5.35988C6.14037 5.38749 6.19904 5.42682 6.24902 5.47588C6.29786 5.52603 6.33717 5.58465 6.36502 5.64888C6.3934 5.7163 6.40802 5.78872 6.40802 5.86188C6.40802 5.93503 6.3934 6.00745 6.36502 6.07488ZM14 3H10V4H14V3Z" fill="#C5C5C5"/>
+</svg>
diff --git a/elpa/company-20220425.1145/icons/vscode-dark/symbol-parameter.svg b/elpa/company-20220425.1145/icons/vscode-dark/symbol-parameter.svg
new file mode 100644
index 0000000..425ced3
--- /dev/null
+++ b/elpa/company-20220425.1145/icons/vscode-dark/symbol-parameter.svg
@@ -0,0 +1,3 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M11 6H10V5.5C10 5.22386 9.77616 5 9.50001 5H8.47902V10.5C8.47902 10.7761 8.70288 11 8.97902 11H9.47902V12H6.47902V11H6.97902C7.25516 11 7.47902 10.7761 7.47902 10.5V5H6.50001C6.22387 5 6.00001 5.22386 6.00001 5.5V6H5.00001V4H11V6ZM13.9142 8.0481L12.4519 6.58581L13.159 5.87871L14.9749 7.69454V8.40165L13.2071 10.1694L12.5 9.46231L13.9142 8.0481ZM3.5481 9.4623L2.08581 8.00002L3.50002 6.58581L2.79291 5.8787L1.02515 7.64647V8.35357L2.841 10.1694L3.5481 9.4623Z" fill="#C5C5C5"/>
+</svg>
diff --git a/elpa/company-20220425.1145/icons/vscode-dark/symbol-property.svg b/elpa/company-20220425.1145/icons/vscode-dark/symbol-property.svg
new file mode 100644
index 0000000..7137a9d
--- /dev/null
+++ b/elpa/company-20220425.1145/icons/vscode-dark/symbol-property.svg
@@ -0,0 +1,3 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M2.80723 14.9754C2.57119 14.9721 2.33826 14.9211 2.12247 14.8254C1.90667 14.7297 1.71248 14.5913 1.55158 14.4186C1.2385 14.1334 1.04433 13.7408 1.00775 13.3189C0.966225 12.8828 1.09269 12.4473 1.36133 12.1013C2.56779 10.8289 4.9473 8.4494 6.67811 6.75479C6.30983 5.75887 6.32704 4.66127 6.72637 3.67739C7.05474 2.85876 7.63869 2.16805 8.39129 1.70807C8.9817 1.31706 9.66031 1.07944 10.3657 1.01673C11.0711 0.954022 11.7809 1.06819 12.4311 1.34892L13.0482 1.6162L10.1824 4.56738L11.4371 5.82582L14.3809 2.94887L14.6482 3.56788C14.8735 4.08976 14.993 4.65119 14.9997 5.21961C15.0064 5.78802 14.9002 6.35211 14.6872 6.87915C14.476 7.40029 14.1623 7.87368 13.7647 8.27122C13.5394 8.49169 13.2904 8.68653 13.0222 8.85218C12.4673 9.22275 11.8324 9.45636 11.1697 9.5338C10.5069 9.61124 9.83521 9.5303 9.20982 9.29764C8.11194 10.4113 5.37142 13.1704 3.89119 14.5522C3.59426 14.8219 3.20832 14.9726 2.80723 14.9754ZM10.7448 1.92802C10.087 1.92637 9.44359 2.12018 8.89614 2.48485C8.68265 2.6152 8.48437 2.76897 8.30498 2.9433C7.82789 3.42423 7.50926 4.03953 7.39182 4.70669C7.27438 5.37385 7.36374 6.06098 7.64792 6.67591L7.78342 6.97288L7.55048 7.20025C5.81224 8.89672 3.28146 11.4201 2.06479 12.7045C1.95646 12.8658 1.91012 13.0608 1.93435 13.2535C1.95857 13.4463 2.05171 13.6238 2.19657 13.7532C2.28005 13.8462 2.38177 13.9211 2.49541 13.9731C2.59557 14.0184 2.70383 14.043 2.81373 14.0455C2.98064 14.0413 3.14044 13.977 3.26383 13.8646C4.83687 12.3964 7.87622 9.32641 8.76807 8.42435L8.9973 8.19326L9.29242 8.32783C9.80617 8.56732 10.3731 8.66985 10.9382 8.62545C11.5033 8.58106 12.0473 8.39125 12.5174 8.07447C12.7313 7.9426 12.9296 7.78694 13.1085 7.61045C13.4183 7.30153 13.6631 6.93374 13.8286 6.52874C13.994 6.12375 14.0767 5.68974 14.0719 5.25228C14.0719 5.03662 14.0505 4.82148 14.0078 4.61007L11.4306 7.12508L8.87944 4.57759L11.3944 1.98834C11.1804 1.94674 10.9628 1.92653 10.7448 1.92802Z" fill="#C5C5C5"/>
+</svg>
diff --git a/elpa/company-20220425.1145/icons/vscode-dark/symbol-ruler.svg b/elpa/company-20220425.1145/icons/vscode-dark/symbol-ruler.svg
new file mode 100644
index 0000000..1957dba
--- /dev/null
+++ b/elpa/company-20220425.1145/icons/vscode-dark/symbol-ruler.svg
@@ -0,0 +1,3 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M4 1L3 2V14L4 15H12L13 14V2L12 1H4ZM4 3V2H12V14H4V13H6V12H4V10H8V9H4V7H6V6H4V4H8V3H4Z" fill="#C5C5C5"/>
+</svg>
diff --git a/elpa/company-20220425.1145/icons/vscode-dark/symbol-snippet.svg b/elpa/company-20220425.1145/icons/vscode-dark/symbol-snippet.svg
new file mode 100644
index 0000000..79799f9
--- /dev/null
+++ b/elpa/company-20220425.1145/icons/vscode-dark/symbol-snippet.svg
@@ -0,0 +1,3 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M2.5 1L2 1.5V13H3V2H14V13H15V1.5L14.5 1H2.5ZM2 15V14H3V15H2ZM5 14.0001H4V15.0001H5V14.0001ZM6 14.0001H7V15.0001H6V14.0001ZM9 14.0001H8V15.0001H9V14.0001ZM10 14.0001H11V15.0001H10V14.0001ZM15 15.0001V14.0001H14V15.0001H15ZM12 14.0001H13V15.0001H12V14.0001Z" fill="#C5C5C5"/>
+</svg>
diff --git a/elpa/company-20220425.1145/icons/vscode-dark/symbol-string.svg b/elpa/company-20220425.1145/icons/vscode-dark/symbol-string.svg
new file mode 100644
index 0000000..ef5f226
--- /dev/null
+++ b/elpa/company-20220425.1145/icons/vscode-dark/symbol-string.svg
@@ -0,0 +1,3 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M2 2L1 3V12L2 13H14L15 12V3L14 2H2ZM2 12V3H14V12H2ZM5.3556 8.93017H6V7.22067C6 6.40689 5.68534 6 5.05603 6C4.92098 6 4.77083 6.02421 4.6056 6.07263C4.44181 6.12104 4.3125 6.17691 4.21767 6.24022V6.90503C4.45474 6.70205 4.70474 6.60056 4.96767 6.60056C5.22917 6.60056 5.35991 6.75698 5.35991 7.06983L4.76078 7.17318C4.25359 7.25885 4 7.57914 4 8.13408C4 8.39665 4.06106 8.60708 4.18319 8.76536C4.30675 8.92179 4.47557 9 4.68966 9C4.97989 9 5.19899 8.83985 5.34698 8.51955H5.3556V8.93017ZM5.35991 7.57542V7.76816C5.35991 7.9432 5.31968 8.08845 5.23922 8.20391C5.15876 8.3175 5.0546 8.3743 4.92672 8.3743C4.83477 8.3743 4.76149 8.34264 4.7069 8.27933C4.65374 8.21415 4.62716 8.13128 4.62716 8.03073C4.62716 7.80912 4.73779 7.6797 4.95905 7.64246L5.35991 7.57542ZM7.60094 8.62622H7.59343V8.93511H7V5H7.59343V6.67683H7.60094C7.74742 6.36708 7.95587 6.2122 8.22629 6.2122C8.47418 6.2122 8.6651 6.32987 8.79906 6.56522C8.93302 6.80056 9 7.12243 9 7.53082C9 7.97383 8.92175 8.32944 8.76526 8.59766C8.60876 8.86589 8.39969 9 8.13803 9C7.90141 9 7.72238 8.87541 7.60094 8.62622ZM7.58404 7.50487V7.77742C7.58404 7.94873 7.61972 8.09063 7.69108 8.20311C7.76244 8.3156 7.85383 8.37184 7.96526 8.37184C8.10047 8.37184 8.20501 8.30002 8.27887 8.15639C8.35399 8.01103 8.39155 7.80597 8.39155 7.54121C8.39155 7.32144 8.35712 7.15012 8.28826 7.02726C8.22066 6.90266 8.12363 6.84036 7.99718 6.84036C7.87825 6.84036 7.77934 6.9018 7.70047 7.02466C7.62285 7.14752 7.58404 7.30759 7.58404 7.50487ZM11.2616 9C11.5834 9 11.8295 8.94227 12 8.82682V8.11732C11.82 8.25512 11.636 8.32402 11.448 8.32402C11.2362 8.32402 11.0697 8.25233 10.9486 8.10894C10.8276 7.96369 10.767 7.76443 10.767 7.51117C10.767 7.25047 10.8299 7.04656 10.9558 6.89944C11.0832 6.75047 11.2553 6.67598 11.4719 6.67598C11.6663 6.67598 11.8423 6.74488 12 6.88268V6.13408C11.871 6.04469 11.6623 6 11.374 6C10.9566 6 10.6229 6.1406 10.3728 6.42179C10.1243 6.70112 10 7.0838 10 7.56983C10 7.99069 10.1163 8.33426 10.3489 8.60056C10.5814 8.86685 10.8857 9 11.2616 9Z" fill="#C5C5C5"/>
+</svg>
diff --git a/elpa/company-20220425.1145/icons/vscode-dark/symbol-structure.svg b/elpa/company-20220425.1145/icons/vscode-dark/symbol-structure.svg
new file mode 100644
index 0000000..13766a5
--- /dev/null
+++ b/elpa/company-20220425.1145/icons/vscode-dark/symbol-structure.svg
@@ -0,0 +1,3 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M2 2L1 3V6L2 7H14L15 6V3L14 2H2ZM2 3H3H13H14V4V5V6H13H3H2V5V4V3ZM1 10L2 9H5L6 10V13L5 14H2L1 13V10ZM3 10H2V11V12V13H3H4H5V12V11V10H4H3ZM10 10L11 9H14L15 10V13L14 14H11L10 13V10ZM12 10H11V11V12V13H12H13H14V12V11V10H13H12Z" fill="#C5C5C5"/>
+</svg>
diff --git a/elpa/company-20220425.1145/icons/vscode-dark/symbol-variable.svg b/elpa/company-20220425.1145/icons/vscode-dark/symbol-variable.svg
new file mode 100644
index 0000000..5ee50e0
--- /dev/null
+++ b/elpa/company-20220425.1145/icons/vscode-dark/symbol-variable.svg
@@ -0,0 +1,3 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M2 5H4V4H1.5L1 4.5V12.5L1.5 13H4V12H2V5ZM14.5 4H12V5H14V12H12V13H14.5L15 12.5V4.5L14.5 4ZM11.76 6.56995L12 7V9.51001L11.7 9.95996L7.19995 11.96H6.73999L4.23999 10.46L4 10.03V7.53003L4.30005 7.06995L8.80005 5.06995H9.26001L11.76 6.56995ZM5 9.70996L6.5 10.61V9.28003L5 8.38V9.70996ZM5.57996 7.56006L7.03003 8.43005L10.42 6.93005L8.96997 6.06006L5.57996 7.56006ZM7.53003 10.73L11.03 9.17004V7.77002L7.53003 9.31995V10.73Z" fill="#75BEFF"/>
+</svg>
diff --git a/elpa/company-20220425.1145/icons/vscode-light/folder.svg b/elpa/company-20220425.1145/icons/vscode-light/folder.svg
new file mode 100644
index 0000000..c0939fe
--- /dev/null
+++ b/elpa/company-20220425.1145/icons/vscode-light/folder.svg
@@ -0,0 +1,3 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M14.5002 3H7.71021L6.86023 2.15002L6.51025 2H1.51025L1.01025 2.5V6.5V13.5L1.51025 14H14.5103L15.0103 13.5V9V3.5L14.5002 3ZM13.9902 11.49V13H1.99023V11.49V7.48999V7H6.48022L6.8302 6.84998L7.69019 5.98999H14.0002V7.48999L13.9902 11.49ZM13.9902 5H7.49023L7.14026 5.15002L6.28027 6.01001H2.00024V3.01001H6.29028L7.14026 3.85999L7.50024 4.01001H14.0002L13.9902 5Z" fill="#424242"/>
+</svg> \ No newline at end of file
diff --git a/elpa/company-20220425.1145/icons/vscode-light/references.svg b/elpa/company-20220425.1145/icons/vscode-light/references.svg
new file mode 100644
index 0000000..eea62e0
--- /dev/null
+++ b/elpa/company-20220425.1145/icons/vscode-light/references.svg
@@ -0,0 +1,10 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g clip-path="url(#clip0)">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M11.1055 4.5613L7.67529 7.98827L6.54097 6.86834L8.61123 4.78848H3.81155C3.17507 4.78848 2.56466 5.04132 2.11461 5.49138C1.66455 5.94144 1.41171 6.55184 1.41171 7.18832C1.41171 7.8248 1.66455 8.43521 2.11461 8.88527C2.56466 9.33532 3.17507 9.58816 3.81155 9.58816H4.70109V11.1881H3.82115C2.79234 11.142 1.82094 10.7009 1.1092 9.95661C0.397467 9.21231 0.000244141 8.22216 0.000244141 7.19232C0.000244141 6.16249 0.397467 5.17234 1.1092 4.42803C1.82094 3.68373 2.79234 3.24263 3.82115 3.19659H8.62083L6.54097 1.13112L7.67529 0L11.1055 3.43177V4.5613ZM16.6203 24H7.02094L6.22099 23.2V10.4121L7.02094 9.61215H16.6203L17.4202 10.4121V23.2L16.6203 24ZM7.82089 22.4001H15.8204V11.212H7.82089V22.4001ZM13.4205 1.6015H23.0199L23.8198 2.40145V15.1878L23.0199 15.9877H19.0201V14.3878H22.2199V3.20139H14.2205V7.98828H12.6206V2.40145L13.4205 1.6015ZM14.2205 12.7879H9.42078V14.3878H14.2205V12.7879ZM9.42078 15.9877H14.2205V17.5876H9.42078V15.9877ZM14.2205 19.1875H9.42078V20.7874H14.2205V19.1875ZM15.8203 4.78848H20.62V6.38838H15.8203V4.78848ZM20.62 11.188H19.0201V12.7879H20.62V11.188ZM17.2827 8.01228V7.98828H20.62V9.58817H18.8585L17.2827 8.01228Z" fill="#424242"/>
+</g>
+<defs>
+<clipPath id="clip0">
+<rect width="24" height="24" fill="white" transform="translate(0.000244141)"/>
+</clipPath>
+</defs>
+</svg>
diff --git a/elpa/company-20220425.1145/icons/vscode-light/symbol-array.svg b/elpa/company-20220425.1145/icons/vscode-light/symbol-array.svg
new file mode 100644
index 0000000..9d7a388
--- /dev/null
+++ b/elpa/company-20220425.1145/icons/vscode-light/symbol-array.svg
@@ -0,0 +1,3 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M1.50024 2L1.00024 2.5V13.5L1.50024 14H4.00024V13H2.00024V3H4.00024V2H1.50024ZM14.5002 14L15.0002 13.5L15.0002 2.5L14.5002 2H12.0002V3L14.0002 3L14.0002 13H12.0002V14H14.5002Z" fill="#424242"/>
+</svg>
diff --git a/elpa/company-20220425.1145/icons/vscode-light/symbol-boolean.svg b/elpa/company-20220425.1145/icons/vscode-light/symbol-boolean.svg
new file mode 100644
index 0000000..8cee69d
--- /dev/null
+++ b/elpa/company-20220425.1145/icons/vscode-light/symbol-boolean.svg
@@ -0,0 +1,3 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M1.00024 3.5L1.50024 3H14.5002L15.0002 3.5L15.0002 12.5L14.5002 13H1.50024L1.00024 12.5V3.5ZM14.0002 4H8.00024L8.00024 7.49297L7.89818 7.49285L7.50024 7.49225V7.49237L3.92639 7.48807L6.01662 5.39784L5.30951 4.69073L2.3538 7.64645L2.3538 8.35355L5.30951 11.3093L6.01662 10.6022L3.90253 8.48807L7.89785 8.49285L8.00024 8.493V7.50702L11.9075 7.51222L9.79313 5.39784L10.5002 4.69073L13.456 7.64645V8.35355L10.5002 11.3093L9.79313 10.6022L11.8831 8.51222L8.00024 8.50702V12H14.0002V4Z" fill="#424242"/>
+</svg>
diff --git a/elpa/company-20220425.1145/icons/vscode-light/symbol-class.svg b/elpa/company-20220425.1145/icons/vscode-light/symbol-class.svg
new file mode 100644
index 0000000..7b0c2b9
--- /dev/null
+++ b/elpa/company-20220425.1145/icons/vscode-light/symbol-class.svg
@@ -0,0 +1,3 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M11.3403 9.70998H12.0503L14.7202 7.04005V6.32997L13.3803 5.00001H12.6803L10.8603 6.81007H5.86024V5.56007L7.72023 3.70997V3L5.72022 1H5.00025L1.00024 5.00001V5.70997L3.00025 7.70998H3.71027L4.85023 6.56007V12.35L5.35023 12.85H10.0003V13.37L11.3303 14.71H12.0402L14.7103 12.0401V11.33L13.3703 10H12.6703L10.8103 11.85H5.81025V7.84999H10.0003V8.32997L11.3403 9.70998ZM13.0303 6.06007L13.6602 6.68995L11.6602 8.68996L11.0303 8.06007L13.0303 6.06007ZM13.0303 11.0601L13.6602 11.69L11.6602 13.69L11.0303 13.0601L13.0303 11.0601ZM3.35022 6.65004L2.06024 5.34998L5.35023 2.06006L6.65028 3.34998L3.35022 6.65004Z" fill="#D67E00"/>
+</svg>
diff --git a/elpa/company-20220425.1145/icons/vscode-light/symbol-color.svg b/elpa/company-20220425.1145/icons/vscode-light/symbol-color.svg
new file mode 100644
index 0000000..a67efd3
--- /dev/null
+++ b/elpa/company-20220425.1145/icons/vscode-light/symbol-color.svg
@@ -0,0 +1,3 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M8.00024 1.00305C6.14373 1.00305 4.36323 1.74059 3.05048 3.05334C1.73772 4.3661 1.00024 6.14654 1.00024 8.00305V8.43311C1.09024 9.94311 2.91024 10.2231 4.00024 9.13306C4.35673 8.81625 4.82078 8.64759 5.29749 8.66162C5.77419 8.67565 6.22753 8.87127 6.56476 9.2085C6.90199 9.54572 7.0976 9.99912 7.11163 10.4758C7.12567 10.9525 6.95707 11.4166 6.64026 11.7731C5.54026 12.9331 5.85025 14.843 7.44025 14.973H8.04022C9.89674 14.973 11.6772 14.2356 12.99 12.9229C14.3027 11.6101 15.0402 9.82954 15.0402 7.97302C15.0402 6.11651 14.3027 4.33607 12.99 3.02332C11.6772 1.71056 9.89674 0.973022 8.04022 0.973022L8.00024 1.00305ZM8.00024 14.0031H7.48022C7.34775 13.9989 7.22072 13.9495 7.12024 13.863C7.04076 13.7807 6.98839 13.6761 6.97021 13.5631C6.93834 13.3682 6.95353 13.1684 7.0144 12.9806C7.07528 12.7927 7.18013 12.6222 7.32025 12.483C7.84072 11.9474 8.1319 11.2299 8.1319 10.483C8.1319 9.73615 7.84072 9.0187 7.32025 8.48303C7.05373 8.21635 6.73723 8.00481 6.38892 7.86047C6.0406 7.71614 5.66726 7.64185 5.29022 7.64185C4.91318 7.64185 4.53984 7.71614 4.19153 7.86047C3.84321 8.00481 3.52678 8.21635 3.26025 8.48303C3.15093 8.61081 3.01113 8.709 2.85382 8.76843C2.69651 8.82786 2.52673 8.84657 2.36023 8.823C2.27617 8.80694 2.19927 8.76498 2.14026 8.703C2.07155 8.6224 2.0358 8.5189 2.04022 8.41309V8.04309C2.04022 6.8564 2.39216 5.69629 3.05145 4.70959C3.71074 3.7229 4.64778 2.95388 5.74414 2.49976C6.8405 2.04563 8.04693 1.92681 9.21082 2.15833C10.3747 2.38984 11.4438 2.9613 12.2829 3.80042C13.122 4.63953 13.6934 5.70867 13.9249 6.87256C14.1564 8.03644 14.0376 9.24275 13.5835 10.3391C13.1294 11.4355 12.3604 12.3726 11.3737 13.0319C10.387 13.6911 9.22691 14.0431 8.04022 14.0431L8.00024 14.0031ZM9.00024 3.99683C9.00024 4.54911 8.55253 4.99683 8.00024 4.99683C7.44796 4.99683 7.00024 4.54911 7.00024 3.99683C7.00024 3.44454 7.44796 2.99683 8.00024 2.99683C8.55253 2.99683 9.00024 3.44454 9.00024 3.99683ZM12.0002 11.0037C12.0002 11.5559 11.5525 12.0037 11.0002 12.0037C10.448 12.0037 10.0002 11.5559 10.0002 11.0037C10.0002 10.4514 10.448 10.0037 11.0002 10.0037C11.5525 10.0037 12.0002 10.4514 12.0002 11.0037ZM5.00024 6.00415C5.55253 6.00415 6.00024 5.55644 6.00024 5.00415C6.00024 4.45187 5.55253 4.00415 5.00024 4.00415C4.44796 4.00415 4.00024 4.45187 4.00024 5.00415C4.00024 5.55644 4.44796 6.00415 5.00024 6.00415ZM12.0002 5.00415C12.0002 5.55644 11.5525 6.00415 11.0002 6.00415C10.448 6.00415 10.0002 5.55644 10.0002 5.00415C10.0002 4.45187 10.448 4.00415 11.0002 4.00415C11.5525 4.00415 12.0002 4.45187 12.0002 5.00415ZM13.0003 7.99939C13.0003 8.55167 12.5526 8.99939 12.0003 8.99939C11.448 8.99939 11.0003 8.55167 11.0003 7.99939C11.0003 7.4471 11.448 6.99939 12.0003 6.99939C12.5526 6.99939 13.0003 7.4471 13.0003 7.99939Z" fill="#424242"/>
+</svg>
diff --git a/elpa/company-20220425.1145/icons/vscode-light/symbol-constant.svg b/elpa/company-20220425.1145/icons/vscode-light/symbol-constant.svg
new file mode 100644
index 0000000..5f185bc
--- /dev/null
+++ b/elpa/company-20220425.1145/icons/vscode-light/symbol-constant.svg
@@ -0,0 +1,4 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M4.00024 6H12.0002V7H4.00024V6ZM12.0002 9H4.00024V10H12.0002V9Z" fill="#424242"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M1.00024 4L2.00024 3H14.0002L15.0002 4V12L14.0002 13H2.00024L1.00024 12V4ZM2.00024 4V12H14.0002V4H2.00024Z" fill="#424242"/>
+</svg>
diff --git a/elpa/company-20220425.1145/icons/vscode-light/symbol-enumerator-member.svg b/elpa/company-20220425.1145/icons/vscode-light/symbol-enumerator-member.svg
new file mode 100644
index 0000000..31d1654
--- /dev/null
+++ b/elpa/company-20220425.1145/icons/vscode-light/symbol-enumerator-member.svg
@@ -0,0 +1,3 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M7.00024 3L8.00024 2H14.0002L15.0002 3V8L14.0002 9H10.0002V8H14.0002V3H8.00024V6H7.00024V3ZM9.00024 9V8L8.00024 7H7.00024H2.00024L1.00024 8V13L2.00024 14H8.00024L9.00024 13V9ZM8.00024 8V9V13H2.00024V8H7.00024H8.00024ZM9.41446 7L9.00024 6.58579V6H13.0002V7H9.41446ZM9.00024 4H13.0002V5H9.00024V4ZM7.00024 10H3.00024V11H7.00024V10Z" fill="#007ACC"/>
+</svg>
diff --git a/elpa/company-20220425.1145/icons/vscode-light/symbol-enumerator.svg b/elpa/company-20220425.1145/icons/vscode-light/symbol-enumerator.svg
new file mode 100644
index 0000000..dbbc5fd
--- /dev/null
+++ b/elpa/company-20220425.1145/icons/vscode-light/symbol-enumerator.svg
@@ -0,0 +1,3 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M14.0002 2H8.00024L7.00024 3V6H8.00024V3H14.0002V8H10.0002V9H14.0002L15.0002 8V3L14.0002 2ZM9.00024 6H13.0002V7H9.41024L9.00024 6.59V6ZM7.00024 7H2.00024L1.00024 8V13L2.00024 14H8.00024L9.00024 13V8L8.00024 7H7.00024ZM8.00024 13H2.00024V8H8.00024V9V13ZM3.00024 9H7.00024V10H3.00024V9ZM3.00024 11H7.00024V12H3.00024V11ZM9.00024 4H13.0002V5H9.00024V4Z" fill="#D67E00"/>
+</svg>
diff --git a/elpa/company-20220425.1145/icons/vscode-light/symbol-event.svg b/elpa/company-20220425.1145/icons/vscode-light/symbol-event.svg
new file mode 100644
index 0000000..31e574b
--- /dev/null
+++ b/elpa/company-20220425.1145/icons/vscode-light/symbol-event.svg
@@ -0,0 +1,3 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M7.41379 1.55996L8.31177 1H11.6059L12.4243 2.57465L10.2358 6H12.0176L12.7365 7.69512L5.61967 15L4.01699 13.837L6.11967 10H4.89822L4.00024 8.55996L7.41379 1.55996ZM7.78058 9L4.90078 14.3049L12.0176 7H8.31177L11.6059 2H8.31177L4.89822 9H7.78058Z" fill="#D67E00"/>
+</svg>
diff --git a/elpa/company-20220425.1145/icons/vscode-light/symbol-field.svg b/elpa/company-20220425.1145/icons/vscode-light/symbol-field.svg
new file mode 100644
index 0000000..5151b2a
--- /dev/null
+++ b/elpa/company-20220425.1145/icons/vscode-light/symbol-field.svg
@@ -0,0 +1,3 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M14.4502 4.5L9.4502 2H8.55029L1.55029 5.5L1.00024 6.39001V10.89L1.55029 11.79L6.55029 14.29H7.4502L14.4502 10.79L15.0002 9.89001V5.39001L14.4502 4.5ZM6.4502 13.14L1.9502 10.89V7.17004L6.4502 9.17004V13.14ZM6.9502 8.33997L2.29028 6.22998L8.9502 2.89001L13.6202 5.22998L6.9502 8.33997ZM13.9502 9.89001L7.4502 13.14V9.20996L13.9502 6.20996V9.89001Z" fill="#007ACC"/>
+</svg>
diff --git a/elpa/company-20220425.1145/icons/vscode-light/symbol-file.svg b/elpa/company-20220425.1145/icons/vscode-light/symbol-file.svg
new file mode 100644
index 0000000..781e39e
--- /dev/null
+++ b/elpa/company-20220425.1145/icons/vscode-light/symbol-file.svg
@@ -0,0 +1,3 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M13.8502 4.44L10.5702 1.14L10.2202 1H2.50024L2.00024 1.5V14.5L2.50024 15H13.5002L14.0002 14.5V4.8L13.8502 4.44ZM13.0002 5H10.0002V2L13.0002 5ZM3.00024 14V2H9.00024V5.5L9.50024 6H13.0002V14H3.00024Z" fill="#424242"/>
+</svg>
diff --git a/elpa/company-20220425.1145/icons/vscode-light/symbol-interface.svg b/elpa/company-20220425.1145/icons/vscode-light/symbol-interface.svg
new file mode 100644
index 0000000..3b83725
--- /dev/null
+++ b/elpa/company-20220425.1145/icons/vscode-light/symbol-interface.svg
@@ -0,0 +1,3 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M11.4967 4C10.6552 3.9989 9.8416 4.30189 9.20581 4.85315C8.57002 5.40442 8.15489 6.16684 8.03674 7H4.93665C4.81495 6.52867 4.52557 6.11794 4.12268 5.84473C3.71979 5.57152 3.23108 5.45466 2.74817 5.51599C2.26526 5.57733 1.82131 5.81261 1.49951 6.17786C1.17772 6.54311 1.00024 7.01322 1.00024 7.5C1.00024 7.98679 1.17772 8.45689 1.49951 8.82215C1.82131 9.1874 2.26526 9.42267 2.74817 9.48401C3.23108 9.54535 3.71979 9.42848 4.12268 9.15528C4.52557 8.88207 4.81495 8.47133 4.93665 8H8.03674C8.13261 8.66418 8.41741 9.28683 8.85718 9.7937C9.29695 10.3006 9.87308 10.6703 10.5171 10.8589C11.1611 11.0475 11.8458 11.047 12.4895 10.8574C13.1332 10.6679 13.7089 10.2973 14.1479 9.7898C14.587 9.28227 14.8708 8.65919 14.9657 7.99488C15.0606 7.33056 14.9624 6.65298 14.683 6.04285C14.4036 5.43272 13.9547 4.91578 13.3898 4.55359C12.8248 4.19141 12.1678 3.99922 11.4967 4V4ZM11.4967 10C11.0023 10 10.5189 9.85332 10.1078 9.57862C9.69667 9.30391 9.37623 8.91348 9.18701 8.45667C8.99779 7.99985 8.94834 7.49728 9.0448 7.01233C9.14126 6.52738 9.37925 6.08181 9.72888 5.73218C10.0785 5.38255 10.5241 5.14456 11.009 5.0481C11.494 4.95164 11.9966 5.00109 12.4534 5.19031C12.9102 5.37953 13.3006 5.69996 13.5753 6.11109C13.85 6.52221 13.9967 7.00555 13.9967 7.5C13.9967 8.16304 13.7334 8.79898 13.2645 9.26783C12.7957 9.73667 12.1597 10 11.4967 10V10Z" fill="#007ACC"/>
+</svg>
diff --git a/elpa/company-20220425.1145/icons/vscode-light/symbol-key.svg b/elpa/company-20220425.1145/icons/vscode-light/symbol-key.svg
new file mode 100644
index 0000000..6af4c1a
--- /dev/null
+++ b/elpa/company-20220425.1145/icons/vscode-light/symbol-key.svg
@@ -0,0 +1,3 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M7.22313 10.933C7.54888 11.1254 7.92188 11.2231 8.30013 11.215C8.63802 11.2218 8.97279 11.1492 9.27746 11.003C9.58213 10.8567 9.84817 10.6409 10.0541 10.373C10.5094 9.76519 10.7404 9.01867 10.7081 8.25998C10.7414 7.58622 10.5376 6.9221 10.1321 6.38298C9.93599 6.14161 9.68601 5.94957 9.40225 5.82228C9.11848 5.69498 8.80883 5.63597 8.49813 5.64997C8.07546 5.64699 7.66018 5.76085 7.29813 5.97898C7.18328 6.04807 7.07515 6.12775 6.97513 6.21698V3.47498H5.98413V11.1H6.97913V10.756C7.0554 10.8217 7.13702 10.8809 7.22313 10.933ZM7.85005 6.70006C8.03622 6.62105 8.23832 6.58677 8.44013 6.59998C8.61281 6.59452 8.78429 6.63054 8.94018 6.70501C9.09608 6.77948 9.23185 6.89023 9.33613 7.02798C9.59277 7.39053 9.71865 7.82951 9.69313 8.27297C9.71996 8.79748 9.57993 9.31701 9.29313 9.75698C9.18846 9.91527 9.04571 10.0447 8.87797 10.1335C8.71023 10.2223 8.52289 10.2675 8.33313 10.265C8.14958 10.2732 7.96654 10.24 7.79758 10.1678C7.62862 10.0956 7.47809 9.98628 7.35713 9.84797C7.10176 9.55957 6.96525 9.18506 6.97513 8.79998V8.19998C6.96324 7.78332 7.10287 7.3765 7.36813 7.05498C7.49883 6.90064 7.66388 6.77908 7.85005 6.70006ZM3.28926 5.67499C2.97035 5.67933 2.65412 5.734 2.35226 5.83699C2.06442 5.92293 1.79372 6.05828 1.55226 6.23699L1.45226 6.31399V7.51399L1.87526 7.15499C2.24603 6.80478 2.73158 6.60146 3.24126 6.58299C3.36617 6.57164 3.49194 6.59147 3.60731 6.64068C3.72267 6.6899 3.82402 6.76697 3.90226 6.86499C4.05245 7.0971 4.13264 7.36754 4.13326 7.64399L2.90026 7.82499C2.39459 7.87781 1.9155 8.07772 1.52226 8.39999C1.36721 8.55181 1.24363 8.73271 1.15859 8.93235C1.07355 9.13199 1.02873 9.34644 1.02668 9.56343C1.02464 9.78042 1.06542 9.99568 1.14668 10.1969C1.22795 10.3981 1.3481 10.5813 1.50026 10.736C1.66895 10.8904 1.86647 11.01 2.08149 11.0879C2.29651 11.1659 2.5248 11.2005 2.75326 11.19C3.14725 11.1931 3.53302 11.0774 3.86026 10.858C3.96178 10.7897 4.05744 10.7131 4.14626 10.629V11.073H5.08726V7.71499C5.12161 7.17422 4.95454 6.63988 4.61826 6.21499C4.45004 6.03285 4.24373 5.89003 4.01402 5.7967C3.78431 5.70336 3.53686 5.66181 3.28926 5.67499ZM4.14626 8.71599C4.16588 9.13435 4.02616 9.54459 3.75526 9.864C3.63714 10.0005 3.49023 10.1092 3.3251 10.1821C3.15998 10.2551 2.98073 10.2906 2.80026 10.286C2.69073 10.2945 2.5806 10.2812 2.47624 10.2469C2.37187 10.2125 2.27536 10.1579 2.19226 10.086C2.06104 9.93455 1.9888 9.74088 1.9888 9.54049C1.9888 9.34011 2.06104 9.14644 2.19226 8.99499C2.47347 8.82131 2.79258 8.71837 3.12226 8.69499L4.14226 8.54699L4.14626 8.71599ZM12.459 11.0325C12.7663 11.1638 13.0985 11.2261 13.4324 11.215C13.9273 11.227 14.4156 11.1006 14.8424 10.85L14.9654 10.775L14.9784 10.768V9.61504L14.5324 9.93504C14.2163 10.1592 13.8359 10.2747 13.4484 10.264C13.2499 10.2719 13.0522 10.2342 12.8705 10.1538C12.6889 10.0733 12.5281 9.95232 12.4004 9.80004C12.1146 9.42453 11.9728 8.95911 12.0004 8.48804C11.9739 7.98732 12.1355 7.49475 12.4534 7.10704C12.5936 6.94105 12.7698 6.80914 12.9685 6.7213C13.1672 6.63346 13.3833 6.592 13.6004 6.60004C13.9441 6.59844 14.281 6.69525 14.5714 6.87904L15.0004 7.14404V5.97004L14.8314 5.89704C14.4628 5.73432 14.0644 5.6502 13.6614 5.65004C13.3001 5.63991 12.9409 5.70762 12.608 5.84859C12.2752 5.98956 11.9766 6.20048 11.7324 6.46704C11.2263 7.02683 10.9584 7.76186 10.9854 8.51604C10.9569 9.22346 11.1958 9.91569 11.6544 10.455C11.8772 10.704 12.1518 10.9012 12.459 11.0325Z" fill="#424242"/>
+</svg>
diff --git a/elpa/company-20220425.1145/icons/vscode-light/symbol-keyword.svg b/elpa/company-20220425.1145/icons/vscode-light/symbol-keyword.svg
new file mode 100644
index 0000000..e040064
--- /dev/null
+++ b/elpa/company-20220425.1145/icons/vscode-light/symbol-keyword.svg
@@ -0,0 +1,3 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M15.0002 4H10.0002V3H15.0002V4ZM14.0002 7H12.0002V8H14.0002V7ZM10.0002 7H1.00024V8H10.0002V7ZM12.0002 13H1.00024V14H12.0002V13ZM7.00024 10H1.00024V11H7.00024V10ZM15.0002 10H10.0002V11H15.0002V10ZM8.00024 2V5H1.00024V2H8.00024ZM7.00024 3H2.00024V4H7.00024V3Z" fill="#424242"/>
+</svg>
diff --git a/elpa/company-20220425.1145/icons/vscode-light/symbol-method.svg b/elpa/company-20220425.1145/icons/vscode-light/symbol-method.svg
new file mode 100644
index 0000000..f922a9a
--- /dev/null
+++ b/elpa/company-20220425.1145/icons/vscode-light/symbol-method.svg
@@ -0,0 +1,3 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M13.5103 4L8.51025 1H7.51025L2.51025 4L2.02026 4.85999V10.86L2.51025 11.71L7.51025 14.71H8.51025L13.5103 11.71L14.0002 10.86V4.85999L13.5103 4ZM7.51025 13.5601L3.01025 10.86V5.69995L7.51025 8.15002V13.5601ZM3.27026 4.69995L8.01025 1.85999L12.7502 4.69995L8.01025 7.29004L3.27026 4.69995ZM13.0103 10.86L8.51025 13.5601V8.15002L13.0103 5.69995V10.86Z" fill="#652D90"/>
+</svg>
diff --git a/elpa/company-20220425.1145/icons/vscode-light/symbol-misc.svg b/elpa/company-20220425.1145/icons/vscode-light/symbol-misc.svg
new file mode 100644
index 0000000..57467b3
--- /dev/null
+++ b/elpa/company-20220425.1145/icons/vscode-light/symbol-misc.svg
@@ -0,0 +1,3 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M4.00024 2H12.0002V6C12.3418 6.03511 12.6777 6.11234 13.0002 6.22998V1H3.00024V9.47998L4.00024 7.72998V2ZM6.14026 10L5.00024 8L4.00024 9.75L3.29028 11L1.00024 15H9.00024L6.71021 11L6.14026 10ZM2.72021 14L4.44019 11L5.00024 10L5.5603 11L7.28027 14H2.72021ZM9.55577 7.58984C10.1313 7.20526 10.808 7 11.5002 7C12.4285 7 13.3187 7.36877 13.9751 8.02515C14.6315 8.68152 15.0002 9.57174 15.0002 10.5C15.0002 11.1922 14.795 11.8689 14.4104 12.4445C14.0258 13.02 13.4791 13.4686 12.8396 13.7335C12.2 13.9984 11.4963 14.0678 10.8174 13.9327C10.1384 13.7977 9.51485 13.4643 9.02537 12.9749C8.53589 12.4854 8.20253 11.8618 8.06748 11.1829C7.93244 10.5039 8.0018 9.80019 8.2667 9.16064C8.53161 8.5211 8.98019 7.97443 9.55577 7.58984ZM10.1113 12.5786C10.5224 12.8533 11.0058 13 11.5002 13C12.1633 13 12.7992 12.7367 13.268 12.2678C13.7369 11.799 14.0002 11.163 14.0002 10.5C14.0002 10.0055 13.8535 9.52221 13.5788 9.11108C13.3041 8.69996 12.9137 8.37953 12.4569 8.19031C12.0001 8.00109 11.4975 7.95163 11.0126 8.0481C10.5276 8.14456 10.082 8.38255 9.7324 8.73218C9.38277 9.08181 9.14478 9.52738 9.04832 10.0123C8.95186 10.4973 9.00131 10.9998 9.19053 11.4567C9.37975 11.9135 9.70018 12.3039 10.1113 12.5786Z" fill="#424242"/>
+</svg>
diff --git a/elpa/company-20220425.1145/icons/vscode-light/symbol-namespace.svg b/elpa/company-20220425.1145/icons/vscode-light/symbol-namespace.svg
new file mode 100644
index 0000000..8d1c0f4
--- /dev/null
+++ b/elpa/company-20220425.1145/icons/vscode-light/symbol-namespace.svg
@@ -0,0 +1,10 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g clip-path="url(#clip0)">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M6.00024 2.98361V2.97184V2H5.91107C5.59767 2 5.29431 2.06161 5.00152 2.18473C4.70842 2.30798 4.44967 2.48474 4.22602 2.71498C4.00336 2.94422 3.83816 3.19498 3.73306 3.46766L3.73257 3.46898C3.63406 3.7352 3.56839 4.01201 3.53557 4.29917L3.53543 4.30053C3.50702 4.5805 3.49894 4.86844 3.51108 5.16428C3.52297 5.45379 3.52891 5.74329 3.52891 6.03279C3.52891 6.23556 3.48999 6.42594 3.41225 6.60507L3.41185 6.60601C3.33712 6.78296 3.23447 6.93866 3.10341 7.07359C2.97669 7.20405 2.8249 7.31055 2.64696 7.3925C2.47084 7.46954 2.28522 7.5082 2.08942 7.5082H2.00024V7.6V8.4V8.4918H2.08942C2.2849 8.4918 2.47026 8.53238 2.64625 8.61334L2.64766 8.61396C2.82482 8.69157 2.97602 8.79762 3.10245 8.93161L3.10436 8.93352C3.23452 9.0637 3.33684 9.21871 3.41153 9.39942L3.41225 9.40108C3.49011 9.58047 3.52891 9.76883 3.52891 9.96721C3.52891 10.2567 3.52297 10.5462 3.51108 10.8357C3.49894 11.1316 3.50701 11.4215 3.5354 11.7055L3.5356 11.7072C3.56844 11.9903 3.63412 12.265 3.73256 12.531L3.73307 12.5323C3.83817 12.805 4.00336 13.0558 4.22602 13.285C4.44967 13.5153 4.70842 13.692 5.00152 13.8153C5.29431 13.9384 5.59767 14 5.91107 14H6.00024V13.2V13.0164H5.91107C5.71119 13.0164 5.52371 12.9777 5.34787 12.9008C5.17421 12.8191 5.02218 12.7126 4.89111 12.5818C4.76411 12.4469 4.66128 12.2911 4.58247 12.1137C4.50862 11.9346 4.47158 11.744 4.47158 11.541C4.47158 11.3127 4.47554 11.0885 4.48346 10.8686C4.49149 10.6411 4.49151 10.4195 4.48349 10.2039C4.47938 9.98246 4.46109 9.76883 4.42847 9.56312C4.39537 9.35024 4.33946 9.14757 4.26063 8.95536C4.18115 8.76157 4.07282 8.57746 3.9364 8.40298C3.8237 8.25881 3.68563 8.12462 3.52307 8C3.68563 7.87538 3.8237 7.74119 3.9364 7.59702C4.07282 7.42254 4.18115 7.23843 4.26063 7.04464C4.33938 6.85263 4.39537 6.65175 4.4285 6.44285C4.46107 6.2333 4.47938 6.01973 4.48349 5.80219C4.49151 5.58262 4.4915 5.36105 4.48345 5.13749C4.47554 4.9134 4.47158 4.68725 4.47158 4.45902C4.47158 4.26019 4.50857 4.07152 4.58263 3.89205C4.6616 3.71034 4.76445 3.55475 4.8911 3.42437C5.02218 3.28942 5.17485 3.18275 5.34826 3.10513C5.52404 3.02427 5.71138 2.98361 5.91107 2.98361H6.00024ZM10.0002 13.0164V13.0282V14H10.0894C10.4028 14 10.7062 13.9384 10.999 13.8153C11.2921 13.692 11.5508 13.5153 11.7745 13.285C11.9971 13.0558 12.1623 12.805 12.2674 12.5323L12.2679 12.531C12.3664 12.2648 12.4321 11.988 12.4649 11.7008L12.4651 11.6995C12.4935 11.4195 12.5015 11.1316 12.4894 10.8357C12.4775 10.5462 12.4716 10.2567 12.4716 9.96721C12.4716 9.76444 12.5105 9.57406 12.5882 9.39493L12.5886 9.39399C12.6634 9.21704 12.766 9.06134 12.8971 8.92642C13.0238 8.79595 13.1756 8.68945 13.3535 8.6075C13.5296 8.53046 13.7153 8.4918 13.9111 8.4918H14.0002V8.4V7.6V7.5082H13.9111C13.7156 7.5082 13.5302 7.46762 13.3542 7.38666L13.3528 7.38604C13.1757 7.30844 13.0245 7.20238 12.898 7.06839L12.8961 7.06648C12.766 6.9363 12.6637 6.78129 12.589 6.60058L12.5882 6.59892C12.5104 6.41953 12.4716 6.23117 12.4716 6.03279C12.4716 5.74329 12.4775 5.45379 12.4894 5.16428C12.5015 4.86842 12.4935 4.57848 12.4651 4.29454L12.4649 4.29285C12.4321 4.00971 12.3664 3.73502 12.2679 3.46897L12.2674 3.46766C12.1623 3.19499 11.9971 2.94422 11.7745 2.71498C11.5508 2.48474 11.2921 2.30798 10.999 2.18473C10.7062 2.06161 10.4028 2 10.0894 2H10.0002V2.8V2.98361H10.0894C10.2893 2.98361 10.4768 3.0223 10.6526 3.09917C10.8263 3.18092 10.9783 3.28736 11.1094 3.41823C11.2364 3.55305 11.3392 3.70889 11.418 3.88628C11.4919 4.0654 11.5289 4.25596 11.5289 4.45902C11.5289 4.68727 11.5249 4.91145 11.517 5.13142C11.509 5.35894 11.509 5.58049 11.517 5.79605C11.5211 6.01754 11.5394 6.23117 11.572 6.43688C11.6051 6.64976 11.661 6.85243 11.7399 7.04464C11.8193 7.23843 11.9277 7.42254 12.0641 7.59702C12.1768 7.74119 12.3149 7.87538 12.4774 8C12.3149 8.12462 12.1768 8.25881 12.0641 8.40298C11.9277 8.57746 11.8193 8.76157 11.7399 8.95536C11.6611 9.14737 11.6051 9.34825 11.572 9.55715C11.5394 9.7667 11.5211 9.98027 11.517 10.1978C11.509 10.4174 11.509 10.6389 11.517 10.8625C11.5249 11.0866 11.5289 11.3128 11.5289 11.541C11.5289 11.7398 11.4919 11.9285 11.4179 12.1079C11.3389 12.2897 11.236 12.4452 11.1094 12.5756C10.9783 12.7106 10.8256 12.8173 10.6522 12.8949C10.4764 12.9757 10.2891 13.0164 10.0894 13.0164H10.0002Z" fill="#424242"/>
+</g>
+<defs>
+<clipPath id="clip0">
+<rect width="16" height="16" fill="white" transform="translate(0.000244141)"/>
+</clipPath>
+</defs>
+</svg>
diff --git a/elpa/company-20220425.1145/icons/vscode-light/symbol-numeric.svg b/elpa/company-20220425.1145/icons/vscode-light/symbol-numeric.svg
new file mode 100644
index 0000000..0ab24fa
--- /dev/null
+++ b/elpa/company-20220425.1145/icons/vscode-light/symbol-numeric.svg
@@ -0,0 +1,3 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M11.0002 1V5H15.0002V6H11.0002L11.0002 10H15.0002V11H11.0002V15H10.0002V11H6.00024V15H5.00024L5.00024 11H1.00024V10H5.00024L5.00024 6H1.00024V5H5.00024L5.00024 1H6.00024V5H10.0002V1H11.0002ZM6.00024 6L6.00024 10H10.0002L10.0002 6H6.00024Z" fill="#424242"/>
+</svg>
diff --git a/elpa/company-20220425.1145/icons/vscode-light/symbol-operator.svg b/elpa/company-20220425.1145/icons/vscode-light/symbol-operator.svg
new file mode 100644
index 0000000..23d0d19
--- /dev/null
+++ b/elpa/company-20220425.1145/icons/vscode-light/symbol-operator.svg
@@ -0,0 +1,3 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M2.87313 1.10023C3.20793 1.23579 3.4757 1.498 3.61826 1.82988C3.69056 1.99959 3.72699 2.18242 3.72526 2.36688C3.72642 2.54999 3.69 2.7314 3.61826 2.89988C3.51324 3.14567 3.33807 3.35503 3.11466 3.50177C2.89126 3.64851 2.62955 3.72612 2.36226 3.72488C2.17948 3.72592 1.99842 3.68951 1.83026 3.61788C1.58322 3.51406 1.37252 3.33932 1.22478 3.11575C1.07704 2.89219 0.99891 2.62984 1.00026 2.36188C0.999374 2.17921 1.03543 1.99825 1.10626 1.82988C1.24362 1.50314 1.50353 1.24323 1.83026 1.10588C2.16357 0.966692 2.53834 0.964661 2.87313 1.10023ZM2.57526 2.86488C2.70564 2.80913 2.80951 2.70526 2.86526 2.57488C2.89314 2.50838 2.90742 2.43698 2.90726 2.36488C2.90838 2.2654 2.88239 2.1675 2.8321 2.08167C2.7818 1.99584 2.70909 1.92531 2.62176 1.87767C2.53443 1.83002 2.43577 1.80705 2.33638 1.81121C2.23698 1.81537 2.1406 1.8465 2.05755 1.90128C1.97451 1.95606 1.90794 2.03241 1.865 2.12215C1.82205 2.21188 1.80434 2.31161 1.81376 2.41065C1.82319 2.50968 1.85939 2.60428 1.9185 2.6843C1.9776 2.76433 2.05738 2.82675 2.14926 2.86488C2.28574 2.92089 2.43878 2.92089 2.57526 2.86488ZM6.43019 1.1095L1.10992 6.42977L1.79581 7.11567L7.11608 1.7954L6.43019 1.1095ZM11.5002 8.99999H12.5002V11.5H15.0002V12.5H12.5002V15H11.5002V12.5H9.00024V11.5H11.5002V8.99999ZM5.76801 9.52509L6.47512 10.2322L4.70735 12L6.47512 13.7677L5.76801 14.4748L4.00024 12.7071L2.23248 14.4748L1.52537 13.7677L3.29314 12L1.52537 10.2322L2.23248 9.52509L4.00024 11.2929L5.76801 9.52509ZM7.11826 5.32988C7.01466 5.08268 6.83997 4.87183 6.61636 4.72406C6.39275 4.57629 6.13028 4.49826 5.86226 4.49988C5.6796 4.49899 5.49864 4.53505 5.33026 4.60588C5.00353 4.74323 4.74362 5.00314 4.60626 5.32988C4.53612 5.49478 4.49922 5.67191 4.49766 5.8511C4.4961 6.0303 4.52992 6.20804 4.59718 6.37414C4.66443 6.54024 4.76381 6.69143 4.88961 6.81906C5.0154 6.94669 5.16515 7.04823 5.33026 7.11788C5.49892 7.18848 5.67993 7.22484 5.86276 7.22484C6.0456 7.22484 6.22661 7.18848 6.39526 7.11788C6.64225 7.01388 6.85295 6.83913 7.00082 6.61563C7.1487 6.39213 7.22713 6.12987 7.22626 5.86188C7.22679 5.67905 7.19005 5.49803 7.11826 5.32988ZM6.36526 6.07488C6.3379 6.13937 6.29854 6.19808 6.24926 6.24788C6.19932 6.29724 6.14066 6.33691 6.07626 6.36488C6.00878 6.39297 5.93635 6.40725 5.86326 6.40688C5.79015 6.40744 5.71769 6.39315 5.65026 6.36488C5.58565 6.33729 5.52693 6.29757 5.47726 6.24788C5.42715 6.19856 5.38738 6.13975 5.36026 6.07488C5.30425 5.9384 5.30425 5.78536 5.36026 5.64888C5.41561 5.51846 5.51965 5.41477 5.65026 5.35988C5.71761 5.33126 5.79008 5.31663 5.86326 5.31688C5.93642 5.31685 6.00884 5.33147 6.07626 5.35988C6.14062 5.38749 6.19928 5.42682 6.24926 5.47588C6.2981 5.52603 6.33741 5.58465 6.36526 5.64888C6.39364 5.7163 6.40827 5.78872 6.40827 5.86188C6.40827 5.93503 6.39364 6.00745 6.36526 6.07488ZM14.0002 3H10.0002V4H14.0002V3Z" fill="#424242"/>
+</svg>
diff --git a/elpa/company-20220425.1145/icons/vscode-light/symbol-parameter.svg b/elpa/company-20220425.1145/icons/vscode-light/symbol-parameter.svg
new file mode 100644
index 0000000..940524d
--- /dev/null
+++ b/elpa/company-20220425.1145/icons/vscode-light/symbol-parameter.svg
@@ -0,0 +1,3 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M11.0003 6H10.0003V5.5C10.0003 5.22386 9.7764 5 9.50026 5H8.47926V10.5C8.47926 10.7761 8.70312 11 8.97926 11H9.47926V12H6.47926V11H6.97926C7.2554 11 7.47926 10.7761 7.47926 10.5V5H6.50026C6.22412 5 6.00026 5.22386 6.00026 5.5V6H5.00026V4H11.0003V6ZM13.9145 8.0481L12.4522 6.58581L13.1593 5.87871L14.9751 7.69454V8.40165L13.2074 10.1694L12.5003 9.46231L13.9145 8.0481ZM3.54835 9.4623L2.08605 8.00002L3.50026 6.58581L2.79316 5.8787L1.02539 7.64647V8.35357L2.84124 10.1694L3.54835 9.4623Z" fill="#424242"/>
+</svg>
diff --git a/elpa/company-20220425.1145/icons/vscode-light/symbol-property.svg b/elpa/company-20220425.1145/icons/vscode-light/symbol-property.svg
new file mode 100644
index 0000000..efffad4
--- /dev/null
+++ b/elpa/company-20220425.1145/icons/vscode-light/symbol-property.svg
@@ -0,0 +1,3 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M2.80747 14.9754C2.57144 14.9721 2.33851 14.9211 2.12271 14.8254C1.90692 14.7297 1.71273 14.5913 1.55183 14.4186C1.23875 14.1334 1.04458 13.7408 1.00799 13.3189C0.966469 12.8828 1.09293 12.4473 1.36158 12.1013C2.56804 10.8289 4.94755 8.4494 6.67836 6.75479C6.31007 5.75887 6.32729 4.66127 6.72661 3.67739C7.05499 2.85876 7.63893 2.16805 8.39153 1.70807C8.98195 1.31706 9.66055 1.07944 10.3659 1.01673C11.0713 0.954022 11.7812 1.06819 12.4313 1.34892L13.0485 1.6162L10.1827 4.56738L11.4374 5.82582L14.3811 2.94887L14.6484 3.56788C14.8738 4.08976 14.9933 4.65119 14.9999 5.21961C15.0066 5.78802 14.9004 6.35211 14.6874 6.87915C14.4763 7.40029 14.1626 7.87368 13.7649 8.27122C13.5396 8.49169 13.2907 8.68653 13.0225 8.85218C12.4676 9.22275 11.8327 9.45636 11.1699 9.5338C10.5071 9.61124 9.83546 9.5303 9.21007 9.29764C8.11219 10.4113 5.37167 13.1704 3.89143 14.5522C3.5945 14.8219 3.20856 14.9726 2.80747 14.9754ZM10.7451 1.92802C10.0873 1.92637 9.44383 2.12018 8.89639 2.48485C8.68289 2.6152 8.48461 2.76897 8.30522 2.9433C7.82813 3.42423 7.5095 4.03953 7.39206 4.70669C7.27462 5.37385 7.36398 6.06098 7.64816 6.67591L7.78366 6.97288L7.55072 7.20025C5.81249 8.89672 3.28171 11.4201 2.06504 12.7045C1.9567 12.8658 1.91037 13.0608 1.93459 13.2535C1.95881 13.4463 2.05195 13.6238 2.19682 13.7532C2.28029 13.8462 2.38201 13.9211 2.49565 13.9731C2.59581 14.0184 2.70408 14.043 2.81397 14.0455C2.98089 14.0413 3.14068 13.977 3.26407 13.8646C4.83711 12.3964 7.87646 9.32641 8.76832 8.42435L8.99754 8.19326L9.29266 8.32783C9.80642 8.56732 10.3734 8.66985 10.9385 8.62545C11.5036 8.58106 12.0476 8.39125 12.5176 8.07447C12.7316 7.9426 12.9299 7.78694 13.1088 7.61045C13.4186 7.30153 13.6634 6.93374 13.8288 6.52874C13.9943 6.12375 14.077 5.68974 14.0721 5.25228C14.0722 5.03662 14.0507 4.82148 14.0081 4.61007L11.4309 7.12508L8.87968 4.57759L11.3947 1.98834C11.1807 1.94674 10.9631 1.92653 10.7451 1.92802Z" fill="#424242"/>
+</svg>
diff --git a/elpa/company-20220425.1145/icons/vscode-light/symbol-ruler.svg b/elpa/company-20220425.1145/icons/vscode-light/symbol-ruler.svg
new file mode 100644
index 0000000..0a0b9a4
--- /dev/null
+++ b/elpa/company-20220425.1145/icons/vscode-light/symbol-ruler.svg
@@ -0,0 +1,3 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M4.00024 1L3.00024 2V14L4.00024 15H12.0002L13.0002 14V2L12.0002 1H4.00024ZM4.00024 3V2H12.0002V14H4.00024V13H6.00024V12H4.00024V10H8.00024V9H4.00024V7H6.00024V6H4.00024V4H8.00024V3H4.00024Z" fill="#424242"/>
+</svg>
diff --git a/elpa/company-20220425.1145/icons/vscode-light/symbol-snippet.svg b/elpa/company-20220425.1145/icons/vscode-light/symbol-snippet.svg
new file mode 100644
index 0000000..ebb8a11
--- /dev/null
+++ b/elpa/company-20220425.1145/icons/vscode-light/symbol-snippet.svg
@@ -0,0 +1,3 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M2.50024 1L2.00024 1.5V13H3.00024V2H14.0002V13H15.0002V1.5L14.5002 1H2.50024ZM2.00024 15V14H3.00024V15H2.00024ZM5.00024 14.0001H4.00024V15.0001H5.00024V14.0001ZM6.00024 14.0001H7.00024V15.0001H6.00024V14.0001ZM9.00024 14.0001H8.00024V15.0001H9.00024V14.0001ZM10.0002 14.0001H11.0002V15.0001H10.0002V14.0001ZM15.0002 15.0001V14.0001H14.0002V15.0001H15.0002ZM12.0002 14.0001H13.0002V15.0001H12.0002V14.0001Z" fill="#424242"/>
+</svg>
diff --git a/elpa/company-20220425.1145/icons/vscode-light/symbol-string.svg b/elpa/company-20220425.1145/icons/vscode-light/symbol-string.svg
new file mode 100644
index 0000000..2fabca5
--- /dev/null
+++ b/elpa/company-20220425.1145/icons/vscode-light/symbol-string.svg
@@ -0,0 +1,3 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M2.00024 2L1.00024 3V12L2.00024 13H14.0002L15.0002 12V3L14.0002 2H2.00024ZM2.00024 12V3H14.0002V12H2.00024ZM5.35585 8.93017H6.00024V7.22067C6.00024 6.40689 5.68559 6 5.05628 6C4.92122 6 4.77108 6.02421 4.60585 6.07263C4.44205 6.12104 4.31274 6.17691 4.21792 6.24022V6.90503C4.45499 6.70205 4.70499 6.60056 4.96792 6.60056C5.22941 6.60056 5.36016 6.75698 5.36016 7.06983L4.76102 7.17318C4.25384 7.25885 4.00024 7.57914 4.00024 8.13408C4.00024 8.39665 4.06131 8.60708 4.18343 8.76536C4.307 8.92179 4.47582 9 4.6899 9C4.98013 9 5.19924 8.83985 5.34723 8.51955H5.35585V8.93017ZM5.36016 7.57542V7.76816C5.36016 7.9432 5.31993 8.08845 5.23947 8.20391C5.15901 8.3175 5.05484 8.3743 4.92697 8.3743C4.83501 8.3743 4.76174 8.34264 4.70714 8.27933C4.65398 8.21415 4.6274 8.13128 4.6274 8.03073C4.6274 7.80912 4.73803 7.6797 4.9593 7.64246L5.36016 7.57542ZM7.60118 8.62622H7.59367V8.93511H7.00024V5H7.59367V6.67683H7.60118C7.74766 6.36708 7.95611 6.2122 8.22653 6.2122C8.47442 6.2122 8.66535 6.32987 8.7993 6.56522C8.93326 6.80056 9.00024 7.12243 9.00024 7.53082C9.00024 7.97383 8.922 8.32944 8.7655 8.59766C8.60901 8.86589 8.39993 9 8.13827 9C7.90165 9 7.72262 8.87541 7.60118 8.62622ZM7.58428 7.50487V7.77742C7.58428 7.94873 7.61996 8.09063 7.69132 8.20311C7.76269 8.3156 7.85408 8.37184 7.9655 8.37184C8.10071 8.37184 8.20525 8.30002 8.27912 8.15639C8.35423 8.01103 8.39179 7.80597 8.39179 7.54121C8.39179 7.32144 8.35736 7.15012 8.28851 7.02726C8.2209 6.90266 8.12387 6.84036 7.99743 6.84036C7.87849 6.84036 7.77959 6.9018 7.70071 7.02466C7.62309 7.14752 7.58428 7.30759 7.58428 7.50487ZM11.2619 9C11.5837 9 11.8298 8.94227 12.0002 8.82682V8.11732C11.8202 8.25512 11.6362 8.32402 11.4483 8.32402C11.2364 8.32402 11.0699 8.25233 10.9489 8.10894C10.8278 7.96369 10.7673 7.76443 10.7673 7.51117C10.7673 7.25047 10.8302 7.04656 10.956 6.89944C11.0835 6.75047 11.2555 6.67598 11.4722 6.67598C11.6665 6.67598 11.8425 6.74488 12.0002 6.88268V6.13408C11.8712 6.04469 11.6625 6 11.3742 6C10.9568 6 10.6231 6.1406 10.373 6.42179C10.1245 6.70112 10.0002 7.0838 10.0002 7.56983C10.0002 7.99069 10.1165 8.33426 10.3491 8.60056C10.5817 8.86685 10.8859 9 11.2619 9Z" fill="#424242"/>
+</svg>
diff --git a/elpa/company-20220425.1145/icons/vscode-light/symbol-structure.svg b/elpa/company-20220425.1145/icons/vscode-light/symbol-structure.svg
new file mode 100644
index 0000000..2b8c0d9
--- /dev/null
+++ b/elpa/company-20220425.1145/icons/vscode-light/symbol-structure.svg
@@ -0,0 +1,3 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M2.00024 2L1.00024 3V6L2.00024 7H14.0002L15.0002 6V3L14.0002 2H2.00024ZM2.00024 3H3.00024H13.0002H14.0002V4V5V6H13.0002H3.00024H2.00024V5V4V3ZM1.00024 10L2.00024 9H5.00024L6.00024 10V13L5.00024 14H2.00024L1.00024 13V10ZM3.00024 10H2.00024V11V12V13H3.00024H4.00024H5.00024V12V11V10H4.00024H3.00024ZM10.0002 10L11.0002 9H14.0002L15.0002 10V13L14.0002 14H11.0002L10.0002 13V10ZM12.0002 10H11.0002V11V12V13H12.0002H13.0002H14.0002V12V11V10H13.0002H12.0002Z" fill="#424242"/>
+</svg>
diff --git a/elpa/company-20220425.1145/icons/vscode-light/symbol-variable.svg b/elpa/company-20220425.1145/icons/vscode-light/symbol-variable.svg
new file mode 100644
index 0000000..3656d9e
--- /dev/null
+++ b/elpa/company-20220425.1145/icons/vscode-light/symbol-variable.svg
@@ -0,0 +1,3 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M2.00024 5H4.00024V4H1.50024L1.00024 4.5V12.5L1.50024 13H4.00024V12H2.00024V5ZM14.5002 4H12.0002V5H14.0002V12H12.0002V13H14.5002L15.0002 12.5V4.5L14.5002 4ZM11.7603 6.56995L12.0002 7V9.51001L11.7002 9.95996L7.2002 11.96H6.74023L4.24023 10.46L4.00024 10.03V7.53003L4.30029 7.06995L8.80029 5.06995H9.26025L11.7603 6.56995ZM5.00024 9.70996L6.50024 10.61V9.28003L5.00024 8.38V9.70996ZM5.5802 7.56006L7.03027 8.43005L10.4203 6.93005L8.97021 6.06006L5.5802 7.56006ZM7.53027 10.73L11.0303 9.17004V7.77002L7.53027 9.31995V10.73Z" fill="#007ACC"/>
+</svg>
diff --git a/elpa/company-20220425.1145/images/small/echo-meta.png b/elpa/company-20220425.1145/images/small/echo-meta.png
new file mode 100755
index 0000000..7f4f079
--- /dev/null
+++ b/elpa/company-20220425.1145/images/small/echo-meta.png
Binary files differ
diff --git a/elpa/company-20220425.1145/images/small/echo-qa.png b/elpa/company-20220425.1145/images/small/echo-qa.png
new file mode 100755
index 0000000..8d924a7
--- /dev/null
+++ b/elpa/company-20220425.1145/images/small/echo-qa.png
Binary files differ
diff --git a/elpa/company-20220425.1145/images/small/echo-strip-qa.png b/elpa/company-20220425.1145/images/small/echo-strip-qa.png
new file mode 100755
index 0000000..3a4b986
--- /dev/null
+++ b/elpa/company-20220425.1145/images/small/echo-strip-qa.png
Binary files differ
diff --git a/elpa/company-20220425.1145/images/small/echo-strip.png b/elpa/company-20220425.1145/images/small/echo-strip.png
new file mode 100755
index 0000000..7909842
--- /dev/null
+++ b/elpa/company-20220425.1145/images/small/echo-strip.png
Binary files differ
diff --git a/elpa/company-20220425.1145/images/small/echo.png b/elpa/company-20220425.1145/images/small/echo.png
new file mode 100755
index 0000000..5150239
--- /dev/null
+++ b/elpa/company-20220425.1145/images/small/echo.png
Binary files differ
diff --git a/elpa/company-20220425.1145/images/small/preview-dark.png b/elpa/company-20220425.1145/images/small/preview-dark.png
new file mode 100755
index 0000000..80c1701
--- /dev/null
+++ b/elpa/company-20220425.1145/images/small/preview-dark.png
Binary files differ
diff --git a/elpa/company-20220425.1145/images/small/preview-light.png b/elpa/company-20220425.1145/images/small/preview-light.png
new file mode 100755
index 0000000..eb93189
--- /dev/null
+++ b/elpa/company-20220425.1145/images/small/preview-light.png
Binary files differ
diff --git a/elpa/company-20220425.1145/images/small/tooltip-annotations.png b/elpa/company-20220425.1145/images/small/tooltip-annotations.png
new file mode 100755
index 0000000..0a75fe8
--- /dev/null
+++ b/elpa/company-20220425.1145/images/small/tooltip-annotations.png
Binary files differ
diff --git a/elpa/company-20220425.1145/images/small/tooltip-faces-light.png b/elpa/company-20220425.1145/images/small/tooltip-faces-light.png
new file mode 100755
index 0000000..165ba68
--- /dev/null
+++ b/elpa/company-20220425.1145/images/small/tooltip-faces-light.png
Binary files differ
diff --git a/elpa/company-20220425.1145/images/small/tooltip-filter.png b/elpa/company-20220425.1145/images/small/tooltip-filter.png
new file mode 100755
index 0000000..a2a873d
--- /dev/null
+++ b/elpa/company-20220425.1145/images/small/tooltip-filter.png
Binary files differ
diff --git a/elpa/company-20220425.1145/images/small/tooltip-flip.png b/elpa/company-20220425.1145/images/small/tooltip-flip.png
new file mode 100755
index 0000000..16d1f60
--- /dev/null
+++ b/elpa/company-20220425.1145/images/small/tooltip-flip.png
Binary files differ
diff --git a/elpa/company-20220425.1145/images/small/tooltip-icon-bg.png b/elpa/company-20220425.1145/images/small/tooltip-icon-bg.png
new file mode 100755
index 0000000..57114cf
--- /dev/null
+++ b/elpa/company-20220425.1145/images/small/tooltip-icon-bg.png
Binary files differ
diff --git a/elpa/company-20220425.1145/images/small/tooltip-icon-face.png b/elpa/company-20220425.1145/images/small/tooltip-icon-face.png
new file mode 100755
index 0000000..dcf2c9d
--- /dev/null
+++ b/elpa/company-20220425.1145/images/small/tooltip-icon-face.png
Binary files differ
diff --git a/elpa/company-20220425.1145/images/small/tooltip-icons-dot.png b/elpa/company-20220425.1145/images/small/tooltip-icons-dot.png
new file mode 100755
index 0000000..b27d270
--- /dev/null
+++ b/elpa/company-20220425.1145/images/small/tooltip-icons-dot.png
Binary files differ
diff --git a/elpa/company-20220425.1145/images/small/tooltip-icons-text.png b/elpa/company-20220425.1145/images/small/tooltip-icons-text.png
new file mode 100755
index 0000000..c2dfc19
--- /dev/null
+++ b/elpa/company-20220425.1145/images/small/tooltip-icons-text.png
Binary files differ
diff --git a/elpa/company-20220425.1145/images/small/tooltip-icons-vscode.png b/elpa/company-20220425.1145/images/small/tooltip-icons-vscode.png
new file mode 100755
index 0000000..55acda1
--- /dev/null
+++ b/elpa/company-20220425.1145/images/small/tooltip-icons-vscode.png
Binary files differ
diff --git a/elpa/company-20220425.1145/images/small/tooltip-limit.png b/elpa/company-20220425.1145/images/small/tooltip-limit.png
new file mode 100755
index 0000000..e52630d
--- /dev/null
+++ b/elpa/company-20220425.1145/images/small/tooltip-limit.png
Binary files differ
diff --git a/elpa/company-20220425.1145/images/small/tooltip-margin.png b/elpa/company-20220425.1145/images/small/tooltip-margin.png
new file mode 100755
index 0000000..dd440ce
--- /dev/null
+++ b/elpa/company-20220425.1145/images/small/tooltip-margin.png
Binary files differ
diff --git a/elpa/company-20220425.1145/images/small/tooltip-minimum-above.png b/elpa/company-20220425.1145/images/small/tooltip-minimum-above.png
new file mode 100644
index 0000000..0052ca5
--- /dev/null
+++ b/elpa/company-20220425.1145/images/small/tooltip-minimum-above.png
Binary files differ
diff --git a/elpa/company-20220425.1145/images/small/tooltip-minimum-below.png b/elpa/company-20220425.1145/images/small/tooltip-minimum-below.png
new file mode 100644
index 0000000..c7b3f19
--- /dev/null
+++ b/elpa/company-20220425.1145/images/small/tooltip-minimum-below.png
Binary files differ
diff --git a/elpa/company-20220425.1145/images/small/tooltip-offset-display.png b/elpa/company-20220425.1145/images/small/tooltip-offset-display.png
new file mode 100755
index 0000000..c70276c
--- /dev/null
+++ b/elpa/company-20220425.1145/images/small/tooltip-offset-display.png
Binary files differ
diff --git a/elpa/company-20220425.1145/images/small/tooltip-qa-faces-light.png b/elpa/company-20220425.1145/images/small/tooltip-qa-faces-light.png
new file mode 100755
index 0000000..d089a56
--- /dev/null
+++ b/elpa/company-20220425.1145/images/small/tooltip-qa-faces-light.png
Binary files differ
diff --git a/elpa/company-20220425.1145/images/small/tooltip-quick-access.png b/elpa/company-20220425.1145/images/small/tooltip-quick-access.png
new file mode 100755
index 0000000..f675cb0
--- /dev/null
+++ b/elpa/company-20220425.1145/images/small/tooltip-quick-access.png
Binary files differ
diff --git a/elpa/company-20220425.1145/images/small/tooltip-search.png b/elpa/company-20220425.1145/images/small/tooltip-search.png
new file mode 100755
index 0000000..eda6726
--- /dev/null
+++ b/elpa/company-20220425.1145/images/small/tooltip-search.png
Binary files differ
diff --git a/elpa/compat-28.1.1.0.signed b/elpa/compat-28.1.1.0.signed
new file mode 100644
index 0000000..672aa68
--- /dev/null
+++ b/elpa/compat-28.1.1.0.signed
@@ -0,0 +1 @@
+Good signature from 066DAFCB81E42C40 GNU ELPA Signing Agent (2019) <elpasign@elpa.gnu.org> (trust undefined) created at 2022-04-23T02:35:01+0530 using RSA \ No newline at end of file
diff --git a/elpa/compat-28.1.1.0/NEWS.org b/elpa/compat-28.1.1.0/NEWS.org
new file mode 100644
index 0000000..ef9263c
--- /dev/null
+++ b/elpa/compat-28.1.1.0/NEWS.org
@@ -0,0 +1,40 @@
+* Release of "Compat" Version 28.1.1.0
+
+This release mostly fixes a number of smaller bugs that were not
+identified as of 28.1.0.0. Nevertheless these warrent a version bump,
+as some of these changes a functional. These include:
+
+- The addition of the =file-attribute-*= accessor functions.
+- The addition of =file-attribute-collect=.
+- Improvements to the Texinfo manual (via Jonas Bernoulli's recent
+ work on =ox-texinfo=). For the time being, the Texinfo file is
+ maintained in the repository itself, next to the =MANUAL= file.
+ This might change in the future.
+- Adding a prefix to =string-trim=, =string-trim-left= and
+ =string-trim-right= (i.e. now =compat-string-trim=,
+ =compat-string-trim-left= and =compat-string-trim-right=)
+- Improving the version inference used in the =compat-*= macros.
+ This improves the compile-time optimisation that strips away
+ functions that are known to be defined for a specific version.
+- The addition of generalised variable (=setf=) support for
+ =compat-alist-get=.
+- The addition of =image-property= and generalised variable support
+ for =image-property=.
+- The addition of the function =compat-executable-find=.
+- The addition of the function =compat-dired-get-marked-files=.
+- The addition of the function =exec-path=.
+- The addition of the function =make-lock-file-name=.
+- The addition of the function =null-device=.
+- The addition of the function =time-equal-p=.
+- The addition of the function =date-days-in-month=.
+- Handling out-of-directory byte compilation better.
+- Fixing the usage and edge-cases of =and-let*=.
+
+Furthermore a bug tracker was added: https://todo.sr.ht/~pkal/compat,
+which is the preferred way to report issues or feature requests.
+General problems, questions, etc. are still better discussed on the
+development mailing list: https://lists.sr.ht/~pkal/compat-devel.
+
+(Released <2022-04-22 Fri>)
+
+
diff --git a/elpa/compat-28.1.1.0/compat-24.el b/elpa/compat-28.1.1.0/compat-24.el
new file mode 100644
index 0000000..a4beccb
--- /dev/null
+++ b/elpa/compat-28.1.1.0/compat-24.el
@@ -0,0 +1,516 @@
+;;; compat-24.el --- Compatibility Layer for Emacs 24.4 -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2021, 2022 Free Software Foundation, Inc.
+
+;; Author: Philip Kaludercic <philipk@posteo.net>
+;; Maintainer: Compat Development <~pkal/compat-devel@lists.sr.ht>
+;; URL: https://git.sr.ht/~pkal/compat/
+;; Keywords: lisp
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Find here the functionality added in Emacs 24.4, needed by older
+;; versions.
+;;
+;; Do NOT load this library manually. Instead require `compat'.
+
+;;; Code:
+
+(eval-when-compile (require 'compat-macs))
+
+;;;; Defined in data.c
+
+(compat-defun = (number-or-marker &rest numbers-or-markers)
+ "Handle multiple arguments."
+ :version "24.4"
+ :prefix t
+ (catch 'fail
+ (while numbers-or-markers
+ (unless (= number-or-marker (car numbers-or-markers))
+ (throw 'fail nil))
+ (setq number-or-marker (pop numbers-or-markers)))
+ t))
+
+(compat-defun < (number-or-marker &rest numbers-or-markers)
+ "Handle multiple arguments."
+ :version "24.4"
+ :prefix t
+ (catch 'fail
+ (while numbers-or-markers
+ (unless (< number-or-marker (car numbers-or-markers))
+ (throw 'fail nil))
+ (setq number-or-marker (pop numbers-or-markers)))
+ t))
+
+(compat-defun > (number-or-marker &rest numbers-or-markers)
+ "Handle multiple arguments."
+ :version "24.4"
+ :prefix t
+ (catch 'fail
+ (while numbers-or-markers
+ (unless (> number-or-marker (car numbers-or-markers))
+ (throw 'fail nil))
+ (setq number-or-marker (pop numbers-or-markers)))
+ t))
+
+(compat-defun <= (number-or-marker &rest numbers-or-markers)
+ "Handle multiple arguments."
+ :version "24.4"
+ :prefix t
+ (catch 'fail
+ (while numbers-or-markers
+ (unless (<= number-or-marker (car numbers-or-markers))
+ (throw 'fail nil))
+ (setq number-or-marker (pop numbers-or-markers)))
+ t))
+
+(compat-defun >= (number-or-marker &rest numbers-or-markers)
+ "Handle multiple arguments."
+ :version "24.4"
+ :prefix t
+ (catch 'fail
+ (while numbers-or-markers
+ (unless (>= number-or-marker (pop numbers-or-markers))
+ (throw 'fail nil)))
+ t))
+
+(compat-defun bool-vector-exclusive-or (a b &optional c)
+ "Return A ^ B, bitwise exclusive or.
+If optional third argument C is given, store result into C.
+A, B, and C must be bool vectors of the same length.
+Return the destination vector if it changed or nil otherwise."
+ :version "24.4"
+ (unless (bool-vector-p a)
+ (signal 'wrong-type-argument (list 'bool-vector-p a)))
+ (unless (bool-vector-p b)
+ (signal 'wrong-type-argument (list 'bool-vector-p b)))
+ (unless (or (null c) (bool-vector-p c))
+ (signal 'wrong-type-argument (list 'bool-vector-p c)))
+ (when (/= (length a) (length b))
+ (signal 'wrong-length-argument (list (length a) (length b))))
+ (let ((dest (or c (make-bool-vector (length a) nil))) changed)
+ (when (/= (length a) (length dest))
+ (signal 'wrong-length-argument (list (length a) (length dest))))
+ (dotimes (i (length dest))
+ (let ((val (not (eq (aref a i) (aref b i)))))
+ (unless (eq val (aref dest i))
+ (setq changed t))
+ (aset dest i val)))
+ (if c (and changed c) dest)))
+
+(compat-defun bool-vector-union (a b &optional c)
+ "Return A | B, bitwise or.
+If optional third argument C is given, store result into C.
+A, B, and C must be bool vectors of the same length.
+Return the destination vector if it changed or nil otherwise."
+ :version "24.4"
+ (unless (bool-vector-p a)
+ (signal 'wrong-type-argument (list 'bool-vector-p a)))
+ (unless (bool-vector-p b)
+ (signal 'wrong-type-argument (list 'bool-vector-p b)))
+ (unless (or (null c) (bool-vector-p c))
+ (signal 'wrong-type-argument (list 'bool-vector-p c)))
+ (when (/= (length a) (length b))
+ (signal 'wrong-length-argument (list (length a) (length b))))
+ (let ((dest (or c (make-bool-vector (length a) nil))) changed)
+ (when (/= (length a) (length dest))
+ (signal 'wrong-length-argument (list (length a) (length dest))))
+ (dotimes (i (length dest))
+ (let ((val (or (aref a i) (aref b i))))
+ (unless (eq val (aref dest i))
+ (setq changed t))
+ (aset dest i val)))
+ (if c (and changed c) dest)))
+
+(compat-defun bool-vector-intersection (a b &optional c)
+ "Return A & B, bitwise and.
+If optional third argument C is given, store result into C.
+A, B, and C must be bool vectors of the same length.
+Return the destination vector if it changed or nil otherwise."
+ :version "24.4"
+ (unless (bool-vector-p a)
+ (signal 'wrong-type-argument (list 'bool-vector-p a)))
+ (unless (bool-vector-p b)
+ (signal 'wrong-type-argument (list 'bool-vector-p b)))
+ (unless (or (null c) (bool-vector-p c))
+ (signal 'wrong-type-argument (list 'bool-vector-p c)))
+ (when (/= (length a) (length b))
+ (signal 'wrong-length-argument (list (length a) (length b))))
+ (let ((dest (or c (make-bool-vector (length a) nil))) changed)
+ (when (/= (length a) (length dest))
+ (signal 'wrong-length-argument (list (length a) (length dest))))
+ (dotimes (i (length dest))
+ (let ((val (and (aref a i) (aref b i))))
+ (unless (eq val (aref dest i))
+ (setq changed t))
+ (aset dest i val)))
+ (if c (and changed c) dest)))
+
+(compat-defun bool-vector-set-difference (a b &optional c)
+ "Return A &~ B, set difference.
+If optional third argument C is given, store result into C.
+A, B, and C must be bool vectors of the same length.
+Return the destination vector if it changed or nil otherwise."
+ :version "24.4"
+ (unless (bool-vector-p a)
+ (signal 'wrong-type-argument (list 'bool-vector-p a)))
+ (unless (bool-vector-p b)
+ (signal 'wrong-type-argument (list 'bool-vector-p b)))
+ (unless (or (null c) (bool-vector-p c))
+ (signal 'wrong-type-argument (list 'bool-vector-p c)))
+ (when (/= (length a) (length b))
+ (signal 'wrong-length-argument (list (length a) (length b))))
+ (let ((dest (or c (make-bool-vector (length a) nil))) changed)
+ (when (/= (length a) (length dest))
+ (signal 'wrong-length-argument (list (length a) (length dest))))
+ (dotimes (i (length dest))
+ (let ((val (and (aref a i) (not (aref b i)))))
+ (unless (eq val (aref dest i))
+ (setq changed t))
+ (aset dest i val)))
+ (if c (and changed c) dest)))
+
+(compat-defun bool-vector-not (a &optional b)
+ "Compute ~A, set complement.
+If optional second argument B is given, store result into B.
+A and B must be bool vectors of the same length.
+Return the destination vector."
+ :version "24.4"
+ (unless (bool-vector-p a)
+ (signal 'wrong-type-argument (list 'bool-vector-p a)))
+ (unless (or (null b) (bool-vector-p b))
+ (signal 'wrong-type-argument (list 'bool-vector-p b)))
+ (let ((dest (or b (make-bool-vector (length a) nil))))
+ (when (/= (length a) (length dest))
+ (signal 'wrong-length-argument (list (length a) (length dest))))
+ (dotimes (i (length dest))
+ (aset dest i (not (aref a i))))
+ dest))
+
+(compat-defun bool-vector-subsetp (a b)
+ "Return t if every t value in A is also t in B, nil otherwise.
+A and B must be bool vectors of the same length."
+ :version "24.4"
+ (unless (bool-vector-p a)
+ (signal 'wrong-type-argument (list 'bool-vector-p a)))
+ (unless (bool-vector-p b)
+ (signal 'wrong-type-argument (list 'bool-vector-p b)))
+ (when (/= (length a) (length b))
+ (signal 'wrong-length-argument (list (length a) (length b))))
+ (catch 'not-subset
+ (dotimes (i (length a))
+ (when (if (aref a i) (not (aref b i)) nil)
+ (throw 'not-subset nil)))
+ t))
+
+(compat-defun bool-vector-count-consecutive (a b i)
+ "Count how many consecutive elements in A equal B starting at I.
+A is a bool vector, B is t or nil, and I is an index into A."
+ :version "24.4"
+ (unless (bool-vector-p a)
+ (signal 'wrong-type-argument (list 'bool-vector-p a)))
+ (setq b (and b t)) ;normalise to nil or t
+ (unless (< i (length a))
+ (signal 'args-out-of-range (list a i)))
+ (let ((len (length a)) (n i))
+ (while (and (< i len) (eq (aref a i) b))
+ (setq i (1+ i)))
+ (- i n)))
+
+(compat-defun bool-vector-count-population (a)
+ "Count how many elements in A are t.
+A is a bool vector. To count A's nil elements, subtract the
+return value from A's length."
+ :version "24.4"
+ (unless (bool-vector-p a)
+ (signal 'wrong-type-argument (list 'bool-vector-p a)))
+ (let ((n 0))
+ (dotimes (i (length a))
+ (when (aref a i)
+ (setq n (1+ n))))
+ n))
+
+;;;; Defined in subr.el
+
+;;* UNTESTED
+(compat-defmacro with-eval-after-load (file &rest body)
+ "Execute BODY after FILE is loaded.
+FILE is normally a feature name, but it can also be a file name,
+in case that file does not provide any feature. See `eval-after-load'
+for more details about the different forms of FILE and their semantics."
+ :version "24.4"
+ (declare (indent 1) (debug (form def-body)))
+ ;; See https://nullprogram.com/blog/2018/02/22/ on how
+ ;; `eval-after-load' is used to preserve compatibility with 24.3.
+ `(eval-after-load ,file `(funcall ',,`(lambda () ,@body))))
+
+(compat-defun special-form-p (object)
+ "Non-nil if and only if OBJECT is a special form."
+ :version "24.4"
+ (if (and (symbolp object) (fboundp object))
+ (setq object (condition-case nil
+ (indirect-function object)
+ (void-function nil))))
+ (and (subrp object) (eq (cdr (subr-arity object)) 'unevalled)))
+
+(compat-defun macrop (object)
+ "Non-nil if and only if OBJECT is a macro."
+ :version "24.4"
+ (let ((def (condition-case nil
+ (indirect-function object)
+ (void-function nil))))
+ (when (consp def)
+ (or (eq 'macro (car def))
+ (and (autoloadp def) (memq (nth 4 def) '(macro t)))))))
+
+(compat-defun string-suffix-p (suffix string &optional ignore-case)
+ "Return non-nil if SUFFIX is a suffix of STRING.
+If IGNORE-CASE is non-nil, the comparison is done without paying
+attention to case differences."
+ :version "24.4"
+ (let ((start-pos (- (length string) (length suffix))))
+ (and (>= start-pos 0)
+ (eq t (compare-strings suffix nil nil
+ string start-pos nil ignore-case)))))
+
+(compat-defun split-string (string &optional separators omit-nulls trim)
+ "Extend `split-string' by a TRIM argument.
+The remaining arguments STRING, SEPARATORS and OMIT-NULLS are
+handled just as with `split-string'."
+ :version "24.4"
+ :prefix t
+ (let* ((token (split-string string separators omit-nulls))
+ (trimmed (if trim
+ (mapcar
+ (lambda (token)
+ (when (string-match (concat "\\`" trim) token)
+ (setq token (substring token (match-end 0))))
+ (when (string-match (concat trim "\\'") token)
+ (setq token (substring token 0 (match-beginning 0))))
+ token)
+ token)
+ token)))
+ (if omit-nulls (delete "" trimmed) trimmed)))
+
+(compat-defun delete-consecutive-dups (list &optional circular)
+ "Destructively remove `equal' consecutive duplicates from LIST.
+First and last elements are considered consecutive if CIRCULAR is
+non-nil."
+ :version "24.4"
+ (let ((tail list) last)
+ (while (cdr tail)
+ (if (equal (car tail) (cadr tail))
+ (setcdr tail (cddr tail))
+ (setq last tail
+ tail (cdr tail))))
+ (if (and circular
+ last
+ (equal (car tail) (car list)))
+ (setcdr last nil)))
+ list)
+
+;;* UNTESTED
+(compat-defun define-error (name message &optional parent)
+ "Define NAME as a new error signal.
+MESSAGE is a string that will be output to the echo area if such an error
+is signaled without being caught by a `condition-case'.
+PARENT is either a signal or a list of signals from which it inherits.
+Defaults to `error'."
+ :version "24.4"
+ (unless parent (setq parent 'error))
+ (let ((conditions
+ (if (consp parent)
+ (apply #'append
+ (mapcar (lambda (parent)
+ (cons parent
+ (or (get parent 'error-conditions)
+ (error "Unknown signal `%s'" parent))))
+ parent))
+ (cons parent (get parent 'error-conditions)))))
+ (put name 'error-conditions
+ (delete-dups (copy-sequence (cons name conditions))))
+ (when message (put name 'error-message message))))
+
+;;;; Defined in minibuffer.el
+
+;;* UNTESTED
+(compat-defun completion-table-with-cache (fun &optional ignore-case)
+ "Create dynamic completion table from function FUN, with cache.
+This is a wrapper for `completion-table-dynamic' that saves the last
+argument-result pair from FUN, so that several lookups with the
+same argument (or with an argument that starts with the first one)
+only need to call FUN once. This can be useful when FUN performs a
+relatively slow operation, such as calling an external process.
+
+When IGNORE-CASE is non-nil, FUN is expected to be case-insensitive."
+ :version "24.4"
+ (let* (last-arg last-result
+ (new-fun
+ (lambda (arg)
+ (if (and last-arg (string-prefix-p last-arg arg ignore-case))
+ last-result
+ (prog1
+ (setq last-result (funcall fun arg))
+ (setq last-arg arg))))))
+ (completion-table-dynamic new-fun)))
+
+;;* UNTESTED
+(compat-defun completion-table-merge (&rest tables)
+ "Create a completion table that collects completions from all TABLES."
+ :version "24.4"
+ (lambda (string pred action)
+ (cond
+ ((null action)
+ (let ((retvals (mapcar (lambda (table)
+ (try-completion string table pred))
+ tables)))
+ (if (member string retvals)
+ string
+ (try-completion string
+ (mapcar (lambda (value)
+ (if (eq value t) string value))
+ (delq nil retvals))
+ pred))))
+ ((eq action t)
+ (apply #'append (mapcar (lambda (table)
+ (all-completions string table pred))
+ tables)))
+ (t
+ (completion--some (lambda (table)
+ (complete-with-action action table string pred))
+ tables)))))
+
+;;;; Defined in subr-x.el
+
+;;* UNTESTED
+(compat-advise require (feature &rest args)
+ "Allow for Emacs 24.x to require the inexistent FEATURE subr-x."
+ :version "24.4"
+ ;; As the compatibility advise around `require` is more a hack than
+ ;; of of actual value, the highlighting is suppressed.
+ :no-highlight t
+ (if (eq feature 'subr-x)
+ (let ((entry (assq feature after-load-alist)))
+ (let ((load-file-name nil))
+ (dolist (form (cdr entry))
+ (funcall (eval form t)))))
+ (apply oldfun feature args)))
+
+(compat-defun hash-table-keys (hash-table)
+ "Return a list of keys in HASH-TABLE."
+ :version "24.4"
+ (let (values)
+ (maphash
+ (lambda (k _v) (push k values))
+ hash-table)
+ values))
+
+(compat-defun hash-table-values (hash-table)
+ "Return a list of values in HASH-TABLE."
+ :version "24.4"
+ (let (values)
+ (maphash
+ (lambda (_k v) (push v values))
+ hash-table)
+ values))
+
+(compat-defun string-empty-p (string)
+ "Check whether STRING is empty."
+ :version "24.4"
+ (string= string ""))
+
+(compat-defun string-join (strings &optional separator)
+ "Join all STRINGS using SEPARATOR.
+Optional argument SEPARATOR must be a string, a vector, or a list of
+characters; nil stands for the empty string."
+ :version "24.4"
+ (mapconcat #'identity strings separator))
+
+(compat-defun string-blank-p (string)
+ "Check whether STRING is either empty or only whitespace.
+The following characters count as whitespace here: space, tab, newline and
+carriage return."
+ :version "24.4"
+ (string-match-p "\\`[ \t\n\r]*\\'" string))
+
+(compat-defun string-remove-prefix (prefix string)
+ "Remove PREFIX from STRING if present."
+ :version "24.4"
+ (if (string-prefix-p prefix string)
+ (substring string (length prefix))
+ string))
+
+(compat-defun string-remove-suffix (suffix string)
+ "Remove SUFFIX from STRING if present."
+ :version "24.4"
+ (if (string-suffix-p suffix string)
+ (substring string 0 (- (length string) (length suffix)))
+ string))
+
+;;;; Defined in faces.el
+
+;;* UNTESTED
+(compat-defun face-spec-set (face spec &optional spec-type)
+ "Set the FACE's spec SPEC, define FACE, and recalculate its attributes.
+See `defface' for the format of SPEC.
+
+The appearance of each face is controlled by its specs (set via
+this function), and by the internal frame-specific face
+attributes (set via `set-face-attribute').
+
+This function also defines FACE as a valid face name if it is not
+already one, and (re)calculates its attributes on existing
+frames.
+
+The optional argument SPEC-TYPE determines which spec to set:
+ nil, omitted or `face-override-spec' means the override spec,
+ which overrides all the other types of spec mentioned below
+ (this is usually what you want if calling this function
+ outside of Custom code);
+ `customized-face' or `saved-face' means the customized spec or
+ the saved custom spec;
+ `face-defface-spec' means the default spec
+ (usually set only via `defface');
+ `reset' means to ignore SPEC, but clear the `customized-face'
+ and `face-override-spec' specs;
+Any other value means not to set any spec, but to run the
+function for defining FACE and recalculating its attributes."
+ :version "24.4"
+ (if (get face 'face-alias)
+ (setq face (get face 'face-alias)))
+ ;; Save SPEC to the relevant symbol property.
+ (unless spec-type
+ (setq spec-type 'face-override-spec))
+ (if (memq spec-type '(face-defface-spec face-override-spec
+ customized-face saved-face))
+ (put face spec-type spec))
+ (if (memq spec-type '(reset saved-face))
+ (put face 'customized-face nil))
+ ;; Setting the face spec via Custom empties out any override spec,
+ ;; similar to how setting a variable via Custom changes its values.
+ (if (memq spec-type '(customized-face saved-face reset))
+ (put face 'face-override-spec nil))
+ ;; If we reset the face based on its custom spec, it is unmodified
+ ;; as far as Custom is concerned.
+ (unless (eq face 'face-override-spec)
+ (put face 'face-modified nil))
+ ;; Initialize the face if it does not exist, then recalculate.
+ (make-empty-face face)
+ (dolist (frame (frame-list))
+ (face-spec-recalc face frame)))
+
+(provide 'compat-24)
+;;; compat-24.el ends here
diff --git a/elpa/compat-28.1.1.0/compat-24.elc b/elpa/compat-28.1.1.0/compat-24.elc
new file mode 100644
index 0000000..aa6c65c
--- /dev/null
+++ b/elpa/compat-28.1.1.0/compat-24.elc
Binary files differ
diff --git a/elpa/compat-28.1.1.0/compat-25.el b/elpa/compat-28.1.1.0/compat-25.el
new file mode 100644
index 0000000..d31b133
--- /dev/null
+++ b/elpa/compat-28.1.1.0/compat-25.el
@@ -0,0 +1,317 @@
+;;; compat-25.el --- Compatibility Layer for Emacs 25.1 -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2021, 2022 Free Software Foundation, Inc.
+
+;; Author: Philip Kaludercic <philipk@posteo.net>
+;; Maintainer: Compat Development <~pkal/compat-devel@lists.sr.ht>
+;; URL: https://git.sr.ht/~pkal/compat/
+;; Keywords: lisp
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Find here the functionality added in Emacs 25.1, needed by older
+;; versions.
+;;
+;; Do NOT load this library manually. Instead require `compat'.
+
+;;; Code:
+
+(eval-when-compile (require 'compat-macs))
+
+;;;; Defined in alloc.c
+
+(compat-defun bool-vector (&rest objects)
+ "Return a new bool-vector with specified arguments as elements.
+Allows any number of arguments, including zero.
+usage: (bool-vector &rest OBJECTS)"
+ (let ((vec (make-bool-vector (length objects) nil))
+ (i 0))
+ (while objects
+ (when (car objects)
+ (aset vec i t))
+ (setq objects (cdr objects)
+ i (1+ i)))
+ vec))
+
+;;;; Defined in fns.c
+
+(compat-defun sort (seq predicate)
+ "Extend `sort' to sort SEQ as a vector."
+ :prefix t
+ (cond
+ ((listp seq)
+ (sort seq predicate))
+ ((vectorp seq)
+ (let ((cseq (sort (append seq nil) predicate)))
+ (dotimes (i (length cseq))
+ (setf (aref seq i) (nth i cseq)))
+ (apply #'vector cseq)))
+ ((signal 'wrong-type-argument 'list-or-vector-p))))
+
+;;;; Defined in editfns.c
+
+(compat-defun format-message (string &rest objects)
+ "Format a string out of a format-string and arguments.
+The first argument is a format control string.
+The other arguments are substituted into it to make the result, a string.
+
+This implementation is equivalent to `format'."
+ (apply #'format string objects))
+
+;;;; Defined in minibuf.c
+
+;; TODO advise read-buffer to handle 4th argument
+
+;;;; Defined in fileio.c
+
+(compat-defun directory-name-p (name)
+ "Return non-nil if NAME ends with a directory separator character."
+ :realname compat--directory-name-p
+ (eq (eval-when-compile
+ (if (memq system-type '(cygwin windows-nt ms-dos))
+ ?\\ ?/))
+ (aref name (1- (length name)))))
+
+;;;; Defined in subr.el
+
+(compat-defun string-greaterp (string1 string2)
+ "Return non-nil if STRING1 is greater than STRING2 in lexicographic order.
+Case is significant.
+Symbols are also allowed; their print names are used instead."
+ (string-lessp string2 string1))
+
+;;* UNTESTED
+(compat-defmacro with-file-modes (modes &rest body)
+ "Execute BODY with default file permissions temporarily set to MODES.
+MODES is as for `set-default-file-modes'."
+ (declare (indent 1) (debug t))
+ (let ((umask (make-symbol "umask")))
+ `(let ((,umask (default-file-modes)))
+ (unwind-protect
+ (progn
+ (set-default-file-modes ,modes)
+ ,@body)
+ (set-default-file-modes ,umask)))))
+
+(compat-defun alist-get (key alist &optional default remove testfn)
+ "Find the first element of ALIST whose `car' equals KEY and return its `cdr'.
+If KEY is not found in ALIST, return DEFAULT.
+Equality with KEY is tested by TESTFN, defaulting to `eq'."
+ :realname compat--alist-get-full-elisp
+ (ignore remove)
+ (let (entry)
+ (cond
+ ((or (null testfn) (eq testfn 'eq))
+ (setq entry (assq key alist)))
+ ((eq testfn 'equal)
+ (setq entry (assoc key alist)))
+ ((catch 'found
+ (dolist (ent alist)
+ (when (and (consp ent) (funcall testfn (car ent) key))
+ (throw 'found (setq entry ent))))
+ default)))
+ (if entry (cdr entry) default)))
+
+;;;; Defined in subr-x.el
+
+(compat-defmacro if-let (spec then &rest else)
+ "Bind variables according to SPEC and evaluate THEN or ELSE.
+Evaluate each binding in turn, as in `let*', stopping if a
+binding value is nil. If all are non-nil return the value of
+THEN, otherwise the last form in ELSE.
+
+Each element of SPEC is a list (SYMBOL VALUEFORM) that binds
+SYMBOL to the value of VALUEFORM. An element can additionally be
+of the form (VALUEFORM), which is evaluated and checked for nil;
+i.e. SYMBOL can be omitted if only the test result is of
+interest. It can also be of the form SYMBOL, then the binding of
+SYMBOL is checked for nil.
+
+As a special case, interprets a SPEC of the form \(SYMBOL SOMETHING)
+like \((SYMBOL SOMETHING)). This exists for backward compatibility
+with an old syntax that accepted only one binding."
+ :realname compat--if-let
+ :feature 'subr-x
+ (declare (indent 2)
+ (debug ([&or (symbolp form)
+ (&rest [&or symbolp (symbolp form) (form)])]
+ body)))
+ (when (and (<= (length spec) 2)
+ (not (listp (car spec))))
+ ;; Adjust the single binding case
+ (setq spec (list spec)))
+ `(compat--if-let* ,spec ,then ,(macroexp-progn else)))
+
+(compat-defmacro when-let (spec &rest body)
+ "Bind variables according to SPEC and conditionally evaluate BODY.
+Evaluate each binding in turn, stopping if a binding value is nil.
+If all are non-nil, return the value of the last form in BODY.
+
+The variable list SPEC is the same as in `if-let'."
+ :feature 'subr-x
+ (declare (indent 1) (debug if-let))
+ `(compat--if-let ,spec ,(macroexp-progn body)))
+
+(compat-defmacro thread-first (&rest forms)
+ "Thread FORMS elements as the first argument of their successor.
+Example:
+ (thread-first
+ 5
+ (+ 20)
+ (/ 25)
+ -
+ (+ 40))
+Is equivalent to:
+ (+ (- (/ (+ 5 20) 25)) 40)
+Note how the single `-' got converted into a list before
+threading."
+ :feature 'subr-x
+ (declare (indent 1)
+ (debug (form &rest [&or symbolp (sexp &rest form)])))
+ (let ((body (car forms)))
+ (dolist (form (cdr forms))
+ (when (symbolp form)
+ (setq form (list form)))
+ (setq body (append (list (car form))
+ (list body)
+ (cdr form))))
+ body))
+
+(compat-defmacro thread-last (&rest forms)
+ "Thread FORMS elements as the last argument of their successor.
+Example:
+ (thread-last
+ 5
+ (+ 20)
+ (/ 25)
+ -
+ (+ 40))
+Is equivalent to:
+ (+ 40 (- (/ 25 (+ 20 5))))
+Note how the single `-' got converted into a list before
+threading."
+ :feature 'subr-x
+ (declare (indent 1) (debug thread-first))
+ (let ((body (car forms)))
+ (dolist (form (cdr forms))
+ (when (symbolp form)
+ (setq form (list form)))
+ (setq body (append form (list body))))
+ body))
+
+;;;; Defined in macroexp.el
+
+(declare-function macrop nil (object))
+(compat-defun macroexpand-1 (form &optional environment)
+ "Perform (at most) one step of macro expansion."
+ :feature 'macroexp
+ (cond
+ ((consp form)
+ (let* ((head (car form))
+ (env-expander (assq head environment)))
+ (if env-expander
+ (if (cdr env-expander)
+ (apply (cdr env-expander) (cdr form))
+ form)
+ (if (not (and (symbolp head) (fboundp head)))
+ form
+ (let ((def (autoload-do-load (symbol-function head) head 'macro)))
+ (cond
+ ;; Follow alias, but only for macros, otherwise we may end up
+ ;; skipping an important compiler-macro (e.g. cl--block-wrapper).
+ ((and (symbolp def) (macrop def)) (cons def (cdr form)))
+ ((not (consp def)) form)
+ (t
+ (if (eq 'macro (car def))
+ (apply (cdr def) (cdr form))
+ form))))))))
+ (t form)))
+
+;;;; Defined in byte-run.el
+
+;;* UNTESTED
+(compat-defun function-put (func prop value)
+ "Set FUNCTION's property PROP to VALUE.
+The namespace for PROP is shared with symbols.
+So far, FUNCTION can only be a symbol, not a lambda expression."
+ :version "24.4"
+ (put func prop value))
+
+;;;; Defined in files.el
+
+;;* UNTESTED
+(compat-defun directory-files-recursively
+ (dir regexp &optional include-directories predicate follow-symlinks)
+ "Return list of all files under directory DIR whose names match REGEXP.
+This function works recursively. Files are returned in \"depth
+first\" order, and files from each directory are sorted in
+alphabetical order. Each file name appears in the returned list
+in its absolute form.
+
+By default, the returned list excludes directories, but if
+optional argument INCLUDE-DIRECTORIES is non-nil, they are
+included.
+
+PREDICATE can be either nil (which means that all subdirectories
+of DIR are descended into), t (which means that subdirectories that
+can't be read are ignored), or a function (which is called with
+the name of each subdirectory, and should return non-nil if the
+subdirectory is to be descended into).
+
+If FOLLOW-SYMLINKS is non-nil, symbolic links that point to
+directories are followed. Note that this can lead to infinite
+recursion."
+ :realname compat--directory-files-recursively
+ (let* ((result nil)
+ (files nil)
+ (dir (directory-file-name dir))
+ ;; When DIR is "/", remote file names like "/method:" could
+ ;; also be offered. We shall suppress them.
+ (tramp-mode (and tramp-mode (file-remote-p (expand-file-name dir)))))
+ (dolist (file (sort (file-name-all-completions "" dir)
+ 'string<))
+ (unless (member file '("./" "../"))
+ (if (directory-name-p file)
+ (let* ((leaf (substring file 0 (1- (length file))))
+ (full-file (concat dir "/" leaf)))
+ ;; Don't follow symlinks to other directories.
+ (when (and (or (not (file-symlink-p full-file))
+ (and (file-symlink-p full-file)
+ follow-symlinks))
+ ;; Allow filtering subdirectories.
+ (or (eq predicate nil)
+ (eq predicate t)
+ (funcall predicate full-file)))
+ (let ((sub-files
+ (if (eq predicate t)
+ (condition-case nil
+ (compat--directory-files-recursively
+ full-file regexp include-directories
+ predicate follow-symlinks)
+ (file-error nil))
+ (compat--directory-files-recursively
+ full-file regexp include-directories
+ predicate follow-symlinks))))
+ (setq result (nconc result sub-files))))
+ (when (and include-directories
+ (string-match regexp leaf))
+ (setq result (nconc result (list full-file)))))
+ (when (string-match regexp file)
+ (push (concat dir "/" file) files)))))
+ (nconc result (nreverse files))))
+
+(provide 'compat-25)
+;;; compat-25.el ends here
diff --git a/elpa/compat-28.1.1.0/compat-25.elc b/elpa/compat-28.1.1.0/compat-25.elc
new file mode 100644
index 0000000..03565d0
--- /dev/null
+++ b/elpa/compat-28.1.1.0/compat-25.elc
Binary files differ
diff --git a/elpa/compat-28.1.1.0/compat-26.el b/elpa/compat-28.1.1.0/compat-26.el
new file mode 100644
index 0000000..07ab3a4
--- /dev/null
+++ b/elpa/compat-28.1.1.0/compat-26.el
@@ -0,0 +1,623 @@
+;;; compat-26.el --- Compatibility Layer for Emacs 26.1 -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2021, 2022 Free Software Foundation, Inc.
+
+;; Author: Philip Kaludercic <philipk@posteo.net>
+;; Maintainer: Compat Development <~pkal/compat-devel@lists.sr.ht>
+;; URL: https://git.sr.ht/~pkal/compat/
+;; Keywords: lisp
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Find here the functionality added in Emacs 26.1, needed by older
+;; versions.
+;;
+;; Do NOT load this library manually. Instead require `compat'.
+
+;;; Code:
+
+(eval-when-compile (require 'compat-macs))
+(declare-function compat-func-arity "compat" (func))
+
+;;;; Defined in eval.c
+
+(compat-defun func-arity (func)
+ "Return minimum and maximum number of args allowed for FUNC.
+FUNC must be a function of some kind.
+The returned value is a cons cell (MIN . MAX). MIN is the minimum number
+of args. MAX is the maximum number, or the symbol ‘many’, for a
+function with ‘&rest’ args, or ‘unevalled’ for a special form."
+ :realname compat--func-arity
+ (cond
+ ((or (null func) (and (symbolp func) (not (fboundp func))))
+ (signal 'void-function func))
+ ((and (symbolp func) (not (null func)))
+ (compat--func-arity (symbol-function func)))
+ ((eq (car-safe func) 'macro)
+ (compat--func-arity (cdr func)))
+ ((subrp func)
+ (subr-arity func))
+ ((memq (car-safe func) '(closure lambda))
+ ;; See lambda_arity from eval.c
+ (when (eq (car func) 'closure)
+ (setq func (cdr func)))
+ (let ((syms-left (if (consp func)
+ (car func)
+ (signal 'invalid-function func)))
+ (min-args 0) (max-args 0) optional)
+ (catch 'many
+ (dolist (next syms-left)
+ (cond
+ ((not (symbolp next))
+ (signal 'invalid-function func))
+ ((eq next '&rest)
+ (throw 'many (cons min-args 'many)))
+ ((eq next '&optional)
+ (setq optional t))
+ (t (unless optional
+ (setq min-args (1+ min-args)))
+ (setq max-args (1+ max-args)))))
+ (cons min-args max-args))))
+ ((and (byte-code-function-p func) (numberp (aref func 0)))
+ ;; See get_byte_code_arity from bytecode.c
+ (let ((at (aref func 0)))
+ (cons (logand at 127)
+ (if (= (logand at 128) 0)
+ (ash at -8)
+ 'many))))
+ ((and (byte-code-function-p func) (numberp (aref func 0)))
+ ;; See get_byte_code_arity from bytecode.c
+ (let ((at (aref func 0)))
+ (cons (logand at 127)
+ (if (= (logand at 128) 0)
+ (ash at -8)
+ 'many))))
+ ((and (byte-code-function-p func) (listp (aref func 0)))
+ ;; Based on `byte-compile-make-args-desc', this is required for
+ ;; old versions of Emacs that don't use a integer for the argument
+ ;; list description, per e2abe5a13dffb08d6371b6a611bc39c3a9ac2bc6.
+ (let ((arglist (aref func 0)) (mandatory 0) nonrest)
+ (while (and arglist (not (memq (car arglist) '(&optional &rest))))
+ (setq mandatory (1+ mandatory))
+ (setq arglist (cdr arglist)))
+ (setq nonrest mandatory)
+ (when (eq (car arglist) '&optional)
+ (setq arglist (cdr arglist))
+ (while (and arglist (not (eq (car arglist) '&rest)))
+ (setq nonrest (1+ nonrest))
+ (setq arglist (cdr arglist))))
+ (cons mandatory (if arglist 'many nonrest))))
+ ((autoloadp func)
+ (autoload-do-load func)
+ (compat--func-arity func))
+ ((signal 'invalid-function func))))
+
+;;;; Defined in fns.c
+
+(compat-defun assoc (key alist &optional testfn)
+ "Handle the optional argument TESTFN.
+Equality is defined by the function TESTFN, defaulting to
+‘equal’. TESTFN is called with 2 arguments: a car of an alist
+element and KEY. With no optional argument, the function behaves
+just like `assoc'."
+ :prefix t
+ (if testfn
+ (catch 'found
+ (dolist (ent alist)
+ (when (funcall testfn (car ent) key)
+ (throw 'found ent))))
+ (assoc key alist)))
+
+(compat-defun mapcan (func sequence)
+ "Apply FUNC to each element of SEQUENCE.
+Concatenate the results by altering them (using `nconc').
+SEQUENCE may be a list, a vector, a boolean vector, or a string."
+ (apply #'nconc (mapcar func sequence)))
+
+;;* UNTESTED
+(compat-defun line-number-at-pos (&optional position absolute)
+ "Handle optional argument ABSOLUTE:
+
+If the buffer is narrowed, the return value by default counts the lines
+from the beginning of the accessible portion of the buffer. But if the
+second optional argument ABSOLUTE is non-nil, the value counts the lines
+from the absolute start of the buffer, disregarding the narrowing."
+ :prefix t
+ (if absolute
+ (save-restriction
+ (widen)
+ (line-number-at-pos position))
+ (line-number-at-pos position)))
+
+;;;; Defined in subr.el
+
+(declare-function compat--alist-get-full-elisp "compat-25"
+ (key alist &optional default remove testfn))
+(compat-defun alist-get (key alist &optional default remove testfn)
+ "Handle TESTFN manually."
+ :realname compat--alist-get-handle-testfn
+ :prefix t
+ (if testfn
+ (compat--alist-get-full-elisp key alist default remove testfn)
+ (alist-get key alist default remove)))
+
+(gv-define-expander compat-alist-get
+ (lambda (do key alist &optional default remove testfn)
+ (macroexp-let2 macroexp-copyable-p k key
+ (gv-letplace (getter setter) alist
+ (macroexp-let2 nil p `(if (and ,testfn (not (eq ,testfn 'eq)))
+ (compat-assoc ,k ,getter ,testfn)
+ (assq ,k ,getter))
+ (funcall do (if (null default) `(cdr ,p)
+ `(if ,p (cdr ,p) ,default))
+ (lambda (v)
+ (macroexp-let2 nil v v
+ (let ((set-exp
+ `(if ,p (setcdr ,p ,v)
+ ,(funcall setter
+ `(cons (setq ,p (cons ,k ,v))
+ ,getter)))))
+ `(progn
+ ,(cond
+ ((null remove) set-exp)
+ ((or (eql v default)
+ (and (eq (car-safe v) 'quote)
+ (eq (car-safe default) 'quote)
+ (eql (cadr v) (cadr default))))
+ `(if ,p ,(funcall setter `(delq ,p ,getter))))
+ (t
+ `(cond
+ ((not (eql ,default ,v)) ,set-exp)
+ (,p ,(funcall setter
+ `(delq ,p ,getter))))))
+ ,v))))))))))
+
+(compat-defun string-trim-left (string &optional regexp)
+ "Trim STRING of leading string matching REGEXP.
+
+REGEXP defaults to \"[ \\t\\n\\r]+\"."
+ :realname compat--string-trim-left
+ :prefix t
+ (if (string-match (concat "\\`\\(?:" (or regexp "[ \t\n\r]+") "\\)") string)
+ (substring string (match-end 0))
+ string))
+
+(compat-defun string-trim-right (string &optional regexp)
+ "Trim STRING of trailing string matching REGEXP.
+
+REGEXP defaults to \"[ \\t\\n\\r]+\"."
+ :realname compat--string-trim-right
+ :prefix t
+ (let ((i (string-match-p
+ (concat "\\(?:" (or regexp "[ \t\n\r]+") "\\)\\'")
+ string)))
+ (if i (substring string 0 i) string)))
+
+(compat-defun string-trim (string &optional trim-left trim-right)
+ "Trim STRING of leading with and trailing matching TRIM-LEFT and TRIM-RIGHT.
+
+TRIM-LEFT and TRIM-RIGHT default to \"[ \\t\\n\\r]+\"."
+ :prefix t
+ ;; `string-trim-left' and `string-trim-right' were moved from subr-x
+ ;; to subr in Emacs 27, so to avoid loading subr-x we use the
+ ;; compatibility function here:
+ (compat--string-trim-left
+ (compat--string-trim-right
+ string
+ trim-right)
+ trim-left))
+
+(compat-defun caaar (x)
+ "Return the `car' of the `car' of the `car' of X."
+ (declare (pure t))
+ (car (car (car x))))
+
+(compat-defun caadr (x)
+ "Return the `car' of the `car' of the `cdr' of X."
+ (declare (pure t))
+ (car (car (cdr x))))
+
+(compat-defun cadar (x)
+ "Return the `car' of the `cdr' of the `car' of X."
+ (declare (pure t))
+ (car (cdr (car x))))
+
+(compat-defun caddr (x)
+ "Return the `car' of the `cdr' of the `cdr' of X."
+ (declare (pure t))
+ (car (cdr (cdr x))))
+
+(compat-defun cdaar (x)
+ "Return the `cdr' of the `car' of the `car' of X."
+ (declare (pure t))
+ (cdr (car (car x))))
+
+(compat-defun cdadr (x)
+ "Return the `cdr' of the `car' of the `cdr' of X."
+ (declare (pure t))
+ (cdr (car (cdr x))))
+
+(compat-defun cddar (x)
+ "Return the `cdr' of the `cdr' of the `car' of X."
+ (declare (pure t))
+ (cdr (cdr (car x))))
+
+(compat-defun cdddr (x)
+ "Return the `cdr' of the `cdr' of the `cdr' of X."
+ (declare (pure t))
+ (cdr (cdr (cdr x))))
+
+(compat-defun caaaar (x)
+ "Return the `car' of the `car' of the `car' of the `car' of X."
+ (declare (pure t))
+ (car (car (car (car x)))))
+
+(compat-defun caaadr (x)
+ "Return the `car' of the `car' of the `car' of the `cdr' of X."
+ (declare (pure t))
+ (car (car (car (cdr x)))))
+
+(compat-defun caadar (x)
+ "Return the `car' of the `car' of the `cdr' of the `car' of X."
+ (declare (pure t))
+ (car (car (cdr (car x)))))
+
+(compat-defun caaddr (x)
+ "Return the `car' of the `car' of the `cdr' of the `cdr' of X."
+ (declare (pure t))
+ (car (car (cdr (cdr x)))))
+
+(compat-defun cadaar (x)
+ "Return the `car' of the `cdr' of the `car' of the `car' of X."
+ (declare (pure t))
+ (car (cdr (car (car x)))))
+
+(compat-defun cadadr (x)
+ "Return the `car' of the `cdr' of the `car' of the `cdr' of X."
+ (declare (pure t))
+ (car (cdr (car (cdr x)))))
+
+(compat-defun caddar (x)
+ "Return the `car' of the `cdr' of the `cdr' of the `car' of X."
+ (declare (pure t))
+ (car (cdr (cdr (car x)))))
+
+(compat-defun cadddr (x)
+ "Return the `car' of the `cdr' of the `cdr' of the `cdr' of X."
+ (declare (pure t))
+ (car (cdr (cdr (cdr x)))))
+
+(compat-defun cdaaar (x)
+ "Return the `cdr' of the `car' of the `car' of the `car' of X."
+ (declare (pure t))
+ (cdr (car (car (car x)))))
+
+(compat-defun cdaadr (x)
+ "Return the `cdr' of the `car' of the `car' of the `cdr' of X."
+ (declare (pure t))
+ (cdr (car (car (cdr x)))))
+
+(compat-defun cdadar (x)
+ "Return the `cdr' of the `car' of the `cdr' of the `car' of X."
+ (declare (pure t))
+ (cdr (car (cdr (car x)))))
+
+(compat-defun cdaddr (x)
+ "Return the `cdr' of the `car' of the `cdr' of the `cdr' of X."
+ (declare (pure t))
+ (cdr (car (cdr (cdr x)))))
+
+(compat-defun cddaar (x)
+ "Return the `cdr' of the `cdr' of the `car' of the `car' of X."
+ (declare (pure t))
+ (cdr (cdr (car (car x)))))
+
+(compat-defun cddadr (x)
+ "Return the `cdr' of the `cdr' of the `car' of the `cdr' of X."
+ (declare (pure t))
+ (cdr (cdr (car (cdr x)))))
+
+(compat-defun cdddar (x)
+ "Return the `cdr' of the `cdr' of the `cdr' of the `car' of X."
+ (declare (pure t))
+ (cdr (cdr (cdr (car x)))))
+
+(compat-defun cddddr (x)
+ "Return the `cdr' of the `cdr' of the `cdr' of the `cdr' of X."
+ (declare (pure t))
+ (cdr (cdr (cdr (cdr x)))))
+
+(compat-defvar gensym-counter 0
+ "Number used to construct the name of the next symbol created by `gensym'.")
+
+(compat-defun gensym (&optional prefix)
+ "Return a new uninterned symbol.
+The name is made by appending `gensym-counter' to PREFIX.
+PREFIX is a string, and defaults to \"g\"."
+ (let ((num (prog1 gensym-counter
+ (setq gensym-counter
+ (1+ gensym-counter)))))
+ (make-symbol (format "%s%d" (or prefix "g") num))))
+
+;;;; Defined in files.el
+
+(declare-function temporary-file-directory nil)
+
+;;* UNTESTED
+(compat-defun make-nearby-temp-file (prefix &optional dir-flag suffix)
+ "Create a temporary file as close as possible to `default-directory'.
+If PREFIX is a relative file name, and `default-directory' is a
+remote file name or located on a mounted file systems, the
+temporary file is created in the directory returned by the
+function `temporary-file-directory'. Otherwise, the function
+`make-temp-file' is used. PREFIX, DIR-FLAG and SUFFIX have the
+same meaning as in `make-temp-file'."
+ (let ((handler (find-file-name-handler
+ default-directory 'make-nearby-temp-file)))
+ (if (and handler (not (file-name-absolute-p default-directory)))
+ (funcall handler 'make-nearby-temp-file prefix dir-flag suffix)
+ (let ((temporary-file-directory (temporary-file-directory)))
+ (make-temp-file prefix dir-flag suffix)))))
+
+(compat-defvar mounted-file-systems
+ (eval-when-compile
+ (if (memq system-type '(windows-nt cygwin))
+ "^//[^/]+/"
+ (concat
+ "^" (regexp-opt '("/afs/" "/media/" "/mnt" "/net/" "/tmp_mnt/")))))
+ "File systems that ought to be mounted.")
+
+(compat-defun file-local-name (file)
+ "Return the local name component of FILE.
+This function removes from FILE the specification of the remote host
+and the method of accessing the host, leaving only the part that
+identifies FILE locally on the remote system.
+The returned file name can be used directly as argument of
+`process-file', `start-file-process', or `shell-command'."
+ :realname compat--file-local-name
+ (or (file-remote-p file 'localname) file))
+
+(compat-defun file-name-quoted-p (name &optional top)
+ "Whether NAME is quoted with prefix \"/:\".
+If NAME is a remote file name and TOP is nil, check the local part of NAME."
+ :realname compat--file-name-quoted-p
+ (let ((file-name-handler-alist (unless top file-name-handler-alist)))
+ (string-prefix-p "/:" (compat--file-local-name name))))
+
+(compat-defun file-name-quote (name &optional top)
+ "Add the quotation prefix \"/:\" to file NAME.
+If NAME is a remote file name and TOP is nil, the local part of
+NAME is quoted. If NAME is already a quoted file name, NAME is
+returned unchanged."
+ (let ((file-name-handler-alist (unless top file-name-handler-alist)))
+ (if (compat--file-name-quoted-p name top)
+ name
+ (concat (file-remote-p name) "/:" (compat--file-local-name name)))))
+
+;;* UNTESTED
+(compat-defun temporary-file-directory ()
+ "The directory for writing temporary files.
+In case of a remote `default-directory', this is a directory for
+temporary files on that remote host. If such a directory does
+not exist, or `default-directory' ought to be located on a
+mounted file system (see `mounted-file-systems'), the function
+returns `default-directory'.
+For a non-remote and non-mounted `default-directory', the value of
+the variable `temporary-file-directory' is returned."
+ (let ((handler (find-file-name-handler
+ default-directory 'temporary-file-directory)))
+ (if handler
+ (funcall handler 'temporary-file-directory)
+ (if (string-match mounted-file-systems default-directory)
+ default-directory
+ temporary-file-directory))))
+
+;;* UNTESTED
+(compat-defun file-attribute-type (attributes)
+ "The type field in ATTRIBUTES returned by `file-attributes'.
+The value is either t for directory, string (name linked to) for
+symbolic link, or nil."
+ (nth 0 attributes))
+
+;;* UNTESTED
+(compat-defun file-attribute-link-number (attributes)
+ "Return the number of links in ATTRIBUTES returned by `file-attributes'."
+ (nth 1 attributes))
+
+;;* UNTESTED
+(compat-defun file-attribute-user-id (attributes)
+ "The UID field in ATTRIBUTES returned by `file-attributes'.
+This is either a string or a number. If a string value cannot be
+looked up, a numeric value, either an integer or a float, is
+returned."
+ (nth 2 attributes))
+
+;;* UNTESTED
+(compat-defun file-attribute-group-id (attributes)
+ "The GID field in ATTRIBUTES returned by `file-attributes'.
+This is either a string or a number. If a string value cannot be
+looked up, a numeric value, either an integer or a float, is
+returned."
+ (nth 3 attributes))
+
+;;* UNTESTED
+(compat-defun file-attribute-access-time (attributes)
+ "The last access time in ATTRIBUTES returned by `file-attributes'.
+This a Lisp timestamp in the style of `current-time'."
+ (nth 4 attributes))
+
+;;* UNTESTED
+(compat-defun file-attribute-modification-time (attributes)
+ "The modification time in ATTRIBUTES returned by `file-attributes'.
+This is the time of the last change to the file's contents, and
+is a Lisp timestamp in the style of `current-time'."
+ (nth 5 attributes))
+
+;;* UNTESTED
+(compat-defun file-attribute-status-change-time (attributes)
+ "The status modification time in ATTRIBUTES returned by `file-attributes'.
+This is the time of last change to the file's attributes: owner
+and group, access mode bits, etc., and is a Lisp timestamp in the
+style of `current-time'."
+ (nth 6 attributes))
+
+;;* UNTESTED
+(compat-defun file-attribute-size (attributes)
+ "The integer size (in bytes) in ATTRIBUTES returned by `file-attributes'."
+ (nth 7 attributes))
+
+;;* UNTESTED
+(compat-defun file-attribute-modes (attributes)
+ "The file modes in ATTRIBUTES returned by `file-attributes'.
+This is a string of ten letters or dashes as in ls -l."
+ (nth 8 attributes))
+
+;;* UNTESTED
+(compat-defun file-attribute-inode-number (attributes)
+ "The inode number in ATTRIBUTES returned by `file-attributes'.
+It is a nonnegative integer."
+ (nth 10 attributes))
+
+;;* UNTESTED
+(compat-defun file-attribute-device-number (attributes)
+ "The file system device number in ATTRIBUTES returned by `file-attributes'.
+It is an integer."
+ (nth 11 attributes))
+
+(compat-defun file-attribute-collect (attributes &rest attr-names)
+ "Return a sublist of ATTRIBUTES returned by `file-attributes'.
+ATTR-NAMES are symbols with the selected attribute names.
+
+Valid attribute names are: type, link-number, user-id, group-id,
+access-time, modification-time, status-change-time, size, modes,
+inode-number and device-number."
+ (let ((idx '((type . 0)
+ (link-number . 1)
+ (user-id . 2)
+ (group-id . 3)
+ (access-time . 4)
+ (modification-time . 5)
+ (status-change-time . 6)
+ (size . 7)
+ (modes . 8)
+ (inode-number . 10)
+ (device-number . 11)))
+ result)
+ (while attr-names
+ (let ((attr (pop attr-names)))
+ (if (assq attr idx)
+ (push (nth (cdr (assq attr idx))
+ attributes)
+ result)
+ (error "Wrong attribute name '%S'" attr))))
+ (nreverse result)))
+
+;;;; Defined in subr-x.el
+
+(compat-defmacro if-let* (varlist then &rest else)
+ "Bind variables according to VARLIST and evaluate THEN or ELSE.
+This is like `if-let' but doesn't handle a VARLIST of the form
+\(SYMBOL SOMETHING) specially."
+ :realname compat--if-let*
+ :feature 'subr-x
+ (declare (indent 2)
+ (debug ((&rest [&or symbolp (symbolp form) (form)])
+ body)))
+ (let ((empty (make-symbol "s"))
+ (last t) list)
+ (dolist (var varlist)
+ (push `(,(if (cdr var) (car var) empty)
+ (and ,last ,(or (cadr var) (car var))))
+ list)
+ (when (or (cdr var) (consp (car var)))
+ (setq last (caar list))))
+ `(let* ,(nreverse list)
+ (if ,(caar list) ,then ,@else))))
+
+(compat-defmacro when-let* (varlist &rest body)
+ "Bind variables according to VARLIST and conditionally evaluate BODY.
+This is like `when-let' but doesn't handle a VARLIST of the form
+\(SYMBOL SOMETHING) specially."
+ ;; :feature 'subr-x
+ (declare (indent 1) (debug if-let*))
+ (let ((empty (make-symbol "s"))
+ (last t) list)
+ (dolist (var varlist)
+ (push `(,(if (cdr var) (car var) empty)
+ (and ,last ,(or (cadr var) (car var))))
+ list)
+ (when (or (cdr var) (consp (car var)))
+ (setq last (caar list))))
+ `(let* ,(nreverse list)
+ (when ,(caar list) ,@body))))
+
+(compat-defmacro and-let* (varlist &rest body)
+ "Bind variables according to VARLIST and conditionally evaluate BODY.
+Like `when-let*', except if BODY is empty and all the bindings
+are non-nil, then the result is non-nil."
+ :feature 'subr-x
+ (declare (indent 1) (debug if-let*))
+ (let ((empty (make-symbol "s"))
+ (last t) list)
+ (dolist (var varlist)
+ (push `(,(if (cdr var) (car var) empty)
+ (and ,last ,(or (cadr var) (car var))))
+ list)
+ (when (or (cdr var) (consp (car var)))
+ (setq last (caar list))))
+ `(let* ,(nreverse list)
+ (if ,(caar list) ,(macroexp-progn (or body '(t)))))))
+
+;;;; Defined in image.el
+
+;;* UNTESTED
+(compat-defun image-property (image property)
+ "Return the value of PROPERTY in IMAGE.
+Properties can be set with
+
+ (setf (image-property IMAGE PROPERTY) VALUE)
+
+If VALUE is nil, PROPERTY is removed from IMAGE."
+ (plist-get (cdr image) property))
+
+;;* UNTESTED
+(unless (get 'image-property 'gv-expander)
+ (gv-define-setter image-property (image property value)
+ (let ((image* (make-symbol "image"))
+ (property* (make-symbol "property"))
+ (value* (make-symbol "value")))
+ `(let ((,image* ,image)
+ (,property* ,property)
+ (,value* ,value))
+ (if
+ (null ,value*)
+ (while
+ (cdr ,image*)
+ (if
+ (eq
+ (cadr ,image*)
+ ,property*)
+ (setcdr ,image*
+ (cdddr ,image*))
+ (setq ,image*
+ (cddr ,image*))))
+ (setcdr ,image*
+ (plist-put
+ (cdr ,image*)
+ ,property* ,value*)))))))
+
+(provide 'compat-26)
+;;; compat-26.el ends here
diff --git a/elpa/compat-28.1.1.0/compat-26.elc b/elpa/compat-28.1.1.0/compat-26.elc
new file mode 100644
index 0000000..d1d5e31
--- /dev/null
+++ b/elpa/compat-28.1.1.0/compat-26.elc
Binary files differ
diff --git a/elpa/compat-28.1.1.0/compat-27.el b/elpa/compat-28.1.1.0/compat-27.el
new file mode 100644
index 0000000..b74450f
--- /dev/null
+++ b/elpa/compat-28.1.1.0/compat-27.el
@@ -0,0 +1,642 @@
+;;; compat-27.el --- Compatibility Layer for Emacs 27.1 -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2021, 2022 Free Software Foundation, Inc.
+
+;; Author: Philip Kaludercic <philipk@posteo.net>
+;; Maintainer: Compat Development <~pkal/compat-devel@lists.sr.ht>
+;; URL: https://git.sr.ht/~pkal/compat/
+;; Keywords: lisp
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Find here the functionality added in Emacs 27.1, needed by older
+;; versions.
+;;
+;; Do NOT load this library manually. Instead require `compat'.
+
+;;; Code:
+
+(eval-when-compile (require 'compat-macs))
+
+;;;; Defined in fns.c
+
+(compat-defun proper-list-p (object)
+ "Return OBJECT's length if it is a proper list, nil otherwise.
+A proper list is neither circular nor dotted (i.e., its last cdr
+is nil)."
+ :min-version "26.1"
+ :max-version "26.3"
+ :realname compat--proper-list-p-length-signal
+ (condition-case nil
+ (and (listp object) (length object))
+ (wrong-type-argument nil)
+ (circular-list nil)))
+
+(compat-defun proper-list-p (object)
+ "Return OBJECT's length if it is a proper list, nil otherwise.
+A proper list is neither circular nor dotted (i.e., its last cdr
+is nil)."
+ :max-version "25.3"
+ :realname compat--proper-list-p-tortoise-hare
+ (when (listp object)
+ (catch 'cycle
+ (let ((hare object) (tortoise object)
+ (max 2) (q 2))
+ (while (consp hare)
+ (setq hare (cdr hare))
+ (when (and (or (/= 0 (setq q (1- q)))
+ (ignore
+ (setq max (ash max 1)
+ q max
+ tortoise hare)))
+ (eq hare tortoise))
+ (throw 'cycle nil)))
+ (and (null hare) (length object))))))
+
+(compat-defun string-distance (string1 string2 &optional bytecompare)
+ "Return Levenshtein distance between STRING1 and STRING2.
+The distance is the number of deletions, insertions, and substitutions
+required to transform STRING1 into STRING2.
+If BYTECOMPARE is nil or omitted, compute distance in terms of characters.
+If BYTECOMPARE is non-nil, compute distance in terms of bytes.
+Letter-case is significant, but text properties are ignored."
+ ;; https://en.wikipedia.org/wiki/Levenshtein_distance
+ (let ((s1 (if bytecompare
+ (encode-coding-string string1 'raw-text)
+ (concat string1 "")))
+ (s2 (if bytecompare
+ (encode-coding-string string2 'raw-text)
+ string2)))
+ (let* ((len1 (length s1))
+ (len2 (length s2))
+ (column (make-vector (1+ len1) 0)))
+ (dotimes (y len1)
+ (setf (aref column (1+ y)) y))
+ (dotimes (x len2)
+ (setf (aref column 0) (1+ x))
+ (let ((lastdiag x) olddiag)
+ (dotimes (y len1)
+ (setf olddiag (aref column (1+ y))
+ (aref column (1+ y))
+ (min (+ (if (= (aref s1 y) (aref s2 x)) 0 1)
+ lastdiag)
+ (1+ (aref column (1+ y)))
+ (1+ (aref column y)))
+ lastdiag olddiag))))
+ (aref column len1))))
+
+;;;; Defined in window.c
+
+(compat-defun recenter (&optional arg redisplay)
+ "Handle optional argument REDISPLAY."
+ :prefix t
+ (recenter arg)
+ (when (and redisplay recenter-redisplay)
+ (redisplay)))
+
+;;;; Defined in keymap.c
+
+(compat-defun lookup-key (keymap key &optional accept-default)
+ "Allow for KEYMAP to be a list of keymaps."
+ :prefix t
+ (cond
+ ((keymapp keymap)
+ (lookup-key keymap key accept-default))
+ ((listp keymap)
+ (catch 'found
+ (dolist (map keymap)
+ (let ((fn (lookup-key map key accept-default)))
+ (when fn (throw 'found fn))))))
+ ((signal 'wrong-type-argument (list 'keymapp keymap)))))
+
+;;;; Defined in json.c
+
+(declare-function json-parse-string nil (string &rest args))
+(declare-function json-encode-string "json" (object))
+(declare-function json-read-from-string "json" (string))
+(declare-function json-read "json" ())
+(defvar json-object-type)
+(defvar json-array-type)
+(defvar json-false)
+(defvar json-null)
+
+(compat-defun json-serialize (object &rest args)
+ "Return the JSON representation of OBJECT as a string.
+
+OBJECT must be t, a number, string, vector, hashtable, alist, plist,
+or the Lisp equivalents to the JSON null and false values, and its
+elements must recursively consist of the same kinds of values. t will
+be converted to the JSON true value. Vectors will be converted to
+JSON arrays, whereas hashtables, alists and plists are converted to
+JSON objects. Hashtable keys must be strings without embedded null
+characters and must be unique within each object. Alist and plist
+keys must be symbols; if a key is duplicate, the first instance is
+used.
+
+The Lisp equivalents to the JSON null and false values are
+configurable in the arguments ARGS, a list of keyword/argument pairs:
+
+The keyword argument `:null-object' specifies which object to use
+to represent a JSON null value. It defaults to `:null'.
+
+The keyword argument `:false-object' specifies which object to use to
+represent a JSON false value. It defaults to `:false'.
+
+In you specify the same value for `:null-object' and `:false-object',
+a potentially ambiguous situation, the JSON output will not contain
+any JSON false values."
+ :cond (condition-case nil
+ (let ((inhibit-message t))
+ (equal (json-parse-string "[]") nil))
+ (json-unavailable t)
+ (void-function t))
+ :realname compat--json-serialize
+ (require 'json)
+ (let ((json-false (or (plist-get args :false-object) :false))
+ (json-null (or (plist-get args :null-object) :null)))
+ (json-encode-string object)))
+
+(compat-defun json-insert (object &rest args)
+ "Insert the JSON representation of OBJECT before point.
+This is the same as (insert (json-serialize OBJECT)), but potentially
+faster. See the function `json-serialize' for allowed values of
+OBJECT."
+ :cond (condition-case nil
+ (let ((inhibit-message t))
+ (equal (json-parse-string "[]") nil))
+ (json-unavailable t)
+ (void-function t))
+ (insert (apply #'compat--json-serialize object args)))
+
+(compat-defun json-parse-string (string &rest args)
+ "Parse the JSON STRING into a Lisp object.
+This is essentially the reverse operation of `json-serialize', which
+see. The returned object will be the JSON null value, the JSON false
+value, t, a number, a string, a vector, a list, a hashtable, an alist,
+or a plist. Its elements will be further objects of these types. If
+there are duplicate keys in an object, all but the last one are
+ignored. If STRING doesn't contain a valid JSON object, this function
+signals an error of type `json-parse-error'.
+
+The arguments ARGS are a list of keyword/argument pairs:
+
+The keyword argument `:object-type' specifies which Lisp type is used
+to represent objects; it can be `hash-table', `alist' or `plist'. It
+defaults to `hash-table'.
+
+The keyword argument `:array-type' specifies which Lisp type is used
+to represent arrays; it can be `array' (the default) or `list'.
+
+The keyword argument `:null-object' specifies which object to use
+to represent a JSON null value. It defaults to `:null'.
+
+The keyword argument `:false-object' specifies which object to use to
+represent a JSON false value. It defaults to `:false'."
+ :cond (condition-case nil
+ (let ((inhibit-message t))
+ (equal (json-parse-string "[]") nil))
+ (json-unavailable t)
+ (void-function t))
+ (require 'json)
+ (condition-case err
+ (let ((json-object-type (or (plist-get args :object-type) 'hash-table))
+ (json-array-type (or (plist-get args :array-type) 'vector))
+ (json-false (or (plist-get args :false-object) :false))
+ (json-null (or (plist-get args :null-object) :null)))
+ (when (eq json-array-type 'array)
+ (setq json-array-type 'vector))
+ (json-read-from-string string))
+ (json-error (signal 'json-parse-error err))))
+
+(compat-defun json-parse-buffer (&rest args)
+ "Read JSON object from current buffer starting at point.
+Move point after the end of the object if parsing was successful.
+On error, don't move point.
+
+The returned object will be a vector, list, hashtable, alist, or
+plist. Its elements will be the JSON null value, the JSON false
+value, t, numbers, strings, or further vectors, lists, hashtables,
+alists, or plists. If there are duplicate keys in an object, all
+but the last one are ignored.
+
+If the current buffer doesn't contain a valid JSON object, the
+function signals an error of type `json-parse-error'.
+
+The arguments ARGS are a list of keyword/argument pairs:
+
+The keyword argument `:object-type' specifies which Lisp type is used
+to represent objects; it can be `hash-table', `alist' or `plist'. It
+defaults to `hash-table'.
+
+The keyword argument `:array-type' specifies which Lisp type is used
+to represent arrays; it can be `array' (the default) or `list'.
+
+The keyword argument `:null-object' specifies which object to use
+to represent a JSON null value. It defaults to `:null'.
+
+The keyword argument `:false-object' specifies which object to use to
+represent a JSON false value. It defaults to `:false'."
+ :cond (condition-case nil
+ (let ((inhibit-message t))
+ (equal (json-parse-string "[]") nil))
+ (json-unavailable t)
+ (void-function t))
+ (require 'json)
+ (condition-case err
+ (let ((json-object-type (or (plist-get args :object-type) 'hash-table))
+ (json-array-type (or (plist-get args :array-type) 'vector))
+ (json-false (or (plist-get args :false-object) :false))
+ (json-null (or (plist-get args :null-object) :null)))
+ (when (eq json-array-type 'array)
+ (setq json-array-type 'vector))
+ (json-read))
+ (json-error (signal 'json-parse-buffer err))))
+
+;;;; Defined in timefns.c
+
+(compat-defun time-equal-p (t1 t2)
+ "Return non-nil if time value T1 is equal to time value T2.
+A nil value for either argument stands for the current time."
+ :note "This function is not as accurate as the actual `time-equal-p'."
+ (cond
+ ((eq t1 t2))
+ ((and (consp t1) (consp t2))
+ (equal t1 t2))
+ ((let ((now (current-time)))
+ ;; Due to inaccuracies and the relatively slow evaluating of
+ ;; Emacs Lisp compared to C, we allow for slight inaccuracies
+ ;; (less than a millisecond) when comparing time values.
+ (< (abs (- (float-time (or t1 now))
+ (float-time (or t2 now))))
+ 1e-5)))))
+
+;;;; Defined in subr.el
+
+(compat-defmacro setq-local (&rest pairs)
+ "Handle multiple assignments."
+ :prefix t
+ (unless (zerop (mod (length pairs) 2))
+ (error "PAIRS must have an even number of variable/value members"))
+ (let (body)
+ (while pairs
+ (let* ((sym (pop pairs))
+ (val (pop pairs)))
+ (unless (symbolp sym)
+ (error "Attempting to set a non-symbol: %s" (car pairs)))
+ (push `(set (make-local-variable ,sym) ,val)
+ body)))
+ (cons 'progn (nreverse body))))
+
+;;* UNTESTED
+(compat-defmacro ignore-error (condition &rest body)
+ "Execute BODY; if the error CONDITION occurs, return nil.
+Otherwise, return result of last form in BODY.
+
+CONDITION can also be a list of error conditions."
+ (declare (debug t) (indent 1))
+ `(condition-case nil (progn ,@body) (,condition nil)))
+
+;;* UNTESTED
+(compat-defmacro dolist-with-progress-reporter (spec reporter-or-message &rest body)
+ "Loop over a list and report progress in the echo area.
+Evaluate BODY with VAR bound to each car from LIST, in turn.
+Then evaluate RESULT to get return value, default nil.
+
+REPORTER-OR-MESSAGE is a progress reporter object or a string. In the latter
+case, use this string to create a progress reporter.
+
+At each iteration, print the reporter message followed by progress
+percentage in the echo area. After the loop is finished,
+print the reporter message followed by the word \"done\".
+
+\(fn (VAR LIST [RESULT]) REPORTER-OR-MESSAGE BODY...)"
+ (declare (indent 2) (debug ((symbolp form &optional form) form body)))
+ (let ((prep (make-symbol "--dolist-progress-reporter--"))
+ (count (make-symbol "--dolist-count--"))
+ (list (make-symbol "--dolist-list--")))
+ `(let ((,prep ,reporter-or-message)
+ (,count 0)
+ (,list ,(cadr spec)))
+ (when (stringp ,prep)
+ (setq ,prep (make-progress-reporter ,prep 0 (1- (length ,list)))))
+ (dolist (,(car spec) ,list)
+ ,@body
+ (progress-reporter-update ,prep (setq ,count (1+ ,count))))
+ (progress-reporter-done ,prep)
+ (or ,@(cdr (cdr spec)) nil))))
+
+(compat-defun flatten-tree (tree)
+ "Return a \"flattened\" copy of TREE.
+In other words, return a list of the non-nil terminal nodes, or
+leaves, of the tree of cons cells rooted at TREE. Leaves in the
+returned list are in the same order as in TREE.
+
+\(flatten-tree \\='(1 (2 . 3) nil (4 5 (6)) 7))
+=> (1 2 3 4 5 6 7)"
+ (let (elems)
+ (while (consp tree)
+ (let ((elem (pop tree)))
+ (while (consp elem)
+ (push (cdr elem) tree)
+ (setq elem (car elem)))
+ (if elem (push elem elems))))
+ (if tree (push tree elems))
+ (nreverse elems)))
+
+(compat-defun xor (cond1 cond2)
+ "Return the boolean exclusive-or of COND1 and COND2.
+If only one of the arguments is non-nil, return it; otherwise
+return nil."
+ (declare (pure t) (side-effect-free error-free))
+ (cond ((not cond1) cond2)
+ ((not cond2) cond1)))
+
+(compat-defvar regexp-unmatchable "\\`a\\`"
+ "Standard regexp guaranteed not to match any string at all."
+ :constant t)
+
+(compat-defun assoc-delete-all (key alist &optional test)
+ "Delete from ALIST all elements whose car is KEY.
+Compare keys with TEST. Defaults to `equal'.
+Return the modified alist.
+Elements of ALIST that are not conses are ignored."
+ :prefix t
+ (unless test (setq test #'equal))
+ (while (and (consp (car alist))
+ (funcall test (caar alist) key))
+ (setq alist (cdr alist)))
+ (let ((tail alist) tail-cdr)
+ (while (setq tail-cdr (cdr tail))
+ (if (and (consp (car tail-cdr))
+ (funcall test (caar tail-cdr) key))
+ (setcdr tail (cdr tail-cdr))
+ (setq tail tail-cdr))))
+ alist)
+
+;;;; Defined in simple.el
+
+;;* UNTESTED
+(compat-defun decoded-time-second (time)
+ "The seconds in TIME, which is a value returned by `decode-time'.
+This is an integer between 0 and 60 (inclusive). (60 is a leap
+second, which only some operating systems support.)"
+ (nth 0 time))
+
+;;* UNTESTED
+(compat-defun decoded-time-minute (time)
+ "The minutes in TIME, which is a value returned by `decode-time'.
+This is an integer between 0 and 59 (inclusive)."
+ (nth 1 time))
+
+;;* UNTESTED
+(compat-defun decoded-time-hour (time)
+ "The hours in TIME, which is a value returned by `decode-time'.
+This is an integer between 0 and 23 (inclusive)."
+ (nth 2 time))
+
+;;* UNTESTED
+(compat-defun decoded-time-day (time)
+ "The day-of-the-month in TIME, which is a value returned by `decode-time'.
+This is an integer between 1 and 31 (inclusive)."
+ (nth 3 time))
+
+;;* UNTESTED
+(compat-defun decoded-time-month (time)
+ "The month in TIME, which is a value returned by `decode-time'.
+This is an integer between 1 and 12 (inclusive). January is 1."
+ (nth 4 time))
+
+;;* UNTESTED
+(compat-defun decoded-time-year (time)
+ "The year in TIME, which is a value returned by `decode-time'.
+This is a four digit integer."
+ (nth 5 time))
+
+;;* UNTESTED
+(compat-defun decoded-time-weekday (time)
+ "The day-of-the-week in TIME, which is a value returned by `decode-time'.
+This is a number between 0 and 6, and 0 is Sunday."
+ (nth 6 time))
+
+;;* UNTESTED
+(compat-defun decoded-time-dst (time)
+ "The daylight saving time in TIME, which is a value returned by `decode-time'.
+This is t if daylight saving time is in effect, and nil if not."
+ (nth 7 time))
+
+;;* UNTESTED
+(compat-defun decoded-time-zone (time)
+ "The time zone in TIME, which is a value returned by `decode-time'.
+This is an integer indicating the UTC offset in seconds, i.e.,
+the number of seconds east of Greenwich."
+ (nth 8 time))
+
+;; TODO define gv-setters
+
+;;;; Defined in files.el
+
+(compat-defun file-size-human-readable (file-size &optional flavor space unit)
+ "Handle the optional third and forth argument:
+
+Optional third argument SPACE is a string put between the number and unit.
+It defaults to the empty string. We recommend a single space or
+non-breaking space, unless other constraints prohibit a space in that
+position.
+
+Optional fourth argument UNIT is the unit to use. It defaults to \"B\"
+when FLAVOR is `iec' and the empty string otherwise. We recommend \"B\"
+in all cases, since that is the standard symbol for byte."
+ :prefix t
+ (let ((power (if (or (null flavor) (eq flavor 'iec))
+ 1024.0
+ 1000.0))
+ (prefixes '("" "k" "M" "G" "T" "P" "E" "Z" "Y")))
+ (while (and (>= file-size power) (cdr prefixes))
+ (setq file-size (/ file-size power)
+ prefixes (cdr prefixes)))
+ (let* ((prefix (car prefixes))
+ (prefixed-unit (if (eq flavor 'iec)
+ (concat
+ (if (string= prefix "k") "K" prefix)
+ (if (string= prefix "") "" "i")
+ (or unit "B"))
+ (concat prefix unit))))
+ (format (if (and (>= (mod file-size 1.0) 0.05)
+ (< (mod file-size 1.0) 0.95))
+ "%.1f%s%s"
+ "%.0f%s%s")
+ file-size
+ (if (string= prefixed-unit "") "" (or space ""))
+ prefixed-unit))))
+
+(declare-function compat--file-name-quote "compat-26"
+ (name &optional top))
+
+;;*UNTESTED
+(compat-defun exec-path ()
+ "Return list of directories to search programs to run in remote subprocesses.
+The remote host is identified by `default-directory'. For remote
+hosts that do not support subprocesses, this returns nil.
+If `default-directory' is a local directory, this function returns
+the value of the variable `exec-path'."
+ :realname compat--exec-path
+ (cond
+ ((let ((handler (find-file-name-handler default-directory 'exec-path)))
+ ;; FIXME: The handler was added in 27.1, and this compatibility
+ ;; function only applies to versions of Emacs before that.
+ (when handler
+ (condition-case nil
+ (funcall handler 'exec-path)
+ (error nil)))))
+ ((file-remote-p default-directory)
+ ;; TODO: This is not completely portable, even if "sh" and
+ ;; "getconf" should be provided on every POSIX system, the chance
+ ;; of this not working are greater than zero.
+ ;;
+ ;; FIXME: This invokes a shell process every time exec-path is
+ ;; called. It should instead be cached on a host-local basis.
+ (with-temp-buffer
+ (if (condition-case nil
+ (zerop (process-file "sh" nil t nil "-c" "getconf PATH"))
+ (file-missing t))
+ (list "/bin" "/usr/bin")
+ (let (path)
+ (while (re-search-forward "\\([^:]+?\\)[\n:]" nil t)
+ (push (match-string 1) path))
+ (nreverse path)))))
+ (exec-path)))
+
+(declare-function compat--file-local-name "compat-26"
+ (file))
+
+;;*UNTESTED
+(compat-defun executable-find (command &optional remote)
+ "Search for COMMAND in `exec-path' and return the absolute file name.
+Return nil if COMMAND is not found anywhere in `exec-path'. If
+REMOTE is non-nil, search on the remote host indicated by
+`default-directory' instead."
+ :prefix t
+ (if (and remote (file-remote-p default-directory))
+ (let ((res (locate-file
+ command
+ (mapcar
+ (apply-partially
+ #'concat (file-remote-p default-directory))
+ (compat--exec-path))
+ exec-suffixes 'file-executable-p)))
+ (when (stringp res) (compat--file-local-name res)))
+ (executable-find command)))
+
+;; TODO provide advice for directory-files-recursively
+
+;;;; Defined in format-spec.el
+
+;; TODO provide advice for format-spec
+
+;;;; Defined in regexp-opt.el
+
+(compat-defun regexp-opt (strings &optional paren)
+ "Handle an empty list of strings."
+ :prefix t
+ (if (null strings)
+ (let ((re "\\`a\\`"))
+ (cond ((null paren)
+ (concat "\\(?:" re "\\)"))
+ ((stringp paren)
+ (concat paren re "\\)"))
+ ((eq paren 'words)
+ (concat "\\<\\(" re "\\)\\>"))
+ ((eq paren 'symbols)
+ (concat "\\_\\(<" re "\\)\\_>"))
+ ((concat "\\(" re "\\)"))))
+ (regexp-opt strings paren)))
+
+;;;; Defined in package.el
+
+(declare-function lm-header "lisp-mnt")
+
+;;* UNTESTED
+(compat-defun package-get-version ()
+ "Return the version number of the package in which this is used.
+Assumes it is used from an Elisp file placed inside the top-level directory
+of an installed ELPA package.
+The return value is a string (or nil in case we can’t find it)."
+ ;; In a sense, this is a lie, but it does just what we want: precompute
+ ;; the version at compile time and hardcodes it into the .elc file!
+ (declare (pure t))
+ ;; Hack alert!
+ (let ((file
+ (or (and (boundp 'byte-compile-current-file) byte-compile-current-file)
+ load-file-name
+ buffer-file-name)))
+ (cond
+ ((null file) nil)
+ ;; Packages are normally installed into directories named "<pkg>-<vers>",
+ ;; so get the version number from there.
+ ((string-match
+ "/[^/]+-\\([0-9]\\(?:[0-9.]\\|pre\\|beta\\|alpha\\|snapshot\\)+\\)/[^/]+\\'"
+ file)
+ (match-string 1 file))
+ ;; For packages run straight from the an elpa.git clone, there's no
+ ;; "-<vers>" in the directory name, so we have to fetch the version
+ ;; the hard way.
+ ((let* ((pkgdir (file-name-directory file))
+ (pkgname (file-name-nondirectory (directory-file-name pkgdir)))
+ (mainfile (expand-file-name (concat pkgname ".el") pkgdir)))
+ (when (file-readable-p mainfile)
+ (require 'lisp-mnt)
+ (with-temp-buffer
+ (insert-file-contents mainfile)
+ (or (lm-header "package-version")
+ (lm-header "version")))))))))
+
+
+;;;; Defined in dired.el
+
+(declare-function
+ dired-get-marked-files "dired.el"
+ (&optional localp arg filter distinguish-one-marked error))
+
+;;* UNTESTED
+(compat-defun dired-get-marked-files
+ (&optional localp arg filter distinguish-one-marked error)
+ "Return the marked files’ names as list of strings."
+ :feature 'dired
+ :prefix t
+ (let ((result (dired-get-marked-files localp arg filter distinguish-one-marked)))
+ (if (and (null result) error)
+ (user-error (if (stringp error) error "No files specified"))
+ result)))
+
+;;;; Defined in time-date.el
+
+(compat-defun date-days-in-month (year month)
+ "The number of days in MONTH in YEAR."
+ :feature 'time-date
+ (unless (and (numberp month)
+ (<= 1 month)
+ (<= month 12))
+ (error "Month %s is invalid" month))
+ (if (= month 2)
+ (if (date-leap-year-p year)
+ 29
+ 28)
+ (if (memq month '(1 3 5 7 8 10 12))
+ 31
+ 30)))
+
+(provide 'compat-27)
+;;; compat-27.el ends here
diff --git a/elpa/compat-28.1.1.0/compat-27.elc b/elpa/compat-28.1.1.0/compat-27.elc
new file mode 100644
index 0000000..2dca45e
--- /dev/null
+++ b/elpa/compat-28.1.1.0/compat-27.elc
Binary files differ
diff --git a/elpa/compat-28.1.1.0/compat-28.el b/elpa/compat-28.1.1.0/compat-28.el
new file mode 100644
index 0000000..862dd08
--- /dev/null
+++ b/elpa/compat-28.1.1.0/compat-28.el
@@ -0,0 +1,835 @@
+;;; compat-28.el --- Compatibility Layer for Emacs 28.1 -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2021, 2022 Free Software Foundation, Inc.
+
+;; Author: Philip Kaludercic <philipk@posteo.net>
+;; Maintainer: Compat Development <~pkal/compat-devel@lists.sr.ht>
+;; URL: https://git.sr.ht/~pkal/compat/
+;; Keywords: lisp
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Find here the functionality added in Emacs 28.1, needed by older
+;; versions.
+;;
+;; Do NOT load this library manually. Instead require `compat'.
+
+;;; Code:
+
+(eval-when-compile (require 'compat-macs))
+
+;;;; Defined in fns.c
+
+;;* INCOMPLETE FEATURE: Should handle multibyte regular expressions
+(compat-defun string-search (needle haystack &optional start-pos)
+ "Search for the string NEEDLE in the strign HAYSTACK.
+
+The return value is the position of the first occurrence of
+NEEDLE in HAYSTACK, or nil if no match was found.
+
+The optional START-POS argument says where to start searching in
+HAYSTACK and defaults to zero (start at the beginning).
+It must be between zero and the length of HAYSTACK, inclusive.
+
+Case is always significant and text properties are ignored."
+ :note "Prior to Emacs 27 `string-match' has issues handling
+multibyte regular expressions. As the compatibility function
+for `string-search' is implemented via `string-match', these
+issues are inherited."
+ (when (and start-pos (or (< (length haystack) start-pos)
+ (< start-pos 0)))
+ (signal 'args-out-of-range (list start-pos)))
+ (save-match-data
+ (let ((case-fold-search nil))
+ (string-match (regexp-quote needle) haystack start-pos))))
+
+(compat-defun length= (sequence length)
+ "Returns non-nil if SEQUENCE has a length equal to LENGTH."
+ (cond
+ ((null sequence) (zerop length))
+ ((consp sequence)
+ (and (null (nthcdr length sequence))
+ (nthcdr (1- length) sequence)
+ t))
+ ((arrayp sequence)
+ (= (length sequence) length))
+ ((signal 'wrong-type-argument sequence))))
+
+(compat-defun length< (sequence length)
+ "Returns non-nil if SEQUENCE is shorter than LENGTH."
+ (cond
+ ((null sequence) (not (zerop length)))
+ ((listp sequence)
+ (null (nthcdr (1- length) sequence)))
+ ((arrayp sequence)
+ (< (length sequence) length))
+ ((signal 'wrong-type-argument sequence))))
+
+(compat-defun length> (sequence length)
+ "Returns non-nil if SEQUENCE is longer than LENGTH."
+ (cond
+ ((listp sequence)
+ (and (nthcdr length sequence) t))
+ ((arrayp sequence)
+ (> (length sequence) length))
+ ((signal 'wrong-type-argument sequence))))
+
+;;;; Defined in fileio.c
+
+(compat-defun file-name-concat (directory &rest components)
+ "Append COMPONENTS to DIRECTORY and return the resulting string.
+Elements in COMPONENTS must be a string or nil.
+DIRECTORY or the non-final elements in COMPONENTS may or may not end
+with a slash -- if they don’t end with a slash, a slash will be
+inserted before contatenating."
+ (let ((seperator (eval-when-compile
+ (if (memq system-type '(ms-dos windows-nt cygwin))
+ "\\" "/")))
+ (last (if components (car (last components)) directory)))
+ (mapconcat (lambda (part)
+ (if (eq part last) ;the last component is not modified
+ last
+ (replace-regexp-in-string
+ (concat seperator "+\\'") "" part)))
+ (cons directory components)
+ seperator)))
+
+;;;; Defined in alloc.c
+
+;;* UNTESTED (but also not necessary)
+(compat-defun garbage-collect-maybe (_factor)
+ "Call ‘garbage-collect’ if enough allocation happened.
+FACTOR determines what \"enough\" means here: If FACTOR is a
+positive number N, it means to run GC if more than 1/Nth of the
+allocations needed to trigger automatic allocation took place.
+Therefore, as N gets higher, this is more likely to perform a GC.
+Returns non-nil if GC happened, and nil otherwise."
+ :note "For releases of Emacs before version 28, this function will do nothing."
+ ;; Do nothing
+ nil)
+
+;;;; Defined in filelock.c
+
+(compat-defun unlock-buffer ()
+ "Handle `file-error' conditions:
+
+Handles file system errors by calling ‘display-warning’ and
+continuing as if the error did not occur."
+ :prefix t
+ (condition-case error
+ (unlock-buffer)
+ (file-error
+ (display-warning
+ '(unlock-file)
+ (message "%s, ignored" (error-message-string error))
+ :warning))))
+
+;;;; Defined in characters.c
+
+(compat-defun string-width (string &optional from to)
+ "Handle optional arguments FROM and TO:
+
+Optional arguments FROM and TO specify the substring of STRING to
+consider, and are interpreted as in `substring'."
+ :prefix t
+ (string-width (substring string (or from 0) to)))
+
+;;;; Defined in dired.c
+
+;;* UNTESTED
+(compat-defun directory-files (directory &optional full match nosort count)
+ "Handle additional optional argument COUNT:
+
+If COUNT is non-nil and a natural number, the function will
+ return COUNT number of file names (if so many are present)."
+ :prefix t
+ (let ((files (directory-files directory full match nosort)))
+ (when (natnump count)
+ (setf (nthcdr count files) nil))
+ files))
+
+;;;; Defined in json.c
+
+(declare-function json-insert nil (object &rest args))
+(declare-function json-serialize nil (object &rest args))
+(declare-function json-parse-string nil (string &rest args))
+(declare-function json-parse-buffer nil (&rest args))
+
+(compat-defun json-serialize (object &rest args)
+ "Handle top-level JSON values."
+ :prefix t
+ :min-version "27"
+ (if (or (listp object) (vectorp object))
+ (apply #'json-serialize object args)
+ (substring (json-serialize (list object)) 1 -1)))
+
+(compat-defun json-insert (object &rest args)
+ "Handle top-level JSON values."
+ :prefix t
+ :min-version "27"
+ (if (or (listp object) (vectorp object))
+ (apply #'json-insert object args)
+ (insert (apply #'compat-json-serialize object args))))
+
+(compat-defun json-parse-string (string &rest args)
+ "Handle top-level JSON values."
+ :prefix t
+ :min-version "27"
+ (if (string-match-p "\\`[[:space:]]*[[{]" string)
+ (apply #'json-parse-string string args)
+ ;; Wrap the string in an array, and extract the value back using
+ ;; `elt', to ensure that no matter what the value of `:array-type'
+ ;; is we can access the first element.
+ (elt (apply #'json-parse-string (concat "[" string "]") args) 0)))
+
+(compat-defun json-parse-buffer (&rest args)
+ "Handle top-level JSON values."
+ :prefix t
+ :min-version "27"
+ (if (looking-at-p "[[:space:]]*[[{]")
+ (apply #'json-parse-buffer args)
+ (catch 'escape
+ (atomic-change-group
+ (with-syntax-table
+ (let ((st (make-syntax-table)))
+ (modify-syntax-entry ?\" "\"" st)
+ (modify-syntax-entry ?. "_" st)
+ st)
+ (let ((inhibit-read-only t))
+ (save-excursion
+ (insert "[")
+ (forward-sexp 1)
+ (insert "]"))))
+ (throw 'escape (elt (apply #'json-parse-buffer args) 0))))))
+
+;;;; xfaces.c
+
+(compat-defun color-values-from-color-spec (spec)
+ "Parse color SPEC as a numeric color and return (RED GREEN BLUE).
+This function recognises the following formats for SPEC:
+
+ #RGB, where R, G and B are hex numbers of equal length, 1-4 digits each.
+ rgb:R/G/B, where R, G, and B are hex numbers, 1-4 digits each.
+ rgbi:R/G/B, where R, G and B are floating-point numbers in [0,1].
+
+If SPEC is not in one of the above forms, return nil.
+
+Each of the 3 integer members of the resulting list, RED, GREEN,
+and BLUE, is normalized to have its value in [0,65535]."
+ (let ((case-fold-search nil))
+ (save-match-data
+ (cond
+ ((string-match
+ ;; (rx bos "#"
+ ;; (or (: (group-n 1 (= 1 hex)) (group-n 2 (= 1 hex)) (group-n 3 (= 1 hex)))
+ ;; (: (group-n 1 (= 2 hex)) (group-n 2 (= 2 hex)) (group-n 3 (= 2 hex)))
+ ;; (: (group-n 1 (= 3 hex)) (group-n 2 (= 3 hex)) (group-n 3 (= 3 hex)))
+ ;; (: (group-n 1 (= 4 hex)) (group-n 2 (= 4 hex)) (group-n 3 (= 4 hex))))
+ ;; eos)
+ "\\`#\\(?:\\(?1:[[:xdigit:]]\\{1\\}\\)\\(?2:[[:xdigit:]]\\{1\\}\\)\\(?3:[[:xdigit:]]\\{1\\}\\)\\|\\(?1:[[:xdigit:]]\\{2\\}\\)\\(?2:[[:xdigit:]]\\{2\\}\\)\\(?3:[[:xdigit:]]\\{2\\}\\)\\|\\(?1:[[:xdigit:]]\\{3\\}\\)\\(?2:[[:xdigit:]]\\{3\\}\\)\\(?3:[[:xdigit:]]\\{3\\}\\)\\|\\(?1:[[:xdigit:]]\\{4\\}\\)\\(?2:[[:xdigit:]]\\{4\\}\\)\\(?3:[[:xdigit:]]\\{4\\}\\)\\)\\'"
+ spec)
+ (let ((max (1- (ash 1 (* (- (match-end 1) (match-beginning 1)) 4)))))
+ (list (/ (* (string-to-number (match-string 1 spec) 16) 65535) max)
+ (/ (* (string-to-number (match-string 2 spec) 16) 65535) max)
+ (/ (* (string-to-number (match-string 3 spec) 16) 65535) max))))
+ ((string-match
+ ;; (rx bos "rgb:"
+ ;; (group (** 1 4 hex)) "/"
+ ;; (group (** 1 4 hex)) "/"
+ ;; (group (** 1 4 hex))
+ ;; eos)
+ "\\`rgb:\\([[:xdigit:]]\\{1,4\\}\\)/\\([[:xdigit:]]\\{1,4\\}\\)/\\([[:xdigit:]]\\{1,4\\}\\)\\'"
+ spec)
+ (list (/ (* (string-to-number (match-string 1 spec) 16) 65535)
+ (1- (ash 1 (* (- (match-end 1) (match-beginning 1)) 4))))
+ (/ (* (string-to-number (match-string 2 spec) 16) 65535)
+ (1- (ash 1 (* (- (match-end 2) (match-beginning 2)) 4))))
+ (/ (* (string-to-number (match-string 3 spec) 16) 65535)
+ (1- (ash 1 (* (- (match-end 3) (match-beginning 3)) 4))))))
+ ;; The "RGBi" (RGB Intensity) specification is defined by
+ ;; XCMS[0], see [1] for the implementation in Xlib.
+ ;;
+ ;; [0] http://www.nic.funet.fi/pub/X11/X11R4/DOCS/color/Xcms.text
+ ;; [1] https://gitlab.freedesktop.org/xorg/lib/libx11/-/blob/master/src/xcms/LRGB.c#L1392
+ ((string-match
+ (rx bos "rgbi:" (* space)
+ (group (? (or "-" "+"))
+ (or (: (+ digit) (? "." (* digit)))
+ (: "." (+ digit)))
+ (? "e" (? (or "-" "+")) (+ digit)))
+ "/" (* space)
+ (group (? (or "-" "+"))
+ (or (: (+ digit) (? "." (* digit)))
+ (: "." (+ digit)))
+ (? "e" (? (or "-" "+")) (+ digit)))
+ "/" (* space)
+ (group (? (or "-" "+"))
+ (or (: (+ digit) (? "." (* digit)))
+ (: "." (+ digit)))
+ (? "e" (? (or "-" "+")) (+ digit)))
+ eos)
+ spec)
+ (let ((r (round (* (string-to-number (match-string 1 spec)) 65535)))
+ (g (round (* (string-to-number (match-string 2 spec)) 65535)))
+ (b (round (* (string-to-number (match-string 3 spec)) 65535))))
+ (when (and (<= 0 r) (<= r 65535)
+ (<= 0 g) (<= g 65535)
+ (<= 0 b) (<= b 65535))
+ (list r g b))))))))
+
+;;;; Defined in subr.el
+
+;;* INCOMPLETE FEATURE: Should handle multibyte regular expressions
+(compat-defun string-replace (fromstring tostring instring)
+ "Replace FROMSTRING with TOSTRING in INSTRING each time it occurs."
+ (when (equal fromstring "")
+ (signal 'wrong-length-argument '(0)))
+ (let ((case-fold-search nil))
+ (replace-regexp-in-string
+ (regexp-quote fromstring)
+ tostring instring
+ t t)))
+
+(compat-defun always (&rest _arguments)
+ "Do nothing and return t.
+This function accepts any number of ARGUMENTS, but ignores them.
+Also see `ignore'."
+ t)
+
+;;* UNTESTED
+(compat-defun insert-into-buffer (buffer &optional start end)
+ "Insert the contents of the current buffer into BUFFER.
+If START/END, only insert that region from the current buffer.
+Point in BUFFER will be placed after the inserted text."
+ (let ((current (current-buffer)))
+ (with-current-buffer buffer
+ (insert-buffer-substring current start end))))
+
+;;* UNTESTED
+(compat-defun replace-string-in-region (string replacement &optional start end)
+ "Replace STRING with REPLACEMENT in the region from START to END.
+The number of replaced occurrences are returned, or nil if STRING
+doesn't exist in the region.
+
+If START is nil, use the current point. If END is nil, use `point-max'.
+
+Comparisons and replacements are done with fixed case."
+ (if start
+ (when (< start (point-min))
+ (error "Start before start of buffer"))
+ (setq start (point)))
+ (if end
+ (when (> end (point-max))
+ (error "End after end of buffer"))
+ (setq end (point-max)))
+ (save-excursion
+ (let ((matches 0)
+ (case-fold-search nil))
+ (goto-char start)
+ (while (search-forward string end t)
+ (delete-region (match-beginning 0) (match-end 0))
+ (insert replacement)
+ (setq matches (1+ matches)))
+ (and (not (zerop matches))
+ matches))))
+
+;;* UNTESTED
+(compat-defun replace-regexp-in-region (regexp replacement &optional start end)
+ "Replace REGEXP with REPLACEMENT in the region from START to END.
+The number of replaced occurrences are returned, or nil if REGEXP
+doesn't exist in the region.
+
+If START is nil, use the current point. If END is nil, use `point-max'.
+
+Comparisons and replacements are done with fixed case.
+
+REPLACEMENT can use the following special elements:
+
+ `\\&' in NEWTEXT means substitute original matched text.
+ `\\N' means substitute what matched the Nth `\\(...\\)'.
+ If Nth parens didn't match, substitute nothing.
+ `\\\\' means insert one `\\'.
+ `\\?' is treated literally."
+ (if start
+ (when (< start (point-min))
+ (error "Start before start of buffer"))
+ (setq start (point)))
+ (if end
+ (when (> end (point-max))
+ (error "End after end of buffer"))
+ (setq end (point-max)))
+ (save-excursion
+ (let ((matches 0)
+ (case-fold-search nil))
+ (goto-char start)
+ (while (re-search-forward regexp end t)
+ (replace-match replacement t)
+ (setq matches (1+ matches)))
+ (and (not (zerop matches))
+ matches))))
+
+;;* UNTESTED
+(compat-defun buffer-local-boundp (symbol buffer)
+ "Return non-nil if SYMBOL is bound in BUFFER.
+Also see `local-variable-p'."
+ (catch 'fail
+ (condition-case nil
+ (buffer-local-value symbol buffer)
+ (void-variable nil (throw 'fail nil)))
+ t))
+
+;;* UNTESTED
+(compat-defmacro with-existing-directory (&rest body)
+ "Execute BODY with `default-directory' bound to an existing directory.
+If `default-directory' is already an existing directory, it's not changed."
+ (declare (indent 0) (debug t))
+ (let ((quit (make-symbol "with-existing-directory-quit")))
+ `(catch ',quit
+ (dolist (dir (list default-directory
+ (expand-file-name "~/")
+ (getenv "TMPDIR")
+ "/tmp/"
+ ;; XXX: check if "/" works on non-POSIX
+ ;; system.
+ "/"))
+ (when (and dir (file-exists-p dir))
+ (throw ',quit (let ((default-directory dir))
+ ,@body)))))))
+
+;;* UNTESTED
+(compat-defmacro dlet (binders &rest body)
+ "Like `let' but using dynamic scoping."
+ (declare (indent 1) (debug let))
+ `(let (_)
+ ,@(mapcar (lambda (binder)
+ `(defvar ,(if (consp binder) (car binder) binder)))
+ binders)
+ (let ,binders ,@body)))
+
+(compat-defun ensure-list (object)
+ "Return OBJECT as a list.
+If OBJECT is already a list, return OBJECT itself. If it's
+not a list, return a one-element list containing OBJECT."
+ (if (listp object)
+ object
+ (list object)))
+
+;;;; Defined in subr-x.el
+
+(compat-defun string-clean-whitespace (string)
+ "Clean up whitespace in STRING.
+All sequences of whitespaces in STRING are collapsed into a
+single space character, and leading/trailing whitespace is
+removed."
+ :feature 'subr-x
+ (let ((blank "[[:blank:]\r\n]+"))
+ (replace-regexp-in-string
+ "^[[:blank:]\r\n]+\\|[[:blank:]\r\n]+$"
+ ""
+ (replace-regexp-in-string
+ blank " " string))))
+
+(compat-defun string-fill (string length)
+ "Clean up whitespace in STRING.
+All sequences of whitespaces in STRING are collapsed into a
+single space character, and leading/trailing whitespace is
+removed."
+ :feature 'subr-x
+ (with-temp-buffer
+ (insert string)
+ (goto-char (point-min))
+ (let ((fill-column length)
+ (adaptive-fill-mode nil))
+ (fill-region (point-min) (point-max)))
+ (buffer-string)))
+
+(compat-defun string-lines (string &optional omit-nulls)
+ "Split STRING into a list of lines.
+If OMIT-NULLS, empty lines will be removed from the results."
+ :feature 'subr-x
+ (split-string string "\n" omit-nulls))
+
+(compat-defun string-pad (string length &optional padding start)
+ "Pad STRING to LENGTH using PADDING.
+If PADDING is nil, the space character is used. If not nil, it
+should be a character.
+
+If STRING is longer than the absolute value of LENGTH, no padding
+is done.
+
+If START is nil (or not present), the padding is done to the end
+of the string, and if non-nil, padding is done to the start of
+the string."
+ :feature 'subr-x
+ (unless (natnump length)
+ (signal 'wrong-type-argument (list 'natnump length)))
+ (let ((pad-length (- length (length string))))
+ (if (< pad-length 0)
+ string
+ (concat (and start
+ (make-string pad-length (or padding ?\s)))
+ string
+ (and (not start)
+ (make-string pad-length (or padding ?\s)))))))
+
+(compat-defun string-chop-newline (string)
+ "Remove the final newline (if any) from STRING."
+ :feature 'subr-x
+ (if (and (>= (length string) 1) (= (aref string (1- (length string))) ?\n))
+ (substring string 0 -1)
+ string))
+
+(compat-defmacro named-let (name bindings &rest body)
+ "Looping construct taken from Scheme.
+Like `let', bind variables in BINDINGS and then evaluate BODY,
+but with the twist that BODY can evaluate itself recursively by
+calling NAME, where the arguments passed to NAME are used
+as the new values of the bound variables in the recursive invocation."
+ :feature 'subr-x
+ (declare (indent 2) (debug (symbolp (&rest (symbolp form)) body)))
+ (let ((fargs (mapcar (lambda (b)
+ (let ((var (if (consp b) (car b) b)))
+ (make-symbol (symbol-name var))))
+ bindings))
+ (aargs (mapcar (lambda (b) (if (consp b) (cadr b))) bindings))
+ rargs)
+ (dotimes (i (length bindings))
+ (let ((b (nth i bindings)))
+ (push (list (if (consp b) (car b) b) (nth i fargs))
+ rargs)
+ (setf (if (consp b) (car b) b)
+ (nth i fargs))))
+ (letrec
+ ((quit (make-symbol "quit")) (self (make-symbol "self"))
+ (total-tco t)
+ (macro (lambda (&rest args)
+ (setq total-tco nil)
+ `(funcall ,self . ,args)))
+ ;; Based on `cl--self-tco':
+ (tco-progn (lambda (exprs)
+ (append
+ (butlast exprs)
+ (list (funcall tco (car (last exprs)))))))
+ (tco (lambda (expr)
+ (cond
+ ((eq (car-safe expr) 'if)
+ (append (list 'if
+ (cadr expr)
+ (funcall tco (nth 2 expr)))
+ (funcall tco-progn (nthcdr 3 expr))))
+ ((eq (car-safe expr) 'cond)
+ (let ((conds (cdr expr)) body)
+ (while conds
+ (let ((branch (pop conds)))
+ (push (cond
+ ((cdr branch) ;has tail
+ (funcall tco-progn branch))
+ ((null conds) ;last element
+ (list t (funcall tco (car branch))))
+ ((progn
+ branch)))
+ body)))
+ (cons 'cond (nreverse body))))
+ ((eq (car-safe expr) 'or)
+ (if (cddr expr)
+ (let ((var (make-symbol "var")))
+ `(let ((,var ,(cadr expr)))
+ (if ,var ,(funcall tco var)
+ ,(funcall tco (cons 'or (cddr expr))))))
+ (funcall tco (cadr expr))))
+ ((eq (car-safe expr) 'condition-case)
+ (append (list 'condition-case (cadr expr) (nth 2 expr))
+ (mapcar
+ (lambda (handler)
+ (cons (car handler)
+ (funcall tco-progn (cdr handler))))
+ (nthcdr 3 expr))))
+ ((memq (car-safe expr) '(and progn))
+ (cons (car expr) (funcall tco-progn (cdr expr))))
+ ((memq (car-safe expr) '(let let*))
+ (append (list (car expr) (cadr expr))
+ (funcall tco-progn (cddr expr))))
+ ((eq (car-safe expr) name)
+ (let (sets (args (cdr expr)))
+ (dolist (farg fargs)
+ (push (list farg (pop args))
+ sets))
+ (cons 'setq (apply #'nconc (nreverse sets)))))
+ (`(throw ',quit ,expr))))))
+ (let ((tco-body (funcall tco (macroexpand-all (macroexp-progn body)))))
+ (when tco-body
+ (setq body `((catch ',quit
+ (while t (let ,rargs ,@(macroexp-unprogn tco-body))))))))
+ (let ((expand (macroexpand-all (macroexp-progn body) (list (cons name macro)))))
+ (if total-tco
+ `(let ,bindings ,expand)
+ `(funcall
+ (letrec ((,self (lambda ,fargs ,expand))) ,self)
+ ,@aargs))))))
+
+;;;; Defined in files.el
+
+(declare-function compat--string-trim-left "compat-26" (string &optional regexp))
+(declare-function compat--directory-name-p "compat-25" (name))
+(compat-defun file-name-with-extension (filename extension)
+ "Set the EXTENSION of a FILENAME.
+The extension (in a file name) is the part that begins with the last \".\".
+
+Trims a leading dot from the EXTENSION so that either \"foo\" or
+\".foo\" can be given.
+
+Errors if the FILENAME or EXTENSION are empty, or if the given
+FILENAME has the format of a directory.
+
+See also `file-name-sans-extension'."
+ (let ((extn (compat--string-trim-left extension "[.]")))
+ (cond
+ ((string= filename "")
+ (error "Empty filename"))
+ ((string= extn "")
+ (error "Malformed extension: %s" extension))
+ ((compat--directory-name-p filename)
+ (error "Filename is a directory: %s" filename))
+ (t
+ (concat (file-name-sans-extension filename) "." extn)))))
+
+;;* UNTESTED
+(compat-defun directory-empty-p (dir)
+ "Return t if DIR names an existing directory containing no other files.
+Return nil if DIR does not name a directory, or if there was
+trouble determining whether DIR is a directory or empty.
+
+Symbolic links to directories count as directories.
+See `file-symlink-p' to distinguish symlinks."
+ (and (file-directory-p dir)
+ (null (directory-files dir nil directory-files-no-dot-files-regexp t))))
+
+(compat-defun file-modes-number-to-symbolic (mode &optional filetype)
+ "Return a string describing a file's MODE.
+For instance, if MODE is #o700, then it produces `-rwx------'.
+FILETYPE if provided should be a character denoting the type of file,
+such as `?d' for a directory, or `?l' for a symbolic link and will override
+the leading `-' char."
+ (string
+ (or filetype
+ (pcase (lsh mode -12)
+ ;; POSIX specifies that the file type is included in st_mode
+ ;; and provides names for the file types but values only for
+ ;; the permissions (e.g., S_IWOTH=2).
+
+ ;; (#o017 ??) ;; #define S_IFMT 00170000
+ (#o014 ?s) ;; #define S_IFSOCK 0140000
+ (#o012 ?l) ;; #define S_IFLNK 0120000
+ ;; (8 ??) ;; #define S_IFREG 0100000
+ (#o006 ?b) ;; #define S_IFBLK 0060000
+ (#o004 ?d) ;; #define S_IFDIR 0040000
+ (#o002 ?c) ;; #define S_IFCHR 0020000
+ (#o001 ?p) ;; #define S_IFIFO 0010000
+ (_ ?-)))
+ (if (zerop (logand 256 mode)) ?- ?r)
+ (if (zerop (logand 128 mode)) ?- ?w)
+ (if (zerop (logand 64 mode))
+ (if (zerop (logand 2048 mode)) ?- ?S)
+ (if (zerop (logand 2048 mode)) ?x ?s))
+ (if (zerop (logand 32 mode)) ?- ?r)
+ (if (zerop (logand 16 mode)) ?- ?w)
+ (if (zerop (logand 8 mode))
+ (if (zerop (logand 1024 mode)) ?- ?S)
+ (if (zerop (logand 1024 mode)) ?x ?s))
+ (if (zerop (logand 4 mode)) ?- ?r)
+ (if (zerop (logand 2 mode)) ?- ?w)
+ (if (zerop (logand 512 mode))
+ (if (zerop (logand 1 mode)) ?- ?x)
+ (if (zerop (logand 1 mode)) ?T ?t))))
+
+;;* UNTESTED
+(compat-defun file-backup-file-names (filename)
+ "Return a list of backup files for FILENAME.
+The list will be sorted by modification time so that the most
+recent files are first."
+ ;; `make-backup-file-name' will get us the right directory for
+ ;; ordinary or numeric backups. It might create a directory for
+ ;; backups as a side-effect, according to `backup-directory-alist'.
+ (let* ((filename (file-name-sans-versions
+ (make-backup-file-name (expand-file-name filename))))
+ (dir (file-name-directory filename))
+ files)
+ (dolist (file (file-name-all-completions
+ (file-name-nondirectory filename) dir))
+ (let ((candidate (concat dir file)))
+ (when (and (backup-file-name-p candidate)
+ (string= (file-name-sans-versions candidate) filename))
+ (push candidate files))))
+ (sort files #'file-newer-than-file-p)))
+
+(compat-defun make-lock-file-name (filename)
+ "Make a lock file name for FILENAME.
+This prepends \".#\" to the non-directory part of FILENAME, and
+doesn't respect `lock-file-name-transforms', as Emacs 28.1 and
+onwards does."
+ (expand-file-name
+ (concat
+ ".#" (file-name-nondirectory filename))
+ (file-name-directory filename)))
+
+;;;; Defined in files-x.el
+
+(declare-function tramp-tramp-file-p "tramp" (name))
+
+;;* UNTESTED
+(compat-defun null-device ()
+ "Return the best guess for the null device."
+ (require 'tramp)
+ (if (tramp-tramp-file-p default-directory)
+ "/dev/null"
+ null-device))
+
+;;;; Defined in minibuffer.el
+
+(compat-defun format-prompt (prompt default &rest format-args)
+ "Format PROMPT with DEFAULT.
+If FORMAT-ARGS is nil, PROMPT is used as a plain string. If
+FORMAT-ARGS is non-nil, PROMPT is used as a format control
+string, and FORMAT-ARGS are the arguments to be substituted into
+it. See `format' for details.
+
+If DEFAULT is a list, the first element is used as the default.
+If not, the element is used as is.
+
+If DEFAULT is nil or an empty string, no \"default value\" string
+is included in the return value."
+ (concat
+ (if (null format-args)
+ prompt
+ (apply #'format prompt format-args))
+ (and default
+ (or (not (stringp default))
+ (not (null default)))
+ (format " (default %s)"
+ (if (consp default)
+ (car default)
+ default)))
+ ": "))
+
+;;;; Defined in windows.el
+
+;;* UNTESTED
+(compat-defun count-windows (&optional minibuf all-frames)
+ "Handle optional argument ALL-FRAMES:
+
+If ALL-FRAMES is non-nil, count the windows in all frames instead
+just the selected frame."
+ :prefix t
+ (if all-frames
+ (let ((sum 0))
+ (dolist (frame (frame-list))
+ (with-selected-frame frame
+ (setq sum (+ (count-windows minibuf) sum))))
+ sum)
+ (count-windows minibuf)))
+
+;;;; Defined in thingatpt.el
+
+(declare-function mouse-set-point "mouse" (event &optional promote-to-region))
+
+;;* UNTESTED
+(compat-defun thing-at-mouse (event thing &optional no-properties)
+ "Return the THING at mouse click.
+Like `thing-at-point', but tries to use the event
+where the mouse button is clicked to find a thing nearby."
+ :feature 'thingatpt
+ (save-excursion
+ (mouse-set-point event)
+ (thing-at-point thing no-properties)))
+
+;;;; Defined in macroexp.el
+
+;;* UNTESTED
+(compat-defun macroexp-file-name ()
+ "Return the name of the file from which the code comes.
+Returns nil when we do not know.
+A non-nil result is expected to be reliable when called from a macro in order
+to find the file in which the macro's call was found, and it should be
+reliable as well when used at the top-level of a file.
+Other uses risk returning non-nil value that point to the wrong file."
+ :feature 'macroexp
+ (let ((file (car (last current-load-list))))
+ (or (if (stringp file) file)
+ (bound-and-true-p byte-compile-current-file))))
+
+;;;; Defined in env.el
+
+;;* UNTESTED
+(compat-defmacro with-environment-variables (variables &rest body)
+ "Set VARIABLES in the environent and execute BODY.
+VARIABLES is a list of variable settings of the form (VAR VALUE),
+where VAR is the name of the variable (a string) and VALUE
+is its value (also a string).
+
+The previous values will be be restored upon exit."
+ (declare (indent 1) (debug (sexp body)))
+ (unless (consp variables)
+ (error "Invalid VARIABLES: %s" variables))
+ `(let ((process-environment (copy-sequence process-environment)))
+ ,@(mapcar (lambda (elem)
+ `(setenv ,(car elem) ,(cadr elem)))
+ variables)
+ ,@body))
+
+;;;; Defined in button.el
+
+;;* UNTESTED
+(compat-defun button-buttonize (string callback &optional data)
+ "Make STRING into a button and return it.
+When clicked, CALLBACK will be called with the DATA as the
+function argument. If DATA isn't present (or is nil), the button
+itself will be used instead as the function argument."
+ :feature 'button
+ (propertize string
+ 'face 'button
+ 'button t
+ 'follow-link t
+ 'category t
+ 'button-data data
+ 'keymap button-map
+ 'action callback))
+
+;;;; Defined in autoload.el
+
+(defvar generated-autoload-file)
+
+;;* UNTESTED
+(compat-defun make-directory-autoloads (dir output-file)
+ "Update autoload definitions for Lisp files in the directories DIRS.
+DIR can be either a single directory or a list of
+directories. (The latter usage is discouraged.)
+
+The autoloads will be written to OUTPUT-FILE. If any Lisp file
+binds `generated-autoload-file' as a file-local variable, write
+its autoloads into the specified file instead.
+
+The function does NOT recursively descend into subdirectories of the
+directory or directories specified."
+ (let ((generated-autoload-file output-file))
+ ;; We intentionally don't sharp-quote
+ ;; `update-directory-autoloads', because it was deprecated in
+ ;; Emacs 28 and we don't want to trigger the byte compiler for
+ ;; newer versions.
+ (apply 'update-directory-autoloads
+ (if (listp dir) dir (list dir)))))
+
+(provide 'compat-28)
+;;; compat-28.el ends here
diff --git a/elpa/compat-28.1.1.0/compat-28.elc b/elpa/compat-28.1.1.0/compat-28.elc
new file mode 100644
index 0000000..42f0b5a
--- /dev/null
+++ b/elpa/compat-28.1.1.0/compat-28.elc
Binary files differ
diff --git a/elpa/compat-28.1.1.0/compat-autoloads.el b/elpa/compat-28.1.1.0/compat-autoloads.el
new file mode 100644
index 0000000..4eb6cfb
--- /dev/null
+++ b/elpa/compat-28.1.1.0/compat-autoloads.el
@@ -0,0 +1,35 @@
+;;; compat-autoloads.el --- automatically extracted autoloads -*- lexical-binding: t -*-
+;;
+;;; Code:
+
+(add-to-list 'load-path (directory-file-name
+ (or (file-name-directory #$) (car load-path))))
+
+
+;;;### (autoloads nil "compat-help" "compat-help.el" (0 0 0 0))
+;;; Generated autoloads from compat-help.el
+
+(register-definition-prefixes "compat-help" '("compat---describe"))
+
+;;;***
+
+;;;### (autoloads nil "compat-macs" "compat-macs.el" (0 0 0 0))
+;;; Generated autoloads from compat-macs.el
+
+(register-definition-prefixes "compat-macs" '("compat-"))
+
+;;;***
+
+;;;### (autoloads nil nil ("compat-24.el" "compat-25.el" "compat-26.el"
+;;;;;; "compat-27.el" "compat-28.el" "compat-font-lock.el" "compat-pkg.el"
+;;;;;; "compat.el") (0 0 0 0))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; coding: utf-8
+;; End:
+;;; compat-autoloads.el ends here
diff --git a/elpa/compat-28.1.1.0/compat-font-lock.el b/elpa/compat-28.1.1.0/compat-font-lock.el
new file mode 100644
index 0000000..66a62e5
--- /dev/null
+++ b/elpa/compat-28.1.1.0/compat-font-lock.el
@@ -0,0 +1,48 @@
+;;; compat-font-lock.el --- -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2022 Free Software Foundation, Inc.
+
+;; Author: Philip Kaludercic <philipk@posteo.net>
+;; Keywords:
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Optional font-locking for `compat' definitions. Every symbol with
+;; an active compatibility definition will be highlighted.
+;;
+;; Load this file to enable the functionality.
+
+;;; Code:
+
+(eval-and-compile
+ (require 'cl-lib)
+ (require 'compat-macs))
+
+(defvar compat-generate-common-fn)
+(let ((compat-generate-common-fn
+ (lambda (name _def-fn _install-fn check-fn attr _type)
+ (unless (and (plist-get attr :no-highlight)
+ (funcall check-fn))
+ `(font-lock-add-keywords
+ 'emacs-lisp-mode
+ ',`((,(concat "\\_<\\("
+ (regexp-quote (symbol-name name))
+ "\\)\\_>")
+ 1 font-lock-preprocessor-face prepend)))))))
+ (load "compat"))
+
+(provide 'compat-font-lock)
+;;; compat-font-lock.el ends here
diff --git a/elpa/compat-28.1.1.0/compat-font-lock.elc b/elpa/compat-28.1.1.0/compat-font-lock.elc
new file mode 100644
index 0000000..15c6315
--- /dev/null
+++ b/elpa/compat-28.1.1.0/compat-font-lock.elc
Binary files differ
diff --git a/elpa/compat-28.1.1.0/compat-help.el b/elpa/compat-28.1.1.0/compat-help.el
new file mode 100644
index 0000000..440e35f
--- /dev/null
+++ b/elpa/compat-28.1.1.0/compat-help.el
@@ -0,0 +1,57 @@
+;;; compat-help.el --- Documentation for compat functions -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2022 Free Software Foundation, Inc.
+
+;; Author: Philip Kaludercic <philipk@posteo.net>
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Load this file to insert `compat'-relevant documentation next to
+;; the regular documentation of a symbol.
+
+;;; Code:
+
+(defun compat---describe (symbol)
+ "Insert documentation for SYMBOL if it has compatibility code."
+ (let ((compat (get symbol 'compat-def)))
+ (when compat
+ (let ((doc (get compat 'compat-doc))
+ (start (point)))
+ (when doc
+ (insert "There is a ")
+ (insert-button
+ "compatibility notice"
+ 'action (let ((type (get compat 'compat-type)))
+ (cond
+ ((memq type '(func macro advice))
+ #'find-function)
+ ((memq type '(variable))
+ #'find-variable)
+ ((error "Unknown type"))))
+ 'button-data compat)
+ (insert (format " for %s (for versions of Emacs before %s):"
+ (symbol-name symbol)
+ (get compat 'compat-version)))
+ (add-text-properties start (point) '(face bold))
+ (newline 2)
+ (insert (substitute-command-keys doc))
+ (fill-region start (point))
+ (newline 2))))))
+
+(add-hook 'help-fns-describe-function-functions #'compat---describe)
+
+(provide 'compat-help)
+;;; compat-help.el ends here
diff --git a/elpa/compat-28.1.1.0/compat-help.elc b/elpa/compat-28.1.1.0/compat-help.elc
new file mode 100644
index 0000000..a8f0ff7
--- /dev/null
+++ b/elpa/compat-28.1.1.0/compat-help.elc
Binary files differ
diff --git a/elpa/compat-28.1.1.0/compat-macs.el b/elpa/compat-28.1.1.0/compat-macs.el
new file mode 100644
index 0000000..e1dcf81
--- /dev/null
+++ b/elpa/compat-28.1.1.0/compat-macs.el
@@ -0,0 +1,367 @@
+;;; compat-macs.el --- Compatibility Macros -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2021, 2022 Free Software Foundation, Inc.
+
+;; Author: Philip Kaludercic <philipk@posteo.net>
+;; Keywords: lisp
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; These macros are used to define compatibility functions, macros and
+;; advice.
+
+;;; Code:
+
+(defmacro compat--ignore (&rest _)
+ "Ignore all arguments."
+ nil)
+
+(defvar compat--generate-function #'compat--generate-minimal
+ "Function used to generate compatibility code.
+The function must take six arguments: NAME, DEF-FN, INSTALL-FN,
+CHECK-FN, ATTR and TYPE. The resulting body is constructed by
+invoking the functions DEF-FN (passed the \"realname\" and the
+version number, returning the compatibility definition), the
+INSTALL-FN (passed the \"realname\" and returning the
+installation code), CHECK-FN (passed the \"realname\" and
+returning a check to see if the compatibility definition should
+be installed). ATTR is a plist used to modify the generated
+code. The following attributes are handled, all others are
+ignored:
+
+- :min-version :: Prevent the compatibility definition from begin
+ installed in versions older than indicated (string).
+
+- :max-version :: Prevent the compatibility definition from begin
+ installed in versions newer than indicated (string).
+
+- :feature :: The library the code is supposed to be loaded
+ with (via `eval-after-load').
+
+- :cond :: Only install the compatibility code, iff the value
+ evaluates to non-nil.
+
+ For prefixed functions, this can be interpreted as a test to
+ `defalias' an existing definition or not.
+
+- :no-highlight :: Do not highlight this definition as
+ compatibility function.
+
+- :version :: Manual specification of the version the compatee
+ code was defined in (string).
+
+- :realname :: Manual specification of a \"realname\" to use for
+ the compatibility definition (symbol).
+
+- :notes :: Additional notes that a developer using this
+ compatibility function should keep in mind.
+
+- :prefix :: Add a `compat-' prefix to the name, and define the
+ compatibility code unconditionally.
+
+TYPE is used to set the symbol property `compat-type' for NAME.")
+
+(defun compat--generate-minimal (name def-fn install-fn check-fn attr type)
+ "Generate a leaner compatibility definition.
+See `compat-generate-function' for details on the arguments NAME,
+DEF-FN, INSTALL-FN, CHECK-FN, ATTR and TYPE."
+ (let* ((min-version (plist-get attr :min-version))
+ (max-version (plist-get attr :max-version))
+ (feature (plist-get attr :feature))
+ (cond (plist-get attr :cond))
+ (version (or (plist-get attr :version)
+ (let ((file (or (bound-and-true-p byte-compile-current-file)
+ load-file-name
+ (buffer-file-name))))
+ ;; Guess the version from the file the macro is
+ ;; being defined in.
+ (cond
+ ((not file) emacs-version)
+ ((string-match
+ "compat-\\([[:digit:]]+\\)\\.\\(?:elc?\\)\\'"
+ file)
+ (match-string 1 file))
+ ((error "No version number could be extracted"))))))
+ (realname (or (plist-get attr :realname)
+ (intern (format "compat--%S" name))))
+ (check (cond
+ ((or (and min-version
+ (version< emacs-version min-version))
+ (and max-version
+ (version< max-version emacs-version)))
+ '(compat--ignore))
+ ((plist-get attr :prefix)
+ '(progn))
+ ((and version (version<= version emacs-version) (not cond))
+ '(compat--ignore))
+ (`(when (and ,(if cond cond t)
+ ,(funcall check-fn)))))))
+ (cond
+ ((and (plist-get attr :prefix) (memq type '(func macro))
+ (string-match "\\`compat-\\(.+\\)\\'" (symbol-name name))
+ (let* ((actual-name (intern (match-string 1 (symbol-name name))))
+ (body (funcall install-fn actual-name version)))
+ (when (and (version<= version emacs-version)
+ (fboundp actual-name))
+ `(,@check
+ ,(if feature
+ ;; See https://nullprogram.com/blog/2018/02/22/:
+ `(eval-after-load ,feature `(funcall ',(lambda () ,body)))
+ body))))))
+ ((plist-get attr :realname)
+ `(progn
+ ,(funcall def-fn realname version)
+ (,@check
+ ,(let ((body (funcall install-fn realname version)))
+ (if feature
+ ;; See https://nullprogram.com/blog/2018/02/22/:
+ `(eval-after-load ,feature `(funcall ',(lambda () ,body)))
+ body)))))
+ ((let* ((body (if (eq type 'advice)
+ `(,@check
+ ,(funcall def-fn realname version)
+ ,(funcall install-fn realname version))
+ `(,@check ,(funcall def-fn name version)))))
+ (if feature
+ ;; See https://nullprogram.com/blog/2018/02/22/:
+ `(eval-after-load ,feature `(funcall ',(lambda () ,body)))
+ body))))))
+
+(defun compat--generate-minimal-no-prefix (name def-fn install-fn check-fn attr type)
+ "Generate a leaner compatibility definition.
+See `compat-generate-function' for details on the arguments NAME,
+DEF-FN, INSTALL-FN, CHECK-FN, ATTR and TYPE."
+ (unless (plist-get attr :prefix)
+ (compat--generate-minimal name def-fn install-fn check-fn attr type)))
+
+(defun compat--generate-verbose (name def-fn install-fn check-fn attr type)
+ "Generate a more verbose compatibility definition, fit for testing.
+See `compat-generate-function' for details on the arguments NAME,
+DEF-FN, INSTALL-FN, CHECK-FN, ATTR and TYPE."
+ (let* ((min-version (plist-get attr :min-version))
+ (max-version (plist-get attr :max-version))
+ (feature (plist-get attr :feature))
+ (cond (plist-get attr :cond))
+ (version (or (plist-get attr :version)
+ (let ((file (or (bound-and-true-p byte-compile-current-file)
+ load-file-name
+ (buffer-file-name))))
+ ;; Guess the version from the file the macro is
+ ;; being defined in.
+ (cond
+ ((not file) emacs-version)
+ ((string-match
+ "compat-\\([[:digit:]]+\\)\\.\\(?:elc?\\)\\'"
+ file)
+ (match-string 1 file))
+ ((error "No version number could be extracted"))))))
+ (realname (or (plist-get attr :realname)
+ (intern (format "compat--%S" name))))
+ (body `(progn
+ (unless (or (null (get ',name 'compat-def))
+ (eq (get ',name 'compat-def) ',realname))
+ (error "Duplicate compatibility definition: %s (was %s, now %s)"
+ ',name (get ',name 'compat-def) ',realname))
+ (put ',name 'compat-def ',realname)
+ ,(funcall install-fn realname version))))
+ `(progn
+ (put ',realname 'compat-type ',type)
+ (put ',realname 'compat-version ,version)
+ (put ',realname 'compat-min-version ,min-version)
+ (put ',realname 'compat-max-version ,max-version)
+ (put ',realname 'compat-doc ,(plist-get attr :note))
+ ,(funcall def-fn realname version)
+ (,@(cond
+ ((or (and min-version
+ (version< emacs-version min-version))
+ (and max-version
+ (version< max-version emacs-version)))
+ '(compat--ignore))
+ ((plist-get attr :prefix)
+ '(progn))
+ ((and version (version<= version emacs-version) (not cond))
+ '(compat--ignore))
+ (`(when (and ,(if cond cond t)
+ ,(funcall check-fn)))))
+ ,(if feature
+ ;; See https://nullprogram.com/blog/2018/02/22/:
+ `(eval-after-load ,feature `(funcall ',(lambda () ,body)))
+ body)))))
+
+(defun compat-generate-common (name def-fn install-fn check-fn attr type)
+ "Common code for generating compatibility definitions.
+See `compat-generate-function' for details on the arguments NAME,
+DEF-FN, INSTALL-FN, CHECK-FN, ATTR and TYPE."
+ (when (and (plist-get attr :cond) (plist-get attr :prefix))
+ (error "A prefixed function %s cannot have a condition" name))
+ (funcall compat--generate-function
+ name def-fn install-fn check-fn attr type))
+
+(defun compat-common-fdefine (type name arglist docstring rest)
+ "Generate compatibility code for a function NAME.
+TYPE is one of `func', for functions and `macro' for macros, and
+`advice' ARGLIST is passed on directly to the definition, and
+DOCSTRING is prepended with a compatibility note. REST contains
+the remaining definition, that may begin with a property list of
+attributes (see `compat-generate-common')."
+ (let ((oldname name) (body rest))
+ (while (keywordp (car body))
+ (setq body (cddr body)))
+ ;; It might be possible to set these properties otherwise. That
+ ;; should be looked into and implemented if it is the case.
+ (when (and (listp (car-safe body)) (eq (caar body) 'declare))
+ (when (version<= emacs-version "25")
+ (delq (assq 'side-effect-free (car body)) (car body))
+ (delq (assq 'pure (car body)) (car body))))
+ ;; Check if we want an explicitly prefixed function
+ (when (plist-get rest :prefix)
+ (setq name (intern (format "compat-%s" name))))
+ (compat-generate-common
+ name
+ (lambda (realname version)
+ `(,(cond
+ ((memq type '(func advice)) 'defun)
+ ((eq type 'macro) 'defmacro)
+ ((error "Unknown type")))
+ ,realname ,arglist
+ ;; Prepend compatibility notice to the actual
+ ;; documentation string.
+ ,(let ((type (cond
+ ((eq type 'func) "function")
+ ((eq type 'macro) "macro")
+ ((eq type 'advice) "advice")
+ ((error "Unknown type")))))
+ (if version
+ (format
+ "[Compatibility %s for `%S', defined in Emacs %s]\n\n%s"
+ type oldname version docstring)
+ (format
+ "[Compatibility %s for `%S']\n\n%s"
+ type oldname docstring)))
+ ;; Advice may use the implicit variable `oldfun', but
+ ;; to avoid triggering the byte compiler, we make
+ ;; sure the argument is used at least once.
+ ,@(if (eq type 'advice)
+ (cons '(ignore oldfun) body)
+ body)))
+ (lambda (realname _version)
+ (cond
+ ((memq type '(func macro))
+ ;; Functions and macros are installed by
+ ;; aliasing the name of the compatible
+ ;; function to the name of the compatibility
+ ;; function.
+ `(defalias ',name #',realname))
+ ((eq type 'advice)
+ `(advice-add ',name :around #',realname))))
+ (lambda ()
+ (cond
+ ((memq type '(func macro))
+ `(not (fboundp ',name)))
+ ((eq type 'advice) t)))
+ rest type)))
+
+(defmacro compat-defun (name arglist docstring &rest rest)
+ "Define NAME with arguments ARGLIST as a compatibility function.
+The function must be documented in DOCSTRING. REST may begin
+with a plist, that is interpreted by the macro but not passed on
+to the actual function. See `compat-generate-common' for a
+listing of attributes.
+
+The definition will only be installed, if the version this
+function was defined in, as indicated by the `:version'
+attribute, is greater than the current Emacs version."
+ (declare (debug (&define name (&rest symbolp)
+ stringp
+ [&rest keywordp sexp]
+ def-body))
+ (doc-string 3) (indent 2))
+ (compat-common-fdefine 'func name arglist docstring rest))
+
+(defmacro compat-defmacro (name arglist docstring &rest rest)
+ "Define NAME with arguments ARGLIST as a compatibility macro.
+The macro must be documented in DOCSTRING. REST may begin
+with a plist, that is interpreted by this macro but not passed on
+to the actual macro. See `compat-generate-common' for a
+listing of attributes.
+
+The definition will only be installed, if the version this
+function was defined in, as indicated by the `:version'
+attribute, is greater than the current Emacs version."
+ (declare (debug compat-defun) (doc-string 3) (indent 2))
+ (compat-common-fdefine 'macro name arglist docstring rest))
+
+(defmacro compat-advise (name arglist docstring &rest rest)
+ "Define NAME with arguments ARGLIST as a compatibility advice.
+The advice function must be documented in DOCSTRING. REST may
+begin with a plist, that is interpreted by this macro but not
+passed on to the actual advice function. See
+`compat-generate-common' for a listing of attributes. The advice
+wraps the old definition, that is accessible via using the symbol
+`oldfun'.
+
+The advice will only be installed, if the version this function
+was defined in, as indicated by the `:version' attribute, is
+greater than the current Emacs version."
+ (declare (debug compat-defun) (doc-string 3) (indent 2))
+ (compat-common-fdefine 'advice name (cons 'oldfun arglist) docstring rest))
+
+(defmacro compat-defvar (name initval docstring &rest attr)
+ "Declare compatibility variable NAME with initial value INITVAL.
+The obligatory documentation string DOCSTRING must be given.
+
+The remaining arguments ATTR form a plist, modifying the
+behaviour of this macro. See `compat-generate-common' for a
+listing of attributes. Furthermore, `compat-defvar' also handles
+the attribute `:local' that either makes the variable permanent
+local with a value of `permanent' or just buffer local with any
+non-nil value."
+ (declare (debug (name form stringp [&rest keywordp sexp]))
+ (doc-string 3) (indent 2))
+ ;; Check if we want an explicitly prefixed function
+ (let ((oldname name))
+ (when (plist-get attr :prefix)
+ (setq name (intern (format "compat-%s" name))))
+ (compat-generate-common
+ name
+ (lambda (realname version)
+ (let ((localp (plist-get attr :local)))
+ `(progn
+ (,(if (plist-get attr :constant) 'defconst 'defvar)
+ ,realname ,initval
+ ;; Prepend compatibility notice to the actual
+ ;; documentation string.
+ ,(if version
+ (format
+ "[Compatibility variable for `%S', defined in Emacs %s]\n\n%s"
+ oldname version docstring)
+ (format
+ "[Compatibility variable for `%S']\n\n%s"
+ oldname docstring)))
+ ;; Make variable as local if necessary
+ ,(cond
+ ((eq localp 'permanent)
+ `(put ',realname 'permanent-local t))
+ (localp
+ `(make-variable-buffer-local ',realname))))))
+ (lambda (realname _version)
+ `(defvaralias ',name ',realname))
+ (lambda ()
+ `(not (boundp ',name)))
+ attr 'variable)))
+
+(provide 'compat-macs)
+;;; compat-macs.el ends here
diff --git a/elpa/compat-28.1.1.0/compat-macs.elc b/elpa/compat-28.1.1.0/compat-macs.elc
new file mode 100644
index 0000000..a3d823d
--- /dev/null
+++ b/elpa/compat-28.1.1.0/compat-macs.elc
Binary files differ
diff --git a/elpa/compat-28.1.1.0/compat-pkg.el b/elpa/compat-28.1.1.0/compat-pkg.el
new file mode 100644
index 0000000..fe45402
--- /dev/null
+++ b/elpa/compat-28.1.1.0/compat-pkg.el
@@ -0,0 +1,2 @@
+;; Generated package description from compat.el -*- no-byte-compile: t -*-
+(define-package "compat" "28.1.1.0" "Compatibility Library" '((emacs "24.3") (nadvice "0.3")) :commit "401df6defaf5ef470a2dc57664b2d258662a5c3d" :authors '(("Philip Kaludercic" . "philipk@posteo.net")) :maintainer '("Compat Development" . "~pkal/compat-devel@lists.sr.ht") :keywords '("lisp") :url "https://sr.ht/~pkal/compat")
diff --git a/elpa/compat-28.1.1.0/compat.el b/elpa/compat-28.1.1.0/compat.el
new file mode 100644
index 0000000..d31cff1
--- /dev/null
+++ b/elpa/compat-28.1.1.0/compat.el
@@ -0,0 +1,99 @@
+;;; compat.el --- Compatibility Library -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2021, 2022 Free Software Foundation, Inc.
+
+;; Author: Philip Kaludercic <philipk@posteo.net>
+;; Maintainer: Compat Development <~pkal/compat-devel@lists.sr.ht>
+;; Version: 28.1.1.0
+;; URL: https://sr.ht/~pkal/compat
+;; Package-Requires: ((emacs "24.3") (nadvice "0.3"))
+;; Keywords: lisp
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; To allow for the usage of Emacs functions and macros that are
+;; defined in newer versions of Emacs, compat.el provides definitions
+;; that are installed ONLY if necessary. These reimplementations of
+;; functions and macros are at least subsets of the actual
+;; implementations. Be sure to read the documentation string to make
+;; sure.
+;;
+;; Not every function provided in newer versions of Emacs is provided
+;; here. Some depend on new features from the core, others cannot be
+;; implemented to a meaningful degree. The main audience for this
+;; library are not regular users, but package maintainers. Therefore
+;; commands and user options are usually not implemented here.
+
+;;; Code:
+
+(eval-when-compile (require 'compat-macs))
+
+;;;; Core functionality
+
+;; To accelerate the loading process, we insert the contents of
+;; compat-N.M.el directly into the compat.elc. Note that by default
+;; this will not include prefix functions. These have to be required
+;; separately, by explicitly requiring the feature that defines them.
+(eval-when-compile
+ (defvar compat--generate-function)
+ (defmacro compat-entwine (version)
+ (cond
+ ((or (not (eq compat--generate-function 'compat--generate-minimal))
+ (bound-and-true-p compat-testing))
+ `(load ,(format "compat-%d.el" version)))
+ ((let* ((compat--generate-function 'compat--generate-minimal-no-prefix)
+ (file (expand-file-name
+ (format "compat-%d.el" version)
+ (file-name-directory
+ (or (if (fboundp 'macroexp-file-name)
+ (macroexp-file-name)
+ (or (bound-and-true-p byte-compile-current-file)
+ load-file-name))
+ (buffer-file-name)))))
+ defs)
+ (with-temp-buffer
+ (insert-file-contents file)
+ (emacs-lisp-mode)
+ (while (progn
+ (forward-comment 1)
+ (not (eobp)))
+ ;; We bind `byte-compile-current-file' before
+ ;; macro-expanding, so that `compat--generate-function'
+ ;; can correctly infer the compatibility version currently
+ ;; being processed.
+ (let ((byte-compile-current-file file)
+ (form (read (current-buffer))))
+ (cond
+ ((memq (car-safe form)
+ '(compat-defun
+ compat-defmacro
+ compat-advise
+ compat-defvar))
+ (push (macroexpand-all form) defs))
+ ((memq (car-safe form)
+ '(declare-function
+ defvar))
+ (push form defs))))))
+ (macroexp-progn (nreverse defs)))))))
+
+(compat-entwine 24)
+(compat-entwine 25)
+(compat-entwine 26)
+(compat-entwine 27)
+(compat-entwine 28)
+
+(provide 'compat)
+;;; compat.el ends here
diff --git a/elpa/compat-28.1.1.0/compat.elc b/elpa/compat-28.1.1.0/compat.elc
new file mode 100644
index 0000000..e10f0c4
--- /dev/null
+++ b/elpa/compat-28.1.1.0/compat.elc
Binary files differ
diff --git a/elpa/compat-28.1.1.0/compat.info b/elpa/compat-28.1.1.0/compat.info
new file mode 100644
index 0000000..c645881
--- /dev/null
+++ b/elpa/compat-28.1.1.0/compat.info
@@ -0,0 +1,1110 @@
+This is compat.info, produced by makeinfo version 6.7 from compat.texi.
+
+Copyright © 2022 Free Software Foundation, Inc.
+
+ Permission is granted to copy, distribute and/or modify this
+ document under the terms of the GNU Free Documentation License,
+ Version 1.3 or any later version published by the Free Software
+ Foundation; with no Invariant Sections, with the Front-Cover Texts
+ being “A GNU Manual,” and with the Back-Cover Texts as in (a)
+ below. A copy of the license is included in the section entitled
+ “GNU Free Documentation License.”
+
+ (a) The FSF’s Back-Cover Text is: “You have the freedom to copy and
+ modify this GNU manual.”
+
+INFO-DIR-SECTION Emacs
+START-INFO-DIR-ENTRY
+* Compat: (compat). Compatibility Library for Emacs Lisp.
+END-INFO-DIR-ENTRY
+
+
+File: compat.info, Node: Top, Next: Introduction, Up: (dir)
+
+"Compat" Manual
+***************
+
+This manual documents the usage of the "Compat" Emacs lisp library, the
+forward-compatibility library for Emacs Lisp, corresponding to version
+28.1.1.0.
+
+ Copyright © 2022 Free Software Foundation, Inc.
+
+ Permission is granted to copy, distribute and/or modify this
+ document under the terms of the GNU Free Documentation License,
+ Version 1.3 or any later version published by the Free Software
+ Foundation; with no Invariant Sections, with the Front-Cover Texts
+ being “A GNU Manual,” and with the Back-Cover Texts as in (a)
+ below. A copy of the license is included in the section entitled
+ “GNU Free Documentation License.”
+
+ (a) The FSF’s Back-Cover Text is: “You have the freedom to copy and
+ modify this GNU manual.”
+
+* Menu:
+
+* Introduction::
+* Support::
+* Development::
+* Function Index::
+* Variable Index::
+
+— The Detailed Node Listing —
+
+Introduction
+
+* Overview::
+* Usage::
+* Intentions::
+
+Usage
+
+* Additional libraries::
+
+Support
+
+* Emacs 24.4:: Compatibility support for Emacs 24.4
+* Emacs 24.5:: Compatibility support for Emacs 24.5
+* Emacs 25.1:: Compatibility support for Emacs 25.1
+* Emacs 26.1:: Compatibility support for Emacs 26.1
+* Emacs 27.1:: Compatibility support for Emacs 27.1
+* Emacs 28.1:: Compatibility support for Emacs 28.1
+
+
+
+File: compat.info, Node: Introduction, Next: Support, Prev: Top, Up: Top
+
+1 Introduction
+**************
+
+* Menu:
+
+* Overview::
+* Usage::
+* Intentions::
+
+
+File: compat.info, Node: Overview, Next: Usage, Up: Introduction
+
+1.1 Overview
+============
+
+The objective of Compat is to provide "forwards compatibility" library
+for Emacs Lisp. That is to say by using Compat, an Elisp package does
+not have to make the decision to either use new and useful functionality
+or support old versions of Emacs.
+
+ Version 24.3 is chosen as the oldest version, because this is the
+newest version on CentOS 7. It is intended to preserve compatibility
+for at least as the Centos 7 reaches EOL
+(https://wiki.centos.org/About/Product), 2024.
+
+ If you are developing a package with Compat in mind, consider loading
+‘compat-help‘ (on your system, not in a package) to get relevant notes
+inserted into the help buffers of functions that are implemented or
+advised in Compat.
+
+ Note that Compat provides a few prefixed function, ie. functions
+with a ‘compat-’ prefix. These are used to provide extended
+functionality for commands that are already defined (‘sort’, ‘assoc’,
+‘seq’, ...). It might be possible to transform these into advised
+functions later on, so that the modified functionality is accessible
+without a prefix. Feedback on this point is appreciated.
+
+
+File: compat.info, Node: Usage, Next: Intentions, Prev: Overview, Up: Introduction
+
+1.2 Usage
+=========
+
+The intended use-case for this library is for package developers to add
+as a dependency in the header:
+
+ ;; Package-Requires: ((emacs "24.3") (compat "28.1.1.0"))
+
+ and later on a
+
+ (require 'compat)
+
+ This will load all non-prefixed definitions (functions and macros
+with a leading ‘compat-‘). To load these, an additional
+
+ (require 'compat-XY) ; e.g. 26
+
+ will be necessary, to load compatibility code for Emacs version XY.
+
+ It is recommended to subscribe to the compat-announce
+(https://lists.sr.ht/~pkal/compat-announce) mailing list to be notified
+when new versions are released or relevant changes are made.
+
+* Menu:
+
+* Additional libraries::
+
+
+File: compat.info, Node: Additional libraries, Up: Usage
+
+1.2.1 Additional libraries
+--------------------------
+
+These libraries are packages with Compat, but are disabled by default.
+To use them you can use ‘M-x load-library’:
+
+compat-help
+ Add notes to ‘*Help*’ buffer, if a compatibility definition has
+ something to warn you about.
+compat-font-lock
+ Highlight functions that are implemented as compatibility
+ definitions.
+
+
+File: compat.info, Node: Intentions, Prev: Usage, Up: Introduction
+
+1.3 Intentions
+==============
+
+The library intends to provide support back until Emacs 24.3. The
+intended audience are package developers that are interested in using
+newer developments, without having to break compatibility.
+
+ Sadly, total backwards compatibility cannot be provided for technical
+reasons. These might include:
+
+ • An existing function or macro was extended by some new
+ functionality. To support these cases, the function or macro would
+ have to be advised. As this is usually regarded as invasive and is
+ shown to be a significant overhead, even when the new feature is
+ not used, this approach is not used.
+
+ As a compromise, prefixed functions and macros (starting with a
+ ‘compat-’ prefix) can be provided.
+
+ • New functionality was implemented in the core, and depends on
+ external libraries that cannot be reasonably duplicated in the
+ scope of a compatibility library.
+
+ • New functionality depends on an entire new, non-trivial library.
+ Sometimes these are provided via ELPA (xref, project, ...), but
+ other times it would be infeasible to duplicate an entire library
+ within Compat while also providing the necessary backwards
+ compatibility.
+
+ • It just wasn’t added, and there is no good reason (though good
+ excuses might exist). If you happen to find such a function, *note
+ reporting: Development. it would be much appreciated.
+
+ Always begin by assuming that this might be the case, unless proven
+ otherwise.
+
+
+File: compat.info, Node: Support, Next: Development, Prev: Introduction, Up: Top
+
+2 Support
+*********
+
+This section goes into the features that Compat manages and doesn’t
+manage to provide for each Emacs version.
+
+* Menu:
+
+* Emacs 24.4:: Compatibility support for Emacs 24.4
+* Emacs 24.5:: Compatibility support for Emacs 24.5
+* Emacs 25.1:: Compatibility support for Emacs 25.1
+* Emacs 26.1:: Compatibility support for Emacs 26.1
+* Emacs 27.1:: Compatibility support for Emacs 27.1
+* Emacs 28.1:: Compatibility support for Emacs 28.1
+
+
+File: compat.info, Node: Emacs 24.4, Next: Emacs 24.5, Up: Support
+
+2.1 Emacs 24.4
+==============
+
+The following functions and macros implemented in 24.4, and are provided
+by Compat by default:
+
+ -- Macro: with-eval-after-load
+ See *note (elisp) Hooks for Loading: (elisp)Hooks for Loading.
+
+ -- Function: special-form-p
+ See *note (elisp) Special Forms: (elisp)Special Forms.
+
+ -- Function: macrop
+ See *note (elisp) Simple Macro: (elisp)Simple Macro.
+
+ -- Function: string-suffix-p
+ See *note (elisp) Text Comparison: (elisp)Text Comparison.
+
+ -- Function: delete-consecutive-dups
+ Defined in ‘subr.el’.
+
+ -- Function: define-error
+ See *note (elisp) Error Symbols: (elisp)Error Symbols.
+
+ -- Function: bool-vector-exclusive-or
+ See *note (elisp) Bool-Vectors: (elisp)Bool-Vectors.
+
+ -- Function: bool-vector-union
+ See *note (elisp) Bool-Vectors: (elisp)Bool-Vectors.
+
+ -- Function: bool-vector-intersection
+ See *note (elisp) Bool-Vectors: (elisp)Bool-Vectors.
+
+ -- Function: bool-vector-not
+ See *note (elisp) Bool-Vectors: (elisp)Bool-Vectors.
+
+ -- Function: bool-vector-subsetp
+ See *note (elisp) Bool-Vectors: (elisp)Bool-Vectors.
+
+ -- Function: bool-vector-count-consecutive
+ See *note (elisp) Bool-Vectors: (elisp)Bool-Vectors.
+
+ -- Function: bool-vector-count-population
+ See *note (elisp) Bool-Vectors: (elisp)Bool-Vectors.
+
+ -- Function: completion-table-merge
+ See *note (elisp) Basic Completion: (elisp)Basic Completion.
+
+ -- Function: completion-table-with-cache
+ See *note (elisp) Programmed Completion: (elisp)Programmed
+ Completion.
+
+ -- Function: face-spec-set
+ See *note (elisp) Defining Faces: (elisp)Defining Faces.
+
+ These functions are prefixed with ‘compat’ prefix, and are only
+loaded when ‘compat-24’ is required:
+
+ -- Function: compat-=
+ -- Function: compat-<
+ -- Function: compat->
+ -- Function: compat-<=
+ -- Function: compat->=
+ See *note (elisp) Comparison of Numbers: (elisp)Comparison of
+ Numbers.
+
+ Allows for more than two arguments to be compared.
+
+ -- Function: compat-split-string
+ See *note (elisp) Creating Strings: (elisp)Creating Strings.
+
+ Takes optional argument TRIM.
+
+ Compat does not provide support for the following Lisp features
+implemented in 24.4:
+
+ • Allowing the second optional argument to ‘eval’ to specify a
+ lexical environment.
+ • The ‘define-alternatives’ macro.
+ • Support for the ‘defalias-fset-function’ symbol property.
+ • The ‘group-gid’ and ‘groupd-read-gid’ functions.
+ • The ‘pre-redisplay-function’ hook.
+ • Allowing for ‘with-demoted-errors’ to take a additional argument
+ ‘format’.
+ • The ‘face-spec-set’ function.
+ • The ‘add-face-text-property’ function.
+ • No ‘tty-setup-hook’ hook.
+ • The ‘get-pos-property’ function.
+ • The ‘define-advice’ macro.
+ • Support for generators.
+ • The ‘string-trim’, ‘string-trim-left’ and ‘string-trim-right’
+ functions. These are instead provided as prefixed function as part
+ of *note Emacs 26.1:: support.
+
+
+File: compat.info, Node: Emacs 24.5, Next: Emacs 25.1, Prev: Emacs 24.4, Up: Support
+
+2.2 Emacs 24.5
+==============
+
+No special support for 24.5 was deemed necessary.
+
+
+File: compat.info, Node: Emacs 25.1, Next: Emacs 26.1, Prev: Emacs 24.5, Up: Support
+
+2.3 Emacs 25.1
+==============
+
+The following functions and macros implemented in 25.1, and are provided
+by Compat by default:
+
+ -- Function: format-message
+ See *note (elisp) Formatting Strings: (elisp)Formatting Strings.
+
+ -- Function: directory-name-p
+ See *note (elisp) Directory Names: (elisp)Directory Names.
+
+ -- Function: string-greaterp
+ See *note (elisp) Text Comparison: (elisp)Text Comparison.
+
+ -- Macro: with-file-modes
+ See *note (elisp) Changing Files: (elisp)Changing Files.
+
+ -- Function: alist-get
+ See *note (elisp) Association Lists: (elisp)Association Lists.
+
+ -- Macro: if-let
+ Defined in ‘subr-x.el’.
+
+ -- Macro: when-let
+ Defined in ‘subr-x.el’.
+
+ -- Macro: thread-first
+ Defined in ‘subr-x.el’.
+
+ -- Macro: thread-last
+ Defined in ‘subr-x.el’.
+
+ -- Function: macroexpand-1
+ See *note (elisp) Expansion: (elisp)Expansion.
+
+ -- Function: directory-files-recursively
+ See *note (elisp) Contents of Directories: (elisp)Contents of
+ Directories.
+
+ -- Function: bool-vector
+ See *note (elisp) Bool-Vectors: (elisp)Bool-Vectors.
+
+ These functions are prefixed with ‘compat’ prefix, and are only
+loaded when ‘compat-25’ is required:
+
+ -- Function: compat-sort
+ See *note (elisp) Sequence Functions: (elisp)Sequence Functions.
+
+ Adds support for vectors to be sorted, next to just lists.
+
+ Compat does not provide support for the following Lisp features
+implemented in 25.1:
+
+ • New ‘pcase’ patterns.
+ • The hook ‘prefix-command-echo-keystrokes-functions’ and
+ ‘prefix-command-preserve-state-hook’.
+ • The hook ‘pre-redisplay-functions’.
+ • The function ‘make-process’.
+ • Support for the variable ‘inhibit-message’.
+ • The ‘define-inline’ functionality.
+ • The functions ‘string-collate-lessp’ and ‘string-collate-equalp’.
+ • Support for ‘alist-get’ as a generalised variable.
+ • The function ‘funcall-interactivly’.
+ • The function ‘buffer-substring-with-bidi-context’.
+ • The function ‘font-info’.
+ • The function ‘default-font-width’.
+ • The function ‘window-font-height’ and ‘window-font-width’.
+ • The function ‘window-max-chars-per-line’.
+ • The function ‘set-binary-mode’.
+ • The functions ‘bufferpos-to-filepos’ and ‘filepos-to-bufferpos’.
+
+ Note that the changes in Emacs 25.2 and 25.3 are also included here,
+for the sake of simplicity.
+
+
+File: compat.info, Node: Emacs 26.1, Next: Emacs 27.1, Prev: Emacs 25.1, Up: Support
+
+2.4 Emacs 26.1
+==============
+
+The following functions and macros implemented in 26.1, and are provided
+by Compat by default:
+
+ -- Function: func-arity
+ See *note (elisp) What Is a Function: (elisp)What Is a Function.
+
+ -- Function: mapcan
+ See *note (elisp) Mapping Functions: (elisp)Mapping Functions.
+
+ -- Function: cXXXr
+ -- Function: cXXXXr
+ See *note (elisp) List Elements: (elisp)List Elements.
+
+ -- Variable: gensym-counter
+ See ‘gensym’.
+
+ -- Function: gensym
+ See *note (elisp) Creating Symbols: (elisp)Creating Symbols.
+
+ -- Function: make-nearby-temp-file
+ See *note (elisp) Unique File Names: (elisp)Unique File Names.
+
+ -- Variable: mounted-file-systems
+ Defined in ‘files.el’.
+
+ -- Function: temporary-file-directory
+ See *note (elisp) Unique File Names: (elisp)Unique File Names.
+
+ -- Macro: if-let*
+ Defined in ‘subr-x.el’.
+
+ -- Macro: when-let*
+ Defined in ‘subr-x.el’.
+
+ -- Macro: and-let*
+ Defined in ‘subr-x.el’.
+
+ **Please Note:** The implementation provided by Compat does not
+ include a bug that was observed with Emacs 26 (see
+ <https://debbugs.gnu.org/cgi/bugreport.cgi?bug=31840>).
+
+ -- Function: file-local-name
+ See *note (elisp) Magic File Names: (elisp)Magic File Names.
+
+ -- Function: file-name-quoted-p
+ See *note (elisp) File Name Expansion: (elisp)File Name Expansion.
+
+ -- Function: file-name-quote
+ See *note (elisp) File Name Expansion: (elisp)File Name Expansion.
+
+ -- Function: image-property
+ Defined in ‘image.el’.
+
+ This function can also be used as a generalised variable. To use
+ this you need to explicitly require ‘compat-26’.
+
+ -- Function: file-attribute-type
+ See *note (elisp) File Attributes: (elisp)File Attributes.
+
+ -- Function: file-attribute-link-number
+ See *note (elisp) File Attributes: (elisp)File Attributes.
+
+ -- Function: file-attribute-user-id
+ See *note (elisp) File Attributes: (elisp)File Attributes.
+
+ -- Function: file-attribute-group-id
+ See *note (elisp) File Attributes: (elisp)File Attributes.
+
+ -- Function: file-attribute-access-time
+ See *note (elisp) File Attributes: (elisp)File Attributes.
+
+ -- Function: file-attribute-modification-time
+ See *note (elisp) File Attributes: (elisp)File Attributes.
+
+ -- Function: file-attribute-status-change-time
+ See *note (elisp) File Attributes: (elisp)File Attributes.
+
+ -- Function: file-attribute-size
+ See *note (elisp) File Attributes: (elisp)File Attributes.
+
+ -- Function: file-attribute-modes
+ See *note (elisp) File Attributes: (elisp)File Attributes.
+
+ -- Function: file-attribute-inode-number
+ See *note (elisp) File Attributes: (elisp)File Attributes.
+
+ -- Function: file-attribute-device-number
+ See *note (elisp) File Attributes: (elisp)File Attributes.
+
+ -- Function: file-attribute-collect
+ Defined in ‘files.el’.
+
+ These functions are prefixed with ‘compat’ prefix, and are only
+loaded when ‘compat-26’ is required:
+
+ -- Function: compat-assoc
+ See *note (elisp) Association Lists: (elisp)Association Lists.
+
+ Handle the optional argument TESTFN.
+
+ -- Function: compat-line-number-at-pos
+ See *note (elisp) Text Lines: (elisp)Text Lines.
+
+ Handle the optional argument ABSOLUTE.
+
+ -- Function: compat-alist-get
+ See *note (elisp) Association Lists: (elisp)Association Lists.
+
+ Handle the optional argument TESTFN. Can also be used as a
+ generalised variable.
+
+ -- Function: compat-string-trim-left
+ See *note (elisp) Creating Strings: (elisp)Creating Strings.
+
+ Handles the optional argument REGEXP.
+
+ -- Function: compat-string-trim-right
+ See *note (elisp) Creating Strings: (elisp)Creating Strings.
+
+ Handles the optional argument REGEXP.
+
+ -- Function: compat-string-trim
+ See *note (elisp) Creating Strings: (elisp)Creating Strings.
+
+ Handles the optional arguments TRIM-LEFT and TRIM-RIGHT.
+
+ Compat does not provide support for the following Lisp features
+implemented in 26.1:
+
+ • The function ‘secure-hash-algorithms’.
+ • The function ‘gnutls-avalaible-p’.
+ • Support for records and record functions.
+ • The function ‘mapbacktrace’.
+ • The function ‘file-name-case-insensitive-p’.
+ • The file-attributes constructors.
+ • The function ‘read-multiple-choice’.
+ • The additional elements of ‘parse-partial-sexp’.
+ • The function ‘add-variable-watcher’.
+ • The function ‘undo-amalgamate-change-group’.
+ • The function ‘char-from-name’
+ • Signalling errors when ‘length’ or ‘member’ deal with list cycles.
+ • The function ‘frame-list-z-order’.
+ • The function ‘frame-restack’.
+ • Support for side windows and atomic windows.
+ • All changes related to ‘display-buffer’.
+ • The function ‘window-swap-states’.
+
+ Note that the changes in Emacs 26.2 and 26.3 are also included here,
+for the sake of simplicity.
+
+
+File: compat.info, Node: Emacs 27.1, Next: Emacs 28.1, Prev: Emacs 26.1, Up: Support
+
+2.5 Emacs 27.1
+==============
+
+The following functions and macros implemented in 27.1, and are provided
+by Compat by default:
+
+ -- Function: proper-list-p
+ See *note (elisp) List-related Predicates: (elisp)List-related
+ Predicates.
+
+ -- Function: string-distance
+ See *note (elisp) Text Comparison: (elisp)Text Comparison.
+
+ -- Function: json-serialize
+ See *note (elisp) Parsing JSON: (elisp)Parsing JSON.
+
+ -- Function: json-insert
+ See *note (elisp) Parsing JSON: (elisp)Parsing JSON.
+
+ -- Function: json-parse-string
+ See *note (elisp) Parsing JSON: (elisp)Parsing JSON.
+
+ -- Function: json-parse-buffer
+ See *note (elisp) Parsing JSON: (elisp)Parsing JSON.
+
+ -- Macro: ignore-error
+ See *note (elisp) Handling Errors: (elisp)Handling Errors.
+
+ -- Macro: dolist-with-progress-reporter
+ See *note (elisp) Progress: (elisp)Progress.
+
+ -- Function: flatten-tree
+ See *note (elisp) Building Lists: (elisp)Building Lists.
+
+ -- Function: xor
+ See *note (elisp) Combining Conditions: (elisp)Combining
+ Conditions.
+
+ -- Variable: regexp-unmatchable
+ Defined in ‘subr.el’.
+
+ -- Function: decoded-time-second
+ Defined in ‘simple.el’.
+
+ -- Function: decoded-time-minute
+ Defined in ‘simple.el’.
+
+ -- Function: decoded-time-hour
+ Defined in ‘simple.el’.
+
+ -- Function: decoded-time-day
+ Defined in ‘simple.el’.
+
+ -- Function: decoded-time-month
+ Defined in ‘simple.el’.
+
+ -- Function: decoded-time-year
+ Defined in ‘simple.el’.
+
+ -- Function: decoded-time-weekday
+ Defined in ‘simple.el’.
+
+ -- Function: decoded-time-dst
+ Defined in ‘simple.el’.
+
+ -- Function: decoded-time-zone
+ Defined in ‘simple.el’.
+
+ -- Function: package-get-version
+ Defined in ‘package.el’.
+
+ -- Function: time-equal-p
+ See *note (elisp) Time Calculations: (elisp)Time Calculations.
+
+ -- Function: date-days-in-month
+ See *note (elisp) Time Calculations: (elisp)Time Calculations.
+
+ -- Function: exec-path
+ See *note (elisp) Subprocess Creation: (elisp)Subprocess Creation.
+
+ This function requires the ‘time-date’ feature to be loaded.
+
+ These functions are prefixed with ‘compat’ prefix, and are only
+loaded when ‘compat-27’ is required:
+
+ -- Function: compat-recenter
+ See *note (elisp) Textual Scrolling: (elisp)Textual Scrolling.
+
+ Adds the optional argument REDISPLAY.
+
+ -- Function: compat-lookup-key
+ See *note (elisp) Low-Level Key Binding: (elisp)Low-Level Key
+ Binding.
+
+ Allows KEYMAP to be a list of keymaps.
+
+ -- Macro: compat-setq-local
+ See *note (elisp) Creating Buffer-Local: (elisp)Creating
+ Buffer-Local.
+
+ Allow for more than one variable to be set.
+
+ -- Function: compat-regexp-opt
+ See *note (elisp) Regexp Functions: (elisp)Regexp Functions.
+
+ Handle an empty list of strings.
+
+ -- Function: compat-file-size-human-readable
+ Defined in ‘files.el’.
+
+ Handle the optional third (SPACE) and forth (UNIT) arguments.
+
+ -- Function: compat-assoc-delete-all
+ See *note (elisp) Association Lists: (elisp)Association Lists.
+
+ Handle the optional third (TESTFN) argument.
+
+ -- Function: compat-executable-find
+ *note (elisp) Locating Files: (elisp)Locating Files.
+
+ Handle the optional second (REMOTE) argument.
+
+ -- Function: compat-dired-get-marked-files
+ Defined in ‘dired.el’
+
+ Handles the optional fifth (ERROR) argument.
+
+ Compat does not provide support for the following Lisp features
+implemented in 27.1:
+
+ • Bigint support.
+ • The function ‘time-convert’.
+ • All ‘iso8601-*’ functions.
+ • The macro ‘benchmark-progn’.
+ • The function ‘read-char-from-minibuffer’.
+ • The minor mode ‘reveal-mode’.
+ • The macro ‘with-suppressed-warnings’.
+ • Support for ‘condition-case’ to handle t.
+ • The functions ‘major-mode-suspend’ and ‘major-mode-restore’.
+ • The function ‘provided-mode-derived-p’.
+ • The function ‘file-system-info’.
+ • The more consistent treatment of NaN values.
+ • The function ‘ring-resize’.
+ • The function ‘group-name’.
+ • Additional ‘format-spec’ modifiers.
+ • Support for additional body forms for
+ ‘define-globalized-minor-mode’.
+ • The macro ‘with-connection-local-variables’ and related
+ functionality.
+
+ Note that the changes in Emacs 27.2 are also included here, for the
+sake of simplicity.
+
+
+File: compat.info, Node: Emacs 28.1, Prev: Emacs 27.1, Up: Support
+
+2.6 Emacs 28.1
+==============
+
+The following functions and macros implemented in 28.1, and are provided
+by Compat by default:
+
+ -- Function: string-search
+ See *note (elisp) Text Comparison: (elisp)Text Comparison.
+
+ -- Function: length=
+ See *note (elisp) Sequence Functions: (elisp)Sequence Functions.
+
+ -- Function: length<
+ See *note (elisp) Sequence Functions: (elisp)Sequence Functions.
+
+ -- Function: length>
+ See *note (elisp) Sequence Functions: (elisp)Sequence Functions.
+
+ -- Function: file-name-concat
+ See *note (elisp) Directory Names: (elisp)Directory Names.
+
+ -- Function: garbage-collect-maybe
+ Defined in ‘alloc.c’.
+
+ -- Function: string-replace
+ See *note (elisp) Search and Replace: (elisp)Search and Replace.
+
+ -- Function: always
+ *note (elisp) Calling Functions: (elisp)Calling Functions.
+
+ -- Function: insert-into-buffer
+ See *note (elisp) Insertion: (elisp)Insertion.
+
+ -- Function: replace-regexp-in-region
+ See *note (elisp) Search and Replace: (elisp)Search and Replace.
+
+ -- Function: replace-string-in-region
+ See *note (elisp) Search and Replace: (elisp)Search and Replace.
+
+ -- Function: buffer-local-boundp
+ See *note (elisp) Creating Buffer-Local: (elisp)Creating
+ Buffer-Local.
+
+ -- Function: with-existing-directory
+ See *note (elisp) Testing Accessibility: (elisp)Testing
+ Accessibility.
+
+ -- Macro: dlet
+ See *note (elisp) Local Variables: (elisp)Local Variables.
+
+ -- Function: ensure-list
+ See *note (elisp) Building Lists: (elisp)Building Lists.
+
+ -- Function: string-clean-whitespace
+ See *note (elisp) Creating Strings: (elisp)Creating Strings.
+
+ -- Function: string-fill
+ See *note (elisp) Creating Strings: (elisp)Creating Strings.
+
+ -- Function: string-lines
+ See *note (elisp) Creating Strings: (elisp)Creating Strings.
+
+ -- Function: string-pad
+ See *note (elisp) Creating Strings: (elisp)Creating Strings.
+
+ -- Function: string-chop-newline
+ See *note (elisp) Creating Strings: (elisp)Creating Strings.
+
+ -- Macro: named-let
+ See *note (elisp) Local Variables: (elisp)Local Variables.
+
+ -- Function: file-name-with-extension
+ See *note (elisp) File Name Components: (elisp)File Name
+ Components.
+
+ -- Function: directory-empty-p
+ See *note (elisp) Contents of Directories: (elisp)Contents of
+ Directories.
+
+ -- Function: format-prompt
+ See *note (elisp) Text from Minibuffer: (elisp)Text from
+ Minibuffer.
+
+ -- Function: thing-at-mouse
+ Defined in ‘thingatpt.el’.
+
+ -- Function: macroexp-file-name
+ Defined in ‘macroexp’.
+
+ -- Macro: with-environment-variables
+ See *note (elisp) System Environment: (elisp)System Environment.
+
+ -- Function: button-buttonize
+ Defined in ‘button.el’.
+
+ -- Function: make-directory-autoloads
+ See *note (elisp) Autoload: (elisp)Autoload.
+
+ -- Function: color-values-from-color-spec
+ Defined in ‘xfaces.c’.
+
+ -- Function: file-modes-number-to-symbolic
+ See *note (elisp) Changing Files: (elisp)Changing Files.
+
+ -- Function: file-backup-file-names
+ See *note (elisp) Backup Names: (elisp)Backup Names.
+
+ -- Function: make-lock-file-name
+ Defined in ‘files.el’.
+
+ -- Function: null-device
+ Defined in ‘files.el’.
+
+ These functions are prefixed with ‘compat’ prefix, and are only
+loaded when ‘compat-28’ is required:
+
+ -- Function: compat-unlock-buffer
+ See *note (elisp) File Locks: (elisp)File Locks.
+
+ Handle ‘file-error’ conditions.
+
+ -- Function: compat-string-width
+ See *note (elisp) Size of Displayed Text: (elisp)Size of Displayed
+ Text.
+
+ Handle optional arguments FROM and TO.
+
+ -- Function: compat-json-serialize
+ See *note (elisp) Parsing JSON: (elisp)Parsing JSON.
+
+ Handle primitive, top-level JSON values.
+
+ -- Function: compat-json-insert
+ See *note (elisp) Parsing JSON: (elisp)Parsing JSON.
+
+ Handle primitive, top-level JSON values.
+
+ -- Function: compat-json-parse-string
+ See *note (elisp) Parsing JSON: (elisp)Parsing JSON.
+
+ Handle primitive, top-level JSON values.
+
+ -- Function: compat-json-parse-buffer
+ See *note (elisp) Parsing JSON: (elisp)Parsing JSON.
+
+ Handle primitive, top-level JSON values.
+
+ -- Function: compat-count-windows
+ Defined in ‘window.el’.
+
+ Handle optional argument ALL-FRAMES.
+
+ Compat does not provide support for the following Lisp features
+implemented in 28.1:
+
+ • Support for ‘interactive’ or ‘declare’ to list applicable modes.
+ • Support for ‘:interactive’ argument to ‘define-minor-mode’ and
+ ‘define-derived-mode’.
+ • Support for ‘:predicate’ argument to
+ ‘define-globalized-minor-mode’.
+ • "Success handler" for ‘condition-case’.
+ • The function ‘benchmark-call’.
+ • Support for the ‘natnum’ defcustom type.
+ • The function ‘macroexp-compiling-p’.
+ • The function ‘macroexp-warn-and-return’.
+ • Additional Edebug keywords.
+ • Shorthand support.
+ • The function ‘custom-add-choice’.
+ • The function ‘decoded-time-period’.
+ • The function ‘dom-print’.
+ • The function ‘dom-remove-attribute’.
+ • The function ‘dns-query-asynchronous’.
+ • The function ‘get-locale-names’.
+ • The function ‘json-avaliable-p’.
+ • The function ‘mail-header-parse-addresses-lax’.
+ • The function ‘mail-header-parse-address-lax’.
+ • The function ‘make-separator-line’.
+ • The function ‘num-processors’.
+ • The function ‘object-intervals’.
+ • The function ‘process-lines-ignore-status’.
+ • The function ‘require-theme’.
+ • The function ‘syntax-class-to-char’.
+ • The function ‘null-device’ and ‘path-separator’.
+
+
+File: compat.info, Node: Development, Next: Function Index, Prev: Support, Up: Top
+
+3 Development
+*************
+
+Compat is developed on SourceHut (https://sr.ht/~pkal/compat). A
+restricted GitHub mirror (https://github.com/phikal/compat.el) is also
+maintained.
+
+ Patches and comments can be sent to the development mailing list
+(https://lists.sr.ht/~pkal/compat-devel) (~pkal/compat-devel@lists.sr.ht
+<~pkal/compat-devel@lists.sr.ht>). Bug reports are best sent to the
+issue tracker (https://todo.sr.ht/~pkal/compat) (~pkal/compat@todo.sr.ht
+<~pkal/compat@todo.sr.ht>). The GitHub mirror can also be used to
+submit patches. These may include issues in the compatibility code,
+missing definitions or performance issues.
+
+ Please note that as a GNU ELPA package, Compat requires contributors
+to have signed the FSF copyright assignment
+(https://www.gnu.org/software/emacs/manual/html_node/emacs/Copyright-Assignment.html),
+before any non-trivial contribution (roughly 15 lines of code) can be
+applied.
+
+
+File: compat.info, Node: Function Index, Next: Variable Index, Prev: Development, Up: Top
+
+Appendix A Function Index
+*************************
+
+
+* Menu:
+
+* alist-get: Emacs 25.1. (line 21)
+* always: Emacs 28.1. (line 30)
+* and-let*: Emacs 26.1. (line 40)
+* bool-vector: Emacs 25.1. (line 43)
+* bool-vector-count-consecutive: Emacs 24.4. (line 42)
+* bool-vector-count-population: Emacs 24.4. (line 45)
+* bool-vector-exclusive-or: Emacs 24.4. (line 27)
+* bool-vector-intersection: Emacs 24.4. (line 33)
+* bool-vector-not: Emacs 24.4. (line 36)
+* bool-vector-subsetp: Emacs 24.4. (line 39)
+* bool-vector-union: Emacs 24.4. (line 30)
+* buffer-local-boundp: Emacs 28.1. (line 42)
+* button-buttonize: Emacs 28.1. (line 95)
+* color-values-from-color-spec: Emacs 28.1. (line 101)
+* compat-<: Emacs 24.4. (line 62)
+* compat-<=: Emacs 24.4. (line 64)
+* compat-=: Emacs 24.4. (line 61)
+* compat->: Emacs 24.4. (line 63)
+* compat->=: Emacs 24.4. (line 65)
+* compat-alist-get: Emacs 26.1. (line 111)
+* compat-assoc: Emacs 26.1. (line 101)
+* compat-assoc-delete-all: Emacs 27.1. (line 115)
+* compat-count-windows: Emacs 28.1. (line 150)
+* compat-dired-get-marked-files: Emacs 27.1. (line 125)
+* compat-executable-find: Emacs 27.1. (line 120)
+* compat-file-size-human-readable: Emacs 27.1. (line 110)
+* compat-json-insert: Emacs 28.1. (line 135)
+* compat-json-parse-buffer: Emacs 28.1. (line 145)
+* compat-json-parse-string: Emacs 28.1. (line 140)
+* compat-json-serialize: Emacs 28.1. (line 130)
+* compat-line-number-at-pos: Emacs 26.1. (line 106)
+* compat-lookup-key: Emacs 27.1. (line 93)
+* compat-recenter: Emacs 27.1. (line 88)
+* compat-regexp-opt: Emacs 27.1. (line 105)
+* compat-setq-local: Emacs 27.1. (line 99)
+* compat-sort: Emacs 25.1. (line 49)
+* compat-split-string: Emacs 24.4. (line 71)
+* compat-string-trim: Emacs 26.1. (line 127)
+* compat-string-trim-left: Emacs 26.1. (line 117)
+* compat-string-trim-right: Emacs 26.1. (line 122)
+* compat-string-width: Emacs 28.1. (line 124)
+* compat-unlock-buffer: Emacs 28.1. (line 119)
+* completion-table-merge: Emacs 24.4. (line 48)
+* completion-table-with-cache: Emacs 24.4. (line 51)
+* cXXXr: Emacs 26.1. (line 15)
+* cXXXXr: Emacs 26.1. (line 16)
+* date-days-in-month: Emacs 27.1. (line 77)
+* decoded-time-day: Emacs 27.1. (line 53)
+* decoded-time-dst: Emacs 27.1. (line 65)
+* decoded-time-hour: Emacs 27.1. (line 50)
+* decoded-time-minute: Emacs 27.1. (line 47)
+* decoded-time-month: Emacs 27.1. (line 56)
+* decoded-time-second: Emacs 27.1. (line 44)
+* decoded-time-weekday: Emacs 27.1. (line 62)
+* decoded-time-year: Emacs 27.1. (line 59)
+* decoded-time-zone: Emacs 27.1. (line 68)
+* define-error: Emacs 24.4. (line 24)
+* delete-consecutive-dups: Emacs 24.4. (line 21)
+* directory-empty-p: Emacs 28.1. (line 78)
+* directory-files-recursively: Emacs 25.1. (line 39)
+* directory-name-p: Emacs 25.1. (line 12)
+* dlet: Emacs 28.1. (line 50)
+* dolist-with-progress-reporter: Emacs 27.1. (line 31)
+* ensure-list: Emacs 28.1. (line 53)
+* exec-path: Emacs 27.1. (line 80)
+* face-spec-set: Emacs 24.4. (line 55)
+* file-attribute-access-time: Emacs 26.1. (line 74)
+* file-attribute-collect: Emacs 26.1. (line 95)
+* file-attribute-device-number: Emacs 26.1. (line 92)
+* file-attribute-group-id: Emacs 26.1. (line 71)
+* file-attribute-inode-number: Emacs 26.1. (line 89)
+* file-attribute-link-number: Emacs 26.1. (line 65)
+* file-attribute-modes: Emacs 26.1. (line 86)
+* file-attribute-modification-time: Emacs 26.1. (line 77)
+* file-attribute-size: Emacs 26.1. (line 83)
+* file-attribute-status-change-time: Emacs 26.1. (line 80)
+* file-attribute-type: Emacs 26.1. (line 62)
+* file-attribute-user-id: Emacs 26.1. (line 68)
+* file-backup-file-names: Emacs 28.1. (line 107)
+* file-local-name: Emacs 26.1. (line 47)
+* file-modes-number-to-symbolic: Emacs 28.1. (line 104)
+* file-name-concat: Emacs 28.1. (line 21)
+* file-name-quote: Emacs 26.1. (line 53)
+* file-name-quoted-p: Emacs 26.1. (line 50)
+* file-name-with-extension: Emacs 28.1. (line 74)
+* flatten-tree: Emacs 27.1. (line 34)
+* format-message: Emacs 25.1. (line 9)
+* format-prompt: Emacs 28.1. (line 82)
+* func-arity: Emacs 26.1. (line 9)
+* garbage-collect-maybe: Emacs 28.1. (line 24)
+* gensym: Emacs 26.1. (line 22)
+* if-let: Emacs 25.1. (line 24)
+* if-let*: Emacs 26.1. (line 34)
+* ignore-error: Emacs 27.1. (line 28)
+* image-property: Emacs 26.1. (line 56)
+* insert-into-buffer: Emacs 28.1. (line 33)
+* json-insert: Emacs 27.1. (line 19)
+* json-parse-buffer: Emacs 27.1. (line 25)
+* json-parse-string: Emacs 27.1. (line 22)
+* json-serialize: Emacs 27.1. (line 16)
+* length<: Emacs 28.1. (line 15)
+* length=: Emacs 28.1. (line 12)
+* length>: Emacs 28.1. (line 18)
+* macroexp-file-name: Emacs 28.1. (line 89)
+* macroexpand-1: Emacs 25.1. (line 36)
+* macrop: Emacs 24.4. (line 15)
+* make-directory-autoloads: Emacs 28.1. (line 98)
+* make-lock-file-name: Emacs 28.1. (line 110)
+* make-nearby-temp-file: Emacs 26.1. (line 25)
+* mapcan: Emacs 26.1. (line 12)
+* named-let: Emacs 28.1. (line 71)
+* null-device: Emacs 28.1. (line 113)
+* package-get-version: Emacs 27.1. (line 71)
+* proper-list-p: Emacs 27.1. (line 9)
+* replace-regexp-in-region: Emacs 28.1. (line 36)
+* replace-string-in-region: Emacs 28.1. (line 39)
+* special-form-p: Emacs 24.4. (line 12)
+* string-chop-newline: Emacs 28.1. (line 68)
+* string-clean-whitespace: Emacs 28.1. (line 56)
+* string-distance: Emacs 27.1. (line 13)
+* string-fill: Emacs 28.1. (line 59)
+* string-greaterp: Emacs 25.1. (line 15)
+* string-lines: Emacs 28.1. (line 62)
+* string-pad: Emacs 28.1. (line 65)
+* string-replace: Emacs 28.1. (line 27)
+* string-search: Emacs 28.1. (line 9)
+* string-suffix-p: Emacs 24.4. (line 18)
+* temporary-file-directory: Emacs 26.1. (line 31)
+* thing-at-mouse: Emacs 28.1. (line 86)
+* thread-first: Emacs 25.1. (line 30)
+* thread-last: Emacs 25.1. (line 33)
+* time-equal-p: Emacs 27.1. (line 74)
+* when-let: Emacs 25.1. (line 27)
+* when-let*: Emacs 26.1. (line 37)
+* with-environment-variables: Emacs 28.1. (line 92)
+* with-eval-after-load: Emacs 24.4. (line 9)
+* with-existing-directory: Emacs 28.1. (line 46)
+* with-file-modes: Emacs 25.1. (line 18)
+* xor: Emacs 27.1. (line 37)
+
+
+File: compat.info, Node: Variable Index, Prev: Function Index, Up: Top
+
+Appendix B Variable Index
+*************************
+
+
+* Menu:
+
+* gensym-counter: Emacs 26.1. (line 19)
+* mounted-file-systems: Emacs 26.1. (line 28)
+* regexp-unmatchable: Emacs 27.1. (line 41)
+
+
+
+Tag Table:
+Node: Top821
+Node: Introduction2344
+Node: Overview2503
+Node: Usage3726
+Node: Additional libraries4514
+Node: Intentions4969
+Node: Support6579
+Node: Emacs 24.47231
+Node: Emacs 24.510391
+Node: Emacs 25.110565
+Node: Emacs 26.113160
+Node: Emacs 27.118253
+Node: Emacs 28.122838
+Node: Development28727
+Node: Function Index29742
+Node: Variable Index40061
+
+End Tag Table
+
+
+Local Variables:
+coding: utf-8
+End:
diff --git a/elpa/compat-28.1.1.0/dir b/elpa/compat-28.1.1.0/dir
new file mode 100644
index 0000000..de02c6e
--- /dev/null
+++ b/elpa/compat-28.1.1.0/dir
@@ -0,0 +1,18 @@
+This is the file .../info/dir, which contains the
+topmost node of the Info hierarchy, called (dir)Top.
+The first time you invoke Info you start off looking at this node.
+
+File: dir, Node: Top This is the top of the INFO tree
+
+ This (the Directory node) gives a menu of major topics.
+ Typing "q" exits, "H" lists all Info commands, "d" returns here,
+ "h" gives a primer for first-timers,
+ "mEmacs<Return>" visits the Emacs manual, etc.
+
+ In Emacs, you can click mouse button 2 on a menu item or cross reference
+ to select it.
+
+* Menu:
+
+Emacs
+* Compat: (compat). Compatibility Library for Emacs Lisp.
diff --git a/elpa/dash-20220417.2250/dash-autoloads.el b/elpa/dash-20220417.2250/dash-autoloads.el
new file mode 100644
index 0000000..6783a8d
--- /dev/null
+++ b/elpa/dash-20220417.2250/dash-autoloads.el
@@ -0,0 +1,87 @@
+;;; dash-autoloads.el --- automatically extracted autoloads -*- lexical-binding: t -*-
+;;
+;;; Code:
+
+(add-to-list 'load-path (directory-file-name
+ (or (file-name-directory #$) (car load-path))))
+
+
+;;;### (autoloads nil "dash" "dash.el" (0 0 0 0))
+;;; Generated autoloads from dash.el
+
+(autoload 'dash-fontify-mode "dash" "\
+Toggle fontification of Dash special variables.
+
+This is a minor mode. If called interactively, toggle the
+`Dash-Fontify mode' mode. If the prefix argument is positive,
+enable the mode, and if it is zero or negative, disable the mode.
+
+If called from Lisp, toggle the mode if ARG is `toggle'. Enable
+the mode if ARG is nil, omitted, or is a positive number.
+Disable the mode if ARG is a negative number.
+
+To check whether the minor mode is enabled in the current buffer,
+evaluate `dash-fontify-mode'.
+
+The mode's hook is called both when the mode is enabled and when
+it is disabled.
+
+Dash-Fontify mode is a buffer-local minor mode intended for Emacs
+Lisp buffers. Enabling it causes the special variables bound in
+anaphoric Dash macros to be fontified. These anaphoras include
+`it', `it-index', `acc', and `other'. In older Emacs versions
+which do not dynamically detect macros, Dash-Fontify mode
+additionally fontifies Dash macro calls.
+
+See also `dash-fontify-mode-lighter' and
+`global-dash-fontify-mode'.
+
+\(fn &optional ARG)" t nil)
+
+(put 'global-dash-fontify-mode 'globalized-minor-mode t)
+
+(defvar global-dash-fontify-mode nil "\
+Non-nil if Global Dash-Fontify mode is enabled.
+See the `global-dash-fontify-mode' command
+for a description of this minor mode.
+Setting this variable directly does not take effect;
+either customize it (see the info node `Easy Customization')
+or call the function `global-dash-fontify-mode'.")
+
+(custom-autoload 'global-dash-fontify-mode "dash" nil)
+
+(autoload 'global-dash-fontify-mode "dash" "\
+Toggle Dash-Fontify mode in all buffers.
+With prefix ARG, enable Global Dash-Fontify mode if ARG is positive;
+otherwise, disable it.
+
+If called from Lisp, toggle the mode if ARG is `toggle'.
+Enable the mode if ARG is nil, omitted, or is a positive number.
+Disable the mode if ARG is a negative number.
+
+Dash-Fontify mode is enabled in all buffers where
+`dash--turn-on-fontify-mode' would do it.
+
+See `dash-fontify-mode' for more information on Dash-Fontify mode.
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'dash-register-info-lookup "dash" "\
+Register the Dash Info manual with `info-lookup-symbol'.
+This allows Dash symbols to be looked up with \\[info-lookup-symbol]." t nil)
+
+(register-definition-prefixes "dash" '("!cdr" "!cons" "--" "->" "-a" "-butlast" "-c" "-d" "-e" "-f" "-gr" "-i" "-juxt" "-keep" "-l" "-m" "-no" "-o" "-p" "-r" "-s" "-t" "-u" "-value-to-list" "-when-let" "-zip" "dash-"))
+
+;;;***
+
+;;;### (autoloads nil nil ("dash-pkg.el") (0 0 0 0))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; coding: utf-8
+;; End:
+;;; dash-autoloads.el ends here
diff --git a/elpa/dash-20220417.2250/dash-pkg.el b/elpa/dash-20220417.2250/dash-pkg.el
new file mode 100644
index 0000000..98425a8
--- /dev/null
+++ b/elpa/dash-20220417.2250/dash-pkg.el
@@ -0,0 +1,12 @@
+(define-package "dash" "20220417.2250" "A modern list library for Emacs"
+ '((emacs "24"))
+ :commit "7fd71338dce041b352f84e7939f6966f4d379459" :authors
+ '(("Magnar Sveen" . "magnars@gmail.com"))
+ :maintainer
+ '("Magnar Sveen" . "magnars@gmail.com")
+ :keywords
+ '("extensions" "lisp")
+ :url "https://github.com/magnars/dash.el")
+;; Local Variables:
+;; no-byte-compile: t
+;; End:
diff --git a/elpa/dash-20220417.2250/dash.el b/elpa/dash-20220417.2250/dash.el
new file mode 100644
index 0000000..26e1f8b
--- /dev/null
+++ b/elpa/dash-20220417.2250/dash.el
@@ -0,0 +1,3570 @@
+;;; dash.el --- A modern list library for Emacs -*- lexical-binding: t -*-
+
+;; Copyright (C) 2012-2021 Free Software Foundation, Inc.
+
+;; Author: Magnar Sveen <magnars@gmail.com>
+;; Version: 2.19.1
+;; Package-Requires: ((emacs "24"))
+;; Keywords: extensions, lisp
+;; Homepage: https://github.com/magnars/dash.el
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; A modern list API for Emacs.
+;;
+;; See its overview at https://github.com/magnars/dash.el#functions.
+
+;;; Code:
+
+;; TODO: `gv' was introduced in Emacs 24.3, so remove this and all
+;; calls to `defsetf' when support for earlier versions is dropped.
+(eval-when-compile
+ (unless (fboundp 'gv-define-setter)
+ (require 'cl)))
+
+(defgroup dash ()
+ "Customize group for Dash, a modern list library."
+ :group 'extensions
+ :group 'lisp
+ :prefix "dash-")
+
+(defmacro !cons (car cdr)
+ "Destructive: Set CDR to the cons of CAR and CDR."
+ (declare (debug (form symbolp)))
+ `(setq ,cdr (cons ,car ,cdr)))
+
+(defmacro !cdr (list)
+ "Destructive: Set LIST to the cdr of LIST."
+ (declare (debug (symbolp)))
+ `(setq ,list (cdr ,list)))
+
+(defmacro --each (list &rest body)
+ "Evaluate BODY for each element of LIST and return nil.
+Each element of LIST in turn is bound to `it' and its index
+within LIST to `it-index' before evaluating BODY.
+This is the anaphoric counterpart to `-each'."
+ (declare (debug (form body)) (indent 1))
+ (let ((l (make-symbol "list"))
+ (i (make-symbol "i")))
+ `(let ((,l ,list)
+ (,i 0)
+ it it-index)
+ (ignore it it-index)
+ (while ,l
+ (setq it (pop ,l) it-index ,i ,i (1+ ,i))
+ ,@body))))
+
+(defun -each (list fn)
+ "Call FN on each element of LIST.
+Return nil; this function is intended for side effects.
+
+Its anaphoric counterpart is `--each'.
+
+For access to the current element's index in LIST, see
+`-each-indexed'."
+ (declare (indent 1))
+ (ignore (mapc fn list)))
+
+(defalias '--each-indexed '--each)
+
+(defun -each-indexed (list fn)
+ "Call FN on each index and element of LIST.
+For each ITEM at INDEX in LIST, call (funcall FN INDEX ITEM).
+Return nil; this function is intended for side effects.
+
+See also: `-map-indexed'."
+ (declare (indent 1))
+ (--each list (funcall fn it-index it)))
+
+(defmacro --each-while (list pred &rest body)
+ "Evaluate BODY for each item in LIST, while PRED evaluates to non-nil.
+Each element of LIST in turn is bound to `it' and its index
+within LIST to `it-index' before evaluating PRED or BODY. Once
+an element is reached for which PRED evaluates to nil, no further
+BODY is evaluated. The return value is always nil.
+This is the anaphoric counterpart to `-each-while'."
+ (declare (debug (form form body)) (indent 2))
+ (let ((l (make-symbol "list"))
+ (i (make-symbol "i"))
+ (elt (make-symbol "elt")))
+ `(let ((,l ,list)
+ (,i 0)
+ ,elt it it-index)
+ (ignore it it-index)
+ (while (and ,l (setq ,elt (pop ,l) it ,elt it-index ,i) ,pred)
+ (setq it ,elt it-index ,i ,i (1+ ,i))
+ ,@body))))
+
+(defun -each-while (list pred fn)
+ "Call FN on each ITEM in LIST, while (PRED ITEM) is non-nil.
+Once an ITEM is reached for which PRED returns nil, FN is no
+longer called. Return nil; this function is intended for side
+effects.
+
+Its anaphoric counterpart is `--each-while'."
+ (declare (indent 2))
+ (--each-while list (funcall pred it) (funcall fn it)))
+
+(defmacro --each-r (list &rest body)
+ "Evaluate BODY for each element of LIST in reversed order.
+Each element of LIST in turn, starting at its end, is bound to
+`it' and its index within LIST to `it-index' before evaluating
+BODY. The return value is always nil.
+This is the anaphoric counterpart to `-each-r'."
+ (declare (debug (form body)) (indent 1))
+ (let ((v (make-symbol "vector"))
+ (i (make-symbol "i")))
+ ;; Implementation note: building a vector is considerably faster
+ ;; than building a reversed list (vector takes less memory, so
+ ;; there is less GC), plus `length' comes naturally. In-place
+ ;; `nreverse' would be faster still, but BODY would be able to see
+ ;; that, even if the modification was undone before we return.
+ `(let* ((,v (vconcat ,list))
+ (,i (length ,v))
+ it it-index)
+ (ignore it it-index)
+ (while (> ,i 0)
+ (setq ,i (1- ,i) it-index ,i it (aref ,v ,i))
+ ,@body))))
+
+(defun -each-r (list fn)
+ "Call FN on each element of LIST in reversed order.
+Return nil; this function is intended for side effects.
+
+Its anaphoric counterpart is `--each-r'."
+ (--each-r list (funcall fn it)))
+
+(defmacro --each-r-while (list pred &rest body)
+ "Eval BODY for each item in reversed LIST, while PRED evals to non-nil.
+Each element of LIST in turn, starting at its end, is bound to
+`it' and its index within LIST to `it-index' before evaluating
+PRED or BODY. Once an element is reached for which PRED
+evaluates to nil, no further BODY is evaluated. The return value
+is always nil.
+This is the anaphoric counterpart to `-each-r-while'."
+ (declare (debug (form form body)) (indent 2))
+ (let ((v (make-symbol "vector"))
+ (i (make-symbol "i"))
+ (elt (make-symbol "elt")))
+ `(let* ((,v (vconcat ,list))
+ (,i (length ,v))
+ ,elt it it-index)
+ (ignore it it-index)
+ (while (when (> ,i 0)
+ (setq ,i (1- ,i) it-index ,i)
+ (setq ,elt (aref ,v ,i) it ,elt)
+ ,pred)
+ (setq it-index ,i it ,elt)
+ ,@body))))
+
+(defun -each-r-while (list pred fn)
+ "Call FN on each ITEM in reversed LIST, while (PRED ITEM) is non-nil.
+Once an ITEM is reached for which PRED returns nil, FN is no
+longer called. Return nil; this function is intended for side
+effects.
+
+Its anaphoric counterpart is `--each-r-while'."
+ (--each-r-while list (funcall pred it) (funcall fn it)))
+
+(defmacro --dotimes (num &rest body)
+ "Evaluate BODY NUM times, presumably for side effects.
+BODY is evaluated with the local variable `it' temporarily bound
+to successive integers running from 0, inclusive, to NUM,
+exclusive. BODY is not evaluated if NUM is less than 1.
+This is the anaphoric counterpart to `-dotimes'."
+ (declare (debug (form body)) (indent 1))
+ (let ((n (make-symbol "num"))
+ (i (make-symbol "i")))
+ `(let ((,n ,num)
+ (,i 0)
+ it)
+ (ignore it)
+ (while (< ,i ,n)
+ (setq it ,i ,i (1+ ,i))
+ ,@body))))
+
+(defun -dotimes (num fn)
+ "Call FN NUM times, presumably for side effects.
+FN is called with a single argument on successive integers
+running from 0, inclusive, to NUM, exclusive. FN is not called
+if NUM is less than 1.
+
+This function's anaphoric counterpart is `--dotimes'."
+ (declare (indent 1))
+ (--dotimes num (funcall fn it)))
+
+(defun -map (fn list)
+ "Apply FN to each item in LIST and return the list of results.
+
+This function's anaphoric counterpart is `--map'."
+ (mapcar fn list))
+
+(defmacro --map (form list)
+ "Eval FORM for each item in LIST and return the list of results.
+Each element of LIST in turn is bound to `it' before evaluating
+FORM.
+This is the anaphoric counterpart to `-map'."
+ (declare (debug (def-form form)))
+ `(mapcar (lambda (it) (ignore it) ,form) ,list))
+
+(defmacro --reduce-from (form init list)
+ "Accumulate a value by evaluating FORM across LIST.
+This macro is like `--each' (which see), but it additionally
+provides an accumulator variable `acc' which it successively
+binds to the result of evaluating FORM for the current LIST
+element before processing the next element. For the first
+element, `acc' is initialized with the result of evaluating INIT.
+The return value is the resulting value of `acc'. If LIST is
+empty, FORM is not evaluated, and the return value is the result
+of INIT.
+This is the anaphoric counterpart to `-reduce-from'."
+ (declare (debug (form form form)))
+ `(let ((acc ,init))
+ (--each ,list (setq acc ,form))
+ acc))
+
+(defun -reduce-from (fn init list)
+ "Reduce the function FN across LIST, starting with INIT.
+Return the result of applying FN to INIT and the first element of
+LIST, then applying FN to that result and the second element,
+etc. If LIST is empty, return INIT without calling FN.
+
+This function's anaphoric counterpart is `--reduce-from'.
+
+For other folds, see also `-reduce' and `-reduce-r'."
+ (--reduce-from (funcall fn acc it) init list))
+
+(defmacro --reduce (form list)
+ "Accumulate a value by evaluating FORM across LIST.
+This macro is like `--reduce-from' (which see), except the first
+element of LIST is taken as INIT. Thus if LIST contains a single
+item, it is returned without evaluating FORM. If LIST is empty,
+FORM is evaluated with `it' and `acc' bound to nil.
+This is the anaphoric counterpart to `-reduce'."
+ (declare (debug (form form)))
+ (let ((lv (make-symbol "list-value")))
+ `(let ((,lv ,list))
+ (if ,lv
+ (--reduce-from ,form (car ,lv) (cdr ,lv))
+ ;; Explicit nil binding pacifies lexical "variable left uninitialized"
+ ;; warning. See issue #377 and upstream https://bugs.gnu.org/47080.
+ (let ((acc nil) (it nil))
+ (ignore acc it)
+ ,form)))))
+
+(defun -reduce (fn list)
+ "Reduce the function FN across LIST.
+Return the result of applying FN to the first two elements of
+LIST, then applying FN to that result and the third element, etc.
+If LIST contains a single element, return it without calling FN.
+If LIST is empty, return the result of calling FN with no
+arguments.
+
+This function's anaphoric counterpart is `--reduce'.
+
+For other folds, see also `-reduce-from' and `-reduce-r'."
+ (if list
+ (-reduce-from fn (car list) (cdr list))
+ (funcall fn)))
+
+(defmacro --reduce-r-from (form init list)
+ "Accumulate a value by evaluating FORM across LIST in reverse.
+This macro is like `--reduce-from', except it starts from the end
+of LIST.
+This is the anaphoric counterpart to `-reduce-r-from'."
+ (declare (debug (form form form)))
+ `(let ((acc ,init))
+ (--each-r ,list (setq acc ,form))
+ acc))
+
+(defun -reduce-r-from (fn init list)
+ "Reduce the function FN across LIST in reverse, starting with INIT.
+Return the result of applying FN to the last element of LIST and
+INIT, then applying FN to the second-to-last element and the
+previous result of FN, etc. That is, the first argument of FN is
+the current element, and its second argument the accumulated
+value. If LIST is empty, return INIT without calling FN.
+
+This function is like `-reduce-from' but the operation associates
+from the right rather than left. In other words, it starts from
+the end of LIST and flips the arguments to FN. Conceptually, it
+is like replacing the conses in LIST with applications of FN, and
+its last link with INIT, and evaluating the resulting expression.
+
+This function's anaphoric counterpart is `--reduce-r-from'.
+
+For other folds, see also `-reduce-r' and `-reduce'."
+ (--reduce-r-from (funcall fn it acc) init list))
+
+(defmacro --reduce-r (form list)
+ "Accumulate a value by evaluating FORM across LIST in reverse order.
+This macro is like `--reduce', except it starts from the end of
+LIST.
+This is the anaphoric counterpart to `-reduce-r'."
+ (declare (debug (form form)))
+ `(--reduce ,form (reverse ,list)))
+
+(defun -reduce-r (fn list)
+ "Reduce the function FN across LIST in reverse.
+Return the result of applying FN to the last two elements of
+LIST, then applying FN to the third-to-last element and the
+previous result of FN, etc. That is, the first argument of FN is
+the current element, and its second argument the accumulated
+value. If LIST contains a single element, return it without
+calling FN. If LIST is empty, return the result of calling FN
+with no arguments.
+
+This function is like `-reduce' but the operation associates from
+the right rather than left. In other words, it starts from the
+end of LIST and flips the arguments to FN. Conceptually, it is
+like replacing the conses in LIST with applications of FN,
+ignoring its last link, and evaluating the resulting expression.
+
+This function's anaphoric counterpart is `--reduce-r'.
+
+For other folds, see also `-reduce-r-from' and `-reduce'."
+ (if list
+ (--reduce-r (funcall fn it acc) list)
+ (funcall fn)))
+
+(defmacro --reductions-from (form init list)
+ "Return a list of FORM's intermediate reductions across LIST.
+That is, a list of the intermediate values of the accumulator
+when `--reduce-from' (which see) is called with the same
+arguments.
+This is the anaphoric counterpart to `-reductions-from'."
+ (declare (debug (form form form)))
+ `(nreverse
+ (--reduce-from (cons (let ((acc (car acc))) (ignore acc) ,form) acc)
+ (list ,init)
+ ,list)))
+
+(defun -reductions-from (fn init list)
+ "Return a list of FN's intermediate reductions across LIST.
+That is, a list of the intermediate values of the accumulator
+when `-reduce-from' (which see) is called with the same
+arguments.
+
+This function's anaphoric counterpart is `--reductions-from'.
+
+For other folds, see also `-reductions' and `-reductions-r'."
+ (--reductions-from (funcall fn acc it) init list))
+
+(defmacro --reductions (form list)
+ "Return a list of FORM's intermediate reductions across LIST.
+That is, a list of the intermediate values of the accumulator
+when `--reduce' (which see) is called with the same arguments.
+This is the anaphoric counterpart to `-reductions'."
+ (declare (debug (form form)))
+ (let ((lv (make-symbol "list-value")))
+ `(let ((,lv ,list))
+ (if ,lv
+ (--reductions-from ,form (car ,lv) (cdr ,lv))
+ (let (acc it)
+ (ignore acc it)
+ (list ,form))))))
+
+(defun -reductions (fn list)
+ "Return a list of FN's intermediate reductions across LIST.
+That is, a list of the intermediate values of the accumulator
+when `-reduce' (which see) is called with the same arguments.
+
+This function's anaphoric counterpart is `--reductions'.
+
+For other folds, see also `-reductions' and `-reductions-r'."
+ (if list
+ (--reductions-from (funcall fn acc it) (car list) (cdr list))
+ (list (funcall fn))))
+
+(defmacro --reductions-r-from (form init list)
+ "Return a list of FORM's intermediate reductions across reversed LIST.
+That is, a list of the intermediate values of the accumulator
+when `--reduce-r-from' (which see) is called with the same
+arguments.
+This is the anaphoric counterpart to `-reductions-r-from'."
+ (declare (debug (form form form)))
+ `(--reduce-r-from (cons (let ((acc (car acc))) (ignore acc) ,form) acc)
+ (list ,init)
+ ,list))
+
+(defun -reductions-r-from (fn init list)
+ "Return a list of FN's intermediate reductions across reversed LIST.
+That is, a list of the intermediate values of the accumulator
+when `-reduce-r-from' (which see) is called with the same
+arguments.
+
+This function's anaphoric counterpart is `--reductions-r-from'.
+
+For other folds, see also `-reductions' and `-reductions-r'."
+ (--reductions-r-from (funcall fn it acc) init list))
+
+(defmacro --reductions-r (form list)
+ "Return a list of FORM's intermediate reductions across reversed LIST.
+That is, a list of the intermediate values of the accumulator
+when `--reduce-re' (which see) is called with the same arguments.
+This is the anaphoric counterpart to `-reductions-r'."
+ (declare (debug (form list)))
+ (let ((lv (make-symbol "list-value")))
+ `(let ((,lv (reverse ,list)))
+ (if ,lv
+ (--reduce-from (cons (let ((acc (car acc))) (ignore acc) ,form) acc)
+ (list (car ,lv))
+ (cdr ,lv))
+ ;; Explicit nil binding pacifies lexical "variable left uninitialized"
+ ;; warning. See issue #377 and upstream https://bugs.gnu.org/47080.
+ (let ((acc nil) (it nil))
+ (ignore acc it)
+ (list ,form))))))
+
+(defun -reductions-r (fn list)
+ "Return a list of FN's intermediate reductions across reversed LIST.
+That is, a list of the intermediate values of the accumulator
+when `-reduce-r' (which see) is called with the same arguments.
+
+This function's anaphoric counterpart is `--reductions-r'.
+
+For other folds, see also `-reductions-r-from' and
+`-reductions'."
+ (if list
+ (--reductions-r (funcall fn it acc) list)
+ (list (funcall fn))))
+
+(defmacro --filter (form list)
+ "Return a new list of the items in LIST for which FORM evals to non-nil.
+Each element of LIST in turn is bound to `it' and its index
+within LIST to `it-index' before evaluating FORM.
+This is the anaphoric counterpart to `-filter'.
+For the opposite operation, see also `--remove'."
+ (declare (debug (form form)))
+ (let ((r (make-symbol "result")))
+ `(let (,r)
+ (--each ,list (when ,form (push it ,r)))
+ (nreverse ,r))))
+
+(defun -filter (pred list)
+ "Return a new list of the items in LIST for which PRED returns non-nil.
+
+Alias: `-select'.
+
+This function's anaphoric counterpart is `--filter'.
+
+For similar operations, see also `-keep' and `-remove'."
+ (--filter (funcall pred it) list))
+
+(defalias '-select '-filter)
+(defalias '--select '--filter)
+
+(defmacro --remove (form list)
+ "Return a new list of the items in LIST for which FORM evals to nil.
+Each element of LIST in turn is bound to `it' and its index
+within LIST to `it-index' before evaluating FORM.
+This is the anaphoric counterpart to `-remove'.
+For the opposite operation, see also `--filter'."
+ (declare (debug (form form)))
+ `(--filter (not ,form) ,list))
+
+(defun -remove (pred list)
+ "Return a new list of the items in LIST for which PRED returns nil.
+
+Alias: `-reject'.
+
+This function's anaphoric counterpart is `--remove'.
+
+For similar operations, see also `-keep' and `-filter'."
+ (--remove (funcall pred it) list))
+
+(defalias '-reject '-remove)
+(defalias '--reject '--remove)
+
+(defmacro --remove-first (form list)
+ "Remove the first item from LIST for which FORM evals to non-nil.
+Each element of LIST in turn is bound to `it' and its index
+within LIST to `it-index' before evaluating FORM. This is a
+non-destructive operation, but only the front of LIST leading up
+to the removed item is a copy; the rest is LIST's original tail.
+If no item is removed, then the result is a complete copy.
+This is the anaphoric counterpart to `-remove-first'."
+ (declare (debug (form form)))
+ (let ((front (make-symbol "front"))
+ (tail (make-symbol "tail")))
+ `(let ((,tail ,list) ,front)
+ (--each-while ,tail (not ,form)
+ (push (pop ,tail) ,front))
+ (if ,tail
+ (nconc (nreverse ,front) (cdr ,tail))
+ (nreverse ,front)))))
+
+(defun -remove-first (pred list)
+ "Remove the first item from LIST for which PRED returns non-nil.
+This is a non-destructive operation, but only the front of LIST
+leading up to the removed item is a copy; the rest is LIST's
+original tail. If no item is removed, then the result is a
+complete copy.
+
+Alias: `-reject-first'.
+
+This function's anaphoric counterpart is `--remove-first'.
+
+See also `-map-first', `-remove-item', and `-remove-last'."
+ (--remove-first (funcall pred it) list))
+
+(defalias '-reject-first '-remove-first)
+(defalias '--reject-first '--remove-first)
+
+(defmacro --remove-last (form list)
+ "Remove the last item from LIST for which FORM evals to non-nil.
+Each element of LIST in turn is bound to `it' before evaluating
+FORM. The result is a copy of LIST regardless of whether an
+element is removed.
+This is the anaphoric counterpart to `-remove-last'."
+ (declare (debug (form form)))
+ `(nreverse (--remove-first ,form (reverse ,list))))
+
+(defun -remove-last (pred list)
+ "Remove the last item from LIST for which PRED returns non-nil.
+The result is a copy of LIST regardless of whether an element is
+removed.
+
+Alias: `-reject-last'.
+
+This function's anaphoric counterpart is `--remove-last'.
+
+See also `-map-last', `-remove-item', and `-remove-first'."
+ (--remove-last (funcall pred it) list))
+
+(defalias '-reject-last '-remove-last)
+(defalias '--reject-last '--remove-last)
+
+(defalias '-remove-item #'remove
+ "Return a copy of LIST with all occurrences of ITEM removed.
+The comparison is done with `equal'.
+\n(fn ITEM LIST)")
+
+(defmacro --keep (form list)
+ "Eval FORM for each item in LIST and return the non-nil results.
+Like `--filter', but returns the non-nil results of FORM instead
+of the corresponding elements of LIST. Each element of LIST in
+turn is bound to `it' and its index within LIST to `it-index'
+before evaluating FORM.
+This is the anaphoric counterpart to `-keep'."
+ (declare (debug (form form)))
+ (let ((r (make-symbol "result"))
+ (m (make-symbol "mapped")))
+ `(let (,r)
+ (--each ,list (let ((,m ,form)) (when ,m (push ,m ,r))))
+ (nreverse ,r))))
+
+(defun -keep (fn list)
+ "Return a new list of the non-nil results of applying FN to each item in LIST.
+Like `-filter', but returns the non-nil results of FN instead of
+the corresponding elements of LIST.
+
+Its anaphoric counterpart is `--keep'."
+ (--keep (funcall fn it) list))
+
+(defun -non-nil (list)
+ "Return a copy of LIST with all nil items removed."
+ (declare (pure t) (side-effect-free t))
+ (--filter it list))
+
+(defmacro --map-indexed (form list)
+ "Eval FORM for each item in LIST and return the list of results.
+Each element of LIST in turn is bound to `it' and its index
+within LIST to `it-index' before evaluating FORM. This is like
+`--map', but additionally makes `it-index' available to FORM.
+
+This is the anaphoric counterpart to `-map-indexed'."
+ (declare (debug (form form)))
+ (let ((r (make-symbol "result")))
+ `(let (,r)
+ (--each ,list
+ (push ,form ,r))
+ (nreverse ,r))))
+
+(defun -map-indexed (fn list)
+ "Apply FN to each index and item in LIST and return the list of results.
+This is like `-map', but FN takes two arguments: the index of the
+current element within LIST, and the element itself.
+
+This function's anaphoric counterpart is `--map-indexed'.
+
+For a side-effecting variant, see also `-each-indexed'."
+ (--map-indexed (funcall fn it-index it) list))
+
+(defmacro --map-when (pred rep list)
+ "Anaphoric form of `-map-when'."
+ (declare (debug (form form form)))
+ (let ((r (make-symbol "result")))
+ `(let (,r)
+ (--each ,list (!cons (if ,pred ,rep it) ,r))
+ (nreverse ,r))))
+
+(defun -map-when (pred rep list)
+ "Use PRED to conditionally apply REP to each item in LIST.
+Return a copy of LIST where the items for which PRED returns nil
+are unchanged, and the rest are mapped through the REP function.
+
+Alias: `-replace-where'
+
+See also: `-update-at'"
+ (--map-when (funcall pred it) (funcall rep it) list))
+
+(defalias '-replace-where '-map-when)
+(defalias '--replace-where '--map-when)
+
+(defun -map-first (pred rep list)
+ "Use PRED to determine the first item in LIST to call REP on.
+Return a copy of LIST where the first item for which PRED returns
+non-nil is replaced with the result of calling REP on that item.
+
+See also: `-map-when', `-replace-first'"
+ (let (front)
+ (while (and list (not (funcall pred (car list))))
+ (push (car list) front)
+ (!cdr list))
+ (if list
+ (-concat (nreverse front) (cons (funcall rep (car list)) (cdr list)))
+ (nreverse front))))
+
+(defmacro --map-first (pred rep list)
+ "Anaphoric form of `-map-first'."
+ (declare (debug (def-form def-form form)))
+ `(-map-first (lambda (it) ,pred) (lambda (it) (ignore it) ,rep) ,list))
+
+(defun -map-last (pred rep list)
+ "Use PRED to determine the last item in LIST to call REP on.
+Return a copy of LIST where the last item for which PRED returns
+non-nil is replaced with the result of calling REP on that item.
+
+See also: `-map-when', `-replace-last'"
+ (nreverse (-map-first pred rep (reverse list))))
+
+(defmacro --map-last (pred rep list)
+ "Anaphoric form of `-map-last'."
+ (declare (debug (def-form def-form form)))
+ `(-map-last (lambda (it) ,pred) (lambda (it) (ignore it) ,rep) ,list))
+
+(defun -replace (old new list)
+ "Replace all OLD items in LIST with NEW.
+
+Elements are compared using `equal'.
+
+See also: `-replace-at'"
+ (declare (pure t) (side-effect-free t))
+ (--map-when (equal it old) new list))
+
+(defun -replace-first (old new list)
+ "Replace the first occurrence of OLD with NEW in LIST.
+
+Elements are compared using `equal'.
+
+See also: `-map-first'"
+ (declare (pure t) (side-effect-free t))
+ (--map-first (equal old it) new list))
+
+(defun -replace-last (old new list)
+ "Replace the last occurrence of OLD with NEW in LIST.
+
+Elements are compared using `equal'.
+
+See also: `-map-last'"
+ (declare (pure t) (side-effect-free t))
+ (--map-last (equal old it) new list))
+
+(defmacro --mapcat (form list)
+ "Anaphoric form of `-mapcat'."
+ (declare (debug (form form)))
+ `(apply 'append (--map ,form ,list)))
+
+(defun -mapcat (fn list)
+ "Return the concatenation of the result of mapping FN over LIST.
+Thus function FN should return a list."
+ (--mapcat (funcall fn it) list))
+
+(defmacro --iterate (form init n)
+ "Anaphoric version of `-iterate'."
+ (declare (debug (form form form)))
+ (let ((res (make-symbol "result"))
+ (len (make-symbol "n")))
+ `(let ((,len ,n))
+ (when (> ,len 0)
+ (let* ((it ,init)
+ (,res (list it)))
+ (dotimes (_ (1- ,len))
+ (push (setq it ,form) ,res))
+ (nreverse ,res))))))
+
+(defun -iterate (fun init n)
+ "Return a list of iterated applications of FUN to INIT.
+
+This means a list of the form:
+
+ (INIT (FUN INIT) (FUN (FUN INIT)) ...)
+
+N is the length of the returned list."
+ (--iterate (funcall fun it) init n))
+
+(defun -flatten (l)
+ "Take a nested list L and return its contents as a single, flat list.
+
+Note that because nil represents a list of zero elements (an
+empty list), any mention of nil in L will disappear after
+flattening. If you need to preserve nils, consider `-flatten-n'
+or map them to some unique symbol and then map them back.
+
+Conses of two atoms are considered \"terminals\", that is, they
+aren't flattened further.
+
+See also: `-flatten-n'"
+ (declare (pure t) (side-effect-free t))
+ (if (and (listp l) (listp (cdr l)))
+ (-mapcat '-flatten l)
+ (list l)))
+
+(defun -flatten-n (num list)
+ "Flatten NUM levels of a nested LIST.
+
+See also: `-flatten'"
+ (declare (pure t) (side-effect-free t))
+ (dotimes (_ num)
+ (setq list (apply #'append (mapcar #'-list list))))
+ list)
+
+(defalias '-concat #'append)
+
+(defalias '-copy 'copy-sequence
+ "Create a shallow copy of LIST.
+
+\(fn LIST)")
+
+(defun -splice (pred fun list)
+ "Splice lists generated by FUN in place of elements matching PRED in LIST.
+
+FUN takes the element matching PRED as input.
+
+This function can be used as replacement for `,@' in case you
+need to splice several lists at marked positions (for example
+with keywords).
+
+See also: `-splice-list', `-insert-at'"
+ (let (r)
+ (--each list
+ (if (funcall pred it)
+ (let ((new (funcall fun it)))
+ (--each new (!cons it r)))
+ (!cons it r)))
+ (nreverse r)))
+
+(defmacro --splice (pred form list)
+ "Anaphoric form of `-splice'."
+ (declare (debug (def-form def-form form)))
+ `(-splice (lambda (it) ,pred) (lambda (it) ,form) ,list))
+
+(defun -splice-list (pred new-list list)
+ "Splice NEW-LIST in place of elements matching PRED in LIST.
+
+See also: `-splice', `-insert-at'"
+ (-splice pred (lambda (_) new-list) list))
+
+(defmacro --splice-list (pred new-list list)
+ "Anaphoric form of `-splice-list'."
+ (declare (debug (def-form form form)))
+ `(-splice-list (lambda (it) ,pred) ,new-list ,list))
+
+(defun -cons* (&rest args)
+ "Make a new list from the elements of ARGS.
+The last 2 elements of ARGS are used as the final cons of the
+result, so if the final element of ARGS is not a list, the result
+is a dotted list. With no ARGS, return nil."
+ (declare (pure t) (side-effect-free t))
+ (let* ((len (length args))
+ (tail (nthcdr (- len 2) args))
+ (last (cdr tail)))
+ (if (null last)
+ (car args)
+ (setcdr tail (car last))
+ args)))
+
+(defun -snoc (list elem &rest elements)
+ "Append ELEM to the end of the list.
+
+This is like `cons', but operates on the end of list.
+
+If any ELEMENTS are given, append them to the list as well."
+ (-concat list (list elem) elements))
+
+(defmacro --first (form list)
+ "Return the first item in LIST for which FORM evals to non-nil.
+Return nil if no such element is found.
+Each element of LIST in turn is bound to `it' and its index
+within LIST to `it-index' before evaluating FORM.
+This is the anaphoric counterpart to `-first'."
+ (declare (debug (form form)))
+ (let ((n (make-symbol "needle")))
+ `(let (,n)
+ (--each-while ,list (or (not ,form)
+ (ignore (setq ,n it))))
+ ,n)))
+
+(defun -first (pred list)
+ "Return the first item in LIST for which PRED returns non-nil.
+Return nil if no such element is found.
+To get the first item in the list no questions asked, use `car'.
+
+Alias: `-find'.
+
+This function's anaphoric counterpart is `--first'."
+ (--first (funcall pred it) list))
+
+(defalias '-find '-first)
+(defalias '--find '--first)
+
+(defmacro --some (form list)
+ "Return non-nil if FORM evals to non-nil for at least one item in LIST.
+If so, return the first such result of FORM.
+Each element of LIST in turn is bound to `it' and its index
+within LIST to `it-index' before evaluating FORM.
+This is the anaphoric counterpart to `-some'."
+ (declare (debug (form form)))
+ (let ((n (make-symbol "needle")))
+ `(let (,n)
+ (--each-while ,list (not (setq ,n ,form)))
+ ,n)))
+
+(defun -some (pred list)
+ "Return (PRED x) for the first LIST item where (PRED x) is non-nil, else nil.
+
+Alias: `-any'.
+
+This function's anaphoric counterpart is `--some'."
+ (--some (funcall pred it) list))
+
+(defalias '-any '-some)
+(defalias '--any '--some)
+
+(defmacro --every (form list)
+ "Return non-nil if FORM evals to non-nil for all items in LIST.
+If so, return the last such result of FORM. Otherwise, once an
+item is reached for which FORM yields nil, return nil without
+evaluating FORM for any further LIST elements.
+Each element of LIST in turn is bound to `it' and its index
+within LIST to `it-index' before evaluating FORM.
+
+This macro is like `--every-p', but on success returns the last
+non-nil result of FORM instead of just t.
+
+This is the anaphoric counterpart to `-every'."
+ (declare (debug (form form)))
+ (let ((a (make-symbol "all")))
+ `(let ((,a t))
+ (--each-while ,list (setq ,a ,form))
+ ,a)))
+
+(defun -every (pred list)
+ "Return non-nil if PRED returns non-nil for all items in LIST.
+If so, return the last such result of PRED. Otherwise, once an
+item is reached for which PRED returns nil, return nil without
+calling PRED on any further LIST elements.
+
+This function is like `-every-p', but on success returns the last
+non-nil result of PRED instead of just t.
+
+This function's anaphoric counterpart is `--every'."
+ (--every (funcall pred it) list))
+
+(defmacro --last (form list)
+ "Anaphoric form of `-last'."
+ (declare (debug (form form)))
+ (let ((n (make-symbol "needle")))
+ `(let (,n)
+ (--each ,list
+ (when ,form (setq ,n it)))
+ ,n)))
+
+(defun -last (pred list)
+ "Return the last x in LIST where (PRED x) is non-nil, else nil."
+ (--last (funcall pred it) list))
+
+(defalias '-first-item 'car
+ "Return the first item of LIST, or nil on an empty list.
+
+See also: `-second-item', `-last-item'.
+
+\(fn LIST)")
+
+;; Ensure that calls to `-first-item' are compiled to a single opcode,
+;; just like `car'.
+(put '-first-item 'byte-opcode 'byte-car)
+(put '-first-item 'byte-compile 'byte-compile-one-arg)
+
+(defalias '-second-item 'cadr
+ "Return the second item of LIST, or nil if LIST is too short.
+
+See also: `-third-item'.
+
+\(fn LIST)")
+
+(defalias '-third-item
+ (if (fboundp 'caddr)
+ #'caddr
+ (lambda (list) (car (cddr list))))
+ "Return the third item of LIST, or nil if LIST is too short.
+
+See also: `-fourth-item'.
+
+\(fn LIST)")
+
+(defun -fourth-item (list)
+ "Return the fourth item of LIST, or nil if LIST is too short.
+
+See also: `-fifth-item'."
+ (declare (pure t) (side-effect-free t))
+ (car (cdr (cdr (cdr list)))))
+
+(defun -fifth-item (list)
+ "Return the fifth item of LIST, or nil if LIST is too short.
+
+See also: `-last-item'."
+ (declare (pure t) (side-effect-free t))
+ (car (cdr (cdr (cdr (cdr list))))))
+
+(defun -last-item (list)
+ "Return the last item of LIST, or nil on an empty list."
+ (declare (pure t) (side-effect-free t))
+ (car (last list)))
+
+;; Use `with-no-warnings' to suppress unbound `-last-item' or
+;; undefined `gv--defsetter' warnings arising from both
+;; `gv-define-setter' and `defsetf' in certain Emacs versions.
+(with-no-warnings
+ (if (fboundp 'gv-define-setter)
+ (gv-define-setter -last-item (val x) `(setcar (last ,x) ,val))
+ (defsetf -last-item (x) (val) `(setcar (last ,x) ,val))))
+
+(defun -butlast (list)
+ "Return a list of all items in list except for the last."
+ ;; no alias as we don't want magic optional argument
+ (declare (pure t) (side-effect-free t))
+ (butlast list))
+
+(defmacro --count (pred list)
+ "Anaphoric form of `-count'."
+ (declare (debug (form form)))
+ (let ((r (make-symbol "result")))
+ `(let ((,r 0))
+ (--each ,list (when ,pred (setq ,r (1+ ,r))))
+ ,r)))
+
+(defun -count (pred list)
+ "Counts the number of items in LIST where (PRED item) is non-nil."
+ (--count (funcall pred it) list))
+
+(defun ---truthy? (obj)
+ "Return OBJ as a boolean value (t or nil)."
+ (declare (pure t) (side-effect-free t))
+ (and obj t))
+
+(defmacro --any? (form list)
+ "Anaphoric form of `-any?'."
+ (declare (debug (form form)))
+ `(and (--some ,form ,list) t))
+
+(defun -any? (pred list)
+ "Return t if (PRED X) is non-nil for any X in LIST, else nil.
+
+Alias: `-any-p', `-some?', `-some-p'"
+ (--any? (funcall pred it) list))
+
+(defalias '-some? '-any?)
+(defalias '--some? '--any?)
+(defalias '-any-p '-any?)
+(defalias '--any-p '--any?)
+(defalias '-some-p '-any?)
+(defalias '--some-p '--any?)
+
+(defmacro --all? (form list)
+ "Return t if FORM evals to non-nil for all items in LIST.
+Otherwise, once an item is reached for which FORM yields nil,
+return nil without evaluating FORM for any further LIST elements.
+Each element of LIST in turn is bound to `it' and its index
+within LIST to `it-index' before evaluating FORM.
+
+The similar macro `--every' is more widely useful, since it
+returns the last non-nil result of FORM instead of just t on
+success.
+
+Alias: `--all-p', `--every-p', `--every?'.
+
+This is the anaphoric counterpart to `-all?'."
+ (declare (debug (form form)))
+ `(and (--every ,form ,list) t))
+
+(defun -all? (pred list)
+ "Return t if (PRED X) is non-nil for all X in LIST, else nil.
+In the latter case, stop after the first X for which (PRED X) is
+nil, without calling PRED on any subsequent elements of LIST.
+
+The similar function `-every' is more widely useful, since it
+returns the last non-nil result of PRED instead of just t on
+success.
+
+Alias: `-all-p', `-every-p', `-every?'.
+
+This function's anaphoric counterpart is `--all?'."
+ (--all? (funcall pred it) list))
+
+(defalias '-every? '-all?)
+(defalias '--every? '--all?)
+(defalias '-all-p '-all?)
+(defalias '--all-p '--all?)
+(defalias '-every-p '-all?)
+(defalias '--every-p '--all?)
+
+(defmacro --none? (form list)
+ "Anaphoric form of `-none?'."
+ (declare (debug (form form)))
+ `(--all? (not ,form) ,list))
+
+(defun -none? (pred list)
+ "Return t if (PRED X) is nil for all X in LIST, else nil.
+
+Alias: `-none-p'"
+ (--none? (funcall pred it) list))
+
+(defalias '-none-p '-none?)
+(defalias '--none-p '--none?)
+
+(defmacro --only-some? (form list)
+ "Anaphoric form of `-only-some?'."
+ (declare (debug (form form)))
+ (let ((y (make-symbol "yes"))
+ (n (make-symbol "no")))
+ `(let (,y ,n)
+ (--each-while ,list (not (and ,y ,n))
+ (if ,form (setq ,y t) (setq ,n t)))
+ (---truthy? (and ,y ,n)))))
+
+(defun -only-some? (pred list)
+ "Return t if different LIST items both satisfy and do not satisfy PRED.
+That is, if PRED returns both nil for at least one item, and
+non-nil for at least one other item in LIST. Return nil if all
+items satisfy the predicate or none of them do.
+
+Alias: `-only-some-p'"
+ (--only-some? (funcall pred it) list))
+
+(defalias '-only-some-p '-only-some?)
+(defalias '--only-some-p '--only-some?)
+
+(defun -slice (list from &optional to step)
+ "Return copy of LIST, starting from index FROM to index TO.
+
+FROM or TO may be negative. These values are then interpreted
+modulo the length of the list.
+
+If STEP is a number, only each STEPth item in the resulting
+section is returned. Defaults to 1."
+ (declare (pure t) (side-effect-free t))
+ (let ((length (length list))
+ (new-list nil))
+ ;; to defaults to the end of the list
+ (setq to (or to length))
+ (setq step (or step 1))
+ ;; handle negative indices
+ (when (< from 0)
+ (setq from (mod from length)))
+ (when (< to 0)
+ (setq to (mod to length)))
+
+ ;; iterate through the list, keeping the elements we want
+ (--each-while list (< it-index to)
+ (when (and (>= it-index from)
+ (= (mod (- from it-index) step) 0))
+ (push it new-list)))
+ (nreverse new-list)))
+
+(defmacro --take-while (form list)
+ "Take successive items from LIST for which FORM evals to non-nil.
+Each element of LIST in turn is bound to `it' and its index
+within LIST to `it-index' before evaluating FORM. Return a new
+list of the successive elements from the start of LIST for which
+FORM evaluates to non-nil.
+This is the anaphoric counterpart to `-take-while'."
+ (declare (debug (form form)))
+ (let ((r (make-symbol "result")))
+ `(let (,r)
+ (--each-while ,list ,form (push it ,r))
+ (nreverse ,r))))
+
+(defun -take-while (pred list)
+ "Take successive items from LIST for which PRED returns non-nil.
+PRED is a function of one argument. Return a new list of the
+successive elements from the start of LIST for which PRED returns
+non-nil.
+
+This function's anaphoric counterpart is `--take-while'.
+
+For another variant, see also `-drop-while'."
+ (--take-while (funcall pred it) list))
+
+(defmacro --drop-while (form list)
+ "Drop successive items from LIST for which FORM evals to non-nil.
+Each element of LIST in turn is bound to `it' and its index
+within LIST to `it-index' before evaluating FORM. Return the
+tail (not a copy) of LIST starting from its first element for
+which FORM evaluates to nil.
+This is the anaphoric counterpart to `-drop-while'."
+ (declare (debug (form form)))
+ (let ((l (make-symbol "list")))
+ `(let ((,l ,list))
+ (--each-while ,l ,form (pop ,l))
+ ,l)))
+
+(defun -drop-while (pred list)
+ "Drop successive items from LIST for which PRED returns non-nil.
+PRED is a function of one argument. Return the tail (not a copy)
+of LIST starting from its first element for which PRED returns
+nil.
+
+This function's anaphoric counterpart is `--drop-while'.
+
+For another variant, see also `-take-while'."
+ (--drop-while (funcall pred it) list))
+
+(defun -take (n list)
+ "Return a copy of the first N items in LIST.
+Return a copy of LIST if it contains N items or fewer.
+Return nil if N is zero or less.
+
+See also: `-take-last'."
+ (declare (pure t) (side-effect-free t))
+ (--take-while (< it-index n) list))
+
+(defun -take-last (n list)
+ "Return a copy of the last N items of LIST in order.
+Return a copy of LIST if it contains N items or fewer.
+Return nil if N is zero or less.
+
+See also: `-take'."
+ (declare (pure t) (side-effect-free t))
+ (copy-sequence (last list n)))
+
+(defalias '-drop #'nthcdr
+ "Return the tail (not a copy) of LIST without the first N items.
+Return nil if LIST contains N items or fewer.
+Return LIST if N is zero or less.
+
+For another variant, see also `-drop-last'.
+\n(fn N LIST)")
+
+(defun -drop-last (n list)
+ "Return a copy of LIST without its last N items.
+Return a copy of LIST if N is zero or less.
+Return nil if LIST contains N items or fewer.
+
+See also: `-drop'."
+ (declare (pure t) (side-effect-free t))
+ (nbutlast (copy-sequence list) n))
+
+(defun -split-at (n list)
+ "Split LIST into two sublists after the Nth element.
+The result is a list of two elements (TAKE DROP) where TAKE is a
+new list of the first N elements of LIST, and DROP is the
+remaining elements of LIST (not a copy). TAKE and DROP are like
+the results of `-take' and `-drop', respectively, but the split
+is done in a single list traversal."
+ (declare (pure t) (side-effect-free t))
+ (let (result)
+ (--each-while list (< it-index n)
+ (push (pop list) result))
+ (list (nreverse result) list)))
+
+(defun -rotate (n list)
+ "Rotate LIST N places to the right (left if N is negative).
+The time complexity is O(n)."
+ (declare (pure t) (side-effect-free t))
+ (cond ((null list) ())
+ ((zerop n) (copy-sequence list))
+ ((let* ((len (length list))
+ (n-mod-len (mod n len))
+ (new-tail-len (- len n-mod-len)))
+ (append (nthcdr new-tail-len list) (-take new-tail-len list))))))
+
+(defun -insert-at (n x list)
+ "Return a list with X inserted into LIST at position N.
+
+See also: `-splice', `-splice-list'"
+ (declare (pure t) (side-effect-free t))
+ (let ((split-list (-split-at n list)))
+ (nconc (car split-list) (cons x (cadr split-list)))))
+
+(defun -replace-at (n x list)
+ "Return a list with element at Nth position in LIST replaced with X.
+
+See also: `-replace'"
+ (declare (pure t) (side-effect-free t))
+ (let ((split-list (-split-at n list)))
+ (nconc (car split-list) (cons x (cdr (cadr split-list))))))
+
+(defun -update-at (n func list)
+ "Use FUNC to update the Nth element of LIST.
+Return a copy of LIST where the Nth element is replaced with the
+result of calling FUNC on it.
+
+See also: `-map-when'"
+ (let ((split-list (-split-at n list)))
+ (nconc (car split-list)
+ (cons (funcall func (car (cadr split-list)))
+ (cdr (cadr split-list))))))
+
+(defmacro --update-at (n form list)
+ "Anaphoric version of `-update-at'."
+ (declare (debug (form def-form form)))
+ `(-update-at ,n (lambda (it) ,form) ,list))
+
+(defun -remove-at (n list)
+ "Return a list with element at Nth position in LIST removed.
+
+See also: `-remove-at-indices', `-remove'"
+ (declare (pure t) (side-effect-free t))
+ (-remove-at-indices (list n) list))
+
+(defun -remove-at-indices (indices list)
+ "Return a list whose elements are elements from LIST without
+elements selected as `(nth i list)` for all i
+from INDICES.
+
+See also: `-remove-at', `-remove'"
+ (declare (pure t) (side-effect-free t))
+ (let* ((indices (-sort '< indices))
+ (diffs (cons (car indices) (-map '1- (-zip-with '- (cdr indices) indices))))
+ r)
+ (--each diffs
+ (let ((split (-split-at it list)))
+ (!cons (car split) r)
+ (setq list (cdr (cadr split)))))
+ (!cons list r)
+ (apply '-concat (nreverse r))))
+
+(defmacro --split-with (pred list)
+ "Anaphoric form of `-split-with'."
+ (declare (debug (form form)))
+ (let ((l (make-symbol "list"))
+ (r (make-symbol "result"))
+ (c (make-symbol "continue")))
+ `(let ((,l ,list)
+ (,r nil)
+ (,c t))
+ (while (and ,l ,c)
+ (let ((it (car ,l)))
+ (if (not ,pred)
+ (setq ,c nil)
+ (!cons it ,r)
+ (!cdr ,l))))
+ (list (nreverse ,r) ,l))))
+
+(defun -split-with (pred list)
+ "Split LIST into a prefix satisfying PRED, and the rest.
+The first sublist is the prefix of LIST with successive elements
+satisfying PRED, and the second sublist is the remaining elements
+that do not. The result is like performing
+
+ ((-take-while PRED LIST) (-drop-while PRED LIST))
+
+but in no more than a single pass through LIST."
+ (--split-with (funcall pred it) list))
+
+(defmacro -split-on (item list)
+ "Split the LIST each time ITEM is found.
+
+Unlike `-partition-by', the ITEM is discarded from the results.
+Empty lists are also removed from the result.
+
+Comparison is done by `equal'.
+
+See also `-split-when'"
+ (declare (debug (def-form form)))
+ `(-split-when (lambda (it) (equal it ,item)) ,list))
+
+(defmacro --split-when (form list)
+ "Anaphoric version of `-split-when'."
+ (declare (debug (def-form form)))
+ `(-split-when (lambda (it) ,form) ,list))
+
+(defun -split-when (fn list)
+ "Split the LIST on each element where FN returns non-nil.
+
+Unlike `-partition-by', the \"matched\" element is discarded from
+the results. Empty lists are also removed from the result.
+
+This function can be thought of as a generalization of
+`split-string'."
+ (let (r s)
+ (while list
+ (if (not (funcall fn (car list)))
+ (push (car list) s)
+ (when s (push (nreverse s) r))
+ (setq s nil))
+ (!cdr list))
+ (when s (push (nreverse s) r))
+ (nreverse r)))
+
+(defmacro --separate (form list)
+ "Anaphoric form of `-separate'."
+ (declare (debug (form form)))
+ (let ((y (make-symbol "yes"))
+ (n (make-symbol "no")))
+ `(let (,y ,n)
+ (--each ,list (if ,form (!cons it ,y) (!cons it ,n)))
+ (list (nreverse ,y) (nreverse ,n)))))
+
+(defun -separate (pred list)
+ "Split LIST into two sublists based on whether items satisfy PRED.
+The result is like performing
+
+ ((-filter PRED LIST) (-remove PRED LIST))
+
+but in a single pass through LIST."
+ (--separate (funcall pred it) list))
+
+(defun dash--partition-all-in-steps-reversed (n step list)
+ "Like `-partition-all-in-steps', but the result is reversed."
+ (when (< step 1)
+ (signal 'wrong-type-argument
+ `("Step size < 1 results in juicy infinite loops" ,step)))
+ (let (result)
+ (while list
+ (push (-take n list) result)
+ (setq list (nthcdr step list)))
+ result))
+
+(defun -partition-all-in-steps (n step list)
+ "Partition LIST into sublists of length N that are STEP items apart.
+Adjacent groups may overlap if N exceeds the STEP stride.
+Trailing groups may contain less than N items."
+ (declare (pure t) (side-effect-free t))
+ (nreverse (dash--partition-all-in-steps-reversed n step list)))
+
+(defun -partition-in-steps (n step list)
+ "Partition LIST into sublists of length N that are STEP items apart.
+Like `-partition-all-in-steps', but if there are not enough items
+to make the last group N-sized, those items are discarded."
+ (declare (pure t) (side-effect-free t))
+ (let ((result (dash--partition-all-in-steps-reversed n step list)))
+ (while (and result (< (length (car result)) n))
+ (pop result))
+ (nreverse result)))
+
+(defun -partition-all (n list)
+ "Return a new list with the items in LIST grouped into N-sized sublists.
+The last group may contain less than N items."
+ (declare (pure t) (side-effect-free t))
+ (-partition-all-in-steps n n list))
+
+(defun -partition (n list)
+ "Return a new list with the items in LIST grouped into N-sized sublists.
+If there are not enough items to make the last group N-sized,
+those items are discarded."
+ (declare (pure t) (side-effect-free t))
+ (-partition-in-steps n n list))
+
+(defmacro --partition-by (form list)
+ "Anaphoric form of `-partition-by'."
+ (declare (debug (form form)))
+ (let ((r (make-symbol "result"))
+ (s (make-symbol "sublist"))
+ (v (make-symbol "value"))
+ (n (make-symbol "new-value"))
+ (l (make-symbol "list")))
+ `(let ((,l ,list))
+ (when ,l
+ (let* ((,r nil)
+ (it (car ,l))
+ (,s (list it))
+ (,v ,form)
+ (,l (cdr ,l)))
+ (while ,l
+ (let* ((it (car ,l))
+ (,n ,form))
+ (unless (equal ,v ,n)
+ (!cons (nreverse ,s) ,r)
+ (setq ,s nil)
+ (setq ,v ,n))
+ (!cons it ,s)
+ (!cdr ,l)))
+ (!cons (nreverse ,s) ,r)
+ (nreverse ,r))))))
+
+(defun -partition-by (fn list)
+ "Apply FN to each item in LIST, splitting it each time FN returns a new value."
+ (--partition-by (funcall fn it) list))
+
+(defmacro --partition-by-header (form list)
+ "Anaphoric form of `-partition-by-header'."
+ (declare (debug (form form)))
+ (let ((r (make-symbol "result"))
+ (s (make-symbol "sublist"))
+ (h (make-symbol "header-value"))
+ (b (make-symbol "seen-body?"))
+ (n (make-symbol "new-value"))
+ (l (make-symbol "list")))
+ `(let ((,l ,list))
+ (when ,l
+ (let* ((,r nil)
+ (it (car ,l))
+ (,s (list it))
+ (,h ,form)
+ (,b nil)
+ (,l (cdr ,l)))
+ (while ,l
+ (let* ((it (car ,l))
+ (,n ,form))
+ (if (equal ,h ,n)
+ (when ,b
+ (!cons (nreverse ,s) ,r)
+ (setq ,s nil)
+ (setq ,b nil))
+ (setq ,b t))
+ (!cons it ,s)
+ (!cdr ,l)))
+ (!cons (nreverse ,s) ,r)
+ (nreverse ,r))))))
+
+(defun -partition-by-header (fn list)
+ "Apply FN to the first item in LIST. That is the header
+value. Apply FN to each item in LIST, splitting it each time FN
+returns the header value, but only after seeing at least one
+other value (the body)."
+ (--partition-by-header (funcall fn it) list))
+
+(defmacro --partition-after-pred (form list)
+ "Partition LIST after each element for which FORM evaluates to non-nil.
+Each element of LIST in turn is bound to `it' before evaluating
+FORM.
+
+This is the anaphoric counterpart to `-partition-after-pred'."
+ (let ((l (make-symbol "list"))
+ (r (make-symbol "result"))
+ (s (make-symbol "sublist")))
+ `(let ((,l ,list) ,r ,s)
+ (when ,l
+ (--each ,l
+ (push it ,s)
+ (when ,form
+ (push (nreverse ,s) ,r)
+ (setq ,s ())))
+ (when ,s
+ (push (nreverse ,s) ,r))
+ (nreverse ,r)))))
+
+(defun -partition-after-pred (pred list)
+ "Partition LIST after each element for which PRED returns non-nil.
+
+This function's anaphoric counterpart is `--partition-after-pred'."
+ (--partition-after-pred (funcall pred it) list))
+
+(defun -partition-before-pred (pred list)
+ "Partition directly before each time PRED is true on an element of LIST."
+ (nreverse (-map #'reverse
+ (-partition-after-pred pred (reverse list)))))
+
+(defun -partition-after-item (item list)
+ "Partition directly after each time ITEM appears in LIST."
+ (-partition-after-pred (lambda (ele) (equal ele item))
+ list))
+
+(defun -partition-before-item (item list)
+ "Partition directly before each time ITEM appears in LIST."
+ (-partition-before-pred (lambda (ele) (equal ele item))
+ list))
+
+(defmacro --group-by (form list)
+ "Anaphoric form of `-group-by'."
+ (declare (debug t))
+ (let ((n (make-symbol "n"))
+ (k (make-symbol "k"))
+ (grp (make-symbol "grp")))
+ `(nreverse
+ (-map
+ (lambda (,n)
+ (cons (car ,n)
+ (nreverse (cdr ,n))))
+ (--reduce-from
+ (let* ((,k (,@form))
+ (,grp (assoc ,k acc)))
+ (if ,grp
+ (setcdr ,grp (cons it (cdr ,grp)))
+ (push
+ (list ,k it)
+ acc))
+ acc)
+ nil ,list)))))
+
+(defun -group-by (fn list)
+ "Separate LIST into an alist whose keys are FN applied to the
+elements of LIST. Keys are compared by `equal'."
+ (--group-by (funcall fn it) list))
+
+(defun -interpose (sep list)
+ "Return a new list of all elements in LIST separated by SEP."
+ (declare (pure t) (side-effect-free t))
+ (let (result)
+ (when list
+ (!cons (car list) result)
+ (!cdr list))
+ (while list
+ (setq result (cons (car list) (cons sep result)))
+ (!cdr list))
+ (nreverse result)))
+
+(defun -interleave (&rest lists)
+ "Return a new list of the first item in each list, then the second etc."
+ (declare (pure t) (side-effect-free t))
+ (when lists
+ (let (result)
+ (while (-none? 'null lists)
+ (--each lists (!cons (car it) result))
+ (setq lists (-map 'cdr lists)))
+ (nreverse result))))
+
+(defmacro --zip-with (form list1 list2)
+ "Anaphoric form of `-zip-with'.
+
+Each element in turn of LIST1 is bound to `it', and of LIST2 to
+`other', before evaluating FORM."
+ (declare (debug (form form form)))
+ (let ((r (make-symbol "result"))
+ (l1 (make-symbol "list1"))
+ (l2 (make-symbol "list2")))
+ `(let ((,r nil)
+ (,l1 ,list1)
+ (,l2 ,list2))
+ (while (and ,l1 ,l2)
+ (let ((it (car ,l1))
+ (other (car ,l2)))
+ (!cons ,form ,r)
+ (!cdr ,l1)
+ (!cdr ,l2)))
+ (nreverse ,r))))
+
+(defun -zip-with (fn list1 list2)
+ "Zip the two lists LIST1 and LIST2 using a function FN. This
+function is applied pairwise taking as first argument element of
+LIST1 and as second argument element of LIST2 at corresponding
+position.
+
+The anaphoric form `--zip-with' binds the elements from LIST1 as symbol `it',
+and the elements from LIST2 as symbol `other'."
+ (--zip-with (funcall fn it other) list1 list2))
+
+(defun -zip-lists (&rest lists)
+ "Zip LISTS together. Group the head of each list, followed by the
+second elements of each list, and so on. The lengths of the returned
+groupings are equal to the length of the shortest input list.
+
+The return value is always list of lists, which is a difference
+from `-zip-pair' which returns a cons-cell in case two input
+lists are provided.
+
+See also: `-zip'"
+ (declare (pure t) (side-effect-free t))
+ (when lists
+ (let (results)
+ (while (-none? 'null lists)
+ (setq results (cons (mapcar 'car lists) results))
+ (setq lists (mapcar 'cdr lists)))
+ (nreverse results))))
+
+(defun -zip (&rest lists)
+ "Zip LISTS together. Group the head of each list, followed by the
+second elements of each list, and so on. The lengths of the returned
+groupings are equal to the length of the shortest input list.
+
+If two lists are provided as arguments, return the groupings as a list
+of cons cells. Otherwise, return the groupings as a list of lists.
+
+Use `-zip-lists' if you need the return value to always be a list
+of lists.
+
+Alias: `-zip-pair'
+
+See also: `-zip-lists'"
+ (declare (pure t) (side-effect-free t))
+ (when lists
+ (let (results)
+ (while (-none? 'null lists)
+ (setq results (cons (mapcar 'car lists) results))
+ (setq lists (mapcar 'cdr lists)))
+ (setq results (nreverse results))
+ (if (= (length lists) 2)
+ ;; to support backward compatibility, return
+ ;; a cons cell if two lists were provided
+ (--map (cons (car it) (cadr it)) results)
+ results))))
+
+(defalias '-zip-pair '-zip)
+
+(defun -zip-fill (fill-value &rest lists)
+ "Zip LISTS, with FILL-VALUE padded onto the shorter lists. The
+lengths of the returned groupings are equal to the length of the
+longest input list."
+ (declare (pure t) (side-effect-free t))
+ (apply '-zip (apply '-pad (cons fill-value lists))))
+
+(defun -unzip (lists)
+ "Unzip LISTS.
+
+This works just like `-zip' but takes a list of lists instead of
+a variable number of arguments, such that
+
+ (-unzip (-zip L1 L2 L3 ...))
+
+is identity (given that the lists are the same length).
+
+Note in particular that calling this on a list of two lists will
+return a list of cons-cells such that the above identity works.
+
+See also: `-zip'"
+ (apply '-zip lists))
+
+(defun -cycle (list)
+ "Return an infinite circular copy of LIST.
+The returned list cycles through the elements of LIST and repeats
+from the beginning."
+ (declare (pure t) (side-effect-free t))
+ ;; Also works with sequences that aren't lists.
+ (let ((newlist (append list ())))
+ (nconc newlist newlist)))
+
+(defun -pad (fill-value &rest lists)
+ "Appends FILL-VALUE to the end of each list in LISTS such that they
+will all have the same length."
+ (let* ((annotations (-annotate 'length lists))
+ (n (-max (-map 'car annotations))))
+ (--map (append (cdr it) (-repeat (- n (car it)) fill-value)) annotations)))
+
+(defun -annotate (fn list)
+ "Return a list of cons cells where each cell is FN applied to each
+element of LIST paired with the unmodified element of LIST."
+ (-zip (-map fn list) list))
+
+(defmacro --annotate (form list)
+ "Anaphoric version of `-annotate'."
+ (declare (debug (def-form form)))
+ `(-annotate (lambda (it) ,form) ,list))
+
+(defun dash--table-carry (lists restore-lists &optional re)
+ "Helper for `-table' and `-table-flat'.
+
+If a list overflows, carry to the right and reset the list."
+ (while (not (or (car lists)
+ (equal lists '(nil))))
+ (setcar lists (car restore-lists))
+ (pop (cadr lists))
+ (!cdr lists)
+ (!cdr restore-lists)
+ (when re
+ (push (nreverse (car re)) (cadr re))
+ (setcar re nil)
+ (!cdr re))))
+
+(defun -table (fn &rest lists)
+ "Compute outer product of LISTS using function FN.
+
+The function FN should have the same arity as the number of
+supplied lists.
+
+The outer product is computed by applying fn to all possible
+combinations created by taking one element from each list in
+order. The dimension of the result is (length lists).
+
+See also: `-table-flat'"
+ (let ((restore-lists (copy-sequence lists))
+ (last-list (last lists))
+ (re (make-list (length lists) nil)))
+ (while (car last-list)
+ (let ((item (apply fn (-map 'car lists))))
+ (push item (car re))
+ (setcar lists (cdar lists)) ;; silence byte compiler
+ (dash--table-carry lists restore-lists re)))
+ (nreverse (car (last re)))))
+
+(defun -table-flat (fn &rest lists)
+ "Compute flat outer product of LISTS using function FN.
+
+The function FN should have the same arity as the number of
+supplied lists.
+
+The outer product is computed by applying fn to all possible
+combinations created by taking one element from each list in
+order. The results are flattened, ignoring the tensor structure
+of the result. This is equivalent to calling:
+
+ (-flatten-n (1- (length lists)) (apply \\='-table fn lists))
+
+but the implementation here is much more efficient.
+
+See also: `-flatten-n', `-table'"
+ (let ((restore-lists (copy-sequence lists))
+ (last-list (last lists))
+ re)
+ (while (car last-list)
+ (let ((item (apply fn (-map 'car lists))))
+ (push item re)
+ (setcar lists (cdar lists)) ;; silence byte compiler
+ (dash--table-carry lists restore-lists)))
+ (nreverse re)))
+
+(defun -elem-index (elem list)
+ "Return the index of the first element in the given LIST which
+is equal to the query element ELEM, or nil if there is no
+such element."
+ (declare (pure t) (side-effect-free t))
+ (car (-elem-indices elem list)))
+
+(defun -elem-indices (elem list)
+ "Return the indices of all elements in LIST equal to the query
+element ELEM, in ascending order."
+ (declare (pure t) (side-effect-free t))
+ (-find-indices (-partial 'equal elem) list))
+
+(defun -find-indices (pred list)
+ "Return the indices of all elements in LIST satisfying the
+predicate PRED, in ascending order."
+ (apply 'append (--map-indexed (when (funcall pred it) (list it-index)) list)))
+
+(defmacro --find-indices (form list)
+ "Anaphoric version of `-find-indices'."
+ (declare (debug (def-form form)))
+ `(-find-indices (lambda (it) ,form) ,list))
+
+(defun -find-index (pred list)
+ "Take a predicate PRED and a LIST and return the index of the
+first element in the list satisfying the predicate, or nil if
+there is no such element.
+
+See also `-first'."
+ (car (-find-indices pred list)))
+
+(defmacro --find-index (form list)
+ "Anaphoric version of `-find-index'."
+ (declare (debug (def-form form)))
+ `(-find-index (lambda (it) ,form) ,list))
+
+(defun -find-last-index (pred list)
+ "Take a predicate PRED and a LIST and return the index of the
+last element in the list satisfying the predicate, or nil if
+there is no such element.
+
+See also `-last'."
+ (-last-item (-find-indices pred list)))
+
+(defmacro --find-last-index (form list)
+ "Anaphoric version of `-find-last-index'."
+ (declare (debug (def-form form)))
+ `(-find-last-index (lambda (it) ,form) ,list))
+
+(defun -select-by-indices (indices list)
+ "Return a list whose elements are elements from LIST selected
+as `(nth i list)` for all i from INDICES."
+ (declare (pure t) (side-effect-free t))
+ (let (r)
+ (--each indices
+ (!cons (nth it list) r))
+ (nreverse r)))
+
+(defun -select-columns (columns table)
+ "Select COLUMNS from TABLE.
+
+TABLE is a list of lists where each element represents one row.
+It is assumed each row has the same length.
+
+Each row is transformed such that only the specified COLUMNS are
+selected.
+
+See also: `-select-column', `-select-by-indices'"
+ (declare (pure t) (side-effect-free t))
+ (--map (-select-by-indices columns it) table))
+
+(defun -select-column (column table)
+ "Select COLUMN from TABLE.
+
+TABLE is a list of lists where each element represents one row.
+It is assumed each row has the same length.
+
+The single selected column is returned as a list.
+
+See also: `-select-columns', `-select-by-indices'"
+ (declare (pure t) (side-effect-free t))
+ (--mapcat (-select-by-indices (list column) it) table))
+
+(defmacro -> (x &optional form &rest more)
+ "Thread the expr through the forms. Insert X as the second item
+in the first form, making a list of it if it is not a list
+already. If there are more forms, insert the first form as the
+second item in second form, etc."
+ (declare (debug (form &rest [&or symbolp (sexp &rest form)])))
+ (cond
+ ((null form) x)
+ ((null more) (if (listp form)
+ `(,(car form) ,x ,@(cdr form))
+ (list form x)))
+ (:else `(-> (-> ,x ,form) ,@more))))
+
+(defmacro ->> (x &optional form &rest more)
+ "Thread the expr through the forms. Insert X as the last item
+in the first form, making a list of it if it is not a list
+already. If there are more forms, insert the first form as the
+last item in second form, etc."
+ (declare (debug ->))
+ (cond
+ ((null form) x)
+ ((null more) (if (listp form)
+ `(,@form ,x)
+ (list form x)))
+ (:else `(->> (->> ,x ,form) ,@more))))
+
+(defmacro --> (x &rest forms)
+ "Starting with the value of X, thread each expression through FORMS.
+
+Insert X at the position signified by the symbol `it' in the first
+form. If there are more forms, insert the first form at the position
+signified by `it' in in second form, etc."
+ (declare (debug (form body)))
+ `(-as-> ,x it ,@forms))
+
+(defmacro -as-> (value variable &rest forms)
+ "Starting with VALUE, thread VARIABLE through FORMS.
+
+In the first form, bind VARIABLE to VALUE. In the second form, bind
+VARIABLE to the result of the first form, and so forth."
+ (declare (debug (form symbolp body)))
+ (if (null forms)
+ `,value
+ `(let ((,variable ,value))
+ (-as-> ,(if (symbolp (car forms))
+ (list (car forms) variable)
+ (car forms))
+ ,variable
+ ,@(cdr forms)))))
+
+(defmacro -some-> (x &optional form &rest more)
+ "When expr is non-nil, thread it through the first form (via `->'),
+and when that result is non-nil, through the next form, etc."
+ (declare (debug ->)
+ (indent 1))
+ (if (null form) x
+ (let ((result (make-symbol "result")))
+ `(-some-> (-when-let (,result ,x)
+ (-> ,result ,form))
+ ,@more))))
+
+(defmacro -some->> (x &optional form &rest more)
+ "When expr is non-nil, thread it through the first form (via `->>'),
+and when that result is non-nil, through the next form, etc."
+ (declare (debug ->)
+ (indent 1))
+ (if (null form) x
+ (let ((result (make-symbol "result")))
+ `(-some->> (-when-let (,result ,x)
+ (->> ,result ,form))
+ ,@more))))
+
+(defmacro -some--> (expr &rest forms)
+ "Thread EXPR through FORMS via `-->', while the result is non-nil.
+When EXPR evaluates to non-nil, thread the result through the
+first of FORMS, and when that result is non-nil, thread it
+through the next form, etc."
+ (declare (debug (form &rest &or symbolp consp)) (indent 1))
+ (if (null forms) expr
+ (let ((result (make-symbol "result")))
+ `(-some--> (-when-let (,result ,expr)
+ (--> ,result ,(car forms)))
+ ,@(cdr forms)))))
+
+(defmacro -doto (init &rest forms)
+ "Evaluate INIT and pass it as argument to FORMS with `->'.
+The RESULT of evaluating INIT is threaded through each of FORMS
+individually using `->', which see. The return value is RESULT,
+which FORMS may have modified by side effect."
+ (declare (debug (form &rest &or symbolp consp)) (indent 1))
+ (let ((retval (make-symbol "result")))
+ `(let ((,retval ,init))
+ ,@(mapcar (lambda (form) `(-> ,retval ,form)) forms)
+ ,retval)))
+
+(defmacro --doto (init &rest forms)
+ "Anaphoric form of `-doto'.
+This just evaluates INIT, binds the result to `it', evaluates
+FORMS, and returns the final value of `it'.
+Note: `it' need not be used in each form."
+ (declare (debug (form body)) (indent 1))
+ `(let ((it ,init))
+ ,@forms
+ it))
+
+(defun -grade-up (comparator list)
+ "Grade elements of LIST using COMPARATOR relation.
+This yields a permutation vector such that applying this
+permutation to LIST sorts it in ascending order."
+ (->> (--map-indexed (cons it it-index) list)
+ (-sort (lambda (it other) (funcall comparator (car it) (car other))))
+ (mapcar #'cdr)))
+
+(defun -grade-down (comparator list)
+ "Grade elements of LIST using COMPARATOR relation.
+This yields a permutation vector such that applying this
+permutation to LIST sorts it in descending order."
+ (->> (--map-indexed (cons it it-index) list)
+ (-sort (lambda (it other) (funcall comparator (car other) (car it))))
+ (mapcar #'cdr)))
+
+(defvar dash--source-counter 0
+ "Monotonic counter for generated symbols.")
+
+(defun dash--match-make-source-symbol ()
+ "Generate a new dash-source symbol.
+
+All returned symbols are guaranteed to be unique."
+ (prog1 (make-symbol (format "--dash-source-%d--" dash--source-counter))
+ (setq dash--source-counter (1+ dash--source-counter))))
+
+(defun dash--match-ignore-place-p (symbol)
+ "Return non-nil if SYMBOL is a symbol and starts with _."
+ (and (symbolp symbol)
+ (eq (aref (symbol-name symbol) 0) ?_)))
+
+(defun dash--match-cons-skip-cdr (skip-cdr source)
+ "Helper function generating idiomatic shifting code."
+ (cond
+ ((= skip-cdr 0)
+ `(pop ,source))
+ (t
+ `(prog1 ,(dash--match-cons-get-car skip-cdr source)
+ (setq ,source ,(dash--match-cons-get-cdr (1+ skip-cdr) source))))))
+
+(defun dash--match-cons-get-car (skip-cdr source)
+ "Helper function generating idiomatic code to get nth car."
+ (cond
+ ((= skip-cdr 0)
+ `(car ,source))
+ ((= skip-cdr 1)
+ `(cadr ,source))
+ (t
+ `(nth ,skip-cdr ,source))))
+
+(defun dash--match-cons-get-cdr (skip-cdr source)
+ "Helper function generating idiomatic code to get nth cdr."
+ (cond
+ ((= skip-cdr 0)
+ source)
+ ((= skip-cdr 1)
+ `(cdr ,source))
+ (t
+ `(nthcdr ,skip-cdr ,source))))
+
+(defun dash--match-cons (match-form source)
+ "Setup a cons matching environment and call the real matcher."
+ (let ((s (dash--match-make-source-symbol))
+ (n 0)
+ (m match-form))
+ (while (and (consp m)
+ (dash--match-ignore-place-p (car m)))
+ (setq n (1+ n)) (!cdr m))
+ (cond
+ ;; when we only have one pattern in the list, we don't have to
+ ;; create a temporary binding (--dash-source--) for the source
+ ;; and just use the input directly
+ ((and (consp m)
+ (not (cdr m)))
+ (dash--match (car m) (dash--match-cons-get-car n source)))
+ ;; handle other special types
+ ((> n 0)
+ (dash--match m (dash--match-cons-get-cdr n source)))
+ ;; this is the only entry-point for dash--match-cons-1, that's
+ ;; why we can't simply use the above branch, it would produce
+ ;; infinite recursion
+ (t
+ (cons (list s source) (dash--match-cons-1 match-form s))))))
+
+(defun dash--get-expand-function (type)
+ "Get expand function name for TYPE."
+ (intern-soft (format "dash-expand:%s" type)))
+
+(defun dash--match-cons-1 (match-form source &optional props)
+ "Match MATCH-FORM against SOURCE.
+
+MATCH-FORM is a proper or improper list. Each element of
+MATCH-FORM is either a symbol, which gets bound to the respective
+value in source or another match form which gets destructured
+recursively.
+
+If the cdr of last cons cell in the list is nil, matching stops
+there.
+
+SOURCE is a proper or improper list."
+ (let ((skip-cdr (or (plist-get props :skip-cdr) 0)))
+ (cond
+ ((consp match-form)
+ (cond
+ ((cdr match-form)
+ (cond
+ ((and (symbolp (car match-form))
+ (functionp (dash--get-expand-function (car match-form))))
+ (dash--match-kv (dash--match-kv-normalize-match-form match-form) (dash--match-cons-get-cdr skip-cdr source)))
+ ((dash--match-ignore-place-p (car match-form))
+ (dash--match-cons-1 (cdr match-form) source
+ (plist-put props :skip-cdr (1+ skip-cdr))))
+ (t
+ (-concat (dash--match (car match-form) (dash--match-cons-skip-cdr skip-cdr source))
+ (dash--match-cons-1 (cdr match-form) source)))))
+ (t ;; Last matching place, no need for shift
+ (dash--match (car match-form) (dash--match-cons-get-car skip-cdr source)))))
+ ((eq match-form nil)
+ nil)
+ (t ;; Handle improper lists. Last matching place, no need for shift
+ (dash--match match-form (dash--match-cons-get-cdr skip-cdr source))))))
+
+(defun dash--match-vector (match-form source)
+ "Setup a vector matching environment and call the real matcher."
+ (let ((s (dash--match-make-source-symbol)))
+ (cond
+ ;; don't bind `s' if we only have one sub-pattern
+ ((= (length match-form) 1)
+ (dash--match (aref match-form 0) `(aref ,source 0)))
+ ;; if the source is a symbol, we don't need to re-bind it
+ ((symbolp source)
+ (dash--match-vector-1 match-form source))
+ ;; don't bind `s' if we only have one sub-pattern which is not ignored
+ ((let* ((ignored-places (mapcar 'dash--match-ignore-place-p match-form))
+ (ignored-places-n (length (-remove 'null ignored-places))))
+ (when (= ignored-places-n (1- (length match-form)))
+ (let ((n (-find-index 'null ignored-places)))
+ (dash--match (aref match-form n) `(aref ,source ,n))))))
+ (t
+ (cons (list s source) (dash--match-vector-1 match-form s))))))
+
+(defun dash--match-vector-1 (match-form source)
+ "Match MATCH-FORM against SOURCE.
+
+MATCH-FORM is a vector. Each element of MATCH-FORM is either a
+symbol, which gets bound to the respective value in source or
+another match form which gets destructured recursively.
+
+If second-from-last place in MATCH-FORM is the symbol &rest, the
+next element of the MATCH-FORM is matched against the tail of
+SOURCE, starting at index of the &rest symbol. This is
+conceptually the same as the (head . tail) match for improper
+lists, where dot plays the role of &rest.
+
+SOURCE is a vector.
+
+If the MATCH-FORM vector is shorter than SOURCE vector, only
+the (length MATCH-FORM) places are bound, the rest of the SOURCE
+is discarded."
+ (let ((i 0)
+ (l (length match-form))
+ (re))
+ (while (< i l)
+ (let ((m (aref match-form i)))
+ (push (cond
+ ((and (symbolp m)
+ (eq m '&rest))
+ (prog1 (dash--match
+ (aref match-form (1+ i))
+ `(substring ,source ,i))
+ (setq i l)))
+ ((and (symbolp m)
+ ;; do not match symbols starting with _
+ (not (eq (aref (symbol-name m) 0) ?_)))
+ (list (list m `(aref ,source ,i))))
+ ((not (symbolp m))
+ (dash--match m `(aref ,source ,i))))
+ re)
+ (setq i (1+ i))))
+ (-flatten-n 1 (nreverse re))))
+
+(defun dash--match-kv-normalize-match-form (pattern)
+ "Normalize kv PATTERN.
+
+This method normalizes PATTERN to the format expected by
+`dash--match-kv'. See `-let' for the specification."
+ (let ((normalized (list (car pattern)))
+ (skip nil)
+ (fill-placeholder (make-symbol "--dash-fill-placeholder--")))
+ (-each (apply '-zip (-pad fill-placeholder (cdr pattern) (cddr pattern)))
+ (lambda (pair)
+ (let ((current (car pair))
+ (next (cdr pair)))
+ (if skip
+ (setq skip nil)
+ (if (or (eq fill-placeholder next)
+ (not (or (and (symbolp next)
+ (not (keywordp next))
+ (not (eq next t))
+ (not (eq next nil)))
+ (and (consp next)
+ (not (eq (car next) 'quote)))
+ (vectorp next))))
+ (progn
+ (cond
+ ((keywordp current)
+ (push current normalized)
+ (push (intern (substring (symbol-name current) 1)) normalized))
+ ((stringp current)
+ (push current normalized)
+ (push (intern current) normalized))
+ ((and (consp current)
+ (eq (car current) 'quote))
+ (push current normalized)
+ (push (cadr current) normalized))
+ (t (error "-let: found key `%s' in kv destructuring but its pattern `%s' is invalid and can not be derived from the key" current next)))
+ (setq skip nil))
+ (push current normalized)
+ (push next normalized)
+ (setq skip t))))))
+ (nreverse normalized)))
+
+(defun dash--match-kv (match-form source)
+ "Setup a kv matching environment and call the real matcher.
+
+kv can be any key-value store, such as plist, alist or hash-table."
+ (let ((s (dash--match-make-source-symbol)))
+ (cond
+ ;; don't bind `s' if we only have one sub-pattern (&type key val)
+ ((= (length match-form) 3)
+ (dash--match-kv-1 (cdr match-form) source (car match-form)))
+ ;; if the source is a symbol, we don't need to re-bind it
+ ((symbolp source)
+ (dash--match-kv-1 (cdr match-form) source (car match-form)))
+ (t
+ (cons (list s source) (dash--match-kv-1 (cdr match-form) s (car match-form)))))))
+
+(defun dash-expand:&hash (key source)
+ "Generate extracting KEY from SOURCE for &hash destructuring."
+ `(gethash ,key ,source))
+
+(defun dash-expand:&plist (key source)
+ "Generate extracting KEY from SOURCE for &plist destructuring."
+ `(plist-get ,source ,key))
+
+(defun dash-expand:&alist (key source)
+ "Generate extracting KEY from SOURCE for &alist destructuring."
+ `(cdr (assoc ,key ,source)))
+
+(defun dash-expand:&hash? (key source)
+ "Generate extracting KEY from SOURCE for &hash? destructuring.
+Similar to &hash but check whether the map is not nil."
+ (let ((src (make-symbol "src")))
+ `(let ((,src ,source))
+ (when ,src (gethash ,key ,src)))))
+
+(defalias 'dash-expand:&keys 'dash-expand:&plist)
+
+(defun dash--match-kv-1 (match-form source type)
+ "Match MATCH-FORM against SOURCE of type TYPE.
+
+MATCH-FORM is a proper list of the form (key1 place1 ... keyN
+placeN). Each placeK is either a symbol, which gets bound to the
+value of keyK retrieved from the key-value store, or another
+match form which gets destructured recursively.
+
+SOURCE is a key-value store of type TYPE, which can be a plist,
+an alist or a hash table.
+
+TYPE is a token specifying the type of the key-value store.
+Valid values are &plist, &alist and &hash."
+ (-flatten-n 1 (-map
+ (lambda (kv)
+ (let* ((k (car kv))
+ (v (cadr kv))
+ (getter
+ (funcall (dash--get-expand-function type) k source)))
+ (cond
+ ((symbolp v)
+ (list (list v getter)))
+ (t (dash--match v getter)))))
+ (-partition 2 match-form))))
+
+(defun dash--match-symbol (match-form source)
+ "Bind a symbol.
+
+This works just like `let', there is no destructuring."
+ (list (list match-form source)))
+
+(defun dash--match (match-form source)
+ "Match MATCH-FORM against SOURCE.
+
+This function tests the MATCH-FORM and dispatches to specific
+matchers based on the type of the expression.
+
+Key-value stores are disambiguated by placing a token &plist,
+&alist or &hash as a first item in the MATCH-FORM."
+ (cond
+ ((symbolp match-form)
+ (dash--match-symbol match-form source))
+ ((consp match-form)
+ (cond
+ ;; Handle the "x &as" bindings first.
+ ((and (consp (cdr match-form))
+ (symbolp (car match-form))
+ (eq '&as (cadr match-form)))
+ (let ((s (car match-form)))
+ (cons (list s source)
+ (dash--match (cddr match-form) s))))
+ ((functionp (dash--get-expand-function (car match-form)))
+ (dash--match-kv (dash--match-kv-normalize-match-form match-form) source))
+ (t (dash--match-cons match-form source))))
+ ((vectorp match-form)
+ ;; We support the &as binding in vectors too
+ (cond
+ ((and (> (length match-form) 2)
+ (symbolp (aref match-form 0))
+ (eq '&as (aref match-form 1)))
+ (let ((s (aref match-form 0)))
+ (cons (list s source)
+ (dash--match (substring match-form 2) s))))
+ (t (dash--match-vector match-form source))))))
+
+(defun dash--normalize-let-varlist (varlist)
+ "Normalize VARLIST so that every binding is a list.
+
+`let' allows specifying a binding which is not a list but simply
+the place which is then automatically bound to nil, such that all
+three of the following are identical and evaluate to nil.
+
+ (let (a) a)
+ (let ((a)) a)
+ (let ((a nil)) a)
+
+This function normalizes all of these to the last form."
+ (--map (if (consp it) it (list it nil)) varlist))
+
+(defmacro -let* (varlist &rest body)
+ "Bind variables according to VARLIST then eval BODY.
+
+VARLIST is a list of lists of the form (PATTERN SOURCE). Each
+PATTERN is matched against the SOURCE structurally. SOURCE is
+only evaluated once for each PATTERN.
+
+Each SOURCE can refer to the symbols already bound by this
+VARLIST. This is useful if you want to destructure SOURCE
+recursively but also want to name the intermediate structures.
+
+See `-let' for the list of all possible patterns."
+ (declare (debug ((&rest [&or (sexp form) sexp]) body))
+ (indent 1))
+ (let* ((varlist (dash--normalize-let-varlist varlist))
+ (bindings (--mapcat (dash--match (car it) (cadr it)) varlist)))
+ `(let* ,bindings
+ ,@body)))
+
+(defmacro -let (varlist &rest body)
+ "Bind variables according to VARLIST then eval BODY.
+
+VARLIST is a list of lists of the form (PATTERN SOURCE). Each
+PATTERN is matched against the SOURCE \"structurally\". SOURCE
+is only evaluated once for each PATTERN. Each PATTERN is matched
+recursively, and can therefore contain sub-patterns which are
+matched against corresponding sub-expressions of SOURCE.
+
+All the SOURCEs are evalled before any symbols are
+bound (i.e. \"in parallel\").
+
+If VARLIST only contains one (PATTERN SOURCE) element, you can
+optionally specify it using a vector and discarding the
+outer-most parens. Thus
+
+ (-let ((PATTERN SOURCE)) ...)
+
+becomes
+
+ (-let [PATTERN SOURCE] ...).
+
+`-let' uses a convention of not binding places (symbols) starting
+with _ whenever it's possible. You can use this to skip over
+entries you don't care about. However, this is not *always*
+possible (as a result of implementation) and these symbols might
+get bound to undefined values.
+
+Following is the overview of supported patterns. Remember that
+patterns can be matched recursively, so every a, b, aK in the
+following can be a matching construct and not necessarily a
+symbol/variable.
+
+Symbol:
+
+ a - bind the SOURCE to A. This is just like regular `let'.
+
+Conses and lists:
+
+ (a) - bind `car' of cons/list to A
+
+ (a . b) - bind car of cons to A and `cdr' to B
+
+ (a b) - bind car of list to A and `cadr' to B
+
+ (a1 a2 a3 ...) - bind 0th car of list to A1, 1st to A2, 2nd to A3...
+
+ (a1 a2 a3 ... aN . rest) - as above, but bind the Nth cdr to REST.
+
+Vectors:
+
+ [a] - bind 0th element of a non-list sequence to A (works with
+ vectors, strings, bit arrays...)
+
+ [a1 a2 a3 ...] - bind 0th element of non-list sequence to A0, 1st to
+ A1, 2nd to A2, ...
+ If the PATTERN is shorter than SOURCE, the values at
+ places not in PATTERN are ignored.
+ If the PATTERN is longer than SOURCE, an `error' is
+ thrown.
+
+ [a1 a2 a3 ... &rest rest] - as above, but bind the rest of
+ the sequence to REST. This is
+ conceptually the same as improper list
+ matching (a1 a2 ... aN . rest)
+
+Key/value stores:
+
+ (&plist key0 a0 ... keyN aN) - bind value mapped by keyK in the
+ SOURCE plist to aK. If the
+ value is not found, aK is nil.
+ Uses `plist-get' to fetch values.
+
+ (&alist key0 a0 ... keyN aN) - bind value mapped by keyK in the
+ SOURCE alist to aK. If the
+ value is not found, aK is nil.
+ Uses `assoc' to fetch values.
+
+ (&hash key0 a0 ... keyN aN) - bind value mapped by keyK in the
+ SOURCE hash table to aK. If the
+ value is not found, aK is nil.
+ Uses `gethash' to fetch values.
+
+Further, special keyword &keys supports \"inline\" matching of
+plist-like key-value pairs, similarly to &keys keyword of
+`cl-defun'.
+
+ (a1 a2 ... aN &keys key1 b1 ... keyN bK)
+
+This binds N values from the list to a1 ... aN, then interprets
+the cdr as a plist (see key/value matching above).
+
+A shorthand notation for kv-destructuring exists which allows the
+patterns be optionally left out and derived from the key name in
+the following fashion:
+
+- a key :foo is converted into `foo' pattern,
+- a key 'bar is converted into `bar' pattern,
+- a key \"baz\" is converted into `baz' pattern.
+
+That is, the entire value under the key is bound to the derived
+variable without any further destructuring.
+
+This is possible only when the form following the key is not a
+valid pattern (i.e. not a symbol, a cons cell or a vector).
+Otherwise the matching proceeds as usual and in case of an
+invalid spec fails with an error.
+
+Thus the patterns are normalized as follows:
+
+ ;; derive all the missing patterns
+ (&plist :foo 'bar \"baz\") => (&plist :foo foo 'bar bar \"baz\" baz)
+
+ ;; we can specify some but not others
+ (&plist :foo 'bar explicit-bar) => (&plist :foo foo 'bar explicit-bar)
+
+ ;; nothing happens, we store :foo in x
+ (&plist :foo x) => (&plist :foo x)
+
+ ;; nothing happens, we match recursively
+ (&plist :foo (a b c)) => (&plist :foo (a b c))
+
+You can name the source using the syntax SYMBOL &as PATTERN.
+This syntax works with lists (proper or improper), vectors and
+all types of maps.
+
+ (list &as a b c) (list 1 2 3)
+
+binds A to 1, B to 2, C to 3 and LIST to (1 2 3).
+
+Similarly:
+
+ (bounds &as beg . end) (cons 1 2)
+
+binds BEG to 1, END to 2 and BOUNDS to (1 . 2).
+
+ (items &as first . rest) (list 1 2 3)
+
+binds FIRST to 1, REST to (2 3) and ITEMS to (1 2 3)
+
+ [vect &as _ b c] [1 2 3]
+
+binds B to 2, C to 3 and VECT to [1 2 3] (_ avoids binding as usual).
+
+ (plist &as &plist :b b) (list :a 1 :b 2 :c 3)
+
+binds B to 2 and PLIST to (:a 1 :b 2 :c 3). Same for &alist and &hash.
+
+This is especially useful when we want to capture the result of a
+computation and destructure at the same time. Consider the
+form (function-returning-complex-structure) returning a list of
+two vectors with two items each. We want to capture this entire
+result and pass it to another computation, but at the same time
+we want to get the second item from each vector. We can achieve
+it with pattern
+
+ (result &as [_ a] [_ b]) (function-returning-complex-structure)
+
+Note: Clojure programmers may know this feature as the \":as
+binding\". The difference is that we put the &as at the front
+because we need to support improper list binding."
+ (declare (debug ([&or (&rest [&or (sexp form) sexp])
+ (vector [&rest [sexp form]])]
+ body))
+ (indent 1))
+ (if (vectorp varlist)
+ `(let* ,(dash--match (aref varlist 0) (aref varlist 1))
+ ,@body)
+ (let* ((varlist (dash--normalize-let-varlist varlist))
+ (inputs (--map-indexed (list (make-symbol (format "input%d" it-index)) (cadr it)) varlist))
+ (new-varlist (--map (list (caar it) (cadr it)) (-zip varlist inputs))))
+ `(let ,inputs
+ (-let* ,new-varlist ,@body)))))
+
+(defmacro -lambda (match-form &rest body)
+ "Return a lambda which destructures its input as MATCH-FORM and executes BODY.
+
+Note that you have to enclose the MATCH-FORM in a pair of parens,
+such that:
+
+ (-lambda (x) body)
+ (-lambda (x y ...) body)
+
+has the usual semantics of `lambda'. Furthermore, these get
+translated into normal `lambda', so there is no performance
+penalty.
+
+See `-let' for a description of the destructuring mechanism."
+ (declare (doc-string 2) (indent defun)
+ (debug (&define sexp
+ [&optional stringp]
+ [&optional ("interactive" interactive)]
+ def-body)))
+ (cond
+ ((nlistp match-form)
+ (signal 'wrong-type-argument (list #'listp match-form)))
+ ;; No destructuring, so just return regular `lambda' for speed.
+ ((-all? #'symbolp match-form)
+ `(lambda ,match-form ,@body))
+ ((let ((inputs (--map-indexed
+ (list it (make-symbol (format "input%d" it-index)))
+ match-form)))
+ ;; TODO: because inputs to the `lambda' are evaluated only once,
+ ;; `-let*' need not create the extra bindings to ensure that.
+ ;; We should find a way to optimize that. Not critical however.
+ `(lambda ,(mapcar #'cadr inputs)
+ (-let* ,inputs ,@body))))))
+
+(defmacro -setq (&rest forms)
+ "Bind each MATCH-FORM to the value of its VAL.
+
+MATCH-FORM destructuring is done according to the rules of `-let'.
+
+This macro allows you to bind multiple variables by destructuring
+the value, so for example:
+
+ (-setq (a b) x
+ (&plist :c c) plist)
+
+expands roughly speaking to the following code
+
+ (setq a (car x)
+ b (cadr x)
+ c (plist-get plist :c))
+
+Care is taken to only evaluate each VAL once so that in case of
+multiple assignments it does not cause unexpected side effects.
+
+\(fn [MATCH-FORM VAL]...)"
+ (declare (debug (&rest sexp form))
+ (indent 1))
+ (when (= (mod (length forms) 2) 1)
+ (signal 'wrong-number-of-arguments (list '-setq (1+ (length forms)))))
+ (let* ((forms-and-sources
+ ;; First get all the necessary mappings with all the
+ ;; intermediate bindings.
+ (-map (lambda (x) (dash--match (car x) (cadr x)))
+ (-partition 2 forms)))
+ ;; To preserve the logic of dynamic scoping we must ensure
+ ;; that we `setq' the variables outside of the `let*' form
+ ;; which holds the destructured intermediate values. For
+ ;; this we generate for each variable a placeholder which is
+ ;; bound to (lexically) the result of the destructuring.
+ ;; Then outside of the helper `let*' form we bind all the
+ ;; original variables to their respective placeholders.
+ ;; TODO: There is a lot of room for possible optimization,
+ ;; for start playing with `special-variable-p' to eliminate
+ ;; unnecessary re-binding.
+ (variables-to-placeholders
+ (-mapcat
+ (lambda (bindings)
+ (-map
+ (lambda (binding)
+ (let ((var (car binding)))
+ (list var (make-symbol (concat "--dash-binding-" (symbol-name var) "--")))))
+ (--filter (not (string-prefix-p "--" (symbol-name (car it)))) bindings)))
+ forms-and-sources)))
+ `(let ,(-map 'cadr variables-to-placeholders)
+ (let* ,(-flatten-n 1 forms-and-sources)
+ (setq ,@(-flatten (-map 'reverse variables-to-placeholders))))
+ (setq ,@(-flatten variables-to-placeholders)))))
+
+(defmacro -if-let* (vars-vals then &rest else)
+ "If all VALS evaluate to true, bind them to their corresponding
+VARS and do THEN, otherwise do ELSE. VARS-VALS should be a list
+of (VAR VAL) pairs.
+
+Note: binding is done according to `-let*'. VALS are evaluated
+sequentially, and evaluation stops after the first nil VAL is
+encountered."
+ (declare (debug ((&rest (sexp form)) form body))
+ (indent 2))
+ (->> vars-vals
+ (--mapcat (dash--match (car it) (cadr it)))
+ (--reduce-r-from
+ (let ((var (car it))
+ (val (cadr it)))
+ `(let ((,var ,val))
+ (if ,var ,acc ,@else)))
+ then)))
+
+(defmacro -if-let (var-val then &rest else)
+ "If VAL evaluates to non-nil, bind it to VAR and do THEN,
+otherwise do ELSE.
+
+Note: binding is done according to `-let'.
+
+\(fn (VAR VAL) THEN &rest ELSE)"
+ (declare (debug ((sexp form) form body))
+ (indent 2))
+ `(-if-let* (,var-val) ,then ,@else))
+
+(defmacro --if-let (val then &rest else)
+ "If VAL evaluates to non-nil, bind it to symbol `it' and do THEN,
+otherwise do ELSE."
+ (declare (debug (form form body))
+ (indent 2))
+ `(-if-let (it ,val) ,then ,@else))
+
+(defmacro -when-let* (vars-vals &rest body)
+ "If all VALS evaluate to true, bind them to their corresponding
+VARS and execute body. VARS-VALS should be a list of (VAR VAL)
+pairs.
+
+Note: binding is done according to `-let*'. VALS are evaluated
+sequentially, and evaluation stops after the first nil VAL is
+encountered."
+ (declare (debug ((&rest (sexp form)) body))
+ (indent 1))
+ `(-if-let* ,vars-vals (progn ,@body)))
+
+(defmacro -when-let (var-val &rest body)
+ "If VAL evaluates to non-nil, bind it to VAR and execute body.
+
+Note: binding is done according to `-let'.
+
+\(fn (VAR VAL) &rest BODY)"
+ (declare (debug ((sexp form) body))
+ (indent 1))
+ `(-if-let ,var-val (progn ,@body)))
+
+(defmacro --when-let (val &rest body)
+ "If VAL evaluates to non-nil, bind it to symbol `it' and
+execute body."
+ (declare (debug (form body))
+ (indent 1))
+ `(--if-let ,val (progn ,@body)))
+
+(defvar -compare-fn nil
+ "Tests for equality use this function or `equal' if this is nil.
+It should only be set using dynamic scope with a let, like:
+
+ (let ((-compare-fn #\\='=)) (-union numbers1 numbers2 numbers3)")
+
+(defun -distinct (list)
+ "Return a new list with all duplicates removed.
+The test for equality is done with `equal',
+or with `-compare-fn' if that's non-nil.
+
+Alias: `-uniq'"
+ ;; Implementation note: The speedup gained from hash table lookup
+ ;; starts to outweigh its overhead for lists of length greater than
+ ;; 32. See discussion in PR #305.
+ (let* ((len (length list))
+ (lut (and (> len 32)
+ ;; Check that `-compare-fn' is a valid hash-table
+ ;; lookup function or nil.
+ (memq -compare-fn '(nil equal eq eql))
+ (make-hash-table :test (or -compare-fn #'equal)
+ :size len))))
+ (if lut
+ (--filter (unless (gethash it lut)
+ (puthash it t lut))
+ list)
+ (--each list (unless (-contains? lut it) (!cons it lut)))
+ (nreverse lut))))
+
+(defalias '-uniq '-distinct)
+
+(defun -union (list list2)
+ "Return a new list of all elements appearing in either LIST1 or LIST2.
+Equality is defined by the value of `-compare-fn' if non-nil;
+otherwise `equal'."
+ ;; We fall back to iteration implementation if the comparison
+ ;; function isn't one of `eq', `eql' or `equal'.
+ (let* ((result (reverse list))
+ ;; TODO: get rid of this dynamic variable, pass it as an
+ ;; argument instead.
+ (-compare-fn (if (bound-and-true-p -compare-fn)
+ -compare-fn
+ 'equal)))
+ (if (memq -compare-fn '(eq eql equal))
+ (let ((ht (make-hash-table :test -compare-fn)))
+ (--each list (puthash it t ht))
+ (--each list2 (unless (gethash it ht) (!cons it result))))
+ (--each list2 (unless (-contains? result it) (!cons it result))))
+ (nreverse result)))
+
+(defun -intersection (list list2)
+ "Return a new list of the elements appearing in both LIST1 and LIST2.
+Equality is defined by the value of `-compare-fn' if non-nil;
+otherwise `equal'."
+ (--filter (-contains? list2 it) list))
+
+(defun -difference (list list2)
+ "Return a new list with only the members of LIST that are not in LIST2.
+The test for equality is done with `equal',
+or with `-compare-fn' if that's non-nil."
+ (--filter (not (-contains? list2 it)) list))
+
+(defun -powerset (list)
+ "Return the power set of LIST."
+ (if (null list) '(())
+ (let ((last (-powerset (cdr list))))
+ (append (mapcar (lambda (x) (cons (car list) x)) last)
+ last))))
+
+(defun -permutations (list)
+ "Return the permutations of LIST."
+ (if (null list) '(())
+ (apply #'append
+ (mapcar (lambda (x)
+ (mapcar (lambda (perm) (cons x perm))
+ (-permutations (remove x list))))
+ list))))
+
+(defun -inits (list)
+ "Return all prefixes of LIST."
+ (let ((res (list list)))
+ (setq list (reverse list))
+ (while list
+ (push (reverse (!cdr list)) res))
+ res))
+
+(defun -tails (list)
+ "Return all suffixes of LIST"
+ (-reductions-r-from 'cons nil list))
+
+(defun -common-prefix (&rest lists)
+ "Return the longest common prefix of LISTS."
+ (declare (pure t) (side-effect-free t))
+ (--reduce (--take-while (and acc (equal (pop acc) it)) it)
+ lists))
+
+(defun -common-suffix (&rest lists)
+ "Return the longest common suffix of LISTS."
+ (nreverse (apply #'-common-prefix (mapcar #'reverse lists))))
+
+(defun -contains? (list element)
+ "Return non-nil if LIST contains ELEMENT.
+
+The test for equality is done with `equal', or with `-compare-fn'
+if that's non-nil.
+
+Alias: `-contains-p'"
+ (not
+ (null
+ (cond
+ ((null -compare-fn) (member element list))
+ ((eq -compare-fn 'eq) (memq element list))
+ ((eq -compare-fn 'eql) (memql element list))
+ (t
+ (let ((lst list))
+ (while (and lst
+ (not (funcall -compare-fn element (car lst))))
+ (setq lst (cdr lst)))
+ lst))))))
+
+(defalias '-contains-p '-contains?)
+
+(defun -same-items? (list list2)
+ "Return true if LIST and LIST2 has the same items.
+
+The order of the elements in the lists does not matter.
+
+Alias: `-same-items-p'"
+ (let ((length-a (length list))
+ (length-b (length list2)))
+ (and
+ (= length-a length-b)
+ (= length-a (length (-intersection list list2))))))
+
+(defalias '-same-items-p '-same-items?)
+
+(defun -is-prefix? (prefix list)
+ "Return non-nil if PREFIX is a prefix of LIST.
+
+Alias: `-is-prefix-p'."
+ (declare (pure t) (side-effect-free t))
+ (--each-while list (and (equal (car prefix) it)
+ (!cdr prefix)))
+ (null prefix))
+
+(defun -is-suffix? (suffix list)
+ "Return non-nil if SUFFIX is a suffix of LIST.
+
+Alias: `-is-suffix-p'."
+ (declare (pure t) (side-effect-free t))
+ (equal suffix (last list (length suffix))))
+
+(defun -is-infix? (infix list)
+ "Return non-nil if INFIX is infix of LIST.
+
+This operation runs in O(n^2) time
+
+Alias: `-is-infix-p'"
+ (declare (pure t) (side-effect-free t))
+ (let (done)
+ (while (and (not done) list)
+ (setq done (-is-prefix? infix list))
+ (!cdr list))
+ done))
+
+(defalias '-is-prefix-p '-is-prefix?)
+(defalias '-is-suffix-p '-is-suffix?)
+(defalias '-is-infix-p '-is-infix?)
+
+(defun -sort (comparator list)
+ "Sort LIST, stably, comparing elements using COMPARATOR.
+Return the sorted list. LIST is NOT modified by side effects.
+COMPARATOR is called with two elements of LIST, and should return non-nil
+if the first element should sort before the second."
+ (sort (copy-sequence list) comparator))
+
+(defmacro --sort (form list)
+ "Anaphoric form of `-sort'."
+ (declare (debug (def-form form)))
+ `(-sort (lambda (it other) ,form) ,list))
+
+(defun -list (&optional arg &rest args)
+ "Ensure ARG is a list.
+If ARG is already a list, return it as is (not a copy).
+Otherwise, return a new list with ARG as its only element.
+
+Another supported calling convention is (-list &rest ARGS).
+In this case, if ARG is not a list, a new list with all of
+ARGS as elements is returned. This use is supported for
+backward compatibility and is otherwise deprecated."
+ (declare (advertised-calling-convention (arg) "2.18.0")
+ (pure t) (side-effect-free t))
+ (if (listp arg) arg (cons arg args)))
+
+(defun -repeat (n x)
+ "Return a new list of length N with each element being X.
+Return nil if N is less than 1."
+ (declare (pure t) (side-effect-free t))
+ (and (natnump n) (make-list n x)))
+
+(defun -sum (list)
+ "Return the sum of LIST."
+ (declare (pure t) (side-effect-free t))
+ (apply '+ list))
+
+(defun -running-sum (list)
+ "Return a list with running sums of items in LIST.
+LIST must be non-empty."
+ (declare (pure t) (side-effect-free t))
+ (or list (signal 'wrong-type-argument (list #'consp list)))
+ (-reductions #'+ list))
+
+(defun -product (list)
+ "Return the product of LIST."
+ (declare (pure t) (side-effect-free t))
+ (apply '* list))
+
+(defun -running-product (list)
+ "Return a list with running products of items in LIST.
+LIST must be non-empty."
+ (declare (pure t) (side-effect-free t))
+ (or list (signal 'wrong-type-argument (list #'consp list)))
+ (-reductions #'* list))
+
+(defun -max (list)
+ "Return the largest value from LIST of numbers or markers."
+ (declare (pure t) (side-effect-free t))
+ (apply 'max list))
+
+(defun -min (list)
+ "Return the smallest value from LIST of numbers or markers."
+ (declare (pure t) (side-effect-free t))
+ (apply 'min list))
+
+(defun -max-by (comparator list)
+ "Take a comparison function COMPARATOR and a LIST and return
+the greatest element of the list by the comparison function.
+
+See also combinator `-on' which can transform the values before
+comparing them."
+ (--reduce (if (funcall comparator it acc) it acc) list))
+
+(defun -min-by (comparator list)
+ "Take a comparison function COMPARATOR and a LIST and return
+the least element of the list by the comparison function.
+
+See also combinator `-on' which can transform the values before
+comparing them."
+ (--reduce (if (funcall comparator it acc) acc it) list))
+
+(defmacro --max-by (form list)
+ "Anaphoric version of `-max-by'.
+
+The items for the comparator form are exposed as \"it\" and \"other\"."
+ (declare (debug (def-form form)))
+ `(-max-by (lambda (it other) ,form) ,list))
+
+(defmacro --min-by (form list)
+ "Anaphoric version of `-min-by'.
+
+The items for the comparator form are exposed as \"it\" and \"other\"."
+ (declare (debug (def-form form)))
+ `(-min-by (lambda (it other) ,form) ,list))
+
+(defun -iota (count &optional start step)
+ "Return a list containing COUNT numbers.
+Starts from START and adds STEP each time. The default START is
+zero, the default STEP is 1.
+This function takes its name from the corresponding primitive in
+the APL language."
+ (declare (pure t) (side-effect-free t))
+ (unless (natnump count)
+ (signal 'wrong-type-argument (list #'natnump count)))
+ (or start (setq start 0))
+ (or step (setq step 1))
+ (if (zerop step)
+ (make-list count start)
+ (--iterate (+ it step) start count)))
+
+(defun -fix (fn list)
+ "Compute the (least) fixpoint of FN with initial input LIST.
+
+FN is called at least once, results are compared with `equal'."
+ (let ((re (funcall fn list)))
+ (while (not (equal list re))
+ (setq list re)
+ (setq re (funcall fn re)))
+ re))
+
+(defmacro --fix (form list)
+ "Anaphoric form of `-fix'."
+ (declare (debug (def-form form)))
+ `(-fix (lambda (it) ,form) ,list))
+
+(defun -unfold (fun seed)
+ "Build a list from SEED using FUN.
+
+This is \"dual\" operation to `-reduce-r': while -reduce-r
+consumes a list to produce a single value, `-unfold' takes a
+seed value and builds a (potentially infinite!) list.
+
+FUN should return nil to stop the generating process, or a
+cons (A . B), where A will be prepended to the result and B is
+the new seed."
+ (let ((last (funcall fun seed)) r)
+ (while last
+ (push (car last) r)
+ (setq last (funcall fun (cdr last))))
+ (nreverse r)))
+
+(defmacro --unfold (form seed)
+ "Anaphoric version of `-unfold'."
+ (declare (debug (def-form form)))
+ `(-unfold (lambda (it) ,form) ,seed))
+
+(defun -cons-pair? (obj)
+ "Return non-nil if OBJ is a true cons pair.
+That is, a cons (A . B) where B is not a list.
+
+Alias: `-cons-pair-p'."
+ (declare (pure t) (side-effect-free t))
+ (nlistp (cdr-safe obj)))
+
+(defalias '-cons-pair-p '-cons-pair?)
+
+(defun -cons-to-list (con)
+ "Convert a cons pair to a list with `car' and `cdr' of the pair respectively."
+ (declare (pure t) (side-effect-free t))
+ (list (car con) (cdr con)))
+
+(defun -value-to-list (val)
+ "Convert a value to a list.
+
+If the value is a cons pair, make a list with two elements, `car'
+and `cdr' of the pair respectively.
+
+If the value is anything else, wrap it in a list."
+ (declare (pure t) (side-effect-free t))
+ (cond
+ ((-cons-pair? val) (-cons-to-list val))
+ (t (list val))))
+
+(defun -tree-mapreduce-from (fn folder init-value tree)
+ "Apply FN to each element of TREE, and make a list of the results.
+If elements of TREE are lists themselves, apply FN recursively to
+elements of these nested lists.
+
+Then reduce the resulting lists using FOLDER and initial value
+INIT-VALUE. See `-reduce-r-from'.
+
+This is the same as calling `-tree-reduce-from' after `-tree-map'
+but is twice as fast as it only traverse the structure once."
+ (cond
+ ((not tree) nil)
+ ((-cons-pair? tree) (funcall fn tree))
+ ((listp tree)
+ (-reduce-r-from folder init-value (mapcar (lambda (x) (-tree-mapreduce-from fn folder init-value x)) tree)))
+ (t (funcall fn tree))))
+
+(defmacro --tree-mapreduce-from (form folder init-value tree)
+ "Anaphoric form of `-tree-mapreduce-from'."
+ (declare (debug (def-form def-form form form)))
+ `(-tree-mapreduce-from (lambda (it) ,form) (lambda (it acc) ,folder) ,init-value ,tree))
+
+(defun -tree-mapreduce (fn folder tree)
+ "Apply FN to each element of TREE, and make a list of the results.
+If elements of TREE are lists themselves, apply FN recursively to
+elements of these nested lists.
+
+Then reduce the resulting lists using FOLDER and initial value
+INIT-VALUE. See `-reduce-r-from'.
+
+This is the same as calling `-tree-reduce' after `-tree-map'
+but is twice as fast as it only traverse the structure once."
+ (cond
+ ((not tree) nil)
+ ((-cons-pair? tree) (funcall fn tree))
+ ((listp tree)
+ (-reduce-r folder (mapcar (lambda (x) (-tree-mapreduce fn folder x)) tree)))
+ (t (funcall fn tree))))
+
+(defmacro --tree-mapreduce (form folder tree)
+ "Anaphoric form of `-tree-mapreduce'."
+ (declare (debug (def-form def-form form)))
+ `(-tree-mapreduce (lambda (it) ,form) (lambda (it acc) ,folder) ,tree))
+
+(defun -tree-map (fn tree)
+ "Apply FN to each element of TREE while preserving the tree structure."
+ (cond
+ ((not tree) nil)
+ ((-cons-pair? tree) (funcall fn tree))
+ ((listp tree)
+ (mapcar (lambda (x) (-tree-map fn x)) tree))
+ (t (funcall fn tree))))
+
+(defmacro --tree-map (form tree)
+ "Anaphoric form of `-tree-map'."
+ (declare (debug (def-form form)))
+ `(-tree-map (lambda (it) ,form) ,tree))
+
+(defun -tree-reduce-from (fn init-value tree)
+ "Use FN to reduce elements of list TREE.
+If elements of TREE are lists themselves, apply the reduction recursively.
+
+FN is first applied to INIT-VALUE and first element of the list,
+then on this result and second element from the list etc.
+
+The initial value is ignored on cons pairs as they always contain
+two elements."
+ (cond
+ ((not tree) nil)
+ ((-cons-pair? tree) tree)
+ ((listp tree)
+ (-reduce-r-from fn init-value (mapcar (lambda (x) (-tree-reduce-from fn init-value x)) tree)))
+ (t tree)))
+
+(defmacro --tree-reduce-from (form init-value tree)
+ "Anaphoric form of `-tree-reduce-from'."
+ (declare (debug (def-form form form)))
+ `(-tree-reduce-from (lambda (it acc) ,form) ,init-value ,tree))
+
+(defun -tree-reduce (fn tree)
+ "Use FN to reduce elements of list TREE.
+If elements of TREE are lists themselves, apply the reduction recursively.
+
+FN is first applied to first element of the list and second
+element, then on this result and third element from the list etc.
+
+See `-reduce-r' for how exactly are lists of zero or one element handled."
+ (cond
+ ((not tree) nil)
+ ((-cons-pair? tree) tree)
+ ((listp tree)
+ (-reduce-r fn (mapcar (lambda (x) (-tree-reduce fn x)) tree)))
+ (t tree)))
+
+(defmacro --tree-reduce (form tree)
+ "Anaphoric form of `-tree-reduce'."
+ (declare (debug (def-form form)))
+ `(-tree-reduce (lambda (it acc) ,form) ,tree))
+
+(defun -tree-map-nodes (pred fun tree)
+ "Call FUN on each node of TREE that satisfies PRED.
+
+If PRED returns nil, continue descending down this node. If PRED
+returns non-nil, apply FUN to this node and do not descend
+further."
+ (if (funcall pred tree)
+ (funcall fun tree)
+ (if (and (listp tree)
+ (not (-cons-pair? tree)))
+ (-map (lambda (x) (-tree-map-nodes pred fun x)) tree)
+ tree)))
+
+(defmacro --tree-map-nodes (pred form tree)
+ "Anaphoric form of `-tree-map-nodes'."
+ (declare (debug (def-form def-form form)))
+ `(-tree-map-nodes (lambda (it) ,pred) (lambda (it) ,form) ,tree))
+
+(defun -tree-seq (branch children tree)
+ "Return a sequence of the nodes in TREE, in depth-first search order.
+
+BRANCH is a predicate of one argument that returns non-nil if the
+passed argument is a branch, that is, a node that can have children.
+
+CHILDREN is a function of one argument that returns the children
+of the passed branch node.
+
+Non-branch nodes are simply copied."
+ (cons tree
+ (when (funcall branch tree)
+ (-mapcat (lambda (x) (-tree-seq branch children x))
+ (funcall children tree)))))
+
+(defmacro --tree-seq (branch children tree)
+ "Anaphoric form of `-tree-seq'."
+ (declare (debug (def-form def-form form)))
+ `(-tree-seq (lambda (it) ,branch) (lambda (it) ,children) ,tree))
+
+(defun -clone (list)
+ "Create a deep copy of LIST.
+The new list has the same elements and structure but all cons are
+replaced with new ones. This is useful when you need to clone a
+structure such as plist or alist."
+ (declare (pure t) (side-effect-free t))
+ (-tree-map 'identity list))
+
+;;; Combinators
+
+(defalias '-partial #'apply-partially)
+
+(defun -rpartial (fn &rest args)
+ "Return a function that is a partial application of FN to ARGS.
+ARGS is a list of the last N arguments to pass to FN. The result
+is a new function which does the same as FN, except that the last
+N arguments are fixed at the values with which this function was
+called. This is like `-partial', except the arguments are fixed
+starting from the right rather than the left."
+ (declare (pure t) (side-effect-free t))
+ (lambda (&rest args-before) (apply fn (append args-before args))))
+
+(defun -juxt (&rest fns)
+ "Return a function that is the juxtaposition of FNS.
+The returned function takes a variable number of ARGS, applies
+each of FNS in turn to ARGS, and returns the list of results."
+ (declare (pure t) (side-effect-free t))
+ (lambda (&rest args) (mapcar (lambda (x) (apply x args)) fns)))
+
+(defun -compose (&rest fns)
+ "Compose FNS into a single composite function.
+Return a function that takes a variable number of ARGS, applies
+the last function in FNS to ARGS, and returns the result of
+calling each remaining function on the result of the previous
+function, right-to-left. If no FNS are given, return a variadic
+`identity' function."
+ (declare (pure t) (side-effect-free t))
+ (let* ((fns (nreverse fns))
+ (head (car fns))
+ (tail (cdr fns)))
+ (cond (tail
+ (lambda (&rest args)
+ (--reduce-from (funcall it acc) (apply head args) tail)))
+ (fns head)
+ ((lambda (&optional arg &rest _) arg)))))
+
+(defun -applify (fn)
+ "Return a function that applies FN to a single list of args.
+This changes the arity of FN from taking N distinct arguments to
+taking 1 argument which is a list of N arguments."
+ (declare (pure t) (side-effect-free t))
+ (lambda (args) (apply fn args)))
+
+(defun -on (op trans)
+ "Return a function that calls TRANS on each arg and OP on the results.
+The returned function takes a variable number of arguments, calls
+the function TRANS on each one in turn, and then passes those
+results as the list of arguments to OP, in the same order.
+
+For example, the following pairs of expressions are morally
+equivalent:
+
+ (funcall (-on #\\='+ #\\='1+) 1 2 3) = (+ (1+ 1) (1+ 2) (1+ 3))
+ (funcall (-on #\\='+ #\\='1+)) = (+)"
+ (declare (pure t) (side-effect-free t))
+ (lambda (&rest args)
+ ;; This unrolling seems to be a relatively cheap way to keep the
+ ;; overhead of `mapcar' + `apply' in check.
+ (cond ((cddr args)
+ (apply op (mapcar trans args)))
+ ((cdr args)
+ (funcall op (funcall trans (car args)) (funcall trans (cadr args))))
+ (args
+ (funcall op (funcall trans (car args))))
+ ((funcall op)))))
+
+(defun -flip (fn)
+ "Return a function that calls FN with its arguments reversed.
+The returned function takes the same number of arguments as FN.
+
+For example, the following two expressions are morally
+equivalent:
+
+ (funcall (-flip #\\='-) 1 2) = (- 2 1)
+
+See also: `-rotate-args'."
+ (declare (pure t) (side-effect-free t))
+ (lambda (&rest args) ;; Open-code for speed.
+ (cond ((cddr args) (apply fn (nreverse args)))
+ ((cdr args) (funcall fn (cadr args) (car args)))
+ (args (funcall fn (car args)))
+ ((funcall fn)))))
+
+(defun -rotate-args (n fn)
+ "Return a function that calls FN with args rotated N places to the right.
+The returned function takes the same number of arguments as FN,
+rotates the list of arguments N places to the right (left if N is
+negative) just like `-rotate', and applies FN to the result.
+
+See also: `-flip'."
+ (declare (pure t) (side-effect-free t))
+ (if (zerop n)
+ fn
+ (let ((even (= (% n 2) 0)))
+ (lambda (&rest args)
+ (cond ((cddr args) ;; Open-code for speed.
+ (apply fn (-rotate n args)))
+ ((cdr args)
+ (let ((fst (car args))
+ (snd (cadr args)))
+ (funcall fn (if even fst snd) (if even snd fst))))
+ (args
+ (funcall fn (car args)))
+ ((funcall fn)))))))
+
+(defun -const (c)
+ "Return a function that returns C ignoring any additional arguments.
+
+In types: a -> b -> a"
+ (declare (pure t) (side-effect-free t))
+ (lambda (&rest _) c))
+
+(defmacro -cut (&rest params)
+ "Take n-ary function and n arguments and specialize some of them.
+Arguments denoted by <> will be left unspecialized.
+
+See SRFI-26 for detailed description."
+ (declare (debug (&optional sexp &rest &or "<>" form)))
+ (let* ((i 0)
+ (args (--keep (when (eq it '<>)
+ (setq i (1+ i))
+ (make-symbol (format "D%d" i)))
+ params)))
+ `(lambda ,args
+ ,(let ((body (--map (if (eq it '<>) (pop args) it) params)))
+ (if (eq (car params) '<>)
+ (cons #'funcall body)
+ body)))))
+
+(defun -not (pred)
+ "Return a predicate that negates the result of PRED.
+The returned predicate passes its arguments to PRED. If PRED
+returns nil, the result is non-nil; otherwise the result is nil.
+
+See also: `-andfn' and `-orfn'."
+ (declare (pure t) (side-effect-free t))
+ (lambda (&rest args) (not (apply pred args))))
+
+(defun -orfn (&rest preds)
+ "Return a predicate that returns the first non-nil result of PREDS.
+The returned predicate takes a variable number of arguments,
+passes them to each predicate in PREDS in turn until one of them
+returns non-nil, and returns that non-nil result without calling
+the remaining PREDS. If all PREDS return nil, or if no PREDS are
+given, the returned predicate returns nil.
+
+See also: `-andfn' and `-not'."
+ (declare (pure t) (side-effect-free t))
+ ;; Open-code for speed.
+ (cond ((cdr preds) (lambda (&rest args) (--some (apply it args) preds)))
+ (preds (car preds))
+ (#'ignore)))
+
+(defun -andfn (&rest preds)
+ "Return a predicate that returns non-nil if all PREDS do so.
+The returned predicate P takes a variable number of arguments and
+passes them to each predicate in PREDS in turn. If any one of
+PREDS returns nil, P also returns nil without calling the
+remaining PREDS. If all PREDS return non-nil, P returns the last
+such value. If no PREDS are given, P always returns non-nil.
+
+See also: `-orfn' and `-not'."
+ (declare (pure t) (side-effect-free t))
+ ;; Open-code for speed.
+ (cond ((cdr preds) (lambda (&rest args) (--every (apply it args) preds)))
+ (preds (car preds))
+ ;; As a `pure' function, this runtime check may generate
+ ;; backward-incompatible bytecode for `(-andfn)' at compile-time,
+ ;; but I doubt that's a problem in practice (famous last words).
+ ((fboundp 'always) #'always)
+ ((lambda (&rest _) t))))
+
+(defun -iteratefn (fn n)
+ "Return a function FN composed N times with itself.
+
+FN is a unary function. If you need to use a function of higher
+arity, use `-applify' first to turn it into a unary function.
+
+With n = 0, this acts as identity function.
+
+In types: (a -> a) -> Int -> a -> a.
+
+This function satisfies the following law:
+
+ (funcall (-iteratefn fn n) init) = (-last-item (-iterate fn init (1+ n)))."
+ (lambda (x) (--dotimes n (setq x (funcall fn x))) x))
+
+(defun -counter (&optional beg end inc)
+ "Return a closure that counts from BEG to END, with increment INC.
+
+The closure will return the next value in the counting sequence
+each time it is called, and nil after END is reached. BEG
+defaults to 0, INC defaults to 1, and if END is nil, the counter
+will increment indefinitely.
+
+The closure accepts any number of arguments, which are discarded."
+ (let ((inc (or inc 1))
+ (n (or beg 0)))
+ (lambda (&rest _)
+ (when (or (not end) (< n end))
+ (prog1 n
+ (setq n (+ n inc)))))))
+
+(defvar -fixfn-max-iterations 1000
+ "The default maximum number of iterations performed by `-fixfn'
+ unless otherwise specified.")
+
+(defun -fixfn (fn &optional equal-test halt-test)
+ "Return a function that computes the (least) fixpoint of FN.
+
+FN must be a unary function. The returned lambda takes a single
+argument, X, the initial value for the fixpoint iteration. The
+iteration halts when either of the following conditions is satisfied:
+
+ 1. Iteration converges to the fixpoint, with equality being
+ tested using EQUAL-TEST. If EQUAL-TEST is not specified,
+ `equal' is used. For functions over the floating point
+ numbers, it may be necessary to provide an appropriate
+ approximate comparison test.
+
+ 2. HALT-TEST returns a non-nil value. HALT-TEST defaults to a
+ simple counter that returns t after `-fixfn-max-iterations',
+ to guard against infinite iteration. Otherwise, HALT-TEST
+ must be a function that accepts a single argument, the
+ current value of X, and returns non-nil as long as iteration
+ should continue. In this way, a more sophisticated
+ convergence test may be supplied by the caller.
+
+The return value of the lambda is either the fixpoint or, if
+iteration halted before converging, a cons with car `halted' and
+cdr the final output from HALT-TEST.
+
+In types: (a -> a) -> a -> a."
+ (let ((eqfn (or equal-test 'equal))
+ (haltfn (or halt-test
+ (-not
+ (-counter 0 -fixfn-max-iterations)))))
+ (lambda (x)
+ (let ((re (funcall fn x))
+ (halt? (funcall haltfn x)))
+ (while (and (not halt?) (not (funcall eqfn x re)))
+ (setq x re
+ re (funcall fn re)
+ halt? (funcall haltfn re)))
+ (if halt? (cons 'halted halt?)
+ re)))))
+
+(defun -prodfn (&rest fns)
+ "Return a function that applies each of FNS to each of a list of arguments.
+
+Takes a list of N functions and returns a function that takes a
+list of length N, applying Ith function to Ith element of the
+input list. Returns a list of length N.
+
+In types (for N=2): ((a -> b), (c -> d)) -> (a, c) -> (b, d)
+
+This function satisfies the following laws:
+
+ (-compose (-prodfn f g ...)
+ (-prodfn f\\=' g\\=' ...))
+ = (-prodfn (-compose f f\\=')
+ (-compose g g\\=')
+ ...)
+
+ (-prodfn f g ...)
+ = (-juxt (-compose f (-partial #\\='nth 0))
+ (-compose g (-partial #\\='nth 1))
+ ...)
+
+ (-compose (-prodfn f g ...)
+ (-juxt f\\=' g\\=' ...))
+ = (-juxt (-compose f f\\=')
+ (-compose g g\\=')
+ ...)
+
+ (-compose (-partial #\\='nth n)
+ (-prod f1 f2 ...))
+ = (-compose fn (-partial #\\='nth n))"
+ (lambda (x) (-zip-with 'funcall fns x)))
+
+;;; Font lock
+
+(defvar dash--keywords
+ `(;; TODO: Do not fontify the following automatic variables
+ ;; globally; detect and limit to their local anaphoric scope.
+ (,(rx symbol-start (| "acc" "it" "it-index" "other") symbol-end)
+ 0 font-lock-variable-name-face)
+ ;; Macros in dev/examples.el. Based on `lisp-mode-symbol-regexp'.
+ (,(rx ?\( (group (| "defexamples" "def-example-group")) symbol-end
+ (+ (in "\t "))
+ (group (* (| (syntax word) (syntax symbol) (: ?\\ nonl)))))
+ (1 font-lock-keyword-face)
+ (2 font-lock-function-name-face))
+ ;; Symbols in dev/examples.el.
+ ,(rx symbol-start (| "=>" "~>" "!!>") symbol-end)
+ ;; Elisp macro fontification was static prior to Emacs 25.
+ ,@(when (< emacs-major-version 25)
+ (let ((macs '("!cdr"
+ "!cons"
+ "-->"
+ "--all?"
+ "--annotate"
+ "--any?"
+ "--count"
+ "--dotimes"
+ "--doto"
+ "--drop-while"
+ "--each"
+ "--each-r"
+ "--each-r-while"
+ "--each-while"
+ "--filter"
+ "--find-index"
+ "--find-indices"
+ "--find-last-index"
+ "--first"
+ "--fix"
+ "--group-by"
+ "--if-let"
+ "--iterate"
+ "--keep"
+ "--last"
+ "--map"
+ "--map-first"
+ "--map-indexed"
+ "--map-last"
+ "--map-when"
+ "--mapcat"
+ "--max-by"
+ "--min-by"
+ "--none?"
+ "--only-some?"
+ "--partition-by"
+ "--partition-by-header"
+ "--reduce"
+ "--reduce-from"
+ "--reduce-r"
+ "--reduce-r-from"
+ "--reductions"
+ "--reductions-from"
+ "--reductions-r"
+ "--reductions-r-from"
+ "--remove"
+ "--remove-first"
+ "--remove-last"
+ "--separate"
+ "--some"
+ "--sort"
+ "--splice"
+ "--splice-list"
+ "--split-when"
+ "--split-with"
+ "--take-while"
+ "--tree-map"
+ "--tree-map-nodes"
+ "--tree-mapreduce"
+ "--tree-mapreduce-from"
+ "--tree-reduce"
+ "--tree-reduce-from"
+ "--tree-seq"
+ "--unfold"
+ "--update-at"
+ "--when-let"
+ "--zip-with"
+ "->"
+ "->>"
+ "-as->"
+ "-doto"
+ "-if-let"
+ "-if-let*"
+ "-lambda"
+ "-let"
+ "-let*"
+ "-setq"
+ "-some-->"
+ "-some->"
+ "-some->>"
+ "-split-on"
+ "-when-let"
+ "-when-let*")))
+ `((,(concat "(" (regexp-opt macs 'symbols)) . 1)))))
+ "Font lock keywords for `dash-fontify-mode'.")
+
+(defcustom dash-fontify-mode-lighter nil
+ "Mode line lighter for `dash-fontify-mode'.
+Either a string to display in the mode line when
+`dash-fontify-mode' is on, or nil to display
+nothing (the default)."
+ :package-version '(dash . "2.18.0")
+ :group 'dash
+ :type '(choice (string :tag "Lighter" :value " Dash")
+ (const :tag "Nothing" nil)))
+
+;;;###autoload
+(define-minor-mode dash-fontify-mode
+ "Toggle fontification of Dash special variables.
+
+Dash-Fontify mode is a buffer-local minor mode intended for Emacs
+Lisp buffers. Enabling it causes the special variables bound in
+anaphoric Dash macros to be fontified. These anaphoras include
+`it', `it-index', `acc', and `other'. In older Emacs versions
+which do not dynamically detect macros, Dash-Fontify mode
+additionally fontifies Dash macro calls.
+
+See also `dash-fontify-mode-lighter' and
+`global-dash-fontify-mode'."
+ :group 'dash :lighter dash-fontify-mode-lighter
+ (if dash-fontify-mode
+ (font-lock-add-keywords nil dash--keywords t)
+ (font-lock-remove-keywords nil dash--keywords))
+ (cond ((fboundp 'font-lock-flush) ;; Added in Emacs 25.
+ (font-lock-flush))
+ ;; `font-lock-fontify-buffer' unconditionally enables
+ ;; `font-lock-mode' and is marked `interactive-only' in later
+ ;; Emacs versions which have `font-lock-flush', so we guard
+ ;; and pacify as needed, respectively.
+ (font-lock-mode
+ (with-no-warnings
+ (font-lock-fontify-buffer)))))
+
+(defun dash--turn-on-fontify-mode ()
+ "Enable `dash-fontify-mode' if in an Emacs Lisp buffer."
+ (when (derived-mode-p #'emacs-lisp-mode)
+ (dash-fontify-mode)))
+
+;;;###autoload
+(define-globalized-minor-mode global-dash-fontify-mode
+ dash-fontify-mode dash--turn-on-fontify-mode
+ :group 'dash)
+
+(defcustom dash-enable-fontlock nil
+ "If non-nil, fontify Dash macro calls and special variables."
+ :group 'dash
+ :set (lambda (sym val)
+ (set-default sym val)
+ (global-dash-fontify-mode (if val 1 0)))
+ :type 'boolean)
+
+(make-obsolete-variable
+ 'dash-enable-fontlock #'global-dash-fontify-mode "2.18.0")
+
+(define-obsolete-function-alias
+ 'dash-enable-font-lock #'global-dash-fontify-mode "2.18.0")
+
+;;; Info
+
+(defvar dash--info-doc-spec '("(dash) Index" nil "^ -+ .*: " "\\( \\|$\\)")
+ "The Dash :doc-spec entry for `info-lookup-alist'.
+It is based on that for `emacs-lisp-mode'.")
+
+(defun dash--info-elisp-docs ()
+ "Return the `emacs-lisp-mode' symbol docs from `info-lookup-alist'.
+Specifically, return the cons containing their
+`info-lookup->doc-spec' so that we can modify it."
+ (defvar info-lookup-alist)
+ (nthcdr 3 (assq #'emacs-lisp-mode (cdr (assq 'symbol info-lookup-alist)))))
+
+;;;###autoload
+(defun dash-register-info-lookup ()
+ "Register the Dash Info manual with `info-lookup-symbol'.
+This allows Dash symbols to be looked up with \\[info-lookup-symbol]."
+ (interactive)
+ (require 'info-look)
+ (let ((docs (dash--info-elisp-docs)))
+ (setcar docs (append (car docs) (list dash--info-doc-spec)))
+ (info-lookup-reset)))
+
+(defun dash-unload-function ()
+ "Remove Dash from `info-lookup-alist'.
+Used by `unload-feature', which see."
+ (let ((docs (and (featurep 'info-look)
+ (dash--info-elisp-docs))))
+ (when (member dash--info-doc-spec (car docs))
+ (setcar docs (remove dash--info-doc-spec (car docs)))
+ (info-lookup-reset)))
+ nil)
+
+(provide 'dash)
+;;; dash.el ends here
diff --git a/elpa/dash-20220417.2250/dash.elc b/elpa/dash-20220417.2250/dash.elc
new file mode 100644
index 0000000..261710e
--- /dev/null
+++ b/elpa/dash-20220417.2250/dash.elc
Binary files differ
diff --git a/elpa/dash-20220417.2250/dash.info b/elpa/dash-20220417.2250/dash.info
new file mode 100644
index 0000000..2741464
--- /dev/null
+++ b/elpa/dash-20220417.2250/dash.info
@@ -0,0 +1,4766 @@
+This is dash.info, produced by makeinfo version 6.7 from dash.texi.
+
+This manual is for Dash version 2.19.1.
+
+ Copyright © 2012–2021 Free Software Foundation, Inc.
+
+ Permission is granted to copy, distribute and/or modify this
+ document under the terms of the GNU Free Documentation License,
+ Version 1.3 or any later version published by the Free Software
+ Foundation; with the Invariant Sections being “GNU General Public
+ License,” and no Front-Cover Texts or Back-Cover Texts. A copy of
+ the license is included in the section entitled “GNU Free
+ Documentation License”.
+INFO-DIR-SECTION Emacs
+START-INFO-DIR-ENTRY
+* Dash: (dash.info). A modern list library for GNU Emacs.
+END-INFO-DIR-ENTRY
+
+
+File: dash.info, Node: Top, Next: Installation, Up: (dir)
+
+Dash
+****
+
+This manual is for Dash version 2.19.1.
+
+ Copyright © 2012–2021 Free Software Foundation, Inc.
+
+ Permission is granted to copy, distribute and/or modify this
+ document under the terms of the GNU Free Documentation License,
+ Version 1.3 or any later version published by the Free Software
+ Foundation; with the Invariant Sections being “GNU General Public
+ License,” and no Front-Cover Texts or Back-Cover Texts. A copy of
+ the license is included in the section entitled “GNU Free
+ Documentation License”.
+
+* Menu:
+
+* Installation:: Installing and configuring Dash.
+* Functions:: Dash API reference.
+* Development:: Contributing to Dash development.
+
+Appendices
+
+* FDL:: The license for this documentation.
+* GPL:: Conditions for copying and changing Dash.
+* Index:: Index including functions and macros.
+
+ — The Detailed Node Listing —
+
+Installation
+
+* Using in a package:: Listing Dash as a package dependency.
+* Fontification of special variables:: Font Lock of anaphoric macro variables.
+* Info symbol lookup:: Looking up Dash symbols in this manual.
+
+Functions
+
+* Maps::
+* Sublist selection::
+* List to list::
+* Reductions::
+* Unfolding::
+* Predicates::
+* Partitioning::
+* Indexing::
+* Set operations::
+* Other list operations::
+* Tree operations::
+* Threading macros::
+* Binding::
+* Side effects::
+* Destructive operations::
+* Function combinators::
+
+Development
+
+* Contribute:: How to contribute.
+* Contributors:: List of contributors.
+
+
+File: dash.info, Node: Installation, Next: Functions, Prev: Top, Up: Top
+
+1 Installation
+**************
+
+Dash is available on GNU ELPA (https://elpa.gnu.org/), GNU-devel ELPA
+(https://elpa.gnu.org/devel/), and MELPA (https://melpa.org/), and can
+be installed with the standard command ‘package-install’ (*note
+(emacs)Package Installation::).
+
+‘M-x package-install <RET> dash <RET>’
+ Install the Dash library.
+
+ Alternatively, you can just dump ‘dash.el’ in your ‘load-path’
+somewhere (*note (emacs)Lisp Libraries::).
+
+* Menu:
+
+* Using in a package:: Listing Dash as a package dependency.
+* Fontification of special variables:: Font Lock of anaphoric macro variables.
+* Info symbol lookup:: Looking up Dash symbols in this manual.
+
+
+File: dash.info, Node: Using in a package, Next: Fontification of special variables, Up: Installation
+
+1.1 Using in a package
+======================
+
+If you use Dash in your own package, be sure to list it as a dependency
+in the library’s headers as follows (*note (elisp)Library Headers::).
+
+ ;; Package-Requires: ((dash "2.19.1"))
+
+
+File: dash.info, Node: Fontification of special variables, Next: Info symbol lookup, Prev: Using in a package, Up: Installation
+
+1.2 Fontification of special variables
+======================================
+
+The autoloaded minor mode ‘dash-fontify-mode’ is provided for optional
+fontification of anaphoric Dash variables (‘it’, ‘acc’, etc.) in Emacs
+Lisp buffers using search-based Font Lock (*note (emacs)Font Lock::).
+In older Emacs versions which do not dynamically detect macros, the
+minor mode also fontifies calls to Dash macros.
+
+ To automatically enable the minor mode in all Emacs Lisp buffers,
+just call its autoloaded global counterpart ‘global-dash-fontify-mode’,
+either interactively or from your ‘user-init-file’:
+
+ (global-dash-fontify-mode)
+
+
+File: dash.info, Node: Info symbol lookup, Prev: Fontification of special variables, Up: Installation
+
+1.3 Info symbol lookup
+======================
+
+While editing Elisp files, you can use ‘C-h S’ (‘info-lookup-symbol’) to
+look up Elisp symbols in the relevant Info manuals (*note (emacs)Info
+Lookup::). To enable the same for Dash symbols, use the command
+‘dash-register-info-lookup’. It can be called directly when needed, or
+automatically from your ‘user-init-file’. For example:
+
+ (with-eval-after-load 'info-look
+ (dash-register-info-lookup))
+
+
+File: dash.info, Node: Functions, Next: Development, Prev: Installation, Up: Top
+
+2 Functions
+***********
+
+This chapter contains reference documentation for the Dash API
+(Application Programming Interface). The names of all public functions
+defined in the library are prefixed with a dash character (‘-’).
+
+ The library also provides anaphoric macro versions of functions where
+that makes sense. The names of these macros are prefixed with two
+dashes (‘--’) instead of one.
+
+ For instance, while the function ‘-map’ applies a function to each
+element of a list, its anaphoric counterpart ‘--map’ evaluates a form
+with the local variable ‘it’ temporarily bound to the current list
+element instead.
+
+ ;; Normal version.
+ (-map (lambda (n) (* n n)) '(1 2 3 4))
+ ⇒ (1 4 9 16)
+
+ ;; Anaphoric version.
+ (--map (* it it) '(1 2 3 4))
+ ⇒ (1 4 9 16)
+
+ The normal version can, of course, also be written as in the
+following example, which demonstrates the utility of both versions.
+
+ (defun my-square (n)
+ "Return N multiplied by itself."
+ (* n n))
+
+ (-map #'my-square '(1 2 3 4))
+ ⇒ (1 4 9 16)
+
+* Menu:
+
+* Maps::
+* Sublist selection::
+* List to list::
+* Reductions::
+* Unfolding::
+* Predicates::
+* Partitioning::
+* Indexing::
+* Set operations::
+* Other list operations::
+* Tree operations::
+* Threading macros::
+* Binding::
+* Side effects::
+* Destructive operations::
+* Function combinators::
+
+
+File: dash.info, Node: Maps, Next: Sublist selection, Up: Functions
+
+2.1 Maps
+========
+
+Functions in this category take a transforming function, which is then
+applied sequentially to each or selected elements of the input list.
+The results are collected in order and returned as a new list.
+
+ -- Function: -map (fn list)
+ Apply FN to each item in LIST and return the list of results.
+
+ This function’s anaphoric counterpart is ‘--map’.
+
+ (-map (lambda (num) (* num num)) '(1 2 3 4))
+ ⇒ (1 4 9 16)
+ (-map #'1+ '(1 2 3 4))
+ ⇒ (2 3 4 5)
+ (--map (* it it) '(1 2 3 4))
+ ⇒ (1 4 9 16)
+
+ -- Function: -map-when (pred rep list)
+ Use PRED to conditionally apply REP to each item in LIST. Return a
+ copy of LIST where the items for which PRED returns ‘nil’ are
+ unchanged, and the rest are mapped through the REP function.
+
+ Alias: ‘-replace-where’
+
+ See also: ‘-update-at’ (*note -update-at::)
+
+ (-map-when 'even? 'square '(1 2 3 4))
+ ⇒ (1 4 3 16)
+ (--map-when (> it 2) (* it it) '(1 2 3 4))
+ ⇒ (1 2 9 16)
+ (--map-when (= it 2) 17 '(1 2 3 4))
+ ⇒ (1 17 3 4)
+
+ -- Function: -map-first (pred rep list)
+ Use PRED to determine the first item in LIST to call REP on.
+ Return a copy of LIST where the first item for which PRED returns
+ non-‘nil’ is replaced with the result of calling REP on that item.
+
+ See also: ‘-map-when’ (*note -map-when::), ‘-replace-first’ (*note
+ -replace-first::)
+
+ (-map-first 'even? 'square '(1 2 3 4))
+ ⇒ (1 4 3 4)
+ (--map-first (> it 2) (* it it) '(1 2 3 4))
+ ⇒ (1 2 9 4)
+ (--map-first (= it 2) 17 '(1 2 3 2))
+ ⇒ (1 17 3 2)
+
+ -- Function: -map-last (pred rep list)
+ Use PRED to determine the last item in LIST to call REP on. Return
+ a copy of LIST where the last item for which PRED returns non-‘nil’
+ is replaced with the result of calling REP on that item.
+
+ See also: ‘-map-when’ (*note -map-when::), ‘-replace-last’ (*note
+ -replace-last::)
+
+ (-map-last 'even? 'square '(1 2 3 4))
+ ⇒ (1 2 3 16)
+ (--map-last (> it 2) (* it it) '(1 2 3 4))
+ ⇒ (1 2 3 16)
+ (--map-last (= it 2) 17 '(1 2 3 2))
+ ⇒ (1 2 3 17)
+
+ -- Function: -map-indexed (fn list)
+ Apply FN to each index and item in LIST and return the list of
+ results. This is like ‘-map’ (*note -map::), but FN takes two
+ arguments: the index of the current element within LIST, and the
+ element itself.
+
+ This function’s anaphoric counterpart is ‘--map-indexed’.
+
+ For a side-effecting variant, see also ‘-each-indexed’ (*note
+ -each-indexed::).
+
+ (-map-indexed (lambda (index item) (- item index)) '(1 2 3 4))
+ ⇒ (1 1 1 1)
+ (--map-indexed (- it it-index) '(1 2 3 4))
+ ⇒ (1 1 1 1)
+ (-map-indexed #'* '(1 2 3 4))
+ ⇒ (0 2 6 12)
+
+ -- Function: -annotate (fn list)
+ Return a list of cons cells where each cell is FN applied to each
+ element of LIST paired with the unmodified element of LIST.
+
+ (-annotate '1+ '(1 2 3))
+ ⇒ ((2 . 1) (3 . 2) (4 . 3))
+ (-annotate 'length '(("h" "e" "l" "l" "o") ("hello" "world")))
+ ⇒ ((5 "h" "e" "l" "l" "o") (2 "hello" "world"))
+ (--annotate (< 1 it) '(0 1 2 3))
+ ⇒ ((nil . 0) (nil . 1) (t . 2) (t . 3))
+
+ -- Function: -splice (pred fun list)
+ Splice lists generated by FUN in place of elements matching PRED in
+ LIST.
+
+ FUN takes the element matching PRED as input.
+
+ This function can be used as replacement for ‘,@’ in case you need
+ to splice several lists at marked positions (for example with
+ keywords).
+
+ See also: ‘-splice-list’ (*note -splice-list::), ‘-insert-at’
+ (*note -insert-at::)
+
+ (-splice 'even? (lambda (x) (list x x)) '(1 2 3 4))
+ ⇒ (1 2 2 3 4 4)
+ (--splice 't (list it it) '(1 2 3 4))
+ ⇒ (1 1 2 2 3 3 4 4)
+ (--splice (equal it :magic) '((list of) (magical) (code)) '((foo) (bar) :magic (baz)))
+ ⇒ ((foo) (bar) (list of) (magical) (code) (baz))
+
+ -- Function: -splice-list (pred new-list list)
+ Splice NEW-LIST in place of elements matching PRED in LIST.
+
+ See also: ‘-splice’ (*note -splice::), ‘-insert-at’ (*note
+ -insert-at::)
+
+ (-splice-list 'keywordp '(a b c) '(1 :foo 2))
+ ⇒ (1 a b c 2)
+ (-splice-list 'keywordp nil '(1 :foo 2))
+ ⇒ (1 2)
+ (--splice-list (keywordp it) '(a b c) '(1 :foo 2))
+ ⇒ (1 a b c 2)
+
+ -- Function: -mapcat (fn list)
+ Return the concatenation of the result of mapping FN over LIST.
+ Thus function FN should return a list.
+
+ (-mapcat 'list '(1 2 3))
+ ⇒ (1 2 3)
+ (-mapcat (lambda (item) (list 0 item)) '(1 2 3))
+ ⇒ (0 1 0 2 0 3)
+ (--mapcat (list 0 it) '(1 2 3))
+ ⇒ (0 1 0 2 0 3)
+
+ -- Function: -copy (list)
+ Create a shallow copy of LIST.
+
+ (-copy '(1 2 3))
+ ⇒ (1 2 3)
+ (let ((a '(1 2 3))) (eq a (-copy a)))
+ ⇒ nil
+
+
+File: dash.info, Node: Sublist selection, Next: List to list, Prev: Maps, Up: Functions
+
+2.2 Sublist selection
+=====================
+
+Functions returning a sublist of the original list.
+
+ -- Function: -filter (pred list)
+ Return a new list of the items in LIST for which PRED returns
+ non-‘nil’.
+
+ Alias: ‘-select’.
+
+ This function’s anaphoric counterpart is ‘--filter’.
+
+ For similar operations, see also ‘-keep’ (*note -keep::) and
+ ‘-remove’ (*note -remove::).
+
+ (-filter (lambda (num) (= 0 (% num 2))) '(1 2 3 4))
+ ⇒ (2 4)
+ (-filter #'natnump '(-2 -1 0 1 2))
+ ⇒ (0 1 2)
+ (--filter (= 0 (% it 2)) '(1 2 3 4))
+ ⇒ (2 4)
+
+ -- Function: -remove (pred list)
+ Return a new list of the items in LIST for which PRED returns
+ ‘nil’.
+
+ Alias: ‘-reject’.
+
+ This function’s anaphoric counterpart is ‘--remove’.
+
+ For similar operations, see also ‘-keep’ (*note -keep::) and
+ ‘-filter’ (*note -filter::).
+
+ (-remove (lambda (num) (= 0 (% num 2))) '(1 2 3 4))
+ ⇒ (1 3)
+ (-remove #'natnump '(-2 -1 0 1 2))
+ ⇒ (-2 -1)
+ (--remove (= 0 (% it 2)) '(1 2 3 4))
+ ⇒ (1 3)
+
+ -- Function: -remove-first (pred list)
+ Remove the first item from LIST for which PRED returns non-‘nil’.
+ This is a non-destructive operation, but only the front of LIST
+ leading up to the removed item is a copy; the rest is LIST’s
+ original tail. If no item is removed, then the result is a
+ complete copy.
+
+ Alias: ‘-reject-first’.
+
+ This function’s anaphoric counterpart is ‘--remove-first’.
+
+ See also ‘-map-first’ (*note -map-first::), ‘-remove-item’ (*note
+ -remove-item::), and ‘-remove-last’ (*note -remove-last::).
+
+ (-remove-first #'natnump '(-2 -1 0 1 2))
+ ⇒ (-2 -1 1 2)
+ (-remove-first #'stringp '(1 2 "first" "second"))
+ ⇒ (1 2 "second")
+ (--remove-first (> it 3) '(1 2 3 4 5 6))
+ ⇒ (1 2 3 5 6)
+
+ -- Function: -remove-last (pred list)
+ Remove the last item from LIST for which PRED returns non-‘nil’.
+ The result is a copy of LIST regardless of whether an element is
+ removed.
+
+ Alias: ‘-reject-last’.
+
+ This function’s anaphoric counterpart is ‘--remove-last’.
+
+ See also ‘-map-last’ (*note -map-last::), ‘-remove-item’ (*note
+ -remove-item::), and ‘-remove-first’ (*note -remove-first::).
+
+ (-remove-last #'natnump '(1 3 5 4 7 8 10 -11))
+ ⇒ (1 3 5 4 7 8 -11)
+ (-remove-last #'stringp '(1 2 "last" "second"))
+ ⇒ (1 2 "last")
+ (--remove-last (> it 3) '(1 2 3 4 5 6 7 8 9 10))
+ ⇒ (1 2 3 4 5 6 7 8 9)
+
+ -- Function: -remove-item (item list)
+ Return a copy of LIST with all occurrences of ITEM removed. The
+ comparison is done with ‘equal’.
+
+ (-remove-item 3 '(1 2 3 2 3 4 5 3))
+ ⇒ (1 2 2 4 5)
+ (-remove-item 'foo '(foo bar baz foo))
+ ⇒ (bar baz)
+ (-remove-item "bob" '("alice" "bob" "eve" "bob"))
+ ⇒ ("alice" "eve")
+
+ -- Function: -non-nil (list)
+ Return a copy of LIST with all ‘nil’ items removed.
+
+ (-non-nil '(nil 1 nil 2 nil nil 3 4 nil 5 nil))
+ ⇒ (1 2 3 4 5)
+ (-non-nil '((nil)))
+ ⇒ ((nil))
+ (-non-nil ())
+ ⇒ ()
+
+ -- Function: -slice (list from &optional to step)
+ Return copy of LIST, starting from index FROM to index TO.
+
+ FROM or TO may be negative. These values are then interpreted
+ modulo the length of the list.
+
+ If STEP is a number, only each STEPth item in the resulting section
+ is returned. Defaults to 1.
+
+ (-slice '(1 2 3 4 5) 1)
+ ⇒ (2 3 4 5)
+ (-slice '(1 2 3 4 5) 0 3)
+ ⇒ (1 2 3)
+ (-slice '(1 2 3 4 5 6 7 8 9) 1 -1 2)
+ ⇒ (2 4 6 8)
+
+ -- Function: -take (n list)
+ Return a copy of the first N items in LIST. Return a copy of LIST
+ if it contains N items or fewer. Return ‘nil’ if N is zero or
+ less.
+
+ See also: ‘-take-last’ (*note -take-last::).
+
+ (-take 3 '(1 2 3 4 5))
+ ⇒ (1 2 3)
+ (-take 17 '(1 2 3 4 5))
+ ⇒ (1 2 3 4 5)
+ (-take 0 '(1 2 3 4 5))
+ ⇒ ()
+
+ -- Function: -take-last (n list)
+ Return a copy of the last N items of LIST in order. Return a copy
+ of LIST if it contains N items or fewer. Return ‘nil’ if N is zero
+ or less.
+
+ See also: ‘-take’ (*note -take::).
+
+ (-take-last 3 '(1 2 3 4 5))
+ ⇒ (3 4 5)
+ (-take-last 17 '(1 2 3 4 5))
+ ⇒ (1 2 3 4 5)
+ (-take-last 1 '(1 2 3 4 5))
+ ⇒ (5)
+
+ -- Function: -drop (n list)
+ Return the tail (not a copy) of LIST without the first N items.
+ Return ‘nil’ if LIST contains N items or fewer. Return LIST if N
+ is zero or less.
+
+ For another variant, see also ‘-drop-last’ (*note -drop-last::).
+
+ (-drop 3 '(1 2 3 4 5))
+ ⇒ (4 5)
+ (-drop 17 '(1 2 3 4 5))
+ ⇒ ()
+ (-drop 0 '(1 2 3 4 5))
+ ⇒ (1 2 3 4 5)
+
+ -- Function: -drop-last (n list)
+ Return a copy of LIST without its last N items. Return a copy of
+ LIST if N is zero or less. Return ‘nil’ if LIST contains N items
+ or fewer.
+
+ See also: ‘-drop’ (*note -drop::).
+
+ (-drop-last 3 '(1 2 3 4 5))
+ ⇒ (1 2)
+ (-drop-last 17 '(1 2 3 4 5))
+ ⇒ ()
+ (-drop-last 0 '(1 2 3 4 5))
+ ⇒ (1 2 3 4 5)
+
+ -- Function: -take-while (pred list)
+ Take successive items from LIST for which PRED returns non-‘nil’.
+ PRED is a function of one argument. Return a new list of the
+ successive elements from the start of LIST for which PRED returns
+ non-‘nil’.
+
+ This function’s anaphoric counterpart is ‘--take-while’.
+
+ For another variant, see also ‘-drop-while’ (*note -drop-while::).
+
+ (-take-while #'even? '(1 2 3 4))
+ ⇒ ()
+ (-take-while #'even? '(2 4 5 6))
+ ⇒ (2 4)
+ (--take-while (< it 4) '(1 2 3 4 3 2 1))
+ ⇒ (1 2 3)
+
+ -- Function: -drop-while (pred list)
+ Drop successive items from LIST for which PRED returns non-‘nil’.
+ PRED is a function of one argument. Return the tail (not a copy)
+ of LIST starting from its first element for which PRED returns
+ ‘nil’.
+
+ This function’s anaphoric counterpart is ‘--drop-while’.
+
+ For another variant, see also ‘-take-while’ (*note -take-while::).
+
+ (-drop-while #'even? '(1 2 3 4))
+ ⇒ (1 2 3 4)
+ (-drop-while #'even? '(2 4 5 6))
+ ⇒ (5 6)
+ (--drop-while (< it 4) '(1 2 3 4 3 2 1))
+ ⇒ (4 3 2 1)
+
+ -- Function: -select-by-indices (indices list)
+ Return a list whose elements are elements from LIST selected as
+ ‘(nth i list)‘ for all i from INDICES.
+
+ (-select-by-indices '(4 10 2 3 6) '("v" "e" "l" "o" "c" "i" "r" "a" "p" "t" "o" "r"))
+ ⇒ ("c" "o" "l" "o" "r")
+ (-select-by-indices '(2 1 0) '("a" "b" "c"))
+ ⇒ ("c" "b" "a")
+ (-select-by-indices '(0 1 2 0 1 3 3 1) '("f" "a" "r" "l"))
+ ⇒ ("f" "a" "r" "f" "a" "l" "l" "a")
+
+ -- Function: -select-columns (columns table)
+ Select COLUMNS from TABLE.
+
+ TABLE is a list of lists where each element represents one row. It
+ is assumed each row has the same length.
+
+ Each row is transformed such that only the specified COLUMNS are
+ selected.
+
+ See also: ‘-select-column’ (*note -select-column::),
+ ‘-select-by-indices’ (*note -select-by-indices::)
+
+ (-select-columns '(0 2) '((1 2 3) (a b c) (:a :b :c)))
+ ⇒ ((1 3) (a c) (:a :c))
+ (-select-columns '(1) '((1 2 3) (a b c) (:a :b :c)))
+ ⇒ ((2) (b) (:b))
+ (-select-columns nil '((1 2 3) (a b c) (:a :b :c)))
+ ⇒ (nil nil nil)
+
+ -- Function: -select-column (column table)
+ Select COLUMN from TABLE.
+
+ TABLE is a list of lists where each element represents one row. It
+ is assumed each row has the same length.
+
+ The single selected column is returned as a list.
+
+ See also: ‘-select-columns’ (*note -select-columns::),
+ ‘-select-by-indices’ (*note -select-by-indices::)
+
+ (-select-column 1 '((1 2 3) (a b c) (:a :b :c)))
+ ⇒ (2 b :b)
+
+
+File: dash.info, Node: List to list, Next: Reductions, Prev: Sublist selection, Up: Functions
+
+2.3 List to list
+================
+
+Functions returning a modified copy of the input list.
+
+ -- Function: -keep (fn list)
+ Return a new list of the non-‘nil’ results of applying FN to each
+ item in LIST. Like ‘-filter’ (*note -filter::), but returns the
+ non-‘nil’ results of FN instead of the corresponding elements of
+ LIST.
+
+ Its anaphoric counterpart is ‘--keep’.
+
+ (-keep #'cdr '((1 2 3) (4 5) (6)))
+ ⇒ ((2 3) (5))
+ (-keep (lambda (n) (and (> n 3) (* 10 n))) '(1 2 3 4 5 6))
+ ⇒ (40 50 60)
+ (--keep (and (> it 3) (* 10 it)) '(1 2 3 4 5 6))
+ ⇒ (40 50 60)
+
+ -- Function: -concat (&rest sequences)
+ Concatenate all the arguments and make the result a list. The
+ result is a list whose elements are the elements of all the
+ arguments. Each argument may be a list, vector or string. The
+ last argument is not copied, just used as the tail of the new list.
+
+ (-concat '(1))
+ ⇒ (1)
+ (-concat '(1) '(2))
+ ⇒ (1 2)
+ (-concat '(1) '(2 3) '(4))
+ ⇒ (1 2 3 4)
+
+ -- Function: -flatten (l)
+ Take a nested list L and return its contents as a single, flat
+ list.
+
+ Note that because ‘nil’ represents a list of zero elements (an
+ empty list), any mention of ‘nil’ in L will disappear after
+ flattening. If you need to preserve nils, consider ‘-flatten-n’
+ (*note -flatten-n::) or map them to some unique symbol and then map
+ them back.
+
+ Conses of two atoms are considered "terminals", that is, they
+ aren’t flattened further.
+
+ See also: ‘-flatten-n’ (*note -flatten-n::)
+
+ (-flatten '((1)))
+ ⇒ (1)
+ (-flatten '((1 (2 3) (((4 (5)))))))
+ ⇒ (1 2 3 4 5)
+ (-flatten '(1 2 (3 . 4)))
+ ⇒ (1 2 (3 . 4))
+
+ -- Function: -flatten-n (num list)
+ Flatten NUM levels of a nested LIST.
+
+ See also: ‘-flatten’ (*note -flatten::)
+
+ (-flatten-n 1 '((1 2) ((3 4) ((5 6)))))
+ ⇒ (1 2 (3 4) ((5 6)))
+ (-flatten-n 2 '((1 2) ((3 4) ((5 6)))))
+ ⇒ (1 2 3 4 (5 6))
+ (-flatten-n 3 '((1 2) ((3 4) ((5 6)))))
+ ⇒ (1 2 3 4 5 6)
+
+ -- Function: -replace (old new list)
+ Replace all OLD items in LIST with NEW.
+
+ Elements are compared using ‘equal’.
+
+ See also: ‘-replace-at’ (*note -replace-at::)
+
+ (-replace 1 "1" '(1 2 3 4 3 2 1))
+ ⇒ ("1" 2 3 4 3 2 "1")
+ (-replace "foo" "bar" '("a" "nice" "foo" "sentence" "about" "foo"))
+ ⇒ ("a" "nice" "bar" "sentence" "about" "bar")
+ (-replace 1 2 nil)
+ ⇒ nil
+
+ -- Function: -replace-first (old new list)
+ Replace the first occurrence of OLD with NEW in LIST.
+
+ Elements are compared using ‘equal’.
+
+ See also: ‘-map-first’ (*note -map-first::)
+
+ (-replace-first 1 "1" '(1 2 3 4 3 2 1))
+ ⇒ ("1" 2 3 4 3 2 1)
+ (-replace-first "foo" "bar" '("a" "nice" "foo" "sentence" "about" "foo"))
+ ⇒ ("a" "nice" "bar" "sentence" "about" "foo")
+ (-replace-first 1 2 nil)
+ ⇒ nil
+
+ -- Function: -replace-last (old new list)
+ Replace the last occurrence of OLD with NEW in LIST.
+
+ Elements are compared using ‘equal’.
+
+ See also: ‘-map-last’ (*note -map-last::)
+
+ (-replace-last 1 "1" '(1 2 3 4 3 2 1))
+ ⇒ (1 2 3 4 3 2 "1")
+ (-replace-last "foo" "bar" '("a" "nice" "foo" "sentence" "about" "foo"))
+ ⇒ ("a" "nice" "foo" "sentence" "about" "bar")
+ (-replace-last 1 2 nil)
+ ⇒ nil
+
+ -- Function: -insert-at (n x list)
+ Return a list with X inserted into LIST at position N.
+
+ See also: ‘-splice’ (*note -splice::), ‘-splice-list’ (*note
+ -splice-list::)
+
+ (-insert-at 1 'x '(a b c))
+ ⇒ (a x b c)
+ (-insert-at 12 'x '(a b c))
+ ⇒ (a b c x)
+
+ -- Function: -replace-at (n x list)
+ Return a list with element at Nth position in LIST replaced with X.
+
+ See also: ‘-replace’ (*note -replace::)
+
+ (-replace-at 0 9 '(0 1 2 3 4 5))
+ ⇒ (9 1 2 3 4 5)
+ (-replace-at 1 9 '(0 1 2 3 4 5))
+ ⇒ (0 9 2 3 4 5)
+ (-replace-at 4 9 '(0 1 2 3 4 5))
+ ⇒ (0 1 2 3 9 5)
+
+ -- Function: -update-at (n func list)
+ Use FUNC to update the Nth element of LIST. Return a copy of LIST
+ where the Nth element is replaced with the result of calling FUNC
+ on it.
+
+ See also: ‘-map-when’ (*note -map-when::)
+
+ (-update-at 0 (lambda (x) (+ x 9)) '(0 1 2 3 4 5))
+ ⇒ (9 1 2 3 4 5)
+ (-update-at 1 (lambda (x) (+ x 8)) '(0 1 2 3 4 5))
+ ⇒ (0 9 2 3 4 5)
+ (--update-at 2 (length it) '("foo" "bar" "baz" "quux"))
+ ⇒ ("foo" "bar" 3 "quux")
+
+ -- Function: -remove-at (n list)
+ Return a list with element at Nth position in LIST removed.
+
+ See also: ‘-remove-at-indices’ (*note -remove-at-indices::),
+ ‘-remove’ (*note -remove::)
+
+ (-remove-at 0 '("0" "1" "2" "3" "4" "5"))
+ ⇒ ("1" "2" "3" "4" "5")
+ (-remove-at 1 '("0" "1" "2" "3" "4" "5"))
+ ⇒ ("0" "2" "3" "4" "5")
+ (-remove-at 2 '("0" "1" "2" "3" "4" "5"))
+ ⇒ ("0" "1" "3" "4" "5")
+
+ -- Function: -remove-at-indices (indices list)
+ Return a list whose elements are elements from LIST without
+ elements selected as ‘(nth i list)‘ for all i from INDICES.
+
+ See also: ‘-remove-at’ (*note -remove-at::), ‘-remove’ (*note
+ -remove::)
+
+ (-remove-at-indices '(0) '("0" "1" "2" "3" "4" "5"))
+ ⇒ ("1" "2" "3" "4" "5")
+ (-remove-at-indices '(0 2 4) '("0" "1" "2" "3" "4" "5"))
+ ⇒ ("1" "3" "5")
+ (-remove-at-indices '(0 5) '("0" "1" "2" "3" "4" "5"))
+ ⇒ ("1" "2" "3" "4")
+
+
+File: dash.info, Node: Reductions, Next: Unfolding, Prev: List to list, Up: Functions
+
+2.4 Reductions
+==============
+
+Functions reducing lists to a single value (which may also be a list).
+
+ -- Function: -reduce-from (fn init list)
+ Reduce the function FN across LIST, starting with INIT. Return the
+ result of applying FN to INIT and the first element of LIST, then
+ applying FN to that result and the second element, etc. If LIST is
+ empty, return INIT without calling FN.
+
+ This function’s anaphoric counterpart is ‘--reduce-from’.
+
+ For other folds, see also ‘-reduce’ (*note -reduce::) and
+ ‘-reduce-r’ (*note -reduce-r::).
+
+ (-reduce-from #'- 10 '(1 2 3))
+ ⇒ 4
+ (-reduce-from #'list 10 '(1 2 3))
+ ⇒ (((10 1) 2) 3)
+ (--reduce-from (concat acc " " it) "START" '("a" "b" "c"))
+ ⇒ "START a b c"
+
+ -- Function: -reduce-r-from (fn init list)
+ Reduce the function FN across LIST in reverse, starting with INIT.
+ Return the result of applying FN to the last element of LIST and
+ INIT, then applying FN to the second-to-last element and the
+ previous result of FN, etc. That is, the first argument of FN is
+ the current element, and its second argument the accumulated value.
+ If LIST is empty, return INIT without calling FN.
+
+ This function is like ‘-reduce-from’ (*note -reduce-from::) but the
+ operation associates from the right rather than left. In other
+ words, it starts from the end of LIST and flips the arguments to
+ FN. Conceptually, it is like replacing the conses in LIST with
+ applications of FN, and its last link with INIT, and evaluating the
+ resulting expression.
+
+ This function’s anaphoric counterpart is ‘--reduce-r-from’.
+
+ For other folds, see also ‘-reduce-r’ (*note -reduce-r::) and
+ ‘-reduce’ (*note -reduce::).
+
+ (-reduce-r-from #'- 10 '(1 2 3))
+ ⇒ -8
+ (-reduce-r-from #'list 10 '(1 2 3))
+ ⇒ (1 (2 (3 10)))
+ (--reduce-r-from (concat it " " acc) "END" '("a" "b" "c"))
+ ⇒ "a b c END"
+
+ -- Function: -reduce (fn list)
+ Reduce the function FN across LIST. Return the result of applying
+ FN to the first two elements of LIST, then applying FN to that
+ result and the third element, etc. If LIST contains a single
+ element, return it without calling FN. If LIST is empty, return
+ the result of calling FN with no arguments.
+
+ This function’s anaphoric counterpart is ‘--reduce’.
+
+ For other folds, see also ‘-reduce-from’ (*note -reduce-from::) and
+ ‘-reduce-r’ (*note -reduce-r::).
+
+ (-reduce #'- '(1 2 3 4))
+ ⇒ -8
+ (-reduce #'list '(1 2 3 4))
+ ⇒ (((1 2) 3) 4)
+ (--reduce (format "%s-%d" acc it) '(1 2 3))
+ ⇒ "1-2-3"
+
+ -- Function: -reduce-r (fn list)
+ Reduce the function FN across LIST in reverse. Return the result
+ of applying FN to the last two elements of LIST, then applying FN
+ to the third-to-last element and the previous result of FN, etc.
+ That is, the first argument of FN is the current element, and its
+ second argument the accumulated value. If LIST contains a single
+ element, return it without calling FN. If LIST is empty, return
+ the result of calling FN with no arguments.
+
+ This function is like ‘-reduce’ (*note -reduce::) but the operation
+ associates from the right rather than left. In other words, it
+ starts from the end of LIST and flips the arguments to FN.
+ Conceptually, it is like replacing the conses in LIST with
+ applications of FN, ignoring its last link, and evaluating the
+ resulting expression.
+
+ This function’s anaphoric counterpart is ‘--reduce-r’.
+
+ For other folds, see also ‘-reduce-r-from’ (*note -reduce-r-from::)
+ and ‘-reduce’ (*note -reduce::).
+
+ (-reduce-r #'- '(1 2 3 4))
+ ⇒ -2
+ (-reduce-r #'list '(1 2 3 4))
+ ⇒ (1 (2 (3 4)))
+ (--reduce-r (format "%s-%d" acc it) '(1 2 3))
+ ⇒ "3-2-1"
+
+ -- Function: -reductions-from (fn init list)
+ Return a list of FN’s intermediate reductions across LIST. That
+ is, a list of the intermediate values of the accumulator when
+ ‘-reduce-from’ (*note -reduce-from::) (which see) is called with
+ the same arguments.
+
+ This function’s anaphoric counterpart is ‘--reductions-from’.
+
+ For other folds, see also ‘-reductions’ (*note -reductions::) and
+ ‘-reductions-r’ (*note -reductions-r::).
+
+ (-reductions-from #'max 0 '(2 1 4 3))
+ ⇒ (0 2 2 4 4)
+ (-reductions-from #'* 1 '(1 2 3 4))
+ ⇒ (1 1 2 6 24)
+ (--reductions-from (format "(FN %s %d)" acc it) "INIT" '(1 2 3))
+ ⇒ ("INIT" "(FN INIT 1)" "(FN (FN INIT 1) 2)" "(FN (FN (FN INIT 1) 2) 3)")
+
+ -- Function: -reductions-r-from (fn init list)
+ Return a list of FN’s intermediate reductions across reversed LIST.
+ That is, a list of the intermediate values of the accumulator when
+ ‘-reduce-r-from’ (*note -reduce-r-from::) (which see) is called
+ with the same arguments.
+
+ This function’s anaphoric counterpart is ‘--reductions-r-from’.
+
+ For other folds, see also ‘-reductions’ (*note -reductions::) and
+ ‘-reductions-r’ (*note -reductions-r::).
+
+ (-reductions-r-from #'max 0 '(2 1 4 3))
+ ⇒ (4 4 4 3 0)
+ (-reductions-r-from #'* 1 '(1 2 3 4))
+ ⇒ (24 24 12 4 1)
+ (--reductions-r-from (format "(FN %d %s)" it acc) "INIT" '(1 2 3))
+ ⇒ ("(FN 1 (FN 2 (FN 3 INIT)))" "(FN 2 (FN 3 INIT))" "(FN 3 INIT)" "INIT")
+
+ -- Function: -reductions (fn list)
+ Return a list of FN’s intermediate reductions across LIST. That
+ is, a list of the intermediate values of the accumulator when
+ ‘-reduce’ (*note -reduce::) (which see) is called with the same
+ arguments.
+
+ This function’s anaphoric counterpart is ‘--reductions’.
+
+ For other folds, see also ‘-reductions’ (*note -reductions::) and
+ ‘-reductions-r’ (*note -reductions-r::).
+
+ (-reductions #'+ '(1 2 3 4))
+ ⇒ (1 3 6 10)
+ (-reductions #'* '(1 2 3 4))
+ ⇒ (1 2 6 24)
+ (--reductions (format "(FN %s %d)" acc it) '(1 2 3))
+ ⇒ (1 "(FN 1 2)" "(FN (FN 1 2) 3)")
+
+ -- Function: -reductions-r (fn list)
+ Return a list of FN’s intermediate reductions across reversed LIST.
+ That is, a list of the intermediate values of the accumulator when
+ ‘-reduce-r’ (*note -reduce-r::) (which see) is called with the same
+ arguments.
+
+ This function’s anaphoric counterpart is ‘--reductions-r’.
+
+ For other folds, see also ‘-reductions-r-from’ (*note
+ -reductions-r-from::) and ‘-reductions’ (*note -reductions::).
+
+ (-reductions-r #'+ '(1 2 3 4))
+ ⇒ (10 9 7 4)
+ (-reductions-r #'* '(1 2 3 4))
+ ⇒ (24 24 12 4)
+ (--reductions-r (format "(FN %d %s)" it acc) '(1 2 3))
+ ⇒ ("(FN 1 (FN 2 3))" "(FN 2 3)" 3)
+
+ -- Function: -count (pred list)
+ Counts the number of items in LIST where (PRED item) is non-‘nil’.
+
+ (-count 'even? '(1 2 3 4 5))
+ ⇒ 2
+ (--count (< it 4) '(1 2 3 4))
+ ⇒ 3
+
+ -- Function: -sum (list)
+ Return the sum of LIST.
+
+ (-sum ())
+ ⇒ 0
+ (-sum '(1))
+ ⇒ 1
+ (-sum '(1 2 3 4))
+ ⇒ 10
+
+ -- Function: -running-sum (list)
+ Return a list with running sums of items in LIST. LIST must be
+ non-empty.
+
+ (-running-sum '(1 2 3 4))
+ ⇒ (1 3 6 10)
+ (-running-sum '(1))
+ ⇒ (1)
+ (-running-sum ())
+ error→ Wrong type argument: consp, nil
+
+ -- Function: -product (list)
+ Return the product of LIST.
+
+ (-product ())
+ ⇒ 1
+ (-product '(1))
+ ⇒ 1
+ (-product '(1 2 3 4))
+ ⇒ 24
+
+ -- Function: -running-product (list)
+ Return a list with running products of items in LIST. LIST must be
+ non-empty.
+
+ (-running-product '(1 2 3 4))
+ ⇒ (1 2 6 24)
+ (-running-product '(1))
+ ⇒ (1)
+ (-running-product ())
+ error→ Wrong type argument: consp, nil
+
+ -- Function: -inits (list)
+ Return all prefixes of LIST.
+
+ (-inits '(1 2 3 4))
+ ⇒ (nil (1) (1 2) (1 2 3) (1 2 3 4))
+ (-inits nil)
+ ⇒ (nil)
+ (-inits '(1))
+ ⇒ (nil (1))
+
+ -- Function: -tails (list)
+ Return all suffixes of LIST
+
+ (-tails '(1 2 3 4))
+ ⇒ ((1 2 3 4) (2 3 4) (3 4) (4) nil)
+ (-tails nil)
+ ⇒ (nil)
+ (-tails '(1))
+ ⇒ ((1) nil)
+
+ -- Function: -common-prefix (&rest lists)
+ Return the longest common prefix of LISTS.
+
+ (-common-prefix '(1))
+ ⇒ (1)
+ (-common-prefix '(1 2) '(3 4) '(1 2))
+ ⇒ ()
+ (-common-prefix '(1 2) '(1 2 3) '(1 2 3 4))
+ ⇒ (1 2)
+
+ -- Function: -common-suffix (&rest lists)
+ Return the longest common suffix of LISTS.
+
+ (-common-suffix '(1))
+ ⇒ (1)
+ (-common-suffix '(1 2) '(3 4) '(1 2))
+ ⇒ ()
+ (-common-suffix '(1 2 3 4) '(2 3 4) '(3 4))
+ ⇒ (3 4)
+
+ -- Function: -min (list)
+ Return the smallest value from LIST of numbers or markers.
+
+ (-min '(0))
+ ⇒ 0
+ (-min '(3 2 1))
+ ⇒ 1
+ (-min '(1 2 3))
+ ⇒ 1
+
+ -- Function: -min-by (comparator list)
+ Take a comparison function COMPARATOR and a LIST and return the
+ least element of the list by the comparison function.
+
+ See also combinator ‘-on’ (*note -on::) which can transform the
+ values before comparing them.
+
+ (-min-by '> '(4 3 6 1))
+ ⇒ 1
+ (--min-by (> (car it) (car other)) '((1 2 3) (2) (3 2)))
+ ⇒ (1 2 3)
+ (--min-by (> (length it) (length other)) '((1 2 3) (2) (3 2)))
+ ⇒ (2)
+
+ -- Function: -max (list)
+ Return the largest value from LIST of numbers or markers.
+
+ (-max '(0))
+ ⇒ 0
+ (-max '(3 2 1))
+ ⇒ 3
+ (-max '(1 2 3))
+ ⇒ 3
+
+ -- Function: -max-by (comparator list)
+ Take a comparison function COMPARATOR and a LIST and return the
+ greatest element of the list by the comparison function.
+
+ See also combinator ‘-on’ (*note -on::) which can transform the
+ values before comparing them.
+
+ (-max-by '> '(4 3 6 1))
+ ⇒ 6
+ (--max-by (> (car it) (car other)) '((1 2 3) (2) (3 2)))
+ ⇒ (3 2)
+ (--max-by (> (length it) (length other)) '((1 2 3) (2) (3 2)))
+ ⇒ (1 2 3)
+
+
+File: dash.info, Node: Unfolding, Next: Predicates, Prev: Reductions, Up: Functions
+
+2.5 Unfolding
+=============
+
+Operations dual to reductions, building lists from a seed value rather
+than consuming a list to produce a single value.
+
+ -- Function: -iterate (fun init n)
+ Return a list of iterated applications of FUN to INIT.
+
+ This means a list of the form:
+
+ (INIT (FUN INIT) (FUN (FUN INIT)) ...)
+
+ N is the length of the returned list.
+
+ (-iterate #'1+ 1 10)
+ ⇒ (1 2 3 4 5 6 7 8 9 10)
+ (-iterate (lambda (x) (+ x x)) 2 5)
+ ⇒ (2 4 8 16 32)
+ (--iterate (* it it) 2 5)
+ ⇒ (2 4 16 256 65536)
+
+ -- Function: -unfold (fun seed)
+ Build a list from SEED using FUN.
+
+ This is "dual" operation to ‘-reduce-r’ (*note -reduce-r::): while
+ -reduce-r consumes a list to produce a single value, ‘-unfold’
+ (*note -unfold::) takes a seed value and builds a (potentially
+ infinite!) list.
+
+ FUN should return ‘nil’ to stop the generating process, or a cons
+ (A . B), where A will be prepended to the result and B is the new
+ seed.
+
+ (-unfold (lambda (x) (unless (= x 0) (cons x (1- x)))) 10)
+ ⇒ (10 9 8 7 6 5 4 3 2 1)
+ (--unfold (when it (cons it (cdr it))) '(1 2 3 4))
+ ⇒ ((1 2 3 4) (2 3 4) (3 4) (4))
+ (--unfold (when it (cons it (butlast it))) '(1 2 3 4))
+ ⇒ ((1 2 3 4) (1 2 3) (1 2) (1))
+
+
+File: dash.info, Node: Predicates, Next: Partitioning, Prev: Unfolding, Up: Functions
+
+2.6 Predicates
+==============
+
+Reductions of one or more lists to a boolean value.
+
+ -- Function: -some (pred list)
+ Return (PRED x) for the first LIST item where (PRED x) is
+ non-‘nil’, else ‘nil’.
+
+ Alias: ‘-any’.
+
+ This function’s anaphoric counterpart is ‘--some’.
+
+ (-some #'stringp '(1 "2" 3))
+ ⇒ t
+ (--some (string-match-p "x" it) '("foo" "axe" "xor"))
+ ⇒ 1
+ (--some (= it-index 3) '(0 1 2))
+ ⇒ nil
+
+ -- Function: -every (pred list)
+ Return non-‘nil’ if PRED returns non-‘nil’ for all items in LIST.
+ If so, return the last such result of PRED. Otherwise, once an
+ item is reached for which PRED returns ‘nil’, return ‘nil’ without
+ calling PRED on any further LIST elements.
+
+ This function is like ‘-every-p’, but on success returns the last
+ non-‘nil’ result of PRED instead of just ‘t’.
+
+ This function’s anaphoric counterpart is ‘--every’.
+
+ (-every #'numberp '(1 2 3))
+ ⇒ t
+ (--every (string-match-p "x" it) '("axe" "xor"))
+ ⇒ 0
+ (--every (= it it-index) '(0 1 3))
+ ⇒ nil
+
+ -- Function: -any? (pred list)
+ Return ‘t’ if (PRED X) is non-‘nil’ for any X in LIST, else ‘nil’.
+
+ Alias: ‘-any-p’, ‘-some?’, ‘-some-p’
+
+ (-any? #'numberp '(nil 0 t))
+ ⇒ t
+ (-any? #'numberp '(nil t t))
+ ⇒ nil
+ (-any? #'null '(1 3 5))
+ ⇒ nil
+
+ -- Function: -all? (pred list)
+ Return ‘t’ if (PRED X) is non-‘nil’ for all X in LIST, else ‘nil’.
+ In the latter case, stop after the first X for which (PRED X) is
+ ‘nil’, without calling PRED on any subsequent elements of LIST.
+
+ The similar function ‘-every’ (*note -every::) is more widely
+ useful, since it returns the last non-‘nil’ result of PRED instead
+ of just ‘t’ on success.
+
+ Alias: ‘-all-p’, ‘-every-p’, ‘-every?’.
+
+ This function’s anaphoric counterpart is ‘--all?’.
+
+ (-all? #'numberp '(1 2 3))
+ ⇒ t
+ (-all? #'numberp '(2 t 6))
+ ⇒ nil
+ (--all? (= 0 (% it 2)) '(2 4 6))
+ ⇒ t
+
+ -- Function: -none? (pred list)
+ Return ‘t’ if (PRED X) is ‘nil’ for all X in LIST, else ‘nil’.
+
+ Alias: ‘-none-p’
+
+ (-none? 'even? '(1 2 3))
+ ⇒ nil
+ (-none? 'even? '(1 3 5))
+ ⇒ t
+ (--none? (= 0 (% it 2)) '(1 2 3))
+ ⇒ nil
+
+ -- Function: -only-some? (pred list)
+ Return ‘t’ if different LIST items both satisfy and do not satisfy
+ PRED. That is, if PRED returns both ‘nil’ for at least one item,
+ and non-‘nil’ for at least one other item in LIST. Return ‘nil’ if
+ all items satisfy the predicate or none of them do.
+
+ Alias: ‘-only-some-p’
+
+ (-only-some? 'even? '(1 2 3))
+ ⇒ t
+ (-only-some? 'even? '(1 3 5))
+ ⇒ nil
+ (-only-some? 'even? '(2 4 6))
+ ⇒ nil
+
+ -- Function: -contains? (list element)
+ Return non-‘nil’ if LIST contains ELEMENT.
+
+ The test for equality is done with ‘equal’, or with ‘-compare-fn’
+ if that’s non-‘nil’.
+
+ Alias: ‘-contains-p’
+
+ (-contains? '(1 2 3) 1)
+ ⇒ t
+ (-contains? '(1 2 3) 2)
+ ⇒ t
+ (-contains? '(1 2 3) 4)
+ ⇒ nil
+
+ -- Function: -same-items? (list list2)
+ Return true if LIST and LIST2 has the same items.
+
+ The order of the elements in the lists does not matter.
+
+ Alias: ‘-same-items-p’
+
+ (-same-items? '(1 2 3) '(1 2 3))
+ ⇒ t
+ (-same-items? '(1 2 3) '(3 2 1))
+ ⇒ t
+ (-same-items? '(1 2 3) '(1 2 3 4))
+ ⇒ nil
+
+ -- Function: -is-prefix? (prefix list)
+ Return non-‘nil’ if PREFIX is a prefix of LIST.
+
+ Alias: ‘-is-prefix-p’.
+
+ (-is-prefix? '(1 2 3) '(1 2 3 4 5))
+ ⇒ t
+ (-is-prefix? '(1 2 3 4 5) '(1 2 3))
+ ⇒ nil
+ (-is-prefix? '(1 3) '(1 2 3 4 5))
+ ⇒ nil
+
+ -- Function: -is-suffix? (suffix list)
+ Return non-‘nil’ if SUFFIX is a suffix of LIST.
+
+ Alias: ‘-is-suffix-p’.
+
+ (-is-suffix? '(3 4 5) '(1 2 3 4 5))
+ ⇒ t
+ (-is-suffix? '(1 2 3 4 5) '(3 4 5))
+ ⇒ nil
+ (-is-suffix? '(3 5) '(1 2 3 4 5))
+ ⇒ nil
+
+ -- Function: -is-infix? (infix list)
+ Return non-‘nil’ if INFIX is infix of LIST.
+
+ This operation runs in O(n^2) time
+
+ Alias: ‘-is-infix-p’
+
+ (-is-infix? '(1 2 3) '(1 2 3 4 5))
+ ⇒ t
+ (-is-infix? '(2 3 4) '(1 2 3 4 5))
+ ⇒ t
+ (-is-infix? '(3 4 5) '(1 2 3 4 5))
+ ⇒ t
+
+ -- Function: -cons-pair? (obj)
+ Return non-‘nil’ if OBJ is a true cons pair. That is, a cons (A .
+ B) where B is not a list.
+
+ Alias: ‘-cons-pair-p’.
+
+ (-cons-pair? '(1 . 2))
+ ⇒ t
+ (-cons-pair? '(1 2))
+ ⇒ nil
+ (-cons-pair? '(1))
+ ⇒ nil
+
+
+File: dash.info, Node: Partitioning, Next: Indexing, Prev: Predicates, Up: Functions
+
+2.7 Partitioning
+================
+
+Functions partitioning the input list into a list of lists.
+
+ -- Function: -split-at (n list)
+ Split LIST into two sublists after the Nth element. The result is
+ a list of two elements (TAKE DROP) where TAKE is a new list of the
+ first N elements of LIST, and DROP is the remaining elements of
+ LIST (not a copy). TAKE and DROP are like the results of ‘-take’
+ (*note -take::) and ‘-drop’ (*note -drop::), respectively, but the
+ split is done in a single list traversal.
+
+ (-split-at 3 '(1 2 3 4 5))
+ ⇒ ((1 2 3) (4 5))
+ (-split-at 17 '(1 2 3 4 5))
+ ⇒ ((1 2 3 4 5) nil)
+ (-split-at 0 '(1 2 3 4 5))
+ ⇒ (nil (1 2 3 4 5))
+
+ -- Function: -split-with (pred list)
+ Split LIST into a prefix satisfying PRED, and the rest. The first
+ sublist is the prefix of LIST with successive elements satisfying
+ PRED, and the second sublist is the remaining elements that do not.
+ The result is like performing
+
+ ((-take-while PRED LIST) (-drop-while PRED LIST))
+
+ but in no more than a single pass through LIST.
+
+ (-split-with 'even? '(1 2 3 4))
+ ⇒ (nil (1 2 3 4))
+ (-split-with 'even? '(2 4 5 6))
+ ⇒ ((2 4) (5 6))
+ (--split-with (< it 4) '(1 2 3 4 3 2 1))
+ ⇒ ((1 2 3) (4 3 2 1))
+
+ -- Macro: -split-on (item list)
+ Split the LIST each time ITEM is found.
+
+ Unlike ‘-partition-by’ (*note -partition-by::), the ITEM is
+ discarded from the results. Empty lists are also removed from the
+ result.
+
+ Comparison is done by ‘equal’.
+
+ See also ‘-split-when’ (*note -split-when::)
+
+ (-split-on '| '(Nil | Leaf a | Node [Tree a]))
+ ⇒ ((Nil) (Leaf a) (Node [Tree a]))
+ (-split-on :endgroup '("a" "b" :endgroup "c" :endgroup "d" "e"))
+ ⇒ (("a" "b") ("c") ("d" "e"))
+ (-split-on :endgroup '("a" "b" :endgroup :endgroup "d" "e"))
+ ⇒ (("a" "b") ("d" "e"))
+
+ -- Function: -split-when (fn list)
+ Split the LIST on each element where FN returns non-‘nil’.
+
+ Unlike ‘-partition-by’ (*note -partition-by::), the "matched"
+ element is discarded from the results. Empty lists are also
+ removed from the result.
+
+ This function can be thought of as a generalization of
+ ‘split-string’.
+
+ (-split-when 'even? '(1 2 3 4 5 6))
+ ⇒ ((1) (3) (5))
+ (-split-when 'even? '(1 2 3 4 6 8 9))
+ ⇒ ((1) (3) (9))
+ (--split-when (memq it '(&optional &rest)) '(a b &optional c d &rest args))
+ ⇒ ((a b) (c d) (args))
+
+ -- Function: -separate (pred list)
+ Split LIST into two sublists based on whether items satisfy PRED.
+ The result is like performing
+
+ ((-filter PRED LIST) (-remove PRED LIST))
+
+ but in a single pass through LIST.
+
+ (-separate (lambda (num) (= 0 (% num 2))) '(1 2 3 4 5 6 7))
+ ⇒ ((2 4 6) (1 3 5 7))
+ (--separate (< it 5) '(3 7 5 9 3 2 1 4 6))
+ ⇒ ((3 3 2 1 4) (7 5 9 6))
+ (-separate 'cdr '((1 2) (1) (1 2 3) (4)))
+ ⇒ (((1 2) (1 2 3)) ((1) (4)))
+
+ -- Function: -partition (n list)
+ Return a new list with the items in LIST grouped into N-sized
+ sublists. If there are not enough items to make the last group
+ N-sized, those items are discarded.
+
+ (-partition 2 '(1 2 3 4 5 6))
+ ⇒ ((1 2) (3 4) (5 6))
+ (-partition 2 '(1 2 3 4 5 6 7))
+ ⇒ ((1 2) (3 4) (5 6))
+ (-partition 3 '(1 2 3 4 5 6 7))
+ ⇒ ((1 2 3) (4 5 6))
+
+ -- Function: -partition-all (n list)
+ Return a new list with the items in LIST grouped into N-sized
+ sublists. The last group may contain less than N items.
+
+ (-partition-all 2 '(1 2 3 4 5 6))
+ ⇒ ((1 2) (3 4) (5 6))
+ (-partition-all 2 '(1 2 3 4 5 6 7))
+ ⇒ ((1 2) (3 4) (5 6) (7))
+ (-partition-all 3 '(1 2 3 4 5 6 7))
+ ⇒ ((1 2 3) (4 5 6) (7))
+
+ -- Function: -partition-in-steps (n step list)
+ Partition LIST into sublists of length N that are STEP items apart.
+ Like ‘-partition-all-in-steps’ (*note -partition-all-in-steps::),
+ but if there are not enough items to make the last group N-sized,
+ those items are discarded.
+
+ (-partition-in-steps 2 1 '(1 2 3 4))
+ ⇒ ((1 2) (2 3) (3 4))
+ (-partition-in-steps 3 2 '(1 2 3 4))
+ ⇒ ((1 2 3))
+ (-partition-in-steps 3 2 '(1 2 3 4 5))
+ ⇒ ((1 2 3) (3 4 5))
+
+ -- Function: -partition-all-in-steps (n step list)
+ Partition LIST into sublists of length N that are STEP items apart.
+ Adjacent groups may overlap if N exceeds the STEP stride. Trailing
+ groups may contain less than N items.
+
+ (-partition-all-in-steps 2 1 '(1 2 3 4))
+ ⇒ ((1 2) (2 3) (3 4) (4))
+ (-partition-all-in-steps 3 2 '(1 2 3 4))
+ ⇒ ((1 2 3) (3 4))
+ (-partition-all-in-steps 3 2 '(1 2 3 4 5))
+ ⇒ ((1 2 3) (3 4 5) (5))
+
+ -- Function: -partition-by (fn list)
+ Apply FN to each item in LIST, splitting it each time FN returns a
+ new value.
+
+ (-partition-by 'even? ())
+ ⇒ ()
+ (-partition-by 'even? '(1 1 2 2 2 3 4 6 8))
+ ⇒ ((1 1) (2 2 2) (3) (4 6 8))
+ (--partition-by (< it 3) '(1 2 3 4 3 2 1))
+ ⇒ ((1 2) (3 4 3) (2 1))
+
+ -- Function: -partition-by-header (fn list)
+ Apply FN to the first item in LIST. That is the header value.
+ Apply FN to each item in LIST, splitting it each time FN returns
+ the header value, but only after seeing at least one other value
+ (the body).
+
+ (--partition-by-header (= it 1) '(1 2 3 1 2 1 2 3 4))
+ ⇒ ((1 2 3) (1 2) (1 2 3 4))
+ (--partition-by-header (> it 0) '(1 2 0 1 0 1 2 3 0))
+ ⇒ ((1 2 0) (1 0) (1 2 3 0))
+ (-partition-by-header 'even? '(2 1 1 1 4 1 3 5 6 6 1))
+ ⇒ ((2 1 1 1) (4 1 3 5) (6 6 1))
+
+ -- Function: -partition-after-pred (pred list)
+ Partition LIST after each element for which PRED returns non-‘nil’.
+
+ This function’s anaphoric counterpart is ‘--partition-after-pred’.
+
+ (-partition-after-pred #'booleanp ())
+ ⇒ ()
+ (-partition-after-pred #'booleanp '(t t))
+ ⇒ ((t) (t))
+ (-partition-after-pred #'booleanp '(0 0 t t 0 t))
+ ⇒ ((0 0 t) (t) (0 t))
+
+ -- Function: -partition-before-pred (pred list)
+ Partition directly before each time PRED is true on an element of
+ LIST.
+
+ (-partition-before-pred #'booleanp ())
+ ⇒ ()
+ (-partition-before-pred #'booleanp '(0 t))
+ ⇒ ((0) (t))
+ (-partition-before-pred #'booleanp '(0 0 t 0 t t))
+ ⇒ ((0 0) (t 0) (t) (t))
+
+ -- Function: -partition-before-item (item list)
+ Partition directly before each time ITEM appears in LIST.
+
+ (-partition-before-item 3 ())
+ ⇒ ()
+ (-partition-before-item 3 '(1))
+ ⇒ ((1))
+ (-partition-before-item 3 '(3))
+ ⇒ ((3))
+
+ -- Function: -partition-after-item (item list)
+ Partition directly after each time ITEM appears in LIST.
+
+ (-partition-after-item 3 ())
+ ⇒ ()
+ (-partition-after-item 3 '(1))
+ ⇒ ((1))
+ (-partition-after-item 3 '(3))
+ ⇒ ((3))
+
+ -- Function: -group-by (fn list)
+ Separate LIST into an alist whose keys are FN applied to the
+ elements of LIST. Keys are compared by ‘equal’.
+
+ (-group-by 'even? ())
+ ⇒ ()
+ (-group-by 'even? '(1 1 2 2 2 3 4 6 8))
+ ⇒ ((nil 1 1 3) (t 2 2 2 4 6 8))
+ (--group-by (car (split-string it "/")) '("a/b" "c/d" "a/e"))
+ ⇒ (("a" "a/b" "a/e") ("c" "c/d"))
+
+
+File: dash.info, Node: Indexing, Next: Set operations, Prev: Partitioning, Up: Functions
+
+2.8 Indexing
+============
+
+Functions retrieving or sorting based on list indices and related
+predicates.
+
+ -- Function: -elem-index (elem list)
+ Return the index of the first element in the given LIST which is
+ equal to the query element ELEM, or ‘nil’ if there is no such
+ element.
+
+ (-elem-index 2 '(6 7 8 2 3 4))
+ ⇒ 3
+ (-elem-index "bar" '("foo" "bar" "baz"))
+ ⇒ 1
+ (-elem-index '(1 2) '((3) (5 6) (1 2) nil))
+ ⇒ 2
+
+ -- Function: -elem-indices (elem list)
+ Return the indices of all elements in LIST equal to the query
+ element ELEM, in ascending order.
+
+ (-elem-indices 2 '(6 7 8 2 3 4 2 1))
+ ⇒ (3 6)
+ (-elem-indices "bar" '("foo" "bar" "baz"))
+ ⇒ (1)
+ (-elem-indices '(1 2) '((3) (1 2) (5 6) (1 2) nil))
+ ⇒ (1 3)
+
+ -- Function: -find-index (pred list)
+ Take a predicate PRED and a LIST and return the index of the first
+ element in the list satisfying the predicate, or ‘nil’ if there is
+ no such element.
+
+ See also ‘-first’ (*note -first::).
+
+ (-find-index 'even? '(2 4 1 6 3 3 5 8))
+ ⇒ 0
+ (--find-index (< 5 it) '(2 4 1 6 3 3 5 8))
+ ⇒ 3
+ (-find-index (-partial 'string-lessp "baz") '("bar" "foo" "baz"))
+ ⇒ 1
+
+ -- Function: -find-last-index (pred list)
+ Take a predicate PRED and a LIST and return the index of the last
+ element in the list satisfying the predicate, or ‘nil’ if there is
+ no such element.
+
+ See also ‘-last’ (*note -last::).
+
+ (-find-last-index 'even? '(2 4 1 6 3 3 5 8))
+ ⇒ 7
+ (--find-last-index (< 5 it) '(2 7 1 6 3 8 5 2))
+ ⇒ 5
+ (-find-last-index (-partial 'string-lessp "baz") '("q" "foo" "baz"))
+ ⇒ 1
+
+ -- Function: -find-indices (pred list)
+ Return the indices of all elements in LIST satisfying the predicate
+ PRED, in ascending order.
+
+ (-find-indices 'even? '(2 4 1 6 3 3 5 8))
+ ⇒ (0 1 3 7)
+ (--find-indices (< 5 it) '(2 4 1 6 3 3 5 8))
+ ⇒ (3 7)
+ (-find-indices (-partial 'string-lessp "baz") '("bar" "foo" "baz"))
+ ⇒ (1)
+
+ -- Function: -grade-up (comparator list)
+ Grade elements of LIST using COMPARATOR relation. This yields a
+ permutation vector such that applying this permutation to LIST
+ sorts it in ascending order.
+
+ (-grade-up #'< '(3 1 4 2 1 3 3))
+ ⇒ (1 4 3 0 5 6 2)
+ (let ((l '(3 1 4 2 1 3 3))) (-select-by-indices (-grade-up #'< l) l))
+ ⇒ (1 1 2 3 3 3 4)
+
+ -- Function: -grade-down (comparator list)
+ Grade elements of LIST using COMPARATOR relation. This yields a
+ permutation vector such that applying this permutation to LIST
+ sorts it in descending order.
+
+ (-grade-down #'< '(3 1 4 2 1 3 3))
+ ⇒ (2 0 5 6 3 1 4)
+ (let ((l '(3 1 4 2 1 3 3))) (-select-by-indices (-grade-down #'< l) l))
+ ⇒ (4 3 3 3 2 1 1)
+
+
+File: dash.info, Node: Set operations, Next: Other list operations, Prev: Indexing, Up: Functions
+
+2.9 Set operations
+==================
+
+Operations pretending lists are sets.
+
+ -- Function: -union (list list2)
+ Return a new list of all elements appearing in either LIST1 or
+ LIST2. Equality is defined by the value of ‘-compare-fn’ if
+ non-‘nil’; otherwise ‘equal’.
+
+ (-union '(1 2 3) '(3 4 5))
+ ⇒ (1 2 3 4 5)
+ (-union '(1 2 3 4) ())
+ ⇒ (1 2 3 4)
+ (-union '(1 1 2 2) '(3 2 1))
+ ⇒ (1 1 2 2 3)
+
+ -- Function: -difference (list list2)
+ Return a new list with only the members of LIST that are not in
+ LIST2. The test for equality is done with ‘equal’, or with
+ ‘-compare-fn’ if that’s non-‘nil’.
+
+ (-difference () ())
+ ⇒ ()
+ (-difference '(1 2 3) '(4 5 6))
+ ⇒ (1 2 3)
+ (-difference '(1 2 3 4) '(3 4 5 6))
+ ⇒ (1 2)
+
+ -- Function: -intersection (list list2)
+ Return a new list of the elements appearing in both LIST1 and
+ LIST2. Equality is defined by the value of ‘-compare-fn’ if
+ non-‘nil’; otherwise ‘equal’.
+
+ (-intersection () ())
+ ⇒ ()
+ (-intersection '(1 2 3) '(4 5 6))
+ ⇒ ()
+ (-intersection '(1 2 3 4) '(3 4 5 6))
+ ⇒ (3 4)
+
+ -- Function: -powerset (list)
+ Return the power set of LIST.
+
+ (-powerset ())
+ ⇒ (nil)
+ (-powerset '(x y z))
+ ⇒ ((x y z) (x y) (x z) (x) (y z) (y) (z) nil)
+
+ -- Function: -permutations (list)
+ Return the permutations of LIST.
+
+ (-permutations ())
+ ⇒ (nil)
+ (-permutations '(1 2))
+ ⇒ ((1 2) (2 1))
+ (-permutations '(a b c))
+ ⇒ ((a b c) (a c b) (b a c) (b c a) (c a b) (c b a))
+
+ -- Function: -distinct (list)
+ Return a new list with all duplicates removed. The test for
+ equality is done with ‘equal’, or with ‘-compare-fn’ if that’s
+ non-‘nil’.
+
+ Alias: ‘-uniq’
+
+ (-distinct ())
+ ⇒ ()
+ (-distinct '(1 2 2 4))
+ ⇒ (1 2 4)
+ (-distinct '(t t t))
+ ⇒ (t)
+
+
+File: dash.info, Node: Other list operations, Next: Tree operations, Prev: Set operations, Up: Functions
+
+2.10 Other list operations
+==========================
+
+Other list functions not fit to be classified elsewhere.
+
+ -- Function: -rotate (n list)
+ Rotate LIST N places to the right (left if N is negative). The
+ time complexity is O(n).
+
+ (-rotate 3 '(1 2 3 4 5 6 7))
+ ⇒ (5 6 7 1 2 3 4)
+ (-rotate -3 '(1 2 3 4 5 6 7))
+ ⇒ (4 5 6 7 1 2 3)
+ (-rotate 16 '(1 2 3 4 5 6 7))
+ ⇒ (6 7 1 2 3 4 5)
+
+ -- Function: -repeat (n x)
+ Return a new list of length N with each element being X. Return
+ ‘nil’ if N is less than 1.
+
+ (-repeat 3 :a)
+ ⇒ (:a :a :a)
+ (-repeat 1 :a)
+ ⇒ (:a)
+ (-repeat 0 :a)
+ ⇒ nil
+
+ -- Function: -cons* (&rest args)
+ Make a new list from the elements of ARGS. The last 2 elements of
+ ARGS are used as the final cons of the result, so if the final
+ element of ARGS is not a list, the result is a dotted list. With
+ no ARGS, return ‘nil’.
+
+ (-cons* 1 2)
+ ⇒ (1 . 2)
+ (-cons* 1 2 3)
+ ⇒ (1 2 . 3)
+ (-cons* 1)
+ ⇒ 1
+
+ -- Function: -snoc (list elem &rest elements)
+ Append ELEM to the end of the list.
+
+ This is like ‘cons’, but operates on the end of list.
+
+ If any ELEMENTS are given, append them to the list as well.
+
+ (-snoc '(1 2 3) 4)
+ ⇒ (1 2 3 4)
+ (-snoc '(1 2 3) 4 5 6)
+ ⇒ (1 2 3 4 5 6)
+ (-snoc '(1 2 3) '(4 5 6))
+ ⇒ (1 2 3 (4 5 6))
+
+ -- Function: -interpose (sep list)
+ Return a new list of all elements in LIST separated by SEP.
+
+ (-interpose "-" ())
+ ⇒ ()
+ (-interpose "-" '("a"))
+ ⇒ ("a")
+ (-interpose "-" '("a" "b" "c"))
+ ⇒ ("a" "-" "b" "-" "c")
+
+ -- Function: -interleave (&rest lists)
+ Return a new list of the first item in each list, then the second
+ etc.
+
+ (-interleave '(1 2) '("a" "b"))
+ ⇒ (1 "a" 2 "b")
+ (-interleave '(1 2) '("a" "b") '("A" "B"))
+ ⇒ (1 "a" "A" 2 "b" "B")
+ (-interleave '(1 2 3) '("a" "b"))
+ ⇒ (1 "a" 2 "b")
+
+ -- Function: -iota (count &optional start step)
+ Return a list containing COUNT numbers. Starts from START and adds
+ STEP each time. The default START is zero, the default STEP is 1.
+ This function takes its name from the corresponding primitive in
+ the APL language.
+
+ (-iota 6)
+ ⇒ (0 1 2 3 4 5)
+ (-iota 4 2.5 -2)
+ ⇒ (2.5 0.5 -1.5 -3.5)
+ (-iota -1)
+ error→ Wrong type argument: natnump, -1
+
+ -- Function: -zip-with (fn list1 list2)
+ Zip the two lists LIST1 and LIST2 using a function FN. This
+ function is applied pairwise taking as first argument element of
+ LIST1 and as second argument element of LIST2 at corresponding
+ position.
+
+ The anaphoric form ‘--zip-with’ binds the elements from LIST1 as
+ symbol ‘it’, and the elements from LIST2 as symbol ‘other’.
+
+ (-zip-with '+ '(1 2 3) '(4 5 6))
+ ⇒ (5 7 9)
+ (-zip-with 'cons '(1 2 3) '(4 5 6))
+ ⇒ ((1 . 4) (2 . 5) (3 . 6))
+ (--zip-with (concat it " and " other) '("Batman" "Jekyll") '("Robin" "Hyde"))
+ ⇒ ("Batman and Robin" "Jekyll and Hyde")
+
+ -- Function: -zip (&rest lists)
+ Zip LISTS together. Group the head of each list, followed by the
+ second elements of each list, and so on. The lengths of the
+ returned groupings are equal to the length of the shortest input
+ list.
+
+ If two lists are provided as arguments, return the groupings as a
+ list of cons cells. Otherwise, return the groupings as a list of
+ lists.
+
+ Use ‘-zip-lists’ (*note -zip-lists::) if you need the return value
+ to always be a list of lists.
+
+ Alias: ‘-zip-pair’
+
+ See also: ‘-zip-lists’ (*note -zip-lists::)
+
+ (-zip '(1 2 3) '(4 5 6))
+ ⇒ ((1 . 4) (2 . 5) (3 . 6))
+ (-zip '(1 2 3) '(4 5 6 7))
+ ⇒ ((1 . 4) (2 . 5) (3 . 6))
+ (-zip '(1 2) '(3 4 5) '(6))
+ ⇒ ((1 3 6))
+
+ -- Function: -zip-lists (&rest lists)
+ Zip LISTS together. Group the head of each list, followed by the
+ second elements of each list, and so on. The lengths of the
+ returned groupings are equal to the length of the shortest input
+ list.
+
+ The return value is always list of lists, which is a difference
+ from ‘-zip-pair’ which returns a cons-cell in case two input lists
+ are provided.
+
+ See also: ‘-zip’ (*note -zip::)
+
+ (-zip-lists '(1 2 3) '(4 5 6))
+ ⇒ ((1 4) (2 5) (3 6))
+ (-zip-lists '(1 2 3) '(4 5 6 7))
+ ⇒ ((1 4) (2 5) (3 6))
+ (-zip-lists '(1 2) '(3 4 5) '(6))
+ ⇒ ((1 3 6))
+
+ -- Function: -zip-fill (fill-value &rest lists)
+ Zip LISTS, with FILL-VALUE padded onto the shorter lists. The
+ lengths of the returned groupings are equal to the length of the
+ longest input list.
+
+ (-zip-fill 0 '(1 2 3 4 5) '(6 7 8 9))
+ ⇒ ((1 . 6) (2 . 7) (3 . 8) (4 . 9) (5 . 0))
+
+ -- Function: -unzip (lists)
+ Unzip LISTS.
+
+ This works just like ‘-zip’ (*note -zip::) but takes a list of
+ lists instead of a variable number of arguments, such that
+
+ (-unzip (-zip L1 L2 L3 ...))
+
+ is identity (given that the lists are the same length).
+
+ Note in particular that calling this on a list of two lists will
+ return a list of cons-cells such that the above identity works.
+
+ See also: ‘-zip’ (*note -zip::)
+
+ (-unzip (-zip '(1 2 3) '(a b c) '("e" "f" "g")))
+ ⇒ ((1 2 3) (a b c) ("e" "f" "g"))
+ (-unzip '((1 2) (3 4) (5 6) (7 8) (9 10)))
+ ⇒ ((1 3 5 7 9) (2 4 6 8 10))
+ (-unzip '((1 2) (3 4)))
+ ⇒ ((1 . 3) (2 . 4))
+
+ -- Function: -cycle (list)
+ Return an infinite circular copy of LIST. The returned list cycles
+ through the elements of LIST and repeats from the beginning.
+
+ (-take 5 (-cycle '(1 2 3)))
+ ⇒ (1 2 3 1 2)
+ (-take 7 (-cycle '(1 "and" 3)))
+ ⇒ (1 "and" 3 1 "and" 3 1)
+ (-zip (-cycle '(1 2 3)) '(1 2))
+ ⇒ ((1 . 1) (2 . 2))
+
+ -- Function: -pad (fill-value &rest lists)
+ Appends FILL-VALUE to the end of each list in LISTS such that they
+ will all have the same length.
+
+ (-pad 0 ())
+ ⇒ (nil)
+ (-pad 0 '(1))
+ ⇒ ((1))
+ (-pad 0 '(1 2 3) '(4 5))
+ ⇒ ((1 2 3) (4 5 0))
+
+ -- Function: -table (fn &rest lists)
+ Compute outer product of LISTS using function FN.
+
+ The function FN should have the same arity as the number of
+ supplied lists.
+
+ The outer product is computed by applying fn to all possible
+ combinations created by taking one element from each list in order.
+ The dimension of the result is (length lists).
+
+ See also: ‘-table-flat’ (*note -table-flat::)
+
+ (-table '* '(1 2 3) '(1 2 3))
+ ⇒ ((1 2 3) (2 4 6) (3 6 9))
+ (-table (lambda (a b) (-sum (-zip-with '* a b))) '((1 2) (3 4)) '((1 3) (2 4)))
+ ⇒ ((7 15) (10 22))
+ (apply '-table 'list (-repeat 3 '(1 2)))
+ ⇒ ((((1 1 1) (2 1 1)) ((1 2 1) (2 2 1))) (((1 1 2) (2 1 2)) ((1 2 2) (2 2 2))))
+
+ -- Function: -table-flat (fn &rest lists)
+ Compute flat outer product of LISTS using function FN.
+
+ The function FN should have the same arity as the number of
+ supplied lists.
+
+ The outer product is computed by applying fn to all possible
+ combinations created by taking one element from each list in order.
+ The results are flattened, ignoring the tensor structure of the
+ result. This is equivalent to calling:
+
+ (-flatten-n (1- (length lists)) (apply ’-table fn lists))
+
+ but the implementation here is much more efficient.
+
+ See also: ‘-flatten-n’ (*note -flatten-n::), ‘-table’ (*note
+ -table::)
+
+ (-table-flat 'list '(1 2 3) '(a b c))
+ ⇒ ((1 a) (2 a) (3 a) (1 b) (2 b) (3 b) (1 c) (2 c) (3 c))
+ (-table-flat '* '(1 2 3) '(1 2 3))
+ ⇒ (1 2 3 2 4 6 3 6 9)
+ (apply '-table-flat 'list (-repeat 3 '(1 2)))
+ ⇒ ((1 1 1) (2 1 1) (1 2 1) (2 2 1) (1 1 2) (2 1 2) (1 2 2) (2 2 2))
+
+ -- Function: -first (pred list)
+ Return the first item in LIST for which PRED returns non-‘nil’.
+ Return ‘nil’ if no such element is found. To get the first item in
+ the list no questions asked, use ‘car’.
+
+ Alias: ‘-find’.
+
+ This function’s anaphoric counterpart is ‘--first’.
+
+ (-first #'natnump '(-1 0 1))
+ ⇒ 0
+ (-first #'null '(1 2 3))
+ ⇒ nil
+ (--first (> it 2) '(1 2 3))
+ ⇒ 3
+
+ -- Function: -last (pred list)
+ Return the last x in LIST where (PRED x) is non-‘nil’, else ‘nil’.
+
+ (-last 'even? '(1 2 3 4 5 6 3 3 3))
+ ⇒ 6
+ (-last 'even? '(1 3 7 5 9))
+ ⇒ nil
+ (--last (> (length it) 3) '("a" "looong" "word" "and" "short" "one"))
+ ⇒ "short"
+
+ -- Function: -first-item (list)
+ Return the first item of LIST, or ‘nil’ on an empty list.
+
+ See also: ‘-second-item’ (*note -second-item::), ‘-last-item’
+ (*note -last-item::).
+
+ (-first-item '(1 2 3))
+ ⇒ 1
+ (-first-item nil)
+ ⇒ nil
+ (let ((list (list 1 2 3))) (setf (-first-item list) 5) list)
+ ⇒ (5 2 3)
+
+ -- Function: -second-item (list)
+ Return the second item of LIST, or ‘nil’ if LIST is too short.
+
+ See also: ‘-third-item’ (*note -third-item::).
+
+ (-second-item '(1 2 3))
+ ⇒ 2
+ (-second-item nil)
+ ⇒ nil
+
+ -- Function: -third-item (list)
+ Return the third item of LIST, or ‘nil’ if LIST is too short.
+
+ See also: ‘-fourth-item’ (*note -fourth-item::).
+
+ (-third-item '(1 2 3))
+ ⇒ 3
+ (-third-item nil)
+ ⇒ nil
+
+ -- Function: -fourth-item (list)
+ Return the fourth item of LIST, or ‘nil’ if LIST is too short.
+
+ See also: ‘-fifth-item’ (*note -fifth-item::).
+
+ (-fourth-item '(1 2 3 4))
+ ⇒ 4
+ (-fourth-item nil)
+ ⇒ nil
+
+ -- Function: -fifth-item (list)
+ Return the fifth item of LIST, or ‘nil’ if LIST is too short.
+
+ See also: ‘-last-item’ (*note -last-item::).
+
+ (-fifth-item '(1 2 3 4 5))
+ ⇒ 5
+ (-fifth-item nil)
+ ⇒ nil
+
+ -- Function: -last-item (list)
+ Return the last item of LIST, or ‘nil’ on an empty list.
+
+ (-last-item '(1 2 3))
+ ⇒ 3
+ (-last-item nil)
+ ⇒ nil
+ (let ((list (list 1 2 3))) (setf (-last-item list) 5) list)
+ ⇒ (1 2 5)
+
+ -- Function: -butlast (list)
+ Return a list of all items in list except for the last.
+
+ (-butlast '(1 2 3))
+ ⇒ (1 2)
+ (-butlast '(1 2))
+ ⇒ (1)
+ (-butlast '(1))
+ ⇒ nil
+
+ -- Function: -sort (comparator list)
+ Sort LIST, stably, comparing elements using COMPARATOR. Return the
+ sorted list. LIST is NOT modified by side effects. COMPARATOR is
+ called with two elements of LIST, and should return non-‘nil’ if
+ the first element should sort before the second.
+
+ (-sort '< '(3 1 2))
+ ⇒ (1 2 3)
+ (-sort '> '(3 1 2))
+ ⇒ (3 2 1)
+ (--sort (< it other) '(3 1 2))
+ ⇒ (1 2 3)
+
+ -- Function: -list (arg)
+ Ensure ARG is a list. If ARG is already a list, return it as is
+ (not a copy). Otherwise, return a new list with ARG as its only
+ element.
+
+ Another supported calling convention is (-list &rest ARGS). In
+ this case, if ARG is not a list, a new list with all of ARGS as
+ elements is returned. This use is supported for backward
+ compatibility and is otherwise deprecated.
+
+ (-list 1)
+ ⇒ (1)
+ (-list ())
+ ⇒ ()
+ (-list '(1 2 3))
+ ⇒ (1 2 3)
+
+ -- Function: -fix (fn list)
+ Compute the (least) fixpoint of FN with initial input LIST.
+
+ FN is called at least once, results are compared with ‘equal’.
+
+ (-fix (lambda (l) (-non-nil (--mapcat (-split-at (/ (length it) 2) it) l))) '((1 2 3)))
+ ⇒ ((1) (2) (3))
+ (let ((l '((starwars scifi) (jedi starwars warrior)))) (--fix (-uniq (--mapcat (cons it (cdr (assq it l))) it)) '(jedi book)))
+ ⇒ (jedi starwars warrior scifi book)
+
+
+File: dash.info, Node: Tree operations, Next: Threading macros, Prev: Other list operations, Up: Functions
+
+2.11 Tree operations
+====================
+
+Functions pretending lists are trees.
+
+ -- Function: -tree-seq (branch children tree)
+ Return a sequence of the nodes in TREE, in depth-first search
+ order.
+
+ BRANCH is a predicate of one argument that returns non-‘nil’ if the
+ passed argument is a branch, that is, a node that can have
+ children.
+
+ CHILDREN is a function of one argument that returns the children of
+ the passed branch node.
+
+ Non-branch nodes are simply copied.
+
+ (-tree-seq 'listp 'identity '(1 (2 3) 4 (5 (6 7))))
+ ⇒ ((1 (2 3) 4 (5 (6 7))) 1 (2 3) 2 3 4 (5 (6 7)) 5 (6 7) 6 7)
+ (-tree-seq 'listp 'reverse '(1 (2 3) 4 (5 (6 7))))
+ ⇒ ((1 (2 3) 4 (5 (6 7))) (5 (6 7)) (6 7) 7 6 5 4 (2 3) 3 2 1)
+ (--tree-seq (vectorp it) (append it nil) [1 [2 3] 4 [5 [6 7]]])
+ ⇒ ([1 [2 3] 4 [5 [6 7]]] 1 [2 3] 2 3 4 [5 [6 7]] 5 [6 7] 6 7)
+
+ -- Function: -tree-map (fn tree)
+ Apply FN to each element of TREE while preserving the tree
+ structure.
+
+ (-tree-map '1+ '(1 (2 3) (4 (5 6) 7)))
+ ⇒ (2 (3 4) (5 (6 7) 8))
+ (-tree-map '(lambda (x) (cons x (expt 2 x))) '(1 (2 3) 4))
+ ⇒ ((1 . 2) ((2 . 4) (3 . 8)) (4 . 16))
+ (--tree-map (length it) '("<body>" ("<p>" "text" "</p>") "</body>"))
+ ⇒ (6 (3 4 4) 7)
+
+ -- Function: -tree-map-nodes (pred fun tree)
+ Call FUN on each node of TREE that satisfies PRED.
+
+ If PRED returns ‘nil’, continue descending down this node. If PRED
+ returns non-‘nil’, apply FUN to this node and do not descend
+ further.
+
+ (-tree-map-nodes 'vectorp (lambda (x) (-sum (append x nil))) '(1 [2 3] 4 (5 [6 7] 8)))
+ ⇒ (1 5 4 (5 13 8))
+ (-tree-map-nodes 'keywordp (lambda (x) (symbol-name x)) '(1 :foo 4 ((5 6 :bar) :baz 8)))
+ ⇒ (1 ":foo" 4 ((5 6 ":bar") ":baz" 8))
+ (--tree-map-nodes (eq (car-safe it) 'add-mode) (-concat it (list :mode 'emacs-lisp-mode)) '(with-mode emacs-lisp-mode (foo bar) (add-mode a b) (baz (add-mode c d))))
+ ⇒ (with-mode emacs-lisp-mode (foo bar) (add-mode a b :mode emacs-lisp-mode) (baz (add-mode c d :mode emacs-lisp-mode)))
+
+ -- Function: -tree-reduce (fn tree)
+ Use FN to reduce elements of list TREE. If elements of TREE are
+ lists themselves, apply the reduction recursively.
+
+ FN is first applied to first element of the list and second
+ element, then on this result and third element from the list etc.
+
+ See ‘-reduce-r’ (*note -reduce-r::) for how exactly are lists of
+ zero or one element handled.
+
+ (-tree-reduce '+ '(1 (2 3) (4 5)))
+ ⇒ 15
+ (-tree-reduce 'concat '("strings" (" on" " various") ((" levels"))))
+ ⇒ "strings on various levels"
+ (--tree-reduce (cond ((stringp it) (concat it " " acc)) (t (let ((sn (symbol-name it))) (concat "<" sn ">" acc "</" sn ">")))) '(body (p "some words") (div "more" (b "bold") "words")))
+ ⇒ "<body><p>some words</p> <div>more <b>bold</b> words</div></body>"
+
+ -- Function: -tree-reduce-from (fn init-value tree)
+ Use FN to reduce elements of list TREE. If elements of TREE are
+ lists themselves, apply the reduction recursively.
+
+ FN is first applied to INIT-VALUE and first element of the list,
+ then on this result and second element from the list etc.
+
+ The initial value is ignored on cons pairs as they always contain
+ two elements.
+
+ (-tree-reduce-from '+ 1 '(1 (1 1) ((1))))
+ ⇒ 8
+ (--tree-reduce-from (-concat acc (list it)) nil '(1 (2 3 (4 5)) (6 7)))
+ ⇒ ((7 6) ((5 4) 3 2) 1)
+
+ -- Function: -tree-mapreduce (fn folder tree)
+ Apply FN to each element of TREE, and make a list of the results.
+ If elements of TREE are lists themselves, apply FN recursively to
+ elements of these nested lists.
+
+ Then reduce the resulting lists using FOLDER and initial value
+ INIT-VALUE. See ‘-reduce-r-from’ (*note -reduce-r-from::).
+
+ This is the same as calling ‘-tree-reduce’ (*note -tree-reduce::)
+ after ‘-tree-map’ (*note -tree-map::) but is twice as fast as it
+ only traverse the structure once.
+
+ (-tree-mapreduce 'list 'append '(1 (2 (3 4) (5 6)) (7 (8 9))))
+ ⇒ (1 2 3 4 5 6 7 8 9)
+ (--tree-mapreduce 1 (+ it acc) '(1 (2 (4 9) (2 1)) (7 (4 3))))
+ ⇒ 9
+ (--tree-mapreduce 0 (max acc (1+ it)) '(1 (2 (4 9) (2 1)) (7 (4 3))))
+ ⇒ 3
+
+ -- Function: -tree-mapreduce-from (fn folder init-value tree)
+ Apply FN to each element of TREE, and make a list of the results.
+ If elements of TREE are lists themselves, apply FN recursively to
+ elements of these nested lists.
+
+ Then reduce the resulting lists using FOLDER and initial value
+ INIT-VALUE. See ‘-reduce-r-from’ (*note -reduce-r-from::).
+
+ This is the same as calling ‘-tree-reduce-from’ (*note
+ -tree-reduce-from::) after ‘-tree-map’ (*note -tree-map::) but is
+ twice as fast as it only traverse the structure once.
+
+ (-tree-mapreduce-from 'identity '* 1 '(1 (2 (3 4) (5 6)) (7 (8 9))))
+ ⇒ 362880
+ (--tree-mapreduce-from (+ it it) (cons it acc) nil '(1 (2 (4 9) (2 1)) (7 (4 3))))
+ ⇒ (2 (4 (8 18) (4 2)) (14 (8 6)))
+ (concat "{" (--tree-mapreduce-from (cond ((-cons-pair? it) (concat (symbol-name (car it)) " -> " (symbol-name (cdr it)))) (t (concat (symbol-name it) " : {"))) (concat it (unless (or (equal acc "}") (equal (substring it (1- (length it))) "{")) ", ") acc) "}" '((elisp-mode (foo (bar . booze)) (baz . qux)) (c-mode (foo . bla) (bum . bam)))))
+ ⇒ "{elisp-mode : {foo : {bar -> booze}, baz -> qux}, c-mode : {foo -> bla, bum -> bam}}"
+
+ -- Function: -clone (list)
+ Create a deep copy of LIST. The new list has the same elements and
+ structure but all cons are replaced with new ones. This is useful
+ when you need to clone a structure such as plist or alist.
+
+ (let* ((a '(1 2 3)) (b (-clone a))) (nreverse a) b)
+ ⇒ (1 2 3)
+
+
+File: dash.info, Node: Threading macros, Next: Binding, Prev: Tree operations, Up: Functions
+
+2.12 Threading macros
+=====================
+
+Macros that conditionally combine sequential forms for brevity or
+readability.
+
+ -- Macro: -> (x &optional form &rest more)
+ Thread the expr through the forms. Insert X as the second item in
+ the first form, making a list of it if it is not a list already.
+ If there are more forms, insert the first form as the second item
+ in second form, etc.
+
+ (-> '(2 3 5))
+ ⇒ (2 3 5)
+ (-> '(2 3 5) (append '(8 13)))
+ ⇒ (2 3 5 8 13)
+ (-> '(2 3 5) (append '(8 13)) (-slice 1 -1))
+ ⇒ (3 5 8)
+
+ -- Macro: ->> (x &optional form &rest more)
+ Thread the expr through the forms. Insert X as the last item in
+ the first form, making a list of it if it is not a list already.
+ If there are more forms, insert the first form as the last item in
+ second form, etc.
+
+ (->> '(1 2 3) (-map 'square))
+ ⇒ (1 4 9)
+ (->> '(1 2 3) (-map 'square) (-remove 'even?))
+ ⇒ (1 9)
+ (->> '(1 2 3) (-map 'square) (-reduce '+))
+ ⇒ 14
+
+ -- Macro: --> (x &rest forms)
+ Starting with the value of X, thread each expression through FORMS.
+
+ Insert X at the position signified by the symbol ‘it’ in the first
+ form. If there are more forms, insert the first form at the
+ position signified by ‘it’ in in second form, etc.
+
+ (--> "def" (concat "abc" it "ghi"))
+ ⇒ "abcdefghi"
+ (--> "def" (concat "abc" it "ghi") (upcase it))
+ ⇒ "ABCDEFGHI"
+ (--> "def" (concat "abc" it "ghi") upcase)
+ ⇒ "ABCDEFGHI"
+
+ -- Macro: -as-> (value variable &rest forms)
+ Starting with VALUE, thread VARIABLE through FORMS.
+
+ In the first form, bind VARIABLE to VALUE. In the second form,
+ bind VARIABLE to the result of the first form, and so forth.
+
+ (-as-> 3 my-var (1+ my-var) (list my-var) (mapcar (lambda (ele) (* 2 ele)) my-var))
+ ⇒ (8)
+ (-as-> 3 my-var 1+)
+ ⇒ 4
+ (-as-> 3 my-var)
+ ⇒ 3
+
+ -- Macro: -some-> (x &optional form &rest more)
+ When expr is non-‘nil’, thread it through the first form (via ‘->’
+ (*note ->::)), and when that result is non-‘nil’, through the next
+ form, etc.
+
+ (-some-> '(2 3 5))
+ ⇒ (2 3 5)
+ (-some-> 5 square)
+ ⇒ 25
+ (-some-> 5 even? square)
+ ⇒ nil
+
+ -- Macro: -some->> (x &optional form &rest more)
+ When expr is non-‘nil’, thread it through the first form (via ‘->>’
+ (*note ->>::)), and when that result is non-‘nil’, through the next
+ form, etc.
+
+ (-some->> '(1 2 3) (-map 'square))
+ ⇒ (1 4 9)
+ (-some->> '(1 3 5) (-last 'even?) (+ 100))
+ ⇒ nil
+ (-some->> '(2 4 6) (-last 'even?) (+ 100))
+ ⇒ 106
+
+ -- Macro: -some--> (expr &rest forms)
+ Thread EXPR through FORMS via ‘-->’ (*note -->::), while the result
+ is non-‘nil’. When EXPR evaluates to non-‘nil’, thread the result
+ through the first of FORMS, and when that result is non-‘nil’,
+ thread it through the next form, etc.
+
+ (-some--> "def" (concat "abc" it "ghi"))
+ ⇒ "abcdefghi"
+ (-some--> nil (concat "abc" it "ghi"))
+ ⇒ nil
+ (-some--> '(0 1) (-remove #'natnump it) (append it it) (-map #'1+ it))
+ ⇒ ()
+
+ -- Macro: -doto (init &rest forms)
+ Evaluate INIT and pass it as argument to FORMS with ‘->’ (*note
+ ->::). The RESULT of evaluating INIT is threaded through each of
+ FORMS individually using ‘->’ (*note ->::), which see. The return
+ value is RESULT, which FORMS may have modified by side effect.
+
+ (-doto (list 1 2 3) pop pop)
+ ⇒ (3)
+ (-doto (cons 1 2) (setcar 3) (setcdr 4))
+ ⇒ (3 . 4)
+ (gethash 'k (--doto (make-hash-table) (puthash 'k 'v it)))
+ ⇒ v
+
+
+File: dash.info, Node: Binding, Next: Side effects, Prev: Threading macros, Up: Functions
+
+2.13 Binding
+============
+
+Macros that combine ‘let’ and ‘let*’ with destructuring and flow
+control.
+
+ -- Macro: -when-let ((var val) &rest body)
+ If VAL evaluates to non-‘nil’, bind it to VAR and execute body.
+
+ Note: binding is done according to ‘-let’ (*note -let::).
+
+ (-when-let (match-index (string-match "d" "abcd")) (+ match-index 2))
+ ⇒ 5
+ (-when-let ((&plist :foo foo) (list :foo "foo")) foo)
+ ⇒ "foo"
+ (-when-let ((&plist :foo foo) (list :bar "bar")) foo)
+ ⇒ nil
+
+ -- Macro: -when-let* (vars-vals &rest body)
+ If all VALS evaluate to true, bind them to their corresponding VARS
+ and execute body. VARS-VALS should be a list of (VAR VAL) pairs.
+
+ Note: binding is done according to ‘-let*’ (*note -let*::). VALS
+ are evaluated sequentially, and evaluation stops after the first
+ ‘nil’ VAL is encountered.
+
+ (-when-let* ((x 5) (y 3) (z (+ y 4))) (+ x y z))
+ ⇒ 15
+ (-when-let* ((x 5) (y nil) (z 7)) (+ x y z))
+ ⇒ nil
+
+ -- Macro: -if-let ((var val) then &rest else)
+ If VAL evaluates to non-‘nil’, bind it to VAR and do THEN,
+ otherwise do ELSE.
+
+ Note: binding is done according to ‘-let’ (*note -let::).
+
+ (-if-let (match-index (string-match "d" "abc")) (+ match-index 3) 7)
+ ⇒ 7
+ (--if-let (even? 4) it nil)
+ ⇒ t
+
+ -- Macro: -if-let* (vars-vals then &rest else)
+ If all VALS evaluate to true, bind them to their corresponding VARS
+ and do THEN, otherwise do ELSE. VARS-VALS should be a list of (VAR
+ VAL) pairs.
+
+ Note: binding is done according to ‘-let*’ (*note -let*::). VALS
+ are evaluated sequentially, and evaluation stops after the first
+ ‘nil’ VAL is encountered.
+
+ (-if-let* ((x 5) (y 3) (z 7)) (+ x y z) "foo")
+ ⇒ 15
+ (-if-let* ((x 5) (y nil) (z 7)) (+ x y z) "foo")
+ ⇒ "foo"
+ (-if-let* (((_ _ x) '(nil nil 7))) x)
+ ⇒ 7
+
+ -- Macro: -let (varlist &rest body)
+ Bind variables according to VARLIST then eval BODY.
+
+ VARLIST is a list of lists of the form (PATTERN SOURCE). Each
+ PATTERN is matched against the SOURCE "structurally". SOURCE is
+ only evaluated once for each PATTERN. Each PATTERN is matched
+ recursively, and can therefore contain sub-patterns which are
+ matched against corresponding sub-expressions of SOURCE.
+
+ All the SOURCEs are evalled before any symbols are bound (i.e. "in
+ parallel").
+
+ If VARLIST only contains one (PATTERN SOURCE) element, you can
+ optionally specify it using a vector and discarding the outer-most
+ parens. Thus
+
+ (-let ((PATTERN SOURCE)) ...)
+
+ becomes
+
+ (-let [PATTERN SOURCE] ...).
+
+ ‘-let’ (*note -let::) uses a convention of not binding places
+ (symbols) starting with _ whenever it’s possible. You can use this
+ to skip over entries you don’t care about. However, this is not
+ *always* possible (as a result of implementation) and these symbols
+ might get bound to undefined values.
+
+ Following is the overview of supported patterns. Remember that
+ patterns can be matched recursively, so every a, b, aK in the
+ following can be a matching construct and not necessarily a
+ symbol/variable.
+
+ Symbol:
+
+ a - bind the SOURCE to A. This is just like regular ‘let’.
+
+ Conses and lists:
+
+ (a) - bind ‘car’ of cons/list to A
+
+ (a . b) - bind car of cons to A and ‘cdr’ to B
+
+ (a b) - bind car of list to A and ‘cadr’ to B
+
+ (a1 a2 a3 ...) - bind 0th car of list to A1, 1st to A2, 2nd to
+ A3...
+
+ (a1 a2 a3 ... aN . rest) - as above, but bind the Nth cdr to REST.
+
+ Vectors:
+
+ [a] - bind 0th element of a non-list sequence to A (works with
+ vectors, strings, bit arrays...)
+
+ [a1 a2 a3 ...] - bind 0th element of non-list sequence to A0, 1st
+ to A1, 2nd to A2, ... If the PATTERN is shorter than SOURCE, the
+ values at places not in PATTERN are ignored. If the PATTERN is
+ longer than SOURCE, an ‘error’ is thrown.
+
+ [a1 a2 a3 ... &rest rest] - as above, but bind the rest of the
+ sequence to REST. This is conceptually the same as improper list
+ matching (a1 a2 ... aN . rest)
+
+ Key/value stores:
+
+ (&plist key0 a0 ... keyN aN) - bind value mapped by keyK in the
+ SOURCE plist to aK. If the value is not found, aK is ‘nil’. Uses
+ ‘plist-get’ to fetch values.
+
+ (&alist key0 a0 ... keyN aN) - bind value mapped by keyK in the
+ SOURCE alist to aK. If the value is not found, aK is ‘nil’. Uses
+ ‘assoc’ to fetch values.
+
+ (&hash key0 a0 ... keyN aN) - bind value mapped by keyK in the
+ SOURCE hash table to aK. If the value is not found, aK is ‘nil’.
+ Uses ‘gethash’ to fetch values.
+
+ Further, special keyword &keys supports "inline" matching of
+ plist-like key-value pairs, similarly to &keys keyword of
+ ‘cl-defun’.
+
+ (a1 a2 ... aN &keys key1 b1 ... keyN bK)
+
+ This binds N values from the list to a1 ... aN, then interprets the
+ cdr as a plist (see key/value matching above).
+
+ A shorthand notation for kv-destructuring exists which allows the
+ patterns be optionally left out and derived from the key name in
+ the following fashion:
+
+ - a key :foo is converted into ‘foo’ pattern, - a key ’bar is
+ converted into ‘bar’ pattern, - a key "baz" is converted into ‘baz’
+ pattern.
+
+ That is, the entire value under the key is bound to the derived
+ variable without any further destructuring.
+
+ This is possible only when the form following the key is not a
+ valid pattern (i.e. not a symbol, a cons cell or a vector).
+ Otherwise the matching proceeds as usual and in case of an invalid
+ spec fails with an error.
+
+ Thus the patterns are normalized as follows:
+
+ ;; derive all the missing patterns (&plist :foo ’bar "baz") =>
+ (&plist :foo foo ’bar bar "baz" baz)
+
+ ;; we can specify some but not others (&plist :foo ’bar
+ explicit-bar) => (&plist :foo foo ’bar explicit-bar)
+
+ ;; nothing happens, we store :foo in x (&plist :foo x) => (&plist
+ :foo x)
+
+ ;; nothing happens, we match recursively (&plist :foo (a b c)) =>
+ (&plist :foo (a b c))
+
+ You can name the source using the syntax SYMBOL &as PATTERN. This
+ syntax works with lists (proper or improper), vectors and all types
+ of maps.
+
+ (list &as a b c) (list 1 2 3)
+
+ binds A to 1, B to 2, C to 3 and LIST to (1 2 3).
+
+ Similarly:
+
+ (bounds &as beg . end) (cons 1 2)
+
+ binds BEG to 1, END to 2 and BOUNDS to (1 . 2).
+
+ (items &as first . rest) (list 1 2 3)
+
+ binds FIRST to 1, REST to (2 3) and ITEMS to (1 2 3)
+
+ [vect &as _ b c] [1 2 3]
+
+ binds B to 2, C to 3 and VECT to [1 2 3] (_ avoids binding as
+ usual).
+
+ (plist &as &plist :b b) (list :a 1 :b 2 :c 3)
+
+ binds B to 2 and PLIST to (:a 1 :b 2 :c 3). Same for &alist and
+ &hash.
+
+ This is especially useful when we want to capture the result of a
+ computation and destructure at the same time. Consider the form
+ (function-returning-complex-structure) returning a list of two
+ vectors with two items each. We want to capture this entire result
+ and pass it to another computation, but at the same time we want to
+ get the second item from each vector. We can achieve it with
+ pattern
+
+ (result &as [_ a] [_ b]) (function-returning-complex-structure)
+
+ Note: Clojure programmers may know this feature as the ":as
+ binding". The difference is that we put the &as at the front
+ because we need to support improper list binding.
+
+ (-let (([a (b c) d] [1 (2 3) 4])) (list a b c d))
+ ⇒ (1 2 3 4)
+ (-let [(a b c . d) (list 1 2 3 4 5 6)] (list a b c d))
+ ⇒ (1 2 3 (4 5 6))
+ (-let [(&plist :foo foo :bar bar) (list :baz 3 :foo 1 :qux 4 :bar 2)] (list foo bar))
+ ⇒ (1 2)
+
+ -- Macro: -let* (varlist &rest body)
+ Bind variables according to VARLIST then eval BODY.
+
+ VARLIST is a list of lists of the form (PATTERN SOURCE). Each
+ PATTERN is matched against the SOURCE structurally. SOURCE is only
+ evaluated once for each PATTERN.
+
+ Each SOURCE can refer to the symbols already bound by this VARLIST.
+ This is useful if you want to destructure SOURCE recursively but
+ also want to name the intermediate structures.
+
+ See ‘-let’ (*note -let::) for the list of all possible patterns.
+
+ (-let* (((a . b) (cons 1 2)) ((c . d) (cons 3 4))) (list a b c d))
+ ⇒ (1 2 3 4)
+ (-let* (((a . b) (cons 1 (cons 2 3))) ((c . d) b)) (list a b c d))
+ ⇒ (1 (2 . 3) 2 3)
+ (-let* (((&alist "foo" foo "bar" bar) (list (cons "foo" 1) (cons "bar" (list 'a 'b 'c)))) ((a b c) bar)) (list foo a b c bar))
+ ⇒ (1 a b c (a b c))
+
+ -- Macro: -lambda (match-form &rest body)
+ Return a lambda which destructures its input as MATCH-FORM and
+ executes BODY.
+
+ Note that you have to enclose the MATCH-FORM in a pair of parens,
+ such that:
+
+ (-lambda (x) body) (-lambda (x y ...) body)
+
+ has the usual semantics of ‘lambda’. Furthermore, these get
+ translated into normal ‘lambda’, so there is no performance
+ penalty.
+
+ See ‘-let’ (*note -let::) for a description of the destructuring
+ mechanism.
+
+ (-map (-lambda ((x y)) (+ x y)) '((1 2) (3 4) (5 6)))
+ ⇒ (3 7 11)
+ (-map (-lambda ([x y]) (+ x y)) '([1 2] [3 4] [5 6]))
+ ⇒ (3 7 11)
+ (funcall (-lambda ((_ . a) (_ . b)) (-concat a b)) '(1 2 3) '(4 5 6))
+ ⇒ (2 3 5 6)
+
+ -- Macro: -setq ([match-form val] ...)
+ Bind each MATCH-FORM to the value of its VAL.
+
+ MATCH-FORM destructuring is done according to the rules of ‘-let’
+ (*note -let::).
+
+ This macro allows you to bind multiple variables by destructuring
+ the value, so for example:
+
+ (-setq (a b) x (&plist :c c) plist)
+
+ expands roughly speaking to the following code
+
+ (setq a (car x) b (cadr x) c (plist-get plist :c))
+
+ Care is taken to only evaluate each VAL once so that in case of
+ multiple assignments it does not cause unexpected side effects.
+
+ (let (a) (-setq a 1) a)
+ ⇒ 1
+ (let (a b) (-setq (a b) (list 1 2)) (list a b))
+ ⇒ (1 2)
+ (let (c) (-setq (&plist :c c) (list :c "c")) c)
+ ⇒ "c"
+
+
+File: dash.info, Node: Side effects, Next: Destructive operations, Prev: Binding, Up: Functions
+
+2.14 Side effects
+=================
+
+Functions iterating over lists for side effect only.
+
+ -- Function: -each (list fn)
+ Call FN on each element of LIST. Return ‘nil’; this function is
+ intended for side effects.
+
+ Its anaphoric counterpart is ‘--each’.
+
+ For access to the current element’s index in LIST, see
+ ‘-each-indexed’ (*note -each-indexed::).
+
+ (let (l) (-each '(1 2 3) (lambda (x) (push x l))) l)
+ ⇒ (3 2 1)
+ (let (l) (--each '(1 2 3) (push it l)) l)
+ ⇒ (3 2 1)
+ (-each '(1 2 3) #'identity)
+ ⇒ nil
+
+ -- Function: -each-while (list pred fn)
+ Call FN on each ITEM in LIST, while (PRED ITEM) is non-‘nil’. Once
+ an ITEM is reached for which PRED returns ‘nil’, FN is no longer
+ called. Return ‘nil’; this function is intended for side effects.
+
+ Its anaphoric counterpart is ‘--each-while’.
+
+ (let (l) (-each-while '(2 4 5 6) #'even? (lambda (x) (push x l))) l)
+ ⇒ (4 2)
+ (let (l) (--each-while '(1 2 3 4) (< it 3) (push it l)) l)
+ ⇒ (2 1)
+ (let ((s 0)) (--each-while '(1 3 4 5) (< it 5) (setq s (+ s it))) s)
+ ⇒ 8
+
+ -- Function: -each-indexed (list fn)
+ Call FN on each index and element of LIST. For each ITEM at INDEX
+ in LIST, call (funcall FN INDEX ITEM). Return ‘nil’; this function
+ is intended for side effects.
+
+ See also: ‘-map-indexed’ (*note -map-indexed::).
+
+ (let (l) (-each-indexed '(a b c) (lambda (i x) (push (list x i) l))) l)
+ ⇒ ((c 2) (b 1) (a 0))
+ (let (l) (--each-indexed '(a b c) (push (list it it-index) l)) l)
+ ⇒ ((c 2) (b 1) (a 0))
+ (let (l) (--each-indexed () (push it l)) l)
+ ⇒ ()
+
+ -- Function: -each-r (list fn)
+ Call FN on each element of LIST in reversed order. Return ‘nil’;
+ this function is intended for side effects.
+
+ Its anaphoric counterpart is ‘--each-r’.
+
+ (let (l) (-each-r '(1 2 3) (lambda (x) (push x l))) l)
+ ⇒ (1 2 3)
+ (let (l) (--each-r '(1 2 3) (push it l)) l)
+ ⇒ (1 2 3)
+ (-each-r '(1 2 3) #'identity)
+ ⇒ nil
+
+ -- Function: -each-r-while (list pred fn)
+ Call FN on each ITEM in reversed LIST, while (PRED ITEM) is
+ non-‘nil’. Once an ITEM is reached for which PRED returns ‘nil’,
+ FN is no longer called. Return ‘nil’; this function is intended
+ for side effects.
+
+ Its anaphoric counterpart is ‘--each-r-while’.
+
+ (let (l) (-each-r-while '(2 4 5 6) #'even? (lambda (x) (push x l))) l)
+ ⇒ (6)
+ (let (l) (--each-r-while '(1 2 3 4) (>= it 3) (push it l)) l)
+ ⇒ (3 4)
+ (let ((s 0)) (--each-r-while '(1 2 3 5) (> it 1) (setq s (+ s it))) s)
+ ⇒ 10
+
+ -- Function: -dotimes (num fn)
+ Call FN NUM times, presumably for side effects. FN is called with
+ a single argument on successive integers running from 0, inclusive,
+ to NUM, exclusive. FN is not called if NUM is less than 1.
+
+ This function’s anaphoric counterpart is ‘--dotimes’.
+
+ (let (s) (-dotimes 3 (lambda (n) (push n s))) s)
+ ⇒ (2 1 0)
+ (let (s) (-dotimes 0 (lambda (n) (push n s))) s)
+ ⇒ ()
+ (let (s) (--dotimes 5 (push it s)) s)
+ ⇒ (4 3 2 1 0)
+
+
+File: dash.info, Node: Destructive operations, Next: Function combinators, Prev: Side effects, Up: Functions
+
+2.15 Destructive operations
+===========================
+
+Macros that modify variables holding lists.
+
+ -- Macro: !cons (car cdr)
+ Destructive: Set CDR to the cons of CAR and CDR.
+
+ (let (l) (!cons 5 l) l)
+ ⇒ (5)
+ (let ((l '(3))) (!cons 5 l) l)
+ ⇒ (5 3)
+
+ -- Macro: !cdr (list)
+ Destructive: Set LIST to the cdr of LIST.
+
+ (let ((l '(3))) (!cdr l) l)
+ ⇒ ()
+ (let ((l '(3 5))) (!cdr l) l)
+ ⇒ (5)
+
+
+File: dash.info, Node: Function combinators, Prev: Destructive operations, Up: Functions
+
+2.16 Function combinators
+=========================
+
+Functions that manipulate and compose other functions.
+
+ -- Function: -partial (fun &rest args)
+ Return a function that is a partial application of FUN to ARGS.
+ ARGS is a list of the first N arguments to pass to FUN. The result
+ is a new function which does the same as FUN, except that the first
+ N arguments are fixed at the values with which this function was
+ called.
+
+ (funcall (-partial #'+ 5))
+ ⇒ 5
+ (funcall (-partial #'- 5) 3)
+ ⇒ 2
+ (funcall (-partial #'+ 5 2) 3)
+ ⇒ 10
+
+ -- Function: -rpartial (fn &rest args)
+ Return a function that is a partial application of FN to ARGS.
+ ARGS is a list of the last N arguments to pass to FN. The result
+ is a new function which does the same as FN, except that the last N
+ arguments are fixed at the values with which this function was
+ called. This is like ‘-partial’ (*note -partial::), except the
+ arguments are fixed starting from the right rather than the left.
+
+ (funcall (-rpartial #'- 5))
+ ⇒ -5
+ (funcall (-rpartial #'- 5) 8)
+ ⇒ 3
+ (funcall (-rpartial #'- 5 2) 10)
+ ⇒ 3
+
+ -- Function: -juxt (&rest fns)
+ Return a function that is the juxtaposition of FNS. The returned
+ function takes a variable number of ARGS, applies each of FNS in
+ turn to ARGS, and returns the list of results.
+
+ (funcall (-juxt) 1 2)
+ ⇒ ()
+ (funcall (-juxt #'+ #'- #'* #'/) 7 5)
+ ⇒ (12 2 35 1)
+ (mapcar (-juxt #'number-to-string #'1+) '(1 2))
+ ⇒ (("1" 2) ("2" 3))
+
+ -- Function: -compose (&rest fns)
+ Compose FNS into a single composite function. Return a function
+ that takes a variable number of ARGS, applies the last function in
+ FNS to ARGS, and returns the result of calling each remaining
+ function on the result of the previous function, right-to-left. If
+ no FNS are given, return a variadic ‘identity’ function.
+
+ (funcall (-compose #'- #'1+ #'+) 1 2 3)
+ ⇒ -7
+ (funcall (-compose #'identity #'1+) 3)
+ ⇒ 4
+ (mapcar (-compose #'not #'stringp) '(nil ""))
+ ⇒ (t nil)
+
+ -- Function: -applify (fn)
+ Return a function that applies FN to a single list of args. This
+ changes the arity of FN from taking N distinct arguments to taking
+ 1 argument which is a list of N arguments.
+
+ (funcall (-applify #'+) nil)
+ ⇒ 0
+ (mapcar (-applify #'+) '((1 1 1) (1 2 3) (5 5 5)))
+ ⇒ (3 6 15)
+ (funcall (-applify #'<) '(3 6))
+ ⇒ t
+
+ -- Function: -on (op trans)
+ Return a function that calls TRANS on each arg and OP on the
+ results. The returned function takes a variable number of
+ arguments, calls the function TRANS on each one in turn, and then
+ passes those results as the list of arguments to OP, in the same
+ order.
+
+ For example, the following pairs of expressions are morally
+ equivalent:
+
+ (funcall (-on #’+ #’1+) 1 2 3) = (+ (1+ 1) (1+ 2) (1+ 3)) (funcall
+ (-on #’+ #’1+)) = (+)
+
+ (-sort (-on #'< #'length) '((1 2 3) (1) (1 2)))
+ ⇒ ((1) (1 2) (1 2 3))
+ (funcall (-on #'min #'string-to-number) "22" "2" "1" "12")
+ ⇒ 1
+ (-min-by (-on #'> #'length) '((1 2 3) (4) (1 2)))
+ ⇒ (4)
+
+ -- Function: -flip (fn)
+ Return a function that calls FN with its arguments reversed. The
+ returned function takes the same number of arguments as FN.
+
+ For example, the following two expressions are morally equivalent:
+
+ (funcall (-flip #’-) 1 2) = (- 2 1)
+
+ See also: ‘-rotate-args’ (*note -rotate-args::).
+
+ (-sort (-flip #'<) '(4 3 6 1))
+ ⇒ (6 4 3 1)
+ (funcall (-flip #'-) 3 2 1 10)
+ ⇒ 4
+ (funcall (-flip #'1+) 1)
+ ⇒ 2
+
+ -- Function: -rotate-args (n fn)
+ Return a function that calls FN with args rotated N places to the
+ right. The returned function takes the same number of arguments as
+ FN, rotates the list of arguments N places to the right (left if N
+ is negative) just like ‘-rotate’ (*note -rotate::), and applies FN
+ to the result.
+
+ See also: ‘-flip’ (*note -flip::).
+
+ (funcall (-rotate-args -1 #'list) 1 2 3 4)
+ ⇒ (2 3 4 1)
+ (funcall (-rotate-args 1 #'-) 1 10 100)
+ ⇒ 89
+ (funcall (-rotate-args 2 #'list) 3 4 5 1 2)
+ ⇒ (1 2 3 4 5)
+
+ -- Function: -const (c)
+ Return a function that returns C ignoring any additional arguments.
+
+ In types: a -> b -> a
+
+ (funcall (-const 2) 1 3 "foo")
+ ⇒ 2
+ (mapcar (-const 1) '("a" "b" "c" "d"))
+ ⇒ (1 1 1 1)
+ (-sum (mapcar (-const 1) '("a" "b" "c" "d")))
+ ⇒ 4
+
+ -- Macro: -cut (&rest params)
+ Take n-ary function and n arguments and specialize some of them.
+ Arguments denoted by <> will be left unspecialized.
+
+ See SRFI-26 for detailed description.
+
+ (funcall (-cut list 1 <> 3 <> 5) 2 4)
+ ⇒ (1 2 3 4 5)
+ (-map (-cut funcall <> 5) `(1+ 1- ,(lambda (x) (/ 1.0 x))))
+ ⇒ (6 4 0.2)
+ (-map (-cut <> 1 2 3) '(list vector string))
+ ⇒ ((1 2 3) [1 2 3] "\1\2\3")
+
+ -- Function: -not (pred)
+ Return a predicate that negates the result of PRED. The returned
+ predicate passes its arguments to PRED. If PRED returns ‘nil’, the
+ result is non-‘nil’; otherwise the result is ‘nil’.
+
+ See also: ‘-andfn’ (*note -andfn::) and ‘-orfn’ (*note -orfn::).
+
+ (funcall (-not #'numberp) "5")
+ ⇒ t
+ (-sort (-not #'<) '(5 2 1 0 6))
+ ⇒ (6 5 2 1 0)
+ (-filter (-not (-partial #'< 4)) '(1 2 3 4 5 6 7 8))
+ ⇒ (1 2 3 4)
+
+ -- Function: -orfn (&rest preds)
+ Return a predicate that returns the first non-‘nil’ result of
+ PREDS. The returned predicate takes a variable number of
+ arguments, passes them to each predicate in PREDS in turn until one
+ of them returns non-‘nil’, and returns that non-‘nil’ result
+ without calling the remaining PREDS. If all PREDS return ‘nil’, or
+ if no PREDS are given, the returned predicate returns ‘nil’.
+
+ See also: ‘-andfn’ (*note -andfn::) and ‘-not’ (*note -not::).
+
+ (-filter (-orfn #'natnump #'booleanp) '(1 nil "a" -4 b c t))
+ ⇒ (1 nil t)
+ (funcall (-orfn #'symbolp (-cut string-match-p "x" <>)) "axe")
+ ⇒ 1
+ (funcall (-orfn #'= #'+) 1 1)
+ ⇒ t
+
+ -- Function: -andfn (&rest preds)
+ Return a predicate that returns non-‘nil’ if all PREDS do so. The
+ returned predicate P takes a variable number of arguments and
+ passes them to each predicate in PREDS in turn. If any one of
+ PREDS returns ‘nil’, P also returns ‘nil’ without calling the
+ remaining PREDS. If all PREDS return non-‘nil’, P returns the last
+ such value. If no PREDS are given, P always returns non-‘nil’.
+
+ See also: ‘-orfn’ (*note -orfn::) and ‘-not’ (*note -not::).
+
+ (-filter (-andfn #'numberp (-cut < <> 5)) '(a 1 b 6 c 2))
+ ⇒ (1 2)
+ (mapcar (-andfn #'numberp #'1+) '(a 1 b 6))
+ ⇒ (nil 2 nil 7)
+ (funcall (-andfn #'= #'+) 1 1)
+ ⇒ 2
+
+ -- Function: -iteratefn (fn n)
+ Return a function FN composed N times with itself.
+
+ FN is a unary function. If you need to use a function of higher
+ arity, use ‘-applify’ (*note -applify::) first to turn it into a
+ unary function.
+
+ With n = 0, this acts as identity function.
+
+ In types: (a -> a) -> Int -> a -> a.
+
+ This function satisfies the following law:
+
+ (funcall (-iteratefn fn n) init) = (-last-item (-iterate fn init
+ (1+ n))).
+
+ (funcall (-iteratefn (lambda (x) (* x x)) 3) 2)
+ ⇒ 256
+ (funcall (-iteratefn '1+ 3) 1)
+ ⇒ 4
+ (funcall (-iteratefn 'cdr 3) '(1 2 3 4 5))
+ ⇒ (4 5)
+
+ -- Function: -fixfn (fn &optional equal-test halt-test)
+ Return a function that computes the (least) fixpoint of FN.
+
+ FN must be a unary function. The returned lambda takes a single
+ argument, X, the initial value for the fixpoint iteration. The
+ iteration halts when either of the following conditions is
+ satisfied:
+
+ 1. Iteration converges to the fixpoint, with equality being tested
+ using EQUAL-TEST. If EQUAL-TEST is not specified, ‘equal’ is used.
+ For functions over the floating point numbers, it may be necessary
+ to provide an appropriate approximate comparison test.
+
+ 2. HALT-TEST returns a non-‘nil’ value. HALT-TEST defaults to a
+ simple counter that returns ‘t’ after ‘-fixfn-max-iterations’, to
+ guard against infinite iteration. Otherwise, HALT-TEST must be a
+ function that accepts a single argument, the current value of X,
+ and returns non-‘nil’ as long as iteration should continue. In
+ this way, a more sophisticated convergence test may be supplied by
+ the caller.
+
+ The return value of the lambda is either the fixpoint or, if
+ iteration halted before converging, a cons with car ‘halted’ and
+ cdr the final output from HALT-TEST.
+
+ In types: (a -> a) -> a -> a.
+
+ (funcall (-fixfn #'cos #'approx=) 0.7)
+ ⇒ 0.7390851332151607
+ (funcall (-fixfn (lambda (x) (expt (+ x 10) 0.25))) 2.0)
+ ⇒ 1.8555845286409378
+ (funcall (-fixfn #'sin #'approx=) 0.1)
+ ⇒ (halted . t)
+
+ -- Function: -prodfn (&rest fns)
+ Return a function that applies each of FNS to each of a list of
+ arguments.
+
+ Takes a list of N functions and returns a function that takes a
+ list of length N, applying Ith function to Ith element of the input
+ list. Returns a list of length N.
+
+ In types (for N=2): ((a -> b), (c -> d)) -> (a, c) -> (b, d)
+
+ This function satisfies the following laws:
+
+ (-compose (-prodfn f g ...) (-prodfn f’ g’ ...)) = (-prodfn
+ (-compose f f’) (-compose g g’) ...)
+
+ (-prodfn f g ...) = (-juxt (-compose f (-partial #’nth 0))
+ (-compose g (-partial #’nth 1)) ...)
+
+ (-compose (-prodfn f g ...) (-juxt f’ g’ ...)) = (-juxt (-compose f
+ f’) (-compose g g’) ...)
+
+ (-compose (-partial #’nth n) (-prod f1 f2 ...)) = (-compose fn
+ (-partial #’nth n))
+
+ (funcall (-prodfn '1+ '1- 'number-to-string) '(1 2 3))
+ ⇒ (2 1 "3")
+ (-map (-prodfn '1+ '1-) '((1 2) (3 4) (5 6) (7 8)))
+ ⇒ ((2 1) (4 3) (6 5) (8 7))
+ (apply '+ (funcall (-prodfn 'length 'string-to-number) '((1 2 3) "15")))
+ ⇒ 18
+
+
+File: dash.info, Node: Development, Next: FDL, Prev: Functions, Up: Top
+
+3 Development
+*************
+
+The Dash repository is hosted on GitHub at
+<https://github.com/magnars/dash.el>.
+
+* Menu:
+
+* Contribute:: How to contribute.
+* Contributors:: List of contributors.
+
+
+File: dash.info, Node: Contribute, Next: Contributors, Up: Development
+
+3.1 Contribute
+==============
+
+Yes, please do. Pure functions in the list manipulation realm only,
+please. There’s a suite of examples/tests in ‘dev/examples.el’, so
+remember to add tests for your additions, or they may get broken later.
+
+ Run the tests with ‘make check’. Regenerate the docs with ‘make
+docs’. Contributors are encouraged to install these commands as a Git
+pre-commit hook, so that the tests are always running and the docs are
+always in sync:
+
+ $ cp dev/pre-commit.sh .git/hooks/pre-commit
+
+ Oh, and don’t edit ‘README.md’ or ‘dash.texi’ directly, as they are
+auto-generated. Instead, change their respective templates
+‘readme-template.md’ or ‘dash-template.texi’.
+
+ To ensure that Dash can be distributed with GNU ELPA or Emacs, we
+require that all contributors assign copyright to the Free Software
+Foundation. For more on this, *note (emacs)Copyright Assignment::.
+
+
+File: dash.info, Node: Contributors, Prev: Contribute, Up: Development
+
+3.2 Contributors
+================
+
+ • Matus Goljer (https://github.com/Fuco1) contributed lots of
+ features and functions.
+ • Takafumi Arakaki (https://github.com/tkf) contributed ‘-group-by’.
+ • tali713 (https://github.com/tali713) is the author of ‘-applify’.
+ • Víctor M. Valenzuela (https://github.com/vemv) contributed
+ ‘-repeat’.
+ • Nic Ferrier (https://github.com/nicferrier) contributed ‘-cons*’.
+ • Wilfred Hughes (https://github.com/Wilfred) contributed ‘-slice’,
+ ‘-first-item’, and ‘-last-item’.
+ • Emanuel Evans (https://github.com/shosti) contributed ‘-if-let’,
+ ‘-when-let’, and ‘-insert-at’.
+ • Johan Andersson (https://github.com/rejeep) contributed ‘-sum’,
+ ‘-product’, and ‘-same-items?’.
+ • Christina Whyte (https://github.com/kurisuwhyte) contributed
+ ‘-compose’.
+ • Steve Lamb (https://github.com/steventlamb) contributed ‘-cycle’,
+ ‘-pad’, ‘-annotate’, ‘-zip-fill’, and a variadic version of ‘-zip’.
+ • Fredrik Bergroth (https://github.com/fbergroth) made the ‘-if-let’
+ family use ‘-let’ destructuring and improved the script for
+ generating documentation.
+ • Mark Oteiza (https://github.com/holomorph) contributed ‘-iota’ and
+ the script to create an Info manual.
+ • Vasilij Schneidermann (https://github.com/wasamasa) contributed
+ ‘-some’.
+ • William West (https://github.com/occidens) made ‘-fixfn’ more
+ robust at handling floats.
+ • Cam Saul (https://github.com/camsaul) contributed ‘-some->’,
+ ‘-some->>’, and ‘-some-->’.
+ • Basil L. Contovounesios (https://github.com/basil-conto)
+ contributed ‘-common-prefix’, ‘-common-suffix’, and various other
+ improvements.
+ • Paul Pogonyshev (https://github.com/doublep) contributed ‘-each-r’
+ and ‘-each-r-while’.
+
+ Thanks!
+
+ New contributors are very welcome. *Note Contribute::.
+
+
+File: dash.info, Node: FDL, Next: GPL, Prev: Development, Up: Top
+
+Appendix A GNU Free Documentation License
+*****************************************
+
+ Version 1.3, 3 November 2008
+
+ Copyright © 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc.
+ <https://fsf.org/>
+
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ 0. PREAMBLE
+
+ The purpose of this License is to make a manual, textbook, or other
+ functional and useful document “free” in the sense of freedom: to
+ assure everyone the effective freedom to copy and redistribute it,
+ with or without modifying it, either commercially or
+ noncommercially. Secondarily, this License preserves for the
+ author and publisher a way to get credit for their work, while not
+ being considered responsible for modifications made by others.
+
+ This License is a kind of “copyleft”, which means that derivative
+ works of the document must themselves be free in the same sense.
+ It complements the GNU General Public License, which is a copyleft
+ license designed for free software.
+
+ We have designed this License in order to use it for manuals for
+ free software, because free software needs free documentation: a
+ free program should come with manuals providing the same freedoms
+ that the software does. But this License is not limited to
+ software manuals; it can be used for any textual work, regardless
+ of subject matter or whether it is published as a printed book. We
+ recommend this License principally for works whose purpose is
+ instruction or reference.
+
+ 1. APPLICABILITY AND DEFINITIONS
+
+ This License applies to any manual or other work, in any medium,
+ that contains a notice placed by the copyright holder saying it can
+ be distributed under the terms of this License. Such a notice
+ grants a world-wide, royalty-free license, unlimited in duration,
+ to use that work under the conditions stated herein. The
+ “Document”, below, refers to any such manual or work. Any member
+ of the public is a licensee, and is addressed as “you”. You accept
+ the license if you copy, modify or distribute the work in a way
+ requiring permission under copyright law.
+
+ A “Modified Version” of the Document means any work containing the
+ Document or a portion of it, either copied verbatim, or with
+ modifications and/or translated into another language.
+
+ A “Secondary Section” is a named appendix or a front-matter section
+ of the Document that deals exclusively with the relationship of the
+ publishers or authors of the Document to the Document’s overall
+ subject (or to related matters) and contains nothing that could
+ fall directly within that overall subject. (Thus, if the Document
+ is in part a textbook of mathematics, a Secondary Section may not
+ explain any mathematics.) The relationship could be a matter of
+ historical connection with the subject or with related matters, or
+ of legal, commercial, philosophical, ethical or political position
+ regarding them.
+
+ The “Invariant Sections” are certain Secondary Sections whose
+ titles are designated, as being those of Invariant Sections, in the
+ notice that says that the Document is released under this License.
+ If a section does not fit the above definition of Secondary then it
+ is not allowed to be designated as Invariant. The Document may
+ contain zero Invariant Sections. If the Document does not identify
+ any Invariant Sections then there are none.
+
+ The “Cover Texts” are certain short passages of text that are
+ listed, as Front-Cover Texts or Back-Cover Texts, in the notice
+ that says that the Document is released under this License. A
+ Front-Cover Text may be at most 5 words, and a Back-Cover Text may
+ be at most 25 words.
+
+ A “Transparent” copy of the Document means a machine-readable copy,
+ represented in a format whose specification is available to the
+ general public, that is suitable for revising the document
+ straightforwardly with generic text editors or (for images composed
+ of pixels) generic paint programs or (for drawings) some widely
+ available drawing editor, and that is suitable for input to text
+ formatters or for automatic translation to a variety of formats
+ suitable for input to text formatters. A copy made in an otherwise
+ Transparent file format whose markup, or absence of markup, has
+ been arranged to thwart or discourage subsequent modification by
+ readers is not Transparent. An image format is not Transparent if
+ used for any substantial amount of text. A copy that is not
+ “Transparent” is called “Opaque”.
+
+ Examples of suitable formats for Transparent copies include plain
+ ASCII without markup, Texinfo input format, LaTeX input format,
+ SGML or XML using a publicly available DTD, and standard-conforming
+ simple HTML, PostScript or PDF designed for human modification.
+ Examples of transparent image formats include PNG, XCF and JPG.
+ Opaque formats include proprietary formats that can be read and
+ edited only by proprietary word processors, SGML or XML for which
+ the DTD and/or processing tools are not generally available, and
+ the machine-generated HTML, PostScript or PDF produced by some word
+ processors for output purposes only.
+
+ The “Title Page” means, for a printed book, the title page itself,
+ plus such following pages as are needed to hold, legibly, the
+ material this License requires to appear in the title page. For
+ works in formats which do not have any title page as such, “Title
+ Page” means the text near the most prominent appearance of the
+ work’s title, preceding the beginning of the body of the text.
+
+ The “publisher” means any person or entity that distributes copies
+ of the Document to the public.
+
+ A section “Entitled XYZ” means a named subunit of the Document
+ whose title either is precisely XYZ or contains XYZ in parentheses
+ following text that translates XYZ in another language. (Here XYZ
+ stands for a specific section name mentioned below, such as
+ “Acknowledgements”, “Dedications”, “Endorsements”, or “History”.)
+ To “Preserve the Title” of such a section when you modify the
+ Document means that it remains a section “Entitled XYZ” according
+ to this definition.
+
+ The Document may include Warranty Disclaimers next to the notice
+ which states that this License applies to the Document. These
+ Warranty Disclaimers are considered to be included by reference in
+ this License, but only as regards disclaiming warranties: any other
+ implication that these Warranty Disclaimers may have is void and
+ has no effect on the meaning of this License.
+
+ 2. VERBATIM COPYING
+
+ You may copy and distribute the Document in any medium, either
+ commercially or noncommercially, provided that this License, the
+ copyright notices, and the license notice saying this License
+ applies to the Document are reproduced in all copies, and that you
+ add no other conditions whatsoever to those of this License. You
+ may not use technical measures to obstruct or control the reading
+ or further copying of the copies you make or distribute. However,
+ you may accept compensation in exchange for copies. If you
+ distribute a large enough number of copies you must also follow the
+ conditions in section 3.
+
+ You may also lend copies, under the same conditions stated above,
+ and you may publicly display copies.
+
+ 3. COPYING IN QUANTITY
+
+ If you publish printed copies (or copies in media that commonly
+ have printed covers) of the Document, numbering more than 100, and
+ the Document’s license notice requires Cover Texts, you must
+ enclose the copies in covers that carry, clearly and legibly, all
+ these Cover Texts: Front-Cover Texts on the front cover, and
+ Back-Cover Texts on the back cover. Both covers must also clearly
+ and legibly identify you as the publisher of these copies. The
+ front cover must present the full title with all words of the title
+ equally prominent and visible. You may add other material on the
+ covers in addition. Copying with changes limited to the covers, as
+ long as they preserve the title of the Document and satisfy these
+ conditions, can be treated as verbatim copying in other respects.
+
+ If the required texts for either cover are too voluminous to fit
+ legibly, you should put the first ones listed (as many as fit
+ reasonably) on the actual cover, and continue the rest onto
+ adjacent pages.
+
+ If you publish or distribute Opaque copies of the Document
+ numbering more than 100, you must either include a machine-readable
+ Transparent copy along with each Opaque copy, or state in or with
+ each Opaque copy a computer-network location from which the general
+ network-using public has access to download using public-standard
+ network protocols a complete Transparent copy of the Document, free
+ of added material. If you use the latter option, you must take
+ reasonably prudent steps, when you begin distribution of Opaque
+ copies in quantity, to ensure that this Transparent copy will
+ remain thus accessible at the stated location until at least one
+ year after the last time you distribute an Opaque copy (directly or
+ through your agents or retailers) of that edition to the public.
+
+ It is requested, but not required, that you contact the authors of
+ the Document well before redistributing any large number of copies,
+ to give them a chance to provide you with an updated version of the
+ Document.
+
+ 4. MODIFICATIONS
+
+ You may copy and distribute a Modified Version of the Document
+ under the conditions of sections 2 and 3 above, provided that you
+ release the Modified Version under precisely this License, with the
+ Modified Version filling the role of the Document, thus licensing
+ distribution and modification of the Modified Version to whoever
+ possesses a copy of it. In addition, you must do these things in
+ the Modified Version:
+
+ A. Use in the Title Page (and on the covers, if any) a title
+ distinct from that of the Document, and from those of previous
+ versions (which should, if there were any, be listed in the
+ History section of the Document). You may use the same title
+ as a previous version if the original publisher of that
+ version gives permission.
+
+ B. List on the Title Page, as authors, one or more persons or
+ entities responsible for authorship of the modifications in
+ the Modified Version, together with at least five of the
+ principal authors of the Document (all of its principal
+ authors, if it has fewer than five), unless they release you
+ from this requirement.
+
+ C. State on the Title page the name of the publisher of the
+ Modified Version, as the publisher.
+
+ D. Preserve all the copyright notices of the Document.
+
+ E. Add an appropriate copyright notice for your modifications
+ adjacent to the other copyright notices.
+
+ F. Include, immediately after the copyright notices, a license
+ notice giving the public permission to use the Modified
+ Version under the terms of this License, in the form shown in
+ the Addendum below.
+
+ G. Preserve in that license notice the full lists of Invariant
+ Sections and required Cover Texts given in the Document’s
+ license notice.
+
+ H. Include an unaltered copy of this License.
+
+ I. Preserve the section Entitled “History”, Preserve its Title,
+ and add to it an item stating at least the title, year, new
+ authors, and publisher of the Modified Version as given on the
+ Title Page. If there is no section Entitled “History” in the
+ Document, create one stating the title, year, authors, and
+ publisher of the Document as given on its Title Page, then add
+ an item describing the Modified Version as stated in the
+ previous sentence.
+
+ J. Preserve the network location, if any, given in the Document
+ for public access to a Transparent copy of the Document, and
+ likewise the network locations given in the Document for
+ previous versions it was based on. These may be placed in the
+ “History” section. You may omit a network location for a work
+ that was published at least four years before the Document
+ itself, or if the original publisher of the version it refers
+ to gives permission.
+
+ K. For any section Entitled “Acknowledgements” or “Dedications”,
+ Preserve the Title of the section, and preserve in the section
+ all the substance and tone of each of the contributor
+ acknowledgements and/or dedications given therein.
+
+ L. Preserve all the Invariant Sections of the Document, unaltered
+ in their text and in their titles. Section numbers or the
+ equivalent are not considered part of the section titles.
+
+ M. Delete any section Entitled “Endorsements”. Such a section
+ may not be included in the Modified Version.
+
+ N. Do not retitle any existing section to be Entitled
+ “Endorsements” or to conflict in title with any Invariant
+ Section.
+
+ O. Preserve any Warranty Disclaimers.
+
+ If the Modified Version includes new front-matter sections or
+ appendices that qualify as Secondary Sections and contain no
+ material copied from the Document, you may at your option designate
+ some or all of these sections as invariant. To do this, add their
+ titles to the list of Invariant Sections in the Modified Version’s
+ license notice. These titles must be distinct from any other
+ section titles.
+
+ You may add a section Entitled “Endorsements”, provided it contains
+ nothing but endorsements of your Modified Version by various
+ parties—for example, statements of peer review or that the text has
+ been approved by an organization as the authoritative definition of
+ a standard.
+
+ You may add a passage of up to five words as a Front-Cover Text,
+ and a passage of up to 25 words as a Back-Cover Text, to the end of
+ the list of Cover Texts in the Modified Version. Only one passage
+ of Front-Cover Text and one of Back-Cover Text may be added by (or
+ through arrangements made by) any one entity. If the Document
+ already includes a cover text for the same cover, previously added
+ by you or by arrangement made by the same entity you are acting on
+ behalf of, you may not add another; but you may replace the old
+ one, on explicit permission from the previous publisher that added
+ the old one.
+
+ The author(s) and publisher(s) of the Document do not by this
+ License give permission to use their names for publicity for or to
+ assert or imply endorsement of any Modified Version.
+
+ 5. COMBINING DOCUMENTS
+
+ You may combine the Document with other documents released under
+ this License, under the terms defined in section 4 above for
+ modified versions, provided that you include in the combination all
+ of the Invariant Sections of all of the original documents,
+ unmodified, and list them all as Invariant Sections of your
+ combined work in its license notice, and that you preserve all
+ their Warranty Disclaimers.
+
+ The combined work need only contain one copy of this License, and
+ multiple identical Invariant Sections may be replaced with a single
+ copy. If there are multiple Invariant Sections with the same name
+ but different contents, make the title of each such section unique
+ by adding at the end of it, in parentheses, the name of the
+ original author or publisher of that section if known, or else a
+ unique number. Make the same adjustment to the section titles in
+ the list of Invariant Sections in the license notice of the
+ combined work.
+
+ In the combination, you must combine any sections Entitled
+ “History” in the various original documents, forming one section
+ Entitled “History”; likewise combine any sections Entitled
+ “Acknowledgements”, and any sections Entitled “Dedications”. You
+ must delete all sections Entitled “Endorsements.”
+
+ 6. COLLECTIONS OF DOCUMENTS
+
+ You may make a collection consisting of the Document and other
+ documents released under this License, and replace the individual
+ copies of this License in the various documents with a single copy
+ that is included in the collection, provided that you follow the
+ rules of this License for verbatim copying of each of the documents
+ in all other respects.
+
+ You may extract a single document from such a collection, and
+ distribute it individually under this License, provided you insert
+ a copy of this License into the extracted document, and follow this
+ License in all other respects regarding verbatim copying of that
+ document.
+
+ 7. AGGREGATION WITH INDEPENDENT WORKS
+
+ A compilation of the Document or its derivatives with other
+ separate and independent documents or works, in or on a volume of a
+ storage or distribution medium, is called an “aggregate” if the
+ copyright resulting from the compilation is not used to limit the
+ legal rights of the compilation’s users beyond what the individual
+ works permit. When the Document is included in an aggregate, this
+ License does not apply to the other works in the aggregate which
+ are not themselves derivative works of the Document.
+
+ If the Cover Text requirement of section 3 is applicable to these
+ copies of the Document, then if the Document is less than one half
+ of the entire aggregate, the Document’s Cover Texts may be placed
+ on covers that bracket the Document within the aggregate, or the
+ electronic equivalent of covers if the Document is in electronic
+ form. Otherwise they must appear on printed covers that bracket
+ the whole aggregate.
+
+ 8. TRANSLATION
+
+ Translation is considered a kind of modification, so you may
+ distribute translations of the Document under the terms of section
+ 4. Replacing Invariant Sections with translations requires special
+ permission from their copyright holders, but you may include
+ translations of some or all Invariant Sections in addition to the
+ original versions of these Invariant Sections. You may include a
+ translation of this License, and all the license notices in the
+ Document, and any Warranty Disclaimers, provided that you also
+ include the original English version of this License and the
+ original versions of those notices and disclaimers. In case of a
+ disagreement between the translation and the original version of
+ this License or a notice or disclaimer, the original version will
+ prevail.
+
+ If a section in the Document is Entitled “Acknowledgements”,
+ “Dedications”, or “History”, the requirement (section 4) to
+ Preserve its Title (section 1) will typically require changing the
+ actual title.
+
+ 9. TERMINATION
+
+ You may not copy, modify, sublicense, or distribute the Document
+ except as expressly provided under this License. Any attempt
+ otherwise to copy, modify, sublicense, or distribute it is void,
+ and will automatically terminate your rights under this License.
+
+ However, if you cease all violation of this License, then your
+ license from a particular copyright holder is reinstated (a)
+ provisionally, unless and until the copyright holder explicitly and
+ finally terminates your license, and (b) permanently, if the
+ copyright holder fails to notify you of the violation by some
+ reasonable means prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+ reinstated permanently if the copyright holder notifies you of the
+ violation by some reasonable means, this is the first time you have
+ received notice of violation of this License (for any work) from
+ that copyright holder, and you cure the violation prior to 30 days
+ after your receipt of the notice.
+
+ Termination of your rights under this section does not terminate
+ the licenses of parties who have received copies or rights from you
+ under this License. If your rights have been terminated and not
+ permanently reinstated, receipt of a copy of some or all of the
+ same material does not give you any rights to use it.
+
+ 10. FUTURE REVISIONS OF THIS LICENSE
+
+ The Free Software Foundation may publish new, revised versions of
+ the GNU Free Documentation License from time to time. Such new
+ versions will be similar in spirit to the present version, but may
+ differ in detail to address new problems or concerns. See
+ <https://www.gnu.org/licenses/>.
+
+ Each version of the License is given a distinguishing version
+ number. If the Document specifies that a particular numbered
+ version of this License “or any later version” applies to it, you
+ have the option of following the terms and conditions either of
+ that specified version or of any later version that has been
+ published (not as a draft) by the Free Software Foundation. If the
+ Document does not specify a version number of this License, you may
+ choose any version ever published (not as a draft) by the Free
+ Software Foundation. If the Document specifies that a proxy can
+ decide which future versions of this License can be used, that
+ proxy’s public statement of acceptance of a version permanently
+ authorizes you to choose that version for the Document.
+
+ 11. RELICENSING
+
+ “Massive Multiauthor Collaboration Site” (or “MMC Site”) means any
+ World Wide Web server that publishes copyrightable works and also
+ provides prominent facilities for anybody to edit those works. A
+ public wiki that anybody can edit is an example of such a server.
+ A “Massive Multiauthor Collaboration” (or “MMC”) contained in the
+ site means any set of copyrightable works thus published on the MMC
+ site.
+
+ “CC-BY-SA” means the Creative Commons Attribution-Share Alike 3.0
+ license published by Creative Commons Corporation, a not-for-profit
+ corporation with a principal place of business in San Francisco,
+ California, as well as future copyleft versions of that license
+ published by that same organization.
+
+ “Incorporate” means to publish or republish a Document, in whole or
+ in part, as part of another Document.
+
+ An MMC is “eligible for relicensing” if it is licensed under this
+ License, and if all works that were first published under this
+ License somewhere other than this MMC, and subsequently
+ incorporated in whole or in part into the MMC, (1) had no cover
+ texts or invariant sections, and (2) were thus incorporated prior
+ to November 1, 2008.
+
+ The operator of an MMC Site may republish an MMC contained in the
+ site under CC-BY-SA on the same site at any time before August 1,
+ 2009, provided the MMC is eligible for relicensing.
+
+ADDENDUM: How to use this License for your documents
+====================================================
+
+To use this License in a document you have written, include a copy of
+the License in the document and put the following copyright and license
+notices just after the title page:
+
+ Copyright (C) YEAR YOUR NAME.
+ Permission is granted to copy, distribute and/or modify this document
+ under the terms of the GNU Free Documentation License, Version 1.3
+ or any later version published by the Free Software Foundation;
+ with no Invariant Sections, no Front-Cover Texts, and no Back-Cover
+ Texts. A copy of the license is included in the section entitled ``GNU
+ Free Documentation License''.
+
+ If you have Invariant Sections, Front-Cover Texts and Back-Cover
+Texts, replace the “with...Texts.” line with this:
+
+ with the Invariant Sections being LIST THEIR TITLES, with
+ the Front-Cover Texts being LIST, and with the Back-Cover Texts
+ being LIST.
+
+ If you have Invariant Sections without Cover Texts, or some other
+combination of the three, merge those two alternatives to suit the
+situation.
+
+ If your document contains nontrivial examples of program code, we
+recommend releasing these examples in parallel under your choice of free
+software license, such as the GNU General Public License, to permit
+their use in free software.
+
+
+File: dash.info, Node: GPL, Next: Index, Prev: FDL, Up: Top
+
+Appendix B GNU General Public License
+*************************************
+
+ Version 3, 29 June 2007
+
+ Copyright © 2007 Free Software Foundation, Inc. <https://fsf.org/>
+
+ Everyone is permitted to copy and distribute verbatim copies of this
+ license document, but changing it is not allowed.
+
+Preamble
+========
+
+The GNU General Public License is a free, copyleft license for software
+and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program—to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers’ and authors’ protection, the GPL clearly explains
+that there is no warranty for this free software. For both users’ and
+authors’ sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users’ freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+TERMS AND CONDITIONS
+====================
+
+ 0. Definitions.
+
+ “This License” refers to version 3 of the GNU General Public
+ License.
+
+ “Copyright” also means copyright-like laws that apply to other
+ kinds of works, such as semiconductor masks.
+
+ “The Program” refers to any copyrightable work licensed under this
+ License. Each licensee is addressed as “you”. “Licensees” and
+ “recipients” may be individuals or organizations.
+
+ To “modify” a work means to copy from or adapt all or part of the
+ work in a fashion requiring copyright permission, other than the
+ making of an exact copy. The resulting work is called a “modified
+ version” of the earlier work or a work “based on” the earlier work.
+
+ A “covered work” means either the unmodified Program or a work
+ based on the Program.
+
+ To “propagate” a work means to do anything with it that, without
+ permission, would make you directly or secondarily liable for
+ infringement under applicable copyright law, except executing it on
+ a computer or modifying a private copy. Propagation includes
+ copying, distribution (with or without modification), making
+ available to the public, and in some countries other activities as
+ well.
+
+ To “convey” a work means any kind of propagation that enables other
+ parties to make or receive copies. Mere interaction with a user
+ through a computer network, with no transfer of a copy, is not
+ conveying.
+
+ An interactive user interface displays “Appropriate Legal Notices”
+ to the extent that it includes a convenient and prominently visible
+ feature that (1) displays an appropriate copyright notice, and (2)
+ tells the user that there is no warranty for the work (except to
+ the extent that warranties are provided), that licensees may convey
+ the work under this License, and how to view a copy of this
+ License. If the interface presents a list of user commands or
+ options, such as a menu, a prominent item in the list meets this
+ criterion.
+
+ 1. Source Code.
+
+ The “source code” for a work means the preferred form of the work
+ for making modifications to it. “Object code” means any non-source
+ form of a work.
+
+ A “Standard Interface” means an interface that either is an
+ official standard defined by a recognized standards body, or, in
+ the case of interfaces specified for a particular programming
+ language, one that is widely used among developers working in that
+ language.
+
+ The “System Libraries” of an executable work include anything,
+ other than the work as a whole, that (a) is included in the normal
+ form of packaging a Major Component, but which is not part of that
+ Major Component, and (b) serves only to enable use of the work with
+ that Major Component, or to implement a Standard Interface for
+ which an implementation is available to the public in source code
+ form. A “Major Component”, in this context, means a major
+ essential component (kernel, window system, and so on) of the
+ specific operating system (if any) on which the executable work
+ runs, or a compiler used to produce the work, or an object code
+ interpreter used to run it.
+
+ The “Corresponding Source” for a work in object code form means all
+ the source code needed to generate, install, and (for an executable
+ work) run the object code and to modify the work, including scripts
+ to control those activities. However, it does not include the
+ work’s System Libraries, or general-purpose tools or generally
+ available free programs which are used unmodified in performing
+ those activities but which are not part of the work. For example,
+ Corresponding Source includes interface definition files associated
+ with source files for the work, and the source code for shared
+ libraries and dynamically linked subprograms that the work is
+ specifically designed to require, such as by intimate data
+ communication or control flow between those subprograms and other
+ parts of the work.
+
+ The Corresponding Source need not include anything that users can
+ regenerate automatically from other parts of the Corresponding
+ Source.
+
+ The Corresponding Source for a work in source code form is that
+ same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+ copyright on the Program, and are irrevocable provided the stated
+ conditions are met. This License explicitly affirms your unlimited
+ permission to run the unmodified Program. The output from running
+ a covered work is covered by this License only if the output, given
+ its content, constitutes a covered work. This License acknowledges
+ your rights of fair use or other equivalent, as provided by
+ copyright law.
+
+ You may make, run and propagate covered works that you do not
+ convey, without conditions so long as your license otherwise
+ remains in force. You may convey covered works to others for the
+ sole purpose of having them make modifications exclusively for you,
+ or provide you with facilities for running those works, provided
+ that you comply with the terms of this License in conveying all
+ material for which you do not control copyright. Those thus making
+ or running the covered works for you must do so exclusively on your
+ behalf, under your direction and control, on terms that prohibit
+ them from making any copies of your copyrighted material outside
+ their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+ the conditions stated below. Sublicensing is not allowed; section
+ 10 makes it unnecessary.
+
+ 3. Protecting Users’ Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+ measure under any applicable law fulfilling obligations under
+ article 11 of the WIPO copyright treaty adopted on 20 December
+ 1996, or similar laws prohibiting or restricting circumvention of
+ such measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+ circumvention of technological measures to the extent such
+ circumvention is effected by exercising rights under this License
+ with respect to the covered work, and you disclaim any intention to
+ limit operation or modification of the work as a means of
+ enforcing, against the work’s users, your or third parties’ legal
+ rights to forbid circumvention of technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program’s source code as you
+ receive it, in any medium, provided that you conspicuously and
+ appropriately publish on each copy an appropriate copyright notice;
+ keep intact all notices stating that this License and any
+ non-permissive terms added in accord with section 7 apply to the
+ code; keep intact all notices of the absence of any warranty; and
+ give all recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+ and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+ produce it from the Program, in the form of source code under the
+ terms of section 4, provided that you also meet all of these
+ conditions:
+
+ a. The work must carry prominent notices stating that you
+ modified it, and giving a relevant date.
+
+ b. The work must carry prominent notices stating that it is
+ released under this License and any conditions added under
+ section 7. This requirement modifies the requirement in
+ section 4 to “keep intact all notices”.
+
+ c. You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable
+ section 7 additional terms, to the whole of the work, and all
+ its parts, regardless of how they are packaged. This License
+ gives no permission to license the work in any other way, but
+ it does not invalidate such permission if you have separately
+ received it.
+
+ d. If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has
+ interactive interfaces that do not display Appropriate Legal
+ Notices, your work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+ works, which are not by their nature extensions of the covered
+ work, and which are not combined with it such as to form a larger
+ program, in or on a volume of a storage or distribution medium, is
+ called an “aggregate” if the compilation and its resulting
+ copyright are not used to limit the access or legal rights of the
+ compilation’s users beyond what the individual works permit.
+ Inclusion of a covered work in an aggregate does not cause this
+ License to apply to the other parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+ of sections 4 and 5, provided that you also convey the
+ machine-readable Corresponding Source under the terms of this
+ License, in one of these ways:
+
+ a. Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b. Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that
+ product model, to give anyone who possesses the object code
+ either (1) a copy of the Corresponding Source for all the
+ software in the product that is covered by this License, on a
+ durable physical medium customarily used for software
+ interchange, for a price no more than your reasonable cost of
+ physically performing this conveying of source, or (2) access
+ to copy the Corresponding Source from a network server at no
+ charge.
+
+ c. Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially,
+ and only if you received the object code with such an offer,
+ in accord with subsection 6b.
+
+ d. Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to
+ the Corresponding Source in the same way through the same
+ place at no further charge. You need not require recipients
+ to copy the Corresponding Source along with the object code.
+ If the place to copy the object code is a network server, the
+ Corresponding Source may be on a different server (operated by
+ you or a third party) that supports equivalent copying
+ facilities, provided you maintain clear directions next to the
+ object code saying where to find the Corresponding Source.
+ Regardless of what server hosts the Corresponding Source, you
+ remain obligated to ensure that it is available for as long as
+ needed to satisfy these requirements.
+
+ e. Convey the object code using peer-to-peer transmission,
+ provided you inform other peers where the object code and
+ Corresponding Source of the work are being offered to the
+ general public at no charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is
+ excluded from the Corresponding Source as a System Library, need
+ not be included in conveying the object code work.
+
+ A “User Product” is either (1) a “consumer product”, which means
+ any tangible personal property which is normally used for personal,
+ family, or household purposes, or (2) anything designed or sold for
+ incorporation into a dwelling. In determining whether a product is
+ a consumer product, doubtful cases shall be resolved in favor of
+ coverage. For a particular product received by a particular user,
+ “normally used” refers to a typical or common use of that class of
+ product, regardless of the status of the particular user or of the
+ way in which the particular user actually uses, or expects or is
+ expected to use, the product. A product is a consumer product
+ regardless of whether the product has substantial commercial,
+ industrial or non-consumer uses, unless such uses represent the
+ only significant mode of use of the product.
+
+ “Installation Information” for a User Product means any methods,
+ procedures, authorization keys, or other information required to
+ install and execute modified versions of a covered work in that
+ User Product from a modified version of its Corresponding Source.
+ The information must suffice to ensure that the continued
+ functioning of the modified object code is in no case prevented or
+ interfered with solely because modification has been made.
+
+ If you convey an object code work under this section in, or with,
+ or specifically for use in, a User Product, and the conveying
+ occurs as part of a transaction in which the right of possession
+ and use of the User Product is transferred to the recipient in
+ perpetuity or for a fixed term (regardless of how the transaction
+ is characterized), the Corresponding Source conveyed under this
+ section must be accompanied by the Installation Information. But
+ this requirement does not apply if neither you nor any third party
+ retains the ability to install modified object code on the User
+ Product (for example, the work has been installed in ROM).
+
+ The requirement to provide Installation Information does not
+ include a requirement to continue to provide support service,
+ warranty, or updates for a work that has been modified or installed
+ by the recipient, or for the User Product in which it has been
+ modified or installed. Access to a network may be denied when the
+ modification itself materially and adversely affects the operation
+ of the network or violates the rules and protocols for
+ communication across the network.
+
+ Corresponding Source conveyed, and Installation Information
+ provided, in accord with this section must be in a format that is
+ publicly documented (and with an implementation available to the
+ public in source code form), and must require no special password
+ or key for unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ “Additional permissions” are terms that supplement the terms of
+ this License by making exceptions from one or more of its
+ conditions. Additional permissions that are applicable to the
+ entire Program shall be treated as though they were included in
+ this License, to the extent that they are valid under applicable
+ law. If additional permissions apply only to part of the Program,
+ that part may be used separately under those permissions, but the
+ entire Program remains governed by this License without regard to
+ the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+ remove any additional permissions from that copy, or from any part
+ of it. (Additional permissions may be written to require their own
+ removal in certain cases when you modify the work.) You may place
+ additional permissions on material, added by you to a covered work,
+ for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material
+ you add to a covered work, you may (if authorized by the copyright
+ holders of that material) supplement the terms of this License with
+ terms:
+
+ a. Disclaiming warranty or limiting liability differently from
+ the terms of sections 15 and 16 of this License; or
+
+ b. Requiring preservation of specified reasonable legal notices
+ or author attributions in that material or in the Appropriate
+ Legal Notices displayed by works containing it; or
+
+ c. Prohibiting misrepresentation of the origin of that material,
+ or requiring that modified versions of such material be marked
+ in reasonable ways as different from the original version; or
+
+ d. Limiting the use for publicity purposes of names of licensors
+ or authors of the material; or
+
+ e. Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f. Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified
+ versions of it) with contractual assumptions of liability to
+ the recipient, for any liability that these contractual
+ assumptions directly impose on those licensors and authors.
+
+ All other non-permissive additional terms are considered “further
+ restrictions” within the meaning of section 10. If the Program as
+ you received it, or any part of it, contains a notice stating that
+ it is governed by this License along with a term that is a further
+ restriction, you may remove that term. If a license document
+ contains a further restriction but permits relicensing or conveying
+ under this License, you may add to a covered work material governed
+ by the terms of that license document, provided that the further
+ restriction does not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+ must place, in the relevant source files, a statement of the
+ additional terms that apply to those files, or a notice indicating
+ where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in
+ the form of a separately written license, or stated as exceptions;
+ the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+ provided under this License. Any attempt otherwise to propagate or
+ modify it is void, and will automatically terminate your rights
+ under this License (including any patent licenses granted under the
+ third paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+ license from a particular copyright holder is reinstated (a)
+ provisionally, unless and until the copyright holder explicitly and
+ finally terminates your license, and (b) permanently, if the
+ copyright holder fails to notify you of the violation by some
+ reasonable means prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+ reinstated permanently if the copyright holder notifies you of the
+ violation by some reasonable means, this is the first time you have
+ received notice of violation of this License (for any work) from
+ that copyright holder, and you cure the violation prior to 30 days
+ after your receipt of the notice.
+
+ Termination of your rights under this section does not terminate
+ the licenses of parties who have received copies or rights from you
+ under this License. If your rights have been terminated and not
+ permanently reinstated, you do not qualify to receive new licenses
+ for the same material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+ run a copy of the Program. Ancillary propagation of a covered work
+ occurring solely as a consequence of using peer-to-peer
+ transmission to receive a copy likewise does not require
+ acceptance. However, nothing other than this License grants you
+ permission to propagate or modify any covered work. These actions
+ infringe copyright if you do not accept this License. Therefore,
+ by modifying or propagating a covered work, you indicate your
+ acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+ receives a license from the original licensors, to run, modify and
+ propagate that work, subject to this License. You are not
+ responsible for enforcing compliance by third parties with this
+ License.
+
+ An “entity transaction” is a transaction transferring control of an
+ organization, or substantially all assets of one, or subdividing an
+ organization, or merging organizations. If propagation of a
+ covered work results from an entity transaction, each party to that
+ transaction who receives a copy of the work also receives whatever
+ licenses to the work the party’s predecessor in interest had or
+ could give under the previous paragraph, plus a right to possession
+ of the Corresponding Source of the work from the predecessor in
+ interest, if the predecessor has it or can get it with reasonable
+ efforts.
+
+ You may not impose any further restrictions on the exercise of the
+ rights granted or affirmed under this License. For example, you
+ may not impose a license fee, royalty, or other charge for exercise
+ of rights granted under this License, and you may not initiate
+ litigation (including a cross-claim or counterclaim in a lawsuit)
+ alleging that any patent claim is infringed by making, using,
+ selling, offering for sale, or importing the Program or any portion
+ of it.
+
+ 11. Patents.
+
+ A “contributor” is a copyright holder who authorizes use under this
+ License of the Program or a work on which the Program is based.
+ The work thus licensed is called the contributor’s “contributor
+ version”.
+
+ A contributor’s “essential patent claims” are all patent claims
+ owned or controlled by the contributor, whether already acquired or
+ hereafter acquired, that would be infringed by some manner,
+ permitted by this License, of making, using, or selling its
+ contributor version, but do not include claims that would be
+ infringed only as a consequence of further modification of the
+ contributor version. For purposes of this definition, “control”
+ includes the right to grant patent sublicenses in a manner
+ consistent with the requirements of this License.
+
+ Each contributor grants you a non-exclusive, worldwide,
+ royalty-free patent license under the contributor’s essential
+ patent claims, to make, use, sell, offer for sale, import and
+ otherwise run, modify and propagate the contents of its contributor
+ version.
+
+ In the following three paragraphs, a “patent license” is any
+ express agreement or commitment, however denominated, not to
+ enforce a patent (such as an express permission to practice a
+ patent or covenant not to sue for patent infringement). To “grant”
+ such a patent license to a party means to make such an agreement or
+ commitment not to enforce a patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent
+ license, and the Corresponding Source of the work is not available
+ for anyone to copy, free of charge and under the terms of this
+ License, through a publicly available network server or other
+ readily accessible means, then you must either (1) cause the
+ Corresponding Source to be so available, or (2) arrange to deprive
+ yourself of the benefit of the patent license for this particular
+ work, or (3) arrange, in a manner consistent with the requirements
+ of this License, to extend the patent license to downstream
+ recipients. “Knowingly relying” means you have actual knowledge
+ that, but for the patent license, your conveying the covered work
+ in a country, or your recipient’s use of the covered work in a
+ country, would infringe one or more identifiable patents in that
+ country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+ arrangement, you convey, or propagate by procuring conveyance of, a
+ covered work, and grant a patent license to some of the parties
+ receiving the covered work authorizing them to use, propagate,
+ modify or convey a specific copy of the covered work, then the
+ patent license you grant is automatically extended to all
+ recipients of the covered work and works based on it.
+
+ A patent license is “discriminatory” if it does not include within
+ the scope of its coverage, prohibits the exercise of, or is
+ conditioned on the non-exercise of one or more of the rights that
+ are specifically granted under this License. You may not convey a
+ covered work if you are a party to an arrangement with a third
+ party that is in the business of distributing software, under which
+ you make payment to the third party based on the extent of your
+ activity of conveying the work, and under which the third party
+ grants, to any of the parties who would receive the covered work
+ from you, a discriminatory patent license (a) in connection with
+ copies of the covered work conveyed by you (or copies made from
+ those copies), or (b) primarily for and in connection with specific
+ products or compilations that contain the covered work, unless you
+ entered into that arrangement, or that patent license was granted,
+ prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+ any implied license or other defenses to infringement that may
+ otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others’ Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement
+ or otherwise) that contradict the conditions of this License, they
+ do not excuse you from the conditions of this License. If you
+ cannot convey a covered work so as to satisfy simultaneously your
+ obligations under this License and any other pertinent obligations,
+ then as a consequence you may not convey it at all. For example,
+ if you agree to terms that obligate you to collect a royalty for
+ further conveying from those to whom you convey the Program, the
+ only way you could satisfy both those terms and this License would
+ be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+ permission to link or combine any covered work with a work licensed
+ under version 3 of the GNU Affero General Public License into a
+ single combined work, and to convey the resulting work. The terms
+ of this License will continue to apply to the part which is the
+ covered work, but the special requirements of the GNU Affero
+ General Public License, section 13, concerning interaction through
+ a network will apply to the combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new
+ versions of the GNU General Public License from time to time. Such
+ new versions will be similar in spirit to the present version, but
+ may differ in detail to address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+ Program specifies that a certain numbered version of the GNU
+ General Public License “or any later version” applies to it, you
+ have the option of following the terms and conditions either of
+ that numbered version or of any later version published by the Free
+ Software Foundation. If the Program does not specify a version
+ number of the GNU General Public License, you may choose any
+ version ever published by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+ versions of the GNU General Public License can be used, that
+ proxy’s public statement of acceptance of a version permanently
+ authorizes you to choose that version for the Program.
+
+ Later license versions may give you additional or different
+ permissions. However, no additional obligations are imposed on any
+ author or copyright holder as a result of your choosing to follow a
+ later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+ APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE
+ COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM “AS IS”
+ WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE
+ RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.
+ SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL
+ NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+ WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES
+ AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR
+ DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+ CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE
+ THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA
+ BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+ PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+ PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF
+ THE POSSIBILITY OF SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+ above cannot be given local legal effect according to their terms,
+ reviewing courts shall apply local law that most closely
+ approximates an absolute waiver of all civil liability in
+ connection with the Program, unless a warranty or assumption of
+ liability accompanies a copy of the Program in return for a fee.
+
+END OF TERMS AND CONDITIONS
+===========================
+
+How to Apply These Terms to Your New Programs
+=============================================
+
+If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these
+terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least the
+“copyright” line and a pointer to where the full notice is found.
+
+ ONE LINE TO GIVE THE PROGRAM'S NAME AND A BRIEF IDEA OF WHAT IT DOES.
+ Copyright (C) YEAR NAME OF AUTHOR
+
+ 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 <https://www.gnu.org/licenses/>.
+
+ Also add information on how to contact you by electronic and paper
+mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ PROGRAM Copyright (C) YEAR NAME OF AUTHOR
+ This program comes with ABSOLUTELY NO WARRANTY; for details type ‘show w’.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type ‘show c’ for details.
+
+ The hypothetical commands ‘show w’ and ‘show c’ should show the
+appropriate parts of the General Public License. Of course, your
+program’s commands might be different; for a GUI interface, you would
+use an “about box”.
+
+ You should also get your employer (if you work as a programmer) or
+school, if any, to sign a “copyright disclaimer” for the program, if
+necessary. For more information on this, and how to apply and follow
+the GNU GPL, see <https://www.gnu.org/licenses/>.
+
+ The GNU General Public License does not permit incorporating your
+program into proprietary programs. If your program is a subroutine
+library, you may consider it more useful to permit linking proprietary
+applications with the library. If this is what you want to do, use the
+GNU Lesser General Public License instead of this License. But first,
+please read <https://www.gnu.org/licenses/why-not-lgpl.html>.
+
+
+File: dash.info, Node: Index, Prev: GPL, Up: Top
+
+Index
+*****
+
+
+* Menu:
+
+* !cdr: Destructive operations.
+ (line 16)
+* !cons: Destructive operations.
+ (line 8)
+* -->: Threading macros. (line 35)
+* ->: Threading macros. (line 9)
+* ->>: Threading macros. (line 22)
+* -all?: Predicates. (line 53)
+* -andfn: Function combinators.
+ (line 184)
+* -annotate: Maps. (line 86)
+* -any?: Predicates. (line 41)
+* -applify: Function combinators.
+ (line 63)
+* -as->: Threading macros. (line 49)
+* -butlast: Other list operations.
+ (line 335)
+* -clone: Tree operations. (line 123)
+* -common-prefix: Reductions. (line 242)
+* -common-suffix: Reductions. (line 252)
+* -compose: Function combinators.
+ (line 49)
+* -concat: List to list. (line 23)
+* -cons*: Other list operations.
+ (line 30)
+* -cons-pair?: Predicates. (line 167)
+* -const: Function combinators.
+ (line 128)
+* -contains?: Predicates. (line 100)
+* -copy: Maps. (line 141)
+* -count: Reductions. (line 172)
+* -cut: Function combinators.
+ (line 140)
+* -cycle: Other list operations.
+ (line 180)
+* -difference: Set operations. (line 20)
+* -distinct: Set operations. (line 62)
+* -dotimes: Side effects. (line 80)
+* -doto: Threading macros. (line 99)
+* -drop: Sublist selection. (line 149)
+* -drop-last: Sublist selection. (line 163)
+* -drop-while: Sublist selection. (line 194)
+* -each: Side effects. (line 8)
+* -each-indexed: Side effects. (line 38)
+* -each-r: Side effects. (line 52)
+* -each-r-while: Side effects. (line 65)
+* -each-while: Side effects. (line 24)
+* -elem-index: Indexing. (line 9)
+* -elem-indices: Indexing. (line 21)
+* -every: Predicates. (line 23)
+* -fifth-item: Other list operations.
+ (line 315)
+* -filter: Sublist selection. (line 8)
+* -find-index: Indexing. (line 32)
+* -find-indices: Indexing. (line 60)
+* -find-last-index: Indexing. (line 46)
+* -first: Other list operations.
+ (line 246)
+* -first-item: Other list operations.
+ (line 272)
+* -fix: Other list operations.
+ (line 375)
+* -fixfn: Function combinators.
+ (line 224)
+* -flatten: List to list. (line 36)
+* -flatten-n: List to list. (line 58)
+* -flip: Function combinators.
+ (line 95)
+* -fourth-item: Other list operations.
+ (line 305)
+* -grade-down: Indexing. (line 81)
+* -grade-up: Indexing. (line 71)
+* -group-by: Partitioning. (line 205)
+* -if-let: Binding. (line 34)
+* -if-let*: Binding. (line 45)
+* -inits: Reductions. (line 222)
+* -insert-at: List to list. (line 112)
+* -interleave: Other list operations.
+ (line 67)
+* -interpose: Other list operations.
+ (line 57)
+* -intersection: Set operations. (line 32)
+* -iota: Other list operations.
+ (line 78)
+* -is-infix?: Predicates. (line 153)
+* -is-prefix?: Predicates. (line 129)
+* -is-suffix?: Predicates. (line 141)
+* -iterate: Unfolding. (line 9)
+* -iteratefn: Function combinators.
+ (line 201)
+* -juxt: Function combinators.
+ (line 37)
+* -keep: List to list. (line 8)
+* -lambda: Binding. (line 247)
+* -last: Other list operations.
+ (line 262)
+* -last-item: Other list operations.
+ (line 325)
+* -let: Binding. (line 61)
+* -let*: Binding. (line 227)
+* -list: Other list operations.
+ (line 358)
+* -map: Maps. (line 10)
+* -map-first: Maps. (line 38)
+* -map-indexed: Maps. (line 68)
+* -map-last: Maps. (line 53)
+* -map-when: Maps. (line 22)
+* -mapcat: Maps. (line 130)
+* -max: Reductions. (line 286)
+* -max-by: Reductions. (line 296)
+* -min: Reductions. (line 262)
+* -min-by: Reductions. (line 272)
+* -non-nil: Sublist selection. (line 95)
+* -none?: Predicates. (line 73)
+* -not: Function combinators.
+ (line 153)
+* -on: Function combinators.
+ (line 75)
+* -only-some?: Predicates. (line 85)
+* -orfn: Function combinators.
+ (line 167)
+* -pad: Other list operations.
+ (line 191)
+* -partial: Function combinators.
+ (line 8)
+* -partition: Partitioning. (line 90)
+* -partition-after-item: Partitioning. (line 195)
+* -partition-after-pred: Partitioning. (line 162)
+* -partition-all: Partitioning. (line 102)
+* -partition-all-in-steps: Partitioning. (line 126)
+* -partition-before-item: Partitioning. (line 185)
+* -partition-before-pred: Partitioning. (line 174)
+* -partition-by: Partitioning. (line 138)
+* -partition-by-header: Partitioning. (line 149)
+* -partition-in-steps: Partitioning. (line 113)
+* -permutations: Set operations. (line 52)
+* -powerset: Set operations. (line 44)
+* -prodfn: Function combinators.
+ (line 258)
+* -product: Reductions. (line 201)
+* -reduce: Reductions. (line 53)
+* -reduce-from: Reductions. (line 8)
+* -reduce-r: Reductions. (line 72)
+* -reduce-r-from: Reductions. (line 26)
+* -reductions: Reductions. (line 136)
+* -reductions-from: Reductions. (line 100)
+* -reductions-r: Reductions. (line 154)
+* -reductions-r-from: Reductions. (line 118)
+* -remove: Sublist selection. (line 26)
+* -remove-at: List to list. (line 149)
+* -remove-at-indices: List to list. (line 162)
+* -remove-first: Sublist selection. (line 44)
+* -remove-item: Sublist selection. (line 84)
+* -remove-last: Sublist selection. (line 65)
+* -repeat: Other list operations.
+ (line 19)
+* -replace: List to list. (line 70)
+* -replace-at: List to list. (line 123)
+* -replace-first: List to list. (line 84)
+* -replace-last: List to list. (line 98)
+* -rotate: Other list operations.
+ (line 8)
+* -rotate-args: Function combinators.
+ (line 112)
+* -rpartial: Function combinators.
+ (line 22)
+* -running-product: Reductions. (line 211)
+* -running-sum: Reductions. (line 190)
+* -same-items?: Predicates. (line 115)
+* -second-item: Other list operations.
+ (line 285)
+* -select-by-indices: Sublist selection. (line 211)
+* -select-column: Sublist selection. (line 241)
+* -select-columns: Sublist selection. (line 222)
+* -separate: Partitioning. (line 75)
+* -setq: Binding. (line 270)
+* -slice: Sublist selection. (line 105)
+* -snoc: Other list operations.
+ (line 43)
+* -some: Predicates. (line 8)
+* -some-->: Threading macros. (line 86)
+* -some->: Threading macros. (line 62)
+* -some->>: Threading macros. (line 74)
+* -sort: Other list operations.
+ (line 345)
+* -splice: Maps. (line 97)
+* -splice-list: Maps. (line 117)
+* -split-at: Partitioning. (line 8)
+* -split-on: Partitioning. (line 40)
+* -split-when: Partitioning. (line 58)
+* -split-with: Partitioning. (line 23)
+* -sum: Reductions. (line 180)
+* -table: Other list operations.
+ (line 202)
+* -table-flat: Other list operations.
+ (line 221)
+* -tails: Reductions. (line 232)
+* -take: Sublist selection. (line 121)
+* -take-last: Sublist selection. (line 135)
+* -take-while: Sublist selection. (line 177)
+* -third-item: Other list operations.
+ (line 295)
+* -tree-map: Tree operations. (line 28)
+* -tree-map-nodes: Tree operations. (line 39)
+* -tree-mapreduce: Tree operations. (line 85)
+* -tree-mapreduce-from: Tree operations. (line 104)
+* -tree-reduce: Tree operations. (line 53)
+* -tree-reduce-from: Tree operations. (line 70)
+* -tree-seq: Tree operations. (line 8)
+* -unfold: Unfolding. (line 25)
+* -union: Set operations. (line 8)
+* -unzip: Other list operations.
+ (line 158)
+* -update-at: List to list. (line 135)
+* -when-let: Binding. (line 9)
+* -when-let*: Binding. (line 21)
+* -zip: Other list operations.
+ (line 107)
+* -zip-fill: Other list operations.
+ (line 150)
+* -zip-lists: Other list operations.
+ (line 131)
+* -zip-with: Other list operations.
+ (line 91)
+* dash-fontify-mode: Fontification of special variables.
+ (line 6)
+* dash-register-info-lookup: Info symbol lookup. (line 6)
+* global-dash-fontify-mode: Fontification of special variables.
+ (line 12)
+
+
+
+Tag Table:
+Node: Top742
+Node: Installation2397
+Node: Using in a package3159
+Node: Fontification of special variables3504
+Node: Info symbol lookup4294
+Node: Functions4877
+Node: Maps6361
+Ref: -map6658
+Ref: -map-when7031
+Ref: -map-first7605
+Ref: -map-last8200
+Ref: -map-indexed8790
+Ref: -annotate9476
+Ref: -splice9963
+Ref: -splice-list10741
+Ref: -mapcat11200
+Ref: -copy11573
+Node: Sublist selection11761
+Ref: -filter11954
+Ref: -remove12507
+Ref: -remove-first13056
+Ref: -remove-last13904
+Ref: -remove-item14634
+Ref: -non-nil15034
+Ref: -slice15316
+Ref: -take15845
+Ref: -take-last16263
+Ref: -drop16700
+Ref: -drop-last17147
+Ref: -take-while17579
+Ref: -drop-while18206
+Ref: -select-by-indices18839
+Ref: -select-columns19350
+Ref: -select-column20053
+Node: List to list20516
+Ref: -keep20708
+Ref: -concat21284
+Ref: -flatten21767
+Ref: -flatten-n22529
+Ref: -replace22913
+Ref: -replace-first23374
+Ref: -replace-last23869
+Ref: -insert-at24357
+Ref: -replace-at24682
+Ref: -update-at25069
+Ref: -remove-at25610
+Ref: -remove-at-indices26095
+Node: Reductions26674
+Ref: -reduce-from26870
+Ref: -reduce-r-from27594
+Ref: -reduce28857
+Ref: -reduce-r29608
+Ref: -reductions-from30886
+Ref: -reductions-r-from31692
+Ref: -reductions32522
+Ref: -reductions-r33233
+Ref: -count33978
+Ref: -sum34208
+Ref: -running-sum34396
+Ref: -product34717
+Ref: -running-product34925
+Ref: -inits35266
+Ref: -tails35511
+Ref: -common-prefix35755
+Ref: -common-suffix36049
+Ref: -min36343
+Ref: -min-by36569
+Ref: -max37090
+Ref: -max-by37315
+Node: Unfolding37841
+Ref: -iterate38082
+Ref: -unfold38529
+Node: Predicates39334
+Ref: -some39511
+Ref: -every39940
+Ref: -any?40654
+Ref: -all?41003
+Ref: -none?41745
+Ref: -only-some?42065
+Ref: -contains?42610
+Ref: -same-items?43011
+Ref: -is-prefix?43396
+Ref: -is-suffix?43728
+Ref: -is-infix?44060
+Ref: -cons-pair?44420
+Node: Partitioning44751
+Ref: -split-at44939
+Ref: -split-with45603
+Ref: -split-on46243
+Ref: -split-when46914
+Ref: -separate47557
+Ref: -partition48091
+Ref: -partition-all48540
+Ref: -partition-in-steps48965
+Ref: -partition-all-in-steps49511
+Ref: -partition-by50025
+Ref: -partition-by-header50403
+Ref: -partition-after-pred51004
+Ref: -partition-before-pred51457
+Ref: -partition-before-item51842
+Ref: -partition-after-item52149
+Ref: -group-by52451
+Node: Indexing52884
+Ref: -elem-index53086
+Ref: -elem-indices53487
+Ref: -find-index53867
+Ref: -find-last-index54362
+Ref: -find-indices54872
+Ref: -grade-up55277
+Ref: -grade-down55684
+Node: Set operations56098
+Ref: -union56281
+Ref: -difference56695
+Ref: -intersection57113
+Ref: -powerset57526
+Ref: -permutations57736
+Ref: -distinct58032
+Node: Other list operations58412
+Ref: -rotate58637
+Ref: -repeat58990
+Ref: -cons*59275
+Ref: -snoc59697
+Ref: -interpose60109
+Ref: -interleave60403
+Ref: -iota60769
+Ref: -zip-with61252
+Ref: -zip61966
+Ref: -zip-lists62795
+Ref: -zip-fill63493
+Ref: -unzip63815
+Ref: -cycle64557
+Ref: -pad64956
+Ref: -table65275
+Ref: -table-flat66061
+Ref: -first67066
+Ref: -last67564
+Ref: -first-item67910
+Ref: -second-item68315
+Ref: -third-item68585
+Ref: -fourth-item68853
+Ref: -fifth-item69125
+Ref: -last-item69393
+Ref: -butlast69690
+Ref: -sort69935
+Ref: -list70427
+Ref: -fix70996
+Node: Tree operations71485
+Ref: -tree-seq71681
+Ref: -tree-map72542
+Ref: -tree-map-nodes72982
+Ref: -tree-reduce73846
+Ref: -tree-reduce-from74728
+Ref: -tree-mapreduce75328
+Ref: -tree-mapreduce-from76187
+Ref: -clone77472
+Node: Threading macros77799
+Ref: ->78024
+Ref: ->>78512
+Ref: -->79015
+Ref: -as->79571
+Ref: -some->80025
+Ref: -some->>80410
+Ref: -some-->80857
+Ref: -doto81424
+Node: Binding81977
+Ref: -when-let82184
+Ref: -when-let*82645
+Ref: -if-let83174
+Ref: -if-let*83540
+Ref: -let84163
+Ref: -let*90253
+Ref: -lambda91190
+Ref: -setq91996
+Node: Side effects92797
+Ref: -each92991
+Ref: -each-while93518
+Ref: -each-indexed94138
+Ref: -each-r94730
+Ref: -each-r-while95172
+Ref: -dotimes95816
+Node: Destructive operations96369
+Ref: !cons96587
+Ref: !cdr96791
+Node: Function combinators96984
+Ref: -partial97188
+Ref: -rpartial97706
+Ref: -juxt98354
+Ref: -compose98806
+Ref: -applify99413
+Ref: -on99843
+Ref: -flip100615
+Ref: -rotate-args101139
+Ref: -const101768
+Ref: -cut102110
+Ref: -not102590
+Ref: -orfn103134
+Ref: -andfn103927
+Ref: -iteratefn104714
+Ref: -fixfn105416
+Ref: -prodfn106990
+Node: Development108151
+Node: Contribute108440
+Node: Contributors109452
+Node: FDL111545
+Node: GPL136865
+Node: Index174614
+
+End Tag Table
+
+
+Local Variables:
+coding: utf-8
+End:
diff --git a/elpa/dash-20220417.2250/dir b/elpa/dash-20220417.2250/dir
new file mode 100644
index 0000000..7d473f4
--- /dev/null
+++ b/elpa/dash-20220417.2250/dir
@@ -0,0 +1,18 @@
+This is the file .../info/dir, which contains the
+topmost node of the Info hierarchy, called (dir)Top.
+The first time you invoke Info you start off looking at this node.
+
+File: dir, Node: Top This is the top of the INFO tree
+
+ This (the Directory node) gives a menu of major topics.
+ Typing "q" exits, "H" lists all Info commands, "d" returns here,
+ "h" gives a primer for first-timers,
+ "mEmacs<Return>" visits the Emacs manual, etc.
+
+ In Emacs, you can click mouse button 2 on a menu item or cross reference
+ to select it.
+
+* Menu:
+
+Emacs
+* Dash: (dash.info). A modern list library for GNU Emacs.
diff --git a/elpa/dashboard-20220409.620/banners/1.txt b/elpa/dashboard-20220409.620/banners/1.txt
new file mode 100644
index 0000000..8bd71a7
--- /dev/null
+++ b/elpa/dashboard-20220409.620/banners/1.txt
@@ -0,0 +1,8 @@
+
+######## ## ## ### ###### ######
+## ### ### ## ## ## ## ## ##
+## #### #### ## ## ## ##
+###### ## ### ## ## ## ## ######
+## ## ## ######### ## ##
+## ## ## ## ## ## ## ## ##
+######## ## ## ## ## ###### ######
diff --git a/elpa/dashboard-20220409.620/banners/2.txt b/elpa/dashboard-20220409.620/banners/2.txt
new file mode 100644
index 0000000..73b761b
--- /dev/null
+++ b/elpa/dashboard-20220409.620/banners/2.txt
@@ -0,0 +1,6 @@
+ _______ .___ ___. ___ ______ _______.
+| ____|| \/ | / \ / | / |
+| |__ | \ / | / ^ \ | ,----' | (----`
+| __| | |\/| | / /_\ \ | | \ \
+| |____ | | | | / _____ \ | `----.----) |
+|_______||__| |__| /__/ \__\ \______|_______/
diff --git a/elpa/dashboard-20220409.620/banners/3.txt b/elpa/dashboard-20220409.620/banners/3.txt
new file mode 100644
index 0000000..3abfd82
--- /dev/null
+++ b/elpa/dashboard-20220409.620/banners/3.txt
@@ -0,0 +1,8 @@
+ _______ _____ ______ ________ ________ ________
+|\ ___ \ |\ _ \ _ \|\ __ \|\ ____\|\ ____\
+\ \ __/|\ \ \\\__\ \ \ \ \|\ \ \ \___|\ \ \___|_
+ \ \ \_|/_\ \ \\|__| \ \ \ __ \ \ \ \ \_____ \
+ \ \ \_|\ \ \ \ \ \ \ \ \ \ \ \ \____\|____|\ \
+ \ \_______\ \__\ \ \__\ \__\ \__\ \_______\____\_\ \
+ \|_______|\|__| \|__|\|__|\|__|\|_______|\_________\
+ \|_________|
diff --git a/elpa/dashboard-20220409.620/banners/4.txt b/elpa/dashboard-20220409.620/banners/4.txt
new file mode 100644
index 0000000..d82d67c
--- /dev/null
+++ b/elpa/dashboard-20220409.620/banners/4.txt
@@ -0,0 +1,17 @@
+_ ___ _ _
+_ ___ __ ___ __ _ ___
+__ _ ___ __ ___
+ _ ___ _
+ _ _ __ _
+ ___ __ _
+ __ _
+ _ _ _
+ _ _ _
+ _ _ _
+ __ ___
+ _ _ _ _
+ _ _
+ _ _
+ _ _
+ _
+__
diff --git a/elpa/dashboard-20220409.620/banners/emacs.png b/elpa/dashboard-20220409.620/banners/emacs.png
new file mode 100644
index 0000000..718b071
--- /dev/null
+++ b/elpa/dashboard-20220409.620/banners/emacs.png
Binary files differ
diff --git a/elpa/dashboard-20220409.620/banners/logo.png b/elpa/dashboard-20220409.620/banners/logo.png
new file mode 100644
index 0000000..c9de00c
--- /dev/null
+++ b/elpa/dashboard-20220409.620/banners/logo.png
Binary files differ
diff --git a/elpa/dashboard-20220409.620/dashboard-autoloads.el b/elpa/dashboard-20220409.620/dashboard-autoloads.el
new file mode 100644
index 0000000..6d2d64a
--- /dev/null
+++ b/elpa/dashboard-20220409.620/dashboard-autoloads.el
@@ -0,0 +1,39 @@
+;;; dashboard-autoloads.el --- automatically extracted autoloads -*- lexical-binding: t -*-
+;;
+;;; Code:
+
+(add-to-list 'load-path (directory-file-name
+ (or (file-name-directory #$) (car load-path))))
+
+
+;;;### (autoloads nil "dashboard" "dashboard.el" (0 0 0 0))
+;;; Generated autoloads from dashboard.el
+
+(autoload 'dashboard-setup-startup-hook "dashboard" "\
+Setup post initialization hooks.
+If a command line argument is provided, assume a filename and skip displaying
+Dashboard." nil nil)
+
+(register-definition-prefixes "dashboard" '("dashboard-"))
+
+;;;***
+
+;;;### (autoloads nil "dashboard-widgets" "dashboard-widgets.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from dashboard-widgets.el
+
+(register-definition-prefixes "dashboard-widgets" '("dashboard-" "org-time-less-p" "recentf-list"))
+
+;;;***
+
+;;;### (autoloads nil nil ("dashboard-pkg.el") (0 0 0 0))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; coding: utf-8
+;; End:
+;;; dashboard-autoloads.el ends here
diff --git a/elpa/dashboard-20220409.620/dashboard-pkg.el b/elpa/dashboard-20220409.620/dashboard-pkg.el
new file mode 100644
index 0000000..6b8e0da
--- /dev/null
+++ b/elpa/dashboard-20220409.620/dashboard-pkg.el
@@ -0,0 +1,12 @@
+(define-package "dashboard" "20220409.620" "A startup screen extracted from Spacemacs"
+ '((emacs "26.1"))
+ :commit "09290bf700cc269ad3c07d9518cd758b90971fcd" :authors
+ '(("Rakan Al-Hneiti" . "rakan.alhneiti@gmail.com"))
+ :maintainer
+ '("Jesús Martínez" . "jesusmartinez93@gmail.com")
+ :keywords
+ '("startup" "screen" "tools" "dashboard")
+ :url "https://github.com/emacs-dashboard/emacs-dashboard")
+;; Local Variables:
+;; no-byte-compile: t
+;; End:
diff --git a/elpa/dashboard-20220409.620/dashboard-widgets.el b/elpa/dashboard-20220409.620/dashboard-widgets.el
new file mode 100644
index 0000000..8168afe
--- /dev/null
+++ b/elpa/dashboard-20220409.620/dashboard-widgets.el
@@ -0,0 +1,1267 @@
+;;; dashboard-widgets.el --- A startup screen extracted from Spacemacs -*- lexical-binding: t -*-
+
+;; Copyright (c) 2016-2022 emacs-dashboard maintainers
+;;
+;; Author : Rakan Al-Hneiti <rakan.alhneiti@gmail.com>
+;; Maintainer : Jesús Martínez <jesusmartinez93@gmail.com>
+;; Shen, Jen-Chieh <jcs090218@gmail.com>
+;; URL : https://github.com/emacs-dashboard/emacs-dashboard
+;;
+;; This file is not part of GNU Emacs.
+;;
+;;; License: GPLv3
+;;
+;; Created: October 05, 2016
+;; Package-Version: 1.8.0-SNAPSHOT
+;; Keywords: startup, screen, tools, dashboard
+;; Package-Requires: ((emacs "26.1"))
+;;; Commentary:
+
+;; An extensible Emacs dashboard, with sections for
+;; bookmarks, projects (projectile or project.el), org-agenda and more.
+
+;;; Code:
+
+(require 'cl-lib)
+(require 'subr-x)
+(require 'image)
+
+;; Compiler pacifier
+(declare-function all-the-icons-icon-for-dir "ext:all-the-icons.el")
+(declare-function all-the-icons-icon-for-file "ext:all-the-icons.el")
+(declare-function all-the-icons-fileicon "ext:data-fileicons.el")
+(declare-function all-the-icons-octicon "ext:data-octicons.el")
+(declare-function bookmark-get-filename "ext:bookmark.el")
+(declare-function bookmark-all-names "ext:bookmark.el")
+(declare-function calendar-date-compare "ext:calendar.el")
+(declare-function projectile-cleanup-known-projects "ext:projectile.el")
+(declare-function projectile-load-known-projects "ext:projectile.el")
+(declare-function projectile-mode "ext:projectile.el")
+(declare-function projectile-relevant-known-projects "ext:projectile.el")
+;;; project.el in Emacs 26 does not contain this function
+(declare-function project-known-project-roots "ext:project.el" nil t)
+(declare-function project-forget-zombie-projects "ext:project.el" nil t)
+(declare-function org-agenda-format-item "ext:org-agenda.el")
+(declare-function org-compile-prefix-format "ext:org-agenda.el")
+(declare-function org-entry-is-done-p "ext:org.el")
+(declare-function org-in-archived-heading-p "ext:org.el")
+(declare-function org-get-category "ext:org.el")
+(declare-function org-get-deadline-time "ext:org.el")
+(declare-function org-get-heading "ext:org.el")
+(declare-function org-get-scheduled-time "ext:org.el")
+(declare-function org-get-tags "ext:org.el")
+(declare-function org-map-entries "ext:org.el")
+(declare-function org-outline-level "ext:org.el")
+(declare-function org-today "ext:org.el")
+(declare-function org-get-todo-face "ext:org.el")
+(declare-function org-get-todo-state "ext:org.el")
+(declare-function org-entry-is-todo-p "ext:org.el")
+(declare-function org-release-buffers "ext:org.el")
+(declare-function recentf-cleanup "ext:recentf.el")
+(defalias 'org-time-less-p 'time-less-p)
+(defvar org-level-faces)
+(defvar org-agenda-new-buffers)
+(defvar org-agenda-prefix-format)
+(defvar org-agenda-todo-keyword-format)
+(defvar org-todo-keywords-1)
+(defvar all-the-icons-dir-icon-alist)
+(defvar package-activated-list)
+
+(defcustom dashboard-page-separator "\n\n"
+ "Separator to use between the different pages."
+ :type 'string
+ :group 'dashboard)
+
+(defcustom dashboard-image-banner-max-height 0
+ "Maximum height of banner image.
+
+This setting applies only if Emacs supports image transforms or
+compiled with Imagemagick support. When value is non-zero the image
+banner will be resized to the specified height in pixels, with aspect
+ratio preserved."
+ :type 'integer
+ :group 'dashboard)
+
+(defcustom dashboard-image-banner-max-width 0
+ "Maximum width of banner image.
+
+This setting applies if Emacs supports image transforms or compiled
+with Imagemagick support. When value is non-zero the image banner
+will be resized to the specified width in pixels, with aspect ratio
+preserved."
+ :type 'integer
+ :group 'dashboard)
+
+(defcustom dashboard-set-heading-icons nil
+ "When non nil, heading sections will have icons."
+ :type 'boolean
+ :group 'dashboard)
+
+(defcustom dashboard-set-file-icons nil
+ "When non nil, file lists will have icons."
+ :type 'boolean
+ :group 'dashboard)
+
+(defcustom dashboard-set-navigator nil
+ "When non nil, a navigator will be displayed under the banner."
+ :type 'boolean
+ :group 'dashboard)
+
+(defcustom dashboard-set-init-info t
+ "When non nil, init info will be displayed under the banner."
+ :type 'boolean
+ :group 'dashboard)
+
+(defcustom dashboard-set-footer t
+ "When non nil, a footer will be displayed at the bottom."
+ :type 'boolean
+ :group 'dashboard)
+
+(defcustom dashboard-footer-messages
+ '("The one true editor, Emacs!"
+ "Who the hell uses VIM anyway? Go Evil!"
+ "Free as free speech, free as free Beer"
+ "Happy coding!"
+ "Vi Vi Vi, the editor of the beast"
+ "Welcome to the church of Emacs"
+ "While any text editor can save your files, only Emacs can save your soul"
+ "I showed you my source code, pls respond")
+ "A list of messages, one of which dashboard chooses to display."
+ :type 'list
+ :group 'dashboard)
+
+(defcustom dashboard-show-shortcuts t
+ "Whether to show shortcut keys for each section."
+ :type 'boolean
+ :group 'dashboard)
+
+(defconst dashboard-banners-directory
+ (concat (file-name-directory (locate-library "dashboard")) "banners/")
+ "Default banner directory.")
+
+(defconst dashboard-banner-official-png
+ (concat dashboard-banners-directory "emacs.png")
+ "Emacs banner image.")
+
+(defconst dashboard-banner-logo-png
+ (concat dashboard-banners-directory "logo.png")
+ "Emacs banner image.")
+
+(defconst dashboard-banner-length 75
+ "Width of a banner.")
+
+(defcustom dashboard-banner-logo-title "Welcome to Emacs!"
+ "Specify the startup banner."
+ :type 'string
+ :group 'dashboard)
+
+(defcustom dashboard-navigator-buttons nil
+ "Specify the navigator buttons.
+The format is: 'icon title help action face prefix suffix'.
+
+Example:
+'((\"☆\" \"Star\" \"Show stars\" (lambda (&rest _)
+ (show-stars)) 'warning \"[\" \"]\"))"
+ :type '(repeat (repeat (list string string string function symbol string string)))
+ :group 'dashboard)
+
+(defcustom dashboard-init-info
+ (lambda ()
+ (let ((package-count 0) (time (emacs-init-time)))
+ (when (bound-and-true-p package-alist)
+ (setq package-count (length package-activated-list)))
+ (when (boundp 'straight--profile-cache)
+ (setq package-count (+ (hash-table-count straight--profile-cache) package-count)))
+ (if (zerop package-count)
+ (format "Emacs started in %s" time)
+ (format "%d packages loaded in %s" package-count time))))
+ "Init info with packages loaded and init time."
+ :type '(function string)
+ :group 'dashboard)
+
+(defcustom dashboard-footer
+ (nth (random (1- (1+ (length dashboard-footer-messages)))) dashboard-footer-messages)
+ "A footer with some short message."
+ :type 'string
+ :group 'dashboard)
+
+(defcustom dashboard-footer-icon
+ (if (and (display-graphic-p)
+ (or (fboundp 'all-the-icons-fileicon)
+ (require 'all-the-icons nil 'noerror)))
+ (all-the-icons-fileicon "emacs"
+ :height 1.1
+ :v-adjust -0.05
+ :face 'font-lock-keyword-face)
+ (propertize ">" 'face 'dashboard-footer))
+ "Footer's icon."
+ :type 'string
+ :group 'dashboard)
+
+(defcustom dashboard-startup-banner 'official
+ "Specify the startup banner.
+Default value is `official', it displays the Emacs logo. `logo' displays Emacs
+alternative logo. An integer value is the index of text banner. A string
+value must be a path to a .PNG or .TXT file. If the value is nil then no banner
+is displayed."
+ :type '(choice (const :tag "offical" official)
+ (const :tag "logo" logo)
+ (string :tag "a png or txt path"))
+ :group 'dashboard)
+
+(defcustom dashboard-buffer-last-width nil
+ "Previous width of dashboard-buffer."
+ :type 'integer
+ :group 'dashboard)
+
+(defcustom dashboard-item-generators
+ '((recents . dashboard-insert-recents)
+ (bookmarks . dashboard-insert-bookmarks)
+ (projects . dashboard-insert-projects)
+ (agenda . dashboard-insert-agenda)
+ (registers . dashboard-insert-registers))
+ "Association list of items to how to generate in the startup buffer.
+Will be of the form `(list-type . list-function)'.
+Possible values for list-type are: `recents', `bookmarks', `projects',
+`agenda' ,`registers'."
+ :type '(repeat (alist :key-type symbol :value-type function))
+ :group 'dashboard)
+
+(defcustom dashboard-projects-backend 'projectile
+ "The package that supplies the list of recent projects.
+With the value `projectile', the projects widget uses the package
+projectile (available in MELPA). With the value `project-el',
+the widget uses the package project (available in GNU ELPA).
+
+To activate the projects widget, add e.g. `(projects . 10)' to
+`dashboard-items' after making sure the necessary package is
+installed."
+ :type '(choice (const :tag "Use projectile" projectile)
+ (const :tag "Use project.el" project-el))
+ :group 'dashboard)
+
+(defcustom dashboard-items
+ '((recents . 5)
+ (bookmarks . 5)
+ (agenda . 5))
+ "Association list of items to show in the startup buffer.
+Will be of the form `(list-type . list-size)'.
+If nil it is disabled. Possible values for list-type are:
+`recents' `bookmarks' `projects' `agenda' `registers'."
+ :type '(repeat (alist :key-type symbol :value-type integer))
+ :group 'dashboard)
+
+(defcustom dashboard-item-shortcuts
+ '((recents . "r")
+ (bookmarks . "m")
+ (projects . "p")
+ (agenda . "a")
+ (registers . "e"))
+ "Association list of items and their corresponding shortcuts.
+Will be of the form `(list-type . keys)' as understood by `(kbd keys)'.
+If nil, shortcuts are disabled. If an entry's value is nil, that item's
+shortcut is disbaled. See `dashboard-items' for possible values of list-type.'"
+ :type '(repeat (alist :key-type symbol :value-type string))
+ :group 'dashboard)
+
+(defcustom dashboard-item-names nil
+ "Association list of item heading names.
+When an item is nil or not present, the default name is used.
+Will be of the form `(default-name . new-name)'."
+ :type '(alist :key-type string :value-type string)
+ :options '("Recent Files:" "Bookmarks:" "Agenda for today:"
+ "Agenda for the coming week:" "Registers:" "Projects:")
+ :group 'dashboard)
+
+(defcustom dashboard-items-default-length 20
+ "Length used for startup lists with otherwise unspecified bounds.
+Set to nil for unbounded."
+ :type 'integer
+ :group 'dashboard)
+
+(defcustom dashboard-heading-icons
+ '((recents . "history")
+ (bookmarks . "bookmark")
+ (agenda . "calendar")
+ (projects . "rocket")
+ (registers . "database"))
+ "Association list for the icons of the heading sections.
+Will be of the form `(list-type . icon-name-string)`.
+If nil it is disabled. Possible values for list-type are:
+`recents' `bookmarks' `projects' `agenda' `registers'"
+ :type '(repeat (alist :key-type symbol :value-type string))
+ :group 'dashboard)
+
+(defcustom dashboard-path-style nil
+ "Style to display path."
+ :type '(choice
+ (const :tag "No specify" nil)
+ (const :tag "Truncate the beginning part of the path" truncate-beginning)
+ (const :tag "Truncate the middle part of the path" truncate-middle)
+ (const :tag "Truncate the end part of the path" truncate-end))
+ :group 'dashboard)
+
+(defcustom dashboard-path-max-length 70
+ "Maximum length for path to display."
+ :type 'integer
+ :group 'dashboard)
+
+(defcustom dashboard-path-shorten-string "..."
+ "String the that displays in the center of the path."
+ :type 'string
+ :group 'dashboard)
+
+(defvar recentf-list nil)
+
+(defvar dashboard-buffer-name)
+
+;;
+;; Faces
+;;
+(defface dashboard-text-banner
+ '((t (:inherit font-lock-keyword-face)))
+ "Face used for text banners."
+ :group 'dashboard)
+
+(defface dashboard-banner-logo-title
+ '((t :inherit default))
+ "Face used for the banner title."
+ :group 'dashboard)
+
+(defface dashboard-navigator
+ '((t (:inherit font-lock-keyword-face)))
+ "Face used for the navigator."
+ :group 'dashboard)
+
+(defface dashboard-heading
+ '((t (:inherit font-lock-keyword-face)))
+ "Face used for widget headings."
+ :group 'dashboard)
+
+(defface dashboard-items-face
+ '((t (:inherit widget-button)))
+ "Face used for items."
+ :group 'dashboard)
+
+(defface dashboard-no-items-face
+ '((t (:inherit widget-button)))
+ "Face used for no items."
+ :group 'dashboard)
+
+(defface dashboard-footer
+ '((t (:inherit font-lock-doc-face)))
+ "Face used for widget headings."
+ :group 'dashboard)
+
+(define-obsolete-face-alias
+ 'dashboard-text-banner-face 'dashboard-text-banner "1.2.6")
+(define-obsolete-face-alias
+ 'dashboard-banner-logo-title-face 'dashboard-banner-logo-title "1.2.6")
+(define-obsolete-face-alias
+ 'dashboard-heading-face 'dashboard-heading "1.2.6")
+
+;;
+;; Util
+;;
+(defmacro dashboard-mute-apply (&rest body)
+ "Execute BODY without message."
+ (declare (indent 0) (debug t))
+ `(let (message-log-max)
+ (with-temp-message (or (current-message) nil)
+ (let ((inhibit-message t)) ,@body))))
+
+(defun dashboard-funcall-fboundp (fnc &rest args)
+ "Call FNC with ARGS if exists."
+ (when (fboundp fnc) (if args (funcall fnc args) (funcall fnc))))
+
+;;
+;; Generic widget helpers
+;;
+(defun dashboard-subseq (seq end)
+ "Return the subsequence of SEQ from 0 to END."
+ (let ((len (length seq)))
+ (butlast seq (- len (min len end)))))
+
+(defun dashboard-get-shortcut-name (item)
+ "Get the shortcut name to be used for ITEM."
+ (let ((elem (rassoc item dashboard-item-shortcuts)))
+ (and elem (car elem))))
+
+(defun dashboard-get-shortcut (item)
+ "Get the shortcut to be used for ITEM."
+ (let ((elem (assq item dashboard-item-shortcuts)))
+ (and elem (cdr elem))))
+
+(defmacro dashboard-insert-shortcut (shortcut-id
+ shortcut-char
+ search-label
+ &optional no-next-line)
+ "Insert a shortcut SHORTCUT-CHAR for a given SEARCH-LABEL.
+Optionally, provide NO-NEXT-LINE to move the cursor forward a line."
+ (let* (;; Ensure punctuation and upper case in search string is not
+ ;; used to construct the `defun'
+ (name (downcase (replace-regexp-in-string "[[:punct:]]+" "" (format "%s" search-label))))
+ ;; remove symbol quote
+ (sym (intern (replace-regexp-in-string "'" "" (format "dashboard-jump-to-%s" shortcut-id)))))
+ `(progn
+ (eval-when-compile (defvar dashboard-mode-map))
+ (defun ,sym nil
+ ,(concat "Jump to " name ". This code is dynamically generated in `dashboard-insert-shortcut'.")
+ (interactive)
+ (unless (search-forward ,search-label (point-max) t)
+ (search-backward ,search-label (point-min) t))
+ ,@(unless no-next-line '((forward-line 1)))
+ (back-to-indentation))
+ (eval-after-load 'dashboard
+ (define-key dashboard-mode-map ,shortcut-char ',sym)))))
+
+(defun dashboard-append (msg &optional _messagebuf)
+ "Append MSG to dashboard buffer.
+If MESSAGEBUF is not nil then MSG is also written in message buffer."
+ (with-current-buffer (get-buffer-create dashboard-buffer-name)
+ (goto-char (point-max))
+ (let (buffer-read-only) (insert msg))))
+
+(defun dashboard-modify-heading-icons (alist)
+ "Append ALIST items to `dashboard-heading-icons' to modify icons."
+ (dolist (icon alist)
+ (add-to-list 'dashboard-heading-icons icon)))
+
+(defun dashboard-insert-page-break ()
+ "Insert a page break line in dashboard buffer."
+ (dashboard-append dashboard-page-separator))
+
+(defun dashboard-insert-heading (heading &optional shortcut)
+ "Insert a widget HEADING in dashboard buffer, adding SHORTCUT if provided."
+ (when (and (display-graphic-p) dashboard-set-heading-icons)
+ ;; Try loading `all-the-icons'
+ (unless (or (fboundp 'all-the-icons-octicon)
+ (require 'all-the-icons nil 'noerror))
+ (error "Package `all-the-icons' isn't installed"))
+
+ (insert (cond
+ ((string-equal heading "Recent Files:")
+ (all-the-icons-octicon (cdr (assoc 'recents dashboard-heading-icons))
+ :height 1.2 :v-adjust 0.0 :face 'dashboard-heading))
+ ((string-equal heading "Bookmarks:")
+ (all-the-icons-octicon (cdr (assoc 'bookmarks dashboard-heading-icons))
+ :height 1.2 :v-adjust 0.0 :face 'dashboard-heading))
+ ((or (string-equal heading "Agenda for today:")
+ (string-equal heading "Agenda for the coming week:"))
+ (all-the-icons-octicon (cdr (assoc 'agenda dashboard-heading-icons))
+ :height 1.2 :v-adjust 0.0 :face 'dashboard-heading))
+ ((string-equal heading "Registers:")
+ (all-the-icons-octicon (cdr (assoc 'registers dashboard-heading-icons))
+ :height 1.2 :v-adjust 0.0 :face 'dashboard-heading))
+ ((string-equal heading "Projects:")
+ (all-the-icons-octicon (cdr (assoc 'projects dashboard-heading-icons))
+ :height 1.2 :v-adjust 0.0 :face 'dashboard-heading))
+ (t " ")))
+ (insert " "))
+
+ (insert (propertize heading 'face 'dashboard-heading))
+
+ ;; Turn the inserted heading into an overlay, so that we may freely change
+ ;; its name without breaking any of the functions that expect the default name.
+ ;; If there isn't a suitable entry in `dashboard-item-names',
+ ;; we fallback to using HEADING. In that case we still want it to be an
+ ;; overlay to maintain consistent behavior (such as the point movement)
+ ;; between modified and default headings.
+ (let ((ov (make-overlay (- (point) (length heading)) (point) nil t)))
+ (overlay-put ov 'display (or (cdr (assoc heading dashboard-item-names)) heading))
+ (overlay-put ov 'face 'dashboard-heading))
+ (when shortcut (insert (format " (%s)" shortcut))))
+
+(defun dashboard-center-line (string)
+ "Center a STRING accoring to it's size."
+ (insert (make-string (max 0 (floor (/ (- dashboard-banner-length
+ (+ (length string) 1)) 2))) ?\ )))
+
+;;
+;; BANNER
+;;
+(defun dashboard-insert-ascii-banner-centered (file)
+ "Insert banner from FILE."
+ (let ((ascii-banner
+ (with-temp-buffer
+ (insert-file-contents file)
+ (let ((banner-width 0))
+ (while (not (eobp))
+ (let ((line-length (- (line-end-position) (line-beginning-position))))
+ (if (< banner-width line-length)
+ (setq banner-width line-length)))
+ (forward-line 1))
+ (goto-char 0)
+ (let ((margin
+ (max 0 (floor (/ (- dashboard-banner-length banner-width) 2)))))
+ (while (not (eobp))
+ (insert (make-string margin ?\ ))
+ (forward-line 1))))
+ (buffer-string))))
+ (put-text-property 0 (length ascii-banner) 'face 'dashboard-text-banner ascii-banner)
+ (insert ascii-banner)))
+
+(defun dashboard--type-is-gif-p (image-path)
+ "Return if image is a gif.
+String -> bool.
+Argument IMAGE-PATH path to the image."
+ (eq 'gif (image-type image-path)))
+
+(defun dashboard-insert-image-banner (banner)
+ "Display an image BANNER."
+ (when (file-exists-p banner)
+ (let* ((title dashboard-banner-logo-title)
+ (size-props
+ (append (when (> dashboard-image-banner-max-width 0)
+ (list :max-width dashboard-image-banner-max-width))
+ (when (> dashboard-image-banner-max-height 0)
+ (list :max-height dashboard-image-banner-max-height))))
+ (spec
+ (cond ((dashboard--type-is-gif-p banner)
+ (create-image banner))
+ ((image-type-available-p 'imagemagick)
+ (apply 'create-image banner 'imagemagick nil size-props))
+ (t
+ (apply 'create-image banner nil nil
+ (when (and (fboundp 'image-transforms-p)
+ (memq 'scale (funcall 'image-transforms-p)))
+ size-props)))))
+ ;; TODO: For some reason, `elisp-lint' is reporting error void
+ ;; function `image-size'.
+ (size (when (fboundp 'image-size) (image-size spec)))
+ (width (car size))
+ (left-margin (max 0 (floor (- dashboard-banner-length width) 2))))
+ (goto-char (point-min))
+ (insert "\n")
+ (insert (make-string left-margin ?\ ))
+ (insert-image spec)
+ (when (dashboard--type-is-gif-p banner) (image-animate spec 0 t))
+ (insert "\n\n")
+ (when title
+ (dashboard-center-line title)
+ (insert (format "%s\n\n" (propertize title 'face 'dashboard-banner-logo-title)))))))
+
+;;
+;; INIT INFO
+;;
+(defun dashboard-insert-init-info ()
+ "Insert init info when `dashboard-set-init-info' is t."
+ (when dashboard-set-init-info
+ (let ((init-info (if (functionp dashboard-init-info)
+ (funcall dashboard-init-info)
+ dashboard-init-info)))
+ (dashboard-center-line init-info)
+ (insert (propertize init-info 'face 'font-lock-comment-face)))))
+
+(defun dashboard-get-banner-path (index)
+ "Return the full path to banner with index INDEX."
+ (concat dashboard-banners-directory (format "%d.txt" index)))
+
+(defun dashboard-choose-banner ()
+ "Return the full path of a banner based on the dotfile value."
+ (when dashboard-startup-banner
+ (cond ((eq 'official dashboard-startup-banner)
+ (if (and (display-graphic-p) (image-type-available-p 'png))
+ dashboard-banner-official-png
+ (dashboard-get-banner-path 1)))
+ ((eq 'logo dashboard-startup-banner)
+ (if (and (display-graphic-p) (image-type-available-p 'png))
+ dashboard-banner-logo-png
+ (dashboard-get-banner-path 1)))
+ ((integerp dashboard-startup-banner)
+ (dashboard-get-banner-path dashboard-startup-banner))
+ ((stringp dashboard-startup-banner)
+ (if (and (file-exists-p dashboard-startup-banner)
+ (or (string-suffix-p ".txt" dashboard-startup-banner)
+ (and (display-graphic-p)
+ (image-type-available-p (intern (file-name-extension
+ dashboard-startup-banner))))))
+ dashboard-startup-banner
+ (message "could not find banner %s, use default instead" dashboard-startup-banner)
+ (dashboard-get-banner-path 1)))
+ (t (dashboard-get-banner-path 1)))))
+
+(defun dashboard-insert-banner ()
+ "Insert Banner at the top of the dashboard."
+ (goto-char (point-max))
+ (let ((banner (dashboard-choose-banner)) buffer-read-only)
+ (when banner
+ (if (image-type-available-p (intern (file-name-extension banner)))
+ (dashboard-insert-image-banner banner)
+ (dashboard-insert-ascii-banner-centered banner))
+ (dashboard-insert-navigator)
+ (dashboard-insert-init-info))))
+
+(defun dashboard-insert-navigator ()
+ "Insert Navigator of the dashboard."
+ (when (and dashboard-set-navigator dashboard-navigator-buttons)
+ (dolist (line dashboard-navigator-buttons)
+ (dolist (btn line)
+ (let* ((icon (car btn))
+ (title (cadr btn))
+ (help (or (cadr (cdr btn)) ""))
+ (action (or (cadr (cddr btn)) #'ignore))
+ (face (or (cadr (cddr (cdr btn))) 'dashboard-navigator))
+ (prefix (or (cadr (cddr (cddr btn))) (propertize "[" 'face face)))
+ (suffix (or (cadr (cddr (cddr (cdr btn)))) (propertize "]" 'face face))))
+ (widget-create 'item
+ :tag (concat
+ (when icon
+ (propertize icon 'face
+ (let ((prop-face (get-text-property 0 'face icon)))
+ (if prop-face
+ `(:inherit ,prop-face :inherit ,face)
+ `(:inherit ,face)))))
+ (when (and icon title
+ (not (string-equal icon ""))
+ (not (string-equal title "")))
+ (propertize " " 'face 'variable-pitch))
+ (when title (propertize title 'face face)))
+ :help-echo help
+ :action action
+ :button-face 'dashboard-items-face
+ :mouse-face 'highlight
+ :button-prefix prefix
+ :button-suffix suffix
+ :format "%[%t%]")
+ (insert " ")))
+ (let* ((width (current-column)))
+ (beginning-of-line)
+ (dashboard-center-line (make-string width ?\s))
+ (end-of-line))
+ (insert "\n"))
+ (insert "\n")))
+
+(defmacro dashboard-insert-section (section-name list list-size shortcut-id shortcut-char action &rest widget-params)
+ "Add a section with SECTION-NAME and LIST of LIST-SIZE items to the dashboard.
+SHORTCUT-CHAR is the keyboard shortcut used to access the section.
+ACTION is theaction taken when the user activates the widget button.
+WIDGET-PARAMS are passed to the \"widget-create\" function."
+ `(progn
+ (dashboard-insert-heading ,section-name
+ (if (and ,list ,shortcut-char dashboard-show-shortcuts) ,shortcut-char))
+ (if ,list
+ (when (and (dashboard-insert-section-list
+ ,section-name
+ (dashboard-subseq ,list ,list-size)
+ ,action
+ ,@widget-params)
+ ,shortcut-id ,shortcut-char)
+ (dashboard-insert-shortcut ,shortcut-id ,shortcut-char ,section-name))
+ (insert (propertize "\n --- No items ---" 'face 'dashboard-no-items-face)))))
+
+;;
+;; Section list
+;;
+(defmacro dashboard-insert-section-list (section-name list action &rest rest)
+ "Insert into SECTION-NAME a LIST of items, expanding ACTION and passing REST
+to widget creation."
+ `(when (car ,list)
+ (mapc
+ (lambda (el)
+ (let ((tag ,@rest))
+ (insert "\n ")
+
+ (when (and (display-graphic-p)
+ dashboard-set-file-icons
+ (or (fboundp 'all-the-icons-icon-for-dir)
+ (require 'all-the-icons nil 'noerror)))
+ (let* ((path (car (last (split-string ,@rest " - "))))
+ (icon (if (and (not (file-remote-p path))
+ (file-directory-p path))
+ (all-the-icons-icon-for-dir path nil "")
+ (cond
+ ((or (string-equal ,section-name "Agenda for today:")
+ (string-equal ,section-name "Agenda for the coming week:"))
+ (all-the-icons-octicon "primitive-dot" :height 1.0 :v-adjust 0.01))
+ ((file-remote-p path)
+ (all-the-icons-octicon "radio-tower" :height 1.0 :v-adjust 0.01))
+ (t (all-the-icons-icon-for-file (file-name-nondirectory path)
+ :v-adjust -0.05))))))
+ (setq tag (concat icon " " ,@rest))))
+
+ (widget-create 'item
+ :tag tag
+ :action ,action
+ :button-face 'dashboard-items-face
+ :mouse-face 'highlight
+ :button-prefix ""
+ :button-suffix ""
+ :format "%[%t%]")))
+ ,list)))
+
+;; Footer
+(defun dashboard-random-footer ()
+ "Return a random footer from `dashboard-footer-messages'."
+ (nth (random (length dashboard-footer-messages)) dashboard-footer-messages))
+
+(defun dashboard-insert-footer ()
+ "Insert footer of dashboard."
+ (when-let ((footer (and dashboard-set-footer (dashboard-random-footer))))
+ (insert "\n")
+ (dashboard-center-line footer)
+ (insert dashboard-footer-icon)
+ (insert " ")
+ (insert (propertize footer 'face 'dashboard-footer))
+ (insert "\n")))
+
+;;
+;; Truncate
+;;
+(defcustom dashboard-shorten-by-window-width nil
+ "Shorten path by window edges."
+ :type 'boolean
+ :group 'dashboard)
+
+(defcustom dashboard-shorten-path-offset 0
+ "Shorten path offset on the edges."
+ :type 'integer
+ :group 'dashboard)
+
+(defun dashboard-f-filename (path)
+ "Return file name from PATH."
+ (file-name-nondirectory path))
+
+(defun dashboard-f-base (path)
+ "Return directory name from PATH."
+ (file-name-nondirectory (directory-file-name (file-name-directory path))))
+
+(defun dashboard-shorten-path-beginning (path)
+ "Shorten PATH from beginning if exceeding maximum length."
+ (let* ((len-path (length path)) (len-rep (length dashboard-path-shorten-string))
+ (len-total (- dashboard-path-max-length len-rep))
+ front)
+ (if (<= len-path dashboard-path-max-length) path
+ (setq front (ignore-errors (substring path (- len-path len-total) len-path)))
+ (if front (concat dashboard-path-shorten-string front) ""))))
+
+(defun dashboard-shorten-path-middle (path)
+ "Shorten PATH from middle if exceeding maximum length."
+ (let* ((len-path (length path)) (len-rep (length dashboard-path-shorten-string))
+ (len-total (- dashboard-path-max-length len-rep))
+ (center (/ len-total 2))
+ (end-back center)
+ (start-front (- len-path center))
+ back front)
+ (if (<= len-path dashboard-path-max-length) path
+ (setq back (substring path 0 end-back)
+ front (ignore-errors (substring path start-front len-path)))
+ (if front (concat back dashboard-path-shorten-string front) ""))))
+
+(defun dashboard-shorten-path-end (path)
+ "Shorten PATH from end if exceeding maximum length."
+ (let* ((len-path (length path)) (len-rep (length dashboard-path-shorten-string))
+ (len-total (- dashboard-path-max-length len-rep))
+ back)
+ (if (<= len-path dashboard-path-max-length) path
+ (setq back (ignore-errors (substring path 0 len-total)))
+ (if (and back (< 0 dashboard-path-max-length))
+ (concat back dashboard-path-shorten-string) ""))))
+
+(defun dashboard--get-base-length (path type)
+ "Return the length of the base from the PATH by TYPE."
+ (let* ((is-dir (file-directory-p path))
+ (base (if is-dir (dashboard-f-base path) (dashboard-f-filename path)))
+ (option (cl-case type
+ (recents 'dashboard-recentf-show-base)
+ (bookmarks 'dashboard-bookmarks-show-base)
+ (projects 'dashboard-projects-show-base)))
+ (option-val (symbol-value option))
+ base-len)
+ (cl-case option-val
+ (`align (setq base-len (dashboard--align-length-by-type type)))
+ (`nil (setq base-len 0))
+ (t (setq base-len (length base))))
+ base-len))
+
+(defun dashboard-shorten-path (path type)
+ "Shorten the PATH by TYPE."
+ (setq path (abbreviate-file-name path))
+ (let ((dashboard-path-max-length
+ (if (and dashboard-path-style dashboard-shorten-by-window-width)
+ (- (window-width) (dashboard--get-base-length path type)
+ dashboard-shorten-path-offset)
+ dashboard-path-max-length)))
+ (cl-case dashboard-path-style
+ (truncate-beginning (dashboard-shorten-path-beginning path))
+ (truncate-middle (dashboard-shorten-path-middle path))
+ (truncate-end (dashboard-shorten-path-end path))
+ (t path))))
+
+(defun dashboard-shorten-paths (paths alist type)
+ "Shorten all path from PATHS by TYPE and store it to ALIST."
+ (let (lst-display abbrev (index 0))
+ (setf (symbol-value alist) nil) ; reset
+ (dolist (item paths)
+ (setq abbrev (dashboard-shorten-path item type)
+ ;; Add salt here, and use for extraction.
+ ;; See function `dashboard-extract-key-path-alist'.
+ abbrev (format "%s|%s" index abbrev))
+ ;; store `abbrev' as id; and `item' with value
+ (push (cons abbrev item) (symbol-value alist))
+ (push abbrev lst-display)
+ (cl-incf index))
+ (reverse lst-display)))
+
+(defun dashboard-extract-key-path-alist (key alist)
+ "Remove salt from KEY, and return true shorten path from ALIST."
+ (let* ((key (car (assoc key alist))) (split (split-string key "|")))
+ (nth 1 split)))
+
+(defun dashboard-expand-path-alist (key alist)
+ "Get the full path (un-shorten) using KEY from ALIST."
+ (cdr (assoc key alist)))
+
+(defun dashboard--generate-align-format (fmt len)
+ "Return FMT after inserting align LEN."
+ (let ((pos (1+ (string-match-p "%s" fmt))))
+ (concat (substring fmt 0 pos)
+ (concat "-" (number-to-string len))
+ (substring fmt pos (length fmt)))))
+
+(defun dashboard--align-length-by-type (type)
+ "Return the align length by TYPE of the section."
+ (let ((len-item (cdr (assoc type dashboard-items))) (count 0) (align-length -1)
+ len-list base)
+ (cl-case type
+ (`recents
+ (require 'recentf)
+ (setq len-list (length recentf-list))
+ (while (and (< count len-item) (< count len-list))
+ (setq base (nth count recentf-list)
+ align-length (max align-length (length (dashboard-f-filename base))))
+ (cl-incf count)))
+ (`bookmarks
+ (let ((bookmarks-lst (bookmark-all-names)))
+ (setq len-list (length bookmarks-lst))
+ (while (and (< count len-item) (< count len-list))
+ (setq base (nth count bookmarks-lst)
+ align-length (max align-length (length base)))
+ (cl-incf count))))
+ (`projects
+ (let ((projects-lst (dashboard-projects-backend-load-projects)))
+ (setq len-list (length projects-lst))
+ (while (and (< count len-item) (< count len-list))
+ (setq base (nth count projects-lst)
+ align-length (max align-length (length (dashboard-f-base base))))
+ (cl-incf count))))
+ (t (error "Unknown type for align length: %s" type)))
+ align-length))
+
+;;
+;; Recentf
+;;
+(defcustom dashboard-recentf-show-base nil
+ "Show the base file name infront of it's path."
+ :type '(choice
+ (const :tag "Don't show the base infront" nil)
+ (const :tag "Respect format" t)
+ (const :tag "Align the from base" align))
+ :group 'dashboard)
+
+(defcustom dashboard-recentf-item-format "%s %s"
+ "Format to use when showing the base of the file name."
+ :type 'string
+ :group 'dashboard)
+
+(defvar dashboard-recentf-alist nil
+ "Alist records shorten's recent files and it's full paths.")
+
+(defvar dashboard--recentf-cache-item-format nil
+ "Cache to record the new generated align format.")
+
+(defun dashboard-insert-recents (list-size)
+ "Add the list of LIST-SIZE items from recently edited files."
+ (setq dashboard--recentf-cache-item-format nil)
+ (recentf-mode)
+ (dashboard-mute-apply (recentf-cleanup))
+ (dashboard-insert-section
+ "Recent Files:"
+ (dashboard-shorten-paths recentf-list 'dashboard-recentf-alist 'recents)
+ list-size
+ 'recents
+ (dashboard-get-shortcut 'recents)
+ `(lambda (&rest _)
+ (find-file-existing (dashboard-expand-path-alist ,el dashboard-recentf-alist)))
+ (let* ((file (dashboard-expand-path-alist el dashboard-recentf-alist))
+ (filename (dashboard-f-filename file))
+ (path (dashboard-extract-key-path-alist el dashboard-recentf-alist)))
+ (cl-case dashboard-recentf-show-base
+ (`align
+ (unless dashboard--recentf-cache-item-format
+ (let* ((len-align (dashboard--align-length-by-type 'recents))
+ (new-fmt (dashboard--generate-align-format
+ dashboard-recentf-item-format len-align)))
+ (setq dashboard--recentf-cache-item-format new-fmt)))
+ (format dashboard--recentf-cache-item-format filename path))
+ (`nil path)
+ (t (format dashboard-recentf-item-format filename path))))))
+
+;;
+;; Bookmarks
+;;
+(defcustom dashboard-bookmarks-show-base t
+ "Show the base file name infront of it's path."
+ :type '(choice
+ (const :tag "Don't show the base infront" nil)
+ (const :tag "Respect format" t)
+ (const :tag "Align the from base" align))
+ :group 'dashboard)
+
+(defcustom dashboard-bookmarks-item-format "%s - %s"
+ "Format to use when showing the base of the file name."
+ :type 'string
+ :group 'dashboard)
+
+(defvar dashboard--bookmarks-cache-item-format nil
+ "Cache to record the new generated align format.")
+
+(defun dashboard-insert-bookmarks (list-size)
+ "Add the list of LIST-SIZE items of bookmarks."
+ (require 'bookmark)
+ (dashboard-insert-section
+ "Bookmarks:"
+ (dashboard-subseq (bookmark-all-names) list-size)
+ list-size
+ 'bookmarks
+ (dashboard-get-shortcut 'bookmarks)
+ `(lambda (&rest _) (bookmark-jump ,el))
+ (if-let* ((filename el)
+ (path (bookmark-get-filename el))
+ (path-shorten (dashboard-shorten-path path 'bookmarks)))
+ (cl-case dashboard-bookmarks-show-base
+ (`align
+ (unless dashboard--bookmarks-cache-item-format
+ (let* ((len-align (dashboard--align-length-by-type 'bookmarks))
+ (new-fmt (dashboard--generate-align-format
+ dashboard-bookmarks-item-format len-align)))
+ (setq dashboard--bookmarks-cache-item-format new-fmt)))
+ (format dashboard--bookmarks-cache-item-format filename path-shorten))
+ (`nil path-shorten)
+ (t (format dashboard-bookmarks-item-format filename path-shorten)))
+ el)))
+
+;;
+;; Projects
+;;
+(defcustom dashboard-projects-switch-function
+ nil
+ "Custom function to switch to projects from dashboard.
+If non-NIL, should be bound to a function with one argument. The function will
+be called with the root directory of the project to switch to."
+ :type '(choice (const :tag "Default" nil) function)
+ :group 'dashboard)
+
+(defcustom dashboard-projects-show-base nil
+ "Show the project name infront of it's path."
+ :type '(choice
+ (const :tag "Don't show the base infront" nil)
+ (const :tag "Respect format" t)
+ (const :tag "Align the from base" align))
+ :group 'dashboard)
+
+(defcustom dashboard-projects-item-format "%s %s"
+ "Format to use when showing the base of the project name."
+ :type 'string
+ :group 'dashboard)
+
+(defvar dashboard-projects-alist nil
+ "Alist records the shorten's project paths and it's full paths.")
+
+(defvar dashboard--projects-cache-item-format nil
+ "Cache to record the new generated align format.")
+
+(defun dashboard-insert-projects (list-size)
+ "Add the list of LIST-SIZE items of projects."
+ (setq dashboard--projects-cache-item-format nil)
+ (dashboard-insert-section
+ "Projects:"
+ (dashboard-shorten-paths
+ (dashboard-subseq (dashboard-projects-backend-load-projects) list-size)
+ 'dashboard-projects-alist 'projects)
+ list-size
+ 'projects
+ (dashboard-get-shortcut 'projects)
+ `(lambda (&rest _)
+ (funcall (dashboard-projects-backend-switch-function)
+ (dashboard-expand-path-alist ,el dashboard-projects-alist)))
+ (let* ((file (dashboard-expand-path-alist el dashboard-projects-alist))
+ (filename (dashboard-f-base file))
+ (path (dashboard-extract-key-path-alist el dashboard-projects-alist)))
+ (cl-case dashboard-projects-show-base
+ (`align
+ (unless dashboard--projects-cache-item-format
+ (let* ((len-align (dashboard--align-length-by-type 'projects))
+ (new-fmt (dashboard--generate-align-format
+ dashboard-projects-item-format len-align)))
+ (setq dashboard--projects-cache-item-format new-fmt)))
+ (format dashboard--projects-cache-item-format filename path))
+ (`nil path)
+ (t (format dashboard-projects-item-format filename path))))))
+
+(defun dashboard-projects-backend-load-projects ()
+ "Depending on `dashboard-projects-backend' load corresponding backend.
+Return function that returns a list of projects."
+ (cl-case dashboard-projects-backend
+ (`projectile
+ (require 'projectile)
+ (dashboard-mute-apply (projectile-cleanup-known-projects))
+ (projectile-load-known-projects))
+ (`project-el
+ (require 'project)
+ (dashboard-mute-apply (dashboard-funcall-fboundp #'project-forget-zombie-projects))
+ (project-known-project-roots))
+ (t
+ (display-warning '(dashboard)
+ "Invalid value for `dashboard-projects-backend'"
+ :error))))
+
+(defun dashboard-projects-backend-switch-function ()
+ "Return the function to switch to a project.
+Custom variable `dashboard-projects-switch-function' variable takes preference
+over custom backends."
+ (or dashboard-projects-switch-function
+ (cl-case dashboard-projects-backend
+ (`projectile 'projectile-switch-project-by-name)
+ (`project-el
+ (lambda (project)
+ "This function is used to switch to `PROJECT'."
+ (let ((default-directory project))
+ (project-find-file))))
+ (t
+ (display-warning '(dashboard)
+ "Invalid value for `dashboard-projects-backend'"
+ :error)))))
+
+;;
+;; Org Agenda
+;;
+(defcustom dashboard-week-agenda t
+ "Show agenda weekly if its not nil."
+ :type 'boolean
+ :group 'dashboard)
+
+(defcustom dashboard-agenda-time-string-format "%Y-%m-%d"
+ "Format time of agenda entries."
+ :type 'string
+ :group 'dashboard)
+
+(defcustom dashboard-match-agenda-entry nil
+ "Match agenda to extra filter.
+It is the MATCH attribute for `org-map-entries'"
+ :type 'string
+ :group 'dashboard)
+
+(defcustom dashboard-agenda-release-buffers nil
+ "If not nil use `org-release-buffers' after getting the entries."
+ :type 'boolean
+ :group 'dashboard)
+
+(defcustom dashboard-filter-agenda-entry 'dashboard-filter-agenda-by-time
+ "Function to filter `org-agenda' entries."
+ :type '(choice
+ (const :tag "No filter" dashboard-no-filter-agenda)
+ (const :tag "Filter by time" dashboard-filter-agenda-by-time)
+ (const :tag "Filter by todo" dashboard-filter-agenda-by-todo)
+ (function :tag "Custom function"))
+ :group 'dashboard)
+
+(defcustom dashboard-agenda-sort-strategy nil
+ "A list of strategies to sort the agenda. If nil agenda is not sorted."
+ :type '(repeat (choice (const time-up) (const time-down)
+ (const todo-state-up) (const todo-state-down)))
+ :group 'dashboard)
+
+(defcustom dashboard-agenda-prefix-format " %i %-12:c %s "
+ "Format for each entry in the agenda.
+When the dashboard-agenda is created this format is inserted into
+`org-agenda-prefix-format' as `dashboard-agenda' and compiled with
+`org-compile-prefix-format' previous calling `dashboard-agenda-entry-format' for
+each agenda entry."
+ :type 'string
+ :group 'dashboard)
+
+(defun dashboard-agenda-entry-format ()
+ "Format agenda entry to show it on dashboard."
+ (let* ((scheduled-time (org-get-scheduled-time (point)))
+ (deadline-time (org-get-deadline-time (point)))
+ (entry-time (or scheduled-time deadline-time))
+ (item (org-agenda-format-item
+ (dashboard-agenda--formatted-time)
+ (dashboard-agenda--formatted-headline)
+ (org-outline-level)
+ (org-get-category)
+ (org-get-tags)))
+ (todo-state (org-get-todo-state))
+ (todo-index (and todo-state
+ (length (member todo-state org-todo-keywords-1))))
+ (entry-data (list 'dashboard-agenda-time entry-time
+ 'dashboard-agenda-todo-index todo-index
+ 'dashboard-agenda-file (buffer-file-name)
+ 'dashboard-agenda-loc (point))))
+ (add-text-properties 0 (length item) entry-data item)
+ item))
+
+(defun dashboard-agenda--formatted-headline ()
+ "Set agenda faces to `HEADLINE' when face text property is nil."
+ (let* ((headline (org-get-heading t t t t))
+ (todo (or (org-get-todo-state) ""))
+ (org-level-face (nth (- (org-outline-level) 1) org-level-faces))
+ (todo-state (format org-agenda-todo-keyword-format todo)))
+ (when (null (get-text-property 0 'face headline))
+ (add-face-text-property 0 (length headline) org-level-face t headline))
+ (when (null (get-text-property 0 'face todo-state))
+ (add-face-text-property 0 (length todo-state) (org-get-todo-face todo) t todo-state))
+ (concat todo-state " " headline)))
+
+(defun dashboard-agenda--formatted-time ()
+ "Get the scheduled or dead time of an entry. If no time is found return nil."
+ (when-let ((time (or (org-get-scheduled-time (point)) (org-get-deadline-time (point)))))
+ (format-time-string dashboard-agenda-time-string-format time)))
+
+(defun dashboard-due-date-for-agenda ()
+ "Return due-date for agenda period."
+ (if dashboard-week-agenda
+ (time-add (current-time) (* 86400 8))
+ (time-add (current-time) 86400)))
+
+(defun dashboard-filter-agenda-by-time ()
+ "Include entry if it has a scheduled-time or deadline-time in the future.
+An entry is included if this function returns nil and excluded if returns a
+point."
+ (let ((scheduled-time (org-get-scheduled-time (point)))
+ (deadline-time (org-get-deadline-time (point)))
+ (due-date (dashboard-due-date-for-agenda)))
+ (unless (and (not (org-entry-is-done-p))
+ (not (org-in-archived-heading-p))
+ (or (and scheduled-time
+ (org-time-less-p scheduled-time due-date))
+ (and deadline-time
+ (org-time-less-p deadline-time due-date))))
+ (point))))
+
+(defun dashboard-filter-agenda-by-todo ()
+ "Include entry if it is todo and not done.
+An entry is included if this function returns nil and excluded
+if returns a point."
+ (unless (and (org-entry-is-todo-p)
+ (not (org-entry-is-done-p))
+ (not (org-in-archived-heading-p)))
+ (point)))
+
+(defun dashboard-no-filter-agenda ()
+ "No filter agenda entries."
+ (when (org-entry-is-done-p) (point)))
+
+(defun dashboard-get-agenda ()
+ "Get agenda items for today or for a week from now."
+ (if-let ((prefix-format (assoc 'dashboard-agenda org-agenda-prefix-format)))
+ (setcdr prefix-format dashboard-agenda-prefix-format)
+ (push (cons 'dashboard-agenda dashboard-agenda-prefix-format) org-agenda-prefix-format))
+ (org-compile-prefix-format 'dashboard-agenda)
+ (prog1 (org-map-entries 'dashboard-agenda-entry-format
+ dashboard-match-agenda-entry
+ 'agenda
+ dashboard-filter-agenda-entry)
+ (dashboard-agenda--release-buffers)))
+
+(defun dashboard-agenda--release-buffers ()
+ "Release agenda buffers buffers.
+This is what `org-agenda-exit' do."
+ (when dashboard-agenda-release-buffers
+ (org-release-buffers org-agenda-new-buffers)
+ (setq org-agenda-new-buffers nil)))
+
+(defun dashboard-agenda--sorted-agenda ()
+ "Return agenda sorted by time.
+For now, it only works when dashboard-agenda has been filter by time
+and dashboard-agenda-sort is not nil."
+ (let ((agenda (dashboard-get-agenda))
+ (sort-function (dashboard-agenda--sort-function)))
+ (sort agenda sort-function)))
+
+(defun dashboard-agenda--sort-function ()
+ "Get the function use to sorted the agenda.
+Depending on the list `dashboard-agenda-sorting-strategy' use this strategies to
+build a predicate to compare each enty.
+This is similar as `org-entries-lessp' but with a different aproach."
+ (dashboard-agenda--build-sort-function dashboard-agenda-sort-strategy))
+
+(defun dashboard-agenda--build-sort-function (strategies)
+ "Build a predicate to sort the dashboard agenda.
+If `STRATEGIES' is nil then sort using the nil predicate. Look for the strategy
+predicate, the attributes of the entry and compare entries. If no predicate is
+found for the strategy it uses nil predicate."
+ (if (null strategies) (lambda (_dont _care) nil)
+ (let ((predicate (dashboard-agenda--build-sort-function-predicate
+ (car strategies)))
+ (attribute (dashboard-agenda--build-sort-function-attribute
+ (car strategies))))
+ (if (null predicate) (lambda (_dont _care) nil)
+ (lambda (entry1 entry2)
+ (dashboard-agenda--compare-entries entry1 entry2 (cdr strategies)
+ predicate attribute))))))
+
+(defun dashboard-agenda--build-sort-function-predicate (strategy)
+ "Return the predicate to compare two entryes depending on the `STRATEGY'."
+ (cl-case strategy
+ (`time-up 'org-time-less-p)
+ (`time-down (lambda (a b) (org-time-less-p b a)))
+ (`todo-state-up '>)
+ (`todo-state-down '<)))
+
+(defun dashboard-agenda--build-sort-function-attribute (strategy)
+ "Return the argument to compare two entries depending to the `STRATEGY'."
+ (cond
+ ((memq strategy '(time-up time-down)) 'dashboard-agenda-time)
+ ((memq strategy '(todo-state-up todo-state-down)) 'dashboard-agenda-todo-index)
+ (t nil)))
+
+(defun dashboard-agenda--compare-entries (entry1 entry2 strategies predicate attribute)
+ "Compare `ENTRY1' and `ENTRY2' by `ATTRIBUTE' using `PREDICATE'.
+If both attributes are nil or equals the next strategy in `STRATEGIES' is used
+to compare."
+ (let ((arg1 (get-text-property 0 attribute entry1))
+ (arg2 (get-text-property 0 attribute entry2)))
+ (cond
+ ((or (and (null arg1) (null arg2)) (equal arg1 arg2))
+ (apply (dashboard-agenda--build-sort-function strategies) (list entry1 entry2)))
+ ((null arg1) nil)
+ ((null arg2) t)
+ (t (apply predicate (list arg1 arg2))))))
+
+(defun dashboard-insert-agenda (list-size)
+ "Add the list of LIST-SIZE items of agenda."
+ (require 'org-agenda)
+ (dashboard-insert-section
+ (if dashboard-week-agenda
+ "Agenda for the coming week:"
+ "Agenda for today:")
+ (dashboard-agenda--sorted-agenda)
+ list-size
+ 'agenda
+ (dashboard-get-shortcut 'agenda)
+ `(lambda (&rest _)
+ (let ((buffer (find-file-other-window (get-text-property 0 'dashboard-agenda-file ,el))))
+ (with-current-buffer buffer
+ (goto-char (get-text-property 0 'dashboard-agenda-loc ,el))
+ (switch-to-buffer buffer))))
+ (format "%s" el)))
+
+;;
+;; Registers
+;;
+(defun dashboard-insert-registers (list-size)
+ "Add the list of LIST-SIZE items of registers."
+ (require 'register)
+ (dashboard-insert-section
+ "Registers:"
+ register-alist
+ list-size
+ 'registers
+ (dashboard-get-shortcut 'registers)
+ (lambda (&rest _) (jump-to-register (car el)))
+ (format "%c - %s" (car el) (register-describe-oneline (car el)))))
+
+(provide 'dashboard-widgets)
+;;; dashboard-widgets.el ends here
diff --git a/elpa/dashboard-20220409.620/dashboard-widgets.elc b/elpa/dashboard-20220409.620/dashboard-widgets.elc
new file mode 100644
index 0000000..1da571d
--- /dev/null
+++ b/elpa/dashboard-20220409.620/dashboard-widgets.elc
Binary files differ
diff --git a/elpa/dashboard-20220409.620/dashboard.el b/elpa/dashboard-20220409.620/dashboard.el
new file mode 100644
index 0000000..9c8b80e
--- /dev/null
+++ b/elpa/dashboard-20220409.620/dashboard.el
@@ -0,0 +1,472 @@
+;;; dashboard.el --- A startup screen extracted from Spacemacs -*- lexical-binding: t -*-
+
+;; Copyright (c) 2016-2022 emacs-dashboard maintainers
+;;
+;; Author : Rakan Al-Hneiti <rakan.alhneiti@gmail.com>
+;; Maintainer : Jesús Martínez <jesusmartinez93@gmail.com>
+;; Shen, Jen-Chieh <jcs090218@gmail.com>
+;; URL : https://github.com/emacs-dashboard/emacs-dashboard
+;;
+;; This file is not part of GNU Emacs.
+;;
+;;; License: GPLv3
+;;
+;; Created: October 05, 2016
+;; Package-Version: 1.8.0-SNAPSHOT
+;; Keywords: startup, screen, tools, dashboard
+;; Package-Requires: ((emacs "26.1"))
+;;; Commentary:
+
+;; An extensible Emacs dashboard, with sections for
+;; bookmarks, projects (projectile or project.el), org-agenda and more.
+
+;;; Code:
+
+(require 'ffap)
+(require 'recentf)
+
+(require 'dashboard-widgets)
+
+(declare-function bookmark-get-filename "ext:bookmark.el")
+(declare-function bookmark-all-names "ext:bookmark.el")
+(declare-function dashboard-ls--dirs "ext:dashboard-ls.el")
+(declare-function dashboard-ls--files "ext:dashboard-ls.el")
+(declare-function page-break-lines-mode "ext:page-break-lines.el")
+(declare-function project-forget-projects-under "ext:project.el")
+
+(defgroup dashboard nil
+ "Extensible startup screen."
+ :group 'applications)
+
+;; Custom splash screen
+(defvar dashboard-mode-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map (kbd "C-p") 'dashboard-previous-line)
+ (define-key map (kbd "C-n") 'dashboard-next-line)
+ (define-key map (kbd "<up>") 'dashboard-previous-line)
+ (define-key map (kbd "<down>") 'dashboard-next-line)
+ (define-key map (kbd "k") 'dashboard-previous-line)
+ (define-key map (kbd "j") 'dashboard-next-line)
+ (define-key map [tab] 'widget-forward)
+ (define-key map (kbd "C-i") 'widget-forward)
+ (define-key map [backtab] 'widget-backward)
+ (define-key map (kbd "RET") 'dashboard-return)
+ (define-key map [mouse-1] 'dashboard-mouse-1)
+ (define-key map (kbd "}") #'dashboard-next-section)
+ (define-key map (kbd "{") #'dashboard-previous-section)
+
+ (define-key map (kbd "<backspace>") #'dashboard-remove-item-under)
+ (define-key map (kbd "<delete>") #'dashboard-remove-item-under)
+ (define-key map (kbd "DEL") #'dashboard-remove-item-under)
+
+ (define-key map (kbd "1") #'dashboard-section-1)
+ (define-key map (kbd "2") #'dashboard-section-2)
+ (define-key map (kbd "3") #'dashboard-section-3)
+ (define-key map (kbd "4") #'dashboard-section-4)
+ (define-key map (kbd "5") #'dashboard-section-5)
+ (define-key map (kbd "6") #'dashboard-section-6)
+ (define-key map (kbd "7") #'dashboard-section-7)
+ (define-key map (kbd "8") #'dashboard-section-8)
+ (define-key map (kbd "9") #'dashboard-section-9)
+ map)
+ "Keymap for dashboard mode.")
+
+(defcustom dashboard-after-initialize-hook nil
+ "Hook that is run after dashboard buffer is initialized."
+ :group 'dashboard
+ :type 'hook)
+
+(define-derived-mode dashboard-mode special-mode "Dashboard"
+ "Dashboard major mode for startup screen."
+ :group 'dashboard
+ :syntax-table nil
+ :abbrev-table nil
+ (buffer-disable-undo)
+ (when (featurep 'whitespace) (whitespace-mode -1))
+ (when (featurep 'linum) (linum-mode -1))
+ (when (featurep 'display-line-numbers) (display-line-numbers-mode -1))
+ (when (featurep 'page-break-lines) (page-break-lines-mode 1))
+ (setq-local revert-buffer-function #'dashboard-refresh-buffer)
+ (setq inhibit-startup-screen t
+ buffer-read-only t
+ truncate-lines t))
+
+(defcustom dashboard-center-content nil
+ "Whether to center content within the window."
+ :type 'boolean
+ :group 'dashboard)
+
+(defconst dashboard-buffer-name "*dashboard*"
+ "Dashboard's buffer name.")
+
+(defvar dashboard-force-refresh nil
+ "If non-nil, force refresh dashboard buffer.")
+
+(defvar dashboard--section-starts nil
+ "List of section starting positions.")
+
+;;
+;; Util
+;;
+(defun dashboard--goto-line (line)
+ "Goto LINE."
+ (goto-char (point-min)) (forward-line (1- line)))
+
+(defmacro dashboard--save-excursion (&rest body)
+ "Execute BODY save window point."
+ (declare (indent 0) (debug t))
+ `(let ((line (line-number-at-pos nil t))
+ (column (current-column)))
+ ,@body
+ (dashboard--goto-line line)
+ (move-to-column column)))
+
+;;
+;; Core
+;;
+(defun dashboard--current-section ()
+ "Return section symbol in dashboard."
+ (save-excursion
+ (if (and (search-backward dashboard-page-separator nil t)
+ (search-forward dashboard-page-separator nil t))
+ (let ((ln (thing-at-point 'line)))
+ (cond ((string-match-p "Recent Files:" ln) 'recents)
+ ((string-match-p "Bookmarks:" ln) 'bookmarks)
+ ((string-match-p "Projects:" ln) 'projects)
+ ((string-match-p "Agenda for " ln) 'agenda)
+ ((string-match-p "Registers:" ln) 'registers)
+ ((string-match-p "List Directories:" ln) 'ls-directories)
+ ((string-match-p "List Files:" ln) 'ls-files)
+ (t (user-error "Unknown section from dashboard"))))
+ (user-error "Failed searching dashboard section"))))
+
+;;
+;; Navigation
+;;
+(defun dashboard-previous-section ()
+ "Navigate back to previous section."
+ (interactive)
+ (let ((current-position (point)) current-section-start previous-section-start)
+ (dolist (elt dashboard--section-starts)
+ (when (and current-section-start (not previous-section-start))
+ (setq previous-section-start elt))
+ (when (and (not current-section-start) (< elt current-position))
+ (setq current-section-start elt)))
+ (goto-char (if (eq current-position current-section-start)
+ previous-section-start
+ current-section-start))))
+
+(defun dashboard-next-section ()
+ "Navigate forward to next section."
+ (interactive)
+ (let ((current-position (point)) next-section-start
+ (section-starts (reverse dashboard--section-starts)))
+ (dolist (elt section-starts)
+ (when (and (not next-section-start)
+ (> elt current-position))
+ (setq next-section-start elt)))
+ (when next-section-start
+ (goto-char next-section-start))))
+
+(defun dashboard--section-lines ()
+ "Return a list of integer represent the starting line number of each section."
+ (let (pb-lst)
+ (save-excursion
+ (goto-char (point-min))
+ (while (search-forward dashboard-page-separator nil t)
+ (when (ignore-errors (dashboard--current-section))
+ (push (line-number-at-pos) pb-lst))))
+ (setq pb-lst (reverse pb-lst))
+ pb-lst))
+
+(defun dashboard--goto-section-by-index (index)
+ "Navigate to item section by INDEX."
+ (let* ((pg-lst (dashboard--section-lines))
+ (items-id (1- index))
+ (items-pg (nth items-id pg-lst))
+ (items-len (length pg-lst)))
+ (when (and items-pg (< items-id items-len))
+ (dashboard--goto-line items-pg))))
+
+(defun dashboard-section-1 ()
+ "Navigate to section 1." (interactive) (dashboard--goto-section-by-index 1))
+(defun dashboard-section-2 ()
+ "Navigate to section 2." (interactive) (dashboard--goto-section-by-index 2))
+(defun dashboard-section-3 ()
+ "Navigate to section 3." (interactive) (dashboard--goto-section-by-index 3))
+(defun dashboard-section-4 ()
+ "Navigate to section 4." (interactive) (dashboard--goto-section-by-index 4))
+(defun dashboard-section-5 ()
+ "Navigate to section 5." (interactive) (dashboard--goto-section-by-index 5))
+(defun dashboard-section-6 ()
+ "Navigate to section 6." (interactive) (dashboard--goto-section-by-index 6))
+(defun dashboard-section-7 ()
+ "Navigate to section 7." (interactive) (dashboard--goto-section-by-index 7))
+(defun dashboard-section-8 ()
+ "Navigate to section 8." (interactive) (dashboard--goto-section-by-index 8))
+(defun dashboard-section-9 ()
+ "Navigate to section 9." (interactive) (dashboard--goto-section-by-index 9))
+
+(defun dashboard-previous-line (arg)
+ "Move point up and position it at that line’s item.
+Optional prefix ARG says how many lines to move; default is one line."
+ (interactive "^p")
+ (dashboard-next-line (- arg)))
+
+(defun dashboard-next-line (arg)
+ "Move point down and position it at that line’s item.
+Optional prefix ARG says how many lines to move; default is one line."
+ ;; code heavily inspired by `dired-next-line'
+ (interactive "^p")
+ (let (line-move-visual goal-column)
+ (line-move arg t))
+ ;; We never want to move point into an invisible line. Dashboard doesn’t
+ ;; use invisible text currently but when it does we’re ready!
+ (while (and (invisible-p (point))
+ (not (if (and arg (< arg 0)) (bobp) (eobp))))
+ (forward-char (if (and arg (< arg 0)) -1 1)))
+ (beginning-of-line-text))
+
+;;
+;; ffap
+;;
+(defun dashboard--goto-section (section)
+ "Move to SECTION declares in variable `dashboard-item-shortcuts'."
+ (let ((fnc (intern (format "dashboard-jump-to-%s" section))))
+ (dashboard-funcall-fboundp fnc)))
+
+(defun dashboard--current-index (section &optional pos)
+ "Return the idex by SECTION from POS."
+ (let (target-ln section-line)
+ (save-excursion
+ (when pos (goto-char pos))
+ (setq target-ln (line-number-at-pos))
+ (dashboard--goto-section section)
+ (setq section-line (line-number-at-pos)))
+ (- target-ln section-line)))
+
+(defun dashboard--section-list (section)
+ "Return the list from SECTION."
+ (cl-case section
+ (`recents recentf-list)
+ (`bookmarks (bookmark-all-names))
+ (`projects (dashboard-projects-backend-load-projects))
+ (`ls-directories (dashboard-ls--dirs))
+ (`ls-files (dashboard-ls--files))
+ (t (user-error "Unknown section for search: %s" section))))
+
+(defun dashboard--current-item-in-path ()
+ "Return the path from current dashboard section in path."
+ (let ((section (dashboard--current-section)) path)
+ (cl-case section
+ (`bookmarks (setq path (bookmark-get-filename path)))
+ (t
+ (let ((lst (dashboard--section-list section))
+ (index (dashboard--current-index section)))
+ (setq path (nth index lst)))))
+ path))
+
+(defun dashboard--on-path-item-p ()
+ "Return non-nil if current point is on the item path from dashboard."
+ (save-excursion
+ (when (= (point) (line-end-position)) (ignore-errors (forward-char -1)))
+ (eq (get-char-property (point) 'face) 'dashboard-items-face)))
+
+(defun dashboard--ffap-guesser--adv (fnc &rest args)
+ "Advice execution around function `ffap-guesser'.
+
+Argument FNC is the adviced function.
+Optional argument ARGS adviced function arguments."
+ (cl-case major-mode
+ (`dashboard-mode
+ (or (and (dashboard--on-path-item-p)
+ (dashboard--current-item-in-path))
+ (apply fnc args))) ; fallback
+ (t (apply fnc args))))
+(advice-add 'ffap-guesser :around #'dashboard--ffap-guesser--adv)
+
+;;
+;; Removal
+;;
+(defun dashboard-remove-item-under ()
+ "Remove a item from the current item section."
+ (interactive)
+ (cl-case (dashboard--current-section)
+ (`recents (dashboard-remove-item-recentf))
+ (`bookmarks (dashboard-remove-item-bookmarks))
+ (`projects (dashboard-remove-item-projects))
+ (`agenda (dashboard-remove-item-agenda))
+ (`registers (dashboard-remove-item-registers)))
+ (dashboard--save-excursion (dashboard-refresh-buffer)))
+
+(defun dashboard-remove-item-recentf ()
+ "Remove a file from `recentf-list'."
+ (interactive)
+ (let ((path (save-excursion (end-of-line) (ffap-guesser))))
+ (setq recentf-list (delete path recentf-list)))
+ (dashboard-mute-apply (recentf-save-list)))
+
+(defun dashboard-remove-item-projects ()
+ "Remove a path from `project--list'."
+ (interactive)
+ (let ((path (save-excursion (end-of-line) (ffap-guesser))))
+ (dashboard-mute-apply
+ (cl-case dashboard-projects-backend
+ (`projectile ) ; TODO: ..
+ (`project-el (project-forget-projects-under path))))))
+
+(defun dashboard-remove-item-bookmarks ()
+ "Remove a bookmarks from `bookmark-alist'."
+ (interactive)) ; TODO: ..
+
+(defun dashboard-remove-item-agenda ()
+ "Remove an agenda from `org-agenda-files'."
+ (interactive "P")
+ (let ((agenda-file (get-text-property (point) 'dashboard-agenda-file))
+ (agenda-loc (get-text-property (point) 'dashboard-agenda-loc)))
+ (with-current-buffer (find-file-noselect agenda-file)
+ (goto-char agenda-loc)
+ (call-interactively 'org-todo))))
+
+(defun dashboard-remove-item-registers ()
+ "Remove a registers from `register-alist'."
+ (interactive)) ; TODO: ..
+
+;;
+;; Confirmation
+;;
+(defun dashboard-return ()
+ "Hit return key in dashboard buffer."
+ (interactive)
+ (let ((start-ln (line-number-at-pos)) (fd-cnt 0) diff-line entry-pt)
+ (save-excursion
+ (while (and (not diff-line)
+ (not (= (point) (point-min)))
+ (not (get-char-property (point) 'button))
+ (not (= (point) (point-max))))
+ (forward-char 1)
+ (setq fd-cnt (1+ fd-cnt))
+ (unless (= start-ln (line-number-at-pos))
+ (setq diff-line t)))
+ (unless (= (point) (point-max))
+ (setq entry-pt (point))))
+ (when (= fd-cnt 1)
+ (setq entry-pt (1- (point))))
+ (if entry-pt
+ (widget-button-press entry-pt)
+ (call-interactively #'widget-button-press))))
+
+(defun dashboard-mouse-1 ()
+ "Key for keymap `mouse-1'."
+ (interactive)
+ (let ((old-track-mouse track-mouse))
+ (when (call-interactively #'widget-button-click)
+ (setq track-mouse old-track-mouse))))
+
+;;
+;; Insertion
+;;
+(defun dashboard-maximum-section-length ()
+ "For the just-inserted section, calculate the length of the longest line."
+ (let ((max-line-length 0))
+ (save-excursion
+ (dashboard-previous-section)
+ (while (not (eobp))
+ (setq max-line-length
+ (max max-line-length
+ (- (line-end-position) (line-beginning-position))))
+ (forward-line 1)))
+ max-line-length))
+
+(defun dashboard-insert-startupify-lists ()
+ "Insert the list of widgets into the buffer."
+ (interactive)
+ (let ((buffer-exists (buffer-live-p (get-buffer dashboard-buffer-name)))
+ (recentf-is-on (recentf-enabled-p))
+ (origial-recentf-list recentf-list)
+ (dashboard-num-recents (or (cdr (assoc 'recents dashboard-items)) 0))
+ (max-line-length 0))
+ ;; disable recentf mode, so we don't flood the recent files list with org
+ ;; mode files do this by making a copy of the part of the list we'll use
+ ;; let dashboard widgets change that then restore the orginal list afterwards
+ ;; (this avoids many saves/loads that would result from disabling/enabling
+ ;; recentf-mode)
+ (when recentf-is-on
+ (setq recentf-list (dashboard-subseq recentf-list dashboard-num-recents)))
+ (when (or dashboard-force-refresh
+ (not (eq dashboard-buffer-last-width (window-width)))
+ (not buffer-exists))
+ (setq dashboard-banner-length (window-width)
+ dashboard-buffer-last-width dashboard-banner-length)
+ (with-current-buffer (get-buffer-create dashboard-buffer-name)
+ (let (buffer-read-only)
+ (erase-buffer)
+ (dashboard-insert-banner)
+ (dashboard-insert-page-break)
+ (setq dashboard--section-starts nil)
+ (mapc (lambda (els)
+ (let* ((el (or (car-safe els) els))
+ (list-size
+ (or (cdr-safe els)
+ dashboard-items-default-length))
+ (item-generator
+ (cdr-safe (assoc el dashboard-item-generators))))
+ (add-to-list 'dashboard--section-starts (point))
+ (funcall item-generator list-size)
+ (when recentf-is-on
+ (setq recentf-list origial-recentf-list))
+ (setq max-line-length
+ (max max-line-length (dashboard-maximum-section-length)))
+ (dashboard-insert-page-break)))
+ dashboard-items)
+ (when dashboard-center-content
+ (when dashboard--section-starts
+ (goto-char (car (last dashboard--section-starts))))
+ (let ((margin (floor (/ (max (- (window-width) max-line-length) 0) 2))))
+ (while (not (eobp))
+ (unless (string-suffix-p (thing-at-point 'line) dashboard-page-separator)
+ (insert (make-string margin ?\ )))
+ (forward-line 1))))
+ (dashboard-insert-footer))
+ (goto-char (point-min))
+ (dashboard-mode)))
+ (when recentf-is-on
+ (setq recentf-list origial-recentf-list))))
+
+(add-hook 'window-setup-hook
+ (lambda ()
+ (add-hook 'window-size-change-functions 'dashboard-resize-on-hook)
+ (dashboard-resize-on-hook)))
+
+(defun dashboard-refresh-buffer (&rest _)
+ "Refresh buffer."
+ (interactive)
+ (let ((dashboard-force-refresh t)) (dashboard-insert-startupify-lists))
+ (switch-to-buffer dashboard-buffer-name))
+
+(defun dashboard-resize-on-hook (&optional _)
+ "Re-render dashboard on window size change."
+ (let ((space-win (get-buffer-window dashboard-buffer-name))
+ (frame-win (frame-selected-window)))
+ (when (and space-win
+ (not (window-minibuffer-p frame-win)))
+ (with-selected-window space-win
+ (dashboard-insert-startupify-lists)))))
+
+;;;###autoload
+(defun dashboard-setup-startup-hook ()
+ "Setup post initialization hooks.
+If a command line argument is provided, assume a filename and skip displaying
+Dashboard."
+ (when (< (length command-line-args) 2)
+ (add-hook 'after-init-hook (lambda ()
+ ;; Display useful lists of items
+ (dashboard-insert-startupify-lists)))
+ (add-hook 'emacs-startup-hook (lambda ()
+ (switch-to-buffer dashboard-buffer-name)
+ (goto-char (point-min))
+ (redisplay)
+ (run-hooks 'dashboard-after-initialize-hook)))))
+
+(provide 'dashboard)
+;;; dashboard.el ends here
diff --git a/elpa/dashboard-20220409.620/dashboard.elc b/elpa/dashboard-20220409.620/dashboard.elc
new file mode 100644
index 0000000..591582f
--- /dev/null
+++ b/elpa/dashboard-20220409.620/dashboard.elc
Binary files differ
diff --git a/elpa/doom-themes-20220504.1557/doom-1337-theme.el b/elpa/doom-themes-20220504.1557/doom-1337-theme.el
new file mode 100644
index 0000000..70fa524
--- /dev/null
+++ b/elpa/doom-themes-20220504.1557/doom-1337-theme.el
@@ -0,0 +1,216 @@
+;;; doom-1337-theme.el --- inspired by 1337 Theme -*- lexical-binding: t; no-byte-compile: t; -*-
+;;
+;; Copyright (C) 2017 Mark Herpich
+;;
+;; Author: ccmywish <ccmywish@users.noreply.github.com>
+;; Created: December 6, 2020
+;; Version: 1.0.0
+;; Keywords: custom themes, faces
+;; Homepage: https://github.com/hlissner/emacs-doom-themes
+;; Package-Requires: ((emacs "25.1") (cl-lib "0.5") (doom-themes "2.2.1"))
+;;
+;;; Commentary:
+;;
+;; Ported from: https://github.com/microsoft/vscode-themes/tree/main/1337
+;;
+;;; Code:
+
+(require 'doom-themes)
+
+
+;;
+;;; Variables
+
+(defgroup doom-1337-theme nil
+ "Options for the doom-1337 theme."
+ :group 'doom-themes)
+
+(defcustom doom-1337-padded-modeline doom-themes-padded-modeline
+ "If non-nil, adds a 4px padding to the mode-line.
+Can be an integer to determine the exact padding."
+ :group 'doom-1337-theme
+ :type '(choice integer boolean))
+
+(defcustom doom-1337-blue-modeline nil
+ "If non-nil, mode-line's color will be blue instead of the default purple."
+ :group 'doom-1337-theme
+ :type '(choice integer boolean))
+
+
+;;
+;;; Theme definition
+
+(def-doom-theme doom-1337
+ "A dark theme inspired by 1337 Theme."
+
+ ;; name default 256 16
+ ((bg '("#191919" "#191919" nil))
+ (bg-alt '("#252526" "#222222" nil))
+ (base0 '("#171F24" "#111122" "black"))
+ (base1 '("#1C1C1C" "#1C1C1C" "brightblack"))
+ (base2 '("#121212" "#626262" "brightblack"))
+ (base3 '("#3D3D3D" "#3D3D3D" "brightblack"))
+ (base4 '("#4b474c" "#444444" "brightblack"))
+ (base5 '("#515151" "#515151" "brightblack"))
+ (base6 '("#6D6D6D" "#6D6D6D" "brightblack"))
+ (base7 '("#777778" "#767676" "brightblack"))
+ (base8 '("#f4f4f4" "#a8a8a8" "white"))
+ (fg '("#d4d4d4" "#d4d4d4" "brightwhite"))
+ (fg-alt '("#AEAFAD" "#bcbcbc" "white"))
+
+ (grey base7)
+ (white '("#FFFFFF" "#FFFFFF" "white"))
+ (red '("#FF5E5E" "#FF5E5E" "red"))
+ (orange '("#FC9354" "#FC9354" "brightred"))
+ (green '("#468800" "#468800" "green"))
+ (light-green '("#B5CEA8" "#BBCCAA" "green"))
+ (teal '("#35CDAF" "#33CCAA" "brightgreen"))
+ (yellow '("#E9FDAC" "#E9FDAC" "brightyellow"))
+ (light-yellow '("#FBE3BF" "#FBE3BF" "brightyellow"))
+ (blue '("#8CDAFF" "#8CDAFF" "brightblue"))
+ (dark-blue '("#6699CC" "#6699CC" "blue"))
+ (magenta '("#C586C0" "#CC88CC" "brightmagenta"))
+ (violet '("#BB80B3" "#BB88BB" "magenta"))
+ (dark-violet '("#68217A" "#662277" "magenta"))
+ (cyan '("#85DDFF" "#5FD7FF" "brightcyan"))
+ (dark-cyan '("#207FA1" "#2277AA" "cyan"))
+
+ ;; component focused
+ (bottomline-blue '("#2467D0" "#2467D0" "blue"))
+ (vcmodified-blue '("#007B9F" "#007B9F" "blue"))
+ (vcdeleted-red '("#9D0012" "#9D0012" "red"))
+
+ ;; face categories -- required for all themes
+ (highlight white)
+ (vertical-bar base2)
+ (selection base5)
+ (builtin dark-blue)
+ (comments base6)
+ (doc-comments base6)
+ (constants orange)
+ (functions blue)
+ (keywords red)
+ (methods dark-blue)
+ (operators red)
+ (type yellow)
+ (strings light-yellow)
+ (variables yellow)
+ (numbers orange)
+ (region (doom-darken base5 0.5))
+ (error red)
+ (warning yellow)
+ (success green)
+ (vc-modified vcmodified-blue)
+ (vc-added green)
+ (vc-deleted red)
+
+ ;; custom categories
+ (modeline-bg (if doom-1337-blue-modeline base8 bottomline-blue))
+ (modeline-bg-alt (doom-darken bg 0.01))
+ (modeline-fg base8)
+ (modeline-fg-alt blue)
+
+ (-modeline-pad
+ (when doom-1337-padded-modeline
+ (if (integerp doom-1337-padded-modeline) doom-1337-padded-modeline 4))))
+
+ ;;;; Base theme face overrides
+ (((highlight &override) :foreground base8)
+ (lazy-highlight :background base4 :foreground fg :weight 'bold)
+ (mode-line
+ :background modeline-bg :foreground modeline-fg
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg)))
+ (mode-line-inactive
+ :background modeline-bg-alt :foreground modeline-fg-alt
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-alt)))
+ (tooltip :background base2 :foreground fg)
+
+ ;;;; all-the-icons
+ (all-the-icons-dblue :foreground bottomline-blue)
+ ;;;; man <built-in>
+ (Man-overstrike :inherit 'bold :foreground magenta)
+ (Man-underline :inherit 'underline :foreground blue)
+ ;;;; centaur-tabs
+ (centaur-tabs-active-bar-face :background base6)
+ (centaur-tabs-selected-modified
+ :inherit 'centaur-tabs-selected :foreground fg :weight 'bold)
+ (centaur-tabs-unselected-modified
+ :inherit 'centaur-tabs-unselected :foreground fg :weight 'bold)
+ (centaur-tabs-modified-marker-selected
+ :inherit 'centaur-tabs-selected :foreground fg)
+ (centaur-tabs-modified-marker-unselected
+ :inherit 'centaur-tabs-unselected :foreground fg)
+ ;;;; company
+ (company-tooltip-selection :background region)
+ ;;;; css-mode <built-in> / scss-mode
+ (css-proprietary-property :foreground orange)
+ (css-property :foreground green)
+ (css-selector :foreground blue)
+ ;;;; dashboard
+ (dashboard-heading :foreground green :weight 'bold)
+ ;;;; dired-k
+ (dired-k-commited :foreground base4)
+ (dired-k-modified :foreground vc-modified)
+ (dired-k-ignored :foreground cyan)
+ (dired-k-added :foreground vc-added)
+ ;;;; doom-modeline
+ (doom-modeline-bar :background (if doom-1337-blue-modeline base8 bottomline-blue))
+ (doom-modeline-buffer-file :inherit 'mode-line-emphasis :weight 'bold)
+ (doom-modeline-buffer-major-mode :inherit 'doom-modeline-buffer-path)
+ (doom-modeline-buffer-minor-mode :inherit 'mode-line-emphasis :weight 'bold)
+ (doom-modeline-buffer-modified :inherit 'mode-line-emphasis :weight 'bold)
+ (doom-modeline-buffer-path :inherit 'mode-line-emphasis :weight 'bold)
+ (doom-modeline-buffer-project-root :inherit 'mode-line-emphasis)
+ (doom-modeline-debug :inherit 'mode-line-emphasis)
+ (doom-modeline-evil-insert-state :foreground cyan)
+ (doom-modeline-evil-visual-state :foreground yellow)
+ (doom-modeline-info :inherit 'mode-line-emphasis)
+ (doom-modeline-lsp-success :inherit 'mode-line-emphasis :weight 'bold)
+ (doom-modeline-persp-name :inherit 'mode-line-emphasis :weight 'bold)
+ (doom-modeline-project-dir :inherit 'mode-line-emphasis :weight 'bold)
+ (doom-modeline-project-parent-dir :inherit 'mode-line-emphasis :weight 'bold)
+ (doom-modeline-urgent :inherit 'mode-line-emphasis)
+ (doom-modeline-warning :inherit 'mode-line-emphasis)
+ ;;;; doom-themes
+ (doom-themes-treemacs-root-face :foreground fg :weight 'ultra-bold :height 1.2)
+ (doom-themes-treemacs-file-face :foreground fg)
+ ;;;; ivy
+ (counsel-active-mode :foreground (doom-lighten base6 0.1))
+ (ivy-current-match :background bg)
+ (ivy-minibuffer-match-face-2 :foreground (doom-lighten base6 0.1) :weight 'extra-bold)
+ ;;;; js2-mode
+ (js2-jsdoc-tag :foreground magenta)
+ (js2-object-property :foreground cyan)
+ (js2-object-property-access :foreground cyan)
+ (js2-function-param :foreground violet)
+ (js2-jsdoc-type :foreground base8)
+ (js2-jsdoc-value :foreground cyan)
+ ;;;; lsp-mode
+ (lsp-lens-face :foreground base7 :height 0.8)
+ ;;;; org <built-in>
+ ((org-block &override) :background base2)
+ ((org-block-background &override) :background base2)
+ ((org-block-begin-line &override) :background base2)
+ ;;;; org-pomodoro
+ (org-pomodoro-mode-line :inherit 'mode-line-emphasis) ; unreadable otherwise
+ (org-pomodoro-mode-line-overtime :inherit 'org-pomodoro-mode-line)
+ (org-pomodoro-mode-line-break :inherit 'org-pomodoro-mode-line)
+ ;;;; rainbow-delimiters
+ (rainbow-delimiters-depth-1-face :foreground magenta)
+ (rainbow-delimiters-depth-2-face :foreground orange)
+ (rainbow-delimiters-depth-3-face :foreground green)
+ (rainbow-delimiters-depth-4-face :foreground cyan)
+ (rainbow-delimiters-depth-5-face :foreground violet)
+ (rainbow-delimiters-depth-6-face :foreground yellow)
+ (rainbow-delimiters-depth-7-face :foreground blue)
+ (rainbow-delimiters-depth-8-face :foreground teal)
+ (rainbow-delimiters-depth-9-face :foreground dark-cyan)
+ ;;;; rjsx-mode
+ (rjsx-tag :foreground blue)
+ (rjsx-attr :foreground cyan :slant 'italic :weight 'medium)
+ ;;;; treemacs
+ (treemacs-root-face :foreground fg :weight 'ultra-bold :height 1.2)
+ (treemacs-directory-face :foreground fg)
+ (treemacs-git-modified-face :foreground blue)))
+
+;;; doom-1337-theme.el ends here
diff --git a/elpa/doom-themes-20220504.1557/doom-Iosvkem-theme.el b/elpa/doom-themes-20220504.1557/doom-Iosvkem-theme.el
new file mode 100644
index 0000000..0fe6bf9
--- /dev/null
+++ b/elpa/doom-themes-20220504.1557/doom-Iosvkem-theme.el
@@ -0,0 +1,196 @@
+;;; doom-Iosvkem-theme.el --- Inspired by VIM Iosvkem -*- lexical-binding: t; no-byte-compile: t; -*-
+(require 'doom-themes)
+
+;;
+(defgroup doom-Iosvkem-theme nil
+ "Options for the `doom-theme.el' theme."
+ :group 'doom-themes)
+
+(defcustom doom-Iosvkem-brighter-modeline nil
+ "If non-nil, more vivid colors will be used to style the mode-line."
+ :group 'doom-Iosvkem-theme
+ :type 'boolean)
+
+(defcustom doom-Iosvkem-brighter-comments nil
+ "If non-nil, comments will be highlighted in more vivid colors."
+ :group 'doom-Iosvkem-theme
+ :type 'boolean)
+
+(defcustom doom-Iosvkem-comment-bg doom-Iosvkem-brighter-comments
+ "If non-nil, comments will have a subtle, darker background. Enhancing their
+legibility."
+ :group 'doom-Iosvkem-theme
+ :type 'boolean)
+
+(defcustom doom-Iosvkem-padded-modeline doom-themes-padded-modeline
+ "If non-nil, adds a 4px padding to the mode-line. Can be an integer to
+determine the exact padding."
+ :group 'doom-Iosvkem-theme
+ :type '(choice integer boolean))
+
+;;
+(def-doom-theme doom-Iosvkem
+ "A dark theme inspired by VIM Iosvkem"
+
+ ;; name default 256 16
+ ((bg '("#1b1d1e" "#1b1d1e" nil))
+ (bg-alt '("#262829" "#262829" nil))
+ (base0 '("#1b1d1e" "#1b1d1e" "black"))
+ (base1 '("#202020" "#202020" "brightblack"))
+ (base2 '("#303030" "#303030" "brightblack"))
+ (base3 '("#303030" "#303030" "brightblack"))
+ (base4 '("#505050" "#505050" "brightblack"))
+ (base5 '("#505050" "#505050" "brightblack"))
+ (base6 '("#808080" "#808080" "brightblack"))
+ (base7 '("#808080" "#808080" "brightblack"))
+ (base8 '("#DFDFDF" "#dfdfdf" "white"))
+ (fg '("#dddddd" "#dddddd" "white"))
+ (fg-alt '("#5B6268" "#2d2d2d" "white"))
+
+ (grey base4)
+ (red '("#d02b61" "#d02b61" "red"))
+ (orange '("#da8548" "#dd8844" "brightred"))
+ (green '("#60aa00" "#60aa00" "green"))
+ (teal '("#4db5bd" "#44b9b1" "brightgreen"))
+ (yellow '("#d08928" "#d08928" "yellow"))
+ (blue '("#6c9ef8" "#6c9ef8" "brightblue"))
+ (dark-blue '("#6688aa" "#6688aa" "blue"))
+ (magenta '("#b77fdb" "#b77fdb" "magenta"))
+ (violet '("#a9a1e1" "#a9a1e1" "brightmagenta"))
+ (cyan '("#00aa80" "#00aa80" "brightcyan"))
+ (dark-cyan '("#5699AF" "#5699AF" "cyan"))
+ (urlblue '("#57aadd" "#57aadd" "blue"))
+ (iolime '("#bbfc20" "#bbfc20" "green"))
+ (iopurple '("#bb20fc" "#bb20fc" "magenta"))
+ (iocyan '("#20bbfc" "#20bbfc" "cyan"))
+ (iopink '("#fc20bb" "#fc20bb" "red"))
+ (ioteal '("#20fcbb" "#20fcbb" "brightgreen"))
+
+ ;; face categories -- required for all themes
+ (highlight iopink)
+ (vertical-bar base2)
+ (selection bg-alt)
+ (builtin magenta)
+ (comments (if doom-Iosvkem-brighter-comments dark-cyan base6))
+ (doc-comments (doom-lighten (if doom-Iosvkem-brighter-comments dark-cyan base6) 0.25))
+ (constants green)
+ (functions magenta)
+ (keywords blue)
+ (methods teal)
+ (operators blue)
+ (type cyan)
+ (strings yellow)
+ (variables dark-cyan)
+ (numbers green)
+ (region `(,(doom-lighten (car bg-alt) 0.15) ,@(doom-lighten (cdr base0) 0.35)))
+ (error red)
+ (warning yellow)
+ (success green)
+ (vc-modified orange)
+ (vc-added green)
+ (vc-deleted red)
+
+ ;; custom categories
+ (hidden `(,(car bg) "black" "black"))
+ (-modeline-bright doom-Iosvkem-brighter-modeline)
+ (-modeline-pad
+ (when doom-Iosvkem-padded-modeline
+ (if (integerp doom-Iosvkem-padded-modeline) doom-Iosvkem-padded-modeline 4)))
+
+ (modeline-fg nil)
+ (modeline-fg-alt base6)
+
+ (modeline-bg
+ (if -modeline-bright
+ (doom-darken blue 0.45)
+ `(,(doom-darken (car bg-alt) 0.1) ,@(cdr base0))))
+ (modeline-bg-alt
+ (if -modeline-bright
+ (doom-darken blue 0.475)
+ `(,(doom-darken (car bg-alt) 0.15) ,@(cdr base0))))
+ (modeline-bg-inactive `(,(car bg-alt) ,@(cdr base1)))
+ (modeline-bg-inactive-alt `(,(doom-darken (car bg-alt) 0.1) ,@(cdr bg-alt))))
+
+
+ ;;;; Base theme face overrides
+ (((font-lock-comment-face &override)
+ :background (if doom-Iosvkem-comment-bg (doom-lighten bg 0.05))
+ :slant 'italic)
+ ((font-lock-function-name-face &override) :weight 'bold)
+ ((font-lock-doc-face &override) :slant 'normal)
+ (lazy-highlight :background iocyan :foreground bg :weight 'bold)
+ ((line-number &override) :foreground base4)
+ ((line-number-current-line &override) :foreground iocyan :background bg)
+ (mode-line
+ :background modeline-bg :foreground modeline-fg
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg)))
+ (mode-line-inactive
+ :background modeline-bg-inactive :foreground modeline-fg-alt
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive)))
+ (mode-line-emphasis :foreground (if -modeline-bright base8 highlight))
+ ((tooltip &override) :background bg)
+
+ ;;;; company
+ ((company-tooltip-selection &override) :foreground iopink)
+ ;;;; css-mode <built-in> / scss-mode
+ (css-proprietary-property :foreground orange)
+ (css-property :foreground green)
+ (css-selector :foreground blue)
+ ;;;; doom-modeline
+ (doom-modeline-bar :background (if -modeline-bright modeline-bg highlight))
+ ;;;; elscreen
+ (elscreen-tab-other-screen-face :background "#353a42" :foreground "#1e2022")
+ ;;;; highlight-escape-sequences
+ ((hes-escape-backslash-face &override) :inherit 'normal :foreground red)
+ ((hes-escape-sequence-face &override) :inherit 'normal :foreground red)
+ ;;;; highlight-numbers
+ (highlight-numbers-number :foreground numbers)
+ ;;;; ivy
+ (ivy-current-match :background dark-blue :distant-foreground base0 :weight 'normal)
+ ;;;; js2-mode
+ ((js2-function-param &override) :foreground fg :slant 'italic)
+ ((js2-object-property &override) :foreground fg)
+ ;;;; markdown-mode
+ ((markdown-bold-face &override) :foreground cyan)
+ ((markdown-code-face &override) :background (doom-lighten base3 0.05))
+ (markdown-header-delimiter-face :inherit 'bold :foreground red)
+ (markdown-header-face :inherit 'bold :foreground fg)
+ ((markdown-italic-face &override) :foreground cyan)
+ ((markdown-link-face &override) :foreground blue)
+ ((markdown-list-face &override) :foreground magenta)
+ (markdown-markup-face :foreground red)
+ ((markdown-url-face &override) :foreground base5)
+ ;;;; nav-flash
+ ((nav-flash-face &override) :background bg-alt :foreground iopink)
+ ;;;; outline
+ ((outline-1 &override) :foreground blue)
+ ((outline-2 &override) :foreground magenta)
+ ((outline-3 &override) :foreground dark-cyan)
+ ((outline-6 &override) :foreground (doom-lighten dark-cyan 0.2))
+ ((outline-7 &override) :foreground (doom-lighten blue 0.4))
+ ((outline-8 &override) :foreground (doom-lighten magenta 0.4))
+ ;;;; org <built-in>
+ (org-hide :foreground hidden)
+ (org-link :foreground urlblue :underline t)
+ ((org-block &override) :background bg-alt)
+ ((org-quote &override) :background bg-alt)
+ ((org-block-begin-line &override) :foreground comments :background bg)
+ ;;;; mic-paren
+ ((paren-face-match &override) :foreground iopink :background bg :weight 'ultra-bold)
+ ;;;; solaire-mode
+ (solaire-mode-line-face
+ :inherit 'mode-line
+ :background modeline-bg-alt
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-alt)))
+ (solaire-mode-line-inactive-face
+ :inherit 'mode-line-inactive
+ :background modeline-bg-inactive-alt
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive-alt)))
+ ;;;; whitespace <built-in>
+ ((whitespace-tab &override) :background bg))
+
+ ;;;; Base theme variable overrides-
+ ;; ()
+ )
+
+;;; doom-Iosvkem-theme.el ends here
diff --git a/elpa/doom-themes-20220504.1557/doom-acario-dark-theme.el b/elpa/doom-themes-20220504.1557/doom-acario-dark-theme.el
new file mode 100644
index 0000000..25d0815
--- /dev/null
+++ b/elpa/doom-themes-20220504.1557/doom-acario-dark-theme.el
@@ -0,0 +1,252 @@
+;;; doom-acario-dark-theme.el --- Acario dark theme -*- lexical-binding: t; no-byte-compile: t; -*-
+(require 'doom-themes)
+
+;;; Variables
+(defgroup doom-acario-dark-theme nil
+ "Options for the `doom-acario-dark' theme."
+ :group 'doom-themes)
+
+(defcustom doom-acario-dark-brighter-modeline nil
+ "If non-nil, more vivid colors will be used to style the mode-line."
+ :group 'doom-acario-dark-theme
+ :type 'boolean)
+
+(defcustom doom-acario-dark-brighter-comments nil
+ "If non-nil, comments will be highlighted in more vivid colors."
+ :group 'doom-acario-dark-theme
+ :type 'boolean)
+
+(defcustom doom-acario-dark-comment-bg doom-acario-dark-brighter-comments
+ "If non-nil, comments will have a subtle, darker background. Enhancing their
+legibility."
+ :group 'doom-acario-dark-theme
+ :type 'boolean)
+
+(defcustom doom-acario-dark-padded-modeline doom-themes-padded-modeline
+ "If non-nil, adds a 4px padding to the mode-line. Can be an integer to
+determine the exact padding."
+ :group 'doom-acario-dark-theme
+ :type '(or integer boolean))
+
+;;; Theme definition
+(def-doom-theme doom-acario-dark
+ "A dark theme inspired by Acario"
+
+ ;; name default 256 16
+ ((bg '("#0D0E16" "color-233" "black" ))
+ (bg-alt '("#040408" "color-232" "brightblack" ))
+ (base0 '("#0F1019" "color-234" "black" ))
+ (base1 '("#121212" "color-233" "brightblack" ))
+ (base2 '("#1E1E33" "color-236" "brightblack" ))
+ (base3 '("#464A56" "color-240" "brightblack" ))
+ (base4 '("#585C6C" "color-60" "brightblack" ))
+ (base5 '("#767676" "color-243" "brightblack" ))
+ (base6 '("#959EA5" "color-109" "white" ))
+ (base7 '("#B2B2B2" "color-249" "white" ))
+ (base8 '("#D0D0D0" "color-252" "brightwhite" ))
+ (fg '("#CEDBE5" "color-152" "brightwhite" ))
+ (fg-alt '("#E5F4FF" "color-195" "brightwhite" ))
+
+ (grey base5)
+
+ (red '("#D83441" "color-167" "red" ))
+ (green '("#79D836" "color-113" "green" ))
+ (yellow '("#D8B941" "color-179" "yellow" ))
+ (blue '("#3679D8" "color-68" "blue" ))
+ (magenta '("#8041D8" "color-98" "magenta" ))
+ (cyan '("#36D8BD" "color-79" "cyan" ))
+
+ (orange '("#D85F00" "color-166" "brightred" ))
+ (teal '("#2D9574" "color-29" "brightcyan" ))
+ (violet '("#AB11D8" "color-128" "brightmagenta"))
+
+ (bg-blue '("#0C213E" "color-17" "brightblack" ))
+ (dark-blue bg-blue)
+ (bg-cyan '("#092D27" "color-23" "brightblack" ))
+ (dark-cyan bg-cyan)
+
+ ;; face categories -- required for all themes
+ (highlight orange)
+ (vertical-bar base0)
+ (selection bg-blue)
+ (builtin blue)
+ (comments (if doom-acario-dark-brighter-comments bg-cyan grey))
+ (doc-comments (doom-lighten (if doom-acario-dark-brighter-comments bg-cyan green) 0.25))
+ (constants magenta)
+ (functions yellow)
+ (keywords red)
+ (methods cyan)
+ (operators blue)
+ (type blue)
+ (strings green)
+ (variables (doom-lighten cyan 0.4))
+ (numbers orange)
+ (region base2)
+ (error red)
+ (warning orange)
+ (success green)
+ (vc-modified yellow)
+ (vc-added green)
+ (vc-deleted red)
+
+ ;; custom categories
+ (hidden bg)
+ (-modeline-bright doom-acario-dark-brighter-modeline)
+ (-modeline-pad
+ (when doom-acario-dark-padded-modeline
+ (if (integerp doom-acario-dark-padded-modeline) doom-acario-dark-padded-modeline 4)))
+
+ (modeline-fg nil)
+ (modeline-fg-alt base7)
+
+ (modeline-bg
+ (if -modeline-bright
+ (doom-blend blue bg 0.35)
+ `(,(car base3) ,@(cdr base1))))
+ (modeline-bg-l
+ (if -modeline-bright
+ (doom-blend blue bg-alt 0.35)
+ `(,(car base2) ,@(cdr base0))))
+ (modeline-bg-inactive `(,(doom-darken (car bg-alt) 0.2) ,@(cdr base0)))
+ (modeline-bg-inactive-l (doom-darken bg 0.20)))
+
+
+ ;;;; Base theme face overrides
+ ((font-lock-comment-face
+ :slant 'italic
+ :foreground comments
+ :background (if doom-acario-dark-comment-bg (doom-lighten bg 0.05)))
+ (font-lock-doc-face
+ :inherit 'font-lock-comment-face
+ :foreground doc-comments)
+ ((line-number &override) :foreground base4)
+ ((line-number-current-line &override) :foreground orange :bold bold)
+ (mode-line
+ :background modeline-bg :foreground modeline-fg
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg)))
+ (mode-line-inactive
+ :background modeline-bg-inactive :foreground modeline-fg-alt
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive)))
+ (mode-line-emphasis :foreground (if -modeline-bright base8 highlight))
+
+ ;;;; all-the-icons
+ ((all-the-icons-dblue &override) :foreground teal)
+ ;;;; css-mode <built-in> / scss-mode
+ (css-proprietary-property :foreground orange)
+ (css-property :foreground green)
+ (css-selector :foreground blue)
+ ;;;; doom-modeline
+ (doom-modeline-bar :background (if -modeline-bright modeline-bg highlight))
+ (doom-modeline-buffer-file :inherit 'mode-line-buffer-id :weight 'bold)
+ (doom-modeline-buffer-path :inherit 'mode-line-emphasis :weight 'bold)
+ (doom-modeline-buffer-project-root :foreground green :weight 'bold)
+ ;;;; elscreen
+ (elscreen-tab-other-screen-face :background bg-blue :foreground fg-alt)
+ ;;;; flycheck
+ (flycheck-popup-tip-face :background bg-blue :foreground fg-alt)
+ (flycheck-posframe-info-face :background bg-blue :foreground fg-alt)
+ (flycheck-posframe-warning-face :inherit 'warning)
+ (flycheck-posframe-error-face :inherit 'error)
+ ;;;; hl-fill-column-face
+ (hl-fill-column-face :background bg-alt :foreground fg-alt)
+ ;;;; ivy
+ (ivy-current-match :background bg-blue :distant-foreground base0 :weight 'normal)
+ (ivy-posframe :background base1 :foreground fg)
+ (internal-border :background base7)
+ ;;;; lsp-mode and lsp-ui-mode
+ (lsp-ui-peek-highlight :foreground yellow)
+ (lsp-ui-sideline-symbol-info :foreground (doom-blend comments bg 0.85)
+ :background bg-alt)
+ ;;;; magit
+ (magit-blame-culprit :foreground yellow)
+ (magit-blame-header :foreground green)
+ (magit-blame-sha1 :foreground yellow)
+ (magit-blame-subject :foreground yellow)
+ (magit-blame-time :foreground green)
+ (magit-blame-name :foreground yellow)
+ (magit-blame-heading :foreground green)
+ (magit-blame-hash :foreground yellow)
+ (magit-blame-summary :foreground yellow)
+ (magit-blame-date :foreground green)
+ (magit-log-date :foreground fg-alt)
+ (magit-log-graph :foreground fg-alt)
+ (magit-reflog-amend :foreground magenta)
+ (magit-reflog-other :foreground cyan)
+ (magit-reflog-rebase :foreground magenta)
+ (magit-reflog-remote :foreground cyan)
+ (magit-reflog-reset :foreground red)
+ (magit-branch :foreground magenta :weight 'bold)
+ (magit-branch-current :foreground blue :weight 'bold :box t)
+ (magit-branch-local :foreground blue :weight 'bold)
+ (magit-branch-remote :foreground orange :weight 'bold)
+ (magit-diff-file-header :foreground yellow)
+ (magit-diff-file-heading :foreground blue :weight 'light)
+ (magit-diff-file-heading-highlight :foreground blue :weight 'bold)
+ (magit-diff-file-heading-selection :foreground blue :weight 'bold :background base1)
+ (magit-diff-hunk-heading :foreground yellow :weight 'light)
+ (magit-diff-hunk-heading-highlight :foreground yellow :weight 'bold)
+ (magit-diff-hunk-heading-selection :inherit 'selection :weight 'bold)
+ (magit-diff-added :foreground green :weight 'light)
+ (magit-diff-removed :foreground red :weight 'light)
+ (magit-diff-context :foreground fg :weight 'light)
+ (magit-diff-added-highlight :foreground green :weight 'bold)
+ (magit-diff-removed-highlight :foreground red :weight 'bold)
+ (magit-diff-context-highlight :foreground fg :weight 'bold)
+ (magit-diff-base :foreground fg :weight 'light)
+ (magit-diff-base-highlight :foreground fg :weight 'bold)
+ (magit-diff-lines-boundary :background fg :foreground base2)
+ (magit-diff-lines-heading :background fg :foreground base2)
+ (magit-hash :foreground yellow)
+ (magit-item-highlight :background grey)
+ (magit-log-author :foreground yellow)
+ (magit-log-head-label-head :background yellow :foreground bg-alt :weight 'bold)
+ (magit-log-head-label-local :background red :foreground bg-alt :weight 'bold)
+ (magit-log-head-label-remote :background green :foreground bg-alt :weight 'bold)
+ (magit-log-head-label-tags :background magenta :foreground bg-alt :weight 'bold)
+ (magit-log-head-label-wip :background cyan :foreground bg-alt :weight 'bold)
+ (magit-log-sha1 :foreground green)
+ (magit-process-ng :foreground orange :weight 'bold)
+ (magit-process-ok :foreground yellow :weight 'bold)
+ (magit-section-heading :foreground red)
+ (magit-section-highlight :weight 'bold)
+ (section-heading-selection :foreground red :weight 'bold)
+ (magit-section-title :background bg-alt :foreground red :weight 'bold)
+ (magit-cherry-equivalent :foreground magenta)
+ (magit-cherry-unmatched :foreground cyan)
+ (magit-reflog-checkout :foreground blue)
+ (magit-reflog-cherry-pick :foreground green)
+ (magit-bisect-bad :foreground red)
+ (magit-bisect-good :foreground green)
+ (magit-bisect-skip :foreground fg)
+ (magit-diff-conflict-heading :foreground fg)
+ (magit-dimmed :foreground base8)
+ (magithub-ci-no-status :foreground grey)
+ (magithub-issue-number :foreground fg)
+ (magithub-notification-reason :foreground fg)
+ ;;;; markdown-mode
+ (markdown-markup-face :foreground base5)
+ (markdown-header-face :inherit 'bold :foreground red)
+ ((markdown-code-face &override) :background (doom-lighten base3 0.05))
+ ;;;; org <built-in>
+ ((org-block &override) :background bg-alt)
+ ((org-block-begin-line &override) :background bg :foreground comments :slant 'italic)
+ ((org-quote &override) :background base1)
+ (org-hide :foreground hidden)
+ ;;;; solaire-mode
+ (solaire-mode-line-face
+ :inherit 'mode-line
+ :background modeline-bg-l
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-l)))
+ (solaire-mode-line-inactive-face
+ :inherit 'mode-line-inactive
+ :background modeline-bg-inactive-l
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive-l)))
+ ;;;; whitespace <built-in>
+ (whitespace-indentation :inherit 'default)
+ (whitespace-big-indent :inherit 'default))
+
+ ;;;; Base theme variable overrides-
+ ;; ()
+ )
+
+;;; doom-acario-dark-theme.el ends here
diff --git a/elpa/doom-themes-20220504.1557/doom-acario-light-theme.el b/elpa/doom-themes-20220504.1557/doom-acario-light-theme.el
new file mode 100644
index 0000000..1b7bbea
--- /dev/null
+++ b/elpa/doom-themes-20220504.1557/doom-acario-light-theme.el
@@ -0,0 +1,250 @@
+;;; doom-acario-light-theme.el --- Acario light theme -*- lexical-binding: t; no-byte-compile: t; -*-
+(require 'doom-themes)
+
+;;; Variables
+(defgroup doom-acario-light-theme nil
+ "Options for the `doom-acario-light' theme."
+ :group 'doom-themes)
+
+(defcustom doom-acario-light-brighter-modeline nil
+ "If non-nil, more vivid colors will be used to style the mode-line."
+ :group 'doom-acario-light-theme
+ :type 'boolean)
+
+(defcustom doom-acario-light-brighter-comments nil
+ "If non-nil, comments will be highlighted in more vivid colors."
+ :group 'doom-acario-light-theme
+ :type 'boolean)
+
+(defcustom doom-acario-light-comment-bg doom-acario-light-brighter-comments
+ "If non-nil, comments will have a subtle, darker background. Enhancing their
+legibility."
+ :group 'doom-acario-light-theme
+ :type 'boolean)
+
+(defcustom doom-acario-light-padded-modeline doom-themes-padded-modeline
+ "If non-nil, adds a 4px padding to the mode-line. Can be an integer to
+determine the exact padding."
+ :group 'doom-acario-light-theme
+ :type '(or integer boolean))
+
+;;; Theme definition
+(def-doom-theme doom-acario-light
+ "A light theme inspired by Acario light"
+
+;;;; Colors
+ ;; name default 256 16
+ ((bg '("#F5F5F9" "color-255" "black" ))
+ (bg-alt '("#E9E9F2" "color-254" "brightblack" ))
+ (base0 '("#D0D0E3" "color-188" "black" ))
+ (base1 '("#D0D0E3" "color-188" "brightblack" ))
+ (base2 '("#C0CCD0" "color-152" "brightblack" ))
+ (base3 '("#9EA6B0" "color-103" "brightblack" ))
+ (base4 '("#585C6C" "color-60" "brightblack" ))
+ (base5 '("#4E4E4E" "color-239" "brightblack" ))
+ (base6 '("#3A3A3A" "color-237" "white" ))
+ (base7 '("#303030" "color-236" "white" ))
+ (base8 '("#1E1E33" "color-236" "brightwhite" ))
+ (fg '("#0F1019" "color-234" "brightwhite" ))
+ (fg-alt '("#0D0E16" "color-233" "brightwhite" ))
+
+ (grey base5)
+
+ (red '("#D70000" "color-160" "red" ))
+ (green '("#005F00" "color-22" "green" ))
+ (yellow '("#AF8700" "color-136" "yellow" ))
+ (blue '("#1F55A0" "color-25" "blue" ))
+ (magenta '("#AF005F" "color-125" "magenta" ))
+ (cyan '("#007687" "color-30" "cyan" ))
+
+ (orange '("#D75F00" "color-166" "brightred" ))
+ (teal '("#009B7C" "color-36" "brightgreen" ))
+ (violet '("#8700AF" "color-91" "brightmagenta"))
+
+ (bg-blue '("#DEEAF8" "color-189" "blue" ))
+ (dark-blue bg-blue)
+ (bg-cyan '("#D5FAFF" "color-195" "cyan" ))
+ (dark-cyan bg-cyan)
+
+;;;; face categories -- required for all themes
+ (highlight teal)
+ (vertical-bar base0)
+ (selection bg-blue)
+ (builtin blue)
+ (comments (if doom-acario-light-brighter-comments cyan grey))
+ (doc-comments (doom-darken (if doom-acario-light-brighter-comments cyan green) 0.25))
+ (constants magenta)
+ (functions yellow)
+ (keywords red)
+ (methods cyan)
+ (operators blue)
+ (type blue)
+ (strings green)
+ (variables (doom-darken cyan 0.4))
+ (numbers orange)
+ (region base2)
+ (error red)
+ (warning orange)
+ (success green)
+ (vc-modified yellow)
+ (vc-added green)
+ (vc-deleted red)
+
+ ;; custom categories
+ (hidden bg)
+ (-modeline-dark doom-acario-light-brighter-modeline)
+ (-modeline-bright -modeline-dark)
+ (-modeline-pad
+ (when doom-acario-light-padded-modeline
+ (if (integerp doom-acario-light-padded-modeline) doom-acario-light-padded-modeline 4)))
+
+ (modeline-fg nil)
+ (modeline-fg-alt base5)
+
+ (modeline-bg
+ (if -modeline-dark
+ (doom-blend blue bg 0.35)
+ `(,(car base3) ,@(cdr base0))))
+ (modeline-bg-l
+ (if -modeline-dark
+ (doom-blend blue bg-alt 0.35)
+ `(,(car base2) ,@(cdr base0))))
+ (modeline-bg-inactive `(,(doom-darken (car bg-alt) 0.2) ,@(cdr base0)))
+ (modeline-bg-inactive-l (doom-darken bg 0.20)))
+
+ ;;;; Base theme face overrides
+ (((font-lock-comment-face &override)
+ :slant 'italic
+ :background (if doom-acario-light-comment-bg (doom-darken bg 0.05)))
+ ((line-number &override) :foreground base4)
+ ((line-number-current-line &override) :foreground orange)
+ (mode-line
+ :background modeline-bg :foreground modeline-fg
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg)))
+ (mode-line-inactive
+ :background modeline-bg-inactive :foreground modeline-fg-alt
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive)))
+ (mode-line-emphasis
+ :foreground (if -modeline-dark base8 highlight))
+
+ ;;;; elscreen
+ (elscreen-tab-other-screen-face :background bg-blue :foreground fg-alt)
+ ;;;; doom-modeline
+ (doom-modeline-bar :background (if -modeline-dark modeline-bg highlight))
+ (doom-modeline-buffer-file :inherit 'mode-line-buffer-id :weight 'bold)
+ (doom-modeline-buffer-path :inherit 'mode-line-emphasis :weight 'bold)
+ (doom-modeline-buffer-project-root :foreground green :weight 'bold)
+ ;;;; doom-themes
+ (doom-themes-treemacs-file-face :foreground comments)
+ ;;;; comments and doc
+ ;;;; css-mode <built-in> / scss-mode
+ (css-proprietary-property :foreground orange)
+ (css-property :foreground green)
+ (css-selector :foreground blue)
+ ;;;; Flycheck
+ (flycheck-popup-tip-face :background bg-blue :foreground fg-alt)
+ (flycheck-posframe-info-face :background bg-blue :foreground fg-alt)
+ (flycheck-posframe-warning-face :inherit 'warning)
+ (flycheck-posframe-error-face :inherit 'error)
+ ;;;; Magit
+ (magit-bisect-skip :foreground fg)
+ (magit-blame-date :foreground green)
+ (magit-blame-header :foreground green)
+ (magit-blame-heading :foreground green)
+ (magit-blame-name :foreground cyan)
+ (magit-blame-sha1 :foreground cyan)
+ (magit-blame-subject :foreground cyan)
+ (magit-blame-summary :foreground cyan)
+ (magit-blame-time :foreground green)
+ (magit-branch :foreground magenta :weight 'bold)
+ ((magit-branch-current &override) :weight 'bold :box t)
+ (magit-branch-local :foreground blue :weight 'bold)
+ (magit-branch-remote :foreground orange :weight 'bold)
+ (magit-cherry-equivalent :foreground magenta)
+ (magit-cherry-unmatched :foreground orange)
+ (magit-diff-added :foreground green :weight 'light)
+ (magit-diff-added-highlight :foreground green :weight 'bold)
+ (magit-diff-base :foreground fg :weight 'light)
+ (magit-diff-base-highlight :foreground fg :weight 'bold)
+ (magit-diff-conflict-heading :foreground fg)
+ (magit-diff-context :foreground fg :weight 'light)
+ (magit-diff-context-highlight :foreground fg :weight 'bold)
+ (magit-diff-file-header :foreground yellow)
+ (magit-diff-file-heading :foreground blue :weight 'light)
+ (magit-diff-file-heading-highlight :foreground blue :weight 'bold)
+ (magit-diff-file-heading-selection :foreground blue :weight 'bold :background base1)
+ (magit-diff-hunk-heading :foreground yellow :weight 'light)
+ (magit-diff-hunk-heading-highlight :foreground yellow :weight 'bold)
+ (magit-diff-hunk-heading-selection :inherit 'selection :weight 'bold)
+ (magit-diff-lines-boundary :background fg :foreground base2)
+ (magit-diff-lines-heading :background fg :foreground base2)
+ (magit-diff-removed :foreground red :weight 'light)
+ (magit-diff-removed-highlight :foreground red :weight 'bold)
+ (magit-dimmed :foreground base8)
+ (magit-hash :foreground cyan)
+ (magit-item-highlight :background grey)
+ (magit-log-author :foreground cyan)
+ (magit-log-date :foreground fg-alt)
+ (magit-log-graph :foreground fg-alt)
+ (magit-log-head-label-head :background cyan :foreground bg-alt :weight 'bold)
+ (magit-log-head-label-local :background red :foreground bg-alt :weight 'bold)
+ (magit-log-head-label-remote :background green :foreground bg-alt :weight 'bold)
+ (magit-log-head-label-tags :background magenta :foreground bg-alt :weight 'bold)
+ (magit-log-head-label-wip :background yellow :foreground bg-alt :weight 'bold)
+ (magit-log-sha1 :foreground green)
+ (magit-process-ng :foreground orange :weight 'bold)
+ (magit-process-ok :foreground cyan :weight 'bold)
+ (magit-reflog-amend :foreground magenta)
+ (magit-reflog-checkout :foreground blue)
+ (magit-reflog-cherry-pick :foreground green)
+ (magit-reflog-other :foreground yellow)
+ (magit-reflog-rebase :foreground magenta)
+ (magit-reflog-remote :foreground yellow)
+ (magit-reflog-reset :foreground red)
+ (magit-section-heading :foreground red)
+ (magit-section-highlight :weight 'bold)
+ (magit-section-title :background bg-alt :foreground red :weight 'bold)
+ (magit-section-heading-selection :foreground red :weight 'bold)
+ ;;;; magithub
+ (magithub-ci-no-status :foreground grey)
+ (magithub-issue-number :foreground fg)
+ (magithub-notification-reason :foreground fg)
+ ;;;; hl-fill-column-face
+ (hl-fill-column-face :background bg-alt :foreground fg-alt)
+ ;;;; ivy
+ (ivy-current-match :background bg-blue :distant-foreground base0 :weight 'normal)
+ (ivy-posframe :background base1 :foreground fg)
+ (internal-border :background base7)
+ ;;;; lsp-mode and lsp-ui-mode
+ (lsp-ui-peek-highlight :foreground yellow)
+ (lsp-ui-sideline-symbol-info :foreground (doom-blend comments bg 0.85)
+ :background bg-alt)
+ ;;;; markdown-mode
+ (markdown-markup-face :foreground base5)
+ (markdown-header-face :inherit 'bold :foreground red)
+ ((markdown-code-face &override) :background (doom-lighten base3 0.05))
+ ;;;; org <built-in>
+ ((org-block &override) :background bg-alt)
+ ((org-block-begin-line &override) :background bg :slant 'italic)
+ ((org-quote &override) :background base1)
+ (org-hide :foreground hidden)
+ ;;;; solaire-mode
+ (solaire-mode-line-face
+ :inherit 'mode-line
+ :background modeline-bg-l
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-l)))
+ (solaire-mode-line-inactive-face
+ :inherit 'mode-line-inactive
+ :background modeline-bg-inactive-l
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive-l)))
+ ;;;; treemacs
+ (treemacs-root-face :foreground strings :weight 'bold :height 1.2)
+ ;;;; whitespace <built-in>
+ (whitespace-indentation :inherit 'default)
+ (whitespace-big-indent :inherit 'default))
+
+ ;;;; Base theme variable overrides-
+ ;; ()
+ )
+
+;;; doom-acario-light-theme.el ends here
diff --git a/elpa/doom-themes-20220504.1557/doom-ayu-light-theme.el b/elpa/doom-themes-20220504.1557/doom-ayu-light-theme.el
new file mode 100644
index 0000000..c6b4541
--- /dev/null
+++ b/elpa/doom-themes-20220504.1557/doom-ayu-light-theme.el
@@ -0,0 +1,223 @@
+;;; doom-ayu-light-theme.el --- inspired by Ayu Mirage -*- lexical-binding: t; no-byte-compile: t; -*-
+
+(require 'doom-themes)
+
+
+;;
+;; Variables
+
+(defgroup doom-ayu-light-theme nil
+ "Options for the `doom-ayu-light' theme."
+ :group 'doom-themes)
+
+(defcustom doom-ayu-light-brighter-modeline nil
+ "If non-nil, more vivid colors will be used to style the mode-line."
+ :group 'doom-ayu-light-theme
+ :type 'boolean)
+
+(defcustom doom-ayu-light-brighter-comments nil
+ "If non-nil, comments will be highlighted in more vivid colors."
+ :group 'doom-ayu-light-theme
+ :type 'boolean)
+
+(defcustom doom-ayu-light-comment-bg doom-ayu-light-brighter-comments
+ "If non-nil, comments will have a subtle, darker background. Enhancing their
+legibility."
+ :group 'doom-ayu-light-theme
+ :type 'boolean)
+
+(defcustom doom-ayu-light-padded-modeline doom-themes-padded-modeline
+ "If non-nil, adds a 4px padding to the mode-line. Can be an integer to
+determine the exact padding."
+ :group 'doom-ayu-light-theme
+ :type '(choice integer boolean))
+
+;;
+(def-doom-theme doom-ayu-light
+ "A light theme inspired by Ayu Light"
+
+ ;; name default 256 16
+ (
+ ;; common
+ (common-accent '("#ff9940" "orange" "orange" ))
+ (common-bg '("#fafafa" "black" "black" ))
+ (common-fg '("#575f66" "grey" "grey" ))
+ (common-ui '("#ba9199" "grey" "grey" ))
+ (test '("#2ea8e6" "grey" "grey" ))
+ ;; syntax
+ (syntax-tag '("#55b4d4" "cyan" "blue" ))
+ (syntax-func '("#f2ae49" "yellow" "yellow" ))
+ (syntax-entity '("#399ee6" "blue" "blue" ))
+ (syntax-string '("#86b300" "green" "green" ))
+ (syntax-regexp '("#4cbf99" "teal" "green" ))
+ (syntax-markup '("#f07171" "red" "red" ))
+ (syntax-keyword '("#fa8d3e" "orange" "orange" ))
+ (syntax-special '("#e6ba7e" "yellow" "yellow" ))
+ (syntax-comment '("#abb0b6" "grey" "grey" ))
+ (syntax-constant '("#a37acc" "magenta" "purple" ))
+ (syntax-operator '("#ed9366" "orange" "orange" ))
+ (syntax-error '("#f51818" "red" "red" ))
+ ;; ui
+ (ui-line (doom-darken common-bg 0.07))
+ (ui-panel-shadow (doom-lighten common-bg 0.35))
+ (ui-panel-border (doom-lighten common-bg 0.45))
+ (ui-gutter-normal (doom-lighten common-ui 0.45))
+ (ui-gutter-active common-ui)
+ (ui-selection-bg (doom-blend common-bg test 0.7))
+ (ui-selection-inactive (doom-lighten test 0.93))
+ (ui-selection-border (doom-lighten test 0.93))
+ (ui-guide-active (doom-lighten common-ui 0.75))
+ (ui-guide-normal (doom-lighten common-ui 0.35))
+ (ui-org-block (doom-lighten test 0.95))
+ (elscreen-bg (doom-lighten common-fg 0.65))
+ (elscreen-fg (doom-darken common-fg 0.85))
+ ;; vcs
+ (vcs-added '("#99bf4d" "green" "green" ))
+ (vcs-modified '("#709ecc" "blue" "blue" ))
+ (vcs-removed '("#f27983" "red" "red" ))
+
+ (bg common-bg)
+ (bg-alt common-bg)
+ (base0 ui-gutter-normal)
+ (base1 ui-gutter-active)
+ (base2 ui-selection-bg)
+ (base3 ui-selection-border)
+ (base4 ui-selection-inactive)
+ (base5 ui-guide-active)
+ (base6 ui-guide-normal)
+ (base7 ui-panel-shadow)
+ (base8 ui-panel-border)
+ (fg common-fg)
+ (fg-alt common-ui)
+
+ (grey syntax-comment)
+ (red syntax-markup)
+ (orange syntax-keyword)
+ (green syntax-string)
+ (teal syntax-regexp)
+ (yellow syntax-func)
+ (blue syntax-entity)
+ (dark-blue (doom-darken syntax-entity 0.2))
+ (magenta syntax-constant)
+ (violet (doom-lighten syntax-constant 0.2))
+ (cyan syntax-tag)
+ (dark-cyan (doom-darken syntax-tag 0.2))
+
+ ;; face categories -- required for all themes
+ (highlight common-accent)
+ (vertical-bar ui-panel-border)
+ (selection ui-selection-inactive)
+ (builtin syntax-func)
+ (comments (if doom-ayu-light-brighter-comments syntax-comment elscreen-bg))
+ (doc-comments (doom-lighten (if doom-ayu-light-brighter-comments syntax-comment elscreen-bg) 0.25))
+ (constants syntax-constant)
+ (functions syntax-func)
+ (keywords syntax-keyword)
+ (methods syntax-func)
+ (operators syntax-operator)
+ (type syntax-special)
+ (strings syntax-string)
+ (variables common-fg)
+ (numbers syntax-func)
+ (region ui-selection-bg)
+ (error syntax-error)
+ (warning yellow)
+ (success green)
+ (vc-modified vcs-modified)
+ (vc-added vcs-added)
+ (vc-deleted vcs-removed)
+
+ ;; custom categories
+ (hidden (car bg))
+ (-modeline-bright doom-ayu-light-brighter-modeline)
+ (-modeline-pad
+ (when doom-ayu-light-padded-modeline
+ (if (integerp doom-ayu-light-padded-modeline) doom-ayu-light-padded-modeline 4)))
+
+ (modeline-fg common-ui)
+ (modeline-fg-alt base5)
+
+ (modeline-bg
+ (if -modeline-bright
+ (doom-lighten blue 0.475)
+ `(,(doom-lighten (car bg) 0.15) ,@(cdr base0))))
+ (modeline-bg-l
+ (if -modeline-bright
+ (doom-lighten blue 0.45)
+ `(,(doom-lighten (car bg-alt) 0.1) ,@(cdr base0))))
+ (modeline-bg-inactive `(,(doom-lighten (car bg) 0.1) ,@(cdr bg)))
+ (modeline-bg-inactive-l `(,(car bg) ,@(cdr base1))))
+
+ ;;;; Base theme face overrides
+ (((line-number &override) :foreground base5)
+ ((line-number-current-line &override) :foreground fg)
+ ((font-lock-comment-face &override)
+ :background (if doom-ayu-light-comment-bg (doom-lighten bg 0.05)))
+ (mode-line
+ :background modeline-bg :foreground modeline-fg
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg)))
+ (mode-line-inactive
+ :background modeline-bg-inactive :foreground modeline-fg
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive)))
+ (mode-line-emphasis :foreground (if -modeline-bright base8 highlight))
+
+
+ ;;;; company
+ (company-tooltip :foreground common-fg :background common-bg)
+ (company-tooltip-annotation :foreground common-fg)
+ (company-tooltip-selection :background ui-line)
+ (company-tooltip-search :foreground common-accent :weight 'bold)
+ (company-scrollbar-bg :background common-bg)
+ (company-scrollbar-fg :background syntax-comment)
+ ;;;; css-mode <built-in> / scss-mode
+ (css-proprietary-property :foreground orange)
+ (css-property :foreground green)
+ (css-selector :foreground blue)
+ ;;;; diff-mode <built-in>
+ (diff-removed :foreground vcs-removed)
+ ;;;; doom-modeline
+ (doom-modeline-bar :background (if -modeline-bright modeline-bg highlight) :weight 'normal)
+ (doom-modeline-buffer-file :inherit 'mode-line-buffer-id :weight 'normal)
+ (doom-modeline-buffer-path :inherit 'mode-line-emphasis :weight 'normal)
+ (doom-modeline-buffer-project-root :foreground green :weight 'normal)
+ ;;;; elscreen
+ (elscreen-tab-other-screen-face :background elscreen-bg :foreground elscreen-fg)
+ ;;;; highlight-numbers
+ (highlight-numbers-number :foreground syntax-func :weight 'normal)
+ ;;;; ivy
+ (ivy-current-match :background ui-line)
+ (ivy-minibuffer-match-face-1 :foreground common-accent :weight 'bold)
+ (ivy-minibuffer-match-face-2 :foreground common-accent :weight 'bold)
+ (ivy-minibuffer-match-face-3 :foreground common-accent :weight 'bold)
+ (ivy-minibuffer-match-face-4 :foreground common-accent :weight 'bold)
+ ;;;; js2-mode
+ (js2-object-property :foreground common-fg)
+ ;;;; LaTeX-mode
+ (font-latex-math-face :foreground green)
+ ;;;; markdown-mode
+ (markdown-markup-face :foreground base5)
+ (markdown-header-face :inherit 'bold :foreground red)
+ ((markdown-code-face &override) :background (doom-lighten common-bg 0.05))
+ ;;;; org <built-in>
+ (org-hide :foreground hidden)
+ (org-headline-done :foreground syntax-comment)
+ (org-document-info-keyword :foreground comments)
+ ;;;; rjsx-mode
+ (rjsx-tag :foreground cyan)
+ (rjsx-tag-bracket-face :foreground (doom-lighten cyan 0.5))
+ (rjsx-attr :foreground syntax-func)
+ ;;;; solaire-mode
+ (solaire-mode-line-face
+ :inherit 'mode-line
+ :background modeline-bg-l
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-l)))
+ (solaire-mode-line-inactive-face
+ :inherit 'mode-line-inactive
+ :background modeline-bg-inactive-l
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive-l)))
+ ;;;; web-mode
+ (web-mode-html-tag-face :foreground cyan)
+ (web-mode-html-tag-bracket-face :foreground (doom-lighten cyan 0.5))
+ (web-mode-html-attr-name-face :foreground syntax-func)))
+
+;;; doom-ayu-light-theme.el ends here
diff --git a/elpa/doom-themes-20220504.1557/doom-ayu-mirage-theme.el b/elpa/doom-themes-20220504.1557/doom-ayu-mirage-theme.el
new file mode 100644
index 0000000..020e178
--- /dev/null
+++ b/elpa/doom-themes-20220504.1557/doom-ayu-mirage-theme.el
@@ -0,0 +1,223 @@
+;;; doom-ayu-light-theme.el --- inspired by Ayu Mirage -*- lexical-binding: t; no-byte-compile: t; -*-
+
+(require 'doom-themes)
+
+
+;;
+;; Variables
+
+(defgroup doom-ayu-mirage-theme nil
+ "Options for the `doom-ayu-mirage' theme."
+ :group 'doom-themes)
+
+(defcustom doom-ayu-mirage-brighter-modeline nil
+ "If non-nil, more vivid colors will be used to style the mode-line."
+ :group 'doom-ayu-mirage-theme
+ :type 'boolean)
+
+(defcustom doom-ayu-mirage-brighter-comments nil
+ "If non-nil, comments will be highlighted in more vivid colors."
+ :group 'doom-ayu-mirage-theme
+ :type 'boolean)
+
+(defcustom doom-ayu-mirage-comment-bg doom-ayu-mirage-brighter-comments
+ "If non-nil, comments will have a subtle, darker background. Enhancing their
+legibility."
+ :group 'doom-ayu-mirage-theme
+ :type 'boolean)
+
+(defcustom doom-ayu-mirage-padded-modeline doom-themes-padded-modeline
+ "If non-nil, adds a 4px padding to the mode-line. Can be an integer to
+determine the exact padding."
+ :group 'doom-ayu-mirage-theme
+ :type '(choice integer boolean))
+
+;;
+(def-doom-theme doom-ayu-mirage
+ "A dark theme inspired by Ayu Mirage"
+
+ ;; name default 256 16
+ (
+ ;; common
+ (common-accent '("#ffcc66" "orange" "orange" ))
+ (common-bg '("#1f2430" "black" "black" ))
+ (common-fg '("#cbccc6" "grey" "grey" ))
+ (common-ui '("#707a8c" "grey" "grey" ))
+ (test '("#7399e6" "grey" "grey" ))
+ ;; syntax
+ (syntax-tag '("#5ccfe6" "cyan" "blue" ))
+ (syntax-func '("#ffd580" "yellow" "yellow" ))
+ (syntax-entity '("#73d0ff" "blue" "blue" ))
+ (syntax-string '("#bae67e" "green" "green" ))
+ (syntax-regexp '("#95e6cb" "teal" "green" ))
+ (syntax-markup '("#f28779" "red" "red" ))
+ (syntax-keyword '("#ffa759" "orange" "orange" ))
+ (syntax-special '("#ffe6b3" "yellow" "yellow" ))
+ (syntax-comment '("#5c6773" "grey" "grey" ))
+ (syntax-constant '("#d4bfff" "magenta" "purple" ))
+ (syntax-operator '("#f29e74" "orange" "orange" ))
+ (syntax-error '("#ff3333" "red" "red" ))
+ ;; ui
+ (ui-line (doom-darken common-bg 0.25))
+ (ui-panel-shadow (doom-darken common-bg 0.35))
+ (ui-panel-border (doom-darken common-bg 0.45))
+ (ui-gutter-normal (doom-darken common-ui 0.45))
+ (ui-gutter-active common-ui)
+ (ui-selection-bg (doom-blend common-bg test 0.8))
+ (ui-selection-inactive (doom-lighten test 0.93))
+ (ui-selection-border (doom-lighten test 0.93))
+ (ui-guide-normal (doom-darken common-ui 0.35))
+ (ui-guide-active (doom-darken common-ui 0.75))
+ (ui-org-block (doom-darken common-bg 0.10))
+ (elscreen-bg (doom-darken common-ui 0.55))
+ (elscreen-fg ui-line)
+ ;; vcs
+ (vcs-added '("#a6cc70" "green" "green" ))
+ (vcs-modified '("#77a8d9" "blue" "blue" ))
+ (vcs-removed '("#f27983" "red" "red" ))
+
+ (bg common-bg)
+ (bg-alt ui-line)
+ (base0 ui-gutter-normal)
+ (base1 ui-gutter-active)
+ (base2 ui-selection-bg)
+ (base3 ui-org-block)
+ (base4 ui-selection-border)
+ (base5 ui-guide-normal)
+ (base6 ui-guide-normal)
+ (base7 ui-panel-shadow)
+ (base8 ui-panel-border)
+ (fg common-fg)
+ (fg-alt common-ui)
+
+ (grey ui-line)
+ (red syntax-markup)
+ (orange syntax-keyword)
+ (green syntax-string)
+ (teal syntax-regexp)
+ (yellow syntax-func)
+ (blue syntax-entity)
+ (dark-blue (doom-darken syntax-entity 0.2))
+ (magenta syntax-constant)
+ (violet (doom-lighten syntax-constant 0.2))
+ (cyan syntax-tag)
+ (dark-cyan test)
+
+ ;; face categories -- required for all themes
+ (highlight common-accent)
+ (vertical-bar ui-panel-border)
+ (selection nil)
+ (builtin nil)
+ (comments (if doom-ayu-mirage-brighter-comments dark-cyan base5))
+ (doc-comments (doom-lighten (if doom-ayu-mirage-brighter-comments dark-cyan base5) 0.25))
+ (constants syntax-constant)
+ (functions syntax-func)
+ (keywords syntax-keyword)
+ (methods syntax-func)
+ (operators syntax-operator)
+ (type syntax-special)
+ (strings syntax-string)
+ (variables common-fg)
+ (numbers syntax-func)
+ (region ui-selection-bg)
+ (error syntax-error)
+ (warning yellow)
+ (success green)
+ (vc-modified vcs-modified)
+ (vc-added vcs-added)
+ (vc-deleted vcs-removed)
+
+ ;; custom categories
+ (hidden (car bg))
+ (-modeline-bright doom-ayu-mirage-brighter-modeline)
+ (-modeline-pad
+ (when doom-ayu-mirage-padded-modeline
+ (if (integerp doom-ayu-mirage-padded-modeline) doom-ayu-mirage-padded-modeline 4)))
+
+ (modeline-fg common-fg)
+ (modeline-fg-alt common-accent)
+
+ (modeline-bg
+ (if -modeline-bright
+ (doom-darken blue 0.45)
+ `(,(doom-darken (car bg-alt) 0.1) ,@(cdr base0))))
+ (modeline-bg-l
+ (if -modeline-bright
+ (doom-darken blue 0.475)
+ `(,(doom-darken (car bg-alt) 0.15) ,@(cdr base0))))
+ (modeline-bg-inactive `(,(car bg-alt) ,@(cdr base1)))
+ (modeline-bg-inactive-l `(,(doom-darken (car bg-alt) 0.1) ,@(cdr bg-alt))))
+
+ ;;;; Base theme face overrides
+ (((line-number &override) :foreground base4)
+ ((line-number-current-line &override) :foreground fg)
+ (diff-removed :foreground vcs-removed)
+ (font-lock-comment-face
+ :foreground comments
+ :background (if doom-ayu-mirage-comment-bg (doom-lighten bg 0.05)))
+ (font-lock-doc-face
+ :inherit 'font-lock-comment-face
+ :foreground doc-comments)
+ (mode-line
+ :background modeline-bg :foreground modeline-fg
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg)))
+ (mode-line-inactive
+ :background modeline-bg-inactive :foreground modeline-fg
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive)))
+ (mode-line-emphasis :foreground (if -modeline-bright base8 highlight))
+
+ ;;;; company
+ (company-tooltip :foreground common-fg :background common-bg)
+ (company-tooltip-annotation :foreground common-fg)
+ (company-tooltip-selection :background ui-line)
+ (company-tooltip-search :foreground common-accent :weight 'bold)
+ (company-scrollbar-bg :background common-bg)
+ (company-scrollbar-fg :background syntax-comment)
+ ;;;; css-mode <built-in> / scss-mode
+ (css-proprietary-property :foreground orange)
+ (css-property :foreground green)
+ (css-selector :foreground blue)
+ ;;;; doom-modeline
+ (doom-modeline-bar :background (if -modeline-bright modeline-bg modeline-bg) :weight 'normal)
+ (doom-modeline-buffer-file :inherit 'mode-line-buffer-id :weight 'normal)
+ (doom-modeline-buffer-path :inherit 'mode-line-emphasis :weight 'normal)
+ (doom-modeline-buffer-project-root :foreground green :weight 'normal)
+ ;;;; elscreen
+ (elscreen-tab-other-screen-face :background elscreen-bg :foreground elscreen-fg)
+ ;;;; ivy
+ (ivy-current-match :background common-bg)
+ (ivy-minibuffer-match-face-1 :foreground common-accent :weight 'bold)
+ (ivy-minibuffer-match-face-2 :foreground common-accent :weight 'bold)
+ (ivy-minibuffer-match-face-3 :foreground common-accent :weight 'bold)
+ (ivy-minibuffer-match-face-4 :foreground common-accent :weight 'bold)
+ ;;;; LaTeX-mode
+ (font-latex-math-face :foreground green)
+ ;;;; markdown-mode
+ (markdown-markup-face :foreground base5)
+ (markdown-header-face :inherit 'bold :foreground red)
+ ((markdown-code-face &override) :background (doom-lighten common-bg 0.05))
+ ;;;; org-mode
+ (org-hide :foreground hidden)
+ (org-headline-done :foreground syntax-comment)
+ (org-document-info-keyword :foreground comments)
+ ;;;; mic-paren
+ ((paren-face-match &override) :foreground fg :background ui-selection-bg :weight 'ultra-bold)
+ ;;;; rjsx-mode
+ (rjsx-tag :foreground cyan)
+ (rjsx-tag-bracket-face :foreground (doom-darken cyan 0.5))
+ (rjsx-attr :foreground syntax-func)
+ ;;;; solaire-mode
+ (solaire-mode-line-face
+ :inherit 'mode-line
+ :background modeline-bg-l
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-l)))
+ (solaire-mode-line-inactive-face
+ :inherit 'mode-line-inactive
+ :background modeline-bg-inactive-l
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive-l)))
+ ;;;; web-mode
+ (web-mode-html-tag-face :foreground cyan)
+ (web-mode-html-tag-bracket-face :foreground (doom-darken cyan 0.5))
+ (web-mode-html-attr-name-face :foreground syntax-func)))
+
+;;; doom-ayu-mirage-theme.el ends here
diff --git a/elpa/doom-themes-20220504.1557/doom-badger-theme.el b/elpa/doom-themes-20220504.1557/doom-badger-theme.el
new file mode 100644
index 0000000..805a2f3
--- /dev/null
+++ b/elpa/doom-themes-20220504.1557/doom-badger-theme.el
@@ -0,0 +1,224 @@
+;;; doom-badger-theme.el --- inspired by original badger theme -*- lexical-binding: t; no-byte-compile: t; -*-
+(require 'doom-themes)
+
+;;
+(defgroup doom-badger-theme nil
+ "Options for the `doom-badger' theme."
+ :group 'doom-themes)
+
+(defcustom doom-badger-brighter-modeline nil
+ "If non-nil, more vivid colors will be used to style the mode-line."
+ :group 'doom-badger-theme
+ :type 'boolean)
+
+(defcustom doom-badger-brighter-comments nil
+ "If non-nil, comments will be highlighted in more vivid colors."
+ :group 'doom-badger-theme
+ :type 'boolean)
+
+(defcustom doom-badger-comment-bg doom-badger-brighter-comments
+ "If non-nil, comments will have a subtle, darker background. Enhancing their
+legibility."
+ :group 'doom-badger-theme
+ :type 'boolean)
+
+(defcustom doom-badger-padded-modeline doom-themes-padded-modeline
+ "If non-nil, adds a 4px padding to the mode-line. Can be an integer to
+determine the exact padding."
+ :group 'doom-badger-theme
+ :type '(choice integer boolean))
+
+;;
+(def-doom-theme doom-badger
+ "A dark theme inspired by original badger theme"
+
+ ;; name default 256 16
+ ((bg '("#171717" nil nil )) ;; badger-bg
+ (bg-alt '("#2f2f2f" nil nil )) ;; badger-bg+1
+ (base0 '("#1D1D1D" "black" "black" )) ;; badger-hl
+ (base1 '("#1c1f24" "#1e1e1e" "brightblack" )) ;;
+ (base2 '("#202328" "#2e2e2e" "brightblack" )) ;;
+ (base3 '("#23272e" "#262626" "brightblack" )) ;;
+ (base4 '("#433F4f" "#3f3f3f" "brightblack" )) ;;
+ (base5 '("#635770" "#525252" "brightblack" )) ;;
+ (base6 '("#656868" "#6b6b6b" "brightblack" )) ;; badger-charcoal
+ (base7 '("#9ca0a4" "#979797" "brightblack" )) ;;
+ (base8 '("#DFDFDF" "#dfdfdf" "white" )) ;;
+ (fg '("#F6F3E8" "#bfbfbf" "brightwhite" )) ;; badger-fg
+ (fg-alt '("#FBF9F3" "#2d2d2d" "white" )) ;; badger-fg+1
+
+ (grey base4)
+ (red '("#E2434C" "#ff6655" "red" )) ;; badger-red
+ (orange '("#EA9847" "#dd8844" "brightred" )) ;; badger-orange
+ (green '("#86B187" "#99bb66" "green" )) ;; badger-green
+ (teal '("#65A399" "#44b9b1" "brightgreen" )) ;; badger-teal
+ (yellow '("#E0D063" "#ECBE7B" "yellow" )) ;; badger-yellow
+ (blue '("#8AC6F2" "#51afef" "brightblue" )) ;; badger-blue
+ (dark-blue '("#2257A0" "#2257A0" "blue" )) ;;
+ (magenta '("#E18Cbb" "#c678dd" "brightmagenta")) ;; badger-pink
+ (violet '("#BF93C3" "#a9a1e1" "magenta" )) ;; badger-violet
+ (cyan '("cyan" "#46D9FF" "brightcyan" )) ;; badger-succ
+ (dark-cyan '("#5699AF" "#5699AF" "cyan" )) ;;
+
+ ;; Custom
+ (olive '("#9AA68E")) ;; badger-olice
+ (lime '("#84C452")) ;; badger-lime
+ (link '("#8ACDAA")) ;; badger-link
+ (dull-red '("#A55662")) ;; badger-dull-red
+ (brown '("#AC8952")) ;; badger-brown
+ (sand '("#C7B299")) ;; badger-sand
+ (salmon '("#F28B86")) ;; badger-salmon
+ (dark-violet '("#635770")) ;; badger-dark-violet
+ ;; (darker-violet '("#433F4F")) ;; badger-darker-violet
+
+ ;; face categories -- required for all themes
+ (highlight blue)
+ (vertical-bar (doom-darken base4 0.1))
+ (selection dark-blue)
+ (builtin salmon)
+ (comments (if doom-badger-brighter-comments base7 base6))
+ (doc-comments (doom-lighten (if doom-badger-brighter-comments base7 base6) 0.25))
+ (constants dark-violet)
+ (functions orange)
+ (keywords blue)
+ (methods cyan)
+ (operators sand)
+ (type sand)
+ (strings green)
+ (variables violet)
+ (numbers fg)
+ (region `(,(doom-lighten (car bg-alt) 0.1) ,@(doom-lighten (cdr base0) 0.1)))
+ (error red)
+ (warning yellow)
+ (success green)
+ (vc-modified orange)
+ (vc-added green)
+ (vc-deleted red)
+
+ ;; custom categories
+ (hidden `(,(car bg) "black" "black"))
+ (-modeline-bright doom-badger-brighter-modeline)
+ (-modeline-pad
+ (when doom-badger-padded-modeline
+ (if (integerp doom-badger-padded-modeline) doom-badger-padded-modeline 4)))
+
+ (modeline-fg fg)
+ (modeline-fg-alt base5)
+
+ (modeline-bg
+ (if -modeline-bright
+ (doom-darken blue 0.475)
+ `(,(doom-darken (car bg-alt) 0.15) ,@(cdr base0))))
+ (modeline-bg-l
+ (if -modeline-bright
+ (doom-darken blue 0.45)
+ `(,(doom-darken (car bg-alt) 0.1) ,@(cdr base0))))
+ (modeline-bg-inactive `(,(doom-darken (car bg-alt) 0.1) ,@(cdr bg-alt)))
+ (modeline-bg-inactive-l `(,(car bg-alt) ,@(cdr base1))))
+
+
+ ;;;; Base theme face overrides
+ (((font-lock-comment-face &override)
+ ((line-number &override) :foreground base6)
+ ((line-number-current-line &override) :foreground fg)
+ :background (if doom-badger-comment-bg (doom-lighten bg 0.05)))
+ (mode-line
+ :background modeline-bg :foreground modeline-fg
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg)))
+ (mode-line-inactive
+ :background modeline-bg-inactive :foreground modeline-fg-alt
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive)))
+ (mode-line-emphasis
+ :foreground (if -modeline-bright base8 highlight))
+
+ ;;;; centaur tabs
+ (centaur-tabs-selected-modified :background bg :foreground yellow)
+ (centaur-tabs-unselected-modified :background bg-alt :foreground yellow)
+ ;;;; css-mode <built-in> / scss-mode
+ (css-proprietary-property :foreground orange)
+ (css-property :foreground green)
+ (css-selector :foreground blue)
+ ;;;; doom-modeline
+ (doom-modeline-bar :background (if -modeline-bright modeline-bg highlight))
+ (doom-modeline-buffer-file :inherit 'mode-line-buffer-id :weight 'bold)
+ (doom-modeline-buffer-path :inherit 'mode-line-emphasis :weight 'bold)
+ (doom-modeline-buffer-project-root :foreground green :weight 'bold)
+ ;;;; elscreen
+ (elscreen-tab-other-screen-face :background "#353a42" :foreground "#1e2022")
+ ;;;; ivy
+ (ivy-current-match :background dark-blue :distant-foreground base0 :weight 'normal)
+ ;;;; linum
+ (linum :foreground base6 :background base6)
+ ;;;; markdown-mode
+ (markdown-markup-face :foreground base5)
+ (markdown-header-face :inherit 'bold :foreground red)
+ ((markdown-code-face &override) :background (doom-lighten base3 0.05))
+ ;;;; org <built-in>
+ (org-agenda-date :foreground blue)
+ (org-agenda-date-today :foreground salmon :weight 'light :slant 'italic)
+ (org-agenda-structure :inherit font-lock-comment-face)
+ (org-archived :foreground fg :weight 'bold)
+ ((org-code &override) :foreground olive)
+ (org-column :background "black")
+ (org-column-title :background "black" :foreground lime :underline t)
+ (org-date :foreground link :underline t)
+ (org-deadline-announce :foreground dull-red)
+ (org-document-info-keyword :foreground olive)
+ (org-document-title :foreground salmon :height 1.50)
+ (org-done :foreground lime :strike-through t)
+ (org-footnote :foreground link :underline t)
+ (org-formula :foreground violet)
+ (org-headline-done :strike-through t :foreground base6)
+ (org-hide :foreground bg)
+ (org-hide :foreground hidden)
+ (org-level-1 :foreground blue)
+ (org-level-2 :foreground violet)
+ (org-level-3 :foreground orange)
+ (org-level-4 :foreground yellow)
+ (org-level-5 :foreground salmon)
+ (org-level-6 :foreground green)
+ (org-level-7 :foreground brown)
+ (org-level-8 :foreground teal)
+ (org-link :foreground link :underline t)
+ (org-mode-line-clock :foreground yellow)
+ (org-special-keyword :foreground olive :weight 'normal)
+ (org-table :foreground olive)
+ (org-tag :bold t :foreground orange :strike-through nil)
+ (org-todo :foreground red)
+ (org-verbatim :inherit 'org-code)
+ (org-warning :bold t :foreground magenta :weight 'bold)
+ ;;;; popup
+ (popup-tip-face :background sand :foreground "black")
+ (popup-scroll-bar-foreground-face :background dark-violet)
+ (popup-scroll-bar-background-face :background olive)
+ (popup-isearch-match :background yellow :foreground "black")
+ ;;;; solaire-mode
+ (solaire-mode-line-face
+ :inherit 'mode-line
+ :background modeline-bg-l
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-l)))
+ (solaire-mode-line-inactive-face
+ :inherit 'mode-line-inactive
+ :background modeline-bg-inactive-l
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive-l)))
+ ;;;; treemacs
+ (treemacs-directory-face :foreground base6)
+ (treemacs-git-modified-face :foreground yellow)
+ (treemacs-file-face :foreground base8)
+ (treemacs-root-face :foreground blue :weight 'bold)
+ (doom-themes-treemacs-file-face :foreground blue)
+ ;;;; web-mode
+ (web-mode-block-control-face :foreground orange)
+ (web-mode-block-delimiter-face :foreground sand)
+ (web-mode-html-attr-equal-face :foreground fg)
+ (web-mode-html-attr-name-face :foreground base8)
+ (web-mode-html-tag-bracket-face :foreground sand)
+ (web-mode-html-tag-face :foreground blue)
+ (web-mode-keyword-face :foreground blue)
+ (web-mode-variable-name-face :foreground (doom-lighten constants 0.3)))
+
+ ;;;; Base theme variable overrides-
+ ()
+ )
+
+;;; doom-badger-theme.el ends here
diff --git a/elpa/doom-themes-20220504.1557/doom-challenger-deep-theme.el b/elpa/doom-themes-20220504.1557/doom-challenger-deep-theme.el
new file mode 100644
index 0000000..1a9d6fd
--- /dev/null
+++ b/elpa/doom-themes-20220504.1557/doom-challenger-deep-theme.el
@@ -0,0 +1,157 @@
+;;; doom-challenger-deep-theme.el --- inspired by VIM Challenger Deep -*- lexical-binding: t; no-byte-compile: t; -*-
+(require 'doom-themes)
+
+;;
+(defgroup doom-challenger-deep-theme nil
+ "Options for the `doom-challenger-deep' theme."
+ :group 'doom-themes)
+
+(defcustom doom-challenger-deep-brighter-modeline nil
+ "If non-nil, more vivid colors will be used to style the mode-line."
+ :group 'doom-challenger-deep-theme
+ :type 'boolean)
+
+(defcustom doom-challenger-deep-brighter-comments nil
+ "If non-nil, comments will be highlighted in more vivid colors."
+ :group 'doom-challenger-deep-theme
+ :type 'boolean)
+
+(defcustom doom-challenger-deep-comment-bg doom-challenger-deep-brighter-comments
+ "If non-nil, comments will have a subtle, darker background. Enhancing their
+legibility."
+ :group 'doom-challenger-deep-theme
+ :type 'boolean)
+
+(defcustom doom-challenger-deep-padded-modeline doom-themes-padded-modeline
+ "If non-nil, adds a 4px padding to the mode-line. Can be an integer to
+determine the exact padding."
+ :group 'doom-challenger-deep-theme
+ :type '(choice integer boolean))
+
+;;
+(def-doom-theme doom-challenger-deep
+ "A dark theme inspired by VIM Challenger Deep"
+
+ ;; name default 256 16
+ ((bg '("#1E1C31" "#121212" nil ))
+ (bg-alt '("#12111E" "#111111" nil ))
+ (base0 '("#100E23" "#080808" "black" ))
+ (base1 '("#292F37" "#262626" "brightblack" ))
+ (base2 '("#3D4551" "#3A3A3A" "brightblack" ))
+ (base3 '("#4C4B68" "#444466" "brightblack" ))
+ (base4 '("#565575" "#555577" "brightblack" ))
+ (base5 '("#858FA5" "#8888AA" "brightblack" ))
+ (base6 '("#9BA7BF" "#99AABB" "brightblack" ))
+ (base7 '("#B0BED8" "#BBBBDD" "brightblack" ))
+ (base8 '("#BAC9E4" "#BBCCEE" "white" ))
+ (fg-alt '("#B2B2B2" "#BBBBBB" "brightwhite" ))
+ (fg '("#CBE3E7" "#CCEEEE" "white" ))
+
+ (grey base4)
+ (red '("#FF8080" "#FF8888" "red" ))
+ (orange '("#FFB378" "#FFBB77" "brightred" ))
+ (green '("#95FFA4" "#99FFAA" "green" ))
+ (teal '("#63F2F1" "#66FFFF" "brightgreen" ))
+ (yellow '("#FFE9AA" "#FFEEAA" "yellow" ))
+ (blue '("#91DDFF" "#99DDFF" "brightblue" ))
+ (dark-blue '("#65B2FF" "#66BBFF" "blue" ))
+ (magenta '("#C991E1" "#CC99EE" "magenta" ))
+ (violet '("#906CFF" "#9966FF" "brightmagenta"))
+ (cyan '("#AAFFE4" "#AAFFEE" "brightcyan" ))
+ (dark-cyan '("#62D196" "#66DD99" "cyan" ))
+
+ ;; face categories -- required for all themes
+ (highlight violet)
+ (vertical-bar base1)
+ (selection violet)
+ (builtin magenta)
+ (comments (if doom-challenger-deep-brighter-comments dark-blue base4))
+ (doc-comments (if doom-challenger-deep-brighter-comments (doom-darken dark-cyan 0.3) base5) )
+ (constants cyan)
+ (functions magenta)
+ (keywords red)
+ (methods magenta)
+ (operators teal)
+ (type blue)
+ (strings yellow)
+ (variables yellow)
+ (numbers orange)
+ (region base2)
+ (error red)
+ (warning yellow)
+ (success green)
+ (vc-modified orange)
+ (vc-added green)
+ (vc-deleted red)
+
+ ;; custom categories
+ (hidden `(,(car bg) "black" "black"))
+ (-modeline-bright doom-challenger-deep-brighter-modeline)
+ (-modeline-pad
+ (when doom-challenger-deep-padded-modeline
+ (if (integerp doom-challenger-deep-padded-modeline) doom-challenger-deep-padded-modeline 4)))
+
+ (modeline-fg nil)
+ (modeline-fg-alt base5)
+
+ (modeline-bg
+ (if -modeline-bright
+ base3
+ `(,(doom-darken (car bg) 0.1) ,@(cdr base0))))
+ (modeline-bg-l
+ (if -modeline-bright
+ base3
+ `(,(doom-darken (car bg) 0.15) ,@(cdr base0))))
+ (modeline-bg-inactive `(,(car bg) ,@(cdr base1)))
+ (modeline-bg-inactive-l (doom-darken bg 0.1)))
+
+
+ ;;;; Base theme face overrides
+ (((line-number &override) :foreground base4)
+ ((line-number-current-line &override) :foreground fg)
+ ((font-lock-comment-face &override)
+ :background (if doom-challenger-deep-comment-bg (doom-lighten bg 0.05)))
+ (mode-line
+ :background modeline-bg :foreground modeline-fg
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg)))
+ (mode-line-inactive
+ :background modeline-bg-inactive :foreground modeline-fg-alt
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive)))
+ (mode-line-emphasis :foreground (if -modeline-bright base8 highlight))
+ ((secondary-selection &override) :background base0)
+ (tooltip :background base0 :foreground fg)
+
+ ;;;; css-mode <built-in> / scss-mode
+ (css-proprietary-property :foreground orange)
+ (css-property :foreground green)
+ (css-selector :foreground blue)
+ ;;;; doom-modeline
+ (doom-modeline-bar :background (if -modeline-bright modeline-bg highlight))
+ ;;;; elscreen
+ (elscreen-tab-other-screen-face :background "#353a42" :foreground "#1e2022")
+ ;;;; markdown-mode
+ (markdown-markup-face :foreground base5)
+ (markdown-header-face :inherit 'bold :foreground red)
+ ((markdown-code-face &override) :background (doom-lighten base3 0.05))
+ ;;;; outline <built-in>
+ ((outline-1 &override) :foreground blue :background nil)
+ ;;;; org <built-in>
+ ((org-block &override) :background base1)
+ ((org-block-begin-line &override) :background base1 :foreground comments)
+ (org-hide :foreground hidden)
+ (org-link :foreground orange :underline t :weight 'bold)
+ ;;;; solaire-mode
+ (solaire-mode-line-face
+ :inherit 'mode-line
+ :background modeline-bg-l
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-l)))
+ (solaire-mode-line-inactive-face
+ :inherit 'mode-line-inactive
+ :background modeline-bg-inactive-l
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive-l))))
+
+ ;;;; Base theme variable overrides-
+ ;; ()
+ )
+
+;;; doom-challenger-deep-theme.el ends here
diff --git a/elpa/doom-themes-20220504.1557/doom-city-lights-theme.el b/elpa/doom-themes-20220504.1557/doom-city-lights-theme.el
new file mode 100644
index 0000000..0987c7f
--- /dev/null
+++ b/elpa/doom-themes-20220504.1557/doom-city-lights-theme.el
@@ -0,0 +1,176 @@
+;;; doom-city-lights-theme.el --- inspired by Atom City Lights -*- lexical-binding: t; no-byte-compile: t; -*-
+(require 'doom-themes)
+
+;;
+(defgroup doom-city-lights-theme nil
+ "Options for the `doom-city-lights' theme."
+ :group 'doom-themes)
+
+(defcustom doom-city-lights-brighter-modeline nil
+ "If non-nil, more vivid colors will be used to style the mode-line."
+ :group 'doom-city-lights-theme
+ :type 'boolean)
+
+(defcustom doom-city-lights-brighter-comments nil
+ "If non-nil, comments will be highlighted in more vivid colors."
+ :group 'doom-city-lights-theme
+ :type 'boolean)
+
+(defcustom doom-city-lights-comment-bg doom-city-lights-brighter-comments
+ "If non-nil, comments will have a subtle, darker background. Enhancing their
+legibility."
+ :group 'doom-city-lights-theme
+ :type 'boolean)
+
+(defcustom doom-city-lights-padded-modeline doom-themes-padded-modeline
+ "If non-nil, adds a 4px padding to the mode-line. Can be an integer to
+determine the exact padding."
+ :group 'doom-city-lights-theme
+ :type '(choice integer boolean))
+
+;;
+(def-doom-theme doom-city-lights
+ "A dark theme inspired by Atom City Lights"
+
+ ;; name default 256 16
+ ((bg '("#1D252C" nil nil ))
+ (bg-alt '("#181E24" nil nil ))
+ (base0 '("#10151C" "black" "black" ))
+ (base1 '("#171D22" "#111122" "brightblack" ))
+ (base2 '("#20282F" "#222222" "brightblack" ))
+ (base3 '("#28323B" "#223333" "brightblack" ))
+ (base4 '("#384551" "#334455" "brightblack" ))
+ (base5 '("#56697A" "#556677" "brightblack" ))
+ (base6 '("#688094" "#668899" "brightblack" ))
+ (base7 '("#7FA0B7" "#77AABB" "brightblack" ))
+ (base8 '("#9CAABB" "#99AABB" "white" ))
+ (fg-alt '("#728CA0" "#7788AA" "brightwhite" ))
+ (fg '("#A0B3C5" "#AABBCC" "white" ))
+
+ (grey '("#41505E" "#ff6655" "red" ))
+ (red '("#D95468" "#ff6655" "red" ))
+ (orange '("#D98E48" "#dd8844" "brightred" ))
+ (green '("#8BD49C" "#99bb66" "green" ))
+ (teal '("#33CED8" "#33CCDD" "brightgreen" ))
+ (yellow '("#EBBF83" "#EEBB88" "yellow" ))
+ (blue '("#5EC4FF" "#55CCFF" "brightblue" ))
+ (bright-blue '("#539AFC" "#5599FF" "blue" ))
+ (dark-blue '("#718CA1" "#7788AA" "blue" ))
+ (magenta '("#E27E8D" "#EE7788" "magenta" ))
+ (violet '("#B62D65" "#BB2266" "brightmagenta"))
+ (cyan '("#70E1E8" "#77EEEE" "brightcyan" ))
+ (dark-cyan '("#008B94" "#008899" "cyan" ))
+
+ ;; face categories -- required for all themes
+ (highlight blue)
+ (vertical-bar (doom-darken base1 0.5))
+ (selection dark-blue)
+ (builtin blue)
+ (comments (if doom-city-lights-brighter-comments dark-cyan grey))
+ (doc-comments (doom-lighten (if doom-city-lights-brighter-comments dark-cyan grey) 0.25))
+ (constants magenta)
+ (functions teal)
+ (keywords blue)
+ (methods cyan)
+ (operators blue)
+ (type yellow)
+ (strings bright-blue)
+ (variables dark-blue)
+ (numbers magenta)
+ (region base3)
+ (error red)
+ (warning yellow)
+ (success green)
+ (vc-modified orange)
+ (vc-added green)
+ (vc-deleted red)
+
+ ;; custom categories
+ (hidden `(,(car bg) "black" "black"))
+ (-modeline-bright doom-city-lights-brighter-modeline)
+ (-modeline-pad
+ (when doom-city-lights-padded-modeline
+ (if (integerp doom-city-lights-padded-modeline) doom-city-lights-padded-modeline 4)))
+
+ (modeline-fg nil)
+ (modeline-fg-alt base5)
+
+ (modeline-bg
+ (if -modeline-bright
+ base3
+ `(,(doom-darken (car bg) 0.15) ,@(cdr base0))))
+ (modeline-bg-l modeline-bg)
+ (modeline-bg-inactive `(,(car bg) ,@(cdr base1)))
+ (modeline-bg-inactive-l (doom-darken bg 0.1)))
+
+
+ ;;;; Base theme face overrides
+ (((line-number &override) :foreground base4)
+ ((line-number-current-line &override) :foreground fg)
+ ((font-lock-comment-face &override)
+ :background (if doom-city-lights-comment-bg (doom-lighten bg 0.05)))
+ (mode-line
+ :background modeline-bg :foreground modeline-fg
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg)))
+ (mode-line-inactive
+ :background modeline-bg-inactive :foreground modeline-fg-alt
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive)))
+ (mode-line-emphasis
+ :foreground (if -modeline-bright base8 highlight))
+
+ ;;;; company
+ (company-tooltip-selection :background base3)
+ ;;;; css-mode <built-in> / scss-mode
+ (css-proprietary-property :foreground orange)
+ (css-property :foreground green)
+ (css-selector :foreground blue)
+ ;;;; doom-modeline
+ (doom-modeline-bar :background (if -modeline-bright modeline-bg highlight))
+ ;;;; elscreen
+ (elscreen-tab-other-screen-face :background "#353a42" :foreground "#1e2022")
+ ;;;; magit
+ (magit-diff-hunk-heading-highlight :foreground fg :background base4 :weight 'bold)
+ (magit-diff-hunk-heading :foreground fg-alt :background base3 :weight 'normal)
+ ;;;; markdown-mode
+ (markdown-markup-face :foreground base5)
+ (markdown-header-face :inherit 'bold :foreground red)
+ (markdown-url-face :foreground teal :weight 'normal)
+ (markdown-reference-face :foreground base6)
+ ((markdown-bold-face &override) :foreground fg)
+ ((markdown-italic-face &override) :foreground fg-alt)
+ ;;;; outline <built-in>
+ ((outline-1 &override) :foreground blue)
+ ((outline-2 &override) :foreground green)
+ ((outline-3 &override) :foreground teal)
+ ((outline-4 &override) :foreground (doom-darken blue 0.2))
+ ((outline-5 &override) :foreground (doom-darken green 0.2))
+ ((outline-6 &override) :foreground (doom-darken teal 0.2))
+ ((outline-7 &override) :foreground (doom-darken blue 0.4))
+ ((outline-8 &override) :foreground (doom-darken green 0.4))
+ ;;;; org <built-in>
+ ((org-block &override) :background base2)
+ ((org-block-begin-line &override) :background base2)
+ (org-hide :foreground hidden)
+ ;;;; ivy
+ (ivy-minibuffer-match-face-2 :foreground blue :weight 'bold)
+ ;;;; js2-mode
+ (js2-object-property :foreground dark-blue)
+ (js2-object-property-access :foreground dark-cyan)
+ ;;;; rjsx-mode
+ (rjsx-tag :foreground dark-cyan)
+ (rjsx-attr :foreground cyan :slant 'italic :weight 'medium)
+ ;;;; solaire-mode
+ (solaire-mode-line-face
+ :inherit 'mode-line
+ :background modeline-bg-l
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-l)))
+ (solaire-mode-line-inactive-face
+ :inherit 'mode-line-inactive
+ :background modeline-bg-inactive-l
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive-l))))
+
+ ;;;; Base theme variable overrides-
+ ()
+ )
+
+;;; doom-city-lights-theme.el ends here
diff --git a/elpa/doom-themes-20220504.1557/doom-dark+-theme.el b/elpa/doom-themes-20220504.1557/doom-dark+-theme.el
new file mode 100644
index 0000000..7703351
--- /dev/null
+++ b/elpa/doom-themes-20220504.1557/doom-dark+-theme.el
@@ -0,0 +1,186 @@
+;;; doom-dark+-theme.el --- inspired by dark+ Theme by equinusocio -*- lexical-binding: t; no-byte-compile: t; -*-
+(require 'doom-themes)
+
+;;
+(defgroup doom-dark+-theme nil
+ "Options for the `doom-dark' theme."
+ :group 'doom-themes)
+
+(defcustom doom-dark+-padded-modeline doom-themes-padded-modeline
+ "If non-nil, adds a 4px padding to the mode-line.
+Can be an integer to determine the exact padding."
+ :group 'doom-dark+-theme
+ :type '(choice integer boolean))
+
+(defcustom doom-dark+-blue-modeline nil
+ "If non-nil, mode-line's color will be blue instead of the default purple."
+ :group 'doom-dark+-theme
+ :type '(choice integer boolean))
+
+;;
+(def-doom-theme doom-dark+
+ "A dark theme inspired by dark+ Theme by equinusocio"
+
+ ;; name default 256 16
+ ((bg '("#1e1e1e" "#1e1e1e" nil))
+ (bg-alt '("#252526" "#222222" nil))
+ (base0 '("#171F24" "#111122" "black"))
+ (base1 '("#1C1C1C" "#1C1C1C" "brightblack"))
+ (base2 '("#121212" "#626262" "brightblack"))
+ (base3 '("#313131" "#3a3a3a" "brightblack"))
+ (base4 '("#4b474c" "#444444" "brightblack"))
+ (base5 '("#37474F" "#585858" "brightblack"))
+ (base6 '("#237AD3" "#2277DD" "brightblack"))
+ (base7 '("#777778" "#767676" "brightblack"))
+ (base8 '("#f4f4f4" "#a8a8a8" "white"))
+ (fg '("#d4d4d4" "#e4e4e4" "brightwhite"))
+ (fg-alt '("#AEAFAD" "#bcbcbc" "white"))
+
+ (grey base7)
+ (red '("#D16969" "#DD6666" "red"))
+ (orange '("#DB8E73" "#DD8877" "brightred"))
+ (green '("#579C4C" "#559944" "green"))
+ (light-green '("#B5CEA8" "#BBCCAA" "green"))
+ (teal '("#35CDAF" "#33CCAA" "brightgreen"))
+ (yellow '("#D7BA7D" "#DDBB77" "brightyellow"))
+ (light-yellow '("#D9DAA2" "#DDDDAA" "brightyellow"))
+ (blue '("#339CDB" "#3399DD" "brightblue"))
+ (dark-blue '("#124F7B" "#114477" "blue"))
+ (magenta '("#C586C0" "#CC88CC" "brightmagenta"))
+ (violet '("#BB80B3" "#BB88BB" "magenta"))
+ (dark-violet '("#68217A" "#662277" "magenta"))
+ (cyan '("#85DDFF" "#5FD7FF" "brightcyan"))
+ (dark-cyan '("#207FA1" "#2277AA" "cyan"))
+
+ ;; face categories -- required for all themes
+ (highlight base6)
+ (vertical-bar bg-alt)
+ (selection base4)
+ (builtin magenta)
+ (comments green)
+ (doc-comments base7)
+ (constants blue)
+ (functions light-yellow)
+ (keywords blue)
+ (methods light-yellow)
+ (operators cyan)
+ (type teal)
+ (strings orange)
+ (variables cyan)
+ (numbers light-green)
+ (region (doom-darken base6 0.5))
+ (error red)
+ (warning yellow)
+ (success green)
+ (vc-modified blue)
+ (vc-added green)
+ (vc-deleted red)
+
+ ;; custom categories
+ (modeline-bg (if doom-dark+-blue-modeline base6 dark-violet))
+ (modeline-bg-alt (doom-darken bg 0.01))
+ (modeline-fg base8)
+ (modeline-fg-alt blue)
+
+ (-modeline-pad
+ (when doom-dark+-padded-modeline
+ (if (integerp doom-dark+-padded-modeline) doom-dark+-padded-modeline 4))))
+
+ ;;;; Base theme face overrides
+ ((lazy-highlight :background base4 :foreground fg :distant-foreground fg :weight 'bold)
+ (mode-line
+ :background modeline-bg :foreground modeline-fg
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg)))
+ (mode-line-inactive
+ :background modeline-bg-alt :foreground modeline-fg-alt
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-alt)))
+ (mode-line-emphasis
+ :foreground fg
+ :weight 'bold)
+
+ ;;;; all-the-icons
+ (all-the-icons-dblue :foreground blue)
+ ;;;; centaur-tabs
+ (centaur-tabs-active-bar-face :background base6)
+ (centaur-tabs-selected-modified
+ :inherit 'centaur-tabs-selected :foreground fg :weight 'bold)
+ (centaur-tabs-unselected-modified
+ :inherit 'centaur-tabs-unselected :foreground fg :weight 'bold)
+ (centaur-tabs-modified-marker-selected
+ :inherit 'centaur-tabs-selected :foreground fg)
+ (centaur-tabs-modified-marker-unselected
+ :inherit 'centaur-tabs-unselected :foreground fg)
+ ;;;; company
+ (company-tooltip-selection :background region)
+ ;;;; css-mode <built-in> / scss-mode
+ (css-proprietary-property :foreground orange)
+ (css-property :foreground green)
+ (css-selector :foreground blue)
+ ;;;; dashboard
+ (dashboard-heading :foreground green :weight 'bold)
+ ;;;; dired-k
+ (dired-k-commited :foreground base4)
+ (dired-k-modified :foreground vc-modified)
+ (dired-k-ignored :foreground cyan)
+ (dired-k-added :foreground vc-added)
+ ;;;; doom-modeline
+ (doom-modeline-bar :background (if doom-dark+-blue-modeline base6 dark-violet))
+ (doom-modeline-buffer-file :inherit 'mode-line-emphasis :weight 'bold)
+ (doom-modeline-buffer-major-mode :inherit 'doom-modeline-buffer-path)
+ (doom-modeline-buffer-modified :inherit 'mode-line-emphasis :weight 'bold)
+ (doom-modeline-debug :inherit 'mode-line-emphasis)
+ (doom-modeline-evil-insert-state :foreground cyan)
+ (doom-modeline-evil-visual-state :foreground yellow)
+ (doom-modeline-info :inherit 'mode-line-emphasis)
+ (doom-modeline-lsp-success :inherit 'mode-line-emphasis :weight 'bold)
+ (doom-modeline-persp-name :inherit 'mode-line-emphasis :weight 'bold)
+ (doom-modeline-project-dir :inherit 'mode-line-emphasis :weight 'bold)
+ (doom-modeline-project-parent-dir :inherit 'mode-line-emphasis :weight 'bold)
+ (doom-modeline-urgent :inherit 'mode-line-emphasis)
+ (doom-modeline-warning :inherit 'mode-line-emphasis)
+ ;;;; ivy
+ (counsel-active-mode :foreground (doom-lighten base6 0.1))
+ (ivy-minibuffer-match-face-2 :foreground (doom-lighten base6 0.1) :weight 'extra-bold)
+ ;;;; js2-mode
+ (js2-jsdoc-tag :foreground magenta)
+ (js2-object-property :foreground cyan)
+ (js2-object-property-access :foreground cyan)
+ (js2-function-param :foreground violet)
+ (js2-jsdoc-type :foreground base8)
+ (js2-jsdoc-value :foreground cyan)
+ ;;;; lsp-mode
+ (lsp-lens-face :foreground base7 :height 0.8)
+ ;;;; man <built-in>
+ (Man-overstrike :inherit 'bold :foreground magenta)
+ (Man-underline :inherit 'underline :foreground blue)
+ ;;;; org <built-in>
+ ((org-block &override) :background base2)
+ ((org-block-background &override) :background base2)
+ ((org-block-begin-line &override) :background base2)
+ ;;;; org-pomodoro
+ (org-pomodoro-mode-line :inherit 'mode-line-emphasis) ; unreadable otherwise
+ (org-pomodoro-mode-line-overtime :inherit 'org-pomodoro-mode-line)
+ (org-pomodoro-mode-line-break :inherit 'org-pomodoro-mode-line)
+ ;;;; rainbow-delimiters
+ (rainbow-delimiters-depth-1-face :foreground magenta)
+ (rainbow-delimiters-depth-2-face :foreground orange)
+ (rainbow-delimiters-depth-3-face :foreground green)
+ (rainbow-delimiters-depth-4-face :foreground cyan)
+ (rainbow-delimiters-depth-5-face :foreground violet)
+ (rainbow-delimiters-depth-6-face :foreground yellow)
+ (rainbow-delimiters-depth-7-face :foreground blue)
+ (rainbow-delimiters-depth-8-face :foreground teal)
+ (rainbow-delimiters-depth-9-face :foreground dark-cyan)
+ ;;;; rjsx-mode
+ (rjsx-tag :foreground blue)
+ (rjsx-attr :foreground cyan :slant 'italic :weight 'medium)
+ ;;;; tooltip
+ (tooltip :background base2 :foreground fg)
+ ;;;; treemacs
+ (treemacs-root-face :foreground fg :weight 'ultra-bold :height 1.2)
+ (doom-themes-treemacs-root-face :foreground fg :weight 'ultra-bold :height 1.2)
+ (doom-themes-treemacs-file-face :foreground fg)
+ (treemacs-directory-face :foreground fg)
+ (treemacs-git-modified-face :foreground blue)))
+
+;;; doom-dark+-theme.el ends here
diff --git a/elpa/doom-themes-20220504.1557/doom-dracula-theme.el b/elpa/doom-themes-20220504.1557/doom-dracula-theme.el
new file mode 100644
index 0000000..c86ab9b
--- /dev/null
+++ b/elpa/doom-themes-20220504.1557/doom-dracula-theme.el
@@ -0,0 +1,251 @@
+;;; doom-dracula-theme.el - based on https://draculatheme.com/ -*- lexical-binding: t; no-byte-compile: t; -*-
+(require 'doom-themes)
+
+;;
+(defgroup doom-dracula-theme nil
+ "Options for the `doom-dracula' theme."
+ :group 'doom-themes)
+
+(defcustom doom-dracula-brighter-modeline nil
+ "If non-nil, more vivid colors will be used to style the mode-line."
+ :group 'doom-dracula-theme
+ :type 'boolean)
+
+(defcustom doom-dracula-brighter-comments nil
+ "If non-nil, comments will be highlighted in more vivid colors."
+ :group 'doom-dracula-theme
+ :type 'boolean)
+
+(defcustom doom-dracula-colorful-headers nil
+ "If non-nil, headers in org-mode will be more colorful; which is truer to the
+original Dracula Emacs theme."
+ :group 'doom-dracula-theme
+ :type 'boolean)
+
+(defcustom doom-dracula-comment-bg doom-dracula-brighter-comments
+ "If non-nil, comments will have a subtle, darker background. Enhancing their
+legibility."
+ :group 'doom-dracula-theme
+ :type 'boolean)
+
+(defcustom doom-dracula-padded-modeline doom-themes-padded-modeline
+ "If non-nil, adds a 4px padding to the mode-line. Can be an integer to
+determine the exact padding."
+ :group 'doom-dracula-theme
+ :type '(choice integer boolean))
+
+;;
+(def-doom-theme doom-dracula
+ "A dark theme based on Dracula theme"
+
+ ;; name default 256 16
+ ((bg '("#282a36" "#262626" "black" ))
+ (bg-alt '("#1E2029" "#1c1c1c" "black" ))
+ (base0 '("#1E2029" "#1c1c1c" "black" ))
+ (base1 '("#282a36" "#1e1e1e" "brightblack" ))
+ (base2 '("#373844" "#2e2e2e" "brightblack" ))
+ (base3 '("#44475a" "#262626" "brightblack" ))
+ (base4 '("#565761" "#3f3f3f" "brightblack" ))
+ (base5 '("#6272a4" "#525252" "brightblack" ))
+ (base6 '("#b6b6b2" "#bbbbbb" "brightblack" ))
+ (base7 '("#ccccc7" "#cccccc" "brightblack" ))
+ (base8 '("#f8f8f2" "#dfdfdf" "white" ))
+ (fg '("#f8f8f2" "#ffffff" "white" ))
+ (fg-alt '("#e2e2dc" "#bfbfbf" "brightwhite" ))
+
+ (grey base4)
+ (red '("#ff5555" "#ff6655" "red" ))
+ (orange '("#ffb86c" "#ffbb66" "brightred" ))
+ (green '("#50fa7b" "#55ff77" "green" ))
+ (teal '("#0189cc" "#0088cc" "brightgreen" ))
+ (yellow '("#f1fa8c" "#ffff88" "yellow" ))
+ (blue '("#61bfff" "#66bbff" "brightblue" ))
+ (dark-blue '("#0189cc" "#0088cc" "blue" ))
+ (magenta '("#ff79c6" "#ff77cc" "magenta" ))
+ (violet '("#bd93f9" "#bb99ff" "brightmagenta"))
+ (cyan '("#8be9fd" "#88eeff" "brightcyan" ))
+ (dark-cyan '("#8be9fd" "#88eeff" "cyan" ))
+
+ ;; face categories -- required for all themes
+ (highlight violet)
+ (vertical-bar (doom-darken base1 0.1))
+ (selection dark-blue)
+ (builtin orange)
+ (comments (if doom-dracula-brighter-comments dark-cyan base5))
+ (doc-comments (doom-lighten (if doom-dracula-brighter-comments dark-cyan base5) 0.25))
+ (constants cyan)
+ (functions green)
+ (keywords magenta)
+ (methods teal)
+ (operators violet)
+ (type violet)
+ (strings yellow)
+ (variables (doom-lighten magenta 0.6))
+ (numbers violet)
+ (region `(,(car base3) ,@(cdr base1)))
+ (error red)
+ (warning yellow)
+ (success green)
+ (vc-modified orange)
+ (vc-added green)
+ (vc-deleted red)
+
+ ;; custom categories
+ (level1 magenta)
+ (level2 violet)
+ (level3 (if doom-dracula-colorful-headers green (doom-lighten violet 0.35)))
+ (level4 (if doom-dracula-colorful-headers yellow (doom-lighten magenta 0.35)))
+ (level5 (if doom-dracula-colorful-headers cyan (doom-lighten violet 0.6)))
+ (level6 (if doom-dracula-colorful-headers orange (doom-lighten magenta 0.6)))
+ (level7 (if doom-dracula-colorful-headers blue (doom-lighten violet 0.85)))
+ (level8 (if doom-dracula-colorful-headers magenta (doom-lighten magenta 0.85)))
+ (level9 (if doom-dracula-colorful-headers violet (doom-lighten violet 0.95)))
+
+ (-modeline-bright doom-dracula-brighter-modeline)
+ (-modeline-pad
+ (when doom-dracula-padded-modeline
+ (if (integerp doom-dracula-padded-modeline) doom-dracula-padded-modeline 4)))
+
+ (region-alt `(,(car base3) ,@(cdr base4)))
+
+ (modeline-fg nil)
+ (modeline-fg-alt base5)
+
+ (modeline-bg
+ (if -modeline-bright
+ (doom-darken magenta 0.6)
+ `(,(doom-darken (car bg) 0.15) ,@(cdr base0))))
+ (modeline-bg-l
+ (if -modeline-bright
+ (doom-darken magenta 0.675)
+ `(,(car bg) ,@(cdr base0))))
+ (modeline-bg-inactive `(,(doom-darken (car bg) 0.075) ,@(cdr base1)))
+ (modeline-bg-inactive-l (doom-darken bg 0.1)))
+
+
+ ;;;; Base theme face overrides
+ (((line-number &override) :foreground base5)
+ ((line-number-current-line &override) :foreground fg)
+ ((font-lock-comment-face &override)
+ :background (if doom-dracula-comment-bg (doom-lighten bg 0.05)))
+ (mode-line
+ :background modeline-bg :foreground modeline-fg
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg)))
+ (mode-line-inactive
+ :background modeline-bg-inactive :foreground modeline-fg-alt
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive)))
+ (mode-line-emphasis :foreground (if -modeline-bright base8 highlight))
+
+ ;;;; company
+ (company-tooltip-selection :background base3)
+ ;;;; css-mode <built-in> / scss-mode
+ (css-proprietary-property :foreground violet)
+ (css-property :foreground violet)
+ (css-selector :foreground green)
+ ;;;; doom-modeline
+ (doom-modeline-bar :background (if -modeline-bright modeline-bg highlight))
+ ;;;; elscreen
+ (elscreen-tab-other-screen-face :background "#353a42" :foreground "#1e2022")
+ ;;;; helm
+ (helm-bookmark-w3m :foreground violet)
+ (helm-buffer-not-saved :foreground violet)
+ (helm-buffer-process :foreground orange)
+ (helm-buffer-saved-out :foreground fg)
+ (helm-buffer-size :foreground fg)
+ (helm-candidate-number :foreground bg :background fg)
+ (helm-ff-directory :foreground green :weight 'bold)
+ (helm-ff-executable :foreground dark-blue :inherit 'italic)
+ (helm-ff-invalid-symlink :foreground magenta :weight 'bold)
+ (helm-ff-prefix :foreground bg :background magenta)
+ (helm-ff-symlink :foreground magenta :weight 'bold)
+ (helm-grep-finish :foreground base2)
+ (helm-grep-running :foreground green)
+ (helm-header :foreground base2 :underline nil :box nil)
+ (helm-moccur-buffer :foreground green)
+ (helm-separator :foreground violet)
+ (helm-source-go-package-godoc-description :foreground yellow)
+ ((helm-source-header &override) :foreground magenta)
+ (helm-time-zone-current :foreground orange)
+ (helm-time-zone-home :foreground violet)
+ (helm-visible-mark :foreground bg :background base3)
+ ;;;; highlight-quoted-mode
+ (highlight-quoted-symbol :foreground cyan)
+ (highlight-quoted-quote :foreground magenta)
+ ;;;; js2-mode
+ (js2-external-variable :foreground violet)
+ (js2-function-param :foreground cyan)
+ (js2-jsdoc-html-tag-delimiter :foreground yellow)
+ (js2-jsdoc-html-tag-name :foreground dark-blue)
+ (js2-jsdoc-value :foreground yellow)
+ (js2-private-function-call :foreground cyan)
+ (js2-private-member :foreground base7)
+ ;;;; markdown-mode
+ (markdown-markup-face :foreground base5)
+ (markdown-header-face :inherit 'bold :foreground red)
+ ((markdown-code-face &override) :background (doom-darken 'bg 0.075))
+ ;;;; outline <built-in>
+ ((outline-1 &override) :foreground level1)
+ (outline-2 :inherit 'outline-1 :foreground level2)
+ (outline-3 :inherit 'outline-2 :foreground level3)
+ (outline-4 :inherit 'outline-3 :foreground level4)
+ (outline-5 :inherit 'outline-4 :foreground level5)
+ (outline-6 :inherit 'outline-5 :foreground level6)
+ (outline-7 :inherit 'outline-6 :foreground level7)
+ (outline-8 :inherit 'outline-7 :foreground level8)
+ ;;;; org <built-in>
+ (org-agenda-date :foreground cyan)
+ (org-agenda-dimmed-todo-face :foreground comments)
+ (org-agenda-done :foreground base4)
+ (org-agenda-structure :foreground violet)
+ ((org-block &override) :background (doom-darken base1 0.125) :foreground violet)
+ ((org-block-begin-line &override) :background (doom-darken base1 0.125) :foreground comments)
+ ((org-code &override) :foreground yellow)
+ (org-column :background base1)
+ (org-column-title :background base1 :bold t :underline t)
+ (org-date :foreground cyan)
+ ((org-document-info &override) :foreground blue)
+ ((org-document-info-keyword &override) :foreground comments)
+ (org-done :foreground green :background base2 :weight 'bold)
+ (org-footnote :foreground blue)
+ (org-headline-base :foreground comments :strike-through t :bold nil)
+ (org-headline-done :foreground base4 :strike-through nil)
+ ((org-link &override) :foreground orange)
+ (org-priority :foreground cyan)
+ ((org-quote &override) :background (doom-darken base1 0.125))
+ (org-scheduled :foreground green)
+ (org-scheduled-previously :foreground yellow)
+ (org-scheduled-today :foreground orange)
+ (org-sexp-date :foreground base4)
+ ((org-special-keyword &override) :foreground yellow)
+ (org-table :foreground violet)
+ ((org-tag &override) :foreground (doom-lighten orange 0.3))
+ (org-todo :foreground orange :bold 'inherit :background (doom-darken base1 0.02))
+ (org-upcoming-deadline :foreground yellow)
+ (org-warning :foreground magenta)
+ ;;;; rjsx-mode
+ (rjsx-tag :foreground magenta)
+ (rjsx-attr :foreground green :slant 'italic :weight 'medium)
+ ;;;; solaire-mode
+ (solaire-hl-line-face :background base2)
+ (solaire-mode-line-face
+ :inherit 'mode-line
+ :background modeline-bg-l
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-l)))
+ (solaire-mode-line-inactive-face
+ :inherit 'mode-line-inactive
+ :background modeline-bg-inactive-l
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive-l)))
+ (solaire-region-face :background region-alt)
+ ;;;; web-mode
+ (web-mode-builtin-face :foreground orange)
+ (web-mode-css-selector-face :foreground green)
+ (web-mode-html-attr-name-face :foreground green)
+ (web-mode-html-tag-bracket-face :inherit 'default)
+ (web-mode-html-tag-face :foreground magenta :weight 'bold)
+ (web-mode-preprocessor-face :foreground orange))
+
+ ;;;; Base theme variable overrides-
+ ()
+ )
+
+;;; doom-dracula-theme.el ends here
diff --git a/elpa/doom-themes-20220504.1557/doom-earl-grey-theme.el b/elpa/doom-themes-20220504.1557/doom-earl-grey-theme.el
new file mode 100644
index 0000000..e32433a
--- /dev/null
+++ b/elpa/doom-themes-20220504.1557/doom-earl-grey-theme.el
@@ -0,0 +1,584 @@
+;;; doom-earl-grey-theme.el --- a gentle color scheme, for code -*- no-byte-compile: t; -*-
+(require 'doom-themes)
+
+;;
+(defgroup doom-earl-grey-theme nil
+ "Options for doom-themes"
+ :group 'doom-themes)
+
+(defcustom doom-earl-grey-brighter-modeline nil
+ "If non-nil, more vivid colors will be used to style the mode-line."
+ :group 'doom-earl-grey-theme
+ :type 'boolean)
+
+(defcustom doom-earl-grey-brighter-comments nil
+ "If non-nil, comments will be highlighted in more vivid colors."
+ :group 'doom-earl-grey-theme
+ :type 'boolean)
+
+(defcustom doom-earl-grey-padded-modeline doom-themes-padded-modeline
+ "If non-nil, adds a 4px padding to the mode-line. Can be an integer to
+determine the exact padding."
+ :group 'doom-earl-grey-theme
+ :type '(choice integer boolean))
+
+;;
+(def-doom-theme doom-earl-grey
+ "A gentle color scheme for code."
+
+ ;; name default 256 16
+ (
+ ;; Earl Grey Colors
+ (eg-fg '("#605A52" "#626262" ""))
+ (eg-fg2 '("#4C4741" "#4e4e4e" ""))
+ (eg-bg '("#FCFBF9" "#FFFFFF" "white"))
+ (eg-bg2 '("#F7F3EE" "#FFFFFF" "white"))
+
+ (eg-purple '("#83577D" "#875FAF" "magenta"))
+ (eg-blue '("#556995" "#5F87AF" "brightblue"))
+ (eg-teal '("#477A7B" "#87AFAF" "brightgreen"))
+ (eg-orange '("#886A44" "#875F00" "brightred"))
+ (eg-green '("#747B4D" "#5F875F" "green"))
+ (eg-red '("#8F5652" "#870000" "red"))
+ (eg-berry '("#AA5087" "#996699" "brightmagenta"))
+
+ (eg-grey1 '("#ECEBE8" "#E4E4E4" "white"))
+ (eg-grey2 '("#DDDBD8" "#DADADA" "brightblack"))
+ (eg-grey3 '("#CDCBC7" "#C6C6C6" "brightblack"))
+ (eg-grey4 '("#BEBBB6" "#B2B2B2" "brightblack"))
+ (eg-grey5 '("#AEABA6" "#A8A8A8" "brightblack"))
+ (eg-grey6 '("#9E9A95" "#949494" "brightblack"))
+ (eg-grey7 '("#8F8A84" "#8A8A8A" "brightblack"))
+ (eg-grey8 '("#7F7A73" "#767676" "brightblack"))
+ (eg-grey9 '("#706A63" "#6C6C6C" "brightblack"))
+
+ (eg-purple1 '("#F0EBED" "#D7D7FF" "brightmagenta"))
+ (eg-purple2 '("#E4DAE0" "#D7D7FF" "brightmagenta"))
+ (eg-purple3 '("#D8CAD4" "#D7D7FF" "brightmagenta"))
+ (eg-purple4 '("#CCB9C7" "#D7D7FF" "brightmagenta"))
+ (eg-purple5 '("#C0A9BB" "#AF87FF" "brightmagenta"))
+ (eg-purple6 '("#B399AF" "#AF87FF" "brightmagenta"))
+ (eg-purple7 '("#A788A2" "#AF87FF" "brightmagenta"))
+ (eg-purple8 '("#9B7896" "#AF87FF" "magenta"))
+ (eg-purple9 '("#8F6789" "#AF87FF" "magenta"))
+
+ (eg-blue1 '("#EBECEF" "#87D7FF" "brightblue"))
+ (eg-blue2 '("#DBDEE5" "#87D7FF" "brightblue"))
+ (eg-blue3 '("#CACFDB" "#87D7FF" "brightblue"))
+ (eg-blue4 '("#B9C1D1" "#87D7FF" "brightblue"))
+ (eg-blue5 '("#A9B2C7" "#87D7FF" "brightblue"))
+ (eg-blue6 '("#98A3BD" "#87AFFF" "brightblue"))
+ (eg-blue7 '("#8795B3" "#87AFFF" "brightblue"))
+ (eg-blue8 '("#7686A9" "#87AFFF" "blue"))
+ (eg-blue9 '("#66789F" "#87AFFF" "blue"))
+
+ (eg-teal1 '("#EAEEEC" "#5FD7D7" "brightgreen"))
+ (eg-teal2 '("#D8E1E0" "#5FD7D7" "brightgreen"))
+ (eg-teal3 '("#C6D4D3" "#5FD7D7" "brightgreen"))
+ (eg-teal4 '("#B4C7C7" "#5FD7D7" "brightgreen"))
+ (eg-teal5 '("#A2BBBA" "#5FD7D7" "brightgreen"))
+ (eg-teal6 '("#8FAEAD" "#00AFAF" "brightgreen"))
+ (eg-teal7 '("#7DA1A1" "#00AFAF" "brightgreen"))
+ (eg-teal8 '("#6B9494" "#00AFAF" "brightgreen"))
+ (eg-teal9 '("#598788" "#00AFAF" "brightgreen"))
+
+ (eg-orange1 '("#F0EDE7" "#D7AF5F" "brightred"))
+ (eg-orange2 '("#E5DED5" "#D7AF5F" "brightred"))
+ (eg-orange3 '("#D9D0C3" "#D7AF5F" "brightred"))
+ (eg-orange4 '("#CEC1B1" "#D7AF5F" "brightred"))
+ (eg-orange5 '("#C2B39F" "#D7AF5F" "brightred"))
+ (eg-orange6 '("#B6A48C" "#D7AF5F" "brightred"))
+ (eg-orange7 '("#AB967A" "#D7AF5F" "brightred"))
+ (eg-orange8 '("#9F8768" "#D7AF5F" "brightred"))
+ (eg-orange9 '("#947956" "#D7AF5F" "brightred"))
+
+ (eg-green1 '("#EEEEE8" "#5FAF5F" "green"))
+ (eg-green2 '("#E1E1D7" "#5FAF5F" "green"))
+ (eg-green3 '("#D3D5C5" "#5FAF5F" "green"))
+ (eg-green4 '("#C6C8B4" "#5FAF5F" "green"))
+ (eg-green5 '("#B8BBA3" "#5FAF5F" "green"))
+ (eg-green6 '("#AAAE92" "#5F875F" "green"))
+ (eg-green7 '("#9DA181" "#5F875F" "green"))
+ (eg-green8 '("#8F956F" "#5F875F" "green"))
+ (eg-green9 '("#82885E" "#5F875F" "green"))
+
+ (eg-red1 '("#F1EBE8" "#D78787" "brightred"))
+ (eg-red2 '("#E6DAD8" "#D78787" "brightred"))
+ (eg-red3 '("#DBCAC7" "#D78787" "brightred"))
+ (eg-red4 '("#D0B9B6" "#D78787" "brightred"))
+ (eg-red5 '("#C6A9A6" "#D78787" "brightred"))
+ (eg-red6 '("#BB9895" "#D75F5F" "brightred"))
+ (eg-red7 '("#B08884" "#D75F5F" "brightred"))
+ (eg-red8 '("#A57773" "#D75F5F" "red"))
+ (eg-red9 '("#9A6763" "#D75F5F" "red"))
+
+ (eg-berry1 '("#F4EAEE" "#D787D7" "brightmagenta"))
+ (eg-berry2 '("#ECD9E2" "#D787D7" "brightmagenta"))
+ (eg-berry3 '("#E3C8D7" "#D787D7" "brightmagenta"))
+ (eg-berry4 '("#DBB7CB" "#D787D7" "brightmagenta"))
+ (eg-berry5 '("#D3A6C0" "#D787D7" "brightmagenta"))
+ (eg-berry6 '("#CB94B5" "#AF00AF" "brightmagenta"))
+ (eg-berry7 '("#C383A9" "#AF00AF" "brightmagenta"))
+ (eg-berry8 '("#BA729E" "#AF00AF" "brightmagenta"))
+ (eg-berry9 '("#B26192" "#AF00AF" "brightmagenta"))
+
+ (bg eg-bg)
+ (bg-alt eg-bg2)
+ (base0 (doom-lighten bg 0.1))
+ (base1 eg-grey2)
+ (base2 eg-grey3)
+ (base3 eg-grey4)
+ (base4 eg-grey5)
+ (base5 eg-grey6)
+ (base6 eg-grey7)
+ (base7 eg-grey8)
+ (base8 eg-fg2)
+ (fg eg-fg)
+ (fg-alt eg-grey8)
+
+ (grey base5)
+ (red eg-red)
+ (orange eg-orange)
+ (green eg-green)
+ (teal eg-teal)
+ (yellow eg-orange)
+ (blue eg-blue)
+ (dark-blue eg-blue)
+ (magenta eg-purple)
+ (violet eg-purple)
+ (cyan eg-teal)
+ (dark-cyan eg-teal)
+
+ ;; face categories -- required for all themes
+ (highlight eg-blue8)
+ (vertical-bar base2)
+ (selection eg-purple4)
+ (builtin fg)
+ (comments (if doom-earl-grey-brighter-comments
+ eg-grey7
+ eg-grey6))
+ (doc-comments comments)
+ (constants teal)
+ (functions fg)
+ (keywords magenta)
+ (methods fg)
+ (operators fg)
+ (type fg)
+ (strings green)
+ (variables blue)
+ (numbers teal)
+ (region eg-berry1)
+ (error red)
+ (warning yellow)
+ (success green)
+ (vc-modified eg-orange8)
+ (vc-added eg-green8)
+ (vc-deleted eg-red8)
+
+ ;; custom categories
+ (hidden `(,(car bg) "black" "black"))
+ (-modeline-bright doom-earl-grey-brighter-modeline)
+ (-modeline-pad
+ (when doom-earl-grey-padded-modeline
+ (if (integerp doom-earl-grey-padded-modeline)
+ doom-earl-grey-padded-modeline 4)))
+
+ (modeline-fg nil)
+ (modeline-fg-alt eg-grey6)
+
+ (modeline-bg
+ (if -modeline-bright
+ (doom-darken eg-grey2 0.1)
+ eg-grey2))
+ (modeline-bg-l
+ (if -modeline-bright
+ base2
+ (doom-blend base1 fg 0.96)))
+ (modeline-bg-inactive eg-grey1)
+ (modeline-bg-inactive-l `(,(doom-darken (car bg-alt) 0.05) ,@(cdr base1))))
+
+ ;; --- extra faces ------------------------
+ (
+ ;; Modeline
+ (doom-modeline-buffer-path :foreground blue)
+ (doom-modeline-buffer-major-mode :inherit 'doom-modeline-buffer-path
+ :bold 'bold)
+ (doom-modeline-info :foreground green)
+ (doom-modeline-project-dir :foreground magenta)
+ (doom-modeline-evil-insert-state :foreground teal)
+ (doom-modeline-bar :background (if -modeline-bright modeline-bg highlight))
+ (mode-line
+ :background modeline-bg :foreground modeline-fg
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg)))
+ (mode-line-inactive
+ :background modeline-bg-inactive :foreground modeline-fg-alt
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive)))
+ (mode-line-emphasis
+ :foreground (if -modeline-bright base8 highlight))
+ (doom-modeline-project-root-dir :foreground base6)
+
+ ;; solaire
+ (solaire-mode-line-face
+ :inherit 'mode-line
+ :background modeline-bg-l
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-l)))
+ (solaire-mode-line-inactive-face
+ :inherit 'mode-line-inactive
+ :background modeline-bg-inactive-l
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive-l)))
+
+ ;; Font-Lock
+ (font-lock-comment-face
+ :foreground comments
+ :inherit 'italic)
+ (font-lock-doc-face
+ :inherit 'font-lock-comment-face
+ :foreground doc-comments)
+ (font-lock-comment-delimiter-face :inherit font-lock-comment-face)
+ (font-lock-builtin-face :foreground fg
+ :inherit 'italic :extend t)
+ (font-lock-type-face :foreground fg
+ :inherit 'italic :extend t)
+ (font-lock-variable-name-face :foreground blue)
+ (font-lock-warning-face :foreground red)
+ (font-lock-negation-char-face :foreground orange
+ :inherit 'default
+ :extend t)
+ (font-lock-preprocessor-face :foreground orange
+ :inherit 'default
+ :extend t)
+ (font-lock-preprocessor-char-face :inherit 'default)
+ (font-lock-regexp-grouping-backslash :inherit 'default)
+ (font-lock-regexp-grouping-construct :inherit 'default)
+ (font-lock-constant-face :foreground teal)
+ (font-lock-function-name-face :foreground fg
+ :inherit 'italic :extend t)
+
+ ;; makefile-*-mode
+ (makefile-targets :foreground magenta)
+ (makefile-space :background eg-red2)
+ (makefile-makepp-perl :background eg-blue1)
+
+ ;; which-key
+ (which-key-key-face :foreground eg-purple8)
+ (which-key-group-description-face :foreground eg-blue8)
+ (which-key-command-description-face :foreground fg)
+ (which-key-local-map-description-face :foreground orange)
+ (which-key-separator-face :background bg-alt
+ :foreground comments)
+
+ ;; highlight-numbers-mode
+ (highlight-numbers-number :foreground teal)
+
+ ;; web-mode
+ (web-mode-doctype-face :foreground comments)
+ (web-mode-html-tag-face :foreground magenta)
+ (web-mode-html-attr-name-face :foreground blue)
+ (web-mode-html-attr-value-face :inherit 'font-lock-string-face)
+ (web-mode-html-entity-face :foreground orange
+ :inherit 'italic)
+ (web-mode-block-control-face :foreground magenta)
+ (web-mode-html-tag-bracket-face :foreground fg-alt)
+ (web-mode-symbol-face :foreground blue)
+ (web-mode-string-face :inherit 'font-lock-string-face)
+ (web-mode-current-element-highlight-face :foreground bg)
+
+ ;; xml
+ (nxml-element-local-name :foreground magenta)
+
+ ;; ocaml
+ (tuareg-font-lock-governing-face :foreground magenta)
+ (tuareg-font-lock-operator-face :foreground orange)
+
+ ;; haskell
+ (haskell-constructor-face :foreground teal)
+ (haskell-operator-face :foreground fg)
+ ((haskell-type-face &override)
+ :foreground blue
+ :inherit 'font-lock-type-face
+ :extend t)
+ ((haskell-definition-face &override)
+ :foreground magenta
+ :inherit 'font-lock-function-name-face
+ :extend t)
+
+ ;; Highlight
+ (lazy-highlight :foreground eg-fg2
+ :background eg-berry2 :inherit 'default :extend t)
+
+ ;; php
+ (php-$this :foreground orange)
+
+
+ ;; rjsx-mode
+ (rjsx-tag :foreground magenta)
+ (rjsx-text :inherit 'default)
+ (rjsx-tag-bracket-face :foreground fg-alt)
+ (rjsx-attr :foreground blue)
+
+ ;; highlight-quoted-mode
+ (highlight-quoted-symbol :foreground blue)
+ (highlight-quoted-quote :foreground teal)
+
+ ;; rainbow-delimiters
+ (rainbow-delimiters-depth-1-face :foreground eg-blue6)
+ (rainbow-delimiters-depth-2-face :foreground eg-purple6)
+ (rainbow-delimiters-depth-3-face :foreground eg-green6)
+ (rainbow-delimiters-depth-4-face :foreground eg-orange6)
+ (rainbow-delimiters-depth-5-face :foreground eg-teal6)
+ (rainbow-delimiters-depth-6-face :foreground eg-blue6)
+ (rainbow-delimiters-depth-7-face :foreground eg-purple6)
+ (rainbow-delimiters-unmatched-face :foreground red
+ :weight 'bold
+ :inverse-video t)
+ (rainbow-delimiters-mismatched-face
+ :inherit 'rainbow-delimiters-unmatched-face)
+
+ ;; swiper
+ (swiper-line-face :background eg-purple2
+ :foreground fg
+ :weight 'semi-bold)
+ (swiper-match-face-1 :inherit 'unspecified
+ :background eg-purple1
+ :foreground fg)
+ (swiper-background-match-face-1 :inherit 'unspecified
+ :background eg-bg2
+ :foreground fg)
+ (swiper-match-face-2 :inherit 'unspecified
+ :background eg-purple1
+ :foreground eg-purple)
+ (swiper-background-match-face-2 :inherit 'unspecified
+ :background eg-purple1
+ :foreground eg-purple
+ :weight 'semi-bold)
+ (swiper-match-face-3 :inherit 'unspecified
+ :background eg-blue1
+ :foreground blue)
+ (swiper-background-match-face-3 :inherit 'unspecified
+ :background eg-blue1
+ :foreground blue
+ :weight 'semi-bold)
+ (swiper-match-face-4 :inherit 'unspecified
+ :background eg-teal1
+ :foreground teal)
+ (swiper-background-match-face-4 :inherit 'unspecified
+ :background eg-teal1
+ :foreground teal
+ :weight 'semi-bold)
+
+ ;; tooltip
+ (tooltip :background bg-alt :foreground fg)
+
+ ;; company
+ (company-tooltip :inherit 'tooltip)
+ (company-tooltip-annotation :foreground magenta)
+ (company-tooltip-annotation-selection :foreground magenta )
+ (company-tooltip-common :foreground magenta
+ :distant-foreground bg-alt
+ :weight 'bold)
+ (company-tooltip-search :background magenta
+ :foreground bg
+ :distant-foreground fg
+ :weight 'bold)
+ (company-tooltip-search-selection :background eg-purple1)
+ (company-tooltip-selection :background eg-purple1
+ :weight 'bold)
+ (company-tooltip-mouse :background eg-purple8
+ :foreground bg
+ :distant-foreground fg)
+ (company-tooltip-annotation :foreground magenta
+ :distant-foreground bg)
+ (company-scrollbar-bg :inherit 'tooltip)
+ (company-scrollbar-fg :background highlight)
+ (company-preview :foreground comments)
+ (company-preview-common :background base3
+ :foreground highlight)
+ (company-preview-search :inherit 'company-tooltip-search)
+ (company-template-field :inherit 'match)
+ (company-echo-common :background eg-red2
+ :foreground fg)
+
+ ;; company-box
+ (company-box-candidate :foreground fg)
+
+ ((region &override)
+ :foreground fg)
+
+ ((line-number &override) :foreground base4)
+ ((line-number-current-line &override) :foreground base6)
+ ((paren-face-match &override) :foreground red :background eg-grey1 :weight 'ultra-bold)
+ ((paren-face-mismatch &override) :foreground base3 :background red :weight 'ultra-bold)
+ ((vimish-fold-overlay &override) :inherit 'font-lock-comment-face :background base3 :weight 'light)
+ ((vimish-fold-fringe &override) :foreground teal)
+
+ ;; parens
+ ((show-paren-match &override)
+ :background eg-grey1)
+
+ ;; elscreen
+ (elscreen-tab-other-screen-face :background bg-alt :foreground fg)
+
+ ;; Magit / Diff
+ (magit-diff-hunk-heading-highlight :foreground bg :background eg-blue8 :weight 'bold)
+ (magit-diff-hunk-heading :foreground bg :background eg-blue5)
+ (magit-blame-heading :foreground magenta
+ :background eg-grey1 :extend t)
+ (magit-blame-date :foreground blue)
+
+ (magit-diff-removed :background eg-red1
+ :foreground eg-red)
+ (magit-diff-removed-highlight :background eg-red3
+ :foreground eg-red)
+ (diff-refine-removed :background eg-red9
+ :foreground eg-red1)
+
+ (magit-diff-added :background eg-green1
+ :foreground eg-green)
+ (magit-diff-added-highlight :background eg-green3
+ :foreground eg-green)
+ (diff-refine-added :background eg-green
+ :foreground bg)
+
+ (diff-refine-changed :background eg-purple9
+ :foreground bg)
+
+ (git-commit-summary :foreground fg)
+
+
+ ;; Dired
+ (diredfl-date-time :foreground blue)
+ (diredfl-dir-heading :foreground magenta :weight 'bold)
+
+ ;; ivy
+ (ivy-posframe :background eg-blue1)
+ (ivy-virtual :foreground eg-blue8)
+ (ivy-cursor :foreground bg-alt
+ :background fg)
+ (ivy-minibuffer-match-face-1
+ :background nil
+ :foreground comments
+ :weight 'semi-bold)
+ (ivy-minibuffer-match-face-2
+ :inherit 'ivy-minibuffer-match-face-1
+ :foreground eg-purple :background eg-purple1)
+ (ivy-minibuffer-match-face-3
+ :inherit 'ivy-minibuffer-match-face-2
+ :foreground blue :background eg-orange1)
+ (ivy-minibuffer-match-face-4
+ :inherit 'ivy-minibuffer-match-face-2
+ :foreground teal :background eg-teal1)
+
+ (internal-border
+ :foreground eg-blue8
+ :background eg-blue1)
+ ;; --- major-mode faces -------------------
+ ;; css-mode / scss-mode
+ (css-property :foreground blue
+ :inherit 'italic)
+ (css-proprietary-property :foreground orange)
+ (css-selector :foreground magenta)
+ (web-mode-css-property-name-face :foreground fg)
+
+ ;; markdown-mode
+ (markdown-header-face :inherit 'bold
+ :foreground magenta)
+ (markdown-header-delimiter-face :inherit 'markdown-header-face)
+ (markdown-metadata-key-face :foreground green)
+ (markdown-list-face :foreground fg
+ :inherit 'bold)
+ (markdown-link-face :foreground teal)
+ (markdown-url-face :foreground blue)
+ (markdown-italic-face :inherit 'italic
+ :foreground fg)
+ (markdown-bold-face :inherit 'bold
+ :foreground fg)
+ (markdown-markup-face :foreground fg
+ :inherit 'bold)
+ (markdown-blockquote-face :inherit 'italic
+ :foreground orange)
+ (markdown-pre-face :foreground orange
+ :extend t)
+ (markdown-code-face :foreground orange
+ :extend t)
+ (markdown-reference-face :foreground blue)
+ (markdown-inline-code-face :inherit '(markdown-code-face markdown-pre-face)
+ :extend nil)
+ (markdown-html-attr-name-face :inherit 'font-lock-variable-name-face)
+ (markdown-html-attr-value-face :inherit 'font-lock-string-face)
+ (markdown-html-entity-face :inherit 'font-lock-variable-name-face)
+ (markdown-html-tag-delimiter-face :inherit 'default)
+ (markdown-html-tag-name-face :inherit 'font-lock-keyword-face)
+
+ (nav-flash-face :background eg-purple1 :foreground fg :weight 'bold)
+
+ ;; org-mode
+ ((outline-1 &override) :foreground magenta)
+ ((outline-2 &override) :foreground red)
+ ((outline-3 &override) :foreground teal)
+ ((outline-4 &override) :foreground orange)
+ ((outline-5 &override) :foreground magenta)
+ ((outline-6 &override) :foreground red)
+ ((outline-7 &override) :foreground teal)
+ ((outline-8 &override) :foreground orange)
+
+ (org-drawer :foreground eg-orange)
+ (org-ellipsis :underline nil :background bg :foreground red)
+ ((org-block-begin-line &override)
+ :foreground orange
+ :background bg-alt
+ :weight 'semi-bold
+ :extend t)
+ ((org-block &override)
+ :background bg-alt
+ :foreground fg
+ :extend t)
+ ((org-quote &override)
+ :foreground orange
+ :background bg-alt
+ :extend t)
+ ((org-document-title &override)
+ :foreground magenta)
+
+ ;; js2-mode
+ (js2-function-param :foreground blue)
+ (js2-function-call :foreground fg :inherit 'italic)
+ (js2-object-property :foreground fg)
+ (js2-jsdoc-tag :foreground doc-comments)
+ (js2-external-variable :foreground fg)
+
+ ;; racket
+ (racket-keyword-argument-face :foreground orange)
+ (racket-selfeval-face :foreground teal)
+ (racket-debug-break-face :foreground bg :background red)
+
+ ;; clojure
+ (clojure-keyword-face :foreground blue)
+
+ ;; elixir
+ (elixir-atom-face :foreground blue)
+ (elixir-attribute-face :foreground teal)
+
+ ;; lsp
+ (lsp-ui-doc-background :background bg-alt)
+ (lsp-face-highlight-read :inherit 'lazy-highlight)
+ (lsp-face-highlight-textual :inherit 'lsp-face-highlight-read)
+ (lsp-face-highlight-write :inherit 'lsp-face-highlight-read)
+
+ ;; doom dashboard
+ (doom-dashboard-banner :foreground eg-grey5)
+ (doom-dashboard-menu-title :foreground eg-purple8)
+ (doom-dashboard-menu-desc :foreground eg-green8)
+ (doom-dashboard-footer-icon :foreground eg-orange8)
+ (doom-dashboard-loaded :foreground eg-blue8)
+
+ ;; evil-snipe
+ (evil-snipe-first-match-face :foreground bg :background blue)
+
+ ;; End
+ )
+
+ ;; --- extra variables ---------------------
+ ()
+ )
+
+;;; doom-earl-grey-theme.el ends here
diff --git a/elpa/doom-themes-20220504.1557/doom-ephemeral-theme.el b/elpa/doom-themes-20220504.1557/doom-ephemeral-theme.el
new file mode 100644
index 0000000..f12d4e5
--- /dev/null
+++ b/elpa/doom-themes-20220504.1557/doom-ephemeral-theme.el
@@ -0,0 +1,253 @@
+;;; doom-ephemeral-theme.el --- ephemeral -*- lexical-binding: t; no-byte-compile: t; -*-
+;;
+;; Author: Aloysuis <aloysuis@users.noreply.github.com>
+;; Created: January 27, 2020
+;; Version: 2.0.0
+;; Keywords: custom themes, faces
+;; Homepage: https://github.com/hlissner/emacs-doom-themes
+;; Package-Requires: ((emacs "25.1") (cl-lib "0.5") (doom-themes "2.2.1"))
+;;
+;;; Commentary:
+;;
+;; Inspired by https://github.com/elenapan/dotfiles
+;;
+;;; Code:
+
+(require 'doom-themes)
+
+
+;;
+;;; Variables
+
+(defgroup doom-ephemeral-theme nil
+ "Options for the `doom-ephemeral' theme."
+ :group 'doom-themes)
+
+(defcustom doom-ephemeral-brighter-modeline nil
+ "If non-nil, more vivid colors will be used to style the mode-line."
+ :group 'doom-ephemeral-theme
+ :type 'boolean)
+
+(defcustom doom-ephemeral-brighter-comments nil
+ "If non-nil, comments will be highlighted in more vivid colors."
+ :group 'doom-ephemeral-theme
+ :type 'boolean)
+
+(defcustom doom-ephemeral-padded-modeline doom-themes-padded-modeline
+ "If non-nil, adds a 4px padding to the mode-line. Can be an integer to determine the exact padding."
+ :group 'doom-ephemeral-theme
+ :type '(choice integer boolean))
+
+(defcustom doom-ephemeral-region-highlight t
+ "Determines the selection highlight style. Can be 'frost, 'snowstorm or t
+(default)."
+ :group 'doom-ephemeral-theme
+ :type 'symbol)
+
+
+;;
+;;; Theme definition
+
+(def-doom-theme doom-ephemeral
+ "A dark theme inspired by Nord."
+
+ ;; name default 256 16
+ ((bg '("#323f4e" "#000000" "black" ))
+ (fg '("#f8f8f2" "#f8f8f2" "white" ))
+
+ (bg-alt '("#28323e" "#000000" "black" ))
+ (fg-alt '("#fdfdfd" "#fdfdfd" "brightwhite" ))
+
+ (base0 '("#181e26" "black" "black" ))
+ (base1 '("#1e262d" "#1e262f" "brightblack" ))
+ (base2 '("#242d39" "#242d39" "brightblack" ))
+ (base3 '("#2a3542" "#2a3542" "brightblack" ))
+ (base4 '("#323f4e" "#323f4e" "brightblack" ))
+ (base5 '("#364455" "#364455" "brightblack" ))
+ (base6 '("#505d6f" "#505d6f" "brightblack" ))
+ (base7 '("#77818f" "#77818f" "brightblack" ))
+ (base8 '("#ebedef" "#ebedef" "white" ))
+
+ (grey '("#3d4c5f" "#3d4c5f" "grey" ))
+ (red '("#f48fb1" "#f48fb1" "red" ))
+ (orange '("#f2a272" "#f2a272" "brightred" ))
+ (green '("#53e2ae" "#53e2ae" "green" ))
+ (teal '("#a1efd3" "#a1efd3" "brightgreen" ))
+ (yellow '("#f1fa8c" "#f1fa8c" "yellow" ))
+ (blue '("#92b6f4" "#92b6f4" "brightblue" ))
+ (dark-blue '("#9f92f4" "#9f92f4" "blue" ))
+ (magenta '("#BD99FF" "#c574dd" "magenta" ))
+ (violet '("#8897f4" "#8897f4" "brightmagenta"))
+ (dark-violet '("#985EFF" "#8897f4" "brightmagenta"))
+ (cyan '("#79e6f3" "#87dfeb" "brightcyan" ))
+ (dark-cyan '("#24d1e7" "#24d1e7" "cyan" ))
+
+ ;; ephemeral colours
+ (pink '("#c574dd" "#c574dd" "grey" ))
+ (light-pink (doom-lighten pink 0.6))
+ (dark-grey (doom-darken grey 0.3) )
+ (light-grey '("#56687e" "#56687e" "grey" ))
+ (alt-blue '("#87DFEB" "#87dfeb" "brightblue" ))
+
+ ;; face categories -- required for all themes
+ (highlight alt-blue)
+ (vertical-bar bg-alt)
+ (selection blue)
+ (builtin yellow)
+ (comments light-grey)
+ (doc-comments light-grey)
+ (constants dark-violet)
+ (functions alt-blue)
+ (keywords yellow)
+ (methods teal)
+ (operators blue)
+ (type cyan)
+ (strings red)
+ (variables light-pink)
+ (numbers green)
+ (region base1)
+ (error orange)
+ (warning yellow)
+ (success green)
+ (vc-modified teal)
+ (vc-added blue)
+ (vc-deleted orange)
+
+ ;; custom categories
+ (-modeline-bright doom-ephemeral-brighter-modeline)
+ (-modeline-pad
+ (when doom-ephemeral-padded-modeline
+ (if (integerp doom-ephemeral-padded-modeline) doom-ephemeral-padded-modeline 4)))
+
+ (region-fg
+ (when (memq doom-ephemeral-region-highlight '(frost snowstorm))
+ bg-alt))
+
+ (modeline-fg fg)
+ (modeline-fg-alt light-grey)
+ (modeline-bg bg)
+ (modeline-bg-l base2)
+ (modeline-bg-inactive base3)
+ (modeline-bg-inactive-l `(,(car base3), (cdr base6))))
+
+
+ ;;;; Base theme face overrides
+ (((line-number &override) :foreground grey)
+ ((line-number-current-line &override) :foreground blue)
+ (link :foreground (doom-lighten light-grey 0.3) :inherit 'underline)
+ ((font-lock-comment-face &override)
+ :inherit 'bold :background (if doom-ephemeral-brighter-comments (doom-lighten bg 0.05)))
+ ((font-lock-builtin-face &override) :inherit 'italic)
+ ((font-lock-keyword-face &override) :inherit 'bold)
+ (mode-line
+ :background modeline-bg :foreground modeline-fg
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg)))
+ (mode-line-inactive
+ :background modeline-bg-inactive :foreground modeline-fg-alt
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive)))
+ (mode-line-emphasis :foreground (if -modeline-bright base8 highlight))
+ ((region &override) :foreground region-fg)
+ (shadow :foreground base6)
+ ((tooltip &override) :background base1)
+
+ ;;;; company
+ (company-tooltip-common :foreground violet)
+ (company-tooltip-selection :background base0 :foreground red)
+ ;;;; company-box
+ (company-box-background :background base0 :foreground fg)
+ ;;;; css-mode <built-in> / scss-mode
+ (css-property :foreground fg)
+ (css-proprietary-property :foreground violet)
+ (css-selector :foreground red)
+ ;;;; doom-modeline
+ (doom-modeline-bar :background (if -modeline-bright modeline-bg highlight))
+ (doom-modeline-buffer-file :foreground fg)
+ (doom-modeline-buffer-major-mode :foreground teal :weight 'bold)
+ (doom-modeline-buffer-modified :foreground violet)
+ (doom-modeline-buffer-path :foreground red)
+ (doom-modeline-highlight :foreground (doom-lighten base2 0.3))
+ (doom-modeline-info :inherit 'bold :foreground cyan)
+ (doom-modeline-panel :background base0)
+ (doom-modeline-project-dir :foreground teal :inherit 'bold)
+ (doom-modeline-urgent :foreground modeline-fg)
+ ;;;; ediff <built-in>
+ (ediff-fine-diff-A :background (doom-darken violet 0.4) :weight 'bold)
+ (ediff-current-diff-A :background (doom-darken base0 0.25))
+ ;;;; elscreen
+ (elscreen-tab-other-screen-face :background "#353a42" :foreground "#1e2022")
+ ;;;; evil
+ (evil-ex-lazy-highlight :background base1 :foreground fg)
+ (evil-ex-search :background base1 :foreground fg)
+ (evil-snipe-first-match-face :background base1 :foreground orange)
+ ;;;; haskell-mode
+ (haskell-constructor-face :inherit 'bold :foreground alt-blue)
+ (haskell-definition-face :inherit 'bold :foreground functions)
+ (haskell-keyword-face :inherit 'italic :foreground blue)
+ (haskell-literate-comment-face :foreground doc-comments)
+ (haskell-operator-face :foreground light-pink)
+ (haskell-type-face :inherit 'bold :foreground violet)
+ ;;;; highlight-symbol
+ (highlight-symbol-face :background region :distant-foreground fg-alt)
+ ;;;; highlight-thing
+ (highlight-thing :background region :distant-foreground fg-alt)
+ ;;;; ivy
+ (ivy-current-match :background base0 :distant-foreground nil)
+ (ivy-posframe-cursor :background alt-blue :foreground base0)
+ (ivy-minibuffer-match-face-2 :foreground red :weight 'bold)
+ ;;;; lsp-mode
+ (lsp-headerline-breadcrumb-symbols-face :foreground functions :weight 'bold)
+ ;;;; magit
+ (magit-diff-hunk-heading :foreground bg :background (doom-blend magenta bg 0.3) :extend t)
+ (magit-diff-hunk-heading-highlight :foreground bg :background magenta :weight 'bold :extend t)
+ (magit-section-heading :foreground red)
+ (magit-branch-remote :foreground orange)
+ ;;;; markdown-mode
+ (markdown-markup-face :foreground red)
+ (markdown-link-face :foreground teal)
+ (markdown-link-title-face :foreground alt-blue)
+ (markdown-header-face :foreground red :inherit 'bold)
+ (markdown-header-delimiter-face :foreground red :inherit 'bold)
+ (markdown-language-keyword-face :foreground pink :inherit 'italic)
+ (markdown-markup-face :foreground blue)
+ (markdown-bold-face :foreground blue)
+ (markdown-table-face :foreground fg :background bg)
+ ((markdown-code-face &override) :foreground teal :background base1)
+ ;;;; notmuch
+ (notmuch-wash-cited-text :foreground base6)
+ ;;;; outline <built-in>
+ (outline-1 :foreground alt-blue)
+ (outline-2 :foreground violet)
+ (outline-3 :foreground blue)
+ (outline-4 :foreground red)
+ (outline-5 :foreground pink)
+ (outline-6 :foreground light-grey)
+ (outline-7 :foreground yellow)
+ (outline-8 :foreground cyan)
+ ;;;; org <built-in>
+ (org-agenda-done :foreground teal)
+ ((org-block &override) :background base2)
+ ((org-block-begin-line &override) :inherit 'bold :background base2 :foreground light-grey)
+ (org-document-info-keyword :foreground comments)
+ (org-headline-done :foreground red)
+ (org-link :inherit 'underline :foreground pink)
+ (org-list-dt :foreground light-grey)
+ (org-todo :foreground red)
+ ;;;; mic-paren
+ ((paren-face-match &override) :background base3)
+ ((paren-face-mismatch &override) :foreground base3)
+ ;;;; rjsx-mode
+ (rjsx-tag :foreground magenta)
+ ;;;; solaire-mode
+ (solaire-mode-line-face
+ :inherit 'mode-line
+ :background modeline-bg-l
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-l)))
+ (solaire-mode-line-inactive-face
+ :inherit 'mode-line-inactive
+ :background modeline-bg-inactive-l
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive-l)))
+ ;;;; vimish-fold
+ ((vimish-fold-overlay &override) :background base3)
+ ((vimish-fold-fringe &override) :foreground teal)))
+
+;;; doom-ephemeral-theme.el ends here
diff --git a/elpa/doom-themes-20220504.1557/doom-fairy-floss-theme.el b/elpa/doom-themes-20220504.1557/doom-fairy-floss-theme.el
new file mode 100644
index 0000000..123455e
--- /dev/null
+++ b/elpa/doom-themes-20220504.1557/doom-fairy-floss-theme.el
@@ -0,0 +1,184 @@
+;;; doom-fairy-floss-theme.el --- inspired by sailorhg Fairy Floss -*- lexical-binding: t; no-byte-compile: t; -*-
+(require 'doom-themes)
+
+;;
+(defgroup doom-fairy-floss-theme nil
+ "Options for doom-themes."
+ :group 'doom-themes)
+
+(defcustom doom-fairy-floss-brighter-modeline nil
+ "If non-nil, more vivid colors will be used to style the mode-line."
+ :group 'doom-fairy-floss-theme
+ :type 'boolean)
+
+(defcustom doom-fairy-floss-brighter-comments nil
+ "If non-nil, comments will be highlighted in more vivid colors."
+ :group 'doom-fairy-floss-theme
+ :type 'boolean)
+
+(defcustom doom-fairy-floss-comment-bg doom-fairy-floss-brighter-comments
+ "If non-nil, comments will have a subtle, darker background. Enhancing their
+legibility."
+ :group 'doom-fairy-floss-theme
+ :type 'boolean)
+
+(defcustom doom-fairy-floss-padded-modeline doom-themes-padded-modeline
+ "If non-nil, adds a 4px padding to the mode-line. Can be an integer to
+determine the exact padding."
+ :group 'doom-fairy-floss-theme
+ :type '(choice integer boolean))
+
+;;
+(def-doom-theme doom-fairy-floss
+ "A candy colored theme inspired by Sublime's Fairy Floss"
+
+ ;; name default 256 16
+ ((bg '("#5a5475" nil nil ))
+ (bg-alt '("#343145" nil nil ))
+ (base0 '("#464258" "black" "black" ))
+ (base1 '("#514C66" "#1e1e1e" "brightblack" ))
+ (base2 '("#6A6483" "#2e2e2e" "brightblack" ))
+ (base3 '("#9673D3" "#262626" "brightblack" ))
+ (base4 '("#A0A0C0" "#3f3f3f" "brightblack" ))
+ (base5 '("#B8A2CE" "#525252" "brightblack" ))
+ (base6 '("#726C8A" "#6b6b6b" "brightblack" ))
+ (base7 '("#5B576C" "#979797" "brightblack" ))
+ (base8 '("#716799" "#dfdfdf" "white" ))
+ (fg-alt '("#B5B2Bd" "#2d2d2d" "white" ))
+ (fg '("#F8F8F0" "#bfbfbf" "brightwhite" ))
+
+ (grey '("#656565" "#515154" "brightblack" ))
+ (red '("#CC6666" "#CC6666" "red" ))
+ (orange '("#E6C000" "#E6C000" "brightred" ))
+ (green '("#C2FFDF" "#C2FFDF" "green" ))
+ (yellow '("#FFEA00" "#FFEA00" "yellow" ))
+ (blue '("#55b3cc" "#55b3cc" "brightblue" ))
+ (teal '("#8295D6" "#8295D6" "brightgreen" ))
+ (dark-blue '("#167be2" "#3F88AD" "blue" ))
+ (magenta '("#FFB8D1" "#FFB8D1" "magenta" ))
+ (violet '("#C5A3FF" "#C5A3FF" "brightmagenta"))
+ (cyan '("#96CBFE" "#C2FFDF" "brightcyan" ))
+ (dark-cyan '("#204052" "#204052" "cyan" ))
+
+ ;; face categories -- required for all themes
+ (highlight violet)
+ (vertical-bar (doom-darken base1 0.5))
+ (selection dark-blue)
+ (builtin blue)
+ (comments (if doom-fairy-floss-brighter-comments cyan orange))
+ (doc-comments violet)
+ (constants violet)
+ (functions green)
+ (keywords cyan)
+ (methods green)
+ (operators orange)
+ (type cyan)
+ (strings yellow)
+ (variables magenta)
+ (numbers violet)
+ (region base0)
+ (error red)
+ (warning yellow)
+ (success green)
+ (vc-modified orange)
+ (vc-added green)
+ (vc-deleted red)
+
+ ;; custom categories
+ (hidden `(,(car bg) "black" "black"))
+ (-modeline-bright doom-fairy-floss-brighter-modeline)
+ (-modeline-pad
+ (when doom-fairy-floss-padded-modeline
+ (if (integerp doom-fairy-floss-padded-modeline) doom-fairy-floss-padded-modeline 4)))
+
+ (modeline-fg nil)
+ (modeline-fg-alt base5)
+
+ (modeline-bg
+ (if -modeline-bright
+ base3
+ `(,(doom-darken (car bg) 0.15) ,@(cdr base0))))
+ (modeline-bg-l
+ (if -modeline-bright
+ base3
+ `(,(doom-darken (car bg) 0.1) ,@(cdr base0))))
+ (modeline-bg-inactive (doom-darken bg 0.1))
+ (modeline-bg-inactive-l `(,(car bg) ,@(cdr base1))))
+
+
+ ;;;; Base theme face overrides
+ (((font-lock-comment-face &override)
+ :background (if doom-fairy-floss-comment-bg (doom-lighten bg 0.05)))
+ ((font-lock-keyword-face &override ) :slant 'italic)
+ ((hl-line &override) :background base2)
+ ((line-number &override) :foreground base4)
+ ((line-number-current-line &override) :foreground fg)
+ (mode-line
+ :background modeline-bg :foreground modeline-fg
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg)))
+ (mode-line-inactive
+ :background modeline-bg-inactive :foreground modeline-fg-alt
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive)))
+ (mode-line-emphasis :foreground (if -modeline-bright cyan highlight))
+
+ ;;;; centaur-tabs
+ (centaur-tabs-active-bar-face :background blue)
+ (centaur-tabs-modified-marker-selected :inherit 'centaur-tabs-selected
+ :foreground blue)
+ (centaur-tabs-modified-marker-unselected :inherit 'centaur-tabs-unselected
+ :foreground blue)
+ ;;;; company
+ (company-tooltip-selection :background base3)
+ ;;;; css-mode <built-in> / scss-mode
+ (css-proprietary-property :foreground orange)
+ (css-property :foreground green)
+ (css-selector :foreground blue)
+ ;;;; doom-modeline
+ (doom-modeline-bar :background blue)
+ ;;;; elscreen
+ (elscreen-tab-other-screen-face :background "#353a42" :foreground "#1e2022")
+ ;;;; highlight-symbol
+ (highlight-symbol-face :background region :distant-foreground fg-alt)
+ ;;;; highlight-thing
+ (highlight-thing :background region :distant-foreground fg-alt)
+ ;;;; magit
+ (magit-diff-removed :foreground (doom-darken red 0.2) :background (doom-blend red base5 0.1))
+ (magit-diff-removed-highlight :foreground red :background (doom-blend red base5 0.2) :weight 'bold)
+ ;;;; markdown-mode
+ (markdown-markup-face :foreground base5)
+ (markdown-header-face :inherit 'bold :foreground red)
+ (markdown-url-face :foreground teal :weight 'normal)
+ (markdown-reference-face :foreground base6)
+ ((markdown-bold-face &override) :foreground fg)
+ ((markdown-italic-face &override) :foreground fg-alt)
+ ;;;; outline <built-in>
+ ((outline-1 &override) :foreground orange)
+ ((outline-2 &override) :foreground green)
+ ((outline-3 &override) :foreground teal)
+ ((outline-4 &override) :foreground (doom-darken orange 0.2))
+ ((outline-5 &override) :foreground (doom-darken green 0.2))
+ ((outline-6 &override) :foreground (doom-darken teal 0.2))
+ ((outline-7 &override) :foreground (doom-darken orange 0.4))
+ ((outline-8 &override) :foreground (doom-darken green 0.4))
+ ;;;; org <built-in>
+ ((org-block &override) :background base0)
+ ((org-block-begin-line &override) :background base0)
+ (org-scheduled :foreground green)
+ (org-scheduled-previously :foreground yellow)
+ (org-scheduled-today :foreground orange)
+ (org-hide :foreground hidden)
+ ;;;; solaire-mode
+ (solaire-mode-line-face
+ :inherit 'mode-line
+ :background modeline-bg-l
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-l)))
+ (solaire-mode-line-inactive-face
+ :inherit 'mode-line-inactive
+ :background modeline-bg-inactive-l
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive-l))))
+
+ ;;;; Base theme variable overrides-
+ ;; ()
+ )
+
+;;; doom-fairy-floss-theme.el ends here
diff --git a/elpa/doom-themes-20220504.1557/doom-flatwhite-theme.el b/elpa/doom-themes-20220504.1557/doom-flatwhite-theme.el
new file mode 100644
index 0000000..ec181f6
--- /dev/null
+++ b/elpa/doom-themes-20220504.1557/doom-flatwhite-theme.el
@@ -0,0 +1,589 @@
+;;; doom-flatwhite-theme.el --- inspired by Flatwhite Syntax -*- lexical-binding: t; no-byte-compile: t; -*-
+(require 'doom-themes)
+
+;;
+(defgroup doom-flatwhite-theme nil
+ "Options for the `doom-flatwhite' theme."
+ :group 'doom-themes)
+
+(defcustom doom-flatwhite-brighter-modeline nil
+ "If non-nil, more vivid colors will be used to style the mode-line."
+ :group 'doom-flatwhite-theme
+ :type 'boolean)
+
+(defcustom doom-flatwhite-no-highlight-variables nil
+ "If non-nil, removes highlight on variable names"
+ :group 'doom-flatwhite-theme
+ :type 'boolean)
+
+(defcustom doom-fw-padded-modeline doom-themes-padded-modeline
+ "If non-nil, adds a 4px padding to the mode-line. Can be an integer to
+determine the exact padding."
+ :group 'doom-flatwhite-theme
+ :type '(choice integer boolean))
+
+;;
+(def-doom-theme doom-flatwhite
+ "A minimal light syntax theme"
+
+ ;; name default 256 16
+ (
+ (fw-base1 '("#605a52" "#666666" "black"))
+ (fw-base2 '("#93836c" "#999966" "brightblack"))
+ (fw-base3 '("#b9a992" "#cc9999" "brightblack"))
+ (fw-base4 '("#dcd3c6" "#cccccc" "brightblack"))
+ (fw-base5 '("#e4ddd2" "#cccccc" "brightblack"))
+ (fw-base6 '("#f1ece4" "#ffffcc" "brightblack"))
+ (fw-base7 '("#f7f3ee" "#ffffff" "brightblack"))
+
+ (fw-accent '("#6a4dff" "#6666ff" "brightblue"))
+
+ (fw-orange-text '("#5b5143" "#666633" "brightblack"))
+ (fw-orange-text-sec '("#957f5f" "#996666" "brightblack"))
+ (fw-orange '("#f08c00" "#ff9900" "orange"))
+ (fw-orange-blend '("#f7e0c3" "#ffcccc" "brightorange"))
+
+ (fw-red-text '("#5b4343" "#663333" "brightblack"))
+ (fw-red-text-sec '("#955f5f" "#996666" "brightblack"))
+ (fw-red '("#f00000" "#ff0000" "red"))
+ (fw-red-blend '("#f6cfcb" "#ffcccc" "brightred"))
+
+ (fw-green-text '("#525643" "#666633" "brightblack"))
+ (fw-green-text-sec '("#81895d" "#999966" "brightblack"))
+ (fw-green '("#84bd00" "#99cc00" "green"))
+ (fw-green-blend '("#e2e9c1" "#ccffcc" "brightgreen"))
+
+ (fw-teal-text '("#465953" "#336666" "brightblack"))
+ (fw-teal-text-sec '("#5f8c7d" "#669966" "brightblack"))
+ (fw-teal '("#00bda4" "#00cc99" "cyan"))
+ (fw-teal-blend '("#d2ebe3" "#ccffcc" "brightcyan"))
+
+ (fw-blue-text '("#4c5361" "#336666" "brightblack"))
+ (fw-blue-text-sec '("#7382a0" "#669999" "brightblack"))
+ (fw-blue '("#75a3ff" "#6699ff" "blue"))
+ (fw-blue-blend '("#dde4f2" "#ccccff" "brightblue"))
+
+ (fw-purple-text '("#614c61" "#663366" "brightblack"))
+ (fw-purple-text-sec '("#9c739c" "#996699" "brightblack"))
+ (fw-purple '("#ce5cff" "#cc66ff" "purple"))
+ (fw-purple-blend '("#f1ddf1" "#ffccff" "brightpurple"))
+
+ (bg `(,(car fw-base7) nil nil ))
+ (bg-alt `(,(car fw-base6) nil nil ))
+ (base0 fw-base6)
+ (base1 fw-base5 )
+ (base2 fw-base4 )
+ (base3 fw-base3 )
+ (base4 fw-base2 )
+ (base5 fw-base1 )
+ (base6 '("#202328" nil "brightblack" ))
+ (base7 '("#1c1f24" nil "brightblack" ))
+ (base8 '("#1b2229" nil "black" ))
+ (fg `(,(car fw-base1) nil "black" ))
+ (fg-alt `(,(car fw-base2) nil "brightblack" ))
+
+ (grey base3)
+ (red fw-red-text-sec)
+ (orange fw-orange-text-sec)
+ (green fw-green-text-sec)
+ (teal fw-teal-text-sec)
+ (yellow fw-orange-text-sec)
+ (blue fw-blue-text-sec)
+ (dark-blue fw-blue-text-sec)
+ (magenta fw-purple-text-sec)
+ (violet fw-purple-text-sec) ;; TODO fix these
+ (cyan fw-teal-text-sec)
+ (dark-cyan fw-teal-text-sec)
+
+ (fw--light-accent (doom-lighten fw-accent 0.85))
+
+ ;; face categories -- required for all themes
+ (highlight blue)
+ (vertical-bar (doom-darken base2 0.1))
+ (selection dark-blue)
+ (builtin magenta)
+ (comments base3)
+ (doc-comments (doom-darken comments 0.15))
+ (constants violet)
+ (functions magenta)
+ (keywords red)
+ (methods cyan)
+ (operators blue)
+ (type orange)
+ (strings green)
+ (variables (doom-darken magenta 0.36))
+ (numbers orange)
+ (region `(,(doom-darken (car bg-alt) 0.1) ,@(doom-darken (cdr base0) 0.3)))
+ (error red)
+ (warning yellow)
+ (success green)
+ (vc-modified orange)
+ (vc-added green)
+ (vc-deleted red)
+
+ ;; custom categories
+ (-modeline-bright doom-flatwhite-brighter-modeline)
+ (-no-highlight-variables doom-flatwhite-no-highlight-variables)
+ (-modeline-pad
+ (when doom-fw-padded-modeline
+ (if (integerp doom-fw-padded-modeline) doom-fw-padded-modeline 4)))
+
+ (modeline-fg nil)
+ (modeline-fg-alt fw-base2)
+
+ (modeline-bg
+ (if -modeline-bright
+ (doom-darken base2 0.05)
+ base1))
+ (modeline-bg-l
+ (if -modeline-bright
+ (doom-darken base2 0.1)
+ base2))
+ (modeline-bg-inactive (doom-darken bg 0.1))
+ (modeline-bg-inactive-l `(,(doom-darken (car bg-alt) 0.05) ,@(cdr base1))))
+
+
+ ;;;; Base theme face overrides
+ ((font-lock-builtin-face :inherit 'italic :foreground fg :extend t)
+ ((font-lock-doc-face &override) :slant 'italic)
+ (font-lock-type-face :inherit 'default)
+ (font-lock-variable-name-face
+ :foreground (if -no-highlight-variables fg fw-blue-text)
+ :background (if -no-highlight-variables bg fw-blue-blend))
+ (font-lock-warning-face :background fw-red-blend
+ :foreground fw-red-text)
+ (font-lock-negation-char-face :inherit 'default)
+ (font-lock-preprocessor-face :inherit 'default)
+ (font-lock-preprocessor-char-face :inherit 'default)
+ (font-lock-regexp-grouping-backslash :inherit 'default)
+ (font-lock-regexp-grouping-construct :inherit 'default)
+ (font-lock-constant-face :background fw-teal-blend
+ :foreground fw-teal-text)
+ (font-lock-function-name-face :foreground fg
+ :weight 'semi-bold)
+ (font-lock-keyword-face :background fw-purple-blend
+ :foreground fw-purple-text)
+ (font-lock-string-face :background fw-green-blend
+ :foreground fw-green-text )
+
+ (lazy-highlight :background fw--light-accent
+ :foreground fw-blue-text
+ :distant-foreground base0
+ :weight 'bold)
+
+ ((line-number &override) :foreground (doom-lighten base4 0.15))
+ ((line-number-current-line &override) :foreground base8)
+
+ (mode-line
+ :background modeline-bg
+ :foreground modeline-fg
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg)))
+ (mode-line-inactive
+ :background modeline-bg-inactive
+ :foreground modeline-fg-alt
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive)))
+ (mode-line-emphasis :foreground (if -modeline-bright base8 highlight))
+
+ ;;;; centaur-tabs
+ (centaur-tabs-unselected :background bg-alt :foreground base4)
+ ;;;; swiper
+ (swiper-line-face :background fw--light-accent
+ :foreground fw-blue-text)
+ (swiper-match-face-1 :inherit 'unspecified
+ :background base0
+ :foreground fg)
+ (swiper-background-match-face-1 :inherit 'unspecified
+ :background base0
+ :foreground fg-alt)
+ (swiper-match-face-2 :inherit 'unspecified
+ :background fw-orange-blend
+ :foreground fw-orange-text
+ :weight 'bold)
+ (swiper-background-match-face-2 :inherit 'unspecified
+ :background fw-orange-blend
+ :foreground fw-orange-text-sec
+ :weight 'bold)
+ (swiper-match-face-3 :inherit 'unspecified
+ :background fw-green-blend
+ :foreground fw-green-text
+ :weight 'bold)
+ (swiper-background-match-face-3 :inherit 'unspecified
+ :background fw-green-blend
+ :foreground fw-green-text-sec
+ :weight 'bold)
+ (swiper-match-face-4 :inherit 'unspecified
+ :background fw-teal-blend
+ :foreground fw-teal-text
+ :weight 'bold)
+ (swiper-background-match-face-4 :inherit 'unspecified
+ :background fw-teal-blend
+ :foreground fw-teal-text-sec
+ :weight 'bold)
+ ;;;; company
+ (company-tooltip :inherit 'tooltip)
+ (company-tooltip-annotation :foreground fw-purple-text-sec )
+ (company-tooltip-annotation-selection :foreground fw-purple-text )
+ (company-tooltip-common :foreground highlight
+ :distant-foreground base0
+ :weight 'bold)
+ (company-tooltip-search :background highlight
+ :foreground bg
+ :distant-foreground fg
+ :weight 'bold)
+ (company-tooltip-search-selection :background fw-blue-blend)
+ (company-tooltip-selection :background fw--light-accent
+ :weight 'bold)
+ (company-tooltip-mouse :background magenta
+ :foreground bg
+ :distant-foreground fg)
+ (company-tooltip-annotation :foreground violet
+ :distant-foreground bg)
+ (company-scrollbar-bg :inherit 'tooltip)
+ (company-scrollbar-fg :background highlight)
+ (company-preview :foreground comments)
+ (company-preview-common :background base3
+ :foreground highlight)
+ (company-preview-search :inherit 'company-tooltip-search)
+ (company-template-field :inherit 'match)
+ ;;;; clojure
+ (clojure-keyword-face :foreground fw-orange-text
+ :background fw-orange-blend)
+ ;;;; css-mode <built-in> / scss-mode
+ (css-property :foreground fg
+ :inherit 'italic)
+ (css-proprietary-property :foreground fw-orange-text
+ :background fw-orange-blend)
+ (css-selector :foreground fw-purple-text
+ :background fw-purple-blend)
+ ;;;; company-box
+ (company-box-candidate :foreground fg)
+ ;;;; doom-emacs
+ (doom-dashboard-banner :foreground comments)
+ (doom-dashboard-menu-title :foreground fw-purple-text-sec)
+ (doom-dashboard-menu-desc :foreground fw-green-text-sec)
+ (doom-dashboard-footer-icon :foreground (doom-darken yellow 0.4))
+ (doom-dashboard-loaded :foreground fw-orange-text)
+ ;;;; doom-modeline
+ (doom-modeline-bar :background (if -modeline-bright modeline-bg highlight))
+ (doom-modeline-buffer-path :foreground fw-blue-text-sec
+ :bold bold)
+ (doom-modeline-buffer-major-mode :inherit 'doom-modeline-buffer-path )
+ (doom-modeline-info :foreground fw-green-text-sec)
+ (doom-modeline-project-dir :foreground fw-purple-text-sec)
+ (doom-modeline-evil-insert-state :foreground fw-teal)
+ ;;;; diff-mode
+ (diff-removed :foreground red
+ :background fw-red-blend)
+ ;;;; ediff <built-in>
+ (ediff-current-diff-A :foreground red
+ :background (doom-lighten red 0.8))
+ (ediff-current-diff-B :foreground green
+ :background (doom-lighten green 0.8))
+ (ediff-current-diff-C :foreground blue
+ :background (doom-lighten blue 0.8))
+ (ediff-current-diff-Ancestor :foreground teal
+ :background (doom-lighten teal 0.8))
+ ;;;; elixir
+ (elixir-atom-face :foreground fw-blue-text
+ :background fw-blue-blend)
+ (elixir-attribute-face :foreground fw-teal-text
+ :background fw-teal-blend)
+ ;;;; fill column
+ (hl-fill-column-face :foreground fg
+ :background fw--light-accent)
+ ;;;; git-commit
+ (git-commit-summary :foreground fg)
+ ;;;; highlight-numbers-mode
+ (highlight-numbers-number :foreground fw-teal-text
+ :background fw-teal-blend)
+ ;;;; highlight-quoted-mode
+ (highlight-quoted-symbol :background fw-blue-blend
+ :foreground fw-blue-text)
+ (highlight-quoted-quote :foreground fw-teal-blend
+ :foreground fw-teal-text)
+ ;;;; ivy
+ (ivy-current-match :background fw-base5
+ :distant-foreground nil
+ :extend t)
+ (ivy-minibuffer-match-face-1
+ :background nil
+ :foreground fg
+ :weight 'light)
+ (ivy-minibuffer-match-face-2
+ :inherit 'ivy-minibuffer-match-face-1
+ :foreground fw-orange-text
+ :background fw-orange-blend
+ :weight 'semi-bold)
+ (ivy-minibuffer-match-face-3
+ :inherit 'ivy-minibuffer-match-face-2
+ :foreground fw-blue-text
+ :background fw-blue-blend
+ :weight 'semi-bold)
+ (ivy-minibuffer-match-face-4
+ :inherit 'ivy-minibuffer-match-face-2
+ :foreground fw-green-text
+ :background fw-green-blend
+ :weight 'semi-bold)
+ (ivy-minibuffer-match-highlight :foreground bg
+ :background fw-purple-text-sec)
+ (ivy-highlight-face :foreground fw-purple-text)
+ (ivy-confirm-face :foreground success)
+ (ivy-match-required-face :foreground error)
+ (ivy-virtual :inherit 'italic :foreground doc-comments)
+ (ivy-modified-buffer :inherit 'bold :foreground vc-modified)
+ ;;;; ivy-posframe
+ (ivy-posframe :background base0)
+ ;;;; js2-mode
+ (js2-function-param :foreground fg)
+ (js2-function-call :foreground fg )
+ (js2-object-property :foreground fg :inherit 'italic)
+ (js2-jsdoc-tag :foreground doc-comments)
+ (js2-external-variable :foreground fg)
+ ;;;; lsp-mode
+ (lsp-ui-doc-background :background base0)
+ (lsp-face-highlight-read :background (doom-blend red bg 0.3))
+ (lsp-face-highlight-textual :inherit 'lsp-face-highlight-read)
+ (lsp-face-highlight-write :inherit 'lsp-face-highlight-read)
+ ;;;; magit
+ (magit-bisect-bad :background fw-red-blend
+ :foreground fw-red-text)
+ (magit-bisect-good :background fw-green-blend
+ :foreground fw-green-text)
+ (magit-bisect-skip :background fw-orange-blend
+ :foreground fw-orange-text)
+ (magit-blame-date :background fw-base4
+ :foreground fw-red-text)
+ (magit-blame-heading :background fw-base4
+ :foreground fw-orange-text)
+ (magit-branch-current :background bg-alt
+ :foreground fw-blue-text)
+ (magit-branch-local :background bg-alt
+ :foreground fw-teal-text)
+ (magit-branch-remote :background bg-alt
+ :foreground fw-green-text)
+ (magit-cherry-equivalent :background fw-base7
+ :foreground fw-purple-text)
+ (magit-cherry-unmatched :background fw-base7
+ :foreground fw-teal-text)
+
+ (magit-diff-added :foreground fw-green-text-sec
+ :background fw-green-blend
+ :extend t)
+ (magit-diff-added-highlight :foreground fw-green-text
+ :background fw-green-blend
+ :weight 'bold :extend t)
+
+ (magit-diff-base :foreground fw-orange-text-sec
+ :background fw-orange-blend
+ :extend t)
+ (magit-diff-base-highlight :foreground fw-orange-text
+ :background fw-orange-blend
+ :weight 'bold
+ :extend t)
+
+ (magit-diff-context :foreground (doom-darken fg 0.4)
+ :background bg
+ :extend t)
+ (magit-diff-context-highlight :foreground fg
+ :background bg-alt
+ :extend t)
+ (magit-diff-file-heading :foreground fw-purple-text-sec
+ :background fw-purple-blend
+ :weight 'bold
+ :extend t)
+ (magit-diff-file-heading-selection :foreground fw-purple-text
+ :background fw-purple-blend
+ :weight 'bold
+ :extend t)
+ (magit-diff-hunk-heading :foreground fw-purple-text-sec
+ :background fw-purple-blend
+ :extend t)
+ (magit-diff-hunk-heading-selection :foreground fw-purple-text-sec
+ :background fw-purple-blend
+ :extend t)
+ (magit-diff-hunk-heading-highlight :foreground fw-purple-blend
+ :background fw-purple-text-sec
+ :weight 'bold
+ :extend t)
+
+ (magit-diff-removed :foreground fw-red-text-sec
+ :background fw-red-blend
+ :extend t)
+ (magit-diff-removed-highlight :foreground fw-red-text
+ :background fw-red-blend
+ :weight 'bold
+ :extend t)
+
+ (magit-diff-lines-heading :foreground yellow
+ :background red
+ :extend t)
+ (magit-diffstat-added :foreground fw-green)
+ (magit-diffstat-removed :foreground fw-red)
+ (magit-dimmed :foreground comments)
+ (magit-hash :foreground fg-alt)
+ (magit-header-line :background fw-blue-blend
+ :foreground fw-blue-text
+ :weight 'bold
+ :box `(:line-width 3 :color ,fw-blue-blend))
+ (magit-log-author :foreground fw-orange-text-sec)
+ (magit-log-date :foreground fw-blue-text-sec)
+ (magit-log-graph :foreground comments)
+ (magit-process-ng :inherit 'error)
+ (magit-process-ok :inherit 'success)
+ (magit-reflog-amend :foreground magenta)
+ (magit-reflog-checkout :foreground blue)
+ (magit-reflog-cherry-pick :foreground green)
+ (magit-reflog-commit :foreground green)
+ (magit-reflog-merge :foreground green)
+ (magit-reflog-other :foreground cyan)
+ (magit-reflog-rebase :foreground magenta)
+ (magit-reflog-remote :foreground cyan)
+ (magit-reflog-reset :inherit 'error)
+ (magit-refname :foreground comments)
+ (magit-section-heading :foreground blue
+ :weight 'bold
+ :extend t)
+ (magit-section-heading-selection :foreground orange
+ :weight 'bold
+ :extend t)
+ (magit-section-highlight :inherit 'hl-line)
+ (magit-sequence-drop :foreground red)
+ (magit-sequence-head :foreground blue)
+ (magit-sequence-part :foreground orange)
+ (magit-sequence-stop :foreground green)
+ (magit-signature-bad :inherit 'error)
+ (magit-signature-error :inherit 'error)
+ (magit-signature-expired :foreground orange)
+ (magit-signature-good :inherit 'success)
+ (magit-signature-revoked :foreground magenta)
+ (magit-signature-untrusted :foreground yellow)
+ (magit-tag :foreground yellow)
+ (magit-filename :foreground violet)
+ (magit-section-secondary-heading :foreground violet
+ :weight 'bold
+ :extend t)
+ ;;;; makefile-*-mode
+ (makefile-targets :foreground fw-purple-text
+ :background fw-purple-blend)
+ ;;;; markdown-mode
+ (markdown-header-face :inherit 'bold
+ :foreground fw-purple-text
+ :background fw-purple-blend)
+ (markdown-header-delimiter-face :inherit 'markdown-header-face)
+ (markdown-metadata-key-face :foreground fw-green-text
+ :background fw-green-blend)
+ (markdown-list-face :foreground fg
+ :inherit 'bold)
+ (markdown-link-face :foreground fw-blue-text
+ :background fw-blue-blend)
+ (markdown-url-face :foreground fw-blue-text
+ :background fw-blue-blend)
+ (markdown-italic-face :inherit 'italic
+ :foreground fg)
+ (markdown-bold-face :inherit 'bold
+ :foreground fg)
+ (markdown-markup-face :foreground fg
+ :inherit 'bold)
+ (markdown-blockquote-face :inherit 'italic
+ :foreground doc-comments)
+ (markdown-pre-face :foreground fg)
+ (markdown-code-face :background fw-orange-blend
+ :foreground fw-orange-text
+ :extend t)
+ (markdown-reference-face :foreground doc-comments)
+ (markdown-inline-code-face :inherit '(markdown-code-face markdown-pre-face)
+ :extend nil)
+ (markdown-html-attr-name-face :inherit 'font-lock-variable-name-face)
+ (markdown-html-attr-value-face :inherit 'font-lock-string-face)
+ (markdown-html-entity-face :inherit 'font-lock-variable-name-face)
+ (markdown-html-tag-delimiter-face :inherit 'markdown-markup-face)
+ (markdown-html-tag-name-face :inherit 'font-lock-keyword-face)
+ ;;;; org-mode
+ ((outline-1 &override) :foreground red)
+ ((outline-2 &override) :foreground orange)
+ (org-ellipsis :underline nil :background bg :foreground red)
+ ((org-block-begin-line &override)
+ :background fw-orange-blend
+ :foreground fw-orange-text
+ :weight 'semi-bold)
+ ((org-block &override)
+ :background fw-orange-blend
+ :foreground fw-orange-text)
+ ((org-quote &override)
+ :background fw-orange-blend
+ :foreground fw-orange-text)
+ ;;;; racket
+ (racket-keyword-argument-face :foreground fw-orange-text
+ :background fw-orange-blend)
+ (racket-selfeval-face :foreground fw-teal-text
+ :background fw-teal-blend)
+ ;;;; rainbow-delimiters
+ (rainbow-delimiters-depth-1-face :foreground fw-blue-text-sec)
+ (rainbow-delimiters-depth-2-face :foreground fw-purple-text-sec)
+ (rainbow-delimiters-depth-3-face :foreground fw-green-text-sec)
+ (rainbow-delimiters-depth-4-face :foreground fw-orange-text-sec)
+ (rainbow-delimiters-depth-5-face :foreground fw-teal-text-sec)
+ (rainbow-delimiters-depth-6-face :foreground fw-red-text-sec)
+ (rainbow-delimiters-depth-7-face :foreground fw-green-text-sec)
+ (rainbow-delimiters-unmatched-face :foreground red
+ :weight 'bold
+ :inverse-video t)
+ (rainbow-delimiters-mismatched-face :inherit 'rainbow-delimiters-unmatched-face)
+ ;;;; rjsx-mode
+ (rjsx-tag :background fw-purple-blend
+ :foreground fw-purple-text)
+ (rjsx-text :inherit 'default)
+ (rjsx-tag-bracket-face :background bg
+ :foreground fg-alt)
+ (rjsx-attr :background bg
+ :foreground fg
+ :inherit 'italic)
+ ;;;; solaire-mode
+ (solaire-mode-line-face
+ :inherit 'mode-line
+ :background modeline-bg-l
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-l)))
+ (solaire-mode-line-inactive-face
+ :inherit 'mode-line-inactive
+ :background modeline-bg-inactive-l
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive-l)))
+ ;;;; web-mode
+ (web-mode-current-element-highlight-face :background dark-blue
+ :foreground bg)
+ (web-mode-css-property-name-face :foreground fg
+ :inherit 'italic)
+ (web-mode-doctype-face :background bg
+ :foreground comments)
+ (web-mode-html-tag-face :background fw-purple-blend
+ :foreground fw-purple-text)
+ (web-mode-html-attr-name-face :background bg
+ :foreground fg
+ :inherit 'italic)
+ (web-mode-html-attr-value-face :inherit 'font-lock-string-face)
+ (web-mode-html-entity-face :background fw-orange-blend
+ :foreground fw-orange-text
+ :inherit 'italic)
+ (web-mode-block-control-face :background bg
+ :foreground fw-base1)
+ (web-mode-html-tag-bracket-face :background bg
+ :foreground fg-alt)
+ (web-mode-symbol-face :foreground fw-blue-text
+ :background fw-blue-blend)
+ (web-mode-string-face :inherit 'font-lock-string-face)
+ ;;;; wgrep <built-in>
+ (wgrep-face :background base1)
+ ;;;; which-key
+ (which-key-key-face :foreground fw-green-text-sec)
+ (which-key-group-description-face :foreground fw-purple-text-sec)
+ (which-key-command-description-face :foreground fg)
+ (which-key-local-map-description-face :foreground fw-orange-text-sec)
+ (which-key-separator-face :background bg-alt :foreground comments)
+ ;;;; whitespace
+ ((whitespace-tab &override) :background (unless (default-value 'indent-tabs-mode) base0))
+ ((whitespace-indentation &override) :background (if (default-value 'indent-tabs-mode) base0)))
+
+ ;;;; Base theme variable overrides-
+ ()
+ )
+
+;;; doom-flatwhite-theme.el ends here
diff --git a/elpa/doom-themes-20220504.1557/doom-gruvbox-light-theme.el b/elpa/doom-themes-20220504.1557/doom-gruvbox-light-theme.el
new file mode 100644
index 0000000..ad63dd8
--- /dev/null
+++ b/elpa/doom-themes-20220504.1557/doom-gruvbox-light-theme.el
@@ -0,0 +1,489 @@
+;;; doom-gruvbox-light-theme.el --- gruvbox light soft -*- lexical-binding: t; no-byte-compile: t; -*-
+(require 'doom-themes)
+
+;;
+(defgroup doom-gruvbox-light-theme nil
+ "Options for the `doom-gruvbox-light' theme."
+ :group 'doom-themes)
+
+(defcustom doom-gruvbox-light-brighter-modeline nil
+ "If non-nil, more vivid colors will be used to style the mode-line."
+ :group 'doom-gruvbox-light-theme
+ :type 'boolean)
+
+(defcustom doom-gruvbox-light-brighter-comments nil
+ "If non-nil, comments will be highlighted in more vivid colors."
+ :group 'doom-gruvbox-light-theme
+ :type 'boolean)
+
+(defcustom doom-gruvbox-light-comment-bg doom-gruvbox-light-brighter-comments
+ "If non-nil, comments will have a subtle, darker background. Enhancing their
+legibility."
+ :group 'doom-gruvbox-light-theme
+ :type 'boolean)
+
+(defcustom doom-gruvbox-light-padded-modeline doom-themes-padded-modeline
+ "If non-nil, adds a 4px padding to the mode-line. Can be an integer to
+determine the exact padding."
+ :group 'doom-gruvbox-light-theme
+ :type '(choice integer boolean))
+
+(defcustom doom-gruvbox-light-variant nil
+ "A choice of \"hard\" or \"soft\" can be used to change the
+background contrast. All other values default to \"medium\"."
+ :group 'doom-gruvbox-light-theme
+ :type 'string)
+
+;;
+(def-doom-theme doom-gruvbox-light
+ "gruvbox light theme"
+
+ ;; name default 256 16
+ ((bg
+ (cond ((equal doom-gruvbox-light-variant "hard") '("#f9f5d7" "#ffffd7" nil)) ; bg0_h
+ ((equal doom-gruvbox-light-variant "soft") '("#f2e5bc" "#ffffd7" nil)) ; bg0_s
+ (t '("#fbf1c7" "#ffffd7" nil)))) ; bg0
+ (bg-alt
+ (cond ((equal doom-gruvbox-light-variant "hard") '("#fbf1c7" "#ffffd7" nil))
+ ((equal doom-gruvbox-light-variant "soft") '("#ebdbb2" "#ffffaf" nil))
+ (t '("#f2e5bc" "#ffffd7" nil))))
+ (base0 '("#f0f0f0" "#f0f0f0" "white" )) ;;
+ (base1 '("#ebdbb2" "#ffffaf" "brightblack" )) ;; gruvbox-dark1
+ (base2 '("#d5c4a1" "#d7d6af" "brightblack" )) ;; gruvbox-dark2
+ (base3 '("#bdae93" "#afaf87" "brightblack" )) ;; gruvbox-dark3
+ (base4 '("#a89984" "#afafaf" "brightblack" )) ;; gruvbox-dark4
+ (base5 '("#504945" "#4e4e4e" "brightblack" )) ;; gruvbox-light2
+ (base6 '("#3c3836" "#3a3a3a" "brightblack" )) ;; gruvbox-light1
+ (base7 '("#282828" "#262626" "brightblack" )) ;; gruvbox-light0
+ (base8 '("#1d2021" "#1c1c1c" "black" )) ;; gruvbox-light0_hard
+ (fg '("#282828" "#262626" "black" )) ;; gruvbox-light0
+ (fg-alt '("#1c1c1c" "#1c1c1c" "brightblack" )) ;;
+
+
+ (grey '("#928374" "#8a8a8a" "grey" )) ;; gruvbox-gray
+ (red '("#9d0006" "#870000" "red" )) ;; gruvbox-bright_red
+ (orange '("#af3a03" "#af5f00" "brightred" )) ;; gruvbox-bright_orange
+ (green '("#79740e" "#878700" "green" )) ;; gruvbox-bright_green
+ (teal '("#4db5bd" "#44b9b1" "brightgreen" )) ;; gruvbox-
+ (yellow '("#b57614" "#af8700" "yellow" )) ;; gruvbox-bright_yellow
+ (blue '("#076678" "#005f87" "brightblue" )) ;; gruvbox-bright_blue
+ (dark-blue '("#2b3c44" "#000087" "blue" )) ;; gruvbox-dark_blue
+ (magenta '("#b16286" "#d75f87" "magenta" )) ;; gruvbox-faded_purple
+ (violet '("#8f3f71" "#875f87" "brightmagenta" )) ;; gruvbox-bright_purple
+ (cyan '("#427b58" "#5f8787" "brightcyan" )) ;; gruvbox-bright_aqua
+ (dark-cyan '("#36473a" "#005f5f" "cyan" )) ;; gruvbox-dark_aqua
+
+ ;; Extra
+ (delimiter-3 '("#8ec07c" "#87af87" ))
+ (light3 '("#665c54" "#626262" "grey" ))
+ (light4 '("#7c6f64" "#767676" "grey" ))
+ (faded-red '("#cc241d" "#d75f5f" "red" ))
+ (faded-green '("#98971a" "#afaf00" "green" ))
+ (faded-yellow '("#d79921" "#ffaf00" "yellow" ))
+ (faded-blue '("#458588" "#87afaf" "blue" ))
+ (faded-orange '("#d65d0e" "#ff8700" "brightorange" ))
+ (faded-aqua '("#689d6a" "#87af87" "brightcyan" ))
+ (dark-red '("#421E1E" "#5f0000" ))
+ (dark-blue '("#2B3C44" "#000087" ))
+ (dark-aqua '("#36473A" "#005f5f" ))
+ (sienna '("#dd6f48" "d7875f" ))
+ (lightblue4 '("#66999D" "#5fafaf" "brightblue" ))
+ (burlywood4 '("#BBAA97" "#aafaf87" ))
+ (aquamarine4 '("#83af98" "#87af87" ))
+ (turquoise4 '("#61ACBB" "#5fafaf" "brightblue" ))
+
+ ;; face categories -- required for all themes
+ (highlight base4)
+ (vertical-bar (doom-darken base1 0.1))
+ (selection base3)
+ (builtin orange)
+ (comments (if doom-gruvbox-light-brighter-comments base5 base4))
+ (doc-comments green)
+ (constants violet)
+ (functions yellow)
+ (keywords red)
+ (methods cyan)
+ (operators blue)
+ (type violet)
+ (strings green)
+ (variables blue)
+ (numbers violet)
+ (region `(,(doom-darken (car bg-alt) 0.1) ,@(doom-darken (cdr base0) 0.3)))
+ (error red)
+ (warning orange)
+ (success green)
+ (vc-modified orange)
+ (vc-added green)
+ (vc-deleted red)
+
+ ;; custom categories
+ (-modeline-bright doom-gruvbox-light-brighter-modeline)
+ (-modeline-pad
+ (when doom-gruvbox-light-padded-modeline
+ (if (integerp doom-gruvbox-light-padded-modeline) doom-gruvbox-light-padded-modeline 4)))
+
+ (modeline-fg nil)
+ (modeline-fg-alt (doom-blend violet base4 (if -modeline-bright 0.5 0.2)))
+
+ (modeline-bg
+ (if -modeline-bright
+ (doom-darken base2 0.05)
+ base1))
+ (modeline-bg-l
+ (if -modeline-bright
+ (doom-darken base2 0.1)
+ base2))
+ (modeline-bg-inactive (doom-darken bg 0.1))
+ (modeline-bg-inactive-l `(,(doom-darken (car bg-alt) 0.05) ,@(cdr base1))))
+
+
+ ;;;; Base theme face overrides
+ ((cursor :background base4)
+ ((font-lock-comment-face &override) :background (if doom-gruvbox-light-comment-bg base0))
+ ((font-lock-doc-face &override) :slant 'italic)
+ (isearch :foreground "black" :background orange)
+ (isearch-fail :foreground fg :background red)
+ (lazy-highlight :background base2 :foreground base8 :distant-foreground base0 :weight 'bold)
+ ((line-number &override) :foreground base4)
+ ((line-number-current-line &override) :foreground orange)
+ (mode-line
+ :background modeline-bg :foreground modeline-fg
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg)))
+ (mode-line-inactive
+ :background modeline-bg-inactive :foreground modeline-fg-alt
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive)))
+ (mode-line-emphasis :foreground (if -modeline-bright base8 highlight))
+ (tooltip :background base1 :foreground base6)
+
+ ;;;; anzu
+ (anzu-mode-line :foreground yellow :weight 'bold)
+ (anzu-match-1 :background green)
+ (anzu-match-2 :background faded-yellow)
+ (anzu-match-3 :background aquamarine4)
+ (anzu-replace-to :foreground yellow)
+ (anzu-replace-highlight :inherit 'isearch)
+ ;;;; centaur-tabs
+ (centaur-tabs-unselected :background bg-alt :foreground base4)
+ ;;;; company
+ (company-scrollbar-bg :background base1)
+ (company-scrollbar-fg :background bg-alt)
+ (company-tooltip :background bg-alt)
+ (company-tooltip-annotation :foreground green)
+ (company-tooltip-annotation-selection :inherit 'company-tooltip-annotation)
+ (company-tooltip-selection :foreground violet :background base2)
+ (company-tooltip-common :foreground blue :underline t)
+ (company-tooltip-common-selection :foreground blue :underline t)
+ (company-preview-common :foreground base7)
+ (company-preview :background lightblue4)
+ (company-preview-search :background turquoise4)
+ (company-template-field :foreground "black" :background yellow)
+ (company-echo-common :foreground faded-red)
+ ;;;; css-mode <built-in> / scss-mode
+ (css-proprietary-property :foreground orange)
+ (css-property :foreground green)
+ (css-selector :foreground blue)
+ ;;;; doom-modeline
+ (doom-modeline-bar :background (if -modeline-bright modeline-bg highlight))
+ ;;;; diredfl
+ (diredfl-autofile-name :foreground base5)
+ (diredfl-compressed-file-name :foreground base5)
+ (diredfl-compressed-file-suffix :foreground faded-blue)
+ (diredfl-dir-priv :foreground blue :backgtround dark-blue)
+ (diredfl-exec-priv :foreground blue :backgrond dark-blue)
+ (diredfl-file-name :foreground base5)
+ (diredfl-file-suffix :foreground light4)
+ (diredfl-link-priv :foreground magenta)
+ (diredfl-no-priv :foreground base5)
+ (diredfl-number :foreground yellow)
+ (diredfl-other-priv :foreground violet)
+ (diredfl-rare-priv :foreground base5)
+ ;;;; diredp
+ (diredp-file-name :foreground base5)
+ (diredp-file-suffix :foreground light4)
+ (diredp-compressed-file-suffix :foreground faded-blue)
+ (diredp-dir-name :foreground faded-blue)
+ (diredp-symlink :foreground orange)
+ (diredp-date-time :foreground light3)
+ (diredp-number :foreground faded-blue)
+ (diredp-no-priv :foreground base4)
+ (diredp-other-priv :foreground base2)
+ (diredp-rare-priv :foreground base4)
+ (diredp-ignored-file-name :foreground base5)
+ (diredp-dir-priv :foreground faded-blue :background dark-blue)
+ ((diredp-dir-exec-priv &inherit diredp-dir-priv))
+ (diredp-link-priv :foreground faded-aqua)
+ ;;;; doom-emacs
+ (doom-dashboard-banner :foreground (doom-darken base4 0.3))
+ (doom-dashboard-menu-title :foreground green)
+ (doom-dashboard-menu-desc :foreground green)
+ (doom-dashboard-footer-icon :foreground (doom-darken yellow 0.4))
+ (doom-dashboard-loaded :foreground yellow)
+ ;;;; diff-mode
+ (diff-changed :background nil :foreground base6)
+ (diff-removed :background nil :foreground red)
+ (diff-indicator-changed :inherit 'diff-changed)
+ (diff-indicator-added :inherit 'diff-added)
+ (diff-indicator-removed :inherit 'diff-removed)
+ ;;;; ediff <built-in>
+ (ediff-current-diff-A :foreground red :background (doom-lighten red 0.8))
+ (ediff-current-diff-B :foreground green :background (doom-lighten green 0.8))
+ (ediff-current-diff-C :foreground blue :background (doom-lighten blue 0.8))
+ (ediff-current-diff-Ancestor :foreground teal :background (doom-lighten teal 0.8))
+ ;;;; elfeed
+ (elfeed-search-title-face :foreground grey)
+ (elfeed-search-date-face :inherit 'font-lock-builtin-face :underline t)
+ (elfeed-search-tag-face :inherit 'font-lock-keyword-face)
+ (elfeed-search-unread-count-face :inherit 'font-lock-comment-face)
+ (elfeed-search-filter-face :inherit 'font-lock-string-face)
+ ;;;; flycheck
+ (flycheck-info :underline `(:style wave :color ,blue))
+ ;;;; git-gutter
+ (git-gutter:modified :foreground faded-blue :background blue)
+ (git-gutter:added :foreground faded-green :background green)
+ (git-gutter:deleted :foreground faded-red :backgrond red)
+ ;;;; git-gutter+
+ (git-gutter+-modified :foreground faded-blue :background blue)
+ (git-gutter+-added :foreground faded-green :background green)
+ (git-gutter+-deleted :foreground faded-red :backgrond red)
+ ;;;; helm
+ (helm-candidate-number :background blue :foreground bg)
+ (helm-M-x-key :foreground orange)
+ (helm-action :foreground base8 :underline t)
+ (helm-bookmark-addressbook :foreground red)
+ (helm-bookmark-directory :foreground violet)
+ (helm-bookmark-file :foreground faded-blue)
+ (helm-bookmark-gnus :foreground magenta)
+ (helm-bookmark-info :foreground turquoise4)
+ (helm-bookmark-man :foreground sienna)
+ (helm-bookmark-w3m :foreground yellow)
+ (helm-buffer-directory :foreground "white" :background blue)
+ (helm-buffer-not-saved :foreground red)
+ (helm-buffer-process :foreground burlywood4)
+ (helm-buffer-saved-out :foreground red)
+ (helm-buffer-size :foreground violet)
+ (helm-candidate-number :foreground green)
+ (helm-ff-directory :foreground violet)
+ (helm-ff-executable :foreground turquoise4)
+ (helm-ff-file :foreground sienna)
+ (helm-ff-invalid-symlink :foreground "white" :background red)
+ (helm-ff-prefix :foreground "black" :background yellow)
+ (helm-ff-symlink :foreground orange)
+ (helm-grep-cmd-line :foreground green)
+ (helm-grep-file :foreground magenta)
+ (helm-grep-finish :foreground turquoise4)
+ (helm-grep-lineno :foreground orange)
+ (helm-grep-match :foreground yellow)
+ (helm-grep-running :foreground red)
+ (helm-header :foreground aquamarine4)
+ (helm-helper :foreground aquamarine4)
+ (helm-history-deleted :foreground "black" :background red)
+ (helm-history-remote :foreground faded-red)
+ (helm-lisp-completion-info :foreground faded-orange)
+ (helm-lisp-show-completion :foreground red)
+ (helm-locate-finish :foreground "white" :background aquamarine4)
+ (helm-match :foreground orange)
+ (helm-moccur-buffer :foreground cyan :underline t)
+ (helm-prefarg :foreground turquoise4)
+ (helm-selection :foreground "white" :background base2)
+ (helm-selection-line :foreground "white" :background base2)
+ (helm-separator :foreground faded-red)
+ (helm-source-header :foreground base5)
+ (helm-visible-mark :foreground "black" :background light3)
+ ;;;; ivy
+ (ivy-minibuffer-match-face-1 :foreground orange)
+ (ivy-minibuffer-match-face-2 :foreground yellow)
+ (ivy-minibuffer-match-face-3 :foreground faded-orange)
+ (ivy-minibuffer-match-face-4 :foreground faded-yellow)
+ ;;;; ivy-posframe
+ (ivy-posframe :background bg-alt)
+ ;;;; js2-mode
+ (js2-warning :underline `(:style wave :color ,yellow))
+ (js2-error :underline `(:style wave :color ,red))
+ (js2-external-variable :underline `(:style wave :color ,cyan))
+ (js2-jsdoc-tag :background nil :foreground grey )
+ (js2-jsdoc-type :background nil :foreground light4)
+ (js2-jsdoc-value :background nil :foreground light3)
+ (js2-function-param :background nil :foreground cyan)
+ (js2-function-call :background nil :foreground blue)
+ (js2-instance-member :background nil :foreground orange)
+ (js2-private-member :background nil :foreground yellow)
+ (js2-private-function-call :background nil :foreground faded-aqua)
+ (js2-jsdoc-html-tag-name :background nil :foreground light4)
+ (js2-jsdoc-html-tag-delimiter :background nil :foreground light3)
+ ;;;; lsp-mode
+ (lsp-face-highlight-textual :background (doom-blend bg orange 0.9) :foreground base0 :distant-foreground base8)
+ ;;;; lsp-ui
+ (lsp-ui-doc-background :background base2)
+ ;;;; magit
+ (magit-bisect-bad :foreground faded-red)
+ (magit-bisect-good :foreground faded-green)
+ (magit-bisect-skip :foreground faded-yellow)
+ (magit-blame-heading :foreground base7 :background base2)
+ (magit-branch-local :foreground blue)
+ (magit-branch-current :underline blue :inherit 'magit-branch-local)
+ (magit-branch-remote :foreground green)
+ (magit-cherry-equivalent :foreground violet)
+ (magit-cherry-unmatched :foreground cyan)
+ (magit-diff-added :foreground green)
+ (magit-diff-added-highlight :foreground green :inherit 'magit-diff-context-highlight)
+ (magit-diff-base :background faded-yellow :foreground base5)
+ (magit-diff-base-highlight :background faded-yellow :foreground base7)
+ (magit-diff-context :foreground base1 :foreground base6)
+ (magit-diff-context-highlight :background base1 :foreground base7)
+ (magit-diff-hunk-heading :background base3 :foreground base5)
+ (magit-diff-hunk-heading-highlight :background base2 :foreground base7)
+ (magit-diff-hunk-heading-selection :background base2 :foreground orange)
+ (magit-diff-lines-heading :background faded-orange :foreground base7)
+ (magit-diff-removed :foreground red)
+ (magit-diff-removed-highlight :foreground red :inherit 'magit-diff-context-highlight)
+ (magit-diffstat-added :foreground faded-green)
+ (magit-diffstat-removed :foreground faded-red)
+ (magit-dimmed :foreground base4)
+ (magit-hash :foreground blue)
+ (magit-log-author :foreground red)
+ (magit-log-date :foreground cyan)
+ (magit-log-graph :foreground base4)
+ (magit-process-ng :foreground red :weight 'bold)
+ (magit-process-ok :foreground green :weight 'bold)
+ (magit-reflog-amend :foreground violet)
+ (magit-reflog-checkout :foreground blue)
+ (magit-reflog-cherry-pick :foreground green)
+ (magit-reflog-commit :foreground green)
+ (magit-reflog-merge :foreground green)
+ (magit-reflog-other :foreground cyan)
+ (magit-reflog-rebase :foreground violet)
+ (magit-reflog-remote :foreground blue)
+ (magit-reflog-reset :foreground red)
+ (magit-refname :foreground light4)
+ (magit-section-heading :foreground yellow :weight 'bold)
+ (magit-section-heading-selection :foreground faded-yellow)
+ (magit-section-highlight :background base1)
+ (magit-sequence-drop :foreground faded-yellow)
+ (magit-sequence-head :foreground cyan)
+ (magit-sequence-part :foreground yellow)
+ (magit-sequence-stop :foreground green)
+ (magit-signature-bad :foreground red :weight 'bold)
+ (magit-signature-error :foreground red)
+ (magit-signature-expired :foreground orange)
+ (magit-signature-good :foreground green)
+ (magit-signature-revoked :foreground violet)
+ (magit-signature-untrusted :foreground blue)
+ (magit-tag :foreground yellow)
+ ;;;; markdown-mode
+ (markdown-markup-face :foreground base5)
+ (markdown-header-face :inherit 'bold :foreground red)
+ ((markdown-code-face &override) :background base1)
+ (mmm-default-submode-face :background base1)
+ (markdown-header-face-1 :foreground blue)
+ (markdown-header-face-2 :foreground yellow)
+ (markdown-header-face-3 :foreground violet)
+ (markdown-header-face-4 :foreground red)
+ (markdown-header-face-5 :foreground green)
+ (markdown-header-face-6 :foreground dark-cyan)
+ ;;;; message <built-in>
+ (message-header-cc :inherit 'font-lock-variable-name-face)
+ (message-header-subject :foreground orange :weight 'bold)
+ (message-header-other :inherit 'font-lock-variable-name-face)
+ (message-header-name :inherit 'font-lock-keyword-face)
+ (message-cited-text :inherit 'font-lock-comment-face)
+ (message-mml :foregrond faded-green :weight 'bold)
+ ;;;; mu4e
+ (mu4e-highlight-face :foreground green)
+ (mu4e-unread-face :foreground blue :weight 'bold)
+ (mu4e-header-key-face :foreground green :weight 'bold)
+ ;;;; outline <built-in>
+ ((outline-1 &override) :foreground red)
+ ((outline-2 &override) :foreground orange)
+ ;;;; org <built-in>
+ (org-agenda-date-today :foreground base7 :weight 'bold :italic t)
+ (org-agenda-done :foreground cyan)
+ (org-agenda-structure :inherit 'font-lock-comment-face)
+ (org-archived :foreground base7 :weight 'bold)
+ (org-block :background base1 :extend t)
+ (org-block-begin-line :background base2 :extend t)
+ (org-block-end-line :background base2 :extend t)
+ (org-date :foreground blue :underline t)
+ (org-deadline-announce :foreground faded-red)
+ (org-document-info :foreground faded-blue)
+ (org-document-title :foreground faded-blue)
+ (org-done :foreground cyan :weight 'bold :bold t)
+ (org-drawer :inherit 'font-lock-function-name-face)
+ (org-ellipsis :foreground light4)
+ (org-footnote :foreground cyan :underline t)
+ (org-formula :foreground yellow)
+ (org-headline-done :foreground cyan)
+ (org-latex-and-related :foreground blue)
+ (org-level-1 :foreground blue)
+ (org-level-2 :foreground yellow)
+ (org-level-3 :foreground violet)
+ (org-level-4 :foreground red)
+ (org-level-5 :foreground green)
+ (org-level-6 :foreground cyan)
+ (org-level-7 :foreground faded-blue)
+ (org-level-8 :foreground orange)
+ (org-link :foreground faded-aqua :underline t)
+ (org-scheduled :foreground yellow)
+ (org-scheduled-previously :foreground faded-red)
+ (org-scheduled-today :foreground blue)
+ (org-sexp-date :foreground faded-blue :underline t)
+ (org-table :foreground blue)
+ (org-tag :bold t :weight 'bold)
+ (org-time-grid :foreground faded-orange)
+ (org-todo :foreground red :weight 'bold :bold t)
+ (org-upcoming-deadline :inherit 'font-lock-keyword-face)
+ (org-warning :foreground red :weight 'bold :bold t)
+ ;;;; org-habit
+ (org-habit-clear-face :background faded-blue)
+ (org-habit-clear-future-face :background blue)
+ (org-habit-ready-face :background faded-green)
+ (org-habit-ready-future-face :background green)
+ (org-habit-alert-face :background faded-yellow)
+ (org-habit-alert-future-face :background yellow)
+ (org-habit-overdue-face :background faded-red)
+ (org-habit-overdue-future-face :background red)
+ ;;;; popup
+ (popup-face :foreground base6 :background base1)
+ (popup-menu-selection-face :foreground fg :background faded-green)
+ (popup-menu-mouse-face :foreground fg :background faded-green)
+ (popup-tip-face :foreground base5 :background base2)
+ ;;;; rainbow-delimiters
+ (rainbow-delimiters-depth-3-face :foreground delimiter-3)
+ (rainbow-delimiters-depth-4-face :foreground faded-orange)
+ (rainbow-delimiters-depth-7-face :foreground delimiter-3)
+ (rainbox-delimiters-depth-8-face :foreground faded-orange)
+ (rainbow-delimiters-depth-11-face :foreground delimiter-3)
+ (rainbox-delimiters-depth-12-face :foreground faded-orange)
+ (rainbow-delimiters-unmatched-face: :foreground fg :background 'nil)
+ ;;;; swiper
+ (swiper-line-face :background base3 :foreground base0)
+ (swiper-match-face-1 :inherit 'unspecified :background base1 :foreground base5)
+ (swiper-match-face-2 :inherit 'unspecified :background orange :foreground base0 :weight 'bold)
+ (swiper-match-face-3 :inherit 'unspecified :background violet :foreground base1 :weight 'bold)
+ (swiper-match-face-4 :inherit 'unspecified :background green :foreground base2 :weight 'bold)
+ (swiper-background-match-face-1 :inherit 'unspecified :background base2)
+ (swiper-background-match-face-2 :inherit 'unspecified :background base3)
+ (swiper-background-match-face-3 :inherit 'unspecified :background base4)
+ (swiper-background-match-face-4 :inherit 'unspecified :background base5)
+ ;;;; solaire-mode
+ (solaire-mode-line-face
+ :inherit 'mode-line
+ :background modeline-bg-l
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-l)))
+ (solaire-mode-line-inactive-face
+ :inherit 'mode-line-inactive
+ :background modeline-bg-inactive-l
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive-l)))
+ ;;;; web-mode
+ (web-mode-current-element-highlight-face :background dark-blue :foreground bg)
+ ;;;; wgrep <built-in>
+ (wgrep-face :background base1)
+ ;;;; whitespace <built-in>
+ (whitespace-trailing :foreground red :background base1)
+ (whitespace-line :foreground red :background base1)
+ (whitespace-indentation :foreground base4 :background bg)
+ (whitespace-empty :foreground 'nil :background 'nil))
+
+ ;;;; Base theme variable overrides-
+ ())
+
+;;; doom-gruvbox-light-theme.el ends here
diff --git a/elpa/doom-themes-20220504.1557/doom-gruvbox-theme.el b/elpa/doom-themes-20220504.1557/doom-gruvbox-theme.el
new file mode 100644
index 0000000..e140053
--- /dev/null
+++ b/elpa/doom-themes-20220504.1557/doom-gruvbox-theme.el
@@ -0,0 +1,285 @@
+;; doom-gruvbox-theme.el --- inspired by morhetz Gruvbox -*- lexical-binding: t; no-byte-compile: t; -*-
+(require 'doom-themes)
+
+;; Compiler pacifier
+(defvar modeline-bg)
+
+;;
+(defgroup doom-gruvbox-theme nil
+ "Options for doom-gruvbox."
+ :group 'doom-themes)
+
+(defcustom doom-gruvbox-brighter-comments nil
+ "If non-nil, comments will be highlighted in more vivid colors."
+ :group 'doom-gruvbox-theme
+ :type 'boolean)
+
+(defcustom doom-gruvbox-padded-modeline doom-themes-padded-modeline
+ "If non-nil, adds a 4px padding to the mode-line. Can be an integer to
+determine the exact padding."
+ :group 'doom-gruvbox-theme
+ :type '(choice integer boolean))
+
+(defcustom doom-gruvbox-dark-variant nil
+ "A choice of \"hard\" or \"soft\" can be used to change the
+background contrast. All other values default to \"medium\"."
+ :group 'doom-gruvbox-theme
+ :type 'string)
+
+;;
+(def-doom-theme doom-gruvbox
+ "Dark theme with pastel 'retro groove' colors."
+
+ ;; name gui 256 16
+ ((bg
+ (cond ((equal doom-gruvbox-dark-variant "hard") '("#1d2021" "#1e1e1e" nil)) ; bg0_h
+ ((equal doom-gruvbox-dark-variant "soft") '("#32302f" "#323232" nil)) ; bg0_s
+ (t '("#282828" "#282828" nil)))) ; bg0
+ (bg-alt
+ (cond ((equal doom-gruvbox-dark-variant "hard") '("#0d1011" "black" nil)) ; (self-defined)
+ ((equal doom-gruvbox-dark-variant "soft") '("#282828" "#282828" nil)) ; bg0
+ (t '("#1d2021" "#1e1e1e" nil)))) ; bg_h
+ (bg-alt2 '("#504945" "#504945" "brown" )) ; bg2 (for region, selection etc.)
+
+ (base0 '("#0d1011" "black" "black" )) ; (self-defined)
+ (base1 '("#1d2021" "#1d1d1d" "brightblack")) ; bg0_h
+ (base2 '("#282828" "#282828" "brightblack")) ; bg0
+ (base3 '("#3c3836" "#383838" "brightblack")) ; bg1
+ (base4 '("#665c54" "#5c5c5c" "brightblack")) ; bg3
+ (base5 '("#7c6f64" "#6f6f6f" "brightblack")) ; bg4
+ (base6 '("#928374" "#909090" "brightblack")) ; gray
+ (base7 '("#d5c4a1" "#cccccc" "brightblack")) ; fg2
+ (base8 '("#fbf1c7" "#fbfbfb" "brightwhite")) ; fg0
+ (fg '("#ebdbb2" "#dfdfdf" "brightwhite")) ; fg/fg1
+ (fg-alt '("#d5c4a1" "#cccccc" "brightwhite")) ; fg2
+
+ ;; Standardized official colours from gruvbox
+ (grey '("#928374" "#909090" "brightblack")) ; gray
+ (red '("#fb4934" "#e74c3c" "red")) ; bright-red
+ (magenta '("#cc241d" "#cc241d" "magenta")) ; red
+ (violet '("#d3869b" "#d3869b" "brightmagenta")) ; bright-purple
+ (orange '("#fe8019" "#fd971f" "orange")) ; bright-orange
+ (yellow '("#fabd2f" "#fabd2f" "yellow")) ; bright-yellow
+ (dark-yellow '("#d79921" "#fabd2f" "yellow")) ; yellow
+ (teal '("#8ec07c" "#8ec07c" "green")) ; bright-aqua
+ (green '("#b8bb26" "#b8bb26" "green")) ; bright-green
+ (dark-green '("#98971a" "#98971a" "green")) ; green
+ (blue '("#83a598" "#83a598" "brightblue")) ; bright-blue
+ (dark-blue '("#458588" "#458588" "blue")) ; blue
+ (cyan '("#8ec07c" "#8ec07c" "brightcyan")) ; bright-aqua
+ (my-black '("#37302f" "#37302f" "black"))
+ (dark-cyan '("#689d6a" "#689d6a" "cyan")) ; aqua
+
+ ;; face categories
+ (highlight yellow)
+ (vertical-bar bg-alt2)
+ (selection bg-alt2)
+ (builtin orange)
+ (comments (if doom-gruvbox-brighter-comments magenta grey))
+ (doc-comments (if doom-gruvbox-brighter-comments (doom-lighten magenta 0.2) (doom-lighten fg-alt 0.25)))
+ (constants violet)
+ (functions green)
+ (keywords red)
+ (methods green)
+ (operators fg)
+ (type yellow)
+ (strings green)
+ (variables blue)
+ (numbers violet)
+ (region bg-alt2)
+ (error red)
+ (warning yellow)
+ (success green)
+
+ (vc-modified (doom-darken cyan 0.15))
+ (vc-added (doom-darken green 0.15))
+ (vc-deleted (doom-darken red 0.15))
+
+ ;; custom categories
+ (-modeline-pad
+ (when doom-gruvbox-padded-modeline
+ (if (integerp doom-gruvbox-padded-modeline)
+ doom-gruvbox-padded-modeline
+ 4)))
+ (modeline-bg bg-alt2)
+ (modeline-fg (doom-lighten fg-alt 0.25))
+ (modeline-inactive-bg (doom-darken modeline-bg 0.15))
+ (modeline-inactive-fg base6)
+
+ (org-quote `(,(doom-lighten (car bg) 0.05) "#1f1f1f")))
+
+
+ ;;;; Base theme face overrides
+ ((button :foreground cyan :underline t :weight 'bold)
+ (cursor :background "white")
+ (hl-line :background base3)
+ ((line-number &override) :foreground base5)
+ ((line-number-current-line &override) :background base3 :foreground yellow)
+ (isearch :foreground base0 :background orange)
+ (lazy-highlight :background yellow :foreground base0 :distant-foreground base0 :bold bold)
+ ((link &override) :foreground violet)
+ (minibuffer-prompt :foreground cyan)
+ (mode-line
+ :background my-black :foreground modeline-fg
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg)))
+ (mode-line-inactive
+ :background bg :foreground base4
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-inactive-bg)))
+
+ ;;;; company
+ (company-preview-common :foreground cyan)
+ (company-tooltip-common :foreground cyan)
+ (company-tooltip-common-selection :foreground cyan)
+ (company-tooltip-annotation :foreground cyan)
+ (company-tooltip-annotation-selection :foreground cyan)
+ (company-scrollbar-bg :background base3)
+ (company-scrollbar-fg :background cyan)
+ (company-tooltip-selection :background bg-alt2)
+ (company-tooltip-mouse :background bg-alt2 :foreground nil)
+ ;;;; css-mode <built-in> / scss-mode
+ (css-proprietary-property :foreground keywords)
+ ;;;; doom-emacs
+ (+workspace-tab-selected-face :background dark-green :foreground "white")
+ ;;;; doom-modeline
+ (doom-modeline-project-dir :bold t :foreground cyan)
+ (doom-modeline-buffer-path :inherit 'bold :foreground green)
+ (doom-modeline-buffer-file :inherit 'bold :foreground fg)
+ (doom-modeline-buffer-modified :inherit 'bold :foreground yellow)
+ (doom-modeline-error :background bg)
+ (doom-modeline-buffer-major-mode :foreground green :bold t)
+ (doom-modeline-info :bold t :foreground cyan)
+ (doom-modeline-bar :background dark-green)
+ (doom-modeline-panel :background dark-green :foreground fg)
+ ;;;; doom-themes
+ (doom-themes-neotree-file-face :foreground fg)
+ (doom-themes-neotree-hidden-file-face :foreground (doom-lighten fg-alt 0.25))
+ (doom-themes-neotree-media-file-face :foreground (doom-lighten fg-alt 0.25))
+ ;;;; emacs-lisp-mode
+ (highlight-quoted-symbol :foreground dark-cyan)
+ ;;;; ediff <built-in>
+ (ediff-fine-diff-A :background (doom-blend red bg 0.4) :weight 'bold)
+ (ediff-current-diff-A :background (doom-blend red bg 0.2))
+ ;;;; evil
+ (evil-search-highlight-persist-highlight-face :background yellow)
+ (evil-ex-substitute-replacement :foreground cyan :strike-through nil :inherit 'evil-ex-substitute-matches)
+ ;;;; evil-snipe
+ (evil-snipe-first-match-face :foreground "white" :background yellow)
+ (evil-snipe-matches-face :foreground yellow :bold t :underline t)
+ ;;;; flycheck
+ (flycheck-error :underline `(:style wave :color ,red) :background base3)
+ (flycheck-warning :underline `(:style wave :color ,yellow) :background base3)
+ (flycheck-info :underline `(:style wave :color ,blue) :background base3)
+ ;;;; dired
+ (dired-directory :foreground cyan)
+ (dired-marked :foreground yellow)
+ (dired-symlink :foreground cyan)
+ (dired-header :foreground cyan)
+ ;;;; helm
+ (helm-swoop-target-line-face :foreground magenta :inverse-video t)
+ ;;;; highlight-thing
+ (highlight-thing :background (doom-lighten base3 0.03) :distant-foreground fg-alt)
+ ;;;; highlight-symbol
+ (highlight-symbol-face :background (doom-lighten base3 0.03) :distant-foreground fg-alt)
+ ;;;; ivy
+ (ivy-current-match :background bg-alt2)
+ (ivy-subdir :background nil :foreground cyan)
+ (ivy-action :background nil :foreground cyan)
+ (ivy-grep-line-number :background nil :foreground cyan)
+ (ivy-minibuffer-match-face-1 :background nil :foreground yellow)
+ (ivy-minibuffer-match-face-2 :background nil :foreground yellow)
+ (ivy-minibuffer-match-highlight :foreground cyan)
+ (counsel-key-binding :foreground cyan)
+ ;;;; ivy-posframe
+ (ivy-posframe :background base3)
+ (ivy-posframe-border :background base1)
+ ;;;; LaTeX-mode
+ (font-latex-math-face :foreground dark-cyan)
+ ;;;; magit
+ (magit-section-heading :foreground cyan :weight 'bold)
+ (magit-branch-current :underline green :inherit 'magit-branch-local)
+ (magit-diff-hunk-heading :background base3 :foreground fg-alt)
+ (magit-diff-hunk-heading-highlight :background bg-alt2 :foreground fg)
+ (magit-diff-context :foreground base3 :foreground fg-alt)
+ ;;;; markdown-mode
+ (markdown-header-face :inherit 'bold :foreground green)
+ (markdown-header-delimiter-face :foreground orange)
+ (markdown-blockquote-face :inherit 'italic :foreground grey)
+ (markdown-list-face :foreground grey)
+ (markdown-url-face :foreground violet)
+ (markdown-pre-face :foreground cyan)
+ (markdown-link-face :inherit 'underline :foreground grey)
+ ((markdown-code-face &override) :background (doom-lighten base2 0.045))
+ ;;;; mu4e-view
+ (mu4e-header-key-face :foreground red :weight 'bold)
+ ;;;; neotree
+ (neo-root-dir-face :foreground cyan)
+ (doom-neotree-dir-face :foreground cyan)
+ (neo-dir-link-face :foreground cyan)
+ (neo-expand-btn-face :foreground magenta)
+ ;;;; outline <built-in>
+ ((outline-1 &override) :foreground violet)
+ ((outline-2 &override) :foreground cyan)
+ ((outline-3 &override) :foreground green)
+ ((outline-4 &override) :foreground (doom-lighten violet 0.2))
+ ((outline-5 &override) :foreground (doom-lighten dark-cyan 0.25))
+ ((outline-6 &override) :foreground (doom-lighten violet 0.4))
+ ((outline-7 &override) :foreground (doom-lighten dark-cyan 0.5))
+ ((outline-8 &override) :foreground (doom-lighten violet 0.6))
+ ; ((outline-1 &override) :foreground green)
+ ; ((outline-2 &override) :foreground green)
+ ; ((outline-3 &override) :foreground yellow)
+ ; ((outline-4 &override) :foreground yellow)
+ ; ((outline-5 &override) :foreground dark-yellow)
+ ; ((outline-6 &override) :foreground dark-yellow)
+ ;;;; org <built-in>
+ ((org-code &override) :foreground orange)
+ (org-date :foreground green)
+ (org-document-info :foreground red)
+ (org-document-title :foreground red)
+ (org-drawer :foreground (doom-lighten cyan 0.4))
+ (org-ellipsis :underline nil :foreground orange)
+ (org-formula :foreground green)
+ (org-meta-line :foreground comments)
+ (org-list-dt :foreground cyan)
+ ; (org-list-dt :foreground yellow)
+ ((org-quote &override) :inherit 'italic :foreground base7 :background org-quote)
+ (org-table :foreground cyan)
+ (org-tag :foreground (doom-darken comments 0.15) :weight 'normal)
+ ; (org-tag :foreground yellow :bold nil)
+ (org-todo :foreground green :bold 'inherit)
+ ; (org-todo :foreground yellow :bold 'inherit)
+ (org-verbatim :foreground yellow)
+ ;;;; rainbow-delimiters
+ (rainbow-delimiters-depth-1-face :foreground orange)
+ (rainbow-delimiters-depth-2-face :foreground magenta)
+ (rainbow-delimiters-depth-3-face :foreground green)
+ (rainbow-delimiters-depth-4-face :foreground blue)
+ ;;;; show-paren <built-in>
+ ((show-paren-match &override) :foreground nil :background base5 :bold t)
+ ((show-paren-mismatch &override) :foreground nil :background "red")
+ ;;;; swiper
+ (swiper-line-face :background bg-alt2)
+ ;;;; undo-tree
+ (undo-tree-visualizer-active-branch-face :foreground cyan)
+ (undo-tree-visualizer-current-face :foreground yellow)
+ ;;;; vimish-fold
+ ((vimish-fold-overlay &override) :inherit 'font-lock-comment-face :background bg-alt2 :weight 'light)
+ ((vimish-fold-mouse-face &override) :foreground "white" :background yellow :weight 'light)
+ ((vimish-fold-fringe &override) :foreground magenta :background magenta)
+ ;;;; web-mode
+ (web-mode-html-tag-bracket-face :foreground blue)
+ (web-mode-html-tag-face :foreground cyan)
+ (web-mode-html-attr-name-face :foreground cyan)
+ (web-mode-json-key-face :foreground green)
+ (web-mode-json-context-face :foreground cyan)
+ ;;;; which-key
+ (which-key-key-face :foreground green)
+ (which-key-group-description-face :foreground red)
+ (which-key-command-description-face :foreground blue)
+ (which-key-local-map-description-face :foreground orange))
+
+ ;;;; Base theme variable overrides
+ ;; ()
+ )
+
+;;; doom-gruvbox-theme.el ends here
diff --git a/elpa/doom-themes-20220504.1557/doom-henna-theme.el b/elpa/doom-themes-20220504.1557/doom-henna-theme.el
new file mode 100644
index 0000000..b4767ca
--- /dev/null
+++ b/elpa/doom-themes-20220504.1557/doom-henna-theme.el
@@ -0,0 +1,270 @@
+;;; doom-henna-theme.el --- inspired by vscode henna theme -*- lexical-binding: t; no-byte-compile: t; -*-
+(require 'doom-themes)
+
+;;; Code:
+(defgroup doom-henna-theme nil
+ "Options for the `doom-henna' theme."
+ :group 'doom-themes)
+
+(defcustom doom-henna-brighter-modeline nil
+ "If non-nil, more vivid colors will be used to style the mode-line."
+ :group 'doom-henna-theme
+ :type 'boolean)
+
+(defcustom doom-henna-brighter-comments nil
+ "If non-nil, comments will be highlighted in more vivid colors."
+ :group 'doom-henna-theme
+ :type 'boolean)
+
+(defcustom doom-henna-comment-bg doom-henna-brighter-comments
+ "If non-nil, comments will have a subtle, darker background. Enhancing their
+legibility."
+ :group 'doom-henna-theme
+ :type 'boolean)
+
+(defcustom doom-henna-padded-modeline doom-themes-padded-modeline
+ "If non-nil, adds a 4px padding to the mode-line. Can be an integer to
+determine the exact padding."
+ :group 'doom-henna-theme
+ :type '(choice integer boolean))
+
+;;
+(def-doom-theme doom-henna
+ "A dark theme inspired by Atom One Dark"
+
+ ;; name default 256 16
+ ((bg '("#21272e" nil nil ))
+ (bg-alt '("#1B1F23" nil nil ))
+ (base0 '("#10151a" "black" "black" ))
+ (base1 '("#181A1F" "#2e2e2e" "brightblack" ))
+ (base2 '("#1B1F23" "#262626" "brightblack" ))
+ (base3 '("#262D35" "#3f3f3f" "brightblack" ))
+ (base4 '("#282C34" "#525252" "brightblack" ))
+ (base5 '("#2c313a" "#6b6b6b" "brightblack" ))
+ (base6 '("#3B4048" "#979797" "brightblack" ))
+ (base7 '("#495162" "#dfdfdf" "white" ))
+ (base8 '("#606F73" "#1e1e1e" "brightblack" ))
+ (fg '("#f8f8f0" "#bfbfbf" "brightwhite" ))
+ (fg-alt '("#6B717D" "#979797" "white" ))
+ (grey '("#737c8c"))
+ (red '("#e74c3c" "#ff6655" "red" ))
+ (green '("#53df83" "#99bb66" "green" ))
+ (teal '("#1abc9c" "#44b9b1" "brightgreen" ))
+ (blue '("#56b5c2" "#51afef" "brightblue" ))
+ (cyan '("#56b6c2" "#46D9FF" "brightcyan" ))
+
+ ;; Not used, so remap to other (henna) colors
+ (orange red)
+ (yellow '("#ECBE7B" "#ECBE7B" "yellow" ))
+ (magenta '("#FFB8D1" "#FFB8D1" "magenta" ))
+ (violet '("#C5A3FF" "#C5A3FF" "brightmagenta"))
+ (dark-blue '("#2257A0" "#2257A0" "blue" ))
+ (dark-cyan '("#2e4a54" "#204052" "cyan" ))
+
+ ;; custom
+ (green-alt '("#9cd230" ))
+ (green-dark '("#30c965" ))
+
+ ;; face categories -- required for all themes
+ (highlight red)
+ (vertical-bar (doom-darken base1 0.1))
+ (selection cyan)
+ (builtin teal)
+ (comments base8)
+ (doc-comments base8)
+ (constants teal)
+ (functions red)
+ (keywords teal)
+ (methods red)
+ (operators red)
+ (type red)
+ (strings green)
+ (variables fg)
+ (numbers teal)
+ (region dark-cyan)
+ (error red)
+ (warning yellow)
+ (success green)
+ (vc-modified blue)
+ (vc-added green-alt)
+ (vc-deleted (doom-darken red 0.2))
+
+ ;; custom categories
+ (hidden `(,(car bg) "black" "black"))
+ (-modeline-bright doom-henna-brighter-modeline)
+ (-modeline-pad
+ (when doom-henna-padded-modeline
+ (if (integerp doom-henna-padded-modeline) doom-henna-padded-modeline 4)))
+
+
+ (modeline-fg fg)
+ (modeline-fg-alt base7)
+ (modeline-bg
+ (if -modeline-bright
+ (doom-darken blue 0.475)
+ `(,(doom-darken (car bg-alt) 0.15) ,@(cdr base0))))
+ (modeline-bg-l
+ (if -modeline-bright
+ (doom-darken blue 0.45)
+ `(,(doom-darken (car bg-alt) 0.1) ,@(cdr base0))))
+ (modeline-bg-inactive `(,(doom-darken (car bg-alt) 0.1) ,@(cdr bg-alt)))
+ (modeline-bg-inactive-l `(,(car bg-alt) ,@(cdr base1))))
+
+
+ ;;;; Base theme face overrides
+ (((font-lock-comment-face &override)
+ :background (if doom-henna-comment-bg (doom-lighten bg 0.05)))
+ ((line-number &override) :foreground base7)
+ ((line-number-current-line &override) :foreground fg)
+ (mode-line
+ :background modeline-bg :foreground modeline-fg
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg)))
+ (mode-line-inactive
+ :background modeline-bg-inactive :foreground modeline-fg-alt
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive)))
+ (mode-line-emphasis :foreground (if -modeline-bright base8 highlight))
+
+ ;;;; elscreen
+ (elscreen-tab-other-screen-face :background "#353a42" :foreground "#1e2022")
+ ;;;; solaire-mode
+ (solaire-mode-line-face
+ :inherit 'mode-line
+ :background modeline-bg-l
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-l)))
+ (solaire-mode-line-inactive-face
+ :inherit 'mode-line-inactive
+ :background modeline-bg-inactive-l
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive-l)))
+ (solaire-default-face :inherit 'default :background base1)
+ ;;;; hl-todo
+ (hl-todo :foreground red :weight 'bold)
+ ;;;; iedit
+ (iedit-occurrence :foreground blue :weight 'bold :inverse-video t)
+ (iedit-read-only-occurrence :inherit 'region)
+ ;;;; doom-modeline
+ (doom-modeline-bar :background (if -modeline-bright modeline-bg highlight))
+ (doom-modeline-buffer-file :inherit 'mode-line-buffer-id :weight 'bold)
+ (doom-modeline-buffer-path :inherit 'mode-line-emphasis :weight 'bold)
+ (doom-modeline-buffer-project-root :foreground green :weight 'bold)
+ ;;;; centaur-tabs
+ (centaur-tabs-selected :background base3 :foreground fg)
+ (centaur-tabs-unselected :background base2 :foreground grey)
+ (centaur-tabs-selected-modified :background bg :foreground green-alt)
+ (centaur-tabs-unselected-modified :background base1 :foreground magenta)
+ (centaur-tabs-active-bar-face :background green)
+ (centaur-tabs-modified-marker-selected :inherit 'centaur-tabs-selected-modified :foreground green)
+ (centaur-tabs-modified-marker-unselected :inherit 'centaur-tabs-unselected-modified :foreground green)
+ ;;;; doom-emacs
+ (doom-dashboard-banner :foreground red)
+ (doom-dashboard-footer-icon :foreground green-alt)
+ (doom-dashboard-loaded :foreground green-alt)
+ ;;;; which-key
+ (which-key-key-face :foreground red)
+ (which-key-group-description-face :foreground green)
+ (which-key-command-description-face :foreground teal)
+ (which-key-local-map-description-face :foreground green)
+ ;;;; highlight-numbers
+ (highlight-numbers-number :foreground blue)
+ ;;;; ivy
+ (ivy-minibuffer-match-highlight :foreground red)
+ (ivy-highlight-face :foreground red)
+ (ivy-minibuffer-match-face-2
+ :inherit 'ivy-minibuffer-match-face-1
+ :foreground red :background base1 :weight 'semi-bold)
+ (ivy-minibuffer-match-face-4
+ :inherit 'ivy-minibuffer-match-face-2
+ :foreground red :weight 'semi-bold)
+ (ivy-current-match :background red :distant-foreground base0 :weight 'normal)
+ ;;;; treemacs
+ (treemacs-directory-face :foreground base8)
+ (treemacs-git-modified-face :foreground yellow)
+ (treemacs-git-added-face :foreground green)
+ (treemacs-git-untracked-face :foreground green-alt)
+ (treemacs-file-face :foreground fg)
+ (treemacs-root-face :foreground red :weight 'bold)
+ ;;;; magit
+ (magit-blame-headling :foreground magenta :background base3)
+ (magit-cherry-equvalent :foreground red)
+ (magit-log-author :foreground magenta)
+ (magit-section-heading :foreground red :weight 'bold)
+ (magit-tag :foreground (doom-lighten green-alt 0.5))
+ (magit-filename :foreground teal)
+ (magit-diff-hunk-heading :background (doom-darken teal 0.5))
+ (magit-diff-hunk-heading-highlight :background (doom-darken teal 0.2))
+ (magit-branch-current :foreground green-alt)
+ ;;;; popup
+ (popup-tip-face :background base8 :foreground fg)
+ (popup-menu-mouse-face :background base8 :foreground fg)
+ (popup-summary-face :background base7 :foreground fg)
+ ;;;; rainbow delimiters
+ (rainbow-delimiters-depth-1-face :foreground red)
+ (rainbow-delimiters-depth-2-face :foreground green)
+ (rainbow-delimiters-depth-3-face :foreground teal)
+ (rainbow-delimiters-depth-4-face :foreground green)
+ (rainbow-delimiters-depth-5-face :foreground blue)
+ (rainbow-delimiters-depth-6-face :foreground green-alt)
+ (rainbow-delimiters-depth-7-face :foreground cyan)
+ ;;;; Dired
+ (diredfl-date-time :foreground teal)
+ (diredfl-number :foreground green)
+ (diredfl-dir-heading :foreground teal :weight 'bold)
+ ;;;; css-mode <built-in> / scss-mode
+ (css-proprietary-property :foreground cyan)
+ (css-property :foreground teal)
+ (css-selector :foreground red)
+ ;;;; markdown-mode
+ (markdown-markup-face :foreground grey)
+ (markdown-header-face :inherit 'bold :foreground red)
+ ((markdown-code-face &override) :background (doom-lighten base3 0.05))
+ (markdown-bold-face :foreground green :weight 'bold)
+ (markdown-url-face :foreground fg :underline t)
+ (markdown-link-face :foreground green)
+ (markdown-list-face :foregroung fg)
+ (markdown-header-face-1 :foreground fg)
+ (markdown-header-face-2 :foreground fg)
+ (markdown-header-face-3 :foreground fg)
+ (markdown-header-face-4 :foreground fg)
+ (markdown-header-face-5 :foreground fg)
+ (markdown-header-face-6 :foreground fg)
+ (markdown-header-delimiter-face :foreground fg)
+ (markdown-inline-code-face :foreground teal)
+ ;;;; outline <built-in>
+ (outline-1 :foreground red :weight 'bold :extend t)
+ (outline-2 :foreground teal :weight 'bold :extend t)
+ (outline-3 :foreground green :weight 'bold :extend t)
+ (outline-4 :foreground (doom-lighten red 0.25) :weight 'bold :extend t)
+ (outline-5 :foreground (doom-lighten green 0.25) :weight 'bold :extend t)
+ (outline-6 :foreground (doom-lighten blue 0.5) :weight 'bold :extend t)
+ (outline-7 :foreground (doom-lighten red 0.5) :weight 'bold :extend t)
+ (outline-8 :foreground (doom-lighten blue 0.8) :weight 'bold :extend t)
+ ;;;; org <built-in>
+ (org-hide :foreground hidden)
+ ((org-code &override) :foreground blue)
+ (org-table :foreground fg-alt)
+ ;;;; web-mode
+ (web-mode-html-attr-equal-face :foreground teal)
+ (web-mode-html-tag-face :foreground green-alt)
+ (web-mode-html-tag-bracket-face :foreground teal)
+ (web-mode-keyword-face :foreground teal)
+ (web-mode-block-control-face :foreground red)
+ (web-mode-variable-name-face :foreground (doom-lighten green 0.5))
+ ;;;; typescript
+ (typescript-access-modifier-face :foreground green-alt)
+ (typescript-this-face :foreground green-alt)
+ ;;;; LSP
+ (lsp-face-highlight-textual :background "black")
+ (lsp-face-highlight-read :background (doom-darken dark-blue 0.3))
+ ;;;; js
+ (js2-object-property :foreground fg)
+ (js2-object-property-access :foreground green)
+ (js2-jsdoc-value :foreground red)
+ (js2-jsdoc-tag :foreground teal)
+ (js2-jsdoc-html-tag-delimiter :foreground base8)
+ (js2-jsdoc-html-tag-name :foreground base8)
+ ;;;; rjsx
+ (rjsx-attr :foreground blue))
+
+ ;;;; Base theme variable overrides-
+ ())
+
+;;; doom-henna-theme.el ends here
diff --git a/elpa/doom-themes-20220504.1557/doom-homage-black-theme.el b/elpa/doom-themes-20220504.1557/doom-homage-black-theme.el
new file mode 100644
index 0000000..e214b8f
--- /dev/null
+++ b/elpa/doom-themes-20220504.1557/doom-homage-black-theme.el
@@ -0,0 +1,210 @@
+;;; doom-homage-black-theme.el --- pitch-black theme version of homage-white -*- lexical-binding: t; no-byte-compile: t; -*-
+;;;
+;;; Commentary:
+;;;
+;;; Theme is (manually) inverted homage-white theme with a focus of having
+;;; pitch-black backgrounds. I'm also incorporated a several ideas from jbeans
+;;; theme (synic/jbeans-emacs).
+
+(require 'doom-themes)
+
+;;
+(defgroup doom-homage-black-theme nil
+ "Options for the `doom-homage-black' theme."
+ :group 'doom-themes)
+
+(defcustom doom-homage-black-padded-modeline doom-themes-padded-modeline
+ "If non-nil, adds a 4px padding to the mode-line. Can be an integer to
+determine the exact padding."
+ :group 'doom-homage-black-theme
+ :type '(choice integer boolean))
+
+;;
+(def-doom-theme doom-homage-black
+ "A light theme inspired by Atom One"
+
+ ;; name default 256 16
+ ((bg '("#000000" nil nil ))
+ (bg-alt '("#000000" nil nil ))
+ (base0 '("#1B2229" "black" "black" ))
+ (base1 '("#1c1f24" "#1e1e1e" "brightblack" ))
+ (base2 '("#202328" "#2e2e2e" "brightblack" ))
+ (base3 '("#23272e" "#262626" "brightblack" ))
+ (base4 '("#3f444a" "#3f3f3f" "brightblack" ))
+ (base5 '("#5B6268" "#525252" "brightblack" ))
+ (base6 '("#73797e" "#6b6b6b" "brightblack" ))
+ (base7 '("#9ca0a4" "#979797" "brightblack" ))
+ (base8 '("#DFDFDF" "#dfdfdf" "white" ))
+ (fg '("#bbc2cf" "#bfbfbf" "brightwhite" ))
+ (fg-alt '("#5B6268" "#2d2d2d" "white" ))
+
+ (grey base5)
+ (red '("#ff6c6b" "#ff6655" "red" ))
+ (orange '("#b4916d" "#b4916d" "brightred" ))
+ (green '("#98be65" "#99bb66" "green" ))
+ (teal '("#4db5bd" "#44b9b1" "brightgreen" ))
+ (yellow '("#ECBE7B" "#ECBE7B" "yellow" ))
+ (blue '("#0170bf" "#0170bf" "brightblue" ))
+ (dark-blue '("#003c64" "#0170bf" "blue" ))
+ (magenta '("#c678dd" "#c678dd" "brightmagenta"))
+ (violet '("#a9a1e1" "#a9a1e1" "magenta" ))
+ (cyan '("#46D9FF" "#46D9FF" "brightcyan" ))
+ (dark-cyan '("#5699AF" "#5699AF" "cyan" ))
+
+ ;; face categories -- required for all themes
+ (highlight blue)
+ (vertical-bar (doom-darken base2 0.1))
+ (selection dark-blue)
+ (builtin fg)
+ (comments green)
+ (doc-comments (doom-darken comments 0.15))
+ (constants fg)
+ (functions blue)
+ (keywords fg)
+ (methods fg)
+ (operators fg)
+ (type fg)
+ (strings orange)
+ (variables fg)
+ (numbers orange)
+ (region `(,(doom-darken (car dark-blue) 0.1) ,@(doom-darken (cdr base0) 0.3)))
+ (error red)
+ (warning yellow)
+ (success green)
+ (vc-modified orange)
+ (vc-added green)
+ (vc-deleted red)
+
+ ;; custom categories
+ (-modeline-bright t)
+ (-modeline-pad
+ (when doom-homage-black-padded-modeline
+ (if (integerp doom-homage-black-padded-modeline) doom-homage-black-padded-modeline 4)))
+
+ (modeline-fg nil)
+ (modeline-fg-alt (doom-blend violet base4 (if -modeline-bright 0.5 0.2)))
+
+ (modeline-bg
+ (if -modeline-bright
+ (doom-darken base2 0.05)
+ base1))
+ (modeline-bg-l
+ (if -modeline-bright
+ (doom-darken base2 0.1)
+ base2))
+ (modeline-bg-inactive (doom-darken bg 0.1))
+ (modeline-bg-inactive-l `(,(doom-darken (car bg-alt) 0.05) ,@(cdr base1))))
+
+ ;;;; Base theme face overrides
+ ((font-lock-builtin-face :inherit 'bold :foreground base8)
+ ((font-lock-doc-face &override) :slant 'italic)
+ (font-lock-function-name-face :inherit 'bold :foreground base8)
+ (font-lock-keyword-face :inherit 'bold :foreground base8)
+ (font-lock-type-face :inherit 'bold :foreground base8)
+ ((hl-line &override) :background (doom-darken highlight 0.75))
+ ((line-number &override) :foreground (doom-lighten base4 0.15))
+ ((line-number-current-line &override) :foreground base8)
+ (mode-line
+ :background modeline-bg :foreground modeline-fg
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg)))
+ (mode-line-inactive
+ :background modeline-bg-inactive :foreground modeline-fg-alt
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive)))
+ (mode-line-emphasis :foreground (if -modeline-bright base8 highlight))
+ (tooltip :background base1 :foreground fg)
+ ((secondary-selection &override) :background base0)
+
+ ;;;; centaur-tabs
+ (centaur-tabs-unselected :background bg-alt :foreground base4)
+ ;;;; css-mode <built-in> / scss-mode
+ (css-proprietary-property :foreground orange)
+ (css-property :foreground green)
+ (css-selector :foreground blue)
+ ;;;; doom-modeline
+ (doom-modeline-bar :background (if -modeline-bright modeline-bg highlight))
+ ;;;; ediff <built-in>
+ (ediff-current-diff-A :foreground red :background (doom-lighten red 0.8))
+ (ediff-current-diff-B :foreground green :background (doom-lighten green 0.8))
+ (ediff-current-diff-C :foreground blue :background (doom-lighten blue 0.8))
+ (ediff-current-diff-Ancestor :foreground teal :background (doom-lighten teal 0.8))
+ ;;;; magit
+ ((magit-diff-hunk-heading &override) :foreground fg :background bg-alt :bold bold)
+ ((magit-diff-hunk-heading-highlight &override) :foreground base8 :background bg-alt :bold bold)
+ (magit-blame-heading :foreground orange :background bg-alt)
+ (magit-diff-removed :foreground (doom-darken red 0.2) :background (doom-blend red bg 0.1))
+ (magit-diff-removed-highlight :foreground red :background (doom-blend red bg 0.2) :bold bold)
+ ;;;; markdown-mode
+ (markdown-markup-face :foreground base5)
+ (markdown-header-face :inherit 'bold :foreground red)
+ ((markdown-code-face &override) :background base1)
+ (mmm-default-submode-face :background base1)
+ ;;;; mu4e
+ (mu4e-highlight-face :background bg :inherit 'bold)
+ ;;;; helm
+ (helm-candidate-number :background blue :foreground bg)
+ ;;;; ivy
+ ;; bg/fg are too close
+ ((ivy-minibuffer-match-face-1 &override) :foreground (doom-lighten grey 0.70))
+ ;;;; ivy-posframe
+ (ivy-posframe :background base0)
+ ;;;; lsp-mode
+ (lsp-ui-doc-background :background base0)
+ (lsp-face-highlight-read :background (doom-blend red bg 0.3))
+ (lsp-face-highlight-textual :inherit 'lsp-face-highlight-read)
+ (lsp-face-highlight-write :inherit 'lsp-face-highlight-read)
+ ;;;; outline <built-in>
+ ((outline-1 &override) :foreground fg)
+ ((outline-2 &override) :foreground fg)
+ ((outline-3 &override) :foreground fg)
+ ((outline-4 &override) :foreground fg)
+ ((outline-5 &override) :foreground fg)
+ ((outline-6 &override) :foreground fg)
+ ((outline-7 &override) :foreground fg)
+ ((outline-8 &override) :foreground fg)
+ ;;;; org <built-in>
+ ;; make unfinished cookie & todo keywords bright to grab attention
+ ((org-todo &override) :foreground red)
+ ;; make tags and dates to have pretty box around them
+ ((org-tag &override) :foreground fg :background base1
+ :box `(:line-width -1 :color ,base5 :style 'released-button))
+ ((org-date &override) :foreground fg :background base1
+ :box `(:line-width -1 :color ,base5 :style 'released-button))
+ ;; Make drawers and special keywords (like scheduled) to be very bleak
+ ((org-special-keyword &override) :foreground grey)
+ ((org-drawer &override) :foreground grey)
+ ;; Make ellipsis as bleak as possible and reset underlines/boxing
+ (org-ellipsis :underline nil :box nil :foreground fg :background bg)
+ ;; Make blocks have a slightly different background
+ ((org-block &override) :background base1)
+ ((org-block-begin-line &override) :foreground fg :slant 'italic)
+ ((org-quote &override) :background base1)
+ ((org-table &override) :foreground fg)
+ ;; org-agendamode: make "unimportant" things like distant deadlines and
+ ;; things scheduled for today to be bleak.
+ (org-upcoming-deadline :foreground base8)
+ (org-upcoming-distant-deadline :foreground fg)
+ (org-scheduled :foreground fg)
+ (org-scheduled-today :foreground fg)
+ (org-scheduled-previously :foreground base8)
+ ;;;; solaire-mode
+ (solaire-mode-line-face
+ :inherit 'mode-line
+ :background modeline-bg-l
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-l)))
+ (solaire-mode-line-inactive-face
+ :inherit 'mode-line-inactive
+ :background modeline-bg-inactive-l
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive-l)))
+ ;;;; swiper
+ ;; bg/fg are too close
+ ((swiper-match-face-1 &override) :background fg :foreground bg)
+ ((swiper-line-face &override) :background dark-blue :foreground fg)
+ ;;;; web-mode
+ (web-mode-current-element-highlight-face :background dark-blue :foreground bg)
+ ;;;; wgrep <built-in>
+ (wgrep-face :background base1))
+
+ ;;;; Base theme variable overrides-
+ ())
+
+;;; doom-homage-black-theme.el ends here
diff --git a/elpa/doom-themes-20220504.1557/doom-homage-white-theme.el b/elpa/doom-themes-20220504.1557/doom-homage-white-theme.el
new file mode 100644
index 0000000..4eff257
--- /dev/null
+++ b/elpa/doom-themes-20220504.1557/doom-homage-white-theme.el
@@ -0,0 +1,214 @@
+;;; doom-homage-white-theme.el --- minimal white theme inspired by editors from 2000s -*- lexical-binding: t; no-byte-compile: t; -*-
+;;;
+;;; Commentary:
+;;;
+;;; Theme is using palette inspired by various editors from 2000s, with a lot of
+;;; inspiration from eziam theme (thblt/eziam-theme-emacs) and tao themes
+;;; (11111000000/tao-theme-emacs).
+
+(require 'doom-themes)
+
+;;
+(defgroup doom-homage-white-theme nil
+ "Options for the `doom-homage-white' theme."
+ :group 'doom-themes)
+
+(defcustom doom-homage-white-padded-modeline doom-themes-padded-modeline
+ "If non-nil, adds a 4px padding to the mode-line. Can be an integer to
+determine the exact padding."
+ :group 'doom-homage-white-theme
+ :type '(choice integer boolean))
+
+;;
+(def-doom-theme doom-homage-white
+ "A light theme inspired by Atom One"
+
+ ;; name default 256 16
+ ((bg '("#fafafa" nil nil ))
+ (bg-alt '("#f0f0f0" nil nil ))
+ (base0 '("#f0f0f0" "#f0f0f0" "white" ))
+ (base1 '("#e7e7e7" "#e7e7e7" "brightblack" ))
+ (base2 '("#dfdfdf" "#dfdfdf" "brightblack" ))
+ (base3 '("#c6c7c7" "#c6c7c7" "brightblack" ))
+ (base4 '("#9ca0a4" "#9ca0a4" "brightblack" ))
+ (base5 '("#383a42" "#424242" "brightblack" ))
+ (base6 '("#202328" "#2e2e2e" "brightblack" ))
+ (base7 '("#1c1f24" "#1e1e1e" "brightblack" ))
+ (base8 '("#1b2229" "black" "black" ))
+ (fg '("#383a42" "#424242" "black" ))
+ (fg-alt '("#c6c7c7" "#c7c7c7" "brightblack" ))
+
+ (grey base5)
+ (red '("#e45649" "#e45649" "red" ))
+ (orange '("#8a3b3c" "#dd8844" "brightred" ))
+ (green '("#556b2f" "#556b2f" "green" ))
+ (teal '("#4db5bd" "#44b9b1" "brightgreen" ))
+ (yellow '("#986801" "#986801" "yellow" ))
+ (yellow-alt '("#fafadd" "#fafadd" "yellow" ))
+ (blue '("#014980" "#014980" "brightblue" ))
+ (dark-blue '("#030f64" "#030f64" "blue" ))
+ (magenta '("#a626a4" "#a626a4" "magenta" ))
+ (violet '("#b751b6" "#b751b6" "brightmagenta"))
+ (cyan '("#0184bc" "#0184bc" "brightcyan" ))
+ (dark-cyan '("#005478" "#005478" "cyan" ))
+
+ ;; face categories -- required for all themes
+ (highlight blue)
+ (vertical-bar (doom-darken base2 0.1))
+ (selection base3)
+ (builtin fg)
+ (comments green)
+ (doc-comments (doom-darken comments 0.15))
+ (constants fg)
+ (functions blue)
+ (keywords fg)
+ (methods fg)
+ (operators fg)
+ (type fg)
+ (strings orange)
+ (variables fg)
+ (numbers orange)
+ (region `(,(doom-darken (car bg-alt) 0.1) ,@(doom-darken (cdr base0) 0.3)))
+ (error red)
+ (warning yellow)
+ (success green)
+ (vc-modified orange)
+ (vc-added green)
+ (vc-deleted red)
+
+ ;; custom categories
+ (-modeline-bright t)
+ (-modeline-pad
+ (when doom-homage-white-padded-modeline
+ (if (integerp doom-homage-white-padded-modeline) doom-homage-white-padded-modeline 4)))
+
+ (modeline-fg nil)
+ (modeline-fg-alt (doom-blend violet base4 (if -modeline-bright 0.5 0.2)))
+
+ (modeline-bg
+ (if -modeline-bright
+ (doom-darken base2 0.05)
+ base1))
+ (modeline-bg-l
+ (if -modeline-bright
+ (doom-darken base2 0.1)
+ base2))
+ (modeline-bg-inactive (doom-darken bg 0.1))
+ (modeline-bg-inactive-l `(,(doom-darken (car bg-alt) 0.05) ,@(cdr base1))))
+
+ ;;;; Base theme face overrides
+ ((font-lock-builtin-face :inherit 'bold)
+ ((font-lock-doc-face &override) :slant 'italic)
+ (font-lock-function-name-face :inherit 'bold)
+ (font-lock-keyword-face :inherit 'bold)
+ (font-lock-type-face :inherit 'bold)
+ ((line-number &override) :foreground (doom-lighten base4 0.15))
+ ((line-number-current-line &override) :foreground base8)
+ (mode-line
+ :background modeline-bg :foreground modeline-fg
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg)))
+ (mode-line-inactive
+ :background modeline-bg-inactive :foreground modeline-fg-alt
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive)))
+ (mode-line-emphasis :foreground (if -modeline-bright base8 highlight))
+ (tooltip :background base1 :foreground fg)
+
+ ;; Override secondary selection
+ ((secondary-selection &override) :background base0)
+
+ ;;;; centaur-tabs
+ (centaur-tabs-unselected :background bg-alt :foreground base4)
+ ;;;; css-mode <built-in> / scss-mode
+ (css-proprietary-property :foreground orange)
+ (css-property :foreground green)
+ (css-selector :foreground blue)
+ ;;;; doom-modeline
+ (doom-modeline-bar :background (if -modeline-bright modeline-bg highlight))
+ ;;;; ediff <built-in>
+ (ediff-current-diff-A :foreground red :background (doom-lighten red 0.8))
+ (ediff-current-diff-B :foreground green :background (doom-lighten green 0.8))
+ (ediff-current-diff-C :foreground blue :background (doom-lighten blue 0.8))
+ (ediff-current-diff-Ancestor :foreground teal :background (doom-lighten teal 0.8))
+ ;;;; magit
+ ((magit-diff-hunk-heading &override) :foreground base4 :background bg :bold bold)
+ ((magit-diff-hunk-heading-highlight &override) :foreground fg :background bg :bold bold)
+ (magit-blame-heading :foreground orange :background bg-alt)
+ (magit-diff-removed :foreground (doom-darken red 0.2) :background (doom-blend red bg 0.1))
+ (magit-diff-removed-highlight :foreground red :background (doom-blend red bg 0.2) :bold bold)
+ ;;;; helm
+ (helm-candidate-number :background blue :foreground bg)
+ ;;;; highlight-indent-guides
+ (highlight-indent-guides-character-face :foreground base2)
+ ;;;; ivy
+ ((ivy-minibuffer-match-face-1 &override) :foreground (doom-darken grey 0.70))
+ ;;;; ivy-posframe
+ (ivy-posframe :background base0)
+ ;;;; lsp-mode
+ (lsp-ui-doc-background :background base0)
+ (lsp-face-highlight-read :background (doom-blend red bg 0.3))
+ (lsp-face-highlight-textual :inherit 'lsp-face-highlight-read)
+ (lsp-face-highlight-write :inherit 'lsp-face-highlight-read)
+ ;;;; markdown-mode
+ (markdown-markup-face :foreground base5)
+ (markdown-header-face :inherit 'bold :foreground red)
+ ((markdown-code-face &override) :background base1)
+ (mmm-default-submode-face :background base1)
+ ;;;; mu4e
+ (mu4e-highlight-face :background bg :inherit 'bold)
+ (mu4e-header-highlight-face :foreground dark-blue :inherit 'bold)
+ (mu4e-unread-face :foreground blue)
+ ;;;; outline <built-in>
+ ((outline-1 &override) :foreground fg)
+ ((outline-2 &override) :foreground fg)
+ ((outline-3 &override) :foreground fg)
+ ((outline-4 &override) :foreground fg)
+ ((outline-5 &override) :foreground fg)
+ ((outline-6 &override) :foreground fg)
+ ((outline-7 &override) :foreground fg)
+ ((outline-8 &override) :foreground fg)
+ ;;;; org <built-in>
+ ;; Make unfinished cookie & todo keywords bright to grab attention
+ ((org-todo &override) :foreground red)
+ ;; Make tags and dates to have pretty box around them
+ ((org-tag &override) :foreground fg :background yellow-alt
+ :box `(:line-width -1 :color ,base5 :style 'released-button))
+ ((org-date &override) :foreground fg :background base1
+ :box `(:line-width -1 :color ,base5 :style 'released-button))
+ ;; Make drawers and special keywords (like scheduled) to be very bleak
+ ((org-special-keyword &override) :foreground grey)
+ ((org-drawer &override) :foreground grey)
+ ;; Make ellipsis as bleak as possible and reset underline/boxing
+ (org-ellipsis :underline nil :box nil :foreground fg :background bg)
+ ;; Make blocks have a slightly different background
+ ((org-block &override) :background base1)
+ ((org-block-begin-line &override) :foreground fg :slant 'italic)
+ ((org-quote &override) :background base1)
+ ((org-table &override) :foreground fg)
+ ;; Make "unimportant" things like distant deadlines and things scheduled for
+ ;; today to be bleak.
+ (org-upcoming-deadline :foreground base8)
+ (org-upcoming-distant-deadline :foreground fg)
+ (org-scheduled :foreground fg)
+ (org-scheduled-today :foreground fg)
+ (org-scheduled-previously :foreground base8)
+ ;;;; solaire-mode
+ (solaire-mode-line-face
+ :inherit 'mode-line
+ :background modeline-bg-l
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-l)))
+ (solaire-mode-line-inactive-face
+ :inherit 'mode-line-inactive
+ :background modeline-bg-inactive-l
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive-l)))
+ ;;;; swiper
+ ((swiper-match-face-1 &override) :foreground bg :background fg)
+ ((swiper-line-face &override) :background (doom-lighten blue 0.70) :foreground fg)
+ ;;;; web-mode
+ (web-mode-current-element-highlight-face :background dark-blue :foreground bg)
+ ;;;; wgrep <built-in>
+ (wgrep-face :background base1))
+
+ ;;;; Base theme variable overrides-
+ ())
+
+;;; doom-homage-white-theme.el ends here
diff --git a/elpa/doom-themes-20220504.1557/doom-horizon-theme.el b/elpa/doom-themes-20220504.1557/doom-horizon-theme.el
new file mode 100644
index 0000000..2ba69f6
--- /dev/null
+++ b/elpa/doom-themes-20220504.1557/doom-horizon-theme.el
@@ -0,0 +1,213 @@
+;;; doom-horizon-theme.el --- Inspired by VSCode Horizon -*- lexical-binding: t; no-byte-compile: t; -*-
+
+;;; Commentary:
+;;; This theme was inspired by the port of Horizon to Emacs
+;;; see: https://github.com/aodhneine/horizon-theme.el
+
+(require 'doom-themes)
+
+;;; Code:
+(defgroup doom-horizon-theme nil
+ "Options for the `doom-horizon' theme."
+ :group 'doom-themes)
+
+(defcustom doom-horizon-brighter-modeline nil
+ "If non-nil, more vivid colors will be used to style the mode-line."
+ :group 'doom-horizon-theme
+ :type 'boolean)
+
+(defcustom doom-horizon-brighter-comments nil
+ "If non-nil, comments will be highlighted in more vivid colors."
+ :group 'doom-horizon-theme
+ :type 'boolean)
+
+(defcustom doom-horizon-comment-bg doom-horizon-brighter-comments
+ "If non-nil, comments will have a subtle, darker background. Enhancing their legibility."
+ :group 'doom-horizon-theme
+ :type 'boolean)
+
+(defcustom doom-horizon-padded-modeline doom-themes-padded-modeline
+ "If non-nil, adds a 4px padding to the mode-line. Can be an integer to determine the exact padding."
+ :group 'doom-horizon-theme
+ :type '(choice integer boolean))
+
+;;
+(def-doom-theme doom-horizon
+ "A port of the port of the Visual Studio Code theme Horizon"
+
+ ;; name default 256 16
+ ((bg '("#232530" nil nil ))
+ (bg-alt '("#1c1e26" nil nil ))
+ (base0 '("#16161c" "black" "black" ))
+ (base1 '("#1a1c23" "#111111" "brightblack" ))
+ (base2 '("#1d1f27" "#333333" "brightblack" ))
+ (base3 '("#232530" "#555555" "white" ))
+ (base4 '("#6a6a6a" "#6a6a6a" "white" ))
+ (base5 '("#f9cec3" "#f9cec3" "white" ))
+ (base6 '("#f9cbbe" "#f9cbbe" "white" ))
+ (base7 '("#fadad1" "#fadad1" "white" ))
+ (base8 '("#fdf0ed" "#fdf0ed" "white" ))
+ (fg-alt '("#fdf0ed" "#fdf0ed" "brightwhite" ))
+ (fg '("#c7c9cb" "#c7c9cb" "white" ))
+
+ (grey base4)
+ (red '("#e95678" "#e95678" "red" ))
+ (orange '("#f09383" "#f09383" "brightred" ))
+ (green '("#09f7a0" "#09f7a0" "green" ))
+ (teal '("#87ceeb" "#87ceeb" "brightgreen" ))
+ (yellow '("#fab795" "#fab795" "yellow" ))
+ (blue '("#21bfc2" "#21bfc2" "brightblue" ))
+ (dark-blue '("#25b2bc" "#25b2bc" "blue" ))
+ (magenta '("#6c6f93" "#6c6f93" "magenta" ))
+ (violet '("#b877db" "#b877db" "brightmagenta"))
+ (cyan '("#59e3e3" "#59e3e3" "brightcyan" ))
+ (dark-cyan '("#27d797" "#27d797" "cyan" ))
+
+ ;; additional highlighting colours for horizon
+ (hor-highlight `(,(doom-lighten (car base3) 0.05) ,@(cdr base2)))
+ (hor-highlight-selected (doom-lighten base3 0.1))
+ (hor-highlight-bright (doom-lighten base3 0.2))
+ (hor-highlight-brighter (doom-lighten base3 0.5))
+
+ ;; face categories -- required for all themes
+ (highlight red)
+ (vertical-bar base0)
+ (selection violet)
+ (builtin violet)
+ (comments (if doom-horizon-brighter-comments magenta hor-highlight-bright))
+ (doc-comments yellow)
+ (constants orange)
+ (functions teal)
+ (keywords violet)
+ (methods magenta)
+ (operators teal)
+ (type teal)
+ (strings yellow)
+ (variables red)
+ (numbers orange)
+ (region hor-highlight)
+ (error red)
+ (warning dark-cyan)
+ (success green)
+ (vc-modified orange)
+ (vc-added green)
+ (vc-deleted red)
+
+
+ ;; custom categories
+ (hidden `(,(car bg) "black" "black"))
+ (-modeline-bright doom-horizon-brighter-modeline)
+ (-modeline-pad
+ (when doom-horizon-padded-modeline
+ (if (integerp doom-horizon-padded-modeline) doom-horizon-padded-modeline 4)))
+
+ (modeline-fg `(,(doom-darken (car fg) 0.2) ,@(cdr fg-alt)))
+ (modeline-fg-alt `(,(doom-lighten (car bg) 0.2) ,@(cdr base3)))
+
+ (modeline-bg (if -modeline-bright base4 base1))
+ (modeline-bg-inactive base1))
+
+
+ ;;;; Base theme face overrides
+ (((font-lock-comment-face &override)
+ :slant 'italic
+ :background (if doom-horizon-comment-bg (doom-lighten bg 0.03)))
+ (fringe :background bg)
+ (link :foreground yellow :inherit 'underline)
+ ((line-number &override) :foreground hor-highlight-selected)
+ ((line-number-current-line &override) :foreground hor-highlight-brighter)
+ (mode-line
+ :background modeline-bg :foreground modeline-fg
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg)))
+ (mode-line-inactive
+ :background modeline-bg-inactive :foreground modeline-fg-alt
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive)))
+ (mode-line-emphasis :foreground (if -modeline-bright base8 highlight))
+ (mode-line-highlight :background base1 :foreground fg)
+ (tooltip :background base0 :foreground fg)
+
+ ;;;; company
+ (company-box-background :background base0 :foreground fg)
+ (company-tooltip-common :foreground red :weight 'bold)
+ (company-tooltip-selection :background hor-highlight :foreground fg)
+ ;;;; css-mode <built-in> / scss-mode
+ (css-proprietary-property :foreground violet)
+ (css-property :foreground fg)
+ (css-selector :foreground red)
+ ;;;; doom-modeline
+ (doom-modeline-bar :background (if -modeline-bright modeline-bg highlight))
+ (doom-modeline-highlight :foreground (doom-lighten bg 0.3))
+ (doom-modeline-project-dir :foreground red :inherit 'bold )
+ (doom-modeline-buffer-path :foreground red)
+ (doom-modeline-buffer-file :foreground fg)
+ (doom-modeline-buffer-modified :foreground violet)
+ (doom-modeline-panel :background base1)
+ (doom-modeline-urgent :foreground modeline-fg)
+ (doom-modeline-info :foreground cyan)
+ ;;;; elscreen
+ (elscreen-tab-other-screen-face :background "#353a42" :foreground "#1e2022")
+ ;;;; evil
+ (evil-ex-search :background hor-highlight-selected :foreground fg)
+ (evil-ex-lazy-highlight :background hor-highlight :foreground fg)
+ ;;;; haskell-mode
+ (haskell-type-face :foreground violet)
+ (haskell-constructor-face :foreground yellow)
+ (haskell-operator-face :foreground fg)
+ (haskell-literate-comment-face :foreground hor-highlight-selected)
+ ;;;; ivy
+ (ivy-current-match :background hor-highlight :distant-foreground nil)
+ (ivy-posframe-cursor :background red :foreground base0)
+ (ivy-minibuffer-match-face-2 :foreground red :weight 'bold)
+ ;;;; js2-mode
+ (js2-object-property :foreground red)
+ ;;;; markdown-mode
+ (markdown-markup-face :foreground cyan)
+ (markdown-link-face :foreground orange)
+ (markdown-link-title-face :foreground yellow)
+ (markdown-header-face :foreground red :inherit 'bold)
+ (markdown-header-delimiter-face :foreground red :inherit 'bold)
+ (markdown-language-keyword-face :foreground orange)
+ (markdown-markup-face :foreground fg)
+ (markdown-bold-face :foreground violet)
+ (markdown-table-face :foreground fg :background base1)
+ ((markdown-code-face &override) :foreground orange :background base1)
+ ;;;; orderless
+ (orderless-match-face-1 :weight 'bold :foreground (doom-blend red fg 0.6) :background (doom-blend red bg 0.1))
+ ;;;; mic-paren
+ (paren-face-match :foreground green :background base0 :weight 'ultra-bold)
+ (paren-face-mismatch :foreground yellow :background base0 :weight 'ultra-bold)
+ (paren-face-no-match :inherit 'paren-face-mismatch :weight 'ultra-bold)
+ ;;;; magit
+ (magit-section-heading :foreground red)
+ (magit-branch-remote :foreground orange)
+ ;;;; outline <built-in>
+ ((outline-1 &override) :foreground blue :background nil)
+ ;;;; org <built-in>
+ ((org-block &override) :background base1)
+ ((org-block-begin-line &override) :background base1 :foreground comments)
+ (org-hide :foreground hidden)
+ (org-link :inherit 'underline :foreground yellow)
+ (org-agenda-done :foreground cyan)
+ ;;;; rjsx-mode
+ (rjsx-tag :foreground red)
+ (rjsx-tag-bracket-face :foreground red)
+ (rjsx-attr :foreground cyan :slant 'italic :weight 'medium)
+ ;;;; solaire-mode
+ (solaire-mode-line-face
+ :inherit 'mode-line
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg)))
+ (solaire-mode-line-inactive-face
+ :inherit 'mode-line-inactive
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive)))
+ ;;;; treemacs
+ (treemacs-root-face :foreground fg :weight 'bold :height 1.2)
+ (doom-themes-treemacs-root-face :foreground fg :weight 'ultra-bold :height 1.2)
+ (doom-themes-treemacs-file-face :foreground fg)
+ (treemacs-directory-face :foreground fg)
+ (treemacs-git-modified-face :foreground green)
+ ;;;; web-mode
+ (web-mode-html-tag-bracket-face :foreground red)
+ (web-mode-html-tag-face :foreground red)
+ (web-mode-html-attr-name-face :foreground orange)))
+
+;;; doom-horizon-theme.el ends here
diff --git a/elpa/doom-themes-20220504.1557/doom-ir-black-theme.el b/elpa/doom-themes-20220504.1557/doom-ir-black-theme.el
new file mode 100644
index 0000000..fbddc70
--- /dev/null
+++ b/elpa/doom-themes-20220504.1557/doom-ir-black-theme.el
@@ -0,0 +1,151 @@
+;;; doom-ir-black-theme.el --- port of ir_black -*- lexical-bindings: t; no-byte-compile: t; -*-
+;;
+;; Author: Todd Werth <todd@infinite.red>
+;; Ported by: Kevin Kainan Li <legendre6891@users.noreply.github.com>
+;; Created: January 10, 2019
+;; Version: 2.0.0
+;; Keywords: custom themes, faces
+;; Homepage: https://github.com/hlissner/emacs-doom-themes
+;; Package-Requires: ((emacs "25.1") (cl-lib "0.5") (doom-themes "2.2.1"))
+;;
+;;; Commentary:
+;;
+;; Ported from the original ir_black theme in hlissner/emacs-doom-themes#255.
+;;
+;;; Code:
+
+(require 'doom-themes)
+
+
+;;
+;;; Variables
+
+(defgroup doom-ir-black-theme nil
+ "Options for the `doom-ir-black' theme."
+ :group 'doom-themes)
+
+(defcustom doom-ir-black-brighter-comments nil
+ "If non-nil, comments will be highlighted in more vivid colors."
+ :group 'doom-ir-black-theme
+ :type 'boolean)
+
+(defcustom doom-ir-black-padded-modeline doom-themes-padded-modeline
+ "If non-nil, adds a 4px padding to the mode-line.
+Can be an integer to determine the exact padding."
+ :group 'doom-ir-black-theme
+ :type '(or integer boolean))
+
+
+;;
+;;; Theme definition
+
+(def-doom-theme doom-ir-black
+ "A port of the original IR Black colorscheme."
+
+ ;; name default 256 16
+ ((bg '("#000000" "black" "black" ))
+ (fg '("#f6f3e8" "#f6f3e8" "brightwhite" ))
+
+ ;; These are off-color variants of bg/fg, used primarily for `solaire-mode',
+ ;; but can also be useful as a basis for subtle highlights (e.g. for hl-line
+ ;; or region), especially when paired with the `doom-darken', `doom-lighten',
+ ;; and `doom-blend' helper functions.
+ (bg-alt '("#121212" "black" "black" ))
+ (fg-alt '("#5B6268" "#2d2d2d" "white" ))
+
+ ;; These should represent a spectrum from bg to fg, where base0 is a starker
+ ;; bg and base8 is a starker fg. For example, if bg is light grey and fg is
+ ;; dark grey, base0 should be white and base8 should be black.
+ (base0 '("#1B2229" "black" "black" ))
+ (base1 '("#1c1f24" "#1e1e1e" "brightblack" ))
+ (base2 '("#202328" "#2e2e2e" "brightblack" ))
+ (base3 '("#23272e" "#262626" "brightblack" ))
+ (base4 '("#3f444a" "#3f3f3f" "brightblack" ))
+ (base5 '("#5B6268" "#525252" "brightblack" ))
+ (base6 '("#73797e" "#6b6b6b" "brightblack" ))
+ (base7 '("#9ca0a4" "#979797" "brightblack" ))
+ (base8 '("#DFDFDF" "#dfdfdf" "white" ))
+
+ (white '("#ffffff" "#ffffff" "white"))
+ (grey base4)
+ (red '("#ff6c60" "#ff6c60" "red" ))
+ (orange '("#E9C062" "#E9C062" "brightred" ))
+ (orange-alt '("#FFD2A7" "#FFD2A7" "brightred" ))
+ (green '("#A8FF60" "#A8FF60" "green" ))
+ (green-alt '("#99CC99" "#99CC99" "green" ))
+ (teal '("#00A0A0" "#00A0A0" "brightgreen" ))
+ (yellow '("#FFFFB6" "#FFFFB6" "yellow" ))
+ (blue '("#96CBFE" "#96CBFE" "brightblue" ))
+ (dark-blue '("#2257A0" "#2257A0" "blue" ))
+ (magenta '("#FF73FD" "#FF73FD" "magenta" ))
+ (violet '("#a9a1e1" "#a9a1e1" "brightmagenta"))
+ (cyan '("#C6C5FE" "#C6C5FE" "brightcyan" ))
+ (dark-cyan '("#5699AF" "#5699AF" "cyan" ))
+
+ ;; face categories -- required for all themes
+ (highlight blue)
+ (vertical-bar base5)
+ (selection cyan)
+ (builtin magenta)
+ (comments (if doom-ir-black-brighter-comments dark-cyan base5))
+ (doc-comments (doom-lighten (if doom-ir-black-brighter-comments dark-cyan base5) 0.25))
+ (constants green-alt)
+ (functions orange-alt)
+ (keywords blue)
+ (methods cyan)
+ (operators white)
+ (type yellow)
+ (strings green)
+ (variables (doom-lighten magenta 0.4))
+ (numbers magenta)
+ (region `(,(doom-lighten (car bg-alt) 0.15) ,@(doom-lighten (cdr base0) 0.35)))
+ (error red)
+ (warning yellow)
+ (success green)
+ (vc-modified orange)
+ (vc-added green)
+ (vc-deleted red)
+
+ ;; custom categories
+ (-modeline-pad
+ (when doom-ir-black-padded-modeline
+ (if (integerp doom-ir-black-padded-modeline) doom-ir-black-padded-modeline 4)))
+
+ (modeline-fg white)
+ (modeline-fg-alt base5)
+ (modeline-bg base4)
+ (modeline-bg-inactive base3))
+
+
+ ;;;; Base theme face overrides
+ (((font-lock-comment-face &override)
+ :background (if doom-ir-black-brighter-comments (doom-lighten bg 0.05)))
+ ((line-number &override) :foreground base5)
+ ((line-number-current-line &override) :foreground "#FFFF00" :weight 'bold)
+ (mode-line
+ :background modeline-bg :foreground modeline-fg
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg)))
+ (mode-line-inactive
+ :background modeline-bg-inactive :foreground modeline-fg-alt
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive)))
+
+ ;;;; css-mode <built-in> / scss-mode
+ (css-proprietary-property :foreground orange)
+ (css-property :foreground green)
+ (css-selector :foreground blue)
+ ;;;; elscreen
+ (elscreen-tab-other-screen-face :background "#353a42" :foreground "#1e2022")
+ ;;;; evil
+ (evil-goggles-default-face :inherit 'region :background (doom-blend region bg 0.5))
+ ;;;; ivy
+ (ivy-current-match :background dark-blue :distant-foreground base0 :weight 'normal)
+ ;;;; markdown-mode
+ (markdown-markup-face :foreground base5)
+ (markdown-header-face :inherit 'bold :foreground red)
+ (markdown-code-face :background (doom-lighten base3 0.05)))
+
+ ;;;; Base theme variable overrides-
+ ;; ()
+ )
+
+;;; doom-ir-black-theme.el ends here
diff --git a/elpa/doom-themes-20220504.1557/doom-laserwave-theme.el b/elpa/doom-themes-20220504.1557/doom-laserwave-theme.el
new file mode 100644
index 0000000..bf85585
--- /dev/null
+++ b/elpa/doom-themes-20220504.1557/doom-laserwave-theme.el
@@ -0,0 +1,163 @@
+;;; doom-laserwave-theme.el --- inspired by VS Code laserwave -*- lexical-binding: t; no-byte-compile: t; -*-
+(require 'doom-themes)
+
+;;
+(defgroup doom-laserwave-theme nil
+ "Options for the `doom-laserwave' theme."
+ :group 'doom-themes)
+
+(defcustom doom-laserwave-padded-modeline doom-themes-padded-modeline
+ "If non-nil, adds a 4px padding to the mode-line. Can be an integer to
+determine the exact padding."
+ :group 'doom-laserwave-theme
+ :type '(choice integer boolean))
+
+;;
+(def-doom-theme doom-laserwave
+ "An clean 80's synthwave / outrun theme inspired by VS Code laserwave."
+
+ ;; name default 256 16
+ ((bg '("#27212E" nil nil ))
+ (bg-alt '("#1B1720" nil nil ))
+ (base0 '("#222228" "black" "black" ))
+ (base1 '("#24262D" "#222222" "brightblack" ))
+ (base2 '("#282b33" "#222233" "brightblack" ))
+ (base3 '("#3E3549" "#333344" "brightblack" ))
+ (base4 '("#4E415C" "#444455" "brightblack" ))
+ (base5 '("#544863" "#554466" "brightblack" ))
+ (base6 '("#ED60BA" "#EE66BB" "brightblack" ))
+ (base7 '("#91889B" "#998899" "brightblack" ))
+ (base8 '("#ECEFF4" "#EEEEFF" "white" ))
+ (fg-alt '("#EEEEEE" "#EEEEEE" "brightwhite" ))
+ (fg '("#FFFFFF" "#FFFFFF" "white" ))
+
+ (grey base4)
+ (red '("#964C7B" "#964477" "red" ))
+ (orange '("#FFB85B" "#FFBB55" "brightred" ))
+ (green '("#74DFC4" "#77DDCC" "green" ))
+ (teal '("#4D8079" "#448877" "brightgreen" ))
+ (yellow '("#FFE261" "#FFEE66" "yellow" ))
+ (blue '("#40B4C4" "#44BBCC" "brightblue" ))
+ (dark-blue '("#336A79" "#336677" "blue" ))
+ (magenta '("#EB64B9" "#EE66BB" "brightmagenta"))
+ (violet '("#B381C5" "#BB88CC" "magenta" ))
+ (cyan '("#B4DCE7" "#BBDDEE" "brightcyan" ))
+ (dark-cyan '("#6D7E8A" "#667788" "cyan" ))
+
+ ;; face categories -- required for all themes
+ (highlight magenta)
+ (vertical-bar (doom-darken base1 0.2))
+ (selection dark-blue)
+ (builtin magenta)
+ (comments base7)
+ (doc-comments (doom-lighten dark-cyan 0.25))
+ (constants violet)
+ (functions magenta)
+ (keywords blue)
+ (methods cyan)
+ (operators blue)
+ (type yellow)
+ (strings cyan)
+ (variables fg)
+ (numbers orange)
+ (region `(,(doom-blend (car bg) (car magenta) 0.8) ,@(doom-lighten (cdr base1) 0.35)))
+ (error red)
+ (warning yellow)
+ (success green)
+ (vc-modified orange)
+ (vc-added green)
+ (vc-deleted red)
+
+ ;; custom categories
+ (hidden `(,(car bg) "black" "black"))
+ (-modeline-pad
+ (when doom-laserwave-padded-modeline
+ (if (integerp doom-laserwave-padded-modeline) doom-laserwave-padded-modeline 4)))
+
+ (modeline-fg bg-alt)
+ (modeline-fg-alt base6)
+ (modeline-bg base6)
+ (modeline-bg-inactive (doom-darken bg 0.1)))
+
+
+ ;;;; Base theme face overrides
+ ((lazy-highlight :background (doom-darken magenta 0.4) :foreground fg)
+ ((line-number &override) :foreground base4)
+ ((line-number-current-line &override) :foreground fg)
+ (mode-line
+ :background modeline-bg :foreground modeline-fg
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg)))
+ (mode-line-inactive
+ :background modeline-bg-inactive :foreground modeline-fg-alt
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive)))
+ (mode-line-emphasis :foreground bg-alt)
+ (mode-line-highlight :background orange :weight 'bold)
+ ;;;; centaur-tabs
+ (centaur-tabs-active-bar-face :background magenta)
+ (centaur-tabs-modified-marker-selected
+ :inherit 'centaur-tabs-selected :foreground magenta)
+ (centaur-tabs-modified-marker-unselected
+ :inherit 'centaur-tabs-unselected :foreground magenta)
+ ;;;; company
+ (company-box-background :foreground fg :background bg-alt)
+ ;;;; css-mode <built-in> / scss-mode
+ (css-proprietary-property :foreground orange)
+ (css-property :foreground green)
+ (css-selector :foreground blue)
+ ;;;; doom-modeline
+ (doom-modeline-bar :background base6)
+ (doom-modeline-info :inherit 'mode-line-emphasis)
+ (doom-modeline-urgent :inherit 'mode-line-emphasis)
+ (doom-modeline-warning :inherit 'mode-line-emphasis)
+ (doom-modeline-debug :inherit 'mode-line-emphasis)
+ (doom-modeline-buffer-minor-mode :inherit 'mode-line-emphasis :weight 'bold)
+ (doom-modeline-project-dir :inherit 'mode-line-emphasis :weight 'bold)
+ (doom-modeline-project-parent-dir :inherit 'mode-line-emphasis :weight 'bold)
+ (doom-modeline-persp-name :inherit 'mode-line-emphasis :weight 'bold)
+ (doom-modeline-buffer-file :inherit 'mode-line-emphasis :weight 'bold)
+ (doom-modeline-buffer-modified :inherit 'mode-line-emphasis :weight 'bold)
+ (doom-modeline-lsp-success :inherit 'mode-line-emphasis :weight 'bold)
+ (doom-modeline-buffer-path :inherit 'mode-line-emphasis :weight 'bold)
+ (doom-modeline-buffer-project-root :inherit 'mode-line-emphasis)
+ (doom-modeline-evil-visual-state :foreground yellow)
+ (doom-modeline-evil-replace-state :foreground orange)
+ (doom-modeline-evil-operator-state :foreground teal)
+ ;;;; elscreen
+ (elscreen-tab-other-screen-face :background "#353a42" :foreground "#1e2022")
+ ;;;; ivy
+ (ivy-current-match :background base2 :distant-foreground nil)
+ ;;;; markdown-mode
+ (markdown-header-delimiter-face :foreground base7)
+ (markdown-metadata-key-face :foreground base7)
+ (markdown-list-face :foreground base7)
+ (markdown-link-face :foreground cyan)
+ (markdown-url-face :inherit 'link :foreground fg :weight 'normal)
+ (markdown-italic-face :inherit 'italic :foreground magenta)
+ (markdown-bold-face :inherit 'bold :foreground magenta)
+ (markdown-markup-face :foreground base7)
+ (markdown-gfm-checkbox-face :foreground cyan)
+ ;;;; mic-paren
+ (paren-face-match :foreground yellow :background (doom-darken bg 0.2) :weight 'ultra-bold)
+ ;;;; outline <built-in>
+ ((outline-1 &override) :foreground blue)
+ ((outline-2 &override) :foreground green)
+ ((outline-3 &override) :foreground teal)
+ ((outline-4 &override) :foreground (doom-darken blue 0.2))
+ ((outline-5 &override) :foreground (doom-darken green 0.2))
+ ((outline-6 &override) :foreground (doom-darken teal 0.2))
+ ((outline-7 &override) :foreground (doom-darken blue 0.4))
+ ((outline-8 &override) :foreground (doom-darken green 0.4))
+ ;;;; org <built-in>
+ ((org-block &override) :background base2)
+ ((org-block-begin-line &override) :background base2)
+ (org-hide :foreground hidden)
+ ;;;; org-pomodoro
+ (org-pomodoro-mode-line :inherit 'mode-line-emphasis :weight 'bold) ; unreadable otherwise
+ (org-pomodoro-mode-line-overtime :inherit 'org-pomodoro-mode-line)
+ (org-pomodoro-mode-line-break :inherit 'org-pomodoro-mode-line)
+ ;;;; solaire-mode
+ (solaire-mode-line-face
+ :background modeline-bg :foreground modeline-fg
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg)))))
+
+;;; doom-laserwave-theme.el ends here
diff --git a/elpa/doom-themes-20220504.1557/doom-manegarm-theme.el b/elpa/doom-themes-20220504.1557/doom-manegarm-theme.el
new file mode 100644
index 0000000..e7cf772
--- /dev/null
+++ b/elpa/doom-themes-20220504.1557/doom-manegarm-theme.el
@@ -0,0 +1,211 @@
+;;; doom-manegarm-theme.el -*- lexical-binding: t; no-byte-compile: t; -*-
+(require 'doom-themes)
+
+;;
+(defgroup doom-manegarm-theme nil
+ "Options for the `doom-manegarm' theme."
+ :group 'doom-themes)
+
+(defcustom doom-manegarm-padded-modeline doom-themes-padded-modeline
+ "If non-nil, adds a 4px padding to the mode-line. Can be an integer to
+determine the exact padding."
+ :group 'doom-manegarm-theme
+ :type '(choice integer boolean))
+
+(defcustom doom-manegarm-muted-modeline nil
+ "If non-nil, the modeline will be in a more muted tone.
+Otherwise it's in a dark green color similar to visual mode
+selections."
+ :group 'doom-manegarm-theme
+ :type 'boolean)
+
+(defcustom doom-manegarm-darker-background nil
+ "If non-nil, the background color will be a bit darker.
+This also affects solaire-mode, where the background colors of
+real file buffers will now be brighter instead."
+ :group 'doom-manegarm-theme
+ :type 'boolean)
+
+;;
+(def-doom-theme doom-manegarm
+ "A dark theme with autumn-inspired colors"
+
+ ;; name default 256 16
+ (
+ (-bg '("#1c1408" nil nil ))
+ (-bg-alt '("#181107" nil nil ))
+ (bg (if doom-manegarm-darker-background -bg-alt -bg))
+ (bg-alt (if doom-manegarm-darker-background -bg -bg-alt))
+ (base0 '("#1B2229" "black" "black" ))
+ (base1 '("#1c1f24" "#1c1f24" "brightblack" ))
+ (base2 '("#202328" "#202328" "brightblack" ))
+ (base3 '("#23272e" "#23272e" "brightblack" ))
+ (base4 '("#3f444a" "#3f444a" "brightblack" ))
+ (base5 '("#95836f" "#95836f" "brightblack" ))
+ (base6 '("#73797e" "#73797e" "brightblack" ))
+ (base7 '("#9ca0a4" "#9ca0a4" "brightblack" ))
+ (base8 '("#dfdfdf" "#dfdfdf" "white" ))
+ (fg '("#5b8512" "#5b8512" "brightwhite" ))
+ (fg-alt '("#4f7410" "#4f7410" "white" ))
+
+ (grey '("#707a6a" "#707a6a" "brightblack" ))
+ (red '("#ff4e00" "#ff4e00" "red" ))
+ (orange '("#ff7000" "#ff7000" "brightred" ))
+ (green '("#7cb518" "#7cb518" "green" ))
+ (teal '("#dbc077" "#dbc077" "brightgreen" )) ;; more of a sand/beige color
+ (yellow '("#ffbf00" "#ffbf00" "yellow" ))
+ (blue '("#0075c4" "#0075c4" "brightblue" ))
+ (dark-blue '("#0060a1" "#0060a1" "blue" ))
+ (magenta '("#d72638" "#d72638" "brightmagenta"))
+ (violet '("#76597b" "#76597b" "magenta" ))
+ (cyan '("#898989" "#898989" "brightcyan" ))
+ (dark-cyan '("#4f7410" "#4f7410" "cyan" ))
+
+ ;; face categories -- required for all themes
+ (highlight yellow)
+ (vertical-bar (doom-darken grey 0.4))
+ (selection (doom-darken dark-cyan 0.8))
+ (builtin yellow)
+ (comments grey)
+ (doc-comments grey)
+ (constants orange)
+ (functions orange)
+ (keywords red)
+ (methods red)
+ (operators yellow)
+ (type green)
+ (strings (doom-darken teal 0.1))
+ (variables green)
+ (numbers teal)
+ (region (doom-darken dark-cyan 0.7))
+ (error red)
+ (warning yellow)
+ (success green)
+ (vc-modified orange)
+ (vc-added green)
+ (vc-deleted red)
+
+ ;; custom categories
+ (hidden `(,(car bg) "black" "black"))
+ (-modeline-pad
+ (when doom-manegarm-padded-modeline
+ (if (integerp doom-manegarm-padded-modeline) doom-manegarm-padded-modeline 4)))
+
+ (modeline-fg green)
+ (modeline-fg-alt vertical-bar)
+
+ (modeline-bg
+ `(,(car (if doom-manegarm-muted-modeline (doom-darken teal 0.75) (doom-darken green 0.8)))
+ ,@(cdr base0)))
+ (modeline-bg-inactive `(,(doom-darken (car bg) 0.2) ,@(cdr base0))))
+
+ ;;;; Base theme face overrides
+ ((button :foreground teal :weight 'bold :underline t)
+ (custom-button :foreground teal :weight 'bold :underline t :background bg)
+ ((font-lock-comment-face &override)
+ :inherit 'fixed-pitch-serif
+ :slant 'italic
+ :background nil)
+ ((line-number &override) :foreground vertical-bar)
+ ((line-number-current-line &override) :foreground orange)
+ (mode-line
+ :background modeline-bg :foreground modeline-fg
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg)))
+ (mode-line-inactive
+ :background modeline-bg-inactive :foreground modeline-fg-alt
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive)))
+ (mode-line-emphasis :foreground highlight)
+
+ ;;;; company
+ (company-tooltip :background (doom-darken region 0.1))
+ (company-tooltip-search-selection :foreground yellow)
+ (company-tooltip-mouse :inherit 'company-tooltip-search-selection)
+ (company-tooltip-selection :inherit 'company-tooltip-search-selection)
+ (company-tooltip-annotation :foreground (doom-darken blue 0.2))
+ (company-tooltip-annotation-selection :foreground blue)
+ ;;;; css-mode <built-in> / scss-mode
+ (css-proprietary-property :foreground orange)
+ (css-property :foreground green)
+ (css-selector :foreground blue)
+ ;;;; dired
+ (dired-directory :foreground green :bold 'bold)
+ ;;;; diredfl
+ (diredfl-dir-heading :foreground yellow :weight 'bold)
+ (diredfl-dir-name :foreground green :bold 'bold)
+ (diredfl-dir-priv :foreground teal)
+ (diredfl-number :foreground red)
+ ;;;; doom-modeline
+ (doom-modeline-bar :background highlight)
+ (doom-modeline-buffer-file :inherit 'mode-line-buffer-id :weight 'bold)
+ (doom-modeline-buffer-path :inherit 'mode-line-emphasis :weight 'bold)
+ (doom-modeline-buffer-project-root :foreground green :weight 'bold)
+ (doom-modeline-project-dir :bold t :foreground orange)
+ ;;;; elscreen
+ (elscreen-tab-other-screen-face :background "#353a42" :foreground "#1e2022")
+ ;;;; evil
+ (evil-ex-search :inverse-radio t)
+ (evil-ex-lazy-highlight :inverse-radio t)
+ ;;;; helm
+ (helm-match :inherit 'bold :foreground yellow :background nil)
+ (helm-selection :inherit 'normal :background region)
+ ;;;; highlight-numbers
+ ((highlight-numbers-number &override) :inherit 'normal :foreground numbers)
+ ;;;; isearch
+ (isearch :inverse-radio t :weight 'bold)
+ ;;;; ivy
+ (ivy-current-match :background region :distant-foreground teal :weight 'normal)
+ (ivy-minibuffer-match-highlight :foreground yellow)
+ (ivy-minibuffer-match-face-1 :foreground green :background nil) ;; seems to be used for weird space between matches
+ (ivy-minibuffer-match-face-2 :inherit 'ivy-minibuffer-match-face-1 :foreground orange)
+ (ivy-minibuffer-match-face-3 :inherit 'ivy-minibuffer-match-face-2 :foreground yellow)
+ (ivy-minibuffer-match-face-4 :inherit 'ivy-minibuffer-match-face-2 :foreground magenta)
+ (ivy-highlight-face :foreground green)
+ ;;;; lsp-mode
+ (lsp-face-highlight-textual
+ :background (doom-darken blue 0.5) :foreground yellow :weight 'bold)
+ ;;;; magit
+ (magit-branch-current :foreground yellow)
+ (magit-branch-remote :foreground orange)
+ (magit-section-heading :foreground blue :weight 'bold)
+ (magit-section-heading-selection :foreground yellow :weight 'bold)
+ (magit-section-secondary-heading :foreground green)
+ (magit-filename :foreground green)
+ (magit-diff-hunk-heading-highlight :foreground bg :background fg)
+ (magit-branch-local :foreground yellow)
+ (magit-diff-file-heading :weight 'regular)
+ (magit-header-line :background nil :foreground blue :weight 'bold)
+ ;;;; markdown-mode
+ (markdown-markup-face :foreground base5)
+ (markdown-header-face :inherit 'bold :foreground red)
+ (markdown-code-face :background (doom-lighten base3 0.05))
+ ;;;; navigation
+ (nav-flash-face :background fg :foreground yellow)
+ ;;;; org <built-in>
+ (org-level-1 :foreground orange :bold t)
+ (org-level-2 :foreground blue :bold t)
+ (org-level-3 :foreground magenta :bold t)
+ (org-level-4 :foreground violet :bold t)
+ (org-level-5 :foreground red :bold t)
+ (org-level-6 :foreground yellow :bold t)
+ (org-hide :foreground hidden)
+ (org-todo :foreground strings :bold 'inherit)
+ ;;;; rainbow-delimiters
+ (rainbow-delimiters-depth-1-face :foreground yellow)
+ (rainbow-delimiters-depth-2-face :foreground orange)
+ (rainbow-delimiters-depth-3-face :foreground green)
+ (rainbow-delimiters-depth-4-face :foreground teal)
+ (rainbow-delimiters-depth-5-face :foreground magenta)
+ (rainbow-delimiters-depth-6-face :foreground blue)
+ (rainbow-delimiters-depth-7-face :foreground fg)
+ (rainbow-delimiters-depth-8-face :foreground violet)
+ (rainbow-delimiters-depth-9-face :foreground red)
+ ;;;; which-key
+ (which-func :foreground green)
+ (which-key-command-description-face :foreground fg)
+ (which-key-group-description-face :foreground yellow)
+ (which-key-local-map-description-face :foreground yellow))
+
+ ;;;; Base theme variable overrides-
+ ())
+
+;;; doom-manegarm-theme.el ends here
diff --git a/elpa/doom-themes-20220504.1557/doom-material-dark-theme.el b/elpa/doom-themes-20220504.1557/doom-material-dark-theme.el
new file mode 100644
index 0000000..4a71ff2
--- /dev/null
+++ b/elpa/doom-themes-20220504.1557/doom-material-dark-theme.el
@@ -0,0 +1,178 @@
+;;; doom-material-dark-theme.el --- inspired by Material Theme by xrei -*- lexical-binding: t; no-byte-compile: t; -*-
+(require 'doom-themes)
+
+;;
+(defgroup doom-material-dark-theme nil
+ "Options for the `material dark' theme."
+ :group 'doom-themes)
+
+
+(defcustom doom-material-padded-modeline doom-themes-padded-modeline
+ "If non-nil, adds a 4px padding to the mode-line.
+Can be an integer to determine the exact padding."
+ :group 'doom-material-dark-theme
+ :type '(choice integer boolean))
+
+;;
+(def-doom-theme doom-material-dark
+ "A darker version of the Material Theme inspired by xrei"
+
+ ;; name default 256 16
+ ((bg '("#212121" nil nil))
+ (bg-alt '("#3e3e3e" nil nil))
+ (base0 '("#171F24" "black" "black"))
+ (base1 '("#262626" "#262626" "brightblack"))
+ (base2 '("#303030" "#303030" "brightblack"))
+ (base3 '("#3A3A3A" "#3A3A3A" "brightblack"))
+ (base4 '("#4a4a4a" "#444444" "brightblack"))
+ (base5 '("#585858" "#585858" "brightblack"))
+ (base6 '("#626262" "#626262" "brightblack"))
+ (base7 '("#767676" "#767676" "brightblack"))
+ (base8 '("#A8A8A8" "#a8a8a8" "white"))
+ (fg '("#EEFFFF" "#e4e4e4" "brightwhite"))
+ (fg-alt '("#BFC7D5" "#bcbcbc" "white"))
+
+ (grey base5)
+
+ (red '("#f57373" "#ff0000" "red"))
+ (orange '("#F78C6C" "#ff5f00" "brightred"))
+ (green '("#c3e88d" "#afff00" "green"))
+ (teal '("#44b9b1" "#00d7af" "brightgreen"))
+ (yellow '("#ffcb6b" "#ffd700" "brightyellow"))
+ (blue '("#82aaff" "#5fafff" "brightblue"))
+ (dark-blue '("#7986E7" "#d7ffff" "blue"))
+ (magenta '("#c792ea" "#d787d7" "brightmagenta"))
+ (violet '("#bb80b3" "#d787af" "magenta"))
+ (cyan '("#89DDFF" "#5fd7ff" "brightcyan"))
+ (dark-cyan '("#80cbc4" "#00d7af" "cyan"))
+
+ ;; face categories -- required for all themes
+ (highlight magenta)
+ (vertical-bar base2)
+ (selection base4)
+ (builtin blue)
+ (comments base6)
+ (doc-comments base6)
+ (constants orange)
+ (functions blue)
+ (keywords cyan)
+ (methods blue)
+ (operators cyan)
+ (type magenta)
+ (strings green)
+ (variables yellow)
+ (numbers orange)
+ (region base3)
+ (error red)
+ (warning yellow)
+ (success green)
+ (vc-modified blue)
+ (vc-added green)
+ (vc-deleted red)
+
+ ;; custom categories
+ (modeline-bg base2)
+ (modeline-bg-alt (doom-darken bg 0.01))
+ (modeline-fg base8)
+ (modeline-fg-alt comments)
+
+ (-modeline-pad
+ (when doom-material-padded-modeline
+ (if (integerp doom-material-padded-modeline) doom-material-padded-modeline 4))))
+
+ ;;;; Base theme face overrides
+ (;;;; emacs
+ (lazy-highlight :background (doom-darken green 0.5) :foreground green :weight 'bold)
+ (minibuffer-prompt :foreground yellow)
+ (region :background (doom-darken dark-cyan 0.5) :foreground dark-cyan :distant-foreground (doom-darken fg 0.2) :extend t)
+ (hl-line :background base2 :foreground nil)
+ (mode-line
+ :background modeline-bg :foreground modeline-fg
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg)))
+ (mode-line-inactive
+ :background modeline-bg-alt :foreground modeline-fg-alt
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-alt)))
+ (tooltip :background (doom-darken bg-alt 0.2) :foreground fg)
+ (cursor :background yellow)
+ (line-number-current-line
+ :inherit '(hl-line default)
+ :foreground cyan :distant-foreground nil
+ :weight 'normal :italic nil :underline nil :strike-through nil)
+ (completions-first-difference :foreground yellow)
+ (icomplete-first-match :foreground green :underline t :weight 'bold)
+
+ ;;;; doom-modeline
+ (doom-modeline-buffer-path :foreground green :weight 'bold)
+ (doom-modeline-buffer-major-mode :inherit 'doom-modeline-buffer-path)
+ ;;;; highlight-thing highlight-symbol
+ (highlight-symbol-face :background region :distant-foreground fg-alt)
+ ;;;; highlight-thing
+ (highlight-thing :background region :distant-foreground fg-alt)
+ ;;;; man <built-in>
+ (Man-overstrike :inherit 'bold :foreground magenta)
+ (Man-underline :inherit 'underline :foreground blue)
+ ;;;; org <built-in>
+ ((org-block &override) :background base2)
+ ((org-block-background &override) :background base2)
+ ((org-block-begin-line &override) :background base2)
+ ;;;; css-mode <built-in> / scss-mode
+ (css-proprietary-property :foreground orange)
+ (css-property :foreground green)
+ (css-selector :foreground blue)
+ ;;;; dired-k
+ (dired-k-commited :foreground base4)
+ (dired-k-modified :foreground vc-modified)
+ (dired-k-ignored :foreground cyan)
+ (dired-k-added :foreground vc-added)
+ ;;;; ivy
+ (ivy-current-match :background base3)
+ (ivy-minibuffer-match-face-2
+ :inherit 'ivy-minibuffer-match-face-1
+ :foreground dark-cyan :background base1 :weight 'semi-bold)
+ ;;;; js2-mode
+ (js2-jsdoc-tag :foreground magenta)
+ (js2-object-property :foreground yellow)
+ (js2-object-property-access :foreground cyan)
+ (js2-function-param :foreground violet)
+ (js2-jsdoc-type :foreground base8)
+ (js2-jsdoc-value :foreground cyan)
+ ;;;; lsp
+ (lsp-headerline-breadcrumb-symbols-face :foreground base7)
+ ;;;; rainbow-delimiters
+ (rainbow-delimiters-depth-1-face :foreground magenta)
+ (rainbow-delimiters-depth-2-face :foreground orange)
+ (rainbow-delimiters-depth-3-face :foreground green)
+ (rainbow-delimiters-depth-4-face :foreground cyan)
+ (rainbow-delimiters-depth-5-face :foreground violet)
+ (rainbow-delimiters-depth-6-face :foreground yellow)
+ (rainbow-delimiters-depth-7-face :foreground blue)
+ (rainbow-delimiters-depth-8-face :foreground teal)
+ (rainbow-delimiters-depth-9-face :foreground dark-cyan)
+ ;;;; rjsx-mode
+ (rjsx-tag :foreground red)
+ (rjsx-attr :foreground yellow :slant 'italic :weight 'medium)
+ (rjsx-tag-bracket-face :foreground cyan)
+ ;;;; Magit
+ (magit-header-line :background (doom-lighten modeline-bg 0.2) :foreground green :weight 'bold
+ :box `(:line-width 3 :color ,(doom-lighten modeline-bg 0.2)))
+ ;;;; Treemacs
+ (treemacs-git-modified-face :foreground vc-modified)
+ ;;;; Web Mode
+ (web-mode-html-tag-face :foreground red)
+ (web-mode-html-attr-equal-face :foreground cyan)
+ ;;;; Org Mode
+ (org-level-1 :foreground green)
+ (org-level-2 :foreground yellow)
+ (org-level-3 :foreground red)
+ (org-level-4 :foreground cyan)
+ (org-level-5 :foreground blue)
+ (org-level-6 :foreground magenta)
+ (org-level-7 :foreground teal)
+ (org-level-8 :foreground violet)
+ (org-todo :foreground orange)
+ ;;;; css
+ (css-property :foreground orange)
+ (css-proprietary-property :foreground magenta)
+ (css-selector :foreground yellow)))
+
+;;; Doom-material-theme.el ends here
diff --git a/elpa/doom-themes-20220504.1557/doom-material-theme.el b/elpa/doom-themes-20220504.1557/doom-material-theme.el
new file mode 100644
index 0000000..634b3a5
--- /dev/null
+++ b/elpa/doom-themes-20220504.1557/doom-material-theme.el
@@ -0,0 +1,141 @@
+;;; doom-material-theme.el --- inspired by Material Theme by equinusocio -*- lexical-binding: t; no-byte-compile: t; -*-
+(require 'doom-themes)
+
+;;
+(defgroup doom-material-theme nil
+ "Options for the `material' theme."
+ :group 'doom-themes)
+
+(defcustom doom-material-padded-modeline doom-themes-padded-modeline
+ "If non-nil, adds a 4px padding to the mode-line.
+Can be an integer to determine the exact padding."
+ :group 'doom-material-theme
+ :type '(choice integer boolean))
+
+;;
+(def-doom-theme doom-material
+ "A dark theme inspired by Material Theme by equinusocio"
+
+ ;; name default 256 16
+ ((bg '("#263238" nil nil))
+ (bg-alt '("#1C262B" nil nil))
+ (base0 '("#171F24" "black" "black"))
+ (base1 '("#1C262B" "#262626" "brightblack"))
+ (base2 '("#222D32" "#303030" "brightblack"))
+ (base3 '("#171F24" "#3a3a3a" "brightblack"))
+ (base4 '("#314048" "#444444" "brightblack"))
+ (base5 '("#37474F" "#585858" "brightblack"))
+ (base6 '("#556369" "#626262" "brightblack"))
+ (base7 '("#737E84" "#767676" "brightblack"))
+ (base8 '("#9BA3A7" "#a8a8a8" "white"))
+ (fg '("#EEFFFF" "#e4e4e4" "brightwhite"))
+ (fg-alt '("#BFC7D5" "#bcbcbc" "white"))
+
+ (grey base5)
+
+ (red '("#ff5370" "#ff0000" "red"))
+ (orange '("#f78c6c" "#ff5f00" "brightred"))
+ (green '("#c3e88d" "#afff00" "green"))
+ (teal '("#44b9b1" "#00d7af" "brightgreen"))
+ (yellow '("#ffcb6b" "#ffd700" "brightyellow"))
+ (blue '("#82aaff" "#5fafff" "brightblue"))
+ (dark-blue '("#7986E7" "#d7ffff" "blue"))
+ (magenta '("#c792ea" "#d787d7" "brightmagenta"))
+ (violet '("#bb80b3" "#d787af" "magenta"))
+ (cyan '("#89DDFF" "#5fd7ff" "brightcyan"))
+ (dark-cyan '("#80cbc4" "#00d7af" "cyan"))
+
+ ;; face categories -- required for all themes
+ (highlight magenta)
+ (vertical-bar base2)
+ (selection base4)
+ (builtin blue)
+ (comments base6)
+ (doc-comments base6)
+ (constants orange)
+ (functions blue)
+ (keywords cyan)
+ (methods blue)
+ (operators cyan)
+ (type magenta)
+ (strings green)
+ (variables yellow)
+ (numbers orange)
+ (region base3)
+ (error red)
+ (warning yellow)
+ (success green)
+ (vc-modified blue)
+ (vc-added green)
+ (vc-deleted red)
+
+ ;; custom categories
+ (modeline-bg base2)
+ (modeline-bg-alt (doom-darken bg 0.01))
+ (modeline-fg base8)
+ (modeline-fg-alt comments)
+
+ (-modeline-pad
+ (when doom-material-padded-modeline
+ (if (integerp doom-material-padded-modeline) doom-material-padded-modeline 4))))
+
+ ;;;; Base theme face overrides
+ (;;;; emacs
+ (lazy-highlight :background base4 :foreground fg :weight 'bold)
+ (mode-line
+ :background modeline-bg :foreground modeline-fg
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg)))
+ (mode-line-inactive
+ :background modeline-bg-alt :foreground modeline-fg-alt
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-alt)))
+ (tooltip :background (doom-darken bg-alt 0.2) :foreground fg)
+
+ ;;;; doom-modeline
+ (doom-modeline-buffer-path :foreground green :weight 'bold)
+ (doom-modeline-buffer-major-mode :inherit 'doom-modeline-buffer-path)
+ ;;;; highlight-thing highlight-symbol
+ (highlight-symbol-face :background region :distant-foreground fg-alt)
+ ;;;; highlight-thing
+ (highlight-thing :background region :distant-foreground fg-alt)
+ ;;;; man <built-in>
+ (Man-overstrike :inherit 'bold :foreground magenta)
+ (Man-underline :inherit 'underline :foreground blue)
+ ;;;; org <built-in>
+ ((org-block &override) :background base2)
+ ((org-block-background &override) :background base2)
+ ((org-block-begin-line &override) :background base2)
+ ;;;; css-mode <built-in> / scss-mode
+ (css-proprietary-property :foreground orange)
+ (css-property :foreground green)
+ (css-selector :foreground blue)
+ ;;;; dired-k
+ (dired-k-commited :foreground base4)
+ (dired-k-modified :foreground vc-modified)
+ (dired-k-ignored :foreground cyan)
+ (dired-k-added :foreground vc-added)
+ ;;;; ivy
+ (ivy-current-match :background base5)
+ ;;;; js2-mode
+ (js2-jsdoc-tag :foreground magenta)
+ (js2-object-property :foreground yellow)
+ (js2-object-property-access :foreground cyan)
+ (js2-function-param :foreground violet)
+ (js2-jsdoc-type :foreground base8)
+ (js2-jsdoc-value :foreground cyan)
+ ;;;; lsp
+ (lsp-headerline-breadcrumb-symbols-face :foreground base7)
+ ;;;; rainbow-delimiters
+ (rainbow-delimiters-depth-1-face :foreground magenta)
+ (rainbow-delimiters-depth-2-face :foreground orange)
+ (rainbow-delimiters-depth-3-face :foreground green)
+ (rainbow-delimiters-depth-4-face :foreground cyan)
+ (rainbow-delimiters-depth-5-face :foreground violet)
+ (rainbow-delimiters-depth-6-face :foreground yellow)
+ (rainbow-delimiters-depth-7-face :foreground blue)
+ (rainbow-delimiters-depth-8-face :foreground teal)
+ (rainbow-delimiters-depth-9-face :foreground dark-cyan)
+ ;;;; rjsx-mode
+ (rjsx-tag :foreground red)
+ (rjsx-attr :foreground yellow :slant 'italic :weight 'medium)))
+
+;;; doom-material-theme.el ends here
diff --git a/elpa/doom-themes-20220504.1557/doom-meltbus-theme.el b/elpa/doom-themes-20220504.1557/doom-meltbus-theme.el
new file mode 100644
index 0000000..c2bcaa7
--- /dev/null
+++ b/elpa/doom-themes-20220504.1557/doom-meltbus-theme.el
@@ -0,0 +1,351 @@
+;;; doom-meltbus-theme.el --- -*- lexical-binding: t; no-byte-compile: t; -*-
+
+;;; Code:
+
+(require 'doom-themes)
+
+;;; Variables:
+
+(defgroup doom-meltbus-theme nil
+ "Options for the `meltbus' theme"
+ :group 'doom-themes)
+
+(defcustom doom-meltbus-hl-line t
+ "If non-nil, highlight the current line with an underline."
+ :group 'doom-meltbus-theme
+ :type 'boolean)
+
+(defcustom doom-meltbus-uniform-font-size nil
+ "If non-nil, all faces use the basic font size."
+ :group 'doom-meltbus-theme
+ :type 'boolean)
+
+(def-doom-theme doom-meltbus
+ "A dark mostly monochromatic theme inspired by the eltbus theme.
+
+Colours are only used to distinguish states and priorities, and to
+highlight interactive elements."
+
+ ;; default 256 16
+ ((bg '("black" "black" "black"))
+ (fg '("#dddddd" "#dddddd" "white"))
+
+ (bg-alt '("black" "black" "black"))
+ (fg-alt '("#dddddd" "#dddddd" "white"))
+
+ (base0 '("black" "black" "black"))
+ (base1 '("#111111" "#111111" "brightblack"))
+ (base2 '("#242424" "#222222" "brightblack"))
+ (base3 '("#464646" "#444444" "brightblack"))
+ (base4 '("#686868" "#666666" "brightblack"))
+ (base5 '("#8a8a8a" "#888888" "brightblack"))
+ (base6 '("#acacac" "#aaaaaa" "brightblack"))
+ (base7 '("#cecece" "#cccccc" "brightblack"))
+ (base8 '("#efefef" "#eeeeee" "white"))
+
+ (grey base4)
+ (red '("#f8b0b0" "#ffaaaa" "red"))
+ (dark-red '("#b22222" "#bb2222" "red"))
+ (orange '("#da8548" "#dd8844" "brightred"))
+ (green '("#448844" "#448844" "green"))
+ (teal '("#c0f860" "#aaffaa" "brightgreen"))
+ (yellow '("#cdad00" "#ccaa00" "yellow"))
+ (blue '("#87afff" "#88aaff" "brightblue"))
+ (dark-blue '("#7070aa" "#6666aa" "blue"))
+ (magenta '("#db7093" "#ee6688" "brightmagenta"))
+ (violet '("#a9a1e1" "#a9a1e1" "magenta"))
+ (cyan '("#46D9FF" "#46D9FF" "brightcyan"))
+ (dark-cyan '("#5699AF" "#5699AF" "cyan"))
+ (white '("#ffffff" "#ffffff" "white"))
+
+ ;; "universal syntax classes"; *mandatory*
+ (highlight blue)
+ (vertical-bar base1)
+ (selection base3)
+ (builtin base5)
+ (comments base4)
+ (doc-comments base5)
+ (constants base5)
+ (functions fg)
+ (keywords fg)
+ (methods fg)
+ (operators base5)
+ (type base6)
+ (strings base6)
+ (variables fg)
+ (numbers fg)
+ (region base2)
+ (error red)
+ (warning orange)
+ (success green)
+ (vc-modified orange)
+ (vc-added green)
+ (vc-deleted red)
+ (vc-conflict magenta)
+
+ ;; theme-local variables
+ (almost-invisible base3))
+
+ ;; Base theme face overrides
+ (((cursor &override) :background base7)
+ (region :inverse-video t)
+ (hl-line :underline doom-meltbus-hl-line)
+ ((link &override) :weight 'normal :underline nil :foreground highlight)
+ (link-visited :inherit 'link)
+ (minibuffer-prompt :foreground base5 :background base2 :weight 'bold)
+ (mode-line-emphasis :foreground fg :weight 'bold :distant-foreground bg)
+ (mode-line-highlight :foreground fg :weight 'bold :distant-foreground bg)
+ (mode-line-inactive :foreground base5)
+
+ ;;;; compilation <built-in>
+ (compilation-line-number :foreground fg :weight 'bold)
+ ;;;; custom <built-in>
+ ((custom-button &override) :foreground highlight)
+ ((custom-button-unraised &override) :foreground comments)
+ ((custom-button-pressed-unraised &override) :background comments)
+ ((custom-button-pressed &override) :background highlight)
+ ((custom-button-mouse &override) :background highlight)
+ ((custom-variable-button &override) :foreground fg)
+ (custom-saved :inherit 'custom-state)
+ (custom-modified :inherit 'custom-changed)
+ (custom-variable-tag :foreground fg)
+ ((custom-visibility &override) :foreground fg)
+ (custom-group-tag :foreground base8 :weight 'bold)
+ (custom-group-tag-1 :foreground fg)
+ (custom-group-subtitle :foreground fg)
+ ((custom-invalid &override) :foreground error)
+ (custom-state :foreground green)
+ (custom-changed :foreground orange)
+ ;;;; diff <built-in>
+ (diff-added :foreground vc-added)
+ (diff-changed :foreground vc-modified)
+ (diff-header :foreground fg :weight 'bold)
+ (diff-hunk-header :foreground base7 :background base3)
+ (diff-file-header :foreground fg :background base3 :weight 'bold)
+ (diff-refine-added :foreground bg :background vc-added :distant-foreground fg)
+ (diff-refine-changed :foreground bg :background vc-modified :distant-foreground fg)
+ (diff-refine-removed :foreground bg :background vc-deleted :distant-foreground fg)
+ (diff-removed :foreground vc-deleted)
+ ;;;; dired <built-in>
+ (dired-header :foreground doc-comments :weight 'bold)
+ (dired-mark :foreground builtin)
+ (dired-marked :foreground orange :weight 'bold)
+ (dired-symlink :foreground doc-comments :weight 'bold)
+ ;;;; diredfl
+ (diredfl-read-priv :foreground fg)
+ (diredfl-symlink :foreground cyan :weight 'bold)
+ ;;;; doom-modeline
+ (doom-modeline-bar :background fg :foreground bg)
+ (doom-modeline-bar-inactive :background base4 :foreground bg)
+ (doom-modeline-info :foreground fg :weight 'bold)
+ (doom-modeline-lsp-running :inherit 'doom-modeline-info)
+ (doom-modeline-evil-insert-state :foreground green)
+ (doom-modeline-evil-emacs-state :foreground cyan)
+ (doom-modeline-evil-normal-state :foreground base5)
+ (doom-modeline-evil-visual-state :foreground white)
+ (doom-modeline-evil-operator-state :inherit 'doom-modeline-evil-visual-state)
+ ;;;; evil
+ ((evil-ex-substitute-replacement &override) :foreground cyan)
+ ;;;; evil-snipe
+ ((evil-snipe-first-match-face &override) :background bg)
+ ;;;; flycheck
+ (flycheck-error :underline `(:style wave :color ,error))
+ (flycheck-info :underline `(:style wave :color ,success))
+ (flycheck-warning :underline `(:style wave :color ,warning))
+ ;;;; flymake
+ (flymake-error :underline `(:style wave :color ,error))
+ (flymake-note :underline `(:style wave :color ,success))
+ (flymake-warning :underline `(:style wave :color ,warning))
+ ;;;; flx-ido
+ ((flx-highlight-face &override) :foreground highlight)
+ ;;;; git-commit
+ ((git-commit-keyword &override) :foreground keywords)
+ (git-commit-comment-branch-local :inherit 'magit-branch-local)
+ (git-commit-comment-branch-remote :inherit 'magit-branch-remote)
+ (git-commit-comment-detached :foreground warning)
+ (git-commit-comment-file :foreground doc-comments)
+ ;;;; magit
+ ;; TODO reflog colours
+ (magit-blame-hash :foreground fg)
+ (magit-blame-date :foreground base6)
+ (magit-blame-heading :inherit 'magit-log-author :background base3 :extend t)
+ (magit-branch-current :foreground fg :weight 'bold :underline t)
+ (magit-branch-local :foreground bg :background fg :weight 'bold :distant-foreground fg)
+ (magit-branch-remote :foreground fg :weight 'bold)
+ (magit-diff-added :inherit 'diff-added)
+ (magit-diff-added-highlight :inherit 'magit-diff-context-highlight :foreground vc-added)
+ (magit-diff-base :foreground (doom-darken orange 0.2))
+ (magit-diff-base-highlight :foreground orange)
+ (magit-diff-context-highlight :foreground base7 :background base1)
+ (magit-diff-hunk-heading :inherit 'diff-hunk-header)
+ (magit-diff-hunk-heading-highlight :inherit 'diff-file-header)
+ (magit-diff-removed :inherit 'diff-removed)
+ (magit-diff-removed-highlight :inherit 'magit-diff-context-highlight :foreground vc-deleted)
+ (magit-diff-whitespace-warning :foreground bg :background vc-deleted)
+ (magit-diffstat-added :inherit 'diff-added)
+ (magit-diffstat-removed :inherit 'diff-removed)
+ (magit-header-line :background base2 :foreground base6 :weight 'bold :box `(:line-width 3 :color ,base2))
+ (magit-filename :foreground fg)
+ (magit-item-highlight :weight 'bold)
+ (magit-log-author :foreground fg)
+ (magit-log-date :foreground fg)
+ (magit-section-heading :weight 'bold :extend t)
+ (magit-section-highlight :background base1)
+ (magit-tag :foreground vc-added)
+ ;;;; marginalia
+ ;; TODO (uses many colours)
+ ;;;; markdown <modes:markdown-mode,gfm-mode>
+ (markdown-header-face :inherit 'bold :foreground fg)
+ (markdown-metadata-key-face :foreground builtin)
+ (markdown-list-face :foreground builtin)
+ (markdown-link-face :foreground fg)
+ (markdown-url-face :inherit 'link)
+ (markdown-italic-face :inherit 'italic)
+ (markdown-bold-face :inherit 'bold)
+ (markdown-blockquote-face :inherit 'org-quote)
+ (markdown-code-face :inherit 'org-code)
+ ;;;; message <built-in>
+ (message-cited-text-1 :foreground base7 :background base2)
+ (message-cited-text-2 :foreground base5 :background base2)
+ (message-cited-text-3 :inherit 'message-cited-text-1)
+ (message-cited-text-4 :inherit 'message-cited-text-2)
+ (message-header-cc :foreground fg :background bg :weight 'bold)
+ (message-header-name :foreground base5)
+ (message-header-newsgroups :inherit 'message-cited-text)
+ (message-header-other :foreground almost-invisible)
+ (message-header-subject :inherit 'message-cited-text)
+ (message-header-to :inherit 'message-header-cc)
+ (message-header-xheader :inherit 'message-header-other)
+ (message-header-mml :inherit 'message-header-other)
+ (message-header-separator :foreground highlight)
+ ;;;; neotree
+ (neo-vc-added-face :inherit 'treemacs-git-added-face)
+ (neo-vc-conflict-face :inherit 'treemacs-git-conflict-face)
+ (neo-vc-modified-face :inherit 'treemacs-git-modified-face)
+ (doom-neotree-data-file-face :foreground comments)
+ ;;;; notmuch
+ (notmuch-crypto-signature-bad :foreground error)
+ (notmuch-crypto-signature-good :foreground almost-invisible)
+ (notmuch-crypto-signature-unknown :foreground warning)
+ (notmuch-crypto-signature-good-key :foreground error)
+ (notmuch-crypto-decryption :foreground error)
+ (notmuch-message-summary-face :background base2)
+ (notmuch-search-matching-authros :foreground highlight)
+ (notmuch-tag-face :inherit 'message-header-separator)
+ (notmuch-tree-match-tag-face :inherit 'notmuch-tag-face)
+ (notmuch-tree-match-author-face :inherit 'notmuch-tree-match-tag-face)
+ ;;;; lsp-ui
+ (lsp-ui-peek-header :foreground base8 :background base3 :bold bold)
+ (lsp-ui-peek-highlight :inherit 'lsp-ui-peek-header :background base4 :foreground fg)
+ (lsp-ui-peek-list :background base2)
+ (lsp-ui-peek-peek :background bg)
+ (lsp-ui-peek-line-number :foreground fg)
+ (lsp-ui-peek-selection :foreground bg :background highlight :bold bold)
+ (lsp-ui-sideline-code-action :foreground base8)
+ (lsp-ui-sideline-current-symbol :inherit 'lsp-ui-sideline-code-action)
+ ;;;; org <built-in> <modes:org-mode>
+ (org-code :foreground doc-comments)
+ (org-date :inherit 'link)
+ (org-date-selected :inherit 'lazy-highlight)
+ (org-document-title :height (if doom-meltbus-uniform-font-size 1.0 1.7)
+ :foreground (if doom-meltbus-uniform-font-size base8 doc-comments)
+ :weight 'bold :slant 'normal)
+ (org-done :foreground success :weight 'bold)
+ (org-done-keyword-face :foreground success)
+ (org-drawer :foreground comments)
+ (org-block :foreground fg :background nil :weight 'normal :slant 'normal :underline nil :inverse-video nil)
+ (org-block-begin-line :foreground base5 :weight 'bold)
+ (org-block-end-line :inherit 'org-block-begin-line)
+ (org-footnote :foreground doc-comments)
+ (org-formula :foreground doc-comments)
+ (org-list-dt :foreground base8 :weight 'bold)
+ ;; org-level-N inherits from outline-N
+ (org-property-value :foreground fg)
+ (org-table :foreground fg)
+ (org-todo :foreground error :weight 'bold)
+ (org-todo-keyword-face :foreground error)
+ (org-verbatim :inherit 'org-code)
+ ;;;; org-agenda <built-in>
+ (org-agenda-clocking :background base3)
+ ; (org-agenda-date :foreground fg)
+ ; (org-agenda-date-today :inherit 'default :bold bold :underline t)
+ ; (org-agenda-date-weekend :inherit 'default :foreground (doom-darken (face-foreground 'org-agenda-date) 0.3))
+ (org-scheduled-previously :foreground base6 :bold bold)
+ ;;;; org-journal <modes:org-journal-mode>
+ (org-journal-calendar-entry-face :foreground fg :slant 'italic :underline t)
+ (org-journal-calendar-scheduled-face :foreground bg :background fg :slant 'italic )
+ ;;;; org-ref
+ (org-ref-acronym-face :foreground red)
+ (org-ref-cite-face :foreground green)
+ (org-ref-glossary-face :foreground dark-red)
+ (org-ref-label-face :foreground blue)
+ (org-ref-ref-face :foreground teal)
+ ;;;; outline
+ (outline-1 :height (if doom-meltbus-uniform-font-size 1.0 1.5)
+ :background base1 :weight 'bold)
+ (outline-2 :height (if doom-meltbus-uniform-font-size 1.0 1.4)
+ :foreground (if doom-meltbus-uniform-font-size (doom-darken fg 0.2))
+ :background base1 :weight 'bold)
+ (outline-3 :height (if doom-meltbus-uniform-font-size 1.0 1.3)
+ :foreground (if doom-meltbus-uniform-font-size (doom-darken fg 0.3))
+ :background base1 :weight 'bold)
+ (outline-4 :height (if doom-meltbus-uniform-font-size 1.0 1.2)
+ :foreground (if doom-meltbus-uniform-font-size (doom-darken fg 0.4))
+ :background base1 :weight 'bold)
+ (outline-5 :height (if doom-meltbus-uniform-font-size 1.0 1.1)
+ :background base1
+ :weight (if doom-meltbus-uniform-font-size 'normal 'bold))
+ (outline-6 :height (if doom-meltbus-uniform-font-size 1.0 1.0)
+ :foreground (if doom-meltbus-uniform-font-size (doom-darken fg 0.2))
+ :background base1
+ :weight (if doom-meltbus-uniform-font-size 'normal 'bold))
+ (outline-7 :height (if doom-meltbus-uniform-font-size 1.0 1.0)
+ :foreground (if doom-meltbus-uniform-font-size (doom-darken fg 0.3))
+ :background base1 :weight 'normal)
+ (outline-8 :height (if doom-meltbus-uniform-font-size 1.0 1.0)
+ :foreground (if doom-meltbus-uniform-font-size (doom-darken fg 0.4))
+ :background base1 :foreground base5 :weight 'normal)
+ ;;;; pkgbuild-mode <modes:pkgbuild-mode>
+ (pkgbuild-error-face :underline `(:style wave :color ,error))
+ ;;;; popup
+ (popup-tip-face :inherit 'popup-face :foreground fg :background bg :bold bold :underline t)
+ ;;;; rainbow-delimiters
+ (rainbow-delimiters-depth-1-face :foreground green)
+ (rainbow-delimiters-depth-2-face :foreground dark-red)
+ (rainbow-delimiters-depth-3-face :foreground red)
+ (rainbow-delimiters-depth-4-face :inherit 'rainbow-delimiters-depth-1-face)
+ (rainbow-delimiters-depth-5-face :inherit 'rainbow-delimiters-depth-2-face)
+ (rainbow-delimiters-depth-6-face :inherit 'rainbow-delimiters-depth-3-face)
+ (rainbow-delimiters-depth-7-face :inherit 'rainbow-delimiters-depth-1-face)
+ (rainbow-delimiters-depth-8-face :inherit 'rainbow-delimiters-depth-2-face)
+ (rainbow-delimiters-depth-9-face :inherit 'rainbow-delimiters-depth-3-face)
+ (rainbow-delimiters-base-face :inherit 'default)
+ ;;;; smerge-tool
+ (smerge-markers :inherit 'magit-diff-conflict-heading)
+ (smerge-lower :inherit 'diff-added)
+ (smerge-upper :inherit 'diff-removed)
+ (smerge-base :inherit 'diff-changed)
+ (smerge-refined-added :inherit 'diff-refine-added)
+ (smerge-refined-removed :inherit 'diff-refine-removed)
+ ;;;; treemacs
+ (treemacs-git-conflict-face :foreground vc-conflict)
+ (treemacs-git-modified-face :foreground vc-modified)
+ ;;;; vterm
+ (vterm-color-black :inherit 'term-color-black)
+ (vterm-color-red :inherit 'term-color-red)
+ (vterm-color-blue :inherit 'term-color-blue)
+ (vterm-color-green :inherit 'term-color-green)
+ (vterm-color-yellow :inherit 'term-color-yellow)
+ (vterm-color-magenta :inherit 'term-color-magenta)
+ (vterm-color-cyan :inherit 'term-color-cyan)
+ (vterm-color-white :inherit 'term-color-white)
+ ;;;; which-key
+ (which-key-key-face :foreground base5)
+ (which-key-group-description-face :foreground base5)
+ (which-key-command-description-face :foreground fg :weight 'bold)
+ (which-key-local-map-description-face :foreground fg))
+
+ ;; Base theme variable overrides
+ ())
+
+;;; doom-meltbus-theme.el ends here
diff --git a/elpa/doom-themes-20220504.1557/doom-miramare-theme.el b/elpa/doom-themes-20220504.1557/doom-miramare-theme.el
new file mode 100644
index 0000000..1934e91
--- /dev/null
+++ b/elpa/doom-themes-20220504.1557/doom-miramare-theme.el
@@ -0,0 +1,253 @@
+;; doom-miramare-theme.el --- inspired by Franbach miramare -*- lexical-binding: t; no-byte-compile: t; -*-
+(require 'doom-themes)
+
+;; Compiler pacifier
+(defvar modeline-bg)
+
+;;
+(defgroup doom-miramare-theme nil
+ "Options for doom-miramare."
+ :group 'doom-themes)
+
+(defcustom doom-miramare-brighter-comments nil
+ "If non-nil, comments will be highlighted in more vivid colors."
+ :group 'doom-miramare-theme
+ :type 'boolean)
+
+(defcustom doom-miramare-padded-modeline doom-themes-padded-modeline
+ "If non-nil, adds a 4px padding to the mode-line. Can be an integer to
+determine the exact padding."
+ :group 'doom-miramare-theme
+ :type '(choice integer boolean))
+
+(def-doom-theme doom-miramare
+ "A gruvbox variant with comfortable and pleasant colors."
+
+ ;; name gui 256 16
+ ((bg '("#2a2426" "#2a2426" nil )) ; bg1
+ (bg-alt '("#242021" "#242021" nil )) ; bg1
+ (bg-alt2 '("#504945" "#504945" "brown" )) ; bg2 (for region, selection etc.)
+
+ (base0 '("#0d1011" "black" "black" )) ; (self-defined)
+ (base1 '("#1d2021" "#1d1d1d" "brightblack")) ; bg0_h
+ (base2 '("#282828" "#282828" "brightblack")) ; bg0
+ (base3 '("#3c3836" "#383838" "brightblack")) ; bg1
+ (base4 '("#5b5b5b" "#5c5c5c" "brightblack")) ; bg3
+ (base5 '("#7c6f64" "#6f6f6f" "brightblack")) ; bg4
+ (base6 '("#928374" "#909090" "brightblack")) ; gray
+ (base7 '("#d5c4a1" "#cccccc" "brightblack")) ; fg2
+ (base8 '("#fbf1c7" "#fbfbfb" "brightwhite")) ; fg0
+ (fg '("#e6d6ac" "#e6d6ac" "brightwhite")) ; fg/fg1
+ (fg-alt '("#d8caac" "#d8caac" "brightwhite")) ; fg2
+
+ (grey '("#5b5b5b" "#5b5b5b" "brightblack")) ; gray
+ (red '("#e68183" "#e68183" "red")) ; bright-red
+ (magenta '("#e68183" "#e68183" "magenta")) ; red
+ (violet '("#d3a0bc" "#d3a0bc" "brightmagenta")) ; bright-purple
+ (orange '("#e39b7b" "#e39b7b" "orange")) ; bright-orange
+ (yellow '("#d9bb80" "#d9bb80" "yellow")) ; bright-yellow
+ (teal '("#87af87" "#87af87" "green")) ; bright-aqua
+ (green '("#87af87" "#87af87" "green")) ; bright-green
+ (dark-green '("#678f67" "#678f67" "green")) ; green
+ (blue '("#89beba" "#89beba" "brightblue")) ; bright-blue
+ (dark-blue '("#458588" "#458588" "blue")) ; blue
+ (cyan '("#87c095" "#87c095" "brightcyan")) ; bright-aqua
+ (dark-cyan '("#67a075" "#67a075" "cyan")) ; aqua
+
+ ;; face categories
+ (highlight yellow)
+ (vertical-bar grey)
+ (selection bg-alt2)
+ (builtin orange)
+ (comments (if doom-miramare-brighter-comments magenta grey))
+ (doc-comments (if doom-miramare-brighter-comments (doom-lighten magenta 0.2) (doom-lighten fg-alt 0.25)))
+ (constants violet)
+ (functions cyan)
+ (keywords red)
+ (methods cyan)
+ (operators cyan)
+ (type yellow)
+ (strings green)
+ (variables cyan)
+ (numbers violet)
+ (region bg-alt2)
+ (error red)
+ (warning yellow)
+ (success green)
+
+ (vc-modified (doom-darken blue 0.15))
+ (vc-added (doom-darken green 0.15))
+ (vc-deleted (doom-darken red 0.15))
+
+ ;; custom categories
+ (-modeline-pad
+ (when doom-miramare-padded-modeline
+ (if (integerp doom-miramare-padded-modeline)
+ doom-miramare-padded-modeline
+ 4)))
+
+ (org-quote `(,(doom-lighten (car bg) 0.05) "#1f1f1f")))
+
+
+ ;;;; Base theme face overrides
+ ((button :foreground cyan :underline t :bold t)
+ (cursor :background "white")
+ (font-lock-variable-name-face :foreground cyan :italic t)
+ (hl-line :background bg-alt)
+ (isearch :foreground base0 :background orange)
+ (lazy-highlight
+ :background yellow :foreground base0 :distant-foreground base0
+ :weight 'bold)
+ ((line-number &override) :foreground base5)
+ ((line-number-current-line &override) :background bg-alt2 :foreground fg :bold t)
+ (minibuffer-prompt :foreground cyan)
+ (mode-line
+ :background bg-alt2 :foreground (doom-lighten fg-alt 0.25)
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color base3)))
+ (mode-line-inactive
+ :background bg :foreground base4
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color base2)))
+
+ ;; vimish-fold
+ ((vimish-fold-overlay &override) :inherit 'font-lock-comment-face :background bg-alt2 :weight 'light)
+ ((vimish-fold-mouse-face &override) :foreground "white" :background yellow :weight 'light)
+ ((vimish-fold-fringe &override) :foreground magenta :background magenta)
+ ;;;; company
+ (company-preview-common :foreground cyan)
+ (company-tooltip-common :foreground cyan)
+ (company-tooltip-common-selection :foreground cyan)
+ (company-tooltip-annotation :foreground cyan)
+ (company-tooltip-annotation-selection :foreground cyan)
+ (company-scrollbar-bg :background bg-alt)
+ (company-scrollbar-fg :background cyan)
+ (company-tooltip-selection :background bg-alt2)
+ (company-tooltip-mouse :background bg-alt2 :foreground nil)
+ ;;;; css-mode <built-in> / scss-mode
+ (css-proprietary-property :foreground keywords)
+ ;;;; dired
+ (dired-directory :foreground cyan)
+ (dired-marked :foreground yellow)
+ (dired-symlink :foreground cyan)
+ (dired-header :foreground cyan)
+ ;;;; doom-emacs
+ (+workspace-tab-selected-face :background dark-green :foreground "white")
+ ;;;; doom-modeline
+ (doom-modeline-bar :background dark-green)
+ (doom-modeline-buffer-file :inherit 'bold :foreground fg)
+ (doom-modeline-buffer-major-mode :foreground green :bold t)
+ (doom-modeline-buffer-modified :inherit 'bold :foreground yellow)
+ (doom-modeline-buffer-path :inherit 'bold :foreground green)
+ (doom-modeline-error :background bg)
+ (doom-modeline-info :bold t :foreground cyan)
+ (doom-modeline-panel :background dark-green :foreground fg)
+ (doom-modeline-project-dir :bold t :foreground cyan)
+ (doom-modeline-warning :foreground red :bold t)
+ ;;;; doom-themes
+ (doom-themes-neotree-file-face :foreground fg)
+ (doom-themes-neotree-hidden-file-face :foreground (doom-lighten fg-alt 0.25))
+ (doom-themes-neotree-media-file-face :foreground (doom-lighten fg-alt 0.25))
+ ;;;; ediff <built-in>
+ (ediff-fine-diff-A :background (doom-blend red bg 0.4) :weight 'bold)
+ (ediff-current-diff-A :background (doom-blend red bg 0.2))
+ ;;;; evil
+ (evil-search-highlight-persist-highlight-face :background yellow)
+ (evil-ex-substitute-replacement :foreground cyan :inherit 'evil-ex-substitute-matches)
+ ;;;; evil-snipe
+ (evil-snipe-first-match-face :foreground "white" :background yellow)
+ (evil-snipe-matches-face :foreground yellow :bold t :underline t)
+ ;;;; flycheck
+ (flycheck-error :underline `(:style wave :color ,red) :background base3)
+ (flycheck-warning :underline `(:style wave :color ,yellow) :background base3)
+ (flycheck-info :underline `(:style wave :color ,cyan) :background base3)
+ ;;;; helm
+ (helm-swoop-target-line-face :foreground magenta :inverse-video t)
+ ;;;; highlight-quoted
+ (highlight-quoted-symbol :foreground dark-cyan)
+ ;;;; highlight-symbol
+ (highlight-symbol-face :background (doom-lighten base3 0.03) :distant-foreground fg-alt)
+ ;;;; highlight-thing
+ (highlight-thing :background (doom-lighten base3 0.03) :distant-foreground fg-alt)
+ ;;;; ivy
+ (ivy-current-match :background bg-alt2)
+ (ivy-subdir :background nil :foreground cyan)
+ (ivy-action :background nil :foreground cyan)
+ (ivy-grep-line-number :background nil :foreground cyan)
+ (ivy-minibuffer-match-face-1 :background nil :foreground yellow :bold t)
+ (ivy-minibuffer-match-face-2 :background nil :foreground red :bold t)
+ (ivy-minibuffer-match-highlight :foreground cyan)
+ (counsel-key-binding :foreground cyan)
+ ;;;; ivy-posframe
+ (ivy-posframe :background bg-alt)
+ (ivy-posframe-border :background base1)
+ ;;;; LaTeX-mode
+ (font-latex-math-face :foreground dark-cyan)
+ ;;;; magit
+ (magit-section-heading :foreground yellow :weight 'bold)
+ (magit-branch-current :underline cyan :inherit 'magit-branch-local)
+ (magit-diff-hunk-heading :background base3 :foreground fg-alt)
+ (magit-diff-hunk-heading-highlight :background bg-alt2 :foreground fg)
+ (magit-diff-context :foreground bg-alt :foreground fg-alt)
+ ;;;; markdown-mode
+ (markdown-blockquote-face :inherit 'italic :foreground cyan)
+ (markdown-list-face :foreground red)
+ (markdown-url-face :foreground red)
+ (markdown-pre-face :foreground cyan)
+ (markdown-link-face :inherit 'bold :foreground cyan)
+ ((markdown-code-face &override) :background (doom-lighten base2 0.045))
+ ;;;; mu4e-view
+ (mu4e-header-key-face :foreground red)
+ ;;;; neotree
+ (neo-root-dir-face :foreground cyan)
+ (doom-neotree-dir-face :foreground cyan)
+ (neo-dir-link-face :foreground cyan)
+ (neo-expand-btn-face :foreground magenta)
+ ;;;; outline <built-in>
+ ((outline-1 &override) :foreground yellow)
+ ((outline-2 &override) :foreground cyan)
+ ((outline-3 &override) :foreground cyan)
+ ;;;; org <built-in>
+ (org-ellipsis :underline nil :foreground orange)
+ (org-tag :foreground yellow :bold nil)
+ ((org-quote &override) :inherit 'italic :foreground base7 :background org-quote)
+ (org-todo :foreground yellow :bold 'inherit)
+ (org-list-dt :foreground yellow)
+ ;;;; show-paren
+ ((show-paren-match &override) :foreground nil :background base5 :bold t)
+ ((show-paren-mismatch &override) :foreground nil :background "red")
+ ;;;; which-func
+ (which-func :foreground cyan)
+ ;;;; which-key
+ (which-key-command-description-face :foreground fg)
+ (which-key-group-description-face :foreground (doom-lighten fg-alt 0.25))
+ (which-key-local-map-description-face :foreground cyan)
+ ;;;; undo-tree
+ (undo-tree-visualizer-active-branch-face :foreground cyan)
+ (undo-tree-visualizer-current-face :foreground yellow)
+ ;;;; rainbow-delimiters
+ (rainbow-delimiters-depth-1-face :foreground red)
+ (rainbow-delimiters-depth-2-face :foreground yellow)
+ (rainbow-delimiters-depth-3-face :foreground cyan)
+ (rainbow-delimiters-depth-4-face :foreground red)
+ (rainbow-delimiters-depth-5-face :foreground yellow)
+ (rainbow-delimiters-depth-6-face :foreground cyan)
+ (rainbow-delimiters-depth-7-face :foreground red)
+ ;;;; rjsx-mode
+ (rjsx-tag :foreground cyan :weight 'semi-bold)
+ (rjsx-text :foreground fg)
+ (rjsx-attr :foreground violet)
+ ;;;; solaire-mode
+ (solaire-hl-line-face :background bg-alt2)
+ ;;;; swiper
+ (swiper-line-face :background bg-alt2)
+ ;;;; web-mode
+ (web-mode-html-tag-bracket-face :foreground blue)
+ (web-mode-html-tag-face :foreground cyan :weight 'semi-bold)
+ (web-mode-html-attr-name-face :foreground violet)
+ (web-mode-json-key-face :foreground green)
+ (web-mode-json-context-face :foreground cyan))
+
+ ;; --- extra variables --------------------
+ ;; ()
+ )
+
+;;; doom-miramare-theme.el ends here
diff --git a/elpa/doom-themes-20220504.1557/doom-molokai-theme.el b/elpa/doom-themes-20220504.1557/doom-molokai-theme.el
new file mode 100644
index 0000000..2fe59ee
--- /dev/null
+++ b/elpa/doom-themes-20220504.1557/doom-molokai-theme.el
@@ -0,0 +1,201 @@
+;; doom-molokai-theme.el --- inspired by Textmate's Monokai -*- lexical-binding: t; no-byte-compile: t; -*-
+;;
+;; Copyright (C) 2017-2022 Henrik Lissner
+;;
+;; Author: Henrik Lissner <contact@henrik.io>
+;; Maintainer: Henrik Lissner <contact@henrik.io>
+;; Created: June 23, 2017
+;;
+;;; Commentary:
+;;
+;; Inspired by the Molokai color scheme available in Textmate.
+;;
+;;; Code:
+
+(require 'doom-themes)
+
+
+;;
+;;; Variables
+
+(defgroup doom-molokai-theme nil
+ "Options for the `doom-molokai' theme."
+ :group 'doom-themes)
+
+(defcustom doom-molokai-brighter-modeline nil
+ "If non-nil, more vivid colors will be used to style the mode-line."
+ :group 'doom-molokai-theme
+ :type 'boolean)
+
+(defcustom doom-molokai-brighter-comments nil
+ "If non-nil, comments will be highlighted in more vivid colors."
+ :group 'doom-molokai-theme
+ :type 'boolean)
+
+(defcustom doom-molokai-padded-modeline doom-themes-padded-modeline
+ "If non-nil, adds a 4px padding to the mode-line.
+Can be an integer to determine the exact padding."
+ :group 'doom-molokai-theme
+ :type '(choice integer boolean))
+
+
+;;
+;;; Theme definition
+
+(def-doom-theme doom-molokai
+ "A dark, vibrant theme inspired by Textmate's Monokai."
+
+ ;; name gui 256 16
+ ((bg '("#1c1e1f" "black" "black" ))
+ (fg '("#d6d6d4" "#dfdfdf" "brightwhite" ))
+
+ ;; These are off-color variants of bg/fg, used primarily for `solaire-mode',
+ ;; but can also be useful as a basis for subtle highlights (e.g. for hl-line
+ ;; or region), especially when paired with the `doom-darken', `doom-lighten',
+ ;; and `doom-blend' helper functions.
+ (bg-alt '("#222323" "black" "black" ))
+ (fg-alt '("#556172" "#4d4d4d" "white" ))
+
+ ;; These should represent a spectrum from bg to fg, where base0 is a starker
+ ;; bg and base8 is a starker fg. For example, if bg is light grey and fg is
+ ;; dark grey, base0 should be white and base8 should be black.
+ (base0 '("#1B2229" "black" "black" ))
+ (base1 '("#151617" "#101010" "brightblack" ))
+ (base2 '("#1d1f20" "#191919" "brightblack" ))
+ (base3 '("#2d2e2e" "#252525" "brightblack" ))
+ (base4 '("#4e4e4e" "#454545" "brightblack" ))
+ (base5 '("#555556" "#6b6b6b" "brightblack" ))
+ (base6 '("#767679" "#7b7b7b" "brightblack" ))
+ (base7 '("#cfc0c5" "#c1c1c1" "brightblack" ))
+ (base8 '("#ffffff" "#ffffff" "brightwhite" ))
+
+ (grey '("#525254" "#515154" "brightblack" ))
+ (red '("#e74c3c" "#e74c3c" "red" ))
+ (orange '("#fd971f" "#fd971f" "brightred" ))
+ (green '("#b6e63e" "#b6e63e" "green" ))
+ (teal green)
+ (yellow '("#e2c770" "#e2c770" "yellow" ))
+ (blue '("#268bd2" "#2686D6" "brightblue" ))
+ (dark-blue '("#727280" "#727280" "blue" ))
+ (magenta '("#fb2874" "#fb2874" "magenta" ))
+ (violet '("#9c91e4" "#9c91e4" "brightmagenta"))
+ (cyan '("#66d9ef" "#66d9ef" "brightcyan" ))
+ (dark-cyan '("#8fa1b3" "#8FA1B3" "cyan" ))
+
+ ;; These are the "universal syntax classes" that doom-themes establishes.
+ ;; These *must* be included in every doom themes, or your theme will throw an
+ ;; error, as they are used in the base theme defined in doom-themes-base.
+ (highlight orange)
+ (vertical-bar (doom-lighten bg 0.1))
+ (selection base5)
+ (builtin orange)
+ (comments (if doom-molokai-brighter-comments violet base5))
+ (doc-comments (if doom-molokai-brighter-comments
+ (doom-lighten violet 0.1)
+ (doom-lighten base5 0.25)))
+ (constants orange)
+ (functions green)
+ (keywords magenta)
+ (methods cyan)
+ (operators violet)
+ (type cyan)
+ (strings yellow)
+ (variables orange)
+ (numbers violet)
+ (region base4)
+ (error red)
+ (warning yellow)
+ (success green)
+ (vc-modified cyan)
+ (vc-added (doom-darken green 0.15))
+ (vc-deleted red)
+
+ ;; These are extra color variables used only in this theme; i.e. they aren't
+ ;; mandatory for derived themes.
+ (modeline-fg fg)
+ (modeline-fg-alt base4)
+ (modeline-bg (if doom-molokai-brighter-modeline base4 base3))
+ (modeline-bg-inactive (doom-darken (if doom-molokai-brighter-modeline
+ base3
+ base2)
+ 0.2))
+ (org-quote `(,(doom-lighten (car bg) 0.05) "#1f1f1f"))
+
+ (-modeline-pad
+ (when doom-molokai-padded-modeline
+ (if (integerp doom-molokai-padded-modeline) doom-molokai-padded-modeline 4))))
+
+
+ ;;;; Base theme face overrides
+ ((cursor :background magenta)
+ (lazy-highlight :background violet :foreground base0 :distant-foreground base0 :bold bold)
+ ((line-number &override) :foreground base5 :distant-foreground nil)
+ ((line-number-current-line &override) :foreground base7 :distant-foreground nil)
+ (mode-line
+ :background modeline-bg :foreground modeline-fg
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color modeline-bg)))
+ (mode-line-inactive
+ :background modeline-bg-inactive :foreground modeline-fg-alt
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color modeline-bg-inactive)))
+ (isearch :foreground base0 :background green)
+
+ ;;;; centaur-tabs
+ (centaur-tabs-active-bar-face :background green)
+ (centaur-tabs-modified-marker-selected :inherit 'centaur-tabs-selected :foreground green)
+ (centaur-tabs-modified-marker-unselected :inherit 'centaur-tabs-unselected :foreground green)
+ ;;;; css-mode <built-in> / scss-mode
+ (css-proprietary-property :foreground keywords)
+ ;;;; doom-modeline
+ (doom-modeline-bar :background green)
+ (doom-modeline-buffer-file :inherit 'mode-line-buffer-id :weight 'bold)
+ (doom-modeline-buffer-path :inherit 'bold :foreground green)
+ (doom-modeline-buffer-project-root :foreground green :weight 'bold)
+ (doom-modeline-buffer-modified :inherit 'bold :foreground orange)
+ ;;;; ediff <built-in>
+ (ediff-fine-diff-A :background (doom-blend magenta bg 0.3) :weight 'bold)
+ ;;;; evil
+ (evil-search-highlight-persist-highlight-face :background violet)
+ ;;;; evil-snipe
+ (evil-snipe-first-match-face :foreground base0 :background green)
+ (evil-snipe-matches-face :foreground green :underline t)
+ ;;;; flycheck
+ (flycheck-error :underline `(:style wave :color ,red) :background base3)
+ (flycheck-warning :underline `(:style wave :color ,yellow) :background base3)
+ (flycheck-info :underline `(:style wave :color ,green) :background base3)
+ ;;;; helm
+ (helm-swoop-target-line-face :foreground magenta :inverse-video t)
+ ;;;; ivy
+ (ivy-current-match :background base3)
+ (ivy-minibuffer-match-face-1 :background base1 :foreground base4)
+ ;;;; markdown-mode
+ (markdown-blockquote-face :inherit 'italic :foreground dark-blue)
+ (markdown-list-face :foreground magenta)
+ (markdown-pre-face :foreground cyan)
+ (markdown-link-face :inherit 'bold :foreground blue)
+ ((markdown-code-face &override) :background (doom-lighten base2 0.045))
+ ;;;; neotree
+ (neo-dir-link-face :foreground cyan)
+ (neo-expand-btn-face :foreground magenta)
+ ;;;; outline <built-in>
+ ((outline-1 &override) :foreground magenta)
+ ((outline-2 &override) :foreground orange)
+ ;;;; org <built-in>
+ (org-ellipsis :foreground orange)
+ (org-tag :foreground yellow :bold nil)
+ ((org-quote &override) :foreground base7)
+ (org-todo :foreground yellow :bold 'inherit)
+ (org-list-dt :foreground yellow)
+ ;;;; rainbow-delimiters
+ (rainbow-delimiters-depth-1-face :foreground magenta)
+ (rainbow-delimiters-depth-2-face :foreground orange)
+ (rainbow-delimiters-depth-3-face :foreground green)
+ (rainbow-delimiters-depth-4-face :foreground cyan)
+ (rainbow-delimiters-depth-5-face :foreground magenta)
+ (rainbow-delimiters-depth-6-face :foreground orange)
+ (rainbow-delimiters-depth-7-face :foreground green))
+
+ ;;;; Base theme variable overrides
+ ;; ()
+ )
+
+;;; doom-molokai-theme.el ends here
diff --git a/elpa/doom-themes-20220504.1557/doom-monokai-classic-theme.el b/elpa/doom-themes-20220504.1557/doom-monokai-classic-theme.el
new file mode 100644
index 0000000..ce4bbf3
--- /dev/null
+++ b/elpa/doom-themes-20220504.1557/doom-monokai-classic-theme.el
@@ -0,0 +1,179 @@
+;; doom-monokai-classic-theme.el --- inspired by Textmate's Monokai -*- lexical-binding: t; no-byte-compile: t; -*-
+(require 'doom-themes)
+
+;;
+(defgroup doom-monokai-classic-theme nil
+ "Options for doom-molokai."
+ :group 'doom-themes)
+
+(defcustom doom-monokai-classic-brighter-comments nil
+ "If non-nil, comments will be highlighted in more vivid colors."
+ :group 'doom-monokai-classic-theme
+ :type 'boolean)
+
+(defcustom doom-monokai-classic-comment-bg doom-monokai-classic-brighter-comments
+ "If non-nil, comments will have a subtle, darker background. Enhancing their
+legibility."
+ :group 'doom-monokai-classic-theme
+ :type 'boolean)
+
+(defcustom doom-monokai-classic-padded-modeline doom-themes-padded-modeline
+ "If non-nil, adds a 4px padding to the mode-line. Can be an integer to
+determine the exact padding."
+ :group 'doom-monokai-classic-theme
+ :type '(choice integer boolean))
+
+;;
+(def-doom-theme doom-monokai-classic
+ "A dark, vibrant theme inspired by Textmate's Monokai."
+
+ ;; name gui 256 16
+ ((bg '("#272822" nil nil ))
+ (bg-alt '("#1D1E19" nil nil ))
+ (base0 '("#1B2229" "black" "black" ))
+ (base1 '("#161613" "#101010" "brightblack"))
+ (base2 '("#1D1F20" "#191919" "brightblack"))
+ (base3 '("#2D2E2E" "#252525" "brightblack"))
+ (base4 '("#4E4E4E" "#454545" "brightblack"))
+ (base5 '("#555556" "#6B6B6B" "brightblack"))
+ (base6 '("#767679" "#7B7B7B" "brightblack"))
+ (base7 '("#CFC0C5" "#C1C1C1" "brightblack"))
+ (base8 '("#FFFFFF" "#FFFFFF" "brightwhite"))
+ (fg '("#F8F8F2" "#DFDFDF" "brightwhite"))
+ (fg-alt '("#556172" "#4D4D4D" "white"))
+
+ (grey '("#525254" "#525254" "brightblack"))
+ (red '("#E74C3C" "#E74C3C" "red"))
+ (orange '("#FD971F" "#FD971F" "brightred"))
+ (green '("#A6E22E" "#A6E22E" "green"))
+ (teal green)
+ (yellow '("#E6DB74" "#E6DB74" "yellow"))
+ (blue '("#268bd2" "#268bd2" "brightblue"))
+ (dark-blue '("#727280" "#727280" "blue"))
+ (magenta '("#F92660" "#F92660" "magenta"))
+ (violet '("#9C91E4" "#9C91E4" "brightmagenta"))
+ (cyan '("#66D9EF" "#66D9EF" "brightcyan"))
+ (dark-cyan '("#8FA1B3" "#8FA1B3" "cyan"))
+
+ ;; face categories
+ (highlight orange)
+ (vertical-bar (doom-lighten bg 0.1))
+ (selection base5)
+ (builtin orange)
+ (comments (if doom-monokai-classic-brighter-comments violet base5))
+ (doc-comments (if doom-monokai-classic-brighter-comments (doom-lighten violet 0.1) (doom-lighten base5 0.25)))
+ (constants violet)
+ (functions green)
+ (keywords magenta)
+ (methods green)
+ (operators magenta)
+ (type cyan)
+ (strings yellow)
+ (variables fg)
+ (numbers violet)
+ (region base4)
+ (error red)
+ (warning yellow)
+ (success green)
+ (vc-modified cyan)
+ (vc-added (doom-darken green 0.15))
+ (vc-deleted red)
+
+ ;; custom categories
+ (hidden `(,(car bg) "black" "black"))
+ (-modeline-pad
+ (when doom-monokai-classic-padded-modeline
+ (if (integerp doom-monokai-classic-padded-modeline) doom-monokai-classic-padded-modeline 4)))
+
+ (modeline-fg nil)
+ (modeline-fg-alt base4)
+
+ (modeline-bg base1)
+ (modeline-bg-inactive (doom-darken base2 0.2))
+
+ (org-quote `(,(doom-lighten (car bg) 0.05) "#1f1f1f")))
+
+
+ ;;;; Base theme face overrides
+ ((cursor :background magenta)
+ ((font-lock-comment-face &override) :slant 'italic)
+ ((font-lock-type-face &override) :slant 'italic)
+ (lazy-highlight :background violet :foreground base0 :distant-foreground base0 :bold bold)
+ ((line-number &override) :foreground base5 :distant-foreground nil)
+ ((line-number-current-line &override) :foreground base7 :distant-foreground nil)
+ (mode-line
+ :background modeline-bg :foreground modeline-fg
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color modeline-bg)))
+ (mode-line-inactive
+ :background modeline-bg-inactive :foreground modeline-fg-alt
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color modeline-bg-inactive)))
+
+ ;;;; centaur-tabs
+ (centaur-tabs-selected-modified :inherit 'centaur-tabs-selected
+ :background bg
+ :foreground yellow)
+ (centaur-tabs-unselected-modified :inherit 'centaur-tabs-unselected
+ :background bg-alt
+ :foreground yellow)
+ (centaur-tabs-active-bar-face :background yellow)
+ (centaur-tabs-modified-marker-selected :inherit 'centaur-tabs-selected :foreground fg)
+ (centaur-tabs-modified-marker-unselected :inherit 'centaur-tabs-unselected :foreground fg)
+ ;;;; css-mode <built-in> / scss-mode
+ (css-proprietary-property :foreground keywords)
+ ;;;; doom-modeline
+ (doom-modeline-bar :background yellow)
+ (doom-modeline-buffer-file :inherit 'mode-line-buffer-id :weight 'bold)
+ (doom-modeline-buffer-path :inherit 'bold :foreground green)
+ (doom-modeline-buffer-project-root :foreground green :weight 'bold)
+ (doom-modeline-buffer-modified :inherit 'bold :foreground orange)
+
+
+ (isearch :foreground base0 :background green)
+ ;;;; ediff <built-in>
+ (ediff-fine-diff-A :background (doom-blend magenta bg 0.3) :weight 'bold)
+ ;;;; evil
+ (evil-search-highlight-persist-highlight-face :background violet)
+ ;;;; evil-snipe
+ (evil-snipe-first-match-face :foreground base0 :background green)
+ (evil-snipe-matches-face :foreground green :underline t)
+ ;;;; flycheck
+ (flycheck-error :underline `(:style wave :color ,red) :background base3)
+ (flycheck-warning :underline `(:style wave :color ,yellow) :background base3)
+ (flycheck-info :underline `(:style wave :color ,green) :background base3)
+ ;;;; helm
+ (helm-swoop-target-line-face :foreground magenta :inverse-video t)
+ ;;;; ivy
+ (ivy-current-match :background base3)
+ (ivy-minibuffer-match-face-1 :background base1 :foreground base4)
+ ;;;; markdown-mode
+ (markdown-blockquote-face :inherit 'italic :foreground dark-blue)
+ (markdown-list-face :foreground magenta)
+ (markdown-pre-face :foreground cyan)
+ (markdown-link-face :inherit 'bold :foreground blue)
+ ((markdown-code-face &override) :background (doom-lighten base2 0.045))
+ ;;;; neotree
+ (neo-dir-link-face :foreground cyan)
+ (neo-expand-btn-face :foreground magenta)
+ ;;;; outline <built-in>
+ ((outline-1 &override) :foreground magenta)
+ ((outline-2 &override) :foreground orange)
+ ;;;; org <built-in>
+ (org-ellipsis :foreground orange)
+ (org-tag :foreground yellow :bold nil)
+ ((org-quote &override) :inherit 'italic :foreground base7 :background org-quote)
+ (org-todo :foreground yellow :bold 'inherit)
+ (org-list-dt :foreground yellow)
+ ;;;; rainbow-delimiters
+ (rainbow-delimiters-depth-1-face :foreground magenta)
+ (rainbow-delimiters-depth-2-face :foreground orange)
+ (rainbow-delimiters-depth-3-face :foreground green)
+ (rainbow-delimiters-depth-4-face :foreground cyan)
+ (rainbow-delimiters-depth-5-face :foreground magenta)
+ (rainbow-delimiters-depth-6-face :foreground orange)
+ (rainbow-delimiters-depth-7-face :foreground green))
+
+ ;;;; Base theme variable overrides
+ ;; ()
+ )
+
+;;; doom-monokai-classic-theme.el ends here
diff --git a/elpa/doom-themes-20220504.1557/doom-monokai-machine-theme.el b/elpa/doom-themes-20220504.1557/doom-monokai-machine-theme.el
new file mode 100644
index 0000000..8ce03c9
--- /dev/null
+++ b/elpa/doom-themes-20220504.1557/doom-monokai-machine-theme.el
@@ -0,0 +1,304 @@
+;; doom-monokai-machine-theme.el --- Machine filter of Monokai Pro -*- lexical-binding: t; no-byte-compile: t; -*-
+(require 'doom-themes)
+
+;;; Code:
+(defgroup doom-monokai-machine-theme nil
+ "Options for doom-molokai."
+ :group 'doom-themes)
+
+(defcustom doom-monokai-machine-brighter-comments nil
+ "If non-nil, comments will be highlighted in more vivid colors."
+ :group 'doom-monokai-machine-theme
+ :type 'boolean)
+
+(defcustom doom-monokai-machine-comment-bg doom-monokai-machine-brighter-comments
+ "If non-nil, comments will have a subtle, darker background.
+Enhancing their legibility."
+ :group 'doom-monokai-machine-theme
+ :type 'boolean)
+
+(defcustom doom-monokai-machine-padded-modeline doom-themes-padded-modeline
+ "If non-nil, adds a 4px padding to the mode-line.
+Can be an integer to determine the exact padding."
+ :group 'doom-monokai-machine-theme
+ :type '(choice integer boolean))
+
+;;
+(def-doom-theme doom-monokai-machine
+ "A dark, vibrant theme inspired by Textmate's Monokai."
+
+ ;; name gui 256 16
+ ((bg '("#273136" nil nil ))
+ (bg-alt '("#1E2528" nil nil ))
+ (base0 '("#131313" "#121212" "black" ))
+ (base1 '("#161b1e" "#1c1c1c" "black" ))
+ (base2 '("#2e363b" "#262626" "brightblack" ))
+ (base3 '("#3a4449" "#3a3a3a" "brightblack" ))
+ (base4 '("#545f62" "#585858" "brightblack" ))
+ (base5 '("#5a6568" "#585858" "brightblack" ))
+ (base6 '("#6b7678" "#6c6c6c" "brightblack" ))
+ (base7 '("#8b9798" "#8a8a8a" "brightblack" ))
+ (base8 '("#b4c1c0" "#bcbcbc" "white" ))
+ (fg '("#f2fffc" "#ffffff" "brightwhite" ))
+ (fg-alt '("#c6c6c6" "#c6c6c6" "white" ))
+
+ (grey base4)
+ (red '("#ff6d7e" "#ff69bf" "red" ))
+ (orange '("#ffb270" "#ff7f50" "brightred" ))
+ (green '("#a2e57b" "#90ee90" "green" ))
+ (yellow '("#ffed72" "#f0e68c" "yellow" ))
+ (violet '("#baa0f8" "#9370db" "magenta" ))
+ (cyan '("#7cd5f1" "#40e0d0" "brightcyan" ))
+ (magenta cyan)
+ (blue cyan)
+ (dark-blue cyan)
+ (teal cyan)
+ (dark-cyan cyan)
+
+ ;; face categories
+ (highlight yellow)
+ (vertical-bar (doom-lighten bg 0.1))
+ (selection base2)
+ (builtin violet)
+ (comments (if doom-monokai-machine-brighter-comments violet base6))
+ (doc-comments (if doom-monokai-machine-brighter-comments (doom-lighten violet 0.1) (doom-lighten base6 0.25)))
+ (constants violet)
+ (functions green)
+ (keywords magenta)
+ (methods green)
+ (operators red)
+ (type cyan)
+ (strings yellow)
+ (variables fg)
+ (numbers violet)
+ (region base3)
+ (error red)
+ (warning orange)
+ (success green)
+ (vc-modified orange)
+ (vc-added green)
+ (vc-deleted red)
+
+ ;; custom categories
+ (hidden `(,(car bg) "black" "black"))
+ (-modeline-pad
+ (when doom-monokai-machine-padded-modeline
+ (if (integerp doom-monokai-machine-padded-modeline) doom-monokai-machine-padded-modeline 4)))
+
+
+ (org-quote `(,(doom-lighten (car bg) 0.05) "#1f1f1f")))
+
+
+ ;;;; Base theme face overrides
+ ((cursor :background fg)
+ ;; I-search
+ (match :foreground fg :background base3)
+ (isearch :inherit 'match :box `(:line-width 2 :color ,yellow))
+ (lazy-highlight :inherit 'match)
+ (isearch-fail :foreground red)
+ ;; current line
+ (hl-line :background base3)
+ ;; line-numbers
+ ((line-number &override) :foreground base4 :distant-foreground nil)
+ ((line-number-current-line &override) :foreground base7 :distant-foreground nil)
+ ;; mode-line
+ (mode-line :background base3 :foreground fg
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color red)))
+ (mode-line-inactive :background bg :foreground fg
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color red)))
+
+ ;;;; centaur-tabs
+ (centaur-tabs-selected-modified :inherit 'centaur-tabs-selected :foreground yellow)
+ (centaur-tabs-unselected-modified :inherit 'centaur-tabs-unselected :foreground yellow)
+ (centaur-tabs-active-bar-face :background yellow)
+ (centaur-tabs-modified-marker-selected :inherit 'centaur-tabs-selected :foreground fg)
+ (centaur-tabs-modified-marker-unselected :inherit 'centaur-tabs-unselected :foreground fg)
+ ;;;; css-mode <built-in> / scss-mode
+ (css-proprietary-property :foreground keywords)
+ ;;;; deadgrep
+ (deadgrep-match-face :inherit 'match :box `(:line-width 2 :color ,yellow))
+
+ ;;;; doom-modeline
+ (doom-modeline-bar :background yellow)
+ (doom-modeline-buffer-file :inherit 'mode-line-buffer-id :weight 'bold)
+ (doom-modeline-buffer-path :inherit 'bold :foreground green)
+ (doom-modeline-buffer-project-root :foreground green :weight 'bold)
+ (doom-modeline-buffer-modified :inherit 'bold :foreground orange)
+ ;;;; doom-emacs
+ (doom-dashboard-menu-title :foreground yellow)
+ ;;;; ediff <built-in>
+ (ediff-fine-diff-A :background (doom-blend red bg 0.3) :weight 'bold)
+ ;;;; evil
+ (evil-search-highlight-persist-highlight-face :background violet)
+ ;;;; evil-snipe
+ (evil-snipe-first-match-face :foreground base0 :background green)
+ (evil-snipe-matches-face :foreground green :underline t)
+ ;;;; flycheck
+ ((flycheck-error &override) :background base3)
+ ((flycheck-warning &override) :background base3)
+ ((flycheck-info &override) :background base3)
+ ;;;; helm
+ (helm-swoop-target-line-face :foreground red :inverse-video t)
+ ;;;; ivy
+ (ivy-action :foreground violet)
+ (ivy-confirm-face :foreground green)
+ (ivy-current-match :background base3)
+ (ivy-cursor :foreground bg :background fg)
+ (ivy-grep-info :foreground red)
+ (ivy-grep-line-number :foreground red)
+ (ivy-highlight-face :background base3 :foreground fg)
+ (ivy-match-required-face :foreground red)
+ (ivy-minibuffer-match-face-1 :foreground yellow)
+ (ivy-minibuffer-match-face-2 :foreground yellow :weight 'bold)
+ (ivy-minibuffer-match-face-3 :foreground green)
+ (ivy-minibuffer-match-face-4 :foreground green :weight 'bold)
+ (ivy-minibuffer-match-highlight :foreground base6 :background base3)
+ (ivy-modified-buffer :foreground fg)
+ (ivy-modified-outside-buffer :foreground fg)
+ (ivy-org :foreground base3 :italic italic)
+ (ivy-prompt-match :foreground bg :background yellow)
+ (ivy-remote :foreground violet)
+ (ivy-separator :foreground base3)
+ (ivy-subdir :foreground green)
+ (ivy-virtual :foreground violet)
+ (ivy-yanked-word :foreground base6 :background base3)
+ ;;;; lsp-mode
+ (lsp-face-highlight-read :background base3)
+ (lsp-face-highlight-textual :background base3)
+ (lsp-face-highlight-write :background base4)
+ ;;;; lsp-ui
+ ;; HIGHLY recommended: (setq lsp-ui-peek-fontify 'always)
+ (lsp-ui-peek-header :foreground fg :background base5)
+ (lsp-ui-peek-footer :inherit 'lsp-ui-peek-header)
+ (lsp-ui-peek-selection :foreground bg :background yellow)
+ (lsp-ui-peek-list :background base3)
+ (lsp-ui-peek-peek :inherit 'lsp-ui-peek-list)
+ (lsp-ui-peek-highlight :inherit 'isearch)
+ (lsp-ui-peek-filename :foreground base8 :weight 'bold)
+ ;;;; markdown-mode
+ (markdown-blockquote-face :inherit 'italic :foreground dark-blue)
+ (markdown-list-face :foreground red)
+ (markdown-pre-face :foreground cyan)
+ (markdown-link-face :inherit 'bold :foreground blue)
+ ((markdown-code-face &override) :background (doom-lighten base2 0.045))
+ ;;;; neotree
+ (neo-dir-link-face :foreground cyan)
+ (neo-expand-btn-face :foreground red)
+ ;;;; outline <built-in>
+ ((outline-1 &override) :foreground yellow)
+ ((outline-2 &override) :foreground blue)
+ ((outline-3 &override) :foreground green)
+ ((outline-4 &override) :foreground fg)
+ (outline-5 :inherit 'outline-4)
+ (outline-6 :inherit 'outline-5)
+ (outline-7 :inherit 'outline-6)
+ (outline-8 :inherit 'outline-7)
+ ;;;; org <built-in>
+ (org-ellipsis :foreground orange)
+ (org-tag :foreground yellow :weight 'normal)
+ ((org-quote &override) :inherit 'italic :foreground base7 :background org-quote)
+ (org-todo :foreground yellow)
+ (org-list-dt :foreground yellow)
+ ;;;;;; php-mode
+ (php-php-tag :foreground orange)
+ (php-function-name :foreground green)
+ (php-function-call :foreground green)
+ (php-string :foreground yellow)
+ (php-keyword :foreground blue)
+ (php-builtin :foreground violet)
+ (php-method-call :foreground green)
+ (php-static-method-call :foreground green)
+ (php-variable-name :foreground fg)
+ (php-property-name :foreground fg)
+ (php-variable-sigil :foreground base8)
+ (php-operator :foreground red)
+ (php-paamayim-nekudotayim :foreground red)
+ (php-type :foreground blue :italic italic)
+ (php-class :foreground red)
+ (php-constant :foreground violet)
+ (php-constant-assign :foreground blue)
+ (php-magical-constant :foreground violet)
+ (php-$this :foreground base8 :italic italic)
+ (php-$this-sigil :foreground base8 :italic italic)
+ (php-errorcontrol-op :foreground red)
+ (php-doc-annotation-tag :foreground blue)
+ (php-doc-variable-sigil :foreground base6)
+ (php-doc-$this :foreground base6)
+ (php-doc-$this-sigil :foreground base6)
+ (php-doc-class-name :foreground base6)
+ ;; As soon as https://github.com/emacs-php/php-mode/pull/606
+ ;; is merged these can be uncommented.
+ ;;(php-class-declaration-spec :foreground red)
+ ;;(php-class-modifier :foreground red)
+ ;;(php-namespace-declaration :foreground red)
+ ;;(php-import-declaration :foreground red)
+ ;;(php-method-modifier :foreground red :italic italic)
+ ;;(php-method-access :foreground red :italic italic)
+ ;;(php-method-static :foreground red :italic italic)
+ ;;(php-property-access :foreground red :italic italic)
+ ;;(php-property-const :foreground red :italic italic)
+ ;;(php-property-static :foreground red :italic italic)
+ ;;(php-block-delimiter :foreground base7)
+ ;;(php-flow-control-statement :foreground red)
+ ;;(php-block-statement :foreground red)
+ ;;(php-include-statement :foreground green)
+ ;;(php-constant-keyword :foreground violet)
+ ;;(php-number :foreground violet)
+ ;;(php-string-quote :foreground base7)
+ ;;(php-type-operator :foreground red)
+ ;;(php-print-statement :foreground green)
+ ;;(php-return-type-colon :foreground red)
+ ;;(php-function-keyword :foreground blue :italic italic)
+ ;;;; rainbow-delimiters
+ (rainbow-delimiters-depth-1-face :foreground red)
+ (rainbow-delimiters-depth-2-face :foreground orange)
+ (rainbow-delimiters-depth-3-face :foreground green)
+ (rainbow-delimiters-depth-4-face :foreground cyan)
+ (rainbow-delimiters-depth-5-face :foreground red)
+ (rainbow-delimiters-depth-6-face :foreground orange)
+ (rainbow-delimiters-depth-7-face :foreground green)
+ ;;;; show-paren-mode
+ (show-paren-match :weight 'bold :foreground green)
+ (show-paren-mismatch :weight 'bold :foreground red)
+ ;;;; swiper
+ (swiper-background-match-face-1 :inherit 'match :weight 'bold)
+ (swiper-background-match-face-2 :inherit 'match)
+ (swiper-background-match-face-3 :inherit 'match :foreground green)
+ (swiper-background-match-face-4 :inherit 'match :weight 'bold :foreground green)
+ (swiper-match-face-1 :inherit 'isearch :weight 'bold)
+ (swiper-match-face-2 :inherit 'isearch)
+ (swiper-match-face-3 :inherit 'isearch :foreground green)
+ (swiper-match-face-4 :inherit 'isearch :weight 'bold :foreground green)
+ (swiper-line-face :inherit 'hl-line)
+ ;;;; term <built-in>
+ (term-color-black :foreground base3)
+ (term-color-blue :foreground blue)
+ (term-color-cyan :foreground violet)
+ (term-color-green :foreground green)
+ (term-color-magenta :foreground red)
+ (term-color-red :foreground red)
+ (term-color-white :foreground fg)
+ (term-color-yellow :foreground yellow)
+ ;;;; treemacs
+ (treemacs-git-added-face :foreground green)
+ (treemacs-git-conflict-face :foreground red)
+ (treemacs-git-ignored-face :foreground base6)
+ (treemacs-git-modified-face :foreground violet)
+ (treemacs-git-renamed-face :foreground orange)
+ (treemacs-git-untracked-face :inherit 'treemacs-git-renamed-face)
+ (treemacs-on-failure-pulse-face :foreground base0 :background red)
+ (treemacs-on-success-pulse-face :foreground base0 :background green)
+ ;;;; web-mode
+ (web-mode-html-tag-face :foreground red)
+ (web-mode-html-tag-bracket-face :foreground base7)
+ (web-mode-html-attr-name-face :foreground cyan :italic italic)
+ (web-mode-html-attr-equal-face :inherit 'web-mode-html-tag-bracket-face)
+ ;; Apparently web-mode has no face for values of css properties.
+ (web-mode-css-selector-face :foreground green)
+ (web-mode-css-property-name-face :foreground base7))
+
+ ;;;; Base theme variable overrides
+ ;; ()
+ )
+
+;;; doom-monokai-machine-theme.el ends here
diff --git a/elpa/doom-themes-20220504.1557/doom-monokai-octagon-theme.el b/elpa/doom-themes-20220504.1557/doom-monokai-octagon-theme.el
new file mode 100644
index 0000000..3f936c1
--- /dev/null
+++ b/elpa/doom-themes-20220504.1557/doom-monokai-octagon-theme.el
@@ -0,0 +1,304 @@
+;; doom-monokai-octagon-theme.el --- Octagon filter of Monokai Pro -*- lexical-binding: t; no-byte-compile: t; -*-
+(require 'doom-themes)
+
+;;; Code:
+(defgroup doom-monokai-octagon-theme nil
+ "Options for doom-molokai."
+ :group 'doom-themes)
+
+(defcustom doom-monokai-octagon-brighter-comments nil
+ "If non-nil, comments will be highlighted in more vivid colors."
+ :group 'doom-monokai-octagon-theme
+ :type 'boolean)
+
+(defcustom doom-monokai-octagon-comment-bg doom-monokai-octagon-brighter-comments
+ "If non-nil, comments will have a subtle, darker background.
+Enhancing their legibility."
+ :group 'doom-monokai-octagon-theme
+ :type 'boolean)
+
+(defcustom doom-monokai-octagon-padded-modeline doom-themes-padded-modeline
+ "If non-nil, adds a 4px padding to the mode-line.
+Can be an integer to determine the exact padding."
+ :group 'doom-monokai-octagon-theme
+ :type '(choice integer boolean))
+
+;;
+(def-doom-theme doom-monokai-octagon
+ "A dark, vibrant theme inspired by Textmate's Monokai."
+
+ ;; name gui 256 16
+ ((bg '("#282a3a" nil nil ))
+ (bg-alt '("#1E1F2B" nil nil ))
+ (base0 '("#131313" "#121212" "black" ))
+ (base1 '("#161821" "#1c1c1c" "black" ))
+ (base2 '("#2e313d" "#262626" "brightblack" ))
+ (base3 '("#3a3d4b" "#3a3a3a" "brightblack" ))
+ (base4 '("#535763" "#585858" "brightblack" ))
+ (base5 '("#595d68" "#585858" "brightblack" ))
+ (base6 '("#696d77" "#6c6c6c" "brightblack" ))
+ (base7 '("#888d94" "#8a8a8a" "brightblack" ))
+ (base8 '("#afb5b9" "#bcbcbc" "white" ))
+ (fg '("#eaf2f1" "#ffffff" "brightwhite" ))
+ (fg-alt '("#c6c6c6" "#c6c6c6" "white" ))
+
+ (grey base4)
+ (red '("#ff657a" "#ff69bf" "red" ))
+ (orange '("#ff95be" "#ff7f50" "brightred" ))
+ (green '("#bad761" "#90ee90" "green" ))
+ (yellow '("#ffd76d" "#f0e68c" "yellow" ))
+ (violet '("#c39ac9" "#9370db" "magenta" ))
+ (cyan '("#9cd1bb" "#40e0d0" "brightcyan" ))
+ (magenta cyan)
+ (blue cyan)
+ (dark-blue cyan)
+ (teal cyan)
+ (dark-cyan cyan)
+
+ ;; face categories
+ (highlight yellow)
+ (vertical-bar (doom-lighten bg 0.1))
+ (selection base2)
+ (builtin violet)
+ (comments (if doom-monokai-octagon-brighter-comments violet base6))
+ (doc-comments (if doom-monokai-octagon-brighter-comments (doom-lighten violet 0.1) (doom-lighten base6 0.25)))
+ (constants violet)
+ (functions green)
+ (keywords magenta)
+ (methods green)
+ (operators red)
+ (type cyan)
+ (strings yellow)
+ (variables fg)
+ (numbers violet)
+ (region base3)
+ (error red)
+ (warning orange)
+ (success green)
+ (vc-modified orange)
+ (vc-added green)
+ (vc-deleted red)
+
+ ;; custom categories
+ (hidden `(,(car bg) "black" "black"))
+ (-modeline-pad
+ (when doom-monokai-octagon-padded-modeline
+ (if (integerp doom-monokai-octagon-padded-modeline) doom-monokai-octagon-padded-modeline 4)))
+
+
+ (org-quote `(,(doom-lighten (car bg) 0.05) "#1f1f1f")))
+
+
+ ;;;; Base theme face overrides
+ ((cursor :background fg)
+ ;; I-search
+ (match :foreground fg :background base3)
+ (isearch :inherit 'match :box `(:line-width 2 :color ,yellow))
+ (lazy-highlight :inherit 'match)
+ (isearch-fail :foreground red)
+ ;; current line
+ (hl-line :background base3)
+ ;; line-numbers
+ ((line-number &override) :foreground base4 :distant-foreground nil)
+ ((line-number-current-line &override) :foreground base7 :distant-foreground nil)
+ ;; mode-line
+ (mode-line :background base3 :foreground fg
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color red)))
+ (mode-line-inactive :background bg :foreground fg
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color red)))
+ ;;;; centaur-tabs
+ (centaur-tabs-selected-modified :inherit 'centaur-tabs-selected :foreground yellow)
+ (centaur-tabs-unselected-modified :inherit 'centaur-tabs-unselected :foreground yellow)
+ (centaur-tabs-active-bar-face :background yellow)
+ (centaur-tabs-modified-marker-selected :inherit 'centaur-tabs-selected :foreground fg)
+ (centaur-tabs-modified-marker-unselected :inherit 'centaur-tabs-unselected :foreground fg)
+ ;;;; css-mode <built-in> / scss-mode
+ (css-proprietary-property :foreground keywords)
+ ;;;; deadgrep
+ (deadgrep-match-face :inherit 'match :box `(:line-width 2 :color ,yellow))
+ ;;;; doom-emacs
+ (doom-dashboard-menu-title :foreground yellow)
+ ;;;; doom-modeline
+ (doom-modeline-bar :background yellow)
+ (doom-modeline-buffer-file :inherit 'mode-line-buffer-id :weight 'bold)
+ (doom-modeline-buffer-path :inherit 'bold :foreground green)
+ (doom-modeline-buffer-project-root :foreground green :weight 'bold)
+ (doom-modeline-buffer-modified :inherit 'bold :foreground orange)
+ ;;;; ediff <built-in>
+ (ediff-fine-diff-A :background (doom-blend red bg 0.3) :bold 'bold)
+ ;;;; evil
+ (evil-search-highlight-persist-highlight-face :background violet)
+ ;;;; evil-snipe
+ (evil-snipe-first-match-face :foreground base0 :background green)
+ (evil-snipe-matches-face :foreground green :underline t)
+ ;;;; flycheck
+ ((flycheck-error &override) :background base3)
+ ((flycheck-warning &override) :background base3)
+ ((flycheck-info &override) :background base3)
+ ;;;; helm
+ (helm-swoop-target-line-face :foreground red :inverse-video t)
+ ;;;; ivy
+ (ivy-action :foreground violet)
+ (ivy-confirm-face :foreground green)
+ (ivy-current-match :background base3)
+ (ivy-cursor :foreground bg :background fg)
+ (ivy-grep-info :foreground red)
+ (ivy-grep-line-number :foreground red)
+ (ivy-highlight-face :background base3 :foreground fg)
+ (ivy-match-required-face :foreground red)
+ (ivy-minibuffer-match-face-1 :background base2 :foreground base4)
+ (ivy-minibuffer-match-face-2 :foreground yellow :bold bold)
+ (ivy-minibuffer-match-face-3 :foreground green)
+ (ivy-minibuffer-match-face-4 :foreground green :bold bold)
+ (ivy-minibuffer-match-highlight :foreground base6 :background base3)
+ (ivy-modified-buffer :foreground fg)
+ (ivy-modified-outside-buffer :foreground fg)
+ (ivy-org :foreground base3 :italic italic)
+ (ivy-prompt-match :foreground bg :background yellow)
+ (ivy-remote :foreground violet)
+ (ivy-separator :foreground base3)
+ (ivy-subdir :foreground green)
+ (ivy-virtual :foreground violet)
+ (ivy-yanked-word :foreground base6 :background base3)
+ ;;;; lsp-mode
+ (lsp-face-highlight-read :background base3)
+ (lsp-face-highlight-textual :background base3)
+ (lsp-face-highlight-write :background base4)
+ ;;;; lsp-ui
+ ;; HIGHLY recommended: (setq lsp-ui-peek-fontify 'always)
+ (lsp-ui-peek-header :foreground fg :background base5)
+ (lsp-ui-peek-footer :inherit 'lsp-ui-peek-header)
+ (lsp-ui-peek-selection :foreground bg :background yellow)
+ (lsp-ui-peek-list :background base3)
+ (lsp-ui-peek-peek :inherit 'lsp-ui-peek-list)
+ (lsp-ui-peek-highlight :inherit 'isearch)
+ (lsp-ui-peek-filename :foreground base8 :bold bold)
+ ;;;; markdown-mode
+ (markdown-blockquote-face :inherit 'italic :foreground dark-blue)
+ (markdown-list-face :foreground red)
+ (markdown-pre-face :foreground cyan)
+ (markdown-link-face :inherit 'bold :foreground blue)
+ ((markdown-code-face &override) :background (doom-lighten base2 0.045))
+ ;;;; neotree
+ (neo-dir-link-face :foreground cyan)
+ (neo-expand-btn-face :foreground red)
+ ;;;; outline <built-in>
+ ((outline-1 &override) :foreground yellow)
+ ((outline-2 &override) :foreground blue)
+ ((outline-3 &override) :foreground green)
+ ((outline-4 &override) :foreground fg)
+ ((outline-5 &override) :inherit 'outline-4)
+ ((outline-6 &override) :inherit 'outline-5)
+ ((outline-7 &override) :inherit 'outline-6)
+ ((outline-8 &override) :inherit 'outline-7)
+ ;;;; org <built-in>
+ (org-ellipsis :foreground orange)
+ (org-tag :foreground yellow :bold nil)
+ ((org-quote &override) :inherit 'italic :foreground base7 :background org-quote)
+ (org-todo :foreground yellow :bold 'inherit)
+ (org-list-dt :foreground yellow)
+ ;;;;;; php-mode
+ (php-php-tag :foreground orange)
+ (php-function-name :foreground green)
+ (php-function-call :foreground green)
+ (php-string :foreground yellow)
+ (php-keyword :foreground blue)
+ (php-builtin :foreground violet)
+ (php-method-call :foreground green)
+ (php-static-method-call :foreground green)
+ (php-variable-name :foreground fg)
+ (php-property-name :foreground fg)
+ (php-variable-sigil :foreground base8)
+ (php-operator :foreground red)
+ (php-paamayim-nekudotayim :foreground red)
+ (php-type :foreground blue :italic italic)
+ (php-class :foreground red)
+ (php-constant :foreground violet)
+ (php-constant-assign :foreground blue)
+ (php-magical-constant :foreground violet)
+ (php-$this :foreground base8 :italic italic)
+ (php-$this-sigil :foreground base8 :italic italic)
+ (php-errorcontrol-op :foreground red)
+ (php-doc-annotation-tag :foreground blue)
+ (php-doc-variable-sigil :foreground base6)
+ (php-doc-$this :foreground base6)
+ (php-doc-$this-sigil :foreground base6)
+ (php-doc-class-name :foreground base6)
+ ;; As soon as https://github.com/emacs-php/php-mode/pull/606
+ ;; is merged these can be uncommented.
+ ;;(php-class-declaration-spec :foreground red)
+ ;;(php-class-modifier :foreground red)
+ ;;(php-namespace-declaration :foreground red)
+ ;;(php-import-declaration :foreground red)
+ ;;(php-method-modifier :foreground red :italic italic)
+ ;;(php-method-access :foreground red :italic italic)
+ ;;(php-method-static :foreground red :italic italic)
+ ;;(php-property-access :foreground red :italic italic)
+ ;;(php-property-const :foreground red :italic italic)
+ ;;(php-property-static :foreground red :italic italic)
+ ;;(php-block-delimiter :foreground base7)
+ ;;(php-flow-control-statement :foreground red)
+ ;;(php-block-statement :foreground red)
+ ;;(php-include-statement :foreground green)
+ ;;(php-constant-keyword :foreground violet)
+ ;;(php-number :foreground violet)
+ ;;(php-string-quote :foreground base7)
+ ;;(php-type-operator :foreground red)
+ ;;(php-print-statement :foreground green)
+ ;;(php-return-type-colon :foreground red)
+ ;;(php-function-keyword :foreground blue :italic italic)
+ ;;;; rainbow-delimiters
+ (rainbow-delimiters-depth-1-face :foreground red)
+ (rainbow-delimiters-depth-2-face :foreground orange)
+ (rainbow-delimiters-depth-3-face :foreground green)
+ (rainbow-delimiters-depth-4-face :foreground cyan)
+ (rainbow-delimiters-depth-5-face :foreground red)
+ (rainbow-delimiters-depth-6-face :foreground orange)
+ (rainbow-delimiters-depth-7-face :foreground green)
+ ;;;; show-paren-mode
+ (show-paren-match :bold bold :foreground green)
+ (show-paren-mismatch :bold bold :foreground red)
+ ;;;; swiper
+ (swiper-background-match-face-1 :inherit 'match :bold bold)
+ (swiper-background-match-face-2 :inherit 'match)
+ (swiper-background-match-face-3 :inherit 'match :foreground green)
+ (swiper-background-match-face-4 :inherit 'match :bold bold :foreground green)
+ (swiper-match-face-1 :inherit 'isearch :bold bold)
+ (swiper-match-face-2 :inherit 'isearch)
+ (swiper-match-face-3 :inherit 'isearch :foreground green)
+ (swiper-match-face-4 :inherit 'isearch :bold bold :foreground green)
+ (swiper-line-face :inherit 'hl-line)
+ ;;;; term <built-in>
+ (term-color-black :foreground base3)
+ (term-color-blue :foreground blue)
+ (term-color-cyan :foreground violet)
+ (term-color-green :foreground green)
+ (term-color-magenta :foreground red)
+ (term-color-red :foreground red)
+ (term-color-white :foreground fg)
+ (term-color-yellow :foreground yellow)
+ ;;;; treemacs
+ (treemacs-git-added-face :foreground green)
+ (treemacs-git-conflict-face :foreground red)
+ (treemacs-git-ignored-face :foreground base6)
+ (treemacs-git-modified-face :foreground violet)
+ (treemacs-git-renamed-face :foreground orange)
+ (treemacs-git-untracked-face :inherit 'treemacs-git-renamed-face)
+ (treemacs-on-failure-pulse-face :foreground base0 :background red)
+ (treemacs-on-success-pulse-face :foreground base0 :background green)
+ ;;;; web-mode
+ ;; html
+ (web-mode-html-tag-face :foreground red)
+ (web-mode-html-tag-bracket-face :foreground base7)
+ (web-mode-html-attr-name-face :foreground cyan :italic italic)
+ (web-mode-html-attr-equal-face :inherit 'web-mode-html-tag-bracket-face)
+ ;; css
+ ;; Apparently web-mode has no face for values of css properties.
+ (web-mode-css-selector-face :foreground green)
+ (web-mode-css-property-name-face :foreground base7))
+
+ ;;;; Base theme variable overrides
+ ;; ()
+ )
+
+;;; doom-monokai-octagon-theme.el ends here
diff --git a/elpa/doom-themes-20220504.1557/doom-monokai-pro-theme.el b/elpa/doom-themes-20220504.1557/doom-monokai-pro-theme.el
new file mode 100644
index 0000000..68b0547
--- /dev/null
+++ b/elpa/doom-themes-20220504.1557/doom-monokai-pro-theme.el
@@ -0,0 +1,146 @@
+;; doom-monokai-pro-theme.el --- Port of Monokai Pro -*- lexical-binding: t; no-byte-compile: t; -*-
+(require 'doom-themes)
+
+(defgroup doom-monokai-pro-theme nil
+ "Options for the `doom-monokai-pro' theme."
+ :group 'doom-themes)
+
+(defcustom doom-monokai-pro-padded-modeline doom-themes-padded-modeline
+ "If non-nil, adds a 4px padding to the mode-line.
+Can be an integer to determine the exact padding."
+ :group 'doom-monokai-pro-theme
+ :type '(choice integer boolean))
+
+(def-doom-theme doom-monokai-pro
+ "A port of VS Code's Monokai Pro"
+
+ ;; name gui 256 16
+ ((bg '("#2D2A2E" nil nil ))
+ (bg-alt '("#221F22" nil nil ))
+ (base0 '("#19181A" "black" "black" ))
+ (base1 '("#1B1B1B" "#1B1B1B" ))
+ (base2 '("#212122" "#212122" ))
+ (base3 '("#2B2B2B" "#2B2B2B" "brightblack"))
+ (base4 '("#383539" "#3F4040" "brightblack"))
+ (base5 '("#4C4A4D" "#5C5E5E" "brightblack"))
+ (base6 '("#727072" "#757878" "brightblack"))
+ (base7 '("#c1c0c0" "#969896" "brightblack"))
+ (base8 '("#FCFCFA" "#FCFCFA" "white" ))
+ (fg '("#FCFCFA" "#939293" "white"))
+ (fg-alt '("#939293" "#A3A2A3" "white"))
+
+ (grey '("#727072" "#727072" "brightblack"))
+ (red '("#CC6666" "#CC6666" "red"))
+ (orange '("#FC9867" "#FC9867" "orange"))
+ (green '("#A9DC76" "#A9DC76" "green"))
+ (teal green)
+ (yellow '("#FFD866" "#FFD866" "yellow"))
+ (blue '("#78DCE8" "#78DCE8" "blue"))
+ (dark-blue '("#81A2BE" "#81A2BE" "blue"))
+ (magenta '("#FF6188" "#FF6188" "violet"))
+ (violet '("#AB9DF2" "#AB9DF2" "violet"))
+ (cyan blue)
+ (dark-cyan dark-blue)
+
+ ;; face categories
+ (highlight base8)
+ (vertical-bar (doom-lighten bg 0.1))
+ (selection base5)
+ (builtin blue)
+ (comments grey)
+ (doc-comments yellow)
+ (constants violet)
+ (functions green)
+ (keywords magenta)
+ (methods green)
+ (operators magenta)
+ (type blue)
+ (strings yellow)
+ (variables base8)
+ (numbers violet)
+ (region selection)
+ (error red)
+ (warning yellow)
+ (success green)
+ (vc-modified fg-alt)
+ (vc-added green)
+ (vc-deleted red)
+
+ ;; custom categories
+ (modeline-bg bg-alt)
+ (modeline-bg-alt `(,(car bg) ,@(cdr base1)))
+ (modeline-fg fg-alt)
+ (modeline-fg-alt comments)
+ (-modeline-pad
+ (when doom-monokai-pro-padded-modeline
+ (if (integerp doom-monokai-pro-padded-modeline)
+ doom-monokai-pro-padded-modeline
+ 4))))
+
+ ;; --- faces ------------------------------
+ (
+ ;; I-search
+ (match :foreground fg :background base3)
+ (isearch :inherit 'match :box `(:line-width 2 :color ,yellow))
+ (lazy-highlight :inherit 'match)
+ (isearch-fail :foreground red)
+
+ ;;;; deadgrep
+ (deadgrep-match-face :inherit 'match :box `(:line-width 2 :color ,yellow))
+
+ ;;;; swiper
+ (swiper-background-match-face-1 :inherit 'match :bold bold)
+ (swiper-background-match-face-2 :inherit 'match)
+ (swiper-background-match-face-3 :inherit 'match :foreground green)
+ (swiper-background-match-face-4 :inherit 'match :bold bold :foreground green)
+ (swiper-match-face-1 :inherit 'isearch :bold bold)
+ (swiper-match-face-2 :inherit 'isearch)
+ (swiper-match-face-3 :inherit 'isearch :foreground green)
+ (swiper-match-face-4 :inherit 'isearch :bold bold :foreground green)
+ (swiper-line-face :inherit 'hl-line)
+
+ ;;;; centaur-tabs
+ (centaur-tabs-selected :foreground yellow :background bg)
+ (centaur-tabs-unselected :foreground fg-alt :background bg-alt)
+ (centaur-tabs-selected-modified :foreground yellow :background bg)
+ (centaur-tabs-unselected-modified :foreground fg-alt :background bg-alt)
+ (centaur-tabs-active-bar-face :background yellow)
+ (centaur-tabs-modified-marker-selected :inherit 'centaur-tabs-selected :foreground base8)
+ (centaur-tabs-modified-marker-unselected :inherit 'centaur-tabs-unselected :foreground base8)
+
+ ;;;; doom-modeline
+ (doom-modeline-bar :background yellow)
+ (doom-modeline-buffer-path :foreground blue :bold bold)
+ (doom-modeline-buffer-major-mode :inherit 'doom-modeline-buffer-path)
+
+ ((line-number &override) :foreground base4)
+ ((line-number-current-line &override) :foreground yellow :bold bold)
+
+ ;;;; rainbow-delimiters
+ (rainbow-delimiters-depth-1-face :foreground violet)
+ (rainbow-delimiters-depth-2-face :foreground blue)
+ (rainbow-delimiters-depth-3-face :foreground orange)
+ (rainbow-delimiters-depth-4-face :foreground green)
+ (rainbow-delimiters-depth-5-face :foreground violet)
+ (rainbow-delimiters-depth-6-face :foreground yellow)
+ (rainbow-delimiters-depth-7-face :foreground blue)
+
+ (mode-line
+ :background modeline-bg :foreground modeline-fg
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg)))
+ (mode-line-inactive
+ :background modeline-bg-alt :foreground modeline-fg-alt
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-alt)))
+
+ ;;;; treemacs
+ (treemacs-file-face :foreground fg-alt)
+
+ ;; tooltip
+ (tooltip :background base2 :foreground fg-alt))
+
+ ;; --- variables --------------------------
+ ;; ()
+ )
+
+(provide 'doom-monokai-pro-theme)
+;;; doom-monokai-pro-theme.el ends here
diff --git a/elpa/doom-themes-20220504.1557/doom-monokai-ristretto-theme.el b/elpa/doom-themes-20220504.1557/doom-monokai-ristretto-theme.el
new file mode 100644
index 0000000..6ce089c
--- /dev/null
+++ b/elpa/doom-themes-20220504.1557/doom-monokai-ristretto-theme.el
@@ -0,0 +1,308 @@
+;; doom-monokai-ristretto-theme.el --- Ristretto filter of Monokai Pro -*- lexical-binding: t; no-byte-compile: t; -*-
+(require 'doom-themes)
+
+;;; Code:
+(defgroup doom-monokai-ristretto-theme nil
+ "Options for doom-molokai."
+ :group 'doom-themes)
+
+(defcustom doom-monokai-ristretto-brighter-comments nil
+ "If non-nil, comments will be highlighted in more vivid colors."
+ :group 'doom-monokai-ristretto-theme
+ :type 'boolean)
+
+(defcustom doom-monokai-ristretto-comment-bg doom-monokai-ristretto-brighter-comments
+ "If non-nil, comments will have a subtle, darker background.
+Enhancing their legibility."
+ :group 'doom-monokai-ristretto-theme
+ :type 'boolean)
+
+(defcustom doom-monokai-ristretto-padded-modeline doom-themes-padded-modeline
+ "If non-nil, adds a 4px padding to the mode-line.
+Can be an integer to determine the exact padding."
+ :group 'doom-monokai-ristretto-theme
+ :type '(choice integer boolean))
+
+;;
+(def-doom-theme doom-monokai-ristretto
+ "A dark, vibrant theme inspired by Textmate's Monokai."
+
+ ;; name gui 256 16
+ ((bg '("#2c2525" nil nil ))
+ (bg-alt '("#201C1C" nil nil ))
+ (base0 '("#131313" "#121212" "black" ))
+ (base1 '("#191515" "#1c1c1c" "black" ))
+ (base2 '("#332c2c" "#262626" "brightblack" ))
+ (base3 '("#403838" "#3a3a3a" "brightblack" ))
+ (base4 '("#5b5353" "#585858" "brightblack" ))
+ (base5 '("#615959" "#585858" "brightblack" ))
+ (base6 '("#72696a" "#6c6c6c" "brightblack" ))
+ (base7 '("#948a8b" "#8a8a8a" "brightblack" ))
+ (base8 '("#bfb3b5" "#bcbcbc" "white" ))
+ (fg '("#fff1f3" "#ffffff" "brightwhite" ))
+ (fg-alt '("#c6c6c6" "#c6c6c6" "white" ))
+
+ (grey base4)
+ (red '("#fd6883" "#ff69bf" "red" ))
+ (orange '("#f38d70" "#ff7f50" "brightred" ))
+ (green '("#adda78" "#90ee90" "green" ))
+ (yellow '("#f9cc6c" "#f0e68c" "yellow" ))
+ (violet '("#a8a9eb" "#9370db" "magenta" ))
+ (cyan '("#85dacc" "#40e0d0" "brightcyan" ))
+ (magenta cyan)
+ (blue cyan)
+ (dark-blue cyan)
+ (teal cyan)
+ (dark-cyan cyan)
+
+ ;; face categories
+ (highlight yellow)
+ (vertical-bar (doom-lighten bg 0.1))
+ (selection base2)
+ (builtin violet)
+ (comments (if doom-monokai-ristretto-brighter-comments violet base6))
+ (doc-comments (if doom-monokai-ristretto-brighter-comments (doom-lighten violet 0.1) (doom-lighten base6 0.25)))
+ (constants violet)
+ (functions green)
+ (keywords magenta)
+ (methods green)
+ (operators red)
+ (type cyan)
+ (strings yellow)
+ (variables fg)
+ (numbers violet)
+ (region base3)
+ (error red)
+ (warning orange)
+ (success green)
+ (vc-modified orange)
+ (vc-added green)
+ (vc-deleted red)
+
+ ;; custom categories
+ (hidden `(,(car bg) "black" "black"))
+ (-modeline-pad
+ (when doom-monokai-ristretto-padded-modeline
+ (if (integerp doom-monokai-ristretto-padded-modeline) doom-monokai-ristretto-padded-modeline 4)))
+
+
+ (org-quote `(,(doom-lighten (car bg) 0.05) "#1f1f1f")))
+
+
+ ;;;; Base theme face overrides
+ ((cursor :background fg)
+ ;; I-search
+ (match :foreground fg :background base3)
+ (isearch :inherit 'match :box `(:line-width 2 :color ,yellow))
+ (lazy-highlight :inherit 'match)
+ (isearch-fail :foreground red)
+ ;; current line
+ (hl-line :background base3)
+ ;; line-numbers
+ ((line-number &override) :foreground base4 :distant-foreground nil)
+ ((line-number-current-line &override) :foreground base7 :distant-foreground nil)
+ ;; mode-line
+ (mode-line :background base3 :foreground fg
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color red)))
+ (mode-line-inactive :background bg :foreground fg
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color red)))
+
+ ;;;; centaur-tabs
+ (centaur-tabs-selected-modified :inherit 'centaur-tabs-selected :foreground yellow)
+ (centaur-tabs-unselected-modified :inherit 'centaur-tabs-unselected :foreground yellow)
+ (centaur-tabs-active-bar-face :background yellow)
+ (centaur-tabs-modified-marker-selected :inherit 'centaur-tabs-selected :foreground fg)
+ (centaur-tabs-modified-marker-unselected :inherit 'centaur-tabs-unselected :foreground fg)
+ ;;;; css-mode <built-in> / scss-mode
+ (css-proprietary-property :foreground keywords)
+ ;;;; deadgrep
+ (deadgrep-match-face :inherit 'match :box `(:line-width 2 :color ,yellow))
+ ;;;; doom-modeline
+ (doom-modeline-bar :background yellow)
+ (doom-modeline-buffer-file :inherit 'mode-line-buffer-id :weight 'bold)
+ (doom-modeline-buffer-path :inherit 'bold :foreground green)
+ (doom-modeline-buffer-project-root :foreground green :weight 'bold)
+ (doom-modeline-buffer-modified :inherit 'bold :foreground orange)
+ ;;;; ivy
+ (ivy-action :foreground violet)
+ (ivy-confirm-face :foreground green)
+ (ivy-current-match :foreground bg :background yellow)
+ (ivy-cursor :foreground bg :background fg)
+ (ivy-grep-info :foreground red)
+ (ivy-grep-line-number :foreground red)
+ (ivy-highlight-face :background base3 :foreground fg)
+ (ivy-match-required-face :foreground red)
+ (ivy-minibuffer-match-face-1 :foreground yellow)
+ (ivy-minibuffer-match-face-2 :foreground yellow :bold bold)
+ (ivy-minibuffer-match-face-3 :foreground green)
+ (ivy-minibuffer-match-face-4 :foreground green :bold bold)
+ (ivy-minibuffer-match-highlight :foreground base6 :background base3)
+ (ivy-modified-buffer :foreground fg)
+ (ivy-modified-outside-buffer :foreground fg)
+ (ivy-org :foreground base3 :italic italic)
+ (ivy-prompt-match :foreground bg :background yellow)
+ (ivy-remote :foreground violet)
+ (ivy-separator :foreground base3)
+ (ivy-subdir :foreground green)
+ (ivy-virtual :foreground violet)
+ (ivy-yanked-word :foreground base6 :background base3)
+ ;;;; doom-emacs
+ (doom-dashboard-menu-title :foreground yellow)
+ ;;;; ediff <built-in>
+ (ediff-fine-diff-A :background (doom-blend red bg 0.3) :bold 'bold)
+ ;;;; evil
+ (evil-search-highlight-persist-highlight-face :background violet)
+ ;;;; evil-snipe
+ (evil-snipe-first-match-face :foreground base0 :background green)
+ (evil-snipe-matches-face :foreground green :underline t)
+ ;;;; flycheck
+ ((flycheck-error &override) :background base3)
+ ((flycheck-warning &override) :background base3)
+ ((flycheck-info &override) :background base3)
+ ;;;; helm
+ (helm-swoop-target-line-face :foreground red :inverse-video t)
+ ;;;; ivy
+ (ivy-current-match :background base3)
+ (ivy-minibuffer-match-face-1 :background base2 :foreground base4)
+ ;;;; lsp-mode
+ (lsp-face-highlight-read :background base3)
+ (lsp-face-highlight-textual :background base3)
+ (lsp-face-highlight-write :background base4)
+ ;;;; lsp-ui
+ ;; HIGHLY recommended: (setq lsp-ui-peek-fontify 'always)
+ (lsp-ui-peek-header :foreground fg :background base5)
+ (lsp-ui-peek-footer :inherit 'lsp-ui-peek-header)
+ (lsp-ui-peek-selection :foreground bg :background yellow)
+ (lsp-ui-peek-list :background base3)
+ (lsp-ui-peek-peek :inherit 'lsp-ui-peek-list)
+ (lsp-ui-peek-highlight :inherit 'isearch)
+ (lsp-ui-peek-filename :foreground base8 :bold bold)
+ ;;;; markdown-mode
+ (markdown-blockquote-face :inherit 'italic :foreground dark-blue)
+ (markdown-list-face :foreground red)
+ (markdown-pre-face :foreground cyan)
+ (markdown-link-face :inherit 'bold :foreground blue)
+ ((markdown-code-face &override) :background (doom-lighten base2 0.045))
+ ;;;; neotree
+ (neo-dir-link-face :foreground cyan)
+ (neo-expand-btn-face :foreground red)
+ ;;;; rainbow-delimiters
+ (rainbow-delimiters-depth-1-face :foreground red)
+ (rainbow-delimiters-depth-2-face :foreground orange)
+ (rainbow-delimiters-depth-3-face :foreground green)
+ (rainbow-delimiters-depth-4-face :foreground cyan)
+ (rainbow-delimiters-depth-5-face :foreground red)
+ (rainbow-delimiters-depth-6-face :foreground orange)
+ (rainbow-delimiters-depth-7-face :foreground green)
+ ;;;; outline <built-in>
+ ((outline-1 &override) :foreground yellow)
+ ((outline-2 &override) :foreground blue)
+ ((outline-3 &override) :foreground green)
+ ((outline-4 &override) :foreground fg)
+ ((outline-5 &override) :inherit 'outline-4)
+ ((outline-6 &override) :inherit 'outline-5)
+ ((outline-7 &override) :inherit 'outline-6)
+ ((outline-8 &override) :inherit 'outline-7)
+ ;;;; org <built-in>
+ (org-ellipsis :foreground orange)
+ (org-tag :foreground yellow :bold nil)
+ ((org-quote &override) :inherit 'italic :foreground base7 :background org-quote)
+ (org-todo :foreground yellow :bold 'inherit)
+ (org-list-dt :foreground yellow)
+ ;;;; php-mode
+ (php-php-tag :foreground orange)
+ (php-function-name :foreground green)
+ (php-function-call :foreground green)
+ (php-string :foreground yellow)
+ (php-keyword :foreground blue)
+ (php-builtin :foreground violet)
+ (php-method-call :foreground green)
+ (php-static-method-call :foreground green)
+ (php-variable-name :foreground fg)
+ (php-property-name :foreground fg)
+ (php-variable-sigil :foreground base8)
+ (php-operator :foreground red)
+ (php-paamayim-nekudotayim :foreground red)
+ (php-type :foreground blue :italic italic)
+ (php-class :foreground red)
+ (php-constant :foreground violet)
+ (php-constant-assign :foreground blue)
+ (php-magical-constant :foreground violet)
+ (php-$this :foreground base8 :italic italic)
+ (php-$this-sigil :foreground base8 :italic italic)
+ (php-errorcontrol-op :foreground red)
+ (php-doc-annotation-tag :foreground blue)
+ (php-doc-variable-sigil :foreground base6)
+ (php-doc-$this :foreground base6)
+ (php-doc-$this-sigil :foreground base6)
+ (php-doc-class-name :foreground base6)
+ ;; As soon as https://github.com/emacs-php/php-mode/pull/606
+ ;; is merged these can be uncommented.
+ ;;(php-class-declaration-spec :foreground red)
+ ;;(php-class-modifier :foreground red)
+ ;;(php-namespace-declaration :foreground red)
+ ;;(php-import-declaration :foreground red)
+ ;;(php-method-modifier :foreground red :italic italic)
+ ;;(php-method-access :foreground red :italic italic)
+ ;;(php-method-static :foreground red :italic italic)
+ ;;(php-property-access :foreground red :italic italic)
+ ;;(php-property-const :foreground red :italic italic)
+ ;;(php-property-static :foreground red :italic italic)
+ ;;(php-block-delimiter :foreground base7)
+ ;;(php-flow-control-statement :foreground red)
+ ;;(php-block-statement :foreground red)
+ ;;(php-include-statement :foreground green)
+ ;;(php-constant-keyword :foreground violet)
+ ;;(php-number :foreground violet)
+ ;;(php-string-quote :foreground base7)
+ ;;(php-type-operator :foreground red)
+ ;;(php-print-statement :foreground green)
+ ;;(php-return-type-colon :foreground red)
+ ;;(php-function-keyword :foreground blue :italic italic)
+ ;;;; show-paren-mode
+ (show-paren-match :bold bold :foreground green)
+ (show-paren-mismatch :bold bold :foreground red)
+ ;;;; swiper
+ (swiper-background-match-face-1 :inherit 'match :bold bold)
+ (swiper-background-match-face-2 :inherit 'match)
+ (swiper-background-match-face-3 :inherit 'match :foreground green)
+ (swiper-background-match-face-4 :inherit 'match :bold bold :foreground green)
+ (swiper-match-face-1 :inherit 'isearch :bold bold)
+ (swiper-match-face-2 :inherit 'isearch)
+ (swiper-match-face-3 :inherit 'isearch :foreground green)
+ (swiper-match-face-4 :inherit 'isearch :bold bold :foreground green)
+ (swiper-line-face :inherit 'hl-line)
+ ;;;; term <built-in>
+ (term-color-black :foreground base3)
+ (term-color-blue :foreground blue)
+ (term-color-cyan :foreground violet)
+ (term-color-green :foreground green)
+ (term-color-magenta :foreground red)
+ (term-color-red :foreground red)
+ (term-color-white :foreground fg)
+ (term-color-yellow :foreground yellow)
+ ;;;; treemacs
+ (treemacs-git-added-face :foreground green)
+ (treemacs-git-conflict-face :foreground red)
+ (treemacs-git-ignored-face :foreground base6)
+ (treemacs-git-modified-face :foreground violet)
+ (treemacs-git-renamed-face :foreground orange)
+ (treemacs-git-untracked-face :inherit 'treemacs-git-renamed-face)
+ (treemacs-on-failure-pulse-face :foreground base0 :background red)
+ (treemacs-on-success-pulse-face :foreground base0 :background green)
+ ;;;; web-mode
+ ;; html
+ (web-mode-html-tag-face :foreground red)
+ (web-mode-html-tag-bracket-face :foreground base7)
+ (web-mode-html-attr-name-face :foreground cyan :italic italic)
+ (web-mode-html-attr-equal-face :inherit 'web-mode-html-tag-bracket-face)
+ ;; css
+ ;; Apparently web-mode has no face for values of css properties.
+ (web-mode-css-selector-face :foreground green)
+ (web-mode-css-property-name-face :foreground base7))
+
+ ;;;; Base theme variable overrides
+ ;; ()
+ )
+
+;;; doom-monokai-ristretto-theme.el ends here
diff --git a/elpa/doom-themes-20220504.1557/doom-monokai-spectrum-theme.el b/elpa/doom-themes-20220504.1557/doom-monokai-spectrum-theme.el
new file mode 100644
index 0000000..9243edd
--- /dev/null
+++ b/elpa/doom-themes-20220504.1557/doom-monokai-spectrum-theme.el
@@ -0,0 +1,305 @@
+;; doom-monokai-spectrum-theme.el --- Spectrum filter of Monokai Pro -*- lexical-binding: t; no-byte-compile: t; -*-
+(require 'doom-themes)
+
+;;; Code:
+(defgroup doom-monokai-spectrum-theme nil
+ "Options for doom-molokai."
+ :group 'doom-themes)
+
+(defcustom doom-monokai-spectrum-brighter-comments nil
+ "If non-nil, comments will be highlighted in more vivid colors."
+ :group 'doom-monokai-spectrum-theme
+ :type 'boolean)
+
+(defcustom doom-monokai-spectrum-comment-bg doom-monokai-spectrum-brighter-comments
+ "If non-nil, comments will have a subtle, darker background.
+Enhancing their legibility."
+ :group 'doom-monokai-spectrum-theme
+ :type 'boolean)
+
+(defcustom doom-monokai-spectrum-padded-modeline doom-themes-padded-modeline
+ "If non-nil, adds a 4px padding to the mode-line.
+Can be an integer to determine the exact padding."
+ :group 'doom-monokai-spectrum-theme
+ :type '(choice integer boolean))
+
+;;
+(def-doom-theme doom-monokai-spectrum
+ "A dark, vibrant theme inspired by Textmate's Monokai."
+
+ ;; name gui 256 16
+ ((bg '("#222222" nil nil ))
+ (bg-alt '("#191919" nil nil ))
+ (base0 '("#131313" "#121212" "black" ))
+ (base1 '("#191919" "#1c1c1c" "black" ))
+ (base2 '("#2c2c2d" "#262626" "brightblack" ))
+ (base3 '("#363537" "#3a3a3a" "brightblack" ))
+ (base4 '("#525053" "#585858" "brightblack" ))
+ (base5 '("#585659" "#585858" "brightblack" ))
+ (base6 '("#69676c" "#6c6c6c" "brightblack" ))
+ (base7 '("#8b888f" "#8a8a8a" "brightblack" ))
+ (base8 '("#b6b2bc" "#bcbcbc" "white" ))
+ (fg '("#f7f1ff" "#ffffff" "brightwhite" ))
+ (fg-alt '("#c6c6c6" "#c6c6c6" "white" ))
+
+ (grey base4)
+ (red '("#fc618d" "#ff69bf" "red" ))
+ (orange '("#fd9353" "#ff7f50" "brightred" ))
+ (green '("#7bd88f" "#90ee90" "green" ))
+ (yellow '("#fce566" "#f0e68c" "yellow" ))
+ (violet '("#948ae3" "#9370db" "magenta" ))
+ (cyan '("#5ad4e6" "#40e0d0" "brightcyan" ))
+ (magenta cyan)
+ (blue cyan)
+ (dark-blue cyan)
+ (teal cyan)
+ (dark-cyan cyan)
+
+ ;; face categories
+ (highlight yellow)
+ (vertical-bar (doom-lighten bg 0.1))
+ (selection base2)
+ (builtin violet)
+ (comments (if doom-monokai-spectrum-brighter-comments violet base6))
+ (doc-comments (if doom-monokai-spectrum-brighter-comments (doom-lighten violet 0.1) (doom-lighten base6 0.25)))
+ (constants violet)
+ (functions green)
+ (keywords magenta)
+ (methods green)
+ (operators red)
+ (type cyan)
+ (strings yellow)
+ (variables fg)
+ (numbers violet)
+ (region base3)
+ (error red)
+ (warning orange)
+ (success green)
+ (vc-modified orange)
+ (vc-added green)
+ (vc-deleted red)
+
+ ;; custom categories
+ (hidden `(,(car bg) "black" "black"))
+ (-modeline-pad
+ (when doom-monokai-spectrum-padded-modeline
+ (if (integerp doom-monokai-spectrum-padded-modeline) doom-monokai-spectrum-padded-modeline 4)))
+
+
+ (org-quote `(,(doom-lighten (car bg) 0.05) "#1f1f1f")))
+
+
+ ;;;; Base theme face overrides
+ ((cursor :background fg)
+ ;; I-search
+ (match :foreground fg :background base3)
+ (isearch :inherit 'match :box `(:line-width 2 :color ,yellow))
+ (lazy-highlight :inherit 'match)
+ (isearch-fail :foreground red)
+ ;; current line
+ (hl-line :background base3)
+ ;; line-numbers
+ ((line-number &override) :foreground base4 :distant-foreground nil)
+ ((line-number-current-line &override) :foreground base7 :distant-foreground nil)
+ ;; mode-line
+ (mode-line :background base3 :foreground fg
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color red)))
+ (mode-line-inactive :background bg :foreground fg
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color red)))
+
+ ;;;; centaur-tabs
+ (centaur-tabs-selected-modified :inherit 'centaur-tabs-selected :foreground yellow)
+ (centaur-tabs-unselected-modified :inherit 'centaur-tabs-unselected :foreground yellow)
+ (centaur-tabs-active-bar-face :background yellow)
+ (centaur-tabs-modified-marker-selected :inherit 'centaur-tabs-selected :foreground fg)
+ (centaur-tabs-modified-marker-unselected :inherit 'centaur-tabs-unselected :foreground fg)
+ ;;;; css-mode <built-in> / scss-mode
+ (css-proprietary-property :foreground keywords)
+ ;;;; deadgrep
+ (deadgrep-match-face :inherit 'match :box `(:line-width 2 :color ,yellow))
+ ;;;; doom-emacs
+ (doom-dashboard-menu-title :foreground yellow)
+ ;;;; doom-modeline
+ (doom-modeline-bar :background yellow)
+ (doom-modeline-buffer-file :inherit 'mode-line-buffer-id :weight 'bold)
+ (doom-modeline-buffer-path :inherit 'bold :foreground green)
+ (doom-modeline-buffer-project-root :foreground green :weight 'bold)
+ (doom-modeline-buffer-modified :inherit 'bold :foreground orange)
+ ;;;; ediff <built-in>
+ (ediff-fine-diff-A :background (doom-blend red bg 0.3) :bold 'bold)
+ ;;;; evil
+ (evil-search-highlight-persist-highlight-face :background violet)
+ ;;;; evil-snipe
+ (evil-snipe-first-match-face :foreground base0 :background green)
+ (evil-snipe-matches-face :foreground green :underline t)
+ ;;;; flycheck
+ ((flycheck-error &override) :background base3)
+ ((flycheck-warning &override) :background base3)
+ ((flycheck-info &override) :background base3)
+ ;;;; helm
+ (helm-swoop-target-line-face :foreground red :inverse-video t)
+ ;;;; ivy
+ (ivy-action :foreground violet)
+ (ivy-confirm-face :foreground green)
+ (ivy-current-match :background base3)
+ (ivy-cursor :foreground bg :background fg)
+ (ivy-grep-info :foreground red)
+ (ivy-grep-line-number :foreground red)
+ (ivy-highlight-face :background base3 :foreground fg)
+ (ivy-match-required-face :foreground red)
+ (ivy-minibuffer-match-face-1 :background base2 :foreground base4)
+ (ivy-minibuffer-match-face-2 :foreground yellow :bold bold)
+ (ivy-minibuffer-match-face-3 :foreground green)
+ (ivy-minibuffer-match-face-4 :foreground green :bold bold)
+ (ivy-minibuffer-match-highlight :foreground base6 :background base3)
+ (ivy-modified-buffer :foreground fg)
+ (ivy-modified-outside-buffer :foreground fg)
+ (ivy-org :foreground base3 :italic italic)
+ (ivy-prompt-match :foreground bg :background yellow)
+ (ivy-remote :foreground violet)
+ (ivy-separator :foreground base3)
+ (ivy-subdir :foreground green)
+ (ivy-virtual :foreground violet)
+ (ivy-yanked-word :foreground base6 :background base3)
+ ;;;; lsp-mode
+ (lsp-face-highlight-read :background base3)
+ (lsp-face-highlight-textual :background base3)
+ (lsp-face-highlight-write :background base4)
+ ;;;; lsp-ui
+ ;; HIGHLY recommended: (setq lsp-ui-peek-fontify 'always)
+ (lsp-ui-peek-header :foreground fg :background base5)
+ (lsp-ui-peek-footer :inherit 'lsp-ui-peek-header)
+ (lsp-ui-peek-selection :foreground bg :background yellow)
+ (lsp-ui-peek-list :background base3)
+ (lsp-ui-peek-peek :inherit 'lsp-ui-peek-list)
+ (lsp-ui-peek-highlight :inherit 'isearch)
+ (lsp-ui-peek-filename :foreground base8 :bold bold)
+ ;;;; markdown-mode
+ (markdown-blockquote-face :inherit 'italic :foreground dark-blue)
+ (markdown-list-face :foreground red)
+ (markdown-pre-face :foreground cyan)
+ (markdown-link-face :inherit 'bold :foreground blue)
+ ((markdown-code-face &override) :background (doom-lighten base2 0.045))
+ ;;;; neotree
+ (neo-dir-link-face :foreground cyan)
+ (neo-expand-btn-face :foreground red)
+ ;;;; outline <built-in>
+ ((outline-1 &override) :foreground yellow)
+ ((outline-2 &override) :foreground blue)
+ ((outline-3 &override) :foreground green)
+ ((outline-4 &override) :foreground fg)
+ ((outline-5 &override) :inherit 'outline-4)
+ ((outline-6 &override) :inherit 'outline-5)
+ ((outline-7 &override) :inherit 'outline-6)
+ ((outline-8 &override) :inherit 'outline-7)
+ ;;;; org <built-in>
+ (org-ellipsis :foreground orange)
+ (org-tag :foreground yellow :bold nil)
+ ((org-quote &override) :inherit 'italic :foreground base7 :background org-quote)
+ (org-todo :foreground yellow :bold 'inherit)
+ (org-list-dt :foreground yellow)
+ ;;;; php-mode
+ (php-php-tag :foreground orange)
+ (php-function-name :foreground green)
+ (php-function-call :foreground green)
+ (php-string :foreground yellow)
+ (php-keyword :foreground blue)
+ (php-builtin :foreground violet)
+ (php-method-call :foreground green)
+ (php-static-method-call :foreground green)
+ (php-variable-name :foreground fg)
+ (php-property-name :foreground fg)
+ (php-variable-sigil :foreground base8)
+ (php-operator :foreground red)
+ (php-paamayim-nekudotayim :foreground red)
+ (php-type :foreground blue :italic italic)
+ (php-class :foreground red)
+ (php-constant :foreground violet)
+ (php-constant-assign :foreground blue)
+ (php-magical-constant :foreground violet)
+ (php-$this :foreground base8 :italic italic)
+ (php-$this-sigil :foreground base8 :italic italic)
+ (php-errorcontrol-op :foreground red)
+ (php-doc-annotation-tag :foreground blue)
+ (php-doc-variable-sigil :foreground base6)
+ (php-doc-$this :foreground base6)
+ (php-doc-$this-sigil :foreground base6)
+ (php-doc-class-name :foreground base6)
+ ;; As soon as https://github.com/emacs-php/php-mode/pull/606
+ ;; is merged these can be uncommented.
+ ;;(php-class-declaration-spec :foreground red)
+ ;;(php-class-modifier :foreground red)
+ ;;(php-namespace-declaration :foreground red)
+ ;;(php-import-declaration :foreground red)
+ ;;(php-method-modifier :foreground red :italic italic)
+ ;;(php-method-access :foreground red :italic italic)
+ ;;(php-method-static :foreground red :italic italic)
+ ;;(php-property-access :foreground red :italic italic)
+ ;;(php-property-const :foreground red :italic italic)
+ ;;(php-property-static :foreground red :italic italic)
+ ;;(php-block-delimiter :foreground base7)
+ ;;(php-flow-control-statement :foreground red)
+ ;;(php-block-statement :foreground red)
+ ;;(php-include-statement :foreground green)
+ ;;(php-constant-keyword :foreground violet)
+ ;;(php-number :foreground violet)
+ ;;(php-string-quote :foreground base7)
+ ;;(php-type-operator :foreground red)
+ ;;(php-print-statement :foreground green)
+ ;;(php-return-type-colon :foreground red)
+ ;;(php-function-keyword :foreground blue :italic italic)
+ ;;;; rainbow-delimiters
+ (rainbow-delimiters-depth-1-face :foreground red)
+ (rainbow-delimiters-depth-2-face :foreground orange)
+ (rainbow-delimiters-depth-3-face :foreground green)
+ (rainbow-delimiters-depth-4-face :foreground cyan)
+ (rainbow-delimiters-depth-5-face :foreground red)
+ (rainbow-delimiters-depth-6-face :foreground orange)
+ (rainbow-delimiters-depth-7-face :foreground green)
+ ;;;; show-paren-mode
+ (show-paren-match :bold bold :foreground green)
+ (show-paren-mismatch :bold bold :foreground red)
+ ;;;; swiper
+ (swiper-background-match-face-1 :inherit 'match :bold bold)
+ (swiper-background-match-face-2 :inherit 'match)
+ (swiper-background-match-face-3 :inherit 'match :foreground green)
+ (swiper-background-match-face-4 :inherit 'match :bold bold :foreground green)
+ (swiper-match-face-1 :inherit 'isearch :bold bold)
+ (swiper-match-face-2 :inherit 'isearch)
+ (swiper-match-face-3 :inherit 'isearch :foreground green)
+ (swiper-match-face-4 :inherit 'isearch :bold bold :foreground green)
+ (swiper-line-face :inherit 'hl-line)
+ ;;;; term <built-in>
+ (term-color-black :foreground base3)
+ (term-color-blue :foreground blue)
+ (term-color-cyan :foreground violet)
+ (term-color-green :foreground green)
+ (term-color-magenta :foreground red)
+ (term-color-red :foreground red)
+ (term-color-white :foreground fg)
+ (term-color-yellow :foreground yellow)
+ ;;;; treemacs
+ (treemacs-git-added-face :foreground green)
+ (treemacs-git-conflict-face :foreground red)
+ (treemacs-git-ignored-face :foreground base6)
+ (treemacs-git-modified-face :foreground violet)
+ (treemacs-git-renamed-face :foreground orange)
+ (treemacs-git-untracked-face :inherit 'treemacs-git-renamed-face)
+ (treemacs-on-failure-pulse-face :foreground base0 :background red)
+ (treemacs-on-success-pulse-face :foreground base0 :background green)
+ ;;;; web-mode
+ ;; html
+ (web-mode-html-tag-face :foreground red)
+ (web-mode-html-tag-bracket-face :foreground base7)
+ (web-mode-html-attr-name-face :foreground cyan :italic italic)
+ (web-mode-html-attr-equal-face :inherit 'web-mode-html-tag-bracket-face)
+ ;; css
+ ;; Apparently web-mode has no face for values of css properties.
+ (web-mode-css-selector-face :foreground green)
+ (web-mode-css-property-name-face :foreground base7))
+
+ ;;;; Base theme variable overrides
+ ;; ()
+ )
+
+;;; doom-monokai-spectrum-theme.el ends here
diff --git a/elpa/doom-themes-20220504.1557/doom-moonlight-theme.el b/elpa/doom-themes-20220504.1557/doom-moonlight-theme.el
new file mode 100644
index 0000000..fee9a2d
--- /dev/null
+++ b/elpa/doom-themes-20220504.1557/doom-moonlight-theme.el
@@ -0,0 +1,259 @@
+;;; doom-moonlight-theme.el --- inspired by VS code's Moonlight -*- lexical-binding: t; no-byte-compile: t; -*-
+(require 'doom-themes)
+
+;;
+(defgroup doom-moonlight-theme nil
+ "Options for the `doom-moonlight' theme."
+ :group 'doom-themes)
+
+(defcustom doom-moonlight-padded-modeline doom-themes-padded-modeline
+ "If non-nil, adds a 4px padding to the mode-line.
+Can be an integer to determine the exact padding."
+ :group 'doom-moonlight-theme
+ :type '(choice integer boolean))
+
+;;
+(def-doom-theme doom-moonlight
+ "A dark theme inspired by VS code's Moonlight"
+
+ ;; name default 256 16
+ ((bg '("#212337" "#212337" "black"))
+ (bg-alt '("#191a2a" "#191a2a" "black"))
+ (base0 '("#161a2a" "#161a2a" "black"))
+ (base1 '("#191a2a" "#191a2a" "brightblack"))
+ (base2 '("#1e2030" "#1e2030" "brightblack"))
+ (base3 '("#222436" "#222436" "brightblack"))
+ (base4 '("#2f334d" "#2f334d" "brightblack"))
+ (base5 '("#444a73" "#444a73" "brightblack"))
+ (base6 '("#828bb8" "#828bb8" "brightblack"))
+ (base7 '("#a9b8e8" "#a9b8e8" "brightblack"))
+ (base8 '("#b4c2f0" "#b4c2f0" "white"))
+ (indigo '("#7a88cf" "#7a88cf" "brightblack"))
+ (region '("#383e5c" "#383e5c" "brightblack"))
+ (fg '("#c8d3f5" "#c8d3f5" "brightwhite"))
+ (fg-alt '("#b4c2f0" "#b4c2f0" "white"))
+
+ (grey base5)
+
+ (dark-red '("#ff5370" "#ff5370" "red"))
+ (red '("#ff757f" "#ff757f" "red"))
+ (light-red '("#ff98a4" "#ff98a4" "brightred"))
+ (orange '("#ff995e" "#ff995e" "brightred"))
+ (green '("#c3e88d" "#c3e88d" "green"))
+ (dark-teal '("#4fd6be" "#4fd6be" "green"))
+ (teal '("#77e0c6" "#77e0c6" "brightgreen"))
+ (light-teal '("#7af8ca" "#7af8ca" "brightgreen"))
+ (yellow '("#ffc777" "#ffc777" "brightyellow"))
+ (blue '("#82aaff" "#82aaff" "brightblue"))
+ (dark-blue '("#4976eb" "#4976eb" "brightblue"))
+ (light-blue '("#50c4fa" "#50c4fa" "blue"))
+ (light-magenta '("#baacff" "#baacff" "brightmagenta"))
+ (magenta '("#c099ff" "#c099ff" "brightmagenta"))
+ (violet '("#f989d3" "#f989d3" "magenta"))
+ (light-pink '("#fca7ea" "#fca7ea" "magenta"))
+ (pink '("#f3c1ff" "#f3c1ff" "magenta"))
+ (cyan '("#b4f9f8" "#b4f9f8" "brightcyan"))
+ (dark-cyan '("#86e1fc" "#86e1fc" "cyan"))
+
+ ;; face categories -- required for all themes
+ (highlight blue)
+ (vertical-bar base0)
+ (line-highlight base4)
+ (selection region)
+ (builtin magenta)
+ (comments indigo)
+ (doc-comments (doom-lighten comments 0.25))
+ (constants orange)
+ (functions blue)
+ (keywords magenta)
+ (methods red)
+ (operators dark-cyan)
+ (type yellow)
+ (strings green)
+ (variables light-red)
+ (numbers orange)
+ (region region)
+ (error red)
+ (warning yellow)
+ (success green)
+ (vc-modified blue)
+ (vc-added teal)
+ (vc-deleted red)
+
+ ;; custom categories
+ (modeline-bg (doom-darken base2 0.1))
+ (modeline-bg-alt (doom-darken bg 0.1))
+ (modeline-fg base8)
+ (modeline-fg-alt comments)
+
+ (-modeline-pad
+ (when doom-moonlight-padded-modeline
+ (if (integerp doom-moonlight-padded-modeline) doom-moonlight-padded-modeline 4))))
+
+ ;;;; Base theme face overrides
+ ((font-lock-keyword-face :foreground keywords)
+ (font-lock-comment-face :foreground comments)
+ (font-lock-doc-face :foreground doc-comments)
+ (hl-line :background line-highlight)
+ (lazy-highlight :background base4 :foreground fg)
+ ((line-number &override) :foreground base5 :background (doom-darken bg 0.06))
+ ((line-number-current-line &override) :foreground fg :background line-highlight)
+ (mode-line
+ :background modeline-bg :foreground modeline-fg
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg)))
+ (mode-line-inactive
+ :background modeline-bg-alt :foreground modeline-fg-alt
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-alt)))
+ (tooltip :background base0 :foreground fg)
+
+ ;;;; all-the-icons
+ (all-the-icons-cyan :foreground dark-cyan)
+ (all-the-icons-cyan-alt :foreground dark-cyan)
+ (all-the-icons-dblue :foreground (doom-darken blue 0.1))
+ (all-the-icons-dgreen :foreground dark-teal)
+ (all-the-icons-dmaroon :foreground magenta)
+ (all-the-icons-dorange :foreground orange)
+ (all-the-icons-dpink :foreground pink)
+ (all-the-icons-dpurple :foreground magenta)
+ (all-the-icons-dred :foreground dark-red)
+ (all-the-icons-dsilver :foreground grey)
+ (all-the-icons-dyellow :foreground orange)
+ (all-the-icons-green :foreground teal)
+ (all-the-icons-lcyan :foreground (doom-lighten dark-cyan 0.3))
+ (all-the-icons-lgreen :foreground green)
+ (all-the-icons-lmaroon :foreground light-magenta)
+ (all-the-icons-lorange :foreground orange)
+ (all-the-icons-lpink :foreground light-pink)
+ (all-the-icons-lpurple :foreground light-magenta)
+ (all-the-icons-lred :foreground light-red)
+ (all-the-icons-lsilver :foreground (doom-lighten grey 0.4))
+ (all-the-icons-lyellow :foreground (doom-lighten yellow 0.3))
+ (all-the-icons-orange :foreground orange)
+ (all-the-icons-pink :foreground pink)
+ (all-the-icons-purple :foreground magenta)
+ (all-the-icons-purple-alt :foreground magenta)
+ (all-the-icons-red-alt :foreground red)
+ (all-the-icons-silver :foreground (doom-lighten grey 0.2))
+ ;;;; all-the-icons-dired
+ (all-the-icons-dired-dir-face :foreground indigo)
+ ;;;; company
+ (company-tooltip :inherit 'tooltip)
+ (company-tooltip-common :foreground highlight)
+ ;;;; company-box
+ (company-box-annotation :foreground base7)
+ ;;;; css-mode <built-in> / scss-mode
+ (css-proprietary-property :foreground orange)
+ (css-property :foreground green)
+ (css-selector :foreground blue)
+ ;;;; doom-emacs
+ (doom-dashboard-menu-desc :foreground dark-cyan)
+ (doom-dashboard-menu-tile :foreground dark-teal)
+ ;;;; diredfl
+ (diredfl-date-time :foreground blue)
+ (diredfl-file-name :foreground base7)
+ (diredfl-file-suffix :foreground base6)
+ (diredfl-symlink :foreground dark-cyan)
+ ;;;; dired+
+ (diredp-number :foreground orange)
+ ;;;; dired-k
+ (dired-k-commited :foreground base4)
+ (dired-k-modified :foreground vc-modified)
+ (dired-k-ignored :foreground cyan)
+ (dired-k-added :foreground vc-added)
+ ;;;; doom-emacs
+ (+workspace-tab-selected-face :background region :foreground blue)
+ ;;;; doom-modeline
+ (doom-modeline-buffer-file :foreground base7)
+ (doom-modeline-icon-inactive :foreground indigo)
+ (doom-modeline-evil-normal-state :foreground dark-cyan)
+ (doom-modeline-evil-insert-state :foreground blue)
+ (doom-modeline-project-dir :foreground light-teal)
+ (doom-modeline-buffer-path :foreground blue)
+ (doom-modeline-buffer-modified :inherit 'bold :foreground yellow)
+ (doom-modeline-buffer-major-mode :inherit 'doom-modeline-buffer-path)
+ ;;;; ivy-posframe
+ (ivy-posframe :background base0)
+ (ivy-posframe-border :background base0)
+ ;;;; js2-mode
+ (js2-jsdoc-tag :foreground magenta)
+ (js2-object-property :foreground dark-teal)
+ (js2-object-property-access :foreground fg-alt)
+ (js2-function-param :foreground pink)
+ (js2-jsdoc-type :foreground base8)
+ (js2-jsdoc-value :foreground cyan)
+ ;;;; linum
+ ((linum &inherit line-number))
+ ;;;; lsp-mode
+ (lsp-face-highlight-read :background region)
+ (lsp-face-highlight-textual :background region)
+ (lsp-face-highlight-write :background region)
+ (lsp-face-semhl-type-primative :foreground orange)
+ (lsp-face-semhl-method :foreground magenta)
+ ;;;; magit
+ (magit-filename :foreground teal)
+ ;;;; man <built-in>
+ (Man-overstrike :inherit 'bold :foreground magenta)
+ (Man-underline :inherit 'underline :foreground blue)
+ ;;;; markdown-mode
+ (markdown-header-face :inherit 'bold :foreground yellow)
+ (markdown-header-delimiter-face :inherit 'markdown-header-face)
+ (markdown-metadata-key-face :foreground magenta :inherit 'italic)
+ (markdown-list-face :foreground red)
+ (markdown-url-face :inherit 'underline :foreground orange)
+ (markdown-gfm-checkbox-face :foreground blue)
+ (markdown-blockquote-face :inherit 'italic :foreground fg)
+ (mmm-default-submode-face :background base1)
+ ;;;; message <built-in>
+ (message-header-name :foreground green)
+ (message-header-subject :foreground highlight :weight 'bold)
+ (message-header-to :foreground highlight :weight 'bold)
+ (message-header-cc :inherit 'message-header-to :foreground (doom-darken highlight 0.15))
+ (message-header-other :foreground violet)
+ (message-header-newsgroups :foreground yellow)
+ (message-header-xheader :foreground doc-comments)
+ (message-separator :foreground comments)
+ (message-mml :foreground comments :slant 'italic)
+ (message-cited-text :foreground magenta)
+ ;;;; nav-flash
+ (nav-flash-face :background region)
+ ;;;; nix-mode
+ (nix-attribute-face :foreground blue)
+ (nix-builtin-face :foreground dark-teal)
+ ;;;; org <built-in>
+ ((outline-1 &override) :foreground light-blue)
+ ((outline-2 &override) :foreground dark-cyan)
+ ((outline-3 &override) :foreground light-red)
+ ((outline-4 &override) :foreground blue)
+ ((outline-5 &override) :foreground magenta)
+ ((outline-6 &override) :foreground red)
+ ((outline-7 &override) :foreground violet)
+ ((org-block &override) :background base2)
+ ((org-block-background &override) :background base2)
+ ((org-block-begin-line &override) :background base2)
+ ;;;; popup
+ (popup-face :inherit 'tooltip)
+ (popup-selection-face :inherit 'tooltip)
+ ;;;; pos-tip
+ (popup-tip-face :inherit 'tooltip)
+ ;;;; rainbow-delimiters
+ (rainbow-delimiters-depth-1-face :foreground magenta)
+ (rainbow-delimiters-depth-2-face :foreground orange)
+ (rainbow-delimiters-depth-3-face :foreground light-red)
+ (rainbow-delimiters-depth-4-face :foreground cyan)
+ (rainbow-delimiters-depth-5-face :foreground violet)
+ (rainbow-delimiters-depth-6-face :foreground yellow)
+ (rainbow-delimiters-depth-7-face :foreground blue)
+ (rainbow-delimiters-depth-8-face :foreground teal)
+ (rainbow-delimiters-depth-9-face :foreground dark-cyan)
+ ;;;; rjsx-mode
+ (rjsx-tag :foreground violet)
+ (rjsx-attr :foreground yellow :slant 'italic :weight 'medium)
+ ;;;; treemacs
+ (treemacs-directory-face :foreground highlight)
+ (treemacs-git-modified-face :foreground highlight)
+ ;;;; which-key
+ (which-key-command-description-face :foreground fg)
+ (which-key-group-description-face :foreground magenta)
+ (which-key-local-map-description-face :foreground cyan)))
+
+;;; doom-moonlight-theme.el ends here
diff --git a/elpa/doom-themes-20220504.1557/doom-nord-light-theme.el b/elpa/doom-themes-20220504.1557/doom-nord-light-theme.el
new file mode 100644
index 0000000..5a72612
--- /dev/null
+++ b/elpa/doom-themes-20220504.1557/doom-nord-light-theme.el
@@ -0,0 +1,181 @@
+;;; doom-nord-light-theme.el --- inspired by Nord -*- lexical-binding: t; no-byte-compile: t; -*-
+(require 'doom-themes)
+
+;;
+(defgroup doom-nord-light-theme nil
+ "Options for the `doom-nord-light' theme."
+ :group 'doom-themes)
+
+(defcustom doom-nord-light-brighter-modeline nil
+ "If non-nil, more vivid colors will be used to style the mode-line."
+ :group 'doom-nord-light-theme
+ :type 'boolean)
+
+(defcustom doom-nord-light-brighter-comments nil
+ "If non-nil, comments will be highlighted in more vivid colors."
+ :group 'doom-nord-light-theme
+ :type 'boolean)
+
+(defcustom doom-nord-light-comment-bg doom-nord-light-brighter-comments
+ "If non-nil, comments will have a subtle, darker background. Enhancing their
+legibility."
+ :group 'doom-nord-light-theme
+ :type 'boolean)
+
+(defcustom doom-nord-light-padded-modeline doom-themes-padded-modeline
+ "If non-nil, adds a 4px padding to the mode-line. Can be an integer to
+determine the exact padding."
+ :group 'doom-nord-light-theme
+ :type '(choice integer boolean))
+
+(defcustom doom-nord-light-region-highlight t
+ "Determines the selection highlight style. Can be 'frost, 'snowstorm or t
+(default)."
+ :group 'doom-nord-light-theme
+ :type 'symbol)
+
+;;
+(def-doom-theme doom-nord-light
+ "A light theme inspired by Nord-Light."
+
+ ;; name default 256 16
+ ((bg '("#E5E9F0" nil nil))
+ (bg-alt '("#D8DEE9" nil nil))
+ (base0 '("#F0F4FC" "black" "black"))
+ (base1 '("#E3EAF5" "#1e1e1e" "brightblack"))
+ (base2 '("#D8DEE9" "#2e2e2e" "brightblack"))
+ (base3 '("#C2D0E7" "#262626" "brightblack"))
+ (base4 '("#B8C5DB" "#3f3f3f" "brightblack"))
+ (base5 '("#AEBACF" "#525252" "brightblack"))
+ (base6 '("#A1ACC0" "#6b6b6b" "brightblack"))
+ (base7 '("#60728C" "#979797" "brightblack"))
+ (base8 '("#485163" "#dfdfdf" "white"))
+ (fg '("#3B4252" "#2d2d2d" "white"))
+ (fg-alt '("#2E3440" "#bfbfbf" "brightwhite"))
+
+ (grey base4)
+ (red '("#99324B" "#ff6655" "red"))
+ (orange '("#AC4426" "#dd8844" "brightred"))
+ (green '("#4F894C" "#99bb66" "green"))
+ (teal '("#29838D" "#44b9b1" "brightgreen"))
+ (yellow '("#9A7500" "#ECBE7B" "yellow"))
+ (blue '("#3B6EA8" "#51afef" "brightblue"))
+ (dark-blue '("#5272AF" "#2257A0" "blue"))
+ (magenta '("#97365B" "#c678dd" "magenta"))
+ (violet '("#842879" "#a9a1e1" "brightmagenta"))
+ (cyan '("#398EAC" "#46D9FF" "brightcyan"))
+ (dark-cyan '("#2C7088" "#5699AF" "cyan"))
+
+ ;; face categories -- required for all themes
+ (highlight (doom-blend blue bg 0.8))
+ (vertical-bar (doom-darken bg 0.15))
+ (selection (doom-blend blue bg 0.5))
+ (builtin teal)
+ (comments (if doom-nord-light-brighter-comments dark-cyan (doom-darken base5 0.2)))
+ (doc-comments (doom-darken (if doom-nord-light-brighter-comments dark-cyan base5) 0.25))
+ (constants magenta)
+ (functions teal)
+ (keywords blue)
+ (methods teal)
+ (operators blue)
+ (type yellow)
+ (strings green)
+ (variables violet)
+ (numbers magenta)
+ (region (pcase doom-nord-light-region-highlight
+ ((\` frost) (doom-lighten teal 0.5))
+ ((\` snowstorm) base0)
+ (_ base4)))
+ (error red)
+ (warning yellow)
+ (success green)
+ (vc-modified orange)
+ (vc-added green)
+ (vc-deleted red)
+
+ ;; custom categories
+ (hidden `(,(car bg) "black" "black"))
+ (-modeline-bright doom-nord-light-brighter-modeline)
+ (-modeline-pad
+ (when doom-nord-light-padded-modeline
+ (if (integerp doom-nord-light-padded-modeline) doom-nord-light-padded-modeline 4)))
+
+ (modeline-fg nil)
+ (modeline-fg-alt base6)
+
+ (modeline-bg
+ (if -modeline-bright
+ (doom-blend bg blue 0.7)
+ `(,(doom-darken (car bg) 0.02) ,@(cdr base0))))
+ (modeline-bg-l
+ (if -modeline-bright
+ (doom-blend bg blue 0.7)
+ `(,(doom-darken (car bg) 0.03) ,@(cdr base0))))
+ (modeline-bg-inactive `(,(car bg) ,@(cdr base1)))
+ (modeline-bg-inactive-l (doom-darken bg 0.01)))
+
+
+ ;;;; Base theme face overrides
+ (((font-lock-comment-face &override)
+ :background (if doom-nord-light-comment-bg (doom-lighten bg 0.05)))
+ ((line-number &override) :foreground (doom-lighten 'base5 0.2))
+ ((line-number-current-line &override) :foreground base7)
+ (internal-border :foreground (doom-blend blue bg 0.2) :background (doom-blend blue bg 0.2))
+ (mode-line
+ :background modeline-bg :foreground modeline-fg
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg)))
+ (mode-line-inactive
+ :background modeline-bg-inactive :foreground modeline-fg-alt
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive)))
+ (mode-line-emphasis
+ :foreground (if -modeline-bright base8 highlight))
+ ((region &override)
+ :foreground (if (memq doom-nord-light-region-highlight '(frost snowstorm))
+ bg-alt))
+
+ ;;;; css-mode <built-in> / scss-mode <built-in>
+ (css-proprietary-property :foreground orange)
+ (css-property :foreground green)
+ (css-selector :foreground blue)
+ ;;;; doom-modeline
+ (doom-modeline-bar :background (if -modeline-bright modeline-bg highlight))
+ (doom-modeline-project-root-dir :foreground base6)
+ ;;;; elscreen
+ (elscreen-tab-other-screen-face :background "#353a42" :foreground "#1e2022")
+ ;;;; ivy
+ (ivy-minibuffer-match-face-1 :background nil :foreground (doom-blend fg bg 0.5) :weight 'light)
+ (ivy-virtual :foreground (doom-blend blue bg 0.8))
+ ;;;; ivy-posframe
+ (ivy-posframe :background (doom-blend blue bg 0.2))
+ ;;;; magit
+ (magit-diff-hunk-heading-highlight :foreground bg :background blue :weight 'bold)
+ (magit-diff-hunk-heading :foreground bg :background (doom-blend blue bg 0.3))
+ ;;;; markdown-mode
+ (markdown-markup-face :foreground base5)
+ (markdown-header-face :inherit 'bold :foreground red)
+ ((markdown-code-face &override) :background (doom-lighten base3 0.05))
+ ;;;; mic-paren
+ ((paren-face-match &override) :foreground red :background base3 :weight 'ultra-bold)
+ ((paren-face-mismatch &override) :foreground base3 :background red :weight 'ultra-bold)
+ ;;;; nav-flash
+ (nav-flash-face :background region :foreground base8 :weight 'bold)
+ ;;;; org <built-in>
+ (org-hide :foreground hidden)
+ ;;;; solaire-mode
+ (solaire-mode-line-face
+ :inherit 'mode-line
+ :background modeline-bg-l
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-l)))
+ (solaire-mode-line-inactive-face
+ :inherit 'mode-line-inactive
+ :background modeline-bg-inactive-l
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive-l)))
+ ;;;; vimish-fold
+ ((vimish-fold-fringe &override) :foreground teal)
+ ((vimish-fold-overlay &override) :inherit 'font-lock-comment-face :background base3 :weight 'light))
+
+ ;;;; Base theme variable overrides-
+ ()
+ )
+
+;;; doom-nord-light-theme.el ends here
diff --git a/elpa/doom-themes-20220504.1557/doom-nord-theme.el b/elpa/doom-themes-20220504.1557/doom-nord-theme.el
new file mode 100644
index 0000000..b1dd484
--- /dev/null
+++ b/elpa/doom-themes-20220504.1557/doom-nord-theme.el
@@ -0,0 +1,183 @@
+;;; doom-nord-theme.el --- inspired by Nord -*- lexical-binding: t; no-byte-compile: t; -*-
+(require 'doom-themes)
+
+;;
+(defgroup doom-nord-theme nil
+ "Options for the `doom-nord' theme."
+ :group 'doom-themes)
+
+(defcustom doom-nord-brighter-modeline nil
+ "If non-nil, more vivid colors will be used to style the mode-line."
+ :group 'doom-nord-theme
+ :type 'boolean)
+
+(defcustom doom-nord-brighter-comments nil
+ "If non-nil, comments will be highlighted in more vivid colors."
+ :group 'doom-nord-theme
+ :type 'boolean)
+
+(defcustom doom-nord-comment-bg doom-nord-brighter-comments
+ "If non-nil, comments will have a subtle, darker background. Enhancing their
+legibility."
+ :group 'doom-nord-theme
+ :type 'boolean)
+
+(defcustom doom-nord-padded-modeline doom-themes-padded-modeline
+ "If non-nil, adds a 4px padding to the mode-line. Can be an integer to
+determine the exact padding."
+ :group 'doom-nord-theme
+ :type '(choice integer boolean))
+
+(eval-and-compile
+ (defcustom doom-nord-region-highlight t
+ "Determines the selection highlight style. Can be 'frost, 'snowstorm or t
+(default)."
+ :group 'doom-nord-theme
+ :type 'symbol))
+
+;;
+(def-doom-theme doom-nord
+ "A dark theme inspired by Nord."
+
+ ;; name default 256 16
+ ((bg '("#2E3440" nil nil ))
+ (bg-alt '("#272C36" nil nil ))
+ (base0 '("#191C25" "black" "black" ))
+ (base1 '("#242832" "#1e1e1e" "brightblack" ))
+ (base2 '("#2C333F" "#2e2e2e" "brightblack" ))
+ (base3 '("#373E4C" "#262626" "brightblack" ))
+ (base4 '("#434C5E" "#3f3f3f" "brightblack" ))
+ (base5 '("#4C566A" "#525252" "brightblack" ))
+ (base6 '("#9099AB" "#6b6b6b" "brightblack" ))
+ (base7 '("#D8DEE9" "#979797" "brightblack" ))
+ (base8 '("#F0F4FC" "#dfdfdf" "white" ))
+ (fg '("#ECEFF4" "#ECECEC" "white" ))
+ (fg-alt '("#E5E9F0" "#bfbfbf" "brightwhite" ))
+
+ (grey base4)
+ (red '("#BF616A" "#ff6655" "red" )) ;; Nord11
+ (orange '("#D08770" "#dd8844" "brightred" )) ;; Nord12
+ (green '("#A3BE8C" "#99bb66" "green" )) ;; Nord14
+ (teal '("#8FBCBB" "#44b9b1" "brightgreen" )) ;; Nord7
+ (yellow '("#EBCB8B" "#ECBE7B" "yellow" )) ;; Nord13
+ (blue '("#81A1C1" "#51afef" "brightblue" )) ;; Nord9
+ (dark-blue '("#5E81AC" "#2257A0" "blue" )) ;; Nord10
+ (magenta '("#B48EAD" "#c678dd" "magenta" )) ;; Nord15
+ (violet '("#5D80AE" "#a9a1e1" "brightmagenta")) ;; ??
+ (cyan '("#88C0D0" "#46D9FF" "brightcyan" )) ;; Nord8
+ (dark-cyan '("#507681" "#5699AF" "cyan" )) ;; ??
+
+ ;; face categories -- required for all themes
+ (highlight blue)
+ (vertical-bar (doom-darken base1 0.2))
+ (selection dark-blue)
+ (builtin blue)
+ (comments (if doom-nord-brighter-comments dark-cyan (doom-lighten base5 0.2)))
+ (doc-comments (doom-lighten (if doom-nord-brighter-comments dark-cyan base5) 0.25))
+ (constants blue)
+ (functions cyan)
+ (keywords blue)
+ (methods cyan)
+ (operators blue)
+ (type teal)
+ (strings green)
+ (variables base7)
+ (numbers magenta)
+ (region (pcase doom-nord-region-highlight
+ (`frost teal)
+ (`snowstorm base7)
+ (_ base4)))
+ (error red)
+ (warning yellow)
+ (success green)
+ (vc-modified orange)
+ (vc-added green)
+ (vc-deleted red)
+
+ ;; custom categories
+ (hidden `(,(car bg) "black" "black"))
+ (-modeline-bright doom-nord-brighter-modeline)
+ (-modeline-pad
+ (when doom-nord-padded-modeline
+ (if (integerp doom-nord-padded-modeline) doom-nord-padded-modeline 4)))
+
+ (region-fg
+ (when (memq doom-nord-region-highlight '(frost snowstorm))
+ base0))
+
+ (modeline-fg nil)
+ (modeline-fg-alt base6)
+
+ (modeline-bg
+ (if -modeline-bright
+ (doom-blend bg base5 0.2)
+ `(,(doom-darken (car bg) 0.1) ,@(cdr base2))))
+ (modeline-bg-l
+ (if -modeline-bright
+ (doom-blend bg base5 0.2)
+ base1))
+ (modeline-bg-inactive `(,(doom-darken (car bg) 0.1) ,@(cdr base2)))
+ (modeline-bg-inactive-l `(,(doom-darken (car bg) 0.025) ,@(cdr base2))))
+
+
+ ;;;; Base theme face overrides
+ ((fringe :foreground teal)
+ ((line-number &override) :foreground (doom-lighten 'base5 0.2))
+ ((line-number-current-line &override) :foreground base7)
+ ((font-lock-comment-face &override)
+ :background (if doom-nord-comment-bg (doom-lighten bg 0.05)))
+ ((tab-line &override) :background modeline-bg :foreground blue)
+ ((tab-line-tab-inactive &override) :foreground dark-blue)
+ (mode-line
+ :background modeline-bg :foreground modeline-fg
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg)))
+ (mode-line-inactive
+ :background modeline-bg-inactive :foreground modeline-fg-alt
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive)))
+ (mode-line-emphasis :foreground (if -modeline-bright base8 highlight))
+ ((region &override) :foreground region-fg)
+
+ ;;;; css-mode <built-in> / scss-mode
+ (css-proprietary-property :foreground orange)
+ (css-property :foreground green)
+ (css-selector :foreground blue)
+ ;;;; doom-modeline
+ (doom-modeline-bar :background (if -modeline-bright modeline-bg highlight))
+ (doom-modeline-project-root-dir :foreground base6)
+ ;;;; ediff <built-in>
+ (ediff-fine-diff-A :background (doom-darken violet 0.4) :weight 'bold)
+ (ediff-current-diff-A :background (doom-darken base0 0.25))
+ ;;;; elscreen
+ (elscreen-tab-other-screen-face :background "#353a42" :foreground "#1e2022")
+ ;;;; highlight-symbol
+ (highlight-symbol-face :background (doom-lighten base4 0.1) :distant-foreground fg-alt)
+ ;;;; highlight-thing
+ (highlight-thing :background (doom-lighten base4 0.1) :distant-foreground fg-alt)
+ ;;;; ivy
+ ((ivy-current-match &override) :foreground region-fg :weight 'semi-bold)
+ ;;;; markdown-mode
+ (markdown-markup-face :foreground base5)
+ (markdown-header-face :inherit 'bold :foreground red)
+ ((markdown-code-face &override) :background (doom-lighten base3 0.05))
+ ;;;; mic-paren
+ ((paren-face-match &override) :foreground bg :background teal :weight 'ultra-bold)
+ ((paren-face-mismatch &override) :foreground base7 :background red :weight 'ultra-bold)
+ ;;;; org <built-in>
+ (org-hide :foreground hidden)
+ ;;;; solaire-mode
+ (solaire-mode-line-face
+ :inherit 'mode-line
+ :background modeline-bg-l
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-l)))
+ (solaire-mode-line-inactive-face
+ :inherit 'mode-line-inactive
+ :background modeline-bg-inactive-l
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive-l)))
+ ;;;; vimish-fold
+ ((vimish-fold-overlay &override) :inherit 'font-lock-comment-face :background base3 :weight 'light)
+ ((vimish-fold-fringe &override) :foreground teal))
+
+ ;;;; Base theme variable overrides-
+ ())
+
+;;; doom-nord-theme.el ends here
diff --git a/elpa/doom-themes-20220504.1557/doom-nova-theme.el b/elpa/doom-themes-20220504.1557/doom-nova-theme.el
new file mode 100644
index 0000000..c56f456
--- /dev/null
+++ b/elpa/doom-themes-20220504.1557/doom-nova-theme.el
@@ -0,0 +1,144 @@
+;;; doom-nova-theme.el --- inspired by Trevord Miller's Nova -*- lexical-binding: t; no-byte-compile: t; -*-
+(require 'doom-themes)
+
+(defgroup doom-nova-theme nil
+ "Options for the `doom-nova' theme."
+ :group 'doom-themes)
+
+(defcustom doom-nova-padded-modeline doom-themes-padded-modeline
+ "If non-nil, adds a 4px padding to the mode-line. Can be an integer to
+determine the exact padding."
+ :group 'doom-nova-theme
+ :type '(choice integer boolean))
+
+(def-doom-theme doom-nova
+ "A light theme inspired by Trevord Miller's Nova. See
+<https://trevordmiller.com/projects/nova>."
+
+ ;; name default 256 16
+ ((bg '("#3c4c55" nil nil ))
+ (fg '("#c5d4dd" "#c5c6c6" "white" ))
+
+ (bg-alt '("#44545d" "#445566" "black" ))
+ (fg-alt '("#c5c8c6" "#c5c8c6" "white" ))
+
+ (base0 '("#0d0f11" "#0d0f11" "black" ))
+ (base1 '("#1e272c" "#1b1b1b" "black" ))
+ (base2 '("#212122" "#1e1e1e" "black" ))
+ (base3 '("#2f3f48" "#292929" "brightblack" ))
+ (base4 '("#3c4c55" "#3f3f3f" "brightblack" ))
+ (base5 '("#556873" "#525252" "brightblack" ))
+ (base6 '("#6A7D89" "#6b6b6b" "brightblack" ))
+ (base7 '("#899BA6" "#878797" "brightblack" ))
+ (base8 '("#e6eef3" "#efefef" "brightwhite" ))
+
+ (grey base7)
+ (red '("#DF8C8C"))
+ (orange '("#F2C38F"))
+ (yellow '("#DADA93"))
+ (green '("#A8CE93"))
+ (blue '("#83AFE5"))
+ (dark-blue '("#759DCE"))
+ (teal '("#95BEBC"))
+ (magenta '("#D18EC2"))
+ (violet '("#9A93E1"))
+ (cyan '("#7FC1CA"))
+ (dark-cyan '("#659AA1"))
+
+ ;; face categories
+ (highlight cyan)
+ (vertical-bar (doom-lighten bg 0.1))
+ (selection highlight)
+ (builtin blue)
+ (comments grey)
+ (doc-comments (doom-lighten grey 0.1))
+ (constants highlight)
+ (functions blue)
+ (keywords violet)
+ (methods blue)
+ (operators green)
+ (type green)
+ (strings cyan)
+ (variables red)
+ (numbers highlight)
+ (region selection)
+ (error red)
+ (warning yellow)
+ (success green)
+ (vc-modified violet)
+ (vc-added green)
+ (vc-deleted red)
+
+ ;; custom categories
+ (current-line base5) ; (doom-lighten bg-alt 0.04)
+ (modeline-fg blue)
+ (modeline-bg base5) ; bg-alt
+ (modeline-fg-alt (doom-lighten bg-alt 0.4))
+ (modeline-bg-alt base4)
+
+ (-modeline-pad
+ (when doom-nova-padded-modeline
+ (if (integerp doom-nova-padded-modeline)
+ doom-nova-padded-modeline
+ 4))))
+
+
+ ;;;; Base theme face overrides
+ ((fringe :inherit 'default :foreground "#6c808d")
+ ((line-number &override) :foreground "#6c808d")
+ ((line-number-current-line &override) :foreground highlight :weight 'bold)
+ (hl-line :background current-line)
+ (mode-line
+ :background modeline-bg :foreground modeline-fg
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg)))
+ (mode-line-inactive
+ :background modeline-bg-alt :foreground modeline-fg-alt
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-alt)))
+ (region :background (doom-lighten current-line 0.1) :foreground nil :distant-foreground nil :weight 'bold)
+
+ ;;;; company
+ (company-tooltip :inherit 'tooltip :background (doom-lighten bg 0.075))
+ (company-tooltip-selection :background base5 :foreground base8 :weight 'bold)
+ (company-tooltip-common :foreground cyan :distant-foreground cyan :weight 'bold)
+ (company-tooltip-search :background highlight :foreground base1 :weight 'ultra-bold)
+ (company-tooltip-search-selection :background highlight :foreground base1 :weight 'ultra-bold)
+ (company-tooltip-mouse :background base6 :foreground bg :distant-foreground fg)
+ ;;;; doom-modeline
+ (doom-modeline-buffer-path :foreground violet :bold nil)
+ (doom-modeline-buffer-major-mode :inherit 'doom-modeline-buffer-path)
+ (doom-modeline-bar :inherit 'mode-line-highlight)
+ ;;;; ediff <built-in>
+ (ediff-fine-diff-A :background base3 :weight 'bold)
+ (ediff-current-diff-A :inherit 'hl-line)
+ (ediff-even-diff-A :background base3)
+ ;;;; helm
+ (helm-selection :background current-line :weight 'bold)
+ (helm-match :foreground highlight)
+ (helm-source-header :foreground base0 :background base6)
+ ;;;; highlight-thing highlight-symbol
+ (highlight-symbol-face :background (doom-lighten current-line 0.1) :distant-foreground fg-alt)
+ ;;;; highlight-thing
+ (highlight-thing :background (doom-lighten current-line 0.1) :distant-foreground fg-alt)
+ ;;;; mic-paren
+ ((paren-face-match &override) :foreground red :background (doom-darken violet 0.4))
+ ((paren-face-mismatch &override) :foreground (doom-darken red 0.4) :background cyan)
+ ;;;; ivy
+ (ivy-current-match :background current-line :distant-foreground base0)
+ ;;;; org <built-in>
+ (org-headline-done :foreground base7)
+ ;;;; rainbow-delimiters
+ (rainbow-delimiters-depth-1-face :foreground violet)
+ (rainbow-delimiters-depth-2-face :foreground blue)
+ (rainbow-delimiters-depth-3-face :foreground orange)
+ (rainbow-delimiters-depth-4-face :foreground green)
+ (rainbow-delimiters-depth-5-face :foreground magenta)
+ (rainbow-delimiters-depth-6-face :foreground yellow)
+ (rainbow-delimiters-depth-7-face :foreground teal)
+ ;;;; solaire-mode
+ (solaire-hl-line-face :inherit 'hl-line))
+
+ ;; --- variables --------------------------
+ ;; ()
+ )
+
+;;; doom-nova-theme.el ends here
diff --git a/elpa/doom-themes-20220504.1557/doom-oceanic-next-theme.el b/elpa/doom-themes-20220504.1557/doom-oceanic-next-theme.el
new file mode 100644
index 0000000..d85e639
--- /dev/null
+++ b/elpa/doom-themes-20220504.1557/doom-oceanic-next-theme.el
@@ -0,0 +1,170 @@
+;;; doom-oceanic-next-theme.el --- inspired by Oceanic Next -*- lexical-binding: t; no-byte-compile: t; -*-
+(require 'doom-themes)
+
+(defgroup doom-oceanic-next-theme nil
+ "Options for the `doom-oceanic-next' theme."
+ :group 'doom-themes)
+
+(defcustom doom-oceanic-next-brighter-modeline nil
+ "If non-nil, more vivid colors will be used to style the mode-line."
+ :group 'doom-oceanic-next-theme
+ :type 'boolean)
+
+(defcustom doom-oceanic-next-brighter-comments nil
+ "If non-nil, comments will be highlighted in more vivid colors."
+ :group 'doom-oceanic-next-theme
+ :type 'boolean)
+
+(defcustom doom-oceanic-next-comment-bg doom-oceanic-next-brighter-comments
+ "If non-nil, comments will have a subtle, darker background. Enhancing their
+legibility."
+ :group 'doom-oceanic-next-theme
+ :type 'boolean)
+
+(defcustom doom-oceanic-next-padded-modeline doom-themes-padded-modeline
+ "If non-nil, adds a 4px padding to the mode-line. Can be an integer to
+determine the exact padding."
+ :group 'doom-oceanic-next-theme
+ :type '(choice integer boolean))
+
+;;
+(def-doom-theme doom-oceanic-next
+ "A dark theme inspired by Oceanic Next "
+
+ ;; name default 256 16
+ ((bg '("#1B2B34" nil nil ))
+ (bg-alt '("#14232D" nil nil ))
+ (base0 '("#1B2B34" "black" "black" ))
+ (base1 '("#343D46" "#1e1e1e" "brightblack" ))
+ (base2 '("#4F5B66" "#2e2e2e" "brightblack" ))
+ (base3 '("#65737E" "#262626" "brightblack" ))
+ (base4 '("#A7ADBA" "#3f3f3f" "brightblack" ))
+ (base5 '("#C0C5CE" "#525252" "brightblack" ))
+ (base6 '("#CDD3DE" "#6b6b6b" "brightblack" ))
+ (base7 '("#D8DEE9" "#979797" "white" ))
+ (base8 base7)
+ (fg-alt base6)
+ (fg base8)
+
+ (grey base4)
+ (red '("#EC5f67" "#EC5f67" "red" ))
+ (orange '("#F99157" "#F99157" "brightred" ))
+ (green '("#99C794" "#99bb66" "green" ))
+ (teal '("#5FB3B3" "#44b9b1" "brightgreen" ))
+ (yellow '("#FAC863" "#ECBE7B" "yellow" ))
+ (blue '("#6699CC" "#51afef" "brightblue" ))
+ (dark-blue blue)
+ (magenta '("#E27E8D" "#c678dd" "magenta" ))
+ (violet '("#C594C5" "#a9a1e1" "brightmagenta"))
+ (cyan teal)
+ (dark-cyan cyan)
+
+ ;; face categories -- required for all themes
+ (highlight yellow)
+ (vertical-bar (doom-darken base1 0.5))
+ (selection base2)
+ (builtin red)
+ (comments (if doom-oceanic-next-brighter-comments dark-cyan base3))
+ (doc-comments (doom-lighten (if doom-oceanic-next-brighter-comments dark-cyan base3) 0.25))
+ (constants orange)
+ (functions blue)
+ (keywords violet)
+ (methods blue)
+ (operators teal)
+ (type yellow)
+ (strings green)
+ (variables orange)
+ (numbers orange)
+ (region base2)
+ (error red)
+ (warning yellow)
+ (success green)
+ (vc-modified orange)
+ (vc-added green)
+ (vc-deleted red)
+
+ ;; custom categories
+ (hidden `(,(car bg) "black" "black"))
+ (-modeline-bright doom-oceanic-next-brighter-modeline)
+ (-modeline-pad
+ (when doom-oceanic-next-padded-modeline
+ (if (integerp doom-oceanic-next-padded-modeline) doom-oceanic-next-padded-modeline 4)))
+
+ (modeline-fg nil)
+ (modeline-fg-alt base5)
+
+ (modeline-bg
+ (if -modeline-bright
+ (doom-darken blue 0.45)
+ `(,(doom-darken (car bg-alt) 0.1) ,@(cdr base0))))
+ (modeline-bg-l
+ (if -modeline-bright
+ (doom-darken blue 0.475)
+ `(,(doom-darken (car bg-alt) 0.15) ,@(cdr base0))))
+ (modeline-bg-inactive `(,(car bg-alt) ,@(cdr base1)))
+ (modeline-bg-inactive-l `(,(doom-darken (car bg-alt) 0.1) ,@(cdr bg-alt))))
+
+
+ ;;;; Base theme face overrides
+ (
+
+ ((line-number &override) :foreground base4)
+ ((line-number-current-line &override) :foreground fg)
+ ((font-lock-comment-face &override)
+ :background (if doom-oceanic-next-comment-bg (doom-lighten bg 0.05)))
+
+ (mode-line
+ :background modeline-bg :foreground modeline-fg
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg)))
+ (mode-line-inactive
+ :background modeline-bg-inactive :foreground modeline-fg-alt
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive)))
+ (mode-line-emphasis :foreground (if -modeline-bright base8 highlight))
+
+ ;;;; VCS/magit readability
+ (diff-refine-removed :foreground vc-deleted :background bg :inverse-video t)
+ (diff-refine-added :foreground vc-added :background bg :inverse-video t)
+
+ (magit-diff-removed-highlight :foreground vc-deleted :background base1 :weight 'bold)
+
+ (magit-diff-base :foreground vc-modified :background bg-alt)
+ (magit-diff-removed :foreground vc-deleted :background base1)
+ (magit-diff-added :foreground vc-added :background base1)
+
+ ;;;; css-mode <built-in> / scss-mode
+ (css-proprietary-property :foreground orange)
+ (css-property :foreground green)
+ (css-selector :foreground blue)
+ ;;;; doom-modeline
+ (doom-modeline-bar :background (if -modeline-bright modeline-bg highlight))
+ (doom-modeline-buffer-file :inherit 'mode-line-buffer-id :weight 'bold)
+ (doom-modeline-buffer-path :inherit 'mode-line-emphasis :weight 'bold)
+ (doom-modeline-buffer-project-root :foreground green :weight 'bold)
+ ;;;; elscreen
+ (elscreen-tab-other-screen-face :background "#353a42" :foreground "#1e2022")
+ ;;;; markdown-mode
+ (markdown-markup-face :foreground base5)
+ (markdown-header-face :inherit 'bold :foreground blue)
+ ((markdown-code-face &override) :background (doom-lighten bg 0.05))
+ ;;;; ivy
+ (ivy-current-match :background base2 :distant-foreground base0 :weight 'bold)
+ ;;;; org <built-in>
+ ((org-block &override) :background bg-alt)
+ ((org-block-begin-line &override) :background bg-alt)
+ ((org-block-end-line &override) :background bg-alt)
+ (org-hide :foreground hidden)
+ ;;;; solaire-mode
+ (solaire-mode-line-face
+ :inherit 'mode-line
+ :background modeline-bg-l
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-l)))
+ (solaire-mode-line-inactive-face
+ :inherit 'mode-line-inactive
+ :background modeline-bg-inactive-l
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive-l))))
+
+ ;;;; Base theme variable overrides-
+ ()
+ )
+
+;;; doom-oceanic-next-theme.el ends here
diff --git a/elpa/doom-themes-20220504.1557/doom-old-hope-theme.el b/elpa/doom-themes-20220504.1557/doom-old-hope-theme.el
new file mode 100644
index 0000000..37e75c7
--- /dev/null
+++ b/elpa/doom-themes-20220504.1557/doom-old-hope-theme.el
@@ -0,0 +1,210 @@
+;;; doom-one-theme.el --- inspired by An Old Hope -*- lexical-binding: t; no-byte-compile: t; -*-
+(require 'doom-themes)
+
+;;
+(defgroup doom-old-hope-theme nil
+ "Options for the `doom-old-hope' theme."
+ :group 'doom-themes)
+
+(defcustom doom-old-hope-brighter-modeline nil
+ "If non-nil, more vivid colors will be used to style the mode-line."
+ :group 'doom-one-theme
+ :type 'boolean)
+
+(defcustom doom-old-hope-brighter-comments nil
+ "If non-nil, comments will be highlighted in more vivid colors."
+ :group 'doom-old-hope-theme
+ :type 'boolean)
+
+(defcustom doom-old-hope-comment-bg doom-old-hope-brighter-comments
+ "If non-nil, comments will have a subtle, darker background. Enhancing their
+legibility."
+ :group 'doom-old-hope-theme
+ :type 'boolean)
+
+(defcustom doom-old-hope-padded-modeline doom-themes-padded-modeline
+ "If non-nil, adds a 4px padding to the mode-line. Can be an integer to
+determine the exact padding."
+ :group 'doom-old-hope-theme
+ :type '(choice integer boolean))
+
+;;
+(def-doom-theme doom-old-hope
+ "A dark theme inspired by An Old Hope"
+
+ ;; name default 256 16
+ ((bg '("#1c1d20" "#1c1d20" nil))
+ (bg-alt '("#151619" "#151619" nil))
+ (base0 '("#1B2229" "black" "black"))
+ (base1 '("#1c1f24" "#1e1e1e" "brightblack"))
+ (base2 '("#202328" "#2e2e2e" "brightblack"))
+ (base3 '("#23272e" "#262626" "brightblack"))
+ (base4 '("#3f444a" "#3f3f3f" "brightblack"))
+ (base5 '("#5B6268" "#525252" "brightblack"))
+ (base6 '("#686b78" "#686b78" "brightblack"))
+ (base7 '("#9ca0a4" "#979797" "brightblack"))
+ (base8 '("#DFDFDF" "#dfdfdf" "white"))
+ (fg '("#cbccd1" "#cbccd1" "brightwhite"))
+ (fg-alt '("#5B6268" "#2d2d2d" "white"))
+
+ (grey base4)
+ (red '("#ea3d54" "#ea3d54" "red"))
+ (orange '("#ee7b29" "#ee7b29" "brightred"))
+ (green '("#78bd65" "#78bd65" "green"))
+ (teal '("#78bd65" "#78bd65" "brightgreen"))
+ (yellow '("#fedd38" "#fedd38" "yellow"))
+ (blue '("#4fb3d8" "#4fb3d8" "brightblue"))
+ (dark-blue '("#5689f0" "#5689f0" "blue"))
+ (magenta '("#b978ab" "#b978ab" "brightmagenta"))
+ (violet '("#b978ab" "#b978ab" "brightmagenta"))
+ (cyan '("#4fb3d8" "#4fb3d8" "brightcyan"))
+ (dark-cyan '("#4fb3d8" "#4fb3d8" "cyan"))
+
+ ;; face categories -- required for all themes
+ (highlight yellow)
+ (vertical-bar (doom-darken base4 0.2))
+ (selection red)
+ (builtin yellow)
+ (comments base5)
+ (doc-comments (doom-lighten blue 0.25))
+ (constants orange)
+ (functions yellow)
+ (keywords red)
+ (methods yellow)
+ (operators green)
+ (type orange)
+ (strings blue)
+ (variables fg)
+ (numbers orange)
+ (region `(,(doom-lighten (car bg-alt) 0.15) ,@(doom-lighten (cdr base1) 0.35)))
+ (error red)
+ (warning yellow)
+ (success green)
+ (vc-modified orange)
+ (vc-added green)
+ (vc-deleted red)
+
+
+ ;; custom categories
+ (hidden `(,(car bg) "black" "black"))
+ (-modeline-bright doom-old-hope-brighter-modeline)
+ (-modeline-pad
+ (when doom-old-hope-padded-modeline
+ (if (integerp doom-old-hope-padded-modeline) doom-old-hope-padded-modeline 4)))
+
+ (modeline-fg fg)
+ (modeline-fg-alt base5)
+
+ (modeline-bg
+ (if -modeline-bright
+ (doom-darken blue 0.475)
+ `(,(doom-darken (car bg-alt) 0.35) ,@(cdr base0))))
+ (modeline-bg-l
+ (if -modeline-bright
+ (doom-darken blue 0.45)
+ `(,(doom-darken (car bg-alt) 0.1) ,@(cdr base0))))
+ (modeline-bg-inactive `(,(doom-darken (car bg) 0.03) ,@(cdr bg-alt)))
+ (modeline-bg-inactive-l `(,(car bg-alt) ,@(cdr base1))))
+
+
+ ;;;; Base theme face overrides
+ (
+ ((line-number &override) :foreground base4)
+ ((line-number-current-line &override) :foreground fg)
+ ((font-lock-comment-face &override)
+ :background (if doom-old-hope-comment-bg (doom-lighten bg 0.05)))
+ (mode-line
+ :background modeline-bg :foreground modeline-fg
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg)))
+ (mode-line-inactive
+ :background modeline-bg-inactive :foreground modeline-fg-alt
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive)))
+ (mode-line-emphasis :foreground (if -modeline-bright base8 highlight))
+
+ ;;;; css-mode <built-in> / scss-mode
+ (css-proprietary-property :foreground orange)
+ (css-property :foreground green)
+ (css-selector :foreground blue)
+ ;;;; doom-modeline
+ (doom-modeline-bar :background (if -modeline-bright modeline-bg highlight))
+ (doom-modeline-buffer-file :inherit 'mode-line-buffer-id :weight 'bold)
+ (doom-modeline-buffer-path :inherit 'mode-line-emphasis :weight 'bold)
+ (doom-modeline-buffer-project-root :foreground green :weight 'bold)
+ ;;;; elscreen
+ (elscreen-tab-other-screen-face :background "#353a42" :foreground "#1e2022")
+ ;;;; ivy
+ (ivy-current-match :background base3 :foreground orange)
+ (ivy-posframe-cursor :background red :foreground base0)
+ ;;;; js2-mode
+ (js2-function-name :forground yellow)
+ (js2-function-param :foreground blue)
+ (js2-warning :underline `(:style wave :color ,yellow))
+ (js2-error :underline `(:style wave :color ,red))
+ (js2-external-variable :underline `(:style wave :color ,blue))
+ (js2-jsdoc-tag :background nil :foreground red)
+ (js2-jsdoc-type :background nil :foreground orange)
+ (js2-jsdoc-value :background nil :foreground blue)
+ (js2-private-member :background nil :foreground orange)
+ (js2-object-property :foreground fg)
+ ;;;; LaTeX-mode
+ (font-latex-math-face :foreground green)
+ ;;;; markdown-mode
+ (markdown-markup-face :foreground base5)
+ (markdown-header-face :inherit 'bold :foreground red)
+ ((markdown-code-face &override) :background (doom-lighten base3 0.05))
+ ;;;; markdown-mode
+ (markdown-list-face :foreground green)
+ (markdown-pre-face :foreground blue)
+ (markdown-blockquote-face :inherit 'italic :foreground blue)
+ (markdown-link-face :inherit 'bold :foreground orange)
+ (markdown-header-face-1 :weight 'bold :foreground blue)
+ (markdown-header-face-2 :weight 'bold :foreground orange)
+ (markdown-header-face-3 :weight 'bold :foreground green)
+ (markdown-header-face-4 :weight 'bold :foreground yellow)
+ (markdown-header-face-5 :weight 'bold :foreground blue)
+ (markdown-header-face-6 :weight 'bold :foreground orange)
+ ;;;; outline <built-in>
+ (outline-1 :foreground blue)
+ (outline-2 :foreground orange)
+ (outline-3 :foreground teal)
+ (outline-4 :foreground magenta)
+ (outline-5 :foreground blue)
+ (outline-6 :foreground orange)
+ (outline-7 :foreground teal)
+ (outline-8 :foreground magenta)
+ ;;;; org <built-in>
+ (org-link :foreground blue :underline t)
+ (org-document-title :foreground orange)
+ (org-document-info-keyword :foreground comments)
+ (org-meta-line :foreground base6)
+ (org-tag :foreground base6 :weight 'normal)
+ (org-block :background (doom-darken bg 0.2 ) :extend t)
+ (org-hide :foreground hidden)
+ ;;;; rainbow-delimiters
+ (rainbow-delimiters-depth-1-face :foreground red)
+ (rainbow-delimiters-depth-2-face :foreground orange)
+ (rainbow-delimiters-depth-3-face :foreground green)
+ (rainbow-delimiters-depth-4-face :foreground cyan)
+ (rainbow-delimiters-depth-5-face :foreground blue)
+ (rainbow-delimiters-depth-6-face :foreground yellow)
+ (rainbow-delimiters-depth-7-face :foreground green)
+ ;;;; rjsx-mode
+ (rjsx-tag :foreground fg)
+ (rjsx-attr :foreground orange :slant 'italic :weight 'medium)
+ (rjsx-tag-bracket-face :foreground green)
+ ;;;; solaire-mode
+ (solaire-mode-line-face
+ :inherit 'mode-line
+ :background modeline-bg-l
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-l)))
+ (solaire-mode-line-inactive-face
+ :inherit 'mode-line-inactive
+ :background modeline-bg-inactive-l
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive-l)))
+ ;;;; web-mode
+ (web-mode-html-tag-face :foreground fg :slant 'italic))
+
+ ;;;; Base theme variable overrides-
+ ())
+
+;;; doom-old-hope-theme.el ends here
diff --git a/elpa/doom-themes-20220504.1557/doom-one-light-theme.el b/elpa/doom-themes-20220504.1557/doom-one-light-theme.el
new file mode 100644
index 0000000..1de09aa
--- /dev/null
+++ b/elpa/doom-themes-20220504.1557/doom-one-light-theme.el
@@ -0,0 +1,208 @@
+;;; doom-one-light-theme.el --- inspired by Atom One Light -*- lexical-binding: t; no-byte-compile: t; -*-
+;;
+;; Copyright (C) 2016-2022 Henrik Lissner
+;;
+;; Author: Henrik Lissner <contact@henrik.io>
+;; Maintainer: Henrik Lissner <contact@henrik.io>
+;; Created: May 23, 2016
+;;
+;;; Commentary:
+;;
+;; Inspired by Atom's One Light color scheme.
+;;
+;;; Code:
+
+(require 'doom-themes)
+
+
+;;
+;;; Variables
+
+(defgroup doom-one-light-theme nil
+ "Options for the `doom-one-light' theme."
+ :group 'doom-themes)
+
+(defcustom doom-one-light-brighter-modeline nil
+ "If non-nil, more vivid colors will be used to style the mode-line."
+ :group 'doom-one-light-theme
+ :type 'boolean)
+
+(defcustom doom-one-light-brighter-comments nil
+ "If non-nil, comments will be highlighted in more vivid colors."
+ :group 'doom-one-light-theme
+ :type 'boolean)
+
+(defcustom doom-one-light-padded-modeline doom-themes-padded-modeline
+ "If non-nil, adds a 4px padding to the mode-line.
+Can be an integer to determine the exact padding."
+ :group 'doom-one-light-theme
+ :type '(choice integer boolean))
+
+
+;;
+;;; Theme definition
+
+(def-doom-theme doom-one-light
+ "A light theme inspired by Atom One Light."
+
+ ;; name default 256 16
+ ((bg '("#fafafa" "white" "white" ))
+ (fg '("#383a42" "#424242" "black" ))
+
+ ;; These are off-color variants of bg/fg, used primarily for `solaire-mode',
+ ;; but can also be useful as a basis for subtle highlights (e.g. for hl-line
+ ;; or region), especially when paired with the `doom-darken', `doom-lighten',
+ ;; and `doom-blend' helper functions.
+ (bg-alt '("#f0f0f0" "white" "white" ))
+ (fg-alt '("#c6c7c7" "#c7c7c7" "brightblack" ))
+
+ ;; These should represent a spectrum from bg to fg, where base0 is a starker
+ ;; bg and base8 is a starker fg. For example, if bg is light grey and fg is
+ ;; dark grey, base0 should be white and base8 should be black.
+ (base0 '("#f0f0f0" "#f0f0f0" "white" ))
+ (base1 '("#e7e7e7" "#e7e7e7" "brightblack" ))
+ (base2 '("#dfdfdf" "#dfdfdf" "brightblack" ))
+ (base3 '("#c6c7c7" "#c6c7c7" "brightblack" ))
+ (base4 '("#9ca0a4" "#9ca0a4" "brightblack" ))
+ (base5 '("#383a42" "#424242" "brightblack" ))
+ (base6 '("#202328" "#2e2e2e" "brightblack" ))
+ (base7 '("#1c1f24" "#1e1e1e" "brightblack" ))
+ (base8 '("#1b2229" "black" "black" ))
+
+ (grey base4)
+ (red '("#e45649" "#e45649" "red" ))
+ (orange '("#da8548" "#dd8844" "brightred" ))
+ (green '("#50a14f" "#50a14f" "green" ))
+ (teal '("#4db5bd" "#44b9b1" "brightgreen" ))
+ (yellow '("#986801" "#986801" "yellow" ))
+ (blue '("#4078f2" "#4078f2" "brightblue" ))
+ (dark-blue '("#a0bcf8" "#a0bcf8" "blue" ))
+ (magenta '("#a626a4" "#a626a4" "magenta" ))
+ (violet '("#b751b6" "#b751b6" "brightmagenta"))
+ (cyan '("#0184bc" "#0184bc" "brightcyan" ))
+ (dark-cyan '("#005478" "#005478" "cyan" ))
+
+ ;; These are the "universal syntax classes" that doom-themes establishes.
+ ;; These *must* be included in every doom themes, or your theme will throw an
+ ;; error, as they are used in the base theme defined in doom-themes-base.
+ (highlight blue)
+ (vertical-bar (doom-darken base2 0.1))
+ (selection dark-blue)
+ (builtin magenta)
+ (comments (if doom-one-light-brighter-comments cyan base4))
+ (doc-comments (doom-darken comments 0.15))
+ (constants violet)
+ (functions magenta)
+ (keywords red)
+ (methods cyan)
+ (operators blue)
+ (type yellow)
+ (strings green)
+ (variables (doom-darken magenta 0.36))
+ (numbers orange)
+ (region `(,(doom-darken (car bg-alt) 0.1) ,@(doom-darken (cdr base0) 0.3)))
+ (error red)
+ (warning yellow)
+ (success green)
+ (vc-modified orange)
+ (vc-added green)
+ (vc-deleted red)
+
+ ;; These are extra color variables used only in this theme; i.e. they aren't
+ ;; mandatory for derived themes.
+ (modeline-fg fg)
+ (modeline-fg-alt (doom-blend
+ violet base4
+ (if doom-one-light-brighter-modeline 0.5 0.2)))
+ (modeline-bg (if doom-one-light-brighter-modeline
+ (doom-darken base2 0.05)
+ base1))
+ (modeline-bg-alt (if doom-one-light-brighter-modeline
+ (doom-darken base2 0.1)
+ base2))
+ (modeline-bg-inactive (doom-darken bg 0.1))
+ (modeline-bg-alt-inactive `(,(doom-darken (car bg-alt) 0.05) ,@(cdr base1)))
+
+ (-modeline-pad
+ (when doom-one-light-padded-modeline
+ (if (integerp doom-one-light-padded-modeline) doom-one-light-padded-modeline 4))))
+
+ ;;;; Base theme face overrides
+ (((font-lock-comment-face &override)
+ :background (if doom-one-light-brighter-comments base0))
+ ((font-lock-doc-face &override) :slant 'italic)
+ ((line-number &override) :foreground (doom-lighten base4 0.15))
+ ((line-number-current-line &override) :foreground base8)
+ (mode-line
+ :background modeline-bg :foreground modeline-fg
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg)))
+ (mode-line-inactive
+ :background modeline-bg-inactive :foreground modeline-fg-alt
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive)))
+ (mode-line-emphasis
+ :foreground (if doom-one-light-brighter-modeline base8 highlight))
+ (shadow :foreground base4)
+ (tooltip :background base1 :foreground fg)
+
+ ;;;; centaur-tabs
+ (centaur-tabs-unselected :background bg-alt :foreground base4)
+ ;;;; css-mode <built-in> / scss-mode
+ (css-proprietary-property :foreground orange)
+ (css-property :foreground green)
+ (css-selector :foreground blue)
+ ;;;; doom-modeline
+ (doom-modeline-bar :background (if doom-one-light-brighter-modeline modeline-bg highlight))
+ ;;;; ediff <built-in>
+ (ediff-current-diff-A :foreground red :background (doom-lighten red 0.8))
+ (ediff-current-diff-B :foreground green :background (doom-lighten green 0.8))
+ (ediff-current-diff-C :foreground blue :background (doom-lighten blue 0.8))
+ (ediff-current-diff-Ancestor :foreground teal :background (doom-lighten teal 0.8))
+ ;;;; helm
+ (helm-candidate-number :background blue :foreground bg)
+ ;;;; lsp-mode
+ (lsp-ui-doc-background :background base0)
+ ;;;; magit
+ (magit-blame-heading :foreground orange :background bg-alt)
+ (magit-diff-removed :foreground (doom-darken red 0.2) :background (doom-blend red bg 0.1))
+ (magit-diff-removed-highlight :foreground red :background (doom-blend red bg 0.2) :bold bold)
+ ;;;; markdown-mode
+ (markdown-markup-face :foreground base5)
+ (markdown-header-face :inherit 'bold :foreground red)
+ ((markdown-code-face &override) :background base1)
+ (mmm-default-submode-face :background base1)
+ ;;;; outline <built-in>
+ ((outline-1 &override) :foreground red)
+ ((outline-2 &override) :foreground orange)
+ ;;;; org <built-in>
+ ((org-block &override) :background base1)
+ ((org-block-begin-line &override) :foreground fg :slant 'italic)
+ (org-ellipsis :underline nil :background bg :foreground red)
+ ((org-quote &override) :background base1)
+ ;;;; posframe
+ (ivy-posframe :background base0)
+ ;;;; selectrum
+ (selectrum-current-candidate :background base1)
+ ;;;; vertico
+ (vertico-current :background base1)
+ ;;;; solaire-mode
+ (solaire-mode-line-face
+ :inherit 'mode-line
+ :background modeline-bg-alt
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-alt)))
+ (solaire-mode-line-inactive-face
+ :inherit 'mode-line-inactive
+ :background modeline-bg-alt-inactive
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-alt-inactive)))
+ ;;;; web-mode
+ (web-mode-current-element-highlight-face :background dark-blue :foreground bg)
+ ;;;; wgrep <built-in>
+ (wgrep-face :background base1)
+ ;;;; whitespace
+ ((whitespace-tab &override) :background (unless (default-value 'indent-tabs-mode) base0))
+ ((whitespace-indentation &override) :background (if (default-value 'indent-tabs-mode) base0)))
+
+ ;;;; Base theme variable overrides-
+ ()
+ )
+
+;;; doom-one-light-theme.el ends here
diff --git a/elpa/doom-themes-20220504.1557/doom-one-theme.el b/elpa/doom-themes-20220504.1557/doom-one-theme.el
new file mode 100644
index 0000000..d20bb22
--- /dev/null
+++ b/elpa/doom-themes-20220504.1557/doom-one-theme.el
@@ -0,0 +1,177 @@
+;;; doom-one-theme.el --- inspired by Atom One Dark -*- lexical-binding: t; no-byte-compile: t; -*-
+;;
+;; Copyright (C) 2016-2022 Henrik Lissner
+;;
+;; Author: Henrik Lissner <contact@henrik.io>
+;; Maintainer: Henrik Lissner <contact@henrik.io>
+;; Created: May 23, 2016
+;;
+;;; Commentary:
+;;
+;; Inspired by Atom's One Dark color scheme.
+;;
+;;; Code:
+
+(require 'doom-themes)
+
+
+;;
+;;; Variables
+
+(defgroup doom-one-theme nil
+ "Options for the `doom-one' theme."
+ :group 'doom-themes)
+
+(defcustom doom-one-brighter-modeline nil
+ "If non-nil, more vivid colors will be used to style the mode-line."
+ :group 'doom-one-theme
+ :type 'boolean)
+
+(defcustom doom-one-brighter-comments nil
+ "If non-nil, comments will be highlighted in more vivid colors."
+ :group 'doom-one-theme
+ :type 'boolean)
+
+(defcustom doom-one-padded-modeline doom-themes-padded-modeline
+ "If non-nil, adds a 4px padding to the mode-line.
+Can be an integer to determine the exact padding."
+ :group 'doom-one-theme
+ :type '(choice integer boolean))
+
+
+;;
+;;; Theme definition
+
+(def-doom-theme doom-one
+ "A dark theme inspired by Atom One Dark."
+
+ ;; name default 256 16
+ ((bg '("#282c34" "black" "black" ))
+ (fg '("#bbc2cf" "#bfbfbf" "brightwhite" ))
+
+ ;; These are off-color variants of bg/fg, used primarily for `solaire-mode',
+ ;; but can also be useful as a basis for subtle highlights (e.g. for hl-line
+ ;; or region), especially when paired with the `doom-darken', `doom-lighten',
+ ;; and `doom-blend' helper functions.
+ (bg-alt '("#21242b" "black" "black" ))
+ (fg-alt '("#5B6268" "#2d2d2d" "white" ))
+
+ ;; These should represent a spectrum from bg to fg, where base0 is a starker
+ ;; bg and base8 is a starker fg. For example, if bg is light grey and fg is
+ ;; dark grey, base0 should be white and base8 should be black.
+ (base0 '("#1B2229" "black" "black" ))
+ (base1 '("#1c1f24" "#1e1e1e" "brightblack" ))
+ (base2 '("#202328" "#2e2e2e" "brightblack" ))
+ (base3 '("#23272e" "#262626" "brightblack" ))
+ (base4 '("#3f444a" "#3f3f3f" "brightblack" ))
+ (base5 '("#5B6268" "#525252" "brightblack" ))
+ (base6 '("#73797e" "#6b6b6b" "brightblack" ))
+ (base7 '("#9ca0a4" "#979797" "brightblack" ))
+ (base8 '("#DFDFDF" "#dfdfdf" "white" ))
+
+ (grey base4)
+ (red '("#ff6c6b" "#ff6655" "red" ))
+ (orange '("#da8548" "#dd8844" "brightred" ))
+ (green '("#98be65" "#99bb66" "green" ))
+ (teal '("#4db5bd" "#44b9b1" "brightgreen" ))
+ (yellow '("#ECBE7B" "#ECBE7B" "yellow" ))
+ (blue '("#51afef" "#51afef" "brightblue" ))
+ (dark-blue '("#2257A0" "#2257A0" "blue" ))
+ (magenta '("#c678dd" "#c678dd" "brightmagenta"))
+ (violet '("#a9a1e1" "#a9a1e1" "magenta" ))
+ (cyan '("#46D9FF" "#46D9FF" "brightcyan" ))
+ (dark-cyan '("#5699AF" "#5699AF" "cyan" ))
+
+ ;; These are the "universal syntax classes" that doom-themes establishes.
+ ;; These *must* be included in every doom themes, or your theme will throw an
+ ;; error, as they are used in the base theme defined in doom-themes-base.
+ (highlight blue)
+ (vertical-bar (doom-darken base1 0.1))
+ (selection dark-blue)
+ (builtin magenta)
+ (comments (if doom-one-brighter-comments dark-cyan base5))
+ (doc-comments (doom-lighten (if doom-one-brighter-comments dark-cyan base5) 0.25))
+ (constants violet)
+ (functions magenta)
+ (keywords blue)
+ (methods cyan)
+ (operators blue)
+ (type yellow)
+ (strings green)
+ (variables (doom-lighten magenta 0.4))
+ (numbers orange)
+ (region `(,(doom-lighten (car bg-alt) 0.15) ,@(doom-lighten (cdr base1) 0.35)))
+ (error red)
+ (warning yellow)
+ (success green)
+ (vc-modified orange)
+ (vc-added green)
+ (vc-deleted red)
+
+ ;; These are extra color variables used only in this theme; i.e. they aren't
+ ;; mandatory for derived themes.
+ (modeline-fg fg)
+ (modeline-fg-alt base5)
+ (modeline-bg (if doom-one-brighter-modeline
+ (doom-darken blue 0.45)
+ (doom-darken bg-alt 0.1)))
+ (modeline-bg-alt (if doom-one-brighter-modeline
+ (doom-darken blue 0.475)
+ `(,(doom-darken (car bg-alt) 0.15) ,@(cdr bg))))
+ (modeline-bg-inactive `(,(car bg-alt) ,@(cdr base1)))
+ (modeline-bg-inactive-alt `(,(doom-darken (car bg-alt) 0.1) ,@(cdr bg)))
+
+ (-modeline-pad
+ (when doom-one-padded-modeline
+ (if (integerp doom-one-padded-modeline) doom-one-padded-modeline 4))))
+
+
+ ;;;; Base theme face overrides
+ (((line-number &override) :foreground base4)
+ ((line-number-current-line &override) :foreground fg)
+ ((font-lock-comment-face &override)
+ :background (if doom-one-brighter-comments (doom-lighten bg 0.05)))
+ (mode-line
+ :background modeline-bg :foreground modeline-fg
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg)))
+ (mode-line-inactive
+ :background modeline-bg-inactive :foreground modeline-fg-alt
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive)))
+ (mode-line-emphasis :foreground (if doom-one-brighter-modeline base8 highlight))
+
+ ;;;; css-mode <built-in> / scss-mode
+ (css-proprietary-property :foreground orange)
+ (css-property :foreground green)
+ (css-selector :foreground blue)
+ ;;;; doom-modeline
+ (doom-modeline-bar :background (if doom-one-brighter-modeline modeline-bg highlight))
+ (doom-modeline-buffer-file :inherit 'mode-line-buffer-id :weight 'bold)
+ (doom-modeline-buffer-path :inherit 'mode-line-emphasis :weight 'bold)
+ (doom-modeline-buffer-project-root :foreground green :weight 'bold)
+ ;;;; elscreen
+ (elscreen-tab-other-screen-face :background "#353a42" :foreground "#1e2022")
+ ;;;; ivy
+ (ivy-current-match :background dark-blue :distant-foreground base0 :weight 'normal)
+ ;;;; LaTeX-mode
+ (font-latex-math-face :foreground green)
+ ;;;; markdown-mode
+ (markdown-markup-face :foreground base5)
+ (markdown-header-face :inherit 'bold :foreground red)
+ ((markdown-code-face &override) :background (doom-lighten base3 0.05))
+ ;;;; rjsx-mode
+ (rjsx-tag :foreground red)
+ (rjsx-attr :foreground orange)
+ ;;;; solaire-mode
+ (solaire-mode-line-face
+ :inherit 'mode-line
+ :background modeline-bg-alt
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-alt)))
+ (solaire-mode-line-inactive-face
+ :inherit 'mode-line-inactive
+ :background modeline-bg-inactive-alt
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive-alt))))
+
+ ;;;; Base theme variable overrides-
+ ())
+
+;;; doom-one-theme.el ends here
diff --git a/elpa/doom-themes-20220504.1557/doom-opera-light-theme.el b/elpa/doom-themes-20220504.1557/doom-opera-light-theme.el
new file mode 100644
index 0000000..c47c0df
--- /dev/null
+++ b/elpa/doom-themes-20220504.1557/doom-opera-light-theme.el
@@ -0,0 +1,144 @@
+;;; doom-opera-light-theme.el --- Opera-Light theme -*- lexical-binding: t; no-byte-compile: t; -*-
+
+(require 'doom-themes)
+
+(defgroup doom-opera-light-theme nil
+ "Options for the `doom-opera-light' theme."
+ :group 'doom-themes)
+
+(defcustom doom-opera-light-brighter-modeline nil
+ "If non-nil, more vivid colors will be used to style the mode-line."
+ :group 'doom-opera-light-theme
+ :type 'boolean)
+
+(defcustom doom-opera-light-brighter-comments nil
+ "If non-nil, comments will be highlighted in more vivid colors."
+ :group 'doom-opera-light-theme
+ :type 'boolean)
+
+(defcustom doom-opera-light-comment-bg doom-opera-light-brighter-comments
+ "If non-nil, comments will have a subtle, darker background. Enhancing their
+legibility."
+ :group 'doom-opera-light-theme
+ :type 'boolean)
+
+(defcustom doom-opera-light-padded-modeline doom-themes-padded-modeline
+ "If non-nil, adds a 4px padding to the mode-line. Can be an integer to
+determine the exact padding."
+ :group 'doom-opera-light-theme
+ :type '(choice integer boolean))
+
+(defcustom doom-opera-light-region-highlight t
+ "Determines the selection highlight style. Can be 'frost, 'snowstorm or t
+(default)."
+ :group 'doom-opera-light-theme
+ :type 'symbol)
+
+(def-doom-theme doom-opera-light
+ "A light Opera theme."
+
+ ;; name default 256 16
+ ((bg '("#fafafa" nil nil ))
+ (bg-alt '("#eeeeee" nil nil ))
+ (base0 '("#fafafa" "#dfdfdf" nil ))
+ (base1 '("#f5f5f5" "#979797" nil ))
+ (base2 '("#eeeeee" "#6b6b6b" nil ))
+ (base3 '("#e0e0e0" "#525252" nil ))
+ (base4 '("#bdbdbd" "#3f3f3f" nil ))
+ (base5 '("#9e9e9e" "#262626" nil ))
+ (base6 '("#757575" "#2e2e2e" nil ))
+ (base7 '("#616161" "#1e1e1e" nil ))
+ (base8 '("#424242" "black" nil ))
+ (fg '("#2a2a2a" "#2a2a2a" nil ))
+ (fg-alt '("#454545" "#757575" nil ))
+
+ (grey base4)
+ (red '("#99324b" "#ff6655" nil ))
+ (orange '("#ac4426" "#dd8844" nil ))
+ (green '("#4f894c" "#99bb66" nil ))
+ (teal '("#29838d" "#44b9b1" nil ))
+ (yellow '("#9a7500" "#ECBE7B" nil ))
+ (blue '("#3b6ea8" "#51afef" nil ))
+ (dark-blue '("#5272AF" "#2257A0" nil ))
+ (magenta '("#97365b" "#c678dd" nil ))
+ (violet '("#842879" "#a9a1e1" nil ))
+ (cyan '("#398eac" "#46D9FF" nil ))
+ (dark-cyan '("#2c7088" "#5699AF" nil ))
+
+ ;; face categories -- required for all themes
+ (highlight blue)
+ (vertical-bar (doom-darken base1 0.2))
+ (selection dark-blue)
+ (builtin teal)
+ (comments (if doom-opera-light-brighter-comments dark-cyan (doom-lighten base5 0.2)))
+ (doc-comments (doom-lighten (if doom-opera-light-brighter-comments dark-cyan base5) 0.25))
+ (constants magenta)
+ (functions teal)
+ (keywords blue)
+ (methods teal)
+ (operators blue)
+ (type yellow)
+ (strings green)
+ (variables (doom-lighten magenta 0.5))
+ (numbers magenta)
+ (region base4)
+ (error red)
+ (warning yellow)
+ (success green)
+ (vc-modified orange)
+ (vc-added green)
+ (vc-deleted red)
+
+ ;; custom categories
+ (hidden `(,(car bg) "black" "black"))
+ (-modeline-bright doom-opera-light-brighter-modeline)
+ (-modeline-pad
+ (when doom-opera-light-padded-modeline
+ (if (integerp doom-opera-light-padded-modeline) doom-opera-light-padded-modeline 4)))
+
+ (modeline-fg nil)
+ (modeline-fg-alt base5)
+
+ (modeline-bg
+ (if -modeline-bright
+ (doom-darken blue 0.45)
+ `(,(doom-darken (car bg-alt) 0.1) ,@(cdr base0))))
+ (modeline-bg-l
+ (if -modeline-bright
+ (doom-darken blue 0.475)
+ `(,(doom-darken (car bg-alt) 0.15) ,@(cdr base0))))
+ (modeline-bg-inactive `(,(car bg-alt) ,@(cdr base1)))
+ (modeline-bg-inactive-l (doom-darken bg-alt 0.1)))
+
+ ;;;; Base theme face overrides
+ (((font-lock-comment-face &override)
+ :background (if doom-opera-light-comment-bg (doom-lighten bg 0.05)))
+ (lazy-highlight :background (doom-blend bg highlight 0.7) :weight 'bold)
+ ((line-number &override) :foreground fg-alt)
+ ((line-number-current-line &override) :foreground fg)
+ (mode-line
+ :background modeline-bg :foreground modeline-fg
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg)))
+ (mode-line-inactive
+ :background modeline-bg-inactive :foreground modeline-fg-alt
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive)))
+ (mode-line-emphasis :foreground (if -modeline-bright base8 highlight))
+
+ ;;;; doom-modeline
+ (doom-modeline-bar :background (if -modeline-bright modeline-bg highlight))
+ ;;;; ivy
+ (ivy-current-match :background base3)
+ ;;;; ivy-posframe
+ (ivy-posframe :background bg-alt)
+ (ivy-posframe-border :background base1)
+ ;;;; solaire-mode
+ (solaire-mode-line-face
+ :inherit 'mode-line
+ :background modeline-bg-l
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-l)))
+ (solaire-mode-line-inactive-face
+ :inherit 'mode-line-inactive
+ :background modeline-bg-inactive-l
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive-l)))))
+
+;;; doom-opera-light-theme.el ends here
diff --git a/elpa/doom-themes-20220504.1557/doom-opera-theme.el b/elpa/doom-themes-20220504.1557/doom-opera-theme.el
new file mode 100644
index 0000000..7408115
--- /dev/null
+++ b/elpa/doom-themes-20220504.1557/doom-opera-theme.el
@@ -0,0 +1,141 @@
+;;; doom-opera-theme.el --- Opera theme -*- lexical-binding: t; no-byte-compile: t; -*-
+
+(require 'doom-themes)
+
+(defgroup doom-opera-theme nil
+ "Options for the `doom-opera' theme."
+ :group 'doom-themes)
+
+(defcustom doom-opera-brighter-modeline nil
+ "If non-nil, more vivid colors will be used to style the mode-line."
+ :group 'doom-opera-theme
+ :type 'boolean)
+
+(defcustom doom-opera-brighter-comments nil
+ "If non-nil, comments will be highlighted in more vivid colors."
+ :group 'doom-opera-theme
+ :type 'boolean)
+
+(defcustom doom-opera-comment-bg doom-opera-brighter-comments
+ "If non-nil, comments will have a subtle, darker background. Enhancing their
+legibility."
+ :group 'doom-opera-theme
+ :type 'boolean)
+
+(defcustom doom-opera-padded-modeline doom-themes-padded-modeline
+ "If non-nil, adds a 4px padding to the mode-line. Can be an integer to
+determine the exact padding."
+ :group 'doom-opera-theme
+ :type '(choice integer boolean))
+
+(defcustom doom-opera-region-highlight t
+ "Determines the selection highlight style. Can be 'frost, 'snowstorm or t
+(default)."
+ :group 'doom-opera-theme
+ :type 'symbol)
+
+(def-doom-theme doom-opera
+ "A dark Opera theme."
+
+ ;; name default 256 16
+ ((bg '("#323334" nil nil ))
+ (bg-alt '("#222224" nil nil ))
+ (base0 '("#000000" "black" "black" ))
+ (base1 '("#1e1e1e" "#1e1e1e" "brightblack" ))
+ (base2 '("#2e2e2e" "#2e2e2e" "brightblack" ))
+ (base3 '("#262626" "#262626" "brightblack" ))
+ (base4 '("#3f3f3f" "#3f3f3f" "brightblack" ))
+ (base5 '("#525252" "#525252" "brightblack" ))
+ (base6 '("#6b6b6b" "#6b6b6b" "brightblack" ))
+ (base7 '("#979797" "#979797" "brightblack" ))
+ (base8 '("#dfdfdf" "#dfdfdf" "white" ))
+ (fg '("#eceff4" "#dfdfdf" "white" ))
+ (fg-alt '("#727269" "#bfbfbf" "brightwhite" ))
+
+ (grey base4)
+ (red '("#C16069" "#ff6655" "red" ))
+ (orange '("#D2876D" "#dd8844" "brightred" ))
+ (green '("#A2BF8A" "#99bb66" "green" ))
+ (teal '("#8EBCBB" "#44b9b1" "brightgreen" ))
+ (yellow '("#ECCC87" "#ECBE7B" "yellow" ))
+ (blue '("#80A0C2" "#51afef" "brightblue" ))
+ (dark-blue '("#5C748E" "#2257A0" "blue" ))
+ (magenta '("#B58DAE" "#c678dd" "magenta" ))
+ (violet '("#5D80AE" "#a9a1e1" "brightmagenta"))
+ (cyan '("#86C0D1" "#46D9FF" "brightcyan" ))
+ (dark-cyan '("#507681" "#5699AF" "cyan" ))
+
+ ;; face categories -- required for all themes
+ (highlight blue)
+ (vertical-bar (doom-darken base1 0.2))
+ (selection dark-blue)
+ (builtin teal)
+ (comments (if doom-opera-brighter-comments dark-cyan (doom-lighten base5 0.2)))
+ (doc-comments (doom-lighten (if doom-opera-brighter-comments dark-cyan base5) 0.25))
+ (constants magenta)
+ (functions teal)
+ (keywords blue)
+ (methods teal)
+ (operators blue)
+ (type yellow)
+ (strings green)
+ (variables (doom-lighten magenta 0.5))
+ (numbers magenta)
+ (region base4)
+ (error red)
+ (warning yellow)
+ (success green)
+ (vc-modified orange)
+ (vc-added green)
+ (vc-deleted red)
+
+ ;; custom categories
+ (hidden `(,(car bg) "black" "black"))
+ (-modeline-bright doom-opera-brighter-modeline)
+ (-modeline-pad
+ (when doom-opera-padded-modeline
+ (if (integerp doom-opera-padded-modeline) doom-opera-padded-modeline 4)))
+
+ (modeline-fg nil)
+ (modeline-fg-alt base5)
+
+ (modeline-bg
+ (if -modeline-bright
+ (doom-darken blue 0.45)
+ `(,(doom-darken (car bg-alt) 0.1) ,@(cdr base0))))
+ (modeline-bg-l
+ (if -modeline-bright
+ (doom-darken blue 0.475)
+ `(,(doom-darken (car bg-alt) 0.15) ,@(cdr base0))))
+ (modeline-bg-inactive `(,(car bg-alt) ,@(cdr base1)))
+ (modeline-bg-inactive-l (doom-darken bg-alt 0.1)))
+
+ ;;;; Base theme face overrides
+ (((line-number &override) :foreground fg-alt)
+ ((line-number-current-line &override) :foreground fg)
+ ((font-lock-comment-face &override)
+ :background (if doom-opera-comment-bg (doom-lighten bg 0.05)))
+ (mode-line
+ :background modeline-bg :foreground modeline-fg
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg)))
+ (mode-line-inactive
+ :background modeline-bg-inactive :foreground modeline-fg-alt
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive)))
+ (mode-line-emphasis :foreground (if -modeline-bright base8 highlight))
+
+ ;;;; doom-modeline
+ (doom-modeline-bar :background (if -modeline-bright modeline-bg highlight))
+ ;;;; solaire-mode
+ (solaire-mode-line-face
+ :inherit 'mode-line
+ :background modeline-bg-l
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-l)))
+ (solaire-mode-line-inactive-face
+ :inherit 'mode-line-inactive
+ :background modeline-bg-inactive-l
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive-l))))
+
+ ;;;; Base theme variable overrides-
+ ())
+
+;;; doom-opera-theme.el ends here
diff --git a/elpa/doom-themes-20220504.1557/doom-outrun-electric-theme.el b/elpa/doom-themes-20220504.1557/doom-outrun-electric-theme.el
new file mode 100644
index 0000000..e3805e7
--- /dev/null
+++ b/elpa/doom-themes-20220504.1557/doom-outrun-electric-theme.el
@@ -0,0 +1,176 @@
+;;; doom-outrun-electric-theme.el --- inspired by VS Code Outrun Electric -*- lexical-binding: t; no-byte-compile: t; -*-
+(require 'doom-themes)
+
+;;
+(defgroup doom-outrun-electric-theme nil
+ "Options for doom-themes."
+ :group 'doom-themes)
+
+(defcustom doom-outrun-electric-brighter-modeline nil
+ "If non-nil, more vivid colors will be used to style the mode-line."
+ :group 'doom-outrun-electric-theme
+ :type 'boolean)
+
+(defcustom doom-outrun-electric-brighter-comments nil
+ "If non-nil, comments will be highlighted in more vivid colors."
+ :group 'doom-outrun-electric-theme
+ :type 'boolean)
+
+(defcustom doom-outrun-electric-comment-bg doom-outrun-electric-brighter-comments
+ "If non-nil, comments will have a subtle, darker background. Enhancing their
+legibility."
+ :group 'doom-outrun-electric-theme
+ :type 'boolean)
+
+(defcustom doom-outrun-electric-padded-modeline doom-themes-padded-modeline
+ "If non-nil, adds a 4px padding to the mode-line. Can be an integer to
+determine the exact padding."
+ :group 'doom-outrun-electric-theme
+ :type '(choice integer boolean))
+
+;;
+(def-doom-theme doom-outrun-electric
+ "A vibrant, neon colored theme inspired by VS Code Outrun Electric."
+
+ ;; name default 256 16
+ ((bg '("#0c0a20" "#0c0a20" nil ))
+ (bg-alt '("#090819" "#090819" nil ))
+ (base0 '("#131033" "#131033" "black" ))
+ (base1 '("#1f1147" "#161130" "brightblack" ))
+ (base2 '("#110d26" "#110d26" "brightblack" ))
+ (base3 '("#3b4167" "#3b4167" "brightblack" ))
+ (base4 '("#2d2844" "#2d2844" "brightblack" ))
+ (base5 '("#BA45A3" "#BA45A3" "brightblack" ))
+ (base6 '("#6A6EA3" "#6A6EA3" "brightblack" ))
+ (base7 '("#6564D1" "#6564D1" "brightblack" ))
+ (base8 '("#919ad9" "#919ad9" "white" ))
+ (fg-alt '("#7984D1" "#7984D1" "white" ))
+ (fg '("#f2f3f7" "#f2f3f7" "brightwhite" ))
+
+ (grey '("#546A90" "#546A90" "gray" ))
+ (red '("#e61f44" "#e61f44" "red" ))
+ (orange '("#cf433e" "#ff9b50" "brightred" ))
+ (green '("#a7da1e" "#a7da1e" "green" ))
+ (teal '("#A875FF" "#A875FF" "brightgreen" ))
+ (yellow '("#ffd400" "#ffd400" "yellow" ))
+ (blue '("#1ea8fc" "#1ea8fc" "brightblue" ))
+ (dark-blue '("#3F88AD" "#3F88AD" "blue" ))
+ (magenta '("#ff2afc" "#ff2afc" "magenta" ))
+ (violet '("#df85ff" "#df85ff" "brightmagenta"))
+ (cyan '("#42c6ff" "#42c6ff" "brightcyan" ))
+ (dark-cyan '("#204052" "#204052" "cyan" ))
+
+ ;; face categories -- required for all themes
+ (highlight blue)
+ (vertical-bar (doom-darken base1 0.5))
+ (selection dark-blue)
+ (builtin blue)
+ (comments (if doom-outrun-electric-brighter-comments blue grey))
+ (doc-comments teal)
+ (constants violet)
+ (functions cyan)
+ (keywords magenta)
+ (methods cyan)
+ (operators magenta)
+ (type yellow)
+ (strings fg-alt)
+ (variables violet)
+ (numbers yellow)
+ (region base1)
+ (error red)
+ (warning yellow)
+ (success green)
+ (vc-modified orange)
+ (vc-added green)
+ (vc-deleted red)
+
+ ;; custom categories
+ (hidden `(,(car bg) "black" "black"))
+ (-modeline-bright doom-outrun-electric-brighter-modeline)
+ (-modeline-pad
+ (when doom-outrun-electric-padded-modeline
+ (if (integerp doom-outrun-electric-padded-modeline) doom-outrun-electric-padded-modeline 4)))
+
+ (modeline-fg nil)
+ (modeline-fg-alt base5)
+
+ (modeline-bg
+ (if -modeline-bright
+ base3
+ `(,(doom-darken (car bg) 0.1) ,@(cdr base0))))
+ (modeline-bg-l
+ (if -modeline-bright
+ base3
+ `(,(doom-darken (car bg) 0.15) ,@(cdr base0))))
+ (modeline-bg-inactive `(,(car bg) ,@(cdr base1)))
+ (modeline-bg-inactive-l (doom-darken bg 0.1)))
+
+
+ ;;;; Base theme face overrides
+ (((font-lock-comment-face &override)
+ :background (if doom-outrun-electric-comment-bg (doom-lighten bg 0.05)))
+ ((font-lock-keyword-face &override) :weight 'bold)
+ ((font-lock-constant-face &override) :weight 'bold)
+ ((font-lock-function-name-face &override) :foreground functions)
+ ((line-number &override) :foreground base4)
+ ((line-number-current-line &override) :foreground fg)
+ (mode-line
+ :background modeline-bg :foreground modeline-fg
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg)))
+ (mode-line-inactive
+ :background modeline-bg-inactive :foreground modeline-fg-alt
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive)))
+ (mode-line-emphasis :foreground (if -modeline-bright base8 highlight))
+ (mode-line-highlight :background magenta :foreground bg :weight 'bold)
+ (vertical-border :foreground base5)
+
+ ;;;; centaur-tabs
+ (centaur-tabs-active-bar-face :background magenta)
+ (centaur-tabs-modified-marker-selected :inherit 'centaur-tabs-selected :foreground magenta)
+ (centaur-tabs-modified-marker-unselected :inherit 'centaur-tabs-unselected :foreground magenta)
+ ;;;; company
+ (company-tooltip-selection :background dark-cyan)
+ (company-tooltip-common :foreground magenta :distant-foreground base0 :weight 'bold)
+ ;;;; css-mode <built-in> / scss-mode
+ (css-proprietary-property :foreground orange)
+ (css-property :foreground green)
+ (css-selector :foreground blue)
+ ;;;; doom-modeline
+ (doom-modeline-bar :background magenta)
+ ;;;; elscreen
+ (elscreen-tab-other-screen-face :background "#353a42" :foreground "#1e2022")
+ ;;;; markdown-mode
+ (markdown-markup-face :foreground base5)
+ (markdown-header-face :inherit 'bold :foreground red)
+ (markdown-url-face :foreground teal :weight 'normal)
+ (markdown-reference-face :foreground base6)
+ ((markdown-bold-face &override) :foreground fg)
+ ((markdown-italic-face &override) :foreground fg-alt)
+ ;;;; outline <built-in>
+ ((outline-1 &override) :foreground blue)
+ ((outline-2 &override) :foreground green)
+ ((outline-3 &override) :foreground teal)
+ ((outline-4 &override) :foreground (doom-darken blue 0.2))
+ ((outline-5 &override) :foreground (doom-darken green 0.2))
+ ((outline-6 &override) :foreground (doom-darken teal 0.2))
+ ((outline-7 &override) :foreground (doom-darken blue 0.4))
+ ((outline-8 &override) :foreground (doom-darken green 0.4))
+ ;;;; org <built-in>
+ ((org-block &override) :background base0)
+ ((org-block-begin-line &override) :background base0)
+ (org-hide :foreground hidden)
+ ;;;; solaire-mode
+ (solaire-mode-line-face
+ :inherit 'mode-line
+ :background modeline-bg-l
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-l)))
+ (solaire-mode-line-inactive-face
+ :inherit 'mode-line-inactive
+ :background modeline-bg-inactive-l
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive-l))))
+
+ ;;;; Base theme variable overrides-
+ ;; ()
+ )
+
+;;; doom-outrun-electric-theme.el ends here
diff --git a/elpa/doom-themes-20220504.1557/doom-palenight-theme.el b/elpa/doom-themes-20220504.1557/doom-palenight-theme.el
new file mode 100644
index 0000000..eca6ce4
--- /dev/null
+++ b/elpa/doom-themes-20220504.1557/doom-palenight-theme.el
@@ -0,0 +1,132 @@
+;;; doom-palenight-theme.el --- inspired by Material-PaleNight -*- lexical-binding: t; no-byte-compile: t; -*-
+(require 'doom-themes)
+
+;;
+(defgroup doom-palenight-theme nil
+ "Options for the `doom-palenight' theme."
+ :group 'doom-themes)
+
+(defcustom doom-palenight-padded-modeline doom-themes-padded-modeline
+ "If non-nil, adds a 4px padding to the mode-line.
+Can be an integer to determine the exact padding."
+ :group 'doom-palenight-theme
+ :type '(choice integer boolean))
+
+;;
+(def-doom-theme doom-palenight
+ "A dark theme inspired by Material-Palenight"
+
+ ;; name default 256 16
+ ((bg '("#292D3E" nil nil))
+ (bg-alt '("#242837" nil nil))
+ (base0 '("#1c1f2b" "black" "black"))
+ (base1 '("#1e212e" "#262626" "brightblack"))
+ (base2 '("#232635" "#303030" "brightblack"))
+ (base3 '("#3C435E" "#3a3a3a" "brightblack"))
+ (base4 '("#4E5579" "#444444" "brightblack"))
+ (base5 '("#676E95" "#585858" "brightblack"))
+ (base6 '("#697098" "#626262" "brightblack"))
+ (base7 '("#717CB4" "#767676" "brightblack"))
+ (base8 '("#A6Accd" "#a8a8a8" "white"))
+ (fg '("#EEFFFF" "#e4e4e4" "brightwhite"))
+ (fg-alt '("#BFC7D5" "#bcbcbc" "white"))
+
+ (grey base5)
+
+ (red '("#ff5370" "#ff0000" "red"))
+ (orange '("#f78c6c" "#ff5f00" "brightred"))
+ (green '("#c3e88d" "#afff00" "green"))
+ (teal '("#44b9b1" "#00d7af" "brightgreen"))
+ (yellow '("#ffcb6b" "#ffd700" "brightyellow"))
+ (blue '("#82aaff" "#5fafff" "brightblue"))
+ (dark-blue '("#7986E7" "#d7ffff" "blue"))
+ (magenta '("#c792ea" "#d787d7" "brightmagenta"))
+ (violet '("#bb80b3" "#d787af" "magenta"))
+ (cyan '("#89DDFF" "#5fd7ff" "brightcyan"))
+ (dark-cyan '("#80cbc4" "#00d7af" "cyan"))
+
+ ;; face categories -- required for all themes
+ (highlight magenta)
+ (vertical-bar base2)
+ (selection base4)
+ (builtin blue)
+ (comments base5)
+ (doc-comments (doom-lighten base5 0.25))
+ (constants orange)
+ (functions blue)
+ (keywords cyan)
+ (methods blue)
+ (operators cyan)
+ (type magenta)
+ (strings green)
+ (variables yellow)
+ (numbers orange)
+ (region base3)
+ (error red)
+ (warning yellow)
+ (success green)
+ (vc-modified blue)
+ (vc-added green)
+ (vc-deleted red)
+
+ ;; custom categories
+ (modeline-bg base2)
+ (modeline-bg-alt (doom-darken bg 0.01))
+ (modeline-fg base8)
+ (modeline-fg-alt comments)
+
+ (-modeline-pad
+ (when doom-palenight-padded-modeline
+ (if (integerp doom-palenight-padded-modeline) doom-palenight-padded-modeline 4))))
+
+ ;;;; Base theme face overrides
+ ((lazy-highlight :background base4 :foreground fg :weight 'bold)
+ (mode-line
+ :background modeline-bg :foreground modeline-fg
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg)))
+ (mode-line-inactive
+ :background modeline-bg-alt :foreground modeline-fg-alt
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-alt)))
+ (tooltip :background (doom-darken bg-alt 0.2) :foreground fg)
+
+ ;;;; css-mode <built-in> / scss-mode
+ (css-proprietary-property :foreground orange)
+ (css-property :foreground green)
+ (css-selector :foreground blue)
+ ;;;; dired-k
+ (dired-k-commited :foreground base4)
+ (dired-k-modified :foreground vc-modified)
+ (dired-k-ignored :foreground cyan)
+ (dired-k-added :foreground vc-added)
+ ;;;; doom-modeline
+ (doom-modeline-buffer-path :foreground green :weight 'bold)
+ (doom-modeline-buffer-major-mode :inherit 'doom-modeline-buffer-path)
+ ;;;; js2-mode
+ (js2-jsdoc-tag :foreground magenta)
+ (js2-object-property :foreground yellow)
+ (js2-object-property-access :foreground cyan)
+ (js2-function-param :foreground violet)
+ (js2-jsdoc-type :foreground base8)
+ (js2-jsdoc-value :foreground cyan)
+ ;;;; man <built-in>
+ (Man-overstrike :inherit 'bold :foreground magenta)
+ (Man-underline :inherit 'underline :foreground blue)
+ ;;;; org <built-in>
+ ((org-block &override) :background base2)
+ ((org-block-background &override) :background base2)
+ ((org-block-begin-line &override) :background base2)
+ ;;;; rainbow-delimiters
+ (rainbow-delimiters-depth-1-face :foreground magenta)
+ (rainbow-delimiters-depth-2-face :foreground orange)
+ (rainbow-delimiters-depth-3-face :foreground green)
+ (rainbow-delimiters-depth-4-face :foreground cyan)
+ (rainbow-delimiters-depth-5-face :foreground violet)
+ (rainbow-delimiters-depth-6-face :foreground yellow)
+ (rainbow-delimiters-depth-7-face :foreground blue)
+ (rainbow-delimiters-depth-8-face :foreground teal)
+ (rainbow-delimiters-depth-9-face :foreground dark-cyan)
+ ;;;; rjsx-mode
+ (rjsx-tag :foreground red)
+ (rjsx-attr :foreground yellow :slant 'italic :weight 'medium)))
+
+;;; doom-palenight-theme.el ends here
diff --git a/elpa/doom-themes-20220504.1557/doom-peacock-theme.el b/elpa/doom-themes-20220504.1557/doom-peacock-theme.el
new file mode 100644
index 0000000..c8bded7
--- /dev/null
+++ b/elpa/doom-themes-20220504.1557/doom-peacock-theme.el
@@ -0,0 +1,174 @@
+;;; doom-peacock-theme.el --- inspired by daylerees Peacock -*- lexical-binding: t; no-byte-compile: t; -*-
+(require 'doom-themes)
+
+(defgroup doom-peacock-theme nil
+ "Options for the `doom-peacock' theme."
+ :group 'doom-themes)
+
+(defcustom doom-peacock-brighter-modeline nil
+ "If non-nil, more vivid colors will be used to style the mode-line."
+ :group 'doom-peacock-theme
+ :type 'boolean)
+
+(defcustom doom-peacock-brighter-comments nil
+ "If non-nil, comments will be highlighted in more vivid colors."
+ :group 'doom-peacock-theme
+ :type 'boolean)
+
+(defcustom doom-peacock-comment-bg doom-peacock-brighter-comments
+ "If non-nil, comments will have a subtle, darker background. Enhancing their
+legibility."
+ :group 'doom-peacock-theme
+ :type 'boolean)
+
+(defcustom doom-peacock-padded-modeline doom-themes-padded-modeline
+ "If non-nil, adds a 4px padding to the mode-line. Can be an integer to
+determine the exact padding."
+ :group 'doom-peacock-theme
+ :type '(choice integer boolean))
+
+;;
+(def-doom-theme doom-peacock
+ "Peacock theme from daylerees themes "
+
+ ;; name default 256 16
+ ((bg '("#2b2a27" nil nil ))
+ (bg-alt '("#1F1E1D" nil nil ))
+ (base0 '("#2b2a27" "black" "black" ))
+ (base1 '("#1c1f24" "#1e1e1e" "brightblack" ))
+ (base2 '("#202328" "#2e2e2e" "brightblack" ))
+ (base3 '("#23272e" "#262626" "brightblack" ))
+ (base4 '("#3f444a" "#3f3f3f" "brightblack" ))
+ (base5 '("#5B6268" "#525252" "brightblack" ))
+ (base6 '("#73797e" "#6b6b6b" "brightblack" ))
+ (base7 '("#9ca0a4" "#979797" "brightblack" ))
+ (base8 '("#DFDFDF" "#dfdfdf" "white" ))
+ (fg '("#ede0ce" "#bfbfbf" "brightwhite" ))
+ (fg-alt '("#5B6268" "#2d2d2d" "white" ))
+
+ (grey base4)
+ (white '("#f8f8f0" "base4" "base4" ))
+ (red '("#ff5d38" "#ff6655" "red" )) ;; peacock todo 16
+ (orange '("#cb4b16" "#dd8844" "brightred" ))
+ (green '("#98be65" "#99bb66" "green" ))
+ (teal '("#26a6a6" "#44b9b1" "brightgreen" )) ;; peacock
+ (yellow '("#bcd42a" "#ECBE7B" "yellow" )) ;; peacock, todo 16
+ (blue '("#51afef" "#51afef" "brightblue" ))
+ (dark-blue '("#2257A0" "#2257A0" "blue" ))
+ (magenta '("#c678dd" "#c678dd" "magenta" ))
+ (violet '("#a9a1e1" "#a9a1e1" "brightmagenta"))
+ (cyan '("#46D9FF" "#46D9FF" "brightcyan" ))
+ (dark-cyan '("#5699AF" "#5699AF" "cyan" ))
+ (coral-popup '("#a60033" "#f6bfbc" "coral-popup" ))
+
+ ;; face categories -- required for all themes
+ (highlight red)
+ (vertical-bar (doom-lighten bg 0.1))
+ (selection coral-popup)
+ (builtin red)
+ (comments (if doom-peacock-brighter-comments dark-cyan base5)) ;; TODO
+ (doc-comments (doom-lighten (if doom-peacock-brighter-comments dark-cyan base5) 0.25)) ;; TODO
+ (constants red) ;; done
+ (functions yellow) ;; done
+ (keywords teal) ;; done
+ (methods yellow) ;; not sure how to test this.
+ (operators red) ;; not showing up on `=` etc.
+ (type white) ;;
+ (strings yellow)
+ (variables white) ;; done
+ (numbers red) ;; done
+
+ (region `(,(doom-lighten (car bg-alt) 0.15) ,@(doom-lighten (cdr base0) 0.35)))
+ (error red)
+ (warning yellow)
+ (success green)
+ (vc-modified orange)
+ (vc-added green)
+ (vc-deleted red)
+
+ ;; custom categories
+ (-modeline-bright doom-peacock-brighter-modeline)
+ (-modeline-pad
+ (when doom-peacock-padded-modeline
+ (if (integerp doom-peacock-padded-modeline) doom-peacock-padded-modeline 4)))
+
+ (modeline-fg nil)
+ (modeline-fg-alt (doom-blend violet base4 (if -modeline-bright 0.5 0.2)))
+
+ (modeline-bg
+ (if -modeline-bright
+ (doom-darken blue 0.45)
+ `(,(doom-darken (car bg-alt) 0.1) ,@(cdr base0))))
+ (modeline-bg-l
+ (if -modeline-bright
+ (doom-darken bg 0.475)
+ `(,(doom-darken (car bg) 0.15) ,@(cdr base0))))
+ (modeline-bg-inactive `(,(doom-darken (car bg) 0.1) ,@(cdr base1)))
+ (modeline-bg-inactive-l (doom-darken bg 0.1)))
+
+
+ ;;;; Base theme face overrides
+ ((font-lock-comment-face
+ :foreground comments
+ :background (if doom-peacock-comment-bg (doom-lighten bg 0.05)))
+ (font-lock-doc-face
+ :inherit 'font-lock-comment-face
+ :foreground doc-comments)
+ ((line-number &override) :foreground base4)
+ ((line-number-current-line &override) :foreground base7)
+ (mode-line
+ :background modeline-bg :foreground modeline-fg
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg)))
+ (mode-line-inactive
+ :background modeline-bg-inactive :foreground modeline-fg-alt
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive)))
+ (mode-line-emphasis :foreground (if -modeline-bright base8 highlight))
+
+ ;;;; company
+ (company-tooltip :inherit 'tooltip)
+ (company-tooltip-common :foreground highlight)
+ (company-tooltip-search :background highlight :foreground bg :distant-foreground fg)
+ (company-tooltip-selection :background selection)
+ (company-tooltip-mouse :background magenta :foreground bg :distant-foreground fg)
+ (company-tooltip-annotation :foreground violet)
+ (company-scrollbar-bg :inherit 'tooltip)
+ (company-scrollbar-fg :background highlight)
+ (company-preview :foreground highlight)
+ (company-preview-common :background base3 :foreground magenta)
+ (company-preview-search :inherit 'company-tooltip-search)
+ (company-template-field :inherit 'match)
+ ;;;; css-mode <built-in> / scss-mode
+ (css-proprietary-property :foreground orange)
+ (css-property :foreground green)
+ (css-selector :foreground blue)
+ ;;;; doom-modeline
+ (doom-modeline-bar :background (if -modeline-bright modeline-bg highlight))
+ ;;;; elscreen
+ (elscreen-tab-other-screen-face :background "#353a42" :foreground "#1e2022")
+ ;;;; markdown-mode
+ (markdown-markup-face :foreground base5)
+ (markdown-header-face :inherit 'bold :foreground red)
+ ((markdown-code-face &override) :background (doom-lighten base3 0.05))
+ ;;;; popup
+ (popup-face :inherit 'tooltip)
+ (popup-selection-face :inherit 'tooltip)
+ ;;;; pos-tip
+ (popup-tip-face :inherit 'tooltip)
+ ;;;; rjsx-mode
+ (rjsx-tag :foreground teal)
+ (rjsx-attr :foreground red)
+ ;;;; solaire-mode
+ (solaire-mode-line-face
+ :inherit 'mode-line
+ :background modeline-bg-l
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-l)))
+ (solaire-mode-line-inactive-face
+ :inherit 'mode-line-inactive
+ :background modeline-bg-inactive-l
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive-l))))
+
+ ;;;; Base theme variable overrides-
+ ;; ()
+ )
+
+;;; doom-peacock-theme.el ends here
diff --git a/elpa/doom-themes-20220504.1557/doom-plain-dark-theme.el b/elpa/doom-themes-20220504.1557/doom-plain-dark-theme.el
new file mode 100644
index 0000000..a6a23fb
--- /dev/null
+++ b/elpa/doom-themes-20220504.1557/doom-plain-dark-theme.el
@@ -0,0 +1,138 @@
+;;; doom-plain-dark-theme.el --- inspired by gko's plain theme for VSCode -*- lexical-binding: t; no-byte-compile: t; -*-
+
+(require 'doom-themes)
+
+(defgroup doom-plain-dark-theme nil
+ "Options for the `doom-plain-dark' theme."
+ :group 'doom-themes)
+
+(defcustom doom-plain-brighter-modeline nil
+ "If non-nil, more vivid colors will be used to style the mode-line."
+ :group 'doom-plain-dark-theme
+ :type 'boolean)
+
+(defcustom doom-plain-padded-modeline doom-themes-padded-modeline
+ "If non-nil, adds a 4px padding to the mode-line. Can be an integer to
+determine the exact padding."
+ :group 'doom-plain-dark-theme
+ :type '(or integer boolean))
+
+(def-doom-theme doom-plain-dark
+ "Theme inspired by gko's plain dark."
+
+ ;; name default 256 16
+ ((bg '("#222222" nil nil ))
+ (bg-alt (doom-lighten bg 0.15))
+ (base0 '("#838083" nil nil ))
+ (base1 '("#0e0c0a" nil nil ))
+ (base2 '("#bbbbbb" nil nil ))
+ (base3 '("#444444" nil nil ))
+ (base4 '("#202020" nil nil ))
+ (base5 '("#545053" nil nil ))
+ (base6 '("#050505" nil nil ))
+ (base7 '("#ffdddd" nil nil ))
+ (base8 '("#050505" nil nil ))
+ (fg '("#d7d5d1" nil nil ))
+ (fg-alt '("#e7e5e3" nil nil ))
+
+ (grey fg)
+ (red fg)
+ (blue fg)
+ (dark-blue fg)
+ (orange fg)
+ (green fg)
+ (teal fg)
+ (yellow fg)
+ (magenta fg)
+ (violet fg)
+ (cyan fg)
+ (dark-cyan fg)
+
+ ;; face categories -- required for all themes
+ (highlight base2)
+ (vertical-bar fg)
+ (selection base1)
+ (builtin base0)
+ (comments base5)
+ (doc-comments base5)
+ (constants base0)
+ (functions fg)
+ (keywords fg)
+ (methods fg)
+ (operators fg)
+ (type fg)
+ (strings base0)
+ (variables base0)
+ (numbers base0)
+ (region base1)
+ (error red)
+ (warning yellow)
+ (success green)
+ (vc-modified (doom-darken fg 0.4))
+ (vc-added (doom-lighten fg 0.4))
+ (vc-deleted red)
+
+ ;; custom categories
+ (hidden `(,(car bg) "black" "black"))
+ (-modeline-bright doom-plain-brighter-modeline)
+ (-modeline-pad
+ (when doom-plain-padded-modeline
+ (if (integerp doom-plain-padded-modeline) doom-plain-padded-modeline 4)))
+
+ (modeline-bg
+ (if -modeline-bright
+ (doom-darken blue 0.475)
+ `(,(doom-darken (car bg-alt) 0.15) ,@(cdr base0))))
+ (modeline-bg-l
+ (if -modeline-bright
+ (doom-darken blue 0.45)
+ `(,(doom-darken (car bg-alt) 0.1) ,@(cdr base0))))
+ (modeline-bg-inactive (doom-darken bg-alt 0.25))
+ (modeline-bg-inactive-l `(,(car bg-alt) ,@(cdr base1)))
+ (modeline-fg nil)
+ (modeline-fg-alt (doom-lighten modeline-bg-inactive 0.3)))
+
+
+ ;;;; Base theme face overrides
+ (((font-lock-constant-face &override) :slant 'italic)
+ ((font-lock-comment-face &override) :slant 'italic)
+ ((font-lock-function-name-face &override) :slant 'italic)
+ ((font-lock-type-face &override) :slant 'italic)
+ (hl-line :background base8)
+ ((line-number &override) :foreground base3)
+ ((line-number-current-line &override) :foreground base2)
+ (mode-line
+ :background modeline-bg :foreground modeline-fg
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg)))
+ (mode-line-inactive
+ :background modeline-bg-inactive :foreground modeline-fg-alt
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive)))
+ (mode-line-emphasis :foreground (if -modeline-bright base8 highlight))
+
+ ;;;; doom-modeline
+ (doom-modeline-bar :background (if -modeline-bright modeline-bg highlight))
+ ;;;; lsp-mode
+ (lsp-headerline-breadcrumb-symbols-face :foreground keywords :weight 'bold)
+ ;;;; outline <built-in>
+ (outline-1 :slant 'italic :foreground fg-alt)
+ (outline-2 :inherit 'outline-1 :foreground base2)
+ (outline-3 :inherit 'outline-2)
+ (outline-4 :inherit 'outline-3)
+ (outline-5 :inherit 'outline-4)
+ (outline-6 :inherit 'outline-5)
+ (outline-7 :inherit 'outline-6)
+ (outline-8 :inherit 'outline-7)
+ ;;;; org <built-in>
+ (org-block-begin-line :foreground base2 :background base3)
+ (org-block-end-line :foreground base2 :background base3)
+ ;;;; solaire-mode
+ (solaire-mode-line-face
+ :inherit 'mode-line
+ :background modeline-bg-l
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-l)))
+ (solaire-mode-line-inactive-face
+ :inherit 'mode-line-inactive
+ :background modeline-bg-inactive-l
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive-l)))))
+
+;;; doom-plain-dark-theme.el ends here
diff --git a/elpa/doom-themes-20220504.1557/doom-plain-theme.el b/elpa/doom-themes-20220504.1557/doom-plain-theme.el
new file mode 100644
index 0000000..2cc1f4d
--- /dev/null
+++ b/elpa/doom-themes-20220504.1557/doom-plain-theme.el
@@ -0,0 +1,159 @@
+;;; doom-plain-theme.el --- inspired by gko's plain theme for VSCode -*- lexical-binding: t; no-byte-compile: t; -*-
+;;
+;; Author: Konstantin <https://github.com/gko>
+;; Ported by: Mateusz Ż <https://github.com/mateossh>
+;; Created: January 11, 2019
+;; Version: 2.0.0
+;; Keywords: custom themes, faces
+;; Homepage: https://github.com/hlissner/emacs-doom-themes
+;; Package-Requires: ((emacs "25.1") (cl-lib "0.5") (doom-themes "2.2.1"))
+;;
+;;; Commentary:
+;;
+;; Ported from VsCode Plain: https://github.com/gko/plain
+;;
+;;; Code:
+
+(require 'doom-themes)
+
+
+;;
+;;; Variables
+
+(defgroup doom-plain-theme nil
+ "Options for the `doom-plain' theme."
+ :group 'doom-themes)
+
+(defcustom doom-plain-padded-modeline doom-themes-padded-modeline
+ "If non-nil, adds a 4px padding to the mode-line.
+Can be an integer to determine the exact padding."
+ :group 'doom-plain-theme
+ :type '(or integer boolean))
+
+
+;;
+;;; Theme definition
+
+(def-doom-theme doom-plain
+ "Theme inspired by gko's plain."
+
+ ;; name default/256/16
+ ((bg '("#ffffff"))
+ (bg-alt '("#f3f3f3"))
+ (base0 '("#969896"))
+ (base1 '("#f1f3f5"))
+ (base2 '("#444444"))
+ (base3 '("#cccccc"))
+ (base4 '("#e7e7e7"))
+ (base5 '("#c5c8c6"))
+ (base6 '("#fafafa"))
+ (base7 '("#dfdfdf"))
+ (base8 '("#fafafa"))
+ (fg '("#282a2e"))
+ (fg-alt (doom-lighten fg 0.15))
+
+ (grey fg)
+ (red fg)
+ (blue fg)
+ (dark-blue fg)
+ (orange fg)
+ (green fg)
+ (teal fg)
+ (yellow fg)
+ (magenta fg)
+ (violet fg)
+ (cyan fg)
+ (dark-cyan fg)
+
+ ;; face categories -- required for all themes
+ (highlight base2)
+ (vertical-bar base5)
+ (selection base1)
+ (builtin base0)
+ (comments base5)
+ (doc-comments base5)
+ (constants base0)
+ (functions fg)
+ (keywords fg)
+ (methods fg)
+ (operators fg)
+ (type fg)
+ (strings base0)
+ (variables base0)
+ (numbers base0)
+ (region base4)
+ (error (doom-blend fg "#ff0000" 0.4))
+ (warning base2)
+ (success green)
+ (vc-modified base5)
+ (vc-added (doom-lighten fg 0.7))
+ (vc-deleted base2)
+
+ ;; custom categories
+ (-modeline-pad
+ (when doom-plain-padded-modeline
+ (if (integerp doom-plain-padded-modeline) doom-plain-padded-modeline 4)))
+
+ (modeline-bg (doom-darken bg-alt 0.15))
+ (modeline-bg-alt (doom-darken bg-alt 0.1))
+ (modeline-bg-inactive (doom-darken bg-alt 0.1))
+ (modeline-bg-inactive-alt bg-alt)
+ (modeline-fg fg)
+ (modeline-fg-alt (doom-darken modeline-bg-inactive 0.35)))
+
+ ;;;; Base theme face overrides
+ ((error :underline `(:style wave :color ,error))
+ (warning :underline `(:style wave :color ,warning))
+ ((font-lock-constant-face &override) :slant 'italic)
+ ((font-lock-comment-face &override) :slant 'italic)
+ ((font-lock-function-name-face &override) :slant 'italic)
+ ((font-lock-type-face &override) :slant 'italic)
+ (hl-line :background base8)
+ ((line-number &override) :foreground base3)
+ ((line-number-current-line &override) :foreground base2)
+ (mode-line
+ :background modeline-bg :foreground modeline-fg
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg)))
+ (mode-line-inactive
+ :background modeline-bg-inactive :foreground modeline-fg-alt
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive)))
+ (mode-line-emphasis :foreground highlight)
+
+ ;;;; doom-modeline
+ (doom-modeline-bar :background modeline-bg)
+ (doom-modeline-bar-inactive :inherit 'doom-modeline-bar)
+ (doom-modeline-project-dir :foreground fg)
+ (doom-modeline-buffer-file :foreground fg)
+ (doom-modeline-buffer-modified :weight 'bold :foreground "#000000")
+ (doom-modeline-panel :inherit 'mode-line-highlight :background base3 :foreground fg)
+ ;;;; ivy
+ (ivy-posframe :background bg-alt)
+ ;;;; magit
+ ((magit-diff-added-highlight &override) :foreground fg :background (doom-blend vc-added bg 0.3))
+ ((magit-diff-removed &override) :foreground (doom-lighten fg 0.4) :background (doom-blend vc-deleted bg 0.1))
+ ((magit-diff-removed-highlight &override) :foreground fg :background (doom-blend vc-deleted bg 0.22))
+ ;;;; lsp-mode
+ (lsp-headerline-breadcrumb-symbols-face :foreground keywords :weight 'bold)
+ ;;;; outline <built-in>
+ (outline-1 :slant 'italic :foreground fg-alt)
+ (outline-2 :inherit 'outline-1 :foreground base2)
+ (outline-3 :inherit 'outline-2)
+ (outline-4 :inherit 'outline-3)
+ (outline-5 :inherit 'outline-4)
+ (outline-6 :inherit 'outline-5)
+ (outline-7 :inherit 'outline-6)
+ (outline-8 :inherit 'outline-7)
+ ;;;; org <built-in>
+ ((org-block &override) :background bg-alt)
+ ((org-block-begin-line &override) :foreground base5)
+ ;;;; solaire-mode
+ (solaire-mode-line-face
+ :inherit 'mode-line
+ :background modeline-bg-alt
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-alt)))
+ (solaire-mode-line-inactive-face
+ :inherit 'mode-line-inactive
+ :background modeline-bg-inactive-alt
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive-alt)))))
+
+;;; doom-plain-theme.el ends here
diff --git a/elpa/doom-themes-20220504.1557/doom-rouge-theme.el b/elpa/doom-themes-20220504.1557/doom-rouge-theme.el
new file mode 100644
index 0000000..aa0aa96
--- /dev/null
+++ b/elpa/doom-themes-20220504.1557/doom-rouge-theme.el
@@ -0,0 +1,191 @@
+;;; doom-rouge-theme.el --- ported from Rouge Theme -*- lexical-binding: t; no-byte-compile: t; -*-
+(require 'doom-themes)
+
+;;
+(defgroup doom-rouge-theme nil
+ "Options for the `doom-rouge' theme."
+ :group 'doom-themes)
+
+(defcustom doom-rouge-brighter-comments nil
+ "If non-nil, comments will be highlighted in more vivid colors."
+ :group 'doom-rouge-theme
+ :type 'boolean)
+
+(defcustom doom-rouge-brighter-tabs t
+ "If non-nil, tabs will a more vivid background color."
+ :group 'doom-rouge-theme
+ :type 'boolean)
+
+(defcustom doom-rouge-comment-bg doom-rouge-brighter-comments
+ "If non-nil, comments will have a subtle, darker background. Enhancing their
+legibility."
+ :group 'doom-rouge-theme
+ :type 'boolean)
+
+(defcustom doom-rouge-padded-modeline doom-themes-padded-modeline
+ "If non-nil, adds a 4px padding to the mode-line. Can be an integer to
+determine the exact padding."
+ :group 'doom-rouge-theme
+ :type '(choice integer boolean))
+
+;;
+(def-doom-theme doom-rouge
+ "A dark theme ported from VS Code's Rouge."
+
+ ;; name default 256 16
+ ((bg '("#172030" nil nil )) ;; modified
+ (bg-alt '("#172030" nil nil ))
+ (base0 '("#070A0E" "black" "black" ))
+ (base1 '("#0E131D" "#1e1e1e" "brightblack" ))
+ (base2 '("#151D2B" "#2e2e2e" "brightblack" ))
+ (base3 '("#1F2A3F" "#262626" "brightblack" ))
+ (base4 '("#5D636E" "#3f3f3f" "brightblack" ))
+ (base5 '("#64727d" "#64727d" "brightblack" ))
+ (base6 '("#B16E75" "#6b6b6b" "brightblack" ))
+ (base7 '("#E8E9EB" "#979797" "brightblack" ))
+ (base8 '("#F0F4FC" "#dfdfdf" "white" ))
+ (fg '("#FAFFF6" "#bbb" "white" ))
+ (fg-alt '("#A7ACB9" "#bfbfbf" "brightwhite" ))
+
+ (grey base5)
+ (red '("#c6797e" "#c6797e" "red" ))
+ (light-red '("#DB6E8F" "#DB6E8F" "red" ))
+ (orange '("#eabe9a" "#eabe9a" "brightred" ))
+ (green '("#A3B09A" "#A3B9A4" "green" ))
+ (teal '("#7ea9a9" "#7ea9a9" "brightgreen" ))
+ (yellow '("#F7E3AF" "#F7E3AF" "yellow" ))
+ (blue '("#6e94b9" "#6e94b9" "brightblue" ))
+ (dark-blue '("#1E6378" "#1E6378" "blue" ))
+ (magenta '("#b18bb1" "#b18bb1" "magenta" ))
+ (salmon '("#F9B5AC" "#F9B5AC" "orange" ))
+ (violet '("#5D80AE" "#5D80AE" "brightmagenta"))
+ (cyan '("#88C0D0" "#88C0D0" "brightcyan" ))
+ (dark-cyan '("#507681" "#507681" "cyan" ))
+
+ ;; face categories -- required for all themes
+ (highlight base6)
+ (vertical-bar (doom-darken base1 0.2))
+ (selection base4)
+ (builtin light-red)
+ (comments grey)
+ (doc-comments green)
+ (constants red)
+ (functions salmon)
+ (keywords magenta)
+ (methods light-red)
+ (operators magenta)
+ (type red)
+ (strings green)
+ (variables red)
+ (numbers orange)
+ (region base4)
+ (error red)
+ (warning yellow)
+ (success green)
+ (vc-modified orange)
+ (vc-added green)
+ (vc-deleted red)
+
+ ;; custom categories
+ (hidden `(,(car bg) "black" "black"))
+ (-modeline-pad
+ (when doom-rouge-padded-modeline
+ (if (integerp doom-rouge-padded-modeline) doom-rouge-padded-modeline 4)))
+
+ (tabs-bg (if doom-rouge-brighter-tabs base6 bg))
+ (tabs-fg (if doom-rouge-brighter-tabs base8 fg))
+ (tabs-bar-bg (if doom-rouge-brighter-tabs bg red))
+ (tabs-marker (if doom-rouge-brighter-tabs base8 highlight))
+
+ (modeline-fg nil)
+ (modeline-fg-alt base6)
+ (modeline-bg base1)
+ (modeline-bg-l `(,(doom-darken (car bg) 0.1) ,@(cdr base0)))
+ (modeline-bg-inactive (doom-darken bg 0.1))
+ (modeline-bg-inactive-l `(,(car bg) ,@(cdr base1))))
+
+
+ ;;;; Base theme face overrides
+ (((font-lock-comment-face &override) :slant 'italic)
+ ((font-lock-keyword-face &override) :slant 'italic)
+ (font-lock-preprocessor-face :foreground magenta :slant 'italic)
+ (lazy-highlight :background base4)
+ ((line-number &override) :foreground (doom-lighten 'base5 0.2))
+ ((line-number-current-line &override) :foreground base7)
+ (mode-line
+ :background modeline-bg :foreground modeline-fg
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg)))
+ (mode-line-inactive
+ :background modeline-bg-inactive :foreground modeline-fg-alt
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive)))
+ (mode-line-emphasis :foreground highlight)
+ (tooltip :background base3 :foreground fg-alt)
+ (vertical-border :foreground base6)
+
+ ;;;; centuar-tabs
+ (centaur-tabs-selected :foreground tabs-fg :background tabs-bg)
+ (centaur-tabs-selected-modified :foreground tabs-fg :background tabs-bg)
+ (centaur-tabs-unselected-modified :foreground tabs-fg :background bg)
+ (centaur-tabs-active-bar-face :background tabs-bar-bg)
+ (centaur-tabs-modified-marker-selected :inherit 'centaur-tabs-selected :foreground tabs-marker)
+ (centaur-tabs-modified-marker-unselected :inherit 'centaur-tabs-unselected :foreground tabs-marker)
+ ;;;; css-mode <built-in> / scss-mode
+ (css-proprietary-property :foreground orange)
+ (css-property :foreground green)
+ (css-selector :foreground blue)
+ ;;;; doom-modeline
+ (doom-modeline-project-root-dir :foreground base6)
+ ;;;; doom-themes
+ (doom-themes-treemacs-root-face :foreground highlight :weight 'ultra-bold :height 1.2)
+ (doom-themes-treemacs-file-face :foreground highlight)
+ ;;;; ediff <built-in>
+ (ediff-fine-diff-A :background (doom-darken violet 0.4) :weight 'bold)
+ (ediff-current-diff-A :background (doom-darken base0 0.25))
+ ;;;; elscreen
+ (elscreen-tab-other-screen-face :background "#353a42" :foreground "#1e2022")
+ ;;;; highlight-symbol
+ (highlight-symbol-face :background region :distant-foreground fg-alt)
+ ;;;; highlight-thing
+ (highlight-thing :background region :distant-foreground fg-alt)
+ ;;;; ivy
+ (ivy-current-match :background base3)
+ (ivy-minibuffer-match-face-2 :foreground highlight :weight 'extra-bold)
+ ;;;; ivy-posframe
+ (ivy-posframe :background bg-alt)
+ (ivy-posframe-border :background highlight)
+ ;;;; magit
+ (magit-diff-hunk-heading :foreground bg :background (doom-blend highlight bg 0.3) :extend t)
+ (magit-diff-hunk-heading-highlight :foreground bg :background highlight :weight 'bold :extend t)
+ (magit-section-heading :foreground highlight)
+ ;;;; markdown-mode
+ (markdown-markup-face :foreground base5)
+ (markdown-header-face :inherit 'bold :foreground red)
+ ((markdown-code-face &override) :background (doom-lighten base3 0.05))
+ ;;;; mic-paren
+ ((paren-face-match &override) :foreground red :background base3 :weight 'ultra-bold)
+ ((paren-face-mismatch &override) :foreground base3 :background red :weight 'ultra-bold)
+ ;;;; neotree
+ (neo-root-dir-face :foreground red)
+ ;;;; org <built-in>
+ (org-hide :foreground hidden)
+ ;;;; solaire-mode
+ (solaire-mode-line-face
+ :inherit 'mode-line
+ :background modeline-bg-l
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-l)))
+ (solaire-mode-line-inactive-face
+ :inherit 'mode-line-inactive
+ :background modeline-bg-inactive-l
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive-l)))
+ (solaire-hl-line-face :background base3)
+ ;;;; treemacs
+ (treemacs-root-face :foreground highlight :weight 'ultra-bold :height 1.2)
+ (treemacs-directory-face :foreground highlight)
+ ;;;; vimish-fold
+ ((vimish-fold-overlay &override) :inherit 'font-lock-comment-face :background base3 :weight 'light)
+ ((vimish-fold-fringe &override) :foreground teal))
+
+ ;;;; Base theme variable overrides-
+ ())
+
+;;; doom-rouge-theme.el ends here
diff --git a/elpa/doom-themes-20220504.1557/doom-shades-of-purple-theme.el b/elpa/doom-themes-20220504.1557/doom-shades-of-purple-theme.el
new file mode 100644
index 0000000..dc043d2
--- /dev/null
+++ b/elpa/doom-themes-20220504.1557/doom-shades-of-purple-theme.el
@@ -0,0 +1,295 @@
+;;; shades-of-purple-theme.el --- A port of Spacemacs' Shades of Purple theme -*- lexical-binding: t; no-byte-compile: t; -*-
+;;
+;; Author: James Baldwin <jwbaldwin3@gmail.com>
+;; Homepage: https://github.com/jwbaldwin/spacemacs-shades-of-purple
+;; Version: 1.0.0
+;;
+;;; Commentary:
+;; Credit to the original https://github.com/ahmadawais/shades-of-purple-vscode
+;;; Code:
+
+;;Background #2D2B55 #2D2B55
+;;Background Dark #1E1E3F #1E1E3F
+;;Foreground #A599E9 #A599E9
+;;Hover Background #4D21FC #4D21FC
+;;Contrast #FAD000 #FAD000
+;;Contrast Lite #FFEE80 #FFEE80
+;;Contrast Lite II #FAEFA5 #FAEFA5
+;;Highlight #FF7200 #FF7200
+;;Comment #B362FF #B362FF
+;;Constants #FF628C #FF628C
+;;Keywords #FF9D00 #FF9D00
+;;Other #9EFFFF #9EFFFF
+;;Strings #A5FF90 #A5FF90
+;;Templates #3AD900 #3AD900
+;;Definitions #FB94FF #FB94FF
+;;Invalid #EC3A37F5 #EC3A37F5
+;;Diff Added #00FF009A #00FF009A
+;;Diff Removed #FF000D81 #FF000D81
+
+(require 'doom-themes)
+
+;;
+(defgroup doom-shades-of-purple-theme nil
+ "Options for the `doom-shades-of-purple' theme."
+ :group 'doom-themes)
+
+(defcustom doom-shades-of-purple-padded-modeline doom-themes-padded-modeline
+ "If non-nil, adds a 4px padding to the mode-line.
+Can be an integer to determine the exact padding."
+ :group 'doom-shades-of-purple-theme
+ :type '(choice integer boolean))
+
+;;
+(def-doom-theme doom-shades-of-purple
+ "A dark theme inspired by VS code's shades-of-purple"
+
+ ;; name default 256 16
+ ((bg '("#2d2b55" "#2d2b55" "black"))
+ (bg-alt '("#1e1e3f" "#1e1e3f" "black"))
+ (base0 '("#161a2a" "#161a2a" "black"))
+ (base1 '("#191a2a" "#191a2a" "brightblack"))
+ (base2 '("#1e2030" "#1e2030" "brightblack"))
+ (base3 '("#222436" "#222436" "brightblack"))
+ (base4 '("#a599e9" "#a599e9" "brightblack"))
+ (base5 '("#444a73" "#444a73" "brightblack"))
+ (base6 '("#828bb8" "#828bb8" "brightblack"))
+ (base7 '("#a9b8e8" "#a9b8e8" "brightblack"))
+ (base8 '("#b4c2f0" "#b4c2f0" "white"))
+ (indigo '("#7a88cf" "#7a88cf" "brightblack"))
+ (region '("#b362ff" "#b362ff" "brightblack"))
+ (selection '("#b362ff" "#b362ff" "brightblack"))
+ (fg '("#e3e9fa" "#e3e9fa" "brightwhite"))
+ (fg-alt '("#b4c2f0" "#b4c2f0" "white"))
+
+ (grey base5)
+
+ (dark-red '("#ff5370" "#ff5370" "red"))
+ (red '("#ff000d" "#ff000d" "red"))
+ (light-red '("#ff98a4" "#ff98a4" "brightred"))
+ (orange '("#ff9d00" "#ff9d00" "brightred"))
+ (light-green '("#a5ff90" "#a5ff90" "green"))
+ (green '("#3ad900" "#3ad900" "green"))
+ (dark-green '("#00ff00" "#00ff00" "green"))
+ (dark-teal '("#37fea1" "#37fea1" "green"))
+ (teal '("#ff628c" "#ff628c" "brightgreen"))
+ (light-teal '("#7af8ca" "#7af8ca" "brightgreen"))
+ (yellow '("#fad000" "#fad000" "brightyellow"))
+ (blue '("#82aaff" "#82aaff" "brightblue"))
+ (dark-blue '("#4976eb" "#4976eb" "brightblue"))
+ (light-blue '("#50c4fa" "#50c4fa" "blue"))
+ (light-magenta '("#baacff" "#baacff" "brightmagenta"))
+ (magenta '("#ff9d00" "#ff9d00" "brightmagenta"))
+ (violet '("#f989d3" "#f989d3" "magenta"))
+ (light-pink '("#fb94ff" "#fb94ff" "magenta"))
+ (pink '("#ff628c" "#ff628c" "magenta"))
+ (cyan '("#ff628c" "#ff628c" "brightcyan"))
+ (dark-cyan '("#9effff" "#9effff" "cyan"))
+ (purple '("#b362ff" "#b362ff" "magenta"))
+
+ ;; face categories -- required for all themes
+ (highlight blue)
+ (vertical-bar bg-alt)
+ (line-highlight bg-alt)
+ (selection selection)
+ (builtin magenta)
+ (comments purple)
+ (doc-comments (doom-lighten comments 0.25))
+ (constants light-pink)
+ (functions (doom-lighten yellow 0.15))
+ (keywords orange)
+ (methods yellow)
+ (operators orange)
+ (type green)
+ (strings light-green)
+ (variables dark-teal)
+ (numbers orange)
+ (region region)
+ (error red)
+ (warning yellow)
+ (success green)
+ (vc-modified blue)
+ (vc-added dark-green)
+ (vc-deleted red)
+
+ ;; custom categories
+ (modeline-bg (doom-darken bg-alt 0.1))
+ (modeline-bg-alt (doom-darken bg 0.1))
+ (modeline-fg base8)
+ (modeline-fg-alt comments)
+
+ (-modeline-pad
+ (when doom-shades-of-purple-padded-modeline
+ (if (integerp doom-shades-of-purple-padded-modeline) doom-shades-of-purple-padded-modeline 4))))
+
+ ;;;; Base theme face overrides
+ (;;;; emacs
+ (font-lock-keyword-face :foreground keywords)
+ (font-lock-comment-face :foreground comments)
+ (font-lock-doc-face :foreground doc-comments)
+ (fringe :background bg)
+ (lazy-highlight :background purple :foreground fg)
+ (mode-line
+ :background modeline-bg :foreground modeline-fg
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg)))
+ (mode-line-inactive
+ :background modeline-bg-alt :foreground modeline-fg-alt
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-alt)))
+ (tooltip :background base0 :foreground fg)
+ ((line-number &override) :foreground base5)
+ ((line-number-current-line &override) :foreground fg :background line-highlight)
+
+ ;;;; linum
+ ((linum &inherit line-number))
+ ;;;; doom-modeline
+ (doom-modeline-buffer-file :foreground base7)
+ (doom-modeline-icon-inactive :foreground indigo)
+ (doom-modeline-evil-normal-state :foreground dark-cyan)
+ (doom-modeline-evil-insert-state :foreground yellow)
+ (doom-modeline-project-dir :foreground light-teal)
+ (doom-modeline-buffer-path :foreground blue)
+ (doom-modeline-buffer-modified :inherit 'bold :foreground yellow)
+ (doom-modeline-buffer-major-mode :inherit 'doom-modeline-buffer-path)
+ ;;;; hl-line <built-in>
+ (hl-line :background line-highlight)
+ ;;;; message <built-in>
+ (message-header-name :foreground green)
+ (message-header-subject :foreground highlight :weight 'bold)
+ (message-header-to :foreground highlight :weight 'bold)
+ (message-header-cc :inherit 'message-header-to :foreground (doom-darken highlight 0.15))
+ (message-header-other :foreground violet)
+ (message-header-newsgroups :foreground yellow)
+ (message-header-xheader :foreground doc-comments)
+ (message-separator :foreground comments)
+ (message-mml :foreground comments :slant 'italic)
+ (message-cited-text :foreground magenta)
+ ;;;; css-mode <built-in> / scss-mode
+ (css-proprietary-property :foreground orange)
+ (css-property :foreground green)
+ (css-selector :foreground blue)
+ ;;;; nix-mode
+ (nix-attribute-face :foreground blue)
+ (nix-builtin-face :foreground dark-teal)
+ ;;;; man <built-in>
+ (Man-overstrike :inherit 'bold :foreground magenta)
+ (Man-underline :inherit 'underline :foreground blue)
+ ;;;; lsp-mode
+ (lsp-face-highlight-read :background region)
+ (lsp-face-highlight-textual :background region)
+ (lsp-face-highlight-write :background region)
+ (lsp-face-semhl-type-primative :foreground orange)
+ (lsp-face-semhl-method :foreground magenta)
+ ;;;; js2-mode
+ (js2-jsdoc-tag :foreground magenta)
+ (js2-object-property :foreground dark-teal)
+ (js2-object-property-access :foreground fg-alt)
+ (js2-function-param :foreground pink)
+ (js2-jsdoc-type :foreground base8)
+ (js2-jsdoc-value :foreground cyan)
+ ;;;; outline <built-in>
+ ((outline-1 &override) :foreground light-blue)
+ ((outline-2 &override) :foreground dark-cyan)
+ ((outline-3 &override) :foreground light-red)
+ ((outline-4 &override) :foreground blue)
+ ((outline-5 &override) :foreground magenta)
+ ((outline-6 &override) :foreground red)
+ ((outline-7 &override) :foreground violet)
+ ;;;; org-mode <built-in>
+ ((org-block &override) :background base2)
+ ((org-block-background &override) :background base2)
+ ((org-block-begin-line &override) :background base2)
+ ;;;; rjsx-mode
+ (rjsx-tag :foreground violet)
+ (rjsx-attr :foreground yellow :slant 'italic :weight 'medium)
+ ;;;; all-the-icons
+ (all-the-icons-cyan :foreground dark-cyan)
+ (all-the-icons-cyan-alt :foreground dark-cyan)
+ (all-the-icons-dblue :foreground (doom-darken blue 0.1))
+ (all-the-icons-dcyan :foreground dark-cyan)
+ (all-the-icons-dgreen :foreground dark-teal)
+ (all-the-icons-dmaroon :foreground magenta)
+ (all-the-icons-dorange :foreground orange)
+ (all-the-icons-dpink :foreground pink)
+ (all-the-icons-dpurple :foreground magenta)
+ (all-the-icons-dred :foreground dark-red)
+ (all-the-icons-dsilver :foreground grey)
+ (all-the-icons-dyellow :foreground orange)
+ (all-the-icons-green :foreground teal)
+ (all-the-icons-lcyan :foreground (doom-lighten dark-cyan 0.3))
+ (all-the-icons-lgreen :foreground green)
+ (all-the-icons-lmaroon :foreground light-magenta)
+ (all-the-icons-lorange :foreground orange)
+ (all-the-icons-lpink :foreground light-pink)
+ (all-the-icons-lpurple :foreground light-magenta)
+ (all-the-icons-lred :foreground light-red)
+ (all-the-icons-lsilver :foreground (doom-lighten grey 0.4))
+ (all-the-icons-lyellow :foreground (doom-lighten yellow 0.3))
+ (all-the-icons-pink :foreground pink)
+ (all-the-icons-purple :foreground magenta)
+ (all-the-icons-purple-alt :foreground magenta)
+ (all-the-icons-red-alt :foreground red)
+ (all-the-icons-silver :foreground (doom-lighten grey 0.2))
+ ;;;; all-the-icons-dired
+ (all-the-icons-dired-dir-face :foreground indigo)
+ ;;;; company
+ (company-tooltip :inherit 'tooltip)
+ (company-tooltip-common :foreground highlight)
+ ;;;; company-box
+ (company-box-annotation :foreground base7)
+ ;;;; doom-emacs
+ (doom-dashboard-menu-desc :foreground dark-cyan)
+ (doom-dashboard-menu-tile :foreground dark-teal)
+ ;;;; diredfl
+ (diredfl-date-time :foreground blue)
+ (diredfl-file-name :foreground base7)
+ (diredfl-file-suffix :foreground base6)
+ (diredfl-symlink :foreground dark-cyan)
+ ;;;; dired+
+ (diredp-number :foreground orange)
+ ;;;; dired-k
+ (dired-k-commited :foreground base4)
+ (dired-k-modified :foreground vc-modified)
+ (dired-k-ignored :foreground cyan)
+ (dired-k-added :foreground vc-added)
+ ;;;; magit
+ (magit-filename :foreground teal)
+ ;;;; markdown-mode
+ (markdown-header-face :inherit 'bold :foreground yellow)
+ (markdown-header-delimiter-face :inherit 'markdown-header-face)
+ (markdown-metadata-key-face :foreground magenta :inherit 'italic)
+ (markdown-list-face :foreground red)
+ (markdown-url-face :inherit 'underline :foreground orange)
+ (markdown-gfm-checkbox-face :foreground blue)
+ (markdown-blockquote-face :inherit 'italic :foreground fg)
+ ;;;; nav-flash
+ (nav-flash-face :background region)
+ ;;;; ivy-posframe
+ (ivy-posframe :background base0)
+ (ivy-posframe-border :background base0)
+ ;;;; popup
+ (popup-face :inherit 'tooltip)
+ (popup-selection-face :inherit 'tooltip)
+ ;;;; pos-tip
+ (popup :inherit 'tooltip)
+ (popup-tip-face :inherit 'tooltip)
+ ;;;; rainbow-delimiters
+ (rainbow-delimiters-depth-1-face :foreground magenta)
+ (rainbow-delimiters-depth-2-face :foreground orange)
+ (rainbow-delimiters-depth-3-face :foreground light-red)
+ (rainbow-delimiters-depth-4-face :foreground cyan)
+ (rainbow-delimiters-depth-5-face :foreground violet)
+ (rainbow-delimiters-depth-6-face :foreground yellow)
+ (rainbow-delimiters-depth-7-face :foreground blue)
+ (rainbow-delimiters-depth-8-face :foreground teal)
+ (rainbow-delimiters-depth-9-face :foreground dark-cyan)
+ ;;;; treemacs
+ (treemacs-directory-face :foreground highlight)
+ (treemacs-git-modified-face :foreground highlight)
+ ;;;; workspaces
+ (+workspace-tab-selected-face :background region :foreground blue)
+ ;;;; which-key
+ (which-key-command-description-face :foreground fg)
+ (which-key-group-description-face :foreground magenta)
+ (which-key-local-map-description-face :foreground cyan)))
+
+;;; doom-shades-of-purple-theme.el ends here
diff --git a/elpa/doom-themes-20220504.1557/doom-snazzy-theme.el b/elpa/doom-themes-20220504.1557/doom-snazzy-theme.el
new file mode 100644
index 0000000..6272945
--- /dev/null
+++ b/elpa/doom-themes-20220504.1557/doom-snazzy-theme.el
@@ -0,0 +1,102 @@
+;;; doom-snazzy-theme.el --- inspired by Hyper Snazzy -*- lexical-binding: t; no-byte-compile: t; -*-
+
+;;; Commentary:
+;;; Code:
+(require 'doom-themes)
+
+;; Compiler pacifier
+(defvar modeline-bg)
+
+;;
+(defgroup doom-snazzy-theme nil
+ "Options for the `doom-snazzy' theme."
+ :group 'doom-themes)
+
+;;
+(def-doom-theme doom-snazzy
+ "A dark theme inspired by Atom Snazzy Dark"
+
+ ;; name default 256 16
+ ((bg '("#282a36" "#282a36" nil )) ;; this is the background for the hl-line, modeline, and minibuffer
+ (bg-alt '("#242631" "#242631" nil )) ;; this is the background for the line you arent currently on
+ (base0 '("#282a36" "#282a36" "black" ))
+ (base1 '("#34353e" "#34353e" "brightblack"))
+ (base2 '("#43454f" "#43454f" "brightblack"))
+ (base3 '("#78787e" "#78787e" "brightblack"))
+ (base4 '("#a5a5a9" "#a5a5a9" "brightblack"))
+ (base5 '("#e2e4e5" "#e2e4e5" "brightblack"))
+ (base6 '("#eff0eb" "#eff0eb" "brightblack"))
+ (base7 '("#f1f1f0" "#f1f1f0" "brightblack"))
+ (base8 '("#ff5c57" "#ff5c57" "white" ))
+ (fg '("#f9f9f9" "#f9f9f9" "white" ))
+ (fg-alt '("#d1d1d1" "#d1d1d1" "brightwhite"))
+
+ (ui0 '("#848688" "#848688" "grey"))
+ (ui1 '("#606580" "#606580" "grey"))
+ (ui2 '("#3a3d4d" "#3a3d4d" "grey"))
+ (ui3 '("#1c1e27" "#1c1e27" "black"))
+
+ (grey ui0)
+ (red '("#ff5c57" "#ff5c57" "red" ))
+ (green '("#5af78e" "#5af78e" "brightred" ))
+ (yellow '("#f3f99d" "#f3f99d" "green" ))
+ (blue '("#57c7ff" "#57c7ff" "brightgreen" ))
+ (dark-blue '("#459fcc" "#459fcc" "yellow" ))
+ (magenta '("#ff6ac1" "#ff6ac1" "brightblue" ))
+ (cyan '("#9aedfe" "#9aedfe" "blue" ))
+ (violet '("#bd93f9" "#bd93f9" "magenta" ))
+ (orange '("#ffb86c" "#ffb86c" "brightmagenta"))
+ (teal '("#aad4d3" "#aad4d3" "brightcyan" ))
+ (dark-cyan '("#82c9d7" "#82c9d7" "cyan" ))
+
+ ;; face categories -- required for all themes
+ (highlight blue) ;; when searching with (/) ?
+ (vertical-bar (doom-darken base1 0.1)) ; the bar that separates modeline and minibuffer?
+ (selection dark-blue) ; for like company autocomplete and stuff
+ (builtin magenta) ; saw this in company autocomplete if i moved my mouse
+ ;; over it
+ (comments ui1) ;; comments
+ (doc-comments (doom-lighten yellow 0.25)) ;; easy to test with elisp
+ ;; documentation or git commit
+ ;; first line thing
+ (constants green)
+ (functions blue)
+ (keywords orange)
+ (methods blue) ;; wtf is the difference between this and function?
+ (operators magenta)
+ (type cyan)
+ (strings yellow)
+ ;; (variables (doom-lighten magenta 0.4))
+ (variables red)
+ (numbers yellow)
+ (region `(,(doom-lighten (car bg-alt) 0.15) ,@(doom-lighten (cdr base0) 0.35)))
+ (error red)
+ (warning yellow)
+ (success green)
+ (vc-modified yellow)
+ (vc-added green)
+ (vc-deleted red))
+
+
+ ;;;; Base theme face overrides
+ ((line-number :foreground ui2)
+ (line-number-current-line :foreground fg)
+ ;; i have no idea what im doing with the modeline
+ (mode-line :background (doom-darken bg-alt 0.15))
+ (mode-line-inactive :background (doom-darken bg-alt 0.1) :foreground base5)
+ (tooltip :background (doom-darken bg-alt 0.2) :foreground fg)
+
+ ;;;; doom-modeline
+ (doom-modeline-bar :background highlight)
+ ;;;; ivy-posframe
+ (ivy-posframe-border :background ui3)
+ ;;;; outline <built-in>
+ ((outline-3 &override) :foreground dark-blue)
+ ;;;; org <built-in>
+ ((org-block &override) :background bg-alt)
+ ((org-block-begin-line &override) :background bg-alt)
+ ((org-block-end-line &override) :background bg-alt)
+ ;;;; rjsx-mode
+ (rjsx-text :foreground fg)))
+
+;;; doom-snazzy-theme.el ends here
diff --git a/elpa/doom-themes-20220504.1557/doom-solarized-dark-high-contrast-theme.el b/elpa/doom-themes-20220504.1557/doom-solarized-dark-high-contrast-theme.el
new file mode 100644
index 0000000..d7c4dfe
--- /dev/null
+++ b/elpa/doom-themes-20220504.1557/doom-solarized-dark-high-contrast-theme.el
@@ -0,0 +1,232 @@
+;;; doom-solarized-dark-high-contrast-theme.el --- inspired by VS Code Solarized Dark -*- lexical-binding: t; no-byte-compile: t; -*-
+;;
+;; Author: Ethan Schoonover <https://ethanschoonover.com/solarized/>
+;; Ported by: Joseph Morag <jmorag@users.noreply.github.com>
+;; Created: February 18, 2021
+;; Version: 2.0.0
+;; Keywords: custom themes, faces
+;; Homepage: https://github.com/hlissner/emacs-doom-themes
+;; Package-Requires: ((emacs "25.1") (cl-lib "0.5") (doom-themes "2.2.1"))
+;;
+;;; Commentary:
+;;
+;; See https://ethanschoonover.com/solarized/
+;;
+;;; Code:
+
+(require 'doom-themes)
+
+
+;;
+;;; Variables
+
+(defgroup doom-solarized-dark-high-contrast-theme nil
+ "Options for the `doom-solarized-dark-high-contrast' theme."
+ :group 'doom-themes)
+
+(defcustom doom-solarized-dark-high-contrast-brighter-modeline nil
+ "If non-nil, more vivid colors will be used to style the mode-line."
+ :group 'doom-solarized-dark-high-contrast-theme
+ :type 'boolean)
+
+(defcustom doom-solarized-dark-high-contrast-brighter-comments nil
+ "If non-nil, comments will be highlighted in more vivid colors."
+ :group 'doom-solarized-dark-high-contrast-theme
+ :type 'boolean)
+
+(defcustom doom-solarized-dark-high-contrast-padded-modeline doom-themes-padded-modeline
+ "If non-nil, adds a 4px padding to the mode-line.
+Can be an integer to determine the exact padding."
+ :group 'doom-solarized-dark-high-contrast-theme
+ :type '(choice integer boolean))
+
+
+;;
+;;; Theme definition
+
+(def-doom-theme doom-solarized-dark-high-contrast
+ "A dark theme inspired by VS Code Solarized Dark"
+
+ ;; name default 256 16
+ ((bg '("#002732" "#002732" "black" ))
+ (fg '("#8d9fa1" "#8d9fa1" "brightwhite"))
+
+ ;; These are off-color variants of bg/fg, used primarily for `solaire-mode',
+ ;; but can also be useful as a basis for subtle highlights (e.g. for hl-line
+ ;; or region), especially when paired with the `doom-darken', `doom-lighten',
+ ;; and `doom-blend' helper functions.
+ (bg-alt '("#00212B" "#00212B" "black" ))
+ (fg-alt '("#60767e" "#60767e" "white" ))
+
+ ;; These should represent a spectrum from bg to fg, where base0 is a starker
+ ;; bg and base8 is a starker fg. For example, if bg is light grey and fg is
+ ;; dark grey, base0 should be white and base8 should be black.
+ (base0 '("#01323d" "#01323d" "black" ))
+ (base1 '("#03282F" "#03282F" "brightblack" ))
+ (base2 '("#00212C" "#00212C" "brightblack" ))
+ (base3 '("#13383C" "#13383C" "brightblack" ))
+ (base4 '("#56697A" "#56697A" "brightblack" ))
+ (base5 '("#62787f" "#62787f" "brightblack" ))
+ (base6 '("#96A7A9" "#96A7A9" "brightblack" ))
+ (base7 '("#788484" "#788484" "brightblack" ))
+ (base8 '("#626C6C" "#626C6C" "white" ))
+
+ (grey base4)
+ (red '("#ec423a" "#ec423a" "red" ))
+ (orange '("#db5823" "#db5823" "brightred" ))
+ (green '("#93a61a" "#93a61a" "green" ))
+ (teal '("#35a69c" "#33aa99" "brightgreen" ))
+ (yellow '("#c49619" "#c49619" "yellow" ))
+ (blue '("#3c98e0" "#3c98e0" "brightblue" ))
+ (dark-blue '("#3F88AD" "#2257A0" "blue" ))
+ (magenta '("#e2468f" "#e2468f" "magenta" ))
+ (violet '("#7a7ed2" "#7a7ed2" "brightmagenta"))
+ (cyan '("#3cafa5" "#3cafa5" "brightcyan" ))
+ (dark-cyan '("#03373f" "#03373f" "cyan" ))
+
+ ;; These are the "universal syntax classes" that doom-themes establishes.
+ ;; These *must* be included in every doom themes, or your theme will throw an
+ ;; error, as they are used in the base theme defined in doom-themes-base.
+ (highlight blue)
+ (vertical-bar (doom-darken base1 0.5))
+ (selection dark-blue)
+ (builtin blue)
+ (comments base5)
+ (doc-comments teal)
+ (constants blue)
+ (functions blue)
+ (keywords green)
+ (methods cyan)
+ (operators orange)
+ (type yellow)
+ (strings green)
+ (variables fg)
+ (numbers violet)
+ (region base0)
+ (error red)
+ (warning yellow)
+ (success green)
+ (vc-modified blue)
+ (vc-added "#119e44")
+ (vc-deleted red)
+
+ ;; custom categories
+ (-modeline-bright doom-solarized-dark-high-contrast-brighter-modeline)
+ (-modeline-pad
+ (when doom-solarized-dark-high-contrast-padded-modeline
+ (if (integerp doom-solarized-dark-high-contrast-padded-modeline) doom-solarized-dark-high-contrast-padded-modeline 4)))
+
+ (modeline-fg nil)
+ (modeline-fg-alt base5)
+
+ (modeline-bg
+ (if -modeline-bright
+ base3
+ `(,(doom-darken (car bg) 0.15) ,@(cdr base0))))
+ (modeline-bg-alt
+ (if -modeline-bright
+ base3
+ `(,(doom-darken (car bg) 0.1) ,@(cdr base0))))
+ (modeline-bg-inactive (doom-darken bg 0.1))
+ (modeline-bg-inactive-alt `(,(car bg) ,@(cdr base1))))
+
+
+ ;;;; Base theme face overrides
+ (((font-lock-comment-face &override)
+ :slant 'italic
+ :background (if doom-solarized-dark-high-contrast-brighter-comments
+ (doom-lighten bg 0.05)))
+ ((font-lock-keyword-face &override) :weight 'bold)
+ ((font-lock-constant-face &override) :weight 'bold)
+ ((font-lock-type-face &override) :slant 'italic)
+ ((font-lock-builtin-face &override) :slant 'italic)
+
+ ((line-number &override) :foreground base4)
+ ((line-number-current-line &override) :foreground fg)
+ (mode-line
+ :background modeline-bg :foreground modeline-fg
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg)))
+ (mode-line-inactive
+ :background modeline-bg-inactive :foreground modeline-fg-alt
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive)))
+ (mode-line-emphasis :foreground (if -modeline-bright base8 highlight))
+ (tooltip :background bg-alt :foreground fg)
+
+ ;;;; centaur-tabs
+ (centaur-tabs-active-bar-face :background blue)
+ (centaur-tabs-modified-marker-selected :inherit 'centaur-tabs-selected
+ :foreground blue)
+ (centaur-tabs-modified-marker-unselected :inherit 'centaur-tabs-unselected
+ :foreground blue)
+ ;;;; company
+ (company-tooltip-selection :background dark-cyan)
+ ;;;; css-mode / scss-mode
+ (css-proprietary-property :foreground orange)
+ (css-property :foreground green)
+ (css-selector :foreground blue)
+ ;;;; doom-modeline
+ (doom-modeline-bar :background blue)
+ (doom-modeline-evil-emacs-state :foreground magenta)
+ (doom-modeline-evil-insert-state :foreground blue)
+ ;;;; elscreen
+ (elscreen-tab-other-screen-face :background "#353a42" :foreground "#1e2022")
+ ;;;; eshell-git-prompt powerline theme
+ (eshell-git-prompt-powerline-dir-face :background "steel blue" :foreground bg)
+ (eshell-git-prompt-powerline-clean-face :background "foreset green" :foreground bg)
+ (eshell-git-prompt-powerline-not-clean-face :background "indian red" :foreground bg)
+ ;;; helm
+ (helm-selection :inherit 'bold
+ :background selection
+ :distant-foreground bg
+ :extend t)
+ ;;;; markdown-mode
+ (markdown-markup-face :foreground base5)
+ (markdown-header-face :inherit 'bold :foreground violet)
+ (markdown-url-face :foreground teal :weight 'normal)
+ (markdown-reference-face :foreground base6)
+ ((markdown-bold-face &override) :foreground fg)
+ ((markdown-italic-face &override) :foreground fg-alt)
+ ;;;; outline (affects org-mode)
+ ((outline-1 &override) :foreground blue)
+ ((outline-2 &override) :foreground green)
+ ((outline-3 &override) :foreground teal)
+ ((outline-4 &override) :foreground (doom-darken blue 0.2))
+ ((outline-5 &override) :foreground (doom-darken green 0.2))
+ ((outline-6 &override) :foreground (doom-darken teal 0.2))
+ ((outline-7 &override) :foreground (doom-darken blue 0.4))
+ ((outline-8 &override) :foreground (doom-darken green 0.4))
+ ;;;; org <built-in>
+ ((org-block &override) :background base0)
+ ((org-block-begin-line &override) :foreground comments :background base0)
+ ;;;; git-gutter-fringe
+ (git-gutter-fr:modified :foreground vc-modified)
+ ;;;; rainbow-delimeters
+ (rainbow-delimiters-depth-1-face :foreground blue)
+ (rainbow-delimiters-depth-2-face :foreground yellow)
+ (rainbow-delimiters-depth-3-face :foreground orange)
+ (rainbow-delimiters-depth-4-face :foreground green)
+ (rainbow-delimiters-depth-5-face :foreground cyan)
+ (rainbow-delimiters-depth-6-face :foreground violet)
+ ;;;; solaire-mode
+ (solaire-mode-line-face
+ :inherit 'mode-line
+ :background modeline-bg-alt
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-alt)))
+ (solaire-mode-line-inactive-face
+ :inherit 'mode-line-inactive
+ :background modeline-bg-inactive-alt
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive-alt)))
+ ;;;; vterm
+ (vterm :foreground fg)
+ (vterm-color-default :foreground fg)
+ (vterm-color-black :background (doom-lighten base0 0.75) :foreground base0)
+ (vterm-color-red :background (doom-lighten red 0.75) :foreground red)
+ (vterm-color-green :background (doom-lighten green 0.75) :foreground green)
+ (vterm-color-yellow :background (doom-lighten yellow 0.75) :foreground yellow)
+ (vterm-color-blue :background (doom-lighten blue 0.75) :foreground blue)
+ (vterm-color-magenta :background (doom-lighten magenta 0.75) :foreground magenta)
+ (vterm-color-cyan :background (doom-lighten cyan 0.75) :foreground cyan)
+ (vterm-color-white :background (doom-lighten base8 0.75) :foreground base8)
+ ))
+
+;;; doom-solarized-dark-high-contrast-theme.el ends here
diff --git a/elpa/doom-themes-20220504.1557/doom-solarized-dark-theme.el b/elpa/doom-themes-20220504.1557/doom-solarized-dark-theme.el
new file mode 100644
index 0000000..090c379
--- /dev/null
+++ b/elpa/doom-themes-20220504.1557/doom-solarized-dark-theme.el
@@ -0,0 +1,210 @@
+;;; doom-solarized-dark-theme.el --- inspired by VS Code Solarized Dark -*- lexical-binding: t; no-byte-compile: t; -*-
+;;
+;; Author: Ethan Schoonover <https://ethanschoonover.com/solarized/>
+;; Ported by: Emmanuel Bustos Torres <ema2159@gmail.com>
+;; Created: July 14, 2019
+;; Version: 2.0.0
+;; Keywords: custom themes, faces
+;; Homepage: https://github.com/hlissner/emacs-doom-themes
+;; Package-Requires: ((emacs "25.1") (cl-lib "0.5") (doom-themes "2.2.1"))
+;;
+;;; Commentary:
+;;
+;; See https://ethanschoonover.com/solarized/
+;;
+;;; Code:
+
+(require 'doom-themes)
+
+
+;;
+;;; Variables
+
+(defgroup doom-solarized-dark-theme nil
+ "Options for the `doom-solarized-dark' theme."
+ :group 'doom-themes)
+
+(defcustom doom-solarized-dark-brighter-modeline nil
+ "If non-nil, more vivid colors will be used to style the mode-line."
+ :group 'doom-solarized-dark-theme
+ :type 'boolean)
+
+(defcustom doom-solarized-dark-brighter-comments nil
+ "If non-nil, comments will be highlighted in more vivid colors."
+ :group 'doom-solarized-dark-theme
+ :type 'boolean)
+
+(defcustom doom-solarized-dark-brighter-text nil
+ "If non-nil, default text will be brighter."
+ :group 'doom-solarized-dark-theme
+ :type 'boolean)
+
+(defcustom doom-solarized-dark-padded-modeline doom-themes-padded-modeline
+ "If non-nil, adds a 4px padding to the mode-line.
+Can be an integer to determine the exact padding."
+ :group 'doom-solarized-dark-theme
+ :type '(choice integer boolean))
+
+
+;;
+;;; Theme definition
+
+(def-doom-theme doom-solarized-dark
+ "A dark theme inspired by VS Code Solarized Dark"
+
+ ;; name default 256 16
+ ((bg '("#002b36" "#002b36" "brightwhite" ))
+ (fg (if doom-solarized-dark-brighter-text
+ '("#BBBBBB" "#BBBBBB" "brightwhite")
+ '("#839496" "#839496" "brightwhite")))
+
+ ;; These are off-color variants of bg/fg, used primarily for `solaire-mode',
+ ;; but can also be useful as a basis for subtle highlights (e.g. for hl-line
+ ;; or region), especially when paired with the `doom-darken', `doom-lighten',
+ ;; and `doom-blend' helper functions.
+ (bg-alt '("#00212B" "#00212B" "white" ))
+ (fg-alt '("#657b83" "#657b83" "white" ))
+
+ ;; These should represent a spectrum from bg to fg, where base0 is a starker
+ ;; bg and base8 is a starker fg. For example, if bg is light grey and fg is
+ ;; dark grey, base0 should be white and base8 should be black.
+ (base0 '("#073642" "#073642" "black" ))
+ (base1 '("#03282F" "#03282F" "brightblack" ))
+ (base2 '("#00212C" "#00212C" "brightblack" ))
+ (base3 '("#13383C" "#13383C" "brightblack" ))
+ (base4 '("#56697A" "#56697A" "brightblack" ))
+ (base5 '("#405A61" "#405A61" "brightblack" ))
+ (base6 '("#96A7A9" "#96A7A9" "brightblack" ))
+ (base7 '("#788484" "#788484" "brightblack" ))
+ (base8 '("#626C6C" "#626C6C" "white" ))
+
+ (grey base4)
+ (red '("#dc322f" "#ff6655" "red" ))
+ (orange '("#cb4b16" "#dd8844" "brightred" ))
+ (green '("#859900" "#99bb66" "green" ))
+ (teal '("#35a69c" "#33aa99" "brightgreen" ))
+ (yellow '("#b58900" "#ECBE7B" "yellow" ))
+ (blue '("#268bd2" "#51afef" "brightblue" ))
+ (dark-blue '("#3F88AD" "#2257A0" "blue" ))
+ (magenta '("#d33682" "#c678dd" "magenta" ))
+ (violet '("#6c71c4" "#a9a1e1" "brightmagenta"))
+ (cyan '("#2aa198" "#46D9FF" "brightcyan" ))
+ (dark-cyan '("#204052" "#5699AF" "cyan" ))
+
+ ;; face categories -- required for all themes
+ (highlight blue)
+ (vertical-bar (doom-darken base1 0.5))
+ (selection dark-blue)
+ (builtin blue)
+ (comments (if doom-solarized-dark-brighter-comments blue base5))
+ (doc-comments teal)
+ (constants magenta)
+ (functions blue)
+ (keywords green)
+ (methods cyan)
+ (operators orange)
+ (type yellow)
+ (strings cyan)
+ (variables violet)
+ (numbers magenta)
+ (region base0)
+ (error red)
+ (warning yellow)
+ (success green)
+ (vc-modified yellow)
+ (vc-added green)
+ (vc-deleted red)
+
+ ;; custom categories
+ (-modeline-bright doom-solarized-dark-brighter-modeline)
+ (-modeline-pad
+ (when doom-solarized-dark-padded-modeline
+ (if (integerp doom-solarized-dark-padded-modeline) doom-solarized-dark-padded-modeline 4)))
+
+ (modeline-fg nil)
+ (modeline-fg-alt base5)
+
+ (modeline-bg
+ (if -modeline-bright
+ base3
+ `(,(doom-darken (car bg) 0.1) ,@(cdr base0))))
+ (modeline-bg-alt
+ (if -modeline-bright
+ base3
+ `(,(doom-darken (car bg) 0.15) ,@(cdr base0))))
+ (modeline-bg-inactive `(,(car bg-alt) ,@(cdr base1)))
+ (modeline-bg-inactive-alt (doom-darken bg 0.1)))
+
+
+ ;;;; Base theme face overrides
+ (((font-lock-comment-face &override)
+ :background (if doom-solarized-dark-brighter-comments (doom-lighten bg 0.05)))
+ ((font-lock-keyword-face &override) :weight 'bold)
+ ((font-lock-constant-face &override) :weight 'bold)
+ ((line-number &override) :foreground base4)
+ ((line-number-current-line &override) :foreground fg)
+ (mode-line
+ :background modeline-bg :foreground modeline-fg
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg)))
+ (mode-line-inactive
+ :background modeline-bg-inactive :foreground modeline-fg-alt
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive)))
+ (mode-line-emphasis :foreground (if -modeline-bright base8 highlight))
+
+ ;;;; centaur-tabs
+ (centaur-tabs-active-bar-face :background blue)
+ (centaur-tabs-modified-marker-selected
+ :inherit 'centaur-tabs-selected :foreground blue)
+ (centaur-tabs-modified-marker-unselected
+ :inherit 'centaur-tabs-unselected :foreground blue)
+ ;;;; company
+ (company-tooltip-selection :background dark-cyan)
+ ;;;; css-mode <built-in> / scss-mode
+ (css-proprietary-property :foreground orange)
+ (css-property :foreground green)
+ (css-selector :foreground blue)
+ ;;;; doom-modeline
+ (doom-modeline-bar :background blue)
+ (doom-modeline-evil-emacs-state :foreground magenta)
+ (doom-modeline-evil-insert-state :foreground blue)
+ ;;;; elscreen
+ (elscreen-tab-other-screen-face :background "#353a42" :foreground "#1e2022")
+ ;;;; helm
+ (helm-selection :inherit 'bold
+ :background selection
+ :distant-foreground bg
+ :extend t)
+ ;;;; markdown-mode
+ (markdown-markup-face :foreground base5)
+ (markdown-header-face :inherit 'bold :foreground red)
+ (markdown-url-face :foreground teal :weight 'normal)
+ (markdown-reference-face :foreground base6)
+ ((markdown-bold-face &override) :foreground fg)
+ ((markdown-italic-face &override) :foreground fg-alt)
+ ;;;; outline <built-in>
+ ((outline-1 &override) :foreground blue)
+ ((outline-2 &override) :foreground green)
+ ((outline-3 &override) :foreground teal)
+ ((outline-4 &override) :foreground (doom-darken blue 0.2))
+ ((outline-5 &override) :foreground (doom-darken green 0.2))
+ ((outline-6 &override) :foreground (doom-darken teal 0.2))
+ ((outline-7 &override) :foreground (doom-darken blue 0.4))
+ ((outline-8 &override) :foreground (doom-darken green 0.4))
+ ;;;; org <built-in>
+ ((org-block &override) :background base0)
+ ((org-block-begin-line &override) :foreground comments :background base0)
+ ;;;; solaire-mode
+ (solaire-mode-line-face
+ :inherit 'mode-line
+ :background modeline-bg-alt
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-alt)))
+ (solaire-mode-line-inactive-face
+ :inherit 'mode-line-inactive
+ :background modeline-bg-inactive-alt
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive-alt))))
+
+ ;;;; Base theme variable overrides-
+ ;; ()
+ )
+
+;;; doom-solarized-dark-theme.el ends here
diff --git a/elpa/doom-themes-20220504.1557/doom-solarized-light-theme.el b/elpa/doom-themes-20220504.1557/doom-solarized-light-theme.el
new file mode 100644
index 0000000..e2d3617
--- /dev/null
+++ b/elpa/doom-themes-20220504.1557/doom-solarized-light-theme.el
@@ -0,0 +1,216 @@
+;;; doom-solarized-light-theme.el --- inspired by Atom One Dark -*- lexical-binding: t; no-byte-compile: t; -*-
+;;
+;; Author: Ethan Schoonover <https://ethanschoonover.com/solarized/>
+;; Ported by: Xi "Alexander" Fu <fuxialexander@users.noreply.github.com>
+;; Created: February 20, 2018
+;; Version: 2.0.0
+;; Keywords: custom themes, faces
+;; Homepage: https://github.com/hlissner/emacs-doom-themes
+;; Package-Requires: ((emacs "25.1") (cl-lib "0.5") (doom-themes "2.2.1"))
+;;
+;;; Commentary:
+;;
+;; See https://ethanschoonover.com/solarized/
+;;
+;;; Code:
+
+(require 'doom-themes)
+
+
+;;
+;;; Variables
+
+(defgroup doom-solarized-light-theme nil
+ "Options for the `doom-solarized-light' theme."
+ :group 'doom-themes)
+
+(defcustom doom-solarized-light-brighter-modeline nil
+ "If non-nil, more vivid colors will be used to style the mode-line."
+ :group 'doom-solarized-light-theme
+ :type 'boolean)
+
+(defcustom doom-solarized-light-brighter-comments nil
+ "If non-nil, comments will be highlighted in more vivid colors."
+ :group 'doom-solarized-light-theme
+ :type 'boolean)
+
+(defcustom doom-solarized-light-padded-modeline doom-themes-padded-modeline
+ "If non-nil, adds a 4px padding to the mode-line.
+Can be an integer to determine the exact padding."
+ :group 'doom-solarized-light-theme
+ :type '(choice integer boolean))
+
+
+;;
+;;; Theme definition
+
+(def-doom-theme doom-solarized-light
+ "A light theme inspired by Solarized light"
+
+ ;; name default 256 16
+ ((bg '("#FDF6E3" "#FDF6E3" "white" ))
+ (fg '("#556b72" "#556b72" "black" ))
+
+ ;; These are off-color variants of bg/fg, used primarily for `solaire-mode',
+ ;; but can also be useful as a basis for subtle highlights (e.g. for hl-line
+ ;; or region), especially when paired with the `doom-darken', `doom-lighten',
+ ;; and `doom-blend' helper functions.
+ (bg-alt '("#EEE8D5" "#EEE8D5" "white" ))
+ (fg-alt '("#7B8787" "#7B8787" "brightwhite" ))
+
+ ;; These should represent a spectrum from bg to fg, where base0 is a starker
+ ;; bg and base8 is a starker fg. For example, if bg is light grey and fg is
+ ;; dark grey, base0 should be white and base8 should be black.
+ (base0 '("#FFFBF0" "#FFFBF0" "white" ))
+ (base1 '("#FCF8ED" "#FCF8ED" "brightblack" ))
+ (base2 '("#FCF7E8" "#FCF7E8" "brightblack" ))
+ (base3 '("#F2E6CE" "#F2E6CE" "brightblack" ))
+ (base4 '("#E1DBCD" "#E1DBCD" "brightblack" ))
+ (base5 '("#D6D6D6" "#D6D6D6" "brightblack" ))
+ (base6 '("#96A7A9" "#96A7A9" "brightblack" ))
+ (base7 '("#788484" "#788484" "brightblack" ))
+ (base8 '("#626C6C" "#626C6C" "black" ))
+
+ (grey base4)
+ (red '("#dc322f" "#dc322f" "red" ))
+ (orange '("#cb4b16" "#cb4b16" "brightred" ))
+ (green '("#859900" "#859900" "green" ))
+ (teal '("#35a69c" "#35a69c" "brightgreen" ))
+ (yellow '("#b58900" "#b58900" "yellow" ))
+ (blue '("#268bd2" "#268bd2" "brightblue" ))
+ (dark-blue '("#3F88AD" "#3F88AD" "blue" ))
+ (magenta '("#d33682" "#d33682" "magenta" ))
+ (violet '("#6c71c4" "#6c71c4" "brightmagenta"))
+ (cyan '("#2aa198" "#2aa198" "brightcyan" ))
+ (dark-cyan '("#204052" "#204052" "cyan" ))
+
+ ;; face categories -- required for all themes
+ (highlight blue)
+ (vertical-bar base4)
+ (selection dark-blue)
+ (builtin magenta)
+ (comments (if doom-solarized-light-brighter-comments
+ (doom-lighten teal 0.25)
+ base6))
+ (doc-comments teal)
+ (constants violet)
+ (functions magenta)
+ (keywords green)
+ (methods cyan)
+ (operators blue)
+ (type yellow)
+ (strings cyan)
+ (variables blue)
+ (numbers violet)
+ (region `(,(doom-darken (car bg-alt) 0.1) ,@(doom-darken (cdr base0) 0.1)))
+ (error red)
+ (warning yellow)
+ (success green)
+ (vc-modified orange)
+ (vc-added green)
+ (vc-deleted red)
+
+ ;; custom categories
+ (-modeline-bright doom-solarized-light-brighter-modeline)
+ (-modeline-pad
+ (when doom-solarized-light-padded-modeline
+ (if (integerp doom-solarized-light-padded-modeline) doom-solarized-light-padded-modeline 4)))
+
+ (modeline-fg nil)
+ (modeline-fg-alt base6)
+
+ (modeline-bg
+ (if -modeline-bright
+ (doom-lighten bg 0.7)
+ (doom-darken bg 0.05)))
+ (modeline-bg-alt
+ (if -modeline-bright
+ (doom-lighten bg 0.7)
+ (doom-lighten base3 0.2)))
+ (modeline-bg-inactive (doom-darken bg 0.025))
+ (modeline-bg-inactive-alt (doom-darken bg 0.02)))
+
+
+ ;;;; Base theme face overrides
+ (((font-lock-comment-face &override)
+ :slant 'italic
+ :background (if doom-solarized-light-brighter-comments
+ (doom-blend teal base0 0.07)))
+ ((font-lock-type-face &override) :slant 'italic)
+ ((font-lock-builtin-face &override) :slant 'italic)
+ ((font-lock-function-name-face &override) :foreground type)
+ ((font-lock-keyword-face &override) :weight 'bold)
+ ((font-lock-constant-face &override) :weight 'bold)
+ (hl-line :background base3)
+ ((line-number &override) :foreground base6)
+ ((line-number-current-line &override) :foreground fg :background region :weight 'bold)
+ (mode-line
+ :background modeline-bg :foreground modeline-fg
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg)))
+ (mode-line-inactive
+ :background modeline-bg-inactive :foreground modeline-fg-alt
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive)))
+ (mode-line-emphasis :foreground (if -modeline-bright base8 highlight))
+
+ ;;;; doom-modeline
+ (doom-modeline-bar :background (if -modeline-bright modeline-bg highlight))
+ (doom-modeline-evil-emacs-state :foreground magenta)
+ (doom-modeline-evil-insert-state :foreground blue)
+ ;;;; solaire-mode
+ (solaire-mode-line-face
+ :inherit 'mode-line
+ :background modeline-bg-alt
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-alt)))
+ (solaire-mode-line-inactive-face
+ :inherit 'mode-line-inactive
+ :background modeline-bg-inactive-alt
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive-alt)))
+ ;;;; elscreen
+ (elscreen-tab-other-screen-face :background "#353a42" :foreground "#1e2022")
+ ;;;; css-mode <built-in> / scss-mode
+ (css-proprietary-property :foreground orange)
+ (css-property :foreground green)
+ (css-selector :foreground blue)
+ ;;;; lsp-ui
+ (lsp-ui-sideline-code-action :foreground blue)
+ ;;;; markdown-mode
+ (markdown-markup-face :foreground base5)
+ (markdown-header-face :inherit 'bold :foreground red)
+ ((markdown-code-face &override) :background (doom-lighten base3 0.05))
+ ;;;; ivy
+ (ivy-current-match :background (doom-lighten yellow 0.65) :distant-foreground fg)
+ (ivy-minibuffer-match-face-1 :foreground blue :background base3 :weight 'bold)
+ (ivy-minibuffer-match-face-2 :foreground magenta :background base3 :weight 'bold)
+ (ivy-minibuffer-match-face-3 :foreground green :background base3 :weight 'bold)
+ (ivy-minibuffer-match-face-4 :foreground yellow :background base3 :weight 'bold)
+ (ivy-minibuffer-match-highlight :foreground violet :weight 'bold)
+ ;;;; ivy-posframe
+ (ivy-posframe :background modeline-bg-alt)
+ ;;;; swiper
+ (swiper-match-face-1 :inherit 'ivy-minibuffer-match-face-1)
+ (swiper-match-face-2 :inherit 'ivy-minibuffer-match-face-2)
+ (swiper-match-face-3 :inherit 'ivy-minibuffer-match-face-3)
+ (swiper-match-face-4 :inherit 'ivy-minibuffer-match-face-4)
+ ;;;; helm
+ (helm-selection :foreground base0 :weight 'bold :background blue)
+ ;;;; company
+ (company-tooltip-selection :background blue :foreground base3)
+ ;;;; org <built-in>
+ (org-block :background (doom-blend yellow bg 0.04) :extend t)
+ (org-block-background :background (doom-blend yellow bg 0.04))
+ (org-block-begin-line :background (doom-blend yellow bg 0.08) :extend t)
+ (org-block-end-line :background (doom-blend yellow bg 0.08) :extend t)
+ ;;;; widget
+ (widget-field :foreground fg :background base3)
+ (widget-single-line-field :foreground fg :background base3)
+ ;;;; latex
+ (font-latex-sedate-face :foreground base6)
+ ;;;; notmuch
+ (notmuch-message-summary-face :foreground teal)
+ (notmuch-wash-cited-text :foreground base6))
+
+ ;;;; Base theme variable overrides-
+ ;; ()
+ )
+
+;;; doom-solarized-light-theme.el ends here
diff --git a/elpa/doom-themes-20220504.1557/doom-sourcerer-theme.el b/elpa/doom-themes-20220504.1557/doom-sourcerer-theme.el
new file mode 100644
index 0000000..183eaf4
--- /dev/null
+++ b/elpa/doom-themes-20220504.1557/doom-sourcerer-theme.el
@@ -0,0 +1,168 @@
+;; doom-sourcerer-theme.el --- a more Sourcerer version of doom-one -*- lexical-binding: t; no-byte-compile: t; -*-
+;;; Commentary:
+(require 'doom-themes)
+;;; Code:
+;;
+(defgroup doom-sourcerer-theme nil
+ "Options for the `doom-sourcerer' theme."
+ :group 'doom-themes)
+
+(defcustom doom-sourcerer-brighter-modeline nil
+ "If non-nil, more vivid colors will be used to style the mode-line."
+ :group 'doom-sourcerer-theme
+ :type 'boolean)
+
+(defcustom doom-sourcerer-brighter-comments nil
+ "If non-nil, comments will be highlighted in more vivid colors."
+ :group 'doom-sourcerer-theme
+ :type 'boolean)
+
+(defcustom doom-sourcerer-comment-bg doom-sourcerer-brighter-comments
+ "If non-nil, comments will have a subtle, darker background.
+Enhancing their legibility."
+ :group 'doom-sourcerer-theme
+ :type 'boolean)
+
+(defcustom doom-sourcerer-padded-modeline doom-themes-padded-modeline
+ "If non-nil, adds a 4px padding to the mode-line.
+Can be an integer to determine the exact padding."
+ :group 'doom-sourcerer-theme
+ :type '(choice integer boolean))
+
+
+;;
+(def-doom-theme doom-sourcerer
+ "A dark theme based off of xero's Sourcerer VIM colorscheme"
+
+ ((bg '("#171717"))
+ (bg-alt '("#222222"))
+ (base0 '("#1d2127"))
+ (base1 '("#1d2127"))
+ (base2 '("#272727"))
+ (base3 '("#32353f"))
+ (base4 '("#494952"))
+ (base5 '("#62686E"))
+ (base6 '("#757B80"))
+ (base7 '("#9ca0a4"))
+ (base8 '("#faf4c6"))
+ (fg '("#c2c2b0"))
+ (fg-alt '("#5D656B"))
+
+ (grey '("#686858"))
+ (red '("#aa4450"))
+ (orange '("#ff9800"))
+ (green '("#87875f"))
+ (green-br '("#719611"))
+ (teal '("#578F8F" "#44b9b1" ))
+ (yellow '("#cc8800" ))
+ (blue '("#87AFD7" ))
+ (dark-blue '("#6688aa" ))
+ (magenta '("#8787AF" ))
+ (violet '("#8181a6" ))
+ (cyan '("#87ceeb" ))
+ (dark-cyan '("#528b8b" ))
+ ;; face categories
+ (highlight cyan)
+ (vertical-bar base0)
+ (selection base5)
+ (builtin blue)
+ (comments (if doom-sourcerer-brighter-comments dark-cyan grey))
+ (doc-comments (if doom-sourcerer-brighter-comments (doom-lighten dark-cyan 0.15) (doom-darken grey 0.1)))
+ (constants teal)
+ (functions base8)
+ (keywords blue)
+ (methods magenta)
+ (operators green-br)
+ (type violet)
+ (strings green)
+ (variables base8)
+ (numbers yellow)
+ (region base3)
+ (error red)
+ (warning orange)
+ (success green)
+ (vc-modified yellow)
+ (vc-added green)
+ (vc-deleted red)
+
+ ;; custom categories
+ (hidden `(,(car bg) "black" "black"))
+ (hidden-alt `(,(car bg-alt) "black" "black"))
+ (-modeline-pad
+ (when doom-sourcerer-padded-modeline
+ (if (integerp doom-sourcerer-padded-modeline) doom-sourcerer-padded-modeline 4)))
+
+ (modeline-fg "#bbc2cf")
+ (modeline-fg-alt (doom-blend blue grey (if doom-sourcerer-brighter-modeline 0.4 0.08)))
+
+ (modeline-bg
+ (if doom-sourcerer-brighter-modeline
+ modeline-bg
+ `(,(doom-darken (car bg) 0.15) ,@(cdr base1))))
+ (modeline-bg-l
+ (if doom-sourcerer-brighter-modeline
+ `("#383f58" ,@(cdr base1))
+ `(,(car base3) ,@(cdr base0))))
+ (modeline-bg-inactive `(,(doom-darken (car bg-alt) 0.2) ,@(cdr base0)))
+ (modeline-bg-inactive-l (doom-darken bg 0.20)))
+
+ ;;;; Base theme face overrides
+ ((cursor :background blue)
+ ((font-lock-comment-face &override)
+ :background (if doom-sourcerer-comment-bg (doom-darken bg-alt 0.095)))
+ ((line-number &override) :foreground base4)
+ ((line-number-current-line &override) :foreground blue :bold bold)
+ (mode-line
+ :background base3 :foreground modeline-fg
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,base3)))
+ (mode-line-inactive
+ :background bg-alt :foreground modeline-fg-alt
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive)))
+ (mode-line-emphasis :foreground (if doom-sourcerer-brighter-modeline base8 highlight))
+ (mode-line-buffer-id :foreground green-br :bold bold)
+
+ ;;;; company
+ (company-tooltip-selection :background base3)
+ ;;;; css-mode <built-in> / scss-mode
+ (css-proprietary-property :foreground orange)
+ (css-property :foreground green)
+ (css-selector :foreground blue)
+ ;;;; doom-modeline
+ (doom-modeline-bar :background (if doom-sourcerer-brighter-modeline modeline-bg highlight))
+ (doom-modeline-buffer-path :foreground (if doom-sourcerer-brighter-modeline base8 blue) :bold bold)
+ ;;;; elscreen
+ (elscreen-tab-other-screen-face :background "#353a42" :foreground "#1e2022")
+ ;;;; markdown-mode
+ (markdown-header-face :inherit 'bold :foreground red)
+ ;;;; org <built-in>
+ ((org-block &override) :background bg-alt)
+ ((org-block-begin-line &override) :background bg-alt)
+ ((org-block-end-line &override) :background bg-alt)
+ (org-hide :foreground hidden)
+ ;;;; rainbow-delimiters
+ (rainbow-delimiters-depth-1-face :foreground dark-cyan)
+ (rainbow-delimiters-depth-2-face :foreground teal)
+ (rainbow-delimiters-depth-3-face :foreground dark-blue)
+ (rainbow-delimiters-depth-4-face :foreground green)
+ (rainbow-delimiters-depth-5-face :foreground violet)
+ (rainbow-delimiters-depth-6-face :foreground green)
+ (rainbow-delimiters-depth-7-face :foreground orange)
+ ;;;; rjsx-mode
+ (rjsx-attr :foreground magenta :slant 'italic :weight 'medium)
+ (rjsx-tag :foreground blue)
+ (rjsx-tag-bracket-face :foreground base8)
+ ;;;; solaire-mode
+ (solaire-mode-line-face
+ :inherit 'mode-line
+ :background modeline-bg-l
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-l)))
+ (solaire-mode-line-inactive-face
+ :inherit 'mode-line-inactive
+ :background modeline-bg-inactive-l
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive-l))))
+
+ ;;;; Base theme variable overrides
+ ;; ()
+ )
+
+;;; doom-sourcerer-theme.el ends here
diff --git a/elpa/doom-themes-20220504.1557/doom-spacegrey-theme.el b/elpa/doom-themes-20220504.1557/doom-spacegrey-theme.el
new file mode 100644
index 0000000..c1a4bb9
--- /dev/null
+++ b/elpa/doom-themes-20220504.1557/doom-spacegrey-theme.el
@@ -0,0 +1,161 @@
+;;; doom-spacegrey-theme.el --- inspired by Atom Spacegrey Dark -*- lexical-binding: t; no-byte-compile: t; -*-
+(require 'doom-themes)
+
+(defgroup doom-spacegrey-theme nil
+ "Options for the `doom-spacegrey' theme."
+ :group 'doom-themes)
+
+(defcustom doom-spacegrey-brighter-modeline nil
+ "If non-nil, more vivid colors will be used to style the mode-line."
+ :group 'doom-spacegrey-theme
+ :type 'boolean)
+
+(defcustom doom-spacegrey-brighter-comments nil
+ "If non-nil, comments will be highlighted in more vivid colors."
+ :group 'doom-spacegrey-theme
+ :type 'boolean)
+
+(defcustom doom-spacegrey-comment-bg doom-spacegrey-brighter-comments
+ "If non-nil, comments will have a subtle, darker background. Enhancing their
+legibility."
+ :group 'doom-spacegrey-theme
+ :type 'boolean)
+
+(defcustom doom-spacegrey-padded-modeline doom-themes-padded-modeline
+ "If non-nil, adds a 4px padding to the mode-line. Can be an integer to
+determine the exact padding."
+ :group 'doom-spacegrey-theme
+ :type '(choice integer boolean))
+
+;;
+(def-doom-theme doom-spacegrey
+ "A dark theme inspired by Atom Spacegrey Dark"
+
+ ;; name default 256 16
+ ((bg '("#2b303b" nil nil ))
+ (bg-alt '("#232830" nil nil ))
+ (base0 '("#1B2229" "black" "black" ))
+ (base1 '("#1c1f24" "#1e1e1e" "brightblack" ))
+ (base2 '("#202328" "#2e2e2e" "brightblack" ))
+ (base3 '("#2F3237" "#2F3237" "brightblack" ))
+ (base4 '("#4f5b66" "#4f5b66" "brightblack" ))
+ (base5 '("#65737E" "#65737E" "brightblack" ))
+ (base6 '("#73797e" "#6b6b6b" "brightblack" ))
+ (base7 '("#9ca0a4" "#979797" "brightblack" ))
+ (base8 '("#DFDFDF" "#dfdfdf" "white" ))
+ (fg '("#c0c5ce" "#c0c5ce" "brightwhite" ))
+ (fg-alt '("#c0c5ce" "#c0c5ce" "white" ))
+
+ (grey base4)
+ (red '("#BF616A" "#BF616A" "red" ))
+ (orange '("#D08770" "#D08770" "brightred" ))
+ (green '("#A3BE8C" "#A3BE8C" "green" ))
+ (blue '("#8FA1B3" "#8FA1B3" "brightblue" ))
+ (violet '("#b48ead" "#b48ead" "brightmagenta"))
+ (teal '("#4db5bd" "#44b9b1" "brightgreen" ))
+ (yellow '("#ECBE7B" "#ECBE7B" "yellow" ))
+ (dark-blue '("#2257A0" "#2257A0" "blue" ))
+ (magenta '("#c678dd" "#c678dd" "magenta" ))
+ (cyan '("#46D9FF" "#46D9FF" "brightcyan" ))
+ (dark-cyan '("#5699AF" "#5699AF" "cyan" ))
+
+ ;; face categories -- required for all themes
+ (highlight orange)
+ (vertical-bar (doom-darken bg 0.25))
+ (selection base4)
+ (builtin orange)
+ (comments (if doom-spacegrey-brighter-comments dark-cyan base5))
+ (doc-comments (doom-lighten (if doom-spacegrey-brighter-comments dark-cyan base5) 0.25))
+ (constants orange)
+ (functions blue)
+ (keywords violet)
+ (methods blue)
+ (operators fg)
+ (type yellow)
+ (strings green)
+ (variables red)
+ (numbers orange)
+ (region selection)
+ (error red)
+ (warning yellow)
+ (success green)
+ (vc-modified orange)
+ (vc-added green)
+ (vc-deleted red)
+
+ ;; custom categories
+ (hidden `(,(car bg-alt) "black" "black"))
+ (-modeline-bright doom-spacegrey-brighter-modeline)
+ (-modeline-pad
+ (when doom-spacegrey-padded-modeline
+ (if (integerp doom-spacegrey-padded-modeline) doom-spacegrey-padded-modeline 4)))
+
+ (modeline-fg nil)
+ (modeline-fg-alt (doom-blend violet base4 (if -modeline-bright 0.5 0.2)))
+ (modeline-bg
+ (if -modeline-bright
+ (doom-darken base3 0.1)
+ base1))
+ (modeline-bg-l
+ (if -modeline-bright
+ (doom-darken base3 0.05)
+ base1))
+ (modeline-bg-inactive `(,(doom-darken (car bg-alt) 0.05) ,@(cdr base1)))
+ (modeline-bg-inactive-l (doom-darken bg 0.1)))
+
+
+ ;;;; Base theme face overrides
+ (((font-lock-comment-face &override)
+ :background (if doom-spacegrey-comment-bg (doom-lighten bg 0.05)))
+ ((line-number &override) :foreground base4)
+ ((line-number-current-line &override) :foreground fg)
+ (mode-line
+ :background modeline-bg :foreground modeline-fg
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg)))
+ (mode-line-inactive
+ :background modeline-bg-inactive :foreground modeline-fg-alt
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive)))
+ (mode-line-emphasis :foreground (if -modeline-bright base8 highlight))
+
+ ;;;; css-mode <built-in> / scss-mode
+ (css-proprietary-property :foreground orange)
+ (css-property :foreground fg)
+ (css-selector :foreground red)
+ ;;;; doom-modeline
+ (doom-modeline-bar :background (if -modeline-bright modeline-bg highlight))
+ ;;;; elscreen
+ (elscreen-tab-other-screen-face :background "#353a42" :foreground "#1e2022")
+ ;;;; markdown-mode
+ (markdown-markup-face :foreground base5)
+ (markdown-header-face :inherit 'bold :foreground red)
+ ((markdown-code-face &override) :background (doom-darken bg 0.1))
+ ;;;; outline <built-in>
+ ((outline-1 &override) :foreground fg :weight 'ultra-bold)
+ ((outline-2 &override) :foreground (doom-blend fg blue 0.35))
+ ((outline-3 &override) :foreground (doom-blend fg blue 0.7))
+ ((outline-4 &override) :foreground blue)
+ ((outline-5 &override) :foreground (doom-blend magenta blue 0.2))
+ ((outline-6 &override) :foreground (doom-blend magenta blue 0.4))
+ ((outline-7 &override) :foreground (doom-blend magenta blue 0.6))
+ ((outline-8 &override) :foreground fg)
+ ;;;; org <built-in>
+ (org-block :background (doom-darken bg-alt 0.04))
+ (org-block-begin-line :foreground base4 :slant 'italic :background (doom-darken bg 0.04))
+ (org-ellipsis :underline nil :background bg :foreground red)
+ ((org-quote &override) :background base1)
+ (org-hide :foreground bg)
+ ;;;; solaire-mode
+ (solaire-mode-line-face
+ :inherit 'mode-line
+ :background modeline-bg-l
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-l)))
+ (solaire-mode-line-inactive-face
+ :inherit 'mode-line-inactive
+ :background modeline-bg-inactive-l
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive-l))))
+
+ ;;;; Base theme variable overrides-
+ ;; ()
+ )
+
+;;; doom-spacegrey-theme.el ends here
diff --git a/elpa/doom-themes-20220504.1557/doom-themes-autoloads.el b/elpa/doom-themes-20220504.1557/doom-themes-autoloads.el
new file mode 100644
index 0000000..b10c185
--- /dev/null
+++ b/elpa/doom-themes-20220504.1557/doom-themes-autoloads.el
@@ -0,0 +1,656 @@
+;;; doom-themes-autoloads.el --- automatically extracted autoloads -*- lexical-binding: t -*-
+;;
+;;; Code:
+
+(add-to-list 'load-path (directory-file-name
+ (or (file-name-directory #$) (car load-path))))
+
+
+;;;### (autoloads nil "doom-1337-theme" "doom-1337-theme.el" (0 0
+;;;;;; 0 0))
+;;; Generated autoloads from doom-1337-theme.el
+
+(register-definition-prefixes "doom-1337-theme" '("doom-1337"))
+
+;;;***
+
+;;;### (autoloads nil "doom-Iosvkem-theme" "doom-Iosvkem-theme.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from doom-Iosvkem-theme.el
+
+(register-definition-prefixes "doom-Iosvkem-theme" '("doom-Iosvkem"))
+
+;;;***
+
+;;;### (autoloads nil "doom-acario-dark-theme" "doom-acario-dark-theme.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from doom-acario-dark-theme.el
+
+(register-definition-prefixes "doom-acario-dark-theme" '("doom-acario-dark"))
+
+;;;***
+
+;;;### (autoloads nil "doom-acario-light-theme" "doom-acario-light-theme.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from doom-acario-light-theme.el
+
+(register-definition-prefixes "doom-acario-light-theme" '("doom-acario-light"))
+
+;;;***
+
+;;;### (autoloads nil "doom-ayu-light-theme" "doom-ayu-light-theme.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from doom-ayu-light-theme.el
+
+(register-definition-prefixes "doom-ayu-light-theme" '("doom-ayu-light"))
+
+;;;***
+
+;;;### (autoloads nil "doom-ayu-mirage-theme" "doom-ayu-mirage-theme.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from doom-ayu-mirage-theme.el
+
+(register-definition-prefixes "doom-ayu-mirage-theme" '("doom-ayu-mirage"))
+
+;;;***
+
+;;;### (autoloads nil "doom-badger-theme" "doom-badger-theme.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from doom-badger-theme.el
+
+(register-definition-prefixes "doom-badger-theme" '("doom-badger"))
+
+;;;***
+
+;;;### (autoloads nil "doom-challenger-deep-theme" "doom-challenger-deep-theme.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from doom-challenger-deep-theme.el
+
+(register-definition-prefixes "doom-challenger-deep-theme" '("doom-challenger-deep"))
+
+;;;***
+
+;;;### (autoloads nil "doom-city-lights-theme" "doom-city-lights-theme.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from doom-city-lights-theme.el
+
+(register-definition-prefixes "doom-city-lights-theme" '("doom-city-lights"))
+
+;;;***
+
+;;;### (autoloads nil "doom-dark+-theme" "doom-dark+-theme.el" (0
+;;;;;; 0 0 0))
+;;; Generated autoloads from doom-dark+-theme.el
+
+(register-definition-prefixes "doom-dark+-theme" '("doom-dark+"))
+
+;;;***
+
+;;;### (autoloads nil "doom-dracula-theme" "doom-dracula-theme.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from doom-dracula-theme.el
+
+(register-definition-prefixes "doom-dracula-theme" '("doom-dracula"))
+
+;;;***
+
+;;;### (autoloads nil "doom-earl-grey-theme" "doom-earl-grey-theme.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from doom-earl-grey-theme.el
+
+(register-definition-prefixes "doom-earl-grey-theme" '("doom-earl-grey"))
+
+;;;***
+
+;;;### (autoloads nil "doom-ephemeral-theme" "doom-ephemeral-theme.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from doom-ephemeral-theme.el
+
+(register-definition-prefixes "doom-ephemeral-theme" '("doom-ephemeral"))
+
+;;;***
+
+;;;### (autoloads nil "doom-fairy-floss-theme" "doom-fairy-floss-theme.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from doom-fairy-floss-theme.el
+
+(register-definition-prefixes "doom-fairy-floss-theme" '("doom-fairy-floss"))
+
+;;;***
+
+;;;### (autoloads nil "doom-flatwhite-theme" "doom-flatwhite-theme.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from doom-flatwhite-theme.el
+
+(register-definition-prefixes "doom-flatwhite-theme" '("doom-f"))
+
+;;;***
+
+;;;### (autoloads nil "doom-gruvbox-light-theme" "doom-gruvbox-light-theme.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from doom-gruvbox-light-theme.el
+
+(register-definition-prefixes "doom-gruvbox-light-theme" '("doom-gruvbox-light"))
+
+;;;***
+
+;;;### (autoloads nil "doom-gruvbox-theme" "doom-gruvbox-theme.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from doom-gruvbox-theme.el
+
+(register-definition-prefixes "doom-gruvbox-theme" '("doom-gruvbox"))
+
+;;;***
+
+;;;### (autoloads nil "doom-henna-theme" "doom-henna-theme.el" (0
+;;;;;; 0 0 0))
+;;; Generated autoloads from doom-henna-theme.el
+
+(register-definition-prefixes "doom-henna-theme" '("doom-henna"))
+
+;;;***
+
+;;;### (autoloads nil "doom-homage-black-theme" "doom-homage-black-theme.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from doom-homage-black-theme.el
+
+(register-definition-prefixes "doom-homage-black-theme" '("doom-homage-black"))
+
+;;;***
+
+;;;### (autoloads nil "doom-homage-white-theme" "doom-homage-white-theme.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from doom-homage-white-theme.el
+
+(register-definition-prefixes "doom-homage-white-theme" '("doom-homage-white"))
+
+;;;***
+
+;;;### (autoloads nil "doom-horizon-theme" "doom-horizon-theme.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from doom-horizon-theme.el
+
+(register-definition-prefixes "doom-horizon-theme" '("doom-horizon"))
+
+;;;***
+
+;;;### (autoloads nil "doom-ir-black-theme" "doom-ir-black-theme.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from doom-ir-black-theme.el
+
+(register-definition-prefixes "doom-ir-black-theme" '("doom-ir-black"))
+
+;;;***
+
+;;;### (autoloads nil "doom-laserwave-theme" "doom-laserwave-theme.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from doom-laserwave-theme.el
+
+(register-definition-prefixes "doom-laserwave-theme" '("doom-laserwave"))
+
+;;;***
+
+;;;### (autoloads nil "doom-manegarm-theme" "doom-manegarm-theme.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from doom-manegarm-theme.el
+
+(register-definition-prefixes "doom-manegarm-theme" '("doom-manegarm"))
+
+;;;***
+
+;;;### (autoloads nil "doom-material-dark-theme" "doom-material-dark-theme.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from doom-material-dark-theme.el
+
+(register-definition-prefixes "doom-material-dark-theme" '("doom-material-"))
+
+;;;***
+
+;;;### (autoloads nil "doom-material-theme" "doom-material-theme.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from doom-material-theme.el
+
+(register-definition-prefixes "doom-material-theme" '("doom-material"))
+
+;;;***
+
+;;;### (autoloads nil "doom-meltbus-theme" "doom-meltbus-theme.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from doom-meltbus-theme.el
+
+(register-definition-prefixes "doom-meltbus-theme" '("doom-meltbus"))
+
+;;;***
+
+;;;### (autoloads nil "doom-miramare-theme" "doom-miramare-theme.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from doom-miramare-theme.el
+
+(register-definition-prefixes "doom-miramare-theme" '("doom-miramare"))
+
+;;;***
+
+;;;### (autoloads nil "doom-molokai-theme" "doom-molokai-theme.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from doom-molokai-theme.el
+
+(register-definition-prefixes "doom-molokai-theme" '("doom-molokai"))
+
+;;;***
+
+;;;### (autoloads nil "doom-monokai-classic-theme" "doom-monokai-classic-theme.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from doom-monokai-classic-theme.el
+
+(register-definition-prefixes "doom-monokai-classic-theme" '("doom-monokai-classic"))
+
+;;;***
+
+;;;### (autoloads nil "doom-monokai-machine-theme" "doom-monokai-machine-theme.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from doom-monokai-machine-theme.el
+
+(register-definition-prefixes "doom-monokai-machine-theme" '("doom-monokai-machine"))
+
+;;;***
+
+;;;### (autoloads nil "doom-monokai-octagon-theme" "doom-monokai-octagon-theme.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from doom-monokai-octagon-theme.el
+
+(register-definition-prefixes "doom-monokai-octagon-theme" '("doom-monokai-octagon"))
+
+;;;***
+
+;;;### (autoloads nil "doom-monokai-pro-theme" "doom-monokai-pro-theme.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from doom-monokai-pro-theme.el
+
+(register-definition-prefixes "doom-monokai-pro-theme" '("doom-monokai-pro"))
+
+;;;***
+
+;;;### (autoloads nil "doom-monokai-ristretto-theme" "doom-monokai-ristretto-theme.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from doom-monokai-ristretto-theme.el
+
+(register-definition-prefixes "doom-monokai-ristretto-theme" '("doom-monokai-ristretto"))
+
+;;;***
+
+;;;### (autoloads nil "doom-monokai-spectrum-theme" "doom-monokai-spectrum-theme.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from doom-monokai-spectrum-theme.el
+
+(register-definition-prefixes "doom-monokai-spectrum-theme" '("doom-monokai-spectrum"))
+
+;;;***
+
+;;;### (autoloads nil "doom-moonlight-theme" "doom-moonlight-theme.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from doom-moonlight-theme.el
+
+(register-definition-prefixes "doom-moonlight-theme" '("doom-moonlight"))
+
+;;;***
+
+;;;### (autoloads nil "doom-nord-light-theme" "doom-nord-light-theme.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from doom-nord-light-theme.el
+
+(register-definition-prefixes "doom-nord-light-theme" '("doom-nord-light"))
+
+;;;***
+
+;;;### (autoloads nil "doom-nord-theme" "doom-nord-theme.el" (0 0
+;;;;;; 0 0))
+;;; Generated autoloads from doom-nord-theme.el
+
+(register-definition-prefixes "doom-nord-theme" '("doom-nord"))
+
+;;;***
+
+;;;### (autoloads nil "doom-nova-theme" "doom-nova-theme.el" (0 0
+;;;;;; 0 0))
+;;; Generated autoloads from doom-nova-theme.el
+
+(register-definition-prefixes "doom-nova-theme" '("doom-nova"))
+
+;;;***
+
+;;;### (autoloads nil "doom-oceanic-next-theme" "doom-oceanic-next-theme.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from doom-oceanic-next-theme.el
+
+(register-definition-prefixes "doom-oceanic-next-theme" '("doom-oceanic-next"))
+
+;;;***
+
+;;;### (autoloads nil "doom-old-hope-theme" "doom-old-hope-theme.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from doom-old-hope-theme.el
+
+(register-definition-prefixes "doom-old-hope-theme" '("doom-old-hope"))
+
+;;;***
+
+;;;### (autoloads nil "doom-one-light-theme" "doom-one-light-theme.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from doom-one-light-theme.el
+
+(register-definition-prefixes "doom-one-light-theme" '("doom-one-light"))
+
+;;;***
+
+;;;### (autoloads nil "doom-one-theme" "doom-one-theme.el" (0 0 0
+;;;;;; 0))
+;;; Generated autoloads from doom-one-theme.el
+
+(register-definition-prefixes "doom-one-theme" '("doom-one"))
+
+;;;***
+
+;;;### (autoloads nil "doom-opera-light-theme" "doom-opera-light-theme.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from doom-opera-light-theme.el
+
+(register-definition-prefixes "doom-opera-light-theme" '("doom-opera-light"))
+
+;;;***
+
+;;;### (autoloads nil "doom-opera-theme" "doom-opera-theme.el" (0
+;;;;;; 0 0 0))
+;;; Generated autoloads from doom-opera-theme.el
+
+(register-definition-prefixes "doom-opera-theme" '("doom-opera"))
+
+;;;***
+
+;;;### (autoloads nil "doom-outrun-electric-theme" "doom-outrun-electric-theme.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from doom-outrun-electric-theme.el
+
+(register-definition-prefixes "doom-outrun-electric-theme" '("doom-outrun-electric"))
+
+;;;***
+
+;;;### (autoloads nil "doom-palenight-theme" "doom-palenight-theme.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from doom-palenight-theme.el
+
+(register-definition-prefixes "doom-palenight-theme" '("doom-palenight"))
+
+;;;***
+
+;;;### (autoloads nil "doom-peacock-theme" "doom-peacock-theme.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from doom-peacock-theme.el
+
+(register-definition-prefixes "doom-peacock-theme" '("doom-peacock"))
+
+;;;***
+
+;;;### (autoloads nil "doom-plain-dark-theme" "doom-plain-dark-theme.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from doom-plain-dark-theme.el
+
+(register-definition-prefixes "doom-plain-dark-theme" '("doom-plain-"))
+
+;;;***
+
+;;;### (autoloads nil "doom-plain-theme" "doom-plain-theme.el" (0
+;;;;;; 0 0 0))
+;;; Generated autoloads from doom-plain-theme.el
+
+(register-definition-prefixes "doom-plain-theme" '("doom-plain"))
+
+;;;***
+
+;;;### (autoloads nil "doom-rouge-theme" "doom-rouge-theme.el" (0
+;;;;;; 0 0 0))
+;;; Generated autoloads from doom-rouge-theme.el
+
+(register-definition-prefixes "doom-rouge-theme" '("doom-rouge"))
+
+;;;***
+
+;;;### (autoloads nil "doom-shades-of-purple-theme" "doom-shades-of-purple-theme.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from doom-shades-of-purple-theme.el
+
+(register-definition-prefixes "doom-shades-of-purple-theme" '("doom-shades-of-purple"))
+
+;;;***
+
+;;;### (autoloads nil "doom-snazzy-theme" "doom-snazzy-theme.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from doom-snazzy-theme.el
+
+(register-definition-prefixes "doom-snazzy-theme" '("doom-snazzy"))
+
+;;;***
+
+;;;### (autoloads nil "doom-solarized-dark-high-contrast-theme" "doom-solarized-dark-high-contrast-theme.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from doom-solarized-dark-high-contrast-theme.el
+
+(register-definition-prefixes "doom-solarized-dark-high-contrast-theme" '("doom-solarized-dark-high-contrast"))
+
+;;;***
+
+;;;### (autoloads nil "doom-solarized-dark-theme" "doom-solarized-dark-theme.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from doom-solarized-dark-theme.el
+
+(register-definition-prefixes "doom-solarized-dark-theme" '("doom-solarized-dark"))
+
+;;;***
+
+;;;### (autoloads nil "doom-solarized-light-theme" "doom-solarized-light-theme.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from doom-solarized-light-theme.el
+
+(register-definition-prefixes "doom-solarized-light-theme" '("doom-solarized-light"))
+
+;;;***
+
+;;;### (autoloads nil "doom-sourcerer-theme" "doom-sourcerer-theme.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from doom-sourcerer-theme.el
+
+(register-definition-prefixes "doom-sourcerer-theme" '("doom-sourcerer"))
+
+;;;***
+
+;;;### (autoloads nil "doom-spacegrey-theme" "doom-spacegrey-theme.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from doom-spacegrey-theme.el
+
+(register-definition-prefixes "doom-spacegrey-theme" '("doom-spacegrey"))
+
+;;;***
+
+;;;### (autoloads nil "doom-themes" "doom-themes.el" (0 0 0 0))
+;;; Generated autoloads from doom-themes.el
+
+(autoload 'doom-name-to-rgb "doom-themes" "\
+Retrieves the hexidecimal string repesented the named COLOR (e.g. \"red\")
+for FRAME (defaults to the current frame).
+
+\(fn COLOR)" nil nil)
+
+(autoload 'doom-blend "doom-themes" "\
+Blend two colors (hexidecimal strings) together by a coefficient ALPHA (a
+float between 0 and 1)
+
+\(fn COLOR1 COLOR2 ALPHA)" nil nil)
+
+(autoload 'doom-darken "doom-themes" "\
+Darken a COLOR (a hexidecimal string) by a coefficient ALPHA (a float between
+0 and 1).
+
+\(fn COLOR ALPHA)" nil nil)
+
+(autoload 'doom-lighten "doom-themes" "\
+Brighten a COLOR (a hexidecimal string) by a coefficient ALPHA (a float
+between 0 and 1).
+
+\(fn COLOR ALPHA)" nil nil)
+
+(autoload 'doom-color "doom-themes" "\
+Retrieve a specific color named NAME (a symbol) from the current theme.
+
+\(fn NAME &optional TYPE)" nil nil)
+
+(autoload 'doom-ref "doom-themes" "\
+TODO
+
+\(fn FACE PROP &optional CLASS)" nil nil)
+
+(autoload 'doom-themes-set-faces "doom-themes" "\
+Customize THEME (a symbol) with FACES.
+
+If THEME is nil, it applies to all themes you load. FACES is a list of Doom
+theme face specs. These is a simplified spec. For example:
+
+ (doom-themes-set-faces 'user
+ '(default :background red :foreground blue)
+ '(doom-modeline-bar :background (if -modeline-bright modeline-bg highlight))
+ '(doom-modeline-buffer-file :inherit 'mode-line-buffer-id :weight 'bold)
+ '(doom-modeline-buffer-path :inherit 'mode-line-emphasis :weight 'bold)
+ '(doom-modeline-buffer-project-root :foreground green :weight 'bold))
+
+\(fn THEME &rest FACES)" nil nil)
+
+(function-put 'doom-themes-set-faces 'lisp-indent-function 'defun)
+
+(when (and (boundp 'custom-theme-load-path) load-file-name) (let* ((base (file-name-directory load-file-name)) (dir (expand-file-name "themes/" base))) (add-to-list 'custom-theme-load-path (or (and (file-directory-p dir) dir) base))))
+
+(register-definition-prefixes "doom-themes" '("def-doom-theme" "doom-"))
+
+;;;***
+
+;;;### (autoloads nil "doom-themes-base" "doom-themes-base.el" (0
+;;;;;; 0 0 0))
+;;; Generated autoloads from doom-themes-base.el
+
+(register-definition-prefixes "doom-themes-base" '("doom-themes-base-"))
+
+;;;***
+
+;;;### (autoloads nil "doom-themes-ext-neotree" "doom-themes-ext-neotree.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from doom-themes-ext-neotree.el
+
+(autoload 'doom-themes-neotree-config "doom-themes-ext-neotree" "\
+Install doom-themes' neotree configuration.
+
+Includes an Atom-esque icon theme and highlighting based on filetype." nil nil)
+
+(register-definition-prefixes "doom-themes-ext-neotree" '("doom-"))
+
+;;;***
+
+;;;### (autoloads nil "doom-themes-ext-org" "doom-themes-ext-org.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from doom-themes-ext-org.el
+
+(autoload 'doom-themes-org-config "doom-themes-ext-org" "\
+Load `doom-themes-ext-org'." nil nil)
+
+(register-definition-prefixes "doom-themes-ext-org" '("doom-themes-"))
+
+;;;***
+
+;;;### (autoloads nil "doom-themes-ext-treemacs" "doom-themes-ext-treemacs.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from doom-themes-ext-treemacs.el
+
+(autoload 'doom-themes-treemacs-config "doom-themes-ext-treemacs" "\
+Install doom-themes' treemacs configuration.
+
+Includes an Atom-esque icon theme and highlighting based on filetype." nil nil)
+
+(register-definition-prefixes "doom-themes-ext-treemacs" '("doom-themes-"))
+
+;;;***
+
+;;;### (autoloads nil "doom-themes-ext-visual-bell" "doom-themes-ext-visual-bell.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from doom-themes-ext-visual-bell.el
+
+(autoload 'doom-themes-visual-bell-fn "doom-themes-ext-visual-bell" "\
+Blink the mode-line red briefly. Set `ring-bell-function' to this to use it." nil nil)
+
+(autoload 'doom-themes-visual-bell-config "doom-themes-ext-visual-bell" "\
+Enable flashing the mode-line on error." nil nil)
+
+;;;***
+
+;;;### (autoloads nil "doom-tokyo-night-theme" "doom-tokyo-night-theme.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from doom-tokyo-night-theme.el
+
+(register-definition-prefixes "doom-tokyo-night-theme" '("doom-tokyo-night"))
+
+;;;***
+
+;;;### (autoloads nil "doom-tomorrow-day-theme" "doom-tomorrow-day-theme.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from doom-tomorrow-day-theme.el
+
+(register-definition-prefixes "doom-tomorrow-day-theme" '("doom-tomorrow-day"))
+
+;;;***
+
+;;;### (autoloads nil "doom-tomorrow-night-theme" "doom-tomorrow-night-theme.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from doom-tomorrow-night-theme.el
+
+(register-definition-prefixes "doom-tomorrow-night-theme" '("doom-tomorrow-night"))
+
+;;;***
+
+;;;### (autoloads nil "doom-vibrant-theme" "doom-vibrant-theme.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from doom-vibrant-theme.el
+
+(register-definition-prefixes "doom-vibrant-theme" '("doom-vibrant"))
+
+;;;***
+
+;;;### (autoloads nil "doom-wilmersdorf-theme" "doom-wilmersdorf-theme.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from doom-wilmersdorf-theme.el
+
+(register-definition-prefixes "doom-wilmersdorf-theme" '("doom-wilmersdorf"))
+
+;;;***
+
+;;;### (autoloads nil "doom-xcode-theme" "doom-xcode-theme.el" (0
+;;;;;; 0 0 0))
+;;; Generated autoloads from doom-xcode-theme.el
+
+(register-definition-prefixes "doom-xcode-theme" '("doom-xcode"))
+
+;;;***
+
+;;;### (autoloads nil "doom-zenburn-theme" "doom-zenburn-theme.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from doom-zenburn-theme.el
+
+(register-definition-prefixes "doom-zenburn-theme" '("doom-zenburn"))
+
+;;;***
+
+;;;### (autoloads nil nil ("doom-themes-pkg.el") (0 0 0 0))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; coding: utf-8
+;; End:
+;;; doom-themes-autoloads.el ends here
diff --git a/elpa/doom-themes-20220504.1557/doom-themes-base.el b/elpa/doom-themes-20220504.1557/doom-themes-base.el
new file mode 100644
index 0000000..ed98690
--- /dev/null
+++ b/elpa/doom-themes-20220504.1557/doom-themes-base.el
@@ -0,0 +1,1537 @@
+;;; doom-themes-base.el --- base faces for all doom themes -*- lexical-binding: t; -*-
+;;; Commentary:
+;;; Code:
+
+;; These are used as a basis for every Doom theme defined with `def-doom-theme',
+;; as a set of reasonble defaults. They are intended to be overidden where it
+;; makes sense to.
+(defvar doom-themes-base-faces
+ '((bold :weight 'bold :foreground (unless bold base8))
+ (bold-italic :inherit '(bold italic))
+ (italic :slant 'italic)
+ (escape-glyph :foreground cyan)
+ (default :background bg :foreground fg)
+ (fringe :inherit 'default :foreground base4)
+ (region :background region :foreground nil :distant-foreground (doom-darken fg 0.2) :extend t)
+ (highlight :background highlight :foreground base0 :distant-foreground base8)
+ (cursor :background highlight)
+ (shadow :foreground base5)
+ (minibuffer-prompt :foreground highlight)
+ (tooltip :background bg-alt :foreground fg)
+ (secondary-selection :background grey :extend t)
+ (lazy-highlight
+ (&dark :background (doom-darken highlight 0.3) :foreground base8 :distant-foreground base0 :weight 'bold)
+ (&light :background (doom-blend bg highlight 0.7) :foreground base0 :distant-foreground base8))
+ (match :foreground green :background base0 :weight 'bold)
+ (trailing-whitespace :background red)
+ (nobreak-space :inherit 'default :underline nil)
+ (vertical-border :background vertical-bar :foreground vertical-bar)
+ (link :foreground highlight :underline t :weight 'bold)
+ (error :foreground error)
+ (warning :foreground warning)
+ (success :foreground success)
+ ;;;; font-lock-* faces
+ (font-lock-builtin-face :foreground builtin)
+ (font-lock-comment-face :foreground comments)
+ (font-lock-comment-delimiter-face :inherit 'font-lock-comment-face)
+ (font-lock-doc-face :inherit 'font-lock-comment-face :foreground doc-comments)
+ (font-lock-constant-face :foreground constants)
+ (font-lock-function-name-face :foreground functions)
+ (font-lock-keyword-face :foreground keywords)
+ (font-lock-string-face :foreground strings)
+ (font-lock-type-face :foreground type)
+ (font-lock-variable-name-face :foreground variables)
+ (font-lock-warning-face :inherit 'warning)
+ (font-lock-negation-char-face :inherit 'bold :foreground operators)
+ (font-lock-preprocessor-face :inherit 'bold :foreground operators)
+ (font-lock-preprocessor-char-face :inherit 'bold :foreground operators)
+ (font-lock-regexp-grouping-backslash :inherit 'bold :foreground operators)
+ (font-lock-regexp-grouping-construct :inherit 'bold :foreground operators)
+ ;;;; mode-line / header-line
+ (mode-line :background bg :foreground fg :distant-foreground bg)
+ (mode-line-active :inherit 'mode-line)
+ (mode-line-inactive :background bg-alt :foreground fg-alt :distant-foreground bg-alt)
+ (mode-line-emphasis :foreground highlight :distant-foreground bg)
+ (mode-line-highlight :inherit 'highlight :distant-foreground bg)
+ (mode-line-buffer-id :weight 'bold)
+ (header-line :inherit 'mode-line)
+ (header-line-highlight :inherit 'mode-line-highlight)
+ ;;;; tab-line/tab-bar (Emacs 27+)
+ (tab-line :background bg-alt :foreground bg-alt)
+ (tab-line-tab :background bg :foreground fg)
+ (tab-line-tab-inactive :inherit 'tab-line-tab :background bg-alt :foreground fg-alt)
+ (tab-line-tab-inactive-alternate :inherit 'tab-line-tab-inactive)
+ (tab-line-tab-current :background bg :foreground fg)
+ ;; (tab-line-special )
+ (tab-line-highlight :inherit 'tab-line-tab)
+ (tab-line-close-highlight :foreground highlight)
+ ((tab-bar &inherit tab-line))
+ ((tab-bar-tab &inherit tab-line-tab))
+ ((tab-bar-tab-inactive &inherit tab-line-tab-inactive))
+ ;;;; Line numbers
+ ;; 1. Line number faces must explicitly disable its text style attributes
+ ;; because nearby faces may "bleed" into the line numbers otherwise.
+ ;; 2. All other line number plugin faces should &inherit from these.
+ (line-number
+ :inherit 'default
+ :foreground base5 :distant-foreground nil
+ :weight 'normal :italic nil :underline nil :strike-through nil)
+ (line-number-current-line
+ :inherit '(hl-line default)
+ :foreground fg :distant-foreground nil
+ :weight 'normal :italic nil :underline nil :strike-through nil)
+
+ ;;;; --- Package faces ----------------------
+ ;; What follows are faces for all the packages doom-themes explicitly
+ ;; supports. Headings are formatted as such:
+ ;;
+ ;; PACKAGE [<built-in>] [<modes:some-mode[, ...]>]
+ ;;
+ ;; The purpose of this is to make it easy to jump to via `imenu', or search
+ ;; for with isearch, swiper, etc.
+ ;;;; agda-mode <modes:agda2-mode>
+ (agda2-highlight-keyword-face :inherit 'font-lock-keyword-face)
+ (agda2-highlight-string-face :inherit 'font-lock-string-face)
+ (agda2-highlight-number-face :inherit 'font-lock-string-face)
+ (agda2-highlight-symbol-face :inherit 'font-lock-variable-name-face)
+ (agda2-highlight-primitive-type-face :inherit 'font-lock-type-face)
+ (agda2-highlight-bound-variable-face :inherit 'font-lock-variable-name-face)
+ (agda2-highlight-inductive-constructor-face :inherit 'font-lock-type-face)
+ (agda2-highlight-coinductive-constructor-face :inherit 'font-lock-type-face)
+ (agda2-highlight-datatype-face :inherit 'font-lock-type-face)
+ (agda2-highlight-field-face :inherit 'font-lock-type-face)
+ (agda2-highlight-function-face :inherit 'font-lock-function-name-face)
+ (agda2-highlight-module-face :inherit 'font-lock-variable-name-face)
+ (agda2-highlight-postulate-face :inherit 'font-lock-type-face)
+ (agda2-highlight-primitive-face :inherit 'font-lock-type-face)
+ (agda2-highlight-macro-face :inherit 'font-lock-function-name-face)
+ (agda2-highlight-record-face :inherit 'font-lock-type-face)
+ (agda2-highlight-error-face :inherit 'font-lock-warning-face)
+ (agda2-highlight-dotted-face :inherit 'font-lock-variable-name-face)
+ (agda2-highlight-unsolved-meta-face :inherit 'font-lock-warning-face)
+ (agda2-highlight-unsolved-constraint-face :inherit 'font-lock-warning-face)
+ (agda2-highlight-termination-problem-face :inherit 'font-lock-warning-face)
+ (agda2-highlight-positivity-problem-face :inherit 'font-lock-warning-face)
+ (agda2-highlight-incomplete-pattern-face :inherit 'font-lock-warning-face)
+ (agda2-highlight-typechecks-face :inherit 'font-lock-warning-face)
+ ;;;; auctex <modes:latex-mode>
+ (font-latex-bold-face :inherit 'bold)
+ (font-latex-italic-face :inherit 'italic)
+ (font-latex-math-face :foreground blue)
+ (font-latex-sectioning-0-face :foreground blue :weight 'ultra-bold)
+ (font-latex-sectioning-1-face :foreground magenta :weight 'semi-bold)
+ (font-latex-sectioning-2-face :foreground violet :weight 'semi-bold)
+ (font-latex-sectioning-3-face :foreground (doom-lighten blue 0.3) :weight 'semi-bold)
+ (font-latex-sectioning-4-face :foreground (doom-lighten magenta 0.3) :weight 'semi-bold)
+ (font-latex-sectioning-5-face :foreground (doom-lighten violet 0.3) :weight 'semi-bold)
+ (font-latex-script-char-face :foreground dark-blue)
+ (font-latex-string-face :inherit 'font-lock-string-face)
+ (font-latex-warning-face :inherit 'font-lock-warning-face)
+ (font-latex-verbatim-face :inherit 'fixed-pitch :foreground violet :slant 'italic)
+ (TeX-error-description-error :inherit 'error :weight 'bold)
+ (TeX-error-description-warning :inherit 'warning :weight 'bold)
+ (TeX-error-description-tex-said :inherit 'success :weight 'bold)
+ ;;;; alert
+ (alert-high-face :inherit bold :foreground warning)
+ (alert-low-face :foreground grey)
+ (alert-moderate-face :inherit bold :foreground fg-alt)
+ (alert-trivial-face :foreground doc-comments)
+ (alert-urgent-face :inherit bold :foreground error)
+ ;;;; all-the-icons
+ (all-the-icons-blue :foreground blue)
+ (all-the-icons-blue-alt :foreground teal)
+ (all-the-icons-cyan :foreground cyan)
+ (all-the-icons-cyan-alt :foreground cyan)
+ (all-the-icons-dblue :foreground dark-blue)
+ (all-the-icons-dcyan :foreground dark-cyan)
+ (all-the-icons-dgreen :foreground (doom-darken green 0.3))
+ (all-the-icons-dmaroon :foreground (doom-darken magenta 0.3))
+ (all-the-icons-dorange :foreground (doom-darken orange 0.3))
+ (all-the-icons-dpink :foreground (doom-lighten red 0.15))
+ (all-the-icons-dpurple :foreground (doom-darken violet 0.3))
+ (all-the-icons-dred :foreground (doom-darken red 0.3))
+ (all-the-icons-dsilver :foreground (doom-lighten grey 0.1))
+ (all-the-icons-dyellow :foreground (doom-darken yellow 0.3))
+ (all-the-icons-green :foreground green)
+ (all-the-icons-lblue :foreground (doom-lighten blue 0.3))
+ (all-the-icons-lcyan :foreground (doom-lighten cyan 0.3))
+ (all-the-icons-lgreen :foreground (doom-lighten green 0.3))
+ (all-the-icons-lmaroon :foreground (doom-lighten magenta 0.3))
+ (all-the-icons-lorange :foreground (doom-lighten orange 0.3))
+ (all-the-icons-lpink :foreground (doom-lighten red 0.55))
+ (all-the-icons-lpurple :foreground (doom-lighten violet 0.3))
+ (all-the-icons-lred :foreground (doom-lighten red 0.3))
+ (all-the-icons-lsilver :foreground (doom-lighten grey 0.7))
+ (all-the-icons-lyellow :foreground (doom-lighten yellow 0.3))
+ (all-the-icons-maroon :foreground magenta)
+ (all-the-icons-orange :foreground orange)
+ (all-the-icons-pink :foreground (doom-lighten red 0.35))
+ (all-the-icons-purple :foreground violet)
+ (all-the-icons-purple-alt :foreground (doom-blend violet grey 0.15))
+ (all-the-icons-red :foreground red)
+ (all-the-icons-red-alt :foreground (doom-blend red grey 0.15))
+ (all-the-icons-silver :foreground (doom-lighten grey 0.45))
+ (all-the-icons-yellow :foreground yellow)
+ ;;;; all-the-icons-dired
+ (all-the-icons-dired-dir-face :foreground doc-comments)
+ ;;;; annotate
+ (annotate-annotation :background (doom-blend highlight bg 0.1) :foreground doc-comments)
+ (annotate-annotation-secondary :background (doom-blend green bg 0.1) :foreground doc-comments)
+ (annotate-highlight :background (doom-blend highlight bg 0.1) :underline highlight)
+ (annotate-highlight-secondary :background (doom-blend green bg 0.1) :underline green)
+ ;;;; ansi-color <built-in>
+ (ansi-color-black :foreground bg :background bg)
+ (ansi-color-red :foreground red :background red)
+ (ansi-color-green :foreground green :background green)
+ (ansi-color-yellow :foreground yellow :background yellow)
+ (ansi-color-blue :foreground blue :background blue)
+ (ansi-color-magenta :foreground magenta :background magenta)
+ (ansi-color-cyan :foreground cyan :background cyan)
+ (ansi-color-white :foreground fg :background fg)
+ (ansi-color-bright-black :foreground base0 :background base2)
+ (ansi-color-bright-red :foreground (doom-lighten red 0.15) :background (doom-lighten red 0.15))
+ (ansi-color-bright-green :foreground (doom-lighten green 0.15) :background (doom-lighten green 0.15))
+ (ansi-color-bright-yellow :foreground (doom-lighten yellow 0.15) :background (doom-lighten yellow 0.15))
+ (ansi-color-bright-blue :foreground (doom-lighten blue 0.15) :background (doom-lighten blue 0.15))
+ (ansi-color-bright-magenta :foreground (doom-lighten magenta 0.15) :background (doom-lighten magenta 0.15))
+ (ansi-color-bright-cyan :foreground (doom-lighten cyan 0.15) :background (doom-lighten cyan 0.15))
+ (ansi-color-bright-white :foreground base8 :background base8)
+ ;;;; anzu
+ (anzu-replace-highlight :background base0 :foreground red :weight 'bold :strike-through t)
+ (anzu-replace-to :background base0 :foreground green :weight 'bold)
+ ;;;; avy
+ (avy-background-face :foreground comments)
+ (avy-lead-face :background highlight :foreground bg :distant-foreground fg :weight 'bold)
+ (avy-lead-face-0
+ (&all :inherit 'avy-lead-face)
+ (&dark :background (doom-lighten highlight 0.3))
+ (&light :background (doom-darken highlight 0.3)))
+ (avy-lead-face-1
+ (&all :inherit 'avy-lead-face)
+ (&dark :background (doom-lighten highlight 0.6))
+ (&light :background (doom-darken highlight 0.6)))
+ (avy-lead-face-2
+ (&all :inherit 'avy-lead-face)
+ (&dark :background (doom-lighten highlight 0.9))
+ (&light :background (doom-darken highlight 0.9)))
+ ;;;; bookmark
+ (bookmark-face :background (doom-blend highlight bg 0.1) :extend t)
+ ;;;; bookmark+
+ (bmkp-*-mark :foreground bg :background yellow)
+ (bmkp->-mark :foreground yellow)
+ (bmkp-D-mark :foreground bg :background red)
+ (bmkp-X-mark :foreground red)
+ (bmkp-a-mark :background red)
+ (bmkp-bad-bookmark :foreground bg :background yellow)
+ (bmkp-bookmark-file :foreground violet :background bg-alt)
+ (bmkp-bookmark-list :background bg-alt)
+ (bmkp-buffer :foreground blue)
+ (bmkp-desktop :foreground bg :background violet)
+ (bmkp-file-handler :background red)
+ (bmkp-function :foreground green)
+ (bmkp-gnus :foreground orange)
+ (bmkp-heading :foreground yellow)
+ (bmkp-info :foreground cyan)
+ (bmkp-light-autonamed :foreground bg-alt :background cyan)
+ (bmkp-light-autonamed-region :foreground bg-alt :background red)
+ (bmkp-light-fringe-autonamed :foreground bg-alt :background violet)
+ (bmkp-light-fringe-non-autonamed :foreground bg-alt :background green)
+ (bmkp-light-mark :foreground bg :background cyan)
+ (bmkp-light-non-autonamed :foreground bg :background violet)
+ (bmkp-light-non-autonamed-region :foreground bg :background red)
+ (bmkp-local-directory :foreground bg :background violet)
+ (bmkp-local-file-with-region :foreground yellow)
+ (bmkp-local-file-without-region :foreground comments)
+ (bmkp-man :foreground violet)
+ (bmkp-no-jump :foreground comments)
+ (bmkp-no-local :foreground yellow)
+ (bmkp-non-file :foreground green)
+ (bmkp-remote-file :foreground orange)
+ (bmkp-sequence :foreground blue)
+ (bmkp-su-or-sudo :foreground red)
+ (bmkp-t-mark :foreground violet)
+ (bmkp-url :foreground blue :underline t)
+ (bmkp-variable-list :foreground green)
+ ;;;; calfw
+ (cfw:face-title :foreground blue :weight 'bold :height 2.0 :inherit 'variable-pitch)
+ (cfw:face-header :foreground (doom-blend blue bg 0.8) :weight 'bold)
+ (cfw:face-sunday :foreground (doom-blend red bg 0.8) :weight 'bold)
+ (cfw:face-saturday :foreground (doom-blend red bg 0.8) :weight 'bold)
+ (cfw:face-holiday :foreground nil :background bg-alt :weight 'bold)
+ (cfw:face-grid :foreground vertical-bar)
+ (cfw:face-periods :foreground yellow)
+ (cfw:face-toolbar :foreground nil :background nil)
+ (cfw:face-toolbar-button-off :foreground base6 :weight 'bold :inherit 'variable-pitch)
+ (cfw:face-toolbar-button-on :foreground blue :weight 'bold :inherit 'variable-pitch)
+ (cfw:face-default-content :foreground fg)
+ (cfw:face-day-title :foreground fg :weight 'bold)
+ (cfw:face-today-title :foreground bg :background blue :weight 'bold)
+ (cfw:face-default-day :weight 'bold)
+ (cfw:face-today :foreground nil :background nil :weight 'bold)
+ (cfw:face-annotation :foreground violet)
+ (cfw:face-disable :foreground grey)
+ (cfw:face-select :background region)
+ ;;;; centaur-tabs
+ ((centaur-tabs-default &inherit tab-bar) :box nil)
+ ((centaur-tabs-selected &inherit tab-bar-tab) :box nil)
+ ((centaur-tabs-unselected &inherit tab-bar-tab-inactive) :box nil)
+ (centaur-tabs-selected-modified :background bg :foreground teal)
+ (centaur-tabs-unselected-modified :background bg-alt :foreground teal)
+ (centaur-tabs-active-bar-face :background (if (bound-and-true-p -modeline-bright) modeline-bg highlight))
+ (centaur-tabs-modified-marker-selected
+ :foreground (if (bound-and-true-p -modeline-bright) modeline-bg highlight)
+ :inherit 'centaur-tabs-selected)
+ (centaur-tabs-modified-marker-unselected
+ :foreground (if (bound-and-true-p -modeline-bright) modeline-bg highlight)
+ :inherit 'centaur-tabs-unselected)
+ ;;;; company
+ (company-tooltip :inherit 'tooltip)
+ (company-tooltip-common :foreground highlight :distant-foreground base0 :weight 'bold)
+ (company-tooltip-search :background highlight :foreground bg :distant-foreground fg :weight 'bold)
+ (company-tooltip-search-selection :background (doom-darken selection 0.25))
+ (company-tooltip-selection :background selection :weight 'bold)
+ (company-tooltip-mouse :background magenta :foreground bg :distant-foreground fg)
+ (company-tooltip-annotation :foreground violet :distant-foreground bg)
+ (company-scrollbar-bg :inherit 'tooltip)
+ (company-scrollbar-fg :background highlight)
+ (company-preview :foreground comments)
+ (company-preview-common :background base3 :foreground highlight)
+ (company-preview-search :inherit 'company-tooltip-search)
+ (company-template-field :inherit 'match)
+ ;;;; company-box
+ (company-box-candidate :foreground fg)
+ ;;;; corfu
+ (corfu-background :inherit 'tooltip)
+ (corfu-current :background bg :foreground fg)
+ ;;;; circe
+ (circe-fool :foreground doc-comments)
+ (circe-highlight-nick-face :weight 'bold :foreground constants)
+ (circe-prompt-face :weight 'bold :foreground highlight)
+ (circe-server-face :foreground comments)
+ (circe-my-message-face :weight 'bold)
+ ;;;; cperl <built-in>
+ (cperl-array-face :weight 'bold :inherit 'font-lock-variable-name-face)
+ (cperl-hash-face :weight 'bold :slant 'italic :inherit 'font-lock-variable-name-face)
+ (cperl-nonoverridable-face :inherit 'font-lock-builtin-face)
+ ;;;; compilation <built-in>
+ (compilation-column-number :inherit 'font-lock-comment-face)
+ (compilation-line-number :foreground highlight)
+ (compilation-error :inherit 'error :weight 'bold)
+ (compilation-warning :inherit 'warning :slant 'italic)
+ (compilation-info :inherit 'success)
+ (compilation-mode-line-exit :inherit 'compilation-info)
+ (compilation-mode-line-fail :inherit 'compilation-error)
+ ;;;; custom <built-in>
+ (custom-button :foreground blue :background bg :box '(:line-width 1 :style none))
+ (custom-button-unraised :foreground violet :background bg :box '(:line-width 1 :style none))
+ (custom-button-pressed-unraised :foreground bg :background violet :box '(:line-width 1 :style none))
+ (custom-button-pressed :foreground bg :background blue :box '(:line-width 1 :style none))
+ (custom-button-mouse :foreground bg :background blue :box '(:line-width 1 :style none))
+ (custom-variable-button :foreground green :underline t)
+ (custom-saved :foreground green :background (doom-blend green bg 0.2) :bold bold)
+ (custom-comment :foreground fg :background region)
+ (custom-comment-tag :foreground grey)
+ (custom-modified :foreground blue :background (doom-blend blue bg 0.2))
+ (custom-variable-tag :foreground magenta)
+ (custom-visibility :foreground blue :underline nil)
+ (custom-group-subtitle :foreground red)
+ (custom-group-tag :foreground violet)
+ (custom-group-tag-1 :foreground blue)
+ (custom-set :foreground yellow :background bg)
+ (custom-themed :foreground yellow :background bg)
+ (custom-invalid :foreground red :background (doom-blend red bg 0.2))
+ (custom-variable-obsolete :foreground grey :background bg)
+ (custom-state :foreground green :background (doom-blend green bg 0.2))
+ (custom-changed :foreground blue :background bg)
+ ;;;; cider
+ ;; (cider-stacktrace-error-class-face :inherit 'font-lock-warning-face)
+ ;; (cider-stacktrace-error-message-face :inherit 'font-lock-doc-face)
+ ;; (cider-stacktrace-filter-active-face :inherit 'button :underline t :weight 'normal)
+ ;; (cider-stacktrace-filter-inactive-face :inherit 'cider-stacktrace-filter-active-face :underline nil)
+ ;; (cider-stacktrace-face :inherit 'default)
+ ;; (cider-stacktrace-ns-face :inherit 'font-lock-comment-face)
+ ;; (cider-stacktrace-fn-face :inherit 'default :weight 'bold)
+ ;; (cider-docview-emphasis-face :inherit 'default :underline t)
+ ;; (cider-docview-strong-face :inherit 'default :underline t :weight 'bold)
+ ;; (cider-docview-literal-face :inherit 'font-lock-string-face)
+ ;; (cider-docview-table-border-face :inherit 'shadow)
+ (cider-debug-code-overlay-face :background base3)
+ ;; (cider-debug-prompt-face :inherit font-lock-builtin-face :underline t)
+ (cider-enlightened-face
+ :inherit 'cider-result-overlay-face :box `(:color ,orange :line-width -1))
+ (cider-enlightened-local-face :foreground orange :weight 'bold)
+ ;; (cider-repl-prompt-face :inherit 'font-lock-keyword-face)
+ ;; (cider-repl-stdout-face :inherit 'font-lock-string-face)
+ ;; (cider-repl-stderr-face :inherit 'font-lock-warning-face)
+ ;; (cider-repl-input-face :weight 'bold)
+ ;; (cider-repl-result-face )
+ (cider-result-overlay-face :background base3 :box `(:line-width -1 :color base5))
+ (cider-fringe-good-face :foreground green)
+ (cider-deprecated-face :background (doom-blend bg yellow 0.8))
+ (cider-instrumented-face :background (doom-blend bg red 0.8))
+ (cider-traced-face :background (doom-blend bg cyan 0.8))
+ ;; (cider-reader-conditional-face :inherit 'font-lock-comment-face)
+ (cider-error-highlight-face
+ `((((supports :underline (:style wave)))
+ (:inherit unspecified :underline (:style wave :color ,(car error))))
+ (t (:inherit font-lock-warning-face :underline t))))
+ (cider-warning-highlight-face
+ `((((supports :underline (:style wave)))
+ (:underline (:style wave :color ,(car warning)) :inherit unspecified))
+ (t (:inherit font-lock-warning-face :underline (:color ,(car warning))))))
+ (cider-test-failure-face :background (doom-blend bg error 0.7))
+ (cider-test-error-face :background orange)
+ (cider-test-success-face
+ (&light :foreground base0 :background green)
+ (&dark :foreground green :background base0))
+ ;;;; diff-hl
+ (diff-hl-change :foreground vc-modified :background vc-modified)
+ (diff-hl-delete :foreground vc-deleted :background vc-deleted)
+ (diff-hl-insert :foreground vc-added :background vc-added)
+ ;;;; diff-mode <built-in>
+ (diff-added :inherit 'hl-line :foreground green)
+ (diff-changed :foreground violet)
+ (diff-context
+ (&dark :foreground (doom-darken fg 0.12))
+ (&light :foreground (doom-lighten fg 0.12)))
+ (diff-removed :foreground red :background base3)
+ (diff-header :foreground cyan :background nil)
+ (diff-file-header :foreground blue :background nil)
+ (diff-hunk-header :foreground violet)
+ (diff-refine-added :inherit 'diff-added :inverse-video t)
+ (diff-refine-changed :inherit 'diff-changed :inverse-video t)
+ (diff-refine-removed :inherit 'diff-removed :inverse-video t)
+ ;;;; dired <built-in>
+ (dired-directory :foreground builtin)
+ (dired-ignored :foreground comments)
+ (dired-flagged :foreground red)
+ (dired-header :foreground blue :weight 'bold)
+ (dired-mark :foreground orange :weight 'bold)
+ (dired-marked :foreground magenta :weight 'bold :inverse-video t)
+ (dired-perm-write :foreground fg :underline t)
+ (dired-symlink :foreground cyan :weight 'bold)
+ (dired-warning :foreground warning)
+ ;;;; dired+
+ (diredp-file-name :foreground base8)
+ (diredp-dir-name :foreground base8 :weight 'bold)
+ (diredp-ignored-file-name :foreground base5)
+ (diredp-compressed-file-suffix :foreground base5)
+ (diredp-symlink :foreground violet)
+ (diredp-dir-heading :foreground blue :weight 'bold)
+ (diredp-file-suffix :foreground violet)
+ (diredp-read-priv :foreground magenta)
+ (diredp-write-priv :foreground green)
+ (diredp-exec-priv :foreground yellow)
+ (diredp-rare-priv :foreground red :weight 'bold)
+ (diredp-dir-priv :foreground blue :weight 'bold)
+ (diredp-no-priv :foreground base5)
+ (diredp-number :foreground magenta)
+ (diredp-date-time :foreground blue)
+ ;;;; dired-k
+ (dired-k-modified :foreground vc-modified :weight 'bold)
+ (dired-k-commited :foreground green :weight 'bold)
+ (dired-k-added :foreground vc-added :weight 'bold)
+ (dired-k-untracked :foreground teal :weight 'bold)
+ (dired-k-ignored :foreground base5 :weight 'bold)
+ (dired-k-directory :foreground blue :weight 'bold)
+ ;;;; dired-subtree
+ (dired-subtree-depth-1-face :background (doom-darken bg-alt 0.02))
+ (dired-subtree-depth-2-face :background (doom-darken bg-alt 0.04))
+ (dired-subtree-depth-3-face :background (doom-darken bg-alt 0.06))
+ (dired-subtree-depth-4-face :background (doom-darken bg-alt 0.08))
+ (dired-subtree-depth-5-face :background (doom-darken bg-alt 0.10))
+ (dired-subtree-depth-6-face :background (doom-darken bg-alt 0.12))
+ ;;;; diredfl
+ (diredfl-autofile-name :foreground base4)
+ (diredfl-compressed-file-name :foreground yellow)
+ (diredfl-compressed-file-suffix :foreground (doom-blend orange bg 0.6))
+ (diredfl-date-time :foreground cyan :weight 'light)
+ (diredfl-deletion :foreground red :background (doom-blend red bg 0.2) :weight 'bold)
+ (diredfl-deletion-file-name :foreground red :background (doom-blend red bg 0.2))
+ (diredfl-dir-heading :foreground blue :weight 'bold)
+ (diredfl-dir-name :foreground blue)
+ (diredfl-dir-priv :foreground blue)
+ (diredfl-exec-priv :foreground green)
+ (diredfl-executable-tag :foreground green)
+ (diredfl-file-name :foreground fg)
+ (diredfl-file-suffix :foreground (doom-blend fg bg 0.6))
+ (diredfl-flag-mark :foreground yellow :background (doom-blend yellow bg 0.2) :weight 'bold)
+ (diredfl-flag-mark-line :background (doom-blend yellow bg 0.1))
+ (diredfl-ignored-file-name :foreground comments)
+ (diredfl-link-priv :foreground violet)
+ (diredfl-no-priv :inherit 'shadow)
+ (diredfl-number :foreground orange)
+ (diredfl-other-priv :foreground magenta)
+ (diredfl-rare-priv :foreground fg)
+ (diredfl-read-priv :foreground yellow)
+ (diredfl-symlink :foreground violet)
+ (diredfl-tagged-autofile-name :foreground base5)
+ (diredfl-write-priv :foreground red)
+ ;;;; doom-modeline
+ (doom-modeline-eldoc-bar :background green)
+ (doom-modeline-bar-inactive :background nil) ; transparent
+ ;;;; doom-themes
+ (doom-themes-visual-bell :background error)
+ ;;;; ediff <built-in>
+ (ediff-fine-diff-A :background (doom-blend selection bg 0.7) :weight 'bold :extend t)
+ (ediff-fine-diff-B :inherit 'ediff-fine-diff-A)
+ (ediff-fine-diff-C :inherit 'ediff-fine-diff-A)
+ (ediff-current-diff-A :background (doom-blend selection bg 0.3) :extend t)
+ (ediff-current-diff-B :inherit 'ediff-current-diff-A)
+ (ediff-current-diff-C :inherit 'ediff-current-diff-A)
+ (ediff-even-diff-A :inherit 'hl-line)
+ (ediff-even-diff-B :inherit 'ediff-even-diff-A)
+ (ediff-even-diff-C :inherit 'ediff-even-diff-A)
+ (ediff-odd-diff-A :inherit 'ediff-even-diff-A)
+ (ediff-odd-diff-B :inherit 'ediff-odd-diff-A)
+ (ediff-odd-diff-C :inherit 'ediff-odd-diff-A)
+ ;;;; elfeed
+ (elfeed-log-debug-level-face :foreground comments)
+ (elfeed-log-error-level-face :inherit 'error)
+ (elfeed-log-info-level-face :inherit 'success)
+ (elfeed-log-warn-level-face :inherit 'warning)
+ (elfeed-search-date-face :foreground violet)
+ (elfeed-search-feed-face :foreground blue)
+ (elfeed-search-tag-face :foreground comments)
+ (elfeed-search-title-face :foreground comments)
+ (elfeed-search-filter-face :foreground violet)
+ (elfeed-search-unread-count-face :foreground yellow)
+ (elfeed-search-unread-title-face :foreground fg :weight 'bold)
+ ;;;; elixir-mode <modes:elixir-mode>
+ (elixir-atom-face (&light :foreground dark-blue)
+ (&dark :foreground cyan))
+ (elixir-attribute-face :foreground violet)
+ ;;;; elscreen
+ (elscreen-tab-background-face :background bg)
+ (elscreen-tab-control-face :background bg :foreground bg)
+ (elscreen-tab-current-screen-face :background bg-alt :foreground fg)
+ (elscreen-tab-other-screen-face :background bg :foreground fg-alt)
+ ;;;; enh-ruby-mode <modes:enh-ruby-mode>
+ (enh-ruby-heredoc-delimiter-face :inherit 'font-lock-string-face)
+ (enh-ruby-op-face :foreground operators)
+ (enh-ruby-regexp-delimiter-face :inherit 'enh-ruby-regexp-face)
+ (enh-ruby-regexp-face :foreground constants)
+ (enh-ruby-string-delimiter-face :inherit 'font-lock-string-face)
+ (erm-syn-errline :underline `(:style wave :color ,error))
+ (erm-syn-warnline :underline `(:style wave :color ,warning))
+ ;;;; erc <built-in>
+ (erc-button :weight 'bold :underline t)
+ (erc-default-face :inherit 'default)
+ (erc-action-face :weight 'bold)
+ (erc-command-indicator-face :weight 'bold)
+ (erc-direct-msg-face :foreground magenta)
+ (erc-error-face :inherit 'error)
+ (erc-header-line :background (doom-darken bg-alt 0.15) :foreground highlight)
+ (erc-input-face :foreground green)
+ (erc-current-nick-face :foreground green :weight 'bold)
+ (erc-timestamp-face :foreground blue :weight 'bold)
+ (erc-nick-default-face :weight 'bold)
+ (erc-nick-msg-face :foreground magenta)
+ (erc-nick-prefix-face :inherit 'erc-nick-default-face)
+ (erc-my-nick-face :foreground green :weight 'bold)
+ (erc-my-nick-prefix-face :inherit 'erc-my-nick-face)
+ (erc-notice-face :foreground comments)
+ (erc-prompt-face :foreground highlight :weight 'bold)
+ ;;;; eshell <built-in>
+ (eshell-prompt :foreground highlight :weight 'bold)
+ (eshell-ls-archive :foreground magenta)
+ (eshell-ls-backup :foreground yellow)
+ (eshell-ls-clutter :foreground red)
+ (eshell-ls-directory :foreground blue)
+ (eshell-ls-executable :foreground green)
+ (eshell-ls-missing :foreground red)
+ (eshell-ls-product :foreground orange)
+ (eshell-ls-readonly :foreground orange)
+ (eshell-ls-special :foreground violet)
+ (eshell-ls-symlink :foreground cyan)
+ (eshell-ls-unreadable :foreground base5)
+ ;;;; evil
+ (evil-ex-info :foreground error :slant 'italic)
+ (evil-ex-search :background highlight :foreground base0 :weight 'bold)
+ (evil-ex-substitute-matches :background base0 :foreground red :weight 'bold :strike-through t)
+ (evil-ex-substitute-replacement :background base0 :foreground green :weight 'bold)
+ (evil-search-highlight-persist-highlight-face :inherit 'lazy-highlight)
+ ;;;; evil-mc
+ (evil-mc-cursor-default-face :background magenta :foreground base0 :inverse-video nil)
+ (evil-mc-region-face :inherit 'region)
+ (evil-mc-cursor-bar-face :height 1 :background magenta :foreground base0)
+ (evil-mc-cursor-hbar-face :underline `(:color ,highlight))
+ ;;;; evil-snipe
+ (evil-snipe-first-match-face :foreground highlight :background dark-blue :weight 'bold)
+ (evil-snipe-matches-face :foreground highlight :underline t :weight 'bold)
+ ;;;; evil-googles
+ (evil-goggles-default-face :inherit 'region :background (doom-blend region bg 0.5))
+ ;;;; eww
+ (eww-form-checkbox :inherit 'eww-form-file)
+ (eww-form-file :inherit 'eww-form-submit :background bg-alt)
+ (eww-form-select :inherit 'eww-form-submit :background bg-alt)
+ (eww-form-submit :inherit 'eww-form-text :box `(:line-width 2 :style released-button) :background base2)
+ (eww-form-text :box `(:line-width 1 :color ,base3) :background bg :foreground fg :distant-foreground bg)
+ (eww-form-textarea :inherit 'eww-form-text)
+ (eww-invalid-certificate :foreground error)
+ (eww-valid-certificate :foreground highlight)
+ ;;;; eyebrowse
+ (eyebrowse-mode-line-active :weight 'bold :foreground highlight)
+ ;;;; flycheck
+ (flycheck-error :underline `(:style wave :color ,red))
+ (flycheck-warning :underline `(:style wave :color ,yellow))
+ (flycheck-info :underline `(:style wave :color ,green))
+ (flycheck-fringe-error :inherit 'fringe :foreground error)
+ (flycheck-fringe-warning :inherit 'fringe :foreground warning)
+ (flycheck-fringe-info :inherit 'fringe :foreground success)
+ ;;;; flycheck-posframe
+ (flycheck-posframe-face :inherit 'default)
+ (flycheck-posframe-background-face :background bg-alt)
+ (flycheck-posframe-error-face :inherit 'flycheck-posframe-face :foreground error)
+ (flycheck-posframe-info-face :inherit 'flycheck-posframe-face :foreground fg)
+ (flycheck-posframe-warning-face :inherit 'flycheck-posframe-face :foreground warning)
+ ;;;; flymake
+ (flymake-error :underline `(:style wave :color ,red))
+ (flymake-note :underline `(:style wave :color ,green))
+ (flymake-warning :underline `(:style wave :color ,orange))
+ ;;;; flyspell <built-in>
+ (flyspell-incorrect :underline `(:style wave :color ,error) :inherit 'unspecified)
+ (flyspell-duplicate :underline `(:style wave :color ,warning) :inherit 'unspecified)
+ ;;;; flx-ido
+ (flx-highlight-face :weight 'bold :foreground yellow :underline nil)
+ ;;;; git-commit
+ (git-commit-summary :foreground strings)
+ (git-commit-overlong-summary :inherit 'error :background base0 :slant 'italic :weight 'bold)
+ (git-commit-nonempty-second-line :inherit 'git-commit-overlong-summary)
+ (git-commit-keyword :foreground cyan :slant 'italic)
+ (git-commit-pseudo-header :foreground doc-comments :slant 'italic)
+ (git-commit-known-pseudo-header :foreground doc-comments :weight 'bold :slant 'italic)
+ (git-commit-comment-branch-local :foreground magenta)
+ (git-commit-comment-branch-remote :foreground green)
+ (git-commit-comment-detached :foreground orange)
+ (git-commit-comment-heading :foreground keywords)
+ (git-commit-comment-file :foreground violet)
+ (git-commit-comment-action)
+ ;;;; git-gutter
+ (git-gutter:modified :inherit 'fringe :foreground vc-modified)
+ (git-gutter:added :inherit 'fringe :foreground vc-added)
+ (git-gutter:deleted :inherit 'fringe :foreground vc-deleted)
+ ;;;; git-gutter+
+ (git-gutter+-modified :inherit 'fringe :foreground vc-modified :background nil)
+ (git-gutter+-added :inherit 'fringe :foreground vc-added :background nil)
+ (git-gutter+-deleted :inherit 'fringe :foreground vc-deleted :background nil)
+ ;;;; git-gutter-fringe
+ ((git-gutter-fr:modified &inherit git-gutter:modified))
+ ((git-gutter-fr:added &inherit git-gutter:added))
+ ((git-gutter-fr:deleted &inherit git-gutter:deleted))
+ ;;;; gnus (built-in)
+ (gnus-group-mail-1 :weight 'bold :foreground fg)
+ (gnus-group-mail-2 :inherit 'gnus-group-mail-1)
+ (gnus-group-mail-3 :inherit 'gnus-group-mail-1)
+ (gnus-group-mail-1-empty :foreground base5)
+ (gnus-group-mail-2-empty :inherit 'gnus-group-mail-1-empty)
+ (gnus-group-mail-3-empty :inherit 'gnus-group-mail-1-empty)
+ (gnus-group-news-1 :inherit 'gnus-group-mail-1)
+ (gnus-group-news-2 :inherit 'gnus-group-news-1)
+ (gnus-group-news-3 :inherit 'gnus-group-news-1)
+ (gnus-group-news-4 :inherit 'gnus-group-news-1)
+ (gnus-group-news-5 :inherit 'gnus-group-news-1)
+ (gnus-group-news-6 :inherit 'gnus-group-news-1)
+ (gnus-group-news-1-empty :inherit 'gnus-group-mail-1-empty)
+ (gnus-group-news-2-empty :inherit 'gnus-group-news-1-empty)
+ (gnus-group-news-3-empty :inherit 'gnus-group-news-1-empty)
+ (gnus-group-news-4-empty :inherit 'gnus-group-news-1-empty)
+ (gnus-group-news-5-empty :inherit 'gnus-group-news-1-empty)
+ (gnus-group-news-6-empty :inherit 'gnus-group-news-1-empty)
+ (gnus-group-mail-low :inherit 'gnus-group-mail-1 :weight 'normal)
+ (gnus-group-mail-low-empty :inherit 'gnus-group-mail-1-empty)
+ (gnus-group-news-low :inherit 'gnus-group-mail-1 :foreground base5)
+ (gnus-group-news-low-empty :inherit 'gnus-group-news-low :weight 'normal)
+ (gnus-header-content :inherit 'message-header-other)
+ (gnus-header-from :inherit 'message-header-other)
+ (gnus-header-name :inherit 'message-header-name)
+ (gnus-header-newsgroups :inherit 'message-header-other)
+ (gnus-header-subject :inherit 'message-header-subject)
+ (gnus-summary-cancelled :foreground red :strike-through t)
+ (gnus-summary-high-ancient :foreground (doom-lighten base5 0.2) :inherit 'italic)
+ (gnus-summary-high-read :foreground (doom-lighten fg 0.2))
+ (gnus-summary-high-ticked :foreground (doom-lighten magenta 0.2))
+ (gnus-summary-high-unread :foreground (doom-lighten green 0.2))
+ (gnus-summary-low-ancient :foreground (doom-darken base5 0.2) :inherit 'italic)
+ (gnus-summary-low-read :foreground (doom-darken fg 0.2))
+ (gnus-summary-low-ticked :foreground (doom-darken magenta 0.2))
+ (gnus-summary-low-unread :foreground (doom-darken green 0.2))
+ (gnus-summary-normal-ancient :foreground base5 :inherit 'italic)
+ (gnus-summary-normal-read :foreground fg)
+ (gnus-summary-normal-ticked :foreground magenta)
+ (gnus-summary-normal-unread :foreground green :inherit 'bold)
+ (gnus-summary-selected :foreground blue :weight 'bold)
+ (gnus-cite-1 :foreground violet)
+ (gnus-cite-2 :foreground yellow)
+ (gnus-cite-3 :foreground magenta)
+ (gnus-cite-4 :foreground green)
+ (gnus-cite-5 :foreground green)
+ (gnus-cite-6 :foreground green)
+ (gnus-cite-7 :foreground magenta)
+ (gnus-cite-8 :foreground magenta)
+ (gnus-cite-9 :foreground magenta)
+ (gnus-cite-10 :foreground yellow)
+ (gnus-cite-11 :foreground yellow)
+ (gnus-signature :foreground yellow)
+ (gnus-x-face :background base5 :foreground fg)
+ ;;;; goggles
+ (goggles-changed :inherit 'region)
+ (goggles-removed :background (doom-blend red bg-alt 0.25) :extend t)
+ (goggles-added :background (doom-blend green bg-alt 0.25))
+ ;;;; helm
+ (helm-selection
+ (&all :inherit 'bold :background selection :extend t)
+ (&dark :distant-foreground highlight)
+ (&light :distant-foreground base0))
+ (helm-match :inherit 'bold :foreground highlight :distant-foreground base8)
+ (helm-source-header :background base2 :foreground keywords :weight 'bold)
+ (helm-visible-mark :inherit '(bold highlight))
+ (helm-moccur-buffer :inherit 'link)
+ (helm-ff-file :foreground fg)
+ (helm-ff-prefix :foreground keywords)
+ (helm-ff-dotted-directory :foreground grey)
+ (helm-ff-directory :foreground variables)
+ (helm-ff-executable :foreground base8 :inherit 'italic)
+ (helm-grep-match :foreground highlight :distant-foreground red)
+ (helm-grep-file :foreground methods)
+ (helm-grep-lineno :foreground base5)
+ (helm-grep-finish :foreground green)
+ ;;;; helm-swoop
+ (helm-swoop-target-line-face :foreground highlight :inverse-video t)
+ (helm-swoop-target-line-block-face :foreground yellow)
+ (helm-swoop-target-word-face :foreground green :inherit 'bold)
+ (helm-swoop-target-number-face :foreground base5)
+ ;;;; helm-rg
+ (helm-rg-active-arg-face :foreground green :weight 'normal)
+ (helm-rg-base-rg-cmd-face :foreground grey :weight 'normal)
+ (helm-rg-colon-separator-ripgrep-output-face :foreground base8)
+ (helm-rg-directory-cmd-face :foreground (doom-darken yellow 0.25) :background base0 :weight 'normal)
+ (helm-rg-directory-header-face :foreground base8 :background base0 :weight 'bold)
+ (helm-rg-error-message :foreground red)
+ (helm-rg-extra-arg-face :foreground yellow :weight 'normal)
+ (helm-rg-file-match-face :foreground cyan :underline t)
+ (helm-rg-inactive-arg-face :foreground grey :weight 'normal)
+ (helm-rg-line-number-match-face :foreground orange :underline t)
+ (helm-rg-match-text-face :foreground base8 :background violet)
+ (helm-rg-title-face :foreground violet :background base0 :weight 'bold)
+ ;;;; helpful
+ (helpful-heading :weight 'bold :height 1.2)
+ ;;;; hi-lock <built-in>
+ (hi-yellow :background yellow)
+ (hi-pink :background magenta)
+ (hi-red-b :foreground red :weight 'bold)
+ (hi-green :background green)
+ (hi-green-b :foreground green :weight 'bold)
+ (hi-blue :background blue)
+ (hi-blue-b :foreground blue :weight 'bold)
+ ;; (hi-black-b :weight 'bold)
+ ;; (hi-black-hb :inherit 'variable-pitch :weight 'bold :height 1.67)
+ ;;;; hideshow <built-in>
+ (+fold-hideshow-folded-face :inherit 'font-lock-comment-face
+ :weight 'light
+ :background (doom-darken bg 0.125))
+ ;;;; highlight-numbers-mode
+ (highlight-numbers-number :inherit 'bold :foreground numbers)
+ ;;;; highlight-indentation-mode
+ (highlight-indentation-face :inherit 'hl-line)
+ (highlight-indentation-current-column-face :background base1)
+ (highlight-indentation-guides-odd-face :inherit 'highlight-indentation-face)
+ (highlight-indentation-guides-even-face :inherit 'highlight-indentation-face)
+ ;;;; highlight-quoted-mode
+ (highlight-quoted-symbol :foreground type)
+ (highlight-quoted-quote :foreground operators)
+ ;;;; highlight-symbol
+ (highlight-symbol-face
+ (&dark :background (doom-lighten region 0.1) :distant-foreground fg-alt)
+ (&light :background (doom-darken region 0.1) :distant-foreground fg-alt))
+ ;;;; highlight-thing
+ (highlight-thing
+ (&dark :background (doom-lighten region 0.1) :distant-foreground fg-alt)
+ (&light :background (doom-darken region 0.1) :distant-foreground fg-alt))
+ ;;;; hl-fill-column-face
+ (hl-fill-column-face :inherit '(hl-line shadow))
+ ;;;; hl-line (built-in)
+ (hl-line :background bg-alt :extend t)
+ ;;;; hl-todo
+ (hl-todo :foreground red :weight 'bold)
+ ;;;; hlinum
+ (linum-highlight-face :foreground fg :distant-foreground nil :weight 'normal)
+ ;;;; hydra
+ (hydra-face-red :foreground red :weight 'bold)
+ (hydra-face-blue :foreground blue :weight 'bold)
+ (hydra-face-amaranth :foreground magenta :weight 'bold)
+ (hydra-face-pink :foreground violet :weight 'bold)
+ (hydra-face-teal :foreground teal :weight 'bold)
+ ;;;; iedit
+ (iedit-occurrence :foreground magenta :weight 'bold :inverse-video t)
+ (iedit-read-only-occurrence :inherit 'region)
+ ;;;; ido <built-in>
+ (ido-first-match :foreground orange)
+ (ido-indicator :foreground red :background bg)
+ (ido-only-match :foreground green)
+ (ido-subdir :foreground violet)
+ (ido-virtual :foreground comments)
+ ;;;; imenu-list
+ ;; (imenu-list-entry-face)
+ (imenu-list-entry-face-0 :foreground highlight)
+ (imenu-list-entry-subalist-face-0 :inherit 'imenu-list-entry-face-0 :weight 'bold)
+ (imenu-list-entry-face-1 :foreground green)
+ (imenu-list-entry-subalist-face-1 :inherit 'imenu-list-entry-face-1 :weight 'bold)
+ (imenu-list-entry-face-2 :foreground yellow)
+ (imenu-list-entry-subalist-face-2 :inherit 'imenu-list-entry-face-2 :weight 'bold)
+ ;;;; indent-guide
+ ((indent-guide-face &inherit highlight-indentation-face))
+ ;;;; isearch <built-in>
+ (isearch :inherit 'lazy-highlight :weight 'bold)
+ (isearch-fail :background error :foreground base0 :weight 'bold)
+ ;;;; ivy
+ (ivy-current-match :background region :distant-foreground nil :extend t)
+ (ivy-minibuffer-match-face-1
+ :background nil
+ :foreground (doom-lighten grey 0.14)
+ :weight 'light)
+ (ivy-minibuffer-match-face-2
+ :inherit 'ivy-minibuffer-match-face-1
+ :foreground magenta :background base1 :weight 'semi-bold)
+ (ivy-minibuffer-match-face-3
+ :inherit 'ivy-minibuffer-match-face-2
+ :foreground green :weight 'semi-bold)
+ (ivy-minibuffer-match-face-4
+ :inherit 'ivy-minibuffer-match-face-2
+ :foreground yellow :weight 'semi-bold)
+ (ivy-minibuffer-match-highlight :foreground violet)
+ (ivy-highlight-face :foreground violet)
+ (ivy-confirm-face :foreground success)
+ (ivy-match-required-face :foreground error)
+ (ivy-virtual :inherit 'italic :foreground doc-comments)
+ (ivy-modified-buffer :inherit 'bold :foreground warning)
+ ;;;; ivy-posframe
+ (ivy-posframe :background (doom-darken bg-alt 0.2))
+ (ivy-posframe-border :inherit 'internal-border)
+ ;;;; selectrum
+ (selectrum-current-candidate :background region :distant-foreground nil :extend t)
+ ;;;; vertico
+ (vertico-current :background region :distant-foreground nil :extend t)
+ ;;;; vertico-posframe
+ ;;(vertico-posframe :inherit 'default)
+ (vertico-posframe-border :background grey)
+ (vertico-posframe-border-2 :background red)
+ (vertico-posframe-border-3 :background green)
+ (vertico-posframe-border-4 :background blue)
+ (vertico-posframe-border-fallback :background yellow)
+ ;;;; jabber
+ (jabber-activity-face :foreground red :weight 'bold)
+ (jabber-activity-personal-face :foreground blue :weight 'bold)
+ (jabber-chat-error :foreground red :weight 'bold)
+ (jabber-chat-prompt-foreign :foreground red :weight 'bold)
+ (jabber-chat-prompt-local :foreground blue :weight 'bold)
+ (jabber-chat-prompt-system :foreground green :weight 'bold)
+ (jabber-chat-text-foreign :foreground fg)
+ (jabber-chat-text-local :foreground fg)
+ (jabber-rare-time-face :foreground green)
+ (jabber-roster-user-away :foreground yellow)
+ (jabber-roster-user-chatty :foreground green :weight 'bold)
+ (jabber-roster-user-dnd :foreground red)
+ (jabber-roster-user-error :foreground red)
+ (jabber-roster-user-offline :foreground fg)
+ (jabber-roster-user-online :foreground green :weight 'bold)
+ (jabber-roster-user-xa :foreground cyan)
+ ;;;; jdee <modes:jdee-mode>
+ (jdee-font-lock-number-face :foreground numbers)
+ (jdee-font-lock-operator-face :foreground operators)
+ (jdee-font-lock-constant-face :inherit 'font-lock-constant-face)
+ (jdee-font-lock-constructor-face :foreground methods)
+ (jdee-font-lock-public-face :inherit 'font-lock-keyword-face)
+ (jdee-font-lock-protected-face :inherit 'font-lock-keyword-face)
+ (jdee-font-lock-private-face :inherit 'font-lock-keyword-face)
+ (jdee-font-lock-modifier-face :inherit 'font-lock-type-face)
+ (jdee-font-lock-doc-tag-face :foreground violet)
+ (jdee-font-lock-italic-face :inherit 'italic)
+ (jdee-font-lock-bold-face :inherit 'bold)
+ (jdee-font-lock-link-face :foreground blue :italic nil :underline t)
+ ;;;; js2-mode <modes:js2-mode,js2-jsx-mode>
+ (js2-function-param :foreground variables)
+ (js2-function-call :foreground functions)
+ (js2-object-property :foreground violet)
+ (js2-jsdoc-tag :foreground doc-comments)
+ (js2-external-variable :foreground operators)
+ ;;;; keycast
+ (keycast-command :inherit 'mode-line-emphasis)
+ (keycast-key :inherit '(bold mode-line-highlight))
+ ;;;; ledger-mode <modes:ledger-mode>
+ (ledger-font-posting-date-face :foreground blue)
+ (ledger-font-posting-amount-face :foreground yellow)
+ (ledger-font-posting-account-face :foreground base8)
+ (ledger-font-payee-cleared-face :foreground violet :weight 'bold)
+ (ledger-font-payee-uncleared-face :foreground base5 :weight 'bold)
+ (ledger-font-xact-highlight-face :background base0)
+ ;;;; linum <built-in>
+ ((linum &inherit line-number))
+ ;;;; linum-relative
+ ((linum-relative-current-face &inherit line-number-current-line))
+ ;;;; lui
+ (lui-time-stamp-face :foreground violet)
+ (lui-highlight-face :foreground highlight)
+ (lui-button-face :foreground builtin :underline t)
+ ;;;; magit
+ (magit-bisect-bad :foreground red)
+ (magit-bisect-good :foreground green)
+ (magit-bisect-skip :foreground orange)
+ (magit-blame-hash :foreground cyan)
+ (magit-blame-date :foreground red)
+ (magit-blame-heading :foreground orange :background base3 :extend t)
+ (magit-branch-current :foreground blue)
+ (magit-branch-local :foreground cyan)
+ (magit-branch-remote :foreground green)
+ (magit-cherry-equivalent :foreground violet)
+ (magit-cherry-unmatched :foreground cyan)
+ (magit-diff-added :foreground (doom-darken vc-added 0.2) :background (doom-blend vc-added bg 0.1) :extend t)
+ (magit-diff-added-highlight :foreground vc-added :background (doom-blend vc-added bg 0.2) :weight 'bold :extend t)
+ (magit-diff-base :foreground (doom-darken orange 0.2) :background (doom-blend orange bg 0.1) :extend t)
+ (magit-diff-base-highlight :foreground orange :background (doom-blend orange bg 0.2) :weight 'bold :extend t)
+ (magit-diff-context :foreground (doom-darken fg 0.4) :background bg :extend t)
+ (magit-diff-context-highlight :foreground fg :background bg-alt :extend t)
+ (magit-diff-file-heading :foreground fg :weight 'bold :extend t)
+ (magit-diff-file-heading-selection :foreground magenta :background dark-blue :weight 'bold :extend t)
+ (magit-diff-hunk-heading :foreground bg :background (doom-blend violet bg 0.3) :extend t)
+ (magit-diff-hunk-heading-highlight :foreground bg :background violet :weight 'bold :extend t)
+ (magit-diff-lines-heading :foreground yellow :background red :extend t :extend t)
+ (magit-diff-removed :foreground (doom-darken vc-deleted 0.2) :background (doom-blend vc-deleted base3 0.1) :extend t)
+ (magit-diff-removed-highlight :foreground vc-deleted :background (doom-blend vc-deleted base3 0.2) :weight 'bold :extend t)
+ (magit-diffstat-added :foreground vc-added)
+ (magit-diffstat-removed :foreground vc-deleted)
+ (magit-dimmed :foreground comments)
+ (magit-hash :foreground comments)
+ (magit-header-line :background dark-blue :foreground base8 :weight 'bold
+ :box `(:line-width 3 :color ,dark-blue))
+ (magit-filename :foreground violet)
+ (magit-log-author :foreground orange)
+ (magit-log-date :foreground blue)
+ (magit-log-graph :foreground comments)
+ (magit-process-ng :inherit 'error)
+ (magit-process-ok :inherit 'success)
+ (magit-reflog-amend :foreground magenta)
+ (magit-reflog-checkout :foreground blue)
+ (magit-reflog-cherry-pick :foreground green)
+ (magit-reflog-commit :foreground green)
+ (magit-reflog-merge :foreground green)
+ (magit-reflog-other :foreground cyan)
+ (magit-reflog-rebase :foreground magenta)
+ (magit-reflog-remote :foreground cyan)
+ (magit-reflog-reset :inherit 'error)
+ (magit-refname :foreground comments)
+ (magit-section-heading :foreground blue :weight 'bold :extend t)
+ (magit-section-heading-selection :foreground orange :weight 'bold :extend t)
+ (magit-section-highlight :inherit 'hl-line)
+ (magit-section-secondary-heading :foreground violet :weight 'bold :extend t)
+ (magit-sequence-drop :foreground red)
+ (magit-sequence-head :foreground blue)
+ (magit-sequence-part :foreground orange)
+ (magit-sequence-stop :foreground green)
+ (magit-signature-bad :inherit 'error)
+ (magit-signature-error :inherit 'error)
+ (magit-signature-expired :foreground orange)
+ (magit-signature-good :inherit 'success)
+ (magit-signature-revoked :foreground magenta)
+ (magit-signature-untrusted :foreground yellow)
+ (magit-tag :foreground yellow)
+ ;;;; make-mode <built-in> <modes:makefile-mode,makefile-automake-mode,makefile-makepp-mode,makefile-gmake-mode,makefile-imake-mode,makefile-bsdmake-mode>
+ (makefile-targets :foreground blue)
+ ;;;; man <built-in> <mode:Man-mode>
+ (Man-overstrike :inherit 'bold :foreground operators)
+ (Man-underline :inherit 'underline :foreground keywords)
+ ;;;; markdown-mode <modes:markdown-mode,gfm-mode>
+ (markdown-header-face :inherit 'bold :foreground highlight)
+ (markdown-header-delimiter-face :inherit 'markdown-header-face)
+ (markdown-metadata-key-face :foreground red)
+ (markdown-list-face :foreground red)
+ (markdown-link-face :foreground highlight)
+ (markdown-url-face :foreground magenta :weight 'normal)
+ (markdown-italic-face :inherit 'italic :foreground violet)
+ (markdown-bold-face :inherit 'bold :foreground orange)
+ (markdown-markup-face :foreground operators)
+ (markdown-blockquote-face :inherit 'italic :foreground doc-comments)
+ (markdown-pre-face :foreground strings)
+ (markdown-code-face :background base3 :extend t)
+ (markdown-reference-face :foreground doc-comments)
+ (markdown-inline-code-face :inherit '(markdown-code-face markdown-pre-face) :extend nil)
+ (markdown-html-attr-name-face :inherit 'font-lock-variable-name-face)
+ (markdown-html-attr-value-face :inherit 'font-lock-string-face)
+ (markdown-html-entity-face :inherit 'font-lock-variable-name-face)
+ (markdown-html-tag-delimiter-face :inherit 'markdown-markup-face)
+ (markdown-html-tag-name-face :inherit 'font-lock-keyword-face)
+ ;;;; marginalia
+ (marginalia-documentation :inherit 'font-lock-doc-face)
+ (marginalia-file-priv-dir :foreground blue)
+ (marginalia-file-priv-exec :foreground green)
+ (marginalia-file-priv-link :foreground violet)
+ (marginalia-file-priv-other :foreground magenta)
+ (marginalia-file-priv-rare :foreground fg)
+ (marginalia-file-priv-read :foreground yellow)
+ (marginalia-file-priv-write :foreground red)
+ (marginalia-number :foreground numbers)
+ (marginalia-size :foreground violet)
+ (marginalia-lighter :foreground violet)
+ ;;;; message <built-in>
+ (message-header-name :foreground green)
+ (message-header-subject :foreground highlight :weight 'bold)
+ (message-header-to :foreground highlight :weight 'bold)
+ (message-header-cc :inherit 'message-header-to :foreground (doom-darken highlight 0.15))
+ (message-header-other :foreground violet)
+ (message-header-newsgroups :foreground yellow)
+ (message-header-xheader :foreground doc-comments)
+ (message-separator :foreground comments)
+ (message-mml :foreground comments :slant 'italic)
+ ((message-cited-text &inherit gnus-cite-1))
+ ((message-cited-text-1 &inherit gnus-cite-2))
+ ((message-cited-text-2 &inherit gnus-cite-3))
+ ((message-cited-text-3 &inherit gnus-cite-4))
+ ((message-cited-text-4 &inherit gnus-cite-5))
+ ;;;; mic-paren
+ (paren-face-match :foreground red :background base0 :weight 'ultra-bold)
+ (paren-face-mismatch :foreground base0 :background red :weight 'ultra-bold)
+ (paren-face-no-match :inherit 'paren-face-mismatch :weight 'ultra-bold)
+ ;;;; minimap
+ (minimap-current-line-face :background selection)
+ (minimap-active-region-background :background vertical-bar)
+ ;;;; mmm-mode
+ (mmm-init-submode-face :background (doom-blend red bg 0.1))
+ (mmm-cleanup-submode-face :background (doom-blend yellow bg 0.1))
+ (mmm-declaration-submode-face :background (doom-blend cyan bg 0.1))
+ (mmm-comment-submode-face :background (doom-blend blue bg 0.1))
+ (mmm-output-submode-face :background (doom-blend violet bg 0.1))
+ (mmm-special-submode-face :background (doom-blend green bg 0.1))
+ (mmm-code-submode-face :background bg-alt)
+ (mmm-default-submode-face :background nil) ; make transparent
+ ;;;; multiple cursors
+ (mc/cursor-face :inherit 'cursor)
+ ;;;; nav-flash
+ (nav-flash-face :background selection :foreground base8 :weight 'bold)
+ ;;;; neotree
+ (neo-root-dir-face :foreground strings :background bg :box `(:line-width 4 :color ,bg))
+ (neo-file-link-face :foreground fg)
+ (neo-dir-link-face :foreground highlight)
+ (neo-expand-btn-face :foreground highlight)
+ (neo-vc-edited-face :foreground yellow)
+ (neo-vc-added-face :foreground green)
+ (neo-vc-removed-face :foreground red :strike-through t)
+ (neo-vc-conflict-face :foreground magenta :weight 'bold)
+ (neo-vc-ignored-face :foreground comments)
+ (doom-neotree-dir-face :foreground highlight)
+ (doom-neotree-file-face :foreground base8)
+ (doom-neotree-hidden-file-face :foreground comments)
+ (doom-neotree-text-file-face :foreground fg)
+ (doom-neotree-data-file-face :foreground violet)
+ (doom-neotree-media-file-face :inherit 'doom-neotree-hidden-file-face)
+ ;;;; nlinum
+ ((nlinum-current-line &inherit line-number-current-line))
+ ;;;; nlinum-hl
+ ((nlinum-hl-face &inherit line-number-current-line))
+ ;;;; nlinum-relative
+ ((nlinum-relative-current-face &inherit line-number-current-line))
+ ;;;; notmuch
+ ;; (notmuch-crypto-decryption :foreground blue-l)
+ ;; (notmuch-crypto-part-header :foreground yellow-l)
+ ;; (notmuch-crypto-signature-bad :foreground red-l)
+ ;; (notmuch-crypto-signature-good :foreground base1)
+ ;; (notmuch-crypto-signature-good-key :foreground aqua-l)
+ ;; (notmuch-crypto-signature-unknown :foreground yellow)
+ ;; (notmuch-hello-logo-background :foreground fg)
+ (notmuch-message-summary-face :foreground grey :background nil)
+ (notmuch-search-count :foreground comments)
+ (notmuch-search-date :foreground numbers)
+ (notmuch-search-flagged-face :foreground (doom-blend red base4 0.5))
+ (notmuch-search-matching-authors :foreground blue)
+ (notmuch-search-non-matching-authors :foreground fg)
+ (notmuch-search-subject :foreground fg)
+ (notmuch-search-unread-face :weight 'bold)
+ (notmuch-tag-added :foreground green :weight 'normal)
+ (notmuch-tag-deleted :foreground red :weight 'normal)
+ (notmuch-tag-face :foreground yellow :weight 'normal)
+ (notmuch-tag-flagged :foreground yellow :weight 'normal)
+ (notmuch-tag-unread :foreground yellow :weight 'normal)
+ (notmuch-tree-match-author-face :foreground blue :weight 'bold)
+ (notmuch-tree-match-date-face :foreground numbers :weight 'bold)
+ (notmuch-tree-match-face :foreground fg)
+ (notmuch-tree-match-subject-face :foreground fg)
+ (notmuch-tree-match-tag-face :foreground yellow)
+ (notmuch-tree-match-tree-face :foreground comments)
+ (notmuch-tree-no-match-author-face :foreground blue)
+ (notmuch-tree-no-match-date-face :foreground numbers)
+ (notmuch-tree-no-match-face :foreground base5)
+ (notmuch-tree-no-match-subject-face :foreground base5)
+ (notmuch-tree-no-match-tag-face :foreground yellow)
+ (notmuch-tree-no-match-tree-face :foreground yellow)
+ (notmuch-wash-cited-text :foreground base4)
+ (notmuch-wash-toggle-button :foreground fg)
+ ;;;; lsp-mode
+ (lsp-face-highlight-textual
+ (&all :weight 'bold)
+ (&light :background base3 :foreground base0 :distant-foreground base8)
+ (&dark :background (doom-blend highlight bg 0.3) :foreground base8 :distant-foreground base0))
+ (lsp-face-highlight-read :inherit 'lsp-face-highlight-textual)
+ (lsp-face-highlight-write :inherit 'lsp-face-highlight-textual)
+ (lsp-headerline-breadcrumb-separator-face :inherit 'shadow)
+ ;;;; lsp-ui
+ (lsp-ui-doc-background :inherit 'tooltip)
+ (lsp-ui-peek-filename :inherit 'mode-line-buffer-id)
+ (lsp-ui-peek-header :foreground fg :background (doom-lighten bg 0.1) :bold bold)
+ (lsp-ui-peek-selection :foreground bg :background blue :bold bold)
+ (lsp-ui-peek-list :background (doom-darken bg 0.1))
+ (lsp-ui-peek-peek :background (doom-darken bg 0.1))
+ (lsp-ui-peek-highlight :inherit 'lsp-ui-peek-header :background region :foreground bg :box t)
+ (lsp-ui-peek-line-number :foreground success)
+ (lsp-ui-sideline-code-action :foreground (doom-blend highlight bg 0.85))
+ (lsp-ui-sideline-current-symbol :inherit 'highlight)
+ (lsp-ui-sideline-symbol-info :foreground (doom-blend comments bg 0.85)
+ :background bg-alt :extend t)
+ ;;;; objed
+ (objed-mode-line :inherit 'warning :weight 'bold)
+ (objed-hl :inherit 'region :background (doom-blend region bg 0.5))
+ ;;;; orderless
+ (orderless-match-face-0 :weight 'bold :foreground (doom-blend blue fg 0.6) :background (doom-blend blue bg 0.1))
+ (orderless-match-face-1 :weight 'bold :foreground (doom-blend magenta fg 0.6) :background (doom-blend magenta bg 0.1))
+ (orderless-match-face-2 :weight 'bold :foreground (doom-blend green fg 0.6) :background (doom-blend green bg 0.1))
+ (orderless-match-face-3 :weight 'bold :foreground (doom-blend yellow fg 0.6) :background (doom-blend yellow bg 0.1))
+ ;;;; org <built-in> <modes:org-mode>
+ (org-archived :foreground doc-comments)
+ (org-block :background base3 :extend t)
+ (org-block-background :background base3 :extend t)
+ (org-block-begin-line :inherit 'org-block :foreground comments)
+ (org-block-end-line :inherit 'org-block-begin-line)
+ (org-checkbox :inherit 'org-todo)
+ (org-checkbox-statistics-done :inherit 'org-done)
+ (org-checkbox-statistics-todo :inherit 'org-todo)
+ (org-cite :foreground (doom-blend teal fg 0.9))
+ (org-cite-key :foreground (doom-blend teal fg 0.6) :underline t)
+ (org-code :inherit 'org-block :foreground orange)
+ (org-date :foreground yellow)
+ (org-default :inherit 'variable-pitch)
+ (org-document-info :foreground builtin)
+ (org-document-title :foreground builtin :weight 'bold)
+ (org-done :inherit 'org-headline-done :strike-through nil :weight 'bold)
+ (org-drawer :foreground comments)
+ (org-ellipsis :underline nil :background nil :foreground comments)
+ (org-footnote :foreground orange)
+ (org-formula :foreground cyan)
+ (org-headline-done :foreground base5)
+ (org-hide :foreground bg)
+ (org-latex-and-related :foreground base8 :weight 'bold)
+ (org-link :inherit 'link :foreground highlight)
+ (org-list-dt :foreground highlight)
+ (org-meta-line :foreground doc-comments)
+ (org-priority :foreground red)
+ (org-property-value :foreground doc-comments)
+ (org-quote :inherit 'org-block :slant 'italic)
+ (org-special-keyword :foreground doc-comments :underline nil)
+ (org-table :foreground violet)
+ (org-tag :foreground doc-comments :weight 'normal)
+ (org-todo :foreground green :bold 'inherit)
+ (org-verbatim :foreground green)
+ (org-warning :foreground warning)
+ ;; Omitted because we rely on style they inherit from the outline-N faces
+ ;;(org-level-1)
+ ;;(org-level-2)
+ ;;(org-level-3)
+ ;;(org-level-4)
+ ;;(org-level-5)
+ ;;(org-level-6)
+ ;;(org-level-7)
+ ;;(org-level-8)
+ ;;;; org-agenda <built-in>
+ (org-agenda-done :inherit 'org-done)
+ (org-agenda-dimmed-todo-face :foreground comments)
+ (org-agenda-date :foreground violet :weight 'ultra-bold)
+ (org-agenda-date-today :foreground (doom-lighten violet 0.4) :weight 'ultra-bold)
+ (org-agenda-date-weekend :foreground (doom-darken violet 0.4) :weight 'ultra-bold)
+ (org-agenda-structure :foreground fg :weight 'ultra-bold)
+ (org-agenda-clocking :background (doom-blend blue bg 0.2))
+ (org-upcoming-deadline :foreground (doom-blend fg bg 0.8))
+ (org-upcoming-distant-deadline :foreground (doom-blend fg bg 0.5))
+ (org-scheduled :foreground fg)
+ (org-scheduled-today :foreground base7)
+ (org-scheduled-previously :foreground base8)
+ (org-time-grid :foreground comments)
+ (org-sexp-date :foreground fg)
+ ;;;; org-habit
+ (org-habit-clear-face :weight 'bold :background base4)
+ (org-habit-clear-future-face :weight 'bold :background base3)
+ (org-habit-ready-face :weight 'bold :background (doom-blend blue bg-alt 0.5))
+ (org-habit-ready-future-face :weight 'bold :background (doom-blend blue bg-alt 0.3))
+ (org-habit-alert-face :weight 'bold :background (doom-blend yellow bg-alt 0.5))
+ (org-habit-alert-future-face :weight 'bold :background (doom-blend yellow bg-alt 0.3))
+ (org-habit-overdue-face :weight 'bold :background (doom-blend red bg-alt 0.5))
+ (org-habit-overdue-future-face :weight 'bold :background (doom-blend red bg-alt 0.3))
+ ;;;; org-journal <modes:org-journal-mode>
+ (org-journal-highlight :foreground highlight)
+ (org-journal-calendar-entry-face :foreground magenta :slant 'italic)
+ (org-journal-calendar-scheduled-face :foreground red :slant 'italic)
+ ;;;; org-pomodoro
+ (org-pomodoro-mode-line :foreground red)
+ (org-pomodoro-mode-line-overtime :foreground warning :weight 'bold)
+ ;;;; org-ref
+ (org-ref-acronym-face :foreground violet)
+ (org-ref-cite-face :foreground yellow :weight 'light :underline t)
+ (org-ref-glossary-face :foreground magenta)
+ (org-ref-label-face :foreground blue)
+ (org-ref-ref-face :inherit 'link :foreground teal)
+ ;;;; outline <built-in>
+ ;; NOTE org-mode's org-level-N faces inherit these outline-N faces.
+ (outline-1 :foreground blue :weight 'bold :extend t)
+ (outline-2 :foreground magenta :weight 'bold :extend t)
+ (outline-3 :foreground violet :weight 'bold :extend t)
+ (outline-4 :foreground (doom-lighten blue 0.25) :weight 'bold :extend t)
+ (outline-5 :foreground (doom-lighten magenta 0.25) :weight 'bold :extend t)
+ (outline-6 :foreground (doom-lighten blue 0.5) :weight 'bold :extend t)
+ (outline-7 :foreground (doom-lighten magenta 0.5) :weight 'bold :extend t)
+ (outline-8 :foreground (doom-lighten blue 0.8) :weight 'bold :extend t)
+ ;;;; parenface
+ (paren-face :foreground comments)
+ ;;;; parinfer
+ (parinfer-pretty-parens:dim-paren-face :foreground base5)
+ (parinfer-smart-tab:indicator-face :foreground base5)
+ ;;;; perspective
+ (persp-selected-face :foreground blue :weight 'bold)
+ ;;;; persp-mode
+ (persp-face-lighter-default :foreground highlight :weight 'bold)
+ (persp-face-lighter-buffer-not-in-persp :foreground doc-comments)
+ (persp-face-lighter-nil-persp :foreground comments)
+ ;;;; pkgbuild-mode <modes:pkgbuild-mode>
+ (pkgbuild-error-face :underline `(:style wave :color ,red))
+ ;;;; popup
+ (popup-face :inherit 'tooltip)
+ (popup-tip-face :inherit 'popup-face :foreground violet :background base0)
+ (popup-selection-face :background selection)
+ ;;;; power
+ (powerline-active0 :inherit 'mode-line :background bg)
+ (powerline-active1 :inherit 'mode-line :background (doom-lighten 'bg 0.025))
+ (powerline-active2 :inherit 'mode-line :foreground base8 :background (doom-lighten 'bg 0.08))
+ (powerline-inactive0 :inherit 'mode-line-inactive :background base2)
+ (powerline-inactive1 :inherit 'mode-line-inactive :background (doom-lighten 'base2 0.02))
+ (powerline-inactive2 :inherit 'mode-line-inactive :background (doom-lighten 'base2 0.04))
+ ;;;; rainbow-delimiters
+ (rainbow-delimiters-depth-1-face :foreground blue)
+ (rainbow-delimiters-depth-2-face :foreground magenta)
+ (rainbow-delimiters-depth-3-face :foreground green)
+ (rainbow-delimiters-depth-4-face :foreground violet)
+ (rainbow-delimiters-depth-5-face :foreground teal)
+ (rainbow-delimiters-depth-6-face :foreground blue)
+ (rainbow-delimiters-depth-7-face :foreground magenta)
+ (rainbow-delimiters-depth-8-face :foreground green)
+ (rainbow-delimiters-depth-9-face :foreground violet)
+ (rainbow-delimiters-base-error-face :inherit 'rainbow-delimiters-base-face :foreground error)
+ (rainbow-delimiters-base-face :inherit 'default)
+ (rainbow-delimiters-unmatched-face :foreground red :weight 'bold :inverse-video t)
+ (rainbow-delimiters-mismatched-face :inherit 'rainbow-delimiters-unmatched-face)
+ ;;;; re-builder <built-in>
+ (reb-match-0 :foreground orange :inverse-video t)
+ (reb-match-1 :foreground magenta :inverse-video t)
+ (reb-match-2 :foreground green :inverse-video t)
+ (reb-match-3 :foreground yellow :inverse-video t)
+ ;;;; rjsx-mode <modes:rjsx-mode>
+ (rjsx-tag :foreground type)
+ (rjsx-attr :foreground functions)
+ ;;;; rpm-spec-mode <modes:rpm-spec-mode>
+ (rpm-spec-macro-face :foreground yellow)
+ (rpm-spec-var-face :foreground violet)
+ (rpm-spec-tag-face :foreground blue)
+ (rpm-spec-obsolete-tag-face :foreground red)
+ (rpm-spec-package-face :foreground orange)
+ (rpm-spec-dir-face :foreground green)
+ (rpm-spec-doc-face :foreground orange)
+ (rpm-spec-ghost-face :foreground comments)
+ (rpm-spec-section-face :foreground magenta)
+ ;;;; rst <built-in> <modes:rst-mode>
+ (rst-block :inherit 'font-lock-constant-face)
+ (rst-level-1 :inherit 'rst-adornment :weight 'bold)
+ (rst-level-2 :inherit 'rst-adornment :weight 'bold)
+ (rst-level-3 :inherit 'rst-adornment :weight 'bold)
+ (rst-level-4 :inherit 'rst-adornment :weight 'bold)
+ (rst-level-5 :inherit 'rst-adornment :weight 'bold)
+ (rst-level-6 :inherit 'rst-adornment :weight 'bold)
+ ;;;; sh-script <built-in> <modes:sh-mode,shell-script-mode>
+ (sh-heredoc :inherit 'font-lock-string-face :weight 'normal)
+ (sh-quoted-exec :inherit 'font-lock-preprocessor-face)
+ ;;;; show-paren <built-in>
+ ((show-paren-match &inherit paren-face-match))
+ ((show-paren-mismatch &inherit paren-face-mismatch))
+ ;;;; smart-mode-line
+ (sml/charging :foreground green)
+ (sml/discharging :foreground yellow :weight 'bold)
+ (sml/filename :foreground violet :weight 'bold)
+ (sml/git :foreground blue)
+ (sml/modified :foreground cyan)
+ (sml/outside-modified :foreground cyan)
+ (sml/process :weight 'bold)
+ (sml/read-only :foreground cyan)
+ (sml/sudo :foreground orange :weight 'bold)
+ (sml/vc-edited :foreground green)
+ ;;;; smartparens
+ (sp-pair-overlay-face :background region)
+ ((sp-show-pair-match-face &inherit show-paren-match))
+ ((sp-show-pair-mismatch-face &inherit show-paren-mismatch))
+ ;;;; smerge-tool
+ (smerge-lower :background (doom-blend green bg 0.2))
+ (smerge-upper :background (doom-blend red base3 0.2))
+ (smerge-base :background (doom-blend blue bg 0.2))
+ (smerge-markers :background comments :foreground bg :distant-foreground fg :weight 'bold)
+ (smerge-refined-added :inherit 'diff-added :inverse-video t)
+ (smerge-refined-removed :inherit 'diff-removed :inverse-video t)
+ ;; Emacs <25 compatibility
+ ((smerge-mine &inherit smerge-upper))
+ ((smerge-other &inherit smerge-lower))
+ ;;;; solaire-mode
+ (solaire-default-face :inherit 'default :background bg-alt)
+ (solaire-hl-line-face :inherit 'hl-line :background bg :extend t)
+ ;;;; spaceline
+ (spaceline-highlight-face :background highlight)
+ (spaceline-modified :background vc-modified)
+ (spaceline-unmodified :background constants)
+ (spaceline-python-venv :foreground magenta :distant-foreground violet)
+ (spaceline-flycheck-error :inherit 'error :distant-background base0)
+ (spaceline-flycheck-warning :inherit 'warning :distant-background base0)
+ (spaceline-flycheck-info :inherit 'success :distant-background base0)
+ (spaceline-evil-normal :background blue)
+ (spaceline-evil-insert :background green)
+ (spaceline-evil-emacs :background cyan)
+ (spaceline-evil-replace :background orange)
+ (spaceline-evil-visual :background grey)
+ (spaceline-evil-motion :background magenta)
+ ;;;; spell-fu
+ (spell-fu-incorrect-face
+ `((((supports :underline (:style wave)))
+ (:underline (:style wave :color ,(car error))))
+ (t (:inherit error :underline t))))
+ ;;;; stripe-buffer
+ (stripe-highlight
+ (&light :background base5)
+ (&dark :background base3))
+ ;;;; swiper
+ (swiper-line-face :background blue :foreground base0)
+ (swiper-match-face-1 :inherit 'unspecified :background base0 :foreground base5)
+ (swiper-match-face-2 :inherit 'unspecified :background orange :foreground base0 :weight 'bold)
+ (swiper-match-face-3 :inherit 'unspecified :background magenta :foreground base0 :weight 'bold)
+ (swiper-match-face-4 :inherit 'unspecified :background green :foreground base0 :weight 'bold)
+ ;;;; tabbar
+ (tabbar-default :foreground bg :background bg :height 1.0)
+ (tabbar-highlight :foreground fg :background selection :distant-foreground bg)
+ (tabbar-button :foreground fg :background bg)
+ (tabbar-button-highlight :inherit 'tabbar-button :inverse-video t)
+ (tabbar-modified :inherit 'tabbar-default :foreground red :weight 'bold)
+ (tabbar-unselected :inherit 'tabbar-default :foreground base5)
+ (tabbar-unselected-modified :inherit 'tabbar-modified)
+ (tabbar-selected
+ :inherit 'tabbar-default :weight 'bold
+ :foreground fg :background bg-alt)
+ (tabbar-selected-modified :inherit 'tabbar-selected :foreground green)
+ ;;;; telephone-line
+ (telephone-line-accent-active :foreground fg :background base4)
+ (telephone-line-accent-inactive :foreground fg :background base2)
+ (telephone-line-projectile :foreground green)
+ (telephone-line-evil :foreground fg :weight 'bold)
+ (telephone-line-evil-insert :background (doom-blend green bg 0.5) :weight 'bold)
+ (telephone-line-evil-normal :background (doom-blend red bg 0.5) :weight 'bold)
+ (telephone-line-evil-visual :background (doom-blend orange bg 0.5) :weight 'bold)
+ (telephone-line-evil-replace :background (doom-color bg-alt) :weight 'bold)
+ (telephone-line-evil-motion :background (doom-blend blue bg 0.5) :weight 'bold)
+ (telephone-line-evil-operator :background (doom-blend violet bg 0.5) :weight 'bold)
+ (telephone-line-evil-emacs :background (doom-blend magenta bg 0.5) :weight 'bold)
+ ;;;; term <built-in>
+ (term :foreground fg)
+ (term-bold :weight 'bold)
+ (term-color-black :background base0 :foreground base0)
+ (term-color-red :background red :foreground red)
+ (term-color-green :background green :foreground green)
+ (term-color-yellow :background yellow :foreground yellow)
+ (term-color-blue :background blue :foreground blue)
+ (term-color-magenta :background magenta :foreground magenta)
+ (term-color-cyan :background cyan :foreground cyan)
+ (term-color-white :background base8 :foreground base8)
+ ;;;; terraform-mode
+ (terraform--resource-type-face :foreground type)
+ (terraform--resource-name-face :foreground strings)
+ ;;;; tldr
+ (tldr-command-itself :foreground bg :background green :weight 'semi-bold)
+ (tldr-title :foreground yellow :bold t :height 1.4)
+ (tldr-description :foreground fg :weight 'semi-bold)
+ (tldr-introduction :foreground (doom-blend blue bg 0.8) :weight 'semi-bold)
+ (tldr-code-block :foreground green :background region :weight 'semi-bold)
+ (tldr-command-argument :foreground fg :background region )
+ ;;;; typescript-mode <modes:typescript-mode,typescript-tsx-mode>
+ (typescript-jsdoc-tag :foreground doc-comments)
+ (typescript-jsdoc-type :foreground (doom-darken doc-comments 0.15))
+ (typescript-jsdoc-value :foreground (doom-lighten doc-comments 0.15))
+ ;;;; treemacs
+ (treemacs-directory-face :foreground fg)
+ (treemacs-file-face :foreground fg)
+ (treemacs-fringe-indicator-face :foreground highlight)
+ (treemacs-git-added-face :foreground vc-added)
+ (treemacs-git-conflict-face :foreground red)
+ (treemacs-git-modified-face :foreground violet)
+ (treemacs-git-untracked-face :inherit 'font-lock-doc-face)
+ (treemacs-on-failure-pulse-face :foreground base0 :background error :extend t)
+ (treemacs-on-success-pulse-face :foreground base0 :background success :extend t)
+ (treemacs-root-face :inherit 'font-lock-string-face :weight 'bold :height 1.2)
+ (treemacs-tags-face :foreground highlight)
+ ;;;; twittering-mode
+ (twitter-divider ; custom face in Doom Emacs
+ (&light :underline `(:color ,(doom-lighten vertical-bar 0.2)))
+ (&dark :underline `(:color ,(doom-darken vertical-bar 0.2))))
+ ;;;; undo-tree
+ (undo-tree-visualizer-default-face :foreground base5)
+ (undo-tree-visualizer-current-face :foreground green :weight 'bold)
+ (undo-tree-visualizer-unmodified-face :foreground base5)
+ (undo-tree-visualizer-active-branch-face :foreground blue)
+ (undo-tree-visualizer-register-face :foreground yellow)
+ ;;;; vimish-fold
+ (vimish-fold-overlay :inherit 'font-lock-comment-face :background base0 :weight 'light)
+ (vimish-fold-fringe :foreground magenta)
+ ;;;; visual-regexp
+ (vr/group-0 :background blue :foreground bg)
+ (vr/group-1 :background magenta :foreground bg)
+ (vr/group-2 :background green :foreground bg)
+ (vr/match-0 :background (doom-blend green bg 0.2) :foreground fg)
+ (vr/match-1 :background (doom-blend green bg 0.4) :foreground fg)
+ (vr/match-separator-face :inherit 'bold :foreground red)
+ ;;;; volatile-highlights
+ (vhl/default-face :background grey)
+ ;;;; vterm
+ (vterm :foreground fg)
+ (vterm-color-default :foreground fg)
+ (vterm-color-black :background (doom-lighten base0 0.25) :foreground base0)
+ (vterm-color-red :background (doom-lighten red 0.25) :foreground red)
+ (vterm-color-green :background (doom-lighten green 0.25) :foreground green)
+ (vterm-color-yellow :background (doom-lighten yellow 0.25) :foreground yellow)
+ (vterm-color-blue :background (doom-lighten blue 0.25) :foreground blue)
+ (vterm-color-magenta :background (doom-lighten magenta 0.25) :foreground magenta)
+ (vterm-color-cyan :background (doom-lighten cyan 0.25) :foreground cyan)
+ (vterm-color-white :background (doom-lighten base8 0.25) :foreground base8)
+ ;;;; web-mode <modes:web-mode>
+ (web-mode-block-control-face :foreground builtin)
+ (web-mode-block-delimiter-face :foreground builtin)
+ (web-mode-css-property-name-face :foreground type)
+ (web-mode-doctype-face :foreground comments)
+ (web-mode-html-tag-face :foreground methods)
+ (web-mode-html-tag-bracket-face :foreground methods)
+ (web-mode-html-attr-name-face :foreground type)
+ (web-mode-html-attr-value-face :foreground strings)
+ (web-mode-html-entity-face :foreground cyan :inherit 'italic)
+ (web-mode-block-control-face :foreground orange)
+ (web-mode-html-tag-bracket-face :foreground operators)
+ (web-mode-json-key-face :foreground strings)
+ (web-mode-json-context-face :foreground strings)
+ (web-mode-keyword-face :foreground keywords)
+ (web-mode-string-face :foreground strings)
+ (web-mode-type-face :foreground type)
+ ;;;; wgrep <built-in>
+ (wgrep-face :weight 'bold :foreground green :background base5)
+ (wgrep-delete-face :foreground base3 :background red)
+ (wgrep-done-face :foreground blue)
+ (wgrep-file-face :foreground comments)
+ (wgrep-reject-face :foreground red :weight 'bold)
+ ;;;; which-func
+ (which-func :foreground blue)
+ ;;;; which-key
+ (which-key-key-face :foreground green)
+ (which-key-group-description-face :foreground violet)
+ (which-key-command-description-face :foreground blue)
+ (which-key-local-map-description-face :foreground magenta)
+ ;;;; whitespace <built-in>
+ (whitespace-empty :background base3)
+ (whitespace-space :foreground base4)
+ (whitespace-newline :foreground base4)
+ (whitespace-tab
+ :foreground base4
+ :background (unless (default-value 'indent-tabs-mode) base3))
+ (whitespace-indentation
+ :foreground base4
+ :background (if (default-value 'indent-tabs-mode) base3))
+ (whitespace-trailing :inherit 'trailing-whitespace)
+ (whitespace-line :background base0 :foreground red :weight 'bold)
+ ;;;; widget
+ (widget-button-pressed :foreground red)
+ (widget-documentation :foreground green)
+ (widget-single-line-field :background base3 :distant-foreground bg)
+ (widget-field :background base3 :distant-foreground bg
+ :box `(:line-width -1 :color ,grey) :extend t)
+ ;;;; window-divider
+ (window-divider :inherit 'vertical-border)
+ (window-divider-first-pixel :inherit 'window-divider)
+ (window-divider-last-pixel :inherit 'window-divider)
+ ;;;; winum
+ (winum-face :inherit 'bold :foreground highlight)
+ ;;;; woman <built-in>
+ (woman-bold :inherit 'Man-overstrike)
+ (woman-italic :inherit 'Man-underline)
+ ;;;; xah-elisp-mode
+ (xah-elisp-at-symbol :inherit 'font-lock-warning-face)
+ (xah-elisp-cap-variable :inherit 'font-lock-preprocessor-face)
+ (xah-elisp-command-face :inherit 'font-lock-type-face)
+ (xah-elisp-dollar-symbol :inherit 'font-lock-variable-name-face)
+ ;;;; workgroups2
+ (wg-current-workgroup-face :foreground base0 :background highlight)
+ (wg-other-workgroup-face :foreground base5)
+ (wg-divider-face :foreground grey)
+ (wg-brace-face :foreground highlight)
+ ;;;; yasnippet
+ (yas-field-highlight-face :inherit 'match)
+ ;;;; xref <built-in>
+ ((xref-file-header &inherit compilation-info))
+ ((xref-line-number &inherit compilation-line-number))
+ ((xref-match &inherit match))
+ ;;;; --- END Package faces ------------------
+ )
+ "TODO")
+
+;;;; --- Package variables ------------------
+(defvar doom-themes-base-vars
+ '(
+ ;;;; ansi-color <built-in> DEPRECATED
+ (ansi-color-names-vector
+ (vconcat (mapcar #'doom-color '(bg red green yellow blue magenta cyan fg))))
+ ;;;; rustic <modes:rustic-mode>
+ (rustic-ansi-faces
+ (vconcat (mapcar #'doom-color '(bg red green yellow blue magenta cyan fg))))
+ ;;;; exwm
+ (exwm-floating-border-color (doom-color 'vertical-bar))
+ ;;;; fill-column-indicator
+ (fci-rule-color (doom-color 'base5))
+ ;;;; jdee <modes:jdee-mode>
+ (jdee-db-spec-breakpoint-face-colors `(cons ,(doom-color 'base0) ,(doom-color 'grey)))
+ (jdee-db-requested-breakpoint-face-colors `(cons ,(doom-color 'base0) ,(doom-color 'green)))
+ (jdee-db-active-breakpoint-face-colors `(cons ,(doom-color 'base0) ,(doom-color 'highlight)))
+ ;;;; highlight-tail
+ (highlight-tail-colors
+ `((,(doom-blend green bg 0.1) . 0)
+ (,(doom-blend cyan bg 0.1) . 20)))
+ ;;;; objed
+ (objed-cursor-color (doom-color 'red))
+ ;;;; pdf-tools
+ (pdf-view-midnight-colors `(cons ,(doom-color 'fg) ,(doom-color 'bg)))
+ ;;;; vc <built-in>
+ (vc-annotate-color-map
+ `(list (cons 20 ,(doom-color 'green))
+ (cons 40 ,(doom-blend 'yellow 'green (/ 1.0 3)))
+ (cons 60 ,(doom-blend 'yellow 'green (/ 2.0 3)))
+ (cons 80 ,(doom-color 'yellow))
+ (cons 100 ,(doom-blend 'orange 'yellow (/ 1.0 3)))
+ (cons 120 ,(doom-blend 'orange 'yellow (/ 2.0 3)))
+ (cons 140 ,(doom-color 'orange))
+ (cons 160 ,(doom-blend 'magenta 'orange (/ 1.0 3)))
+ (cons 180 ,(doom-blend 'magenta 'orange (/ 2.0 3)))
+ (cons 200 ,(doom-color 'magenta))
+ (cons 220 ,(doom-blend 'red 'magenta (/ 1.0 3)))
+ (cons 240 ,(doom-blend 'red 'magenta (/ 2.0 3)))
+ (cons 260 ,(doom-color 'red))
+ (cons 280 ,(doom-blend 'grey 'red (/ 1.0 4)))
+ (cons 300 ,(doom-blend 'grey 'red (/ 2.0 4)))
+ (cons 320 ,(doom-blend 'grey 'red (/ 3.0 4)))
+ (cons 340 ,(doom-color 'base5))
+ (cons 360 ,(doom-color 'base5))))
+ (vc-annotate-very-old-color nil)
+ (vc-annotate-background (doom-color 'bg)))
+;;;; --- END Package variables --------------
+ "TODO")
+
+(provide 'doom-themes-base)
+;;; doom-themes-base.el ends here
diff --git a/elpa/doom-themes-20220504.1557/doom-themes-base.elc b/elpa/doom-themes-20220504.1557/doom-themes-base.elc
new file mode 100644
index 0000000..6f8ad43
--- /dev/null
+++ b/elpa/doom-themes-20220504.1557/doom-themes-base.elc
Binary files differ
diff --git a/elpa/doom-themes-20220504.1557/doom-themes-ext-neotree.el b/elpa/doom-themes-20220504.1557/doom-themes-ext-neotree.el
new file mode 100644
index 0000000..7dd3674
--- /dev/null
+++ b/elpa/doom-themes-20220504.1557/doom-themes-ext-neotree.el
@@ -0,0 +1,384 @@
+;;; doom-themes-ext-neotree.el --- ... -*- lexical-binding: t; no-byte-compile: t -*-
+;;
+;; Copyright (C) 2016-2022 Henrik Lissner
+;;
+;; Author: Henrik Lissner <contact@henrik.io>
+;; Maintainer: Henrik Lissner <contact@henrik.io>
+;; Created: September 10, 2016
+;;
+;; This file is not part of GNU Emacs.
+;;
+;;; Commentary:
+;;; Code:
+
+(defgroup doom-themes-neotree nil
+ "Options for doom's neotree theme"
+ :group 'doom-themes)
+
+
+;;
+;;; Variables
+
+(defcustom doom-themes-neotree-project-size 1.4
+ "What :height to display the project icon at the top at."
+ :type 'float
+ :group 'doom-themes-neotree)
+
+(defcustom doom-themes-neotree-folder-size 1.05
+ "What :height to display the folder icons at."
+ :type 'float
+ :group 'doom-themes-neotree)
+
+(defcustom doom-themes-neotree-chevron-size 0.8
+ "What :height to display the chevron icons at."
+ :type 'float
+ :group 'doom-themes-neotree)
+
+(defcustom doom-themes-neotree-line-spacing 2
+ "Line-spacing for neotree buffer."
+ :type 'symbol
+ :group 'doom-themes-neotree)
+
+(defcustom doom-themes-neotree-file-icons 'simple
+ "The style to use for the file icons. Can be nil (disabled), non-nil (for a
+diverse iconset), or 'simple, which is closest's to Atom's style as it only
+distinguishes text, source, pdfs, images and binary files."
+ :type '(choice
+ (const :tag "A diverse array of file icons based on file type" t)
+ (const :tag "Minimalistic file icons (like Atom's)" 'simple)
+ (const :tag "Disable file icons" nil))
+ :group 'doom-themes-neotree)
+
+(defcustom doom-themes-neotree-enable-folder-icons t
+ "If non-nil, display folder icons next to each file. Different icons are used
+depending on whether the folder is a repo, symlink or regular folder."
+ :type 'boolean
+ :group 'doom-themes-neotree)
+
+(defcustom doom-themes-neotree-enable-open-chevron-icons t
+ "If non-nil, display the chevron-down icon next to each expanded folder."
+ :type 'boolean
+ :group 'doom-themes-neotree)
+
+(defcustom doom-themes-neotree-enable-closed-chevron-icons t
+ "If non-nil, display the chevron-right icon next to each collapsed folder."
+ :type 'boolean
+ :group 'doom-themes-neotree)
+
+(defcustom doom-themes-neotree-enable-variable-pitch nil
+ "If non-nil, labels will use the `doom-themes-neotree-dir-face' and
+`doom-themes-neotree-dir-face' faces, which inherit from the `variable-pitch' face."
+ :type 'boolean
+ :group 'doom-themes-neotree)
+
+(defcustom doom-themes-neotree-enable-type-colors t
+ "If non-nil, color each file/folder based on the categories determined by
+`doom-themes-neotree-file-face-re-alist'."
+ :type 'boolean
+ :group 'doom-themes-neotree)
+
+
+(defun doom-themes--neo-is-repo-dir-p (path)
+ (or (file-exists-p (format "%s/.git" path))
+ (all-the-icons-dir-is-submodule path)))
+
+(defvar doom-themes-neotree-dir-rules
+ (eval-when-compile
+ `(("/\\(?:node_modules\\|vendor\\)$"
+ :face doom-themes-neotree-hidden-file-face)
+ ("/\\.[^$/#]+$"
+ :face doom-themes-neotree-hidden-file-face)
+ (file-symlink-p
+ :icon (all-the-icons-octicon "file-symlink-directory"))
+ (doom-themes--neo-is-repo-dir-p
+ :icon (all-the-icons-octicon "file-submodule"))
+ (t :icon (all-the-icons-octicon "file-directory"))))
+ "TODO")
+
+(defvar doom-themes-neotree-file-rules
+ (eval-when-compile
+ `((file-symlink-p
+ :icon (all-the-icons-octicon "file-symlink-file"))
+ (file-executable-p
+ :face doom-themes-neotree-executable-file-face
+ :icon (all-the-icons-octicon "file-binary"))
+ ("\\.\\(?:md\\|org\\|rst\\|log\\)\\|/[A-Z_-]+\\(?:\\.[a-z]+\\)?$"
+ :face doom-themes-neotree-text-file-face
+ :icon (all-the-icons-octicon "file-text"))
+ (,(concat "\\." (regexp-opt '("htm" "html" "phtml" "tpl" "erb" "mustache"
+ "twig" "ejs" "erb" "jsx" "haml" "inky-haml"
+ "inky-slim" "slim" "pug" "jade"))
+ "$")
+ :icon (all-the-icons-octicon "file-code"))
+ (,(concat "\\(?:/\\(?:Gemfile\\|Vagrantfile\\|Makefile\\|Rakefile\\|Cask\\|\\.[^$]+rc\\|\\)\\|"
+ "\\." (regexp-opt '("json" "cson" "yaml" "yml" "xml" "toml"
+ "tpl" "ini" "erb" "mustache" "twig" "ejs"
+ "mk" "haml" "pug" "jade"))
+ "\\)$")
+ :icon (all-the-icons-octicon "file-code"))
+ (,(concat "\\."
+ (regexp-opt '("png" "jpg" "jpeg" "gif" "ico" "tif" "tiff"
+ "svg" "bmp" "psd" "ai" "eps" "indd" ; images
+ "mov" "avi" "mp4" "webm" "mkv" ; video
+ "wav" "mp3" "ogg" "midi")) ; audio
+ "$")
+ :face doom-themes-neotree-data-file-face
+ :icon (all-the-icons-octicon "file-media"))
+ (,(concat "\\.\\(?:[gl]?zip\\|bzip2\\|deb\\|dmg\\|iso\\|7z\\|rpm\\|pkg\\|dat\\|[rjt]ar\\(?:\\.gz\\)?\\)$")
+ :face doom-themes-neotree-data-file-face
+ :icon (all-the-icons-octicon "file-zip"))
+ ("\\.pdf$"
+ :face doom-themes-neotree-data-file-face
+ :icon (all-the-icons-octicon "file-pdf"))
+ ("\\.\\(?:lock\\|resolved\\|dll\\|so\\|pyc\\|elc\\|class\\|css\\.map\\)$"
+ :face doom-themes-neotree-hidden-file-face
+ :icon (all-the-icons-octicon "file-binary"))
+ ("/\\.[^$/#]+$"
+ :face doom-themes-neotree-hidden-file-face)
+ (t :icon (all-the-icons-octicon "file-text"))))
+ "TODO")
+
+
+;;
+;;; Faces
+
+(defface doom-themes-neotree-dir-face '((t (:inherit neo-dir-link-face)))
+ "Face for directory labels."
+ :group 'doom-themes-neotree)
+
+(defface doom-themes-neotree-file-face '((t (:inherit neo-file-link-face)))
+ "Face for file name labels."
+ :group 'doom-themes-neotree)
+
+;; file type faces
+(defface doom-themes-neotree-hidden-file-face '((t (:inherit font-lock-comment-face)))
+ "Face for labels of hidden files. See `doom-themes-neotree-file-face-re-alist'."
+ :group 'doom-themes-neotree)
+
+(defface doom-themes-neotree-text-file-face '((t (:inherit neo-file-link-face)))
+ "Face for labels of text/documentation files (readmes, org files, etc). See
+`doom-themes-neotree-file-face-re-alist'."
+ :group 'doom-themes-neotree)
+
+(defface doom-themes-neotree-media-file-face '((t (:inherit neo-file-link-face)))
+ "Face for labels of media files. See `doom-themes-neotree-file-face-re-alist'."
+ :group 'doom-themes-neotree)
+
+(defface doom-themes-neotree-data-file-face '((t (:inherit neo-file-link-face)))
+ "Face for labels of data files (json, yaml, xml, etc). See
+`doom-themes-neotree-file-face-re-alist'."
+ :group 'doom-themes-neotree)
+
+(defface doom-themes-neotree-executable-file-face '((t (:inherit neo-file-link-face)))
+ "TODO"
+ :group 'doom-themes-neotree)
+
+
+;;
+;;; Helpers
+
+(defun doom-themes--neotree-no-fringes ()
+ "Remove fringes in neotree.
+They are reset each time you select the neotree pane and highlighted
+incorrectly, so remove them."
+ (set-window-fringes neo-global--window 0 0))
+
+(defun doom-themes--neotree-setup (&rest _)
+ (setq line-spacing doom-themes-neotree-line-spacing
+ tab-width 1)
+ (when (featurep 'hl-line)
+ (set (make-local-variable 'hl-line-sticky-flag) t)
+ (hl-line-mode +1)))
+
+(defun doom-themes-neotree-spec (node rules)
+ (let (case-fold-search)
+ (cl-loop for spec in rules
+ for pred = (car spec)
+ for plist = (cdr spec)
+ when
+ (cond ((eq pred 't))
+ ((symbolp pred) (funcall pred node))
+ ((stringp pred) (string-match-p pred node)))
+ return plist)))
+
+(defun doom--neotree-insert-file-icon (node icon &optional faces)
+ (if node
+ (cond ((eq doom-themes-neotree-file-icons 'simple)
+ (propertize
+ (if icon
+ (apply (car icon) (cdr icon))
+ (all-the-icons-octicon "file-text"))
+ 'face `(:inherit ,faces
+ :family ,(all-the-icons-octicon-family)
+ :height 1.3)
+ 'display '(raise 0)))
+ (t (all-the-icons-icon-for-file node)))
+ (all-the-icons-fileicon "default")))
+
+(defun doom--neotree-insert-dir-icon (node type &optional faces)
+ (concat (if type
+ (all-the-icons-octicon
+ (format "chevron-%s" (if (eq type 'open) "down" "right"))
+ :v-adjust 0.1
+ :height doom-themes-neotree-chevron-size
+ :face `(:inherit ,faces
+ :family ,(all-the-icons-octicon-family)
+ :height ,doom-themes-neotree-chevron-size))
+ "\t")
+ "\t"
+ (when doom-themes-neotree-enable-folder-icons
+ (all-the-icons-octicon
+ (cond ((file-symlink-p node) "file-symlink-directory")
+ ((file-exists-p (format "%s/.git" node)) "file-submodule")
+ ((all-the-icons-dir-is-submodule node) "file-submodule")
+ ("file-directory"))
+ :v-adjust 0
+ :height doom-themes-neotree-folder-size
+ :face `(:inherit ,faces
+ :family ,(all-the-icons-octicon-family)
+ :height ,doom-themes-neotree-folder-size)))))
+
+(defun doom--neotree-insert-icon (type node &optional icon faces)
+ "Custom hybrid unicode theme with leading whitespace."
+ (let ((spc "\t")
+ (vspc (propertize " " 'face 'variable-pitch)))
+ (cond ((eq type 'open)
+ (insert
+ (concat spc
+ (doom--neotree-insert-dir-icon
+ node (if doom-themes-neotree-enable-open-chevron-icons type)
+ faces)
+ vspc)))
+ ((eq type 'close)
+ (insert
+ (concat spc
+ (doom--neotree-insert-dir-icon
+ node (if doom-themes-neotree-enable-closed-chevron-icons type)
+ faces)
+ vspc)))
+ ((eq type 'leaf)
+ (insert
+ (concat (when (or doom-themes-neotree-enable-open-chevron-icons
+ doom-themes-neotree-enable-closed-chevron-icons)
+ spc)
+ (when doom-themes-neotree-enable-folder-icons spc)
+ (when doom-themes-neotree-file-icons
+ (concat spc (doom--neotree-insert-file-icon node icon faces)))
+ vspc))))))
+
+
+;;
+;;; Public library
+
+(defun doom-themes-neotree-insert-root (node)
+ ;; insert icon
+ (when (display-graphic-p)
+ (insert
+ (concat (propertize "\t" 'face 'neo-root-dir-face)
+ (all-the-icons-octicon
+ "repo"
+ :height doom-themes-neotree-project-size
+ :face 'neo-root-dir-face
+ :v-adjust -0.1)
+ (propertize " " 'face 'neo-root-dir-face))))
+ ;; insert project name
+ (insert
+ (propertize
+ (concat (or (neo-path--file-short-name node) "-")
+ "\n")
+ 'face `(:inherit ,(append (if doom-themes-neotree-enable-variable-pitch '(variable-pitch))
+ '(neo-root-dir-face))))))
+
+(defun doom-themes-neotree-insert-dir (node depth expanded)
+ (let ((short-name (neo-path--file-short-name node))
+ (faces '(doom-themes-neotree-dir-face))
+ icon-text)
+ ;; insert indentation
+ (insert-char ?\s (* (- depth 1) 2))
+ ;; vcs integration
+ (let ((vc (if neo-vc-integration (neo-vc-for-node node))))
+ (when (memq 'char neo-vc-integration)
+ (insert-char (car vc))
+ (insert-char ?\s))
+ (unless (and (memq 'face neo-vc-integration)
+ (not (eq (cdr vc) 'neo-vc-up-to-date-face))
+ (setq faces (list (cdr vc))))
+ (cl-destructuring-bind (&key face icon)
+ (doom-themes-neotree-spec node doom-themes-neotree-dir-rules)
+ (if face (push face faces))
+ (if icon (setq icon-text icon)))))
+ ;; insert icon
+ (let ((type (if expanded 'open 'close)))
+ (if (display-graphic-p)
+ (doom--neotree-insert-icon type node icon-text faces)
+ (neo-buffer--insert-fold-symbol type node)))
+ ;; insert label button
+ (when doom-themes-neotree-enable-variable-pitch
+ (push 'variable-pitch faces))
+ (insert-button short-name
+ 'follow-link t
+ 'face `(:inherit (,@faces))
+ 'neo-full-path node
+ 'keymap neotree-dir-button-keymap)
+ ;; metadata + newline
+ (neo-buffer--node-list-set nil node)
+ (neo-buffer--newline-and-begin)))
+
+(defun doom-themes-neotree-insert-file (node depth)
+ (let ((short-name (neo-path--file-short-name node))
+ (vc (if neo-vc-integration (neo-vc-for-node node)))
+ (faces '(doom-themes-neotree-file-face))
+ icon-text)
+ ;; insert indentation
+ (insert-char ?\s (* (- depth 1) 2))
+ ;; vcs integration
+ (unless (and (memq 'face neo-vc-integration)
+ (not (eq (cdr vc) 'neo-vc-up-to-date-face))
+ (setq faces (list (cdr vc))))
+ (cl-destructuring-bind (&key face icon)
+ (doom-themes-neotree-spec node doom-themes-neotree-file-rules)
+ (if face (push face faces))
+ (if icon (setq icon-text icon))))
+ ;; insert icon
+ (if (display-graphic-p)
+ (doom--neotree-insert-icon 'leaf node icon-text faces)
+ (neo-buffer--insert-fold-symbol 'leaf node))
+ ;; insert label button
+ (when doom-themes-neotree-enable-variable-pitch
+ (push 'variable-pitch faces))
+ (insert-button short-name
+ 'follow-link t
+ 'face `(:inherit (,@faces))
+ 'neo-full-path node
+ 'keymap neotree-file-button-keymap)
+ ;; metadata + newline
+ (neo-buffer--node-list-set nil node)
+ (neo-buffer--newline-and-begin)))
+
+
+;;; Bootstrap
+
+(with-eval-after-load 'neotree
+ (unless (require 'all-the-icons nil t)
+ (error "all-the-icons isn't installed"))
+
+ ;; Incompatible with this theme
+ (setq neo-vc-integration nil)
+ ;; Enable buffer-local hl-line and adjust line-spacing
+ (add-hook 'neo-after-create-hook #'doom-themes--neotree-setup)
+ ;; Remove fringes in Neotree pane
+ (advice-add #'neo-global--select-window :after #'doom-themes--neotree-no-fringes)
+ ;; Patch neotree to use `doom--neotree-insert-icon'
+ (advice-add #'neo-buffer--insert-file-entry :override #'doom-themes-neotree-insert-file)
+ (advice-add #'neo-buffer--insert-dir-entry :override #'doom-themes-neotree-insert-dir)
+ ;; Shorter pwd in neotree override
+ (advice-add #'neo-buffer--insert-root-entry :override #'doom-themes-neotree-insert-root))
+
+;;;###autoload
+(defun doom-themes-neotree-config ()
+ "Install doom-themes' neotree configuration.
+
+Includes an Atom-esque icon theme and highlighting based on filetype.")
+
+(provide 'doom-themes-ext-neotree)
+;;; doom-themes-neotree.el ends here
diff --git a/elpa/doom-themes-20220504.1557/doom-themes-ext-org.el b/elpa/doom-themes-20220504.1557/doom-themes-ext-org.el
new file mode 100644
index 0000000..775410d
--- /dev/null
+++ b/elpa/doom-themes-20220504.1557/doom-themes-ext-org.el
@@ -0,0 +1,138 @@
+;;; doom-themes-ext-org.el --- fix fontification issues in org-mode -*- lexical-binding: t; -*-
+;;
+;; Copyright (C) 2017-2022 Henrik Lissner
+;;
+;; Author: Henrik Lissner <contact@henrik.io>
+;; Maintainer: Henrik Lissner <contact@henrik.io>
+;; Created: August 3, 2017
+;;
+;; This file is not part of GNU Emacs.
+;;
+;;; Commentary:
+;;
+;; Fixes a few fontification issues in org-mode and adds special fontification
+;; for @-tags and #hashtags. Simply load this file to use it.
+;;
+;; (with-eval-after-load 'org-mode
+;; (require 'doom-themes-ext-org))
+;;
+;; Or call `doom-themes-enable-org-config', which does nothing but load this
+;; package (because it's autoloaded).
+;;
+;; (with-eval-after-load 'org-mode
+;; (doom-themes-enable-org-config))
+;;
+;;; Code:
+
+(defgroup doom-themes-org nil
+ "Options for doom's org customizations."
+ :group 'doom-themes)
+
+(define-obsolete-variable-alias
+ 'doom-org-special-tags 'doom-themes-org-fontify-special-tags
+ "2021-02-10")
+(defcustom doom-themes-org-fontify-special-tags t
+ "If non-nil, fontify #hashtags and @attags.
+Uses `doom-themes-org-at-tag' and `doom-themes-org-hash-tag' faces."
+ :type 'boolean
+ :group 'doom-themes-org)
+
+(defcustom doom-themes-org-fontify-exclude-types
+ '(src-block
+ link
+ citation-reference)
+ "A list of org elements not to highlight special tags in.
+See `doom-themes-org-fontify-special-tags'."
+ :type '(repeat symbol)
+ :group 'doom-themes-org)
+
+(defface doom-themes-org-at-tag '((t :inherit org-formula))
+ "Face used to fontify @-tags in org-mode."
+ :group 'doom-themes-org)
+
+(defface doom-themes-org-hash-tag '((t :inherit org-tag))
+ "Face used to fontify #hashtags in org-mode."
+ :group 'doom-themes-org)
+
+
+(defvar org-done-keywords)
+(defvar org-font-lock-extra-keywords)
+(defvar org-heading-keyword-regexp-format)
+(defvar org-todo-regexp)
+(defvar org-fontify-done-headline)
+(defvar org-activate-links)
+(declare-function org-delete-all "ext:org-macs" (elts list))
+(declare-function org-element-type "ext:org-element" (element))
+(declare-function org-element-context "ext:org-element" (&optional element))
+
+;;
+(defun doom-themes--org-tag-face (n)
+ "Return the face to use for the currently matched tag.
+N is the match index."
+ (declare (pure t) (side-effect-free t))
+ (let ((context (save-match-data (org-element-context))))
+ (unless (memq (org-element-type context) doom-themes-org-fontify-exclude-types)
+ (pcase (match-string n)
+ ("#" 'doom-themes-org-hash-tag)
+ ("@" 'doom-themes-org-at-tag)))))
+
+(defun doom-themes-enable-org-fontification ()
+ "Correct (and improve) org-mode's font-lock keywords.
+
+ 1. Re-set `org-todo' & `org-headline-done' faces, to make them respect
+ (inherit) underlying faces.
+ 2. Make statistic cookies respect (inherit) underlying faces.
+ 3. Fontify item bullets (make them stand out)
+ 4. Fontify item checkboxes (and when they're marked done), like TODOs that are
+ marked done.
+ 5. Fontify dividers/separators (5+ dashes)
+ 6. Fontify #hashtags and @at-tags, for personal convenience; see
+ `doom-org-special-tags' to disable this."
+ (let ((org-todo (format org-heading-keyword-regexp-format
+ org-todo-regexp))
+ (org-done (format org-heading-keyword-regexp-format
+ (concat "\\(?:" (mapconcat #'regexp-quote org-done-keywords
+ "\\|")
+ "\\)"))))
+ (setq
+ org-font-lock-extra-keywords
+ (append (org-delete-all
+ (append `(("\\[\\([0-9]*%\\)\\]\\|\\[\\([0-9]*\\)/\\([0-9]*\\)\\]"
+ (0 (org-get-checkbox-statistics-face) t))
+ (,org-todo (2 (org-get-todo-face 2) t)))
+ (when org-fontify-done-headline
+ `((,org-done (2 'org-headline-done t))))
+ (when (memq 'date org-activate-links)
+ '((org-activate-dates (0 'org-date t)))))
+ org-font-lock-extra-keywords)
+ ;; respsect underlying faces!
+ `((,org-todo (2 (org-get-todo-face 2) prepend)))
+ (when org-fontify-done-headline
+ `((,org-done (2 'org-headline-done prepend))))
+ (when (memq 'date org-activate-links)
+ '((org-activate-dates (0 'org-date prepend))))
+ ;; Make checkbox statistic cookies respect underlying faces
+ '(("\\[\\([0-9]*%\\)\\]\\|\\[\\([0-9]*\\)/\\([0-9]*\\)\\]"
+ (0 (org-get-checkbox-statistics-face) prepend))
+ ;; make plain list bullets stand out
+ ("^ *\\([-+]\\|\\(?:[0-9]+\\|[a-zA-Z]\\)[).]\\)[ \t]" 1 'org-list-dt append)
+ ;; and separators/dividers
+ ("^ *\\(-----+\\)$" 1 'org-meta-line))
+ ;; I like how org-mode fontifies checked TODOs and want this to
+ ;; extend to checked checkbox items:
+ (when org-fontify-done-headline
+ '(("^[ \t]*\\(?:[-+*]\\|[0-9]+[).]\\)[ \t]+\\(\\(?:\\[@\\(?:start:\\)?[0-9]+\\][ \t]*\\)?\\[\\(?:X\\|\\([0-9]+\\)/\\2\\)\\][^\n]*\n\\)"
+ 1 'org-headline-done prepend)))
+ ;; custom #hashtags & @at-tags for another level of organization
+ (when doom-themes-org-fontify-special-tags
+ '(("\\(?:\\s-\\|^\\)\\(\\([#@]\\)[A-Za-z0-9_.-]+\\)"
+ 1 (doom-themes--org-tag-face 2) prepend)))))))
+
+(add-hook 'org-font-lock-set-keywords-hook #'doom-themes-enable-org-fontification)
+
+;;;###autoload
+(defun doom-themes-org-config ()
+ "Load `doom-themes-ext-org'.")
+
+(provide 'doom-themes-ext-org)
+;;; doom-themes-ext-org.el ends here
diff --git a/elpa/doom-themes-20220504.1557/doom-themes-ext-org.elc b/elpa/doom-themes-20220504.1557/doom-themes-ext-org.elc
new file mode 100644
index 0000000..fd318cc
--- /dev/null
+++ b/elpa/doom-themes-20220504.1557/doom-themes-ext-org.elc
Binary files differ
diff --git a/elpa/doom-themes-20220504.1557/doom-themes-ext-treemacs.el b/elpa/doom-themes-20220504.1557/doom-themes-ext-treemacs.el
new file mode 100644
index 0000000..e969e80
--- /dev/null
+++ b/elpa/doom-themes-20220504.1557/doom-themes-ext-treemacs.el
@@ -0,0 +1,313 @@
+;;; doom-themes-ext-treemacs.el --- ... -*- lexical-binding: t; no-byte-compile: t -*-
+;;
+;; Copyright (C) 2018-2022 Henrik Lissner
+;;
+;; Author: Henrik Lissner <contact@henrik.io>
+;; Maintainer: Henrik Lissner <contact@henrik.io>
+;; Created: July 10, 2018
+;;
+;; This file is not part of GNU Emacs.
+;;
+;;; Commentary:
+;;; Code:
+
+(defgroup doom-themes-treemacs nil
+ "Options for doom's treemacs theme."
+ :group 'doom-themes)
+
+
+;;
+;;; Variables
+
+(defcustom doom-themes-treemacs-enable-variable-pitch t
+ "If non-nil, remap file, folder & project labels to `variable-pitch'.
+
+See `doom-themes-treemacs-variable-pitch-face'."
+ :type 'boolean
+ :group 'doom-themes-treemacs)
+
+(defcustom doom-themes-treemacs-line-spacing 1
+ "Line-spacing for treemacs buffer."
+ :type 'integer
+ :group 'doom-themes-treemacs)
+
+(defcustom doom-themes-treemacs-theme "doom-atom"
+ "Default treemacs theme."
+ :type '(radio (const :doc "A minimalistic atom-inspired icon theme" "doom-atom")
+ (const :doc "A colorful icon theme leveraging all-the-icons" "doom-colors"))
+ :group 'doom-themes-treemacs)
+
+(defcustom doom-themes-treemacs-bitmap-indicator-width 3
+ "Default treemacs bitmap indicators width."
+ :type 'integer
+ :group 'doom-themes-treemacs)
+
+(defcustom doom-themes-treemacs-variable-pitch-face 'variable-pitch
+ "The face to remap file/directory labels to.
+
+Only takes effect if `doom-themes-treemacs-enable-variable-pitch' is non-nil."
+ :type 'face
+ :group 'doom-themes-treemacs)
+
+
+;;
+;;; Faces
+(defface doom-themes-treemacs-root-face
+ '((t (:inherit font-lock-string-face)))
+ "Face used for the root icon in doom themes' treemacs theme."
+ :group 'doom-themes-treemacs)
+
+(defface doom-themes-treemacs-file-face
+ '((t (:inherit font-lock-doc-face :slant normal)))
+ "Face used for the directory and file icons in doom themes' treemacs theme."
+ :group 'doom-themes-treemacs)
+
+;;
+;;; Library
+
+(defun doom-themes-hide-fringes-maybe (&rest _)
+ "Remove fringes in current window if `treemacs-fringe-indicator-mode' is nil"
+ (when (display-graphic-p)
+ (if treemacs-fringe-indicator-mode
+ (set-window-fringes nil doom-themes-treemacs-bitmap-indicator-width 0)
+ (set-window-fringes nil 0 0))))
+
+(defun doom-themes-setup-tab-width (&rest _)
+ "Set `tab-width' to 1, so tab characters don't ruin formatting."
+ (setq tab-width 1))
+
+(defun doom-themes-define-treemacs-fringe-indicator-bitmap ()
+ "Defines `treemacs--fringe-indicator-bitmap'"
+ (if (fboundp 'define-fringe-bitmap)
+ (define-fringe-bitmap 'treemacs--fringe-indicator-bitmap
+ (make-vector 26 #b111) nil doom-themes-treemacs-bitmap-indicator-width)))
+
+(defun doom-themes-setup-line-spacing ()
+ "Set `line-spacing' in treemacs buffers."
+ (setq line-spacing doom-themes-treemacs-line-spacing))
+
+(defun doom-themes-hide-modeline ()
+ (setq mode-line-format nil))
+
+(defun doom-themes-enable-treemacs-variable-pitch-labels (&rest _)
+ (when doom-themes-treemacs-enable-variable-pitch
+ (dolist (face '(treemacs-root-face
+ treemacs-git-unmodified-face
+ treemacs-git-modified-face
+ treemacs-git-renamed-face
+ treemacs-git-ignored-face
+ treemacs-git-untracked-face
+ treemacs-git-added-face
+ treemacs-git-conflict-face
+ treemacs-directory-face
+ treemacs-directory-collapsed-face
+ treemacs-file-face
+ treemacs-tags-face))
+ (let ((faces (face-attribute face :inherit nil)))
+ (set-face-attribute
+ face nil :inherit
+ `(,doom-themes-treemacs-variable-pitch-face
+ ,@(delq 'unspecified (if (listp faces) faces (list faces)))))))))
+
+(defun doom-themes-fix-treemacs-icons-dired-mode ()
+ "Set `tab-width' to 1 in dired-mode if `treemacs-icons-dired-mode' is active."
+ (funcall (if treemacs-icons-dired-mode #'add-hook #'remove-hook)
+ 'dired-mode-hook
+ #'doom-themes-setup-tab-width))
+
+;;
+;;; Bootstrap
+
+(with-eval-after-load 'treemacs
+ (unless (require 'all-the-icons nil t)
+ (error "all-the-icons isn't installed"))
+
+ (add-hook 'treemacs-mode-hook #'doom-themes-setup-tab-width)
+ (add-hook 'treemacs-mode-hook #'doom-themes-setup-line-spacing)
+ (add-hook 'treemacs-mode-hook #'doom-themes-define-treemacs-fringe-indicator-bitmap)
+
+ ;; Fix #293: tabs messing up formatting in `treemacs-icons-dired-mode'
+ (add-hook 'treemacs-icons-dired-mode-hook #'doom-themes-fix-treemacs-icons-dired-mode)
+
+ ;; The modeline isn't useful in treemacs
+ (add-hook 'treemacs-mode-hook #'doom-themes-hide-modeline)
+
+ ;; Disable fringes (and reset them everytime treemacs is selected because it
+ ;; may change due to outside factors)
+ (add-hook 'treemacs-mode-hook #'doom-themes-hide-fringes-maybe)
+ (advice-add #'treemacs-select-window :after #'doom-themes-hide-fringes-maybe)
+
+ ;; variable-pitch labels for files/folders
+ (doom-themes-enable-treemacs-variable-pitch-labels)
+ (advice-add #'load-theme :after #'doom-themes-enable-treemacs-variable-pitch-labels)
+
+ ;; minimalistic atom-inspired icon theme
+ (let ((face-spec 'doom-themes-treemacs-file-face))
+ (treemacs-create-theme "doom-atom"
+ :config
+ (progn
+ (treemacs-create-icon
+ :icon (format " %s\t" (all-the-icons-octicon "repo" :height 1.2 :v-adjust -0.1 :face 'doom-themes-treemacs-root-face))
+ :extensions (root-open))
+ (treemacs-create-icon
+ :icon (format " %s\t" (all-the-icons-octicon "repo" :height 1.2 :v-adjust -0.1 :face 'doom-themes-treemacs-root-face))
+ :extensions (root-closed))
+ (treemacs-create-icon
+ :icon (format "%s\t%s\t"
+ (all-the-icons-octicon "chevron-down" :height 0.75 :v-adjust 0.1 :face face-spec)
+ (all-the-icons-octicon "file-directory" :v-adjust 0 :face face-spec))
+ :extensions (dir-open))
+ (treemacs-create-icon
+ :icon (format "%s\t%s\t"
+ (all-the-icons-octicon "chevron-right" :height 0.75 :v-adjust 0.1 :face face-spec)
+ (all-the-icons-octicon "file-directory" :v-adjust 0 :face face-spec))
+ :extensions (dir-closed))
+ (treemacs-create-icon
+ :icon (format "%s\t%s\t"
+ (all-the-icons-octicon "chevron-down" :height 0.75 :v-adjust 0.1 :face face-spec)
+ (all-the-icons-octicon "package" :v-adjust 0 :face face-spec)) :extensions (tag-open))
+ (treemacs-create-icon
+ :icon (format "%s\t%s\t"
+ (all-the-icons-octicon "chevron-right" :height 0.75 :v-adjust 0.1 :face face-spec)
+ (all-the-icons-octicon "package" :v-adjust 0 :face face-spec))
+ :extensions (tag-closed))
+ (treemacs-create-icon
+ :icon (format "%s\t" (all-the-icons-octicon "tag" :height 0.9 :v-adjust 0 :face face-spec))
+ :extensions (tag-leaf))
+ (treemacs-create-icon
+ :icon (format "%s\t" (all-the-icons-octicon "flame" :v-adjust 0 :face face-spec))
+ :extensions (error))
+ (treemacs-create-icon
+ :icon (format "%s\t" (all-the-icons-octicon "stop" :v-adjust 0 :face face-spec))
+ :extensions (warning))
+ (treemacs-create-icon
+ :icon (format "%s\t" (all-the-icons-octicon "info" :height 0.75 :v-adjust 0.1 :face face-spec))
+ :extensions (info))
+ (treemacs-create-icon
+ :icon (format " %s\t" (all-the-icons-octicon "file-media" :v-adjust 0 :face face-spec))
+ :extensions ("ai" "aiff" "avi" "bmp" "eps" "flac" "gif" "ico" "indd"
+ "jpeg" "jpg" "midi" "mkv" "mov" "mp3" "mp4" "ogg" "png"
+ "psd" "svg" "tif" "tiff" "wav" "webm" "webp"))
+ (treemacs-create-icon
+ :icon (format " %s\t" (all-the-icons-octicon "file-code" :v-adjust 0 :face face-spec))
+ :extensions ("accdb" "accdt" "actionscript" "adoc" "adoc" "ansible"
+ "antlr" "applescript" "asciidoc" "asm" "c" "cask" "cc"
+ "cc" "clj" "cljc" "cljs" "cmake" "coffee" "cpp" "css"
+ "cxx" "cython" "d" "dart" "diet" "diff" "dml"
+ "docker-compose.yml" "dockerfile" "dscript" "edn" "eex"
+ "el" "elm" "ex" "exs" "fennel" "fish" "fortran"
+ "fortran-modern" "fortranfreeform" "fsharp" "gdscript"
+ "go" "gradle" "graphql" "h" "hh" "hpp" "hs" "htm" "html"
+ "hy" "iced" "inc" "ino" "j2" "j2" "java" "jinja" "jinja2"
+ "jl" "js" "jsx" "kt" "kts" "ledger" "less" "lhs" "lisp"
+ "lua" "makefile" "matlab" "merlin" "mips" "ml" "mli"
+ "moonscript" "nim" "nims" "nix" "objectpascal" "ocaml"
+ "pascal" "patch" "pde" "perl" "pgsql" "php" "php4" "php5"
+ "phps" "pl" "plt" "pm" "pm6" "pony" "pp" "pp" "pro"
+ "prolog" "ps1" "purs" "py" "pyc" "r" "racket" "rb" "rd"
+ "rdx" "re" "rei" "rkt" "rktd" "rktl" "rs" "rsx" "sass"
+ "sbt" "scala" "scm" "scpt" "scrbl" "scribble" "scss" "sh"
+ "sql" "styles" "sv" "tex" "tpp" "ts" "tsx" "v"
+ "vagrantfile" "vh" "vhd" "vhdl" "vhms" "vim" "vue" "xsl"
+ "zsh" "zshrc"))
+ (treemacs-create-icon
+ :icon (format " %s\t" (all-the-icons-octicon "book" :v-adjust 0 :face face-spec))
+ :extensions ("azw" "azw3" "cb7" "cba" "cbr" "cbt" "cbz" "ceb" "chm"
+ "djvu" "doc" "docx" "exe" "fb2" "inf" "kf8" "kfx" "lit"
+ "lrf" "lrx" "mobi" "opf" "or" "oxps" "pdb" "pdb" "pdb"
+ "pdg" "pkg" "prc" "ps" "rtf" "tr2" "tr3" "txt" "xeb" "xps"
+ "pot" "potx" "potm" "pps" "ppsx" "ppsm" "ppt" "pptx"
+ "pptm" "pa" "ppa" "ppam" "sldm" "sldx" ))
+ (treemacs-create-icon
+ :icon (format " %s\t" (all-the-icons-faicon "cogs" :height 0.85 :v-adjust 0 :face face-spec))
+ :extensions ("Vagrantfile" "babel.config.js" "babelignore" "babelrc"
+ "babelrc.js" "babelrc.json" "bashrc" "bazel" "bazelrc"
+ "bower.json" "bowerrc" "cabal" "cfg" "conf" "config"
+ "cson" "csv" "editorconfig" "envrc" "eslintignore"
+ "eslintrc" "feature" "gemfile" "git" "gitattributes"
+ "gitconfig" "gitignore" "gitmodules" "ideavimrc" "iml"
+ "ini" "inputrc" "json" "ledgerrc" "lock" "nginx"
+ "npm-shrinkwrap.json" "npmignore" "npmrc"
+ "package-lock.json" "package.json" "phpunit" "pkg" "plist"
+ "properties" "terminalrc" "toml" "tridactylrc"
+ "vimperatorrc" "vimrc" "vrapperrc" "xdefaults" "xml"
+ "xresources" "yaml" "yarn-integrity" "yarnclean"
+ "yarnignore" "yarnrc" "yml"))
+ (treemacs-create-icon
+ :icon (format " %s\t" (all-the-icons-octicon "file-text" :v-adjust 0 :face face-spec))
+ :extensions ("md" "markdown" "rst" "org" "log" "txt" "contribute"
+ "license" "readme" "changelog"))
+ (treemacs-create-icon
+ :icon (format " %s\t" (all-the-icons-octicon "file-binary" :v-adjust 0 :face face-spec))
+ :extensions ("exe" "dll" "obj" "so" "o" "out" "elc" "cmake-cache" "csr"
+ "eslintcache" "crt" "cer" "der" "pfx" "p12" "p7b" "p7r"
+ "DS_STORE" "key" "pem" "src" "crl" "sst" "stl" "ipynb"))
+ (treemacs-create-icon
+ :icon (format " %s\t" (all-the-icons-octicon "file-pdf" :v-adjust 0 :face face-spec))
+ :extensions ("pdf"))
+ (treemacs-create-icon
+ :icon (format " %s\t" (all-the-icons-octicon "file-zip" :v-adjust 0 :face face-spec))
+ :extensions ("zip" "xz" "7z" "tar" "gz" "rar" "tgz" "jar"))
+ (treemacs-create-icon
+ :icon (format " %s\t" (all-the-icons-octicon "file-text" :v-adjust 0 :face face-spec))
+ :extensions (fallback))))
+
+ (treemacs-create-theme "doom-colors"
+ :extends "doom-atom"
+ :config
+ (progn
+ (treemacs-create-icon
+ :icon (format " %s\t" (all-the-icons-octicon "repo" :height 1.2 :v-adjust -0.1 :face 'doom-themes-treemacs-root-face))
+ :extensions (root-open))
+ (treemacs-create-icon
+ :icon (format " %s\t" (all-the-icons-octicon "repo" :height 1.2 :v-adjust -0.1 :face 'doom-themes-treemacs-root-face))
+ :extensions (root-closed))
+ (treemacs-create-icon
+ :icon (format "%s\t" (all-the-icons-octicon "flame" :height 0.8 :v-adjust 0 :face 'all-the-icons-red))
+ :extensions (error))
+ (treemacs-create-icon
+ :icon (format "%s\t" (all-the-icons-octicon "stop" :height 0.8 :v-adjust 0 :face 'all-the-icons-yellow))
+ :extensions (warning))
+ (treemacs-create-icon
+ :icon (format "%s\t" (all-the-icons-octicon "info" :height 0.75 :v-adjust 0.1 :face 'all-the-icons-green))
+ :extensions (info))
+ (treemacs-create-icon
+ :icon (format " %s\t" (all-the-icons-alltheicon "git" :height 0.85 :v-adjust 0.0 :face 'all-the-icons-red))
+ :extensions ("gitignore" "git" "gitattributes" "gitconfig" "gitmodules"))
+ (treemacs-create-icon
+ :icon (format "%s\t" (all-the-icons-octicon "book" :height 1.0 :v-adjust 0.0 :face 'all-the-icons-blue))
+ :extensions (license))
+
+ (dolist (item all-the-icons-extension-icon-alist)
+ (let* ((extension (car item))
+ (func (cadr item))
+ (args (append (list (cadr (cdr item))) '(:v-adjust -0.05 :height 0.85) (cdr (cddr item))))
+ (icon (apply func args)))
+ (let* ((icon-pair (cons (format " %s\t" icon) " "))
+ (gui-icons (treemacs-theme->gui-icons treemacs--current-theme))
+ (tui-icons (treemacs-theme->tui-icons treemacs--current-theme))
+ (gui-icon (car icon-pair))
+ (tui-icon (cdr icon-pair)))
+ (ht-set! gui-icons extension gui-icon)
+ (ht-set! tui-icons extension tui-icon))))
+
+ ;; File extensions for whom the above did not work (likely because their
+ ;; regexp is too complicated to be reversed with
+ ;; `doom-themes--get-treemacs-extensions' -- which is too naive)
+ (treemacs-create-icon
+ :icon (format " %s\t" (all-the-icons-fileicon "R" :v-adjust 0 :face 'all-the-icons-dblue))
+ :extensions ("r"))
+ (treemacs-create-icon
+ :icon (format " %s\t" (all-the-icons-octicon "file-code" :v-adjust 0 :face face-spec))
+ :extensions ("elc")))))
+
+ (treemacs-load-theme doom-themes-treemacs-theme))
+
+;;;###autoload
+(defun doom-themes-treemacs-config ()
+ "Install doom-themes' treemacs configuration.
+
+Includes an Atom-esque icon theme and highlighting based on filetype.")
+
+(provide 'doom-themes-ext-treemacs)
+;;; doom-themes-treemacs.el ends here
diff --git a/elpa/doom-themes-20220504.1557/doom-themes-ext-visual-bell.el b/elpa/doom-themes-20220504.1557/doom-themes-ext-visual-bell.el
new file mode 100644
index 0000000..82e1af3
--- /dev/null
+++ b/elpa/doom-themes-20220504.1557/doom-themes-ext-visual-bell.el
@@ -0,0 +1,44 @@
+;;; doom-themes-ext-visual-bell.el --- flash mode-line on error -*- lexical-binding: t; -*-
+;;
+;; Copyright (C) 2019-2022 Henrik Lissner
+;;
+;; Author: Henrik Lissner <contact@henrik.io>
+;; Maintainer: Henrik Lissner <contact@henrik.io>
+;; Created: July 29, 2019
+;;
+;;; Commentary:
+;;; Code:
+
+(require 'face-remap)
+
+(defface doom-themes-visual-bell '((t :inherit error))
+ "Face to use for the mode-line when `doom-themes-visual-bell-config' is used."
+ :group 'doom-themes)
+
+;;;###autoload
+(defun doom-themes-visual-bell-fn ()
+ "Blink the mode-line red briefly. Set `ring-bell-function' to this to use it."
+ ;; Since emacs 29, the mode-line face is the parent of the new face
+ ;; mode-line-active and mode-line-inactive. For remapping purposes, the
+ ;; mode-line-active face has to be used, see details at:
+ ;; http://debbugs.gnu.org/cgi/bugreport.cgi?bug=53636
+ (let* ((face (if (facep 'mode-line-active)
+ 'mode-line-active
+ 'mode-line))
+ (buf (current-buffer))
+ (cookie (face-remap-add-relative face 'doom-themes-visual-bell)))
+ (force-mode-line-update)
+ (run-with-timer 0.15 nil
+ (lambda ()
+ (with-current-buffer buf
+ (face-remap-remove-relative cookie)
+ (force-mode-line-update))))))
+
+;;;###autoload
+(defun doom-themes-visual-bell-config ()
+ "Enable flashing the mode-line on error."
+ (setq ring-bell-function #'doom-themes-visual-bell-fn
+ visible-bell t))
+
+(provide 'doom-themes-ext-visual-bell)
+;;; doom-themes-ext-visual-bell.el ends here
diff --git a/elpa/doom-themes-20220504.1557/doom-themes-ext-visual-bell.elc b/elpa/doom-themes-20220504.1557/doom-themes-ext-visual-bell.elc
new file mode 100644
index 0000000..d29de36
--- /dev/null
+++ b/elpa/doom-themes-20220504.1557/doom-themes-ext-visual-bell.elc
Binary files differ
diff --git a/elpa/doom-themes-20220504.1557/doom-themes-pkg.el b/elpa/doom-themes-20220504.1557/doom-themes-pkg.el
new file mode 100644
index 0000000..648b14b
--- /dev/null
+++ b/elpa/doom-themes-20220504.1557/doom-themes-pkg.el
@@ -0,0 +1,13 @@
+(define-package "doom-themes" "20220504.1557" "an opinionated pack of modern color-themes"
+ '((emacs "25.1")
+ (cl-lib "0.5"))
+ :commit "cdbeb346aa19e4129014cb3ebab7e87c66b4a8da" :authors
+ '(("Henrik Lissner" . "contact@henrik.io"))
+ :maintainer
+ '("Henrik Lissner" . "contact@henrik.io")
+ :keywords
+ '("themes" "faces")
+ :url "https://github.com/doomemacs/themes")
+;; Local Variables:
+;; no-byte-compile: t
+;; End:
diff --git a/elpa/doom-themes-20220504.1557/doom-themes.el b/elpa/doom-themes-20220504.1557/doom-themes.el
new file mode 100644
index 0000000..1e5816c
--- /dev/null
+++ b/elpa/doom-themes-20220504.1557/doom-themes.el
@@ -0,0 +1,435 @@
+;;; doom-themes.el --- an opinionated pack of modern color-themes -*- lexical-binding: t; -*-
+;;
+;; Copyright (C) 2016-2022 Henrik Lissner
+;;
+;; Author: Henrik Lissner <contact@henrik.io>
+;; Maintainer: Henrik Lissner <contact@henrik.io>
+;; Maintainer: Emmanuel Bustos Torres <ema2159@gmail.com>
+;; Created: May 22, 2016
+;; Version: 2.2.1
+;; Keywords: themes faces
+;; Homepage: https://github.com/doomemacs/themes
+;; Package-Requires: ((emacs "25.1") (cl-lib "0.5"))
+;;
+;; This file is not part of GNU Emacs.
+;;
+;;; Commentary:
+;;
+;; DOOM Themes is an opinionated UI plugin and pack of themes extracted from my
+;; [emacs.d], inspired by some of my favorite color themes including:
+;;
+;; Flagship themes
+;; `doom-one'
+;; `doom-one-light'
+;; `doom-vibrant'
+;;
+;; Additional themes
+;; + `doom-acario-dark' (added by gagbo)
+;; + `doom-acario-light' (added by gagbo)
+;; + `doom-ayu-dark': (added by LoveSponge)
+;; + `doom-ayu-light': (added by LoveSponge)
+;; + `doom-city-lights' (added by fuxialexnder)
+;; + `doom-challenger-deep' (added by fuxialexnder)
+;; + `doom-dark+' (added by ema2159)
+;; + `doom-dracula' (added by fuxialexnder)
+;; + `doom-ephemeral' (added by karetsu)
+;; + `doom-fairy-floss' (added by ema2159)
+;; + `doom-flatwhite' (added by ShaneKilkelly)
+;; + `doom-gruvbox' (added by JongW)
+;; + `doom-gruxbox-light' (added by jsoa)
+;; + `doom-henna' (added by jsoa)
+;; + `doom-homage-white' (added by [mskorzhinskiy])
+;; + `doom-homage-black': (added by [mskorzhinskiy])
+;; + `doom-horizon' (added by karetsu)
+;; + `doom-Iosvkem' (added by neutaaaaan)
+;; + `doom-ir-black' (added by legendre6891)
+;; + `doom-laserwave' (added by hyakt)
+;; + `doom-material' (added by tam5)
+;; + `doom-material-dark' (added by trev-dev)
+;; + `doom-manegarm' (added by kenranunderscore)
+;; + `doom-meltbus' (added by spacefrogg)
+;; + `doom-miramare' (added by sagittaros)
+;; + `doom-molokai' (added by hlissner)
+;; + `doom-monokai-classic' (added by ema2159)
+;; + `doom-monokai-pro' (added by kadenbarlow)
+;; + `doom-monokai-machine' (added by minikN)
+;; + `doom-monokai-octagon' (added by minikN)
+;; + `doom-monokai-ristretto' (added by minikN)
+;; + `doom-monokai-spectrum' (added by minikN)
+;; + `doom-moonlight' (added by Brettm12345)
+;; + `doom-nord' (added by fuxialexnder)
+;; + `doom-nord-light' (added by fuxialexnder)
+;; + `doom-nova' (added by bigardone)
+;; + `doom-oceanic-next' (added by juanwolf)
+;; + `doom-old-hope' (added by teesloane)
+;; + `doom-opera' (added by jwintz)
+;; + `doom-opera-light' (added by jwintz)
+;; + `doom-outrun' (added by ema2159)
+;; + `doom-palenight' (added by Brettm12345)
+;; + `doom-peacock' (added by teesloane)
+;; + `doom-plain': (added by [mateossh])
+;; + `doom-plain-dark': (added by [das-s])
+;; + `doom-rouge' (added by JordanFaust)
+;; + `doom-snazzy' (added by ar1a)
+;; + `doom-solarized-dark' (added by ema2159)
+;; + `doom-solarized-light' (added by fuxialexnder)
+;; + `doom-sourcerer' (added by defphil)
+;; + `doom-spacegrey' (added by teesloane)
+;; + `doom-tokyo-night' (added by FosterHangdaan)
+;; + `doom-tomorrow-night' (added by emacswatcher)
+;; + `doom-tomorrow-day' (added by emacswatcher)
+;; + `doom-wilmersdorf' (added by ianpan870102)
+;; + `doom-zenburn' (added by jsoa)
+;;
+;; ## Install
+;;
+;; `M-x package-install RET doom-themes`
+;;
+;; A comprehensive configuration example:
+;;
+;; (require 'doom-themes)
+;;
+;; ;; Global settings (defaults)
+;; (setq doom-themes-enable-bold t ; if nil, bold is universally disabled
+;; doom-themes-enable-italic t) ; if nil, italics is universally disabled
+;;
+;; ;; Load the theme (doom-one, doom-molokai, etc); keep in mind that each
+;; ;; theme may have their own settings.
+;; (load-theme 'doom-one t)
+;;
+;; ;; Enable flashing mode-line on errors
+;; (doom-themes-visual-bell-config)
+;;
+;; ;; Enable custom neotree theme
+;; (doom-themes-neotree-config) ; all-the-icons fonts must be installed!
+;;
+;;; Code:
+
+(require 'cl-lib)
+(require 'doom-themes-base)
+
+(defgroup doom-themes nil
+ "Options for doom-themes."
+ :group 'faces)
+
+(defcustom doom-themes-padded-modeline nil
+ "Default value for padded-modeline setting for themes that support it."
+ :group 'doom-themes
+ :type '(choice integer boolean))
+
+;;
+(defcustom doom-themes-enable-bold t
+ "If nil, bold will be disabled across all faces."
+ :group 'doom-themes
+ :type 'boolean)
+
+(defcustom doom-themes-enable-italic t
+ "If nil, italics will be disabled across all faces."
+ :group 'doom-themes
+ :type 'boolean)
+
+
+;;
+;;; API
+
+(defvar doom-themes--colors nil)
+(defvar doom--min-colors '(257 256 16))
+(defvar doom--quoted-p nil)
+(defvar doom-themes--faces nil)
+
+(defun doom-themes--colors-p (item)
+ (declare (pure t) (side-effect-free t))
+ (when item
+ (cond ((listp item)
+ (let ((car (car item)))
+ (cond ((memq car '(quote doom-color)) nil)
+
+ ((memq car '(backquote \`))
+ (let ((doom--quoted-p t))
+ (doom-themes--colors-p (cdr item))))
+
+ ((eq car '\,)
+ (let (doom--quoted-p)
+ (doom-themes--colors-p (cdr item))))
+
+ ((or (doom-themes--colors-p car)
+ (doom-themes--colors-p (cdr-safe item)))))))
+
+ ((and (symbolp item)
+ (not (keywordp item))
+ (not doom--quoted-p)
+ (not (equal (substring (symbol-name item) 0 1) "-"))
+ (assq item doom-themes--colors))))))
+
+(defun doom-themes--apply-faces (new-faces &optional default-faces)
+ (declare (pure t) (side-effect-free t))
+ (let ((default-faces (or default-faces doom-themes-base-faces))
+ (faces (make-hash-table :test #'eq :size (+ (length default-faces) (length new-faces))))
+ (directives (make-hash-table :test #'eq)))
+ (dolist (spec (append (mapcar #'copy-sequence default-faces) new-faces))
+ (if (listp (car spec))
+ (cl-destructuring-bind (face action &optional arg) (car spec)
+ (unless (assq face new-faces)
+ (puthash face (list action arg (cdr spec))
+ directives)))
+ (puthash (car spec) (cdr spec) faces)))
+ (cl-loop for face being the hash-keys of directives
+ for (action target spec) = (gethash face directives)
+ unless (memq action '(&inherit &extend &override))
+ do (error "Invalid operation (%s) for '%s' face" action face)
+ if (eq (car spec) 'quote)
+ do (error "Can't extend literal face spec (for '%s')" face)
+ ;; TODO Add &all/&light/&dark extension support
+ else if (memq (car spec) '(&all &light &dark))
+ do (error "Can't extend face with &all, &light or &dark specs (for '%s')" face)
+ else do
+ (puthash face
+ (let ((old-spec (gethash (or target face) faces))
+ (plist spec))
+ ;; remove duplicates
+ (while (keywordp (car plist))
+ (setq old-spec (plist-put old-spec (car plist) (cadr plist))
+ plist (cddr plist)))
+ old-spec)
+ faces))
+ (let (results)
+ (maphash (lambda (face plist)
+ (when (keywordp (car plist))
+ ;; TODO Clean up duplicates in &all/&light/&dark blocks
+ (dolist (prop (append (unless doom-themes-enable-bold '(:weight normal :bold nil))
+ (unless doom-themes-enable-italic '(:slant normal :italic nil))))
+ (when (and (plist-member plist prop)
+ (not (eq (plist-get plist prop) 'inherit)))
+ (plist-put plist prop
+ (if (memq prop '(:weight :slant))
+ (quote 'normal))))))
+ (push (cons face plist) results))
+ faces)
+ (nreverse results))))
+
+(defun doom-themes--colorize (item type)
+ (declare (pure t) (side-effect-free t))
+ (when item
+ (let ((doom--quoted-p doom--quoted-p))
+ (cond ((listp item)
+ (cond ((memq (car item) '(quote doom-color))
+ item)
+ ((eq (car item) 'doom-ref)
+ (doom-themes--colorize
+ (apply #'doom-ref (cdr item)) type))
+ ((let* ((item (append item nil))
+ (car (car item))
+ (doom--quoted-p
+ (cond ((memq car '(backquote \`)) t)
+ ((eq car '\,) nil)
+ (t doom--quoted-p))))
+ (cons car
+ (cl-loop
+ for i in (cdr item)
+ collect (doom-themes--colorize i type)))))))
+
+ ((and (symbolp item)
+ (not (keywordp item))
+ (not doom--quoted-p)
+ (not (equal (substring (symbol-name item) 0 1) "-"))
+ (assq item doom-themes--colors))
+ `(doom-color ',item ',type))
+
+ (item)))))
+
+(defun doom-themes--build-face (face)
+ (declare (pure t) (side-effect-free t))
+ `(list
+ ',(car face)
+ ,(let ((face-body (cdr face)))
+ (cond ((keywordp (car face-body))
+ (let ((real-attrs face-body)
+ defs)
+ (if (doom-themes--colors-p real-attrs)
+ (dolist (cl doom--min-colors `(list ,@(nreverse defs)))
+ (push `(list '((class color) (min-colors ,cl))
+ (list ,@(doom-themes--colorize real-attrs cl)))
+ defs))
+ `(list (list 't (list ,@real-attrs))))))
+
+ ((memq (car-safe (car face-body)) '(quote backquote \`))
+ (car face-body))
+
+ ((let (all-attrs defs)
+ (dolist (attrs face-body `(list ,@(nreverse defs)))
+ (cond ((eq (car attrs) '&all)
+ (setq all-attrs (append all-attrs (cdr attrs))))
+
+ ((memq (car attrs) '(&dark &light))
+ (let ((bg (if (eq (car attrs) '&dark) 'dark 'light))
+ (real-attrs (append all-attrs (cdr attrs) '())))
+ (cond ((doom-themes--colors-p real-attrs)
+ (dolist (cl doom--min-colors)
+ (push `(list '((class color) (min-colors ,cl) (background ,bg))
+ (list ,@(doom-themes--colorize real-attrs cl)))
+ defs)))
+
+ ((push `(list '((background ,bg)) (list ,@real-attrs))
+ defs)))))))))))))
+
+
+;;
+;;; Color helper functions
+
+;; Shamelessly *borrowed* from solarized
+;;;###autoload
+(defun doom-name-to-rgb (color)
+ "Retrieves the hexidecimal string repesented the named COLOR (e.g. \"red\")
+for FRAME (defaults to the current frame)."
+ (cl-loop with div = (float (car (tty-color-standard-values "#ffffff")))
+ for x in (tty-color-standard-values (downcase color))
+ collect (/ x div)))
+
+;;;###autoload
+(defun doom-blend (color1 color2 alpha)
+ "Blend two colors (hexidecimal strings) together by a coefficient ALPHA (a
+float between 0 and 1)"
+ (when (and color1 color2)
+ (cond ((and color1 color2 (symbolp color1) (symbolp color2))
+ (doom-blend (doom-color color1) (doom-color color2) alpha))
+
+ ((or (listp color1) (listp color2))
+ (cl-loop for x in color1
+ when (if (listp color2) (pop color2) color2)
+ collect (doom-blend x it alpha)))
+
+ ((and (string-prefix-p "#" color1) (string-prefix-p "#" color2))
+ (apply (lambda (r g b) (format "#%02x%02x%02x" (* r 255) (* g 255) (* b 255)))
+ (cl-loop for it in (doom-name-to-rgb color1)
+ for other in (doom-name-to-rgb color2)
+ collect (+ (* alpha it) (* other (- 1 alpha))))))
+
+ (color1))))
+
+;;;###autoload
+(defun doom-darken (color alpha)
+ "Darken a COLOR (a hexidecimal string) by a coefficient ALPHA (a float between
+0 and 1)."
+ (cond ((and color (symbolp color))
+ (doom-darken (doom-color color) alpha))
+
+ ((listp color)
+ (cl-loop for c in color collect (doom-darken c alpha)))
+
+ ((doom-blend color "#000000" (- 1 alpha)))))
+
+;;;###autoload
+(defun doom-lighten (color alpha)
+ "Brighten a COLOR (a hexidecimal string) by a coefficient ALPHA (a float
+between 0 and 1)."
+ (cond ((and color (symbolp color))
+ (doom-lighten (doom-color color) alpha))
+
+ ((listp color)
+ (cl-loop for c in color collect (doom-lighten c alpha)))
+
+ ((doom-blend color "#FFFFFF" (- 1 alpha)))))
+
+;;;###autoload
+(defun doom-color (name &optional type)
+ "Retrieve a specific color named NAME (a symbol) from the current theme."
+ (let ((colors (if (listp name)
+ name
+ (cdr-safe (assq name doom-themes--colors)))))
+ (and colors
+ (cond ((listp colors)
+ (let ((i (or (plist-get '(256 1 16 2 8 3) type) 0)))
+ (if (> i (1- (length colors)))
+ (car (last colors))
+ (nth i colors))))
+ (t colors)))))
+
+;;;###autoload
+(defun doom-ref (face prop &optional class)
+ "TODO"
+ (let ((spec (or (cdr (assq face doom-themes--faces))
+ (error "Couldn't find the '%s' face" face))))
+ (when (memq (car spec) '(quote backquote \`))
+ (user-error "Can't fetch the literal spec for '%s'" face))
+ (when class
+ (setq spec (cdr (assq class spec)))
+ (unless spec
+ (error "Couldn't find the '%s' class in the '%s' face"
+ class face)))
+ (unless (plist-member spec prop)
+ (error "Couldn't find the '%s' property in the '%s' face%s"
+ prop face (if class (format "'s '%s' class" class) "")))
+ (plist-get spec prop)))
+
+
+;;
+;;; Defining themes
+
+(defun doom-themes-prepare-facelist (custom-faces)
+ "Return an alist of face definitions for `custom-theme-set-faces'.
+
+Faces in EXTRA-FACES override the default faces."
+ (declare (pure t) (side-effect-free t))
+ (setq doom-themes--faces (doom-themes--apply-faces custom-faces))
+ (mapcar #'doom-themes--build-face doom-themes--faces))
+
+(defun doom-themes-prepare-varlist (vars)
+ "Return an alist of variable definitions for `custom-theme-set-variables'.
+
+Variables in EXTRA-VARS override the default ones."
+ (declare (pure t) (side-effect-free t))
+ (cl-loop for (var val) in (append doom-themes-base-vars vars)
+ collect `(list ',var ,val)))
+
+;;;###autoload
+(defun doom-themes-set-faces (theme &rest faces)
+ "Customize THEME (a symbol) with FACES.
+
+If THEME is nil, it applies to all themes you load. FACES is a list of Doom
+theme face specs. These is a simplified spec. For example:
+
+ (doom-themes-set-faces 'user
+ '(default :background red :foreground blue)
+ '(doom-modeline-bar :background (if -modeline-bright modeline-bg highlight))
+ '(doom-modeline-buffer-file :inherit 'mode-line-buffer-id :weight 'bold)
+ '(doom-modeline-buffer-path :inherit 'mode-line-emphasis :weight 'bold)
+ '(doom-modeline-buffer-project-root :foreground green :weight 'bold))"
+ (declare (indent defun))
+ (apply #'custom-theme-set-faces
+ (or theme 'user)
+ (eval
+ `(let* ((bold ,doom-themes-enable-bold)
+ (italic ,doom-themes-enable-italic)
+ ,@(cl-loop for (var . val) in doom-themes--colors
+ collect `(,var ',val)))
+ (list ,@(mapcar #'doom-themes--build-face faces))))))
+
+(defmacro def-doom-theme (name docstring defs &optional extra-faces extra-vars)
+ "Define a DOOM theme, named NAME (a symbol)."
+ (declare (doc-string 2))
+ (let ((doom-themes--colors defs))
+ `(let* ((bold doom-themes-enable-bold)
+ (italic doom-themes-enable-italic)
+ ,@defs)
+ (setq doom-themes--colors
+ (list ,@(cl-loop for (var val) in defs
+ collect `(cons ',var ,val))))
+ (deftheme ,name ,docstring)
+ (custom-theme-set-faces
+ ',name ,@(doom-themes-prepare-facelist extra-faces))
+ (custom-theme-set-variables
+ ',name ,@(doom-themes-prepare-varlist extra-vars))
+ (unless bold (set-face-bold 'bold nil))
+ (unless italic (set-face-italic 'italic nil))
+ (provide-theme ',name))))
+
+;;;###autoload
+(when (and (boundp 'custom-theme-load-path) load-file-name)
+ (let* ((base (file-name-directory load-file-name))
+ (dir (expand-file-name "themes/" base)))
+ (add-to-list 'custom-theme-load-path
+ (or (and (file-directory-p dir) dir)
+ base))))
+
+(provide 'doom-themes)
+;;; doom-themes.el ends here
diff --git a/elpa/doom-themes-20220504.1557/doom-themes.elc b/elpa/doom-themes-20220504.1557/doom-themes.elc
new file mode 100644
index 0000000..c8b2689
--- /dev/null
+++ b/elpa/doom-themes-20220504.1557/doom-themes.elc
Binary files differ
diff --git a/elpa/doom-themes-20220504.1557/doom-tokyo-night-theme.el b/elpa/doom-themes-20220504.1557/doom-tokyo-night-theme.el
new file mode 100644
index 0000000..09e4332
--- /dev/null
+++ b/elpa/doom-themes-20220504.1557/doom-tokyo-night-theme.el
@@ -0,0 +1,280 @@
+;;; doom-tokyo-night-theme.el - based on https://github.com/enkia/tokyo-night-vscode-theme -*- lexical-binding: t; no-byte-compile: t; -*-
+(require 'doom-themes)
+
+;;
+(defgroup doom-tokyo-night-theme nil
+ "Options for doom-themes"
+ :group 'doom-themes)
+
+(defcustom doom-tokyo-night-brighter-modeline nil
+ "If non-nil, more vivid colors will be used to style the mode-line."
+ :group 'doom-tokyo-night-theme
+ :type 'boolean)
+
+(defcustom doom-tokyo-night-brighter-comments nil
+ "If non-nil, comments will be highlighted in more vivid colors."
+ :group 'doom-tokyo-night-theme
+ :type 'boolean)
+
+(defcustom doom-tokyo-night-comment-bg doom-tokyo-night-brighter-comments
+ "If non-nil, comments will have a subtle, darker background. Enhancing their legibility."
+ :group 'doom-tokyo-night-theme
+ :type 'boolean)
+
+(defcustom doom-tokyo-night-padded-modeline nil
+ "If non-nil, adds a 4px padding to the mode-line. Can be an integer to determine the exact padding."
+ :group 'doom-tokyo-night-theme
+ :type '(or integer boolean))
+
+(def-doom-theme doom-tokyo-night
+ "A clean, dark theme that celebrates the lights of downtown Tokyo at night."
+
+ ; Color Scheme
+ ; gui 256
+ ; "#f7768e" "#f7768e" => This keyword, HTML elements, Regex group symbol, CSS units, Terminal Red
+ ; "#ff9e64" "#ff9e64" => Number and Boolean constants, Language support constants
+ ; "#e0af68" "#e0af68" => Function parameters, Regex character sets, Terminal Yellow
+ ; "#9ece6a" "#9ece6a" => Strings, CSS class names
+ ; "#73daca" "#73daca" => Object literal keys, Markdown links, Terminal Green
+ ; "#b4f9f8" "#b4f9f8" => Regex literal strings
+ ; "#2ac3de" "#2ac3de" => Language support functions, CSS HTML elements
+ ; "#7dcfff" "#7dcfff" => Object properties, Regex quantifiers and flags, Markdown headings, Terminal Cyan, Markdown code, Import/export keywords
+ ; "#7aa2f7" "#7aa2f7" => Function names, CSS property names, Terminal Blue
+ ; "#bb9af7" "#bb9af7" => Control Keywords, Storage Types, Regex symbols and operators, HTML Attributes, Terminal Magenta
+ ; "#c0caf5" "#c0caf5" => Variables, Class names, Terminal White
+ ; "#a9b1d6" "#a9b1d6" => Editor foreground
+ ; "#9aa5ce" "#9aa5ce" => Markdown Text, HTML Text
+ ; "#cfc9c2" "#cfc9c2" => Parameters inside functions (semantic highlighting only)
+ ; "#565f89" "#565f89" => Comments
+ ; "#414868" "#414868" => Terminal black
+ ; "#24283b" "#24283b" => Editor background (Storm)
+ ; "#1a1b26" "#1a1b26" => Editor background (Night)
+
+ ;; name default 256 16
+ ((bg '("#1a1b26" nil nil ))
+ (bg-alt '("#13141c" nil nil ))
+ (base0 '("#414868" "#414868" "black" ))
+ (base1 '("#51587a" "#51587a" "brightblack" ))
+ (base2 '("#61698b" "#61698b" "brightblack" ))
+ (base3 '("#71799d" "#71799d" "brightblack" ))
+ (base4 '("#8189af" "#8189af" "brightblack" ))
+ (base5 '("#9099c0" "#9099c0" "brightblack" ))
+ (base6 '("#a0aad2" "#a0aad2" "brightblack" ))
+ (base7 '("#b0bae3" "#b0bae3" "brightblack" ))
+ (base8 '("#c0caf5" "#c0caf5" "white" ))
+ (fg-alt '("#c0caf5" "#c0caf5" "brightwhite" ))
+ (fg '("#a9b1d6" "#a9b1d6" "white" ))
+
+ (grey base4)
+ (red '("#f7768e" "#f7768e" "red" ))
+ (orange '("#ff9e64" "#ff9e64" "brightred" ))
+ (green '("#73daca" "#73daca" "green" ))
+ (teal '("#2ac3de" "#2ac3de" "brightgreen" ))
+ (yellow '("#e0af68" "#e0af68" "yellow" ))
+ (blue '("#7aa2f7" "#7aa2f7" "brightblue" ))
+ (dark-blue '("#565f89" "#565f89" "blue" ))
+ (magenta '("#bb9af7" "#bb9af7" "magenta" ))
+ (violet '("#9aa5ce" "#9aa5ce" "brightmagenta"))
+ (cyan '("#b4f9f8" "#b4f9f8" "brightcyan" ))
+ (dark-cyan '("#7dcfff" "#7dcfff" "cyan" ))
+ ; Additional custom colors
+ (dark-green '("#9ece6a" "#9ece6a" "green" ))
+ (brown '("#cfc9c2" "#cfc9c2" "yellow" ))
+
+ ;; face categories -- required for all themes
+ (highlight cyan)
+ (vertical-bar (doom-lighten bg 0.05))
+ (selection base0)
+ (builtin red)
+ (comments (if doom-tokyo-night-brighter-comments base5 base1))
+ (doc-comments (doom-lighten (if doom-tokyo-night-brighter-comments base5 base1) 0.25))
+ (constants orange)
+ (functions blue)
+ (keywords magenta)
+ (methods blue)
+ (operators dark-cyan)
+ (type base8)
+ (strings dark-green)
+ (variables base8)
+ (numbers orange)
+ (region base0)
+ (error red)
+ (warning yellow)
+ (success green)
+ (vc-modified orange)
+ (vc-added green)
+ (vc-deleted red)
+
+ ;; custom categories
+ (hidden `(,(car bg) "black" "black"))
+ (-modeline-bright doom-tokyo-night-brighter-modeline)
+ (-modeline-pad
+ (when doom-tokyo-night-padded-modeline
+ (if (integerp doom-tokyo-night-padded-modeline) doom-tokyo-night-padded-modeline 4)))
+
+ (modeline-fg nil)
+ (modeline-fg-alt base5)
+
+ (modeline-bg
+ (if -modeline-bright
+ base3
+ `(,(doom-darken (car bg) 0.15) ,@(cdr base0))))
+ (modeline-bg-l
+ (if -modeline-bright
+ base3
+ `(,(doom-darken (car bg) 0.1) ,@(cdr base0))))
+ (modeline-bg-inactive (doom-darken bg 0.1))
+ (modeline-bg-inactive-l `(,(car bg) ,@(cdr base1))))
+
+
+ ;; --- Extra Faces ------------------------
+ (
+ ((line-number-current-line &override) :foreground base8)
+ ((line-number &override) :foreground comments :background (doom-darken bg 0.025))
+
+ (font-lock-comment-face
+ :foreground comments
+ :background (if doom-tokyo-night-comment-bg (doom-lighten bg 0.05)))
+ (font-lock-doc-face
+ :inherit 'font-lock-comment-face
+ :foreground doc-comments)
+
+ ;;; Doom Modeline
+ (doom-modeline-bar :background (if -modeline-bright modeline-bg highlight))
+ (doom-modeline-buffer-path :foreground base8 :weight 'normal)
+ (doom-modeline-buffer-file :foreground brown :weight 'normal)
+
+ (mode-line
+ :background modeline-bg :foreground modeline-fg
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg)))
+ (mode-line-inactive
+ :background modeline-bg-inactive :foreground modeline-fg-alt
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive)))
+ (mode-line-emphasis
+ :foreground (if -modeline-bright base8 highlight))
+ (mode-line-buffer-id
+ :foreground highlight)
+
+ ;;; Indentation
+ (whitespace-indentation :background bg)
+ (whitespace-tab :background bg)
+
+ ;;; Ivy
+ (ivy-subdir :foreground blue)
+ (ivy-minibuffer-match-face-1 :foreground green :background bg-alt)
+ (ivy-minibuffer-match-face-2 :foreground orange :background bg-alt)
+ (ivy-minibuffer-match-face-3 :foreground red :background bg-alt)
+ (ivy-minibuffer-match-face-4 :foreground yellow :background bg-alt)
+
+ ;;; Elscreen
+ (elscreen-tab-other-screen-face :background "#353a42" :foreground "#1e2022")
+
+ ;;; Solaire
+ (solaire-mode-line-face
+ :inherit 'mode-line
+ :background modeline-bg-l
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-l)))
+ (solaire-mode-line-inactive-face
+ :inherit 'mode-line-inactive
+ :background modeline-bg-inactive-l
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive-l)))
+
+ ;;; Telephone
+ (telephone-line-accent-active
+ :inherit 'mode-line
+ :background (doom-lighten bg 0.2))
+ (telephone-line-accent-inactive
+ :inherit 'mode-line
+ :background (doom-lighten bg 0.05))
+ (telephone-line-evil-emacs
+ :inherit 'mode-line
+ :background dark-blue)
+
+ ;;;; rainbow-delimiters
+ (rainbow-delimiters-depth-1-face :foreground fg)
+ (rainbow-delimiters-depth-2-face :foreground blue)
+ (rainbow-delimiters-depth-3-face :foreground orange)
+ (rainbow-delimiters-depth-4-face :foreground green)
+ (rainbow-delimiters-depth-5-face :foreground cyan)
+ (rainbow-delimiters-depth-6-face :foreground yellow)
+ (rainbow-delimiters-depth-7-face :foreground teal)
+
+ ;;; Treemacs
+ (treemacs-root-face :foreground magenta :weight 'bold :height 1.2)
+ (doom-themes-treemacs-root-face :foreground magenta :weight 'ultra-bold :height 1.2)
+ (doom-themes-treemacs-file-face :foreground fg-alt)
+ (treemacs-directory-face :foreground base8)
+ (treemacs-file-face :foreground fg)
+ (treemacs-git-modified-face :foreground green)
+ (treemacs-git-renamed-face :foreground yellow)
+
+ ;;; Magit
+ (magit-section-heading :foreground blue)
+ (magit-branch-remote :foreground orange)
+ (magit-diff-our :foreground (doom-darken red 0.2) :background (doom-darken red 0.7))
+ (magit-diff-our-highlight :foreground red :background (doom-darken red 0.5) :weight 'bold)
+ (magit-diff-removed :foreground (doom-darken red 0.2) :background (doom-darken red 0.7))
+ (magit-diff-removed-highlight :foreground red :background (doom-darken red 0.5) :weight 'bold)
+
+ ;; --- Major-Mode Faces -------------------
+ ;;; elisp
+ (highlight-quoted-symbol :foreground yellow)
+
+ ;;; js2-mode
+ (js2-function-param :foreground yellow)
+ (js2-object-property :foreground green)
+
+ ;;; typescript-mode
+ (typescript-this-face :foreground red)
+ (typescript-access-modifier-face :foreground brown)
+
+ ;;; rjsx-mode
+ (rjsx-tag :foreground red)
+ (rjsx-text :foreground violet)
+ (rjsx-attr :foreground magenta :slant 'italic :weight 'medium)
+ (rjsx-tag-bracket-face :foreground (doom-darken red 0.3))
+
+ ;;; css-mode / scss-mode
+ (css-property :foreground blue)
+ (css-selector :foreground teal)
+ (css-pseudo-class :foreground orange)
+
+ ;;; markdown-mode
+ (markdown-markup-face :foreground violet)
+ (markdown-header-face :inherit 'bold :foreground dark-cyan)
+ (markdown-blockquote-face :foreground violet :background (doom-lighten bg 0.04))
+ (markdown-table-face :foreground violet :background (doom-lighten bg 0.04))
+ ((markdown-code-face &override) :foreground dark-cyan :background (doom-lighten bg 0.04))
+
+ ;;; org-mode
+ (org-hide :foreground hidden)
+ (org-block :background (doom-darken base2 0.65))
+ (org-block-begin-line :background (doom-darken base2 0.65) :foreground comments :extend t)
+ (solaire-org-hide-face :foreground hidden)
+
+ ;;; web-mode
+ (web-mode-json-context-face :foreground brown)
+ (web-mode-json-key-face :foreground teal)
+ ;;;; Block
+ (web-mode-block-delimiter-face :foreground yellow)
+ ;;;; Code
+ (web-mode-constant-face :foreground constants)
+ (web-mode-variable-name-face :foreground variables)
+ ;;;; CSS
+ (web-mode-css-pseudo-class-face :foreground orange)
+ (web-mode-css-property-name-face :foreground blue)
+ (web-mode-css-selector-face :foreground teal)
+ (web-mode-css-function-face :foreground yellow)
+ ;;;; HTML
+ (web-mode-html-attr-engine-face :foreground yellow)
+ (web-mode-html-attr-equal-face :foreground operators)
+ (web-mode-html-attr-name-face :foreground magenta)
+ (web-mode-html-tag-bracket-face :foreground (doom-darken red 0.3))
+ (web-mode-html-tag-face :foreground red))
+
+
+ ;; --- extra variables ---------------------
+ ;; ()
+ )
+
+;;; doom-tokyo-night-theme.el ends here
diff --git a/elpa/doom-themes-20220504.1557/doom-tomorrow-day-theme.el b/elpa/doom-themes-20220504.1557/doom-tomorrow-day-theme.el
new file mode 100644
index 0000000..fbdf9b9
--- /dev/null
+++ b/elpa/doom-themes-20220504.1557/doom-tomorrow-day-theme.el
@@ -0,0 +1,150 @@
+;;; doom-tomorrow-day-theme.el -- port of tomorrow theme -*- lexical-binding: t; no-byte-compile: t; -*-
+;;; Commentary:
+;; This file is part of emacs-doom-themes, which provides license
+;; information.
+;;; Code:
+
+(require 'doom-themes)
+
+(defgroup doom-tomorrow-day-theme nil
+ "Options for the `doom-tomorrow-day' theme."
+ :group 'doom-themes)
+
+(defcustom doom-tomorrow-day-padded-modeline doom-themes-padded-modeline
+ "If non-nil, adds a 4px padding to the mode-line.
+Can be an integer to determine the exact padding."
+ :group 'doom-tomorrow-day-theme
+ :type '(choice integer boolean))
+
+(def-doom-theme doom-tomorrow-day
+ "A light theme based off of Chris Kempson's Tomorrow Dark."
+
+ ;; name gui 256 16
+ ((bg '("#ffffff" "white" "white" ))
+ (bg-alt '("#f2f2f2" nil nil ))
+ (base0 '("#f2f2f2" "white" "white" ))
+ (base1 '("#e4e4e4" "#e4e4e4" ))
+ (base2 '("#dedede" "#cccccc" ))
+ (base3 '("#d6d4d4" "#cccccc" "silver"))
+ (base4 '("#C0bfbf" "#c0c0c0" "silver"))
+ (base5 '("#a3a1a1" "#adadad" "silver"))
+ (base6 '("#8a8787" "#949494" "silver"))
+ (base7 '("#696769" "#6b6b6b" "silver"))
+ (base8 '("#000000" "#000000" "black" ))
+ (fg '("#4d4d4c" "#3a3a3a" "black"))
+ (fg-alt (doom-darken fg 0.6))
+
+ (grey '("#8e908c" "#999999" "silver"))
+ (red '("#c82829" "#cc3333" "red"))
+ (orange '("#f5871f" "#ff9933" "brightred"))
+ (yellow '("#eab700" "#ffcc00" "yellow"))
+ (green '("#718c00" "#669900" "green"))
+ (blue '("#4271ae" "#339999" "brightblue"))
+ (dark-blue (doom-darken blue 0.25))
+ (teal '("#3e999f" "#339999" "brightblue"))
+ (magenta '("#c678dd" "#c9b4cf" "magenta"))
+ (violet '("#8959a8" "#996699" "brightmagenta"))
+ (cyan '("#8abeb7" "#8abeb7" "cyan"))
+ (dark-cyan (doom-lighten cyan 0.4))
+
+ ;; face categories
+ (highlight blue)
+ (vertical-bar base3)
+ (selection base1)
+ (builtin blue)
+ (comments grey)
+ (doc-comments grey)
+ (constants orange)
+ (functions blue)
+ (keywords violet)
+ (methods blue)
+ (operators fg)
+ (type (doom-darken yellow 0.2))
+ (strings green)
+ (variables red)
+ (numbers orange)
+ (region selection)
+ (error red)
+ (warning yellow)
+ (success green)
+ (vc-modified (doom-lighten yellow 0.4))
+ (vc-added (doom-lighten green 0.4))
+ (vc-deleted red)
+
+ ;; custom categories
+ (org-block-bg (doom-lighten bg-alt 0.3))
+ (modeline-bg `(,(doom-lighten (car bg-alt) 0.4) ,@(cdr base3)))
+ (modeline-bg-alt bg)
+ (modeline-bg-inactive `(,(doom-darken (car bg) 0.04) ,@(cdr base1)))
+ (modeline-bg-alt-inactive bg)
+ (modeline-fg fg)
+ (modeline-fg-inactive comments)
+ (modeline-fg-alt-inactive comments)
+
+ (-modeline-pad
+ (when doom-tomorrow-day-padded-modeline
+ (if (integerp doom-tomorrow-day-padded-modeline)
+ doom-tomorrow-day-padded-modeline
+ 4))))
+
+ ;;;; Base theme face overrides
+ (((font-lock-doc-face &override) :slant 'italic)
+ ((line-number &override) :foreground base4)
+ ((line-number-current-line &override) :foreground base8)
+ (mode-line
+ :background modeline-bg :foreground modeline-fg
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg)))
+ (mode-line-inactive
+ :background modeline-bg-inactive :foreground modeline-fg-inactive
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive)))
+ (mode-line-highlight :inherit 'bold :background highlight :foreground base0)
+
+ ;;;; doom-modeline
+ (doom-modeline-bar :background highlight)
+ (doom-modeline-buffer-path :foreground violet :weight 'bold)
+ (doom-modeline-buffer-major-mode :inherit 'doom-modeline-buffer-path)
+ ;;;; ivy
+ (ivy-current-match :background region :distant-foreground grey :weight 'ultra-bold)
+ (ivy-minibuffer-match-face-1 :foreground base5 :weight 'light)
+ (ivy-minibuffer-match-face-2 :inherit 'ivy-minibuffer-match-face-1 :foreground violet :weight 'ultra-bold)
+ (ivy-minibuffer-match-face-3 :inherit 'ivy-minibuffer-match-face-2 :foreground blue)
+ (ivy-minibuffer-match-face-4 :inherit 'ivy-minibuffer-match-face-2 :foreground red)
+ ;;;; org <built-in>
+ ((org-block &override) :background org-block-bg)
+ ((org-block-background &override) :background org-block-bg)
+ ((org-block-begin-line &override) :background org-block-bg)
+ ((org-quote &override) :background org-block-bg)
+ ;;;; outline <built-in>
+ ((outline-1 &override) :foreground teal)
+ ((outline-2 &override) :foreground blue)
+ ((outline-3 &override) :foreground violet)
+ ((outline-4 &override) :foreground blue)
+ ((outline-5 &override) :foreground violet)
+ ((outline-6 &override) :foreground blue)
+ ((outline-7 &override) :foreground violet)
+ ((outline-8 &override) :foreground blue)
+ ;;;; rainbow-delimiters
+ (rainbow-delimiters-depth-1-face :foreground violet)
+ (rainbow-delimiters-depth-2-face :foreground blue)
+ (rainbow-delimiters-depth-3-face :foreground green)
+ (rainbow-delimiters-depth-4-face :foreground magenta)
+ (rainbow-delimiters-depth-5-face :foreground orange)
+ (rainbow-delimiters-depth-6-face :foreground yellow)
+ (rainbow-delimiters-depth-7-face :foreground teal)
+ ;;;; solaire-mode
+ (solaire-mode-line-face :inherit 'mode-line :background modeline-bg-alt)
+ (solaire-mode-line-inactive-face
+ :inherit 'mode-line-inactive
+ :background modeline-bg-alt-inactive
+ :foreground modeline-fg-alt-inactive)
+ ;;;; treemacs
+ (treemacs-git-untracked-face :foreground yellow)
+ ;;;; whitespace <built-in>
+ (whitespace-tab :background (doom-lighten base0 0.6)
+ :foreground comments))
+
+ ;; --- variables --------------------------
+ ;; ()
+ )
+
+;;; doom-tomorrow-day-theme.el ends here
diff --git a/elpa/doom-themes-20220504.1557/doom-tomorrow-night-theme.el b/elpa/doom-themes-20220504.1557/doom-tomorrow-night-theme.el
new file mode 100644
index 0000000..2b4fba2
--- /dev/null
+++ b/elpa/doom-themes-20220504.1557/doom-tomorrow-night-theme.el
@@ -0,0 +1,106 @@
+;;; doom-tomorrow-night-theme.el -*- lexical-binding: t; no-byte-compile: t; -*-
+(require 'doom-themes)
+
+(defgroup doom-tomorrow-night-theme nil
+ "Options for the `doom-tomorrow-night' theme."
+ :group 'doom-themes)
+
+(defcustom doom-tomorrow-night-padded-modeline doom-themes-padded-modeline
+ "If non-nil, adds a 4px padding to the mode-line. Can be an integer to
+determine the exact padding."
+ :group 'doom-tomorrow-night-theme
+ :type '(choice integer boolean))
+
+(def-doom-theme doom-tomorrow-night
+ "A theme based off of Chris Kempson's Tomorrow Dark."
+
+ ;; name gui 256 16
+ ((bg '("#1d1f21" nil nil ))
+ (bg-alt '("#161719" nil nil ))
+ (base0 '("#0d0d0d" "black" "black" ))
+ (base1 '("#1b1b1b" "#1b1b1b" ))
+ (base2 '("#212122" "#1e1e1e" ))
+ (base3 '("#292b2b" "#292929" "brightblack"))
+ (base4 '("#3f4040" "#3f3f3f" "brightblack"))
+ (base5 '("#5c5e5e" "#525252" "brightblack"))
+ (base6 '("#757878" "#6b6b6b" "brightblack"))
+ (base7 '("#969896" "#979797" "brightblack"))
+ (base8 '("#ffffff" "#ffffff" "white" ))
+ (fg '("#c5c8c6" "#c5c5c5" "white"))
+ (fg-alt (doom-darken fg 0.4))
+
+ (grey '("#5a5b5a" "#5a5a5a" "brightblack"))
+ (red '("#cc6666" "#cc6666" "red"))
+ (orange '("#de935f" "#dd9955" "brightred"))
+ (yellow '("#f0c674" "#f0c674" "yellow"))
+ (green '("#b5bd68" "#b5bd68" "green"))
+ (blue '("#81a2be" "#88aabb" "brightblue"))
+ (dark-blue '("#41728e" "#41728e" "blue"))
+ (teal blue) ; FIXME replace with real teal
+ (magenta '("#c9b4cf" "#c9b4cf" "magenta"))
+ (violet '("#b294bb" "#b294bb" "brightmagenta"))
+ (cyan '("#8abeb7" "#8abeb7" "cyan"))
+ (dark-cyan (doom-darken cyan 0.4))
+
+ ;; face categories
+ (highlight blue)
+ (vertical-bar base0)
+ (selection `(,(car (doom-lighten bg 0.1)) ,@(cdr base4)))
+ (builtin blue)
+ (comments grey)
+ (doc-comments (doom-lighten grey 0.14))
+ (constants orange)
+ (functions blue)
+ (keywords violet)
+ (methods blue)
+ (operators fg)
+ (type yellow)
+ (strings green)
+ (variables red)
+ (numbers orange)
+ (region selection)
+ (error red)
+ (warning yellow)
+ (success green)
+ (vc-modified fg-alt)
+ (vc-added green)
+ (vc-deleted red)
+
+ ;; custom categories
+ (modeline-bg `(,(doom-darken (car bg-alt) 0.3) ,@(cdr base3)))
+ (modeline-bg-alt `(,(car bg) ,@(cdr base1)))
+ (modeline-fg base8)
+ (modeline-fg-alt comments)
+ (-modeline-pad
+ (when doom-tomorrow-night-padded-modeline
+ (if (integerp doom-tomorrow-night-padded-modeline)
+ doom-tomorrow-night-padded-modeline
+ 4))))
+
+ ;; --- faces ------------------------------
+ (((line-number &override) :foreground base4)
+ ((line-number-current-line &override) :foreground blue :bold bold)
+ (mode-line
+ :background modeline-bg :foreground modeline-fg
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg)))
+ (mode-line-inactive
+ :background modeline-bg-alt :foreground modeline-fg-alt
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-alt)))
+
+ ;;;; rainbow-delimiters
+ (rainbow-delimiters-depth-1-face :foreground violet)
+ (rainbow-delimiters-depth-2-face :foreground blue)
+ (rainbow-delimiters-depth-3-face :foreground orange)
+ (rainbow-delimiters-depth-4-face :foreground green)
+ (rainbow-delimiters-depth-5-face :foreground magenta)
+ (rainbow-delimiters-depth-6-face :foreground yellow)
+ (rainbow-delimiters-depth-7-face :foreground teal)
+ ;;;; doom-modeline
+ (doom-modeline-buffer-path :foreground violet :bold bold)
+ (doom-modeline-buffer-major-mode :inherit 'doom-modeline-buffer-path))
+
+ ;; --- variables --------------------------
+ ;; ()
+ )
+
+;;; doom-tomorrow-night-theme.el ends here
diff --git a/elpa/doom-themes-20220504.1557/doom-vibrant-theme.el b/elpa/doom-themes-20220504.1557/doom-vibrant-theme.el
new file mode 100644
index 0000000..9728e3e
--- /dev/null
+++ b/elpa/doom-themes-20220504.1557/doom-vibrant-theme.el
@@ -0,0 +1,179 @@
+;; doom-vibrant-theme.el --- a more vibrant version of doom-one -*- lexical-binding: t; no-byte-compile: t; -*-
+;;
+;; Copyright (C) 2016-2021 Henrik Lissner
+;;
+;; Author: Henrik Lissner <https://github.com/hlissner>
+;; Created: December 6, 2020
+;; Version: 2.0.0
+;; Keywords: custom themes, faces
+;; Homepage: https://github.com/hlissner/emacs-doom-themes
+;; Package-Requires: ((emacs "25.1") (cl-lib "0.5") (doom-themes "2.2.1"))
+;;
+;;; Commentary:
+;;
+;; A version of `doom-one' that uses more vibrant colors.
+;;
+;;; Code:
+
+(require 'doom-themes)
+
+
+;;
+;;; Variables
+
+(defgroup doom-vibrant-theme nil
+ "Options for the `doom-vibrant' theme."
+ :group 'doom-themes)
+
+(defcustom doom-vibrant-brighter-modeline nil
+ "If non-nil, more vivid colors will be used to style the mode-line."
+ :group 'doom-vibrant-theme
+ :type 'boolean)
+
+(defcustom doom-vibrant-brighter-comments nil
+ "If non-nil, comments will be highlighted in more vivid colors."
+ :group 'doom-vibrant-theme
+ :type 'boolean)
+
+(defcustom doom-vibrant-padded-modeline doom-themes-padded-modeline
+ "If non-nil, adds a 4px padding to the mode-line.
+Can be an integer to determine the exact padding."
+ :group 'doom-vibrant-theme
+ :type '(choice integer boolean))
+
+
+;;
+;;; Theme definition
+
+(def-doom-theme doom-vibrant
+ "A dark theme based off of doom-one with more vibrant colors."
+
+ ;; name gui 256 16
+ ((bg '("#242730" "black" "black" ))
+ (fg '("#bbc2cf" "#bfbfbf" "brightwhite" ))
+
+ ;; These are off-color variants of bg/fg, used primarily for `solaire-mode',
+ ;; but can also be useful as a basis for subtle highlights (e.g. for hl-line
+ ;; or region), especially when paired with the `doom-darken', `doom-lighten',
+ ;; and `doom-blend' helper functions.
+ (bg-alt '("#2a2e38" "black" "black" ))
+ (fg-alt '("#5D656B" "#5d5d5d" "white" ))
+
+ ;; These should represent a spectrum from bg to fg, where base0 is a starker
+ ;; bg and base8 is a starker fg. For example, if bg is light grey and fg is
+ ;; dark grey, base0 should be white and base8 should be black.
+ (base0 '("#1c1f24" "#101010" "black" ))
+ (base1 '("#1c1f24" "#1e1e1e" "brightblack" ))
+ (base2 '("#21272d" "#21212d" "brightblack" ))
+ (base3 '("#23272e" "#262626" "brightblack" ))
+ (base4 '("#484854" "#5e5e5e" "brightblack" ))
+ (base5 '("#62686E" "#666666" "brightblack" ))
+ (base6 '("#757B80" "#7b7b7b" "brightblack" ))
+ (base7 '("#9ca0a4" "#979797" "brightblack" ))
+ (base8 '("#DFDFDF" "#dfdfdf" "white" ))
+
+ (grey base4)
+ (red '("#ff665c" "#ff6655" "red" ))
+ (orange '("#e69055" "#dd8844" "brightred" ))
+ (green '("#7bc275" "#99bb66" "green" ))
+ (teal '("#4db5bd" "#44b9b1" "brightgreen" ))
+ (yellow '("#FCCE7B" "#ECBE7B" "yellow" ))
+ (blue '("#51afef" "#51afef" "brightblue" ))
+ (dark-blue '("#1f5582" "#2257A0" "blue" ))
+ (magenta '("#C57BDB" "#c678dd" "brightmagenta" ))
+ (violet '("#a991f1" "#a9a1e1" "magenta" )) ;a9a1e1
+ (cyan '("#5cEfFF" "#46D9FF" "brightcyan" ))
+ (dark-cyan '("#6A8FBF" "#5699AF" "cyan" ))
+
+ ;; These are the "universal syntax classes" that doom-themes establishes.
+ ;; These *must* be included in every doom themes, or your theme will throw an
+ ;; error, as they are used in the base theme defined in doom-themes-base.
+ (highlight blue)
+ (vertical-bar base0)
+ (selection dark-blue)
+ (builtin magenta)
+ (comments (if doom-vibrant-brighter-comments dark-cyan base5))
+ (doc-comments (if doom-vibrant-brighter-comments (doom-lighten dark-cyan 0.15) (doom-lighten base4 0.3)))
+ (constants violet)
+ (functions cyan)
+ (keywords blue)
+ (methods violet)
+ (operators magenta)
+ (type yellow)
+ (strings green)
+ (variables base8)
+ (numbers orange)
+ (region "#3d4451")
+ (error red)
+ (warning yellow)
+ (success green)
+ (vc-modified yellow)
+ (vc-added green)
+ (vc-deleted red)
+
+ ;; These are extra color variables used only in this theme; i.e. they aren't
+ ;; mandatory for derived themes.
+ (modeline-fg fg)
+ (modeline-fg-inactive (doom-blend blue grey (if doom-vibrant-brighter-modeline 0.9 0.2)))
+ (modeline-bg (if doom-vibrant-brighter-modeline
+ `("#383f58" ,@(cdr base1))
+ `(,(doom-darken (car bg) 0.15) ,@(cdr base1))))
+ (modeline-bg-alt (if doom-vibrant-brighter-modeline
+ modeline-bg
+ `(,(car bg-alt) ,@(cdr base0))))
+ (modeline-bg-inactive `(,(doom-darken (car bg-alt) 0.2) ,@(cdr base0)))
+ (modeline-bg-alt-inactive (doom-darken bg 0.25))
+
+ (-modeline-pad
+ (when doom-vibrant-padded-modeline
+ (if (integerp doom-vibrant-padded-modeline) doom-vibrant-padded-modeline 4))))
+
+
+ ;;;; Base theme face overrides
+ (((font-lock-comment-face &override)
+ :background (if doom-vibrant-brighter-comments (doom-darken bg-alt 0.095)))
+ ((line-number &override) :foreground base4)
+ ((line-number-current-line &override) :foreground blue :bold bold)
+ (mode-line
+ :background modeline-bg :foreground modeline-fg
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg)))
+ (mode-line-inactive
+ :background modeline-bg-inactive :foreground modeline-fg-inactive
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive)))
+ (mode-line-emphasis :foreground (if doom-vibrant-brighter-modeline base8 highlight))
+ (org-block :background (doom-darken base3 0.1))
+
+ ;;;; all-the-icons
+ ((all-the-icons-dblue &override) :foreground dark-cyan)
+ ;;;; centaur-tabs
+ (centaur-tabs-unselected :background bg-alt :foreground base6)
+ ;;;; css-mode <built-in> / scss-mode
+ (css-proprietary-property :foreground orange)
+ (css-property :foreground green)
+ (css-selector :foreground blue)
+ ;;;; doom-modeline
+ (doom-modeline-bar
+ :background (if doom-vibrant-brighter-modeline modeline-bg highlight))
+ (doom-modeline-buffer-path
+ :foreground (if doom-vibrant-brighter-modeline base8 blue) :bold bold)
+ ;;;; elscreen
+ (elscreen-tab-other-screen-face :background "#353a42" :foreground "#1e2022")
+ ;;;; markdown-mode
+ (markdown-header-face :inherit 'bold :foreground red)
+ ;;;; solaire-mode
+ (solaire-mode-line-face
+ :inherit 'mode-line
+ :background modeline-bg-alt
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-alt)))
+ (solaire-mode-line-inactive-face
+ :inherit 'mode-line-inactive
+ :background modeline-bg-alt-inactive
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-alt-inactive)))
+ ;;;; whitespace <built-in>
+ (whitespace-empty :background base2))
+
+ ;;;; Base theme variable overrides
+ ;; ()
+ )
+
+;;; doom-vibrant-theme.el ends here
diff --git a/elpa/doom-themes-20220504.1557/doom-wilmersdorf-theme.el b/elpa/doom-themes-20220504.1557/doom-wilmersdorf-theme.el
new file mode 100644
index 0000000..ce688b4
--- /dev/null
+++ b/elpa/doom-themes-20220504.1557/doom-wilmersdorf-theme.el
@@ -0,0 +1,147 @@
+;;; doom-wilmersdorf-theme.el --- inspired by Atom City Lights -*- lexical-binding: t; no-byte-compile: t; -*-
+(require 'doom-themes)
+
+;;
+(defgroup doom-wilmersdorf-theme nil
+ "Options for the `doom-wilmersdorf' theme."
+ :group 'doom-themes)
+
+(defcustom doom-wilmersdorf-padded-modeline doom-themes-padded-modeline
+ "If non-nil, adds a 4px padding to the mode-line. Can be an integer to
+determine the exact padding."
+ :group 'doom-wilmersdorf-theme
+ :type '(choice integer boolean))
+
+;;
+(def-doom-theme doom-wilmersdorf
+ "A dark theme inspired by Atom City Lights"
+
+ ;; name default 256 16
+ ((bg '("#282b33" "#282b33" nil ))
+ (bg-alt '("#1f2024" "#1f2024" nil ))
+ (base0 '("#222228" "#222228" "black" ))
+ (base1 '("#282b33" "#282b33" "brightblack" ))
+ (base2 '("#34373e" "#34373e" "brightblack" ))
+ (base3 '("#41454b" "#41454b" "brightblack" ))
+ (base4 '("#515462" "#515462" "brightblack" ))
+ (base5 '("#888395" "#888395" "brightblack" ))
+ (base6 '("#929292" "#929292" "brightblack" ))
+ (base7 '("#727269" "#727269" "brightblack" ))
+ (base8 '("#eceff4" "#eceff4" "white" ))
+ (fg-alt '("#c9d9ff" "#c9d9ff" "brightwhite" ))
+ (fg '("#c6c6c6" "#c6c6c6" "white" ))
+
+ (grey base4)
+ (red '("#e1c1ee" "#e1c1ee" "red" ))
+ (orange '("#a6c1e0" "#a6c1e0" "brightred" ))
+ (green '("#5b94ab" "#5b94ab" "green" ))
+ (teal '("#7ebebd" "#7ebebd" "brightgreen" ))
+ (yellow '("#cfcf9c" "#cfcf9c" "yellow" ))
+ (blue '("#819cd6" "#819cd6" "brightblue" ))
+ (light-blue '("#90a6db" "#90a6db" "yellow" ))
+ (dark-blue '("#616c96" "#616c96" "blue" ))
+ (magenta '("#a6c1e0" "#a6c1e0" "magenta" ))
+ (violet '("#b0a2e7" "#b0a2e7" "brightmagenta"))
+ (cyan '("#7289bc" "#7289bc" "brightcyan" ))
+ (dark-cyan '("#6e7899" "#6e7899" "cyan" ))
+
+ ;; face categories -- required for all themes
+ (highlight blue)
+ (vertical-bar (doom-darken base1 0.5))
+ (selection dark-blue)
+ (builtin teal)
+ (comments dark-cyan)
+ (doc-comments (doom-lighten dark-cyan 0.25))
+ (constants magenta)
+ (functions teal)
+ (keywords blue)
+ (methods cyan)
+ (operators blue)
+ (type violet)
+ (strings green)
+ (variables magenta)
+ (numbers magenta)
+ (region base3)
+ (error red)
+ (warning yellow)
+ (success green)
+ (vc-modified orange)
+ (vc-added green)
+ (vc-deleted red)
+
+ ;; custom categories
+ (hidden `(,(car bg) "black" "black"))
+ (-modeline-pad
+ (when doom-wilmersdorf-padded-modeline
+ (if (integerp doom-wilmersdorf-padded-modeline) doom-wilmersdorf-padded-modeline 4)))
+
+ (modeline-fg nil)
+ (modeline-fg-alt base5)
+
+ (modeline-bg
+ `(,(doom-darken (car bg) 0.1) ,@(cdr base0)))
+ (modeline-bg-l
+ `(,(doom-darken (car bg) 0.15) ,@(cdr base0)))
+ (modeline-bg-inactive `(,(car bg) ,@(cdr base1)))
+ (modeline-bg-inactive-l (doom-darken bg 0.1)))
+
+
+ ;;;; Base theme face overrides
+ (((line-number &override) :foreground base4)
+ ((line-number-current-line &override) :foreground fg)
+ (mode-line
+ :background modeline-bg :foreground modeline-fg
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg)))
+ (mode-line-inactive
+ :background modeline-bg-inactive :foreground modeline-fg-alt
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive)))
+ (mode-line-emphasis :foreground highlight)
+ ((mode-line-highlight &override) :background teal)
+
+ ;;;; css-mode <built-in> / scss-mode
+ (css-proprietary-property :foreground orange)
+ (css-property :foreground green)
+ (css-selector :foreground blue)
+ ;;;; doom-modeline
+ (doom-modeline-bar :background highlight)
+ ;;;; elscreen
+ (elscreen-tab-other-screen-face :background "#353a42" :foreground "#1e2022")
+ ;;;; markdown-mode
+ (markdown-markup-face :foreground base5)
+ (markdown-header-face :inherit 'bold :foreground red)
+ (markdown-url-face :foreground teal :weight 'normal)
+ (markdown-reference-face :foreground base6)
+ ((markdown-bold-face &override) :foreground fg)
+ ((markdown-italic-face &override) :foreground fg-alt)
+ ;;;; mic-paren
+ (paren-face-match :foreground teal :background base0 :weight 'ultra-bold)
+ (paren-face-mismatch :foreground red :background violet :weight 'ultra-bold)
+ (paren-face-no-match :inherit 'paren-face-mismatch :weight 'ultra-bold)
+ ;;;; outline <built-in>
+ ((outline-1 &override) :foreground blue)
+ ((outline-2 &override) :foreground green)
+ ((outline-3 &override) :foreground teal)
+ ((outline-4 &override) :foreground (doom-darken blue 0.2))
+ ((outline-5 &override) :foreground (doom-darken green 0.2))
+ ((outline-6 &override) :foreground (doom-darken teal 0.2))
+ ((outline-7 &override) :foreground (doom-darken blue 0.4))
+ ((outline-8 &override) :foreground (doom-darken green 0.4))
+ ;;;; org <built-in>
+ ((org-block &override) :background base2)
+ ((org-block-begin-line &override) :background base2)
+ (org-hide :foreground hidden)
+ ;;;; solaire-mode
+ (solaire-mode-line-face
+ :inherit 'mode-line
+ :background modeline-bg-l
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-l)))
+ (solaire-mode-line-inactive-face
+ :inherit 'mode-line-inactive
+ :background modeline-bg-inactive-l
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive-l))))
+
+ ;;;; Base theme variable overrides-
+ ()
+ )
+
+;;; doom-wilmersdorf-theme.el ends here
diff --git a/elpa/doom-themes-20220504.1557/doom-xcode-theme.el b/elpa/doom-themes-20220504.1557/doom-xcode-theme.el
new file mode 100644
index 0000000..aef30c6
--- /dev/null
+++ b/elpa/doom-themes-20220504.1557/doom-xcode-theme.el
@@ -0,0 +1,111 @@
+;;; doom-xcode-theme.el --- ibased off of Apple's Xcode Dark Theme -*- lexical-binding: t; no-byte-compile: t; -*-
+(require 'doom-themes)
+
+(defgroup doom-xcode-theme nil
+ "Options for the `doom-xcode' theme."
+ :group 'doom-themes)
+
+(defcustom doom-xcode-padded-modeline doom-themes-padded-modeline
+ "If non-nil, adds a 4px padding to the mode-line.
+Can be an integer to determine the exact padding."
+ :group 'doom-xcode-theme
+ :type '(choice integer boolean))
+
+(def-doom-theme doom-xcode
+ "A theme based off of the Xcode Dark Theme"
+
+ ;; name gui 256 16
+ ((bg '("#292A30" nil nil ))
+ (bg-alt '("#252629" nil nil ))
+ (base0 '("#0d0d0d" "black" "black" ))
+ (base1 '("#1b1b1b" "#1b1b1b" ))
+ (base2 '("#212122" "#1e1e1e" ))
+ (base3 '("#292b2b" "#292929" "brightblack"))
+ (base4 '("#3f4040" "#3f3f3f" "brightblack"))
+ (base5 '("#5c5e5e" "#525252" "brightblack"))
+ (base6 '("#757878" "#6b6b6b" "brightblack"))
+ (base7 '("#969896" "#979797" "brightblack"))
+ (base8 '("#ffffff" "#ffffff" "white" ))
+ (fg '("#FFFFFF" "#ffffff" "white"))
+ (fg-alt (doom-darken fg 0.4))
+
+ (red '("#FC6A5D" "#FC6A5D" "red"))
+ (orange '("#FD8F3F" "#FD8F3F" "orange"))
+ (yellow '("#D0BF68" "#D0BF68" "yellow"))
+ (green '("#67B7A4" "#67B7A4" "green"))
+ (blue '("#5DD8FF" "#5DD8FF" "brightblue"))
+ (teal '("#59B0CF" "#59B0CF" "brightblue"))
+ (magenta '("#D0A8FF" "#D0A8FF" "magenta"))
+ (cyan '("#8abeb7" "#8abeb7" "cyan"))
+ (dark-cyan (doom-darken cyan 0.4))
+
+
+ (grey '("#6C7986" "#6C7986" "brightblack"))
+ (light-green'("#9EF1DD" "#9EF1DD" "lightgreen"))
+ (violet '("#A167E6" "#A167E6" "brightmagenta"))
+ (dark-blue '("#41A1C0" "#41A1C0" "darkblue"))
+ (pink '("#FC5FA3" "#FC5FA3" "pink"))
+
+ ;; face categories
+ (highlight blue)
+ (vertical-bar `("#161616" ,@base0))
+ (selection `(,(car (doom-lighten bg 0.1)) ,@(cdr base4)))
+ (builtin light-green)
+ (comments grey)
+ (doc-comments (doom-lighten grey 0.14))
+ (constants violet)
+ (functions dark-blue)
+ (keywords pink)
+ (methods dark-blue)
+ (operators orange)
+ (type blue)
+ (strings red)
+ (variables dark-blue)
+ (numbers yellow)
+ (region selection)
+ (error red)
+ (warning yellow)
+ (success green)
+ (vc-modified fg-alt)
+ (vc-added green)
+ (vc-deleted red)
+
+ ;; custom categories
+ (modeline-bg `(,(doom-darken (car bg-alt) 0.3) ,@(cdr base3)))
+ (modeline-bg-alt `(,(car bg) ,@(cdr base1)))
+ (modeline-fg base8)
+ (modeline-fg-alt comments)
+ (-modeline-pad
+ (when doom-xcode-padded-modeline
+ (if (integerp doom-xcode-padded-modeline)
+ doom-xcode-padded-modeline
+ 4))))
+
+ ;; --- faces ------------------------------
+ (((font-lock-keyword-face &override) :weight 'bold)
+ ((line-number &override) :foreground base4)
+ ((line-number-current-line &override) :foreground orange :weight 'bold)
+ (mode-line
+ :background modeline-bg :foreground modeline-fg
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg)))
+ (mode-line-inactive
+ :background modeline-bg-alt :foreground modeline-fg-alt
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-alt)))
+
+ ;;;; doom-modeline
+ (doom-modeline-buffer-path :foreground dark-blue :bold bold)
+ (doom-modeline-buffer-major-mode :inherit 'doom-modeline-buffer-path)
+ ;;;; rainbow-delimiters
+ (rainbow-delimiters-depth-1-face :foreground violet)
+ (rainbow-delimiters-depth-2-face :foreground blue)
+ (rainbow-delimiters-depth-3-face :foreground orange)
+ (rainbow-delimiters-depth-4-face :foreground green)
+ (rainbow-delimiters-depth-5-face :foreground magenta)
+ (rainbow-delimiters-depth-6-face :foreground yellow)
+ (rainbow-delimiters-depth-7-face :foreground teal))
+
+ ;; --- variables --------------------------
+ ;; ()
+ )
+
+;;; doom-xcode-theme.el ends here
diff --git a/elpa/doom-themes-20220504.1557/doom-zenburn-theme.el b/elpa/doom-themes-20220504.1557/doom-zenburn-theme.el
new file mode 100644
index 0000000..919f71f
--- /dev/null
+++ b/elpa/doom-themes-20220504.1557/doom-zenburn-theme.el
@@ -0,0 +1,341 @@
+;;; doom-zenburn-theme.el --- -*- lexical-binding: t; no-byte-compile: t; -*-
+(require 'doom-themes)
+
+;;
+(defgroup doom-zenburn-theme nil
+ "Options for the `doom-zenburn' theme."
+ :group 'doom-themes)
+
+(defcustom doom-zenburn-brighter-modeline nil
+ "If non-nil, more vivid colors will be used to style the mode-line."
+ :group 'doom-zenburn-theme
+ :type 'boolean)
+
+(defcustom doom-zenburn-brighter-comments nil
+ "If non-nil, comments will be highlighted in more vivid colors."
+ :group 'doom-zenburn-theme
+ :type 'boolean)
+
+(defcustom doom-zenburn-comment-bg doom-zenburn-brighter-comments
+ "If non-nil, comments will have a subtle, darker background.
+Enhances their legibility."
+ :group 'doom-zenburn-theme
+ :type 'boolean)
+
+(defcustom doom-zenburn-padded-modeline doom-themes-padded-modeline
+ "If non-nil, adds a 4px padding to the mode-line.
+Can be an integer to determine the exact padding."
+ :group 'doom-zenburn-theme
+ :type '(choice integer boolean))
+
+;;
+(def-doom-theme doom-zenburn
+ "An implementation of the popular Zenburn theme."
+
+ ;; name default 256 16
+ ((bg '("#3F3F3F" nil nil )) ;; zenburn-bg
+ (bg-alt '("#383838" nil nil )) ;; zenburn-bg-05
+ (base0 '("#000000" "black" "black" )) ;; zenburn-bg-2
+ (base1 '("#2B2B2B" "#1e1e1e" "brightblack" )) ;; zenburn-bg-1
+ (base2 '("#303030" "#2e2e2e" "brightblack" )) ;; zenburn-bg-08
+ (base3 '("#383838" "#262626" "brightblack" )) ;; zenburn-bg-05
+ (base4 '("#494949" "#3f3f3f" "brightblack" )) ;; zenburn-bg+05
+ (base5 '("#4F4F4F" "#525252" "brightblack" )) ;; zenburn-bg+1
+ (base6 '("#5F5F5F" "#6b6b6b" "brightblack" )) ;; zenburn-bg+2
+ (base7 '("#6F6F6F" "#979797" "brightblack" )) ;; zenburn-bg+3
+ (base8 '("#FFFFEF" "#dfdfdf" "white" )) ;; zenburn-fg+1
+ (fg '("#DCDCDC" "#bfbfbf" "brightwhite" )) ;; zenburn-fg
+ (fg-alt '("#989890" "#2d2d2d" "white" )) ;; zenburn-fg-05
+
+ (grey base4)
+ (red '("#CC9393" "#ff6655" "red" )) ;; zenburn-red
+ (orange '("#DFAF8F" "#dd8844" "brightred" )) ;; zenburn-orange
+ (green '("#7F9F7F" "#99bb66" "green" )) ;; zenburn-green
+ (teal '("#4db5bd" "#44b9b1" "brightgreen" )) ;; zenburn-??
+ (yellow '("#F0DFAF" "#ECBE7B" "yellow" )) ;; zenburn-yellow
+ (blue '("#8CD0D3" "#51afef" "brightblue" )) ;; zenburn-blue
+ (dark-blue '("#2257A0" "#2257A0" "blue" )) ;; zenburn-??
+ (magenta '("#DC8CC3" "#c678dd" "brightmagenta")) ;; zenburn-magenta
+ (violet '("#a9a1e1" "#a9a1e1" "magenta" )) ;; zendurn-??
+ (cyan '("#93E0E3" "#46D9FF" "brightcyan" )) ;; zenburn-cyan
+ (dark-cyan '("#5699AF" "#5699AF" "cyan" )) ;; zenburn-??
+
+ ;; Extra zenburn colors
+ (fg-1 '("#656555"))
+ (fg+2 '("#FFFFFD"))
+ (red-4 '("#8C5353"))
+ (red-1 '("#BC8383"))
+ (red+1 '("#DCA3A3"))
+ (yellow-2 '("#D0BF8F"))
+ (yellow-1 '("#E0CF9F"))
+ (green-2 '("#5F7F5F"))
+ (green+1 '("#8FB28F"))
+ (green+2 '("#9FC59F"))
+ (green+3 '("#AFD8AF"))
+ (green+4 '("#BFEBBF"))
+ (blue+1 '("#94BFF3"))
+ (blue-1 '("#7CB8BB"))
+ (blue-2 '("#6CA0A3"))
+ (blue-3 '("#5C888B"))
+ (blue-4 '("#4C7073"))
+ (blue-5 '("#366060"))
+
+ ;; face categories -- required for all themes
+ (highlight blue)
+ (vertical-bar (doom-darken base1 0.1))
+ (selection dark-blue)
+ (builtin fg)
+ (comments green)
+ (doc-comments green+2)
+ (constants green+4)
+ (functions cyan)
+ (keywords yellow)
+ (methods cyan)
+ (operators blue)
+ (type blue-1)
+ (strings red)
+ (variables orange)
+ (numbers fg)
+ (region base1)
+ (error red)
+ (warning yellow)
+ (success green)
+ (vc-modified orange)
+ (vc-added green)
+ (vc-deleted red)
+
+ ;; custom categories
+ (hidden `(,(car bg) "black" "black"))
+ (-modeline-bright doom-zenburn-brighter-modeline)
+ (-modeline-pad
+ (when doom-zenburn-padded-modeline
+ (if (integerp doom-zenburn-padded-modeline) doom-zenburn-padded-modeline 4)))
+
+ (modeline-fg green+1)
+ (modeline-fg-alt `(,(car fg-alt) ,@(cdr base6)))
+
+ (modeline-bg
+ (if -modeline-bright
+ (doom-darken blue 0.475)
+ base1))
+ (modeline-bg-l
+ (if -modeline-bright
+ (doom-darken blue 0.45)
+ bg))
+ (modeline-bg-inactive `(,(doom-lighten (car modeline-bg) 0.05) ,@(cdr base1)))
+ (modeline-bg-inactive-l `(,(car bg-alt) ,@(cdr base1))))
+
+
+ ;;;; Base theme face overrides
+ ((cursor :foreground fg :background base8)
+ (escape-glyph :foreground yellow :weight 'bold)
+ (font-lock-builtin-face :foreground fg :weight 'bold)
+ (font-lock-comment-delimiter-face :foreground green-2)
+ ((font-lock-comment-face &override)
+ :background (if doom-zenburn-comment-bg (doom-lighten bg 0.05)))
+ (font-lock-constant-face :foreground green+4)
+ (font-lock-doc-face :foreground green+2)
+ (font-lock-type-face :foreground blue-1)
+ (font-lock-warning-face :foreground yellow-1 :weight 'bold)
+ (font-lock-keyword-face :foreground yellow :weight 'bold)
+ (highlight :background base4)
+ (isearch :freground yellow-2 :weight 'bold :background base6)
+ (isearch-fail :foreground fg :background red-4)
+ (lazy-highlight :foreground yellow-2 :weight 'bold :background base3)
+ ((line-number &override) :foreground base7)
+ ((line-number-current-line &override) :foreground yellow-2)
+ (link :foreground yellow-2 :underline t :weight 'bold)
+ (minibuffer-prompt :foreground yellow)
+ (mode-line
+ :background modeline-bg :foreground modeline-fg
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg)))
+ (mode-line-inactive
+ :background modeline-bg-inactive :foreground modeline-fg-alt
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive)))
+ (mode-line-emphasis :foreground (if -modeline-bright base8 highlight))
+ (success :foreground green :weight 'bold)
+ (tooltip :foreground fg :background base5)
+ (vertical-border :foreground fg-1) ;; different
+ (warning :foreground orange :weight 'bold)
+ (widget-field :foreground fg :background base7)
+
+ ;;;; compilation
+ (compilation-error-face :inherit error :underline t)
+ (compilation-info :foreground blue)
+ (compilation-line-number :foreground yellow)
+ (compilation-warning-face :foreground yellow)
+ (compilation-mode-line-exit :foreground green+2 :weight 'bold)
+ ;;;; calfw
+ (cfw:face-default-content :foreground green)
+ (cfw:face-disable :foreground fg-1)
+ (cfw:face :inherit 'shadow)
+ (cfw:face :inherit 'font-lock-keyword-face)
+ (cfw:face-sunday :foreground red :weight 'bold)
+ (cfw:face :inherit 'cfw:face-sunday)
+ (cfw:face-periods :foreground cyan)
+ (cfw:face-select :background blue-5)
+ (cfw:face-saturday :foreground blue :weight 'bold)
+ (cfw:face-select :background blue-5)
+ (cfw:face-title :height 2.0 :inherit '(variable-pitch font-lock-keyword-face))
+ (cfw:face-today :foreground cyan :weight 'bold)
+ (cfw:face-toolbar-button-off :underline nil :inherit 'link)
+ (cfw:face-toolbar-button-on :underline nil :inherit 'link-visited)
+ ;;;; company
+ (company-tooltip-selection :background base6)
+ (company-scrollbar-fg :background base7)
+ (company-tooltip-annotation :foreground green :distant-foreground green)
+ ;;;; centaur-tabs
+ (centaur-tabs-selected :background bg :foreground fg+2)
+ (centaur-tabs-unselected :background base1 :foreground fg-alt)
+ (centaur-tabs-selected-modified :background bg :foreground orange)
+ (centaur-tabs-unselected-modified :background base1 :foreground orange)
+ (centaur-tabs-active-bar-face :background yellow)
+ (centaur-tabs-modified-marker-selected :inherit 'centaur-tabs-selected-modified :foreground yellow)
+ (centaur-tabs-modified-marker-unselected :inherit 'centaur-tabs-unselected-modified :foreground yellow)
+ ;;;; css-mode <built-in> / scss-mode
+ (css-proprietary-property :foreground orange)
+ (css-property :foreground green)
+ (css-selector :foreground blue)
+ ;;;; custom
+ (custom-variable-tag :foreground blue :weight 'bold)
+ (custom-group-tag :foreground blue :weight 'bold)
+ (custom-state :foreground green+4)
+ ;;;; diff-hl
+ (diff-hl-change :foreground blue :background blue-2)
+ (diff-hl-delete :foreground red+1 :background red-1)
+ (diff-hl-insert :foreground green+1 :background green-2)
+ ;;;; doom-modeline
+ (doom-modeline-bar :background yellow)
+ (doom-modeline-buffer-file :inherit 'mode-line-buffer-id :weight 'bold)
+ (doom-modeline-buffer-path :inherit 'mode-line-emphasis :weight 'bold)
+ (doom-modeline-buffer-project-root :foreground green :weight 'bold)
+ ;;;; elscreen
+ (elscreen-tab-other-screen-face :background "#353a42" :foreground "#1e2022")
+ ;;;; fill-column
+ (fill-column-indicator :foreground base4 :weight 'semilight)
+ ;;;; flycheck
+ (flycheck-error :underline `(:style wave :color ,red-1) :weight 'bold)
+ (flycheck-warning :underline `(:style wave :color ,yellow) :weight 'bold)
+ (flycheck-info :underline `(:style wave :color ,cyan) :weight 'bold)
+ ;;;; git-commit
+ (git-commit-comment-action :foreground green+1 :weight 'bold)
+ (git-commit-comment-branch :foreground blue+1 :weight 'bold)
+ (git-commit-comment-branch-local :foreground blue+1 :weight 'bold)
+ ;;;; git-gutter
+ (git-gutter:added :foreground green :weight 'bold)
+ (git-gutter:deleted :foreground red :weight 'bold)
+ (git-gutter:modified :foreground magenta :weight 'bold)
+ ;;;; hi-lock
+ (hi-green :background green+4 :background base1)
+ (hi-green-b :foreground green+2 :weight 'bold)
+ ;;;; highlight-symbol
+ (highlight-symbol-face :background base6)
+ ;;;; highlight-thing
+ (highlight-thing :background base6)
+ ;;;; helm
+ (helm-header :foreground yellow :background base1 :weight 'bold :extend t)
+ (helm-source-header :foreground yellow :background base1 :weight 'bold :extend t)
+ (helm-selection :background base5)
+ (helm-selection-line :background base5)
+ (helm-visible-mark :foreground bg :background yellow-2)
+ (helm-candidate-number :foreground green+4 :background base1)
+ (helm-separator :foreground red :background bg)
+ (helm-time-zone-current :foreground green+2 :background bg)
+ (helm-time-zone-home :foreground red :background bg)
+ (helm-buffer-not-saved :foreground red :background bg)
+ (helm-buffer-process :foreground cyan :background bg)
+ (helm-buffer-saved-out :foreground fg :background bg)
+ (helm-buffer-size :foreground fg-1 :background bg)
+ (helm-ff-directory :foreground cyan :weight 'bold)
+ (helm-ff-executable :foreground green+2 :background bg :weight 'normal)
+ (helm-ff-invalid-symlink :foreground red :background bg :weight 'bold)
+ (helm-ff-symlink :foreground yellow :background bg :weight 'bold)
+ (helm-ff-prefix :foreground bg :background yellow :weight 'normal)
+ (helm-grep-cmd-line :foreground cyan :background bg)
+ (helm-grep-file :foreground fg :background bg)
+ (helm-grep-finish :foreground green+2 :background bg)
+ (helm-grep-lineno :foreground fg-1 :background bg)
+ (helm-grep-match :foreground 'nil :background 'nil :inherit 'helm-match)
+ (helm-grep-running :foreground red :background bg)
+ (helm-match :foreground orange :background base1 :weight 'bold)
+ (helm-swoop-target-line-face :foreground fg :background base6)
+ (helm-swoop-target-word-face :foreground yellow :background base6 :weight 'bold)
+ ;;;; ivy
+ (ivy-current-match :background bg-alt :weight 'bold)
+ (ivy-minibuffer-match-face-2 :foreground green+4 :weight 'bold)
+ ;;;; js2-mode
+ (js2-jsdoc-tag :foreground green-2)
+ (js2-jsdoc-type :foreground green+2)
+ (js2-jsdoc-value :foreground green+3)
+ (js2-exernal-variable :foreground orange)
+ (js2-instance-member :foreground green-2)
+ (js2-jsdoc-html-tag-delimiter :foreground orange)
+ (js2-jsdoc-html-tag-name :foreground red-1)
+ (js2-object-property :foreground blue+1)
+ (js2-magic-paren :foreground blue-5)
+ (js2-private-function-call :foreground cyan)
+ (js2-function-call :foreground cyan)
+ (js2-private-member :foreground blue-1)
+ (js2-keywords :foreground magenta)
+ ;;;; lui
+ (lui-time-stampe-face :foreground blue-1)
+ (lui-hilight-face :foreground green+2 :background bg)
+ (lui-button-face :inherit 'hover-highlight)
+ ;;;; markdown-mode
+ (markdown-markup-face :foreground base5)
+ (markdown-header-face :inherit 'bold :foreground red)
+ ((markdown-code-face &override) :background (doom-lighten base3 0.05))
+ ;;;; mic-paren
+ (paren-face-match :foreground cyan :background bg :weight 'bold)
+ (paren-face-mismatch :foreground bg :background magenta :weight 'bold)
+ (paren-face-no-match :foreground bg :background red :weight 'bold)
+ ;;;; minibuffer
+ (completion-annotations :foreground fg-1)
+ ;;;; outline <built-in>
+ (outline-1 :foreground orange)
+ (outline-2 :foreground green+4)
+ (outline-3 :foreground blue-1)
+ (outline-4 :foreground yellow-2)
+ (outline-5 :foreground cyan)
+ (outline-6 :foreground green+2)
+ (outline-7 :foreground red-4)
+ (outline-8 :foreground blue-4)
+ ;;;; rpm-model
+ (rpm-doc-face :foreground green)
+ (rpm-ghost-face :foreground red)
+ (rpm-package-face :foreground red)
+ (rpm-package-section-face :foreground yellow)
+ ;;;; rst-mode <built-in>
+ (rst-level-1-face :foreground orange)
+ (rst-level-2-face :foreground green+1)
+ (rst-level-3-face :foreground blue-1)
+ (rst-level-4-face :foreground yellow-2)
+ (rst-level-5-face :foreground cyan)
+ (rst-level-6-face :foreground green-2)
+ ;;;; solaire-mode
+ (solaire-default-face :inherit 'default :background base2)
+ (solaire-hl-line-face :inherit 'hl-line :background bg)
+ (solaire-minibuffer-face :inherit 'default :background base2)
+ (solaire-mode-line-face
+ :inherit 'mode-line
+ :background modeline-bg-l
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-l)))
+ (solaire-mode-line-inactive-face
+ :inherit 'mode-line-inactive
+ :background modeline-bg-inactive-l
+ :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive-l)))
+ ;;;; web-mode
+ (web-mode-html-attr-name-face :foreground orange)
+ (web-mode-css-pseudo-class-face :foreground green+3 :weight 'bold)
+ (web-mode-css-at-rule-face :foreground orange )
+ (web-mode-function-name-face :foreground blue)
+ (web-mode-html-attr-value-face :inherit 'font-lock-string-face)
+ (web-mode-whitespaces-face :background red)
+ ;;;; woman <built-in>
+ (woman :inherit 'font-lock-keyword-face)
+ (woman :inherit 'font-lock-string-face italic))
+
+ ;;;; Base theme variable overrides-
+ ())
+
+;;; doom-zenburn-theme.el ends here
diff --git a/elpa/emmet-mode-20210820.1124/emmet-mode-autoloads.el b/elpa/emmet-mode-20210820.1124/emmet-mode-autoloads.el
new file mode 100644
index 0000000..250d0b2
--- /dev/null
+++ b/elpa/emmet-mode-20210820.1124/emmet-mode-autoloads.el
@@ -0,0 +1,94 @@
+;;; emmet-mode-autoloads.el --- automatically extracted autoloads -*- lexical-binding: t -*-
+;;
+;;; Code:
+
+(add-to-list 'load-path (directory-file-name
+ (or (file-name-directory #$) (car load-path))))
+
+
+;;;### (autoloads nil "emmet-mode" "emmet-mode.el" (0 0 0 0))
+;;; Generated autoloads from emmet-mode.el
+
+(autoload 'emmet-expand-line "emmet-mode" "\
+Replace the current line's emmet expression with the corresponding expansion.
+If prefix ARG is given or region is visible call `emmet-preview' to start an
+interactive preview.
+
+Otherwise expand line directly.
+
+For more information see `emmet-mode'.
+
+\(fn ARG)" t nil)
+
+(autoload 'emmet-mode "emmet-mode" "\
+Minor mode for writing HTML and CSS markup.
+With emmet for HTML and CSS you can write a line like
+
+This is a minor mode. If called interactively, toggle the `Emmet
+mode' mode. If the prefix argument is positive, enable the mode,
+and if it is zero or negative, disable the mode.
+
+If called from Lisp, toggle the mode if ARG is `toggle'. Enable
+the mode if ARG is nil, omitted, or is a positive number.
+Disable the mode if ARG is a negative number.
+
+To check whether the minor mode is enabled in the current buffer,
+evaluate `emmet-mode'.
+
+The mode's hook is called both when the mode is enabled and when
+it is disabled.
+
+ ul#name>li.item*2
+
+and have it expanded to
+
+ <ul id=\"name\">
+ <li class=\"item\"></li>
+ <li class=\"item\"></li>
+ </ul>
+
+This minor mode defines keys for quick access:
+
+\\{emmet-mode-keymap}
+
+Home page URL `http://www.emacswiki.org/emacs/Emmet'.
+
+See also `emmet-expand-line'.
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'emmet-expand-yas "emmet-mode" nil t nil)
+
+(autoload 'emmet-preview "emmet-mode" "\
+Expand emmet between BEG and END interactively.
+This will show a preview of the expanded emmet code and you can
+accept it or skip it.
+
+\(fn BEG END)" t nil)
+
+(autoload 'emmet-wrap-with-markup "emmet-mode" "\
+Wrap region with markup.
+
+\(fn WRAP-WITH)" t nil)
+
+(autoload 'emmet-next-edit-point "emmet-mode" "\
+
+
+\(fn COUNT)" t nil)
+
+(autoload 'emmet-prev-edit-point "emmet-mode" "\
+
+
+\(fn COUNT)" t nil)
+
+(register-definition-prefixes "emmet-mode" '("emmet-"))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; coding: utf-8
+;; End:
+;;; emmet-mode-autoloads.el ends here
diff --git a/elpa/emmet-mode-20210820.1124/emmet-mode-pkg.el b/elpa/emmet-mode-20210820.1124/emmet-mode-pkg.el
new file mode 100644
index 0000000..a717e91
--- /dev/null
+++ b/elpa/emmet-mode-20210820.1124/emmet-mode-pkg.el
@@ -0,0 +1,2 @@
+;;; Generated package description from emmet-mode.el -*- no-byte-compile: t -*-
+(define-package "emmet-mode" "20210820.1124" "Unofficial Emmet's support for emacs" 'nil :commit "6b2e554f7fd27f732810f4b14ea01e3c54b7b3da" :authors '(("Shin Aoyama" . "smihica@gmail.com")) :maintainer '("Shin Aoyama" . "smihica@gmail.com") :keywords '("convenience") :url "https://github.com/smihica/emmet-mode")
diff --git a/elpa/emmet-mode-20210820.1124/emmet-mode.el b/elpa/emmet-mode-20210820.1124/emmet-mode.el
new file mode 100644
index 0000000..77544f6
--- /dev/null
+++ b/elpa/emmet-mode-20210820.1124/emmet-mode.el
@@ -0,0 +1,4274 @@
+;;; emmet-mode.el --- Unofficial Emmet's support for emacs
+
+;; Copyright (C) 2014- Dmitry Mukhutdinov (@flyingleafe https://github.com/flyingleafe)
+;; Copyright (C) 2014- William David Mayo (@pbocks https://github.com/pobocks)
+;; Copyright (C) 2013- Shin Aoyama (@smihica https://github.com/smihica)
+;; Copyright (C) 2009-2012 Chris Done
+
+;; Version: 1.0.10
+;; Package-Version: 20210820.1124
+;; Package-Commit: 6b2e554f7fd27f732810f4b14ea01e3c54b7b3da
+;; Author: Shin Aoyama <smihica@gmail.com>
+;; URL: https://github.com/smihica/emmet-mode
+;; Last-Updated: 2014-08-11 Mon
+;; Keywords: convenience
+
+;; 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 3, 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 GNU Emacs; see the file COPYING. If not, write to
+;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Commentary:
+;;
+;; Unfold CSS-selector-like expressions to markup. Intended to be used
+;; with sgml-like languages; xml, html, xhtml, xsl, etc.
+;;
+;; See `emmet-mode' for more information.
+;;
+;; Copy emmet-mode.el to your load-path and add to your .emacs:
+;;
+;; (require 'emmet-mode)
+;;
+;; Example setup:
+;;
+;; (add-to-list 'load-path "~/Emacs/emmet/")
+;; (require 'emmet-mode)
+;; (add-hook 'sgml-mode-hook 'emmet-mode) ;; Auto-start on any markup modes
+;; (add-hook 'html-mode-hook 'emmet-mode)
+;; (add-hook 'css-mode-hook 'emmet-mode)
+;;
+;; Enable the minor mode with M-x emmet-mode.
+;;
+;; See ``Test cases'' section for a complete set of expression types.
+;;
+;; If you are hacking on this project, eval (emmet-test-cases) to
+;; ensure that your changes have not broken anything. Feel free to add
+;; new test cases if you add new features.
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; History:
+;;
+;; This is a fork of zencoding-mode to support Emmet's feature.
+;; zencoding-mode (https://github.com/rooney/zencoding)
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Code:
+
+(defconst emmet-mode:version "1.0.10")
+
+(with-no-warnings
+ (require 'cl))
+
+;; for portability with < 24.3 EMACS
+(unless (fboundp 'cl-labels) (fset 'cl-labels 'labels))
+(unless (fboundp 'cl-flet) (fset 'cl-flet 'flet))
+;; < 22.1
+(unless (fboundp 'string-to-number) (fset 'string-to-number 'string-to-int))
+
+(defmacro emmet-defparameter (symbol &optional initvalue docstring)
+ `(progn
+ (defvar ,symbol nil ,docstring)
+ (setq ,symbol ,initvalue)))
+
+(defun emmet-join-string (lis joiner)
+ (mapconcat 'identity lis joiner))
+
+(defun emmet-get-keys-of-hash (hash)
+ (let ((ks nil))
+ (maphash #'(lambda (k v) (setq ks (cons k ks))) hash)
+ ks))
+
+(defun emmet-get-vals-of-hash (hash)
+ (let ((vs nil))
+ (maphash #'(lambda (k v) (setq vs (cons v vs))) hash)
+ vs))
+
+(defun emmet-jsx-prop-value-var? (prop-value)
+ (string-match "{.+}" prop-value))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Generic parsing macros and utilities
+
+(defmacro emmet-aif (test-form then-form &rest else-forms)
+ "Anaphoric if. Temporary variable `it' is the result of test-form."
+ `(let ((it ,test-form))
+ (if it ,then-form ,@(or else-forms '(it)))))
+
+(defmacro emmet-pif (test-form then-form &rest else-forms)
+ "Parser anaphoric if. Temporary variable `it' is the result of test-form."
+ `(let ((it ,test-form))
+ (if (not (eq 'error (car it))) ,then-form ,@(or else-forms '(it)))))
+
+(defmacro emmet-parse (regex nums label &rest body)
+ "Parse according to a regex and update the `input' variable."
+ `(emmet-aif (emmet-regex ,regex input ',(number-sequence 0 nums))
+ (let ((input (elt it ,nums)))
+ ,@body)
+ `,`(error ,(concat "expected " ,label))))
+
+(defmacro emmet-run (parser then-form &rest else-forms)
+ "Run a parser and update the input properly, extract the parsed
+ expression."
+ `(emmet-pif (,parser input)
+ (let ((input (cdr it))
+ (expr (car it)))
+ ,then-form)
+ ,@(or else-forms '(it))))
+
+(defmacro emmet-por (parser1 parser2 then-form &rest else-forms)
+ "OR two parsers. Try one parser, if it fails try the next."
+ `(emmet-pif (,parser1 input)
+ (let ((input (cdr it))
+ (expr (car it)))
+ ,then-form)
+ (emmet-pif (,parser2 input)
+ (let ((input (cdr it))
+ (expr (car it)))
+ ,then-form)
+ ,@else-forms)))
+
+(defmacro emmet-find (direction regexp &optional limit-of-search repeat-count)
+ "Regexp-search in given direction, returning the position (or nil)
+and leaving the point in place."
+ `(save-excursion
+ (if (,(intern (concat "re-search-" direction))
+ ,regexp ,limit-of-search t ,repeat-count)
+ (match-beginning 0))))
+
+(defun emmet-regex (regexp string refs)
+ "Return a list of (`ref') matches for a `regex' on a `string' or nil."
+ (if (string-match (concat "^" regexp "\\([^\n]*\\)$") string)
+ (mapcar (lambda (ref) (match-string ref string))
+ (if (sequencep refs) refs (list refs)))
+ nil))
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Emmet minor mode
+
+(defgroup emmet nil
+ "Customization group for emmet-mode."
+ :group 'convenience)
+
+(defun emmet-expr-on-line ()
+ "Extract a emmet expression and the corresponding bounds
+ for the current line."
+ (let* ((end (point))
+ (start (emmet-find-left-bound))
+ (line (buffer-substring-no-properties start end))
+ (expr (emmet-regex "\\([ \t]*\\)\\([^\n]+\\)" line 2)))
+ (if (first expr)
+ (list (first expr) start end))))
+
+(defun emmet-find-left-bound ()
+ "Find the left bound of an emmet expr"
+ (save-excursion (save-match-data
+ (let ((char (char-before))
+ (in-style-attr (looking-back "style=[\"'][^\"']*" nil))
+ (syn-tab (make-syntax-table)))
+ (modify-syntax-entry ?\\ "\\")
+ (while char
+ (cond ((and in-style-attr (member char '(?\" ?\')))
+ (setq char nil))
+ ((member char '(?\} ?\] ?\)))
+ (with-syntax-table syn-tab
+ (backward-sexp) (setq char (char-before))))
+ ((eq char ?\>)
+ (if (looking-back "<[^>]+>" (line-beginning-position))
+ (setq char nil)
+ (progn (backward-char) (setq char (char-before)))))
+ ((not (string-match-p "[[:space:]\n;]" (string char)))
+ (backward-char) (setq char (char-before)))
+ (t
+ (setq char nil))))
+ (point)))))
+
+(defcustom emmet-indentation 4
+ "Number of spaces used for indentation."
+ :type '(number :tag "Spaces")
+ :group 'emmet)
+
+(defcustom emmet-indent-after-insert t
+ "Indent region after insert?"
+ :type 'boolean
+ :group 'emmet)
+
+(defcustom emmet-use-style-tag-and-attr-detection t
+ "When true, enables detection of style tags and attributes in HTML
+to provide proper CSS abbreviations completion."
+ :type 'boolean
+ :group 'emmet)
+
+(defcustom emmet-self-closing-tag-style "/"
+ "Self-closing tags style.
+
+This determines how Emmet expands self-closing tags.
+
+E.g., FOO is a self-closing tag. When expanding \"FOO\":
+
+When \" /\", the expansion is \"<FOO />\".
+When \"/\", the expansion is \"<FOO/>\".
+When \"\", the expansion is \"<FOO>\".
+
+Default value is \"/\".
+
+NOTE: only \" /\", \"/\" and \"\" are valid."
+ :type '(choice (const :tag " />" " /")
+ (const :tag "/>" "/")
+ (const :tag ">" ""))
+ :group 'emmet)
+
+(defvar emmet-use-css-transform nil
+ "When true, transform Emmet snippets into CSS, instead of the usual HTML.")
+(make-variable-buffer-local 'emmet-use-css-transform)
+
+(defvar emmet-use-sass-syntax nil
+ "When true, uses Sass syntax for CSS abbreviations expanding,
+e. g. without semicolons")
+(make-variable-buffer-local 'emmet-use-sass-syntax)
+
+
+(defvar emmet-css-major-modes
+ '(css-mode
+ scss-mode
+ sass-mode
+ less-mode
+ less-css-mode)
+ "Major modes that use emmet for CSS, rather than HTML.")
+
+(defvar emmet-fallback-filter '("html")
+ "Fallback filter for `emmet-default-filter', if none is found.")
+
+(defvar emmet-file-filter nil
+ "File local filter used by `emmet-default-filter'.")
+(make-variable-buffer-local 'emmet-file-filter)
+
+(defvar emmet-jsx-major-modes
+ '(rjsx-mode
+ typescript-tsx-mode
+ js-jsx-mode
+ js2-jsx-mode
+ jsx-mode
+ js-mode)
+ "Which modes to check before using jsx class expansion")
+
+(defun emmet-transform (input)
+ (if (or (emmet-detect-style-tag-and-attr) emmet-use-css-transform)
+ (emmet-css-transform input)
+ (emmet-html-transform input)))
+
+(defun emmet-detect-style-tag-and-attr ()
+ (let* ((style-attr-end "[^=][\"']")
+ (style-attr-begin "style=[\"']")
+ (style-tag-end "</style>")
+ (style-tag-begin "<style>"))
+ (and emmet-use-style-tag-and-attr-detection
+ (or
+ (emmet-check-if-between style-attr-begin style-attr-end) ; style attr
+ (emmet-check-if-between style-tag-begin style-tag-end))))) ; style tag
+
+(defun emmet-check-if-between (begin end)
+ (let ((begin-back (emmet-find "backward" begin))
+ (end-back (emmet-find "backward" end))
+ (begin-front (emmet-find "forward" begin))
+ (end-front (emmet-find "forward" end)))
+ (and begin-back end-front
+ (or (not end-back) (> begin-back end-back))
+ (or (not begin-front) (< end-front begin-front)))))
+
+(defcustom emmet-preview-default nil
+ "If non-nil then preview is the default action.
+This determines how `emmet-expand-line' works by default."
+ :type 'boolean
+ :group 'emmet)
+
+;;;###autoload
+(defun emmet-expand-line (arg)
+ "Replace the current line's emmet expression with the corresponding expansion.
+If prefix ARG is given or region is visible call `emmet-preview' to start an
+interactive preview.
+
+Otherwise expand line directly.
+
+For more information see `emmet-mode'."
+ (interactive "P")
+ (let* ((here (point))
+ (preview (if emmet-preview-default (not arg) arg))
+ (beg (if preview
+ (emmet-find-left-bound)
+ (when (use-region-p) (region-beginning))))
+ (end (if preview
+ here
+ (when (use-region-p) (region-end)))))
+ (if (and preview beg)
+ (progn
+ (goto-char here)
+ (emmet-preview beg end))
+ (let ((expr (emmet-expr-on-line)))
+ (if expr
+ (let ((markup (emmet-transform (first expr))))
+ (when markup
+ (delete-region (second expr) (third expr))
+ (emmet-insert-and-flash markup)
+ (emmet-reposition-cursor expr))))))))
+
+(defvar emmet-mode-keymap
+ (let
+ ((map (make-sparse-keymap)))
+ (define-key map (kbd "C-j") 'emmet-expand-line)
+ (define-key map (kbd "<C-return>") 'emmet-expand-line)
+ (define-key map (kbd "<C-M-right>") 'emmet-next-edit-point)
+ (define-key map (kbd "<C-M-left>") 'emmet-prev-edit-point)
+ (define-key map (kbd "C-c C-c w") 'emmet-wrap-with-markup)
+ map)
+ "Keymap for emmet minor mode.")
+
+(defun emmet-after-hook ()
+ "Initialize Emmet's buffer-local variables."
+ (if (memq major-mode emmet-css-major-modes)
+ (setq emmet-use-css-transform t))
+ (if (eq major-mode 'sass-mode)
+ (setq emmet-use-sass-syntax t)))
+
+;;;###autoload
+(define-minor-mode emmet-mode
+ "Minor mode for writing HTML and CSS markup.
+With emmet for HTML and CSS you can write a line like
+
+ ul#name>li.item*2
+
+and have it expanded to
+
+ <ul id=\"name\">
+ <li class=\"item\"></li>
+ <li class=\"item\"></li>
+ </ul>
+
+This minor mode defines keys for quick access:
+
+\\{emmet-mode-keymap}
+
+Home page URL `http://www.emacswiki.org/emacs/Emmet'.
+
+See also `emmet-expand-line'."
+ :lighter (" Emmet" (:eval (if emmet-preview-mode "[P]" "")))
+ :keymap emmet-mode-keymap
+ :after-hook (emmet-after-hook))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Emmet yasnippet integration
+
+(defun emmet-transform-yas (input)
+ (let* ((leaf-count 0)
+ (emmet-leaf-function
+ (lambda ()
+ (format "$%d" (cl-incf leaf-count)))))
+ (emmet-transform input)))
+
+;;;###autoload
+(defun emmet-expand-yas ()
+ (interactive)
+ (let ((expr (emmet-expr-on-line)))
+ (if expr
+ (let* ((markup (emmet-transform-yas (first expr)))
+ (filled (replace-regexp-in-string "><" ">\n<" markup)))
+ (delete-region (second expr) (third expr))
+ (insert filled)
+ (indent-region (second expr) (point))
+ (if (fboundp 'yas/expand-snippet)
+ (yas/expand-snippet
+ (buffer-substring (second expr) (point))
+ (second expr) (point)))))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; Real-time preview
+;;
+
+;;;;;;;;;;
+;; Lennart's version
+
+(defvar emmet-preview-input nil)
+(make-local-variable 'emmet-preview-input)
+(defvar emmet-preview-output nil)
+(make-local-variable 'emmet-preview-output)
+(defvar emmet-old-show-paren nil)
+(make-local-variable 'emmet-old-show-paren)
+
+(defface emmet-preview-input
+ '((default :box t :inherit secondary-selection))
+ "Face for preview input field."
+ :group 'emmet)
+
+(defface emmet-preview-output
+ '((default :inherit highlight))
+ "Face for preview output field."
+ :group 'emmet)
+
+(defvar emmet-preview-keymap
+ (let ((map (make-sparse-keymap)))
+ (define-key map (kbd "RET") 'emmet-preview-accept)
+ (define-key map (kbd "<return>") 'emmet-preview-accept)
+ (define-key map [(control ?g)] 'emmet-preview-abort)
+ map))
+
+(defun emmet-html-text-p (markup)
+ (string-match "^[\s|\t|\n|\r]*<.*$" markup))
+
+(defun emmet-preview-accept ()
+ (interactive)
+ (let ((ovli emmet-preview-input)
+ (expr (emmet-expr-on-line)))
+ (if (not (and (overlayp ovli)
+ (bufferp (overlay-buffer ovli))))
+ (message "Preview is not active")
+ (let* ((indent (current-indentation))
+ (markup (emmet-preview-transformed indent)))
+ (when markup
+ (delete-region (overlay-start ovli) (overlay-end ovli))
+ (emmet-insert-and-flash markup)
+ (emmet-reposition-cursor expr)))))
+ (emmet-preview-abort))
+
+(defun emmet-html-next-insert-point (str)
+ (with-temp-buffer
+ (insert str)
+ (goto-char (point-min))
+ (or
+ (emmet-aif (emmet-go-to-edit-point 1 t) (- it 1)) ; try to find an edit point
+ (emmet-aif (re-search-forward ".+</" nil t) (- it 3)) ; try to place cursor after tag contents
+ (length str)))) ; ok, just go to the end
+
+(defun emmet-css-next-insert-point (str)
+ (let ((regexp (if emmet-use-sass-syntax ": *\\($\\)" ": *\\(;\\)$")))
+ (save-match-data
+ (set-match-data nil t)
+ (string-match regexp str)
+ (or (match-beginning 1) (length str)))))
+
+(defvar emmet-flash-ovl nil)
+(make-variable-buffer-local 'emmet-flash-ovl)
+
+(defun emmet-remove-flash-ovl (buf)
+ (with-current-buffer buf
+ (when (overlayp emmet-flash-ovl)
+ (delete-overlay emmet-flash-ovl))
+ (setq emmet-flash-ovl nil)))
+
+(defcustom emmet-insert-flash-time 0.5
+ "Time to flash insertion.
+Set this to a negative number if you do not want flashing the
+expansion after insertion."
+ :type '(number :tag "Seconds")
+ :group 'emmet)
+
+(defcustom emmet-move-cursor-after-expanding t
+ "If non-nil the the cursor position is
+moved to before the first closing tag when the exp was expanded."
+ :type 'boolean
+ :group 'emmet)
+
+(defcustom emmet-move-cursor-between-quotes nil
+ "If emmet-move-cursor-after-expands is non-nil and this is non-nil then
+cursor position will be moved to after the first quote."
+ :type 'boolean
+ :group 'emmet)
+
+(defun emmet-reposition-cursor (expr)
+ (let ((output-markup (buffer-substring-no-properties (second expr) (point))))
+ (when emmet-move-cursor-after-expanding
+ (let ((p (point))
+ (new-pos (if (emmet-html-text-p output-markup)
+ (emmet-html-next-insert-point output-markup)
+ (emmet-css-next-insert-point output-markup))))
+ (goto-char
+ (+ (- p (length output-markup))
+ new-pos))))))
+
+(defun emmet-insert-and-flash (markup)
+ (emmet-remove-flash-ovl (current-buffer))
+ (let ((here (point)))
+ (insert markup)
+ (when emmet-indent-after-insert
+ (indent-region here (point))
+ (setq here
+ (save-excursion
+ (goto-char here)
+ (skip-chars-forward "[:space:]")
+ (point))))
+ (setq emmet-flash-ovl (make-overlay here (point)))
+ (overlay-put emmet-flash-ovl 'face 'emmet-preview-output)
+ (when (< 0 emmet-insert-flash-time)
+ (run-with-idle-timer emmet-insert-flash-time
+ nil 'emmet-remove-flash-ovl (current-buffer)))))
+
+;;;###autoload
+(defun emmet-preview (beg end)
+ "Expand emmet between BEG and END interactively.
+This will show a preview of the expanded emmet code and you can
+accept it or skip it."
+ (interactive (if (use-region-p)
+ (list (region-beginning) (region-end))
+ (list nil nil)))
+ (emmet-preview-abort)
+ (if (not beg)
+ (message "Region not active")
+ (setq emmet-old-show-paren show-paren-mode)
+ (show-paren-mode -1)
+ (let ((here (point)))
+ (goto-char beg)
+ (forward-line 1)
+ (unless (= 0 (current-column))
+ (insert "\n"))
+ (let* ((opos (point))
+ (ovli (make-overlay beg end nil nil t))
+ (ovlo (make-overlay opos opos))
+ (info (propertize " Emmet preview. Choose with RET. Cancel by stepping out. \n"
+ 'face 'tooltip)))
+ (overlay-put ovli 'face 'emmet-preview-input)
+ (overlay-put ovli 'keymap emmet-preview-keymap)
+ (overlay-put ovlo 'face 'emmet-preview-output)
+ (overlay-put ovlo 'before-string info)
+ (setq emmet-preview-input ovli)
+ (setq emmet-preview-output ovlo)
+ (add-hook 'before-change-functions 'emmet-preview-before-change t t)
+ (goto-char here)
+ (add-hook 'post-command-hook 'emmet-preview-post-command t t)))))
+
+(defun emmet-preview-online ()
+ "Display `emmet-preview' on the fly as the user types.
+
+To use this, add the function as a local hook:
+
+ (add-hook 'post-self-insert-hook 'emmet-preview-online t t)
+
+or enable `emmet-preview-mode'."
+ (ignore-errors
+ (let* ((expr (emmet-expr-on-line))
+ (text (nth 0 expr))
+ (beg (nth 1 expr))
+ (end (nth 2 expr)))
+ (let ((wap (thing-at-point 'word 'no-properties)))
+ (when (and (not (equal wap text))
+ (emmet-transform text))
+ (emmet-preview beg end))))))
+
+(define-minor-mode emmet-preview-mode
+ "When enabled, automatically show `emmet-preview' as the user types.
+
+See `emmet-preview-online'."
+ :init-value nil
+ :group 'emmet
+ (if emmet-preview-mode
+ (add-hook 'post-self-insert-hook 'emmet-preview-online :append :local)
+ (remove-hook 'post-self-insert-hook 'emmet-preview-online :local)))
+
+(defvar emmet-preview-pending-abort nil)
+(make-variable-buffer-local 'emmet-preview-pending-abort)
+
+(defun emmet-preview-before-change (beg end)
+ (when
+ (or (> beg (overlay-end emmet-preview-input))
+ (< beg (overlay-start emmet-preview-input))
+ (> end (overlay-end emmet-preview-input))
+ (< end (overlay-start emmet-preview-input)))
+ (setq emmet-preview-pending-abort t)))
+
+(defun emmet-preview-abort ()
+ "Abort emmet code preview."
+ (interactive)
+ (setq emmet-preview-pending-abort nil)
+ (remove-hook 'before-change-functions 'emmet-preview-before-change t)
+ (when (overlayp emmet-preview-input)
+ (delete-overlay emmet-preview-input))
+ (setq emmet-preview-input nil)
+ (when (overlayp emmet-preview-output)
+ (delete-overlay emmet-preview-output))
+ (setq emmet-preview-output nil)
+ (remove-hook 'post-command-hook 'emmet-preview-post-command t)
+ (when emmet-old-show-paren (show-paren-mode 1)))
+
+(defun emmet-preview-post-command ()
+ (condition-case err
+ (emmet-preview-post-command-1)
+ (error (message "emmet-preview-post: %s" err))))
+
+(defun emmet-preview-post-command-1 ()
+ (if (and (not emmet-preview-pending-abort)
+ (<= (point) (overlay-end emmet-preview-input))
+ (>= (point) (overlay-start emmet-preview-input)))
+ (emmet-update-preview (current-indentation))
+ (emmet-preview-abort)))
+
+(defun emmet-preview-transformed (indent)
+ (let* ((string (buffer-substring-no-properties
+ (overlay-start emmet-preview-input)
+ (overlay-end emmet-preview-input))))
+ (let ((output (emmet-transform string)))
+ (when output
+ output))))
+
+(defun emmet-update-preview (indent)
+ (let* ((pretty (emmet-preview-transformed indent))
+ (show (when pretty
+ (propertize pretty 'face 'highlight))))
+ (when show
+ (overlay-put emmet-preview-output 'after-string
+ (concat show "\n")))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Implementation of "Go to Edit Point" functionality ;;
+;; http://docs.emmet.io/actions/go-to-edit-point/ ;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defun emmet-go-to-edit-point (count &optional only-before-closed-tag)
+ (let*
+ ((between-tags
+ (if only-before-closed-tag "\\(><\\)/" "\\(><\\)"))
+ (indented-line "\\(^[[:blank:]]+$\\)")
+ (between-quotes
+ (if emmet-move-cursor-between-quotes "\\(=\\(\"\\|'\\)\\{2\\}\\)" nil))
+ (whole-regex
+ (mapconcat 'identity
+ (delq nil
+ (list between-tags indented-line between-quotes))
+ "\\|"))
+ (edit-point (format "\\(%s\\)" whole-regex)))
+ (if (> count 0)
+ (progn
+ (forward-char)
+ (let
+ ((search-result (re-search-forward edit-point nil t count)))
+ (if search-result
+ (progn
+ (cond
+ ((match-string 2) (goto-char (- (match-end 2) 1)))
+ ((match-string 3) (end-of-line))
+ ((match-string 4) (backward-char)))
+ (point))
+ (backward-char))))
+ (progn
+ (backward-char)
+ (let
+ ((search-result (re-search-backward edit-point nil t (- count))))
+ (if search-result
+ (progn
+ (cond
+ ((match-string 2) (goto-char (- (match-end 2) 1)))
+ ((match-string 3) (end-of-line))
+ ((match-string 4) (forward-char 2)))
+ (point))
+ (forward-char)))))))
+
+(defcustom emmet-postwrap-goto-edit-point nil
+ "Goto first edit point after wrapping markup?"
+ :type 'boolean
+ :group 'emmet)
+
+;;;###autoload
+(defun emmet-wrap-with-markup (wrap-with)
+ "Wrap region with markup."
+ (interactive "sExpression to wrap with: ")
+ (let* ((multi (string-match "\\*$" wrap-with))
+ (txt (buffer-substring-no-properties (region-beginning) (region-end)))
+ (to-wrap (if multi
+ (split-string txt "\n")
+ (list txt)))
+ (initial-elements (replace-regexp-in-string
+ "\\(.*\\(\\+\\|>\\)\\)?[^>*]+\\*?[[:digit:]]*$"
+ "\\1" wrap-with t))
+ (terminal-element (replace-regexp-in-string
+ "\\(.*>\\)?\\([^>*]+\\)\\(\\*[[:digit:]]+$\\)?\\*?$"
+ "\\2" wrap-with t))
+ (multiplier-expr (replace-regexp-in-string
+ "\\(.*>\\)?\\([^>*]+\\)\\(\\*[[:digit:]]+$\\)?\\*?$"
+ "\\3" wrap-with t))
+ (expr (concat
+ initial-elements
+ (mapconcat (lambda (el)
+ (concat terminal-element
+ "{!!!"
+ (secure-hash 'sha1 el)
+ "!!!}"
+ multiplier-expr))
+ to-wrap
+ "+")))
+ (markup
+ (cl-reduce
+ (lambda (result text)
+ (replace-regexp-in-string
+ (concat "!!!" (secure-hash 'sha1 text) "!!!")
+ text
+ result t t))
+ to-wrap
+ :initial-value (emmet-transform expr))))
+ (when markup
+ (delete-region (region-beginning) (region-end))
+ (insert markup)
+ (indent-region (region-beginning) (region-end))
+ (if emmet-postwrap-goto-edit-point
+ (let ((end (region-end)))
+ (goto-char (region-beginning))
+ (unless (ignore-errors (progn (emmet-next-edit-point 1) t))
+ (goto-char end)))
+ ))))
+
+;;;###autoload
+(defun emmet-next-edit-point (count)
+ (interactive "^p")
+ (unless (or emmet-use-css-transform (emmet-go-to-edit-point count))
+ (error "Last edit point reached.")))
+
+;;;###autoload
+(defun emmet-prev-edit-point (count)
+ (interactive "^p")
+ (unless (or emmet-use-css-transform (emmet-go-to-edit-point (- count)))
+ (error "First edit point reached.")))
+
+(provide 'emmet-mode)
+;; src/snippets.el
+;; This file is generated from conf/snippets.json
+;; Don't edit.
+(emmet-defparameter emmet-snippets
+(let ((tbl (make-hash-table :test 'equal)))
+(puthash "css" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "snippets" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "!" "!important" tbl)
+(puthash "@f" "@font-face {\n\tfont-family:|;\n\tsrc:url(|);\n}" tbl)
+(puthash "@f+" "@font-face {\n\tfont-family: '${1:FontName}';\n\tsrc: url('${2:FileName}.eot');\n\tsrc: url('${2:FileName}.eot?#iefix') format('embedded-opentype'),\n\t\t url('${2:FileName}.woff') format('woff'),\n\t\t url('${2:FileName}.ttf') format('truetype'),\n\t\t url('${2:FileName}.svg#${1:FontName}') format('svg');\n\tfont-style: ${3:normal};\n\tfont-weight: ${4:normal};\n}" tbl)
+(puthash "@i" "@import url(|);" tbl)
+(puthash "@import" "@import url(|);" tbl)
+(puthash "@kf" "@-webkit-keyframes ${1:identifier} {\n\t${2:from} { ${3} }${6}\n\t${4:to} { ${5} }\n}\n@-o-keyframes ${1:identifier} {\n\t${2:from} { ${3} }${6}\n\t${4:to} { ${5} }\n}\n@-moz-keyframes ${1:identifier} {\n\t${2:from} { ${3} }${6}\n\t${4:to} { ${5} }\n}\n@keyframes ${1:identifier} {\n\t${2:from} { ${3} }${6}\n\t${4:to} { ${5} }\n}" tbl)
+(puthash "@m" "@media ${1:screen} {\n\t|\n}" tbl)
+(puthash "@media" "@media ${1:screen} {\n\t|\n}" tbl)
+(puthash "ac" "align-content:|;" tbl)
+(puthash "ac:c" "align-content:center;" tbl)
+(puthash "ac:fe" "align-content:flex-end;" tbl)
+(puthash "ac:fs" "align-content:flex-start;" tbl)
+(puthash "ac:s" "align-content:stretch;" tbl)
+(puthash "ac:sa" "align-content:space-around;" tbl)
+(puthash "ac:sb" "align-content:space-between;" tbl)
+(puthash "ai" "align-items:|;" tbl)
+(puthash "ai:b" "align-items:baseline;" tbl)
+(puthash "ai:c" "align-items:center;" tbl)
+(puthash "ai:fe" "align-items:flex-end;" tbl)
+(puthash "ai:fs" "align-items:flex-start;" tbl)
+(puthash "ai:s" "align-items:stretch;" tbl)
+(puthash "anim" "animation:|;" tbl)
+(puthash "anim-" "animation:${1:name} ${2:duration} ${3:timing-function} ${4:delay} ${5:iteration-count} ${6:direction} ${7:fill-mode};" tbl)
+(puthash "animdel" "animation-delay:${1:time};" tbl)
+(puthash "animdir" "animation-direction:${1:normal};" tbl)
+(puthash "animdir:a" "animation-direction:alternate;" tbl)
+(puthash "animdir:ar" "animation-direction:alternate-reverse;" tbl)
+(puthash "animdir:n" "animation-direction:normal;" tbl)
+(puthash "animdir:r" "animation-direction:reverse;" tbl)
+(puthash "animdur" "animation-duration:${1:0}s;" tbl)
+(puthash "animfm" "animation-fill-mode:${1:both};" tbl)
+(puthash "animfm:b" "animation-fill-mode:backwards;" tbl)
+(puthash "animfm:bh" "animation-fill-mode:both;" tbl)
+(puthash "animfm:bt" "animation-fill-mode:both;" tbl)
+(puthash "animfm:f" "animation-fill-mode:forwards;" tbl)
+(puthash "animic" "animation-iteration-count:${1:1};" tbl)
+(puthash "animic:i" "animation-iteration-count:infinite;" tbl)
+(puthash "animn" "animation-name:${1:none};" tbl)
+(puthash "animps" "animation-play-state:${1:running};" tbl)
+(puthash "animps:p" "animation-play-state:paused;" tbl)
+(puthash "animps:r" "animation-play-state:running;" tbl)
+(puthash "animtf" "animation-timing-function:${1:linear};" tbl)
+(puthash "animtf:cb" "animation-timing-function:cubic-bezier(${1:0.1}, ${2:0.7}, ${3:1.0}, ${3:0.1});" tbl)
+(puthash "animtf:e" "animation-timing-function:ease;" tbl)
+(puthash "animtf:ei" "animation-timing-function:ease-in;" tbl)
+(puthash "animtf:eio" "animation-timing-function:ease-in-out;" tbl)
+(puthash "animtf:eo" "animation-timing-function:ease-out;" tbl)
+(puthash "animtf:l" "animation-timing-function:linear;" tbl)
+(puthash "ap" "appearance:${none};" tbl)
+(puthash "as" "align-self:|;" tbl)
+(puthash "as:a" "align-self:auto;" tbl)
+(puthash "as:b" "align-self:baseline;" tbl)
+(puthash "as:c" "align-self:center;" tbl)
+(puthash "as:fe" "align-self:flex-end;" tbl)
+(puthash "as:fs" "align-self:flex-start;" tbl)
+(puthash "as:s" "align-self:stretch;" tbl)
+(puthash "b" "bottom:|;" tbl)
+(puthash "b:a" "bottom:auto;" tbl)
+(puthash "bb" "border-bottom:|;" tbl)
+(puthash "bd" "border:|;" tbl)
+(puthash "bd+" "border:${1:1px} ${2:solid} ${3:#000};" tbl)
+(puthash "bd:n" "border:none;" tbl)
+(puthash "bdb" "border-bottom:|;" tbl)
+(puthash "bdb+" "border-bottom:${1:1px} ${2:solid} ${3:#000};" tbl)
+(puthash "bdb:n" "border-bottom:none;" tbl)
+(puthash "bdbc" "border-bottom-color:${1:#000};" tbl)
+(puthash "bdbc:t" "border-bottom-color:transparent;" tbl)
+(puthash "bdbi" "border-bottom-image:url(|);" tbl)
+(puthash "bdbi:n" "border-bottom-image:none;" tbl)
+(puthash "bdbk" "border-break:${1:close};" tbl)
+(puthash "bdbk:c" "border-break:close;" tbl)
+(puthash "bdbli" "border-bottom-left-image:url(|);" tbl)
+(puthash "bdbli:c" "border-bottom-left-image:continue;" tbl)
+(puthash "bdbli:n" "border-bottom-left-image:none;" tbl)
+(puthash "bdblrs" "border-bottom-left-radius:|;" tbl)
+(puthash "bdbri" "border-bottom-right-image:url(|);" tbl)
+(puthash "bdbri:c" "border-bottom-right-image:continue;" tbl)
+(puthash "bdbri:n" "border-bottom-right-image:none;" tbl)
+(puthash "bdbrrs" "border-bottom-right-radius:|;" tbl)
+(puthash "bdbs" "border-bottom-style:|;" tbl)
+(puthash "bdbs:n" "border-bottom-style:none;" tbl)
+(puthash "bdbw" "border-bottom-width:|;" tbl)
+(puthash "bdc" "border-color:${1:#000};" tbl)
+(puthash "bdc:t" "border-color:transparent;" tbl)
+(puthash "bdci" "border-corner-image:url(|);" tbl)
+(puthash "bdci:c" "border-corner-image:continue;" tbl)
+(puthash "bdci:n" "border-corner-image:none;" tbl)
+(puthash "bdcl" "border-collapse:|;" tbl)
+(puthash "bdcl:c" "border-collapse:collapse;" tbl)
+(puthash "bdcl:s" "border-collapse:separate;" tbl)
+(puthash "bdf" "border-fit:${1:repeat};" tbl)
+(puthash "bdf:c" "border-fit:clip;" tbl)
+(puthash "bdf:of" "border-fit:overflow;" tbl)
+(puthash "bdf:ow" "border-fit:overwrite;" tbl)
+(puthash "bdf:r" "border-fit:repeat;" tbl)
+(puthash "bdf:sc" "border-fit:scale;" tbl)
+(puthash "bdf:sp" "border-fit:space;" tbl)
+(puthash "bdf:st" "border-fit:stretch;" tbl)
+(puthash "bdi" "border-image:url(|);" tbl)
+(puthash "bdi:n" "border-image:none;" tbl)
+(puthash "bdl" "border-left:|;" tbl)
+(puthash "bdl+" "border-left:${1:1px} ${2:solid} ${3:#000};" tbl)
+(puthash "bdl:n" "border-left:none;" tbl)
+(puthash "bdlc" "border-left-color:${1:#000};" tbl)
+(puthash "bdlc:t" "border-left-color:transparent;" tbl)
+(puthash "bdlen" "border-length:|;" tbl)
+(puthash "bdlen:a" "border-length:auto;" tbl)
+(puthash "bdli" "border-left-image:url(|);" tbl)
+(puthash "bdli:n" "border-left-image:none;" tbl)
+(puthash "bdls" "border-left-style:|;" tbl)
+(puthash "bdls:n" "border-left-style:none;" tbl)
+(puthash "bdlw" "border-left-width:|;" tbl)
+(puthash "bdr" "border-right:|;" tbl)
+(puthash "bdr+" "border-right:${1:1px} ${2:solid} ${3:#000};" tbl)
+(puthash "bdr:n" "border-right:none;" tbl)
+(puthash "bdrc" "border-right-color:${1:#000};" tbl)
+(puthash "bdrc:t" "border-right-color:transparent;" tbl)
+(puthash "bdri" "border-right-image:url(|);" tbl)
+(puthash "bdri:n" "border-right-image:none;" tbl)
+(puthash "bdrs" "border-radius:|;" tbl)
+(puthash "bdrst" "border-right-style:|;" tbl)
+(puthash "bdrst:n" "border-right-style:none;" tbl)
+(puthash "bdrw" "border-right-width:|;" tbl)
+(puthash "bds" "border-style:|;" tbl)
+(puthash "bds:db" "border-style:double;" tbl)
+(puthash "bds:ds" "border-style:dashed;" tbl)
+(puthash "bds:dt" "border-style:dotted;" tbl)
+(puthash "bds:dtds" "border-style:dot-dash;" tbl)
+(puthash "bds:dtdtds" "border-style:dot-dot-dash;" tbl)
+(puthash "bds:g" "border-style:groove;" tbl)
+(puthash "bds:h" "border-style:hidden;" tbl)
+(puthash "bds:i" "border-style:inset;" tbl)
+(puthash "bds:n" "border-style:none;" tbl)
+(puthash "bds:o" "border-style:outset;" tbl)
+(puthash "bds:r" "border-style:ridge;" tbl)
+(puthash "bds:s" "border-style:solid;" tbl)
+(puthash "bds:w" "border-style:wave;" tbl)
+(puthash "bdsp" "border-spacing:|;" tbl)
+(puthash "bdt" "border-top:|;" tbl)
+(puthash "bdt+" "border-top:${1:1px} ${2:solid} ${3:#000};" tbl)
+(puthash "bdt:n" "border-top:none;" tbl)
+(puthash "bdtc" "border-top-color:${1:#000};" tbl)
+(puthash "bdtc:t" "border-top-color:transparent;" tbl)
+(puthash "bdti" "border-top-image:url(|);" tbl)
+(puthash "bdti:n" "border-top-image:none;" tbl)
+(puthash "bdtli" "border-top-left-image:url(|);" tbl)
+(puthash "bdtli:c" "border-top-left-image:continue;" tbl)
+(puthash "bdtli:n" "border-top-left-image:none;" tbl)
+(puthash "bdtlrs" "border-top-left-radius:|;" tbl)
+(puthash "bdtri" "border-top-right-image:url(|);" tbl)
+(puthash "bdtri:c" "border-top-right-image:continue;" tbl)
+(puthash "bdtri:n" "border-top-right-image:none;" tbl)
+(puthash "bdtrrs" "border-top-right-radius:|;" tbl)
+(puthash "bdts" "border-top-style:|;" tbl)
+(puthash "bdts:n" "border-top-style:none;" tbl)
+(puthash "bdtw" "border-top-width:|;" tbl)
+(puthash "bdw" "border-width:|;" tbl)
+(puthash "bfv" "backface-visibility:|;" tbl)
+(puthash "bfv:h" "backface-visibility:hidden;" tbl)
+(puthash "bfv:v" "backface-visibility:visible;" tbl)
+(puthash "bg" "background:#${1:000};" tbl)
+(puthash "bg+" "background:${1:#fff} url(${2}) ${3:0} ${4:0} ${5:no-repeat};" tbl)
+(puthash "bg:ie" "filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='${1:x}.png',sizingMethod='${2:crop}');" tbl)
+(puthash "bg:n" "background:none;" tbl)
+(puthash "bga" "background-attachment:|;" tbl)
+(puthash "bga:f" "background-attachment:fixed;" tbl)
+(puthash "bga:s" "background-attachment:scroll;" tbl)
+(puthash "bgbk" "background-break:|;" tbl)
+(puthash "bgbk:bb" "background-break:bounding-box;" tbl)
+(puthash "bgbk:c" "background-break:continuous;" tbl)
+(puthash "bgbk:eb" "background-break:each-box;" tbl)
+(puthash "bgc" "background-color:${1:fff};" tbl)
+(puthash "bgc:t" "background-color:transparent;" tbl)
+(puthash "bgcp" "background-clip:${1:padding-box};" tbl)
+(puthash "bgcp:bb" "background-clip:border-box;" tbl)
+(puthash "bgcp:cb" "background-clip:content-box;" tbl)
+(puthash "bgcp:nc" "background-clip:no-clip;" tbl)
+(puthash "bgcp:pb" "background-clip:padding-box;" tbl)
+(puthash "bgi" "background-image:url(|);" tbl)
+(puthash "bgi:n" "background-image:none;" tbl)
+(puthash "bgo" "background-origin:|;" tbl)
+(puthash "bgo:bb" "background-origin:border-box;" tbl)
+(puthash "bgo:cb" "background-origin:content-box;" tbl)
+(puthash "bgo:pb" "background-origin:padding-box;" tbl)
+(puthash "bgp" "background-position:${1:0} ${2:0};" tbl)
+(puthash "bgpx" "background-position-x:|;" tbl)
+(puthash "bgpy" "background-position-y:|;" tbl)
+(puthash "bgr" "background-repeat:|;" tbl)
+(puthash "bgr:n" "background-repeat:no-repeat;" tbl)
+(puthash "bgr:rd" "background-repeat:round;" tbl)
+(puthash "bgr:sp" "background-repeat:space;" tbl)
+(puthash "bgr:x" "background-repeat:repeat-x;" tbl)
+(puthash "bgr:y" "background-repeat:repeat-y;" tbl)
+(puthash "bgsz" "background-size:|;" tbl)
+(puthash "bgsz:a" "background-size:auto;" tbl)
+(puthash "bgsz:ct" "background-size:contain;" tbl)
+(puthash "bgsz:cv" "background-size:cover;" tbl)
+(puthash "bl" "border-left:|;" tbl)
+(puthash "br" "border-right:|;" tbl)
+(puthash "bt" "border-top:|;" tbl)
+(puthash "bxsh" "box-shadow:${1:inset }${2:hoff} ${3:voff} ${4:blur} ${5:color};" tbl)
+(puthash "bxsh:n" "box-shadow:none;" tbl)
+(puthash "bxsh:r" "box-shadow:${1:inset }${2:hoff} ${3:voff} ${4:blur} ${5:spread }rgb(${6:0}, ${7:0}, ${8:0});" tbl)
+(puthash "bxsh:ra" "box-shadow:${1:inset }${2:h} ${3:v} ${4:blur} ${5:spread }rgba(${6:0}, ${7:0}, ${8:0}, .${9:5});" tbl)
+(puthash "bxz" "box-sizing:${1:border-box};" tbl)
+(puthash "bxz:bb" "box-sizing:border-box;" tbl)
+(puthash "bxz:cb" "box-sizing:content-box;" tbl)
+(puthash "c" "color:${1:#000};" tbl)
+(puthash "c:r" "color:rgb(${1:0}, ${2:0}, ${3:0});" tbl)
+(puthash "c:ra" "color:rgba(${1:0}, ${2:0}, ${3:0}, .${4:5});" tbl)
+(puthash "cl" "clear:${1:both};" tbl)
+(puthash "cl:b" "clear:both;" tbl)
+(puthash "cl:l" "clear:left;" tbl)
+(puthash "cl:n" "clear:none;" tbl)
+(puthash "cl:r" "clear:right;" tbl)
+(puthash "cm" "/* |${child} */" tbl)
+(puthash "cnt" "content:'|';" tbl)
+(puthash "cnt:a" "content:attr(|);" tbl)
+(puthash "cnt:c" "content:counter(|);" tbl)
+(puthash "cnt:cq" "content:close-quote;" tbl)
+(puthash "cnt:cs" "content:counters(|);" tbl)
+(puthash "cnt:n" "content:normal;" tbl)
+(puthash "cnt:ncq" "content:no-close-quote;" tbl)
+(puthash "cnt:noq" "content:no-open-quote;" tbl)
+(puthash "cnt:oq" "content:open-quote;" tbl)
+(puthash "coi" "counter-increment:|;" tbl)
+(puthash "colm" "columns:|;" tbl)
+(puthash "colmc" "column-count:|;" tbl)
+(puthash "colmf" "column-fill:|;" tbl)
+(puthash "colmg" "column-gap:|;" tbl)
+(puthash "colmr" "column-rule:|;" tbl)
+(puthash "colmrc" "column-rule-color:|;" tbl)
+(puthash "colmrs" "column-rule-style:|;" tbl)
+(puthash "colmrw" "column-rule-width:|;" tbl)
+(puthash "colms" "column-span:|;" tbl)
+(puthash "colmw" "column-width:|;" tbl)
+(puthash "cor" "counter-reset:|;" tbl)
+(puthash "cp" "clip:|;" tbl)
+(puthash "cp:a" "clip:auto;" tbl)
+(puthash "cp:r" "clip:rect(${1:top} ${2:right} ${3:bottom} ${4:left});" tbl)
+(puthash "cps" "caption-side:|;" tbl)
+(puthash "cps:b" "caption-side:bottom;" tbl)
+(puthash "cps:t" "caption-side:top;" tbl)
+(puthash "ct" "content:|;" tbl)
+(puthash "ct:a" "content:attr(|);" tbl)
+(puthash "ct:c" "content:counter(|);" tbl)
+(puthash "ct:cq" "content:close-quote;" tbl)
+(puthash "ct:cs" "content:counters(|);" tbl)
+(puthash "ct:n" "content:normal;" tbl)
+(puthash "ct:ncq" "content:no-close-quote;" tbl)
+(puthash "ct:noq" "content:no-open-quote;" tbl)
+(puthash "ct:oq" "content:open-quote;" tbl)
+(puthash "cur" "cursor:${pointer};" tbl)
+(puthash "cur:a" "cursor:auto;" tbl)
+(puthash "cur:c" "cursor:crosshair;" tbl)
+(puthash "cur:d" "cursor:default;" tbl)
+(puthash "cur:ha" "cursor:hand;" tbl)
+(puthash "cur:he" "cursor:help;" tbl)
+(puthash "cur:m" "cursor:move;" tbl)
+(puthash "cur:p" "cursor:pointer;" tbl)
+(puthash "cur:t" "cursor:text;" tbl)
+(puthash "d" "display:${1:block};" tbl)
+(puthash "d:b" "display:block;" tbl)
+(puthash "d:cp" "display:compact;" tbl)
+(puthash "d:f" "display:flex;" tbl)
+(puthash "d:i" "display:inline;" tbl)
+(puthash "d:ib" "display:inline-block;" tbl)
+(puthash "d:ib+" "display: inline-block;\n*display: inline;\n*zoom: 1;" tbl)
+(puthash "d:if" "display:inline-flex;" tbl)
+(puthash "d:itb" "display:inline-table;" tbl)
+(puthash "d:li" "display:list-item;" tbl)
+(puthash "d:n" "display:none;" tbl)
+(puthash "d:rb" "display:ruby;" tbl)
+(puthash "d:rbb" "display:ruby-base;" tbl)
+(puthash "d:rbbg" "display:ruby-base-group;" tbl)
+(puthash "d:rbt" "display:ruby-text;" tbl)
+(puthash "d:rbtg" "display:ruby-text-group;" tbl)
+(puthash "d:ri" "display:run-in;" tbl)
+(puthash "d:tb" "display:table;" tbl)
+(puthash "d:tbc" "display:table-cell;" tbl)
+(puthash "d:tbcl" "display:table-column;" tbl)
+(puthash "d:tbclg" "display:table-column-group;" tbl)
+(puthash "d:tbcp" "display:table-caption;" tbl)
+(puthash "d:tbfg" "display:table-footer-group;" tbl)
+(puthash "d:tbhg" "display:table-header-group;" tbl)
+(puthash "d:tbr" "display:table-row;" tbl)
+(puthash "d:tbrg" "display:table-row-group;" tbl)
+(puthash "ec" "empty-cells:|;" tbl)
+(puthash "ec:h" "empty-cells:hide;" tbl)
+(puthash "ec:s" "empty-cells:show;" tbl)
+(puthash "f" "font:|;" tbl)
+(puthash "f+" "font:${1:1em} ${2:Arial,sans-serif};" tbl)
+(puthash "fef" "font-effect:|;" tbl)
+(puthash "fef:eb" "font-effect:emboss;" tbl)
+(puthash "fef:eg" "font-effect:engrave;" tbl)
+(puthash "fef:n" "font-effect:none;" tbl)
+(puthash "fef:o" "font-effect:outline;" tbl)
+(puthash "fem" "font-emphasize:|;" tbl)
+(puthash "femp" "font-emphasize-position:|;" tbl)
+(puthash "femp:a" "font-emphasize-position:after;" tbl)
+(puthash "femp:b" "font-emphasize-position:before;" tbl)
+(puthash "fems" "font-emphasize-style:|;" tbl)
+(puthash "fems:ac" "font-emphasize-style:accent;" tbl)
+(puthash "fems:c" "font-emphasize-style:circle;" tbl)
+(puthash "fems:ds" "font-emphasize-style:disc;" tbl)
+(puthash "fems:dt" "font-emphasize-style:dot;" tbl)
+(puthash "fems:n" "font-emphasize-style:none;" tbl)
+(puthash "ff" "font-family:|;" tbl)
+(puthash "ff:a" "font-family: Arial, \"Helvetica Neue\", Helvetica, sans-serif;" tbl)
+(puthash "ff:c" "font-family:cursive;" tbl)
+(puthash "ff:f" "font-family:fantasy;" tbl)
+(puthash "ff:m" "font-family:monospace;" tbl)
+(puthash "ff:s" "font-family:serif;" tbl)
+(puthash "ff:ss" "font-family:sans-serif;" tbl)
+(puthash "ff:t" "font-family: \"Times New Roman\", Times, Baskerville, Georgia, serif;" tbl)
+(puthash "ff:v" "font-family: Verdana, Geneva, sans-serif;" tbl)
+(puthash "fl" "float:${1:left};" tbl)
+(puthash "fl:l" "float:left;" tbl)
+(puthash "fl:n" "float:none;" tbl)
+(puthash "fl:r" "float:right;" tbl)
+(puthash "fs" "font-style:italic;" tbl)
+(puthash "fs:i" "font-style:italic;" tbl)
+(puthash "fs:n" "font-style:normal;" tbl)
+(puthash "fs:o" "font-style:oblique;" tbl)
+(puthash "fsm" "font-smooth:|;" tbl)
+(puthash "fsm:a" "font-smooth:auto;" tbl)
+(puthash "fsm:aw" "font-smooth:always;" tbl)
+(puthash "fsm:n" "font-smooth:never;" tbl)
+(puthash "fst" "font-stretch:|;" tbl)
+(puthash "fst:c" "font-stretch:condensed;" tbl)
+(puthash "fst:e" "font-stretch:expanded;" tbl)
+(puthash "fst:ec" "font-stretch:extra-condensed;" tbl)
+(puthash "fst:ee" "font-stretch:extra-expanded;" tbl)
+(puthash "fst:n" "font-stretch:normal;" tbl)
+(puthash "fst:sc" "font-stretch:semi-condensed;" tbl)
+(puthash "fst:se" "font-stretch:semi-expanded;" tbl)
+(puthash "fst:uc" "font-stretch:ultra-condensed;" tbl)
+(puthash "fst:ue" "font-stretch:ultra-expanded;" tbl)
+(puthash "fv" "font-variant:|;" tbl)
+(puthash "fv:n" "font-variant:normal;" tbl)
+(puthash "fv:sc" "font-variant:small-caps;" tbl)
+(puthash "fw" "font-weight:|;" tbl)
+(puthash "fw:b" "font-weight:bold;" tbl)
+(puthash "fw:br" "font-weight:bolder;" tbl)
+(puthash "fw:lr" "font-weight:lighter;" tbl)
+(puthash "fw:n" "font-weight:normal;" tbl)
+(puthash "fx" "flex:|;" tbl)
+(puthash "fxb" "flex-basis:|;" tbl)
+(puthash "fxd" "flex-direction:|;" tbl)
+(puthash "fxd:c" "flex-direction:column;" tbl)
+(puthash "fxd:cr" "flex-direction:column-reverse;" tbl)
+(puthash "fxd:r" "flex-direction:row;" tbl)
+(puthash "fxd:rr" "flex-direction:row-reverse;" tbl)
+(puthash "fxf" "flex-flow:|;" tbl)
+(puthash "fxg" "flex-grow:|;" tbl)
+(puthash "fxsh" "flex-shrink:|;" tbl)
+(puthash "fxw" "flex-wrap: |;" tbl)
+(puthash "fxw:n" "flex-wrap:nowrap;" tbl)
+(puthash "fxw:w" "flex-wrap:wrap;" tbl)
+(puthash "fxw:wr" "flex-wrap:wrap-reverse;" tbl)
+(puthash "fz" "font-size:|;" tbl)
+(puthash "fza" "font-size-adjust:|;" tbl)
+(puthash "fza:n" "font-size-adjust:none;" tbl)
+(puthash "h" "height:|;" tbl)
+(puthash "h:a" "height:auto;" tbl)
+(puthash "jc" "justify-content:|;" tbl)
+(puthash "jc:c" "justify-content:center;" tbl)
+(puthash "jc:fe" "justify-content:flex-end;" tbl)
+(puthash "jc:fs" "justify-content:flex-start;" tbl)
+(puthash "jc:sa" "justify-content:space-around;" tbl)
+(puthash "jc:sb" "justify-content:space-between;" tbl)
+(puthash "l" "left:|;" tbl)
+(puthash "l:a" "left:auto;" tbl)
+(puthash "lh" "line-height:|;" tbl)
+(puthash "lis" "list-style:|;" tbl)
+(puthash "lis:n" "list-style:none;" tbl)
+(puthash "lisi" "list-style-image:|;" tbl)
+(puthash "lisi:n" "list-style-image:none;" tbl)
+(puthash "lisp" "list-style-position:|;" tbl)
+(puthash "lisp:i" "list-style-position:inside;" tbl)
+(puthash "lisp:o" "list-style-position:outside;" tbl)
+(puthash "list" "list-style-type:|;" tbl)
+(puthash "list:c" "list-style-type:circle;" tbl)
+(puthash "list:d" "list-style-type:disc;" tbl)
+(puthash "list:dc" "list-style-type:decimal;" tbl)
+(puthash "list:dclz" "list-style-type:decimal-leading-zero;" tbl)
+(puthash "list:lr" "list-style-type:lower-roman;" tbl)
+(puthash "list:n" "list-style-type:none;" tbl)
+(puthash "list:s" "list-style-type:square;" tbl)
+(puthash "list:ur" "list-style-type:upper-roman;" tbl)
+(puthash "lts" "letter-spacing:|;" tbl)
+(puthash "lts-n" "letter-spacing:normal;" tbl)
+(puthash "m" "margin:|;" tbl)
+(puthash "m:a" "margin:auto;" tbl)
+(puthash "mah" "max-height:|;" tbl)
+(puthash "mah:n" "max-height:none;" tbl)
+(puthash "mar" "max-resolution:${1:res};" tbl)
+(puthash "maw" "max-width:|;" tbl)
+(puthash "maw:n" "max-width:none;" tbl)
+(puthash "mb" "margin-bottom:|;" tbl)
+(puthash "mb:a" "margin-bottom:auto;" tbl)
+(puthash "mih" "min-height:|;" tbl)
+(puthash "mir" "min-resolution:${1:res};" tbl)
+(puthash "miw" "min-width:|;" tbl)
+(puthash "ml" "margin-left:|;" tbl)
+(puthash "ml:a" "margin-left:auto;" tbl)
+(puthash "mr" "margin-right:|;" tbl)
+(puthash "mr:a" "margin-right:auto;" tbl)
+(puthash "mt" "margin-top:|;" tbl)
+(puthash "mt:a" "margin-top:auto;" tbl)
+(puthash "ol" "outline:|;" tbl)
+(puthash "ol:n" "outline:none;" tbl)
+(puthash "olc" "outline-color:${1:#000};" tbl)
+(puthash "olc:i" "outline-color:invert;" tbl)
+(puthash "olo" "outline-offset:|;" tbl)
+(puthash "ols" "outline-style:|;" tbl)
+(puthash "ols:db" "outline-style:double;" tbl)
+(puthash "ols:ds" "outline-style:dashed;" tbl)
+(puthash "ols:dt" "outline-style:dotted;" tbl)
+(puthash "ols:g" "outline-style:groove;" tbl)
+(puthash "ols:i" "outline-style:inset;" tbl)
+(puthash "ols:n" "outline-style:none;" tbl)
+(puthash "ols:o" "outline-style:outset;" tbl)
+(puthash "ols:r" "outline-style:ridge;" tbl)
+(puthash "ols:s" "outline-style:solid;" tbl)
+(puthash "olw" "outline-width:|;" tbl)
+(puthash "olw:m" "outline-width:medium;" tbl)
+(puthash "olw:tc" "outline-width:thick;" tbl)
+(puthash "olw:tn" "outline-width:thin;" tbl)
+(puthash "op" "opacity:|;" tbl)
+(puthash "op+" "opacity: $1;\nfilter: alpha(opacity=$2);" tbl)
+(puthash "op:ie" "filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=100);" tbl)
+(puthash "op:ms" "-ms-filter:'progid:DXImageTransform.Microsoft.Alpha(Opacity=100)';" tbl)
+(puthash "ord" "order:|;" tbl)
+(puthash "ori" "orientation:|;" tbl)
+(puthash "ori:l" "orientation:landscape;" tbl)
+(puthash "ori:p" "orientation:portrait;" tbl)
+(puthash "orp" "orphans:|;" tbl)
+(puthash "ov" "overflow:${1:hidden};" tbl)
+(puthash "ov:a" "overflow:auto;" tbl)
+(puthash "ov:h" "overflow:hidden;" tbl)
+(puthash "ov:s" "overflow:scroll;" tbl)
+(puthash "ov:v" "overflow:visible;" tbl)
+(puthash "ovs" "overflow-style:${1:scrollbar};" tbl)
+(puthash "ovs:a" "overflow-style:auto;" tbl)
+(puthash "ovs:m" "overflow-style:move;" tbl)
+(puthash "ovs:mq" "overflow-style:marquee;" tbl)
+(puthash "ovs:p" "overflow-style:panner;" tbl)
+(puthash "ovs:s" "overflow-style:scrollbar;" tbl)
+(puthash "ovx" "overflow-x:${1:hidden};" tbl)
+(puthash "ovx:a" "overflow-x:auto;" tbl)
+(puthash "ovx:h" "overflow-x:hidden;" tbl)
+(puthash "ovx:s" "overflow-x:scroll;" tbl)
+(puthash "ovx:v" "overflow-x:visible;" tbl)
+(puthash "ovy" "overflow-y:${1:hidden};" tbl)
+(puthash "ovy:a" "overflow-y:auto;" tbl)
+(puthash "ovy:h" "overflow-y:hidden;" tbl)
+(puthash "ovy:s" "overflow-y:scroll;" tbl)
+(puthash "ovy:v" "overflow-y:visible;" tbl)
+(puthash "p" "padding:|;" tbl)
+(puthash "pb" "padding-bottom:|;" tbl)
+(puthash "pgba" "page-break-after:|;" tbl)
+(puthash "pgba:al" "page-break-after:always;" tbl)
+(puthash "pgba:au" "page-break-after:auto;" tbl)
+(puthash "pgba:l" "page-break-after:left;" tbl)
+(puthash "pgba:r" "page-break-after:right;" tbl)
+(puthash "pgbb" "page-break-before:|;" tbl)
+(puthash "pgbb:al" "page-break-before:always;" tbl)
+(puthash "pgbb:au" "page-break-before:auto;" tbl)
+(puthash "pgbb:l" "page-break-before:left;" tbl)
+(puthash "pgbb:r" "page-break-before:right;" tbl)
+(puthash "pgbi" "page-break-inside:|;" tbl)
+(puthash "pgbi:au" "page-break-inside:auto;" tbl)
+(puthash "pgbi:av" "page-break-inside:avoid;" tbl)
+(puthash "pl" "padding-left:|;" tbl)
+(puthash "pos" "position:${1:relative};" tbl)
+(puthash "pos:a" "position:absolute;" tbl)
+(puthash "pos:f" "position:fixed;" tbl)
+(puthash "pos:r" "position:relative;" tbl)
+(puthash "pos:s" "position:static;" tbl)
+(puthash "pr" "padding-right:|;" tbl)
+(puthash "pt" "padding-top:|;" tbl)
+(puthash "q" "quotes:|;" tbl)
+(puthash "q:en" "quotes:'\\201C' '\\201D' '\\2018' '\\2019';" tbl)
+(puthash "q:n" "quotes:none;" tbl)
+(puthash "q:ru" "quotes:'\\00AB' '\\00BB' '\\201E' '\\201C';" tbl)
+(puthash "r" "right:|;" tbl)
+(puthash "r:a" "right:auto;" tbl)
+(puthash "rsz" "resize:|;" tbl)
+(puthash "rsz:b" "resize:both;" tbl)
+(puthash "rsz:h" "resize:horizontal;" tbl)
+(puthash "rsz:n" "resize:none;" tbl)
+(puthash "rsz:v" "resize:vertical;" tbl)
+(puthash "t" "top:|;" tbl)
+(puthash "t:a" "top:auto;" tbl)
+(puthash "ta" "text-align:${1:left};" tbl)
+(puthash "ta-lst" "text-align-last:|;" tbl)
+(puthash "ta:c" "text-align:center;" tbl)
+(puthash "ta:j" "text-align:justify;" tbl)
+(puthash "ta:l" "text-align:left;" tbl)
+(puthash "ta:r" "text-align:right;" tbl)
+(puthash "tal:a" "text-align-last:auto;" tbl)
+(puthash "tal:c" "text-align-last:center;" tbl)
+(puthash "tal:l" "text-align-last:left;" tbl)
+(puthash "tal:r" "text-align-last:right;" tbl)
+(puthash "tbl" "table-layout:|;" tbl)
+(puthash "tbl:a" "table-layout:auto;" tbl)
+(puthash "tbl:f" "table-layout:fixed;" tbl)
+(puthash "td" "text-decoration:${1:none};" tbl)
+(puthash "td:l" "text-decoration:line-through;" tbl)
+(puthash "td:n" "text-decoration:none;" tbl)
+(puthash "td:o" "text-decoration:overline;" tbl)
+(puthash "td:u" "text-decoration:underline;" tbl)
+(puthash "te" "text-emphasis:|;" tbl)
+(puthash "te:a" "text-emphasis:after;" tbl)
+(puthash "te:ac" "text-emphasis:accent;" tbl)
+(puthash "te:b" "text-emphasis:before;" tbl)
+(puthash "te:c" "text-emphasis:circle;" tbl)
+(puthash "te:ds" "text-emphasis:disc;" tbl)
+(puthash "te:dt" "text-emphasis:dot;" tbl)
+(puthash "te:n" "text-emphasis:none;" tbl)
+(puthash "th" "text-height:|;" tbl)
+(puthash "th:a" "text-height:auto;" tbl)
+(puthash "th:f" "text-height:font-size;" tbl)
+(puthash "th:m" "text-height:max-size;" tbl)
+(puthash "th:t" "text-height:text-size;" tbl)
+(puthash "ti" "text-indent:|;" tbl)
+(puthash "ti:-" "text-indent:-9999px;" tbl)
+(puthash "tj" "text-justify:|;" tbl)
+(puthash "tj:a" "text-justify:auto;" tbl)
+(puthash "tj:d" "text-justify:distribute;" tbl)
+(puthash "tj:ic" "text-justify:inter-cluster;" tbl)
+(puthash "tj:ii" "text-justify:inter-ideograph;" tbl)
+(puthash "tj:iw" "text-justify:inter-word;" tbl)
+(puthash "tj:k" "text-justify:kashida;" tbl)
+(puthash "tj:t" "text-justify:tibetan;" tbl)
+(puthash "to" "text-outline:|;" tbl)
+(puthash "to+" "text-outline:${1:0} ${2:0} ${3:#000};" tbl)
+(puthash "to:n" "text-outline:none;" tbl)
+(puthash "tov" "text-overflow:${ellipsis};" tbl)
+(puthash "tov:c" "text-overflow:clip;" tbl)
+(puthash "tov:e" "text-overflow:ellipsis;" tbl)
+(puthash "tr" "text-replace:|;" tbl)
+(puthash "tr:n" "text-replace:none;" tbl)
+(puthash "trf" "transform:|;" tbl)
+(puthash "trf:r" "transform: rotate(${1:angle});" tbl)
+(puthash "trf:rx" "transform: rotateX(${1:angle});" tbl)
+(puthash "trf:ry" "transform: rotateY(${1:angle});" tbl)
+(puthash "trf:rz" "transform: rotateZ(${1:angle});" tbl)
+(puthash "trf:sc" "transform: scale(${1:x}, ${2:y});" tbl)
+(puthash "trf:sc3" "transform: scale3d(${1:x}, ${2:y}, ${3:z});" tbl)
+(puthash "trf:scx" "transform: scaleX(${1:x});" tbl)
+(puthash "trf:scy" "transform: scaleY(${1:y});" tbl)
+(puthash "trf:scz" "transform: scaleZ(${1:z});" tbl)
+(puthash "trf:skx" "transform: skewX(${1:angle});" tbl)
+(puthash "trf:sky" "transform: skewY(${1:angle});" tbl)
+(puthash "trf:t" "transform: translate(${1:x}, ${2:y});" tbl)
+(puthash "trf:t3" "transform: translate3d(${1:tx}, ${2:ty}, ${3:tz});" tbl)
+(puthash "trf:tx" "transform: translateX(${1:x});" tbl)
+(puthash "trf:ty" "transform: translateY(${1:y});" tbl)
+(puthash "trf:tz" "transform: translateZ(${1:z});" tbl)
+(puthash "trfo" "transform-origin:|;" tbl)
+(puthash "trfs" "transform-style:${1:preserve-3d};" tbl)
+(puthash "trs" "transition:${1:prop} ${2:time};" tbl)
+(puthash "trsde" "transition-delay:${1:time};" tbl)
+(puthash "trsdu" "transition-duration:${1:time};" tbl)
+(puthash "trsp" "transition-property:${1:prop};" tbl)
+(puthash "trstf" "transition-timing-function:${1:tfunc};" tbl)
+(puthash "tsh" "text-shadow:${1:hoff} ${2:voff} ${3:blur} ${4:#000};" tbl)
+(puthash "tsh+" "text-shadow:${1:0} ${2:0} ${3:0} ${4:#000};" tbl)
+(puthash "tsh:n" "text-shadow:none;" tbl)
+(puthash "tsh:r" "text-shadow:${1:h} ${2:v} ${3:blur} rgb(${4:0}, ${5:0}, ${6:0});" tbl)
+(puthash "tsh:ra" "text-shadow:${1:h} ${2:v} ${3:blur} rgba(${4:0}, ${5:0}, ${6:0}, .${7:5});" tbl)
+(puthash "tt" "text-transform:${1:uppercase};" tbl)
+(puthash "tt:c" "text-transform:capitalize;" tbl)
+(puthash "tt:l" "text-transform:lowercase;" tbl)
+(puthash "tt:n" "text-transform:none;" tbl)
+(puthash "tt:u" "text-transform:uppercase;" tbl)
+(puthash "tw" "text-wrap:|;" tbl)
+(puthash "tw:n" "text-wrap:normal;" tbl)
+(puthash "tw:no" "text-wrap:none;" tbl)
+(puthash "tw:s" "text-wrap:suppress;" tbl)
+(puthash "tw:u" "text-wrap:unrestricted;" tbl)
+(puthash "us" "user-select:${none};" tbl)
+(puthash "v" "visibility:${1:hidden};" tbl)
+(puthash "v:c" "visibility:collapse;" tbl)
+(puthash "v:h" "visibility:hidden;" tbl)
+(puthash "v:v" "visibility:visible;" tbl)
+(puthash "va" "vertical-align:${1:top};" tbl)
+(puthash "va:b" "vertical-align:bottom;" tbl)
+(puthash "va:bl" "vertical-align:baseline;" tbl)
+(puthash "va:m" "vertical-align:middle;" tbl)
+(puthash "va:sub" "vertical-align:sub;" tbl)
+(puthash "va:sup" "vertical-align:super;" tbl)
+(puthash "va:t" "vertical-align:top;" tbl)
+(puthash "va:tb" "vertical-align:text-bottom;" tbl)
+(puthash "va:tt" "vertical-align:text-top;" tbl)
+(puthash "w" "width:|;" tbl)
+(puthash "w:a" "width:auto;" tbl)
+(puthash "wfsm" "-webkit-font-smoothing:${antialiased};" tbl)
+(puthash "wfsm:a" "-webkit-font-smoothing:antialiased;" tbl)
+(puthash "wfsm:n" "-webkit-font-smoothing:none;" tbl)
+(puthash "wfsm:s" "-webkit-font-smoothing:subpixel-antialiased;" tbl)
+(puthash "wfsm:sa" "-webkit-font-smoothing:subpixel-antialiased;" tbl)
+(puthash "whs" "white-space:|;" tbl)
+(puthash "whs:n" "white-space:normal;" tbl)
+(puthash "whs:nw" "white-space:nowrap;" tbl)
+(puthash "whs:p" "white-space:pre;" tbl)
+(puthash "whs:pl" "white-space:pre-line;" tbl)
+(puthash "whs:pw" "white-space:pre-wrap;" tbl)
+(puthash "whsc" "white-space-collapse:|;" tbl)
+(puthash "whsc:ba" "white-space-collapse:break-all;" tbl)
+(puthash "whsc:bs" "white-space-collapse:break-strict;" tbl)
+(puthash "whsc:k" "white-space-collapse:keep-all;" tbl)
+(puthash "whsc:l" "white-space-collapse:loose;" tbl)
+(puthash "whsc:n" "white-space-collapse:normal;" tbl)
+(puthash "wid" "widows:|;" tbl)
+(puthash "wm" "writing-mode:${1:lr-tb};" tbl)
+(puthash "wm:btl" "writing-mode:bt-lr;" tbl)
+(puthash "wm:btr" "writing-mode:bt-rl;" tbl)
+(puthash "wm:lrb" "writing-mode:lr-bt;" tbl)
+(puthash "wm:lrt" "writing-mode:lr-tb;" tbl)
+(puthash "wm:rlb" "writing-mode:rl-bt;" tbl)
+(puthash "wm:rlt" "writing-mode:rl-tb;" tbl)
+(puthash "wm:tbl" "writing-mode:tb-lr;" tbl)
+(puthash "wm:tbr" "writing-mode:tb-rl;" tbl)
+(puthash "wob" "word-break:|;" tbl)
+(puthash "wob:ba" "word-break:break-all;" tbl)
+(puthash "wob:k" "word-break:keep-all;" tbl)
+(puthash "wob:n" "word-break:normal;" tbl)
+(puthash "wos" "word-spacing:|;" tbl)
+(puthash "wow" "word-wrap:|;" tbl)
+(puthash "wow:b" "word-wrap:break-word;" tbl)
+(puthash "wow:n" "word-wrap:none;" tbl)
+(puthash "wow:nm" "word-wrap:normal;" tbl)
+(puthash "wow:s" "word-wrap:suppress;" tbl)
+(puthash "wow:u" "word-wrap:unrestricted;" tbl)
+(puthash "z" "z-index:|;" tbl)
+(puthash "z:a" "z-index:auto;" tbl)
+(puthash "zm" "zoom:1;" tbl)
+(puthash "zoo" "zoom:1;" tbl)
+tbl) tbl)
+tbl) tbl)
+(puthash "html" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "aliases" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "!" "html:5" tbl)
+(puthash "!mvp" "html>(head>meta[charset=UTF-8]+meta:vp+title{Document})+body" tbl)
+(puthash "a:link" "a[href=http://]" tbl)
+(puthash "a:mail" "a[href=mailto:]" tbl)
+(puthash "acr" "acronym" tbl)
+(puthash "adr" "address" tbl)
+(puthash "area:c" "area[shape=circle coords href alt]" tbl)
+(puthash "area:d" "area[shape=default href alt]" tbl)
+(puthash "area:p" "area[shape=poly coords href alt]" tbl)
+(puthash "area:r" "area[shape=rect coords href alt]" tbl)
+(puthash "art" "article" tbl)
+(puthash "bdo:l" "bdo[dir=ltr]" tbl)
+(puthash "bdo:r" "bdo[dir=rtl]" tbl)
+(puthash "bq" "blockquote" tbl)
+(puthash "btn" "button" tbl)
+(puthash "btn:b" "button[type=button]" tbl)
+(puthash "btn:r" "button[type=reset]" tbl)
+(puthash "btn:s" "button[type=submit]" tbl)
+(puthash "cap" "caption" tbl)
+(puthash "cmd" "command" tbl)
+(puthash "colg" "colgroup" tbl)
+(puthash "colg+" "colgroup>col" tbl)
+(puthash "colgroup+" "colgroup>col" tbl)
+(puthash "datag" "datagrid" tbl)
+(puthash "datal" "datalist" tbl)
+(puthash "det" "details" tbl)
+(puthash "dl+" "dl>dt+dd" tbl)
+(puthash "dlg" "dialog" tbl)
+(puthash "doc" "html>(head>meta[charset=UTF-8]+title{Document})+body" tbl)
+(puthash "doc4" "html>(head>meta[http-equiv=\"Content-Type\" content=\"text/html;charset=UTF-8\"]+title{Document})" tbl)
+(puthash "emb" "embed" tbl)
+(puthash "fig" "figure" tbl)
+(puthash "figc" "figcaption" tbl)
+(puthash "form:get" "form[action method=get]" tbl)
+(puthash "form:post" "form[action method=post]" tbl)
+(puthash "fset" "fieldset" tbl)
+(puthash "fst" "fieldset" tbl)
+(puthash "ftr" "footer" tbl)
+(puthash "hdr" "header" tbl)
+(puthash "html:4s" "!!!4s+doc4[lang=en]" tbl)
+(puthash "html:4t" "!!!4t+doc4[lang=en]" tbl)
+(puthash "html:5" "!!!+doc[lang=en]" tbl)
+(puthash "html:xml" "html[xmlns=http://www.w3.org/1999/xhtml]" tbl)
+(puthash "html:xs" "!!!xs+doc4[xmlns=http://www.w3.org/1999/xhtml xml:lang=en]" tbl)
+(puthash "html:xt" "!!!xt+doc4[xmlns=http://www.w3.org/1999/xhtml xml:lang=en]" tbl)
+(puthash "html:xxs" "!!!xxs+doc4[xmlns=http://www.w3.org/1999/xhtml xml:lang=en]" tbl)
+(puthash "ifr" "iframe" tbl)
+(puthash "input:b" "input:button" tbl)
+(puthash "input:button" "input[type=button]" tbl)
+(puthash "input:c" "input:checkbox" tbl)
+(puthash "input:checkbox" "input[type=checkbox]" tbl)
+(puthash "input:color" "input[type=color]" tbl)
+(puthash "input:date" "input[type=date]" tbl)
+(puthash "input:datetime" "input[type=datetime]" tbl)
+(puthash "input:datetime-local" "input[type=datetime-local]" tbl)
+(puthash "input:email" "input[type=email]" tbl)
+(puthash "input:f" "input:file" tbl)
+(puthash "input:file" "input[type=file]" tbl)
+(puthash "input:h" "input:hidden" tbl)
+(puthash "input:hidden" "input[type=hidden]" tbl)
+(puthash "input:i" "input:image" tbl)
+(puthash "input:image" "input[type=image src alt]" tbl)
+(puthash "input:month" "input[type=month]" tbl)
+(puthash "input:number" "input[type=number]" tbl)
+(puthash "input:p" "input:password" tbl)
+(puthash "input:password" "input[type=password]" tbl)
+(puthash "input:r" "input:radio" tbl)
+(puthash "input:radio" "input[type=radio]" tbl)
+(puthash "input:range" "input[type=range]" tbl)
+(puthash "input:reset" "input[type=reset]" tbl)
+(puthash "input:s" "input:submit" tbl)
+(puthash "input:search" "input[type=search]" tbl)
+(puthash "input:submit" "input[type=submit]" tbl)
+(puthash "input:t" "input" tbl)
+(puthash "input:text" "input" tbl)
+(puthash "input:time" "input[type=time]" tbl)
+(puthash "input:url" "input[type=url]" tbl)
+(puthash "input:week" "input[type=week]" tbl)
+(puthash "kg" "keygen" tbl)
+(puthash "leg" "legend" tbl)
+(puthash "link:atom" "link[rel=alternate type=\"application/atom+xml\" title=Atom href=atom.xml]" tbl)
+(puthash "link:css" "link[rel=stylesheet href=style.css]" tbl)
+(puthash "link:favicon" "link[icon rel=shortcut type=image/x-icon href=favicon.ico]" tbl)
+(puthash "link:print" "link[rel=stylesheet href=print.css media=print]" tbl)
+(puthash "link:rss" "link[rel=alternate type=application/rss+xml title=RSS href=rss.xml]" tbl)
+(puthash "link:touch" "link[rel=apple-touch-icon href=favicon.png]" tbl)
+(puthash "map+" "map>area" tbl)
+(puthash "menu:c" "menu:context" tbl)
+(puthash "menu:context" "menu[type=context]" tbl)
+(puthash "menu:t" "menu:toolbar" tbl)
+(puthash "menu:toolbar" "menu[type=toolbar]" tbl)
+(puthash "meta:compat" "meta[http-equiv=X-UA-Compatible content=\"IE=edge,chrome=1\"]" tbl)
+(puthash "meta:utf" "meta[http-equiv=Content-Type content=\"text/html;charset=UTF-8\"]" tbl)
+(puthash "meta:vp" "meta[name=viewport content=\"width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0\"]" tbl)
+(puthash "meta:win" "meta[http-equiv=Content-Type content=\"text/html;charset=windows-1251\"]" tbl)
+(puthash "obj" "object" tbl)
+(puthash "ol+" "ol>li" tbl)
+(puthash "opt" "option" tbl)
+(puthash "optg" "optgroup" tbl)
+(puthash "optg+" "optgroup>option" tbl)
+(puthash "optgroup+" "optgroup>option" tbl)
+(puthash "out" "output" tbl)
+(puthash "prog" "progress" tbl)
+(puthash "script:src" "script[src]" tbl)
+(puthash "sect" "section" tbl)
+(puthash "select+" "select>option" tbl)
+(puthash "src" "source" tbl)
+(puthash "str" "strong" tbl)
+(puthash "table+" "table>tr>td" tbl)
+(puthash "tarea" "textarea" tbl)
+(puthash "tr+" "tr>td" tbl)
+(puthash "ul+" "ul>li" tbl)
+tbl) tbl)
+(puthash "snippets" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "!!!" "<!doctype html>" tbl)
+(puthash "!!!4s" "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">" tbl)
+(puthash "!!!4t" "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">" tbl)
+(puthash "!!!xs" "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">" tbl)
+(puthash "!!!xt" "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">" tbl)
+(puthash "!!!xxs" "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\" \"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">" tbl)
+(puthash "cc:ie" "<!--[if IE]>\n\t${child}\n<![endif]-->" tbl)
+(puthash "cc:ie6" "<!--[if lte IE 6]>\n\t${child}\n<![endif]-->" tbl)
+(puthash "cc:noie" "<!--[if !IE]><!-->\n\t${child}\n<!--<![endif]-->" tbl)
+tbl) tbl)
+tbl) tbl)
+(puthash "sass" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "snippets" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "@f" "@font-face\n\tfont-family:|\n\tsrc:url(|)\n" tbl)
+(puthash "@f+" "@font-face\n\tfont-family: '${1:FontName}'\n\tsrc: url('${2:FileName}.eot')\n\tsrc: url('${2:FileName}.eot?#iefix') format('embedded-opentype'), url('${2:FileName}.woff') format('woff'), url('${2:FileName}.ttf') format('truetype'), url('${2:FileName}.svg#${1:FontName}') format('svg')\n\tfont-style: ${3:normal}\n\tfont-weight: ${4:normal}\n" tbl)
+(puthash "@kf" "@-webkit-keyframes ${1:identifier}\n\t${2:from}\n\t\t${3}${6}\n\t${4:to}\n\t\t${5}\n\n@-o-keyframes ${1:identifier}\n\t${2:from}\n\t\t${3}${6}\n\t${4:to}\n\t\t${5}\n\n@-moz-keyframes ${1:identifier}\n\t${2:from}\n\t\t${3}${6}\n\t${4:to}\n\t\t${5}\n\n@keyframes ${1:identifier}\n\t${2:from}\n\t\t${3}${6}\n\t${4:to}\n\t\t${5}\n" tbl)
+(puthash "@m" "@media ${1:screen}\n\t|\n" tbl)
+(puthash "@media" "@media ${1:screen}\n\t|\n" tbl)
+tbl) tbl)
+tbl) tbl)
+tbl))
+;; src/preferences.el
+;; This file is generated from conf/preferences.json
+;; Don't edit.
+(emmet-defparameter emmet-preferences
+(let ((tbl (make-hash-table :test 'equal)))
+(puthash "css" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "color" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "case" "auto" tbl)
+(puthash "shortenIfPossible" t tbl)
+(puthash "trailingAliases" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "h" "hidden" tbl)
+(puthash "n" "none" tbl)
+(puthash "s" "solid" tbl)
+(puthash "t" "dotted" tbl)
+tbl) tbl)
+tbl) tbl)
+(puthash "floatUnit" "em" tbl)
+(puthash "intUnit" "px" tbl)
+(puthash "keywordAliases" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "a" "auto" tbl)
+(puthash "da" "dashed" tbl)
+(puthash "do" "dotted" tbl)
+(puthash "i" "inherit" tbl)
+(puthash "s" "solid" tbl)
+(puthash "t" "transparent" tbl)
+tbl) tbl)
+(puthash "keywords" (vector
+"auto"
+"inherit"
+)
+ tbl)
+(puthash "unitAliases" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "-" "px" tbl)
+(puthash "e" "em" tbl)
+(puthash "p" "%" tbl)
+(puthash "r" "rem" tbl)
+(puthash "x" "ex" tbl)
+tbl) tbl)
+(puthash "unitlessProperties" (vector
+"z-index"
+"line-height"
+"opacity"
+"font-weight"
+"zoom"
+)
+ tbl)
+(puthash "vendorPrefixesProperties" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "accelerator" (vector
+"ms"
+)
+ tbl)
+(puthash "accesskey" (vector
+"o"
+)
+ tbl)
+(puthash "animation" (vector
+"webkit"
+"o"
+)
+ tbl)
+(puthash "animation-delay" (vector
+"webkit"
+"moz"
+"o"
+)
+ tbl)
+(puthash "animation-direction" (vector
+"webkit"
+"moz"
+"o"
+)
+ tbl)
+(puthash "animation-duration" (vector
+"webkit"
+"moz"
+"o"
+)
+ tbl)
+(puthash "animation-fill-mode" (vector
+"webkit"
+"moz"
+"o"
+)
+ tbl)
+(puthash "animation-iteration-count" (vector
+"webkit"
+"moz"
+"o"
+)
+ tbl)
+(puthash "animation-name" (vector
+"webkit"
+"moz"
+"o"
+)
+ tbl)
+(puthash "animation-play-state" (vector
+"webkit"
+"moz"
+"o"
+)
+ tbl)
+(puthash "animation-timing-function" (vector
+"webkit"
+"moz"
+"o"
+)
+ tbl)
+(puthash "appearance" (vector
+"webkit"
+"moz"
+)
+ tbl)
+(puthash "backface-visibility" (vector
+"webkit"
+"moz"
+"ms"
+)
+ tbl)
+(puthash "background-clip" (vector
+"webkit"
+"moz"
+)
+ tbl)
+(puthash "background-composite" (vector
+"webkit"
+)
+ tbl)
+(puthash "background-inline-policy" (vector
+"moz"
+)
+ tbl)
+(puthash "background-origin" (vector
+"webkit"
+)
+ tbl)
+(puthash "background-position-x" (vector
+"ms"
+)
+ tbl)
+(puthash "background-position-y" (vector
+"ms"
+)
+ tbl)
+(puthash "background-size" (vector
+"webkit"
+)
+ tbl)
+(puthash "behavior" (vector
+"ms"
+)
+ tbl)
+(puthash "binding" (vector
+"moz"
+)
+ tbl)
+(puthash "block-progression" (vector
+"ms"
+)
+ tbl)
+(puthash "border-bottom-colors" (vector
+"moz"
+)
+ tbl)
+(puthash "border-fit" (vector
+"webkit"
+)
+ tbl)
+(puthash "border-horizontal-spacing" (vector
+"webkit"
+)
+ tbl)
+(puthash "border-image" (vector
+"webkit"
+"moz"
+"o"
+)
+ tbl)
+(puthash "border-left-colors" (vector
+"moz"
+)
+ tbl)
+(puthash "border-radius" (vector
+"webkit"
+"moz"
+)
+ tbl)
+(puthash "border-right-colors" (vector
+"moz"
+)
+ tbl)
+(puthash "border-top-colors" (vector
+"moz"
+)
+ tbl)
+(puthash "border-vertical-spacing" (vector
+"webkit"
+)
+ tbl)
+(puthash "box-align" (vector
+"webkit"
+"moz"
+"ms"
+)
+ tbl)
+(puthash "box-direction" (vector
+"webkit"
+"moz"
+"ms"
+)
+ tbl)
+(puthash "box-flex" (vector
+"webkit"
+"moz"
+"ms"
+)
+ tbl)
+(puthash "box-flex-group" (vector
+"webkit"
+)
+ tbl)
+(puthash "box-line-progression" (vector
+"ms"
+)
+ tbl)
+(puthash "box-lines" (vector
+"webkit"
+"ms"
+)
+ tbl)
+(puthash "box-ordinal-group" (vector
+"webkit"
+"moz"
+"ms"
+)
+ tbl)
+(puthash "box-orient" (vector
+"webkit"
+"moz"
+"ms"
+)
+ tbl)
+(puthash "box-pack" (vector
+"webkit"
+"moz"
+"ms"
+)
+ tbl)
+(puthash "box-reflect" (vector
+"webkit"
+)
+ tbl)
+(puthash "box-shadow" (vector
+"webkit"
+"moz"
+)
+ tbl)
+(puthash "box-sizing" (vector
+"webkit"
+"moz"
+)
+ tbl)
+(puthash "color-correction" (vector
+"webkit"
+)
+ tbl)
+(puthash "column-break-after" (vector
+"webkit"
+)
+ tbl)
+(puthash "column-break-before" (vector
+"webkit"
+)
+ tbl)
+(puthash "column-break-inside" (vector
+"webkit"
+)
+ tbl)
+(puthash "column-count" (vector
+"webkit"
+"moz"
+)
+ tbl)
+(puthash "column-gap" (vector
+"webkit"
+"moz"
+)
+ tbl)
+(puthash "column-rule-color" (vector
+"webkit"
+"moz"
+)
+ tbl)
+(puthash "column-rule-style" (vector
+"webkit"
+"moz"
+)
+ tbl)
+(puthash "column-rule-width" (vector
+"webkit"
+"moz"
+)
+ tbl)
+(puthash "column-span" (vector
+"webkit"
+)
+ tbl)
+(puthash "column-width" (vector
+"webkit"
+"moz"
+)
+ tbl)
+(puthash "content-zoom-boundary" (vector
+"ms"
+)
+ tbl)
+(puthash "content-zoom-boundary-max" (vector
+"ms"
+)
+ tbl)
+(puthash "content-zoom-boundary-min" (vector
+"ms"
+)
+ tbl)
+(puthash "content-zoom-chaining" (vector
+"ms"
+)
+ tbl)
+(puthash "content-zoom-snap" (vector
+"ms"
+)
+ tbl)
+(puthash "content-zoom-snap-points" (vector
+"ms"
+)
+ tbl)
+(puthash "content-zoom-snap-type" (vector
+"ms"
+)
+ tbl)
+(puthash "content-zooming" (vector
+"ms"
+)
+ tbl)
+(puthash "dashboard-region" (vector
+"webkit"
+"o"
+)
+ tbl)
+(puthash "filter" (vector
+"ms"
+)
+ tbl)
+(puthash "float-edge" (vector
+"moz"
+)
+ tbl)
+(puthash "flow-from" (vector
+"ms"
+)
+ tbl)
+(puthash "flow-into" (vector
+"ms"
+)
+ tbl)
+(puthash "font-feature-settings" (vector
+"moz"
+"ms"
+)
+ tbl)
+(puthash "font-language-override" (vector
+"moz"
+)
+ tbl)
+(puthash "font-smoothing" (vector
+"webkit"
+)
+ tbl)
+(puthash "force-broken-image-icon" (vector
+"moz"
+)
+ tbl)
+(puthash "grid-column" (vector
+"ms"
+)
+ tbl)
+(puthash "grid-column-align" (vector
+"ms"
+)
+ tbl)
+(puthash "grid-column-span" (vector
+"ms"
+)
+ tbl)
+(puthash "grid-columns" (vector
+"ms"
+)
+ tbl)
+(puthash "grid-layer" (vector
+"ms"
+)
+ tbl)
+(puthash "grid-row" (vector
+"ms"
+)
+ tbl)
+(puthash "grid-row-align" (vector
+"ms"
+)
+ tbl)
+(puthash "grid-row-span" (vector
+"ms"
+)
+ tbl)
+(puthash "grid-rows" (vector
+"ms"
+)
+ tbl)
+(puthash "high-contrast-adjust" (vector
+"ms"
+)
+ tbl)
+(puthash "highlight" (vector
+"webkit"
+)
+ tbl)
+(puthash "hyphenate-character" (vector
+"webkit"
+)
+ tbl)
+(puthash "hyphenate-limit-after" (vector
+"webkit"
+)
+ tbl)
+(puthash "hyphenate-limit-before" (vector
+"webkit"
+)
+ tbl)
+(puthash "hyphenate-limit-chars" (vector
+"ms"
+)
+ tbl)
+(puthash "hyphenate-limit-lines" (vector
+"ms"
+)
+ tbl)
+(puthash "hyphenate-limit-zone" (vector
+"ms"
+)
+ tbl)
+(puthash "hyphens" (vector
+"webkit"
+"moz"
+"ms"
+)
+ tbl)
+(puthash "image-region" (vector
+"moz"
+)
+ tbl)
+(puthash "ime-mode" (vector
+"ms"
+)
+ tbl)
+(puthash "input-format" (vector
+"o"
+)
+ tbl)
+(puthash "input-required" (vector
+"o"
+)
+ tbl)
+(puthash "interpolation-mode" (vector
+"ms"
+)
+ tbl)
+(puthash "layout-flow" (vector
+"ms"
+)
+ tbl)
+(puthash "layout-grid" (vector
+"ms"
+)
+ tbl)
+(puthash "layout-grid-char" (vector
+"ms"
+)
+ tbl)
+(puthash "layout-grid-line" (vector
+"ms"
+)
+ tbl)
+(puthash "layout-grid-mode" (vector
+"ms"
+)
+ tbl)
+(puthash "layout-grid-type" (vector
+"ms"
+)
+ tbl)
+(puthash "line-box-contain" (vector
+"webkit"
+)
+ tbl)
+(puthash "line-break" (vector
+"webkit"
+"ms"
+)
+ tbl)
+(puthash "line-clamp" (vector
+"webkit"
+)
+ tbl)
+(puthash "link" (vector
+"o"
+)
+ tbl)
+(puthash "link-source" (vector
+"o"
+)
+ tbl)
+(puthash "locale" (vector
+"webkit"
+)
+ tbl)
+(puthash "margin-after-collapse" (vector
+"webkit"
+)
+ tbl)
+(puthash "margin-before-collapse" (vector
+"webkit"
+)
+ tbl)
+(puthash "marquee-dir" (vector
+"o"
+)
+ tbl)
+(puthash "marquee-direction" (vector
+"webkit"
+)
+ tbl)
+(puthash "marquee-increment" (vector
+"webkit"
+)
+ tbl)
+(puthash "marquee-loop" (vector
+"o"
+)
+ tbl)
+(puthash "marquee-repetition" (vector
+"webkit"
+)
+ tbl)
+(puthash "marquee-speed" (vector
+"o"
+)
+ tbl)
+(puthash "marquee-style" (vector
+"webkit"
+"o"
+)
+ tbl)
+(puthash "mask-attachment" (vector
+"webkit"
+)
+ tbl)
+(puthash "mask-box-image" (vector
+"webkit"
+)
+ tbl)
+(puthash "mask-box-image-outset" (vector
+"webkit"
+)
+ tbl)
+(puthash "mask-box-image-repeat" (vector
+"webkit"
+)
+ tbl)
+(puthash "mask-box-image-slice" (vector
+"webkit"
+)
+ tbl)
+(puthash "mask-box-image-source" (vector
+"webkit"
+)
+ tbl)
+(puthash "mask-box-image-width" (vector
+"webkit"
+)
+ tbl)
+(puthash "mask-clip" (vector
+"webkit"
+)
+ tbl)
+(puthash "mask-composite" (vector
+"webkit"
+)
+ tbl)
+(puthash "mask-image" (vector
+"webkit"
+)
+ tbl)
+(puthash "mask-origin" (vector
+"webkit"
+)
+ tbl)
+(puthash "mask-position" (vector
+"webkit"
+)
+ tbl)
+(puthash "mask-repeat" (vector
+"webkit"
+)
+ tbl)
+(puthash "mask-size" (vector
+"webkit"
+)
+ tbl)
+(puthash "nbsp-mode" (vector
+"webkit"
+)
+ tbl)
+(puthash "object-fit" (vector
+"o"
+)
+ tbl)
+(puthash "object-position" (vector
+"o"
+)
+ tbl)
+(puthash "orient" (vector
+"moz"
+)
+ tbl)
+(puthash "outline-radius-bottomleft" (vector
+"moz"
+)
+ tbl)
+(puthash "outline-radius-bottomright" (vector
+"moz"
+)
+ tbl)
+(puthash "outline-radius-topleft" (vector
+"moz"
+)
+ tbl)
+(puthash "outline-radius-topright" (vector
+"moz"
+)
+ tbl)
+(puthash "overflow-style" (vector
+"ms"
+)
+ tbl)
+(puthash "perspective" (vector
+"webkit"
+"moz"
+"ms"
+)
+ tbl)
+(puthash "perspective-origin" (vector
+"webkit"
+"moz"
+"ms"
+)
+ tbl)
+(puthash "perspective-origin-x" (vector
+"ms"
+)
+ tbl)
+(puthash "perspective-origin-y" (vector
+"ms"
+)
+ tbl)
+(puthash "rtl-ordering" (vector
+"webkit"
+)
+ tbl)
+(puthash "scroll-boundary" (vector
+"ms"
+)
+ tbl)
+(puthash "scroll-boundary-bottom" (vector
+"ms"
+)
+ tbl)
+(puthash "scroll-boundary-left" (vector
+"ms"
+)
+ tbl)
+(puthash "scroll-boundary-right" (vector
+"ms"
+)
+ tbl)
+(puthash "scroll-boundary-top" (vector
+"ms"
+)
+ tbl)
+(puthash "scroll-chaining" (vector
+"ms"
+)
+ tbl)
+(puthash "scroll-rails" (vector
+"ms"
+)
+ tbl)
+(puthash "scroll-snap-points-x" (vector
+"ms"
+)
+ tbl)
+(puthash "scroll-snap-points-y" (vector
+"ms"
+)
+ tbl)
+(puthash "scroll-snap-type" (vector
+"ms"
+)
+ tbl)
+(puthash "scroll-snap-x" (vector
+"ms"
+)
+ tbl)
+(puthash "scroll-snap-y" (vector
+"ms"
+)
+ tbl)
+(puthash "scrollbar-arrow-color" (vector
+"ms"
+)
+ tbl)
+(puthash "scrollbar-base-color" (vector
+"ms"
+)
+ tbl)
+(puthash "scrollbar-darkshadow-color" (vector
+"ms"
+)
+ tbl)
+(puthash "scrollbar-face-color" (vector
+"ms"
+)
+ tbl)
+(puthash "scrollbar-highlight-color" (vector
+"ms"
+)
+ tbl)
+(puthash "scrollbar-shadow-color" (vector
+"ms"
+)
+ tbl)
+(puthash "scrollbar-track-color" (vector
+"ms"
+)
+ tbl)
+(puthash "stack-sizing" (vector
+"moz"
+)
+ tbl)
+(puthash "svg-shadow" (vector
+"webkit"
+)
+ tbl)
+(puthash "tab-size" (vector
+"moz"
+"o"
+)
+ tbl)
+(puthash "table-baseline" (vector
+"o"
+)
+ tbl)
+(puthash "text-align-last" (vector
+"ms"
+)
+ tbl)
+(puthash "text-autospace" (vector
+"ms"
+)
+ tbl)
+(puthash "text-blink" (vector
+"moz"
+)
+ tbl)
+(puthash "text-combine" (vector
+"webkit"
+)
+ tbl)
+(puthash "text-decoration-color" (vector
+"moz"
+)
+ tbl)
+(puthash "text-decoration-line" (vector
+"moz"
+)
+ tbl)
+(puthash "text-decoration-style" (vector
+"moz"
+)
+ tbl)
+(puthash "text-decorations-in-effect" (vector
+"webkit"
+)
+ tbl)
+(puthash "text-emphasis-color" (vector
+"webkit"
+)
+ tbl)
+(puthash "text-emphasis-position" (vector
+"webkit"
+)
+ tbl)
+(puthash "text-emphasis-style" (vector
+"webkit"
+)
+ tbl)
+(puthash "text-fill-color" (vector
+"webkit"
+)
+ tbl)
+(puthash "text-justify" (vector
+"ms"
+)
+ tbl)
+(puthash "text-kashida-space" (vector
+"ms"
+)
+ tbl)
+(puthash "text-orientation" (vector
+"webkit"
+)
+ tbl)
+(puthash "text-overflow" (vector
+"ms"
+)
+ tbl)
+(puthash "text-security" (vector
+"webkit"
+)
+ tbl)
+(puthash "text-size-adjust" (vector
+"moz"
+"ms"
+)
+ tbl)
+(puthash "text-stroke-color" (vector
+"webkit"
+)
+ tbl)
+(puthash "text-stroke-width" (vector
+"webkit"
+)
+ tbl)
+(puthash "text-underline-position" (vector
+"ms"
+)
+ tbl)
+(puthash "touch-action" (vector
+"ms"
+)
+ tbl)
+(puthash "transform" (vector
+"webkit"
+"moz"
+"ms"
+"o"
+)
+ tbl)
+(puthash "transform-origin" (vector
+"webkit"
+"moz"
+"ms"
+"o"
+)
+ tbl)
+(puthash "transform-origin-x" (vector
+"ms"
+)
+ tbl)
+(puthash "transform-origin-y" (vector
+"ms"
+)
+ tbl)
+(puthash "transform-origin-z" (vector
+"ms"
+)
+ tbl)
+(puthash "transform-style" (vector
+"webkit"
+"moz"
+"ms"
+)
+ tbl)
+(puthash "transition" (vector
+"webkit"
+"moz"
+"ms"
+"o"
+)
+ tbl)
+(puthash "transition-delay" (vector
+"webkit"
+"moz"
+"ms"
+"o"
+)
+ tbl)
+(puthash "transition-duration" (vector
+"webkit"
+"moz"
+"ms"
+"o"
+)
+ tbl)
+(puthash "transition-property" (vector
+"webkit"
+"moz"
+"ms"
+"o"
+)
+ tbl)
+(puthash "transition-timing-function" (vector
+"webkit"
+"moz"
+"ms"
+"o"
+)
+ tbl)
+(puthash "user-drag" (vector
+"webkit"
+)
+ tbl)
+(puthash "user-focus" (vector
+"moz"
+)
+ tbl)
+(puthash "user-input" (vector
+"moz"
+)
+ tbl)
+(puthash "user-modify" (vector
+"webkit"
+"moz"
+)
+ tbl)
+(puthash "user-select" (vector
+"webkit"
+"moz"
+"ms"
+)
+ tbl)
+(puthash "window-shadow" (vector
+"moz"
+)
+ tbl)
+(puthash "word-break" (vector
+"ms"
+)
+ tbl)
+(puthash "word-wrap" (vector
+"ms"
+)
+ tbl)
+(puthash "wrap-flow" (vector
+"ms"
+)
+ tbl)
+(puthash "wrap-margin" (vector
+"ms"
+)
+ tbl)
+(puthash "wrap-through" (vector
+"ms"
+)
+ tbl)
+(puthash "writing-mode" (vector
+"webkit"
+"ms"
+)
+ tbl)
+tbl) tbl)
+tbl) tbl)
+(puthash "html" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "tags" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "a" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" nil tbl)
+(puthash "defaultAttr" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "href" "" tbl)
+tbl) tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "abbr" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" nil tbl)
+(puthash "defaultAttr" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "title" "" tbl)
+tbl) tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "acronym" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" nil tbl)
+(puthash "defaultAttr" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "title" "" tbl)
+tbl) tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "address" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" t tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "applet" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" t tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "area" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" nil tbl)
+(puthash "defaultAttr" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "alt" "" tbl)
+(puthash "coords" "" tbl)
+(puthash "href" "" tbl)
+(puthash "shape" "" tbl)
+tbl) tbl)
+(puthash "selfClosing" t tbl)
+tbl) tbl)
+(puthash "article" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" t tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "aside" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" t tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "audio" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" t tbl)
+(puthash "defaultAttr" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "src" "" tbl)
+tbl) tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "b" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" nil tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "base" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" nil tbl)
+(puthash "defaultAttr" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "href" "" tbl)
+tbl) tbl)
+(puthash "selfClosing" t tbl)
+tbl) tbl)
+(puthash "basefont" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" nil tbl)
+(puthash "selfClosing" t tbl)
+tbl) tbl)
+(puthash "bdi" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" nil tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "bdo" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" t tbl)
+(puthash "defaultAttr" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "dir" "" tbl)
+tbl) tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "big" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" nil tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "blockquote" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" t tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "body" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" t tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "br" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" nil tbl)
+(puthash "selfClosing" t tbl)
+tbl) tbl)
+(puthash "button" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" nil tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "canvas" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" nil tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "caption" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" nil tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "center" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" nil tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "cite" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" nil tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "code" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" nil tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "col" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" nil tbl)
+(puthash "selfClosing" t tbl)
+tbl) tbl)
+(puthash "colgroup" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" t tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "command" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" nil tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "datalist" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" t tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "dd" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" nil tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "del" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" nil tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "details" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" t tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "dfn" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" nil tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "dialog" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" nil tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "dir" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" t tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "div" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" t tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "dl" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" t tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "dt" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" nil tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "em" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" nil tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "embed" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" nil tbl)
+(puthash "defaultAttr" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "src" "" tbl)
+(puthash "type" "" tbl)
+tbl) tbl)
+(puthash "selfClosing" t tbl)
+tbl) tbl)
+(puthash "fieldset" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" t tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "figcaption" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" nil tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "figure" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" t tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "font" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" nil tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "footer" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" t tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "form" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" t tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "frame" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" nil tbl)
+(puthash "selfClosing" t tbl)
+tbl) tbl)
+(puthash "frameset" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" t tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "h1" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" nil tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "h2" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" nil tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "h3" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" nil tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "h4" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" nil tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "h5" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" nil tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "h6" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" nil tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "head" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" t tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "header" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" t tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "hgroup" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" t tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "hr" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" nil tbl)
+(puthash "selfClosing" t tbl)
+tbl) tbl)
+(puthash "html" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" t tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "i" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" nil tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "iframe" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" nil tbl)
+(puthash "defaultAttr" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "frameborder" "0" tbl)
+(puthash "src" "" tbl)
+tbl) tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "img" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" nil tbl)
+(puthash "defaultAttr" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "alt" "" tbl)
+(puthash "src" "" tbl)
+tbl) tbl)
+(puthash "selfClosing" t tbl)
+tbl) tbl)
+(puthash "input" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" nil tbl)
+(puthash "defaultAttr" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "name" "" tbl)
+(puthash "type" "text" tbl)
+(puthash "value" "" tbl)
+tbl) tbl)
+(puthash "selfClosing" t tbl)
+tbl) tbl)
+(puthash "ins" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" nil tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "kbd" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" nil tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "keygen" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" nil tbl)
+(puthash "selfClosing" t tbl)
+tbl) tbl)
+(puthash "label" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" nil tbl)
+(puthash "defaultAttr" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "for" "" tbl)
+tbl) tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "legend" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" nil tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "li" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" nil tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "link" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" nil tbl)
+(puthash "defaultAttr" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "href" "" tbl)
+(puthash "rel" "stylesheet" tbl)
+tbl) tbl)
+(puthash "selfClosing" t tbl)
+tbl) tbl)
+(puthash "map" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" t tbl)
+(puthash "defaultAttr" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "name" "" tbl)
+tbl) tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "mark" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" nil tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "menu" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" t tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "meta" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" nil tbl)
+(puthash "selfClosing" t tbl)
+tbl) tbl)
+(puthash "meter" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" nil tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "nav" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" t tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "noframes" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" nil tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "noscript" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" nil tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "object" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" nil tbl)
+(puthash "defaultAttr" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "data" "" tbl)
+(puthash "type" "" tbl)
+tbl) tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "ol" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" t tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "optgroup" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" t tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "option" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" nil tbl)
+(puthash "defaultAttr" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "value" "" tbl)
+tbl) tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "output" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" nil tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "p" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" t tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "param" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" nil tbl)
+(puthash "defaultAttr" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "name" "" tbl)
+(puthash "value" "" tbl)
+tbl) tbl)
+(puthash "selfClosing" t tbl)
+tbl) tbl)
+(puthash "pre" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" t tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "progress" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" nil tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "q" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" nil tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "rp" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" nil tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "rt" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" nil tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "ruby" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" nil tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "s" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" nil tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "samp" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" nil tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "script" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" t tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "section" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" t tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "select" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" t tbl)
+(puthash "defaultAttr" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "id" "" tbl)
+(puthash "name" "" tbl)
+tbl) tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "small" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" nil tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "source" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" nil tbl)
+(puthash "selfClosing" t tbl)
+tbl) tbl)
+(puthash "span" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" nil tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "strike" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" nil tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "strong" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" nil tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "style" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" t tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "sub" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" nil tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "summary" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" nil tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "sup" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" nil tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "table" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" t tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "tbody" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" t tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "td" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" nil tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "textarea" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" t tbl)
+(puthash "defaultAttr" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "cols" "30" tbl)
+(puthash "id" "" tbl)
+(puthash "name" "" tbl)
+(puthash "rows" "10" tbl)
+tbl) tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "tfoot" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" t tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "th" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" nil tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "thead" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" t tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "time" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" nil tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "title" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" nil tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "tr" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" t tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "track" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" nil tbl)
+(puthash "selfClosing" t tbl)
+tbl) tbl)
+(puthash "tt" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" nil tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "u" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" nil tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "ul" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" t tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "var" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" nil tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "video" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" t tbl)
+(puthash "defaultAttr" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "src" "" tbl)
+tbl) tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+(puthash "wbr" (let ((tbl (make-hash-table :test 'equal)))
+(puthash "block" nil tbl)
+(puthash "selfClosing" nil tbl)
+tbl) tbl)
+tbl) tbl)
+tbl) tbl)
+tbl))
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; XML abbrev
+
+(require 'cl-lib)
+
+(emmet-defparameter
+ emmet-tag-aliases-table
+ (gethash "aliases" (gethash "html" emmet-snippets)))
+
+(defun emmet-expr (input)
+ "Parse a zen coding expression with optional filters."
+ (emmet-pif (emmet-extract-expr-filters input)
+ (let ((input (elt it 1))
+ (filters (elt it 2)))
+ (emmet-pif (emmet-extract-filters filters)
+ (emmet-filter input it)
+ it))
+ (emmet-filter input (emmet-default-filter))))
+
+(defun emmet-subexpr (input)
+ "Parse a zen coding expression with no filter. This pretty much defines precedence."
+ (emmet-run emmet-siblings
+ it
+ (emmet-run emmet-parent-child
+ it
+ (emmet-run emmet-multiplier
+ it
+ (emmet-run emmet-pexpr
+ it
+ (emmet-run emmet-text
+ it
+ (emmet-run emmet-tag
+ it
+ '(error "no match, expecting ( or a-zA-Z0-9"))))))))
+
+(defun emmet-extract-expr-filters (input)
+ (cl-flet ((string-match-reverse (str regexp)
+ (emmet-aif (string-match regexp (reverse str)) (- (length str) 1 it))))
+ (let ((err '(error "expected expr|filter")))
+ (emmet-aif (string-match-reverse input "|")
+ (if (string-match "[\"}]" (substring input (+ it 1)))
+ err
+ `(,input
+ ,(substring input 0 it)
+ ,(substring input (+ it 1))))
+ err))))
+
+(defun emmet-extract-filters (input)
+ "Extract filters from expression."
+ (emmet-pif (emmet-parse "\\([^\\|]+?\\)|" 2 "" it)
+ (let ((filter-name (elt it 1))
+ (more-filters (elt it 2)))
+ (emmet-pif (emmet-extract-filters more-filters)
+ (cons filter-name it)
+ it))
+ (emmet-parse "\\([^\\|]+\\)" 1 "filter name" `(,(elt it 1)))))
+
+(defun emmet-extract-inner-text (input)
+ "Extract inner-text in the form of {inner_text}...
+Right curly braces can be escaped by backslash, i.e. '\\}'
+Return `(,inner-text ,input-without-inner-text) if succeeds, otherwise return
+`(error ,error-message)"
+ (cl-labels (
+ (string-find-paired-right-curly-brace
+ (str)
+ (cl-labels ((char-at-pos (str pos) (string-to-char (substring str pos)))
+ (helper (str pos cnt)
+ (let ((len (length str)))
+ (if (>= pos len) nil
+ (let ((c (char-at-pos str pos)))
+ (cond ((char-equal c ?{) (setq cnt (+ cnt 1)))
+ ((and (char-equal c ?}) (not (char-equal (char-at-pos str (- pos 1)) ?\\))) (setq cnt (- cnt 1))))
+ (if (= cnt 0) pos (helper str (+ pos 1) cnt)))))
+ ))
+ (helper str 0 0))))
+ (let ((err '(error "expected inner text")))
+ (if (or (< (length input) 2) (not (char-equal (string-to-char input) ?{))) err
+ (emmet-aif (string-find-paired-right-curly-brace input)
+ `(,input
+ ,(substring input 1 it)
+ ,(substring input (+ it 1)))
+ err)))))
+
+(defun emmet-filter (input filters)
+ "Construct AST with specified filters."
+ (emmet-pif (emmet-subexpr input)
+ (let ((result (car it))
+ (rest (cdr it)))
+ `((filter ,filters ,result) . ,rest))
+ it))
+
+(defun emmet-default-filter ()
+ "Default filter(s) to be used if none is specified."
+ (or emmet-file-filter
+ (let* ((file-ext (car (emmet-regex ".*\\(\\..*\\)" (or (buffer-file-name) "") 1)))
+ (defaults '(".html" ("html")
+ ".htm" ("html")
+ ".haml" ("haml")
+ ".clj" ("hic")
+ ".cljs" ("hic")))
+ (default-else emmet-fallback-filter)
+ (selected-default (member file-ext defaults)))
+ (if selected-default
+ (cadr selected-default)
+ default-else))))
+
+(defun emmet-numbering (input)
+ (emmet-parse
+ "\\(\\$+\\)" 2 "numbering, $"
+ (let ((doller (elt it 1)))
+ (emmet-pif (emmet-parse
+ "@\\([0-9-][0-9]*\\)" 2 "numbering args"
+ (let* ((args (read (elt it 1)))
+ (direction (not (or (eq '- args) (minusp args))))
+ (base (if (eq '- args) 1 (abs args))))
+ `((n ,(length doller) ,direction ,base) . ,input)))
+ it
+ `((n ,(length doller) t 1) . ,input)))))
+
+(defun emmet-split-numbering-expressions (input)
+ (cl-labels
+ ((iter (input)
+ (emmet-aif (emmet-regex "\\([^$]*\\)\\(\\$.*\\)" input '(1 2))
+ (let ((prefix (car it))
+ (input (cadr it)))
+ (if (and (< 0 (length prefix)) ; check if ..\\$... or ...$...
+ (string-equal (substring prefix -1) "\\"))
+ `(,(store-substring prefix (- (length prefix) 1) ?$)
+ ,@(iter (substring input 1)))
+ (let ((res (emmet-numbering input)))
+ `(,prefix ,(car res) ,@(iter (cdr res))))))
+ (list input))))
+ (let ((res (iter input)))
+ (if (cl-every #'stringp res)
+ (apply #'concat res)
+ `(numberings ,@res)))))
+
+(defun emmet-instantiate-numbering-expression (i lim exp)
+ (cl-labels ((instantiate
+ (i lim exps)
+ (apply #'concat
+ (mapcar
+ (lambda (exp)
+ (if (listp exp)
+ (let ((digits (second exp))
+ (direction (third exp))
+ (base (fourth exp)))
+ (let ((num (if direction (+ base i)
+ (- (+ lim (- base 1)) i))))
+ (format (concat "%0" (format "%d" digits) "d") num)))
+ exp)) exps)))
+ (cl-search
+ (i lim exp)
+ (if (listp exp)
+ (if (eql (car exp) 'numberings)
+ (instantiate i lim (cdr exp))
+ ;; Should do like this for real searching.
+ ;; But stack overflow occurs.
+ ;; (cons (search-numberings i lim (car exp))
+ ;; (search-numberings i lim (cdr exp)))
+ (mapcar (lambda (exp) (cl-search i lim exp)) exp))
+ exp)))
+ (cl-search i lim exp)))
+
+(defun emmet-multiply-expression (multiplicand exp)
+ (cl-loop for i to (- multiplicand 1) collect
+ (emmet-instantiate-numbering-expression i multiplicand exp)))
+
+(defun emmet-multiplier (input)
+ (emmet-pif (emmet-run emmet-pexpr
+ it
+ (emmet-run emmet-tag
+ it
+ (emmet-run emmet-text
+ it
+ '(error "expected *n multiplier"))))
+ (let* ((expr (car it)) (input (cdr it))
+ (multiplier expr))
+ (emmet-parse "\\*\\([0-9]+\\)" 2 "*n where n is a number"
+ (let ((multiplicand (read (elt it 1))))
+ `((list ,(emmet-multiply-expression
+ multiplicand
+ multiplier)) . ,input))))))
+
+(defun emmet-tag (input)
+ "Parse a tag."
+ (emmet-run
+ emmet-tagname
+ (let ((tagname (cadr expr))
+ (has-body? (cddr expr)))
+ (emmet-pif
+ (emmet-run emmet-identifier
+ (emmet-tag-classes
+ `(tag (,tagname ,has-body? ,(cddr expr))) input)
+ (emmet-tag-classes
+ `(tag (,tagname ,has-body? nil)) input))
+ (let ((tag-data (cadar it)) (input (cdr it)))
+ (emmet-pif (emmet-run
+ emmet-properties
+ (let ((props (cdr expr)))
+ `((tag ,(append tag-data (list props))) . ,input))
+ `((tag ,(append tag-data '(nil))) . ,input))
+ (let ((expr (car it)) (input (cdr it)))
+ (cl-destructuring-bind (expr . input)
+ (emmet-tag-text expr input)
+ (or
+ (emmet-expand-lorem expr input)
+ (emmet-expand-tag-alias expr input))))))))
+ (emmet-default-tag input)))
+
+(defun emmet-get-first-tag (expr)
+ (if (listp expr)
+ (if (listp (car expr))
+ (emmet-get-first-tag (car expr))
+ (if (eql (car expr) 'tag)
+ expr
+ (emmet-get-first-tag (cdr expr))))
+ nil))
+
+(defun emmet-lorem (input)
+ (emmet-aif
+ (and (stringp input) (emmet-regex "\\(?:lorem\\|ipsum\\)\\([0-9]*\\)" input '(0 1)))
+ (let ((w (elt it 1)))
+ (let ((word-num (if (string-equal w "") 30 (read w))))
+ word-num))))
+
+(defun emmet-expand-lorem (tag input)
+ (let ((tag-data (cadr tag)))
+ (let ((tag-name (car tag-data)))
+ (emmet-aif (emmet-lorem tag-name)
+ (if (cl-equalp (cdr tag-data) '(t nil nil nil nil))
+ `((text (lorem ,it)) . ,input)
+ `((tag ("div" ,@(cl-subseq tag-data 1 -1) (lorem ,it))) . ,input))))))
+
+(defun emmet-expand-tag-alias (tag input)
+ (let ((tag-data (cadr tag)))
+ (let ((tag-name (car tag-data)))
+ (emmet-aif
+ (gethash tag-name emmet-tag-aliases-table)
+ (let ((expr (if (stringp it)
+ (emmet-subexpr it)
+ it)))
+ (prog1
+ (let ((rt (copy-tree expr)))
+ (let ((first-tag-data (cadr (emmet-get-first-tag rt))))
+ (setf (second first-tag-data) (second tag-data))
+ (setf (third first-tag-data) (third tag-data))
+ (setf (fourth first-tag-data)
+ (cl-remove-duplicates
+ (append (fourth first-tag-data)
+ (fourth tag-data)) :test #'string=))
+ (setf (fifth first-tag-data)
+ (cl-remove-duplicates
+ (append (fifth first-tag-data)
+ (fifth tag-data))
+ :test #'(lambda (p1 p2)
+ (eql (car p1) (car p2)))))
+ (setf (cl-sixth first-tag-data) (cl-sixth tag-data))
+ (setf (cdr rt) (concat (cdr rt) input))
+ rt))
+ (puthash tag-name expr emmet-tag-aliases-table)))
+ `(,tag . ,input)))))
+
+(defun emmet-default-tag (input)
+ "Parse a #id or .class"
+ (emmet-parse "\\([#|\\.]\\)" 1 "tagname"
+ (emmet-tag (concat "div" (elt it 0)))))
+
+(defun emmet-tag-text (tag input)
+ (let ((tag-data (cadr tag)))
+ (emmet-run emmet-text
+ (let ((txt (cadr expr)))
+ `((tag ,(append tag-data (list txt))) . ,input))
+ `((tag ,(append tag-data '(nil))) . ,input))))
+
+(defun emmet-tag-props (tag input)
+ (let ((tag-data (cadr tag)))
+ (emmet-run emmet-properties
+ (let ((props (cdr expr)))
+ `((tag ,(append tag-data (list props))) . ,input))
+ `((tag ,(append tag-data '(nil))) . ,input))))
+
+(defun emmet-props (input)
+ "Parse many props."
+ (emmet-run emmet-prop
+ (emmet-pif (emmet-props input)
+ `((props . ,(cons expr (cdar it))) . ,(cdr it))
+ `((props . ,(list expr)) . ,input))))
+
+(defun emmet-prop (input)
+ (emmet-parse
+ " *" 1 "space"
+ (emmet-run
+ emmet-name
+ (let ((name (cdr expr)))
+ (emmet-pif (emmet-parse "\\.\\(.*?\\)" 2 "."
+ `((,(read name)) . ,input))
+ it
+ (emmet-pif (emmet-prop-value name input)
+ it
+ `((,(read name) "") . ,input)))))))
+
+(defun emmet-prop-value (name input)
+ (emmet-pif (emmet-parse
+ "=\"\\(.*?\\)\"" 2
+ "=\"property value\""
+ (let ((value (elt it 1))
+ (input (elt it 2)))
+ `((,(read name) ,(emmet-split-numbering-expressions value)) . ,input)))
+ it
+ (let ((emmet--prop-value-parse-any
+ (lambda () (emmet-parse
+ "=\\([^\\,\\+\\>\\{\\}\\ )]*\\)" 2
+ "=property value"
+ (let ((value (elt it 1))
+ (input (elt it 2)))
+ `((,(read name) ,(emmet-split-numbering-expressions value)) . ,input))))))
+ (if (emmet-jsx-supported-mode?)
+ (emmet-pif
+ (emmet-parse "=\\({.*?}\\)" 2
+ "=\"property value\""
+ (let ((value (elt it 1))
+ (input (elt it 2)))
+ `((,(read name) ,(emmet-split-numbering-expressions value)) . ,input)))
+ it
+ (funcall emmet--prop-value-parse-any))
+ (funcall emmet--prop-value-parse-any)))))
+
+(defun emmet-tag-classes (tag input)
+ (let ((tag-data (cadr tag)))
+ (emmet-run emmet-classes
+ (let ((classes (mapcar (lambda (cls) (cdadr cls))
+ (cdr expr))))
+ `((tag ,(append tag-data (list classes))) . ,input))
+ `((tag ,(append tag-data '(nil))) . ,input))))
+
+(defun emmet-tagname (input)
+ "Parse a tagname a-zA-Z0-9 tagname (e.g. html/head/xsl:if/br)."
+ (emmet-parse "\\([a-zA-Z!][a-zA-Z0-9:!$@-]*\/?\\)" 2 "tagname, a-zA-Z0-9"
+ (let* ((tag-spec (elt it 1))
+ (empty-tag (emmet-regex "\\([^\/]*\\)\/" tag-spec 1))
+ (tag (emmet-split-numbering-expressions
+ (if empty-tag (car empty-tag) tag-spec))))
+ `((tagname . (,tag . ,(not empty-tag))) . ,input))))
+
+(defun emmet-text (input)
+ "A zen coding expression innertext."
+ (emmet-pif (emmet-extract-inner-text input)
+ (let ((txt (emmet-split-numbering-expressions (elt it 1))))
+ (if (listp txt)
+ (setq txt (cons (car txt) (cons (replace-regexp-in-string "\\\\\\(.\\)" "\\1" (cadr txt)) (cddr txt))))
+ (setq txt (replace-regexp-in-string "\\\\\\(.\\)" "\\1" txt)))
+ `((text ,txt) . ,(elt it 2)))
+ '(error "expected inner text")))
+
+;; (defun emmet-text (input)
+;; "A zen coding expression innertext."
+;; (emmet-parse "{\\(\\(?:\\\\.\\|[^\\\\}]\\|\\\\}\\)*?\\)}" 2 "inner text"
+;; (let ((txt (emmet-split-numbering-expressions (elt it 1))))
+;; (if (listp txt)
+;; (setq txt (cons (car txt) (cons (replace-regexp-in-string "\\\\\\(.\\)" "\\1" (cadr txt)) (cddr txt))))
+;; (setq txt (replace-regexp-in-string "\\\\\\(.\\)" "\\1" txt)))
+;; `((text ,txt) . ,input))
+;; '(error "expected inner text")))
+
+(defun emmet-properties (input)
+ "A bracketed emmet property expression."
+ (emmet-parse "\\[\\(.*?\\)\\]" 2 "properties"
+ `(,(car (emmet-props (elt it 1))) . ,input)))
+
+
+(defun emmet-pexpr (input)
+ "A zen coding expression with parentheses around it."
+ (emmet-parse "(" 1 "("
+ (emmet-run emmet-subexpr
+ (emmet-aif (emmet-regex ")" input '(0 1))
+ `(,expr . ,(elt it 1))
+ '(error "expecting `)'")))))
+
+(defun emmet-parent-child (input)
+ "Parse an tag>e expression, where `n' is an tag and `e' is any
+ expression."
+ (cl-labels
+ ((listing (parents child input)
+ (let ((len (length parents)))
+ `((list ,(map 'list
+ (lambda (parent i)
+ `(parent-child ,parent
+ ,(emmet-instantiate-numbering-expression i len child)))
+ parents
+ (cl-loop for i to (- len 1) collect i))) . ,input))))
+ (emmet-run
+ emmet-multiplier
+ (let* ((items (cadr expr))
+ (rest (emmet-child-sans expr input)))
+ (if (not (eq (car rest) 'error))
+ (let ((child (car rest))
+ (input (cdr rest)))
+
+ (emmet-aif (emmet-regex "^" input '(0 1))
+ (let ((input (elt it 1)))
+ (emmet-run
+ emmet-subexpr
+ `((sibling ,(car (listing items child "")) ,expr) . ,input)
+ (listing items child input)))
+ (listing items child input)))
+ '(error "expected child")))
+ (emmet-run emmet-tag
+ (emmet-child expr input)
+ '(error "expected parent")))))
+
+(defun emmet-child-sans (parent input)
+ (emmet-parse ">" 1 ">"
+ (emmet-run emmet-subexpr
+ it
+ '(error "expected child"))))
+
+(defun emmet-child (parent input)
+ (emmet-parse ">" 1 ">"
+ (emmet-run emmet-subexpr
+ (let ((child expr))
+ (emmet-aif (emmet-regex "^" input '(0 1))
+ (let ((input (elt it 1)))
+ (emmet-run emmet-subexpr
+ `((sibling (parent-child ,parent ,child) ,expr) . ,input)
+ `((parent-child ,parent ,child) . ,input)))
+ `((parent-child ,parent ,child) . ,input)))
+ '(error "expected child"))))
+
+(defun emmet-sibling (input)
+ (emmet-por emmet-pexpr emmet-multiplier
+ it
+ (emmet-run emmet-tag
+ it
+ (emmet-run emmet-text
+ it
+ '(error "expected sibling")))))
+
+(defun emmet-siblings (input)
+ "Parse an e+e expression, where e is an tag or a pexpr."
+ (emmet-run emmet-sibling
+ (let ((parent expr))
+ (emmet-parse
+ "\\+" 1 "+"
+ (emmet-run
+ emmet-subexpr
+ (let ((child expr))
+ `((sibling ,parent ,child) . ,input))
+ (emmet-expand parent input))))
+ '(error "expected first sibling")))
+
+(defun emmet-expand (parent input)
+ "Parse an e+ expression, where e is an expandable tag"
+ (let* ((parent-tag (car (cadr parent))))
+ (setf (caadr parent) (concat parent-tag "+"))
+ (cl-destructuring-bind (parent . input)
+ (emmet-expand-tag-alias parent input)
+ (emmet-pif (emmet-parse "+\\(.*\\)" 1 "+expr"
+ (emmet-subexpr (elt it 1)))
+ `((sibling ,parent ,@it))
+ `(,parent . ,input)))))
+
+(defun emmet-name (input)
+ "Parse a class or identifier name, e.g. news, footer, mainimage"
+ (emmet-parse "\\([a-zA-Z$@][a-zA-Z0-9$@_:-]*\\)" 2 "class or identifer name"
+ `((name . ,(emmet-split-numbering-expressions
+ (elt it 1))) . ,input)))
+
+(defun emmet-class (input)
+ "Parse a classname expression, e.g. .foo"
+ (emmet-parse "\\." 1 "."
+ (emmet-run emmet-name
+ `((class ,expr) . ,input)
+ '(error "expected class name"))))
+(defun emmet-identifier (input)
+ "Parse an identifier expression, e.g. #foo"
+ (emmet-parse "#" 1 "#"
+ (emmet-run emmet-name
+ `((identifier . ,expr) . ,input))))
+
+(defun emmet-classes (input)
+ "Parse many classes."
+ (emmet-run emmet-class
+ (emmet-pif (emmet-classes input)
+ `((classes . ,(cons expr (cdar it))) . ,(cdr it))
+ `((classes . ,(list expr)) . ,input))
+ '(error "expected class")))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Zen coding transformer from AST to string
+
+(defvar emmet-leaf-function nil
+ "Function to execute when expanding a leaf node in the
+ Emmet AST.")
+
+(defvar emmet-jsx-className-braces? nil
+ "Wether to wrap classNames in {} instead of \"\"")
+
+(emmet-defparameter
+ emmet-tag-settings-table
+ (gethash "tags" (gethash "html" emmet-preferences)))
+
+(emmet-defparameter
+ emmet-tag-snippets-table
+ (gethash "snippets" (gethash "html" emmet-snippets)))
+
+(defvar emmet-filters
+ '("html" (emmet-primary-filter emmet-make-html-tag)
+ "c" (emmet-primary-filter emmet-make-commented-html-tag)
+ "haml" (emmet-primary-filter emmet-make-haml-tag)
+ "hic" (emmet-primary-filter emmet-make-hiccup-tag)
+ "e" (emmet-escape-xml)))
+
+(defun emmet-instantiate-lorem-expression (input)
+ (if input
+ (if (consp input)
+ (if (and (eql (car input) 'lorem) (numberp (cadr input)))
+ (emmet-lorem-generate (cadr input))
+ (cons (emmet-instantiate-lorem-expression (car input))
+ (emmet-instantiate-lorem-expression (cdr input))))
+ input)))
+
+(defun emmet-primary-filter (input proc)
+ "Process filter that needs to be executed first, ie. not given output from other filter."
+ (if (listp input)
+ (let ((tag-maker (cadr proc)))
+ (emmet-transform-ast
+ (emmet-instantiate-lorem-expression input)
+ tag-maker))
+ nil))
+
+(defun emmet-process-filter (filters input)
+ "Process filters, chain one filter output as the input of the next filter."
+ (let ((filter-data (member (car filters) emmet-filters))
+ (more-filters (cdr filters)))
+ (if filter-data
+ (let* ((proc (cadr filter-data))
+ (fun (car proc))
+ (filter-output (funcall fun input proc)))
+ (if more-filters
+ (emmet-process-filter more-filters filter-output)
+ filter-output))
+ nil)))
+
+(defun emmet-make-tag (tag-maker tag-info &optional content)
+ "Extract tag info and pass them to tag-maker."
+ (let* ((name (pop tag-info))
+ (has-body? (pop tag-info))
+ (id (pop tag-info))
+ (classes (pop tag-info))
+ (props (pop tag-info))
+ (txt (pop tag-info))
+ (settings (gethash name emmet-tag-settings-table))
+ (self-closing?
+ (and (not (or txt content))
+ (or (not has-body?)
+ (and settings (gethash "selfClosing" settings))))))
+ (funcall tag-maker name has-body? id classes props txt settings
+ (if content content
+ (if (and emmet-leaf-function (not self-closing?))
+ (funcall emmet-leaf-function))))))
+
+(defun emmet-hash-to-list (hash &optional proc)
+ (unless proc (setq proc #'cons))
+ (cl-loop for key being the hash-keys of hash using (hash-values val)
+ collect (funcall proc key val)))
+
+(defun emmet-merge-tag-props (default-table tag-props)
+ (if default-table
+ (let ((tbl (copy-hash-table default-table)))
+ (cl-loop for prop in tag-props do
+ (puthash (symbol-name (car prop)) (cadr prop) tbl))
+ (emmet-hash-to-list tbl 'list))
+ tag-props))
+
+(defun emmet-html-snippets-instantiate-lambda (src)
+ (let ((lines (mapcar
+ #'(lambda (src)
+ (if (string-match "^\\(.*\\)${child}\\(.*\\)$" src)
+ (mapcar (lambda (i)
+ (match-string i src))
+ '(1 2))
+ (list src)))
+ (split-string src "\n"))))
+ (cl-labels
+ ((iter
+ (l m a b)
+ (if l
+ (if (< 1 (length (car l)))
+ (iter (cdr l)
+ 'b
+ (cons (caar l) a)
+ (cons (cadar l) b))
+ (if (eql m 'a)
+ (iter (cdr l) m (cons (caar l) a) b)
+ (iter (cdr l) m a (cons (caar l) b))))
+ (if b
+ `(lambda (contents)
+ (concat
+ ,(emmet-join-string (reverse a) "\n")
+ contents
+ ,(emmet-join-string (reverse b) "\n")))
+ `(lambda (contents)
+ (concat
+ ,(emmet-join-string (reverse a) "\n")
+ contents))))))
+ (eval (iter lines 'a nil nil)))))
+
+(defun emmet-jsx-supported-mode? ()
+ "Is the current mode we're on enabled for jsx class attribute expansion?"
+ (member major-mode emmet-jsx-major-modes))
+
+(defun emmet-make-html-tag (tag-name tag-has-body? tag-id tag-classes tag-props tag-txt settings content)
+ "Create HTML markup string"
+ (emmet-aif
+ (gethash tag-name emmet-tag-snippets-table)
+
+ (let ((fn (if (stringp it)
+ (emmet-html-snippets-instantiate-lambda it)
+ it)))
+ (prog1
+ (funcall fn content)
+ (puthash tag-name fn emmet-tag-snippets-table)))
+
+ (let* ((id (emmet-concat-or-empty " id=\"" tag-id "\""))
+ (class-attr (if (emmet-jsx-supported-mode?)
+ (if emmet-jsx-className-braces?
+ " className={"
+ " className=\"")
+ " class=\""))
+ (class-list-closer (if emmet-jsx-className-braces? "}" "\""))
+ (class-list-delimiter (if emmet-jsx-className-braces? "." " "))
+ (classes (emmet-mapconcat-or-empty class-attr tag-classes class-list-delimiter class-list-closer))
+ (props (let* ((tag-props-default
+ (and settings (gethash "defaultAttr" settings)))
+ (merged-tag-props
+ (emmet-merge-tag-props
+ tag-props-default
+ tag-props)))
+ (emmet-mapconcat-or-empty
+ " " merged-tag-props " " nil
+ (lambda (prop)
+ (let* ((key-raw (car prop))
+ (key-str
+ (if (symbolp key-raw)
+ (symbol-name key-raw)
+ key-raw))
+ (key
+ (if (and (emmet-jsx-supported-mode?)
+ (string= key-str "for"))
+ "htmlFor"
+ key-str))
+ (val (cadr prop))
+ (format-string
+ (if (and (emmet-jsx-supported-mode?)
+ (emmet-jsx-prop-value-var? val))
+ "%s=%s"
+ "%s=\"%s\"")))
+ (if val (format format-string key val) key))))))
+ (content-multiline? (and content (string-match "\n" content)))
+ (block-tag? (and settings (gethash "block" settings)))
+ (self-closing? (and (not (or tag-txt content))
+ (or (not tag-has-body?)
+ (and settings (gethash "selfClosing" settings)))))
+ (block-indentation? (or content-multiline? (and block-tag? content)))
+ (lf (if block-indentation? "\n")))
+ (concat "<" tag-name id classes props
+ (if self-closing?
+ (concat emmet-self-closing-tag-style ">")
+ (concat ">"
+ (if tag-txt
+ (if block-indentation?
+ (emmet-indent tag-txt)
+ tag-txt))
+ (if content
+ (if block-indentation?
+ (emmet-indent content)
+ content))
+ lf
+ "</" tag-name ">"))))))
+
+(defun emmet-make-commented-html-tag (tag-name tag-has-body? tag-id tag-classes tag-props tag-txt settings content)
+ "Create HTML markup string with extra comments for elements with #id or .classes"
+ (let ((body (emmet-make-html-tag tag-name tag-has-body? tag-id tag-classes tag-props tag-txt settings content)))
+ (if (or tag-id tag-classes)
+ (let ((id (emmet-concat-or-empty "#" tag-id))
+ (classes (emmet-mapconcat-or-empty "." tag-classes ".")))
+ (concat "<!-- " id classes " -->\n"
+ body
+ "\n<!-- /" id classes " -->"))
+ body)))
+
+(defun emmet-make-haml-tag (tag-name tag-has-body? tag-id tag-classes tag-props tag-txt settings content)
+ "Create HAML string"
+ (let ((name (if (and (equal tag-name "div")
+ (or tag-id tag-classes))
+ ""
+ (concat "%" tag-name)))
+ (id (emmet-concat-or-empty "#" tag-id))
+ (classes (emmet-mapconcat-or-empty "." tag-classes "."))
+ (props (emmet-mapconcat-or-empty
+ "{" tag-props ", " "}"
+ (lambda (prop)
+ (concat ":" (symbol-name (car prop)) " => \"" (cadr prop) "\"")))))
+ (concat name id classes props
+ (if tag-txt
+ (emmet-indent tag-txt))
+ (if content
+ (emmet-indent content)))))
+
+(defun emmet-make-hiccup-tag (tag-name tag-has-body? tag-id tag-classes tag-props tag-txt settings content)
+ "Create Hiccup string"
+ (let* ((id (emmet-concat-or-empty "#" tag-id))
+ (classes (emmet-mapconcat-or-empty "." tag-classes "."))
+ (props (emmet-mapconcat-or-empty
+ " {" tag-props ", " "}"
+ (lambda (prop)
+ (concat ":" (symbol-name (car prop)) " \"" (cadr prop) "\""))))
+ (content-multiline? (and content (string-match "\n" content)))
+ (block-tag? (and settings (gethash "block" settings)))
+ (block-indentation? (or content-multiline? (and block-tag? content))))
+ (concat "[:" tag-name id classes props
+ (if tag-txt
+ (let ((tag-txt-quoted (concat "\"" tag-txt "\"")))
+ (if block-indentation?
+ (emmet-indent tag-txt-quoted)
+ (concat " " tag-txt-quoted))))
+ (if content
+ (if block-indentation?
+ (emmet-indent content)
+ (concat " " content)))
+ "]")))
+
+(defun emmet-make-text (tag-maker text)
+ (cond
+ ((eq tag-maker 'emmet-make-hiccup-tag)
+ (concat "\"" text "\""))
+ (t text)))
+
+(defun emmet-concat-or-empty (prefix body &optional suffix)
+ "Return prefixed suffixed text or empty string."
+ (if body
+ (concat prefix body suffix)
+ ""))
+
+(defun emmet-mapconcat-or-empty (prefix list-body delimiter &optional suffix map-fun)
+ "Return prefixed suffixed mapconcated text or empty string."
+ (if list-body
+ (let* ((mapper (if map-fun map-fun 'identity))
+ (body (mapconcat mapper list-body delimiter)))
+ (concat prefix body suffix))
+ ""))
+
+(defun emmet-escape-xml (input proc)
+ "Escapes XML-unsafe characters: <, > and &."
+ (replace-regexp-in-string
+ "<" "&lt;"
+ (replace-regexp-in-string
+ ">" "&gt;"
+ (replace-regexp-in-string
+ "&" "&amp;"
+ (if (stringp input)
+ input
+ (emmet-process-filter (emmet-default-filter) input))))))
+
+(defun emmet-html-transform (input)
+ (let ((ast (car (emmet-expr input))))
+ (when (not (eq ast 'error))
+ (emmet-transform-ast-with-filters ast))))
+
+(defun emmet-transform-ast-with-filters (ast-with-filters)
+ "Transform AST (containing filter data) into string."
+ (let ((filters (cadr ast-with-filters))
+ (ast (caddr ast-with-filters)))
+ (emmet-process-filter filters ast)))
+
+(defun emmet-transform-ast (ast tag-maker)
+ "Transform AST (without filter data) into string."
+ (let ((type (car ast)))
+ (cond
+ ((eq type 'list)
+ (mapconcat (lexical-let ((make-tag-fun tag-maker))
+ #'(lambda (sub-ast)
+ (emmet-transform-ast sub-ast make-tag-fun)))
+ (cadr ast)
+ "\n"))
+ ((eq type 'tag)
+ (emmet-make-tag tag-maker (cadr ast)))
+ ((eq type 'text)
+ (emmet-make-text tag-maker (cadr ast)))
+ ((eq type 'parent-child)
+ (let ((parent (cadadr ast))
+ (children (emmet-transform-ast (caddr ast) tag-maker)))
+ (emmet-make-tag tag-maker parent children)))
+ ((eq type 'sibling)
+ (let ((sib1 (emmet-transform-ast (cadr ast) tag-maker))
+ (sib2 (emmet-transform-ast (caddr ast) tag-maker)))
+ (concat sib1 "\n" sib2))))))
+
+;; Indents text rigidly by inserting spaces
+;; Only matters if emmet-indent-after-insert is set to nil
+(defun emmet-indent (text)
+ "Indent the text"
+ (if text
+ (replace-regexp-in-string "\n" (concat "\n" (make-string emmet-indentation ?\ )) (concat "\n" text))
+ nil))
+(defvar emmet-lorem-words
+ '("lorem" "ipsum" "dolor" "sit" "amet," "consectetur" "adipiscing" "elit" "ut" "aliquam," "purus" "sit" "amet" "luctus" "venenatis,"
+ "lectus" "magna" "fringilla" "urna," "porttitor" "rhoncus" "dolor" "purus" "non" "enim" "praesent" "elementum" "facilisis" "leo,"
+ "vel" "fringilla" "est" "ullamcorper" "eget" "nulla" "facilisi" "etiam" "dignissim" "diam" "quis" "enim" "lobortis" "scelerisque"
+ "fermentum" "dui" "faucibus" "in" "ornare" "quam" "viverra" "orci" "sagittis" "eu" "volutpat" "odio" "facilisis" "mauris" "sit" "amet"
+ "massa" "vitae" "tortor" "condimentum" "lacinia" "quis" "vel" "eros" "donec" "ac" "odio" "tempor" "orci" "dapibus" "ultrices" "in"
+ "iaculis" "nunc" "sed" "augue" "lacus," "viverra" "vitae" "congue" "eu," "consequat" "ac" "felis" "donec" "et" "odio" "pellentesque"
+ "diam" "volutpat" "commodo" "sed" "egestas" "egestas" "fringilla" "phasellus" "faucibus" "scelerisque" "eleifend" "donec" "pretium"
+ "vulputate" "sapien" "nec" "sagittis" "aliquam" "malesuada" "bibendum" "arcu" "vitae" "elementum" "curabitur" "vitae" "nunc" "sed"
+ "velit" "dignissim" "sodales" "ut" "eu" "sem" "integer" "vitae" "justo" "eget" "magna" "fermentum" "iaculis" "eu" "non" "diam"
+ "phasellus" "vestibulum" "lorem" "sed" "risus" "ultricies" "tristique" "nulla" "aliquet" "enim" "tortor," "at" "auctor" "urna" "nunc"
+ "id" "cursus" "metus" "aliquam" "eleifend" "mi" "in" "nulla" "posuere" "sollicitudin" "aliquam" "ultrices" "sagittis" "orci," "a"
+ "scelerisque" "purus" "semper" "eget" "duis" "at" "tellus" "at" "urna" "condimentum" "mattis" "pellentesque" "id" "nibh" "tortor,"
+ "id" "aliquet" "lectus" "proin" "nibh" "nisl," "condimentum" "id" "venenatis" "a," "condimentum" "vitae" "sapien" "pellentesque"
+ "habitant" "morbi" "tristique" "senectus" "et" "netus" "et" "malesuada" "fames" "ac" "turpis" "egestas" "sed" "tempus," "urna" "et"
+ "pharetra" "pharetra," "massa" "massa" "ultricies" "mi," "quis" "hendrerit" "dolor" "magna" "eget" "est" "lorem" "ipsum" "dolor" "sit"
+ "amet," "consectetur" "adipiscing" "elit" "pellentesque" "habitant" "morbi" "tristique" "senectus" "et" "netus" "et" "malesuada" "fames"
+ "ac" "turpis" "egestas" "integer" "eget" "aliquet" "nibh" "praesent" "tristique" "magna" "sit" "amet" "purus" "gravida" "quis" "blandit"
+ "turpis" "cursus" "in" "hac" "habitasse" "platea" "dictumst" "quisque" "sagittis," "purus" "sit" "amet" "volutpat" "consequat," "mauris"
+ "nunc" "congue" "nisi," "vitae" "suscipit" "tellus" "mauris" "a" "diam" "maecenas" "sed" "enim" "ut" "sem" "viverra" "aliquet" "eget"
+ "sit" "amet" "tellus" "cras" "adipiscing" "enim" "eu" "turpis" "egestas" "pretium" "aenean" "pharetra," "magna" "ac" "placerat"
+ "vestibulum," "lectus" "mauris" "ultrices" "eros," "in" "cursus" "turpis" "massa" "tincidunt" "dui" "ut" "ornare" "lectus" "sit" "amet"
+ "est" "placerat" "in" "egestas" "erat" "imperdiet" "sed" "euismod" "nisi" "porta" "lorem" "mollis" "aliquam" "ut" "porttitor" "leo" "a"
+ "diam" "sollicitudin" "tempor" "id" "eu" "nisl" "nunc" "mi" "ipsum," "faucibus" "vitae" "aliquet" "nec," "ullamcorper" "sit" "amet"
+ "risus" "nullam" "eget" "felis" "eget" "nunc" "lobortis" "mattis" "aliquam" "faucibus" "purus" "in" "massa" "tempor" "nec" "feugiat"
+ "nisl" "pretium" "fusce" "id" "velit" "ut" "tortor" "pretium" "viverra" "suspendisse" "potenti" "nullam" "ac" "tortor" "vitae" "purus"
+ "faucibus" "ornare" "suspendisse" "sed" "nisi" "lacus," "sed" "viverra" "tellus" "in" "hac" "habitasse" "platea" "dictumst" "vestibulum"
+ "rhoncus" "est" "pellentesque" "elit" "ullamcorper" "dignissim" "cras" "tincidunt" "lobortis" "feugiat" "vivamus" "at" "augue" "eget"
+ "arcu" "dictum" "varius" "duis" "at" "consectetur" "lorem" "donec" "massa" "sapien," "faucibus" "et" "molestie" "ac," "feugiat" "sed"
+ "lectus" "vestibulum" "mattis" "ullamcorper" "velit" "sed" "ullamcorper" "morbi" "tincidunt" "ornare" "massa," "eget" "egestas" "purus"
+ "viverra" "accumsan" "in" "nisl" "nisi," "scelerisque" "eu" "ultrices" "vitae," "auctor" "eu" "augue" "ut" "lectus" "arcu," "bibendum"
+ "at" "varius" "vel," "pharetra" "vel" "turpis" "nunc" "eget" "lorem" "dolor," "sed" "viverra" "ipsum" "nunc" "aliquet" "bibendum" "enim,"
+ "facilisis" "gravida" "neque" "convallis" "a" "cras" "semper" "auctor" "neque," "vitae" "tempus" "quam" "pellentesque" "nec" "nam"
+ "aliquam" "sem" "et" "tortor" "consequat" "id" "porta" "nibh" "venenatis" "cras" "sed" "felis" "eget" "velit" "aliquet" "sagittis"
+ "id" "consectetur" "purus" "ut" "faucibus" "pulvinar" "elementum" "integer" "enim" "neque," "volutpat" "ac" "tincidunt" "vitae,"
+ "semper" "quis" "lectus" "nulla" "at" "volutpat" "diam" "ut" "venenatis" "tellus" "in" "metus" "vulputate" "eu" "scelerisque" "felis"
+ "imperdiet" "proin" "fermentum" "leo" "vel" "orci" "porta" "non" "pulvinar" "neque" "laoreet" "suspendisse" "interdum" "consectetur"
+ "libero," "id" "faucibus" "nisl" "tincidunt" "eget" "nullam" "non" "nisi" "est," "sit" "amet" "facilisis" "magna" "etiam" "tempor,"
+ "orci" "eu" "lobortis" "elementum," "nibh" "tellus" "molestie" "nunc," "non" "blandit" "massa" "enim" "nec" "dui" "nunc" "mattis"
+ "enim" "ut" "tellus" "elementum" "sagittis" "vitae" "et" "leo" "duis" "ut" "diam" "quam" "nulla" "porttitor" "massa" "id" "neque"
+ "aliquam" "vestibulum" "morbi" "blandit" "cursus" "risus," "at" "ultrices" "mi" "tempus" "imperdiet" "nulla" "malesuada" "pellentesque"
+ "elit" "eget" "gravida" "cum" "sociis" "natoque" "penatibus" "et" "magnis" "dis" "parturient" "montes," "nascetur" "ridiculus" "mus"
+ "mauris" "vitae" "ultricies" "leo" "integer" "malesuada" "nunc" "vel" "risus" "commodo" "viverra" "maecenas" "accumsan," "lacus" "vel"
+ "facilisis" "volutpat," "est" "velit" "egestas" "dui," "id" "ornare" "arcu" "odio" "ut" "sem" "nulla" "pharetra" "diam" "sit" "amet"
+ "nisl" "suscipit" "adipiscing" "bibendum" "est" "ultricies" "integer" "quis" "auctor" "elit" "sed" "vulputate" "mi" "sit" "amet" "mauris"
+ "commodo" "quis" "imperdiet" "massa" "tincidunt" "nunc" "pulvinar" "sapien" "et" "ligula" "ullamcorper" "malesuada" "proin" "libero"
+ "nunc," "consequat" "interdum" "varius" "sit" "amet," "mattis" "vulputate" "enim" "nulla" "aliquet" "porttitor" "lacus," "luctus"
+ "accumsan" "tortor" "posuere" "ac" "ut" "consequat" "semper" "viverra" "nam" "libero" "justo," "laoreet" "sit" "amet" "cursus" "sit"
+ "amet," "dictum" "sit" "amet" "justo" "donec" "enim" "diam," "vulputate" "ut" "pharetra" "sit" "amet," "aliquam" "id" "diam" "maecenas"
+ "ultricies" "mi" "eget" "mauris" "pharetra" "et" "ultrices" "neque" "ornare" "aenean" "euismod" "elementum" "nisi," "quis" "eleifend"
+ "quam" "adipiscing" "vitae" "proin" "sagittis," "nisl" "rhoncus" "mattis" "rhoncus," "urna" "neque" "viverra" "justo," "nec" "ultrices"
+ "dui" "sapien" "eget" "mi" "proin" "sed" "libero" "enim," "sed" "faucibus" "turpis" "in" "eu" "mi" "bibendum" "neque" "egestas" "congue"
+ "quisque" "egestas" "diam" "in" "arcu" "cursus" "euismod" "quis" "viverra" "nibh" "cras" "pulvinar" "mattis" "nunc," "sed" "blandit"
+ "libero" "volutpat" "sed" "cras" "ornare" "arcu" "dui" "vivamus" "arcu" "felis," "bibendum" "ut" "tristique" "et," "egestas" "quis"
+ "ipsum" "suspendisse" "ultrices" "gravida" "dictum" "fusce" "ut" "placerat" "orci" "nulla" "pellentesque" "dignissim" "enim," "sit"
+ "amet" "venenatis" "urna" "cursus" "eget" "nunc" "scelerisque" "viverra" "mauris," "in" "aliquam" "sem" "fringilla" "ut" "morbi"
+ "tincidunt" "augue" "interdum" "velit" "euismod" "in" "pellentesque" "massa" "placerat" "duis" "ultricies" "lacus" "sed" "turpis"
+ "tincidunt" "id" "aliquet" "risus" "feugiat" "in" "ante" "metus," "dictum" "at" "tempor" "commodo," "ullamcorper" "a" "lacus" "vestibulum"
+ "sed" "arcu" "non" "odio" "euismod" "lacinia" "at" "quis" "risus" "sed" "vulputate" "odio" "ut" "enim" "blandit" "volutpat" "maecenas"
+ "volutpat" "blandit" "aliquam" "etiam" "erat" "velit," "scelerisque" "in" "dictum" "non," "consectetur" "a" "erat" "nam" "at" "lectus"
+ "urna" "duis" "convallis" "convallis" "tellus," "id" "interdum" "velit" "laoreet" "id" "donec" "ultrices" "tincidunt" "arcu," "non"
+ "sodales" "neque" "sodales" "ut" "etiam" "sit" "amet" "nisl" "purus," "in" "mollis" "nunc" "sed" "id" "semper" "risus" "in" "hendrerit"
+ "gravida" "rutrum" "quisque" "non" "tellus" "orci," "ac" "auctor" "augue" "mauris" "augue" "neque," "gravida" "in" "fermentum" "et,"
+ "sollicitudin" "ac" "orci" "phasellus" "egestas" "tellus" "rutrum" "tellus" "pellentesque" "eu" "tincidunt" "tortor" "aliquam" "nulla"
+ "facilisi" "cras" "fermentum," "odio" "eu" "feugiat" "pretium," "nibh" "ipsum" "consequat" "nisl," "vel" "pretium" "lectus" "quam" "id"
+ "leo" "in" "vitae" "turpis" "massa" "sed" "elementum" "tempus" "egestas" "sed" "sed" "risus" "pretium" "quam" "vulputate" "dignissim"
+ "suspendisse" "in" "est" "ante" "in" "nibh" "mauris," "cursus" "mattis" "molestie" "a," "iaculis" "at" "erat" "pellentesque" "adipiscing"
+ "commodo" "elit," "at" "imperdiet" "dui" "accumsan" "sit" "amet" "nulla" "facilisi" "morbi" "tempus" "iaculis" "urna," "id" "volutpat"
+ "lacus" "laoreet" "non" "curabitur" "gravida" "arcu" "ac" "tortor" "dignissim" "convallis" "aenean" "et" "tortor" "at" "risus" "viverra"
+ "adipiscing" "at" "in" "tellus" "integer" "feugiat" "scelerisque" "varius" "morbi" "enim" "nunc," "faucibus" "a" "pellentesque" "sit"
+ "amet," "porttitor" "eget" "dolor" "morbi" "non" "arcu" "risus," "quis" "varius" "quam" "quisque" "id" "diam" "vel" "quam" "elementum"
+ "pulvinar" "etiam" "non" "quam" "lacus" "suspendisse" "faucibus" "interdum" "posuere" "lorem" "ipsum" "dolor" "sit" "amet," "consectetur"
+ "adipiscing" "elit" "duis" "tristique" "sollicitudin" "nibh" "sit" "amet" "commodo" "nulla" "facilisi" "nullam" "vehicula" "ipsum" "a"
+ "arcu" "cursus" "vitae" "congue" "mauris" "rhoncus" "aenean" "vel" "elit" "scelerisque" "mauris" "pellentesque" "pulvinar" "pellentesque"
+ "habitant" "morbi" "tristique" "senectus" "et" "netus" "et" "malesuada" "fames" "ac" "turpis" "egestas" "maecenas" "pharetra" "convallis"
+ "posuere" "morbi" "leo" "urna," "molestie" "at" "elementum" "eu," "facilisis" "sed" "odio" "morbi" "quis" "commodo" "odio" "aenean" "sed"
+ "adipiscing" "diam" "donec" "adipiscing" "tristique" "risus" "nec" "feugiat" "in" "fermentum" "posuere" "urna" "nec" "tincidunt" "praesent"
+ "semper" "feugiat" "nibh" "sed" "pulvinar" "proin" "gravida" "hendrerit" "lectus" "a" "molestie"))
+
+(defun emmet-random-range (min max)
+ (+ min (random (+ (- max min) 1))))
+
+(defun emmet-lorem-choice-words (count &optional s)
+ (let* ((l (length emmet-lorem-words))
+ (s (if s s (random l)))
+ (f (+ s count))
+ (e (if (< l f) l f)))
+ (append
+ (cl-subseq emmet-lorem-words s e)
+ (if (= e l) (emmet-lorem-choice-words (- f l) 0)))))
+
+(defvar emmet-lorem-min-sentence 5)
+
+(defvar emmet-lorem-max-sentence 30)
+
+(defun emmet-upcase-first (s)
+ (concat (upcase (cl-subseq s 0 1)) (cl-subseq s 1)))
+
+(defun emmet-lorem-generate (count)
+ (if (<= count 0) ""
+ (let ((sl (if (< count emmet-lorem-max-sentence) count
+ (emmet-random-range
+ emmet-lorem-min-sentence
+ (min (- count emmet-lorem-min-sentence)
+ emmet-lorem-max-sentence))))
+ (last (let ((r (random 4)))
+ (if (< 1 r) "." (if (< 0 r) "?" "!")))))
+ (let ((words (let ((w (emmet-lorem-choice-words sl)))
+ (let ((l (car (last w))))
+ (if (string-equal (substring l -1) ",")
+ (append (cl-subseq w 0 -1) (list (substring l 0 -1)))
+ w)))))
+ (concat (emmet-upcase-first (emmet-join-string words " ")) last
+ (let ((next (emmet-lorem-generate (- count sl))))
+ (if (string-equal next "") ""
+ (concat " " next))))))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; CSS abbrev:
+
+(emmet-defparameter
+ emmet-css-unit-aliases
+ (gethash "unitAliases" (gethash "css" emmet-preferences)))
+(defun emmet-css-arg-number (input)
+ (emmet-parse
+ " *\\(\\(?:-\\|\\)[0-9.]+\\)\\(-\\|[A-Za-z]*\\)" 3 "css number arguments"
+ (cons (list (elt it 1)
+ (let ((unit (elt it 2)))
+ (if (= (length unit) 0)
+ (if (cl-find ?. (elt it 1)) "em" "px")
+ (gethash unit emmet-css-unit-aliases unit))))
+ input)))
+
+(emmet-defparameter
+ emmet-css-color-shorten-if-possible
+ (gethash "shortenIfPossible" (gethash "color" (gethash "css" emmet-preferences))))
+(emmet-defparameter
+ emmet-css-color-case
+ (gethash "case" (gethash "color" (gethash "css" emmet-preferences))))
+(emmet-defparameter
+ emmet-css-color-trailing-aliases
+ (gethash "trailingAliases" (gethash "color" (gethash "css" emmet-preferences))))
+(defun emmet-css-arg-color (input)
+ (emmet-parse
+ (concat " *#\\([0-9a-fA-F]\\{1,6\\}\\)\\(rgb\\|\\)\\(["
+ (emmet-join-string
+ (emmet-get-keys-of-hash emmet-css-color-trailing-aliases) "")
+ "]\\|\\)")
+ 4 "css color argument"
+ (let ((color
+ (let* ((n (elt it 1))
+ (l (length n)))
+ (substring
+ (cond ((= l 1) (concat (make-list 6 (string-to-char n))))
+ ((= l 2) (concat n n n))
+ ((= l 3) (concat
+ (cl-loop for c in (string-to-list n)
+ append (list c c))))
+ (t (concat n n)))
+ 0 6))))
+ (cons
+ (let ((rgb-mode (string= (elt it 2) "rgb")))
+ (if rgb-mode
+ (format "rgb(%d,%d,%d)"
+ (string-to-number (substring color 0 2) 16)
+ (string-to-number (substring color 2 4) 16)
+ (string-to-number (substring color 4 6) 16))
+ (concat
+ "#"
+ (let ((filter (cond ((string= emmet-css-color-case "auto") #'identity)
+ ((string= emmet-css-color-case "up") #'upcase)
+ (t #'downcase))))
+ (funcall
+ filter
+ (if (and emmet-css-color-shorten-if-possible
+ (eql (aref color 0) (aref color 1))
+ (eql (aref color 2) (aref color 3))
+ (eql (aref color 4) (aref color 5)))
+ (concat (mapcar #'(lambda (i) (aref color i)) '(0 2 4)))
+ color))))))
+ (if (< 0 (length (elt it 3)))
+ (cons (gethash (elt it 3) emmet-css-color-trailing-aliases) input)
+ input)))))
+
+(defun emmet-css-arg-something (input)
+ (emmet-parse
+ " *\\([^ ]+\\)" 2 "css argument"
+ (cons (elt it 1) input)))
+
+(defun emmet-css-parse-arg (input)
+ (emmet-run emmet-css-arg-number it
+ (emmet-run emmet-css-arg-color it
+ (emmet-run emmet-css-arg-something it
+ (if (equal input "")
+ it
+ (cons input ""))))))
+
+(defun emmet-css-important-p (input)
+ (let ((len (length input)))
+ (and (< 0 len)
+ (char-equal (aref input (1- len)) ?!))))
+
+(defun emmet-css-parse-args (args)
+ (when args
+ (let ((rt nil))
+ (cl-loop
+ (emmet-pif
+ (emmet-css-parse-arg args)
+ (cl-loop for i on it do (push (car i) rt)
+ while (consp (cdr i))
+ finally (setq args (cdr i)))
+ (cl-return (nreverse rt)))))))
+
+(defun emmet-css-split-args (exp)
+ (emmet-aif
+ (string-match "\\(?:[ #0-9$]\\|-[0-9]\\)" exp)
+ (list (substring exp 0 it) (substring exp it))
+ (list exp nil)))
+
+(defun emmet-css-split-vendor-prefixes (input)
+ (emmet-parse
+ "\\(-[wmso]+-\\|-\\|\\)\\(.*\\)" 3 "css vendor prefixes"
+ (list (elt it 2)
+ (let ((vp (elt it 1)))
+ (if (not (string= vp ""))
+ (if (string= vp "-") 'auto
+ (string-to-list (cl-subseq vp 1 -1))))))))
+
+(defun emmet-css-subexpr (exp)
+ (let* ((importantp (emmet-css-important-p exp)))
+ (cl-destructuring-bind (exp vp)
+ (emmet-css-split-vendor-prefixes exp)
+ (cl-destructuring-bind (key args)
+ (emmet-css-split-args (if importantp (cl-subseq exp 0 -1) exp))
+ `(,key ,vp
+ ,importantp
+ ,@(emmet-css-parse-args args))))))
+
+(defun emmet-css-toknize (str)
+ (let* ((i (split-string str "+"))
+ (rt nil))
+ (cl-loop
+ (let ((f (first i))
+ (s (second i)))
+ (if f
+ (if (and s (or (string= s "")
+ (string-match "^\\(?:[ #0-9$]\\|-[0-9]\\)" s)))
+ (progn
+ (setf rt (cons (concat f "+" s) rt))
+ (setf i (cddr i)))
+ (progn
+ (setf rt (cons f rt))
+ (setf i (cdr i))))
+ (cl-return (nreverse rt)))))))
+
+(defun emmet-css-expr (input)
+ (mapcar #'emmet-css-subexpr
+ (emmet-css-toknize input)))
+
+(emmet-defparameter
+ emmet-css-snippets
+ (gethash "snippets" (gethash "css" emmet-snippets)))
+
+(emmet-defparameter
+ emmet-sass-snippets
+ (gethash "snippets" (gethash "sass" emmet-snippets)))
+
+(emmet-defparameter
+ emmet-css-unitless-properties
+ (gethash "unitlessProperties" (gethash "css" emmet-preferences)))
+
+(emmet-defparameter
+ emmet-css-unitless-properties-regex
+ (concat "^\\(:?" (emmet-join-string
+ emmet-css-unitless-properties "\\|")
+ "\\):.*$"))
+
+(defun emmet-css-instantiate-lambda (str)
+ (cl-flet ((insert-space-between-name-and-body
+ (str)
+ (if (string-match "^\\([a-z-]+:\\)\\(.+\\)$" str)
+ (emmet-join-string
+ (mapcar (lambda (ref) (match-string ref str)) '(1 2)) " ")
+ str))
+ (split-string-to-body
+ (str args-sym)
+ (let ((rt '(concat)) (idx-max 0))
+ (cl-loop for i from 0 to 255 do
+ (emmet-aif
+ (string-match "\\(?:|\\|${\\(?:\\([0-9]\\)\\|\\)\\(?::\\(.+?\\)\\|\\)}\\)" str)
+ (cl-destructuring-bind (mat idx def)
+ (mapcar (lambda (ref) (match-string ref str)) '(0 1 2))
+ (setf rt
+ `((or
+ (nth ,(let ((cur-idx (if idx (1- (string-to-number idx)) i)))
+ (setf idx-max (max cur-idx idx-max)))
+ ,args-sym)
+ ,(or def ""))
+ ,(substring str 0 it) ;; ordered to reverse
+ ,@rt))
+ (setf str (substring str (+ it (length mat)))))
+ ;; don't use nreverse. cause bug in emacs-lisp.
+ (cl-return (cons idx-max (reverse (cons str rt)))))))))
+ (let ((args (gensym))
+ (str (insert-space-between-name-and-body str)))
+ (cl-destructuring-bind (idx-max . body) (split-string-to-body str args)
+ (eval
+ `(lambda (&rest ,args)
+ (progn
+ (when (nthcdr ,idx-max ,args)
+ (setf (nthcdr ,idx-max ,args)
+ (list (emmet-join-string
+ (nthcdr ,idx-max ,args) " "))))
+ ,body)))))))
+
+(emmet-defparameter
+ emmet-vendor-prefixes-properties
+ (gethash "vendorPrefixesProperties" (gethash "css" emmet-preferences)))
+(emmet-defparameter
+ emmet-vendor-prefixes-default
+ (list "webkit" "moz" "ms" "o"))
+(defun emmet-css-transform-vendor-prefixes (line vp)
+ (let ((key (cl-subseq line 0 (or (cl-position ?: line) (length line)))))
+ (let ((vps (if (eql vp 'auto)
+ (gethash key
+ emmet-vendor-prefixes-properties
+ emmet-vendor-prefixes-default)
+ (mapcar (lambda (v)
+ (cond ((= v ?w) "webkit")
+ ((= v ?m) "moz")
+ ((= v ?s) "ms")
+ ((= v ?o) "o")))
+ vp))))
+ (emmet-join-string
+ (append (mapcar (lambda (v) (concat "-" v "-" line)) vps)
+ (list line))
+ "\n"))))
+
+(defun emmet-css-transform-exprs (exprs)
+ (emmet-join-string
+ (mapcar
+ #'(lambda (expr)
+ (let*
+ ((hash-map (if emmet-use-sass-syntax emmet-sass-snippets emmet-css-snippets))
+ (basement
+ (emmet-aif
+ (or (gethash (car expr) hash-map) (gethash (car expr) emmet-css-snippets))
+ (let ((set it) (fn nil) (unitlessp nil))
+ (if (stringp set)
+ (progn
+ ;; new pattern
+ ;; creating print function
+ (setf fn (emmet-css-instantiate-lambda set))
+ ;; get unitless or no
+ (setf unitlessp
+ (not (null (string-match
+ emmet-css-unitless-properties-regex set))))
+ ;; caching
+ (puthash (car expr) (cons fn unitlessp) hash-map))
+ (progn
+ ;; cache hit.
+ (setf fn (car set))
+ (setf unitlessp (cdr set))))
+ (apply fn
+ (mapcar
+ #'(lambda (arg)
+ (if (listp arg)
+ (if unitlessp (car arg)
+ (apply #'concat arg))
+ arg))
+ (cdddr expr))))
+ (concat (car expr) ": "
+ (emmet-join-string
+ (mapcar #'(lambda (arg)
+ (if (listp arg) (apply #'concat arg) arg))
+ (cdddr expr)) " ")
+ ";"))))
+ (let ((line
+ (if (caddr expr)
+ (concat (cl-subseq basement 0 -1) " !important;")
+ basement)))
+ ;; remove trailing semicolon while editing Sass files
+ (if (and emmet-use-sass-syntax (equal ";" (cl-subseq line -1)))
+ (setq line (cl-subseq line 0 -1)))
+ (emmet-aif
+ (cadr expr)
+ (emmet-css-transform-vendor-prefixes line it)
+ line))))
+ exprs)
+ "\n"))
+
+(defun emmet-css-transform (input)
+ (emmet-css-transform-exprs (emmet-css-expr input)))
+
+;;; emmet-mode.el ends here
diff --git a/elpa/emmet-mode-20210820.1124/emmet-mode.elc b/elpa/emmet-mode-20210820.1124/emmet-mode.elc
new file mode 100644
index 0000000..6bfb08d
--- /dev/null
+++ b/elpa/emmet-mode-20210820.1124/emmet-mode.elc
Binary files differ
diff --git a/elpa/epl-20180205.2049/epl-autoloads.el b/elpa/epl-20180205.2049/epl-autoloads.el
new file mode 100644
index 0000000..fdd3313
--- /dev/null
+++ b/elpa/epl-20180205.2049/epl-autoloads.el
@@ -0,0 +1,22 @@
+;;; epl-autoloads.el --- automatically extracted autoloads -*- lexical-binding: t -*-
+;;
+;;; Code:
+
+(add-to-list 'load-path (directory-file-name
+ (or (file-name-directory #$) (car load-path))))
+
+
+;;;### (autoloads nil "epl" "epl.el" (0 0 0 0))
+;;; Generated autoloads from epl.el
+
+(register-definition-prefixes "epl" '("epl-"))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; coding: utf-8
+;; End:
+;;; epl-autoloads.el ends here
diff --git a/elpa/epl-20180205.2049/epl-pkg.el b/elpa/epl-20180205.2049/epl-pkg.el
new file mode 100644
index 0000000..7ef07f3
--- /dev/null
+++ b/elpa/epl-20180205.2049/epl-pkg.el
@@ -0,0 +1,2 @@
+;;; Generated package description from epl.el -*- no-byte-compile: t -*-
+(define-package "epl" "20180205.2049" "Emacs Package Library" '((cl-lib "0.3")) :commit "78ab7a85c08222cd15582a298a364774e3282ce6" :authors '(("Sebastian Wiesner" . "swiesner@lunaryorn.com")) :maintainer '("Johan Andersson" . "johan.rejeep@gmail.com") :keywords '("convenience") :url "http://github.com/cask/epl")
diff --git a/elpa/epl-20180205.2049/epl.el b/elpa/epl-20180205.2049/epl.el
new file mode 100644
index 0000000..a660ba8
--- /dev/null
+++ b/elpa/epl-20180205.2049/epl.el
@@ -0,0 +1,712 @@
+;;; epl.el --- Emacs Package Library -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2013-2015 Sebastian Wiesner
+;; Copyright (C) 1985-1986, 1992, 1994-1995, 1999-2015 Free Software
+
+;; Author: Sebastian Wiesner <swiesner@lunaryorn.com>
+;; Maintainer: Johan Andersson <johan.rejeep@gmail.com>
+;; Sebastian Wiesner <swiesner@lunaryorn.com>
+;; Version: 0.10-cvs
+;; Package-Version: 20180205.2049
+;; Package-Commit: 78ab7a85c08222cd15582a298a364774e3282ce6
+;; Package-Requires: ((cl-lib "0.3"))
+;; Keywords: convenience
+;; URL: http://github.com/cask/epl
+
+;; 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 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:
+
+;; A package management library for Emacs, based on package.el.
+
+;; The purpose of this library is to wrap all the quirks and hassle of
+;; package.el into a sane API.
+
+;; The following functions comprise the public interface of this library:
+
+;;; Package directory selection
+
+;; `epl-package-dir' gets the directory of packages.
+
+;; `epl-default-package-dir' gets the default package directory.
+
+;; `epl-change-package-dir' changes the directory of packages.
+
+;;; Package system management
+
+;; `epl-initialize' initializes the package system and activates all
+;; packages.
+
+;; `epl-reset' resets the package system.
+
+;; `epl-refresh' refreshes all package archives.
+
+;; `epl-add-archive' adds a new package archive.
+
+;;; Package objects
+
+;; Struct `epl-requirement' describes a requirement of a package with `name' and
+;; `version' slots.
+
+;; `epl-requirement-version-string' gets a requirement version as string.
+
+;; Struct `epl-package' describes an installed or installable package with a
+;; `name' and some internal `description'.
+
+;; `epl-package-version' gets the version of a package.
+
+;; `epl-package-version-string' gets the version of a package as string.
+
+;; `epl-package-summary' gets the summary of a package.
+
+;; `epl-package-requirements' gets the requirements of a package.
+
+;; `epl-package-directory' gets the installation directory of a package.
+
+;; `epl-package-from-buffer' creates a package object for the package contained
+;; in the current buffer.
+
+;; `epl-package-from-file' creates a package object for a package file, either
+;; plain lisp or tarball.
+
+;; `epl-package-from-descriptor-file' creates a package object for a package
+;; description (i.e. *-pkg.el) file.
+
+;;; Package database access
+
+;; `epl-package-installed-p' determines whether a package is installed, either
+;; built-in or explicitly installed.
+
+;; `epl-package-outdated-p' determines whether a package is outdated, that is,
+;; whether a package with a higher version number is available.
+
+;; `epl-built-in-packages', `epl-installed-packages', `epl-outdated-packages'
+;; and `epl-available-packages' get all packages built-in, installed, outdated,
+;; or available for installation respectively.
+
+;; `epl-find-built-in-package', `epl-find-installed-packages' and
+;; `epl-find-available-packages' find built-in, installed and available packages
+;; by name.
+
+;; `epl-find-upgrades' finds all upgradable packages.
+
+;; `epl-built-in-p' return true if package is built-in to Emacs.
+
+;;; Package operations
+
+;; `epl-install-file' installs a package file.
+
+;; `epl-package-install' installs a package.
+
+;; `epl-package-delete' deletes a package.
+
+;; `epl-upgrade' upgrades packages.
+
+;;; Code:
+
+(require 'cl-lib)
+(require 'package)
+
+
+(unless (fboundp #'define-error)
+ ;; `define-error' for 24.3 and earlier, copied from subr.el
+ (defun define-error (name message &optional parent)
+ "Define NAME as a new error signal.
+MESSAGE is a string that will be output to the echo area if such an error
+is signaled without being caught by a `condition-case'.
+PARENT is either a signal or a list of signals from which it inherits.
+Defaults to `error'."
+ (unless parent (setq parent 'error))
+ (let ((conditions
+ (if (consp parent)
+ (apply #'append
+ (mapcar (lambda (parent)
+ (cons parent
+ (or (get parent 'error-conditions)
+ (error "Unknown signal `%s'" parent))))
+ parent))
+ (cons parent (get parent 'error-conditions)))))
+ (put name 'error-conditions
+ (delete-dups (copy-sequence (cons name conditions))))
+ (when message (put name 'error-message message)))))
+
+(defsubst epl--package-desc-p (package)
+ "Whether PACKAGE is a `package-desc' object.
+
+Like `package-desc-p', but return nil, if `package-desc-p' is not
+defined as function."
+ (and (fboundp 'package-desc-p) (package-desc-p package)))
+
+
+;;; EPL errors
+(define-error 'epl-error "EPL error")
+
+(define-error 'epl-invalid-package "Invalid EPL package" 'epl-error)
+
+(define-error 'epl-invalid-package-file "Invalid EPL package file"
+ 'epl-invalid-package)
+
+
+;;; Package directory
+(defun epl-package-dir ()
+ "Get the directory of packages."
+ package-user-dir)
+
+(defun epl-default-package-dir ()
+ "Get the default directory of packages."
+ (eval (car (get 'package-user-dir 'standard-value))))
+
+(defun epl-change-package-dir (directory)
+ "Change the directory of packages to DIRECTORY."
+ (setq package-user-dir directory)
+ (epl-initialize))
+
+
+;;; Package system management
+(defvar epl--load-path-before-initialize nil
+ "Remember the load path for `epl-reset'.")
+
+(defun epl-initialize (&optional no-activate)
+ "Load Emacs Lisp packages and activate them.
+
+With NO-ACTIVATE non-nil, do not activate packages."
+ (setq epl--load-path-before-initialize load-path)
+ (package-initialize no-activate))
+
+(defalias 'epl-refresh 'package-refresh-contents)
+
+(defun epl-add-archive (name url)
+ "Add a package archive with NAME and URL."
+ (add-to-list 'package-archives (cons name url)))
+
+(defun epl-reset ()
+ "Reset the package system.
+
+Clear the list of installed and available packages, the list of
+package archives and reset the package directory."
+ (setq package-alist nil
+ package-archives nil
+ package-archive-contents nil
+ load-path epl--load-path-before-initialize)
+ (when (boundp 'package-obsolete-alist) ; Legacy package.el
+ (setq package-obsolete-alist nil))
+ (epl-change-package-dir (epl-default-package-dir)))
+
+
+;;; Package structures
+(cl-defstruct (epl-requirement
+ (:constructor epl-requirement-create))
+ "Structure describing a requirement.
+
+Slots:
+
+`name' The name of the required package, as symbol.
+
+`version' The version of the required package, as version list."
+ name
+ version)
+
+(defun epl-requirement-version-string (requirement)
+ "The version of a REQUIREMENT, as string."
+ (package-version-join (epl-requirement-version requirement)))
+
+(cl-defstruct (epl-package (:constructor epl-package-create))
+ "Structure representing a package.
+
+Slots:
+
+`name' The package name, as symbol.
+
+`description' The package description.
+
+The format package description varies between package.el
+variants. For `package-desc' variants, it is simply the
+corresponding `package-desc' object. For legacy variants, it is
+a vector `[VERSION REQS DOCSTRING]'.
+
+Do not access `description' directly, but instead use the
+`epl-package' accessors."
+ name
+ description)
+
+(defmacro epl-package-as-description (var &rest body)
+ "Cast VAR to a package description in BODY.
+
+VAR is a symbol, bound to an `epl-package' object. This macro
+casts this object to the `description' object, and binds the
+description to VAR in BODY."
+ (declare (indent 1))
+ (unless (symbolp var)
+ (signal 'wrong-type-argument (list #'symbolp var)))
+ `(if (epl-package-p ,var)
+ (let ((,var (epl-package-description ,var)))
+ ,@body)
+ (signal 'wrong-type-argument (list #'epl-package-p ,var))))
+
+(defsubst epl-package--package-desc-p (package)
+ "Whether the description of PACKAGE is a `package-desc'."
+ (epl--package-desc-p (epl-package-description package)))
+
+(defun epl-package-version (package)
+ "Get the version of PACKAGE, as version list."
+ (epl-package-as-description package
+ (cond
+ ((fboundp 'package-desc-version) (package-desc-version package))
+ ;; Legacy
+ ((fboundp 'package-desc-vers)
+ (let ((version (package-desc-vers package)))
+ (if (listp version) version (version-to-list version))))
+ (:else (error "Cannot get version from %S" package)))))
+
+(defun epl-package-version-string (package)
+ "Get the version from a PACKAGE, as string."
+ (package-version-join (epl-package-version package)))
+
+(defun epl-package-summary (package)
+ "Get the summary of PACKAGE, as string."
+ (epl-package-as-description package
+ (cond
+ ((fboundp 'package-desc-summary) (package-desc-summary package))
+ ((fboundp 'package-desc-doc) (package-desc-doc package)) ; Legacy
+ (:else (error "Cannot get summary from %S" package)))))
+
+(defsubst epl-requirement--from-req (req)
+ "Create a `epl-requirement' from a `package-desc' REQ."
+ (let ((version (cadr req)))
+ (epl-requirement-create :name (car req)
+ :version (if (listp version) version
+ (version-to-list version)))))
+
+(defun epl-package-requirements (package)
+ "Get the requirements of PACKAGE.
+
+The requirements are a list of `epl-requirement' objects."
+ (epl-package-as-description package
+ (mapcar #'epl-requirement--from-req (package-desc-reqs package))))
+
+(defun epl-package-directory (package)
+ "Get the directory PACKAGE is installed to.
+
+Return the absolute path of the installation directory of
+PACKAGE, or nil, if PACKAGE is not installed."
+ (cond
+ ((fboundp 'package-desc-dir)
+ (package-desc-dir (epl-package-description package)))
+ ((fboundp 'package--dir)
+ (package--dir (symbol-name (epl-package-name package))
+ (epl-package-version-string package)))
+ (:else (error "Cannot get package directory from %S" package))))
+
+(defun epl-package-->= (pkg1 pkg2)
+ "Determine whether PKG1 is before PKG2 by version."
+ (not (version-list-< (epl-package-version pkg1)
+ (epl-package-version pkg2))))
+
+(defun epl-package--from-package-desc (package-desc)
+ "Create an `epl-package' from a PACKAGE-DESC.
+
+PACKAGE-DESC is a `package-desc' object, from recent package.el
+variants."
+ (if (and (fboundp 'package-desc-name)
+ (epl--package-desc-p package-desc))
+ (epl-package-create :name (package-desc-name package-desc)
+ :description package-desc)
+ (signal 'wrong-type-argument (list 'epl--package-desc-p package-desc))))
+
+(defun epl-package--parse-info (info)
+ "Parse a package.el INFO."
+ (if (epl--package-desc-p info)
+ (epl-package--from-package-desc info)
+ ;; For legacy package.el, info is a vector [NAME REQUIRES DESCRIPTION
+ ;; VERSION COMMENTARY]. We need to re-shape this vector into the
+ ;; `package-alist' format [VERSION REQUIRES DESCRIPTION] to attach it to the
+ ;; new `epl-package'.
+ (let ((name (intern (aref info 0)))
+ (info (vector (aref info 3) (aref info 1) (aref info 2))))
+ (epl-package-create :name name :description info))))
+
+(defun epl-package-from-buffer (&optional buffer)
+ "Create an `epl-package' object from BUFFER.
+
+BUFFER defaults to the current buffer.
+
+Signal `epl-invalid-package' if the buffer does not contain a
+valid package file."
+ (let ((info (with-current-buffer (or buffer (current-buffer))
+ (condition-case err
+ (package-buffer-info)
+ (error (signal 'epl-invalid-package (cdr err)))))))
+ (epl-package--parse-info info)))
+
+(defun epl-package-from-lisp-file (file-name)
+ "Parse the package headers the file at FILE-NAME.
+
+Return an `epl-package' object with the header metadata."
+ (with-temp-buffer
+ (insert-file-contents file-name)
+ (condition-case err
+ (epl-package-from-buffer (current-buffer))
+ ;; Attach file names to invalid package errors
+ (epl-invalid-package
+ (signal 'epl-invalid-package-file (cons file-name (cdr err))))
+ ;; Forward other errors
+ (error (signal (car err) (cdr err))))))
+
+(defun epl-package-from-tar-file (file-name)
+ "Parse the package tarball at FILE-NAME.
+
+Return a `epl-package' object with the meta data of the tarball
+package in FILE-NAME."
+ (condition-case nil
+ ;; In legacy package.el, `package-tar-file-info' takes the name of the tar
+ ;; file to parse as argument. In modern package.el, it has no arguments
+ ;; and works on the current buffer. Hence, we just try to call the legacy
+ ;; version, and if that fails because of a mismatch between formal and
+ ;; actual arguments, we use the modern approach. To avoid spurious
+ ;; signature warnings by the byte compiler, we suppress warnings when
+ ;; calling the function.
+ (epl-package--parse-info (with-no-warnings
+ (package-tar-file-info file-name)))
+ (wrong-number-of-arguments
+ (with-temp-buffer
+ (insert-file-contents-literally file-name)
+ ;; Switch to `tar-mode' to enable extraction of the file. Modern
+ ;; `package-tar-file-info' relies on `tar-mode', and signals an error if
+ ;; called in a buffer with a different mode.
+ (tar-mode)
+ (epl-package--parse-info (with-no-warnings
+ (package-tar-file-info)))))))
+
+(defun epl-package-from-file (file-name)
+ "Parse the package at FILE-NAME.
+
+Return an `epl-package' object with the meta data of the package
+at FILE-NAME."
+ (if (string-match-p (rx ".tar" string-end) file-name)
+ (epl-package-from-tar-file file-name)
+ (epl-package-from-lisp-file file-name)))
+
+(defun epl-package--parse-descriptor-requirement (requirement)
+ "Parse a REQUIREMENT in a package descriptor."
+ ;; This function is only called on legacy package.el. On package-desc
+ ;; package.el, we just let package.el do the work.
+ (cl-destructuring-bind (name version-string) requirement
+ (list name (version-to-list version-string))))
+
+(defun epl-package-from-descriptor-file (descriptor-file)
+ "Load a `epl-package' from a package DESCRIPTOR-FILE.
+
+A package descriptor is a file defining a new package. Its name
+typically ends with -pkg.el."
+ (with-temp-buffer
+ (insert-file-contents descriptor-file)
+ (goto-char (point-min))
+ (let ((sexp (read (current-buffer))))
+ (unless (eq (car sexp) 'define-package)
+ (error "%S is no valid package descriptor" descriptor-file))
+ (if (and (fboundp 'package-desc-from-define)
+ (fboundp 'package-desc-name))
+ ;; In Emacs snapshot, we can conveniently call a function to parse the
+ ;; descriptor
+ (let ((desc (apply #'package-desc-from-define (cdr sexp))))
+ (epl-package-create :name (package-desc-name desc)
+ :description desc))
+ ;; In legacy package.el, we must manually deconstruct the descriptor,
+ ;; because the load function has eval's the descriptor and has a lot of
+ ;; global side-effects.
+ (cl-destructuring-bind
+ (name version-string summary requirements) (cdr sexp)
+ (epl-package-create
+ :name (intern name)
+ :description
+ (vector (version-to-list version-string)
+ (mapcar #'epl-package--parse-descriptor-requirement
+ ;; Strip the leading `quote' from the package list
+ (cadr requirements))
+ summary)))))))
+
+
+;;; Package database access
+(defun epl-package-installed-p (package &optional min-version)
+ "Determine whether a PACKAGE, of MIN-VERSION or newer, is installed.
+
+PACKAGE is either a package name as symbol, or a package object.
+When a explicit MIN-VERSION is provided it overwrites the version of the PACKAGE object."
+ (let ((name (if (epl-package-p package)
+ (epl-package-name package)
+ package))
+ (min-version (or min-version (and (epl-package-p package)
+ (epl-package-version package)))))
+ (package-installed-p name min-version)))
+
+(defun epl--parse-built-in-entry (entry)
+ "Parse an ENTRY from the list of built-in packages.
+
+Return the corresponding `epl-package' object."
+ (if (fboundp 'package--from-builtin)
+ ;; In package-desc package.el, convert the built-in package to a
+ ;; `package-desc' and convert that to an `epl-package'
+ (epl-package--from-package-desc (package--from-builtin entry))
+ (epl-package-create :name (car entry) :description (cdr entry))))
+
+(defun epl-built-in-packages ()
+ "Get all built-in packages.
+
+Return a list of `epl-package' objects."
+ ;; This looks mighty strange, but it's the only way to force package.el to
+ ;; build the list of built-in packages. Without this, `package--builtins'
+ ;; might be empty.
+ (package-built-in-p 'foo)
+ (mapcar #'epl--parse-built-in-entry package--builtins))
+
+(defun epl-find-built-in-package (name)
+ "Find a built-in package with NAME.
+
+NAME is a package name, as symbol.
+
+Return the built-in package as `epl-package' object, or nil if
+there is no built-in package with NAME."
+ (when (package-built-in-p name)
+ ;; We must call `package-built-in-p' *before* inspecting
+ ;; `package--builtins', because otherwise `package--builtins' might be
+ ;; empty.
+ (epl--parse-built-in-entry (assq name package--builtins))))
+
+(defun epl-package-outdated-p (package)
+ "Determine whether a PACKAGE is outdated.
+
+A package is outdated, if there is an available package with a
+higher version.
+
+PACKAGE is either a package name as symbol, or a package object.
+In the former case, test the installed or built-in package with
+the highest version number, in the later case, test the package
+object itself.
+
+Return t, if the package is outdated, or nil otherwise."
+ (let* ((package (if (epl-package-p package)
+ package
+ (or (car (epl-find-installed-packages package))
+ (epl-find-built-in-package package))))
+ (available (car (epl-find-available-packages
+ (epl-package-name package)))))
+ (and package available (version-list-< (epl-package-version package)
+ (epl-package-version available)))))
+
+(defun epl--parse-package-list-entry (entry)
+ "Parse a list of packages from ENTRY.
+
+ENTRY is a single entry in a package list, e.g. `package-alist',
+`package-archive-contents', etc. Typically it is a cons cell,
+but the exact format varies between package.el versions. This
+function tries to parse all known variants.
+
+Return a list of `epl-package' objects parsed from ENTRY."
+ (let ((descriptions (cdr entry)))
+ (cond
+ ((listp descriptions)
+ (sort (mapcar #'epl-package--from-package-desc descriptions)
+ #'epl-package-->=))
+ ;; Legacy package.el has just a single package in an entry, which is a
+ ;; standard description vector
+ ((vectorp descriptions)
+ (list (epl-package-create :name (car entry)
+ :description descriptions)))
+ (:else (error "Cannot parse entry %S" entry)))))
+
+(defun epl-installed-packages ()
+ "Get all installed packages.
+
+Return a list of package objects."
+ (apply #'append (mapcar #'epl--parse-package-list-entry package-alist)))
+
+(defsubst epl--filter-outdated-packages (packages)
+ "Filter outdated packages from PACKAGES."
+ (let (res)
+ (dolist (package packages)
+ (when (epl-package-outdated-p package)
+ (push package res)))
+ (nreverse res)))
+
+(defun epl-outdated-packages ()
+ "Get all outdated packages, as in `epl-package-outdated-p'.
+
+Return a list of package objects."
+ (epl--filter-outdated-packages (epl-installed-packages)))
+
+(defsubst epl--find-package-in-list (name list)
+ "Find a package by NAME in a package LIST.
+
+Return a list of corresponding `epl-package' objects."
+ (let ((entry (assq name list)))
+ (when entry
+ (epl--parse-package-list-entry entry))))
+
+(defun epl-find-installed-package (name)
+ "Find the latest installed package by NAME.
+
+NAME is a package name, as symbol.
+
+Return the installed package with the highest version number as
+`epl-package' object, or nil, if no package with NAME is
+installed."
+ (car (epl-find-installed-packages name)))
+(make-obsolete 'epl-find-installed-package 'epl-find-installed-packages "0.7")
+
+(defun epl-find-installed-packages (name)
+ "Find all installed packages by NAME.
+
+NAME is a package name, as symbol.
+
+Return a list of all installed packages with NAME, sorted by
+version number in descending order. Return nil, if there are no
+packages with NAME."
+ (epl--find-package-in-list name package-alist))
+
+(defun epl-available-packages ()
+ "Get all packages available for installation.
+
+Return a list of package objects."
+ (apply #'append (mapcar #'epl--parse-package-list-entry
+ package-archive-contents)))
+
+(defun epl-find-available-packages (name)
+ "Find available packages for NAME.
+
+NAME is a package name, as symbol.
+
+Return a list of available packages for NAME, sorted by version
+number in descending order. Return nil, if there are no packages
+for NAME."
+ (epl--find-package-in-list name package-archive-contents))
+
+(cl-defstruct (epl-upgrade
+ (:constructor epl-upgrade-create))
+ "Structure describing an upgradable package.
+Slots:
+
+`installed' The installed package
+
+`available' The package available for installation."
+ installed
+ available)
+
+(defun epl-find-upgrades (&optional packages)
+ "Find all upgradable PACKAGES.
+
+PACKAGES is a list of package objects to upgrade, defaulting to
+all installed packages.
+
+Return a list of `epl-upgrade' objects describing all upgradable
+packages."
+ (let ((packages (or packages (epl-installed-packages)))
+ upgrades)
+ (dolist (pkg packages)
+ (let* ((version (epl-package-version pkg))
+ (name (epl-package-name pkg))
+ ;; Find the latest available package for NAME
+ (available-pkg (car (epl-find-available-packages name)))
+ (available-version (when available-pkg
+ (epl-package-version available-pkg))))
+ (when (and available-version (version-list-< version available-version))
+ (push (epl-upgrade-create :installed pkg
+ :available available-pkg)
+ upgrades))))
+ (nreverse upgrades)))
+
+(defalias 'epl-built-in-p 'package-built-in-p)
+
+
+;;; Package operations
+
+(defun epl-install-file (file)
+ "Install a package from FILE, like `package-install-file'."
+ (interactive (advice-eval-interactive-spec
+ (cadr (interactive-form #'package-install-file))))
+ (apply #'package-install-file (list file))
+ (let ((package (epl-package-from-file file)))
+ (unless (epl-package--package-desc-p package)
+ (epl--kill-autoload-buffer package))))
+
+(defun epl--kill-autoload-buffer (package)
+ "Kill the buffer associated with autoloads for PACKAGE."
+ (let* ((auto-name (format "%s-autoloads.el" (epl-package-name package)))
+ (generated-autoload-file (expand-file-name auto-name (epl-package-directory package)))
+ (buf (find-buffer-visiting generated-autoload-file)))
+ (when buf (kill-buffer buf))))
+
+(defun epl-package-install (package &optional force)
+ "Install a PACKAGE.
+
+PACKAGE is a `epl-package' object. If FORCE is given and
+non-nil, install PACKAGE, even if it is already installed."
+ (when (or force (not (epl-package-installed-p package)))
+ (if (epl-package--package-desc-p package)
+ (package-install (epl-package-description package))
+ ;; The legacy API installs by name. We have no control over versioning,
+ ;; etc.
+ (package-install (epl-package-name package))
+ (epl--kill-autoload-buffer package))))
+
+(defun epl-package-delete (package)
+ "Delete a PACKAGE.
+
+PACKAGE is a `epl-package' object to delete."
+ ;; package-delete allows for packages being trashed instead of fully deleted.
+ ;; Let's prevent his silly behavior
+ (let ((delete-by-moving-to-trash nil))
+ ;; The byte compiler will warn us that we are calling `package-delete' with
+ ;; the wrong number of arguments, since it can't infer that we guarantee to
+ ;; always call the correct version. Thus we suppress all warnings when
+ ;; calling `package-delete'. I wish there was a more granular way to
+ ;; disable just that specific warning, but it is what it is.
+ (if (epl-package--package-desc-p package)
+ (with-no-warnings
+ (package-delete (epl-package-description package)))
+ ;; The legacy API deletes by name (as string!) and version instead by
+ ;; descriptor. Hence `package-delete' takes two arguments. For some
+ ;; insane reason, the arguments are strings here!
+ (let ((name (symbol-name (epl-package-name package)))
+ (version (epl-package-version-string package)))
+ (with-no-warnings
+ (package-delete name version))
+ ;; Legacy package.el does not remove the deleted package
+ ;; from the `package-alist', so we do it manually here.
+ (let ((pkg (assq (epl-package-name package) package-alist)))
+ (when pkg
+ (setq package-alist (delq pkg package-alist))))))))
+
+(defun epl-upgrade (&optional packages preserve-obsolete)
+ "Upgrade PACKAGES.
+
+PACKAGES is a list of package objects to upgrade, defaulting to
+all installed packages.
+
+The old versions of the updated packages are deleted, unless
+PRESERVE-OBSOLETE is non-nil.
+
+Return a list of all performed upgrades, as a list of
+`epl-upgrade' objects."
+ (let ((upgrades (epl-find-upgrades packages)))
+ (dolist (upgrade upgrades)
+ (epl-package-install (epl-upgrade-available upgrade) 'force)
+ (unless preserve-obsolete
+ (epl-package-delete (epl-upgrade-installed upgrade))))
+ upgrades))
+
+(provide 'epl)
+
+;;; epl.el ends here
diff --git a/elpa/epl-20180205.2049/epl.elc b/elpa/epl-20180205.2049/epl.elc
new file mode 100644
index 0000000..9fd210c
--- /dev/null
+++ b/elpa/epl-20180205.2049/epl.elc
Binary files differ
diff --git a/elpa/evil-20220503.1314/dir b/elpa/evil-20220503.1314/dir
new file mode 100644
index 0000000..b3717a5
--- /dev/null
+++ b/elpa/evil-20220503.1314/dir
@@ -0,0 +1,18 @@
+This is the file .../info/dir, which contains the
+topmost node of the Info hierarchy, called (dir)Top.
+The first time you invoke Info you start off looking at this node.
+
+File: dir, Node: Top This is the top of the INFO tree
+
+ This (the Directory node) gives a menu of major topics.
+ Typing "q" exits, "H" lists all Info commands, "d" returns here,
+ "h" gives a primer for first-timers,
+ "mEmacs<Return>" visits the Emacs manual, etc.
+
+ In Emacs, you can click mouse button 2 on a menu item or cross reference
+ to select it.
+
+* Menu:
+
+Emacs
+* evil: (evil.info). Extensible vi layer for Emacs
diff --git a/elpa/evil-20220503.1314/evil-autoloads.el b/elpa/evil-20220503.1314/evil-autoloads.el
new file mode 100644
index 0000000..fb58c6a
--- /dev/null
+++ b/elpa/evil-20220503.1314/evil-autoloads.el
@@ -0,0 +1,128 @@
+;;; evil-autoloads.el --- automatically extracted autoloads -*- lexical-binding: t -*-
+;;
+;;; Code:
+
+(add-to-list 'load-path (directory-file-name
+ (or (file-name-directory #$) (car load-path))))
+
+
+;;;### (autoloads nil "evil-command-window" "evil-command-window.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from evil-command-window.el
+
+(register-definition-prefixes "evil-command-window" '("evil-"))
+
+;;;***
+
+;;;### (autoloads nil "evil-commands" "evil-commands.el" (0 0 0 0))
+;;; Generated autoloads from evil-commands.el
+
+(register-definition-prefixes "evil-commands" '("evil-"))
+
+;;;***
+
+;;;### (autoloads nil "evil-common" "evil-common.el" (0 0 0 0))
+;;; Generated autoloads from evil-common.el
+
+(register-definition-prefixes "evil-common" '("bounds-of-evil-" "evil-" "forward-evil-"))
+
+;;;***
+
+;;;### (autoloads nil "evil-core" "evil-core.el" (0 0 0 0))
+;;; Generated autoloads from evil-core.el
+ (autoload 'evil-mode "evil" nil t)
+
+(register-definition-prefixes "evil-core" '("evil-" "turn-o"))
+
+;;;***
+
+;;;### (autoloads nil "evil-digraphs" "evil-digraphs.el" (0 0 0 0))
+;;; Generated autoloads from evil-digraphs.el
+
+(register-definition-prefixes "evil-digraphs" '("evil-digraph"))
+
+;;;***
+
+;;;### (autoloads nil "evil-ex" "evil-ex.el" (0 0 0 0))
+;;; Generated autoloads from evil-ex.el
+
+(register-definition-prefixes "evil-ex" '("evil-"))
+
+;;;***
+
+;;;### (autoloads nil "evil-integration" "evil-integration.el" (0
+;;;;;; 0 0 0))
+;;; Generated autoloads from evil-integration.el
+
+(register-definition-prefixes "evil-integration" '("evil-"))
+
+;;;***
+
+;;;### (autoloads nil "evil-jumps" "evil-jumps.el" (0 0 0 0))
+;;; Generated autoloads from evil-jumps.el
+
+(register-definition-prefixes "evil-jumps" '("evil-"))
+
+;;;***
+
+;;;### (autoloads nil "evil-macros" "evil-macros.el" (0 0 0 0))
+;;; Generated autoloads from evil-macros.el
+
+(register-definition-prefixes "evil-macros" '("evil-"))
+
+;;;***
+
+;;;### (autoloads nil "evil-maps" "evil-maps.el" (0 0 0 0))
+;;; Generated autoloads from evil-maps.el
+
+(register-definition-prefixes "evil-maps" '("evil-"))
+
+;;;***
+
+;;;### (autoloads nil "evil-repeat" "evil-repeat.el" (0 0 0 0))
+;;; Generated autoloads from evil-repeat.el
+
+(register-definition-prefixes "evil-repeat" '("evil-"))
+
+;;;***
+
+;;;### (autoloads nil "evil-search" "evil-search.el" (0 0 0 0))
+;;; Generated autoloads from evil-search.el
+
+(register-definition-prefixes "evil-search" '("evil-"))
+
+;;;***
+
+;;;### (autoloads nil "evil-states" "evil-states.el" (0 0 0 0))
+;;; Generated autoloads from evil-states.el
+
+(register-definition-prefixes "evil-states" '("evil-"))
+
+;;;***
+
+;;;### (autoloads nil "evil-types" "evil-types.el" (0 0 0 0))
+;;; Generated autoloads from evil-types.el
+
+(register-definition-prefixes "evil-types" '("evil-ex-get-optional-register-and-count"))
+
+;;;***
+
+;;;### (autoloads nil "evil-vars" "evil-vars.el" (0 0 0 0))
+;;; Generated autoloads from evil-vars.el
+
+(register-definition-prefixes "evil-vars" '("evil-"))
+
+;;;***
+
+;;;### (autoloads nil nil ("evil-development.el" "evil-keybindings.el"
+;;;;;; "evil-pkg.el" "evil.el") (0 0 0 0))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; coding: utf-8
+;; End:
+;;; evil-autoloads.el ends here
diff --git a/elpa/evil-20220503.1314/evil-command-window.el b/elpa/evil-20220503.1314/evil-command-window.el
new file mode 100644
index 0000000..b4c2b1a
--- /dev/null
+++ b/elpa/evil-20220503.1314/evil-command-window.el
@@ -0,0 +1,189 @@
+;;; evil-command-window.el --- Evil command line window implementation -*- lexical-binding: t -*-
+;; Author: Emanuel Evans <emanuel.evans at gmail.com>
+;; Maintainer: Vegard Øye <vegard_oye at hotmail.com>
+
+;; Version: 1.15.0
+
+;;
+;; This file is NOT part of GNU Emacs.
+
+;;; License:
+
+;; This file is part of Evil.
+;;
+;; Evil 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.
+;;
+;; Evil 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 Evil. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This provides an implementation of the vim command line window for
+;; editing and repeating past ex commands and searches.
+
+;;; Code:
+
+(require 'evil-vars)
+(require 'evil-common)
+(require 'evil-search)
+(require 'evil-ex)
+
+(defvar evil-search-module)
+
+(define-derived-mode evil-command-window-mode fundamental-mode "Evil-cmd"
+ "Major mode for the Evil command line window."
+ (auto-fill-mode 0)
+ (setq-local after-change-functions (cons 'evil-command-window-draw-prefix
+ after-change-functions)))
+
+(defun evil-command-window (hist cmd-key execute-fn)
+ "Open a command line window for HIST with CMD-KEY and EXECUTE-FN.
+HIST should be a list of commands. CMD-KEY should be the string of
+the key whose history is being shown (one of \":\", \"/\", or
+\"?\"). EXECUTE-FN should be a function of one argument to
+execute on the result that the user selects."
+ (when (eq major-mode 'evil-command-window-mode)
+ (user-error "Cannot recursively open command line window"))
+ (dolist (win (window-list))
+ (when (equal (buffer-name (window-buffer win))
+ "*Command Line*")
+ (kill-buffer (window-buffer win))
+ (delete-window win)))
+ (split-window nil
+ (unless (zerop evil-command-window-height)
+ evil-command-window-height)
+ 'above)
+ (setq evil-command-window-current-buffer (current-buffer))
+ (ignore-errors (kill-buffer "*Command Line*"))
+ (switch-to-buffer "*Command Line*")
+ (setq-local evil-command-window-execute-fn execute-fn)
+ (setq-local evil-command-window-cmd-key cmd-key)
+ (evil-command-window-mode)
+ (evil-command-window-insert-commands hist))
+
+(defun evil-command-window-ex (&optional current-command execute-fn)
+ "Open a command line window for editing and executing ex commands.
+If CURRENT-COMMAND is present, it will be inserted under the
+cursor as the current command to be edited. If EXECUTE-FN is given,
+it will be used as the function to execute instead of
+`evil-command-window-ex-execute', the default."
+ (interactive)
+ (evil-command-window (cons (or current-command "") evil-ex-history)
+ ":"
+ (or execute-fn 'evil-command-window-ex-execute)))
+
+(defun evil-ex-command-window ()
+ "Start command window with ex history and current minibuffer content."
+ (interactive)
+ (let ((current (minibuffer-contents))
+ (config (current-window-configuration)))
+ (evil-ex-teardown)
+ (select-window (minibuffer-selected-window) t)
+ (evil-command-window-ex current (apply-partially 'evil-ex-command-window-execute config))))
+
+(defun evil-ex-search-command-window ()
+ "Start command window with search history and current minibuffer content."
+ (interactive)
+ (let ((current (minibuffer-contents))
+ (config (current-window-configuration)))
+ (select-window (minibuffer-selected-window) t)
+ (evil-command-window (cons current evil-ex-search-history)
+ (evil-search-prompt (eq evil-ex-search-direction 'forward))
+ (apply-partially 'evil-ex-command-window-execute config))))
+
+(defun evil-command-window-execute ()
+ "Execute the command under the cursor in the appropriate buffer.
+The local var `evil-command-window-execute-fn' determines which
+function to execute."
+ (interactive)
+ (let ((result (buffer-substring (line-beginning-position)
+ (line-end-position)))
+ (execute-fn evil-command-window-execute-fn)
+ (command-window (get-buffer-window)))
+ (select-window (previous-window))
+ (unless (equal evil-command-window-current-buffer (current-buffer))
+ (user-error "Originating buffer is no longer active"))
+ (kill-buffer "*Command Line*")
+ (delete-window command-window)
+ (funcall execute-fn result)
+ (setq evil-command-window-current-buffer nil)))
+
+(defun evil-command-window-ex-execute (result)
+ "Execute RESULT as an ex command in the appropriate buffer."
+ (unless (string-match-p "^ *$" result)
+ (unless (equal result (car evil-ex-history))
+ (setq evil-ex-history (cons result evil-ex-history)))
+ (let ((evil-ex-current-buffer evil-command-window-current-buffer))
+ (evil-ex-execute result))))
+
+(defun evil-command-window-search-forward ()
+ "Open a command line window for forward searches."
+ (interactive)
+ (evil-command-window (cons ""
+ (if (eq evil-search-module 'evil-search)
+ evil-ex-search-history
+ evil-search-forward-history))
+ "/"
+ (lambda (result)
+ (evil-command-window-search-execute result t))))
+
+(defun evil-command-window-search-backward ()
+ "Open a command line window for backward searches."
+ (interactive)
+ (evil-command-window (cons ""
+ (if (eq evil-search-module 'evil-search)
+ evil-ex-search-history
+ evil-search-backward-history))
+ "?"
+ (lambda (result)
+ (evil-command-window-search-execute result nil))))
+
+(defun evil-command-window-search-execute (result forward)
+ "Search for RESULT using FORWARD to determine direction."
+ (unless (zerop (length result))
+
+ (if (eq evil-search-module 'evil-search)
+ (progn
+ (setq evil-ex-search-pattern (evil-ex-make-search-pattern result)
+ evil-ex-search-direction (if forward 'forward 'backward))
+ (unless (equal result (car-safe evil-ex-search-history))
+ (push result evil-ex-search-history))
+ (evil-ex-search))
+ (if forward
+ (unless (equal result (car-safe evil-search-forward-history))
+ (push result evil-search-forward-history))
+ (unless (equal result (car-safe evil-search-backward-history))
+ (push result evil-search-backward-history)))
+ (evil-search result forward evil-regexp-search))))
+
+(defun evil-command-window-draw-prefix (&rest ignored)
+ "Display `evil-command-window-cmd-key' as a prefix to the current line.
+Parameters passed in through IGNORED are ignored."
+ (let ((prefix (propertize evil-command-window-cmd-key
+ 'font-lock-face 'minibuffer-prompt)))
+ (set-text-properties (line-beginning-position) (line-beginning-position 2)
+ (list 'line-prefix prefix))))
+
+(defun evil-command-window-insert-commands (hist)
+ "Insert the commands in HIST."
+ (let ((inhibit-modification-hooks t))
+ (mapc #'(lambda (cmd) (insert cmd) (newline)) hist)
+ (reverse-region (point-min) (point-max)))
+ (let ((prefix (propertize evil-command-window-cmd-key
+ 'font-lock-face 'minibuffer-prompt)))
+ (set-text-properties (point-min) (point-max) (list 'line-prefix prefix)))
+ (goto-char (point-max))
+ (when (and (bolp) (not (bobp))) (backward-char))
+ (evil-adjust-cursor))
+
+(provide 'evil-command-window)
+
+;;; evil-command-window.el ends here
diff --git a/elpa/evil-20220503.1314/evil-command-window.elc b/elpa/evil-20220503.1314/evil-command-window.elc
new file mode 100644
index 0000000..886eccf
--- /dev/null
+++ b/elpa/evil-20220503.1314/evil-command-window.elc
Binary files differ
diff --git a/elpa/evil-20220503.1314/evil-commands.el b/elpa/evil-20220503.1314/evil-commands.el
new file mode 100644
index 0000000..d6b2e62
--- /dev/null
+++ b/elpa/evil-20220503.1314/evil-commands.el
@@ -0,0 +1,4908 @@
+;;; evil-commands.el --- Evil commands and operators -*- lexical-binding: t -*-
+;; Author: Vegard Øye <vegard_oye at hotmail.com>
+;; Maintainer: Vegard Øye <vegard_oye at hotmail.com>
+
+;; Version: 1.15.0
+
+;;
+;; This file is NOT part of GNU Emacs.
+
+;;; License:
+
+;; This file is part of Evil.
+;;
+;; Evil 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.
+;;
+;; Evil 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 Evil. If not, see <http://www.gnu.org/licenses/>.
+
+(require 'evil-common)
+(require 'evil-digraphs)
+(require 'evil-search)
+(require 'evil-states)
+(require 'evil-ex)
+(require 'evil-types)
+(require 'evil-command-window)
+(require 'evil-jumps)
+(require 'evil-vars)
+(require 'flyspell)
+(require 'cl-lib)
+(require 'reveal)
+
+(declare-function imenu--in-alist "imenu")
+
+;;; Motions
+
+;; Movement commands, or motions, are defined with the macro
+;; `evil-define-motion'. A motion is a command with an optional
+;; argument COUNT (interactively accessed by the code "<c>").
+;; It may specify the :type command property (e.g., :type line),
+;; which determines how it is handled by an operator command.
+;; Furthermore, the command must have the command properties
+;; :keep-visual t and :repeat motion; these are automatically
+;; set by the `evil-define-motion' macro.
+
+;;; Code:
+
+(evil-define-motion evil-forward-char (count &optional crosslines noerror)
+ "Move cursor to the right by COUNT characters.
+Movement is restricted to the current line unless CROSSLINES is non-nil.
+If NOERROR is non-nil, don't signal an error upon reaching the end
+of the line or the buffer; just return nil."
+ :type exclusive
+ (interactive "<c>" (list evil-cross-lines
+ (evil-kbd-macro-suppress-motion-error)))
+ (cond
+ (noerror
+ (condition-case nil
+ (evil-forward-char count crosslines nil)
+ (error nil)))
+ ((not crosslines)
+ ;; for efficiency, narrow the buffer to the projected
+ ;; movement before determining the current line
+ (evil-with-restriction
+ (point)
+ (save-excursion
+ (evil-forward-char (1+ (or count 1)) t t)
+ (point))
+ (condition-case err
+ (evil-narrow-to-line
+ (evil-forward-char count t noerror))
+ (error
+ ;; Restore the previous command (this one never happend).
+ ;; Actually, this preserves the current column if the
+ ;; previous command was `evil-next-line' or
+ ;; `evil-previous-line'.
+ (setq this-command last-command)
+ (signal (car err) (cdr err))))))
+ (t
+ (evil-motion-loop (nil (or count 1))
+ (forward-char)
+ ;; don't put the cursor on a newline
+ (when (and (not evil-move-beyond-eol)
+ (not (evil-visual-state-p))
+ (not (evil-operator-state-p))
+ (eolp) (not (eobp)) (not (bolp)))
+ (forward-char))))))
+
+(evil-define-motion evil-backward-char (count &optional crosslines noerror)
+ "Move cursor to the left by COUNT characters.
+Movement is restricted to the current line unless CROSSLINES is non-nil.
+If NOERROR is non-nil, don't signal an error upon reaching the beginning
+of the line or the buffer; just return nil."
+ :type exclusive
+ (interactive "<c>" (list evil-cross-lines
+ (evil-kbd-macro-suppress-motion-error)))
+ (cond
+ (noerror
+ (condition-case nil
+ (evil-backward-char count crosslines nil)
+ (error nil)))
+ ((not crosslines)
+ ;; restrict movement to the current line
+ (evil-with-restriction
+ (save-excursion
+ (evil-backward-char (1+ (or count 1)) t t)
+ (point))
+ (1+ (point))
+ (condition-case err
+ (evil-narrow-to-line
+ (evil-backward-char count t noerror))
+ (error
+ ;; Restore the previous command (this one never happened).
+ ;; Actually, this preserves the current column if the
+ ;; previous command was `evil-next-line' or
+ ;; `evil-previous-line'.
+ (setq this-command last-command)
+ (signal (car err) (cdr err))))))
+ (t
+ (evil-motion-loop (nil (or count 1))
+ (backward-char)
+ ;; don't put the cursor on a newline
+ (unless (or (evil-visual-state-p) (evil-operator-state-p))
+ (evil-adjust-cursor))))))
+
+(evil-define-motion evil-next-line (count)
+ "Move the cursor COUNT lines down."
+ :type line
+ (let (line-move-visual)
+ (evil-line-move (or count 1))))
+
+(evil-define-motion evil-previous-line (count)
+ "Move the cursor COUNT lines up."
+ :type line
+ (let (line-move-visual)
+ (evil-line-move (- (or count 1)))))
+
+(evil-define-motion evil-next-visual-line (count)
+ "Move the cursor COUNT screen lines down."
+ :type exclusive
+ (let ((line-move-visual t))
+ (evil-line-move (or count 1))))
+
+(evil-define-motion evil-previous-visual-line (count)
+ "Move the cursor COUNT screen lines up."
+ :type exclusive
+ (let ((line-move-visual t))
+ (evil-line-move (- (or count 1)))))
+
+;; used for repeated commands like "dd"
+(evil-define-motion evil-line (count)
+ "Move COUNT - 1 lines down."
+ :type line
+ (let (line-move-visual)
+ ;; Catch bob and eob errors. These are caused when not moving
+ ;; point starting in the first or last line, respectively. In this
+ ;; case the current line should be selected.
+ (condition-case _err
+ (evil-line-move (1- (or count 1)))
+ ((beginning-of-buffer end-of-buffer)))))
+
+(evil-define-motion evil-line-or-visual-line (count)
+ "Move COUNT - 1 lines down."
+ :type screen-line
+ (let ((line-move-visual (and evil-respect-visual-line-mode
+ visual-line-mode)))
+ ;; Catch bob and eob errors. These are caused when not moving
+ ;; point starting in the first or last line, respectively. In this
+ ;; case the current line should be selected.
+ (condition-case _err
+ (evil-line-move (1- (or count 1)))
+ ((beginning-of-buffer end-of-buffer)))))
+
+(evil-define-motion evil-beginning-of-line ()
+ "Move the cursor to the beginning of the current line."
+ :type exclusive
+ (move-beginning-of-line nil))
+
+(evil-define-motion evil-end-of-line (count)
+ "Move the cursor to the end of the current line.
+If COUNT is given, move COUNT - 1 lines downward first."
+ :type inclusive
+ (move-end-of-line count)
+ (when evil-track-eol
+ (setq temporary-goal-column most-positive-fixnum
+ this-command 'next-line))
+ (if (evil-visual-state-p)
+ (when evil-v$-excludes-newline
+ (let ((evil-move-beyond-eol nil))
+ (evil-adjust-cursor)))
+ (evil-adjust-cursor)
+ (when (eolp)
+ ;; prevent "c$" and "d$" from deleting blank lines
+ (setq evil-this-type 'exclusive))))
+
+(evil-define-motion evil-beginning-of-visual-line ()
+ "Move the cursor to the first character of the current screen line."
+ :type exclusive
+ (if (fboundp 'beginning-of-visual-line)
+ (beginning-of-visual-line)
+ (beginning-of-line)))
+
+(evil-define-motion evil-end-of-visual-line (count)
+ "Move the cursor to the last character of the current screen line.
+If COUNT is given, move COUNT - 1 screen lines downward first."
+ :type inclusive
+ (if (fboundp 'end-of-visual-line)
+ (end-of-visual-line count)
+ (end-of-line count)))
+
+(evil-define-motion evil-end-of-line-or-visual-line (count)
+ "Move the cursor to the last character of the current screen
+line if `visual-line-mode' is active and
+`evil-respect-visual-line-mode' is non-nil. If COUNT is given,
+move COUNT - 1 screen lines downward first."
+ :type inclusive
+ (if (and (fboundp 'end-of-visual-line)
+ evil-respect-visual-line-mode
+ visual-line-mode)
+ (end-of-visual-line count)
+ (evil-end-of-line count)))
+
+(evil-define-motion evil-middle-of-visual-line ()
+ "Move the cursor to the middle of the current visual line."
+ :type exclusive
+ (beginning-of-visual-line)
+ (evil-with-restriction
+ nil
+ (save-excursion (end-of-visual-line) (point))
+ (move-to-column (+ (current-column)
+ -1
+ (/ (with-no-warnings (window-body-width)) 2)))))
+
+(evil-define-motion evil-percentage-of-line (count)
+ "Move the cursor to COUNT % of the width of the current line.
+If no COUNT is given, default to 50%."
+ :type exclusive
+ (let ((line-length (- (line-end-position)
+ (line-beginning-position)
+ (if evil-move-beyond-eol -1 0))))
+ (move-to-column (truncate (* line-length (/ (or count 50) 100.0))))))
+
+(evil-define-motion evil-first-non-blank ()
+ "Move the cursor to the first non-blank character of the current line."
+ :type exclusive
+ (evil-narrow-to-line (back-to-indentation)))
+
+(evil-define-motion evil-last-non-blank (count)
+ "Move the cursor to the last non-blank character of the current line.
+If COUNT is given, move COUNT - 1 lines downward first."
+ :type inclusive
+ (goto-char
+ (save-excursion
+ (evil-move-beginning-of-line count)
+ (if (re-search-forward "[ \t]*$")
+ (max (line-beginning-position)
+ (1- (match-beginning 0)))
+ (line-beginning-position)))))
+
+(evil-define-motion evil-first-non-blank-of-visual-line ()
+ "Move the cursor to the first non blank character
+of the current screen line."
+ :type exclusive
+ (evil-beginning-of-visual-line)
+ (skip-chars-forward " \t\r"))
+
+(evil-define-motion evil-next-line-first-non-blank (count)
+ "Move the cursor COUNT lines down on the first non-blank character."
+ :type line
+ (let ((this-command this-command))
+ (evil-next-line (or count 1)))
+ (evil-first-non-blank))
+
+(evil-define-motion evil-next-line-1-first-non-blank (count)
+ "Move the cursor COUNT-1 lines down on the first non-blank character."
+ :type line
+ (let ((this-command this-command))
+ (evil-next-line (1- (or count 1))))
+ (evil-first-non-blank))
+
+(evil-define-motion evil-previous-line-first-non-blank (count)
+ "Move the cursor COUNT lines up on the first non-blank character."
+ :type line
+ (let ((this-command this-command))
+ (evil-previous-line (or count 1)))
+ (evil-first-non-blank))
+
+(evil-define-motion evil-goto-line (count)
+ "Go to line COUNT. By default the last line."
+ :jump t
+ :type line
+ (evil-ensure-column
+ (if (null count)
+ (goto-char (point-max))
+ (goto-char (point-min))
+ (forward-line (1- count)))))
+
+(evil-define-motion evil-goto-first-line (count)
+ "Go to line COUNT. By default the first line."
+ :jump t
+ :type line
+ (evil-goto-line (or count 1)))
+
+(evil-define-motion evil-forward-word-begin (count &optional bigword)
+ "Move the cursor to the beginning of the COUNT-th next word.
+If BIGWORD is non-nil, move by WORDS.
+
+If this command is called in operator-pending state it behaves
+differently. If point reaches the beginning of a word on a new
+line point is moved back to the end of the previous line.
+
+If called after a change operator, i.e. cw or cW,
+`evil-want-change-word-to-end' is non-nil and point is on a word,
+then both behave like ce or cE.
+
+If point is at the end of the buffer and cannot be moved signal
+'end-of-buffer is raised.
+"
+ :type exclusive
+ (let ((thing (if bigword 'evil-WORD 'evil-word))
+ (orig (point))
+ (count (or count 1)))
+ (evil-signal-at-bob-or-eob count)
+ (cond
+ ;; default motion, beginning of next word
+ ((not (evil-operator-state-p))
+ (evil-forward-beginning thing count))
+ ;; the evil-change operator, maybe behave like ce or cE
+ ((and evil-want-change-word-to-end
+ (memq evil-this-operator evil-change-commands)
+ (< orig (or (cdr-safe (bounds-of-thing-at-point thing)) orig)))
+ ;; forward-thing moves point to the correct position because
+ ;; this is an exclusive motion
+ (forward-thing thing count))
+ ;; operator state
+ (t
+ (prog1 (evil-forward-beginning thing count)
+ ;; if we reached the beginning of a word on a new line in
+ ;; Operator-Pending state, go back to the end of the previous
+ ;; line
+ (when (and (> (line-beginning-position) orig)
+ (looking-back "^[[:space:]]*" (line-beginning-position)))
+ ;; move cursor back as long as the line contains only
+ ;; whitespaces and is non-empty
+ (evil-move-end-of-line 0)
+ ;; skip non-empty lines containing only spaces
+ (while (and (looking-back "^[[:space:]]+$" (line-beginning-position))
+ (not (<= (line-beginning-position) orig)))
+ (evil-move-end-of-line 0))
+ ;; but if the previous line is empty, delete this line
+ (when (bolp) (forward-char))))))))
+
+(evil-define-motion evil-forward-word-end (count &optional bigword)
+ "Move the cursor to the end of the COUNT-th next word.
+If BIGWORD is non-nil, move by WORDS."
+ :type inclusive
+ (let ((thing (if bigword 'evil-WORD 'evil-word))
+ (count (or count 1)))
+ (evil-signal-at-bob-or-eob count)
+ ;; Evil special behaviour: e or E on a one-character word in
+ ;; operator state does not move point
+ (unless (and (evil-operator-state-p)
+ (= 1 count)
+ (let ((bnd (bounds-of-thing-at-point thing)))
+ (and bnd
+ (= (car bnd) (point))
+ (= (cdr bnd) (1+ (point)))))
+ (looking-at "[[:word:]]"))
+ (evil-forward-end thing count))))
+
+(evil-define-motion evil-backward-word-begin (count &optional bigword)
+ "Move the cursor to the beginning of the COUNT-th previous word.
+If BIGWORD is non-nil, move by WORDS."
+ :type exclusive
+ (let ((thing (if bigword 'evil-WORD 'evil-word)))
+ (evil-signal-at-bob-or-eob (- (or count 1)))
+ (evil-backward-beginning thing count)))
+
+(evil-define-motion evil-backward-word-end (count &optional bigword)
+ "Move the cursor to the end of the COUNT-th previous word.
+If BIGWORD is non-nil, move by WORDS."
+ :type inclusive
+ (let ((thing (if bigword 'evil-WORD 'evil-word)))
+ (evil-signal-at-bob-or-eob (- (or count 1)))
+ (evil-backward-end thing count)))
+
+(evil-define-motion evil-forward-WORD-begin (count)
+ "Move the cursor to the beginning of the COUNT-th next WORD."
+ :type exclusive
+ (evil-forward-word-begin count t))
+
+(evil-define-motion evil-forward-WORD-end (count)
+ "Move the cursor to the end of the COUNT-th next WORD."
+ :type inclusive
+ (evil-forward-word-end count t))
+
+(evil-define-motion evil-backward-WORD-begin (count)
+ "Move the cursor to the beginning of the COUNT-th previous WORD."
+ :type exclusive
+ (evil-backward-word-begin count t))
+
+(evil-define-motion evil-backward-WORD-end (count)
+ "Move the cursor to the end of the COUNT-th previous WORD."
+ :type inclusive
+ (evil-backward-word-end count t))
+
+;; section movement
+(evil-define-motion evil-forward-section-begin (count)
+ "Move the cursor to the beginning of the COUNT-th next section."
+ :jump t
+ :type exclusive
+ (evil-signal-at-bob-or-eob count)
+ (evil-forward-beginning 'evil-defun count))
+
+(evil-define-motion evil-forward-section-end (count)
+ "Move the cursor to the end of the COUNT-th next section."
+ :jump t
+ :type inclusive
+ (evil-signal-at-bob-or-eob count)
+ (evil-forward-end 'evil-defun count)
+ (unless (eobp) (forward-line)))
+
+(evil-define-motion evil-backward-section-begin (count)
+ "Move the cursor to the beginning of the COUNT-th previous section."
+ :jump t
+ :type exclusive
+ (evil-signal-at-bob-or-eob (- (or count 1)))
+ (evil-backward-beginning 'evil-defun count))
+
+(evil-define-motion evil-backward-section-end (count)
+ "Move the cursor to the end of the COUNT-th previous section."
+ :jump t
+ :type inclusive
+ (evil-signal-at-bob-or-eob (- (or count 1)))
+ (end-of-line -1)
+ (evil-backward-end 'evil-defun count)
+ (unless (eobp) (forward-line)))
+
+(evil-define-motion evil-forward-sentence-begin (count)
+ "Move to the next COUNT-th beginning of a sentence or end of a paragraph."
+ :jump t
+ :type exclusive
+ (evil-signal-at-bob-or-eob count)
+ (evil-forward-nearest count
+ #'(lambda (_cnt)
+ (evil-forward-beginning 'evil-sentence))
+ #'evil-forward-paragraph))
+
+(evil-define-motion evil-backward-sentence-begin (count)
+ "Move to the previous COUNT-th beginning of a sentence or paragraph."
+ :jump t
+ :type exclusive
+ (evil-signal-at-bob-or-eob (- (or count 1)))
+ (evil-forward-nearest (- (or count 1))
+ #'(lambda (_cnt)
+ (evil-backward-beginning 'evil-sentence))
+ #'(lambda (_cnt)
+ (evil-backward-paragraph))))
+
+(evil-define-motion evil-forward-paragraph (count)
+ "Move to the end of the COUNT-th next paragraph."
+ :jump t
+ :type exclusive
+ (evil-signal-at-bob-or-eob count)
+ (evil-forward-end 'evil-paragraph count)
+ (unless (eobp) (forward-line)))
+
+(evil-define-motion evil-backward-paragraph (count)
+ "Move to the beginning of the COUNT-th previous paragraph."
+ :jump t
+ :type exclusive
+ (evil-signal-at-bob-or-eob (- (or count 1)))
+ (unless (eobp) (forward-line))
+ (evil-backward-beginning 'evil-paragraph count)
+ (unless (bobp) (forward-line -1)))
+
+(defvar hif-ifx-else-endif-regexp)
+(evil-define-motion evil-jump-item (count)
+ "Find the next item in this line after or under the cursor
+and jump to the corresponding one."
+ :jump t
+ :type inclusive
+ (cond
+ ;; COUNT% jumps to a line COUNT percentage down the file
+ (count
+ (evil-ensure-column
+ (goto-char
+ (evil-normalize-position
+ (let ((size (- (point-max) (point-min))))
+ (+ (point-min)
+ (if (> size 80000)
+ (* count (/ size 100))
+ (/ (* count size) 100)))))))
+ (setq evil-this-type 'line))
+ ((and (evil-looking-at-start-comment t)
+ (let ((pnt (point)))
+ (forward-comment 1)
+ (or (not (bolp))
+ (prog1 nil (goto-char pnt)))))
+ (backward-char))
+ ((and (not (eolp)) (evil-looking-at-end-comment t))
+ (forward-comment -1))
+ ((and
+ (memq major-mode '(c-mode c++-mode))
+ (require 'hideif nil t)
+ (with-no-warnings
+ (let* ((hif-else-regexp (concat hif-cpp-prefix "\\(?:else\\|elif[ \t]+\\)"))
+ (hif-ifx-else-endif-regexp
+ (concat hif-ifx-regexp "\\|" hif-else-regexp "\\|" hif-endif-regexp)))
+ (cond
+ ((save-excursion (beginning-of-line) (or (hif-looking-at-ifX) (hif-looking-at-else)))
+ (hif-find-next-relevant)
+ (while (hif-looking-at-ifX)
+ (hif-ifdef-to-endif)
+ (hif-find-next-relevant))
+ t)
+ ((save-excursion (beginning-of-line) (hif-looking-at-endif))
+ (hif-endif-to-ifdef)
+ t))))))
+ (t
+ (let* ((open (point-max))
+ (close (point-max))
+ (open-pair (condition-case nil
+ (save-excursion
+ ;; consider the character right before eol given that
+ ;; point may be placed there, e.g. in visual state
+ (when (and (eolp) (not (bolp)))
+ (backward-char))
+ (setq open (1- (scan-lists (point) 1 -1)))
+ (when (< open (line-end-position))
+ (goto-char open)
+ (forward-list)
+ (1- (point))))
+ (error nil)))
+ (close-pair (condition-case nil
+ (save-excursion
+ ;; consider the character right before eol given that
+ ;; point may be placed there, e.g. in visual state
+ (when (and (eolp) (not (bolp)))
+ (backward-char))
+ (setq close (1- (scan-lists (point) 1 1)))
+ (when (< close (line-end-position))
+ (goto-char (1+ close))
+ (backward-list)
+ (point)))
+ (error nil))))
+ (cond
+ ((not (or open-pair close-pair))
+ ;; nothing found, check if we are inside a string
+ (let ((pnt (point))
+ (bnd (bounds-of-thing-at-point 'evil-string)))
+ (if (not (and bnd (< (point) (cdr bnd))))
+ ;; no, then we really failed
+ (user-error "No matching item found on the current line")
+ ;; yes, go to the end of the string and try again
+ (let ((endstr (cdr bnd)))
+ (when (or (save-excursion
+ (goto-char endstr)
+ (let ((b (bounds-of-thing-at-point 'evil-string)))
+ (and b (< (point) (cdr b))))) ; not at end of string
+ (condition-case nil
+ (progn
+ (goto-char endstr)
+ (evil-jump-item)
+ nil)
+ (error t)))
+ ;; failed again, go back to original point
+ (goto-char pnt)
+ (user-error "No matching item found on the current line"))))))
+ ((< open close) (goto-char open-pair))
+ (t (goto-char close-pair)))))))
+
+(defun evil--flyspell-overlays-in-p (beg end)
+ (let ((ovs (overlays-in beg end))
+ done)
+ (while (and ovs (not done))
+ (when (flyspell-overlay-p (car ovs))
+ (setq done t))
+ (setq ovs (cdr ovs)))
+ done))
+
+(defun evil--flyspell-overlay-at (pos forwardp)
+ (when (not forwardp)
+ (setq pos (max (1- pos) (point-min))))
+ (let ((ovs (overlays-at pos))
+ done)
+ (while (and ovs (not done))
+ (if (flyspell-overlay-p (car ovs))
+ (setq done t)
+ (setq ovs (cdr ovs))))
+ (when done
+ (car ovs))))
+
+(defun evil--flyspell-overlay-after (pos limit forwardp)
+ (let (done)
+ (while (and (if forwardp
+ (< pos limit)
+ (> pos limit))
+ (not done))
+ (let ((ov (evil--flyspell-overlay-at pos forwardp)))
+ (when ov
+ (setq done ov)))
+ (setq pos (if forwardp
+ (next-overlay-change pos)
+ (previous-overlay-change pos))))
+ done))
+
+(defun evil--next-flyspell-error (forwardp)
+ (when (evil--flyspell-overlays-in-p (point-min) (point-max))
+ (let ((pos (point))
+ limit
+ ov)
+ (when (evil--flyspell-overlay-at pos forwardp)
+ (if (/= pos (point-min))
+ (setq pos (save-excursion (goto-char pos)
+ (forward-word (if forwardp 1 -1))
+ (point)))
+ (setq pos (point-max))))
+ (setq limit (if forwardp (point-max) (point-min))
+ ov (evil--flyspell-overlay-after pos limit forwardp))
+ (if ov
+ (goto-char (overlay-start ov))
+ (when evil-search-wrap
+ (setq limit pos
+ pos (if forwardp (point-min) (point-max))
+ ov (evil--flyspell-overlay-after pos limit forwardp))
+ (when ov
+ (goto-char (overlay-start ov))))))))
+
+(evil-define-motion evil-next-flyspell-error (count)
+ "Go to the COUNT'th spelling mistake after point."
+ (interactive "p")
+ (dotimes (_ count)
+ (evil--next-flyspell-error t)))
+
+(evil-define-motion evil-prev-flyspell-error (count)
+ "Go to the COUNT'th spelling mistake preceding point."
+ (interactive "p")
+ (dotimes (_ count)
+ (evil--next-flyspell-error nil)))
+
+(evil-define-motion evil-previous-open-paren (count)
+ "Go to [count] previous unmatched '('."
+ :type exclusive
+ (evil-up-paren ?\( ?\) (- (or count 1))))
+
+(evil-define-motion evil-next-close-paren (count)
+ "Go to [count] next unmatched ')'."
+ :type exclusive
+ (forward-char)
+ (evil-up-paren ?\( ?\) (or count 1))
+ (backward-char))
+
+(evil-define-motion evil-previous-open-brace (count)
+ "Go to [count] previous unmatched '{'."
+ :type exclusive
+ (evil-up-paren ?{ ?} (- (or count 1))))
+
+(evil-define-motion evil-next-close-brace (count)
+ "Go to [count] next unmatched '}'."
+ :type exclusive
+ (forward-char)
+ (evil-up-paren ?{ ?} (or count 1))
+ (backward-char))
+
+(defun evil--lowercase-markers ()
+ "Get all lowercase markers."
+ (cl-remove-if-not (lambda (x) (and (markerp (cdr x))
+ (<= ?a (car x) ?z)))
+ evil-markers-alist))
+
+(defun evil--next-mark (forwardp)
+ "Move to next lowercase mark.
+Move forward if FORWARDP is truthy or backward if falsey.
+Loop back to the top of buffer if the end is reached."
+ (let ((pos (point))
+ (sorted-markers (sort (evil--lowercase-markers)
+ (lambda (a b) (< (cdr a) (cdr b))))))
+ (cond
+ ((null sorted-markers)
+ (user-error "No marks in this buffer"))
+ (forwardp
+ (let ((next-marker (cl-some (lambda (x) (and (< pos (cdr x)) (cdr x)))
+ sorted-markers)))
+ (if next-marker
+ (goto-char (marker-position next-marker))
+ (goto-char (marker-position (cdar sorted-markers))))))
+ (t
+ (let* ((descending-markers (reverse sorted-markers))
+ (prev-marker (cl-some (lambda (x) (and (> pos (cdr x)) (cdr x)))
+ descending-markers)))
+ (if prev-marker
+ (goto-char (marker-position prev-marker))
+ (goto-char (marker-position (cdar descending-markers)))))))))
+
+(evil-define-motion evil-next-mark (count)
+ "Go to [count] next lowercase mark."
+ :keep-visual t
+ :repeat nil
+ :type exclusive
+ :jump t
+ (dotimes (_ (or count 1))
+ (evil--next-mark t)))
+
+(evil-define-motion evil-next-mark-line (count)
+ "Go to [count] line of next lowercase mark after current line."
+ :keep-visual t
+ :repeat nil
+ :type exclusive
+ :jump t
+ (if (evil--lowercase-markers)
+ (dotimes (_ (or count 1))
+ (evil-end-of-line)
+ (evil--next-mark t)
+ (evil-first-non-blank))
+ (user-error "No marks in this buffer")))
+
+(evil-define-motion evil-previous-mark (count)
+ "Go to [count] previous lowercase mark."
+ :keep-visual t
+ :repeat nil
+ :type exclusive
+ :jump t
+ (dotimes (_ (or count 1))
+ (evil--next-mark nil)))
+
+(evil-define-motion evil-previous-mark-line (count)
+ "Go to [count] line of previous lowercase mark before current line."
+ :keep-visual t
+ :repeat nil
+ :type exclusive
+ :jump t
+ (if (evil--lowercase-markers)
+ (dotimes (_ (or count 1))
+ (evil-beginning-of-line)
+ (evil--next-mark nil)
+ (evil-first-non-blank))
+ (user-error "No marks in this buffer")))
+
+(evil-define-command evil-set-col-0-mark (beg end mark)
+ "Set MARK at column 0 of line of END. Default is cursor line."
+ (interactive "<r><a>")
+ (if (< 1 (length mark))
+ (user-error "Trailing characters")
+ (save-excursion
+ (goto-char (if (eobp) end (1- end)))
+ (evil-beginning-of-line)
+ (evil-set-marker (string-to-char mark)))))
+
+(evil-define-motion evil-find-char (count char)
+ "Move to the next COUNT'th occurrence of CHAR.
+Movement is restricted to the current line unless `evil-cross-lines' is non-nil."
+ :type inclusive
+ (interactive "<c><C>")
+ (setq count (or count 1))
+ (let ((fwd (> count 0))
+ (visual (and evil-respect-visual-line-mode
+ visual-line-mode)))
+ (setq evil-last-find (list #'evil-find-char char fwd))
+ (when fwd (evil-forward-char 1 evil-cross-lines))
+ (let ((case-fold-search nil))
+ (unless (prog1
+ (search-forward (char-to-string char)
+ (cond (evil-cross-lines
+ nil)
+ ((and fwd visual)
+ (save-excursion
+ (end-of-visual-line)
+ (point)))
+ (fwd
+ (line-end-position))
+ (visual
+ (save-excursion
+ (beginning-of-visual-line)
+ (point)))
+ (t
+ (line-beginning-position)))
+ t count)
+ (when fwd (backward-char)))
+ (user-error "Can't find %c" char)))))
+
+(evil-define-motion evil-find-char-backward (count char)
+ "Move to the previous COUNT'th occurrence of CHAR."
+ :type exclusive
+ (interactive "<c><C>")
+ (evil-find-char (- (or count 1)) char))
+
+(evil-define-motion evil-find-char-to (count char)
+ "Move before the next COUNT'th occurrence of CHAR."
+ :type inclusive
+ (interactive "<c><C>")
+ (unwind-protect
+ (progn
+ (evil-find-char count char)
+ (if (> (or count 1) 0)
+ (backward-char)
+ (forward-char)))
+ (setcar evil-last-find #'evil-find-char-to)))
+
+(evil-define-motion evil-find-char-to-backward (count char)
+ "Move before the previous COUNT'th occurrence of CHAR."
+ :type exclusive
+ (interactive "<c><C>")
+ (evil-find-char-to (- (or count 1)) char))
+
+(evil-define-motion evil-repeat-find-char (count)
+ "Repeat the last find COUNT times."
+ :type inclusive
+ (setq count (or count 1))
+ (if evil-last-find
+ (let ((cmd (car evil-last-find))
+ (char (nth 1 evil-last-find))
+ (fwd (nth 2 evil-last-find))
+ evil-last-find)
+ ;; ensure count is non-negative
+ (when (< count 0)
+ (setq count (- count)
+ fwd (not fwd)))
+ ;; skip next character when repeating t or T
+ (and (eq cmd #'evil-find-char-to)
+ evil-repeat-find-to-skip-next
+ (= count 1)
+ (or (and fwd (= (char-after (1+ (point))) char))
+ (and (not fwd) (= (char-before) char)))
+ (setq count (1+ count)))
+ (funcall cmd (if fwd count (- count)) char)
+ (unless (nth 2 evil-last-find)
+ (setq evil-this-type 'exclusive)))
+ (user-error "No previous search")))
+
+(evil-define-motion evil-repeat-find-char-reverse (count)
+ "Repeat the last find COUNT times in the opposite direction."
+ :type inclusive
+ (evil-repeat-find-char (- (or count 1))))
+
+;; ceci n'est pas une pipe
+(evil-define-motion evil-goto-column (count)
+ "Go to column COUNT on the current line.
+Columns are counted from zero."
+ :type exclusive
+ (move-to-column (or count 0)))
+
+(evil-define-command evil-goto-mark (char &optional noerror)
+ "Go to the marker specified by CHAR."
+ :keep-visual t
+ :repeat nil
+ :type exclusive
+ :jump t
+ (interactive (list (read-char)))
+ (let ((marker (evil-get-marker char)))
+ (cond
+ ((markerp marker)
+ (switch-to-buffer (marker-buffer marker))
+ (goto-char (marker-position marker)))
+ ((numberp marker)
+ (goto-char marker))
+ ((consp marker)
+ (when (or (find-buffer-visiting (car marker))
+ (and (y-or-n-p (format "Visit file %s again? "
+ (car marker)))
+ (find-file (car marker))))
+ (goto-char (cdr marker))))
+ ((not noerror)
+ (user-error "Marker `%c' is not set%s" char
+ (if (evil-global-marker-p char) ""
+ " in this buffer"))))))
+
+(evil-define-command evil-goto-mark-line (char &optional noerror)
+ "Go to the line of the marker specified by CHAR."
+ :keep-visual t
+ :repeat nil
+ :type line
+ :jump t
+ (interactive (list (read-char)))
+ (evil-goto-mark char noerror)
+ (evil-first-non-blank))
+
+(evil-define-motion evil-jump-backward (count)
+ "Go to older position in jump list.
+To go the other way, press \
+\\<evil-motion-state-map>\\[evil-jump-forward]."
+ (evil--jump-backward count))
+
+(evil-define-motion evil-jump-forward (count)
+ "Go to newer position in jump list.
+To go the other way, press \
+\\<evil-motion-state-map>\\[evil-jump-backward]."
+ (evil--jump-forward count))
+
+(evil-define-motion evil-jump-backward-swap (count)
+ "Go to the previous position in jump list.
+The current position is placed in the jump list."
+ (let ((pnt (point)))
+ (evil--jump-backward 1)
+ (evil-set-jump pnt)))
+
+(defvar xref-prompt-for-identifier)
+(evil-define-motion evil-jump-to-tag (arg)
+ "Jump to tag under point.
+If called with a prefix argument, provide a prompt
+for specifying the tag."
+ :jump t
+ (interactive "P")
+ (cond
+ ((fboundp 'xref-find-definitions)
+ (let ((xref-prompt-for-identifier arg))
+ (call-interactively #'xref-find-definitions)))
+ ((fboundp 'find-tag)
+ (if arg (call-interactively #'find-tag)
+ (let ((tag (funcall (or find-tag-default-function
+ (get major-mode 'find-tag-default-function)
+ #'find-tag-default))))
+ (unless tag (user-error "No tag candidate found around point"))
+ (find-tag tag))))))
+
+(evil-define-motion evil-lookup ()
+ "Look up the keyword at point.
+Calls `evil-lookup-func'."
+ (funcall evil-lookup-func))
+
+(defun evil-ret-gen (count indent?)
+ (let* ((field (get-char-property (point) 'field))
+ (button (get-char-property (point) 'button))
+ (doc (get-char-property (point) 'widget-doc))
+ (widget (or field button doc)))
+ (cond
+ ((and widget
+ (fboundp 'widget-type)
+ (fboundp 'widget-button-press)
+ (or (and (symbolp widget)
+ (get widget 'widget-type))
+ (and (consp widget)
+ (get (widget-type widget) 'widget-type))))
+ (when (evil-operator-state-p)
+ (setq evil-inhibit-operator t))
+ (when (fboundp 'widget-button-press)
+ (widget-button-press (point))))
+ ((and (fboundp 'button-at)
+ (fboundp 'push-button)
+ (button-at (point)))
+ (when (evil-operator-state-p)
+ (setq evil-inhibit-operator t))
+ (push-button))
+ ((or (evil-emacs-state-p)
+ (and (evil-insert-state-p)
+ (not buffer-read-only)))
+ (if (not indent?)
+ (newline count)
+ (delete-horizontal-space t)
+ (newline count)
+ (indent-according-to-mode)))
+ (t
+ (evil-next-line-first-non-blank count)))))
+
+(evil-define-motion evil-ret (count)
+ "Move the cursor COUNT lines down.
+If point is on a widget or a button, click on it.
+In Insert state, insert a newline."
+ :type line
+ (evil-ret-gen count nil))
+
+(evil-define-motion evil-ret-and-indent (count)
+ "Move the cursor COUNT lines down.
+If point is on a widget or a button, click on it.
+In Insert state, insert a newline and indent."
+ :type line
+ (evil-ret-gen count t))
+
+(evil-define-motion evil-window-top (count)
+ "Move the cursor to line COUNT from the top of the window."
+ :jump t
+ :type line
+ (evil-ensure-column
+ (move-to-window-line (max (or count 0)
+ (if (= (point-min) (window-start))
+ 0
+ scroll-margin)))))
+
+(evil-define-motion evil-window-middle ()
+ "Move the cursor to the middle line in the window."
+ :jump t
+ :type line
+ (evil-ensure-column
+ (move-to-window-line
+ (/ (1+ (save-excursion (move-to-window-line -1))) 2))))
+
+(evil-define-motion evil-window-bottom (count)
+ "Move the cursor to line COUNT from the bottom of the window."
+ :jump t
+ :type line
+ (evil-ensure-column
+ (move-to-window-line (- (max (or count 1) (1+ scroll-margin))))))
+
+;; scrolling
+(evil-define-command evil-scroll-line-up (count)
+ "Scrolls the window COUNT lines upwards."
+ :repeat nil
+ :keep-visual t
+ (interactive "p")
+ (let ((scroll-preserve-screen-position nil))
+ (scroll-down count)))
+
+(evil-define-command evil-scroll-line-down (count)
+ "Scrolls the window COUNT lines downwards."
+ :repeat nil
+ :keep-visual t
+ (interactive "p")
+ (let ((scroll-preserve-screen-position nil))
+ (scroll-up count)))
+
+(evil-define-command evil-scroll-count-reset ()
+ "Sets `evil-scroll-count' to 0.
+`evil-scroll-up' and `evil-scroll-down' will scroll
+for a half of the screen(default)."
+ :repeat nil
+ :keep-visual t
+ (interactive)
+ (setq evil-scroll-count 0))
+
+(evil-define-command evil-scroll-up (count)
+ "Scrolls the window and the cursor COUNT lines upwards.
+If COUNT is not specified the function scrolls down
+`evil-scroll-count', which is the last used count.
+If the scroll count is zero the command scrolls half the screen."
+ :repeat nil
+ :keep-visual t
+ (interactive "<c>")
+ (evil-ensure-column
+ (setq count (or count (max 0 evil-scroll-count))
+ evil-scroll-count count
+ this-command 'next-line)
+ (when (= (point-min) (line-beginning-position))
+ (signal 'beginning-of-buffer nil))
+ (when (zerop count)
+ (setq count (/ (window-body-height) 2)))
+ (let ((xy (evil-posn-x-y (posn-at-point))))
+ (condition-case nil
+ (progn
+ (scroll-down count)
+ (goto-char (posn-point (posn-at-x-y (car xy) (cdr xy)))))
+ (beginning-of-buffer
+ (condition-case nil
+ (with-no-warnings (previous-line count))
+ (beginning-of-buffer)))))))
+
+(evil-define-command evil-scroll-down (count)
+ "Scrolls the window and the cursor COUNT lines downwards.
+If COUNT is not specified the function scrolls down
+`evil-scroll-count', which is the last used count.
+If the scroll count is zero the command scrolls half the screen."
+ :repeat nil
+ :keep-visual t
+ (interactive "<c>")
+ (evil-ensure-column
+ (setq count (or count (max 0 evil-scroll-count))
+ evil-scroll-count count
+ this-command 'next-line)
+ (when (eobp) (signal 'end-of-buffer nil))
+ (when (zerop count)
+ (setq count (/ (window-body-height) 2)))
+ ;; BUG #660: First check whether the eob is visible.
+ ;; In that case we do not scroll but merely move point.
+ (if (<= (point-max) (window-end))
+ (with-no-warnings (next-line count nil))
+ (let ((xy (evil-posn-x-y (posn-at-point))))
+ (condition-case nil
+ (progn
+ (scroll-up count)
+ (let* ((wend (window-end nil t))
+ (p (posn-at-x-y (car xy) (cdr xy)))
+ (margin (max 0 (- scroll-margin
+ (cdr (posn-col-row p))))))
+ (goto-char (posn-point p))
+ ;; ensure point is not within the scroll-margin
+ (when (> margin 0)
+ (with-no-warnings (next-line margin))
+ (recenter scroll-margin))
+ (when (<= (point-max) wend)
+ (save-excursion
+ (goto-char (point-max))
+ (recenter (- (max 1 scroll-margin)))))))
+ (end-of-buffer
+ (goto-char (point-max))
+ (recenter (- (max 1 scroll-margin)))))))))
+
+(evil-define-command evil-scroll-page-up (count)
+ "Scrolls the window COUNT pages upwards."
+ :repeat nil
+ :keep-visual t
+ (interactive "p")
+ (evil-ensure-column
+ (dotimes (i count)
+ (condition-case err
+ (scroll-down nil)
+ (beginning-of-buffer
+ (if (and (bobp) (zerop i))
+ (signal (car err) (cdr err))
+ (goto-char (point-min))))))))
+
+(evil-define-command evil-scroll-page-down (count)
+ "Scrolls the window COUNT pages downwards."
+ :repeat nil
+ :keep-visual t
+ (interactive "p")
+ (evil-ensure-column
+ (dotimes (i count)
+ (condition-case err
+ (scroll-up nil)
+ (end-of-buffer
+ (if (and (eobp) (zerop i))
+ (signal (car err) (cdr err))
+ (goto-char (point-max))))))))
+
+(evil-define-command evil-scroll-line-to-top (count)
+ "Scrolls line number COUNT (or the cursor line) to the top of the window."
+ :repeat nil
+ :keep-visual t
+ (interactive "<c>")
+ (evil-save-column
+ (let ((line (or count (line-number-at-pos (point)))))
+ (goto-char (point-min))
+ (forward-line (1- line)))
+ (recenter (1- (max 1 scroll-margin)))))
+
+(evil-define-command evil-scroll-line-to-center (count)
+ "Scrolls line number COUNT (or the cursor line) to the center of the window."
+ :repeat nil
+ :keep-visual t
+ (interactive "<c>")
+ (evil-save-column
+ (when count
+ (goto-char (point-min))
+ (forward-line (1- count)))
+ (recenter nil)))
+
+(evil-define-command evil-scroll-line-to-bottom (count)
+ "Scrolls line number COUNT (or the cursor line) to the bottom of the window."
+ :repeat nil
+ :keep-visual t
+ (interactive "<c>")
+ (evil-save-column
+ (let ((line (or count (line-number-at-pos (point)))))
+ (goto-char (point-min))
+ (forward-line (1- line)))
+ (recenter (- (max 1 scroll-margin)))))
+
+(evil-define-command evil-scroll-bottom-line-to-top (count)
+ "Scrolls the line right below the window,
+or line COUNT to the top of the window."
+ :repeat nil
+ :keep-visual t
+ (interactive "<c>")
+ (if count
+ (progn
+ (goto-char (point-min))
+ (forward-line (1- count)))
+ (goto-char (window-end))
+ (evil-move-cursor-back))
+ (recenter (1- (max 0 scroll-margin)))
+ (evil-first-non-blank))
+
+(evil-define-command evil-scroll-top-line-to-bottom (count)
+ "Scrolls the line right below the window,
+or line COUNT to the top of the window."
+ :repeat nil
+ :keep-visual t
+ (interactive "<c>")
+ (if count
+ (progn
+ (goto-char (point-min))
+ (forward-line (1- count)))
+ (goto-char (window-start)))
+ (recenter (- (max 1 scroll-margin)))
+ (evil-first-non-blank))
+
+(evil-define-command evil-scroll-left (count)
+ "Scrolls the window COUNT half-screenwidths to the left."
+ :repeat nil
+ :keep-visual t
+ (interactive "p")
+ (evil-with-hproject-point-on-window
+ (scroll-right (* count (/ (window-width) 2)))))
+
+(evil-define-command evil-scroll-right (count)
+ "Scrolls the window COUNT half-screenwidths to the right."
+ :repeat nil
+ :keep-visual t
+ (interactive "p")
+ (evil-with-hproject-point-on-window
+ (scroll-left (* count (/ (window-width) 2)))))
+
+(evil-define-command evil-scroll-column-left (count)
+ "Scrolls the window COUNT columns to the left."
+ :repeat nil
+ :keep-visual t
+ (interactive "p")
+ (evil-with-hproject-point-on-window
+ (scroll-right count)))
+
+(evil-define-command evil-scroll-column-right (count)
+ "Scrolls the window COUNT columns to the right."
+ :repeat nil
+ :keep-visual t
+ (interactive "p")
+ (evil-with-hproject-point-on-window
+ (scroll-left count)))
+
+;;; Text objects
+
+;; Text objects are defined with `evil-define-text-object'. In Visual
+;; state, they modify the current selection; in Operator-Pending
+;; state, they return a pair of buffer positions. Outer text objects
+;; are bound in the keymap `evil-outer-text-objects-map', and inner
+;; text objects are bound in `evil-inner-text-objects-map'.
+;;
+;; Common text objects like words, WORDS, paragraphs and sentences are
+;; defined via a corresponding move-function. This function must have
+;; the following properties:
+;;
+;; 1. Take exactly one argument, the count.
+;; 2. When the count is positive, move point forward to the first
+;; character after the end of the next count-th object.
+;; 3. When the count is negative, move point backward to the first
+;; character of the count-th previous object.
+;; 4. If point is placed on the first character of an object, the
+;; backward motion does NOT count that object.
+;; 5. If point is placed on the last character of an object, the
+;; forward motion DOES count that object.
+;; 6. The return value is "count left", i.e., in forward direction
+;; count is decreased by one for each successful move and in
+;; backward direction count is increased by one for each
+;; successful move, returning the final value of count.
+;; Therefore, if the complete move is successful, the return
+;; value is 0.
+;;
+;; A useful macro in this regard is `evil-motion-loop', which quits
+;; when point does not move further and returns the count difference.
+;; It also provides a "unit value" of 1 or -1 for use in each
+;; iteration. For example, a hypothetical "foo-bar" move could be
+;; written as such:
+;;
+;; (defun foo-bar (count)
+;; (evil-motion-loop (var count)
+;; (forward-foo var) ; `var' is 1 or -1 depending on COUNT
+;; (forward-bar var)))
+;;
+;; If "forward-foo" and "-bar" didn't accept negative arguments,
+;; we could choose their backward equivalents by inspecting `var':
+;;
+;; (defun foo-bar (count)
+;; (evil-motion-loop (var count)
+;; (cond
+;; ((< var 0)
+;; (backward-foo 1)
+;; (backward-bar 1))
+;; (t
+;; (forward-foo 1)
+;; (forward-bar 1)))))
+;;
+;; After a forward motion, point has to be placed on the first
+;; character after some object, unless no motion was possible at all.
+;; Similarly, after a backward motion, point has to be placed on the
+;; first character of some object. This implies that point should
+;; NEVER be moved to eob or bob, unless an object ends or begins at
+;; eob or bob. (Usually, Emacs motions always move as far as possible.
+;; But we want to use the motion-function to identify certain objects
+;; in the buffer, and thus exact movement to object boundaries is
+;; required.)
+
+(evil-define-text-object evil-a-word (count &optional beg end type)
+ "Select a word."
+ (evil-select-an-object 'evil-word beg end type count))
+
+(evil-define-text-object evil-inner-word (count &optional beg end type)
+ "Select inner word."
+ (evil-select-inner-object 'evil-word beg end type count))
+
+(evil-define-text-object evil-a-WORD (count &optional beg end type)
+ "Select a WORD."
+ (evil-select-an-object 'evil-WORD beg end type count))
+
+(evil-define-text-object evil-inner-WORD (count &optional beg end type)
+ "Select inner WORD."
+ (evil-select-inner-object 'evil-WORD beg end type count))
+
+(evil-define-text-object evil-a-symbol (count &optional beg end type)
+ "Select a symbol."
+ (evil-select-an-unrestricted-object 'evil-symbol beg end type count))
+
+(evil-define-text-object evil-inner-symbol (count &optional beg end type)
+ "Select inner symbol."
+ (evil-select-inner-unrestricted-object 'evil-symbol beg end type count))
+
+(evil-define-text-object evil-a-sentence (count &optional beg end type)
+ "Select a sentence."
+ (evil-select-an-unrestricted-object 'evil-sentence beg end type count))
+
+(evil-define-text-object evil-inner-sentence (count &optional beg end type)
+ "Select inner sentence."
+ (evil-select-inner-unrestricted-object 'evil-sentence beg end type count))
+
+(evil-define-text-object evil-a-paragraph (count &optional beg end type)
+ "Select a paragraph."
+ :type line
+ (evil-select-an-unrestricted-object 'evil-paragraph beg end type count t))
+
+(evil-define-text-object evil-inner-paragraph (count &optional beg end type)
+ "Select inner paragraph."
+ :type line
+ (evil-select-inner-unrestricted-object 'evil-paragraph beg end type count t))
+
+(evil-define-text-object evil-a-paren (count &optional beg end type)
+ "Select a parenthesis."
+ :extend-selection nil
+ (evil-select-paren ?\( ?\) beg end type count t))
+
+(evil-define-text-object evil-inner-paren (count &optional beg end type)
+ "Select inner parenthesis."
+ :extend-selection nil
+ (evil-select-paren ?\( ?\) beg end type count))
+
+(evil-define-text-object evil-a-bracket (count &optional beg end type)
+ "Select a square bracket."
+ :extend-selection nil
+ (evil-select-paren ?\[ ?\] beg end type count t))
+
+(evil-define-text-object evil-inner-bracket (count &optional beg end type)
+ "Select inner square bracket."
+ :extend-selection nil
+ (evil-select-paren ?\[ ?\] beg end type count))
+
+(evil-define-text-object evil-a-curly (count &optional beg end type)
+ "Select a curly bracket (\"brace\")."
+ :extend-selection nil
+ (evil-select-paren ?{ ?} beg end type count t))
+
+(evil-define-text-object evil-inner-curly (count &optional beg end type)
+ "Select inner curly bracket (\"brace\")."
+ :extend-selection nil
+ (evil-select-paren ?{ ?} beg end type count))
+
+(evil-define-text-object evil-an-angle (count &optional beg end type)
+ "Select an angle bracket."
+ :extend-selection nil
+ (evil-select-paren ?< ?> beg end type count t))
+
+(evil-define-text-object evil-inner-angle (count &optional beg end type)
+ "Select inner angle bracket."
+ :extend-selection nil
+ (evil-select-paren ?< ?> beg end type count))
+
+(evil-define-text-object evil-a-single-quote (count &optional beg end type)
+ "Select a single-quoted expression."
+ :extend-selection t
+ (evil-select-quote ?' beg end type count t))
+
+(evil-define-text-object evil-inner-single-quote (count &optional beg end type)
+ "Select inner single-quoted expression."
+ :extend-selection nil
+ (evil-select-quote ?' beg end type count))
+
+(evil-define-text-object evil-a-double-quote (count &optional beg end type)
+ "Select a double-quoted expression."
+ :extend-selection t
+ (evil-select-quote ?\" beg end type count t))
+
+(evil-define-text-object evil-inner-double-quote (count &optional beg end type)
+ "Select inner double-quoted expression."
+ :extend-selection nil
+ (evil-select-quote ?\" beg end type count))
+
+(evil-define-text-object evil-a-back-quote (count &optional beg end type)
+ "Select a back-quoted expression."
+ :extend-selection t
+ (evil-select-quote ?\` beg end type count t))
+
+(evil-define-text-object evil-inner-back-quote (count &optional beg end type)
+ "Select inner back-quoted expression."
+ :extend-selection nil
+ (evil-select-quote ?\` beg end type count))
+
+(evil-define-text-object evil-a-tag (count &optional beg end type)
+ "Select a tag block."
+ :extend-selection nil
+ (evil-select-xml-tag beg end type count t))
+
+(evil-define-text-object evil-inner-tag (count &optional beg end type)
+ "Select inner tag block."
+ :extend-selection nil
+ (evil-select-xml-tag beg end type count))
+
+(defun evil-match (direction count)
+ "Find COUNTth next match in DIRECTION."
+ (unless (and (boundp 'evil-search-module)
+ (eq evil-search-module 'evil-search))
+ (user-error "Match text objects only work with Evil search module"))
+ (let ((pnt (point))
+ (count (abs count)) ;; Undo effect of evil-visual-direction
+ (evil-ex-search-direction 'backward)
+ (visual-state (evil-visual-state-p))
+ on-start-match in-match on-end-match)
+ (save-excursion
+ (unless (eobp) (forward-char)) ;; If on start of a match, stay there
+ (evil-ex-search 1)
+ (setq on-start-match (= evil-ex-search-match-beg pnt)
+ in-match (<= evil-ex-search-match-beg pnt (1- evil-ex-search-match-end))
+ on-end-match (= (1- evil-ex-search-match-end) pnt)
+ evil-ex-search-direction direction)
+ (cond
+ ((and visual-state on-start-match (eq 'backward direction))
+ (evil-ex-search count))
+ ((and visual-state on-end-match (eq 'forward direction))
+ (evil-ex-search count))
+ ((or in-match (eq 'backward direction))
+ (evil-ex-search (1- count)))
+ (t (evil-ex-search count)))
+ (setq pnt (point)))
+ (goto-char pnt)
+ (cond
+ ((evil-normal-state-p)
+ (evil-visual-select evil-ex-search-match-beg
+ evil-ex-search-match-end
+ 'inclusive
+ (cl-case direction ('forward +1) ('backward -1))
+ t)
+ (list evil-ex-search-match-beg evil-ex-search-match-end))
+ ((and visual-state (eq 'forward direction))
+ (goto-char (1- evil-ex-search-match-end)))
+ ((and visual-state (eq 'backward direction))
+ (goto-char evil-ex-search-match-beg))
+ ;; e.g. operator pending...
+ (t (list evil-ex-search-match-beg evil-ex-search-match-end)))))
+
+(evil-define-text-object evil-next-match (count &optional beg end type)
+ "Select next match."
+ :extend-selection t
+ (evil-match 'forward count))
+
+(evil-define-text-object evil-previous-match (count &optional beg end type)
+ "Select previous match."
+ :extend-selection t
+ (evil-match 'backward count))
+
+;;; Operator commands
+
+(evil-define-operator evil-yank (beg end type register yank-handler)
+ "Saves the characters in motion into the kill-ring."
+ :move-point nil
+ :repeat nil
+ (interactive "<R><x><y>")
+ (let ((evil-was-yanked-without-register
+ (and evil-was-yanked-without-register (not register))))
+ (cond
+ ((and (fboundp 'cua--global-mark-active)
+ (fboundp 'cua-copy-region-to-global-mark)
+ (cua--global-mark-active))
+ (cua-copy-region-to-global-mark beg end))
+ ((eq type 'block)
+ (evil-yank-rectangle beg end register yank-handler))
+ ((memq type '(line screen-line))
+ (evil-yank-lines beg end register yank-handler))
+ (t
+ (evil-yank-characters beg end register yank-handler)))))
+
+(evil-define-operator evil-yank-line (beg end type register)
+ "Saves whole lines into the kill-ring."
+ :motion evil-line-or-visual-line
+ :move-point nil
+ (interactive "<R><x>")
+ (when (evil-visual-state-p)
+ (unless (memq type '(line block screen-line))
+ (let ((range (evil-expand beg end
+ (if (and evil-respect-visual-line-mode
+ visual-line-mode)
+ 'screen-line
+ 'line))))
+ (setq beg (evil-range-beginning range)
+ end (evil-range-end range)
+ type (evil-type range))))
+ (evil-exit-visual-state))
+ (evil-yank beg end type register))
+
+(evil-define-operator evil-delete (beg end type register yank-handler)
+ "Delete text from BEG to END with TYPE.
+Save in REGISTER or in the kill-ring with YANK-HANDLER."
+ (interactive "<R><x><y>")
+ (if (and (memq type '(inclusive exclusive))
+ (not (evil-visual-state-p))
+ (eq 'evil-delete evil-this-operator)
+ (save-excursion (goto-char beg) (bolp))
+ (save-excursion (goto-char end) (eolp))
+ (<= 1 (evil-count-lines beg end)))
+ ;; Imitate Vi strangeness: if motion meets above criteria,
+ ;; delete linewise. Not for change operator or visual state.
+ (let ((new-range (evil-expand beg end 'line)))
+ (evil-delete (nth 0 new-range) (nth 1 new-range) 'line register yank-handler))
+ (unless register
+ (let ((text (filter-buffer-substring beg end)))
+ (unless (string-match-p "\n" text)
+ ;; set the small delete register
+ (evil-set-register ?- text))))
+ (let ((evil-was-yanked-without-register nil))
+ (evil-yank beg end type register yank-handler))
+ (cond
+ ((eq type 'block)
+ (evil-apply-on-block #'delete-region beg end nil))
+ ((and (eq type 'line)
+ (= end (point-max))
+ (or (= beg end)
+ (/= (char-before end) ?\n))
+ (/= beg (point-min))
+ (= (char-before beg) ?\n))
+ (delete-region (1- beg) end))
+ (t
+ (delete-region beg end)))
+ (when (and (called-interactively-p 'any)
+ (eq type 'line))
+ (evil-first-non-blank)
+ (when (and (not evil-start-of-line)
+ evil-operator-start-col
+ ;; Special exceptions to ever saving column:
+ (not (memq evil-this-motion '(evil-forward-word-begin
+ evil-forward-WORD-begin))))
+ (move-to-column evil-operator-start-col)))))
+
+(evil-define-operator evil-delete-line (beg end type register yank-handler)
+ "Delete to end of line."
+ :motion nil
+ :keep-visual t
+ (interactive "<R><x>")
+ ;; act linewise in Visual state
+ (let* ((beg (or beg (point)))
+ (end (or end beg))
+ (visual-line-mode (and evil-respect-visual-line-mode
+ visual-line-mode))
+ (line-end (if visual-line-mode
+ (save-excursion
+ (end-of-visual-line)
+ (point))
+ (line-end-position))))
+ (when (evil-visual-state-p)
+ (unless (memq type '(line screen-line block))
+ (let ((range (evil-expand beg end
+ (if visual-line-mode
+ 'screen-line
+ 'line))))
+ (setq beg (evil-range-beginning range)
+ end (evil-range-end range)
+ type (evil-type range))))
+ (evil-exit-visual-state))
+ (cond
+ ((eq type 'block)
+ ;; equivalent to $d, i.e., we use the block-to-eol selection and
+ ;; call `evil-delete'. In this case we fake the call to
+ ;; `evil-end-of-line' by setting `temporary-goal-column' and
+ ;; `last-command' appropriately as `evil-end-of-line' would do.
+ (let ((temporary-goal-column most-positive-fixnum)
+ (last-command 'next-line))
+ (evil-delete beg end 'block register yank-handler)))
+ ((memq type '(line screen-line))
+ (evil-delete beg end type register yank-handler))
+ (t
+ (evil-delete beg line-end type register yank-handler)))))
+
+(evil-define-operator evil-delete-whole-line
+ (beg end type register yank-handler)
+ "Delete whole line."
+ :motion evil-line-or-visual-line
+ (interactive "<R><x>")
+ (evil-delete beg end type register yank-handler))
+
+(evil-define-operator evil-delete-char (beg end type register)
+ "Delete next character."
+ :motion evil-forward-char
+ (interactive "<R><x>")
+ (evil-delete beg end type register))
+
+(evil-define-operator evil-delete-backward-char (beg end type register)
+ "Delete previous character."
+ :motion evil-backward-char
+ (interactive "<R><x>")
+ (evil-delete beg end type register))
+
+(evil-define-command evil-delete-backward-char-and-join (count)
+ "Delete previous character and join lines.
+If point is at the beginning of a line then the current line will
+be joined with the previous line if and only if
+`evil-backspace-join-lines'."
+ (interactive "p")
+ (if (or evil-backspace-join-lines (not (bolp)))
+ (call-interactively 'delete-backward-char)
+ (user-error "Beginning of line")))
+
+(evil-define-command evil-delete-backward-word ()
+ "Delete previous word."
+ (let ((beg (save-excursion (evil-backward-word-begin) (point)))
+ (end (point)))
+ (cond
+ ((evil-replace-state-p) (while (< beg (point))
+ (evil-replace-backspace)))
+ ((or (not (bolp)) (bobp)) (delete-region (max beg (line-beginning-position))
+ end))
+ (evil-backspace-join-lines (delete-char -1))
+ (t (user-error "Beginning of line")))))
+
+(evil-define-command evil-delete-back-to-indentation ()
+ "Delete back to the first non-whitespace character.
+If point is before the first non-whitespace character of a
+current line then delete from the point to the beginning of the
+current line. If point is on the beginning of the line, behave
+according to `evil-backspace-join-lines'."
+ (let ((beg (if (<= (current-column) (current-indentation))
+ (line-beginning-position)
+ (save-excursion
+ (evil-first-non-blank)
+ (point)))))
+ (cond
+ ((and (bolp) (evil-replace-state-p)) (evil-replace-backspace))
+ ((bolp) (evil-delete-backward-char-and-join 1))
+ ((evil-replace-state-p) (while (< beg (point))
+ (evil-replace-backspace)))
+ (t (delete-region beg (point))))))
+
+(defun evil-ex-delete-or-yank (should-delete beg end type register count yank-handler)
+ "Execute evil-delete or evil-yank on the given region.
+If SHOULD-DELETE is t, evil-delete will be executed, otherwise
+evil-yank.
+The region specified by BEG and END will be adjusted if COUNT is
+given."
+ (when count
+ ;; with COUNT, the command should go the end of the region and delete/yank
+ ;; COUNT lines from there
+ (setq beg (save-excursion
+ (goto-char end)
+ (forward-line -1)
+ (point))
+ end (save-excursion
+ (goto-char end)
+ (point-at-bol count))
+ type 'line))
+ (funcall (if should-delete 'evil-delete 'evil-yank) beg end type register yank-handler))
+
+(evil-define-operator evil-ex-delete (beg end type register count yank-handler)
+ "The Ex delete command.
+\[BEG,END]delete [REGISTER] [COUNT]"
+ (interactive "<R><xc/><y>")
+ (evil-ex-delete-or-yank t beg end type register count yank-handler))
+
+(evil-define-operator evil-ex-yank (beg end type register count yank-handler)
+ "The Ex yank command.
+\[BEG,END]yank [REGISTER] [COUNT]"
+ :restore-point t
+ (interactive "<R><xc/><y>")
+ (evil-ex-delete-or-yank nil beg end type register count yank-handler))
+
+(evil-define-command evil-ex-put (beg end ex-arg &optional force)
+ (interactive "<r><a><!>")
+ (let* ((arg-chars (remove ?\s (string-to-list ex-arg)))
+ (reg (or (car arg-chars) ?\"))
+ (text (cond
+ ((and (< 1 (length arg-chars))
+ (/= ?= reg))
+ (user-error "Trailing characters"))
+ ((eq ?= reg)
+ (evil--eval-expr (if (= 1 (length arg-chars))
+ evil-last-=-register-input
+ (setq evil-last-=-register-input (substring ex-arg 1)))))
+ (t (evil-get-register reg)))))
+ (unless text (user-error "Nothing in register %c" reg))
+ (evil-remove-yank-excluded-properties text)
+ (goto-char (if (= (point-max) end) end (1- end)))
+ (if force (evil-insert-newline-above) (evil-insert-newline-below))
+ (evil-set-marker ?\[ (point))
+ ;; `insert' rather than `insert-for-yank' as we want to ignore yank-handlers...
+ (insert (if (and (< 0 (length text))
+ (eq ?\n (aref text (1- (length text)))))
+ (substring text 0 (1- (length text)))
+ text))
+ (evil-set-marker ?\] (1- (point)))
+ (back-to-indentation)
+ (evil-normal-state)))
+
+(evil-define-operator evil-change
+ (beg end type register yank-handler delete-func)
+ "Change text from BEG to END with TYPE.
+Save in REGISTER or the kill-ring with YANK-HANDLER.
+DELETE-FUNC is a function for deleting text, default `evil-delete'.
+If TYPE is `line', insertion starts on an empty line.
+If TYPE is `block', the inserted text in inserted at each line
+of the block."
+ (interactive "<R><x><y>")
+ (let ((delete-func (or delete-func #'evil-delete))
+ (nlines (1+ (evil-count-lines beg end)))
+ (opoint (save-excursion
+ (goto-char beg)
+ (line-beginning-position))))
+ (unless (eq evil-want-fine-undo t)
+ (evil-start-undo-step))
+ (funcall delete-func beg end type register yank-handler)
+ (cond
+ ((eq type 'line)
+ (setq this-command 'evil-change-whole-line) ; for evil-maybe-remove-spaces
+ (if (= opoint (point))
+ (evil-open-above 1)
+ (evil-open-below 1)))
+ ((eq type 'block)
+ (evil-insert 1 nlines))
+ (t
+ (evil-insert 1)))
+ (setq evil-this-register nil)))
+
+(evil-define-operator evil-change-line (beg end type register yank-handler)
+ "Change to end of line, or change whole line if characterwise visual mode."
+ :motion evil-end-of-line-or-visual-line
+ (interactive "<R><x><y>")
+ (if (and (evil-visual-state-p) (eq 'inclusive type))
+ (cl-destructuring-bind (beg* end* &rest) (evil-line-expand beg end)
+ (evil-change-whole-line beg* end* register yank-handler))
+ (evil-change beg end type register yank-handler #'evil-delete-line)))
+
+(evil-define-operator evil-change-whole-line
+ (beg end register yank-handler)
+ "Change whole line."
+ :motion evil-line-or-visual-line
+ :type line
+ (interactive "<r><x>")
+ (evil-change beg end 'line register yank-handler #'evil-delete-whole-line))
+
+(evil-define-command evil-copy (beg end address)
+ "Copy lines in BEG END below line given by ADDRESS."
+ :motion evil-line-or-visual-line
+ (interactive "<r><addr>")
+ (goto-char (point-min))
+ (forward-line address)
+ (let* ((txt (buffer-substring-no-properties beg end))
+ (len (length txt)))
+ ;; ensure text consists of complete lines
+ (when (or (zerop len) (/= (aref txt (1- len)) ?\n))
+ (setq txt (concat txt "\n")))
+ (when (and (eobp) (not (bolp))) (newline)) ; incomplete last line
+ (insert txt)
+ (forward-line -1)))
+
+(evil-define-command evil-move (beg end address)
+ "Move lines in BEG END below line given by ADDRESS."
+ :motion evil-line-or-visual-line
+ (interactive "<r><addr>")
+ (unless (= (1+ address) (line-number-at-pos beg))
+ (goto-char (point-min))
+ (forward-line address)
+ (let* ((m (set-marker (make-marker) (point)))
+ (txt (buffer-substring-no-properties beg end))
+ (len (length txt))
+ (last-line-blank (progn (goto-char (point-max)) (bolp))))
+ (delete-region beg end)
+ (unless last-line-blank ; as vim, preserve lack of blank last line
+ (progn (goto-char (point-max)) (when (bolp) (delete-char -1))))
+ (goto-char m)
+ (set-marker m nil)
+ ;; ensure text consists of complete lines
+ (when (or (zerop len) (/= (aref txt (1- len)) ?\n))
+ (setq txt (concat txt "\n")))
+ (when (and (eobp) (not (bolp))) (newline)) ; incomplete last line
+ (when (evil-visual-state-p)
+ (move-marker evil-visual-mark (point)))
+ (insert txt)
+ (forward-line -1)
+ (when (evil-visual-state-p)
+ (move-marker evil-visual-point (point))))))
+
+(defun evil--check-undo-system ()
+ (when (and (eq evil-undo-system 'undo-tree)
+ (not (bound-and-true-p undo-tree-mode)))
+ (user-error "Enable `global-undo-tree-mode' to use undo-tree commands.
+Add (add-hook 'evil-local-mode-hook 'turn-on-undo-tree-mode) to your init file for undo in non-file buffers.")))
+
+(evil-define-command evil-undo (count)
+ "Undo COUNT changes in buffer using `evil-undo-function'."
+ :repeat abort
+ (interactive "*p")
+ (evil--check-undo-system)
+ (funcall evil-undo-function count))
+
+(evil-define-command evil-redo (count)
+ "Undo COUNT changes in buffer using `evil-redo-function'."
+ :repeat abort
+ (interactive "*p")
+ (evil--check-undo-system)
+ (funcall evil-redo-function count))
+
+(evil-define-operator evil-substitute (beg end type register)
+ "Change a character."
+ :motion evil-forward-char
+ (interactive "<R><x>")
+ (evil-change beg end type register))
+
+(evil-define-operator evil-upcase (beg end type)
+ "Convert text to upper case."
+ (if (eq type 'block)
+ (evil-apply-on-block #'evil-upcase beg end nil)
+ (upcase-region beg end)))
+
+(evil-define-operator evil-downcase (beg end type)
+ "Convert text to lower case."
+ (if (eq type 'block)
+ (evil-apply-on-block #'evil-downcase beg end nil)
+ (downcase-region beg end)))
+
+(evil-define-operator evil-invert-case (beg end type)
+ "Invert case of text."
+ (let (char)
+ (if (eq type 'block)
+ (evil-apply-on-block #'evil-invert-case beg end nil)
+ (save-excursion
+ (goto-char beg)
+ (while (< beg end)
+ (setq char (following-char))
+ (delete-char 1 nil)
+ (if (eq (upcase char) char)
+ (insert-char (downcase char) 1)
+ (insert-char (upcase char) 1))
+ (setq beg (1+ beg)))))))
+
+(evil-define-operator evil-invert-char (beg end type)
+ "Invert case of character."
+ :motion evil-forward-char
+ (if (eq type 'block)
+ (evil-apply-on-block #'evil-invert-case beg end nil)
+ (evil-invert-case beg end)
+ (when evil-this-motion
+ (goto-char end)
+ (when (and evil-cross-lines
+ (not evil-move-beyond-eol)
+ (not (evil-visual-state-p))
+ (not (evil-operator-state-p))
+ (eolp) (not (eobp)) (not (bolp)))
+ (forward-char)))))
+
+(evil-define-operator evil-rot13 (beg end type)
+ "ROT13 encrypt text."
+ (if (eq type 'block)
+ (evil-apply-on-block #'evil-rot13 beg end nil)
+ (rot13-region beg end)))
+
+(evil-define-operator evil-join (beg end)
+ "Join the selected lines."
+ :motion evil-line
+ (let ((count (count-lines beg end)))
+ (when (> count 1)
+ (setq count (1- count)))
+ (goto-char beg)
+ (dotimes (_ count)
+ (join-line 1))))
+
+(evil-define-operator evil-join-whitespace (beg end)
+ "Join the selected lines without changing whitespace.
+\\<evil-normal-state-map>Like \\[evil-join], \
+but doesn't insert or remove any spaces."
+ :motion evil-line
+ (let ((count (count-lines beg end)))
+ (when (> count 1)
+ (setq count (1- count)))
+ (goto-char beg)
+ (dotimes (_ count)
+ (evil-move-end-of-line 1)
+ (unless (eobp)
+ (delete-char 1)))))
+
+(evil-define-operator evil-ex-join (beg end &optional count bang)
+ "Join the selected lines with optional COUNT and BANG."
+ (interactive "<r><a><!>")
+ (if (and count (not (string-match-p "^[1-9][0-9]*$" count)))
+ (user-error "Invalid count")
+ (let ((join-fn (if bang 'evil-join-whitespace 'evil-join)))
+ (cond
+ ((not count)
+ ;; without count - just join the given region
+ (funcall join-fn beg end))
+ (t
+ ;; emulate vim's :join when count is given - start from the
+ ;; end of the region and join COUNT lines from there
+ (let* ((count-num (string-to-number count))
+ (beg-adjusted (save-excursion
+ (goto-char end)
+ (forward-line -1)
+ (point)))
+ (end-adjusted (save-excursion
+ (goto-char end)
+ (point-at-bol count-num))))
+ (funcall join-fn beg-adjusted end-adjusted)))))))
+
+(evil-define-operator evil-fill (beg end)
+ "Fill text."
+ :move-point nil
+ :type line
+ (save-excursion
+ (condition-case nil
+ (fill-region beg end)
+ (error nil))))
+
+(evil-define-operator evil-fill-and-move (beg end)
+ "Fill text and move point to the end of the filled region."
+ :move-point nil
+ :type line
+ (let ((marker (make-marker)))
+ (move-marker marker (1- end))
+ (condition-case nil
+ (progn
+ (fill-region beg end)
+ (goto-char marker)
+ (evil-first-non-blank))
+ (error nil))))
+
+(evil-define-operator evil-indent (beg end)
+ "Indent text."
+ :move-point nil
+ :type line
+ (save-restriction
+ (narrow-to-region beg end)
+ (if (and (= beg (line-beginning-position))
+ (= end (line-beginning-position 2)))
+ ;; since some Emacs modes can only indent one line at a time,
+ ;; implement "==" as a call to `indent-according-to-mode'
+ (indent-according-to-mode)
+ (goto-char beg)
+ (indent-region beg end))
+ ;; Update `beg' and `end'
+ (setq beg (point-min)
+ end (point-max))
+ ;; We also need to tabify or untabify the leading white characters
+ (when evil-indent-convert-tabs
+ (let* ((beg-line (line-number-at-pos beg))
+ (end-line (line-number-at-pos end))
+ (ln beg-line)
+ (convert-white (if indent-tabs-mode 'tabify 'untabify)))
+ (save-excursion
+ (while (<= ln end-line)
+ (goto-char (point-min))
+ (forward-line (- ln 1))
+ (back-to-indentation)
+ ;; Whether tab or space should be used is determined by indent-tabs-mode
+ (funcall convert-white (line-beginning-position) (point))
+ (setq ln (1+ ln)))))
+ (back-to-indentation))))
+
+(evil-define-operator evil-indent-line (beg end)
+ "Indent the line."
+ :motion evil-line
+ (evil-indent beg end))
+
+(evil-define-operator evil-shift-left (beg end &optional count preserve-empty)
+ "Shift text from BEG to END to the left.
+The text is shifted to the nearest multiple of `evil-shift-width'
+\(the rounding can be disabled by setting `evil-shift-round').
+If PRESERVE-EMPTY is non-nil, lines that contain only spaces are
+indented, too, otherwise they are ignored. Location of point
+is preserved relative to text when called from insert state.
+Otherwise, it is determined by `evil-start-of-line' and/or `evil-track-eol'.
+See also `evil-shift-right'."
+ :type line
+ (interactive "<r><vc>")
+ (evil-shift-right beg end (- (or count 1)) preserve-empty))
+
+(evil-define-operator evil-shift-right (beg end &optional count preserve-empty)
+ "Shift text from BEG to END to the right.
+The text is shifted to the nearest multiple of `evil-shift-width'
+\(the rounding can be disabled by setting `evil-shift-round').
+If PRESERVE-EMPTY is non-nil, lines that contain only spaces are
+indented, too, otherwise they are ignored. Location of point
+is preserved relative to text when called from insert or replace states.
+Otherwise, it is determined by `evil-start-of-line' and/or `evil-track-eol'.
+See also `evil-shift-left'."
+ :type line
+ :move-point nil ; point is moved according to `evil-start-of-line' and state
+ (interactive "<r><vc>")
+ (setq count (or count 1))
+ (let ((beg (set-marker (make-marker) beg))
+ (end (set-marker (make-marker) end))
+ (col-for-insert (current-column))
+ first-shift) ; shift of first line
+ (save-excursion
+ (goto-char beg)
+ (while (< (point) end)
+ (let* ((indent (current-indentation))
+ (new-indent
+ (max 0
+ (if (not evil-shift-round)
+ (+ indent (* count evil-shift-width))
+ (* (+ (/ indent evil-shift-width)
+ count
+ (cond
+ ((> count 0) 0)
+ ((zerop (mod indent evil-shift-width)) 0)
+ (t 1)))
+ evil-shift-width)))))
+ (unless first-shift
+ (setq first-shift (- new-indent indent)))
+ (when (or preserve-empty
+ (save-excursion
+ (skip-chars-forward " \t")
+ (not (eolp))))
+ (indent-to new-indent 0))
+ (delete-region (point) (progn (skip-chars-forward " \t") (point)))
+ (forward-line 1))))
+ ;; in case we're in an empty buffer first-shift is still unchanged
+ (unless first-shift
+ (if (< count 0)
+ (setq first-shift 0)
+ (setq first-shift (* count evil-shift-width))
+ (indent-to first-shift)))
+ ;; When called from insert state (C-t or C-d) the cursor should shift with the line,
+ ;; otherwise (normal state) its position is determined by `evil-start-of-line'.
+ (cond
+ ((or (evil-insert-state-p) (evil-replace-state-p))
+ (move-to-column (max 0 (+ col-for-insert first-shift))))
+ (evil-start-of-line (evil-first-non-blank))
+ ((evil--stick-to-eol-p) (move-end-of-line 1))
+ (t (move-to-column (or goal-column evil-operator-start-col col-for-insert))))
+ (setq temporary-goal-column 0)))
+
+(defun evil-delete-indentation ()
+ "Delete all indentation on current line."
+ (interactive)
+ (save-excursion
+ (evil-beginning-of-line)
+ (delete-region (point) (progn (skip-chars-forward " \t") (point)))))
+
+(evil-define-command evil-shift-right-line (count)
+ "Shift the current line COUNT times to the right.
+The text is shifted to the nearest multiple of
+`evil-shift-width'. Like `evil-shift-right' but always works on
+the current line."
+ (interactive "<c>")
+ (evil-shift-right (line-beginning-position) (line-beginning-position 2) count t))
+
+(evil-define-command evil-shift-left-line (count)
+ "Shift the current line COUNT times to the left.
+The text is shifted to the nearest multiple of
+`evil-shift-width'. Like `evil-shift-left' but always works on
+the current line."
+ (interactive "<c>")
+ (if (and (eq 'self-insert-command last-command)
+ (eq ?0 (char-before)))
+ (progn (backward-delete-char 1)
+ (evil-delete-indentation))
+ (evil-shift-left (line-beginning-position) (line-beginning-position 2) count t)))
+
+(evil-define-operator evil-align-left (beg end type &optional width)
+ "Left-align lines in the region at WIDTH columns.
+The default for width is the value of `fill-column'."
+ :motion evil-line
+ :type line
+ (interactive "<R><a>")
+ (evil-justify-lines beg end 'left (if width
+ (string-to-number width)
+ 0)))
+
+(evil-define-operator evil-align-right (beg end type &optional width)
+ "Right-align lines in the region at WIDTH columns.
+The default for width is the value of `fill-column'."
+ :motion evil-line
+ :type line
+ (interactive "<R><a>")
+ (evil-justify-lines beg end 'right (if width
+ (string-to-number width)
+ fill-column)))
+
+(evil-define-operator evil-align-center (beg end type &optional width)
+ "Centers lines in the region between WIDTH columns.
+The default for width is the value of `fill-column'."
+ :motion evil-line
+ :type line
+ (interactive "<R><a>")
+ (evil-justify-lines beg end 'center (if width
+ (string-to-number width)
+ fill-column)))
+
+(evil-define-operator evil-replace (beg end type char)
+ "Replace text from BEG to END with CHAR."
+ :motion evil-forward-char
+ (interactive "<R>"
+ (unwind-protect
+ (let ((evil-force-cursor 'replace))
+ (evil-refresh-cursor)
+ (list (evil-read-key)))
+ (evil-refresh-cursor)))
+ (when char
+ (if (eq type 'block)
+ (save-excursion
+ (evil-apply-on-rectangle
+ #'(lambda (begcol endcol char)
+ (let ((maxcol (evil-column (line-end-position))))
+ (when (< begcol maxcol)
+ (setq endcol (min endcol maxcol))
+ (let ((beg (evil-move-to-column begcol nil t))
+ (end (evil-move-to-column endcol nil t)))
+ (delete-region beg end)
+ (insert (make-string (- endcol begcol) char))))))
+ beg end char))
+ (goto-char beg)
+ (cond
+ ((eq char ?\n)
+ (delete-region beg end)
+ (newline)
+ (when evil-auto-indent
+ (indent-according-to-mode)))
+ (t
+ (while (< (point) end)
+ (if (eq (char-after) ?\n)
+ (forward-char)
+ (delete-char 1)
+ (insert-char char 1)))
+ (goto-char (max beg (1- end))))))))
+
+(evil-define-command evil-paste-before
+ (count &optional register yank-handler)
+ "Pastes the latest yanked text before the cursor position.
+The return value is the yanked text."
+ :suppress-operator t
+ (interactive "*P<x>")
+ (setq count (prefix-numeric-value count))
+ (if (evil-visual-state-p)
+ (evil-visual-paste count register)
+ (evil-with-undo
+ (let* ((text (if register
+ (evil-get-register register)
+ (current-kill 0)))
+ (yank-handler (or yank-handler
+ (when (stringp text)
+ (car-safe (get-text-property
+ 0 'yank-handler text)))))
+ (opoint (point)))
+ (when evil-paste-clear-minibuffer-first
+ (delete-minibuffer-contents)
+ (setq evil-paste-clear-minibuffer-first nil))
+ (when text
+ (if (functionp yank-handler)
+ (let ((evil-paste-count count)
+ ;; for non-interactive use
+ (this-command #'evil-paste-before))
+ (push-mark opoint t)
+ (insert-for-yank text))
+ ;; no yank-handler, default
+ (when (vectorp text)
+ (setq text (evil-vector-to-string text)))
+ (set-text-properties 0 (length text) nil text)
+ (push-mark opoint t)
+ (dotimes (_ (or count 1))
+ (insert-for-yank text))
+ (setq evil-last-paste
+ (list #'evil-paste-before
+ count
+ opoint
+ opoint ; beg
+ (point))) ; end
+ (evil-set-marker ?\[ opoint)
+ (evil-set-marker ?\] (1- (point)))
+ (when (and evil-move-cursor-back
+ (> (length text) 0))
+ (backward-char))))
+ ;; no paste-pop after pasting from a register
+ (when register
+ (setq evil-last-paste nil))
+ (and (> (length text) 0) text)))))
+
+(evil-define-command evil-paste-after
+ (count &optional register yank-handler)
+ "Pastes the latest yanked text behind point.
+The return value is the yanked text."
+ :suppress-operator t
+ (interactive "*P<x>")
+ (setq count (prefix-numeric-value count))
+ (if (evil-visual-state-p)
+ (evil-visual-paste count register)
+ (evil-with-undo
+ (let* ((text (if register
+ (evil-get-register register)
+ (current-kill 0)))
+ (yank-handler (or yank-handler
+ (when (stringp text)
+ (car-safe (get-text-property
+ 0 'yank-handler text)))))
+ (opoint (point)))
+ (when text
+ (if (functionp yank-handler)
+ (let ((evil-paste-count count)
+ ;; for non-interactive use
+ (this-command #'evil-paste-after))
+ (insert-for-yank text))
+ ;; no yank-handler, default
+ (when (vectorp text)
+ (setq text (evil-vector-to-string text)))
+ (set-text-properties 0 (length text) nil text)
+ (unless (eolp) (forward-char))
+ (push-mark (point) t)
+ ;; TODO: Perhaps it is better to collect a list of all
+ ;; (point . mark) pairs to undo the yanking for COUNT > 1.
+ ;; The reason is that this yanking could very well use
+ ;; `yank-handler'.
+ (let ((beg (point)))
+ (dotimes (_ (or count 1))
+ (insert-for-yank text))
+ (setq evil-last-paste
+ (list #'evil-paste-after
+ count
+ opoint
+ beg ; beg
+ (point))) ; end
+ (evil-set-marker ?\[ beg)
+ (evil-set-marker ?\] (1- (point)))
+ (when (evil-normal-state-p)
+ (evil-move-cursor-back)))))
+ (when register
+ (setq evil-last-paste nil))
+ (and (> (length text) 0) text)))))
+
+(defun evil-insert-for-yank-at-col (startcol _endcol string count)
+ "Insert STRING at STARTCOL."
+ (move-to-column startcol)
+ (dotimes (_ (or count 1))
+ (insert-for-yank string))
+ (evil-set-marker ?\] (1- (point))))
+
+(evil-define-command evil-visual-paste (count &optional register)
+ "Paste over Visual selection."
+ :suppress-operator t
+ (interactive "*P<x>")
+ (setq count (prefix-numeric-value count))
+ ;; evil-visual-paste is typically called from evil-paste-before or
+ ;; evil-paste-after, but we have to mark that the paste was from
+ ;; visual state
+ (setq this-command 'evil-visual-paste)
+ (let* ((text (if register
+ (evil-get-register register)
+ (current-kill 0)))
+ (yank-handler (car-safe (get-text-property
+ 0 'yank-handler text)))
+ (dir (evil-visual-direction))
+ beg end paste-eob)
+ (evil-with-undo
+ (let ((kill-ring-yank-pointer (when kill-ring (list (current-kill 0)))))
+ (when (evil-visual-state-p)
+ (setq beg evil-visual-beginning
+ end evil-visual-end)
+ (evil-visual-rotate 'upper-left)
+ ;; if we replace the last buffer line that does not end in a
+ ;; newline, we use `evil-paste-after' because `evil-delete'
+ ;; will move point to the line above
+ (when (and (= evil-visual-end (point-max))
+ (/= (char-before (point-max)) ?\n))
+ (setq paste-eob t))
+ (evil-delete beg end (evil-visual-type) (unless evil-kill-on-visual-paste ?_))
+ (when (and (eq yank-handler #'evil-yank-line-handler)
+ (not (memq (evil-visual-type) '(line block)))
+ (not (= evil-visual-end (point-max))))
+ (insert "\n"))
+ (evil-normal-state)
+ (when kill-ring (current-kill 1)))
+ ;; Effectively memoize `evil-get-register' because it can be
+ ;; side-effecting (e.g. for the `=' register)...
+ (cl-letf (((symbol-function 'evil-get-register)
+ (lambda (&rest _) text)))
+ (cond
+ ((eq 'block (evil-visual-type))
+ (when (eq yank-handler #'evil-yank-line-handler)
+ (setq text (concat "\n" text)))
+ (evil-set-marker ?\[ beg)
+ (evil-apply-on-block #'evil-insert-for-yank-at-col beg end t text count))
+ (paste-eob (evil-paste-after count register))
+ (t (evil-paste-before count register)))))
+ (when evil-kill-on-visual-paste
+ (current-kill -1))
+ ;; Ensure that gv can restore visually pasted area...
+ (setq evil-visual-previous-mark evil-visual-mark
+ evil-visual-mark (evil-get-marker (if (<= 0 dir) ?\[ ?\]) t)
+ evil-visual-previous-point evil-visual-point
+ evil-visual-point (evil-get-marker (if (<= 0 dir) ?\] ?\[) t))
+ ;; mark the last paste as visual-paste
+ (setq evil-last-paste
+ (list (nth 0 evil-last-paste)
+ (nth 1 evil-last-paste)
+ (nth 2 evil-last-paste)
+ (nth 3 evil-last-paste)
+ (nth 4 evil-last-paste)
+ t)))))
+
+(defun evil-paste-from-register (register)
+ "Paste from REGISTER."
+ (interactive
+ (let* ((opoint (point))
+ (overlay (make-overlay opoint (+ opoint (if (evil-replace-state-p) 1 0)))))
+ (unwind-protect
+ (progn
+ (overlay-put overlay 'invisible t)
+ (overlay-put overlay 'after-string (propertize "\""
+ 'face 'minibuffer-prompt
+ 'cursor 1))
+ (list (or evil-this-register (read-char))))
+ (delete-overlay overlay))))
+ (let ((opoint (point))
+ (evil-move-cursor-back nil)
+ reg-length chars-to-delete)
+ (evil-paste-before nil register t)
+ (when (evil-replace-state-p)
+ (setq reg-length (- (point) opoint)
+ chars-to-delete (min (- (point-at-eol) (point)) reg-length))
+ ;; TODO: handle multi-line paste backspacing
+ (evil-update-replace-alist (point) reg-length chars-to-delete chars-to-delete)
+ (delete-char chars-to-delete))))
+
+(defun evil-paste-last-insertion ()
+ "Paste last insertion."
+ (interactive)
+ (evil-paste-from-register ?.))
+
+(defun evil-paste-last-insertion-and-stop-insert ()
+ "Paste last insertion and change to normal state."
+ (interactive)
+ (evil-paste-last-insertion)
+ (evil-normal-state))
+
+(evil-define-command evil-use-register (register)
+ "Use REGISTER for the next command."
+ :keep-visual t
+ :repeat ignore
+ (interactive "<C>")
+ (setq evil-this-register register))
+
+(defvar evil-macro-buffer nil
+ "The buffer that has been active on macro recording.")
+
+(defun evil-end-and-return-macro ()
+ "Like `kmacro-end-macro' but also return the macro.
+Remove \\<evil-insert-state-map>\\[evil-execute-in-normal-state] from the end."
+ ;; `end-kbd-macro' rather than `kmacro-end-macro' to allow clearing registers
+ (end-kbd-macro nil #'kmacro-loop-setup-function)
+ (let ((end-keys-seq (append evil-execute-normal-keys nil))
+ (last-kbd-macro-seq (append last-kbd-macro nil)))
+ (unless last-kbd-macro-seq
+ (setq last-kbd-macro nil))
+ (if (and end-keys-seq last-kbd-macro-seq)
+ (apply #'vector (butlast last-kbd-macro-seq (length end-keys-seq)))
+ last-kbd-macro)))
+
+(evil-define-command evil-record-macro (register)
+ "Record a keyboard macro into REGISTER.
+If REGISTER is :, /, or ?, the corresponding command line window
+will be opened instead."
+ :keep-visual t
+ :suppress-operator t
+ (interactive
+ (list (unless (and evil-this-macro defining-kbd-macro)
+ (or evil-this-register (evil-read-key)))))
+ (let (last-macro)
+ (cond
+ ((eq register ?\C-g)
+ (keyboard-quit))
+ ((and evil-this-macro defining-kbd-macro)
+ (setq evil-macro-buffer nil)
+ (condition-case nil
+ (setq last-macro (evil-end-and-return-macro))
+ (error nil))
+ (when last-macro
+ (evil-set-register evil-this-macro last-macro))
+ (setq evil-this-macro nil))
+ ((eq register ?:)
+ (evil-command-window-ex))
+ ((eq register ?/)
+ (evil-command-window-search-forward))
+ ((eq register ??)
+ (evil-command-window-search-backward))
+ ((or (<= ?0 register ?9)
+ (<= ?a register ?z)
+ (<= ?A register ?Z))
+ (when defining-kbd-macro (end-kbd-macro))
+ (setq evil-this-macro register)
+ (evil-set-register evil-this-macro nil)
+ (kmacro-start-macro nil)
+ (setq evil-macro-buffer (current-buffer)))
+ (t (error "Invalid register")))))
+
+(evil-define-command evil-execute-macro (count macro)
+ "Execute keyboard macro MACRO, COUNT times.
+When called with a non-numerical prefix \
+\(such as \\[universal-argument]),
+COUNT is infinite. MACRO is read from a register
+when called interactively."
+ :keep-visual t
+ :suppress-operator t
+ (interactive
+ (let (count macro register)
+ (setq count (if current-prefix-arg
+ (if (numberp current-prefix-arg)
+ current-prefix-arg
+ 0) 1)
+ register (or evil-this-register (read-char)))
+ (cond
+ ((or (and (eq register ?@) (eq evil-last-register ?:))
+ (eq register ?:))
+ (setq macro (lambda () (evil-ex-repeat nil))
+ evil-last-register ?:))
+ ((eq register ?@)
+ (unless evil-last-register
+ (user-error "No previously executed keyboard macro."))
+ (setq macro (evil-get-register evil-last-register t)))
+ (t
+ (setq macro (evil-get-register register t)
+ evil-last-register register)))
+ (list count macro)))
+ (cond
+ ((functionp macro)
+ (evil-repeat-abort)
+ (dotimes (_ (or count 1))
+ (funcall macro)))
+ ((or (and (not (stringp macro))
+ (not (vectorp macro)))
+ (member macro '("" [])))
+ ;; allow references to currently empty registers
+ ;; when defining macro
+ (unless evil-this-macro
+ (user-error "No previous macro")))
+ (t
+ (condition-case err
+ (evil-with-single-undo
+ (dotimes (_ (or count 1))
+ (execute-kbd-macro macro)))
+ ;; enter Normal state if the macro fails
+ (error
+ (evil-normal-state)
+ (evil-normalize-keymaps)
+ (signal (car err) (cdr err)))))))
+
+;;; Visual commands
+
+(evil-define-motion evil-visual-restore ()
+ "Restore previous selection."
+ (let* ((point (point))
+ (mark (or (mark t) point))
+ (type (evil-visual-type)))
+ ;; TODO handle swapping selection in visual state...
+ (unless (evil-visual-state-p)
+ (cond
+ ;; No previous selection.
+ ((or (null evil-visual-selection)
+ (null evil-visual-mark)
+ (null evil-visual-point)))
+ (t
+ (setq mark evil-visual-mark
+ point evil-visual-point)))
+ (evil-visual-make-selection mark point type t))))
+
+(evil-define-motion evil-visual-exchange-corners ()
+ "Rearrange corners in Visual Block mode.
+
+ M---+ +---M
+ | | <=> | |
+ +---P P---+
+
+For example, if mark is in the upper left corner and point
+in the lower right, this function puts mark in the upper right
+corner and point in the lower left."
+ (cond
+ ((eq evil-visual-selection 'block)
+ (let* ((point (point))
+ (mark (or (mark t) point))
+ (point-col (evil-column point))
+ (mark-col (evil-column mark))
+ (mark (save-excursion
+ (goto-char mark)
+ (evil-move-to-column point-col)
+ (point)))
+ (point (save-excursion
+ (goto-char point)
+ (evil-move-to-column mark-col)
+ (point))))
+ (evil-visual-refresh mark point)))
+ (t
+ (evil-exchange-point-and-mark)
+ (evil-visual-refresh))))
+
+(evil-define-command evil-visual-rotate (corner &optional beg end type)
+ "In Visual Block selection, put point in CORNER.
+Corner may be one of `upper-left', `upper-right', `lower-left'
+and `lower-right':
+
+ upper-left +---+ upper-right
+ | |
+ lower-left +---+ lower-right
+
+When called interactively, the selection is rotated blockwise."
+ :keep-visual t
+ (interactive
+ (let ((corners '(upper-left upper-right lower-right lower-left)))
+ (list (or (cadr (memq (evil-visual-block-corner) corners))
+ 'upper-left))))
+ (let* ((beg (or beg (point)))
+ (end (or end (mark t) beg))
+ (type (or type evil-this-type))
+ range)
+ (cond
+ ((memq type '(rectangle block))
+ (setq range (evil-block-rotate beg end :corner corner)
+ beg (pop range)
+ end (pop range))
+ (unless (eq corner (evil-visual-block-corner corner beg end))
+ (evil-swap beg end))
+ (goto-char beg)
+ (when (evil-visual-state-p)
+ (evil-move-mark end)
+ (evil-visual-refresh nil nil nil :corner corner)))
+ ((memq corner '(upper-right lower-right))
+ (goto-char (max beg end))
+ (when (evil-visual-state-p)
+ (evil-move-mark (min beg end))))
+ (t
+ (goto-char (min beg end))
+ (when (evil-visual-state-p)
+ (evil-move-mark (max beg end)))))))
+
+;;; Insertion commands
+
+(defun evil-insert (count &optional vcount skip-empty-lines)
+ "Switch to Insert state just before point.
+The insertion will be repeated COUNT times and repeated once for
+the next VCOUNT - 1 lines starting at the same column.
+If SKIP-EMPTY-LINES is non-nil, the insertion will not be performed
+on lines on which the insertion point would be after the end of the
+lines. This is the default behaviour for Visual-state insertion."
+ (interactive
+ (list (prefix-numeric-value current-prefix-arg)
+ (and (evil-visual-state-p)
+ (memq (evil-visual-type) '(line block))
+ (save-excursion
+ (let ((m (mark)))
+ ;; go to upper-left corner temporarily so
+ ;; `count-lines' yields accurate results
+ (evil-visual-rotate 'upper-left)
+ (prog1 (count-lines evil-visual-beginning evil-visual-end)
+ (set-mark m)))))
+ (evil-visual-state-p)))
+ (if (and (called-interactively-p 'any)
+ (evil-visual-state-p))
+ (cond
+ ((eq (evil-visual-type) 'line)
+ (evil-visual-rotate 'upper-left)
+ (evil-insert-line count vcount))
+ ((eq (evil-visual-type) 'block)
+ (let ((column (min (evil-column evil-visual-beginning)
+ (evil-column evil-visual-end))))
+ (evil-visual-rotate 'upper-left)
+ (move-to-column column t)
+ (evil-insert count vcount skip-empty-lines)))
+ (t
+ (evil-visual-rotate 'upper-left)
+ (evil-insert count vcount skip-empty-lines)))
+ (setq evil-insert-count count
+ evil-insert-lines nil
+ evil-insert-vcount (and vcount
+ (> vcount 1)
+ (list (line-number-at-pos)
+ (current-column)
+ vcount))
+ evil-insert-skip-empty-lines skip-empty-lines)
+ (evil-insert-state 1)))
+
+(defun evil-append (count &optional vcount skip-empty-lines)
+ "Switch to Insert state just after point.
+The insertion will be repeated COUNT times and repeated once for
+the next VCOUNT - 1 lines starting at the same column. If
+SKIP-EMPTY-LINES is non-nil, the insertion will not be performed
+on lines on which the insertion point would be after the end of
+the lines."
+ (interactive
+ (list (prefix-numeric-value current-prefix-arg)
+ (and (evil-visual-state-p)
+ (memq (evil-visual-type) '(line block))
+ (save-excursion
+ (let ((m (mark)))
+ ;; go to upper-left corner temporarily so
+ ;; `count-lines' yields accurate results
+ (evil-visual-rotate 'upper-left)
+ (prog1 (count-lines evil-visual-beginning evil-visual-end)
+ (set-mark m)))))))
+ (if (and (called-interactively-p 'any)
+ (evil-visual-state-p))
+ (cond
+ ((or (eq (evil-visual-type) 'line)
+ (and (eq (evil-visual-type) 'block)
+ (memq last-command '(next-line previous-line))
+ (numberp temporary-goal-column)
+ (= temporary-goal-column most-positive-fixnum)))
+ (evil-visual-rotate 'upper-left)
+ (evil-append-line count vcount))
+ ((eq (evil-visual-type) 'block)
+ (let ((column (max (evil-column evil-visual-beginning)
+ (evil-column evil-visual-end))))
+ (evil-visual-rotate 'upper-left)
+ (move-to-column column t)
+ (evil-insert count vcount skip-empty-lines)))
+ (t
+ (evil-visual-rotate 'lower-right)
+ (backward-char)
+ (evil-append count)))
+ (unless (= (current-column)
+ (save-excursion (end-of-line) (current-column)))
+ ;; Subtly different from `(eolp)' - see issue #1617
+ (forward-char))
+ (evil-insert count vcount skip-empty-lines)
+ (add-hook 'post-command-hook #'evil-maybe-remove-spaces)))
+
+(defun evil-insert-resume (count)
+ "Switch to Insert state at previous insertion point.
+The insertion will be repeated COUNT times. If called from visual
+state, only place point at the previous insertion position but do not
+switch to insert state."
+ (interactive "p")
+ (evil-goto-mark ?^ t)
+ (unless (evil-visual-state-p)
+ (evil-insert count)))
+
+(defun evil-quoted-insert (count)
+ "Like `quoted-insert' but delete COUNT chars forward in replace state.
+Adds a `^' overlay as an input prompt."
+ (interactive "p")
+ (let* ((opoint (point))
+ chars-to-delete insert-prompt)
+ (unwind-protect
+ (progn
+ (if (evil-replace-state-p)
+ (progn
+ (setq chars-to-delete (min (- (point-at-eol) opoint) count)
+ insert-prompt (make-overlay opoint (+ chars-to-delete opoint)))
+ (evil-update-replace-alist opoint count chars-to-delete))
+ (setq insert-prompt (make-overlay opoint opoint)))
+ (overlay-put insert-prompt 'invisible t)
+ (overlay-put insert-prompt 'after-string (propertize "^"
+ 'face 'escape-glyph
+ 'cursor 1))
+ (let (overwrite-mode) ;; Force `read-quoted-char'
+ (quoted-insert count))
+ (when (evil-replace-state-p) (delete-char chars-to-delete)))
+ (when insert-prompt (delete-overlay insert-prompt)))))
+
+(defun evil-open-above (count)
+ "Insert a new line above point and switch to Insert state.
+The insertion will be repeated COUNT times."
+ (interactive "p")
+ (unless (eq evil-want-fine-undo t)
+ (evil-start-undo-step))
+ (evil-insert-newline-above)
+ (setq evil-insert-count count
+ evil-insert-lines t
+ evil-insert-vcount nil)
+ (evil-insert-state 1)
+ (when evil-auto-indent
+ (indent-according-to-mode)))
+
+(defun evil-open-below (count)
+ "Insert a new line below point and switch to Insert state.
+The insertion will be repeated COUNT times."
+ (interactive "p")
+ (unless (eq evil-want-fine-undo t)
+ (evil-start-undo-step))
+ (push (point) buffer-undo-list)
+ (evil-insert-newline-below)
+ (setq evil-insert-count count
+ evil-insert-lines t
+ evil-insert-vcount nil)
+ (evil-insert-state 1)
+ (when evil-auto-indent
+ (indent-according-to-mode)))
+
+(defun evil--insert-line (count vcount non-blank-p)
+ "Switch to insert state at the beginning of the current line.
+If NON-BLANK-P is non-nil, point is placed at the first non-blank character
+on the current line. If NON-BLANK-P is nil, point is placed at column 0,
+or the beginning of visual line. The insertion will be repeated COUNT times.
+If VCOUNT is non nil it should be number > 0. The insertion will be repeated
+in the next VCOUNT - 1 lines below the current one."
+ (push (point) buffer-undo-list)
+ (let ((move-fn (if non-blank-p #'back-to-indentation #'evil-beginning-of-line)))
+ (if (and visual-line-mode
+ evil-respect-visual-line-mode)
+ (goto-char
+ (max (save-excursion
+ (funcall move-fn)
+ (point))
+ (save-excursion
+ (beginning-of-visual-line)
+ (point))))
+ (funcall move-fn)))
+ (setq evil-insert-count count
+ evil-insert-lines nil
+ evil-insert-vcount
+ (and vcount
+ (> vcount 1)
+ (list (line-number-at-pos)
+ (if non-blank-p #'evil-first-non-blank #'evil-beginning-of-line)
+ vcount)))
+ (evil-insert-state 1))
+
+(defun evil-insert-line (count &optional vcount)
+ "Switch to insert state at beginning of current line.
+Point is placed at the first non-blank character on the current
+line. The insertion will be repeated COUNT times. If VCOUNT is
+non nil it should be number > 0. The insertion will be repeated
+in the next VCOUNT - 1 lines below the current one."
+ (interactive "p")
+ (evil--insert-line count vcount t))
+
+(defun evil-insert-0-line (count &optional vcount)
+ "Switch to insert state at beginning of current line.
+Point is placed at column 0, or the beginning of the visual line.
+The insertion will be repeated COUNT times. If VCOUNT is
+non nil it should be number > 0. The insertion will be repeated
+in the next VCOUNT - 1 lines below the current one."
+ (interactive "p")
+ (evil--insert-line count vcount nil))
+
+(defun evil-append-line (count &optional vcount)
+ "Switch to Insert state at the end of the current line.
+The insertion will be repeated COUNT times. If VCOUNT is non nil
+it should be number > 0. The insertion will be repeated in the
+next VCOUNT - 1 lines below the current one."
+ (interactive "p")
+ (if (and visual-line-mode
+ evil-respect-visual-line-mode)
+ (evil-end-of-visual-line)
+ (evil-move-end-of-line))
+ (setq evil-insert-count count
+ evil-insert-lines nil
+ evil-insert-vcount
+ (and vcount
+ (> vcount 1)
+ (list (line-number-at-pos)
+ #'end-of-line
+ vcount)))
+ (evil-insert-state 1))
+
+(evil-define-command evil-insert-digraph (count)
+ "Insert COUNT digraphs."
+ :repeat change
+ (interactive "p")
+ (let ((opoint (point))
+ chars-to-delete insert-prompt)
+ (if (evil-replace-state-p)
+ (progn
+ (setq chars-to-delete (min (- (point-at-eol) opoint) count)
+ insert-prompt (make-overlay opoint (+ chars-to-delete opoint)))
+ (evil-update-replace-alist opoint count chars-to-delete))
+ (setq insert-prompt (make-overlay opoint opoint)))
+ (insert-char (evil-read-digraph-char-with-overlay insert-prompt) count)
+ (when chars-to-delete (delete-char chars-to-delete))))
+
+(evil-define-command evil-ex-show-digraphs ()
+ "Shows a list of all available digraphs."
+ :repeat nil
+ (let ((columns 3))
+ (evil-with-view-list
+ :name "evil-digraphs"
+ :mode-name "Evil Digraphs"
+ :format
+ (cl-loop repeat columns
+ vconcat [("Digraph" 8 nil)
+ ("Sequence" 16 nil)])
+ :entries
+ (let* ((digraphs (mapcar #'(lambda (digraph)
+ (cons (cdr digraph)
+ (car digraph)))
+ (append evil-digraphs-table
+ evil-digraphs-table-user)))
+ (entries (cl-loop for digraph in digraphs
+ collect `(,(concat (char-to-string (nth 1 digraph))
+ (char-to-string (nth 2 digraph)))
+ ,(char-to-string (nth 0 digraph)))))
+ (row)
+ (rows)
+ (clength (* columns 2)))
+ (cl-loop for e in entries
+ do
+ (push (nth 0 e) row)
+ (push (nth 1 e) row)
+ (when (eq (length row) clength)
+ (push `(nil ,(apply #'vector row)) rows)
+ (setq row nil)))
+ rows))))
+
+(defun evil--self-insert-string (string)
+ "Insert STRING as if typed interactively."
+ (let ((chars (append string nil)))
+ (dolist (char chars)
+ (let ((last-command-event char))
+ (self-insert-command 1)))))
+
+(defun evil-copy-from-above (arg)
+ "Copy characters from preceding non-blank line.
+The copied text is inserted before point.
+ARG is the number of lines to move backward.
+See also \\<evil-insert-state-map>\\[evil-copy-from-below]."
+ (interactive
+ (cond
+ ;; if a prefix argument was given, repeat it for subsequent calls
+ ((and (null current-prefix-arg)
+ (eq last-command #'evil-copy-from-above))
+ (setq current-prefix-arg last-prefix-arg)
+ (list (prefix-numeric-value current-prefix-arg)))
+ (t
+ (list (prefix-numeric-value current-prefix-arg)))))
+ (evil--self-insert-string (evil-copy-chars-from-line arg -1)))
+
+(defun evil-copy-from-below (arg)
+ "Copy characters from following non-blank line.
+The copied text is inserted before point.
+ARG is the number of lines to move forward.
+See also \\<evil-insert-state-map>\\[evil-copy-from-above]."
+ (interactive
+ (cond
+ ((and (null current-prefix-arg)
+ (eq last-command #'evil-copy-from-below))
+ (setq current-prefix-arg last-prefix-arg)
+ (list (prefix-numeric-value current-prefix-arg)))
+ (t
+ (list (prefix-numeric-value current-prefix-arg)))))
+ (evil--self-insert-string (evil-copy-chars-from-line arg 1)))
+
+;; adapted from `copy-from-above-command' in misc.el
+(defun evil-copy-chars-from-line (n num &optional col)
+ "Return N characters from line NUM, starting at column COL.
+NUM is relative to the current line and can be negative.
+COL defaults to the current column."
+ (interactive "p")
+ (let ((col (or col (current-column))) prefix)
+ (save-excursion
+ (forward-line num)
+ (when (looking-at "[[:space:]]*$")
+ (if (< num 0)
+ (skip-chars-backward " \t\n")
+ (skip-chars-forward " \t\n")))
+ (evil-move-beginning-of-line)
+ (move-to-column col)
+ ;; if the column winds up in middle of a tab,
+ ;; return the appropriate number of spaces
+ (when (< col (current-column))
+ (if (eq (preceding-char) ?\t)
+ (let ((len (min n (- (current-column) col))))
+ (setq prefix (make-string len ?\s)
+ n (- n len)))
+ ;; if in middle of a control char, return the whole char
+ (backward-char 1)))
+ (concat prefix
+ (buffer-substring (point)
+ (min (line-end-position)
+ (+ n (point))))))))
+
+;; completion
+(evil-define-command evil-complete-next (&optional arg)
+ "Complete to the nearest following word.
+Search backward if a match isn't found.
+Calls `evil-complete-next-func'."
+ :repeat change
+ (interactive "P")
+ (if (minibufferp)
+ (funcall evil-complete-next-minibuffer-func)
+ (funcall evil-complete-next-func arg)))
+
+(evil-define-command evil-complete-previous (&optional arg)
+ "Complete to the nearest preceding word.
+Search forward if a match isn't found.
+Calls `evil-complete-previous-func'."
+ :repeat change
+ (interactive "P")
+ (if (minibufferp)
+ (funcall evil-complete-previous-minibuffer-func)
+ (funcall evil-complete-previous-func arg)))
+
+(evil-define-command evil-complete-next-line (&optional arg)
+ "Complete a whole line.
+Calls `evil-complete-next-line-func'."
+ :repeat change
+ (interactive "P")
+ (if (minibufferp)
+ (funcall evil-complete-next-minibuffer-func)
+ (funcall evil-complete-next-line-func arg)))
+
+(evil-define-command evil-complete-previous-line (&optional arg)
+ "Complete a whole line.
+Calls `evil-complete-previous-line-func'."
+ :repeat change
+ (interactive "P")
+ (if (minibufferp)
+ (funcall evil-complete-previous-minibuffer-func)
+ (funcall evil-complete-previous-line-func arg)))
+
+;;; Search
+
+(defun evil-repeat-search (flag)
+ "Called to record a search command.
+FLAG is either 'pre or 'post if the function is called before resp.
+after executing the command."
+ (cond
+ ((and (evil-operator-state-p) (eq flag 'pre))
+ (evil-repeat-record (this-command-keys))
+ (evil-clear-command-keys))
+ ((and (evil-operator-state-p) (eq flag 'post))
+ ;; The value of (this-command-keys) at this point should be the
+ ;; key-sequence that called the last command that finished the
+ ;; search, usually RET. Therefore this key-sequence will be
+ ;; recorded in the post-command of the operator. Alternatively we
+ ;; could do it here.
+ (evil-repeat-record (if evil-regexp-search
+ (car-safe regexp-search-ring)
+ (car-safe search-ring))))
+ (t (evil-repeat-motion flag))))
+
+(evil-define-motion evil-search-forward ()
+ (format "Search forward for user-entered text.
+Searches for regular expression if `evil-regexp-search' is t.%s"
+ (if (and (fboundp 'isearch-forward)
+ (documentation 'isearch-forward))
+ (format "\n\nBelow is the documentation string \
+for `isearch-forward',\nwhich lists available keys:\n\n%s"
+ (documentation 'isearch-forward)) ""))
+ :jump t
+ :type exclusive
+ :repeat evil-repeat-search
+ (evil-search-incrementally t evil-regexp-search))
+
+(evil-define-motion evil-search-backward ()
+ (format "Search backward for user-entered text.
+Searches for regular expression if `evil-regexp-search' is t.%s"
+ (if (and (fboundp 'isearch-forward)
+ (documentation 'isearch-forward))
+ (format "\n\nBelow is the documentation string \
+for `isearch-forward',\nwhich lists available keys:\n\n%s"
+ (documentation 'isearch-forward)) ""))
+ :jump t
+ :type exclusive
+ :repeat evil-repeat-search
+ (evil-search-incrementally nil evil-regexp-search))
+
+(evil-define-motion evil-search-next (count)
+ "Repeat the last search."
+ :jump t
+ :type exclusive
+ (let ((orig (point))
+ (search-string (if evil-regexp-search
+ (car-safe regexp-search-ring)
+ (car-safe search-ring))))
+ (goto-char
+ ;; Wrap in `save-excursion' so that multiple searches have no visual effect.
+ (save-excursion
+ (evil-search search-string isearch-forward evil-regexp-search)
+ (when (and (> (point) orig)
+ (save-excursion
+ (evil-adjust-cursor)
+ (= (point) orig)))
+ ;; Point won't move after first attempt and `evil-adjust-cursor' takes
+ ;; effect, so start again.
+ (evil-search search-string isearch-forward evil-regexp-search))
+ (point)))
+ (when (and count (> count 1))
+ (dotimes (_ (1- count))
+ (evil-search search-string isearch-forward evil-regexp-search)))))
+
+(evil-define-motion evil-search-previous (count)
+ "Repeat the last search in the opposite direction."
+ :jump t
+ :type exclusive
+ (dotimes (_ (or count 1))
+ (evil-search (if evil-regexp-search
+ (car-safe regexp-search-ring)
+ (car-safe search-ring))
+ (not isearch-forward) evil-regexp-search)))
+
+(evil-define-motion evil-search-word-backward (count &optional symbol)
+ "Search backward for symbol under point."
+ :jump t
+ :type exclusive
+ (interactive (list (prefix-numeric-value current-prefix-arg)
+ evil-symbol-word-search))
+ (dotimes (_ (or count 1))
+ (evil-search-word nil nil symbol)))
+
+(evil-define-motion evil-search-word-forward (count &optional symbol)
+ "Search forward for symbol under point."
+ :jump t
+ :type exclusive
+ (interactive (list (prefix-numeric-value current-prefix-arg)
+ evil-symbol-word-search))
+ (dotimes (_ (or count 1))
+ (evil-search-word t nil symbol)))
+
+(evil-define-motion evil-search-unbounded-word-backward (count &optional symbol)
+ "Search backward for symbol under point.
+The search is unbounded, i.e., the pattern is not wrapped in
+\\<...\\>."
+ :jump t
+ :type exclusive
+ (interactive (list (prefix-numeric-value current-prefix-arg)
+ evil-symbol-word-search))
+ (dotimes (_ (or count 1))
+ (evil-search-word nil t symbol)))
+
+(evil-define-motion evil-search-unbounded-word-forward (count &optional symbol)
+ "Search forward for symbol under point.
+The search is unbounded, i.e., the pattern is not wrapped in
+\\<...\\>."
+ :jump t
+ :type exclusive
+ (interactive (list (prefix-numeric-value current-prefix-arg)
+ evil-symbol-word-search))
+ (dotimes (_ (or count 1))
+ (evil-search-word t t symbol)))
+
+(defun evil-goto-definition-imenu (string _position)
+ "Find definition for STRING with imenu."
+ (require 'imenu nil t)
+ (let (ientry ipos)
+ (when (fboundp 'imenu--make-index-alist)
+ (ignore-errors (setq ientry (imenu--make-index-alist)))
+ (setq ientry (imenu--in-alist string ientry))
+ (setq ipos (cdr ientry))
+ (when (and (markerp ipos)
+ (eq (marker-buffer ipos) (current-buffer)))
+ (setq ipos (marker-position ipos))
+ (when (numberp ipos)
+ (evil-search (format "\\_<%s\\_>" (regexp-quote string)) t t ipos)
+ t)))))
+
+(defun evil-goto-definition-semantic (_string position)
+ "Find definition for POSITION with semantic."
+ (and (fboundp 'semantic-ia-fast-jump)
+ (ignore-errors (semantic-ia-fast-jump position))))
+
+(declare-function xref-backend-identifier-at-point "xref")
+
+(defun evil-goto-definition-xref (_string position)
+ "Find definition at POSITION with xref."
+ (when (fboundp 'xref-find-definitions)
+ (let ((identifier (save-excursion
+ (goto-char position)
+ (xref-backend-identifier-at-point (xref-find-backend)))))
+ (condition-case ()
+ (progn
+ (xref-find-definitions identifier)
+ t)
+ (user-error nil)))))
+
+(defun evil-goto-definition-search (string _position)
+ "Find definition for STRING with evil-search."
+ (evil-search (format "\\_<%s\\_>" (regexp-quote string)) t t (point-min))
+ t)
+
+(evil-define-motion evil-goto-definition ()
+ "Go to definition or first occurrence of symbol under point.
+See also `evil-goto-definition-functions'."
+ :jump t
+ :type exclusive
+ (let* ((match (evil--find-thing t 'symbol))
+ (string (car match))
+ (position (cdr match)))
+ (if (null string)
+ (user-error "No symbol under cursor")
+ (setq isearch-forward t)
+ (run-hook-with-args-until-success 'evil-goto-definition-functions
+ string position))))
+
+;;; Folding
+(defun evil-fold-action (list action)
+ "Perform fold ACTION for each matching major or minor mode in LIST.
+
+ACTION will be performed for the first matching handler in LIST. For more
+information on its features and format, see the documentation for
+`evil-fold-list'.
+
+If no matching ACTION is found in LIST, an error will signaled.
+
+Handler errors will be demoted, so a problem in one handler will (hopefully)
+not interfere with another."
+ (if (null list)
+ (user-error
+ "Enable one of the following modes for folding to work: %s"
+ (mapconcat 'symbol-name (mapcar 'caar evil-fold-list) ", "))
+ (let* ((modes (caar list)))
+ (if (evil--mode-p modes)
+ (let* ((actions (cdar list))
+ (fn (plist-get actions action)))
+ (when fn
+ (with-demoted-errors "Error: %S" (funcall fn))))
+ (evil-fold-action (cdr list) action)))))
+
+(defun evil--mode-p (modes)
+ "Determines whether any symbol in MODES represents the current
+buffer's major mode or any of its minors."
+ (unless (eq modes '())
+ (let ((mode (car modes)))
+ (or (eq major-mode mode)
+ (and (boundp mode) (symbol-value mode))
+ (evil--mode-p (cdr modes))))))
+
+(evil-define-command evil-toggle-fold ()
+ "Open or close a fold under point.
+See also `evil-open-fold' and `evil-close-fold'."
+ (evil-fold-action evil-fold-list :toggle))
+
+(evil-define-command evil-open-folds ()
+ "Open all folds.
+See also `evil-close-folds'."
+ (evil-fold-action evil-fold-list :open-all))
+
+(evil-define-command evil-close-folds ()
+ "Close all folds.
+See also `evil-open-folds'."
+ (evil-fold-action evil-fold-list :close-all))
+
+(evil-define-command evil-open-fold ()
+ "Open fold at point.
+See also `evil-close-fold'."
+ (evil-fold-action evil-fold-list :open))
+
+(evil-define-command evil-open-fold-rec ()
+ "Open fold at point recursively.
+See also `evil-open-fold' and `evil-close-fold'."
+ (evil-fold-action evil-fold-list :open-rec))
+
+(evil-define-command evil-close-fold ()
+ "Close fold at point.
+See also `evil-open-fold'."
+ (evil-fold-action evil-fold-list :close))
+
+;;; Ex
+
+(evil-define-operator evil-write (beg end type file-or-append &optional bang)
+ "Save the current buffer, from BEG to END, to FILE-OR-APPEND.
+If FILE-OR-APPEND is of the form \">> FILE\", append to FILE
+instead of overwriting. The current buffer's filename is not
+changed unless it has no associated file and no region is
+specified. If the file already exists and the BANG argument is
+non-nil, it is overwritten without confirmation."
+ :motion nil
+ :move-point nil
+ :type line
+ :repeat nil
+ (interactive "<R><fsh><!>")
+ (let* ((append-and-filename (evil-extract-append file-or-append))
+ (append (car append-and-filename))
+ (filename (cdr append-and-filename))
+ (bufname (buffer-file-name (buffer-base-buffer))))
+ (when (zerop (length filename))
+ (setq filename bufname))
+ (cond
+ ((zerop (length filename))
+ (user-error "Please specify a file name for the buffer"))
+ ;; execute command on region
+ ((eq (aref filename 0) ?!)
+ (shell-command-on-region beg end (substring filename 1)))
+ ;; with region or append, always save to file without resetting
+ ;; modified flag
+ ((or append (and beg end))
+ (write-region beg end filename append nil nil (not (or append bang))))
+ ;; no current file
+ ((null bufname)
+ (write-file filename (not bang)))
+ ;; save current buffer to its file
+ ((string= filename bufname)
+ (if (not bang) (save-buffer) (write-file filename)))
+ ;; save to another file
+ (t
+ (write-region nil nil filename
+ nil (not bufname) nil
+ (not bang))))))
+
+(evil-define-command evil-write-all (bang)
+ "Saves all buffers visiting a file.
+If BANG is non nil then read-only buffers are saved, too,
+otherwise they are skipped. "
+ :repeat nil
+ :move-point nil
+ (interactive "<!>")
+ (if bang
+ (save-some-buffers t)
+ ;; save only buffer that are not read-only and
+ ;; that are visiting a file
+ (save-some-buffers t
+ #'(lambda ()
+ (and (not buffer-read-only)
+ (buffer-file-name))))))
+
+(evil-define-command evil-update ()
+ "Same as `evil-write', but only write when the buffer has been modified."
+ :motion nil
+ :move-point nil
+ :type line
+ :repeat nil
+ (when (buffer-modified-p)
+ (call-interactively #'evil-write)))
+
+(evil-define-command evil-save (filename &optional bang)
+ "Save the current buffer to FILENAME.
+Changes the file name of the current buffer to FILENAME. If no
+FILENAME is given, the current file name is used."
+ :repeat nil
+ :move-point nil
+ (interactive "<f><!>")
+ (when (zerop (length filename))
+ (setq filename (buffer-file-name (buffer-base-buffer))))
+ (write-file filename (not bang)))
+
+(evil-define-command evil-edit (file &optional bang)
+ "Open FILE.
+If no FILE is specified, reload the current buffer from disk."
+ :repeat nil
+ (interactive "<f><!>")
+ (if file
+ (find-file file)
+ (revert-buffer bang (or bang (not (buffer-modified-p))) t)))
+
+(evil-define-command evil-read (count file)
+ "Inserts the contents of FILE below the current line or line COUNT."
+ :repeat nil
+ :move-point nil
+ (interactive "P<fsh>")
+ (when (and file (not (zerop (length file))))
+ (when count (goto-char (point-min)))
+ (when (or (not (zerop (forward-line (or count 1))))
+ (not (bolp)))
+ (insert "\n"))
+ (cond
+ ((/= (aref file 0) ?!)
+ (when (member file '("#" "%"))
+ (setq file (evil-ex-replace-special-filenames file)))
+ (let ((result (insert-file-contents file)))
+ (save-excursion
+ (forward-char (cadr result))
+ (unless (bolp) (insert "\n")))))
+ (t
+ (shell-command (evil-ex-replace-special-filenames (substring file 1)) t)
+ (goto-char (mark))
+ (unless (bolp) (insert "\n"))
+ (forward-line -1)))))
+
+(evil-define-command evil-show-files ()
+ "Shows the file-list.
+The same as `buffer-menu', but shows only buffers visiting
+files."
+ :repeat nil
+ (buffer-menu 1))
+
+(evil-define-command evil-goto-error (count)
+ "Go to error number COUNT.
+
+If no COUNT supplied, move to the current error.
+
+Acts like `first-error' other than when given no counts, goes
+to the current error instead of the first, like in Vim's :cc
+command."
+ :repeat nil
+ (interactive "<c>")
+ (if count
+ (first-error (if (eql 0 count) 1 count))
+ (next-error 0)))
+
+(evil-define-command evil-buffer (buffer)
+ "Switches to another buffer."
+ :repeat nil
+ (interactive "<b>")
+ (cond
+ ;; no buffer given, switch to "other" buffer
+ ((null buffer) (switch-to-buffer (other-buffer)))
+ ;; we are given the name of an existing buffer
+ ((get-buffer buffer) (switch-to-buffer buffer))
+ ;; try to complete the buffer
+ ((let ((all-buffers (internal-complete-buffer buffer nil t)))
+ (when (= (length all-buffers) 1)
+ (switch-to-buffer (car all-buffers)))))
+ (t
+ (when (y-or-n-p
+ (format "No buffer with name \"%s\" exists. Create new buffer? "
+ buffer))
+ (switch-to-buffer buffer)))))
+
+(evil-define-command evil-next-buffer (&optional count)
+ "Goes to the `count'-th next buffer in the buffer list."
+ :repeat nil
+ (interactive "p")
+ (dotimes (_ (or count 1))
+ (next-buffer)))
+
+(evil-define-command evil-prev-buffer (&optional count)
+ "Goes to the `count'-th prev buffer in the buffer list."
+ :repeat nil
+ (interactive "p")
+ (dotimes (_ (or count 1))
+ (previous-buffer)))
+
+(evil-define-command evil-delete-buffer (buffer &optional bang)
+ "Deletes a buffer.
+All windows currently showing this buffer will be closed except
+for the last window in each frame."
+ (interactive "<b><!>")
+ (with-current-buffer (or buffer (current-buffer))
+ (when bang
+ (set-buffer-modified-p nil)
+ (dolist (process (process-list))
+ (when (eq (process-buffer process) (current-buffer))
+ (set-process-query-on-exit-flag process nil))))
+ ;; get all windows that show this buffer
+ (let ((wins (get-buffer-window-list (current-buffer) nil t)))
+ ;; if the buffer which was initiated by emacsclient,
+ ;; call `server-edit' from server.el to avoid
+ ;; "Buffer still has clients" message
+ (if (and (fboundp 'server-edit)
+ (boundp 'server-buffer-clients)
+ server-buffer-clients)
+ (server-edit)
+ (kill-buffer nil))
+ ;; close all windows that showed this buffer
+ (mapc #'(lambda (w)
+ (condition-case nil
+ (delete-window w)
+ (error nil)))
+ wins))))
+
+(evil-define-command evil-quit (&optional force)
+ "Closes the current window, current frame, Emacs.
+If the current frame belongs to some client the client connection
+is closed."
+ :repeat nil
+ (interactive "<!>")
+ (condition-case nil
+ (delete-window)
+ (error
+ (if (and (boundp 'server-buffer-clients)
+ (fboundp 'server-edit)
+ (fboundp 'server-buffer-done)
+ server-buffer-clients)
+ (if force
+ (server-buffer-done (current-buffer))
+ (server-edit))
+ (condition-case nil
+ (delete-frame)
+ (error
+ (if force
+ (kill-emacs)
+ (save-buffers-kill-emacs))))))))
+
+(evil-define-command evil-quit-all (&optional bang)
+ "Exits Emacs, asking for saving."
+ :repeat nil
+ (interactive "<!>")
+ (if (null bang)
+ (save-buffers-kill-terminal)
+ (let ((proc (frame-parameter (selected-frame) 'client)))
+ (if proc
+ (with-no-warnings
+ (server-delete-client proc))
+ (dolist (process (process-list))
+ (set-process-query-on-exit-flag process nil))
+ (kill-emacs)))))
+
+(evil-define-command evil-quit-all-with-error-code (&optional force)
+ "Exits Emacs without saving, returning an non-zero error code.
+The FORCE argument is only there for compatibility and is ignored.
+This function fails with an error if Emacs is run in server mode."
+ :repeat nil
+ (interactive "<!>")
+ (if (and (boundp 'server-buffer-clients)
+ (fboundp 'server-edit)
+ (fboundp 'server-buffer-done)
+ server-buffer-clients)
+ (user-error "Cannot exit client process with error code.")
+ (kill-emacs 1)))
+
+(evil-define-command evil-save-and-quit ()
+ "Save all buffers and exit Emacs."
+ (save-buffers-kill-terminal t))
+
+(evil-define-command evil-save-and-close (file &optional bang)
+ "Saves the current buffer and closes the window."
+ :repeat nil
+ (interactive "<f><!>")
+ (evil-write nil nil nil file bang)
+ (evil-quit))
+
+(evil-define-command evil-save-modified-and-close (file &optional bang)
+ "Saves the current buffer and closes the window."
+ :repeat nil
+ (interactive "<f><!>")
+ (when (buffer-modified-p)
+ (evil-write nil nil nil file bang))
+ (evil-quit))
+
+(evil-define-operator evil-shell-command
+ (beg end type command &optional previous)
+ "Execute a shell command.
+If BEG, END and TYPE is specified, COMMAND is executed on the region,
+which is replaced with the command's output. Otherwise, the
+output is displayed in its own buffer. If PREVIOUS is non-nil,
+the previous shell command is executed instead."
+ (interactive "<R><sh><!>")
+ (if (not (evil-ex-p))
+ (let ((evil-ex-initial-input
+ (if (and beg
+ (not (evil-visual-state-p))
+ (not current-prefix-arg))
+ (let ((range (evil-range beg end type)))
+ (evil-contract-range range)
+ ;; TODO: this is not exactly the same as Vim, which
+ ;; uses .,+count as range. However, this is easier
+ ;; to achieve with the current implementation and
+ ;; the very inconvenient range interface.
+ ;;
+ ;; TODO: the range interface really needs some
+ ;; rework!
+ (format
+ "%d,%d!"
+ (line-number-at-pos (evil-range-beginning range))
+ (line-number-at-pos (evil-range-end range))))
+ "!")))
+ (call-interactively 'evil-ex))
+ (when command
+ (setq command (evil-ex-replace-special-filenames command)))
+ (if (zerop (length command))
+ (when previous (setq command evil-previous-shell-command))
+ (setq evil-previous-shell-command command))
+ (cond
+ ((zerop (length command))
+ (if previous (user-error "No previous shell command")
+ (user-error "No shell command")))
+ (evil-ex-range
+ (if (not evil-display-shell-error-in-message)
+ (shell-command-on-region beg end command nil t)
+ (let ((output-buffer (generate-new-buffer " *temp*"))
+ (error-buffer (generate-new-buffer " *temp*")))
+ (unwind-protect
+ (if (zerop (shell-command-on-region beg end
+ command
+ output-buffer nil
+ error-buffer))
+ (progn
+ (delete-region beg end)
+ (insert-buffer-substring output-buffer)
+ (goto-char beg)
+ (evil-first-non-blank))
+ (display-message-or-buffer error-buffer))
+ (kill-buffer output-buffer)
+ (kill-buffer error-buffer)))))
+ (t
+ (shell-command command)))))
+
+(evil-define-command evil-make (arg)
+ "Call a build command in the current directory.
+If ARG is nil this function calls `recompile', otherwise it calls
+`compile' passing ARG as build command."
+ (interactive "<sh>")
+ (if (and (fboundp 'recompile)
+ (not arg))
+ (recompile)
+ (compile arg)))
+
+;; TODO: escape special characters (currently only \n) ... perhaps
+;; there is some Emacs function doing this?
+(evil-define-command evil-show-registers (registers)
+ "Shows the contents of REGISTERS, or all registers, if none supplied."
+ :repeat nil
+ (interactive "<a>")
+ (let* ((all-registers (evil-register-list))
+ (reg-chars (string-to-list registers))
+ (display-regs (if reg-chars
+ (cl-remove-if-not (lambda (r) (memq (car r) reg-chars))
+ all-registers)
+ all-registers)))
+ (evil-with-view-list
+ :name "evil-registers"
+ :mode-name "Evil Registers"
+ :format
+ [("Register" 10 nil)
+ ("Value" 1000 nil)]
+ :entries
+ (cl-loop for (key . val) in display-regs
+ collect `(nil [,(char-to-string key)
+ ,(cond ((stringp val)
+ (replace-regexp-in-string "\n" "^J" val))
+ ((vectorp val)
+ (key-description val))
+ (t ""))])))))
+
+(evil-define-command evil-show-marks (mrks)
+ "Shows all marks.
+If MRKS is non-nil it should be a string and only registers
+corresponding to the characters of this string are shown."
+ :repeat nil
+ (interactive "<a>")
+ ;; To get markers and positions, we can't rely on 'global-mark-ring'
+ ;; provided by Emacs (although it will be much simpler and faster),
+ ;; because 'global-mark-ring' does not store mark characters, but
+ ;; only buffer name and position. Instead, 'evil-markers-alist' is
+ ;; used; this is list maintained by Evil for each buffer.
+ (let ((all-markers
+ ;; get global and local marks
+ (append (cl-remove-if (lambda (m)
+ (or (evil-global-marker-p (car m))
+ (not (markerp (cdr m)))))
+ evil-markers-alist)
+ (cl-remove-if (lambda (m)
+ (or (not (evil-global-marker-p (car m)))
+ (not (markerp (cdr m)))))
+ (default-value 'evil-markers-alist)))))
+ (when mrks
+ (setq mrks (string-to-list mrks))
+ (setq all-markers (cl-delete-if (lambda (m)
+ (not (member (car m) mrks)))
+ all-markers)))
+ ;; map marks to list of 4-tuples (char row col file)
+ (setq all-markers
+ (mapcar (lambda (m)
+ (with-current-buffer (marker-buffer (cdr m))
+ (save-excursion
+ (goto-char (cdr m))
+ (list (car m)
+ (line-number-at-pos (point))
+ (current-column)
+ (buffer-name)))))
+ all-markers))
+ (evil-with-view-list
+ :name "evil-marks"
+ :mode-name "Evil Marks"
+ :format [("Mark" 8 nil)
+ ("Line" 8 nil)
+ ("Column" 8 nil)
+ ("Buffer" 1000 nil)]
+ :entries (cl-loop for m in (sort all-markers (lambda (a b) (< (car a) (car b))))
+ collect `(nil [,(char-to-string (nth 0 m))
+ ,(number-to-string (nth 1 m))
+ ,(number-to-string (nth 2 m))
+ (,(nth 3 m))]))
+ :select-action #'evil--show-marks-select-action)))
+
+(defun evil--show-marks-select-action (entry)
+ (kill-buffer)
+ (switch-to-buffer (car (elt entry 3)))
+ (evil-goto-mark (string-to-char (elt entry 0))))
+
+(defun evil--parse-delmarks (to-be-parsed &optional parsed)
+ "Where TO-BE-PARSED can contain ranges in the form `x-y'.
+PARSED is a list of characters whose marks should be deleted.
+Like vim, on invalid input, preceeding valid input is still parsed."
+ (cl-destructuring-bind (&optional a b c &rest) to-be-parsed
+ (cond
+ ((null to-be-parsed) parsed)
+ ;; single mark...
+ ((and (not (eq ?- b)) (or (<= ?a a ?z) (<= ?A a ?Z) (<= ?0 a ?9)
+ (memq a '(?\" ?^ ?. ?\[ ?\] ?< ?>))))
+ (evil--parse-delmarks (cdr to-be-parsed) (cons a parsed)))
+ ;; range of marks...
+ ((and (eq ?- b) c (or (<= ?a a c ?z) (<= ?A a c ?Z) (<= ?0 a c ?9)))
+ (evil--parse-delmarks (nthcdr 3 to-be-parsed)
+ (append parsed (number-sequence a c))))
+ (t (progn (message "Invalid input: %s" (apply #'string (remove nil to-be-parsed)))
+ parsed)))))
+
+(evil-define-command evil-delete-marks (marks &optional force)
+ "MARKS is a string denoting all marks to be deleted. Mark names are
+either single characters or a range of characters in the form `x-y'.
+If FORCE is non-nil and MARKS is blank, all local marks except 0-9 are removed."
+ (interactive "<a><!>")
+ (let ((mark-chars (remove ?\s (append marks nil))))
+ (cond
+ ((and force mark-chars) (message "Invalid input"))
+ (mark-chars
+ (let* ((delmarks (evil--parse-delmarks mark-chars))
+ (delmarkp (lambda (m) (member (car m) delmarks))))
+ ;; delete all parsed marks...
+ (setq evil-markers-alist
+ (cl-remove-if delmarkp evil-markers-alist))
+ ;; ensure all parsed marks are deleted globally...
+ (set-default 'evil-markers-alist
+ (cl-remove-if delmarkp (default-value 'evil-markers-alist)))))
+ ;; delete local marks except 0-9...
+ (force (setq evil-markers-alist
+ (cl-remove-if-not (lambda (m) (<= ?0 (car m) ?9))
+ evil-markers-alist))))))
+
+(eval-when-compile (require 'ffap))
+(evil-define-command evil-find-file-at-point-with-line ()
+ "Opens the file at point and goes to position if present."
+ (require 'ffap)
+ (let ((fname (with-no-warnings (ffap-file-at-point))))
+ (unless fname
+ (user-error "File does not exist."))
+ (let* ((line-number-pattern ":\\([0-9]+\\)\\=" )
+ (line-and-column-numbers-pattern ":\\([0-9]+\\):\\([0-9]+\\)\\=")
+ (get-number (lambda (pattern match-number)
+ (save-excursion
+ (goto-char (cadr ffap-string-at-point-region))
+ (and (re-search-backward pattern (line-beginning-position) t)
+ (string-to-number (match-string match-number))))))
+ (line-number (or (funcall get-number line-and-column-numbers-pattern 1)
+ (funcall get-number line-number-pattern 1)))
+ (column-number (funcall get-number line-and-column-numbers-pattern 2)))
+ (message "line: %s, column: %s" line-number column-number)
+ (with-no-warnings (find-file-at-point fname))
+ (when line-number
+ (goto-char (point-min))
+ (forward-line (1- line-number))
+ (when column-number
+ (move-to-column (1- column-number)))))))
+
+(evil-define-command evil-find-file-at-point-visual ()
+ "Find the filename selected by the visual region.
+ Returns an error message if the file does not exist."
+ (require 'ffap)
+ (let ((region (buffer-substring (region-beginning) (region-end))))
+ (if (file-exists-p region)
+ (find-file-at-point region)
+ (user-error (format "Can't find file \"%s\" in path" region)))))
+
+(evil-ex-define-argument-type state
+ "Defines an argument type which can take state names."
+ :collection
+ (lambda (arg predicate flag)
+ (let ((completions
+ (append '("nil")
+ (mapcar #'(lambda (state)
+ (format "%s" (car state)))
+ evil-state-properties))))
+ (when arg
+ (cond
+ ((eq flag nil)
+ (try-completion arg completions predicate))
+ ((eq flag t)
+ (all-completions arg completions predicate))
+ ((eq flag 'lambda)
+ (test-completion arg completions predicate))
+ ((eq (car-safe flag) 'boundaries)
+ (cons 'boundaries
+ (completion-boundaries arg
+ completions
+ predicate
+ (cdr flag)))))))))
+
+(evil-define-interactive-code "<state>"
+ "A valid evil state."
+ :ex-arg state
+ (list (when (and (evil-ex-p) evil-ex-argument)
+ (intern evil-ex-argument))))
+
+;; TODO: should we merge this command with `evil-set-initial-state'?
+(evil-define-command evil-ex-set-initial-state (state)
+ "Set the initial state for the current major mode to STATE.
+This is the state the buffer comes up in. See `evil-set-initial-state'."
+ :repeat nil
+ (interactive "<state>")
+ (if (not (or (assq state evil-state-properties)
+ (null state)))
+ (user-error "State %s cannot be set as initial Evil state" state)
+ (let ((current-initial-state (evil-initial-state major-mode)))
+ (unless (eq current-initial-state state)
+ ;; only if we selected a new mode
+ (when (y-or-n-p (format "Major-mode `%s' has initial mode `%s'. \
+Change to `%s'? "
+ major-mode
+ (or current-initial-state "DEFAULT")
+ (or state "DEFAULT")))
+ (evil-set-initial-state major-mode state)
+ (when (y-or-n-p "Save setting in customization file? ")
+ (dolist (s (list current-initial-state state))
+ (when s
+ (let ((var (intern (format "evil-%s-state-modes" s))))
+ (customize-save-variable var (symbol-value var)))))))))))
+
+(evil-define-command evil-force-normal-state ()
+ "Switch to normal state without recording current command."
+ :repeat abort
+ :suppress-operator t
+ (evil-normal-state))
+
+(evil-define-motion evil-ex-search-next (count)
+ "Goes to the next occurrence."
+ :jump t
+ :type exclusive
+ (evil-ex-search count))
+
+(evil-define-motion evil-ex-search-previous (count)
+ "Goes the the previous occurrence."
+ :jump t
+ :type exclusive
+ (let ((evil-ex-search-direction
+ (if (eq evil-ex-search-direction 'backward) 'forward 'backward)))
+ (evil-ex-search count)))
+
+(defun evil-repeat-ex-search (flag)
+ "Called to record a search command.
+FLAG is either 'pre or 'post if the function is called before
+resp. after executing the command."
+ (cond
+ ((and (evil-operator-state-p) (eq flag 'pre))
+ (evil-repeat-record (this-command-keys))
+ (evil-clear-command-keys))
+ ((and (evil-operator-state-p) (eq flag 'post))
+ (evil-repeat-record (evil-ex-pattern-regex evil-ex-search-pattern))
+ ;; If it weren't for the fact that `exit-minibuffer' throws an `exit'
+ ;; tag, which bypasses the source of `this-command-keys', we'd be able
+ ;; to capture the key(s) in the post-command of the operator as usual.
+ ;; Fortunately however, `last-input-event' can see the key (by default, `return')
+ (unless (append (this-command-keys) nil)
+ (evil-repeat-record (vector last-input-event))))
+ (t (evil-repeat-motion flag))))
+
+(evil-define-motion evil-ex-search-forward (count)
+ "Starts a forward search."
+ :jump t
+ :type exclusive
+ :repeat evil-repeat-ex-search
+ (evil-ex-start-search 'forward count))
+
+(evil-define-motion evil-ex-search-backward (count)
+ "Starts a forward search."
+ :jump t
+ :repeat evil-repeat-ex-search
+ (evil-ex-start-search 'backward count))
+
+(evil-define-motion evil-ex-search-word-forward (count &optional symbol)
+ "Search for the next occurrence of word under the cursor."
+ :jump t
+ :type exclusive
+ (interactive (list (prefix-numeric-value current-prefix-arg)
+ evil-symbol-word-search))
+ (evil-ex-start-word-search nil 'forward count symbol))
+
+(evil-define-motion evil-ex-search-word-backward (count &optional symbol)
+ "Search for the next occurrence of word under the cursor."
+ :jump t
+ :type exclusive
+ (interactive (list (prefix-numeric-value current-prefix-arg)
+ evil-symbol-word-search))
+ (evil-ex-start-word-search nil 'backward count symbol))
+
+(evil-define-motion evil-ex-search-unbounded-word-forward (count &optional symbol)
+ "Search for the next occurrence of word under the cursor."
+ :jump t
+ :type exclusive
+ (interactive (list (prefix-numeric-value current-prefix-arg)
+ evil-symbol-word-search))
+ (evil-ex-start-word-search t 'forward count symbol))
+
+(evil-define-motion evil-ex-search-unbounded-word-backward (count &optional symbol)
+ "Search for the next occurrence of word under the cursor."
+ :jump t
+ :type exclusive
+ (interactive (list (prefix-numeric-value current-prefix-arg)
+ evil-symbol-word-search))
+ (evil-ex-start-word-search t 'backward count symbol))
+
+(defun evil-revert-reveal (open-spots)
+ "Unconditionally close overlays in OPEN-SPOTS in current window.
+Modified version of `reveal-close-old-overlays' from
+reveal.el. OPEN-SPOTS is a local version of `reveal-open-spots'."
+ (dolist (spot open-spots)
+ (let ((window (car spot))
+ (ol (cdr spot)))
+ (unless (eq window (selected-window))
+ (error "evil-revert-reveal: slot with wrong window"))
+ (let* ((inv (overlay-get ol 'reveal-invisible))
+ (open (or (overlay-get ol 'reveal-toggle-invisible)
+ (get inv 'reveal-toggle-invisible)
+ (overlay-get ol 'isearch-open-invisible-temporary))))
+ (if (and (overlay-start ol) ;Check it's still live.
+ open)
+ (condition-case err
+ (funcall open ol t)
+ (error (message "!!Reveal-hide (funcall %s %s t): %s !!"
+ open ol err)))
+ (overlay-put ol 'invisible inv))
+ ;; Remove the overlay from the list of open spots.
+ (overlay-put ol 'reveal-invisible nil)))))
+
+(evil-define-operator evil-ex-substitute
+ (beg end pattern replacement flags)
+ "The Ex substitute command.
+\[BEG,END]substitute/PATTERN/REPLACEMENT/FLAGS"
+ :repeat nil
+ :jump t
+ :move-point nil
+ :motion evil-line
+ (interactive "<r><s/>")
+ (evil-ex-nohighlight)
+ (unless pattern
+ (user-error "No pattern given"))
+ (setq replacement (or replacement ""))
+ (setq evil-ex-last-was-search nil)
+ (let* ((flags (append flags nil))
+ (count-only (memq ?n flags))
+ (confirm (and (memq ?c flags) (not count-only)))
+ (case-fold-search (evil-ex-pattern-ignore-case pattern))
+ (case-replace case-fold-search)
+ (evil-ex-substitute-regex (evil-ex-pattern-regex pattern))
+ (evil-ex-substitute-nreplaced 0)
+ (evil-ex-substitute-last-point (point))
+ (whole-line (evil-ex-pattern-whole-line pattern))
+ (evil-ex-substitute-overlay (make-overlay (point) (point)))
+ (orig-point-marker (move-marker (make-marker) (point)))
+ (end-marker (move-marker (make-marker) end))
+ (use-reveal confirm)
+ reveal-open-spots
+ zero-length-match
+ match-contains-newline
+ transient-mark-mode)
+ (setq evil-ex-substitute-pattern pattern
+ evil-ex-substitute-replacement replacement
+ evil-ex-substitute-flags flags
+ isearch-string evil-ex-substitute-regex)
+ (isearch-update-ring evil-ex-substitute-regex t)
+ (unwind-protect
+ (progn
+ (evil-ex-hl-change 'evil-ex-substitute pattern)
+ (overlay-put evil-ex-substitute-overlay 'face 'isearch)
+ (overlay-put evil-ex-substitute-overlay 'priority 1001)
+ (goto-char beg)
+ (catch 'exit-search
+ (while (re-search-forward evil-ex-substitute-regex end-marker t)
+ (when (not (and query-replace-skip-read-only
+ (text-property-any (match-beginning 0) (match-end 0) 'read-only t)))
+ (let ((match-str (match-string 0))
+ (match-beg (move-marker (make-marker) (match-beginning 0)))
+ (match-end (move-marker (make-marker) (match-end 0)))
+ (match-data (match-data)))
+ (goto-char match-beg)
+ (setq match-contains-newline
+ (string-match-p "\n" (buffer-substring-no-properties
+ match-beg match-end)))
+ (setq zero-length-match (= match-beg match-end))
+ (when (and (= match-end end-marker) (not match-contains-newline) (bolp))
+ ;; The range (beg end) includes the final newline which means
+ ;; end-marker is on one line down.
+ ;; With the exception of explicitly substituting newlines,
+ ;; we abort when the match ends here and it's an empty line
+ (throw 'exit-search t))
+ (setq evil-ex-substitute-last-point match-beg)
+ (if confirm
+ (let ((prompt
+ (format "Replace %s with %s (y/n/a/q/l/^E/^Y)? "
+ match-str
+ (evil-match-substitute-replacement
+ evil-ex-substitute-replacement
+ (not case-replace))))
+ (search-invisible t)
+ response)
+ (move-overlay evil-ex-substitute-overlay match-beg match-end)
+ ;; Simulate `reveal-mode'. `reveal-mode' uses
+ ;; `post-command-hook' but that won't work here.
+ (when use-reveal
+ (reveal-post-command))
+ (catch 'exit-read-char
+ (while (setq response (read-char prompt))
+ (when (member response '(?y ?a ?l))
+ (unless count-only
+ (set-match-data match-data)
+ (evil-replace-match evil-ex-substitute-replacement
+ (not case-replace)))
+ (setq evil-ex-substitute-nreplaced
+ (1+ evil-ex-substitute-nreplaced))
+ (evil-ex-hl-set-region 'evil-ex-substitute
+ (save-excursion
+ (forward-line)
+ (point))
+ (evil-ex-hl-get-max
+ 'evil-ex-substitute)))
+ (cl-case response
+ ((?y ?n) (throw 'exit-read-char t))
+ (?a (setq confirm nil)
+ (throw 'exit-read-char t))
+ ((?q ?l ?\C-\[) (throw 'exit-search t))
+ (?\C-e (evil-scroll-line-down 1))
+ (?\C-y (evil-scroll-line-up 1))))))
+ (setq evil-ex-substitute-nreplaced
+ (1+ evil-ex-substitute-nreplaced))
+ (unless count-only
+ (set-match-data match-data)
+ (evil-replace-match evil-ex-substitute-replacement
+ (not case-replace))))
+ (goto-char match-end)
+ (cond ((>= (point) end-marker)
+ ;; Don't want to perform multiple replacements at the end
+ ;; of the search region.
+ (throw 'exit-search t))
+ ((and (not whole-line)
+ (not match-contains-newline))
+ (forward-line)
+ ;; forward-line just moves to the end of the line on the
+ ;; last line of the buffer.
+ (when (or (eobp)
+ (> (point) end-marker))
+ (throw 'exit-search t)))
+ ;; For zero-length matches check to see if point won't
+ ;; move next time. This is a problem when matching the
+ ;; regexp "$" because we can enter an infinite loop,
+ ;; repeatedly matching the same character
+ ((and zero-length-match
+ (let ((pnt (point)))
+ (save-excursion
+ (and
+ (re-search-forward
+ evil-ex-substitute-regex end-marker t)
+ (= pnt (point))))))
+ (if (or (eobp)
+ (>= (point) end-marker))
+ (throw 'exit-search t)
+ (forward-char)))))))))
+ (evil-ex-delete-hl 'evil-ex-substitute)
+ (delete-overlay evil-ex-substitute-overlay)
+
+ (if count-only
+ (goto-char orig-point-marker)
+ (goto-char evil-ex-substitute-last-point))
+
+ (move-marker orig-point-marker nil)
+ (move-marker end-marker nil)
+
+ (when use-reveal
+ (evil-revert-reveal reveal-open-spots)))
+
+ (message "%s %d occurrence%s"
+ (if count-only "Found" "Replaced")
+ evil-ex-substitute-nreplaced
+ (if (/= evil-ex-substitute-nreplaced 1) "s" ""))
+ (evil-first-non-blank)))
+
+(evil-define-operator evil-ex-repeat-substitute
+ (beg end flags)
+ "Repeat last substitute command.
+This is the same as :s//~/"
+ :repeat nil
+ :jump t
+ :move-point nil
+ :motion evil-line
+ (interactive "<r><a>")
+ (apply #'evil-ex-substitute beg end
+ (evil-ex-get-substitute-info (concat "//~/" flags))))
+
+(evil-define-operator evil-ex-repeat-substitute-with-flags
+ (beg end flags)
+ "Repeat last substitute command with last flags.
+This is the same as :s//~/&"
+ :repeat nil
+ :jump t
+ :move-point nil
+ :motion evil-line
+ (interactive "<r><a>")
+ (apply #'evil-ex-substitute beg end
+ (evil-ex-get-substitute-info (concat "//~/&" flags))))
+
+(evil-define-operator evil-ex-repeat-substitute-with-search
+ (beg end flags)
+ "Repeat last substitute command with last search pattern.
+This is the same as :s//~/r"
+ :repeat nil
+ :jump t
+ :move-point nil
+ :motion evil-line
+ (interactive "<r><a>")
+ (apply #'evil-ex-substitute beg end
+ (evil-ex-get-substitute-info (concat "//~/r" flags))))
+
+(evil-define-operator evil-ex-repeat-substitute-with-search-and-flags
+ (beg end flags)
+ "Repeat last substitute command with last search pattern and last flags.
+This is the same as :s//~/&r"
+ :repeat nil
+ :jump t
+ :move-point nil
+ :motion evil-line
+ (interactive "<r><a>")
+ (apply #'evil-ex-substitute beg end
+ (evil-ex-get-substitute-info (concat "//~/&r" flags))))
+
+(evil-define-operator evil-ex-repeat-global-substitute ()
+ "Repeat last substitute command on the whole buffer.
+This is the same as :%s//~/&"
+ :repeat nil
+ :jump t
+ :move-point nil
+ :motion evil-line
+ (interactive)
+ (apply #'evil-ex-substitute (point-min) (point-max)
+ (evil-ex-get-substitute-info (concat "//~/&"))))
+
+(evil-define-operator evil-ex-global
+ (beg end pattern command &optional invert)
+ "The Ex global command.
+\[BEG,END]global[!]/PATTERN/COMMAND"
+ :motion mark-whole-buffer
+ :move-point nil
+ (interactive "<r><g/><!>")
+ (unless pattern
+ (user-error "No pattern given"))
+ (unless command
+ (user-error "No command given"))
+ ;; TODO: `evil-ex-make-substitute-pattern' should be executed so
+ ;; :substitute can re-use :global's pattern depending on its `r'
+ ;; flag. This isn't supported currently but should be simple to add
+ (evil-with-single-undo
+ (let ((case-fold-search
+ (eq (evil-ex-regex-case pattern evil-ex-search-case) 'insensitive))
+ (command-form (evil-ex-parse command))
+ (transient-mark-mode transient-mark-mode)
+ (deactivate-mark deactivate-mark)
+ match markers)
+ (when (and pattern command)
+ (when evil-ex-search-vim-style-regexp
+ (setq pattern (evil-transform-vim-style-regexp pattern)))
+ (setq isearch-string pattern)
+ (isearch-update-ring pattern t)
+ (goto-char beg)
+ (evil-move-beginning-of-line)
+ (while (< (point) end)
+ (setq match (re-search-forward pattern (line-end-position) t))
+ (when (or (and match (not invert))
+ (and invert (not match)))
+ (push (move-marker (make-marker)
+ (or (and match (match-beginning 0))
+ (line-beginning-position)))
+ markers))
+ (forward-line))
+ (setq markers (nreverse markers))
+ (unwind-protect
+ (dolist (marker markers)
+ (goto-char marker)
+ (eval command-form))
+ ;; ensure that all markers are deleted afterwards,
+ ;; even in the event of failure
+ (dolist (marker markers)
+ (set-marker marker nil)))))))
+
+(evil-define-operator evil-ex-global-inverted
+ (beg end pattern command &optional invert)
+ "The Ex vglobal command.
+\[BEG,END]vglobal/PATTERN/COMMAND"
+ :motion mark-whole-buffer
+ :move-point nil
+ (interactive "<r><g/><!>")
+ (evil-ex-global beg end pattern command (not invert)))
+
+(evil-define-operator evil-ex-normal (beg end commands)
+ "The Ex normal command.
+Execute the argument as normal command on each line in the
+range. The given argument is passed straight to
+`execute-kbd-macro'. The default is the current line."
+ :motion evil-line
+ (interactive "<r><a>")
+ (evil-with-single-undo
+ (let (markers evil-ex-current-buffer prefix-arg current-prefix-arg)
+ (goto-char beg)
+ (while
+ (and (< (point) end)
+ (progn
+ (push (move-marker (make-marker) (line-beginning-position))
+ markers)
+ (and (= (forward-line) 0) (bolp)))))
+ (setq markers (nreverse markers))
+ (deactivate-mark)
+ (evil-force-normal-state)
+ ;; replace ^[ by escape
+ (setq commands
+ (vconcat
+ (mapcar #'(lambda (ch) (if (equal ch ?) 'escape ch))
+ (append commands nil))))
+ (dolist (marker markers)
+ (goto-char marker)
+ (condition-case nil
+ (execute-kbd-macro commands)
+ (error nil))
+ (evil-force-normal-state)
+ (set-marker marker nil)))))
+
+(evil-define-command evil-goto-char (position)
+ "Go to POSITION in the buffer.
+Default position is the beginning of the buffer."
+ :jump t
+ (interactive "<N>")
+ (let ((position (evil-normalize-position
+ (or position (point-min)))))
+ (goto-char position)))
+
+(evil-define-operator evil-ex-line-number (beg end)
+ "Print the last line number."
+ :motion mark-whole-buffer
+ :move-point nil
+ (interactive "<r>")
+ (message "%d" (count-lines (point-min) end)))
+
+(evil-define-command evil-show-file-info ()
+ "Shows basic file information."
+ (let* ((nlines (count-lines (point-min) (point-max)))
+ (curr (line-number-at-pos (point)))
+ (perc (if (> nlines 0)
+ (format "%d%%" (* (/ (float curr) (float nlines)) 100.0))
+ "No lines in buffer"))
+ (file (buffer-file-name (buffer-base-buffer)))
+ (writable (and file (file-writable-p file)))
+ (readonly (if (and file (not writable)) "[readonly] " "")))
+ (if file
+ (message "\"%s\" %d %slines --%s--" file nlines readonly perc)
+ (message "%d lines --%s--" nlines perc))))
+
+(defvar sort-fold-case)
+(evil-define-operator evil-ex-sort (beg end &optional options reverse)
+ "The Ex sort command.
+\[BEG,END]sort[!] [i][u]
+The following additional options are supported:
+
+ * i ignore case
+ * u remove duplicate lines
+
+The 'bang' argument means to sort in reverse order."
+ :motion mark-whole-buffer
+ :move-point nil
+ (interactive "<r><a><!>")
+ (let ((beg (copy-marker beg))
+ (end (copy-marker end))
+ sort-fold-case uniq)
+ (dolist (opt (append options nil))
+ (cond
+ ((eq opt ?i) (setq sort-fold-case t))
+ ((eq opt ?u) (setq uniq t))
+ (t (user-error "Unsupported sort option: %c" opt))))
+ (sort-lines reverse beg end)
+ (when uniq
+ (let (line prev-line)
+ (goto-char beg)
+ (while (and (< (point) end) (not (eobp)))
+ (setq line (buffer-substring-no-properties
+ (line-beginning-position)
+ (line-end-position)))
+ (if (and (stringp prev-line)
+ (eq t (compare-strings line nil nil
+ prev-line nil nil
+ sort-fold-case)))
+ (delete-region (progn (forward-line 0) (point))
+ (progn (forward-line 1) (point)))
+ (setq prev-line line)
+ (forward-line 1)))))
+ (goto-char beg)
+ (set-marker beg nil)
+ (set-marker end nil)))
+
+;;; Window navigation
+
+(defmacro evil-save-side-windows (&rest body)
+ "Toggle side windows, evaluate BODY, restore side windows."
+ (declare (indent defun) (debug (&rest form)))
+ (let ((sides (make-symbol "sidesvar")))
+ `(let ((,sides (and (functionp 'window-toggle-side-windows)
+ (window-with-parameter 'window-side))))
+ (when ,sides
+ (window-toggle-side-windows))
+ (unwind-protect
+ (progn ,@body)
+ (when ,sides
+ (window-toggle-side-windows))))))
+
+(defun evil-resize-window (new-size &optional horizontal)
+ "Set the current window's width or height to NEW-SIZE.
+If HORIZONTAL is non-nil the width of the window is changed,
+otherwise its height is changed."
+ (let ((count (- new-size (if horizontal (window-width) (window-height)))))
+ (enlarge-window count horizontal)))
+
+(defun evil-move-window (side)
+ "Move the `selected-window' to SIDE.
+The state of the `selected-window' is saved along with the state
+of the window tree consisting of all the other windows. Then, all
+windows are deleted, the remaining window is split according to
+SIDE, the state of the window at SIDE is replaced with the saved
+state of the `selected-window', and, finally, the state of the
+saved window tree is reconstructed on the opposite side.
+
+SIDE has the same meaning as in `split-window'.
+
+Note, this function only operates on the window tree rooted in
+the frame's main window and effectively preserves any side
+windows \(i.e. windows with a valid window-side window
+parameter\)."
+ (evil-save-side-windows
+ (unless (one-window-p)
+ (save-excursion
+ (let ((w (window-state-get (selected-window))))
+ (delete-window)
+ (let ((wtree (window-state-get)))
+ (delete-other-windows)
+ (let ((subwin (selected-window))
+ ;; NOTE: SIDE is new in Emacs 24
+ (newwin (split-window nil nil side)))
+ (window-state-put wtree subwin)
+ (window-state-put w newwin)
+ (select-window newwin)))))
+ (balance-windows))))
+
+(defun evil-alternate-buffer (&optional window)
+ "Return the last buffer WINDOW has displayed other than the
+current one (equivalent to Vim's alternate buffer).
+
+Returns the first item in `window-prev-buffers' that isn't
+`window-buffer' of WINDOW."
+ ;; If the last buffer visited has been killed, then `window-prev-buffers'
+ ;; returns a list with `current-buffer' at the head, we account for this
+ ;; possibility.
+ (let* ((prev-buffers (window-prev-buffers))
+ (head (car prev-buffers)))
+ (if (eq (car head) (window-buffer window))
+ (cadr prev-buffers)
+ head)))
+
+(evil-define-command evil-switch-to-windows-last-buffer ()
+ "Switch to current windows last open buffer."
+ :repeat nil
+ (let ((previous-place (evil-alternate-buffer)))
+ (when previous-place
+ (switch-to-buffer (car previous-place))
+ (goto-char (car (last previous-place))))))
+
+(evil-define-command evil-window-delete ()
+ "Deletes the current window.
+If `evil-auto-balance-windows' is non-nil then all children of
+the deleted window's parent window are rebalanced."
+ (let ((p (window-parent)))
+ (delete-window)
+ (when evil-auto-balance-windows
+ ;; balance-windows raises an error if the parent does not have
+ ;; any further children (then rebalancing is not necessary anyway)
+ (condition-case nil
+ (balance-windows p)
+ (error)))))
+
+(evil-define-command evil-window-split (&optional count file)
+ "Splits the current window horizontally, COUNT lines height,
+editing a certain FILE. The new window will be created below
+when `evil-split-window-below' is non-nil. If COUNT and
+`evil-auto-balance-windows' are both non-nil then all children
+of the parent of the splitted window are rebalanced."
+ :repeat nil
+ (interactive "P<f>")
+ (select-window
+ (split-window (selected-window) (when count (- count))
+ (if evil-split-window-below 'below 'above)))
+ (when (and (not count) evil-auto-balance-windows)
+ (balance-windows (window-parent)))
+ (when file
+ (evil-edit file)))
+
+(evil-define-command evil-window-vsplit (&optional count file)
+ "Splits the current window vertically, COUNT columns width,
+editing a certain FILE. The new window will be created to the
+right when `evil-vsplit-window-right' is non-nil. If COUNT and
+`evil-auto-balance-windows'are both non-nil then all children
+of the parent of the splitted window are rebalanced."
+ :repeat nil
+ (interactive "P<f>")
+ (select-window
+ (split-window (selected-window) (when count (- count))
+ (if evil-vsplit-window-right 'right 'left)))
+ (when (and (not count) evil-auto-balance-windows)
+ (balance-windows (window-parent)))
+ (when file
+ (evil-edit file)))
+
+(evil-define-command evil-split-buffer (buffer)
+ "Splits window and switches to another buffer."
+ :repeat nil
+ (interactive "<b>")
+ (evil-window-split)
+ (evil-buffer buffer))
+
+(evil-define-command evil-split-next-buffer (&optional count)
+ "Splits the window and goes to the COUNT-th next buffer in the buffer list."
+ :repeat nil
+ (interactive "p")
+ (evil-window-split)
+ (evil-next-buffer count))
+
+(evil-define-command evil-split-prev-buffer (&optional count)
+ "Splits window and goes to the COUNT-th prev buffer in the buffer list."
+ :repeat nil
+ (interactive "p")
+ (evil-window-split)
+ (evil-prev-buffer count))
+
+(evil-define-command evil-window-left (count)
+ "Move the cursor to new COUNT-th window left of the current one."
+ :repeat nil
+ (interactive "p")
+ (dotimes (_ count)
+ (windmove-left)))
+
+(evil-define-command evil-window-right (count)
+ "Move the cursor to new COUNT-th window right of the current one."
+ :repeat nil
+ (interactive "p")
+ (dotimes (_ count)
+ (windmove-right)))
+
+(evil-define-command evil-window-up (count)
+ "Move the cursor to new COUNT-th window above the current one."
+ :repeat nil
+ (interactive "p")
+ (dotimes (_ (or count 1))
+ (windmove-up)))
+
+(evil-define-command evil-window-down (count)
+ "Move the cursor to new COUNT-th window below the current one."
+ :repeat nil
+ (interactive "p")
+ (dotimes (_ (or count 1))
+ (windmove-down)))
+
+(evil-define-command evil-window-bottom-right ()
+ "Move the cursor to bottom-right window."
+ :repeat nil
+ (let ((last-sibling (frame-root-window)))
+ (while (and last-sibling (not (window-live-p last-sibling)))
+ (setq last-sibling (window-last-child last-sibling)))
+ (when last-sibling
+ (select-window last-sibling))))
+
+(evil-define-command evil-window-top-left ()
+ "Move the cursor to top-left window."
+ :repeat nil
+ (let ((first-child (window-child (frame-root-window))))
+ (while (and first-child (not (window-live-p first-child)))
+ (setq first-child (window-child first-child)))
+ (when first-child
+ (select-window
+ first-child))))
+
+(evil-define-command evil-window-mru ()
+ "Move the cursor to the previous (last accessed) buffer in another window.
+More precisely, it selects the most recently used buffer that is
+shown in some other window, preferably of the current frame, and
+is different from the current one."
+ :repeat nil
+ (catch 'done
+ (dolist (buf (buffer-list (selected-frame)))
+ (let ((win (get-buffer-window buf)))
+ (when (and (not (eq buf (current-buffer)))
+ win
+ (not (eq win (selected-window))))
+ (select-window win)
+ (throw 'done nil))))))
+
+(evil-define-command evil-window-next (count)
+ "Move the cursor to the next window in the cyclic order.
+With COUNT go to the count-th window in the order starting from
+top-left."
+ :repeat nil
+ (interactive "<c>")
+ (if (not count)
+ (select-window (next-window))
+ (evil-window-top-left)
+ (other-window (1- count))))
+
+(evil-define-command evil-window-prev (count)
+ "Move the cursor to the previous window in the cyclic order.
+With COUNT go to the count-th window in the order starting from
+top-left."
+ :repeat nil
+ (interactive "<c>")
+ (if (not count)
+ (select-window (previous-window))
+ (evil-window-top-left)
+ (other-window (1- count))))
+
+(evil-define-command evil-window-new (count file)
+ "Splits the current window horizontally
+and opens a new buffer or edits a certain FILE."
+ :repeat nil
+ (interactive "P<f>")
+ (let ((new-window (split-window (selected-window) (when count (- count))
+ (if evil-split-window-below 'below 'above))))
+ (when (and (not count) evil-auto-balance-windows)
+ (balance-windows (window-parent)))
+ (let ((buffer (generate-new-buffer "*new*")))
+ (set-window-buffer new-window buffer)
+ (select-window new-window)
+ (with-current-buffer buffer
+ (funcall (default-value 'major-mode))))
+ (when file
+ (evil-edit file))))
+
+(evil-define-command evil-window-vnew (count file)
+ "Splits the current window vertically
+and opens a new buffer name or edits a certain FILE."
+ :repeat nil
+ (interactive "P<f>")
+ (let ((new-window (split-window (selected-window) (when count (- count))
+ (if evil-vsplit-window-right 'right 'left))))
+ (when (and (not count) evil-auto-balance-windows)
+ (balance-windows (window-parent)))
+ (let ((buffer (generate-new-buffer "*new*")))
+ (set-window-buffer new-window buffer)
+ (select-window new-window)
+ (with-current-buffer buffer
+ (funcall (default-value 'major-mode))))
+ (when file
+ (evil-edit file))))
+
+(evil-define-command evil-buffer-new (count file)
+ "Creates a new buffer replacing the current window, optionally
+ editing a certain FILE"
+ :repeat nil
+ (interactive "P<f>")
+ (if file
+ (evil-edit file)
+ (let ((buffer (generate-new-buffer "*new*")))
+ (set-window-buffer nil buffer)
+ (with-current-buffer buffer
+ (funcall (default-value 'major-mode))))))
+
+(evil-define-command evil-window-increase-height (count)
+ "Increase current window height by COUNT."
+ :repeat nil
+ (interactive "p")
+ (evil-resize-window (+ (window-height) count)))
+
+(evil-define-command evil-window-decrease-height (count)
+ "Decrease current window height by COUNT."
+ :repeat nil
+ (interactive "p")
+ (evil-resize-window (- (window-height) count)))
+
+(evil-define-command evil-window-increase-width (count)
+ "Increase current window width by COUNT."
+ :repeat nil
+ (interactive "p")
+ (evil-resize-window (+ (window-width) count) t))
+
+(evil-define-command evil-window-decrease-width (count)
+ "Decrease current window width by COUNT."
+ :repeat nil
+ (interactive "p")
+ (evil-resize-window (- (window-width) count) t))
+
+(evil-define-command evil-window-set-height (count)
+ "Sets the height of the current window to COUNT."
+ :repeat nil
+ (interactive "<c>")
+ (evil-resize-window (or count (frame-height)) nil))
+
+(evil-define-command evil-window-set-width (count)
+ "Sets the width of the current window to COUNT."
+ :repeat nil
+ (interactive "<c>")
+ (evil-resize-window (or count (frame-width)) t))
+
+(evil-define-command evil-ex-resize (arg)
+ "The ex :resize command.
+
+If ARG is a signed positive integer, increase the current window
+height by ARG.
+
+If ARG is a signed negative integer, decrease the current window
+height by ARG.
+
+If ARG is a positive integer without explicit sign, set the current
+window height to ARG.
+
+If ARG is empty, maximize the current window height."
+ (interactive "<a>")
+ (if (or (not arg) (= 0 (length arg)))
+ (evil-window-set-height nil)
+ (let ((n (string-to-number arg)))
+ (if (> n 0)
+ (if (= ?+ (aref arg 0))
+ (evil-window-increase-height n)
+ (evil-window-set-height n))
+ (evil-window-decrease-height (- n))))))
+
+(evil-define-command evil-window-rotate-upwards ()
+ "Rotates the windows according to the current cyclic ordering."
+ :repeat nil
+ (evil-save-side-windows
+ (let ((wlist (window-list))
+ (slist (mapcar #'window-state-get (window-list))))
+ (setq slist (append (cdr slist) (list (car slist))))
+ (while (and wlist slist)
+ (window-state-put (car slist) (car wlist))
+ (setq wlist (cdr wlist)
+ slist (cdr slist)))
+ (select-window (car (last (window-list)))))))
+
+(evil-define-command evil-window-rotate-downwards ()
+ "Rotates the windows according to the current cyclic ordering."
+ :repeat nil
+ (evil-save-side-windows
+ (let ((wlist (window-list))
+ (slist (mapcar #'window-state-get (window-list))))
+ (setq slist (append (last slist) slist))
+ (while (and wlist slist)
+ (window-state-put (car slist) (car wlist))
+ (setq wlist (cdr wlist)
+ slist (cdr slist)))
+ (select-window (cadr (window-list))))))
+
+(evil-define-command evil-window-move-very-top ()
+ "Closes the current window, splits the upper-left one horizontally
+and redisplays the current buffer there."
+ :repeat nil
+ (evil-move-window 'above))
+
+(evil-define-command evil-window-move-far-left ()
+ "Closes the current window, splits the upper-left one vertically
+and redisplays the current buffer there."
+ :repeat nil
+ (evil-move-window 'left))
+
+(evil-define-command evil-window-move-far-right ()
+ "Closes the current window, splits the lower-right one vertically
+and redisplays the current buffer there."
+ :repeat nil
+ (evil-move-window 'right))
+
+(evil-define-command evil-window-move-very-bottom ()
+ "Closes the current window, splits the lower-right one horizontally
+and redisplays the current buffer there."
+ :repeat nil
+ (evil-move-window 'below))
+
+;;; Mouse handling
+
+;; Large parts of this code are taken from mouse.el which is
+;; distributed with GNU Emacs
+(defun evil-mouse-drag-region (start-event)
+ "Set the region to the text that the mouse is dragged over.
+Highlight the drag area as you move the mouse.
+This must be bound to a button-down mouse event.
+
+If the click is in the echo area, display the `*Messages*' buffer.
+
+START-EVENT should be the event that started the drag."
+ (interactive "e")
+ ;; Give temporary modes such as isearch a chance to turn off.
+ (run-hooks 'mouse-leave-buffer-hook)
+ (evil-mouse-drag-track start-event t))
+(evil-set-command-property 'evil-mouse-drag-region :keep-visual t)
+
+(defun evil-mouse-drag-track (start-event &optional
+ do-mouse-drag-region-post-process)
+ "Track mouse drags by highlighting area between point and cursor.
+The region will be defined with mark and point.
+DO-MOUSE-DRAG-REGION-POST-PROCESS should only be used by
+`mouse-drag-region'."
+ (mouse-minibuffer-check start-event)
+ (setq mouse-selection-click-count-buffer (current-buffer))
+ (deactivate-mark)
+ (let* ((scroll-margin 0) ; Avoid margin scrolling (Bug#9541).
+ (original-window (selected-window))
+ ;; We've recorded what we needed from the current buffer and
+ ;; window, now let's jump to the place of the event, where things
+ ;; are happening.
+ (_ (mouse-set-point start-event))
+ (echo-keystrokes 0)
+ (start-posn (event-start start-event))
+ (start-point (posn-point start-posn))
+ (start-window (posn-window start-posn))
+ (start-window-start (window-start start-window))
+ (start-hscroll (window-hscroll start-window))
+ (bounds (window-edges start-window))
+ (make-cursor-line-fully-visible nil)
+ (top (nth 1 bounds))
+ (bottom (if (or (window-minibuffer-p start-window)
+ (not mode-line-format))
+ (nth 3 bounds)
+ ;; Don't count the mode line.
+ (1- (nth 3 bounds))))
+ (on-link (and mouse-1-click-follows-link
+ (or mouse-1-click-in-non-selected-windows
+ (eq start-window original-window))
+ ;; Use start-point before the intangibility
+ ;; treatment, in case we click on a link inside an
+ ;; intangible text.
+ (mouse-on-link-p start-posn)))
+ (click-count (1- (event-click-count start-event)))
+ (remap-double-click (and on-link
+ (eq mouse-1-click-follows-link 'double)
+ (= click-count 1)))
+ ;; Suppress automatic hscrolling, because that is a nuisance
+ ;; when setting point near the right fringe (but see below).
+ (auto-hscroll-mode-saved auto-hscroll-mode)
+ (auto-hscroll-mode nil)
+ event end end-point)
+
+ (setq mouse-selection-click-count click-count)
+ ;; In case the down click is in the middle of some intangible text,
+ ;; use the end of that text, and put it in START-POINT.
+ (if (< (point) start-point)
+ (goto-char start-point))
+ (setq start-point (point))
+ (if remap-double-click
+ (setq click-count 0))
+
+ (setq click-count (mod click-count 4))
+
+ ;; activate correct visual state
+ (let ((range (evil-mouse-start-end start-point start-point click-count)))
+ (set-mark (nth 0 range))
+ (goto-char (nth 1 range)))
+
+ (cond
+ ((= click-count 0)
+ (when (evil-visual-state-p) (evil-exit-visual-state)))
+ ((= click-count 1)
+ (evil-visual-char)
+ (evil-visual-post-command))
+ ((= click-count 2)
+ (evil-visual-line)
+ (evil-visual-post-command))
+ ((= click-count 3)
+ (evil-visual-block)
+ (evil-visual-post-command)))
+
+ ;; Track the mouse until we get a non-movement event.
+ (track-mouse
+ (while (progn
+ (setq event (read-key))
+ (or (mouse-movement-p event)
+ (memq (car-safe event) '(switch-frame select-window))))
+ (unless (evil-visual-state-p)
+ (cond
+ ((= click-count 0) (evil-visual-char))
+ ((= click-count 1) (evil-visual-char))
+ ((= click-count 2) (evil-visual-line))
+ ((= click-count 3) (evil-visual-block))))
+
+ (evil-visual-pre-command)
+ (unless (memq (car-safe event) '(switch-frame select-window))
+ ;; Automatic hscrolling did not occur during the call to
+ ;; `read-event'; but if the user subsequently drags the
+ ;; mouse, go ahead and hscroll.
+ (let ((auto-hscroll-mode auto-hscroll-mode-saved))
+ (redisplay))
+ (setq end (event-end event)
+ end-point (posn-point end))
+ (if (and (eq (posn-window end) start-window)
+ (integer-or-marker-p end-point))
+ (evil-mouse--drag-set-mark-and-point start-point
+ end-point click-count)
+ (let ((mouse-row (cdr (cdr (mouse-position)))))
+ (cond
+ ((null mouse-row))
+ ((< mouse-row top)
+ (mouse-scroll-subr start-window (- mouse-row top)
+ nil start-point))
+ ((>= mouse-row bottom)
+ (mouse-scroll-subr start-window (1+ (- mouse-row bottom))
+ nil start-point))))))
+ (evil-visual-post-command)))
+
+ ;; Handle the terminating event if possible.
+ (when (consp event)
+ ;; Ensure that point is on the end of the last event.
+ (when (and (setq end-point (posn-point (event-end event)))
+ (eq (posn-window end) start-window)
+ (integer-or-marker-p end-point)
+ (/= start-point end-point))
+ (evil-mouse--drag-set-mark-and-point start-point
+ end-point click-count))
+
+ ;; Find its binding.
+ (let* ((fun (key-binding (vector (car event))))
+ (do-multi-click (and (> (event-click-count event) 0)
+ (functionp fun)
+ (not (memq fun '(mouse-set-point
+ mouse-set-region))))))
+ (if (and (or (/= (mark) (point))
+ (= click-count 1) ; word selection
+ (and (memq (evil-visual-type) '(line block))))
+ (not do-multi-click))
+
+ ;; If point has moved, finish the drag.
+ (let (last-command this-command)
+ (and mouse-drag-copy-region
+ do-mouse-drag-region-post-process
+ (let (deactivate-mark)
+ (evil-visual-expand-region)
+ (copy-region-as-kill (mark) (point))
+ (evil-visual-contract-region))))
+
+ ;; If point hasn't moved, run the binding of the
+ ;; terminating up-event.
+ (if do-multi-click
+ (goto-char start-point)
+ (deactivate-mark))
+ (when (and (functionp fun)
+ (= start-hscroll (window-hscroll start-window))
+ ;; Don't run the up-event handler if the window
+ ;; start changed in a redisplay after the
+ ;; mouse-set-point for the down-mouse event at
+ ;; the beginning of this function. When the
+ ;; window start has changed, the up-mouse event
+ ;; contains a different position due to the new
+ ;; window contents, and point is set again.
+ (or end-point
+ (= (window-start start-window)
+ start-window-start)))
+ (when (and on-link
+ (= start-point (point))
+ (evil-mouse--remap-link-click-p start-event event))
+ ;; If we rebind to mouse-2, reselect previous selected
+ ;; window, so that the mouse-2 event runs in the same
+ ;; situation as if user had clicked it directly. Fixes
+ ;; the bug reported by juri@jurta.org on 2005-12-27.
+ (if (or (vectorp on-link) (stringp on-link))
+ (setq event (aref on-link 0))
+ (select-window original-window)
+ (setcar event 'mouse-2)
+ ;; If this mouse click has never been done by the
+ ;; user, it doesn't have the necessary property to be
+ ;; interpreted correctly.
+ (put 'mouse-2 'event-kind 'mouse-click)))
+ (push event unread-command-events)))))))
+
+;; This function is a plain copy of `mouse--drag-set-mark-and-point',
+;; which is only available in Emacs 24
+(defun evil-mouse--drag-set-mark-and-point (start click click-count)
+ (let* ((range (evil-mouse-start-end start click click-count))
+ (beg (nth 0 range))
+ (end (nth 1 range)))
+ (cond ((eq (mark) beg)
+ (goto-char end))
+ ((eq (mark) end)
+ (goto-char beg))
+ ((< click (mark))
+ (set-mark end)
+ (goto-char beg))
+ (t
+ (set-mark beg)
+ (goto-char end)))))
+
+;; This function is a plain copy of `mouse--remap-link-click-p',
+;; which is only available in Emacs 23
+(defun evil-mouse--remap-link-click-p (start-event end-event)
+ (or (and (eq mouse-1-click-follows-link 'double)
+ (= (event-click-count start-event) 2))
+ (and
+ (not (eq mouse-1-click-follows-link 'double))
+ (= (event-click-count start-event) 1)
+ (= (event-click-count end-event) 1)
+ (or (not (integerp mouse-1-click-follows-link))
+ (let ((t0 (posn-timestamp (event-start start-event)))
+ (t1 (posn-timestamp (event-end end-event))))
+ (and (integerp t0) (integerp t1)
+ (if (> mouse-1-click-follows-link 0)
+ (<= (- t1 t0) mouse-1-click-follows-link)
+ (< (- t0 t1) mouse-1-click-follows-link))))))))
+
+(defun evil-mouse-start-end (start end mode)
+ "Return a list of region bounds based on START and END according to MODE.
+If MODE is not 1 then set point to (min START END), mark to (max
+START END). If MODE is 1 then set point to start of word at (min
+START END), mark to end of word at (max START END)."
+ (evil-sort start end)
+ (setq mode (mod mode 4))
+ (if (/= mode 1) (list start end)
+ (list
+ (save-excursion
+ (goto-char (min (point-max) (1+ start)))
+ (if (zerop (forward-thing evil-mouse-word -1))
+ (let ((bpnt (point)))
+ (forward-thing evil-mouse-word +1)
+ (if (> (point) start) bpnt (point)))
+ (point-min)))
+ (save-excursion
+ (goto-char end)
+ (1-
+ (if (zerop (forward-thing evil-mouse-word +1))
+ (let ((epnt (point)))
+ (forward-thing evil-mouse-word -1)
+ (if (<= (point) end) epnt (point)))
+ (point-max)))))))
+
+;;; State switching
+
+(evil-define-command evil-exit-emacs-state (&optional buffer message)
+ "Exit Emacs state.
+Changes the state to the previous state, or to Normal state
+if the previous state was Emacs state."
+ :keep-visual t
+ :suppress-operator t
+ (interactive '(nil t))
+ (with-current-buffer (or buffer (current-buffer))
+ (when (evil-emacs-state-p)
+ (evil-change-to-previous-state buffer message)
+ (when (evil-emacs-state-p)
+ (evil-normal-state (and message 1))))))
+
+(defvar evil-execute-normal-keys nil
+ "The keys used to invoke the current `evil-execute-in-normal-state'.
+Can be used to detect if we are currently in that quasi-state.
+With current bindings, it will be \\<evil-insert-state-map>\\[evil-execute-in-normal-state]")
+
+(evil-define-local-var evil--execute-normal-eol-pos nil
+ "Vim has special behaviour for executing in normal state at eol.
+This var stores the eol position, so it can be restored when necessary.")
+
+(defun evil--restore-repeat-hooks ()
+ "No insert-state repeat info is recorded after executing in normal state.
+Restore the disabled repeat hooks on insert-state exit."
+ (evil-repeat-stop)
+ (add-hook 'pre-command-hook 'evil-repeat-pre-hook)
+ (add-hook 'post-command-hook 'evil-repeat-post-hook)
+ (remove-hook 'evil-insert-state-exit-hook 'evil--restore-repeat-hooks))
+
+(defvar evil--execute-normal-return-state nil
+ "The state to return to after executing in normal state.")
+
+(defun evil-execute-in-normal-state ()
+ "Execute the next command in Normal state."
+ (interactive)
+ (evil-delay '(not (memq this-command
+ '(nil
+ evil-execute-in-normal-state
+ evil-replace-state
+ evil-use-register
+ digit-argument
+ negative-argument
+ universal-argument
+ universal-argument-minus
+ universal-argument-more
+ universal-argument-other-key)))
+ `(progn
+ (with-current-buffer ,(current-buffer)
+ (when (and evil--execute-normal-eol-pos
+ (= (point) (1- evil--execute-normal-eol-pos))
+ (not (memq this-command '(evil-insert
+ evil-goto-mark))))
+ (forward-char))
+ (unless (memq evil-state '(replace insert))
+ (evil-change-state ',evil-state))
+ (when (eq 'insert evil-state)
+ (remove-hook 'pre-command-hook 'evil-repeat-pre-hook)
+ (remove-hook 'post-command-hook 'evil-repeat-post-hook)
+ (add-hook 'evil-insert-state-exit-hook 'evil--restore-repeat-hooks))
+ (setq evil-move-cursor-back ',evil-move-cursor-back
+ evil-move-beyond-eol ',evil-move-beyond-eol
+ evil-execute-normal-keys nil)))
+ 'post-command-hook)
+ (setq evil-insert-count nil
+ evil--execute-normal-return-state evil-state
+ evil--execute-normal-eol-pos (when (eolp) (point))
+ evil-move-cursor-back nil
+ evil-execute-normal-keys (this-command-keys))
+ (evil-normal-state)
+ (setq evil-move-beyond-eol t)
+ (evil-echo "Switched to Normal state for the next command ..."))
+
+(defun evil-stop-execute-in-emacs-state ()
+ (when (and (not (eq this-command #'evil-execute-in-emacs-state))
+ (not (minibufferp)))
+ (remove-hook 'post-command-hook 'evil-stop-execute-in-emacs-state)
+ (when (buffer-live-p evil-execute-in-emacs-state-buffer)
+ (with-current-buffer evil-execute-in-emacs-state-buffer
+ (if (and (eq evil-previous-state 'visual)
+ (not (use-region-p)))
+ (progn
+ (evil-change-to-previous-state)
+ (evil-exit-visual-state))
+ (evil-change-to-previous-state))))
+ (setq evil-execute-in-emacs-state-buffer nil)))
+
+(evil-define-command evil-execute-in-emacs-state ()
+ "Execute the next command in Emacs state."
+ (add-hook 'post-command-hook #'evil-stop-execute-in-emacs-state t)
+ (setq evil-execute-in-emacs-state-buffer (current-buffer))
+ (cond
+ ((evil-visual-state-p)
+ (let ((mrk (mark))
+ (pnt (point)))
+ (evil-emacs-state)
+ (set-mark mrk)
+ (goto-char pnt)))
+ (t
+ (evil-emacs-state)))
+ (evil-echo "Switched to Emacs state for the next command ..."))
+
+(defun evil-exit-visual-and-repeat (event)
+ "Exit insert state and repeat event.
+This special command should be used if some command called from
+visual state should actually be called in normal-state. The main
+reason for doing this is that the repeat system should *not*
+record the visual state information for some command. This
+command should be bound to exactly the same event in visual state
+as the original command is bound in normal state. EVENT is the
+event that triggered the execution of this command."
+ (interactive "e")
+ (when (evil-visual-state-p)
+ (evil-exit-visual-state)
+ (push event unread-command-events)))
+(evil-declare-ignore-repeat 'evil-exit-visual-and-repeat)
+
+(provide 'evil-commands)
+
+;;; evil-commands.el ends here
diff --git a/elpa/evil-20220503.1314/evil-commands.elc b/elpa/evil-20220503.1314/evil-commands.elc
new file mode 100644
index 0000000..aa9bc86
--- /dev/null
+++ b/elpa/evil-20220503.1314/evil-commands.elc
Binary files differ
diff --git a/elpa/evil-20220503.1314/evil-common.el b/elpa/evil-20220503.1314/evil-common.el
new file mode 100644
index 0000000..d755120
--- /dev/null
+++ b/elpa/evil-20220503.1314/evil-common.el
@@ -0,0 +1,4066 @@
+;;; evil-common.el --- Common functions and utilities -*- lexical-binding: t -*-
+;; Author: Vegard Øye <vegard_oye at hotmail.com>
+;; Maintainer: Vegard Øye <vegard_oye at hotmail.com>
+
+;; Version: 1.15.0
+
+;;
+;; This file is NOT part of GNU Emacs.
+
+;;; License:
+
+;; This file is part of Evil.
+;;
+;; Evil 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.
+;;
+;; Evil 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 Evil. If not, see <http://www.gnu.org/licenses/>.
+
+(require 'evil-vars)
+(require 'evil-digraphs)
+(require 'rect)
+(require 'thingatpt)
+(require 'cl-lib)
+(require 'calc)
+
+;;; Code:
+
+(declare-function evil-visual-state-p "evil-states")
+(declare-function evil-visual-restore "evil-states")
+(declare-function evil-motion-state "evil-states")
+(declare-function evil-ex-p "evil-ex")
+(declare-function evil-set-jump "evil-jumps")
+
+(condition-case nil
+ (require 'windmove)
+ (error
+ (message "evil: Could not load `windmove', \
+window commands not available.")
+ nil))
+
+;;; Compatibility with different Emacs versions
+
+;; x-set-selection and x-get-selection have been deprecated since 25.1
+;; by gui-set-selection and gui-get-selection
+(defalias 'evil-get-selection
+ (if (fboundp 'gui-get-selection) 'gui-get-selection 'x-get-selection))
+(defalias 'evil-set-selection
+ (if (fboundp 'gui-set-selection) 'gui-set-selection 'x-set-selection))
+
+(defmacro evil-called-interactively-p ()
+ "Wrapper for `called-interactively-p'.
+In older versions of Emacs, `called-interactively-p' takes
+no arguments. In Emacs 23.2 and newer, it takes one argument."
+ (called-interactively-p 'any))
+(make-obsolete 'evil-called-interactively-p
+ "please use (called-interactively-p 'any) instead."
+ "Git commit 222b791")
+
+;; macro helper
+(eval-and-compile
+ (defun evil-unquote (exp)
+ "Return EXP unquoted."
+ (while (eq (car-safe exp) 'quote)
+ (setq exp (cadr exp)))
+ exp))
+
+(defun evil-delay (condition form hook &optional append local name)
+ "Execute FORM when CONDITION becomes true, checking with HOOK.
+NAME specifies the name of the entry added to HOOK. If APPEND is
+non-nil, the entry is appended to the hook. If LOCAL is non-nil,
+the buffer-local value of HOOK is modified."
+ (if (and (not (booleanp condition)) (eval condition))
+ (eval form)
+ (let* ((name (or name (format "evil-delay-form-in-%s" hook)))
+ (fun (make-symbol name))
+ (condition (or condition t)))
+ (fset fun `(lambda (&rest args)
+ (when ,condition
+ (remove-hook ',hook #',fun ',local)
+ ,form)))
+ (put fun 'permanent-local-hook t)
+ (add-hook hook fun append local))))
+(put 'evil-delay 'lisp-indent-function 2)
+
+;;; List functions
+
+(defmacro evil--add-to-alist (list-var &rest elements)
+ "Add the assocation of KEY and VAL to the value of LIST-VAR.
+If the list already contains an entry for KEY, update that entry;
+otherwise add at the end of the list.
+
+\(fn LIST-VAR KEY VAL &rest ELEMENTS)"
+ (when (eq (car-safe list-var) 'quote)
+ (setq list-var (cadr list-var)))
+ `(progn
+ ,@(if (version< emacs-version "26")
+ ;; TODO: Remove this path when support for Emacs 25 is dropped
+ (cl-loop for (key val) on elements by #'cddr
+ collect `(let* ((key ,key)
+ (val ,val)
+ (cell (assoc key ,list-var)))
+ (if cell
+ (setcdr cell val)
+ (push (cons key val) ,list-var))))
+ (cl-loop for (key val) on elements by #'cddr
+ collect `(setf (alist-get ,key ,list-var nil nil #'equal) ,val)))
+ ,list-var))
+
+(defun evil-add-to-alist (list-var key val &rest elements)
+ "Add the assocation of KEY and VAL to the value of LIST-VAR.
+If the list already contains an entry for KEY, update that entry;
+otherwise add at the end of the list."
+ (let ((tail (symbol-value list-var)))
+ (while (and tail (not (equal (car-safe (car-safe tail)) key)))
+ (setq tail (cdr tail)))
+ (if tail
+ (setcar tail (cons key val))
+ (set list-var (append (symbol-value list-var)
+ (list (cons key val)))))
+ (if elements
+ (with-no-warnings
+ (apply #'evil-add-to-alist list-var elements))
+ (symbol-value list-var))))
+
+(make-obsolete 'evil-add-to-alist
+ "use `evil--add-to-alist' instead. You may need to recompile code with evil macros."
+ "1.13.1")
+
+;; custom version of `delete-if'
+(defun evil-filter-list (predicate list &optional pointer)
+ "Delete by side-effect all items satisfying PREDICATE in LIST.
+Stop when reaching POINTER. If the first item satisfies PREDICATE,
+there is no way to remove it by side-effect; therefore, write
+\(setq foo (evil-filter-list 'predicate foo)) to be sure of
+changing the value of `foo'."
+ (let ((tail list) elt head)
+ (while (and tail (not (eq tail pointer)))
+ (setq elt (car tail))
+ (cond
+ ((funcall predicate elt)
+ (setq tail (cdr tail))
+ (if head
+ (setcdr head tail)
+ (setq list tail)))
+ (t
+ (setq head tail
+ tail (cdr tail)))))
+ list))
+
+(defun evil-member-if (predicate list &optional pointer)
+ "Find the first item satisfying PREDICATE in LIST.
+Stop when reaching POINTER, which should point at a link
+in the list."
+ (let (elt)
+ (catch 'done
+ (while (and (consp list) (not (eq list pointer)))
+ (setq elt (car list))
+ (if (funcall predicate elt)
+ (throw 'done elt)
+ (setq list (cdr list)))))))
+
+(defun evil-member-recursive-if (predicate tree)
+ "Find the first item satisfying PREDICATE in TREE."
+ (cond
+ ((funcall predicate tree)
+ tree)
+ ((listp tree)
+ (catch 'done
+ (dolist (elt tree)
+ (when (setq elt (evil-member-recursive-if predicate elt))
+ (throw 'done elt)))))))
+
+(defun evil-concat-lists (&rest sequences)
+ "Concatenate lists, removing duplicates.
+Elements are compared with `eq'."
+ (let (result)
+ (dolist (sequence sequences)
+ (dolist (elt sequence)
+ (push elt result)))
+ (nreverse (cl-remove-duplicates result :test #'eq))))
+
+(defun evil-concat-alists (&rest sequences)
+ "Concatenate association lists, removing duplicates.
+An alist is a list of cons cells (KEY . VALUE) where each key
+may occur only once. Later values overwrite earlier values."
+ (let (result)
+ (dolist (sequence sequences)
+ (dolist (elt sequence)
+ (setq result (assq-delete-all (car-safe elt) result))
+ (push elt result)))
+ (nreverse result)))
+
+(defun evil-concat-plists (&rest sequences)
+ "Concatenate property lists, removing duplicates.
+A property list is a list (:KEYWORD1 VALUE1 :KEYWORD2 VALUE2...)
+where each keyword may occur only once. Later values overwrite
+earlier values."
+ (let (result)
+ (dolist (sequence sequences result)
+ (while sequence
+ (setq result
+ (plist-put result (pop sequence) (pop sequence)))))))
+
+(defun evil-concat-keymap-alists (&rest sequences)
+ "Concatenate keymap association lists, removing duplicates.
+A keymap alist is a list of cons cells (VAR . MAP) where each keymap
+may occur only once, but where the variables may be repeated
+\(e.g., (VAR . MAP1) (VAR . MAP2) is allowed). The order matters,
+with the highest priority keymaps being listed first."
+ (let (result)
+ (dolist (sequence sequences)
+ (dolist (elt sequence)
+ (unless (rassq (cdr-safe elt) result)
+ (push elt result))))
+ (nreverse result)))
+
+(defun evil-plist-delete (prop plist)
+ "Delete by side effect the property PROP from PLIST.
+If PROP is the first property in PLIST, there is no way
+to remove it by side-effect; therefore, write
+\(setq foo (evil-plist-delete :prop foo)) to be sure of
+changing the value of `foo'."
+ (let ((tail plist) elt head)
+ (while tail
+ (setq elt (car tail))
+ (cond
+ ((eq elt prop)
+ (setq tail (cdr (cdr tail)))
+ (if head
+ (setcdr (cdr head) tail)
+ (setq plist tail)))
+ (t
+ (setq head tail
+ tail (cdr (cdr tail))))))
+ plist))
+
+(defun evil-get-property (alist key &optional prop)
+ "Return property PROP for KEY in ALIST.
+ALIST is an association list with entries of the form
+\(KEY . PLIST), where PLIST is a property list.
+If PROP is nil, return all properties for KEY.
+If KEY is t, return an association list of keys
+and their PROP values."
+ (cond
+ ((null prop)
+ (cdr (assq key alist)))
+ ((eq key t)
+ (let (result val)
+ (dolist (entry alist result)
+ (setq key (car entry)
+ val (cdr entry))
+ (when (plist-member val prop)
+ (setq val (plist-get val prop))
+ (push (cons key val) result)))))
+ (t
+ (plist-get (cdr (assq key alist)) prop))))
+
+(defun evil-put-property (alist-var key prop val &rest properties)
+ "Set PROP to VAL for KEY in ALIST-VAR.
+ALIST-VAR points to an association list with entries of the form
+\(KEY . PLIST), where PLIST is a property list storing PROP and VAL."
+ (set alist-var
+ (let* ((alist (symbol-value alist-var))
+ (plist (cdr (assq key alist))))
+ (setq plist (plist-put plist prop val))
+ (when properties
+ (setq plist (evil-concat-plists plist properties)
+ val (car (last properties))))
+ (setq alist (assq-delete-all key alist))
+ (push (cons key plist) alist)))
+ val)
+
+(defun evil-state-property (state prop &optional value)
+ "Return the value of property PROP for STATE.
+PROP is a keyword as used by `evil-define-state'.
+STATE is the state's symbolic name.
+If VALUE is non-nil and the value is a variable,
+return the value of that variable."
+ (let ((val (evil-get-property evil-state-properties state prop)))
+ (if (and value (symbolp val) (boundp val))
+ (symbol-value val)
+ val)))
+
+(defmacro evil-swap (this that &rest vars)
+ "Swap the values of variables THIS and THAT.
+If three or more arguments are given, the values are rotated.
+E.g., (evil-swap A B C) sets A to B, B to C, and C to A."
+ `(progn
+ (setq ,this (prog1 ,that
+ (setq ,that ,this)))
+ ,@(when vars
+ `((evil-swap ,that ,@vars)))))
+
+(defmacro evil-sort (min max &rest vars)
+ "Place the smallest value in MIN and the largest in MAX.
+If three or more arguments are given, place the smallest
+value in the first argument and the largest in the last,
+sorting in between."
+ (let ((sorted (make-symbol "sortvar")))
+ `(let ((,sorted (sort (list ,min ,max ,@vars) '<)))
+ (setq ,min (pop ,sorted)
+ ,max (pop ,sorted)
+ ,@(apply #'append
+ (mapcar #'(lambda (var)
+ (list var `(pop ,sorted)))
+ vars))))))
+
+(defun evil-vector-to-string (vector)
+ "Turns vector into a string, changing <escape> to '\\e'"
+ (mapconcat (lambda (c)
+ (if (equal c 'escape)
+ "\e"
+ (make-string 1 c)))
+ vector
+ ""))
+
+;;; Command properties
+
+(defmacro evil-define-command (command &rest body)
+ "Define a command COMMAND.
+
+\(fn COMMAND (ARGS...) DOC [[KEY VALUE]...] BODY...)"
+ (declare (indent defun)
+ (doc-string 3)
+ (debug (&define name
+ [&optional lambda-list]
+ [&optional stringp]
+ [&rest keywordp sexp]
+ [&optional ("interactive" [&rest form])]
+ def-body)))
+ (let ((interactive '(interactive))
+ arg args doc doc-form key keys)
+ ;; collect arguments
+ (when (listp (car-safe body))
+ (setq args (pop body)))
+ ;; collect docstring
+ (when (> (length body) 1)
+ (if (eq (car-safe (car-safe body)) 'format)
+ (setq doc-form (pop body))
+ (when (stringp (car-safe body))
+ (setq doc (pop body)))))
+ ;; collect keywords
+ (setq keys (plist-put keys :repeat t))
+ (while (keywordp (car-safe body))
+ (setq key (pop body)
+ arg (pop body))
+ (unless nil ; TODO: add keyword check
+ (setq keys (plist-put keys key arg))))
+ ;; collect `interactive' form
+ (when (and body (consp (car body))
+ (eq (car (car body)) 'interactive))
+ (let* ((iform (pop body))
+ (result (apply #'evil-interactive-form (cdr iform)))
+ (form (car result))
+ (attrs (cdr result)))
+ (setq interactive `(interactive ,form)
+ keys (evil-concat-plists keys attrs))))
+ `(progn
+ ;; the compiler does not recognize `defun' inside `let'
+ ,(when (and command body)
+ `(defun ,command ,args
+ ,@(when doc `(,doc))
+ ,interactive
+ (ignore ,@(cl-set-difference args '(&optional &rest)))
+ ,@body))
+ ,(when (and command doc-form)
+ `(put ',command 'function-documentation ,doc-form))
+ ;; set command properties for symbol or lambda function
+ (let ((func ',(if (and (null command) body)
+ `(lambda ,args
+ ,interactive
+ ,@body)
+ command)))
+ (apply #'evil-set-command-properties func ',keys)
+ func))))
+
+;; If no Evil properties are defined for the command, several parts of
+;; Evil apply certain default rules; e.g., the repeat system decides
+;; whether the command is repeatable by monitoring buffer changes.
+(defun evil-has-command-property-p (command property)
+ "Whether COMMAND has Evil PROPERTY.
+See also `evil-has-command-properties-p'."
+ (plist-member (evil-get-command-properties command) property))
+
+(defun evil-has-command-properties-p (command)
+ "Whether Evil properties are defined for COMMAND.
+See also `evil-has-command-property-p'."
+ (and (evil-get-command-properties command) t))
+
+(defun evil-get-command-property (command property &optional default)
+ "Return the value of Evil PROPERTY of COMMAND.
+If the command does not have the property, return DEFAULT.
+See also `evil-get-command-properties'."
+ (if (evil-has-command-property-p command property)
+ (evil-get-property evil-command-properties command property)
+ default))
+
+(defun evil-get-command-properties (command)
+ "Return all Evil properties of COMMAND.
+See also `evil-get-command-property'."
+ (evil-get-property evil-command-properties command))
+
+(defun evil-set-command-property (command property value)
+ "Set PROPERTY to VALUE for COMMAND.
+To set multiple properties at once, see
+`evil-set-command-properties' and `evil-add-command-properties'."
+ (evil-put-property 'evil-command-properties command property value))
+(defalias 'evil-put-command-property 'evil-set-command-property)
+
+(defun evil-add-command-properties (command &rest properties)
+ "Add PROPERTIES to COMMAND.
+PROPERTIES should be a property list.
+To replace all properties at once, use `evil-set-command-properties'."
+ (apply #'evil-put-property
+ 'evil-command-properties command properties))
+
+(defun evil-set-command-properties (command &rest properties)
+ "Replace all of COMMAND's properties with PROPERTIES.
+PROPERTIES should be a property list.
+This erases all previous properties; to only add properties,
+use `evil-set-command-property'."
+ (setq evil-command-properties
+ (assq-delete-all command evil-command-properties))
+ (when properties
+ (apply #'evil-add-command-properties command properties)))
+
+(defun evil-remove-command-properties (command &rest properties)
+ "Remove PROPERTIES from COMMAND.
+PROPERTIES should be a list of properties (:PROP1 :PROP2 ...).
+If PROPERTIES is the empty list, all properties are removed."
+ (let (plist)
+ (when properties
+ (setq plist (evil-get-command-properties command))
+ (dolist (property properties)
+ (setq plist (evil-plist-delete property plist))))
+ (apply #'evil-set-command-properties command plist)))
+
+(defun evil-yank-handler (&optional motion)
+ "Return the yank handler for MOTION.
+MOTION defaults to the current motion."
+ (setq motion (or motion evil-this-motion))
+ (evil-get-command-property motion :yank-handler))
+
+(defun evil-declare-motion (command)
+ "Declare COMMAND to be a movement function.
+This ensures that it behaves correctly in visual state."
+ (evil-add-command-properties command :keep-visual t :repeat 'motion))
+
+(defun evil-declare-repeat (command)
+ "Declare COMMAND to be repeatable."
+ (evil-add-command-properties command :repeat t))
+
+(defun evil-declare-not-repeat (command)
+ "Declare COMMAND to be nonrepeatable."
+ (evil-add-command-properties command :repeat nil))
+
+(defun evil-declare-ignore-repeat (command)
+ "Declare COMMAND to be nonrepeatable."
+ (evil-add-command-properties command :repeat 'ignore))
+
+(defun evil-declare-change-repeat (command)
+ "Declare COMMAND to be repeatable by buffer changes rather than
+keystrokes."
+ (evil-add-command-properties command :repeat 'change))
+
+(defun evil-declare-insert-at-point-repeat (command)
+ "Declare COMMAND to be repeatable by buffer changes."
+ (evil-add-command-properties command :repeat 'insert-at-point))
+
+(defun evil-declare-abort-repeat (command)
+ "Declare COMMAND to be nonrepeatable."
+ (evil-add-command-properties command :repeat 'abort))
+
+(defun evil-delimited-arguments (string &optional num)
+ "Parse STRING as a sequence of delimited arguments.
+Returns a list of NUM strings, or as many arguments as
+the string contains. The first non-blank character is
+taken to be the delimiter. If some arguments are missing
+from STRING, the resulting list is padded with nil values.
+Two delimiters following directly after each other gives
+an empty string."
+ (save-match-data
+ (let ((string (or string ""))
+ (count (or num -1)) (idx 0)
+ argument delim match result)
+ (when (string-match "^[[:space:]]*\\([^[:space:]]\\)" string)
+ (setq delim (match-string 1 string)
+ argument (format "%s\\(\\(?:[\\].\\|[^%s]\\)*\\)"
+ (regexp-quote delim)
+ delim))
+ (while (and (/= count 0) (string-match argument string idx))
+ (setq match (match-string 1 string)
+ idx (match-end 1)
+ count (1- count))
+ (when (= count 0)
+ (unless (save-match-data
+ (string-match
+ (format "%s[[:space:]]*$" delim) string idx))
+ (setq match (substring string (match-beginning 1)))))
+ (unless (and (zerop (length match))
+ (zerop (length (substring string idx))))
+ (push match result))))
+ (when (and num (< (length result) num))
+ (dotimes (_ (- num (length result)))
+ (push nil result)))
+ (nreverse result))))
+
+(defun evil-concat-charsets (&rest sets)
+ "Concatenate character sets.
+A character set is the part between [ and ] in a regular expression.
+If any character set is complemented, the result is also complemented."
+ (let ((bracket "") (complement "") (hyphen "") result)
+ (save-match-data
+ (dolist (set sets)
+ (when (string-match-p "^\\^" set)
+ (setq set (substring set 1)
+ complement "^"))
+ (when (string-match-p "^]" set)
+ (setq set (substring set 1)
+ bracket "]"))
+ (when (string-match-p "^-" set)
+ (setq set (substring set 1)
+ hyphen "-"))
+ (setq result (concat result set)))
+ (format "%s%s%s%s" complement bracket hyphen result))))
+
+;;; Key sequences
+
+(defun evil-keypress-parser (&optional input)
+ "Read from keyboard or INPUT and build a command description.
+Returns (CMD COUNT), where COUNT is the numeric prefix argument.
+Both COUNT and CMD may be nil."
+ (let (count negative)
+ (when input (setq unread-command-events (append input unread-command-events)))
+ (catch 'done
+ (while t
+ (let ((seq (read-key-sequence "")))
+ (when seq
+ (let ((cmd (key-binding seq)))
+ (cond
+ ((null cmd) (throw 'done (list nil nil)))
+ ((arrayp cmd) ; keyboard macro, recursive call
+ (let ((cmd (evil-keypress-parser cmd)))
+ (throw 'done
+ (list (car cmd)
+ (if (or count (cadr cmd))
+ (list (car cmd) (* (or count 1)
+ (or (cadr cmd) 1))))))))
+ ((or (eq cmd #'digit-argument)
+ (and (equal seq "0")
+ count))
+ (let* ((event (aref seq (- (length seq) 1)))
+ (char (or (when (characterp event) event)
+ (when (symbolp event)
+ (get event 'ascii-character))))
+ (digit (if (or (characterp char) (integerp char))
+ (- (logand char ?\177) ?0))))
+ (setq count (+ (* 10 (or count 0)) digit))))
+ ((eq cmd #'negative-argument)
+ (setq negative (not negative)))
+ (t
+ (throw 'done (list cmd
+ (and count
+ (* count
+ (if negative -1 1))))))))))))))
+
+(defun evil-read-key (&optional prompt)
+ "Read a key from the keyboard.
+Translates it according to the input method."
+ (let ((old-global-map (current-global-map))
+ (new-global-map (make-sparse-keymap))
+ (overriding-terminal-local-map nil)
+ (overriding-local-map evil-read-key-map)
+ seq char cmd)
+ (unwind-protect
+ (condition-case nil
+ (progn
+ (define-key new-global-map [menu-bar]
+ (lookup-key global-map [menu-bar]))
+ (define-key new-global-map [tab-bar]
+ (lookup-key global-map [tab-bar]))
+ (define-key new-global-map [tool-bar]
+ (lookup-key global-map [tool-bar]))
+ (setq new-global-map
+ (append new-global-map
+ (list (make-char-table 'display-table
+ 'self-insert-command))))
+ (use-global-map new-global-map)
+ (setq seq (read-key-sequence prompt nil t)
+ char (aref seq 0)
+ cmd (key-binding seq))
+ (while (arrayp cmd)
+ (setq char (aref cmd 0)
+ cmd (key-binding cmd)))
+ (cond
+ ((eq cmd 'self-insert-command)
+ char)
+ (cmd
+ (call-interactively cmd))
+ (t
+ (user-error "No replacement character typed"))))
+ (quit
+ (when (fboundp 'evil-repeat-abort)
+ (evil-repeat-abort))
+ (signal 'quit nil)))
+ (use-global-map old-global-map))))
+
+(defun evil-read-quoted-char ()
+ "Command that calls `read-quoted-char'.
+This command can be used wherever `read-quoted-char' is required
+as a command. Its main use is in the `evil-read-key-map'."
+ (interactive)
+ (read-quoted-char))
+
+(defun evil-read-digraph-char-with-overlay (overlay)
+ "Read two chars, displaying the first in OVERLAY, replacing `?'.
+Return the digraph from `evil-digraph', else return second char."
+ (interactive)
+ (let (char1 char2 string)
+ (unwind-protect
+ (progn
+ (overlay-put overlay 'invisible t)
+ ;; create overlay prompt
+ (setq string (propertize "?"
+ 'face 'minibuffer-prompt
+ 'cursor 1))
+ (overlay-put overlay 'after-string string)
+ (setq char1 (read-key))
+ (setq string (propertize (string char1)
+ 'face 'minibuffer-prompt
+ 'cursor 1))
+ (overlay-put overlay 'after-string string)
+ (setq char2 (read-key)))
+ (delete-overlay overlay))
+ (or (evil-digraph (list char1 char2))
+ ;; use the last character if undefined
+ char2)))
+
+(defun evil-read-digraph-char (&optional hide-chars)
+ "Read two keys from keyboard forming a digraph.
+This function creates an overlay at (point), hiding the next
+HIDE-CHARS characters. HIDE-CHARS defaults to 1."
+ (interactive)
+ (let ((overlay (make-overlay (point)
+ (min (point-max)
+ (+ (or hide-chars 1)
+ (point))))))
+ (evil-read-digraph-char-with-overlay overlay)))
+
+(defun evil-read-motion (&optional motion count type modifier)
+ "Read a MOTION, motion COUNT and motion TYPE from the keyboard.
+The type may be overridden with MODIFIER, which may be a type
+or a Visual selection as defined by `evil-define-visual-selection'.
+Return a list (MOTION COUNT [TYPE])."
+ (let (command prefix)
+ (setq evil-this-type-modified nil)
+ (unless motion
+ (while (progn
+ (setq command (evil-keypress-parser)
+ motion (pop command)
+ prefix (pop command))
+ (when prefix
+ (if count
+ (setq count (string-to-number
+ (concat (number-to-string count)
+ (number-to-string prefix))))
+ (setq count prefix)))
+ ;; if the command is a type modifier, read more
+ (when (rassq motion evil-visual-alist)
+ (setq modifier
+ (or modifier
+ (car (rassq motion evil-visual-alist))))))))
+ (when modifier
+ (setq type (or type (evil-type motion 'exclusive)))
+ (cond
+ ((eq modifier 'char)
+ ;; TODO: this behavior could be less hard-coded
+ (if (eq type 'exclusive)
+ (setq type 'inclusive)
+ (setq type 'exclusive)))
+ (t
+ (setq type modifier)))
+ (setq evil-this-type-modified type))
+ (list motion count type)))
+
+(defun evil-mouse-events-p (keys)
+ "Returns non-nil iff KEYS contains a mouse event."
+ (catch 'done
+ (dotimes (i (length keys))
+ (when (or (and (fboundp 'mouse-event-p)
+ (mouse-event-p (aref keys i)))
+ (mouse-movement-p (aref keys i)))
+ (throw 'done t)))
+ nil))
+
+(defun evil-extract-count (keys)
+ "Splits the key-sequence KEYS into prefix-argument and the rest.
+Returns the list (PREFIX CMD SEQ REST), where PREFIX is the
+prefix count, CMD the command to be executed, SEQ the subsequence
+calling CMD, and REST is all remaining events in the
+key-sequence. PREFIX and REST may be nil if they do not exist.
+If a command is bound to some keyboard macro, it is expanded
+recursively."
+ (catch 'done
+ (let* ((len (length keys))
+ (beg 0)
+ (end 1)
+ (found-prefix nil))
+ (while (and (<= end len))
+ (let* ((seq (substring keys beg end))
+ (cmd (key-binding seq)))
+ (cond
+ ((memq cmd '(undefined nil))
+ (user-error "No command bound to %s" seq))
+ ((arrayp cmd) ; keyboard macro, replace command with macro
+ (setq keys (vconcat (substring keys 0 beg)
+ cmd
+ (substring keys end))
+ end (1+ beg)
+ len (length keys)))
+ ((functionp cmd)
+ (if (or (memq cmd '(digit-argument negative-argument))
+ (and found-prefix
+ (equal (vconcat seq) (vector ?0))))
+ ;; skip those commands
+ (setq found-prefix t ; found at least one prefix argument
+ beg end
+ end (1+ end))
+ ;; a real command, finish
+ (throw 'done
+ (list (unless (zerop beg)
+ (string-to-number
+ (concat (substring keys 0 beg))))
+ cmd
+ seq
+ (when (< end len)
+ (substring keys end))))))
+ (t ; append a further event
+ (setq end (1+ end))))))
+ (user-error "Key sequence contains no complete binding"))))
+
+(defun evil-extract-append (file-or-append)
+ "Return an (APPEND . FILENAME) pair based on FILE-OR-APPEND.
+FILE-OR-APPEND should either be a filename or a \">> FILE\"
+directive. APPEND will be t if FILE-OR-APPEND is an append
+directive and nil otherwise. FILENAME will be the extracted
+filename."
+ (if (and (stringp file-or-append)
+ (string-match "\\(>> *\\)" file-or-append))
+ (cons t (substring file-or-append(match-end 1)))
+ (cons nil file-or-append)))
+
+(defun evil-set-keymap-prompt (map prompt)
+ "Set the prompt-string of MAP to PROMPT."
+ (delq (keymap-prompt map) map)
+ (when prompt
+ (setcdr map (cons prompt (cdr map)))))
+
+(defun evil-lookup-key (map key)
+ "Returns non-nil value if KEY is bound in MAP."
+ (let ((definition (lookup-key map key)))
+ (if (numberp definition) ; in-band error
+ nil
+ definition)))
+
+;;; Display
+
+(defun evil-set-cursor (specs)
+ "Change the cursor's apperance according to SPECS.
+SPECS may be a cursor type as per `cursor-type', a color
+string as passed to `set-cursor-color', a zero-argument
+function for changing the cursor, or a list of the above."
+ (unless (and (not (functionp specs))
+ (listp specs)
+ (null (cdr-safe (last specs))))
+ (setq specs (list specs)))
+ (dolist (spec specs)
+ (cond
+ ((functionp spec)
+ (condition-case nil
+ (funcall spec)
+ (error nil)))
+ ((stringp spec)
+ (evil-set-cursor-color spec))
+ (t
+ (setq cursor-type spec)))))
+
+(defun evil-set-cursor-color (color)
+ "Set the cursor color to COLOR."
+ (unless (equal (frame-parameter nil 'cursor-color) color)
+ ;; `set-cursor-color' forces a redisplay, so only
+ ;; call it when the color actually changes
+ (set-cursor-color color)))
+
+(defun evil-refresh-cursor (&optional state buffer)
+ "Refresh the cursor for STATE in BUFFER.
+BUFFER defaults to the current buffer. If STATE is nil the
+cursor type is either `evil-force-cursor' or the current state."
+ (when (and (boundp 'evil-local-mode) evil-local-mode)
+ (let* ((state (or state evil-force-cursor evil-state 'normal))
+ (default (or evil-default-cursor t))
+ (cursor (evil-state-property state :cursor t))
+ (color (or (and (stringp cursor) cursor)
+ (and (listp cursor)
+ (evil-member-if #'stringp cursor))
+ (frame-parameter nil 'cursor-color))))
+ (with-current-buffer (or buffer (current-buffer))
+ ;; if both STATE and `evil-default-cursor'
+ ;; specify a color, don't set it twice
+ (when (and color (listp default))
+ (setq default (evil-filter-list #'stringp default)))
+ (evil-set-cursor default)
+ (evil-set-cursor cursor)))))
+
+(defmacro evil-save-cursor (&rest body)
+ "Save the current cursor; execute BODY; restore the cursor."
+ (declare (indent defun)
+ (debug t))
+ `(let ((cursor cursor-type)
+ (color (frame-parameter (selected-frame) 'cursor-color))
+ (inhibit-quit t))
+ (unwind-protect
+ (progn ,@body)
+ (evil-set-cursor cursor)
+ (evil-set-cursor color))))
+
+(defun evil-echo (string &rest args)
+ "Display an unlogged message in the echo area.
+That is, the message is not logged in the *Messages* buffer.
+\(To log the message, just use `message'.)"
+ (unless evil-no-display
+ (let (message-log-max)
+ (apply #'message string args))))
+
+(defun evil-echo-area-save ()
+ "Save the current echo area in `evil-echo-area-message'."
+ (setq evil-echo-area-message (current-message)))
+
+(defun evil-echo-area-restore ()
+ "Restore the echo area from `evil-echo-area-message'.
+Does not restore if `evil-write-echo-area' is non-nil."
+ (unless evil-write-echo-area
+ (if evil-echo-area-message
+ (message "%s" evil-echo-area-message)
+ (message nil)))
+ (setq evil-echo-area-message nil
+ evil-write-echo-area nil))
+
+;; toggleable version of `with-temp-message'
+(defmacro evil-save-echo-area (&rest body)
+ "Save the echo area; execute BODY; restore the echo area.
+Intermittent messages are not logged in the *Messages* buffer."
+ (declare (indent defun)
+ (debug t))
+ `(let ((inhibit-quit t)
+ evil-echo-area-message
+ evil-write-echo-area)
+ (unwind-protect
+ (progn
+ (evil-echo-area-save)
+ ,@body)
+ (evil-echo-area-restore))))
+
+(defmacro evil-without-display (&rest body)
+ "Execute BODY without Evil displays.
+Inhibits echo area messages, mode line updates and cursor changes."
+ (declare (indent defun)
+ (debug t))
+ `(let ((evil-no-display t))
+ ,@body))
+
+(defvar evil-cached-header-line-height nil
+ "Cached height of the header line.
+Used for fallback implementation on older Emacsen.")
+
+(defun evil-header-line-height ()
+ "Return the height of the header line.
+If there is no header line, return 0.
+Used as a fallback implementation of `window-header-line-height' on
+older Emacsen."
+ (let ((posn (posn-at-x-y 0 0)))
+ (or (when (eq (posn-area posn) 'header-line)
+ (cdr (posn-object-width-height posn)))
+ 0)))
+
+(defun evil-posn-x-y (position)
+ "Return the x and y coordinates in POSITION.
+This function returns y offset from the top of the buffer area including
+the header line and the tab line (on Emacs 27 and later versions).
+
+On Emacs 24 and later versions, the y-offset returned by
+`posn-at-point' is relative to the text area excluding the header
+line and the tab line, while y offset taken by `posn-at-x-y' is relative to
+the buffer area including the header line and the tab line.
+This asymmetry is by design according to GNU Emacs team.
+This function fixes the asymmetry between them.
+
+Learned from mozc.el."
+ (let ((xy (posn-x-y position)))
+ (when header-line-format
+ (setcdr xy (+ (cdr xy)
+ (or (and (fboundp 'window-header-line-height)
+ (window-header-line-height))
+ evil-cached-header-line-height
+ (setq evil-cached-header-line-height (evil-header-line-height))))))
+ (when (fboundp 'window-tab-line-height)
+ (setcdr xy (+ (cdr xy) (window-tab-line-height))))
+ xy))
+
+(defun evil-count-lines (beg end)
+ "Return absolute line-number-difference betweeen `beg` and `end`.
+This should give the same results no matter where on the line `beg`
+and `end` are."
+ (if (= beg end)
+ 0
+ (let* ((last (max beg end))
+ (end-at-bol (save-excursion (goto-char last)
+ (bolp))))
+ (if end-at-bol
+ (count-lines beg end)
+ (1- (count-lines beg end))))))
+
+;;; Movement
+
+(defun evil-normalize-position (pos)
+ "Return POS if it does not exceed the buffer boundaries.
+If POS is less than `point-min', return `point-min'.
+Is POS is more than `point-max', return `point-max'.
+If POS is a marker, return its position."
+ (cond
+ ((not (number-or-marker-p pos))
+ pos)
+ ((< pos (point-min))
+ (point-min))
+ ((> pos (point-max))
+ (point-max))
+ ((markerp pos)
+ (marker-position pos))
+ (t
+ pos)))
+
+(defmacro evil-save-goal-column (&rest body)
+ "Restores the goal column after execution of BODY.
+See also `evil-save-column'."
+ (declare (indent defun)
+ (debug t))
+ `(let ((goal-column goal-column)
+ (temporary-goal-column temporary-goal-column))
+ ,@body))
+
+(defmacro evil-save-column (&rest body)
+ "Restores the column after execution of BODY.
+See also `evil-save-goal-column'."
+ (declare (indent defun)
+ (debug t))
+ `(let ((col (current-column)))
+ (evil-save-goal-column
+ ,@body
+ (move-to-column col))))
+
+(defun evil--stick-to-eol-p ()
+ "Called by vertical movement commands to help determine cursor position."
+ (let ((goal-col (or goal-column
+ (if (consp temporary-goal-column)
+ (car temporary-goal-column)
+ temporary-goal-column))))
+ (and evil-track-eol
+ (= most-positive-fixnum goal-col)
+ (eq last-command 'next-line))))
+
+(defun evil-eolp ()
+ "Like `eolp' but accounts for `evil-move-beyond-eol' being nil."
+ (ignore-errors
+ (save-excursion
+ (unless (or evil-move-beyond-eol (memq evil-state '(insert replace)))
+ (forward-char))
+ (eolp))))
+
+(defmacro evil-ensure-column (&rest body)
+ "Execute BODY so that column after execution is correct.
+If `evil-start-of-line' is nil, treat BODY as if it were a `next-line' command.
+This mostly copies the approach of Emacs' `line-move-1', but is modified
+so it is more compatible with evil's notions of eol & tracking."
+ (declare (indent defun)
+ (debug t))
+ (let ((normalize-temporary-goal-column
+ `(if (consp temporary-goal-column)
+ (setq temporary-goal-column (+ (car temporary-goal-column)
+ (cdr temporary-goal-column))))))
+ `(progn
+ (unless evil-start-of-line (setq this-command 'next-line))
+ ,normalize-temporary-goal-column
+ (if (not (memq last-command '(next-line previous-line)))
+ (setq temporary-goal-column
+ (if (and evil-track-eol
+ (evil-eolp)
+ (memq real-last-command '(move-end-of-line evil-end-of-line)))
+ most-positive-fixnum
+ (current-column))))
+ ,@body
+ (if evil-start-of-line
+ (evil-first-non-blank)
+ ,normalize-temporary-goal-column
+ (line-move-to-column (truncate (or goal-column temporary-goal-column)))))))
+
+(defun evil-narrow (beg end)
+ "Restrict the buffer to BEG and END.
+BEG or END may be nil, specifying a one-sided restriction including
+`point-min' or `point-max'. See also `evil-with-restriction.'"
+ (setq beg (or (evil-normalize-position beg) (point-min)))
+ (setq end (or (evil-normalize-position end) (point-max)))
+ (narrow-to-region beg end))
+
+(defmacro evil-with-restriction (beg end &rest body)
+ "Execute BODY with the buffer narrowed to BEG and END.
+BEG or END may be nil as passed to `evil-narrow'; this creates
+a one-sided restriction."
+ (declare (indent 2)
+ (debug t))
+ `(save-restriction
+ (let ((evil-restriction-stack
+ (cons (cons (point-min) (point-max)) evil-restriction-stack)))
+ (evil-narrow ,beg ,end)
+ ,@body)))
+
+(defmacro evil-without-restriction (&rest body)
+ "Execute BODY with the top-most narrowing removed.
+This works only if the previous narrowing has been generated by
+`evil-with-restriction'."
+ (declare (indent defun)
+ (debug t))
+ `(save-restriction
+ (widen)
+ (narrow-to-region (car (car evil-restriction-stack))
+ (cdr (car evil-restriction-stack)))
+ (let ((evil-restriction-stack (cdr evil-restriction-stack)))
+ ,@body)))
+
+(defmacro evil-narrow-to-field (&rest body)
+ "Narrow to the current field."
+ (declare (indent defun)
+ (debug t))
+ `(evil-with-restriction (field-beginning) (field-end)
+ ,@body))
+
+(defun evil-move-beginning-of-line (&optional arg)
+ "Move to the beginning of the line as displayed.
+Like `move-beginning-of-line', but retains the goal column."
+ (evil-save-goal-column
+ (move-beginning-of-line arg)
+ (beginning-of-line)))
+
+(defun evil-move-end-of-line (&optional arg)
+ "Move to the end of the line as displayed.
+Like `move-end-of-line', but retains the goal column."
+ (evil-save-goal-column
+ (move-end-of-line arg)
+ (end-of-line)))
+
+(defun evil-adjust-cursor (&optional _)
+ "Move point one character back if at the end of a non-empty line.
+This behavior is controled by `evil-move-beyond-eol'."
+ (when (and (eolp)
+ (not evil-move-beyond-eol)
+ (not (bolp))
+ (= (point)
+ (save-excursion
+ (evil-move-end-of-line)
+ (point))))
+ (evil-move-cursor-back t)))
+
+(defun evil-move-cursor-back (&optional force)
+ "Move point one character back within the current line.
+Contingent on the variable `evil-move-cursor-back' or the FORCE
+argument. Honors field boundaries, i.e., constrains the movement
+to the current field as recognized by `line-beginning-position'."
+ (when (or evil-move-cursor-back force)
+ (unless (or (= (point) (line-beginning-position))
+ (and (boundp 'visual-line-mode)
+ visual-line-mode
+ (= (point) (save-excursion
+ (beginning-of-visual-line)
+ (point)))))
+ (backward-char))))
+
+(defun evil-line-position (line &optional column)
+ "Return the position of LINE.
+If COLUMN is specified, return its position on the line.
+A negative number means the end of the line."
+ (save-excursion
+ (when (fboundp 'evil-goto-line)
+ (evil-goto-line line))
+ (if (numberp column)
+ (if (< column 0)
+ (beginning-of-line 2)
+ (move-to-column column))
+ (beginning-of-line))
+ (point)))
+
+(defun evil-column (&optional pos)
+ "Return the horizontal position of POS.
+POS defaults to point."
+ (save-excursion
+ (when pos
+ (goto-char pos))
+ (current-column)))
+
+(defun evil-move-to-column (column &optional dir force)
+ "Move point to column COLUMN in the current line.
+Places point at left of the tab character (at the right if DIR
+is non-nil) and returns point."
+ (interactive "p")
+ (move-to-column column force)
+ (unless force
+ (when (or (not dir) (and (numberp dir) (< dir 1)))
+ (when (> (current-column) column)
+ (evil-move-cursor-back))))
+ (point))
+
+(defmacro evil-loop (spec &rest body)
+ "Loop with countdown variable.
+Evaluate BODY with VAR counting down from COUNT to 0.
+COUNT can be negative, in which case VAR counts up instead.
+The return value is the value of VAR when the loop
+terminates, which is 0 if the loop completes successfully.
+RESULT specifies a variable for storing this value.
+
+\(fn (VAR COUNT [RESULT]) BODY...)"
+ (declare (indent defun)
+ (debug dolist))
+ (let* ((i (make-symbol "loopvar"))
+ (var (pop spec))
+ (count (pop spec))
+ (result (pop spec)))
+ (setq var (or (unless (eq var result) var) i)
+ result (or result var))
+ `(let ((,var ,count))
+ (setq ,result ,var)
+ (while (/= ,var 0)
+ ,@body
+ (if (> ,var 0)
+ (setq ,var (1- ,var))
+ (setq ,var (1+ ,var)))
+ (setq ,result ,var))
+ ,var)))
+
+;;; Motions
+
+(defmacro evil-motion-loop (spec &rest body)
+ "Loop a certain number of times.
+Evaluate BODY repeatedly COUNT times with VAR bound to 1 or -1,
+depending on the sign of COUNT. RESULT, if specified, holds
+the number of unsuccessful iterations, which is 0 if the loop
+completes successfully. This is also the return value.
+
+Each iteration must move point; if point does not change,
+the loop immediately quits. See also `evil-loop'.
+
+\(fn (VAR COUNT [RESULT]) BODY...)"
+ (declare (indent defun)
+ (debug ((symbolp form &optional symbolp) body)))
+ (let* ((var (or (pop spec) (make-symbol "unitvar")))
+ (countval (or (pop spec) 0))
+ (result (pop spec))
+ (i (make-symbol "loopvar"))
+ (count (make-symbol "countvar"))
+ (done (make-symbol "donevar"))
+ (orig (make-symbol "origvar")))
+ `(let* ((,count ,countval)
+ (,var (if (< ,count 0) -1 1)))
+ (catch ',done
+ (evil-loop (,i ,count ,result)
+ (let ((,orig (point)))
+ ,@body
+ (when (= (point) ,orig)
+ (throw ',done ,i))))))))
+
+(defmacro evil-signal-without-movement (&rest body)
+ "Catches errors provided point moves within this scope."
+ (declare (indent defun)
+ (debug t))
+ `(let ((p (point)))
+ (condition-case err
+ (progn ,@body)
+ (error
+ (when (= p (point))
+ (signal (car err) (cdr err)))))))
+
+(defun evil-signal-at-bob-or-eob (&optional count)
+ "Signals error if `point' is at boundaries.
+If `point' is at bob and COUNT is negative this function signal
+'beginning-of-buffer. If `point' is at eob and COUNT is positive
+this function singal 'end-of-buffer. This function should be used
+in motions. COUNT defaults to 1."
+ (setq count (or count 1))
+ (cond
+ ((< count 0) (evil-signal-at-bob))
+ ((> count 0) (evil-signal-at-eob))))
+
+(defun evil-signal-at-bob ()
+ "Signals 'beginning-of-buffer if `point' is at bob.
+This function should be used in backward motions. If `point' is at
+bob so that no further backward motion is possible the error
+'beginning-of-buffer is raised."
+ (when (bobp) (signal 'beginning-of-buffer nil)))
+
+(defun evil-signal-at-eob ()
+ "Signals 'end-of-buffer if `point' is at eob.
+This function should be used in forward motions. If `point' is close
+to eob so that no further forward motion is possible the error
+'end-of-buffer is raised. This is the case if `point' is at
+`point-max' or if is one position before `point-max',
+`evil-move-beyond-eol' is nil and `point' is not at the end
+of a line. The latter is necessary because `point' cannot be
+moved to `point-max' if `evil-move-beyond-eol' is nil and
+the last line in the buffer is not empty."
+ (when (or (eobp)
+ (and (not (eolp))
+ (not evil-move-beyond-eol)
+ (save-excursion (forward-char) (eobp))))
+ (signal 'end-of-buffer nil)))
+
+(defmacro evil-with-hproject-point-on-window (&rest body)
+ "Project point after BODY to current window.
+If point is on a position left or right of the current window
+then it is moved to the left and right boundary of the window,
+respectively. If `auto-hscroll-mode' is non-nil then the left and
+right positions are increased or decreased, respectively, by
+`horizontal-margin' so that no automatic scrolling occurs."
+ (declare (indent defun)
+ (debug t))
+ (let ((diff (make-symbol "diff"))
+ (left (make-symbol "left"))
+ (right (make-symbol "right")))
+ `(let ((,diff (if auto-hscroll-mode (1+ hscroll-margin) 0))
+ auto-hscroll-mode)
+ ,@body
+ (let* ((,left (+ (window-hscroll) ,diff))
+ (,right (+ (window-hscroll) (window-width) (- ,diff) -1)))
+ (move-to-column (min (max (current-column) ,left) ,right))))))
+
+(defun evil-goto-min (&rest positions)
+ "Go to the smallest position in POSITIONS.
+Non-numerical elements are ignored.
+See also `evil-goto-max'."
+ (when (setq positions (evil-filter-list
+ #'(lambda (elt)
+ (not (number-or-marker-p elt)))
+ positions))
+ (goto-char (apply #'min positions))))
+
+(defun evil-goto-max (&rest positions)
+ "Go to the largest position in POSITIONS.
+Non-numerical elements are ignored.
+See also `evil-goto-min'."
+ (when (setq positions (evil-filter-list
+ #'(lambda (elt)
+ (not (number-or-marker-p elt)))
+ positions))
+ (goto-char (apply #'max positions))))
+
+(defun evil-forward-not-thing (thing &optional count)
+ "Move point to the end or beginning of the complement of THING."
+ (evil-motion-loop (dir (or count 1))
+ (let (bnd)
+ (cond
+ ((> dir 0)
+ (while (and (setq bnd (bounds-of-thing-at-point thing))
+ (< (point) (cdr bnd)))
+ (goto-char (cdr bnd)))
+ ;; no thing at (point)
+ (if (zerop (forward-thing thing))
+ ;; now at the end of the next thing
+ (let ((bnd (bounds-of-thing-at-point thing)))
+ (if (or (< (car bnd) (point)) ; end of a thing
+ (= (car bnd) (cdr bnd))) ; zero width thing
+ (goto-char (car bnd))
+ ;; beginning of yet another thing, go back
+ (forward-thing thing -1)))
+ (goto-char (point-max))))
+ (t
+ (while (and (not (bobp))
+ (or (backward-char) t)
+ (setq bnd (bounds-of-thing-at-point thing))
+ (< (point) (cdr bnd)))
+ (goto-char (car bnd)))
+ ;; either bob or no thing at point
+ (goto-char
+ (if (and (not (bobp))
+ (zerop (forward-thing thing -1))
+ (setq bnd (bounds-of-thing-at-point thing)))
+ (cdr bnd)
+ (point-min))))))))
+
+(defun evil-bounds-of-not-thing-at-point (thing &optional which)
+ "Returns the bounds of a complement of THING at point.
+If there is a THING at point nil is returned. Otherwise if WHICH
+is nil or 0 a cons cell (BEG . END) is returned. If WHICH is
+negative the beginning is returned. If WHICH is positive the END
+is returned."
+ (let ((pnt (point)))
+ (let ((beg (save-excursion
+ (and (zerop (forward-thing thing -1))
+ (forward-thing thing))
+ (if (> (point) pnt) (point-min) (point))))
+ (end (save-excursion
+ (and (zerop (forward-thing thing))
+ (forward-thing thing -1))
+ (if (< (point) pnt) (point-max) (point)))))
+ (when (and (<= beg (point)) (<= (point) end) (< beg end))
+ (cond
+ ((or (not which) (zerop which)) (cons beg end))
+ ((< which 0) beg)
+ ((> which 0) end))))))
+
+(defun evil-forward-nearest (count &rest forwards)
+ "Moves point forward to the first of several motions.
+FORWARDS is a list of forward motion functions (i.e. each moves
+point forward to the next end of a text object (if passed a +1)
+or backward to the preceeding beginning of a text object (if
+passed a -1)). This function calls each of these functions once
+and moves point to the nearest of the resulting positions. If
+COUNT is positive point is moved forward COUNT times, if negative
+point is moved backward -COUNT times."
+ (evil-motion-loop (dir (or count 1))
+ (let ((pnt (point))
+ (nxt (if (> dir 0) (point-max) (point-min))))
+ (dolist (fwd forwards)
+ (goto-char pnt)
+ (condition-case nil
+ (evil-with-restriction
+ (and (< dir 0)
+ (save-excursion
+ (goto-char nxt)
+ (line-beginning-position 0)))
+ (and (> dir 0)
+ (save-excursion
+ (goto-char nxt)
+ (line-end-position 2)))
+ (if (and (zerop (funcall fwd dir))
+ (/= (point) pnt)
+ (or (and (> dir 0) (< (point) nxt))
+ (and (< dir 0) (> (point) nxt))))
+ (setq nxt (point))))
+ (error)))
+ (goto-char nxt))))
+
+(defun bounds-of-evil-string-at-point (&optional state)
+ "Return the bounds of a string at point.
+If STATE is given it used a parsing state at point."
+ (save-excursion
+ (let ((state (or state (syntax-ppss))))
+ (and (nth 3 state)
+ (cons (nth 8 state)
+ (and (parse-partial-sexp (point)
+ (point-max)
+ nil
+ nil
+ state
+ 'syntax-table)
+ (point)))))))
+(put 'evil-string 'bounds-of-thing-at-point #'bounds-of-evil-string-at-point)
+
+(defun bounds-of-evil-comment-at-point ()
+ "Return the bounds of a string at point."
+ (save-excursion
+ (let ((state (syntax-ppss)))
+ (and (nth 4 state)
+ (cons (nth 8 state)
+ (and (parse-partial-sexp (point)
+ (point-max)
+ nil
+ nil
+ state
+ 'syntax-table)
+ (point)))))))
+(put 'evil-comment 'bounds-of-thing-at-point #'bounds-of-evil-comment-at-point)
+
+;; The purpose of this function is to provide line motions which
+;; preserve the column. This is how `previous-line' and `next-line'
+;; work, but unfortunately the behaviour is hard-coded: if and only if
+;; the last command was `previous-line' or `next-line', the column is
+;; preserved. Furthermore, in contrast to Vim, when we cannot go
+;; further, those motions move point to the beginning resp. the end of
+;; the line (we never want point to leave its column). The code here
+;; comes from simple.el, and I hope it will work in future.
+(defun evil-line-move (count &optional noerror)
+ "A wrapper for line motions which conserves the column.
+Signals an error at buffer boundaries unless NOERROR is non-nil."
+ (cond
+ (noerror
+ (condition-case nil
+ (evil-line-move count)
+ (error nil)))
+ (t
+ (evil-signal-without-movement
+ (setq this-command (if (>= count 0)
+ #'next-line
+ #'previous-line))
+ (let ((opoint (point)))
+ (condition-case err
+ (with-no-warnings
+ (funcall this-command (abs count)))
+ ((beginning-of-buffer end-of-buffer)
+ (let ((col (or goal-column
+ (if (consp temporary-goal-column)
+ (car temporary-goal-column)
+ temporary-goal-column))))
+ (if line-move-visual
+ (vertical-motion (cons col 0))
+ (line-move-finish col opoint (< count 0)))
+ ;; Maybe we should just `ding'?
+ (signal (car err) (cdr err))))))))))
+
+(defun evil-forward-syntax (syntax &optional count)
+ "Move point to the end or beginning of a sequence of characters in
+SYNTAX.
+Stop on reaching a character not in SYNTAX."
+ (let ((notsyntax (if (= (aref syntax 0) ?^)
+ (substring syntax 1)
+ (concat "^" syntax))))
+ (evil-motion-loop (dir (or count 1))
+ (cond
+ ((< dir 0)
+ (skip-syntax-backward notsyntax)
+ (skip-syntax-backward syntax))
+ (t
+ (skip-syntax-forward notsyntax)
+ (skip-syntax-forward syntax))))))
+
+(defun evil-forward-chars (chars &optional count)
+ "Move point to the end or beginning of a sequence of CHARS.
+CHARS is a character set as inside [...] in a regular expression."
+ (let ((notchars (if (= (aref chars 0) ?^)
+ (substring chars 1)
+ (concat "^" chars))))
+ (evil-motion-loop (dir (or count 1))
+ (cond
+ ((< dir 0)
+ (skip-chars-backward notchars)
+ (skip-chars-backward chars))
+ (t
+ (skip-chars-forward notchars)
+ (skip-chars-forward chars))))))
+
+(defun evil-up-block (beg end &optional count)
+ "Move point to the end or beginning of text enclosed by BEG and END.
+BEG and END should be regular expressions matching the opening
+and closing delimiters, respectively. If COUNT is greater than
+zero point is moved forward otherwise it is moved
+backwards. Whenever an opening delimiter is found the COUNT is
+increased by one, if a closing delimiter is found the COUNT is
+decreased by one. The motion stops when COUNT reaches zero. The
+match-data reflects the last successful match (that caused COUNT
+to reach zero). The behaviour of this functions is similar to
+`up-list'."
+ (let* ((count (or count 1))
+ (forwardp (> count 0))
+ (dir (if forwardp +1 -1)))
+ (catch 'done
+ (while (not (zerop count))
+ (let* ((pnt (point))
+ (cl (save-excursion
+ (and (re-search-forward (if forwardp end beg) nil t dir)
+ (or (/= pnt (point))
+ (progn
+ ;; zero size match, repeat search from
+ ;; the next position
+ (forward-char dir)
+ (re-search-forward (if forwardp end beg) nil t dir)))
+ (point))))
+ (match (match-data t))
+ (op (save-excursion
+ (and (not (equal beg end))
+ (re-search-forward (if forwardp beg end) cl t dir)
+ (or (/= pnt (point))
+ (progn
+ ;; zero size match, repeat search from
+ ;; the next position
+ (forward-char dir)
+ (re-search-forward (if forwardp beg end) cl t dir)))
+ (point)))))
+ (cond
+ ((not cl)
+ (goto-char (if forwardp (point-max) (point-min)))
+ (set-match-data nil)
+ (throw 'done count))
+ (t
+ (if op
+ (progn
+ (setq count (if forwardp (1+ count) (1- count)))
+ (goto-char op))
+ (setq count (if forwardp (1- count) (1+ count)))
+ (if (zerop count) (set-match-data match))
+ (goto-char cl))))))
+ 0)))
+
+(defun evil-up-paren (open close &optional count)
+ "Move point to the end or beginning of balanced parentheses.
+OPEN and CLOSE should be characters identifying the opening and
+closing parenthesis, respectively. If COUNT is greater than zero
+point is moved forward otherwise it is moved backwards. Whenever
+an opening delimiter is found the COUNT is increased by one, if a
+closing delimiter is found the COUNT is decreased by one. The
+motion stops when COUNT reaches zero. The match-data reflects the
+last successful match (that caused COUNT to reach zero)."
+ ;; Always use the default `forward-sexp-function'. This is important
+ ;; for modes that use a custom one like `python-mode'.
+ ;; (addresses #364)
+ (let (forward-sexp-function)
+ (with-syntax-table (copy-syntax-table (syntax-table))
+ (modify-syntax-entry open (format "(%c" close))
+ (modify-syntax-entry close (format ")%c" open))
+ (let ((rest (evil-motion-loop (dir count)
+ (let ((pnt (point)))
+ (condition-case nil
+ (cond
+ ((> dir 0)
+ (while (progn
+ (up-list dir)
+ (/= (char-before) close))))
+ (t
+ (while (progn
+ (up-list dir)
+ (/= (char-after) open)))))
+ (error (goto-char pnt)))))))
+ (cond
+ ((= rest count) (set-match-data nil))
+ ((> count 0) (set-match-data (list (1- (point)) (point))))
+ (t (set-match-data (list (point) (1+ (point))))))
+ rest))))
+
+(defun evil-up-xml-tag (&optional count)
+ "Move point to the end or beginning of balanced xml tags.
+OPEN and CLOSE should be characters identifying the opening and
+closing parenthesis, respectively. If COUNT is greater than zero
+point is moved forward otherwise it is moved backwards. Whenever
+an opening delimiter is found the COUNT is increased by one, if a
+closing delimiter is found the COUNT is decreased by one. The
+motion stops when COUNT reaches zero. The match-data reflects the
+last successful match (that caused COUNT to reach zero)."
+ (let* ((dir (if (> (or count 1) 0) +1 -1))
+ (count (abs (or count 1)))
+ (op (if (> dir 0) 1 2))
+ (cl (if (> dir 0) 2 1))
+ (orig (point))
+ pnt tags match)
+ (catch 'done
+ (while (> count 0)
+ ;; find the previous opening tag
+ (while
+ (and (setq match
+ (re-search-forward
+ "<\\([^/ >\n]+\\)\\(?:=>?\\|[^\"/>]\\|\"[^\"]*\"\\)*?>\\|</\\([^>]+?\\)>"
+ nil t dir))
+ (cond
+ ((match-beginning op)
+ (push (match-string op) tags))
+ ((null tags) nil) ; free closing tag
+ ((and (< dir 0)
+ (string= (car tags) (match-string cl)))
+ ;; in backward direction we only accept matching
+ ;; tags. If the current tag is a free opener
+ ;; without matching closing tag, the subsequents
+ ;; test will make us ignore this tag
+ (pop tags))
+ ((and (> dir 0))
+ ;; non matching openers are considered free openers
+ (while (and tags
+ (not (string= (car tags)
+ (match-string cl))))
+ (pop tags))
+ (pop tags)))))
+ (unless (setq match (and match (match-data t)))
+ (setq match nil)
+ (throw 'done count))
+ ;; found closing tag, look for corresponding opening tag
+ (cond
+ ((> dir 0)
+ (setq pnt (match-end 0))
+ (goto-char (match-beginning 0)))
+ (t
+ (setq pnt (match-beginning 0))
+ (goto-char (match-end 0))))
+ (let* ((tag (match-string cl))
+ (refwd (concat "<\\(/\\)?"
+ (regexp-quote tag)
+ "\\(?:>\\|[ \n]\\(?:[^\"/>]\\|\"[^\"]*\"\\)*?>\\)"))
+ (cnt 1))
+ (while (and (> cnt 0) (re-search-backward refwd nil t dir))
+ (setq cnt (+ cnt (if (match-beginning 1) dir (- dir)))))
+ (if (zerop cnt) (setq count (1- count) tags nil))
+ (goto-char pnt)))
+ (if (> count 0)
+ (set-match-data nil)
+ (set-match-data match)
+ (goto-char (if (> dir 0) (match-end 0) (match-beginning 0)))))
+ ;; if not found, set to point-max/point-min
+ (unless (zerop count)
+ (set-match-data nil)
+ (goto-char (if (> dir 0) (point-max) (point-min)))
+ (if (/= (point) orig) (setq count (1- count))))
+ (* dir count)))
+
+(defun evil-forward-quote (quote &optional count)
+ "Move point to the end or beginning of a string.
+QUOTE is the character delimiting the string. If COUNT is greater
+than zero point is moved forward otherwise it is moved
+backwards."
+ (let (reset-parser)
+ (with-syntax-table (copy-syntax-table (syntax-table))
+ (unless (= (char-syntax quote) ?\")
+ (modify-syntax-entry quote "\"")
+ (setq reset-parser t))
+ ;; global parser state is out of state, use local one
+ (let* ((pnt (point))
+ (state (save-excursion
+ (beginning-of-defun)
+ (parse-partial-sexp (point) pnt nil nil (syntax-ppss))))
+ (bnd (bounds-of-evil-string-at-point state)))
+ (when (and bnd (< (point) (cdr bnd)))
+ ;; currently within a string
+ (if (> count 0)
+ (progn
+ (goto-char (cdr bnd))
+ (setq count (1- count)))
+ (goto-char (car bnd))
+ (setq count (1+ count))))
+ ;; forward motions work with local parser state
+ (cond
+ ((> count 0)
+ ;; no need to reset global parser state because we only use
+ ;; the local one
+ (setq reset-parser nil)
+ (catch 'done
+ (while (and (> count 0) (not (eobp)))
+ (setq state (parse-partial-sexp (point) (point-max)
+ nil
+ nil
+ state
+ 'syntax-table))
+ (cond
+ ((nth 3 state)
+ (setq bnd (bounds-of-thing-at-point 'evil-string))
+ (goto-char (cdr bnd))
+ (setq count (1- count)))
+ ((eobp) (goto-char pnt) (throw 'done nil))))))
+ ((< count 0)
+ ;; need to update global cache because of backward motion
+ (setq reset-parser (and reset-parser (point)))
+ (save-excursion
+ (beginning-of-defun)
+ (syntax-ppss-flush-cache (point)))
+ (catch 'done
+ (while (and (< count 0) (not (bobp)))
+ (setq pnt (point))
+ (while (and (not (bobp))
+ (or (eobp) (/= (char-after) quote)))
+ (backward-char))
+ (cond
+ ((setq bnd (bounds-of-thing-at-point 'evil-string))
+ (goto-char (car bnd))
+ (setq count (1+ count)))
+ ((bobp) (goto-char pnt) (throw 'done nil))
+ (t (backward-char))))))
+ (t (setq reset-parser nil)))))
+ (when reset-parser
+ ;; reset global cache
+ (save-excursion
+ (goto-char reset-parser)
+ (beginning-of-defun)
+ (syntax-ppss-flush-cache (point))))
+ count))
+
+;;; Thing-at-point motion functions for Evil text objects and motions
+(defun forward-evil-empty-line (&optional count)
+ "Move forward COUNT empty lines."
+ (setq count (or count 1))
+ (cond
+ ((> count 0)
+ (while (and (> count 0) (not (eobp)))
+ (when (and (bolp) (eolp))
+ (setq count (1- count)))
+ (forward-line 1)))
+ (t
+ (while (and (< count 0) (not (bobp))
+ (zerop (forward-line -1)))
+ (when (and (bolp) (eolp))
+ (setq count (1+ count))))))
+ count)
+
+(defun forward-evil-space (&optional count)
+ "Move forward COUNT whitespace sequences [[:space:]]+."
+ (evil-forward-chars "[:space:]" count))
+
+(defun forward-evil-word (&optional count)
+ "Move forward COUNT words.
+Moves point COUNT words forward or (- COUNT) words backward if
+COUNT is negative. Point is placed after the end of the word (if
+forward) or at the first character of the word (if backward). A
+word is a sequence of word characters matching
+\[[:word:]] (recognized by `forward-word'), a sequence of
+non-whitespace non-word characters '[^[:word:]\\n\\r\\t\\f ]', or
+an empty line matching ^$."
+ (evil-forward-nearest
+ count
+ #'(lambda (&optional cnt)
+ (let ((word-separating-categories evil-cjk-word-separating-categories)
+ (word-combining-categories evil-cjk-word-combining-categories)
+ (pnt (point)))
+ (forward-word cnt)
+ (if (= pnt (point)) cnt 0)))
+ #'(lambda (&optional cnt)
+ (evil-forward-chars "^[:word:]\n\r\t\f " cnt))
+ #'forward-evil-empty-line))
+
+(defun forward-evil-WORD (&optional count)
+ "Move forward COUNT \"WORDS\".
+Moves point COUNT WORDS forward or (- COUNT) WORDS backward if
+COUNT is negative. Point is placed after the end of the WORD (if
+forward) or at the first character of the WORD (if backward). A
+WORD is a sequence of non-whitespace characters
+'[^\\n\\r\\t\\f ]', or an empty line matching ^$."
+ (evil-forward-nearest count
+ #'(lambda (&optional cnt)
+ (evil-forward-chars "^\n\r\t\f " cnt))
+ #'forward-evil-empty-line))
+
+(defun forward-evil-symbol (&optional count)
+ "Move forward COUNT symbols.
+Moves point COUNT symbols forward or (- COUNT) symbols backward
+if COUNT is negative. Point is placed after the end of the
+symbol (if forward) or at the first character of the symbol (if
+backward). A symbol is either determined by `forward-symbol', or
+is a sequence of characters not in the word, symbol or whitespace
+syntax classes."
+ (evil-forward-nearest
+ count
+ #'(lambda (&optional cnt)
+ (evil-forward-syntax "^w_->" cnt))
+ #'(lambda (&optional cnt)
+ (let ((pnt (point)))
+ (forward-symbol cnt)
+ (if (= pnt (point)) cnt 0)))
+ #'forward-evil-empty-line))
+
+(defun forward-evil-defun (&optional count)
+ "Move forward COUNT defuns.
+Moves point COUNT defuns forward or (- COUNT) defuns backward
+if COUNT is negative. A defun is defined by
+`beginning-of-defun' and `end-of-defun' functions."
+ (evil-motion-loop (dir (or count 1))
+ (if (> dir 0) (end-of-defun) (beginning-of-defun))))
+
+(defun forward-evil-sentence (&optional count)
+ "Move forward COUNT sentences.
+Moves point COUNT sentences forward or (- COUNT) sentences
+backward if COUNT is negative. This function is the same as
+`forward-sentence' but returns the number of sentences that could
+NOT be moved over."
+ (evil-motion-loop (dir (or count 1))
+ (condition-case nil
+ (forward-sentence dir)
+ (error))))
+
+(defun forward-evil-paragraph (&optional count)
+ "Move forward COUNT paragraphs.
+Moves point COUNT paragraphs forward or (- COUNT) paragraphs backward
+if COUNT is negative. A paragraph is defined by
+`start-of-paragraph-text' and `forward-paragraph' functions."
+ (evil-motion-loop (dir (or count 1))
+ (cond
+ ((> dir 0) (forward-paragraph))
+ ((not (bobp)) (start-of-paragraph-text) (beginning-of-line)))))
+
+(defvar evil-forward-quote-char ?\"
+ "The character to be used by `forward-evil-quote'.")
+
+(defun forward-evil-quote (&optional count)
+ "Move forward COUNT strings.
+The quotation character is specified by the global variable
+`evil-forward-quote-char'. This character is passed to
+`evil-forward-quote'."
+ (evil-forward-quote evil-forward-quote-char count))
+
+(defun forward-evil-quote-simple (&optional count)
+ "Move forward COUNT strings.
+The quotation character is specified by the global variable
+`evil-forward-quote-char'. This functions uses Vim's rules
+parsing from the beginning of the current line for quotation
+characters. It should only be used when looking for strings
+within comments and buffer *must* be narrowed to the comment."
+ (let ((dir (if (> (or count 1) 0) 1 -1))
+ (ch evil-forward-quote-char)
+ (pnt (point))
+ (cnt 0))
+ (beginning-of-line)
+ ;; count number of quotes before pnt
+ (while (< (point) pnt)
+ (when (= (char-after) ch)
+ (setq cnt (1+ cnt)))
+ (forward-char))
+ (setq cnt (- (* 2 (abs count)) (mod cnt 2)))
+ (cond
+ ((> dir 0)
+ (while (and (not (eolp)) (not (zerop cnt)))
+ (when (= (char-after) ch) (setq cnt (1- cnt)))
+ (forward-char))
+ (when (not (zerop cnt)) (goto-char (point-max))))
+ (t
+ (while (and (not (bolp)) (not (zerop cnt)))
+ (when (= (char-before) ch) (setq cnt (1- cnt)))
+ (forward-char -1))
+ (when (not (zerop cnt)) (goto-char (point-min)))))
+ (/ cnt 2)))
+
+;;; Motion functions
+(defun evil-forward-beginning (thing &optional count)
+ "Move forward to beginning of THING.
+The motion is repeated COUNT times."
+ (setq count (or count 1))
+ (if (< count 0)
+ (forward-thing thing count)
+ (let ((bnd (bounds-of-thing-at-point thing))
+ rest)
+ (when (and bnd (< (point) (cdr bnd)))
+ (goto-char (cdr bnd)))
+ (condition-case nil
+ (when (zerop (setq rest (forward-thing thing count)))
+ (when (and (bounds-of-thing-at-point thing)
+ (not (bobp))
+ ;; handle final empty line
+ (not (and (bolp) (eobp))))
+ (forward-char -1))
+ (beginning-of-thing thing))
+ (error))
+ rest)))
+
+(defun evil-backward-beginning (thing &optional count)
+ "Move backward to beginning of THING.
+The motion is repeated COUNT times. This is the same as calling
+`evil-backward-beginning' with -COUNT."
+ (evil-forward-beginning thing (- (or count 1))))
+
+(defun evil-forward-end (thing &optional count)
+ "Move forward to end of THING.
+The motion is repeated COUNT times."
+ (setq count (or count 1))
+ (cond
+ ((> count 0)
+ (unless (eobp) (forward-char))
+ (prog1 (forward-thing thing count)
+ (unless (bobp) (forward-char -1))))
+ (t
+ (let ((bnd (bounds-of-thing-at-point thing))
+ rest)
+ (when (and bnd (< (point) (cdr bnd) ))
+ (goto-char (car bnd)))
+ (condition-case nil
+ (when (zerop (setq rest (forward-thing thing count)))
+ (end-of-thing thing)
+ (forward-char -1))
+ (error))
+ rest))))
+
+(defun evil-backward-end (thing &optional count)
+ "Move backward to end of THING.
+The motion is repeated COUNT times. This is the same as calling
+`evil-backward-end' with -COUNT."
+ (evil-forward-end thing (- (or count 1))))
+
+(defun evil-forward-word (&optional count)
+ "Move by words.
+Moves point COUNT words forward or (- COUNT) words backward if
+COUNT is negative. This function is the same as `forward-word'
+but returns the number of words by which point could *not* be
+moved."
+ (setq count (or count 1))
+ (let* ((dir (if (>= count 0) +1 -1))
+ (count (abs count)))
+ (while (and (> count 0)
+ (forward-word dir))
+ (setq count (1- count)))
+ count))
+
+(defun evil-in-comment-p (&optional pos)
+ "Checks if POS is within a comment according to current syntax.
+If POS is nil, (point) is used. The return value is the beginning
+position of the comment."
+ (setq pos (or pos (point)))
+ (let ((chkpos
+ (cond
+ ((eobp) pos)
+ ((= (char-syntax (char-after)) ?<) (1+ pos))
+ ((and (not (zerop (logand (car (syntax-after (point)))
+ (lsh 1 16))))
+ (not (zerop (logand (or (car (syntax-after (1+ (point)))) 0)
+ (lsh 1 17)))))
+ (+ pos 2))
+ ((and (not (zerop (logand (car (syntax-after (point)))
+ (lsh 1 17))))
+ (not (zerop (logand (or (car (syntax-after (1- (point)))) 0)
+ (lsh 1 16)))))
+ (1+ pos))
+ (t pos))))
+ (let ((syn (save-excursion (syntax-ppss chkpos))))
+ (and (nth 4 syn) (nth 8 syn)))))
+
+(defun evil-looking-at-start-comment (&optional move)
+ "Returns t if point is at the start of a comment.
+point must be on one of the opening characters of a block comment
+according to the current syntax table. Futhermore these
+characters must been parsed as opening characters, i.e. they
+won't be considered as comment starters inside a string or
+possibly another comment. Point is moved to the first character
+of the comment opener if MOVE is non-nil."
+ (cond
+ ;; one character opener
+ ((= (char-syntax (char-after)) ?<)
+ (equal (point) (evil-in-comment-p (1+ (point)))))
+ ;; two character opener on first char
+ ((and (not (zerop (logand (car (syntax-after (point)))
+ (lsh 1 16))))
+ (not (zerop (logand (or (car (syntax-after (1+ (point)))) 0)
+ (lsh 1 17)))))
+ (equal (point) (evil-in-comment-p (+ 2 (point)))))
+ ;; two character opener on second char
+ ((and (not (zerop (logand (car (syntax-after (point)))
+ (lsh 1 17))))
+ (not (zerop (logand (or (car (syntax-after (1- (point)))) 0)
+ (lsh 1 16)))))
+ (and (equal (1- (point)) (evil-in-comment-p (1+ (point))))
+ (prog1 t (when move (backward-char)))))))
+
+(defun evil-looking-at-end-comment (&optional move)
+ "Returns t if point is at the end of a comment.
+point must be on one of the opening characters of a block comment
+according to the current syntax table. Futhermore these
+characters must been parsed as opening characters, i.e. they
+won't be considered as comment starters inside a string or
+possibly another comment. Point is moved right after the comment
+closer if MOVE is non-nil."
+ (cond
+ ;; one char closer
+ ((= (char-syntax (char-after)) ?>)
+ (and (evil-in-comment-p) ; in comment
+ (not (evil-in-comment-p (1+ (point))))
+ (prog1 t (when move (forward-char)))))
+ ;; two char closer on first char
+ ((and (not (zerop (logand (car (syntax-after (point)))
+ (lsh 1 18))))
+ (not (zerop (logand (or (car (syntax-after (1+ (point)))) 0)
+ (lsh 1 19)))))
+ (and (evil-in-comment-p)
+ (not (evil-in-comment-p (+ (point) 2)))
+ (prog1 t (when move (forward-char 2)))))
+ ;; two char closer on second char
+ ((and (not (zerop (logand (car (syntax-after (point)))
+ (lsh 1 19))))
+ (not (zerop (logand (or (car (syntax-after (1- (point)))) 0)
+ (lsh 1 18)))))
+ (and (evil-in-comment-p)
+ (not (evil-in-comment-p (1+ (point))))
+ (prog1 t (when move (forward-char)))))))
+
+(defun evil-insert-newline-above ()
+ "Inserts a new line above point and places point in that line
+with regard to indentation."
+ (evil-narrow-to-field
+ (evil-move-beginning-of-line)
+ (insert (if use-hard-newlines hard-newline "\n"))
+ (forward-line -1)
+ (back-to-indentation)))
+
+(defun evil-insert-newline-below ()
+ "Inserts a new line below point and places point in that line
+with regard to indentation."
+ (evil-narrow-to-field
+ (evil-move-end-of-line)
+ (insert (if use-hard-newlines hard-newline "\n"))
+ (back-to-indentation)))
+
+;;; Markers
+
+(defun evil-global-marker-p (char)
+ "Whether CHAR denotes a global marker."
+ (or (and (>= char ?A) (<= char ?Z))
+ (assq char (default-value 'evil-markers-alist))))
+
+(defun evil-set-marker (char &optional pos advance)
+ "Set the marker denoted by CHAR to position POS.
+POS defaults to the current position of point.
+If ADVANCE is t, the marker advances when inserting text at it;
+otherwise, it stays behind."
+ (interactive (list (read-char)))
+ (catch 'done
+ (let ((marker (evil-get-marker char t)) alist)
+ (unless (markerp marker)
+ (cond
+ ((and marker (symbolp marker) (boundp marker))
+ (set marker (or (symbol-value marker) (make-marker)))
+ (setq marker (symbol-value marker)))
+ ((eq marker 'evil-jump-backward-swap)
+ (evil-set-jump)
+ (throw 'done nil))
+ ((functionp marker)
+ (user-error "Cannot set special marker `%c'" char))
+ ((evil-global-marker-p char)
+ (setq alist (default-value 'evil-markers-alist)
+ marker (make-marker))
+ (evil--add-to-alist 'alist char marker)
+ (setq-default evil-markers-alist alist))
+ (t
+ (setq marker (make-marker))
+ (evil--add-to-alist 'evil-markers-alist char marker))))
+ (add-hook 'kill-buffer-hook #'evil-swap-out-markers nil t)
+ (set-marker-insertion-type marker advance)
+ (set-marker marker (or pos (point))))))
+
+(defun evil-get-marker (char &optional raw)
+ "Return the marker denoted by CHAR.
+This is either a marker object as returned by `make-marker',
+a number, a cons cell (FILE . POS) with FILE being a string
+and POS a number, or nil. If RAW is non-nil, then the
+return value may also be a variable, a movement function,
+or a marker object pointing nowhere."
+ (let ((marker (if (evil-global-marker-p char)
+ (cdr-safe (assq char (default-value
+ 'evil-markers-alist)))
+ (cdr-safe (assq char evil-markers-alist)))))
+ (save-excursion
+ (if raw
+ marker
+ (when (and (symbolp marker) (boundp marker))
+ (setq marker (symbol-value marker)))
+ (when (functionp marker)
+ (save-window-excursion
+ (funcall marker)
+ (setq marker (move-marker (make-marker) (point)))))
+ (when (markerp marker)
+ (if (eq (marker-buffer marker) (current-buffer))
+ (setq marker (marker-position marker))
+ (setq marker (and (marker-buffer marker) marker))))
+ (when (or (numberp marker)
+ (markerp marker)
+ (and (consp marker)
+ (stringp (car marker))
+ (numberp (cdr marker))))
+ marker)))))
+
+(defun evil-swap-out-markers ()
+ "Turn markers into file references when the buffer is killed."
+ (and buffer-file-name
+ (dolist (entry evil-markers-alist)
+ (and (markerp (cdr entry))
+ (eq (marker-buffer (cdr entry)) (current-buffer))
+ (setcdr entry (cons buffer-file-name
+ (marker-position (cdr entry))))))))
+(put 'evil-swap-out-markers 'permanent-local-hook t)
+
+(defun evil--eval-expr (input)
+ "Eval INPUT and return stringified result, if of a suitable type.
+If INPUT starts with a number, +, -, or . use `calc-eval' instead."
+ (let* ((first-char (car (remove ?\s (string-to-list input))))
+ (calcable-p (and first-char (or (<= ?0 first-char ?9)
+ (memq first-char '(?- ?+ ?.)))))
+ (result (if calcable-p
+ (let ((calc-multiplication-has-precedence nil))
+ (calc-eval input))
+ (eval (car (read-from-string input))))))
+ (cond
+ (calcable-p result)
+ ((or (stringp result)
+ (numberp result)
+ (symbolp result))
+ (format "%s" result))
+ ((sequencep result)
+ (mapconcat (lambda (x) (format "%s" x)) result "\n"))
+ (t (user-error "Using %s as a string" (type-of result))))))
+
+(defvar evil-paste-clear-minibuffer-first nil
+ "`evil-paste-before' cannot have `delete-minibuffer-contents' called before
+it fetches certain registers becuase this would trigger various ex-updates,
+sometimes moving point, so `C-a' `C-w' etc. would miss their intended target.")
+
+(defun evil-ex-remove-default ()
+ "Remove the default text shown in the ex minibuffer.
+When ex starts, the previous command is shown enclosed in
+parenthesis. This function removes this text when the first key
+is pressed."
+ (when (and (not (eq this-command 'exit-minibuffer))
+ (/= (minibuffer-prompt-end) (point-max)))
+ (if (eq this-command 'evil-ex-delete-backward-char)
+ (setq this-command 'ignore))
+ (if (eq this-original-command 'evil-paste-from-register)
+ (setq evil-paste-clear-minibuffer-first t)
+ (delete-minibuffer-contents)))
+ (remove-hook 'pre-command-hook #'evil-ex-remove-default))
+(put 'evil-ex-remove-default 'permanent-local-hook t)
+
+(defun evil-get-register (register &optional noerror)
+ "Return contents of REGISTER.
+Signal an error if empty, unless NOERROR is non-nil.
+
+The following special registers are supported.
+ \" the unnamed register
+ * the clipboard contents
+ + the clipboard contents
+ <C-w> the word at point (ex mode only)
+ <C-a> the WORD at point (ex mode only)
+ <C-o> the symbol at point (ex mode only)
+ <C-f> the current file at point (ex mode only)
+ % the current file name (read only)
+ # the alternate file name (read only)
+ / the last search pattern (read only)
+ : the last command line (read only)
+ . the last inserted text (read only)
+ - the last small (less than a line) delete
+ _ the black hole register
+ = the expression register (read only)"
+ (condition-case err
+ (when (characterp register)
+ (or (cond
+ ((eq register ?\")
+ (current-kill 0))
+ ((<= ?1 register ?9)
+ (let ((reg (- register ?1)))
+ (and (< reg (length kill-ring))
+ (current-kill reg t))))
+ ((memq register '(?* ?+))
+ ;; the following code is modified from
+ ;; `x-selection-value-internal'
+ (let ((what (if (eq register ?*) 'PRIMARY 'CLIPBOARD))
+ (request-type (or (and (boundp 'x-select-request-type)
+ x-select-request-type)
+ '(UTF8_STRING COMPOUND_TEXT STRING)))
+ text)
+ (unless (consp request-type)
+ (setq request-type (list request-type)))
+ (while (and request-type (not text))
+ (condition-case nil
+ (setq text (evil-get-selection what (pop request-type)))
+ (error nil)))
+ (when text
+ (remove-text-properties 0 (length text) '(foreign-selection nil) text))
+ text))
+ ((eq register ?\C-W)
+ (unless (evil-ex-p)
+ (user-error "Register <C-w> only available in ex state"))
+ (with-current-buffer evil-ex-current-buffer
+ (thing-at-point 'evil-word)))
+ ((eq register ?\C-A)
+ (unless (evil-ex-p)
+ (user-error "Register <C-a> only available in ex state"))
+ (with-current-buffer evil-ex-current-buffer
+ (thing-at-point 'evil-WORD)))
+ ((eq register ?\C-O)
+ (unless (evil-ex-p)
+ (user-error "Register <C-o> only available in ex state"))
+ (with-current-buffer evil-ex-current-buffer
+ (thing-at-point 'evil-symbol)))
+ ((eq register ?\C-F)
+ (unless (evil-ex-p)
+ (user-error "Register <C-f> only available in ex state"))
+ (with-current-buffer evil-ex-current-buffer
+ (thing-at-point 'filename)))
+ ((eq register ?\C-L)
+ (unless (evil-ex-p)
+ (user-error "Register <C-l> only available in ex state"))
+ (with-current-buffer evil-ex-current-buffer
+ (replace-regexp-in-string "\n\\'" "" (thing-at-point 'line))))
+ ((eq register ?%)
+ (or (buffer-file-name (and (evil-ex-p)
+ (minibufferp)
+ evil-ex-current-buffer))
+ (user-error "No file name")))
+ ((= register ?#)
+ (or (with-current-buffer (other-buffer) (buffer-file-name))
+ (user-error "No file name")))
+ ((eq register ?/)
+ (or (car-safe
+ (or (and (boundp 'evil-search-module)
+ (eq evil-search-module 'evil-search)
+ evil-ex-search-history)
+ (and isearch-regexp regexp-search-ring)
+ search-ring))
+ (user-error "No previous regular expression")))
+ ((eq register ?:)
+ (or (car-safe evil-ex-history)
+ (user-error "No previous command line")))
+ ((eq register ?.)
+ evil-last-insertion)
+ ((eq register ?-)
+ evil-last-small-deletion)
+ ((eq register ?=)
+ (let ((enable-recursive-minibuffers t))
+ (setq evil-last-=-register-input
+ (minibuffer-with-setup-hook
+ (lambda () (when evil-last-=-register-input
+ (add-hook 'pre-command-hook #'evil-ex-remove-default)))
+ (read-from-minibuffer
+ "="
+ (and evil-last-=-register-input
+ (propertize evil-last-=-register-input 'face 'shadow))
+ evil-eval-map
+ nil
+ 'evil-eval-history
+ evil-last-=-register-input
+ t)))
+ (evil--eval-expr evil-last-=-register-input)))
+ ((eq register ?_) ; the black hole register
+ "")
+ (t
+ (setq register (downcase register))
+ (get-register register)))
+ (user-error "Register `%c' is empty" register)))
+ (error (unless noerror (signal (car err) (cdr err))))))
+
+(defun evil-append-register (register text)
+ "Append TEXT to the contents of register REGISTER."
+ (let ((content (get-register register)))
+ (cond
+ ((not content)
+ (set-register register text))
+ ((or (text-property-not-all 0 (length content)
+ 'yank-handler nil
+ content)
+ (text-property-not-all 0 (length text)
+ 'yank-handler nil
+ text))
+ ;; some non-trivial yank-handler -> always switch to line handler
+ ;; ensure complete lines
+ (when (and (> (length content) 0)
+ (/= (aref content (1- (length content))) ?\n))
+ (setq content (concat content "\n")))
+ (when (and (> (length text) 0)
+ (/= (aref text (1- (length text))) ?\n))
+ (setq text (concat text "\n")))
+ (setq text (concat content text))
+ (remove-list-of-text-properties 0 (length text) '(yank-handler) text)
+ (setq text (propertize text 'yank-handler '(evil-yank-line-handler)))
+ (set-register register text))
+ (t
+ (set-register register (concat content text))))))
+
+(defun evil-set-register (register text)
+ "Set the contents of register REGISTER to TEXT.
+If REGISTER is an upcase character then text is appended to that
+register instead of replacing its content."
+ (cond
+ ((not (characterp register))
+ (user-error "Invalid register"))
+ ;; don't allow modification of read-only registers
+ ((member register '(?: ?. ?%))
+ (user-error "Can't modify read-only register"))
+ ((eq register ?\")
+ (kill-new text))
+ ((and (<= ?1 register) (<= register ?9))
+ (if (null kill-ring)
+ (kill-new text)
+ (let ((kill-ring-yank-pointer kill-ring-yank-pointer)
+ interprogram-paste-function
+ interprogram-cut-function)
+ (current-kill (- register ?1))
+ (setcar kill-ring-yank-pointer text))))
+ ((eq register ?*)
+ (evil-set-selection 'PRIMARY text))
+ ((eq register ?+)
+ (evil-set-selection 'CLIPBOARD text))
+ ((eq register ?-)
+ (setq evil-last-small-deletion text))
+ ((eq register ?_) ; the black hole register
+ nil)
+ ((and (<= ?A register) (<= register ?Z))
+ (evil-append-register (downcase register) text))
+ (t
+ (set-register register text))))
+
+(defun evil-register-list ()
+ "Returns an alist of all registers, but only those named
+with number or character. Registers with symbol or string in names are ignored
+to keep Vim compatibility with register jumps."
+ (sort (append (mapcar #'(lambda (reg)
+ (cons reg (evil-get-register reg t)))
+ '(?\" ?* ?+ ?% ?# ?/ ?: ?. ?-
+ ?1 ?2 ?3 ?4 ?5 ?6 ?7 ?8 ?9))
+ (list (cons ?= evil-last-=-register-input))
+ (cl-remove-if-not (lambda (reg) (number-or-marker-p (car reg))) register-alist)
+ nil)
+ #'(lambda (reg1 reg2) (< (car reg1) (car reg2)))))
+
+(defsubst evil-kbd-macro-suppress-motion-error ()
+ "Returns non-nil if a motion error should be suppressed.
+Whether the motion error should be suppressed depends on the
+variable `evil-kbd-macro-suppress-motion-error'."
+ (or (and defining-kbd-macro
+ (memq evil-kbd-macro-suppress-motion-error '(t record)))
+ (and executing-kbd-macro
+ (memq evil-kbd-macro-suppress-motion-error '(t replay)))))
+
+;;; Region
+
+;; `set-mark' does too much at once
+(defun evil-move-mark (pos)
+ "Set buffer's mark to POS.
+If POS is nil, delete the mark."
+ (when pos
+ (setq pos (evil-normalize-position pos)))
+ (set-marker (mark-marker) pos))
+
+(defun evil-save-transient-mark-mode ()
+ "Save Transient Mark mode and make it buffer-local.
+Any changes to Transient Mark mode are now local to the current
+buffer, until `evil-restore-transient-mark-mode' is called.
+
+Variables pertaining to Transient Mark mode are listed in
+`evil-transient-vars', and their values are stored in
+`evil-transient-vals'."
+ (dolist (var evil-transient-vars)
+ (when (and (boundp var)
+ (not (assq var evil-transient-vals)))
+ (push (list var (symbol-value var)
+ (local-variable-p var))
+ evil-transient-vals)
+ (make-variable-buffer-local var)
+ (put var 'permanent-local t))))
+
+(defun evil-restore-transient-mark-mode ()
+ "Restore Transient Mark mode.
+This presupposes that `evil-save-transient-mark-mode' has been
+called earlier. If Transient Mark mode was disabled before but
+enabled in the meantime, this function disables it; if it was
+enabled before but disabled in the meantime, this function
+enables it.
+
+The earlier settings of Transient Mark mode are stored in
+`evil-transient-vals'."
+ (let (entry local var val)
+ (while (setq entry (pop evil-transient-vals))
+ (setq var (pop entry)
+ val (pop entry)
+ local (pop entry))
+ (unless local
+ (kill-local-variable var))
+ (unless (equal (symbol-value var) val)
+ (if (fboundp var)
+ (funcall var (if val 1 -1))
+ (setq var val))))))
+
+(defun evil-save-mark ()
+ "Save the current mark, including whether it is transient.
+See also `evil-restore-mark'."
+ (unless evil-visual-previous-mark
+ (setq evil-visual-previous-mark (mark t))
+ (evil-save-transient-mark-mode)))
+
+(defun evil-restore-mark ()
+ "Restore the mark, including whether it was transient.
+See also `evil-save-mark'."
+ (when evil-visual-previous-mark
+ (evil-restore-transient-mark-mode)
+ (evil-move-mark evil-visual-previous-mark)
+ (setq evil-visual-previous-mark nil)))
+
+;; In theory, an active region implies Transient Mark mode, and
+;; disabling Transient Mark mode implies deactivating the region.
+;; In practice, Emacs never clears `mark-active' except in Transient
+;; Mark mode, so we define our own toggle functions to make things
+;; more predictable.
+(defun evil-transient-mark (&optional arg)
+ "Toggle Transient Mark mode.
+Ensure that the region is properly deactivated.
+Enable with positive ARG, disable with negative ARG."
+ (unless (numberp arg)
+ (setq arg (if transient-mark-mode -1 1)))
+ (cond
+ ((< arg 1)
+ (evil-active-region -1)
+ ;; Transient Mark mode cannot be disabled
+ ;; while CUA mode is enabled
+ (when (fboundp 'cua-mode)
+ (cua-mode -1))
+ (when transient-mark-mode
+ (transient-mark-mode -1)))
+ (t
+ (unless transient-mark-mode
+ (evil-active-region -1)
+ (transient-mark-mode 1)))))
+
+(defun evil-active-region (&optional arg)
+ "Toggle active region.
+Ensure that Transient Mark mode is properly enabled.
+Enable with positive ARG, disable with negative ARG."
+ (unless (numberp arg)
+ (setq arg (if (region-active-p) -1 1)))
+ (cond
+ ((and (< arg 1))
+ (when (or transient-mark-mode mark-active)
+ (setq mark-active nil
+ deactivate-mark nil)
+ (when (boundp 'cua--explicit-region-start)
+ (setq cua--explicit-region-start nil))
+ (run-hooks 'deactivate-mark-hook)))
+ (t
+ (evil-transient-mark 1)
+ (when deactivate-mark
+ (setq deactivate-mark nil))
+ (unless (mark t)
+ (evil-move-mark (point)))
+ (unless (region-active-p)
+ (set-mark (mark t)))
+ (when (boundp 'cua--explicit-region-start)
+ (setq cua--explicit-region-start t)))))
+
+(defmacro evil-with-transient-mark-mode (&rest body)
+ "Execute BODY with Transient Mark mode.
+Then restore Transient Mark mode to its previous setting."
+ (declare (indent defun)
+ (debug t))
+ `(let ((inhibit-quit t)
+ evil-transient-vals)
+ (unwind-protect
+ (progn
+ (evil-save-transient-mark-mode)
+ (evil-transient-mark 1)
+ ,@body)
+ (evil-restore-transient-mark-mode))))
+
+(defmacro evil-with-active-region (beg end &rest body)
+ "Execute BODY with an active region from BEG to END."
+ (declare (indent 2)
+ (debug t))
+ `(let ((beg ,beg) (end ,end)
+ evil-transient-vals)
+ (evil-with-transient-mark-mode
+ (save-excursion
+ (evil-active-region 1)
+ (evil-move-mark beg)
+ (goto-char end)
+ ,@body))))
+
+(defun evil-exchange-point-and-mark ()
+ "Exchange point and mark without activating the region."
+ (let* ((point (point))
+ (mark (or (mark t) point)))
+ (set-marker (mark-marker) point)
+ (goto-char mark)))
+
+(defun evil-apply-on-block (func beg end pass-columns &rest args)
+ "Call FUNC for each line of a block selection.
+The selection is specified by the region BEG and END. FUNC must
+take at least two arguments, the beginning and end of each
+line. If PASS-COLUMNS is non-nil, these values are the columns,
+otherwise they are buffer positions. Extra arguments to FUNC may
+be passed via ARGS."
+ (let ((eol-col (and (memq last-command '(next-line previous-line))
+ (numberp temporary-goal-column)
+ temporary-goal-column))
+ startcol startpt endcol endpt)
+ (save-excursion
+ (goto-char beg)
+ (setq startcol (current-column))
+ (beginning-of-line)
+ (setq startpt (point))
+ (goto-char end)
+ (setq endcol (current-column))
+ (forward-line 1)
+ (setq endpt (point-marker))
+ ;; ensure the start column is the left one.
+ (evil-sort startcol endcol)
+ ;; maybe find maximal column
+ (when eol-col
+ (setq eol-col 0)
+ (goto-char startpt)
+ (while (< (point) endpt)
+ (setq eol-col (max eol-col
+ (evil-column (line-end-position))))
+ (forward-line 1))
+ (setq endcol (max endcol
+ (min eol-col
+ (1+ (min (1- most-positive-fixnum)
+ (truncate temporary-goal-column)))))))
+ ;; start looping over lines
+ (goto-char startpt)
+ (while (< (point) endpt)
+ (if pass-columns
+ (apply func startcol endcol args)
+ (apply func
+ (save-excursion (evil-move-to-column startcol))
+ (save-excursion (evil-move-to-column endcol t))
+ args))
+ (forward-line 1)))))
+
+(defun evil-apply-on-rectangle (function start end &rest args)
+ "Like `apply-on-rectangle' but maybe extends to eol.
+If `temporary-goal-column' is set to a big number, then the
+region of each line is extended to the end of each line. The end
+column is set to the maximal column in all covered lines."
+ (apply #'evil-apply-on-block function start end t args))
+
+;;; Insertion
+
+(defun evil-concat-ranges (ranges)
+ "Concatenate RANGES.
+RANGES must be a list of ranges. They must be ordered so that
+successive ranges share their boundaries. The return value is a
+single range of disjoint union of the ranges or nil if the
+disjoint union is not a single range."
+ (let ((range (car-safe ranges)) (ranges (cdr ranges)) r)
+ (while (and range (setq r (car-safe ranges)))
+ (setq range
+ (cond ((and (= (cdr r) (car range))) (cons (car r) (cdr range)))
+ ((and (= (cdr range) (car r))) (cons (car range) (cdr r)))))
+ (setq ranges (cdr ranges)))
+ range))
+
+(defun evil-track-last-insertion (beg end len)
+ "Track the last insertion range and its text.
+The insertion range is stored as a pair of buffer positions in
+`evil-current-insertion'. If a subsequent change is compatible,
+then the current range is modified, otherwise it is replaced by a
+new range. Compatible changes are changes that do not create a
+disjoin range."
+ ;; deletion
+ (when (> len 0)
+ (if (and evil-current-insertion
+ (>= beg (car evil-current-insertion))
+ (<= (+ beg len) (cdr evil-current-insertion)))
+ (setcdr evil-current-insertion
+ (- (cdr evil-current-insertion) len))
+ (setq evil-current-insertion nil)))
+ ;; insertion
+ (if (and evil-current-insertion
+ (>= beg (car evil-current-insertion))
+ (<= beg (cdr evil-current-insertion)))
+ (setcdr evil-current-insertion
+ (+ (- end beg)
+ (cdr evil-current-insertion)))
+ (setq evil-current-insertion (cons beg end))))
+(put 'evil-track-last-insertion 'permanent-local-hook t)
+
+(defun evil-start-track-last-insertion ()
+ "Start tracking the last insertion."
+ (setq evil-current-insertion nil)
+ (add-hook 'after-change-functions #'evil-track-last-insertion nil t))
+
+(defun evil-stop-track-last-insertion ()
+ "Stop tracking the last insertion.
+The tracked insertion is set to `evil-last-insertion'."
+ (setq evil-last-insertion
+ (and evil-current-insertion
+ ;; Check whether the insertion range is a valid buffer
+ ;; range. If a buffer modification is done from within
+ ;; another change hook or modification-hook (yasnippet
+ ;; does this using overlay modification-hooks), then the
+ ;; insertion information may be invalid. There is no way
+ ;; to detect this situation, but at least we should
+ ;; ensure that no error occurs (see bug #272).
+ (>= (car evil-current-insertion) (point-min))
+ (<= (cdr evil-current-insertion) (point-max))
+ (buffer-substring-no-properties (car evil-current-insertion)
+ (cdr evil-current-insertion))))
+ (remove-hook 'after-change-functions #'evil-track-last-insertion t))
+
+;;; Paste
+
+(defun evil-yank-characters (beg end &optional register yank-handler)
+ "Saves the characters defined by the region BEG and END in the kill-ring."
+ (let ((text (filter-buffer-substring beg end)))
+ (when yank-handler
+ (setq text (propertize text 'yank-handler (list yank-handler))))
+ (when register
+ (evil-set-register register text))
+ (when evil-was-yanked-without-register
+ (evil-set-register ?0 text)) ; "0 register contains last yanked text
+ (unless (eq register ?_)
+ (kill-new text))))
+
+(defun evil-yank-lines (beg end &optional register yank-handler)
+ "Saves the lines in the region BEG and END into the kill-ring."
+ (let* ((text (filter-buffer-substring beg end))
+ (yank-handler (list (or yank-handler
+ #'evil-yank-line-handler)
+ nil
+ t)))
+ ;; Ensure the text ends with a newline. This is required
+ ;; if the deleted lines were the last lines in the buffer.
+ (when (or (zerop (length text))
+ (/= (aref text (1- (length text))) ?\n))
+ (setq text (concat text "\n")))
+ (setq text (propertize text 'yank-handler yank-handler))
+ (when register
+ (evil-set-register register text))
+ (when evil-was-yanked-without-register
+ (evil-set-register ?0 text)) ; "0 register contains last yanked text
+ (unless (eq register ?_)
+ (kill-new text))))
+
+(defun evil-yank-rectangle (beg end &optional register yank-handler)
+ "Saves the rectangle defined by region BEG and END into the kill-ring."
+ (let ((lines (list nil)))
+ (evil-apply-on-rectangle #'extract-rectangle-line beg end lines)
+ ;; We remove spaces from the beginning and the end of the next.
+ ;; Spaces are inserted explicitly in the yank-handler in order to
+ ;; NOT insert lines full of spaces.
+ (setq lines (nreverse (cdr lines)))
+ ;; `text' is used as default insert text when pasting this rectangle
+ ;; in another program, e.g., using the X clipboard.
+ (let* ((yank-handler (list (or yank-handler
+ #'evil-yank-block-handler)
+ lines
+ t
+ 'evil-delete-yanked-rectangle))
+ (text (propertize (mapconcat #'identity lines "\n")
+ 'yank-handler yank-handler)))
+ (when register
+ (evil-set-register register text))
+ (when evil-was-yanked-without-register
+ (evil-set-register ?0 text)) ; "0 register contains last yanked text
+ (unless (eq register ?_)
+ (kill-new text))
+ text)))
+
+(defun evil-remove-yank-excluded-properties (text)
+ "Removes `yank-excluded-properties' from TEXT."
+ (if (eq yank-excluded-properties t)
+ (set-text-properties 0 (length text) nil text)
+ (remove-list-of-text-properties 0 (length text)
+ yank-excluded-properties text)))
+
+(defun evil-yank-line-handler (text)
+ "Inserts the current text linewise."
+ (let ((text (apply #'concat (make-list (or evil-paste-count 1) text)))
+ (opoint (point)))
+ (evil-remove-yank-excluded-properties text)
+ (cond
+ ((eq this-command 'evil-paste-before)
+ (evil-move-beginning-of-line)
+ (evil-move-mark (point))
+ (insert text)
+ (setq evil-last-paste
+ (list 'evil-paste-before
+ evil-paste-count
+ opoint
+ (mark t)
+ (point)))
+ (evil-set-marker ?\[ (mark))
+ (evil-set-marker ?\] (1- (point)))
+ (evil-exchange-point-and-mark)
+ (back-to-indentation))
+ ((eq this-command 'evil-paste-after)
+ (evil-move-end-of-line)
+ (evil-move-mark (point))
+ (insert "\n")
+ (insert text)
+ (evil-set-marker ?\[ (1+ (mark)))
+ (evil-set-marker ?\] (1- (point)))
+ (delete-char -1) ; delete the last newline
+ (setq evil-last-paste
+ (list 'evil-paste-after
+ evil-paste-count
+ opoint
+ (mark t)
+ (point)))
+ (evil-move-mark (1+ (mark t)))
+ (evil-exchange-point-and-mark)
+ (back-to-indentation))
+ (t
+ (insert text)))))
+
+(defun evil-yank-block-handler (lines)
+ "Inserts the current text as block."
+ (let ((count (or evil-paste-count 1))
+ (col (if (eq this-command 'evil-paste-after)
+ (1+ (current-column))
+ (current-column)))
+ (current-line (line-number-at-pos (point)))
+ (opoint (point))
+ epoint)
+ (dolist (line lines)
+ ;; concat multiple copies according to count
+ (setq line (apply #'concat (make-list count line)))
+ ;; strip whitespaces at beginning and end
+ (string-match "^ *\\(.*?\\) *$" line)
+ (let ((text (match-string 1 line))
+ (begextra (match-beginning 1))
+ (endextra (- (match-end 0) (match-end 1))))
+ ;; maybe we have to insert a new line at eob
+ (while (< (line-number-at-pos (point))
+ current-line)
+ (goto-char (point-max))
+ (insert "\n"))
+ (setq current-line (1+ current-line))
+ ;; insert text unless we insert an empty line behind eol
+ (unless (and (< (evil-column (line-end-position)) col)
+ (zerop (length text)))
+ ;; if we paste behind eol, it may be sufficient to insert tabs
+ (if (< (evil-column (line-end-position)) col)
+ (move-to-column (+ col begextra) t)
+ (move-to-column col t)
+ (insert (make-string begextra ?\s)))
+ (evil-remove-yank-excluded-properties text)
+ (insert text)
+ (unless (eolp)
+ ;; text follows, so we have to insert spaces
+ (insert (make-string endextra ?\s)))
+ (setq epoint (point)))
+ (forward-line 1)))
+ (setq evil-last-paste
+ (list this-command
+ evil-paste-count
+ opoint
+ (length lines) ; number of rows
+ (* count (length (car lines))))) ; number of colums
+ (evil-set-marker ?\[ opoint)
+ (evil-set-marker ?\] (1- epoint))
+ (goto-char opoint)
+ (when (and (eq this-command 'evil-paste-after)
+ (not (eolp)))
+ (forward-char))))
+
+(defun evil-delete-yanked-rectangle (nrows ncols)
+ "Special function to delete the block yanked by a previous paste command.
+Supplied as the `undo' element of a yank handler."
+ (let ((opoint (point))
+ (col (if (eq last-command 'evil-paste-after)
+ (1+ (current-column))
+ (current-column))))
+ (dotimes (_ nrows)
+ (delete-region (save-excursion
+ (move-to-column col)
+ (point))
+ (save-excursion
+ (move-to-column (+ col ncols))
+ (point)))
+ (unless (eobp) (forward-line)))
+ (goto-char opoint)))
+
+;; TODO: if undoing is disabled in the current buffer, paste-pop won't
+;; work. Although this is probably not a big problem, because usually
+;; buffers where `evil-paste-pop' may be useful have undoing enabled.
+;; A solution would be to temporarily enable undo when pasting and
+;; store the undo information in a special variable that does not
+;; interfere with `buffer-undo-list'.
+(defun evil-paste-pop (count)
+ "Replace the just-yanked stretch of killed text with a different stretch.
+This command is allowed only immediatly after a `yank',
+`evil-paste-before', `evil-paste-after' or `evil-paste-pop'.
+This command uses the same paste command as before, i.e., when
+used after `evil-paste-after' the new text is also yanked using
+`evil-paste-after', used with the same paste-count argument.
+
+The COUNT argument inserts the COUNTth previous kill. If COUNT
+is negative this is a more recent kill."
+ (interactive "p")
+ (unless (memq last-command
+ '(evil-paste-after
+ evil-paste-before
+ evil-visual-paste))
+ (user-error "Previous command was not an evil-paste: %s" last-command))
+ (unless evil-last-paste
+ (user-error "Previous paste command used a register"))
+ (evil-undo-pop)
+ (when (eq last-command 'evil-visual-paste)
+ (evil-swap evil-visual-previous-mark evil-visual-mark)
+ (evil-swap evil-visual-previous-point evil-visual-point))
+ (goto-char (nth 2 evil-last-paste))
+ (setq this-command (nth 0 evil-last-paste))
+ ;; use temporary kill-ring, so the paste cannot modify it
+ (let ((kill-ring (list (current-kill
+ (if (and (> count 0) (nth 5 evil-last-paste))
+ ;; if was visual paste then skip the
+ ;; text that has been replaced
+ (1+ count)
+ count))))
+ (kill-ring-yank-pointer kill-ring))
+ (when (eq last-command 'evil-visual-paste)
+ (let ((evil-no-display t))
+ (evil-visual-restore)))
+ (funcall (nth 0 evil-last-paste) (nth 1 evil-last-paste))
+ ;; if this was a visual paste, then mark the last paste as NOT
+ ;; being the first visual paste
+ (when (eq last-command 'evil-visual-paste)
+ (setcdr (nthcdr 4 evil-last-paste) nil))))
+
+(defun evil-paste-pop-next (count)
+ "Same as `evil-paste-pop' but with negative argument."
+ (interactive "p")
+ (evil-paste-pop (- count)))
+
+;;; Interactive forms
+
+(defun evil-match-interactive-code (interactive &optional pos)
+ "Match an interactive code at position POS in string INTERACTIVE.
+Returns the first matching entry in `evil-interactive-alist', or nil."
+ (let ((length (length interactive))
+ (pos (or pos 0)))
+ (catch 'done
+ (dolist (entry evil-interactive-alist)
+ (let* ((string (car entry))
+ (end (+ (length string) pos)))
+ (when (and (<= end length)
+ (string= string
+ (substring interactive pos end)))
+ (throw 'done entry)))))))
+
+(defun evil-concatenate-interactive-forms (&rest forms)
+ "Concatenate interactive list expressions FORMS.
+Returns a single expression where successive expressions
+are joined, if possible."
+ (let (result)
+ (when forms
+ (while (cdr forms)
+ (cond
+ ((null (car forms))
+ (pop forms))
+ ((and (eq (car (car forms)) 'list)
+ (eq (car (cadr forms)) 'list))
+ (setq forms (cons (append (car forms)
+ (cdr (cadr forms)))
+ (cdr (cdr forms)))))
+ (t
+ (push (pop forms) result))))
+ (when (car forms)
+ (push (pop forms) result))
+ (setq result (nreverse result))
+ (cond
+ ((null result))
+ ((null (cdr result))
+ (car result))
+ (t
+ `(append ,@result))))))
+
+(defun evil-interactive-string (string)
+ "Evaluate the interactive string STRING.
+The string may contain extended interactive syntax.
+The return value is a cons cell (FORM . PROPERTIES),
+where FORM is a single list-expression to be passed to
+a standard `interactive' statement, and PROPERTIES is a
+list of command properties as passed to `evil-define-command'."
+ (let ((length (length string))
+ (pos 0)
+ code expr forms match plist prompt properties)
+ (while (< pos length)
+ (if (eq (aref string pos) ?\n)
+ (setq pos (1+ pos))
+ (setq match (evil-match-interactive-code string pos))
+ (if (null match)
+ (user-error "Unknown interactive code: `%s'"
+ (substring string pos))
+ (setq code (car match)
+ expr (car (cdr match))
+ plist (cdr (cdr match))
+ pos (+ pos (length code)))
+ (when (functionp expr)
+ (setq prompt
+ (substring string pos
+ (or (string-match "\n" string pos)
+ length))
+ pos (+ pos (length prompt))
+ expr `(funcall ,expr ,prompt)))
+ (setq forms (append forms (list expr))
+ properties (append properties plist)))))
+ (cons `(append ,@forms) properties)))
+
+(defun evil-interactive-form (&rest args)
+ "Evaluate interactive forms ARGS.
+The return value is a cons cell (FORM . PROPERTIES),
+where FORM is a single list-expression to be passed to
+a standard `interactive' statement, and PROPERTIES is a
+list of command properties as passed to `evil-define-command'."
+ (let (forms properties)
+ (dolist (arg args)
+ (if (not (stringp arg))
+ (setq forms (append forms (list arg)))
+ (setq arg (evil-interactive-string arg)
+ forms (append forms (cdr (car arg)))
+ properties (append properties (cdr arg)))))
+ (cons (apply #'evil-concatenate-interactive-forms forms)
+ properties)))
+
+;;; Types
+
+(defun evil-type (object &optional default)
+ "Return the type of OBJECT, or DEFAULT if none."
+ (let (type)
+ (cond
+ ((overlayp object)
+ (setq type (overlay-get object :type)))
+ ((evil-range-p object)
+ (setq type (nth 2 object)))
+ ((listp object)
+ (setq type (plist-get object :type)))
+ ((commandp object)
+ (setq type (evil-get-command-property object :type)))
+ ((symbolp object)
+ (setq type (get object 'type))))
+ (setq type (or type default))
+ (and (evil-type-p type) type)))
+
+(defun evil-set-type (object type)
+ "Set the type of OBJECT to TYPE.
+For example, (evil-set-type 'next-line 'line)
+will make `line' the type of the `next-line' command."
+ (cond
+ ((overlayp object)
+ (overlay-put object :type type))
+ ((evil-range-p object)
+ (evil-set-range-type object type))
+ ((listp object)
+ (plist-put object :type type))
+ ((commandp object)
+ (evil-set-command-property object :type type))
+ ((symbolp object)
+ (put object 'type type)))
+ object)
+
+(defun evil-type-property (type prop)
+ "Return property PROP for TYPE."
+ (evil-get-property evil-type-properties type prop))
+
+(defun evil-type-p (sym)
+ "Whether SYM is the name of a type."
+ (assq sym evil-type-properties))
+
+(defun evil-expand (beg end type &rest properties)
+ "Expand BEG and END as TYPE with PROPERTIES.
+Returns a list (BEG END TYPE PROPERTIES ...), where the tail
+may contain a property list."
+ (apply #'evil-transform
+ ;; don't expand if already expanded
+ (unless (plist-get properties :expanded) :expand)
+ beg end type properties))
+
+(defun evil-contract (beg end type &rest properties)
+ "Contract BEG and END as TYPE with PROPERTIES.
+Returns a list (BEG END TYPE PROPERTIES ...), where the tail
+may contain a property list."
+ (apply #'evil-transform :contract beg end type properties))
+
+(defun evil-normalize (beg end type &rest properties)
+ "Normalize BEG and END as TYPE with PROPERTIES.
+Returns a list (BEG END TYPE PROPERTIES ...), where the tail
+may contain a property list."
+ (apply #'evil-transform :normalize beg end type properties))
+
+(defun evil-transform (transform beg end type &rest properties)
+ "Apply TRANSFORM on BEG and END with PROPERTIES.
+Returns a list (BEG END TYPE PROPERTIES ...), where the tail
+may contain a property list. If TRANSFORM is undefined,
+return positions unchanged."
+ (let* ((type (or type (evil-type properties)))
+ (transform (when (and type transform)
+ (evil-type-property type transform))))
+ (if transform
+ (apply transform beg end properties)
+ (apply #'evil-range beg end type properties))))
+
+(defun evil-describe (beg end type &rest properties)
+ "Return description of BEG and END with PROPERTIES.
+If no description is available, return the empty string."
+ (let* ((type (or type (evil-type properties)))
+ (properties (plist-put properties :type type))
+ (describe (evil-type-property type :string)))
+ (or (when describe
+ (apply describe beg end properties))
+ "")))
+
+;;; Ranges
+
+(defun evil-range (beg end &optional type &rest properties)
+ "Return a list (BEG END [TYPE] PROPERTIES...).
+BEG and END are buffer positions (numbers or markers),
+TYPE is a type as per `evil-type-p', and PROPERTIES is
+a property list."
+ (let ((beg (evil-normalize-position beg))
+ (end (evil-normalize-position end)))
+ (when (and (numberp beg) (numberp end))
+ (append (list (min beg end) (max beg end))
+ (when (evil-type-p type)
+ (list type))
+ properties))))
+
+(defun evil-range-p (object)
+ "Whether OBJECT is a range."
+ (and (listp object)
+ (>= (length object) 2)
+ (numberp (nth 0 object))
+ (numberp (nth 1 object))))
+
+(defun evil-range-beginning (range)
+ "Return beginning of RANGE."
+ (when (evil-range-p range)
+ (let ((beg (evil-normalize-position (nth 0 range)))
+ (end (evil-normalize-position (nth 1 range))))
+ (min beg end))))
+
+(defun evil-range-end (range)
+ "Return end of RANGE."
+ (when (evil-range-p range)
+ (let ((beg (evil-normalize-position (nth 0 range)))
+ (end (evil-normalize-position (nth 1 range))))
+ (max beg end))))
+
+(defun evil-range-properties (range)
+ "Return properties of RANGE."
+ (when (evil-range-p range)
+ (if (evil-type range)
+ (nthcdr 3 range)
+ (nthcdr 2 range))))
+
+(defun evil-copy-range (range)
+ "Return a copy of RANGE."
+ (copy-sequence range))
+
+(defun evil-set-range (range &optional beg end type &rest properties)
+ "Set RANGE to have beginning BEG and end END.
+The TYPE and additional PROPERTIES may also be specified.
+If an argument is nil, it's not used; the previous value is retained.
+See also `evil-set-range-beginning', `evil-set-range-end',
+`evil-set-range-type' and `evil-set-range-properties'."
+ (when (evil-range-p range)
+ (let ((beg (or (evil-normalize-position beg)
+ (evil-range-beginning range)))
+ (end (or (evil-normalize-position end)
+ (evil-range-end range)))
+ (type (or type (evil-type range)))
+ (plist (evil-range-properties range)))
+ (evil-sort beg end)
+ (setq plist (evil-concat-plists plist properties))
+ (evil-set-range-beginning range beg)
+ (evil-set-range-end range end)
+ (evil-set-range-type range type)
+ (evil-set-range-properties range plist)
+ range)))
+
+(defun evil-set-range-beginning (range beg &optional copy)
+ "Set RANGE's beginning to BEG.
+If COPY is non-nil, return a copy of RANGE."
+ (when copy
+ (setq range (evil-copy-range range)))
+ (setcar range beg)
+ range)
+
+(defun evil-set-range-end (range end &optional copy)
+ "Set RANGE's end to END.
+If COPY is non-nil, return a copy of RANGE."
+ (when copy
+ (setq range (evil-copy-range range)))
+ (setcar (cdr range) end)
+ range)
+
+(defun evil-set-range-type (range type &optional copy)
+ "Set RANGE's type to TYPE.
+If COPY is non-nil, return a copy of RANGE."
+ (when copy
+ (setq range (evil-copy-range range)))
+ (if type
+ (setcdr (cdr range)
+ (cons type (evil-range-properties range)))
+ (setcdr (cdr range) (evil-range-properties range)))
+ range)
+
+(defun evil-set-range-properties (range properties &optional copy)
+ "Set RANGE's properties to PROPERTIES.
+If COPY is non-nil, return a copy of RANGE."
+ (when copy
+ (setq range (evil-copy-range range)))
+ (if (evil-type range)
+ (setcdr (cdr (cdr range)) properties)
+ (setcdr (cdr range) properties))
+ range)
+
+(defun evil-range-union (range1 range2 &optional type)
+ "Return the union of the ranges RANGE1 and RANGE2.
+If the ranges have conflicting types, use RANGE1's type.
+This can be overridden with TYPE."
+ (when (and (evil-range-p range1)
+ (evil-range-p range2))
+ (evil-range (min (evil-range-beginning range1)
+ (evil-range-beginning range2))
+ (max (evil-range-end range1)
+ (evil-range-end range2))
+ (or type
+ (evil-type range1)
+ (evil-type range2)))))
+
+(defun evil-subrange-p (range1 range2)
+ "Whether RANGE1 is contained within RANGE2."
+ (and (evil-range-p range1)
+ (evil-range-p range2)
+ (<= (evil-range-beginning range2)
+ (evil-range-beginning range1))
+ (>= (evil-range-end range2)
+ (evil-range-end range1))))
+
+(defun evil-select-inner-unrestricted-object (thing beg end type &optional count line)
+ "Return an inner text object range of COUNT objects.
+If COUNT is positive, return objects following point; if COUNT is
+negative, return objects preceding point. If one is unspecified,
+the other is used with a negative argument. THING is a symbol
+understood by `thing-at-point'. BEG, END and TYPE specify the
+current selection. If LINE is non-nil, the text object should be
+linewise, otherwise it is character wise."
+ (let* ((count (or count 1))
+ (bnd (or (let ((b (bounds-of-thing-at-point thing)))
+ (and b (< (point) (cdr b)) b))
+ (evil-bounds-of-not-thing-at-point thing))))
+ ;; check if current object is selected
+ (when (or (not beg) (not end)
+ (> beg (car bnd))
+ (< end (cdr bnd))
+ (and (eq type 'inclusive)
+ (= (1+ beg) end))) ; empty region does not count
+ (when (or (not beg) (< (car bnd) beg)) (setq beg (car bnd)))
+ (when (or (not end) (> (cdr bnd) end)) (setq end (cdr bnd)))
+ (setq count (if (> count 0) (1- count) (1+ count))))
+ (goto-char (if (< count 0) beg end))
+ (evil-forward-nearest count
+ #'(lambda (cnt) (forward-thing thing cnt))
+ #'(lambda (cnt) (evil-forward-not-thing thing cnt)))
+ (evil-range (if (>= count 0) beg (point))
+ (if (< count 0) end (point))
+ (if line 'line type)
+ :expanded t)))
+
+(defun evil-select-inner-object (thing beg end type &optional count line)
+ "Return an inner text object range of COUNT objects.
+Selection is restricted to the current line.
+If COUNT is positive, return objects following point; if COUNT is
+negative, return objects preceding point. If one is unspecified,
+the other is used with a negative argument. THING is a symbol
+understood by `thing-at-point'. BEG, END and TYPE specify the
+current selection. If LINE is non-nil, the text object should be
+linewise, otherwise it is character wise."
+ (save-restriction
+ (narrow-to-region (save-excursion (beginning-of-line) (point))
+ (save-excursion (end-of-line) (point)))
+ (evil-select-inner-unrestricted-object thing beg end type count line)))
+
+(defun evil-select-an-unrestricted-object (thing beg end type count &optional line)
+ "Return an outer text object range of COUNT objects.
+If COUNT is positive, return objects following point; if COUNT is
+negative, return objects preceding point. If one is unspecified,
+the other is used with a negative argument. THING is a symbol
+understood by thing-at-point. BEG, END and TYPE specify the
+current selection. If LINE is non-nil, the text object should be
+linewise, otherwise it is character wise."
+ (let* ((dir (if (> (or count 1) 0) +1 -1))
+ (count (abs (or count 1)))
+ (objbnd (let ((b (bounds-of-thing-at-point thing)))
+ (and b (< (point) (cdr b)) b)))
+ (bnd (or objbnd (evil-bounds-of-not-thing-at-point thing)))
+ addcurrent other)
+ ;; check if current object is not selected
+ (when (or (not beg) (not end)
+ (> beg (car bnd))
+ (< end (cdr bnd))
+ (and (eq type 'inclusive)
+ (= (1+ beg) end))) ; empty region does not count
+ ;; if not, enlarge selection
+ (when (or (not beg) (< (car bnd) beg)) (setq beg (car bnd)))
+ (when (or (not end) (> (cdr bnd) end)) (setq end (cdr bnd)))
+ (if objbnd (setq addcurrent t)))
+ ;; make other and (point) reflect the selection
+ (cond
+ ((> dir 0) (goto-char end) (setq other beg))
+ (t (goto-char beg) (setq other end)))
+ (cond
+ ;; do nothing more than only current is selected
+ ((not (and (= beg (car bnd)) (= end (cdr bnd)))))
+ ;; current match is thing, add whitespace
+ (objbnd
+ (let ((wsend (evil-with-restriction
+ ;; restrict to current line if we do non-line selection
+ (and (not line) (line-beginning-position))
+ (and (not line) (line-end-position))
+ (evil-bounds-of-not-thing-at-point thing dir))))
+ (cond
+ (wsend
+ ;; add whitespace at end
+ (goto-char wsend)
+ (setq addcurrent t))
+ (t
+ ;; no whitespace at end, try beginning
+ (save-excursion
+ (goto-char other)
+ (setq wsend
+ (evil-with-restriction
+ ;; restrict to current line if we do non-line selection
+ (and (not line) (line-beginning-position))
+ (and (not line) (line-end-position))
+ (evil-bounds-of-not-thing-at-point thing (- dir))))
+ (when wsend (setq other wsend addcurrent t)))))))
+ ;; current match is whitespace, add thing
+ (t
+ (forward-thing thing dir)
+ (setq addcurrent t)))
+ ;; possibly count current object as selection
+ (if addcurrent (setq count (1- count)))
+ ;; move
+ (dotimes (_ count)
+ (let ((wsend (evil-bounds-of-not-thing-at-point thing dir)))
+ (if (and wsend (/= wsend (point)))
+ ;; start with whitespace
+ (forward-thing thing dir)
+ ;; start with thing
+ (forward-thing thing dir)
+ (setq wsend (evil-bounds-of-not-thing-at-point thing dir))
+ (when wsend (goto-char wsend)))))
+ ;; return range
+ (evil-range (if (> dir 0) other (point))
+ (if (< dir 0) other (point))
+ (if line 'line type)
+ :expanded t)))
+
+(defun evil-select-an-object (thing beg end type &optional count line)
+ "Return an outer text object range of COUNT objects.
+Selection is restricted to the current line.
+If COUNT is positive, return objects following point; if COUNT is
+negative, return objects preceding point. If one is unspecified,
+the other is used with a negative argument. THING is a symbol
+understood by thing-at-point. BEG, END and TYPE specify the
+current selection. If LINE is non-nil, the text object should be
+linewise, otherwise it is character wise."
+ (save-restriction
+ (narrow-to-region (save-excursion (beginning-of-line) (point))
+ (save-excursion (end-of-line) (point)))
+ (evil-select-an-unrestricted-object thing beg end type count line)))
+
+(defun evil--get-block-range (op cl selection-type)
+ "Return the exclusive range of a visual selection.
+OP and CL are pairs of buffer positions for the opening and
+closing delimiter of a range. SELECTION-TYPE is the desired type
+of selection. It is a symbol that determines which parts of the
+block are selected. If it is 'inclusive or t the returned range
+is \(cons (car OP) (cdr CL)). If it is 'exclusive or nil the
+returned range is (cons (cdr OP) (car CL)). If it is
+'exclusive-line the returned range will skip whitespace at the
+end of the line of OP and at the beginning of the line of CL."
+ (cond
+ ((memq selection-type '(inclusive t)) (cons (car op) (cdr cl)))
+ ((memq selection-type '(exclusive nil)) (cons (cdr op) (car cl)))
+ ((eq selection-type 'exclusive-line)
+ (let ((beg (cdr op))
+ (end (car cl)))
+ (save-excursion
+ (goto-char beg)
+ (when (and (eolp) (not (eobp)))
+ (setq beg (line-beginning-position 2)))
+ (goto-char end)
+ (skip-chars-backward " \t")
+ (when (bolp)
+ (setq end (point))
+ (goto-char beg)
+ (when (and (not (bolp)) (< beg end))
+ (setq end (1- end)))))
+ (cons beg end)))
+ (t
+ (user-error "Unknown selection-type %s" selection-type))))
+
+(defun evil-select-block (thing beg end type count
+ &optional
+ selection-type
+ countcurrent
+ fixedscan)
+ "Return a range (BEG END) of COUNT delimited text objects.
+BEG END TYPE are the currently selected (visual) range. The
+delimited object must be given by THING-up function (see
+`evil-up-block').
+
+SELECTION-TYPE is symbol that determines which parts of the block
+are selected. If it is 'inclusive or t OPEN and CLOSE are
+included in the range. If it is 'exclusive or nil the delimiters
+are not contained. If it is 'exclusive-line the delimiters are
+not included as well as adjacent whitespace until the beginning
+of the next line or the end of the previous line. If the
+resulting selection consists of complete lines only and visual
+state is not active, the returned selection is linewise.
+
+If COUNTCURRENT is non-nil an objected is counted if the current
+selection matches that object exactly.
+
+Usually scanning for the surrounding block starts at (1+ beg)
+and (1- end). If this might fail due to the behavior of THING
+then FIXEDSCAN can be set to t. In this case the scan starts at
+BEG and END. One example where this might fail is if BEG and END
+are the delimiters of a string or comment."
+ (save-excursion
+ (save-match-data
+ (let* ((orig-beg beg)
+ (orig-end end)
+ (beg (or beg (point)))
+ (end (or end (point)))
+ (count (abs (or count 1)))
+ op cl op-end cl-end)
+ ;; We always assume at least one selected character.
+ (if (= beg end) (setq end (1+ end)))
+ ;; We scan twice: starting at (1+ beg) forward and at (1- end)
+ ;; backward. The resulting selection is the smaller one.
+ (goto-char (if fixedscan beg (1+ beg)))
+ (when (and (zerop (funcall thing +1)) (match-beginning 0))
+ (setq cl (cons (match-beginning 0) (match-end 0)))
+ (goto-char (car cl))
+ (when (and (zerop (funcall thing -1)) (match-beginning 0))
+ (setq op (cons (match-beginning 0) (match-end 0)))))
+ ;; start scanning from end
+ (goto-char (if fixedscan end (1- end)))
+ (when (and (zerop (funcall thing -1)) (match-beginning 0))
+ (setq op-end (cons (match-beginning 0) (match-end 0)))
+ (goto-char (cdr op-end))
+ (when (and (zerop (funcall thing +1)) (match-beginning 0))
+ (setq cl-end (cons (match-beginning 0) (match-end 0)))))
+ ;; Bug #607: use the tightest selection that contains the
+ ;; original selection. If non selection contains the original,
+ ;; use the larger one.
+ (cond
+ ((and (not op) (not cl-end))
+ (error "No surrounding delimiters found"))
+ ((or (not op) ; first not found
+ (and cl-end ; second found
+ (>= (car op-end) (car op)) ; second smaller
+ (<= (cdr cl-end) (cdr cl))
+ (<= (car op-end) beg) ; second contains orig
+ (>= (cdr cl-end) end)))
+ (setq op op-end cl cl-end)))
+ (setq op-end op cl-end cl) ; store copy
+ ;; if the current selection contains the surrounding
+ ;; delimiters, they do not count as new selection
+ (let ((cnt (if (and orig-beg orig-end (not countcurrent))
+ (let ((sel (evil--get-block-range op cl selection-type)))
+ (if (and (<= orig-beg (car sel))
+ (>= orig-end (cdr sel)))
+ count
+ (1- count)))
+ (1- count))))
+ ;; starting from the innermost surrounding delimiters
+ ;; increase selection
+ (when (> cnt 0)
+ (setq op (progn
+ (goto-char (car op-end))
+ (funcall thing (- cnt))
+ (if (match-beginning 0)
+ (cons (match-beginning 0) (match-end 0))
+ op))
+ cl (progn
+ (goto-char (cdr cl-end))
+ (funcall thing cnt)
+ (if (match-beginning 0)
+ (cons (match-beginning 0) (match-end 0))
+ cl)))))
+ (let ((sel (evil--get-block-range op cl selection-type)))
+ (setq op (car sel)
+ cl (cdr sel)))
+ (cond
+ ((and (equal op orig-beg) (equal cl orig-end)
+ (or (not countcurrent)
+ (and countcurrent (/= count 1))))
+ (error "No surrounding delimiters found"))
+ ((save-excursion
+ (and (not (evil-visual-state-p))
+ (eq type 'inclusive)
+ (progn (goto-char op) (bolp))
+ (progn (goto-char cl) (bolp))))
+ (evil-range op cl 'line :expanded t))
+ (t
+ (evil-range op cl type :expanded t)))))))
+
+(defun evil-select-paren (open close beg end type count &optional inclusive)
+ "Return a range (BEG END) of COUNT delimited text objects.
+OPEN and CLOSE specify the opening and closing delimiter,
+respectively. BEG END TYPE are the currently selected (visual)
+range. If INCLUSIVE is non-nil, OPEN and CLOSE are included in
+the range; otherwise they are excluded.
+
+The types of OPEN and CLOSE specify which kind of THING is used
+for parsing with `evil-select-block'. If OPEN and CLOSE are
+characters `evil-up-paren' is used. Otherwise OPEN and CLOSE
+must be regular expressions and `evil-up-block' is used.
+
+If the selection is exclusive, whitespace at the end or at the
+beginning of the selection until the end-of-line or beginning-of-line
+is ignored."
+ ;; we need special linewise exclusive selection
+ (unless inclusive (setq inclusive 'exclusive-line))
+ (cond
+ ((and (characterp open) (characterp close))
+ (let ((thing #'(lambda (&optional cnt)
+ (evil-up-paren open close cnt)))
+ (bnd (or (bounds-of-thing-at-point 'evil-string)
+ (bounds-of-thing-at-point 'evil-comment)
+ ;; If point is at the opening quote of a string,
+ ;; this must be handled as if point is within the
+ ;; string, i.e. the selection must be extended
+ ;; around the string. Otherwise
+ ;; `evil-select-block' might do the wrong thing
+ ;; because it accidentally moves point inside the
+ ;; string (for inclusive selection) when looking
+ ;; for the current surrounding block. (re #364)
+ (and (= (point) (or beg (point)))
+ (save-excursion
+ (goto-char (1+ (or beg (point))))
+ (or (bounds-of-thing-at-point 'evil-string)
+ (bounds-of-thing-at-point 'evil-comment)))))))
+ (if (not bnd)
+ (evil-select-block thing beg end type count inclusive)
+ (or (evil-with-restriction (car bnd) (cdr bnd)
+ (condition-case nil
+ (evil-select-block thing beg end type count inclusive)
+ (error nil)))
+ (save-excursion
+ (setq beg (or beg (point))
+ end (or end (point)))
+ (goto-char (car bnd))
+ (let ((extbeg (min beg (car bnd)))
+ (extend (max end (cdr bnd))))
+ (evil-select-block thing
+ extbeg extend
+ type
+ count
+ inclusive
+ (or (< extbeg beg) (> extend end))
+ t)))))))
+ (t
+ (evil-select-block #'(lambda (&optional cnt)
+ (evil-up-block open close cnt))
+ beg end type count inclusive))))
+
+(defun evil-select-quote-thing (thing beg end _type count &optional inclusive)
+ "Selection THING as if it described a quoted object.
+THING is typically either 'evil-quote or 'evil-chars. This
+function is called from `evil-select-quote'."
+ (save-excursion
+ (let* ((count (or count 1))
+ (dir (if (> count 0) 1 -1))
+ (bnd (let ((b (bounds-of-thing-at-point thing)))
+ (and b (< (point) (cdr b)) b)))
+ addcurrent
+ wsboth)
+ (if inclusive (setq inclusive t)
+ (when (= (abs count) 2)
+ (setq count dir)
+ (setq inclusive 'quote-only))
+ ;; never extend with exclusive selection
+ (setq beg nil end nil))
+ ;; check if the previously selected range does not contain a
+ ;; string
+ (unless (and beg end
+ (save-excursion
+ (goto-char (if (> dir 0) beg end))
+ (forward-thing thing dir)
+ (and (<= beg (point)) (< (point) end))))
+ ;; if so forget the range
+ (setq beg nil end nil))
+ ;; check if there is a current object, if not fetch one
+ (when (not bnd)
+ (unless (and (zerop (forward-thing thing dir))
+ (setq bnd (bounds-of-thing-at-point thing)))
+ (error "No quoted string found"))
+ (if (> dir 0)
+ (setq end (point))
+ (setq beg (point)))
+ (setq addcurrent t))
+ ;; check if current object is not selected
+ (when (or (not beg) (not end) (> beg (car bnd)) (< end (cdr bnd)))
+ ;; if not, enlarge selection
+ (when (or (not beg) (< (car bnd) beg)) (setq beg (car bnd)))
+ (when (or (not end) (> (cdr bnd) end)) (setq end (cdr bnd)))
+ (setq addcurrent t wsboth t))
+ ;; maybe count current element
+ (when addcurrent
+ (setq count (if (> dir 0) (1- count) (1+ count))))
+ ;; enlarge selection
+ (goto-char (if (> dir 0) end beg))
+ (when (and (not addcurrent)
+ (= count (forward-thing thing count)))
+ (error "No quoted string found"))
+ (if (> dir 0) (setq end (point)) (setq beg (point)))
+ ;; add whitespace
+ (cond
+ ((not inclusive) (setq beg (1+ beg) end (1- end)))
+ ((not (eq inclusive 'quote-only))
+ ;; try to add whitespace in forward direction
+ (goto-char (if (> dir 0) end beg))
+ (if (setq bnd (bounds-of-thing-at-point 'evil-space))
+ (if (> dir 0) (setq end (cdr bnd)) (setq beg (car bnd)))
+ ;; if not found try backward direction
+ (goto-char (if (> dir 0) beg end))
+ (if (and wsboth (setq bnd (bounds-of-thing-at-point 'evil-space)))
+ (if (> dir 0) (setq beg (car bnd)) (setq end (cdr bnd)))))))
+ (evil-range beg end
+ ;; HACK: fixes #583
+ ;; When not in visual state, an empty range is
+ ;; possible. However, this cannot be achieved with
+ ;; inclusive ranges, hence we use exclusive ranges
+ ;; in this case. In visual state the range must be
+ ;; inclusive because otherwise the selection would
+ ;; be wrong.
+ (if (evil-visual-state-p) 'inclusive 'exclusive)
+ :expanded t))))
+
+(defun evil-select-quote (quote beg end type count &optional inclusive)
+ "Return a range (BEG END) of COUNT quoted text objects.
+QUOTE specifies the quotation delimiter. BEG END TYPE are the
+currently selected (visual) range.
+
+If INCLUSIVE is nil the previous selection is ignore. If there is
+quoted string at point this object will be selected, otherwise
+the following (if (> COUNT 0)) or preceeding object (if (< COUNT
+0)) is selected. If (/= (abs COUNT) 2) the delimiting quotes are not
+contained in the range, otherwise they are contained in the range.
+
+If INCLUSIVE is non-nil the selection depends on the previous
+selection. If the currently selection contains at least one
+character that is contained in a quoted string then the selection
+is extended, otherwise it is thrown away. If there is a
+non-selected object at point then this object is added to the
+selection. Otherwise the selection is extended to the
+following (if (> COUNT 0)) or preceeding object (if (< COUNT
+0)). Any whitespace following (or preceeding if (< COUNT 0)) the
+new selection is added to the selection. If no such whitespace
+exists and the selection contains only one quoted string then the
+preceeding (or following) whitespace is added to the range. "
+ (let ((evil-forward-quote-char quote))
+ (or (let ((bnd (or (bounds-of-thing-at-point 'evil-comment)
+ (bounds-of-thing-at-point 'evil-string))))
+ (when (and bnd (< (point) (cdr bnd))
+ (/= (char-after (car bnd)) quote)
+ (/= (char-before (cdr bnd)) quote))
+ (evil-with-restriction (car bnd) (cdr bnd)
+ (condition-case nil
+ (evil-select-quote-thing 'evil-quote-simple
+ beg end type
+ count
+ inclusive)
+ (error nil)))))
+ (let ((evil-forward-quote-char quote))
+ (evil-select-quote-thing 'evil-quote
+ beg end type
+ count
+ inclusive)))))
+
+(defun evil-select-xml-tag (beg end type &optional count inclusive)
+ "Return a range (BEG END) of COUNT matching XML tags.
+If INCLUSIVE is non-nil, the tags themselves are included
+from the range."
+ (cond
+ ((and (not inclusive) (= (abs (or count 1)) 1))
+ (let ((rng (evil-select-block #'evil-up-xml-tag beg end type count nil t)))
+ (if (or (and beg (= beg (evil-range-beginning rng))
+ end (= end (evil-range-end rng)))
+ (= (evil-range-beginning rng) (evil-range-end rng)))
+ (evil-select-block #'evil-up-xml-tag beg end type count t)
+ rng)))
+ (t
+ (evil-select-block #'evil-up-xml-tag beg end type count inclusive))))
+
+(defun evil-expand-range (range &optional copy)
+ "Expand RANGE according to its type.
+Return a new range if COPY is non-nil."
+ (when copy
+ (setq range (evil-copy-range range)))
+ (unless (plist-get (evil-range-properties range) :expanded)
+ (setq range (evil-transform-range :expand range)))
+ range)
+
+(defun evil-contract-range (range &optional copy)
+ "Contract RANGE according to its type.
+Return a new range if COPY is non-nil."
+ (evil-transform-range :contract range copy))
+
+(defun evil-normalize-range (range &optional copy)
+ "Normalize RANGE according to its type.
+Return a new range if COPY is non-nil."
+ (evil-transform-range :normalize range copy))
+
+(defun evil-transform-range (transform range &optional copy)
+ "Apply TRANSFORM to RANGE according to its type.
+Return a new range if COPY is non-nil."
+ (when copy
+ (setq range (evil-copy-range range)))
+ (when (evil-type range)
+ (apply #'evil-set-range range
+ (apply #'evil-transform transform range)))
+ range)
+
+(defun evil-describe-range (range)
+ "Return description of RANGE.
+If no description is available, return the empty string."
+ (apply #'evil-describe range))
+
+;;; Undo
+
+(defun evil-start-undo-step (&optional continue)
+ "Start a undo step.
+All following buffer modifications are grouped together as a
+single action. If CONTINUE is non-nil, preceding modifications
+are included. The step is terminated with `evil-end-undo-step'."
+ (when (and (listp buffer-undo-list)
+ (not evil-in-single-undo))
+ (if evil-undo-list-pointer
+ (evil-refresh-undo-step)
+ (unless (or continue (null (car-safe buffer-undo-list)))
+ (undo-boundary))
+ (setq evil-undo-list-pointer (or buffer-undo-list t)))))
+
+(defun evil-end-undo-step (&optional continue)
+ "End a undo step started with `evil-start-undo-step'.
+Adds an undo boundary unless CONTINUE is specified."
+ (when (and (listp buffer-undo-list)
+ evil-undo-list-pointer
+ (not evil-in-single-undo))
+ (evil-refresh-undo-step)
+ (unless (or continue (null (car-safe buffer-undo-list)))
+ (undo-boundary))
+ (setq evil-undo-list-pointer nil)))
+
+(defun evil-refresh-undo-step ()
+ "Refresh `buffer-undo-list' entries for current undo step.
+Undo boundaries until `evil-undo-list-pointer' are removed to
+make the entries undoable as a single action. See
+`evil-start-undo-step'."
+ (when evil-undo-list-pointer
+ (setq buffer-undo-list
+ (evil-filter-list #'null buffer-undo-list evil-undo-list-pointer))
+ (setq evil-undo-list-pointer (or buffer-undo-list t))))
+
+(defmacro evil-with-undo (&rest body)
+ "Execute BODY with enabled undo.
+If undo is disabled in the current buffer, the undo information
+is stored in `evil-temporary-undo' instead of `buffer-undo-list'."
+ (declare (indent defun)
+ (debug t))
+ `(unwind-protect
+ (let (buffer-undo-list)
+ (unwind-protect
+ (progn ,@body)
+ (setq evil-temporary-undo buffer-undo-list)
+ ;; ensure evil-temporary-undo starts with exactly one undo
+ ;; boundary marker, i.e. nil
+ (unless (null (car-safe evil-temporary-undo))
+ (push nil evil-temporary-undo))))
+ (unless (eq buffer-undo-list t)
+ ;; undo is enabled, so update the global buffer undo list
+ (setq buffer-undo-list
+ ;; prepend new undos (if there are any)
+ (if (cdr evil-temporary-undo)
+ (nconc evil-temporary-undo buffer-undo-list)
+ buffer-undo-list)
+ evil-temporary-undo nil))))
+
+(defmacro evil-with-single-undo (&rest body)
+ "Execute BODY as a single undo step."
+ (declare (indent defun)
+ (debug t))
+ `(let (evil-undo-list-pointer)
+ (evil-with-undo
+ (unwind-protect
+ (progn
+ (evil-start-undo-step)
+ (let ((evil-in-single-undo t))
+ ,@body))
+ (evil-end-undo-step)))))
+
+(defun evil-undo-pop ()
+ "Undo the last buffer change.
+Removes the last undo information from `buffer-undo-list'.
+If undo is disabled in the current buffer, use the information
+in `evil-temporary-undo' instead."
+ (let ((paste-undo (list nil)))
+ (let ((undo-list (if (eq buffer-undo-list t)
+ evil-temporary-undo
+ buffer-undo-list)))
+ (when (or (not undo-list) (car undo-list))
+ (user-error "Can't undo previous change"))
+ (while (and undo-list (null (car undo-list)))
+ (pop undo-list)) ; remove nil
+ (while (and undo-list (car undo-list))
+ (push (pop undo-list) paste-undo))
+ (let ((buffer-undo-list (nreverse paste-undo)))
+ (evil-save-echo-area
+ (undo)))
+ (if (eq buffer-undo-list t)
+ (setq evil-temporary-undo nil)
+ (setq buffer-undo-list undo-list)))))
+
+;;; Search
+(defun evil-transform-regexp (regexp replacements-alist)
+ (replace-regexp-in-string
+ "\\\\+[^\\\\]"
+ #'(lambda (txt)
+ (let* ((b (match-beginning 0))
+ (e (match-end 0))
+ (ch (aref txt (1- e)))
+ (repl (assoc ch replacements-alist)))
+ (if (and repl (zerop (mod (length txt) 2)))
+ (concat (substring txt b (- e 2))
+ (cdr repl))
+ txt)))
+ regexp nil t))
+
+(defun evil-transform-magic (str magic quote transform &optional _start)
+ "Transforms STR with magic characters.
+MAGIC is a regexp that matches all potential magic
+characters. Each occurence of CHAR as magic character within str
+is replaced by the result of calling the associated TRANSFORM
+function. TRANSFORM is a function taking two arguments, the
+character to be transformed and the rest of string after the
+character. The function should return a triple (REPLACEMENT REST
+. STOP) where REPLACEMENT is the replacement and REST is the rest
+of the string that has not been transformed. If STOP is non-nil
+then the substitution stops immediately. The replacement starts
+at position START, everything before that position is returned
+literally. The result is a pair (RESULT . REST). RESULT is a
+list containing the transformed parts in order. If two
+subsequents parts are both strings, they are concatenated. REST
+is the untransformed rest string (usually \"\" but may be more if
+TRANSFORM stopped the substitution). Which characters are
+considered as magic characters (i.e. the transformation happens
+if the character is NOT preceeded by a backslash) is determined
+by `evil-magic'. The special tokens \\v, \\V, \\m and \\M have
+always a special meaning (like in Vim) and should not be
+contained in TRANSFORMS, otherwise their meaning is overwritten.
+
+The parameter QUOTE is a quoting function applied to literal
+transformations, usually `regexp-quote' or `replace-quote'."
+ (save-match-data
+ (let ((regexp (concat "\\(?:\\`\\|[^\\]\\)\\(\\\\\\(?:\\(" magic "\\)\\|\\(.\\)\\)\\|\\(" magic "\\)\\)"))
+ (magic-chars (evil-get-magic evil-magic))
+ (evil-magic evil-magic)
+ (quote (or quote #'identity))
+ result stop)
+ (while (and (not stop) str (string-match regexp str))
+ (unless (zerop (match-beginning 1))
+ (push (substring str 0 (match-beginning 1)) result))
+ (let ((char (or (match-string 2 str)
+ (match-string 3 str)
+ (match-string 4 str)))
+ (rest (substring str (match-end 0))))
+ (cond
+ ((match-beginning 4)
+ ;; magic character without backslash
+ (if (string-match magic-chars char)
+ ;; magic, do transform
+ (let ((trans (funcall transform (aref char 0) rest)))
+ (push (car trans) result)
+ (setq str (cadr trans) stop (nthcdr 2 trans)))
+ ;; non-magic, literal transformation
+ (push (funcall quote char) result)
+ (setq str rest)))
+ ((match-beginning 2)
+ ;; magic character with backslash
+ (if (not (string-match magic-chars char))
+ ;; non-magic, do transform
+ (let ((trans (funcall transform (aref char 0) rest)))
+ (push (car trans) result)
+ (setq str (cadr trans) stop (nthcdr 2 trans)))
+ ;; magic, literal transformation
+ (push (funcall quote char) result)
+ (setq str rest)))
+ ((memq (aref char 0) '(?m ?M ?v ?V))
+ (setq evil-magic (cdr (assq (aref char 0)
+ '((?m . t)
+ (?M . nil)
+ (?v . very-magic)
+ (?V . very-nomagic)))))
+ (setq magic-chars (evil-get-magic evil-magic))
+ (setq str rest))
+ (t
+ ;; non-magic char with backslash, literal transformation
+ (push (funcall quote char) result)
+ (setq str rest)))))
+ (cond
+ ((and str (not stop))
+ (push str result)
+ (setq str ""))
+ ((not str)
+ (setq str "")))
+ ;; concatenate subsequent strings
+ ;; note that result is in reverse order
+ (let (repl)
+ (while result
+ (cond
+ ((and (stringp (car result))
+ (zerop (length (car result))))
+ (pop result))
+ ((and (stringp (car result))
+ (stringp (cadr result)))
+ (setq result (cons (concat (cadr result)
+ (car result))
+ (nthcdr 2 result))))
+ (t
+ (push (pop result) repl))))
+ (cons repl str)))))
+
+(defconst evil-vim-regexp-replacements
+ '((?n . "\n") (?r . "\r")
+ (?t . "\t") (?b . "\b")
+ (?s . "[[:space:]]") (?S . "[^[:space:]]")
+ (?d . "[[:digit:]]") (?D . "[^[:digit:]]")
+ (?x . "[[:xdigit:]]") (?X . "[^[:xdigit:]]")
+ (?o . "[0-7]") (?O . "[^0-7]")
+ (?a . "[[:alpha:]]") (?A . "[^[:alpha:]]")
+ (?l . "[a-z]") (?L . "[^a-z]")
+ (?u . "[A-Z]") (?U . "[^A-Z]")
+ (?y . "\\s") (?Y . "\\S")
+ (?\( . "\\(") (?\) . "\\)")
+ (?{ . "\\{") (?} . "\\}")
+ (?\[ . "[") (?\] . "]")
+ (?< . "\\<") (?> . "\\>")
+ (?_ . "\\_")
+ (?* . "*") (?+ . "+")
+ (?? . "?") (?= . "?")
+ (?. . ".")
+ (?` . "`") (?^ . "^")
+ (?$ . "$") (?| . "\\|")))
+
+(defconst evil-regexp-magic "[][(){}<>_dDsSxXoOaAlLuUwWyY.*+?=^$`|nrtb]")
+
+(defun evil-transform-vim-style-regexp (regexp)
+ "Transforms vim-style backslash codes to Emacs regexp.
+This includes the backslash codes \\d, \\D, \\s, \\S, \\x, \\X,
+\\o, \\O, \\a, \\A, \\l, \\L, \\u, \\U and \\w, \\W. The new
+codes \\y and \\Y can be used instead of the Emacs code \\s and
+\\S which have a different meaning in Vim-style."
+ (car
+ (car
+ (evil-transform-magic
+ regexp evil-regexp-magic #'regexp-quote
+ #'(lambda (char rest)
+ (let ((repl (assoc char evil-vim-regexp-replacements)))
+ (if repl
+ (list (cdr repl) rest)
+ (list (concat "\\" (char-to-string char)) rest))))))))
+
+;;; Substitute
+
+(defun evil-downcase-first (str)
+ "Return STR with the first letter downcased."
+ (if (zerop (length str))
+ str
+ (concat (downcase (substring str 0 1))
+ (substring str 1))))
+
+(defun evil-upcase-first (str)
+ "Return STR with the first letter upcased."
+ (if (zerop (length str))
+ str
+ (concat (upcase (substring str 0 1))
+ (substring str 1))))
+
+(defun evil-get-magic (magic)
+ "Returns a regexp matching the magic characters according to MAGIC.
+Depending on the value of MAGIC the following characters are
+considered magic.
+ t [][{}*+?.&~$^
+ nil [][{}*+?$^
+ 'very-magic not 0-9A-Za-z_
+ 'very-nomagic empty."
+ (cond
+ ((eq magic t) "[][}{*+?.&~$^]")
+ ((eq magic 'very-magic) "[^0-9A-Za-z_]")
+ ((eq magic 'very-nomagic) "\\\\")
+ (t "[][}{*+?$^]")))
+
+;; TODO: support magic characters in patterns
+(defconst evil-replacement-magic "[eElLuU0-9&#,rnbt=]"
+ "All magic characters in a replacement string")
+
+(defun evil-compile-subreplacement (to &optional start)
+ "Convert a regexp replacement TO to Lisp from START until \\e or \\E.
+Returns a pair (RESULT . REST). RESULT is a list suitable for
+`perform-replace' if necessary, the original string if not.
+REST is the unparsed remainder of TO."
+ (let ((result
+ (evil-transform-magic
+ to evil-replacement-magic #'replace-quote
+ #'(lambda (char rest)
+ (cond
+ ((eq char ?#)
+ (list '(number-to-string replace-count) rest))
+ ((eq char ?r) (list "\r" rest))
+ ((eq char ?n) (list "\n" rest))
+ ((eq char ?b) (list "\b" rest))
+ ((eq char ?t) (list "\t" rest))
+ ((memq char '(?e ?E))
+ `("" ,rest . t))
+ ((memq char '(?l ?L ?u ?U))
+ (let ((result (evil-compile-subreplacement rest))
+ (func (cdr (assoc char
+ '((?l . evil-downcase-first)
+ (?L . downcase)
+ (?u . evil-upcase-first)
+ (?U . upcase))))))
+ (list `(,func
+ (replace-quote
+ (evil-match-substitute-replacement
+ ,(car result)
+ (not case-replace))))
+ (cdr result))))
+ ((eq char ?=)
+ (when (or (zerop (length rest))
+ (not (eq (aref rest 0) ?@)))
+ (user-error "Expected @ after \\="))
+ (when (< (length rest) 2)
+ (user-error "Expected register after \\=@"))
+ (list (evil-get-register (aref rest 1))
+ (substring rest 2)))
+ ((eq char ?,)
+ (let* ((obj (read-from-string rest))
+ (result `(replace-quote ,(car obj)))
+ (end
+ ;; swallow a space after a symbol
+ (if (and (or (symbolp (car obj))
+ ;; swallow a space after 'foo,
+ ;; but not after (quote foo)
+ (and (eq (car-safe (car obj)) 'quote)
+ (not (= ?\( (aref rest 0)))))
+ (eq (string-match " " rest (cdr obj))
+ (cdr obj)))
+ (1+ (cdr obj))
+ (cdr obj))))
+ (list result (substring rest end))))
+ ((eq char ?0)
+ (list "\\&" rest))
+ (t
+ (list (concat "\\" (char-to-string char)) rest))))
+ start)))
+ (let ((rest (cdr result))
+ (result (car result)))
+ (replace-match-string-symbols result)
+ (cons (if (cdr result)
+ (cons 'concat result)
+ (or (car result) ""))
+ rest))))
+
+(defun evil-compile-replacement (to)
+ "Maybe convert a regexp replacement TO to Lisp.
+Returns a list suitable for `perform-replace' if necessary, the
+original string if not. Currently the following magic characters
+in replacements are supported: 0-9&#lLuUrnbt,
+The magic character , (comma) start an Emacs-lisp expression."
+ (when (stringp to)
+ (save-match-data
+ (cons 'replace-eval-replacement
+ (car (evil-compile-subreplacement to))))))
+
+(defun evil-replace-match (replacement &optional fixedcase string)
+ "Replace text match by last search with REPLACEMENT.
+If REPLACEMENT is an expression it will be evaluated to compute
+the replacement text, otherwise the function behaves as
+`replace-match'."
+ (if (stringp replacement)
+ (replace-match replacement fixedcase nil string)
+ (replace-match (funcall (car replacement)
+ (cdr replacement)
+ 0)
+ fixedcase nil string)))
+
+(defun evil-match-substitute-replacement (replacement &optional fixedcase string)
+ "Return REPLACEMENT as it will be inserted by `evil-replace-match'."
+ (if (stringp replacement)
+ (match-substitute-replacement replacement fixedcase nil string)
+ (match-substitute-replacement (funcall (car replacement)
+ (cdr replacement)
+ 0)
+ fixedcase nil string)))
+
+;;; Alignment
+
+(defun evil-justify-lines (beg end justify position)
+ "Justifes all lines in a range.
+BEG and END specify the range of those lines to be
+justified. JUSTIFY is either 'left, 'right or 'center according
+to the justification type. POSITION is the maximal text width for
+right and center justification or the column at which the lines
+should be left-aligned for left justification."
+ (let ((fill-column position)
+ adaptive-fill-mode fill-prefix)
+ (evil-with-restriction
+ (save-excursion
+ (goto-char beg)
+ (line-beginning-position))
+ (save-excursion
+ (goto-char end)
+ (if (bolp)
+ (line-end-position 0)
+ (line-end-position)))
+ (goto-char (point-min))
+ (while (progn
+ (if (eq justify 'left)
+ (indent-line-to position)
+ (when (re-search-forward "^[[:space:]]*" nil t)
+ (delete-region (match-beginning 0)
+ (match-end 0)))
+ (justify-current-line justify nil t))
+ (and (zerop (forward-line)) (bolp))))
+ (goto-char (point-min))
+ (back-to-indentation))))
+
+;;; View helper
+
+(defvar-local evil-list-view-select-action nil)
+(put 'evil-list-view-select-action 'permanent-local t)
+
+(define-derived-mode evil-list-view-mode tabulated-list-mode
+ "Evil List View"
+ (tabulated-list-init-header)
+ (tabulated-list-print))
+
+(defun evil-list-view-goto-entry ()
+ (interactive)
+ (when (and evil-list-view-select-action
+ (not (eobp)))
+ (let* ((line (line-number-at-pos (point)))
+ (entry (elt tabulated-list-entries (1- line))))
+ (funcall evil-list-view-select-action (nth 1 entry)))))
+
+(defun evil-list-view-quit ()
+ (interactive)
+ (quit-window 'kill))
+
+(define-key evil-list-view-mode-map (kbd "q") #'evil-list-view-quit)
+(define-key evil-list-view-mode-map [follow-link] nil) ;; allows mouse-1 to be activated
+(define-key evil-list-view-mode-map [mouse-1] #'evil-list-view-goto-entry)
+(define-key evil-list-view-mode-map [return] #'evil-list-view-goto-entry)
+
+(defmacro evil-with-view-list (&rest properties)
+ "Opens new list view buffer.
+
+PROPERTIES is a property-list which supports the following properties:
+
+:name (required) The name of the buffer.
+:mode-name (required) The name for the mode line.
+:format (required) The value for `tabulated-list-format'.
+:entries (required) The value for `tabulated-list-entries'.
+:select-action (optional) A function for row selection.
+ It takes in a single parameter, which is the selected row's
+ vector value that is passed into `:entries'.
+"
+ (declare (indent defun) (debug t))
+ `(let ((bufname (concat "*" ,(plist-get properties :name) "*"))
+ (inhibit-read-only t))
+ (and (get-buffer bufname)
+ (kill-buffer bufname))
+ (let ((buf (get-buffer-create bufname)))
+ (with-current-buffer buf
+ (setq tabulated-list-format ,(plist-get properties :format))
+ (setq tabulated-list-entries ,(plist-get properties :entries))
+ (setq evil-list-view-select-action ,(plist-get properties :select-action))
+ (evil-list-view-mode)
+ (setq mode-name ,(plist-get properties :mode-name))
+ (evil-motion-state))
+ (switch-to-buffer-other-window buf))))
+
+(provide 'evil-common)
+
+;;; evil-common.el ends here
diff --git a/elpa/evil-20220503.1314/evil-common.elc b/elpa/evil-20220503.1314/evil-common.elc
new file mode 100644
index 0000000..1d3d831
--- /dev/null
+++ b/elpa/evil-20220503.1314/evil-common.elc
Binary files differ
diff --git a/elpa/evil-20220503.1314/evil-core.el b/elpa/evil-20220503.1314/evil-core.el
new file mode 100644
index 0000000..cf75497
--- /dev/null
+++ b/elpa/evil-20220503.1314/evil-core.el
@@ -0,0 +1,1392 @@
+;;; evil-core.el --- Core functionality -*- lexical-binding: t -*-
+;; Author: Vegard Øye <vegard_oye at hotmail.com>
+;; Maintainer: Vegard Øye <vegard_oye at hotmail.com>
+
+;; Version: 1.15.0
+
+;;
+;; This file is NOT part of GNU Emacs.
+
+;;; License:
+
+;; This file is part of Evil.
+;;
+;; Evil 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.
+;;
+;; Evil 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 Evil. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Evil is defined as a globalized minor mode, enabled with the toggle
+;; function `evil-mode'. This in turn enables `evil-local-mode' in
+;; every buffer, which sets up the buffer's state.
+;;
+;; Each state has its own keymaps, and these keymaps have status as
+;; "emulation keymaps" with priority over regular keymaps. Emacs
+;; maintains the following keymap hierarchy (highest priority first):
+;;
+;; * Overriding keymaps/overlay keymaps...
+;; * Emulation mode keymaps...
+;; - Evil keymaps...
+;; * Minor mode keymaps...
+;; * Local keymap (`local-set-key')
+;; * Global keymap (`global-set-key')
+;;
+;; Within this hierarchy, Evil arranges the keymaps for the current
+;; state as shown below:
+;;
+;; * Intercept keymaps...
+;; * Local state keymap
+;; * Minor-mode keymaps...
+;; * Auxiliary keymaps...
+;; * Overriding keymaps...
+;; * Global state keymap
+;; * Keymaps for other states...
+;;
+;; These keymaps are listed in `evil-mode-map-alist', which is listed
+;; in `emulation-mode-map-alist'.
+;;
+;; Most of the key bindings for a state are stored in its global
+;; keymap, which has a name such as `evil-normal-state-map'. (See the
+;; file evil-maps.el, which contains all the default key bindings.) A
+;; state also has a local keymap (`evil-normal-state-local-map'),
+;; which may contain user customizations for the current buffer.
+;; Furthermore, any Emacs mode may be assigned state bindings of its
+;; own by passing the mode's keymap to the function `evil-define-key'
+;; or `evil-define-minor-mode-key'. The former uses a specific map to
+;; define the key in while the latter associates the key with a
+;; particular mode. These mode-specific bindings are ultimately stored
+;; in so-called auxiliary and minor-mode keymaps respectively, which
+;; are sandwiched between the local keymap and the global keymap.
+;; Finally, the state may also activate the keymaps of other states
+;; (e.g., Normal state inherits bindings from Motion state).
+;;
+;; For integration purposes, a regular Emacs keymap may be "elevated"
+;; to emulation status by passing it to `evil-make-intercept-map' or
+;; `evil-make-overriding-map'. An "intercept" keymap has priority over
+;; all other Evil keymaps. (Evil uses this facility when debugging and
+;; for handling the "ESC" key in the terminal.) More common is the
+;; "overriding" keymap, which only has priority over the global state
+;; keymap. (This is useful for adapting key-heavy modes such as Dired,
+;; where all but a few keys should be left as-is and should not be
+;; shadowed by Evil's default bindings.)
+;;
+;; States are defined with the macro `evil-define-state', which
+;; creates a command for switching to the state. This command,
+;; for example `evil-normal-state' for Normal state, performs
+;; the following tasks:
+;;
+;; * Setting `evil-state' to the new state.
+;; * Refreshing the keymaps in `evil-mode-map-alist'.
+;; * Updating the mode line.
+;; - Normal state depends on `evil-normal-state-tag'.
+;; * Adjusting the cursor's appearance.
+;; - Normal state depends on `evil-normal-state-cursor'.
+;; * Displaying a message in the echo area.
+;; - Normal state depends on `evil-normal-state-message'.
+;; * Running hooks.
+;; - Normal state runs `evil-normal-state-entry-hook' when
+;; entering, and `evil-normal-state-exit-hook' when exiting.
+;;
+;; The various properties of a state can be accessed through their
+;; respective variables, or by passing a keyword and the state's name
+;; to the `evil-state-property' function. Evil defines the states
+;; Normal state ("normal"), Insert state ("insert"), Visual state
+;; ("visual"), Replace state ("replace"), Operator-Pending state
+;; ("operator"), Motion state ("motion") and Emacs state ("emacs").
+
+(require 'evil-common)
+
+;;; Code:
+
+(declare-function evil-emacs-state-p "evil-states")
+(declare-function evil-ex-p "evil-ex")
+(defvar evil-mode-buffers)
+
+(define-minor-mode evil-local-mode
+ "Minor mode for setting up Evil in a single buffer."
+ :init-value nil
+ (cond
+ ((evil-disabled-buffer-p)
+ ;; Don't leave the mode variable on in buffers where evil disabled, because
+ ;; functions that check this variable will get an incorrect result (e.g.,
+ ;; evil-refresh-cursor).
+ (setq evil-local-mode nil))
+ (evil-local-mode
+ (setq emulation-mode-map-alists
+ (evil-concat-lists '(evil-mode-map-alist)
+ emulation-mode-map-alists))
+ (evil-initialize-local-keymaps)
+ ;; restore the proper value of `major-mode' in Fundamental buffers
+ (when (eq major-mode 'turn-on-evil-mode)
+ (setq major-mode 'fundamental-mode))
+ (when (minibufferp)
+ (setq-local evil-default-state 'insert)
+ (setq-local evil-echo-state nil))
+ ;; The initial state is usually setup by `evil-initialize' when
+ ;; the major-mode in a buffer changes. This preliminary
+ ;; initialization is only for the case when `evil-local-mode' is
+ ;; called directly for the first time in a buffer.
+ (unless evil-state (evil-initialize-state))
+ (add-hook 'input-method-activate-hook 'evil-activate-input-method t t)
+ (add-hook 'input-method-deactivate-hook 'evil-deactivate-input-method t t)
+ (add-hook 'activate-mark-hook 'evil-visual-activate-hook nil t)
+ (add-hook 'pre-command-hook 'evil-repeat-pre-hook)
+ (add-hook 'post-command-hook 'evil-repeat-post-hook))
+ (t
+ (evil-refresh-mode-line)
+ (remove-hook 'activate-mark-hook 'evil-visual-activate-hook t)
+ (remove-hook 'input-method-activate-hook 'evil-activate-input-method t)
+ (remove-hook 'input-method-deactivate-hook 'evil-deactivate-input-method t)
+ (evil-change-state nil))))
+
+;; Make the variable permanent local. This is particular useful in
+;; conjunction with nXhtml/mumamo because mumamo does not touch these
+;; variables.
+(put 'evil-local-mode 'permanent-local t)
+
+(defun turn-on-evil-mode (&optional arg)
+ "Turn on Evil in the current buffer."
+ (interactive)
+ (evil-local-mode (or arg 1)))
+
+(defun turn-off-evil-mode (&optional arg)
+ "Turn off Evil in the current buffer."
+ (interactive)
+ (evil-local-mode (or arg -1)))
+
+;; The function `evil-initialize' should only be used to initialize
+;; `evil-local-mode' from the globalized minor-mode `evil-mode'. It is
+;; called whenever evil is enabled in a buffer for the first time or
+;; when evil is active and the major-mode of the buffer changes. In
+;; addition to enabling `evil-local-mode' it also sets the initial
+;; evil-state according to the major-mode.
+(defun evil-initialize ()
+ "Enable Evil in the current buffer, if appropriate.
+To enable Evil globally, do (evil-mode 1)."
+ (unless (and (minibufferp) (not evil-want-minibuffer))
+ (evil-local-mode 1)
+ (evil-initialize-state)))
+
+;;;###autoload (autoload 'evil-mode "evil" nil t)
+(define-globalized-minor-mode evil-mode
+ evil-local-mode evil-initialize)
+
+;; No hooks are run in Fundamental buffers, so other measures are
+;; necessary to initialize Evil in these buffers. When Evil is
+;; enabled globally, the default value of `major-mode' is set to
+;; `turn-on-evil-mode', so that Evil is enabled in Fundamental
+;; buffers as well. Then, the buffer-local value of `major-mode' is
+;; changed back to `fundamental-mode'. (Since the `evil-mode' function
+;; is created by a macro, we use `defadvice' to augment it.)
+(defadvice evil-mode (after start-evil activate)
+ "Enable Evil in Fundamental mode."
+ (if evil-mode
+ (progn
+ (when (eq (default-value 'major-mode) 'fundamental-mode)
+ ;; changed back by `evil-local-mode'
+ (setq-default major-mode 'turn-on-evil-mode))
+ (ad-enable-regexp "^evil")
+ (ad-activate-regexp "^evil")
+ (with-no-warnings (evil-esc-mode 1)))
+ (when (eq (default-value 'major-mode) 'turn-on-evil-mode)
+ (setq-default major-mode 'fundamental-mode))
+ (ad-disable-regexp "^evil")
+ (ad-update-regexp "^evil")
+ (with-no-warnings (evil-esc-mode -1))))
+
+(defun evil-change-state (state &optional message)
+ "Change the state to STATE.
+If STATE is nil, disable all states."
+ (let ((func (evil-state-property (or state evil-state) :toggle)))
+ (when (and (functionp func)
+ (or message (not (eq state evil-state))))
+ (funcall func (if state (and message 1) -1)))))
+
+(defmacro evil-save-state (&rest body)
+ "Save the current state; execute BODY; restore the state."
+ (declare (indent defun)
+ (debug t))
+ `(let* ((evil-state evil-state)
+ (evil-previous-state evil-previous-state)
+ (evil-previous-state-alist (copy-tree evil-previous-state-alist))
+ (evil-next-state evil-next-state)
+ (old-state evil-state)
+ (inhibit-quit t)
+ (buf (current-buffer)))
+ (unwind-protect
+ (progn ,@body)
+ (when (buffer-live-p buf)
+ (with-current-buffer buf
+ (evil-change-state old-state))))))
+
+(defmacro evil-with-state (state &rest body)
+ "Change to STATE and execute BODY without refreshing the display.
+Restore the previous state afterwards."
+ (declare (indent defun)
+ (debug t))
+ `(evil-without-display
+ (evil-save-state
+ (evil-change-state ',state)
+ ,@body)))
+
+(defun evil-initializing-p (&optional buffer)
+ "Whether Evil is in the process of being initialized."
+ (memq (or buffer (current-buffer)) evil-mode-buffers))
+
+(defun evil-initialize-state (&optional state buffer)
+ "Set up the initial state for BUFFER.
+BUFFER defaults to the current buffer.
+Uses STATE if specified, or calls `evil-initial-state-for-buffer'.
+See also `evil-set-initial-state'."
+ (with-current-buffer (or buffer (current-buffer))
+ (if state (evil-change-state state)
+ (evil-change-to-initial-state buffer))))
+(put 'evil-initialize-state 'permanent-local-hook t)
+
+(defun evil-initial-state-for-buffer-name (&optional name default)
+ "Return the initial Evil state to use for a buffer with name NAME.
+Matches the name against the regular expressions in
+`evil-buffer-regexps'. If none matches, returns DEFAULT."
+ (let ((name (if (stringp name) name (buffer-name name)))
+ regexp state)
+ (when (stringp name)
+ (catch 'done
+ (dolist (entry evil-buffer-regexps default)
+ (setq regexp (car entry)
+ state (cdr entry))
+ (when (string-match regexp name)
+ (throw 'done state)))))))
+
+(defun evil-disabled-buffer-p (&optional buffer)
+ "Whether Evil should be disabled in BUFFER."
+ (null (evil-initial-state-for-buffer-name buffer 'undefined)))
+
+(defun evil-initial-state-for-buffer (&optional buffer default)
+ "Return the initial Evil state to use for BUFFER.
+BUFFER defaults to the current buffer. Returns DEFAULT
+if no initial state is associated with BUFFER.
+See also `evil-initial-state'."
+ (with-current-buffer (or buffer (current-buffer))
+ (or (evil-initial-state-for-buffer-name (buffer-name))
+ (catch 'done
+ (dolist (mode minor-mode-map-alist)
+ (setq mode (car-safe mode))
+ (when (and (boundp mode) (symbol-value mode))
+ (when (setq mode (evil-initial-state mode))
+ (throw 'done mode)))))
+ (evil-initial-state major-mode nil t)
+ default)))
+
+(defun evil-initial-state (mode &optional default follow-parent checked-modes)
+ "Return the Evil state to use for MODE or its alias.
+Returns DEFAULT if no initial state is associated with MODE.
+The initial state for a mode can be set with
+`evil-set-initial-state'.
+
+If FOLLOW-PARENT is non-nil, also check parent modes of MODE and
+its alias. CHECKED-MODES is used internally and should not be set
+initially."
+ (cond
+ ((and mode (symbolp mode) (memq mode checked-modes))
+ (error "Circular reference detected in ancestors of %s\n%s"
+ major-mode checked-modes))
+ ((and mode (symbolp mode))
+ (let ((mode-alias (let ((func (symbol-function mode)))
+ (when (symbolp func)
+ func)))
+ state modes)
+ (or
+ (catch 'done
+ (dolist (entry (evil-state-property t :modes) default)
+ (setq state (car entry)
+ modes (symbol-value (cdr entry)))
+ (when (or (memq mode modes)
+ (and mode-alias
+ (memq mode-alias modes)))
+ (throw 'done state))))
+ (when follow-parent
+ (evil-initial-state (get mode 'derived-mode-parent)
+ nil t (cons mode checked-modes)))
+ (when follow-parent
+ (evil-initial-state (get mode-alias 'derived-mode-parent)
+ nil t (cons mode-alias checked-modes))))))))
+
+(defun evil-set-initial-state (mode state)
+ "Set the initial state for major mode MODE to STATE.
+This is the state the buffer comes up in."
+ (dolist (modes (evil-state-property t :modes))
+ (setq modes (cdr-safe modes))
+ (set modes (delq mode (symbol-value modes))))
+ (when state
+ (add-to-list (evil-state-property state :modes) mode)))
+
+(evil-define-command evil-change-to-initial-state
+ (&optional buffer message)
+ "Change the state of BUFFER to its initial state.
+This is the state the buffer came up in. If Evil is not activated
+then this function does nothing."
+ :keep-visual t
+ :suppress-operator t
+ (with-current-buffer (or buffer (current-buffer))
+ (when evil-local-mode
+ (evil-change-state (evil-initial-state-for-buffer
+ buffer (or evil-default-state 'normal))
+ message))))
+
+(evil-define-command evil-change-to-previous-state
+ (&optional buffer message)
+ "Change the state of BUFFER to its previous state."
+ :keep-visual t
+ :repeat abort
+ :suppress-operator t
+ (with-current-buffer (or buffer (current-buffer))
+ (let ((prev-state evil-previous-state)
+ (prev-prev-state (cdr-safe (assoc evil-previous-state
+ evil-previous-state-alist))))
+ (evil-change-state nil)
+ (when prev-prev-state
+ (setq evil-previous-state prev-prev-state))
+ (evil-change-state (or prev-state evil-default-state 'normal)
+ message))))
+
+;; When a buffer is created in a low-level way, it is invisible to
+;; Evil (as well as other globalized minor modes) because no hooks are
+;; run. This is appropriate since many buffers are used for throwaway
+;; purposes. Passing the buffer to `set-window-buffer' indicates
+;; otherwise, though, so advise this function to initialize Evil.
+(defadvice set-window-buffer (before evil)
+ "Initialize Evil in the displayed buffer."
+ (when evil-mode
+ (when (get-buffer (ad-get-arg 1))
+ (with-current-buffer (ad-get-arg 1)
+ (unless evil-local-mode
+ (evil-local-mode 1))))))
+
+;; Refresh cursor color.
+;; Cursor color can only be set for each frame but not for each buffer.
+(add-hook 'window-configuration-change-hook 'evil-refresh-cursor)
+(defadvice select-window (after evil activate)
+ (evil-refresh-cursor))
+
+(defun evil-generate-mode-line-tag (&optional state)
+ "Generate the evil mode-line tag for STATE."
+ (let ((tag (evil-state-property state :tag t)))
+ (when (functionp tag)
+ (setq tag (funcall tag)))
+ ;; prepare mode-line: add tooltip
+ (if (stringp tag)
+ (propertize tag
+ 'help-echo (evil-state-property state :name)
+ 'mouse-face 'mode-line-highlight)
+ tag)))
+
+(defun evil-refresh-mode-line (&optional state)
+ "Refresh mode line tag."
+ (when (listp mode-line-format)
+ (setq evil-mode-line-tag (evil-generate-mode-line-tag state))
+ ;; refresh mode line data structure
+ ;; first remove evil from mode-line
+ (setq mode-line-format (delq 'evil-mode-line-tag mode-line-format))
+ (let ((mlpos mode-line-format)
+ pred which where)
+ ;; determine before/after which symbol the tag should be placed
+ (cond
+ ((eq evil-mode-line-format 'before)
+ (setq where 'after which 'mode-line-position))
+ ((eq evil-mode-line-format 'after)
+ (setq where 'after which 'mode-line-modes))
+ ((consp evil-mode-line-format)
+ (setq where (car evil-mode-line-format)
+ which (cdr evil-mode-line-format))))
+ ;; find the cons-cell of the symbol before/after which the tag
+ ;; should be placed
+ (while (and mlpos
+ (let ((sym (or (car-safe (car mlpos)) (car mlpos))))
+ (not (eq which sym))))
+ (setq pred mlpos
+ mlpos (cdr mlpos)))
+ ;; put evil tag at the right position in the mode line
+ (cond
+ ((not mlpos)) ;; position not found, so do not add the tag
+ ((eq where 'before)
+ (if pred
+ (setcdr pred (cons 'evil-mode-line-tag mlpos))
+ (setq mode-line-format
+ (cons 'evil-mode-line-tag mode-line-format))))
+ ((eq where 'after)
+ (setcdr mlpos (cons 'evil-mode-line-tag (cdr mlpos)))))
+ (force-mode-line-update))))
+
+;; input methods should be disabled in non-insertion states
+(defun evil-activate-input-method ()
+ "Enable input method in states with :input-method non-nil."
+ (let (input-method-activate-hook
+ input-method-deactivate-hook)
+ (when (and evil-local-mode evil-state)
+ (setq evil-input-method current-input-method)
+ (unless (evil-state-property evil-state :input-method)
+ (deactivate-input-method)))))
+(put 'evil-activate-input-method 'permanent-local-hook t)
+
+(defun evil-deactivate-input-method ()
+ "Disable input method in all states."
+ (let (input-method-activate-hook
+ input-method-deactivate-hook)
+ (when (and evil-local-mode evil-state)
+ (setq evil-input-method nil))))
+(put 'evil-deactivate-input-method 'permanent-local-hook t)
+
+(defmacro evil-without-input-method-hooks (&rest body)
+ "Execute body with evil's activate/deactivate-input-method hooks deactivated.
+
+This allows input methods to be used in normal-state."
+ `(unwind-protect
+ (progn
+ (remove-hook 'input-method-activate-hook 'evil-activate-input-method t)
+ (remove-hook 'input-method-deactivate-hook
+ 'evil-deactivate-input-method t)
+ ,@body)
+ (progn
+ (add-hook 'input-method-activate-hook 'evil-activate-input-method nil t)
+ (add-hook 'input-method-deactivate-hook
+ 'evil-deactivate-input-method nil t))))
+
+(defadvice toggle-input-method (around evil)
+ "Refresh `evil-input-method'."
+ (cond
+ ((not evil-local-mode)
+ ad-do-it)
+ ((evil-state-property evil-state :input-method)
+ ad-do-it)
+ (t
+ (let ((current-input-method evil-input-method))
+ ad-do-it))))
+
+;; Local keymaps are implemented using buffer-local variables.
+;; However, unless a buffer-local value already exists,
+;; `define-key' acts on the variable's default (global) value.
+;; So we need to initialize the variable whenever we enter a
+;; new buffer or when the buffer-local values are reset.
+(defun evil-initialize-local-keymaps ()
+ "Initialize a buffer-local value for local keymaps as necessary.
+The initial value is that of `make-sparse-keymap'."
+ (dolist (entry evil-local-keymaps-alist)
+ (let ((map (cdr entry)))
+ (unless (and (keymapp (symbol-value map))
+ (local-variable-p map))
+ (set map (make-sparse-keymap))))))
+
+(defun evil-make-overriding-map (keymap &optional state copy)
+ "Give KEYMAP precedence over the global keymap of STATE.
+The keymap will have lower precedence than custom STATE bindings.
+If STATE is nil, give it precedence over all states.
+If COPY is t, create a copy of KEYMAP and give that
+higher precedence. See also `evil-make-intercept-map'."
+ (let ((key [override-state]))
+ (if (not copy)
+ (define-key keymap key (or state 'all))
+ (unless (keymapp copy)
+ (setq copy (assq-delete-all 'menu-bar (copy-keymap keymap))))
+ (define-key copy key (or state 'all))
+ (define-key keymap key copy))))
+
+(defun evil-make-intercept-map (keymap &optional state aux)
+ "Give KEYMAP precedence over all Evil keymaps in STATE.
+If STATE is nil, give it precedence over all states. If AUX is non-nil, make the
+auxiliary keymap corresponding to KEYMAP in STATE an intercept keymap instead of
+KEYMAP itself. See also `evil-make-overriding-map'."
+ (let ((key [intercept-state])
+ (keymap (if aux
+ (evil-get-auxiliary-keymap keymap state t t)
+ keymap)))
+ (define-key keymap key (or state 'all))))
+
+(defmacro evil-define-keymap (keymap doc &rest body)
+ "Define a keymap KEYMAP listed in `evil-mode-map-alist'.
+That means it will have precedence over regular keymaps.
+
+DOC is the documentation for the variable. BODY, if specified,
+is executed after toggling the mode. Optional keyword arguments
+may be specified before the body code:
+
+:mode VAR Mode variable. If unspecified, the variable
+ is based on the keymap name.
+:local BOOLEAN Whether the keymap should be buffer-local, that is,
+ reinitialized for each buffer.
+:func BOOLEAN Create a toggle function even if BODY is empty.
+
+\(fn KEYMAP DOC [[KEY VAL]...] BODY...)"
+ (declare (indent defun)
+ (doc-string 2)
+ (debug (&define name
+ [&optional stringp]
+ [&rest [keywordp sexp]]
+ def-body)))
+ (let ((func t)
+ arg intercept key local mode overriding)
+ (while (keywordp (car-safe body))
+ (setq key (pop body)
+ arg (pop body))
+ (cond
+ ((eq key :mode)
+ (setq mode arg))
+ ((eq key :local)
+ (setq local arg))
+ ((eq key :func)
+ (setq func arg))
+ ((eq key :intercept)
+ (setq intercept arg))
+ ((eq key :overriding)
+ (setq overriding arg))))
+ (setq mode (or mode
+ (intern (replace-regexp-in-string
+ "\\(?:-\\(?:mode-\\)?\\(?:key\\)?map\\)?$"
+ "-mode"
+ (symbol-name keymap)))))
+ `(progn
+ (defvar ,keymap ,(unless local '(make-sparse-keymap)))
+ (unless (get ',keymap 'variable-documentation)
+ (put ',keymap 'variable-documentation ,doc))
+ (defvar ,mode nil)
+ (unless (get ',mode 'variable-documentation)
+ (put ',mode 'variable-documentation ,doc))
+ (make-variable-buffer-local ',mode)
+ (put ',mode 'permanent-local t)
+ (when ,intercept
+ (evil-make-intercept-map ,keymap))
+ (when ,overriding
+ (evil-make-overriding-map ,keymap))
+ ,@(if local
+ `((make-variable-buffer-local ',keymap)
+ (put ',keymap 'permanent-local t)
+ (evil--add-to-alist 'evil-local-keymaps-alist
+ ',mode ',keymap))
+ `((evil--add-to-alist 'evil-global-keymaps-alist
+ ',mode ',keymap)
+ (evil--add-to-alist 'evil-mode-map-alist
+ ',mode ,keymap)))
+ ,(when (or body func)
+ `(defun ,mode (&optional arg)
+ ,@(when doc `(,doc))
+ (interactive)
+ (cond
+ ((numberp arg)
+ (setq ,mode (> arg 0)))
+ (t
+ (setq ,mode (not ,mode))))
+ ,@body))
+ ',keymap)))
+
+;; The ESC -> escape translation code has been provided by Stefan
+;; Monnier in the discussion of GNU Emacs bug #13793.
+(defun evil-esc-mode (&optional arg)
+ "Toggle interception of \\e (escape).
+Enable with positive ARG and disable with negative ARG.
+
+When enabled, `evil-esc-mode' modifies the entry of \\e in
+`input-decode-map'. If such an event arrives, it is translated to
+a plain 'escape event if no further event occurs within
+`evil-esc-delay' seconds. Otherwise no translation happens and
+the ESC prefix map (i.e. the map originally bound to \\e in
+`input-decode-map`) is returned."
+ (cond
+ ((or (null arg) (eq arg 0))
+ (evil-esc-mode (if evil-esc-mode -1 +1)))
+ ((> arg 0)
+ (unless evil-esc-mode
+ (setq evil-esc-mode t)
+ (add-hook 'after-make-frame-functions #'evil-init-esc)
+ (mapc #'evil-init-esc (frame-list))))
+ ((< arg 0)
+ (when evil-esc-mode
+ (remove-hook 'after-make-frame-functions #'evil-init-esc)
+ (mapc #'evil-deinit-esc (frame-list))
+ (setq evil-esc-mode nil)))))
+
+(defun evil-init-esc (frame)
+ "Update `input-decode-map' in terminal."
+ (with-selected-frame frame
+ (let ((term (frame-terminal frame)))
+ (when (and
+ (or (eq evil-intercept-esc 'always)
+ (and evil-intercept-esc
+ (eq (terminal-live-p term) t))) ; only patch tty
+ (not (terminal-parameter term 'evil-esc-map)))
+ (let ((evil-esc-map (lookup-key input-decode-map [?\e])))
+ (set-terminal-parameter term 'evil-esc-map evil-esc-map)
+ (define-key input-decode-map [?\e]
+ `(menu-item "" ,evil-esc-map :filter ,#'evil-esc)))))))
+
+(defun evil-deinit-esc (frame)
+ "Restore `input-decode-map' in terminal."
+ (with-selected-frame frame
+ (let ((term (frame-terminal frame)))
+ (when (terminal-live-p term)
+ (let ((evil-esc-map (terminal-parameter term 'evil-esc-map)))
+ (when evil-esc-map
+ (define-key input-decode-map [?\e] evil-esc-map)
+ (set-terminal-parameter term 'evil-esc-map nil)))))))
+
+(defun evil-esc (map)
+ "Translate \\e to 'escape if no further event arrives.
+This function is used to translate a \\e event either to 'escape
+or to the standard ESC prefix translation map. If \\e arrives,
+this function waits for `evil-esc-delay' seconds for another
+event. If no other event arrives, the event is translated to
+'escape, otherwise it is translated to the standard ESC prefix
+map stored in `input-decode-map'. If `evil-inhibit-esc' is
+non-nil or if evil is in emacs state, the event is always
+translated to the ESC prefix.
+
+The translation to 'escape happens only if the current command
+has indeed been triggered by \\e. In other words, this will only
+happen when the keymap is accessed from `read-key-sequence'. In
+particular, if it is access from `define-key' the returned
+mapping will always be the ESC prefix map."
+ (if (and (not evil-inhibit-esc)
+ (or evil-local-mode (evil-ex-p)
+ (active-minibuffer-window))
+ (not (evil-emacs-state-p))
+ (let ((keys (this-single-command-keys)))
+ (and (> (length keys) 0)
+ (= (aref keys (1- (length keys))) ?\e)))
+ (sit-for evil-esc-delay))
+ (prog1 [escape]
+ (when defining-kbd-macro
+ (end-kbd-macro)
+ (setq last-kbd-macro (vconcat last-kbd-macro [escape]))
+ (start-kbd-macro t t)))
+ map))
+
+(defun evil-state-p (sym)
+ "Whether SYM is the name of a state."
+ (assq sym evil-state-properties))
+
+(defun evil-state-keymaps (state &rest excluded)
+ "Return a keymap alist of keymaps activated by STATE.
+If STATE references other states in its :enable property,
+these states are recursively processed and added to the list.
+\(The EXCLUDED argument is an internal safeguard against
+infinite recursion, keeping track of processed states.)"
+ (let* ((state (or state evil-state))
+ (enable (evil-state-property state :enable))
+ (map (cons
+ (evil-state-property state :mode)
+ (evil-state-property state :keymap t)))
+ (local-map (cons
+ (evil-state-property state :local)
+ (evil-state-property state :local-keymap t)))
+ (minor-mode-maps (evil-state-minor-mode-keymaps state))
+ (aux-maps (evil-state-auxiliary-keymaps state))
+ (overriding-maps
+ (evil-state-overriding-keymaps state))
+ (intercept-maps
+ (evil-state-intercept-keymaps state))
+ (result `(,intercept-maps))
+ (remove-duplicates (null excluded)))
+ (unless (memq state enable)
+ (setq enable (cons state enable)))
+ ;; process STATE's :enable property
+ (dolist (entry enable)
+ (cond
+ ((memq entry excluded))
+ ;; the keymaps for STATE
+ ((eq entry state)
+ (setq result `(,@result
+ (,local-map)
+ ,minor-mode-maps
+ ,aux-maps
+ ,overriding-maps
+ (,map)))
+ (push state excluded))
+ ;; the keymaps for another state: call `evil-state-keymaps'
+ ;; recursively, but keep track of processed states
+ ((evil-state-p entry)
+ (setq result `(,@result
+ ,(apply #'evil-state-keymaps entry excluded))))
+ ;; a single keymap
+ ((or (keymapp entry)
+ (and (keymapp (symbol-value entry))
+ (setq entry (symbol-value entry)))
+ (setq entry (evil-keymap-for-mode entry)))
+ (setq result `(,@result
+ ((,(evil-mode-for-keymap entry t) .
+ ,entry)))))))
+ ;; postpone the expensive filtering of duplicates to the top level
+ (if remove-duplicates
+ (apply #'evil-concat-keymap-alists result)
+ (apply #'append result))))
+
+(defun evil-normalize-keymaps (&optional state)
+ "Create a buffer-local value for `evil-mode-map-alist'.
+This is a keymap alist, determined by the current state
+\(or by STATE if specified)."
+ (let ((state (or state evil-state))
+ (excluded '(nil t))
+ map mode temp)
+ ;; initialize buffer-local keymaps as necessary
+ (evil-initialize-local-keymaps)
+ ;; deactivate keymaps of previous state
+ (dolist (entry evil-mode-map-alist)
+ (setq mode (car-safe entry)
+ map (cdr-safe entry))
+ ;; don't deactivate overriding keymaps;
+ ;; they are toggled by their associated mode
+ (if (or (memq mode excluded)
+ (evil-intercept-keymap-p map)
+ (evil-overriding-keymap-p map)
+ (evil-auxiliary-keymap-p map)
+ (evil-minor-mode-keymap-p map))
+ (push mode excluded)
+ (when (and (fboundp mode) (symbol-value mode))
+ (funcall mode -1))
+ (set mode nil)))
+ (setq evil-mode-map-alist nil)
+ ;; activate keymaps of current state
+ (when state
+ (setq temp (evil-state-keymaps state))
+ (dolist (entry temp)
+ (setq mode (car entry)
+ map (cdr entry))
+ (unless (or (and (boundp mode) (symbol-value mode))
+ ;; the minor-mode keymaps include modes that are not
+ ;; necessarily active
+ (evil-minor-mode-keymap-p map))
+ (when (fboundp mode)
+ (funcall mode 1))
+ (set mode t))
+ ;; refresh the keymap in case it has changed
+ ;; (e.g., `evil-operator-shortcut-map' is
+ ;; reset on toggling)
+ (if (or (memq mode excluded)
+ (evil-intercept-keymap-p map)
+ (evil-overriding-keymap-p map)
+ (evil-auxiliary-keymap-p map)
+ (evil-minor-mode-keymap-p map))
+ (push mode excluded)
+ (setcdr entry (or (evil-keymap-for-mode mode) map))))
+ ;; update `evil-mode-map-alist'
+ (setq evil-mode-map-alist temp))))
+
+(defun evil-mode-for-keymap (keymap &optional default)
+ "Return the minor mode associated with KEYMAP.
+Returns DEFAULT if no mode is found.
+See also `evil-keymap-for-mode'."
+ (let ((map (if (keymapp keymap) keymap (symbol-value keymap)))
+ (var (when (symbolp keymap) keymap)))
+ ;; Check Evil variables first for speed purposes.
+ ;; If all else fails, check `minor-mode-map-alist'.
+ (or (when var
+ (or (car (rassq var evil-global-keymaps-alist))
+ (car (rassq var evil-local-keymaps-alist))))
+ (car (rassq map (mapcar #'(lambda (e)
+ ;; from (MODE-VAR . MAP-VAR)
+ ;; to (MODE-VAR . MAP)
+ (cons (car-safe e)
+ (symbol-value (cdr-safe e))))
+ (append evil-global-keymaps-alist
+ evil-local-keymaps-alist))))
+ (car (rassq map minor-mode-map-alist))
+ default)))
+
+(defun evil-keymap-for-mode (mode &optional variable)
+ "Return the keymap associated with MODE.
+Return the keymap variable if VARIABLE is non-nil.
+See also `evil-mode-for-keymap'."
+ (let* ((var (or (cdr (assq mode evil-global-keymaps-alist))
+ (cdr (assq mode evil-local-keymaps-alist))))
+ (map (or (symbol-value var)
+ (cdr (assq mode minor-mode-map-alist)))))
+ (if variable var map)))
+
+(defun evil-state-auxiliary-keymaps (state)
+ "Return a keymap alist of auxiliary keymaps for STATE."
+ (let ((state (or state evil-state))
+ aux result)
+ (dolist (map (current-active-maps) result)
+ (when (setq aux (evil-get-auxiliary-keymap map state))
+ (push (cons (evil-mode-for-keymap map t) aux) result)))
+ (nreverse result)))
+
+(defun evil-state-minor-mode-keymaps (state)
+ "Return a keymap alist of minor-mode keymaps for STATE."
+ (let* ((state (or state evil-state))
+ (state-entry (assq state evil-minor-mode-keymaps-alist)))
+ (when state-entry
+ (cdr state-entry))))
+
+(defun evil-state-overriding-keymaps (&optional state)
+ "Return a keymap alist of overriding keymaps for STATE."
+ (let* ((state (or state evil-state))
+ result)
+ (dolist (map (current-active-maps))
+ (when (setq map (evil-overriding-keymap-p map state))
+ (push (cons (evil-mode-for-keymap map t) map) result)))
+ (nreverse result)))
+
+(defun evil-state-intercept-keymaps (&optional state)
+ "Return a keymap alist of intercept keymaps for STATE."
+ (let* ((state (or state evil-state))
+ result)
+ (dolist (map (current-active-maps))
+ (when (setq map (or (evil-intercept-keymap-p map state)
+ (evil-intercept-keymap-p
+ (evil-get-auxiliary-keymap map state) state)))
+ (push (cons (evil-mode-for-keymap map t) map) result)))
+ (setq result (nreverse result))
+ result))
+
+(defun evil-set-auxiliary-keymap (map state &optional aux)
+ "Set the auxiliary keymap for MAP in STATE to AUX.
+If AUX is nil, create a new auxiliary keymap."
+ (unless (keymapp aux)
+ (setq aux (make-sparse-keymap)))
+ (unless (evil-auxiliary-keymap-p aux)
+ (evil-set-keymap-prompt
+ aux (format "Auxiliary keymap for %s"
+ (or (evil-state-property state :name)
+ (format "%s state" state)))))
+ (define-key map
+ (vconcat (list (intern (format "%s-state" state)))) aux)
+ aux)
+(put 'evil-set-auxiliary-keymap 'lisp-indent-function 'defun)
+
+(defun evil-get-auxiliary-keymap (map state &optional create ignore-parent)
+ "Get the auxiliary keymap for MAP in STATE.
+If CREATE is non-nil, create an auxiliary keymap
+if MAP does not have one. If CREATE and
+IGNORE-PARENT are non-nil then a new auxiliary
+keymap is created even if the parent of MAP has
+one already."
+ (when state
+ (let* ((key (vconcat (list (intern (format "%s-state" state)))))
+ (parent-aux (when (and ignore-parent
+ (keymap-parent map))
+ (lookup-key (keymap-parent map) key)))
+ (aux (lookup-key map key)))
+ (cond
+ ((and ignore-parent
+ (equal parent-aux aux)
+ create)
+ (evil-set-auxiliary-keymap map state))
+ ((evil-auxiliary-keymap-p aux)
+ aux)
+ (create
+ (evil-set-auxiliary-keymap map state))))))
+
+(defun evil-get-minor-mode-keymap (state mode)
+ "Get the auxiliary keymap for MODE in STATE, creating one if it
+does not already exist."
+ (let ((state-entry (assq state evil-minor-mode-keymaps-alist)))
+ (if (and state-entry
+ (assq mode state-entry))
+ (cdr (assq mode state-entry))
+ (let ((map (make-sparse-keymap)))
+ (evil-set-keymap-prompt
+ map (format "Minor-mode keymap for %s in %s"
+ (symbol-name mode)
+ (or (evil-state-property state :name)
+ (format "%s state" state))))
+ (if state-entry
+ (setcdr state-entry
+ (append (list (cons mode map)) (cdr state-entry)))
+ (push (cons state (list (cons mode map)))
+ evil-minor-mode-keymaps-alist))
+ map))))
+
+(defun evil-auxiliary-keymap-p (map)
+ "Whether MAP is an auxiliary keymap."
+ (and (keymapp map)
+ (string-match-p "Auxiliary keymap"
+ (or (keymap-prompt map) "")) t))
+
+(defun evil-minor-mode-keymap-p (map)
+ "Whether MAP is a minor-mode keymap."
+ (and (keymapp map)
+ (string-match-p "Minor-mode keymap"
+ (or (keymap-prompt map) "")) t))
+
+(defun evil-intercept-keymap-p (map &optional state)
+ "Whether MAP is an intercept keymap for STATE.
+If STATE is nil, it means any state."
+ (let ((entry (and (keymapp map)
+ (lookup-key map [intercept-state]))))
+ (cond
+ ((null entry)
+ nil)
+ ((null state)
+ map)
+ ((eq entry state)
+ map)
+ ((eq entry 'all)
+ map))))
+
+(defun evil-overriding-keymap-p (map &optional state)
+ "Whether MAP is an overriding keymap for STATE.
+If STATE is nil, it means any state."
+ (let ((entry (and (keymapp map)
+ (lookup-key map [override-state]))))
+ (cond
+ ((null entry)
+ nil)
+ ((keymapp entry)
+ (evil-overriding-keymap-p entry state))
+ ((null state)
+ map)
+ ((eq entry state)
+ map)
+ ((eq entry 'all)
+ map))))
+
+(defun evil-intercept-keymap-state (map)
+ "Return the state for the intercept keymap MAP.
+A return value of t means all states."
+ (let ((state (lookup-key map [intercept-state] map)))
+ (cond
+ ((keymapp state)
+ (evil-intercept-keymap-state state))
+ ((eq state 'all)
+ t)
+ (t
+ state))))
+
+(defun evil-overriding-keymap-state (map)
+ "Return the state for the overriding keymap MAP.
+A return value of t means all states."
+ (let ((state (lookup-key map [override-state] map)))
+ (cond
+ ((keymapp state)
+ (evil-overriding-keymap-state state))
+ ((eq state 'all)
+ t)
+ (t
+ state))))
+
+(defun evil-send-leader ()
+ "Put symbol leader in `unread-command-events' to trigger any
+<leader> bindings."
+ (interactive)
+ (setq prefix-arg current-prefix-arg)
+ (push '(t . leader) unread-command-events))
+
+(defun evil-send-localleader ()
+ "Put symbol localleader in `unread-command-events' to trigger any
+<localleader> bindings."
+ (interactive)
+ (setq prefix-arg current-prefix-arg)
+ (push '(t . localleader) unread-command-events))
+
+(defun evil-set-leader (state key &optional localleader)
+ "Set KEY to trigger leader bindings in STATE.
+KEY should be in the form produced by `kbd'. STATE is one of
+`normal', `insert', `visual', `replace', `operator', `motion',
+`emacs', a list of one or more of these, or `nil', which means
+all of the above. If LOCALLEADER is non-nil, set the local leader
+instead."
+ (let* ((all-states '(normal insert visual replace operator motion emacs))
+ (states (cond ((listp state) state)
+ ((member state all-states) (list state))
+ ((null state) all-states)
+ ;; Maybe throw error here
+ (t (list state))))
+ (binding (if localleader 'evil-send-localleader 'evil-send-leader)))
+ (dolist (state states)
+ (evil-global-set-key state key binding))))
+
+(defmacro evil-define-key (state keymap key def &rest bindings)
+ "Create a STATE binding from KEY to DEF for KEYMAP.
+STATE is one of `normal', `insert', `visual', `replace',
+`operator', `motion', `emacs', or a list of one or more of
+these. Omitting a state by using `nil' corresponds to a standard
+Emacs binding using `define-key'. The remaining arguments are
+like those of `define-key'. For example:
+
+ (evil-define-key 'normal foo-map \"a\" 'bar)
+
+This creates a binding from `a' to `bar' in normal state, which
+is active whenever `foo-map' is active. Using nil for the state,
+the following lead to identical bindings:
+
+ (evil-define-key nil foo-map \"a\" 'bar)
+ (define-key foo-map \"a\" 'bar)
+
+It is possible to specify multiple states and/or bindings at
+once:
+
+ (evil-define-key '(normal visual) foo-map
+ \"a\" 'bar
+ \"b\" 'foo)
+
+If `foo-map' has not been initialized yet, this macro adds an
+entry to `after-load-functions', delaying execution as necessary.
+
+KEYMAP may also be a quoted symbol. If the symbol is `global', the
+global evil keymap corresponding to the state(s) is used, meaning
+the following lead to identical bindings:
+
+ (evil-define-key 'normal 'global \"a\" 'bar)
+ (evil-global-set-key 'normal \"a\" 'bar)
+
+The symbol `local' may also be used, which corresponds to using
+`evil-local-set-key'. If a quoted symbol is used that is not
+`global' or `local', it is assumed to be the name of a minor
+mode, in which case `evil-define-minor-mode-key' is used."
+ (declare (indent defun))
+ (cond ((member keymap '('global 'local))
+ `(evil-define-key* ,state ,keymap ,key ,def ,@bindings))
+ ((and (consp keymap) (eq (car keymap) 'quote))
+ `(evil-define-minor-mode-key ,state ,keymap ,key ,def ,@bindings))
+ (t
+ `(evil-delay ',(if (symbolp keymap)
+ `(and (boundp ',keymap) (keymapp ,keymap))
+ `(keymapp ,keymap))
+ '(condition-case-unless-debug err
+ (evil-define-key* ,state ,keymap ,key ,def ,@bindings)
+ (error
+ (message "error in evil-define-key: %s"
+ (error-message-string err))))
+ 'after-load-functions t nil
+ (format "evil-define-key-in-%s"
+ ',(if (symbolp keymap) keymap 'keymap))))))
+(defalias 'evil-declare-key 'evil-define-key)
+
+(defun evil-define-key* (state keymap key def &rest bindings)
+ "Create a STATE binding from KEY to DEF for KEYMAP.
+STATE is one of normal, insert, visual, replace, operator,
+motion, emacs, or a list of one or more of these. Omitting a
+state by using nil corresponds to a standard Emacs binding using
+`define-key' The remaining arguments are like those of
+`define-key'. For example:
+
+ (evil-define-key* 'normal foo-map \"a\" 'bar)
+
+This creates a binding from \"a\" to bar in Normal state, which
+is active whenever foo-map is active. Using nil for the state,
+the following are equivalent:
+
+ (evil-define-key* nil foo-map \"a\" 'bar)
+
+ (define-key foo-map \"a\" 'bar)
+
+ It is possible to specify multiple states and/or bindings at
+ once:
+
+ (evil-define-key* '(normal visual) foo-map
+ \"a\" 'bar
+ \"b\" 'foo)
+
+KEYMAP may also be a quoted symbol. If the symbol is global, the
+global evil keymap corresponding to the state(s) is used, meaning
+the following are equivalent:
+
+ (evil-define-key* 'normal 'global \"a\" 'bar)
+
+ (evil-global-set-key 'normal \"a\" 'bar)
+
+The symbol local may also be used, which corresponds to using
+`evil-local-set-key'.
+
+The use is nearly identical to `evil-define-key' with the
+exception that this is a function and not a macro (and so will
+not be expanded when compiled which can have unintended
+consequences). `evil-define-key*' also does not defer any
+bindings like `evil-define-key' does using `evil-delay'. This
+allows errors in the bindings to be caught immediately, and makes
+its behavior more predictable."
+ (declare (indent defun))
+ (let ((maps
+ (if state
+ (mapcar
+ (lambda (st)
+ (cond ((eq keymap 'global)
+ (evil-state-property st :keymap t))
+ ((eq keymap 'local)
+ (evil-state-property st :local-keymap t))
+ (t
+ (evil-get-auxiliary-keymap keymap st t t))))
+ (if (listp state) state (list state)))
+ (list
+ (cond ((eq keymap 'global)
+ global-map)
+ ((eq keymap 'local)
+ ;; see `local-set-key'
+ (or (current-local-map)
+ (let ((map (make-sparse-keymap)))
+ (use-local-map map)
+ map)))
+ (t
+ keymap))))))
+ (while key
+ (dolist (map maps)
+ (define-key map key def))
+ (setq key (pop bindings)
+ def (pop bindings)))
+ ;; ensure the prompt string comes first
+ (dolist (map maps)
+ (evil-set-keymap-prompt map (keymap-prompt map)))))
+
+(defun evil-define-minor-mode-key (state mode key def &rest bindings)
+ "Similar to `evil-define-key' but the bindings are associated
+with the minor-mode symbol MODE instead of a particular map.
+Associating bindings with a mode symbol instead of a map allows
+evil to use Emacs' built-in mechanisms to enable the bindings
+automatically when MODE is active without relying on calling
+`evil-normalize-keymaps'. Another less significant difference is
+that the bindings can be created immediately, because this
+function only uses the symbol MODE and does not rely on its
+value.
+
+See `evil-define-key' for the usage of STATE, KEY, DEF and
+BINDINGS."
+ (declare (indent defun))
+ (let ((maps (mapcar
+ (lambda (st)
+ (evil-get-minor-mode-keymap st mode))
+ (if (listp state) state (list state)))))
+ (while key
+ (dolist (map maps)
+ (define-key map key def))
+ (setq key (pop bindings)
+ def (pop bindings)))))
+
+(defmacro evil-add-hjkl-bindings (keymap &optional state &rest bindings)
+ "Add \"h\", \"j\", \"k\", \"l\" bindings to KEYMAP in STATE.
+Add additional BINDINGS if specified."
+ (declare (indent defun))
+ `(evil-define-key ,state ,keymap
+ "h" (lookup-key evil-motion-state-map "h")
+ "j" (lookup-key evil-motion-state-map "j")
+ "k" (lookup-key evil-motion-state-map "k")
+ "l" (lookup-key evil-motion-state-map "l")
+ ":" (lookup-key evil-motion-state-map ":")
+ ,@bindings))
+
+;; may be useful for programmatic purposes
+(defun evil-global-set-key (state key def)
+ "Bind KEY to DEF in STATE."
+ (define-key (evil-state-property state :keymap t) key def))
+
+(defun evil-local-set-key (state key def)
+ "Bind KEY to DEF in STATE in the current buffer."
+ (define-key (evil-state-property state :local-keymap t) key def))
+
+;; Advise these functions as they may activate an overriding keymap or
+;; a keymap with state bindings; if so, refresh `evil-mode-map-alist'.
+(defadvice use-global-map (after evil activate)
+ "Refresh Evil keymaps."
+ (evil-normalize-keymaps))
+
+(defadvice use-local-map (after evil activate)
+ "Refresh Evil keymaps."
+ (evil-normalize-keymaps))
+
+(defmacro evil-define-state (state doc &rest body)
+ "Define an Evil state STATE.
+DOC is a general description and shows up in all docstrings;
+the first line of the string should be the full name of the state.
+
+BODY is executed each time the state is enabled or disabled.
+
+Optional keyword arguments:
+- `:tag' - the mode line indicator, e.g. \"<T>\".
+- `:message' - string shown in the echo area when the state is
+ activated.
+- `:cursor' - default cursor specification.
+- `:enable' - list of other state keymaps to enable when in this
+ state.
+- `:entry-hook' - list of functions to run when entering this state.
+- `:exit-hook' - list of functions to run when exiting this state.
+- `:suppress-keymap' - if non-nil, effectively disables bindings to
+ `self-insert-command' by making `evil-suppress-map' the parent of
+ the global state keymap.
+
+The global keymap of this state will be `evil-test-state-map',
+the local keymap will be `evil-test-state-local-map', and so on.
+
+\(fn STATE DOC [[KEY VAL]...] BODY...)"
+ (declare (indent defun)
+ (doc-string 2)
+ (debug (&define name
+ [&optional stringp]
+ [&rest [keywordp sexp]]
+ def-body)))
+ (let* ((name (and (string-match "^\\(.+\\)\\(\\(?:.\\|\n\\)*\\)" doc)
+ (match-string 1 doc)))
+ (doc (match-string 2 doc))
+ (name (and (string-match "^\\(.+?\\)\\.?$" name)
+ (match-string 1 name)))
+ (doc (if (or (null doc) (string= doc "")) ""
+ (format "\n%s" doc)))
+ (toggle (intern (format "evil-%s-state" state)))
+ (mode (intern (format "%s-minor-mode" toggle)))
+ (keymap (intern (format "%s-map" toggle)))
+ (local (intern (format "%s-local-minor-mode" toggle)))
+ (local-keymap (intern (format "%s-local-map" toggle)))
+ (tag (intern (format "%s-tag" toggle)))
+ (message (intern (format "%s-message" toggle)))
+ (cursor (intern (format "%s-cursor" toggle)))
+ (entry-hook (intern (format "%s-entry-hook" toggle)))
+ (exit-hook (intern (format "%s-exit-hook" toggle)))
+ (modes (intern (format "%s-modes" toggle)))
+ (predicate (intern (format "%s-p" toggle)))
+ arg cursor-value enable entry-hook-value exit-hook-value
+ input-method key message-value suppress-keymap tag-value)
+ ;; collect keywords
+ (while (keywordp (car-safe body))
+ (setq key (pop body)
+ arg (pop body))
+ (cond
+ ((eq key :tag)
+ (setq tag-value arg))
+ ((eq key :message)
+ (setq message-value arg))
+ ((eq key :cursor)
+ (setq cursor-value arg))
+ ((eq key :entry-hook)
+ (setq entry-hook-value arg)
+ (unless (listp entry-hook-value)
+ (setq entry-hook-value (list entry-hook-value))))
+ ((eq key :exit-hook)
+ (setq exit-hook-value arg)
+ (unless (listp exit-hook-value)
+ (setq exit-hook-value (list exit-hook-value))))
+ ((eq key :enable)
+ (setq enable arg))
+ ((eq key :input-method)
+ (setq input-method arg))
+ ((eq key :suppress-keymap)
+ (setq suppress-keymap arg))))
+
+ ;; macro expansion
+ `(progn
+ ;; Save the state's properties in `evil-state-properties' for
+ ;; runtime lookup. Among other things, this information is used
+ ;; to determine what keymaps should be activated by the state
+ ;; (and, when processing :enable, what keymaps are activated by
+ ;; other states). We cannot know this at compile time because
+ ;; it depends on the current buffer and its active keymaps
+ ;; (to which we may have assigned state bindings), as well as
+ ;; states whose definitions may not have been processed yet.
+ (evil-put-property
+ 'evil-state-properties ',state
+ :name ',name
+ :toggle ',toggle
+ :mode (defvar ,mode nil
+ ,(format "Non-nil if %s is enabled.
+Use the command `%s' to change this variable." name toggle))
+ :keymap (defvar ,keymap (make-sparse-keymap)
+ ,(format "Keymap for %s." name))
+ :local (defvar ,local nil
+ ,(format "Non-nil if %s is enabled.
+Use the command `%s' to change this variable." name toggle))
+ :local-keymap (defvar ,local-keymap nil
+ ,(format "Buffer-local keymap for %s." name))
+ :tag (defvar ,tag ,tag-value
+ ,(format "Mode line tag for %s." name))
+ :message (defvar ,message ,message-value
+ ,(format "Echo area message for %s." name))
+ :cursor (defvar ,cursor ',cursor-value
+ ,(format "Cursor for %s.
+May be a cursor type as per `cursor-type', a color string as passed
+to `set-cursor-color', a zero-argument function for changing the
+cursor, or a list of the above." name))
+ :entry-hook (defvar ,entry-hook nil
+ ,(format "Hooks to run when entering %s." name))
+ :exit-hook (defvar ,exit-hook nil
+ ,(format "Hooks to run when exiting %s." name))
+ :modes (defvar ,modes nil
+ ,(format "Modes that should come up in %s." name))
+ :input-method ',input-method
+ :predicate ',predicate
+ :enable ',enable)
+
+ ,@(when suppress-keymap
+ `((set-keymap-parent ,keymap evil-suppress-map)))
+
+ (dolist (func ',entry-hook-value)
+ (add-hook ',entry-hook func))
+
+ (dolist (func ',exit-hook-value)
+ (add-hook ',exit-hook func))
+
+ (defun ,predicate (&optional state)
+ ,(format "Whether the current state is %s.
+\(That is, whether `evil-state' is `%s'.)" name state)
+ (and evil-local-mode
+ (eq (or state evil-state) ',state)))
+
+ ;; define state function
+ (defun ,toggle (&optional arg)
+ ,(format "Enable %s. Disable with negative ARG.
+If ARG is nil, don't display a message in the echo area.%s" name doc)
+ (interactive)
+ (cond
+ ((and (numberp arg) (< arg 1))
+ (setq evil-previous-state evil-state
+ evil-state nil)
+ (let ((evil-state ',state))
+ (run-hooks ',exit-hook)
+ (setq evil-state nil)
+ (evil-normalize-keymaps)
+ ,@body))
+ (t
+ (unless evil-local-mode
+ (evil-local-mode 1))
+ (let ((evil-next-state ',state)
+ input-method-activate-hook
+ input-method-deactivate-hook)
+ (evil-change-state nil)
+ (setq evil-state ',state)
+ (evil--add-to-alist 'evil-previous-state-alist
+ ',state evil-previous-state)
+ (let ((evil-state ',state))
+ (evil-normalize-keymaps)
+ (if ',input-method
+ (activate-input-method evil-input-method)
+ ;; BUG #475: Deactivate the current input method only
+ ;; if there is a function to deactivate it, otherwise
+ ;; an error would be raised. This strange situation
+ ;; should not arise in general and there should
+ ;; probably be a better way to handle this situation.
+ (if deactivate-current-input-method-function
+ (deactivate-input-method)))
+ (unless evil-no-display
+ (evil-refresh-cursor ',state)
+ (evil-refresh-mode-line ',state)
+ (when (called-interactively-p 'any)
+ (redisplay)))
+ ,@body
+ (run-hooks ',entry-hook)
+ (when (and evil-echo-state
+ arg (not evil-no-display) ,message)
+ (if (functionp ,message)
+ (funcall ,message)
+ (evil-echo "%s" ,message))))))))
+
+ (evil-set-command-property ',toggle :keep-visual t)
+ (evil-set-command-property ',toggle :suppress-operator t)
+
+ (evil-define-keymap ,keymap nil
+ :mode ,mode
+ :func nil)
+
+ (evil-define-keymap ,local-keymap nil
+ :mode ,local
+ :local t
+ :func nil)
+
+ ',state)))
+
+(provide 'evil-core)
+
+;;; evil-core.el ends here
diff --git a/elpa/evil-20220503.1314/evil-core.elc b/elpa/evil-20220503.1314/evil-core.elc
new file mode 100644
index 0000000..7f3b55c
--- /dev/null
+++ b/elpa/evil-20220503.1314/evil-core.elc
Binary files differ
diff --git a/elpa/evil-20220503.1314/evil-development.el b/elpa/evil-20220503.1314/evil-development.el
new file mode 100644
index 0000000..60da92d
--- /dev/null
+++ b/elpa/evil-20220503.1314/evil-development.el
@@ -0,0 +1,50 @@
+;;; evil-development.el --- Useful features for Evil developers -*- lexical-binding: t -*-
+
+;; Author: Justin Burkett <justin at burkett dot cc>
+
+;; Version: 1.15.0
+
+;;
+;; This file is NOT part of GNU Emacs.
+
+;;; License:
+
+;; This file is part of Evil.
+;;
+;; Evil 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.
+;;
+;; Evil 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 Evil. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Code:
+
+;;; Teach imenu about evil macros
+
+(with-eval-after-load 'lisp-mode
+ (when (boundp 'lisp-imenu-generic-expression)
+ (dolist (macro '("interactive-code"
+ "type"
+ "text-object"
+ "motion"
+ "command"
+ "operator"))
+ (let ((macro-name (format "evil-%s" macro)))
+ (unless (assoc macro-name lisp-imenu-generic-expression)
+ (push (list
+ macro-name
+ (format "^\\s-*(evil-define-%s\\s-+\\(\\(?:\\sw\\|\\s_\\|\\\\.\\)+\\)"
+ macro)
+ 1)
+ lisp-imenu-generic-expression))))))
+
+(provide 'evil-development)
+
+;;; evil-development.el ends here
diff --git a/elpa/evil-20220503.1314/evil-development.elc b/elpa/evil-20220503.1314/evil-development.elc
new file mode 100644
index 0000000..0e5ed7a
--- /dev/null
+++ b/elpa/evil-20220503.1314/evil-development.elc
Binary files differ
diff --git a/elpa/evil-20220503.1314/evil-digraphs.el b/elpa/evil-20220503.1314/evil-digraphs.el
new file mode 100644
index 0000000..9baef3d
--- /dev/null
+++ b/elpa/evil-20220503.1314/evil-digraphs.el
@@ -0,0 +1,1729 @@
+;;; evil-digraphs.el --- Digraphs -*- lexical-binding: t -*-
+
+;; Author: Vegard Øye <vegard_oye at hotmail.com>
+;; Maintainer: Vegard Øye <vegard_oye at hotmail.com>
+
+;; Version: 1.15.0
+
+;;
+;; This file is NOT part of GNU Emacs.
+
+;;; License:
+
+;; This file is part of Evil.
+;;
+;; Evil 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.
+;;
+;; Evil 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 Evil. If not, see <http://www.gnu.org/licenses/>.
+
+(require 'evil-vars)
+
+;;; Code:
+
+(defgroup evil-digraphs nil
+ "Digraph support based on RFC 1345."
+ :group 'evil
+ :prefix "evil-digraph-")
+
+(defcustom evil-digraphs-table-user nil
+ "List of user-defined digraphs.
+Entries have the form ((?CHAR1 ?CHAR2) . ?DIGRAPH). That is,
+a cons cell of the digraph and its character replacement,
+where the digraph is a list of two characters.
+See also `evil-digraphs-table'."
+ :type '(alist :key-type (list character character)
+ :value-type character)
+ :require 'evil-digraphs
+ :group 'evil-digraphs)
+
+(defconst evil-digraphs-table
+ '(((?N ?U) . ?\x00)
+ ((?S ?H) . ?\x01)
+ ((?S ?X) . ?\x02)
+ ((?E ?X) . ?\x03)
+ ((?E ?T) . ?\x04)
+ ((?E ?Q) . ?\x05)
+ ((?A ?K) . ?\x06)
+ ((?B ?L) . ?\x07)
+ ((?B ?S) . ?\x08)
+ ((?H ?T) . ?\x09)
+ ((?L ?F) . ?\x0a)
+ ((?V ?T) . ?\x0b)
+ ((?F ?F) . ?\x0c)
+ ((?C ?R) . ?\x0d)
+ ((?S ?O) . ?\x0e)
+ ((?S ?I) . ?\x0f)
+ ((?D ?L) . ?\x10)
+ ((?D ?1) . ?\x11)
+ ((?D ?2) . ?\x12)
+ ((?D ?3) . ?\x13)
+ ((?D ?4) . ?\x14)
+ ((?N ?K) . ?\x15)
+ ((?S ?Y) . ?\x16)
+ ((?E ?B) . ?\x17)
+ ((?C ?N) . ?\x18)
+ ((?E ?M) . ?\x19)
+ ((?S ?B) . ?\x1a)
+ ((?E ?C) . ?\x1b)
+ ((?F ?S) . ?\x1c)
+ ((?G ?S) . ?\x1d)
+ ((?R ?S) . ?\x1e)
+ ((?U ?S) . ?\x1f)
+ ((?S ?P) . ?\x20)
+ ((?N ?b) . ?\x23)
+ ((?D ?O) . ?\x24)
+ ((?A ?t) . ?\x40)
+ ((?< ?\() . ?\x5b)
+ ((?/ ?/) . ?\x5c)
+ ((?\) ?>) . ?\x5d)
+ ((?' ?>) . ?\x5e)
+ ((?' ?!) . ?\x60)
+ ((?\( ?!) . ?\x7b)
+ ((?! ?!) . ?\x7c)
+ ((?! ?\)) . ?\x7d)
+ ((?' ??) . ?\x7e)
+ ((?D ?T) . ?\x7f)
+ ((?P ?A) . ?\x80)
+ ((?H ?O) . ?\x81)
+ ((?B ?H) . ?\x82)
+ ((?N ?H) . ?\x83)
+ ((?I ?N) . ?\x84)
+ ((?N ?L) . ?\x85)
+ ((?S ?A) . ?\x86)
+ ((?E ?S) . ?\x87)
+ ((?H ?S) . ?\x88)
+ ((?H ?J) . ?\x89)
+ ((?V ?S) . ?\x8a)
+ ((?P ?D) . ?\x8b)
+ ((?P ?U) . ?\x8c)
+ ((?R ?I) . ?\x8d)
+ ((?S ?2) . ?\x8e)
+ ((?S ?3) . ?\x8f)
+ ((?D ?C) . ?\x90)
+ ((?P ?1) . ?\x91)
+ ((?P ?2) . ?\x92)
+ ((?T ?S) . ?\x93)
+ ((?C ?C) . ?\x94)
+ ((?M ?W) . ?\x95)
+ ((?S ?G) . ?\x96)
+ ((?E ?G) . ?\x97)
+ ((?S ?S) . ?\x98)
+ ((?G ?C) . ?\x99)
+ ((?S ?C) . ?\x9a)
+ ((?C ?I) . ?\x9b)
+ ((?S ?T) . ?\x9c)
+ ((?O ?C) . ?\x9d)
+ ((?P ?M) . ?\x9e)
+ ((?A ?C) . ?\x9f)
+ ((?N ?S) . ?\xa0)
+ ((?! ?I) . ?\xa1)
+ ((?C ?t) . ?\xa2)
+ ((?P ?d) . ?\xa3)
+ ((?C ?u) . ?\xa4)
+ ((?Y ?e) . ?\xa5)
+ ((?B ?B) . ?\xa6)
+ ((?S ?E) . ?\xa7)
+ ((?' ?:) . ?\xa8)
+ ((?C ?o) . ?\xa9)
+ ((?- ?a) . ?\xaa)
+ ((?< ?<) . ?\xab)
+ ((?N ?O) . ?\xac)
+ ((?- ?-) . ?\xad)
+ ((?R ?g) . ?\xae)
+ ((?' ?m) . ?\xaf)
+ ((?D ?G) . ?\xb0)
+ ((?+ ?-) . ?\xb1)
+ ((?2 ?S) . ?\xb2)
+ ((?3 ?S) . ?\xb3)
+ ((?' ?') . ?\xb4)
+ ((?M ?y) . ?\xb5)
+ ((?P ?I) . ?\xb6)
+ ((?. ?M) . ?\xb7)
+ ((?' ?,) . ?\xb8)
+ ((?1 ?S) . ?\xb9)
+ ((?- ?o) . ?\xba)
+ ((?> ?>) . ?\xbb)
+ ((?1 ?4) . ?\xbc)
+ ((?1 ?2) . ?\xbd)
+ ((?3 ?4) . ?\xbe)
+ ((?? ?I) . ?\xbf)
+ ((?A ?!) . ?\xc0)
+ ((?A ?') . ?\xc1)
+ ((?A ?>) . ?\xc2)
+ ((?A ??) . ?\xc3)
+ ((?A ?:) . ?\xc4)
+ ((?A ?A) . ?\xc5)
+ ((?A ?E) . ?\xc6)
+ ((?C ?,) . ?\xc7)
+ ((?E ?!) . ?\xc8)
+ ((?E ?') . ?\xc9)
+ ((?E ?>) . ?\xca)
+ ((?E ?:) . ?\xcb)
+ ((?I ?!) . ?\xcc)
+ ((?I ?') . ?\xcd)
+ ((?I ?>) . ?\xce)
+ ((?I ?:) . ?\xcf)
+ ((?D ?-) . ?\xd0)
+ ((?N ??) . ?\xd1)
+ ((?O ?!) . ?\xd2)
+ ((?O ?') . ?\xd3)
+ ((?O ?>) . ?\xd4)
+ ((?O ??) . ?\xd5)
+ ((?O ?:) . ?\xd6)
+ ((?* ?X) . ?\xd7)
+ ((?O ?/) . ?\xd8)
+ ((?U ?!) . ?\xd9)
+ ((?U ?') . ?\xda)
+ ((?U ?>) . ?\xdb)
+ ((?U ?:) . ?\xdc)
+ ((?Y ?') . ?\xdd)
+ ((?T ?H) . ?\xde)
+ ((?s ?s) . ?\xdf)
+ ((?a ?!) . ?\xe0)
+ ((?a ?') . ?\xe1)
+ ((?a ?>) . ?\xe2)
+ ((?a ??) . ?\xe3)
+ ((?a ?:) . ?\xe4)
+ ((?a ?a) . ?\xe5)
+ ((?a ?e) . ?\xe6)
+ ((?c ?,) . ?\xe7)
+ ((?e ?!) . ?\xe8)
+ ((?e ?') . ?\xe9)
+ ((?e ?>) . ?\xea)
+ ((?e ?:) . ?\xeb)
+ ((?i ?!) . ?\xec)
+ ((?i ?') . ?\xed)
+ ((?i ?>) . ?\xee)
+ ((?i ?:) . ?\xef)
+ ((?d ?-) . ?\xf0)
+ ((?n ??) . ?\xf1)
+ ((?o ?!) . ?\xf2)
+ ((?o ?') . ?\xf3)
+ ((?o ?>) . ?\xf4)
+ ((?o ??) . ?\xf5)
+ ((?o ?:) . ?\xf6)
+ ((?- ?:) . ?\xf7)
+ ((?o ?/) . ?\xf8)
+ ((?u ?!) . ?\xf9)
+ ((?u ?') . ?\xfa)
+ ((?u ?>) . ?\xfb)
+ ((?u ?:) . ?\xfc)
+ ((?y ?') . ?\xfd)
+ ((?t ?h) . ?\xfe)
+ ((?y ?:) . ?\xff)
+ ((?A ?-) . ?\x0100)
+ ((?a ?-) . ?\x0101)
+ ((?A ?\() . ?\x0102)
+ ((?a ?\() . ?\x0103)
+ ((?A ?\;) . ?\x0104)
+ ((?a ?\;) . ?\x0105)
+ ((?C ?') . ?\x0106)
+ ((?c ?') . ?\x0107)
+ ((?C ?>) . ?\x0108)
+ ((?c ?>) . ?\x0109)
+ ((?C ?.) . ?\x010a)
+ ((?c ?.) . ?\x010b)
+ ((?C ?<) . ?\x010c)
+ ((?c ?<) . ?\x010d)
+ ((?D ?<) . ?\x010e)
+ ((?d ?<) . ?\x010f)
+ ((?D ?/) . ?\x0110)
+ ((?d ?/) . ?\x0111)
+ ((?E ?-) . ?\x0112)
+ ((?e ?-) . ?\x0113)
+ ((?E ?\() . ?\x0114)
+ ((?e ?\() . ?\x0115)
+ ((?E ?.) . ?\x0116)
+ ((?e ?.) . ?\x0117)
+ ((?E ?\;) . ?\x0118)
+ ((?e ?\;) . ?\x0119)
+ ((?E ?<) . ?\x011a)
+ ((?e ?<) . ?\x011b)
+ ((?G ?>) . ?\x011c)
+ ((?g ?>) . ?\x011d)
+ ((?G ?\() . ?\x011e)
+ ((?g ?\() . ?\x011f)
+ ((?G ?.) . ?\x0120)
+ ((?g ?.) . ?\x0121)
+ ((?G ?,) . ?\x0122)
+ ((?g ?,) . ?\x0123)
+ ((?H ?>) . ?\x0124)
+ ((?h ?>) . ?\x0125)
+ ((?H ?/) . ?\x0126)
+ ((?h ?/) . ?\x0127)
+ ((?I ??) . ?\x0128)
+ ((?i ??) . ?\x0129)
+ ((?I ?-) . ?\x012a)
+ ((?i ?-) . ?\x012b)
+ ((?I ?\() . ?\x012c)
+ ((?i ?\() . ?\x012d)
+ ((?I ?\;) . ?\x012e)
+ ((?i ?\;) . ?\x012f)
+ ((?I ?.) . ?\x0130)
+ ((?i ?.) . ?\x0131)
+ ((?I ?J) . ?\x0132)
+ ((?i ?j) . ?\x0133)
+ ((?J ?>) . ?\x0134)
+ ((?j ?>) . ?\x0135)
+ ((?K ?,) . ?\x0136)
+ ((?k ?,) . ?\x0137)
+ ((?k ?k) . ?\x0138)
+ ((?L ?') . ?\x0139)
+ ((?l ?') . ?\x013a)
+ ((?L ?,) . ?\x013b)
+ ((?l ?,) . ?\x013c)
+ ((?L ?<) . ?\x013d)
+ ((?l ?<) . ?\x013e)
+ ((?L ?.) . ?\x013f)
+ ((?l ?.) . ?\x0140)
+ ((?L ?/) . ?\x0141)
+ ((?l ?/) . ?\x0142)
+ ((?N ?') . ?\x0143)
+ ((?n ?') . ?\x0144)
+ ((?N ?,) . ?\x0145)
+ ((?n ?,) . ?\x0146)
+ ((?N ?<) . ?\x0147)
+ ((?n ?<) . ?\x0148)
+ ((?' ?n) . ?\x0149)
+ ((?N ?G) . ?\x014a)
+ ((?n ?g) . ?\x014b)
+ ((?O ?-) . ?\x014c)
+ ((?o ?-) . ?\x014d)
+ ((?O ?\() . ?\x014e)
+ ((?o ?\() . ?\x014f)
+ ((?O ?\") . ?\x0150)
+ ((?o ?\") . ?\x0151)
+ ((?O ?E) . ?\x0152)
+ ((?o ?e) . ?\x0153)
+ ((?R ?') . ?\x0154)
+ ((?r ?') . ?\x0155)
+ ((?R ?,) . ?\x0156)
+ ((?r ?,) . ?\x0157)
+ ((?R ?<) . ?\x0158)
+ ((?r ?<) . ?\x0159)
+ ((?S ?') . ?\x015a)
+ ((?s ?') . ?\x015b)
+ ((?S ?>) . ?\x015c)
+ ((?s ?>) . ?\x015d)
+ ((?S ?,) . ?\x015e)
+ ((?s ?,) . ?\x015f)
+ ((?S ?<) . ?\x0160)
+ ((?s ?<) . ?\x0161)
+ ((?T ?,) . ?\x0162)
+ ((?t ?,) . ?\x0163)
+ ((?T ?<) . ?\x0164)
+ ((?t ?<) . ?\x0165)
+ ((?T ?/) . ?\x0166)
+ ((?t ?/) . ?\x0167)
+ ((?U ??) . ?\x0168)
+ ((?u ??) . ?\x0169)
+ ((?U ?-) . ?\x016a)
+ ((?u ?-) . ?\x016b)
+ ((?U ?\() . ?\x016c)
+ ((?u ?\() . ?\x016d)
+ ((?U ?0) . ?\x016e)
+ ((?u ?0) . ?\x016f)
+ ((?U ?\") . ?\x0170)
+ ((?u ?\") . ?\x0171)
+ ((?U ?\;) . ?\x0172)
+ ((?u ?\;) . ?\x0173)
+ ((?W ?>) . ?\x0174)
+ ((?w ?>) . ?\x0175)
+ ((?Y ?>) . ?\x0176)
+ ((?y ?>) . ?\x0177)
+ ((?Y ?:) . ?\x0178)
+ ((?Z ?') . ?\x0179)
+ ((?z ?') . ?\x017a)
+ ((?Z ?.) . ?\x017b)
+ ((?z ?.) . ?\x017c)
+ ((?Z ?<) . ?\x017d)
+ ((?z ?<) . ?\x017e)
+ ((?O ?9) . ?\x01a0)
+ ((?o ?9) . ?\x01a1)
+ ((?O ?I) . ?\x01a2)
+ ((?o ?i) . ?\x01a3)
+ ((?y ?r) . ?\x01a6)
+ ((?U ?9) . ?\x01af)
+ ((?u ?9) . ?\x01b0)
+ ((?Z ?/) . ?\x01b5)
+ ((?z ?/) . ?\x01b6)
+ ((?E ?D) . ?\x01b7)
+ ((?A ?<) . ?\x01cd)
+ ((?a ?<) . ?\x01ce)
+ ((?I ?<) . ?\x01cf)
+ ((?i ?<) . ?\x01d0)
+ ((?O ?<) . ?\x01d1)
+ ((?o ?<) . ?\x01d2)
+ ((?U ?<) . ?\x01d3)
+ ((?u ?<) . ?\x01d4)
+ ((?A ?1) . ?\x01de)
+ ((?a ?1) . ?\x01df)
+ ((?A ?7) . ?\x01e0)
+ ((?a ?7) . ?\x01e1)
+ ((?A ?3) . ?\x01e2)
+ ((?a ?3) . ?\x01e3)
+ ((?G ?/) . ?\x01e4)
+ ((?g ?/) . ?\x01e5)
+ ((?G ?<) . ?\x01e6)
+ ((?g ?<) . ?\x01e7)
+ ((?K ?<) . ?\x01e8)
+ ((?k ?<) . ?\x01e9)
+ ((?O ?\;) . ?\x01ea)
+ ((?o ?\;) . ?\x01eb)
+ ((?O ?1) . ?\x01ec)
+ ((?o ?1) . ?\x01ed)
+ ((?E ?Z) . ?\x01ee)
+ ((?e ?z) . ?\x01ef)
+ ((?j ?<) . ?\x01f0)
+ ((?G ?') . ?\x01f4)
+ ((?g ?') . ?\x01f5)
+ ((?\; ?S) . ?\x02bf)
+ ((?' ?<) . ?\x02c7)
+ ((?' ?\() . ?\x02d8)
+ ((?' ?.) . ?\x02d9)
+ ((?' ?0) . ?\x02da)
+ ((?' ?\;) . ?\x02db)
+ ((?' ?\") . ?\x02dd)
+ ((?A ?%) . ?\x0386)
+ ((?E ?%) . ?\x0388)
+ ((?Y ?%) . ?\x0389)
+ ((?I ?%) . ?\x038a)
+ ((?O ?%) . ?\x038c)
+ ((?U ?%) . ?\x038e)
+ ((?W ?%) . ?\x038f)
+ ((?i ?3) . ?\x0390)
+ ((?A ?*) . ?\x0391)
+ ((?B ?*) . ?\x0392)
+ ((?G ?*) . ?\x0393)
+ ((?D ?*) . ?\x0394)
+ ((?E ?*) . ?\x0395)
+ ((?Z ?*) . ?\x0396)
+ ((?Y ?*) . ?\x0397)
+ ((?H ?*) . ?\x0398)
+ ((?I ?*) . ?\x0399)
+ ((?K ?*) . ?\x039a)
+ ((?L ?*) . ?\x039b)
+ ((?M ?*) . ?\x039c)
+ ((?N ?*) . ?\x039d)
+ ((?C ?*) . ?\x039e)
+ ((?O ?*) . ?\x039f)
+ ((?P ?*) . ?\x03a0)
+ ((?R ?*) . ?\x03a1)
+ ((?S ?*) . ?\x03a3)
+ ((?T ?*) . ?\x03a4)
+ ((?U ?*) . ?\x03a5)
+ ((?F ?*) . ?\x03a6)
+ ((?X ?*) . ?\x03a7)
+ ((?Q ?*) . ?\x03a8)
+ ((?W ?*) . ?\x03a9)
+ ((?J ?*) . ?\x03aa)
+ ((?V ?*) . ?\x03ab)
+ ((?a ?%) . ?\x03ac)
+ ((?e ?%) . ?\x03ad)
+ ((?y ?%) . ?\x03ae)
+ ((?i ?%) . ?\x03af)
+ ((?u ?3) . ?\x03b0)
+ ((?a ?*) . ?\x03b1)
+ ((?b ?*) . ?\x03b2)
+ ((?g ?*) . ?\x03b3)
+ ((?d ?*) . ?\x03b4)
+ ((?e ?*) . ?\x03b5)
+ ((?z ?*) . ?\x03b6)
+ ((?y ?*) . ?\x03b7)
+ ((?h ?*) . ?\x03b8)
+ ((?i ?*) . ?\x03b9)
+ ((?k ?*) . ?\x03ba)
+ ((?l ?*) . ?\x03bb)
+ ((?m ?*) . ?\x03bc)
+ ((?n ?*) . ?\x03bd)
+ ((?c ?*) . ?\x03be)
+ ((?o ?*) . ?\x03bf)
+ ((?p ?*) . ?\x03c0)
+ ((?r ?*) . ?\x03c1)
+ ((?* ?s) . ?\x03c2)
+ ((?s ?*) . ?\x03c3)
+ ((?t ?*) . ?\x03c4)
+ ((?u ?*) . ?\x03c5)
+ ((?f ?*) . ?\x03c6)
+ ((?x ?*) . ?\x03c7)
+ ((?q ?*) . ?\x03c8)
+ ((?w ?*) . ?\x03c9)
+ ((?j ?*) . ?\x03ca)
+ ((?v ?*) . ?\x03cb)
+ ((?o ?%) . ?\x03cc)
+ ((?u ?%) . ?\x03cd)
+ ((?w ?%) . ?\x03ce)
+ ((?' ?G) . ?\x03d8)
+ ((?, ?G) . ?\x03d9)
+ ((?T ?3) . ?\x03da)
+ ((?t ?3) . ?\x03db)
+ ((?M ?3) . ?\x03dc)
+ ((?m ?3) . ?\x03dd)
+ ((?K ?3) . ?\x03de)
+ ((?k ?3) . ?\x03df)
+ ((?P ?3) . ?\x03e0)
+ ((?p ?3) . ?\x03e1)
+ ((?' ?%) . ?\x03f4)
+ ((?j ?3) . ?\x03f5)
+ ((?I ?O) . ?\x0401)
+ ((?D ?%) . ?\x0402)
+ ((?G ?%) . ?\x0403)
+ ((?I ?E) . ?\x0404)
+ ((?D ?S) . ?\x0405)
+ ((?I ?I) . ?\x0406)
+ ((?Y ?I) . ?\x0407)
+ ((?J ?%) . ?\x0408)
+ ((?L ?J) . ?\x0409)
+ ((?N ?J) . ?\x040a)
+ ((?T ?s) . ?\x040b)
+ ((?K ?J) . ?\x040c)
+ ((?V ?%) . ?\x040e)
+ ((?D ?Z) . ?\x040f)
+ ((?A ?=) . ?\x0410)
+ ((?B ?=) . ?\x0411)
+ ((?V ?=) . ?\x0412)
+ ((?G ?=) . ?\x0413)
+ ((?D ?=) . ?\x0414)
+ ((?E ?=) . ?\x0415)
+ ((?Z ?%) . ?\x0416)
+ ((?Z ?=) . ?\x0417)
+ ((?I ?=) . ?\x0418)
+ ((?J ?=) . ?\x0419)
+ ((?K ?=) . ?\x041a)
+ ((?L ?=) . ?\x041b)
+ ((?M ?=) . ?\x041c)
+ ((?N ?=) . ?\x041d)
+ ((?O ?=) . ?\x041e)
+ ((?P ?=) . ?\x041f)
+ ((?R ?=) . ?\x0420)
+ ((?S ?=) . ?\x0421)
+ ((?T ?=) . ?\x0422)
+ ((?U ?=) . ?\x0423)
+ ((?F ?=) . ?\x0424)
+ ((?H ?=) . ?\x0425)
+ ((?C ?=) . ?\x0426)
+ ((?C ?%) . ?\x0427)
+ ((?S ?%) . ?\x0428)
+ ((?S ?c) . ?\x0429)
+ ((?= ?\") . ?\x042a)
+ ((?Y ?=) . ?\x042b)
+ ((?% ?\") . ?\x042c)
+ ((?J ?E) . ?\x042d)
+ ((?J ?U) . ?\x042e)
+ ((?J ?A) . ?\x042f)
+ ((?a ?=) . ?\x0430)
+ ((?b ?=) . ?\x0431)
+ ((?v ?=) . ?\x0432)
+ ((?g ?=) . ?\x0433)
+ ((?d ?=) . ?\x0434)
+ ((?e ?=) . ?\x0435)
+ ((?z ?%) . ?\x0436)
+ ((?z ?=) . ?\x0437)
+ ((?i ?=) . ?\x0438)
+ ((?j ?=) . ?\x0439)
+ ((?k ?=) . ?\x043a)
+ ((?l ?=) . ?\x043b)
+ ((?m ?=) . ?\x043c)
+ ((?n ?=) . ?\x043d)
+ ((?o ?=) . ?\x043e)
+ ((?p ?=) . ?\x043f)
+ ((?r ?=) . ?\x0440)
+ ((?s ?=) . ?\x0441)
+ ((?t ?=) . ?\x0442)
+ ((?u ?=) . ?\x0443)
+ ((?f ?=) . ?\x0444)
+ ((?h ?=) . ?\x0445)
+ ((?c ?=) . ?\x0446)
+ ((?c ?%) . ?\x0447)
+ ((?s ?%) . ?\x0448)
+ ((?s ?c) . ?\x0449)
+ ((?= ?') . ?\x044a)
+ ((?y ?=) . ?\x044b)
+ ((?% ?') . ?\x044c)
+ ((?j ?e) . ?\x044d)
+ ((?j ?u) . ?\x044e)
+ ((?j ?a) . ?\x044f)
+ ((?i ?o) . ?\x0451)
+ ((?d ?%) . ?\x0452)
+ ((?g ?%) . ?\x0453)
+ ((?i ?e) . ?\x0454)
+ ((?d ?s) . ?\x0455)
+ ((?i ?i) . ?\x0456)
+ ((?y ?i) . ?\x0457)
+ ((?j ?%) . ?\x0458)
+ ((?l ?j) . ?\x0459)
+ ((?n ?j) . ?\x045a)
+ ((?t ?s) . ?\x045b)
+ ((?k ?j) . ?\x045c)
+ ((?v ?%) . ?\x045e)
+ ((?d ?z) . ?\x045f)
+ ((?Y ?3) . ?\x0462)
+ ((?y ?3) . ?\x0463)
+ ((?O ?3) . ?\x046a)
+ ((?o ?3) . ?\x046b)
+ ((?F ?3) . ?\x0472)
+ ((?f ?3) . ?\x0473)
+ ((?V ?3) . ?\x0474)
+ ((?v ?3) . ?\x0475)
+ ((?C ?3) . ?\x0480)
+ ((?c ?3) . ?\x0481)
+ ((?G ?3) . ?\x0490)
+ ((?g ?3) . ?\x0491)
+ ((?A ?+) . ?\x05d0)
+ ((?B ?+) . ?\x05d1)
+ ((?G ?+) . ?\x05d2)
+ ((?D ?+) . ?\x05d3)
+ ((?H ?+) . ?\x05d4)
+ ((?W ?+) . ?\x05d5)
+ ((?Z ?+) . ?\x05d6)
+ ((?X ?+) . ?\x05d7)
+ ((?T ?j) . ?\x05d8)
+ ((?J ?+) . ?\x05d9)
+ ((?K ?%) . ?\x05da)
+ ((?K ?+) . ?\x05db)
+ ((?L ?+) . ?\x05dc)
+ ((?M ?%) . ?\x05dd)
+ ((?M ?+) . ?\x05de)
+ ((?N ?%) . ?\x05df)
+ ((?N ?+) . ?\x05e0)
+ ((?S ?+) . ?\x05e1)
+ ((?E ?+) . ?\x05e2)
+ ((?P ?%) . ?\x05e3)
+ ((?P ?+) . ?\x05e4)
+ ((?Z ?j) . ?\x05e5)
+ ((?Z ?J) . ?\x05e6)
+ ((?Q ?+) . ?\x05e7)
+ ((?R ?+) . ?\x05e8)
+ ((?S ?h) . ?\x05e9)
+ ((?T ?+) . ?\x05ea)
+ ((?, ?+) . ?\x060c)
+ ((?\; ?+) . ?\x061b)
+ ((?? ?+) . ?\x061f)
+ ((?H ?') . ?\x0621)
+ ((?a ?M) . ?\x0622)
+ ((?a ?H) . ?\x0623)
+ ((?w ?H) . ?\x0624)
+ ((?a ?h) . ?\x0625)
+ ((?y ?H) . ?\x0626)
+ ((?a ?+) . ?\x0627)
+ ((?b ?+) . ?\x0628)
+ ((?t ?m) . ?\x0629)
+ ((?t ?+) . ?\x062a)
+ ((?t ?k) . ?\x062b)
+ ((?g ?+) . ?\x062c)
+ ((?h ?k) . ?\x062d)
+ ((?x ?+) . ?\x062e)
+ ((?d ?+) . ?\x062f)
+ ((?d ?k) . ?\x0630)
+ ((?r ?+) . ?\x0631)
+ ((?z ?+) . ?\x0632)
+ ((?s ?+) . ?\x0633)
+ ((?s ?n) . ?\x0634)
+ ((?c ?+) . ?\x0635)
+ ((?d ?d) . ?\x0636)
+ ((?t ?j) . ?\x0637)
+ ((?z ?H) . ?\x0638)
+ ((?e ?+) . ?\x0639)
+ ((?i ?+) . ?\x063a)
+ ((?+ ?+) . ?\x0640)
+ ((?f ?+) . ?\x0641)
+ ((?q ?+) . ?\x0642)
+ ((?k ?+) . ?\x0643)
+ ((?l ?+) . ?\x0644)
+ ((?m ?+) . ?\x0645)
+ ((?n ?+) . ?\x0646)
+ ((?h ?+) . ?\x0647)
+ ((?w ?+) . ?\x0648)
+ ((?j ?+) . ?\x0649)
+ ((?y ?+) . ?\x064a)
+ ((?: ?+) . ?\x064b)
+ ((?\" ?+) . ?\x064c)
+ ((?= ?+) . ?\x064d)
+ ((?/ ?+) . ?\x064e)
+ ((?' ?+) . ?\x064f)
+ ((?1 ?+) . ?\x0650)
+ ((?3 ?+) . ?\x0651)
+ ((?0 ?+) . ?\x0652)
+ ((?a ?S) . ?\x0670)
+ ((?p ?+) . ?\x067e)
+ ((?v ?+) . ?\x06a4)
+ ((?g ?f) . ?\x06af)
+ ((?0 ?a) . ?\x06f0)
+ ((?1 ?a) . ?\x06f1)
+ ((?2 ?a) . ?\x06f2)
+ ((?3 ?a) . ?\x06f3)
+ ((?4 ?a) . ?\x06f4)
+ ((?5 ?a) . ?\x06f5)
+ ((?6 ?a) . ?\x06f6)
+ ((?7 ?a) . ?\x06f7)
+ ((?8 ?a) . ?\x06f8)
+ ((?9 ?a) . ?\x06f9)
+ ((?B ?.) . ?\x1e02)
+ ((?b ?.) . ?\x1e03)
+ ((?B ?_) . ?\x1e06)
+ ((?b ?_) . ?\x1e07)
+ ((?D ?.) . ?\x1e0a)
+ ((?d ?.) . ?\x1e0b)
+ ((?D ?_) . ?\x1e0e)
+ ((?d ?_) . ?\x1e0f)
+ ((?D ?,) . ?\x1e10)
+ ((?d ?,) . ?\x1e11)
+ ((?F ?.) . ?\x1e1e)
+ ((?f ?.) . ?\x1e1f)
+ ((?G ?-) . ?\x1e20)
+ ((?g ?-) . ?\x1e21)
+ ((?H ?.) . ?\x1e22)
+ ((?h ?.) . ?\x1e23)
+ ((?H ?:) . ?\x1e26)
+ ((?h ?:) . ?\x1e27)
+ ((?H ?,) . ?\x1e28)
+ ((?h ?,) . ?\x1e29)
+ ((?K ?') . ?\x1e30)
+ ((?k ?') . ?\x1e31)
+ ((?K ?_) . ?\x1e34)
+ ((?k ?_) . ?\x1e35)
+ ((?L ?_) . ?\x1e3a)
+ ((?l ?_) . ?\x1e3b)
+ ((?M ?') . ?\x1e3e)
+ ((?m ?') . ?\x1e3f)
+ ((?M ?.) . ?\x1e40)
+ ((?m ?.) . ?\x1e41)
+ ((?N ?.) . ?\x1e44)
+ ((?n ?.) . ?\x1e45)
+ ((?N ?_) . ?\x1e48)
+ ((?n ?_) . ?\x1e49)
+ ((?P ?') . ?\x1e54)
+ ((?p ?') . ?\x1e55)
+ ((?P ?.) . ?\x1e56)
+ ((?p ?.) . ?\x1e57)
+ ((?R ?.) . ?\x1e58)
+ ((?r ?.) . ?\x1e59)
+ ((?R ?_) . ?\x1e5e)
+ ((?r ?_) . ?\x1e5f)
+ ((?S ?.) . ?\x1e60)
+ ((?s ?.) . ?\x1e61)
+ ((?T ?.) . ?\x1e6a)
+ ((?t ?.) . ?\x1e6b)
+ ((?T ?_) . ?\x1e6e)
+ ((?t ?_) . ?\x1e6f)
+ ((?V ??) . ?\x1e7c)
+ ((?v ??) . ?\x1e7d)
+ ((?W ?!) . ?\x1e80)
+ ((?w ?!) . ?\x1e81)
+ ((?W ?') . ?\x1e82)
+ ((?w ?') . ?\x1e83)
+ ((?W ?:) . ?\x1e84)
+ ((?w ?:) . ?\x1e85)
+ ((?W ?.) . ?\x1e86)
+ ((?w ?.) . ?\x1e87)
+ ((?X ?.) . ?\x1e8a)
+ ((?x ?.) . ?\x1e8b)
+ ((?X ?:) . ?\x1e8c)
+ ((?x ?:) . ?\x1e8d)
+ ((?Y ?.) . ?\x1e8e)
+ ((?y ?.) . ?\x1e8f)
+ ((?Z ?>) . ?\x1e90)
+ ((?z ?>) . ?\x1e91)
+ ((?Z ?_) . ?\x1e94)
+ ((?z ?_) . ?\x1e95)
+ ((?h ?_) . ?\x1e96)
+ ((?t ?:) . ?\x1e97)
+ ((?w ?0) . ?\x1e98)
+ ((?y ?0) . ?\x1e99)
+ ((?A ?2) . ?\x1ea2)
+ ((?a ?2) . ?\x1ea3)
+ ((?E ?2) . ?\x1eba)
+ ((?e ?2) . ?\x1ebb)
+ ((?E ??) . ?\x1ebc)
+ ((?e ??) . ?\x1ebd)
+ ((?I ?2) . ?\x1ec8)
+ ((?i ?2) . ?\x1ec9)
+ ((?O ?2) . ?\x1ece)
+ ((?o ?2) . ?\x1ecf)
+ ((?U ?2) . ?\x1ee6)
+ ((?u ?2) . ?\x1ee7)
+ ((?Y ?!) . ?\x1ef2)
+ ((?y ?!) . ?\x1ef3)
+ ((?Y ?2) . ?\x1ef6)
+ ((?y ?2) . ?\x1ef7)
+ ((?Y ??) . ?\x1ef8)
+ ((?y ??) . ?\x1ef9)
+ ((?\; ?') . ?\x1f00)
+ ((?, ?') . ?\x1f01)
+ ((?\; ?!) . ?\x1f02)
+ ((?, ?!) . ?\x1f03)
+ ((?? ?\;) . ?\x1f04)
+ ((?? ?,) . ?\x1f05)
+ ((?! ?:) . ?\x1f06)
+ ((?? ?:) . ?\x1f07)
+ ((?1 ?N) . ?\x2002)
+ ((?1 ?M) . ?\x2003)
+ ((?3 ?M) . ?\x2004)
+ ((?4 ?M) . ?\x2005)
+ ((?6 ?M) . ?\x2006)
+ ((?1 ?T) . ?\x2009)
+ ((?1 ?H) . ?\x200a)
+ ((?- ?1) . ?\x2010)
+ ((?- ?N) . ?\x2013)
+ ((?- ?M) . ?\x2014)
+ ((?- ?3) . ?\x2015)
+ ((?! ?2) . ?\x2016)
+ ((?= ?2) . ?\x2017)
+ ((?' ?6) . ?\x2018)
+ ((?' ?9) . ?\x2019)
+ ((?. ?9) . ?\x201a)
+ ((?9 ?') . ?\x201b)
+ ((?\" ?6) . ?\x201c)
+ ((?\" ?9) . ?\x201d)
+ ((?: ?9) . ?\x201e)
+ ((?9 ?\") . ?\x201f)
+ ((?/ ?-) . ?\x2020)
+ ((?/ ?=) . ?\x2021)
+ ((?. ?.) . ?\x2025)
+ ((?% ?0) . ?\x2030)
+ ((?1 ?') . ?\x2032)
+ ((?2 ?') . ?\x2033)
+ ((?3 ?') . ?\x2034)
+ ((?1 ?\") . ?\x2035)
+ ((?2 ?\") . ?\x2036)
+ ((?3 ?\") . ?\x2037)
+ ((?C ?a) . ?\x2038)
+ ((?< ?1) . ?\x2039)
+ ((?> ?1) . ?\x203a)
+ ((?: ?X) . ?\x203b)
+ ((?' ?-) . ?\x203e)
+ ((?/ ?f) . ?\x2044)
+ ((?0 ?S) . ?\x2070)
+ ((?4 ?S) . ?\x2074)
+ ((?5 ?S) . ?\x2075)
+ ((?6 ?S) . ?\x2076)
+ ((?7 ?S) . ?\x2077)
+ ((?8 ?S) . ?\x2078)
+ ((?9 ?S) . ?\x2079)
+ ((?+ ?S) . ?\x207a)
+ ((?- ?S) . ?\x207b)
+ ((?= ?S) . ?\x207c)
+ ((?\( ?S) . ?\x207d)
+ ((?\) ?S) . ?\x207e)
+ ((?n ?S) . ?\x207f)
+ ((?0 ?s) . ?\x2080)
+ ((?1 ?s) . ?\x2081)
+ ((?2 ?s) . ?\x2082)
+ ((?3 ?s) . ?\x2083)
+ ((?4 ?s) . ?\x2084)
+ ((?5 ?s) . ?\x2085)
+ ((?6 ?s) . ?\x2086)
+ ((?7 ?s) . ?\x2087)
+ ((?8 ?s) . ?\x2088)
+ ((?9 ?s) . ?\x2089)
+ ((?+ ?s) . ?\x208a)
+ ((?- ?s) . ?\x208b)
+ ((?= ?s) . ?\x208c)
+ ((?\( ?s) . ?\x208d)
+ ((?\) ?s) . ?\x208e)
+ ((?L ?i) . ?\x20a4)
+ ((?P ?t) . ?\x20a7)
+ ((?W ?=) . ?\x20a9)
+ ((?= ?e) . ?\x20ac)
+ ((?E ?u) . ?\x20ac)
+ ((?o ?C) . ?\x2103)
+ ((?c ?o) . ?\x2105)
+ ((?o ?F) . ?\x2109)
+ ((?N ?0) . ?\x2116)
+ ((?P ?O) . ?\x2117)
+ ((?R ?x) . ?\x211e)
+ ((?S ?M) . ?\x2120)
+ ((?T ?M) . ?\x2122)
+ ((?O ?m) . ?\x2126)
+ ((?A ?O) . ?\x212b)
+ ((?1 ?3) . ?\x2153)
+ ((?2 ?3) . ?\x2154)
+ ((?1 ?5) . ?\x2155)
+ ((?2 ?5) . ?\x2156)
+ ((?3 ?5) . ?\x2157)
+ ((?4 ?5) . ?\x2158)
+ ((?1 ?6) . ?\x2159)
+ ((?5 ?6) . ?\x215a)
+ ((?1 ?8) . ?\x215b)
+ ((?3 ?8) . ?\x215c)
+ ((?5 ?8) . ?\x215d)
+ ((?7 ?8) . ?\x215e)
+ ((?1 ?R) . ?\x2160)
+ ((?2 ?R) . ?\x2161)
+ ((?3 ?R) . ?\x2162)
+ ((?4 ?R) . ?\x2163)
+ ((?5 ?R) . ?\x2164)
+ ((?6 ?R) . ?\x2165)
+ ((?7 ?R) . ?\x2166)
+ ((?8 ?R) . ?\x2167)
+ ((?9 ?R) . ?\x2168)
+ ((?a ?R) . ?\x2169)
+ ((?b ?R) . ?\x216a)
+ ((?c ?R) . ?\x216b)
+ ((?1 ?r) . ?\x2170)
+ ((?2 ?r) . ?\x2171)
+ ((?3 ?r) . ?\x2172)
+ ((?4 ?r) . ?\x2173)
+ ((?5 ?r) . ?\x2174)
+ ((?6 ?r) . ?\x2175)
+ ((?7 ?r) . ?\x2176)
+ ((?8 ?r) . ?\x2177)
+ ((?9 ?r) . ?\x2178)
+ ((?a ?r) . ?\x2179)
+ ((?b ?r) . ?\x217a)
+ ((?c ?r) . ?\x217b)
+ ((?< ?-) . ?\x2190)
+ ((?- ?!) . ?\x2191)
+ ((?- ?>) . ?\x2192)
+ ((?- ?v) . ?\x2193)
+ ((?< ?>) . ?\x2194)
+ ((?U ?D) . ?\x2195)
+ ((?< ?=) . ?\x21d0)
+ ((?= ?>) . ?\x21d2)
+ ((?= ?=) . ?\x21d4)
+ ((?F ?A) . ?\x2200)
+ ((?d ?P) . ?\x2202)
+ ((?T ?E) . ?\x2203)
+ ((?/ ?0) . ?\x2205)
+ ((?D ?E) . ?\x2206)
+ ((?N ?B) . ?\x2207)
+ ((?\( ?-) . ?\x2208)
+ ((?- ?\)) . ?\x220b)
+ ((?* ?P) . ?\x220f)
+ ((?+ ?Z) . ?\x2211)
+ ((?- ?2) . ?\x2212)
+ ((?- ?+) . ?\x2213)
+ ((?* ?-) . ?\x2217)
+ ((?O ?b) . ?\x2218)
+ ((?S ?b) . ?\x2219)
+ ((?R ?T) . ?\x221a)
+ ((?0 ?\() . ?\x221d)
+ ((?0 ?0) . ?\x221e)
+ ((?- ?L) . ?\x221f)
+ ((?- ?V) . ?\x2220)
+ ((?P ?P) . ?\x2225)
+ ((?A ?N) . ?\x2227)
+ ((?O ?R) . ?\x2228)
+ ((?\( ?U) . ?\x2229)
+ ((?\) ?U) . ?\x222a)
+ ((?I ?n) . ?\x222b)
+ ((?D ?I) . ?\x222c)
+ ((?I ?o) . ?\x222e)
+ ((?. ?:) . ?\x2234)
+ ((?: ?.) . ?\x2235)
+ ((?: ?R) . ?\x2236)
+ ((?: ?:) . ?\x2237)
+ ((?? ?1) . ?\x223c)
+ ((?C ?G) . ?\x223e)
+ ((?? ?-) . ?\x2243)
+ ((?? ?=) . ?\x2245)
+ ((?? ?2) . ?\x2248)
+ ((?= ??) . ?\x224c)
+ ((?H ?I) . ?\x2253)
+ ((?! ?=) . ?\x2260)
+ ((?= ?3) . ?\x2261)
+ ((?= ?<) . ?\x2264)
+ ((?> ?=) . ?\x2265)
+ ((?< ?*) . ?\x226a)
+ ((?* ?>) . ?\x226b)
+ ((?! ?<) . ?\x226e)
+ ((?! ?>) . ?\x226f)
+ ((?\( ?C) . ?\x2282)
+ ((?\) ?C) . ?\x2283)
+ ((?\( ?_) . ?\x2286)
+ ((?\) ?_) . ?\x2287)
+ ((?0 ?.) . ?\x2299)
+ ((?0 ?2) . ?\x229a)
+ ((?- ?T) . ?\x22a5)
+ ((?. ?P) . ?\x22c5)
+ ((?: ?3) . ?\x22ee)
+ ((?. ?3) . ?\x22ef)
+ ((?E ?h) . ?\x2302)
+ ((?< ?7) . ?\x2308)
+ ((?> ?7) . ?\x2309)
+ ((?7 ?<) . ?\x230a)
+ ((?7 ?>) . ?\x230b)
+ ((?N ?I) . ?\x2310)
+ ((?\( ?A) . ?\x2312)
+ ((?T ?R) . ?\x2315)
+ ((?I ?u) . ?\x2320)
+ ((?I ?l) . ?\x2321)
+ ((?< ?/) . ?\x2329)
+ ((?/ ?>) . ?\x232a)
+ ((?V ?s) . ?\x2423)
+ ((?1 ?h) . ?\x2440)
+ ((?3 ?h) . ?\x2441)
+ ((?2 ?h) . ?\x2442)
+ ((?4 ?h) . ?\x2443)
+ ((?1 ?j) . ?\x2446)
+ ((?2 ?j) . ?\x2447)
+ ((?3 ?j) . ?\x2448)
+ ((?4 ?j) . ?\x2449)
+ ((?1 ?.) . ?\x2488)
+ ((?2 ?.) . ?\x2489)
+ ((?3 ?.) . ?\x248a)
+ ((?4 ?.) . ?\x248b)
+ ((?5 ?.) . ?\x248c)
+ ((?6 ?.) . ?\x248d)
+ ((?7 ?.) . ?\x248e)
+ ((?8 ?.) . ?\x248f)
+ ((?9 ?.) . ?\x2490)
+ ((?h ?h) . ?\x2500)
+ ((?H ?H) . ?\x2501)
+ ((?v ?v) . ?\x2502)
+ ((?V ?V) . ?\x2503)
+ ((?3 ?-) . ?\x2504)
+ ((?3 ?_) . ?\x2505)
+ ((?3 ?!) . ?\x2506)
+ ((?3 ?/) . ?\x2507)
+ ((?4 ?-) . ?\x2508)
+ ((?4 ?_) . ?\x2509)
+ ((?4 ?!) . ?\x250a)
+ ((?4 ?/) . ?\x250b)
+ ((?d ?r) . ?\x250c)
+ ((?d ?R) . ?\x250d)
+ ((?D ?r) . ?\x250e)
+ ((?D ?R) . ?\x250f)
+ ((?d ?l) . ?\x2510)
+ ((?d ?L) . ?\x2511)
+ ((?D ?l) . ?\x2512)
+ ((?L ?D) . ?\x2513)
+ ((?u ?r) . ?\x2514)
+ ((?u ?R) . ?\x2515)
+ ((?U ?r) . ?\x2516)
+ ((?U ?R) . ?\x2517)
+ ((?u ?l) . ?\x2518)
+ ((?u ?L) . ?\x2519)
+ ((?U ?l) . ?\x251a)
+ ((?U ?L) . ?\x251b)
+ ((?v ?r) . ?\x251c)
+ ((?v ?R) . ?\x251d)
+ ((?V ?r) . ?\x2520)
+ ((?V ?R) . ?\x2523)
+ ((?v ?l) . ?\x2524)
+ ((?v ?L) . ?\x2525)
+ ((?V ?l) . ?\x2528)
+ ((?V ?L) . ?\x252b)
+ ((?d ?h) . ?\x252c)
+ ((?d ?H) . ?\x252f)
+ ((?D ?h) . ?\x2530)
+ ((?D ?H) . ?\x2533)
+ ((?u ?h) . ?\x2534)
+ ((?u ?H) . ?\x2537)
+ ((?U ?h) . ?\x2538)
+ ((?U ?H) . ?\x253b)
+ ((?v ?h) . ?\x253c)
+ ((?v ?H) . ?\x253f)
+ ((?V ?h) . ?\x2542)
+ ((?V ?H) . ?\x254b)
+ ((?F ?D) . ?\x2571)
+ ((?B ?D) . ?\x2572)
+ ((?T ?B) . ?\x2580)
+ ((?L ?B) . ?\x2584)
+ ((?F ?B) . ?\x2588)
+ ((?l ?B) . ?\x258c)
+ ((?R ?B) . ?\x2590)
+ ((?. ?S) . ?\x2591)
+ ((?: ?S) . ?\x2592)
+ ((?? ?S) . ?\x2593)
+ ((?f ?S) . ?\x25a0)
+ ((?O ?S) . ?\x25a1)
+ ((?R ?O) . ?\x25a2)
+ ((?R ?r) . ?\x25a3)
+ ((?R ?F) . ?\x25a4)
+ ((?R ?Y) . ?\x25a5)
+ ((?R ?H) . ?\x25a6)
+ ((?R ?Z) . ?\x25a7)
+ ((?R ?K) . ?\x25a8)
+ ((?R ?X) . ?\x25a9)
+ ((?s ?B) . ?\x25aa)
+ ((?S ?R) . ?\x25ac)
+ ((?O ?r) . ?\x25ad)
+ ((?U ?T) . ?\x25b2)
+ ((?u ?T) . ?\x25b3)
+ ((?P ?R) . ?\x25b6)
+ ((?T ?r) . ?\x25b7)
+ ((?D ?t) . ?\x25bc)
+ ((?d ?T) . ?\x25bd)
+ ((?P ?L) . ?\x25c0)
+ ((?T ?l) . ?\x25c1)
+ ((?D ?b) . ?\x25c6)
+ ((?D ?w) . ?\x25c7)
+ ((?L ?Z) . ?\x25ca)
+ ((?0 ?m) . ?\x25cb)
+ ((?0 ?o) . ?\x25ce)
+ ((?0 ?M) . ?\x25cf)
+ ((?0 ?L) . ?\x25d0)
+ ((?0 ?R) . ?\x25d1)
+ ((?S ?n) . ?\x25d8)
+ ((?I ?c) . ?\x25d9)
+ ((?F ?d) . ?\x25e2)
+ ((?B ?d) . ?\x25e3)
+ ((?* ?2) . ?\x2605)
+ ((?* ?1) . ?\x2606)
+ ((?< ?H) . ?\x261c)
+ ((?> ?H) . ?\x261e)
+ ((?0 ?u) . ?\x263a)
+ ((?0 ?U) . ?\x263b)
+ ((?S ?U) . ?\x263c)
+ ((?F ?m) . ?\x2640)
+ ((?M ?l) . ?\x2642)
+ ((?c ?S) . ?\x2660)
+ ((?c ?H) . ?\x2661)
+ ((?c ?D) . ?\x2662)
+ ((?c ?C) . ?\x2663)
+ ((?M ?d) . ?\x2669)
+ ((?M ?8) . ?\x266a)
+ ((?M ?2) . ?\x266b)
+ ((?M ?b) . ?\x266d)
+ ((?M ?x) . ?\x266e)
+ ((?M ?X) . ?\x266f)
+ ((?O ?K) . ?\x2713)
+ ((?X ?X) . ?\x2717)
+ ((?- ?X) . ?\x2720)
+ ((?I ?S) . ?\x3000)
+ ((?, ?_) . ?\x3001)
+ ((?. ?_) . ?\x3002)
+ ((?+ ?\") . ?\x3003)
+ ((?+ ?_) . ?\x3004)
+ ((?* ?_) . ?\x3005)
+ ((?\; ?_) . ?\x3006)
+ ((?0 ?_) . ?\x3007)
+ ((?< ?+) . ?\x300a)
+ ((?> ?+) . ?\x300b)
+ ((?< ?') . ?\x300c)
+ ((?> ?') . ?\x300d)
+ ((?< ?\") . ?\x300e)
+ ((?> ?\") . ?\x300f)
+ ((?\( ?\") . ?\x3010)
+ ((?\) ?\") . ?\x3011)
+ ((?= ?T) . ?\x3012)
+ ((?= ?_) . ?\x3013)
+ ((?\( ?') . ?\x3014)
+ ((?\) ?') . ?\x3015)
+ ((?\( ?I) . ?\x3016)
+ ((?\) ?I) . ?\x3017)
+ ((?- ??) . ?\x301c)
+ ((?A ?5) . ?\x3041)
+ ((?a ?5) . ?\x3042)
+ ((?I ?5) . ?\x3043)
+ ((?i ?5) . ?\x3044)
+ ((?U ?5) . ?\x3045)
+ ((?u ?5) . ?\x3046)
+ ((?E ?5) . ?\x3047)
+ ((?e ?5) . ?\x3048)
+ ((?O ?5) . ?\x3049)
+ ((?o ?5) . ?\x304a)
+ ((?k ?a) . ?\x304b)
+ ((?g ?a) . ?\x304c)
+ ((?k ?i) . ?\x304d)
+ ((?g ?i) . ?\x304e)
+ ((?k ?u) . ?\x304f)
+ ((?g ?u) . ?\x3050)
+ ((?k ?e) . ?\x3051)
+ ((?g ?e) . ?\x3052)
+ ((?k ?o) . ?\x3053)
+ ((?g ?o) . ?\x3054)
+ ((?s ?a) . ?\x3055)
+ ((?z ?a) . ?\x3056)
+ ((?s ?i) . ?\x3057)
+ ((?z ?i) . ?\x3058)
+ ((?s ?u) . ?\x3059)
+ ((?z ?u) . ?\x305a)
+ ((?s ?e) . ?\x305b)
+ ((?z ?e) . ?\x305c)
+ ((?s ?o) . ?\x305d)
+ ((?z ?o) . ?\x305e)
+ ((?t ?a) . ?\x305f)
+ ((?d ?a) . ?\x3060)
+ ((?t ?i) . ?\x3061)
+ ((?d ?i) . ?\x3062)
+ ((?t ?U) . ?\x3063)
+ ((?t ?u) . ?\x3064)
+ ((?d ?u) . ?\x3065)
+ ((?t ?e) . ?\x3066)
+ ((?d ?e) . ?\x3067)
+ ((?t ?o) . ?\x3068)
+ ((?d ?o) . ?\x3069)
+ ((?n ?a) . ?\x306a)
+ ((?n ?i) . ?\x306b)
+ ((?n ?u) . ?\x306c)
+ ((?n ?e) . ?\x306d)
+ ((?n ?o) . ?\x306e)
+ ((?h ?a) . ?\x306f)
+ ((?b ?a) . ?\x3070)
+ ((?p ?a) . ?\x3071)
+ ((?h ?i) . ?\x3072)
+ ((?b ?i) . ?\x3073)
+ ((?p ?i) . ?\x3074)
+ ((?h ?u) . ?\x3075)
+ ((?b ?u) . ?\x3076)
+ ((?p ?u) . ?\x3077)
+ ((?h ?e) . ?\x3078)
+ ((?b ?e) . ?\x3079)
+ ((?p ?e) . ?\x307a)
+ ((?h ?o) . ?\x307b)
+ ((?b ?o) . ?\x307c)
+ ((?p ?o) . ?\x307d)
+ ((?m ?a) . ?\x307e)
+ ((?m ?i) . ?\x307f)
+ ((?m ?u) . ?\x3080)
+ ((?m ?e) . ?\x3081)
+ ((?m ?o) . ?\x3082)
+ ((?y ?A) . ?\x3083)
+ ((?y ?a) . ?\x3084)
+ ((?y ?U) . ?\x3085)
+ ((?y ?u) . ?\x3086)
+ ((?y ?O) . ?\x3087)
+ ((?y ?o) . ?\x3088)
+ ((?r ?a) . ?\x3089)
+ ((?r ?i) . ?\x308a)
+ ((?r ?u) . ?\x308b)
+ ((?r ?e) . ?\x308c)
+ ((?r ?o) . ?\x308d)
+ ((?w ?A) . ?\x308e)
+ ((?w ?a) . ?\x308f)
+ ((?w ?i) . ?\x3090)
+ ((?w ?e) . ?\x3091)
+ ((?w ?o) . ?\x3092)
+ ((?n ?5) . ?\x3093)
+ ((?v ?u) . ?\x3094)
+ ((?\" ?5) . ?\x309b)
+ ((?0 ?5) . ?\x309c)
+ ((?* ?5) . ?\x309d)
+ ((?+ ?5) . ?\x309e)
+ ((?a ?6) . ?\x30a1)
+ ((?A ?6) . ?\x30a2)
+ ((?i ?6) . ?\x30a3)
+ ((?I ?6) . ?\x30a4)
+ ((?u ?6) . ?\x30a5)
+ ((?U ?6) . ?\x30a6)
+ ((?e ?6) . ?\x30a7)
+ ((?E ?6) . ?\x30a8)
+ ((?o ?6) . ?\x30a9)
+ ((?O ?6) . ?\x30aa)
+ ((?K ?a) . ?\x30ab)
+ ((?G ?a) . ?\x30ac)
+ ((?K ?i) . ?\x30ad)
+ ((?G ?i) . ?\x30ae)
+ ((?K ?u) . ?\x30af)
+ ((?G ?u) . ?\x30b0)
+ ((?K ?e) . ?\x30b1)
+ ((?G ?e) . ?\x30b2)
+ ((?K ?o) . ?\x30b3)
+ ((?G ?o) . ?\x30b4)
+ ((?S ?a) . ?\x30b5)
+ ((?Z ?a) . ?\x30b6)
+ ((?S ?i) . ?\x30b7)
+ ((?Z ?i) . ?\x30b8)
+ ((?S ?u) . ?\x30b9)
+ ((?Z ?u) . ?\x30ba)
+ ((?S ?e) . ?\x30bb)
+ ((?Z ?e) . ?\x30bc)
+ ((?S ?o) . ?\x30bd)
+ ((?Z ?o) . ?\x30be)
+ ((?T ?a) . ?\x30bf)
+ ((?D ?a) . ?\x30c0)
+ ((?T ?i) . ?\x30c1)
+ ((?D ?i) . ?\x30c2)
+ ((?T ?U) . ?\x30c3)
+ ((?T ?u) . ?\x30c4)
+ ((?D ?u) . ?\x30c5)
+ ((?T ?e) . ?\x30c6)
+ ((?D ?e) . ?\x30c7)
+ ((?T ?o) . ?\x30c8)
+ ((?D ?o) . ?\x30c9)
+ ((?N ?a) . ?\x30ca)
+ ((?N ?i) . ?\x30cb)
+ ((?N ?u) . ?\x30cc)
+ ((?N ?e) . ?\x30cd)
+ ((?N ?o) . ?\x30ce)
+ ((?H ?a) . ?\x30cf)
+ ((?B ?a) . ?\x30d0)
+ ((?P ?a) . ?\x30d1)
+ ((?H ?i) . ?\x30d2)
+ ((?B ?i) . ?\x30d3)
+ ((?P ?i) . ?\x30d4)
+ ((?H ?u) . ?\x30d5)
+ ((?B ?u) . ?\x30d6)
+ ((?P ?u) . ?\x30d7)
+ ((?H ?e) . ?\x30d8)
+ ((?B ?e) . ?\x30d9)
+ ((?P ?e) . ?\x30da)
+ ((?H ?o) . ?\x30db)
+ ((?B ?o) . ?\x30dc)
+ ((?P ?o) . ?\x30dd)
+ ((?u ?R) . ?\x2515)
+ ((?U ?r) . ?\x2516)
+ ((?U ?R) . ?\x2517)
+ ((?u ?l) . ?\x2518)
+ ((?u ?L) . ?\x2519)
+ ((?U ?l) . ?\x251a)
+ ((?U ?L) . ?\x251b)
+ ((?v ?r) . ?\x251c)
+ ((?v ?R) . ?\x251d)
+ ((?V ?r) . ?\x2520)
+ ((?V ?R) . ?\x2523)
+ ((?v ?l) . ?\x2524)
+ ((?v ?L) . ?\x2525)
+ ((?V ?l) . ?\x2528)
+ ((?V ?L) . ?\x252b)
+ ((?d ?h) . ?\x252c)
+ ((?d ?H) . ?\x252f)
+ ((?D ?h) . ?\x2530)
+ ((?D ?H) . ?\x2533)
+ ((?u ?h) . ?\x2534)
+ ((?u ?H) . ?\x2537)
+ ((?U ?h) . ?\x2538)
+ ((?U ?H) . ?\x253b)
+ ((?v ?h) . ?\x253c)
+ ((?v ?H) . ?\x253f)
+ ((?V ?h) . ?\x2542)
+ ((?V ?H) . ?\x254b)
+ ((?F ?D) . ?\x2571)
+ ((?B ?D) . ?\x2572)
+ ((?T ?B) . ?\x2580)
+ ((?L ?B) . ?\x2584)
+ ((?F ?B) . ?\x2588)
+ ((?l ?B) . ?\x258c)
+ ((?R ?B) . ?\x2590)
+ ((?. ?S) . ?\x2591)
+ ((?: ?S) . ?\x2592)
+ ((?? ?S) . ?\x2593)
+ ((?f ?S) . ?\x25a0)
+ ((?O ?S) . ?\x25a1)
+ ((?R ?O) . ?\x25a2)
+ ((?R ?r) . ?\x25a3)
+ ((?R ?F) . ?\x25a4)
+ ((?R ?Y) . ?\x25a5)
+ ((?R ?H) . ?\x25a6)
+ ((?R ?Z) . ?\x25a7)
+ ((?R ?K) . ?\x25a8)
+ ((?R ?X) . ?\x25a9)
+ ((?s ?B) . ?\x25aa)
+ ((?S ?R) . ?\x25ac)
+ ((?O ?r) . ?\x25ad)
+ ((?U ?T) . ?\x25b2)
+ ((?u ?T) . ?\x25b3)
+ ((?P ?R) . ?\x25b6)
+ ((?T ?r) . ?\x25b7)
+ ((?D ?t) . ?\x25bc)
+ ((?d ?T) . ?\x25bd)
+ ((?P ?L) . ?\x25c0)
+ ((?T ?l) . ?\x25c1)
+ ((?D ?b) . ?\x25c6)
+ ((?D ?w) . ?\x25c7)
+ ((?L ?Z) . ?\x25ca)
+ ((?0 ?m) . ?\x25cb)
+ ((?0 ?o) . ?\x25ce)
+ ((?0 ?M) . ?\x25cf)
+ ((?0 ?L) . ?\x25d0)
+ ((?0 ?R) . ?\x25d1)
+ ((?S ?n) . ?\x25d8)
+ ((?I ?c) . ?\x25d9)
+ ((?F ?d) . ?\x25e2)
+ ((?B ?d) . ?\x25e3)
+ ((?* ?2) . ?\x2605)
+ ((?* ?1) . ?\x2606)
+ ((?< ?H) . ?\x261c)
+ ((?> ?H) . ?\x261e)
+ ((?0 ?u) . ?\x263a)
+ ((?0 ?U) . ?\x263b)
+ ((?S ?U) . ?\x263c)
+ ((?F ?m) . ?\x2640)
+ ((?M ?l) . ?\x2642)
+ ((?c ?S) . ?\x2660)
+ ((?c ?H) . ?\x2661)
+ ((?c ?D) . ?\x2662)
+ ((?c ?C) . ?\x2663)
+ ((?M ?d) . ?\x2669)
+ ((?M ?8) . ?\x266a)
+ ((?M ?2) . ?\x266b)
+ ((?M ?b) . ?\x266d)
+ ((?M ?x) . ?\x266e)
+ ((?M ?X) . ?\x266f)
+ ((?O ?K) . ?\x2713)
+ ((?X ?X) . ?\x2717)
+ ((?- ?X) . ?\x2720)
+ ((?I ?S) . ?\x3000)
+ ((?, ?_) . ?\x3001)
+ ((?. ?_) . ?\x3002)
+ ((?+ ?\") . ?\x3003)
+ ((?+ ?_) . ?\x3004)
+ ((?* ?_) . ?\x3005)
+ ((?\; ?_) . ?\x3006)
+ ((?0 ?_) . ?\x3007)
+ ((?< ?+) . ?\x300a)
+ ((?> ?+) . ?\x300b)
+ ((?< ?') . ?\x300c)
+ ((?> ?') . ?\x300d)
+ ((?< ?\") . ?\x300e)
+ ((?> ?\") . ?\x300f)
+ ((?\( ?\") . ?\x3010)
+ ((?\) ?\") . ?\x3011)
+ ((?= ?T) . ?\x3012)
+ ((?= ?_) . ?\x3013)
+ ((?\( ?') . ?\x3014)
+ ((?\) ?') . ?\x3015)
+ ((?\( ?I) . ?\x3016)
+ ((?\) ?I) . ?\x3017)
+ ((?- ??) . ?\x301c)
+ ((?A ?5) . ?\x3041)
+ ((?a ?5) . ?\x3042)
+ ((?I ?5) . ?\x3043)
+ ((?i ?5) . ?\x3044)
+ ((?U ?5) . ?\x3045)
+ ((?u ?5) . ?\x3046)
+ ((?E ?5) . ?\x3047)
+ ((?e ?5) . ?\x3048)
+ ((?O ?5) . ?\x3049)
+ ((?o ?5) . ?\x304a)
+ ((?k ?a) . ?\x304b)
+ ((?g ?a) . ?\x304c)
+ ((?k ?i) . ?\x304d)
+ ((?g ?i) . ?\x304e)
+ ((?k ?u) . ?\x304f)
+ ((?g ?u) . ?\x3050)
+ ((?k ?e) . ?\x3051)
+ ((?g ?e) . ?\x3052)
+ ((?k ?o) . ?\x3053)
+ ((?g ?o) . ?\x3054)
+ ((?s ?a) . ?\x3055)
+ ((?z ?a) . ?\x3056)
+ ((?s ?i) . ?\x3057)
+ ((?z ?i) . ?\x3058)
+ ((?s ?u) . ?\x3059)
+ ((?z ?u) . ?\x305a)
+ ((?s ?e) . ?\x305b)
+ ((?z ?e) . ?\x305c)
+ ((?s ?o) . ?\x305d)
+ ((?z ?o) . ?\x305e)
+ ((?t ?a) . ?\x305f)
+ ((?d ?a) . ?\x3060)
+ ((?t ?i) . ?\x3061)
+ ((?d ?i) . ?\x3062)
+ ((?t ?U) . ?\x3063)
+ ((?t ?u) . ?\x3064)
+ ((?d ?u) . ?\x3065)
+ ((?t ?e) . ?\x3066)
+ ((?d ?e) . ?\x3067)
+ ((?t ?o) . ?\x3068)
+ ((?d ?o) . ?\x3069)
+ ((?n ?a) . ?\x306a)
+ ((?n ?i) . ?\x306b)
+ ((?n ?u) . ?\x306c)
+ ((?n ?e) . ?\x306d)
+ ((?n ?o) . ?\x306e)
+ ((?h ?a) . ?\x306f)
+ ((?b ?a) . ?\x3070)
+ ((?p ?a) . ?\x3071)
+ ((?h ?i) . ?\x3072)
+ ((?b ?i) . ?\x3073)
+ ((?p ?i) . ?\x3074)
+ ((?h ?u) . ?\x3075)
+ ((?b ?u) . ?\x3076)
+ ((?p ?u) . ?\x3077)
+ ((?h ?e) . ?\x3078)
+ ((?b ?e) . ?\x3079)
+ ((?p ?e) . ?\x307a)
+ ((?h ?o) . ?\x307b)
+ ((?b ?o) . ?\x307c)
+ ((?p ?o) . ?\x307d)
+ ((?m ?a) . ?\x307e)
+ ((?m ?i) . ?\x307f)
+ ((?m ?u) . ?\x3080)
+ ((?m ?e) . ?\x3081)
+ ((?m ?o) . ?\x3082)
+ ((?y ?A) . ?\x3083)
+ ((?y ?a) . ?\x3084)
+ ((?y ?U) . ?\x3085)
+ ((?y ?u) . ?\x3086)
+ ((?y ?O) . ?\x3087)
+ ((?y ?o) . ?\x3088)
+ ((?r ?a) . ?\x3089)
+ ((?r ?i) . ?\x308a)
+ ((?r ?u) . ?\x308b)
+ ((?r ?e) . ?\x308c)
+ ((?r ?o) . ?\x308d)
+ ((?w ?A) . ?\x308e)
+ ((?w ?a) . ?\x308f)
+ ((?w ?i) . ?\x3090)
+ ((?w ?e) . ?\x3091)
+ ((?w ?o) . ?\x3092)
+ ((?n ?5) . ?\x3093)
+ ((?v ?u) . ?\x3094)
+ ((?\" ?5) . ?\x309b)
+ ((?0 ?5) . ?\x309c)
+ ((?* ?5) . ?\x309d)
+ ((?+ ?5) . ?\x309e)
+ ((?a ?6) . ?\x30a1)
+ ((?A ?6) . ?\x30a2)
+ ((?i ?6) . ?\x30a3)
+ ((?I ?6) . ?\x30a4)
+ ((?u ?6) . ?\x30a5)
+ ((?U ?6) . ?\x30a6)
+ ((?e ?6) . ?\x30a7)
+ ((?E ?6) . ?\x30a8)
+ ((?o ?6) . ?\x30a9)
+ ((?O ?6) . ?\x30aa)
+ ((?K ?a) . ?\x30ab)
+ ((?G ?a) . ?\x30ac)
+ ((?K ?i) . ?\x30ad)
+ ((?G ?i) . ?\x30ae)
+ ((?K ?u) . ?\x30af)
+ ((?G ?u) . ?\x30b0)
+ ((?K ?e) . ?\x30b1)
+ ((?G ?e) . ?\x30b2)
+ ((?K ?o) . ?\x30b3)
+ ((?G ?o) . ?\x30b4)
+ ((?S ?a) . ?\x30b5)
+ ((?Z ?a) . ?\x30b6)
+ ((?S ?i) . ?\x30b7)
+ ((?Z ?i) . ?\x30b8)
+ ((?S ?u) . ?\x30b9)
+ ((?Z ?u) . ?\x30ba)
+ ((?S ?e) . ?\x30bb)
+ ((?Z ?e) . ?\x30bc)
+ ((?S ?o) . ?\x30bd)
+ ((?Z ?o) . ?\x30be)
+ ((?T ?a) . ?\x30bf)
+ ((?D ?a) . ?\x30c0)
+ ((?T ?i) . ?\x30c1)
+ ((?D ?i) . ?\x30c2)
+ ((?T ?U) . ?\x30c3)
+ ((?T ?u) . ?\x30c4)
+ ((?D ?u) . ?\x30c5)
+ ((?T ?e) . ?\x30c6)
+ ((?D ?e) . ?\x30c7)
+ ((?T ?o) . ?\x30c8)
+ ((?D ?o) . ?\x30c9)
+ ((?N ?a) . ?\x30ca)
+ ((?N ?i) . ?\x30cb)
+ ((?N ?u) . ?\x30cc)
+ ((?N ?e) . ?\x30cd)
+ ((?N ?o) . ?\x30ce)
+ ((?H ?a) . ?\x30cf)
+ ((?B ?a) . ?\x30d0)
+ ((?P ?a) . ?\x30d1)
+ ((?H ?i) . ?\x30d2)
+ ((?B ?i) . ?\x30d3)
+ ((?P ?i) . ?\x30d4)
+ ((?H ?u) . ?\x30d5)
+ ((?B ?u) . ?\x30d6)
+ ((?P ?u) . ?\x30d7)
+ ((?H ?e) . ?\x30d8)
+ ((?B ?e) . ?\x30d9)
+ ((?P ?e) . ?\x30da)
+ ((?H ?o) . ?\x30db)
+ ((?B ?o) . ?\x30dc)
+ ((?P ?o) . ?\x30dd)
+ ((?M ?a) . ?\x30de)
+ ((?M ?i) . ?\x30df)
+ ((?M ?u) . ?\x30e0)
+ ((?M ?e) . ?\x30e1)
+ ((?M ?o) . ?\x30e2)
+ ((?Y ?A) . ?\x30e3)
+ ((?Y ?a) . ?\x30e4)
+ ((?Y ?U) . ?\x30e5)
+ ((?Y ?u) . ?\x30e6)
+ ((?Y ?O) . ?\x30e7)
+ ((?Y ?o) . ?\x30e8)
+ ((?R ?a) . ?\x30e9)
+ ((?R ?i) . ?\x30ea)
+ ((?R ?u) . ?\x30eb)
+ ((?R ?e) . ?\x30ec)
+ ((?R ?o) . ?\x30ed)
+ ((?W ?A) . ?\x30ee)
+ ((?W ?a) . ?\x30ef)
+ ((?W ?i) . ?\x30f0)
+ ((?W ?e) . ?\x30f1)
+ ((?W ?o) . ?\x30f2)
+ ((?N ?6) . ?\x30f3)
+ ((?V ?u) . ?\x30f4)
+ ((?K ?A) . ?\x30f5)
+ ((?K ?E) . ?\x30f6)
+ ((?V ?a) . ?\x30f7)
+ ((?V ?i) . ?\x30f8)
+ ((?V ?e) . ?\x30f9)
+ ((?V ?o) . ?\x30fa)
+ ((?. ?6) . ?\x30fb)
+ ((?- ?6) . ?\x30fc)
+ ((?* ?6) . ?\x30fd)
+ ((?+ ?6) . ?\x30fe)
+ ((?b ?4) . ?\x3105)
+ ((?p ?4) . ?\x3106)
+ ((?m ?4) . ?\x3107)
+ ((?f ?4) . ?\x3108)
+ ((?d ?4) . ?\x3109)
+ ((?t ?4) . ?\x310a)
+ ((?n ?4) . ?\x310b)
+ ((?l ?4) . ?\x310c)
+ ((?g ?4) . ?\x310d)
+ ((?k ?4) . ?\x310e)
+ ((?h ?4) . ?\x310f)
+ ((?j ?4) . ?\x3110)
+ ((?q ?4) . ?\x3111)
+ ((?x ?4) . ?\x3112)
+ ((?z ?h) . ?\x3113)
+ ((?c ?h) . ?\x3114)
+ ((?s ?h) . ?\x3115)
+ ((?r ?4) . ?\x3116)
+ ((?z ?4) . ?\x3117)
+ ((?c ?4) . ?\x3118)
+ ((?s ?4) . ?\x3119)
+ ((?a ?4) . ?\x311a)
+ ((?o ?4) . ?\x311b)
+ ((?e ?4) . ?\x311c)
+ ((?a ?i) . ?\x311e)
+ ((?e ?i) . ?\x311f)
+ ((?a ?u) . ?\x3120)
+ ((?o ?u) . ?\x3121)
+ ((?a ?n) . ?\x3122)
+ ((?e ?n) . ?\x3123)
+ ((?a ?N) . ?\x3124)
+ ((?e ?N) . ?\x3125)
+ ((?e ?r) . ?\x3126)
+ ((?i ?4) . ?\x3127)
+ ((?u ?4) . ?\x3128)
+ ((?i ?u) . ?\x3129)
+ ((?v ?4) . ?\x312a)
+ ((?n ?G) . ?\x312b)
+ ((?g ?n) . ?\x312c)
+ ((?1 ?c) . ?\x3220)
+ ((?2 ?c) . ?\x3221)
+ ((?3 ?c) . ?\x3222)
+ ((?4 ?c) . ?\x3223)
+ ((?5 ?c) . ?\x3224)
+ ((?6 ?c) . ?\x3225)
+ ((?7 ?c) . ?\x3226)
+ ((?8 ?c) . ?\x3227)
+ ((?9 ?c) . ?\x3228)
+ ((?\s ?\s) . ?\xe000)
+ ((?/ ?c) . ?\xe001)
+ ((?U ?A) . ?\xe002)
+ ((?U ?B) . ?\xe003)
+ ((?\" ?3) . ?\xe004)
+ ((?\" ?1) . ?\xe005)
+ ((?\" ?!) . ?\xe006)
+ ((?\" ?') . ?\xe007)
+ ((?\" ?>) . ?\xe008)
+ ((?\" ??) . ?\xe009)
+ ((?\" ?-) . ?\xe00a)
+ ((?\" ?\() . ?\xe00b)
+ ((?\" ?.) . ?\xe00c)
+ ((?\" ?:) . ?\xe00d)
+ ((?\" ?0) . ?\xe00e)
+ ((?\" ?\") . ?\xe00f)
+ ((?\" ?<) . ?\xe010)
+ ((?\" ?,) . ?\xe011)
+ ((?\" ?\;) . ?\xe012)
+ ((?\" ?_) . ?\xe013)
+ ((?\" ?=) . ?\xe014)
+ ((?\" ?/) . ?\xe015)
+ ((?\" ?i) . ?\xe016)
+ ((?\" ?d) . ?\xe017)
+ ((?\" ?p) . ?\xe018)
+ ((?\; ?\;) . ?\xe019)
+ ((?, ?,) . ?\xe01a)
+ ((?b ?3) . ?\xe01b)
+ ((?C ?i) . ?\xe01c)
+ ((?f ?\() . ?\xe01d)
+ ((?e ?d) . ?\xe01e)
+ ((?a ?m) . ?\xe01f)
+ ((?p ?m) . ?\xe020)
+ ((?F ?l) . ?\xe023)
+ ((?G ?F) . ?\xe024)
+ ((?> ?V) . ?\xe025)
+ ((?! ?*) . ?\xe026)
+ ((?? ?*) . ?\xe027)
+ ((?J ?<) . ?\xe028)
+ ((?f ?f) . ?\xfb00)
+ ((?f ?i) . ?\xfb01)
+ ((?f ?l) . ?\xfb02)
+ ((?f ?t) . ?\xfb05)
+ ((?s ?t) . ?\xfb06)
+ ((?~ ?!) . ?\x00a1)
+ ((?c ?|) . ?\x00a2)
+ ((?$ ?$) . ?\x00a3)
+ ((?o ?x) . ?\x00a4)
+ ((?Y ?-) . ?\x00a5)
+ ((?| ?|) . ?\x00a6)
+ ((?c ?O) . ?\x00a9)
+ ((?- ?,) . ?\x00ac)
+ ((?- ?=) . ?\x00af)
+ ((?~ ?o) . ?\x00b0)
+ ((?2 ?2) . ?\x00b2)
+ ((?3 ?3) . ?\x00b3)
+ ((?p ?p) . ?\x00b6)
+ ((?~ ?.) . ?\x00b7)
+ ((?1 ?1) . ?\x00b9)
+ ((?~ ??) . ?\x00bf)
+ ((?A ?`) . ?\x00c0)
+ ((?A ?^) . ?\x00c2)
+ ((?A ?~) . ?\x00c3)
+ ((?A ?\") . ?\x00c4)
+ ((?A ?@) . ?\x00c5)
+ ((?E ?`) . ?\x00c8)
+ ((?E ?^) . ?\x00ca)
+ ((?E ?\") . ?\x00cb)
+ ((?I ?`) . ?\x00cc)
+ ((?I ?^) . ?\x00ce)
+ ((?I ?\") . ?\x00cf)
+ ((?N ?~) . ?\x00d1)
+ ((?O ?`) . ?\x00d2)
+ ((?O ?^) . ?\x00d4)
+ ((?O ?~) . ?\x00d5)
+ ((?/ ?\\) . ?\x00d7)
+ ((?U ?`) . ?\x00d9)
+ ((?U ?^) . ?\x00db)
+ ((?I ?p) . ?\x00de)
+ ((?a ?`) . ?\x00e0)
+ ((?a ?^) . ?\x00e2)
+ ((?a ?~) . ?\x00e3)
+ ((?a ?\") . ?\x00e4)
+ ((?a ?@) . ?\x00e5)
+ ((?e ?`) . ?\x00e8)
+ ((?e ?^) . ?\x00ea)
+ ((?e ?\") . ?\x00eb)
+ ((?i ?`) . ?\x00ec)
+ ((?i ?^) . ?\x00ee)
+ ((?n ?~) . ?\x00f1)
+ ((?o ?`) . ?\x00f2)
+ ((?o ?^) . ?\x00f4)
+ ((?o ?~) . ?\x00f5)
+ ((?u ?`) . ?\x00f9)
+ ((?u ?^) . ?\x00fb)
+ ((?y ?\") . ?\x00ff))
+ "Table of default digraphs.
+This includes all digraphs defined in RFC 1345,
+as well as miscellaneous digraphs for multi-byte characters.
+See also `evil-digraphs-table-user'.")
+
+(defun evil-digraph (digraph)
+ "Convert DIGRAPH to character or list representation.
+If DIGRAPH is a list (CHAR1 CHAR2), return the corresponding character;
+if DIGRAPH is a character, return the corresponding list.
+Searches in `evil-digraphs-table-user' and `evil-digraphs-table'."
+ (if (listp digraph)
+ (let* ((char1 (car digraph))
+ (char2 (cadr digraph)))
+ (or (cdr (assoc (list char1 char2) evil-digraphs-table-user))
+ (cdr (assoc (list char1 char2) evil-digraphs-table))
+ (unless (eq char1 char2)
+ (or (cdr (assoc (list char2 char1) evil-digraphs-table-user))
+ (cdr (assoc (list char2 char1) evil-digraphs-table))))))
+ (or (car (rassoc digraph evil-digraphs-table-user))
+ (car (rassoc digraph evil-digraphs-table)))))
+
+(provide 'evil-digraphs)
+
+;;; evil-digraphs.el ends here
diff --git a/elpa/evil-20220503.1314/evil-digraphs.elc b/elpa/evil-20220503.1314/evil-digraphs.elc
new file mode 100644
index 0000000..529ff54
--- /dev/null
+++ b/elpa/evil-20220503.1314/evil-digraphs.elc
Binary files differ
diff --git a/elpa/evil-20220503.1314/evil-ex.el b/elpa/evil-20220503.1314/evil-ex.el
new file mode 100644
index 0000000..3120e79
--- /dev/null
+++ b/elpa/evil-20220503.1314/evil-ex.el
@@ -0,0 +1,1195 @@
+;;; evil-ex.el --- Ex-mode -*- lexical-binding: nil -*-
+
+;; Author: Frank Fischer <frank fischer at mathematik.tu-chemnitz.de>
+;; Maintainer: Vegard Øye <vegard_oye at hotmail.com>
+
+;; Version: 1.15.0
+
+;;
+;; This file is NOT part of GNU Emacs.
+
+;;; License:
+
+;; This file is part of Evil.
+;;
+;; Evil 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.
+;;
+;; Evil 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 Evil. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Ex is implemented as an extensible minilanguage, whose grammar
+;; is stored in `evil-ex-grammar'. Ex commands are defined with
+;; `evil-ex-define-cmd', which creates a binding from a string
+;; to an interactive function. It is also possible to define key
+;; sequences which execute a command immediately when entered:
+;; such shortcuts go in `evil-ex-map'.
+;;
+;; To provide buffer and filename completion, as well as interactive
+;; feedback, Ex defines the concept of an argument handler, specified
+;; with `evil-ex-define-argument-type'. In the case of the
+;; substitution command (":s/foo/bar"), the handler incrementally
+;; highlights matches in the buffer as the substitution is typed.
+
+(require 'evil-common)
+(require 'evil-states)
+(require 'evil-types)
+(require 'shell)
+
+;;; Code:
+
+(defconst evil-ex-grammar
+ '((expression
+ (count command argument #'evil-ex-call-command)
+ ((\? range) command argument #'evil-ex-call-command)
+ (line #'evil-goto-line)
+ (sexp #'eval-expression))
+ (count
+ number)
+ (command #'evil-ex-parse-command)
+ (binding
+ "[~&*@<>=:]+\\|[[:alpha:]_]+\\|!")
+ (emacs-binding
+ "[[:alpha:]-][[:alnum:][:punct:]-]+")
+ (bang
+ (\? (! space) "!" #'$1))
+ (argument
+ ((\? space) (\? "\\(?:.\\|\n\\)+") #'$2))
+ (range
+ ("%" #'(evil-ex-full-range))
+ ("*" #'(evil-ex-last-visual-range))
+ ((alt "," ";") line #'(evil-ex-range (evil-ex-current-line) $2))
+ (line ";" line #'(let ((tmp1 $1))
+ (save-excursion
+ (goto-line tmp1)
+ (evil-ex-range tmp1 $3))))
+ (line "," line #'(evil-ex-range $1 $3))
+ (line #'(evil-ex-range $1 nil))
+ ("`" marker-name ",`" marker-name
+ #'(evil-ex-char-marker-range $2 $4)))
+ (line
+ (base (\? offset) search (\? offset)
+ #'(let ((tmp (evil-ex-line $1 $2)))
+ (save-excursion
+ (goto-line tmp)
+ (evil-ex-line $3 $4))))
+ ((\? base) offset search (\? offset)
+ #'(let ((tmp (evil-ex-line $1 $2)))
+ (save-excursion
+ (goto-line tmp)
+ (evil-ex-line $3 $4))))
+ (base (\? offset) #'evil-ex-line)
+ ((\? base) offset #'evil-ex-line))
+ (base
+ number
+ marker
+ search
+ ("\\^" #'(evil-ex-first-line))
+ ("\\$" #'(evil-ex-last-line))
+ ("\\." #'(evil-ex-current-line)))
+ (offset
+ (+ signed-number #'+))
+ (marker
+ ("'" marker-name #'(evil-ex-marker $2)))
+ (search
+ forward
+ backward
+ next
+ prev
+ subst)
+ (forward
+ ("/" "\\(?:[\\].\\|[^/,; ]\\)+" (! "/")
+ #'(evil-ex-re-fwd $2))
+ ("/" "\\(?:[\\].\\|[^/]\\)+" "/"
+ #'(evil-ex-re-fwd $2)))
+ (backward
+ ("\\?" "\\(?:[\\].\\|[^?,; ]\\)+" (! "\\?")
+ #'(evil-ex-re-bwd $2))
+ ("\\?" "\\(?:[\\].\\|[^?]\\)+" "\\?"
+ #'(evil-ex-re-bwd $2)))
+ (marker-name
+ "[]\\[-a-zA-Z_<>'}{)(]")
+ (next
+ "\\\\/" #'(evil-ex-prev-search))
+ (prev
+ "\\\\\\?" #'(evil-ex-prev-search))
+ (subst
+ "\\\\&" #'(evil-ex-prev-search))
+ (signed-number
+ (sign (\? number) #'evil-ex-signed-number))
+ (sign
+ "\\+\\|-" #'intern)
+ (number
+ "[0-9]+" #'string-to-number)
+ (space
+ "[ ]+")
+ (sexp
+ "(.*)" #'(car-safe (read-from-string $1))))
+ "Grammar for Ex.
+An association list of syntactic symbols and their definitions.
+The first entry is the start symbol. A symbol's definition may
+reference other symbols, but the grammar cannot contain
+left recursion. See `evil-parser' for a detailed explanation
+of the syntax.")
+
+(defvar evil-ex-echo-overlay nil
+ "Overlay used for displaying info messages during ex.")
+
+(defun evil-ex-p ()
+ "Whether Ex is currently active."
+ (and evil-ex-current-buffer t))
+
+(evil-define-command evil-ex (&optional initial-input)
+ "Enter an Ex command.
+The ex command line is initialized with the value of
+INITIAL-INPUT. If the command is called interactively the initial
+input depends on the current state. If the current state is
+normal state and no count argument is given then the initial
+input is empty. If a prefix count is given the initial input is
+.,.+count. If the current state is visual state then the initial
+input is the visual region '<,'> or `<,`>. If the value of the
+global variable `evil-ex-initial-input' is non-nil, its content
+is appended to the line."
+ :keep-visual t
+ :repeat abort
+ (interactive
+ (list
+ (let ((s (concat
+ (cond
+ ((and (evil-visual-state-p)
+ evil-ex-visual-char-range
+ (memq (evil-visual-type) '(inclusive exclusive)))
+ "`<,`>")
+ ((evil-visual-state-p)
+ "'<,'>")
+ (current-prefix-arg
+ (let ((arg (prefix-numeric-value current-prefix-arg)))
+ (cond ((< arg 0) (setq arg (1+ arg)))
+ ((> arg 0) (setq arg (1- arg))))
+ (if (= arg 0) "."
+ (format ".,.%+d" arg)))))
+ evil-ex-initial-input)))
+ (and (> (length s) 0) s))))
+ (let ((evil-ex-current-buffer (current-buffer))
+ (evil-ex-previous-command (unless initial-input
+ (car-safe evil-ex-history)))
+ evil-ex-argument-handler
+ evil-ex-info-string
+ result)
+ (minibuffer-with-setup-hook
+ (if initial-input #'evil-ex-setup-and-update #'evil-ex-setup)
+ (setq result
+ (read-from-minibuffer
+ ":"
+ (or initial-input
+ (and evil-ex-previous-command
+ evil-want-empty-ex-last-command
+ (propertize evil-ex-previous-command 'face 'shadow)))
+ evil-ex-completion-map
+ nil
+ 'evil-ex-history
+ (when evil-want-empty-ex-last-command
+ evil-ex-previous-command)
+ t)))
+ (evil-ex-execute result)))
+
+(defun evil-ex-execute (result)
+ "Execute RESULT as an ex command on `evil-ex-current-buffer'."
+ ;; empty input means repeating the previous command
+ (when (and (zerop (length result))
+ evil-want-empty-ex-last-command)
+ (setq result evil-ex-previous-command))
+ ;; parse data
+ (evil-ex-update nil nil nil result)
+ ;; execute command
+ (unless (zerop (length result))
+ (if evil-ex-expression
+ (eval evil-ex-expression)
+ (user-error "Ex: syntax error"))))
+
+(defun evil-ex-delete-backward-char ()
+ "Close the minibuffer if it is empty.
+Otherwise behaves like `delete-backward-char'."
+ (interactive)
+ (call-interactively
+ (if (zerop (length (minibuffer-contents)))
+ #'abort-recursive-edit
+ #'delete-backward-char)))
+
+(defun evil-ex-abort ()
+ "Cancel ex state when another buffer is selected."
+ (unless (or (minibufferp)
+ (memq this-command '(mouse-drag-region choose-completion)))
+ (abort-recursive-edit)))
+
+(defun evil-ex-command-window-execute (config result)
+ (select-window (active-minibuffer-window) t)
+ (set-window-configuration config)
+ (delete-minibuffer-contents)
+ (insert result)
+ (exit-minibuffer))
+
+(defun evil-ex-elisp-completion-at-point ()
+ "Complete an `evil-ex' Elisp expression."
+ (when (and (fboundp 'elisp-completion-at-point)
+ (string-prefix-p "(" (minibuffer-contents-no-properties)))
+ (elisp-completion-at-point)))
+
+(defun evil-ex-setup ()
+ "Initialize Ex minibuffer.
+This function registers several hooks that are used for the
+interactive actions during ex state."
+ (add-hook 'post-command-hook #'evil-ex-abort)
+ (add-hook 'after-change-functions #'evil-ex-update nil t)
+ (add-hook 'minibuffer-exit-hook #'evil-ex-teardown nil t)
+ (when evil-ex-previous-command
+ (add-hook 'pre-command-hook #'evil-ex-remove-default))
+ (remove-hook 'minibuffer-setup-hook #'evil-ex-setup)
+ (with-no-warnings
+ (make-variable-buffer-local 'completion-at-point-functions))
+ (setq completion-at-point-functions
+ '(evil-ex-elisp-completion-at-point
+ evil-ex-command-completion-at-point
+ evil-ex-argument-completion-at-point)))
+(put 'evil-ex-setup 'permanent-local-hook t)
+
+(defun evil-ex-setup-and-update ()
+ "Initialize Ex minibuffer with `evil-ex-setup', then call `evil-ex-update'."
+ (evil-ex-setup)
+ (evil-ex-update))
+
+(defun evil-ex-teardown ()
+ "Deinitialize Ex minibuffer.
+Clean up everything set up by `evil-ex-setup'."
+ (remove-hook 'post-command-hook #'evil-ex-abort)
+ (remove-hook 'minibuffer-exit-hook #'evil-ex-teardown t)
+ (remove-hook 'after-change-functions #'evil-ex-update t)
+ (when evil-ex-argument-handler
+ (let ((runner (evil-ex-argument-handler-runner
+ evil-ex-argument-handler)))
+ (when runner
+ (funcall runner 'stop)))))
+(put 'evil-ex-teardown 'permanent-local-hook t)
+
+(defun evil-ex-update (&optional beg end len string)
+ "Update Ex variables when the minibuffer changes.
+This function is usually called from `after-change-functions'
+hook. If BEG is non-nil (which is the case when called from
+`after-change-functions'), then an error description is shown
+in case of incomplete or unknown commands."
+ (let* ((prompt (minibuffer-prompt-end))
+ (string (or string (buffer-substring prompt (point-max))))
+ arg bang cmd count expr func handler range tree type)
+ (cond
+ ((and (eq this-command #'self-insert-command)
+ (commandp (setq cmd (lookup-key evil-ex-map string))))
+ (setq evil-ex-expression `(call-interactively #',cmd))
+ (when (minibufferp)
+ (exit-minibuffer)))
+ (t
+ (setq cmd nil)
+ ;; store the buffer position of each character
+ ;; as the `ex-index' text property
+ (dotimes (i (length string))
+ (add-text-properties
+ i (1+ i) (list 'ex-index (+ i prompt)) string))
+ (with-current-buffer evil-ex-current-buffer
+ (setq tree (evil-ex-parse string t)
+ expr (evil-ex-parse string))
+ (when (eq (car-safe expr) 'evil-ex-call-command)
+ (setq count (eval (nth 1 expr))
+ cmd (eval (nth 2 expr))
+ arg (eval (nth 3 expr))
+ range (cond
+ ((evil-range-p count)
+ count)
+ ((numberp count)
+ (evil-ex-range count count)))
+ bang (and (save-match-data (string-match ".!$" cmd)) t))))
+ (setq evil-ex-tree tree
+ evil-ex-expression expr
+ evil-ex-range range
+ evil-ex-cmd cmd
+ evil-ex-bang bang
+ evil-ex-argument arg)
+ ;; test the current command
+ (when (and cmd (minibufferp))
+ (setq func (evil-ex-completed-binding cmd t))
+ (cond
+ ;; update argument-handler
+ (func
+ (when (setq type (evil-get-command-property
+ func :ex-arg))
+ (setq handler (cdr-safe
+ (assoc type
+ evil-ex-argument-types))))
+ (unless (eq handler evil-ex-argument-handler)
+ (let ((runner (and evil-ex-argument-handler
+ (evil-ex-argument-handler-runner
+ evil-ex-argument-handler))))
+ (when runner (funcall runner 'stop)))
+ (setq evil-ex-argument-handler handler)
+ (let ((runner (and evil-ex-argument-handler
+ (evil-ex-argument-handler-runner
+ evil-ex-argument-handler))))
+ (when runner (funcall runner 'start evil-ex-argument))))
+ (let ((runner (and evil-ex-argument-handler
+ (evil-ex-argument-handler-runner
+ evil-ex-argument-handler))))
+ (when runner (funcall runner 'update evil-ex-argument))))
+ (beg
+ ;; show error message only when called from `after-change-functions'
+ (let ((n (length (all-completions cmd (evil-ex-completion-table)))))
+ (cond
+ ((> n 1) (evil-ex-echo "Incomplete command"))
+ ((= n 0) (evil-ex-echo "Unknown command")))))))))))
+(put 'evil-ex-update 'permanent-local-hook t)
+
+(defun evil-ex-echo (string &rest args)
+ "Display a message after the current Ex command."
+ (with-selected-window (minibuffer-window)
+ (with-current-buffer (window-buffer (minibuffer-window))
+ (unless (or evil-no-display
+ (zerop (length string)))
+ (let ((string (format " [%s]" (apply #'format string args)))
+ (ov (or evil-ex-echo-overlay
+ (setq evil-ex-echo-overlay (make-overlay (point-min) (point-max) nil t t))))
+ after-change-functions before-change-functions)
+ (put-text-property 0 (length string) 'face 'evil-ex-info string)
+ ;; The following 'trick' causes point to be shown before the
+ ;; message instead behind. It is shamelessly stolen from the
+ ;; implementation of `minibuffer-message`.
+ (put-text-property 0 1 'cursor t string)
+ (move-overlay ov (point-max) (point-max))
+ (overlay-put ov 'after-string string)
+ (add-hook 'pre-command-hook #'evil--ex-remove-echo-overlay nil t))))))
+
+(defun evil--ex-remove-echo-overlay ()
+ "Remove echo overlay from ex minibuffer."
+ (when evil-ex-echo-overlay
+ (delete-overlay evil-ex-echo-overlay)
+ (setq evil-ex-echo-overlay nil))
+ (remove-hook 'pre-command-hook 'evil--ex-remove-echo-overlay t))
+
+(defun evil-ex-completion ()
+ "Completes the current ex command or argument."
+ (interactive)
+ (let (after-change-functions)
+ (evil-ex-update)
+ (completion-at-point)
+ (remove-text-properties (minibuffer-prompt-end) (point-max) '(face nil evil))))
+
+(defun evil-ex-command-completion-at-point ()
+ (let ((beg (or (get-text-property 0 'ex-index evil-ex-cmd)
+ (point)))
+ (end (point)))
+ (list beg end (evil-ex-completion-table) :exclusive 'no)))
+
+(defun evil-ex-completion-table ()
+ (cond
+ ((eq evil-ex-complete-emacs-commands nil)
+ #'evil-ex-command-collection)
+ ((eq evil-ex-complete-emacs-commands 'in-turn)
+ (completion-table-in-turn
+ #'evil-ex-command-collection
+ #'(lambda (str pred flag)
+ (completion-table-with-predicate
+ obarray #'commandp t str pred flag))))
+ (t
+ #'(lambda (str pred flag)
+ (evil-completion-table-concat
+ #'evil-ex-command-collection
+ #'(lambda (str pred flag)
+ (completion-table-with-predicate
+ obarray #'commandp t str pred flag))
+ str pred flag)))))
+
+(defun evil-completion-table-concat (table1 table2 string pred flag)
+ (cond
+ ((eq flag nil)
+ (let ((result1 (try-completion string table1 pred))
+ (result2 (try-completion string table2 pred)))
+ (cond
+ ((null result1) result2)
+ ((null result2) result1)
+ ((and (eq result1 t) (eq result2 t)) t)
+ (t result1))))
+ ((eq flag t)
+ (delete-dups
+ (append (all-completions string table1 pred)
+ (all-completions string table2 pred))))
+ ((eq flag 'lambda)
+ (and (or (eq t (test-completion string table1 pred))
+ (eq t (test-completion string table2 pred)))
+ t))
+ ((eq (car-safe flag) 'boundaries)
+ (or (completion-boundaries string table1 pred (cdr flag))
+ (completion-boundaries string table2 pred (cdr flag))))
+ ((eq flag 'metadata)
+ '(metadata (display-sort-function . evil-ex-sort-completions)))))
+
+(defun evil-ex-sort-completions (completions)
+ (sort completions
+ #'(lambda (str1 str2)
+ (let ((p1 (eq 'evil-ex-commands (get-text-property 0 'face str1)))
+ (p2 (eq 'evil-ex-commands (get-text-property 0 'face str2))))
+ (if (equal p1 p2)
+ (string< str1 str2)
+ p1)))))
+
+(defun evil-ex-command-collection (cmd predicate flag)
+ "Called to complete a command."
+ (let (commands)
+ ;; append ! to all commands that may take a bang argument
+ (dolist (cmd (mapcar #'car evil-ex-commands))
+ (push cmd commands)
+ (if (evil-ex-command-force-p cmd)
+ (push (concat cmd "!") commands)))
+ (when (eq evil-ex-complete-emacs-commands t)
+ (setq commands
+ (mapcar #'(lambda (str) (propertize str 'face 'evil-ex-commands))
+ commands)))
+ (cond
+ ((eq flag nil) (try-completion cmd commands predicate))
+ ((eq flag t) (all-completions cmd commands predicate))
+ ((eq flag 'lambda) (test-completion cmd commands))
+ ((eq (car-safe flag) 'boundaries)
+ `(boundaries 0 . ,(length (cdr flag)))))))
+
+(defun evil-ex-argument-completion-at-point ()
+ (let ((context (evil-ex-syntactic-context (1- (point)))))
+ (when (memq 'argument context)
+ ;; if it's an autoload, load the function; this allows external
+ ;; packages to register autoloaded ex commands which will be
+ ;; loaded when ex argument completion is triggered
+ (let ((binding-definition (symbol-function (evil-ex-binding evil-ex-cmd))))
+ (when (autoloadp binding-definition)
+ (autoload-do-load binding-definition)))
+
+ (let* ((beg (or (and evil-ex-argument
+ (get-text-property 0 'ex-index evil-ex-argument))
+ (point)))
+ (end (1+ (or (and evil-ex-argument
+ (get-text-property (1- (length evil-ex-argument))
+ 'ex-index
+ evil-ex-argument))
+ (1- (point)))))
+ (binding (evil-ex-completed-binding evil-ex-cmd))
+ (arg-type (evil-get-command-property binding :ex-arg))
+ (arg-handler (assoc arg-type evil-ex-argument-types))
+ (completer (and arg-handler
+ (evil-ex-argument-handler-completer
+ (cdr arg-handler)))))
+ (when completer
+ (if (eq (car completer) 'collection)
+ (list beg end (cdr completer))
+ (save-restriction
+ (narrow-to-region beg (point-max))
+ (funcall (cdr completer)))))))))
+
+(defun evil-ex-define-cmd (cmd function)
+ "Binds the function FUNCTION to the command CMD."
+ (save-match-data
+ (if (string-match "^[^][]*\\(\\[\\(.*\\)\\]\\)[^][]*$" cmd)
+ (let ((abbrev (replace-match "" nil t cmd 1))
+ (full (replace-match "\\2" nil nil cmd 1)))
+ (evil--add-to-alist 'evil-ex-commands full function)
+ (evil--add-to-alist 'evil-ex-commands abbrev full))
+ (evil--add-to-alist 'evil-ex-commands cmd function))))
+
+(defun evil-ex-make-argument-handler (runner completer)
+ (list runner completer))
+
+(defun evil-ex-argument-handler-runner (arg-handler)
+ (car arg-handler))
+
+(defun evil-ex-argument-handler-completer (arg-handler)
+ (cadr arg-handler))
+
+(defmacro evil-ex-define-argument-type (arg-type doc &rest body)
+ "Defines a new handler for argument-type ARG-TYPE.
+DOC is the documentation string. It is followed by a list of
+keywords and function:
+
+:collection COLLECTION
+
+ A collection for completion as required by `all-completions'.
+
+:completion-at-point FUNC
+
+ Function to be called to initialize a potential
+ completion. FUNC must match the requirements as described for
+ the variable `completion-at-point-functions'. When FUNC is
+ called the minibuffer content is narrowed to exactly match the
+ argument.
+
+:runner FUNC
+
+ Function to be called when the type of the current argument
+ changes or when the content of this argument changes. This
+ function should take one obligatory argument FLAG followed by
+ an optional argument ARG. FLAG is one of three symbol 'start,
+ 'stop or 'update. When the argument type is recognized for the
+ first time and this handler is started the FLAG is 'start. If
+ the argument type changes to something else or ex state
+ finished the handler FLAG is 'stop. If the content of the
+ argument has changed FLAG is 'update. If FLAG is either 'start
+ or 'update then ARG is the current value of this argument. If
+ FLAG is 'stop then arg is nil."
+ (declare (indent defun)
+ (doc-string 2)
+ (debug (&define name
+ [&optional stringp]
+ [&rest [keywordp function-form]])))
+ (unless (stringp doc) (push doc body))
+ (let (runner completer)
+ (while (keywordp (car-safe body))
+ (let ((key (pop body))
+ (func (pop body)))
+ (cond
+ ((eq key :runner)
+ (setq runner func))
+ ((eq key :collection)
+ (setq completer (cons 'collection func)))
+ ((eq key :completion-at-point)
+ (setq completer (cons 'completion-at-point func))))))
+ `(eval-and-compile
+ (evil--add-to-alist
+ 'evil-ex-argument-types
+ ',arg-type
+ '(,runner ,completer)))))
+
+(evil-ex-define-argument-type file
+ "Handles a file argument."
+ :collection read-file-name-internal)
+
+(evil-ex-define-argument-type buffer
+ "Called to complete a buffer name argument."
+ :collection internal-complete-buffer)
+
+(declare-function shell-completion-vars "shell" ())
+
+(defun evil-ex-init-shell-argument-completion (flag &optional arg)
+ "Prepares the current minibuffer for completion of shell commands.
+This function must be called from the :runner function of some
+argument handler that requires shell completion."
+ (when (and (eq flag 'start)
+ (not evil-ex-shell-argument-initialized))
+ (set (make-local-variable 'evil-ex-shell-argument-initialized) t)
+ (cond
+ ;; Emacs 24
+ ((fboundp 'comint-completion-at-point)
+ (shell-completion-vars))
+ (t
+ (set (make-local-variable 'minibuffer-default-add-function)
+ 'minibuffer-default-add-shell-commands)))
+ (setq completion-at-point-functions
+ '(evil-ex-command-completion-at-point
+ evil-ex-argument-completion-at-point))))
+
+(define-obsolete-function-alias
+ 'evil-ex-shell-command-completion-at-point
+ 'comint-completion-at-point "1.2.13")
+
+(evil-ex-define-argument-type shell
+ "Shell argument type, supports completion."
+ :completion-at-point comint-completion-at-point
+ :runner evil-ex-init-shell-argument-completion)
+
+(defun evil-ex-file-or-shell-command-completion-at-point ()
+ (if (and (< (point-min) (point-max))
+ (= (char-after (point-min)) ?!))
+ (save-restriction
+ (narrow-to-region (1+ (point-min)) (point-max))
+ (comint-completion-at-point))
+ (list (point-min) (point-max) #'read-file-name-internal)))
+
+(evil-ex-define-argument-type file-or-shell
+ "File or shell argument type.
+If the current argument starts with a ! the rest of the argument
+is considered a shell command, otherwise a file-name. Completion
+works accordingly."
+ :completion-at-point evil-ex-file-or-shell-command-completion-at-point
+ :runner evil-ex-init-shell-argument-completion)
+
+(defun evil-ex-binding (command &optional noerror)
+ "Returns the final binding of COMMAND."
+ (save-match-data
+ (let ((binding command))
+ (when binding
+ (string-match "^\\(.+?\\)\\!?$" binding)
+ (setq binding (match-string 1 binding))
+ (while (progn
+ (setq binding (cdr (assoc binding evil-ex-commands)))
+ (stringp binding)))
+ (unless binding
+ (setq binding (intern command)))
+ (if (commandp binding)
+ ;; check for remaps
+ (or (command-remapping binding) binding)
+ (unless noerror
+ (user-error "Unknown command: `%s'" command)))))))
+
+(defun evil-ex-completed-binding (command &optional noerror)
+ "Returns the final binding of the completion of COMMAND."
+ (let ((completion (try-completion command evil-ex-commands)))
+ (evil-ex-binding (if (eq completion t) command
+ (or completion command))
+ noerror)))
+
+;;; TODO: extensions likes :p :~ <cfile> ...
+(defun evil-ex-replace-special-filenames (file-name)
+ "Replace special symbols in FILE-NAME.
+Replaces % by the current file-name,
+Replaces # by the alternate file-name in FILE-NAME."
+ (let ((remote (file-remote-p file-name))
+ (current-fname (buffer-file-name))
+ (alternate-fname (and (other-buffer)
+ (buffer-file-name (other-buffer)))))
+ (setq file-name (or (file-remote-p file-name 'localname) file-name))
+ (when current-fname
+ (setq current-fname (or (file-remote-p current-fname 'localname)
+ current-fname))
+ (setq file-name
+ (replace-regexp-in-string "\\(^\\|[^\\\\]\\)\\(%\\)"
+ current-fname file-name
+ t t 2)))
+ (when alternate-fname
+ (setq alternate-fname (or (file-remote-p alternate-fname 'localname)
+ alternate-fname))
+ (setq file-name
+ (replace-regexp-in-string "\\(^\\|[^\\\\]\\)\\(#\\)"
+ alternate-fname file-name
+ t t 2)))
+ (setq file-name
+ (replace-regexp-in-string "\\\\\\([#%]\\)"
+ "\\1" file-name t))
+ (setq file-name (concat remote file-name)))
+ file-name)
+
+(defun evil-ex-file-arg ()
+ "Returns the current Ex argument as a file name.
+This function interprets special file names like # and %."
+ (unless (zerop (length evil-ex-argument))
+ (evil-ex-replace-special-filenames evil-ex-argument)))
+
+(defun evil-ex-repeat (count)
+ "Repeats the last ex command."
+ (interactive "P")
+ (when count
+ (goto-char (point-min))
+ (forward-line (1- count)))
+ (let ((evil-ex-current-buffer (current-buffer))
+ (hist evil-ex-history))
+ (while hist
+ (let ((evil-ex-last-cmd (pop hist)))
+ (when evil-ex-last-cmd
+ (evil-ex-update nil nil nil evil-ex-last-cmd)
+ (let ((binding (evil-ex-binding evil-ex-cmd)))
+ (unless (eq binding #'evil-ex-repeat)
+ (setq hist nil)
+ (if evil-ex-expression
+ (eval evil-ex-expression)
+ (user-error "Ex: syntax error")))))))))
+
+(defun evil-ex-call-command (range command argument)
+ "Execute the given command COMMAND."
+ (let* ((count (when (numberp range) range))
+ (range (when (evil-range-p range) range))
+ (bang (and (save-match-data (string-match ".!$" command)) t))
+ (evil-ex-point (point))
+ (evil-ex-range
+ (or range (and count (evil-ex-range count count))))
+ (evil-ex-command (evil-ex-completed-binding command))
+ (restore-point (when (evil-get-command-property evil-ex-command :restore-point)
+ (min (point) (or (mark) most-positive-fixnum))))
+ (evil-ex-bang (and bang t))
+ (evil-ex-argument (copy-sequence argument))
+ (evil-this-type (evil-type evil-ex-range))
+ (current-prefix-arg count)
+ (prefix-arg current-prefix-arg))
+ (when (stringp evil-ex-argument)
+ (set-text-properties
+ 0 (length evil-ex-argument) nil evil-ex-argument))
+ (let ((buf (current-buffer)))
+ (unwind-protect
+ (cond
+ ((not evil-ex-range)
+ (setq this-command evil-ex-command)
+ (evil-exit-visual-state)
+ (run-hooks 'pre-command-hook)
+ (call-interactively evil-ex-command)
+ (run-hooks 'post-command-hook))
+ (t
+ ;; set visual selection to match the region if an explicit
+ ;; range has been specified
+ (let ((ex-range (evil-copy-range evil-ex-range))
+ beg end)
+ (evil-expand-range ex-range)
+ (setq beg (evil-range-beginning ex-range)
+ end (evil-range-end ex-range))
+ (evil-sort beg end)
+ (setq this-command evil-ex-command)
+ (run-hooks 'pre-command-hook)
+ (set-mark end)
+ (goto-char beg)
+ (activate-mark)
+ (call-interactively evil-ex-command)
+ (run-hooks 'post-command-hook)
+ (when restore-point (goto-char restore-point)))))
+ (when (buffer-live-p buf)
+ (with-current-buffer buf
+ (deactivate-mark)))))))
+
+(defun evil-ex-line (base &optional offset)
+ "Return the line number of BASE plus OFFSET."
+ (+ (or base (line-number-at-pos))
+ (or offset 0)))
+
+(defun evil-ex-first-line ()
+ "Return the line number of the first line."
+ (line-number-at-pos (point-min)))
+
+(defun evil-ex-current-line ()
+ "Return the line number of the current line."
+ (line-number-at-pos (point)))
+
+(defun evil-ex-last-line ()
+ "Return the line number of the last line."
+ (save-excursion
+ (goto-char (point-max))
+ (when (bolp)
+ (forward-line -1))
+ (line-number-at-pos)))
+
+(defun evil-ex-range (beg-line &optional end-line)
+ "Returns the first and last position of the current range."
+ (evil-range
+ (evil-line-position beg-line)
+ (evil-line-position (or end-line beg-line) -1)
+ 'line
+ :expanded t))
+
+(defun evil-ex-full-range ()
+ "Return a range encompassing the whole buffer."
+ (evil-range (point-min) (point-max) 'line))
+
+(defun evil-ex-last-visual-range ()
+ "Return a linewise range of the last visual selection."
+ (evil-line-expand evil-visual-mark evil-visual-point))
+
+(defun evil-ex-marker (marker)
+ "Return MARKER's line number in the current buffer.
+Signal an error if MARKER is in a different buffer."
+ (when (stringp marker)
+ (setq marker (aref marker 0)))
+ (setq marker (evil-get-marker marker))
+ (if (numberp marker)
+ (line-number-at-pos marker)
+ (user-error "Ex does not support markers in other files")))
+
+(defun evil-ex-char-marker-range (beg end)
+ (when (stringp beg) (setq beg (aref beg 0)))
+ (when (stringp end) (setq end (aref end 0)))
+ (setq beg (evil-get-marker beg)
+ end (evil-get-marker end))
+ (if (and (numberp beg) (numberp end))
+ (evil-expand-range
+ (evil-range beg end
+ (if (evil-visual-state-p)
+ (evil-visual-type)
+ 'inclusive)))
+ (user-error "Ex does not support markers in other files")))
+
+(defun evil-ex-re-fwd (pattern)
+ "Search forward for PATTERN.
+Returns the line number of the match."
+ (condition-case err
+ (save-match-data
+ (save-excursion
+ (set-text-properties 0 (length pattern) nil pattern)
+ (evil-move-end-of-line)
+ (if (re-search-forward pattern nil t)
+ (line-number-at-pos (1- (match-end 0)))
+ (goto-char (point-min))
+ (and (re-search-forward pattern nil t)
+ (line-number-at-pos (1- (match-end 0)))))))
+ (invalid-regexp
+ (evil-ex-echo (cadr err))
+ nil)))
+
+(defun evil-ex-re-bwd (pattern)
+ "Search backward for PATTERN.
+Returns the line number of the match."
+ (condition-case err
+ (save-match-data
+ (save-excursion
+ (set-text-properties 0 (length pattern) nil pattern)
+ (evil-move-beginning-of-line)
+ (if (re-search-backward pattern nil t)
+ (line-number-at-pos (match-beginning 0))
+ (goto-char (point-max))
+ (and (re-search-backward pattern nil t)
+ (line-number-at-pos (match-beginning 0))))))
+ (invalid-regexp
+ (evil-ex-echo (cadr err))
+ nil)))
+
+(defun evil-ex-prev-search ()
+ (error "Previous search not yet implemented"))
+
+(defun evil-ex-signed-number (sign &optional number)
+ "Return a signed number like -3 and +1.
+NUMBER defaults to 1."
+ (funcall sign (or number 1)))
+
+;; function `evil-ex-eval' has been superseded by `evil-ex-parse' plus `eval'
+(make-obsolete 'evil-ex-eval 'evil-ex-parse "1.2.14")
+
+(defun evil-ex-parse (string &optional syntax start)
+ "Parse STRING as an Ex expression and return an evaluation tree.
+If SYNTAX is non-nil, return a syntax tree instead.
+START is the start symbol, which defaults to `expression'."
+ (let* ((start (or start (car-safe (car-safe evil-ex-grammar))))
+ (match (evil-parser
+ string start evil-ex-grammar t syntax)))
+ (car-safe match)))
+
+(defun evil-ex-parse-command (string)
+ "Parse STRING as an Ex binding."
+ (let ((result (evil-parser string 'binding evil-ex-grammar))
+ bang command)
+ (when result
+ (setq command (car-safe result)
+ string (cdr-safe result))
+ ;; check whether the parsed command is followed by a slash, dash
+ ;; or number and either the part before is NOT known to be a binding,
+ ;; or the complete string IS known to be a binding
+ (when (and (> (length string) 0)
+ (string-match-p "^[-/[:digit:]]" string)
+ (or (evil-ex-binding (concat command string) t)
+ (not (evil-ex-binding command t))))
+ (setq result (evil-parser (concat command string)
+ 'emacs-binding
+ evil-ex-grammar)
+ command (car-safe result)
+ string (cdr-safe result)))
+ ;; parse a following "!" as bang only if
+ ;; the command has the property :ex-bang t
+ (when (evil-ex-command-force-p command)
+ (setq result (evil-parser string 'bang evil-ex-grammar)
+ bang (or (car-safe result) "")
+ string (cdr-safe result)
+ command (concat command bang)))
+ (cons command string))))
+
+(defun evil-ex-command-force-p (command)
+ "Whether COMMAND accepts the bang argument."
+ (let ((binding (evil-ex-completed-binding command t)))
+ (when binding
+ (evil-get-command-property binding :ex-bang))))
+
+(defun evil-flatten-syntax-tree (tree)
+ "Find all paths from the root of TREE to its leaves.
+TREE is a syntax tree, i.e., all its leave nodes are strings.
+The `nth' element in the result is the syntactic context
+for the corresponding string index (counted from zero)."
+ (let* ((result nil)
+ (traverse nil)
+ (traverse
+ #'(lambda (tree path)
+ (if (stringp tree)
+ (dotimes (char (length tree))
+ (push path result))
+ (let ((path (cons (car tree) path)))
+ (dolist (subtree (cdr tree))
+ (funcall traverse subtree path)))))))
+ (funcall traverse tree nil)
+ (nreverse result)))
+
+(defun evil-ex-syntactic-context (&optional pos)
+ "Return the syntactical context of the character at POS.
+POS defaults to the current position of point."
+ (let* ((contexts (evil-flatten-syntax-tree evil-ex-tree))
+ (length (length contexts))
+ (pos (- (or pos (point)) (minibuffer-prompt-end))))
+ (when (>= pos length)
+ (setq pos (1- length)))
+ (when (< pos 0)
+ (setq pos 0))
+ (when contexts
+ (nth pos contexts))))
+
+(defun evil-parser--dexp (obj)
+ "Parse a numerical dollar-sign symbol.
+Given e.g. $4, return 4."
+ (when (symbolp obj)
+ (let ((str (symbol-name obj)))
+ (save-match-data
+ (when (string-match "\\$\\([0-9]+\\)" str)
+ (string-to-number (match-string 1 str)))))))
+
+(defun evil-parser--dval (obj result)
+ "Substitute all dollar-sign symbols in OBJ.
+Each dollar-sign symbol is replaced with the corresponding
+element in RESULT, so that $1 becomes the first element, etc.
+The special value $0 is substituted with the whole list RESULT.
+If RESULT is not a list, all dollar-sign symbols are substituted with
+RESULT."
+ (if (listp obj)
+ (mapcar (lambda (obj) (evil-parser--dval obj result)) obj)
+ (let ((num (evil-parser--dexp obj)))
+ (if num
+ (if (not (listp result))
+ result
+ (if (eq num 0)
+ `(list ,@result)
+ (nth (1- num) result)))
+ obj))))
+
+(defun evil-parser (string symbol grammar &optional greedy syntax)
+ "Parse STRING as a SYMBOL in GRAMMAR.
+If GREEDY is non-nil, the whole of STRING must match.
+If the parse succeeds, the return value is a cons cell
+\(RESULT . TAIL), where RESULT is a parse tree and TAIL is
+the remainder of STRING. Otherwise, the return value is nil.
+
+GRAMMAR is an association list of symbols and their definitions.
+A definition is either a list of production rules, which are
+tried in succession, or a #'-quoted function, which is called
+to parse the input.
+
+A production rule can be one of the following:
+
+ nil matches the empty string.
+ A regular expression matches a substring.
+ A symbol matches a production for that symbol.
+ (X Y) matches X followed by Y.
+ (\\? X) matches zero or one of X.
+ (* X) matches zero or more of X.
+ (+ X) matches one or more of X.
+ (& X) matches X, but does not consume.
+ (! X) matches anything but X, but does not consume.
+
+Thus, a simple grammar may look like:
+
+ ((plus \"\\\\+\") ; plus <- \"+\"
+ (minus \"-\") ; minus <- \"-\"
+ (operator plus minus)) ; operator <- plus / minus
+
+All input-consuming rules have a value. A regular expression evaluates
+to the text matched, while a list evaluates to a list of values.
+The value of a list may be overridden with a semantic action, which is
+specified with a #'-quoted expression at the end:
+
+ (X Y #'foo)
+
+The value of this rule is the result of calling foo with the values
+of X and Y as arguments. Alternatively, the function call may be
+specified explicitly:
+
+ (X Y #'(foo $1 $2))
+
+Here, $1 refers to X and $2 refers to Y. $0 refers to the whole list.
+Dollar expressions can also be used directly:
+
+ (X Y #'$1)
+
+This matches X followed by Y, but ignores the value of Y;
+the value of the list is the same as the value of X.
+
+If the SYNTAX argument is non-nil, then all semantic actions
+are ignored, and a syntax tree is constructed instead. The
+syntax tree obeys the property that all the leave nodes are
+parts of the input string. Thus, by traversing the syntax tree,
+one can determine how each character was parsed.
+
+The following symbols have reserved meanings within a grammar:
+`\\?', `*', `+', `&', `!', `function', `alt', `seq' and nil."
+ (let ((string (or string ""))
+ func pair result rules tail)
+ (cond
+ ;; epsilon
+ ((member symbol '("" nil))
+ (setq pair (cons (if syntax "" nil) string)))
+ ;; token
+ ((stringp symbol)
+ (save-match-data
+ (when (or (eq (string-match symbol string) 0)
+ ;; ignore leading whitespace
+ (and (eq (string-match "^[ \f\t\n\r\v]+" string) 0)
+ (eq (match-end 0)
+ (string-match
+ symbol string (match-end 0)))))
+ (setq result (match-string 0 string)
+ tail (substring string (match-end 0))
+ pair (cons result tail))
+ (when (and syntax pair)
+ (setq result (substring string 0
+ (- (length string)
+ (length tail))))
+ (setcar pair result)))))
+ ;; symbol
+ ((symbolp symbol)
+ (let ((context symbol))
+ (setq rules (cdr-safe (assq symbol grammar)))
+ (setq pair (evil-parser string `(alt ,@rules)
+ grammar greedy syntax))
+ (when (and syntax pair)
+ (setq result (car pair))
+ (if (and (listp result) (sequencep (car result)))
+ (setq result `(,symbol ,@result))
+ (setq result `(,symbol ,result)))
+ (setcar pair result))))
+ ;; function
+ ((eq (car-safe symbol) 'function)
+ (setq symbol (cadr symbol)
+ pair (funcall symbol string))
+ (when (and syntax pair)
+ (setq tail (or (cdr pair) "")
+ result (substring string 0
+ (- (length string)
+ (length tail))))
+ (setcar pair result)))
+ ;; list
+ ((listp symbol)
+ (setq rules symbol
+ symbol (car-safe rules))
+ (if (memq symbol '(& ! \? * + alt seq))
+ (setq rules (cdr rules))
+ (setq symbol 'seq))
+ (when (and (memq symbol '(+ alt seq))
+ (> (length rules) 1))
+ (setq func (car (last rules)))
+ (if (eq (car-safe func) 'function)
+ (setq rules (delq func (copy-sequence rules))
+ func (cadr func))
+ (setq func nil)))
+ (cond
+ ;; positive lookahead
+ ((eq symbol '&)
+ (when (evil-parser string rules grammar greedy syntax)
+ (setq pair (evil-parser string nil grammar nil syntax))))
+ ;; negative lookahead
+ ((eq symbol '!)
+ (unless (evil-parser string rules grammar greedy syntax)
+ (setq pair (evil-parser string nil grammar nil syntax))))
+ ;; zero or one
+ ((eq symbol '\?)
+ (setq rules (if (> (length rules) 1)
+ `(alt ,rules nil)
+ `(alt ,@rules nil))
+ pair (evil-parser string rules grammar greedy syntax)))
+ ;; zero or more
+ ((eq symbol '*)
+ (setq rules `(alt (+ ,@rules) nil)
+ pair (evil-parser string rules grammar greedy syntax)))
+ ;; one or more
+ ((eq symbol '+)
+ (let (current results)
+ (catch 'done
+ (while (setq current (evil-parser
+ string rules grammar nil syntax))
+ (setq result (car-safe current)
+ tail (or (cdr-safe current) "")
+ results (append results (if syntax result
+ (cdr-safe result))))
+ ;; stop if stuck
+ (if (equal string tail)
+ (throw 'done nil)
+ (setq string tail))))
+ (when results
+ (setq func (or func 'list)
+ pair (cons results tail)))))
+ ;; alternatives
+ ((eq symbol 'alt)
+ (catch 'done
+ (dolist (rule rules)
+ (when (setq pair (evil-parser
+ string rule grammar greedy syntax))
+ (throw 'done pair)))))
+ ;; sequence
+ (t
+ (setq func (or func 'list))
+ (let ((last (car-safe (last rules)))
+ current results rule)
+ (catch 'done
+ (while rules
+ (setq rule (pop rules)
+ current (evil-parser string rule grammar
+ (when greedy
+ (null rules))
+ syntax))
+ (cond
+ ((null current)
+ (setq results nil)
+ (throw 'done nil))
+ (t
+ (setq result (car-safe current)
+ tail (cdr-safe current))
+ (unless (memq (car-safe rule) '(& !))
+ (if (and syntax
+ (or (null result)
+ (and (listp result)
+ (listp rule)
+ ;; splice in single-element
+ ;; (\? ...) expressions
+ (not (and (eq (car-safe rule) '\?)
+ (eq (length rule) 2))))))
+ (setq results (append results result))
+ (setq results (append results (list result)))))
+ (setq string (or tail ""))))))
+ (when results
+ (setq pair (cons results tail))))))
+ ;; semantic action
+ (when (and pair func (not syntax))
+ (setq result (car pair))
+ (cond
+ ((null func)
+ (setq result nil))
+ ;; lambda function
+ ((eq (car-safe func) 'lambda)
+ (if (memq symbol '(+ seq))
+ (setq result `(funcall ,func ,@result))
+ (setq result `(funcall ,func ,result))))
+ ;; string replacement
+ ((or (stringp func) (stringp (car-safe func)))
+ (let* ((symbol (or (car-safe (cdr-safe func))
+ (and (boundp 'context) context)
+ (car-safe (car-safe grammar))))
+ (string (if (stringp func) func (car-safe func))))
+ (setq result (car-safe (evil-parser string symbol grammar
+ greedy syntax)))))
+ ;; dollar expression
+ ((evil-parser--dexp func)
+ (setq result (evil-parser--dval func result)))
+ ;; function call
+ ((listp func)
+ (setq result (evil-parser--dval func result)))
+ ;; symbol
+ (t
+ (if (memq symbol '(+ seq))
+ (setq result `(,func ,@result))
+ (setq result `(,func ,result)))))
+ (setcar pair result))))
+ ;; weed out incomplete matches
+ (when pair
+ (if (not greedy) pair
+ (if (null (cdr pair)) pair
+ ;; ignore trailing whitespace
+ (when (save-match-data (string-match "^[ \f\t\n\r\v]*$" (cdr pair)))
+ (unless syntax (setcdr pair nil))
+ pair))))))
+
+(provide 'evil-ex)
+
+;;; evil-ex.el ends here
diff --git a/elpa/evil-20220503.1314/evil-ex.elc b/elpa/evil-20220503.1314/evil-ex.elc
new file mode 100644
index 0000000..b3a1118
--- /dev/null
+++ b/elpa/evil-20220503.1314/evil-ex.elc
Binary files differ
diff --git a/elpa/evil-20220503.1314/evil-integration.el b/elpa/evil-20220503.1314/evil-integration.el
new file mode 100644
index 0000000..03fc3cf
--- /dev/null
+++ b/elpa/evil-20220503.1314/evil-integration.el
@@ -0,0 +1,511 @@
+;;; evil-integration.el --- Integrate Evil with other modules -*- lexical-binding: t -*-
+
+;; Author: Vegard Øye <vegard_oye at hotmail.com>
+;; Maintainer: Vegard Øye <vegard_oye at hotmail.com>
+
+;; Version: 1.15.0
+
+;;
+;; This file is NOT part of GNU Emacs.
+
+;;; License:
+
+;; This file is part of Evil.
+;;
+;; Evil 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.
+;;
+;; Evil 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 Evil. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This provides evil integration for various emacs modes.
+;; Additional keybindings (or default state) should go into evil-keybindings.el.
+
+;;; Code:
+
+(require 'evil-maps)
+(require 'evil-core)
+(require 'evil-macros)
+(require 'evil-types)
+(require 'evil-repeat)
+
+;;; Evilize some commands
+
+;; unbound keys should be ignored
+(evil-declare-ignore-repeat 'undefined)
+
+(mapc #'(lambda (cmd)
+ (evil-set-command-property cmd :keep-visual t)
+ (evil-declare-not-repeat cmd))
+ '(digit-argument
+ negative-argument
+ universal-argument
+ universal-argument-minus
+ universal-argument-more
+ universal-argument-other-key))
+(mapc #'evil-declare-not-repeat
+ '(what-cursor-position))
+(mapc #'evil-declare-change-repeat
+ '(dabbrev-expand
+ hippie-expand
+ quoted-insert))
+(mapc #'evil-declare-abort-repeat
+ '(balance-windows
+ eval-expression
+ execute-extended-command
+ exit-minibuffer
+ compile
+ delete-window
+ delete-other-windows
+ find-file-at-point
+ ffap-other-window
+ recompile
+ redo
+ save-buffer
+ split-window
+ split-window-horizontally
+ split-window-vertically
+ undo
+ undo-tree-redo
+ undo-tree-undo))
+
+(evil-set-type #'previous-line 'line)
+(evil-set-type #'next-line 'line)
+
+(dolist (cmd '(keyboard-quit keyboard-escape-quit))
+ (evil-set-command-property cmd :suppress-operator t))
+
+;;; Mouse
+(evil-declare-insert-at-point-repeat 'mouse-yank-primary)
+(evil-declare-insert-at-point-repeat 'mouse-yank-secondary)
+
+;;; key-binding
+
+;; Calling `keyboard-quit' should cancel repeat
+(defadvice keyboard-quit (before evil activate)
+ (when (fboundp 'evil-repeat-abort)
+ (evil-repeat-abort)))
+
+(eval-after-load 'wdired
+ '(progn
+ (add-hook 'wdired-mode-hook #'evil-change-to-initial-state)
+ (defadvice wdired-change-to-dired-mode (after evil activate)
+ (evil-change-to-initial-state nil t))))
+
+;;; Parentheses
+
+(defadvice show-paren-function (around evil disable)
+ "Match parentheses in Normal state."
+ (if (if (memq 'not evil-highlight-closing-paren-at-point-states)
+ (memq evil-state evil-highlight-closing-paren-at-point-states)
+ (not (memq evil-state evil-highlight-closing-paren-at-point-states)))
+ ad-do-it
+ (let ((pos (point)) syntax narrow)
+ (setq pos
+ (catch 'end
+ (dotimes (var (1+ (* 2 evil-show-paren-range)))
+ (if (zerop (mod var 2))
+ (setq pos (+ pos var))
+ (setq pos (- pos var)))
+ (setq syntax (syntax-class (syntax-after pos)))
+ (cond
+ ((eq syntax 4)
+ (setq narrow pos)
+ (throw 'end pos))
+ ((eq syntax 5)
+ (throw 'end (1+ pos)))))))
+ (if pos
+ (save-excursion
+ (goto-char pos)
+ (save-restriction
+ (when narrow
+ (narrow-to-region narrow (point-max)))
+ ad-do-it))
+ ;; prevent the preceding pair from being highlighted
+ (dolist (ov '(show-paren--overlay
+ show-paren--overlay-1
+ show-paren-overlay
+ show-paren-overlay-1))
+ (let ((ov (and (boundp ov) (symbol-value ov))))
+ (when (overlayp ov) (delete-overlay ov))))))))
+
+;;; Undo tree
+(eval-after-load 'undo-tree
+ '(with-no-warnings
+ (defadvice undo-tree-visualize (after evil activate)
+ "Initialize Evil in the visualization buffer."
+ (when evil-local-mode
+ (evil-initialize-state)))
+
+ (when (fboundp 'undo-tree-visualize)
+ (evil-ex-define-cmd "undol[ist]" 'undo-tree-visualize)
+ (evil-ex-define-cmd "ul" 'undo-tree-visualize))
+
+ (when (boundp 'undo-tree-visualizer-mode-map)
+ (define-key undo-tree-visualizer-mode-map
+ [remap evil-backward-char] 'undo-tree-visualize-switch-branch-left)
+ (define-key undo-tree-visualizer-mode-map
+ [remap evil-forward-char] 'undo-tree-visualize-switch-branch-right)
+ (define-key undo-tree-visualizer-mode-map
+ [remap evil-next-line] 'undo-tree-visualize-redo)
+ (define-key undo-tree-visualizer-mode-map
+ [remap evil-previous-line] 'undo-tree-visualize-undo)
+ (define-key undo-tree-visualizer-mode-map
+ [remap evil-ret] 'undo-tree-visualizer-set))
+
+ (when (boundp 'undo-tree-visualizer-selection-mode-map)
+ (define-key undo-tree-visualizer-selection-mode-map
+ [remap evil-backward-char] 'undo-tree-visualizer-select-left)
+ (define-key undo-tree-visualizer-selection-mode-map
+ [remap evil-forward-char] 'undo-tree-visualizer-select-right)
+ (define-key undo-tree-visualizer-selection-mode-map
+ [remap evil-next-line] 'undo-tree-visualizer-select-next)
+ (define-key undo-tree-visualizer-selection-mode-map
+ [remap evil-previous-line] 'undo-tree-visualizer-select-previous)
+ (define-key undo-tree-visualizer-selection-mode-map
+ [remap evil-ret] 'undo-tree-visualizer-set))))
+
+;;; Auto-complete
+(eval-after-load 'auto-complete
+ '(progn
+ (evil-add-command-properties 'auto-complete :repeat 'evil-ac-repeat)
+ (evil-add-command-properties 'ac-complete :repeat 'evil-ac-repeat)
+ (evil-add-command-properties 'ac-expand :repeat 'evil-ac-repeat)
+ (evil-add-command-properties 'ac-next :repeat 'ignore)
+ (evil-add-command-properties 'ac-previous :repeat 'ignore)
+
+ (defvar evil-ac-prefix-len nil
+ "The length of the prefix of the current item to be completed.")
+
+ (defvar ac-prefix)
+ (defun evil-ac-repeat (flag)
+ "Record the changes for auto-completion."
+ (cond
+ ((eq flag 'pre)
+ (setq evil-ac-prefix-len (length ac-prefix))
+ (evil-repeat-start-record-changes))
+ ((eq flag 'post)
+ ;; Add change to remove the prefix
+ (evil-repeat-record-change (- evil-ac-prefix-len)
+ ""
+ evil-ac-prefix-len)
+ ;; Add change to insert the full completed text
+ (evil-repeat-record-change
+ (- evil-ac-prefix-len)
+ (buffer-substring-no-properties (- evil-repeat-pos
+ evil-ac-prefix-len)
+ (point))
+ 0)
+ ;; Finish repeation
+ (evil-repeat-finish-record-changes))))))
+
+;;; Company
+(eval-after-load 'company
+ '(progn
+ (mapc #'evil-declare-change-repeat
+ '(company-complete-mouse
+ company-complete-number
+ company-complete-selection
+ company-complete-common))
+
+ (mapc #'evil-declare-ignore-repeat
+ '(company-abort
+ company-select-next
+ company-select-previous
+ company-select-next-or-abort
+ company-select-previous-or-abort
+ company-select-mouse
+ company-show-doc-buffer
+ company-show-location
+ company-search-candidates
+ company-filter-candidates))))
+
+;; Eval last sexp
+(cond
+ ((version< emacs-version "25")
+ (defadvice preceding-sexp (around evil activate)
+ "In normal-state or motion-state, last sexp ends at point."
+ (if (and (not evil-move-beyond-eol)
+ (or (evil-normal-state-p) (evil-motion-state-p)))
+ (save-excursion
+ (unless (or (eobp) (eolp)) (forward-char))
+ ad-do-it)
+ ad-do-it))
+
+ (defadvice pp-last-sexp (around evil activate)
+ "In normal-state or motion-state, last sexp ends at point."
+ (if (and (not evil-move-beyond-eol)
+ (or (evil-normal-state-p) (evil-motion-state-p)))
+ (save-excursion
+ (unless (or (eobp) (eolp)) (forward-char))
+ ad-do-it)
+ ad-do-it)))
+ (t
+ (defun evil--preceding-sexp (command &rest args)
+ "In normal-state or motion-state, last sexp ends at point."
+ (if (and (not evil-move-beyond-eol)
+ (or (evil-normal-state-p) (evil-motion-state-p)))
+ (save-excursion
+ (unless (or (eobp) (eolp)) (forward-char))
+ (apply command args))
+ (apply command args)))
+
+ (advice-add 'elisp--preceding-sexp :around 'evil--preceding-sexp '((name . evil)))
+ (advice-add 'pp-last-sexp :around 'evil--preceding-sexp '((name . evil)))))
+
+;; Show key
+(defadvice quail-show-key (around evil activate)
+ "Temporarily go to Emacs state"
+ (evil-with-state emacs ad-do-it))
+
+(defadvice describe-char (around evil activate)
+ "Temporarily go to Emacs state"
+ (evil-with-state emacs ad-do-it))
+
+;; ace-jump-mode
+(declare-function ace-jump-char-mode "ext:ace-jump-mode")
+(declare-function ace-jump-word-mode "ext:ace-jump-mode")
+(declare-function ace-jump-line-mode "ext:ace-jump-mode")
+(defvar ace-jump-mode-scope)
+
+(defvar evil-ace-jump-active nil)
+
+(defmacro evil-enclose-ace-jump-for-motion (&rest body)
+ "Enclose ace-jump to make it suitable for motions.
+This includes restricting `ace-jump-mode' to the current window
+in visual and operator state, deactivating visual updates, saving
+the mark and entering `recursive-edit'."
+ (declare (indent defun)
+ (debug t))
+ `(let ((old-mark (mark))
+ (ace-jump-mode-scope
+ (if (and (not (memq evil-state '(visual operator)))
+ (boundp 'ace-jump-mode-scope))
+ ace-jump-mode-scope
+ 'window)))
+ (remove-hook 'pre-command-hook #'evil-visual-pre-command t)
+ (remove-hook 'post-command-hook #'evil-visual-post-command t)
+ (unwind-protect
+ (let ((evil-ace-jump-active 'prepare))
+ (add-hook 'ace-jump-mode-end-hook
+ #'evil-ace-jump-exit-recursive-edit)
+ ,@body
+ (when evil-ace-jump-active
+ (setq evil-ace-jump-active t)
+ (recursive-edit)))
+ (remove-hook 'post-command-hook
+ #'evil-ace-jump-exit-recursive-edit)
+ (remove-hook 'ace-jump-mode-end-hook
+ #'evil-ace-jump-exit-recursive-edit)
+ (if (evil-visual-state-p)
+ (progn
+ (add-hook 'pre-command-hook #'evil-visual-pre-command nil t)
+ (add-hook 'post-command-hook #'evil-visual-post-command nil t)
+ (set-mark old-mark))
+ (push-mark old-mark)))))
+
+(eval-after-load 'ace-jump-mode
+ `(defadvice ace-jump-done (after evil activate)
+ (when evil-ace-jump-active
+ (add-hook 'post-command-hook #'evil-ace-jump-exit-recursive-edit))))
+
+(defun evil-ace-jump-exit-recursive-edit ()
+ "Exit a recursive edit caused by an evil jump."
+ (cond
+ ((eq evil-ace-jump-active 'prepare)
+ (setq evil-ace-jump-active nil))
+ (evil-ace-jump-active
+ (remove-hook 'post-command-hook #'evil-ace-jump-exit-recursive-edit)
+ (exit-recursive-edit))))
+
+(evil-define-motion evil-ace-jump-char-mode (count)
+ "Jump visually directly to a char using ace-jump."
+ :type inclusive
+ (evil-without-repeat
+ (let ((pnt (point))
+ (buf (current-buffer)))
+ (evil-enclose-ace-jump-for-motion
+ (call-interactively 'ace-jump-char-mode))
+ ;; if we jump backwards, motion type is exclusive, analogously
+ ;; to `evil-find-char-backward'
+ (when (and (equal buf (current-buffer))
+ (< (point) pnt))
+ (setq evil-this-type
+ (cond
+ ((eq evil-this-type 'exclusive) 'inclusive)
+ ((eq evil-this-type 'inclusive) 'exclusive)))))))
+
+(evil-define-motion evil-ace-jump-char-to-mode (count)
+ "Jump visually to the char in front of a char using ace-jump."
+ :type inclusive
+ (evil-without-repeat
+ (let ((pnt (point))
+ (buf (current-buffer)))
+ (evil-enclose-ace-jump-for-motion
+ (call-interactively 'ace-jump-char-mode))
+ (if (and (equal buf (current-buffer))
+ (< (point) pnt))
+ (progn
+ (or (eobp) (forward-char))
+ (setq evil-this-type
+ (cond
+ ((eq evil-this-type 'exclusive) 'inclusive)
+ ((eq evil-this-type 'inclusive) 'exclusive))))
+ (backward-char)))))
+
+(evil-define-motion evil-ace-jump-line-mode (count)
+ "Jump visually to the beginning of a line using ace-jump."
+ :type line
+ :repeat abort
+ (evil-without-repeat
+ (evil-enclose-ace-jump-for-motion
+ (call-interactively 'ace-jump-line-mode))))
+
+(evil-define-motion evil-ace-jump-word-mode (count)
+ "Jump visually to the beginning of a word using ace-jump."
+ :type exclusive
+ :repeat abort
+ (evil-without-repeat
+ (evil-enclose-ace-jump-for-motion
+ (call-interactively 'ace-jump-word-mode))))
+
+(define-key evil-motion-state-map [remap ace-jump-char-mode] #'evil-ace-jump-char-mode)
+(define-key evil-motion-state-map [remap ace-jump-line-mode] #'evil-ace-jump-line-mode)
+(define-key evil-motion-state-map [remap ace-jump-word-mode] #'evil-ace-jump-word-mode)
+
+;;; avy
+(declare-function avy-goto-word-or-subword-1 "ext:avy")
+(declare-function avy-goto-line "ext:avy")
+(declare-function avy-goto-char "ext:avy")
+(declare-function avy-goto-char-2 "ext:avy")
+(declare-function avy-goto-char-2-above "ext:avy")
+(declare-function avy-goto-char-2-below "ext:avy")
+(declare-function avy-goto-char-in-line "ext:avy")
+(declare-function avy-goto-word-0 "ext:avy")
+(declare-function avy-goto-word-1 "ext:avy")
+(declare-function avy-goto-word-1-above "ext:avy")
+(declare-function avy-goto-word-1-below "ext:avy")
+(declare-function avy-goto-subword-0 "ext:avy")
+(declare-function avy-goto-subword-1 "ext:avy")
+(declare-function avy-goto-char-timer "ext:avy")
+(defvar avy-all-windows)
+
+(defmacro evil-enclose-avy-for-motion (&rest body)
+ "Enclose avy to make it suitable for motions.
+Based on `evil-enclose-ace-jump-for-motion'."
+ (declare (indent defun)
+ (debug t))
+ `(let ((avy-all-windows
+ (if (and (not (memq evil-state '(visual operator)))
+ (boundp 'avy-all-windows))
+ avy-all-windows
+ nil)))
+ ,@body))
+
+(defmacro evil-define-avy-motion (command type)
+ (declare (indent defun)
+ (debug t))
+ (let ((name (intern (format "evil-%s" command))))
+ `(evil-define-motion ,name (count)
+ ,(format "Evil motion for `%s'." command)
+ :type ,type
+ :jump t
+ :repeat abort
+ (evil-without-repeat
+ (evil-enclose-avy-for-motion
+ (call-interactively ',command))))))
+
+;; define evil-avy-* motion commands for avy-* commands
+(evil-define-avy-motion avy-goto-char inclusive)
+(evil-define-avy-motion avy-goto-char-2 inclusive)
+(evil-define-avy-motion avy-goto-char-2-above inclusive)
+(evil-define-avy-motion avy-goto-char-2-below inclusive)
+(evil-define-avy-motion avy-goto-char-in-line inclusive)
+(evil-define-avy-motion avy-goto-char-timer inclusive)
+(evil-define-avy-motion avy-goto-line line)
+(evil-define-avy-motion avy-goto-line-above line)
+(evil-define-avy-motion avy-goto-line-below line)
+(evil-define-avy-motion avy-goto-subword-0 exclusive)
+(evil-define-avy-motion avy-goto-subword-1 exclusive)
+(evil-define-avy-motion avy-goto-symbol-1 exclusive)
+(evil-define-avy-motion avy-goto-symbol-1-above exclusive)
+(evil-define-avy-motion avy-goto-symbol-1-below exclusive)
+(evil-define-avy-motion avy-goto-word-0 exclusive)
+(evil-define-avy-motion avy-goto-word-1 exclusive)
+(evil-define-avy-motion avy-goto-word-1-above exclusive)
+(evil-define-avy-motion avy-goto-word-1-below exclusive)
+(evil-define-avy-motion avy-goto-word-or-subword-1 exclusive)
+
+;; remap avy-* commands to evil-avy-* commands
+(dolist (command '(avy-goto-char
+ avy-goto-char-2
+ avy-goto-char-2-above
+ avy-goto-char-2-below
+ avy-goto-char-in-line
+ avy-goto-char-timer
+ avy-goto-line
+ avy-goto-line-above
+ avy-goto-line-below
+ avy-goto-subword-0
+ avy-goto-subword-1
+ avy-goto-symbol-1
+ avy-goto-symbol-1-above
+ avy-goto-symbol-1-below
+ avy-goto-word-0
+ avy-goto-word-1
+ avy-goto-word-1-above
+ avy-goto-word-1-below
+ avy-goto-word-or-subword-1))
+ (define-key evil-motion-state-map
+ (vector 'remap command) (intern-soft (format "evil-%s" command))))
+
+;;; nXhtml/mumamo
+;; ensure that mumamo does not toggle evil through its globalized mode
+(eval-after-load 'mumamo
+ '(with-no-warnings
+ (push 'evil-mode-cmhh mumamo-change-major-mode-no-nos)))
+
+;; visual-line-mode integration
+(when evil-respect-visual-line-mode
+ (evil-define-minor-mode-key 'motion 'visual-line-mode
+ "j" 'evil-next-visual-line
+ "gj" 'evil-next-line
+ "k" 'evil-previous-visual-line
+ "gk" 'evil-previous-line
+ "0" 'evil-beginning-of-visual-line
+ "g0" 'evil-beginning-of-line
+ "$" 'evil-end-of-visual-line
+ "g$" 'evil-end-of-line
+ "V" 'evil-visual-screen-line))
+
+;;; abbrev.el
+(defun evil-maybe-expand-abbrev ()
+ (when (and abbrev-mode evil-want-abbrev-expand-on-insert-exit)
+ (expand-abbrev)))
+
+(eval-after-load 'abbrev
+ '(add-hook 'evil-insert-state-exit-hook 'evil-maybe-expand-abbrev))
+
+;;; ElDoc
+(eval-after-load 'eldoc
+ '(when (fboundp 'eldoc-add-command-completions)
+ (eldoc-add-command-completions "evil-window-")))
+
+;;; XRef
+(eval-after-load 'xref
+ '(progn
+ (evil-set-command-property 'xref-find-definitions :jump t)
+ (evil-set-command-property 'xref-find-references :jump t)))
+
+(provide 'evil-integration)
+
+;;; evil-integration.el ends here
diff --git a/elpa/evil-20220503.1314/evil-integration.elc b/elpa/evil-20220503.1314/evil-integration.elc
new file mode 100644
index 0000000..fbf91bd
--- /dev/null
+++ b/elpa/evil-20220503.1314/evil-integration.elc
Binary files differ
diff --git a/elpa/evil-20220503.1314/evil-jumps.el b/elpa/evil-20220503.1314/evil-jumps.el
new file mode 100644
index 0000000..fea2e43
--- /dev/null
+++ b/elpa/evil-20220503.1314/evil-jumps.el
@@ -0,0 +1,354 @@
+;;; evil-jumps.el --- Jump list implementation -*- lexical-binding: t -*-
+
+;; Author: Bailey Ling <bling at live.ca>
+
+;; Version: 1.15.0
+
+;;
+;; This file is NOT part of GNU Emacs.
+
+;;; License:
+
+;; This file is part of Evil.
+;;
+;; Evil 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.
+;;
+;; Evil 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 Evil. If not, see <http://www.gnu.org/licenses/>.
+
+(require 'cl-lib)
+(require 'evil-core)
+(require 'evil-states)
+
+;;; Code:
+
+(defgroup evil-jumps nil
+ "Evil jump list configuration options."
+ :prefix "evil-jumps"
+ :group 'evil)
+
+(defcustom evil-jumps-cross-buffers t
+ "When non-nil, the jump commands can cross borders between buffers, otherwise the jump commands act only within the current buffer."
+ :type 'boolean
+ :group 'evil-jumps)
+
+(defcustom evil-jumps-max-length 100
+ "The maximum number of jumps to keep track of."
+ :type 'integer
+ :group 'evil-jumps)
+
+(defcustom evil-jumps-pre-jump-hook nil
+ "Hooks to run just before jumping to a location in the jump list."
+ :type 'hook
+ :group 'evil-jumps)
+
+(defcustom evil-jumps-post-jump-hook nil
+ "Hooks to run just after jumping to a location in the jump list."
+ :type 'hook
+ :group 'evil-jumps)
+
+(defcustom evil-jumps-ignored-file-patterns '("COMMIT_EDITMSG$" "TAGS$")
+ "A list of pattern regexps to match on the file path to exclude from being included in the jump list."
+ :type '(repeat string)
+ :group 'evil-jumps)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defvar savehist-additional-variables)
+
+(defvar evil--jumps-jumping nil)
+
+(defvar evil--jumps-jumping-backward nil
+ "Set by `evil--jump-backward', used and cleared in the
+`post-command-hook' by `evil--jump-handle-buffer-crossing'")
+
+(eval-when-compile (defvar evil--jumps-debug nil))
+
+(defvar evil--jumps-buffer-targets "\\*\\(new\\|scratch\\)\\*"
+ "Regexp to match against `buffer-name' to determine whether it's a valid jump target.")
+
+(defvar evil--jumps-window-jumps (make-hash-table)
+ "Hashtable which stores all jumps on a per window basis.")
+
+(defvar evil-jumps-history nil
+ "History of `evil-mode' jumps that are persisted with `savehist'.")
+
+(cl-defstruct evil-jumps-struct
+ ring
+ (idx -1)
+ previous-pos)
+
+;; Is inlining this really worth it?
+(defsubst evil--jumps-message (format &rest args)
+ (when (eval-when-compile evil--jumps-debug)
+ (with-current-buffer (get-buffer-create "*evil-jumps*")
+ (goto-char (point-max))
+ (insert (apply #'format format args) "\n"))))
+
+(defun evil--jumps-get-current (&optional window)
+ (unless window
+ (setq window (frame-selected-window)))
+ (let* ((jump-struct (gethash window evil--jumps-window-jumps)))
+ (unless jump-struct
+ (setq jump-struct (make-evil-jumps-struct))
+ (puthash window jump-struct evil--jumps-window-jumps))
+ jump-struct))
+
+(defun evil--jumps-get-jumps (struct)
+ (let ((ring (evil-jumps-struct-ring struct)))
+ (unless ring
+ (setq ring (make-ring evil-jumps-max-length))
+ (setf (evil-jumps-struct-ring struct) ring))
+ ring))
+
+(defun evil--jumps-get-window-jump-list ()
+ (let ((struct (evil--jumps-get-current)))
+ (evil--jumps-get-jumps struct)))
+
+(defun evil--jumps-savehist-load ()
+ (add-to-list 'savehist-additional-variables 'evil-jumps-history)
+ (let ((ring (make-ring evil-jumps-max-length)))
+ (cl-loop for jump in (reverse evil-jumps-history)
+ do (ring-insert ring jump))
+ (setf (evil-jumps-struct-ring (evil--jumps-get-current)) ring))
+ (add-hook 'savehist-save-hook #'evil--jumps-savehist-sync)
+ (remove-hook 'savehist-mode-hook #'evil--jumps-savehist-load))
+
+(defun evil--jumps-savehist-sync ()
+ "Updates the printable value of window jumps for `savehist'."
+ (setq evil-jumps-history
+ (delq nil (mapcar #'(lambda (jump)
+ (let* ((mark (car jump))
+ (pos (if (markerp mark)
+ (marker-position mark)
+ mark))
+ (file-name (cadr jump)))
+ (when (and (not (file-remote-p file-name))
+ (file-exists-p file-name)
+ pos)
+ (list pos file-name))))
+ (ring-elements (evil--jumps-get-window-jump-list))))))
+
+(defun evil--jumps-jump (idx shift)
+ (let ((target-list (evil--jumps-get-window-jump-list)))
+ (evil--jumps-message "jumping from %s by %s" idx shift)
+ (evil--jumps-message "target list = %s" target-list)
+ (setq idx (+ idx shift))
+ (let* ((current-file-name (or (buffer-file-name) (buffer-name)))
+ (size (ring-length target-list)))
+ (unless evil-jumps-cross-buffers
+ ;; skip jump marks pointing to other buffers
+ (while (and (< idx size) (>= idx 0)
+ (not (string= current-file-name (cadr (ring-ref target-list idx)))))
+ (setq idx (+ idx shift))))
+ (when (and (< idx size) (>= idx 0))
+ ;; actual jump
+ (run-hooks 'evil-jumps-pre-jump-hook)
+ (let* ((place (ring-ref target-list idx))
+ (pos (car place))
+ (file-name (cadr place)))
+ (setq evil--jumps-jumping t)
+ (unless (string= current-file-name file-name)
+ (if (string-match-p evil--jumps-buffer-targets file-name)
+ (switch-to-buffer file-name)
+ (find-file file-name)))
+ (setq evil--jumps-jumping nil)
+ (goto-char pos)
+ (setf (evil-jumps-struct-idx (evil--jumps-get-current)) idx)
+ (run-hooks 'evil-jumps-post-jump-hook))))))
+
+(defun evil--jumps-push ()
+ "Pushes the current cursor/file position to the jump list."
+ (let ((target-list (evil--jumps-get-window-jump-list)))
+ (let ((file-name (buffer-file-name))
+ (buffer-name (buffer-name))
+ (current-pos (point-marker))
+ (first-pos nil)
+ (first-file-name nil)
+ (excluded nil))
+ (when (and (not file-name)
+ (string-match-p evil--jumps-buffer-targets buffer-name))
+ (setq file-name buffer-name))
+ (when file-name
+ (dolist (pattern evil-jumps-ignored-file-patterns)
+ (when (string-match-p pattern file-name)
+ (setq excluded t)))
+ (unless excluded
+ (unless (ring-empty-p target-list)
+ (setq first-pos (car (ring-ref target-list 0)))
+ (setq first-file-name (car (cdr (ring-ref target-list 0)))))
+ (unless (and (equal first-pos current-pos)
+ (equal first-file-name file-name))
+ (evil--jumps-message "pushing %s on %s" current-pos file-name)
+ (ring-insert target-list `(,current-pos ,file-name))))))
+ (evil--jumps-message "%s %s"
+ (selected-window)
+ (and (not (ring-empty-p target-list))
+ (ring-ref target-list 0)))))
+
+(evil-define-command evil-show-jumps ()
+ "Display the contents of the jump list."
+ :repeat nil
+ (evil-with-view-list
+ :name "evil-jumps"
+ :mode "Evil Jump List"
+ :format [("Jump" 5 nil)
+ ("Marker" 8 nil)
+ ("File/text" 1000 t)]
+ :entries (let* ((jumps (evil--jumps-savehist-sync))
+ (count 0))
+ (cl-loop for jump in jumps
+ collect `(nil [,(number-to-string (cl-incf count))
+ ,(number-to-string (car jump))
+ (,(cadr jump))])))
+ :select-action #'evil--show-jumps-select-action))
+
+(defun evil--show-jumps-select-action (jump)
+ (let ((position (string-to-number (elt jump 1)))
+ (file (car (elt jump 2))))
+ (kill-buffer)
+ (switch-to-buffer (find-file file))
+ (goto-char position)))
+
+(defun evil-set-jump (&optional pos)
+ "Set jump point at POS.
+POS defaults to point."
+ (save-excursion
+ (when (markerp pos)
+ (set-buffer (marker-buffer pos)))
+
+ (unless (or (region-active-p) (evil-visual-state-p))
+ (push-mark pos t))
+
+ (unless evil--jumps-jumping
+ ;; clear out intermediary jumps when a new one is set
+ (let* ((struct (evil--jumps-get-current))
+ (target-list (evil--jumps-get-jumps struct))
+ (idx (evil-jumps-struct-idx struct)))
+ (cl-loop repeat idx
+ do (ring-remove target-list))
+ (setf (evil-jumps-struct-idx struct) -1))
+ (when pos
+ (goto-char pos))
+ (evil--jumps-push))))
+
+(defun evil--jump-backward (count)
+ (setq evil--jumps-jumping-backward t)
+ (let ((count (or count 1)))
+ (evil-motion-loop (nil count)
+ (let* ((struct (evil--jumps-get-current))
+ (idx (evil-jumps-struct-idx struct)))
+ (evil--jumps-message "jumping back %s" idx)
+ (when (= idx -1)
+ (setq idx 0)
+ (setf (evil-jumps-struct-idx struct) 0)
+ (evil--jumps-push))
+ (evil--jumps-jump idx 1)))))
+
+(defun evil--jump-forward (count)
+ (let ((count (or count 1)))
+ (evil-motion-loop (nil count)
+ (let* ((struct (evil--jumps-get-current))
+ (idx (evil-jumps-struct-idx struct)))
+ (when (= idx -1)
+ (setq idx 0)
+ (setf (evil-jumps-struct-idx struct) 0)
+ (evil--jumps-push))
+ (evil--jumps-jump idx -1)))))
+
+(defun evil--jumps-window-configuration-hook (&rest _args)
+ (let* ((window-list (window-list-1 nil nil t))
+ (existing-window (selected-window))
+ (new-window (previous-window)))
+ (when (and (not (eq existing-window new-window))
+ (> (length window-list) 1))
+ (let* ((target-jump-struct (evil--jumps-get-current new-window)))
+ (if (not (ring-empty-p (evil--jumps-get-jumps target-jump-struct)))
+ (evil--jumps-message "target window %s already has %s jumps" new-window
+ (ring-length (evil--jumps-get-jumps target-jump-struct)))
+ (evil--jumps-message "new target window detected; copying %s to %s" existing-window new-window)
+ (let* ((source-jump-struct (evil--jumps-get-current existing-window))
+ (source-list (evil--jumps-get-jumps source-jump-struct)))
+ (when (= (ring-length (evil--jumps-get-jumps target-jump-struct)) 0)
+ (setf (evil-jumps-struct-previous-pos target-jump-struct) (evil-jumps-struct-previous-pos source-jump-struct))
+ (setf (evil-jumps-struct-idx target-jump-struct) (evil-jumps-struct-idx source-jump-struct))
+ (setf (evil-jumps-struct-ring target-jump-struct) (ring-copy source-list)))))))
+ ;; delete obsolete windows
+ (maphash (lambda (key _val)
+ (unless (member key window-list)
+ (evil--jumps-message "removing %s" key)
+ (remhash key evil--jumps-window-jumps)))
+ evil--jumps-window-jumps)))
+
+(defun evil--jump-hook (&optional command)
+ "`pre-command-hook' for evil-jumps.
+Set jump point if COMMAND has a non-nil `:jump' property. Otherwise,
+save the current position in case the command being executed will
+change the current buffer."
+ (setq command (or command this-command))
+ (if (evil-get-command-property command :jump)
+ (evil-set-jump)
+ (setf (evil-jumps-struct-previous-pos (evil--jumps-get-current))
+ (point-marker))))
+
+(defun evil--jump-handle-buffer-crossing ()
+ (let ((jumping-backward evil--jumps-jumping-backward))
+ (setq evil--jumps-jumping-backward nil)
+ (dolist (frame (frame-list))
+ (dolist (window (window-list frame))
+ (let* ((struct (evil--jumps-get-current window))
+ (previous-pos (evil-jumps-struct-previous-pos struct)))
+ (when previous-pos
+ (setf (evil-jumps-struct-previous-pos struct) nil)
+ (if (and
+ ;; `evil-jump-backward' (and other backward jumping
+ ;; commands) needs to be handled specially. When
+ ;; jumping backward multiple times, calling
+ ;; `evil-set-jump' is always wrong: If you jump back
+ ;; twice and we call `evil-set-jump' after the second
+ ;; time, we clear the forward jump list and
+ ;; `evil--jump-forward' won't work.
+
+ ;; The first time you jump backward, setting a jump
+ ;; point is sometimes correct. But we don't do it
+ ;; here because this function is called after
+ ;; `evil--jump-backward' has updated our position in
+ ;; the jump list so, again, `evil-set-jump' would
+ ;; break `evil--jump-forward'.
+ (not jumping-backward)
+ (let ((previous-buffer (marker-buffer previous-pos)))
+ (and previous-buffer
+ (not (eq previous-buffer (window-buffer window))))))
+ (evil-set-jump previous-pos)
+ (set-marker previous-pos nil))))))))
+
+(if (bound-and-true-p savehist-loaded)
+ (evil--jumps-savehist-load)
+ (add-hook 'savehist-mode-hook #'evil--jumps-savehist-load))
+
+(defun evil--jumps-install-or-uninstall ()
+ (if evil-local-mode
+ (progn
+ (add-hook 'pre-command-hook #'evil--jump-hook nil t)
+ (add-hook 'post-command-hook #'evil--jump-handle-buffer-crossing nil t)
+ (add-hook 'next-error-hook #'evil-set-jump nil t)
+ (add-hook 'window-configuration-change-hook #'evil--jumps-window-configuration-hook nil t))
+ (remove-hook 'pre-command-hook #'evil--jump-hook t)
+ (remove-hook 'post-command-hook #'evil--jump-handle-buffer-crossing t)
+ (remove-hook 'next-error-hook #'evil-set-jump t)
+ (remove-hook 'window-configuration-change-hook #'evil--jumps-window-configuration-hook t)
+ (evil--jump-handle-buffer-crossing)))
+
+(add-hook 'evil-local-mode-hook #'evil--jumps-install-or-uninstall)
+
+(provide 'evil-jumps)
+
+;;; evil-jumps.el ends here
diff --git a/elpa/evil-20220503.1314/evil-jumps.elc b/elpa/evil-20220503.1314/evil-jumps.elc
new file mode 100644
index 0000000..bb988b8
--- /dev/null
+++ b/elpa/evil-20220503.1314/evil-jumps.elc
Binary files differ
diff --git a/elpa/evil-20220503.1314/evil-keybindings.el b/elpa/evil-20220503.1314/evil-keybindings.el
new file mode 100644
index 0000000..baafaf8
--- /dev/null
+++ b/elpa/evil-20220503.1314/evil-keybindings.el
@@ -0,0 +1,124 @@
+;;; evil-keybindings.el --- Add some Evil keybindings to other modules -*- lexical-binding: t -*-
+
+;; Author: Vegard Øye <vegard_oye at hotmail.com>
+;; Maintainer: Vegard Øye <vegard_oye at hotmail.com>
+
+;; Version: 1.15.0
+
+;;
+;; This file is NOT part of GNU Emacs.
+
+;;; License:
+
+;; This file is part of Evil.
+;;
+;; Evil 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.
+;;
+;; Evil 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 Evil. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This provides a set of keybindings for other emacs modes. This also includes
+;; setting up the initial evil state of those other modes.
+
+;;; Code:
+
+(require 'evil-maps)
+(require 'evil-core)
+(require 'evil-macros)
+(require 'evil-types)
+(require 'evil-repeat)
+
+;; etags-select
+;; FIXME: probably etags-select should be recomended in docs
+(eval-after-load 'etags-select
+ '(progn
+ (define-key evil-motion-state-map "g]" 'etags-select-find-tag-at-point)))
+
+;;; Buffer-menu
+
+(evil-add-hjkl-bindings Buffer-menu-mode-map 'motion)
+
+;; dictionary.el
+
+(evil-add-hjkl-bindings dictionary-mode-map 'motion
+ "?" 'dictionary-help ; "h"
+ "C-o" 'dictionary-previous) ; "l"
+
+;;; Dired
+
+(eval-after-load 'dired
+ '(progn
+ ;; use the standard Dired bindings as a base
+ (defvar dired-mode-map)
+ (evil-make-overriding-map dired-mode-map 'normal)
+ (evil-add-hjkl-bindings dired-mode-map 'normal
+ "J" 'dired-goto-file ; "j"
+ "K" 'dired-do-kill-lines ; "k"
+ "r" 'dired-do-redisplay ; "l"
+ ;; ":d", ":v", ":s", ":e"
+ ";" (lookup-key dired-mode-map ":"))))
+
+;;; ERT
+
+(evil-add-hjkl-bindings ert-results-mode-map 'motion)
+
+;;; Info
+
+(evil-add-hjkl-bindings Info-mode-map 'motion
+ "0" 'evil-beginning-of-line
+ (kbd "\M-h") 'Info-help ; "h"
+ "\C-t" 'Info-history-back ; "l"
+ "\C-o" 'Info-history-back
+ " " 'Info-scroll-up
+ "\C-]" 'Info-follow-nearest-node
+ (kbd "DEL") 'Info-scroll-down)
+
+;;; Speedbar
+
+(evil-add-hjkl-bindings speedbar-key-map 'motion
+ "h" 'backward-char
+ "j" 'speedbar-next
+ "k" 'speedbar-prev
+ "l" 'forward-char
+ "i" 'speedbar-item-info
+ "r" 'speedbar-refresh
+ "u" 'speedbar-up-directory
+ "o" 'speedbar-toggle-line-expansion
+ (kbd "RET") 'speedbar-edit-line)
+
+;; Ibuffer
+(eval-after-load 'ibuffer
+ '(progn
+ (defvar ibuffer-mode-map)
+ (evil-make-overriding-map ibuffer-mode-map 'normal)
+ (evil-define-key 'normal ibuffer-mode-map
+ "j" 'evil-next-line
+ "k" 'evil-previous-line
+ "RET" 'ibuffer-visit-buffer)))
+
+;;; ag.el
+(eval-after-load 'ag
+ '(progn
+ (defvar ag-mode-map)
+ (add-to-list 'evil-motion-state-modes 'ag-mode)
+ (evil-add-hjkl-bindings ag-mode-map 'motion)))
+
+;;; ELP
+
+(eval-after-load 'elp
+ '(defadvice elp-results (after evil activate)
+ (evil-motion-state)))
+
+(provide 'evil-keybindings)
+
+;;; evil-keybindings.el ends here
diff --git a/elpa/evil-20220503.1314/evil-keybindings.elc b/elpa/evil-20220503.1314/evil-keybindings.elc
new file mode 100644
index 0000000..738c977
--- /dev/null
+++ b/elpa/evil-20220503.1314/evil-keybindings.elc
Binary files differ
diff --git a/elpa/evil-20220503.1314/evil-macros.el b/elpa/evil-20220503.1314/evil-macros.el
new file mode 100644
index 0000000..71bf122
--- /dev/null
+++ b/elpa/evil-20220503.1314/evil-macros.el
@@ -0,0 +1,817 @@
+;;; evil-macros.el --- Macros -*- lexical-binding: t -*-
+
+;; Author: Vegard Øye <vegard_oye at hotmail.com>
+;; Maintainer: Vegard Øye <vegard_oye at hotmail.com>
+
+;; Version: 1.15.0
+
+;;
+;; This file is NOT part of GNU Emacs.
+
+;;; License:
+
+;; This file is part of Evil.
+;;
+;; Evil 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.
+;;
+;; Evil 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 Evil. If not, see <http://www.gnu.org/licenses/>.
+
+(require 'evil-common)
+(require 'evil-states)
+(require 'evil-repeat)
+
+;;; Code:
+
+(declare-function evil-ex-p "evil-ex")
+
+;; set some error codes
+(put 'beginning-of-line 'error-conditions '(beginning-of-line error))
+(put 'beginning-of-line 'error-message "Beginning of line")
+(put 'end-of-line 'error-conditions '(end-of-line error))
+(put 'end-of-line 'error-message "End of line")
+
+(defun evil-motion-range (motion &optional count type)
+ "Execute a motion and return the buffer positions.
+The return value is a list (BEG END TYPE)."
+ (let ((opoint (point))
+ (omark (mark t))
+ (obuffer (current-buffer))
+ (evil-motion-marker (move-marker (make-marker) (point)))
+ range)
+ (evil-with-transient-mark-mode
+ (evil-narrow-to-field
+ (unwind-protect
+ (let ((current-prefix-arg count)
+ ;; Store type in global variable `evil-this-type'.
+ ;; If necessary, motions can change their type
+ ;; during execution by setting this variable.
+ (evil-this-type
+ (or type (evil-type motion 'exclusive))))
+ (condition-case err
+ (let ((repeat-type (evil-repeat-type motion t)))
+ (if (functionp repeat-type)
+ (funcall repeat-type 'pre))
+ (unless (with-local-quit
+ (setq range (call-interactively motion))
+ t)
+ (evil-repeat-abort)
+ (setq quit-flag t))
+ (if (functionp repeat-type)
+ (funcall repeat-type 'post)))
+ (error (prog1 nil
+ (evil-repeat-abort)
+ ;; some operators depend on succeeding
+ ;; motions, in particular for
+ ;; `evil-forward-char' (e.g., used by
+ ;; `evil-substitute'), therefore we let
+ ;; end-of-line and end-of-buffer pass
+ (if (not (memq (car err) '(end-of-line end-of-buffer)))
+ (signal (car err) (cdr err))
+ (message (error-message-string err))))))
+ (cond
+ ;; the motion returned a range
+ ((evil-range-p range))
+ ;; the motion made a Visual selection
+ ((evil-visual-state-p)
+ (setq range (evil-visual-range)))
+ ;; the motion made an active region
+ ((region-active-p)
+ (setq range (evil-range (region-beginning)
+ (region-end)
+ evil-this-type)))
+ ;; default: range from previous position to current
+ (t
+ (setq range (evil-expand-range
+ (evil-normalize evil-motion-marker
+ (point)
+ evil-this-type)))))
+ (unless (or (null type) (eq (evil-type range) type))
+ (evil-set-type range type)
+ (evil-expand-range range))
+ (evil-set-range-properties range nil)
+ range)
+ ;; restore point and mark like `save-excursion',
+ ;; but only if the motion hasn't disabled the operator
+ (unless evil-inhibit-operator
+ (set-buffer obuffer)
+ (evil-move-mark omark)
+ (goto-char opoint))
+ ;; delete marker so it doesn't slow down editing
+ (move-marker evil-motion-marker nil))))))
+
+(defmacro evil-define-motion (motion args &rest body)
+ "Define a motion command MOTION.
+ARGS is a list of arguments. Motions can have any number of
+arguments, but the first (if any) has the predefined meaning of
+count. BODY must execute the motion by moving point.
+
+Optional keyword arguments are:
+- `:type' - determines how the motion works after an operator (one of
+ `inclusive', `line', `block' and `exclusive', or a self-defined
+ motion type)
+- `:jump' - if non-nil, the previous position is stored in the jump
+ list, so that it can be restored with \
+\\<evil-motion-state-map>\\[evil-jump-backward]
+
+\(fn MOTION (COUNT ARGS...) DOC [[KEY VALUE]...] BODY...)"
+ (declare (indent defun)
+ (doc-string 3)
+ (debug (&define name lambda-list
+ [&optional stringp]
+ [&rest keywordp sexp]
+ [&optional ("interactive" [&rest form])]
+ def-body)))
+ (let (arg doc interactive key keys)
+ (when args
+ (setq args `(&optional ,@(delq '&optional args))
+ ;; the count is either numerical or nil
+ interactive '("<c>")))
+ ;; collect docstring
+ (when (and (> (length body) 1)
+ (or (eq (car-safe (car-safe body)) 'format)
+ (stringp (car-safe body))))
+ (setq doc (pop body)))
+ ;; collect keywords
+ (setq keys (plist-put keys :repeat 'motion))
+ (while (keywordp (car-safe body))
+ (setq key (pop body)
+ arg (pop body)
+ keys (plist-put keys key arg)))
+ ;; collect `interactive' specification
+ (when (eq (car-safe (car-safe body)) 'interactive)
+ (setq interactive (cdr (pop body))))
+ ;; macro expansion
+ `(progn
+ ;; refresh echo area in Eldoc mode
+ (when ',motion
+ (eval-after-load 'eldoc
+ '(and (fboundp 'eldoc-add-command)
+ (eldoc-add-command ',motion))))
+ (evil-define-command ,motion (,@args)
+ ,@(when doc `(,doc)) ; avoid nil before `interactive'
+ ,@keys
+ :keep-visual t
+ (interactive ,@interactive)
+ ,@body))))
+
+(defmacro evil-narrow-to-line (&rest body)
+ "Narrow BODY to the current line.
+BODY will signal the errors 'beginning-of-line or 'end-of-line
+upon reaching the beginning or end of the current line.
+
+\(fn [[KEY VAL]...] BODY...)"
+ (declare (indent defun)
+ (debug t))
+ `(let* ((range (evil-expand (point) (point) 'line))
+ (beg (evil-range-beginning range))
+ (end (evil-range-end range))
+ (min (point-min))
+ (max (point-max)))
+ (when (save-excursion (goto-char end) (bolp))
+ (setq end (max beg (1- end))))
+ ;; don't include the newline in Normal state
+ (when (and (not evil-move-beyond-eol)
+ (not (evil-visual-state-p))
+ (not (evil-operator-state-p)))
+ (setq end (max beg (1- end))))
+ (evil-with-restriction beg end
+ (evil-signal-without-movement
+ (condition-case err
+ (progn ,@body)
+ (beginning-of-buffer
+ (if (= beg min)
+ (signal (car err) (cdr err))
+ (signal 'beginning-of-line nil)))
+ (end-of-buffer
+ (if (= end max)
+ (signal (car err) (cdr err))
+ (signal 'end-of-line nil))))))))
+
+;; we don't want line boundaries to trigger the debugger
+;; when `debug-on-error' is t
+(add-to-list 'debug-ignored-errors "^Beginning of line$")
+(add-to-list 'debug-ignored-errors "^End of line$")
+
+(defun evil-eobp (&optional pos)
+ "Whether point is at end-of-buffer with regard to end-of-line."
+ (save-excursion
+ (when pos (goto-char pos))
+ (cond
+ ((eobp))
+ ;; the rest only pertains to Normal state
+ ((not (evil-normal-state-p))
+ nil)
+ ;; at the end of the last line
+ ((eolp)
+ (forward-char)
+ (eobp))
+ ;; at the last character of the last line
+ (t
+ (forward-char)
+ (cond
+ ((eobp))
+ ((eolp)
+ (forward-char)
+ (eobp)))))))
+
+(defun evil-move-beginning (count forward &optional backward)
+ "Move to the beginning of the COUNT next object.
+If COUNT is negative, move to the COUNT previous object.
+FORWARD is a function which moves to the end of the object, and
+BACKWARD is a function which moves to the beginning.
+If one is unspecified, the other is used with a negative argument."
+ (let* ((count (or count 1))
+ (backward (or backward
+ #'(lambda (count)
+ (funcall forward (- count)))))
+ (forward (or forward
+ #'(lambda (count)
+ (funcall backward (- count)))))
+ (opoint (point)))
+ (cond
+ ((< count 0)
+ (when (bobp)
+ (signal 'beginning-of-buffer nil))
+ (unwind-protect
+ (evil-motion-loop (nil count count)
+ (funcall backward 1))
+ (unless (zerop count)
+ (goto-char (point-min)))))
+ ((> count 0)
+ (when (evil-eobp)
+ (signal 'end-of-buffer nil))
+ ;; Do we need to move past the current object?
+ (when (<= (save-excursion
+ (funcall forward 1)
+ (funcall backward 1)
+ (point))
+ opoint)
+ (setq count (1+ count)))
+ (unwind-protect
+ (evil-motion-loop (nil count count)
+ (funcall forward 1))
+ (if (zerop count)
+ ;; go back to beginning of object
+ (funcall backward 1)
+ (goto-char (point-max)))))
+ (t
+ count))))
+
+(defun evil-move-end (count forward &optional backward inclusive)
+ "Move to the end of the COUNT next object.
+If COUNT is negative, move to the COUNT previous object.
+FORWARD is a function which moves to the end of the object, and
+BACKWARD is a function which moves to the beginning.
+If one is unspecified, the other is used with a negative argument.
+If INCLUSIVE is non-nil, then point is placed at the last character
+of the object; otherwise it is placed at the end of the object."
+ (let* ((count (or count 1))
+ (backward (or backward
+ #'(lambda (count)
+ (funcall forward (- count)))))
+ (forward (or forward
+ #'(lambda (count)
+ (funcall backward (- count)))))
+ (opoint (point)))
+ (cond
+ ((< count 0)
+ (when (bobp)
+ (signal 'beginning-of-buffer nil))
+ ;; Do we need to move past the current object?
+ (when (>= (save-excursion
+ (funcall backward 1)
+ (funcall forward 1)
+ (point))
+ (if inclusive
+ (1+ opoint)
+ opoint))
+ (setq count (1- count)))
+ (unwind-protect
+ (evil-motion-loop (nil count count)
+ (funcall backward 1))
+ (if (not (zerop count))
+ (goto-char (point-min))
+ ;; go to end of object
+ (funcall forward 1)
+ (when inclusive
+ (unless (bobp) (backward-char)))
+ (when (or (evil-normal-state-p)
+ (evil-motion-state-p))
+ (evil-adjust-cursor)))))
+ ((> count 0)
+ (when (evil-eobp)
+ (signal 'end-of-buffer nil))
+ (when inclusive
+ (forward-char))
+ (unwind-protect
+ (evil-motion-loop (nil count count)
+ (funcall forward 1))
+ (if (not (zerop count))
+ (goto-char (point-max))
+ (when inclusive
+ (unless (bobp) (backward-char)))
+ (when (or (evil-normal-state-p)
+ (evil-motion-state-p))
+ (evil-adjust-cursor)))))
+ (t
+ count))))
+
+(defun evil-text-object-make-linewise (range)
+ "Turn the text object selection RANGE to linewise.
+The selection is adjusted in a sensible way so that the selected
+lines match the user intent. In particular, whitespace-only parts
+at the first and last lines are omitted. This function returns
+the new range."
+ ;; Bug #607
+ ;; If new type is linewise and the selection of the
+ ;; first line consists of whitespace only, the
+ ;; beginning is moved to the start of the next line. If
+ ;; the selections of the last line consists of
+ ;; whitespace only, the end is moved to the end of the
+ ;; previous line.
+ (if (eq (evil-type range) 'line)
+ range
+ (let ((expanded (plist-get (evil-range-properties range) :expanded))
+ (newrange (evil-expand-range range t)))
+ (save-excursion
+ ;; skip whitespace at the beginning
+ (goto-char (evil-range-beginning newrange))
+ (skip-chars-forward " \t")
+ (when (and (not (bolp)) (eolp))
+ (evil-set-range-beginning newrange (1+ (point))))
+ ;; skip whitepsace at the end
+ (goto-char (evil-range-end newrange))
+ (skip-chars-backward " \t")
+ (when (and (not (eolp)) (bolp))
+ (evil-set-range-end newrange (1- (point))))
+ ;; only modify range if result is not empty
+ (if (> (evil-range-beginning newrange)
+ (evil-range-end newrange))
+ range
+ (unless expanded
+ (evil-contract-range newrange))
+ newrange)))))
+
+(defmacro evil-define-text-object (object args &rest body)
+ "Define a text object command OBJECT.
+BODY should return a range (BEG END) to the right of point
+if COUNT is positive, and to the left of it if negative.
+
+Optional keyword arguments:
+- `:type' - determines how the range applies after an operator
+ (`inclusive', `line', `block', and `exclusive', or a self-defined
+ motion type).
+- `:extend-selection' - if non-nil (default), the text object always
+ enlarges the current selection. Otherwise, it replaces the current
+ selection.
+
+\(fn OBJECT (COUNT) DOC [[KEY VALUE]...] BODY...)"
+ (declare (indent defun)
+ (doc-string 3)
+ (debug (&define name lambda-list
+ [&optional stringp]
+ [&rest keywordp sexp]
+ def-body)))
+ (let* ((args (delq '&optional args))
+ (count (or (pop args) 'count))
+ (args (when args `(&optional ,@args)))
+ (interactive '((interactive "<c><v>")))
+ arg doc key keys)
+ ;; collect docstring
+ (when (stringp (car-safe body))
+ (setq doc (pop body)))
+ ;; collect keywords
+ (setq keys (plist-put keys :extend-selection t))
+ (while (keywordp (car-safe body))
+ (setq key (pop body)
+ arg (pop body)
+ keys (plist-put keys key arg)))
+ ;; interactive
+ (when (eq (car-safe (car-safe body)) 'interactive)
+ (setq interactive (list (pop body))))
+ ;; macro expansion
+ `(evil-define-motion ,object (,count ,@args)
+ ,@(when doc `(,doc))
+ ,@keys
+ ,@interactive
+ (setq ,count (or ,count 1))
+ (when (/= ,count 0)
+ (let ((type (evil-type ',object evil-visual-char))
+ (extend (and (evil-visual-state-p)
+ (evil-get-command-property
+ ',object :extend-selection
+ ',(plist-get keys :extend-selection))))
+ (dir evil-visual-direction)
+ mark point range selection)
+ (cond
+ ;; Visual state: extend the current selection
+ ((and (evil-visual-state-p)
+ (called-interactively-p 'any))
+ ;; if we are at the beginning of the Visual selection,
+ ;; go to the left (negative COUNT); if at the end,
+ ;; go to the right (positive COUNT)
+ (setq dir evil-visual-direction
+ ,count (* ,count dir))
+ (setq range (progn ,@body))
+ (when (evil-range-p range)
+ (setq range (evil-expand-range range))
+ (evil-set-type range (evil-type range type))
+ (setq range (evil-contract-range range))
+ ;; the beginning is mark and the end is point
+ ;; unless the selection goes the other way
+ (setq mark (evil-range-beginning range)
+ point (evil-range-end range)
+ type (evil-type
+ (if evil-text-object-change-visual-type
+ range
+ (evil-visual-range))))
+ (when (and (eq type 'line)
+ (not (eq type (evil-type range))))
+ (let ((newrange (evil-text-object-make-linewise range)))
+ (setq mark (evil-range-beginning newrange)
+ point (evil-range-end newrange))))
+ (when (< dir 0)
+ (evil-swap mark point))
+ ;; select the union
+ (evil-visual-make-selection mark point type)))
+ ;; not Visual state: return a pair of buffer positions
+ (t
+ (setq range (progn ,@body))
+ (unless (evil-range-p range)
+ (setq ,count (- ,count)
+ range (progn ,@body)))
+ (when (evil-range-p range)
+ (setq selection (evil-range (point) (point) type))
+ (if extend
+ (setq range (evil-range-union range selection))
+ (evil-set-type range (evil-type range type)))
+ ;; possibly convert to linewise
+ (when (eq evil-this-type-modified 'line)
+ (setq range (evil-text-object-make-linewise range)))
+ (evil-set-range-properties range nil)
+ range))))))))
+
+(defmacro evil-define-operator (operator args &rest body)
+ "Define an operator command OPERATOR.
+The operator acts on the range of characters BEG through
+END. BODY must execute the operator by potentially manipulating
+the buffer contents, or otherwise causing side effects to happen.
+
+Optional keyword arguments are:
+- `:type' - force the input range to be of a given type (`inclusive',
+ `line', `block', and `exclusive', or a self-defined motion type).
+- `:motion' - use a predetermined motion instead of waiting for one
+ from the keyboard. This does not affect the behavior in visual
+ state, where selection boundaries are always used.
+- `:repeat' - if non-nil (default), then \
+ \\<evil-normal-state-map>\\[evil-repeat] will repeat the
+ operator.
+- `:move-point' - if non-nil (default), the cursor will be moved to
+ the beginning of the range before the body executes
+- `:keep-visual' - if non-nil, the selection is not disabled when the
+ operator is executed in visual state. By default, visual state is
+ exited automatically.
+- `:restore-point' - if non-nil, point is restored when the
+ operator is executed from ex.
+
+\(fn OPERATOR (BEG END ARGS...) DOC [[KEY VALUE]...] BODY...)"
+ (declare (indent defun)
+ (doc-string 3)
+ (debug (&define name lambda-list
+ [&optional stringp]
+ [&rest keywordp sexp]
+ [&optional ("interactive" [&rest form])]
+ def-body)))
+ (let* ((args (delq '&optional args))
+ (interactive (if (> (length args) 2) '("<R>") '("<r>")))
+ (args (if (> (length args) 2)
+ `(,(nth 0 args) ,(nth 1 args)
+ &optional ,@(nthcdr 2 args))
+ args))
+ arg doc key keys visual)
+ ;; collect docstring
+ (when (and (> (length body) 1)
+ (or (eq (car-safe (car-safe body)) 'format)
+ (stringp (car-safe body))))
+ (setq doc (pop body)))
+ ;; collect keywords
+ (setq keys (plist-put keys :move-point t))
+ (while (keywordp (car-safe body))
+ (setq key (pop body)
+ arg (pop body))
+ (cond
+ ((eq key :keep-visual)
+ (setq visual arg))
+ (t
+ (setq keys (plist-put keys key arg)))))
+ ;; collect `interactive' specification
+ (when (eq (car-safe (car-safe body)) 'interactive)
+ (setq interactive (cdr-safe (pop body))))
+ ;; transform extended interactive specs
+ (setq interactive (apply #'evil-interactive-form interactive))
+ (setq keys (evil-concat-plists keys (cdr-safe interactive))
+ interactive (car-safe interactive))
+ ;; macro expansion
+ `(evil-define-command ,operator ,args
+ ,@(when doc `(,doc))
+ ,@keys
+ :keep-visual t
+ :suppress-operator t
+ (interactive
+ (let* ((evil-operator-range-motion
+ (when (evil-has-command-property-p ',operator :motion)
+ ;; :motion nil is equivalent to :motion undefined
+ (or (evil-get-command-property ',operator :motion)
+ #'undefined)))
+ (evil-operator-range-type
+ (evil-get-command-property ',operator :type))
+ (orig (point))
+ evil-operator-range-beginning
+ evil-operator-range-end
+ evil-inhibit-operator)
+ (setq evil-inhibit-operator-value nil
+ evil-this-operator this-command)
+ (setq evil-operator-start-col (current-column))
+ (prog1 ,interactive
+ (setq orig (point)
+ evil-inhibit-operator-value evil-inhibit-operator)
+ (if ,visual
+ (when (evil-visual-state-p)
+ (evil-visual-expand-region))
+ (when (or (evil-visual-state-p) (region-active-p))
+ (setq deactivate-mark t)))
+ (cond
+ ((evil-visual-state-p)
+ (evil-visual-rotate 'upper-left))
+ ((evil-get-command-property ',operator :move-point)
+ (goto-char (or evil-operator-range-beginning orig)))
+ (t
+ (goto-char orig))))))
+ (unwind-protect
+ (let ((evil-inhibit-operator evil-inhibit-operator-value))
+ (unless (and evil-inhibit-operator
+ (called-interactively-p 'any))
+ ,@body))
+ (setq evil-inhibit-operator-value nil)))))
+
+;; this is used in the `interactive' specification of an operator command
+(defun evil-operator-range (&optional return-type)
+ "Read a motion from the keyboard and return its buffer positions.
+The return value is a list (BEG END), or (BEG END TYPE) if
+RETURN-TYPE is non-nil."
+ (let* ((evil-ex-p (and (not (minibufferp)) (evil-ex-p)))
+ (motion (or evil-operator-range-motion
+ (when evil-ex-p 'evil-line)))
+ (type evil-operator-range-type)
+ (range (evil-range (point) (point)))
+ command count)
+ (setq evil-this-type-modified nil)
+ (evil-save-echo-area
+ (cond
+ ;; Ex mode
+ ((and evil-ex-p evil-ex-range)
+ (setq range evil-ex-range))
+ ;; Visual selection
+ ((and (not evil-ex-p) (evil-visual-state-p))
+ (setq range (evil-visual-range)))
+ ;; active region
+ ((and (not evil-ex-p) (region-active-p))
+ (setq range (evil-range (region-beginning)
+ (region-end)
+ (or evil-this-type 'exclusive))))
+ (t
+ ;; motion
+ (evil-save-state
+ (unless motion
+ (evil-change-state 'operator)
+ ;; Make linewise operator shortcuts. E.g., "d" yields the
+ ;; shortcut "dd", and "g?" yields shortcuts "g??" and "g?g?".
+ (let ((keys (nth 2 (evil-extract-count (this-command-keys)))))
+ (setq keys (listify-key-sequence keys))
+ (dotimes (var (length keys))
+ (define-key evil-operator-shortcut-map
+ (vconcat (nthcdr var keys)) 'evil-line-or-visual-line)))
+ ;; read motion from keyboard
+ (setq command (evil-read-motion motion)
+ motion (nth 0 command)
+ count (nth 1 command)
+ type (or type (nth 2 command))))
+ (cond
+ ((eq motion #'undefined)
+ (setq range (if return-type '(nil nil nil) '(nil nil))
+ motion nil))
+ ((or (null motion) ; keyboard-quit
+ (evil-get-command-property motion :suppress-operator))
+ (when (fboundp 'evil-repeat-abort)
+ (evil-repeat-abort))
+ (setq quit-flag t
+ motion nil))
+ (evil-repeat-count
+ (setq count evil-repeat-count
+ ;; only the first operator's count is overwritten
+ evil-repeat-count nil))
+ ((or count current-prefix-arg)
+ ;; multiply operator count and motion count together
+ (setq count
+ (* (prefix-numeric-value count)
+ (prefix-numeric-value current-prefix-arg)))))
+ (when motion
+ (let ((evil-state 'operator)
+ mark-active)
+ ;; calculate motion range
+ (setq range (evil-motion-range
+ motion
+ count
+ type))))
+ ;; update global variables
+ (setq evil-this-motion motion
+ evil-this-motion-count count
+ type (evil-type range type)
+ evil-this-type type))))
+ (when (evil-range-p range)
+ (unless (or (null type) (eq (evil-type range) type))
+ (evil-contract-range range)
+ (evil-set-type range type)
+ (evil-expand-range range))
+ (evil-set-range-properties range nil)
+ (unless return-type
+ (evil-set-type range nil))
+ (setq evil-operator-range-beginning (evil-range-beginning range)
+ evil-operator-range-end (evil-range-end range)
+ evil-operator-range-type (evil-type range)))
+ range)))
+
+(defmacro evil-define-type (type doc &rest body)
+ "Define type TYPE.
+DOC is a general description and shows up in all docstrings.
+
+Optional keyword arguments:
+- `:expand' - expansion function. This function should accept two
+ positions in the current buffer, BEG and END,and return a pair of
+ expanded buffer positions.
+- `:contract' - the opposite of `:expand'. Optional.
+- `:one-to-one' - non-nil if expansion is one-to-one. This means that
+ `:expand' followed by `:contract' always return the original range.
+- `:normalize' - normalization function. This function should accept
+ two unexpanded positions and adjust them before expansion. May be
+ used to deal with buffer boundaries.
+- `:string' - description function. Takes two buffer positions and
+ returns a human-readable string. For example \"2 lines\"
+
+If further keywords and functions are specified, they are assumed to
+be transformations on buffer positions, like `:expand' and `:contract'.
+
+\(fn TYPE DOC [[KEY FUNC]...])"
+ (declare (indent defun)
+ (doc-string 2)
+ (debug (&define name
+ [&optional stringp]
+ [&rest [keywordp function-form]])))
+ (let (args defun-forms func key name plist string sym val)
+ ;; standard values
+ (setq plist (plist-put plist :one-to-one t))
+ ;; keywords
+ (while (keywordp (car-safe body))
+ (setq key (pop body)
+ val (pop body))
+ (if (plist-member plist key) ; not a function
+ (setq plist (plist-put plist key val))
+ (setq func val
+ sym (intern (replace-regexp-in-string
+ "^:" "" (symbol-name key)))
+ name (intern (format "evil-%s-%s" type sym))
+ args (car (cdr-safe func))
+ string (car (cdr (cdr-safe func)))
+ string (if (stringp string)
+ (format "%s\n\n" string) "")
+ plist (plist-put plist key `',name))
+ (push
+ (cond
+ ((eq key :string)
+ `(defun ,name (beg end &rest properties)
+ ,(format "Return size of %s from BEG to END \
+with PROPERTIES.\n\n%s%s" type string doc)
+ (let ((beg (evil-normalize-position beg))
+ (end (evil-normalize-position end))
+ (type ',type)
+ plist range)
+ (when (and beg end)
+ (save-excursion
+ (evil-sort beg end)
+ (unless (plist-get properties :expanded)
+ (setq range (apply #'evil-expand
+ beg end type properties)
+ beg (evil-range-beginning range)
+ end (evil-range-end range)
+ type (evil-type range type)
+ plist (evil-range-properties range))
+ (setq properties
+ (evil-concat-plists properties plist)))
+ (or (apply #',func beg end
+ (when ,(> (length args) 2)
+ properties))
+ ""))))))
+ (t
+ `(defun ,name (beg end &rest properties)
+ ,(format "Perform %s transformation on %s from BEG to END \
+with PROPERTIES.\n\n%s%s" sym type string doc)
+ (let ((beg (evil-normalize-position beg))
+ (end (evil-normalize-position end))
+ (type ',type)
+ plist range)
+ (when (and beg end)
+ (save-excursion
+ (evil-sort beg end)
+ (when (memq ,key '(:expand :contract))
+ (setq properties
+ (plist-put properties
+ :expanded
+ ,(eq key :expand))))
+ (setq range (or (apply #',func beg end
+ (when ,(> (length args) 2)
+ properties))
+ (apply #'evil-range
+ beg end type properties))
+ beg (evil-range-beginning range)
+ end (evil-range-end range)
+ type (evil-type range type)
+ plist (evil-range-properties range))
+ (setq properties
+ (evil-concat-plists properties plist))
+ (apply #'evil-range beg end type properties)))))))
+ defun-forms)))
+ ;; :one-to-one requires both or neither of :expand and :contract
+ (when (plist-get plist :expand)
+ (setq plist (plist-put plist :one-to-one
+ (and (plist-get plist :contract)
+ (plist-get plist :one-to-one)))))
+ `(progn
+ (evil-put-property 'evil-type-properties ',type ,@plist)
+ ,@defun-forms
+ ',type)))
+
+(defmacro evil-define-interactive-code (code &rest body)
+ "Define an interactive code.
+PROMPT, if given, is the remainder of the interactive string
+up to the next newline. Command properties may be specified
+via KEY-VALUE pairs. BODY should evaluate to a list of values.
+
+\(fn CODE (PROMPT) [[KEY VALUE]...] BODY...)"
+ (declare (indent defun))
+ (let* ((args (when (and (> (length body) 1)
+ (listp (car-safe body)))
+ (pop body)))
+ (doc (when (stringp (car-safe body)) (pop body)))
+ func properties)
+ (while (keywordp (car-safe body))
+ (setq properties
+ (append properties (list (pop body) (pop body)))))
+ (cond
+ (args
+ (setq func `(lambda ,args
+ ,@(when doc `(,doc))
+ ,@body)))
+ ((> (length body) 1)
+ (setq func `(progn ,@body)))
+ (t
+ (setq func (car body))))
+ `(eval-and-compile
+ (let* ((code ,code)
+ (entry (assoc code evil-interactive-alist))
+ (value (cons ',func ',properties)))
+ (if entry
+ (setcdr entry value)
+ (push (cons code value) evil-interactive-alist))
+ code))))
+
+;;; Highlighting
+
+(when (fboundp 'font-lock-add-keywords)
+ (font-lock-add-keywords
+ 'emacs-lisp-mode
+ ;; Match all `evil-define-' forms except `evil-define-key'.
+ ;; (In the interests of speed, this expression is incomplete
+ ;; and does not match all three-letter words.)
+ '(("(\\(evil-\\(?:ex-\\)?define-\
+\\(?:[^ k][^ e][^ y]\\|[-[:word:]]\\{4,\\}\\)\\)\
+\\>[ \f\t\n\r\v]*\\(\\(?:\\sw\\|\\s_\\)+\\)?"
+ (1 font-lock-keyword-face)
+ (2 font-lock-function-name-face nil t))
+ ("(\\(evil-\\(?:delay\\|narrow\\|signal\\|save\\|with\\(?:out\\)?\\)\
+\\(?:-[-[:word:]]+\\)?\\)\\>\[ \f\t\n\r\v]+"
+ 1 font-lock-keyword-face)
+ ("(\\(evil-\\(?:[-[:word:]]\\)*loop\\)\\>[ \f\t\n\r\v]+"
+ 1 font-lock-keyword-face))))
+
+(provide 'evil-macros)
+
+;;; evil-macros.el ends here
diff --git a/elpa/evil-20220503.1314/evil-macros.elc b/elpa/evil-20220503.1314/evil-macros.elc
new file mode 100644
index 0000000..c1999ee
--- /dev/null
+++ b/elpa/evil-20220503.1314/evil-macros.elc
Binary files differ
diff --git a/elpa/evil-20220503.1314/evil-maps.el b/elpa/evil-20220503.1314/evil-maps.el
new file mode 100644
index 0000000..2166d9a
--- /dev/null
+++ b/elpa/evil-20220503.1314/evil-maps.el
@@ -0,0 +1,643 @@
+;;; evil-maps.el --- Default keymaps -*- lexical-binding: t -*-
+
+;; Author: Vegard Øye <vegard_oye at hotmail.com>
+;; Maintainer: Vegard Øye <vegard_oye at hotmail.com>
+
+;; Version: 1.15.0
+
+;;
+;; This file is NOT part of GNU Emacs.
+
+;;; License:
+
+;; This file is part of Evil.
+;;
+;; Evil 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.
+;;
+;; Evil 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 Evil. If not, see <http://www.gnu.org/licenses/>.
+
+(require 'evil-states)
+(require 'evil-ex)
+(require 'evil-commands)
+(require 'evil-command-window)
+(require 'evil-common)
+
+;;; Code:
+
+;;; Normal state
+
+(define-key evil-normal-state-map "a" 'evil-append)
+(define-key evil-normal-state-map "A" 'evil-append-line)
+(define-key evil-normal-state-map "c" 'evil-change)
+(define-key evil-normal-state-map "C" 'evil-change-line)
+(define-key evil-normal-state-map "d" 'evil-delete)
+(define-key evil-normal-state-map "D" 'evil-delete-line)
+(define-key evil-normal-state-map "i" 'evil-insert)
+(define-key evil-normal-state-map (kbd "<insert>") 'evil-insert)
+(define-key evil-normal-state-map (kbd "<insertchar>") 'evil-insert)
+(define-key evil-normal-state-map "I" 'evil-insert-line)
+(define-key evil-normal-state-map "J" 'evil-join)
+(define-key evil-normal-state-map "m" 'evil-set-marker)
+(define-key evil-normal-state-map "o" 'evil-open-below)
+(define-key evil-normal-state-map "O" 'evil-open-above)
+(define-key evil-normal-state-map "p" 'evil-paste-after)
+(define-key evil-normal-state-map "P" 'evil-paste-before)
+(define-key evil-normal-state-map "q" 'evil-record-macro)
+(define-key evil-normal-state-map "r" 'evil-replace)
+(define-key evil-normal-state-map "R" 'evil-replace-state)
+(define-key evil-normal-state-map "s" 'evil-substitute)
+(define-key evil-normal-state-map "S" 'evil-change-whole-line)
+(define-key evil-normal-state-map "x" 'evil-delete-char)
+(define-key evil-normal-state-map "X" 'evil-delete-backward-char)
+(define-key evil-normal-state-map [deletechar] 'evil-delete-char)
+(define-key evil-normal-state-map "y" 'evil-yank)
+(define-key evil-normal-state-map "Y" 'evil-yank-line)
+(define-key evil-normal-state-map "&" 'evil-ex-repeat-substitute)
+(define-key evil-normal-state-map "g&" 'evil-ex-repeat-global-substitute)
+(define-key evil-normal-state-map "g8" 'what-cursor-position)
+(define-key evil-normal-state-map "ga" 'what-cursor-position)
+(define-key evil-normal-state-map "gi" 'evil-insert-resume)
+(define-key evil-normal-state-map "gI" 'evil-insert-0-line)
+(define-key evil-normal-state-map "gJ" 'evil-join-whitespace)
+(define-key evil-normal-state-map "gq" 'evil-fill-and-move)
+(define-key evil-normal-state-map "gw" 'evil-fill)
+(define-key evil-normal-state-map "gu" 'evil-downcase)
+(define-key evil-normal-state-map "gU" 'evil-upcase)
+(define-key evil-normal-state-map "gf" 'find-file-at-point)
+(define-key evil-normal-state-map "]f" 'find-file-at-point)
+(define-key evil-normal-state-map "[f" 'find-file-at-point)
+(define-key evil-normal-state-map "gF" 'evil-find-file-at-point-with-line)
+(define-key evil-normal-state-map "]F" 'evil-find-file-at-point-with-line)
+(define-key evil-normal-state-map "[F" 'evil-find-file-at-point-with-line)
+(define-key evil-normal-state-map "gx" 'browse-url-at-point)
+(define-key evil-normal-state-map "g?" 'evil-rot13)
+(define-key evil-normal-state-map "g~" 'evil-invert-case)
+(define-key evil-normal-state-map "zo" 'evil-open-fold)
+(define-key evil-normal-state-map "zO" 'evil-open-fold-rec)
+(define-key evil-normal-state-map "zc" 'evil-close-fold)
+(define-key evil-normal-state-map "za" 'evil-toggle-fold)
+(define-key evil-normal-state-map "zr" 'evil-open-folds)
+(define-key evil-normal-state-map "zm" 'evil-close-folds)
+(define-key evil-normal-state-map "z=" 'ispell-word)
+(define-key evil-normal-state-map "\C-n" 'evil-paste-pop-next)
+(define-key evil-normal-state-map "\C-p" 'evil-paste-pop)
+(define-key evil-normal-state-map "\C-t" 'pop-tag-mark)
+(define-key evil-normal-state-map (kbd "C-.") 'evil-repeat-pop)
+(define-key evil-normal-state-map (kbd "M-.") 'evil-repeat-pop-next)
+(define-key evil-normal-state-map "." 'evil-repeat)
+(define-key evil-normal-state-map "@" 'evil-execute-macro)
+(define-key evil-normal-state-map "\"" 'evil-use-register)
+(define-key evil-normal-state-map "~" 'evil-invert-char)
+(define-key evil-normal-state-map "=" 'evil-indent)
+(define-key evil-normal-state-map "<" 'evil-shift-left)
+(define-key evil-normal-state-map ">" 'evil-shift-right)
+(define-key evil-normal-state-map "ZZ" 'evil-save-modified-and-close)
+(define-key evil-normal-state-map "ZQ" 'evil-quit)
+(define-key evil-normal-state-map (kbd "DEL") 'evil-backward-char)
+(define-key evil-normal-state-map [escape] 'evil-force-normal-state)
+(define-key evil-normal-state-map [remap cua-paste-pop] 'evil-paste-pop)
+(define-key evil-normal-state-map [remap yank-pop] 'evil-paste-pop)
+
+(when (featurep 'tab-bar)
+ (define-key evil-normal-state-map "gt" 'tab-bar-switch-to-next-tab)
+ (define-key evil-normal-state-map "gT" 'tab-bar-switch-to-prev-tab))
+
+;; go to last change
+(define-key evil-normal-state-map "g;" 'goto-last-change)
+(define-key evil-normal-state-map "g," 'goto-last-change-reverse)
+
+;; undo
+(define-key evil-normal-state-map "u" 'evil-undo)
+(define-key evil-normal-state-map "\C-r" 'evil-redo)
+
+;; window commands
+(define-prefix-command 'evil-window-map)
+(define-key evil-window-map "b" 'evil-window-bottom-right)
+(define-key evil-window-map "c" 'evil-window-delete)
+(define-key evil-window-map "h" 'evil-window-left)
+(define-key evil-window-map "H" 'evil-window-move-far-left)
+(define-key evil-window-map "j" 'evil-window-down)
+(define-key evil-window-map "J" 'evil-window-move-very-bottom)
+(define-key evil-window-map "k" 'evil-window-up)
+(define-key evil-window-map "K" 'evil-window-move-very-top)
+(define-key evil-window-map "l" 'evil-window-right)
+(define-key evil-window-map "L" 'evil-window-move-far-right)
+(define-key evil-window-map "n" 'evil-window-new)
+(define-key evil-window-map "o" 'delete-other-windows)
+(define-key evil-window-map "p" 'evil-window-mru)
+(define-key evil-window-map "q" 'evil-quit)
+(define-key evil-window-map "r" 'evil-window-rotate-downwards)
+(define-key evil-window-map "R" 'evil-window-rotate-upwards)
+(define-key evil-window-map "s" 'evil-window-split)
+(define-key evil-window-map "S" 'evil-window-split)
+(define-key evil-window-map "t" 'evil-window-top-left)
+(define-key evil-window-map "v" 'evil-window-vsplit)
+(define-key evil-window-map "w" 'evil-window-next)
+(define-key evil-window-map "W" 'evil-window-prev)
+(define-key evil-window-map "+" 'evil-window-increase-height)
+(define-key evil-window-map "-" 'evil-window-decrease-height)
+(define-key evil-window-map "_" 'evil-window-set-height)
+(define-key evil-window-map "<" 'evil-window-decrease-width)
+(define-key evil-window-map ">" 'evil-window-increase-width)
+(define-key evil-window-map "=" 'balance-windows)
+(define-key evil-window-map "|" 'evil-window-set-width)
+(define-key evil-window-map "\C-b" 'evil-window-bottom-right)
+(define-key evil-window-map "\C-c" 'evil-window-delete)
+(define-key evil-window-map (kbd "C-S-h") 'evil-window-move-far-left)
+(define-key evil-window-map (kbd "C-S-j") 'evil-window-move-very-bottom)
+(define-key evil-window-map (kbd "C-S-k") 'evil-window-move-very-top)
+(define-key evil-window-map (kbd "C-S-l") 'evil-window-move-far-right)
+(define-key evil-window-map "\C-n" 'evil-window-new)
+(define-key evil-window-map "\C-o" 'delete-other-windows)
+(define-key evil-window-map "\C-p" 'evil-window-mru)
+(define-key evil-window-map "\C-r" 'evil-window-rotate-downwards)
+(define-key evil-window-map (kbd "C-S-r") 'evil-window-rotate-upwards)
+(define-key evil-window-map "\C-s" 'evil-window-split)
+(define-key evil-window-map (kbd "C-S-s") 'evil-window-split)
+(define-key evil-window-map "\C-t" 'evil-window-top-left)
+(define-key evil-window-map "\C-v" 'evil-window-vsplit)
+(define-key evil-window-map "\C-w" 'evil-window-next)
+(define-key evil-window-map (kbd "C-S-W") 'evil-window-prev)
+(define-key evil-window-map "\C-_" 'evil-window-set-height)
+(define-key evil-window-map "\C-f" 'ffap-other-window)
+
+;;; Motion state
+
+;; "0" is a special command when called first
+(define-key evil-motion-state-map "0" 'evil-beginning-of-line)
+(define-key evil-motion-state-map "1" 'digit-argument)
+(define-key evil-motion-state-map "2" 'digit-argument)
+(define-key evil-motion-state-map "3" 'digit-argument)
+(define-key evil-motion-state-map "4" 'digit-argument)
+(define-key evil-motion-state-map "5" 'digit-argument)
+(define-key evil-motion-state-map "6" 'digit-argument)
+(define-key evil-motion-state-map "7" 'digit-argument)
+(define-key evil-motion-state-map "8" 'digit-argument)
+(define-key evil-motion-state-map "9" 'digit-argument)
+(define-key evil-motion-state-map "b" 'evil-backward-word-begin)
+(define-key evil-motion-state-map "B" 'evil-backward-WORD-begin)
+(define-key evil-motion-state-map "e" 'evil-forward-word-end)
+(define-key evil-motion-state-map "E" 'evil-forward-WORD-end)
+(define-key evil-motion-state-map "f" 'evil-find-char)
+(define-key evil-motion-state-map "F" 'evil-find-char-backward)
+(define-key evil-motion-state-map "G" 'evil-goto-line)
+(define-key evil-motion-state-map "h" 'evil-backward-char)
+(define-key evil-motion-state-map "H" 'evil-window-top)
+(define-key evil-motion-state-map "j" 'evil-next-line)
+(define-key evil-motion-state-map "k" 'evil-previous-line)
+(define-key evil-motion-state-map "l" 'evil-forward-char)
+(define-key evil-motion-state-map " " 'evil-forward-char)
+(define-key evil-motion-state-map "K" 'evil-lookup)
+(define-key evil-motion-state-map "L" 'evil-window-bottom)
+(define-key evil-motion-state-map "M" 'evil-window-middle)
+(define-key evil-motion-state-map "n" 'evil-search-next)
+(define-key evil-motion-state-map "N" 'evil-search-previous)
+(define-key evil-motion-state-map "t" 'evil-find-char-to)
+(define-key evil-motion-state-map "T" 'evil-find-char-to-backward)
+(define-key evil-motion-state-map "w" 'evil-forward-word-begin)
+(define-key evil-motion-state-map "W" 'evil-forward-WORD-begin)
+(define-key evil-motion-state-map "y" 'evil-yank)
+(define-key evil-motion-state-map "Y" 'evil-yank-line)
+(define-key evil-motion-state-map "gd" 'evil-goto-definition)
+(define-key evil-motion-state-map "ge" 'evil-backward-word-end)
+(define-key evil-motion-state-map "gE" 'evil-backward-WORD-end)
+(define-key evil-motion-state-map "gg" 'evil-goto-first-line)
+(define-key evil-motion-state-map "gj" 'evil-next-visual-line)
+(define-key evil-motion-state-map (vconcat "g" [down]) 'evil-next-visual-line)
+(define-key evil-motion-state-map "gk" 'evil-previous-visual-line)
+(define-key evil-motion-state-map (vconcat "g" [up]) 'evil-previous-visual-line)
+(define-key evil-motion-state-map "g0" 'evil-beginning-of-visual-line)
+(define-key evil-motion-state-map "g_" 'evil-last-non-blank)
+(define-key evil-motion-state-map "g^" 'evil-first-non-blank-of-visual-line)
+(define-key evil-motion-state-map (vconcat "g" [home]) 'evil-first-non-blank-of-visual-line)
+(define-key evil-motion-state-map "gm" 'evil-middle-of-visual-line)
+(define-key evil-motion-state-map "gM" 'evil-percentage-of-line)
+(define-key evil-motion-state-map "go" 'evil-goto-char)
+(define-key evil-motion-state-map "g$" 'evil-end-of-visual-line)
+(define-key evil-motion-state-map (vconcat "g" [end]) 'evil-end-of-visual-line)
+(define-key evil-motion-state-map "g\C-]" 'evil-jump-to-tag)
+(define-key evil-motion-state-map "{" 'evil-backward-paragraph)
+(define-key evil-motion-state-map "}" 'evil-forward-paragraph)
+(define-key evil-motion-state-map "#" 'evil-search-word-backward)
+(define-key evil-motion-state-map "g#" 'evil-search-unbounded-word-backward)
+(define-key evil-motion-state-map "$" 'evil-end-of-line)
+(define-key evil-motion-state-map [end] 'evil-end-of-line)
+(define-key evil-motion-state-map [home] 'evil-beginning-of-line)
+(define-key evil-motion-state-map "%" 'evil-jump-item)
+(define-key evil-motion-state-map "`" 'evil-goto-mark)
+(define-key evil-motion-state-map "'" 'evil-goto-mark-line)
+(define-key evil-motion-state-map "(" 'evil-backward-sentence-begin)
+(define-key evil-motion-state-map ")" 'evil-forward-sentence-begin)
+(define-key evil-motion-state-map "]]" 'evil-forward-section-begin)
+(define-key evil-motion-state-map "][" 'evil-forward-section-end)
+(define-key evil-motion-state-map "[[" 'evil-backward-section-begin)
+(define-key evil-motion-state-map "[]" 'evil-backward-section-end)
+(define-key evil-motion-state-map "[(" 'evil-previous-open-paren)
+(define-key evil-motion-state-map "])" 'evil-next-close-paren)
+(define-key evil-motion-state-map "[{" 'evil-previous-open-brace)
+(define-key evil-motion-state-map "]}" 'evil-next-close-brace)
+(define-key evil-motion-state-map "]'" 'evil-next-mark-line)
+(define-key evil-motion-state-map "]`" 'evil-next-mark)
+(define-key evil-motion-state-map "['" 'evil-previous-mark-line)
+(define-key evil-motion-state-map "[`" 'evil-previous-mark)
+(define-key evil-motion-state-map "]s" 'evil-next-flyspell-error)
+(define-key evil-motion-state-map "[s" 'evil-prev-flyspell-error)
+(define-key evil-motion-state-map "*" 'evil-search-word-forward)
+(define-key evil-motion-state-map "g*" 'evil-search-unbounded-word-forward)
+(define-key evil-motion-state-map "," 'evil-repeat-find-char-reverse)
+(define-key evil-motion-state-map "/" 'evil-search-forward)
+(define-key evil-motion-state-map ";" 'evil-repeat-find-char)
+(define-key evil-motion-state-map "?" 'evil-search-backward)
+(define-key evil-motion-state-map "|" 'evil-goto-column)
+(define-key evil-motion-state-map "^" 'evil-first-non-blank)
+(define-key evil-motion-state-map "+" 'evil-next-line-first-non-blank)
+(define-key evil-motion-state-map "_" 'evil-next-line-1-first-non-blank)
+(define-key evil-motion-state-map "-" 'evil-previous-line-first-non-blank)
+(define-key evil-motion-state-map "\C-w" 'evil-window-map)
+(define-key evil-motion-state-map (kbd "C-6") 'evil-switch-to-windows-last-buffer)
+(define-key evil-motion-state-map "\C-]" 'evil-jump-to-tag)
+(define-key evil-motion-state-map (kbd "C-b") 'evil-scroll-page-up)
+(define-key evil-motion-state-map (kbd "C-e") 'evil-scroll-line-down)
+(define-key evil-motion-state-map (kbd "C-f") 'evil-scroll-page-down)
+(define-key evil-motion-state-map (kbd "C-o") 'evil-jump-backward)
+(define-key evil-motion-state-map (kbd "C-y") 'evil-scroll-line-up)
+(define-key evil-motion-state-map (kbd "RET") 'evil-ret)
+(define-key evil-motion-state-map "\\" 'evil-execute-in-emacs-state)
+(define-key evil-motion-state-map "z^" 'evil-scroll-top-line-to-bottom)
+(define-key evil-motion-state-map "z+" 'evil-scroll-bottom-line-to-top)
+(define-key evil-motion-state-map "zt" 'evil-scroll-line-to-top)
+;; TODO: z RET has an advanced form taking an count before the RET
+;; but this requires again a special state with a single command
+;; bound to RET
+(define-key evil-motion-state-map (vconcat "z" [return]) "zt^")
+(define-key evil-motion-state-map (kbd "z RET") (vconcat "z" [return]))
+(define-key evil-motion-state-map "zz" 'evil-scroll-line-to-center)
+(define-key evil-motion-state-map "z." "zz^")
+(define-key evil-motion-state-map "zb" 'evil-scroll-line-to-bottom)
+(define-key evil-motion-state-map "z-" "zb^")
+(define-key evil-motion-state-map "v" 'evil-visual-char)
+(define-key evil-motion-state-map "V" 'evil-visual-line)
+(define-key evil-motion-state-map "\C-v" 'evil-visual-block)
+(define-key evil-motion-state-map "gv" 'evil-visual-restore)
+(define-key evil-motion-state-map (kbd "C-^") 'evil-buffer)
+(define-key evil-motion-state-map [left] 'evil-backward-char)
+(define-key evil-motion-state-map [right] 'evil-forward-char)
+(define-key evil-motion-state-map [up] 'evil-previous-line)
+(define-key evil-motion-state-map [down] 'evil-next-line)
+(define-key evil-motion-state-map "zl" 'evil-scroll-column-right)
+(define-key evil-motion-state-map [?z right] "zl")
+(define-key evil-motion-state-map "zh" 'evil-scroll-column-left)
+(define-key evil-motion-state-map [?z left] "zh")
+(define-key evil-motion-state-map "zL" 'evil-scroll-right)
+(define-key evil-motion-state-map "zH" 'evil-scroll-left)
+(define-key evil-motion-state-map
+ (read-kbd-macro evil-toggle-key) 'evil-emacs-state)
+
+;; text objects
+(define-key evil-outer-text-objects-map "w" 'evil-a-word)
+(define-key evil-outer-text-objects-map "W" 'evil-a-WORD)
+(define-key evil-outer-text-objects-map "s" 'evil-a-sentence)
+(define-key evil-outer-text-objects-map "p" 'evil-a-paragraph)
+(define-key evil-outer-text-objects-map "b" 'evil-a-paren)
+(define-key evil-outer-text-objects-map "(" 'evil-a-paren)
+(define-key evil-outer-text-objects-map ")" 'evil-a-paren)
+(define-key evil-outer-text-objects-map "[" 'evil-a-bracket)
+(define-key evil-outer-text-objects-map "]" 'evil-a-bracket)
+(define-key evil-outer-text-objects-map "B" 'evil-a-curly)
+(define-key evil-outer-text-objects-map "{" 'evil-a-curly)
+(define-key evil-outer-text-objects-map "}" 'evil-a-curly)
+(define-key evil-outer-text-objects-map "<" 'evil-an-angle)
+(define-key evil-outer-text-objects-map ">" 'evil-an-angle)
+(define-key evil-outer-text-objects-map "'" 'evil-a-single-quote)
+(define-key evil-outer-text-objects-map "\"" 'evil-a-double-quote)
+(define-key evil-outer-text-objects-map "`" 'evil-a-back-quote)
+(define-key evil-outer-text-objects-map "t" 'evil-a-tag)
+(define-key evil-outer-text-objects-map "o" 'evil-a-symbol)
+(define-key evil-inner-text-objects-map "w" 'evil-inner-word)
+(define-key evil-inner-text-objects-map "W" 'evil-inner-WORD)
+(define-key evil-inner-text-objects-map "s" 'evil-inner-sentence)
+(define-key evil-inner-text-objects-map "p" 'evil-inner-paragraph)
+(define-key evil-inner-text-objects-map "b" 'evil-inner-paren)
+(define-key evil-inner-text-objects-map "(" 'evil-inner-paren)
+(define-key evil-inner-text-objects-map ")" 'evil-inner-paren)
+(define-key evil-inner-text-objects-map "[" 'evil-inner-bracket)
+(define-key evil-inner-text-objects-map "]" 'evil-inner-bracket)
+(define-key evil-inner-text-objects-map "B" 'evil-inner-curly)
+(define-key evil-inner-text-objects-map "{" 'evil-inner-curly)
+(define-key evil-inner-text-objects-map "}" 'evil-inner-curly)
+(define-key evil-inner-text-objects-map "<" 'evil-inner-angle)
+(define-key evil-inner-text-objects-map ">" 'evil-inner-angle)
+(define-key evil-inner-text-objects-map "'" 'evil-inner-single-quote)
+(define-key evil-inner-text-objects-map "\"" 'evil-inner-double-quote)
+(define-key evil-inner-text-objects-map "`" 'evil-inner-back-quote)
+(define-key evil-inner-text-objects-map "t" 'evil-inner-tag)
+(define-key evil-inner-text-objects-map "o" 'evil-inner-symbol)
+(define-key evil-motion-state-map "gn" 'evil-next-match)
+(define-key evil-motion-state-map "gN" 'evil-previous-match)
+
+(when evil-want-C-i-jump
+ (define-key evil-motion-state-map (kbd "C-i") 'evil-jump-forward))
+
+(when evil-want-C-u-scroll
+ (define-key evil-motion-state-map (kbd "C-u") 'evil-scroll-up))
+
+(when evil-want-C-d-scroll
+ (define-key evil-motion-state-map (kbd "C-d") 'evil-scroll-down))
+
+(when evil-want-C-g-bindings
+ (define-key evil-motion-state-map "g\C-g" 'count-words))
+
+;;; Visual state
+
+(define-key evil-visual-state-map "A" 'evil-append)
+(define-key evil-visual-state-map "I" 'evil-insert)
+(define-key evil-visual-state-map "o" 'exchange-point-and-mark)
+(define-key evil-visual-state-map "O" 'evil-visual-exchange-corners)
+(define-key evil-visual-state-map "R" 'evil-change-whole-line)
+(define-key evil-visual-state-map "u" 'evil-downcase)
+(define-key evil-visual-state-map "U" 'evil-upcase)
+(define-key evil-visual-state-map "z=" 'ispell-word)
+(define-key evil-visual-state-map "a" evil-outer-text-objects-map)
+(define-key evil-visual-state-map "i" evil-inner-text-objects-map)
+(define-key evil-visual-state-map (kbd "<insert>") 'undefined)
+(define-key evil-visual-state-map (kbd "<insertchar>") 'undefined)
+(define-key evil-visual-state-map [remap evil-repeat] 'undefined)
+(define-key evil-visual-state-map [escape] 'evil-exit-visual-state)
+(define-key evil-visual-state-map "gf" 'evil-find-file-at-point-visual)
+
+;;; Operator-Pending state
+
+(define-key evil-operator-state-map "a" evil-outer-text-objects-map)
+(define-key evil-operator-state-map "i" evil-inner-text-objects-map)
+;; (define-key evil-operator-state-map [escape] 'keyboard-quit)
+
+;;; Insert state
+
+(defvar evil-insert-state-bindings
+ `(([insert] . evil-replace-state)
+ ("\C-q" . evil-quoted-insert)
+ ("\C-v" . evil-quoted-insert)
+ ("\C-k" . evil-insert-digraph)
+ ("\C-o" . evil-execute-in-normal-state)
+ ("\C-r" . evil-paste-from-register)
+ ("\C-y" . evil-copy-from-above)
+ ("\C-e" . evil-copy-from-below)
+ ("\C-n" . evil-complete-next) ;; Completion commands
+ ("\C-p" . evil-complete-previous) ;; don't yet behave correctly
+ ("\C-x\C-n" . evil-complete-next-line) ;; in replace state
+ ("\C-x\C-p" . evil-complete-previous-line) ;; TODO - fix this
+ ("\C-t" . evil-shift-right-line)
+ ("\C-d" . evil-shift-left-line)
+ ("\C-a" . evil-paste-last-insertion)
+ ("\C-@" . evil-paste-last-insertion-and-stop-insert)
+ ([remap delete-backward-char] . evil-delete-backward-char-and-join)
+ ,(if evil-want-C-w-delete
+ '("\C-w" . evil-delete-backward-word)
+ '("\C-w" . evil-window-map))
+ ,@(when evil-want-C-u-delete
+ '(("\C-u" . evil-delete-back-to-indentation)))
+ ,@(when evil-want-C-h-delete
+ '(("\C-h" . evil-delete-backward-char-and-join)))
+ ([mouse-2] . mouse-yank-primary))
+ "Evil's bindings for insert & replace states.
+Used in `evil-insert-state-map' and `evil-replace-state-map',
+excluding <delete>, <escape>, and `evil-toggle-key'.")
+
+(defun evil-update-insert-state-bindings (&optional _option-name remove force)
+ "Update bindings in `evil-insert-state-map'.
+If no arguments are given add the bindings specified in
+`evil-insert-state-bindings'. If REMOVE is non nil, remove only
+these bindings. Unless FORCE is non nil, this will not
+overwriting existing bindings, which means bindings will not be
+added if one already exists for a key and only default bindings
+are removed.
+
+Note that <delete>, <escape> and `evil-toggle-key' are not
+included in `evil-insert-state-bindings' by default."
+ (interactive)
+ (dolist (binding evil-insert-state-bindings)
+ (cond
+ ((and remove
+ (or force
+ ;; Only remove if the default binding has not changed
+ (eq (evil-lookup-key evil-insert-state-map (car binding))
+ (cdr binding))))
+ (define-key evil-insert-state-map (car binding) nil))
+ ((and (null remove)
+ (or force
+ ;; Check to see that nothing is bound here before adding
+ (not (evil-lookup-key evil-insert-state-map (car binding)))))
+ (define-key evil-insert-state-map (car binding) (cdr binding))))))
+
+(define-key evil-insert-state-map [delete] 'delete-char)
+(define-key evil-insert-state-map [escape] 'evil-normal-state)
+(define-key evil-insert-state-map
+ (read-kbd-macro evil-toggle-key) 'evil-emacs-state)
+
+;;; Replace state
+
+(dolist (binding evil-insert-state-bindings)
+ (define-key evil-replace-state-map (car binding) (cdr binding)))
+(define-key evil-replace-state-map (kbd "DEL") 'evil-replace-backspace)
+(when evil-want-C-h-delete
+ (define-key evil-replace-state-map "\C-h" 'evil-replace-backspace))
+(define-key evil-replace-state-map [escape] 'evil-normal-state)
+(define-key evil-replace-state-map [insert] 'evil-append)
+
+;;; Emacs state
+
+(define-key evil-emacs-state-map
+ (read-kbd-macro evil-toggle-key) 'evil-exit-emacs-state)
+
+(when evil-want-C-w-in-emacs-state
+ (define-key evil-emacs-state-map "\C-w" 'evil-window-map))
+
+;;; Mouse
+(define-key evil-motion-state-map [down-mouse-1] 'evil-mouse-drag-region)
+(define-key evil-visual-state-map [mouse-2] 'evil-exit-visual-and-repeat)
+(define-key evil-normal-state-map [mouse-2] 'mouse-yank-primary)
+
+;; Ex
+(define-key evil-motion-state-map ":" 'evil-ex)
+(define-key evil-motion-state-map "!" 'evil-shell-command)
+
+(evil-ex-define-cmd "e[dit]" 'evil-edit)
+(evil-ex-define-cmd "w[rite]" 'evil-write)
+(evil-ex-define-cmd "up[date]" 'evil-update)
+(evil-ex-define-cmd "wa[ll]" 'evil-write-all)
+(evil-ex-define-cmd "sav[eas]" 'evil-save)
+(evil-ex-define-cmd "r[ead]" 'evil-read)
+(evil-ex-define-cmd "b[uffer]" 'evil-buffer)
+(evil-ex-define-cmd "bn[ext]" 'evil-next-buffer)
+(evil-ex-define-cmd "bp[revious]" 'evil-prev-buffer)
+(evil-ex-define-cmd "bN[ext]" "bprevious")
+(evil-ex-define-cmd "sb[uffer]" 'evil-split-buffer)
+(evil-ex-define-cmd "sbn[ext]" 'evil-split-next-buffer)
+(evil-ex-define-cmd "sbp[revious]" 'evil-split-prev-buffer)
+(evil-ex-define-cmd "sbN[ext]" "sbprevious")
+(evil-ex-define-cmd "buffers" 'buffer-menu)
+(evil-ex-define-cmd "files" 'evil-show-files)
+(evil-ex-define-cmd "ls" "buffers")
+
+(evil-ex-define-cmd "c[hange]" 'evil-change)
+(evil-ex-define-cmd "co[py]" 'evil-copy)
+(evil-ex-define-cmd "t" "copy")
+(evil-ex-define-cmd "m[ove]" 'evil-move)
+(evil-ex-define-cmd "d[elete]" 'evil-ex-delete)
+(evil-ex-define-cmd "y[ank]" 'evil-ex-yank)
+(evil-ex-define-cmd "pu[t]" 'evil-ex-put)
+(evil-ex-define-cmd "go[to]" 'evil-goto-char)
+(evil-ex-define-cmd "j[oin]" 'evil-ex-join)
+(evil-ex-define-cmd "le[ft]" 'evil-align-left)
+(evil-ex-define-cmd "ri[ght]" 'evil-align-right)
+(evil-ex-define-cmd "ce[nter]" 'evil-align-center)
+(evil-ex-define-cmd "sp[lit]" 'evil-window-split)
+(evil-ex-define-cmd "vs[plit]" 'evil-window-vsplit)
+(evil-ex-define-cmd "new" 'evil-window-new)
+(evil-ex-define-cmd "ene[w]" 'evil-buffer-new)
+(evil-ex-define-cmd "vne[w]" 'evil-window-vnew)
+(evil-ex-define-cmd "clo[se]" 'evil-window-delete)
+(evil-ex-define-cmd "on[ly]" 'delete-other-windows)
+(evil-ex-define-cmd "q[uit]" 'evil-quit)
+(evil-ex-define-cmd "wq" 'evil-save-and-close)
+(evil-ex-define-cmd "quita[ll]" 'evil-quit-all)
+(evil-ex-define-cmd "qa[ll]" "quitall")
+(evil-ex-define-cmd "cq[uit]" 'evil-quit-all-with-error-code)
+(evil-ex-define-cmd "wqa[ll]" 'evil-save-and-quit)
+(evil-ex-define-cmd "xa[ll]" "wqall")
+(evil-ex-define-cmd "x[it]" 'evil-save-modified-and-close)
+(evil-ex-define-cmd "exi[t]" 'evil-save-modified-and-close)
+(evil-ex-define-cmd "bd[elete]" 'evil-delete-buffer)
+(evil-ex-define-cmd "bw[ipeout]" 'evil-delete-buffer)
+(evil-ex-define-cmd "g[lobal]" 'evil-ex-global)
+(evil-ex-define-cmd "v[global]" 'evil-ex-global-inverted)
+(evil-ex-define-cmd "norm[al]" 'evil-ex-normal)
+(evil-ex-define-cmd "s[ubstitute]" 'evil-ex-substitute)
+(evil-ex-define-cmd "&" 'evil-ex-repeat-substitute)
+(evil-ex-define-cmd "&&" 'evil-ex-repeat-substitute-with-flags)
+(evil-ex-define-cmd "~" 'evil-ex-repeat-substitute-with-search)
+(evil-ex-define-cmd "~&" 'evil-ex-repeat-substitute-with-search-and-flags)
+(evil-ex-define-cmd "registers" 'evil-show-registers)
+(evil-ex-define-cmd "di[splay]" "registers")
+(evil-ex-define-cmd "ma[rk]" 'evil-set-col-0-mark)
+(evil-ex-define-cmd "marks" 'evil-show-marks)
+(evil-ex-define-cmd "delm[arks]" 'evil-delete-marks)
+(evil-ex-define-cmd "ju[mps]" 'evil-show-jumps)
+(evil-ex-define-cmd "noh[lsearch]" 'evil-ex-nohighlight)
+(evil-ex-define-cmd "f[ile]" 'evil-show-file-info)
+(evil-ex-define-cmd "<" 'evil-shift-left)
+(evil-ex-define-cmd ">" 'evil-shift-right)
+(evil-ex-define-cmd "=" 'evil-ex-line-number)
+(evil-ex-define-cmd "!" 'evil-shell-command)
+(evil-ex-define-cmd "@:" 'evil-ex-repeat)
+(evil-ex-define-cmd "mak[e]" 'evil-make)
+(evil-ex-define-cmd "cc" 'evil-goto-error)
+(evil-ex-define-cmd "cfir[st]" 'first-error)
+(evil-ex-define-cmd "cr[ewind]" 'first-error)
+(evil-ex-define-cmd "cn[ext]" 'next-error)
+(evil-ex-define-cmd "cp[revious]" 'previous-error)
+(evil-ex-define-cmd "set-initial-state" 'evil-ex-set-initial-state)
+(evil-ex-define-cmd "show-digraphs" 'evil-ex-show-digraphs)
+(evil-ex-define-cmd "sor[t]" 'evil-ex-sort)
+(evil-ex-define-cmd "res[ize]" 'evil-ex-resize)
+(evil-ex-define-cmd "u[ndo]" 'evil-undo)
+(evil-ex-define-cmd "red[o]" 'evil-redo)
+
+(when (featurep 'tab-bar)
+ (evil-ex-define-cmd "tabnew" 'tab-bar-new-tab)
+ (evil-ex-define-cmd "tabc[lose]" 'tab-bar-close-tab)
+ (evil-ex-define-cmd "tabo[nly]" 'tab-bar-close-other-tabs)
+ (evil-ex-define-cmd "tabn[ext]" 'tab-bar-switch-to-next-tab)
+ (evil-ex-define-cmd "tabp[revious]" 'tab-bar-switch-to-prev-tab))
+
+;; search command line
+(define-key evil-ex-search-keymap "\d" #'evil-ex-delete-backward-char)
+(define-key evil-ex-search-keymap "\C-b" 'move-beginning-of-line)
+(define-key evil-ex-search-keymap "\C-c" 'abort-recursive-edit)
+(define-key evil-ex-search-keymap "\C-g" 'abort-recursive-edit)
+(define-key evil-ex-search-keymap "\C-k" 'evil-insert-digraph)
+(define-key evil-ex-search-keymap "\C-f" 'evil-ex-search-command-window)
+(define-key evil-ex-search-keymap "\C-r" 'evil-paste-from-register)
+(define-key evil-ex-search-keymap "\C-n" 'next-history-element)
+(define-key evil-ex-search-keymap "\C-p" 'previous-history-element)
+(define-key evil-ex-search-keymap "\C-u" 'evil-delete-whole-line)
+(define-key evil-ex-search-keymap "\C-v" #'quoted-insert)
+(define-key evil-ex-search-keymap "\C-w" 'backward-kill-word)
+
+;; ex command line
+(define-key evil-ex-completion-map "\d" #'evil-ex-delete-backward-char)
+(define-key evil-ex-completion-map "\t" #'evil-ex-completion)
+(define-key evil-ex-completion-map [tab] #'evil-ex-completion)
+(define-key evil-ex-completion-map [remap completion-at-point] #'evil-ex-completion)
+(define-key evil-ex-completion-map "\C-a" 'evil-ex-completion)
+(define-key evil-ex-completion-map "\C-b" 'move-beginning-of-line)
+(define-key evil-ex-completion-map "\C-c" 'abort-recursive-edit)
+(define-key evil-ex-completion-map "\C-d" 'evil-ex-completion)
+(define-key evil-ex-completion-map "\C-f" 'evil-ex-command-window)
+(define-key evil-ex-completion-map "\C-g" 'abort-recursive-edit)
+(define-key evil-ex-completion-map "\C-k" 'evil-insert-digraph)
+(define-key evil-ex-completion-map "\C-l" 'evil-ex-completion)
+(define-key evil-ex-completion-map "\C-p" #'previous-complete-history-element)
+(define-key evil-ex-completion-map "\C-r" 'evil-paste-from-register)
+(define-key evil-ex-completion-map "\C-n" #'next-complete-history-element)
+(define-key evil-ex-completion-map "\C-u" 'evil-delete-whole-line)
+(define-key evil-ex-completion-map "\C-v" #'quoted-insert)
+(define-key evil-ex-completion-map "\C-w" 'backward-kill-word)
+(define-key evil-ex-completion-map [escape] 'abort-recursive-edit)
+(define-key evil-ex-completion-map [S-left] 'backward-word)
+(define-key evil-ex-completion-map [S-right] 'forward-word)
+(define-key evil-ex-completion-map [up] 'previous-complete-history-element)
+(define-key evil-ex-completion-map [down] 'next-complete-history-element)
+(define-key evil-ex-completion-map [prior] 'previous-history-element)
+(define-key evil-ex-completion-map [next] 'next-history-element)
+(define-key evil-ex-completion-map [return] 'exit-minibuffer)
+(define-key evil-ex-completion-map (kbd "RET") 'exit-minibuffer)
+
+;; eval prompt (the `=' register)
+(define-key evil-eval-map "\C-b" 'move-beginning-of-line)
+(define-key evil-eval-map "\C-c" 'abort-recursive-edit)
+(define-key evil-eval-map "\C-g" 'abort-recursive-edit)
+(define-key evil-eval-map "\C-k" 'evil-insert-digraph)
+(define-key evil-eval-map "\C-p" #'previous-complete-history-element)
+(define-key evil-eval-map "\C-r" 'evil-paste-from-register)
+(define-key evil-eval-map "\C-n" #'next-complete-history-element)
+(define-key evil-eval-map "\C-u" 'evil-delete-whole-line)
+(define-key evil-eval-map "\C-v" #'quoted-insert)
+(define-key evil-eval-map "\C-w" 'backward-kill-word)
+(define-key evil-eval-map [escape] 'abort-recursive-edit)
+(define-key evil-eval-map [S-left] 'backward-word)
+(define-key evil-eval-map [S-right] 'forward-word)
+(define-key evil-eval-map [up] 'previous-complete-history-element)
+(define-key evil-eval-map [down] 'next-complete-history-element)
+(define-key evil-eval-map [prior] 'previous-history-element)
+(define-key evil-eval-map [next] 'next-history-element)
+(define-key evil-eval-map [return] 'exit-minibuffer)
+(define-key evil-eval-map (kbd "RET") 'exit-minibuffer)
+
+;; evil-read-key
+(define-key evil-read-key-map (kbd "ESC") #'keyboard-quit)
+(define-key evil-read-key-map (kbd "C-]") #'keyboard-quit)
+(define-key evil-read-key-map (kbd "C-g") #'keyboard-quit)
+(define-key evil-read-key-map (kbd "C-q") #'evil-read-quoted-char)
+(define-key evil-read-key-map (kbd "C-v") #'evil-read-quoted-char)
+(define-key evil-read-key-map (kbd "C-k") #'evil-read-digraph-char)
+(define-key evil-read-key-map "\r" "\n")
+
+;; command line window
+(evil-define-key 'normal
+ evil-command-window-mode-map (kbd "RET") 'evil-command-window-execute)
+(evil-define-key 'insert
+ evil-command-window-mode-map (kbd "RET") 'evil-command-window-execute)
+
+(provide 'evil-maps)
+
+;;; evil-maps.el ends here
diff --git a/elpa/evil-20220503.1314/evil-maps.elc b/elpa/evil-20220503.1314/evil-maps.elc
new file mode 100644
index 0000000..01fd9aa
--- /dev/null
+++ b/elpa/evil-20220503.1314/evil-maps.elc
Binary files differ
diff --git a/elpa/evil-20220503.1314/evil-pkg.el b/elpa/evil-20220503.1314/evil-pkg.el
new file mode 100644
index 0000000..1b658e2
--- /dev/null
+++ b/elpa/evil-20220503.1314/evil-pkg.el
@@ -0,0 +1,12 @@
+(define-package "evil" "20220503.1314" "Extensible Vi layer for Emacs."
+ '((emacs "24.1")
+ (goto-chg "1.6")
+ (cl-lib "0.5"))
+ :commit "6c5079b105b2ccbcfa735fd1b6a19797daa7081d" :maintainer
+ '("Tom Dalziel" . "tom.dalziel@gmail.com")
+ :keywords
+ '("emulation" "vim")
+ :url "https://github.com/emacs-evil/evil")
+;; Local Variables:
+;; no-byte-compile: t
+;; End:
diff --git a/elpa/evil-20220503.1314/evil-repeat.el b/elpa/evil-20220503.1314/evil-repeat.el
new file mode 100644
index 0000000..f305704
--- /dev/null
+++ b/elpa/evil-20220503.1314/evil-repeat.el
@@ -0,0 +1,646 @@
+;;; evil-repeat.el --- Repeat system -*- lexical-binding: t -*-
+
+;; Author: Frank Fischer <frank.fischer at mathematik.tu-chemnitz.de>
+;; Maintainer: Vegard Øye <vegard_oye at hotmail.com>
+
+;; Version: 1.15.0
+
+;;
+;; This file is NOT part of GNU Emacs.
+
+;;; License:
+
+;; This file is part of Evil.
+;;
+;; Evil 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.
+;;
+;; Evil 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 Evil. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; A repeat begins when leaving Normal state; it ends when re-entering
+;; Normal state. The diagram below shows possible routes between
+;; Normal state (N), Insert state (I), Visual state (V),
+;; Operator-Pending state (O) and Replace state (R). (Emacs state
+;; is an exception: nothing is repeated in that state.)
+;; ___
+;; / \
+;; | R |
+;; \___/
+;; ^ |
+;; | |
+;; ___ |___V ___
+;; / \ <------- / \ -------> / \
+;; | V | | N | | O |
+;; \___/ -------> \___/ <------- \___/
+;; | | ^ |
+;; | | | |
+;; | V___| |
+;; | / \ |
+;; +--------> | I | <--------+
+;; \___/
+;;
+;; The recording of a repeat is started in one of two cases: Either a
+;; command is about to be executed (in pre-command-hook) or normal
+;; state is exited. The recording is stopped whenever a command has
+;; been completed and evil is in normal state afterwards. Therefore,
+;; a non-inserting command in normal-state is recorded as a single
+;; repeat unit. In contrast, if the command leaves normal state and
+;; starts insert-state, all commands that are executed until
+;; insert-state is left and normal state is reactivated are recorded
+;; together in one repeat unit. In other words, a repeat unit consists
+;; of all commands that are executed starting and ending in normal
+;; state.
+;;
+;; Not all commands are recorded. There are several commands that are
+;; completely ignored and other commands that even abort the currently
+;; active recording, e.g., commands that switch buffer.
+;;
+;; During recording the repeat information is appended to the variable
+;; `evil-repeat-info', which is cleared when the recording
+;; starts. This accumulated repeat information is put into the
+;; `evil-repeat-ring' when the recording is finished. The dot command,
+;; `\[evil-repeat]' (`evil-repeat') replays the most recent entry in
+;; the ring, preceeding repeats can be replayed using
+;; `\[evil-repeat-pop]' (`evil-repeat-pop').
+;;
+;; Repeat information can be stored in almost arbitrary form. How the
+;; repeat information for each single command is recored is determined
+;; by the :repeat property of the command. This property has the
+;; following interpretation:
+;;
+;; t record commands by storing the key-sequence that invoked it
+;; nil ignore this command completely
+;; ignore synonym to nil
+;; motion command is recorded by storing the key-sequence but only in
+;; insert state, otherwise it is ignored.
+;; abort stop recording of repeat information immediately
+;; change record commands by storing buffer changes
+;; SYMBOL if SYMBOL is contained as key in `evil-repeat-types'
+;; call the corresponding (function-)value, otherwise
+;; call the function associated with SYMBOL. In both
+;; cases the function should take exactly one argument
+;; which is either 'pre or 'post depending on whether
+;; the function is called before or after the execution
+;; of the command.
+;;
+;; Therefore, using a certain SYMBOL one can write specific repeation
+;; functions for each command.
+;;
+;; Each value of ring `evil-repeat-info', i.e., each single repeat
+;; information must be one of the following two possibilities:
+;; If element is a sequence, it is regarded as a key-sequence to
+;; be repeated. Otherwise the element must be a list
+;; (FUNCTION PARAMS ...) which will be called using
+;; (apply FUNCTION PARAMS) whenever this repeat is being executed.
+;;
+;; A user supplied repeat function can use the functions
+;; `evil-record-repeat' to append further repeat-information of the
+;; form described above to `evil-repeat-info'. See the implementation
+;; of `evil-repeat-keystrokes' and `evil-repeat-changes' for examples.
+;; Those functions are called in different situations before and after
+;; the execution of a command. Each function should take one argument
+;; which can be either 'pre, 'post, 'pre-operator or 'post-operator
+;; specifying when the repeat function has been called. If the command
+;; is a usual command the function is called with 'pre before the
+;; command is executed and with 'post after the command has been
+;; executed.
+;;
+;; The repeat information is executed with `evil-execute-repeat-info',
+;; which passes key-sequence elements to `execute-kbd-macro' and
+;; executes other elements as defined above. A special version is
+;; `evil-execute-repeat-info-with-count'. This function works as
+;; `evil-execute-repeat-info', but replaces the count of the first
+;; command. This is done by parsing the key-sequence, ignoring all
+;; calls to `digit-prefix-argument' and `negative-argument', and
+;; prepending the count as a string to the vector of the remaining
+;; key-sequence.
+
+(require 'evil-states)
+
+;;; Code:
+
+(declare-function evil-visual-state-p "evil-visual")
+(declare-function evil-visual-range "evil-visual")
+(declare-function evil-visual-char "evil-visual")
+(declare-function evil-visual-line "evil-visual")
+(declare-function evil-visual-block "evil-visual")
+
+(defmacro evil-without-repeat (&rest body)
+ (declare (indent defun)
+ (debug t))
+ `(let ((pre-command-hook (remq 'evil-repeat-pre-hook pre-command-hook))
+ (post-command-hook (remq 'evil-repeat-post-hook post-command-hook)))
+ ,@body
+ (evil-repeat-abort)))
+
+(defsubst evil-repeat-recording-p ()
+ "Returns non-nil iff a recording is in progress."
+ (eq evil-recording-repeat t))
+
+(defun evil-repeat-start ()
+ "Start recording a new repeat into `evil-repeat-info'."
+ (evil-repeat-reset t)
+ (evil-repeat-record-buffer)
+ (when (evil-visual-state-p)
+ (let* ((range (evil-visual-range))
+ (beg (evil-range-beginning range))
+ (end (1- (evil-range-end range)))
+ (nfwdlines (evil-count-lines beg end)))
+ (evil-repeat-record
+ (cond
+ ((eq evil-visual-selection 'char)
+ (list #'evil-repeat-visual-char
+ nfwdlines
+ (- end
+ (if (zerop nfwdlines)
+ beg
+ (save-excursion
+ (goto-char end)
+ (line-beginning-position))))))
+ ((eq evil-visual-selection 'line)
+ (list #'evil-repeat-visual-line nfwdlines))
+ ((eq evil-visual-selection 'block)
+ (list #'evil-repeat-visual-block
+ nfwdlines
+ (abs (- (evil-column beg) (evil-column end))))))))))
+
+(defun evil-repeat-stop ()
+ "Stop recording a repeat.
+Update `evil-repeat-ring' with the accumulated changes
+in `evil-repeat-info' and clear variables."
+ (unwind-protect
+ (when (evil-repeat-recording-p)
+ (setq evil-repeat-info
+ (evil-normalize-repeat-info evil-repeat-info))
+ (when (and evil-repeat-info evil-repeat-ring)
+ (ring-insert evil-repeat-ring evil-repeat-info)))
+ (evil-repeat-reset nil)))
+
+(defun evil-repeat-abort ()
+ "Abort current repeation."
+ (evil-repeat-reset 'abort))
+
+(defun evil-repeat-reset (flag)
+ "Clear all repeat recording variables.
+Set `evil-recording-repeat' to FLAG."
+ (setq evil-recording-repeat flag
+ evil-repeat-info nil
+ evil-repeat-buffer nil))
+
+(defsubst evil-repeat-record-position (&optional pos)
+ "Set `evil-repeat-pos' to POS or point."
+ (setq evil-repeat-pos (or pos (point))))
+
+(defun evil-repeat-record-buffer ()
+ "Set `evil-repeat-buffer' to the current buffer."
+ (unless (minibufferp)
+ (setq evil-repeat-buffer (current-buffer))))
+
+(defmacro evil-save-repeat-info (&rest body)
+ "Execute BODY, protecting the values of repeat variables."
+ (declare (indent defun)
+ (debug t))
+ `(let (evil-repeat-ring
+ evil-recording-repeat
+ evil-recording-current-command
+ evil-repeat-info
+ evil-repeat-changes
+ evil-repeat-pos
+ evil-repeat-keys
+ evil-repeat-buffer
+ this-command
+ last-command)
+ ,@body))
+
+(defun evil-repeat-different-buffer-p (&optional strict)
+ "Whether the buffer has changed in a repeat.
+If STRICT is non-nil, returns t if the previous buffer
+is unknown; otherwise returns t only if the previous
+buffer is known and different from the current buffer."
+ (and (or (buffer-live-p evil-repeat-buffer) strict)
+ (not (minibufferp))
+ (not (eq (current-buffer) evil-repeat-buffer))))
+
+(defun evil-repeat-type (command &optional default)
+ "Return the :repeat property of COMMAND.
+If COMMAND doesn't have this property, return DEFAULT."
+ (when (functionp command) ; ignore keyboard macros
+ (let* ((type (evil-get-command-property command :repeat default))
+ (repeat-type (assq type evil-repeat-types)))
+ (if repeat-type (cdr repeat-type) type))))
+
+(defun evil-repeat-force-abort-p (repeat-type)
+ "Returns non-nil iff the current command should abort the recording of repeat information."
+ (or (evil-repeat-different-buffer-p) ; ... buffer changed
+ (eq repeat-type 'abort) ; ... explicitely forced
+ (eq evil-recording-repeat 'abort) ; ... already aborted
+ (evil-emacs-state-p) ; ... in Emacs state
+ (and (evil-mouse-events-p (this-command-keys)) ; ... mouse events
+ (eq repeat-type nil))
+ (minibufferp))) ; ... minibuffer activated
+
+(defun evil-repeat-record (info)
+ "Add INFO to the end of `evil-repeat-info'."
+ (when (evil-repeat-recording-p)
+ (setq evil-repeat-info (nconc evil-repeat-info (list info)))))
+
+;; called from `evil-normal-state-exit-hook'
+(defun evil-repeat-start-hook ()
+ "Record a new repeat when exiting Normal state.
+Does not record in Emacs state or if the current command
+has :repeat nil."
+ (when (and (eq (evil-repeat-type this-command t) t)
+ (not (evil-emacs-state-p)))
+ (evil-repeat-start)))
+
+;; called from `pre-command-hook'
+(defun evil-repeat-pre-hook ()
+ "Prepare the current command for recording the repeation."
+ (when evil-local-mode
+ (let ((repeat-type (evil-repeat-type this-command t)))
+ (cond
+ ;; abort the repeat
+ ((evil-repeat-force-abort-p repeat-type)
+ ;; We mark the current record as being aborted, because there
+ ;; may be further pre-hooks following before the post-hook is
+ ;; called.
+ (evil-repeat-abort))
+ ;; ignore those commands completely
+ ((or (null repeat-type)
+ (evil-mouse-events-p (this-command-keys))))
+ ;; record command
+ (t
+ ;; In normal-state or visual state, each command is a single
+ ;; repeation, therefore start a new repeation.
+ (when (or (evil-normal-state-p)
+ (evil-visual-state-p))
+ (evil-repeat-start))
+ (setq evil-recording-current-command t)
+ (funcall repeat-type 'pre))))))
+(put 'evil-repeat-pre-hook 'permanent-local-hook t)
+
+;; called from `post-command-hook'
+(defun evil-repeat-post-hook ()
+ "Finish recording of repeat-information for the current-command."
+ (when (and evil-local-mode evil-recording-repeat)
+ (let ((repeat-type (evil-repeat-type this-command t)))
+ (cond
+ ;; abort the repeat
+ ((evil-repeat-force-abort-p repeat-type)
+ ;; The command has been aborted but is complete, so just reset
+ ;; the recording state.
+ (evil-repeat-reset nil))
+ ;; ignore if command should not be recorded or the current
+ ;; command is not being recorded
+ ((or (null repeat-type)
+ (not evil-recording-current-command)))
+ ;; record command
+ (t
+ (funcall repeat-type 'post)
+ ;; In normal state, the repeat sequence is complete, so record it.
+ (when (evil-normal-state-p)
+ (evil-repeat-stop)))))
+ ;; done with recording the current command
+ (setq evil-recording-current-command nil)))
+(put 'evil-repeat-post-hook 'permanent-local-hook t)
+
+(defun evil-clear-command-keys ()
+ "Clear `this-command-keys' and all information about the current command keys.
+Calling this function prevents further recording of the keys that
+invoked the current command"
+ (clear-this-command-keys t)
+ (setq evil-repeat-keys ""))
+
+(defun evil-this-command-keys (&optional post-cmd)
+ "Version of `this-command-keys' with finer control over prefix args."
+ (let ((arg (if post-cmd current-prefix-arg prefix-arg)))
+ (vconcat
+ (when (and (numberp arg)
+ ;; Only add prefix if no repeat info recorded yet
+ (null evil-repeat-info))
+ (string-to-vector (number-to-string arg)))
+ (this-single-command-keys))))
+
+(defun evil-repeat-keystrokes (flag)
+ "Repeation recording function for commands that are repeated by keystrokes."
+ (cond
+ ((eq flag 'pre)
+ (when evil-this-register
+ (evil-repeat-record
+ `(set evil-this-register ,evil-this-register)))
+ (setq evil-repeat-keys (evil-this-command-keys)))
+ ((eq flag 'post)
+ (evil-repeat-record (if (zerop (length (evil-this-command-keys t)))
+ evil-repeat-keys
+ (evil-this-command-keys t)))
+ ;; erase commands keys to prevent double recording
+ (evil-clear-command-keys))))
+
+(defun evil-repeat-motion (flag)
+ "Repeation for motions. Motions are recorded by keystroke but only in insert state."
+ (when (memq evil-state '(insert replace))
+ (evil-repeat-keystrokes flag)))
+
+(defun evil-repeat-changes (flag)
+ "Repeation recording function for commands that are repeated by buffer changes."
+ (cond
+ ((eq flag 'pre)
+ (add-hook 'after-change-functions #'evil-repeat-change-hook nil t)
+ (evil-repeat-start-record-changes))
+ ((eq flag 'post)
+ (remove-hook 'after-change-functions #'evil-repeat-change-hook t)
+ (evil-repeat-finish-record-changes))))
+
+;; called from the `after-change-functions' hook
+(defun evil-repeat-change-hook (beg end length)
+ "Record change information for current command."
+ (let ((repeat-type (evil-repeat-type this-command t)))
+ (when (and (evil-repeat-recording-p)
+ (eq repeat-type 'evil-repeat-changes)
+ (not (evil-emacs-state-p))
+ (not (evil-repeat-different-buffer-p t))
+ evil-state)
+ (unless (evil-repeat-recording-p)
+ (evil-repeat-start))
+ (evil-repeat-record-change (- beg evil-repeat-pos)
+ (buffer-substring beg end)
+ length))))
+(put 'evil-repeat-change-hook 'permanent-local-hook t)
+
+(defun evil-repeat-record-change (relpos ins ndel)
+ "Record the current buffer changes during a repeat.
+If CHANGE is specified, it is added to `evil-repeat-changes'."
+ (when (evil-repeat-recording-p)
+ (setq evil-repeat-changes
+ (nconc evil-repeat-changes (list (list relpos ins ndel))))))
+
+(defun evil-repeat-start-record-changes ()
+ "Starts the recording of a new set of buffer changes."
+ (setq evil-repeat-changes nil)
+ (evil-repeat-record-position))
+
+(defun evil-repeat-finish-record-changes ()
+ "Finishes the recording of buffer changes and records them as repeat."
+ (when (evil-repeat-recording-p)
+ (evil-repeat-record `(evil-execute-change
+ ,evil-repeat-changes
+ ,(- (point) evil-repeat-pos)))
+ (setq evil-repeat-changes nil)))
+
+(defun evil-repeat-insert-at-point (flag)
+ "Repeation recording function for commands that insert text in region.
+For example `mouse-yank-primary'. This records text insertion when a command
+inserts some text in a buffer between (point) and (mark)."
+ (cond
+ ((eq flag 'pre)
+ (add-hook 'after-change-functions #'evil-repeat-insert-at-point-hook nil t))
+ ((eq flag 'post)
+ (remove-hook 'after-change-functions #'evil-repeat-insert-at-point-hook t))))
+
+(defun evil-repeat-insert-at-point-hook (beg end _length)
+ (let ((repeat-type (evil-repeat-type this-command t)))
+ (when (and (evil-repeat-recording-p)
+ (eq repeat-type 'evil-repeat-insert-at-point)
+ (not (evil-emacs-state-p))
+ (not (evil-repeat-different-buffer-p t))
+ evil-state)
+ (setq evil-repeat-pos beg)
+ (evil-repeat-record (list 'insert (buffer-substring beg end))))))
+(put 'evil-repeat-insert-at-point-hook 'permanent-local-hook t)
+
+(defun evil-normalize-repeat-info (repeat-info)
+ "Concatenate consecutive arrays in REPEAT-INFO.
+Returns a single array."
+ (let* ((result (cons nil nil))
+ (result-last result)
+ cur cur-last)
+ (dolist (rep repeat-info)
+ (cond
+ ((null rep))
+ ((arrayp rep)
+ (setq rep (listify-key-sequence rep))
+ (cond
+ (cur
+ (setcdr cur-last (cons rep nil))
+ (setq cur-last (cdr cur-last)))
+ (t
+ (setq cur (cons rep nil))
+ (setq cur-last cur))))
+ (t
+ (when cur
+ (setcdr result-last (cons (apply #'vconcat cur) nil))
+ (setq result-last (cdr result-last))
+ (setq cur nil))
+ (setcdr result-last (cons rep nil))
+ (setq result-last (cdr result-last)))))
+ (when cur
+ (setcdr result-last (cons (apply #'vconcat cur) nil)))
+ (cdr result)))
+
+(defun evil-repeat-visual-char (nfwdlines nfwdchars)
+ "Restores a character visual selection.
+If the selection is in a single line, the restored visual
+selection covers the same number of characters. If the selection
+covers several lines, the restored selection covers the same
+number of lines and the same number of characters in the last
+line as the original selection."
+ (evil-visual-char)
+ (when (> nfwdlines 0)
+ (forward-line nfwdlines))
+ (forward-char nfwdchars))
+
+(defun evil-repeat-visual-line (nfwdlines)
+ "Restores a character visual selection.
+If the selection is in a single line, the restored visual
+selection covers the same number of characters. If the selection
+covers several lines, the restored selection covers the same
+number of lines and the same number of characters in the last
+line as the original selection."
+ (evil-visual-line)
+ (forward-line nfwdlines))
+
+(defun evil-repeat-visual-block (nfwdlines nfwdchars)
+ "Restores a character visual selection.
+If the selection is in a single line, the restored visual
+selection covers the same number of characters. If the selection
+covers several lines, the restored selection covers the same
+number of lines and the same number of characters in the last
+line as the original selection."
+ (evil-visual-block)
+ (let ((col (current-column)))
+ (forward-line nfwdlines)
+ (move-to-column (+ col nfwdchars) t)))
+
+(defun evil-execute-change (changes rel-point)
+ "Executes as list of changes.
+
+CHANGES is a list of triples (REL-BEG INSERT-TEXT NDEL).
+REL-BEG is the relative position (to point) where the change
+takes place. INSERT-TEXT is the text to be inserted at that
+position and NDEL the number of characters to be deleted at that
+position before insertion.
+
+REL-POINT is the relative position to point before the changed
+where point should be placed after all changes."
+ (evil-save-repeat-info
+ (let ((point (point)))
+ (dolist (change changes)
+ (goto-char (+ point (nth 0 change)))
+ (delete-char (nth 2 change))
+ (insert (nth 1 change)))
+ (goto-char (+ point rel-point)))))
+
+(defun evil-execute-repeat-info (repeat-info)
+ "Executes a repeat-information REPEAT-INFO."
+ (evil-save-repeat-info
+ (dolist (rep repeat-info)
+ (cond
+ ((or (arrayp rep) (stringp rep))
+ (let ((input-method current-input-method)
+ (evil-input-method nil))
+ (deactivate-input-method)
+ (unwind-protect
+ (execute-kbd-macro rep)
+ (activate-input-method input-method))))
+ ((consp rep)
+ (when (and (= 3 (length rep))
+ (eq (nth 0 rep) 'set)
+ (eq (nth 1 rep) 'evil-this-register)
+ (>= (nth 2 rep) ?0)
+ (< (nth 2 rep) ?9))
+ (setcar (nthcdr 2 rep) (1+ (nth 2 rep))))
+ (apply (car rep) (cdr rep)))
+ (t
+ (error "Unexpected repeat-info: %S" rep))))))
+
+;; TODO: currently we prepend the replacing count before the
+;; key-sequence that calls the command. Can we use direct
+;; modification of prefix-arg instead? Does it work in
+;; conjunction with `execute-kbd-macro'?
+(defun evil-execute-repeat-info-with-count (count repeat-info)
+ "Repeat the repeat-information REPEAT-INFO with the count of
+the first command replaced by COUNT. The count is replaced if
+and only if COUNT is non-nil."
+ (evil-save-repeat-info
+ (cond
+ ;; do nothing (zero repeating)
+ ((and count (zerop count)))
+ ;; replace count
+ (count
+ (let ((evil-repeat-count count)
+ done)
+ (while (and repeat-info
+ (arrayp (car repeat-info))
+ (not done))
+ (let* ((count-and-cmd (evil-extract-count (pop repeat-info))))
+ (push (vconcat (number-to-string count)
+ (nth 2 count-and-cmd)
+ (nth 3 count-and-cmd))
+ repeat-info)
+ (setq done t)))
+ (evil-execute-repeat-info repeat-info)))
+ ;; repeat with original count
+ (t
+ (evil-execute-repeat-info repeat-info)))))
+
+;; Keep the compiler happy - this is a buffer local var
+(defvar evil--execute-normal-return-state)
+
+(evil-define-command evil-repeat (count &optional save-point)
+ "Repeat the last editing command with count replaced by COUNT.
+If SAVE-POINT is non-nil, do not move point."
+ :repeat ignore
+ :suppress-operator t
+ (interactive (list current-prefix-arg
+ (not evil-repeat-move-cursor)))
+ (cond
+ ((null evil-repeat-ring)
+ (error "Already executing repeat"))
+ (save-point
+ (save-excursion
+ (evil-repeat count)))
+ (t
+ (unwind-protect
+ (let ((evil-last-find-temp evil-last-find)
+ (confirm-kill-emacs t)
+ (kill-buffer-hook
+ (cons #'(lambda ()
+ (user-error "Cannot delete buffer in repeat command"))
+ kill-buffer-hook))
+ (undo-pointer buffer-undo-list))
+ (evil-with-single-undo
+ (setq evil-last-repeat (list (point) count undo-pointer))
+ (evil-execute-repeat-info-with-count
+ count (ring-ref evil-repeat-ring 0))
+ (setq evil-last-find evil-last-find-temp)))
+ (if (eq 'evil-execute-in-normal-state last-command)
+ (evil-change-state evil--execute-normal-return-state)
+ (evil-normal-state))))))
+
+;; TODO: the same issue concering disabled undos as for `evil-paste-pop'
+(evil-define-command evil-repeat-pop (count &optional save-point)
+ "Replace the just repeated command with a previously executed command.
+Only allowed after `evil-repeat', `evil-repeat-pop' or
+`evil-repeat-pop-next'. Uses the same repeat count that
+was used for the first repeat.
+
+The COUNT argument inserts the COUNT-th previous kill.
+If COUNT is negative, this is a more recent kill."
+ :repeat nil
+ :suppress-operator t
+ (interactive (list (prefix-numeric-value current-prefix-arg)
+ (not evil-repeat-move-cursor)))
+ (cond
+ ((not (and (eq last-command #'evil-repeat)
+ evil-last-repeat))
+ (user-error "Previous command was not evil-repeat: %s" last-command))
+ (save-point
+ (save-excursion
+ (evil-repeat-pop count)))
+ (t
+ (unless (eq buffer-undo-list (nth 2 evil-last-repeat))
+ (evil-undo-pop))
+ (goto-char (car evil-last-repeat))
+ ;; rotate the repeat-ring
+ (while (> count 0)
+ (when evil-repeat-ring
+ (ring-insert-at-beginning evil-repeat-ring
+ (ring-remove evil-repeat-ring 0)))
+ (setq count (1- count)))
+ (while (< count 0)
+ (when evil-repeat-ring
+ (ring-insert evil-repeat-ring
+ (ring-remove evil-repeat-ring)))
+ (setq count (1+ count)))
+ (setq this-command #'evil-repeat)
+ (evil-repeat (cadr evil-last-repeat)))))
+
+(evil-define-command evil-repeat-pop-next (count &optional save-point)
+ "Same as `evil-repeat-pop', but with negative COUNT."
+ :repeat nil
+ :suppress-operator t
+ (interactive (list (prefix-numeric-value current-prefix-arg)
+ (not evil-repeat-move-cursor)))
+ (evil-repeat-pop (- count) save-point))
+
+(defadvice read-key-sequence (before evil activate)
+ "Record `this-command-keys' before it is reset."
+ (when (and (evil-repeat-recording-p)
+ evil-recording-current-command)
+ (let ((repeat-type (evil-repeat-type this-command t)))
+ (if (functionp repeat-type)
+ (funcall repeat-type 'post)))))
+
+(provide 'evil-repeat)
+
+;;; evil-repeat.el ends here
diff --git a/elpa/evil-20220503.1314/evil-repeat.elc b/elpa/evil-20220503.1314/evil-repeat.elc
new file mode 100644
index 0000000..895645f
--- /dev/null
+++ b/elpa/evil-20220503.1314/evil-repeat.elc
Binary files differ
diff --git a/elpa/evil-20220503.1314/evil-search.el b/elpa/evil-20220503.1314/evil-search.el
new file mode 100644
index 0000000..0cc9c1b
--- /dev/null
+++ b/elpa/evil-20220503.1314/evil-search.el
@@ -0,0 +1,1336 @@
+;;; evil-search.el --- Search and substitute -*- lexical-binding: t -*-
+
+;; Author: Vegard Øye <vegard_oye at hotmail.com>
+;; Maintainer: Vegard Øye <vegard_oye at hotmail.com>
+
+;; Version: 1.15.0
+
+;;
+;; This file is NOT part of GNU Emacs.
+
+;;; License:
+
+;; This file is part of Evil.
+;;
+;; Evil 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.
+;;
+;; Evil 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 Evil. If not, see <http://www.gnu.org/licenses/>.
+
+(require 'evil-core)
+(require 'evil-common)
+(require 'evil-ex)
+
+;;; Code:
+
+(defun evil-select-search-module (option module)
+ "Change the search module according to MODULE.
+If MODULE is `isearch', then Emacs' isearch module is used.
+If MODULE is `evil-search', then Evil's own interactive
+search module is used."
+ (let ((search-functions
+ '(forward
+ backward
+ word-forward
+ word-backward
+ unbounded-word-forward
+ unbounded-word-backward
+ next
+ previous)))
+ (dolist (fun search-functions)
+ (let ((isearch (intern (format "evil-search-%s" fun)))
+ (evil-search (intern (format "evil-ex-search-%s" fun))))
+ (if (eq module 'isearch)
+ (substitute-key-definition
+ evil-search isearch evil-motion-state-map)
+ (substitute-key-definition
+ isearch evil-search evil-motion-state-map)))))
+ (set-default option module))
+
+;; this customization is here because it requires
+;; the knowledge of `evil-select-search-mode'
+(defcustom evil-search-module 'isearch
+ "The search module to be used. May be either `isearch', for
+Emacs' isearch module, or `evil-search', for Evil's own
+interactive search module. N.b. changing this will not affect keybindings.
+To swap out relevant keybindings, see `evil-select-search-module' function."
+ :type '(radio (const :tag "Emacs built-in isearch." :value isearch)
+ (const :tag "Evil interactive search." :value evil-search))
+ :group 'evil
+ :set 'evil-select-search-module
+ :initialize 'evil-custom-initialize-pending-reset)
+
+(defun evil-push-search-history (string forward)
+ "Push STRING into the appropriate search history (determined by FORWARD)."
+ (let* ((history-var (if forward
+ 'evil-search-forward-history
+ 'evil-search-backward-history))
+ (history (symbol-value history-var)))
+ (unless (equal (car-safe history) string)
+ (set history-var (cons string history)))))
+
+(defun evil-search-incrementally (forward regexp-p)
+ "Search incrementally for user-entered text."
+ (let ((evil-search-prompt (evil-search-prompt forward))
+ (isearch-search-fun-function 'evil-isearch-function)
+ (point (point))
+ search-nonincremental-instead)
+ (setq isearch-forward forward)
+ (evil-save-echo-area
+ (evil-without-input-method-hooks
+ ;; set the input method locally rather than globally to ensure that
+ ;; isearch clears the input method when it's finished
+ (setq current-input-method evil-input-method)
+ (if forward
+ (isearch-forward regexp-p)
+ (isearch-backward regexp-p))
+ (evil-push-search-history isearch-string forward)
+ (setq current-input-method nil))
+ (when (/= (point) point)
+ ;; position the point at beginning of the match only if the call to
+ ;; `isearch' has really moved the point. `isearch' doesn't move the
+ ;; point only if "C-g" is hit twice to exit the search, in which case we
+ ;; shouldn't move the point either.
+ (when (and forward isearch-other-end)
+ (goto-char isearch-other-end))
+ (when (and (eq point (point))
+ (not (string= isearch-string "")))
+ (if forward
+ (isearch-repeat-forward)
+ (isearch-repeat-backward))
+ (isearch-exit)
+ (when (and forward isearch-other-end)
+ (goto-char isearch-other-end)))
+ (evil-flash-search-pattern
+ (evil-search-message isearch-string forward))))))
+
+(defun evil-flash-search-pattern (string &optional all)
+ "Flash last search matches for duration of `evil-flash-delay'.
+If ALL is non-nil, flash all matches. STRING is a message
+to display in the echo area."
+ (let ((lazy-highlight-initial-delay 0)
+ (isearch-search-fun-function 'evil-isearch-function)
+ (isearch-case-fold-search case-fold-search)
+ (disable #'(lambda (&optional _arg) (evil-flash-hook t))))
+ (when evil-flash-timer
+ (cancel-timer evil-flash-timer))
+ (unless (or (null string)
+ (string= string ""))
+ (evil-echo-area-save)
+ (evil-echo "%s" string)
+ (isearch-highlight (match-beginning 0) (match-end 0))
+ (when all
+ (setq isearch-lazy-highlight-wrapped nil
+ isearch-lazy-highlight-start (point)
+ isearch-lazy-highlight-end (point))
+ (isearch-lazy-highlight-new-loop)
+ (unless isearch-lazy-highlight-overlays
+ (isearch-lazy-highlight-update)))
+ (add-hook 'pre-command-hook #'evil-flash-hook nil t)
+ (add-hook 'evil-operator-state-exit-hook #'evil-flash-hook nil t)
+ (add-hook 'pre-command-hook #'evil-clean-isearch-overlays nil t)
+ (setq evil-flash-timer
+ (run-at-time evil-flash-delay nil disable)))))
+
+(defun evil-clean-isearch-overlays ()
+ "Clean isearch overlays unless `this-command' is search."
+ (remove-hook 'pre-command-hook #'evil-clean-isearch-overlays t)
+ (unless (memq this-command
+ '(evil-search-backward
+ evil-search-forward
+ evil-search-next
+ evil-search-previous
+ evil-search-word-backward
+ evil-search-word-forward))
+ (isearch-clean-overlays)))
+(put 'evil-clean-isearch-overlays 'permanent-local-hook t)
+
+(defun evil-flash-hook (&optional force)
+ "Disable hightlighting if `this-command' is not search.
+Disable anyway if FORCE is t."
+ (when (or force
+ ;; to avoid flicker, don't disable highlighting
+ ;; if the next command is also a search command
+ (not (memq this-command
+ '(evil-search-backward
+ evil-search-forward
+ evil-search-next
+ evil-search-previous
+ evil-search-word-backward
+ evil-search-word-forward))))
+ (evil-echo-area-restore)
+ (isearch-dehighlight)
+ (setq isearch-lazy-highlight-last-string nil)
+ (lazy-highlight-cleanup t)
+ (when evil-flash-timer
+ (cancel-timer evil-flash-timer)))
+ (remove-hook 'pre-command-hook #'evil-flash-hook t)
+ (remove-hook 'evil-operator-state-exit-hook #'evil-flash-hook t))
+(put 'evil-flash-hook 'permanent-local-hook t)
+
+(defun evil-search-with-predicate (search-fun pred string bound noerror count)
+ "Execute a search with a predicate function.
+SEARCH-FUN is a search function (e.g. `re-search-forward') and
+PREDICATE is a two-argument function satisfying the interface of
+`isearch-filter-predicate', or `nil'. STRING, BOUND, NOERROR and
+COUNT are passed unchanged to SEARCH-FUN. The first match
+satisfying the predicate (or `nil') is returned."
+ (catch 'done
+ (while t
+ (let ((result (funcall search-fun string bound noerror count)))
+ (cond
+ ((not result) (throw 'done nil))
+ ((not pred) (throw 'done result))
+ ((funcall pred (match-beginning 0) (match-end 0)) (throw 'done result)))))))
+
+(defun evil-search-function (&optional forward regexp-p wrap predicate)
+ "Return a search function.
+If FORWARD is nil, search backward, otherwise forward.
+If REGEXP-P is non-nil, the input is a regular expression.
+If WRAP is non-nil, the search wraps around the top or bottom
+of the buffer.
+If PREDICATE is non-nil, it must be a function accepting two
+arguments: the bounds of a match, returning non-nil if that match is
+acceptable."
+ `(lambda (string &optional bound noerror count)
+ (let ((start (point))
+ (search-fun ',(if regexp-p
+ (if forward
+ 're-search-forward
+ 're-search-backward)
+ (if forward
+ 'search-forward
+ 'search-backward)))
+ result)
+ (setq result (evil-search-with-predicate
+ search-fun ,predicate string
+ bound ,(if wrap t 'noerror) count))
+ (when (and ,wrap (null result))
+ (goto-char ,(if forward '(point-min) '(point-max)))
+ (unwind-protect
+ (setq result (evil-search-with-predicate
+ search-fun ,predicate string bound noerror count))
+ (unless result
+ (goto-char start))))
+ result)))
+
+(defun evil-isearch-function ()
+ "Return a search function for use with isearch.
+Based on `isearch-regexp' and `isearch-forward'."
+ (evil-search-function isearch-forward evil-regexp-search evil-search-wrap 'isearch-filter-predicate))
+
+(defun evil-search (string forward &optional regexp-p start)
+ "Search for STRING and highlight matches.
+If FORWARD is nil, search backward, otherwise forward.
+If REGEXP-P is non-nil, STRING is taken to be a regular expression.
+START is the position to search from; if unspecified, it is
+one more than the current position."
+ (when (and (stringp string)
+ (not (string= string "")))
+ (let* ((orig (point))
+ (start (or start
+ (if forward
+ (min (point-max) (1+ orig))
+ orig)))
+ (isearch-regexp regexp-p)
+ (isearch-forward forward)
+ (case-fold-search
+ (unless (and search-upper-case
+ (not (isearch-no-upper-case-p string nil)))
+ case-fold-search))
+ (search-func (evil-search-function
+ forward regexp-p evil-search-wrap 'isearch-filter-predicate)))
+ ;; no text properties, thank you very much
+ (set-text-properties 0 (length string) nil string)
+ ;; position to search from
+ (goto-char start)
+ (setq isearch-string string)
+ (isearch-update-ring string regexp-p)
+ (condition-case nil
+ (funcall search-func string)
+ (search-failed
+ (goto-char orig)
+ (user-error "\"%s\": %s not found"
+ string (if regexp-p "pattern" "string"))))
+ ;; always position point at the beginning of the match
+ (goto-char (match-beginning 0))
+ ;; determine message for echo area
+ (cond
+ ((and forward (< (point) start))
+ (when evil-search-wrap-ring-bell (ding))
+ (setq string "Search wrapped around BOTTOM of buffer"))
+ ((and (not forward) (> (point) start))
+ (when evil-search-wrap-ring-bell (ding))
+ (setq string "Search wrapped around TOP of buffer"))
+ (t
+ (setq string (evil-search-message string forward))))
+ (evil-flash-search-pattern string t))))
+
+(defun evil-search-word (forward unbounded symbol)
+ "Search for word near point.
+If FORWARD is nil, search backward, otherwise forward. If SYMBOL
+is non-nil then the functions searches for the symbol at point,
+otherwise for the word at point."
+ (let ((string (car-safe regexp-search-ring)))
+ (setq isearch-forward forward)
+ (cond
+ ((and (memq last-command
+ '(evil-search-word-forward
+ evil-search-word-backward))
+ (stringp string)
+ (not (string= string "")))
+ (evil-search string forward t))
+ (t
+ (setq string (evil-find-thing forward (if symbol 'symbol 'evil-word)))
+ (cond
+ ((null string)
+ (user-error "No word under point"))
+ (unbounded
+ (setq string (regexp-quote string)))
+ (t
+ (setq string
+ (format (if symbol "\\_<%s\\_>" "\\<%s\\>")
+ (regexp-quote string)))))
+ (evil-push-search-history string forward)
+ (evil-search string forward t)))))
+
+(defun evil--find-thing (forward thing)
+ "Return a cons of THING near point as a string and its position.
+THING should be a symbol understood by `thing-at-point',
+e.g. 'symbol or 'word. If FORWARD is nil, search backward,
+otherwise forward. Returns nil if nothing is found."
+ (let ((move (if forward #'forward-char #'backward-char))
+ (end (if forward #'eobp #'bobp))
+ string)
+ (save-excursion
+ (setq string (thing-at-point thing))
+ ;; if there's nothing under point, go forwards
+ ;; (or backwards) to find it
+ (while (and (null string) (not (funcall end)))
+ (funcall move)
+ (setq string (thing-at-point thing)))
+ (when (stringp string)
+ (set-text-properties 0 (length string) nil string))
+ (when (> (length string) 0)
+ (cons string (point))))))
+
+(defun evil-find-thing (forward thing)
+ "Return a THING near point as a string.
+THING should be a symbol understood by `thing-at-point',
+e.g. 'symbol or 'word. If FORWARD is nil, search backward,
+otherwise forward. Returns nil if nothing is found."
+ (car (evil--find-thing forward thing)))
+
+(defun evil-find-word (forward)
+ "Return word near point as a string.
+If FORWARD is nil, search backward, otherwise forward. Returns
+nil if nothing is found."
+ (evil-find-thing forward 'word))
+
+(defun evil-find-symbol (forward)
+ "Return word near point as a string.
+If FORWARD is nil, search backward, otherwise forward. Returns
+nil if nothing is found."
+ (evil-find-thing forward 'symbol))
+
+(defun evil-search-prompt (forward)
+ "Return the search prompt for the given direction."
+ (if forward "/" "?"))
+
+(defun evil-search-message (string forward)
+ "Prefix STRING with the search prompt."
+ (format "%s%s" (evil-search-prompt forward) string))
+
+(defadvice isearch-message-prefix (around evil activate)
+ "Use `evil-search-prompt'."
+ (if evil-search-prompt
+ (setq ad-return-value evil-search-prompt)
+ ad-do-it))
+
+(defadvice isearch-delete-char (around evil activate)
+ "Exit search if no search string."
+ (cond
+ ((and evil-search-prompt (string= isearch-string ""))
+ (let (search-nonincremental-instead)
+ (setq isearch-success nil)
+ (isearch-exit)))
+ (t
+ ad-do-it)))
+
+(defadvice isearch-lazy-highlight-search (around evil activate)
+ "Never wrap the search in this context."
+ (let (evil-search-wrap)
+ ad-do-it))
+
+;;; Ex search
+
+(defun evil-ex-regex-without-case (re)
+ "Return the regular expression without all occurrences of \\c and \\C."
+ (evil-transform-regexp re '((?c . "") (?C . ""))))
+
+(defun evil-ex-regex-case (re default-case)
+ "Return the case as implied by \\c or \\C in regular expression RE.
+If \\c appears anywhere in the pattern, the pattern is case
+insensitive. If \\C appears, the pattern is case sensitive.
+Only the first occurrence of \\c or \\C is used, all others are
+ignored. If neither \\c nor \\C appears in the pattern, the case
+specified by DEFAULT-CASE is used. DEFAULT-CASE should be either
+`sensitive', `insensitive' or `smart'. In the latter case, the pattern
+will be case-sensitive if and only if it contains an upper-case
+letter, otherwise it will be case-insensitive."
+ (cond
+ ((string-match "\\(?:^\\|[^\\\\]\\)\\(?:\\\\\\\\\\)*\\\\\\([cC]\\)" re)
+ (if (eq (aref (match-string 1 re) 0) ?c) 'insensitive 'sensitive))
+ ((eq default-case 'smart)
+ (if (isearch-no-upper-case-p re t)
+ 'insensitive
+ 'sensitive))
+ (t default-case)))
+
+;; a pattern
+(defun evil-ex-make-substitute-pattern (regexp flags)
+ "Creates a PATTERN for substitution with FLAGS.
+This function respects the values of `evil-ex-substitute-case'
+and `evil-ex-substitute-global'."
+ (evil-ex-make-pattern regexp
+ (cond
+ ((memq ?i flags) 'insensitive)
+ ((memq ?I flags) 'sensitive)
+ ((not evil-ex-substitute-case)
+ evil-ex-search-case)
+ (t evil-ex-substitute-case))
+ (or (and evil-ex-substitute-global
+ (not (memq ?g flags)))
+ (and (not evil-ex-substitute-global)
+ (memq ?g flags)))))
+
+(defun evil-ex-make-search-pattern (regexp)
+ "Creates a PATTERN for search.
+This function respects the values of `evil-ex-search-case'."
+ (evil-ex-make-pattern regexp evil-ex-search-case t))
+
+(defun evil-ex-make-pattern (regexp case whole-line)
+ "Create a new search pattern.
+REGEXP is the regular expression to be searched for. CASE should
+be either 'sensitive, 'insensitive for case-sensitive and
+case-insensitive search, respectively, or anything else. In the
+latter case the pattern is smart-case, i.e. it is automatically
+sensitive of the pattern contains one upper case letter,
+otherwise it is insensitive. The input REGEXP is considered a
+Vim-style regular expression if `evil-ex-search-vim-style-regexp'
+is non-nil, in which case it is transformed to an Emacs style
+regular expression (i.e. certain backslash-codes are
+transformed. Otherwise REGEXP must be an Emacs style regular
+expression and is not transformed."
+ (let ((re (evil-ex-regex-without-case regexp))
+ (ignore-case (eq (evil-ex-regex-case regexp case) 'insensitive)))
+ ;; possibly transform regular expression from vim-style to
+ ;; Emacs-style.
+ (if (and evil-ex-search-vim-style-regexp
+ (not (or (string-match-p "\\`\\\\_?<" regexp)
+ (string-match-p "\\\\_?>\\'" regexp))))
+ (setq re (evil-transform-vim-style-regexp re))
+ ;; Even for Emacs regular expressions we translate certain
+ ;; whitespace sequences
+ (setq re (evil-transform-regexp re
+ '((?t . "\t")
+ (?n . "\n")
+ (?r . "\r")))))
+ (list re ignore-case whole-line)))
+
+(defun evil-ex-pattern-regex (pattern)
+ "Return the regular expression of a search PATTERN."
+ (nth 0 pattern))
+
+(defun evil-ex-pattern-ignore-case (pattern)
+ "Return t if and only if PATTERN should ignore case."
+ (nth 1 pattern))
+
+(defun evil-ex-pattern-whole-line (pattern)
+ "Return t if and only if PATTERN should match all occurences of a line.
+Otherwise PATTERN matches only the first occurence."
+ (nth 2 pattern))
+
+;; Highlight
+(defun evil-ex-make-hl (name &rest args)
+ "Create a new highlight object with name NAME and properties ARGS.
+The following properties are supported:
+:face The face to be used for the highlighting overlays.
+:win The window in which the highlighting should be shown.
+ Note that the highlight will be visible in all windows showing
+ the corresponding buffer, but only the matches visible in the
+ specified window will actually be highlighted. If :win is nil,
+ the matches in all windows will be highlighted.
+:min The minimal buffer position for highlighted matches.
+:max The maximal buffer position for highlighted matches.
+:match-hook A hook to be called once for each highlight.
+ The hook must take two arguments, the highlight and
+ the overlay for that highlight.
+:update-hook A hook called once after updating the highlighting
+ with two arguments, the highlight and a message string
+ describing the current match status."
+ (unless (symbolp name)
+ (user-error "Expected symbol as name of highlight"))
+ (let ((face 'evil-ex-lazy-highlight)
+ (win (selected-window))
+ min max match-hook update-hook)
+ (while args
+ (let ((key (pop args))
+ (val (pop args)))
+ (cond
+ ((eq key :face) (setq face val))
+ ((eq key :win) (setq win val))
+ ((eq key :min) (setq min val))
+ ((eq key :max) (setq max val))
+ ((eq key :match-hook) (setq match-hook val))
+ ((eq key :update-hook) (setq update-hook val))
+ (t (user-error "Unexpected keyword: %s" key)))))
+ (when (assoc name evil-ex-active-highlights-alist)
+ (evil-ex-delete-hl name))
+ (when (null evil-ex-active-highlights-alist)
+ (add-hook 'window-scroll-functions
+ #'evil-ex-hl-update-highlights-scroll nil t)
+ (add-hook 'window-size-change-functions
+ #'evil-ex-hl-update-highlights-resize nil))
+ (push (cons name (vector name
+ nil
+ face
+ win
+ min
+ max
+ match-hook
+ update-hook
+ nil))
+ evil-ex-active-highlights-alist)))
+
+(defun evil-ex-hl-name (hl)
+ "Return the name of the highlight HL."
+ (aref hl 0))
+
+(defun evil-ex-hl-pattern (hl)
+ "Return the pattern of the highlight HL."
+ (aref hl 1))
+
+(defun evil-ex-hl-set-pattern (hl pattern)
+ "Set the pattern of the highlight HL to PATTERN."
+ (aset hl 1 pattern))
+
+(defun evil-ex-hl-face (hl)
+ "Return the face of the highlight HL."
+ (aref hl 2))
+
+(defun evil-ex-hl-window (hl)
+ "Return the window of the highlight HL."
+ (aref hl 3))
+
+(defun evil-ex-hl-min (hl)
+ "Return the minimal buffer position of the highlight HL."
+ (aref hl 4))
+
+(defun evil-ex-hl-set-min (hl min)
+ "Set the minimal buffer position of the highlight HL to MIN."
+ (aset hl 4 min))
+
+(defun evil-ex-hl-max (hl)
+ "Return the maximal buffer position of the highlight HL."
+ (aref hl 5))
+
+(defun evil-ex-hl-set-max (hl max)
+ "Set the minimal buffer position of the highlight HL to MAX."
+ (aset hl 5 max))
+
+(defun evil-ex-hl-match-hook (hl)
+ "Return the match-hook of the highlight HL."
+ (aref hl 6))
+
+(defun evil-ex-hl-update-hook (hl)
+ "Return the update-hook of the highlight HL."
+ (aref hl 7))
+
+(defun evil-ex-hl-overlays (hl)
+ "Return the list of active overlays of the highlight HL."
+ (aref hl 8))
+
+(defun evil-ex-hl-set-overlays (hl overlays)
+ "Set the list of active overlays of the highlight HL to OVERLAYS."
+ (aset hl 8 overlays))
+
+(defun evil-ex-delete-hl (name)
+ "Remove the highlighting object with a certain NAME."
+ (let ((hl (cdr-safe (assoc name evil-ex-active-highlights-alist))))
+ (when hl
+ (mapc #'delete-overlay (evil-ex-hl-overlays hl))
+ (setq evil-ex-active-highlights-alist
+ (assq-delete-all name evil-ex-active-highlights-alist))
+ (evil-ex-hl-update-highlights))
+ (when (null evil-ex-active-highlights-alist)
+ (remove-hook 'window-scroll-functions
+ #'evil-ex-hl-update-highlights-scroll t)
+ (remove-hook 'window-size-change-functions
+ #'evil-ex-hl-update-highlights-resize))))
+
+(defun evil-ex-hl-active-p (name)
+ "Whether the highlight with a certain NAME is active."
+ (and (assoc name evil-ex-active-highlights-alist) t))
+
+(defun evil-ex-hl-change (name pattern)
+ "Set the regular expression of highlight NAME to PATTERN."
+ (let ((hl (cdr-safe (assoc name evil-ex-active-highlights-alist))))
+ (when hl
+ (evil-ex-hl-set-pattern hl
+ (if (zerop (length pattern))
+ nil
+ pattern))
+ (evil-ex-hl-idle-update))))
+
+(defun evil-ex-hl-set-region (name beg end &optional _type)
+ "Set minimal and maximal position of highlight NAME to BEG and END."
+ (let ((hl (cdr-safe (assoc name evil-ex-active-highlights-alist))))
+ (when hl
+ (evil-ex-hl-set-min hl beg)
+ (evil-ex-hl-set-max hl end)
+ (evil-ex-hl-idle-update))))
+
+(defun evil-ex-hl-get-max (name)
+ "Return the maximal position of the highlight with name NAME."
+ (let ((hl (cdr-safe (assoc name evil-ex-active-highlights-alist))))
+ (and hl (evil-ex-hl-max hl))))
+
+(defun evil-ex-hl-update-highlights ()
+ "Update the overlays of all active highlights."
+ (dolist (hl (mapcar #'cdr evil-ex-active-highlights-alist))
+ (let* ((old-ovs (evil-ex-hl-overlays hl))
+ new-ovs
+ (pattern (evil-ex-hl-pattern hl))
+ (case-fold-search (evil-ex-pattern-ignore-case pattern))
+ (case-replace case-fold-search)
+ (face (evil-ex-hl-face hl))
+ (match-hook (evil-ex-hl-match-hook hl))
+ result)
+ (if pattern
+ ;; collect all visible ranges
+ (let (ranges sranges)
+ (dolist (win (if (eq evil-ex-interactive-search-highlight
+ 'all-windows)
+ (get-buffer-window-list (current-buffer) nil t)
+ (list (evil-ex-hl-window hl))))
+ (when (window-live-p win)
+ (let ((beg (max (window-start win)
+ (or (evil-ex-hl-min hl) (point-min))))
+ (end (min (window-end win)
+ (or (evil-ex-hl-max hl) (point-max)))))
+ (when (< beg end)
+ (push (cons beg end) ranges)))))
+ (setq ranges
+ (sort ranges #'(lambda (r1 r2) (< (car r1) (car r2)))))
+ (while ranges
+ (let ((r1 (pop ranges))
+ (r2 (pop ranges)))
+ (cond
+ ;; last range
+ ((null r2)
+ (push r1 sranges))
+ ;; ranges overlap, union
+ ((>= (cdr r1) (car r2))
+ (push (cons (car r1)
+ (max (cdr r1) (cdr r2)))
+ ranges))
+ ;; ranges distinct
+ (t
+ (push r1 sranges)
+ (push r2 ranges)))))
+
+ ;; run through all ranges
+ (condition-case lossage
+ (save-match-data
+ (dolist (r sranges)
+ (let ((beg (car r))
+ (end (cdr r)))
+ (save-excursion
+ (goto-char beg)
+ ;; set the overlays for the current highlight,
+ ;; reusing old overlays (if possible)
+ (while (and (not (eobp))
+ (evil-ex-search-find-next-pattern pattern)
+ (<= (match-end 0) end)
+ (not (and (= (match-end 0) end)
+ (string= (evil-ex-pattern-regex pattern)
+ "^"))))
+ (let ((ov (or (pop old-ovs) (make-overlay 0 0))))
+ (move-overlay ov (match-beginning 0) (match-end 0))
+ (overlay-put ov 'face face)
+ (overlay-put ov 'evil-ex-hl (evil-ex-hl-name hl))
+ (overlay-put ov 'priority 1000)
+ (push ov new-ovs)
+ (when match-hook (funcall match-hook hl ov)))
+ (cond
+ ((and (not (evil-ex-pattern-whole-line pattern))
+ (not (string-match-p "\n" (buffer-substring-no-properties
+ (match-beginning 0)
+ (match-end 0)))))
+ (forward-line))
+ ((= (match-beginning 0) (match-end 0))
+ (forward-char))
+ (t (goto-char (match-end 0))))))))
+ (mapc #'delete-overlay old-ovs)
+ (evil-ex-hl-set-overlays hl new-ovs)
+ (if (or (null pattern) new-ovs)
+ (setq result t)
+ ;; Maybe the match could just not be found somewhere else?
+ (save-excursion
+ (goto-char (or (evil-ex-hl-min hl) (point-min)))
+ (if (and (evil-ex-search-find-next-pattern pattern)
+ (< (match-end 0) (or (evil-ex-hl-max hl)
+ (point-max))))
+ (setq result (format "Match in line %d"
+ (line-number-at-pos
+ (match-beginning 0))))
+ (setq result "No match")))))
+
+ (invalid-regexp
+ (setq result (cadr lossage)))
+
+ (search-failed
+ (setq result (nth 2 lossage)))
+
+ (error
+ (setq result (format "%s" (cadr lossage))))
+
+ (user-error
+ (setq result (format "%s" (cadr lossage))))))
+ ;; no pattern, remove all highlights
+ (mapc #'delete-overlay old-ovs)
+ (evil-ex-hl-set-overlays hl new-ovs))
+ (when (evil-ex-hl-update-hook hl)
+ (funcall (evil-ex-hl-update-hook hl) hl result)))))
+
+(defun evil-ex-search-find-next-pattern (pattern &optional direction)
+ "Look for the next occurrence of PATTERN in a certain DIRECTION.
+Note that this function ignores the whole-line property of PATTERN."
+ (setq direction (or direction 'forward))
+ (let ((case-fold-search (evil-ex-pattern-ignore-case pattern)))
+ (cond
+ ((eq direction 'forward)
+ (re-search-forward (evil-ex-pattern-regex pattern) nil t))
+ ((eq direction 'backward)
+ (let* ((pnt (point))
+ (ret (re-search-backward (evil-ex-pattern-regex pattern) nil t))
+ (m (and ret (match-data))))
+ (if ret
+ (forward-char)
+ (goto-char (point-min)))
+ (let ((fwdret
+ (re-search-forward (evil-ex-pattern-regex pattern) nil t)))
+ (cond
+ ((and fwdret (< (match-beginning 0) pnt))
+ (setq ret fwdret)
+ (goto-char (match-beginning 0)))
+ (ret
+ (set-match-data m)
+ (goto-char (match-beginning 0)))
+ (t
+ (goto-char pnt)
+ ret)))))
+ (t
+ (user-error "Unknown search direction: %s" direction)))))
+
+(defun evil-ex-hl-idle-update ()
+ "Triggers the timer to update the highlights in the current buffer."
+ (when (and evil-ex-interactive-search-highlight
+ evil-ex-active-highlights-alist)
+ (when evil-ex-hl-update-timer
+ (cancel-timer evil-ex-hl-update-timer))
+ (setq evil-ex-hl-update-timer
+ (run-at-time evil-ex-hl-update-delay nil
+ #'evil-ex-hl-do-update-highlight
+ (current-buffer)))))
+
+(defun evil-ex-hl-do-update-highlight (&optional buffer)
+ "Timer function for updating the highlights."
+ (when (buffer-live-p buffer)
+ (with-current-buffer buffer
+ (evil-ex-hl-update-highlights)))
+ (setq evil-ex-hl-update-timer nil))
+
+(defun evil-ex-hl-update-highlights-scroll (win _beg)
+ "Update highlights after scrolling in some window."
+ (with-current-buffer (window-buffer win)
+ (evil-ex-hl-idle-update)))
+(put 'evil-ex-hl-update-highlights-scroll 'permanent-local-hook t)
+
+(defun evil-ex-hl-update-highlights-resize (frame)
+ "Update highlights after resizing a window."
+ (let ((buffers (delete-dups (mapcar #'window-buffer (window-list frame)))))
+ (dolist (buf buffers)
+ (with-current-buffer buf
+ (evil-ex-hl-idle-update)))))
+(put 'evil-ex-hl-update-highlights-resize 'permanent-local-hook t)
+
+;; interactive search
+(defun evil-ex-search-activate-highlight (pattern)
+ "Activate highlighting of the search pattern set to PATTERN.
+This function does nothing if `evil-ex-search-interactive' or
+`evil-ex-search-highlight-all' is nil. "
+ (when (and evil-ex-search-interactive evil-ex-search-highlight-all)
+ (with-current-buffer (or evil-ex-current-buffer (current-buffer))
+ (unless (evil-ex-hl-active-p 'evil-ex-search)
+ (evil-ex-make-hl 'evil-ex-search
+ :win (or (minibuffer-selected-window) (selected-window))))
+ (if pattern
+ (evil-ex-hl-change 'evil-ex-search pattern)))))
+
+(defun evil-ex-search (&optional count)
+ "Search forward or backward COUNT times for the current ex search pattern.
+The search pattern is determined by `evil-ex-search-pattern' and
+the direcion is determined by `evil-ex-search-direction'."
+ (setq evil-ex-search-start-point (point)
+ evil-ex-last-was-search t
+ count (or count 1))
+ (let ((orig (point))
+ wrapped)
+ (dotimes (_ (or count 1))
+ (when (eq evil-ex-search-direction 'forward)
+ (unless (eobp) (forward-char))
+ ;; maybe skip end-of-line
+ (when (and (not evil-move-beyond-eol) (eolp) (not (eobp)))
+ (forward-char)))
+ (let ((res (evil-ex-find-next nil nil (not evil-search-wrap))))
+ (cond
+ ((not res)
+ (goto-char orig)
+ (signal 'search-failed
+ (list (evil-ex-pattern-regex evil-ex-search-pattern))))
+ ((eq res 'wrapped) (setq wrapped t)))))
+ (if wrapped
+ (let (message-log-max)
+ (message "Search wrapped")))
+ (goto-char (match-beginning 0))
+ (setq evil-ex-search-match-beg (match-beginning 0)
+ evil-ex-search-match-end (match-end 0))
+ (evil-ex-search-goto-offset evil-ex-search-offset)
+ (evil-ex-search-activate-highlight evil-ex-search-pattern)))
+
+(defun evil-ex-find-next (&optional pattern direction nowrap)
+ "Search for the next occurrence of the PATTERN in DIRECTION.
+PATTERN must be created using `evil-ex-make-pattern', DIRECTION
+is either 'forward or 'backward. If NOWRAP is non nil, the search
+does not wrap at buffer boundaries. Furthermore this function
+only searches invisible text if `search-invisible' is t. If
+PATTERN is not specified the current global pattern
+`evil-ex-search-pattern' and if DIRECTION is not specified the
+current global direction `evil-ex-search-direction' is used.
+This function returns t if the search was successful, nil if it
+was unsuccessful and 'wrapped if the search was successful but
+has been wrapped at the buffer boundaries."
+ (setq pattern (or pattern evil-ex-search-pattern)
+ direction (or direction evil-ex-search-direction))
+ (unless (and pattern (evil-ex-pattern-regex pattern))
+ (signal 'search-failed (list "No search pattern")))
+ (catch 'done
+ (let (wrapped)
+ (while t
+ (let ((search-result (evil-ex-search-find-next-pattern pattern
+ direction)))
+ (cond
+ ((and search-result
+ (or (eq search-invisible t)
+ (not (isearch-range-invisible
+ (match-beginning 0) (match-end 0)))))
+ ;; successful search and not invisible
+ (throw 'done (if wrapped 'wrapped t)))
+ ((not search-result)
+ ;; unsuccessful search
+ (if nowrap
+ (throw 'done nil)
+ (setq nowrap t
+ wrapped t)
+ (goto-char (if (eq direction 'forward)
+ (point-min)
+ (point-max)))))))))))
+
+(defun evil-ex-search-update (pattern offset beg end message)
+ "Update the highlighting and info-message for the search pattern.
+PATTERN is the search pattern and OFFSET the associated offset.
+BEG and END specifiy the current match, MESSAGE is the info
+message to be shown. This function does nothing if
+`evil-ex-search-interactive' is nil."
+ (when evil-ex-search-interactive
+ (cond
+ ((and beg end)
+ ;; update overlay
+ (if evil-ex-search-overlay
+ (move-overlay evil-ex-search-overlay beg end)
+ (setq evil-ex-search-overlay
+ (make-overlay beg end))
+ (overlay-put evil-ex-search-overlay 'priority 1001)
+ (overlay-put evil-ex-search-overlay 'face 'evil-ex-search))
+ ;; move point
+ (goto-char beg)
+ (evil-ex-search-goto-offset offset)
+ ;; update highlights
+ (when evil-ex-search-highlight-all
+ (evil-ex-hl-change 'evil-ex-search pattern)))
+ (t
+ ;; no match
+ (when evil-ex-search-overlay
+ ;; remove overlay
+ (delete-overlay evil-ex-search-overlay)
+ (setq evil-ex-search-overlay nil))
+ ;; no highlights
+ (when evil-ex-search-highlight-all
+ (evil-ex-hl-change 'evil-ex-search nil))
+ ;; and go to initial position
+ (goto-char evil-ex-search-start-point)))
+ (when (stringp message)
+ (evil-ex-echo "%s" message))))
+
+(defun evil-ex-search-start-session ()
+ "Initialize Ex for interactive search."
+ (remove-hook 'minibuffer-setup-hook #'evil-ex-search-start-session)
+ (when evil-ex-search-incremental
+ (add-hook 'after-change-functions #'evil-ex-search-update-pattern nil t))
+ (add-hook 'minibuffer-exit-hook #'evil-ex-search-stop-session)
+ (add-hook 'mouse-leave-buffer-hook #'evil-ex-search-exit)
+ (evil-ex-search-activate-highlight nil))
+(put 'evil-ex-search-start-session 'permanent-local-hook t)
+
+(defun evil-ex-search-stop-session ()
+ "Stop interactive search."
+ (with-current-buffer evil-ex-current-buffer
+ ;; TODO: This is a bad fix to remove duplicates. The duplicates
+ ;; exist because `isearch-range-invisible' may add a single
+ ;; overlay multiple times if we are in an unlucky situation
+ ;; of overlapping overlays. This happens in our case because
+ ;; of the overlays that are used for (lazy) highlighting.
+ ;; Perhaps it would be better to disable those overlays
+ ;; temporarily before calling `isearch-range-invisible'.
+ (setq isearch-opened-overlays (delete-dups isearch-opened-overlays))
+ (isearch-clean-overlays))
+ (remove-hook 'minibuffer-exit-hook #'evil-ex-search-stop-session)
+ (remove-hook 'mouse-leave-buffer-hook #'evil-ex-search-exit)
+ (remove-hook 'after-change-functions #'evil-ex-search-update-pattern t)
+ (when evil-ex-search-overlay
+ (delete-overlay evil-ex-search-overlay)
+ (setq evil-ex-search-overlay nil)))
+(put 'evil-ex-search-stop-session 'permanent-local-hook t)
+
+(defun evil-ex-split-search-pattern (pattern direction)
+ "Split PATTERN in regexp, offset and next-pattern parts.
+Returns a triple (regexp offset next-search)."
+ (save-match-data
+ (if (or (and (eq direction 'forward)
+ (string-match "\\(?:^\\|[^\\\\]\\)\\(?:\\\\\\\\\\)*\\(/\\([^;]*\\)\\(?:;\\([/?].*\\)?\\)?\\)?$"
+ pattern))
+ (and (eq direction 'backward)
+ (string-match "\\(?:^\\|[^\\\\]\\)\\(?:\\\\\\\\\\)*\\(\\?\\([^;]*\\)\\(?:;\\([/?].*\\)?\\)?\\)?$"
+ pattern)))
+ (list (substring pattern 0 (match-beginning 1))
+ (match-string 2 pattern)
+ (match-string 3 pattern))
+ (list pattern nil nil))))
+
+(defun evil-ex-search-full-pattern (pattern-string count direction)
+ "Search for a full search pattern PATTERN-STRING in DIRECTION.
+This function split PATTERN-STRING in
+pattern/offset/;next-pattern parts and performs the search in
+DIRECTION which must be either 'forward or 'backward. The first
+search is repeated COUNT times. If the pattern part of
+PATTERN-STRING is empty, the last global pattern stored in
+`evil-ex-search-pattern' is used instead if in addition the
+offset part is nil (i.e. no pattern/offset separator), the last
+global offset stored in `evil-ex-search-offset' is used as
+offset. The current match data will correspond to the last
+successful match. This function returns a triple (RESULT PATTERN
+OFFSET) where RESULT is
+
+ t the search has been successful without wrap
+ 'wrap the search has been successful with wrap
+ 'empty-pattern the last pattern has been empty
+ nil the search has not been successful
+
+and PATTERN and OFFSET are the last pattern and offset this
+function searched for. Note that this function does not handle
+any error conditions."
+ (setq count (or count 1))
+ (catch 'done
+ (while t
+ (let* ((res (evil-ex-split-search-pattern pattern-string direction))
+ (pat (pop res))
+ (offset (pop res))
+ (next-pat (pop res))
+ (orig-pat pat))
+ ;; use last pattern if no new pattern has been specified
+ (if (not (zerop (length pat)))
+ (setq pat (evil-ex-make-search-pattern pat))
+ (setq pat evil-ex-search-pattern
+ offset (or offset evil-ex-search-offset)))
+ (when (zerop (length pat))
+ (throw 'done (list 'empty-pattern pat offset)))
+ (let (new-dir repeat-last search-result)
+ (while (> count 0)
+ (let ((result (evil-ex-find-next pat direction
+ (not evil-search-wrap))))
+ (if (not result) (setq search-result nil count 0)
+ (setq search-result
+ (if (or (eq result 'wrap)
+ (eq search-result 'wrap))
+ 'wrap t)
+ count (1- count)))))
+ (cond
+ ;; search failed
+ ((not search-result) (throw 'done (list nil pat offset)))
+ ;; no next pattern, search complete
+ ((zerop (length next-pat))
+ (evil-ex-search-goto-offset offset)
+ (throw 'done (list search-result pat offset)))
+ ;; single `?' or `/' means repeat last pattern and finish
+ ((= 1 (length next-pat))
+ (evil-ex-search-goto-offset offset)
+ (setq new-dir (if (string= "/" next-pat) 'forward 'backward)
+ count (if (eq direction new-dir) 1 2)
+ pattern-string orig-pat
+ direction new-dir))
+ ;; next non-empty pattern, next search iteration
+ (t
+ (evil-ex-search-goto-offset offset)
+ (setq new-dir (if (= (aref next-pat 0) ?/) 'forward 'backward)
+ repeat-last (and (<= 2 (length next-pat))
+ (member (substring next-pat 0 2) '("//" "??")))
+ count (if (or (eq direction new-dir) (not repeat-last)) 1 2)
+ pattern-string (if repeat-last
+ (concat orig-pat (substring next-pat 1))
+ (substring next-pat 1))
+ direction new-dir))))))))
+
+(defun evil-ex-search-update-pattern (_beg _end _range)
+ "Update the current search pattern."
+ (save-match-data
+ (let ((pattern-string (minibuffer-contents)))
+ (with-current-buffer evil-ex-current-buffer
+ (with-selected-window (minibuffer-selected-window)
+ (goto-char (1+ evil-ex-search-start-point))
+ (condition-case err
+ (let* ((result (evil-ex-search-full-pattern pattern-string
+ (or evil-ex-search-count 1)
+ evil-ex-search-direction))
+ (success (pop result))
+ (pattern (pop result))
+ (offset (pop result)))
+ (cond
+ ((eq success 'wrap)
+ (evil-ex-search-update pattern offset
+ (match-beginning 0) (match-end 0)
+ "Wrapped"))
+ ((eq success 'empty-pattern)
+ (evil-ex-search-update nil nil nil nil nil))
+ (success
+ (evil-ex-search-update pattern offset
+ (match-beginning 0) (match-end 0)
+ nil))
+ (t
+ (evil-ex-search-update nil nil
+ nil nil
+ "search failed"))))
+ (invalid-regexp
+ (evil-ex-search-update nil nil nil nil (cadr err)))
+ (error
+ (evil-ex-search-update nil nil nil nil (format "%s" err)))))))))
+(put 'evil-ex-search-update-pattern 'permanent-local-hook t)
+
+(defun evil-ex-search-exit ()
+ "Exit interactive search, keeping lazy highlighting active."
+ (interactive)
+ (evil-ex-search-stop-session)
+ (exit-minibuffer))
+
+(defun evil-ex-search-abort ()
+ "Abort interactive search, disabling lazy highlighting."
+ (interactive)
+ (evil-ex-search-stop-session)
+ (evil-ex-delete-hl 'evil-ex-search)
+ (abort-recursive-edit))
+
+(defun evil-ex-search-goto-offset (offset)
+ "Move point according to search OFFSET and set `evil-this-type' accordingly.
+This function assumes that the current match data represents the
+current search result."
+ (unless (zerop (length offset))
+ (let ((beg (match-beginning 0))
+ (end (match-end 0)))
+ (save-match-data
+ (unless
+ (string-match
+ "^\\([esb]\\)?\\(\\([-+]\\)?\\([0-9]*\\)\\)$"
+ offset)
+ (user-error "Invalid search offset: %s" offset))
+ (let ((count (if (= (match-beginning 4) (match-end 4))
+ (cond
+ ((not (match-beginning 3)) 0)
+ ((= (aref offset (match-beginning 3)) ?+) +1)
+ (t -1))
+ (string-to-number (match-string 2 offset)))))
+ (cond
+ ((not (match-beginning 1))
+ (setq evil-this-type 'line)
+ (forward-line count))
+ ((= (aref offset (match-beginning 1)) ?e)
+ (goto-char (+ end count -1))
+ (setq evil-this-type 'inclusive))
+ ((memq (aref offset (match-beginning 1)) '(?s ?b))
+ (goto-char (+ beg count))
+ (setq evil-this-type 'inclusive))))))))
+
+(defun evil-ex-search-setup ()
+ "Hook to initialize the minibuffer for ex search."
+ (add-hook 'pre-command-hook #'evil-ex-remove-default))
+
+(defun evil-ex-start-search (direction count)
+ "Start a new search in a certain DIRECTION."
+ ;; store buffer and window where the search started
+ (let ((evil-ex-current-buffer (current-buffer)))
+ (setq evil-ex-search-count count
+ evil-ex-search-direction direction
+ evil-ex-search-start-point (point)
+ evil-ex-last-was-search t)
+ (progn
+ ;; ensure minibuffer is initialized accordingly
+ (add-hook 'minibuffer-setup-hook #'evil-ex-search-start-session)
+ ;; read the search string
+ (let* ((minibuffer-local-map evil-ex-search-keymap)
+ (search-string
+ (condition-case err
+ (minibuffer-with-setup-hook
+ #'evil-ex-search-setup
+ (read-string (if (eq evil-ex-search-direction 'forward)
+ "/" "?")
+ (and evil-ex-search-history
+ (propertize
+ (car evil-ex-search-history)
+ 'face 'shadow))
+ 'evil-ex-search-history))
+ (quit
+ (evil-ex-search-stop-session)
+ (evil-ex-delete-hl 'evil-ex-search)
+ (goto-char evil-ex-search-start-point)
+ (signal (car err) (cdr err))))))
+ ;; pattern entered successful
+ (goto-char (if (eq evil-ex-search-direction 'forward)
+ (1+ evil-ex-search-start-point)
+ (1- evil-ex-search-start-point)))
+ (let* ((result
+ (evil-ex-search-full-pattern search-string
+ evil-ex-search-count
+ evil-ex-search-direction))
+ (success (pop result))
+ (pattern (pop result))
+ (offset (pop result)))
+ (setq evil-ex-search-pattern pattern
+ evil-ex-search-offset offset)
+ (cond
+ ((memq success '(t wrap))
+ (goto-char (match-beginning 0))
+ (setq evil-ex-search-match-beg (match-beginning 0)
+ evil-ex-search-match-end (match-end 0))
+ (evil-ex-search-goto-offset offset)
+ (evil-push-search-history search-string (eq direction 'forward))
+ (when (and (not evil-ex-search-incremental) evil-ex-search-highlight-all)
+ (evil-ex-search-activate-highlight pattern))
+ (when (and evil-ex-search-incremental (not evil-ex-search-persistent-highlight))
+ (evil-ex-delete-hl 'evil-ex-search)))
+ (t
+ (goto-char evil-ex-search-start-point)
+ (evil-ex-delete-hl 'evil-ex-search)
+ (signal 'search-failed (list search-string)))))))))
+
+(defun evil-ex-start-word-search (unbounded direction count &optional symbol)
+ "Search for the symbol under point.
+The search matches the COUNT-th occurrence of the word. If the
+UNBOUNDED argument is nil, the search matches only at symbol
+boundaries, otherwise it matches anywhere. The DIRECTION
+argument should be either `forward' or `backward', determining
+the search direction. If SYMBOL is non-nil then the functions
+searches for the symbol at point, otherwise for the word at
+point."
+ (let ((string (evil-find-thing (eq direction 'forward)
+ (if symbol 'symbol 'word))))
+ (if (null string)
+ (user-error "No word under point")
+ (let ((regex (if unbounded
+ (regexp-quote string)
+ (format (if symbol "\\_<%s\\_>" "\\<%s\\>")
+ (regexp-quote string)))))
+ (setq evil-ex-search-count count
+ evil-ex-search-direction direction
+ evil-ex-search-pattern
+ (let (evil-ex-search-vim-style-regexp)
+ (evil-ex-make-search-pattern regex))
+ evil-ex-search-offset nil
+ evil-ex-last-was-search t)
+ ;; update search history unless this pattern equals the
+ ;; previous pattern
+ (unless (equal (car-safe evil-ex-search-history) regex)
+ (push regex evil-ex-search-history))
+ (evil-push-search-history regex (eq direction 'forward)))
+ (evil-ex-delete-hl 'evil-ex-search)
+ (when (fboundp 'evil-ex-search-next)
+ (evil-ex-search-next count)))))
+
+;; substitute
+(evil-ex-define-argument-type substitution
+ "A substitution pattern argument /pattern/replacement/flags.
+This handler highlights the pattern of the current substitution."
+ :runner
+ (lambda (flag &optional arg)
+ (with-selected-window (minibuffer-selected-window)
+ (with-current-buffer evil-ex-current-buffer
+ (cond
+ ((eq flag 'start)
+ (evil-ex-make-hl
+ 'evil-ex-substitute
+ :face 'evil-ex-substitute-matches
+ :update-hook #'evil-ex-pattern-update-ex-info
+ :match-hook (and evil-ex-substitute-interactive-replace
+ #'evil-ex-pattern-update-replacement))
+ (setq flag 'update))
+
+ ((eq flag 'stop)
+ (evil-ex-delete-hl 'evil-ex-substitute))))
+
+ (when (and (eq flag 'update)
+ evil-ex-substitute-highlight-all
+ (not (zerop (length arg))))
+ (condition-case lossage
+ (let* ((result (evil-ex-get-substitute-info arg t))
+ (pattern (pop result))
+ (replacement (pop result))
+ (range (or (evil-copy-range evil-ex-range)
+ (evil-range (line-beginning-position)
+ (line-end-position)
+ 'line
+ :expanded t))))
+ (setq evil-ex-substitute-current-replacement replacement)
+ (evil-expand-range range)
+ (evil-ex-hl-set-region 'evil-ex-substitute
+ (evil-range-beginning range)
+ (evil-range-end range))
+ (evil-ex-hl-change 'evil-ex-substitute pattern))
+ (end-of-file
+ (evil-ex-pattern-update-ex-info nil
+ "incomplete replacement"))
+ (user-error
+ (evil-ex-pattern-update-ex-info nil
+ (format "%s" lossage))))))))
+
+(defun evil-ex-pattern-update-ex-info (_hl result)
+ "Update the Ex info string."
+ (when (stringp result)
+ (evil-ex-echo "%s" result)))
+
+(defun evil-ex-pattern-update-replacement (_hl overlay)
+ "Update the replacement display."
+ (when (fboundp 'match-substitute-replacement)
+ (let ((fixedcase (not case-replace))
+ repl)
+ (setq repl (if evil-ex-substitute-current-replacement
+ (evil-match-substitute-replacement
+ evil-ex-substitute-current-replacement
+ fixedcase)
+ ""))
+ (put-text-property 0 (length repl)
+ 'face 'evil-ex-substitute-replacement
+ repl)
+ (overlay-put overlay 'after-string repl))))
+
+(defun evil-ex-parse-global (string)
+ "Parse STRING as a global argument."
+ (let* ((pattern (nth 0 (evil-delimited-arguments string 2)))
+ (command (and pattern
+ (>= (- (length string) (length pattern)) 2)
+ (substring string (+ (length pattern) 2)))))
+ ;; use last pattern if none given
+ (when (zerop (length pattern))
+ (setq pattern
+ (cond
+ ((and (eq evil-search-module 'evil-search) evil-ex-search-pattern)
+ (evil-ex-pattern-regex evil-ex-search-pattern))
+ ((and (eq evil-search-module 'isearch) (not (zerop (length isearch-string))))
+ isearch-string)
+ (t (user-error "No previous pattern")))))
+ (list pattern command)))
+
+(defun evil-ex-get-substitute-info (string &optional implicit-r)
+ "Returns the substitution info of command line STRING.
+This function returns a three-element list \(PATTERN REPLACEMENT
+FLAGS) consisting of the substitution parts of STRING. PATTERN is
+a ex-pattern (see `evil-ex-make-pattern') and REPLACEMENT in a
+compiled replacement expression (see `evil-compile-replacement').
+The information returned is the actual substitution information
+w.r.t. to special situations like empty patterns or repetition of
+previous substitution commands. If IMPLICIT-R is non-nil, then
+the flag 'r' is assumed, i.e. in the case of an empty pattern the
+last search pattern is used. This will be used when called from
+a :substitute command with arguments."
+ (let (pattern replacement flags)
+ (cond
+ ((or (null string) (string-match "^[a-zA-Z]" string))
+ ;; starts with letter so there is no pattern because the
+ ;; separator must not be a letter repeat last substitute
+ (setq replacement evil-ex-substitute-replacement)
+ ;; flags are everything that is not a white space
+ (when (and string (string-match "[^[:space:]]+" string))
+ (setq flags (match-string 0 string))))
+ (t
+ (let ((args (evil-delimited-arguments string 3)))
+ (setq pattern (pop args)
+ replacement (pop args)
+ flags (pop args))
+ ;; if replacment equals "~" use previous replacement
+ (if (equal replacement "~")
+ (setq replacement evil-ex-substitute-replacement)
+ (setq replacement (evil-compile-replacement replacement)))
+ ;; append implicit "r" flag if required
+ (when (and implicit-r (not (memq ?r (append flags nil))))
+ (setq flags (concat flags "r"))))))
+ ;; if flags equals "&" add previous flags
+ (if (and (not (zerop (length flags)))
+ (= (aref flags 0) ?&))
+ (setq flags (append (substring flags 1)
+ evil-ex-substitute-flags))
+ (setq flags (append flags nil)))
+ ;; if no pattern, use previous pattern, either search or
+ ;; substitute pattern depending on `evil-ex-last-was-search' and
+ ;; the r flag
+ (when (zerop (length pattern))
+ (setq pattern
+ (if (eq evil-search-module 'evil-search)
+ (if (and evil-ex-last-was-search (memq ?r flags))
+ (and evil-ex-search-pattern
+ (evil-ex-pattern-regex evil-ex-search-pattern))
+ (and evil-ex-substitute-pattern
+ (evil-ex-pattern-regex evil-ex-substitute-pattern)))
+ (if (eq case-fold-search t)
+ isearch-string
+ (concat isearch-string "\\C")))
+ flags (remq ?r flags)))
+ ;; generate pattern
+ (when pattern
+ (setq pattern (evil-ex-make-substitute-pattern pattern flags)))
+ (list pattern replacement flags)))
+
+(defun evil-ex-nohighlight ()
+ "Disable the active search highlightings."
+ (interactive)
+ (evil-ex-delete-hl 'evil-ex-substitute)
+ (evil-ex-delete-hl 'evil-ex-search))
+
+(provide 'evil-search)
+
+;;; evil-search.el ends here
diff --git a/elpa/evil-20220503.1314/evil-search.elc b/elpa/evil-20220503.1314/evil-search.elc
new file mode 100644
index 0000000..1acb664
--- /dev/null
+++ b/elpa/evil-20220503.1314/evil-search.elc
Binary files differ
diff --git a/elpa/evil-20220503.1314/evil-states.el b/elpa/evil-20220503.1314/evil-states.el
new file mode 100644
index 0000000..a2e0e6e
--- /dev/null
+++ b/elpa/evil-20220503.1314/evil-states.el
@@ -0,0 +1,937 @@
+;;; evil-states.el --- States -*- lexical-binding: t -*-
+
+;; Author: Vegard Øye <vegard_oye at hotmail.com>
+;; Maintainer: Vegard Øye <vegard_oye at hotmail.com>
+
+;; Version: 1.15.0
+
+;;
+;; This file is NOT part of GNU Emacs.
+
+;;; License:
+
+;; This file is part of Evil.
+;;
+;; Evil 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.
+;;
+;; Evil 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 Evil. If not, see <http://www.gnu.org/licenses/>.
+
+(require 'evil-core)
+
+;;; Code:
+
+;;; Normal state
+
+(evil-define-state normal
+ "Normal state.
+AKA \"Command\" state."
+ :tag " <N> "
+ :enable (motion)
+ :exit-hook (evil-repeat-start-hook)
+ (cond
+ ((evil-normal-state-p)
+ (overwrite-mode -1)
+ (add-hook 'post-command-hook #'evil-normal-post-command nil t))
+ (t
+ (remove-hook 'post-command-hook #'evil-normal-post-command t))))
+
+(defun evil-normal-post-command (&optional command)
+ "Reset command loop variables in Normal state.
+Also prevent point from reaching the end of the line.
+If the region is activated, enter Visual state."
+ (unless (or (evil-initializing-p)
+ (null this-command))
+ (setq command (or command this-command))
+ (when (evil-normal-state-p)
+ (setq evil-this-type nil
+ evil-this-operator nil
+ evil-this-motion nil
+ evil-this-motion-count nil
+ evil-inhibit-operator nil
+ evil-inhibit-operator-value nil)
+ (unless (memq command '(evil-use-register
+ digit-argument
+ negative-argument
+ universal-argument
+ universal-argument-minus
+ universal-argument-more
+ universal-argument-other-key))
+ (setq evil-this-register nil))
+ (evil-adjust-cursor))))
+(put 'evil-normal-post-command 'permanent-local-hook t)
+
+;;; Insert state
+
+(defun evil-maybe-remove-spaces (&optional do-remove)
+ "Remove space from newly opened empty line.
+This function removes (indentation) spaces that have been
+inserted by opening a new empty line. The behavior depends on the
+variable `evil-maybe-remove-spaces'. If this variable is nil the
+function does nothing. Otherwise the behavior depends on
+DO-REMOVE. If DO-REMOVE is non-nil the spaces are
+removed. Otherwise `evil-maybe-remove-spaces' is set to nil
+unless the last command opened yet another new line.
+
+This function should be added as a post-command-hook to track
+commands opening a new line."
+ (cond
+ ((not evil-maybe-remove-spaces)
+ (remove-hook 'post-command-hook #'evil-maybe-remove-spaces))
+ (do-remove
+ (when (save-excursion
+ (beginning-of-line)
+ (looking-at "^\\s-*$"))
+ (delete-region (line-beginning-position)
+ (line-end-position)))
+ (setq evil-maybe-remove-spaces nil)
+ (remove-hook 'post-command-hook #'evil-maybe-remove-spaces))
+ ((not (memq this-command
+ '(evil-open-above
+ evil-open-below
+ evil-append
+ evil-append-line
+ evil-change-whole-line
+ newline
+ newline-and-indent
+ indent-and-newline)))
+ (setq evil-maybe-remove-spaces nil)
+ (remove-hook 'post-command-hook #'evil-maybe-remove-spaces))))
+
+(evil-define-state insert
+ "Insert state."
+ :tag " <I> "
+ :cursor (bar . 2)
+ :message "-- INSERT --"
+ :entry-hook (evil-start-track-last-insertion)
+ :exit-hook (evil-cleanup-insert-state evil-stop-track-last-insertion)
+ :input-method t
+ (cond
+ ((evil-insert-state-p)
+ (add-hook 'post-command-hook #'evil-maybe-remove-spaces)
+ (add-hook 'pre-command-hook #'evil-insert-repeat-hook)
+ (setq evil-maybe-remove-spaces t)
+ (unless (eq evil-want-fine-undo t)
+ (evil-start-undo-step)))
+ (t
+ (remove-hook 'post-command-hook #'evil-maybe-remove-spaces)
+ (remove-hook 'pre-command-hook #'evil-insert-repeat-hook)
+ (evil-maybe-remove-spaces t)
+ (setq evil-insert-repeat-info evil-repeat-info)
+ (evil-set-marker ?^ nil t)
+ (unless (eq evil-want-fine-undo t)
+ (evil-end-undo-step))
+ (when (or (evil-normal-state-p evil-next-state)
+ (evil-motion-state-p evil-next-state))
+ (evil-move-cursor-back
+ (and (eolp) (not evil-move-beyond-eol)))))))
+
+(defun evil-insert-repeat-hook ()
+ "Record insertion keys in `evil-insert-repeat-info'."
+ (setq evil-insert-repeat-info (last evil-repeat-info))
+ (remove-hook 'pre-command-hook #'evil-insert-repeat-hook))
+(put 'evil-insert-repeat-hook 'permanent-local-hook t)
+
+(defun evil-cleanup-insert-state ()
+ "Called when Insert state is about to be exited.
+Handles the repeat-count of the insertion command."
+ (when evil-insert-count
+ (dotimes (_ (1- evil-insert-count))
+ (when evil-insert-lines
+ (evil-insert-newline-below)
+ (when evil-auto-indent
+ (indent-according-to-mode)))
+ (when (fboundp 'evil-execute-repeat-info)
+ (evil-execute-repeat-info
+ (cdr evil-insert-repeat-info)))))
+ (when evil-insert-vcount
+ (let ((buffer-invisibility-spec buffer-invisibility-spec))
+ ;; make all lines hidden by hideshow temporarily visible
+ (when (listp buffer-invisibility-spec)
+ (setq buffer-invisibility-spec
+ (evil-filter-list
+ #'(lambda (x)
+ (or (eq x 'hs)
+ (eq (car-safe x) 'hs)))
+ buffer-invisibility-spec)))
+ (let ((line (nth 0 evil-insert-vcount))
+ (col (nth 1 evil-insert-vcount))
+ (vcount (nth 2 evil-insert-vcount)))
+ (save-excursion
+ (dotimes (v (1- vcount))
+ (goto-char (point-min))
+ (forward-line (+ line v))
+ (when (or (not evil-insert-skip-empty-lines)
+ (not (integerp col))
+ (save-excursion
+ (evil-move-end-of-line)
+ (>= (current-column) col)))
+ (if (integerp col)
+ (move-to-column col t)
+ (funcall col))
+ (dotimes (_ (or evil-insert-count 1))
+ (when (fboundp 'evil-execute-repeat-info)
+ (evil-execute-repeat-info
+ (cdr evil-insert-repeat-info)))))))))))
+
+;;; Visual state
+
+;; Visual selections are implemented in terms of types, and are
+;; compatible with the Emacs region. This is achieved by "translating"
+;; the region to the selected text right before a command is executed.
+;; If the command is a motion, the translation is postponed until a
+;; non-motion command is invoked (distinguished by the :keep-visual
+;; command property).
+;;
+;; Visual state activates the region, enabling Transient Mark mode if
+;; not already enabled. This is only temporay: if Transient Mark mode
+;; was disabled before entering Visual state, it is disabled when
+;; exiting Visual state. This allows Visual state to harness the
+;; "transient" behavior of many commands without overriding the user's
+;; preferences in other states.
+
+(defmacro evil-define-visual-selection (selection doc &rest body)
+ "Define a Visual selection SELECTION.
+Creates a command evil-visual-SELECTION for enabling the selection.
+DOC is the function's documentation string. The following keywords
+may be specified in BODY:
+
+:message STRING Status message when enabling the selection.
+:type TYPE Type to use (defaults to SELECTION).
+
+Following the keywords is optional code which is executed each time
+the selection is enabled.
+
+\(fn SELECTION DOC [[KEY VAL]...] BODY...)"
+ (declare (indent defun)
+ (doc-string 2)
+ (debug (&define name stringp
+ [&rest keywordp sexp]
+ def-body)))
+ (let* ((name (intern (format "evil-visual-%s" selection)))
+ (message (intern (format "%s-message" name)))
+ (tagvar (intern (format "%s-tag" name)))
+ (type selection)
+ (tag " <V> ")
+ arg key string)
+ ;; collect keywords
+ (while (keywordp (car-safe body))
+ (setq key (pop body)
+ arg (pop body))
+ (cond
+ ((eq key :message)
+ (setq string arg))
+ ((eq key :type)
+ (setq type arg))
+ ((eq key :tag)
+ (setq tag arg))))
+ ;; macro expansion
+ `(progn
+ (add-to-list 'evil-visual-alist (cons ',selection ',name))
+ (defvar ,name ',type ,(format "*%s" doc))
+ (defvar ,message ,string ,doc)
+ (defvar ,tagvar ,tag ,doc)
+ (evil-define-command ,name (&optional mark point type message)
+ ,@(when doc `(,doc))
+ :keep-visual t
+ :repeat nil
+ (interactive
+ (list nil nil
+ (if (and (evil-visual-state-p)
+ (eq evil-visual-selection ',selection))
+ 'exit ,name) t))
+ (if (eq type 'exit)
+ (evil-exit-visual-state)
+ (setq type (or type ,name)
+ evil-visual-selection ',selection)
+ (evil-visual-make-region mark point type message)
+ ,@body))
+ ',selection)))
+
+(evil-define-visual-selection char
+ "Characterwise selection."
+ :type inclusive
+ :message "-- VISUAL --"
+ :tag " <V> ")
+
+(evil-define-visual-selection line
+ "Linewise selection."
+ :message "-- VISUAL LINE --"
+ :tag " <Vl> ")
+
+(evil-define-visual-selection screen-line
+ "Linewise selection in `visual-line-mode'."
+ :message "-- SCREEN LINE --"
+ :tag " <Vs> ")
+
+(evil-define-visual-selection block
+ "Blockwise selection."
+ :message "-- VISUAL BLOCK --"
+ :tag " <Vb> "
+ (evil-transient-mark -1)
+ ;; refresh the :corner property
+ (setq evil-visual-properties
+ (plist-put evil-visual-properties :corner
+ (evil-visual-block-corner 'upper-left))))
+
+(evil-define-state visual
+ "Visual state."
+ :tag 'evil-visual-tag
+ :enable (motion normal)
+ :message 'evil-visual-message
+ (cond
+ ((evil-visual-state-p)
+ (evil-save-transient-mark-mode)
+ (setq select-active-regions nil)
+ (cond
+ ((region-active-p)
+ (if (< (evil-visual-direction) 0)
+ (evil-visual-select (region-beginning) (region-end)
+ evil-visual-char
+ (evil-visual-direction))
+ (evil-visual-make-selection (mark t) (point)
+ evil-visual-char))
+ (evil-visual-highlight))
+ (t
+ (evil-visual-make-region (point) (point) evil-visual-char)))
+ (add-hook 'pre-command-hook #'evil-visual-pre-command nil t)
+ (add-hook 'post-command-hook #'evil-visual-post-command nil t)
+ (add-hook 'deactivate-mark-hook #'evil-visual-deactivate-hook nil t))
+ (t
+ ;; Postpone deactivation of region if next state is Insert.
+ ;; This gives certain insertion commands (auto-pairing characters,
+ ;; for example) an opportunity to access the region.
+ (if (and (eq evil-next-state 'insert)
+ (eq evil-visual-selection 'char))
+ (add-hook 'evil-normal-state-entry-hook
+ #'evil-visual-deactivate-hook nil t)
+ (evil-visual-deactivate-hook))
+ (setq evil-visual-region-expanded nil)
+ (remove-hook 'pre-command-hook #'evil-visual-pre-command t)
+ (remove-hook 'post-command-hook #'evil-visual-post-command t)
+ (remove-hook 'deactivate-mark-hook #'evil-visual-deactivate-hook t)
+ (evil-visual-highlight -1))))
+
+(defun evil-visual-pre-command (&optional command)
+ "Run before each COMMAND in Visual state.
+Expand the region to the selection unless COMMAND is a motion."
+ (when (evil-visual-state-p)
+ (setq command (or command this-command))
+ (when evil-visual-x-select-timer
+ (cancel-timer evil-visual-x-select-timer))
+ (unless (evil-get-command-property command :keep-visual)
+ (evil-visual-update-x-selection)
+ (evil-visual-expand-region
+ ;; exclude final newline from linewise selection
+ ;; unless the command has real need of it
+ (and (eq (evil-visual-type) 'line)
+ (evil-get-command-property command :exclude-newline))))))
+
+(put 'evil-visual-pre-command 'permanent-local-hook t)
+
+(defun evil-visual-post-command (&optional command)
+ "Run after each COMMAND in Visual state.
+If COMMAND is a motion, refresh the selection;
+otherwise exit Visual state."
+ (when (evil-visual-state-p)
+ (setq command (or command this-command))
+ (if (or quit-flag
+ (eq command #'keyboard-quit)
+ ;; Is `mark-active' nil for an unexpanded region?
+ deactivate-mark
+ (and (not evil-visual-region-expanded)
+ (not (region-active-p))
+ (not (eq evil-visual-selection 'block))))
+ (progn
+ (evil-exit-visual-state)
+ (evil-adjust-cursor))
+ (if evil-visual-region-expanded
+ (evil-visual-contract-region)
+ (evil-visual-refresh))
+ (setq evil-visual-x-select-timer
+ (run-with-idle-timer evil-visual-x-select-timeout nil
+ #'evil-visual-update-x-selection
+ (current-buffer)))
+ (evil-visual-highlight))))
+(put 'evil-visual-post-command 'permanent-local-hook t)
+
+(defun evil-visual-update-x-selection (&optional buffer)
+ "Update the X selection with the current visual region of BUFFER."
+ (let ((buf (or buffer (current-buffer))))
+ (when (and evil-visual-update-x-selection-p
+ (buffer-live-p buf)
+ (evil-visual-state-p)
+ (display-selections-p)
+ (not (eq evil-visual-selection 'block)))
+ (with-current-buffer buf
+ (evil-set-selection 'PRIMARY (buffer-substring-no-properties
+ evil-visual-beginning
+ evil-visual-end))))))
+
+(defun evil-visual-activate-hook (&optional _command)
+ "Enable Visual state if the region is activated."
+ (unless (evil-visual-state-p)
+ (evil-delay nil
+ ;; the activation may only be momentary, so re-check
+ ;; in `post-command-hook' before entering Visual state
+ '(unless (or (evil-visual-state-p)
+ (evil-insert-state-p)
+ (evil-emacs-state-p))
+ (when (and (region-active-p)
+ (not deactivate-mark))
+ (evil-visual-state)))
+ 'post-command-hook nil t
+ "evil-activate-visual-state")))
+(put 'evil-visual-activate-hook 'permanent-local-hook t)
+
+(defun evil-visual-deactivate-hook (&optional command)
+ "Deactivate the region and restore Transient Mark mode."
+ (setq command (or command this-command))
+ (remove-hook 'deactivate-mark-hook
+ #'evil-visual-deactivate-hook t)
+ (remove-hook 'evil-normal-state-entry-hook
+ #'evil-visual-deactivate-hook t)
+ (cond
+ ((and (evil-visual-state-p) command
+ (not (evil-get-command-property command :keep-visual)))
+ (setq evil-visual-region-expanded nil)
+ (evil-exit-visual-state))
+ ((not (evil-visual-state-p))
+ (evil-active-region -1)
+ (evil-restore-transient-mark-mode))))
+(put 'evil-visual-deactivate-hook 'permanent-local-hook t)
+
+(evil-define-command evil-exit-visual-state (&optional later buffer)
+ "Exit from Visual state to the previous state.
+If LATER is non-nil, exit after the current command."
+ :keep-visual t
+ :repeat abort
+ (with-current-buffer (or buffer (current-buffer))
+ (when (evil-visual-state-p)
+ (if later
+ (setq deactivate-mark t)
+ (when evil-visual-region-expanded
+ (evil-visual-contract-region))
+ (evil-change-to-previous-state)))))
+
+(defun evil-visual-tag (&optional selection)
+ "Return a mode-line tag for SELECTION.
+SELECTION is a kind of selection as defined by
+`evil-define-visual-selection', such as `char', `line'
+or `block'."
+ (setq selection (or selection evil-visual-selection))
+ (when selection
+ (symbol-value (intern (format "evil-visual-%s-tag" selection)))))
+
+(defun evil-visual-message (&optional selection)
+ "Create an echo area message for SELECTION.
+SELECTION is a kind of selection as defined by
+`evil-define-visual-selection', such as `char', `line'
+or `block'."
+ (let (message)
+ (setq selection (or selection evil-visual-selection))
+ (when selection
+ (setq message
+ (symbol-value (intern (format "evil-visual-%s-message"
+ selection))))
+ (cond
+ ((functionp message)
+ (funcall message))
+ ((stringp message)
+ (evil-echo "%s" message))))))
+
+(defun evil-visual-select (beg end &optional type dir message)
+ "Create a Visual selection of type TYPE from BEG to END.
+Point and mark are positioned so that the resulting selection
+has the specified boundaries. If DIR is negative, point precedes mark,
+otherwise it succedes it. To specify point and mark directly,
+use `evil-visual-make-selection'."
+ (let* ((range (evil-contract beg end type))
+ (mark (evil-range-beginning range))
+ (point (evil-range-end range))
+ (dir (or dir 1)))
+ (when (< dir 0)
+ (evil-swap mark point))
+ (evil-visual-make-selection mark point type message)))
+
+(defun evil-visual-make-selection (mark point &optional type message)
+ "Create a Visual selection with point at POINT and mark at MARK.
+The boundaries of the selection are inferred from these
+and the current TYPE. To specify the boundaries and infer
+mark and point, use `evil-visual-select' instead."
+ (let* ((selection (evil-visual-selection-for-type type))
+ (func (evil-visual-selection-function selection))
+ (prev (and (evil-visual-state-p) evil-visual-selection))
+ (mark (evil-normalize-position mark))
+ (point (evil-normalize-position point))
+ (state evil-state))
+ (unless (evil-visual-state-p)
+ (evil-visual-state))
+ (setq evil-visual-selection selection)
+ (funcall func mark point type
+ ;; signal a message when changing the selection
+ (when (or (not (evil-visual-state-p state))
+ (not (eq selection prev)))
+ message))))
+
+(defun evil-visual-make-region (mark point &optional type message)
+ "Create an active region from MARK to POINT.
+If TYPE is given, also set the Visual type.
+If MESSAGE is given, display it in the echo area."
+ (interactive)
+ (let* ((point (evil-normalize-position
+ (or point (point))))
+ (mark (evil-normalize-position
+ (or mark
+ (when (or (evil-visual-state-p)
+ (region-active-p))
+ (mark t))
+ point))))
+ (unless (evil-visual-state-p)
+ (evil-visual-state))
+ (evil-active-region 1)
+ (setq evil-visual-region-expanded nil)
+ (evil-visual-refresh mark point type)
+ (cond
+ ((null evil-echo-state))
+ ((stringp message)
+ (evil-echo "%s" message))
+ (message
+ (cond
+ ((stringp evil-visual-state-message)
+ (evil-echo "%s" evil-visual-state-message))
+ ((functionp evil-visual-state-message)
+ (funcall evil-visual-state-message)))))))
+
+(defun evil-visual-expand-region (&optional exclude-newline)
+ "Expand the region to the Visual selection.
+If EXCLUDE-NEWLINE is non-nil and the selection ends with a newline,
+exclude that newline from the region."
+ (when (and (evil-visual-state-p)
+ (not evil-visual-region-expanded))
+ (let ((mark evil-visual-beginning)
+ (point evil-visual-end))
+ (when (< evil-visual-direction 0)
+ (evil-swap mark point))
+ (setq evil-visual-region-expanded t)
+ (evil-visual-refresh mark point)
+ (when (and exclude-newline
+ (save-excursion
+ (goto-char evil-visual-end)
+ (and (bolp) (not (bobp)))))
+ (if (< evil-visual-direction 0)
+ (evil-move-mark (max point (1- (mark))))
+ (goto-char (max mark (1- (point)))))))))
+
+(defun evil-visual-contract-region ()
+ "The inverse of `evil-visual-expand-region'.
+Create a Visual selection that expands to the current region."
+ (evil-visual-refresh)
+ (setq evil-visual-region-expanded nil)
+ (evil-visual-refresh evil-visual-mark evil-visual-point))
+
+(defun evil-visual-refresh (&optional mark point type &rest properties)
+ "Refresh point, mark and Visual variables.
+Refreshes `evil-visual-beginning', `evil-visual-end',
+`evil-visual-mark', `evil-visual-point', `evil-visual-selection',
+`evil-visual-direction', `evil-visual-properties' and `evil-this-type'."
+ (let* ((point (or point (point)))
+ (mark (or mark (mark t) point))
+ (dir (evil-visual-direction))
+ (type (or type (evil-visual-type evil-visual-selection)
+ (evil-visual-type)))
+ range)
+ (evil-move-mark mark)
+ (goto-char point)
+ (setq evil-visual-beginning
+ (or evil-visual-beginning
+ (let ((marker (make-marker)))
+ (move-marker marker (min point mark))))
+ evil-visual-end
+ (or evil-visual-end
+ (let ((marker (make-marker)))
+ (set-marker-insertion-type marker t)
+ (move-marker marker (max point mark))))
+ evil-visual-mark
+ (or evil-visual-mark
+ (let ((marker (make-marker)))
+ (move-marker marker mark)))
+ evil-visual-point
+ (or evil-visual-point
+ (let ((marker (make-marker)))
+ (move-marker marker point))))
+ (setq evil-visual-properties
+ (evil-concat-plists evil-visual-properties properties))
+ (cond
+ (evil-visual-region-expanded
+ (setq type (or (evil-visual-type) type))
+ (move-marker evil-visual-beginning (min point mark))
+ (move-marker evil-visual-end (max point mark))
+ ;; if the type is one-to-one, we can safely refresh
+ ;; the unexpanded positions as well
+ (when (evil-type-property type :one-to-one)
+ (setq range (apply #'evil-contract point mark type
+ evil-visual-properties)
+ mark (evil-range-beginning range)
+ point (evil-range-end range))
+ (when (< dir 0)
+ (evil-swap mark point))
+ (move-marker evil-visual-mark mark)
+ (move-marker evil-visual-point point)))
+ (t
+ (setq range (apply #'evil-expand point mark type
+ evil-visual-properties)
+ type (evil-type range type))
+ (move-marker evil-visual-beginning (evil-range-beginning range))
+ (move-marker evil-visual-end (evil-range-end range))
+ (move-marker evil-visual-mark mark)
+ (move-marker evil-visual-point point)))
+ (setq evil-visual-direction dir
+ evil-this-type type)))
+
+(defun evil-visual-highlight (&optional arg)
+ "Highlight Visual selection, depending on the Visual type.
+With negative ARG, disable highlighting."
+ (cond
+ ((and (numberp arg) (< arg 1))
+ (when evil-visual-overlay
+ (delete-overlay evil-visual-overlay)
+ (setq evil-visual-overlay nil))
+ (when evil-visual-block-overlays
+ (mapc #'delete-overlay evil-visual-block-overlays)
+ (setq evil-visual-block-overlays nil)))
+ ((eq evil-visual-selection 'block)
+ (when evil-visual-overlay
+ (evil-visual-highlight -1))
+ (evil-visual-highlight-block
+ evil-visual-beginning
+ evil-visual-end))
+ (t
+ (when evil-visual-block-overlays
+ (evil-visual-highlight -1))
+ (if evil-visual-overlay
+ (move-overlay evil-visual-overlay
+ evil-visual-beginning evil-visual-end)
+ (setq evil-visual-overlay
+ (make-overlay evil-visual-beginning evil-visual-end)))
+ (overlay-put evil-visual-overlay 'face 'region)
+ (overlay-put evil-visual-overlay 'priority 99))))
+
+(defun evil-visual-highlight-block (beg end &optional overlays)
+ "Highlight rectangular region from BEG to END.
+Do this by putting an overlay on each line within the rectangle.
+Each overlay extends across all the columns of the rectangle.
+Reuse overlays where possible to prevent flicker."
+ (let* ((point (point))
+ (overlays (or overlays 'evil-visual-block-overlays))
+ (old (symbol-value overlays))
+ (eol-col (and (memq this-command '(next-line previous-line))
+ (numberp temporary-goal-column)
+ (1+ (min (round temporary-goal-column)
+ (1- most-positive-fixnum)))))
+ beg-col end-col new nlines overlay window-beg window-end)
+ (save-excursion
+ ;; calculate the rectangular region represented by BEG and END,
+ ;; but put BEG in the upper-left corner and END in the
+ ;; lower-right if not already there
+ (setq beg-col (evil-column beg)
+ end-col (evil-column end))
+ (when (>= beg-col end-col)
+ (if (= beg-col end-col)
+ (setq end-col (1+ end-col))
+ (evil-sort beg-col end-col))
+ (setq beg (save-excursion
+ (goto-char beg)
+ (evil-move-to-column beg-col))
+ end (save-excursion
+ (goto-char end)
+ (evil-move-to-column end-col 1))))
+ ;; update end column with eol-col (extension to eol).
+ (when (and eol-col (> eol-col end-col))
+ (setq end-col eol-col))
+ ;; force a redisplay so we can do reliable window
+ ;; BEG/END calculations
+ (sit-for 0)
+ (setq window-beg (max (window-start) beg)
+ window-end (min (window-end) (1+ end))
+ nlines (count-lines window-beg
+ (min window-end (point-max))))
+ ;; iterate over those lines of the rectangle which are
+ ;; visible in the currently selected window
+ (goto-char window-beg)
+ (dotimes (_ nlines)
+ (let (before after row-beg row-end)
+ ;; beginning of row
+ (evil-move-to-column beg-col)
+ (when (< (current-column) beg-col)
+ ;; prepend overlay with virtual spaces if unable to
+ ;; move directly to the first column
+ (setq before
+ (propertize
+ (make-string
+ (- beg-col (current-column)) ?\s)
+ 'face
+ (or (get-text-property (1- (point)) 'face)
+ 'default))))
+ (setq row-beg (point))
+ ;; end of row
+ (evil-move-to-column end-col)
+ (when (and (not (eolp))
+ (< (current-column) end-col))
+ ;; append overlay with virtual spaces if unable to
+ ;; move directly to the last column
+ (setq after
+ (propertize
+ (make-string
+ (if (= (point) row-beg)
+ (- end-col beg-col)
+ (- end-col (current-column)))
+ ?\s) 'face 'region))
+ ;; place cursor on one of the virtual spaces
+ (if (= point row-beg)
+ (put-text-property
+ 0 (min (length after) 1)
+ 'cursor t after)
+ (put-text-property
+ (max 0 (1- (length after))) (length after)
+ 'cursor t after)))
+ (setq row-end (min (point) (line-end-position)))
+ ;; trim old leading overlays
+ (while (and old
+ (setq overlay (car old))
+ (< (overlay-start overlay) row-beg)
+ (/= (overlay-end overlay) row-end))
+ (delete-overlay overlay)
+ (setq old (cdr old)))
+ ;; reuse an overlay if possible, otherwise create one
+ (cond
+ ((and old (setq overlay (car old))
+ (or (= (overlay-start overlay) row-beg)
+ (= (overlay-end overlay) row-end)))
+ (move-overlay overlay row-beg row-end)
+ (overlay-put overlay 'before-string before)
+ (overlay-put overlay 'after-string after)
+ (setq new (cons overlay new)
+ old (cdr old)))
+ (t
+ (setq overlay (make-overlay row-beg row-end))
+ (overlay-put overlay 'before-string before)
+ (overlay-put overlay 'after-string after)
+ (setq new (cons overlay new)))))
+ (forward-line 1))
+ ;; display overlays
+ (dolist (overlay new)
+ (overlay-put overlay 'face 'region)
+ (overlay-put overlay 'priority 99))
+ ;; trim old overlays
+ (dolist (overlay old)
+ (delete-overlay overlay))
+ (set overlays (nreverse new)))))
+
+(defun evil-visual-range ()
+ "Return the Visual selection as a range.
+This is a list (BEG END TYPE PROPERTIES...), where BEG is the
+beginning of the selection, END is the end of the selection,
+TYPE is the selection's type, and PROPERTIES is a property list
+of miscellaneous selection attributes."
+ (apply #'evil-range
+ evil-visual-beginning evil-visual-end
+ (evil-visual-type)
+ :expanded t
+ evil-visual-properties))
+
+(defun evil-visual-direction ()
+ "Return direction of Visual selection.
+The direction is -1 if point precedes mark and 1 otherwise.
+See also the variable `evil-visual-direction', which holds
+the direction of the last selection."
+ (let* ((point (point))
+ (mark (or (mark t) point)))
+ (if (< point mark) -1 1)))
+
+(defun evil-visual-type (&optional selection)
+ "Return the type of the Visual selection.
+If SELECTION is specified, return the type of that instead."
+ (if (and (null selection) (evil-visual-state-p))
+ (or evil-this-type (evil-visual-type evil-visual-selection))
+ (setq selection (or selection evil-visual-selection))
+ (symbol-value (cdr-safe (assq selection evil-visual-alist)))))
+
+(defun evil-visual-goto-end ()
+ "Go to the last line of the Visual selection.
+This position may differ from `evil-visual-end' depending on
+the selection type, and is contained in the selection."
+ (let ((range (evil-contract-range (evil-visual-range))))
+ (goto-char (evil-range-end range))))
+
+(defun evil-visual-alist ()
+ "Return an association list from types to selection symbols."
+ (mapcar #'(lambda (e)
+ (cons (symbol-value (cdr-safe e)) (cdr-safe e)))
+ evil-visual-alist))
+
+(defun evil-visual-selection-function (selection)
+ "Return a selection function for TYPE.
+Default to `evil-visual-make-region'."
+ (or (cdr-safe (assq selection evil-visual-alist))
+ ;; generic selection function
+ 'evil-visual-make-region))
+
+(defun evil-visual-selection-for-type (type)
+ "Return a Visual selection for TYPE."
+ (catch 'done
+ (dolist (selection evil-visual-alist)
+ (when (eq (symbol-value (cdr selection)) type)
+ (throw 'done (car selection))))))
+
+(defun evil-visual-block-corner (&optional corner point mark)
+ "Block corner corresponding to POINT, with MARK in opposite corner.
+Depending on POINT and MARK, the return value is `upper-left',
+`upper-right', `lower-left' or `lower-right':
+
+ upper-left +---+ upper-right
+ | |
+ lower-left +---+ lower-right
+
+One-column or one-row blocks are ambiguous. In such cases,
+the horizontal or vertical component of CORNER is used.
+CORNER defaults to `upper-left'."
+ (let* ((point (or point (point)))
+ (mark (or mark (mark t)))
+ (corner (symbol-name
+ (or corner
+ (and (overlayp evil-visual-overlay)
+ (overlay-get evil-visual-overlay
+ :corner))
+ 'upper-left)))
+ (point-col (evil-column point))
+ (mark-col (evil-column mark))
+ horizontal vertical)
+ (cond
+ ((= point-col mark-col)
+ (setq horizontal
+ (or (and (string-match "left\\|right" corner)
+ (match-string 0 corner))
+ "left")))
+ ((< point-col mark-col)
+ (setq horizontal "left"))
+ ((> point-col mark-col)
+ (setq horizontal "right")))
+ (cond
+ ((= (line-number-at-pos point)
+ (line-number-at-pos mark))
+ (setq vertical
+ (or (and (string-match "upper\\|lower" corner)
+ (match-string 0 corner))
+ "upper")))
+ ((< point mark)
+ (setq vertical "upper"))
+ ((> point mark)
+ (setq vertical "lower")))
+ (intern (format "%s-%s" vertical horizontal))))
+
+;;; Operator-Pending state
+
+(evil-define-state operator
+ "Operator-Pending state."
+ :tag " <O> "
+ :cursor evil-half-cursor
+ :enable (evil-operator-shortcut-map operator motion normal))
+
+(evil-define-keymap evil-operator-shortcut-map
+ "Keymap for Operator-Pending shortcuts like \"dd\" and \"gqq\"."
+ :local t
+ (setq evil-operator-shortcut-map (make-sparse-keymap))
+ (evil-initialize-local-keymaps))
+
+;; the half-height "Operator-Pending cursor" cannot be specified
+;; as a static `cursor-type' value, since its height depends on
+;; the current font size
+(defun evil-half-cursor ()
+ "Change cursor to a half-height box.
+\(This is really just a thick horizontal bar.)"
+ (let ((height (/ (window-pixel-height) (* (window-height) 2))))
+ (setq cursor-type (cons 'hbar height))))
+
+;;; Replace state
+
+(evil-define-state replace
+ "Replace state."
+ :tag " <R> "
+ :cursor hbar
+ :message "-- REPLACE --"
+ :input-method t
+ (cond
+ ((evil-replace-state-p)
+ (overwrite-mode 1)
+ (add-hook 'pre-command-hook #'evil-replace-pre-command nil t)
+ (unless (eq evil-want-fine-undo t)
+ (evil-start-undo-step)))
+ (t
+ (overwrite-mode -1)
+ (remove-hook 'pre-command-hook #'evil-replace-pre-command t)
+ (unless (eq evil-want-fine-undo t)
+ (evil-end-undo-step))
+ (evil-move-cursor-back)))
+ (setq evil-replace-alist nil))
+
+(defun evil-replace-pre-command ()
+ "Remember the character under point."
+ (when (evil-replace-state-p)
+ (unless (assq (point) evil-replace-alist)
+ (add-to-list 'evil-replace-alist
+ (cons (point)
+ (unless (eolp)
+ (char-after)))))))
+(put 'evil-replace-pre-command 'permanent-local-hook t)
+
+(defun evil-replace-backspace ()
+ "Restore character under cursor."
+ (interactive)
+ (let (char)
+ (backward-char)
+ (when (assq (point) evil-replace-alist)
+ (setq char (cdr (assq (point) evil-replace-alist)))
+ (save-excursion
+ (delete-char 1)
+ (when char
+ (insert char))))))
+
+(defun evil-update-replace-alist (opoint count chars-to-delete &optional offset)
+ "Add CHARS-TO-DELETE chars to evil-replace-alist, starting at OPOINT.
+If COUNT is greater than CHARS-TO-DELETE, pad the alist with nils.
+Decrement recorded position by optional offset, or 0."
+ (when (evil-replace-state-p)
+ (dotimes (c count)
+ (let ((pos (+ c opoint)))
+ (add-to-list 'evil-replace-alist
+ (cons (- pos (or offset 0)) (when (< c chars-to-delete)
+ (char-after pos))))))))
+
+;;; Motion state
+
+(evil-define-state motion
+ "Motion state."
+ :tag " <M> "
+ :suppress-keymap t)
+
+;;; Emacs state
+
+(evil-define-state emacs
+ "Emacs state."
+ :tag " <E> "
+ :message "-- EMACS --"
+ :input-method t
+ :intercept-esc nil)
+
+(provide 'evil-states)
+
+;;; evil-states.el ends here
diff --git a/elpa/evil-20220503.1314/evil-states.elc b/elpa/evil-20220503.1314/evil-states.elc
new file mode 100644
index 0000000..5d49059
--- /dev/null
+++ b/elpa/evil-20220503.1314/evil-states.elc
Binary files differ
diff --git a/elpa/evil-20220503.1314/evil-types.el b/elpa/evil-20220503.1314/evil-types.el
new file mode 100644
index 0000000..a230b3c
--- /dev/null
+++ b/elpa/evil-20220503.1314/evil-types.el
@@ -0,0 +1,460 @@
+;;; evil-types.el --- Type system -*- lexical-binding: t -*-
+
+;; Author: Vegard Øye <vegard_oye at hotmail.com>
+;; Maintainer: Vegard Øye <vegard_oye at hotmail.com>
+
+;; Version: 1.15.0
+
+;;
+;; This file is NOT part of GNU Emacs.
+
+;;; License:
+
+;; This file is part of Evil.
+;;
+;; Evil 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.
+;;
+;; Evil 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 Evil. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; A type defines a transformation on a pair of buffer positions.
+;; Types are used by Visual state (character/line/block selection)
+;; and Operator-Pending state (character/line/block motions).
+;;
+;; The basic transformation is "expansion". For example, the `line'
+;; type "expands" a pair of positions to whole lines by moving the
+;; first position to the beginning of the line and the last position
+;; to the end of the line. That expanded selection is what the rest
+;; of Emacs sees and acts on.
+;;
+;; An optional transformation is "contraction", which is the opposite
+;; of expansion. If the transformation is one-to-one, expansion
+;; followed by contraction always returns the original range.
+;; (The `line' type is not one-to-one, as it may expand multiple
+;; positions to the same lines.)
+;;
+;; Another optional transformation is "normalization", which takes
+;; two unexpanded positions and adjusts them before expansion.
+;; This is useful for cleaning up "invalid" positions.
+;;
+;; Types are defined at the end of this file using the macro
+;; `evil-define-type'.
+
+(require 'evil-common)
+(require 'evil-macros)
+
+;;; Code:
+
+;;; Type definitions
+
+(evil-define-type exclusive
+ "Return the positions unchanged, with some exceptions.
+If the end position is at the beginning of a line, then:
+
+* If the beginning position is at or before the first non-blank
+ character on the line, return `line' (expanded).
+
+* Otherwise, move the end position to the end of the previous
+ line and return `inclusive' (expanded)."
+ :normalize (lambda (beg end)
+ (cond
+ ((progn
+ (goto-char end)
+ (and (/= beg end) (bolp)))
+ (setq end (max beg (1- end)))
+ (cond
+ ((progn
+ (goto-char beg)
+ (looking-back "^[ \f\t\v]*" (line-beginning-position)))
+ (evil-expand beg end 'line))
+ (t
+ (unless evil-cross-lines
+ (setq end (max beg (1- end))))
+ (evil-expand beg end 'inclusive))))
+ (t
+ (evil-range beg end))))
+ :string (lambda (beg end)
+ (let ((width (- end beg)))
+ (format "%s character%s" width
+ (if (= width 1) "" "s")))))
+
+(evil-define-type inclusive
+ "Include the character under point.
+Handling for `evil-want-visual-char-semi-exclusive' is deprecated,
+and will be removed in a future version."
+ :expand (lambda (beg end)
+ (if (and evil-want-visual-char-semi-exclusive
+ (evil-visual-state-p)
+ (< beg end)
+ (save-excursion
+ (goto-char end)
+ (or (bolp) (eolp))))
+ (evil-range beg end 'exclusive)
+ (evil-range beg (1+ end))))
+ :contract (lambda (beg end)
+ (evil-range beg (max beg (1- end))))
+ :normalize (lambda (beg end)
+ (goto-char end)
+ (when (eq (char-after) ?\n)
+ (setq end (max beg (1- end))))
+ (evil-range beg end))
+ :string (lambda (beg end)
+ (let ((width (- end beg)))
+ (format "%s character%s" width
+ (if (= width 1) "" "s")))))
+
+(evil-define-type line
+ "Include whole lines."
+ :one-to-one nil
+ :expand (lambda (beg end)
+ (evil-range
+ (progn
+ (goto-char beg)
+ (min (line-beginning-position)
+ (progn
+ ;; move to beginning of line as displayed
+ (evil-move-beginning-of-line)
+ (line-beginning-position))))
+ (progn
+ (goto-char end)
+ (max (line-beginning-position 2)
+ (progn
+ ;; move to end of line as displayed
+ (evil-move-end-of-line)
+ (line-beginning-position 2))))))
+ :contract (lambda (beg end)
+ (evil-range beg (max beg (1- end))))
+ :string (lambda (beg end)
+ (let ((height (count-lines beg end)))
+ (format "%s line%s" height
+ (if (= height 1) "" "s")))))
+
+(evil-define-type screen-line
+ "Include whole lines, being aware of `visual-line-mode'
+when `evil-respect-visual-line-mode' is non-nil."
+ :one-to-one nil
+ :expand (lambda (beg end)
+ (if (or (not evil-respect-visual-line-mode)
+ (not visual-line-mode))
+ (evil-line-expand beg end)
+ (evil-range
+ (progn
+ (goto-char beg)
+ (save-excursion
+ (beginning-of-visual-line)))
+ (progn
+ (goto-char end)
+ (save-excursion
+ ;; `beginning-of-visual-line' reverts to the beginning of the
+ ;; last visual line if the end of the last line is the end of
+ ;; the buffer. This would prevent selecting the last screen
+ ;; line.
+ (if (= (line-beginning-position 2) (point-max))
+ (point-max)
+ (beginning-of-visual-line 2)))))))
+ :contract (lambda (beg end)
+ (evil-range beg (max beg (1- end))))
+ :string (lambda (beg end)
+ (let ((height (count-screen-lines beg end)))
+ (format "%s screen line%s" height
+ (if (= height 1) "" "s")))))
+
+(evil-define-type block
+ "Like `inclusive', but for rectangles:
+the last column is included."
+ :expand (lambda (beg end &rest properties)
+ (let ((beg-col (evil-column beg))
+ (end-col (evil-column end))
+ (corner (plist-get properties :corner)))
+ ;; Since blocks are implemented as a pair of buffer
+ ;; positions, expansion is restricted to what the buffer
+ ;; allows. In the case of a one-column block, there are
+ ;; two ways to expand it (either move the upper corner
+ ;; beyond the lower corner, or the lower beyond the
+ ;; upper), so try out both possibilities when
+ ;; encountering the end of the line.
+ (cond
+ ((= beg-col end-col)
+ (goto-char end)
+ (cond
+ ((eolp)
+ (goto-char beg)
+ (if (eolp)
+ (evil-range beg end)
+ (evil-range (1+ beg) end)))
+ ((memq corner '(lower-right upper-right right))
+ (evil-range (1+ beg) end))
+ (t
+ (evil-range beg (1+ end)))))
+ ((< beg-col end-col)
+ (goto-char end)
+ (if (eolp)
+ (evil-range beg end)
+ (evil-range beg (1+ end))))
+ (t
+ (goto-char beg)
+ (if (eolp)
+ (evil-range beg end)
+ (evil-range (1+ beg) end))))))
+ :contract (lambda (beg end)
+ (let ((beg-col (evil-column beg))
+ (end-col (evil-column end)))
+ (if (> beg-col end-col)
+ (evil-range (1- beg) end)
+ (evil-range beg (max beg (1- end))))))
+ :string (lambda (beg end)
+ (let ((height (count-lines
+ beg
+ (progn
+ (goto-char end)
+ (if (and (bolp) (not (eobp)))
+ (1+ end)
+ end))))
+ (width (abs (- (evil-column beg)
+ (evil-column end)))))
+ (format "%s row%s and %s column%s"
+ height
+ (if (= height 1) "" "s")
+ width
+ (if (= width 1) "" "s"))))
+ :rotate (lambda (beg end &rest properties)
+ "Rotate block according to :corner property.
+:corner can be one of `upper-left',``upper-right', `lower-left'
+and `lower-right'."
+ (let ((left (evil-column beg))
+ (right (evil-column end))
+ (corner (or (plist-get properties :corner)
+ 'upper-left)))
+ (evil-sort left right)
+ (goto-char beg)
+ (if (memq corner '(upper-right lower-left))
+ (move-to-column right)
+ (move-to-column left))
+ (setq beg (point))
+ (goto-char end)
+ (if (memq corner '(upper-right lower-left))
+ (move-to-column left)
+ (move-to-column right))
+ (setq end (point))
+ (setq properties (plist-put properties
+ :corner corner))
+ (apply #'evil-range beg end properties))))
+
+(evil-define-type rectangle
+ "Like `exclusive', but for rectangles:
+the last column is excluded."
+ :expand (lambda (beg end)
+ ;; select at least one column
+ (if (= (evil-column beg) (evil-column end))
+ (evil-expand beg end 'block)
+ (evil-range beg end 'block))))
+
+;;; Standard interactive codes
+
+(evil-define-interactive-code "*"
+ "Signal error if the buffer is read-only."
+ (when buffer-read-only
+ (signal 'buffer-read-only nil)))
+
+(evil-define-interactive-code "b" (prompt)
+ "Name of existing buffer."
+ (list (read-buffer prompt (current-buffer) t)))
+
+(evil-define-interactive-code "c"
+ "Read character."
+ (list (read-char)))
+
+(evil-define-interactive-code "p"
+ "Prefix argument converted to number."
+ (list (prefix-numeric-value current-prefix-arg)))
+
+(evil-define-interactive-code "P"
+ "Prefix argument in raw form."
+ (list current-prefix-arg))
+
+;;; Custom interactive codes
+
+(evil-define-interactive-code "<c>"
+ "Count."
+ (list (when current-prefix-arg
+ (prefix-numeric-value
+ current-prefix-arg))))
+
+(evil-define-interactive-code "<vc>"
+ "Count, but only in visual state.
+This should be used by an operator taking a count. In normal
+state the count should not be handled by the operator but by the
+motion that defines the operator's range. In visual state the
+range is specified by the visual region and the count is not used
+at all. Thus in the case the operator may use the count
+directly."
+ (list (when (and (evil-visual-state-p) current-prefix-arg)
+ (prefix-numeric-value
+ current-prefix-arg))))
+
+(evil-define-interactive-code "<C>"
+ "Character read through `evil-read-key'."
+ (list
+ (if (evil-operator-state-p)
+ (evil-without-restriction (evil-read-key))
+ (evil-read-key))))
+
+(evil-define-interactive-code "<r>"
+ "Untyped motion range (BEG END)."
+ (evil-operator-range))
+
+(evil-define-interactive-code "<R>"
+ "Typed motion range (BEG END TYPE)."
+ (evil-operator-range t))
+
+(evil-define-interactive-code "<v>"
+ "Typed motion range of visual range(BEG END TYPE).
+If visual state is inactive then those values are nil."
+ (if (evil-visual-state-p)
+ (let ((range (evil-visual-range)))
+ (list (car range)
+ (cadr range)
+ (evil-type range)))
+ (list nil nil nil)))
+
+(evil-define-interactive-code "<x>"
+ "Current register."
+ (list evil-this-register))
+
+(evil-define-interactive-code "<y>"
+ "Current yank-handler."
+ (list (evil-yank-handler)))
+
+(evil-define-interactive-code "<a>"
+ "Ex argument."
+ :ex-arg t
+ (list (when (evil-ex-p) evil-ex-argument)))
+
+(evil-define-interactive-code "<N>" ()
+ "Prefix argument or ex-arg, converted to number"
+ (list (cond
+ (current-prefix-arg (prefix-numeric-value current-prefix-arg))
+ ((and evil-ex-argument (evil-ex-p)) (string-to-number evil-ex-argument))
+ ((evil-ex-p) nil)
+ (t 1))))
+
+(evil-define-interactive-code "<f>"
+ "Ex file argument."
+ :ex-arg file
+ (list (when (evil-ex-p) (evil-ex-file-arg))))
+
+(evil-define-interactive-code "<b>"
+ "Ex buffer argument."
+ :ex-arg buffer
+ (list (when (evil-ex-p) evil-ex-argument)))
+
+(evil-define-interactive-code "<sh>"
+ "Ex shell command argument."
+ :ex-arg shell
+ (list (when (evil-ex-p) evil-ex-argument)))
+
+(evil-define-interactive-code "<fsh>"
+ "Ex file or shell command argument."
+ :ex-arg file-or-shell
+ (list (when (evil-ex-p) evil-ex-argument)))
+
+(evil-define-interactive-code "<sym>"
+ "Ex symbolic argument."
+ :ex-arg sym
+ (list (when (and (evil-ex-p) evil-ex-argument)
+ (intern evil-ex-argument))))
+
+(evil-define-interactive-code "<addr>"
+ "Ex line number."
+ (list
+ (and (evil-ex-p)
+ (let ((expr (evil-ex-parse evil-ex-argument)))
+ (if (eq (car expr) 'evil-goto-line)
+ (save-excursion
+ (goto-char evil-ex-point)
+ (eval (cadr expr)))
+ (user-error "Invalid address"))))))
+
+(evil-define-interactive-code "<!>"
+ "Ex bang argument."
+ :ex-bang t
+ (list (when (evil-ex-p) evil-ex-bang)))
+
+(evil-define-interactive-code "</>"
+ "Ex delimited argument."
+ (when (evil-ex-p)
+ (evil-delimited-arguments evil-ex-argument)))
+
+(evil-define-interactive-code "<g/>"
+ "Ex global argument."
+ (when (evil-ex-p)
+ (evil-ex-parse-global evil-ex-argument)))
+
+(evil-define-interactive-code "<s/>"
+ "Ex substitution argument."
+ :ex-arg substitution
+ (when (evil-ex-p)
+ (evil-ex-get-substitute-info evil-ex-argument t)))
+
+(evil-define-interactive-code "<xc/>"
+ "Ex register and count argument, both optional.
+Can be used for commands such as :delete [REGISTER] [COUNT] where the
+command can be called with either zero, one or two arguments. When the
+argument is one, if it's numeric it's treated as a COUNT, otherwise -
+REGISTER"
+ (when (evil-ex-p)
+ (evil-ex-get-optional-register-and-count evil-ex-argument)))
+
+(defun evil-ex-get-optional-register-and-count (string)
+ "Parse STRING as an ex arg with both optional REGISTER and COUNT.
+Returns a list (REGISTER COUNT)."
+ (let* ((split-args (split-string (or string "")))
+ (arg-count (length split-args))
+ (arg0 (car split-args))
+ (arg1 (cadr split-args))
+ (number-regex "^-?[1-9][0-9]*$")
+ (register nil)
+ (count nil))
+ (cond
+ ;; :command REGISTER or :command COUNT
+ ((= arg-count 1)
+ (if (string-match-p number-regex arg0)
+ (setq count arg0)
+ (setq register arg0)))
+ ;; :command REGISTER COUNT
+ ((eq arg-count 2)
+ (setq register arg0
+ count arg1))
+ ;; more than 2 args aren't allowed
+ ((> arg-count 2)
+ (user-error "Invalid use")))
+
+ ;; if register is given, check it's valid
+ (when register
+ (unless (= (length register) 1)
+ (user-error "Invalid register"))
+ (setq register (string-to-char register)))
+
+ ;; if count is given, check it's valid
+ (when count
+ (unless (string-match-p number-regex count)
+ (user-error "Invalid count"))
+ (setq count (string-to-number count))
+ (unless (> count 0)
+ (user-error "Invalid count")))
+
+ (list register count)))
+
+(provide 'evil-types)
+
+;;; evil-types.el ends here
diff --git a/elpa/evil-20220503.1314/evil-types.elc b/elpa/evil-20220503.1314/evil-types.elc
new file mode 100644
index 0000000..bc6336d
--- /dev/null
+++ b/elpa/evil-20220503.1314/evil-types.elc
Binary files differ
diff --git a/elpa/evil-20220503.1314/evil-vars.el b/elpa/evil-20220503.1314/evil-vars.el
new file mode 100644
index 0000000..3b1635e
--- /dev/null
+++ b/elpa/evil-20220503.1314/evil-vars.el
@@ -0,0 +1,2100 @@
+;;; evil-vars.el --- Settings and variables -*- lexical-binding: t -*-
+
+;; Author: Vegard Øye <vegard_oye at hotmail.com>
+;; Maintainer: Vegard Øye <vegard_oye at hotmail.com>
+
+;; Version: 1.15.0
+
+;;
+;; This file is NOT part of GNU Emacs.
+
+;;; License:
+
+;; This file is part of Evil.
+;;
+;; Evil 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.
+;;
+;; Evil 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 Evil. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Code:
+
+(declare-function evil-add-command-properties "evil-common"
+ (command &rest properties))
+(declare-function evil-update-insert-state-bindings "evil-maps"
+ (&optional _option-name remove force))
+
+;;; Hooks
+
+(defvar evil-after-load-hook nil
+ "Functions to be run when loading of Evil is finished.
+This hook can be used the execute some initialization routines
+when Evil is completely loaded.")
+
+(defcustom evil-goto-definition-functions
+ '(evil-goto-definition-imenu
+ evil-goto-definition-semantic
+ evil-goto-definition-xref
+ evil-goto-definition-search)
+ "List of functions run until success by `evil-goto-definition'."
+ :type 'hook
+ :group 'evil)
+
+;;; Initialization
+
+(defvar evil-pending-custom-initialize nil
+ "A list of pending initializations for custom variables.
+Each element is a triple (FUNC VAR VALUE). When Evil is
+completely loaded then the functions (funcall FUNC VAR VALUE) is
+called for each element. FUNC should be a function suitable for
+the :initialize property of `defcustom'.")
+
+(defun evil-custom-initialize-pending-reset (var value)
+ "Add a pending customization with `custom-initialize-reset'."
+ (push (list 'custom-initialize-reset var value)
+ evil-pending-custom-initialize))
+
+(defun evil-run-pending-custom-initialize ()
+ "Executes the pending initializations.
+See `evil-pending-custom-initialize'."
+ (dolist (init evil-pending-custom-initialize)
+ (apply (car init) (cdr init)))
+ (remove-hook 'evil-after-load-hook 'evil-run-pending-custom-initialize))
+(add-hook 'evil-after-load-hook 'evil-run-pending-custom-initialize)
+
+;;; Setters
+
+(defun evil-set-toggle-key (key)
+ "Set `evil-toggle-key' to KEY.
+KEY must be readable by `read-kbd-macro'."
+ (let ((old-key (read-kbd-macro
+ (if (boundp 'evil-toggle-key)
+ evil-toggle-key
+ "C-z")))
+ (key (read-kbd-macro key)))
+ (with-no-warnings
+ (dolist (pair '((evil-motion-state-map evil-emacs-state)
+ (evil-insert-state-map evil-emacs-state)
+ (evil-emacs-state-map evil-exit-emacs-state)))
+ (when (boundp (car pair))
+ (let ((map (symbol-value (car pair)))
+ (fun (cadr pair)))
+ (when (keymapp map)
+ (define-key map key fun)
+ (define-key map old-key nil))))))))
+
+(defun evil-set-custom-state-maps (var pending-var key _make newlist)
+ "Changes the list of special keymaps.
+VAR is the variable containing the list of keymaps.
+PENDING-VAR is the variable containing the list of the currently pending
+ keymaps.
+KEY the special symbol to be stored in the keymaps.
+MAKE the creation function of the special keymaps.
+NEWLIST the list of new special keymaps."
+ (set-default pending-var newlist)
+ (when (default-boundp var)
+ (dolist (map (default-value var))
+ (when (and (boundp (car map))
+ (keymapp (default-value (car map))))
+ (define-key (default-value (car map)) (vector key) nil))))
+ (set-default var newlist)
+ (evil-update-pending-maps))
+
+(defun evil-update-pending-maps (&optional _file)
+ "Tries to set pending special keymaps.
+This function should be called from an `after-load-functions'
+hook."
+ (let ((maps '((evil-make-overriding-map . evil-pending-overriding-maps)
+ (evil-make-intercept-map . evil-pending-intercept-maps))))
+ (while maps
+ (let* ((map (pop maps))
+ (make (car map))
+ (pending-var (cdr map))
+ (pending (symbol-value pending-var))
+ newlist)
+ (while pending
+ (let* ((map (pop pending))
+ (kmap (and (boundp (car map))
+ (keymapp (symbol-value (car map)))
+ (symbol-value (car map))))
+ (state (cdr map)))
+ (if kmap
+ (funcall make kmap state)
+ (push map newlist))))
+ (set-default pending-var newlist)))))
+
+(defun evil-set-visual-newline-commands (var value)
+ "Set the value of `evil-visual-newline-commands'.
+Setting this variable changes the properties of the appropriate
+commands."
+ (with-no-warnings
+ (when (default-boundp var)
+ (dolist (cmd (default-value var))
+ (evil-set-command-property cmd :exclude-newline nil)))
+ (set-default var value)
+ (dolist (cmd (default-value var))
+ (evil-set-command-property cmd :exclude-newline t))))
+
+(defun evil-set-custom-motions (var values)
+ "Sets the list of motion commands."
+ (with-no-warnings
+ (when (default-boundp var)
+ (dolist (motion (default-value var))
+ (evil-add-command-properties motion :keep-visual nil :repeat nil)))
+ (set-default var values)
+ (mapc #'evil-declare-motion (default-value var))))
+
+;;; Customization group
+
+(defgroup evil nil
+ "Extensible vi layer."
+ :group 'emulations
+ :prefix 'evil-)
+
+(defcustom evil-auto-indent t
+ "\\<evil-normal-state-map>
+Whether to auto-indent when opening lines with \\[evil-open-below] \
+and \\[evil-open-above]."
+ :type 'boolean
+ :group 'evil)
+(make-variable-buffer-local 'evil-auto-indent)
+
+(defcustom evil-shift-width 4
+ "\\<evil-normal-state-map>
+The number of columns by which a line is shifted.
+This applies to the shifting operators \\[evil-shift-right] and \
+\\[evil-shift-left]."
+ :type 'integer
+ :group 'evil)
+(make-variable-buffer-local 'evil-shift-width)
+
+(defcustom evil-shift-round t
+ "\\<evil-normal-state-map>
+Whether shifting rounds to the nearest multiple.
+If non-nil, \\[evil-shift-right] and \\[evil-shift-left] adjust line
+indentation to the nearest multiple of `evil-shift-width'."
+ :type 'boolean
+ :group 'evil)
+(make-variable-buffer-local 'evil-shift-round)
+
+(defcustom evil-indent-convert-tabs t
+ "\\<evil-normal-state-map>
+If non-nil, the \\[evil-indent] operator converts between leading tabs and spaces.
+Whether tabs are converted to spaces or vice versa depends on the
+value of `indent-tabs-mode'."
+ :type 'boolean
+ :group 'evil)
+
+(defcustom evil-default-cursor t
+ "The default cursor.
+May be a cursor type as per `cursor-type', a color string as passed
+to `set-cursor-color', a zero-argument function for changing the
+cursor, or a list of the above."
+ :type '(set symbol (cons symbol symbol) string function)
+ :group 'evil)
+
+(defvar evil-force-cursor nil
+ "Overwrite the current states default cursor.")
+
+(defcustom evil-start-of-line nil
+ "Analogue of vim's `startofline'.
+If nil, preserve column when making relevant movements of the cursor.
+Otherwise, move the cursor to the start of the line."
+ :type 'boolean
+ :group 'evil)
+
+(defcustom evil-repeat-move-cursor t
+ "\\<evil-normal-state-map>
+Whether repeating commands with \\[evil-repeat] may move the cursor.
+If nil, the original cursor position is preserved, even if the command
+normally would have moved the cursor."
+ :type 'boolean
+ :group 'evil)
+
+(defcustom evil-cross-lines nil
+ "\\<evil-motion-state-map>
+Whether horizontal motions may move to other lines. If non-nil,
+certain motions that conventionally operate in a single line may move
+the cursor to other lines. Otherwise, they are restricted to the
+current line. This applies to \\[evil-backward-char], \
+\\[evil-forward-char], \\[evil-find-char], \
+\\[evil-find-char-backward], \\[evil-find-char-to], \
+\\[evil-find-char-to-backward], \
+\\<evil-normal-state-map>\\[evil-invert-char]."
+ :type 'boolean
+ :group 'evil)
+
+(defcustom evil-backspace-join-lines t
+ "Whether backward delete in insert state may join lines."
+ :type 'boolean
+ :group 'evil)
+
+(defcustom evil-move-cursor-back t
+ "Whether the cursor is moved backwards when exiting insert state.
+If non-nil, the cursor moves \"backwards\" when exiting insert state,
+so that it ends up on the character to the left. Otherwise it remains
+in place, on the character to the right."
+ :type 'boolean
+ :group 'evil)
+
+(defcustom evil-move-beyond-eol nil
+ "Whether the cursor can move past the end of the line.
+If non-nil, the cursor is allowed to move one character past the
+end of the line, as in Emacs."
+ :type 'boolean
+ :group 'evil)
+
+(defcustom evil-respect-visual-line-mode nil
+ "\\<evil-motion-state-map>
+Whether movement commands respect `visual-line-mode'.
+If non-nil, `visual-line-mode' is generally respected when it is
+on. In this case, motions such as \\[evil-next-line] and
+\\[evil-previous-line] navigate by visual lines (on the screen) rather
+than \"physical\" lines (defined by newline characters). If nil,
+the setting of `visual-line-mode' is ignored.
+
+This variable must be set before Evil is loaded."
+ :type 'boolean
+ :group 'evil)
+
+(defcustom evil-repeat-find-to-skip-next t
+ "Whether a repeat of t or T should skip an adjacent character."
+ :type 'boolean
+ :group 'evil)
+
+(defcustom evil-kbd-macro-suppress-motion-error nil
+ "\\<evil-motion-state-map>
+Whether left/right motions signal errors in keyboard macros.
+This variable only affects beginning-of-line or end-of-line errors
+regarding the motions \\[evil-backward-char] and \\[evil-forward-char]
+respectively. This may be desired since such errors cause macro
+definition or execution to be terminated. There are four
+possibilities:
+
+- `record': errors are suppressed when recording macros, but not when
+ replaying them.
+- `replay': errors are suppressed when replaying macros, but not when
+ recording them.
+- `t': errors are suppressed in both cases.
+- `nil': errors are never suppressed."
+ :type '(radio (const :tag "No" :value nil)
+ (const :tag "Record" :value record)
+ (const :tag "Replay" :value replay)
+ (const :tag "Both" :value t))
+ :group 'evil)
+
+(defcustom evil-track-eol t
+ "\\<evil-motion-state-map>
+Whether \\[evil-end-of-line] \"sticks\" the cursor to the end of the line.
+If non-nil, vertical motions after \\[evil-end-of-line] maintain the cursor at the
+end of the line, even if the target line is longer. This is analogous
+to `track-eol', but respects Evil's interpretation of end-of-line."
+ :type 'boolean
+ :group 'evil)
+
+(defcustom evil-mode-line-format 'before
+ "The position of the state tag in the mode line.
+If set to `before' or `after', the tag is placed at the beginning
+or the end of the mode-line, respectively. If nil, there is no
+tag. Otherwise it should be a cons cell (WHERE . WHICH), where
+WHERE is either `before' or `after', and WHICH is a symbol in
+`mode-line-format'. The tag is then placed before or after that
+symbol, respectively."
+ :type '(radio :value 'before
+ (const before)
+ (const after)
+ (cons :tag "Next to symbol"
+ (choice :value after
+ (const before)
+ (const after))
+ symbol))
+ :group 'evil)
+
+(defcustom evil-mouse-word 'evil-word
+ "The thing-at-point symbol for double click selection.
+The double-click starts visual state in a special word selection
+mode. This symbol is used to determine the words to be
+selected. Possible values are `evil-word' or `evil-WORD'."
+ :type 'symbol
+ :group 'evil)
+
+(defcustom evil-bigword "^ \t\r\n"
+ "The set of characters to be interpreted as WORD boundaries.
+This is enclosed with square brackets and used as a regular
+expression. By default, whitespace characters are considered
+WORD boundaries."
+ :type 'string
+ :group 'evil)
+(make-variable-buffer-local 'evil-bigword)
+
+(defcustom evil-want-fine-undo nil
+ "Whether actions are undone in several steps.
+There are two possible choices: nil (\"no\") means that all
+changes made during insert state, including a possible delete
+after a change operation, are collected in a single undo step.
+Non-nil (\"yes\") means that undo steps are determined according
+to Emacs heuristics, and no attempt is made to aggregate changes.
+
+For backward compatibility purposes, the value `fine' is
+interpreted as `nil'. This option was removed because it did not
+work consistently."
+ :type '(radio (const :tag "No" :value nil)
+ (const :tag "Fine (obsolete)" :value fine)
+ (const :tag "Yes" :value t))
+ :group 'evil)
+
+(defcustom evil-regexp-search t
+ "\\<evil-motion-state-map>
+Whether to use regular expressions for searching in \
+\\[evil-search-forward] and \\[evil-search-backward]."
+ :type 'boolean
+ :group 'evil)
+
+(defcustom evil-search-wrap t
+ "\\<evil-motion-state-map>
+Whether search with \\[evil-search-forward] and \
+\\[evil-search-backward] wraps around the buffer.
+If this is non-nil, search stops at the buffer boundaries."
+ :type 'boolean
+ :group 'evil)
+
+(defcustom evil-flash-delay 2
+ "\\<evil-motion-state-map>
+Time in seconds to flash search matches after \\[evil-search-next] and \
+\\[evil-search-previous]."
+ :type 'number
+ :group 'evil)
+
+(defcustom evil-auto-balance-windows t
+ "If non-nil window creation and deletion trigger rebalancing."
+ :type 'boolean
+ :group 'evil)
+
+(defcustom evil-split-window-below nil
+ "If non-nil split windows are created below."
+ :type 'boolean
+ :group 'evil)
+
+(defcustom evil-vsplit-window-right nil
+ "If non-nil vertically split windows with are created to the right."
+ :type 'boolean
+ :group 'evil)
+
+(defcustom evil-esc-delay 0.01
+ "The time, in seconds, to wait for another key after escape.
+If no further event arrives during this time, the event is
+translated to `ESC'. Otherwise, it is translated according to
+`input-decode-map'. This does not apply in Emacs state, and may
+also be inhibited by setting `evil-inhibit-esc'."
+ :type 'number
+ :group 'evil)
+
+(defvar evil-esc-mode nil
+ "Non-nil if `evil-esc-mode' is enabled.")
+
+(defvar evil-esc-map nil
+ "Original ESC prefix map in `input-decode-map'.
+Used by `evil-esc-mode'.")
+
+(defvar evil-inhibit-esc nil
+ "If non-nil, the \\e event will never be translated to 'escape.")
+
+(defcustom evil-intercept-esc 'always
+ "Whether Evil should intercept the escape key.
+In the terminal, escape and a meta key sequence both generate the
+same event. In order to distingush these, Evil uses
+`input-decode-map'. It is not necessary to do this in a graphical
+Emacs session. However, if you prefer to use `C-[' as escape (which
+is identical to the terminal escape key code), this interception must
+also happen in graphical Emacs sessions. Set this variable to
+`always', t (only in the terminal) or nil (never intercept)."
+ :type '(radio (const :tag "Never" :value nil)
+ (const :tag "In terminal only" :value t)
+ (const :tag "Always" :value always))
+ :group 'evil)
+
+(defcustom evil-show-paren-range 0
+ "The minimal distance between point and a parenthesis
+which causes the parenthesis to be highlighted."
+ :type 'integer
+ :group 'evil)
+
+(defcustom evil-ex-hl-update-delay 0.02
+ "Time in seconds of idle before updating search highlighting.
+Setting this to a period shorter than that of keyboard's repeat
+rate allows highlights to update while scrolling."
+ :type 'number
+ :group 'evil)
+
+(defcustom evil-highlight-closing-paren-at-point-states
+ '(not emacs insert replace)
+ "The states in which the closing parenthesis at point should be highlighted.
+All states listed here highlight the closing parenthesis at
+point (which is Vim's default behavior). All others highlight the
+parenthesis before point (which is Emacs default behavior). If
+this list contains the symbol `not' then its meaning is inverted,
+i.e. all states listed here highlight the closing parenthesis
+before point."
+ :type '(repeat symbol)
+ :group 'evil)
+
+(defcustom evil-kill-on-visual-paste t
+ "Whether pasting in visual state adds the replaced text to the
+kill ring, making it the default for the next paste. The default,
+replicates the default Vim behavior."
+ :type 'boolean
+ :group 'evil)
+
+(defcustom evil-want-C-i-jump t
+ "Whether `C-i' jumps forward in the jump list (like Vim).
+Otherwise, `C-i' inserts a tab character."
+ :type 'boolean
+ :group 'evil
+ :set #'(lambda (sym value)
+ (set-default sym value)
+ (when (boundp 'evil-motion-state-map)
+ (cond
+ ((and (not value)
+ (eq (lookup-key evil-motion-state-map (kbd "C-i"))
+ 'evil-jump-forward))
+ (define-key evil-motion-state-map (kbd "C-i") nil))
+ ((and value
+ (not (lookup-key evil-motion-state-map (kbd "C-i"))))
+ (define-key evil-motion-state-map (kbd "C-i") 'evil-jump-forward))))))
+
+(defcustom evil-want-C-u-scroll nil
+ "Whether `C-u' scrolls up (like Vim).
+Otherwise, `C-u' applies a prefix argument. The binding of
+`C-u' mirrors Emacs behaviour by default due to the relative
+ubiquity of prefix arguments."
+ :type 'boolean
+ :group 'evil
+ :set #'(lambda (sym value)
+ (set-default sym value)
+ (when (boundp 'evil-motion-state-map)
+ (cond
+ ((and (not value)
+ (eq (lookup-key evil-motion-state-map (kbd "C-u"))
+ 'evil-scroll-up))
+ (define-key evil-motion-state-map (kbd "C-u") nil))
+ ((and value
+ (not (lookup-key evil-motion-state-map (kbd "C-u"))))
+ (define-key evil-motion-state-map (kbd "C-u") 'evil-scroll-up))))))
+
+(defcustom evil-want-C-d-scroll t
+ "Whether `C-d' scrolls down (like Vim)."
+ :type 'boolean
+ :group 'evil
+ :set #'(lambda (sym value)
+ (set-default sym value)
+ (when (boundp 'evil-motion-state-map)
+ (cond
+ ((and (not value)
+ (eq (lookup-key evil-motion-state-map (kbd "C-d"))
+ 'evil-scroll-down))
+ (define-key evil-motion-state-map (kbd "C-d") nil))
+ ((and value
+ (not (lookup-key evil-motion-state-map (kbd "C-d"))))
+ (define-key evil-motion-state-map (kbd "C-d") 'evil-scroll-down))))))
+
+(defcustom evil-want-C-u-delete nil
+ "Whether `C-u' deletes back to indentation in insert state.
+Otherwise, `C-u' applies a prefix argument. The binding of
+`C-u' mirrors Emacs behaviour by default due to the relative
+ubiquity of prefix arguments."
+ :type 'boolean
+ :group 'evil
+ :set #'(lambda (sym value)
+ (set-default sym value)
+ (when (and (boundp 'evil-insert-state-map)
+ (boundp 'evil-replace-state-map))
+ (cond
+ ((and (not value)
+ (eq (lookup-key evil-insert-state-map (kbd "C-u"))
+ 'evil-delete-back-to-indentation))
+ (define-key evil-insert-state-map (kbd "C-u") nil)
+ (define-key evil-replace-state-map (kbd "C-u") nil))
+ ((and value
+ (not (lookup-key evil-insert-state-map (kbd "C-u"))))
+ (define-key evil-insert-state-map (kbd "C-u") 'evil-delete-back-to-indentation)
+ (define-key evil-replace-state-map (kbd "C-u") 'evil-delete-back-to-indentation))))))
+
+(defcustom evil-want-C-w-delete t
+ "Whether `C-w' deletes a word in Insert state."
+ :type 'boolean
+ :group 'evil
+ :set #'(lambda (sym value)
+ (set-default sym value)
+ (when (and (boundp 'evil-insert-state-map)
+ (boundp 'evil-replace-state-map))
+ (cond
+ ((and (not value)
+ (eq (lookup-key evil-insert-state-map (kbd "C-w"))
+ 'evil-delete-backward-word))
+ (define-key evil-insert-state-map (kbd "C-w") 'evil-window-map)
+ (define-key evil-replace-state-map (kbd "C-w") 'evil-window-map))
+ ((and value
+ (eq (lookup-key evil-insert-state-map (kbd "C-w"))
+ 'evil-window-map))
+ (define-key evil-insert-state-map (kbd "C-w") 'evil-delete-backward-word)
+ (define-key evil-replace-state-map (kbd "C-w") 'evil-delete-backward-word))))))
+
+(defcustom evil-want-C-h-delete nil
+ "Whether `C-h' deletes a char in Insert state."
+ :type 'boolean
+ :group 'evil
+ :set #'(lambda (sym value)
+ (set-default sym value)
+ (when (and (boundp 'evil-insert-state-map)
+ (boundp 'evil-replace-state-map))
+ (cond
+ ((and (not value)
+ (eq (lookup-key evil-insert-state-map (kbd "C-h"))
+ 'evil-delete-backward-char-and-join))
+ (define-key evil-insert-state-map (kbd "C-h") nil)
+ (define-key evil-replace-state-map (kbd "C-h") nil))
+ ((and value
+ (not (lookup-key evil-insert-state-map (kbd "C-h"))))
+ (define-key evil-insert-state-map (kbd "C-h") 'evil-delete-backward-char-and-join)
+ (define-key evil-replace-state-map (kbd "C-h") 'evil-replace-backspace))))))
+
+(defcustom evil-want-C-g-bindings nil
+ "Whether `C-g' postfix can be used in bindings."
+ :type 'boolean
+ :group 'evil)
+
+(defcustom evil-want-C-w-in-emacs-state nil
+ "Whether `C-w' prefixes windows commands in Emacs state."
+ :type 'boolean
+ :group 'evil
+ :set #'(lambda (sym value)
+ (set-default sym value)
+ (when (boundp 'evil-emacs-state-map)
+ (cond
+ ((and (not value)
+ (eq (lookup-key evil-emacs-state-map (kbd "C-w"))
+ 'evil-window-map))
+ (define-key evil-emacs-state-map (kbd "C-w") nil))
+ ((and value
+ (not (lookup-key evil-emacs-state-map (kbd "C-w"))))
+ (define-key evil-emacs-state-map (kbd "C-w") 'evil-window-map))))))
+
+(defcustom evil-want-change-word-to-end t
+ "Whether `cw' behaves like `ce'."
+ :type 'boolean
+ :group 'evil)
+
+(defcustom evil-want-Y-yank-to-eol nil
+ "Whether `Y' yanks to the end of the line.
+The default behavior is to yank the whole line, like Vim."
+ :group 'evil
+ :type 'boolean
+ :initialize #'evil-custom-initialize-pending-reset
+ :set #'(lambda (sym value)
+ (set-default sym value)
+ (evil-add-command-properties
+ 'evil-yank-line
+ :motion (if value
+ 'evil-end-of-line-or-visual-line
+ 'evil-line-or-visual-line))))
+
+(defcustom evil-disable-insert-state-bindings nil
+ "Whether insert state bindings should be used.
+Bindings for escape, delete and `evil-toggle-key' are always
+available. If this is non-nil, default Emacs bindings are by and
+large accessible in insert state."
+ :group 'evil
+ :type 'boolean
+ :initialize #'evil-custom-initialize-pending-reset
+ :set #'(lambda (sym value)
+ (set-default sym value)
+ (evil-update-insert-state-bindings sym value)))
+
+(defcustom evil-echo-state t
+ "Whether to signal the current state in the echo area."
+ :type 'boolean
+ :group 'evil)
+
+(defcustom evil-complete-all-buffers t
+ "\\<evil-insert-state-map>
+Whether completion looks for matches in all buffers.
+This applies to \\[evil-complete-next] and \\[evil-complete-previous] \
+in insert state."
+ :type 'boolean
+ :group 'evil)
+
+(defcustom evil-search-wrap-ring-bell nil
+ "Whether to ring the bell when search wraps around the buffer."
+ :type 'boolean
+ :group 'evil)
+
+(defvar dabbrev-search-these-buffers-only)
+(defvar dabbrev-case-distinction)
+(defcustom evil-complete-next-func
+ #'(lambda (arg)
+ (require 'dabbrev)
+ (let ((dabbrev-search-these-buffers-only
+ (unless evil-complete-all-buffers
+ (list (current-buffer))))
+ dabbrev-case-distinction)
+ (condition-case nil
+ (if (eq last-command this-command)
+ (dabbrev-expand nil)
+ (dabbrev-expand (- (abs (or arg 1)))))
+ (error (dabbrev-expand nil)))))
+ "Completion function used by \
+\\<evil-insert-state-map>\\[evil-complete-next]."
+ :type 'function
+ :group 'evil)
+
+(defcustom evil-complete-previous-func
+ #'(lambda (arg)
+ (require 'dabbrev)
+ (let ((dabbrev-search-these-buffers-only
+ (unless evil-complete-all-buffers
+ (list (current-buffer))))
+ dabbrev-case-distinction)
+ (dabbrev-expand arg)))
+ "Completion function used by \
+\\<evil-insert-state-map>\\[evil-complete-previous]."
+ :type 'function
+ :group 'evil)
+
+(defcustom evil-complete-next-minibuffer-func 'minibuffer-complete
+ "Minibuffer completion function used by \
+\\<evil-insert-state-map>\\[evil-complete-next]."
+ :type 'function
+ :group 'evil)
+
+(defcustom evil-complete-previous-minibuffer-func 'minibuffer-complete
+ "Minibuffer completion function used by \
+\\<evil-insert-state-map>\\[evil-complete-previous]."
+ :type 'function
+ :group 'evil)
+
+(defcustom evil-complete-next-line-func
+ #'(lambda (arg)
+ (let ((hippie-expand-try-functions-list
+ '(try-expand-line
+ try-expand-line-all-buffers)))
+ (hippie-expand arg)))
+ "Minibuffer completion function used by \
+\\<evil-insert-state-map>\\[evil-complete-next-line]."
+ :type 'function
+ :group 'evil)
+
+(defcustom evil-complete-previous-line-func
+ evil-complete-next-line-func
+ "Minibuffer completion function used by \
+\\<evil-insert-state-map>\\[evil-complete-previous-line]."
+ :type 'function
+ :group 'evil)
+
+(defcustom evil-lookup-func #'woman
+ "Lookup function used by \
+\"\\<evil-motion-state-map>\\[evil-lookup]\"."
+ :type 'function
+ :group 'evil)
+
+(defcustom evil-toggle-key "C-z"
+ "The key used to change to and from Emacs state.
+Must be readable by `read-kbd-macro'. For example: \"C-z\"."
+ :type 'string
+ :group 'evil
+ :set #'(lambda (sym value)
+ (evil-set-toggle-key value)
+ (set-default sym value)))
+
+(defcustom evil-default-state 'normal
+ "The default Evil state.
+This is the state a buffer starts in when it is not otherwise
+configured (see `evil-set-initial-state' and
+`evil-buffer-regexps'). The value may be one of `normal',
+`insert', `visual', `replace', `operator', `motion' and `emacs'."
+ :type 'symbol
+ :group 'evil)
+
+(defcustom evil-buffer-regexps
+ '(("^ \\*load\\*" . nil))
+ "Regular expressions determining the initial state for a buffer.
+Entries have the form (REGEXP . STATE), where REGEXP is a regular
+expression matching the buffer's name and STATE is one of `normal',
+`insert', `visual', `replace', `operator', `motion', `emacs' and
+`nil'. If STATE is `nil', Evil is disabled in the buffer."
+ :type '(alist :key-type string :value-type symbol)
+ :group 'evil)
+
+(defcustom evil-emacs-state-modes
+ '(5x5-mode
+ archive-mode
+ bbdb-mode
+ biblio-selection-mode
+ blackbox-mode
+ bookmark-bmenu-mode
+ bookmark-edit-annotation-mode
+ browse-kill-ring-mode
+ bs-mode
+ bubbles-mode
+ bzr-annotate-mode
+ calc-mode
+ cfw:calendar-mode
+ completion-list-mode
+ Custom-mode
+ custom-theme-choose-mode
+ debugger-mode
+ delicious-search-mode
+ desktop-menu-blist-mode
+ desktop-menu-mode
+ doc-view-mode
+ dun-mode
+ dvc-bookmarks-mode
+ dvc-diff-mode
+ dvc-info-buffer-mode
+ dvc-log-buffer-mode
+ dvc-revlist-mode
+ dvc-revlog-mode
+ dvc-status-mode
+ dvc-tips-mode
+ ediff-mode
+ ediff-meta-mode
+ efs-mode
+ Electric-buffer-menu-mode
+ emms-browser-mode
+ emms-mark-mode
+ emms-metaplaylist-mode
+ emms-playlist-mode
+ ess-help-mode
+ etags-select-mode
+ fj-mode
+ gc-issues-mode
+ gdb-breakpoints-mode
+ gdb-disassembly-mode
+ gdb-frames-mode
+ gdb-locals-mode
+ gdb-memory-mode
+ gdb-registers-mode
+ gdb-threads-mode
+ gist-list-mode
+ git-rebase-mode
+ gnus-article-mode
+ gnus-browse-mode
+ gnus-group-mode
+ gnus-server-mode
+ gnus-summary-mode
+ gomoku-mode
+ google-maps-static-mode
+ ibuffer-mode
+ jde-javadoc-checker-report-mode
+ magit-cherry-mode
+ magit-diff-mode
+ magit-log-mode
+ magit-log-select-mode
+ magit-popup-mode
+ magit-popup-sequence-mode
+ magit-process-mode
+ magit-reflog-mode
+ magit-refs-mode
+ magit-revision-mode
+ magit-stash-mode
+ magit-stashes-mode
+ magit-status-mode
+ mh-folder-mode
+ monky-mode
+ mpuz-mode
+ mu4e-main-mode
+ mu4e-headers-mode
+ mu4e-view-mode
+ notmuch-hello-mode
+ notmuch-search-mode
+ notmuch-show-mode
+ notmuch-tree-mode
+ occur-mode
+ org-agenda-mode
+ package-menu-mode
+ pdf-outline-buffer-mode
+ pdf-view-mode
+ proced-mode
+ rcirc-mode
+ rebase-mode
+ recentf-dialog-mode
+ reftex-select-bib-mode
+ reftex-select-label-mode
+ reftex-toc-mode
+ sldb-mode
+ slime-inspector-mode
+ slime-thread-control-mode
+ slime-xref-mode
+ snake-mode
+ solitaire-mode
+ sr-buttons-mode
+ sr-mode
+ sr-tree-mode
+ sr-virtual-mode
+ tar-mode
+ tetris-mode
+ tla-annotate-mode
+ tla-archive-list-mode
+ tla-bconfig-mode
+ tla-bookmarks-mode
+ tla-branch-list-mode
+ tla-browse-mode
+ tla-category-list-mode
+ tla-changelog-mode
+ tla-follow-symlinks-mode
+ tla-inventory-file-mode
+ tla-inventory-mode
+ tla-lint-mode
+ tla-logs-mode
+ tla-revision-list-mode
+ tla-revlog-mode
+ tla-tree-lint-mode
+ tla-version-list-mode
+ twittering-mode
+ urlview-mode
+ vc-annotate-mode
+ vc-dir-mode
+ vc-git-log-view-mode
+ vc-hg-log-view-mode
+ vc-svn-log-view-mode
+ vm-mode
+ vm-summary-mode
+ w3m-mode
+ wab-compilation-mode
+ xgit-annotate-mode
+ xgit-changelog-mode
+ xgit-diff-mode
+ xgit-revlog-mode
+ xhg-annotate-mode
+ xhg-log-mode
+ xhg-mode
+ xhg-mq-mode
+ xhg-mq-sub-mode
+ xhg-status-extra-mode)
+ "Modes that should come up in Emacs state."
+ :type '(repeat symbol)
+ :group 'evil)
+
+(defcustom evil-insert-state-modes
+ '(comint-mode
+ erc-mode
+ eshell-mode
+ geiser-repl-mode
+ gud-mode
+ inferior-apl-mode
+ inferior-caml-mode
+ inferior-emacs-lisp-mode
+ inferior-j-mode
+ inferior-python-mode
+ inferior-scheme-mode
+ inferior-sml-mode
+ internal-ange-ftp-mode
+ haskell-interactive-mode
+ prolog-inferior-mode
+ reb-mode
+ shell-mode
+ slime-repl-mode
+ term-mode
+ utop-mode
+ wdired-mode)
+ "Modes that should come up in Insert state."
+ :type '(repeat symbol)
+ :group 'evil)
+
+(defcustom evil-motion-state-modes
+ '(apropos-mode
+ Buffer-menu-mode
+ calendar-mode
+ color-theme-mode
+ command-history-mode
+ compilation-mode
+ dictionary-mode
+ ert-results-mode
+ help-mode
+ Info-mode
+ Man-mode
+ speedbar-mode
+ undo-tree-visualizer-mode
+ woman-mode)
+ "Modes that should come up in Motion state."
+ :type '(repeat symbol)
+ :group 'evil)
+
+(defvar evil-pending-overriding-maps nil
+ "An alist of pending overriding maps.")
+
+(defvar evil-pending-intercept-maps nil
+ "An alist of pending intercept maps.")
+
+(defcustom evil-overriding-maps '()
+ "Keymaps that should override Evil maps.
+Entries have the form (MAP-VAR . STATE), where MAP-VAR is
+a keymap variable and STATE is the state whose bindings
+should be overridden. If STATE is nil, all states are
+overridden."
+ :type '(alist :key-type symbol :value-type symbol)
+ :group 'evil
+ :set #'(lambda (var values)
+ (set-default var values)
+ (evil-set-custom-state-maps 'evil-overriding-maps
+ 'evil-pending-overriding-maps
+ 'override-state
+ 'evil-make-overriding-map
+ values))
+ :initialize 'evil-custom-initialize-pending-reset)
+
+(add-hook 'after-load-functions #'evil-update-pending-maps)
+
+(defcustom evil-intercept-maps
+ '((edebug-mode-map . nil))
+ "Keymaps that should intercept Evil maps.
+Entries have the form (MAP-VAR . STATE), where MAP-VAR is
+a keymap variable and STATE is the state whose bindings
+should be intercepted. If STATE is nil, all states are
+intercepted."
+ :type '(alist :key-type symbol :value-type symbol)
+ :group 'evil
+ :set #'(lambda (var values)
+ (set-default var values)
+ (evil-set-custom-state-maps 'evil-intercept-maps
+ 'evil-pending-intercept-maps
+ 'intercept-state
+ 'evil-make-intercept-map
+ values))
+ :initialize 'evil-custom-initialize-pending-reset)
+
+(defcustom evil-motions
+ '(back-to-indentation
+ backward-char
+ backward-list
+ backward-paragraph
+ backward-sentence
+ backward-sexp
+ backward-up-list
+ backward-word
+ beginning-of-buffer
+ beginning-of-defun
+ beginning-of-line
+ beginning-of-visual-line
+ c-beginning-of-defun
+ c-end-of-defun
+ diff-file-next
+ diff-file-prev
+ diff-hunk-next
+ diff-hunk-prev
+ down-list
+ end-of-buffer
+ end-of-defun
+ end-of-line
+ end-of-visual-line
+ exchange-point-and-mark
+ forward-char
+ forward-list
+ forward-paragraph
+ forward-sentence
+ forward-sexp
+ forward-word
+ goto-last-change
+ ibuffer-backward-line
+ ibuffer-forward-line
+ isearch-abort
+ isearch-cancel
+ isearch-complete
+ isearch-del-char
+ isearch-delete-char
+ isearch-edit-string
+ isearch-exit
+ isearch-highlight-regexp
+ isearch-occur
+ isearch-other-control-char
+ isearch-other-meta-char
+ isearch-printing-char
+ isearch-query-replace
+ isearch-query-replace-regexp
+ isearch-quote-char
+ isearch-repeat-backward
+ isearch-repeat-forward
+ isearch-ring-advance
+ isearch-ring-retreat
+ isearch-toggle-case-fold
+ isearch-toggle-input-method
+ isearch-toggle-regexp
+ isearch-toggle-specified-input-method
+ isearch-toggle-word
+ isearch-yank-char
+ isearch-yank-kill
+ isearch-yank-line
+ isearch-yank-word-or-char
+ keyboard-quit
+ left-char
+ left-word
+ mouse-drag-region
+ mouse-save-then-kill
+ mouse-set-point
+ mouse-set-region
+ mwheel-scroll
+ move-beginning-of-line
+ move-end-of-line
+ next-error
+ next-line
+ paredit-backward
+ paredit-backward-down
+ paredit-backward-up
+ paredit-forward
+ paredit-forward-down
+ paredit-forward-up
+ pop-global-mark
+ pop-tag-mark
+ pop-to-mark-command
+ previous-error
+ previous-line
+ right-char
+ right-word
+ scroll-down
+ scroll-down-command
+ scroll-up
+ scroll-up-command
+ sgml-skip-tag-backward
+ sgml-skip-tag-forward
+ up-list)
+ "Non-Evil commands to initialize to motions."
+ :type '(repeat symbol)
+ :group 'evil
+ :set 'evil-set-custom-motions
+ :initialize 'evil-custom-initialize-pending-reset)
+
+(defcustom evil-visual-newline-commands
+ '(LaTeX-section
+ TeX-font)
+ "Commands excluding the trailing newline of a Visual Line selection.
+These commands work better without this newline."
+ :type '(repeat symbol)
+ :group 'evil
+ :set 'evil-set-visual-newline-commands
+ :initialize 'evil-custom-initialize-pending-reset)
+
+(defcustom evil-want-visual-char-semi-exclusive nil
+ "DEPRECATED. Will be removed in a future version.
+Prefer to set `evil-v$-excludes-newline' to non-nil.
+
+Visual character selection to beginning/end of line is exclusive.
+If non nil then an inclusive visual character selection which
+ends at the beginning or end of a line is turned into an
+exclusive selection. Thus if the selected (inclusive) range ends
+at the beginning of a line it is changed to not include the first
+character of that line, and if the selected range ends at the end
+of a line it is changed to not include the newline character of
+that line."
+ :type 'boolean
+ :group 'evil)
+(make-obsolete-variable
+ evil-want-visual-char-semi-exclusive
+ "Semi-exclusivity prevents selecting text + 1st char of next line,
+without having to introduce new niche functionality.
+Prefer to set `evil-v$-excludes-newline' to non-nil."
+ "1.15.0")
+
+(defcustom evil-v$-excludes-newline nil
+ "If non-nil, `evil-end-of-line' does not move as far as to include
+the `\n' char at eol. This makes `v$' consistent with `$' used as a
+motion (e.g. `v$y' is consistent with `y$' in normal state)."
+ :type 'boolean
+ :group 'evil)
+
+(defcustom evil-text-object-change-visual-type t
+ "Text objects change the current visual state type.
+If non-nil then a text-object changes the type of the visual state to
+its default selection type (e.g. a word object always changes to
+charwise visual state). Otherwise the current visual state type is
+preserved."
+ :type 'boolean
+ :group 'evil)
+
+(defgroup evil-cjk nil
+ "CJK support"
+ :prefix "evil-cjk-"
+ :group 'evil)
+
+(defcustom evil-cjk-emacs-word-boundary nil
+ "Determine word boundary exactly the same way as Emacs does."
+ :type 'boolean
+ :group 'evil-cjk)
+
+(defcustom evil-cjk-word-separating-categories
+ '(;; Kanji
+ (?C . ?H) (?C . ?K) (?C . ?k) (?C . ?A) (?C . ?G)
+ ;; Hiragana
+ (?H . ?C) (?H . ?K) (?H . ?k) (?H . ?A) (?H . ?G)
+ ;; Katakana
+ (?K . ?C) (?K . ?H) (?K . ?k) (?K . ?A) (?K . ?G)
+ ;; half-width Katakana
+ (?k . ?C) (?k . ?H) (?k . ?K) ; (?k . ?A) (?k . ?G)
+ ;; full-width alphanumeric
+ (?A . ?C) (?A . ?H) (?A . ?K) ; (?A . ?k) (?A . ?G)
+ ;; full-width Greek
+ (?G . ?C) (?G . ?H) (?G . ?K) ; (?G . ?k) (?G . ?A)
+ )
+ "List of pair (cons) of categories to determine word boundary
+used in `evil-cjk-word-boundary-p'. See the documentation of
+`word-separating-categories'. Use `describe-categories' to see
+the list of categories."
+ :type '(alist :key-type (choice character (const nil))
+ :value-type (choice character (const nil)))
+ :group 'evil-cjk)
+
+(defcustom evil-cjk-word-combining-categories
+ '(;; default value in word-combining-categories
+ (nil . ?^) (?^ . nil)
+ ;; Roman
+ (?r . ?k) (?r . ?A) (?r . ?G)
+ ;; half-width Katakana
+ (?k . ?r) (?k . ?A) (?k . ?G)
+ ;; full-width alphanumeric
+ (?A . ?r) (?A . ?k) (?A . ?G)
+ ;; full-width Greek
+ (?G . ?r) (?G . ?k) (?G . ?A)
+ )
+ "List of pair (cons) of categories to determine word boundary
+used in `evil-cjk-word-boundary-p'. See the documentation of
+`word-combining-categories'. Use `describe-categories' to see the
+list of categories."
+ :type '(alist :key-type (choice character (const nil))
+ :value-type (choice character (const nil)))
+ :group 'evil-cjk)
+
+(defcustom evil-ex-complete-emacs-commands 'in-turn
+ "TAB-completion for Emacs commands in ex command line.
+This variable determines when Emacs commands are considered for
+completion, always, never, or only if no Evil ex command is
+available for completion."
+ :group 'evil
+ :type '(radio (const :tag "Only if no ex-command." :value in-turn)
+ (const :tag "Never" :value nil)
+ (const :tag "Always" :value t)))
+
+(defface evil-ex-commands '(( nil
+ :underline t
+ :slant italic))
+ "Face for the Evil command in completion in ex mode."
+ :group 'evil)
+
+(defface evil-ex-info '(( ((supports :slant))
+ :slant italic
+ :foreground "red"))
+ "Face for the info message in ex mode."
+ :group 'evil)
+
+(defcustom evil-ex-visual-char-range nil
+ "Type of default ex range in visual char state.
+If non-nil the default range when starting an ex command from
+character visual state is `<,`> otherwise it is '<,'>. In the
+first case the ex command will be passed a region covering only
+the visual selection. In the second case the passed region will
+be extended to contain full lines."
+ :group 'evil
+ :type 'boolean)
+
+;; Searching
+(defcustom evil-symbol-word-search nil
+ "If nil then * and # search for words otherwise for symbols."
+ :group 'evil
+ :type 'boolean)
+(make-variable-buffer-local 'evil-symbol-word-search)
+
+(defcustom evil-magic t
+ "Meaning which characters in a pattern are magic.
+The meaning of those values is the same as in Vim. Note that it
+only has influence if the Evil search module is chosen in
+`evil-search-module'."
+ :group 'evil
+ :type '(radio (const :tag "Very magic." :value very-magic)
+ (const :tag "Magic" :value t)
+ (const :tag "Nomagic" :value nil)
+ (const :tag "Very nomagic" :value very-nomagic)))
+
+(defcustom evil-ex-search-vim-style-regexp nil
+ "If non-nil Vim-style backslash codes are supported in search patterns.
+See `evil-transform-vim-style-regexp' for the supported backslash
+codes. Note that this only affects the search command if
+`evil-search-module' is set to 'evil-search. The isearch module
+always uses plain Emacs regular expressions."
+ :type 'boolean
+ :group 'evil)
+
+(defcustom evil-ex-interactive-search-highlight 'all-windows
+ "Determine in which windows the interactive highlighting should be shown."
+ :type '(radio (const :tag "All windows." all-windows)
+ (const :tag "Selected window." selected-window)
+ (const :tag "Disable highlighting." nil))
+ :group 'evil)
+
+(defcustom evil-ex-search-persistent-highlight t
+ "If non-nil matches remain highlighted when the search ends."
+ :type 'boolean
+ :group 'evil)
+
+(defcustom evil-ex-search-case 'smart
+ "The case behaviour of the search command.
+Smart case means that the pattern is case sensitive if and only
+if it contains an upper case letter, otherwise it is case
+insensitive."
+ :type '(radio (const :tag "Case sensitive." sensitive)
+ (const :tag "Case insensitive." insensitive)
+ (const :tag "Smart case." smart))
+ :group 'evil)
+
+(defcustom evil-ex-substitute-case nil
+ "The case behaviour of the search command.
+Smart case means that the pattern is case sensitive if and only
+if it contains an upper case letter, otherwise it is case
+insensitive. If nil then the setting of `evil-ex-search-case' is
+used."
+ :type '(radio (const :tag "Same as interactive search." nil)
+ (const :tag "Case sensitive." sensitive)
+ (const :tag "Case insensitive." insensitive)
+ (const :tag "Smart case." smart))
+ :group 'evil)
+
+(defcustom evil-ex-search-interactive t
+ "If t search is interactive."
+ :type 'boolean
+ :group 'evil)
+
+(defcustom evil-ex-search-incremental t
+ "If t, use incremental search. Note that this only affects the
+search command if `evil-search-module' is set to 'evil-search."
+ :type 'boolean
+ :group 'evil)
+
+(defcustom evil-ex-search-highlight-all t
+ "If t and interactive search is enabled, all matches are
+highlighted."
+ :type 'boolean
+ :group 'evil)
+
+(defcustom evil-ex-substitute-highlight-all t
+ "If t all matches for the substitute pattern are highlighted."
+ :type 'boolean
+ :group 'evil)
+
+(defcustom evil-ex-substitute-interactive-replace t
+ "If t and substitute patterns are highlighted,
+the replacement is shown interactively."
+ :type 'boolean
+ :group 'evil)
+
+(defcustom evil-ex-substitute-global nil
+ "If non-nil substitute patterns are global by default.
+Usually (if this variable is nil) a substitution works only on
+the first match of a pattern in a line unless the 'g' flag is
+given, in which case the substitution happens on all matches in a
+line. If this option is non-nil, this behaviour is reversed: the
+substitution works on all matches unless the 'g' pattern is
+specified, then is works only on the first match."
+ :type 'boolean
+ :group 'evil)
+
+(defface evil-ex-search '((t :inherit isearch))
+ "Face for interactive search."
+ :group 'evil)
+
+(defface evil-ex-lazy-highlight '((t :inherit lazy-highlight))
+ "Face for highlighting all matches in interactive search."
+ :group 'evil)
+
+(defface evil-ex-substitute-matches '((t :inherit lazy-highlight))
+ "Face for interactive substitute matches."
+ :group 'evil)
+
+(defface evil-ex-substitute-replacement '((((supports :underline))
+ :underline t
+ :foreground "red"))
+ "Face for interactive replacement text."
+ :group 'evil)
+
+(defcustom evil-command-window-height 8
+ "Height (in lines) of the command line window.
+Set to 0 to use the default height for `split-window'."
+ :type 'integer
+ :group 'evil)
+
+(defcustom evil-display-shell-error-in-message nil
+ "Show error output of a shell command in the error buffer.
+If this variable is non-nil the error output of a shell command
+goes to the messages buffer instead of being mixed with the
+regular output. This happens only if the exit status of the
+command is non-zero."
+ :type 'boolean
+ :group 'evil)
+
+(defcustom evil-want-abbrev-expand-on-insert-exit t
+ "If non-nil abbrevs will be expanded when leaving insert state
+like in Vim, if `abbrev-mode' is on."
+ :type 'boolean
+ :group 'evil)
+
+;;; Variables
+
+(defmacro evil-define-local-var (symbol &optional initvalue docstring)
+ "Define SYMBOL as permanent buffer local variable, and return SYMBOL.
+The parameters are the same as for `defvar', but the variable
+SYMBOL is made permanent buffer local."
+ (declare (indent defun)
+ (doc-string 3)
+ (debug (symbolp &optional form stringp)))
+ `(progn
+ (defvar ,symbol ,initvalue ,docstring)
+ (make-variable-buffer-local ',symbol)
+ (put ',symbol 'permanent-local t)))
+
+(evil-define-local-var evil-scroll-count 0
+ "Holds last used prefix for `evil-scroll-up'
+and `evil-scroll-down'.
+Determines how many lines should be scrolled.
+Default value is 0 - scroll half the screen.")
+
+(evil-define-local-var evil-state nil
+ "The current Evil state.
+To change the state, use `evil-change-state'
+or call the state function (e.g., `evil-normal-state').")
+
+;; these may be used inside `evil-define-state'
+(evil-define-local-var evil-next-state nil
+ "The Evil state being switched to.")
+
+(evil-define-local-var evil-previous-state-alist nil
+ "For Each evil state the Evil state being switched from.")
+
+(evil-define-local-var evil-previous-state nil
+ "The Evil state being switched from.")
+
+(defvar evil-execute-in-emacs-state-buffer nil
+ "The buffer of the latest `evil-execute-in-emacs-state'.
+When this command is being executed the current buffer is stored
+in this variable. This is necessary in case the Emacs-command to
+be called changes the current buffer.")
+
+(evil-define-local-var evil-mode-line-tag nil
+ "Mode-Line indicator for the current state.")
+(put 'evil-mode-line-tag 'risky-local-variable t)
+
+(defvar evil-global-keymaps-alist nil
+ "Association list of keymap variables.
+Entries have the form (MODE . KEYMAP), where KEYMAP
+is the variable containing the keymap for MODE.")
+
+(defvar evil-local-keymaps-alist nil
+ "Association list of keymap variables that must be
+reinitialized in each buffer. Entries have the form
+\(MODE . KEYMAP), where KEYMAP is the variable containing
+the keymap for MODE.")
+
+(defvar evil-minor-mode-keymaps-alist nil
+ "Association list of Evil states to minor-mode keymap alists.
+Entries have the form (STATE . MODE-MAP-ALIST), where
+MODE-MAP-ALIST is an alist taking the form of
+`minor-mode-map-alist'.")
+
+(defvar evil-state-properties nil
+ "Specifications made by `evil-define-state'.
+Entries have the form (STATE . PLIST), where PLIST is a property
+list specifying various aspects of the state. To access a property,
+use `evil-state-property'.")
+
+(evil-define-local-var evil-mode-map-alist nil
+ "Association list of keymaps to use for Evil modes.
+Elements have the form (MODE . KEYMAP), with the first keymaps
+having higher priority.")
+
+(defvar evil-command-properties nil
+ "Specifications made by `evil-define-command'.")
+
+(defvar evil-change-commands '(evil-change)
+ "Commands that wrap or replace `evil-change'.
+This list exists to apply an inconsistency with vim's change command
+to commands that wrap or redefine it. See emacs-evil/evil#916.")
+
+(defvar evil-transient-vars '(cua-mode transient-mark-mode select-active-regions)
+ "List of variables pertaining to Transient Mark mode.")
+
+(defvar evil-transient-vals nil
+ "Association list of old values for Transient Mark mode variables.
+Entries have the form (VARIABLE VALUE LOCAL), where LOCAL is
+whether the variable was previously buffer-local.")
+
+(evil-define-local-var evil-no-display nil
+ "If non-nil, various Evil displays are inhibited.
+Use the macro `evil-without-display' to set this variable.")
+
+(defvar evil-type-properties nil
+ "Specifications made by `evil-define-type'.
+Entries have the form (TYPE . PLIST), where PLIST is a property
+list specifying functions for handling the type: expanding it,
+describing it, etc.")
+
+(defvar evil-interactive-alist nil
+ "Association list of Evil-specific interactive codes.")
+
+(evil-define-local-var evil-motion-marker nil
+ "Marker for storing the starting position of a motion.")
+
+(evil-define-local-var evil-this-type nil
+ "Current motion type.")
+
+(evil-define-local-var evil-this-type-modified nil
+ "Non-nil iff current motion type has been modified by the user.
+If the type has been modified, this variable contains the new
+type.")
+
+(evil-define-local-var evil-this-register nil
+ "Current register.")
+
+(defvar evil-last-=-register-input nil
+ "Most recent input from the `=' register. A string.")
+
+(defvar evil-this-macro nil
+ "Current macro register.")
+
+(evil-define-local-var evil-this-operator nil
+ "Current operator.")
+
+(evil-define-local-var evil-this-motion nil
+ "Current motion.")
+
+(evil-define-local-var evil-this-motion-count nil
+ "Current motion count.")
+
+(defvar evil-last-register nil
+ "The last executed register.")
+
+(defvar evil-inhibit-operator nil
+ "Inhibit current operator.
+If an operator calls a motion and the motion sets this variable
+to t, the operator code is not executed.")
+
+(defvar evil-inhibit-operator-value nil
+ "This variable is used to transfer the value
+of `evil-inhibit-operator' from one local scope to another.")
+
+;; used by `evil-define-operator'
+(defvar evil-operator-range-beginning nil
+ "Beginning of `evil-operator-range'.")
+
+(defvar evil-operator-range-end nil
+ "End of `evil-operator-range'.")
+
+(defvar evil-operator-range-type nil
+ "Type of `evil-operator-range'.")
+
+(defvar evil-operator-range-motion nil
+ "Motion of `evil-operator-range'.")
+
+(defvar evil-operator-start-col nil
+ "Used to restore column (where possible) after an operator has moved it.")
+
+(defvar evil-restriction-stack nil
+ "List of previous restrictions.
+Using `evil-with-restriction' stores the previous values of
+`point-min' and `point-max' as a pair in this list.")
+
+(evil-define-local-var evil-markers-alist
+ '((?\( . evil-backward-sentence-begin)
+ (?\) . evil-forward-sentence-begin)
+ (?{ . evil-backward-paragraph)
+ (?} . evil-forward-paragraph)
+ (?' . evil-jump-backward-swap)
+ (?` . evil-jump-backward-swap)
+ (?< . evil-visual-beginning)
+ (?> . evil-visual-goto-end)
+ (?. . (lambda ()
+ (let (last-command)
+ (goto-last-change nil)))))
+ "Association list for markers.
+Entries have the form (CHAR . DATA), where CHAR is the marker's
+name and DATA is either a marker object as returned by `make-marker',
+a variable, a movement function, or a cons cell (STRING NUMBER),
+where STRING is a file path and NUMBER is a buffer position.
+The global value of this variable holds markers available from
+every buffer, while the buffer-local value holds markers available
+only in the current buffer.")
+
+(defconst evil-suppress-map (make-keymap)
+ "Full keymap disabling default bindings to `self-insert-command'.")
+(suppress-keymap evil-suppress-map t)
+
+(defvar evil-read-key-map (make-sparse-keymap)
+ "Keymap active during `evil-read-key'.
+This keymap can be used to bind some commands during the
+execution of `evil-read-key' which is usually used to read a
+character argument for some commands, e.g. `evil-replace'.")
+
+;; TODO: customize size of ring
+(defvar evil-repeat-ring (make-ring 10)
+ "A ring of repeat-informations to repeat the last command.")
+
+(defvar evil-repeat-types
+ '((t . evil-repeat-keystrokes)
+ (change . evil-repeat-changes)
+ (motion . evil-repeat-motion)
+ (insert-at-point . evil-repeat-insert-at-point)
+ (ignore . nil))
+ "An alist of defined repeat-types.")
+
+(defvar evil-recording-repeat nil
+ "Whether we are recording a repeat.")
+
+(defvar evil-recording-current-command nil
+ "Whether we are recording the current command for repeat.")
+
+(defvar evil-repeat-changes nil
+ "Accumulated buffer changes for changed-based commands.")
+
+(defvar evil-repeat-info nil
+ "Information accumulated during current repeat.")
+
+(defvar evil-repeat-buffer nil
+ "The buffer in which the repeat started.
+If the buffer is changed, the repeat is cancelled.")
+
+(defvar evil-repeat-pos nil
+ "The position of point at the beginning of an change-tracking
+ editing command.")
+
+(defvar evil-repeat-keys nil
+ "The keys that invoked the current command.")
+
+(defvar evil-last-repeat nil
+ "Information about the latest repeat command.
+This is a list of three elements (POINT COUNT UNDO-POINTER),
+where POINT is the position of point before the latest repeat,
+COUNT the count-argument of the latest repeat command and
+UNDO-POINTER the head of the undo-list before the last command
+has been repeated.")
+
+(defvar evil-repeat-count nil
+ "The explicit count when repeating a command.")
+
+(defvar evil-maybe-remove-spaces nil
+ "Flag to determine if newly inserted spaces should be removed.
+See the function `evil-maybe-remove-spaces'.")
+
+(evil-define-local-var evil-insert-count nil
+ "The explicit count passed to an command starting Insert state.")
+
+(evil-define-local-var evil-insert-vcount nil
+ "The information about the number of following lines the
+insertion should be repeated. This is list (LINE COLUMN COUNT)
+where LINE is the line-number where the original insertion
+started and COLUMN is either a number or function determining the
+column where the repeated insertions should take place. COUNT is
+number of repeats (including the original insertion).")
+
+(defvar evil-insert-skip-empty-lines nil
+ "Non-nil of the current insertion should not take place on
+ lines at which the insertion point is behind the end of the
+ line.")
+
+(evil-define-local-var evil-insert-lines nil
+ "Non-nil if the current insertion command is a line-insertion
+command o or O.")
+
+(evil-define-local-var evil-insert-repeat-info nil
+ "Repeat information accumulated during an insertion.")
+
+(evil-define-local-var evil-replace-alist nil
+ "Association list of characters overwritten in Replace state.
+The format is (POS . CHAR).")
+
+(evil-define-local-var evil-echo-area-message nil
+ "Previous value of `current-message'.")
+
+(defvar evil-write-echo-area nil
+ "If set to t inside `evil-save-echo-area', then the echo area
+is not restored.")
+
+(defvar evil-last-find nil
+ "A pair (FUNCTION . CHAR) describing the lastest character
+ search command.")
+
+(defvar evil-last-paste nil
+ "Information about the latest paste.
+This should be a list (CMD COUNT POINT BEG END FIRSTVISUAL) where
+CMD is the last paste-command (`evil-paste-before',
+`evil-paste-after' or `evil-visual-paste'), COUNT is the repeat
+count of the paste, POINT is the position of point before the
+paste, BEG end END are the region of the inserted
+text. FIRSTVISUAL is t if and only if the previous command was
+the first visual paste (i.e. before any paste-pop).")
+
+(evil-define-local-var evil-last-undo-entry nil
+ "Information about the latest undo entry in the buffer.
+This should be a pair (OBJ . CONS) where OBJ is the entry as an
+object, and CONS is a copy of the entry.")
+
+(evil-define-local-var evil-current-insertion nil
+ "Information about the latest insertion in insert state.
+This should be a pair (BEG . END) that describes the
+buffer-region of the newly inserted text.")
+
+(defvar evil-last-insertion nil
+ "The last piece of inserted text.")
+
+(defvar evil-last-small-deletion nil
+ "The last piece of deleted text.
+The text should be less than a line.")
+
+(defvar evil-was-yanked-without-register t
+ "Whether text being saved to the numbered-register ring was
+not deleted and not yanked to a specific register.")
+
+(defvar evil-paste-count nil
+ "The count argument of the current paste command.")
+
+(defvar evil-temporary-undo nil
+ "When undo is disabled in current buffer.
+Certain commands depending on undo use this variable
+instead of `buffer-undo-list'.")
+
+(evil-define-local-var evil-undo-list-pointer nil
+ "Everything up to this mark is united in the undo-list.")
+
+(defvar evil-in-single-undo nil
+ "Set to non-nil if the current undo steps are connected.")
+
+(defvar evil-flash-timer nil
+ "Timer for flashing search results.")
+
+(defvar evil-search-prompt nil
+ "String to use for search prompt.")
+
+(defvar evil-search-forward-history nil
+ "History of forward searches.")
+
+(defvar evil-search-backward-history nil
+ "History of backward searches.")
+
+(defvar evil-inner-text-objects-map (make-sparse-keymap)
+ "Keymap for inner text objects.")
+
+(defvar evil-outer-text-objects-map (make-sparse-keymap)
+ "Keymap for outer text objects.")
+
+(defvar evil-window-map (make-sparse-keymap)
+ "Keymap for window-related commands.")
+
+(evil-define-local-var evil-input-method nil
+ "Input method used in Insert state and Emacs state.")
+
+;;; Visual state
+
+(evil-define-local-var evil-visual-beginning nil
+ "The beginning of the Visual selection, a marker.")
+
+(evil-define-local-var evil-visual-end nil
+ "The end of the Visual selection, a marker.")
+
+(evil-define-local-var evil-visual-point nil
+ "The position of point in Visual state, a marker.")
+
+(evil-define-local-var evil-visual-previous-point nil
+ "The position of point before Visual state, a marker.")
+
+(evil-define-local-var evil-visual-mark nil
+ "The position of mark in Visual state, a marker.")
+
+(evil-define-local-var evil-visual-previous-mark nil
+ "The position of mark before Visual state, a marker.")
+
+(evil-define-local-var evil-visual-selection nil
+ "The kind of Visual selection.
+This is a selection as defined by `evil-define-visual-selection'.")
+
+;; we could infer the direction by comparing `evil-visual-mark'
+;; and `evil-visual-point', but destructive operations may
+;; displace the markers
+(evil-define-local-var evil-visual-direction 0
+ "Whether point follows mark in Visual state.
+Negative if point precedes mark, otherwise positive.
+See also the function `evil-visual-direction'.")
+
+(evil-define-local-var evil-visual-properties nil
+ "Property list of miscellaneous Visual properties.")
+
+(evil-define-local-var evil-visual-region-expanded nil
+ "Whether the region matches the Visual selection.
+That is, whether the positions of point and mark have been
+expanded to coincide with the selection's boundaries.
+This makes the selection available to functions acting
+on Emacs' region.")
+
+(evil-define-local-var evil-visual-overlay nil
+ "Overlay for highlighting the Visual selection.
+Not used for blockwise selections, in which case
+see `evil-visual-block-overlays'.")
+
+(evil-define-local-var evil-visual-block-overlays nil
+ "Overlays for Visual Block selection, one for each line.
+They are reused to minimize flicker.")
+
+(defvar evil-visual-alist nil
+ "Association list of Visual selection functions.
+Elements have the form (NAME . FUNCTION).")
+
+(evil-define-local-var evil-visual-x-select-timer nil
+ "Timer for updating the X selection in visual state.")
+
+(defvar evil-visual-x-select-timeout 0.1
+ "Time in seconds for the update of the X selection.")
+
+(declare-function origami-open-all-nodes "ext:origami.el")
+(declare-function origami-close-all-nodes "ext:origami.el")
+(declare-function origami-toggle-node "ext:origami.el")
+(declare-function origami-open-node "ext:origami.el")
+(declare-function origami-open-node-recursively "ext:origami.el")
+(declare-function origami-close-node "ext:origami.el")
+
+(defvar evil-fold-list
+ `(((vdiff-mode)
+ :open-all vdiff-open-all-folds
+ :close-all vdiff-close-all-folds
+ :toggle ,(lambda () (call-interactively 'vdiff-toggle-fold))
+ :open ,(lambda () (call-interactively 'vdiff-open-fold))
+ :open-rec ,(lambda () (call-interactively 'vdiff-open-fold))
+ :close ,(lambda () (call-interactively 'vdiff-close-fold)))
+ ((vdiff-3way-mode)
+ :open-all vdiff-open-all-folds
+ :close-all vdiff-close-all-folds
+ :toggle ,(lambda () (call-interactively 'vdiff-toggle-fold))
+ :open ,(lambda () (call-interactively 'vdiff-open-fold))
+ :open-rec ,(lambda () (call-interactively 'vdiff-open-fold))
+ :close ,(lambda () (call-interactively 'vdiff-close-fold)))
+ ((hs-minor-mode)
+ :open-all hs-show-all
+ :close-all hs-hide-all
+ :toggle hs-toggle-hiding
+ :open hs-show-block
+ :open-rec nil
+ :close hs-hide-block)
+ ((hide-ifdef-mode)
+ :open-all show-ifdefs
+ :close-all hide-ifdefs
+ :toggle nil
+ :open show-ifdef-block
+ :open-rec nil
+ :close hide-ifdef-block)
+ ((outline-mode
+ outline-minor-mode
+ org-mode
+ markdown-mode)
+ :open-all show-all
+ :close-all ,(lambda ()
+ (with-no-warnings (hide-sublevels 1)))
+ :toggle outline-toggle-children
+ :open ,(lambda ()
+ (with-no-warnings
+ (show-entry)
+ (show-children)))
+ :open-rec show-subtree
+ :close hide-subtree)
+ ((origami-mode)
+ :open-all ,(lambda () (origami-open-all-nodes (current-buffer)))
+ :close-all ,(lambda () (origami-close-all-nodes (current-buffer)))
+ :toggle ,(lambda () (origami-toggle-node (current-buffer) (point)))
+ :open ,(lambda () (origami-open-node (current-buffer) (point)))
+ :open-rec ,(lambda () (origami-open-node-recursively (current-buffer) (point)))
+ :close ,(lambda () (origami-close-node (current-buffer) (point)))))
+ "Actions to be performed for various folding operations.
+
+The value should be a list of fold handlers, were a fold handler has
+the format:
+
+ ((MODES) PROPERTIES)
+
+MODES acts as a predicate, containing the symbols of all major or
+minor modes for which the handler should match. For example:
+
+ '((outline-minor-mode org-mode) ...)
+
+would match for either outline-minor-mode or org-mode, even though the
+former is a minor mode and the latter is a major.
+
+PROPERTIES specifies possible folding actions and the functions to be
+applied in the event of a match on one (or more) of the MODES; the
+supported properties are:
+
+ - `:open-all'
+ Open all folds.
+ - `:close-all'
+ Close all folds.
+ - `:toggle'
+ Toggle the display of the fold at point.
+ - `:open'
+ Open the fold at point.
+ - `:open-rec'
+ Open the fold at point recursively.
+ - `:close'
+ Close the fold at point.
+
+Each value must be a function. A value of `nil' will cause the action
+to be ignored for that respective handler. For example:
+
+ `((org-mode)
+ :close-all nil
+ :open ,(lambda ()
+ (show-entry)
+ (show-children))
+ :close hide-subtree)
+
+would ignore `:close-all' actions and invoke the provided functions on
+`:open' or `:close'.")
+
+;;; Ex
+
+(defvar evil-ex-map (make-sparse-keymap)
+ "Keymap for Ex.
+Key sequences bound in this map are immediately executed.")
+
+(defvar evil-ex-completion-map (make-sparse-keymap)
+ "Completion keymap for Ex.")
+
+(defvar evil-ex-initial-input nil
+ "Additional initial content of the ex command line.
+This content of this variable is appended to the ex command line
+if ex is started interactively.")
+
+(defvar evil-ex-shell-argument-initialized nil
+ "This variable is set to t if shell command completion has been initialized.
+See `evil-ex-init-shell-argument-completion'.")
+
+(defvar evil-ex-commands nil
+ "Association list of command bindings and functions.")
+
+(defvar evil-ex-history nil
+ "History of Ex commands.")
+
+(defvar evil-ex-current-buffer nil
+ "The buffer from which Ex was started.")
+
+(defvar evil-ex-expression nil
+ "The evaluation tree.")
+
+(defvar evil-ex-tree nil
+ "The syntax tree.")
+
+(defvar evil-ex-command nil
+ "The current Ex command.")
+
+(defvar evil-ex-previous-command nil
+ "The previously executed Ex command.")
+
+(defvar evil-ex-cmd nil
+ "The current Ex command string.")
+
+(defvar evil-ex-point nil
+ "The position of `point' when the ex command has been called.")
+
+(defvar evil-ex-range nil
+ "The current range of the Ex command.")
+
+(defvar evil-ex-bang nil
+ "The \"!\" argument of the current Ex command.")
+
+(defvar evil-ex-argument nil
+ "The current argument of the Ex command.")
+
+(defvar evil-ex-argument-handler nil
+ "The argument handler for the current Ex command.")
+
+(defvar evil-ex-argument-types nil
+ "Association list of argument handlers.")
+
+(defvar evil-previous-shell-command nil
+ "The last shell command.")
+
+;; Eval
+(defvar evil-eval-history nil
+ "History of eval input, from the `=' register.")
+
+(defvar evil-eval-map (make-sparse-keymap)
+ "Keymap for eval input.")
+
+;; Searching
+(defvar evil-ex-search-history nil
+ "The history for the search command.")
+
+(defvar evil-ex-search-direction nil
+ "The direction of the current search, either 'forward or 'backward.")
+
+(defvar evil-ex-search-count nil
+ "The count if the current search.")
+
+(defvar evil-ex-search-start-point nil
+ "The point where the search started.")
+
+(defvar evil-ex-search-overlay nil
+ "The overlay for the current search result.")
+
+(defvar evil-ex-search-pattern nil
+ "The last search pattern.")
+
+(defvar evil-ex-search-offset nil
+ "The last search offset.")
+
+(defvar evil-ex-search-match-beg nil
+ "The beginning position of the last match.")
+
+(defvar evil-ex-search-match-end nil
+ "The end position of the last match.")
+
+(defvar evil-ex-substitute-pattern nil
+ "The last substitute pattern.")
+
+(defvar evil-ex-substitute-replacement nil
+ "The last substitute replacement.")
+
+(defvar evil-ex-substitute-flags nil
+ "The last substitute flags.")
+
+(defvar evil-ex-substitute-current-replacement nil
+ "The actual replacement.")
+
+(defvar evil-ex-last-was-search nil
+ "Non-nil if the previous was a search.
+Otherwise the previous command is assumed as substitute.")
+
+;;; Command line window
+
+(defvar evil-command-window-current-buffer nil
+ "The buffer from which the command line window was called.")
+
+(evil-define-local-var evil-command-window-execute-fn nil
+ "The command to execute when exiting the command line window.")
+
+(evil-define-local-var evil-command-window-cmd-key nil
+ "The key for the command that opened the command line window (:, /, or ?).")
+
+;; The lazy-highlighting framework.
+(evil-define-local-var evil-ex-active-highlights-alist nil
+ "An alist of currently active highlights.")
+
+(evil-define-local-var evil-ex-hl-update-timer nil
+ "Time used for updating highlights.")
+
+(defvar evil-ex-search-keymap (make-sparse-keymap)
+ "Keymap used in ex-search-mode.")
+(define-key evil-ex-search-keymap [escape] 'abort-recursive-edit)
+(set-keymap-parent evil-ex-search-keymap minibuffer-local-map)
+
+(defcustom evil-want-empty-ex-last-command t
+ "Whether to default to evil-ex-previous-command at empty ex prompt."
+ :type 'boolean
+ :group 'evil)
+
+(defconst evil-version
+ (eval-when-compile
+ (with-temp-buffer
+ (let ((dir (file-name-directory (or load-file-name
+ byte-compile-current-file))))
+ ;; git repository
+ (if (and (file-exists-p (concat dir "/.git"))
+ (ignore-errors
+ (zerop (call-process "git" nil '(t nil) nil
+ "rev-parse"
+ "--short" "HEAD"))))
+ (progn
+ (goto-char (point-min))
+ (concat "evil-git-"
+ (buffer-substring (point-min)
+ (line-end-position))))
+ ;; no repo, use plain version
+ "1.15.0"))))
+ "The current version of Evil")
+
+(defcustom evil-want-integration t
+ "Whether to load evil-integration.el.
+This variable must be set before Evil is loaded."
+ :type 'boolean
+ :group 'evil)
+
+(defcustom evil-want-keybinding t
+ "Whether to load evil-keybindings.el.
+
+This loads a set of keybindings for evil in other modes as well as
+setting the initial evil state in those modes.
+
+This variable must be set before evil is loaded."
+ :type 'boolean
+ :group 'evil)
+
+(defcustom evil-want-minibuffer nil
+ "Whether to enable Evil in minibuffer(s)."
+ :type 'boolean
+ :group 'evil
+ :set #'(lambda (sym value)
+ (set-default sym value)
+ (if value
+ (add-hook 'minibuffer-setup-hook 'evil-initialize)
+ (remove-hook 'minibuffer-setup-hook 'evil-initialize))))
+
+(defun evil--redo-placeholder (_count)
+ (user-error "Customize `evil-undo-system' for redo functionality."))
+
+(defvar evil-undo-function 'undo
+ "Function to be used by `evil-undo'.
+Customized via `evil-undo-system'.")
+
+(defvar evil-redo-function 'evil--redo-placeholder
+ "Function to be used by 'evil-redo'.
+Customized via `evil-undo-system'.")
+
+(defun evil-set-undo-system (system)
+ "Set `evil-undo-function' and `evil-redo-function` by SYSTEM."
+ (cond
+ ((not system)
+ (setq evil-undo-function 'undo
+ evil-redo-function 'evil--redo-placeholder))
+ ((eq system 'undo-redo)
+ (setq evil-undo-function 'undo-only
+ evil-redo-function 'undo-redo))
+ ((eq system 'undo-tree)
+ (setq evil-undo-function 'undo-tree-undo
+ evil-redo-function 'undo-tree-redo))
+ ((eq system 'undo-fu)
+ (setq evil-undo-function 'undo-fu-only-undo
+ evil-redo-function 'undo-fu-only-redo))
+ (t
+ (error "Unknown undo system %s" system))))
+
+(defcustom evil-undo-system nil
+ "Undo system Evil should use. If equal to `undo-tree' or
+`undo-fu', those packages must be installed. If equal to
+`undo-tree', `undo-tree-mode' must also be activated. If equal
+to `undo-redo', Evil uses commands natively available in Emacs 28."
+ :type '(choice (const :tag "Vanilla undo" nil)
+ (const undo-redo)
+ (const undo-tree)
+ (const undo-fu))
+ :group 'evil
+ :set #'(lambda (sym value)
+ (evil-set-undo-system value)
+ (set-default sym value)))
+
+(defcustom evil-visual-update-x-selection-p t
+ "Whether to update the X PRIMARY selection with the current visual region automatically."
+ :type 'boolean
+ :group 'evil)
+
+(defun evil-version ()
+ (interactive)
+ (message "Evil version %s" evil-version))
+
+(provide 'evil-vars)
+
+;;; evil-vars.el ends here
diff --git a/elpa/evil-20220503.1314/evil-vars.elc b/elpa/evil-20220503.1314/evil-vars.elc
new file mode 100644
index 0000000..9cea0e1
--- /dev/null
+++ b/elpa/evil-20220503.1314/evil-vars.elc
Binary files differ
diff --git a/elpa/evil-20220503.1314/evil.el b/elpa/evil-20220503.1314/evil.el
new file mode 100644
index 0000000..8a8a3f3
--- /dev/null
+++ b/elpa/evil-20220503.1314/evil.el
@@ -0,0 +1,158 @@
+;;; evil.el --- extensible vi layer
+
+;; The following list of authors was kept up to date until the beginning of
+;; 2017, when evil moved under new maintainers. For authors since then, please
+;; consult the git logs.
+
+;; Alessandro Piras <laynor at gmail.com>
+;; Alexander Baier <alexander.baier at mailbox.org>
+;; Antono Vasiljev <antono.vasiljev at gmail.com>
+;; Bailey Ling <bling at live.ca>
+;; Barry O'Reilly <gundaetiapo at gmail.com>
+;; Christoph Lange <langec at web.de>
+;; Daniel Reiter <danieltreiter at gmail.com>
+;; Eivind Fonn <evfonn at gmail.com>
+;; Emanuel Evans <emanuel.evans at gmail.com>
+;; Eric Siegel <siegel.eric at gmail.com>
+;; Eugene Yaremenko <w3techplayground at gmail.com>
+;; Frank Fischer <frank-fischer at shadow-soft.de>
+;; Frank Terbeck <ft at bewatermyfriend.org>
+;; Gordon Gustafson <gordon3.14 at gmail.com>
+;; Herbert Jones <jones.herbert at gmail.com>
+;; Jonas Bernoulli <jonas at bernoul.li>
+;; Jonathan Claggett <jclaggett at lonocloud.com>
+;; José A. Romero L. <escherdragon at gmail.com>
+;; Justin Burkett <justin at burkett.cc>
+;; Lars Andersen <expez at expez.com>
+;; Lintaro Ina <tarao.gnn at gmail.com>
+;; Lukasz Wrzosek <wrzoski at mail.com>
+;; Marian Schubert <maio at netsafe.cz>
+;; Matthew Malcomson <>
+;; Michael Markert <markert.michael at googlemail.com>
+;; Mike Gerwitz <mikegerwitz at gnu.org>
+;; Nikolai Weibull <now at bitwi.se>
+;; phaebz <phaebz at gmail.com>
+;; ralesi <scio62 at gmail.com>
+;; Rodrigo Setti <rodrigosetti at gmail.com>
+;; Sanel Zukan <sanelz at gmail.com>
+;; Sarah Brofeldt <sarah at thinkmonster.(none)>
+;; Simon Hafner <hafnersimon at gmail.com>
+;; Stefan Wehr <mail at stefanwehr.de>
+;; Sune Simonsen <sune.simonsen at jayway.com>
+;; Thomas Hisch <thomas at opentech.at>
+;; Tim Harper <timcharper at gmail.com>
+;; Tom Willemse <tom at ryuslash.org>
+;; Trevor Murphy <trevor.m.murphy at gmail.com>
+;; Ulrich Müller <ulm at gentoo.org>
+;; Vasilij Schneidermann <v.schneidermann at gmail.com>
+;; Vegard Øye <vegard_oye at hotmail.com>
+;; Winfred Lu <winfred.lu at gmail.com>
+;; Wolfgang Jenkner <wjenkner at inode.at>
+;; Xiao Hanyu <xiaohanyu1988 at gmail.com>
+;; York Zhao <yzhao at telecor.com>
+
+;; The following line is included for NonGNU ELPA's build script:
+;; Maintainer: Tom Dalziel <tom.dalziel@gmail.com>
+
+;; Maintainers: The emacs-evil team. <https://github.com/orgs/emacs-evil/people>
+;; To get in touch, please use the bug tracker or the
+;; mailing list (see below).
+;; Created: 2011-03-01
+;; Version: 1.15.0
+;; Keywords: emulation, vim
+;; URL: https://github.com/emacs-evil/evil
+;; Repository: https://github.com/emacs-evil/evil.git
+;; EmacsWiki: http://www.emacswiki.org/emacs/Evil
+;; Bug tracker: https://github.com/emacs-evil/evil/issues
+;; If you have bug reports, suggestions or patches, please
+;; create an issue at the bug tracker (open for everyone).
+;; Other discussions (tips, extensions) go to the mailing list.
+;; Mailing list: <implementations-list at lists.ourproject.org>
+;; Subscribe: http://tinyurl.com/implementations-list
+;; Newsgroup: nntp://news.gmane.org/gmane.emacs.vim-emulation
+;; Archives: http://dir.gmane.org/gmane.emacs.vim-emulation
+;; You don't have to subscribe to post; we usually reply
+;; within a few days and CC our replies back to you.
+;;
+;; This file is NOT part of GNU Emacs.
+
+;;; License:
+
+;; This file is part of Evil.
+;;
+;; Evil 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.
+;;
+;; Evil 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 Evil. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Evil is an extensible vi layer for Emacs. It emulates the main
+;; features of Vim, and provides facilities for writing custom
+;; extensions.
+;;
+;; Evil lives in a Git repository. To obtain Evil, do
+;;
+;; git clone git://github.com/emacs-evil/evil.git
+;;
+;; Move Evil to ~/.emacs.d/evil (or somewhere else in the `load-path').
+;; Then add the following lines to ~/.emacs:
+;;
+;; (add-to-list 'load-path "~/.emacs.d/evil")
+;; (require 'evil)
+;; (evil-mode 1)
+;;
+;; Evil requires undo-redo (Emacs 28), undo-fu or undo-tree for redo
+;; functionality. Otherwise, Evil uses regular Emacs undo.
+;;
+;; https://gitlab.com/ideasman42/emacs-undo-fu
+;; https://melpa.org/#/undo-fu
+;; https://gitlab.com/tsc25/undo-tree
+;; https://elpa.gnu.org/packages/undo-tree.html
+;;
+;; Evil requires `goto-last-change' and `goto-last-change-reverse'
+;; function for the corresponding motions g; g, as well as the
+;; last-change-register `.'. One package providing these functions is
+;; goto-chg.el:
+;;
+;; https://github.com/emacs-evil/goto-chg
+;; https://melpa.org/#/goto-chg
+;; https://elpa.nongnu.org/nongnu/goto-chg.html
+;;
+;; Without this package the corresponding motions will raise an error.
+
+;;; Code:
+
+(require 'evil-vars)
+(require 'evil-common)
+(require 'evil-core)
+(require 'evil-states)
+(require 'evil-repeat)
+(require 'evil-macros)
+(require 'evil-search)
+(require 'evil-ex)
+(require 'evil-digraphs)
+(require 'evil-types)
+(require 'evil-commands)
+(require 'evil-jumps)
+(require 'evil-maps)
+
+(when evil-want-integration
+ (require 'evil-integration))
+
+(when evil-want-keybinding
+ (require 'evil-keybindings))
+
+(run-hooks 'evil-after-load-hook)
+
+(provide 'evil)
+
+;;; evil.el ends here
diff --git a/elpa/evil-20220503.1314/evil.elc b/elpa/evil-20220503.1314/evil.elc
new file mode 100644
index 0000000..28c49c2
--- /dev/null
+++ b/elpa/evil-20220503.1314/evil.elc
Binary files differ
diff --git a/elpa/evil-20220503.1314/evil.info b/elpa/evil-20220503.1314/evil.info
new file mode 100644
index 0000000..96e70f8
--- /dev/null
+++ b/elpa/evil-20220503.1314/evil.info
@@ -0,0 +1,2235 @@
+This is evil.info, produced by makeinfo version 6.7 from evil.texi.
+
+ Evil 1.15.0, Jan 07, 2022
+
+ Eivind Fonn, Frank Fischer, Vegard Øye
+
+ Copyright © 2011-2019, Eivind Fonn, Frank Fischer, Vegard Øye
+
+INFO-DIR-SECTION Emacs
+START-INFO-DIR-ENTRY
+* evil: (evil.info). Extensible vi layer for Emacs
+END-INFO-DIR-ENTRY
+
+
+ Generated by Sphinx 4.3.2.
+
+
+File: evil.info, Node: Top, Next: Overview, Up: (dir)
+
+Evil documentation
+******************
+
+ Evil 1.15.0, Jan 07, 2022
+
+ Eivind Fonn, Frank Fischer, Vegard Øye
+
+ Copyright © 2011-2019, Eivind Fonn, Frank Fischer, Vegard Øye
+
+* Menu:
+
+* Overview::
+* Settings::
+* Keymaps::
+* Hooks::
+* Extension::
+* Frequently Asked Questions::
+* Internals::
+* The GNU Free Documentation License::
+* Emacs lisp functions and variables::
+
+ — The Detailed Node Listing —
+
+Overview
+
+* Installation via package.el: Installation via package el.
+* Manual installation::
+* Modes and states::
+
+Settings
+
+* The initial state::
+* Keybindings and other behaviour::
+* Search::
+* Indentation::
+* Cursor movement::
+* Cursor display::
+* Window management::
+* Parenthesis highlighting::
+* Miscellaneous::
+
+Keymaps
+
+* evil-define-key::
+* Leader keys::
+
+Extension
+
+* Motions::
+* Operators::
+* Text objects::
+* Range types::
+* States::
+
+Frequently Asked Questions
+
+* Problems with the escape key in the terminal::
+* Underscore is not a word character::
+
+Internals
+
+* Command properties::
+
+
+
+File: evil.info, Node: Overview, Next: Settings, Prev: Top, Up: Top
+
+1 Overview
+**********
+
+Evil is an extensible vi layer for Emacs. It emulates the main features
+of Vim, (1) turning Emacs into a modal editor. Like Emacs in general,
+Evil is extensible in Emacs Lisp.
+
+* Menu:
+
+* Installation via package.el: Installation via package el.
+* Manual installation::
+* Modes and states::
+
+ ---------- Footnotes ----------
+
+ (1) (1) Vim is the most popular version of `vi', a modal text editor
+with many implementations. Vim also adds some functions of its own,
+like visual selection and text objects. For more information see the
+official Vim website (https://vim.org).
+
+
+File: evil.info, Node: Installation via package el, Next: Manual installation, Up: Overview
+
+1.1 Installation via package.el
+===============================
+
+Evil is available as a package from MELPA stable, MELPA unstable and
+NonGNU ELPA. This is the recommended way of installing Evil.
+
+To set up ‘package.el’ to work with one of the MELPA repositories, you
+can follow the instructions on melpa.org(1).
+
+Alternatively you can use NonGNU ELPA. It is part of the default package
+archives as of Emacs 28. For older Emacs versions you’ll need to add it
+yourself:
+
+ (add-to-list 'package-archives
+ (cons "nongnu" (format "http%s://elpa.nongnu.org/nongnu/"
+ (if (gnutls-available-p) "s" ""))))
+
+Once that is done, you can execute the following commands:
+
+ M-x package-refresh-contents
+ M-x package-install RET evil RET
+
+Finally, add the following lines to your Emacs init file:
+
+ (require 'evil)
+ (evil-mode 1)
+
+ ---------- Footnotes ----------
+
+ (1) https://melpa.org/#/getting-started
+
+
+File: evil.info, Node: Manual installation, Next: Modes and states, Prev: Installation via package el, Up: Overview
+
+1.2 Manual installation
+=======================
+
+First, install ‘goto-chg’ and ‘cl-lib’. If you have an Emacs version of
+24.3 or newer, you should already have ‘cl-lib’.
+
+Evil lives in a git repository. To download Evil, do:
+
+ git clone --depth 1 https://github.com/emacs-evil/evil.git
+
+Then add the following lines to your Emacs init file:
+
+ (add-to-list 'load-path "path/to/evil")
+ (require 'evil)
+ (evil-mode 1)
+
+Ensure that your replace ‘path/to/evil’ with the actual path to where
+you cloned Evil.
+
+
+File: evil.info, Node: Modes and states, Prev: Manual installation, Up: Overview
+
+1.3 Modes and states
+====================
+
+The next time Emacs is started, it will come up in `normal state',
+denoted by ‘<N>’ in the mode line. This is where the main vi bindings
+are defined. Note that you can always disable normal state with ‘C-z’,
+which switches to an “Emacs state” (denoted by ‘<E>’) in which vi keys
+are completely disabled. Press ‘C-z’ again to switch back to normal
+state.
+
+state
+
+ Evil uses the term `state' for what is called a “mode” in regular
+ vi usage, because `modes' are understood in Emacs terms to mean
+ something else.
+
+Evil defines a number of states by default:
+
+normal state (‘<N>’)
+
+ This is the default “resting state” of Evil, in which the main body
+ of vi bindings are defined.
+
+insert state (‘<I>’)
+
+ This is the state for insertion of text, where non-modified keys
+ will insert the corresponding character in the buffer.
+
+visual state (‘<V>’)
+
+ A state for selecting text regions. Motions are available for
+ modifying the selected region, and operators are available for
+ acting on it.
+
+replace state (‘<R>’)
+
+ A special state mostly similar to insert state, except it replaces
+ text instead of inserting.
+
+operator-pending state (‘<O>’)
+
+ A special state entered after launching an operator, but before
+ specifying the corresponding motion or text object.
+
+motion state (‘<M>’)
+
+ A special state useful for buffers that are read-only, where
+ motions are available but editing operations are not.
+
+Emacs state (‘<E>’)
+
+ A state that as closely as possible mimics default Emacs behaviour,
+ by eliminating all vi bindings, except for ‘C-z’, to re-enter
+ normal state.
+
+
+File: evil.info, Node: Settings, Next: Keymaps, Prev: Overview, Up: Top
+
+2 Settings
+**********
+
+Evil’s behaviour can be adjusted by setting some variables. The list of
+all available variables and their current values can be inspected by
+doing:
+
+ M-x customize-group RET evil RET
+
+To change the value of a variable, you can use this interface, or add a
+‘setq’ form to your Emacs init file, preferably before Evil is loaded.
+(1)
+
+ (setq evil-shift-width 0)
+ ;; Load Evil
+ (require 'evil)
+
+What follows is a non-exhaustive list of the most relevant customization
+options.
+
+* Menu:
+
+* The initial state::
+* Keybindings and other behaviour::
+* Search::
+* Indentation::
+* Cursor movement::
+* Cursor display::
+* Window management::
+* Parenthesis highlighting::
+* Miscellaneous::
+
+ ---------- Footnotes ----------
+
+ (1) (1) Strictly speaking, the order only matters if the variable
+affects the way Evil is loaded. This is the case with some variables.
+
+
+File: evil.info, Node: The initial state, Next: Keybindings and other behaviour, Up: Settings
+
+2.1 The initial state
+=====================
+
+The initial state of a buffer is determined by its major mode. Evil
+maintains an association between major modes and their corresponding
+states, which is most easily modified using the function *note
+evil-set-initial-state: 30.
+
+ -- Emacs Lisp Autofunction: (evil-set-initial-state MODE STATE)
+
+ Set the initial state for major mode `MODE' to `STATE'. This is the
+ state the buffer comes up in.
+
+If no state can be found, Evil uses the default initial state.
+
+ -- Emacs Lisp Autovariable: evil-default-state
+
+ The default Evil state. This is the state a buffer starts in when
+ it is not otherwise configured (see *note evil-set-initial-state:
+ 30. and *note evil-buffer-regexps: 5.). The value may be one of
+ ‘normal’, ‘insert’, ‘visual’, ‘replace’, ‘operator’, ‘motion’ and
+ ‘emacs’.
+
+ Default: ‘normal’
+
+Alternatively, it is possible to select the initial state based on the
+buffer `name' rather than its major mode. This is checked first, so it
+takes precedence over the other methods for setting the state.
+
+ -- Emacs Lisp Autovariable: evil-buffer-regexps
+
+ Regular expressions determining the initial state for a buffer.
+ Entries have the form ‘(REGEXP . STATE)’, where `REGEXP' is a
+ regular expression matching the buffer’s name and `STATE' is one of
+ ‘normal’, ‘insert’, ‘visual’, ‘replace’, ‘operator’, ‘motion’,
+ ‘emacs’ and ‘nil’. If `STATE' is ‘nil’, Evil is disabled in the
+ buffer.
+
+ Default: ‘(("^ \\*load\\*"))’
+
+
+File: evil.info, Node: Keybindings and other behaviour, Next: Search, Prev: The initial state, Up: Settings
+
+2.2 Keybindings and other behaviour
+===================================
+
+Evil comes with a rich system for modifying its key bindings *note
+Keymaps: 4f. For the most common tweaks, the following variables are
+available.
+
+ -- Emacs Lisp Autovariable: evil-toggle-key
+
+ The key used to change to and from Emacs state. Must be readable
+ by ‘read-kbd-macro’. For example: “C-z”.
+
+ Default: ‘"C-z"’
+
+ -- Emacs Lisp Autovariable: evil-want-C-i-jump
+
+ Whether ‘C-i’ jumps forward in the jump list (like Vim).
+ Otherwise, ‘C-i’ inserts a tab character.
+
+ Default: ‘t’
+
+ -- Emacs Lisp Autovariable: evil-want-C-u-delete
+
+ Whether ‘C-u’ deletes back to indentation in insert state.
+ Otherwise, ‘C-u’ applies a prefix argument. The binding of ‘C-u’
+ mirrors Emacs behaviour by default due to the relative ubiquity of
+ prefix arguments.
+
+ Default: ‘nil’
+
+ -- Emacs Lisp Autovariable: evil-want-C-u-scroll
+
+ Whether ‘C-u’ scrolls up (like Vim). Otherwise, ‘C-u’ applies a
+ prefix argument. The binding of ‘C-u’ mirrors Emacs behaviour by
+ default due to the relative ubiquity of prefix arguments.
+
+ Default: ‘nil’
+
+ -- Emacs Lisp Autovariable: evil-want-C-d-scroll
+
+ Whether ‘C-d’ scrolls down (like Vim).
+
+ Default: ‘t’
+
+ -- Emacs Lisp Autovariable: evil-want-C-w-delete
+
+ Whether ‘C-w’ deletes a word in Insert state.
+
+ Default: ‘t’
+
+ -- Emacs Lisp Autovariable: evil-want-C-w-in-emacs-state
+
+ Whether ‘C-w’ prefixes windows commands in Emacs state.
+
+ Default: ‘nil’
+
+ -- Emacs Lisp Autovariable: evil-want-Y-yank-to-eol
+
+ Whether ‘Y’ yanks to the end of the line. The default behavior is
+ to yank the whole line, like Vim.
+
+ Default: ‘nil’
+
+ -- Emacs Lisp Autovariable: evil-disable-insert-state-bindings
+
+ Whether insert state bindings should be used. Bindings for escape,
+ delete and *note evil-toggle-key: 37. are always available. If
+ this is non-nil, default Emacs bindings are by and large accessible
+ in insert state.
+
+ Default: ‘nil’
+
+
+File: evil.info, Node: Search, Next: Indentation, Prev: Keybindings and other behaviour, Up: Settings
+
+2.3 Search
+==========
+
+ -- Emacs Lisp Autovariable: evil-search-module
+
+ The search module to be used. May be either ‘isearch’, for Emacs’
+ isearch module, or ‘evil-search’, for Evil’s own interactive search
+ module. N.b. changing this will not affect keybindings. To swap
+ out relevant keybindings, see ‘evil-select-search-module’ function.
+
+ Default: ‘isearch’
+
+ -- Emacs Lisp Autovariable: evil-regexp-search
+
+ Whether to use regular expressions for searching in ‘/’ and ‘?’.
+
+ Default: ‘t’
+
+ -- Emacs Lisp Autovariable: evil-search-wrap
+
+ Whether search with ‘/’ and ‘?’ wraps around the buffer. If this
+ is non-nil, search stops at the buffer boundaries.
+
+ Default: ‘t’
+
+ -- Emacs Lisp Autovariable: evil-flash-delay
+
+ Time in seconds to flash search matches after ‘n’ and ‘N’.
+
+ Default: ‘2’
+
+ -- Emacs Lisp Autovariable: evil-ex-hl-update-delay
+
+ Time in seconds of idle before updating search highlighting.
+ Setting this to a period shorter than that of keyboard’s repeat
+ rate allows highlights to update while scrolling.
+
+ Default: ‘0.02’
+
+
+File: evil.info, Node: Indentation, Next: Cursor movement, Prev: Search, Up: Settings
+
+2.4 Indentation
+===============
+
+ -- Emacs Lisp Autovariable: evil-auto-indent
+
+ Whether to auto-indent when opening lines with ‘o’ and ‘O’.
+
+ Default: ‘t’, buffer-local
+
+ -- Emacs Lisp Autovariable: evil-shift-width
+
+ The number of columns by which a line is shifted. This applies to
+ the shifting operators ‘>’ and ‘<’.
+
+ Default: ‘4’, buffer-local
+
+ -- Emacs Lisp Autovariable: evil-shift-round
+
+ Whether shifting rounds to the nearest multiple. If non-nil, ‘>’
+ and ‘<’ adjust line indentation to the nearest multiple of *note
+ evil-shift-width: 33.
+
+ Default: ‘t’, buffer-local
+
+ -- Emacs Lisp Autovariable: evil-indent-convert-tabs
+
+ If non-nil, the ‘=’ operator converts between leading tabs and
+ spaces. Whether tabs are converted to spaces or vice versa depends
+ on the value of ‘indent-tabs-mode’.
+
+ Default: ‘t’
+
+
+File: evil.info, Node: Cursor movement, Next: Cursor display, Prev: Indentation, Up: Settings
+
+2.5 Cursor movement
+===================
+
+In standard Emacs terms, the cursor is generally understood to be
+located between two characters. In Vim, and therefore also Evil, this
+is the case in insert state, but in other states the cursor is
+understood to be `on' a character, and that this character is not a
+newline.
+
+Forcing this behaviour in Emacs is the source of some potentially
+surprising results (especially for traditional Emacs users—users used to
+Vim may find the default behavior to their satisfaction). Many of them
+can be tweaked using the following variables.
+
+ -- Emacs Lisp Autovariable: evil-repeat-move-cursor
+
+ Whether repeating commands with ‘.’ may move the cursor. If nil,
+ the original cursor position is preserved, even if the command
+ normally would have moved the cursor.
+
+ Default: ‘t’
+
+ -- Emacs Lisp Autovariable: evil-move-cursor-back
+
+ Whether the cursor is moved backwards when exiting insert state.
+ If non-nil, the cursor moves “backwards” when exiting insert state,
+ so that it ends up on the character to the left. Otherwise it
+ remains in place, on the character to the right.
+
+ Default: ‘t’
+
+ -- Emacs Lisp Autovariable: evil-move-beyond-eol
+
+ Whether the cursor can move past the end of the line. If non-nil,
+ the cursor is allowed to move one character past the end of the
+ line, as in Emacs.
+
+ Default: ‘nil’
+
+ -- Emacs Lisp Autovariable: evil-cross-lines
+
+ Whether horizontal motions may move to other lines. If non-nil,
+ certain motions that conventionally operate in a single line may
+ move the cursor to other lines. Otherwise, they are restricted to
+ the current line. This applies to ‘h’, ‘SPC’, ‘f’, ‘F’, ‘t’, ‘T’,
+ ‘~’.
+
+ Default: ‘nil’
+
+ -- Emacs Lisp Autovariable: evil-respect-visual-line-mode
+
+ Whether movement commands respect ‘visual-line-mode’. If non-nil,
+ ‘visual-line-mode’ is generally respected when it is on. In this
+ case, motions such as ‘j’ and ‘k’ navigate by visual lines (on the
+ screen) rather than “physical” lines (defined by newline
+ characters). If nil, the setting of ‘visual-line-mode’ is ignored.
+
+ This variable must be set before Evil is loaded.
+
+ Default: ‘nil’
+
+ -- Emacs Lisp Autovariable: evil-track-eol
+
+ Whether ‘$’ “sticks” the cursor to the end of the line. If
+ non-nil, vertical motions after ‘$’ maintain the cursor at the end
+ of the line, even if the target line is longer. This is analogous
+ to ‘track-eol’, but respects Evil’s interpretation of end-of-line.
+
+ Default: ‘t’
+
+ -- Emacs Lisp Autovariable: evil-start-of-line
+
+ Analogue of vim’s ‘startofline’. If nil, preserve column when
+ making relevant movements of the cursor. Otherwise, move the
+ cursor to the start of the line.
+
+ Default: ‘nil’
+
+
+File: evil.info, Node: Cursor display, Next: Window management, Prev: Cursor movement, Up: Settings
+
+2.6 Cursor display
+==================
+
+A state may change the appearance of the cursor. Use the variable *note
+evil-default-cursor: c. to set the default cursor, and the variables
+‘evil-normal-state-cursor’, ‘evil-insert-state-cursor’ etc. to set the
+cursors for specific states. The acceptable values for all of them are
+the same.
+
+ -- Emacs Lisp Autovariable: evil-default-cursor
+
+ The default cursor. May be a cursor type as per ‘cursor-type’, a
+ color string as passed to ‘set-cursor-color’, a zero-argument
+ function for changing the cursor, or a list of the above.
+
+ Default: ‘t’
+
+
+File: evil.info, Node: Window management, Next: Parenthesis highlighting, Prev: Cursor display, Up: Settings
+
+2.7 Window management
+=====================
+
+ -- Emacs Lisp Autovariable: evil-auto-balance-windows
+
+ If non-nil window creation and deletion trigger rebalancing.
+
+ Default: ‘t’
+
+ -- Emacs Lisp Autovariable: evil-split-window-below
+
+ If non-nil split windows are created below.
+
+ Default: ‘nil’
+
+ -- Emacs Lisp Autovariable: evil-vsplit-window-right
+
+ If non-nil vertically split windows with are created to the right.
+
+ Default: ‘nil’
+
+
+File: evil.info, Node: Parenthesis highlighting, Next: Miscellaneous, Prev: Window management, Up: Settings
+
+2.8 Parenthesis highlighting
+============================
+
+These settings concern the integration between Evil and
+‘show-paren-mode’. They take no effect if this mode is not enabled.
+
+ -- Emacs Lisp Autovariable: evil-show-paren-range
+
+ The minimal distance between point and a parenthesis which causes
+ the parenthesis to be highlighted.
+
+ Default: ‘0’
+
+ -- Emacs Lisp Autovariable:
+ evil-highlight-closing-paren-at-point-states
+
+ The states in which the closing parenthesis at point should be
+ highlighted. All states listed here highlight the closing
+ parenthesis at point (which is Vim’s default behavior). All others
+ highlight the parenthesis before point (which is Emacs default
+ behavior). If this list contains the symbol ‘not’ then its meaning
+ is inverted, i.e. all states listed here highlight the closing
+ parenthesis before point.
+
+ Default: ‘(not emacs insert replace)’
+
+
+File: evil.info, Node: Miscellaneous, Prev: Parenthesis highlighting, Up: Settings
+
+2.9 Miscellaneous
+=================
+
+ -- Emacs Lisp Autovariable: evil-want-fine-undo
+
+ Whether actions are undone in several steps. There are two
+ possible choices: nil (“no”) means that all changes made during
+ insert state, including a possible delete after a change operation,
+ are collected in a single undo step. Non-nil (“yes”) means that
+ undo steps are determined according to Emacs heuristics, and no
+ attempt is made to aggregate changes.
+
+ For backward compatibility purposes, the value ‘fine’ is
+ interpreted as ‘nil’. This option was removed because it did not
+ work consistently.
+
+ Default: ‘nil’
+
+ -- Emacs Lisp Autovariable: evil-undo-system
+
+ Undo system Evil should use. If equal to ‘undo-tree’ or ‘undo-fu’,
+ those packages must be installed. If equal to ‘undo-tree’,
+ ‘undo-tree-mode’ must also be activated. If equal to ‘undo-redo’,
+ Evil uses commands natively available in Emacs 28.
+
+ Default: ‘nil’
+
+ -- Emacs Lisp Autovariable: evil-backspace-join-lines
+
+ Whether backward delete in insert state may join lines.
+
+ Default: ‘t’
+
+ -- Emacs Lisp Autovariable: evil-kbd-macro-suppress-motion-error
+
+ Whether left/right motions signal errors in keyboard macros. This
+ variable only affects beginning-of-line or end-of-line errors
+ regarding the motions ‘h’ and ‘SPC’ respectively. This may be
+ desired since such errors cause macro definition or execution to be
+ terminated. There are four possibilities:
+
+ - ‘record’: errors are suppressed when recording macros, but not
+ when replaying them.
+
+ - ‘replay’: errors are suppressed when replaying macros, but not
+ when recording them.
+
+ - ‘t’: errors are suppressed in both cases.
+
+ - ‘nil’: errors are never suppressed.
+
+ Default: ‘nil’
+
+ -- Emacs Lisp Autovariable: evil-mode-line-format
+
+ The position of the state tag in the mode line. If set to ‘before’
+ or ‘after’, the tag is placed at the beginning or the end of the
+ mode-line, respectively. If nil, there is no tag. Otherwise it
+ should be a cons cell ‘(WHERE . WHICH)’, where `WHERE' is either
+ ‘before’ or ‘after’, and `WHICH' is a symbol in ‘mode-line-format’.
+ The tag is then placed before or after that symbol, respectively.
+
+ Default: ‘before’
+
+ -- Emacs Lisp Autovariable: evil-mouse-word
+
+ The `thing-at-point' symbol for double click selection. The
+ double-click starts visual state in a special word selection mode.
+ This symbol is used to determine the words to be selected.
+ Possible values are ‘evil-word’ or ‘evil-WORD’.
+
+ Default: ‘evil-word’
+
+ -- Emacs Lisp Autovariable: evil-bigword
+
+ The set of characters to be interpreted as WORD boundaries. This
+ is enclosed with square brackets and used as a regular expression.
+ By default, whitespace characters are considered WORD boundaries.
+
+ Default: ‘"^ \t\r\n"’, buffer-local
+
+ -- Emacs Lisp Autovariable: evil-esc-delay
+
+ The time, in seconds, to wait for another key after escape. If no
+ further event arrives during this time, the event is translated to
+ ‘ESC’. Otherwise, it is translated according to
+ ‘input-decode-map’. This does not apply in Emacs state, and may
+ also be inhibited by setting ‘evil-inhibit-esc’.
+
+ Default: ‘0.01’
+
+ -- Emacs Lisp Autovariable: evil-intercept-esc
+
+ Whether Evil should intercept the escape key. In the terminal,
+ escape and a meta key sequence both generate the same event. In
+ order to distingush these, Evil uses ‘input-decode-map’. It is not
+ necessary to do this in a graphical Emacs session. However, if you
+ prefer to use ‘C-[’ as escape (which is identical to the terminal
+ escape key code), this interception must also happen in graphical
+ Emacs sessions. Set this variable to ‘always’, t (only in the
+ terminal) or nil (never intercept).
+
+ Default: ‘always’
+
+ -- Emacs Lisp Autovariable: evil-kill-on-visual-paste
+
+ Whether pasting in visual state adds the replaced text to the kill
+ ring, making it the default for the next paste. The default,
+ replicates the default Vim behavior.
+
+ Default: ‘t’
+
+ -- Emacs Lisp Autovariable: evil-echo-state
+
+ Whether to signal the current state in the echo area.
+
+ Default: ‘t’
+
+ -- Emacs Lisp Autovariable: evil-complete-all-buffers
+
+ Whether completion looks for matches in all buffers. This applies
+ to ‘C-n’ and ‘C-p’ in insert state.
+
+ Default: ‘t’
+
+ -- Emacs Lisp Autovariable: evil-want-empty-ex-last-command
+
+ Whether to default to evil-ex-previous-command at empty ex prompt.
+
+ Default: ‘t’
+
+
+File: evil.info, Node: Keymaps, Next: Hooks, Prev: Settings, Up: Top
+
+3 Keymaps
+*********
+
+Evil’s key bindings are stored in a number of different keymaps. Each
+state has a `global keymap', where the default bindings for that state
+are stored. They are named ‘evil-normal-state-map’,
+‘evil-insert-state-map’, and so on. The bindings in these maps are
+visible in all buffers currently in the corresponding state.
+
+These keymaps function like ordinary Emacs keymaps and may be modified
+using the Emacs function ‘define-key’:
+
+ (define-key evil-normal-state-map (kbd "w") 'some-function)
+
+This binds the key ‘w’ to the command ‘some-function’ in normal state.
+The use of ‘kbd’ is optional for simple key sequences, like this one,
+but recommended in general.
+
+Most of Evil’s bindings are defined in the file ‘evil-maps.el’.
+
+To facilitate shared keybindings between states, some states may
+activate keybindings from other states as well. For example, motion
+state bindings are visible in normal and visual state, and normal state
+bindings are also visible in visual state.
+
+Each state also has a `buffer-local keymap' which is specific to the
+current buffer, and which takes precedence over the global keymap.
+These maps are most suitably modified by a mode hook. They are named
+‘evil-normal-state-local-map’, ‘evil-insert-state-local-map’, and so on.
+
+ (add-hook 'some-mode-hook
+ (lambda ()
+ (define-key evil-normal-state-local-map
+ (kbd "w") 'some-function)))
+
+For convenience, the functions *note evil-global-set-key: 1c. and *note
+evil-local-set-key: 22. are available for setting global and local state
+keys.
+
+ -- Emacs Lisp Autofunction: (evil-global-set-key STATE KEY DEF)
+
+ Bind `KEY' to `DEF' in `STATE'.
+
+ -- Emacs Lisp Autofunction: (evil-local-set-key STATE KEY DEF)
+
+ Bind `KEY' to `DEF' in `STATE' in the current buffer.
+
+The above examples could therefore have been written as follows:
+
+ (evil-global-set-key 'normal (kbd "w") 'some-function)
+
+ (add-hook 'some-mode-hook
+ (lambda ()
+ (evil-local-set-key 'normal (kbd "w") 'some-function)))
+
+* Menu:
+
+* evil-define-key::
+* Leader keys::
+
+
+File: evil.info, Node: evil-define-key, Next: Leader keys, Up: Keymaps
+
+3.1 evil-define-key
+===================
+
+Evil provides the macro *note evil-define-key: f. for adding state
+bindings to ordinary keymaps. It is quite powerful, and is the
+preferred method for fine-tuning bindings to activate in specific
+circumstances.
+
+ -- Emacs Lisp Autofunction: (evil-define-key STATE KEYMAP KEY DEF
+ [BINDINGS...])
+
+ Create a `STATE' binding from `KEY' to `DEF' for `KEYMAP'. `STATE'
+ is one of ‘normal’, ‘insert’, ‘visual’, ‘replace’, ‘operator’,
+ ‘motion’, ‘emacs’, or a list of one or more of these. Omitting a
+ state by using ‘nil’ corresponds to a standard Emacs binding using
+ ‘define-key’. The remaining arguments are like those of
+ ‘define-key’. For example:
+
+ (evil-define-key 'normal foo-map "a" 'bar)
+
+ This creates a binding from ‘a’ to ‘bar’ in normal state, which is
+ active whenever ‘foo-map’ is active. Using nil for the state, the
+ following lead to identical bindings:
+
+ (evil-define-key nil foo-map "a" 'bar)
+ (define-key foo-map "a" 'bar)
+
+ It is possible to specify multiple states and/or bindings at once:
+
+ (evil-define-key '(normal visual) foo-map
+ "a" 'bar
+ "b" 'foo)
+
+ If ‘foo-map’ has not been initialized yet, this macro adds an entry
+ to ‘after-load-functions’, delaying execution as necessary.
+
+ `KEYMAP' may also be a quoted symbol. If the symbol is ‘global’,
+ the global evil keymap corresponding to the state(s) is used,
+ meaning the following lead to identical bindings:
+
+ (evil-define-key 'normal 'global "a" 'bar)
+ (evil-global-set-key 'normal "a" 'bar)
+
+ The symbol ‘local’ may also be used, which corresponds to using
+ *note evil-local-set-key: 22. If a quoted symbol is used that is
+ not ‘global’ or ‘local’, it is assumed to be the name of a minor
+ mode, in which case ‘evil-define-minor-mode-key’ is used.
+
+There follows a brief overview of the main functions of this macro.
+
+ - Define a binding in a given state
+
+ (evil-define-key 'state 'global (kbd "key") 'target)
+
+ - Define a binding in a given state in the current buffer
+
+ (evil-define-key 'state 'local (kbd "key") 'target)
+
+ - Define a binding in a given state under the `foo-mode' major mode.
+
+ (evil-define-key 'state foo-mode-map (kbd "key") 'target)
+
+ Note that ‘foo-mode-map’ is unquoted, and that this form is safe
+ before ‘foo-mode-map’ is loaded.
+
+ - Define a binding in a given state under the `bar-mode' minor mode.
+
+ (evil-define-key 'state 'bar-mode (kbd "key") 'target)
+
+ Note that ‘bar-mode’ is quoted, and that this form is safe before
+ ‘bar-mode’ is loaded.
+
+The macro *note evil-define-key: f. can be used to augment existing
+modes with state bindings, as well as creating packages with custom
+bindings. For example, the following will create a minor mode
+‘foo-mode’ with normal state bindings for the keys ‘w’ and ‘e’:
+
+ (define-minor-mode foo-mode
+ "Foo mode."
+ :keymap (make-sparse-keymap))
+
+ (evil-define-key 'normal 'foo-mode "w" 'bar)
+ (evil-define-key 'normal 'foo-mode "e" 'baz)
+
+This minor mode can then be enabled in any buffers where the custom
+bindings are desired:
+
+ (add-hook 'text-mode-hook 'foo-mode) ; enable alongside text-mode
+
+
+File: evil.info, Node: Leader keys, Prev: evil-define-key, Up: Keymaps
+
+3.2 Leader keys
+===============
+
+Evil supports a simple implementation of Vim’s `leader' keys. To bind a
+function to a leader key you can use the expression ‘<leader>’ in a key
+mapping, e.g.
+
+ (evil-define-key 'normal 'global (kbd "<leader>fs") 'save-buffer)
+
+Likewise, you can use the expression ‘<localleader>’ to mimic Vim’s
+local leader, which is designed for mode-specific key bindings.
+
+You can use the function *note evil-set-leader: 31. to designate which
+key acts as the leader and the local leader.
+
+ -- Emacs Lisp Autofunction: (evil-set-leader STATE KEY [LOCALLEADER])
+
+ Set `KEY' to trigger leader bindings in `STATE'. `KEY' should be in
+ the form produced by ‘kbd’. `STATE' is one of ‘normal’, ‘insert’,
+ ‘visual’, ‘replace’, ‘operator’, ‘motion’, ‘emacs’, a list of one
+ or more of these, or ‘nil’, which means all of the above. If
+ `LOCALLEADER' is non-nil, set the local leader instead.
+
+
+File: evil.info, Node: Hooks, Next: Extension, Prev: Keymaps, Up: Top
+
+4 Hooks
+*******
+
+A `hook' is a list of functions that are executed when certain events
+happen. Hooks are modified with the Emacs function ‘add-hook’. Evil
+provides entry and exit hooks for all its states. For example, when
+switching from normal state to insert state, all functions in
+‘evil-normal-state-exit-hook’ and ‘evil-insert-state-entry-hook’ are
+executed.
+
+It is guaranteed that the exit hook will be executed before the entry
+hook on all state switches.
+
+During the hook execution, the variables ‘evil-next-state’ and
+‘evil-previous-state’ contain information about the states being
+switched to and from, respectively.
+
+
+File: evil.info, Node: Extension, Next: Frequently Asked Questions, Prev: Hooks, Up: Top
+
+5 Extension
+***********
+
+The main functionality of Evil is implemented in terms of reusable
+macros. Package writers can use these to define new commands.
+
+* Menu:
+
+* Motions::
+* Operators::
+* Text objects::
+* Range types::
+* States::
+
+
+File: evil.info, Node: Motions, Next: Operators, Up: Extension
+
+5.1 Motions
+===========
+
+A `motion' is a command which moves the cursor, such as ‘w’ or ‘e’.
+Motions are defined with the macro *note evil-define-motion: 10.
+Motions not defined in this way should be declared with *note
+evil-declare-motion: 9.
+
+ -- Emacs Lisp Autofunction: (evil-declare-motion COMMAND)
+
+ Declare `COMMAND' to be a movement function. This ensures that it
+ behaves correctly in visual state.
+
+ -- Emacs Lisp Autofunction: (evil-define-motion MOTION (COUNT ARGS...)
+ DOC [[KEY VALUE]...] BODY...)
+
+ Define a motion command `MOTION'. `ARGS' is a list of arguments.
+ Motions can have any number of arguments, but the first (if any)
+ has the predefined meaning of count. `BODY' must execute the
+ motion by moving point.
+
+ Optional keyword arguments are:
+
+ - ‘:type’ - determines how the motion works after an operator
+ (one of ‘inclusive’, ‘line’, ‘block’ and ‘exclusive’, or a
+ self-defined motion type)
+
+ - ‘:jump’ - if non-nil, the previous position is stored in the
+ jump list, so that it can be restored with ‘C-o’
+
+For example, this is a motion that moves the cursor forward by a number
+of characters:
+
+ (evil-define-motion foo-forward (count)
+ "Move to the right by COUNT characters."
+ :type inclusive
+ (forward-char (or count 1)))
+
+The `type' of a motion determines how it works when used together with
+an operator. Inclusive motions include the endpoint in the range being
+operated on, while exclusive motions do not. Line motions extend the
+whole range to linewise positions, effectively behaving as if the
+endpoint were really at the end of the line. Blockwise ranges behave as
+a “rectangle” on screen rather than a contiguous range of characters.
+
+
+File: evil.info, Node: Operators, Next: Text objects, Prev: Motions, Up: Extension
+
+5.2 Operators
+=============
+
+An operator is a command that acts on the text moved over by a motion,
+such as ‘c’ (change), ‘d’ (delete) or ‘y’ (yank or copy, not to be
+confused with “yank” in Emacs terminology which means `paste').
+
+ -- Emacs Lisp Autofunction: (evil-define-operator OPERATOR (BEG END
+ ARGS...) DOC [[KEY VALUE]...] BODY...)
+
+ Define an operator command `OPERATOR'. The operator acts on the
+ range of characters `BEG' through `END'. `BODY' must execute the
+ operator by potentially manipulating the buffer contents, or
+ otherwise causing side effects to happen.
+
+ Optional keyword arguments are:
+
+ - ‘:type’ - force the input range to be of a given type
+ (‘inclusive’, ‘line’, ‘block’, and ‘exclusive’, or a
+ self-defined motion type).
+
+ - ‘:motion’ - use a predetermined motion instead of waiting for
+ one from the keyboard. This does not affect the behavior in
+ visual state, where selection boundaries are always used.
+
+ - ‘:repeat’ - if non-nil (default), then ‘.’ will repeat the
+ operator.
+
+ - ‘:move-point’ - if non-nil (default), the cursor will be moved
+ to the beginning of the range before the body executes
+
+ - ‘:keep-visual’ - if non-nil, the selection is not disabled
+ when the operator is executed in visual state. By default,
+ visual state is exited automatically.
+
+For example, this is an operator that performs ROT13 encryption on the
+text under consideration:
+
+ (evil-define-operator evil-rot13 (beg end)
+ "ROT13 encrypt text."
+ (rot13-region beg end))
+
+Binding this to ‘g?’ (where it is by default) will cause a key sequence
+such as ‘g?w’ to encrypt from the current cursor to the end of the word.
+
+
+File: evil.info, Node: Text objects, Next: Range types, Prev: Operators, Up: Extension
+
+5.3 Text objects
+================
+
+Text objects are like motions in that they define a range over which an
+operator may act. Unlike motions, text objects can set both a beginning
+and an endpoint. In visual state, text objects alter both ends of the
+selection.
+
+Text objects are not directly usable in normal state. Instead, they are
+bound in the two keymaps ‘evil-inner-text-ojects-map’ and
+‘evil-outer-text-objects-map’, which are available in visual and
+operator-pending state under the keys ‘i’ and ‘a’ respectively.
+
+ -- Emacs Lisp Autofunction: (evil-define-text-object OBJECT (COUNT) DOC
+ [[KEY VALUE]...] BODY...)
+
+ Define a text object command `OBJECT'. `BODY' should return a range
+ ‘(BEG END)’ to the right of point if `COUNT' is positive, and to
+ the left of it if negative.
+
+ Optional keyword arguments:
+
+ - ‘:type’ - determines how the range applies after an operator
+ (‘inclusive’, ‘line’, ‘block’, and ‘exclusive’, or a
+ self-defined motion type).
+
+ - ‘:extend-selection’ - if non-nil (default), the text object
+ always enlarges the current selection. Otherwise, it replaces
+ the current selection.
+
+For eample, this is a text object which selects the next three
+characters after the current location:
+
+ (evil-define-text-object foo (count)
+ "Select three characters."
+ (list (point) (+ 3 (point))))
+
+For convenience, Evil provides several functions returning a list of
+positions which can be used for defining text objects. All of them
+follow the convention that a positive `count' selects text after the
+current location, while negative `count' selects text before it.
+
+ Note: The `thingatpt' library is used quite extensively in Evil to
+ define text objects, and this dependency leaks through in the
+ following functions. A `thing' in this context is any symbol for
+ which there is a function called ‘forward-THING’ (1) which moves
+ past a number of `things'.
+
+ -- Emacs Lisp Autofunction: (evil-select-inner-object THING BEG END
+ TYPE [COUNT LINE])
+
+ Return an inner text object range of `COUNT' objects. If `COUNT'
+ is positive, return objects following point; if `COUNT' is
+ negative, return objects preceding point. If one is unspecified,
+ the other is used with a negative argument. `THING' is a symbol
+ understood by `thing-at-point'. `BEG', `END' and `TYPE' specify
+ the current selection. If `LINE' is non-nil, the text object
+ should be linewise, otherwise it is character wise.
+
+ -- Emacs Lisp Autofunction: (evil-select-an-object THING BEG END TYPE
+ COUNT [LINE])
+
+ Return an outer text object range of `COUNT' objects. If `COUNT'
+ is positive, return objects following point; if `COUNT' is
+ negative, return objects preceding point. If one is unspecified,
+ the other is used with a negative argument. `THING' is a symbol
+ understood by `thing-at-point'. `BEG', `END' and `TYPE' specify
+ the current selection. If `LINE' is non-nil, the text object
+ should be linewise, otherwise it is character wise.
+
+ -- Emacs Lisp Autofunction: (evil-select-paren OPEN CLOSE BEG END TYPE
+ COUNT [INCLUSIVE])
+
+ Return a range ‘(BEG END)’ of `COUNT' delimited text objects.
+ `OPEN' and `CLOSE' specify the opening and closing delimiter,
+ respectively. `BEG' `END' `TYPE' are the currently selected
+ (visual) range. If `INCLUSIVE' is non-nil, `OPEN' and `CLOSE' are
+ included in the range; otherwise they are excluded.
+
+ The types of `OPEN' and `CLOSE' specify which kind of THING is used
+ for parsing with ‘evil-select-block’. If `OPEN' and `CLOSE' are
+ characters ‘evil-up-paren’ is used. Otherwise `OPEN' and `CLOSE'
+ must be regular expressions and ‘evil-up-block’ is used.
+
+ If the selection is exclusive, whitespace at the end or at the
+ beginning of the selection until the end-of-line or
+ beginning-of-line is ignored.
+
+ ---------- Footnotes ----------
+
+ (1) (1) There are many more ways that a `thing' can be defined, but
+the definition of ‘forward-THING’ is perhaps the most straightforward
+way to go about it.
+
+
+File: evil.info, Node: Range types, Next: States, Prev: Text objects, Up: Extension
+
+5.4 Range types
+===============
+
+A `type' is a transformation acting on a pair of buffer positions. Evil
+defines the types ‘inclusive’, ‘line’, ‘block’ and ‘exclusive’, which
+are used for motion ranges and visual selection. New types may be
+defined with the macro `evil-define-type'.
+
+ -- Emacs Lisp Autofunction: (evil-define-type TYPE DOC [[KEY FUNC]...])
+
+ Define type `TYPE'. `DOC' is a general description and shows up in
+ all docstrings.
+
+ Optional keyword arguments:
+
+ - ‘:expand’ - expansion function. This function should accept
+ two positions in the current buffer, BEG and END,and return a
+ pair of expanded buffer positions.
+
+ - ‘:contract’ - the opposite of ‘:expand’. Optional.
+
+ - ‘:one-to-one’ - non-nil if expansion is one-to-one. This
+ means that ‘:expand’ followed by ‘:contract’ always return the
+ original range.
+
+ - ‘:normalize’ - normalization function. This function should
+ accept two unexpanded positions and adjust them before
+ expansion. May be used to deal with buffer boundaries.
+
+ - ‘:string’ - description function. Takes two buffer positions
+ and returns a human-readable string. For example “2 lines”
+
+ If further keywords and functions are specified, they are assumed
+ to be transformations on buffer positions, like ‘:expand’ and
+ ‘:contract’.
+
+
+File: evil.info, Node: States, Prev: Range types, Up: Extension
+
+5.5 States
+==========
+
+States are defined with the macro *note evil-define-state: 12, which
+takes care to define the necessary hooks, keymaps and variables, as well
+as a toggle function ‘evil-NAME-state’ and a predicate function
+‘evil-NAME-state-p’ for checking whether the state is active.
+
+ -- Emacs Lisp Autofunction: (evil-define-state STATE DOC [[KEY VAL]...]
+ BODY...)
+
+ Define an Evil state `STATE'. `DOC' is a general description and
+ shows up in all docstrings; the first line of the string should be
+ the full name of the state.
+
+ `BODY' is executed each time the state is enabled or disabled.
+
+ Optional keyword arguments:
+
+ - ‘:tag’ - the mode line indicator, e.g. “<T>”.
+
+ - ‘:message’ - string shown in the echo area when the state is
+ activated.
+
+ - ‘:cursor’ - default cursor specification.
+
+ - ‘:enable’ - list of other state keymaps to enable when in this
+ state.
+
+ - ‘:entry-hook’ - list of functions to run when entering this
+ state.
+
+ - ‘:exit-hook’ - list of functions to run when exiting this
+ state.
+
+ - ‘:suppress-keymap’ - if non-nil, effectively disables bindings
+ to ‘self-insert-command’ by making ‘evil-suppress-map’ the
+ parent of the global state keymap.
+
+ The global keymap of this state will be ‘evil-test-state-map’, the
+ local keymap will be ‘evil-test-state-local-map’, and so on.
+
+For example:
+
+ (evil-define-state test
+ "Test state."
+ :tag " <T> "
+ (message (if (evil-test-state-p)
+ "Enabling test state."
+ "Disabling test state.")))
+
+
+File: evil.info, Node: Frequently Asked Questions, Next: Internals, Prev: Extension, Up: Top
+
+6 Frequently Asked Questions
+****************************
+
+* Menu:
+
+* Problems with the escape key in the terminal::
+* Underscore is not a word character::
+
+
+File: evil.info, Node: Problems with the escape key in the terminal, Next: Underscore is not a word character, Up: Frequently Asked Questions
+
+6.1 Problems with the escape key in the terminal
+================================================
+
+A common problem when using Evil in terminal mode is a certain delay
+after pressing the escape key. Even more, when pressing the escape key
+followed quickly by another key the command is recognized as ‘M-<key>’
+instead of two separate keys: ‘ESC’ followed by ‘<key>’. In fact, it is
+perfectly valid to simulate ‘M-<key>’ by pressing ‘ESC <key>’ quickly
+(but see below).
+
+The reason for this is that in terminal mode a key sequence involving
+the meta key (or alt key) always generates a so called “escape
+sequence”, i.e. a sequence of two events sent to Emacs, the first being
+‘ESC’ and the second the key pressed simultaneously. The problem is
+that pressing the escape key itself also generates the ‘ESC’ event.
+Thus, if Emacs (and therefore Evil) receives an ‘ESC’ event there is no
+way to tell whether the escape key has been pressed (and no further
+event will arrive) or a ‘M-<key>’ combination has been pressed (and the
+‘<key>’ event will arrive soon). In order to distinguish both
+situations Evil does the following. After receiving an ‘ESC’ event Evil
+waits for a short time period (specified by the variable *note
+evil-esc-delay: 17. which defaults to 0.01 seconds) for another event.
+If no other event arrives Evil assumes that the plain escape key has
+been pressed, otherwise it assumes a ‘M-<key>’ combination has been
+pressed and combines the ‘ESC’ event with the second one. Because a
+‘M-<key>’ sequence usually generates both events in very quick
+succession, 0.01 seconds are usually enough and the delay is hardly
+noticeable by the user.
+
+If you use a terminal multiplexer like `tmux' or `screen' the situation
+may be worse. These multiplexers have exactly the same problem
+recognizing ‘M-<key>’ sequences and often introduce their own delay for
+the ‘ESC’ key. There is no way for Evil to influence this delay. In
+order to reduce it you must reconfigure your terminal multiplexer.
+
+Note that this problem should not arise when using Evil in graphical
+mode. The reason is that in this case the escape key itself generates a
+different command, namely ‘escape’ (a symbol) and hence Evil can
+distinguish whether the escape key or a ‘M-<key>’ combination has been
+pressed. But this also implies that pressing ‘ESC’ followed by <key>
+cannot be used to simulate ‘M-<key>’ in graphical mode!
+
+
+File: evil.info, Node: Underscore is not a word character, Prev: Problems with the escape key in the terminal, Up: Frequently Asked Questions
+
+6.2 Underscore is not a word character
+======================================
+
+An underscore ‘_’ is a word character in Vim. This means that word
+motions like ‘w’ skip over underlines in a sequence of letters as if it
+was a letter itself. In contrast, in Evil the underscore is often a
+non-word character like operators, e.g. ‘+’.
+
+The reason is that Evil uses Emacs’ definition of a word and this
+definition does often not include the underscore. In Emacs word
+characters are determined by the syntax-class of the buffer. The
+syntax-class usually depends on the major-mode of this buffer. This has
+the advantage that the definition of a “word” may be adapted to the
+particular type of document being edited. Evil uses Emacs’ definition
+and does not simply use Vim’s definition in order to be consistent with
+other Emacs functions. For example, word characters are exactly those
+characters that are matched by the regular expression character class
+‘[:word:]’.
+
+If you would be satisfied by having the ‘*’ and ‘#’ searches use symbols
+instead of words, this can be achieved by setting the
+‘evil-symbol-word-search’ variable to ‘t’.
+
+If you want the underscore to be recognised as word character for other
+motions, you can modify its entry in the syntax-table:
+
+ (modify-syntax-entry ?_ "w")
+
+This gives the underscore the ‘word’ syntax class. You can use a
+mode-hook to modify the syntax-table in all buffers of some mode, e.g.:
+
+ (add-hook 'c-mode-common-hook
+ (lambda () (modify-syntax-entry ?_ "w")))
+
+This gives the underscore the word syntax-class in all C-like buffers.
+
+Similarly to Emacs’ definition of a word, the definition of a “symbol”
+is also dependent on the syntax-class of the buffer, which often
+includes the underscore. The default text objects keymap associates
+kbd::‘o’ with the symbol object, making kbd::‘cio’ a good alternative to
+Vim’s kbd::‘ciw’, for example. The following will swap between the word
+and symbol objects in the keymap:
+
+ (define-key evil-outer-text-objects-map "w" 'evil-a-symbol)
+ (define-key evil-inner-text-objects-map "w" 'evil-inner-symbol)
+ (define-key evil-outer-text-objects-map "o" 'evil-a-word)
+ (define-key evil-inner-text-objects-map "o" 'evil-inner-word)
+
+This will not change the motion keys, however. One way to make word
+motions operate as symbol motions is to alias the ‘evil-word’ `thing'
+(1) to the ‘evil-symbol’ thing:
+
+ (defalias 'forward-evil-word 'forward-evil-symbol)
+
+ ---------- Footnotes ----------
+
+ (1) (1) Many of Evil’s text objects and motions are defined in terms
+of the `thingatpt' library, which in this case are defined entirely in
+terms of ‘forward-THING’ functions. Thus aliasing one to another should
+make all motions and text objects implemented in terms of that `thing'
+behave the same.
+
+
+File: evil.info, Node: Internals, Next: The GNU Free Documentation License, Prev: Frequently Asked Questions, Up: Top
+
+7 Internals
+***********
+
+* Menu:
+
+* Command properties::
+
+
+File: evil.info, Node: Command properties, Up: Internals
+
+7.1 Command properties
+======================
+
+Evil defines `command properties' to store information about commands
+(1), such as whether they should be repeated. A command property is a
+‘:keyword’ with an associated value, e.g. ‘:repeat nil’.
+
+ -- Emacs Lisp Autofunction: (evil-add-command-properties COMMAND
+ [PROPERTIES...])
+
+ Add `PROPERTIES' to `COMMAND'. `PROPERTIES' should be a property
+ list. To replace all properties at once, use *note
+ evil-set-command-properties: 2f.
+
+ -- Emacs Lisp Autofunction: (evil-set-command-properties COMMAND
+ [PROPERTIES...])
+
+ Replace all of `COMMAND'’s properties with `PROPERTIES'.
+ `PROPERTIES' should be a property list. This erases all previous
+ properties; to only add properties, use
+ ‘evil-set-command-property’.
+
+ -- Emacs Lisp Autofunction: (evil-get-command-properties COMMAND)
+
+ Return all Evil properties of `COMMAND'. See also *note
+ evil-get-command-property: 1b.
+
+ -- Emacs Lisp Autofunction: (evil-get-command-property COMMAND PROPERTY
+ [DEFAULT])
+
+ Return the value of Evil `PROPERTY' of `COMMAND'. If the command
+ does not have the property, return `DEFAULT'. See also *note
+ evil-get-command-properties: 1a.
+
+ -- Emacs Lisp Autofunction: (evil-define-command COMMAND (ARGS...) DOC
+ [[KEY VALUE]...] BODY...)
+
+ Define a command `COMMAND'.
+
+For setting repeat properties, use the following functions:
+
+ -- Emacs Lisp Autofunction: (evil-declare-repeat COMMAND)
+
+ Declare `COMMAND' to be repeatable.
+
+ -- Emacs Lisp Autofunction: (evil-declare-not-repeat COMMAND)
+
+ Declare `COMMAND' to be nonrepeatable.
+
+ -- Emacs Lisp Autofunction: (evil-declare-change-repeat COMMAND)
+
+ Declare `COMMAND' to be repeatable by buffer changes rather than
+ keystrokes.
+
+ ---------- Footnotes ----------
+
+ (1) (1) In this context, a `command' may mean any Evil motion, text
+object, operator or indeed other Emacs commands, which have not been
+defined through the Evil machinery.
+
+
+File: evil.info, Node: The GNU Free Documentation License, Next: Emacs lisp functions and variables, Prev: Internals, Up: Top
+
+8 The GNU Free Documentation License
+************************************
+
+Version 1.3, 3 November 2008
+
+ Copyright (c) 2000, 2001, 2002, 2007, 2008 Free Software
+ Foundation, Inc. ‘http://fsf.org/’
+
+ Everyone is permitted to copy and distribute verbatim copies of
+ this license document, but changing it is not allowed.
+
+ 0. PREAMBLE
+
+ The purpose of this License is to make a manual, textbook, or other
+ functional and useful document `free' in the sense of freedom: to
+ assure everyone the effective freedom to copy and redistribute it,
+ with or without modifying it, either commercially or
+ noncommercially. Secondarily, this License preserves for the
+ author and publisher a way to get credit for their work, while not
+ being considered responsible for modifications made by others.
+
+ This License is a kind of “copyleft”, which means that derivative
+ works of the document must themselves be free in the same sense.
+ It complements the GNU General Public License, which is a copyleft
+ license designed for free software.
+
+ We have designed this License in order to use it for manuals for
+ free software, because free software needs free documentation: a
+ free program should come with manuals providing the same freedoms
+ that the software does. But this License is not limited to
+ software manuals; it can be used for any textual work, regardless
+ of subject matter or whether it is published as a printed book. We
+ recommend this License principally for works whose purpose is
+ instruction or reference.
+
+ 1. APPLICABILITY AND DEFINITIONS
+
+ This License applies to any manual or other work, in any medium,
+ that contains a notice placed by the copyright holder saying it can
+ be distributed under the terms of this License. Such a notice
+ grants a world-wide, royalty-free license, unlimited in duration,
+ to use that work under the conditions stated herein. The
+ “Document”, below, refers to any such manual or work. Any member
+ of the public is a licensee, and is addressed as “you”. You accept
+ the license if you copy, modify or distribute the work in a way
+ requiring permission under copyright law.
+
+ A “Modified Version” of the Document means any work containing the
+ Document or a portion of it, either copied verbatim, or with
+ modifications and/or translated into another language.
+
+ A “Secondary Section” is a named appendix or a front-matter section
+ of the Document that deals exclusively with the relationship of the
+ publishers or authors of the Document to the Document’s overall
+ subject (or to related matters) and contains nothing that could
+ fall directly within that overall subject. (Thus, if the Document
+ is in part a textbook of mathematics, a Secondary Section may not
+ explain any mathematics.) The relationship could be a matter of
+ historical connection with the subject or with related matters, or
+ of legal, commercial, philosophical, ethical or political position
+ regarding them.
+
+ The “Invariant Sections” are certain Secondary Sections whose
+ titles are designated, as being those of Invariant Sections, in the
+ notice that says that the Document is released under this License.
+ If a section does not fit the above definition of Secondary then it
+ is not allowed to be designated as Invariant. The Document may
+ contain zero Invariant Sections. If the Document does not identify
+ any Invariant Sections then there are none.
+
+ The “Cover Texts” are certain short passages of text that are
+ listed, as Front-Cover Texts or Back-Cover Texts, in the notice
+ that says that the Document is released under this License. A
+ Front-Cover Text may be at most 5 words, and a Back-Cover Text may
+ be at most 25 words.
+
+ A “Transparent” copy of the Document means a machine-readable copy,
+ represented in a format whose specification is available to the
+ general public, that is suitable for revising the document
+ straightforwardly with generic text editors or (for images composed
+ of pixels) generic paint programs or (for drawings) some widely
+ available drawing editor, and that is suitable for input to text
+ formatters or for automatic translation to a variety of formats
+ suitable for input to text formatters. A copy made in an otherwise
+ Transparent file format whose markup, or absence of markup, has
+ been arranged to thwart or discourage subsequent modification by
+ readers is not Transparent. An image format is not Transparent if
+ used for any substantial amount of text. A copy that is not
+ “Transparent” is called “Opaque”.
+
+ Examples of suitable formats for Transparent copies include plain
+ ASCII without markup, Texinfo input format, LaTeX input format,
+ SGML or XML using a publicly available DTD, and standard-conforming
+ simple HTML, PostScript or PDF designed for human modification.
+ Examples of transparent image formats include PNG, XCF and JPG.
+ Opaque formats include proprietary formats that can be read and
+ edited only by proprietary word processors, SGML or XML for which
+ the DTD and/or processing tools are not generally available, and
+ the machine-generated HTML, PostScript or PDF produced by some word
+ processors for output purposes only.
+
+ The “Title Page” means, for a printed book, the title page itself,
+ plus such following pages as are needed to hold, legibly, the
+ material this License requires to appear in the title page. For
+ works in formats which do not have any title page as such, “Title
+ Page” means the text near the most prominent appearance of the
+ work’s title, preceding the beginning of the body of the text.
+
+ The “publisher” means any person or entity that distributes copies
+ of the Document to the public.
+
+ A section “Entitled XYZ” means a named subunit of the Document
+ whose title either is precisely XYZ or contains XYZ in parentheses
+ following text that translates XYZ in another language. (Here XYZ
+ stands for a specific section name mentioned below, such as
+ “Acknowledgements”, “Dedications”, “Endorsements”, or “History”.)
+ To “Preserve the Title” of such a section when you modify the
+ Document means that it remains a section “Entitled XYZ” according
+ to this definition.
+
+ The Document may include Warranty Disclaimers next to the notice
+ which states that this License applies to the Document. These
+ Warranty Disclaimers are considered to be included by reference in
+ this License, but only as regards disclaiming warranties: any other
+ implication that these Warranty Disclaimers may have is void and
+ has no effect on the meaning of this License.
+
+ 2. VERBATIM COPYING
+
+ You may copy and distribute the Document in any medium, either
+ commercially or noncommercially, provided that this License, the
+ copyright notices, and the license notice saying this License
+ applies to the Document are reproduced in all copies, and that you
+ add no other conditions whatsoever to those of this License. You
+ may not use technical measures to obstruct or control the reading
+ or further copying of the copies you make or distribute. However,
+ you may accept compensation in exchange for copies. If you
+ distribute a large enough number of copies you must also follow the
+ conditions in section 3.
+
+ You may also lend copies, under the same conditions stated above,
+ and you may publicly display copies.
+
+ 3. COPYING IN QUANTITY
+
+ If you publish printed copies (or copies in media that commonly
+ have printed covers) of the Document, numbering more than 100, and
+ the Document’s license notice requires Cover Texts, you must
+ enclose the copies in covers that carry, clearly and legibly, all
+ these Cover Texts: Front-Cover Texts on the front cover, and
+ Back-Cover Texts on the back cover. Both covers must also clearly
+ and legibly identify you as the publisher of these copies. The
+ front cover must present the full title with all words of the title
+ equally prominent and visible. You may add other material on the
+ covers in addition. Copying with changes limited to the covers, as
+ long as they preserve the title of the Document and satisfy these
+ conditions, can be treated as verbatim copying in other respects.
+
+ If the required texts for either cover are too voluminous to fit
+ legibly, you should put the first ones listed (as many as fit
+ reasonably) on the actual cover, and continue the rest onto
+ adjacent pages.
+
+ If you publish or distribute Opaque copies of the Document
+ numbering more than 100, you must either include a machine-readable
+ Transparent copy along with each Opaque copy, or state in or with
+ each Opaque copy a computer-network location from which the general
+ network-using public has access to download using public-standard
+ network protocols a complete Transparent copy of the Document, free
+ of added material. If you use the latter option, you must take
+ reasonably prudent steps, when you begin distribution of Opaque
+ copies in quantity, to ensure that this Transparent copy will
+ remain thus accessible at the stated location until at least one
+ year after the last time you distribute an Opaque copy (directly or
+ through your agents or retailers) of that edition to the public.
+
+ It is requested, but not required, that you contact the authors of
+ the Document well before redistributing any large number of copies,
+ to give them a chance to provide you with an updated version of the
+ Document.
+
+ 4. MODIFICATIONS
+
+ You may copy and distribute a Modified Version of the Document
+ under the conditions of sections 2 and 3 above, provided that you
+ release the Modified Version under precisely this License, with the
+ Modified Version filling the role of the Document, thus licensing
+ distribution and modification of the Modified Version to whoever
+ possesses a copy of it. In addition, you must do these things in
+ the Modified Version:
+
+ A. Use in the Title Page (and on the covers, if any) a title
+ distinct from that of the Document, and from those of previous
+ versions (which should, if there were any, be listed in the
+ History section of the Document). You may use the same title
+ as a previous version if the original publisher of that
+ version gives permission.
+
+ B. List on the Title Page, as authors, one or more persons or
+ entities responsible for authorship of the modifications in
+ the Modified Version, together with at least five of the
+ principal authors of the Document (all of its principal
+ authors, if it has fewer than five), unless they release you
+ from this requirement.
+
+ C. State on the Title page the name of the publisher of the
+ Modified Version, as the publisher.
+
+ D. Preserve all the copyright notices of the Document.
+
+ E. Add an appropriate copyright notice for your modifications
+ adjacent to the other copyright notices.
+
+ F. Include, immediately after the copyright notices, a license
+ notice giving the public permission to use the Modified
+ Version under the terms of this License, in the form shown in
+ the Addendum below.
+
+ G. Preserve in that license notice the full lists of Invariant
+ Sections and required Cover Texts given in the Document’s
+ license notice.
+
+ H. Include an unaltered copy of this License.
+
+ I. Preserve the section Entitled “History”, Preserve its Title,
+ and add to it an item stating at least the title, year, new
+ authors, and publisher of the Modified Version as given on the
+ Title Page. If there is no section Entitled “History” in the
+ Document, create one stating the title, year, authors, and
+ publisher of the Document as given on its Title Page, then add
+ an item describing the Modified Version as stated in the
+ previous sentence.
+
+ J. Preserve the network location, if any, given in the Document
+ for public access to a Transparent copy of the Document, and
+ likewise the network locations given in the Document for
+ previous versions it was based on. These may be placed in the
+ “History” section. You may omit a network location for a work
+ that was published at least four years before the Document
+ itself, or if the original publisher of the version it refers
+ to gives permission.
+
+ K. For any section Entitled “Acknowledgements” or “Dedications”,
+ Preserve the Title of the section, and preserve in the section
+ all the substance and tone of each of the contributor
+ acknowledgements and/or dedications given therein.
+
+ L. Preserve all the Invariant Sections of the Document, unaltered
+ in their text and in their titles. Section numbers or the
+ equivalent are not considered part of the section titles.
+
+ M. Delete any section Entitled “Endorsements”. Such a section
+ may not be included in the Modified Version.
+
+ N. Do not retitle any existing section to be Entitled
+ “Endorsements” or to conflict in title with any Invariant
+ Section.
+
+ O. Preserve any Warranty Disclaimers.
+
+ If the Modified Version includes new front-matter sections or
+ appendices that qualify as Secondary Sections and contain no
+ material copied from the Document, you may at your option designate
+ some or all of these sections as invariant. To do this, add their
+ titles to the list of Invariant Sections in the Modified Version’s
+ license notice. These titles must be distinct from any other
+ section titles.
+
+ You may add a section Entitled “Endorsements”, provided it contains
+ nothing but endorsements of your Modified Version by various
+ parties—for example, statements of peer review or that the text has
+ been approved by an organization as the authoritative definition of
+ a standard.
+
+ You may add a passage of up to five words as a Front-Cover Text,
+ and a passage of up to 25 words as a Back-Cover Text, to the end of
+ the list of Cover Texts in the Modified Version. Only one passage
+ of Front-Cover Text and one of Back-Cover Text may be added by (or
+ through arrangements made by) any one entity. If the Document
+ already includes a cover text for the same cover, previously added
+ by you or by arrangement made by the same entity you are acting on
+ behalf of, you may not add another; but you may replace the old
+ one, on explicit permission from the previous publisher that added
+ the old one.
+
+ The author(s) and publisher(s) of the Document do not by this
+ License give permission to use their names for publicity for or to
+ assert or imply endorsement of any Modified Version.
+
+ 5. COMBINING DOCUMENTS
+
+ You may combine the Document with other documents released under
+ this License, under the terms defined in section 4 above for
+ modified versions, provided that you include in the combination all
+ of the Invariant Sections of all of the original documents,
+ unmodified, and list them all as Invariant Sections of your
+ combined work in its license notice, and that you preserve all
+ their Warranty Disclaimers.
+
+ The combined work need only contain one copy of this License, and
+ multiple identical Invariant Sections may be replaced with a single
+ copy. If there are multiple Invariant Sections with the same name
+ but different contents, make the title of each such section unique
+ by adding at the end of it, in parentheses, the name of the
+ original author or publisher of that section if known, or else a
+ unique number. Make the same adjustment to the section titles in
+ the list of Invariant Sections in the license notice of the
+ combined work.
+
+ In the combination, you must combine any sections Entitled
+ “History” in the various original documents, forming one section
+ Entitled “History”; likewise combine any sections Entitled
+ “Acknowledgements”, and any sections Entitled “Dedications”. You
+ must delete all sections Entitled “Endorsements.”
+
+ 6. COLLECTIONS OF DOCUMENTS
+
+ You may make a collection consisting of the Document and other
+ documents released under this License, and replace the individual
+ copies of this License in the various documents with a single copy
+ that is included in the collection, provided that you follow the
+ rules of this License for verbatim copying of each of the documents
+ in all other respects.
+
+ You may extract a single document from such a collection, and
+ distribute it individually under this License, provided you insert
+ a copy of this License into the extracted document, and follow this
+ License in all other respects regarding verbatim copying of that
+ document.
+
+ 7. AGGREGATION WITH INDEPENDENT WORKS
+
+ A compilation of the Document or its derivatives with other
+ separate and independent documents or works, in or on a volume of a
+ storage or distribution medium, is called an “aggregate” if the
+ copyright resulting from the compilation is not used to limit the
+ legal rights of the compilation’s users beyond what the individual
+ works permit. When the Document is included in an aggregate, this
+ License does not apply to the other works in the aggregate which
+ are not themselves derivative works of the Document.
+
+ If the Cover Text requirement of section 3 is applicable to these
+ copies of the Document, then if the Document is less than one half
+ of the entire aggregate, the Document’s Cover Texts may be placed
+ on covers that bracket the Document within the aggregate, or the
+ electronic equivalent of covers if the Document is in electronic
+ form. Otherwise they must appear on printed covers that bracket
+ the whole aggregate.
+
+ 8. TRANSLATION
+
+ Translation is considered a kind of modification, so you may
+ distribute translations of the Document under the terms of section
+ 4. Replacing Invariant Sections with translations requires special
+ permission from their copyright holders, but you may include
+ translations of some or all Invariant Sections in addition to the
+ original versions of these Invariant Sections. You may include a
+ translation of this License, and all the license notices in the
+ Document, and any Warranty Disclaimers, provided that you also
+ include the original English version of this License and the
+ original versions of those notices and disclaimers. In case of a
+ disagreement between the translation and the original version of
+ this License or a notice or disclaimer, the original version will
+ prevail.
+
+ If a section in the Document is Entitled “Acknowledgements”,
+ “Dedications”, or “History”, the requirement (section 4) to
+ Preserve its Title (section 1) will typically require changing the
+ actual title.
+
+ 9. TERMINATION
+
+ You may not copy, modify, sublicense, or distribute the Document
+ except as expressly provided under this License. Any attempt
+ otherwise to copy, modify, sublicense, or distribute it is void,
+ and will automatically terminate your rights under this License.
+
+ However, if you cease all violation of this License, then your
+ license from a particular copyright holder is reinstated (a)
+ provisionally, unless and until the copyright holder explicitly and
+ finally terminates your license, and (b) permanently, if the
+ copyright holder fails to notify you of the violation by some
+ reasonable means prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+ reinstated permanently if the copyright holder notifies you of the
+ violation by some reasonable means, this is the first time you have
+ received notice of violation of this License (for any work) from
+ that copyright holder, and you cure the violation prior to 30 days
+ after your receipt of the notice.
+
+ Termination of your rights under this section does not terminate
+ the licenses of parties who have received copies or rights from you
+ under this License. If your rights have been terminated and not
+ permanently reinstated, receipt of a copy of some or all of the
+ same material does not give you any rights to use it.
+
+ 10. FUTURE REVISIONS OF THIS LICENSE
+
+ The Free Software Foundation may publish new, revised versions of
+ the GNU Free Documentation License from time to time. Such new
+ versions will be similar in spirit to the present version, but may
+ differ in detail to address new problems or concerns. See
+ ‘http://www.gnu.org/copyleft’.
+
+ Each version of the License is given a distinguishing version
+ number. If the Document specifies that a particular numbered
+ version of this License “or any later version” applies to it, you
+ have the option of following the terms and conditions either of
+ that specified version or of any later version that has been
+ published (not as a draft) by the Free Software Foundation. If the
+ Document does not specify a version number of this License, you may
+ choose any version ever published (not as a draft) by the Free
+ Software Foundation. If the Document specifies that a proxy can
+ decide which future versions of this License can be used, that
+ proxy’s public statement of acceptance of a version permanently
+ authorizes you to choose that version for the Document.
+
+ 11. RELICENSING
+
+ “Massive Multiauthor Collaboration Site” (or “MMC Site”) means any
+ World Wide Web server that publishes copyrightable works and also
+ provides prominent facilities for anybody to edit those works. A
+ public wiki that anybody can edit is an example of such a server.
+ A “Massive Multiauthor Collaboration” (or “MMC”) contained in the
+ site means any set of copyrightable works thus published on the MMC
+ site.
+
+ “CC-BY-SA” means the Creative Commons Attribution-Share Alike 3.0
+ license published by Creative Commons Corporation, a not-for-profit
+ corporation with a principal place of business in San Francisco,
+ California, as well as future copyleft versions of that license
+ published by that same organization.
+
+ “Incorporate” means to publish or republish a Document, in whole or
+ in part, as part of another Document.
+
+ An MMC is “eligible for relicensing” if it is licensed under this
+ License, and if all works that were first published under this
+ License somewhere other than this MMC, and subsequently
+ incorporated in whole or in part into the MMC, (1) had no cover
+ texts or invariant sections, and (2) were thus incorporated prior
+ to November 1, 2008.
+
+ The operator of an MMC Site may republish an MMC contained in the
+ site under CC-BY-SA on the same site at any time before August 1,
+ 2009, provided the MMC is eligible for relicensing.
+
+
+File: evil.info, Node: Emacs lisp functions and variables, Prev: The GNU Free Documentation License, Up: Top
+
+Emacs lisp functions and variables
+**********************************
+
+* Menu:
+
+* evil-add-command-properties: 0.
+* evil-auto-balance-windows: 1.
+* evil-auto-indent: 2.
+* evil-backspace-join-lines: 3.
+* evil-bigword: 4.
+* evil-buffer-regexps: 5.
+* evil-complete-all-buffers: 6.
+* evil-cross-lines: 7.
+* evil-declare-change-repeat: 8.
+* evil-declare-motion: 9.
+* evil-declare-not-repeat: a.
+* evil-declare-repeat: b.
+* evil-default-cursor: c.
+* evil-default-state: d.
+* evil-define-command: e.
+* evil-define-key: f.
+* evil-define-motion: 10.
+* evil-define-operator: 11.
+* evil-define-state: 12.
+* evil-define-text-object: 13.
+* evil-define-type: 14.
+* evil-disable-insert-state-bindings: 15.
+* evil-echo-state: 16.
+* evil-esc-delay: 17.
+* evil-ex-hl-update-delay: 18.
+* evil-flash-delay: 19.
+* evil-get-command-properties: 1a.
+* evil-get-command-property: 1b.
+* evil-global-set-key: 1c.
+* evil-highlight-closing-paren-at-point-states: 1d.
+* evil-indent-convert-tabs: 1e.
+* evil-intercept-esc: 1f.
+* evil-kbd-macro-suppress-motion-error: 20.
+* evil-kill-on-visual-paste: 21.
+* evil-local-set-key: 22.
+* evil-mode-line-format: 23.
+* evil-mouse-word: 24.
+* evil-move-beyond-eol: 25.
+* evil-move-cursor-back: 26.
+* evil-regexp-search: 27.
+* evil-repeat-move-cursor: 28.
+* evil-respect-visual-line-mode: 29.
+* evil-search-module: 2a.
+* evil-search-wrap: 2b.
+* evil-select-an-object: 2c.
+* evil-select-inner-object: 2d.
+* evil-select-paren: 2e.
+* evil-set-command-properties: 2f.
+* evil-set-initial-state: 30.
+* evil-set-leader: 31.
+* evil-shift-round: 32.
+* evil-shift-width: 33.
+* evil-show-paren-range: 34.
+* evil-split-window-below: 35.
+* evil-start-of-line: 36.
+* evil-toggle-key: 37.
+* evil-track-eol: 38.
+* evil-undo-system: 39.
+* evil-vsplit-window-right: 3a.
+* evil-want-C-d-scroll: 3b.
+* evil-want-C-i-jump: 3c.
+* evil-want-C-u-delete: 3d.
+* evil-want-C-u-scroll: 3e.
+* evil-want-C-w-delete: 3f.
+* evil-want-C-w-in-emacs-state: 40.
+* evil-want-empty-ex-last-command: 41.
+* evil-want-fine-undo: 42.
+* evil-want-Y-yank-to-eol: 43.
+
+
+
+Tag Table:
+Node: Top364
+Ref: index doc611
+Ref: 44611
+Node: Overview1443
+Ref: overview doc1518
+Ref: 451518
+Ref: overview evil1518
+Ref: 461518
+Ref: overview overview1518
+Ref: 471518
+Ref: Overview-Footnote-11871
+Node: Installation via package el2123
+Ref: overview installation-via-package-el2221
+Ref: 482221
+Ref: Installation via package el-Footnote-13156
+Node: Manual installation3200
+Ref: overview manual-installation3323
+Ref: 493323
+Node: Modes and states3861
+Ref: overview modes-and-states3948
+Ref: 4a3948
+Node: Settings5699
+Ref: settings doc5778
+Ref: 4b5778
+Ref: settings settings5778
+Ref: 4c5778
+Ref: Settings-Footnote-16537
+Node: The initial state6678
+Ref: settings the-initial-state6778
+Ref: 4d6778
+Ref: settings elispobj-evil-set-initial-state7053
+Ref: 307053
+Ref: settings elispobj-evil-default-state7292
+Ref: d7292
+Ref: settings elispobj-evil-buffer-regexps7903
+Ref: 57903
+Node: Keybindings and other behaviour8396
+Ref: settings keybindings-and-other-behaviour8511
+Ref: 4e8511
+Ref: settings elispobj-evil-toggle-key8733
+Ref: 378733
+Ref: settings elispobj-evil-want-C-i-jump8933
+Ref: 3c8933
+Ref: settings elispobj-evil-want-C-u-delete9123
+Ref: 3d9123
+Ref: settings elispobj-evil-want-C-u-scroll9442
+Ref: 3e9442
+Ref: settings elispobj-evil-want-C-d-scroll9735
+Ref: 3b9735
+Ref: settings elispobj-evil-want-C-w-delete9858
+Ref: 3f9858
+Ref: settings elispobj-evil-want-C-w-in-emacs-state9988
+Ref: 409988
+Ref: settings elispobj-evil-want-Y-yank-to-eol10138
+Ref: 4310138
+Ref: settings elispobj-evil-disable-insert-state-bindings10333
+Ref: 1510333
+Node: Search10661
+Ref: settings search10770
+Ref: 5010770
+Ref: settings elispobj-evil-search-module10793
+Ref: 2a10793
+Ref: settings elispobj-evil-regexp-search11178
+Ref: 2711178
+Ref: settings elispobj-evil-search-wrap11329
+Ref: 2b11329
+Ref: settings elispobj-evil-flash-delay11535
+Ref: 1911535
+Ref: settings elispobj-evil-ex-hl-update-delay11678
+Ref: 1811678
+Node: Indentation11951
+Ref: settings indentation12044
+Ref: 5112044
+Ref: settings elispobj-evil-auto-indent12077
+Ref: 212077
+Ref: settings elispobj-evil-shift-width12235
+Ref: 3312235
+Ref: settings elispobj-evil-shift-round12441
+Ref: 3212441
+Ref: settings elispobj-evil-indent-convert-tabs12702
+Ref: 1e12702
+Node: Cursor movement12971
+Ref: settings cursor-movement13072
+Ref: 5213072
+Ref: settings elispobj-evil-repeat-move-cursor13651
+Ref: 2813651
+Ref: settings elispobj-evil-move-cursor-back13915
+Ref: 2613915
+Ref: settings elispobj-evil-move-beyond-eol14260
+Ref: 2514260
+Ref: settings elispobj-evil-cross-lines14502
+Ref: 714502
+Ref: settings elispobj-evil-respect-visual-line-mode14897
+Ref: 2914897
+Ref: settings elispobj-evil-track-eol15412
+Ref: 3815412
+Ref: settings elispobj-evil-start-of-line15780
+Ref: 3615780
+Node: Cursor display16034
+Ref: settings cursor-display16141
+Ref: 5316141
+Ref: settings elispobj-evil-default-cursor16485
+Ref: c16485
+Node: Window management16768
+Ref: settings window-management16884
+Ref: 5416884
+Ref: settings elispobj-evil-auto-balance-windows16929
+Ref: 116929
+Ref: settings elispobj-evil-split-window-below17075
+Ref: 3517075
+Ref: settings elispobj-evil-vsplit-window-right17204
+Ref: 3a17204
+Node: Parenthesis highlighting17357
+Ref: settings parenthesis-highlighting17472
+Ref: 5517472
+Ref: settings elispobj-evil-show-paren-range17661
+Ref: 3417661
+Ref: settings elispobj-evil-highlight-closing-paren-at-point-states17848
+Ref: 1d17848
+Node: Miscellaneous18434
+Ref: settings miscellaneous18523
+Ref: 5618523
+Ref: settings elispobj-evil-want-fine-undo18560
+Ref: 4218560
+Ref: settings elispobj-evil-undo-system19199
+Ref: 3919199
+Ref: settings elispobj-evil-backspace-join-lines19558
+Ref: 319558
+Ref: settings elispobj-evil-kbd-macro-suppress-motion-error19699
+Ref: 2019699
+Ref: settings elispobj-evil-mode-line-format20454
+Ref: 2320454
+Ref: settings elispobj-evil-mouse-word20986
+Ref: 2420986
+Ref: settings elispobj-evil-bigword21327
+Ref: 421327
+Ref: settings elispobj-evil-esc-delay21631
+Ref: 1721631
+Ref: settings elispobj-evil-intercept-esc22037
+Ref: 1f22037
+Ref: settings elispobj-evil-kill-on-visual-paste22663
+Ref: 2122663
+Ref: settings elispobj-evil-echo-state22924
+Ref: 1622924
+Ref: settings elispobj-evil-complete-all-buffers23053
+Ref: 623053
+Ref: settings elispobj-evil-want-empty-ex-last-command23254
+Ref: 4123254
+Node: Keymaps23412
+Ref: keymaps doc23488
+Ref: 5723488
+Ref: keymaps chapter-keymaps23488
+Ref: 4f23488
+Ref: keymaps keymaps23488
+Ref: 5823488
+Ref: keymaps elispobj-evil-global-set-key25140
+Ref: 1c25140
+Ref: keymaps elispobj-evil-local-set-key25244
+Ref: 2225244
+Node: evil-define-key25673
+Ref: keymaps evil-define-key25750
+Ref: 5925750
+Ref: keymaps elispobj-evil-define-key26004
+Ref: f26004
+Node: Leader keys29201
+Ref: keymaps leader-keys29278
+Ref: 5a29278
+Ref: keymaps elispobj-evil-set-leader29805
+Ref: 3129805
+Node: Hooks30258
+Ref: hooks doc30335
+Ref: 5b30335
+Ref: hooks hooks30335
+Ref: 5c30335
+Node: Extension30987
+Ref: extension doc31083
+Ref: 5d31083
+Ref: extension extension31083
+Ref: 5e31083
+Node: Motions31319
+Ref: extension motions31388
+Ref: 5f31388
+Ref: extension elispobj-evil-declare-motion31641
+Ref: 931641
+Ref: extension elispobj-evil-define-motion31814
+Ref: 1031814
+Node: Operators33205
+Ref: extension operators33295
+Ref: 6033295
+Ref: extension elispobj-evil-define-operator33543
+Ref: 1133543
+Node: Text objects35148
+Ref: extension text-objects35242
+Ref: 6135242
+Ref: extension elispobj-evil-define-text-object35782
+Ref: 1335782
+Ref: extension elispobj-evil-select-inner-object37286
+Ref: 2d37286
+Ref: extension elispobj-evil-select-an-object37856
+Ref: 2c37856
+Ref: extension elispobj-evil-select-paren38423
+Ref: 2e38423
+Ref: Text objects-Footnote-139345
+Node: Range types39511
+Ref: extension range-types39602
+Ref: 6239602
+Ref: extension elispobj-evil-define-type39905
+Ref: 1439905
+Node: States41074
+Ref: extension states41144
+Ref: 6341144
+Ref: extension elispobj-evil-define-state41444
+Ref: 1241444
+Node: Frequently Asked Questions42873
+Ref: faq doc42973
+Ref: 6442973
+Ref: faq frequently-asked-questions42973
+Ref: 6542973
+Node: Problems with the escape key in the terminal43130
+Ref: faq problems-with-the-escape-key-in-the-terminal43278
+Ref: 6643278
+Node: Underscore is not a word character45772
+Ref: faq underscore-is-not-a-word-character45920
+Ref: 6745920
+Ref: Underscore is not a word character-Footnote-148518
+Node: Internals48829
+Ref: internals doc48954
+Ref: 6848954
+Ref: internals internals48954
+Ref: 6948954
+Node: Command properties49012
+Ref: internals command-properties49074
+Ref: 6a49074
+Ref: internals elispobj-evil-add-command-properties49329
+Ref: 049329
+Ref: internals elispobj-evil-set-command-properties49589
+Ref: 2f49589
+Ref: internals elispobj-evil-get-command-properties49902
+Ref: 1a49902
+Ref: internals elispobj-evil-get-command-property50068
+Ref: 1b50068
+Ref: internals elispobj-evil-define-command50338
+Ref: e50338
+Ref: internals elispobj-evil-declare-repeat50542
+Ref: b50542
+Ref: internals elispobj-evil-declare-not-repeat50644
+Ref: a50644
+Ref: internals elispobj-evil-declare-change-repeat50753
+Ref: 850753
+Ref: Command properties-Footnote-150944
+Node: The GNU Free Documentation License51121
+Ref: license doc51254
+Ref: 6b51254
+Ref: license the-gnu-free-documentation-license51254
+Ref: 6c51254
+Node: Emacs lisp functions and variables75062
+
+End Tag Table
+
+
+Local Variables:
+coding: utf-8
+End:
diff --git a/elpa/f-20220405.1534/f-autoloads.el b/elpa/f-20220405.1534/f-autoloads.el
new file mode 100644
index 0000000..2f24ece
--- /dev/null
+++ b/elpa/f-20220405.1534/f-autoloads.el
@@ -0,0 +1,22 @@
+;;; f-autoloads.el --- automatically extracted autoloads -*- lexical-binding: t -*-
+;;
+;;; Code:
+
+(add-to-list 'load-path (directory-file-name
+ (or (file-name-directory #$) (car load-path))))
+
+
+;;;### (autoloads nil "f" "f.el" (0 0 0 0))
+;;; Generated autoloads from f.el
+
+(register-definition-prefixes "f" '("f-"))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; coding: utf-8
+;; End:
+;;; f-autoloads.el ends here
diff --git a/elpa/f-20220405.1534/f-pkg.el b/elpa/f-20220405.1534/f-pkg.el
new file mode 100644
index 0000000..bf8fdc1
--- /dev/null
+++ b/elpa/f-20220405.1534/f-pkg.el
@@ -0,0 +1,2 @@
+;;; Generated package description from f.el -*- no-byte-compile: t -*-
+(define-package "f" "20220405.1534" "Modern API for working with files and directories" '((s "1.7.0") (dash "2.2.0")) :commit "b5cb884b3b4372a6f3d1d4428cf092ca1e5c8044" :authors '(("Johan Andersson" . "johan.rejeep@gmail.com")) :maintainer '("Johan Andersson" . "johan.rejeep@gmail.com") :keywords '("files" "directories") :url "http://github.com/rejeep/f.el")
diff --git a/elpa/f-20220405.1534/f.el b/elpa/f-20220405.1534/f.el
new file mode 100644
index 0000000..5f18971
--- /dev/null
+++ b/elpa/f-20220405.1534/f.el
@@ -0,0 +1,599 @@
+;;; f.el --- Modern API for working with files and directories -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2013 Johan Andersson
+
+;; Author: Johan Andersson <johan.rejeep@gmail.com>
+;; Maintainer: Johan Andersson <johan.rejeep@gmail.com>
+;; Version: 0.20.0
+;; Package-Version: 20220405.1534
+;; Package-Commit: b5cb884b3b4372a6f3d1d4428cf092ca1e5c8044
+;; Keywords: files, directories
+;; URL: http://github.com/rejeep/f.el
+;; Package-Requires: ((s "1.7.0") (dash "2.2.0"))
+
+;; This file is NOT part of GNU Emacs.
+
+;;; License:
+
+;; 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 GNU Emacs; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Code:
+
+
+
+(require 's)
+(require 'dash)
+
+(put 'f-guard-error 'error-conditions '(error f-guard-error))
+(put 'f-guard-error 'error-message "Destructive operation outside sandbox")
+
+(defvar f--guard-paths nil
+ "List of allowed paths to modify when guarded.
+
+Do not modify this variable.")
+
+(defmacro f--destructive (path &rest body)
+ "If PATH is allowed to be modified, yield BODY.
+
+If PATH is not allowed to be modified, throw error."
+ (declare (indent 1))
+ `(if f--guard-paths
+ (if (--any? (or (f-same? it ,path)
+ (f-ancestor-of? it ,path)) f--guard-paths)
+ (progn ,@body)
+ (signal 'f-guard-error (list ,path f--guard-paths)))
+ ,@body))
+
+
+;;;; Paths
+
+(defun f-join (&rest args)
+ "Join ARGS to a single path."
+ (let (path (relative (f-relative? (car args))))
+ (-map
+ (lambda (arg)
+ (setq path (f-expand arg path)))
+ args)
+ (if relative (f-relative path) path)))
+
+(defun f-split (path)
+ "Split PATH and return list containing parts."
+ (let ((parts (s-split (f-path-separator) path 'omit-nulls)))
+ (if (f-absolute? path)
+ (push (f-path-separator) parts)
+ parts)))
+
+(defun f-expand (path &optional dir)
+ "Expand PATH relative to DIR (or `default-directory').
+PATH and DIR can be either a directory names or directory file
+names. Return a directory name if PATH is a directory name, and
+a directory file name otherwise. File name handlers are
+ignored."
+ (let (file-name-handler-alist)
+ (expand-file-name path dir)))
+
+(defun f-filename (path)
+ "Return the name of PATH."
+ (file-name-nondirectory (directory-file-name path)))
+
+(defalias 'f-parent 'f-dirname)
+(defun f-dirname (path)
+ "Return the parent directory to PATH."
+ (let ((parent (file-name-directory
+ (directory-file-name (f-expand path default-directory)))))
+ (unless (f-same? path parent)
+ (if (f-relative? path)
+ (f-relative parent)
+ (directory-file-name parent)))))
+
+(defun f-common-parent (paths)
+ "Return the deepest common parent directory of PATHS."
+ (cond
+ ((not paths) nil)
+ ((not (cdr paths)) (f-parent (car paths)))
+ (:otherwise
+ (let* ((paths (-map 'f-split paths))
+ (common (caar paths))
+ (re nil))
+ (while (and (not (null (car paths))) (--all? (equal (car it) common) paths))
+ (setq paths (-map 'cdr paths))
+ (push common re)
+ (setq common (caar paths)))
+ (cond
+ ((null re) "")
+ ((and (= (length re) 1) (f-root? (car re)))
+ (f-root))
+ (:otherwise
+ (concat (apply 'f-join (nreverse re)) "/")))))))
+
+(defalias 'f-ext 'file-name-extension)
+
+(defalias 'f-no-ext 'file-name-sans-extension)
+
+(defun f-swap-ext (path ext)
+ "Return PATH but with EXT as the new extension.
+EXT must not be nil or empty."
+ (if (s-blank? ext)
+ (error "Extension cannot be empty or nil")
+ (concat (f-no-ext path) "." ext)))
+
+(defun f-base (path)
+ "Return the name of PATH, excluding the extension of file."
+ (f-no-ext (f-filename path)))
+
+(defalias 'f-relative 'file-relative-name)
+
+(defalias 'f-short 'abbreviate-file-name)
+(defalias 'f-abbrev 'abbreviate-file-name)
+
+(defun f-long (path)
+ "Return long version of PATH."
+ (f-expand path))
+
+(defalias 'f-canonical 'file-truename)
+
+(defun f-slash (path)
+ "Append slash to PATH unless one already.
+
+Some functions, such as `call-process' requires there to be an
+ending slash."
+ (if (f-dir? path)
+ (file-name-as-directory path)
+ path))
+
+(defun f-full (path)
+ "Return absolute path to PATH, with ending slash."
+ (f-slash (f-long path)))
+
+(defun f--uniquify (paths)
+ "Helper for `f-uniquify' and `f-uniquify-alist'."
+ (let* ((files-length (length paths))
+ (uniq-filenames (--map (cons it (f-filename it)) paths))
+ (uniq-filenames-next (-group-by 'cdr uniq-filenames)))
+ (while (/= files-length (length uniq-filenames-next))
+ (setq uniq-filenames-next
+ (-group-by 'cdr
+ (--mapcat
+ (let ((conf-files (cdr it)))
+ (if (> (length conf-files) 1)
+ (--map (cons
+ (car it)
+ (concat
+ (f-filename (s-chop-suffix (cdr it)
+ (car it)))
+ (f-path-separator) (cdr it)))
+ conf-files)
+ conf-files))
+ uniq-filenames-next))))
+ uniq-filenames-next))
+
+(defun f-uniquify (files)
+ "Return unique suffixes of FILES.
+
+This function expects no duplicate paths."
+ (-map 'car (f--uniquify files)))
+
+(defun f-uniquify-alist (files)
+ "Return alist mapping FILES to unique suffixes of FILES.
+
+This function expects no duplicate paths."
+ (-map 'cadr (f--uniquify files)))
+
+
+;;;; I/O
+
+(defun f-read-bytes (path &optional beg end)
+ "Read binary data from PATH.
+
+Return the binary data as unibyte string. The optional second and
+third arguments BEG and END specify what portion of the file to
+read."
+ (with-temp-buffer
+ (set-buffer-multibyte nil)
+ (setq buffer-file-coding-system 'binary)
+ (insert-file-contents-literally path nil beg end)
+ (buffer-substring-no-properties (point-min) (point-max))))
+
+(defalias 'f-read 'f-read-text)
+(defun f-read-text (path &optional coding)
+ "Read text with PATH, using CODING.
+
+CODING defaults to `utf-8'.
+
+Return the decoded text as multibyte string."
+ (decode-coding-string (f-read-bytes path) (or coding 'utf-8)))
+
+(defalias 'f-write 'f-write-text)
+(defun f-write-text (text coding path)
+ "Write TEXT with CODING to PATH.
+
+TEXT is a multibyte string. CODING is a coding system to encode
+TEXT with. PATH is a file name to write to."
+ (f-write-bytes (encode-coding-string text coding) path))
+
+(defun f-unibyte-string-p (s)
+ "Determine whether S is a unibyte string."
+ (not (multibyte-string-p s)))
+
+(defun f-write-bytes (data path)
+ "Write binary DATA to PATH.
+
+DATA is a unibyte string. PATH is a file name to write to."
+ (f--write-bytes data path nil))
+
+(defalias 'f-append 'f-append-text)
+(defun f-append-text (text coding path)
+ "Append TEXT with CODING to PATH.
+
+If PATH does not exist, it is created."
+ (f-append-bytes (encode-coding-string text coding) path))
+
+(defun f-append-bytes (data path)
+ "Append binary DATA to PATH.
+
+If PATH does not exist, it is created."
+ (f--write-bytes data path :append))
+
+(defun f--write-bytes (data filename append)
+ "Write binary DATA to FILENAME.
+If APPEND is non-nil, append the DATA to the existing contents."
+ (f--destructive filename
+ (unless (f-unibyte-string-p data)
+ (signal 'wrong-type-argument (list 'f-unibyte-string-p data)))
+ (let ((coding-system-for-write 'binary)
+ (write-region-annotate-functions nil)
+ (write-region-post-annotation-function nil))
+ (write-region data nil filename append :silent)
+ nil)))
+
+
+;;;; Destructive
+
+(defun f-mkdir (&rest dirs)
+ "Create directories DIRS."
+ (let (path)
+ (-each
+ dirs
+ (lambda (dir)
+ (setq path (f-expand dir path))
+ (unless (f-directory? path)
+ (f--destructive path (make-directory path)))))))
+
+(defun f-delete (path &optional force)
+ "Delete PATH, which can be file or directory.
+
+If FORCE is t, a directory will be deleted recursively."
+ (f--destructive path
+ (if (or (f-file? path) (f-symlink? path))
+ (delete-file path)
+ (delete-directory path force))))
+
+(defun f-symlink (source path)
+ "Create a symlink to SOURCE from PATH."
+ (f--destructive path (make-symbolic-link source path)))
+
+(defun f-move (from to)
+ "Move or rename FROM to TO.
+If TO is a directory name, move FROM into TO."
+ (f--destructive to (rename-file from to t)))
+
+(defun f-copy (from to)
+ "Copy file or directory FROM to TO.
+If FROM names a directory and TO is a directory name, copy FROM
+into TO as a subdirectory."
+ (f--destructive to
+ (if (f-file? from)
+ (copy-file from to)
+ ;; The behavior of `copy-directory' differs between Emacs 23 and
+ ;; 24 in that in Emacs 23, the contents of `from' is copied to
+ ;; `to', while in Emacs 24 the directory `from' is copied to
+ ;; `to'. We want the Emacs 24 behavior.
+ (if (> emacs-major-version 23)
+ (copy-directory from to)
+ (if (f-dir? to)
+ (progn
+ (apply 'f-mkdir (f-split to))
+ (let ((new-to (f-expand (f-filename from) to)))
+ (copy-directory from new-to)))
+ (copy-directory from to))))))
+
+(defun f-copy-contents (from to)
+ "Copy contents in directory FROM, to directory TO."
+ (unless (f-exists? to)
+ (error "Cannot copy contents to non existing directory %s" to))
+ (unless (f-dir? from)
+ (error "Cannot copy contents as %s is a file" from))
+ (--each (f-entries from)
+ (f-copy it (file-name-as-directory to))))
+
+(defun f-touch (path)
+ "Update PATH last modification date or create if it does not exist."
+ (f--destructive path
+ (if (f-file? path)
+ (set-file-times path)
+ (f-write-bytes "" path))))
+
+
+;;;; Predicates
+
+(defalias 'f-exists? 'file-exists-p)
+(defalias 'f-exists-p 'file-exists-p)
+
+(defalias 'f-directory? 'file-directory-p)
+(defalias 'f-directory-p 'file-directory-p)
+(defalias 'f-dir? 'file-directory-p)
+(defalias 'f-dir-p 'file-directory-p)
+
+
+(defalias 'f-file? 'file-regular-p)
+(defalias 'f-file-p 'file-regular-p)
+
+(defun f-symlink? (path)
+ "Return t if PATH is symlink, false otherwise."
+ (not (not (file-symlink-p path))))
+
+(defalias 'f-symlink-p 'f-symlink?)
+
+(defalias 'f-readable? 'file-readable-p)
+(defalias 'f-readable-p 'file-readable-p)
+
+(defalias 'f-writable? 'file-writable-p)
+(defalias 'f-writable-p 'file-writable-p)
+
+(defalias 'f-executable? 'file-executable-p)
+(defalias 'f-executable-p 'f-executable?)
+
+(defalias 'f-absolute? 'file-name-absolute-p)
+(defalias 'f-absolute-p 'file-name-absolute-p)
+
+(defun f-relative? (path)
+ "Return t if PATH is relative, false otherwise."
+ (not (f-absolute? path)))
+
+(defalias 'f-relative-p 'f-relative?)
+
+(defun f-root? (path)
+ "Return t if PATH is root directory, false otherwise."
+ (not (f-parent path)))
+
+(defalias 'f-root-p 'f-root?)
+
+(defun f-ext? (path &optional ext)
+ "Return t if extension of PATH is EXT, false otherwise.
+
+If EXT is nil or omitted, return t if PATH has any extension,
+false otherwise.
+
+The extension, in a file name, is the part that follows the last
+'.', excluding version numbers and backup suffixes."
+ (if ext
+ (string= (f-ext path) ext)
+ (not (eq (f-ext path) nil))))
+
+(defalias 'f-ext-p 'f-ext?)
+
+(defalias 'f-equal? 'f-same?)
+(defalias 'f-equal-p 'f-equal?)
+
+(defun f-same? (path-a path-b)
+ "Return t if PATH-A and PATH-B are references to same file."
+ (when (and (f-exists? path-a)
+ (f-exists? path-b))
+ (equal
+ (f-canonical (directory-file-name (f-expand path-a)))
+ (f-canonical (directory-file-name (f-expand path-b))))))
+
+(defalias 'f-same-p 'f-same?)
+
+(defun f-parent-of? (path-a path-b)
+ "Return t if PATH-A is parent of PATH-B."
+ (--when-let (f-parent path-b)
+ (f-same? path-a it)))
+
+(defalias 'f-parent-of-p 'f-parent-of?)
+
+(defun f-child-of? (path-a path-b)
+ "Return t if PATH-A is child of PATH-B."
+ (--when-let (f-parent path-a)
+ (f-same? it path-b)))
+
+(defalias 'f-child-of-p 'f-child-of?)
+
+(defun f-ancestor-of? (path-a path-b)
+ "Return t if PATH-A is ancestor of PATH-B."
+ (unless (f-same? path-a path-b)
+ (s-starts-with? (f-full path-a)
+ (f-full path-b))))
+
+(defalias 'f-ancestor-of-p 'f-ancestor-of?)
+
+(defun f-descendant-of? (path-a path-b)
+ "Return t if PATH-A is desendant of PATH-B."
+ (unless (f-same? path-a path-b)
+ (s-starts-with? (f-full path-b)
+ (f-full path-a))))
+
+(defalias 'f-descendant-of-p 'f-descendant-of?)
+
+(defun f-hidden? (path)
+ "Return t if PATH is hidden, nil otherwise."
+ (unless (f-exists? path)
+ (error "Path does not exist: %s" path))
+ (string= (substring path 0 1) "."))
+
+(defalias 'f-hidden-p 'f-hidden?)
+
+(defun f-empty? (path)
+ "If PATH is a file, return t if the file in PATH is empty, nil otherwise.
+If PATH is directory, return t if directory has no files, nil otherwise."
+ (if (f-directory? path)
+ (equal (f-files path nil t) nil)
+ (= (f-size path) 0)))
+
+(defalias 'f-empty-p 'f-empty?)
+
+
+;;;; Stats
+
+(defun f-size (path)
+ "Return size of PATH.
+
+If PATH is a file, return size of that file. If PATH is
+directory, return sum of all files in PATH."
+ (if (f-directory? path)
+ (-sum (-map 'f-size (f-files path nil t)))
+ (nth 7 (file-attributes path))))
+
+(defun f-depth (path)
+ "Return the depth of PATH.
+
+At first, PATH is expanded with `f-expand'. Then the full path is used to
+detect the depth.
+'/' will be zero depth, '/usr' will be one depth. And so on."
+ (- (length (f-split (f-expand path))) 1))
+
+
+;;;; Misc
+
+(defun f-this-file ()
+ "Return path to this file."
+ (cond
+ (load-in-progress load-file-name)
+ ((and (boundp 'byte-compile-current-file) byte-compile-current-file)
+ byte-compile-current-file)
+ (:else (buffer-file-name))))
+
+(defvar f--path-separator nil
+ "A variable to cache result of `f-path-separator'.")
+
+(defun f-path-separator ()
+ "Return path separator."
+ (or f--path-separator
+ (setq f--path-separator (substring (f-join "x" "y") 1 2))))
+
+(defun f-glob (pattern &optional path)
+ "Find PATTERN in PATH."
+ (file-expand-wildcards
+ (f-join (or path default-directory) pattern)))
+
+(defun f--collect-entries (path recursive)
+ (let (result
+ (entries
+ (-reject
+ (lambda (file)
+ (or
+ (equal (f-filename file) ".")
+ (equal (f-filename file) "..")))
+ (directory-files path t))))
+ (cond (recursive
+ (-map
+ (lambda (entry)
+ (if (f-file? entry)
+ (setq result (cons entry result))
+ (when (f-directory? entry)
+ (setq result (cons entry result))
+ (setq result (append result (f--collect-entries entry recursive))))))
+ entries))
+ (t (setq result entries)))
+ result))
+
+(defmacro f--entries (path body &optional recursive)
+ "Anaphoric version of `f-entries'."
+ `(f-entries
+ ,path
+ (lambda (path)
+ (let ((it path))
+ ,body))
+ ,recursive))
+
+(defun f-entries (path &optional fn recursive)
+ "Find all files and directories in PATH.
+
+FN - called for each found file and directory. If FN returns a thruthy
+value, file or directory will be included.
+RECURSIVE - Search for files and directories recursive."
+ (let ((entries (f--collect-entries path recursive)))
+ (if fn (-select fn entries) entries)))
+
+(defmacro f--directories (path body &optional recursive)
+ "Anaphoric version of `f-directories'."
+ `(f-directories
+ ,path
+ (lambda (path)
+ (let ((it path))
+ ,body))
+ ,recursive))
+
+(defun f-directories (path &optional fn recursive)
+ "Find all directories in PATH. See `f-entries'."
+ (let ((directories (-select 'f-directory? (f--collect-entries path recursive))))
+ (if fn (-select fn directories) directories)))
+
+(defmacro f--files (path body &optional recursive)
+ "Anaphoric version of `f-files'."
+ `(f-files
+ ,path
+ (lambda (path)
+ (let ((it path))
+ ,body))
+ ,recursive))
+
+(defun f-files (path &optional fn recursive)
+ "Find all files in PATH. See `f-entries'."
+ (let ((files (-select 'f-file? (f--collect-entries path recursive))))
+ (if fn (-select fn files) files)))
+
+(defmacro f--traverse-upwards (body &optional path)
+ "Anaphoric version of `f-traverse-upwards'."
+ `(f-traverse-upwards
+ (lambda (dir)
+ (let ((it dir))
+ ,body))
+ ,path))
+
+(defun f-traverse-upwards (fn &optional path)
+ "Traverse up as long as FN return nil, starting at PATH.
+
+If FN returns a non-nil value, the path sent as argument to FN is
+returned. If no function callback return a non-nil value, nil is
+returned."
+ (unless path
+ (setq path default-directory))
+ (when (f-relative? path)
+ (setq path (f-expand path)))
+ (if (funcall fn path)
+ path
+ (unless (f-root? path)
+ (f-traverse-upwards fn (f-parent path)))))
+
+(defun f-root ()
+ "Return absolute root."
+ (f-traverse-upwards 'f-root?))
+
+(defmacro f-with-sandbox (path-or-paths &rest body)
+ "Only allow PATH-OR-PATHS and descendants to be modified in BODY."
+ (declare (indent 1))
+ `(let ((paths (if (listp ,path-or-paths)
+ ,path-or-paths
+ (list ,path-or-paths))))
+ (unwind-protect
+ (let ((f--guard-paths paths))
+ ,@body)
+ (setq f--guard-paths nil))))
+
+(provide 'f)
+
+;;; f.el ends here
diff --git a/elpa/f-20220405.1534/f.elc b/elpa/f-20220405.1534/f.elc
new file mode 100644
index 0000000..abde638
--- /dev/null
+++ b/elpa/f-20220405.1534/f.elc
Binary files differ
diff --git a/elpa/flycheck-20220504.830/flycheck-autoloads.el b/elpa/flycheck-20220504.830/flycheck-autoloads.el
new file mode 100644
index 0000000..631a2d7
--- /dev/null
+++ b/elpa/flycheck-20220504.830/flycheck-autoloads.el
@@ -0,0 +1,310 @@
+;;; flycheck-autoloads.el --- automatically extracted autoloads -*- lexical-binding: t -*-
+;;
+;;; Code:
+
+(add-to-list 'load-path (directory-file-name
+ (or (file-name-directory #$) (car load-path))))
+
+
+;;;### (autoloads nil "flycheck" "flycheck.el" (0 0 0 0))
+;;; Generated autoloads from flycheck.el
+
+(autoload 'flycheck-manual "flycheck" "\
+Open the Flycheck manual." t nil)
+
+(autoload 'flycheck-mode "flycheck" "\
+Flycheck is a minor mode for on-the-fly syntax checking.
+
+In `flycheck-mode' the buffer is automatically syntax-checked
+using the first suitable syntax checker from `flycheck-checkers'.
+Use `flycheck-select-checker' to select a checker for the current
+buffer manually.
+
+If you run into issues, use `\\[flycheck-verify-setup]' to get help.
+
+Flycheck supports many languages out of the box, and many
+additional ones are available on MELPA. Adding new ones is very
+easy. Complete documentation is available online at URL
+`https://www.flycheck.org/en/latest/'. Please report issues and
+request features at URL `https://github.com/flycheck/flycheck'.
+
+Flycheck displays its status in the mode line. In the default
+configuration, it looks like this:
+
+`FlyC' This buffer has not been checked yet.
+`FlyC-' Flycheck doesn't have a checker for this buffer.
+`FlyC*' Flycheck is running. Expect results soon!
+`FlyC:3|2' This buffer contains three warnings and two errors.
+ Use `\\[flycheck-list-errors]' to see the list.
+
+You may also see the following icons:
+`FlyC!' The checker crashed.
+`FlyC.' The last syntax check was manually interrupted.
+`FlyC?' The checker did something unexpected, like exiting with 1
+ but returning no errors.
+
+The following keybindings are available in `flycheck-mode':
+
+\\{flycheck-mode-map}
+\(you can change the prefix by customizing
+`flycheck-keymap-prefix')
+
+If called interactively, enable Flycheck mode if ARG is positive,
+and disable it if ARG is zero or negative. If called from Lisp,
+also enable the mode if ARG is omitted or nil, and toggle it if
+ARG is ‘toggle’; disable the mode otherwise.
+
+\(fn &optional ARG)" t nil)
+
+(put 'global-flycheck-mode 'globalized-minor-mode t)
+
+(defvar global-flycheck-mode nil "\
+Non-nil if Global Flycheck mode is enabled.
+See the `global-flycheck-mode' command
+for a description of this minor mode.
+Setting this variable directly does not take effect;
+either customize it (see the info node `Easy Customization')
+or call the function `global-flycheck-mode'.")
+
+(custom-autoload 'global-flycheck-mode "flycheck" nil)
+
+(autoload 'global-flycheck-mode "flycheck" "\
+Toggle Flycheck mode in all buffers.
+With prefix ARG, enable Global Flycheck mode if ARG is positive;
+otherwise, disable it.
+
+If called from Lisp, toggle the mode if ARG is `toggle'.
+Enable the mode if ARG is nil, omitted, or is a positive number.
+Disable the mode if ARG is a negative number.
+
+Flycheck mode is enabled in all buffers where `flycheck-mode-on-safe'
+would do it.
+
+See `flycheck-mode' for more information on Flycheck mode.
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'flycheck-define-error-level "flycheck" "\
+Define a new error LEVEL with PROPERTIES.
+
+The following PROPERTIES constitute an error level:
+
+`:severity SEVERITY'
+ A number denoting the severity of this level. The higher
+ the number, the more severe is this level compared to other
+ levels. Defaults to 0; info is -10, warning is 10, and
+ error is 100.
+
+ The severity is used by `flycheck-error-level-<' to
+ determine the ordering of errors according to their levels.
+
+`:compilation-level LEVEL'
+
+ A number indicating the broad class of messages that errors
+ at this level belong to: one of 0 (info), 1 (warning), or
+ 2 or nil (error). Defaults to nil.
+
+ This is used by `flycheck-checker-pattern-to-error-regexp'
+ to map error levels into `compilation-mode''s hierarchy and
+ to get proper highlighting of errors in `compilation-mode'.
+
+`:overlay-category CATEGORY'
+ A symbol denoting the overlay category to use for error
+ highlight overlays for this level. See Info
+ node `(elisp)Overlay Properties' for more information about
+ overlay categories.
+
+ A category for an error level overlay should at least define
+ the `face' property, for error highlighting. Another useful
+ property for error level categories is `priority', to
+ influence the stacking of multiple error level overlays.
+
+`:fringe-bitmap BITMAPS'
+ A fringe bitmap symbol denoting the bitmap to use for fringe
+ indicators for this level, or a cons of two bitmaps (one for
+ narrow fringes and one for wide fringes). See Info node
+ `(elisp)Fringe Bitmaps' for more information about fringe
+ bitmaps, including a list of built-in fringe bitmaps.
+
+`:fringe-face FACE'
+ A face symbol denoting the face to use for fringe indicators
+ for this level.
+
+`:margin-spec SPEC'
+ A display specification indicating what to display in the
+ margin when `flycheck-indication-mode' is `left-margin' or
+ `right-margin'. See Info node `(elisp)Displaying in the
+ Margins'. If omitted, Flycheck generates an image spec from
+ the fringe bitmap.
+
+`:error-list-face FACE'
+ A face symbol denoting the face to use for messages of this
+ level in the error list. See `flycheck-list-errors'.
+
+\(fn LEVEL &rest PROPERTIES)" nil nil)
+
+(function-put 'flycheck-define-error-level 'lisp-indent-function '1)
+
+(autoload 'flycheck-define-command-checker "flycheck" "\
+Define SYMBOL as syntax checker to run a command.
+
+Define SYMBOL as generic syntax checker via
+`flycheck-define-generic-checker', which uses an external command
+to check the buffer. SYMBOL and DOCSTRING are the same as for
+`flycheck-define-generic-checker'.
+
+In addition to the properties understood by
+`flycheck-define-generic-checker', the following PROPERTIES
+constitute a command syntax checker. Unless otherwise noted, all
+properties are mandatory. Note that the default `:error-filter'
+of command checkers is `flycheck-sanitize-errors'.
+
+`:command COMMAND'
+ The command to run for syntax checking.
+
+ COMMAND is a list of the form `(EXECUTABLE [ARG ...])'.
+
+ EXECUTABLE is a string with the executable of this syntax
+ checker. It can be overridden with the variable
+ `flycheck-SYMBOL-executable'. Note that this variable is
+ NOT implicitly defined by this function. Use
+ `flycheck-def-executable-var' to define this variable.
+
+ Each ARG is an argument to the executable, either as string,
+ or as special symbol or form for
+ `flycheck-substitute-argument', which see.
+
+`:error-patterns PATTERNS'
+ A list of patterns to parse the output of the `:command'.
+
+ Each ITEM in PATTERNS is a list `(LEVEL SEXP ...)', where
+ LEVEL is a Flycheck error level (see
+ `flycheck-define-error-level'), followed by one or more RX
+ `SEXP's which parse an error of that level and extract line,
+ column, file name and the message.
+
+ See `rx' for general information about RX, and
+ `flycheck-rx-to-string' for some special RX forms provided
+ by Flycheck.
+
+ All patterns are applied in the order of declaration to the
+ whole output of the syntax checker. Output already matched
+ by a pattern will not be matched by subsequent patterns. In
+ other words, the first pattern wins.
+
+ This property is optional. If omitted, however, an
+ `:error-parser' is mandatory.
+
+`:error-parser FUNCTION'
+ A function to parse errors with.
+
+ The function shall accept three arguments OUTPUT CHECKER
+ BUFFER. OUTPUT is the syntax checker output as string,
+ CHECKER the syntax checker that was used, and BUFFER a
+ buffer object representing the checked buffer. The function
+ must return a list of `flycheck-error' objects parsed from
+ OUTPUT.
+
+ This property is optional. If omitted, it defaults to
+ `flycheck-parse-with-patterns'. In this case,
+ `:error-patterns' is mandatory.
+
+`:standard-input t'
+ Whether to send the buffer contents on standard input.
+
+ If this property is given and has a non-nil value, send the
+ contents of the buffer on standard input.
+
+ Defaults to nil.
+
+Note that you may not give `:start', `:interrupt', and
+`:print-doc' for a command checker. You can give a custom
+`:verify' function, though, whose results will be appended to the
+default `:verify' function of command checkers.
+
+\(fn SYMBOL DOCSTRING &rest PROPERTIES)" nil nil)
+
+(function-put 'flycheck-define-command-checker 'lisp-indent-function '1)
+
+(function-put 'flycheck-define-command-checker 'doc-string-elt '2)
+
+(autoload 'flycheck-def-config-file-var "flycheck" "\
+Define SYMBOL as config file variable for CHECKER, with default FILE-NAME.
+
+SYMBOL is declared as customizable variable using `defcustom', to
+provide configuration files for the given syntax CHECKER.
+CUSTOM-ARGS are forwarded to `defcustom'.
+
+FILE-NAME is the initial value of the new variable. If omitted,
+the default value is nil. It can be either a string or a list of
+strings.
+
+Use this together with the `config-file' form in the `:command'
+argument to `flycheck-define-checker'.
+
+\(fn SYMBOL CHECKER &optional FILE-NAME &rest CUSTOM-ARGS)" nil t)
+
+(function-put 'flycheck-def-config-file-var 'lisp-indent-function '3)
+
+(autoload 'flycheck-def-option-var "flycheck" "\
+Define SYMBOL as option variable with INIT-VALUE for CHECKER.
+
+SYMBOL is declared as customizable variable using `defcustom', to
+provide an option for the given syntax CHECKERS (a checker or a
+list of checkers). INIT-VALUE is the initial value of the
+variable, and DOCSTRING is its docstring. CUSTOM-ARGS are
+forwarded to `defcustom'.
+
+Use this together with the `option', `option-list' and
+`option-flag' forms in the `:command' argument to
+`flycheck-define-checker'.
+
+\(fn SYMBOL INIT-VALUE CHECKERS DOCSTRING &rest CUSTOM-ARGS)" nil t)
+
+(function-put 'flycheck-def-option-var 'lisp-indent-function '3)
+
+(function-put 'flycheck-def-option-var 'doc-string-elt '4)
+
+(autoload 'flycheck-define-checker "flycheck" "\
+Define SYMBOL as command syntax checker with DOCSTRING and PROPERTIES.
+
+Like `flycheck-define-command-checker', but PROPERTIES must not
+be quoted. Also, implicitly define the executable variable for
+SYMBOL with `flycheck-def-executable-var'.
+
+\(fn SYMBOL DOCSTRING &rest PROPERTIES)" nil t)
+
+(function-put 'flycheck-define-checker 'lisp-indent-function '1)
+
+(function-put 'flycheck-define-checker 'doc-string-elt '2)
+
+(register-definition-prefixes "flycheck" '("flycheck-" "help-flycheck-checker-d" "list-flycheck-errors"))
+
+;;;***
+
+;;;### (autoloads nil "flycheck-buttercup" "flycheck-buttercup.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from flycheck-buttercup.el
+
+(register-definition-prefixes "flycheck-buttercup" '("flycheck-buttercup-format-error-list"))
+
+;;;***
+
+;;;### (autoloads nil "flycheck-ert" "flycheck-ert.el" (0 0 0 0))
+;;; Generated autoloads from flycheck-ert.el
+
+(register-definition-prefixes "flycheck-ert" '("flycheck-er"))
+
+;;;***
+
+;;;### (autoloads nil nil ("flycheck-pkg.el") (0 0 0 0))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; coding: utf-8
+;; End:
+;;; flycheck-autoloads.el ends here
diff --git a/elpa/flycheck-20220504.830/flycheck-buttercup.el b/elpa/flycheck-20220504.830/flycheck-buttercup.el
new file mode 100644
index 0000000..9802265
--- /dev/null
+++ b/elpa/flycheck-20220504.830/flycheck-buttercup.el
@@ -0,0 +1,157 @@
+;;; flycheck-buttercup.el --- Flycheck: Extensions to Buttercup -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2017 Flycheck contributors
+;; Copyright (C) 2016 Sebastian Wiesner and Flycheck contributors
+
+;; Author: Sebastian Wiesner <swiesner@lunaryorn.com>
+;; Maintainer: Clément Pit-Claudel <clement.pitclaudel@live.com>
+;; fmdkdd <fmdkdd@gmail.com>
+;; Keywords: lisp, tools
+
+;; 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 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:
+
+;; Extensions to Buttercup to write BDD tests for Flycheck.
+;;
+;; Buttercup is a BDD testing framework for Emacs, see URL
+;; `https://github.com/jorgenschaefer/emacs-buttercup/'. Flycheck uses
+;; Buttercup extensively for new tests.
+;;
+;; This library provides extensions to Buttercup to write Specs for Flycheck.
+;;
+;; * Custom matchers
+;;
+;; (expect 'foo :to-be-local) - Is `foo' a local variable in the current buffer?
+
+;;; Code:
+
+(require 'buttercup)
+(require 'flycheck)
+(require 'seq)
+
+
+;;; Buttercup helpers
+
+(defun flycheck-buttercup-format-error-list (errors)
+ "Format ERRORS into a human-readable string."
+ (mapconcat (lambda (e) (flycheck-error-format e 'with-file-name))
+ errors "\n"))
+
+
+;;; Data matchers
+
+(buttercup-define-matcher :to-be-empty-string (s)
+ (let ((s (funcall s)))
+ (if (equal s "")
+ (cons t (format "Expected %S not be an empty string" s))
+ (cons nil (format "Expected %S to be an empty string" s)))))
+
+(buttercup-define-matcher :to-match-with-group (re s index match)
+ (let* ((re (funcall re))
+ (s (funcall s))
+ (index (funcall index))
+ (match (funcall match))
+ (matches? (string-match re s))
+ (result (and matches? (match-string index s))))
+ (if (and matches? (equal result match))
+ (cons t (format "Expected %S not to match %S with %S in group %s"
+ re s match index))
+
+ (cons nil (format "Expected %S to match %S with %S in group %s, %s"
+ re s match index
+ (if matches?
+ (format "but got %S" result)
+ "but did not match"))))))
+
+
+;;; Emacs feature matchers
+
+(buttercup-define-matcher :to-be-live (buffer)
+ (let ((buffer (get-buffer (funcall buffer))))
+ (if (buffer-live-p buffer)
+ (cons t (format "Expected %S not to be a live buffer, but it is"
+ buffer))
+ (cons nil (format "Expected %S to be a live buffer, but it is not"
+ buffer)))))
+
+(buttercup-define-matcher :to-be-visible (buffer)
+ (let ((buffer (get-buffer (funcall buffer))))
+ (cond
+ ((and buffer (get-buffer-window buffer))
+ (cons t (format "Expected %S not to be a visible buffer, but it is"
+ buffer)))
+ ((not (bufferp buffer))
+ (cons nil
+ (format "Expected %S to be a visible buffer, but it is not a buffer"
+ buffer)))
+ (t (cons
+ nil
+ (format "Expected %S to be a visible buffer, but it is not visible"
+ buffer))))))
+
+(buttercup-define-matcher :to-be-local (symbol)
+ (let ((symbol (funcall symbol)))
+ (if (local-variable-p symbol)
+ (cons t (format "Expected %S not to be a local variable, but it is"
+ symbol))
+ (cons nil (format "Expected %S to be a local variable, but it is not"
+ symbol)))))
+
+(buttercup-define-matcher :to-contain-match (buffer re)
+ (let ((buffer (funcall buffer))
+ (re (funcall re)))
+ (if (not (get-buffer buffer))
+ (cons nil (format "Expected %S to contain a match of %s, \
+but is not a buffer" buffer re))
+ (with-current-buffer buffer
+ (save-excursion
+ (goto-char (point-min))
+ (if (re-search-forward re nil 'noerror)
+ (cons t (format "Expected %S to contain a match \
+for %s, but it did not" buffer re))
+ (cons nil (format "Expected %S not to contain a match for \
+%s but it did not." buffer re))))))))
+
+
+;;; Flycheck matchers
+
+(buttercup-define-matcher :to-be-equal-flycheck-errors (a b)
+ (let* ((a (funcall a))
+ (b (funcall b))
+ (a-formatted (flycheck-buttercup-format-error-list a))
+ (b-formatted (flycheck-buttercup-format-error-list b)))
+ (if (equal a b)
+ (cons t (format "Expected
+%s
+not to be equal to
+%s" a-formatted b-formatted))
+ (cons nil (format "Expected
+%s
+to be equal to
+%s" a-formatted b-formatted)))))
+
+(provide 'flycheck-buttercup)
+
+;; Disable byte compilation for this library, to prevent package.el choking on a
+;; missing `buttercup' library. See
+;; https://github.com/flycheck/flycheck/issues/860
+
+;; Local Variables:
+;; no-byte-compile: t
+;; End:
+
+;;; flycheck-buttercup.el ends here
diff --git a/elpa/flycheck-20220504.830/flycheck-ert.el b/elpa/flycheck-20220504.830/flycheck-ert.el
new file mode 100644
index 0000000..4d64a73
--- /dev/null
+++ b/elpa/flycheck-20220504.830/flycheck-ert.el
@@ -0,0 +1,507 @@
+;;; flycheck-ert.el --- Flycheck: ERT extensions -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2017-2018 Flycheck contributors
+;; Copyright (C) 2013-2016 Sebastian Wiesner and Flycheck contributors
+
+;; Author: Sebastian Wiesner <swiesner@lunaryorn.com>
+;; Maintainer: Clément Pit-Claudel <clement.pitclaudel@live.com>
+;; fmdkdd <fmdkdd@gmail.com>
+;; URL: https://github.com/flycheck/flycheck
+
+;; 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 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:
+
+;; Unit testing library for Flycheck, the modern on-the-fly syntax checking
+;; extension for GNU Emacs.
+
+;; Provide various utility functions and unit test helpers to test Flycheck and
+;; Flycheck extensions.
+
+;;; Code:
+
+(require 'flycheck)
+(require 'ert)
+(require 'macroexp) ; For macro utilities
+
+
+;;; Compatibility
+
+(eval-and-compile
+ ;; Provide `ert-skip' and friends for Emacs 24.3
+ (defconst flycheck-ert-ert-can-skip (fboundp 'ert-skip)
+ "Whether ERT supports test skipping.")
+
+ (unless (fboundp 'define-error)
+ ;; from Emacs `subr.el'
+ (defun define-error (name message &optional parent)
+ "Define NAME as a new error signal.
+MESSAGE is a string that will be output to the echo area if such an error
+is signaled without being caught by a `condition-case'.
+PARENT is either a signal or a list of signals from which it inherits.
+Defaults to `error'."
+ (unless parent (setq parent 'error))
+ (let ((conditions
+ (if (consp parent)
+ (apply #'append
+ (mapcar
+ (lambda (parent)
+ (cons parent
+ (or (get parent 'error-conditions)
+ (error "Unknown signal `%s'" parent))))
+ parent))
+ (cons parent (get parent 'error-conditions)))))
+ (put name 'error-conditions
+ (delete-dups (copy-sequence (cons name conditions))))
+ (when message (put name 'error-message message)))))
+
+ (unless flycheck-ert-ert-can-skip
+ ;; Fake skipping
+
+ (define-error 'flycheck-ert-skipped "Test skipped")
+
+ (defun ert-skip (data)
+ (signal 'flycheck-ert-skipped data))
+
+ (defmacro skip-unless (form)
+ `(unless (ignore-errors ,form)
+ (signal 'flycheck-ert-skipped ',form)))
+
+ (defun ert-test-skipped-p (result)
+ (and (ert-test-failed-p result)
+ (eq (car (ert-test-failed-condition result))
+ 'flycheck-ert-skipped)))))
+
+
+;;; Internal variables
+
+(defvar flycheck-ert--resource-directory nil
+ "The directory to get resources from in this test suite.")
+
+
+;;; Resource management macros
+
+(defmacro flycheck-ert-with-temp-buffer (&rest body)
+ "Eval BODY within a temporary buffer.
+
+Like `with-temp-buffer', but resets the modification state of the
+temporary buffer to make sure that it is properly killed even if
+it has a backing file and is modified."
+ (declare (indent 0) (debug t))
+ `(with-temp-buffer
+ (unwind-protect
+ ,(macroexp-progn body)
+ ;; Reset modification state of the buffer, and unlink it from its backing
+ ;; file, if any, because Emacs refuses to kill modified buffers with
+ ;; backing files, even if they are temporary.
+ (set-buffer-modified-p nil)
+ (set-visited-file-name nil 'no-query))))
+
+(defmacro flycheck-ert-with-file-buffer (file-name &rest body)
+ "Create a buffer from FILE-NAME and eval BODY.
+
+BODY is evaluated with `current-buffer' being a buffer with the
+contents FILE-NAME."
+ (declare (indent 1) (debug t))
+ `(let ((file-name ,file-name))
+ (unless (file-exists-p file-name)
+ (error "%s does not exist" file-name))
+ (flycheck-ert-with-temp-buffer
+ (insert-file-contents file-name 'visit)
+ (set-visited-file-name file-name 'no-query)
+ (cd (file-name-directory file-name))
+ ;; Mark the buffer as not modified, because we just loaded the file up to
+ ;; now.
+ (set-buffer-modified-p nil)
+ ,@body)))
+
+(defmacro flycheck-ert-with-help-buffer (&rest body)
+ "Execute BODY and kill the help buffer afterwards.
+
+Use this macro to test functions that create a Help buffer."
+ (declare (indent 0))
+ `(unwind-protect
+ ,(macroexp-progn body)
+ (when (buffer-live-p (get-buffer (help-buffer)))
+ (kill-buffer (help-buffer)))))
+
+(defmacro flycheck-ert-with-global-mode (&rest body)
+ "Execute BODY with Global Flycheck Mode enabled.
+
+After BODY, restore the old state of Global Flycheck Mode."
+ (declare (indent 0))
+ `(let ((old-state global-flycheck-mode))
+ (unwind-protect
+ (progn
+ (global-flycheck-mode 1)
+ ,@body)
+ (global-flycheck-mode (if old-state 1 -1)))))
+
+(defmacro flycheck-ert-with-env (env &rest body)
+ "Add ENV to `process-environment' in BODY.
+
+Execute BODY with a `process-environment' which contains all
+variables from ENV added.
+
+ENV is an alist, where each cons cell `(VAR . VALUE)' is a
+environment variable VAR to be added to `process-environment'
+with VALUE."
+ (declare (indent 1))
+ `(let ((process-environment (copy-sequence process-environment)))
+ (pcase-dolist (`(,var . ,value) ,env)
+ (setenv var value))
+ ,@body))
+
+
+;;; Test resources
+(defun flycheck-ert-resource-filename (resource-file)
+ "Determine the absolute file name of a RESOURCE-FILE.
+
+Relative file names are expanded against
+`flycheck-ert--resource-directory'."
+ (expand-file-name resource-file flycheck-ert--resource-directory))
+
+(defmacro flycheck-ert-with-resource-buffer (resource-file &rest body)
+ "Create a temp buffer from a RESOURCE-FILE and execute BODY.
+
+The absolute file name of RESOURCE-FILE is determined with
+`flycheck-ert-resource-filename'."
+ (declare (indent 1))
+ `(flycheck-ert-with-file-buffer
+ (flycheck-ert-resource-filename ,resource-file)
+ ,@body))
+
+
+;;; Test suite initialization
+
+(defun flycheck-ert-initialize (resource-dir)
+ "Initialize a test suite with RESOURCE-DIR.
+
+RESOURCE-DIR is the directory, `flycheck-ert-resource-filename'
+should use to lookup resource files."
+ (when flycheck-ert--resource-directory
+ (error "Test suite already initialized"))
+ (let ((tests (ert-select-tests t t)))
+ ;; Select all tests
+ (unless tests
+ (error "No tests defined. \
+Call `flycheck-ert-initialize' after defining all tests!"))
+
+ (setq flycheck-ert--resource-directory resource-dir)
+
+ ;; Emacs 24.3 don't support skipped tests, so we add poor man's test
+ ;; skipping: We mark skipped tests as expected failures by adjusting the
+ ;; expected result of all test cases. Not particularly pretty, but works :)
+ (unless flycheck-ert-ert-can-skip
+ (dolist (test tests)
+ (let ((result (ert-test-expected-result-type test)))
+ (setf (ert-test-expected-result-type test)
+ `(or ,result (satisfies ert-test-skipped-p))))))))
+
+
+;;; Test case definitions
+(defmacro flycheck-ert-def-checker-test (checker language name
+ &rest keys-and-body)
+ "Define a test case for a syntax CHECKER for LANGUAGE.
+
+CHECKER is a symbol or a list of symbols denoting syntax checkers
+being tested by the test. The test case is skipped, if any of
+these checkers cannot be used. LANGUAGE is a symbol or a list of
+symbols denoting the programming languages supported by the
+syntax checkers. This is currently only used for tagging the
+test appropriately.
+
+NAME is a symbol denoting the local name of the test. The test
+itself is ultimately named
+`flycheck-define-checker/CHECKER/NAME'. If CHECKER is a list,
+the first checker in the list is used for naming the test.
+
+Optionally, the keyword arguments `:tags' and `:expected-result'
+may be given. They have the same meaning as in `ert-deftest.',
+and are added to the tags and result expectations set up by this
+macro.
+
+The remaining forms KEYS-AND-BODY denote the body of the test
+case, including assertions and setup code."
+ (declare (indent 3))
+ (unless checker
+ (error "No syntax checkers specified"))
+ (unless language
+ (error "No languages specified"))
+ (let* ((checkers (if (symbolp checker) (list checker) checker))
+ (checker (car checkers))
+ (languages (if (symbolp language) (list language) language))
+ (language-tags (mapcar (lambda (l) (intern (format "language-%s" l)))
+ languages))
+ (checker-tags (mapcar (lambda (c) (intern (format "checker-%s" c)))
+ checkers))
+ (local-name (or name 'default))
+ (full-name (intern (format "flycheck-define-checker/%s/%s"
+ checker local-name)))
+ (keys-and-body (ert--parse-keys-and-body keys-and-body))
+ (body (cadr keys-and-body))
+ (keys (car keys-and-body))
+ (default-tags '(syntax-checker external-tool)))
+ `(ert-deftest ,full-name ()
+ :expected-result ,(or (plist-get keys :expected-result) :passed)
+ :tags (append ',(append default-tags language-tags checker-tags)
+ ,(plist-get keys :tags))
+ ,@(mapcar (lambda (c)
+ `(skip-unless
+ ;; Ignore non-command checkers
+ (or (not (flycheck-checker-get ',c 'command))
+ (executable-find (flycheck-checker-executable ',c)))))
+ checkers)
+ ,@body)))
+
+
+;;; Test case results
+
+(defun flycheck-ert-syntax-check-timed-out-p (result)
+ "Whether RESULT denotes a timed-out test.
+
+RESULT is an ERT test result object."
+ (and (ert-test-failed-p result)
+ (eq (car (ert-test-failed-condition result))
+ 'flycheck-ert-syntax-check-timed-out)))
+
+
+;;; Syntax checking in tests
+
+(defvar-local flycheck-ert-syntax-checker-finished nil
+ "Non-nil if the current checker has finished.")
+
+(add-hook 'flycheck-after-syntax-check-hook
+ (lambda () (setq flycheck-ert-syntax-checker-finished t)))
+
+(defconst flycheck-ert-checker-wait-time 10
+ "Time to wait until a checker is finished in seconds.
+
+After this time has elapsed, the checker is considered to have
+failed, and the test aborted with failure.")
+
+(define-error 'flycheck-ert-syntax-check-timed-out "Syntax check timed out.")
+
+(defun flycheck-ert-wait-for-syntax-checker ()
+ "Wait until the syntax check in the current buffer is finished."
+ (let ((starttime (float-time)))
+ (while (and (not flycheck-ert-syntax-checker-finished)
+ (< (- (float-time) starttime) flycheck-ert-checker-wait-time))
+ (accept-process-output nil 0.02))
+ (unless (< (- (float-time) starttime) flycheck-ert-checker-wait-time)
+ (flycheck-stop)
+ (signal 'flycheck-ert-syntax-check-timed-out nil)))
+ (setq flycheck-ert-syntax-checker-finished nil))
+
+(defun flycheck-ert-buffer-sync ()
+ "Like `flycheck-buffer', but synchronously."
+ (setq flycheck-ert-syntax-checker-finished nil)
+ (should (not (flycheck-running-p)))
+ (flycheck-mode) ;; This will only start a deferred check,
+ (should (flycheck-get-checker-for-buffer))
+ (flycheck-buffer) ;; …so we need an explicit manual check
+ ;; After starting the check, the checker should either be running now, or
+ ;; already be finished (if it was fast).
+ (should (or flycheck-current-syntax-check
+ flycheck-ert-syntax-checker-finished))
+ ;; Also there should be no deferred check pending anymore
+ (should-not (flycheck-deferred-check-p))
+ (flycheck-ert-wait-for-syntax-checker))
+
+(defun flycheck-ert-ensure-clear ()
+ "Clear the current buffer.
+
+Raise an assertion error if the buffer is not clear afterwards."
+ (flycheck-clear)
+ (should (not flycheck-current-errors))
+ (should (not (-any? (lambda (ov) (overlay-get ov 'flycheck-overlay))
+ (overlays-in (point-min) (point-max))))))
+
+
+;;; Test assertions
+
+(defun flycheck-error-without-group (err)
+ "Return a copy ERR with the `group' property set to nil."
+ (let ((copy (copy-flycheck-error err)))
+ (setf (flycheck-error-group copy) nil)
+ copy))
+
+(defun flycheck-ert-should-overlay (error)
+ "Test that ERROR has a proper overlay in the current buffer.
+
+ERROR is a Flycheck error object."
+ (let* ((overlay (-first (lambda (ov)
+ (equal (flycheck-error-without-group
+ (overlay-get ov 'flycheck-error))
+ (flycheck-error-without-group error)))
+ (flycheck-overlays-in 0 (+ 1 (buffer-size)))))
+ (region
+ ;; Overlays of errors from other files are on the first line
+ (if (flycheck-relevant-error-other-file-p error)
+ (cons (point-min)
+ (save-excursion (goto-char (point-min)) (point-at-eol)))
+ (flycheck-error-region-for-mode error 'symbols)))
+ (level (flycheck-error-level error))
+ (category (flycheck-error-level-overlay-category level))
+ (face (get category 'face))
+ (fringe-bitmap (flycheck-error-level-fringe-bitmap level))
+ (fringe-face (flycheck-error-level-fringe-face level))
+ (fringe-icon (list 'left-fringe fringe-bitmap fringe-face)))
+ (should overlay)
+ (should (overlay-get overlay 'flycheck-overlay))
+ (should (= (overlay-start overlay) (car region)))
+ (should (= (overlay-end overlay) (cdr region)))
+ (should (eq (overlay-get overlay 'face) face))
+ (should (equal (get-char-property 0 'display
+ (overlay-get overlay 'before-string))
+ fringe-icon))
+ (should (eq (overlay-get overlay 'category) category))
+ (should (equal (flycheck-error-without-group (overlay-get overlay
+ 'flycheck-error))
+ (flycheck-error-without-group error)))))
+
+(defun flycheck-ert-sort-errors (errors)
+ "Sort ERRORS by `flycheck-error-<'."
+ (seq-sort #'flycheck-error-< errors))
+
+(defun flycheck-ert-should-errors (&rest errors)
+ "Test that the current buffers has ERRORS.
+
+ERRORS is a list of errors expected to be present in the current
+buffer. Each error is given as a list of arguments to
+`flycheck-error-new-at'.
+
+If ERRORS are omitted, test that there are no errors at all in
+the current buffer.
+
+With ERRORS, test that each error in ERRORS is present in the
+current buffer, and that the number of errors in the current
+buffer is equal to the number of given ERRORS. In other words,
+check that the buffer has all ERRORS, and no other errors."
+ (let ((expected (flycheck-ert-sort-errors
+ (mapcar (apply-partially #'apply #'flycheck-error-new-at)
+ errors)))
+ (current (flycheck-ert-sort-errors flycheck-current-errors)))
+ (should (equal (mapcar #'flycheck-error-without-group expected)
+ (mapcar #'flycheck-error-without-group current)))
+ ;; Check that related errors are the same
+ (cl-mapcar
+ (lambda (err1 err2)
+ (should (equal (flycheck-ert-sort-errors
+ (mapcar #'flycheck-error-without-group
+ (flycheck-related-errors err1 expected)))
+ (flycheck-ert-sort-errors
+ (mapcar #'flycheck-error-without-group
+ (flycheck-related-errors err2))))))
+ expected current)
+ (mapc #'flycheck-ert-should-overlay expected))
+ (should (= (length errors)
+ (length (flycheck-overlays-in (point-min) (point-max))))))
+
+(define-error 'flycheck-ert-suspicious-checker "Suspicious state from checker")
+
+(defun flycheck-ert-should-syntax-check-in-buffer (&rest errors)
+ "Test a syntax check in BUFFER, expecting ERRORS.
+
+This is like `flycheck-ert-should-syntax-check', but with a
+buffer in the right mode instead of a file."
+ ;; Load safe file-local variables because some tests depend on them
+ (let ((enable-local-variables :safe)
+ ;; Disable all hooks at this place, to prevent 3rd party packages
+ ;; from interfering
+ (hack-local-variables-hook))
+ (hack-local-variables))
+ ;; Configure config file locating for unit tests
+ (let ((process-hook-called 0)
+ (suspicious nil))
+ (add-hook 'flycheck-process-error-functions
+ (lambda (_err)
+ (setq process-hook-called (1+ process-hook-called))
+ nil)
+ nil :local)
+ (add-hook 'flycheck-status-changed-functions
+ (lambda (status)
+ (when (eq status 'suspicious)
+ (setq suspicious t)))
+ nil :local)
+ (flycheck-ert-buffer-sync)
+ (when suspicious
+ (signal 'flycheck-ert-suspicious-checker nil))
+ (apply #'flycheck-ert-should-errors errors)
+ (should (= process-hook-called (length errors))))
+ (flycheck-ert-ensure-clear))
+
+(defun flycheck-ert-should-syntax-check (resource-file modes &rest errors)
+ "Test a syntax check in RESOURCE-FILE with MODES.
+
+RESOURCE-FILE is the file to check. MODES is a single major mode
+symbol or a list thereof, specifying the major modes to syntax
+check with. If more than one major mode is specified, the test
+is run for each mode separately, so if you give three major
+modes, the entire test will run three times. ERRORS is the list
+of expected errors, as in `flycheck-ert-should-errors'. If
+omitted, the syntax check must not emit any errors. The errors
+are cleared after each test.
+
+The syntax checker is selected via standard syntax checker
+selection. To test a specific checker, you need to set
+`flycheck-checker' or `flycheck-disabled-checkers' accordingly
+before using this predicate, depending on whether you want to use
+manual or automatic checker selection.
+
+During the syntax check, configuration files of syntax checkers
+are also searched in the `config-files' sub-directory of the
+resource directory."
+ (when (symbolp modes)
+ (setq modes (list modes)))
+ (dolist (mode modes)
+ (unless (fboundp mode)
+ (ert-skip (format "%S missing" mode)))
+ (flycheck-ert-with-resource-buffer resource-file
+ (funcall mode)
+ (apply #'flycheck-ert-should-syntax-check-in-buffer errors))))
+
+(defun flycheck-ert-at-nth-error (n)
+ "Determine whether point is at the N'th Flycheck error.
+
+Return non-nil if the point is at the N'th Flycheck error in the
+current buffer. Otherwise return nil."
+ (let* ((error (nth (1- n) flycheck-current-errors))
+ (mode flycheck-highlighting-mode)
+ (region (flycheck-error-region-for-mode error mode)))
+ (and (member error (flycheck-overlay-errors-at (point)))
+ (= (point) (car region)))))
+
+(defun flycheck-ert-explain--at-nth-error (n)
+ "Explain a failed at-nth-error predicate at N."
+ (let ((errors (flycheck-overlay-errors-at (point))))
+ (if (null errors)
+ (format "Expected to be at error %s, but no error at point %s"
+ n (point))
+ (let ((pos (cl-position (car errors) flycheck-current-errors)))
+ (format "Expected to be at point %s and error %s, \
+but point %s is at error %s"
+ (car (flycheck-error-region-for-mode
+ (nth (1- n) flycheck-current-errors)
+ flycheck-highlighting-mode))
+ n (point) (1+ pos))))))
+
+(put 'flycheck-ert-at-nth-error 'ert-explainer
+ 'flycheck-ert-explain--at-nth-error)
+
+(provide 'flycheck-ert)
+
+;;; flycheck-ert.el ends here
diff --git a/elpa/flycheck-20220504.830/flycheck-ert.elc b/elpa/flycheck-20220504.830/flycheck-ert.elc
new file mode 100644
index 0000000..da04ccd
--- /dev/null
+++ b/elpa/flycheck-20220504.830/flycheck-ert.elc
Binary files differ
diff --git a/elpa/flycheck-20220504.830/flycheck-pkg.el b/elpa/flycheck-20220504.830/flycheck-pkg.el
new file mode 100644
index 0000000..043208d
--- /dev/null
+++ b/elpa/flycheck-20220504.830/flycheck-pkg.el
@@ -0,0 +1,16 @@
+(define-package "flycheck" "20220504.830" "On-the-fly syntax checking"
+ '((dash "2.12.1")
+ (pkg-info "0.4")
+ (let-alist "1.0.4")
+ (seq "1.11")
+ (emacs "24.3"))
+ :commit "1d7c1b20782ccbaa6f97e37f5e1d0cee3d5eda8a" :authors
+ '(("Sebastian Wiesner" . "swiesner@lunaryorn.com"))
+ :maintainer
+ '("Clément Pit-Claudel" . "clement.pitclaudel@live.com")
+ :keywords
+ '("convenience" "languages" "tools")
+ :url "http://www.flycheck.org")
+;; Local Variables:
+;; no-byte-compile: t
+;; End:
diff --git a/elpa/flycheck-20220504.830/flycheck.el b/elpa/flycheck-20220504.830/flycheck.el
new file mode 100644
index 0000000..95c755d
--- /dev/null
+++ b/elpa/flycheck-20220504.830/flycheck.el
@@ -0,0 +1,12469 @@
+;;; flycheck.el --- On-the-fly syntax checking -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2017-2020 Flycheck contributors
+;; Copyright (C) 2012-2016 Sebastian Wiesner and Flycheck contributors
+;; Copyright (C) 2013, 2014 Free Software Foundation, Inc.
+;;
+;; Author: Sebastian Wiesner <swiesner@lunaryorn.com>
+;; Maintainer: Clément Pit-Claudel <clement.pitclaudel@live.com>
+;; fmdkdd <fmdkdd@gmail.com>
+;; URL: http://www.flycheck.org
+;; Keywords: convenience, languages, tools
+;; Version: 33-cvs
+;; Package-Requires: ((dash "2.12.1") (pkg-info "0.4") (let-alist "1.0.4") (seq "1.11") (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 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:
+
+;; On-the-fly syntax checking for GNU Emacs 24.
+;;
+;; Flycheck is a modern on-the-fly syntax checking extension for GNU Emacs,
+;; intended as replacement for the older Flymake extension which is part of GNU
+;; Emacs.
+;;
+;; Flycheck automatically checks buffers for errors while you type, and reports
+;; warnings and errors directly in the buffer and in an optional IDE-like error
+;; list.
+;;
+;; It comes with a rich interface for custom syntax checkers and other
+;; extensions, and has already many 3rd party extensions adding new features.
+;;
+;; Please read the online manual at http://www.flycheck.org for more
+;; information. You can open the manual directly from Emacs with `M-x
+;; flycheck-manual'.
+;;
+;; # Setup
+;;
+;; Flycheck works best on Unix systems. It does not officially support Windows,
+;; but tries to maintain Windows compatibility and should generally work fine on
+;; Windows, too.
+;;
+;; To enable Flycheck add the following to your init file:
+;;
+;; (add-hook 'after-init-hook #'global-flycheck-mode)
+;;
+;; Flycheck will then automatically check buffers in supported languages, as
+;; long as all necessary tools are present. Use `flycheck-verify-setup' to
+;; troubleshoot your Flycheck setup.
+
+;;; Code:
+
+(eval-when-compile
+ (require 'let-alist) ; `let-alist'
+ (require 'compile) ; Compile Mode integration
+ (require 'jka-compr) ; To inhibit compression of temp files
+ (require 'pcase) ; `pcase-dolist' (`pcase' itself is autoloaded)
+ )
+
+(require 'dash)
+
+(require 'seq) ; Sequence functions
+(require 'subr-x nil 'no-error) ; Additional utilities, Emacs 24.4 and upwards
+(require 'cl-lib) ; `cl-defstruct' and CL utilities
+(require 'tabulated-list) ; To list errors
+(require 'easymenu) ; Flycheck Mode menu definition
+(require 'rx) ; Regexp fanciness in `flycheck-define-checker'
+(require 'help-mode) ; `define-button-type'
+(require 'find-func) ; `find-function-regexp-alist'
+(require 'json) ; `flycheck-parse-tslint'
+(require 'ansi-color) ; `flycheck-parse-with-patterns-without-color'
+
+
+;; Declare a bunch of dynamic variables that we need from other modes
+(defvar sh-shell) ; For shell script checker predicates
+(defvar ess-language) ; For r-lintr predicate
+(defvar markdown-hide-markup) ;
+(defvar markdown-fontify-code-block-default-mode) ; For rust-error-explainer
+(defvar markdown-fontify-code-blocks-natively) ;
+
+;; Tell the byte compiler about autoloaded functions from packages
+(declare-function pkg-info-version-info "pkg-info" (package))
+
+
+;;; Compatibility
+(eval-and-compile
+ (unless (fboundp 'string-suffix-p)
+ ;; TODO: Remove when dropping support for Emacs 24.3 and earlier
+ (defun string-suffix-p (suffix string &optional ignore-case)
+ "Return non-nil if SUFFIX is a suffix of STRING.
+If IGNORE-CASE is non-nil, the comparison is done without paying
+attention to case differences."
+ (let ((start-pos (- (length string) (length suffix))))
+ (and (>= start-pos 0)
+ (eq t (compare-strings suffix nil nil
+ string start-pos nil ignore-case))))))
+
+ (defalias 'flycheck--format-message
+ (if (fboundp 'format-message) #'format-message #'format))
+
+ ;; TODO: Remove when dropping support for Emacs 24.3 and earlier
+ (unless (featurep 'subr-x)
+ ;; `subr-x' function for Emacs 24.3 and below
+ (defsubst string-join (strings &optional separator)
+ "Join all STRINGS using SEPARATOR."
+ (mapconcat 'identity strings separator))
+
+ (defsubst string-trim-left (string)
+ "Remove leading whitespace from STRING."
+ (if (string-match "\\`[ \t\n\r]+" string)
+ (replace-match "" t t string)
+ string))
+
+ (defsubst string-trim-right (string)
+ "Remove trailing whitespace from STRING."
+ (if (string-match "[ \t\n\r]+\\'" string)
+ (replace-match "" t t string)
+ string))
+
+ (defsubst string-trim (string)
+ "Remove leading and trailing whitespace from STRING."
+ (string-trim-left (string-trim-right string)))
+
+ (defsubst string-empty-p (string)
+ "Check whether STRING is empty."
+ (string= string ""))))
+
+
+;;; Customization
+(defgroup flycheck nil
+ "Modern on-the-fly syntax checking for GNU Emacs."
+ :prefix "flycheck-"
+ :group 'tools
+ :link '(url-link :tag "Website" "http://www.flycheck.org")
+ :link '(url-link :tag "Github" "https://github.com/flycheck/flycheck"))
+
+(defgroup flycheck-config-files nil
+ "Configuration files for on-the-fly syntax checkers."
+ :prefix "flycheck-"
+ :group 'flycheck)
+
+(defgroup flycheck-options nil
+ "Options for on-the-fly syntax checkers."
+ :prefix "flycheck-"
+ :group 'flycheck)
+
+(defgroup flycheck-executables nil
+ "Executables of syntax checkers."
+ :prefix "flycheck-"
+ :group 'flycheck)
+
+(defgroup flycheck-faces nil
+ "Faces used by on-the-fly syntax checking."
+ :prefix "flycheck-"
+ :group 'flycheck)
+
+(defcustom flycheck-checkers
+ '(ada-gnat
+ asciidoctor
+ asciidoc
+ awk-gawk
+ bazel-buildifier
+ c/c++-clang
+ c/c++-gcc
+ c/c++-cppcheck
+ cfengine
+ chef-foodcritic
+ coffee
+ coffee-coffeelint
+ coq
+ css-csslint
+ css-stylelint
+ cuda-nvcc
+ cwl
+ d-dmd
+ dockerfile-hadolint
+ elixir-credo
+ emacs-lisp
+ emacs-lisp-checkdoc
+ ember-template
+ erlang-rebar3
+ erlang
+ eruby-erubis
+ eruby-ruumba
+ fortran-gfortran
+ go-gofmt
+ go-golint
+ go-vet
+ go-build
+ go-test
+ go-errcheck
+ go-unconvert
+ go-staticcheck
+ groovy
+ haml
+ handlebars
+ haskell-stack-ghc
+ haskell-ghc
+ haskell-hlint
+ html-tidy
+ javascript-eslint
+ javascript-jshint
+ javascript-standard
+ json-jsonlint
+ json-python-json
+ json-jq
+ jsonnet
+ less
+ less-stylelint
+ llvm-llc
+ lua-luacheck
+ lua
+ markdown-markdownlint-cli
+ markdown-mdl
+ nix
+ nix-linter
+ opam
+ perl
+ perl-perlcritic
+ php
+ php-phpmd
+ php-phpcs
+ processing
+ proselint
+ protobuf-protoc
+ protobuf-prototool
+ pug
+ puppet-parser
+ puppet-lint
+ python-flake8
+ python-pylint
+ python-pycompile
+ python-pyright
+ python-mypy
+ r-lintr
+ racket
+ rpm-rpmlint
+ rst-sphinx
+ rst
+ ruby-rubocop
+ ruby-standard
+ ruby-reek
+ ruby-rubylint
+ ruby
+ ruby-jruby
+ rust-cargo
+ rust
+ rust-clippy
+ scala
+ scala-scalastyle
+ scheme-chicken
+ scss-lint
+ scss-stylelint
+ sass/scss-sass-lint
+ sass
+ scss
+ sh-bash
+ sh-posix-dash
+ sh-posix-bash
+ sh-zsh
+ sh-shellcheck
+ slim
+ slim-lint
+ sql-sqlint
+ systemd-analyze
+ tcl-nagelfar
+ terraform
+ terraform-tflint
+ tex-chktex
+ tex-lacheck
+ texinfo
+ textlint
+ typescript-tslint
+ verilog-verilator
+ vhdl-ghdl
+ xml-xmlstarlet
+ xml-xmllint
+ yaml-jsyaml
+ yaml-ruby
+ yaml-yamllint)
+ "Syntax checkers available for automatic selection.
+
+A list of Flycheck syntax checkers to choose from when syntax
+checking a buffer. Flycheck will automatically select a suitable
+syntax checker from this list, unless `flycheck-checker' is set,
+either directly or with `flycheck-select-checker'.
+
+You should not need to change this variable normally. In order
+to disable syntax checkers, please use
+`flycheck-disabled-checkers'. This variable is intended for 3rd
+party extensions to tell Flycheck about new syntax checkers.
+
+Syntax checkers in this list must be defined with
+`flycheck-define-checker'."
+ :group 'flycheck
+ :type '(repeat (symbol :tag "Checker"))
+ :risky t)
+
+(defcustom flycheck-disabled-checkers nil
+ "Syntax checkers excluded from automatic selection.
+
+A list of Flycheck syntax checkers to exclude from automatic
+selection. Flycheck will never automatically select a syntax
+checker in this list, regardless of the value of
+`flycheck-checkers'.
+
+However, syntax checkers in this list are still available for
+manual selection with `flycheck-select-checker'.
+
+Use this variable to disable syntax checkers, instead of removing
+the syntax checkers from `flycheck-checkers'. You may also use
+this option as a file or directory local variable to disable
+specific checkers in individual files and directories
+respectively."
+ :group 'flycheck
+ :type '(repeat (symbol :tag "Checker"))
+ :package-version '(flycheck . "0.16")
+ :safe #'flycheck-symbol-list-p)
+(make-variable-buffer-local 'flycheck-disabled-checkers)
+
+(defvar-local flycheck--automatically-disabled-checkers nil
+ "List of syntax checkers automatically disabled for this buffer.
+
+A checker can be automatically disabled in two cases:
+
+1. Its `:enabled' predicate returned false.
+2. It returned too many errors (see `flycheck-checker-error-threshold').
+
+To trigger a reverification from Emacs Lisp code, do not modify
+this variable: use `flycheck-reset-enabled-checker'.")
+
+(defvar-local flycheck-checker nil
+ "Syntax checker to use for the current buffer.
+
+If unset or nil, automatically select a suitable syntax checker
+from `flycheck-checkers' on every syntax check.
+
+If set to a syntax checker only use this syntax checker and never
+select one from `flycheck-checkers' automatically. The syntax
+checker is used regardless of whether it is contained in
+`flycheck-checkers' or `flycheck-disabled-checkers'. If the
+syntax checker is unusable in the current buffer an error is
+signaled.
+
+A syntax checker assigned to this variable must be defined with
+`flycheck-define-checker'.
+
+Use the command `flycheck-select-checker' to select a syntax
+checker for the current buffer, or set this variable as file
+local variable to always use a specific syntax checker for a
+file. See Info Node `(Emacs)Specifying File Variables' for more
+information about file variables.")
+(put 'flycheck-checker 'safe-local-variable 'flycheck-registered-checker-p)
+
+(defcustom flycheck-locate-config-file-functions nil
+ "Functions to locate syntax checker configuration files.
+
+Each function in this hook must accept two arguments: The value
+of the configuration file variable, and the syntax checker
+symbol. It must return either a string with an absolute path to
+the configuration file, or nil, if it cannot locate the
+configuration file.
+
+The functions in this hook are called in order of appearance, until a
+function returns non-nil. The configuration file returned by that
+function is then given to the syntax checker if it exists.
+
+This variable is an abnormal hook. See Info
+node `(elisp)Hooks'."
+ :group 'flycheck
+ :type 'hook
+ :risky t)
+
+(defcustom flycheck-checker-error-threshold 400
+ "Maximum errors allowed per syntax checker.
+
+The value of this variable is either an integer denoting the
+maximum number of errors per syntax checker and buffer, or nil to
+not limit the errors reported from a syntax checker.
+
+If this variable is a number and a syntax checker reports more
+errors than the value of this variable, its errors are not
+discarded, and not highlighted in the buffer or available in the
+error list. The affected syntax checker is also disabled for
+future syntax checks of the buffer."
+ :group 'flycheck
+ :type '(choice (const :tag "Do not limit reported errors" nil)
+ (integer :tag "Maximum number of errors"))
+ :risky t
+ :package-version '(flycheck . "0.22"))
+
+(defcustom flycheck-process-error-functions nil
+ "Functions to process errors.
+
+Each function in this hook must accept a single argument: A
+Flycheck error to process.
+
+All functions in this hook are called in order of appearance,
+until a function returns non-nil. Thus, a function in this hook
+may return nil, to allow for further processing of the error, or
+any non-nil value, to indicate that the error was fully processed
+and inhibit any further processing.
+
+The functions are called for each newly parsed error immediately
+after the corresponding syntax checker finished. At this stage,
+the overlays from the previous syntax checks are still present,
+and there may be further syntax checkers in the chain.
+
+This variable is an abnormal hook. See Info
+node `(elisp)Hooks'."
+ :group 'flycheck
+ :type 'hook
+ :package-version '(flycheck . "0.13")
+ :risky t)
+
+(defcustom flycheck-display-errors-delay 0.9
+ "Delay in seconds before displaying errors at point.
+
+Use floating point numbers to express fractions of seconds."
+ :group 'flycheck
+ :type 'number
+ :package-version '(flycheck . "0.15")
+ :safe #'numberp)
+
+(defcustom flycheck-display-errors-function #'flycheck-display-error-messages
+ "Function to display error messages.
+
+If set to a function, call the function with the list of errors
+to display as single argument. Each error is an instance of the
+`flycheck-error' struct.
+
+If set to nil, do not display errors at all."
+ :group 'flycheck
+ :type '(choice (const :tag "Display error messages"
+ flycheck-display-error-messages)
+ (const :tag "Display error messages only if no error list"
+ flycheck-display-error-messages-unless-error-list)
+ (function :tag "Error display function"))
+ :package-version '(flycheck . "0.13")
+ :risky t)
+
+(defcustom flycheck-help-echo-function #'flycheck-help-echo-all-error-messages
+ "Function to compute the contents of the error tooltips.
+
+If set to a function, call the function with the list of errors
+to display as single argument. Each error is an instance of the
+`flycheck-error' struct. The function is used to set the
+help-echo property of flycheck error overlays. It should return
+a string, which is displayed when the user hovers over an error
+or presses \\[display-local-help].
+
+If set to nil, do not show error tooltips."
+ :group 'flycheck
+ :type '(choice (const :tag "Concatenate error messages to form a tooltip"
+ flycheck-help-echo-all-error-messages)
+ (function :tag "Help echo function"))
+ :package-version '(flycheck . "0.25")
+ :risky t)
+
+(defcustom flycheck-command-wrapper-function #'identity
+ "Function to modify checker commands before execution.
+
+The value of this option is a function which is given a list
+containing the full command of a syntax checker after
+substitution through `flycheck-substitute-argument' but before
+execution. The function may return a new command for Flycheck to
+execute.
+
+The default value is `identity' which does not change the
+command. You may provide your own function to run Flycheck
+commands through `bundle exec', `nix-shell' or similar wrappers."
+ :group 'flycheck
+ :type '(choice (const :tag "Do not modify commands" identity)
+ (function :tag "Modify command with a custom function"))
+ :package-version '(flycheck . "0.25")
+ :risky t)
+
+(defcustom flycheck-executable-find #'flycheck-default-executable-find
+ "Function to search for executables.
+
+The value of this option is a function which is given the name or
+path of an executable and shall return the full path to the
+executable, or nil if the executable does not exit.
+
+The default is `flycheck-default-executable-find', which searches
+variable `exec-path' when given a command name, and resolves
+paths to absolute ones. You can customize this option to search
+for checkers in other environments such as bundle or NixOS
+sandboxes."
+ :group 'flycheck
+ :type '(choice
+ (const :tag "Search executables in `exec-path'"
+ flycheck-default-executable-find)
+ (function :tag "Search executables with a custom function"))
+ :package-version '(flycheck . "32")
+ :risky t)
+
+(defun flycheck-default-executable-find (executable)
+ "Resolve EXECUTABLE to a full path.
+
+Like `executable-find', but supports relative paths.
+
+Attempts invoking `executable-find' first; if that returns nil,
+and EXECUTABLE contains a directory component, expands to a full
+path and tries invoking `executable-find' again."
+ ;; file-name-directory returns non-nil iff the given path has a
+ ;; directory component.
+ (or
+ (executable-find executable)
+ (when (file-name-directory executable)
+ (executable-find (expand-file-name executable)))))
+
+(defcustom flycheck-indication-mode 'left-fringe
+ "The indication mode for Flycheck errors.
+
+This variable controls how Flycheck indicates errors in buffers.
+May be `left-fringe', `right-fringe', `left-margin',
+`right-margin', or nil.
+
+If set to `left-fringe' or `right-fringe', indicate errors via
+icons in the left and right fringe respectively. If set to
+`left-margin' or `right-margin', use the margins instead.
+
+If set to nil, do not indicate errors and warnings, but just
+highlight them according to `flycheck-highlighting-mode'."
+ :group 'flycheck
+ :type '(choice (const :tag "Indicate in the left fringe" left-fringe)
+ (const :tag "Indicate in the right fringe" right-fringe)
+ (const :tag "Indicate in the left margin" left-margin)
+ (const :tag "Indicate in the right margin" right-margin)
+ (const :tag "Do not indicate" nil))
+ :safe #'symbolp)
+
+(defcustom flycheck-highlighting-mode 'symbols
+ "The highlighting mode for Flycheck errors and warnings.
+
+The highlighting mode controls how Flycheck highlights errors in
+buffers when a checker only reports the starting position of an
+error. The following modes are known:
+
+`columns'
+ Highlight a single character. If the error does not have a column,
+ highlight the whole line.
+
+`symbols'
+ Highlight a full symbol if there is any, otherwise behave like `columns'.
+ This is the default.
+
+`sexps'
+ Highlight a full expression, if there is any, otherwise behave like
+ `columns'. Note that this mode can be *very* slow in some major modes.
+
+`lines'
+ Highlight the whole line.
+
+nil
+ Do not highlight errors at all. However, errors will still
+ be reported in the mode line and in error message popups,
+ and indicated according to `flycheck-indication-mode'."
+ :group 'flycheck
+ :type '(choice (const :tag "Highlight columns only" columns)
+ (const :tag "Highlight symbols" symbols)
+ (const :tag "Highlight expressions" sexps)
+ (const :tag "Highlight whole lines" lines)
+ (const :tag "Do not highlight errors" nil))
+ :package-version '(flycheck . "0.14")
+ :safe #'symbolp)
+
+(defvar flycheck-current-errors)
+(defun flycheck-refresh-fringes-and-margins ()
+ "Refresh fringes and margins of all windows displaying the current buffer.
+
+If any errors are currently shown, launch a new check, to adjust
+to a potential new indication mode."
+ (dolist (win (get-buffer-window-list))
+ (set-window-margins win left-margin-width right-margin-width)
+ (set-window-fringes win left-fringe-width right-fringe-width))
+ (when flycheck-current-errors
+ (flycheck-buffer)))
+
+(defun flycheck-set-indication-mode (&optional mode)
+ "Set `flycheck-indication-mode' to MODE and adjust margins and fringes.
+
+When MODE is nil, adjust window parameters without changing the
+mode. This function can be useful as a `flycheck-mode-hook',
+especially if you use margins only in Flycheck buffers.
+
+When MODE is `left-margin', the left fringe is reduced to 1 pixel
+to save space."
+ (interactive (list (intern (completing-read
+ "Mode: " '("left-fringe" "right-fringe"
+ "left-margin" "right-margin")
+ nil t nil nil
+ (prin1-to-string flycheck-indication-mode)))))
+ (setq mode (or mode flycheck-indication-mode))
+ (pcase mode
+ ((or `left-fringe `right-fringe)
+ (setq left-fringe-width 8 right-fringe-width 8
+ left-margin-width 0 right-margin-width 0))
+ (`left-margin
+ (setq left-fringe-width 1 right-fringe-width 8
+ left-margin-width 1 right-margin-width 0))
+ (`right-margin
+ (setq left-fringe-width 8 right-fringe-width 8
+ left-margin-width 0 right-margin-width 1))
+ (_ (user-error "Invalid indication mode")))
+ (setq-local flycheck-indication-mode mode)
+ (flycheck-refresh-fringes-and-margins))
+
+(define-widget 'flycheck-highlighting-style 'lazy
+ "A value for `flycheck-highlighting-style'."
+ :offset 2
+ :format "%t: Use %v"
+ :type '(choice
+ :format "%[Value Menu%] %v"
+ (const :tag "no highlighting" nil)
+ (const :tag "a face indicating the error level" level-face)
+ (list :tag "a pair of delimiters"
+ (const :format "" delimiters)
+ (string :tag "Before")
+ (string :tag "After"))
+ (list :tag "a conditional mix of styles"
+ (const :format "" conditional)
+ (integer :tag "Up to this many lines")
+ (flycheck-highlighting-style :format "Use %v")
+ (flycheck-highlighting-style :format "Otherwise, use %v"))))
+
+(defun flycheck--make-highlighting-delimiter (char)
+ "Make a highlighting bracket symbol by repeating CHAR twice."
+ (compose-chars ?\s
+ ;; '(Bl . Br) ?\s
+ '(Bc Br 30 0) char
+ '(Bc Bl -30 0) char))
+
+(defcustom flycheck-highlighting-style
+ `(conditional 4 level-face (delimiters "" ""))
+ "The highlighting style for Flycheck errors and warnings.
+
+The highlighting style controls how Flycheck highlights error
+regions in buffers. The following styles are supported:
+
+nil
+ Do not highlight errors. Same as setting
+ `flycheck-highlighting-mode' to nil.
+
+`level-face'
+ Chose a face depending on the severity of the error, and
+ apply it to the whole error text. See also the
+ `flycheck-define-error-level' and `flycheck-error',
+ `flycheck-warning', and `flycheck-info' faces.
+
+\(`delimiters' BEFORE AFTER)
+ Draw delimiters on each side of the error. BEFORE and AFTER
+ indicate which delimiters to use. If they are strings, they
+ are used as-is. If they are characters, they are repeated
+ twice and composed into a single character. Delimiters use
+ the fringe face corresponding to the severity of each error,
+ as well as the `flycheck-error-delimiter' face. Delimited
+ text has the `flycheck-delimited-error' face.
+
+\(`conditional' NLINES S1 S2)
+ Use style S1 for errors spanning up to NLINES lines, and
+ style S2 otherwise.
+
+See also `flycheck-highlighting-mode' and
+`flycheck-indication-mode'."
+ :group 'flycheck
+ :type 'flycheck-highlighting-style
+ :package-version '(flycheck . "32")
+ :safe t)
+
+(defcustom flycheck-check-syntax-automatically '(save
+ idle-change
+ new-line
+ mode-enabled)
+ "When Flycheck should check syntax automatically.
+
+This variable is a list of events that may trigger syntax checks.
+The following events are known:
+
+`save'
+ Check syntax immediately after the buffer was saved.
+
+`idle-change'
+ Check syntax a short time (see `flycheck-idle-change-delay')
+ after the last change to the buffer.
+
+`idle-buffer-switch'
+ Check syntax a short time (see `flycheck-idle-buffer-switch-delay')
+ after the user switches to a buffer.
+
+`new-line'
+ Check syntax immediately after a new line was inserted into
+ the buffer.
+
+`mode-enabled'
+ Check syntax immediately when variable `flycheck-mode' is
+ non-nil.
+
+Flycheck performs a syntax checks only on events, which are
+contained in this list. For instance, if the value of this
+variable is `(mode-enabled save)', Flycheck will only check if
+the mode is enabled or the buffer was saved, but never after
+changes to the buffer contents.
+
+If nil, never check syntax automatically. In this case, use
+`flycheck-buffer' to start a syntax check manually."
+ :group 'flycheck
+ :type '(set (const :tag "After the buffer was saved" save)
+ (const :tag "After the buffer was changed and idle" idle-change)
+ (const
+ :tag "After switching the current buffer" idle-buffer-switch)
+ (const :tag "After a new line was inserted" new-line)
+ (const :tag "After `flycheck-mode' was enabled" mode-enabled))
+ :package-version '(flycheck . "0.12")
+ :safe #'flycheck-symbol-list-p)
+
+(defcustom flycheck-idle-change-delay 0.5
+ "How many seconds to wait after a change before checking syntax.
+
+After the buffer was changed, Flycheck will wait as many seconds
+as the value of this variable before starting a syntax check. If
+the buffer is modified during this time, Flycheck will wait
+again.
+
+This variable has no effect, if `idle-change' is not contained in
+`flycheck-check-syntax-automatically'."
+ :group 'flycheck
+ :type 'number
+ :package-version '(flycheck . "0.13")
+ :safe #'numberp)
+
+(defcustom flycheck-idle-buffer-switch-delay 0.5
+ "How many seconds to wait after switching buffers before checking syntax.
+
+After the user switches to a new buffer, Flycheck will wait as
+many seconds as the value of this variable before starting a
+syntax check. If the user switches to another buffer during this
+time, whether a syntax check is still performed depends on the
+value of `flycheck-buffer-switch-check-intermediate-buffers'.
+
+This variable has no effect if `idle-buffer-switch' is not
+contained in `flycheck-check-syntax-automatically'."
+ :group 'flycheck
+ :type 'number
+ :package-version '(flycheck . "32")
+ :safe #'numberp)
+
+(defcustom flycheck-buffer-switch-check-intermediate-buffers nil
+ "Whether to check syntax in a buffer you only visit briefly.
+
+If nil, then when you switch to a buffer but switch to another
+buffer before the syntax check is performed, then the check is
+canceled. If non-nil, then syntax checks due to switching
+buffers are always performed. This only affects buffer switches
+that happen less than `flycheck-idle-buffer-switch-delay' seconds
+apart.
+
+This variable has no effect if `idle-buffer-switch' is not
+contained in `flycheck-check-syntax-automatically'."
+ :group 'flycheck
+ :type 'boolean
+ :package-version '(flycheck . "32")
+ :safe #'booleanp)
+
+(defcustom flycheck-standard-error-navigation t
+ "Whether to support error navigation with `next-error'.
+
+If non-nil, enable navigation of Flycheck errors with
+`next-error', `previous-error' and `first-error'. Otherwise,
+these functions just navigate errors from compilation modes.
+
+Flycheck error navigation with `flycheck-next-error',
+`flycheck-previous-error' and `flycheck-first-error' is always
+enabled, regardless of the value of this variable.
+
+Note that this setting only takes effect when variable
+`flycheck-mode' is non-nil. Changing it will not affect buffers
+where variable `flycheck-mode' is already non-nil."
+ :group 'flycheck
+ :type 'boolean
+ :package-version '(flycheck . "0.15")
+ :safe #'booleanp)
+
+(define-widget 'flycheck-minimum-level 'lazy
+ "A radio-type choice of minimum error levels.
+
+See `flycheck-navigation-minimum-level' and
+`flycheck-error-list-minimum-level'."
+ :type '(radio (const :tag "All locations" nil)
+ (const :tag "Informational messages" info)
+ (const :tag "Warnings" warning)
+ (const :tag "Errors" error)
+ (symbol :tag "Custom error level")))
+
+(defcustom flycheck-navigation-minimum-level nil
+ "The minimum level of errors to navigate.
+
+If set to an error level, only navigate errors whose error level
+is at least as severe as this one. If nil, navigate all errors."
+ :group 'flycheck
+ :type 'flycheck-minimum-level
+ :safe #'flycheck-error-level-p
+ :package-version '(flycheck . "0.21"))
+
+(defcustom flycheck-error-list-minimum-level nil
+ "The minimum level of errors to display in the error list.
+
+If set to an error level, only display errors whose error level
+is at least as severe as this one in the error list. If nil,
+display all errors.
+
+This is the default level, used when the error list is opened.
+You can temporarily change the level using
+\\[flycheck-error-list-set-filter], or reset it to this value
+using \\[flycheck-error-list-reset-filter]."
+ :group 'flycheck
+ :type 'flycheck-minimum-level
+ :safe #'flycheck-error-level-p
+ :package-version '(flycheck . "0.24"))
+
+(defcustom flycheck-relevant-error-other-file-minimum-level 'error
+ "The minimum level of errors from other files to display in this buffer.
+
+If set to an error level, only display errors from other files
+whose error level is at least as severe as this one. If nil,
+display all errors from other files."
+ :group 'flycheck
+ :type 'flycheck-minimum-level
+ :safe #'flycheck-error-level-p
+ :package-version '(flycheck . "32"))
+
+(defcustom flycheck-relevant-error-other-file-show t
+ "Whether to show errors from other files."
+ :group 'flycheck
+ :type 'boolean
+ :package-version '(flycheck . "32")
+ :safe #'booleanp)
+
+(defcustom flycheck-completing-read-function #'completing-read
+ "Function to read from minibuffer with completion.
+
+The function must be compatible to the built-in `completing-read'
+function."
+ :group 'flycheck
+ :type '(choice (const :tag "Default" completing-read)
+ (const :tag "IDO" ido-completing-read)
+ (function :tag "Custom function"))
+ :risky t
+ :package-version '(flycheck . "26"))
+
+(defcustom flycheck-temp-prefix "flycheck"
+ "Prefix for temporary files created by Flycheck."
+ :group 'flycheck
+ :type 'string
+ :package-version '(flycheck . "0.19")
+ :risky t)
+
+(defcustom flycheck-mode-hook nil
+ "Hooks to run after command `flycheck-mode' is toggled."
+ :group 'flycheck
+ :type 'hook
+ :risky t)
+
+(defcustom flycheck-after-syntax-check-hook nil
+ "Functions to run after each syntax check.
+
+This hook is run after a syntax check was finished.
+
+At this point, *all* chained checkers were run, and all errors
+were parsed, highlighted and reported. The variable
+`flycheck-current-errors' contains all errors from all syntax
+checkers run during the syntax check, so you can apply any error
+analysis functions.
+
+Note that this hook does *not* run after each individual syntax
+checker in the syntax checker chain, but only after the *last
+checker*.
+
+This variable is a normal hook. See Info node `(elisp)Hooks'."
+ :group 'flycheck
+ :type 'hook
+ :risky t)
+
+(defcustom flycheck-before-syntax-check-hook nil
+ "Functions to run before each syntax check.
+
+This hook is run right before a syntax check starts.
+
+Error information from the previous syntax check is *not*
+cleared before this hook runs.
+
+Note that this hook does *not* run before each individual syntax
+checker in the syntax checker chain, but only before the *first
+checker*.
+
+This variable is a normal hook. See Info node `(elisp)Hooks'."
+ :group 'flycheck
+ :type 'hook
+ :risky t)
+
+(defcustom flycheck-syntax-check-failed-hook nil
+ "Functions to run if a syntax check failed.
+
+This hook is run whenever an error occurs during Flycheck's
+internal processing. No information about the error is given to
+this hook.
+
+You should use this hook to conduct additional cleanup actions
+when Flycheck failed.
+
+This variable is a normal hook. See Info node `(elisp)Hooks'."
+ :group 'flycheck
+ :type 'hook
+ :risky t)
+
+(defcustom flycheck-status-changed-functions nil
+ "Functions to run if the Flycheck status changed.
+
+This hook is run whenever the status of Flycheck changes. Each
+hook function takes the status symbol as single argument, as
+given to `flycheck-report-status', which see.
+
+This variable is an abnormal hook. See Info
+node `(elisp)Hooks'."
+ :group 'flycheck
+ :type 'hook
+ :risky t
+ :package-version '(flycheck . "0.20"))
+
+(defcustom flycheck-error-list-after-refresh-hook nil
+ "Functions to run after the error list was refreshed.
+
+This hook is run whenever the error list is refreshed.
+
+This variable is a normal hook. See Info node `(elisp)Hooks'."
+ :group 'flycheck
+ :type 'hook
+ :risky t
+ :package-version '(flycheck . "0.21"))
+
+(defface flycheck-error-delimiter
+ `((t))
+ "Flycheck face for errors spanning multiple lines.
+
+See `flycheck-highlighting-style' for details on when this face
+is used."
+ :package-version '(flycheck . "32")
+ :group 'flycheck-faces)
+
+(defface flycheck-delimited-error
+ `((t))
+ "Flycheck face for errors spanning multiple lines.
+
+See `flycheck-highlighting-style' for details on when this face
+is used."
+ :package-version '(flycheck . "32")
+ :group 'flycheck-faces)
+
+(defface flycheck-error
+ '((((supports :underline (:style wave)))
+ :underline (:style wave :color "Red1"))
+ (t
+ :underline t :inherit error))
+ "Flycheck face for errors."
+ :package-version '(flycheck . "0.13")
+ :group 'flycheck-faces)
+
+(defface flycheck-warning
+ '((((supports :underline (:style wave)))
+ :underline (:style wave :color "DarkOrange"))
+ (t
+ :underline t :inherit warning))
+ "Flycheck face for warnings."
+ :package-version '(flycheck . "0.13")
+ :group 'flycheck-faces)
+
+(defface flycheck-info
+ '((((supports :underline (:style wave)))
+ :underline (:style wave :color "ForestGreen"))
+ (t
+ :underline t :inherit success))
+ "Flycheck face for informational messages."
+ :package-version '(flycheck . "0.15")
+ :group 'flycheck-faces)
+
+(defface flycheck-fringe-error
+ '((t :inherit error))
+ "Flycheck face for fringe error indicators."
+ :package-version '(flycheck . "0.13")
+ :group 'flycheck-faces)
+
+(defface flycheck-fringe-warning
+ '((t :inherit warning))
+ "Flycheck face for fringe warning indicators."
+ :package-version '(flycheck . "0.13")
+ :group 'flycheck-faces)
+
+(defface flycheck-fringe-info
+ ;; Semantically `success' is probably not the right face, but it looks nice as
+ ;; a base face
+ '((t :inherit success))
+ "Flycheck face for fringe info indicators."
+ :package-version '(flycheck . "0.15")
+ :group 'flycheck-faces)
+
+(defface flycheck-error-list-error
+ '((t :inherit error))
+ "Flycheck face for error messages in the error list."
+ :package-version '(flycheck . "0.16")
+ :group 'flycheck-faces)
+
+(defface flycheck-error-list-warning
+ '((t :inherit warning))
+ "Flycheck face for warning messages in the error list."
+ :package-version '(flycheck . "0.16")
+ :group 'flycheck-faces)
+
+(defface flycheck-error-list-info
+ '((t :inherit success))
+ "Flycheck face for info messages in the error list."
+ :package-version '(flycheck . "0.16")
+ :group 'flycheck-faces)
+
+(defface flycheck-error-list-line-number
+ '((t))
+ "Face for line numbers in the error list."
+ :group 'flycheck-faces
+ :package-version '(flycheck . "0.16"))
+
+(defface flycheck-error-list-column-number
+ '((t))
+ "Face for line numbers in the error list."
+ :group 'flycheck-faces
+ :package-version '(flycheck . "0.16"))
+
+(defface flycheck-error-list-filename
+ '((t :inherit mode-line-buffer-id :bold nil))
+ "Face for filenames in the error list."
+ :group 'flycheck-faces
+ :package-version '(flycheck . "32"))
+
+(defface flycheck-error-list-id
+ '((t :inherit font-lock-type-face))
+ "Face for the error ID in the error list."
+ :group 'flycheck-faces
+ :package-version '(flycheck . "0.22"))
+
+(defface flycheck-error-list-id-with-explainer
+ '((t :inherit flycheck-error-list-id
+ :box (:style released-button)))
+ "Face for the error ID in the error list, for errors that have an explainer."
+ :group 'flycheck-faces
+ :package-version '(flycheck . "30"))
+
+(defface flycheck-error-list-checker-name
+ '((t :inherit font-lock-function-name-face))
+ "Face for the syntax checker name in the error list."
+ :group 'flycheck-faces
+ :package-version '(flycheck . "0.21"))
+
+(defface flycheck-error-list-error-message
+ '((t))
+ "Face for the error message in the error list."
+ :group 'flycheck-faces
+ :package-version '(flycheck . "33"))
+
+(defface flycheck-error-list-highlight
+ '((t :bold t))
+ "Flycheck face to highlight errors in the error list."
+ :package-version '(flycheck . "0.15")
+ :group 'flycheck-faces)
+
+(defface flycheck-verify-select-checker
+ '((t :box (:style released-button)))
+ "Flycheck face for the 'select' button in the verify setup buffer."
+ :package-version '(flycheck . "32")
+ :group 'flycheck-faces)
+
+(defvar flycheck-command-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map "c" #'flycheck-buffer)
+ (define-key map "C" #'flycheck-clear)
+ (define-key map (kbd "C-c") #'flycheck-compile)
+ (define-key map "n" #'flycheck-next-error)
+ (define-key map "p" #'flycheck-previous-error)
+ (define-key map "l" #'flycheck-list-errors)
+ (define-key map (kbd "C-w") #'flycheck-copy-errors-as-kill)
+ (define-key map "s" #'flycheck-select-checker)
+ (define-key map "?" #'flycheck-describe-checker)
+ (define-key map "h" #'flycheck-display-error-at-point)
+ (define-key map "e" #'flycheck-explain-error-at-point)
+ (define-key map "H" #'display-local-help)
+ (define-key map "i" #'flycheck-manual)
+ (define-key map "V" #'flycheck-version)
+ (define-key map "v" #'flycheck-verify-setup)
+ (define-key map "x" #'flycheck-disable-checker)
+ map)
+ "Keymap of Flycheck interactive commands.")
+
+(defcustom flycheck-keymap-prefix (kbd "C-c !")
+ "Prefix for key bindings of Flycheck.
+
+Changing this variable outside Customize does not have any
+effect. To change the keymap prefix from Lisp, you need to
+explicitly re-define the prefix key:
+
+ (define-key flycheck-mode-map flycheck-keymap-prefix nil)
+ (setq flycheck-keymap-prefix (kbd \"C-c f\"))
+ (define-key flycheck-mode-map flycheck-keymap-prefix
+ flycheck-command-map)
+
+Please note that Flycheck's manual documents the default
+keybindings. Changing this variable is at your own risk."
+ :group 'flycheck
+ :package-version '(flycheck . "0.19")
+ :type 'string
+ :risky t
+ :set
+ (lambda (variable key)
+ (when (and (boundp variable) (boundp 'flycheck-mode-map))
+ (define-key flycheck-mode-map (symbol-value variable) nil)
+ (define-key flycheck-mode-map key flycheck-command-map))
+ (set-default variable key)))
+
+(defcustom flycheck-mode-line '(:eval (flycheck-mode-line-status-text))
+ "Mode line lighter for Flycheck.
+
+The value of this variable is a mode line template as in
+`mode-line-format'. See Info Node `(elisp)Mode Line Format' for
+more information. Note that it should contain a _single_ mode
+line construct only.
+
+Customize this variable to change how Flycheck reports its status
+in the mode line. You may use `flycheck-mode-line-status-text'
+to obtain a human-readable status text, including an
+error/warning count.
+
+You may also assemble your own status text. The current status
+of Flycheck is available in `flycheck-last-status-change'. The
+errors in the current buffer are stored in
+`flycheck-current-errors', and the function
+`flycheck-count-errors' may be used to obtain the number of
+errors grouped by error level.
+
+Set this variable to nil to disable the mode line completely."
+ :group 'flycheck
+ :type 'sexp
+ :risky t
+ :package-version '(flycheck . "0.20"))
+
+(defcustom flycheck-mode-line-prefix "FlyC"
+ "Base mode line lighter for Flycheck.
+
+This will have an effect only with the default
+`flycheck-mode-line'.
+
+If you've customized `flycheck-mode-line' then the customized
+function must be updated to use this variable."
+ :group 'flycheck
+ :type 'string
+ :package-version '(flycheck . "26"))
+
+(defcustom flycheck-error-list-mode-line
+ `(,(propertized-buffer-identification "%12b")
+ " for buffer "
+ (:eval (flycheck-error-list-propertized-source-name))
+ (:eval (flycheck-error-list-mode-line-filter-indicator)))
+ "Mode line construct for Flycheck error list.
+
+The value of this variable is a mode line template as in
+`mode-line-format', to be used as
+`mode-line-buffer-identification' in `flycheck-error-list-mode'.
+See Info Node `(elisp)Mode Line Format' for more information.
+
+Customize this variable to change how the error list appears in
+the mode line. The default shows the name of the buffer and the
+name of the source buffer, i.e. the buffer whose errors are
+currently listed."
+ :group 'flycheck
+ :type 'sexp
+ :risky t
+ :package-version '(flycheck . "0.20"))
+
+(defcustom flycheck-global-modes t
+ "Modes for which option `flycheck-mode' is turned on.
+
+If t, Flycheck Mode is turned on for all major modes. If a list,
+Flycheck Mode is turned on for all `major-mode' symbols in that
+list. If the `car' of the list is `not', Flycheck Mode is turned
+on for all `major-mode' symbols _not_ in that list. If nil,
+Flycheck Mode is never turned on by command
+`global-flycheck-mode'.
+
+Note that Flycheck is never turned on for modes whose
+`mode-class' property is `special' (see Info node `(elisp)Major
+Mode Conventions'), regardless of the value of this option.
+
+Only has effect when variable `global-flycheck-mode' is non-nil."
+ :group 'flycheck
+ :type '(choice (const :tag "none" nil)
+ (const :tag "all" t)
+ (set :menu-tag "mode specific" :tag "modes"
+ :value (not)
+ (const :tag "Except" not)
+ (repeat :inline t (symbol :tag "mode"))))
+ :risky t
+ :package-version '(flycheck . "0.23"))
+
+;; Add built-in functions to our hooks, via `add-hook', to make sure that our
+;; functions are really present, even if the variable was implicitly defined by
+;; another call to `add-hook' that occurred before Flycheck was loaded. See
+;; http://lists.gnu.org/archive/html/emacs-devel/2015-02/msg01271.html for why
+;; we don't initialize the hook variables right away. We append our own
+;; functions, because a user likely expects that their functions come first,
+;; even if they added them before Flycheck was loaded.
+(dolist (hook (list #'flycheck-locate-config-file-by-path
+ #'flycheck-locate-config-file-ancestor-directories
+ #'flycheck-locate-config-file-home))
+ (add-hook 'flycheck-locate-config-file-functions hook 'append))
+
+(add-hook 'flycheck-process-error-functions #'flycheck-add-overlay 'append)
+
+
+;;; Global Flycheck menu
+(defvar flycheck-mode-menu-map
+ (easy-menu-create-menu
+ "Syntax Checking"
+ '(["Enable on-the-fly syntax checking" flycheck-mode
+ :style toggle :selected flycheck-mode
+ :enable (or flycheck-mode
+ ;; Don't let users toggle the mode if there is no syntax
+ ;; checker for this buffer
+ (seq-find #'flycheck-checker-supports-major-mode-p
+ flycheck-checkers))]
+ ["Check current buffer" flycheck-buffer flycheck-mode]
+ ["Clear errors in buffer" flycheck-clear t]
+ "---"
+ ["Go to next error" flycheck-next-error flycheck-mode]
+ ["Go to previous error" flycheck-previous-error flycheck-mode]
+ ["Show all errors" flycheck-list-errors flycheck-mode]
+ "---"
+ ["Copy messages at point" flycheck-copy-errors-as-kill
+ (flycheck-overlays-at (point))]
+ ["Explain error at point" flycheck-explain-error-at-point]
+ "---"
+ ["Select syntax checker" flycheck-select-checker flycheck-mode]
+ ["Disable syntax checker" flycheck-disable-checker flycheck-mode]
+ ["Set executable of syntax checker" flycheck-set-checker-executable
+ flycheck-mode]
+ "---"
+ ["Describe syntax checker" flycheck-describe-checker t]
+ ["Verify setup" flycheck-verify-setup t]
+ ["Show Flycheck version" flycheck-version t]
+ ["Read the Flycheck manual" flycheck-info t]))
+ "Menu of command `flycheck-mode'.")
+
+(easy-menu-add-item nil '("Tools") flycheck-mode-menu-map "Spell Checking")
+
+
+;;; Version information, manual and loading of Flycheck
+(defun flycheck-version (&optional show-version)
+ "Get the Flycheck version as string.
+
+If called interactively or if SHOW-VERSION is non-nil, show the
+version in the echo area and the messages buffer.
+
+The returned string includes both, the version from package.el
+and the library version, if both a present and different.
+
+If the version number could not be determined, signal an error,
+if called interactively, or if SHOW-VERSION is non-nil, otherwise
+just return nil."
+ (interactive (list t))
+ (let ((version (pkg-info-version-info 'flycheck)))
+ (when show-version
+ (message "Flycheck version: %s" version))
+ version))
+
+(defun flycheck-unload-function ()
+ "Unload function for Flycheck."
+ (global-flycheck-mode -1)
+ (easy-menu-remove-item nil '("Tools") (cadr flycheck-mode-menu-map))
+ (remove-hook 'kill-emacs-hook #'flycheck-global-teardown)
+ (setq find-function-regexp-alist
+ (assq-delete-all 'flycheck-checker find-function-regexp-alist)))
+
+;;;###autoload
+(defun flycheck-manual ()
+ "Open the Flycheck manual."
+ (interactive)
+ (browse-url "http://www.flycheck.org"))
+
+(define-obsolete-function-alias 'flycheck-info
+ 'flycheck-manual "Flycheck 26" "Open the Flycheck manual.")
+
+
+;;; Utility functions
+(defun flycheck-sexp-to-string (sexp)
+ "Convert SEXP to a string.
+
+Like `prin1-to-string' but ensure that the returned string
+is loadable."
+ (let ((print-quoted t)
+ (print-length nil)
+ (print-level nil))
+ (prin1-to-string sexp)))
+
+(defun flycheck-string-to-number-safe (string)
+ "Safely convert STRING to a number.
+
+If STRING is of string type and a numeric string, convert STRING
+to a number and return it. Otherwise return nil."
+ (let ((number-re (rx string-start (one-or-more (any digit)) string-end)))
+ (when (and (stringp string) (string-match-p number-re string))
+ (string-to-number string))))
+
+(defun flycheck-string-or-nil-p (obj)
+ "Determine if OBJ is a string or nil."
+ (or (null obj) (stringp obj)))
+
+(defun flycheck-string-list-p (obj)
+ "Determine if OBJ is a list of strings."
+ (and (listp obj) (seq-every-p #'stringp obj)))
+
+(defun flycheck-string-or-string-list-p (obj)
+ "Determine if OBJ is a string or a list of strings."
+ (or (stringp obj) (flycheck-string-list-p obj)))
+
+(defun flycheck-symbol-list-p (obj)
+ "Determine if OBJ is a list of symbols."
+ (and (listp obj) (seq-every-p #'symbolp obj)))
+
+(defvar-local flycheck--file-truename-cache nil)
+
+(defun flycheck--file-truename (file)
+ "Memoize the result of `file-truename' on (directory-file-name FILE)."
+ ;; `file-truename' is slow, but alternatives are incomplete, so memoizing is
+ ;; our best bet. See https://github.com/flycheck/flycheck/pull/1698.
+ (unless flycheck--file-truename-cache
+ (setq-local flycheck--file-truename-cache (make-hash-table :test 'equal)))
+ (or (gethash file flycheck--file-truename-cache)
+ (puthash file (file-truename (directory-file-name file))
+ flycheck--file-truename-cache)))
+
+(defun flycheck-same-files-p (file-a file-b)
+ "Determine whether FILE-A and FILE-B refer to the same file.
+
+Files are the same if (in the order checked) they are equal, or
+if they resolve to the same canonical paths."
+ (or (string= file-a file-b)
+ (string= (flycheck--file-truename file-a)
+ (flycheck--file-truename file-b))))
+
+(defvar-local flycheck-temporaries nil
+ "Temporary files and directories created by Flycheck.")
+
+(defun flycheck-temp-dir-system ()
+ "Create a unique temporary directory.
+
+Use `flycheck-temp-prefix' as prefix, and add the directory to
+`flycheck-temporaries'.
+
+Return the path of the directory"
+ (let* ((tempdir (make-temp-file flycheck-temp-prefix 'directory)))
+ (push tempdir flycheck-temporaries)
+ tempdir))
+
+(defun flycheck-temp-file-system (filename &optional suffix)
+ "Create a temporary file named after FILENAME.
+
+If FILENAME is non-nil, this function creates a temporary
+directory with `flycheck-temp-dir-system', and creates a file
+with the same name as FILENAME in this directory.
+
+Otherwise this function creates a temporary file starting with
+`flycheck-temp-prefix'. If present, SUFFIX is appended;
+otherwise, a random suffix is used. The path of the file is
+added to `flycheck-temporaries'.
+
+Return the path of the file."
+ (let ((tempfile (convert-standard-filename
+ (if filename
+ (expand-file-name (file-name-nondirectory filename)
+ (flycheck-temp-dir-system))
+ (make-temp-file flycheck-temp-prefix nil suffix)))))
+ (push tempfile flycheck-temporaries)
+ tempfile))
+
+(defun flycheck-temp-file-inplace (filename &optional suffix)
+ "Create an in-place copy of FILENAME.
+
+Prefix the file with `flycheck-temp-prefix' and add the path of
+the file to `flycheck-temporaries'.
+
+If FILENAME is nil, fall back to `flycheck-temp-file-system' with
+the specified SUFFIX.
+
+Return the path of the file."
+ (if filename
+ (let* ((tempname (format "%s_%s"
+ flycheck-temp-prefix
+ (file-name-nondirectory filename)))
+ (tempfile (convert-standard-filename
+ (expand-file-name tempname
+ (file-name-directory filename)))))
+ (push tempfile flycheck-temporaries)
+ tempfile)
+ (flycheck-temp-file-system filename suffix)))
+
+(defun flycheck-temp-directory (checker)
+ "Return the directory where CHECKER writes temporary files.
+
+Return nil if the CHECKER does not write temporary files."
+ (let ((args (flycheck-checker-arguments checker)))
+ (cond
+ ((memq 'source args) temporary-file-directory)
+ ((memq 'source-inplace args)
+ (if buffer-file-name (file-name-directory buffer-file-name)
+ temporary-file-directory))
+ (t nil))))
+
+(defun flycheck-temp-files-writable-p (checker)
+ "Whether CHECKER can write temporary files.
+
+If CHECKER has `source' or `source-inplace' in its `:command',
+return whether flycheck has the permissions to create the
+respective temporary files.
+
+Return t if CHECKER does not use temporary files."
+ (let ((dir (flycheck-temp-directory checker)))
+ (or (not dir) (file-writable-p dir))))
+
+(defun flycheck-save-buffer-to-file (file-name)
+ "Save the contents of the current buffer to FILE-NAME."
+ (make-directory (file-name-directory file-name) t)
+ (let ((jka-compr-inhibit t))
+ (write-region nil nil file-name nil 0)))
+
+(defun flycheck-save-buffer-to-temp (temp-file-fn)
+ "Save buffer to temp file returned by TEMP-FILE-FN.
+
+Return the name of the temporary file."
+ (let ((filename (funcall temp-file-fn (buffer-file-name))))
+ ;; Do not flush short-lived temporary files onto disk
+ (let ((write-region-inhibit-fsync t))
+ (flycheck-save-buffer-to-file filename))
+ filename))
+
+(defun flycheck-prepend-with-option (option items &optional prepend-fn)
+ "Prepend OPTION to each item in ITEMS, using PREPEND-FN.
+
+Prepend OPTION to each item in ITEMS.
+
+ITEMS is a list of strings to pass to the syntax checker. OPTION
+is the option, as string. PREPEND-FN is a function called to
+prepend OPTION to each item in ITEMS. It receives the option and
+a single item from ITEMS as argument, and must return a string or
+a list of strings with OPTION prepended to the item. If
+PREPEND-FN is nil or omitted, use `list'.
+
+Return a list of strings where OPTION is prepended to each item
+in ITEMS using PREPEND-FN. If PREPEND-FN returns a list, it is
+spliced into the resulting list."
+ (unless (stringp option)
+ (error "Option %S is not a string" option))
+ (unless prepend-fn
+ (setq prepend-fn #'list))
+ (let ((prepend
+ (lambda (item)
+ (let ((result (funcall prepend-fn option item)))
+ (cond
+ ((and (listp result) (seq-every-p #'stringp result)) result)
+ ((stringp result) (list result))
+ (t (error "Invalid result type for option: %S" result)))))))
+ (apply #'append (seq-map prepend items))))
+
+(defun flycheck-find-in-buffer (pattern)
+ "Find PATTERN in the current buffer.
+
+Return the result of the first matching group of PATTERN, or nil,
+if PATTERN did not match."
+ (save-excursion
+ (save-restriction
+ (widen)
+ (goto-char (point-min))
+ (when (re-search-forward pattern nil 'no-error)
+ (match-string-no-properties 1)))))
+
+(defun flycheck-buffer-empty-p (&optional buffer)
+ "Check whether a BUFFER is empty, defaulting to the current one."
+ (= (buffer-size buffer) 0))
+
+(defun flycheck-buffer-nonempty-p (&optional buffer)
+ "Check whether a BUFFER is nonempty, defaulting to the current one."
+ (> (buffer-size buffer) 0))
+
+(defun flycheck-ephemeral-buffer-p ()
+ "Determine whether the current buffer is an ephemeral buffer.
+
+See Info node `(elisp)Buffer Names' for information about
+ephemeral buffers."
+ (string-prefix-p " " (buffer-name)))
+
+(defun flycheck-encrypted-buffer-p ()
+ "Determine whether the current buffer is an encrypted file.
+
+See Info node `(epa)Top' for Emacs' interface to encrypted
+files."
+ ;; The EPA file handler sets this variable locally to remember the recipients
+ ;; of the encrypted file for re-encryption. Hence, a local binding of this
+ ;; variable is a good indication that the buffer is encrypted. I haven't
+ ;; found any better indicator anyway.
+ (local-variable-p 'epa-file-encrypt-to))
+
+(defun flycheck-autoloads-file-p ()
+ "Determine whether the current buffer is an autoloads file.
+
+Autoloads are generated by package.el during installation."
+ (string-suffix-p "-autoloads.el" (buffer-name)))
+
+(defun flycheck-in-user-emacs-directory-p (filename)
+ "Whether FILENAME is in `user-emacs-directory'."
+ (string-prefix-p (file-name-as-directory
+ (flycheck--file-truename user-emacs-directory))
+ (flycheck--file-truename filename)))
+
+(defun flycheck-safe-delete (file-or-dir)
+ "Safely delete FILE-OR-DIR."
+ (ignore-errors
+ (if (file-directory-p file-or-dir)
+ (delete-directory file-or-dir 'recursive)
+ (delete-file file-or-dir))))
+
+(defun flycheck-safe-delete-temporaries ()
+ "Safely delete all temp files and directories of Flycheck.
+
+Safely delete all files and directories listed in
+`flycheck-temporaries' and set the variable's value to nil."
+ (seq-do #'flycheck-safe-delete flycheck-temporaries)
+ (setq flycheck-temporaries nil))
+
+(defun flycheck-rx-file-name (form)
+ "Translate the `(file-name)' FORM into a regular expression."
+ (let ((body (or (cdr form) '((minimal-match
+ (one-or-more not-newline))))))
+ (rx-to-string `(group-n 1 ,@body) t)))
+
+(defun flycheck-rx-message (form)
+ "Translate the `(message)' FORM into a regular expression."
+ (let ((body (or (cdr form) '((one-or-more not-newline)))))
+ (rx-to-string `(group-n 4 ,@body) t)))
+
+(defun flycheck-rx-id (form)
+ "Translate the `(id)' FORM into a regular expression."
+ (rx-to-string `(group-n 5 ,@(cdr form)) t))
+
+(defun flycheck-rx-to-string (form &optional no-group)
+ "Like `rx-to-string' for FORM, but with special keywords:
+
+`line'
+ matches the initial line number.
+
+`column'
+ matches the initial column number.
+
+`end-line'
+ matches the final line number.
+
+`end-column'
+ matches the final column number (exclusive).
+
+
+`(file-name SEXP ...)'
+ matches the file name. SEXP describes the file name. If no
+ SEXP is given, use a default body of `(minimal-match
+ (one-or-more not-newline))'.
+
+`(message SEXP ...)'
+ matches the message. SEXP constitutes the body of the
+ message. If no SEXP is given, use a default body
+ of `(one-or-more not-newline)'.
+
+`(id SEXP ...)'
+ matches an error ID. SEXP describes the ID.
+
+NO-GROUP is passed to `rx-to-string'.
+
+See `rx' for a complete list of all built-in `rx' forms."
+ (let ((rx-constituents
+ (append
+ `((file-name flycheck-rx-file-name 0 nil) ;; group 1
+ (line . ,(rx (group-n 2 (one-or-more digit))))
+ (column . ,(rx (group-n 3 (one-or-more digit))))
+ (message flycheck-rx-message 0 nil) ;; group 4
+ (id flycheck-rx-id 0 nil) ;; group 5
+ (end-line . ,(rx (group-n 6 (one-or-more digit))))
+ (end-column . ,(rx (group-n 7 (one-or-more digit)))))
+ rx-constituents nil)))
+ (rx-to-string form no-group)))
+
+(defun flycheck-current-load-file ()
+ "Get the source file currently being loaded.
+
+Always return the name of the corresponding source file, never
+any byte-compiled file.
+
+Return nil, if the currently loaded file cannot be determined."
+ (-when-let* ((this-file (cond
+ (load-in-progress load-file-name)
+ ((bound-and-true-p byte-compile-current-file))
+ (t (buffer-file-name))))
+ ;; A best guess for the source file of a compiled library. Works
+ ;; well in most cases, and especially for ELPA packages
+ (source-file (concat (file-name-sans-extension this-file)
+ ".el")))
+ (when (file-exists-p source-file)
+ source-file)))
+
+(defun flycheck-module-root-directory (module &optional file-name)
+ "Get the root directory for a MODULE in FILE-NAME.
+
+MODULE is a qualified module name, either a string with
+components separated by a dot, or as list of components.
+FILE-NAME is the name of the file or directory containing the
+module as string. When nil or omitted, defaults to the return
+value of function `buffer-file-name'.
+
+Return the root directory of the module, that is, the directory,
+from which FILE-NAME can be reached by descending directories
+along each part of MODULE.
+
+If the MODULE name does not match the directory hierarchy upwards
+from FILE-NAME, return the directory containing FILE-NAME. When
+FILE-NAME is nil, return `default-directory'."
+ (let ((file-name (or file-name (buffer-file-name)))
+ (module-components (if (stringp module)
+ (split-string module (rx "."))
+ (copy-sequence module))))
+ (if (and module-components file-name)
+ (let ((parts (nreverse module-components))
+ (base-directory (directory-file-name
+ (file-name-sans-extension file-name))))
+ (while (and parts
+ (string= (file-name-nondirectory base-directory)
+ (car parts)))
+ (pop parts)
+ (setq base-directory (directory-file-name
+ (file-name-directory base-directory))))
+ (file-name-as-directory base-directory))
+ (if file-name
+ (file-name-directory file-name)
+ (expand-file-name default-directory)))))
+
+(cl-defstruct (flycheck-line-cache
+ (:constructor flycheck-line-cache-new))
+ "Cache structure used to speed up `flycheck-goto-line'."
+ tick point line)
+
+(defvar-local flycheck--line-cache nil
+ "Cache used to speed ip `flycheck-goto-line'.")
+
+(defsubst flycheck--init-line-cache ()
+ "Initialize or reinitialize `flycheck--line-cache'."
+ (let ((tick (buffer-modified-tick)))
+ (if flycheck--line-cache
+ (unless (= (flycheck-line-cache-tick flycheck--line-cache) tick)
+ (setf (flycheck-line-cache-tick flycheck--line-cache) tick
+ (flycheck-line-cache-point flycheck--line-cache) 1
+ (flycheck-line-cache-line flycheck--line-cache) 1))
+ (setq-local flycheck--line-cache
+ (flycheck-line-cache-new :tick tick :point 1 :line 1)))))
+
+(defun flycheck-goto-line (line)
+ "Move point to beginning of line number LINE.
+
+This function assumes that the current buffer is not narrowed."
+ (flycheck--init-line-cache)
+ (goto-char (flycheck-line-cache-point flycheck--line-cache))
+ (let ((delta (- line (flycheck-line-cache-line flycheck--line-cache))))
+ (when (= 0 (forward-line delta))
+ (setf (flycheck-line-cache-point flycheck--line-cache) (point))
+ (setf (flycheck-line-cache-line flycheck--line-cache) line))))
+
+(defun flycheck-line-column-to-position (line column)
+ "Return the point closest to LINE, COLUMN on line LINE.
+
+COLUMN is one-based."
+ (save-excursion
+ (flycheck-goto-line line)
+ (min (+ (point) (1- column)) (line-end-position))))
+
+(defun flycheck-line-column-at-point ()
+ "Return the line and column number at point."
+ (cons (line-number-at-pos) (1+ (- (point) (line-beginning-position)))))
+
+(defun flycheck-line-column-at-pos (pos)
+ "Return the line and column number at position POS.
+
+COLUMN is one-based."
+ (let ((inhibit-field-text-motion t))
+ (save-excursion
+ (goto-char pos)
+ (flycheck-line-column-at-point))))
+
+
+;;; Minibuffer tools
+(defvar flycheck-read-checker-history nil
+ "`completing-read' history of `flycheck-read-checker'.")
+
+(defun flycheck-completing-read (prompt candidates default &optional history)
+ "Read a value from the minibuffer.
+
+Use `flycheck-completing-read-function' to read input from the
+minibuffer with completion.
+
+Show PROMPT and read one of CANDIDATES, defaulting to DEFAULT.
+HISTORY is passed to `flycheck-completing-read-function'.
+
+Note that `flycheck-completing-read-function' may return an empty
+string instead of nil, even when \"\" isn't among the candidates.
+See `completing-read' for more details."
+ (funcall flycheck-completing-read-function
+ prompt candidates nil 'require-match nil history default))
+
+(defun flycheck-read-checker (prompt &optional default property candidates)
+ "Read a flycheck checker from minibuffer with PROMPT and DEFAULT.
+
+PROMPT is a string to show in the minibuffer as prompt. It
+should end with a single space. DEFAULT is a symbol denoting the
+default checker to use, if the user did not select any checker.
+PROPERTY is a symbol denoting a syntax checker property. If
+non-nil, only complete syntax checkers which have a non-nil value
+for PROPERTY. CANDIDATES is an optional list of all syntax
+checkers available for completion, defaulting to all defined
+checkers. If given, PROPERTY is ignored.
+
+Return the checker as symbol, or DEFAULT if no checker was
+chosen. If DEFAULT is nil and no checker was chosen, signal a
+`user-error' if the underlying completion system does not provide
+a default on its own."
+ (when (and default (not (flycheck-valid-checker-p default)))
+ (error "%S is no valid Flycheck checker" default))
+ (let* ((candidates (seq-map #'symbol-name
+ (or candidates
+ (flycheck-defined-checkers property))))
+ (default (and default (symbol-name default)))
+ (input (flycheck-completing-read
+ prompt candidates default
+ 'flycheck-read-checker-history)))
+ (when (string-empty-p input)
+ (unless default
+ (user-error "No syntax checker selected"))
+ (setq input default))
+ (let ((checker (intern input)))
+ (unless (flycheck-valid-checker-p checker)
+ (error "%S is not a valid Flycheck syntax checker" checker))
+ checker)))
+
+(defun flycheck-read-error-level (prompt)
+ "Read an error level from the user with PROMPT.
+
+Only offers level for which errors currently exist, in addition
+to the default levels."
+ (let* ((levels (seq-map #'flycheck-error-level
+ (flycheck-error-list-current-errors)))
+ (levels-with-defaults (append '(info warning error) levels))
+ (uniq-levels (seq-uniq levels-with-defaults))
+ (level (flycheck-completing-read prompt uniq-levels nil)))
+ (when (string-empty-p level) (setq level nil))
+ (and level (intern level))))
+
+
+;;; Checker API
+(defun flycheck-defined-checkers (&optional property)
+ "Find all defined syntax checkers, optionally with PROPERTY.
+
+PROPERTY is a symbol. If given, only return syntax checkers with
+a non-nil value for PROPERTY.
+
+The returned list is sorted alphapetically by the symbol name of
+the syntax checkers."
+ (let (defined-checkers)
+ (mapatoms (lambda (symbol)
+ (when (and (flycheck-valid-checker-p symbol)
+ (or (null property)
+ (flycheck-checker-get symbol property)))
+ (push symbol defined-checkers))))
+ (sort defined-checkers #'string<)))
+
+(defun flycheck-registered-checker-p (checker)
+ "Determine whether CHECKER is registered.
+
+A checker is registered if it is contained in
+`flycheck-checkers'."
+ (and (flycheck-valid-checker-p checker)
+ (memq checker flycheck-checkers)))
+
+(defun flycheck-disabled-checker-p (checker)
+ "Determine whether CHECKER is disabled, manually or automatically."
+ (or (flycheck-manually-disabled-checker-p checker)
+ (flycheck-automatically-disabled-checker-p checker)))
+
+(defun flycheck-manually-disabled-checker-p (checker)
+ "Determine whether CHECKER has been manually disabled.
+
+A checker has been manually disabled if it is contained in
+`flycheck-disabled-checkers'."
+ (memq checker flycheck-disabled-checkers))
+
+(defun flycheck-automatically-disabled-checker-p (checker)
+ "Determine whether CHECKER has been automatically disabled.
+
+A checker has been automatically disabled if it is contained in
+`flycheck--automatically-disabled-checkers'."
+ (memq checker flycheck--automatically-disabled-checkers))
+
+
+;;; Generic syntax checkers
+(defconst flycheck-generic-checker-version 2
+ "The internal version of generic syntax checker declarations.
+
+Flycheck will not use syntax checkers whose generic version is
+less than this constant.")
+
+(defsubst flycheck--checker-property-name (property)
+ "Return the SYMBOL property for checker PROPERTY."
+ (intern (concat "flycheck-" (symbol-name property))))
+
+(defun flycheck-checker-get (checker property)
+ "Get the value of CHECKER's PROPERTY."
+ (get checker (flycheck--checker-property-name property)))
+
+(gv-define-setter flycheck-checker-get (value checker property)
+ `(setf (get ,checker (flycheck--checker-property-name ,property)) ,value))
+
+(defun flycheck-validate-next-checker (next &optional strict)
+ "Validate NEXT checker.
+
+With STRICT non-nil, also check whether the syntax checker and
+the error level in NEXT are valid. Otherwise just check whether
+these are symbols.
+
+Signal an error if NEXT is not a valid entry for
+`:next-checkers'."
+ (when (symbolp next)
+ (setq next (cons t next)))
+ (pcase next
+ (`(,level . ,checker)
+ (if strict
+ (progn
+ (unless (or (eq level t) (flycheck-error-level-p level))
+ (error "%S is not a valid Flycheck error level" level))
+ (unless (flycheck-valid-checker-p checker)
+ (error "%s is not a valid Flycheck syntax checker" checker)))
+ (unless (symbolp level)
+ (error "Error level %S must be a symbol" level))
+ (unless (symbolp checker)
+ (error "Checker %S must be a symbol" checker))))
+ (_ (error "%S must be a symbol or cons cell" next)))
+ t)
+
+(defun flycheck-define-generic-checker (symbol docstring &rest properties)
+ "Define SYMBOL as generic syntax checker.
+
+Any syntax checker defined with this macro is eligible for manual
+syntax checker selection with `flycheck-select-checker'. To make
+the new syntax checker available for automatic selection, it must
+be registered in `flycheck-checkers'.
+
+DOCSTRING is the documentation of the syntax checker, for
+`flycheck-describe-checker'. The following PROPERTIES constitute
+a generic syntax checker. Unless otherwise noted, all properties
+are mandatory.
+
+`:start FUNCTION'
+ A function to start the syntax checker.
+
+ FUNCTION shall take two arguments and return a context
+ object if the checker is started successfully. Otherwise it
+ shall signal an error.
+
+ The first argument is the syntax checker being started. The
+ second is a callback function to report state changes to
+ Flycheck. The callback takes two arguments STATUS DATA,
+ where STATUS is a symbol denoting the syntax checker status
+ and DATA an optional argument with additional data for the
+ status report. See `flycheck-report-buffer-checker-status'
+ for more information about STATUS and DATA.
+
+ FUNCTION may be synchronous or asynchronous, i.e. it may
+ call the given callback either immediately, or at some later
+ point (e.g. from a process sentinel).
+
+ A syntax checker _must_ call CALLBACK at least once with a
+ STATUS that finishes the current syntax checker. Otherwise
+ Flycheck gets stuck at the current syntax check with this
+ syntax checker.
+
+ The context object returned by FUNCTION is passed to
+ `:interrupt'.
+
+`:interrupt FUNCTION'
+ A function to interrupt the syntax check.
+
+ FUNCTION is called with the syntax checker and the context
+ object returned by the `:start' function and shall try to
+ interrupt the syntax check. The context may be nil, if the
+ syntax check is interrupted before actually started.
+ FUNCTION should handle this situation.
+
+ If it cannot interrupt the syntax check, it may either
+ signal an error or silently ignore the attempt to interrupt
+ the syntax checker, depending on the severity of the
+ situation.
+
+ If interrupting the syntax check failed, Flycheck will let
+ the syntax check continue, but ignore any status reports.
+ Notably, it won't highlight any errors reported by the
+ syntax check in the buffer.
+
+ This property is optional. If omitted, Flycheck won't
+ attempt to interrupt syntax checks with this syntax checker,
+ and simply ignore their results.
+
+`:print-doc FUNCTION'
+ A function to print additional documentation into the Help
+ buffer of this checker.
+
+ FUNCTION is called when creating the Help buffer for the
+ syntax checker, with the syntax checker as single argument,
+ after printing the name of the syntax checker and its modes
+ and predicate, but before printing DOCSTRING. It may insert
+ additional documentation into the current buffer.
+
+ The call occurs within `with-help-window'. Hence
+ `standard-output' points to the current buffer, so you may
+ use `princ' and friends to add content. Also, the current
+ buffer is put into Help mode afterwards, which automatically
+ turns symbols into references, if possible.
+
+ This property is optional. If omitted, no additional
+ documentation is printed for this syntax checker.
+
+:verify FUNCTION
+ A function to verify the checker for the current buffer.
+
+ FUNCTION is called with the syntax checker as single
+ argument, and shall return a list of
+ `flycheck-verification-result' objects indicating whether
+ the syntax checker could be used in the current buffer, and
+ highlighting potential setup problems.
+
+ This property is optional. If omitted, no additional
+ verification occurs for this syntax checker. It is however
+ absolutely recommended that you add a `:verify' function to
+ your syntax checker, because it will help users to spot
+ potential setup problems.
+
+`:modes MODES'
+ A major mode symbol or a list thereof, denoting major modes
+ to use this syntax checker in.
+
+ This syntax checker will only be used in buffers whose
+ `major-mode' is contained in MODES.
+
+ If `:predicate' is also given the syntax checker will only
+ be used in buffers for which the `:predicate' returns
+ non-nil.
+
+`:predicate FUNCTION'
+ A function to determine whether to use the syntax checker in
+ the current buffer.
+
+ FUNCTION is called without arguments and shall return
+ non-nil if this syntax checker shall be used to check the
+ current buffer. Otherwise it shall return nil.
+
+ If this checker has a `:working-directory' FUNCTION is
+ called with `default-directory' bound to the checker's
+ working directory.
+
+ FUNCTION is only called in matching major modes.
+
+ This property is optional.
+
+`:enabled FUNCTION'
+ A function to determine whether to use the syntax checker in
+ the current buffer.
+
+ This property behaves as `:predicate', except that it's only
+ called the first time a syntax checker is to be used in a buffer.
+
+ FUNCTION is called without arguments and shall return
+ non-nil if this syntax checker shall be used to check the
+ current buffer. Otherwise it shall return nil.
+
+ If FUNCTION returns a non-nil value the checker is put in a
+ whitelist in `flycheck--automatically-enabled-checkers' to
+ prevent further invocations of `:enabled'. Otherwise it is
+ disabled via `flycheck--automatically-disabled-checkers' to
+ prevent any further use of it.
+
+ If this checker has a `:working-directory' FUNCTION is
+ called with `default-directory' bound to the checker's
+ working directory.
+
+ FUNCTION is only called in matching major modes.
+
+ This property is optional.
+
+`:error-filter FUNCTION'
+ A function to filter the errors returned by this checker.
+
+ FUNCTION is called with the list of `flycheck-error' objects
+ returned by the syntax checker and shall return another list
+ of `flycheck-error' objects, which is considered the final
+ result of this syntax checker.
+
+ FUNCTION is free to add, remove or modify errors, whether in
+ place or by copying.
+
+ This property is optional. The default filter is
+ `identity'.
+
+`:error-explainer FUNCTION'
+ A function to return an explanation text for errors
+ generated by this checker.
+
+ FUNCTION is called with a `flycheck-error' object, in the
+ buffer of that error. It shall return an explanation
+ message for the error.
+
+ The message can take any of the following forms:
+ - A string, which will be displayed to the user
+ - A function (likely a closure), which will be called with
+ `standard-output' set to a `flycheck-explain-error-mode'
+ buffer, and should write to it.
+ - A cons `(url . ,URL), indicating that the explanation can
+ be found online at URL.
+ - nil if there is no explanation for this error.
+
+ If URL is provided by the checker, and cannot be composed
+ from other elements in the `flycheck-error' object, consider
+ passing the URL via text properties:
+
+ ;; During the error object creation
+ (put-text-property 0 1 'explainer-url .url .check_id)
+
+ ;; In the error-explainer FUNCTION
+ (let ((id (flycheck-error-id err)))
+ (and id `(url . ,(get-text-property 0 'explainer-url id))))
+
+ This property is optional.
+
+`:next-checkers NEXT-CHECKERS'
+ A list denoting syntax checkers to apply after this syntax
+ checker, in what we call \"chaining\" of syntax checkers.
+
+ Each ITEM is a cons cell `(LEVEL . CHECKER)'. CHECKER is a
+ syntax checker to run after this syntax checker. LEVEL is
+ an error level. CHECKER will only be used if there are no
+ current errors of at least LEVEL. LEVEL may also be t, in
+ which case CHECKER is used regardless of the current errors.
+
+ ITEM may also be a syntax checker symbol, which is
+ equivalent to `(t . ITEM)'.
+
+ Flycheck tries all items in order of declaration, and uses
+ the first whose LEVEL matches and whose CHECKER is
+ registered and can be used for the current buffer.
+
+ This feature is typically used to apply more than one syntax
+ checker to a buffer. For instance, you might first use a
+ compiler to check a buffer for syntax and type errors, and
+ then run a linting tool that checks for insecure code, or
+ questionable style.
+
+ This property is optional. If omitted, it defaults to the
+ nil, i.e. no other syntax checkers are applied after this
+ syntax checker.
+
+`:working-directory FUNCTION'
+ The value of `default-directory' when invoking `:start'.
+
+ FUNCTION is a function taking the syntax checker as sole
+ argument. It shall return the absolute path to an existing
+ directory to use as `default-directory' for `:start' or
+ nil to fall back to the `default-directory' of the current
+ buffer.
+
+ This property is optional. If omitted, invoke `:start'
+ from the `default-directory' of the buffer being checked.
+
+Signal an error, if any property has an invalid value."
+ (declare (indent 1)
+ (doc-string 2))
+ (let ((start (plist-get properties :start))
+ (interrupt (plist-get properties :interrupt))
+ (print-doc (plist-get properties :print-doc))
+ (modes (plist-get properties :modes))
+ (predicate (plist-get properties :predicate))
+ (verify (plist-get properties :verify))
+ (enabled (plist-get properties :enabled))
+ (filter (or (plist-get properties :error-filter) #'identity))
+ (explainer (plist-get properties :error-explainer))
+ (next-checkers (plist-get properties :next-checkers))
+ (file (flycheck-current-load-file))
+ (working-directory (plist-get properties :working-directory)))
+
+ (unless (listp modes)
+ (setq modes (list modes)))
+
+ (unless (functionp start)
+ (error ":start %S of syntax checker %s is not a function" start symbol))
+ (unless (or (null interrupt) (functionp interrupt))
+ (error ":interrupt %S of syntax checker %s is not a function"
+ interrupt symbol))
+ (unless (or (null print-doc) (functionp print-doc))
+ (error ":print-doc %S of syntax checker %s is not a function"
+ print-doc symbol))
+ (unless (or (null verify) (functionp verify))
+ (error ":verify %S of syntax checker %S is not a function"
+ verify symbol))
+ (unless (or (null enabled) (functionp enabled))
+ (error ":enabled %S of syntax checker %S is not a function"
+ enabled symbol))
+ (unless modes
+ (error "Missing :modes in syntax checker %s" symbol))
+ (dolist (mode modes)
+ (unless (symbolp mode)
+ (error "Invalid :modes %s in syntax checker %s, %s must be a symbol"
+ modes symbol mode)))
+ (unless (or (null predicate) (functionp predicate))
+ (error ":predicate %S of syntax checker %s is not a function"
+ predicate symbol))
+ (unless (functionp filter)
+ (error ":error-filter %S of syntax checker %s is not a function"
+ filter symbol))
+ (unless (or (null explainer) (functionp explainer))
+ (error ":error-explainer %S of syntax checker %S is not a function"
+ explainer symbol))
+ (dolist (checker next-checkers)
+ (flycheck-validate-next-checker checker))
+
+ (let ((real-predicate
+ (and predicate
+ (lambda ()
+ ;; Run predicate in the checker's default directory
+ (let ((default-directory
+ (flycheck-compute-working-directory symbol)))
+ (funcall predicate)))))
+ (real-enabled
+ (lambda ()
+ (if (flycheck-valid-checker-p symbol)
+ (or (null enabled)
+ ;; Run enabled in the checker's default directory
+ (let ((default-directory
+ (flycheck-compute-working-directory symbol)))
+ (funcall enabled)))
+ (lwarn 'flycheck
+ :warning "%S is no valid Flycheck syntax checker.
+Try to reinstall the package defining this syntax checker." symbol)
+ nil))))
+ (pcase-dolist (`(,prop . ,value)
+ `((start . ,start)
+ (interrupt . ,interrupt)
+ (print-doc . ,print-doc)
+ (modes . ,modes)
+ (predicate . ,real-predicate)
+ (verify . ,verify)
+ (enabled . ,real-enabled)
+ (error-filter . ,filter)
+ (error-explainer . ,explainer)
+ (next-checkers . ,next-checkers)
+ (documentation . ,docstring)
+ (file . ,file)
+ (working-directory . ,working-directory)))
+ (setf (flycheck-checker-get symbol prop) value)))
+
+ ;; Track the version, to avoid breakage if the internal format changes
+ (setf (flycheck-checker-get symbol 'generic-checker-version)
+ flycheck-generic-checker-version)))
+
+(defun flycheck-valid-checker-p (checker)
+ "Check whether a CHECKER is valid.
+
+A valid checker is a symbol defined as syntax checker with
+`flycheck-define-checker'."
+ (and (symbolp checker)
+ (= (or (get checker 'flycheck-generic-checker-version) 0)
+ flycheck-generic-checker-version)))
+
+(defun flycheck-checker-supports-major-mode-p (checker &optional mode)
+ "Whether CHECKER supports the given major MODE.
+
+CHECKER is a syntax checker symbol and MODE a major mode symbol.
+Look at the `modes' property of CHECKER to determine whether
+CHECKER supports buffers in the given major MODE.
+
+MODE defaults to the value of `major-mode' if omitted or nil.
+
+Return non-nil if CHECKER supports MODE and nil otherwise."
+ (let ((mode (or mode major-mode)))
+ (memq mode (flycheck-checker-get checker 'modes))))
+
+(define-obsolete-variable-alias 'flycheck-enabled-checkers
+ 'flycheck--automatically-enabled-checkers "32")
+
+(defvar flycheck--automatically-enabled-checkers nil
+ "Syntax checkers included in automatic selection.
+
+A list of Flycheck syntax checkers included in automatic
+selection for the current buffer.")
+(make-variable-buffer-local 'flycheck--automatically-enabled-checkers)
+
+(defun flycheck-may-enable-checker (checker)
+ "Whether a generic CHECKER may be enabled for current buffer.
+
+Return non-nil if CHECKER may be used for the current buffer, and
+nil otherwise. The result of the `:enabled' check, if any, is
+cached."
+ (and
+ ;; May only enable valid checkers
+ (flycheck-valid-checker-p checker)
+ ;; Don't run the :enabled check if the checker is already disabled…
+ (not (flycheck-disabled-checker-p checker))
+ (or
+ ;; …or if we've already cached the result
+ (memq checker flycheck--automatically-enabled-checkers)
+ (let* ((enabled (flycheck-checker-get checker 'enabled))
+ (may-enable (or (null enabled) (funcall enabled))))
+ ;; Cache the result
+ (if may-enable
+ (cl-pushnew checker flycheck--automatically-enabled-checkers)
+ (cl-pushnew checker flycheck--automatically-disabled-checkers))
+ may-enable))))
+
+(defun flycheck-reset-enabled-checker (checker)
+ "Reset the `:enabled' test of CHECKER.
+
+Forget that CHECKER has been enabled or automatically disabled
+from a previous `:enabled' test. The result of the `:enabled'
+test is cached in `flycheck-may-enable-checker': if you wish to
+test the `:enabled' predicate again, you must first reset its
+state using this function."
+ (when (memq checker flycheck--automatically-disabled-checkers)
+ (setq flycheck--automatically-disabled-checkers
+ (remq checker flycheck--automatically-disabled-checkers)))
+ (when (memq checker flycheck--automatically-enabled-checkers)
+ (setq flycheck--automatically-enabled-checkers
+ (remq checker flycheck--automatically-enabled-checkers)))
+ (flycheck-buffer))
+
+(defun flycheck-may-use-checker (checker)
+ "Whether a generic CHECKER may be used.
+
+Return non-nil if CHECKER may be used for the current buffer, and
+nil otherwise."
+ (let ((predicate (flycheck-checker-get checker 'predicate)))
+ (and (flycheck-valid-checker-p checker)
+ (flycheck-checker-supports-major-mode-p checker)
+ (flycheck-may-enable-checker checker)
+ (or (null predicate) (funcall predicate)))))
+
+(defun flycheck-may-use-next-checker (next-checker)
+ "Determine whether NEXT-CHECKER may be used."
+ (when (symbolp next-checker)
+ (push t next-checker))
+ (let ((level (car next-checker))
+ (next-checker (cdr next-checker)))
+ (and (or (eq level t)
+ (flycheck-has-max-current-errors-p level))
+ (flycheck-registered-checker-p next-checker)
+ (flycheck-may-use-checker next-checker))))
+
+
+;;; Help for generic syntax checkers
+(define-button-type 'help-flycheck-checker-def
+ :supertype 'help-xref
+ 'help-function #'flycheck-goto-checker-definition
+ 'help-echo "mouse-1, RET: find Flycheck checker definition")
+
+(defconst flycheck-find-checker-regexp
+ (rx line-start (zero-or-more (syntax whitespace))
+ "(" symbol-start
+ (or "flycheck-define-checker" "flycheck-define-command-checker")
+ symbol-end
+ (eval (list 'regexp find-function-space-re))
+ (? "'")
+ symbol-start "%s" symbol-end
+ (or (syntax whitespace) line-end))
+ "Regular expression to find a checker definition.")
+
+(add-to-list 'find-function-regexp-alist
+ '(flycheck-checker . flycheck-find-checker-regexp))
+
+(defun flycheck-goto-checker-definition (checker file)
+ "Go to to the definition of CHECKER in FILE."
+ (let ((location (find-function-search-for-symbol
+ checker 'flycheck-checker file)))
+ (pop-to-buffer (car location))
+ (if (cdr location)
+ (goto-char (cdr location))
+ (message "Unable to find checker location in file"))))
+
+(defun flycheck-checker-at-point ()
+ "Return the Flycheck checker found at or before point.
+
+Return nil if there is no checker."
+ (let ((symbol (variable-at-point 'any-symbol)))
+ (when (flycheck-valid-checker-p symbol)
+ symbol)))
+
+(defun flycheck-describe-checker (checker)
+ "Display the documentation of CHECKER.
+
+CHECKER is a checker symbol.
+
+Pop up a help buffer with the documentation of CHECKER."
+ (interactive
+ (let* ((enable-recursive-minibuffers t)
+ (default (or (flycheck-checker-at-point)
+ (ignore-errors (flycheck-get-checker-for-buffer))))
+ (prompt (if default
+ (format "Describe syntax checker (default %s): " default)
+ "Describe syntax checker: ")))
+ (list (flycheck-read-checker prompt default))))
+ (unless (flycheck-valid-checker-p checker)
+ (user-error "You didn't specify a Flycheck syntax checker"))
+ (let ((filename (flycheck-checker-get checker 'file))
+ (modes (flycheck-checker-get checker 'modes))
+ (predicate (flycheck-checker-get checker 'predicate))
+ (print-doc (flycheck-checker-get checker 'print-doc))
+ (next-checkers (flycheck-checker-get checker 'next-checkers))
+ (help-xref-following
+ ;; Ensure that we don't reuse buffers like `flycheck-verify-checker',
+ ;; and that we don't error out if a `help-flycheck-checker-doc' button
+ ;; is added outside of a documentation window.
+ (and help-xref-following (eq major-mode 'help-mode))))
+ (help-setup-xref (list #'flycheck-describe-checker checker)
+ (called-interactively-p 'interactive))
+ (save-excursion
+ (with-help-window (help-buffer)
+ (princ (format "%s is a Flycheck syntax checker" checker))
+ (when filename
+ (princ (format " in `%s'" (file-name-nondirectory filename)))
+ (with-current-buffer standard-output
+ (save-excursion
+ (re-search-backward "`\\([^`']+\\)'" nil t)
+ (help-xref-button 1 'help-flycheck-checker-def
+ checker filename))))
+ (princ ".\n\n")
+
+ (let ((modes-start (with-current-buffer standard-output (point-max))))
+ ;; Track the start of the modes documentation, to properly re-fill
+ ;; it later
+ (princ " This syntax checker checks syntax in the major mode(s) ")
+ (princ (string-join
+ (seq-map (apply-partially #'format "`%s'") modes)
+ ", "))
+ (when predicate
+ (princ ", and uses a custom predicate"))
+ (princ ".")
+ (when next-checkers
+ (princ " It runs the following checkers afterwards:"))
+ (with-current-buffer standard-output
+ (save-excursion
+ (fill-region-as-paragraph modes-start (point-max))))
+ (princ "\n")
+
+ ;; Print the list of next checkers
+ (when next-checkers
+ (princ "\n")
+ (let ((beg-checker-list (with-current-buffer standard-output
+ (point))))
+ (dolist (next-checker next-checkers)
+ (if (symbolp next-checker)
+ (princ (format " * `%s'\n" next-checker))
+ (princ (format " * `%s' (maximum level `%s')\n"
+ (cdr next-checker) (car next-checker)))))
+ ;;
+ (with-current-buffer standard-output
+ (save-excursion
+ (while (re-search-backward "`\\([^`']+\\)'"
+ beg-checker-list t)
+ (let ((checker (intern-soft (match-string 1))))
+ (when (flycheck-valid-checker-p checker)
+ (help-xref-button 1 'help-flycheck-checker-doc
+ checker)))))))))
+ ;; Call the custom print-doc function of the checker, if present
+ (when print-doc
+ (funcall print-doc checker))
+ ;; Ultimately, print the docstring
+ (princ "\nDocumentation:\n")
+ (princ (flycheck-checker-get checker 'documentation))))))
+
+
+;;; Syntax checker verification
+(cl-defstruct (flycheck-verification-result
+ (:constructor flycheck-verification-result-new))
+ "Structure for storing a single verification result.
+
+Slots:
+
+`label'
+ A label for this result, as string
+
+`message'
+ A message for this result, as string
+
+`face'
+ The face to use for the `message'.
+
+ You can either use a face symbol, or a list of face symbols."
+ label message face)
+
+(defun flycheck-verify-generic-checker (checker)
+ "Verify a generic CHECKER in the current buffer.
+
+Return a list of `flycheck-verification-result' objects."
+ (let (results
+ (predicate (flycheck-checker-get checker 'predicate))
+ (enabled (flycheck-checker-get checker 'enabled))
+ (verify (flycheck-checker-get checker 'verify)))
+ (when enabled
+ (let ((result (funcall enabled)))
+ (push (flycheck-verification-result-new
+ :label (propertize "may enable" 'help-echo ":enable")
+ :message (if result "yes" "no")
+ :face (if result 'success '(bold warning)))
+ results)))
+ (when predicate
+ (let ((result (funcall predicate)))
+ (push (flycheck-verification-result-new
+ :label (propertize "may run" 'help-echo ":predicate")
+ :message (prin1-to-string (not (null result)))
+ :face (if result 'success '(bold warning)))
+ results)))
+ (append (nreverse results)
+ (and verify (funcall verify checker)))))
+
+(define-button-type 'help-flycheck-checker-doc
+ :supertype 'help-xref
+ 'help-function #'flycheck-describe-checker
+ 'help-echo "mouse-1, RET: describe Flycheck checker")
+
+(define-button-type 'flycheck-button
+ 'follow-link t
+ 'action (lambda (pos)
+ (apply (get-text-property pos 'flycheck-action)
+ (get-text-property pos 'flycheck-data))
+ ;; Revert the verify-setup buffer since it is now stale
+ (revert-buffer))
+ 'face 'flycheck-verify-select-checker)
+
+(define-button-type 'flycheck-checker-select
+ :supertype 'flycheck-button
+ 'flycheck-action (lambda (buffer checker)
+ (with-current-buffer buffer
+ (flycheck-select-checker checker)))
+ 'help-echo "mouse-1, RET: select this checker")
+
+(define-button-type 'flycheck-checker-enable
+ :supertype 'flycheck-button
+ 'flycheck-action (lambda (buffer checker)
+ (interactive)
+ (with-current-buffer buffer
+ (flycheck--toggle-checker checker t)
+ (flycheck-buffer)))
+ 'help-echo "mouse-1, RET: re-enable this checker in this buffer")
+
+(define-button-type 'flycheck-checker-reset-enabled
+ :supertype 'flycheck-button
+ 'flycheck-action (lambda (buffer checker)
+ (with-current-buffer buffer
+ (flycheck-reset-enabled-checker checker)))
+ 'help-echo "mouse-1, RET: try to re-enable this checker")
+
+(defun flycheck--verify-princ-checker (checker buffer
+ &optional with-mm with-select)
+ "Print verification result of CHECKER for BUFFER.
+
+When WITH-MM is given and non-nil, also include the major mode
+into the verification results.
+
+When WITH-SELECT is non-nil, add a button to select this checker."
+ (princ " ")
+ (insert-button (symbol-name checker)
+ 'type 'help-flycheck-checker-doc
+ 'help-args (list checker))
+ (cond
+ ((with-current-buffer buffer
+ (flycheck-manually-disabled-checker-p checker))
+ (insert (propertize " (manually disabled) " 'face '(bold error)))
+ (insert-text-button "enable"
+ 'type 'flycheck-checker-enable
+ 'flycheck-data (list buffer checker)))
+ ((with-current-buffer buffer
+ (flycheck-automatically-disabled-checker-p checker))
+ (insert (propertize " (automatically disabled) " 'face '(bold error)))
+ (insert-text-button "reset"
+ 'type 'flycheck-checker-reset-enabled
+ 'flycheck-data (list buffer checker))))
+ (when (eq checker (buffer-local-value 'flycheck-checker buffer))
+ (insert (propertize " (explicitly selected)" 'face 'bold)))
+ (when with-select
+ (princ " ")
+ (insert-text-button "select"
+ 'type 'flycheck-checker-select
+ 'flycheck-data (list buffer checker)))
+ (princ "\n")
+ (let ((results (with-current-buffer buffer
+ (append (flycheck-verify-generic-checker checker)
+ (flycheck--verify-next-checkers checker)))))
+ (when with-mm
+ (with-current-buffer buffer
+ (let ((message-and-face
+ (if (flycheck-checker-supports-major-mode-p checker)
+ (cons (format "`%s' supported" major-mode) 'success)
+ (cons (format "`%s' not supported" major-mode) 'error))))
+ (push (flycheck-verification-result-new
+ :label "major mode"
+ :message (car message-and-face)
+ :face (cdr message-and-face))
+ results))))
+ (let* ((label-length
+ (seq-max (mapcar
+ (lambda (res)
+ (length (flycheck-verification-result-label res)))
+ results)))
+ (message-column (+ 8 label-length)))
+ (dolist (result results)
+ (princ " - ")
+ (princ (flycheck-verification-result-label result))
+ (princ ": ")
+ (princ (make-string (- message-column (current-column)) ?\ ))
+ (let ((message (flycheck-verification-result-message result))
+ (face (flycheck-verification-result-face result)))
+ ;; If face is nil, using propertize erases the face already contained
+ ;; by the message. We don't want that, since this would remove the
+ ;; button face from the checker chain result.
+ (insert (if face (propertize message 'face face) message)))
+ (princ "\n"))))
+ (princ "\n"))
+
+(defun flycheck--get-next-checker-symbol (next)
+ "Get the checker symmbol of NEXT checker.
+
+NEXT should be either a cons (NEXT-CHECKER . LEVEL) or a
+symbol."
+ (if (consp next) (cdr next) next))
+
+(defun flycheck-get-next-checkers (checker)
+ "Return the immediate next checkers of CHECKER.
+
+This is a list of checker symbols. The error levels of the
+`:next-checker' property are ignored."
+ (mapcar #'flycheck--get-next-checker-symbol
+ (flycheck-checker-get checker 'next-checkers)))
+
+(defun flycheck-all-next-checkers (checker)
+ "Return all checkers that may follow CHECKER.
+
+Return the transitive closure of the next-checker relation. The
+return value is a list of checkers, not including CHECKER."
+ (let ((next-checkers)
+ (visited)
+ (queue (list checker)))
+ (while queue
+ (let ((c (pop queue)))
+ (push c visited)
+ (dolist (n (flycheck-get-next-checkers c))
+ (push n next-checkers)
+ (unless (memq n visited)
+ (cl-pushnew n queue)))))
+ (seq-uniq next-checkers)))
+
+(defun flycheck--verify-next-checkers (checker)
+ "Return a verification result for the next checkers of CHECKER."
+ (-when-let (next (flycheck-get-next-checkers checker))
+ (list
+ (flycheck-verification-result-new
+ :label "next checkers"
+ ;; We use `make-text-button' to preserve the button properties in the
+ ;; string
+ :message (mapconcat
+ (lambda (checker)
+ (make-text-button (symbol-name checker) nil
+ 'type 'help-flycheck-checker-doc
+ 'help-args (list checker)))
+ next
+ ", ")))))
+
+(defun flycheck--verify-print-header (desc buffer)
+ "Print a title with DESC for BUFFER in the current buffer.
+
+DESC is an arbitrary string containing a description, and BUFFER
+is the buffer being verified. The name and the major mode mode
+of BUFFER are printed.
+
+DESC and information about BUFFER are printed in the current
+buffer."
+ (princ desc)
+ (insert (propertize (buffer-name buffer) 'face 'bold))
+ (princ " in ")
+ (let ((mode (buffer-local-value 'major-mode buffer)))
+ (insert-button (symbol-name mode)
+ 'type 'help-function
+ 'help-args (list mode)))
+ (princ ":\n\n"))
+
+(defun flycheck--verify-print-footer (buffer)
+ "Print a footer for BUFFER in the current buffer.
+
+BUFFER is the buffer being verified."
+ (princ "Flycheck Mode is ")
+ (let ((enabled (buffer-local-value 'flycheck-mode buffer)))
+ (insert (propertize (if enabled "enabled" "disabled")
+ 'face (if enabled 'success '(warning bold)))))
+ (princ
+ (with-current-buffer buffer
+ ;; Use key binding state in the verified buffer to print the help.
+ (substitute-command-keys
+ ". Use \\[universal-argument] \\[flycheck-disable-checker] \
+to enable disabled checkers.")))
+ (save-excursion
+ (let ((end (point)))
+ (backward-paragraph)
+ (fill-region-as-paragraph (point) end)))
+
+ (princ "\n\n--------------------\n\n")
+ (princ (format "Flycheck version: %s\n" (flycheck-version)))
+ (princ (format "Emacs version: %s\n" emacs-version))
+ (princ (format "System: %s\n" system-configuration))
+ (princ (format "Window system: %S\n" window-system)))
+
+(define-derived-mode flycheck-verify-mode help-mode
+ "Flycheck verification"
+ "Major mode to display Flycheck verification results."
+ ;; `help-mode-finish' will restore `buffer-read-only'
+ (setq buffer-read-only nil))
+
+(defun flycheck-verify-checker (checker)
+ "Check whether a CHECKER can be used in this buffer.
+
+Show a buffer listing possible problems that prevent CHECKER from
+being used for the current buffer.
+
+Note: Do not use this function to check whether a syntax checker
+is applicable from Emacs Lisp code. Use
+`flycheck-may-use-checker' instead."
+ (interactive (list (flycheck-read-checker "Checker to verify: ")))
+ (unless (flycheck-valid-checker-p checker)
+ (user-error "%s is not a syntax checker" checker))
+
+ ;; Save the buffer to make sure that all predicates are good
+ ;; FIXME: this may be surprising to users, with unintended side-effects.
+ (when (and (buffer-file-name) (buffer-modified-p))
+ (save-buffer))
+
+ (let ((buffer (current-buffer)))
+ (with-help-window "*Flycheck checker*"
+ (with-current-buffer standard-output
+ (flycheck-verify-mode)
+ (flycheck--verify-print-header "Syntax checker in buffer " buffer)
+ (flycheck--verify-princ-checker checker buffer 'with-mm)
+ (if (with-current-buffer buffer (flycheck-may-use-checker checker))
+ (insert (propertize
+ "Flycheck can use this syntax checker for this buffer.\n"
+ 'face 'success))
+ (insert (propertize
+ "Flycheck cannot use this syntax checker for this buffer.\n"
+ 'face 'error)))
+ (insert "\n")
+ (flycheck--verify-print-footer buffer)))))
+
+(defun flycheck-verify-setup ()
+ "Check whether Flycheck can be used in this buffer.
+
+Display a new buffer listing all syntax checkers that could be
+applicable in the current buffer. For each syntax checkers,
+possible problems are shown."
+ (interactive)
+ ;; Save to make sure checkers that only work on saved buffers will pass the
+ ;; verification
+ (when (and (buffer-file-name) (buffer-modified-p))
+ (save-buffer))
+
+ (let* ((buffer (current-buffer))
+ (first-checker (flycheck-get-checker-for-buffer))
+ (valid-checkers
+ (remq first-checker
+ (seq-filter #'flycheck-may-use-checker flycheck-checkers)))
+ (valid-next-checkers
+ (when first-checker
+ (seq-intersection valid-checkers
+ (flycheck-all-next-checkers first-checker))))
+ (valid-remaining (seq-difference valid-checkers valid-next-checkers))
+ (other-checkers
+ (seq-difference (seq-filter #'flycheck-checker-supports-major-mode-p
+ flycheck-checkers)
+ (cons first-checker valid-checkers))))
+
+ ;; Print all applicable checkers for this buffer
+ (with-help-window "*Flycheck checkers*"
+ (with-current-buffer standard-output
+ (flycheck-verify-mode)
+
+ (flycheck--verify-print-header "Syntax checkers for buffer " buffer)
+
+ (if first-checker
+ (progn
+ (princ "First checker to run:\n\n")
+ (flycheck--verify-princ-checker first-checker buffer))
+ (insert (propertize
+ "No checker to run in this buffer.\n\n"
+ 'face '(bold error))))
+
+ (when valid-next-checkers
+ (princ
+ "Checkers that may run as part of the first checker's chain:\n\n")
+ (dolist (checker valid-next-checkers)
+ (flycheck--verify-princ-checker checker buffer)))
+
+ (when valid-remaining
+ (princ "Checkers that could run if selected:\n\n")
+ (dolist (checker valid-remaining)
+ (flycheck--verify-princ-checker checker buffer nil 'with-select)))
+
+ (when other-checkers
+ (princ
+ "Checkers that are compatible with this mode, \
+but will not run until properly configured:\n\n")
+ (dolist (checker other-checkers)
+ (flycheck--verify-princ-checker checker buffer)))
+
+ ;; If we have no checkers at all, that's worth mentioning
+ (unless (or first-checker valid-checkers other-checkers)
+ (insert (propertize
+ "No checkers are available for this buffer.\n\n"
+ 'face '(bold error))))
+
+ (let ((unregistered-checkers
+ (seq-difference (flycheck-defined-checkers) flycheck-checkers)))
+ (when unregistered-checkers
+ (insert (propertize
+ "The following syntax checkers are not registered:\n"
+ 'face '(bold warning)))
+ (dolist (checker unregistered-checkers)
+ (princ " - ")
+ (princ checker)
+ (princ "\n"))
+ (princ
+ "Try adding these syntax checkers to `flycheck-checkers'.\n\n")))
+
+ (flycheck--verify-print-footer buffer)
+
+ (setq-local revert-buffer-function
+ (lambda (_ignore-auto _noconfirm)
+ (with-current-buffer buffer (flycheck-verify-setup))))))))
+
+
+;;; Predicates for generic syntax checkers
+(defun flycheck-buffer-saved-p (&optional buffer)
+ "Determine whether BUFFER is saved to a file.
+
+BUFFER is the buffer to check. If omitted or nil, use the
+current buffer as BUFFER.
+
+Return non-nil if the BUFFER is backed by a file, and not
+modified, or nil otherwise."
+ (let ((file-name (buffer-file-name buffer)))
+ (and file-name (file-exists-p file-name) (not (buffer-modified-p buffer)))))
+
+
+;;; Extending generic checkers
+(defun flycheck-remove-next-checker (checker next)
+ "After CHECKER remove a NEXT checker.
+
+CHECKER is a syntax checker symbol, from which to remove NEXT
+checker.
+
+NEXT is a cons or a symbol, as documented in
+`flycheck-add-next-checker'."
+ (unless (flycheck-valid-checker-p checker)
+ (error "%s is not a valid syntax checker" checker))
+ (let* ((next-symbol (flycheck--get-next-checker-symbol next)))
+ (setf
+ (flycheck-checker-get checker 'next-checkers)
+ (seq-remove
+ (lambda (next) (eq (flycheck--get-next-checker-symbol next) next-symbol))
+ (flycheck-checker-get checker 'next-checkers)))))
+
+(defun flycheck-add-next-checker (checker next &optional append)
+ "After CHECKER add a NEXT checker.
+
+CHECKER is a syntax checker symbol, to which to add NEXT checker.
+
+NEXT is a cons cell `(LEVEL . NEXT-CHECKER)'. NEXT-CHECKER is a
+symbol denoting the syntax checker to run after CHECKER. LEVEL
+is an error level. NEXT-CHECKER will only be used if there is no
+current error whose level is more severe than LEVEL. LEVEL may
+also be t, in which case NEXT-CHECKER is used regardless of the
+current errors.
+
+NEXT can also be a syntax checker symbol only, which is
+equivalent to `(t . NEXT)'.
+
+NEXT-CHECKER is prepended before other next checkers, unless
+APPEND is non-nil."
+ (unless (flycheck-valid-checker-p checker)
+ (error "%s is not a valid syntax checker" checker))
+ (flycheck-validate-next-checker next 'strict)
+ (flycheck-remove-next-checker checker next)
+ (let ((next-checkers (flycheck-checker-get checker 'next-checkers)))
+ (setf (flycheck-checker-get checker 'next-checkers)
+ (if append (append next-checkers (list next))
+ (cons next next-checkers)))))
+
+(defun flycheck-add-mode (checker mode)
+ "To CHECKER add a new major MODE.
+
+CHECKER and MODE are symbols denoting a syntax checker and a
+major mode respectively.
+
+Add MODE to the `:modes' property of CHECKER, so that CHECKER
+will be used in buffers with MODE."
+ (unless (flycheck-valid-checker-p checker)
+ (error "%s is not a valid syntax checker" checker))
+ (unless (symbolp mode)
+ (error "%s is not a symbol" mode))
+ (push mode (flycheck-checker-get checker 'modes)))
+
+
+;;; Generic syntax checks
+(cl-defstruct (flycheck-syntax-check
+ (:constructor flycheck-syntax-check-new))
+ "Structure for storing syntax check state.
+
+Slots:
+
+`buffer'
+ The buffer being checked.
+
+`checker'
+ The syntax checker being used.
+
+`context'
+ The context object.
+
+`working-directory'
+ Working directory for the syntax checker. Serve as a value for
+ `default-directory' for a checker."
+ buffer checker context working-directory)
+
+(defun flycheck-syntax-check-start (syntax-check callback)
+ "Start a SYNTAX-CHECK with CALLBACK."
+ (let ((checker (flycheck-syntax-check-checker syntax-check))
+ (default-directory
+ (flycheck-syntax-check-working-directory syntax-check)))
+ (setf (flycheck-syntax-check-context syntax-check)
+ (funcall (flycheck-checker-get checker 'start) checker callback))))
+
+(defun flycheck-syntax-check-interrupt (syntax-check)
+ "Interrupt a SYNTAX-CHECK."
+ (let* ((checker (flycheck-syntax-check-checker syntax-check))
+ (interrupt-fn (flycheck-checker-get checker 'interrupt))
+ (context (flycheck-syntax-check-context syntax-check)))
+ (when interrupt-fn
+ (funcall interrupt-fn checker context))))
+
+
+;;; Syntax checking mode
+
+(defvar flycheck-mode-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map flycheck-keymap-prefix flycheck-command-map)
+ ;; We place the menu under a custom menu key. Since this menu key is not
+ ;; present in the menu of the global map, no top-level menu entry is added
+ ;; to the global menu bar. However, it still appears on the mode line
+ ;; lighter.
+ (define-key map [menu-bar flycheck] flycheck-mode-menu-map)
+ map)
+ "Keymap of command `flycheck-mode'.")
+
+(defvar-local flycheck-old-next-error-function nil
+ "Remember the old `next-error-function'.")
+
+(defconst flycheck-hooks-alist
+ '(
+ ;; Handle events that may start automatic syntax checks
+ (after-save-hook . flycheck-handle-save)
+ (after-change-functions . flycheck-handle-change)
+ ;; Handle events that may triggered pending deferred checks
+ (window-configuration-change-hook . flycheck-perform-deferred-syntax-check)
+ (post-command-hook . flycheck-perform-deferred-syntax-check)
+ ;; Teardown Flycheck whenever the buffer state is about to get lost, to
+ ;; clean up temporary files and directories.
+ (kill-buffer-hook . flycheck-teardown)
+ (change-major-mode-hook . flycheck-teardown)
+ (before-revert-hook . flycheck-teardown)
+ ;; Update the error list if necessary
+ (post-command-hook . flycheck-error-list-update-source)
+ (post-command-hook . flycheck-error-list-highlight-errors)
+ ;; Display errors. Show errors at point after commands (like movements) and
+ ;; when Emacs gets focus. Cancel the display timer when Emacs looses focus
+ ;; (as there's no need to display errors if the user can't see them), and
+ ;; hide the error buffer (for large error messages) if necessary. Note that
+ ;; the focus hooks only work on Emacs 24.4 and upwards, but since undefined
+ ;; hooks are perfectly ok we don't need a version guard here. They'll just
+ ;; not work silently.
+ (post-command-hook . flycheck-maybe-display-error-at-point-soon)
+ (focus-in-hook . flycheck-display-error-at-point-soon)
+ (focus-out-hook . flycheck-cancel-error-display-error-at-point-timer)
+ (post-command-hook . flycheck-hide-error-buffer)
+ ;; Immediately show error popups when navigating to an error
+ (next-error-hook . flycheck-display-error-at-point))
+ "Hooks which Flycheck needs to hook in.
+
+The `car' of each pair is a hook variable, the `cdr' a function
+to be added or removed from the hook variable if Flycheck mode is
+enabled and disabled respectively.")
+
+;;;###autoload
+(define-minor-mode flycheck-mode
+ "Flycheck is a minor mode for on-the-fly syntax checking.
+
+In `flycheck-mode' the buffer is automatically syntax-checked
+using the first suitable syntax checker from `flycheck-checkers'.
+Use `flycheck-select-checker' to select a checker for the current
+buffer manually.
+
+If you run into issues, use `\\[flycheck-verify-setup]' to get help.
+
+Flycheck supports many languages out of the box, and many
+additional ones are available on MELPA. Adding new ones is very
+easy. Complete documentation is available online at URL
+`https://www.flycheck.org/en/latest/'. Please report issues and
+request features at URL `https://github.com/flycheck/flycheck'.
+
+Flycheck displays its status in the mode line. In the default
+configuration, it looks like this:
+
+`FlyC' This buffer has not been checked yet.
+`FlyC-' Flycheck doesn't have a checker for this buffer.
+`FlyC*' Flycheck is running. Expect results soon!
+`FlyC:3|2' This buffer contains three warnings and two errors.
+ Use `\\[flycheck-list-errors]' to see the list.
+
+You may also see the following icons:
+`FlyC!' The checker crashed.
+`FlyC.' The last syntax check was manually interrupted.
+`FlyC?' The checker did something unexpected, like exiting with 1
+ but returning no errors.
+
+The following keybindings are available in `flycheck-mode':
+
+\\{flycheck-mode-map}
+\(you can change the prefix by customizing
+`flycheck-keymap-prefix')
+
+If called interactively, enable Flycheck mode if ARG is positive,
+and disable it if ARG is zero or negative. If called from Lisp,
+also enable the mode if ARG is omitted or nil, and toggle it if
+ARG is ‘toggle’; disable the mode otherwise."
+ :init-value nil
+ :keymap flycheck-mode-map
+ :lighter flycheck-mode-line
+ :after-hook (flycheck-buffer-automatically 'mode-enabled 'force-deferred)
+ (cond
+ (flycheck-mode
+ (flycheck-clear)
+
+ (pcase-dolist (`(,hook . ,fn) (reverse flycheck-hooks-alist))
+ (add-hook hook fn nil 'local))
+
+ (setq flycheck-old-next-error-function
+ (if flycheck-standard-error-navigation
+ next-error-function
+ :unset))
+ (when flycheck-standard-error-navigation
+ (setq next-error-function #'flycheck-next-error-function))
+
+ ;; This hook must be added globally since otherwise we cannot
+ ;; detect a change from a buffer where Flycheck is enabled to a
+ ;; buffer where Flycheck is not enabled, and therefore cannot
+ ;; notice that there has been any change when the user switches
+ ;; back to the buffer where Flycheck is enabled.
+ (add-hook 'buffer-list-update-hook #'flycheck-handle-buffer-switch))
+ (t
+ (unless (eq flycheck-old-next-error-function :unset)
+ (setq next-error-function flycheck-old-next-error-function))
+
+ (pcase-dolist (`(,hook . ,fn) flycheck-hooks-alist)
+ (remove-hook hook fn 'local))
+
+ (flycheck-teardown))))
+
+
+;;; Syntax checker selection for the current buffer
+(defun flycheck-get-checker-for-buffer ()
+ "Find the checker for the current buffer.
+
+Use the selected checker for the current buffer, if any,
+otherwise search for the best checker from `flycheck-checkers'.
+
+Return checker if there is a checker for the current buffer, or
+nil otherwise."
+ (if flycheck-checker
+ (when (flycheck-may-use-checker flycheck-checker)
+ flycheck-checker)
+ (seq-find #'flycheck-may-use-checker flycheck-checkers)))
+
+(defun flycheck-get-next-checker-for-buffer (checker)
+ "Get the checker to run after CHECKER for the current buffer."
+ (let ((next (seq-find #'flycheck-may-use-next-checker
+ (flycheck-checker-get checker 'next-checkers))))
+ (when next
+ (if (symbolp next) next (cdr next)))))
+
+(defun flycheck-select-checker (checker)
+ "Select CHECKER for the current buffer.
+
+CHECKER is a syntax checker symbol (see `flycheck-checkers') or
+nil. In the former case, use CHECKER for the current buffer,
+otherwise deselect the current syntax checker (if any) and use
+automatic checker selection via `flycheck-checkers'.
+
+If called interactively prompt for CHECKER. With prefix arg
+deselect the current syntax checker and enable automatic
+selection again.
+
+Set `flycheck-checker' to CHECKER and automatically start a new
+syntax check if the syntax checker changed.
+
+CHECKER will be used, even if it is not contained in
+`flycheck-checkers', or if it is disabled via
+`flycheck-disabled-checkers'."
+ (interactive
+ (if current-prefix-arg
+ (list nil)
+ (list (flycheck-read-checker "Select checker: "
+ (flycheck-get-checker-for-buffer)))))
+ (when (not (eq checker flycheck-checker))
+ (unless (or (not checker) (flycheck-may-use-checker checker))
+ (flycheck-verify-checker checker)
+ (user-error "Can't use syntax checker %S in this buffer" checker))
+ (setq flycheck-checker checker)
+ (when flycheck-mode
+ (flycheck-buffer))))
+
+(defun flycheck--toggle-checker (checker enable)
+ "Enable or disable CHECKER for the current buffer.
+
+If ENABLE, re-enable CHECKER by removing it from the buffer-local
+value of `flycheck-disabled-checkers'. Otherwise, add the syntax
+checker to the buffer-local value of `flycheck-disabled-checkers'."
+ (cond
+ (enable
+ ;; We must use `remq' instead of `delq', because we must _not_ modify the
+ ;; list. Otherwise we could potentially modify the global default value,
+ ;; in case the list is the global default.
+ (when (memq checker flycheck-disabled-checkers)
+ (setq flycheck-disabled-checkers
+ (remq checker flycheck-disabled-checkers)))
+ (when (memq checker flycheck--automatically-disabled-checkers)
+ (setq flycheck--automatically-disabled-checkers
+ (remq checker flycheck--automatically-disabled-checkers))))
+ (t (unless (memq checker flycheck-disabled-checkers)
+ (push checker flycheck-disabled-checkers)))))
+
+(defun flycheck-disable-checker (checker &optional enable)
+ "Interactively disable CHECKER for the current buffer.
+
+Prompt for a syntax checker to disable, and add the syntax
+checker to the buffer-local value of
+`flycheck-disabled-checkers'.
+
+With non-nil ENABLE or with prefix arg, prompt for a disabled
+syntax checker and re-enable it by removing it from the
+buffer-local value of `flycheck-disabled-checkers'."
+ (declare
+ (interactive-only "Directly set `flycheck-disabled-checkers' instead"))
+ (interactive
+ (let* ((enable current-prefix-arg)
+ (candidates (if enable
+ (append flycheck-disabled-checkers
+ flycheck--automatically-disabled-checkers)
+ flycheck-checkers))
+ (prompt (if enable "Enable syntax checker: "
+ "Disable syntax checker: ")))
+ (when (and enable (not candidates))
+ (user-error "No syntax checkers disabled in this buffer"))
+ (list (flycheck-read-checker prompt nil nil candidates) enable)))
+ (unless checker
+ (user-error "No syntax checker given"))
+ (flycheck--toggle-checker checker enable)
+ (flycheck-buffer))
+
+
+;;; Syntax checks for the current buffer
+(defvar-local flycheck-current-syntax-check nil
+ "The current syntax check in the this buffer.")
+(put 'flycheck-current-syntax-check 'permanent-local t)
+
+(defun flycheck-start-current-syntax-check (checker)
+ "Start a syntax check in the current buffer with CHECKER.
+
+Set `flycheck-current-syntax-check' accordingly."
+ ;; Allocate the current syntax check *before* starting it. This allows for
+ ;; synchronous checks, which call the status callback immediately in their
+ ;; start function.
+ (let* ((check
+ (flycheck-syntax-check-new
+ :buffer (current-buffer)
+ :checker checker
+ :context nil
+ :working-directory (flycheck-compute-working-directory checker)))
+ (callback (flycheck-buffer-status-callback check)))
+ (setq flycheck-current-syntax-check check)
+ (flycheck-report-status 'running)
+ (flycheck-syntax-check-start check callback)))
+
+(defun flycheck-running-p ()
+ "Determine whether a syntax check is running in the current buffer."
+ (not (null flycheck-current-syntax-check)))
+
+(defun flycheck-stop ()
+ "Stop any ongoing syntax check in the current buffer."
+ (when (flycheck-running-p)
+ (flycheck-syntax-check-interrupt flycheck-current-syntax-check)
+ ;; Remove the current syntax check, to reset Flycheck into a non-running
+ ;; state, and to make `flycheck-report-buffer-checker-status' ignore any
+ ;; status reports from the current syntax check.
+ (setq flycheck-current-syntax-check nil)
+ (flycheck-report-status 'interrupted)))
+
+(defun flycheck-buffer-status-callback (syntax-check)
+ "Create a status callback for SYNTAX-CHECK in the current buffer."
+ (lambda (&rest args)
+ (apply #'flycheck-report-buffer-checker-status
+ syntax-check args)))
+
+(defun flycheck-buffer ()
+ "Start checking syntax in the current buffer.
+
+Get a syntax checker for the current buffer with
+`flycheck-get-checker-for-buffer', and start it."
+ (interactive)
+ (flycheck-clean-deferred-check)
+ (if flycheck-mode
+ (unless (flycheck-running-p)
+ ;; Clear error list and mark all overlays for deletion. We do not
+ ;; delete all overlays immediately to avoid excessive re-displays and
+ ;; flickering, if the same errors gets highlighted again after the check
+ ;; completed.
+ (run-hooks 'flycheck-before-syntax-check-hook)
+ (flycheck-clear-errors)
+ (flycheck-mark-all-overlays-for-deletion)
+ (condition-case err
+ (let* ((checker (flycheck-get-checker-for-buffer)))
+ (if checker
+ (flycheck-start-current-syntax-check checker)
+ (flycheck-clear)
+ (flycheck-report-status 'no-checker)))
+ (error
+ (flycheck-report-failed-syntax-check)
+ (signal (car err) (cdr err)))))
+ (user-error "Flycheck mode disabled")))
+
+(defun flycheck-report-buffer-checker-status
+ (syntax-check status &optional data)
+ "In BUFFER, report a SYNTAX-CHECK STATUS with DATA.
+
+SYNTAX-CHECK is the `flycheck-syntax-check' which reported
+STATUS. STATUS denotes the status of CHECKER, with an optional
+DATA. STATUS may be one of the following symbols:
+
+`errored'
+ The syntax checker has errored. DATA is an optional error
+ message.
+
+ This report finishes the current syntax check.
+
+`interrupted'
+ The syntax checker was interrupted. DATA is ignored.
+
+ This report finishes the current syntax check.
+
+`finished'
+ The syntax checker has finished with a proper error report
+ for the current buffer. DATA is the (potentially empty)
+ list of `flycheck-error' objects reported by the syntax
+ check.
+
+ This report finishes the current syntax check.
+
+`suspicious'
+ The syntax checker encountered a suspicious state, which the
+ user needs to be informed about. DATA is an optional
+ message.
+
+A syntax checker _must_ report a status at least once with any
+symbol that finishes the current syntax checker. Otherwise
+Flycheck gets stuck with the current syntax check.
+
+If CHECKER is not the currently used syntax checker in
+`flycheck-current-syntax-check', the status report is largely
+ignored. Notably, any errors reported by the checker are
+discarded."
+ (let ((buffer (flycheck-syntax-check-buffer syntax-check)))
+ ;; Ignore the status report if the buffer is gone, or if this syntax check
+ ;; isn't the current one in buffer (which can happen if this is an old
+ ;; report of an interrupted syntax check, and a new syntax check was started
+ ;; since this check was interrupted)
+ (when (and (buffer-live-p buffer)
+ (eq syntax-check
+ (buffer-local-value 'flycheck-current-syntax-check buffer)))
+ (with-current-buffer buffer
+ (let ((checker (flycheck-syntax-check-checker syntax-check)))
+ (pcase status
+ ((or `errored `interrupted)
+ (flycheck-report-failed-syntax-check status)
+ (when (eq status 'errored)
+ ;; In case of error, show the error message
+ (message "Error from syntax checker %s: %s"
+ checker (or data "UNKNOWN!"))))
+ (`suspicious
+ (when flycheck-mode
+ (message "Suspicious state from syntax checker %s: %s"
+ checker (or data "UNKNOWN!")))
+ (flycheck-report-status 'suspicious))
+ (`finished
+ (when flycheck-mode
+ ;; Only report errors from the checker if Flycheck Mode is
+ ;; still enabled.
+ (flycheck-finish-current-syntax-check
+ data
+ (flycheck-syntax-check-working-directory syntax-check))))
+ (_
+ (error "Unknown status %s from syntax checker %s"
+ status checker))))))))
+
+(defun flycheck-finish-current-syntax-check (errors working-dir)
+ "Finish the current syntax-check in the current buffer with ERRORS.
+
+ERRORS is a list of `flycheck-error' objects reported by the
+current syntax check in `flycheck-current-syntax-check'.
+
+Report all ERRORS and potentially start any next syntax checkers.
+
+If the current syntax checker reported excessive errors, it is
+disabled via `flycheck-disable-excessive-checker' for subsequent
+syntax checks.
+
+Relative file names in ERRORS will be expanded relative to
+WORKING-DIR."
+ (let* ((syntax-check flycheck-current-syntax-check)
+ (checker (flycheck-syntax-check-checker syntax-check))
+ (errors (flycheck-relevant-errors
+ (flycheck-fill-and-expand-error-file-names
+ (flycheck-filter-errors
+ (flycheck-assert-error-list-p errors) checker)
+ working-dir))))
+ (unless (flycheck-disable-excessive-checker checker errors)
+ (flycheck-report-current-errors errors))
+ (let ((next-checker (flycheck-get-next-checker-for-buffer checker)))
+ (if next-checker
+ (flycheck-start-current-syntax-check next-checker)
+ (setq flycheck-current-syntax-check nil)
+ (flycheck-report-status 'finished)
+ ;; Delete overlays only after the very last checker has run, to avoid
+ ;; flickering on intermediate re-displays
+ (flycheck-delete-marked-overlays)
+ (flycheck-error-list-refresh)
+ (run-hooks 'flycheck-after-syntax-check-hook)
+ (when (eq (current-buffer) (window-buffer))
+ (flycheck-display-error-at-point))
+ ;; Immediately try to run any pending deferred syntax check, which
+ ;; were triggered by intermediate automatic check event, to make sure
+ ;; that we quickly refine outdated error information
+ (flycheck-perform-deferred-syntax-check)))))
+
+(defun flycheck-disable-excessive-checker (checker errors)
+ "Disable CHECKER if it reported excessive ERRORS.
+
+If ERRORS has more items than `flycheck-checker-error-threshold',
+add CHECKER to `flycheck--automatically-disabled-checkers', and
+show a warning.
+
+Return t when CHECKER was disabled, or nil otherwise."
+ (when (and flycheck-checker-error-threshold
+ (> (length errors) flycheck-checker-error-threshold))
+ ;; Disable CHECKER for this buffer
+ ;; (`flycheck--automatically-disabled-checkers' is a local variable).
+ (lwarn '(flycheck syntax-checker) :warning
+ (substitute-command-keys
+ "Syntax checker %s reported too many errors (%s) and is disabled.
+Use `\\[customize-variable] RET flycheck-checker-error-threshold' to
+change the threshold or `\\[universal-argument] \
+\\[flycheck-disable-checker]' to re-enable the checker.")
+ checker (length errors))
+ (push checker flycheck--automatically-disabled-checkers)
+ t))
+
+(defun flycheck-clear (&optional shall-interrupt)
+ "Clear all errors in the current buffer.
+
+With prefix arg or SHALL-INTERRUPT non-nil, also interrupt the
+current syntax check."
+ (interactive "P")
+ (when shall-interrupt
+ (flycheck-stop))
+ (flycheck-delete-all-overlays)
+ (flycheck-clear-errors)
+ (flycheck-error-list-refresh)
+ (flycheck-hide-error-buffer))
+
+(defun flycheck--empty-variables ()
+ "Empty variables used by Flycheck."
+ (kill-local-variable 'flycheck--file-truename-cache)
+ (kill-local-variable 'flycheck--idle-trigger-timer)
+ (kill-local-variable 'flycheck--idle-trigger-conditions)
+ (kill-local-variable 'flycheck--last-error-display-tick))
+
+(defun flycheck-teardown (&optional ignore-global)
+ "Teardown Flycheck in the current buffer.
+
+Completely clear the whole Flycheck state. Remove overlays, kill
+running checks, and empty all variables used by Flycheck.
+
+Unless optional argument IGNORE-GLOBAL is non-nil, check to see
+if no more Flycheck buffers remain (aside from the current
+buffer), and if so then clean up global hooks."
+ (flycheck-safe-delete-temporaries)
+ (flycheck-stop)
+ (flycheck-clean-deferred-check)
+ (flycheck-clear)
+ (flycheck-cancel-error-display-error-at-point-timer)
+ (flycheck--clear-idle-trigger-timer)
+ (flycheck--empty-variables)
+ (unless (or ignore-global
+ (seq-some (lambda (buf)
+ (and (not (equal buf (current-buffer)))
+ (buffer-local-value 'flycheck-mode buf)))
+ (buffer-list)))
+ (flycheck-global-teardown 'ignore-local)))
+
+
+;;; Automatic syntax checking in a buffer
+(defun flycheck-may-check-automatically (&rest conditions)
+ "Determine whether the buffer may be checked under one of CONDITIONS.
+
+Read-only buffers may never be checked automatically.
+
+If CONDITIONS are given, determine whether syntax may be checked
+under at least one of them, according to
+`flycheck-check-syntax-automatically'."
+ (and (not (or buffer-read-only (flycheck-ephemeral-buffer-p)))
+ (file-exists-p default-directory)
+ (or (not conditions)
+ (seq-some
+ (lambda (condition)
+ (memq condition flycheck-check-syntax-automatically))
+ conditions))))
+
+(defvar-local flycheck--idle-trigger-timer nil
+ "Timer used to trigger a syntax check after an idle delay.")
+
+(defvar-local flycheck--idle-trigger-conditions nil
+ "List of conditions under which an idle syntax check will be triggered.
+This will be some subset of the allowable values for
+`flycheck-check-syntax-automatically'.
+
+For example, if the user switches to a buffer and then makes an
+edit, this list will have the values `idle-change' and
+`idle-buffer-switch' in it, at least until the idle timer
+expires.")
+
+(defun flycheck-buffer-automatically (&optional condition force-deferred)
+ "Automatically check syntax at CONDITION.
+
+Syntax is not checked if `flycheck-may-check-automatically'
+returns nil for CONDITION. (CONDITION may be a single condition
+or a list of them.)
+
+The syntax check is deferred if FORCE-DEFERRED is non-nil, or if
+`flycheck-must-defer-check' returns t."
+ (when (and flycheck-mode (if (listp condition)
+ (apply #'flycheck-may-check-automatically
+ condition)
+ (flycheck-may-check-automatically condition)))
+ (flycheck--clear-idle-trigger-timer)
+ (setq flycheck--idle-trigger-conditions nil)
+ (if (or force-deferred (flycheck-must-defer-check))
+ (flycheck-buffer-deferred)
+ (with-demoted-errors "Error while checking syntax automatically: %S"
+ (flycheck-buffer)))))
+
+(defun flycheck--clear-idle-trigger-timer ()
+ "Clear the idle trigger timer."
+ (when flycheck--idle-trigger-timer
+ (cancel-timer flycheck--idle-trigger-timer)
+ (setq flycheck--idle-trigger-timer nil)))
+
+(defun flycheck--handle-idle-trigger (buffer)
+ "Run a syntax check in BUFFER if appropriate.
+This function is called by `flycheck--idle-trigger-timer'."
+ (let ((current-buffer (current-buffer)))
+ (when (buffer-live-p buffer)
+ (with-current-buffer buffer
+ (unless (or flycheck-buffer-switch-check-intermediate-buffers
+ (eq buffer current-buffer))
+ (setq flycheck--idle-trigger-conditions
+ (delq 'idle-buffer-switch
+ flycheck--idle-trigger-conditions)))
+ (when flycheck--idle-trigger-conditions
+ (flycheck-buffer-automatically flycheck--idle-trigger-conditions)
+ (setq flycheck--idle-trigger-conditions nil))))))
+
+(defun flycheck-handle-change (beg end _len)
+ "Handle a buffer change between BEG and END.
+
+BEG and END mark the beginning and end of the change text. _LEN
+is ignored.
+
+Start a syntax check if a new line has been inserted into the
+buffer."
+ ;; Save and restore the match data, as recommended in (elisp)Change Hooks
+ (save-match-data
+ (when flycheck-mode
+ (if (string-match-p (rx "\n") (buffer-substring beg end))
+ (flycheck-buffer-automatically 'new-line 'force-deferred)
+ (when (memq 'idle-change flycheck-check-syntax-automatically)
+ (flycheck--clear-idle-trigger-timer)
+ (cl-pushnew 'idle-change flycheck--idle-trigger-conditions)
+ (setq flycheck--idle-trigger-timer
+ (run-at-time flycheck-idle-change-delay nil
+ #'flycheck--handle-idle-trigger
+ (current-buffer))))))))
+
+(defvar flycheck--last-buffer (current-buffer)
+ "The current buffer or the buffer that was previously current.
+This is usually equal to the current buffer, unless the user just
+switched buffers. After a buffer switch, it is the previous
+buffer.")
+
+(defun flycheck-handle-buffer-switch ()
+ "Handle a possible switch to another buffer.
+
+If a buffer switch actually happened, schedule a syntax check."
+ ;; Switching buffers here is weird, but unfortunately necessary. It
+ ;; turns out that `with-temp-buffer' triggers
+ ;; `buffer-list-update-hook' twice, and the value of
+ ;; `current-buffer' is bogus in one of those triggers (the one just
+ ;; after the temp buffer is killed). If we rely on the bogus value,
+ ;; Flycheck will think that the user is switching back and forth
+ ;; between different buffers during the `with-temp-buffer' call
+ ;; (note: two different normal buffers, not the current buffer and
+ ;; the temp buffer!), and that would trigger spurious syntax checks.
+ ;; It seems that reading (window-buffer) gets us the correct current
+ ;; buffer in all important real-life situations (although it doesn't
+ ;; necessarily catch uses of `set-buffer').
+ (with-current-buffer (window-buffer)
+ (unless (or (equal flycheck--last-buffer (current-buffer))
+ ;; Don't bother keeping track of changes to and from
+ ;; the minibuffer, as they will never require us to
+ ;; run a syntax check.
+ (minibufferp))
+ (setq flycheck--last-buffer (current-buffer))
+ (when (and flycheck-mode
+ (memq 'idle-buffer-switch flycheck-check-syntax-automatically))
+ (flycheck--clear-idle-trigger-timer)
+ (cl-pushnew 'idle-buffer-switch flycheck--idle-trigger-conditions)
+ (setq flycheck--idle-trigger-timer
+ (run-at-time flycheck-idle-buffer-switch-delay nil
+ #'flycheck--handle-idle-trigger
+ (current-buffer)))))))
+
+(defun flycheck-handle-save ()
+ "Handle a save of the buffer."
+ (flycheck-buffer-automatically 'save))
+
+
+;;; Deferred syntax checking
+(defvar-local flycheck-deferred-syntax-check nil
+ "If non-nil, a deferred syntax check is pending.")
+
+(defun flycheck-must-defer-check ()
+ "Determine whether the syntax check has to be deferred.
+
+A check has to be deferred if the buffer is not visible, or if the buffer is
+currently being reverted.
+
+Return t if the check is to be deferred, or nil otherwise."
+ (or (not (get-buffer-window))
+ ;; We defer the syntax check if Flycheck is already running, to
+ ;; immediately start a new syntax check after the current one finished,
+ ;; because the result of the current check will most likely be outdated by
+ ;; the time it is finished.
+ (flycheck-running-p)
+ ;; We must defer checks while a buffer is being reverted, to avoid race
+ ;; conditions while the buffer contents are being restored.
+ revert-buffer-in-progress-p))
+
+(defun flycheck-deferred-check-p ()
+ "Determine whether the current buffer has a deferred check.
+
+Return t if so, or nil otherwise."
+ flycheck-deferred-syntax-check)
+
+(defun flycheck-buffer-deferred ()
+ "Defer syntax check for the current buffer."
+ (setq flycheck-deferred-syntax-check t))
+
+(defun flycheck-clean-deferred-check ()
+ "Clean a deferred syntax checking state."
+ (setq flycheck-deferred-syntax-check nil))
+
+(defun flycheck-perform-deferred-syntax-check ()
+ "Perform the deferred syntax check."
+ (when (flycheck-deferred-check-p)
+ (flycheck-clean-deferred-check)
+ (flycheck-buffer-automatically)))
+
+
+;;; Syntax checking in all buffers
+(defun flycheck-may-enable-mode ()
+ "Determine whether Flycheck mode may be enabled.
+
+Flycheck mode is not enabled for
+
+- the minibuffer,
+- `fundamental-mode'
+- major modes whose `mode-class' property is `special',
+- ephemeral buffers (see `flycheck-ephemeral-buffer-p'),
+- encrypted buffers (see `flycheck-encrypted-buffer-p'),
+- remote files (see `file-remote-p'),
+- and major modes excluded by `flycheck-global-modes'.
+
+Return non-nil if Flycheck mode may be enabled, and nil
+otherwise."
+ (and (pcase flycheck-global-modes
+ ;; Whether `major-mode' is disallowed by `flycheck-global-modes'
+ (`t t)
+ (`(not . ,modes) (not (memq major-mode modes)))
+ (modes (memq major-mode modes)))
+ (not (or (minibufferp)
+ (eq major-mode 'fundamental-mode)
+ (eq (get major-mode 'mode-class) 'special)
+ (flycheck-ephemeral-buffer-p)
+ (flycheck-encrypted-buffer-p)
+ (and (buffer-file-name)
+ (file-remote-p (buffer-file-name) 'method))))))
+
+(defun flycheck-mode-on-safe ()
+ "Enable command `flycheck-mode' if it is safe to do so.
+
+Command `flycheck-mode' is only enabled if
+`flycheck-may-enable-mode' returns a non-nil result."
+ (when (flycheck-may-enable-mode)
+ (flycheck-mode)))
+
+;;;###autoload
+(define-globalized-minor-mode global-flycheck-mode flycheck-mode
+ flycheck-mode-on-safe
+ :init-value nil
+ ;; Do not expose Global Flycheck Mode on customize interface, because the
+ ;; interaction between package.el and customize is currently broken. See
+ ;; https://github.com/flycheck/flycheck/issues/595
+
+ ;; :require 'flycheck :group
+ ;; 'flycheck
+ )
+
+(defun flycheck-global-teardown (&optional ignore-local)
+ "Teardown Flycheck in all buffers.
+
+Completely clear the whole Flycheck state in all buffers, stop
+all running checks, remove all temporary files, and empty all
+variables of Flycheck.
+
+Also remove global hooks. (If optional argument IGNORE-LOCAL is
+non-nil, then only do this and skip per-buffer teardown.)"
+ (unless ignore-local
+ (dolist (buffer (buffer-list))
+ (when (buffer-live-p buffer)
+ (with-current-buffer buffer
+ (when flycheck-mode
+ (flycheck-teardown 'ignore-global))))))
+ (remove-hook 'buffer-list-update-hook #'flycheck-handle-buffer-switch))
+
+;; Clean up the entire state of Flycheck when Emacs is killed, to get rid of any
+;; pending temporary files.
+(add-hook 'kill-emacs-hook #'flycheck-global-teardown)
+
+
+;;; Errors from syntax checks
+(cl-defstruct (flycheck-error
+ (:constructor nil)
+ (:constructor
+ flycheck-error-new
+ (&key
+ line column end-line end-column
+ buffer checker filename message level id group
+ &aux (-end-line end-line) (-end-column end-column)))
+ (:constructor
+ flycheck-error-new-at
+ (line
+ column
+ &optional level message
+ &key end-line end-column checker id group
+ (filename (buffer-file-name)) (buffer (current-buffer))
+ &aux (-end-line end-line) (-end-column end-column)))
+ (:constructor
+ flycheck-error-new-at-pos
+ (pos
+ &optional level message
+ &key end-pos checker id group
+ (filename (buffer-file-name)) (buffer (current-buffer))
+ &aux
+ ((line . column)
+ (if pos (flycheck-line-column-at-pos pos)
+ '(nil . nil)))
+ ((-end-line . -end-column)
+ (if end-pos (flycheck-line-column-at-pos end-pos)
+ '(nil . nil))))))
+ "Structure representing an error reported by a syntax checker.
+Slots:
+
+`buffer'
+ The buffer that the error was reported for, as buffer object.
+
+`checker'
+ The syntax checker which reported this error, as symbol.
+
+`filename'
+ The file name the error refers to, as string.
+
+`line'
+ The line on which the error starts, as number.
+
+`column' (optional)
+ The column at which the error starts, as number.
+
+ For compatibility with external tools and unlike Emacs
+ itself (e.g. in Compile Mode) Flycheck uses _1-based_
+ columns: The first character on a line is column 1.
+
+ Occasionally some tools try to proactively adapt to Emacs
+ and emit 0-based columns automatically. In these cases, the
+ columns must be adjusted for Flycheck, see
+ `flycheck-increment-error-columns'.
+
+ If nil, the whole line is highlighted.
+
+`end-line' (optional)
+ The line on which the error ends. If nil, this is computed according to
+ `flycheck-highlighting-mode'.
+
+`end-column'
+ The column at which the error ends. If nil, this is computed according to
+ `flycheck-highlighting-mode'. Error intervals are right-open: the
+ end-column points to the first character not included in the error. For
+ example, 1:1 is an empty range. and in \"line-number-at-pos\", the range
+ 6:12 covers the word \"number\".
+
+`message' (optional)
+ The error message as a string, if any.
+
+`level'
+ The error level, as either `info', `warning' or `error'.
+
+`id' (optional)
+ An ID identifying the kind of error.
+
+`group' (optional)
+ A symbol identifying the group the error belongs to.
+
+ Some tools will emit multiple errors that relate to the same
+ issue (e.g., lifetime errors in Rust). All related errors
+ collected by a checker should have the same `group` value,
+ in order to be able to present them to the user.
+
+ See `flycheck-related-errors`."
+ buffer checker filename line column message level id group
+ ;; The fields below are at the end of the record to preserve backwards
+ ;; compatibility; see https://github.com/flycheck/flycheck/pull/1400 and
+ ;; https://lists.gnu.org/archive/html/emacs-devel/2018-07/msg00436.html
+ -end-line -end-column)
+
+;; These accessors are defined for backwards compatibility
+;; FIXME: Clean up once package.el learns how to recompile dependencies.
+
+(defun flycheck-error-end-line (err)
+ "Return the end line of a Flycheck error ERR."
+ (condition-case nil (flycheck-error--end-line err)
+ (args-out-of-range nil)))
+
+(defun flycheck-error-end-column (err)
+ "Return the end column of a Flycheck error ERR."
+ (condition-case nil (flycheck-error--end-column err)
+ (args-out-of-range nil)))
+
+(defun flycheck-error--set-end-line (err line)
+ "Set the end line of a Flycheck error ERR to LINE."
+ (condition-case nil (setf (flycheck-error--end-line err) line)
+ (args-out-of-range nil)))
+
+(defun flycheck-error--set-end-column (err column)
+ "Set the end column of a Flycheck error ERR to COLUMN."
+ (condition-case nil (setf (flycheck-error--end-column err) column)
+ (args-out-of-range nil)))
+
+(gv-define-simple-setter flycheck-error-end-line
+ flycheck-error--set-end-line)
+(gv-define-simple-setter flycheck-error-end-column
+ flycheck-error--set-end-column)
+
+(defmacro flycheck-error-with-buffer (err &rest forms)
+ "Switch to the buffer of ERR and evaluate FORMS.
+
+If the buffer of ERR is not live, FORMS are not evaluated."
+ (declare (indent 1) (debug t))
+ `(when (buffer-live-p (flycheck-error-buffer ,err))
+ (with-current-buffer (flycheck-error-buffer ,err)
+ ,@forms)))
+
+(defun flycheck--exact-region (err)
+ "Get the region of ERR, if ERR specifies a range.
+
+Return a cons cell `(BEG . END)'. If the input range is empty,
+it is expanded to cover at least one character so that END is
+always greater than BEG. If ERR doesn't specify an end-column
+return nil."
+ (-if-let* ((line (flycheck-error-line err))
+ (column (flycheck-error-column err))
+ (end-line (or (flycheck-error-end-line err) line))
+ (end-column (flycheck-error-end-column err)))
+ ;; Ignoring fields speeds up calls to `line-end-position'.
+ (let* ((inhibit-field-text-motion t)
+ (beg (flycheck-line-column-to-position line column))
+ (end (flycheck-line-column-to-position end-line end-column)))
+ (cond
+ ((< beg end) (cons beg end))
+ ((= end (point-max)) (cons (1- end) end))
+ (t (cons end (1+ end)))))))
+
+(defun flycheck--line-region (pos)
+ "Get the line region of position POS.
+
+Return a cons cell `(BEG . END)' where BEG is the first
+non-whitespace character on the line ERR refers to, and END the
+end of the line."
+ (save-excursion
+ (goto-char pos)
+ (forward-line 0)
+ (let ((bol (point))
+ (end (line-end-position)))
+ ;; Move to the beginning of this line's indentation, similar to
+ ;; `back-to-indentation'
+ (skip-syntax-forward " " end)
+ (backward-prefix-chars)
+ ;; If the current line is blank, highlight it in full; if it's
+ ;; empty, include the previous line break character(s) to have
+ ;; any region at all (when called with 0, `line-end-position'
+ ;; gives us the end of the previous line).
+ (cons (if (eolp) (if (= bol end) (line-end-position 0) bol) (point))
+ end))))
+
+(defun flycheck--column-region (pos)
+ "Get the column region of position POS.
+
+Return a cons cell `(BEG . END)' where BEG is the character
+before the column, and END the actual column."
+ (save-excursion
+ (goto-char pos)
+ ;; (eobp): No enough lines in the buffer
+ (if (eobp) (cons (1- (point-max)) (point-max))
+ (cons pos (1+ pos)))))
+
+(defun flycheck-bounds-of-thing-at-point (thing pos)
+ "Get the region of THING at position POS.
+
+THING is a understood by `thing-at-point'.
+
+Return a cons cell `(BEG . END)' where BEG is the beginning of
+the THING at the column, and END the end of the THING."
+ (save-excursion
+ (goto-char pos)
+ (bounds-of-thing-at-point thing)))
+
+(defun flycheck--approximate-region (err mode)
+ "Compute the region of ERR based on MODE and ERR's line and column."
+ ;; Ignoring fields speeds up calls to `line-end-position'.
+ (let* ((inhibit-field-text-motion t)
+ (line (flycheck-error-line err))
+ (column (flycheck-error-column err))
+ (beg (flycheck-line-column-to-position line (or column 1))))
+ (if (or (null column)
+ (eq mode 'lines))
+ (flycheck--line-region beg)
+ (or (pcase mode
+ (`symbols
+ ;; Ensure that we're on a word or symbol. See
+ ;; https://github.com/flycheck/flycheck/issues/1519
+ (and (<= (point-min) beg) (< beg (point-max))
+ (memq (char-syntax (char-after beg)) '(?w ?_))
+ (flycheck-bounds-of-thing-at-point 'symbol beg)))
+ (`sexps
+ (flycheck-bounds-of-thing-at-point 'sexp beg)))
+ (flycheck--column-region beg)))))
+
+(defun flycheck-error-region-for-mode (err mode)
+ "Get the region of ERR for the highlighting MODE.
+
+ERR is a Flycheck error. If its position is fully specified, use
+that to compute a region; otherwise, use MODE, as documented in
+`flycheck-highlighting-mode'. If MODE is nil, signal an error."
+ (flycheck-error-with-buffer err
+ (save-restriction
+ (widen)
+ (or (flycheck--exact-region err)
+ (flycheck--approximate-region err mode)))))
+
+(defun flycheck-error-pos (err)
+ "Get the buffer position of ERR.
+
+ERR is a Flycheck error whose position to get.
+
+The error position is the error column, or the first
+non-whitespace character of the error line, if ERR has no error column."
+ (car (flycheck-error-region-for-mode
+ err flycheck-highlighting-mode)))
+
+(defun flycheck-error-format-snippet (err &optional max-length)
+ "Extract the text that ERR refers to from the buffer.
+
+Newlines and blanks are replaced by single spaces. If ERR
+doesn't include an end-position, return nil.
+
+MAX-LENGTH is how many characters to read from the buffer, at
+most. It defaults to 20."
+ (flycheck-error-with-buffer err
+ (save-restriction
+ (widen)
+ (pcase (flycheck--exact-region err)
+ (`(,beg . ,end)
+ (truncate-string-to-width
+ (replace-regexp-in-string
+ "\\s-+" " " (buffer-substring beg (min end (point-max))))
+ (or max-length 20) nil nil t))))))
+
+(defun flycheck-error-format-message-and-id (err &optional include-snippet)
+ "Format the message and id of ERR as human-readable string.
+
+If INCLUDE-SNIPPET is non-nil, prepend the message with a snippet
+of the text that the error applies to (such text can only be
+determined if the error contains a full span, not just a
+beginning position)."
+ (let* ((id (flycheck-error-id err))
+ (fname (flycheck-error-filename err))
+ (other-file-p (and fname (not (equal fname (buffer-file-name))))))
+ (concat (and other-file-p (format "In %S:\n" (file-relative-name fname)))
+ (and include-snippet
+ (-when-let* ((snippet (flycheck-error-format-snippet err)))
+ (flycheck--format-message "`%s': " snippet)))
+ (or (flycheck-error-message err)
+ (format "Unknown %S" (flycheck-error-level err)))
+ (and id (format " [%s]" id)))))
+
+(defun flycheck-error-format-position (err)
+ "Format the position of ERR as a human-readable string."
+ (let ((line (flycheck-error-line err))
+ (column (flycheck-error-column err))
+ (end-line (flycheck-error-end-line err))
+ (end-column (flycheck-error-end-column err)))
+ (if (and line column)
+ (if (or (null end-line) (equal line end-line))
+ (if (or (null end-column) (equal column (1- end-column)))
+ (format "%d:%d" line column)
+ (format "%d:%d-%d" line column end-column))
+ (format "(%d:%d)-(%d:%d)" line column end-line end-column))
+ (if (or (null end-line) (equal line end-line))
+ (format "%d" line)
+ (format "%d-%d" line end-line)))))
+
+(defun flycheck-error-format (err &optional with-file-name)
+ "Format ERR as human-readable string, optionally WITH-FILE-NAME.
+
+Return a string that represents the given ERR. If WITH-FILE-NAME
+is given and non-nil, include the file-name as well, otherwise
+omit it."
+ (let* ((level (symbol-name (flycheck-error-level err)))
+ (checker (symbol-name (flycheck-error-checker err)))
+ (format `(,@(when with-file-name
+ (list (flycheck-error-filename err) ":"))
+ ,(flycheck-error-format-position err) ":"
+ ,level ": "
+ ,(flycheck-error-format-message-and-id err)
+ " (" ,checker ")")))
+ (apply #'concat format)))
+
+(defun flycheck-error-< (err1 err2)
+ "Determine whether ERR1 is less than ERR2 by location."
+ (let ((l1 (flycheck-error-line err1))
+ (l2 (flycheck-error-line err2)))
+ (if (/= l1 l2)
+ (< l1 l2)
+ (let ((c1 (or (flycheck-error-column err1) 1))
+ (c2 (or (flycheck-error-column err2) 1)))
+ (if (/= c1 c2)
+ (< c1 c2)
+ (let ((el1 (or (flycheck-error-end-line err1) l1))
+ (el2 (or (flycheck-error-end-line err2) l2)))
+ (if (/= el1 el2)
+ (< el1 el2)
+ (let ((cl1 (or (flycheck-error-end-column err1) 1))
+ (cl2 (or (flycheck-error-end-column err2) 1)))
+ (< cl1 cl2)))))))))
+
+(defun flycheck-error-level-< (err1 err2)
+ "Determine whether ERR1 is less than ERR2 by error level.
+
+Like `flycheck-error-<', but compares by error level severity
+first. Levels of the same severity are compared by name."
+ (let* ((level1 (flycheck-error-level err1))
+ (level2 (flycheck-error-level err2))
+ (severity1 (flycheck-error-level-severity level1))
+ (severity2 (flycheck-error-level-severity level2)))
+ (cond
+ ((= severity1 severity2)
+ (if (string= level1 level2)
+ (flycheck-error-< err1 err2)
+ (string< level1 level2)))
+ (t (< severity1 severity2)))))
+
+(defun flycheck-assert-error-list-p (errors)
+ "Assert that all items in ERRORS are of `flycheck-error' type.
+
+Signal an error if any item in ERRORS is not a `flycheck-error'
+object, as by `flycheck-error-p'. Otherwise return ERRORS
+again."
+ (unless (listp errors)
+ (signal 'wrong-type-argument (list 'listp errors)))
+ (dolist (err errors)
+ (unless (flycheck-error-p err)
+ (signal 'wrong-type-argument (list 'flycheck-error-p err))))
+ errors)
+
+
+;;; Errors in the current buffer
+(defvar-local flycheck-current-errors nil
+ "A list of all errors and warnings in the current buffer.")
+
+(defun flycheck-report-current-errors (errors)
+ "Report ERRORS in the current buffer.
+
+Add ERRORS to `flycheck-current-errors' and process each error
+with `flycheck-process-error-functions'."
+ (setq flycheck-current-errors (append errors flycheck-current-errors))
+ (overlay-recenter (point-max))
+ ;; We can't use `seq-sort-by' because it's not in Emacs 25's built-in `seq',
+ ;; and installing an updated version doesn't help (this is a package.el bug;
+ ;; see https://lists.gnu.org/archive/html/emacs-devel/2020-04/msg01974.html).
+ (seq-do (lambda (err)
+ (run-hook-with-args-until-success 'flycheck-process-error-functions
+ err))
+ (seq-sort (lambda (e1 e2)
+ (< (flycheck-error-line e1) (flycheck-error-line e2)))
+ errors)))
+
+(defun flycheck-clear-errors ()
+ "Remove all error information from the current buffer."
+ (setq flycheck-current-errors nil)
+ (flycheck-report-status 'not-checked))
+
+(defun flycheck-fill-and-expand-error-file-names (errors directory)
+ "Fill and expand file names in ERRORS relative to DIRECTORY.
+
+Expand all file names of ERRORS against DIRECTORY. If the file
+name of an error is nil fill in the result of function
+`buffer-file-name' in the current buffer.
+
+Return ERRORS, modified in-place."
+ (seq-do (lambda (err)
+ (setf (flycheck-error-filename err)
+ (-if-let (filename (flycheck-error-filename err))
+ (expand-file-name filename directory)
+ (buffer-file-name))))
+ errors)
+ errors)
+
+(defun flycheck-relevant-error-other-file-p (err)
+ "Determine whether ERR is a relevant error for another file."
+ (let ((file-name (flycheck-error-filename err)))
+ (and file-name
+ flycheck-relevant-error-other-file-show
+ (or (null buffer-file-name)
+ (not (flycheck-same-files-p buffer-file-name file-name)))
+ (<= (flycheck-error-level-severity
+ flycheck-relevant-error-other-file-minimum-level)
+ (flycheck-error-level-severity (flycheck-error-level err))))))
+
+(defun flycheck-relevant-error-p (err)
+ "Determine whether ERR is relevant for the current buffer.
+
+Return t if ERR may be shown for the current buffer, or nil
+otherwise."
+ (flycheck-error-with-buffer err
+ (let ((file-name (flycheck-error-filename err))
+ (message (flycheck-error-message err)))
+ (and
+ (or
+ ;; Neither the error nor buffer have a file name
+ (and (not file-name) (not buffer-file-name))
+ ;; Both have files, and they match
+ (and buffer-file-name file-name
+ (flycheck-same-files-p file-name buffer-file-name))
+ ;; This is a significant error from another file
+ (flycheck-relevant-error-other-file-p err))
+ message
+ (not (string-empty-p message))
+ ;; Errors without line numbers are discarded. If a linter
+ ;; reports relevant errors without line numbers, use
+ ;; `flycheck-fill-empty-line-numbers' as the checker's
+ ;; `:error-filter' to set them to line 0.
+ (flycheck-error-line err)))))
+
+(defun flycheck-relevant-errors (errors)
+ "Filter the relevant errors from ERRORS.
+
+Return a list of all errors that are relevant for their
+corresponding buffer."
+ (seq-filter #'flycheck-relevant-error-p errors))
+
+(defun flycheck-related-errors (err &optional error-set)
+ "Get all the errors that are in the same group as ERR.
+
+Return a list of all errors (from ERROR-SET) that have the same
+`flycheck-error-group' as ERR, including ERR itself.
+
+If ERROR-SET is nil, `flycheck-current-errors' is used instead."
+ (let ((group (flycheck-error-group err))
+ (checker (flycheck-error-checker err)))
+ (if group
+ (seq-filter (lambda (e)
+ (and (eq (flycheck-error-checker e) checker)
+ (eq (flycheck-error-group e) group)))
+ (or error-set flycheck-current-errors))
+ (list err))))
+
+
+;;; Status reporting for the current buffer
+(defvar-local flycheck-last-status-change 'not-checked
+ "The last status change in the current buffer.")
+
+(defun flycheck-report-failed-syntax-check (&optional status)
+ "Report a failed Flycheck syntax check with STATUS.
+
+STATUS is a status symbol for `flycheck-report-status',
+defaulting to `errored'.
+
+Clear Flycheck state, run `flycheck-syntax-check-failed-hook' and
+report an error STATUS."
+ (flycheck-clear)
+ (setq flycheck-current-syntax-check nil)
+ (run-hooks 'flycheck-syntax-check-failed-hook)
+ (flycheck-report-status (or status 'errored)))
+
+(defun flycheck-report-status (status)
+ "Report Flycheck STATUS.
+
+STATUS is one of the following symbols:
+
+`not-checked'
+ The current buffer was not checked.
+
+`no-checker'
+ Automatic syntax checker selection did not find a suitable
+ syntax checker.
+
+`running'
+ A syntax check is now running in the current buffer.
+
+`errored'
+ The current syntax check has errored.
+
+`finished'
+ The current syntax check was finished normally.
+
+`interrupted'
+ The current syntax check was interrupted.
+
+`suspicious'
+ The last syntax check had a suspicious result.
+
+Set `flycheck-last-status-change' and call
+`flycheck-status-changed-functions' with STATUS. Afterwards
+refresh the mode line."
+ (setq flycheck-last-status-change status)
+ (run-hook-with-args 'flycheck-status-changed-functions status)
+ (force-mode-line-update))
+
+(defun flycheck-mode-line-status-text (&optional status)
+ "Get a text describing STATUS for use in the mode line.
+
+STATUS defaults to `flycheck-last-status-change' if omitted or
+nil."
+ (let ((text (pcase (or status flycheck-last-status-change)
+ (`not-checked "")
+ (`no-checker "-")
+ (`running "*")
+ (`errored "!")
+ (`finished
+ (let-alist (flycheck-count-errors flycheck-current-errors)
+ (if (or .error .warning)
+ (format ":%s|%s" (or .error 0) (or .warning 0))
+ "")))
+ (`interrupted ".")
+ (`suspicious "?"))))
+ (concat " " flycheck-mode-line-prefix text)))
+
+
+;;; Error levels
+(defun flycheck-make-margin-spec (margin-str face)
+ "Make a display spec to indicate errors in the margins.
+
+Returns MARGIN-STR with FACE applied."
+ (propertize margin-str 'face `(,face default)))
+
+(defconst flycheck-default-margin-str "»"
+ "String used to indicate errors in the margins.")
+
+(defconst flycheck-default-margin-continuation-str "⋮"
+ "String used to indicate continuation lines in the margins.")
+
+;;;###autoload
+(defun flycheck-define-error-level (level &rest properties)
+ "Define a new error LEVEL with PROPERTIES.
+
+The following PROPERTIES constitute an error level:
+
+`:severity SEVERITY'
+ A number denoting the severity of this level. The higher
+ the number, the more severe is this level compared to other
+ levels. Defaults to 0; info is -10, warning is 10, and
+ error is 100.
+
+ The severity is used by `flycheck-error-level-<' to
+ determine the ordering of errors according to their levels.
+
+`:compilation-level LEVEL'
+
+ A number indicating the broad class of messages that errors
+ at this level belong to: one of 0 (info), 1 (warning), or
+ 2 or nil (error). Defaults to nil.
+
+ This is used by `flycheck-checker-pattern-to-error-regexp'
+ to map error levels into `compilation-mode''s hierarchy and
+ to get proper highlighting of errors in `compilation-mode'.
+
+`:overlay-category CATEGORY'
+ A symbol denoting the overlay category to use for error
+ highlight overlays for this level. See Info
+ node `(elisp)Overlay Properties' for more information about
+ overlay categories.
+
+ A category for an error level overlay should at least define
+ the `face' property, for error highlighting. Another useful
+ property for error level categories is `priority', to
+ influence the stacking of multiple error level overlays.
+
+`:fringe-bitmap BITMAPS'
+ A fringe bitmap symbol denoting the bitmap to use for fringe
+ indicators for this level, or a cons of two bitmaps (one for
+ narrow fringes and one for wide fringes). See Info node
+ `(elisp)Fringe Bitmaps' for more information about fringe
+ bitmaps, including a list of built-in fringe bitmaps.
+
+`:fringe-face FACE'
+ A face symbol denoting the face to use for fringe indicators
+ for this level.
+
+`:margin-spec SPEC'
+ A display specification indicating what to display in the
+ margin when `flycheck-indication-mode' is `left-margin' or
+ `right-margin'. See Info node `(elisp)Displaying in the
+ Margins'. If omitted, Flycheck generates an image spec from
+ the fringe bitmap.
+
+`:error-list-face FACE'
+ A face symbol denoting the face to use for messages of this
+ level in the error list. See `flycheck-list-errors'."
+ (declare (indent 1))
+ (setf (get level 'flycheck-error-level) t)
+ (setf (get level 'flycheck-error-severity)
+ (or (plist-get properties :severity) 0))
+ (setf (get level 'flycheck-compilation-level)
+ (plist-get properties :compilation-level))
+ (setf (get level 'flycheck-overlay-category)
+ (plist-get properties :overlay-category))
+ (setf (get level 'flycheck-fringe-bitmaps)
+ (let ((bitmap (plist-get properties :fringe-bitmap)))
+ (if (consp bitmap) bitmap (cons bitmap bitmap))))
+ ;; Kept for compatibility
+ (setf (get level 'flycheck-fringe-bitmap-double-arrow)
+ (car (get level 'flycheck-fringe-bitmaps)))
+ (setf (get level 'flycheck-fringe-face)
+ (plist-get properties :fringe-face))
+ (setf (get level 'flycheck-margin-spec)
+ (or (plist-get properties :margin-spec)
+ (flycheck-make-margin-spec
+ flycheck-default-margin-str
+ (or (get level 'flycheck-fringe-face) 'default))))
+ (setf (get level 'flycheck-margin-continuation)
+ (flycheck-make-margin-spec
+ flycheck-default-margin-continuation-str
+ (or (get level 'flycheck-fringe-face) 'default)))
+ (setf (get level 'flycheck-error-list-face)
+ (plist-get properties :error-list-face)))
+
+(defun flycheck-error-level-p (level)
+ "Determine whether LEVEL is a Flycheck error level."
+ (get level 'flycheck-error-level))
+
+(defun flycheck-error-level-severity (level)
+ "Get the numeric severity of LEVEL."
+ (or (get level 'flycheck-error-severity) 0))
+
+(defun flycheck-error-level-compilation-level (level)
+ "Get the compilation level for LEVEL."
+ (get level 'flycheck-compilation-level))
+
+(defun flycheck-error-level-overlay-category (level)
+ "Get the overlay category for LEVEL."
+ (get level 'flycheck-overlay-category))
+
+(defun flycheck-error-level-margin-spec (level)
+ "Get the margin spec for LEVEL."
+ (get level 'flycheck-margin-spec))
+
+(defun flycheck-error-level-margin-continuation-spec (level)
+ "Get the margin continuation spec for LEVEL."
+ (get level 'flycheck-margin-continuation))
+
+(defun flycheck-error-level-fringe-bitmap (level &optional hi-res)
+ "Get the fringe bitmap for LEVEL.
+
+Optional argument HI-RES non-nil means that the returned bitmap
+will be the high resolution version."
+ (let ((bitmaps (get level 'flycheck-fringe-bitmaps)))
+ (if hi-res (cdr bitmaps) (car bitmaps))))
+
+(defun flycheck-error-level-fringe-face (level)
+ "Get the fringe face for LEVEL."
+ (get level 'flycheck-fringe-face))
+
+(defun flycheck-error-level-error-list-face (level)
+ "Get the error list face for LEVEL."
+ (get level 'flycheck-error-list-face))
+
+(defun flycheck-error-level-make-indicator (level side &optional continuation)
+ "Create the fringe or margin icon for LEVEL at SIDE.
+
+Return a propertized string that shows an indicator according
+to LEVEL and the given fringe or margin SIDE.
+
+LEVEL is a Flycheck error level defined with
+`flycheck-define-error-level', and SIDE is either `left-fringe',
+`right-fringe', `left-margin', or `right-margin'.
+
+CONTINUATION indicates which fringe bitmap or margin spec to use:
+either the `:fringe-bitmap' and `:margin-spec' properties of
+LEVEL when CONTINUATION is nil or omitted, or bitmaps and specs
+indicating an error spanning more than one line.
+
+Return a propertized string representing the fringe icon,
+intended for use as `before-string' of an overlay to actually
+show the indicator."
+ (propertize
+ "!" 'display
+ (pcase side
+ ((or `left-fringe `right-fringe)
+ (list side
+ (if continuation 'flycheck-fringe-bitmap-continuation
+ (let* ((fringe-width
+ (pcase side
+ (`left-fringe (car (window-fringes)))
+ (`right-fringe (cadr (window-fringes)))))
+ (high-res (>= fringe-width 16)))
+ (flycheck-error-level-fringe-bitmap level high-res)))
+ (flycheck-error-level-fringe-face level)))
+ ((or `left-margin `right-margin)
+ `((margin ,side)
+ ,(or (if continuation
+ (flycheck-error-level-margin-continuation-spec level)
+ (flycheck-error-level-margin-spec level))
+ "")))
+ (_ (error "Invalid fringe side: %S" side)))))
+
+(define-obsolete-function-alias
+ 'flycheck-error-level-make-fringe-icon
+ 'flycheck-error-level-make-indicator
+ "33")
+
+
+;;; Built-in error levels
+(defconst flycheck-fringe-bitmap-double-arrow
+ [#b11011000
+ #b01101100
+ #b00110110
+ #b00011011
+ #b00110110
+ #b01101100
+ #b11011000]
+ "Bitmaps used to indicate errors in the fringes.")
+
+(defconst flycheck-fringe-bitmap-double-arrow-hi-res
+ [#b1111001111000000
+ #b0111100111100000
+ #b0011110011110000
+ #b0001111001111000
+ #b0000111100111100
+ #b0000011110011110
+ #b0000011110011110
+ #b0000111100111100
+ #b0001111001111000
+ #b0011110011110000
+ #b0111100111100000
+ #b1111001111000000]
+ "High-resolution bitmap used to indicate errors in the fringes.")
+
+(defconst flycheck-fringe-bitmap-continuation
+ [#b1000000010000000
+ #b0010000000100000
+ #b0000100000001000
+ #b0000001000000010]
+ "Bitmap used to indicate continuation lines in the fringes.")
+
+(when (fboundp 'define-fringe-bitmap) ;; #ifdef HAVE_WINDOW_SYSTEM
+ (define-fringe-bitmap
+ 'flycheck-fringe-bitmap-double-arrow
+ flycheck-fringe-bitmap-double-arrow)
+ (define-fringe-bitmap
+ 'flycheck-fringe-bitmap-double-arrow-hi-res
+ flycheck-fringe-bitmap-double-arrow-hi-res
+ nil 16)
+ (define-fringe-bitmap
+ 'flycheck-fringe-bitmap-continuation
+ flycheck-fringe-bitmap-continuation
+ nil 16 '(top repeat)))
+
+(defun flycheck-redefine-standard-error-levels
+ (&optional margin-str fringe-bitmap)
+ "Redefine Flycheck's standard error levels.
+
+This is useful to change the character drawn in the
+margins (MARGIN-STR, a string) or the bitmap drawn in the
+fringes (FRINGE-BITMAP, a fringe bitmap symbol or a cons of such
+symbols, as in `flycheck-define-error-level')."
+ (unless margin-str
+ (setq margin-str flycheck-default-margin-str))
+
+ (unless fringe-bitmap
+ (setq fringe-bitmap
+ (cons 'flycheck-fringe-bitmap-double-arrow
+ 'flycheck-fringe-bitmap-double-arrow-hi-res)))
+
+ (setf (get 'flycheck-error-overlay 'face) 'flycheck-error)
+ (setf (get 'flycheck-error-overlay 'priority) 110)
+
+ (flycheck-define-error-level 'error
+ :severity 100
+ :compilation-level 2
+ :overlay-category 'flycheck-error-overlay
+ :margin-spec (flycheck-make-margin-spec margin-str 'flycheck-fringe-error)
+ :fringe-bitmap fringe-bitmap
+ :fringe-face 'flycheck-fringe-error
+ :error-list-face 'flycheck-error-list-error)
+
+ (setf (get 'flycheck-warning-overlay 'face) 'flycheck-warning)
+ (setf (get 'flycheck-warning-overlay 'priority) 100)
+
+ (flycheck-define-error-level 'warning
+ :severity 10
+ :compilation-level 1
+ :overlay-category 'flycheck-warning-overlay
+ :margin-spec (flycheck-make-margin-spec margin-str 'flycheck-fringe-warning)
+ :fringe-bitmap fringe-bitmap
+ :fringe-face 'flycheck-fringe-warning
+ :error-list-face 'flycheck-error-list-warning)
+
+ (setf (get 'flycheck-info-overlay 'face) 'flycheck-info)
+ (setf (get 'flycheck-info-overlay 'priority) 90)
+
+ (flycheck-define-error-level 'info
+ :severity -10
+ :compilation-level 0
+ :overlay-category 'flycheck-info-overlay
+ :margin-spec (flycheck-make-margin-spec margin-str 'flycheck-fringe-info)
+ :fringe-bitmap fringe-bitmap
+ :fringe-face 'flycheck-fringe-info
+ :error-list-face 'flycheck-error-list-info))
+
+(flycheck-redefine-standard-error-levels)
+
+
+;;; Error filtering
+(defun flycheck-filter-errors (errors checker)
+ "Filter ERRORS from CHECKER.
+
+Apply the error filter of CHECKER to ERRORs and return the
+result. If CHECKER has no error filter, fall back to
+`flycheck-sanitize-errors'."
+ (let ((filter (or (flycheck-checker-get checker 'error-filter)
+ #'flycheck-sanitize-errors)))
+ (funcall filter errors)))
+
+(defun flycheck-sanitize-errors (errors)
+ "Sanitize ERRORS.
+
+Sanitize ERRORS by trimming leading and trailing whitespace in
+all error messages, and by replacing 0 columns and empty error
+messages with nil.
+
+Returns sanitized ERRORS."
+ (dolist (err errors)
+ (flycheck-error-with-buffer err
+ (let ((message (flycheck-error-message err))
+ (id (flycheck-error-id err)))
+ (when message
+ (setq message (string-trim message))
+ (setf (flycheck-error-message err)
+ (if (string-empty-p message) nil message)))
+ (when (and id (string-empty-p id))
+ (setf (flycheck-error-id err) nil))
+ (when (eq (flycheck-error-column err) 0)
+ (setf (flycheck-error-column err) nil))
+ (when (eq (flycheck-error-end-column err) 0)
+ (setf (flycheck-error-end-column err) nil)))))
+ errors)
+
+(defun flycheck-remove-error-file-names (file-name errors)
+ "Remove matching FILE-NAME from ERRORS.
+
+Use as `:error-filter' for syntax checkers that output faulty
+filenames. Flycheck will later fill in the buffer file name.
+
+Return ERRORS."
+ (seq-do (lambda (err)
+ (when (and (flycheck-error-filename err)
+ (string= (flycheck-error-filename err) file-name))
+ (setf (flycheck-error-filename err) nil)))
+ errors)
+ errors)
+
+(defun flycheck-increment-error-columns (errors &optional offset)
+ "Increment all columns of ERRORS by OFFSET (default: 1).
+
+ Use this as `:error-filter' if a syntax checker outputs 0-based
+ columns."
+ (setq offset (or offset 1)) ;; Emacs bug #31715
+ (seq-do (lambda (err)
+ (when (flycheck-error-column err)
+ (cl-incf (flycheck-error-column err) offset))
+ (when (flycheck-error-end-column err)
+ (cl-incf (flycheck-error-end-column err) offset)))
+ errors)
+ errors)
+
+(defun flycheck-collapse-error-message-whitespace (errors)
+ "Collapse whitespace in all messages of ERRORS.
+
+Return ERRORS."
+ (dolist (err errors)
+ (-when-let (message (flycheck-error-message err))
+ (setf (flycheck-error-message err)
+ (replace-regexp-in-string (rx (one-or-more (any space "\n" "\r")))
+ " " message 'fixed-case 'literal))))
+ errors)
+
+(defun flycheck-dedent-error-messages (errors)
+ "Dedent all messages of ERRORS.
+
+For each error in ERRORS, determine the indentation offset from
+the leading whitespace of the first line, and dedent all further
+lines accordingly.
+
+Return ERRORS, with in-place modifications."
+ (dolist (err errors)
+ (-when-let (message (flycheck-error-message err))
+ (with-temp-buffer
+ (insert message)
+ ;; Determine the indentation offset
+ (goto-char (point-min))
+ (back-to-indentation)
+ (let* ((indent-offset (- (point) (point-min))))
+ ;; Now iterate over all lines and dedent each according to
+ ;; `indent-offset'
+ (while (not (eobp))
+ (back-to-indentation)
+ ;; If the current line starts with sufficient whitespace, delete the
+ ;; indentation offset. Otherwise keep the line intact, as we might
+ ;; loose valuable information
+ (when (>= (- (point) (line-beginning-position)) indent-offset)
+ (delete-char (- indent-offset)))
+ (forward-line 1)))
+ (delete-trailing-whitespace (point-min) (point-max))
+ (setf (flycheck-error-message err)
+ (buffer-substring-no-properties (point-min) (point-max))))))
+ errors)
+
+(defun flycheck-fold-include-levels (errors sentinel-message)
+ "Fold levels of ERRORS from included files.
+
+ERRORS is a list of `flycheck-error' objects. SENTINEL-MESSAGE
+is a regular expression matched against the error message to
+determine whether the error denotes errors from an included
+file. Alternatively, it is a function that is given an error and
+shall return non-nil, if the error denotes errors from an
+included file."
+ (unless (or (stringp sentinel-message) (functionp sentinel-message))
+ (error "Sentinel must be string or function: %S" sentinel-message))
+ (let ((sentinel (if (functionp sentinel-message)
+ sentinel-message
+ (lambda (err)
+ (string-match-p sentinel-message
+ (flycheck-error-message err)))))
+ (remaining-errors errors))
+ (while remaining-errors
+ (let* ((current-error (pop remaining-errors)))
+ (when (funcall sentinel current-error)
+ ;; We found an error denoting errors in the included file:
+ ;; 1. process all subsequent errors until faulty include file is found
+ ;; 2. process again all subsequent errors until an error has the
+ ;; current file name again
+ ;; 3. find the most severe error level
+ (let ((current-filename (flycheck-error-filename current-error))
+ (current-level nil)
+ (faulty-include-filename nil)
+ (filename nil)
+ (done (null remaining-errors)))
+
+ (while (not done)
+ (setq filename (flycheck-error-filename (car remaining-errors)))
+ (unless faulty-include-filename
+ (unless (string= filename current-filename)
+ (setq faulty-include-filename filename)))
+
+ (let* ((error-in-include (pop remaining-errors))
+ (in-include-level (flycheck-error-level error-in-include)))
+ (unless (funcall sentinel error-in-include)
+ ;; Ignore nested "included file" errors, we are only
+ ;; interested in real errors because these define our level
+ (when (or (not current-level)
+ (> (flycheck-error-level-severity in-include-level)
+ (flycheck-error-level-severity current-level)))
+ (setq current-level in-include-level))))
+
+ (setq done (or (null remaining-errors)
+ (and faulty-include-filename
+ (string= filename current-filename)))))
+
+ (setf (flycheck-error-level current-error) current-level
+ (flycheck-error-message current-error)
+ (format "In include %s" faulty-include-filename))))))
+ errors))
+
+(defun flycheck-dequalify-error-ids (errors)
+ "De-qualify error ids in ERRORS.
+
+Remove all qualifications from error ids in ERRORS, by stripping
+all leading dotted components from error IDs. For instance, if
+the error ID is com.foo.E100, replace it with E100.
+
+This error filter is mainly useful to simplify error IDs obtained
+from parsing Checkstyle XML, which frequently has very verbose
+IDs, that include the name of the tool."
+ (seq-do (lambda (err)
+ (let ((id (flycheck-error-id err)))
+ (when id
+ (setf (flycheck-error-id err)
+ (replace-regexp-in-string
+ (rx string-start
+ (group
+ (optional (zero-or-more not-newline) "."))
+ (one-or-more (not (any ".")))
+ string-end)
+ "" id 'fixedcase 'literal 1)))))
+ errors)
+ errors)
+
+(defun flycheck-remove-error-ids (errors)
+ "Remove all error ids from ERRORS."
+ (seq-do (lambda (err) (setf (flycheck-error-id err) nil)) errors)
+ errors)
+
+(defun flycheck-fill-empty-line-numbers (errors)
+ "Set ERRORS without lines to line 0.
+
+Use as `:error-filter' for syntax checkers that output errors
+without line numbers.
+
+Return ERRORS."
+ (seq-do (lambda (err)
+ (unless (flycheck-error-line err)
+ (setf (flycheck-error-line err) 0)))
+ errors)
+ errors)
+
+
+;;; Error analysis
+(defun flycheck-count-errors (errors)
+ "Count the number of ERRORS, grouped by level.
+
+Return an alist, where each ITEM is a cons cell whose `car' is an
+error level, and whose `cdr' is the number of errors of that
+level."
+ (let (counts-by-level)
+ (dolist (err errors)
+ (let* ((level (flycheck-error-level err))
+ (item (assq level counts-by-level)))
+ (if item
+ (cl-incf (cdr item))
+ (push (cons level 1) counts-by-level))))
+ counts-by-level))
+
+(defun flycheck-has-max-errors-p (errors level)
+ "Check if there is no error in ERRORS more severe than LEVEL."
+ (let ((severity (flycheck-error-level-severity level)))
+ (seq-every-p (lambda (e) (<= (flycheck-error-level-severity
+ (flycheck-error-level e))
+ severity))
+ errors)))
+
+(defun flycheck-has-max-current-errors-p (level)
+ "Check if there is no current error more severe than LEVEL."
+ (flycheck-has-max-errors-p flycheck-current-errors level))
+
+(defun flycheck-has-errors-p (errors level)
+ "Determine if there are any ERRORS with LEVEL."
+ (seq-some (lambda (e) (eq (flycheck-error-level e) level)) errors))
+
+(defun flycheck-has-current-errors-p (&optional level)
+ "Determine if the current buffer has errors with LEVEL.
+
+If LEVEL is omitted if the current buffer has any errors at all."
+ (if level
+ (flycheck-has-errors-p flycheck-current-errors level)
+ (and flycheck-current-errors t)))
+
+
+;;; Error overlays in the current buffer
+(defvar-local flycheck--last-overlay-index 0
+ "Last index given to a Flycheck overlay.
+
+These indices are used to preserve error order (Emacs doesn't
+preserve overlay order when calling `overlays-at').")
+
+(defun flycheck--next-overlay-index ()
+ "Compute the index to assign to a new Flycheck overlay."
+ (cl-incf flycheck--last-overlay-index))
+
+(defun flycheck--highlighting-style (err)
+ "Determine the highlighting style to apply to ERR.
+
+Styles are documented in `flycheck-highlighting-style'; this
+functions resolves `conditional' style specifications."
+ (let* ((style flycheck-highlighting-style)
+ (first-line (flycheck-error-line err))
+ (end-line (or (flycheck-error-end-line err) first-line))
+ (nlines (- end-line first-line)))
+ (while (eq (car-safe style) 'conditional)
+ (pcase-let ((`(,threshold ,s1 ,s2) (cdr style)))
+ (setq style (if (< nlines threshold) s1 s2))))
+ (pcase style
+ (`(delimiters ,before ,after)
+ (when (characterp before)
+ (setq before (flycheck--make-highlighting-delimiter before)))
+ (when (characterp after)
+ (setq after (flycheck--make-highlighting-delimiter after)))
+ (setq style `(delimiters ,before ,after))))
+ style))
+
+(defun flycheck--setup-highlighting (err overlay)
+ "Apply properties to OVERLAY to highlight ERR."
+ (let ((level (flycheck-error-level err)))
+ (unless flycheck-highlighting-mode
+ ;; Erase the highlighting from the overlay if requested by the user
+ (setf (overlay-get overlay 'face) nil))
+ (when flycheck-indication-mode
+ (setf (overlay-get overlay 'before-string)
+ (flycheck-error-level-make-indicator
+ level flycheck-indication-mode))
+ (setf (overlay-get overlay 'line-prefix)
+ (flycheck-error-level-make-indicator
+ level flycheck-indication-mode t)))
+ (pcase (flycheck--highlighting-style err)
+ ((or `nil (guard (null flycheck-highlighting-mode)))
+ ;; Erase the highlighting
+ (setf (overlay-get overlay 'face) nil))
+ (`level-face)
+ (`(delimiters ,before ,after)
+ ;; Replace the highlighting with delimiters
+ (let* ((fringe-face (flycheck-error-level-fringe-face level))
+ (delim-face `(flycheck-error-delimiter ,fringe-face)))
+ (setf (overlay-get overlay 'face) 'flycheck-delimited-error)
+ (setf (overlay-get overlay 'before-string)
+ (concat (propertize before 'face delim-face)
+ (or (overlay-get overlay 'before-string) "")))
+ (setf (overlay-get overlay 'after-string)
+ (propertize after 'face delim-face))))
+ (other (error "Unsupported highlighting style: %S" other)))))
+
+(defun flycheck-add-overlay (err)
+ "Add overlay for ERR.
+
+Return the created overlay."
+ ;; We must have a proper error region for the sake of fringe indication,
+ ;; error display and error navigation, even if the highlighting is disabled.
+ ;; We erase the highlighting later on in this case
+ (pcase-let* ((`(,beg . ,end)
+ (if (flycheck-relevant-error-other-file-p err)
+ ;; Display overlays for other-file errors on the first line
+ (cons (point-min)
+ (save-excursion (goto-char (point-min))
+ (point-at-eol)))
+ (flycheck-error-region-for-mode
+ err (or flycheck-highlighting-mode 'lines))))
+ (overlay (make-overlay beg end))
+ (level (flycheck-error-level err))
+ (category (flycheck-error-level-overlay-category level))
+ (index (flycheck--next-overlay-index)))
+ (unless (flycheck-error-level-p level)
+ (error "Undefined error level: %S" level))
+ (setf (overlay-get overlay 'flycheck-error-index) index)
+ (setf (overlay-get overlay 'flycheck-overlay) t)
+ (setf (overlay-get overlay 'flycheck-error) err)
+ (setf (overlay-get overlay 'category) category)
+ (setf (overlay-get overlay 'help-echo) #'flycheck-help-echo)
+ (flycheck--setup-highlighting err overlay)
+ overlay))
+
+(defun flycheck-help-echo (_window object pos)
+ "Construct a tooltip message.
+
+Most of the actual work is done by calling
+`flycheck-help-echo-function' with the appropriate list of
+errors. Arguments WINDOW, OBJECT and POS are as described in
+info node `(elisp)Special properties', as this function is
+intended to be used as the 'help-echo property of flycheck error
+overlays."
+ (-when-let (buf (cond ((bufferp object) object)
+ ((overlayp object) (overlay-buffer object))))
+ (with-current-buffer buf
+ (-when-let* ((fn flycheck-help-echo-function)
+ (errs (flycheck-overlay-errors-at pos)))
+ (propertize (funcall fn errs) 'help-echo-inhibit-substitution t)))))
+
+(defun flycheck-help-echo-all-error-messages (errs)
+ "Concatenate error messages and ids from ERRS."
+ (pcase (delq nil errs) ;; FIXME why would errors be nil here?
+ (`(,err) ;; A single error
+ (flycheck-error-format-message-and-id err))
+ (_ ;; Zero or multiple errors
+ (mapconcat
+ (lambda (err)
+ (flycheck-error-format-message-and-id err 'include-snippet))
+ errs "\n"))))
+
+(defun flycheck-filter-overlays (overlays)
+ "Get all Flycheck overlays from OVERLAYS, in original order."
+ ;; The order of errors returned from overlays is not stable, so we sort
+ ;; them again using the internal index to guarantee errors are always
+ ;; displayed in the same order.
+ (seq-sort
+ ;; We can't use `seq-sort-by' here; see above
+ (lambda (o1 o2) (< (overlay-get o1 'flycheck-error-index)
+ (overlay-get o2 'flycheck-error-index)))
+ (seq-filter (lambda (o) (overlay-get o 'flycheck-overlay)) overlays)))
+
+(defun flycheck-overlays-at (pos)
+ "Get all Flycheck overlays at POS."
+ (flycheck-filter-overlays (overlays-at pos)))
+
+(defun flycheck-overlays-in (beg end)
+ "Get all Flycheck overlays between BEG and END."
+ (flycheck-filter-overlays (overlays-in beg end)))
+
+(defun flycheck-overlay-errors-at (pos)
+ "Return a list of all flycheck errors overlaid at POS."
+ (seq-map (lambda (o) (overlay-get o 'flycheck-error))
+ (flycheck-overlays-at pos)))
+
+(defun flycheck-overlay-errors-in (beg end)
+ "Return a list of all flycheck errors overlaid between BEG and END."
+ (seq-map (lambda (o) (overlay-get o 'flycheck-error))
+ (flycheck-overlays-in beg end)))
+
+(defvar-local flycheck-overlays-to-delete nil
+ "Overlays mark for deletion after all syntax checks completed.")
+(put 'flycheck-overlays-to-delete 'permanent-local t)
+
+(defun flycheck-delete-all-overlays ()
+ "Remove all flycheck overlays in the current buffer."
+ (overlay-recenter (point-max))
+ (flycheck-delete-marked-overlays)
+ (setq flycheck--last-overlay-index 0)
+ (save-restriction
+ (widen)
+ (seq-do #'delete-overlay (flycheck-overlays-in (point-min) (point-max)))))
+
+(defun flycheck-mark-all-overlays-for-deletion ()
+ "Mark all current overlays for deletion."
+ (setq flycheck-overlays-to-delete
+ (append (flycheck-overlays-in (point-min) (point-max))
+ flycheck-overlays-to-delete)))
+
+(defun flycheck-delete-marked-overlays ()
+ "Delete all overlays marked for deletion."
+ (overlay-recenter (point-max))
+ (seq-do #'delete-overlay flycheck-overlays-to-delete)
+ (setq flycheck-overlays-to-delete nil))
+
+
+;;; Error navigation in the current buffer
+(defun flycheck-error-level-interesting-at-pos-p (pos)
+ "Check if error severity at POS passes `flycheck-error-level-interesting-p'."
+ (flycheck-error-level-interesting-p (get-char-property pos 'flycheck-error)))
+
+(defun flycheck-error-level-interesting-p (err)
+ "Check if ERR severity is >= `flycheck-navigation-minimum-level'.
+
+ERR is also interesting (the function returns true) if there are
+no errors as or more severe than `flycheck-navigation-minimum-level'."
+ (when (flycheck-error-p err)
+ (-if-let (min-level flycheck-navigation-minimum-level)
+ (or (<= (flycheck-error-level-severity min-level)
+ (flycheck-error-level-severity (flycheck-error-level err)))
+ (not (flycheck-has-current-errors-p min-level)))
+ t)))
+
+(defun flycheck-next-error-pos (n &optional reset)
+ "Get the position of the N-th next error.
+
+With negative N, get the position of the (-N)-th previous error
+instead. With non-nil RESET, search from `point-min', otherwise
+search from the current point.
+
+Return the position of the next or previous error, or nil if
+there is none. If N is zero, return `point', or `point-min' if
+RESET is non-nil."
+ (let ((n (or n 1))
+ (pos (if reset (point-min) (point))))
+ (if (>= n 0)
+ ;; Search forwards
+ (while (and pos (> n 0))
+ (setq n (1- n))
+ (when (get-char-property pos 'flycheck-error)
+ ;; Move beyond from the current error if any
+ (setq pos (next-single-char-property-change pos 'flycheck-error)))
+ (while (not (or (= pos (point-max))
+ (flycheck-error-level-interesting-at-pos-p pos)))
+ ;; Scan for the next error
+ (setq pos (next-single-char-property-change pos 'flycheck-error)))
+ (when (and (= pos (point-max))
+ (not (flycheck-error-level-interesting-at-pos-p pos)))
+ ;; If we reached the end of the buffer, but no error, we didn't find
+ ;; any
+ (setq pos nil)))
+ ;; Search backwards
+ (while (and pos (< n 0))
+ (setq n (1+ n))
+ ;; Loop until we find an error. We need to check the position *before*
+ ;; the current one, because `previous-single-char-property-change'
+ ;; always moves to the position *of* the change.
+ (while (not (or (= pos (point-min))
+ (flycheck-error-level-interesting-at-pos-p (1- pos))))
+ (setq pos (previous-single-char-property-change pos 'flycheck-error)))
+ (when (and (= pos (point-min))
+ (not (flycheck-error-level-interesting-at-pos-p pos)))
+ ;; We didn't find any error.
+ (setq pos nil))
+ (when pos
+ ;; We found an error, so move to its beginning
+ (setq pos (previous-single-char-property-change pos
+ 'flycheck-error)))))
+ pos))
+
+(defun flycheck-next-error-function (n reset)
+ "Visit the N-th error from the current point.
+
+N is the number of errors to advance by, where a negative N
+advances backwards. With non-nil RESET, advance from the
+beginning of the buffer, otherwise advance from the current
+position.
+
+Intended for use with `next-error-function'."
+ (-if-let* ((pos (flycheck-next-error-pos n reset))
+ (err (get-char-property pos 'flycheck-error)))
+ (flycheck-jump-to-error err)
+ (user-error "No more Flycheck errors")))
+
+(defun flycheck-next-error (&optional n reset)
+ "Visit the N-th error from the current point.
+
+N is the number of errors to advance by, where a negative N
+advances backwards. With non-nil RESET, advance from the
+beginning of the buffer, otherwise advance from the current
+position."
+ (interactive "P")
+ (when (consp n)
+ ;; Universal prefix argument means reset
+ (setq reset t n nil))
+ (flycheck-next-error-function n reset)
+ (flycheck-display-error-at-point))
+
+(defun flycheck-previous-error (&optional n)
+ "Visit the N-th previous error.
+
+If given, N specifies the number of errors to move backwards by.
+If N is negative, move forwards instead."
+ (interactive "P")
+ (flycheck-next-error (- (or n 1))))
+
+(defun flycheck-first-error (&optional n)
+ "Visit the N-th error from beginning of the buffer.
+
+If given, N specifies the number of errors to move forward from
+the beginning of the buffer."
+ (interactive "P")
+ (flycheck-next-error n 'reset))
+
+
+;;; Listing errors in buffers
+(defconst flycheck-error-list-buffer "*Flycheck errors*"
+ "The name of the buffer to show error lists.")
+
+(defmacro flycheck-error-list-with-buffer (&rest body)
+ "Evaluate BODY in flycheck-error-list-buffer, if it exists."
+ (declare (indent 0) (debug t))
+ `(when (get-buffer flycheck-error-list-buffer)
+ (with-current-buffer flycheck-error-list-buffer
+ ,@body)))
+
+(defvar flycheck-error-list-mode-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map (kbd "f") #'flycheck-error-list-set-filter)
+ (define-key map (kbd "F") #'flycheck-error-list-reset-filter)
+ (define-key map (kbd "n") #'flycheck-error-list-next-error)
+ (define-key map (kbd "p") #'flycheck-error-list-previous-error)
+ (define-key map (kbd "g") #'flycheck-error-list-check-source)
+ (define-key map (kbd "e") #'flycheck-error-list-explain-error)
+ (define-key map (kbd "RET") #'flycheck-error-list-goto-error)
+ map)
+ "The keymap of `flycheck-error-list-mode'.")
+
+(defun flycheck-error-list-make-last-column (message checker)
+ "Compute contents of the last error list cell.
+
+MESSAGE and CHECKER are displayed in a single column to allow the
+message to stretch arbitrarily far."
+ (let ((checker-name (propertize (symbol-name checker)
+ 'face 'flycheck-error-list-checker-name))
+ (message (propertize message
+ 'face 'flycheck-error-list-error-message)))
+ (format "%s (%s)" message checker-name)))
+
+(defconst flycheck-error-list-format
+ `[("File" 6)
+ ("Line" 5 flycheck-error-list-entry-< :right-align t)
+ ("Col" 3 nil :right-align t)
+ ("Level" 8 flycheck-error-list-entry-level-<)
+ ("ID" 6 t)
+ (,(flycheck-error-list-make-last-column "Message" 'Checker) 0 t)]
+ "Table format for the error list.")
+
+(defconst flycheck-error-list-padding 1
+ "Padding used in error list.")
+
+(defconst flycheck--error-list-msg-offset
+ (seq-reduce
+ (lambda (offset fmt)
+ (pcase-let* ((`(,_ ,width ,_ . ,props) fmt)
+ (padding (or (plist-get props :pad-right) 1)))
+ (+ offset width padding)))
+ (seq-subseq flycheck-error-list-format 0 -1)
+ flycheck-error-list-padding)
+ "Amount of space to use in `flycheck-flush-multiline-message'.")
+
+(define-derived-mode flycheck-error-list-mode tabulated-list-mode
+ "Flycheck errors"
+ "Major mode for listing Flycheck errors.
+
+\\{flycheck-error-list-mode-map}"
+ (setq tabulated-list-format flycheck-error-list-format
+ ;; Sort by location initially
+ tabulated-list-sort-key (cons "Line" nil)
+ tabulated-list-padding flycheck-error-list-padding
+ tabulated-list-entries #'flycheck-error-list-entries
+ ;; `revert-buffer' updates the mode line for us, so all we need to do is
+ ;; set the corresponding mode line construct.
+ mode-line-buffer-identification flycheck-error-list-mode-line)
+ ;; Guard `truncate-string-ellipsis' for Emacs 24.
+ ;; TODO: Remove when dropping Emacs 24 compatibility
+ (when (boundp 'truncate-string-ellipsis)
+ ;; See https://github.com/flycheck/flycheck/issues/1101
+ (setq-local truncate-string-ellipsis "…"))
+ (tabulated-list-init-header))
+
+(defvar-local flycheck-error-list-source-buffer nil
+ "The current source buffer of the error list.")
+;; Needs to permanently local to preserve the source buffer across buffer
+;; reversions
+(put 'flycheck-error-list-source-buffer 'permanent-local t)
+
+(defun flycheck-error-list-set-source (buffer)
+ "Set BUFFER as the source buffer of the error list."
+ (flycheck-error-list-with-buffer
+ (setq flycheck-error-list-source-buffer buffer)
+ (flycheck-error-list-refresh)))
+
+(defun flycheck-error-list-update-source ()
+ "Make the error list display errors from the current buffer.
+
+The update is skipped if the current buffer is the error list or
+if the error list is already pointing to the current buffer."
+ (unless (memq (current-buffer)
+ (list (get-buffer flycheck-error-list-buffer)
+ (flycheck-error-list-with-buffer
+ flycheck-error-list-source-buffer)))
+ (flycheck-error-list-set-source (current-buffer))))
+
+(defun flycheck-error-list-check-source ()
+ "Trigger a syntax check in the source buffer of the error list."
+ (interactive)
+ (let ((buffer (get-buffer flycheck-error-list-source-buffer)))
+ (when (buffer-live-p buffer)
+ (with-current-buffer buffer
+ (flycheck-buffer)))))
+
+(define-button-type 'flycheck-error-list
+ 'action #'flycheck-error-list-goto-error
+ 'help-echo "mouse-1, RET: goto error"
+ 'face nil)
+
+(define-button-type 'flycheck-error-list-explain-error
+ 'action #'flycheck-error-list-explain-error
+ 'help-echo "mouse-1, RET: explain error")
+
+(defsubst flycheck-error-list-make-cell (text &optional face help-echo type)
+ "Make an error list cell with TEXT and FACE.
+
+If FACE is nil don't set a FACE on TEXT. If TEXT already has
+face properties, do not specify a FACE. Note though, that if
+TEXT gets truncated it will not inherit any previous face
+properties. If you expect TEXT to be truncated in the error
+list, do specify a FACE explicitly!
+
+If HELP-ECHO is non-nil, set a help-echo property on TEXT, with
+value HELP-ECHO. This is convenient if you expect TEXT to be
+truncated.
+
+The cell will have the type TYPE unless TYPE is nil, and the
+default type `flycheck-error-list' will be used instead."
+ (append (list text 'type (if type type
+ 'flycheck-error-list))
+ (and face (list 'face face))
+ (and help-echo (list 'help-echo help-echo))))
+
+(defsubst flycheck-error-list-make-number-cell (number face)
+ "Make a table cell for a NUMBER with FACE.
+
+Convert NUMBER to string, fontify it with FACE and return the
+string with attached text properties."
+ (flycheck-error-list-make-cell
+ (if (numberp number) (number-to-string number) "")
+ face))
+
+(defun flycheck-error-list-make-entry (error)
+ "Make a table cell for the given ERROR.
+
+Return a list with the contents of the table cell."
+ (let* ((level (flycheck-error-level error))
+ (level-face (flycheck-error-level-error-list-face level))
+ (filename (flycheck-error-filename error))
+ (line (flycheck-error-line error))
+ (column (flycheck-error-column error))
+ (message (or (flycheck-error-message error)
+ (format "Unknown %S" level)))
+ (flushed-msg (flycheck-flush-multiline-message message))
+ (id (flycheck-error-id error))
+ (id-str (if id (format "%s" id) ""))
+ (checker (flycheck-error-checker error))
+ (msg-and-checker
+ (flycheck-error-list-make-last-column flushed-msg checker))
+ (explainer (flycheck-checker-get checker 'error-explainer)))
+ (list error
+ (vector (flycheck-error-list-make-cell
+ (if filename
+ (file-name-nondirectory filename)
+ "")
+ 'flycheck-error-list-filename)
+ (flycheck-error-list-make-number-cell
+ line 'flycheck-error-list-line-number)
+ (flycheck-error-list-make-number-cell
+ column 'flycheck-error-list-column-number)
+ (flycheck-error-list-make-cell
+ (symbol-name (flycheck-error-level error)) level-face)
+ ;; Error ID use a different face when an error-explainer is
+ ;; present
+ (flycheck-error-list-make-cell
+ id-str (if explainer 'flycheck-error-list-id-with-explainer
+ 'flycheck-error-list-id)
+ id-str 'flycheck-error-list-explain-error)
+ (flycheck-error-list-make-cell
+ msg-and-checker nil msg-and-checker)))))
+
+(defun flycheck-flush-multiline-message (msg)
+ "Prepare error message MSG for display in the error list.
+
+Prepend all lines of MSG except the first with enough space to
+ensure that they line up properly once the message is displayed."
+ (let* ((spc-spec `(space . (:width ,flycheck--error-list-msg-offset)))
+ (spc (propertize " " 'display spc-spec))
+ (rep (concat "\\1" spc "\\2")))
+ (replace-regexp-in-string "\\([\r\n]+\\)\\(.\\)" rep msg)))
+
+(defun flycheck-error-list-current-errors ()
+ "Read the list of errors in `flycheck-error-list-source-buffer'."
+ (when (buffer-live-p flycheck-error-list-source-buffer)
+ (buffer-local-value 'flycheck-current-errors
+ flycheck-error-list-source-buffer)))
+
+(defun flycheck-error-list-entries ()
+ "Create the entries for the error list."
+ (-when-let* ((errors (flycheck-error-list-current-errors))
+ (filtered (flycheck-error-list-apply-filter errors)))
+ (seq-map #'flycheck-error-list-make-entry filtered)))
+
+(defun flycheck-error-list-entry-< (entry1 entry2)
+ "Determine whether ENTRY1 is before ENTRY2 by location.
+
+See `flycheck-error-<'."
+ (flycheck-error-< (car entry1) (car entry2)))
+
+(defun flycheck-error-list-entry-level-< (entry1 entry2)
+ "Determine whether ENTRY1 is before ENTRY2 by level.
+
+See `flycheck-error-level-<'."
+ (not (flycheck-error-level-< (car entry1) (car entry2))))
+
+(defvar flycheck-error-list-mode-line-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map [mode-line mouse-1]
+ #'flycheck-error-list-mouse-switch-to-source)
+ map)
+ "Keymap for error list mode line.")
+
+(defun flycheck-error-list-propertized-source-name ()
+ "Get the name of the current source buffer for the mode line.
+
+Propertize the name of the current source buffer for use in the
+mode line indication of `flycheck-error-list-mode'."
+ (let ((name (replace-regexp-in-string
+ (rx "%") "%%"
+ (buffer-name flycheck-error-list-source-buffer)
+ 'fixed-case 'literal)))
+ (propertize name 'face 'mode-line-buffer-id
+ 'mouse-face 'mode-line-highlight
+ 'help-echo "mouse-1: switch to source"
+ 'local-map flycheck-error-list-mode-line-map)))
+
+(defun flycheck-error-list-mouse-switch-to-source (event)
+ "Switch to the error list source buffer of the EVENT window."
+ (interactive "e")
+ (save-selected-window
+ (when (eventp event)
+ (select-window (posn-window (event-start event))))
+ (when (buffer-live-p flycheck-error-list-source-buffer)
+ (switch-to-buffer flycheck-error-list-source-buffer))))
+
+(defun flycheck-get-error-list-window-list (&optional all-frames)
+ "Get all windows displaying the error list.
+
+ALL-FRAMES specifies the frames to consider, as in
+`get-buffer-window-list'."
+ (-when-let (buf (get-buffer flycheck-error-list-buffer))
+ (get-buffer-window-list buf nil all-frames)))
+
+(defun flycheck-get-error-list-window (&optional all-frames)
+ "Get a window displaying the error list, or nil if none.
+
+ALL-FRAMES specifies the frames to consider, as in
+`get-buffer-window'."
+ (-when-let (buf (get-buffer flycheck-error-list-buffer))
+ (get-buffer-window buf all-frames)))
+
+(defun flycheck-error-list-recenter-at (pos)
+ "Recenter the error list at POS."
+ (dolist (window (flycheck-get-error-list-window-list t))
+ (with-selected-window window
+ (goto-char pos)
+ (let ((recenter-redisplay nil))
+ (recenter)))))
+
+(defun flycheck-error-list-refresh ()
+ "Refresh the current error list.
+
+Add all errors currently reported for the current
+`flycheck-error-list-source-buffer', and recenter the error
+list."
+ ;; We only refresh the error list, when it is visible in a window, and we
+ ;; select this window while reverting, because Tabulated List mode attempts to
+ ;; recenter the error at the old location, so it must have the proper window
+ ;; selected.
+ (-when-let (window (flycheck-get-error-list-window t))
+ (with-selected-window window
+ (revert-buffer))
+ (run-hooks 'flycheck-error-list-after-refresh-hook)
+ (let ((preserve-pos (eq (current-buffer)
+ (get-buffer flycheck-error-list-buffer))))
+ ;; If the error list is the current buffer, don't recenter when
+ ;; highlighting
+ (flycheck-error-list-highlight-errors preserve-pos))))
+
+(defun flycheck-error-list-mode-line-filter-indicator ()
+ "Create a string representing the current error list filter."
+ (if flycheck-error-list-minimum-level
+ (format " [>= %s]" flycheck-error-list-minimum-level)
+ ""))
+
+(defun flycheck-error-list-set-filter (level)
+ "Restrict the error list to errors at level LEVEL or higher.
+
+LEVEL is either an error level symbol, or nil, to remove the filter."
+ (interactive
+ (list (flycheck-read-error-level
+ "Minimum error level (errors at lower levels will be hidden): ")))
+ (when (and level (not (flycheck-error-level-p level)))
+ (user-error "Invalid level: %s" level))
+ (flycheck-error-list-with-buffer
+ (setq-local flycheck-error-list-minimum-level level)
+ (force-mode-line-update)
+ (flycheck-error-list-refresh)
+ (flycheck-error-list-recenter-at (point-min))))
+
+(defun flycheck-error-list-reset-filter (&optional refresh)
+ "Remove local error filters and reset to the default filter.
+
+Interactively, or with non-nil REFRESH, refresh the error list."
+ (interactive '(t))
+ (flycheck-error-list-with-buffer
+ (kill-local-variable 'flycheck-error-list-minimum-level)
+ (when refresh
+ (flycheck-error-list-refresh)
+ (flycheck-error-list-recenter-at (point-min))
+ (force-mode-line-update))))
+
+(defun flycheck-error-list-apply-filter (errors)
+ "Filter ERRORS according to `flycheck-error-list-minimum-level'."
+ (-if-let* ((min-level flycheck-error-list-minimum-level)
+ (min-severity (flycheck-error-level-severity min-level)))
+ (seq-filter (lambda (err) (>= (flycheck-error-level-severity
+ (flycheck-error-level err))
+ min-severity))
+ errors)
+ errors))
+
+(defun flycheck-error-list-goto-error (&optional pos)
+ "Go to the location of the error at POS in the error list.
+
+POS defaults to `point'."
+ (interactive)
+ (-when-let* ((error (tabulated-list-get-id pos)))
+ (flycheck-jump-to-error error)))
+
+(defun flycheck-jump-to-error (error)
+ "Go to the location of ERROR."
+ (let* ((error-copy (copy-flycheck-error error))
+ (filename (flycheck-error-filename error))
+ (other-file-error (flycheck-relevant-error-other-file-p error))
+ (buffer (if filename
+ (find-file-noselect filename)
+ (flycheck-error-buffer error))))
+ (when (buffer-live-p buffer)
+ (setf (flycheck-error-buffer error-copy) buffer)
+ (flycheck-jump-in-buffer buffer error-copy)
+ ;; When jumping to an error in another file, it may not have
+ ;; this error available for highlighting yet, so we trigger a check
+ ;; if necessary.
+ (when other-file-error
+ (with-current-buffer buffer
+ ;; `seq-contains-p' is only in seq >= 2.21
+ (unless (with-no-warnings
+ (seq-contains flycheck-current-errors error-copy 'equal))
+ (when flycheck-mode
+ (flycheck-buffer))))))))
+
+(defun flycheck-jump-in-buffer (buffer error)
+ "In BUFFER, jump to ERROR."
+ ;; FIXME: we assume BUFFER and the buffer of ERROR are the same. We don't
+ ;; need the first argument then.
+ (if (eq (window-buffer) (get-buffer flycheck-error-list-buffer))
+ ;; When called from within the error list, keep the error list,
+ ;; otherwise replace the current buffer.
+ (pop-to-buffer buffer 'other-window)
+ (switch-to-buffer buffer))
+ (let ((pos (flycheck-error-pos error)))
+ (unless (eq (goto-char pos) (point))
+ ;; If widening gets in the way of moving to the right place, remove it
+ ;; and try again
+ (widen)
+ (goto-char pos)))
+ ;; Re-highlight the errors. We have post-command-hook for that, but calls to
+ ;; `flycheck-jump-in-buffer' that come from other buffers (e.g. from the error
+ ;; list) won't trigger it.
+ (flycheck-error-list-highlight-errors 'preserve-pos))
+
+(defun flycheck-error-list-explain-error (&optional pos)
+ "Explain the error at POS in the error list.
+
+POS defaults to `point'."
+ (interactive)
+ (-when-let* ((error (tabulated-list-get-id pos))
+ (explainer (flycheck-checker-get (flycheck-error-checker error)
+ 'error-explainer)))
+ (flycheck-error-with-buffer error
+ (-when-let (explanation (funcall explainer error))
+ (flycheck-display-error-explanation explanation)))))
+
+(defun flycheck-error-list-next-error-pos (pos &optional n)
+ "Starting from POS get the N'th next error in the error list.
+
+N defaults to 1. If N is negative, search for the previous error
+instead.
+
+Get the beginning position of the N'th next error from POS, or
+nil, if there is no next error."
+ (let ((n (or n 1)))
+ (if (>= n 0)
+ ;; Search forward
+ (while (and pos (/= n 0))
+ (setq n (1- n))
+ (setq pos (next-single-property-change pos 'tabulated-list-id)))
+ ;; Search backwards
+ (while (/= n 0)
+ (setq n (1+ n))
+ ;; We explicitly give the limit here to explicitly have the minimum
+ ;; point returned, to be able to move to the first error (which starts
+ ;; at `point-min')
+ (setq pos (previous-single-property-change pos 'tabulated-list-id
+ nil (point-min)))))
+ pos))
+
+(defun flycheck-error-list-previous-error (n)
+ "Go to the N'th previous error in the error list."
+ (interactive "P")
+ (flycheck-error-list-next-error (- (or n 1))))
+
+(defun flycheck-error-list-next-error (n)
+ "Go to the N'th next error in the error list."
+ (interactive "P")
+ (let ((pos (flycheck-error-list-next-error-pos (point) n)))
+ (when (and pos (/= pos (point)))
+ (goto-char pos)
+ (save-selected-window
+ ;; Keep the error list selected, so that the user can navigate errors by
+ ;; repeatedly pressing n/p, without having to re-select the error list
+ ;; window.
+ (flycheck-error-list-goto-error)))))
+
+(defvar-local flycheck-error-list-highlight-overlays nil
+ "Error highlight overlays in the error list buffer.")
+(put 'flycheck-error-list-highlight-overlays 'permanent-local t)
+
+(defun flycheck-error-list-highlight-errors (&optional preserve-pos)
+ "Highlight errors in the error list.
+
+Highlight all errors in the error list that are at point in the
+source buffer, and on the same line as point. Then recenter the
+error list to the highlighted error, unless PRESERVE-POS is
+non-nil."
+ (when (get-buffer flycheck-error-list-buffer)
+ (with-current-buffer flycheck-error-list-buffer
+ (let ((current-errors
+ (when (buffer-live-p flycheck-error-list-source-buffer)
+ (with-current-buffer flycheck-error-list-source-buffer
+ (flycheck-overlay-errors-in (line-beginning-position)
+ (line-end-position))))))
+ (let ((old-overlays flycheck-error-list-highlight-overlays)
+ (min-point (point-max))
+ (max-point (point-min)))
+ ;; Display the new overlays first, to avoid re-display flickering
+ (setq flycheck-error-list-highlight-overlays nil)
+ (when current-errors
+ (let ((next-error-pos (point-min)))
+ (while next-error-pos
+ (let* ((beg next-error-pos)
+ (end (flycheck-error-list-next-error-pos beg))
+ (err (tabulated-list-get-id beg)))
+ (when (member err current-errors)
+ (setq min-point (min min-point beg)
+ max-point (max max-point beg))
+ (let ((ov (make-overlay beg
+ ;; Extend overlay to the beginning
+ ;; of the next line, to highlight
+ ;; the whole line
+ (or end (point-max)))))
+ (push ov flycheck-error-list-highlight-overlays)
+ (setf (overlay-get ov 'flycheck-error-highlight-overlay)
+ t)
+ (setf (overlay-get ov 'face)
+ 'flycheck-error-list-highlight)))
+ (setq next-error-pos end)))))
+ ;; Delete the old overlays
+ (seq-do #'delete-overlay old-overlays)
+ (when (and (not preserve-pos) current-errors)
+ ;; Move point to the middle error
+ (goto-char (+ min-point (/ (- max-point min-point) 2)))
+ (beginning-of-line)
+ ;; And recenter the error list at this position
+ (flycheck-error-list-recenter-at (point))))))))
+
+(defun flycheck-list-errors ()
+ "Show the error list for the current buffer."
+ (interactive)
+ (unless flycheck-mode
+ (user-error "Flycheck mode not enabled"))
+ ;; Create and initialize the error list
+ (unless (get-buffer flycheck-error-list-buffer)
+ (with-current-buffer (get-buffer-create flycheck-error-list-buffer)
+ (flycheck-error-list-mode)))
+ ;; Reset the error filter
+ (flycheck-error-list-reset-filter)
+ (let ((source (current-buffer)))
+ ;; Show the error list in a side window. Under some configurations of
+ ;; `display-buffer', this may select `flycheck-error-list-buffer' (see URL
+ ;; `https://github.com/flycheck/flycheck/issues/1776').
+ (display-buffer flycheck-error-list-buffer)
+ ;; Adjust the source, causing a refresh
+ (flycheck-error-list-set-source source)))
+
+(defalias 'list-flycheck-errors 'flycheck-list-errors)
+
+
+;;; Displaying errors in the current buffer
+(defun flycheck-display-errors (errors)
+ "Display ERRORS using `flycheck-display-errors-function'."
+ (when flycheck-display-errors-function
+ (funcall flycheck-display-errors-function errors)))
+
+(defvar-local flycheck-display-error-at-point-timer nil
+ "Timer to automatically show errors.")
+
+(defun flycheck-cancel-error-display-error-at-point-timer ()
+ "Cancel the error display timer for the current buffer."
+ (when flycheck-display-error-at-point-timer
+ (cancel-timer flycheck-display-error-at-point-timer)
+ (setq flycheck-display-error-at-point-timer nil)))
+
+(defun flycheck--error-display-tick ()
+ "Return point and tick counter of current buffer."
+ (cons (point) (buffer-modified-tick)))
+
+(defvar-local flycheck--last-error-display-tick nil
+ "Value of `flycheck--error-display-tick' when errors were last displayed.")
+
+(defun flycheck-display-error-at-point ()
+ "Display all the error messages at point."
+ (interactive)
+ ;; This function runs from a timer, so we must take care to not ignore any
+ ;; errors
+ (with-demoted-errors "Flycheck error display error: %s"
+ (flycheck-cancel-error-display-error-at-point-timer)
+ (setq flycheck--last-error-display-tick (flycheck--error-display-tick))
+ (when flycheck-mode
+ (-when-let (errors (flycheck-overlay-errors-at (point)))
+ (flycheck-display-errors errors)))))
+
+(defun flycheck-display-error-at-point-soon ()
+ "Display error messages at point, with a delay."
+ (setq flycheck--last-error-display-tick nil)
+ (flycheck-maybe-display-error-at-point-soon))
+
+(defun flycheck-maybe-display-error-at-point-soon ()
+ "Display error message at point with a delay, unless already displayed."
+ (flycheck-cancel-error-display-error-at-point-timer)
+ (when (and (not (equal flycheck--last-error-display-tick
+ (setq flycheck--last-error-display-tick
+ (flycheck--error-display-tick))))
+ (flycheck-overlays-at (point)))
+ (setq flycheck-display-error-at-point-timer
+ (run-at-time flycheck-display-errors-delay nil
+ 'flycheck-display-error-at-point))))
+
+
+;;; Functions to display errors
+(defconst flycheck-error-message-buffer "*Flycheck error messages*"
+ "The name of the buffer to show long error messages in.")
+
+(defun flycheck-error-message-buffer ()
+ "Get the buffer object to show long error messages in.
+
+Get the buffer named by variable `flycheck-error-message-buffer',
+or nil if the buffer does not exist."
+ (get-buffer flycheck-error-message-buffer))
+
+(defun flycheck-may-use-echo-area-p ()
+ "Determine whether the echo area may be used.
+
+The echo area may be used if the cursor is not in the echo area,
+and if the echo area is not occupied by minibuffer input."
+ (not (or cursor-in-echo-area (active-minibuffer-window))))
+
+(define-derived-mode flycheck-error-message-mode text-mode
+ "Flycheck error messages"
+ "Major mode for extended error messages.")
+
+(defun flycheck-display-error-messages (errors)
+ "Display the messages of ERRORS.
+
+Concatenate all non-nil messages of ERRORS as with
+`flycheck-help-echo-all-error-messages', and display them with
+`display-message-or-buffer', which shows the messages either in
+the echo area or in a separate buffer, depending on the number of
+lines. See Info node `(elisp)Displaying Messages' for more
+information.
+
+In the latter case, show messages in the buffer denoted by
+variable `flycheck-error-message-buffer'."
+ (when (and errors (flycheck-may-use-echo-area-p))
+ (let ((message (flycheck-help-echo-all-error-messages errors)))
+ (display-message-or-buffer
+ message flycheck-error-message-buffer 'not-this-window)
+ ;; We cannot rely on `display-message-or-buffer' returning the right
+ ;; window. See URL `https://github.com/flycheck/flycheck/issues/1643'.
+ (-when-let (buf (get-buffer flycheck-error-message-buffer))
+ (with-current-buffer buf
+ (unless (derived-mode-p 'flycheck-error-message-mode)
+ (flycheck-error-message-mode)))))))
+
+(defun flycheck-display-error-messages-unless-error-list (errors)
+ "Show messages of ERRORS unless the error list is visible.
+
+Like `flycheck-display-error-messages', but only if the error
+list (see `flycheck-list-errors') is not visible in any window in
+the current frame."
+ (unless (flycheck-get-error-list-window 'current-frame)
+ (flycheck-display-error-messages errors)))
+
+(defun flycheck-hide-error-buffer ()
+ "Hide the Flycheck error buffer if necessary.
+
+Hide the error buffer if there is no error under point."
+ (-when-let* ((buffer (flycheck-error-message-buffer))
+ (window (get-buffer-window buffer)))
+ (unless (flycheck-overlays-at (point))
+ ;; save-selected-window prevents `quit-window' from changing the current
+ ;; buffer (see https://github.com/flycheck/flycheck/issues/648).
+ (save-selected-window
+ (quit-window nil window)))))
+
+
+;;; Working with errors
+(defun flycheck-copy-errors-as-kill (pos &optional formatter)
+ "Copy each error at POS into kill ring, using FORMATTER.
+
+FORMATTER is a function to turn an error into a string,
+defaulting to `flycheck-error-message'.
+
+Interactively, use `flycheck-error-format-message-and-id' as
+FORMATTER with universal prefix arg, and `flycheck-error-id' with
+normal prefix arg, i.e. copy the message and the ID with
+universal prefix arg, and only the id with normal prefix arg."
+ (interactive (list (point)
+ (pcase current-prefix-arg
+ ((pred not) #'flycheck-error-message)
+ ((pred consp) #'flycheck-error-format-message-and-id)
+ (_ #'flycheck-error-id))))
+ (let ((messages (delq nil (seq-map (or formatter #'flycheck-error-message)
+ (flycheck-overlay-errors-at pos)))))
+ (when messages
+ (seq-do #'kill-new (reverse messages))
+ (message (string-join messages "\n")))))
+
+(defun flycheck-explain-error-at-point ()
+ "Display an explanation for the first explainable error at point.
+
+The first explainable error at point is the first error at point
+with a non-nil `:error-explainer' function defined in its
+checker. The `:error-explainer' function is then called with
+this error to produce the explanation to display."
+ (interactive)
+ (-when-let* ((first-error
+ ;; Get the first error at point that has an `error-explainer'.
+ (seq-find (lambda (error)
+ (flycheck-checker-get
+ (flycheck-error-checker error) 'error-explainer))
+ (flycheck-overlay-errors-at (point))))
+ (explainer
+ (flycheck-checker-get (flycheck-error-checker first-error)
+ 'error-explainer))
+ (explanation (funcall explainer first-error)))
+ (flycheck-display-error-explanation explanation)))
+
+(defconst flycheck-explain-error-buffer "*Flycheck error explanation*"
+ "The name of the buffer to show error explanations.")
+
+(define-derived-mode flycheck-explain-error-mode help-mode
+ "Error explanation"
+ "Major mode for displaying error explanations."
+ (setq buffer-read-only t))
+
+(defun flycheck-display-error-explanation (explanation)
+ "Display the EXPLANATION for an error."
+ (pcase explanation
+ (`nil)
+ (`(url . ,url) (browse-url url))
+ (_ (let ((inhibit-read-only t)
+ (standard-output (temp-buffer-window-setup
+ flycheck-explain-error-buffer)))
+ (with-current-buffer standard-output
+ (flycheck-explain-error-mode))
+ (cond
+ ((functionp explanation) (funcall explanation))
+ ((stringp explanation) (princ explanation))
+ (t (error "Unsupported error explanation: %S" explanation)))
+ (display-message-or-buffer standard-output nil 'not-this-window)))))
+
+
+;;; Syntax checkers using external commands
+(defun flycheck-command-argument-p (arg)
+ "Check whether ARG is a valid command argument."
+ (pcase arg
+ ((pred stringp) t)
+ ((or `source `source-inplace `source-original) t)
+ (`(,(or `source `source-inplace) ,suffix)
+ (stringp suffix))
+ ((or `temporary-directory `temporary-file-name) t)
+ (`null-device t)
+ (`(config-file ,option-name ,config-file-var)
+ (and (stringp option-name)
+ (symbolp config-file-var)))
+ (`(config-file ,option-name ,config-file-var ,prepender)
+ (and (stringp option-name)
+ (symbolp config-file-var)
+ (symbolp prepender)))
+ (`(,(or `option `option-list) ,option-name ,option-var)
+ (and (stringp option-name)
+ (symbolp option-var)))
+ (`(,(or `option `option-list) ,option-name ,option-var ,prepender)
+ (and (stringp option-name)
+ (symbolp option-var)
+ (symbolp prepender)))
+ (`(,(or `option `option-list) ,option-name ,option-var ,prepender ,filter)
+ (and (stringp option-name)
+ (symbolp option-var)
+ (symbolp prepender)
+ (symbolp filter)))
+ (`(option-flag ,option-name ,option-var)
+ (and (stringp option-name)
+ (symbolp option-var)))
+ (`(eval ,_) t)
+ (_ nil)))
+
+(defun flycheck-compute-working-directory (checker)
+ "Get the default working directory for CHECKER.
+
+Compute the value of `default-directory' for the invocation of
+the syntax checker command, by calling the function in the
+`working-directory' property of CHECKER, with CHECKER as sole
+argument, and returning its value. Signal an error if the
+function returns a non-existing working directory.
+
+If the property is undefined or if the function returns nil
+return the `default-directory' of the current buffer."
+ (let* ((def-directory-fn (flycheck-checker-get checker 'working-directory))
+ (directory (or (and def-directory-fn
+ (funcall def-directory-fn checker))
+ ;; Default to the `default-directory' of the current
+ ;; buffer
+ default-directory)))
+ (unless (file-exists-p directory)
+ (error ":working-directory %s of syntax checker %S does not exist"
+ directory checker))
+ directory))
+
+;;;###autoload
+(defun flycheck-define-command-checker (symbol docstring &rest properties)
+ "Define SYMBOL as syntax checker to run a command.
+
+Define SYMBOL as generic syntax checker via
+`flycheck-define-generic-checker', which uses an external command
+to check the buffer. SYMBOL and DOCSTRING are the same as for
+`flycheck-define-generic-checker'.
+
+In addition to the properties understood by
+`flycheck-define-generic-checker', the following PROPERTIES
+constitute a command syntax checker. Unless otherwise noted, all
+properties are mandatory. Note that the default `:error-filter'
+of command checkers is `flycheck-sanitize-errors'.
+
+`:command COMMAND'
+ The command to run for syntax checking.
+
+ COMMAND is a list of the form `(EXECUTABLE [ARG ...])'.
+
+ EXECUTABLE is a string with the executable of this syntax
+ checker. It can be overridden with the variable
+ `flycheck-SYMBOL-executable'. Note that this variable is
+ NOT implicitly defined by this function. Use
+ `flycheck-def-executable-var' to define this variable.
+
+ Each ARG is an argument to the executable, either as string,
+ or as special symbol or form for
+ `flycheck-substitute-argument', which see.
+
+`:error-patterns PATTERNS'
+ A list of patterns to parse the output of the `:command'.
+
+ Each ITEM in PATTERNS is a list `(LEVEL SEXP ...)', where
+ LEVEL is a Flycheck error level (see
+ `flycheck-define-error-level'), followed by one or more RX
+ `SEXP's which parse an error of that level and extract line,
+ column, file name and the message.
+
+ See `rx' for general information about RX, and
+ `flycheck-rx-to-string' for some special RX forms provided
+ by Flycheck.
+
+ All patterns are applied in the order of declaration to the
+ whole output of the syntax checker. Output already matched
+ by a pattern will not be matched by subsequent patterns. In
+ other words, the first pattern wins.
+
+ This property is optional. If omitted, however, an
+ `:error-parser' is mandatory.
+
+`:error-parser FUNCTION'
+ A function to parse errors with.
+
+ The function shall accept three arguments OUTPUT CHECKER
+ BUFFER. OUTPUT is the syntax checker output as string,
+ CHECKER the syntax checker that was used, and BUFFER a
+ buffer object representing the checked buffer. The function
+ must return a list of `flycheck-error' objects parsed from
+ OUTPUT.
+
+ This property is optional. If omitted, it defaults to
+ `flycheck-parse-with-patterns'. In this case,
+ `:error-patterns' is mandatory.
+
+`:standard-input t'
+ Whether to send the buffer contents on standard input.
+
+ If this property is given and has a non-nil value, send the
+ contents of the buffer on standard input.
+
+ Defaults to nil.
+
+Note that you may not give `:start', `:interrupt', and
+`:print-doc' for a command checker. You can give a custom
+`:verify' function, though, whose results will be appended to the
+default `:verify' function of command checkers."
+ (declare (indent 1)
+ (doc-string 2))
+ (dolist (prop '(:start :interrupt :print-doc))
+ (when (plist-get properties prop)
+ (error "%s not allowed in definition of command syntax checker %s"
+ prop symbol)))
+
+ (unless (plist-get properties :error-filter)
+ ;; Default to `flycheck-sanitize-errors' as error filter
+ (setq properties (plist-put properties :error-filter
+ #'flycheck-sanitize-errors)))
+ (let ((verify-fn (plist-get properties :verify)))
+ (setq properties
+ (plist-put properties :verify
+ (lambda (checker)
+ (append (flycheck-verify-command-checker checker)
+ (and verify-fn
+ (funcall verify-fn checker)))))))
+
+ (let ((command (plist-get properties :command))
+ (patterns (plist-get properties :error-patterns))
+ (parser (or (plist-get properties :error-parser)
+ #'flycheck-parse-with-patterns))
+ (enabled (plist-get properties :enabled))
+ (standard-input (plist-get properties :standard-input)))
+ (unless command
+ (error "Missing :command in syntax checker %s" symbol))
+ (unless (stringp (car command))
+ (error "Command executable for syntax checker %s must be a string: %S"
+ symbol (car command)))
+ (dolist (arg (cdr command))
+ (unless (flycheck-command-argument-p arg)
+ (error "Invalid command argument %S in syntax checker %s" arg symbol)))
+ (when (and (eq parser 'flycheck-parse-with-patterns)
+ (not patterns))
+ (error "Missing :error-patterns in syntax checker %s" symbol))
+
+ (setq properties
+ ;; Automatically disable command checkers if the executable does not
+ ;; exist.
+ (plist-put properties :enabled
+ (lambda ()
+ (and (flycheck-find-checker-executable symbol)
+ (flycheck-temp-files-writable-p symbol)
+ (or (not enabled) (funcall enabled))))))
+
+ (apply #'flycheck-define-generic-checker symbol docstring
+ :start #'flycheck-start-command-checker
+ :interrupt #'flycheck-interrupt-command-checker
+ :print-doc #'flycheck-command-checker-print-doc
+ properties)
+
+ ;; Pre-compile all errors patterns into strings, so that we don't need to do
+ ;; that on each error parse
+ (let ((patterns (seq-map (lambda (p)
+ (cons (flycheck-rx-to-string `(and ,@(cdr p))
+ 'no-group)
+ (car p)))
+ patterns)))
+ (pcase-dolist (`(,prop . ,value)
+ `((command . ,command)
+ (error-parser . ,parser)
+ (error-patterns . ,patterns)
+ (standard-input . ,standard-input)))
+ (setf (flycheck-checker-get symbol prop) value)))))
+
+(eval-and-compile
+ ;; Make this function available during byte-compilation, since we need it
+ ;; at macro expansion of `flycheck-def-executable-var'.
+ (defun flycheck-checker-executable-variable (checker)
+ "Get the executable variable of CHECKER.
+
+The executable variable is named `flycheck-CHECKER-executable'."
+ (intern (format "flycheck-%s-executable" checker))))
+
+(defun flycheck-checker-default-executable (checker)
+ "Get the default executable of CHECKER."
+ (car (flycheck-checker-get checker 'command)))
+
+(defun flycheck-checker-executable (checker)
+ "Get the command executable of CHECKER.
+
+The executable is either the value of the variable
+`flycheck-CHECKER-executable', or the default executable given in
+the syntax checker definition, if the variable is nil."
+ (let ((var (flycheck-checker-executable-variable checker)))
+ (or (and (boundp var) (symbol-value var))
+ (flycheck-checker-default-executable checker))))
+
+(defun flycheck-find-checker-executable (checker)
+ "Get the full path of the executable of CHECKER.
+
+Return the full absolute path to the executable of CHECKER, or
+nil if the executable does not exist."
+ (funcall flycheck-executable-find (flycheck-checker-executable checker)))
+
+(defun flycheck-call-checker-process
+ (checker infile destination error &rest args)
+ "Call CHECKER's executable with ARGS.
+
+Return nil (or raise an error if ERROR is non-nil) when CHECKER's
+executable cannot be found, and return a numeric exit status or a
+signal description string otherwise. CHECKER's input is taken
+from INFILE, and its output is sent to DESTINATION, as in
+`call-process'."
+ (-if-let (executable (flycheck-find-checker-executable checker))
+ (condition-case err
+ (apply #'call-process executable infile destination nil args)
+ (error (when error (signal (car err) (cdr err)))))
+ (when error
+ (user-error "Cannot find `%s' using `flycheck-executable-find'"
+ (flycheck-checker-executable checker)))))
+
+(defun flycheck-call-checker-process-for-output
+ (checker infile error &rest args)
+ "Call CHECKER's executable with ARGS and return its output.
+
+Call `flycheck-call-checker-process' with INFILE, ERROR, and
+ARGS. If it returns 0, return the process' output. Otherwise,
+return nil or throw an error.
+
+This function is similar to `flycheck-call-checker-process'
+called in a `with-output-to-string' block, but it takes care of
+the error checking automatically."
+ (let ((temp (generate-new-buffer " *temp*")))
+ (unwind-protect
+ ;; We need to call the checker process in the right buffer, so that it
+ ;; uses the right exec-path, checker executable, etc. See URL
+ ;; `https://github.com/flycheck/flycheck/issues/1770'.
+ (let ((exit-code (apply #'flycheck-call-checker-process
+ checker infile temp error args))
+ (output (with-current-buffer temp (buffer-string))))
+ (if (eql 0 exit-code) output
+ (when error
+ (error "Process %s failed with %S (%s)"
+ checker exit-code output))))
+ (kill-buffer temp))))
+
+(defun flycheck-checker-arguments (checker)
+ "Get the command arguments of CHECKER."
+ (cdr (flycheck-checker-get checker 'command)))
+
+(defun flycheck-substitute-argument (arg checker)
+ "Substitute ARG for CHECKER.
+
+Return a list of real arguments for the executable of CHECKER,
+substituted for the symbolic argument ARG. Single arguments,
+e.g. if ARG is a literal strings, are wrapped in a list.
+
+ARG may be one of the following forms:
+
+STRING
+ Return ARG unchanged.
+
+`source', `source-inplace'
+ Create a temporary file to check and return its path. With
+ `source-inplace' create the temporary file in the same
+ directory as the original file. The value of
+ `flycheck-temp-prefix' is used as prefix of the file name.
+
+ With `source', try to retain the non-directory component of
+ the buffer's file name in the temporary file.
+
+ `source' is the preferred way to pass the input file to a
+ syntax checker. `source-inplace' should only be used if the
+ syntax checker needs other files from the source directory,
+ such as include files in C.
+
+`(source SUFFIX)', `(source-inplace SUFFIX)'
+ Like `source' and `source-inplace', but ensure generated
+ file names end with the given suffix. Use this when the
+ checker requires that file names on its command line have a
+ certain suffix (file extension).
+
+`source-original'
+ Return the path of the actual file to check, or an empty
+ string if the buffer has no file name.
+
+ Note that the contents of the file may not be up to date
+ with the contents of the buffer to check. Do not use this
+ as primary input to a checker, unless absolutely necessary.
+
+ When using this symbol as primary input to the syntax
+ checker, add `flycheck-buffer-saved-p' to the `:predicate'.
+
+`temporary-directory'
+ Create a unique temporary directory and return its path.
+
+`temporary-file-name'
+ Return a unique temporary filename. The file is *not*
+ created.
+
+ To ignore the output of syntax checkers, try symbol
+ `null-device' first.
+
+symbol `null-device'
+ Return the value of variable `null-device', i.e the system
+ null device.
+
+ Use this option to ignore the output of a syntax checker.
+ If the syntax checker cannot handle the null device, or
+ won't write to an existing file, try `temporary-file-name'
+ instead.
+
+`(config-file OPTION VARIABLE [PREPEND-FN])'
+ Search the configuration file bound to VARIABLE with
+ `flycheck-locate-config-file' and return a list of arguments
+ that pass this configuration file to the syntax checker, or
+ nil if the configuration file was not found.
+
+ PREPEND-FN is called with the OPTION and the located
+ configuration file, and should return OPTION prepended
+ before the file, either a string or as list. If omitted,
+ PREPEND-FN defaults to `list'.
+
+`(option OPTION VARIABLE [PREPEND-FN [FILTER]])'
+ Retrieve the value of VARIABLE and return a list of
+ arguments that pass this value as value for OPTION to the
+ syntax checker.
+
+ PREPEND-FN is called with the OPTION and the value of
+ VARIABLE, and should return OPTION prepended before the
+ file, either a string or as list. If omitted, PREPEND-FN
+ defaults to `list'.
+
+ FILTER is an optional function to be applied to the value of
+ VARIABLE before prepending. This function must return nil
+ or a string. In the former case, return nil. In the latter
+ case, return a list of arguments as described above.
+
+`(option-list OPTION VARIABLE [PREPEND-FN [FILTER]])'
+ Retrieve the value of VARIABLE, which must be a list,
+ and prepend OPTION before each item in this list, using
+ PREPEND-FN.
+
+ PREPEND-FN is called with the OPTION and each item of the
+ list as second argument, and should return OPTION prepended
+ before the item, either as string or as list. If omitted,
+ PREPEND-FN defaults to `list'.
+
+ FILTER is an optional function to be applied to each item in
+ the list before prepending OPTION. It shall return the
+ option value for each item as string, or nil, if the item is
+ to be ignored.
+
+`(option-flag OPTION VARIABLE)'
+ Retrieve the value of VARIABLE and return OPTION, if the
+ value is non-nil. Otherwise return nil.
+
+`(eval FORM)'
+ Return the result of evaluating FORM in the buffer to be
+ checked. FORM must either return a string or a list of
+ strings, or nil to indicate that nothing should be
+ substituted for CELL. For all other return types, signal an
+ error
+
+ _No_ further substitutions are performed, neither in FORM
+ before it is evaluated, nor in the result of evaluating
+ FORM.
+
+In all other cases, signal an error.
+
+Note that substitution is *not* recursive. No symbols or cells
+are substituted within the body of cells!"
+ (pcase arg
+ ((pred stringp) (list arg))
+ (`source
+ (list (flycheck-save-buffer-to-temp #'flycheck-temp-file-system)))
+ (`source-inplace
+ (list (flycheck-save-buffer-to-temp #'flycheck-temp-file-inplace)))
+ (`(source ,suffix)
+ (list (flycheck-save-buffer-to-temp
+ (lambda (filename) (flycheck-temp-file-system filename suffix)))))
+ (`(source-inplace ,suffix)
+ (list (flycheck-save-buffer-to-temp
+ (lambda (filename) (flycheck-temp-file-inplace filename suffix)))))
+ (`source-original (list (or (buffer-file-name) "")))
+ (`temporary-directory (list (flycheck-temp-dir-system)))
+ (`temporary-file-name
+ (let ((directory (flycheck-temp-dir-system)))
+ (list (make-temp-name (expand-file-name "flycheck" directory)))))
+ (`null-device (list null-device))
+ (`(config-file ,option-name ,file-name-var)
+ (-when-let* ((value (symbol-value file-name-var))
+ (file-name (flycheck-locate-config-file value checker)))
+ (flycheck-prepend-with-option option-name (list file-name))))
+ (`(config-file ,option-name ,file-name-var ,prepend-fn)
+ (-when-let* ((value (symbol-value file-name-var))
+ (file-name (flycheck-locate-config-file value checker)))
+ (flycheck-prepend-with-option option-name (list file-name) prepend-fn)))
+ (`(option ,option-name ,variable)
+ (-when-let (value (symbol-value variable))
+ (unless (stringp value)
+ (error "Value %S of %S for option %s is not a string"
+ value variable option-name))
+ (flycheck-prepend-with-option option-name (list value))))
+ (`(option ,option-name ,variable ,prepend-fn)
+ (-when-let (value (symbol-value variable))
+ (unless (stringp value)
+ (error "Value %S of %S for option %s is not a string"
+ value variable option-name))
+ (flycheck-prepend-with-option option-name (list value) prepend-fn)))
+ (`(option ,option-name ,variable ,prepend-fn ,filter)
+ (-when-let (value (funcall filter (symbol-value variable)))
+ (unless (stringp value)
+ (error "Value %S of %S (filter: %S) for option %s is not a string"
+ value variable filter option-name))
+ (flycheck-prepend-with-option option-name (list value) prepend-fn)))
+ (`(option-list ,option-name ,variable)
+ (let ((value (symbol-value variable)))
+ (unless (and (listp value) (seq-every-p #'stringp value))
+ (error "Value %S of %S for option %S is not a list of strings"
+ value variable option-name))
+ (flycheck-prepend-with-option option-name value)))
+ (`(option-list ,option-name ,variable ,prepend-fn)
+ (let ((value (symbol-value variable)))
+ (unless (and (listp value) (seq-every-p #'stringp value))
+ (error "Value %S of %S for option %S is not a list of strings"
+ value variable option-name))
+ (flycheck-prepend-with-option option-name value prepend-fn)))
+ (`(option-list ,option-name ,variable ,prepend-fn ,filter)
+ (let ((value (delq nil (seq-map filter (symbol-value variable)))))
+ (unless (and (listp value) (seq-every-p #'stringp value))
+ (error "Value %S of %S for option %S is not a list of strings"
+ value variable option-name))
+ (flycheck-prepend-with-option option-name value prepend-fn)))
+ (`(option-flag ,option-name ,variable)
+ (when (symbol-value variable)
+ (list option-name)))
+ (`(eval ,form)
+ (let ((result (eval form)))
+ (cond
+ ((and (listp result) (seq-every-p #'stringp result)) result)
+ ((stringp result) (list result))
+ (t (error "Invalid result from evaluation of %S: %S" form result)))))
+ (_ (error "Unsupported argument %S" arg))))
+
+(defun flycheck-checker-substituted-arguments (checker)
+ "Get the substituted arguments of a CHECKER.
+
+Substitute each argument of CHECKER using
+`flycheck-substitute-argument'. This replaces any special
+symbols in the command."
+ (apply #'append
+ (seq-map (lambda (arg) (flycheck-substitute-argument arg checker))
+ (flycheck-checker-arguments checker))))
+
+(defun flycheck--process-send-buffer-contents-chunked (process)
+ "Send contents of current buffer to PROCESS in small batches.
+
+Send the entire buffer to the standard input of PROCESS in chunks
+of 4096 characters. Chunking is done in Emacs Lisp, hence this
+function is probably far less efficient than
+`send-process-region'. Use only when required."
+ (let ((from (point-min)))
+ (while (< from (point-max))
+ (let ((to (min (+ from 4096) (point-max))))
+ (process-send-region process from to)
+ (setq from to)))))
+
+(defvar flycheck-chunked-process-input
+ ;; Chunk process output on Windows to work around
+ ;; https://github.com/flycheck/flycheck/issues/794 and
+ ;; https://debbugs.gnu.org/cgi/bugreport.cgi?bug=22344. The presence of
+ ;; `w32-pipe-buffer-size' denotes an Emacs version (> Emacs 25.1) where pipe
+ ;; writes on Windows are fixed.
+ ;;
+ ;; TODO: Remove option and chunking when dropping Emacs 24 support, see
+ ;; https://github.com/flycheck/flycheck/issues/856
+ (and (eq system-type 'windows-nt) (not (boundp 'w32-pipe-buffer-size)))
+ "If non-nil send process input in small chunks.
+
+If this variable is non-nil `flycheck-process-send-buffer' sends
+buffer contents in small chunks.
+
+Defaults to nil, except on Windows to work around Emacs bug
+#22344.")
+
+(defun flycheck-process-send-buffer (process)
+ "Send all contents of current buffer to PROCESS.
+
+Sends all contents of the current buffer to the standard input of
+PROCESS, and terminates standard input with EOF.
+
+If `flycheck-chunked-process-input' is non-nil, send buffer
+contents in chunks via
+`flycheck--process-send-buffer-contents-chunked', which see.
+Otherwise use `process-send-region' to send all contents at once
+and rely on Emacs' own buffering and chunking."
+ (save-restriction
+ (widen)
+ (if flycheck-chunked-process-input
+ (flycheck--process-send-buffer-contents-chunked process)
+ (process-send-region process (point-min) (point-max))))
+ (process-send-eof process))
+
+(defun flycheck--wrap-command (prog args)
+ "Wrap PROG and ARGS using `flycheck-command-wrapper-function'."
+ ;; We don't call `flycheck-executable-find' on the output of the wrapper
+ ;; function, since it might not expect it (an executable-find function
+ ;; designed to find binaries in a sandbox could get confused if we asked it
+ ;; about the sandboxing program itself).
+ (funcall flycheck-command-wrapper-function (cons prog args)))
+
+(defun flycheck-start-command-checker (checker callback)
+ "Start a command CHECKER with CALLBACK."
+ (let (process)
+ (condition-case err
+ (let* ((program (flycheck-find-checker-executable checker))
+ (args (flycheck-checker-substituted-arguments checker))
+ (command (flycheck--wrap-command program args))
+ (sentinel-events nil)
+ ;; Use pipes to receive output from the syntax checker. They are
+ ;; more efficient and more robust than PTYs, which Emacs uses by
+ ;; default, and since we don't need any job control features, we
+ ;; can easily use pipes.
+ (process-connection-type nil))
+ ;; We pass do not associate the process with any buffer, by
+ ;; passing nil for the BUFFER argument of `start-process'.
+ ;; Instead, we just remember the buffer being checked in a
+ ;; process property (see below). This neatly avoids all
+ ;; side-effects implied by attached a process to a buffer, which
+ ;; may cause conflicts with other packages.
+ ;;
+ ;; See https://github.com/flycheck/flycheck/issues/298 for an
+ ;; example for such a conflict.
+ (setq process (apply 'start-process (format "flycheck-%s" checker)
+ nil command))
+ ;; Process sentinels can be called while sending input to the process.
+ ;; We want to record errors raised by process-send before calling
+ ;; `flycheck-handle-signal', so initially just accumulate events.
+ (setf (process-sentinel process)
+ (lambda (_ event) (push event sentinel-events)))
+ (setf (process-filter process) #'flycheck-receive-checker-output)
+ (set-process-query-on-exit-flag process nil)
+ ;; Remember the syntax checker, the buffer and the callback
+ (process-put process 'flycheck-checker checker)
+ (process-put process 'flycheck-callback callback)
+ (process-put process 'flycheck-buffer (current-buffer))
+ ;; The default directory is bound in the `flycheck-syntax-check-start'
+ ;; function.
+ (process-put process 'flycheck-working-directory default-directory)
+ ;; Track the temporaries created by argument substitution in the
+ ;; process itself, to get rid of the global state ASAP.
+ (process-put process 'flycheck-temporaries flycheck-temporaries)
+ (setq flycheck-temporaries nil)
+ ;; Send the buffer to the process on standard input, if enabled.
+ (when (flycheck-checker-get checker 'standard-input)
+ (condition-case err
+ (flycheck-process-send-buffer process)
+ ;; Some checkers exit before reading all input, causing errors
+ ;; such as a `file-error' for a closed pipe, or a plain “no longer
+ ;; connected to pipe; closed it” error for a disconnection. We
+ ;; report them if needed in `flycheck-finish-checker-process' (see
+ ;; `https://github.com/flycheck/flycheck/issues/1278').
+ (error (process-put process 'flycheck-error err))))
+ ;; Set the actual sentinel and process any events that might have
+ ;; happened while we were sending input.
+ (setf (process-sentinel process) #'flycheck-handle-signal)
+ (dolist (event (nreverse sentinel-events))
+ (flycheck-handle-signal process event))
+ ;; Return the process.
+ process)
+ (error
+ ;; In case of error, clean up our resources, and report the error back to
+ ;; Flycheck.
+ (flycheck-safe-delete-temporaries)
+ (when process
+ ;; No need to explicitly delete the temporary files of the process,
+ ;; because deleting runs the sentinel, which will delete them anyway.
+ (delete-process process))
+ (signal (car err) (cdr err))))))
+
+(defun flycheck-interrupt-command-checker (_checker process)
+ "Interrupt a PROCESS."
+ ;; Deleting the process always triggers the sentinel, which does the cleanup
+ (when process
+ (delete-process process)))
+
+(defun flycheck-command-checker-print-doc (checker)
+ "Print additional documentation for a command CHECKER."
+ (let ((executable (flycheck-checker-default-executable checker))
+ (config-file-var (flycheck-checker-get checker 'config-file-var))
+ (option-vars (seq-sort #'string<
+ (flycheck-checker-get checker 'option-vars))))
+ (princ "\n")
+
+ (let ((doc-start (with-current-buffer standard-output (point-max))))
+ ;; Track the start of our documentation so that we can re-indent it
+ ;; properly
+ (princ " This syntax checker executes \"")
+ (princ executable)
+ (princ "\"")
+ (when config-file-var
+ (princ ", using a configuration file from `")
+ (princ (symbol-name config-file-var))
+ (princ "'"))
+ (princ ". The executable can be overridden with `")
+ (princ (symbol-name (flycheck-checker-executable-variable checker)))
+ (princ "'.")
+
+ (with-current-buffer standard-output
+ (save-excursion
+ (fill-region-as-paragraph doc-start (point-max)))))
+ (princ "\n")
+ (when option-vars
+ (princ
+ "\n This syntax checker can be configured with these options:\n\n")
+ (dolist (var option-vars)
+ (princ (format " * `%s'\n" var))))))
+
+(defun flycheck-verify-command-checker (checker)
+ "Verify a command CHECKER in the current buffer.
+
+Return a list of `flycheck-verification-result' objects for
+CHECKER."
+ (let ((executable (flycheck-find-checker-executable checker))
+ (config-file-var (flycheck-checker-get checker 'config-file-var)))
+ `(
+ ,(flycheck-verification-result-new
+ :label "executable"
+ :message (if executable (format "Found at %s" executable) "Not found")
+ :face (if executable 'success '(bold error)))
+ ,@(when config-file-var
+ (let* ((value (symbol-value config-file-var))
+ (path (and value (flycheck-locate-config-file value checker))))
+ (list (flycheck-verification-result-new
+ :label "configuration file"
+ :message (if path (format "Found at %S" path) "Not found")
+ :face (if path 'success 'warning)))))
+ ,@(when (not (flycheck-temp-files-writable-p checker))
+ (list (flycheck-verification-result-new
+ :label "temp directory"
+ :message (format "%s is not writable"
+ (flycheck-temp-directory checker))
+ :face 'error))))))
+
+
+;;; Process management for command syntax checkers
+(defun flycheck-receive-checker-output (process output)
+ "Receive a syntax checking PROCESS OUTPUT."
+ (push output (process-get process 'flycheck-pending-output)))
+
+(defun flycheck-get-output (process)
+ "Get the complete output of PROCESS."
+ (with-demoted-errors "Error while retrieving process output: %S"
+ (let ((pending-output (process-get process 'flycheck-pending-output)))
+ (apply #'concat (nreverse pending-output)))))
+
+(defun flycheck-handle-signal (process _event)
+ "Handle a signal from the syntax checking PROCESS.
+
+_EVENT is ignored."
+ (when (memq (process-status process) '(signal exit))
+ (let ((files (process-get process 'flycheck-temporaries))
+ (buffer (process-get process 'flycheck-buffer))
+ (callback (process-get process 'flycheck-callback))
+ (cwd (process-get process 'flycheck-working-directory))
+ (err (process-get process 'flycheck-error)))
+ ;; Delete the temporary files
+ (seq-do #'flycheck-safe-delete files)
+ (when (buffer-live-p buffer)
+ (with-current-buffer buffer
+ (condition-case err
+ (pcase (process-status process)
+ (`signal
+ (funcall callback 'interrupted))
+ (`exit
+ (flycheck-finish-checker-process
+ (process-get process 'flycheck-checker)
+ (or err (process-exit-status process))
+ files
+ (flycheck-get-output process) callback cwd)))
+ ((debug error)
+ (funcall callback 'errored (error-message-string err)))))))))
+
+(defun flycheck-finish-checker-process
+ (checker exit-status files output callback cwd)
+ "Finish a checker process from CHECKER with EXIT-STATUS.
+
+EXIT-STATUS can be a number or an arbitrary form (if it is not 0,
+a `suspicious' status is reported to CALLBACK).
+
+FILES is a list of files given as input to the checker. OUTPUT
+is the output of the syntax checker. CALLBACK is the status
+callback to use for reporting.
+
+Parse the OUTPUT and report an appropriate error status.
+
+Resolve all errors in OUTPUT using CWD as working directory."
+ (let ((errors (flycheck-parse-output output checker (current-buffer))))
+ (when (and (not (equal exit-status 0)) (null errors))
+ ;; Warn about a suspicious result from the syntax checker. We do right
+ ;; after parsing the errors, before filtering, because a syntax checker
+ ;; might report errors from other files (e.g. includes) even if there
+ ;; are no errors in the file being checked.
+ (funcall callback 'suspicious
+ (format "Flycheck checker %S returned %S, but \
+its output contained no errors: %s\nTry installing a more \
+recent version of %S, and please open a bug report if the issue \
+persists in the latest release. Thanks!" checker exit-status
+output checker)))
+ (funcall callback 'finished
+ ;; Fix error file names, by substituting them backwards from the
+ ;; temporaries.
+ (seq-map (lambda (e) (flycheck-fix-error-filename e files cwd))
+ errors))))
+
+
+;;; Executables of command checkers.
+(defmacro flycheck-def-executable-var (checker default-executable)
+ "Define the executable variable for CHECKER.
+
+DEFAULT-EXECUTABLE is the default executable. It is only used in
+the docstring of the variable.
+
+The variable is defined with `defcustom' in the
+`flycheck-executables' group. It's also defined to be risky as
+file-local variable, to avoid arbitrary executables being used
+for syntax checking."
+ (let ((executable-var (flycheck-checker-executable-variable checker)))
+ `(progn
+ (defcustom ,executable-var nil
+ ,(format "The executable of the %s syntax checker.
+
+Either a string containing the name or the path of the
+executable, or nil to use the default executable from the syntax
+checker declaration.
+
+The default executable is %S." checker default-executable)
+ :type '(choice (const :tag "Default executable" nil)
+ (string :tag "Name or path"))
+ :group 'flycheck-executables
+ :risky t))))
+
+(defun flycheck-set-checker-executable (checker &optional executable)
+ "Set the executable of CHECKER in the current buffer.
+
+CHECKER is a syntax checker symbol. EXECUTABLE is a string with
+the name of an executable or the path to an executable file, which
+is to be used as executable for CHECKER. If omitted or nil,
+reset the executable of CHECKER.
+
+Interactively, prompt for a syntax checker and an executable
+file, and set the executable of the selected syntax checker.
+With prefix arg, prompt for a syntax checker only, and reset the
+executable of the select checker to the default.
+
+Set the executable variable of CHECKER, that is,
+`flycheck-CHECKER-executable' to EXECUTABLE. Signal
+`user-error', if EXECUTABLE does not denote a command or an
+executable file.
+
+This command is intended for interactive use only. In Lisp, just
+`let'-bind the corresponding variable, or set it directly. Use
+`flycheck-checker-executable-variable' to obtain the executable
+variable symbol for a syntax checker."
+ (declare (interactive-only "Set the executable variable directly instead"))
+ (interactive
+ (let* ((checker (flycheck-read-checker "Syntax checker: "))
+ (default-executable (flycheck-checker-default-executable checker))
+ (executable (if current-prefix-arg
+ nil
+ (read-file-name "Executable: " nil default-executable
+ nil nil flycheck-executable-find))))
+ (list checker executable)))
+ (when (and executable (not (funcall flycheck-executable-find executable)))
+ (user-error "%s is no executable" executable))
+ (let ((variable (flycheck-checker-executable-variable checker)))
+ (set (make-local-variable variable) executable)))
+
+
+;;; Configuration files and options for command checkers
+(defun flycheck-register-config-file-var (var checkers)
+ "Register VAR as config file var for CHECKERS.
+
+CHECKERS is a single syntax checker or a list thereof."
+ (when (symbolp checkers)
+ (setq checkers (list checkers)))
+ (dolist (checker checkers)
+ (setf (flycheck-checker-get checker 'config-file-var) var)))
+
+;;;###autoload
+(defmacro flycheck-def-config-file-var (symbol checker &optional file-name
+ &rest custom-args)
+ "Define SYMBOL as config file variable for CHECKER, with default FILE-NAME.
+
+SYMBOL is declared as customizable variable using `defcustom', to
+provide configuration files for the given syntax CHECKER.
+CUSTOM-ARGS are forwarded to `defcustom'.
+
+FILE-NAME is the initial value of the new variable. If omitted,
+the default value is nil. It can be either a string or a list of
+strings.
+
+Use this together with the `config-file' form in the `:command'
+argument to `flycheck-define-checker'."
+ (declare (indent 3))
+ `(progn
+ (defcustom ,symbol ,file-name
+ ,(format "Configuration file for `%s'.
+
+If set to a string, locate the configuration file using the
+functions from `flycheck-locate-config-file-functions'. If the
+file is found pass it to the syntax checker as configuration
+file.
+
+If no configuration file is found, or if this variable is set to
+nil, invoke the syntax checker without a configuration file.
+
+Use this variable as file-local variable if you need a specific
+configuration file for a buffer." checker)
+ :type '(choice (const :tag "No configuration file" nil)
+ (string :tag "File name or path")
+ (repeat :tag "File names or paths" string))
+ :safe #'flycheck-string-or-string-list-p
+ :group 'flycheck-config-files
+ ,@custom-args)
+ (flycheck-register-config-file-var ',symbol ',checker)))
+
+(defun flycheck-locate-config-file (filenames checker)
+ "Locate the configuration file for CHECKER, based on FILENAMES.
+
+FILENAMES can be either a single file, or a list. Each filename
+is passed to all `flycheck-locate-config-file-functions', until
+one returns non-nil.
+
+Return the absolute path of the configuration file, or nil if no
+configuration file was found."
+ (when (stringp filenames)
+ (setq filenames (list filenames)))
+ (let ((config-file nil))
+ (while (and filenames (null config-file))
+ (setq config-file (run-hook-with-args-until-success
+ 'flycheck-locate-config-file-functions
+ (pop filenames) checker)))
+ (when (and config-file (file-exists-p config-file))
+ config-file)))
+
+(defun flycheck-locate-config-file-by-path (filepath _checker)
+ "Locate a configuration file by a FILEPATH.
+
+If FILEPATH is a contains a path separator, expand it against the
+default directory and return it if it points to an existing file.
+Otherwise return nil.
+
+_CHECKER is ignored."
+ ;; If the path is just a plain file name, skip it.
+ (unless (string= (file-name-nondirectory filepath) filepath)
+ (let ((file-name (expand-file-name filepath)))
+ (and (file-exists-p file-name) file-name))))
+
+(defun flycheck-locate-config-file-ancestor-directories (filename _checker)
+ "Locate a configuration FILENAME in ancestor directories.
+
+If the current buffer has a file name, search FILENAME in the
+directory of the current buffer and all ancestors thereof (see
+`locate-dominating-file'). If the file is found, return its
+absolute path. Otherwise return nil.
+
+_CHECKER is ignored."
+ (-when-let* ((basefile (buffer-file-name))
+ (directory (locate-dominating-file basefile filename)))
+ (expand-file-name filename directory)))
+
+(defun flycheck-locate-config-file-home (filename _checker)
+ "Locate a configuration FILENAME in the home directory.
+
+Return the absolute path, if FILENAME exists in the user's home
+directory, or nil otherwise."
+ (let ((path (expand-file-name filename "~")))
+ (when (file-exists-p path)
+ path)))
+
+(seq-do (apply-partially #'custom-add-frequent-value
+ 'flycheck-locate-config-file-functions)
+ '(flycheck-locate-config-file-by-path
+ flycheck-locate-config-file-ancestor-directories
+ flycheck-locate-config-file-home))
+
+(defun flycheck-register-option-var (var checkers)
+ "Register an option VAR with CHECKERS.
+
+VAR is an option symbol, and CHECKERS a syntax checker symbol or
+a list thereof. Register VAR with all CHECKERS so that it
+appears in the help output."
+ (when (symbolp checkers)
+ (setq checkers (list checkers)))
+ (dolist (checker checkers)
+ (cl-pushnew var (flycheck-checker-get checker 'option-vars))))
+
+;;;###autoload
+(defmacro flycheck-def-option-var (symbol init-value checkers docstring
+ &rest custom-args)
+ "Define SYMBOL as option variable with INIT-VALUE for CHECKER.
+
+SYMBOL is declared as customizable variable using `defcustom', to
+provide an option for the given syntax CHECKERS (a checker or a
+list of checkers). INIT-VALUE is the initial value of the
+variable, and DOCSTRING is its docstring. CUSTOM-ARGS are
+forwarded to `defcustom'.
+
+Use this together with the `option', `option-list' and
+`option-flag' forms in the `:command' argument to
+`flycheck-define-checker'."
+ (declare (indent 3)
+ (doc-string 4))
+ `(progn
+ (defcustom ,symbol ,init-value
+ ,(concat docstring "
+
+This variable is an option for the following syntax checkers:
+
+"
+ (mapconcat (lambda (c) (format " - `%s'" c))
+ (if (symbolp checkers) (list checkers) checkers)
+ "\n"))
+ :group 'flycheck-options
+ ,@custom-args)
+ (flycheck-register-option-var ',symbol ',checkers)))
+
+(defun flycheck-option-int (value)
+ "Convert an integral option VALUE to a string.
+
+If VALUE is nil, return nil. Otherwise return VALUE converted to
+a string."
+ (and value (number-to-string value)))
+
+(defun flycheck-option-symbol (value)
+ "Convert a symbol option VALUE to string.
+
+If VALUE is nil return nil. Otherwise return VALUE converted to
+a string."
+ (and value (symbol-name value)))
+
+(defun flycheck-option-comma-separated-list (value &optional separator filter)
+ "Convert VALUE into a list separated by SEPARATOR.
+
+SEPARATOR is a string to separate items in VALUE, defaulting to
+\",\". FILTER is an optional function, which takes a single
+argument and returns either a string or nil.
+
+If VALUE is a list, apply FILTER to each item in VALUE, remove
+all nil items, and return a single string of all remaining items
+separated by SEPARATOR.
+
+Otherwise, apply FILTER to VALUE and return the result.
+SEPARATOR is ignored in this case."
+ (let ((filter (or filter #'identity))
+ (separator (or separator ",")))
+ (if (listp value)
+ (-when-let (value (delq nil (seq-map filter value)))
+ (string-join value separator))
+ (funcall filter value))))
+
+(defmacro flycheck-def-args-var (symbol checkers &rest custom-args)
+ "Define SYMBOL as argument variable for CHECKERS.
+
+SYMBOL is declared as customizable, risky and buffer-local
+variable using `defcustom' to provide an option for arbitrary
+arguments for the given syntax CHECKERS (either a single checker
+or a list of checkers). CUSTOM-ARGS is forwarded to `defcustom'.
+
+Use the `eval' form to splice this variable into the
+`:command'."
+ (declare (indent 2))
+ `(flycheck-def-option-var ,symbol nil ,checkers
+ "A list of additional command line arguments.
+
+The value of this variable is a list of strings with additional
+command line arguments."
+ :risky t
+ :type '(repeat (string :tag "Argument"))
+ ,@custom-args))
+
+
+;;; Command syntax checkers as compile commands
+(defun flycheck-checker-pattern-to-error-regexp (pattern)
+ "Convert PATTERN into an error regexp for compile.el.
+
+Return a list representing PATTERN, suitable as element in
+`compilation-error-regexp-alist'."
+ (let* ((regexp (car pattern))
+ (level (cdr pattern))
+ (level-no (flycheck-error-level-compilation-level level)))
+ `(,regexp 1 (2 . 6) (3 . 7) ,level-no)))
+
+(defun flycheck-checker-compilation-error-regexp-alist (checker)
+ "Convert error patterns of CHECKER for use with compile.el.
+
+Return an alist of all error patterns of CHECKER, suitable for
+use with `compilation-error-regexp-alist'."
+ (seq-map #'flycheck-checker-pattern-to-error-regexp
+ (flycheck-checker-get checker 'error-patterns)))
+
+(defun flycheck--substitute-shell-command-argument (arg checker)
+ "Substitute ARG for CHECKER.
+
+Like `flycheck-substitute-argument', except for source,
+source-inplace, and source-original."
+ (if (memq arg '(source source-inplace source-original))
+ (list buffer-file-name)
+ (flycheck-substitute-argument arg checker)))
+
+(defun flycheck--checker-substituted-shell-command-arguments (checker)
+ "Get the substituted arguments of a CHECKER to run as a shell command.
+
+Substitute each argument of CHECKER using
+`flycheck-substitute-shell-command-argument'."
+ (apply #'append
+ (seq-map (lambda (arg)
+ (flycheck--substitute-shell-command-argument arg checker))
+ (flycheck-checker-arguments checker))))
+
+(defun flycheck-checker-shell-command (checker)
+ "Get a shell command for CHECKER.
+
+Perform substitution in the arguments of CHECKER, but with
+`flycheck--substitute-shell-command-argument'.
+
+Return the command of CHECKER as single string, suitable for
+shell execution."
+ ;; Note: Do NOT use `combine-and-quote-strings' here. Despite it's name it
+ ;; does not properly quote shell arguments, and actually breaks for special
+ ;; characters. See https://github.com/flycheck/flycheck/pull/522
+ (let* ((args (flycheck--checker-substituted-shell-command-arguments checker))
+ (program
+ (or (flycheck-find-checker-executable checker)
+ (user-error "Cannot find `%s' using `flycheck-executable-find'"
+ (flycheck-checker-executable checker))))
+ (wrapped (flycheck--wrap-command program args))
+ (abs-prog
+ ;; The executable path returned by `flycheck-command-wrapper-function'
+ ;; may not be absolute, so expand it here. See URL
+ ;; `https://github.com/flycheck/flycheck/issues/1461'.
+ (or (executable-find (car wrapped))
+ (user-error "Cannot find `%s' using `executable-find'"
+ (car wrapped))))
+ (command (mapconcat #'shell-quote-argument
+ (cons abs-prog (cdr wrapped)) " ")))
+ (if (flycheck-checker-get checker 'standard-input)
+ ;; If the syntax checker expects the source from standard input add an
+ ;; appropriate shell redirection
+ (concat command " < " (shell-quote-argument (buffer-file-name)))
+ command)))
+
+(defun flycheck-compile-name (_name)
+ "Get a name for a Flycheck compilation buffer.
+
+_NAME is ignored."
+ (format "*Flycheck %s*" (buffer-file-name)))
+
+(defun flycheck-compile (checker)
+ "Run CHECKER via `compile'.
+
+CHECKER must be a valid syntax checker. Interactively, prompt
+for a syntax checker to run.
+
+Instead of highlighting errors in the buffer, this command pops
+up a separate buffer with the entire output of the syntax checker
+tool, just like `compile' (\\[compile])."
+ (interactive
+ (let ((default (flycheck-get-checker-for-buffer)))
+ (list (flycheck-read-checker "Run syntax checker as compile command: "
+ (when (flycheck-checker-get default 'command)
+ default)
+ 'command))))
+ (unless (flycheck-valid-checker-p checker)
+ (user-error "%S is not a valid syntax checker" checker))
+ (unless (buffer-file-name)
+ (user-error "Cannot compile a buffer without a backing file"))
+ (unless (flycheck-may-use-checker checker)
+ (user-error "Cannot use syntax checker %S in this buffer" checker))
+ (unless (flycheck-checker-executable checker)
+ (user-error "Cannot run checker %S as shell command" checker))
+ (save-some-buffers)
+ (let* ((default-directory (flycheck-compute-working-directory checker))
+ (command (flycheck-checker-shell-command checker))
+ (buffer (compilation-start command nil #'flycheck-compile-name)))
+ (with-current-buffer buffer
+ (setq-local compilation-error-regexp-alist
+ (flycheck-checker-compilation-error-regexp-alist checker)))))
+
+
+;;; General error parsing for command checkers
+(defun flycheck-parse-output (output checker buffer)
+ "Parse OUTPUT from CHECKER in BUFFER.
+
+OUTPUT is a string with the output from the checker symbol
+CHECKER. BUFFER is the buffer which was checked.
+
+Return the errors parsed with the error patterns of CHECKER."
+ (funcall (flycheck-checker-get checker 'error-parser) output checker buffer))
+
+(defun flycheck-fix-error-filename (err buffer-files cwd)
+ "Fix the file name of ERR from BUFFER-FILES.
+
+Resolves error file names relative to CWD directory.
+
+Make the file name of ERR absolute. If the absolute file name of
+ERR is in BUFFER-FILES, replace it with the value of variable
+`buffer-file-name'."
+ (flycheck-error-with-buffer err
+ (-when-let (filename (flycheck-error-filename err))
+ (when (seq-some (apply-partially #'flycheck-same-files-p
+ (expand-file-name filename cwd))
+ buffer-files)
+ (setf (flycheck-error-filename err) buffer-file-name)
+ (when (and buffer-file-name (flycheck-error-message err))
+ (setf (flycheck-error-message err)
+ (replace-regexp-in-string
+ (regexp-quote filename) buffer-file-name
+ (flycheck-error-message err) 'fixed-case 'literal))))))
+ err)
+
+
+;;; Error parsers for command syntax checkers
+(defun flycheck-parse-xml-region (beg end)
+ "Parse the xml region between BEG and END.
+
+Wrapper around `xml-parse-region' which transforms the return
+value of this function into one compatible to
+`libxml-parse-xml-region' by simply returning the first element
+from the node list."
+ (ignore-errors (car (xml-parse-region beg end))))
+
+(defun flycheck-parse-xml-region-with-fallback (beg end)
+ "Parse the xml region between BEG and END.
+
+Try parsing with libxml first; if that fails, revert to
+`flycheck-parse-xml-region'. Failures can be caused by incorrect
+XML (see URL `https://github.com/flycheck/flycheck/issues/1298'),
+or on Windows by a missing libxml DLL with a libxml-enabled Emacs
+\(see URL `https://github.com/flycheck/flycheck/issues/1330')."
+ ;; FIXME use `libxml-available-p' when it gets implemented.
+ (or (and (fboundp 'libxml-parse-xml-region)
+ (libxml-parse-xml-region beg end))
+ (flycheck-parse-xml-region beg end)))
+
+(defvar flycheck-xml-parser 'flycheck-parse-xml-region-with-fallback
+ "Function used to parse an xml string from a region.
+
+The default uses libxml if available, and falls back to
+`flycheck-parse-xml-region' otherwise.")
+
+(defun flycheck-parse-xml-string (xml)
+ "Parse an XML string.
+
+Return the document tree parsed from XML in the form `(ROOT ATTRS
+BODY...)'. ROOT is a symbol identifying the name of the root
+element. ATTRS is an alist of the attributes of the root node.
+BODY is zero or more body elements, either as strings (in case of
+text nodes) or as XML nodes, in the same for as the root node."
+ (with-temp-buffer
+ (insert xml)
+ (funcall flycheck-xml-parser (point-min) (point-max))))
+
+(defun flycheck-parse-checkstyle (output checker buffer)
+ "Parse Checkstyle errors from OUTPUT.
+
+Parse Checkstyle-like XML output. Use this error parser for
+checkers that have an option to output errors in this format.
+
+CHECKER and BUFFER denoted the CHECKER that returned OUTPUT and
+the BUFFER that was checked respectively.
+
+See URL `http://checkstyle.sourceforge.net/' for information
+about Checkstyle."
+ (pcase (flycheck-parse-xml-string output)
+ (`(checkstyle ,_ . ,file-nodes)
+ (let (errors)
+ (dolist (node file-nodes)
+ (pcase node
+ (`(file ,file-attrs . ,error-nodes)
+ (dolist (node error-nodes)
+ (pcase node
+ (`(error ,error-attrs . ,_)
+ (let-alist error-attrs
+ (push (flycheck-error-new-at
+ (flycheck-string-to-number-safe .line)
+ (flycheck-string-to-number-safe .column)
+ (pcase .severity
+ (`"error" 'error)
+ (`"warning" 'warning)
+ (`"info" 'info)
+ ;; Default to error for unknown .severity
+ (_ 'error))
+ .message
+ :checker checker :id .source
+ :buffer buffer
+ :filename (cdr (assq 'name file-attrs)))
+ errors))))))))
+ (nreverse errors)))))
+
+(defun flycheck-parse-cppcheck (output checker buffer)
+ "Parse Cppcheck errors from OUTPUT.
+
+Parse Cppcheck XML v2 output.
+
+CHECKER and BUFFER denoted the CHECKER that returned OUTPUT and
+the BUFFER that was checked respectively.
+
+See URL `http://cppcheck.sourceforge.net/' for more information
+about Cppcheck."
+ (pcase (flycheck-parse-xml-string output)
+ (`(results ,_ . ,body)
+ (let (errors)
+ (dolist (node body)
+ (pcase node
+ (`(errors ,_ . ,error-nodes)
+ (dolist (node error-nodes)
+ (pcase node
+ (`(error ,error-attrs . ,loc-nodes)
+ (let ((id (cdr (assq 'id error-attrs)))
+ (message (cdr (assq 'verbose error-attrs)))
+ (level (pcase (cdr (assq 'severity error-attrs))
+ (`"error" 'error)
+ (`"style" 'info)
+ (`"information" 'info)
+ (_ 'warning))))
+ (dolist (node loc-nodes)
+ (pcase node
+ (`(location ,loc-attrs . ,_)
+ (let-alist loc-attrs
+ (push (flycheck-error-new-at
+ (flycheck-string-to-number-safe .line)
+ nil
+ level
+ ;; cppcheck return newline characters as "\012"
+ (replace-regexp-in-string "\\\\012" "\n"
+ message)
+ :id id
+ :checker checker
+ :buffer buffer
+ :filename .file)
+ errors))))))))))))
+ (nreverse errors)))))
+
+(defun flycheck-parse-phpmd (output checker buffer)
+ "Parse phpmd errors from OUTPUT.
+
+CHECKER and BUFFER denoted the CHECKER that returned OUTPUT and
+the BUFFER that was checked respectively.
+
+See URL `http://phpmd.org/' for more information about phpmd."
+ (pcase (flycheck-parse-xml-string output)
+ (`(pmd ,_ . ,body)
+ (let (errors)
+ (dolist (node body)
+ (pcase node
+ (`(file ,file-attrs . ,violation-nodes)
+ (let ((filename (cdr (assq 'name file-attrs))))
+ (dolist (node violation-nodes)
+ (pcase node
+ (`(violation ,vio-attrs ,(and message (pred stringp)))
+ (let-alist vio-attrs
+ (push
+ (flycheck-error-new-at
+ (flycheck-string-to-number-safe .beginline)
+ nil
+ 'warning (string-trim message)
+ ;; Ignore .endline (phpmd marks giant spans as errors)
+ ;; :end-line (flycheck-string-to-number-safe .endline)
+ :id .rule
+ :checker checker
+ :buffer buffer
+ :filename filename)
+ errors)))))))))
+ (nreverse errors)))))
+
+(defun flycheck-parse-reek (output checker buffer)
+ "Parse Reek warnings from JSON OUTPUT.
+
+CHECKER and BUFFER denote the CHECKER that returned OUTPUT and
+the BUFFER that was checked respectively.
+
+See URL `https://github.com/troessner/reek' for more information
+about Reek."
+ (let ((errors nil))
+ (dolist (message (car (flycheck-parse-json output)))
+ (let-alist message
+ (dolist (line (delete-dups .lines))
+ (push
+ (flycheck-error-new-at
+ line
+ nil
+ 'warning (concat .context " " .message)
+ :id .smell_type
+ :checker checker
+ :buffer buffer
+ :filename .source)
+ errors))))
+ (nreverse errors)))
+
+(defun flycheck-parse-go-staticcheck (output checker buffer)
+ "Parse staticheck warnings from JSON OUTPUT.
+
+CHECKER and BUFFER denote the CHECKER that returned OUTPUT and
+the BUFFER that was checked respectively.
+
+See URL `https://staticcheck.io/docs/formatters' for more
+information about staticheck."
+ (let ((errors nil))
+ (dolist (msg (flycheck-parse-json output))
+ (let-alist msg
+ (push
+ (flycheck-error-new-at
+ .location.line
+ .location.column
+ (pcase .severity
+ (`"error" 'error)
+ (`"warning" 'warning)
+ (`"ignored" 'info)
+ ;; Default to warning for unknown .severity
+ (_ 'warning))
+ .message
+ :id .code
+ :checker checker
+ :buffer buffer
+ :filename .location.file)
+ errors)))
+ (nreverse errors)))
+
+(defun flycheck-parse-tslint (output checker buffer)
+ "Parse TSLint errors from JSON OUTPUT.
+
+CHECKER and BUFFER denoted the CHECKER that returned OUTPUT and
+the BUFFER that was checked respectively.
+
+See URL `https://palantir.github.io/tslint/' for more information
+about TSLint."
+ (seq-map (lambda (message)
+ (let-alist message
+ (flycheck-error-new-at
+ (+ 1 .startPosition.line)
+ (+ 1 .startPosition.character)
+ (pcase .ruleSeverity
+ ("ERROR" 'error)
+ ("WARNING" 'warning)
+ (_ 'warning))
+ .failure
+ :id .ruleName
+ :checker checker
+ :buffer buffer
+ :filename .name
+ :end-line (+ 1 .endPosition.line)
+ :end-column (+ 1 .endPosition.character))))
+ (car (flycheck-parse-json output))))
+
+(defun flycheck-parse-rust-collect-spans (span)
+ "Return a list of spans contained in a SPAN object."
+ (let ((spans))
+ (let-alist span
+ ;; With macro expansion errors, some spans will point to phony file names
+ ;; to indicate an error inside the std rust lib. We skip these spans as
+ ;; they won't appear in flycheck anyway.
+ (unless (string= .file_name "<std macros>")
+ (push span spans))
+
+ ;; Macro expansion errors will have a span in the 'expansion' field, so we
+ ;; recursively collect it.
+ (if .expansion.span
+ (append (flycheck-parse-rust-collect-spans .expansion.span)
+ spans)
+ spans))))
+
+(defun flycheck-parse-rustc-diagnostic (diagnostic checker buffer)
+ "Turn a rustc DIAGNOSTIC into a `flycheck-error'.
+
+CHECKER and BUFFER denote the CHECKER that returned DIAGNOSTIC
+and the BUFFER that was checked respectively.
+
+DIAGNOSTIC should be a parsed JSON object describing a rustc
+diagnostic, following the format described there:
+
+https://github.com/rust-lang/rust/blob/master/src/librustc_errors/json.rs#L154"
+ (let ((error-message)
+ (error-level)
+ (error-code)
+ (primary-filename)
+ (primary-line)
+ (primary-column)
+ (primary-end-line)
+ (primary-end-column)
+ (group (make-symbol "group"))
+ (spans)
+ (children)
+ (errors))
+ ;; The diagnostic format is described in the link above. The gist of it is
+ ;; that a diagnostic can have several causes in the source text; these
+ ;; causes are represented by spans. The diagnostic has a message and a
+ ;; level (error, warning), while the spans have a filename, line, column,
+ ;; and an optional label. The primary span points to the root cause of the
+ ;; error in the source text, while non-primary spans point to related
+ ;; causes. Spans may have an 'expansion' field for macro expansion errors;
+ ;; these expansion fields will contain another span (and so on). In
+ ;; addition, a diagnostic can also have children diagnostics that are used
+ ;; to provide additional information through their message field, but do not
+ ;; seem to contain any spans (yet).
+ ;;
+ ;; We first gather spans in order to turn every span into a flycheck error
+ ;; object, that we collect into the `errors' list.
+
+ ;; Nested `let-alist' cause compilation warnings, hence we `setq' all
+ ;; these values here first to avoid nesting.
+ (let-alist diagnostic
+ (setq error-message .message
+ error-level (pcase .level
+ (`"error" 'error)
+ (`"warning" 'warning)
+ (`"note" 'info)
+ (_ 'error))
+ ;; The 'code' field of the diagnostic contains the actual error
+ ;; code and an optional explanation that we ignore
+ error-code .code.code
+ ;; Collect all spans recursively
+ spans (seq-mapcat #'flycheck-parse-rust-collect-spans .spans)
+ children .children))
+
+ ;; Turn each span into a flycheck error
+ (dolist (span spans)
+ (let-alist span
+ ;; Children may not have filename/line/column information, so we use
+ ;; those from the primary span
+ (when .is_primary
+ (setq primary-filename .file_name
+ primary-line .line_start
+ primary-column .column_start
+ primary-end-line .line_end
+ primary-end-column .column_end))
+ (push
+ (flycheck-error-new-at
+ .line_start
+ .column_start
+ ;; Non-primary spans are used for notes
+ (if .is_primary error-level 'info)
+ (if .is_primary
+ ;; Primary spans may have labels with additional information
+ (concat error-message (when .label
+ (format " (%s)" .label)))
+ ;; If the label is empty, fallback on the error message,
+ ;; otherwise we won't be able to display anything
+ (or .label error-message))
+ :id error-code
+ :checker checker
+ :buffer buffer
+ :filename .file_name
+ :group group
+ :end-line .line_end
+ :end-column .column_end)
+ errors)))
+
+ ;; Then we turn children messages into flycheck errors pointing to the
+ ;; location of the primary span.
+ (dolist (child children)
+ (let ((message (let-alist child .message)))
+ (let-alist (car (let-alist child .spans))
+ (push
+ (flycheck-error-new-at
+ ;; Use the line/column from the first span if there is one, or
+ ;; fallback to the line/column information from the primary span of
+ ;; the diagnostic.
+ (or .line_start primary-line)
+ (or .column_start primary-column)
+ 'info
+ ;; Messages from `cargo clippy' may suggest replacement code. In
+ ;; these cases, the `message' field itself is an unhelpful `try' or
+ ;; `change this to'. We add the `suggested_replacement' field in
+ ;; these cases.
+ (if .suggested_replacement
+ (format "%s: `%s`" message .suggested_replacement)
+ message)
+ :id error-code
+ :checker checker
+ :buffer buffer
+ :filename primary-filename
+ :group group
+ :end-line (or .line_end primary-end-line)
+ :end-column (or .column_end primary-end-column))
+ errors))))
+
+ ;; If there are no spans, the error is not associated with a specific
+ ;; file but with the project as a whole. We still need to report it to
+ ;; the user by emitting a corresponding flycheck-error object.
+ ;; Check whether the code is non-nil because Rust≥1.44 includes the
+ ;; warning count upon completion.
+ (when (and error-code (not spans))
+ (push (flycheck-error-new-at
+ ;; We have no specific position to attach the error to, so
+ ;; let's use the top of the file.
+ 1 1
+ error-level
+ error-message
+ :id error-code
+ :checker checker
+ :buffer buffer
+ :group group)
+ errors))
+ (nreverse errors)))
+
+(defconst flycheck--json-parser
+ (if (and (functionp 'json-parse-buffer)
+ ;; json-parse-buffer only supports keyword arguments in Emacs 27+
+ (>= emacs-major-version 27))
+ (lambda ()
+ (json-parse-buffer
+ :object-type 'alist :array-type 'list
+ :null-object nil :false-object nil))
+ #'json-read)
+ "Function to use to parse JSON strings.")
+
+(defun flycheck-parse-json (output)
+ "Return parsed JSON data from OUTPUT.
+
+OUTPUT is a string that contains JSON data. Each line of OUTPUT
+may be either plain text, a JSON array (starting with `['), or a
+JSON object (starting with `{').
+
+This function ignores the plain text lines, parses the JSON
+lines, and returns the parsed JSON lines in a list."
+ (let ((objects nil)
+ (json-array-type 'list)
+ (json-false nil))
+ (with-temp-buffer
+ (insert output)
+ (goto-char (point-min))
+ (while (not (eobp))
+ (when (memq (char-after) '(?\{ ?\[))
+ (push (funcall flycheck--json-parser) objects))
+ (forward-line)))
+ (nreverse objects)))
+
+(defun flycheck-parse-rustc (output checker buffer)
+ "Parse rustc errors from OUTPUT and return a list of `flycheck-error'.
+
+CHECKER and BUFFER denote the CHECKER that returned OUTPUT and
+the BUFFER that was checked respectively.
+
+The expected format for OUTPUT is a mix of plain text lines and
+JSON lines. This function ignores the plain text lines and
+parses only JSON lines. Each JSON line is expected to be a JSON
+object that corresponds to a diagnostic from the compiler. The
+expected diagnostic format is described there:
+
+https://github.com/rust-lang/rust/blob/master/src/libsyntax/json.rs#L67-L139"
+ (seq-mapcat (lambda (msg)
+ (flycheck-parse-rustc-diagnostic msg checker buffer))
+ (flycheck-parse-json output)))
+
+(defun flycheck-parse-cargo-rustc (output checker buffer)
+ "Parse Cargo errors from OUTPUT and return a list of `flycheck-error'.
+
+CHECKER and BUFFER denote the CHECKER that returned OUTPUT and
+the BUFFER that was checked respectively.
+
+The expected format for OUTPUT is a mix of plain text lines and
+JSON lines. This function ignores the plain text lines and
+parses only JSON lines. Each JSON line is expected to be a JSON
+object that represents a message from Cargo. The format of
+messages emitted by Cargo is described in cargo's
+machine_message.rs at URL `https://git.io/vh24R'."
+ (let ((errors))
+ (dolist (msg (flycheck-parse-json output))
+ (let-alist msg
+ ;; Errors and warnings from rustc are wrapped by cargo, so we filter and
+ ;; unwrap them, and delegate the actual construction of `flycheck-error'
+ ;; objects to `flycheck-parse-rustc-diagnostic'.
+ ;; We put the error record with nil code since flycheck regards
+ ;; the case of nonzero return code without any error report
+ ;; as abnormal result.
+ (when (string= .reason "compiler-message")
+ (push (flycheck-parse-rustc-diagnostic .message checker buffer)
+ errors))))
+ (apply #'nconc errors)))
+
+;; Some checkers output ANSI terminal colors, which don't match up
+;; with :error-patterns, so we strip those color codes from the output
+;; here before passing it along to the default behavior. This is
+;; originally only used in the rebar3 checker, but the systemd checker
+;; now also makes use of it.
+;;
+;; The relevant discussion can be found at
+;; https://github.com/flycheck/flycheck/pull/1144
+(defun flycheck-parse-with-patterns-without-color (output checker buffer)
+ "Strip color codes from OUTPUT before passing it to the default behavior.
+
+CHECKER and BUFFER are passed along as well."
+ (flycheck-parse-with-patterns
+ (and (fboundp 'ansi-color-filter-apply) (ansi-color-filter-apply output))
+ checker buffer))
+
+
+;;; Error parsing with regular expressions
+(defun flycheck-get-regexp (patterns)
+ "Create a single regular expression from PATTERNS."
+ (rx-to-string `(or ,@(seq-map (lambda (p) (list 'regexp (car p))) patterns))
+ 'no-group))
+
+(defun flycheck-tokenize-output-with-patterns (output patterns)
+ "Tokenize OUTPUT with PATTERNS.
+
+Split the output into error tokens, using all regular expressions
+from the error PATTERNS. An error token is simply a string
+containing a single error from OUTPUT. Such a token can then be
+parsed into a structured error by applying the PATTERNS again,
+see `flycheck-parse-error-with-patterns'.
+
+Return a list of error tokens."
+ (let ((regexp (flycheck-get-regexp patterns))
+ (last-match 0)
+ errors)
+ (while (string-match regexp output last-match)
+ (push (match-string 0 output) errors)
+ (setq last-match (match-end 0)))
+ (reverse errors)))
+
+(defun flycheck-try-parse-error-with-pattern (err pattern checker)
+ "Try to parse a single ERR with a PATTERN for CHECKER.
+
+Return the parsed error if PATTERN matched ERR, or nil
+otherwise.
+
+`end-line' defaults to the value of `line' when `end-column' is
+set, since checkers often omit redundant end lines (as in
+<file>:<line>:<column>-<end-column>)."
+ (let ((regexp (car pattern))
+ (level (cdr pattern)))
+ (when (string-match regexp err)
+ (let ((filename (match-string 1 err))
+ (line (flycheck-string-to-number-safe (match-string 2 err)))
+ (column (flycheck-string-to-number-safe (match-string 3 err)))
+ (message (match-string 4 err))
+ (id (match-string 5 err))
+ (end-line (flycheck-string-to-number-safe (match-string 6 err)))
+ (end-column (flycheck-string-to-number-safe (match-string 7 err))))
+ (flycheck-error-new-at
+ line
+ column
+ level
+ (unless (string-empty-p message) message)
+ :id (unless (string-empty-p id) id)
+ :checker checker
+ :filename (if (or (null filename) (string-empty-p filename))
+ (buffer-file-name)
+ filename)
+ :end-line (or end-line (and end-column line))
+ :end-column end-column)))))
+
+(defun flycheck-parse-error-with-patterns (err patterns checker)
+ "Parse a single ERR with error PATTERNS for CHECKER.
+
+Apply each pattern in PATTERNS to ERR, in the given order, and
+return the first parsed error."
+ ;; Try to parse patterns in the order of declaration to make sure that the
+ ;; first match wins.
+ (let (parsed-error)
+ (while (and patterns
+ (not (setq parsed-error
+ (flycheck-try-parse-error-with-pattern
+ err (car patterns) checker))))
+ (setq patterns (cdr patterns)))
+ parsed-error))
+
+(defun flycheck-parse-with-patterns (output checker buffer)
+ "Parse OUTPUT from CHECKER with error patterns.
+
+Uses the error patterns of CHECKER to tokenize the output and
+tries to parse each error token with all patterns, in the order
+of declaration. Hence an error is never matched twice by two
+different patterns. The pattern declared first always wins.
+
+_BUFFER is ignored.
+
+Return a list of parsed errors and warnings (as `flycheck-error'
+objects)."
+ (with-current-buffer buffer
+ (let ((patterns (flycheck-checker-get checker 'error-patterns)))
+ (seq-map (lambda (err)
+ (flycheck-parse-error-with-patterns err patterns checker))
+ (flycheck-tokenize-output-with-patterns output patterns)))))
+
+
+;;; Convenience definition of command-syntax checkers
+
+;; This macro is autoloaded to prevent `with-eval-after-load' from expanding its
+;; arguments. See https://github.com/flycheck/flycheck/issues/1398.
+;;;###autoload
+(defmacro flycheck-define-checker (symbol docstring &rest properties)
+ "Define SYMBOL as command syntax checker with DOCSTRING and PROPERTIES.
+
+Like `flycheck-define-command-checker', but PROPERTIES must not
+be quoted. Also, implicitly define the executable variable for
+SYMBOL with `flycheck-def-executable-var'."
+ (declare (indent 1)
+ (doc-string 2))
+ (let ((command (plist-get properties :command))
+ (parser (plist-get properties :error-parser))
+ (filter (plist-get properties :error-filter))
+ (explainer (plist-get properties :error-explainer))
+ (predicate (plist-get properties :predicate))
+ (enabled-fn (plist-get properties :enabled))
+ (verify-fn (plist-get properties :verify)))
+
+ `(progn
+ (flycheck-def-executable-var ,symbol ,(car command))
+
+ (flycheck-define-command-checker ',symbol
+ ,docstring
+ :command ',command
+ ,@(when parser
+ `(:error-parser #',parser))
+ :error-patterns ',(plist-get properties :error-patterns)
+ ,@(when filter
+ `(:error-filter #',filter))
+ ,@(when explainer
+ `(:error-explainer #',explainer))
+ :modes ',(plist-get properties :modes)
+ ,@(when predicate
+ `(:predicate #',predicate))
+ :next-checkers ',(plist-get properties :next-checkers)
+ ,@(when enabled-fn
+ `(:enabled #',enabled-fn))
+ ,@(when verify-fn
+ `(:verify #',verify-fn))
+ :standard-input ',(plist-get properties :standard-input)
+ :working-directory ',(plist-get properties :working-directory)))))
+
+
+;;; Built-in checkers
+(flycheck-def-args-var flycheck-gnat-args ada-gnat
+ :package-version '(flycheck . "0.20"))
+
+(flycheck-def-option-var flycheck-gnat-include-path nil ada-gnat
+ "A list of include directories for GNAT.
+
+The value of this variable is a list of strings, where each
+string is a directory to add to the include path of gcc.
+Relative paths are relative to the file being checked."
+ :type '(repeat (directory :tag "Include directory"))
+ :safe #'flycheck-string-list-p
+ :package-version '(flycheck . "0.20"))
+
+(flycheck-def-option-var flycheck-gnat-language-standard "2012" ada-gnat
+ "The language standard to use in GNAT.
+
+The value of this variable is either a string denoting a language
+standard, or nil, to use the default standard. When non-nil, pass
+the language standard via the `-std' option."
+ :type '(choice (const :tag "Default standard" nil)
+ (string :tag "Language standard"))
+ :safe #'flycheck-string-or-nil-p
+ :package-version '(flycheck . "0.20"))
+
+(flycheck-def-option-var flycheck-gnat-warnings
+ '("wa") ada-gnat
+ "A list of additional Ada warnings to enable in GNAT.
+
+The value of this variable is a list of strings, where each
+string is the name of a warning category to enable. By default,
+most optional warnings are recommended, as in `-gnata'.
+
+Refer to Info Node `(gnat_ugn_unw)Warning Message Control' for
+more information about GNAT warnings."
+ :type '(repeat :tag "Warnings" (string :tag "Warning name"))
+ :safe #'flycheck-string-list-p
+ :package-version '(flycheck . "0.20"))
+
+(flycheck-define-checker ada-gnat
+ "An Ada syntax checker using GNAT.
+
+Uses the GNAT compiler from GCC. See URL
+`https://www.adacore.com/community/'."
+ :command ("gnatmake"
+ "-c" ; Just compile, don't bind
+ "-f" ; Force re-compilation
+ "-u" ; Compile the main file only
+ "-gnatf" ; Full error information
+ "-gnatef" ; Full source file name
+ "-D" temporary-directory
+ (option-list "-gnat" flycheck-gnat-warnings concat)
+ (option-list "-I" flycheck-gnat-include-path concat)
+ (option "-gnat" flycheck-gnat-language-standard concat)
+ (eval flycheck-gnat-args)
+ source)
+ :error-patterns
+ ((error line-start
+ (message "In file included from") " " (file-name) ":" line ":"
+ column ":"
+ line-end)
+ (info line-start (file-name) ":" line ":" column
+ ": note: " (message) line-end)
+ (warning line-start (file-name) ":" line ":" column
+ ": warning: " (message) line-end)
+ ;; no specific error prefix in Ada
+ (error line-start (file-name) ":" line ":" column
+ ": " (message) line-end))
+ :modes ada-mode)
+
+(flycheck-define-checker asciidoc
+ "A AsciiDoc syntax checker using the AsciiDoc compiler.
+
+See URL `http://www.methods.co.nz/asciidoc'."
+ :command ("asciidoc" "-o" null-device "-")
+ :standard-input t
+ :error-patterns
+ ((error line-start
+ "asciidoc: ERROR: <stdin>: Line " line ": " (message)
+ line-end)
+ (warning line-start
+ "asciidoc: WARNING: <stdin>: Line " line ": " (message)
+ line-end)
+ (info line-start
+ "asciidoc: DEPRECATED: <stdin>: Line " line ": " (message)
+ line-end))
+ :modes adoc-mode)
+
+(flycheck-define-checker asciidoctor
+ "An AsciiDoc syntax checker using the Asciidoctor compiler.
+
+See URL `http://asciidoctor.org'."
+ :command ("asciidoctor" "-o" null-device "-")
+ :standard-input t
+ :error-patterns
+ ((error line-start
+ "asciidoctor: ERROR: <stdin>: Line " line ": " (message)
+ line-end)
+ (warning line-start
+ "asciidoctor: WARNING: <stdin>: Line " line ": " (message)
+ line-end))
+ :modes adoc-mode)
+
+(defun flycheck-awk-gawk-fix-message (err)
+ "Remove the repeated file-name/line from the error message of ERR."
+ (setf (flycheck-error-message err)
+ (replace-regexp-in-string
+ (rx line-start
+ (group (zero-or-more (any " " "\t")))
+ (group (zero-or-more nonl) "\n")
+ (backref 1))
+ "\\2"
+ (replace-regexp-in-string
+ (rx "\ngawk: " (zero-or-more (not (any " "))) ":")
+ "\n"
+ (flycheck-error-message err))))
+ err)
+
+(defun flycheck-awk-gawk-error-filter (errors)
+ "Remove repeated file-name/line from ERRORS."
+ (seq-do #'flycheck-awk-gawk-fix-message errors)
+ errors)
+
+(flycheck-define-checker awk-gawk
+ "GNU awk's built-in --lint checker."
+ :command ("gawk"
+ ;; Avoid code execution. See https://github.com/w0rp/ale/pull/1411
+ "--source" "'BEGIN{exit} END{exit 1}'"
+ "-f" source
+ "--lint"
+ "/dev/null")
+ :standard-input nil
+ :error-patterns
+ ((warning line-start
+ "gawk: "
+ (file-name) ":" line ":" (optional column ":")
+ (message (one-or-more not-newline)
+ (optional "\n"
+ (one-or-more not-newline)
+ " ^ "
+ (one-or-more not-newline)))
+ line-end))
+ :error-filter flycheck-awk-gawk-error-filter
+ :modes awk-mode)
+
+(flycheck-define-checker bazel-buildifier
+ "An Bazel checker using the buildifier.
+
+See URL `https://github.com/bazelbuild/buildtools/blob/master/buildifier'."
+ :command ("buildifier" "-lint=warn")
+ :standard-input t
+ :error-patterns
+ ((error line-start
+ "<stdin>:" line ":" column ": " (message)
+ line-end)
+ (warning line-start
+ "<stdin>:" line ": " (id (one-or-more (in word "-"))) ": " (message)
+ line-end))
+ :modes bazel-mode)
+
+(flycheck-def-args-var flycheck-clang-args c/c++-clang
+ :package-version '(flycheck . "0.22"))
+
+(flycheck-def-option-var flycheck-clang-blocks nil c/c++-clang
+ "Enable blocks in Clang.
+
+When non-nil, enable blocks in Clang with `-fblocks'. See URL
+`http://clang.llvm.org/docs/BlockLanguageSpec.html' for more
+information about blocks."
+ :type 'boolean
+ :safe #'booleanp
+ :package-version '(flycheck . "0.20"))
+
+(flycheck-def-option-var flycheck-clang-definitions nil c/c++-clang
+ "Additional preprocessor definitions for Clang.
+
+The value of this variable is a list of strings, where each
+string is an additional definition to pass to Clang, via the `-D'
+option."
+ :type '(repeat (string :tag "Definition"))
+ :safe #'flycheck-string-list-p
+ :package-version '(flycheck . "0.15"))
+
+(flycheck-def-option-var flycheck-clang-include-path nil c/c++-clang
+ "A list of include directories for Clang.
+
+The value of this variable is a list of strings, where each
+string is a directory to add to the include path of Clang.
+Relative paths are relative to the file being checked."
+ :type '(repeat (directory :tag "Include directory"))
+ :safe #'flycheck-string-list-p
+ :package-version '(flycheck . "0.14"))
+
+(flycheck-def-option-var flycheck-clang-includes nil c/c++-clang
+ "A list of additional include files for Clang.
+
+The value of this variable is a list of strings, where each
+string is a file to include before syntax checking. Relative
+paths are relative to the file being checked."
+ :type '(repeat (file :tag "Include file"))
+ :safe #'flycheck-string-list-p
+ :package-version '(flycheck . "0.15"))
+
+(flycheck-def-option-var flycheck-clang-language-standard nil c/c++-clang
+ "The language standard to use in Clang.
+
+The value of this variable is either a string denoting a language
+standard, or nil, to use the default standard. When non-nil,
+pass the language standard via the `-std' option."
+ :type '(choice (const :tag "Default standard" nil)
+ (string :tag "Language standard"))
+ :safe #'flycheck-string-or-nil-p
+ :package-version '(flycheck . "0.15"))
+(make-variable-buffer-local 'flycheck-clang-language-standard)
+
+(flycheck-def-option-var flycheck-clang-ms-extensions nil c/c++-clang
+ "Whether to enable Microsoft extensions to C/C++ in Clang.
+
+When non-nil, enable Microsoft extensions to C/C++ via
+`-fms-extensions'."
+ :type 'boolean
+ :safe #'booleanp
+ :package-version '(flycheck . "0.16"))
+
+(flycheck-def-option-var flycheck-clang-no-exceptions nil c/c++-clang
+ "Whether to disable exceptions in Clang.
+
+When non-nil, disable exceptions for syntax checks, via
+`-fno-exceptions'."
+ :type 'boolean
+ :safe #'booleanp
+ :package-version '(flycheck . "0.20"))
+
+(flycheck-def-option-var flycheck-clang-no-rtti nil c/c++-clang
+ "Whether to disable RTTI in Clang.
+
+When non-nil, disable RTTI for syntax checks, via `-fno-rtti'."
+ :type 'boolean
+ :safe #'booleanp
+ :package-version '(flycheck . "0.15"))
+
+(flycheck-def-option-var flycheck-clang-pedantic nil c/c++-clang
+ "Whether to warn about language extensions in Clang.
+
+For ISO C, follows the version specified by any -std option used.
+When non-nil, disable non-ISO extensions to C/C++ via
+`-pedantic'."
+ :type 'boolean
+ :safe #'booleanp
+ :package-version '(flycheck . "0.23"))
+
+(flycheck-def-option-var flycheck-clang-pedantic-errors nil c/c++-clang
+ "Whether to error on language extensions in Clang.
+
+For ISO C, follows the version specified by any -std option used.
+When non-nil, disable non-ISO extensions to C/C++ via
+`-pedantic-errors'."
+ :type 'boolean
+ :safe #'booleanp
+ :package-version '(flycheck . "0.23"))
+
+(flycheck-def-option-var flycheck-clang-standard-library nil c/c++-clang
+ "The standard library to use for Clang.
+
+The value of this variable is the name of a standard library as
+string, or nil to use the default standard library.
+
+Refer to the Clang manual at URL
+`http://clang.llvm.org/docs/UsersManual.html' for more
+information about the standard library."
+ :type '(choice (const :tag "Default standard library" nil)
+ (const "libc++")
+ (const :tag "GNU libstdc++" "libstdc++")
+ (string :tag "Library name"))
+ :safe #'flycheck-string-or-nil-p
+ :package-version '(flycheck . "0.15"))
+
+(flycheck-def-option-var flycheck-clang-warnings '("all" "extra") c/c++-clang
+ "A list of additional warnings to enable in Clang.
+
+The value of this variable is a list of strings, where each string
+is the name of a warning category to enable. By default, all
+recommended warnings and some extra warnings are enabled (as by
+`-Wall' and `-Wextra' respectively).
+
+Refer to the Clang manual at URL
+`http://clang.llvm.org/docs/UsersManual.html' for more
+information about warnings."
+ :type '(choice (const :tag "No additional warnings" nil)
+ (repeat :tag "Additional warnings"
+ (string :tag "Warning name")))
+ :safe #'flycheck-string-list-p
+ :package-version '(flycheck . "0.14"))
+
+(defun flycheck-c/c++-quoted-include-directory ()
+ "Get the directory for quoted includes.
+
+C/C++ compilers typically look up includes with quotation marks
+in the directory of the file being compiled. However, since
+Flycheck uses temporary copies for syntax checking, it needs to
+explicitly determine the directory for quoted includes.
+
+This function determines the directory by looking at function
+`buffer-file-name', or if that is nil, at `default-directory'."
+ (-if-let (fn (buffer-file-name))
+ (file-name-directory fn)
+ ;; If the buffer has no file name, fall back to its default directory
+ default-directory))
+
+(flycheck-define-checker c/c++-clang
+ "A C/C++ syntax checker using Clang.
+
+See URL `http://clang.llvm.org/'."
+ :command ("clang"
+ "-fsyntax-only"
+ "-fno-color-diagnostics" ; Do not include color codes in output
+ "-fno-caret-diagnostics" ; Do not visually indicate the source
+ ; location
+ "-fno-diagnostics-show-option" ; Do not show the corresponding
+ ; warning group
+ "-iquote" (eval (flycheck-c/c++-quoted-include-directory))
+ (option "-std=" flycheck-clang-language-standard concat)
+ (option-flag "-pedantic" flycheck-clang-pedantic)
+ (option-flag "-pedantic-errors" flycheck-clang-pedantic-errors)
+ (option "-stdlib=" flycheck-clang-standard-library concat)
+ (option-flag "-fms-extensions" flycheck-clang-ms-extensions)
+ (option-flag "-fno-exceptions" flycheck-clang-no-exceptions)
+ (option-flag "-fno-rtti" flycheck-clang-no-rtti)
+ (option-flag "-fblocks" flycheck-clang-blocks)
+ (option-list "-include" flycheck-clang-includes)
+ (option-list "-W" flycheck-clang-warnings concat)
+ (option-list "-D" flycheck-clang-definitions concat)
+ (option-list "-I" flycheck-clang-include-path)
+ (eval flycheck-clang-args)
+ "-x" (eval
+ (pcase major-mode
+ (`c++-mode "c++")
+ (`c-mode "c")))
+ ;; Read from standard input
+ "-")
+ :standard-input t
+ :error-patterns
+ ((info line-start (or "<stdin>" (file-name)) ":" line ":" column
+ ": note: " (optional (message)) line-end)
+ (warning line-start (or "<stdin>" (file-name)) ":" line ":" column
+ ": warning: " (optional (message)) line-end)
+ (error line-start (or "<stdin>" (file-name)) ":" line ":" column
+ ": " (or "fatal error" "error") ": " (optional (message)) line-end))
+ :error-filter
+ (lambda (errors)
+ (let ((errors (flycheck-sanitize-errors errors)))
+ (dolist (err errors)
+ ;; Clang will output empty messages for #error/#warning pragmas without
+ ;; messages. We fill these empty errors with a dummy message to get
+ ;; them past our error filtering
+ (setf (flycheck-error-message err)
+ (or (flycheck-error-message err) "no message")))
+ errors))
+ :modes (c-mode c++-mode)
+ :next-checkers ((warning . c/c++-cppcheck)))
+
+(flycheck-def-args-var flycheck-gcc-args c/c++-gcc
+ :package-version '(flycheck . "0.22"))
+
+(flycheck-def-option-var flycheck-gcc-definitions nil c/c++-gcc
+ "Additional preprocessor definitions for GCC.
+
+The value of this variable is a list of strings, where each
+string is an additional definition to pass to GCC, via the `-D'
+option."
+ :type '(repeat (string :tag "Definition"))
+ :safe #'flycheck-string-list-p
+ :package-version '(flycheck . "0.20"))
+
+(flycheck-def-option-var flycheck-gcc-include-path nil c/c++-gcc
+ "A list of include directories for GCC.
+
+The value of this variable is a list of strings, where each
+string is a directory to add to the include path of gcc.
+Relative paths are relative to the file being checked."
+ :type '(repeat (directory :tag "Include directory"))
+ :safe #'flycheck-string-list-p
+ :package-version '(flycheck . "0.20"))
+
+(flycheck-def-option-var flycheck-gcc-includes nil c/c++-gcc
+ "A list of additional include files for GCC.
+
+The value of this variable is a list of strings, where each
+string is a file to include before syntax checking. Relative
+paths are relative to the file being checked."
+ :type '(repeat (file :tag "Include file"))
+ :safe #'flycheck-string-list-p
+ :package-version '(flycheck . "0.20"))
+
+(flycheck-def-option-var flycheck-gcc-language-standard nil c/c++-gcc
+ "The language standard to use in GCC.
+
+The value of this variable is either a string denoting a language
+standard, or nil, to use the default standard. When non-nil,
+pass the language standard via the `-std' option."
+ :type '(choice (const :tag "Default standard" nil)
+ (string :tag "Language standard"))
+ :safe #'flycheck-string-or-nil-p
+ :package-version '(flycheck . "0.20"))
+(make-variable-buffer-local 'flycheck-gcc-language-standard)
+
+(flycheck-def-option-var flycheck-gcc-no-exceptions nil c/c++-gcc
+ "Whether to disable exceptions in GCC.
+
+When non-nil, disable exceptions for syntax checks, via
+`-fno-exceptions'."
+ :type 'boolean
+ :safe #'booleanp
+ :package-version '(flycheck . "0.20"))
+
+(flycheck-def-option-var flycheck-gcc-no-rtti nil c/c++-gcc
+ "Whether to disable RTTI in GCC.
+
+When non-nil, disable RTTI for syntax checks, via `-fno-rtti'."
+ :type 'boolean
+ :safe #'booleanp
+ :package-version '(flycheck . "0.20"))
+
+(flycheck-def-option-var flycheck-gcc-openmp nil c/c++-gcc
+ "Whether to enable OpenMP in GCC.
+
+When non-nil, enable OpenMP for syntax checkers, via
+`-fopenmp'."
+ :type 'boolean
+ :safe #'booleanp
+ :package-version '(flycheck . "0.21"))
+
+(flycheck-def-option-var flycheck-gcc-pedantic nil c/c++-gcc
+ "Whether to warn about language extensions in GCC.
+
+For ISO C, follows the version specified by any -std option used.
+When non-nil, disable non-ISO extensions to C/C++ via
+`-pedantic'."
+ :type 'boolean
+ :safe #'booleanp
+ :package-version '(flycheck . "0.23"))
+
+(flycheck-def-option-var flycheck-gcc-pedantic-errors nil c/c++-gcc
+ "Whether to error on language extensions in GCC.
+
+For ISO C, follows the version specified by any -std option used.
+When non-nil, disable non-ISO extensions to C/C++ via
+`-pedantic-errors'."
+ :type 'boolean
+ :safe #'booleanp
+ :package-version '(flycheck . "0.23"))
+
+(flycheck-def-option-var flycheck-gcc-warnings '("all" "extra") c/c++-gcc
+ "A list of additional warnings to enable in GCC.
+
+The value of this variable is a list of strings, where each string
+is the name of a warning category to enable. By default, all
+recommended warnings and some extra warnings are enabled (as by
+`-Wall' and `-Wextra' respectively).
+
+Refer to the gcc manual at URL
+`https://gcc.gnu.org/onlinedocs/gcc/' for more information about
+warnings."
+ :type '(choice (const :tag "No additional warnings" nil)
+ (repeat :tag "Additional warnings"
+ (string :tag "Warning name")))
+ :safe #'flycheck-string-list-p
+ :package-version '(flycheck . "0.20"))
+
+(flycheck-define-checker c/c++-gcc
+ "A C/C++ syntax checker using GCC.
+
+Requires GCC 4.4 or newer. See URL `https://gcc.gnu.org/'."
+ :command ("gcc"
+ "-fshow-column"
+ "-iquote" (eval (flycheck-c/c++-quoted-include-directory))
+ (option "-std=" flycheck-gcc-language-standard concat)
+ (option-flag "-pedantic" flycheck-gcc-pedantic)
+ (option-flag "-pedantic-errors" flycheck-gcc-pedantic-errors)
+ (option-flag "-fno-exceptions" flycheck-gcc-no-exceptions)
+ (option-flag "-fno-rtti" flycheck-gcc-no-rtti)
+ (option-flag "-fopenmp" flycheck-gcc-openmp)
+ (option-list "-include" flycheck-gcc-includes)
+ (option-list "-W" flycheck-gcc-warnings concat)
+ (option-list "-D" flycheck-gcc-definitions concat)
+ (option-list "-I" flycheck-gcc-include-path)
+ (eval flycheck-gcc-args)
+ "-x" (eval
+ (pcase major-mode
+ (`c++-mode "c++")
+ (`c-mode "c")))
+ ;; GCC performs full checking only when actually compiling, so
+ ;; `-fsyntax-only' is not enough. Just let it generate assembly
+ ;; code.
+ "-S" "-o" null-device
+ ;; Read from standard input
+ "-")
+ :standard-input t
+ :error-patterns
+ ((info line-start (or "<stdin>" (file-name))
+ ":" line (optional ":" column)
+ ": note: " (message) line-end)
+ (warning line-start (or "<stdin>" (file-name))
+ ":" line (optional ":" column)
+ ": warning: " (message (one-or-more (not (any "\n["))))
+ (optional "[" (id (one-or-more not-newline)) "]") line-end)
+ (error line-start (or "<stdin>" (file-name))
+ ":" line (optional ":" column)
+ ": " (or "fatal error" "error") ": " (message) line-end))
+ :modes (c-mode c++-mode)
+ :next-checkers ((warning . c/c++-cppcheck)))
+
+(flycheck-def-option-var flycheck-cppcheck-checks '("style") c/c++-cppcheck
+ "Enabled checks for Cppcheck.
+
+The value of this variable is a list of strings, where each
+string is the name of an additional check to enable. By default,
+all coding style checks are enabled.
+
+See section \"Enable message\" in the Cppcheck manual at URL
+`http://cppcheck.sourceforge.net/manual.pdf', and the
+documentation of the `--enable' option for more information,
+including a list of supported checks."
+ :type '(repeat :tag "Additional checks"
+ (string :tag "Check name"))
+ :safe #'flycheck-string-list-p
+ :package-version '(flycheck . "0.14"))
+
+(flycheck-def-option-var flycheck-cppcheck-standards nil c/c++-cppcheck
+ "The standards to use in cppcheck.
+
+The value of this variable is either a list of strings denoting
+the standards to use, or nil to pass nothing to cppcheck. When
+non-nil, pass the standards via one or more `--std=' options."
+ :type '(choice (const :tag "Default" nil)
+ (repeat :tag "Custom standards"
+ (string :tag "Standard name")))
+ :safe #'flycheck-string-list-p
+ :package-version '(flycheck . "28"))
+(make-variable-buffer-local 'flycheck-cppcheck-standards)
+
+(flycheck-def-option-var flycheck-cppcheck-suppressions-file nil c/c++-cppcheck
+ "The suppressions file to use in cppcheck.
+
+The value of this variable is a file with the suppressions to
+use, or nil to pass nothing to cppcheck. When non-nil, pass the
+suppressions file via the `--suppressions-list=' option."
+ :type '(choice (const :tag "Default" nil)
+ (file :tag "Suppressions file"))
+ :safe #'flycheck-string-or-nil-p
+ :package-version '(flycheck . "32"))
+(make-variable-buffer-local 'flycheck-cppcheck-suppressions-file)
+
+(flycheck-def-option-var flycheck-cppcheck-suppressions nil c/c++-cppcheck
+ "The suppressions to use in cppcheck.
+
+The value of this variable is either a list of strings denoting
+the suppressions to use, or nil to pass nothing to cppcheck.
+When non-nil, pass the suppressions via one or more `--suppress='
+options."
+ :type '(choice (const :tag "Default" nil)
+ (repeat :tag "Additional suppressions"
+ (string :tag "Suppression")))
+ :safe #'flycheck-string-list-p
+ :package-version '(flycheck . "28"))
+
+(flycheck-def-option-var flycheck-cppcheck-inconclusive nil c/c++-cppcheck
+ "Whether to enable Cppcheck inconclusive checks.
+
+When non-nil, enable Cppcheck inconclusive checks. This allows Cppcheck to
+report warnings it's not certain of, but it may result in false positives.
+
+This will have no effect when using Cppcheck 1.53 and older."
+ :type 'boolean
+ :safe #'booleanp
+ :package-version '(flycheck . "0.19"))
+
+(flycheck-def-option-var flycheck-cppcheck-include-path nil c/c++-cppcheck
+ "A list of include directories for cppcheck.
+
+The value of this variable is a list of strings, where each
+string is a directory to add to the include path of cppcheck.
+Relative paths are relative to the file being checked."
+ :type '(repeat (directory :tag "Include directory"))
+ :safe #'flycheck-string-list-p
+ :package-version '(flycheck . "0.24"))
+
+(flycheck-define-checker c/c++-cppcheck
+ "A C/C++ checker using cppcheck.
+
+See URL `http://cppcheck.sourceforge.net/'."
+ :command ("cppcheck" "--quiet" "--xml-version=2" "--inline-suppr"
+ (option "--enable=" flycheck-cppcheck-checks concat
+ flycheck-option-comma-separated-list)
+ (option-flag "--inconclusive" flycheck-cppcheck-inconclusive)
+ (option-list "-I" flycheck-cppcheck-include-path)
+ (option-list "--std=" flycheck-cppcheck-standards concat)
+ (option-list "--suppress=" flycheck-cppcheck-suppressions concat)
+ (option "--suppressions-list="
+ flycheck-cppcheck-suppressions-file concat)
+ "-x" (eval
+ (pcase major-mode
+ (`c++-mode "c++")
+ (`c-mode "c")))
+ source)
+ :error-parser flycheck-parse-cppcheck
+ :modes (c-mode c++-mode))
+
+(flycheck-define-checker cfengine
+ "A CFEngine syntax checker using cf-promises.
+
+See URL `https://cfengine.com/'."
+ :command ("cf-promises" "-Wall" "-f"
+ ;; We must stay in the same directory to resolve @include
+ source-inplace)
+ :error-patterns
+ ((warning line-start (file-name) ":" line ":" column
+ ": warning: " (message) line-end)
+ (error line-start (file-name) ":" line ":" column
+ ": error: " (message) line-end))
+ :modes (cfengine-mode cfengine3-mode))
+
+(flycheck-def-option-var flycheck-foodcritic-tags nil chef-foodcritic
+ "A list of tags to select for Foodcritic.
+
+The value of this variable is a list of strings where each string
+is a tag expression describing Foodcritic rules to enable or
+disable, via the `--tags' option. To disable a tag, prefix it
+with `~'."
+ :type '(repeat :tag "Tags" (string :tag "Tag expression"))
+ :safe #'flycheck-string-list-p
+ :package-version '(flycheck . "0.23"))
+
+(flycheck-define-checker chef-foodcritic
+ "A Chef cookbooks syntax checker using Foodcritic.
+
+See URL `http://www.foodcritic.io'."
+ ;; Use `source-inplace' to allow resource discovery with relative paths.
+ ;; foodcritic interprets these as relative to the source file, so we need to
+ ;; stay within the source tree. See
+ ;; https://github.com/flycheck/flycheck/pull/556
+ :command ("foodcritic"
+ (option-list "--tags" flycheck-foodcritic-tags)
+ source-inplace)
+ :error-patterns
+ ((error line-start (id (one-or-more alnum)) ": "
+ (message) ": " (file-name) ":" line line-end))
+ :modes (enh-ruby-mode ruby-mode)
+ :predicate
+ (lambda ()
+ (let ((parent-dir (file-name-directory
+ (directory-file-name
+ (expand-file-name default-directory)))))
+ (or
+ ;; Chef CookBook
+ ;; http://docs.opscode.com/chef/knife.html#id38
+ (locate-dominating-file parent-dir "recipes")
+ ;; Knife Solo
+ ;; http://matschaffer.github.io/knife-solo/#label-Init+command
+ (locate-dominating-file parent-dir "cookbooks")))))
+
+(flycheck-define-checker coffee
+ "A CoffeeScript syntax checker using coffee.
+
+See URL `https://coffeescript.org/'."
+ ;; --print suppresses generation of compiled .js files
+ :command ("coffee" "--compile" "--print" "--stdio")
+ :standard-input t
+ :error-patterns
+ ((error line-start "[stdin]:" line ":" column
+ ": error: " (message) line-end))
+ :modes coffee-mode
+ :next-checkers ((warning . coffee-coffeelint)))
+
+(flycheck-def-config-file-var flycheck-coffeelintrc coffee-coffeelint
+ ".coffeelint.json")
+
+(flycheck-define-checker coffee-coffeelint
+ "A CoffeeScript style checker using coffeelint.
+
+See URL `http://www.coffeelint.org/'."
+ :command
+ ("coffeelint"
+ (config-file "--file" flycheck-coffeelintrc)
+ "--stdin" "--reporter" "checkstyle")
+ :standard-input t
+ :error-parser flycheck-parse-checkstyle
+ :error-filter (lambda (errors)
+ (flycheck-remove-error-file-names
+ "stdin" (flycheck-remove-error-ids
+ (flycheck-sanitize-errors errors))))
+ :modes coffee-mode)
+
+(defun flycheck-coq-error-filter (errors)
+ "Sanitize Coq ERRORS and compute end-lines and end-columns."
+ (flycheck-increment-error-columns errors)
+ (dolist (err errors)
+ (setf (flycheck-error-message err)
+ (replace-regexp-in-string (rx (1+ (syntax whitespace)) line-end)
+ "" (flycheck-error-message err)
+ 'fixedcase 'literal))
+ (-when-let* ((end-col (flycheck-error-end-column err)))
+ ;; Coq reports an offset (potentially past eol), not an end column
+ (let* ((line (flycheck-error-line err))
+ (end-lc (save-excursion
+ (flycheck-goto-line line)
+ (goto-char (+ (point) (1- end-col)))
+ (flycheck-line-column-at-point))))
+ (setf (flycheck-error-end-line err) (car end-lc))
+ (setf (flycheck-error-end-column err) (cdr end-lc)))))
+ (flycheck-sanitize-errors errors))
+
+(flycheck-define-checker coq
+ "A Coq syntax checker using the Coq compiler.
+
+See URL `https://coq.inria.fr/'."
+ ;; We use coqtop in batch mode, because coqc is picky about file names.
+ :command ("coqtop" "-batch" "-load-vernac-source" source)
+ :error-patterns
+ ((error line-start "File \"" (file-name) "\", line " line
+ ", characters " column "-" end-column ":\n"
+ (or "Syntax error:" "Error:")
+ ;; Most Coq error messages span multiple lines, and end with a dot.
+ ;; There are simple one-line messages, too, though.
+ (message (or (and (one-or-more (or not-newline "\n")) ".")
+ (one-or-more not-newline)))
+ line-end))
+ :error-filter flycheck-coq-error-filter
+ :modes coq-mode)
+
+(flycheck-define-checker css-csslint
+ "A CSS syntax and style checker using csslint.
+
+See URL `https://github.com/CSSLint/csslint'."
+ :command ("csslint" "--format=checkstyle-xml" source)
+ :error-parser flycheck-parse-checkstyle
+ :error-filter flycheck-dequalify-error-ids
+ :modes css-mode)
+
+(defconst flycheck-stylelint-args '("--formatter" "json")
+ "Common arguments to stylelint invocations.")
+
+(flycheck-def-config-file-var flycheck-stylelintrc
+ (css-stylelint scss-stylelint less-stylelint) nil)
+
+(flycheck-def-option-var flycheck-stylelint-quiet
+ nil (css-stylelint scss-stylelint less-stylelint)
+ "Whether to run stylelint in quiet mode.
+
+When non-nil, enable quiet mode, via `--quiet'."
+ :type 'boolean
+ :safe #'booleanp
+ :package-version '(flycheck . 26))
+
+(defconst flycheck-stylelint-error-re
+ (flycheck-rx-to-string
+ '(: line-start (id (one-or-more word)) ": " (message) line-end)))
+
+(defun flycheck-parse-stylelint (output checker buffer)
+ "Parse stylelint errors from OUTPUT.
+
+CHECKER and BUFFER denoted the CHECKER that returned OUTPUT and
+the BUFFER that was checked respectively.
+
+The CHECKER usually returns the errors as JSON.
+
+If the CHECKER throws an Error it returns an Error message with a stacktrace."
+ (condition-case nil
+ (flycheck-parse-stylelint-json output checker buffer)
+
+ ;; The output could not be parsed as JSON
+ (json-error
+
+ ;; Extract a flycheck error from the output (with a regular expression)
+ ;; For match-string 4/5 see flycheck-rx-message/flycheck-rx-id
+ (when (string-match flycheck-stylelint-error-re output)
+ (list (flycheck-error-new-at
+ 1 nil 'error
+ (match-string 4 output)
+ :id (match-string 5 output)
+ :checker checker
+ :buffer buffer
+ :filename (buffer-file-name buffer)))))))
+
+(defun flycheck-parse-stylelint-json (output checker buffer)
+ "Parse stylelint JSON errors from OUTPUT.
+
+CHECKER and BUFFER denoted the CHECKER that returned OUTPUT and
+the BUFFER that was checked respectively.
+
+See URL `http://stylelint.io/developer-guide/formatters/' for information
+about the JSON format of stylelint."
+ (let ((json-object-type 'plist))
+
+ ;; stylelint returns a vector of result objects
+ ;; Since we only passed one file, the first element is enough
+ (let* ((stylelint-output (elt (json-read-from-string output) 0))
+ (filename (buffer-file-name buffer))
+
+ ;; Turn all deprecations into warnings
+ (deprecations
+ (mapcar (lambda (d)
+ (flycheck-error-new-at
+ 1 nil 'warning
+ (plist-get d :text)
+ :id "Deprecation Warning"
+ :checker checker
+ :buffer buffer
+ :filename filename))
+ (plist-get stylelint-output :deprecations)))
+
+ ;; Turn all invalid options into errors
+ (invalid-options
+ (mapcar (lambda (io)
+ (flycheck-error-new-at
+ 1 nil 'error
+ (plist-get io :text)
+ :id "Invalid Option"
+ :checker checker
+ :buffer buffer
+ :filename filename))
+ (plist-get stylelint-output :invalidOptionWarnings)))
+
+ ;; Read all linting warnings
+ (warnings
+ (mapcar (lambda (w)
+ (flycheck-error-new-at
+ (plist-get w :line) (plist-get w :column)
+ (pcase (plist-get w :severity)
+ (`"error" 'error)
+ (`"warning" 'warning)
+ ;; Default to info for unknown .severity
+ (_ 'info))
+ (plist-get w :text)
+ :id (plist-get w :rule)
+ :checker checker
+ :buffer buffer
+ :filename filename))
+ (plist-get stylelint-output :warnings))))
+
+ ;; Return the combined errors (deprecations, invalid options, warnings)
+ (append deprecations invalid-options warnings))))
+
+(flycheck-define-checker css-stylelint
+ "A CSS syntax and style checker using stylelint.
+
+See URL `http://stylelint.io/'."
+ :command ("stylelint"
+ (eval flycheck-stylelint-args)
+ (option-flag "--quiet" flycheck-stylelint-quiet)
+ (config-file "--config" flycheck-stylelintrc)
+ "--stdin-filename" (eval (or (buffer-file-name) "style.css")))
+ :standard-input t
+ :error-parser flycheck-parse-stylelint
+ :predicate flycheck-buffer-nonempty-p
+ :modes (css-mode))
+
+(flycheck-def-option-var flycheck-cuda-language-standard nil cuda-nvcc
+ "Our CUDA Language Standard."
+ :type '(choice (const :tag "Default standard" nil)
+ (string :tag "Language standard"))
+ :safe #'flycheck-string-or-nil-p
+ :package-version '(flycheck . "32"))
+(make-variable-buffer-local 'flycheck-cuda-language-standard)
+
+(flycheck-def-option-var flycheck-cuda-includes nil cuda-nvcc
+ "Our include directories to pass to nvcc."
+ :type '(repeat (file :tag "Include file"))
+ :safe #'flycheck-string-list-p
+ :package-version '(flycheck . "32"))
+
+(flycheck-def-option-var flycheck-cuda-definitions nil cuda-nvcc
+ "Additional preprocessor definitions for nvcc.
+A list of strings to pass to cuda, a la flycheck-clang"
+ :type '(repeat (string :tag "Definitions"))
+ :safe #'flycheck-string-list-p
+ :package-version '(flycheck . "32"))
+
+(flycheck-def-option-var flycheck-cuda-include-path nil cuda-nvcc
+ "A list of include directories for nvcc."
+ :type '(repeat (directory :tag "Include directory"))
+ :safe #'flycheck-string-list-p
+ :package-version '(flycheck . "32"))
+
+(flycheck-define-checker cuda-nvcc
+ "A CUDA C/C++ syntax checker using nvcc.
+
+See URL `https://developer.nvidia.com/cuda-llvm-compiler'."
+ :command ("nvcc"
+ "-c" ;; Compile Only
+ "--output-file" "/dev/null" ;; avoid creating output .o
+ "--x=cu" ;; explicitly specify it's a CUDA language file
+ (option "-std=" flycheck-cuda-language-standard concat)
+ (option-list "-include" flycheck-cuda-includes)
+ (option-list "-D" flycheck-cuda-definitions concat)
+ (option-list "-I" flycheck-cuda-include-path)
+ source)
+ :error-patterns
+ ((error line-start
+ (message "In file included from")
+ " " (or "<stdin>" (file-name))
+ ":" line ":" line-end)
+ (error line-start (or "<stdin>" (file-name))
+ "(" line "): error: " (message) line-end)
+ (error line-start (or "<stdin>" (file-name))
+ ":" line ":" column
+ ": fatal error: " (optional (message)) line-end)
+ (warning line-start (or "<stdin>" (file-name))
+ "(" line "): warning: " (message) line-end))
+ :modes cuda-mode)
+
+
+(flycheck-def-option-var flycheck-cwl-schema-path nil cwl
+ "A path for the schema file for Common Workflow Language.
+
+The value of this variable is a string that denotes a path for
+the schema file of Common Workflow Language."
+ :type '(choice (const :tag "None" nil)
+ (file :tag "Schema file"))
+ :safe #'flycheck-string-or-nil-p)
+
+(flycheck-define-checker cwl
+ "A CWL syntax checker using Schema Salad validator.
+
+Requires Schema Salad 2.6.20171101113912 or newer.
+See URL `https://www.commonwl.org/v1.0/SchemaSalad.html'."
+ :command ("schema-salad-tool"
+ "--quiet"
+ "--print-oneline"
+ (eval flycheck-cwl-schema-path)
+ source-inplace)
+ :error-patterns
+ ((error line-start
+ (file-name) ":" line ":" column ":" (zero-or-more blank)
+ (message (one-or-more not-newline))
+ line-end))
+ :modes cwl-mode)
+
+(defconst flycheck-d-module-re
+ (rx "module" (one-or-more (syntax whitespace))
+ (group (one-or-more (not (syntax whitespace))))
+ (zero-or-more (syntax whitespace))
+ ";")
+ "Regular expression to match a D module declaration.")
+
+(defun flycheck-d-base-directory ()
+ "Get the relative base directory path for this module."
+ (let* ((file-name (buffer-file-name))
+ (module-file (if (and file-name
+ (string= (file-name-nondirectory file-name)
+ "package.d"))
+ (directory-file-name (file-name-directory file-name))
+ file-name)))
+ (flycheck-module-root-directory
+ (flycheck-find-in-buffer flycheck-d-module-re)
+ module-file)))
+
+(flycheck-def-option-var flycheck-dmd-include-path nil d-dmd
+ "A list of include directories for dmd.
+
+The value of this variable is a list of strings, where each
+string is a directory to add to the include path of dmd.
+Relative paths are relative to the file being checked."
+ :type '(repeat (directory :tag "Include directory"))
+ :safe #'flycheck-string-list-p
+ :package-version '(flycheck . "0.18"))
+
+(flycheck-def-args-var flycheck-dmd-args d-dmd
+ :package-version '(flycheck . "0.24"))
+
+(flycheck-define-checker d-dmd
+ "A D syntax checker using the DMD compiler.
+
+Requires DMD 2.066 or newer. See URL `https://dlang.org/'."
+ :command ("dmd"
+ "-debug" ; Compile in debug mode
+ "-o-" ; Don't generate an object file
+ "-vcolumns" ; Add columns in output
+ "-wi" ; Compilation will continue even if there are warnings
+ (eval (concat "-I" (flycheck-d-base-directory)))
+ (option-list "-I" flycheck-dmd-include-path concat)
+ (eval flycheck-dmd-args)
+ (source ".d"))
+ :error-patterns
+ ((error line-start
+ (file-name) "(" line "," column "): Error: " (message)
+ line-end)
+ (warning line-start (file-name) "(" line "," column "): "
+ (or "Warning" "Deprecation") ": " (message) line-end)
+ (info line-start (file-name) "(" line "," column "): "
+ (one-or-more " ") (message) line-end))
+ :modes d-mode)
+
+(flycheck-define-checker dockerfile-hadolint
+ "A Dockerfile syntax checker using the hadolint.
+
+See URL `http://github.com/hadolint/hadolint/'."
+ :command ("hadolint" "--no-color" "-")
+ :standard-input t
+ :error-patterns
+ ((error line-start
+ (file-name) ":" line " " (id (one-or-more alnum)) " error: " (message)
+ line-end)
+ (warning line-start
+ (file-name) ":" line " " (id (one-or-more alnum))
+ " warning: " (message) line-end)
+ (info line-start
+ (file-name) ":" line " " (id (one-or-more alnum)) " info: " (message)
+ line-end)
+ (error line-start
+ (file-name) ":" line ":" column " " (message)
+ line-end))
+ :error-filter
+ (lambda (errors)
+ (flycheck-sanitize-errors
+ (flycheck-remove-error-file-names "/dev/stdin" errors)))
+ :modes dockerfile-mode)
+
+(defun flycheck-credo--working-directory (&rest _ignored)
+ "Check if `credo' is installed as dependency in the application."
+ (and buffer-file-name
+ (locate-dominating-file buffer-file-name "deps/credo")))
+
+(flycheck-def-option-var flycheck-elixir-credo-strict nil elixir-credo
+ "Enable strict mode in `credo'.
+
+When non-nil, pass the `--strict' flag to credo."
+ :type 'boolean
+ :safe #'booleanp
+ :package-version '(flycheck . "32"))
+
+(flycheck-define-checker elixir-credo
+ "An Elixir checker for static code analysis using Credo.
+
+See `http://credo-ci.org/'."
+ :command ("mix" "credo"
+ (option-flag "--strict" flycheck-elixir-credo-strict)
+ "--format" "flycheck"
+ "--read-from-stdin" source-original)
+ :standard-input t
+ :working-directory flycheck-credo--working-directory
+ :enabled flycheck-credo--working-directory
+ :error-patterns
+ ((info line-start
+ (file-name) ":" line (optional ":" column) ": "
+ (or "F" "R" "C") ": " (message) line-end)
+ (warning line-start
+ (file-name) ":" line (optional ":" column) ": "
+ (or "D" "W") ": " (message) line-end))
+ :modes elixir-mode)
+
+(defconst flycheck-this-emacs-executable
+ (concat invocation-directory invocation-name)
+ "The path to the currently running Emacs executable.")
+
+(defconst flycheck-emacs-args '("-Q" "--batch")
+ "Common arguments to Emacs invocations.")
+
+(defmacro flycheck-prepare-emacs-lisp-form (&rest body)
+ "Prepare BODY for use as check form in a subprocess."
+ (declare (indent 0))
+ `(flycheck-sexp-to-string
+ '(progn
+ (defvar jka-compr-inhibit)
+ (unwind-protect
+ ;; Flycheck inhibits compression of temporary files, thus we
+ ;; must not attempt to decompress.
+ (let ((jka-compr-inhibit t))
+ ;; Strip option-argument separator from arguments, if present
+ (when (equal (car command-line-args-left) "--")
+ (setq command-line-args-left (cdr command-line-args-left)))
+ ,@body)
+ ;; Prevent Emacs from processing the arguments on its own, see
+ ;; https://github.com/flycheck/flycheck/issues/319
+ (setq command-line-args-left nil)))))
+
+(defun flycheck-emacs-lisp-bytecomp-config-form ()
+ "Prepare an Emacs Lisp form to set byte-compiler variables."
+ (flycheck-sexp-to-string
+ `(progn
+ (require 'bytecomp)
+ (setq byte-compile-root-dir
+ ,(if buffer-file-name
+ (file-name-directory buffer-file-name)
+ default-directory)))))
+
+(defconst flycheck-emacs-lisp-check-form
+ (flycheck-prepare-emacs-lisp-form
+ ;; Keep track of the generated bytecode files, to delete them after byte
+ ;; compilation.
+ (require 'bytecomp)
+ (defvar flycheck-byte-compiled-files nil)
+ (let ((byte-compile-dest-file-function
+ (lambda (source)
+ (let ((temp-file (make-temp-file (file-name-nondirectory source))))
+ (push temp-file flycheck-byte-compiled-files)
+ temp-file))))
+ (unwind-protect
+ (byte-compile-file (car command-line-args-left))
+ (mapc (lambda (f) (ignore-errors (delete-file f)))
+ flycheck-byte-compiled-files))
+ (when (bound-and-true-p flycheck-emacs-lisp-check-declare)
+ (check-declare-file (car command-line-args-left))))))
+
+(flycheck-def-option-var flycheck-emacs-lisp-load-path nil emacs-lisp
+ "Load path to use in the Emacs Lisp syntax checker.
+
+When set to `inherit', use the `load-path' of the current Emacs
+session during syntax checking.
+
+When set to a list of strings, add each directory in this list to
+the `load-path' before invoking the byte compiler. Relative
+paths in this list are expanded against the `default-directory'
+of the buffer to check.
+
+When nil, do not explicitly set the `load-path' during syntax
+checking. The syntax check only uses the built-in `load-path' of
+Emacs in this case.
+
+Note that changing this variable can lead to wrong results of the
+syntax check, e.g. if an unexpected version of a required library
+is used."
+ :type '(choice (const :tag "Inherit current `load-path'" inherit)
+ (repeat :tag "Load path" directory))
+ :risky t
+ :package-version '(flycheck . "0.14"))
+
+(flycheck-def-option-var flycheck-emacs-lisp-initialize-packages
+ 'auto emacs-lisp
+ "Whether to initialize packages in the Emacs Lisp syntax checker.
+
+When nil, never initialize packages. When `auto', initialize
+packages only when checking `user-init-file' or files from
+`user-emacs-directory'. For any other non-nil value, always
+initialize packages.
+
+When initializing packages is enabled the `emacs-lisp' syntax
+checker calls `package-initialize' before byte-compiling the file
+to be checked. It also sets `package-user-dir' according to
+`flycheck-emacs-lisp-package-user-dir'."
+ :type '(choice (const :tag "Do not initialize packages" nil)
+ (const :tag "Initialize packages for configuration only" auto)
+ (const :tag "Always initialize packages" t))
+ :risky t
+ :package-version '(flycheck . "0.14"))
+
+(defconst flycheck-emacs-lisp-package-initialize-form
+ (flycheck-sexp-to-string
+ '(with-demoted-errors "Error during package initialization: %S"
+ (package-initialize)))
+ "Form used to initialize packages.")
+
+(defun flycheck-option-emacs-lisp-package-initialize (value)
+ "Option VALUE filter for `flycheck-emacs-lisp-initialize-packages'."
+ (let ((shall-initialize
+ (if (eq value 'auto)
+ (or (flycheck-in-user-emacs-directory-p
+ (or buffer-file-name default-directory))
+ ;; `user-init-file' is nil in non-interactive sessions. Now,
+ ;; no user would possibly use Flycheck in a non-interactive
+ ;; session, but our unit tests run non-interactively, so we
+ ;; have to handle this case anyway
+ (and user-init-file buffer-file-name
+ (flycheck-same-files-p buffer-file-name user-init-file)))
+ value)))
+ (when shall-initialize
+ ;; If packages shall be initialized, return the corresponding form,
+ ;; otherwise make Flycheck ignore the option by returning nil.
+ flycheck-emacs-lisp-package-initialize-form)))
+
+(flycheck-def-option-var flycheck-emacs-lisp-package-user-dir nil emacs-lisp
+ "Package directory for the Emacs Lisp syntax checker.
+
+If set to a string set `package-user-dir' to the value of this
+variable before initializing packages. If set to nil just inherit
+the value of `package-user-dir' from the running Emacs session.
+
+This variable has no effect, if
+`flycheck-emacs-lisp-initialize-packages' is nil."
+ :type '(choice (const :tag "Default package directory" nil)
+ (directory :tag "Custom package directory"))
+ :risky t
+ :package-version '(flycheck . "0.14"))
+
+(defun flycheck-option-emacs-lisp-package-user-dir (value)
+ "Option VALUE filter for `flycheck-emacs-lisp-package-user-dir'."
+ ;; Inherit the package directory from our Emacs session
+ (let ((value (or value (bound-and-true-p package-user-dir))))
+ (when value
+ (flycheck-sexp-to-string `(setq package-user-dir ,value)))))
+
+(flycheck-def-option-var flycheck-emacs-lisp-check-declare nil emacs-lisp
+ "If non-nil, check ‘declare-function’ forms using ‘check-declare-file’."
+ :type '(choice (const :tag "Do not check declare forms" nil)
+ (const :tag "Check declare forms" t))
+ :risky t
+ :package-version '(flycheck . "31"))
+
+(defun flycheck-option-emacs-lisp-check-declare (value)
+ "Option VALUE filter for `flycheck-emacs-lisp-check-declare'."
+ (when value
+ (flycheck-sexp-to-string
+ `(progn
+ (defvar flycheck-emacs-lisp-check-declare)
+ (setq flycheck-emacs-lisp-check-declare ,value)))))
+
+(defun flycheck--emacs-lisp-enabled-p ()
+ "Check whether to enable Emacs Lisp checker in the current buffer."
+ (not
+ (or
+ ;; Do not check buffers used for autoloads generation during package
+ ;; installation. These buffers are too short-lived for being checked, and
+ ;; doing so causes spurious errors. See
+ ;; https://github.com/flycheck/flycheck/issues/45 and
+ ;; https://github.com/bbatsov/prelude/issues/248. We must also not check
+ ;; compilation buffers, but as these are ephemeral, Flycheck won't check
+ ;; them anyway.
+ (flycheck-autoloads-file-p)
+ ;; Cask/Carton and dir-locals files contain data, not code, and don't need
+ ;; to follow Checkdoc conventions either.
+ (and (buffer-file-name)
+ (member (file-name-nondirectory (buffer-file-name))
+ '("Cask" "Carton" ".dir-locals.el" ".dir-locals-2.el"))))))
+
+(defun flycheck--emacs-lisp-checkdoc-enabled-p ()
+ "Check whether to enable Emacs Lisp Checkdoc in the current buffer."
+ (and (flycheck--emacs-lisp-enabled-p)
+ ;; These files are valid Lisp, but don't contain "standard" comments.
+ (not (member (buffer-file-name) '("Eldev" "Eldev-local")))))
+
+(flycheck-define-checker emacs-lisp
+ "An Emacs Lisp syntax checker using the Emacs Lisp Byte compiler.
+
+See Info Node `(elisp)Byte Compilation'."
+ :command ("emacs" (eval flycheck-emacs-args)
+ (eval
+ (let ((path (pcase flycheck-emacs-lisp-load-path
+ (`inherit load-path)
+ (p (seq-map #'expand-file-name p)))))
+ (flycheck-prepend-with-option "--directory" path)))
+ (option "--eval" flycheck-emacs-lisp-package-user-dir nil
+ flycheck-option-emacs-lisp-package-user-dir)
+ (option "--eval" flycheck-emacs-lisp-initialize-packages nil
+ flycheck-option-emacs-lisp-package-initialize)
+ (option "--eval" flycheck-emacs-lisp-check-declare nil
+ flycheck-option-emacs-lisp-check-declare)
+ "--eval" (eval (flycheck-emacs-lisp-bytecomp-config-form))
+ "--eval" (eval flycheck-emacs-lisp-check-form)
+ "--"
+ source-inplace)
+ :error-patterns
+ ((error line-start (file-name) ":" line ":" column ":"
+ (zero-or-more whitespace) "Error:" (zero-or-more whitespace)
+ (message (zero-or-more not-newline)
+ (zero-or-more "\n " (zero-or-more not-newline)))
+ line-end)
+ (warning line-start (file-name) ":" line ":" column ":"
+ (zero-or-more whitespace) "Warning:" (zero-or-more whitespace)
+ (message (zero-or-more not-newline)
+ (zero-or-more "\n " (zero-or-more not-newline)))
+ line-end)
+ (warning line-start (file-name) ":" line (optional ":" column) ":"
+ (zero-or-more whitespace) "Warning (check-declare): said\n"
+ (message (zero-or-more " " (zero-or-more not-newline))
+ (zero-or-more "\n " (zero-or-more not-newline)))
+ line-end)
+ ;; The following is for Emacs 24 ‘check-declare-file’, which uses a
+ ;; less informative format.
+ (warning line-start "Warning (check-declare): " (file-name) " said "
+ (message (zero-or-more not-newline))
+ line-end))
+ :error-filter
+ (lambda (errors)
+ (flycheck-fill-empty-line-numbers
+ (flycheck-collapse-error-message-whitespace
+ (flycheck-sanitize-errors errors))))
+ :modes (emacs-lisp-mode lisp-interaction-mode)
+ :enabled flycheck--emacs-lisp-enabled-p
+ :predicate
+ (lambda ()
+ ;; Do not check buffers that should not be byte-compiled. The checker
+ ;; process will refuse to compile these, which would confuse Flycheck
+ (not (bound-and-true-p no-byte-compile)))
+ :next-checkers (emacs-lisp-checkdoc))
+
+(defconst flycheck-emacs-lisp-checkdoc-form
+ (flycheck-prepare-emacs-lisp-form
+ (unless (require 'elisp-mode nil 'no-error)
+ ;; TODO: Fallback for Emacs 24, remove when dropping support for 24
+ (require 'lisp-mode))
+ (require 'checkdoc)
+
+ (let ((source (car command-line-args-left))
+ ;; Remember the default directory of the process
+ (process-default-directory default-directory))
+ ;; Note that we deliberately use our custom approach even despite of
+ ;; `checkdoc-file' which was added to Emacs 25.1. While it's conceptually
+ ;; the better thing, its implementation has too many flaws to be of use
+ ;; for us.
+ (with-temp-buffer
+ (insert-file-contents source 'visit)
+ (setq buffer-file-name source)
+ ;; And change back to the process default directory to make file-name
+ ;; back-substutition work
+ (setq default-directory process-default-directory)
+ (with-demoted-errors "Error in checkdoc: %S"
+ ;; Checkdoc needs the Emacs Lisp syntax table and comment syntax to
+ ;; parse sexps and identify docstrings correctly; see
+ ;; https://github.com/flycheck/flycheck/issues/833
+ (delay-mode-hooks (emacs-lisp-mode))
+ (setq delayed-mode-hooks nil)
+ (checkdoc-current-buffer t)
+ (with-current-buffer checkdoc-diagnostic-buffer
+ (princ (buffer-substring-no-properties (point-min) (point-max)))
+ (kill-buffer)))))))
+
+(defconst flycheck-emacs-lisp-checkdoc-variables
+ '(checkdoc-symbol-words
+ checkdoc-arguments-in-order-flag
+ checkdoc-force-history-flag
+ checkdoc-permit-comma-termination-flag
+ checkdoc-force-docstrings-flag
+ checkdoc-package-keywords-flag
+ checkdoc-spellcheck-documentation-flag
+ checkdoc-verb-check-experimental-flag
+ checkdoc-max-keyref-before-warn
+ sentence-end-double-space)
+ "Variables inherited by the checkdoc subprocess.")
+
+(defun flycheck-emacs-lisp-checkdoc-variables-form ()
+ "Make a sexp to pass relevant variables to a checkdoc subprocess.
+
+Variables are taken from `flycheck-emacs-lisp-checkdoc-variables'."
+ `(progn
+ ,@(seq-map (lambda (opt) `(setq-default ,opt ',(symbol-value opt)))
+ (seq-filter #'boundp flycheck-emacs-lisp-checkdoc-variables))))
+
+(flycheck-define-checker emacs-lisp-checkdoc
+ "An Emacs Lisp style checker using CheckDoc.
+
+The checker runs `checkdoc-current-buffer'."
+ :command ("emacs" (eval flycheck-emacs-args)
+ "--eval" (eval (flycheck-sexp-to-string
+ (flycheck-emacs-lisp-checkdoc-variables-form)))
+ "--eval" (eval flycheck-emacs-lisp-checkdoc-form)
+ "--" source)
+ :error-patterns
+ ((info line-start (file-name) ":" line ": " (message) line-end))
+ :modes (emacs-lisp-mode)
+ :enabled flycheck--emacs-lisp-checkdoc-enabled-p)
+
+(dolist (checker '(emacs-lisp emacs-lisp-checkdoc))
+ (setf (car (flycheck-checker-get checker 'command))
+ flycheck-this-emacs-executable))
+
+(defun flycheck-ember-template--check-for-config (&rest _ignored)
+ "Check the required config file is available up the file system."
+ (and buffer-file-name
+ (locate-dominating-file buffer-file-name ".template-lintrc.js")))
+
+(defun flycheck-ember-template--parse-error (output checker buffer)
+ "Parse Ember-template-lint errors/warnings from JSON OUTPUT.
+CHECKER and BUFFER denote the CHECKER that returned OUTPUT and
+the BUFFER that was checked respectively."
+ (mapcar (lambda (err)
+ (let-alist err
+ (flycheck-error-new-at
+ .line
+ .column
+ (pcase .severity
+ (2 'error)
+ (1 'warning)
+ (_ 'warning))
+ .message
+ :id .rule
+ :checker checker
+ :buffer buffer
+ :filename (buffer-file-name buffer))))
+ (cdr (car (car (flycheck-parse-json output))))))
+
+(flycheck-def-config-file-var flycheck-ember-template-lintrc
+ ember-template
+ ".template-lintrc.js")
+
+(flycheck-define-checker ember-template
+ "An Ember template checker using ember-template-lint."
+ :command ("ember-template-lint"
+ (config-file "--config-path" flycheck-ember-template-lintrc)
+ "--filename" source-original
+ "--json")
+ :standard-input t
+ :error-parser flycheck-ember-template--parse-error
+ :modes web-mode
+ :enabled flycheck-ember-template--check-for-config
+ :working-directory flycheck-ember-template--check-for-config)
+
+(flycheck-def-option-var flycheck-erlang-include-path nil erlang
+ "A list of include directories for Erlang.
+
+The value of this variable is a list of strings, where each
+string is a directory to add to the include path of erlc.
+Relative paths are relative to the file being checked."
+ :type '(repeat (directory :tag "Include directory"))
+ :safe #'flycheck-string-list-p
+ :package-version '(flycheck . "0.24"))
+
+(flycheck-def-option-var flycheck-erlang-library-path nil erlang
+ "A list of library directories for Erlang.
+
+The value of this variable is a list of strings, where each
+string is a directory to add to the library path of erlc.
+Relative paths are relative to the file being checked."
+ :type '(repeat (directory :tag "Library directory"))
+ :safe #'flycheck-string-list-p
+ :package-version '(flycheck . "0.24"))
+
+(flycheck-define-checker erlang
+ "An Erlang syntax checker using the Erlang interpreter.
+
+See URL `http://www.erlang.org/'."
+ :command ("erlc"
+ "-o" temporary-directory
+ (option-list "-I" flycheck-erlang-include-path)
+ (option-list "-pa" flycheck-erlang-library-path)
+ "-Wall"
+ source)
+ :error-patterns
+ ((warning line-start (file-name) ":" line ": Warning:" (message) line-end)
+ (error line-start (file-name) ":" line ": " (message) line-end))
+ :modes erlang-mode
+ :enabled (lambda () (string-suffix-p ".erl" (buffer-file-name))))
+
+(defun flycheck--contains-rebar-config (dir-name)
+ "Return DIR-NAME if rebar config file exists in DIR-NAME, nil otherwise."
+ (when (or (file-exists-p (expand-file-name "rebar.config" dir-name))
+ (file-exists-p (expand-file-name "rebar.config.script" dir-name)))
+ dir-name))
+
+(defun flycheck--locate-rebar3-project-root
+ (file-name &optional prev-file-name acc)
+ "Find the top-most rebar project root for source FILE-NAME.
+
+A project root directory is any directory containing a
+rebar.config file. Find the top-most directory to move out of any
+nested dependencies.
+
+FILE-NAME is a source file for which to find the project.
+
+PREV-FILE-NAME helps us prevent infinite looping
+
+ACC is an accumulator that keeps the list of results, the first
+non-nil of which will be our project root.
+
+Return the absolute path to the directory"
+ (if (string= file-name prev-file-name)
+ (car (remove nil acc))
+ (let ((current-dir (file-name-directory file-name)))
+ (flycheck--locate-rebar3-project-root
+ (directory-file-name current-dir)
+ file-name
+ (cons (flycheck--contains-rebar-config current-dir) acc)))))
+
+(defun flycheck-rebar3-project-root (&optional _checker)
+ "Return directory where rebar.config is located."
+ (flycheck--locate-rebar3-project-root buffer-file-name))
+
+(flycheck-def-option-var flycheck-erlang-rebar3-profile nil erlang-rebar3
+ "The rebar3 profile to use.
+
+The profile used when compiling, if VALUE is nil \"test\" will be used
+when the file is located in test directory, otherwise \"default\" will be
+used as profile."
+ :type '(choice (const :tag "Automatic" nil)
+ (string :tag "Profile"))
+ :safe #'flycheck-string-or-nil-p
+ :package-version '(flycheck . "32"))
+
+(defun flycheck-erlang-rebar3-get-profile ()
+ "Return rebar3 profile.
+
+Use flycheck-erlang-rebar3-profile if set, otherwise use test or eqc profile if
+directory name is \"test\" or \"eqc\", or else \"default\"."
+ (or
+ flycheck-erlang-rebar3-profile
+ (with-no-warnings
+ ;; `seq-contains-p' is only in seq >= 2.21
+ (seq-contains '("test" "eqc")
+ (and buffer-file-name
+ (file-name-base
+ (directory-file-name
+ (file-name-directory buffer-file-name))))))
+ "default"))
+
+(flycheck-define-checker erlang-rebar3
+ "An Erlang syntax checker using the rebar3 build tool."
+ :command ("rebar3" "as" (eval (flycheck-erlang-rebar3-get-profile)) "compile")
+ :error-parser flycheck-parse-with-patterns-without-color
+ :error-patterns
+ ((warning line-start
+ (file-name) ":" line ": Warning:" (message) line-end)
+ (error line-start
+ (file-name) ":" line ": " (message) line-end))
+ :modes erlang-mode
+ :enabled flycheck-rebar3-project-root
+ :predicate flycheck-buffer-saved-p
+ :working-directory flycheck-rebar3-project-root)
+
+(flycheck-define-checker eruby-erubis
+ "An eRuby syntax checker using the `erubis' command.
+
+See URL `http://www.kuwata-lab.com/erubis/'."
+ :command ("erubis" "-z" source)
+ :error-patterns
+ ((error line-start (file-name) ":" line ": " (message) line-end))
+ :modes (html-erb-mode rhtml-mode)
+ :next-checkers ((warning . eruby-ruumba)))
+
+(flycheck-def-config-file-var flycheck-ruumbarc eruby-ruumba ".ruumba.yml")
+
+(flycheck-def-option-var flycheck-ruumba-lint-only nil eruby-ruumba
+ "Whether to only report code issues in Ruumba.
+
+When non-nil, only report code issues in Ruumba, via `--lint'.
+Otherwise report style issues as well."
+ :safe #'booleanp
+ :type 'boolean
+ :package-version '(flycheck . "32"))
+
+(flycheck-define-checker eruby-ruumba
+ "An eRuby syntax and style checker using the Ruumba tool.
+
+You need at least Ruumba 0.1.7 for this syntax checker.
+
+See URL `https://github.com/ericqweinstein/ruumba'."
+ :command ("ruumba"
+ "--display-cop-names"
+ "--force-exclusion"
+ "--format" "emacs"
+ "--cache" "false"
+ (config-file "--config" flycheck-ruumbarc)
+ (option-flag "--lint" flycheck-ruumba-lint-only)
+ ;; Ruumba takes the original file name as argument when reading
+ ;; from standard input
+ "--stdin" source-original)
+ :standard-input t
+ :working-directory flycheck-ruby--find-project-root
+ :error-patterns
+ ((info line-start (file-name) ":" line ":" column ": C: "
+ (optional (id (one-or-more (not (any ":")))) ": ") (message) line-end)
+ (warning line-start (file-name) ":" line ":" column ": W: "
+ (optional (id (one-or-more (not (any ":")))) ": ") (message)
+ line-end)
+ (error line-start (file-name) ":" line ":" column ": " (or "E" "F") ": "
+ (optional (id (one-or-more (not (any ":")))) ": ") (message)
+ line-end))
+ :modes (html-erb-mode rhtml-mode))
+
+(flycheck-def-args-var flycheck-gfortran-args fortran-gfortran
+ :package-version '(flycheck . "0.22"))
+
+(flycheck-def-option-var flycheck-gfortran-include-path nil fortran-gfortran
+ "A list of include directories for GCC Fortran.
+
+The value of this variable is a list of strings, where each
+string is a directory to add to the include path of gcc.
+Relative paths are relative to the file being checked."
+ :type '(repeat (directory :tag "Include directory"))
+ :safe #'flycheck-string-list-p
+ :package-version '(flycheck . "0.20"))
+
+(flycheck-def-option-var flycheck-gfortran-language-standard "f95"
+ fortran-gfortran
+ "The language standard to use in GFortran.
+
+The value of this variable is either a string denoting a language
+standard, or nil, to use the default standard. When non-nil,
+pass the language standard via the `-std' option."
+ :type '(choice (const :tag "Default standard" nil)
+ (string :tag "Language standard"))
+ :package-version '(flycheck . "0.20"))
+
+(flycheck-def-option-var flycheck-gfortran-layout nil fortran-gfortran
+ "The source code layout to use in GFortran.
+
+The value of this variable is one of the following symbols:
+
+nil
+ Let gfortran determine the layout from the extension
+
+`free'
+ Use free form layout
+
+
+`fixed'
+ Use fixed form layout
+
+In any other case, an error is signaled."
+ :type '(choice (const :tag "Guess layout from extension" nil)
+ (const :tag "Free form layout" free)
+ (const :tag "Fixed form layout" fixed))
+ :safe (lambda (value) (or (not value) (memq value '(free fixed))))
+ :package-version '(flycheck . "0.20"))
+
+(defun flycheck-option-gfortran-layout (value)
+ "Option VALUE filter for `flycheck-gfortran-layout'."
+ (pcase value
+ (`nil nil)
+ (`free "free-form")
+ (`fixed "fixed-form")
+ (_ (error "Invalid value for flycheck-gfortran-layout: %S" value))))
+
+(flycheck-def-option-var flycheck-gfortran-warnings '("all" "extra")
+ fortran-gfortran
+ "A list of warnings for GCC Fortran.
+
+The value of this variable is a list of strings, where each string
+is the name of a warning category to enable. By default, all
+recommended warnings and some extra warnings are enabled (as by
+`-Wall' and `-Wextra' respectively).
+
+Refer to the gfortran manual at URL
+`https://gcc.gnu.org/onlinedocs/gfortran/' for more information
+about warnings"
+ :type '(choice (const :tag "No additional warnings" nil)
+ (repeat :tag "Additional warnings"
+ (string :tag "Warning name")))
+ :safe #'flycheck-string-list-p
+ :package-version '(flycheck . "0.20"))
+
+(flycheck-define-checker fortran-gfortran
+ "An Fortran syntax checker using GCC.
+
+Uses GCC's Fortran compiler gfortran. See URL
+`https://gcc.gnu.org/onlinedocs/gfortran/'."
+ :command ("gfortran"
+ "-fsyntax-only"
+ "-fshow-column"
+ ;; Do not visually indicate the source location
+ "-fno-diagnostics-show-caret"
+ ;; Do not show the corresponding warning group
+ "-fno-diagnostics-show-option"
+ ;; Fortran has similar include processing as C/C++
+ "-iquote" (eval (flycheck-c/c++-quoted-include-directory))
+ (option "-std=" flycheck-gfortran-language-standard concat)
+ (option "-f" flycheck-gfortran-layout concat
+ flycheck-option-gfortran-layout)
+ (option-list "-W" flycheck-gfortran-warnings concat)
+ (option-list "-I" flycheck-gfortran-include-path concat)
+ (eval flycheck-gfortran-args)
+ source)
+ :error-patterns
+ ((error line-start (file-name) ":" line (or ":" ".") column (or ": " ":\n")
+ (or (= 3 (zero-or-more not-newline) "\n") "")
+ (or "Error" "Fatal Error") ": "
+ (message) line-end)
+ (warning line-start (file-name) ":" line (or ":" ".") column (or ": " ":\n")
+ (or (= 3 (zero-or-more not-newline) "\n") "")
+ "Warning: " (message) line-end))
+ :modes (fortran-mode f90-mode))
+
+(flycheck-define-checker go-gofmt
+ "A Go syntax and style checker using the gofmt utility.
+
+See URL `https://golang.org/cmd/gofmt/'."
+ :command ("gofmt")
+ :standard-input t
+ :error-patterns
+ ((error line-start "<standard input>:" line ":" column ": "
+ (message) line-end))
+ :modes go-mode
+ :next-checkers ((warning . go-golint)
+ ;; Fall back, if go-golint doesn't exist
+ (warning . go-vet)
+ ;; Fall back, if go-vet doesn't exist
+ (warning . go-build) (warning . go-test)
+ (warning . go-errcheck)
+ (warning . go-unconvert)
+ (warning . go-staticcheck)))
+
+(flycheck-define-checker go-golint
+ "A Go style checker using Golint.
+
+See URL `https://github.com/golang/lint'."
+ :command ("golint" source)
+ :error-patterns
+ ((warning line-start (file-name) ":" line ":" column ": " (message) line-end))
+ :modes go-mode
+ :next-checkers (go-vet
+ ;; Fall back, if go-vet doesn't exist
+ go-build go-test go-errcheck go-unconvert))
+
+(flycheck-def-option-var flycheck-go-vet-print-functions nil go-vet
+ "A list of print-like functions for `go vet'.
+
+Go vet will check these functions for format string problems and
+issues, such as a mismatch between the number of formats used,
+and the number of arguments given.
+
+Each entry is in the form Name:N where N is the zero-based
+argument position of the first argument involved in the print:
+either the format or the first print argument for non-formatted
+prints. For example, if you have Warn and Warnf functions that
+take an io.Writer as their first argument, like Fprintf,
+-printfuncs=Warn:1,Warnf:1 "
+ :type '(repeat :tag "print-like functions"
+ (string :tag "function"))
+ :safe #'flycheck-string-list-p)
+
+(flycheck-define-checker go-vet
+ "A Go syntax checker using the `go vet' command.
+
+See URL `https://golang.org/cmd/go/' and URL
+`https://golang.org/cmd/vet/'."
+ :command ("go" "vet"
+ (option "-printf.funcs=" flycheck-go-vet-print-functions concat
+ flycheck-option-comma-separated-list)
+ (source ".go"))
+ :error-patterns
+ ((warning line-start (file-name) ":" line ": " (message) line-end))
+ :modes go-mode
+ :next-checkers (go-build
+ go-test
+ ;; Fall back if `go build' or `go test' can be used
+ go-errcheck
+ go-unconvert
+ go-staticcheck)
+ :verify (lambda (_)
+ (let* ((go (flycheck-checker-executable 'go-vet))
+ (have-vet (member "vet" (ignore-errors
+ (process-lines go "tool")))))
+ (list
+ (flycheck-verification-result-new
+ :label "go tool vet"
+ :message (if have-vet "present" "missing")
+ :face (if have-vet 'success '(bold error)))))))
+
+(flycheck-def-option-var flycheck-go-build-install-deps nil (go-build go-test)
+ "Whether to install dependencies in `go build' and `go test'.
+
+If non-nil automatically install dependencies with `go build'
+while syntax checking."
+ :type 'boolean
+ :safe #'booleanp
+ :package-version '(flycheck . "0.25"))
+
+(flycheck-def-option-var flycheck-go-build-tags nil
+ (go-build go-test go-errcheck go-staticcheck)
+ "A list of tags for `go build'.
+
+Each item is a string with a tag to be given to `go build'."
+ :type '(repeat (string :tag "Tag"))
+ :safe #'flycheck-string-list-p
+ :package-version '(flycheck . "0.25"))
+
+
+(flycheck-def-option-var flycheck-go-version nil go-staticcheck
+ "The version of go that should be targeted by `staticcheck'.
+
+Should be a string representing a version, like 1.6 or 1.11.4.
+See `https://staticcheck.io/docs/#targeting-go-versions' for
+details."
+ :type '(choice (const :tag "Unspecified" nil)
+ (string :tag "Version"))
+ :safe #'flycheck-string-or-nil-p
+ :package-version '(flycheck . "0.32"))
+
+(flycheck-define-checker go-build
+ "A Go syntax and type checker using the `go build' command.
+
+Requires Go 1.6 or newer. See URL `https://golang.org/cmd/go'."
+ :command ("go" "build"
+ (option-flag "-i" flycheck-go-build-install-deps)
+ ;; multiple tags are listed as "dev debug ..."
+ (option-list "-tags=" flycheck-go-build-tags concat)
+ "-o" null-device)
+ :error-patterns
+ ((error line-start (file-name) ":" line ":"
+ (optional column ":") " "
+ (message (one-or-more not-newline)
+ (zero-or-more "\n\t" (one-or-more not-newline)))
+ line-end)
+ ;; Catch error message about multiple packages in a directory, which doesn't
+ ;; follow the standard error message format.
+ (info line-start
+ (message "can't load package: package "
+ (one-or-more (not (any ?: ?\n)))
+ ": found packages "
+ (one-or-more not-newline))
+ line-end))
+ :error-filter
+ (lambda (errors)
+ (dolist (error errors)
+ (unless (flycheck-error-line error)
+ ;; Flycheck ignores errors without line numbers, but the error
+ ;; message about multiple packages in a directory doesn't come with a
+ ;; line number, so inject a fake one.
+ (setf (flycheck-error-line error) 1)))
+ errors)
+ :modes go-mode
+ :predicate (lambda ()
+ (and (flycheck-buffer-saved-p)
+ (not (string-suffix-p "_test.go" (buffer-file-name)))))
+ :next-checkers ((warning . go-errcheck)
+ (warning . go-unconvert)
+ (warning . go-staticcheck)))
+
+(flycheck-define-checker go-test
+ "A Go syntax and type checker using the `go test' command.
+
+Requires Go 1.6 or newer. See URL `https://golang.org/cmd/go'."
+ :command ("go" "test"
+ (option-flag "-i" flycheck-go-build-install-deps)
+ (option-list "-tags=" flycheck-go-build-tags concat)
+ "-c" "-o" null-device)
+ :error-patterns
+ ((error line-start (file-name) ":" line ":"
+ (optional column ":") " "
+ (message (one-or-more not-newline)
+ (zero-or-more "\n\t" (one-or-more not-newline)))
+ line-end))
+ :modes go-mode
+ :predicate
+ (lambda () (and (flycheck-buffer-saved-p)
+ (string-suffix-p "_test.go" (buffer-file-name))))
+ :next-checkers ((warning . go-errcheck)
+ (warning . go-unconvert)
+ (warning . go-staticcheck)))
+
+(flycheck-define-checker go-errcheck
+ "A Go checker for unchecked errors.
+
+Requires errcheck newer than commit 8515d34 (Aug 28th, 2015).
+
+See URL `https://github.com/kisielk/errcheck'."
+ :command ("errcheck"
+ "-abspath"
+ (option-list "-tags=" flycheck-go-build-tags concat)
+ ".")
+ :error-patterns
+ ((warning line-start
+ (file-name) ":" line ":" column (or (one-or-more "\t") ": " ":\t")
+ (message)
+ line-end))
+ :error-filter
+ (lambda (errors)
+ (let ((errors (flycheck-sanitize-errors errors)))
+ (dolist (err errors)
+ (-when-let (message (flycheck-error-message err))
+ ;; Improve the messages reported by errcheck to make them more clear.
+ (setf (flycheck-error-message err)
+ (format "Ignored `error` returned from `%s`" message)))))
+ errors)
+ :modes go-mode
+ :predicate (lambda () (flycheck-buffer-saved-p))
+ :next-checkers ((warning . go-unconvert)
+ (warning . go-staticcheck)))
+
+(flycheck-define-checker go-unconvert
+ "A Go checker looking for unnecessary type conversions.
+
+See URL `https://github.com/mdempsky/unconvert'."
+ :command ("unconvert" ".")
+ :error-patterns
+ ((warning line-start (file-name) ":" line ":" column ": " (message) line-end))
+ :modes go-mode
+ :predicate (lambda () (flycheck-buffer-saved-p)))
+
+(flycheck-define-checker go-staticcheck
+ "A Go checker that performs static analysis and linting using
+the `staticcheck' command.
+
+`staticcheck' is explicitly fully compatible with \"the last two
+versions of go\". `staticheck' can target earlier versions (with
+limited features) if `flycheck-go-version' is set. See URL
+`https://staticcheck.io/'."
+ :command ("staticcheck" "-f" "json"
+ (option-list "-tags" flycheck-go-build-tags concat)
+ (option "-go" flycheck-go-version))
+
+ :error-parser flycheck-parse-go-staticcheck
+ :modes go-mode)
+
+(flycheck-define-checker groovy
+ "A groovy syntax checker using groovy compiler API.
+
+See URL `http://www.groovy-lang.org'."
+ :command ("groovy" "-e"
+ "import org.codehaus.groovy.control.*
+
+unit = new CompilationUnit()
+unit.addSource(\"input\", System.in)
+
+try {
+ unit.compile(Phases.CONVERSION)
+} catch (MultipleCompilationErrorsException e) {
+ e.errorCollector.write(new PrintWriter(System.out, true), null)
+}")
+ :standard-input t
+ :error-patterns
+ ((error line-start "input: " line ":" (message)
+ " @ line " line ", column " column "." line-end))
+ :modes groovy-mode)
+
+(flycheck-define-checker haml
+ "A Haml syntax checker using the Haml compiler.
+
+See URL `http://haml.info'."
+ :command ("haml" "-c" "--stdin")
+ :standard-input t
+ :error-patterns
+ ((error line-start "Syntax error on line " line ": " (message) line-end)
+ (error line-start ":" line ": syntax error, " (message) line-end))
+ :modes haml-mode)
+
+(flycheck-define-checker handlebars
+ "A Handlebars syntax checker using the Handlebars compiler.
+
+See URL `http://handlebarsjs.com/'."
+ :command ("handlebars" "-i-")
+ :standard-input t
+ :error-patterns
+ ((error line-start
+ "Error: Parse error on line " line ":" (optional "\r") "\n"
+ (zero-or-more not-newline) "\n" (zero-or-more not-newline) "\n"
+ (message) line-end))
+ :modes (handlebars-mode handlebars-sgml-mode web-mode)
+ :predicate
+ (lambda ()
+ (if (eq major-mode 'web-mode)
+ ;; Check if this is a handlebars file since web-mode does not store the
+ ;; non-canonical engine name
+ (let* ((regexp-alist (bound-and-true-p web-mode-engine-file-regexps))
+ (pattern (cdr (assoc "handlebars" regexp-alist))))
+ (and pattern (buffer-file-name)
+ (string-match-p pattern (buffer-file-name))))
+ t)))
+
+(defconst flycheck-haskell-module-re
+ (rx line-start (zero-or-more (or "\n" (any space)))
+ "module" (one-or-more (or "\n" (any space)))
+ (group (one-or-more (not (any space "(" "\n")))))
+ "Regular expression for a Haskell module name.")
+
+(flycheck-def-args-var flycheck-ghc-args (haskell-stack-ghc haskell-ghc)
+ :package-version '(flycheck . "0.22"))
+
+(flycheck-def-option-var flycheck-ghc-stack-use-nix nil haskell-stack-ghc
+ "Whether to enable nix support in stack.
+
+When non-nil, stack will append '--nix' flag to any call."
+ :type 'boolean
+ :safe #'booleanp
+ :package-version '(flycheck . "26"))
+
+(flycheck-def-option-var flycheck-ghc-stack-project-file nil haskell-stack-ghc
+ "Override project stack.yaml file.
+
+The value of this variable is a file path that refers to a yaml
+file for the current stack project. Relative file paths are
+resolved against the checker's working directory. When non-nil,
+stack will get overridden value via `--stack-yaml'."
+ :type '(choice (const :tag "Unspecified" nil)
+ (file :tag "Project file"))
+ :safe #'flycheck-string-or-nil-p
+ :package-version '(flycheck . "32"))
+
+(flycheck-def-option-var flycheck-ghc-no-user-package-database nil haskell-ghc
+ "Whether to disable the user package database in GHC.
+
+When non-nil, disable the user package database in GHC, via
+`-no-user-package-db'."
+ :type 'boolean
+ :safe #'booleanp
+ :package-version '(flycheck . "0.16"))
+
+(flycheck-def-option-var flycheck-ghc-package-databases nil haskell-ghc
+ "Additional module databases for GHC.
+
+The value of this variable is a list of strings, where each
+string is a directory of a package database. Each package
+database is given to GHC via `-package-db'."
+ :type '(repeat (directory :tag "Package database"))
+ :safe #'flycheck-string-list-p
+ :package-version '(flycheck . "0.16"))
+
+(flycheck-def-option-var flycheck-ghc-search-path nil
+ (haskell-stack-ghc haskell-ghc)
+ "Module search path for (Stack) GHC.
+
+The value of this variable is a list of strings, where each
+string is a directory containing Haskell modules. Each directory
+is added to the GHC search path via `-i'."
+ :type '(repeat (directory :tag "Module directory"))
+ :safe #'flycheck-string-list-p
+ :package-version '(flycheck . "0.16"))
+
+(flycheck-def-option-var flycheck-ghc-language-extensions nil
+ (haskell-stack-ghc haskell-ghc)
+ "Language extensions for (Stack) GHC.
+
+The value of this variable is a list of strings, where each
+string is a Haskell language extension, as in the LANGUAGE
+pragma. Each extension is enabled via `-X'."
+ :type '(repeat (string :tag "Language extension"))
+ :safe #'flycheck-string-list-p
+ :package-version '(flycheck . "0.19"))
+
+(defvar flycheck-haskell-ghc-cache-directory nil
+ "The cache directory for `ghc' output.")
+
+(defun flycheck-haskell-ghc-cache-directory ()
+ "Get the cache location for `ghc' output.
+
+If no cache directory exists yet, create one and return it.
+Otherwise return the previously used cache directory."
+ (setq flycheck-haskell-ghc-cache-directory
+ (or flycheck-haskell-ghc-cache-directory
+ (make-temp-file "flycheck-haskell-ghc-cache" 'directory))))
+
+(defun flycheck--locate-dominating-file-matching (directory regexp)
+ "Search for a file in directory hierarchy starting at DIRECTORY.
+
+Look up the directory hierarchy from DIRECTORY for a directory
+containing a file that matches REGEXP."
+ (locate-dominating-file
+ directory
+ (lambda (dir)
+ (directory-files dir nil regexp t))))
+
+(defun flycheck-haskell--find-stack-default-directory ()
+ "Find a directory to run haskell-stack-ghc.
+
+Return a parent directory with a stack*.y[a]ml file, or the
+directory returned by \"stack path --project-root\"."
+ (or
+ (when (buffer-file-name)
+ (flycheck--locate-dominating-file-matching
+ (file-name-directory (buffer-file-name))
+ (rx "stack" (* any) "." (or "yml" "yaml") eos)))
+ (-when-let* ((stack (funcall flycheck-executable-find "stack"))
+ (output (ignore-errors
+ (process-lines stack
+ "--no-install-ghc"
+ "path" "--project-root")))
+ (stack-dir (car output)))
+ (and (file-directory-p stack-dir) stack-dir))))
+
+(defun flycheck-haskell--ghc-find-default-directory (_checker)
+ "Find a parent directory containing a cabal or package.yaml file."
+ (when (buffer-file-name)
+ (flycheck--locate-dominating-file-matching
+ (file-name-directory (buffer-file-name))
+ "\\.cabal\\'\\|\\`package\\.yaml\\'")))
+
+(flycheck-define-checker haskell-stack-ghc
+ "A Haskell syntax and type checker using `stack ghc'.
+
+See URL `https://github.com/commercialhaskell/stack'."
+ :command ("stack"
+ "--no-install-ghc"
+ (option "--stack-yaml" flycheck-ghc-stack-project-file)
+ (option-flag "--nix" flycheck-ghc-stack-use-nix)
+ "ghc" "--" "-Wall" "-no-link"
+ "-outputdir" (eval (flycheck-haskell-ghc-cache-directory))
+ (option-list "-X" flycheck-ghc-language-extensions concat)
+ (option-list "-i" flycheck-ghc-search-path concat)
+ (eval (concat
+ "-i"
+ (flycheck-module-root-directory
+ (flycheck-find-in-buffer flycheck-haskell-module-re))))
+ (eval flycheck-ghc-args)
+ "-x" (eval
+ (pcase major-mode
+ (`haskell-mode "hs")
+ (`haskell-literate-mode "lhs")))
+ source)
+ :error-patterns
+ ((warning line-start (file-name) ":" line ":" column ":"
+ (or " " "\n ") (in "Ww") "arning:"
+ (optional " " "[" (id (one-or-more not-newline)) "]")
+ (optional "\n")
+ (message
+ (one-or-more " ") (one-or-more not-newline)
+ (zero-or-more "\n"
+ (one-or-more " ")
+ (one-or-more (not (any ?\n ?|)))))
+ line-end)
+ (error line-start (file-name) ":" line ":" column ":" (optional " error:")
+ (or (message (one-or-more not-newline))
+ (and "\n"
+ (message
+ (one-or-more " ") (one-or-more not-newline)
+ (zero-or-more "\n"
+ (one-or-more " ")
+ (one-or-more (not (any ?\n ?|)))))))
+ line-end))
+ :error-filter
+ (lambda (errors)
+ (flycheck-sanitize-errors (flycheck-dedent-error-messages errors)))
+ :modes (haskell-mode haskell-literate-mode)
+ :next-checkers ((warning . haskell-hlint))
+ :working-directory (lambda (_)
+ (flycheck-haskell--find-stack-default-directory))
+ :enabled flycheck-haskell--find-stack-default-directory
+ :verify (lambda (_)
+ (let* ((stack (flycheck-haskell--find-stack-default-directory)))
+ (list
+ (flycheck-verification-result-new
+ :label "stack config"
+ :message (or stack "Not found")
+ :face (if stack 'success '(bold error)))))))
+
+(flycheck-define-checker haskell-ghc
+ "A Haskell syntax and type checker using ghc.
+
+See URL `https://www.haskell.org/ghc/'."
+ :command ("ghc" "-Wall" "-no-link"
+ "-outputdir" (eval (flycheck-haskell-ghc-cache-directory))
+ (option-flag "-no-user-package-db"
+ flycheck-ghc-no-user-package-database)
+ (option-list "-package-db" flycheck-ghc-package-databases)
+ (option-list "-i" flycheck-ghc-search-path concat)
+ ;; Include the parent directory of the current module tree, to
+ ;; properly resolve local imports
+ (eval (concat
+ "-i"
+ (flycheck-module-root-directory
+ (flycheck-find-in-buffer flycheck-haskell-module-re))))
+ (option-list "-X" flycheck-ghc-language-extensions concat)
+ (eval flycheck-ghc-args)
+ "-x" (eval
+ (pcase major-mode
+ (`haskell-mode "hs")
+ (`haskell-literate-mode "lhs")))
+ source)
+ :error-patterns
+ ((warning line-start (file-name) ":" line ":" column ":"
+ (or " " "\n ") (in "Ww") "arning:"
+ (optional " " "[" (id (one-or-more not-newline)) "]")
+ (optional "\n")
+ (message
+ (one-or-more " ") (one-or-more not-newline)
+ (zero-or-more "\n"
+ (one-or-more " ")
+ (one-or-more (not (any ?\n ?|)))))
+ line-end)
+ (error line-start (file-name) ":" line ":" column ":" (optional " error:")
+ (or (message (one-or-more not-newline))
+ (and "\n"
+ (message
+ (one-or-more " ") (one-or-more not-newline)
+ (zero-or-more "\n"
+ (one-or-more " ")
+ (one-or-more (not (any ?\n ?|)))))))
+ line-end))
+ :error-filter
+ (lambda (errors)
+ (flycheck-sanitize-errors (flycheck-dedent-error-messages errors)))
+ :modes (haskell-mode haskell-literate-mode)
+ :next-checkers ((warning . haskell-hlint))
+ :working-directory flycheck-haskell--ghc-find-default-directory)
+
+(flycheck-def-config-file-var flycheck-hlintrc haskell-hlint "HLint.hs")
+
+(flycheck-def-args-var flycheck-hlint-args haskell-hlint
+ :package-version '(flycheck . "0.25"))
+
+(flycheck-def-option-var flycheck-hlint-language-extensions
+ nil haskell-hlint
+ "Extensions list to enable for hlint.
+
+The value of this variable is a list of strings, where each
+string is a name of extension to enable in
+hlint (e.g. \"QuasiQuotes\")."
+ :type '(repeat :tag "Extensions" (string :tag "Extension"))
+ :safe #'flycheck-string-list-p
+ :package-version '(flycheck . "0.24"))
+
+(flycheck-def-option-var flycheck-hlint-ignore-rules
+ nil haskell-hlint
+ "Ignore rules list for hlint checks.
+
+The value of this variable is a list of strings, where each
+string is an ignore rule (e.g. \"Use fmap\")."
+ :type '(repeat :tag "Ignore rules" (string :tag "Ignore rule"))
+ :safe #'flycheck-string-list-p
+ :package-version '(flycheck . "0.24"))
+
+(flycheck-def-option-var flycheck-hlint-hint-packages
+ nil haskell-hlint
+ "Hint packages to include for hlint checks.
+
+The value of this variable is a list of strings, where each
+string is a default hint package (e.g. (\"Generalise\"
+\"Default\" \"Dollar\"))."
+ :type '(repeat :tag "Hint packages" (string :tag "Hint package"))
+ :safe #'flycheck-string-list-p
+ :package-version '(flycheck . "0.24"))
+
+(flycheck-define-checker haskell-hlint
+ "A Haskell style checker using hlint.
+
+See URL `https://github.com/ndmitchell/hlint'."
+ :command ("hlint"
+ (option-list "-X" flycheck-hlint-language-extensions concat)
+ (option-list "-i=" flycheck-hlint-ignore-rules concat)
+ (option-list "-h" flycheck-hlint-hint-packages concat)
+ (config-file "-h" flycheck-hlintrc)
+ (eval flycheck-hlint-args)
+ source-inplace)
+ :error-patterns
+ ((info line-start
+ (file-name) ":" line ":" column (optional "-" end-column)
+ ": Suggestion: "
+ (message (one-or-more (and (one-or-more (not (any ?\n))) ?\n)))
+ line-end)
+ (warning line-start
+ (file-name) ":" line ":" column (optional "-" end-column)
+ ": Warning: "
+ (message (one-or-more (and (one-or-more (not (any ?\n))) ?\n)))
+ line-end)
+ (error line-start
+ (file-name) ":" line ":" column (optional "-" end-column)
+ ": Error: "
+ (message (one-or-more (and (one-or-more (not (any ?\n))) ?\n)))
+ line-end))
+ :modes (haskell-mode haskell-literate-mode))
+
+(flycheck-def-config-file-var flycheck-tidyrc html-tidy ".tidyrc")
+
+(flycheck-define-checker html-tidy
+ "A HTML syntax and style checker using Tidy.
+
+See URL `https://github.com/htacg/tidy-html5'."
+ :command ("tidy" (config-file "-config" flycheck-tidyrc)
+ "-lang" "en"
+ "-e" "-q")
+ :standard-input t
+ :error-patterns
+ ((error line-start
+ "line " line
+ " column " column
+ " - Error: " (message) line-end)
+ (warning line-start
+ "line " line
+ " column " column
+ " - Warning: " (message) line-end))
+ :modes (html-mode mhtml-mode nxhtml-mode))
+
+(flycheck-def-config-file-var flycheck-jshintrc javascript-jshint ".jshintrc")
+
+(flycheck-def-option-var flycheck-jshint-extract-javascript nil
+ javascript-jshint
+ "Whether jshint should extract Javascript from HTML.
+
+If nil no extract rule is given to jshint. If `auto' only
+extract Javascript if a HTML file is detected. If `always' or
+`never' extract Javascript always or never respectively.
+
+Refer to the jshint manual at the URL
+`http://jshint.com/docs/cli/#flags' for more information."
+ :type
+ '(choice (const :tag "No extraction rule" nil)
+ (const :tag "Try to extract Javascript when detecting HTML files"
+ auto)
+ (const :tag "Always try to extract Javascript" always)
+ (const :tag "Never try to extract Javascript" never))
+ :safe #'symbolp
+ :package-version '(flycheck . "26"))
+
+(flycheck-define-checker javascript-jshint
+ "A Javascript syntax and style checker using jshint.
+
+See URL `http://www.jshint.com'."
+ :command ("jshint" "--reporter=checkstyle"
+ "--filename" source-original
+ (config-file "--config" flycheck-jshintrc)
+ (option "--extract=" flycheck-jshint-extract-javascript
+ concat flycheck-option-symbol)
+ "-")
+ :standard-input t
+ :error-parser flycheck-parse-checkstyle
+ :error-filter
+ (lambda (errors)
+ (flycheck-remove-error-file-names
+ "stdin" (flycheck-dequalify-error-ids errors)))
+ :modes (js-mode js2-mode js3-mode rjsx-mode))
+
+(flycheck-def-args-var flycheck-eslint-args javascript-eslint
+ :package-version '(flycheck . "32"))
+
+(flycheck-def-option-var flycheck-eslint-rules-directories nil javascript-eslint
+ "A list of directories with custom rules for ESLint.
+
+The value of this variable is a list of strings, where each
+string is a directory with custom rules for ESLint.
+
+Refer to the ESLint manual at URL
+`http://eslint.org/docs/user-guide/command-line-interface#--rulesdir'
+for more information about the custom directories."
+ :type '(repeat (directory :tag "Custom rules directory"))
+ :safe #'flycheck-string-list-p
+ :package-version '(flycheck . "29"))
+
+(defun flycheck-eslint-config-exists-p ()
+ "Whether there is a valid eslint config for the current buffer."
+ (eql 0 (flycheck-call-checker-process
+ 'javascript-eslint nil nil nil
+ "--print-config" (or buffer-file-name "index.js"))))
+
+(defun flycheck-parse-eslint (output checker buffer)
+ "Parse ESLint errors/warnings from JSON OUTPUT.
+
+CHECKER and BUFFER denote the CHECKER that returned OUTPUT and
+the BUFFER that was checked respectively.
+
+See URL `https://eslint.org' for more information about ESLint."
+ (mapcar (lambda (err)
+ (let-alist err
+ (flycheck-error-new-at
+ .line
+ .column
+ (pcase .severity
+ (2 'error)
+ (1 'warning)
+ (_ 'warning))
+ .message
+ :id .ruleId
+ :checker checker
+ :buffer buffer
+ :filename (buffer-file-name buffer)
+ :end-line .endLine
+ :end-column .endColumn)))
+ (let-alist (caar (flycheck-parse-json output))
+ .messages)))
+
+(defun flycheck-eslint--find-working-directory (_checker)
+ "Look for a working directory to run ESLint CHECKER in.
+
+This will be the directory that contains the `node_modules'
+directory. If no such directory is found in the directory
+hierarchy, it looks first for `.eslintignore' and then for
+`.eslintrc' files to detect the project root."
+ (let* ((regex-config (concat "\\`\\.eslintrc"
+ "\\(\\.\\(js\\|ya?ml\\|json\\)\\)?\\'")))
+ (when buffer-file-name
+ (or (locate-dominating-file buffer-file-name "node_modules")
+ (locate-dominating-file buffer-file-name ".eslintignore")
+ (locate-dominating-file
+ (file-name-directory buffer-file-name)
+ (lambda (directory)
+ (> (length (directory-files directory nil regex-config t)) 0)))))))
+
+(flycheck-define-checker javascript-eslint
+ "A Javascript syntax and style checker using eslint.
+
+See URL `https://eslint.org/'."
+ :command ("eslint" "--format=json"
+ (option-list "--rulesdir" flycheck-eslint-rules-directories)
+ (eval flycheck-eslint-args)
+ "--stdin" "--stdin-filename" source-original)
+ :standard-input t
+ :error-parser flycheck-parse-eslint
+ :enabled (lambda () (flycheck-eslint-config-exists-p))
+ :modes (js-mode js-jsx-mode js2-mode js2-jsx-mode js3-mode rjsx-mode
+ typescript-mode)
+ :working-directory flycheck-eslint--find-working-directory
+ :verify
+ (lambda (_)
+ (let* ((default-directory
+ (flycheck-compute-working-directory 'javascript-eslint))
+ (have-config (flycheck-eslint-config-exists-p)))
+ (list
+ (flycheck-verification-result-new
+ :label "config file"
+ :message (if have-config "found" "missing or incorrect")
+ :face (if have-config 'success '(bold error))))))
+ :error-explainer
+ (lambda (err)
+ (let ((error-code (flycheck-error-id err))
+ (url "https://eslint.org/docs/rules/%s"))
+ (and error-code
+ ;; skip non-builtin rules
+ (not ;; `seq-contains-p' is only in seq >= 2.21
+ (with-no-warnings (seq-contains error-code ?/)))
+ `(url . ,(format url error-code))))))
+
+(flycheck-define-checker javascript-standard
+ "A Javascript code and style checker for the (Semi-)Standard Style.
+
+This checker works with `standard' and `semistandard', defaulting
+to the former. To use it with the latter, set
+`flycheck-javascript-standard-executable' to `semistandard'.
+
+See URL `https://github.com/standard/standard' and URL
+`https://github.com/Flet/semistandard'."
+ :command ("standard" "--stdin")
+ :standard-input t
+ :error-patterns
+ ((error line-start " <text>:" line ":" column ":" (message) line-end))
+ :modes (js-mode js-jsx-mode js2-mode js2-jsx-mode js3-mode rjsx-mode))
+
+(flycheck-define-checker json-jsonlint
+ "A JSON syntax and style checker using jsonlint.
+
+See URL `https://github.com/zaach/jsonlint'."
+ ;; We can't use standard input for jsonlint, because it doesn't output errors
+ ;; anymore when using -c -q with standard input :/
+ :command ("jsonlint" "-c" "-q" source)
+ :error-patterns
+ ((error line-start
+ (file-name)
+ ": line " line
+ ", col " column ", "
+ (message) line-end))
+ :error-filter
+ (lambda (errors)
+ (flycheck-sanitize-errors (flycheck-increment-error-columns errors)))
+ :modes json-mode)
+
+(flycheck-define-checker json-python-json
+ "A JSON syntax checker using Python json.tool module.
+
+See URL `https://docs.python.org/3.5/library/json.html#command-line-interface'."
+ :command ("python3" "-m" "json.tool" source
+ ;; Send the pretty-printed output to the null device
+ null-device)
+ :error-patterns
+ ((error line-start
+ (message) ": line " line " column " column
+ ;; Ignore the rest of the line which shows the char position.
+ (one-or-more not-newline)
+ line-end))
+ :modes json-mode
+ ;; The JSON parser chokes if the buffer is empty and has no JSON inside
+ :predicate flycheck-buffer-nonempty-p)
+
+(flycheck-define-checker json-jq
+ "JSON checker using the jq tool.
+
+This checker accepts multiple consecutive JSON values in a
+single input, which is useful for jsonlines data.
+
+See URL `https://stedolan.github.io/jq/'."
+ :command ("jq" "." source null-device)
+ ;; Example error message:
+ ;; parse error: Expected another key-value pair at line 3, column 1
+ :error-patterns
+ ((error line-start
+ (optional "parse error: ")
+ (message) "at line " line ", column " column
+ (zero-or-more not-newline) line-end))
+ :modes json-mode)
+
+(flycheck-define-checker jsonnet
+ "A Jsonnet syntax checker using the jsonnet binary.
+
+See URL `https://jsonnet.org'."
+ :command ("jsonnet" source-inplace)
+ :error-patterns
+ ((error line-start "STATIC ERROR: " (file-name) ":"
+ (or (seq line ":" column (zero-or-one (seq "-" end-column)))
+ (seq "(" line ":" column ")" "-"
+ "(" end-line ":" end-column ")"))
+ ": " (message) line-end)
+ (error line-start "RUNTIME ERROR: " (message) "\n"
+ (? "\t" (file-name) ":" ;; first line of the backtrace
+ (or (seq line ":" column (zero-or-one (seq "-" end-column)))
+ (seq "(" line ":" column ")" "-"
+ "(" end-line ":" end-column ")")))))
+ :error-filter
+ (lambda (errs)
+ ;; Some errors are missing line numbers. See URL
+ ;; `https://github.com/google/jsonnet/issues/786'.
+ (dolist (err errs)
+ (unless (flycheck-error-line err)
+ (setf (flycheck-error-line err) 1)))
+ (flycheck-sanitize-errors errs))
+ :modes jsonnet-mode)
+
+(flycheck-define-checker less
+ "A LESS syntax checker using lessc.
+
+Requires lessc 1.4 or newer.
+
+See URL `http://lesscss.org'."
+ :command ("lessc" "--lint" "--no-color"
+ "-")
+ :standard-input t
+ :error-patterns
+ ((error line-start (one-or-more word) ":"
+ (message)
+ " in - on line " line
+ ", column " column ":"
+ line-end))
+ :modes less-css-mode)
+
+(flycheck-define-checker less-stylelint
+ "A LESS syntax and style checker using stylelint.
+
+See URL `http://stylelint.io/'."
+ :command ("stylelint"
+ (eval flycheck-stylelint-args)
+ "--syntax" "less"
+ (option-flag "--quiet" flycheck-stylelint-quiet)
+ (config-file "--config" flycheck-stylelintrc))
+ :standard-input t
+ :error-parser flycheck-parse-stylelint
+ :predicate flycheck-buffer-nonempty-p
+ :modes (less-css-mode))
+
+(flycheck-define-checker llvm-llc
+ "Flycheck LLVM IR checker using llc.
+
+See URL `http://llvm.org/docs/CommandGuide/llc.html'."
+ :command ("llc" "-o" null-device source)
+ :error-patterns
+ ((error line-start
+ ;; llc prints the executable path
+ (zero-or-one (minimal-match (one-or-more not-newline)) ": ")
+ (file-name) ":" line ":" column ": error: " (message)
+ line-end))
+ :error-filter
+ (lambda (errors)
+ ;; sanitize errors occurring in inline assembly
+ (flycheck-sanitize-errors
+ (flycheck-remove-error-file-names "<inline asm>" errors)))
+ :modes llvm-mode)
+
+(flycheck-def-config-file-var flycheck-luacheckrc lua-luacheck ".luacheckrc")
+
+(flycheck-def-option-var flycheck-luacheck-standards nil lua-luacheck
+ "The standards to use in luacheck.
+
+The value of this variable is either a list of strings denoting
+the standards to use, or nil to pass nothing to luacheck. When
+non-nil, pass the standards via one or more `--std' options."
+ :type '(choice (const :tag "Default" nil)
+ (repeat :tag "Custom standards"
+ (string :tag "Standard name")))
+ :safe #'flycheck-string-list-p)
+(make-variable-buffer-local 'flycheck-luacheck-standards)
+
+(flycheck-define-checker lua-luacheck
+ "A Lua syntax checker using luacheck.
+
+See URL `https://github.com/mpeterv/luacheck'."
+ :command ("luacheck"
+ "--formatter" "plain"
+ "--codes" ; Show warning codes
+ "--no-color"
+ (option-list "--std" flycheck-luacheck-standards)
+ (config-file "--config" flycheck-luacheckrc)
+ "--filename" source-original
+ ;; Read from standard input
+ "-")
+ :standard-input t
+ :error-patterns
+ ((warning line-start
+ (optional (file-name))
+ ":" line ":" column
+ ": (" (id "W" (one-or-more digit)) ") "
+ (message) line-end)
+ (error line-start
+ (optional (file-name))
+ ":" line ":" column ":"
+ ;; `luacheck' before 0.11.0 did not output codes for errors, hence
+ ;; the ID is optional here
+ (optional " (" (id "E" (one-or-more digit)) ") ")
+ (message) line-end))
+ :modes lua-mode)
+
+(flycheck-define-checker lua
+ "A Lua syntax checker using the Lua compiler.
+
+See URL `http://www.lua.org/'."
+ :command ("luac" "-p" "-")
+ :standard-input t
+ :error-patterns
+ ((error line-start
+ ;; Skip the name of the luac executable.
+ (minimal-match (zero-or-more not-newline))
+ ": stdin:" line ": " (message) line-end))
+ :modes lua-mode)
+
+(flycheck-define-checker opam
+ "A Opam syntax and style checker using opam lint.
+
+See URL `https://opam.ocaml.org/doc/man/opam-lint.html'."
+ :command ("opam" "lint" "-")
+ :standard-input t
+ :error-patterns
+ ((error line-start ; syntax error
+ (one-or-more space) "error " (id ?2)
+ ": File format error"
+ (or (and " at line " line ", column " column ": " (message))
+ (and ": " (message)))
+ line-end)
+ (error line-start
+ (one-or-more space) "error " (id ?3)
+ (minimal-match (zero-or-more not-newline))
+ "at line " line ", column " column ": " (message)
+ line-end)
+ (error line-start
+ (one-or-more space) "error " (id (one-or-more num))
+ ": " (message (one-or-more not-newline))
+ line-end)
+ (warning line-start
+ (one-or-more space) "warning " (id (one-or-more num))
+ ": " (message)
+ line-end))
+ :error-filter
+ (lambda (errors)
+ (flycheck-increment-error-columns
+ (flycheck-fill-empty-line-numbers errors)))
+ :modes tuareg-opam-mode)
+
+(flycheck-def-option-var flycheck-perl-include-path nil perl
+ "A list of include directories for Perl.
+
+The value of this variable is a list of strings, where each
+string is a directory to add to the include path of Perl.
+Relative paths are relative to the file being checked."
+ :type '(repeat (directory :tag "Include directory"))
+ :safe #'flycheck-string-list-p
+ :package-version '(flycheck . "0.24"))
+
+(flycheck-def-option-var flycheck-perl-module-list nil perl
+ "A list of modules to use for Perl.
+
+The value of this variable is a list of strings, where each
+string is a module to 'use' in Perl."
+ :type '(repeat :tag "Module")
+ :safe #'flycheck-string-list-p
+ :package-version '(flycheck . "32"))
+
+(flycheck-define-checker perl
+ "A Perl syntax checker using the Perl interpreter.
+
+See URL `https://www.perl.org'."
+ :command ("perl" "-w" "-c"
+ (option-list "-I" flycheck-perl-include-path)
+ (option-list "-M" flycheck-perl-module-list concat))
+ :standard-input t
+ :error-patterns
+ ((error line-start (minimal-match (message))
+ " at - line " line
+ (or "." (and ", " (zero-or-more not-newline))) line-end))
+ :modes (perl-mode cperl-mode)
+ :next-checkers (perl-perlcritic))
+
+(flycheck-def-option-var flycheck-perlcritic-severity nil perl-perlcritic
+ "The message severity for Perl Critic.
+
+The value of this variable is a severity level as integer, for
+the `--severity' option to Perl Critic."
+ :type '(integer :tag "Severity level")
+ :safe #'integerp
+ :package-version '(flycheck . "0.18"))
+
+(flycheck-def-option-var flycheck-perlcritic-theme nil perl-perlcritic
+ "The theme expression for Perl Critic.
+
+The value of this variable is passed as the `--theme' option to
+`Perl::Critic'. See the documentation of `Perl::Critic' for
+details."
+ :type '(choice (const :tag "None" nil)
+ (string :tag "Theme expression"))
+ :safe #'flycheck-string-or-nil-p
+ :package-version '(flycheck . "32-csv"))
+
+(flycheck-def-config-file-var flycheck-perlcriticrc perl-perlcritic
+ ".perlcriticrc"
+ :package-version '(flycheck . "26"))
+
+(flycheck-define-checker perl-perlcritic
+ "A Perl syntax checker using Perl::Critic.
+
+See URL `https://metacpan.org/pod/Perl::Critic'."
+ :command ("perlcritic" "--no-color" "--verbose" "%f/%l/%c/%s/%p/%m (%e)\n"
+ (config-file "--profile" flycheck-perlcriticrc)
+ (option "--severity" flycheck-perlcritic-severity nil
+ flycheck-option-int)
+ (option "--theme" flycheck-perlcritic-theme))
+ :standard-input t
+ :error-patterns
+ ((info line-start
+ "STDIN/" line "/" column "/" (any "1") "/"
+ (id (one-or-more (not (any "/")))) "/" (message)
+ line-end)
+ (warning line-start
+ "STDIN/" line "/" column "/" (any "234") "/"
+ (id (one-or-more (not (any "/")))) "/" (message)
+ line-end)
+ (error line-start
+ "STDIN/" line "/" column "/" (any "5") "/"
+ (id (one-or-more (not (any "/")))) "/" (message)
+ line-end))
+ :modes (cperl-mode perl-mode))
+
+(flycheck-define-checker php
+ "A PHP syntax checker using the PHP command line interpreter.
+
+See URL `http://php.net/manual/en/features.commandline.php'."
+ :command ("php" "-l" "-d" "error_reporting=E_ALL" "-d" "display_errors=1"
+ "-d" "log_errors=0" source)
+ :error-patterns
+ ((error line-start (or "Parse" "Fatal" "syntax") " error" (any ":" ",") " "
+ (message) " in " (file-name) " on line " line line-end))
+ :modes (php-mode php+-mode)
+ :next-checkers ((warning . php-phpmd)
+ (warning . php-phpcs)))
+
+(flycheck-def-option-var flycheck-phpmd-rulesets
+ '("cleancode" "codesize" "controversial" "design" "naming" "unusedcode")
+ php-phpmd
+ "The rule sets for PHP Mess Detector.
+
+Set default rule sets and custom rule set files.
+
+See section \"Using multiple rule sets\" in the PHP Mess Detector
+manual at URL `https://phpmd.org/documentation/index.html'."
+ :type '(repeat :tag "rule sets"
+ (string :tag "A filename or rule set"))
+ :safe #'flycheck-string-list-p)
+
+(flycheck-define-checker php-phpmd
+ "A PHP style checker using PHP Mess Detector.
+
+See URL `https://phpmd.org/'."
+ :command ("phpmd" source "xml"
+ (eval (flycheck-option-comma-separated-list
+ flycheck-phpmd-rulesets)))
+ :error-parser flycheck-parse-phpmd
+ :modes (php-mode php+-mode)
+ :next-checkers (php-phpcs))
+
+(flycheck-def-option-var flycheck-phpcs-standard nil php-phpcs
+ "The coding standard for PHP CodeSniffer.
+
+When nil, use the default standard from the global PHP
+CodeSniffer configuration. When set to a string, pass the string
+to PHP CodeSniffer which will interpret it as name as a standard,
+or as path to a standard specification."
+ :type '(choice (const :tag "Default standard" nil)
+ (string :tag "Standard name or file"))
+ :safe #'flycheck-string-or-nil-p)
+
+(flycheck-define-checker php-phpcs
+ "A PHP style checker using PHP Code Sniffer.
+
+Needs PHP Code Sniffer 2.6 or newer.
+
+See URL `http://pear.php.net/package/PHP_CodeSniffer/'."
+ :command ("phpcs" "--report=checkstyle"
+ ;; Use -q flag to force quiet mode
+ ;; Quiet mode prevents errors from extra output when phpcs has
+ ;; been configured with show_progress enabled
+ "-q"
+ (option "--standard=" flycheck-phpcs-standard concat)
+ ;; Some files are not detected correctly
+ ;; so it is necessary to pass the extension.
+ (eval
+ (-when-let* ((fname buffer-file-name)
+ (ext (file-name-extension fname)))
+ (concat "--extensions=" ext)))
+
+ ;; Pass original file name to phpcs. We need to concat explicitly
+ ;; here, because phpcs really insists to get option and argument as
+ ;; a single command line argument :|
+ (eval (when (buffer-file-name)
+ (concat "--stdin-path=" (buffer-file-name))))
+ ;; Read from standard input
+ "-")
+ :standard-input t
+ :error-parser flycheck-parse-checkstyle
+ :error-filter
+ (lambda (errors)
+ (flycheck-sanitize-errors
+ (flycheck-remove-error-file-names "STDIN" errors)))
+ :modes (php-mode php+-mode)
+ ;; phpcs seems to choke on empty standard input, hence skip phpcs if the
+ ;; buffer is empty, see https://github.com/flycheck/flycheck/issues/907
+ :predicate flycheck-buffer-nonempty-p)
+
+(flycheck-define-checker processing
+ "Processing command line tool.
+
+See https://github.com/processing/processing/wiki/Command-Line"
+ :command ("processing-java" "--force"
+ ;; Don't change the order of these arguments, processing is pretty
+ ;; picky
+ (eval (concat "--sketch=" (file-name-directory (buffer-file-name))))
+ (eval (concat "--output=" (flycheck-temp-dir-system)))
+ "--build")
+ :error-patterns
+ ((error line-start (file-name) ":" line ":" column
+ (zero-or-more (or digit ":")) (message) line-end))
+ :modes processing-mode
+ ;; This syntax checker needs a file name
+ :predicate (lambda () (buffer-file-name)))
+
+(defun flycheck-proselint-parse-errors (output checker buffer)
+ "Parse proselint json output errors from OUTPUT.
+
+CHECKER and BUFFER denoted the CHECKER that returned OUTPUT and
+the BUFFER that was checked respectively.
+
+See URL `http://proselint.com/' for more information about proselint."
+ (mapcar (lambda (err)
+ (let-alist err
+ (flycheck-error-new-at-pos
+ .start
+ (pcase .severity
+ (`"suggestion" 'info)
+ (`"warning" 'warning)
+ (`"error" 'error)
+ ;; Default to error
+ (_ 'error))
+ .message
+ :id .check
+ :buffer buffer
+ :checker checker
+ ;; See https://github.com/amperser/proselint/issues/1048
+ :end-pos .end)))
+ (let-alist (car (flycheck-parse-json output))
+ .data.errors)))
+
+(flycheck-define-checker proselint
+ "Flycheck checker using Proselint.
+
+See URL `http://proselint.com/'."
+ :command ("proselint" "--json" "-")
+ :standard-input t
+ :error-parser flycheck-proselint-parse-errors
+ :modes (text-mode markdown-mode gfm-mode message-mode org-mode))
+
+(flycheck-def-option-var flycheck-protoc-import-path nil protobuf-protoc
+ "A list of directories to resolve import directives.
+
+The value of this variable is a list of strings, where each
+string is a directory to add to the import path. Relative paths
+are relative to the file being checked."
+ :type '(repeat (directory :tag "Import directory"))
+ :safe #'flycheck-string-list-p
+ :package-version '(flycheck . "32"))
+
+(flycheck-define-checker protobuf-protoc
+ "A protobuf syntax checker using the protoc compiler.
+
+See URL `https://developers.google.com/protocol-buffers/'."
+ :command ("protoc" "--error_format" "gcc"
+ (eval (concat "--java_out=" (flycheck-temp-dir-system)))
+ ;; Add the current directory to resolve imports
+ (eval (concat "--proto_path="
+ (file-name-directory (buffer-file-name))))
+ ;; Add other import paths; this needs to be after the current
+ ;; directory to produce the right output. See URL
+ ;; `https://github.com/flycheck/flycheck/pull/1655'
+ (option-list "--proto_path=" flycheck-protoc-import-path concat)
+ source-inplace)
+ :error-patterns
+ ((info line-start (file-name) ":" line ":" column
+ ": note: " (message) line-end)
+ (error line-start (file-name) ":" line ":" column
+ ": " (message) line-end)
+ (error line-start
+ (message "In file included from") " " (file-name) ":" line ":"
+ column ":" line-end))
+ :modes protobuf-mode
+ :predicate (lambda () (buffer-file-name)))
+
+(defun flycheck-prototool-project-root (&optional _checker)
+ "Return the nearest directory holding the prototool.yaml configuration."
+ (and buffer-file-name
+ (locate-dominating-file buffer-file-name "prototool.yaml")))
+
+(flycheck-define-checker protobuf-prototool
+ "A protobuf syntax checker using prototool.
+
+See URL `https://github.com/uber/prototool'."
+ :command ("prototool" "lint" source-original)
+ :error-patterns
+ ((warning line-start (file-name) ":" line ":" column ":" (message) line-end))
+ :modes protobuf-mode
+ :enabled flycheck-prototool-project-root
+ :predicate flycheck-buffer-saved-p)
+
+(flycheck-define-checker pug
+ "A Pug syntax checker using the pug compiler.
+
+See URL `https://pugjs.org/'."
+ :command ("pug" "-p" (eval (expand-file-name (buffer-file-name))))
+ :standard-input t
+ :error-patterns
+ ;; errors with includes/extends (e.g. missing files)
+ ((error "Error: " (message) (zero-or-more not-newline) "\n"
+ (zero-or-more not-newline) "at "
+ (zero-or-more not-newline) " line " line)
+ ;; error when placing anything other than a mixin or
+ ;; block at the top-level of an extended template
+ ;; also unknown filters
+ (error line-start "Error: " (file-name) ":"
+ line ":" column "\n\n" (message) line-end)
+ ;; syntax/runtime errors (e.g. type errors, bad indentation, etc.)
+ (error line-start
+ (optional "Type") "Error: " (file-name) ":"
+ line (optional ":" column)
+ (zero-or-more not-newline) "\n"
+ (one-or-more (or (zero-or-more not-newline) "|"
+ (zero-or-more not-newline) "\n")
+ (zero-or-more "-") (zero-or-more not-newline) "|"
+ (zero-or-more not-newline) "\n")
+ (zero-or-more not-newline) "\n"
+ (one-or-more
+ (zero-or-more not-newline) "|"
+ (zero-or-more not-newline) "\n")
+ (zero-or-more not-newline) "\n"
+ (message)
+ line-end))
+ :modes pug-mode)
+
+(flycheck-define-checker puppet-parser
+ "A Puppet DSL syntax checker using puppet's own parser.
+
+See URL `https://puppet.com/'."
+ :command ("puppet" "parser" "validate" "--color=false")
+ :standard-input t
+ :error-patterns
+ (
+ ;; Patterns for Puppet 4
+ (error line-start "Error: Could not parse for environment "
+ (one-or-more (in "a-z" "0-9" "_")) ":"
+ (message) "(line: " line ", column: " column ")" line-end)
+ ;; Errors from Puppet < 4
+ (error line-start "Error: Could not parse for environment "
+ (one-or-more (in "a-z" "0-9" "_")) ":"
+ (message (minimal-match (one-or-more anything)))
+ " at line " line line-end)
+ (error line-start
+ ;; Skip over the path of the Puppet executable
+ (minimal-match (zero-or-more not-newline))
+ ": Could not parse for environment " (one-or-more word)
+ ": " (message (minimal-match (zero-or-more anything)))
+ " at " (file-name "/" (zero-or-more not-newline)) ":" line line-end))
+ :modes puppet-mode
+ :next-checkers ((warning . puppet-lint)))
+
+(flycheck-def-config-file-var flycheck-puppet-lint-rc puppet-lint
+ ".puppet-lint.rc"
+ :package-version '(flycheck . "26"))
+
+(flycheck-def-option-var flycheck-puppet-lint-disabled-checks nil puppet-lint
+ "Disabled checkers for `puppet-lint'.
+
+The value of this variable is a list of strings, where each
+string is the name of a check to disable (e.g. \"80chars\" or
+\"double_quoted_strings\").
+
+See URL `http://puppet-lint.com/checks/' for a list of all checks
+and their names."
+ :type '(repeat (string :tag "Check Name"))
+ :package-version '(flycheck . "26"))
+
+(defun flycheck-puppet-lint-disabled-arg-name (check)
+ "Create an argument to disable a puppetlint CHECK."
+ (concat "--no-" check "-check"))
+
+(flycheck-define-checker puppet-lint
+ "A Puppet DSL style checker using puppet-lint.
+
+See URL `http://puppet-lint.com/'."
+ ;; We must check the original file, because Puppetlint is quite picky on the
+ ;; names of files and there place in the directory structure, to comply with
+ ;; Puppet's autoload directory layout. For instance, a class foo::bar is
+ ;; required to be in a file foo/bar.pp. Any other place, such as a Flycheck
+ ;; temporary file will cause an error.
+ :command ("puppet-lint"
+ (config-file "--config" flycheck-puppet-lint-rc)
+ "--log-format"
+ "%{path}:%{line}:%{kind}: %{message} (%{check})"
+ (option-list "" flycheck-puppet-lint-disabled-checks concat
+ flycheck-puppet-lint-disabled-arg-name)
+ source-original)
+ :error-patterns
+ ((warning line-start (file-name) ":" line ":warning: " (message) line-end)
+ (error line-start (file-name) ":" line ":error: " (message) line-end))
+ :modes puppet-mode
+ ;; Since we check the original file, we can only use this syntax checker if
+ ;; the buffer is actually linked to a file, and if it is not modified.
+ :predicate flycheck-buffer-saved-p)
+
+(defun flycheck-python-run-snippet (checker snippet)
+ "Run a python SNIPPET and return the output.
+
+CHECKER's executable is assumed to be a Python REPL."
+ (-when-let (output (flycheck-call-checker-process-for-output
+ checker nil nil "-c" snippet))
+ (string-trim output)))
+
+(defun flycheck-python-get-path (checker)
+ "Compute the current Python path (CHECKER is a Python REPL) ."
+ (flycheck-python-run-snippet checker "import sys; print(sys.path[1:])"))
+
+(defun flycheck-python-find-module (checker module)
+ "Check if a Python MODULE is available (CHECKER is a Python REPL)."
+ (flycheck-python-run-snippet
+ checker (concat "import sys; sys.path.pop(0);"
+ (format "import %s; print(%s.__file__)" module module))))
+
+(defun flycheck-python-needs-module-p (checker)
+ "Determines whether CHECKER needs to be invoked through Python.
+
+Previous versions of Flycheck called pylint and flake8 directly,
+while new version call them through `python -c'. This check
+ensures that we don't break existing code; it also allows people
+who use virtualenvs to run globally-installed checkers."
+ (not (string-match-p (rx (or "pylint" "pylint3" "flake8")
+ (or "-script.pyw" ".exe" ".bat" "")
+ eos)
+ (flycheck-checker-executable checker))))
+
+(defun flycheck-python-verify-module (checker module)
+ "Verify that a Python MODULE is available.
+
+Return nil if CHECKER's executable is not a Python REPL. This
+function's is suitable for a checker's :verify."
+ (when (flycheck-python-needs-module-p checker)
+ (let ((mod-path (flycheck-python-find-module checker module)))
+ (list (flycheck-verification-result-new
+ :label (format "`%s' module" module)
+ :message (if mod-path (format "Found at %S" mod-path)
+ (format "Missing; sys.path is %s"
+ (flycheck-python-get-path checker)))
+ :face (if mod-path 'success '(bold error)))))))
+
+(defun flycheck-python-module-args (checker module-name)
+ "Compute arguments to pass to CHECKER's executable to run MODULE-NAME.
+
+Return nil if CHECKER's executable is not a Python REPL.
+Otherwise, return a list starting with -c (-m is not enough
+because it adds the current directory to Python's path)."
+ (when (flycheck-python-needs-module-p checker)
+ `("-c" ,(concat "import sys;sys.path.pop(0);import runpy;"
+ (format "runpy.run_module(%S)" module-name)))))
+
+(defcustom flycheck-python-project-files
+ '("pyproject.toml" "setup.cfg" "mypy.ini" "pyrightconfig.json")
+ "Files used to find where to run Python checkers from.
+Currently used for pylint, flake8, and pyright.
+
+The presence of one in these files indicates the root of the
+current project; `.pylintrc' is not part of the list because it
+is commonly found in ~/."
+ :group 'flycheck
+ :type '(repeat (string :tag "File name"))
+ :package-version '(flycheck . "0.33")
+ :safe #'flycheck-string-list-p)
+
+(defun flycheck-python-find-project-root (_checker)
+ "Find the root directory of a Python project.
+
+The root directory is assumed to be the nearest parent directory
+that contains one of `flycheck-python-project-files'. If no such
+file is found, we use the same heuristic as epylint: the nearest
+parent directory that doesn't have a __init__.py file."
+ (let ((start (if buffer-file-name
+ (file-name-directory buffer-file-name)
+ default-directory)))
+ (or (flycheck--locate-dominating-file-matching
+ start (regexp-opt flycheck-python-project-files))
+ (locate-dominating-file
+ start (lambda (dir)
+ (not (file-exists-p (expand-file-name "__init__.py" dir))))))))
+
+(flycheck-def-config-file-var flycheck-flake8rc python-flake8 ".flake8rc")
+
+(flycheck-def-option-var flycheck-flake8-error-level-alist
+ '(("^E9.*$" . error) ; Syntax errors from pep8
+ ("^F82.*$" . error) ; undefined variables from pyflakes
+ ("^F83.*$" . error) ; Duplicate arguments from flake8
+ ("^D.*$" . info) ; Docstring issues from flake8-pep257
+ ("^N.*$" . info) ; Naming issues from pep8-naming
+ )
+ python-flake8
+ "An alist mapping flake8 error IDs to Flycheck error levels.
+
+Each item in this list is a cons cell `(PATTERN . LEVEL)' where
+PATTERN is a regular expression matched against the error ID, and
+LEVEL is a Flycheck error level symbol.
+
+Each PATTERN is matched in the order of appearance in this list
+against the error ID. If it matches the ID, the level of the
+corresponding error is set to LEVEL. An error that is not
+matched by any PATTERN defaults to warning level.
+
+The default value of this option matches errors from flake8
+itself and from the following flake8 plugins:
+
+- pep8-naming
+- flake8-pep257
+
+You may add your own mappings to this option in order to support
+further flake8 plugins."
+ :type '(repeat (cons (regexp :tag "Error ID pattern")
+ (symbol :tag "Error level")))
+ :package-version '(flycheck . "0.22"))
+
+(flycheck-def-option-var flycheck-flake8-maximum-complexity nil python-flake8
+ "The maximum McCabe complexity of methods.
+
+If nil, do not check the complexity of methods. If set to an
+integer, report any complexity greater than the value of this
+variable as warning.
+
+If set to an integer, this variable overrules any similar setting
+in the configuration file denoted by `flycheck-flake8rc'."
+ :type '(choice (const :tag "Do not check McCabe complexity" nil)
+ (integer :tag "Maximum complexity"))
+ :safe #'integerp)
+
+(flycheck-def-option-var flycheck-flake8-maximum-line-length nil python-flake8
+ "The maximum length of lines.
+
+If set to an integer, the value of this variable denotes the
+maximum length of lines, overruling any similar setting in the
+configuration file denoted by `flycheck-flake8rc'. An error will
+be reported for any line longer than the value of this variable.
+
+If set to nil, use the maximum line length from the configuration
+file denoted by `flycheck-flake8rc', or the PEP 8 recommendation
+of 79 characters if there is no configuration with this setting."
+ :type '(choice (const :tag "Default value")
+ (integer :tag "Maximum line length in characters"))
+ :safe #'integerp)
+
+(defun flycheck-flake8-fix-error-level (err)
+ "Fix the error level of ERR.
+
+Update the error level of ERR according to
+`flycheck-flake8-error-level-alist'."
+ (pcase-dolist (`(,pattern . ,level) flycheck-flake8-error-level-alist)
+ (when (string-match-p pattern (flycheck-error-id err))
+ (setf (flycheck-error-level err) level)))
+ err)
+
+(defun flycheck-flake8--find-project-root (_checker)
+ "Find setup.cfg in a parent directory of the current buffer."
+ ;; This is a workaround for `https://gitlab.com/pycqa/flake8/issues/517'; see
+ ;; also `https://github.com/flycheck/flycheck/issues/1722'
+ (locate-dominating-file (or buffer-file-name default-directory) "setup.cfg"))
+
+(flycheck-define-checker python-flake8
+ "A Python syntax and style checker using Flake8.
+
+Requires Flake8 3.0 or newer. See URL
+`https://flake8.readthedocs.io/'."
+ ;; Not calling flake8 directly makes it easier to switch between different
+ ;; Python versions; see https://github.com/flycheck/flycheck/issues/1055.
+ :command ("python3"
+ (eval (flycheck-python-module-args 'python-flake8 "flake8"))
+ "--format=default"
+ (config-file "--append-config" flycheck-flake8rc)
+ (option "--max-complexity" flycheck-flake8-maximum-complexity nil
+ flycheck-option-int)
+ (option "--max-line-length" flycheck-flake8-maximum-line-length nil
+ flycheck-option-int)
+ (eval (when buffer-file-name
+ (concat "--stdin-display-name=" buffer-file-name)))
+ "-")
+ :standard-input t
+ :working-directory flycheck-python-find-project-root
+ :error-filter (lambda (errors)
+ (let ((errors (flycheck-sanitize-errors errors)))
+ (seq-map #'flycheck-flake8-fix-error-level errors)))
+ :error-patterns
+ ((warning line-start
+ (file-name) ":" line ":" (optional column ":") " "
+ (id (one-or-more (any alpha)) (one-or-more digit)) " "
+ (message (one-or-more not-newline))
+ line-end))
+ :enabled (lambda ()
+ (or (not (flycheck-python-needs-module-p 'python-flake8))
+ (flycheck-python-find-module 'python-flake8 "flake8")))
+ :verify (lambda (_) (flycheck-python-verify-module 'python-flake8 "flake8"))
+ :modes python-mode
+ :next-checkers ((warning . python-pylint)
+ (warning . python-mypy)))
+
+(flycheck-def-config-file-var
+ flycheck-pylintrc python-pylint
+ '("pylintrc" ".pylintrc" "pyproject.toml" "setup.cfg"))
+
+(flycheck-def-option-var flycheck-pylint-use-symbolic-id t python-pylint
+ "Whether to use pylint message symbols or message codes.
+
+A pylint message has both an opaque identifying code (such as `F0401') and a
+more meaningful symbolic code (such as `import-error'). This option governs
+which should be used and reported to the user."
+ :type 'boolean
+ :safe #'booleanp
+ :package-version '(flycheck . "0.25"))
+
+(defun flycheck-parse-pylint (output checker buffer)
+ "Parse JSON OUTPUT of CHECKER on BUFFER as Pylint errors."
+ (mapcar (lambda (err)
+ (let-alist err
+ ;; Pylint can return -1 as a line or a column, hence the call to
+ ;; `max'. See `https://github.com/flycheck/flycheck/issues/1383'.
+ (flycheck-error-new-at
+ (and .line (max .line 1))
+ (and .column (max (1+ .column) 1))
+ (pcase .type
+ ;; See "pylint/utils.py"
+ ((or "fatal" "error") 'error)
+ ((or "info" "convention") 'info)
+ ((or "warning" "refactor" _) 'warning))
+ ;; Drop lines showing the error in context
+ (and (string-match (rx (*? nonl) eol) .message)
+ (match-string 0 .message))
+ :id (if flycheck-pylint-use-symbolic-id .symbol .message-id)
+ :checker checker
+ :buffer buffer
+ :filename .path)))
+ (car (flycheck-parse-json output))))
+
+(flycheck-define-checker python-pylint
+ "A Python syntax and style checker using Pylint.
+
+This syntax checker requires Pylint 1.0 or newer.
+
+See URL `https://www.pylint.org/'."
+ ;; --reports=n disables the scoring report.
+ ;; Not calling pylint directly makes it easier to switch between different
+ ;; Python versions; see https://github.com/flycheck/flycheck/issues/1055.
+ :command ("python3"
+ (eval (flycheck-python-module-args 'python-pylint "pylint"))
+ "--reports=n"
+ "--output-format=json"
+ (config-file "--rcfile=" flycheck-pylintrc concat)
+ ;; Need `source-inplace' for relative imports (e.g. `from .foo
+ ;; import bar'), see https://github.com/flycheck/flycheck/issues/280
+ source-inplace)
+ :error-parser flycheck-parse-pylint
+ :working-directory flycheck-python-find-project-root
+ :enabled (lambda ()
+ (or (not (flycheck-python-needs-module-p 'python-pylint))
+ (flycheck-python-find-module 'python-pylint "pylint")))
+ :verify (lambda (_) (flycheck-python-verify-module 'python-pylint "pylint"))
+ :error-explainer (lambda (err)
+ (-when-let (id (flycheck-error-id err))
+ (apply
+ #'flycheck-call-checker-process-for-output
+ 'python-pylint nil t
+ (append
+ (flycheck-python-module-args 'python-pylint "pylint")
+ (list (format "--help-msg=%s" id))))))
+ :modes python-mode
+ :next-checkers ((warning . python-mypy)))
+
+(flycheck-define-checker python-pycompile
+ "A Python syntax checker using Python's builtin compiler.
+
+See URL `https://docs.python.org/3.4/library/py_compile.html'."
+ :command ("python3" "-m" "py_compile" source)
+ :error-patterns
+ ;; Python 2.7
+ ((error line-start " File \"" (file-name) "\", line " line "\n"
+ (>= 2 (zero-or-more not-newline) "\n")
+ "SyntaxError: " (message) line-end)
+ (error line-start "Sorry: IndentationError: "
+ (message) "(" (file-name) ", line " line ")"
+ line-end)
+ ;; 2.6
+ (error line-start "SyntaxError: ('" (message (one-or-more (not (any "'"))))
+ "', ('" (file-name (one-or-more (not (any "'")))) "', "
+ line ", " column ", " (one-or-more not-newline) line-end))
+ :working-directory flycheck-python-find-project-root
+ :modes python-mode
+ :next-checkers ((warning . python-mypy)))
+
+(defun flycheck-pyright--parse-error (output checker buffer)
+ "Parse pyright errors/warnings from JSON OUTPUT.
+CHECKER and BUFFER denote the CHECKER that returned OUTPUT and
+the BUFFER that was checked respectively."
+ (seq-map
+ (lambda (err)
+ (let-alist err
+ (flycheck-error-new-at
+ (+ 1 .range.start.line)
+ (+ 1 .range.start.character)
+ (pcase .severity
+ ("error" 'error)
+ ("warning" 'warning)
+ (_ 'warning))
+ .message
+ :end-line (+ 1 .range.end.line)
+ :end-column (+ 1 .range.end.character)
+ :checker checker
+ :buffer buffer
+ :filename (buffer-file-name buffer))))
+ (cdr (nth 2 (car (flycheck-parse-json output))))))
+
+(flycheck-define-checker python-pyright
+ "Static type checker for Python
+
+See URL https://github.com/microsoft/pyright."
+ :command ("pyright"
+ "--outputjson"
+ source-inplace)
+ :working-directory flycheck-python-find-project-root
+ :error-parser flycheck-pyright--parse-error
+ :modes python-mode)
+
+(define-obsolete-variable-alias 'flycheck-python-mypy-ini
+ 'flycheck-python-mypy-config "32")
+
+(flycheck-def-config-file-var flycheck-python-mypy-config python-mypy
+ '("mypy.ini" "pyproject.toml" "setup.cfg"))
+
+(flycheck-def-option-var flycheck-python-mypy-cache-dir nil python-mypy
+ "Directory used to write .mypy_cache directories."
+ :type '(choice
+ (const :tag "Write to the working directory" nil)
+ (const :tag "Never write .mypy_cache directories" null-device)
+ (string :tag "Path"))
+ :safe #'flycheck-string-or-nil-p
+ :package-version '(flycheck . "32"))
+
+(flycheck-define-checker python-mypy
+ "Mypy syntax and type checker. Requires mypy>=0.580.
+
+See URL `http://mypy-lang.org/'."
+ :command ("mypy"
+ "--show-column-numbers"
+ (config-file "--config-file" flycheck-python-mypy-config)
+ (option "--cache-dir" flycheck-python-mypy-cache-dir)
+ source-original)
+ :error-patterns
+ ((error line-start (file-name) ":" line (optional ":" column)
+ ": error:" (message) line-end)
+ (warning line-start (file-name) ":" line (optional ":" column)
+ ": warning:" (message) line-end)
+ (info line-start (file-name) ":" line (optional ":" column)
+ ": note:" (message) line-end))
+ :working-directory flycheck-python-find-project-root
+ :modes python-mode
+ ;; Ensure the file is saved, to work around
+ ;; https://github.com/python/mypy/issues/4746.
+ :predicate flycheck-buffer-saved-p)
+
+(flycheck-def-option-var flycheck-lintr-caching t r-lintr
+ "Whether to enable caching in lintr.
+
+By default, lintr caches all expressions in a file and re-checks
+only those that have changed. Setting this option to nil
+disables caching in case there are problems."
+ :type 'boolean
+ :safe #'booleanp
+ :package-version '(flycheck . "0.23"))
+
+(flycheck-def-option-var flycheck-lintr-linters "default_linters" r-lintr
+ "Linters to use with lintr.
+
+The value of this variable is a string containing an R
+expression, which selects linters for lintr."
+ :type 'string
+ :risky t
+ :package-version '(flycheck . "0.23"))
+
+(defun flycheck-r-has-lintr (checker)
+ "Whether CHECKER (R) has installed the `lintr' library."
+ (eql 0 (flycheck-call-checker-process
+ checker nil nil nil
+ "--slave" "--no-restore" "--no-save" "-e"
+ "library('lintr')")))
+
+(flycheck-define-checker r-lintr
+ "An R style and syntax checker using the lintr package.
+
+See URL `https://github.com/jimhester/lintr'."
+ :command ("R" "--slave" "--no-restore" "--no-save" "-e"
+ (eval (concat
+ "library(lintr);"
+ "try(lint(commandArgs(TRUE)"
+ ", cache=" (if flycheck-lintr-caching "TRUE" "FALSE")
+ ", " flycheck-lintr-linters
+ "))"))
+ "--args" source)
+ :error-patterns
+ ((info line-start (file-name) ":" line ":" column ": style: " (message)
+ line-end)
+ (warning line-start (file-name) ":" line ":" column ": warning: " (message)
+ line-end)
+ (error line-start (file-name) ":" line ":" column ": error: " (message)
+ line-end))
+ :modes (ess-mode ess-r-mode)
+ :predicate
+ ;; Don't check ESS files which do not contain R, and make sure that lintr is
+ ;; actually available
+ (lambda ()
+ (and (equal ess-language "S")
+ (flycheck-r-has-lintr 'r-lintr)))
+ :verify (lambda (checker)
+ (let ((has-lintr (flycheck-r-has-lintr checker)))
+ (list
+ (flycheck-verification-result-new
+ :label "lintr library"
+ :message (if has-lintr "present" "missing")
+ :face (if has-lintr 'success '(bold error)))))))
+
+(defun flycheck-racket-has-expand-p (checker)
+ "Whether the executable of CHECKER provides the `expand' command."
+ (eql 0 (flycheck-call-checker-process checker nil nil nil "expand")))
+
+(flycheck-define-checker racket
+ "A Racket syntax checker with `raco expand'.
+
+The `compiler-lib' racket package is required for this syntax
+checker.
+
+See URL `https://racket-lang.org/'."
+ :command ("raco" "expand" source-inplace)
+ :predicate
+ (lambda ()
+ (and (or (not (eq major-mode 'scheme-mode))
+ ;; In `scheme-mode' we must check the current Scheme implementation
+ ;; being used
+ (and (boundp 'geiser-impl--implementation)
+ (eq geiser-impl--implementation 'racket)))
+ (flycheck-racket-has-expand-p 'racket)))
+ :verify
+ (lambda (checker)
+ (let ((has-expand (flycheck-racket-has-expand-p checker))
+ (in-scheme-mode (eq major-mode 'scheme-mode))
+ (geiser-impl (bound-and-true-p geiser-impl--implementation)))
+ (list
+ (flycheck-verification-result-new
+ :label "compiler-lib package"
+ :message (if has-expand "present" "missing")
+ :face (if has-expand 'success '(bold error)))
+ (flycheck-verification-result-new
+ :label "Geiser Implementation"
+ :message (cond
+ ((not in-scheme-mode) "Using Racket Mode")
+ ((eq geiser-impl 'racket) "Racket")
+ (geiser-impl (format "Other: %s" geiser-impl))
+ (t "Geiser not active"))
+ :face (cond
+ ((or (not in-scheme-mode) (eq geiser-impl 'racket)) 'success)
+ (t '(bold error)))))))
+ :error-filter
+ (lambda (errors)
+ (flycheck-sanitize-errors
+ (flycheck-increment-error-columns
+ (seq-remove
+ (lambda (err)
+ (string-suffix-p
+ "/share/racket/pkgs/compiler-lib/compiler/commands/expand.rkt"
+ (flycheck-error-filename err)))
+ errors))))
+ :error-patterns
+ ((error line-start (zero-or-more space)
+ (file-name) ":" line ":" column ":" (message) line-end))
+ :modes (racket-mode scheme-mode))
+
+(flycheck-define-checker rpm-rpmlint
+ "A RPM SPEC file syntax checker using rpmlint.
+
+See URL `https://github.com/rpm-software-management/rpmlint'."
+ :command ("rpmlint" source)
+ :error-patterns
+ ((error line-start
+ (file-name) ":" (optional line ":") " E: " (message)
+ line-end)
+ (warning line-start
+ (file-name) ":" (optional line ":") " W: " (message)
+ line-end))
+ :error-filter
+ ;; rpmlint 1.1 outputs a spurious error for the temp file created by flycheck
+ (lambda (errors)
+ (dolist (err (seq-remove
+ (lambda (err)
+ (string-suffix-p "(none)" (flycheck-error-filename err)))
+ errors))
+ ;; Add fake line numbers if they are missing in the lint output
+ (unless (flycheck-error-line err)
+ (setf (flycheck-error-line err) 1)))
+ errors)
+ :error-explainer
+ (lambda (error)
+ (-when-let* ((error-message (flycheck-error-message error))
+ (message-id (save-match-data
+ (string-match "\\([^ ]+\\)" error-message)
+ (match-string 1 error-message))))
+ (flycheck-call-checker-process-for-output
+ 'rpm-rpmlint nil t "-I" message-id)))
+ :modes (sh-mode rpm-spec-mode)
+ :predicate (lambda () (or (not (eq major-mode 'sh-mode))
+ ;; In `sh-mode', we need the proper shell
+ (eq sh-shell 'rpm))))
+
+(flycheck-def-config-file-var flycheck-markdown-markdownlint-cli-config
+ markdown-markdownlint-cli nil
+ :package-version '(flycheck . "32"))
+
+(flycheck-define-checker markdown-markdownlint-cli
+ "Markdown checker using markdownlint-cli.
+
+See URL `https://github.com/igorshubovych/markdownlint-cli'."
+ :command ("markdownlint"
+ (config-file "--config" flycheck-markdown-markdownlint-cli-config)
+ source)
+ :error-patterns
+ ((error line-start
+ (file-name) ":" line
+ (? ":" column) " " (id (one-or-more (not (any space))))
+ " " (message) line-end))
+ :error-filter
+ (lambda (errors)
+ (flycheck-sanitize-errors
+ (flycheck-remove-error-file-names "(string)" errors)))
+ :modes (markdown-mode gfm-mode))
+
+(flycheck-def-option-var flycheck-markdown-mdl-rules nil markdown-mdl
+ "Rules to enable for mdl.
+
+The value of this variable is a list of strings each of which is
+the name of a rule to enable.
+
+By default all rules are enabled.
+
+See URL `https://git.io/vhi2t'."
+ :type '(repeat :tag "Enabled rules"
+ (string :tag "rule name"))
+ :safe #'flycheck-string-list-p
+ :package-version '(flycheck . "27"))
+
+(flycheck-def-option-var flycheck-markdown-mdl-tags nil markdown-mdl
+ "Rule tags to enable for mdl.
+
+The value of this variable is a list of strings each of which is
+the name of a rule tag. Only rules with these tags are enabled.
+
+By default all rules are enabled.
+
+See URL `https://git.io/vhi2t'."
+ :type '(repeat :tag "Enabled tags"
+ (string :tag "tag name"))
+ :safe #'flycheck-string-list-p
+ :package-version '(flycheck . "27"))
+
+(flycheck-def-config-file-var flycheck-markdown-mdl-style markdown-mdl nil
+ :package-version '(flycheck . "27"))
+
+(flycheck-define-checker markdown-mdl
+ "Markdown checker using mdl.
+
+See URL `https://github.com/markdownlint/markdownlint'."
+ :command ("mdl"
+ (config-file "--style" flycheck-markdown-mdl-style)
+ (option "--tags=" flycheck-markdown-mdl-tags concat
+ flycheck-option-comma-separated-list)
+ (option "--rules=" flycheck-markdown-mdl-rules concat
+ flycheck-option-comma-separated-list))
+ :standard-input t
+ :error-patterns
+ ((error line-start
+ (file-name) ":" line ": " (id (one-or-more alnum)) " " (message)
+ line-end))
+ :error-filter
+ (lambda (errors)
+ (flycheck-sanitize-errors
+ (flycheck-remove-error-file-names "(stdin)" errors)))
+ :modes (markdown-mode gfm-mode))
+
+(flycheck-define-checker nix
+ "Nix checker using nix-instantiate.
+
+See URL `https://nixos.org/nix/manual/#sec-nix-instantiate'."
+ :command ("nix-instantiate" "--parse" "-")
+ :standard-input t
+ :error-patterns
+ ((error line-start
+ "error: " (message)
+ (one-or-more "\n")
+ (zero-or-more space) "at «stdin»:" line ":" column ":" line-end)
+ (error line-start
+ "at: (" line ":" column ") from stdin"
+ (one-or-more "\n" (zero-or-more space (one-or-more not-newline)))
+ (message) line-end)
+ (error line-start
+ "error: " (message) " at " (file-name) ":" line ":" column
+ line-end))
+ :error-filter
+ (lambda (errors)
+ (flycheck-sanitize-errors
+ (flycheck-remove-error-file-names "(string)" errors)))
+ :next-checkers ((warning . nix-linter))
+ :modes nix-mode)
+
+(defun flycheck-parse-nix-linter (output checker buffer)
+ "Parse nix-linter warnings from JSON OUTPUT.
+
+CHECKER and BUFFER denote the CHECKER that returned OUTPUT and
+the BUFFER that was checked respectively.
+
+See URL `https://github.com/Synthetica9/nix-linter' for more
+information about nix-linter."
+ (mapcar (lambda (err)
+ (let-alist err
+ (flycheck-error-new-at
+ .pos.spanBegin.sourceLine
+ .pos.spanBegin.sourceColumn
+ 'warning
+ .description
+ :id .offense
+ :checker checker
+ :buffer buffer
+ :filename (buffer-file-name buffer)
+ :end-line .pos.spanEnd.sourceLine
+ :end-column .pos.spanEnd.sourceColumn)))
+ (flycheck-parse-json output)))
+
+(flycheck-define-checker nix-linter
+ "Nix checker using nix-linter.
+
+See URL `https://github.com/Synthetica9/nix-linter'."
+ :command ("nix-linter" "--json-stream" "-")
+ :standard-input t
+ :error-parser flycheck-parse-nix-linter
+ :error-explainer
+ (lambda (error)
+ (-when-let (error-code (flycheck-error-id error))
+ (flycheck-call-checker-process-for-output
+ 'nix-linter nil t "--help-for" error-code)))
+ :modes nix-mode)
+
+(defun flycheck-locate-sphinx-source-directory ()
+ "Locate the Sphinx source directory for the current buffer.
+
+Return the source directory, or nil, if the current buffer is not
+part of a Sphinx project."
+ (-when-let* ((filename (buffer-file-name))
+ (dir (locate-dominating-file filename "conf.py")))
+ (expand-file-name dir)))
+
+(flycheck-define-checker rst
+ "A ReStructuredText (RST) syntax checker using Docutils.
+
+See URL `http://docutils.sourceforge.net/'."
+ ;; include:: directives
+ :command ("rst2pseudoxml.py" "--report=2" "--halt=5"
+ ;; Read from standard input and throw output away
+ "-" null-device)
+ :standard-input t
+ :error-patterns
+ ((warning line-start "<stdin>:" line ": (WARNING/2) " (message) line-end)
+ (error line-start "<stdin>:" line
+ ": (" (or "ERROR/3" "SEVERE/4") ") "
+ (message) line-end))
+ :modes rst-mode)
+
+(flycheck-def-option-var flycheck-sphinx-warn-on-missing-references t rst-sphinx
+ "Whether to warn about missing references in Sphinx.
+
+When non-nil (the default), warn about all missing references in
+Sphinx via `-n'."
+ :type 'boolean
+ :safe #'booleanp
+ :package-version '(flycheck . "0.17"))
+
+(flycheck-define-checker rst-sphinx
+ "A ReStructuredText (RST) syntax checker using Sphinx.
+
+Requires Sphinx 1.2 or newer. See URL `http://sphinx-doc.org'."
+ :command ("sphinx-build" "-b" "pseudoxml"
+ "-q" "-N" ; Reduced output and no colors
+ (option-flag "-n" flycheck-sphinx-warn-on-missing-references)
+ (eval (flycheck-locate-sphinx-source-directory))
+ temporary-directory ; Redirect the output to a temporary
+ ; directory
+ source-original) ; Sphinx needs the original document
+ :error-patterns
+ ((warning line-start (file-name) ":" line ": WARNING: " (message) line-end)
+ (error line-start
+ (file-name) ":" line
+ ": " (or "ERROR" "SEVERE") ": "
+ (message) line-end))
+ :modes rst-mode
+ :predicate (lambda () (and (flycheck-buffer-saved-p)
+ (flycheck-locate-sphinx-source-directory))))
+
+(defun flycheck-ruby--find-project-root (_checker)
+ "Compute an appropriate working-directory for flycheck-ruby.
+
+This is either a parent directory containing a Gemfile, or nil."
+ (and
+ buffer-file-name
+ (locate-dominating-file buffer-file-name "Gemfile")))
+
+(flycheck-def-config-file-var flycheck-rubocoprc ruby-rubocop ".rubocop.yml")
+
+(flycheck-def-option-var flycheck-rubocop-lint-only nil
+ (ruby-rubocop ruby-standard)
+ "Whether to only report code issues in Rubocop and Standard.
+
+When non-nil, only report code issues, via `--lint'. Otherwise
+report style issues as well."
+ :safe #'booleanp
+ :type 'boolean
+ :package-version '(flycheck . "0.16"))
+
+(defconst flycheck-ruby-rubocop-error-patterns
+ '((info line-start (file-name) ":" line ":" column ": C: "
+ (optional (id (one-or-more (not (any ":")))) ": ") (message) line-end)
+ (warning line-start (file-name) ":" line ":" column ": W: "
+ (optional (id (one-or-more (not (any ":")))) ": ") (message)
+ line-end)
+ (error line-start (file-name) ":" line ":" column ": " (or "E" "F") ": "
+ (optional (id (one-or-more (not (any ":")))) ": ") (message)
+ line-end)))
+
+(flycheck-def-executable-var ruby-rubocop "rubocop")
+(flycheck-define-command-checker 'ruby-rubocop
+ "A Ruby syntax and style checker using the RuboCop tool.
+
+You need at least RuboCop 0.34 for this syntax checker.
+
+See URL `https://rubocop.org/'."
+ ;; ruby-standard is defined based on this checker
+ :command '("rubocop"
+ "--display-cop-names"
+ "--force-exclusion"
+ "--format" "emacs"
+ ;; Explicitly disable caching to prevent Rubocop 0.35.1 and earlier
+ ;; from caching standard input. Later versions of Rubocop
+ ;; automatically disable caching with --stdin, see
+ ;; https://github.com/flycheck/flycheck/issues/844 and
+ ;; https://github.com/bbatsov/rubocop/issues/2576
+ "--cache" "false"
+ (config-file "--config" flycheck-rubocoprc)
+ (option-flag "--lint" flycheck-rubocop-lint-only)
+ ;; Rubocop takes the original file name as argument when reading
+ ;; from standard input
+ "--stdin" source-original)
+ :standard-input t
+ :working-directory #'flycheck-ruby--find-project-root
+ :error-patterns flycheck-ruby-rubocop-error-patterns
+ :modes '(enh-ruby-mode ruby-mode)
+ :next-checkers '((warning . ruby-reek)
+ (warning . ruby-rubylint)))
+
+(flycheck-def-config-file-var flycheck-ruby-standardrc ruby-standard
+ ".standard.yml")
+
+(flycheck-def-executable-var ruby-standard "standardrb")
+(flycheck-define-command-checker 'ruby-standard
+ "A Ruby syntax and style checker using the StandardRB gem.
+
+See URL `https://github.com/testdouble/standard' for more information."
+ ;; This checker is derived from ruby-rubocop; see above
+ :command '("standardrb"
+ "--display-cop-names"
+ "--force-exclusion"
+ "--format" "emacs"
+ "--cache" "false"
+ (config-file "--config" flycheck-ruby-standardrc)
+ (option-flag "--lint" flycheck-rubocop-lint-only)
+ "--stdin" source-original)
+ :standard-input t
+ :working-directory #'flycheck-ruby--find-project-root
+ :error-patterns flycheck-ruby-rubocop-error-patterns
+ :modes '(enh-ruby-mode ruby-mode)
+ :next-checkers '((warning . ruby-reek)
+ (warning . ruby-rubylint)))
+
+(flycheck-def-config-file-var flycheck-reekrc ruby-reek ".reek.yml"
+ :safe #'string-or-null-p
+ :package-version '(flycheck . "30"))
+
+(flycheck-define-checker ruby-reek
+ "A Ruby smell checker using reek.
+
+See URL `https://github.com/troessner/reek'."
+ :command ("reek" "--format" "json"
+ (config-file "--config" flycheck-reekrc)
+ source)
+ :error-parser flycheck-parse-reek
+ :modes (enh-ruby-mode ruby-mode)
+ :next-checkers ((warning . ruby-rubylint)))
+
+;; Default to `nil' to let Rubylint find its configuration file by itself, and
+;; to maintain backwards compatibility with older Rubylint and Flycheck releases
+(flycheck-def-config-file-var flycheck-rubylintrc ruby-rubylint nil)
+
+(flycheck-define-checker ruby-rubylint
+ "A Ruby syntax and code analysis checker using ruby-lint.
+
+Requires ruby-lint 2.0.2 or newer. See URL
+`https://github.com/YorickPeterse/ruby-lint'."
+ :command ("ruby-lint" "--presenter=syntastic"
+ (config-file "--config" flycheck-rubylintrc)
+ source)
+ ;; Ruby Lint can't read from standard input
+ :error-patterns
+ ((info line-start
+ (file-name) ":I:" line ":" column ": " (message) line-end)
+ (warning line-start
+ (file-name) ":W:" line ":" column ": " (message) line-end)
+ (error line-start
+ (file-name) ":E:" line ":" column ": " (message) line-end))
+ :modes (enh-ruby-mode ruby-mode))
+
+(flycheck-define-checker ruby
+ "A Ruby syntax checker using the standard Ruby interpreter.
+
+Please note that the output of different Ruby versions and
+implementations varies wildly. This syntax checker supports
+current versions of MRI and JRuby, but may break when used with
+other implementations or future versions of these
+implementations.
+
+Please consider using `ruby-rubocop' or `ruby-reek' instead.
+
+See URL `https://www.ruby-lang.org/'."
+ :command ("ruby" "-w" "-c")
+ :standard-input t
+ :error-patterns
+ ;; These patterns support output from JRuby, too, to deal with RVM or Rbenv
+ ((error line-start "SyntaxError in -:" line ": " (message) line-end)
+ (warning line-start "-:" line ":" (optional column ":")
+ " warning: " (message) line-end)
+ (error line-start "-:" line ": " (message) line-end))
+ :modes (enh-ruby-mode ruby-mode)
+ :next-checkers ((warning . ruby-rubylint)))
+
+(flycheck-define-checker ruby-jruby
+ "A Ruby syntax checker using the JRuby interpreter.
+
+This syntax checker is very primitive, and may break on future
+versions of JRuby.
+
+Please consider using `ruby-rubocop' or `ruby-rubylint' instead.
+
+See URL `http://jruby.org/'."
+ :command ("jruby" "-w" "-c")
+ :standard-input t
+ :error-patterns
+ ((error line-start "SyntaxError in -:" line ": " (message) line-end)
+ (warning line-start "-:" line ": warning: " (message) line-end)
+ (error line-start "-:" line ": " (message) line-end))
+ :modes (enh-ruby-mode ruby-mode)
+ :next-checkers ((warning . ruby-rubylint)))
+
+(flycheck-def-args-var flycheck-cargo-check-args (rust-cargo)
+ :package-version '(flycheck . "32"))
+
+(flycheck-def-args-var flycheck-rust-args (rust)
+ :package-version '(flycheck . "0.24"))
+
+(flycheck-def-option-var flycheck-rust-check-tests t (rust-cargo rust)
+ "Whether to check test code in Rust.
+
+For the `rust' checker: When non-nil, `rustc' is passed the
+`--test' flag, which will check any code marked with the
+`#[cfg(test)]' attribute and any functions marked with
+`#[test]'. Otherwise, `rustc' is not passed `--test' and test
+code will not be checked. Skipping `--test' is necessary when
+using `#![no_std]', because compiling the test runner requires
+`std'.
+
+For the `rust-cargo' checker: When non-nil, calls `cargo test
+--no-run' instead of `cargo check'."
+ :type 'boolean
+ :safe #'booleanp
+ :package-version '("flycheck" . "0.19"))
+
+(flycheck-def-option-var flycheck-rust-crate-root nil rust
+ "A path to the crate root for the current buffer.
+
+The value of this variable is either a string with the path to
+the crate root for the current buffer, or nil if the current buffer
+is a crate. A relative path is relative to the current buffer.
+
+If this variable is non nil the current buffer will only be checked
+if it is not modified, i.e. after it has been saved."
+ :type '(choice (const :tag "Unspecified" nil)
+ (file :tag "Root"))
+ :safe #'flycheck-string-or-nil-p
+ :package-version '(flycheck . "0.20"))
+(make-variable-buffer-local 'flycheck-rust-crate-root)
+
+(flycheck-def-option-var flycheck-rust-crate-type "lib" (rust-cargo rust)
+ "The type of the Rust Crate to check.
+
+For `rust-cargo', the value should be a string denoting the
+target type passed to Cargo. See
+`flycheck-rust-valid-crate-type-p' for the list of allowed
+values.
+
+For `rust', the value should be a string denoting the crate type
+for the `--crate-type' flag of rustc."
+ :type '(choice (const :tag "nil (rust/rust-cargo)" nil)
+ (const :tag "lib (rust/rust-cargo)" "lib")
+ (const :tag "bin (rust/rust-cargo)" "bin")
+ (const :tag "example (rust-cargo)" "example")
+ (const :tag "test (rust-cargo)" "test")
+ (const :tag "bench (rust-cargo)" "bench")
+ (const :tag "rlib (rust)" "rlib")
+ (const :tag "dylib (rust)" "dylib")
+ (const :tag "cdylib (rust)" "cdylib")
+ (const :tag "staticlib (rust)" "staticlib")
+ (const :tag "metadata (rust)" "metadata"))
+ :safe #'stringp
+ :package-version '(flycheck . "0.20"))
+(make-variable-buffer-local 'flycheck-rust-crate-type)
+
+(flycheck-def-option-var flycheck-rust-binary-name nil rust-cargo
+ "The name of the binary to pass to `cargo check --CRATE-TYPE'.
+
+The value of this variable is a string denoting the name of the
+target to check: usually the name of the crate, or the name of
+one of the files under `src/bin', `tests', `examples' or
+`benches'.
+
+This always requires a non-nil value, unless
+`flycheck-rust-crate-type' is `lib' or nil, in which case it is
+ignored."
+ :type '(choice (const :tag "Unspecified" nil)
+ (string :tag "Binary name"))
+ :safe #'flycheck-string-or-nil-p
+ :package-version '(flycheck . "28"))
+(make-variable-buffer-local 'flycheck-rust-binary-name)
+
+(flycheck-def-option-var flycheck-rust-features nil rust-cargo
+ "List of features to activate during build or check.
+
+The value of this variable is a list of strings denoting features
+that will be activated to build the target to check. Features will
+be passed to `cargo check --features=FEATURES'."
+ :type '(repeat :tag "Features to activate"
+ (string :tag "Feature"))
+ :safe #'flycheck-string-list-p
+ :package-version '(flycheck . "32"))
+(make-variable-buffer-local 'flycheck-rust-features)
+
+(flycheck-def-option-var flycheck-rust-library-path nil rust
+ "A list of library directories for Rust.
+
+The value of this variable is a list of strings, where each
+string is a directory to add to the library path of Rust.
+Relative paths are relative to the file being checked."
+ :type '(repeat (directory :tag "Library directory"))
+ :safe #'flycheck-string-list-p
+ :package-version '(flycheck . "0.18"))
+
+(defun flycheck--fontify-as-markdown ()
+ "Place current buffer in `markdown-view-mode' and fontify it."
+ (when (fboundp 'markdown-view-mode)
+ (let ((markdown-fontify-code-block-default-mode 'rust-mode)
+ (markdown-fontify-code-blocks-natively t)
+ (markdown-hide-markup t))
+ (markdown-view-mode)
+ (font-lock-flush)
+ (font-lock-ensure))))
+
+(defun flycheck-rust-error-explainer (error)
+ "Return an explanation for the given `flycheck-error' ERROR."
+ (-when-let (error-code (flycheck-error-id error))
+ (lambda ()
+ (flycheck-call-checker-process
+ 'rust nil standard-output t "--explain" error-code)
+ (with-current-buffer standard-output
+ (flycheck--fontify-as-markdown)))))
+
+(defun flycheck-rust-error-filter (errors)
+ "Filter ERRORS from rustc output that have no explanatory value."
+ (seq-remove
+ (lambda (err)
+ (or
+ ;; Macro errors emit a diagnostic in a phony file,
+ ;; e.g. "<println macros>".
+ (-when-let (filename (flycheck-error-filename err))
+ (string-match-p (rx "macros>" line-end) filename))
+ ;; Redundant message giving the number of failed errors
+ (-when-let (msg (flycheck-error-message err))
+ (string-match-p
+ (rx
+ (or (: "aborting due to " (optional (one-or-more num) " ")
+ "previous error")
+ (: "For more information about this error, try `rustc --explain "
+ (one-or-more alnum) "`.")))
+ msg))))
+ errors))
+
+(defun flycheck-rust-manifest-directory ()
+ "Return the nearest directory holding the Cargo manifest.
+
+Return the nearest directory containing the `Cargo.toml' manifest
+file, starting from the current buffer and using
+`locate-dominating-file'. Return nil if there is no such file,
+or if the current buffer has no file name."
+ (and buffer-file-name
+ (locate-dominating-file buffer-file-name "Cargo.toml")))
+
+(defun flycheck-rust-cargo-metadata ()
+ "Run 'cargo metadata' and return the result as parsed JSON object."
+ (car (flycheck-parse-json
+ (flycheck-call-checker-process-for-output
+ 'rust-cargo nil t
+ "metadata" "--no-deps" "--format-version" "1"))))
+
+(defun flycheck-rust-cargo-workspace-root ()
+ "Return the path to the workspace root of a Rust Cargo project.
+
+Return nil if the workspace root does not exist (for Rust
+versions inferior to 1.25)."
+ (let-alist (flycheck-rust-cargo-metadata)
+ .workspace_root))
+
+(defun flycheck-rust-cargo-has-command-p (command)
+ "Whether Cargo has COMMAND in its list of commands.
+
+Execute `cargo --list' to find out whether COMMAND is present."
+ (let ((cargo (funcall flycheck-executable-find "cargo")))
+ (member command (mapcar #'string-trim-left
+ (ignore-errors (process-lines cargo "--list"))))))
+
+(defun flycheck-rust-valid-crate-type-p (crate-type)
+ "Whether CRATE-TYPE is a valid target type for Cargo.
+
+A valid Cargo target type is one of `lib', `bin', `example',
+`test' or `bench'."
+ (member crate-type '(nil "lib" "bin" "example" "test" "bench")))
+
+(flycheck-define-checker rust-cargo
+ "A Rust syntax checker using Cargo.
+
+This syntax checker requires Rust 1.17 or newer. See URL
+`https://www.rust-lang.org'."
+ :command ("cargo"
+ (eval (if flycheck-rust-check-tests
+ "test"
+ "check"))
+ (eval (when flycheck-rust-check-tests
+ "--no-run"))
+ (eval (when flycheck-rust-crate-type
+ (concat "--" flycheck-rust-crate-type)))
+ ;; All crate targets except "lib" need a binary name
+ (eval (when (and flycheck-rust-crate-type
+ (not (string= flycheck-rust-crate-type "lib")))
+ flycheck-rust-binary-name))
+ (option "--features=" flycheck-rust-features concat
+ flycheck-option-comma-separated-list)
+ (eval flycheck-cargo-check-args)
+ "--message-format=json")
+ :error-parser flycheck-parse-cargo-rustc
+ :error-filter (lambda (errors)
+ ;; In Rust 1.25+, filenames are relative to the workspace
+ ;; root.
+ (let ((root (flycheck-rust-cargo-workspace-root)))
+ (seq-do (lambda (err)
+ ;; Some errors are crate level and do not have a
+ ;; filename
+ (when (flycheck-error-filename err)
+ (setf (flycheck-error-filename err)
+ (expand-file-name
+ (flycheck-error-filename err) root))))
+ (flycheck-rust-error-filter errors))))
+ :error-explainer flycheck-rust-error-explainer
+ :modes rust-mode
+ :predicate flycheck-buffer-saved-p
+ :enabled flycheck-rust-manifest-directory
+ :working-directory (lambda (_) (flycheck-rust-manifest-directory))
+ :verify
+ (lambda (_)
+ (and buffer-file-name
+ (let* ((has-toml (flycheck-rust-manifest-directory))
+ (valid-crate-type (flycheck-rust-valid-crate-type-p
+ flycheck-rust-crate-type))
+ (need-binary-name
+ (and flycheck-rust-crate-type
+ (not (string= flycheck-rust-crate-type "lib")))))
+ (list
+ (flycheck-verification-result-new
+ :label "Cargo.toml"
+ :message (if has-toml "Found" "Missing")
+ :face (if has-toml 'success '(bold warning)))
+ (flycheck-verification-result-new
+ :label "Crate type"
+ :message (if valid-crate-type
+ (format "%s" flycheck-rust-crate-type)
+ (format "%s (invalid, should be one of 'lib', 'bin', \
+'test', 'example' or 'bench')"
+ flycheck-rust-crate-type))
+ :face (if valid-crate-type 'success '(bold error)))
+ (flycheck-verification-result-new
+ :label "Binary name"
+ :message (cond
+ ((not need-binary-name) "Not required")
+ ((not flycheck-rust-binary-name) "Required")
+ (t (format "%s" flycheck-rust-binary-name)))
+ :face (cond
+ ((not need-binary-name) 'success)
+ ((not flycheck-rust-binary-name) '(bold error))
+ (t 'success))))))))
+
+(flycheck-define-checker rust
+ "A Rust syntax checker using Rust compiler.
+
+This syntax checker needs Rust 1.18 or newer. See URL
+`https://www.rust-lang.org'."
+ :command ("rustc"
+ (option "--crate-type" flycheck-rust-crate-type)
+ "--emit=mir" "-o" "/dev/null" ; avoid creating binaries
+ "--error-format=json"
+ (option-flag "--test" flycheck-rust-check-tests)
+ (option-list "-L" flycheck-rust-library-path concat)
+ (eval flycheck-rust-args)
+ (eval (or flycheck-rust-crate-root
+ (flycheck-substitute-argument 'source-original 'rust))))
+ :error-parser flycheck-parse-rustc
+ :error-filter flycheck-rust-error-filter
+ :error-explainer flycheck-rust-error-explainer
+ :modes rust-mode
+ :predicate flycheck-buffer-saved-p)
+
+(flycheck-define-checker rust-clippy
+ "A Rust syntax checker using clippy.
+
+See URL `https://github.com/rust-lang-nursery/rust-clippy'."
+ :command ("cargo" "clippy" "--message-format=json")
+ :error-parser flycheck-parse-cargo-rustc
+ :error-filter flycheck-rust-error-filter
+ :error-explainer flycheck-rust-error-explainer
+ :modes rust-mode
+ :predicate flycheck-buffer-saved-p
+ :enabled (lambda ()
+ (and (flycheck-rust-cargo-has-command-p "clippy")
+ (flycheck-rust-manifest-directory)))
+ :working-directory (lambda (_) (flycheck-rust-manifest-directory))
+ :verify
+ (lambda (_)
+ (and buffer-file-name
+ (let ((has-toml (flycheck-rust-manifest-directory))
+ (has-clippy (flycheck-rust-cargo-has-command-p "clippy")))
+ (list
+ (flycheck-verification-result-new
+ :label "Clippy"
+ :message (if has-clippy "Found"
+ "Cannot find the `cargo clippy' command")
+ :face (if has-clippy 'success '(bold warning)))
+ (flycheck-verification-result-new
+ :label "Cargo.toml"
+ :message (if has-toml "Found" "Missing")
+ :face (if has-toml 'success '(bold warning))))))))
+
+(defvar flycheck-sass-scss-cache-directory nil
+ "The cache directory for `sass' and `scss'.")
+
+(defun flycheck-sass-scss-cache-location ()
+ "Get the cache location for `sass' and `scss'.
+
+If no cache directory exists yet, create one and return it.
+Otherwise return the previously used cache directory."
+ (setq flycheck-sass-scss-cache-directory
+ (or flycheck-sass-scss-cache-directory
+ (make-temp-file "flycheck-sass-scss-cache" 'directory))))
+
+(flycheck-def-option-var flycheck-sass-compass nil sass
+ "Whether to enable the Compass CSS framework.
+
+When non-nil, enable the Compass CSS framework, via `--compass'."
+ :type 'boolean
+ :safe #'booleanp
+ :package-version '(flycheck . "0.16"))
+
+(flycheck-define-checker sass
+ "A Sass syntax checker using the Sass compiler.
+
+See URL `http://sass-lang.com'."
+ :command ("sass"
+ "--cache-location" (eval (flycheck-sass-scss-cache-location))
+ (option-flag "--compass" flycheck-sass-compass)
+ "--check" "--stdin")
+ :standard-input t
+ :error-patterns
+ ((error line-start
+ (or "Syntax error: " "Error: ")
+ (message (one-or-more not-newline)
+ (zero-or-more "\n"
+ (one-or-more " ")
+ (one-or-more not-newline)))
+ (optional "\r") "\n" (one-or-more " ") "on line " line
+ " of standard input"
+ line-end)
+ (warning line-start
+ "WARNING: "
+ (message (one-or-more not-newline)
+ (zero-or-more "\n"
+ (one-or-more " ")
+ (one-or-more not-newline)))
+ (optional "\r") "\n" (one-or-more " ") "on line " line
+ " of " (one-or-more not-newline)
+ line-end))
+ :modes sass-mode)
+
+(flycheck-def-config-file-var flycheck-sass-lintrc sass/scss-sass-lint
+ ".sass-lint.yml"
+ :package-version '(flycheck . "30"))
+
+(flycheck-define-checker sass/scss-sass-lint
+ "A SASS/SCSS syntax checker using sass-Lint.
+
+See URL `https://github.com/sasstools/sass-lint'."
+ :command ("sass-lint"
+ "--verbose"
+ "--no-exit"
+ "--format" "Checkstyle"
+ (config-file "--config" flycheck-sass-lintrc)
+ source)
+ :error-parser flycheck-parse-checkstyle
+ :modes (sass-mode scss-mode))
+
+(flycheck-define-checker scala
+ "A Scala syntax checker using the Scala compiler.
+
+See URL `https://www.scala-lang.org/'."
+ :command ("scalac" "-Ystop-after:parser" source)
+ :error-patterns
+ ((error line-start (file-name) ":" line ": error: " (message) line-end))
+ :modes scala-mode
+ :next-checkers ((warning . scala-scalastyle)))
+
+(flycheck-def-config-file-var flycheck-scalastylerc scala-scalastyle nil
+ :package-version '(flycheck . "0.20"))
+
+(flycheck-define-checker scala-scalastyle
+ "A Scala style checker using scalastyle.
+
+Note that this syntax checker is not used if
+`flycheck-scalastylerc' is nil or refers to a non-existing file.
+
+See URL `http://www.scalastyle.org'."
+ :command ("scalastyle"
+ (config-file "-c" flycheck-scalastylerc)
+ source)
+ :error-patterns
+ ((error line-start "error file=" (file-name) " message="
+ (message) " line=" line (optional " column=" column) line-end)
+ (warning line-start "warning file=" (file-name) " message="
+ (message) " line=" line (optional " column=" column) line-end))
+ :error-filter (lambda (errors)
+ (flycheck-sanitize-errors
+ (flycheck-increment-error-columns errors)))
+ :modes scala-mode
+ :predicate
+ ;; Inhibit this syntax checker if the JAR or the configuration are unset or
+ ;; missing
+ (lambda () (and flycheck-scalastylerc
+ (flycheck-locate-config-file flycheck-scalastylerc
+ 'scala-scalastyle)))
+ :verify (lambda (checker)
+ (let ((config-file (and flycheck-scalastylerc
+ (flycheck-locate-config-file
+ flycheck-scalastylerc checker))))
+ (list
+ (flycheck-verification-result-new
+ :label "Configuration file"
+ :message (cond
+ ((not flycheck-scalastylerc)
+ "`flycheck-scalastyletrc' not set")
+ ((not config-file)
+ (format "file %s not found" flycheck-scalastylerc))
+ (t (format "found at %s" config-file)))
+ :face (cond
+ ((not flycheck-scalastylerc) '(bold warning))
+ ((not config-file) '(bold error))
+ (t 'success)))))))
+
+(flycheck-def-args-var flycheck-scheme-chicken-args scheme-chicken
+ :package-version '(flycheck . "32"))
+
+(flycheck-define-checker scheme-chicken
+ "A CHICKEN Scheme syntax checker using the CHICKEN compiler `csc'.
+
+See URL `http://call-cc.org/'."
+ :command ("csc" "-analyze-only" "-local"
+ (eval flycheck-scheme-chicken-args)
+ source)
+ :error-patterns
+ ((info line-start
+ "Note: " (zero-or-more not-newline) ":\n"
+ (one-or-more (any space)) "(" (file-name) ":" line ") " (message)
+ line-end)
+ (warning line-start
+ "Warning: " (zero-or-more not-newline) ",\n"
+ (one-or-more (any space)) (zero-or-more not-newline) ":\n"
+ (one-or-more (any space)) "(" (file-name) ":" line ") " (message)
+ line-end)
+ (warning line-start
+ "Warning: " (zero-or-more not-newline) ":\n"
+ (one-or-more (any space)) "(" (file-name) ":" line ") " (message)
+ line-end)
+ (error line-start "Error: (line " line ") " (message) line-end)
+ (error line-start "Syntax error: (" (file-name) ":" line ")"
+ (zero-or-more not-newline) " - "
+ (message (one-or-more not-newline)
+ (zero-or-more "\n"
+ (zero-or-more space)
+ (zero-or-more not-newline))
+ (one-or-more space) "<--")
+ line-end)
+ ;; A of version 4.12.0, the chicken compiler doesn't provide a
+ ;; line number for this error.
+ (error line-start "Syntax error: "
+ (message (one-or-more not-newline)
+ (zero-or-more "\n"
+ (zero-or-more space)
+ (zero-or-more not-newline))
+ (one-or-more space) "<--")
+ line-end)
+ (error line-start
+ "Error: " (zero-or-more not-newline) ":\n"
+ (one-or-more (any space)) "(" (file-name) ":" line ") " (message)
+ line-end)
+ ;; A of version 4.12.0, the chicken compiler doesn't provide a
+ ;; line number for this error.
+ (error line-start "Error: "
+ (message (one-or-more not-newline)
+ (zero-or-more "\n"
+ (zero-or-more space)
+ (zero-or-more not-newline))
+ (one-or-more space) "<--")))
+ :error-filter flycheck-fill-empty-line-numbers
+ :predicate
+ (lambda ()
+ ;; In `scheme-mode' we must check the current Scheme implementation
+ ;; being used
+ (and (boundp 'geiser-impl--implementation)
+ (eq geiser-impl--implementation 'chicken)))
+ :verify
+ (lambda (_checker)
+ (let ((geiser-impl (bound-and-true-p geiser-impl--implementation)))
+ (list
+ (flycheck-verification-result-new
+ :label "Geiser Implementation"
+ :message (cond
+ ((eq geiser-impl 'chicken) "Chicken Scheme")
+ (geiser-impl (format "Other: %s" geiser-impl))
+ (t "Geiser not active"))
+ :face (cond
+ ((eq geiser-impl 'chicken) 'success)
+ (t '(bold error)))))))
+ :modes scheme-mode)
+
+(defconst flycheck-scss-lint-checkstyle-re
+ (rx "cannot load such file" (1+ not-newline) "scss_lint_reporter_checkstyle")
+ "Regular expression to parse missing checkstyle error.")
+
+(defun flycheck-parse-scss-lint (output checker buffer)
+ "Parse SCSS-Lint OUTPUT from CHECKER and BUFFER.
+
+Like `flycheck-parse-checkstyle', but catches errors about
+missing checkstyle reporter from SCSS-Lint."
+ (if (string-match-p flycheck-scss-lint-checkstyle-re output)
+ (list (flycheck-error-new-at
+ 1 nil 'error "Checkstyle reporter for SCSS-Lint missing.
+Please run gem install scss_lint_reporter_checkstyle"
+ :checker checker
+ :buffer buffer
+ :filename (buffer-file-name buffer)))
+ (flycheck-parse-checkstyle output checker buffer)))
+
+(flycheck-def-config-file-var flycheck-scss-lintrc scss-lint ".scss-lint.yml"
+ :package-version '(flycheck . "0.23"))
+
+(flycheck-define-checker scss-lint
+ "A SCSS syntax checker using SCSS-Lint.
+
+Needs SCSS-Lint 0.43.2 or newer.
+
+See URL `https://github.com/brigade/scss-lint'."
+ :command ("scss-lint"
+ "--require=scss_lint_reporter_checkstyle"
+ "--format=Checkstyle"
+ (config-file "--config" flycheck-scss-lintrc)
+ "--stdin-file-path" source-original "-")
+ :standard-input t
+ ;; We cannot directly parse Checkstyle XML, since for some mysterious reason
+ ;; SCSS-Lint doesn't have a built-in Checkstyle reporter, and instead ships it
+ ;; as an addon which might not be installed. We use a custom error parser to
+ ;; check whether the addon is missing and turn that into a special kind of
+ ;; Flycheck error.
+ :error-parser flycheck-parse-scss-lint
+ :modes scss-mode
+ :verify
+ (lambda (checker)
+ (-when-let
+ (output (flycheck-call-checker-process-for-output
+ checker nil nil "--require=scss_lint_reporter_checkstyle"))
+ (let ((reporter-missing
+ (string-match-p flycheck-scss-lint-checkstyle-re output)))
+ (list
+ (flycheck-verification-result-new
+ :label "checkstyle reporter"
+ :message (if reporter-missing
+ "scss_lint_reporter_checkstyle plugin missing"
+ "present")
+ :face (if reporter-missing
+ '(bold error)
+ 'success)))))))
+
+(flycheck-define-checker scss-stylelint
+ "A SCSS syntax and style checker using stylelint.
+
+See URL `http://stylelint.io/'."
+ :command ("stylelint"
+ (eval flycheck-stylelint-args)
+ "--syntax" "scss"
+ (option-flag "--quiet" flycheck-stylelint-quiet)
+ (config-file "--config" flycheck-stylelintrc))
+ :standard-input t
+ :error-parser flycheck-parse-stylelint
+ :predicate flycheck-buffer-nonempty-p
+ :modes (scss-mode))
+
+(flycheck-def-option-var flycheck-scss-compass nil scss
+ "Whether to enable the Compass CSS framework.
+
+When non-nil, enable the Compass CSS framework, via `--compass'."
+ :type 'boolean
+ :safe #'booleanp
+ :package-version '(flycheck . "0.16"))
+
+(flycheck-define-checker scss
+ "A SCSS syntax checker using the SCSS compiler.
+
+See URL `http://sass-lang.com'."
+ :command ("scss"
+ "--cache-location" (eval (flycheck-sass-scss-cache-location))
+ (option-flag "--compass" flycheck-scss-compass)
+ "--check" "--stdin")
+ :standard-input t
+ :error-patterns
+ ((error line-start
+ (or "Syntax error: " "Error: ")
+ (message (one-or-more not-newline)
+ (zero-or-more "\n"
+ (one-or-more " ")
+ (one-or-more not-newline)))
+ (optional "\r") "\n" (one-or-more " ") "on line " line
+ " of standard input"
+ line-end)
+ (warning line-start
+ "WARNING: "
+ (message (one-or-more not-newline)
+ (zero-or-more "\n"
+ (one-or-more " ")
+ (one-or-more not-newline)))
+ (optional "\r") "\n" (one-or-more " ") "on line " line
+ " of an unknown file"
+ line-end))
+ :modes scss-mode)
+
+(flycheck-def-args-var flycheck-sh-bash-args (sh-bash)
+ :package-version '(flycheck . "32"))
+
+(flycheck-define-checker sh-bash
+ "A Bash syntax checker using the Bash shell.
+
+See URL `http://www.gnu.org/software/bash/'."
+ :command ("bash" "--norc" "-n"
+ (eval flycheck-sh-bash-args)
+ "--")
+ :standard-input t
+ :error-patterns
+ ((error line-start
+ ;; The name/path of the bash executable
+ (one-or-more (not (any ":"))) ":"
+ ;; A label "line", possibly localized
+ (one-or-more (not (any digit)))
+ line (zero-or-more " ") ":" (zero-or-more " ")
+ (message) line-end))
+ :modes sh-mode
+ :predicate (lambda () (eq sh-shell 'bash))
+ :next-checkers ((warning . sh-shellcheck)))
+
+(flycheck-define-checker sh-posix-dash
+ "A POSIX Shell syntax checker using the Dash shell.
+
+See URL `http://gondor.apana.org.au/~herbert/dash/'."
+ :command ("dash" "-n")
+ :standard-input t
+ :error-patterns
+ ((error line-start (one-or-more (not (any ":"))) ": " line ": " (message)))
+ :modes sh-mode
+ :predicate (lambda () (eq sh-shell 'sh))
+ :next-checkers ((warning . sh-shellcheck)))
+
+(flycheck-define-checker sh-posix-bash
+ "A POSIX Shell syntax checker using the Bash shell.
+
+See URL `http://www.gnu.org/software/bash/'."
+ :command ("bash" "--posix" "--norc" "-n" "--")
+ :standard-input t
+ :error-patterns
+ ((error line-start
+ ;; The name/path of the bash executable
+ (one-or-more (not (any ":"))) ":"
+ ;; A label "line", possibly localized
+ (one-or-more (not (any digit)))
+ line (zero-or-more " ") ":" (zero-or-more " ")
+ (message) line-end))
+ :modes sh-mode
+ :predicate (lambda () (eq sh-shell 'sh))
+ :next-checkers ((warning . sh-shellcheck)))
+
+(flycheck-define-checker sh-zsh
+ "A Zsh syntax checker using the Zsh shell.
+
+See URL `http://www.zsh.org/'."
+ :command ("zsh" "--no-exec" "--no-globalrcs" "--no-rcs" source)
+ :error-patterns
+ ((error line-start (file-name) ":" line ": " (message) line-end))
+ :modes sh-mode
+ :predicate (lambda () (eq sh-shell 'zsh))
+ :next-checkers ((warning . sh-shellcheck)))
+
+(defconst flycheck-shellcheck-supported-shells '(bash ksh88 sh)
+ "Shells supported by ShellCheck.")
+
+(flycheck-def-option-var flycheck-shellcheck-excluded-warnings nil sh-shellcheck
+ "A list of excluded warnings for ShellCheck.
+
+The value of this variable is a list of strings, where each
+string is a warning code to be excluded from ShellCheck reports.
+By default, no warnings are excluded."
+ :type '(repeat :tag "Excluded warnings"
+ (string :tag "Warning code"))
+ :safe #'flycheck-string-list-p
+ :package-version '(flycheck . "0.21"))
+
+(flycheck-def-option-var flycheck-shellcheck-follow-sources t sh-shellcheck
+ "Whether to follow external sourced files in scripts.
+
+Shellcheck will follow and parse sourced files so long as a
+pre-runtime resolvable path to the file is present. This can
+either be part of the source command itself:
+ source /full/path/to/file.txt
+or added as a shellcheck directive before the source command:
+ # shellcheck source=/full/path/to/file.txt."
+ :type 'boolean
+ :safe #'booleanp
+ :package-version '(flycheck . "31"))
+
+(flycheck-define-checker sh-shellcheck
+ "A shell script syntax and style checker using Shellcheck.
+
+See URL `https://github.com/koalaman/shellcheck/'."
+ :command ("shellcheck"
+ "--format" "checkstyle"
+ "--shell" (eval (symbol-name sh-shell))
+ (option-flag "--external-sources"
+ flycheck-shellcheck-follow-sources)
+ (option "--exclude" flycheck-shellcheck-excluded-warnings list
+ flycheck-option-comma-separated-list)
+ "-")
+ :standard-input t
+ :error-parser flycheck-parse-checkstyle
+ :error-filter
+ (lambda (errors)
+ (flycheck-remove-error-file-names
+ "-" (flycheck-dequalify-error-ids errors)))
+ :modes sh-mode
+ :predicate (lambda () (memq sh-shell flycheck-shellcheck-supported-shells))
+ :verify (lambda (_)
+ (let ((supports-shell (memq sh-shell
+ flycheck-shellcheck-supported-shells)))
+ (list
+ (flycheck-verification-result-new
+ :label (format "Shell %s supported" sh-shell)
+ :message (if supports-shell "yes" "no")
+ :face (if supports-shell 'success '(bold warning))))))
+ :error-explainer
+ (lambda (err)
+ (let ((error-code (flycheck-error-id err))
+ (url "https://github.com/koalaman/shellcheck/wiki/%s"))
+ (and error-code `(url . ,(format url error-code))))))
+
+(flycheck-define-checker slim
+ "A Slim syntax checker using the Slim compiler.
+
+See URL `http://slim-lang.com'."
+ :command ("slimrb" "--compile")
+ :standard-input t
+ :error-patterns
+ ((error line-start
+ "Slim::Parser::SyntaxError:" (message) (optional "\r") "\n "
+ "STDIN, Line " line (optional ", Column " column)
+ line-end))
+ :modes slim-mode
+ :next-checkers ((warning . slim-lint)))
+
+(flycheck-define-checker slim-lint
+ "A Slim linter.
+
+See URL `https://github.com/sds/slim-lint'."
+ :command ("slim-lint" "--reporter=checkstyle" source)
+ :error-parser flycheck-parse-checkstyle
+ :modes slim-mode)
+
+(flycheck-define-checker sql-sqlint
+ "A SQL syntax checker using the sqlint tool.
+
+See URL `https://github.com/purcell/sqlint'."
+ :command ("sqlint")
+ :standard-input t
+ :error-patterns
+ ((warning line-start "stdin:" line ":" column ":WARNING "
+ (message (one-or-more not-newline)
+ (zero-or-more "\n"
+ (one-or-more " ")
+ (one-or-more not-newline)))
+ line-end)
+ (error line-start "stdin:" line ":" column ":ERROR "
+ (message (one-or-more not-newline)
+ (zero-or-more "\n"
+ (one-or-more " ")
+ (one-or-more not-newline)))
+ line-end))
+ :modes (sql-mode))
+
+(flycheck-define-checker systemd-analyze
+ "A systemd unit checker using systemd-analyze(1).
+
+See URL
+`https://www.freedesktop.org/software/systemd/man/systemd-analyze.html'."
+ :command ("systemd-analyze" "verify" source)
+ :error-parser flycheck-parse-with-patterns-without-color
+ :error-patterns
+ ((error line-start (file-name) ":" (optional line ":") (message) line-end)
+ (error line-start "[" (file-name) ":" line "]" (message) line-end))
+ :error-filter (lambda (errors)
+ (flycheck-sanitize-errors
+ (flycheck-fill-empty-line-numbers errors)))
+ :modes (systemd-mode))
+
+(flycheck-def-config-file-var flycheck-chktexrc tex-chktex ".chktexrc")
+
+(flycheck-define-checker tcl-nagelfar
+ "An extensible tcl syntax checker
+
+See URL `http://nagelfar.sourceforge.net/'."
+ :command ("nagelfar" "-H" source)
+ :error-patterns
+ ;; foo.tcl: 29: E Wrong number of arguments (4) to "set"
+ ;; foo.tcl: 29: W Expr without braces
+ ((info line-start (file-name) ": " line ": N " (message) line-end)
+ (warning line-start (file-name) ": " line ": W " (message) line-end)
+ (error line-start (file-name) ": " line ": E " (message) line-end))
+ :modes tcl-mode)
+
+(flycheck-define-checker terraform
+ "A Terraform syntax checker with `terraform fmt'.
+
+See URL `https://www.terraform.io/docs/commands/fmt.html'."
+ :command ("terraform" "fmt" "-no-color" "-")
+ :standard-input t
+ :error-patterns
+ ((error line-start "Error: " (one-or-more not-newline)
+ "\n\n on <stdin> line " line ", in " (one-or-more not-newline) ":"
+ (one-or-more "\n" (zero-or-more space (one-or-more not-newline)))
+ (message (one-or-more (and (one-or-more (not (any ?\n))) ?\n)))
+ line-end)
+ (error line-start "Error: " (one-or-more not-newline)
+ "\n\n on <stdin> line " line ":\n (source code not available)\n\n"
+ (message (one-or-more (and (one-or-more (not (any ?\n))) ?\n)))
+ line-end))
+ :next-checkers ((warning . terraform-tflint))
+ :modes terraform-mode)
+
+(flycheck-def-option-var flycheck-tflint-variable-files nil terraform-tflint
+ "A list of files to resolve terraform variables.
+
+The value of this variable is a list of strings, where each
+string is a file to add to the terraform variables files.
+Relative files are relative to the file being checked."
+ :type '(repeat (directory :tag "Variable file"))
+ :safe #'flycheck-string-list-p
+ :package-version '(flycheck . "32"))
+
+(defun flycheck-parse-tflint-linter (output checker buffer)
+ "Parse tflint warnings from JSON OUTPUT.
+
+CHECKER and BUFFER denote the CHECKER that returned OUTPUT and
+the BUFFER that was checked respectively.
+
+See URL `https://github.com/wata727/tflint' for more
+information about tflint."
+ (mapcar (lambda (err)
+ (let-alist err
+ (flycheck-error-new-at
+ .range.start.line
+ .range.start.column
+ (pcase .rule.severity
+ ("error" 'error)
+ ("warning" 'warning)
+ (_ 'error))
+ .message
+ :end-line .range.end.line
+ :end-column .range.end.column
+ :id .rule.name
+ :checker checker
+ :buffer buffer
+ :filename (buffer-file-name buffer))))
+ (cdr (assq 'issues (car (flycheck-parse-json output))))))
+
+(flycheck-define-checker terraform-tflint
+ "A Terraform checker using tflint.
+
+See URL `https://github.com/wata727/tflint'."
+ :command ("tflint" "--format=json"
+ (option-list "--var-file=" flycheck-tflint-variable-files concat)
+ source-original)
+ :error-parser flycheck-parse-tflint-linter
+ :predicate flycheck-buffer-saved-p
+ :modes terraform-mode)
+
+(flycheck-define-checker tex-chktex
+ "A TeX and LaTeX syntax and style checker using chktex.
+
+See URL `http://www.nongnu.org/chktex/'."
+ :command ("chktex"
+ (config-file "--localrc" flycheck-chktexrc)
+ ;; Compact error messages, and no version information, and execute
+ ;; \input statements
+ "--verbosity=0" "--quiet" "--inputfiles")
+ :standard-input t
+ :error-patterns
+ ((warning line-start "stdin:" line ":" column ":"
+ (id (one-or-more digit)) ":" (message) line-end))
+ :error-filter
+ (lambda (errors)
+ (flycheck-sanitize-errors (flycheck-increment-error-columns errors)))
+ :modes (latex-mode plain-tex-mode))
+
+(flycheck-define-checker tex-lacheck
+ "A LaTeX syntax and style checker using lacheck.
+
+See URL `http://www.ctan.org/pkg/lacheck'."
+ :command ("lacheck" source-inplace)
+ :error-patterns
+ ((warning line-start
+ "\"" (file-name) "\", line " line ": " (message)
+ line-end))
+ :modes latex-mode)
+
+(flycheck-define-checker texinfo
+ "A Texinfo syntax checker using makeinfo.
+
+See URL `http://www.gnu.org/software/texinfo/'."
+ :command ("makeinfo" "-o" null-device "-")
+ :standard-input t
+ :error-patterns
+ ((warning line-start
+ "-:" line (optional ":" column) ": " "warning: " (message)
+ line-end)
+ (error line-start
+ "-:" line (optional ":" column) ": " (message)
+ line-end))
+ :modes texinfo-mode)
+
+(flycheck-def-config-file-var flycheck-textlint-config
+ textlint "textlintrc.json")
+
+;; This needs to be set because textlint plugins are installed separately,
+;; and there is no way to check their installation status -- textlint simply
+;; prints a backtrace.
+(flycheck-def-option-var flycheck-textlint-plugin-alist
+ '((markdown-mode . "@textlint/markdown")
+ (gfm-mode . "@textlint/markdown")
+ (t . "@textlint/text"))
+ textlint
+ "An alist mapping major modes to textlint plugins.
+
+Each item is a cons cell `(MAJOR-MODE . PLUGIN)', where MAJOR-MODE is a mode
+`flycheck-textlint' supports and PLUGIN is a textlint plugin. As a catch-all,
+when MAJOR-MODE is t, that PLUGIN will be used for any supported mode that
+isn't specified.
+
+See URL `https://npms.io/search?q=textlint-plugin' for all textlint plugins
+published on NPM."
+ :type '(repeat (choice (cons symbol string)
+ (cons (const t) string))))
+
+(defun flycheck--textlint-get-plugin ()
+ "Return the textlint plugin for the current mode."
+ (cdr (-first
+ (lambda (arg)
+ (pcase-let ((`(,mode . _) arg))
+ (or (and (booleanp mode) mode) ; mode is t
+ (derived-mode-p mode))))
+ flycheck-textlint-plugin-alist)))
+
+(flycheck-define-checker textlint
+ "A text prose linter using textlint.
+
+See URL `https://textlint.github.io/'."
+ :command ("textlint"
+ (config-file "--config" flycheck-textlint-config)
+ "--format" "json"
+ ;; get the first matching plugin from plugin-alist
+ "--plugin"
+ (eval (flycheck--textlint-get-plugin))
+ source)
+ ;; textlint seems to say that its json output is compatible with ESLint.
+ ;; https://textlint.github.io/docs/formatter.html
+ :error-parser flycheck-parse-eslint
+ ;; textlint can support different formats with textlint plugins, but
+ ;; only text and markdown formats are installed by default. Ask the
+ ;; user to add mode->plugin mappings manually in
+ ;; `flycheck-textlint-plugin-alist'.
+ :modes
+ (text-mode markdown-mode gfm-mode message-mode adoc-mode
+ mhtml-mode latex-mode org-mode rst-mode)
+ :enabled
+ (lambda () (flycheck--textlint-get-plugin))
+ :verify
+ (lambda (_)
+ (let ((plugin (flycheck--textlint-get-plugin)))
+ (list
+ (flycheck-verification-result-new
+ :label "textlint plugin"
+ :message plugin
+ :face 'success)))))
+
+(flycheck-def-config-file-var flycheck-typescript-tslint-config
+ typescript-tslint "tslint.json"
+ :package-version '(flycheck . "27"))
+
+(flycheck-def-option-var flycheck-typescript-tslint-rulesdir
+ nil typescript-tslint
+ "The directory of custom rules for TSLint.
+
+The value of this variable is either a string containing the path
+to a directory with custom rules, or nil, to not give any custom
+rules to TSLint.
+
+Refer to the TSLint manual at URL
+`http://palantir.github.io/tslint/usage/cli/'
+for more information about the custom directory."
+ :type '(choice (const :tag "No custom rules directory" nil)
+ (directory :tag "Custom rules directory"))
+ :safe #'flycheck-string-or-nil-p
+ :package-version '(flycheck . "27"))
+
+(flycheck-def-args-var flycheck-tslint-args (typescript-tslint)
+ :package-version '(flycheck . "31"))
+
+(flycheck-define-checker typescript-tslint
+ "TypeScript style checker using TSLint.
+
+Note that this syntax checker is not used if
+`flycheck-typescript-tslint-config' is nil or refers to a
+non-existing file.
+
+See URL `https://github.com/palantir/tslint'."
+ :command ("tslint" "--format" "json"
+ (config-file "--config" flycheck-typescript-tslint-config)
+ (option "--rules-dir" flycheck-typescript-tslint-rulesdir)
+ (eval flycheck-tslint-args)
+ source-inplace)
+ :error-parser flycheck-parse-tslint
+ :modes (typescript-mode))
+
+(flycheck-def-option-var flycheck-verilator-include-path nil verilog-verilator
+ "A list of include directories for Verilator.
+
+The value of this variable is a list of strings, where each
+string is a directory to add to the include path of Verilator.
+Relative paths are relative to the file being checked."
+ :type '(repeat (directory :tag "Include directory"))
+ :safe #'flycheck-string-list-p
+ :package-version '(flycheck . "0.24"))
+
+(flycheck-define-checker verilog-verilator
+ "A Verilog syntax checker using the Verilator Verilog HDL simulator.
+
+See URL `https://www.veripool.org/wiki/verilator'."
+ :command ("verilator" "--lint-only" "-Wall" "--quiet-exit"
+ (option-list "-I" flycheck-verilator-include-path concat)
+ source)
+ :error-patterns
+ ((warning line-start "%Warning"
+ (? "-" (id (+ (any "0-9A-Z_")))) ": "
+ (? (file-name) ":" line ":" (? column ":") " ")
+ (message) line-end)
+ (error line-start "%Error"
+ (? "-" (id (+ (any "0-9A-Z_")))) ": "
+ (? (file-name) ":" line ":" (? column ":") " ")
+ (message) line-end))
+ :modes verilog-mode)
+
+(flycheck-def-option-var flycheck-ghdl-language-standard nil vhdl-ghdl
+ "The language standard to use in GHDL.
+
+The value of this variable is either a string denoting a language
+standard, or nil, to use the default standard. When non-nil,
+pass the language standard via the `--std' option."
+ :type '(choice (const :tag "Default standard" nil)
+ (string :tag "Language standard"))
+ :safe #'flycheck-string-or-nil-p
+ :package-version '(flycheck . "32"))
+(make-variable-buffer-local 'flycheck-ghdl-language-standard)
+
+(flycheck-def-option-var flycheck-ghdl-workdir nil vhdl-ghdl
+ "The directory to use for the file library.
+
+The value of this variable is either a string with the directory
+to use for the file library, or nil, to use the default value.
+When non-nil, pass the directory via the `--workdir' option."
+ :type '(choice (const :tag "Default directory" nil)
+ (string :tag "Directory for the file library"))
+ :safe #'flycheck-string-or-nil-p
+ :package-version '(flycheck . "32"))
+(make-variable-buffer-local 'flycheck-ghdl-workdir)
+
+(flycheck-def-option-var flycheck-ghdl-ieee-library nil vhdl-ghdl
+ "The standard to use for the IEEE library.
+
+The value of this variable is either a string denoting an ieee library
+standard, or nil, to use the default standard. When non-nil,
+pass the ieee library standard via the `--ieee' option."
+ :type '(choice (const :tag "Default standard" nil)
+ (const :tag "No IEEE Library" "none")
+ (const :tag "IEEE standard" "standard")
+ (const :tag "Synopsys standard" "synopsys")
+ (const :tag "Mentor standard" "mentor"))
+ :safe #'flycheck-string-or-nil-p
+ :package-version '(flycheck . "32"))
+(make-variable-buffer-local 'flycheck-ghdl-ieee-library)
+
+(flycheck-define-checker vhdl-ghdl
+ "A VHDL syntax checker using GHDL.
+
+See URL `https://github.com/ghdl/ghdl'."
+ :command ("ghdl"
+ "-s" ; only do the syntax checking
+ (option "--std=" flycheck-ghdl-language-standard concat)
+ (option "--workdir=" flycheck-ghdl-workdir concat)
+ (option "--ieee=" flycheck-ghdl-ieee-library concat)
+ source)
+ :error-patterns
+ ((error line-start (file-name) ":" line ":" column ": " (message) line-end))
+ :modes vhdl-mode)
+
+(flycheck-def-option-var flycheck-xml-xmlstarlet-xsd-path nil xml-xmlstarlet
+ "An XSD schema to validate against."
+ :type '(choice (const :tag "None" nil)
+ (file :tag "XSD schema"))
+ :safe #'flycheck-string-or-nil-p
+ :package-version '(flycheck . "31"))
+
+(flycheck-define-checker xml-xmlstarlet
+ "A XML syntax checker and validator using the xmlstarlet utility.
+
+See URL `http://xmlstar.sourceforge.net/'."
+ ;; Validate standard input with verbose error messages, and do not dump
+ ;; contents to standard output
+ :command ("xmlstarlet" "val" "--err" "--quiet"
+ (option "--xsd" flycheck-xml-xmlstarlet-xsd-path)
+ "-")
+ :standard-input t
+ :error-patterns
+ ((error line-start "-:" line "." column ": " (message) line-end))
+ :modes (xml-mode nxml-mode))
+
+(flycheck-def-option-var flycheck-xml-xmllint-xsd-path nil xml-xmllint
+ "An XSD schema to validate against."
+ :type '(choice (const :tag "None" nil)
+ (file :tag "XSD schema"))
+ :safe #'flycheck-string-or-nil-p
+ :package-version '(flycheck . "31"))
+
+(flycheck-define-checker xml-xmllint
+ "A XML syntax checker and validator using the xmllint utility.
+
+The xmllint is part of libxml2, see URL
+`http://www.xmlsoft.org/'."
+ :command ("xmllint" "--noout"
+ (option "--schema" flycheck-xml-xmllint-xsd-path)
+ "-")
+ :standard-input t
+ :error-patterns
+ ((error line-start "-:" line ": " (message) line-end))
+ :modes (xml-mode nxml-mode))
+
+(flycheck-define-checker yaml-jsyaml
+ "A YAML syntax checker using JS-YAML.
+
+See URL `https://github.com/nodeca/js-yaml'."
+ :command ("js-yaml")
+ :standard-input t
+ :error-patterns
+ ((error line-start
+ (or "JS-YAML" "YAMLException") ": "
+ (message) " at line " line ", column " column ":"
+ line-end)
+ (error line-start
+ (or "JS-YAML" "YAMLException") ": "
+ (message) " (" line ":" column ")"
+ line-end))
+ :modes yaml-mode
+ :next-checkers ((warning . yaml-yamllint)
+ (warning . cwl)))
+
+(flycheck-define-checker yaml-ruby
+ "A YAML syntax checker using Ruby's YAML parser.
+
+This syntax checker uses the YAML parser from Ruby's standard
+library.
+
+See URL `http://www.ruby-doc.org/stdlib-2.0.0/libdoc/yaml/rdoc/YAML.html'."
+ :command ("ruby" "-ryaml" "-e" "begin;
+ YAML.load(STDIN); \
+ rescue Exception => e; \
+ STDERR.puts \"stdin:#{e}\"; \
+ end")
+ :standard-input t
+ :error-patterns
+ ((error line-start "stdin:" (zero-or-more not-newline) ":" (message)
+ "at line " line " column " column line-end))
+ :modes yaml-mode
+ :next-checkers ((warning . yaml-yamllint)
+ (warning . cwl)))
+
+(flycheck-def-config-file-var flycheck-yamllintrc yaml-yamllint ".yamllint")
+
+(flycheck-define-checker yaml-yamllint
+ "A YAML syntax checker using YAMLLint.
+See URL `https://github.com/adrienverge/yamllint'."
+ :standard-input t
+ :command ("yamllint" "-f" "parsable" "-"
+ (config-file "-c" flycheck-yamllintrc))
+ :error-patterns
+ ((error line-start
+ "stdin:" line ":" column ": [error] " (message) line-end)
+ (warning line-start
+ "stdin:" line ":" column ": [warning] " (message) line-end))
+ :modes yaml-mode
+ :next-checkers ((warning . cwl)))
+
+(provide 'flycheck)
+
+;; Local Variables:
+;; coding: utf-8
+;; indent-tabs-mode: nil
+;; End:
+
+;;; flycheck.el ends here
diff --git a/elpa/flycheck-20220504.830/flycheck.elc b/elpa/flycheck-20220504.830/flycheck.elc
new file mode 100644
index 0000000..7264d58
--- /dev/null
+++ b/elpa/flycheck-20220504.830/flycheck.elc
Binary files differ
diff --git a/elpa/git-commit-20220429.934/git-commit-autoloads.el b/elpa/git-commit-20220429.934/git-commit-autoloads.el
new file mode 100644
index 0000000..a194e2b
--- /dev/null
+++ b/elpa/git-commit-20220429.934/git-commit-autoloads.el
@@ -0,0 +1,33 @@
+;;; git-commit-autoloads.el --- automatically extracted autoloads -*- lexical-binding: t -*-
+;;
+;;; Code:
+
+(add-to-list 'load-path (directory-file-name
+ (or (file-name-directory #$) (car load-path))))
+
+
+;;;### (autoloads nil "git-commit" "git-commit.el" (0 0 0 0))
+;;; Generated autoloads from git-commit.el
+(put 'git-commit-major-mode 'safe-local-variable
+ (lambda (val)
+ (memq val '(text-mode
+ markdown-mode
+ org-mode
+ fundamental-mode
+ git-commit-elisp-text-mode))))
+
+(register-definition-prefixes "git-commit" '("git-commit-" "global-git-commit-mode"))
+
+;;;***
+
+;;;### (autoloads nil nil ("git-commit-pkg.el") (0 0 0 0))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; coding: utf-8
+;; End:
+;;; git-commit-autoloads.el ends here
diff --git a/elpa/git-commit-20220429.934/git-commit-pkg.el b/elpa/git-commit-20220429.934/git-commit-pkg.el
new file mode 100644
index 0000000..6bee898
--- /dev/null
+++ b/elpa/git-commit-20220429.934/git-commit-pkg.el
@@ -0,0 +1,18 @@
+(define-package "git-commit" "20220429.934" "Edit Git commit messages."
+ '((emacs "25.1")
+ (compat "28.1.1.0")
+ (transient "20210920")
+ (with-editor "20211001"))
+ :commit "476383fc8fb0f6ea4c6fc29d7057a1b5b5f95bd8" :authors
+ '(("Jonas Bernoulli" . "jonas@bernoul.li")
+ ("Sebastian Wiesner" . "lunaryorn@gmail.com")
+ ("Florian Ragwitz" . "rafl@debian.org")
+ ("Marius Vollmer" . "marius.vollmer@gmail.com"))
+ :maintainer
+ '("Jonas Bernoulli" . "jonas@bernoul.li")
+ :keywords
+ '("git" "tools" "vc")
+ :url "https://github.com/magit/magit")
+;; Local Variables:
+;; no-byte-compile: t
+;; End:
diff --git a/elpa/git-commit-20220429.934/git-commit.el b/elpa/git-commit-20220429.934/git-commit.el
new file mode 100644
index 0000000..0df9ae0
--- /dev/null
+++ b/elpa/git-commit-20220429.934/git-commit.el
@@ -0,0 +1,1141 @@
+;;; git-commit.el --- Edit Git commit messages -*- lexical-binding:t -*-
+
+;; Copyright (C) 2008-2022 The Magit Project Contributors
+
+;; Author: Jonas Bernoulli <jonas@bernoul.li>
+;; Sebastian Wiesner <lunaryorn@gmail.com>
+;; Florian Ragwitz <rafl@debian.org>
+;; Marius Vollmer <marius.vollmer@gmail.com>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+
+;; Homepage: https://github.com/magit/magit
+;; Keywords: git tools vc
+
+;; Package-Version: 3.3.0-git
+;; Package-Requires: (
+;; (emacs "25.1")
+;; (compat "28.1.1.0")
+;; (transient "0.3.6")
+;; (with-editor "3.0.5"))
+
+;; SPDX-License-Identifier: GPL-3.0-or-later
+
+;; Magit 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.
+;;
+;; Magit 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 Magit. If not, see <https://www.gnu.org/licenses/>.
+
+;; You should have received a copy of the AUTHORS.md file, which
+;; lists all contributors. If not, see https://magit.vc/authors.
+
+;;; Commentary:
+
+;; This package assists the user in writing good Git commit messages.
+
+;; While Git allows for the message to be provided on the command
+;; line, it is preferable to tell Git to create the commit without
+;; actually passing it a message. Git then invokes the `$GIT_EDITOR'
+;; (or if that is undefined `$EDITOR') asking the user to provide the
+;; message by editing the file ".git/COMMIT_EDITMSG" (or another file
+;; in that directory, e.g. ".git/MERGE_MSG" for merge commits).
+
+;; When `global-git-commit-mode' is enabled, which it is by default,
+;; then opening such a file causes the features described below, to
+;; be enabled in that buffer. Normally this would be done using a
+;; major-mode but to allow the use of any major-mode, as the user sees
+;; fit, it is done here by running a setup function, which among other
+;; things turns on the preferred major-mode, by default `text-mode'.
+
+;; Git waits for the `$EDITOR' to finish and then either creates the
+;; commit using the contents of the file as commit message, or, if the
+;; editor process exited with a non-zero exit status, aborts without
+;; creating a commit. Unfortunately Emacsclient (which is what Emacs
+;; users should be using as `$EDITOR' or at least as `$GIT_EDITOR')
+;; does not differentiate between "successfully" editing a file and
+;; aborting; not out of the box that is.
+
+;; By making use of the `with-editor' package this package provides
+;; both ways of finish an editing session. In either case the file
+;; is saved, but Emacseditor's exit code differs.
+;;
+;; C-c C-c Finish the editing session successfully by returning
+;; with exit code 0. Git then creates the commit using
+;; the message it finds in the file.
+;;
+;; C-c C-k Aborts the edit editing session by returning with exit
+;; code 1. Git then aborts the commit.
+
+;; Aborting the commit does not cause the message to be lost, but
+;; relying solely on the file not being tampered with is risky. This
+;; package additionally stores all aborted messages for the duration
+;; of the current session (i.e. until you close Emacs). To get back
+;; an aborted message use M-p and M-n while editing a message.
+;;
+;; M-p Replace the buffer contents with the previous message
+;; from the message ring. Of course only after storing
+;; the current content there too.
+;;
+;; M-n Replace the buffer contents with the next message from
+;; the message ring, after storing the current content.
+
+;; Some support for pseudo headers as used in some projects is
+;; provided by these commands:
+;;
+;; C-c C-s Insert a Signed-off-by header.
+;; C-c C-a Insert a Acked-by header.
+;; C-c C-m Insert a Modified-by header.
+;; C-c C-t Insert a Tested-by header.
+;; C-c C-r Insert a Reviewed-by header.
+;; C-c C-o Insert a Cc header.
+;; C-c C-p Insert a Reported-by header.
+;; C-c C-i Insert a Suggested-by header.
+
+;; When Git requests a commit message from the user, it does so by
+;; having her edit a file which initially contains some comments,
+;; instructing her what to do, and providing useful information, such
+;; as which files were modified. These comments, even when left
+;; intact by the user, do not become part of the commit message. This
+;; package ensures these comments are propertizes as such and further
+;; prettifies them by using different faces for various parts, such as
+;; files.
+
+;; Finally this package highlights style errors, like lines that are
+;; too long, or when the second line is not empty. It may even nag
+;; you when you attempt to finish the commit without having fixed
+;; these issues. The style checks and many other settings can easily
+;; be configured:
+;;
+;; M-x customize-group RET git-commit RET
+
+;;; Code:
+;;;; Dependencies
+
+(require 'seq)
+(require 'subr-x)
+
+(require 'magit-base nil t)
+(require 'magit-git nil t)
+(require 'magit-mode nil t)
+
+(require 'log-edit)
+(require 'ring)
+(require 'rx)
+(require 'server)
+(require 'transient)
+(require 'with-editor)
+
+(defvar recentf-exclude)
+
+;;;; Declarations
+
+(defvar diff-default-read-only)
+(defvar flyspell-generic-check-word-predicate)
+(defvar font-lock-beg)
+(defvar font-lock-end)
+
+(declare-function magit-completing-read "magit-base"
+ (prompt collection &optional predicate require-match
+ initial-input hist def fallback))
+(declare-function magit-expand-git-file-name "magit-git" (filename))
+(declare-function magit-git-lines "magit-git" (&rest args))
+(declare-function magit-list-local-branch-names "magit-git" ())
+(declare-function magit-list-remote-branch-names "magit-git"
+ (&optional remote relative))
+
+;;; Options
+;;;; Variables
+
+(defgroup git-commit nil
+ "Edit Git commit messages."
+ :prefix "git-commit-"
+ :link '(info-link "(magit)Editing Commit Messages")
+ :group 'tools)
+
+(define-minor-mode global-git-commit-mode
+ "Edit Git commit messages.
+
+This global mode arranges for `git-commit-setup' to be called
+when a Git commit message file is opened. That usually happens
+when Git uses the Emacsclient as $GIT_EDITOR to have the user
+provide such a commit message.
+
+Loading the library `git-commit' by default enables this mode,
+but the library is not automatically loaded because doing that
+would pull in many dependencies and increase startup time too
+much. You can either rely on `magit' loading this library or
+you can load it explicitly. Autoloading is not an alternative
+because in this case autoloading would immediately trigger
+full loading."
+ :group 'git-commit
+ :type 'boolean
+ :global t
+ :init-value t
+ :initialize (lambda (symbol exp)
+ (custom-initialize-default symbol exp)
+ (when global-git-commit-mode
+ (add-hook 'find-file-hook #'git-commit-setup-check-buffer)))
+ (if global-git-commit-mode
+ (add-hook 'find-file-hook #'git-commit-setup-check-buffer)
+ (remove-hook 'find-file-hook #'git-commit-setup-check-buffer)))
+
+(defcustom git-commit-major-mode #'text-mode
+ "Major mode used to edit Git commit messages.
+The major mode configured here is turned on by the minor mode
+`git-commit-mode'."
+ :group 'git-commit
+ :type '(choice (function-item text-mode)
+ (function-item markdown-mode)
+ (function-item org-mode)
+ (function-item fundamental-mode)
+ (function-item git-commit-elisp-text-mode)
+ (function :tag "Another mode")
+ (const :tag "No major mode")))
+;;;###autoload(put 'git-commit-major-mode 'safe-local-variable
+;;;###autoload (lambda (val)
+;;;###autoload (memq val '(text-mode
+;;;###autoload markdown-mode
+;;;###autoload org-mode
+;;;###autoload fundamental-mode
+;;;###autoload git-commit-elisp-text-mode))))
+
+(defcustom git-commit-setup-hook
+ '(git-commit-save-message
+ git-commit-setup-changelog-support
+ git-commit-turn-on-auto-fill
+ git-commit-propertize-diff
+ bug-reference-mode
+ with-editor-usage-message)
+ "Hook run at the end of `git-commit-setup'."
+ :group 'git-commit
+ :type 'hook
+ :get (and (featurep 'magit-base) #'magit-hook-custom-get)
+ :options '(git-commit-save-message
+ git-commit-setup-changelog-support
+ magit-generate-changelog
+ git-commit-turn-on-auto-fill
+ git-commit-turn-on-orglink
+ git-commit-turn-on-flyspell
+ git-commit-propertize-diff
+ bug-reference-mode
+ with-editor-usage-message))
+
+(defcustom git-commit-post-finish-hook nil
+ "Hook run after the user finished writing a commit message.
+
+\\<with-editor-mode-map>\
+This hook is only run after pressing \\[with-editor-finish] in a buffer used
+to edit a commit message. If a commit is created without the
+user typing a message into a buffer, then this hook is not run.
+
+This hook is not run until the new commit has been created. If
+doing so takes Git longer than one second, then this hook isn't
+run at all. For certain commands such as `magit-rebase-continue'
+this hook is never run because doing so would lead to a race
+condition.
+
+This hook is only run if `magit' is available.
+
+Also see `magit-post-commit-hook'."
+ :group 'git-commit
+ :type 'hook
+ :get (and (featurep 'magit-base) #'magit-hook-custom-get))
+
+(defcustom git-commit-finish-query-functions
+ '(git-commit-check-style-conventions)
+ "List of functions called to query before performing commit.
+
+The commit message buffer is current while the functions are
+called. If any of them returns nil, then the commit is not
+performed and the buffer is not killed. The user should then
+fix the issue and try again.
+
+The functions are called with one argument. If it is non-nil,
+then that indicates that the user used a prefix argument to
+force finishing the session despite issues. Functions should
+usually honor this wish and return non-nil."
+ :options '(git-commit-check-style-conventions)
+ :type 'hook
+ :group 'git-commit)
+
+(defcustom git-commit-style-convention-checks '(non-empty-second-line)
+ "List of checks performed by `git-commit-check-style-conventions'.
+Valid members are `non-empty-second-line' and `overlong-summary-line'.
+That function is a member of `git-commit-finish-query-functions'."
+ :options '(non-empty-second-line overlong-summary-line)
+ :type '(list :convert-widget custom-hook-convert-widget)
+ :group 'git-commit)
+
+(defcustom git-commit-summary-max-length 68
+ "Column beyond which characters in the summary lines are highlighted.
+
+The highlighting indicates that the summary is getting too long
+by some standards. It does in no way imply that going over the
+limit a few characters or in some cases even many characters is
+anything that deserves shaming. It's just a friendly reminder
+that if you can make the summary shorter, then you might want
+to consider doing so."
+ :group 'git-commit
+ :safe 'numberp
+ :type 'number)
+
+(defcustom git-commit-fill-column nil
+ "Override `fill-column' in commit message buffers.
+
+If this is non-nil, then it should be an integer. If that is the
+case and the buffer-local value of `fill-column' is not already
+set by the time `git-commit-turn-on-auto-fill' is called as a
+member of `git-commit-setup-hook', then that function sets the
+buffer-local value of `fill-column' to the value of this option.
+
+This option exists mostly for historic reasons. If you are not
+already using it, then you probably shouldn't start doing so."
+ :group 'git-commit
+ :safe 'numberp
+ :type '(choice (const :tag "use regular fill-column")
+ number))
+
+(make-obsolete-variable 'git-commit-fill-column 'fill-column
+ "Magit 2.11.0" 'set)
+
+(defcustom git-commit-known-pseudo-headers
+ '("Signed-off-by" "Acked-by" "Modified-by" "Cc"
+ "Suggested-by" "Reported-by" "Tested-by" "Reviewed-by"
+ "Co-authored-by")
+ "A list of Git pseudo headers to be highlighted."
+ :group 'git-commit
+ :safe (lambda (val) (and (listp val) (seq-every-p #'stringp val)))
+ :type '(repeat string))
+
+(defcustom git-commit-use-local-message-ring nil
+ "Whether to use a local message ring instead of the global one.
+This can be set globally, in which case every repository gets its
+own commit message ring, or locally for a single repository. If
+Magit isn't available, then setting this to a non-nil value has
+no effect."
+ :group 'git-commit
+ :safe 'booleanp
+ :type 'boolean)
+
+;;;; Faces
+
+(defgroup git-commit-faces nil
+ "Faces used for highlighting Git commit messages."
+ :prefix "git-commit-"
+ :group 'git-commit
+ :group 'faces)
+
+(defface git-commit-summary
+ '((t :inherit font-lock-type-face))
+ "Face used for the summary in commit messages."
+ :group 'git-commit-faces)
+
+(defface git-commit-overlong-summary
+ '((t :inherit font-lock-warning-face))
+ "Face used for the tail of overlong commit message summaries."
+ :group 'git-commit-faces)
+
+(defface git-commit-nonempty-second-line
+ '((t :inherit font-lock-warning-face))
+ "Face used for non-whitespace on the second line of commit messages."
+ :group 'git-commit-faces)
+
+(defface git-commit-keyword
+ '((t :inherit font-lock-string-face))
+ "Face used for keywords in commit messages.
+In this context a \"keyword\" is text surrounded by brackets."
+ :group 'git-commit-faces)
+
+(define-obsolete-face-alias 'git-commit-note
+ 'git-commit-keyword "Git-Commit 3.0.0")
+
+(defface git-commit-pseudo-header
+ '((t :inherit font-lock-string-face))
+ "Face used for pseudo headers in commit messages."
+ :group 'git-commit-faces)
+
+(defface git-commit-known-pseudo-header
+ '((t :inherit font-lock-keyword-face))
+ "Face used for the keywords of known pseudo headers in commit messages."
+ :group 'git-commit-faces)
+
+(defface git-commit-comment-branch-local
+ (if (featurep 'magit)
+ '((t :inherit magit-branch-local))
+ '((t :inherit font-lock-variable-name-face)))
+ "Face used for names of local branches in commit message comments."
+ :group 'git-commit-faces)
+
+(define-obsolete-face-alias 'git-commit-comment-branch
+ 'git-commit-comment-branch-local "Git-Commit 2.12.0")
+
+(defface git-commit-comment-branch-remote
+ (if (featurep 'magit)
+ '((t :inherit magit-branch-remote))
+ '((t :inherit font-lock-variable-name-face)))
+ "Face used for names of remote branches in commit message comments.
+This is only used if Magit is available."
+ :group 'git-commit-faces)
+
+(defface git-commit-comment-detached
+ '((t :inherit git-commit-comment-branch-local))
+ "Face used for detached `HEAD' in commit message comments."
+ :group 'git-commit-faces)
+
+(defface git-commit-comment-heading
+ '((t :inherit git-commit-known-pseudo-header))
+ "Face used for headings in commit message comments."
+ :group 'git-commit-faces)
+
+(defface git-commit-comment-file
+ '((t :inherit git-commit-pseudo-header))
+ "Face used for file names in commit message comments."
+ :group 'git-commit-faces)
+
+(defface git-commit-comment-action
+ '((t :inherit bold))
+ "Face used for actions in commit message comments."
+ :group 'git-commit-faces)
+
+;;; Keymap
+
+(defvar git-commit-mode-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map (kbd "M-p") #'git-commit-prev-message)
+ (define-key map (kbd "M-n") #'git-commit-next-message)
+ (define-key map (kbd "C-c M-p") #'git-commit-search-message-backward)
+ (define-key map (kbd "C-c M-n") #'git-commit-search-message-forward)
+ (define-key map (kbd "C-c C-i") #'git-commit-insert-pseudo-header)
+ (define-key map (kbd "C-c C-a") #'git-commit-ack)
+ (define-key map (kbd "C-c M-i") #'git-commit-suggested)
+ (define-key map (kbd "C-c C-m") #'git-commit-modified)
+ (define-key map (kbd "C-c C-o") #'git-commit-cc)
+ (define-key map (kbd "C-c C-p") #'git-commit-reported)
+ (define-key map (kbd "C-c C-r") #'git-commit-review)
+ (define-key map (kbd "C-c C-s") #'git-commit-signoff)
+ (define-key map (kbd "C-c C-t") #'git-commit-test)
+ (define-key map (kbd "C-c M-s") #'git-commit-save-message)
+ map)
+ "Key map used by `git-commit-mode'.")
+
+;;; Menu
+
+(require 'easymenu)
+(easy-menu-define git-commit-mode-menu git-commit-mode-map
+ "Git Commit Mode Menu"
+ '("Commit"
+ ["Previous" git-commit-prev-message t]
+ ["Next" git-commit-next-message t]
+ "-"
+ ["Ack" git-commit-ack :active t
+ :help "Insert an 'Acked-by' header"]
+ ["Sign-Off" git-commit-signoff :active t
+ :help "Insert a 'Signed-off-by' header"]
+ ["Modified-by" git-commit-modified :active t
+ :help "Insert a 'Modified-by' header"]
+ ["Tested-by" git-commit-test :active t
+ :help "Insert a 'Tested-by' header"]
+ ["Reviewed-by" git-commit-review :active t
+ :help "Insert a 'Reviewed-by' header"]
+ ["CC" git-commit-cc t
+ :help "Insert a 'Cc' header"]
+ ["Reported" git-commit-reported :active t
+ :help "Insert a 'Reported-by' header"]
+ ["Suggested" git-commit-suggested t
+ :help "Insert a 'Suggested-by' header"]
+ ["Co-authored-by" git-commit-co-authored t
+ :help "Insert a 'Co-authored-by' header"]
+ "-"
+ ["Save" git-commit-save-message t]
+ ["Cancel" with-editor-cancel t]
+ ["Commit" with-editor-finish t]))
+
+;;; Hooks
+
+(defconst git-commit-filename-regexp "/\\(\
+\\(\\(COMMIT\\|NOTES\\|PULLREQ\\|MERGEREQ\\|TAG\\)_EDIT\\|MERGE_\\|\\)MSG\
+\\|\\(BRANCH\\|EDIT\\)_DESCRIPTION\\)\\'")
+
+(with-eval-after-load 'recentf
+ (add-to-list 'recentf-exclude git-commit-filename-regexp))
+
+(add-to-list 'with-editor-file-name-history-exclude git-commit-filename-regexp)
+
+(defun git-commit-setup-font-lock-in-buffer ()
+ (and buffer-file-name
+ (string-match-p git-commit-filename-regexp buffer-file-name)
+ (git-commit-setup-font-lock)))
+
+(add-hook 'after-change-major-mode-hook #'git-commit-setup-font-lock-in-buffer)
+
+(defun git-commit-setup-check-buffer ()
+ (and buffer-file-name
+ (string-match-p git-commit-filename-regexp buffer-file-name)
+ (git-commit-setup)))
+
+(defvar git-commit-mode)
+
+(defun git-commit-file-not-found ()
+ ;; cygwin git will pass a cygwin path (/cygdrive/c/foo/.git/...),
+ ;; try to handle this in window-nt Emacs.
+ (when-let
+ ((file (and (or (string-match-p git-commit-filename-regexp
+ buffer-file-name)
+ (and (boundp 'git-rebase-filename-regexp)
+ (string-match-p git-rebase-filename-regexp
+ buffer-file-name)))
+ (not (file-accessible-directory-p
+ (file-name-directory buffer-file-name)))
+ (if (require 'magit-git nil t)
+ ;; Emacs prepends a "c:".
+ (magit-expand-git-file-name
+ (substring buffer-file-name 2))
+ ;; Fallback if we can't load `magit-git'.
+ (and (string-match
+ "\\`[a-z]:/\\(cygdrive/\\)?\\([a-z]\\)/\\(.*\\)"
+ buffer-file-name)
+ (concat (match-string 2 buffer-file-name) ":/"
+ (match-string 3 buffer-file-name)))))))
+ (when (file-accessible-directory-p (file-name-directory file))
+ (let ((inhibit-read-only t))
+ (insert-file-contents file t)
+ t))))
+
+(when (eq system-type 'windows-nt)
+ (add-hook 'find-file-not-found-functions #'git-commit-file-not-found))
+
+(defconst git-commit-usage-message "\
+Type \\[with-editor-finish] to finish, \
+\\[with-editor-cancel] to cancel, and \
+\\[git-commit-prev-message] and \\[git-commit-next-message] \
+to recover older messages")
+
+(defun git-commit-setup ()
+ (when (fboundp 'magit-toplevel)
+ ;; `magit-toplevel' is autoloaded and defined in magit-git.el,
+ ;; That library declares this functions without loading
+ ;; magit-process.el, which defines it.
+ (require 'magit-process nil t))
+ (when git-commit-major-mode
+ (let ((auto-mode-alist (list (cons (concat "\\`"
+ (regexp-quote buffer-file-name)
+ "\\'")
+ git-commit-major-mode)))
+ ;; The major-mode hook might want to consult these minor
+ ;; modes, while the minor-mode hooks might want to consider
+ ;; the major mode.
+ (git-commit-mode t)
+ (with-editor-mode t))
+ (normal-mode t)))
+ ;; Pretend that git-commit-mode is a major-mode,
+ ;; so that directory-local settings can be used.
+ (let ((default-directory
+ (or (and (not (file-exists-p ".dir-locals.el"))
+ ;; When $GIT_DIR/.dir-locals.el doesn't exist,
+ ;; fallback to $GIT_WORK_TREE/.dir-locals.el,
+ ;; because the maintainer can use the latter
+ ;; to enforce conventions, while s/he has no
+ ;; control over the former.
+ (fboundp 'magit-toplevel) ; silence byte-compiler
+ (magit-toplevel))
+ default-directory)))
+ (let ((buffer-file-name nil) ; trick hack-dir-local-variables
+ (major-mode 'git-commit-mode)) ; trick dir-locals-collect-variables
+ (hack-dir-local-variables)
+ (hack-local-variables-apply)))
+ ;; Show our own message using our hook.
+ (setq with-editor-show-usage nil)
+ (setq with-editor-usage-message git-commit-usage-message)
+ (unless with-editor-mode
+ ;; Maybe already enabled when using `shell-command' or an Emacs shell.
+ (with-editor-mode 1))
+ (add-hook 'with-editor-finish-query-functions
+ #'git-commit-finish-query-functions nil t)
+ (add-hook 'with-editor-pre-finish-hook
+ #'git-commit-save-message nil t)
+ (add-hook 'with-editor-pre-cancel-hook
+ #'git-commit-save-message nil t)
+ (when (and (fboundp 'magit-rev-parse)
+ (not (memq last-command
+ '(magit-sequencer-continue
+ magit-sequencer-skip
+ magit-am-continue
+ magit-am-skip
+ magit-rebase-continue
+ magit-rebase-skip))))
+ (add-hook 'with-editor-post-finish-hook
+ (apply-partially #'git-commit-run-post-finish-hook
+ (magit-rev-parse "HEAD"))
+ nil t)
+ (when (fboundp 'magit-wip-maybe-add-commit-hook)
+ (magit-wip-maybe-add-commit-hook)))
+ (setq with-editor-cancel-message
+ #'git-commit-cancel-message)
+ (git-commit-mode 1)
+ (git-commit-setup-font-lock)
+ (git-commit-prepare-message-ring)
+ (when (boundp 'save-place)
+ (setq save-place nil))
+ (save-excursion
+ (goto-char (point-min))
+ (when (looking-at "\\`\\(\\'\\|\n[^\n]\\)")
+ (open-line 1)))
+ (with-demoted-errors "Error running git-commit-setup-hook: %S"
+ (run-hooks 'git-commit-setup-hook))
+ (set-buffer-modified-p nil))
+
+(defun git-commit-run-post-finish-hook (previous)
+ (when (and git-commit-post-finish-hook
+ (require 'magit nil t)
+ (fboundp 'magit-rev-parse))
+ (cl-block nil
+ (let ((break (time-add (current-time)
+ (seconds-to-time 1))))
+ (while (equal (magit-rev-parse "HEAD") previous)
+ (if (time-less-p (current-time) break)
+ (sit-for 0.01)
+ (message "No commit created after 1 second. Not running %s."
+ 'git-commit-post-finish-hook)
+ (cl-return))))
+ (run-hooks 'git-commit-post-finish-hook))))
+
+(define-minor-mode git-commit-mode
+ "Auxiliary minor mode used when editing Git commit messages.
+This mode is only responsible for setting up some key bindings.
+Don't use it directly, instead enable `global-git-commit-mode'."
+ :lighter "")
+
+(put 'git-commit-mode 'permanent-local t)
+
+(defun git-commit-setup-changelog-support ()
+ "Treat ChangeLog entries as unindented paragraphs."
+ (when (fboundp 'log-indent-fill-entry) ; New in Emacs 27.
+ (setq-local fill-paragraph-function #'log-indent-fill-entry))
+ (setq-local fill-indent-according-to-mode t)
+ (setq-local paragraph-start (concat paragraph-start "\\|\\*\\|(")))
+
+(defun git-commit-turn-on-auto-fill ()
+ "Unconditionally turn on Auto Fill mode.
+If `git-commit-fill-column' is non-nil, and `fill-column'
+doesn't already have a buffer-local value, then set that
+to `git-commit-fill-column'."
+ (when (and (numberp git-commit-fill-column)
+ (not (local-variable-p 'fill-column)))
+ (setq fill-column git-commit-fill-column))
+ (setq-local comment-auto-fill-only-comments nil)
+ (turn-on-auto-fill))
+
+(defun git-commit-turn-on-orglink ()
+ "Turn on Orglink mode if it is available.
+If `git-commit-major-mode' is `org-mode', then silently forgo
+turning on `orglink-mode'."
+ (when (and (not (derived-mode-p 'org-mode))
+ (boundp 'orglink-match-anywhere)
+ (fboundp 'orglink-mode))
+ (setq-local orglink-match-anywhere t)
+ (orglink-mode 1)))
+
+(defun git-commit-turn-on-flyspell ()
+ "Unconditionally turn on Flyspell mode.
+Also prevent comments from being checked and
+finally check current non-comment text."
+ (require 'flyspell)
+ (turn-on-flyspell)
+ (setq flyspell-generic-check-word-predicate
+ #'git-commit-flyspell-verify)
+ (let ((end)
+ (comment-start-regex (format "^\\(%s\\|$\\)" comment-start)))
+ (save-excursion
+ (goto-char (point-max))
+ (while (and (not (bobp)) (looking-at comment-start-regex))
+ (forward-line -1))
+ (unless (looking-at comment-start-regex)
+ (forward-line))
+ (setq end (point)))
+ (flyspell-region (point-min) end)))
+
+(defun git-commit-flyspell-verify ()
+ (not (= (char-after (line-beginning-position))
+ (aref comment-start 0))))
+
+(defun git-commit-finish-query-functions (force)
+ (run-hook-with-args-until-failure
+ 'git-commit-finish-query-functions force))
+
+(defun git-commit-check-style-conventions (force)
+ "Check for violations of certain basic style conventions.
+
+For each violation ask the user if she wants to proceed anyway.
+Option `git-commit-style-convention-checks' controls which
+conventions are checked."
+ (or force
+ (save-excursion
+ (goto-char (point-min))
+ (re-search-forward (git-commit-summary-regexp) nil t)
+ (if (equal (match-string 1) "")
+ t ; Just try; we don't know whether --allow-empty-message was used.
+ (and (or (not (memq 'overlong-summary-line
+ git-commit-style-convention-checks))
+ (equal (match-string 2) "")
+ (y-or-n-p "Summary line is too long. Commit anyway? "))
+ (or (not (memq 'non-empty-second-line
+ git-commit-style-convention-checks))
+ (not (match-string 3))
+ (y-or-n-p "Second line is not empty. Commit anyway? ")))))))
+
+(defun git-commit-cancel-message ()
+ (message
+ (concat "Commit canceled"
+ (and (memq 'git-commit-save-message with-editor-pre-cancel-hook)
+ ". Message saved to `log-edit-comment-ring'"))))
+
+;;; History
+
+(defun git-commit-prev-message (arg)
+ "Cycle backward through message history, after saving current message.
+With a numeric prefix ARG, go back ARG comments."
+ (interactive "*p")
+ (let ((len (ring-length log-edit-comment-ring)))
+ (if (<= len 0)
+ (progn (message "Empty comment ring") (ding))
+ ;; Unlike `log-edit-previous-comment' we save the current
+ ;; non-empty and newly written comment, because otherwise
+ ;; it would be irreversibly lost.
+ (when-let ((message (git-commit-buffer-message)))
+ (unless (ring-member log-edit-comment-ring message)
+ (ring-insert log-edit-comment-ring message)
+ (cl-incf arg)
+ (setq len (ring-length log-edit-comment-ring))))
+ ;; Delete the message but not the instructions at the end.
+ (save-restriction
+ (goto-char (point-min))
+ (narrow-to-region
+ (point)
+ (if (re-search-forward (concat "^" comment-start) nil t)
+ (max 1 (- (point) 2))
+ (point-max)))
+ (delete-region (point-min) (point)))
+ (setq log-edit-comment-ring-index (log-edit-new-comment-index arg len))
+ (message "Comment %d" (1+ log-edit-comment-ring-index))
+ (insert (ring-ref log-edit-comment-ring log-edit-comment-ring-index)))))
+
+(defun git-commit-next-message (arg)
+ "Cycle forward through message history, after saving current message.
+With a numeric prefix ARG, go forward ARG comments."
+ (interactive "*p")
+ (git-commit-prev-message (- arg)))
+
+(defun git-commit-search-message-backward (string)
+ "Search backward through message history for a match for STRING.
+Save current message first."
+ (interactive
+ ;; Avoid `format-prompt' because it isn't available until Emacs 28.
+ (list (read-string (format "Comment substring (default %s): "
+ log-edit-last-comment-match)
+ nil nil log-edit-last-comment-match)))
+ (cl-letf (((symbol-function #'log-edit-previous-comment)
+ (symbol-function #'git-commit-prev-message)))
+ (log-edit-comment-search-backward string)))
+
+(defun git-commit-search-message-forward (string)
+ "Search forward through message history for a match for STRING.
+Save current message first."
+ (interactive
+ ;; Avoid `format-prompt' because it isn't available until Emacs 28.
+ (list (read-string (format "Comment substring (default %s): "
+ log-edit-last-comment-match)
+ nil nil log-edit-last-comment-match)))
+ (cl-letf (((symbol-function #'log-edit-previous-comment)
+ (symbol-function #'git-commit-prev-message)))
+ (log-edit-comment-search-forward string)))
+
+(defun git-commit-save-message ()
+ "Save current message to `log-edit-comment-ring'."
+ (interactive)
+ (if-let ((message (git-commit-buffer-message)))
+ (progn
+ (when-let ((index (ring-member log-edit-comment-ring message)))
+ (ring-remove log-edit-comment-ring index))
+ (ring-insert log-edit-comment-ring message)
+ (when (and git-commit-use-local-message-ring
+ (fboundp 'magit-repository-local-set))
+ (magit-repository-local-set 'log-edit-comment-ring
+ log-edit-comment-ring))
+ (message "Message saved"))
+ (message "Only whitespace and/or comments; message not saved")))
+
+(defun git-commit-prepare-message-ring ()
+ (make-local-variable 'log-edit-comment-ring-index)
+ (when (and git-commit-use-local-message-ring
+ (fboundp 'magit-repository-local-get))
+ (setq-local log-edit-comment-ring
+ (magit-repository-local-get
+ 'log-edit-comment-ring
+ (make-ring log-edit-maximum-comment-ring-size)))))
+
+(defun git-commit-buffer-message ()
+ (let ((flush (concat "^" comment-start))
+ (str (buffer-substring-no-properties (point-min) (point-max))))
+ (with-temp-buffer
+ (insert str)
+ (goto-char (point-min))
+ (when (re-search-forward (concat flush " -+ >8 -+$") nil t)
+ (delete-region (point-at-bol) (point-max)))
+ (goto-char (point-min))
+ (flush-lines flush)
+ (goto-char (point-max))
+ (unless (eq (char-before) ?\n)
+ (insert ?\n))
+ (setq str (buffer-string)))
+ (unless (string-match "\\`[ \t\n\r]*\\'" str)
+ (when (string-match "\\`\n\\{2,\\}" str)
+ (setq str (replace-match "\n" t t str)))
+ (when (string-match "\n\\{2,\\}\\'" str)
+ (setq str (replace-match "\n" t t str)))
+ str)))
+
+;;; Utilities
+
+(defsubst git-commit-executable ()
+ (if (fboundp 'magit-git-executable)
+ (magit-git-executable)
+ "git"))
+
+;;; Headers
+
+(transient-define-prefix git-commit-insert-pseudo-header ()
+ "Insert a commit message pseudo header."
+ [["Insert ... by yourself"
+ ("a" "Ack" git-commit-ack)
+ ("m" "Modified" git-commit-modified)
+ ("r" "Reviewed" git-commit-review)
+ ("s" "Signed-off" git-commit-signoff)
+ ("t" "Tested" git-commit-test)]
+ ["Insert ... by someone"
+ ("C-c" "Cc" git-commit-cc)
+ ("C-r" "Reported" git-commit-reported)
+ ("C-i" "Suggested" git-commit-suggested)
+ ("C-a" "Co-authored" git-commit-co-authored)]])
+
+(defun git-commit-ack (name mail)
+ "Insert a header acknowledging that you have looked at the commit."
+ (interactive (git-commit-self-ident))
+ (git-commit-insert-header "Acked-by" name mail))
+
+(defun git-commit-modified (name mail)
+ "Insert a header to signal that you have modified the commit."
+ (interactive (git-commit-self-ident))
+ (git-commit-insert-header "Modified-by" name mail))
+
+(defun git-commit-review (name mail)
+ "Insert a header acknowledging that you have reviewed the commit."
+ (interactive (git-commit-self-ident))
+ (git-commit-insert-header "Reviewed-by" name mail))
+
+(defun git-commit-signoff (name mail)
+ "Insert a header to sign off the commit."
+ (interactive (git-commit-self-ident))
+ (git-commit-insert-header "Signed-off-by" name mail))
+
+(defun git-commit-test (name mail)
+ "Insert a header acknowledging that you have tested the commit."
+ (interactive (git-commit-self-ident))
+ (git-commit-insert-header "Tested-by" name mail))
+
+(defun git-commit-cc (name mail)
+ "Insert a header mentioning someone who might be interested."
+ (interactive (git-commit-read-ident "Cc"))
+ (git-commit-insert-header "Cc" name mail))
+
+(defun git-commit-reported (name mail)
+ "Insert a header mentioning the person who reported the issue."
+ (interactive (git-commit-read-ident "Reported-by"))
+ (git-commit-insert-header "Reported-by" name mail))
+
+(defun git-commit-suggested (name mail)
+ "Insert a header mentioning the person who suggested the change."
+ (interactive (git-commit-read-ident "Suggested-by"))
+ (git-commit-insert-header "Suggested-by" name mail))
+
+(defun git-commit-co-authored (name mail)
+ "Insert a header mentioning the person who co-authored the commit."
+ (interactive (git-commit-read-ident "Co-authored-by"))
+ (git-commit-insert-header "Co-authored-by" name mail))
+
+(defun git-commit-self-ident ()
+ (list (or (getenv "GIT_AUTHOR_NAME")
+ (getenv "GIT_COMMITTER_NAME")
+ (with-demoted-errors "Error running 'git config user.name': %S"
+ (car (process-lines
+ (git-commit-executable) "config" "user.name")))
+ user-full-name
+ (read-string "Name: "))
+ (or (getenv "GIT_AUTHOR_EMAIL")
+ (getenv "GIT_COMMITTER_EMAIL")
+ (getenv "EMAIL")
+ (with-demoted-errors "Error running 'git config user.email': %S"
+ (car (process-lines
+ (git-commit-executable) "config" "user.email")))
+ (read-string "Email: "))))
+
+(defvar git-commit-read-ident-history nil)
+
+(defun git-commit-read-ident (prompt)
+ (if (require 'magit-git nil t)
+ (let ((str (magit-completing-read
+ prompt
+ (sort (delete-dups
+ (magit-git-lines "log" "-n9999" "--format=%aN <%ae>"))
+ #'string<)
+ nil nil nil 'git-commit-read-ident-history)))
+ (save-match-data
+ (if (string-match "\\`\\([^<]+\\) *<\\([^>]+\\)>\\'" str)
+ (list (save-match-data (string-trim (match-string 1 str)))
+ (string-trim (match-string 2 str)))
+ (user-error "Invalid input"))))
+ (list (read-string "Name: ")
+ (read-string "Email: "))))
+
+(defun git-commit-insert-header (header name email)
+ (setq header (format "%s: %s <%s>" header name email))
+ (save-excursion
+ (goto-char (point-max))
+ (cond ((re-search-backward "^[-a-zA-Z]+: [^<]+? <[^>]+>" nil t)
+ (end-of-line)
+ (insert ?\n header)
+ (unless (= (char-after) ?\n)
+ (insert ?\n)))
+ (t
+ (while (re-search-backward (concat "^" comment-start) nil t))
+ (unless (looking-back "\n\n" nil)
+ (insert ?\n))
+ (insert header ?\n)))
+ (unless (or (eobp) (= (char-after) ?\n))
+ (insert ?\n))))
+
+;;; Font-Lock
+
+(defvar-local git-commit-need-summary-line t
+ "Whether the text should have a heading that is separated from the body.
+
+For commit messages that is a convention that should not
+be violated. For notes it is up to the user. If you do
+not want to insist on an empty second line here, then use
+something like:
+
+ (add-hook \\='git-commit-setup-hook
+ (lambda ()
+ (when (equal (file-name-nondirectory (buffer-file-name))
+ \"NOTES_EDITMSG\")
+ (setq git-commit-need-summary-line nil))))")
+
+(defun git-commit-summary-regexp ()
+ (if git-commit-need-summary-line
+ (concat
+ ;; Leading empty lines and comments
+ (format "\\`\\(?:^\\(?:\\s-*\\|%s.*\\)\n\\)*" comment-start)
+ ;; Summary line
+ (format "\\(.\\{0,%d\\}\\)\\(.*\\)" git-commit-summary-max-length)
+ ;; Non-empty non-comment second line
+ (format "\\(?:\n%s\\|\n\\(.+\\)\\)?" comment-start))
+ "\\(EASTER\\) \\(EGG\\)"))
+
+(defun git-commit-extend-region-summary-line ()
+ "Identify the multiline summary-regexp construct.
+Added to `font-lock-extend-region-functions'."
+ (save-excursion
+ (save-match-data
+ (goto-char (point-min))
+ (when (looking-at (git-commit-summary-regexp))
+ (let ((summary-beg (match-beginning 0))
+ (summary-end (match-end 0)))
+ (when (or (< summary-beg font-lock-beg summary-end)
+ (< summary-beg font-lock-end summary-end))
+ (setq font-lock-beg (min font-lock-beg summary-beg))
+ (setq font-lock-end (max font-lock-end summary-end))))))))
+
+(defvar-local git-commit--branch-name-regexp nil)
+
+(defconst git-commit-comment-headings
+ '("Changes to be committed:"
+ "Untracked files:"
+ "Changed but not updated:"
+ "Changes not staged for commit:"
+ "Unmerged paths:"
+ "Author:"
+ "Date:")
+ "Also fontified outside of comments in `git-commit-font-lock-keywords-2'.")
+
+(defconst git-commit-font-lock-keywords-1
+ '(;; Pseudo headers
+ (eval . `(,(format "^\\(%s:\\)\\( .*\\)"
+ (regexp-opt git-commit-known-pseudo-headers))
+ (1 'git-commit-known-pseudo-header)
+ (2 'git-commit-pseudo-header)))
+ ;; Summary
+ (eval . `(,(git-commit-summary-regexp)
+ (1 'git-commit-summary)))
+ ;; - Keyword [aka "text in brackets"] (overrides summary)
+ ("\\[.+?\\]"
+ (0 'git-commit-keyword t))
+ ;; - Non-empty second line (overrides summary and note)
+ (eval . `(,(git-commit-summary-regexp)
+ (2 'git-commit-overlong-summary t t)
+ (3 'git-commit-nonempty-second-line t t)))))
+
+(defconst git-commit-font-lock-keywords-2
+ `(,@git-commit-font-lock-keywords-1
+ ;; Comments
+ (eval . `(,(format "^%s.*" comment-start)
+ (0 'font-lock-comment-face append)))
+ (eval . `(,(format "^%s On branch \\(.*\\)" comment-start)
+ (1 'git-commit-comment-branch-local t)))
+ (eval . `(,(format "^%s \\(HEAD\\) detached at" comment-start)
+ (1 'git-commit-comment-detached t)))
+ (eval . `(,(format "^%s %s" comment-start
+ (regexp-opt git-commit-comment-headings t))
+ (1 'git-commit-comment-heading t)))
+ (eval . `(,(format "^%s\t\\(?:\\([^:\n]+\\):\\s-+\\)?\\(.*\\)" comment-start)
+ (1 'git-commit-comment-action t t)
+ (2 'git-commit-comment-file t)))
+ ;; "commit HASH"
+ (eval . `(,(rx bol "commit " (1+ alnum) eol)
+ (0 'git-commit-pseudo-header)))
+ ;; `git-commit-comment-headings' (but not in commented lines)
+ (eval . `(,(rx-to-string `(seq bol (or ,@git-commit-comment-headings) (1+ blank) (1+ nonl) eol))
+ (0 'git-commit-pseudo-header)))))
+
+(defconst git-commit-font-lock-keywords-3
+ `(,@git-commit-font-lock-keywords-2
+ ;; More comments
+ (eval
+ ;; Your branch is ahead of 'master' by 3 commits.
+ ;; Your branch is behind 'master' by 2 commits, and can be fast-forwarded.
+ . `(,(format
+ "^%s Your branch is \\(?:ahead\\|behind\\) of '%s' by \\([0-9]*\\)"
+ comment-start git-commit--branch-name-regexp)
+ (1 'git-commit-comment-branch-local t)
+ (2 'git-commit-comment-branch-remote t)
+ (3 'bold t)))
+ (eval
+ ;; Your branch is up to date with 'master'.
+ ;; Your branch and 'master' have diverged,
+ . `(,(format
+ "^%s Your branch \\(?:is up[- ]to[- ]date with\\|and\\) '%s'"
+ comment-start git-commit--branch-name-regexp)
+ (1 'git-commit-comment-branch-local t)
+ (2 'git-commit-comment-branch-remote t)))
+ (eval
+ ;; and have 1 and 2 different commits each, respectively.
+ . `(,(format
+ "^%s and have \\([0-9]*\\) and \\([0-9]*\\) commits each"
+ comment-start)
+ (1 'bold t)
+ (2 'bold t)))))
+
+(defvar git-commit-font-lock-keywords git-commit-font-lock-keywords-3
+ "Font-Lock keywords for Git-Commit mode.")
+
+(defun git-commit-setup-font-lock ()
+ (with-demoted-errors "Error running git-commit-setup-font-lock: %S"
+ (let ((table (make-syntax-table (syntax-table))))
+ (when comment-start
+ (modify-syntax-entry (string-to-char comment-start) "." table))
+ (modify-syntax-entry ?# "." table)
+ (modify-syntax-entry ?\" "." table)
+ (modify-syntax-entry ?\' "." table)
+ (modify-syntax-entry ?` "." table)
+ (set-syntax-table table))
+ (setq-local comment-start
+ (or (with-temp-buffer
+ (and (zerop
+ (call-process
+ (git-commit-executable) nil (list t nil) nil
+ "config" "core.commentchar"))
+ (not (bobp))
+ (progn
+ (goto-char (point-min))
+ (buffer-substring (point) (line-end-position)))))
+ "#"))
+ (setq-local comment-start-skip (format "^%s+[\s\t]*" comment-start))
+ (setq-local comment-end-skip "\n")
+ (setq-local comment-use-syntax nil)
+ (setq-local git-commit--branch-name-regexp
+ (if (and (featurep 'magit-git)
+ ;; When using cygwin git, we may end up in a
+ ;; non-existing directory, which would cause
+ ;; any git calls to signal an error.
+ (file-accessible-directory-p default-directory))
+ (progn
+ ;; Make sure the below functions are available.
+ (require 'magit)
+ ;; Font-Lock wants every submatch to succeed, so
+ ;; also match the empty string. Avoid listing
+ ;; remote branches and using `regexp-quote',
+ ;; because in repositories have thousands of
+ ;; branches that would be very slow. See #4353.
+ (format "\\(\\(?:%s\\)\\|\\)\\([^']+\\)"
+ (mapconcat #'identity
+ (magit-list-local-branch-names)
+ "\\|")))
+ "\\([^']*\\)"))
+ (setq-local font-lock-multiline t)
+ (add-hook 'font-lock-extend-region-functions
+ #'git-commit-extend-region-summary-line
+ t t)
+ (font-lock-add-keywords nil git-commit-font-lock-keywords)))
+
+(defun git-commit-propertize-diff ()
+ (require 'diff-mode)
+ (save-excursion
+ (goto-char (point-min))
+ (when (re-search-forward "^diff --git" nil t)
+ (beginning-of-line)
+ (let ((buffer (current-buffer)))
+ (insert
+ (with-temp-buffer
+ (insert
+ (with-current-buffer buffer
+ (prog1 (buffer-substring-no-properties (point) (point-max))
+ (delete-region (point) (point-max)))))
+ (let ((diff-default-read-only nil))
+ (diff-mode))
+ (let (font-lock-verbose font-lock-support-mode)
+ (if (fboundp 'font-lock-ensure)
+ (font-lock-ensure)
+ (with-no-warnings
+ (font-lock-fontify-buffer))))
+ (let (next (pos (point-min)))
+ (while (setq next (next-single-property-change pos 'face))
+ (put-text-property pos next 'font-lock-face
+ (get-text-property pos 'face))
+ (setq pos next))
+ (put-text-property pos (point-max) 'font-lock-face
+ (get-text-property pos 'face)))
+ (buffer-string)))))))
+
+;;; Elisp Text Mode
+
+(define-derived-mode git-commit-elisp-text-mode text-mode "ElText"
+ "Major mode for editing commit messages of elisp projects.
+This is intended for use as `git-commit-major-mode' for projects
+that expect `symbols' to look like this. I.e. like they look in
+Elisp doc-strings, including this one. Unlike in doc-strings,
+\"strings\" also look different than the other text."
+ (setq font-lock-defaults '(git-commit-elisp-text-mode-keywords)))
+
+(defvar git-commit-elisp-text-mode-keywords
+ `((,(concat "[`‘]\\(" lisp-mode-symbol-regexp "\\)['’]")
+ (1 font-lock-constant-face prepend))
+ ("\"[^\"]*\"" (0 font-lock-string-face prepend))))
+
+;;; _
+(provide 'git-commit)
+;;; git-commit.el ends here
diff --git a/elpa/git-commit-20220429.934/git-commit.elc b/elpa/git-commit-20220429.934/git-commit.elc
new file mode 100644
index 0000000..20c4144
--- /dev/null
+++ b/elpa/git-commit-20220429.934/git-commit.elc
Binary files differ
diff --git a/elpa/gnupg/pubring.kbx b/elpa/gnupg/pubring.kbx
new file mode 100644
index 0000000..3e70f7a
--- /dev/null
+++ b/elpa/gnupg/pubring.kbx
Binary files differ
diff --git a/elpa/gnupg/pubring.kbx~ b/elpa/gnupg/pubring.kbx~
new file mode 100644
index 0000000..8e7f46d
--- /dev/null
+++ b/elpa/gnupg/pubring.kbx~
Binary files differ
diff --git a/elpa/gnupg/trustdb.gpg b/elpa/gnupg/trustdb.gpg
new file mode 100644
index 0000000..bcf57c2
--- /dev/null
+++ b/elpa/gnupg/trustdb.gpg
Binary files differ
diff --git a/elpa/goto-chg-20220107.1733/goto-chg-autoloads.el b/elpa/goto-chg-20220107.1733/goto-chg-autoloads.el
new file mode 100644
index 0000000..49b1b93
--- /dev/null
+++ b/elpa/goto-chg-20220107.1733/goto-chg-autoloads.el
@@ -0,0 +1,55 @@
+;;; goto-chg-autoloads.el --- automatically extracted autoloads -*- lexical-binding: t -*-
+;;
+;;; Code:
+
+(add-to-list 'load-path (directory-file-name
+ (or (file-name-directory #$) (car load-path))))
+
+
+;;;### (autoloads nil "goto-chg" "goto-chg.el" (0 0 0 0))
+;;; Generated autoloads from goto-chg.el
+
+(autoload 'goto-last-change "goto-chg" "\
+Go to the point where the last edit was made in the current buffer.
+Repeat the command to go to the second last edit, etc.
+
+To go back to more recent edit, the reverse of this command, use \\[goto-last-change-reverse]
+or precede this command with \\[universal-argument] - (minus).
+
+It does not go to the same point twice even if there has been many edits
+there. I call the minimal distance between distinguishable edits \"span\".
+Set variable `glc-default-span' to control how close is \"the same point\".
+Default span is 8.
+The span can be changed temporarily with \\[universal-argument] right before \\[goto-last-change]:
+\\[universal-argument] <NUMBER> set current span to that number,
+\\[universal-argument] (no number) multiplies span by 4, starting with default.
+The so set span remains until it is changed again with \\[universal-argument], or the consecutive
+repetition of this command is ended by any other command.
+
+When span is zero (i.e. \\[universal-argument] 0) subsequent \\[goto-last-change] visits each and
+every point of edit and a message shows what change was made there.
+In this case it may go to the same point twice.
+
+This command uses undo information. If undo is disabled, so is this command.
+At times, when undo information becomes too large, the oldest information is
+discarded. See variable `undo-limit'.
+
+\(fn ARG)" t nil)
+
+(autoload 'goto-last-change-reverse "goto-chg" "\
+Go back to more recent changes after \\[goto-last-change] have been used.
+See `goto-last-change' for use of prefix argument.
+
+\(fn ARG)" t nil)
+
+(register-definition-prefixes "goto-chg" '("glc-"))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; coding: utf-8
+;; End:
+;;; goto-chg-autoloads.el ends here
diff --git a/elpa/goto-chg-20220107.1733/goto-chg-pkg.el b/elpa/goto-chg-20220107.1733/goto-chg-pkg.el
new file mode 100644
index 0000000..cd8628d
--- /dev/null
+++ b/elpa/goto-chg-20220107.1733/goto-chg-pkg.el
@@ -0,0 +1,2 @@
+;;; Generated package description from goto-chg.el -*- no-byte-compile: t -*-
+(define-package "goto-chg" "20220107.1733" "Go to last change" '((emacs "24.1")) :commit "278cd3e6d5107693aa2bb33189ca503f22f227d0" :authors '(("David Andersson <l.david.andersson(at)sverige.nu>")) :maintainer '("Vasilij Schneidermann" . "mail@vasilij.de") :keywords '("convenience" "matching") :url "https://github.com/emacs-evil/goto-chg")
diff --git a/elpa/goto-chg-20220107.1733/goto-chg.el b/elpa/goto-chg-20220107.1733/goto-chg.el
new file mode 100644
index 0000000..1aa6a4c
--- /dev/null
+++ b/elpa/goto-chg-20220107.1733/goto-chg.el
@@ -0,0 +1,370 @@
+;;; goto-chg.el --- Go to last change
+;;--------------------------------------------------------------------
+;;
+;; Copyright (C) 2002-2008,2013 David Andersson
+;;
+;; 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 <https://www.gnu.org/licenses/>.
+;;
+;;-------------------------------------------------------------------
+;;
+;; Author: David Andersson <l.david.andersson(at)sverige.nu>
+;; Maintainer: Vasilij Schneidermann <mail@vasilij.de>
+;; Created: 16 May 2002
+;; Version: 1.7.5
+;; Package-Version: 20220107.1733
+;; Package-Commit: 278cd3e6d5107693aa2bb33189ca503f22f227d0
+;; Package-Requires: ((emacs "24.1"))
+;; Keywords: convenience, matching
+;; URL: https://github.com/emacs-evil/goto-chg
+;;
+;;; Commentary:
+;;
+;; Goto Last Change
+;;
+;; Goto the point of the most recent edit in the buffer.
+;; When repeated, goto the second most recent edit, etc.
+;; Negative argument, C-u -, for reverse direction.
+;; Works by looking into buffer-undo-list to find points of edit.
+;;
+;; You would probably like to bind this command to a key.
+;; For example in your ~/.emacs:
+;;
+;; (require 'goto-chg)
+;;
+;; (global-set-key [(control ?.)] 'goto-last-change)
+;; (global-set-key [(control ?,)] 'goto-last-change-reverse)
+;;
+;; Works with emacs-19.29, 19.31, 20.3, 20.7, 21.1, 21.4, 22.1 and 23.1
+;; Works with XEmacs-20.4 and 21.4 (but see todo about `last-command' below)
+;;
+;;--------------------------------------------------------------------
+;; History
+;;
+;; Ver 1.7.5 2022-01-04 Axel Foesman, Stefan Kangas
+;; Consider all entries in undo-tree changesets, bump license to GPL3+
+;; Ver 1.7.4 2020-10-08 Vasilij Schneidermann
+;; Remove hard dependency on undo-tree
+;; Ver 1.7.3 2019-01-07 Vasilij Schneidermann
+;; Fix errors when used with persistent undo
+;; Ver 1.7.2 2018-01-05 Vasilij Schneidermann
+;; Fix byte-compiler warnings again
+;; Ver 1.7.1 2017-12-31 Vasilij Schneidermann
+;; Fix byte-compiler warnings
+;; Ver 1.7 2017-09-17 Vasilij Schneidermann
+;; Make it work with undo-tree-mode (see
+;; <https://github.com/martinp26/goto-chg>)
+;; Ver 1.6 2013-12-12 David Andersson
+;; Add keywords; Cleanup comments
+;; Ver 1.5 2013-12-11 David Andersson
+;; Autoload and document `goto-last-change-reverse'
+;; Ver 1.4 2008-09-20 David Andersson
+;; Improved property change description; Update comments.
+;; Ver 1.3 2007-03-14 David Andersson
+;; Added `goto-last-change-reverse'
+;; Ver 1.2 2003-04-06 David Andersson
+;; Don't let repeating error depthen glc-probe-depth.
+;; Ver 1.1 2003-04-06 David Andersson
+;; Zero arg describe changes. Negative arg go back.
+;; Autoload. Remove message using nil in stead of an empty string.
+;; Ver 1.0 2002-05-18 David Andersson
+;; Initial version
+;;
+;;--------------------------------------------------------------------
+;;
+;;todo: Rename "goto-chg.el" -> "gotochange.el" or "goto-chgs" ?
+;;todo: Rename function goto-last-change -> goto-last-edit ?
+;;todo: Rename adjective "-last-" -> "-latest-" or "-most-recent-" ?
+;;todo: There are some, maybe useful, funcs for region undo
+;; in simple.el in emacs 20. Take a look.
+;;todo: Add functionality to visit changed point in text order, not only in
+;; chronological order. (Naa, highlight-changes-mode does that).
+;;todo: Inverse indication that a change has been saved or not
+;;todo: Highlight the range of text involved in the last change?
+;;todo: See session-jump-to-last-change in session.el?
+;;todo: Unhide invisible text (e.g. outline mode) like isearch do.
+;;todo: XEmacs sets last-command to `t' after an error, so you cannot reverse
+;; after "No furter change info". Should we bother?
+;;todo: Try distinguish "No further change info" (end of truncated undo list)
+;; and "No further changes" (end of a complete undo list).
+;;
+;;--------------------------------------------------------------------
+
+;;; Code:
+
+(require 'undo-tree nil t)
+
+(defvar glc-default-span 8 "*goto-last-change don't visit the same point twice.
+glc-default-span tells how far around a visited point not to visit again.")
+(defvar glc-current-span 8 "Internal for goto-last-change.\nA copy of glc-default-span or the ARG passed to goto-last-change.")
+(defvar glc-probe-depth 0 "Internal for goto-last-change.\nIt is non-zero between successive goto-last-change.")
+(defvar glc-direction 1 "Direction goto-last-change moves towards.")
+
+;;todo: Find begin and end of line, then use it somewhere
+
+(defun glc-fixup-edit (e)
+ "Convert an Emacs 27.1-style combined change to a regular edit."
+ (when (and (consp e)
+ (eq (car e) 'apply)
+ (not (functionp (cadr e)))
+ (eq (nth 4 e) 'undo--wrap-and-run-primitive-undo))
+ (let ((args (last e)))
+ (when (and (consp args) (= (length args) 1)
+ (consp (car args)) (= (length (car args)) 1)
+ (consp (caar args)) (numberp (car (caar args))) (numberp (cdr (caar args))))
+ (setq e (caar args)))))
+ e)
+
+(defun glc-center-ellipsis (str maxlen &optional ellipsis)
+ "Truncate STRING in the middle to length MAXLEN.
+If STRING is max MAXLEN just return the string.
+Optional third argument is the replacement, which defaults to \"...\"."
+ (if (<= (length str) maxlen)
+ str
+ ;; else
+ (let* ((lipsis (or ellipsis "..."))
+ (i (/ (- maxlen (length lipsis)) 2)))
+ (concat (substring str 0 i)
+ lipsis
+ (substring str (- i))))))
+
+(defun glc-adjust-pos2 (pos p1 p2 adj)
+ ;; Helper function to glc-adjust-pos
+ ;; p1, p2: interval where an edit occured
+ ;; adj: amount of text added (positive) or removed (negativ) by the edit
+ ;; Return pos if well before p1, or pos+adj if well after p2, or nil if too close
+ (cond ((<= pos (- p1 glc-current-span))
+ pos)
+ ((> pos (+ p2 glc-current-span))
+ (+ pos adj))
+ ((zerop glc-current-span)
+ p1)
+ (t
+ nil)))
+
+(defun glc-adjust-pos (pos e)
+ "Given POS, a buffer position before the edit E, compute and return
+the \"same\" buffer position after E happened.
+Exception: return nil if POS is closer than `glc-current-span' to the edit E.
+\nInsertion edits before POS returns a larger value.
+Deletion edits before POS returns a smaller value.
+\nThe edit E is an entry from the `buffer-undo-list'. See for details."
+ (setq e (glc-fixup-edit e))
+ (cond ((atom e) ; nil==cmd boundary, or, num==changed pos
+ pos)
+ ((numberp (car e)) ; (beg . end)==insertion
+ (glc-adjust-pos2 pos (car e) (car e) (- (cdr e) (car e))))
+ ((stringp (car e)) ; (string . pos)==deletion
+ (glc-adjust-pos2 pos (abs (cdr e)) (+ (abs (cdr e)) (length (car e))) (- (length (car e)))))
+ ((null (car e)) ; (nil prop val beg . end)==prop change
+ (glc-adjust-pos2 pos (nth 3 e) (nthcdr 4 e) 0))
+ (t ; (marker . dist)==marker moved
+ pos)))
+
+;; If recursive in stead of iterative (while), it tends to fill the call stack.
+;; (Isn't it tail optimized?)
+(defun glc-adjust-list (r)
+ "R is list of edit entries in chronological order.
+Pick the point of the first edit entry and update that point with
+the second, third, etc, edit entries. Return the final updated point,
+or nil if the point was closer than `glc-current-span' to some edit in R.
+\nR is basically a reversed slice from the buffer-undo-list."
+ (if r
+ ;; Get pos
+ (let ((pos (glc-get-pos (car r))))
+ (setq r (cdr r))
+ ;; Walk back in reverse list
+ (while (and r pos)
+ (setq pos (glc-adjust-pos pos (car r))
+ r (cdr r)))
+ pos)
+ ;; else
+ nil))
+
+(defun glc-get-pos (e)
+ "If E represents an edit, return a position value in E, the position
+where the edit took place. Return nil if E represents no real change.
+\nE is an entry in the buffer-undo-list."
+ (setq e (glc-fixup-edit e))
+ (cond ((numberp e) e) ; num==changed position
+ ((atom e) nil) ; nil==command boundary
+ ((numberp (car e)) (cdr e)) ; (beg . end)==insertion
+ ((stringp (car e)) (abs (cdr e))) ; (string . pos)==deletion
+ ((null (car e)) (nthcdr 4 e)) ; (nil ...)==text property change
+ ((atom (car e)) nil) ; (t ...)==file modification time
+ (t nil))) ; (marker ...)==marker moved
+
+(defun glc-get-descript (e &optional n)
+ "If E represents an edit, return a short string describing E.
+Return nil if E represents no real change.
+\nE is an entry in the buffer-undo-list."
+ (setq e (glc-fixup-edit e))
+ (let ((nn (or (format "T-%d: " n) "")))
+ (cond ((numberp e) "New position") ; num==changed position
+ ((atom e) nil) ; nil==command boundary
+ ((numberp (car e)) ; (beg . end)==insertion
+ (if (and n (< n 2))
+ (format "%sInserted %d chars \"%s\"" nn (- (cdr e) (car e))
+ (glc-center-ellipsis (buffer-substring (car e) (cdr e)) 60))
+ ;; else
+ ;; An older insert. The inserted text cannot easily be computed.
+ ;; Just show the char count.
+ (format "%sInserted %d chars" nn (- (cdr e) (car e)))))
+ ((stringp (car e)) ; (string . pos)==deletion
+ (format "%sDeleted \"%s\"" nn (glc-center-ellipsis (car e) 60)))
+ ((null (car e)) ; (nil ...)==text property change
+ (format "%sProperty change" nn))
+ ((atom (car e)) nil) ; (t ...)==file modification time
+ (t nil)))) ; (marker ...)==marker moved
+
+(defun glc-is-positionable (e)
+ "Return non-nil if E is an insertion, deletion or text property change.
+\nE is an entry in the buffer-undo-list."
+ (and (not (numberp e)) (glc-get-pos e)))
+
+(defun glc-is-filetime (e)
+ "Return t if E indicates a buffer became \"modified\",
+that is, it was previously saved or unchanged. Nil otherwise."
+ (and (listp e) (eq (car e) t)))
+
+(declare-function undo-tree-current "ext:undo-tree")
+(declare-function undo-tree-node-previous "ext:undo-tree")
+(declare-function undo-tree-node-undo "ext:undo-tree")
+(declare-function undo-list-transfer-to-tree "ext:undo-tree")
+(defvar buffer-undo-tree)
+
+;;;###autoload
+(defun goto-last-change (arg)
+"Go to the point where the last edit was made in the current buffer.
+Repeat the command to go to the second last edit, etc.
+\nTo go back to more recent edit, the reverse of this command, use \\[goto-last-change-reverse]
+or precede this command with \\[universal-argument] - (minus).
+\nIt does not go to the same point twice even if there has been many edits
+there. I call the minimal distance between distinguishable edits \"span\".
+Set variable `glc-default-span' to control how close is \"the same point\".
+Default span is 8.
+The span can be changed temporarily with \\[universal-argument] right before \\[goto-last-change]:
+\\[universal-argument] <NUMBER> set current span to that number,
+\\[universal-argument] (no number) multiplies span by 4, starting with default.
+The so set span remains until it is changed again with \\[universal-argument], or the consecutive
+repetition of this command is ended by any other command.
+\nWhen span is zero (i.e. \\[universal-argument] 0) subsequent \\[goto-last-change] visits each and
+every point of edit and a message shows what change was made there.
+In this case it may go to the same point twice.
+\nThis command uses undo information. If undo is disabled, so is this command.
+At times, when undo information becomes too large, the oldest information is
+discarded. See variable `undo-limit'."
+ (interactive "P")
+ (cond ((not (eq this-command last-command))
+ ;; Start a glc sequence
+ ;; Don't go to current point if last command was an obvious edit
+ ;; (yank or self-insert, but not kill-region). Makes it easier to
+ ;; jump back and forth when copying seleced lines.
+ (setq glc-probe-depth (if (memq last-command '(yank self-insert-command)) 1 0)
+ glc-direction 1
+ glc-current-span glc-default-span)
+ (if (< (prefix-numeric-value arg) 0)
+ (error "Negative arg: Cannot reverse as the first operation"))))
+ (cond ((and (null buffer-undo-list)
+ (or (not (boundp 'buffer-undo-tree))
+ (null buffer-undo-tree)))
+ (error "Buffer has not been changed"))
+ ((eq buffer-undo-list t)
+ (error "No change info (undo is disabled)")))
+ (cond ((numberp arg) ; Numeric arg sets span
+ (setq glc-current-span (abs arg)))
+ ((consp arg) ; C-u's multiply previous span by 4
+ (setq glc-current-span (* (abs (car arg)) glc-default-span))
+ (message "Current span is %d chars" glc-current-span))) ;todo: keep message with "waiting" and "is saved"
+ (setq glc-direction (if (< (prefix-numeric-value arg) 0) -1 1))
+ (let* (rev ; Reversed (and filtered) undo list
+ pos ; The pos we look for, nil until found
+ (n 0) ; Steps in undo list (length of 'rev')
+ (undo-tree-p (bound-and-true-p undo-tree-mode))
+ (orig-l (if (not undo-tree-p)
+ buffer-undo-list
+ (undo-list-transfer-to-tree)
+ ;; Each node has a list of undo entries: Need to flatten.
+ ;; Keep current entries and next node to consider in tuple.
+ (cons nil (undo-tree-current buffer-undo-tree))))
+ (l orig-l)
+ (passed-save-entry (not (buffer-modified-p)))
+ (new-probe-depth glc-probe-depth))
+ ;; Walk back and forth in the buffer-undo-list, each time one step deeper,
+ ;; until we can walk back the whole list with a 'pos' that is not coming
+ ;; too close to another edit.
+ (while (null pos)
+ (setq new-probe-depth (+ new-probe-depth glc-direction))
+ (when (< glc-direction 0)
+ (setq rev ()
+ n 0
+ l orig-l
+ passed-save-entry (not (buffer-modified-p))))
+ (when (< new-probe-depth 1)
+ (error "No later change info"))
+ (when (> n 150)
+ (message "working..."))
+ ;; Walk forward in buffer-undo-list, glc-probe-depth steps.
+ ;; Build reverse list along the way
+ (while (< n new-probe-depth)
+ (let ((entry (if (not undo-tree-p)
+ (if l
+ (pop l)
+ (error "No further change info"))
+ (when (null (car l))
+ (setq l (cons (cons nil
+ (undo-tree-node-undo
+ (or (cdr l)
+ (error "No further change info"))))
+ (undo-tree-node-previous (cdr l)))))
+ (pop (car l)))))
+ (cond ((glc-is-positionable entry)
+ (setq n (1+ n)
+ rev (cons entry rev)))
+ ((or passed-save-entry (glc-is-filetime entry))
+ (setq passed-save-entry t)))))
+ ;; Walk back in reverse list, from older to newer edits.
+ ;; Adjusting pos along the way.
+ (setq pos (glc-adjust-list rev)))
+ ;; Found a place not previously visited, in 'pos'.
+ ;; (An error have been issued if nothing (more) found.)
+ (if (> n 150)
+ (message nil)) ; remove message "working..."
+ (if (and (= glc-current-span 0) (glc-get-descript (car rev) n))
+ (message "%s" (glc-get-descript (car rev) n))
+ ;; else
+ (if passed-save-entry
+ (message "(This change is saved)")))
+ (setq glc-probe-depth new-probe-depth)
+ (goto-char pos)))
+
+;;;###autoload
+(defun goto-last-change-reverse (arg)
+ "Go back to more recent changes after \\[goto-last-change] have been used.
+See `goto-last-change' for use of prefix argument."
+ (interactive "P")
+ ;; Negate arg, all kinds
+ (cond ((eq arg nil) (setq arg '-))
+ ((eq arg '-) (setq arg nil))
+ ((listp arg) (setq arg (list (- (car arg)))))
+ (t (setq arg (- arg))))
+ ;; Make 'goto-last-change-reverse' look like 'goto-last-change'
+ (cond ((eq last-command this-command)
+ (setq last-command 'goto-last-change)))
+ (setq this-command 'goto-last-change)
+ ;; Call 'goto-last-change' to do the job
+ (goto-last-change arg))
+
+(provide 'goto-chg)
+
+;;; goto-chg.el ends here
diff --git a/elpa/goto-chg-20220107.1733/goto-chg.elc b/elpa/goto-chg-20220107.1733/goto-chg.elc
new file mode 100644
index 0000000..93d85e6
--- /dev/null
+++ b/elpa/goto-chg-20220107.1733/goto-chg.elc
Binary files differ
diff --git a/elpa/ht-20210119.741/ht-autoloads.el b/elpa/ht-20210119.741/ht-autoloads.el
new file mode 100644
index 0000000..853fc5a
--- /dev/null
+++ b/elpa/ht-20210119.741/ht-autoloads.el
@@ -0,0 +1,22 @@
+;;; ht-autoloads.el --- automatically extracted autoloads -*- lexical-binding: t -*-
+;;
+;;; Code:
+
+(add-to-list 'load-path (directory-file-name
+ (or (file-name-directory #$) (car load-path))))
+
+
+;;;### (autoloads nil "ht" "ht.el" (0 0 0 0))
+;;; Generated autoloads from ht.el
+
+(register-definition-prefixes "ht" 'nil)
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; coding: utf-8
+;; End:
+;;; ht-autoloads.el ends here
diff --git a/elpa/ht-20210119.741/ht-pkg.el b/elpa/ht-20210119.741/ht-pkg.el
new file mode 100644
index 0000000..91d3285
--- /dev/null
+++ b/elpa/ht-20210119.741/ht-pkg.el
@@ -0,0 +1,2 @@
+;;; Generated package description from ht.el -*- no-byte-compile: t -*-
+(define-package "ht" "20210119.741" "The missing hash table library for Emacs" '((dash "2.12.0")) :commit "c4c1be487d6ecb353d07881526db05d7fc90ea87" :authors '(("Wilfred Hughes" . "me@wilfred.me.uk")) :maintainer '("Wilfred Hughes" . "me@wilfred.me.uk") :keywords '("hash table" "hash map" "hash"))
diff --git a/elpa/ht-20210119.741/ht.el b/elpa/ht-20210119.741/ht.el
new file mode 100644
index 0000000..0809ef1
--- /dev/null
+++ b/elpa/ht-20210119.741/ht.el
@@ -0,0 +1,337 @@
+;;; ht.el --- The missing hash table library for Emacs -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2013 Wilfred Hughes
+
+;; Author: Wilfred Hughes <me@wilfred.me.uk>
+;; Version: 2.4
+;; Package-Version: 20210119.741
+;; Package-Commit: c4c1be487d6ecb353d07881526db05d7fc90ea87
+;; Keywords: hash table, hash map, hash
+;; Package-Requires: ((dash "2.12.0"))
+
+;; 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:
+
+;; The missing hash table library for Emacs.
+;;
+;; See documentation at https://github.com/Wilfred/ht.el
+
+;;; Code:
+
+(require 'dash)
+(require 'gv)
+(eval-when-compile
+ (require 'inline))
+
+(defmacro ht (&rest pairs)
+ "Create a hash table with the key-value pairs given.
+Keys are compared with `equal'.
+
+\(fn (KEY-1 VALUE-1) (KEY-2 VALUE-2) ...)"
+ (let* ((table-symbol (make-symbol "ht-temp"))
+ (assignments
+ (mapcar
+ (lambda (pair) `(ht-set! ,table-symbol ,@pair))
+ pairs)))
+ `(let ((,table-symbol (ht-create)))
+ ,@assignments
+ ,table-symbol)))
+
+(define-inline ht-set! (table key value)
+ "Associate KEY in TABLE with VALUE."
+ (inline-quote
+ (prog1 nil
+ (puthash ,key ,value ,table))))
+
+(defalias 'ht-set 'ht-set!)
+
+(define-inline ht-create (&optional test)
+ "Create an empty hash table.
+
+TEST indicates the function used to compare the hash
+keys. Default is `equal'. It can be `eq', `eql', `equal' or a
+user-supplied test created via `define-hash-table-test'."
+ (declare (side-effect-free t))
+ (inline-quote (make-hash-table :test (or ,test 'equal))))
+
+(defun ht<-alist (alist &optional test)
+ "Create a hash table with initial values according to ALIST.
+
+TEST indicates the function used to compare the hash
+keys. Default is `equal'. It can be `eq', `eql', `equal' or a
+user-supplied test created via `define-hash-table-test'."
+ (declare (side-effect-free t))
+ (let ((h (ht-create test)))
+ ;; the first key-value pair in an alist gets precedence, so we
+ ;; start from the end of the list:
+ (dolist (pair (reverse alist) h)
+ (let ((key (car pair))
+ (value (cdr pair)))
+ (ht-set! h key value)))))
+
+(defalias 'ht-from-alist 'ht<-alist)
+
+(defun ht<-plist (plist &optional test)
+ "Create a hash table with initial values according to PLIST.
+
+TEST indicates the function used to compare the hash
+keys. Default is `equal'. It can be `eq', `eql', `equal' or a
+user-supplied test created via `define-hash-table-test'."
+ (declare (side-effect-free t))
+ (let ((h (ht-create test)))
+ (dolist (pair (nreverse (-partition 2 plist)) h)
+ (let ((key (car pair))
+ (value (cadr pair)))
+ (ht-set! h key value)))))
+
+(defalias 'ht-from-plist 'ht<-plist)
+
+(define-inline ht-get (table key &optional default)
+ "Look up KEY in TABLE, and return the matching value.
+If KEY isn't present, return DEFAULT (nil if not specified)."
+ (declare (side-effect-free t))
+ (inline-quote
+ (gethash ,key ,table ,default)))
+
+;; Don't use `ht-set!' here, gv setter was assumed to return the value
+;; to be set.
+(gv-define-setter ht-get (value table key) `(puthash ,key ,value ,table))
+
+(define-inline ht-get* (table &rest keys)
+ "Look up KEYS in nested hash tables, starting with TABLE.
+The lookup for each key should return another hash table, except
+for the final key, which may return any value."
+ (declare (side-effect-free t))
+ (inline-letevals (table keys)
+ (inline-quote
+ (progn
+ (while ,keys
+ (setf ,table (ht-get ,table (pop ,keys))))
+ ,table))))
+
+(put 'ht-get* 'compiler-macro
+ (lambda (_ table &rest keys)
+ (--reduce-from `(ht-get ,acc ,it) table keys)))
+
+(defun ht-update! (table from-table)
+ "Update TABLE according to every key-value pair in FROM-TABLE."
+ (maphash
+ (lambda (key value) (puthash key value table))
+ from-table)
+ nil)
+
+(defalias 'ht-update 'ht-update!)
+
+(defun ht-merge (&rest tables)
+ "Crete a new tables that includes all the key-value pairs from TABLES.
+If multiple have tables have the same key, the value in the last
+table is used."
+ (let ((merged (ht-create)))
+ (mapc (lambda (table) (ht-update! merged table)) tables)
+ merged))
+
+(define-inline ht-remove! (table key)
+ "Remove KEY from TABLE."
+ (inline-quote (remhash ,key ,table)))
+
+(defalias 'ht-remove 'ht-remove!)
+
+(define-inline ht-clear! (table)
+ "Remove all keys from TABLE."
+ (inline-quote
+ (prog1 nil
+ (clrhash ,table))))
+
+(defalias 'ht-clear 'ht-clear!)
+
+(defun ht-map (function table)
+ "Apply FUNCTION to each key-value pair of TABLE, and make a list of the results.
+FUNCTION is called with two arguments, KEY and VALUE."
+ (let (results)
+ (maphash
+ (lambda (key value)
+ (push (funcall function key value) results))
+ table)
+ results))
+
+(defmacro ht-amap (form table)
+ "Anaphoric version of `ht-map'.
+For every key-value pair in TABLE, evaluate FORM with the
+variables KEY and VALUE bound. If you don't use both of
+these variables, then use `ht-map' to avoid warnings."
+ `(ht-map (lambda (key value) ,form) ,table))
+
+(defun ht-keys (table)
+ "Return a list of all the keys in TABLE."
+ (declare (side-effect-free t))
+ (ht-map (lambda (key _value) key) table))
+
+(defun ht-values (table)
+ "Return a list of all the values in TABLE."
+ (declare (side-effect-free t))
+ (ht-map (lambda (_key value) value) table))
+
+(defun ht-items (table)
+ "Return a list of two-element lists '(key value) from TABLE."
+ (declare (side-effect-free t))
+ (ht-amap (list key value) table))
+
+(defalias 'ht-each 'maphash
+ "Apply FUNCTION to each key-value pair of TABLE.
+Returns nil, used for side-effects only.")
+
+(defmacro ht-aeach (form table)
+ "Anaphoric version of `ht-each'.
+For every key-value pair in TABLE, evaluate FORM with the
+variables key and value bound."
+ `(ht-each (lambda (key value) ,form) ,table))
+
+(defun ht-select-keys (table keys)
+ "Return a copy of TABLE with only the specified KEYS."
+ (declare (side-effect-free t))
+ (let (result)
+ (setq result (make-hash-table :test (hash-table-test table)))
+ (dolist (key keys result)
+ (if (not (equal (gethash key table 'key-not-found) 'key-not-found))
+ (puthash key (gethash key table) result)))))
+
+(defun ht->plist (table)
+ "Return a flat list '(key1 value1 key2 value2...) from TABLE.
+
+Note that hash tables are unordered, so this cannot be an exact
+inverse of `ht<-plist'. The following is not guaranteed:
+
+\(let ((data '(a b c d)))
+ (equalp data
+ (ht->plist (ht<-plist data))))"
+ (declare (side-effect-free t))
+ (apply 'append (ht-items table)))
+
+(defalias 'ht-to-plist 'ht->plist)
+
+(define-inline ht-copy (table)
+ "Return a shallow copy of TABLE (keys and values are shared)."
+ (declare (side-effect-free t))
+ (inline-quote (copy-hash-table ,table)))
+
+(defun ht->alist (table)
+ "Return a list of two-element lists '(key . value) from TABLE.
+
+Note that hash tables are unordered, so this cannot be an exact
+inverse of `ht<-alist'. The following is not guaranteed:
+
+\(let ((data '((a . b) (c . d))))
+ (equalp data
+ (ht->alist (ht<-alist data))))"
+ (declare (side-effect-free t))
+ (ht-amap (cons key value) table))
+
+(defalias 'ht-to-alist 'ht->alist)
+
+(defalias 'ht? 'hash-table-p)
+
+(defalias 'ht-p 'hash-table-p)
+
+(define-inline ht-contains? (table key)
+ "Return 't if TABLE contains KEY."
+ (declare (side-effect-free t))
+ (inline-quote
+ (let ((not-found-symbol (make-symbol "ht--not-found")))
+ (not (eq (ht-get ,table ,key not-found-symbol) not-found-symbol)))))
+
+(defalias 'ht-contains-p 'ht-contains?)
+
+(define-inline ht-size (table)
+ "Return the actual number of entries in TABLE."
+ (declare (side-effect-free t))
+ (inline-quote
+ (hash-table-count ,table)))
+
+(define-inline ht-empty? (table)
+ "Return true if the actual number of entries in TABLE is zero."
+ (declare (side-effect-free t))
+ (inline-quote
+ (zerop (ht-size ,table))))
+
+(defalias 'ht-empty-p 'ht-empty?)
+
+(defun ht-select (function table)
+ "Return a hash table containing all entries in TABLE for which
+FUNCTION returns a truthy value.
+
+FUNCTION is called with two arguments, KEY and VALUE."
+ (let ((results (ht-create)))
+ (ht-each
+ (lambda (key value)
+ (when (funcall function key value)
+ (ht-set! results key value)))
+ table)
+ results))
+
+(defun ht-reject (function table)
+ "Return a hash table containing all entries in TABLE for which
+FUNCTION returns a falsy value.
+
+FUNCTION is called with two arguments, KEY and VALUE."
+ (let ((results (ht-create)))
+ (ht-each
+ (lambda (key value)
+ (unless (funcall function key value)
+ (ht-set! results key value)))
+ table)
+ results))
+
+(defun ht-reject! (function table)
+ "Delete entries from TABLE for which FUNCTION returns a falsy value.
+
+FUNCTION is called with two arguments, KEY and VALUE."
+ (ht-each
+ (lambda (key value)
+ (when (funcall function key value)
+ (remhash key table)))
+ table)
+ nil)
+
+(defalias 'ht-delete-if 'ht-reject!)
+
+(defun ht-find (function table)
+ "Return (key, value) from TABLE for which FUNCTION returns a truthy value.
+Return nil otherwise.
+
+FUNCTION is called with two arguments, KEY and VALUE."
+ (catch 'break
+ (ht-each
+ (lambda (key value)
+ (when (funcall function key value)
+ (throw 'break (list key value))))
+ table)))
+
+(defun ht-equal? (table1 table2)
+ "Return t if TABLE1 and TABLE2 have the same keys and values.
+Does not compare equality predicates."
+ (declare (side-effect-free t))
+ (let ((keys1 (ht-keys table1))
+ (keys2 (ht-keys table2))
+ (sentinel (make-symbol "ht-sentinel")))
+ (and (equal (length keys1) (length keys2))
+ (--all?
+ (equal (ht-get table1 it)
+ (ht-get table2 it sentinel))
+ keys1))))
+
+(defalias 'ht-equal-p 'ht-equal?)
+
+(provide 'ht)
+;;; ht.el ends here
diff --git a/elpa/ht-20210119.741/ht.elc b/elpa/ht-20210119.741/ht.elc
new file mode 100644
index 0000000..2f0a5d7
--- /dev/null
+++ b/elpa/ht-20210119.741/ht.elc
Binary files differ
diff --git a/elpa/hungry-delete-20210409.1643/hungry-delete-autoloads.el b/elpa/hungry-delete-20210409.1643/hungry-delete-autoloads.el
new file mode 100644
index 0000000..94074dd
--- /dev/null
+++ b/elpa/hungry-delete-20210409.1643/hungry-delete-autoloads.el
@@ -0,0 +1,110 @@
+;;; hungry-delete-autoloads.el --- automatically extracted autoloads -*- lexical-binding: t -*-
+;;
+;;; Code:
+
+(add-to-list 'load-path (directory-file-name
+ (or (file-name-directory #$) (car load-path))))
+
+
+;;;### (autoloads nil "hungry-delete" "hungry-delete.el" (0 0 0 0))
+;;; Generated autoloads from hungry-delete.el
+
+(autoload 'hungry-delete-forward "hungry-delete" "\
+Delete the following character, or all of the following
+whitespace, up to the next non-whitespace character. See
+\\[c-hungry-delete-forward].
+
+hungry-delete-backward tries to mimic delete-backward-char's
+behavior in several ways: if the region is activate, it deletes
+the text in the region. If a prefix argument is given, delete
+the following N characters (previous if N is negative).
+
+Optional second arg KILLFLAG non-nil means to kill (save in kill
+ring) instead of delete. Interactively, N is the prefix arg, and
+KILLFLAG is set if N was explicitly specified.
+
+\(fn N &optional KILLFLAG)" t nil)
+
+(autoload 'hungry-delete-backward "hungry-delete" "\
+Delete the preceding character or all preceding whitespace
+back to the previous non-whitespace character. See also
+\\[c-hungry-delete-backward].
+
+hungry-delete-backward tries to mimic delete-backward-char's
+behavior in several ways: if the region is activate, it deletes
+the text in the region. If a prefix argument is given, delete
+the previous N characters (following if N is negative).
+
+In Overwrite mode, single character backward deletion may replace
+tabs with spaces so as to back over columns, unless point is at
+the end of the line.
+
+Optional second arg KILLFLAG, if non-nil, means to kill (save in
+kill ring) instead of delete. Interactively, N is the prefix
+arg, and KILLFLAG is set if N is explicitly specified.
+
+\(fn N &optional KILLFLAG)" t nil)
+
+(autoload 'hungry-delete-mode "hungry-delete" "\
+Minor mode to enable hungry deletion. This will delete all
+whitespace after or before point when the deletion command is
+executed.
+
+This is a minor mode. If called interactively, toggle the
+`hungry-Delete mode' mode. If the prefix argument is positive,
+enable the mode, and if it is zero or negative, disable the mode.
+
+If called from Lisp, toggle the mode if ARG is `toggle'. Enable
+the mode if ARG is nil, omitted, or is a positive number.
+Disable the mode if ARG is a negative number.
+
+To check whether the minor mode is enabled in the current buffer,
+evaluate `hungry-delete-mode'.
+
+The mode's hook is called both when the mode is enabled and when
+it is disabled.
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'turn-on-hungry-delete-mode "hungry-delete" "\
+Turn on hungry delete mode if the buffer is appropriate." t nil)
+
+(put 'global-hungry-delete-mode 'globalized-minor-mode t)
+
+(defvar global-hungry-delete-mode nil "\
+Non-nil if Global Hungry-Delete mode is enabled.
+See the `global-hungry-delete-mode' command
+for a description of this minor mode.
+Setting this variable directly does not take effect;
+either customize it (see the info node `Easy Customization')
+or call the function `global-hungry-delete-mode'.")
+
+(custom-autoload 'global-hungry-delete-mode "hungry-delete" nil)
+
+(autoload 'global-hungry-delete-mode "hungry-delete" "\
+Toggle Hungry-Delete mode in all buffers.
+With prefix ARG, enable Global Hungry-Delete mode if ARG is positive;
+otherwise, disable it.
+
+If called from Lisp, toggle the mode if ARG is `toggle'.
+Enable the mode if ARG is nil, omitted, or is a positive number.
+Disable the mode if ARG is a negative number.
+
+Hungry-Delete mode is enabled in all buffers where
+`turn-on-hungry-delete-mode' would do it.
+
+See `hungry-delete-mode' for more information on Hungry-Delete mode.
+
+\(fn &optional ARG)" t nil)
+
+(register-definition-prefixes "hungry-delete" '("hungry-delete-"))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; coding: utf-8
+;; End:
+;;; hungry-delete-autoloads.el ends here
diff --git a/elpa/hungry-delete-20210409.1643/hungry-delete-pkg.el b/elpa/hungry-delete-20210409.1643/hungry-delete-pkg.el
new file mode 100644
index 0000000..17e1923
--- /dev/null
+++ b/elpa/hungry-delete-20210409.1643/hungry-delete-pkg.el
@@ -0,0 +1,2 @@
+;;; Generated package description from hungry-delete.el -*- no-byte-compile: t -*-
+(define-package "hungry-delete" "20210409.1643" "hungry delete minor mode" 'nil :commit "d919e555e5c13a2edf4570f3ceec84f0ade71657" :authors '(("Nathaniel Flath" . "flat0103@gmail.com")) :maintainer '("Nathaniel Flath" . "flat0103@gmail.com") :url "http://github.com/nflath/hungry-delete")
diff --git a/elpa/hungry-delete-20210409.1643/hungry-delete.el b/elpa/hungry-delete-20210409.1643/hungry-delete.el
new file mode 100644
index 0000000..2f697b6
--- /dev/null
+++ b/elpa/hungry-delete-20210409.1643/hungry-delete.el
@@ -0,0 +1,254 @@
+;;; hungry-delete.el --- hungry delete minor mode
+
+;; Copyright (C) 2009 - 2014 Nathaniel Flath <flat0103@gmail.com>
+
+;; Author: Nathaniel Flath <flat0103@gmail.com>
+;; URL: http://github.com/nflath/hungry-delete
+;; Package-Version: 20210409.1643
+;; Package-Commit: d919e555e5c13a2edf4570f3ceec84f0ade71657
+;; Version: 1.1.7
+
+;; This file is not part of GNU Emacs.
+
+;;; Commentary:
+
+;; cc-mode implements hungry deletion for its programming modes. This
+;; package borrows its implementation in a minor mode, so that hungry
+;; deletion can be used in all modes.
+
+;;; Installation
+
+;; To use this mode, put the following in your init.el:
+;; (require 'hungry-delete)
+
+;; You then need to enable hungry-delete-mode, either in
+;; relevant hooks, with turn-on-hungry-delete-mode, or with
+;; global-hungry-delete-mode.
+
+;;; License:
+
+;; 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 GNU Emacs; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Code:
+
+(defvar hungry-delete-mode-map (make-keymap)
+ "Keymap for hungry-delete-minor-mode.")
+
+(if (fboundp 'delete-forward-char)
+ (define-key hungry-delete-mode-map [remap delete-forward-char] 'hungry-delete-forward))
+
+(if (fboundp 'delete-char)
+ (define-key hungry-delete-mode-map [remap delete-char] 'hungry-delete-forward))
+
+(define-key hungry-delete-mode-map [remap delete-backward-char] 'hungry-delete-backward)
+(define-key hungry-delete-mode-map [remap backward-delete-char-untabify] 'hungry-delete-backward)
+(define-key hungry-delete-mode-map [remap c-electric-backspace] 'hungry-delete-backward)
+(define-key hungry-delete-mode-map [remap c-electric-delete-forward] 'hungry-delete-forward)
+
+(defcustom hungry-delete-join-reluctantly nil
+ "If truthy, the hungry deletion functions will leave words
+seperated by a single space if they would have been joined,
+unless the words were separated by just one space to begin with"
+ :type 'boolean
+ :group 'hungry-delete)
+
+(defcustom hungry-delete-chars-to-skip " \t\n\r\f\v"
+ "String of characters to skip. Note that whitespace characters
+are not escaped and may look as if it is empty on the customize
+screen"
+ :type 'string
+ :group 'hungry-delete)
+
+(defcustom hungry-delete-except-modes '(help-mode minibuffer-inactive-mode calc-mode)
+ "List of modes hungry-delete will not be turned on in."
+ :type '(repeat (symbol :tag "Major mode exception"))
+ :group 'hungry-delete)
+
+(defun hungry-delete-skip-ws-forward ()
+ "Skip over any whitespace following point.
+This function skips over horizontal and vertical whitespace and
+line continuations."
+ (while (and
+ (> (skip-chars-forward hungry-delete-chars-to-skip) 0)
+ (eq (char-after) ?\\)
+ (progn
+ (forward-char)
+ (or (eolp) (backward-char)))))
+ (while (get-text-property (point) 'read-only)
+ (backward-char)))
+
+(defun hungry-delete-skip-ws-backward ()
+ "Skip over any whitespace preceding point.
+This function skips over horizontal and vertical whitespace and
+line continuations."
+ (let ((original-point (point)))
+ (skip-chars-backward hungry-delete-chars-to-skip)
+
+ (while (and
+ (eolp)
+ (eq (char-before) ?\\)
+ (progn
+ (backward-char)
+ (or
+ (= (point) (point-min))
+ (< (skip-chars-backward hungry-delete-chars-to-skip) 0)
+ (forward-char)))))
+ (while (and (get-text-property (point) 'read-only) (< (point) original-point))
+ (forward-char))))
+
+;;;###autoload
+(defun hungry-delete-forward (n &optional killflag)
+ "Delete the following character, or all of the following
+whitespace, up to the next non-whitespace character. See
+\\[c-hungry-delete-forward].
+
+hungry-delete-backward tries to mimic delete-backward-char's
+behavior in several ways: if the region is activate, it deletes
+the text in the region. If a prefix argument is given, delete
+the following N characters (previous if N is negative).
+
+Optional second arg KILLFLAG non-nil means to kill (save in kill
+ring) instead of delete. Interactively, N is the prefix arg, and
+KILLFLAG is set if N was explicitly specified."
+ (interactive "p\nP")
+ (unless (integerp n)
+ (signal 'wrong-type-argument (list 'integerp n)))
+ (if (bound-and-true-p rectangle-mark-mode)
+ (delete-forward-char n killflag)
+ (cond ((and
+ (use-region-p)
+ delete-active-region
+ (= n 1))
+ ;; If a region is active, kill or delete it.
+ (if (eq delete-active-region 'kill)
+ (kill-region (region-beginning) (region-end))
+ (delete-region (region-beginning) (region-end))))
+ ;; If a prefix argument has been given, delete n characters.
+ (current-prefix-arg (delete-char n killflag))
+ ;; Otherwise, call hungry-delete-forward-impl.
+ (t (hungry-delete-forward-impl)))))
+
+
+
+
+;;;###autoload
+(defun hungry-delete-backward (n &optional killflag)
+ "Delete the preceding character or all preceding whitespace
+back to the previous non-whitespace character. See also
+\\[c-hungry-delete-backward].
+
+hungry-delete-backward tries to mimic delete-backward-char's
+behavior in several ways: if the region is activate, it deletes
+the text in the region. If a prefix argument is given, delete
+the previous N characters (following if N is negative).
+
+In Overwrite mode, single character backward deletion may replace
+tabs with spaces so as to back over columns, unless point is at
+the end of the line.
+
+Optional second arg KILLFLAG, if non-nil, means to kill (save in
+kill ring) instead of delete. Interactively, N is the prefix
+arg, and KILLFLAG is set if N is explicitly specified."
+ (interactive "p\nP")
+ (unless (integerp n)
+ (signal 'wrong-type-argument (list 'integerp n)))
+ (if (bound-and-true-p rectangle-mark-mode)
+ (delete-backward-char n killflag)
+ (cond ((and
+ (use-region-p)
+ delete-active-region
+ (= n 1))
+ ;; If a region is active, kill or delete it.
+ (if (eq delete-active-region 'kill)
+ (kill-region (region-beginning) (region-end))
+ (delete-region (region-beginning) (region-end))))
+ ;; In Overwrite mode, maybe untabify while deleting
+ ((null (or (null overwrite-mode)
+ (<= n 0)
+ (memq (char-before) '(?\t ?\n))
+ (eobp)
+ (eq (char-after) ?\n)))
+ (let ((ocol (current-column)))
+ (delete-char (- n) killflag)
+ (save-excursion
+ (insert-char ?\s (- ocol (current-column)) nil))))
+ ;; If a prefix has been given, delete n characters backwards.
+ (current-prefix-arg (delete-char (- n) killflag))
+ ;; Otherwise, call hungry-delete-backward-impl.
+ (t (hungry-delete-backward-impl)))))
+
+(defun hungry-delete-impl (fn n insertion-fn)
+ "Implementation of hungry-delete functionality.
+FN is the function to call to go to the end of whitespace (will
+be either hungry-delete-skip-ws-forward or
+hungry-delete-skip-ws-backwards by default). N is the number of
+characters to delete if there is no whitespace (will be either 1
+or -1 by default).
+
+insertion-fn is inserts before point for delete backwards and after
+point for delete-forwards"
+ (let ((here (point)))
+ (funcall fn)
+ (let* ((region-start (min (point) here))
+ (region-end (max (point) here))
+ (region-size (- region-end region-start)))
+ (if (/= region-start region-end)
+ (if (and hungry-delete-join-reluctantly
+ (or (>= region-size 2)
+ (and (= region-size 1)
+ (not (seq-contains " " (char-before region-end)))))
+ (not (= region-start (point-min)))
+ (not (= region-end (point-max)))
+ (not (seq-contains hungry-delete-chars-to-skip (char-before region-start)))
+ (not (seq-contains hungry-delete-chars-to-skip (char-after region-end))))
+ (progn
+ (delete-region region-start region-end)
+ (funcall insertion-fn " "))
+ (delete-region region-start region-end))
+ (let ((hungry-delete-mode nil))
+ (delete-char n))))))
+
+(defun hungry-delete-forward-impl ()
+ "Do the dirty work of calling hungry-delete-forward."
+ (hungry-delete-impl 'hungry-delete-skip-ws-forward 1
+ (lambda (x) (save-excursion (insert x)))))
+
+(defun hungry-delete-backward-impl ()
+ "Do the dirty work of calling hungry-delete-backward."
+ (hungry-delete-impl 'hungry-delete-skip-ws-backward -1 #'insert))
+
+;;;###autoload
+(define-minor-mode hungry-delete-mode
+ "Minor mode to enable hungry deletion. This will delete all
+whitespace after or before point when the deletion command is
+executed."
+ :init-value nil
+ :group 'hungry-delete
+ :lighter " h")
+
+;;;###autoload
+(defun turn-on-hungry-delete-mode ()
+ "Turn on hungry delete mode if the buffer is appropriate."
+ (interactive)
+ (unless (member major-mode hungry-delete-except-modes)
+ (hungry-delete-mode t)))
+
+;;;###autoload
+(define-globalized-minor-mode global-hungry-delete-mode hungry-delete-mode turn-on-hungry-delete-mode
+ :group 'hungry-delete)
+
+(provide 'hungry-delete)
+;;; hungry-delete.el ends here
diff --git a/elpa/hungry-delete-20210409.1643/hungry-delete.elc b/elpa/hungry-delete-20210409.1643/hungry-delete.elc
new file mode 100644
index 0000000..bbeaf54
--- /dev/null
+++ b/elpa/hungry-delete-20210409.1643/hungry-delete.elc
Binary files differ
diff --git a/elpa/ido-vertical-mode-20210205.436/ido-vertical-mode-autoloads.el b/elpa/ido-vertical-mode-20210205.436/ido-vertical-mode-autoloads.el
new file mode 100644
index 0000000..fb9e0d0
--- /dev/null
+++ b/elpa/ido-vertical-mode-20210205.436/ido-vertical-mode-autoloads.el
@@ -0,0 +1,52 @@
+;;; ido-vertical-mode-autoloads.el --- automatically extracted autoloads -*- lexical-binding: t -*-
+;;
+;;; Code:
+
+(add-to-list 'load-path (directory-file-name
+ (or (file-name-directory #$) (car load-path))))
+
+
+;;;### (autoloads nil "ido-vertical-mode" "ido-vertical-mode.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from ido-vertical-mode.el
+
+(defvar ido-vertical-mode nil "\
+Non-nil if Ido-Vertical mode is enabled.
+See the `ido-vertical-mode' command
+for a description of this minor mode.
+Setting this variable directly does not take effect;
+either customize it (see the info node `Easy Customization')
+or call the function `ido-vertical-mode'.")
+
+(custom-autoload 'ido-vertical-mode "ido-vertical-mode" nil)
+
+(autoload 'ido-vertical-mode "ido-vertical-mode" "\
+Makes ido-mode display vertically.
+
+This is a minor mode. If called interactively, toggle the
+`Ido-Vertical mode' mode. If the prefix argument is positive,
+enable the mode, and if it is zero or negative, disable the mode.
+
+If called from Lisp, toggle the mode if ARG is `toggle'. Enable
+the mode if ARG is nil, omitted, or is a positive number.
+Disable the mode if ARG is a negative number.
+
+To check whether the minor mode is enabled in the current buffer,
+evaluate `(default-value \\='ido-vertical-mode)'.
+
+The mode's hook is called both when the mode is enabled and when
+it is disabled.
+
+\(fn &optional ARG)" t nil)
+
+(register-definition-prefixes "ido-vertical-mode" '("ido-vertical-"))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; coding: utf-8
+;; End:
+;;; ido-vertical-mode-autoloads.el ends here
diff --git a/elpa/ido-vertical-mode-20210205.436/ido-vertical-mode-pkg.el b/elpa/ido-vertical-mode-20210205.436/ido-vertical-mode-pkg.el
new file mode 100644
index 0000000..c4cbf17
--- /dev/null
+++ b/elpa/ido-vertical-mode-20210205.436/ido-vertical-mode-pkg.el
@@ -0,0 +1,2 @@
+;;; Generated package description from ido-vertical-mode.el -*- no-byte-compile: t -*-
+(define-package "ido-vertical-mode" "20210205.436" "Makes ido-mode display vertically" '((emacs "24.4")) :commit "b1659e967da0687abceca733b389ace24004fa66" :authors '(("Steven Degutis")) :maintainer '("Christopher Reichert" . "creichert07@gmail.com") :keywords '("convenience") :url "https://github.com/creichert/ido-vertical-mode.el")
diff --git a/elpa/ido-vertical-mode-20210205.436/ido-vertical-mode.el b/elpa/ido-vertical-mode-20210205.436/ido-vertical-mode.el
new file mode 100644
index 0000000..5724267
--- /dev/null
+++ b/elpa/ido-vertical-mode-20210205.436/ido-vertical-mode.el
@@ -0,0 +1,397 @@
+;;; ido-vertical-mode.el --- Makes ido-mode display vertically
+
+;; Copyright (C) 2013, 2014 Steven Degutis
+
+;; Author: Steven Degutis
+;; Maintainer: Christopher Reichert <creichert07@gmail.com>
+;; Version: 1.0.1
+;; Package-Version: 20210205.436
+;; Package-Commit: b1659e967da0687abceca733b389ace24004fa66
+;; Package-Requires: ((emacs "24.4"))
+;; Keywords: convenience
+;; URL: https://github.com/creichert/ido-vertical-mode.el
+
+;; 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:
+
+;; Makes ido-mode display prospects vertically
+
+;;; Code:
+
+(require 'ido)
+(require 'cl-lib)
+
+;;; The following three variables and their comments are lifted
+;;; directly from `ido.el'; they are defined here to avoid compile-log
+;;; warnings. See `ido.el' for more information.
+
+;; Non-nil if we should add [confirm] to prompt
+(defvar ido-show-confirm-message)
+
+;; Remember if current directory is non-readable (so we cannot do completion).
+(defvar ido-directory-nonreadable)
+
+;; Remember if current directory is 'huge' (so we don't want to do completion).
+(defvar ido-directory-too-big)
+
+(defvar ido-vertical-decorations nil
+ "Changing the decorations does most of the work for ido-vertical
+
+This sets up newlines and arrows before, between, and after the
+prospects. For additional information, see `ido-decorations'.")
+
+(defcustom ido-vertical-padding " "
+ "How many spaces to pad the completion candidates.
+
+When setting this variable in ELISP, you must also make sure
+`ido-vertical-decorations' is updated. In addition, if
+`ido-vertical-mode' is on, it must be set to the new value of
+`ido-vertical-decorations' for this variable to take effect in
+the next ido completion event."
+ :type 'string
+ :group 'ido-vertical
+ :initialize 'custom-initialize-default
+ :set (lambda (symbol value)
+ (set-default symbol value)
+ (setq ido-vertical-decorations (ido-vertical-make-decorations :padding value))
+ (when (bound-and-true-p ido-vertical-mode)
+ (setq ido-decorations ido-vertical-decorations))))
+
+(defcustom ido-vertical-indicator "->"
+ "Indicator displayed next to the candidate that will be selected.
+
+When setting this variable in ELISP, you must also make sure
+`ido-vertical-decorations' is updated. In addition, if
+`ido-vertical-mode' is on, it must be set to the new value of
+`ido-vertical-decorations' for this variable to take effect in
+the next ido completion event."
+ :type 'string
+ :group 'ido-vertical
+ :initialize 'custom-initialize-default
+ :set (lambda (symbol value)
+ (set-default symbol value)
+ (setq ido-vertical-decorations (ido-vertical-make-decorations :indicator value))
+ (when (bound-and-true-p ido-vertical-mode)
+ (setq ido-decorations ido-vertical-decorations))))
+
+(defvar ido-vertical-old-decorations nil
+ "The original `ido-decorations' variable
+
+We need to keep track of the original value so we can restore it
+when turning `ido-vertical-mode' off")
+
+(defvar ido-vertical-old-completions nil
+ "The original `ido-completions' function
+
+We need to keep track of the original value of `ido-completions'
+so we can restore it when turning `ido-vertical-mode' off")
+
+(defgroup ido-vertical nil
+ "Make ido behave vertically."
+ :group 'ido)
+
+(defcustom ido-vertical-show-count nil
+ "Non nil means show the count of candidates while completing."
+ :type 'boolean
+ :group 'ido-vertical)
+
+(defvar ido-vertical-count-active nil
+ "Used internally to track whether we're already showing the count")
+
+(defcustom ido-vertical-define-keys nil
+ "Defines which keys that `ido-vertical-mode' redefines."
+ :type '(choice
+ (const :tag "Keep default ido keys." nil)
+ (const :tag "C-p and C-n are up & down in match" C-n-and-C-p-only)
+ (const :tag "C-p/up and C-n/down are up and down in match." C-n-C-p-up-and-down)
+ (const :tag "C-p/up, C-n/down are up/down in match. left or right cycle history or directory." C-n-C-p-up-down-left-right))
+ :group 'ido-vertical)
+
+(defcustom ido-vertical-pad-list t
+ "Non nil means to pad the list of candidates to ensure the minibuffer area is always tall"
+ :type 'boolean
+ :group 'ido-vertical)
+
+(defcustom ido-vertical-disable-if-short nil
+ "Non nil means that ido will go back to horizontal mode if the candidates all fit in the minibuffer area"
+ :type 'boolean
+ :group 'ido-vertical)
+
+(defface ido-vertical-first-match-face
+ '((t (:inherit ido-first-match)))
+ "Face used by Ido Vertical for highlighting first match."
+ :group 'ido-vertical)
+
+(defface ido-vertical-only-match-face
+ '((t (:inherit ido-only-match)))
+ "Face used by Ido Vertical for highlighting only match."
+ :group 'ido-vertical)
+
+(defface ido-vertical-match-face
+ '((t (:inherit font-lock-variable-name-face :bold t :underline t)))
+ "Face used by Ido Vertical for the matched part."
+ :group 'ido-vertical)
+
+(cl-defun ido-vertical-make-decorations (&key (padding ido-vertical-padding)
+ (indicator ido-vertical-indicator))
+ "Construct a new `ido-decorations' format."
+ (list
+ (concat "\n" indicator padding) ; left bracket around prospect list
+ "" ; right bracket around prospect list
+ (concat (format (format "\n%%-%ds" (length indicator)) "") padding) ; separator between prospects, depends on `ido-separator`
+ (concat (format (format "\n%%-%ds" (length indicator)) "") padding "...") ; inserted at the end of a truncated list of prospects
+ "[" ; left bracket around common match string
+ "]" ; right bracket around common match string
+ " [No match]"
+ " [Matched]"
+ " [Not readable]"
+ " [Too big]"
+ " [Confirm]"
+ (concat "\n" indicator padding) ; left bracket around the sole remaining completion
+ "" ; right bracket around the sole remaining completion
+ ))
+
+(defun ido-vertical-or-horizontal-completions (name)
+ (if (and ido-vertical-disable-if-short
+ (<= (length ido-matches) ido-max-prospects))
+
+ (let ((short-result
+ (let ((ido-decorations ido-vertical-old-decorations))
+ (funcall ido-vertical-old-completions name))))
+ (if (>= (window-body-width (minibuffer-window))
+ (+ (minibuffer-prompt-width)
+ (length short-result)))
+ short-result
+ (ido-vertical-completions name)))
+
+ (ido-vertical-completions name)))
+
+;; borrowed from ido.el and modified to work better when vertical
+(defun ido-vertical-completions (name)
+ ;; Return the string that is displayed after the user's text.
+ ;; Modified from `icomplete-completions'.
+
+ (let* ((comps ido-matches)
+ (ind (and (consp (car comps)) (> (length (cdr (car comps))) 1)
+ ido-merged-indicator))
+ (lencomps (length comps))
+ (additional-items-indicator (nth 3 ido-decorations))
+ (comps-empty (null comps))
+ (ncomps lencomps)
+ first)
+
+ ;; Keep the height of the suggestions list constant by padding
+ ;; when lencomps is too small. Also, if lencomps is too short, we
+ ;; should not indicate that there are additional prospects.
+ (when (< lencomps (1+ ido-max-prospects))
+ (setq additional-items-indicator "\n")
+ (when ido-vertical-pad-list
+ (setq comps (append comps (make-list (- (1+ ido-max-prospects) lencomps) "")))
+ (setq ncomps (length comps))))
+
+ (if (not ido-incomplete-regexp)
+ (when ido-use-faces
+ ;; Make a copy of [ido-matches], otherwise the selected string
+ ;; could contain text properties which could lead to weird
+ ;; artifacts, e.g. buffer-file-name having text properties.
+ (setq comps (cl-loop for comps-i being the elements of (if (eq comps ido-matches)
+ ido-matches
+ comps)
+ do
+ (setf comps-i (substring-no-properties
+ (if (listp comps-i)
+ (car comps-i)
+ comps-i)
+ 0))
+ (when (string-match (if ido-enable-regexp name (regexp-quote name)) comps-i)
+ (ignore-errors
+ (add-face-text-property (match-beginning 0)
+ (match-end 0)
+ 'ido-vertical-match-face
+ nil comps-i)))
+ collect comps-i))))
+
+ (if (and ind ido-use-faces)
+ (put-text-property 0 1 'face 'ido-indicator ind))
+
+ (when ido-vertical-show-count
+ (setcar ido-vertical-decorations (concat (format " [%d]\n%s" lencomps ido-vertical-indicator)
+ ido-vertical-padding))
+ (setq ido-vertical-count-active t))
+ (when (and (not ido-vertical-show-count)
+ ido-vertical-count-active)
+ (setcar ido-vertical-decorations (concat "\n" ido-vertical-indicator ido-vertical-padding))
+ (setq ido-vertical-count-active nil))
+
+ (if (and ido-use-faces comps)
+ (let* ((fn (ido-name (car comps)))
+ (ln (length fn)))
+ (setq first (format "%s" fn))
+ (if (fboundp 'add-face-text-property)
+ (add-face-text-property 0 (length first)
+ (cond ((> lencomps 1)
+ 'ido-vertical-first-match-face)
+
+ (ido-incomplete-regexp
+ 'ido-incomplete-regexp)
+
+ (t
+ 'ido-vertical-only-match-face))
+ nil first)
+ (put-text-property 0 ln 'face
+ (if (= lencomps 1)
+ (if ido-incomplete-regexp
+ 'ido-incomplete-regexp
+ 'ido-vertical-only-match-face)
+ 'ido-vertical-first-match-face)
+ first))
+ (if ind (setq first (concat first ind)))
+ (setq comps (cons first (cdr comps)))))
+
+ ;; Previously we'd check null comps to see if the list was
+ ;; empty. We pad the list with empty items to keep the list at a
+ ;; constant height, so we have to check if the entire list is
+ ;; empty, instead of (null comps)
+ (cond (comps-empty
+ (cond
+ (ido-show-confirm-message
+ (or (nth 10 ido-decorations) " [Confirm]"))
+ (ido-directory-nonreadable
+ (or (nth 8 ido-decorations) " [Not readable]"))
+ (ido-directory-too-big
+ (or (nth 9 ido-decorations) " [Too big]"))
+ (ido-report-no-match
+ (nth 6 ido-decorations)) ;; [No match]
+ (t "")))
+ (ido-incomplete-regexp
+ (concat " " (car comps)))
+ ((null (cdr comps)) ;one match
+ (concat (concat (nth 11 ido-decorations) ;; [ ... ]
+ (ido-name (car comps))
+ (nth 12 ido-decorations))
+ (if (not ido-use-faces) (nth 7 ido-decorations)))) ;; [Matched]
+ (t ;multiple matches
+ (let* ((items (if (> ido-max-prospects 0) (1+ ido-max-prospects) 999))
+ (alternatives
+ (apply
+ #'concat
+ (cdr (apply
+ #'nconc
+ (mapcar
+ (lambda (com)
+ (setq com (ido-name com))
+ (setq items (1- items))
+ (cond
+ ((< items 0) ())
+ ((= items 0) (list additional-items-indicator)) ; " | ..."
+ (t
+ (list (nth 2 ido-decorations) ; " | "
+ (let ((str (substring com 0)))
+ (if (and ido-use-faces
+ (not (string= str first))
+ (ido-final-slash str))
+ (put-text-property 0 (length str) 'face 'ido-subdir str))
+ str)))))
+ comps))))))
+
+ (concat
+ ;; put in common completion item -- what you get by pressing tab
+ (if (and (stringp ido-common-match-string)
+ (> (length ido-common-match-string) (length name)))
+ (concat (nth 4 ido-decorations) ;; [ ... ]
+ (substring ido-common-match-string (length name))
+ (nth 5 ido-decorations)))
+ ;; list all alternatives
+ (nth 0 ido-decorations) ;; { ... }
+ alternatives
+ (nth 1 ido-decorations)))))))
+
+(defun ido-vertical-disable-line-truncation ()
+ "Prevent the newlines in the minibuffer from being truncated"
+ (set (make-local-variable 'truncate-lines) nil))
+
+(defun ido-vertical-turn-on ()
+ (if (and (eq nil ido-vertical-old-decorations)
+ (eq nil ido-vertical-old-completions))
+ (progn
+ (setq ido-vertical-old-decorations ido-decorations)
+ (setq ido-vertical-old-completions (symbol-function 'ido-completions))))
+
+ (setq ido-vertical-decorations (ido-vertical-make-decorations) ido-decorations ido-vertical-decorations)
+ (fset 'ido-completions 'ido-vertical-or-horizontal-completions)
+
+ (add-hook 'ido-minibuffer-setup-hook 'ido-vertical-disable-line-truncation)
+ (add-hook 'ido-setup-hook 'ido-vertical-define-keys))
+(make-obsolete 'turn-on-ido-vertical 'ido-vertical-turn-on "1.0.1")
+
+(defun ido-vertical-turn-off ()
+ (setq ido-decorations ido-vertical-old-decorations)
+ (fset 'ido-completions ido-vertical-old-completions)
+
+ (remove-hook 'ido-minibuffer-setup-hook 'ido-vertical-disable-line-truncation)
+ (remove-hook 'ido-setup-hook 'ido-vertical-define-keys))
+(make-obsolete 'turn-off-ido-vertical 'ido-vertical-turn-off "1.0.1")
+
+(defun ido-vertical-next-match ()
+ "Call the correct next-match function for right key.
+
+This is based on:
+- Different functions for completing directories and prior history.
+"
+ (interactive)
+ (cond
+ ((and (boundp 'item) item (eq item 'file))
+ (ido-next-match-dir))
+ (t
+ (next-history-element 1))))
+
+(defun ido-vertical-prev-match ()
+ "Call the correct prev-match function for left key.
+
+This is based on:
+- Different functions for completing directories and prior history.
+"
+ (interactive)
+ (cond
+ ((and (boundp 'item) item (eq item 'file))
+ (ido-prev-match-dir))
+ (t
+ (previous-history-element 1))))
+
+(defun ido-vertical-define-keys () ;; C-n/p is more intuitive in vertical layout
+ (when ido-vertical-define-keys
+ (define-key ido-completion-map (kbd "C-n") 'ido-next-match)
+ (define-key ido-completion-map (kbd "C-p") 'ido-prev-match)
+ (define-key ido-completion-map (kbd "C-c C-t") 'ido-toggle-prefix))
+ (when (memq ido-vertical-define-keys '(C-n-C-p-up-and-down C-n-C-p-up-down-left-right))
+ (define-key ido-completion-map (kbd "<up>") 'ido-prev-match)
+ (define-key ido-completion-map (kbd "<down>") 'ido-next-match))
+ (when (eq ido-vertical-define-keys 'C-n-C-p-up-down-left-right)
+ (define-key ido-completion-map (kbd "<left>") 'ido-vertical-prev-match)
+ (define-key ido-completion-map (kbd "<right>") 'ido-vertical-next-match)))
+
+;;;###autoload
+(define-minor-mode ido-vertical-mode
+ "Makes ido-mode display vertically."
+ :global t
+ (if ido-vertical-mode
+ (ido-vertical-turn-on)
+ (ido-vertical-turn-off)))
+
+(provide 'ido-vertical-mode)
+;; Local Variables:
+;; indent-tabs-mode: nil
+;; End:
+;;; ido-vertical-mode.el ends here
diff --git a/elpa/ido-vertical-mode-20210205.436/ido-vertical-mode.elc b/elpa/ido-vertical-mode-20210205.436/ido-vertical-mode.elc
new file mode 100644
index 0000000..ddc7fde
--- /dev/null
+++ b/elpa/ido-vertical-mode-20210205.436/ido-vertical-mode.elc
Binary files differ
diff --git a/elpa/ivy-20220406.1052/colir.el b/elpa/ivy-20220406.1052/colir.el
new file mode 100644
index 0000000..09b4f5c
--- /dev/null
+++ b/elpa/ivy-20220406.1052/colir.el
@@ -0,0 +1,124 @@
+;;; colir.el --- Color blending library -*- lexical-binding: t -*-
+
+;; Copyright (C) 2015-2021 Free Software Foundation, Inc.
+
+;; Author: Oleh Krehel <ohwoeowho@gmail.com>
+
+;; This file is part of GNU 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 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.
+
+;; For a full copy of the GNU General Public License
+;; see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This package solves the problem of adding a face with a background
+;; to text which may already have a background. In all conflicting
+;; areas, instead of choosing either the original or the new
+;; background face, their blended sum is used.
+;;
+;; The blend mode functions are taken from URL
+;; `https://en.wikipedia.org/wiki/Blend_modes'.
+
+;;; Code:
+
+(require 'cl-lib)
+(require 'color)
+
+(defcustom colir-compose-method #'colir-compose-alpha
+ "Select a method to compose two color channels."
+ :group 'ivy
+ :type '(radio
+ (function-item colir-compose-alpha)
+ (function-item colir-compose-overlay)
+ (function-item colir-compose-soft-light)))
+
+(defun colir-compose-soft-light (a b)
+ "Compose A and B channels."
+ (if (< b 0.5)
+ (+ (* 2 a b) (* a a (- 1 b b)))
+ (+ (* 2 a (- 1 b)) (* (sqrt a) (- (* 2 b) 1)))))
+
+(defun colir-compose-overlay (a b)
+ "Compose A and B channels."
+ (if (< a 0.5)
+ (* 2 a b)
+ (- 1 (* 2 (- 1 a) (- 1 b)))))
+
+(defun colir-compose-alpha (a b &optional alpha gamma)
+ "Compose A and B channels.
+Optional argument ALPHA is a number between 0.0 and 1.0 which corresponds
+to the influence of A on the result. Default value is 0.5.
+Optional argument GAMMA is used for gamma correction. Default value is 2.2."
+ (setq alpha (or alpha 0.5))
+ (setq gamma (or gamma 2.2))
+ (+ (* (expt a gamma) alpha) (* (expt b gamma) (- 1 alpha))))
+
+(defun colir-blend (c1 c2)
+ "Blend the two colors C1 and C2 using `colir-compose-method'.
+C1 and C2 are triples of floats in [0.0 1.0] range."
+ (apply #'color-rgb-to-hex
+ (cl-mapcar
+ (if (eq (frame-parameter nil 'background-mode) 'dark)
+ ;; this method works nicely for dark themes
+ 'colir-compose-soft-light
+ colir-compose-method)
+ c1 c2)))
+
+(defun colir-color-parse (color)
+ "Convert string COLOR to triple of floats in [0.0 1.0]."
+ (if (string-match "#\\([[:xdigit:]]\\{2\\}\\)\\([[:xdigit:]]\\{2\\}\\)\\([[:xdigit:]]\\{2\\}\\)" color)
+ (mapcar (lambda (v) (/ (string-to-number v 16) 255.0))
+ (list (match-string 1 color) (match-string 2 color) (match-string 3 color)))
+ ;; does not work properly in terminal (maps color to nearest color
+ ;; from available color palette).
+ (color-name-to-rgb color)))
+
+(defun colir--blend-background (start next prevn face object)
+ (let ((background-prev (face-background prevn)))
+ (progn
+ (put-text-property
+ start next 'face
+ (if background-prev
+ (cons `(background-color
+ . ,(colir-blend
+ (colir-color-parse background-prev)
+ (colir-color-parse (face-background face nil t))))
+ prevn)
+ (list face prevn))
+ object))))
+
+(defun colir-blend-face-background (start end face &optional object)
+ "Append to the face property of the text from START to END the face FACE.
+When the text already has a face with a non-plain background,
+blend it with the background of FACE.
+Optional argument OBJECT is the string or buffer containing the text.
+See also `font-lock-append-text-property'."
+ (let (next prev prevn)
+ (while (/= start end)
+ (setq next (next-single-property-change start 'face object end))
+ (setq prev (get-text-property start 'face object))
+ (setq prevn (if (listp prev)
+ (cl-find-if #'atom prev)
+ prev))
+ (cond
+ ((or (keywordp (car-safe prev)) (consp (car-safe prev)))
+ (put-text-property start next 'face (cons face prev) object))
+ ((facep prevn)
+ (colir--blend-background start next prevn face object))
+ (t
+ (put-text-property start next 'face face object)))
+ (setq start next))))
+
+(provide 'colir)
+
+;;; colir.el ends here
diff --git a/elpa/ivy-20220406.1052/colir.elc b/elpa/ivy-20220406.1052/colir.elc
new file mode 100644
index 0000000..66f9d80
--- /dev/null
+++ b/elpa/ivy-20220406.1052/colir.elc
Binary files differ
diff --git a/elpa/ivy-20220406.1052/dir b/elpa/ivy-20220406.1052/dir
new file mode 100644
index 0000000..b68b083
--- /dev/null
+++ b/elpa/ivy-20220406.1052/dir
@@ -0,0 +1,18 @@
+This is the file .../info/dir, which contains the
+topmost node of the Info hierarchy, called (dir)Top.
+The first time you invoke Info you start off looking at this node.
+
+File: dir, Node: Top This is the top of the INFO tree
+
+ This (the Directory node) gives a menu of major topics.
+ Typing "q" exits, "H" lists all Info commands, "d" returns here,
+ "h" gives a primer for first-timers,
+ "mEmacs<Return>" visits the Emacs manual, etc.
+
+ In Emacs, you can click mouse button 2 on a menu item or cross reference
+ to select it.
+
+* Menu:
+
+Emacs
+* Ivy: (ivy). Using Ivy for completion.
diff --git a/elpa/ivy-20220406.1052/elpa.el b/elpa/ivy-20220406.1052/elpa.el
new file mode 100644
index 0000000..e49b8d4
--- /dev/null
+++ b/elpa/ivy-20220406.1052/elpa.el
@@ -0,0 +1,6 @@
+(setq package-user-dir
+ (expand-file-name
+ (format "~/.elpa/%s/elpa"
+ (concat emacs-version (when (getenv "MELPA_STABLE") "-stable")))))
+(package-initialize)
+(add-to-list 'load-path default-directory)
diff --git a/elpa/ivy-20220406.1052/elpa.elc b/elpa/ivy-20220406.1052/elpa.elc
new file mode 100644
index 0000000..19610d4
--- /dev/null
+++ b/elpa/ivy-20220406.1052/elpa.elc
Binary files differ
diff --git a/elpa/ivy-20220406.1052/ivy-autoloads.el b/elpa/ivy-20220406.1052/ivy-autoloads.el
new file mode 100644
index 0000000..b7c6ca4
--- /dev/null
+++ b/elpa/ivy-20220406.1052/ivy-autoloads.el
@@ -0,0 +1,166 @@
+;;; ivy-autoloads.el --- automatically extracted autoloads -*- lexical-binding: t -*-
+;;
+;;; Code:
+
+(add-to-list 'load-path (directory-file-name
+ (or (file-name-directory #$) (car load-path))))
+
+
+;;;### (autoloads nil "colir" "colir.el" (0 0 0 0))
+;;; Generated autoloads from colir.el
+
+(register-definition-prefixes "colir" '("colir-"))
+
+;;;***
+
+;;;### (autoloads nil "ivy" "ivy.el" (0 0 0 0))
+;;; Generated autoloads from ivy.el
+
+(autoload 'ivy-resume "ivy" "\
+Resume the last completion session, or SESSION if non-nil.
+With a prefix arg, try to restore a recorded completion session,
+if one exists.
+
+\(fn &optional SESSION)" t nil)
+
+(autoload 'ivy-read "ivy" "\
+Read a string in the minibuffer, with completion.
+
+PROMPT is a string, normally ending in a colon and a space.
+`ivy-count-format' is prepended to PROMPT during completion.
+
+COLLECTION is either a list of strings, a function, an alist, or
+a hash table, supplied for `minibuffer-completion-table'.
+
+PREDICATE is applied to filter out the COLLECTION immediately.
+This argument is for compatibility with `completing-read'.
+
+When REQUIRE-MATCH is non-nil, only members of COLLECTION can be
+selected. In can also be a lambda.
+
+If INITIAL-INPUT is non-nil, then insert that input in the
+minibuffer initially.
+
+HISTORY is a name of a variable to hold the completion session
+history.
+
+KEYMAP is composed with `ivy-minibuffer-map'.
+
+PRESELECT, when non-nil, determines which one of the candidates
+matching INITIAL-INPUT to select initially. An integer stands
+for the position of the desired candidate in the collection,
+counting from zero. Otherwise, use the first occurrence of
+PRESELECT in the collection. Comparison is first done with
+`equal'. If that fails, and when applicable, match PRESELECT as
+a regular expression.
+
+DEF is for compatibility with `completing-read'.
+
+UPDATE-FN is called each time the candidate list is re-displayed.
+
+When SORT is non-nil, `ivy-sort-functions-alist' determines how
+to sort candidates before displaying them.
+
+ACTION is a function to call after selecting a candidate.
+It takes one argument, the selected candidate. If COLLECTION is
+an alist, the argument is a cons cell, otherwise it's a string.
+
+MULTI-ACTION, when non-nil, is called instead of ACTION when
+there are marked candidates. It takes the list of candidates as
+its only argument. When it's nil, ACTION is called on each marked
+candidate.
+
+UNWIND is a function of no arguments to call before exiting.
+
+RE-BUILDER is a function transforming input text into a regex
+pattern.
+
+MATCHER is a function which can override how candidates are
+filtered based on user input. It takes a regex pattern and a
+list of candidates, and returns the list of matching candidates.
+
+DYNAMIC-COLLECTION is a boolean specifying whether the list of
+candidates is updated after each input by calling COLLECTION.
+
+EXTRA-PROPS is a plist that can be used to store
+collection-specific session-specific data.
+
+CALLER is a symbol to uniquely identify the caller to `ivy-read'.
+It is used, along with COLLECTION, to determine which
+customizations apply to the current completion session.
+
+\(fn PROMPT COLLECTION &key PREDICATE REQUIRE-MATCH INITIAL-INPUT HISTORY PRESELECT DEF KEYMAP UPDATE-FN SORT ACTION MULTI-ACTION UNWIND RE-BUILDER MATCHER DYNAMIC-COLLECTION EXTRA-PROPS CALLER)" nil nil)
+
+(autoload 'ivy-completing-read "ivy" "\
+Read a string in the minibuffer, with completion.
+
+This interface conforms to `completing-read' and can be used for
+`completing-read-function'.
+
+PROMPT is a string that normally ends in a colon and a space.
+COLLECTION is either a list of strings, an alist, an obarray, or a hash table.
+PREDICATE limits completion to a subset of COLLECTION.
+REQUIRE-MATCH is a boolean value or a symbol. See `completing-read'.
+INITIAL-INPUT is a string inserted into the minibuffer initially.
+HISTORY is a list of previously selected inputs.
+DEF is the default value.
+INHERIT-INPUT-METHOD is currently ignored.
+
+\(fn PROMPT COLLECTION &optional PREDICATE REQUIRE-MATCH INITIAL-INPUT HISTORY DEF INHERIT-INPUT-METHOD)" nil nil)
+
+(defvar ivy-mode nil "\
+Non-nil if ivy mode is enabled.
+See the `ivy-mode' command
+for a description of this minor mode.
+Setting this variable directly does not take effect;
+either customize it (see the info node `Easy Customization')
+or call the function `ivy-mode'.")
+
+(custom-autoload 'ivy-mode "ivy" nil)
+
+(autoload 'ivy-mode "ivy" "\
+Toggle Ivy mode on or off.
+Turn Ivy mode on if ARG is positive, off otherwise.
+Turning on Ivy mode sets `completing-read-function' to
+`ivy-completing-read'.
+
+Global bindings:
+\\{ivy-mode-map}
+
+Minibuffer bindings:
+\\{ivy-minibuffer-map}
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'ivy-switch-buffer "ivy" "\
+Switch to another buffer." t nil)
+
+(autoload 'ivy-switch-view "ivy" "\
+Switch to one of the window views stored by `ivy-push-view'." t nil)
+
+(autoload 'ivy-switch-buffer-other-window "ivy" "\
+Switch to another buffer in another window." t nil)
+
+(register-definition-prefixes "ivy" '("ivy-" "with-ivy-window"))
+
+;;;***
+
+;;;### (autoloads nil "ivy-overlay" "ivy-overlay.el" (0 0 0 0))
+;;; Generated autoloads from ivy-overlay.el
+
+(register-definition-prefixes "ivy-overlay" '("ivy-"))
+
+;;;***
+
+;;;### (autoloads nil nil ("elpa.el" "ivy-faces.el" "ivy-pkg.el")
+;;;;;; (0 0 0 0))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; coding: utf-8
+;; End:
+;;; ivy-autoloads.el ends here
diff --git a/elpa/ivy-20220406.1052/ivy-faces.el b/elpa/ivy-20220406.1052/ivy-faces.el
new file mode 100644
index 0000000..bedb9cb
--- /dev/null
+++ b/elpa/ivy-20220406.1052/ivy-faces.el
@@ -0,0 +1,138 @@
+;;; ivy-faces.el --- Faces for Ivy -*- lexical-binding: t -*-
+
+;; Copyright (C) 2020-2021 Free Software Foundation, Inc.
+
+;; Author: Oleh Krehel <ohwoeowho@gmail.com>
+;; Keywords: convenience
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;; Code:
+
+(defgroup ivy-faces nil
+ "Font-lock faces for `ivy'."
+ :group 'ivy
+ :group 'faces)
+
+(defface ivy-current-match
+ '((((class color) (background light))
+ :background "#1a4b77" :foreground "white" :extend t)
+ (((class color) (background dark))
+ :background "#65a7e2" :foreground "black" :extend t))
+ "Face used by Ivy for highlighting the current match.")
+
+(defface ivy-minibuffer-match-highlight
+ '((t :inherit highlight))
+ "Face used by Ivy for highlighting the match under the cursor.")
+
+(defface ivy-minibuffer-match-face-1
+ '((((class color) (background light))
+ :background "#d3d3d3")
+ (((class color) (background dark))
+ :background "#555555"))
+ "The background face for `ivy' minibuffer matches.")
+
+(defface ivy-minibuffer-match-face-2
+ '((((class color) (background light))
+ :background "#e99ce8" :weight bold)
+ (((class color) (background dark))
+ :background "#777777" :weight bold))
+ "Face for `ivy' minibuffer matches numbered 1 modulo 3.")
+
+(defface ivy-minibuffer-match-face-3
+ '((((class color) (background light))
+ :background "#bbbbff" :weight bold)
+ (((class color) (background dark))
+ :background "#7777ff" :weight bold))
+ "Face for `ivy' minibuffer matches numbered 2 modulo 3.")
+
+(defface ivy-minibuffer-match-face-4
+ '((((class color) (background light))
+ :background "#ffbbff" :weight bold)
+ (((class color) (background dark))
+ :background "#8a498a" :weight bold))
+ "Face for `ivy' minibuffer matches numbered 3 modulo 3.")
+
+(defface ivy-confirm-face
+ '((t :foreground "ForestGreen" :inherit minibuffer-prompt))
+ "Face used by Ivy for a confirmation prompt.")
+
+(defface ivy-match-required-face
+ '((t :foreground "red" :inherit minibuffer-prompt))
+ "Face used by Ivy for a match required prompt.")
+
+(defface ivy-subdir
+ '((t :inherit dired-directory))
+ "Face used by Ivy for highlighting subdirs in the alternatives.")
+
+(defface ivy-org
+ '((t :inherit org-level-4))
+ "Face used by Ivy for highlighting Org buffers in the alternatives.")
+
+(defface ivy-modified-buffer
+ '((t :inherit default))
+ "Face used by Ivy for highlighting modified file visiting buffers.")
+
+(defface ivy-modified-outside-buffer
+ '((t :inherit default))
+ "Face used by Ivy for highlighting file visiting buffers modified outside Emacs.")
+
+(defface ivy-remote
+ '((((class color) (background light))
+ :foreground "#110099")
+ (((class color) (background dark))
+ :foreground "#7B6BFF"))
+ "Face used by Ivy for highlighting remotes in the alternatives.")
+
+(defface ivy-virtual
+ '((t :inherit font-lock-builtin-face))
+ "Face used by Ivy for matching virtual buffer names.")
+
+(defface ivy-action
+ '((t :inherit font-lock-builtin-face))
+ "Face used by Ivy for displaying keys in `ivy-read-action'.")
+
+(defface ivy-highlight-face
+ '((t :inherit highlight))
+ "Face used by Ivy to highlight certain candidates.")
+
+(defface ivy-prompt-match
+ '((t :inherit ivy-current-match))
+ "Face used by Ivy for highlighting the selected prompt line.")
+
+(defface ivy-separator
+ '((t :inherit font-lock-doc-face))
+ "Face for multiline source separator.")
+
+(defface ivy-grep-info
+ '((t :inherit compilation-info))
+ "Face for highlighting grep information such as file names.")
+
+(defface ivy-grep-line-number
+ '((t :inherit compilation-line-number))
+ "Face for displaying line numbers in grep messages.")
+
+(defface ivy-completions-annotations
+ '((t :inherit completions-annotations))
+ "Face for displaying completion annotations.")
+
+(defface ivy-yanked-word
+ '((t :inherit highlight))
+ "Face used to highlight yanked word.")
+
+(provide 'ivy-faces)
+
+;;; ivy-faces.el ends here
diff --git a/elpa/ivy-20220406.1052/ivy-faces.elc b/elpa/ivy-20220406.1052/ivy-faces.elc
new file mode 100644
index 0000000..135c693
--- /dev/null
+++ b/elpa/ivy-20220406.1052/ivy-faces.elc
Binary files differ
diff --git a/elpa/ivy-20220406.1052/ivy-help.org b/elpa/ivy-20220406.1052/ivy-help.org
new file mode 100644
index 0000000..3a94118
--- /dev/null
+++ b/elpa/ivy-20220406.1052/ivy-help.org
@@ -0,0 +1,138 @@
+* Ivy Generic Help
+
+=ivy= is an Emacs incremental completion framework.
+
+- Narrow the list by typing some pattern,
+- Multiple patterns are allowed by separating with a space,
+- Select with ~C-n~ and ~C-p~, choose with ~RET~.
+
+** Help
+
+- ~C-h m~ :: Pop to this generic help buffer.
+
+** Basic Operations
+*** Key bindings for navigation
+
+- ~C-n~ (=ivy-next-line=) :: next candidate.
+- ~C-p~ (=ivy-previous-line=) :: previous candidate.
+- ~C-v~ (=ivy-scroll-up-command=) :: next page.
+- ~M-v~ (=ivy-scroll-down-command=) :: previous page.
+- ~M-<~ (=ivy-beginning-of-buffer=) :: first candidate.
+- ~M->~ (=ivy-end-of-buffer=) :: last candidate.
+
+*** Key bindings for single selection
+
+When selecting a candidate, an action is called on it. You can think
+of an action as a function that takes the selected candidate as an
+argument and does something with it.
+
+Ivy can offer several actions from which to choose. This can be
+independently composed with whether you want to end completion when
+the action is called. Depending on this, the short term is either
+"calling an action" or "exiting with action".
+
+~C-m~ or ~RET~ (=ivy-done=) - exit with the current action.
+
+~M-o~ (=ivy-dispatching-done=) - select an action and exit with it.
+
+~C-j~ (=ivy-alt-done=) - when the candidate is a directory, enter
+it. Otherwise, exit with the current action.
+
+~TAB~ (=ivy-partial-or-done=) - attempt partial completion, extending
+the current input as much as possible. ~TAB TAB~ is the same as ~C-j~.
+
+~C-M-j~ (=ivy-immediate-done=) - exit with the current action, calling
+it on the /current input/ instead of the current candidate. This is
+useful especially when creating new files or directories - often the
+input will match an existing file, which you don't want to select.
+
+~C-'~ (=ivy-avy=) - select a candidate from the current page with avy
+and exit with the current action.
+
+** Advanced Operations
+*** Key bindings for multiple selection
+
+For repeatedly applying multiple actions or acting on multiple
+candidates, Ivy does not close the minibuffer between commands. It
+keeps the minibuffer open for applying subsequent actions.
+
+Adding an extra meta key to the normal key chord invokes the special
+version of the regular commands that enables applying multiple
+actions.
+
+~C-M-m~ (=ivy-call=) is the non-exiting version of ~C-m~ (=ivy-done=).
+
+~C-M-n~ (=ivy-next-line-and-call=) combines ~C-n~ and ~C-M-m~.
+
+~C-M-p~ (=ivy-previous-line-and-call=) combines ~C-p~ and ~C-M-m~.
+
+~C-M-o~ (=ivy-dispatching-call=) is a non-exiting version of ~M-o~
+(=ivy-dispatching-done=).
+
+*** Key bindings that alter the minibuffer input
+
+~M-n~ (=ivy-next-history-element=) select the next history element or
+symbol/URL at point.
+
+~M-p~ (=ivy-previous-history-element=) select the previous history
+element.
+
+~C-r~ (=ivy-reverse-i-search=) start a recursive completion session to
+select a history element.
+
+~M-i~ (=ivy-insert-current=) insert the current candidate into the
+minibuffer. Useful for copying and renaming files, for example: ~M-i~
+to insert the original file name string, edit it, and then ~C-m~ to
+complete the renaming.
+
+~M-j~ (=ivy-yank-word=) insert the sub-word at point into the
+minibuffer.
+
+~S-SPC~ (=ivy-restrict-to-matches=) deletes the current input, and
+resets the candidates list to the currently restricted matches. This
+is how Ivy provides narrowing in successive tiers.
+
+*** Other key bindings
+
+~M-w~ (=ivy-kill-ring-save=) copies the selected candidates to the
+kill ring; when the region is active, copies the active region.
+
+*** Saving the current completion session to a buffer
+
+~C-c C-o~ (=ivy-occur=) saves the current candidates to a new buffer;
+the list is active in the new buffer.
+
+~RET~ or ~mouse-1~ in the new buffer calls the appropriate action on
+the selected candidate.
+
+Ivy has no limit on the number of active buffers like these.
+
+Ivy takes care of making these buffer names unique. It applies
+descriptive names, for example: =*ivy-occur counsel-describe-variable
+"function$*=.
+
+*** Global key bindings
+
+=ivy-resume= recalls the state of the completion session just before
+its last exit. Useful after an accidental ~C-m~ (=ivy-done=).
+Recommended global binding: ~C-c C-r~.
+
+*** Hydra in the minibuffer
+
+~C-o~ (=hydra-ivy/body=) invokes Hydra menus with key shortcuts.
+
+When in Hydra, ~C-o~ or ~i~ resumes editing.
+
+Hydra reduces key strokes, for example: ~C-n C-n C-n C-n~ is ~C-o
+jjjj~ in Hydra. Besides certain shorter keys, Hydra shows useful info
+such as case folding and the current action.
+
+Additionally, here are the keys that are otherwise not bound:
+
+- ~<~ and ~>~ adjust the height of the minibuffer.
+- ~c~ (=ivy-toggle-calling=) - toggle calling the current action each
+ time a different candidate is selected.
+- ~M~ (=ivy-rotate-preferred-builders=) - rotate regex matcher.
+- ~w~ and ~s~ scroll the actions list.
+
+Minibuffer editing is disabled when Hydra is active.
diff --git a/elpa/ivy-20220406.1052/ivy-overlay.el b/elpa/ivy-20220406.1052/ivy-overlay.el
new file mode 100644
index 0000000..2da1306
--- /dev/null
+++ b/elpa/ivy-20220406.1052/ivy-overlay.el
@@ -0,0 +1,171 @@
+;;; ivy-overlay.el --- Overlay display functions for Ivy -*- lexical-binding: t -*-
+
+;; Copyright (C) 2016-2021 Free Software Foundation, Inc.
+
+;; Author: Oleh Krehel <ohwoeowho@gmail.com>
+;; Keywords: convenience
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This package allows to setup Ivy's completion at point to actually
+;; show the candidates and the input at point, instead of in the
+;; minibuffer.
+
+;;; Code:
+
+(eval-when-compile
+ (require 'cl-lib)
+ (require 'subr-x))
+
+(defface ivy-cursor
+ '((((class color) (background light))
+ :background "black" :foreground "white")
+ (((class color) (background dark))
+ :background "white" :foreground "black"))
+ "Cursor face for inline completion."
+ :group 'ivy-faces)
+
+(defvar ivy--old-cursor-type t)
+
+(defvar ivy-overlay-at nil
+ "Overlay variable for `ivy-display-function-overlay'.")
+
+(declare-function ivy--truncate-string "ivy")
+
+(defun ivy-left-pad (str width)
+ "Return STR, but with each line indented by WIDTH spaces.
+Lines are truncated to the window width."
+ (let ((padding (make-string width ?\s)))
+ (mapconcat (lambda (x)
+ (ivy--truncate-string (concat padding x)
+ (1- (+ (window-width)
+ (window-hscroll)))))
+ (split-string str "\n")
+ "\n")))
+
+(defun ivy-overlay-cleanup ()
+ "Clean up after `ivy-display-function-overlay'."
+ (when (overlayp ivy-overlay-at)
+ (delete-overlay ivy-overlay-at)
+ (setq ivy-overlay-at nil))
+ (unless cursor-type
+ (setq cursor-type ivy--old-cursor-type))
+ (when (fboundp 'company-abort)
+ (company-abort)))
+
+(defvar ivy-height)
+
+(defun ivy-overlay-show-after (str)
+ "Display STR in an overlay at point.
+
+First, fill each line of STR with spaces to the current column.
+Then attach the overlay to the character before point."
+ (if ivy-overlay-at
+ (progn
+ (move-overlay ivy-overlay-at (1- (point)) (line-end-position))
+ (overlay-put ivy-overlay-at 'invisible nil))
+ (let ((available-height (- (window-height) (count-lines (window-start) (point)) 1)))
+ (unless (>= available-height ivy-height)
+ (recenter (- (window-height) ivy-height 2))))
+ (setq ivy-overlay-at (make-overlay (1- (point)) (line-end-position)))
+ ;; Specify face to avoid clashing with other overlays.
+ (overlay-put ivy-overlay-at 'face 'default)
+ (overlay-put ivy-overlay-at 'priority 9999))
+ (overlay-put ivy-overlay-at 'display str)
+ (overlay-put ivy-overlay-at 'after-string ""))
+
+(declare-function org-current-level "org")
+(declare-function org-at-heading-p "org")
+(defvar org-indent-indentation-per-level)
+(defvar ivy-height)
+(defvar ivy-last)
+(defvar ivy-text)
+(defvar ivy-completion-beg)
+(declare-function ivy--get-window "ivy")
+(declare-function ivy-state-current "ivy")
+(declare-function ivy-state-window "ivy")
+
+(defun ivy-overlay--current-column ()
+ "Return `current-column', ignoring `ivy-overlay-at'.
+Temporarily make `ivy-overlay-at' invisible so that the
+`string-width' of its `display' property is not included in the
+`current-column' calculation by Emacs >= 29.
+See URL `https://bugs.gnu.org/53795'."
+ (if (overlayp ivy-overlay-at)
+ (cl-letf (((overlay-get ivy-overlay-at 'invisible) t))
+ (1+ (current-column)))
+ (current-column)))
+
+(defun ivy-overlay-impossible-p (_str)
+ (or
+ (and (eq major-mode 'org-mode)
+ ;; If this breaks, an alternative is to call the canonical function
+ ;; `org-in-src-block-p', which is slower. Neither approach works
+ ;; in Org versions that shipped with Emacs < 26, however.
+ (get-text-property (point) 'src-block))
+ (<= (window-height) (+ ivy-height 2))
+ (bobp)
+ (< (- (+ (window-width) (window-hscroll))
+ (ivy-overlay--current-column))
+ 30)))
+
+(defun ivy-display-function-overlay (str)
+ "Called from the minibuffer, display STR in an overlay in Ivy window.
+Hide the minibuffer contents and cursor."
+ (if (save-selected-window
+ (select-window (ivy-state-window ivy-last))
+ (ivy-overlay-impossible-p str))
+ (let ((buffer-undo-list t))
+ (save-excursion
+ (forward-line 1)
+ (insert str)))
+ (add-face-text-property (minibuffer-prompt-end) (point-max)
+ '(:foreground "white"))
+ (setq cursor-type nil)
+ (with-selected-window (ivy--get-window ivy-last)
+ (when cursor-type
+ (setq ivy--old-cursor-type cursor-type))
+ (setq cursor-type nil)
+ (let ((overlay-str
+ (apply
+ #'concat
+ (buffer-substring (max (point-min) (1- (point))) (point))
+ ivy-text
+ (and (eolp) " ")
+ (buffer-substring (point) (line-end-position))
+ (and (> (length str) 0)
+ (list "\n"
+ (ivy-left-pad
+ (string-remove-prefix "\n" str)
+ (+
+ (if (and (eq major-mode 'org-mode)
+ (bound-and-true-p org-indent-mode))
+ (if (org-at-heading-p)
+ (1- (org-current-level))
+ (* org-indent-indentation-per-level (or (org-current-level) 1)))
+ 0)
+ (save-excursion
+ (when ivy-completion-beg
+ (goto-char ivy-completion-beg))
+ (ivy-overlay--current-column)))))))))
+ (let ((cursor-offset (1+ (length ivy-text))))
+ (add-face-text-property cursor-offset (1+ cursor-offset)
+ 'ivy-cursor t overlay-str))
+ (ivy-overlay-show-after overlay-str)))))
+
+(provide 'ivy-overlay)
+
+;;; ivy-overlay.el ends here
diff --git a/elpa/ivy-20220406.1052/ivy-overlay.elc b/elpa/ivy-20220406.1052/ivy-overlay.elc
new file mode 100644
index 0000000..897d5bb
--- /dev/null
+++ b/elpa/ivy-20220406.1052/ivy-overlay.elc
Binary files differ
diff --git a/elpa/ivy-20220406.1052/ivy-pkg.el b/elpa/ivy-20220406.1052/ivy-pkg.el
new file mode 100644
index 0000000..cfcf266
--- /dev/null
+++ b/elpa/ivy-20220406.1052/ivy-pkg.el
@@ -0,0 +1,12 @@
+(define-package "ivy" "20220406.1052" "Incremental Vertical completYon"
+ '((emacs "24.5"))
+ :commit "8bf8027e4bd8c093bddb76a813952d2a0dcbf21d" :authors
+ '(("Oleh Krehel" . "ohwoeowho@gmail.com"))
+ :maintainer
+ '("Oleh Krehel" . "ohwoeowho@gmail.com")
+ :keywords
+ '("matching")
+ :url "https://github.com/abo-abo/swiper")
+;; Local Variables:
+;; no-byte-compile: t
+;; End:
diff --git a/elpa/ivy-20220406.1052/ivy.el b/elpa/ivy-20220406.1052/ivy.el
new file mode 100644
index 0000000..dac9a31
--- /dev/null
+++ b/elpa/ivy-20220406.1052/ivy.el
@@ -0,0 +1,5412 @@
+;;; ivy.el --- Incremental Vertical completYon -*- lexical-binding: t -*-
+
+;; Copyright (C) 2015-2021 Free Software Foundation, Inc.
+
+;; Author: Oleh Krehel <ohwoeowho@gmail.com>
+;; URL: https://github.com/abo-abo/swiper
+;; Version: 0.13.4
+;; Package-Requires: ((emacs "24.5"))
+;; Keywords: matching
+
+;; This file is part of GNU 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 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.
+
+;; For a full copy of the GNU General Public License
+;; see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This package provides `ivy-read' as an alternative to
+;; `completing-read' and similar functions.
+;;
+;; There's no intricate code to determine the best candidate.
+;; Instead, the user can navigate to it with `ivy-next-line' and
+;; `ivy-previous-line'.
+;;
+;; The matching is done by splitting the input text by spaces and
+;; re-building it into a regex.
+;; So "for example" is transformed into "\\(for\\).*\\(example\\)".
+
+;;; Code:
+
+(require 'colir)
+(require 'ivy-overlay)
+(require 'ivy-faces)
+
+(require 'cl-lib)
+(require 'ring)
+
+(eval-when-compile
+ (require 'subr-x))
+
+;;* Customization
+(defgroup ivy nil
+ "Incremental vertical completion."
+ :group 'convenience)
+
+(defcustom ivy-height 10
+ "Number of lines for the minibuffer window.
+
+See also `ivy-height-alist'."
+ :type 'integer)
+
+(defcustom ivy-count-format "%-4d "
+ "The style to use for displaying the current candidate count for `ivy-read'.
+Set this to \"\" to suppress the count visibility.
+Set this to \"(%d/%d) \" to display both the index and the count."
+ :type '(choice
+ (const :tag "Count disabled" "")
+ (const :tag "Count matches" "%-4d ")
+ (const :tag "Count matches and show current match" "(%d/%d) ")
+ string))
+
+(defcustom ivy-pre-prompt-function nil
+ "When non-nil, add strings before the `ivy-read' prompt."
+ :type '(choice
+ (const :tag "Do nothing" nil)
+ (function :tag "Custom function")))
+
+(defcustom ivy-add-newline-after-prompt nil
+ "When non-nil, add a newline after the `ivy-read' prompt."
+ :type 'boolean)
+
+(defcustom ivy-wrap nil
+ "When non-nil, wrap around after the first and the last candidate."
+ :type 'boolean)
+
+(defcustom ivy-display-style 'fancy
+ "The style for formatting the minibuffer.
+
+By default, the matched strings are copied as is.
+
+The fancy display style highlights matching parts of the regexp,
+a behavior similar to `swiper'."
+ :type '(choice
+ (const :tag "Plain" nil)
+ (const :tag "Fancy" fancy)))
+
+(defcustom ivy-on-del-error-function #'abort-recursive-edit
+ "Function to call when deletion fails during completion.
+The usual reason for `ivy-backward-delete-char' to fail is when
+there is no text left to delete, i.e., when it is called at the
+beginning of the minibuffer.
+The default setting provides a quick exit from completion.
+Another common option is `ignore', which does nothing."
+ :type '(choice
+ (const :tag "Exit completion" abort-recursive-edit)
+ (const :tag "Do nothing" ignore)
+ (function :tag "Custom function")))
+
+(defcustom ivy-extra-directories '("../" "./")
+ "Add this to the front of the list when completing file names.
+Only \"./\" and \"../\" apply here. They appear in reverse order."
+ :type '(repeat :tag "Dirs"
+ (choice
+ (const :tag "Parent Directory" "../")
+ (const :tag "Current Directory" "./"))))
+
+(defcustom ivy-use-virtual-buffers nil
+ "When non-nil, add recent files and/or bookmarks to `ivy-switch-buffer'.
+The value `recentf' includes only recent files to the virtual
+buffers list, whereas the value `bookmarks' does the same for
+bookmarks. Any other non-nil value includes both."
+ :type '(choice
+ (const :tag "Don't use virtual buffers" nil)
+ (const :tag "Recent files" recentf)
+ (const :tag "Bookmarks" bookmarks)
+ (const :tag "All virtual buffers" t)))
+
+(defvar ivy--display-function nil
+ "The display-function is used in current.")
+
+(defvar ivy-display-functions-props
+ '((ivy-display-function-overlay :cleanup ivy-overlay-cleanup))
+ "Map Ivy display functions to their property lists.
+Examples of properties include associated `:cleanup' functions.")
+
+(defcustom ivy-display-functions-alist
+ '((ivy-completion-in-region . ivy-display-function-overlay)
+ (t . nil))
+ "An alist for customizing where to display the candidates.
+
+Each key is a caller symbol. When the value is nil (the default),
+the candidates are shown in the minibuffer. Otherwise, the value
+is a function which takes a string argument comprising the
+current matching candidates and displays it somewhere.
+
+See also `https://github.com/abo-abo/swiper/wiki/ivy-display-function'."
+ :type '(alist
+ :key-type symbol
+ :value-type (choice
+ (const :tag "Minibuffer" nil)
+ (const :tag "LV" ivy-display-function-lv)
+ (const :tag "Popup" ivy-display-function-popup)
+ (const :tag "Overlay" ivy-display-function-overlay)
+ (function :tag "Custom function"))))
+
+(defvar ivy-completing-read-dynamic-collection nil
+ "Run `ivy-completing-read' with `:dynamic-collection t`.")
+
+(defcustom ivy-completing-read-handlers-alist
+ '((tmm-menubar . completing-read-default)
+ (tmm-shortcut . completing-read-default)
+ (bbdb-create . ivy-completing-read-with-empty-string-def)
+ (auto-insert . ivy-completing-read-with-empty-string-def)
+ (Info-on-current-buffer . ivy-completing-read-with-empty-string-def)
+ (Info-follow-reference . ivy-completing-read-with-empty-string-def)
+ (Info-menu . ivy-completing-read-with-empty-string-def)
+ (Info-index . ivy-completing-read-with-empty-string-def)
+ (Info-virtual-index . ivy-completing-read-with-empty-string-def)
+ (info-display-manual . ivy-completing-read-with-empty-string-def))
+ "An alist of handlers to replace `completing-read' in `ivy-mode'."
+ :type '(alist :key-type symbol :value-type function))
+
+(defcustom ivy-height-alist nil
+ "An alist to customize `ivy-height'.
+
+It is a list of (CALLER . HEIGHT). CALLER is a caller of
+`ivy-read' and HEIGHT is the number of lines displayed.
+HEIGHT can also be a function that returns the number of lines."
+ :type '(alist
+ :key-type function
+ :value-type (choice integer function)))
+
+(defvar ivy-completing-read-ignore-handlers-depth -1
+ "Used to avoid infinite recursion.
+
+If `(minibuffer-depth)' equals this, `ivy-completing-read' will
+act as if `ivy-completing-read-handlers-alist' is empty.")
+
+(defvar ivy-highlight-grep-commands nil
+ "List of grep-like commands.")
+
+(defvar ivy--actions-list nil
+ "A list of extra actions per command.")
+
+(defun ivy-set-actions (cmd actions)
+ "Set CMD extra exit points to ACTIONS."
+ (setq ivy--actions-list
+ (plist-put ivy--actions-list cmd actions)))
+
+(defun ivy-add-actions (cmd actions)
+ "Add extra exit points ACTIONS to CMD.
+Existing exit points of CMD are overwritten by those in
+ACTIONS that have the same key."
+ (setq ivy--actions-list
+ (plist-put ivy--actions-list cmd
+ (cl-delete-duplicates
+ (append (plist-get ivy--actions-list cmd) actions)
+ :key #'car :test #'equal))))
+
+(defun ivy--compute-extra-actions (action caller)
+ "Add extra actions to ACTION based on CALLER."
+ (let* ((extra-actions (cl-delete-duplicates
+ (append (plist-get ivy--actions-list t)
+ (plist-get ivy--actions-list this-command)
+ (plist-get ivy--actions-list caller))
+ :key #'car :test #'equal))
+ (override-default (assoc "o" extra-actions)))
+ (cond (override-default
+ (cons 1 (cons override-default
+ (cl-delete "o" extra-actions
+ :key #'car :test #'equal))))
+ ((not extra-actions)
+ action)
+ ((functionp action)
+ `(1
+ ("o" ,action "default")
+ ,@extra-actions))
+ ((null action)
+ `(1
+ ("o" identity "default")
+ ,@extra-actions))
+ (t
+ (cons (car action)
+ (cl-delete-duplicates (cdr (append action extra-actions))
+ :key #'car :test #'equal :from-end t))))))
+
+(defvar ivy--prompts-list nil)
+
+(defun ivy-set-prompt (caller prompt-fn)
+ "Associate CALLER with PROMPT-FN.
+PROMPT-FN is a function of no arguments that returns a prompt string."
+ (setq ivy--prompts-list
+ (plist-put ivy--prompts-list caller prompt-fn)))
+
+(defvar ivy--display-transformers-alist nil
+ "A list of str->str transformers per command.")
+
+(defun ivy-set-display-transformer (cmd transformer)
+ "Set CMD a displayed candidate TRANSFORMER.
+
+It's a lambda that takes a string one of the candidates in the
+collection and returns a string for display, the same candidate
+plus some extra information.
+
+This lambda is called only on the `ivy-height' candidates that
+are about to be displayed, not on the whole collection."
+ (declare (obsolete "Use `ivy-configure' :display-transformer-fn" "<2020-05-20 Wed>"))
+ (ivy--alist-set 'ivy--display-transformers-alist cmd transformer))
+
+(defvar ivy--sources-list nil
+ "A list of extra sources per command.")
+
+(defun ivy-set-sources (cmd sources)
+ "Attach to CMD a list of extra SOURCES.
+
+Each static source is a function that takes no argument and
+returns a list of strings.
+
+The (original-source) determines the position of the original
+dynamic source.
+
+Extra dynamic sources aren't supported yet.
+
+Example:
+
+ (defun small-recentf ()
+ (cl-subseq recentf-list 0 20))
+
+ (ivy-set-sources
+ 'counsel-locate
+ '((small-recentf)
+ (original-source)))"
+ (setq ivy--sources-list
+ (plist-put ivy--sources-list cmd sources)))
+
+(defun ivy--compute-extra-candidates (caller)
+ (let ((extra-sources (or (plist-get ivy--sources-list caller)
+ '((original-source))))
+ (result nil))
+ (dolist (source extra-sources)
+ (cond ((equal source '(original-source))
+ (push source result))
+ ((null (cdr source))
+ (push (list (car source) (funcall (car source))) result))))
+ result))
+
+(defvar ivy-current-prefix-arg nil
+ "Prefix arg to pass to actions.
+This is a global variable that is set by ivy functions for use in
+action functions.")
+
+;;* Keymap
+(require 'delsel)
+(defun ivy-define-key (keymap key def)
+ "Forward to (`define-key' KEYMAP KEY DEF).
+Remove DEF from `counsel-M-x' list."
+ (put def 'no-counsel-M-x t)
+ (define-key keymap key def))
+
+(defvar ivy-minibuffer-map
+ (let ((map (make-sparse-keymap)))
+ (ivy-define-key map (kbd "C-m") 'ivy-done)
+ (define-key map [down-mouse-1] 'ignore)
+ (ivy-define-key map [mouse-1] 'ivy-mouse-done)
+ (ivy-define-key map [mouse-3] 'ivy-mouse-dispatching-done)
+ (ivy-define-key map (kbd "C-M-m") 'ivy-call)
+ (ivy-define-key map (kbd "C-j") 'ivy-alt-done)
+ (ivy-define-key map (kbd "C-M-j") 'ivy-immediate-done)
+ (ivy-define-key map (kbd "TAB") 'ivy-partial-or-done)
+ (ivy-define-key map [remap next-line] 'ivy-next-line)
+ (ivy-define-key map [remap previous-line] 'ivy-previous-line)
+ (ivy-define-key map (kbd "C-r") 'ivy-reverse-i-search)
+ (define-key map (kbd "SPC") 'self-insert-command)
+ (ivy-define-key map [remap delete-backward-char] 'ivy-backward-delete-char)
+ (ivy-define-key map [remap backward-delete-char-untabify] 'ivy-backward-delete-char)
+ (ivy-define-key map [remap backward-kill-word] 'ivy-backward-kill-word)
+ (ivy-define-key map [remap delete-char] 'ivy-delete-char)
+ (ivy-define-key map [remap forward-char] 'ivy-forward-char)
+ (ivy-define-key map (kbd "<right>") 'ivy-forward-char)
+ (ivy-define-key map [remap kill-word] 'ivy-kill-word)
+ (ivy-define-key map [remap beginning-of-buffer] 'ivy-beginning-of-buffer)
+ (ivy-define-key map [remap end-of-buffer] 'ivy-end-of-buffer)
+ (ivy-define-key map (kbd "M-n") 'ivy-next-history-element)
+ (ivy-define-key map (kbd "M-p") 'ivy-previous-history-element)
+ (define-key map (kbd "C-g") 'minibuffer-keyboard-quit)
+ (ivy-define-key map [remap scroll-up-command] 'ivy-scroll-up-command)
+ (ivy-define-key map [remap scroll-down-command] 'ivy-scroll-down-command)
+ (ivy-define-key map (kbd "<next>") 'ivy-scroll-up-command)
+ (ivy-define-key map (kbd "<prior>") 'ivy-scroll-down-command)
+ (ivy-define-key map (kbd "C-v") 'ivy-scroll-up-command)
+ (ivy-define-key map (kbd "M-v") 'ivy-scroll-down-command)
+ (ivy-define-key map (kbd "C-M-n") 'ivy-next-line-and-call)
+ (ivy-define-key map (kbd "C-M-p") 'ivy-previous-line-and-call)
+ (ivy-define-key map (kbd "M-a") 'ivy-toggle-marks)
+ (ivy-define-key map (kbd "M-r") 'ivy-toggle-regexp-quote)
+ (ivy-define-key map (kbd "M-j") 'ivy-yank-word)
+ (ivy-define-key map (kbd "M-i") 'ivy-insert-current)
+ (ivy-define-key map (kbd "C-M-y") 'ivy-insert-current-full)
+ (ivy-define-key map (kbd "C-o") 'hydra-ivy/body)
+ (ivy-define-key map (kbd "M-o") 'ivy-dispatching-done)
+ (ivy-define-key map (kbd "C-M-o") 'ivy-dispatching-call)
+ (ivy-define-key map [remap kill-line] 'ivy-kill-line)
+ (ivy-define-key map [remap kill-whole-line] 'ivy-kill-whole-line)
+ (ivy-define-key map (kbd "S-SPC") 'ivy-restrict-to-matches)
+ (ivy-define-key map [remap kill-ring-save] 'ivy-kill-ring-save)
+ (ivy-define-key map (kbd "C-M-a") 'ivy-read-action)
+ (ivy-define-key map (kbd "C-c C-o") 'ivy-occur)
+ (ivy-define-key map (kbd "C-c C-a") 'ivy-toggle-ignore)
+ (ivy-define-key map (kbd "C-c C-s") 'ivy-rotate-sort)
+ (ivy-define-key map [remap describe-mode] 'ivy-help)
+ (ivy-define-key map "$" 'ivy-magic-read-file-env)
+ map)
+ "Keymap used in the minibuffer.")
+(autoload 'hydra-ivy/body "ivy-hydra" "" t)
+(autoload 'ivy-hydra-read-action "ivy-hydra" "" t)
+
+(defvar ivy-mode-map
+ (let ((map (make-sparse-keymap)))
+ (ivy-define-key map [remap switch-to-buffer] 'ivy-switch-buffer)
+ (ivy-define-key map [remap switch-to-buffer-other-window] 'ivy-switch-buffer-other-window)
+ map)
+ "Keymap for `ivy-mode'.")
+
+;;* Globals
+(cl-defstruct ivy-state
+ prompt collection
+ predicate require-match initial-input
+ history preselect keymap update-fn sort
+ ;; The frame in which `ivy-read' was called
+ frame
+ ;; The window in which `ivy-read' was called
+ window
+ ;; The buffer in which `ivy-read' was called
+ buffer
+ ;; The value of `ivy-text' to be used by `ivy-occur'
+ text
+ action
+ unwind
+ re-builder
+ matcher
+ ;; When this is non-nil, call it for each input change to get new candidates
+ dynamic-collection
+ ;; A lambda that transforms candidates only for display
+ display-transformer-fn
+ directory
+ caller
+ current
+ def
+ ignore
+ multi-action
+ extra-props)
+
+(defvar ivy-last (make-ivy-state)
+ "The last parameters passed to `ivy-read'.
+
+This should eventually become a stack so that you could use
+`ivy-read' recursively.")
+
+(defvar ivy--sessions nil
+ "Alist mapping session symbols to `ivy-state' objects.")
+
+(defvar ivy-recursive-last nil)
+
+(defvar ivy-recursive-restore t
+ "When non-nil, restore the above state when exiting the minibuffer.
+This variable is let-bound to nil by functions that take care of
+the restoring themselves.")
+
+(defsubst ivy-set-action (action)
+ "Set the current `ivy-last' field to ACTION."
+ (setf (ivy-state-action ivy-last) action))
+
+(defvar inhibit-message)
+
+(defvar ffap-machine-p-known)
+
+(defun ivy-thing-at-point ()
+ "Return a string that corresponds to the current thing at point."
+ (substring-no-properties
+ (cond
+ ((use-region-p)
+ (let* ((beg (region-beginning))
+ (end (region-end))
+ (eol (save-excursion (goto-char beg) (line-end-position))))
+ (buffer-substring-no-properties beg (min end eol))))
+ ((thing-at-point 'url))
+ ((and (eq (ivy-state-collection ivy-last) #'read-file-name-internal)
+ (let ((inhibit-message t)
+ (ffap-machine-p-known 'reject))
+ (run-hook-with-args-until-success 'file-name-at-point-functions))))
+ ((let ((s (thing-at-point 'symbol)))
+ (and (stringp s)
+ (if (string-match "\\`[`']?\\(.*?\\)'?\\'" s)
+ (match-string 1 s)
+ s))))
+ ((looking-at "(+\\(\\(?:\\sw\\|\\s_\\)+\\)\\_>")
+ (match-string-no-properties 1))
+ (t
+ ""))))
+
+(defvar ivy-history nil
+ "History list of candidates entered in the minibuffer.
+
+Maximum length of the history list is determined by the value
+of `history-length'.")
+
+(defvar ivy--directory nil
+ "Current directory when completing file names.")
+
+(defvar ivy--directory-hist nil
+ "Store the history of directories.
+This allows RET to reverse consecutive DEL.")
+
+(defvar ivy--length 0
+ "Store the amount of viable candidates.")
+
+(defvar ivy-text ""
+ "Store the user's string as it is typed in.")
+
+(defvar ivy-regex ""
+ "Store the regex value that corresponds to `ivy-text'.")
+
+(defvar ivy--regex-function 'ivy--regex
+ "Current function for building a regex.")
+
+(defun ivy-set-text (str)
+ "Set `ivy-text' to STR."
+ (setq ivy-text str)
+ (setq ivy-regex (funcall ivy--regex-function ivy-text)))
+
+(defvar ivy--index 0
+ "Store the index of the current candidate.")
+
+(defvar ivy--window-index 0
+ "Store the index of the current candidate in the minibuffer window.
+
+This means it's between 0 and `ivy-height'.")
+
+(defvar ivy-exit nil
+ "Store `done' if the completion was successfully selected.
+Otherwise, store nil.")
+
+(defvar ivy--all-candidates nil
+ "Store the candidates passed to `ivy-read'.")
+
+(defvar ivy--extra-candidates '((original-source))
+ "Store candidates added by the extra sources.
+
+This is an internal-use alist. Each key is a function name, or
+original-source (which represents where the current dynamic
+candidates should go).
+
+Each value is an evaluation of the function, in case of static
+sources. These values will subsequently be filtered on `ivy-text'.
+
+This variable is set by `ivy-read' and used by `ivy--set-candidates'.")
+
+(defcustom ivy-use-ignore-default t
+ "The default policy for user-configured candidate filtering."
+ :type '(choice
+ (const :tag "Ignore ignored always" always)
+ (const :tag "Ignore ignored when others exist" t)
+ (const :tag "Don't ignore" nil)))
+
+(defvar ivy-use-ignore t
+ "Store policy for user-configured candidate filtering.
+This may be changed dynamically by `ivy-toggle-ignore'.
+Use `ivy-use-ignore-default' for a permanent configuration.")
+
+(defvar ivy--default nil
+ "Default initial input.")
+
+(defvar ivy--prompt nil
+ "Store the format-style prompt.
+When non-nil, it should contain at least one %d.")
+
+(defvar ivy--prompt-extra ""
+ "Temporary modifications to the prompt.")
+
+(defvar ivy--old-re nil
+ "Store the old regexp.
+Either a string or a list for `ivy-re-match'.")
+
+(defvar ivy--old-cands nil
+ "Store the candidates matched by `ivy--old-re'.")
+
+(defvar ivy--highlight-function 'ivy--highlight-default
+ "Current function for formatting the candidates.")
+
+(defvar ivy--subexps 0
+ "Number of groups in the current `ivy--regex'.")
+
+(defvar ivy--full-length nil
+ "The total amount of candidates when :dynamic-collection is non-nil.")
+
+(defvar ivy--old-text ""
+ "Store old `ivy-text' for dynamic completion.")
+
+(defvar ivy--trying-to-resume-dynamic-collection nil
+ "Non-nil if resuming from a dynamic collection.
+When non-nil, ivy will wait until the first chunk of asynchronous
+candidates has been received before selecting the last
+preselected candidate.")
+
+(defun ivy--set-index-dynamic-collection ()
+ (when ivy--trying-to-resume-dynamic-collection
+ (let ((preselect-index
+ (ivy--preselect-index (ivy-state-preselect ivy-last) ivy--all-candidates)))
+ (when preselect-index
+ (ivy-set-index preselect-index)))
+ (setq ivy--trying-to-resume-dynamic-collection nil)))
+
+(defcustom ivy-case-fold-search-default
+ (if search-upper-case
+ 'auto
+ case-fold-search)
+ "The default value for `case-fold-search' in Ivy operations.
+The special value `auto' means case folding is performed so long
+as the entire input string comprises lower-case characters. This
+corresponds to the default behaviour of most Emacs search
+functionality, e.g. as seen in `isearch'."
+ :link '(info-link "(emacs)Lax Search")
+ :type '(choice
+ (const :tag "Auto" auto)
+ (const :tag "Always" t)
+ (const :tag "Never" nil)))
+
+(defvar ivy-case-fold-search ivy-case-fold-search-default
+ "Store the current overriding `case-fold-search'.")
+
+(defcustom ivy-more-chars-alist
+ '((t . 3))
+ "Map commands to their minimum required input length.
+That is the number of characters prompted for before fetching
+candidates. The special key t is used as a fallback."
+ :type '(alist :key-type symbol :value-type integer))
+
+(defun ivy-more-chars ()
+ "Return two fake candidates prompting for at least N input.
+N is obtained from `ivy-more-chars-alist'."
+ (let ((diff (- (ivy-alist-setting ivy-more-chars-alist)
+ (length ivy-text))))
+ (when (> diff 0)
+ (list "" (format "%d chars more" diff)))))
+
+(defun ivy--case-fold-p (string)
+ "Return nil if STRING should be matched case-sensitively."
+ (if (eq ivy-case-fold-search 'auto)
+ (string= string (downcase string))
+ ivy-case-fold-search))
+
+(defun ivy--case-fold-string= (s1 s2)
+ "Like `string=', but obeys `case-fold-search'."
+ (eq t (compare-strings s1 nil nil s2 nil nil case-fold-search)))
+
+(defmacro ivy-quit-and-run (&rest body)
+ "Quit the minibuffer and run BODY afterwards."
+ (declare (indent 0))
+ `(progn
+ (put 'quit 'error-message "")
+ (run-at-time nil nil
+ (lambda ()
+ (put 'quit 'error-message "Quit")
+ (with-demoted-errors "Error: %S"
+ ,@body)))
+ (abort-recursive-edit)))
+
+(defun ivy-exit-with-action (action &optional exit-code)
+ "Quit the minibuffer and call ACTION afterwards."
+ (ivy-set-action
+ `(lambda (x)
+ (funcall ',action x)
+ (ivy-set-action ',(ivy-state-action ivy-last))))
+ (setq ivy-exit (or exit-code 'done))
+ (exit-minibuffer))
+
+(defmacro with-ivy-window (&rest body)
+ "Execute BODY in the window from which `ivy-read' was called."
+ (declare (indent 0)
+ (debug t))
+ `(with-selected-window (ivy--get-window ivy-last)
+ ,@body))
+
+(defun ivy--expand-file-name (text)
+ (cond
+ ((eq (ivy-state-history ivy-last) 'grep-files-history)
+ text)
+ (ivy--directory
+ (if (and (string-match-p "^/" text) (file-remote-p ivy--directory))
+ (let ((parts (split-string ivy--directory ":")))
+ (concat (nth 0 parts) ":" (nth 1 parts) ":" text))
+ (expand-file-name text ivy--directory)))
+ (t
+ text)))
+
+(defun ivy--done (text)
+ "Insert TEXT and exit minibuffer."
+ (if (member (ivy-state-prompt ivy-last) '("Create directory: " "Make directory: "))
+ (ivy-immediate-done)
+ (when (stringp text)
+ (insert
+ (setf (ivy-state-current ivy-last)
+ (ivy--expand-file-name text))))
+ (setq ivy-exit 'done)
+ (exit-minibuffer)))
+
+(defcustom ivy-use-selectable-prompt nil
+ "When non-nil, make the prompt line selectable like a candidate.
+
+The prompt line can be selected by calling `ivy-previous-line' when the first
+regular candidate is selected. Both actions `ivy-done' and `ivy-alt-done',
+when called on a selected prompt, are forwarded to `ivy-immediate-done', which
+results to the same as calling `ivy-immediate-done' explicitly when a regular
+candidate is selected.
+
+Note that if `ivy-wrap' is set to t, calling `ivy-previous-line' when the
+prompt is selected wraps around to the last candidate, while calling
+`ivy-next-line' on the last candidate wraps around to the first
+candidate, not the prompt."
+ :type 'boolean)
+
+(defvar ivy--use-selectable-prompt nil
+ "Store the effective `ivy-use-selectable-prompt' for current session.")
+
+(defun ivy--prompt-selectable-p ()
+ "Return t if the prompt line is selectable."
+ (and ivy-use-selectable-prompt
+ (or (memq (ivy-state-require-match ivy-last)
+ '(nil confirm confirm-after-completion))
+ ;; :require-match is t, but "" is in the collection
+ (let ((coll (ivy-state-collection ivy-last)))
+ (and (listp coll)
+ (if (consp (car coll))
+ (member '("") coll)
+ (member "" coll)))))))
+
+(defun ivy--prompt-selected-p ()
+ "Return t if the prompt line is selected."
+ (and ivy--use-selectable-prompt
+ (= ivy--index -1)))
+
+;;* Commands
+(defun ivy-done ()
+ "Exit the minibuffer with the selected candidate."
+ (interactive)
+ (if (ivy--prompt-selected-p)
+ (ivy-immediate-done)
+ (setq ivy-current-prefix-arg current-prefix-arg)
+ (let ((require-match (ivy-state-require-match ivy-last))
+ (input (ivy--input)))
+ (delete-minibuffer-contents)
+ (cond ((and (= ivy--length 0)
+ (eq this-command 'ivy-dispatching-done))
+ (ivy--done ivy-text))
+ ((or (> ivy--length 0)
+ ;; the action from `ivy-dispatching-done' may not need a
+ ;; candidate at all
+ (eq this-command 'ivy-dispatching-done))
+ (ivy--done (ivy-state-current ivy-last)))
+ ((string= " (confirm)" ivy--prompt-extra)
+ (ivy--done ivy-text))
+ ((or (and (memq (ivy-state-collection ivy-last)
+ '(read-file-name-internal internal-complete-buffer))
+ (eq confirm-nonexistent-file-or-buffer t))
+ (and (functionp require-match)
+ (setq require-match (funcall require-match))))
+ (setq ivy--prompt-extra " (confirm)")
+ (insert input)
+ (ivy--exhibit))
+ ((memq require-match '(nil confirm confirm-after-completion))
+ (ivy--done ivy-text))
+ (t
+ (setq ivy--prompt-extra " (match required)")
+ (insert ivy-text)
+ (ivy--exhibit))))))
+
+(defvar ivy-mouse-1-tooltip
+ "Exit the minibuffer with the selected candidate."
+ "The doc visible in the tooltip for mouse-1 binding in the minibuffer.")
+(defvar ivy-mouse-3-tooltip
+ "Display alternative actions."
+ "The doc visible in the tooltip for mouse-3 binding in the minibuffer.")
+
+(defun ivy-mouse-offset (event)
+ "Compute the offset between the candidate at point and the selected one."
+ (if event
+ (let* ((line-number-at-point
+ (max 2
+ (line-number-at-pos (posn-point (event-start event)))))
+
+ (line-number-candidate ;; convert to 0 based index
+ (- line-number-at-point 2))
+ (offset
+ (- line-number-candidate
+ ivy--window-index)))
+ offset)
+ nil))
+
+(defun ivy-mouse-done (event)
+ (interactive "@e")
+ (let ((offset (ivy-mouse-offset event)))
+ (when offset
+ (ivy-next-line offset)
+ (ivy--exhibit)
+ (ivy-alt-done))))
+
+(defun ivy-mouse-dispatching-done (event)
+ (interactive "@e")
+ (let ((offset (ivy-mouse-offset event)))
+ (when offset
+ (ivy-next-line offset)
+ (ivy--exhibit)
+ (ivy-dispatching-done))))
+
+(defcustom ivy-read-action-format-function 'ivy-read-action-format-default
+ "Function used to transform the actions list into a docstring."
+ :type '(radio
+ (function-item ivy-read-action-format-default)
+ (function-item ivy-read-action-format-columns)))
+
+(defun ivy-read-action-format-default (actions)
+ "Create a docstring from ACTIONS.
+
+ACTIONS is a list. Each list item is a list of 3 items:
+key (a string), cmd and doc (a string)."
+ (format "%s\n%s\n"
+ (if (eq this-command 'ivy-read-action)
+ "Select action: "
+ (ivy-state-current ivy-last))
+ (mapconcat
+ (lambda (x)
+ (format "%s: %s"
+ (propertize
+ (car x)
+ 'face 'ivy-action)
+ (nth 2 x)))
+ actions
+ "\n")))
+
+(defun ivy-read-action-format-columns (actions)
+ "Create a potentially multi-column docstring from ACTIONS.
+Several columns are used as needed to preserve `ivy-height'.
+
+ACTIONS is a list with elements of the form (KEY COMMAND DOC),
+where KEY and DOC are strings."
+ (let ((length (length actions))
+ (i 0)
+ (max-rows (- ivy-height 1))
+ rows cols col lwidth rwidth)
+ (while (< i length)
+ (setq col (cl-subseq actions i (min length (cl-incf i max-rows))))
+ (setq lwidth (apply 'max (mapcar (lambda (x)
+ (length (nth 0 x)))
+ col)))
+ (setq rwidth (apply 'max (mapcar (lambda (x)
+ (length (nth 2 x)))
+ col)))
+ (setq col (mapcar (lambda (x)
+ (format (format "%%%ds: %%-%ds" lwidth rwidth)
+ (propertize (car x) 'face 'ivy-action)
+ (nth 2 x)))
+ col))
+ (cond
+ ((null rows)
+ (setq rows (length col)))
+ ((< (length col) rows)
+ (setq col (append col (make-list (- rows (length col)) "")))))
+ (push col cols))
+ (format "%s\n%s\n"
+ (if (eq this-command 'ivy-read-action)
+ "Select action: "
+ (ivy-state-current ivy-last))
+ (mapconcat 'identity
+ (apply 'cl-mapcar
+ (lambda (&rest args)
+ (mapconcat 'identity args " | "))
+ (nreverse cols))
+ "\n"))))
+
+(defcustom ivy-read-action-function #'ivy-read-action-by-key
+ "Function used to read an action."
+ :type '(radio
+ (function-item ivy-read-action-by-key)
+ (function-item ivy-read-action-ivy)
+ (function-item ivy-hydra-read-action)))
+
+(defun ivy-read-action ()
+ "Change the action to one of the available ones.
+
+Return nil for `minibuffer-keyboard-quit' or wrong key during the
+selection, non-nil otherwise."
+ (interactive)
+ (let ((actions (ivy-state-action ivy-last)))
+ (if (not (ivy--actionp actions))
+ t
+ (let ((ivy--directory ivy--directory))
+ (funcall ivy-read-action-function actions)))))
+
+(defvar set-message-function)
+
+(defun ivy-read-action-by-key (actions)
+ (let* ((set-message-function nil)
+ (hint (funcall ivy-read-action-format-function (cdr actions)))
+ (resize-mini-windows t)
+ (key "")
+ action-idx)
+ (while (and (setq action-idx (cl-position-if
+ (lambda (x)
+ (string-prefix-p key (car x)))
+ (cdr actions)))
+ (not (string= key (car (nth action-idx (cdr actions))))))
+ (setq key (concat key (key-description (vector (read-key hint))))))
+ ;; Ignore resize errors with minibuffer-only frames (#2726).
+ (ignore-errors (ivy-shrink-after-dispatching))
+ (cond ((member key '("ESC" "C-g" "M-o"))
+ nil)
+ ((null action-idx)
+ (message "%s is not bound" key)
+ nil)
+ (t
+ (message "")
+ (setcar actions (1+ action-idx))
+ (ivy-set-action actions)))))
+
+(defvar ivy-marked-candidates nil
+ "List of marked candidates.
+Use `ivy-mark' to populate this.
+
+When this list is non-nil at the end of the session, the action
+will be called for each element of this list.")
+
+(defun ivy-read-action-ivy (actions)
+ "Select an action from ACTIONS using Ivy."
+ (let ((enable-recursive-minibuffers t))
+ (if (and (> (minibuffer-depth) 1)
+ (eq (ivy-state-caller ivy-last) 'ivy-read-action-ivy))
+ (minibuffer-keyboard-quit)
+ (let ((ivy-marked-candidates ivy-marked-candidates))
+ (ivy-read (format "action (%s): " (ivy-state-current ivy-last))
+ (cl-mapcar
+ (lambda (a i) (cons (format "[%s] %s" (nth 0 a) (nth 2 a)) i))
+ (cdr actions) (number-sequence 1 (length (cdr actions))))
+ :action (lambda (a)
+ (setcar actions (cdr a))
+ (ivy-set-action actions))
+ :caller 'ivy-read-action-ivy)))))
+
+(defun ivy-shrink-after-dispatching ()
+ "Shrink the window after dispatching when action list is too large."
+ (when (window-minibuffer-p)
+ (window-resize nil (- ivy-height (window-height)))))
+
+(defun ivy-dispatching-done ()
+ "Select one of the available actions and call `ivy-done'."
+ (interactive)
+ (let ((ivy-exit 'ivy-dispatching-done))
+ (when (ivy-read-action)
+ (ivy-done)))
+ (ivy-shrink-after-dispatching))
+
+(defun ivy-dispatching-call ()
+ "Select one of the available actions and call `ivy-call'."
+ (interactive)
+ (setq ivy-current-prefix-arg current-prefix-arg)
+ (let ((actions (copy-sequence (ivy-state-action ivy-last)))
+ (old-ivy-text ivy-text))
+ (unwind-protect
+ (when (ivy-read-action)
+ (ivy-set-text old-ivy-text)
+ (ivy-call))
+ (ivy-set-action actions)))
+ (ivy-shrink-after-dispatching))
+
+(defun ivy-build-tramp-name (x)
+ "Reconstruct X into a path.
+Is is a cons cell, related to `tramp-get-completion-function'."
+ (let ((user (car x))
+ (domain (cadr x)))
+ (if user
+ (concat user "@" domain)
+ domain)))
+
+(declare-function Info-find-node "info")
+(declare-function Info-read-node-name-1 "info")
+(declare-function tramp-get-completion-function "tramp")
+
+(defcustom ivy-alt-done-functions-alist nil
+ "Customize what `ivy-alt-done' does per-collection."
+ :type '(alist :key-type symbol :value-type function))
+
+(defun ivy--completing-fname-p ()
+ (let ((meta (ignore-errors
+ (funcall (ivy-state-collection ivy-last) ivy-text nil 'metadata))))
+ (and (consp meta)
+ (eq 'file (cdr (assoc 'category meta))))))
+
+(defun ivy-alt-done (&optional arg)
+ "Exit the minibuffer with the selected candidate.
+When ARG is t, exit with current text, ignoring the candidates.
+When the current candidate during file name completion is a
+directory, continue completion from within that directory instead
+of exiting. This function is otherwise like `ivy-done'."
+ (interactive "P")
+ (setq ivy-current-prefix-arg current-prefix-arg)
+ (let (alt-done-fn)
+ (cond ((or arg (ivy--prompt-selected-p))
+ (ivy-immediate-done))
+ ((setq alt-done-fn (ivy-alist-setting ivy-alt-done-functions-alist))
+ (funcall alt-done-fn))
+ ((ivy--completing-fname-p)
+ (ivy--directory-done))
+ (t
+ (ivy-done)))))
+
+(defun ivy--info-alt-done ()
+ (if (member (ivy-state-current ivy-last) '("(./)" "(../)"))
+ (ivy-quit-and-run
+ (ivy-read "Go to file: " #'read-file-name-internal
+ :action (lambda (x)
+ (Info-find-node
+ (expand-file-name x ivy--directory)
+ "Top"))))
+ (ivy-done)))
+
+(defvar ivy-auto-select-single-candidate nil
+ "When non-nil, auto-select the candidate if it is the only one.
+When t, it is the same as if the user were prompted and selected the candidate
+by calling the default action. This variable has no use unless the collection
+contains a single candidate.")
+
+(defun ivy--directory-enter ()
+ (let (dir)
+ (when (and
+ (> ivy--length 0)
+ (not (string= (ivy-state-current ivy-last) "./"))
+ (setq dir (ivy-expand-file-if-directory (ivy-state-current ivy-last))))
+ (ivy--cd dir)
+ (ivy--exhibit))))
+
+(defun ivy--handle-directory (input)
+ "Detect the next directory based on special values of INPUT."
+ (cond ((string= input "/")
+ "/")
+ ((string= input "/sudo::")
+ (concat input ivy--directory))))
+
+(defun ivy--tramp-candidates ()
+ (let ((method (match-string 1 ivy-text))
+ (user (match-string 2 ivy-text))
+ (rest (match-string 3 ivy-text))
+ res)
+ (dolist (x (tramp-get-completion-function method))
+ (setq res (append res (funcall (car x) (cadr x)))))
+ (setq res (delq nil res))
+ (when user
+ (dolist (x res)
+ (setcar x user)))
+ (setq res (delete-dups res))
+ (let* ((old-ivy-last ivy-last)
+ (enable-recursive-minibuffers t)
+ (host (let ((ivy-auto-select-single-candidate nil))
+ (ivy-read "user@host: "
+ (mapcar #'ivy-build-tramp-name res)
+ :initial-input rest))))
+ (setq ivy-last old-ivy-last)
+ (when host
+ (setq ivy--directory "/")
+ (ivy--cd (concat "/" method ":" host ":/"))))))
+
+(defun ivy--directory-done ()
+ "Handle exit from the minibuffer when completing file names."
+ (let ((dir (ivy--handle-directory ivy-text)))
+ (cond ((equal (ivy-state-current ivy-last) (ivy-state-def ivy-last))
+ (ivy-done))
+ ((and (ivy-state-require-match ivy-last)
+ (equal ivy-text "")
+ (null ivy--old-cands))
+ (ivy-immediate-done))
+ (dir
+ (let ((inhibit-message t))
+ (ivy--cd dir)))
+ ((ivy--directory-enter))
+ ((unless (string= ivy-text "")
+ ;; Obsolete since 26.1 and removed in 28.1.
+ (defvar tramp-completion-mode)
+ (with-no-warnings
+ (let* ((tramp-completion-mode t)
+ (file (expand-file-name
+ (if (> ivy--length 0) (ivy-state-current ivy-last) ivy-text)
+ ivy--directory)))
+ (when (ignore-errors (file-exists-p file))
+ (if (file-directory-p file)
+ (ivy--cd (file-name-as-directory file))
+ (ivy-done))
+ ivy-text)))))
+ ((or (and (equal ivy--directory "/")
+ (string-match-p "\\`[^/]+:.*:.*\\'" ivy-text))
+ (string-match-p "\\`/[^/]+:.*:.*\\'" ivy-text))
+ (ivy-done))
+ ((ivy--tramp-prefix-p)
+ (ivy--tramp-candidates))
+ (t
+ (ivy-done)))))
+
+(defun ivy--tramp-prefix-p ()
+ (or (and (equal ivy--directory "/")
+ (cond ((string-match
+ "\\`\\([^/]+?\\):\\(?:\\(.*\\)@\\)?\\(.*\\)\\'"
+ ivy-text)
+ (save-match-data
+ (ivy-set-text (ivy-state-current ivy-last))))
+ ((string-match
+ "\\`\\([^/]+?\\):\\(?:\\(.*\\)@\\)?\\(.*\\)\\'"
+ (ivy-state-current ivy-last))
+ (save-match-data
+ (ivy-set-text (ivy-state-current ivy-last))))))
+ (string-match
+ "\\`/\\([^/]+?\\):\\(?:\\(.*\\)@\\)?\\(.*\\)\\'"
+ ivy-text)))
+
+(defun ivy-expand-file-if-directory (file-name)
+ "Expand FILE-NAME as directory.
+When this directory doesn't exist, return nil."
+ (when (stringp file-name)
+ (let ((full-name
+ ;; Ignore host name must not match method "ssh"
+ (ignore-errors
+ (file-name-as-directory
+ (expand-file-name file-name ivy--directory)))))
+ (when (and full-name (file-directory-p full-name))
+ full-name))))
+
+(defcustom ivy-tab-space nil
+ "When non-nil, `ivy-partial-or-done' should insert a space."
+ :type 'boolean)
+
+(defun ivy-partial-or-done ()
+ "Complete the minibuffer text as much as possible.
+If the text hasn't changed as a result, forward to `ivy-alt-done'."
+ (interactive)
+ (cond
+ ((and (numberp completion-cycle-threshold)
+ (< (length ivy--all-candidates) completion-cycle-threshold))
+ (let ((ivy-wrap t))
+ (ivy-next-line)))
+ ((and (eq (ivy-state-collection ivy-last) #'read-file-name-internal)
+ (or (and (equal ivy--directory "/")
+ (string-match-p "\\`[^/]+:.*\\'" ivy-text))
+ (= (string-to-char ivy-text) ?/)))
+ (let ((default-directory ivy--directory)
+ dir)
+ (minibuffer-complete)
+ (ivy-set-text (ivy--input))
+ (when (setq dir (ivy-expand-file-if-directory ivy-text))
+ (ivy--cd dir))))
+ (t
+ (or (ivy-partial)
+ (when (or (eq this-command last-command)
+ (eq ivy--length 1))
+ (ivy-alt-done))))))
+
+(defun ivy--partial-cd-for-single-directory ()
+ (when (and
+ (eq (ivy-state-collection ivy-last) #'read-file-name-internal)
+ (= 1 (length
+ (ivy--re-filter
+ (funcall ivy--regex-function
+ (concat "^" (string-remove-prefix "^" ivy-text)))
+ ivy--all-candidates)))
+ (let ((default-directory ivy--directory))
+ (file-directory-p (ivy-state-current ivy-last))))
+ (ivy--directory-done)))
+
+(defun ivy-partial ()
+ "Complete the minibuffer text as much as possible."
+ (interactive)
+ (if (ivy-state-dynamic-collection ivy-last)
+ (let* ((bnd
+ (ignore-errors
+ (funcall
+ (ivy-state-collection ivy-last)
+ ivy-text nil (cons 'boundaries (buffer-substring (point) (line-end-position))))))
+ (beg (+ (minibuffer-prompt-end)
+ (if bnd (cadr bnd) 0))))
+ (delete-region beg (point-max))
+ (insert
+ (ivy-state-current ivy-last))
+ t)
+ (let* ((parts (or (ivy--split-spaces ivy-text) (list "")))
+ (tail (last parts))
+ (postfix (car tail))
+ (case-fold-search (ivy--case-fold-p ivy-text))
+ (completion-ignore-case case-fold-search)
+ (new (try-completion (string-remove-prefix "^" postfix)
+ (mapcar (lambda (str)
+ (let ((i (string-match-p postfix str)))
+ (and i (substring str i))))
+ ivy--old-cands))))
+ (cond
+ ((eq new t) nil)
+ ((string= new ivy-text) nil)
+ ((string= (car tail) (car (ivy--split-spaces new))) nil)
+ (new
+ (delete-region (minibuffer-prompt-end) (point-max))
+ (setcar tail
+ (if (= (string-to-char postfix) ?^)
+ (concat "^" new)
+ new))
+ (ivy-set-text
+ (concat
+ (mapconcat #'identity parts " ")
+ (and ivy-tab-space (not (= (length ivy--old-cands) 1)) " ")))
+ (insert ivy-text)
+ (ivy--partial-cd-for-single-directory)
+ t)))))
+
+(defvar ivy-completion-beg nil
+ "Completion bounds start.")
+
+(defvar ivy-completion-end nil
+ "Completion bounds end.")
+
+(defun ivy-immediate-done ()
+ "Exit the minibuffer with current input instead of current candidate."
+ (interactive)
+ (delete-minibuffer-contents)
+ (setf (ivy-state-current ivy-last)
+ (cond ((or (not ivy--directory)
+ (eq (ivy-state-history ivy-last) 'grep-files-history))
+ ivy-text)
+ ((and (string= ivy-text "")
+ (eq (ivy-state-collection ivy-last)
+ #'read-file-name-internal))
+ (if (ivy-state-def ivy-last)
+ (if (and
+ (file-exists-p (ivy-state-def ivy-last))
+ (/= (length ivy--directory)
+ (1+ (length (expand-file-name (ivy-state-def ivy-last))))))
+ ivy--directory
+ (copy-sequence (ivy-state-def ivy-last)))
+ ivy--directory))
+ (t
+ (expand-file-name ivy-text ivy--directory))))
+ (insert (ivy-state-current ivy-last))
+ (setq ivy-completion-beg ivy-completion-end)
+ (setq ivy-exit 'done)
+ (exit-minibuffer))
+
+(defun ivy--restore-session (&optional session)
+ "Resume a recorded completion SESSION, if any exists."
+ (when ivy--sessions
+ (unless session
+ (setq session (intern
+ (let ((ivy-last ivy-last)
+ ivy--all-candidates
+ ivy-text)
+ (ivy-read "Choose ivy session: "
+ ivy--sessions
+ :require-match t)))))
+ (setq ivy-last (or (cdr (assq session ivy--sessions))
+ ivy-last)))
+ (let ((data (plist-get (ivy-state-extra-props ivy-last) :ivy-data)))
+ (when data
+ (setq ivy--all-candidates (plist-get data :all-candidates))
+ (setq ivy-text (plist-get data :text)))))
+
+;;;###autoload
+(defun ivy-resume (&optional session)
+ "Resume the last completion session, or SESSION if non-nil.
+With a prefix arg, try to restore a recorded completion session,
+if one exists."
+ (interactive)
+ (when (or current-prefix-arg session)
+ (ivy--restore-session session))
+
+ (if (or (null (ivy-state-action ivy-last))
+ (eq (ivy--get-action ivy-last) #'identity))
+ (user-error "The last session isn't compatible with `ivy-resume'")
+ (when (memq (ivy-state-caller ivy-last)
+ '(swiper
+ swiper-isearch swiper-backward
+ swiper-isearch-backward
+ counsel-grep))
+ (switch-to-buffer (ivy-state-buffer ivy-last)))
+ (with-current-buffer (ivy-state-buffer ivy-last)
+ (let ((default-directory (ivy-state-directory ivy-last))
+ (ivy-use-ignore-default (ivy-state-ignore ivy-last)))
+ (ivy-read
+ (ivy-state-prompt ivy-last)
+ (ivy-state-collection ivy-last)
+ :predicate (ivy-state-predicate ivy-last)
+ :require-match (ivy-state-require-match ivy-last)
+ :initial-input ivy-text
+ :history (ivy-state-history ivy-last)
+ :preselect (ivy-state-current ivy-last)
+ :keymap (ivy-state-keymap ivy-last)
+ :update-fn (ivy-state-update-fn ivy-last)
+ :sort (ivy-state-sort ivy-last)
+ :action (ivy-state-action ivy-last)
+ :unwind (ivy-state-unwind ivy-last)
+ :re-builder (ivy-state-re-builder ivy-last)
+ :matcher (ivy-state-matcher ivy-last)
+ :dynamic-collection (ivy-state-dynamic-collection ivy-last)
+ :extra-props (ivy-state-extra-props ivy-last)
+ :caller (ivy-state-caller ivy-last))))))
+
+(defvar-local ivy-calling nil
+ "When non-nil, call the current action when `ivy--index' changes.")
+
+(defun ivy-set-index (index)
+ "Set `ivy--index' to INDEX."
+ (setq ivy--index index)
+ (when ivy-calling
+ (ivy--exhibit)
+ (ivy-call)))
+
+(defun ivy-beginning-of-buffer ()
+ "Select the first completion candidate."
+ (interactive)
+ (ivy-set-index 0))
+
+(defun ivy-end-of-buffer ()
+ "Select the last completion candidate."
+ (interactive)
+ (ivy-set-index (1- ivy--length)))
+
+(defun ivy-scroll-up-command ()
+ "Scroll the candidates upward by the minibuffer height."
+ (interactive)
+ (ivy-set-index (min (1- (+ ivy--index ivy-height))
+ (1- ivy--length))))
+
+(defun ivy-scroll-down-command ()
+ "Scroll the candidates downward by the minibuffer height."
+ (interactive)
+ (ivy-set-index (max (1+ (- ivy--index ivy-height))
+ 0)))
+
+(defun ivy-next-line (&optional arg)
+ "Move cursor vertically down ARG candidates."
+ (interactive "p")
+ (setq arg (or arg 1))
+ (let ((index (+ ivy--index arg)))
+ (if (> index (1- ivy--length))
+ (if ivy-wrap
+ (ivy-beginning-of-buffer)
+ (ivy-set-index (1- ivy--length)))
+ (ivy-set-index index))))
+
+(defun ivy-next-line-or-history (&optional arg)
+ "Move cursor vertically down ARG candidates.
+If the input is empty, select the previous history element instead."
+ (interactive "p")
+ (let ((orig-index ivy--index))
+ (ivy-next-line arg)
+ (when (and (string= ivy-text "") (= ivy--index orig-index))
+ (ivy-previous-history-element 1))))
+
+(defun ivy-previous-line (&optional arg)
+ "Move cursor vertically up ARG candidates."
+ (interactive "p")
+ (setq arg (or arg 1))
+ (let ((index (- ivy--index arg))
+ (min-index (if ivy--use-selectable-prompt -1 0)))
+ (if (< index min-index)
+ (if ivy-wrap
+ (ivy-end-of-buffer)
+ (ivy-set-index min-index))
+ (ivy-set-index index))))
+
+(defun ivy-previous-line-or-history (arg)
+ "Move cursor vertically up ARG candidates.
+If the input is empty, select the previous history element instead."
+ (interactive "p")
+ (let ((orig-index ivy--index))
+ (ivy-previous-line arg)
+ (when (and (string= ivy-text "") (= ivy--index orig-index))
+ (ivy-previous-history-element 1))))
+
+(defun ivy-toggle-calling ()
+ "Flip `ivy-calling'."
+ (interactive)
+ (when (setq ivy-calling (not ivy-calling))
+ (ivy-call)))
+
+(defun ivy-toggle-ignore ()
+ "Toggle user-configured candidate filtering."
+ (interactive)
+ (setq ivy-use-ignore
+ (if ivy-use-ignore
+ nil
+ (or ivy-use-ignore-default t)))
+ (setf (ivy-state-ignore ivy-last) ivy-use-ignore)
+ ;; invalidate cache
+ (setq ivy--old-cands nil))
+
+(defun ivy--get-action (state)
+ "Get the action function from STATE."
+ (let ((action (ivy-state-action state)))
+ (when action
+ (if (functionp action)
+ action
+ (cadr (nth (car action) action))))))
+
+(defun ivy--get-multi-action (state)
+ "Get the multi-action function from STATE."
+ (let* ((action (ivy-state-action state))
+ (multi-action
+ (and (listp action)
+ (not (eq (car action) 'lambda))
+ (nth 3 (nth (car action) action)))))
+ (if multi-action
+ multi-action
+ (when (eq (car action) 1)
+ (ivy-state-multi-action state)))))
+
+(defun ivy--get-window (state)
+ "Get the window from STATE."
+ (if (ivy-state-p state)
+ (let ((window (ivy-state-window state)))
+ (if (window-live-p window)
+ window
+ (next-window)))
+ (selected-window)))
+
+(defun ivy--actionp (x)
+ "Return non-nil when X is a list of actions."
+ (and (consp x) (not (memq (car x) '(closure lambda)))))
+
+(defcustom ivy-action-wrap nil
+ "When non-nil, `ivy-next-action' and `ivy-prev-action' wrap."
+ :type 'boolean)
+
+(defun ivy-next-action ()
+ "When the current action is a list, scroll it forwards."
+ (interactive)
+ (let ((action (ivy-state-action ivy-last)))
+ (when (ivy--actionp action)
+ (let ((len (1- (length action)))
+ (idx (car action)))
+ (if (>= idx len)
+ (when ivy-action-wrap
+ (setf (car action) 1))
+ (cl-incf (car action)))))))
+
+(defun ivy-prev-action ()
+ "When the current action is a list, scroll it backwards."
+ (interactive)
+ (let ((action (ivy-state-action ivy-last)))
+ (when (ivy--actionp action)
+ (if (<= (car action) 1)
+ (when ivy-action-wrap
+ (setf (car action) (1- (length action))))
+ (cl-decf (car action))))))
+
+(defun ivy-action-name ()
+ "Return the name associated with the current action."
+ (let ((action (ivy-state-action ivy-last)))
+ (if (ivy--actionp action)
+ (format "[%d/%d] %s"
+ (car action)
+ (1- (length action))
+ (nth 2 (nth (car action) action)))
+ "[1/1] default")))
+
+(defvar ivy-inhibit-action nil
+ "When non-nil, `ivy-call' does nothing.
+
+Example use:
+
+ (let* ((ivy-inhibit-action t)
+ (str (ivy-switch-buffer)))
+ ;; do whatever with str - the corresponding buffer will not be opened
+ )")
+
+(defun ivy-recursive-restore ()
+ "Restore the above state when exiting the minibuffer.
+See variable `ivy-recursive-restore' for further information."
+ (when (and ivy-recursive-last
+ ivy-recursive-restore
+ (not (eq ivy-last ivy-recursive-last)))
+ (ivy--reset-state (setq ivy-last ivy-recursive-last))))
+
+(defvar ivy-mark-prefix ">"
+ "Prefix used by `ivy-mark'.")
+
+(defun ivy--call-marked (action)
+ (let* ((prefix-len (length ivy-mark-prefix))
+ (marked-candidates
+ (mapcar
+ (lambda (s)
+ (let ((cand (substring s prefix-len)))
+ (if ivy--directory
+ (expand-file-name cand ivy--directory)
+ cand)))
+ ivy-marked-candidates))
+ (multi-action (ivy--get-multi-action ivy-last)))
+ (if multi-action
+ (let ((default-directory (ivy-state-directory ivy-last)))
+ (funcall multi-action (mapcar #'ivy--call-cand marked-candidates)))
+ (dolist (c marked-candidates)
+ (let ((default-directory (ivy-state-directory ivy-last)))
+ (funcall action (ivy--call-cand c)))))))
+
+(defun ivy--call-cand (current)
+ (let ((collection (ivy-state-collection ivy-last)))
+ (cond
+ ;; Alist type.
+ ((and (consp (car-safe collection))
+ ;; Previously, the cdr of the selected
+ ;; candidate would be returned. Now, the
+ ;; whole candidate is returned.
+ (let ((idx (get-text-property 0 'idx current)))
+ (if idx
+ (progn
+ (ivy--remove-props current 'idx)
+ (nth idx collection))
+ (assoc current collection)))))
+ (ivy--directory
+ (expand-file-name current ivy--directory))
+ ((equal current "")
+ ivy-text)
+ (t
+ current))))
+
+(defun ivy-call ()
+ "Call the current action without exiting completion."
+ (interactive)
+ ;; Testing with `ivy-with' seems to call `ivy-call' again,
+ ;; in which case `this-command' is nil; so check for this.
+ (unless (memq this-command '(nil
+ ivy-done
+ ivy-alt-done
+ ivy-dispatching-done))
+ (setq ivy-current-prefix-arg current-prefix-arg))
+ (let* ((action
+ (if (functionp ivy-inhibit-action)
+ ivy-inhibit-action
+ (and (not ivy-inhibit-action)
+ (ivy--get-action ivy-last))))
+ (current (ivy-state-current ivy-last))
+ (x (ivy--call-cand current))
+ (res
+ (cond
+ ((null action)
+ current)
+ (t
+ (select-window (ivy--get-window ivy-last))
+ (set-buffer (ivy-state-buffer ivy-last))
+ (prog1 (unwind-protect
+ (if ivy-marked-candidates
+ (ivy--call-marked action)
+ (funcall action x))
+ (ivy-recursive-restore))
+ (unless (or (eq ivy-exit 'done)
+ (minibuffer-window-active-p (selected-window))
+ (null (active-minibuffer-window)))
+ (select-window (active-minibuffer-window))))))))
+ (if ivy-inhibit-action
+ res
+ current)))
+
+(defun ivy-call-and-recenter ()
+ "Call action and recenter window according to the selected candidate."
+ (interactive)
+ (ivy-call)
+ (with-ivy-window
+ (recenter-top-bottom)))
+
+(defun ivy-next-line-and-call (&optional arg)
+ "Move cursor vertically down ARG candidates.
+Call the permanent action if possible."
+ (interactive "p")
+ (ivy-next-line arg)
+ (ivy--exhibit)
+ (ivy-call))
+
+(defun ivy-previous-line-and-call (&optional arg)
+ "Move cursor vertically up ARG candidates.
+Call the permanent action if possible."
+ (interactive "p")
+ (ivy-previous-line arg)
+ (ivy--exhibit)
+ (ivy-call))
+
+(defun ivy-previous-history-element (arg)
+ "Forward to `previous-history-element' with ARG."
+ (interactive "p")
+ (previous-history-element arg)
+ (ivy--cd-maybe)
+ (move-end-of-line 1)
+ (ivy--maybe-scroll-history))
+
+(defun ivy--insert-symbol-boundaries ()
+ (undo-boundary)
+ (beginning-of-line)
+ (insert "\\_<")
+ (end-of-line)
+ (insert "\\_>"))
+
+(defun ivy-next-history-element (arg)
+ "Forward to `next-history-element' with ARG."
+ (interactive "p")
+ (if (and (= minibuffer-history-position 0)
+ (equal ivy-text ""))
+ (progn
+ (when minibuffer-default
+ (setq ivy--default (car minibuffer-default)))
+ (insert ivy--default)
+ (when (and (with-ivy-window (derived-mode-p 'prog-mode))
+ (eq (ivy-state-caller ivy-last) 'swiper)
+ (not (file-exists-p ivy--default))
+ (not (ivy-ffap-url-p ivy--default))
+ (not (ivy-state-dynamic-collection ivy-last))
+ (> (point) (minibuffer-prompt-end)))
+ (ivy--insert-symbol-boundaries)))
+ (next-history-element arg))
+ (ivy--cd-maybe)
+ (move-end-of-line 1)
+ (ivy--maybe-scroll-history))
+
+(defvar ivy-ffap-url-functions nil
+ "List of functions that check if the point is on a URL.")
+
+(defun ivy--cd-maybe ()
+ "Check if the current input points to a different directory.
+If so, move to that directory, while keeping only the file name."
+ (when ivy--directory
+ (let ((input (ivy--input))
+ url)
+ (if (setq url (or (ivy-ffap-url-p input)
+ (with-ivy-window
+ (cl-reduce
+ (lambda (a b)
+ (or a (funcall b)))
+ ivy-ffap-url-functions
+ :initial-value nil))))
+ (ivy-exit-with-action
+ (lambda (_)
+ (ivy-ffap-url-fetcher url))
+ 'no-update-history)
+ (setq input (expand-file-name input))
+ (let ((file (file-name-nondirectory input))
+ (dir (expand-file-name (file-name-directory input))))
+ (if (string= dir ivy--directory)
+ (progn
+ (delete-minibuffer-contents)
+ (insert file))
+ (ivy--cd dir)
+ (insert file)))))))
+
+(defun ivy--maybe-scroll-history ()
+ "If the selected history element has an index, scroll there."
+ (let ((idx (ignore-errors
+ (get-text-property
+ (minibuffer-prompt-end)
+ 'ivy-index))))
+ (when idx
+ (ivy--exhibit)
+ (ivy-set-index idx))))
+
+(declare-function tramp-get-completion-methods "tramp")
+
+(defun ivy--cd (dir)
+ "When completing file names, move to directory DIR."
+ (if (ivy--completing-fname-p)
+ (progn
+ (push dir ivy--directory-hist)
+ (setq ivy--old-cands nil)
+ (setq ivy--old-re nil)
+ (ivy-set-index 0)
+ (setq ivy--all-candidates
+ (append
+ (ivy--sorted-files (setq ivy--directory dir))
+ (when (and (string= dir "/") (featurep 'tramp))
+ (sort
+ (mapcar
+ (lambda (s) (substring s 1))
+ (tramp-get-completion-methods ""))
+ #'string<))))
+ (ivy-set-text "")
+ (setf (ivy-state-directory ivy-last) dir)
+ (delete-minibuffer-contents))
+ (error "Unexpected")))
+
+(defun ivy--parent-dir (filename)
+ "Return parent directory of absolute FILENAME."
+ (file-name-directory (directory-file-name filename)))
+
+(defun ivy-backward-delete-char ()
+ "Forward to `delete-backward-char'.
+Call `ivy-on-del-error-function' if an error occurs, usually when
+there is no more text to delete at the beginning of the
+minibuffer."
+ (interactive)
+ (if (and ivy--directory (= (minibuffer-prompt-end) (point)))
+ (progn
+ (ivy--cd (ivy--parent-dir (expand-file-name ivy--directory)))
+ (ivy--exhibit))
+ (setq prefix-arg current-prefix-arg)
+ (condition-case nil
+ (call-interactively #'delete-backward-char)
+ (error
+ (when ivy-on-del-error-function
+ (funcall ivy-on-del-error-function))))))
+
+(defun ivy-delete-char (arg)
+ "Forward to `delete-char' ARG."
+ (interactive "p")
+ (unless (eolp)
+ (delete-char arg)))
+
+(defun ivy-forward-char (arg)
+ "Forward to `forward-char' ARG."
+ (interactive "p")
+ (unless (eolp)
+ (forward-char arg)))
+
+(defun ivy-kill-word (arg)
+ "Forward to `kill-word' ARG."
+ (interactive "p")
+ (unless (eolp)
+ (kill-word arg)))
+
+(defun ivy-kill-line ()
+ "Forward to `kill-line'."
+ (interactive)
+ (if (eolp)
+ (progn
+ (kill-region (minibuffer-prompt-end) (point))
+ (setq ivy--old-text (current-kill 0 t)))
+ (kill-line)))
+
+(defun ivy-kill-whole-line ()
+ "Forward to `kill-whole-line'."
+ (interactive)
+ (kill-region (minibuffer-prompt-end) (line-end-position)))
+
+(defun ivy-backward-kill-word ()
+ "Forward to `backward-kill-word'."
+ (interactive)
+ (if (and ivy--directory (= (minibuffer-prompt-end) (point)))
+ (progn
+ (ivy--cd (ivy--parent-dir (expand-file-name ivy--directory)))
+ (ivy--exhibit))
+ (ignore-errors
+ (let ((pt (point))
+ (last-command (if (eq last-command 'ivy-backward-kill-word)
+ 'kill-region
+ last-command)))
+ (forward-word -1)
+ (kill-region pt (point))))))
+
+(defvar ivy--regexp-quote #'regexp-quote
+ "Store the regexp quoting state.")
+
+(defun ivy-toggle-regexp-quote ()
+ "Toggle the regexp quoting."
+ (interactive)
+ (setq ivy--old-re nil)
+ (cl-rotatef ivy--regex-function ivy--regexp-quote)
+ (setq ivy--old-text "")
+ (setq ivy-regex (funcall ivy--regex-function ivy-text)))
+
+(defcustom ivy-format-functions-alist
+ '((t . ivy-format-function-default))
+ "An alist of functions that transform the list of candidates into a string.
+This string is inserted into the minibuffer."
+ :type '(alist
+ :key-type symbol
+ :value-type
+ (choice
+ (const :tag "Default" ivy-format-function-default)
+ (const :tag "Arrow prefix" ivy-format-function-arrow)
+ (const :tag "Full line" ivy-format-function-line)
+ (const :tag "Arrow prefix + full line"
+ ivy-format-function-arrow-line)
+ (function :tag "Custom function"))))
+
+(defun ivy-sort-file-function-default (x y)
+ "Compare two files X and Y.
+Prioritize directories."
+ (if (get-text-property 0 'dirp x)
+ (if (get-text-property 0 'dirp y)
+ (string< (directory-file-name x) (directory-file-name y))
+ t)
+ (if (get-text-property 0 'dirp y)
+ nil
+ (string< x y))))
+
+(defun ivy-string< (x y)
+ "Like `string<', but operate on CARs when given cons cells."
+ (string< (if (consp x) (car x) x)
+ (if (consp y) (car y) y)))
+
+(define-obsolete-function-alias 'ivy-sort-file-function-using-ido
+ 'ido-file-extension-lessp "<2019-10-12 Sat>")
+
+(defcustom ivy-sort-functions-alist
+ '((t . ivy-string<))
+ "An alist of sorting functions for each collection function.
+Interactive functions that call completion fit in here as well.
+
+Nil means no sorting, which is useful to turn off the sorting for
+functions that have candidates in the natural buffer order, like
+`org-refile' or `Man-goto-section'.
+
+A list can be used to associate multiple sorting functions with a
+collection. The car of the list is the current sort
+function. This list can be rotated with `ivy-rotate-sort'.
+
+The entry associated with t is used for all fall-through cases.
+
+See also `ivy-sort-max-size'."
+ :type
+ '(alist
+ :key-type (choice
+ (const :tag "Fall-through" t)
+ (symbol :tag "Collection"))
+ :value-type (choice
+ (const :tag "Plain sort" ivy-string<)
+ (const :tag "File sort" ivy-sort-file-function-default)
+ (const :tag "File sort using Ido" ido-file-extension-lessp)
+ (const :tag "No sort" nil)
+ (function :tag "Custom function")
+ (repeat (function :tag "Custom function")))))
+
+(defun ivy--sort-function (collection)
+ "Retrieve sort function for COLLECTION from `ivy-sort-functions-alist'."
+ (let ((entry (cdr (or (assq collection ivy-sort-functions-alist)
+ (assq (ivy-state-caller ivy-last) ivy-sort-functions-alist)
+ (assq t ivy-sort-functions-alist)))))
+ (and (or (functionp entry)
+ (functionp (setq entry (car-safe entry))))
+ entry)))
+
+(defun ivy-rotate-sort ()
+ "Rotate through sorting functions available for current collection.
+This only has an effect if multiple sorting functions are
+specified for the current collection in
+`ivy-sort-functions-alist'."
+ (interactive)
+ (let ((cell (or (assq (ivy-state-collection ivy-last) ivy-sort-functions-alist)
+ (assq (ivy-state-caller ivy-last) ivy-sort-functions-alist)
+ (assq t ivy-sort-functions-alist))))
+ (when (consp (cdr cell))
+ (setcdr cell (nconc (cddr cell) (list (cadr cell))))
+ (ivy--reset-state ivy-last))))
+
+(defcustom ivy-index-functions-alist
+ '((t . ivy-recompute-index-zero))
+ "An alist of index recomputing functions for each collection function.
+When the input changes, the appropriate function returns an
+integer - the index of the matched candidate that should be
+selected."
+ :type '(alist :key-type symbol :value-type function))
+
+(defvar ivy-re-builders-alist
+ '((t . ivy--regex-plus))
+ "An alist of regex building functions for each collection function.
+
+Each key is (in order of priority):
+1. The actual collection function, e.g. `read-file-name-internal'.
+2. The symbol passed by :caller into `ivy-read'.
+3. `this-command'.
+4. t.
+
+Each value is a function that should take a string and return a
+valid regex or a regex sequence (see below).
+
+Possible choices: `ivy--regex', `regexp-quote',
+`ivy--regex-plus', `ivy--regex-fuzzy', `ivy--regex-ignore-order'.
+
+If a function returns a list, it should format like this:
+'((\"matching-regexp\" . t) (\"non-matching-regexp\") ...).
+
+The matches will be filtered in a sequence, you can mix the
+regexps that should match and that should not match as you
+like.")
+
+(defvar ivy-highlight-functions-alist
+ '((ivy--regex-ignore-order . ivy--highlight-ignore-order)
+ (ivy--regex-fuzzy . ivy--highlight-fuzzy)
+ (ivy--regex-plus . ivy--highlight-default))
+ "An alist of highlighting functions for each regex builder function.")
+
+(defcustom ivy-initial-inputs-alist
+ '((org-refile . "^")
+ (org-agenda-refile . "^")
+ (org-capture-refile . "^")
+ (Man-completion-table . "^")
+ (woman . "^"))
+ "An alist associating commands with their initial input.
+
+Each cdr is either a string or a function called in the context
+of a call to `ivy-read'."
+ :type '(alist
+ :key-type (symbol)
+ :value-type (choice (string) (function))))
+
+(defcustom ivy-hooks-alist nil
+ "An alist associating commands to setup functions.
+Examples: `toggle-input-method', (lambda () (insert \"^\")), etc.
+May supersede `ivy-initial-inputs-alist'."
+ :type '(alist :key-type symbol :value-type function))
+
+(defvar ivy--occurs-list nil
+ "A list of custom occur generators per command.")
+
+(defun ivy-set-occur (cmd occur)
+ "Assign CMD a custom OCCUR function."
+ (setq ivy--occurs-list
+ (plist-put ivy--occurs-list cmd occur)))
+
+(defcustom ivy-update-fns-alist nil
+ "An alist associating commands to their :update-fn values."
+ :type '(alist
+ :key-type symbol
+ :value-type
+ (radio
+ (const :tag "Off" nil)
+ (const :tag "Call action on change" auto))))
+
+(defcustom ivy-unwind-fns-alist nil
+ "An alist associating commands to their :unwind values."
+ :type '(alist :key-type symbol :value-type function))
+
+(defcustom ivy-init-fns-alist nil
+ "An alist associating commands to their :init values.
+An :init is a function with no arguments.
+`ivy-read' calls it to initialize."
+ :type '(alist :key-type symbol :value-type function))
+
+(defun ivy--alist-set (alist-sym key val)
+ (let ((curr-val (symbol-value alist-sym))
+ (customized-val (get alist-sym 'customized-value))
+ (default-val (eval (car (get alist-sym 'standard-value)))))
+ ;; when the value was set by `customize-set-variable', don't touch it
+ (unless customized-val
+ ;; only works if the value wasn't customized by the user
+ (when (or (null default-val) (equal curr-val default-val))
+ (let ((cell (assoc key curr-val)))
+ (if cell
+ (setcdr cell val)
+ (set alist-sym (cons (cons key val)
+ (symbol-value alist-sym)))))
+ (when default-val
+ (put alist-sym 'standard-value
+ (list (list 'quote (symbol-value alist-sym)))))))))
+
+(declare-function counsel-set-async-exit-code "counsel")
+
+(defvar ivy--parents-alist nil
+ "Configure parent caller for child caller.
+The child caller inherits and can override the settings of the parent.")
+
+(cl-defun ivy-configure (caller
+ &key
+ parent
+ initial-input
+ height
+ occur
+ update-fn
+ init-fn
+ unwind-fn
+ index-fn
+ sort-fn
+ sort-matches-fn
+ format-fn
+ display-fn
+ display-transformer-fn
+ alt-done-fn
+ more-chars
+ grep-p
+ exit-codes)
+ "Configure `ivy-read' params for CALLER."
+ (declare (indent 1))
+ (when parent
+ (ivy--alist-set 'ivy--parents-alist caller parent))
+ (when initial-input
+ (ivy--alist-set 'ivy-initial-inputs-alist caller initial-input))
+ (when height
+ (ivy--alist-set 'ivy-height-alist caller height))
+ (when occur
+ (ivy-set-occur caller occur))
+ (when update-fn
+ (ivy--alist-set 'ivy-update-fns-alist caller update-fn))
+ (when unwind-fn
+ (ivy--alist-set 'ivy-unwind-fns-alist caller unwind-fn))
+ (when init-fn
+ (ivy--alist-set 'ivy-init-fns-alist caller init-fn))
+ (when index-fn
+ (ivy--alist-set 'ivy-index-functions-alist caller index-fn))
+ (when sort-fn
+ (ivy--alist-set 'ivy-sort-functions-alist caller sort-fn))
+ (when sort-matches-fn
+ (ivy--alist-set 'ivy-sort-matches-functions-alist caller sort-matches-fn))
+ (when format-fn
+ (ivy--alist-set 'ivy-format-functions-alist caller format-fn))
+ (when display-fn
+ (ivy--alist-set 'ivy-display-functions-alist caller display-fn))
+ (when display-transformer-fn
+ (ivy--alist-set 'ivy--display-transformers-alist caller display-transformer-fn))
+ (when alt-done-fn
+ (ivy--alist-set 'ivy-alt-done-functions-alist caller alt-done-fn))
+ (when more-chars
+ (ivy--alist-set 'ivy-more-chars-alist caller more-chars))
+ (when grep-p
+ (cl-pushnew caller ivy-highlight-grep-commands))
+ (when exit-codes
+ (let (code msg)
+ (while (and (setq code (pop exit-codes))
+ (setq msg (pop exit-codes)))
+ (counsel-set-async-exit-code caller code msg)))))
+
+(defcustom ivy-sort-max-size 30000
+ "Sorting won't be done for collections larger than this."
+ :type 'integer)
+
+(defalias 'ivy--dirname-p
+ ;; Added in Emacs 25.1.
+ (if (fboundp 'directory-name-p)
+ #'directory-name-p
+ (lambda (name)
+ "Return non-nil if NAME ends with a directory separator."
+ (string-suffix-p "/" name))))
+
+(defun ivy--sorted-files (dir)
+ "Return the list of files in DIR.
+Directories come first."
+ (let* ((default-directory dir)
+ (seq (condition-case nil
+ (mapcar (lambda (s) (replace-regexp-in-string "\\$\\$" "$" s))
+ (all-completions "" #'read-file-name-internal
+ (ivy-state-predicate ivy-last)))
+ (error
+ (directory-files dir))))
+ sort-fn)
+ (setq seq (delete "./" (delete "../" seq)))
+ (when (eq (setq sort-fn (ivy--sort-function #'read-file-name-internal))
+ #'ivy-sort-file-function-default)
+ (setq seq (mapcar (lambda (x)
+ (propertize x 'dirp (ivy--dirname-p x)))
+ seq)))
+ (when sort-fn
+ (setq seq (sort seq sort-fn)))
+ (dolist (dir ivy-extra-directories)
+ (push dir seq))
+ (if (string= dir "/")
+ (cl-remove-if (lambda (s) (string-match ":$" s)) (delete "../" seq))
+ seq)))
+
+(defun ivy-alist-setting (alist &optional key)
+ "Return the value associated with KEY in ALIST, using `assq'.
+KEY defaults to the last caller of `ivy-read'; if no entry is
+found, it falls back to the key t."
+ (let ((caller (or key (ivy-state-caller ivy-last))))
+ (or
+ (and caller (cdr (assq caller alist)))
+ (let ((parent (cdr (assq caller ivy--parents-alist))))
+ (when parent
+ (ivy-alist-setting alist parent)))
+ (cdr (assq t alist)))))
+
+(defun ivy--height (caller)
+ (let ((v (or (ivy-alist-setting ivy-height-alist caller)
+ ivy-height)))
+ (if (integerp v)
+ v
+ (if (functionp v)
+ (funcall v caller)
+ (error "Unexpected value: %S" v)))))
+
+(defun ivy--remove-props (str &rest props)
+ "Return STR with text PROPS destructively removed."
+ (ignore-errors
+ (remove-list-of-text-properties 0 (length str) props str))
+ str)
+
+(defun ivy--update-prompt (prompt)
+ (cond ((equal prompt "Keyword, C-h: ")
+ ;; auto-insert.el
+ "Keyword (C-M-j to end): ")
+ (t
+ ;; misearch.el
+ (replace-regexp-in-string "RET to end" "C-M-j to end" prompt))))
+
+;;** Entry Point
+;;;###autoload
+(cl-defun ivy-read (prompt collection
+ &key
+ predicate require-match initial-input
+ history preselect def keymap update-fn sort
+ action multi-action
+ unwind re-builder matcher
+ dynamic-collection
+ extra-props
+ caller)
+ "Read a string in the minibuffer, with completion.
+
+PROMPT is a string, normally ending in a colon and a space.
+`ivy-count-format' is prepended to PROMPT during completion.
+
+COLLECTION is either a list of strings, a function, an alist, or
+a hash table, supplied for `minibuffer-completion-table'.
+
+PREDICATE is applied to filter out the COLLECTION immediately.
+This argument is for compatibility with `completing-read'.
+
+When REQUIRE-MATCH is non-nil, only members of COLLECTION can be
+selected. In can also be a lambda.
+
+If INITIAL-INPUT is non-nil, then insert that input in the
+minibuffer initially.
+
+HISTORY is a name of a variable to hold the completion session
+history.
+
+KEYMAP is composed with `ivy-minibuffer-map'.
+
+PRESELECT, when non-nil, determines which one of the candidates
+matching INITIAL-INPUT to select initially. An integer stands
+for the position of the desired candidate in the collection,
+counting from zero. Otherwise, use the first occurrence of
+PRESELECT in the collection. Comparison is first done with
+`equal'. If that fails, and when applicable, match PRESELECT as
+a regular expression.
+
+DEF is for compatibility with `completing-read'.
+
+UPDATE-FN is called each time the candidate list is re-displayed.
+
+When SORT is non-nil, `ivy-sort-functions-alist' determines how
+to sort candidates before displaying them.
+
+ACTION is a function to call after selecting a candidate.
+It takes one argument, the selected candidate. If COLLECTION is
+an alist, the argument is a cons cell, otherwise it's a string.
+
+MULTI-ACTION, when non-nil, is called instead of ACTION when
+there are marked candidates. It takes the list of candidates as
+its only argument. When it's nil, ACTION is called on each marked
+candidate.
+
+UNWIND is a function of no arguments to call before exiting.
+
+RE-BUILDER is a function transforming input text into a regex
+pattern.
+
+MATCHER is a function which can override how candidates are
+filtered based on user input. It takes a regex pattern and a
+list of candidates, and returns the list of matching candidates.
+
+DYNAMIC-COLLECTION is a boolean specifying whether the list of
+candidates is updated after each input by calling COLLECTION.
+
+EXTRA-PROPS is a plist that can be used to store
+collection-specific session-specific data.
+
+CALLER is a symbol to uniquely identify the caller to `ivy-read'.
+It is used, along with COLLECTION, to determine which
+customizations apply to the current completion session."
+ (let ((init-fn (ivy-alist-setting ivy-init-fns-alist caller)))
+ (when init-fn
+ (funcall init-fn)))
+ ;; get un-stuck from an existing `read-key' overriding minibuffer keys
+ (when (equal overriding-local-map '(keymap))
+ (keyboard-quit))
+ (setq caller (or caller this-command))
+ (let* ((ivy-recursive-last (and (active-minibuffer-window) ivy-last))
+ (ivy--display-function
+ (when (or ivy-recursive-last
+ (not (window-minibuffer-p)))
+ (ivy-alist-setting ivy-display-functions-alist caller))))
+ (setq update-fn (or update-fn (ivy-alist-setting ivy-update-fns-alist caller)))
+ (setq unwind (or unwind (ivy-alist-setting ivy-unwind-fns-alist caller)))
+ (setq ivy-last
+ (make-ivy-state
+ :prompt (ivy--update-prompt prompt)
+ :collection collection
+ :predicate predicate
+ :require-match require-match
+ :initial-input initial-input
+ :history history
+ :preselect preselect
+ :keymap keymap
+ :update-fn (if (eq update-fn 'auto)
+ (lambda ()
+ (with-ivy-window
+ (funcall
+ (ivy--get-action ivy-last)
+ (if (consp (car-safe (ivy-state-collection ivy-last)))
+ (assoc (ivy-state-current ivy-last)
+ (ivy-state-collection ivy-last))
+ (ivy-state-current ivy-last)))))
+ update-fn)
+ :sort sort
+ :action (ivy--compute-extra-actions action caller)
+ :multi-action multi-action
+ :frame (selected-frame)
+ :window (selected-window)
+ :buffer (current-buffer)
+ :unwind unwind
+ :re-builder re-builder
+ :matcher matcher
+ :dynamic-collection dynamic-collection
+ :display-transformer-fn (ivy-alist-setting ivy--display-transformers-alist caller)
+ :directory default-directory
+ :extra-props extra-props
+ :caller caller
+ :def def))
+ (ivy--reset-state ivy-last)
+ (unwind-protect
+ (minibuffer-with-setup-hook
+ #'ivy--minibuffer-setup
+ (let* ((hist (or history 'ivy-history))
+ (minibuffer-completion-table collection)
+ (minibuffer-completion-predicate predicate)
+ (ivy-height (ivy--height caller))
+ (resize-mini-windows (unless (display-graphic-p)
+ 'grow-only)))
+ (if (and ivy-auto-select-single-candidate
+ ivy--all-candidates
+ (null (cdr ivy--all-candidates)))
+ (progn
+ (setf (ivy-state-current ivy-last)
+ (car ivy--all-candidates))
+ (setq ivy-exit 'done))
+ (condition-case err
+ (read-from-minibuffer
+ prompt
+ (ivy-state-initial-input ivy-last)
+ (make-composed-keymap keymap ivy-minibuffer-map)
+ nil
+ hist)
+ (error
+ (unless (equal err '(error "Selecting deleted buffer"))
+ (signal (car err) (cdr err))))))
+ (when (eq ivy-exit 'done)
+ (ivy--update-history hist))))
+ (let ((session (or (plist-get extra-props :session)
+ (unless (or (minibufferp)
+ (null (ivy-state-action ivy-last))
+ (eq (ivy--get-action ivy-last) #'identity))
+ caller))))
+ (when session
+ (setf (ivy-state-extra-props ivy-last)
+ (plist-put extra-props :ivy-data `(:all-candidates ,ivy--all-candidates
+ :text ,ivy-text)))
+ (ivy--alist-set 'ivy--sessions session ivy-last)))
+ (ivy--cleanup))
+ (ivy-call)))
+
+(defun ivy--update-history (hist)
+ (unless (eq hist t)
+ (let ((item
+ (if (or (string= ivy-text "")
+ (eq (plist-get (ivy-state-extra-props ivy-last) :caller)
+ #'ivy-completing-read)
+ (eq (ivy-state-history ivy-last) 'file-name-history))
+ (ivy-state-current ivy-last)
+ ivy-text)))
+ (cond ((equal item ""))
+ ((stringp item)
+ (set hist (cons (propertize item 'ivy-index ivy--index)
+ (delete item (symbol-value hist)))))))))
+
+(defun ivy--cleanup ()
+ ;; Fixes a bug in ESS, #1660
+ (put 'post-command-hook 'permanent-local nil)
+ (remove-hook 'post-command-hook #'ivy--queue-exhibit)
+ (remove-hook 'window-size-change-functions #'ivy--window-size-changed)
+ (let ((cleanup (ivy--display-function-prop :cleanup))
+ (unwind (ivy-state-unwind ivy-last)))
+ (when (functionp cleanup)
+ (funcall cleanup))
+ (when unwind
+ (funcall unwind)))
+ (ivy--pulse-cleanup)
+ (unless (eq ivy-exit 'done)
+ (ivy-recursive-restore)))
+
+(defun ivy--display-function-prop (prop)
+ "Return PROP associated with current `ivy--display-function'."
+ (plist-get (cdr (assq ivy--display-function
+ ivy-display-functions-props))
+ prop))
+
+(defvar Info-complete-menu-buffer)
+
+(defun ivy--alist-to-cands (alist)
+ "Transform ALIST to a list of strings."
+ (let ((i -1))
+ (mapcar (lambda (x)
+ (propertize x 'idx (cl-incf i)))
+ (all-completions "" alist))))
+
+(defvar ivy--minibuffer-metadata nil
+ "Store `completion-metadata'.")
+
+(defun ivy--reset-state (state)
+ "Reset the ivy to STATE.
+This is useful for recursive `ivy-read'."
+ (setq ivy-marked-candidates nil)
+ (setq ivy--minibuffer-metadata nil)
+ (unless (equal (selected-frame) (ivy-state-frame state))
+ (select-window (active-minibuffer-window)))
+ (let* ((prompt (or (ivy-state-prompt state) ""))
+ (collection (ivy-state-collection state))
+ (predicate (ivy-state-predicate state))
+ (history (ivy-state-history state))
+ (preselect (ivy-state-preselect state))
+ (re-builder (ivy-state-re-builder state))
+ (dynamic-collection (ivy-state-dynamic-collection state))
+ (require-match (ivy-state-require-match state))
+ (caller (or (ivy-state-caller state) this-command))
+ (sort (or (ivy-state-sort state) (assoc caller ivy-sort-functions-alist)))
+ (initial-input
+ (or (ivy-state-initial-input state)
+ (let ((init (ivy-alist-setting ivy-initial-inputs-alist caller)))
+ (if (functionp init) (funcall init) init))))
+ (def (ivy-state-def state)))
+ (when (and (eq caller 'swiper-isearch) (buffer-modified-p))
+ (setq preselect nil))
+ (setq ivy--extra-candidates (ivy--compute-extra-candidates caller))
+ (setq ivy--directory nil)
+ (setq ivy--directory-hist (list default-directory))
+ (setq ivy-case-fold-search ivy-case-fold-search-default)
+ (setf (ivy-state-re-builder ivy-last)
+ (setq ivy--regex-function
+ (or re-builder
+ (and (functionp collection)
+ (cdr (assq collection ivy-re-builders-alist)))
+ (ivy-alist-setting ivy-re-builders-alist)
+ #'ivy--regex)))
+ (setq ivy--subexps 0)
+ (setq ivy--regexp-quote #'regexp-quote)
+ (setq ivy--old-text "")
+ (setq ivy--full-length nil)
+ (ivy-set-text (or initial-input ""))
+ (setq ivy--index 0)
+ (setq ivy-calling nil)
+ (setq ivy-use-ignore ivy-use-ignore-default)
+ (setf (ivy-state-ignore state) ivy-use-ignore)
+ (setq ivy--highlight-function
+ (or (cdr (assq (ivy-alist-setting ivy-re-builders-alist)
+ ivy-highlight-functions-alist))
+ #'ivy--highlight-default))
+ (let ((ivy-recursive-restore nil)
+ coll sort-fn)
+ (cond ((eq collection #'Info-read-node-name-1)
+ (setq coll
+ (if (equal (bound-and-true-p Info-current-file) "dir")
+ (mapcar (lambda (x) (format "(%s)" x))
+ (delete-dups
+ (all-completions "(" collection predicate)))
+ (all-completions "" collection predicate))))
+ ((memq collection '(read-file-name-internal ffap-read-file-or-url-internal))
+ (require 'tramp)
+ (when (and (equal def initial-input)
+ (member "./" ivy-extra-directories))
+ (setq def nil))
+ (setq ivy--directory default-directory)
+ (when (and initial-input
+ (not (equal initial-input "")))
+ (cond ((file-directory-p initial-input)
+ (when (equal (file-name-nondirectory initial-input) "")
+ (setf (ivy-state-preselect state) (setq preselect nil))
+ (setq def nil))
+ (setq ivy--directory (file-name-as-directory initial-input))
+ (setq initial-input nil)
+ (when preselect
+ (let ((preselect-directory
+ (file-name-directory preselect)))
+ (when (and preselect-directory
+ (not (equal
+ (expand-file-name
+ preselect-directory)
+ (expand-file-name ivy--directory))))
+ (setf (ivy-state-preselect state)
+ (setq preselect nil))))))
+ ((ignore-errors
+ (file-exists-p (file-name-directory initial-input)))
+ (setq ivy--directory (file-name-directory initial-input))
+ (setf (ivy-state-preselect state)
+ (file-name-nondirectory initial-input)))))
+ (require 'dired)
+ (when preselect
+ (let ((preselect-directory (ivy--parent-dir preselect)))
+ (when (and preselect-directory
+ (not (string= preselect-directory
+ default-directory)))
+ (setq ivy--directory preselect-directory))
+ (setq preselect (file-relative-name preselect
+ preselect-directory))
+ (setf (ivy-state-preselect state) preselect)))
+ (setq sort nil)
+ (setq coll (ivy--sorted-files ivy--directory))
+ (when initial-input
+ (unless (or require-match
+ (equal initial-input default-directory)
+ (equal initial-input ""))
+ (setq coll (cons initial-input coll)))
+ (setq initial-input (file-name-nondirectory initial-input))))
+ ((eq collection #'internal-complete-buffer)
+ (setq coll (ivy--buffer-list
+ ""
+ (and ivy-use-virtual-buffers
+ (member caller '(ivy-switch-buffer
+ ivy-switch-buffer-other-window
+ counsel-switch-buffer)))
+ predicate)))
+ (dynamic-collection
+ (setq ivy--minibuffer-metadata
+ (ignore-errors
+ (completion-metadata
+ ""
+ (ivy-state-collection ivy-last)
+ (ivy-state-predicate ivy-last))))
+ (setq coll (if (and (eq this-command 'ivy-resume) (not (buffer-modified-p)))
+ ivy--all-candidates
+ (ivy--dynamic-collection-cands (or initial-input "")))))
+ ((consp (car-safe collection))
+ (setq collection (cl-remove-if-not predicate collection))
+ (when (and sort (setq sort-fn (ivy--sort-function caller)))
+ (setq collection (sort (copy-sequence collection) sort-fn))
+ (setq sort nil))
+ (setf (ivy-state-collection ivy-last) collection)
+ (setq coll (ivy--alist-to-cands collection)))
+ ((or (functionp collection)
+ (byte-code-function-p collection)
+ (vectorp collection)
+ (hash-table-p collection)
+ (and (listp collection) (symbolp (car collection))))
+ (let ((Info-complete-menu-buffer
+ ;; FIXME: This is a temporary workaround for issue #1803.
+ (or (bound-and-true-p Info-complete-menu-buffer)
+ (ivy-state-buffer state))))
+ (setq coll (all-completions "" collection predicate))))
+ (t
+ (setq coll (all-completions "" collection predicate))))
+ (unless (ivy-state-dynamic-collection ivy-last)
+ (setq coll (delete "" coll)))
+ (when (and sort
+ (or (functionp collection)
+ (not (eq history 'org-refile-history)))
+ (setq sort-fn (ivy--sort-function
+ (if (functionp collection) collection caller)))
+ (listp coll)
+ (null (nthcdr ivy-sort-max-size coll)))
+ (setq coll (sort (copy-sequence coll) sort-fn)))
+ (when def
+ (cond ((stringp (car-safe def))
+ (setq coll
+ (delete-dups
+ (append def coll))))
+ ((and (stringp def) (not (member def coll)))
+ (push def coll))))
+ (setq coll (ivy--set-candidates coll))
+ (setq ivy--old-re nil)
+ (setq ivy--old-cands nil)
+ (when initial-input
+ ;; Needed for anchor to work
+ (setq ivy--old-cands coll)
+ (setq ivy--old-cands (ivy--filter initial-input coll)))
+ (unless (setq ivy--trying-to-resume-dynamic-collection
+ (and preselect dynamic-collection))
+ (when (integerp preselect)
+ (setq ivy--old-re "")
+ (ivy-set-index preselect)))
+ (setq ivy--all-candidates coll)
+ (unless (integerp preselect)
+ (ivy-set-index (or
+ (and dynamic-collection
+ ivy--index)
+ (and preselect
+ (ivy--preselect-index
+ preselect
+ (if initial-input
+ ivy--old-cands
+ coll)))
+ 0))))
+ (setq ivy-exit nil)
+ (setq ivy--default
+ (if (region-active-p)
+ (buffer-substring (region-beginning) (region-end))
+ (ivy-thing-at-point)))
+ (setq ivy--prompt (ivy-add-prompt-count (ivy--quote-format-string prompt)))
+ (setq ivy--use-selectable-prompt (ivy--prompt-selectable-p))
+ (setf (ivy-state-initial-input ivy-last) initial-input)))
+
+(defun ivy-add-prompt-count (prompt)
+ "Add count information to PROMPT."
+ (cond ((null ivy-count-format)
+ (error "`ivy-count-format' must not be nil; set it to \"\" instead"))
+ ((string-match "%d.*\\(%d\\)" ivy-count-format)
+ (let* ((w
+ (if (listp ivy--all-candidates)
+ (1+ (floor (log (max 1 (length ivy--all-candidates)) 10)))
+ 1))
+ (s (replace-match (format "%%-%dd" w) t t ivy-count-format 1)))
+ (string-match "%d" s)
+ (concat (replace-match (format "%%%dd" w) t t s)
+ prompt)))
+ ((string-match-p "%.*d" ivy-count-format)
+ (concat ivy-count-format prompt))
+ (t
+ prompt)))
+
+(defun ivy--quote-format-string (str)
+ "Make STR suitable for `format' with no extra arguments."
+ (replace-regexp-in-string "%" "%%" str t t))
+
+;;;###autoload
+(defun ivy-completing-read (prompt collection
+ &optional predicate require-match initial-input
+ history def inherit-input-method)
+ "Read a string in the minibuffer, with completion.
+
+This interface conforms to `completing-read' and can be used for
+`completing-read-function'.
+
+PROMPT is a string that normally ends in a colon and a space.
+COLLECTION is either a list of strings, an alist, an obarray, or a hash table.
+PREDICATE limits completion to a subset of COLLECTION.
+REQUIRE-MATCH is a boolean value or a symbol. See `completing-read'.
+INITIAL-INPUT is a string inserted into the minibuffer initially.
+HISTORY is a list of previously selected inputs.
+DEF is the default value.
+INHERIT-INPUT-METHOD is currently ignored."
+ (let ((handler
+ (and (< ivy-completing-read-ignore-handlers-depth (minibuffer-depth))
+ (assq this-command ivy-completing-read-handlers-alist))))
+ (if handler
+ (let ((completion-in-region-function #'completion--in-region)
+ (ivy-completing-read-ignore-handlers-depth (1+ (minibuffer-depth))))
+ (funcall (cdr handler)
+ prompt collection
+ predicate require-match
+ initial-input history
+ def inherit-input-method))
+ ;; See the doc of `completing-read'.
+ (when (consp history)
+ (when (numberp (cdr history))
+ (setq initial-input (nth (1- (cdr history))
+ (symbol-value (car history)))))
+ (setq history (car history)))
+ (when (consp def)
+ (setq def (car def)))
+ (let ((str (ivy-read
+ prompt collection
+ :predicate predicate
+ :require-match (when (and collection require-match)
+ require-match)
+ :initial-input (cond ((consp initial-input)
+ (car initial-input))
+ ((and (stringp initial-input)
+ (not (eq collection #'read-file-name-internal))
+ (string-match-p "\\+" initial-input))
+ (replace-regexp-in-string
+ "\\+" "\\\\+" initial-input))
+ (t
+ initial-input))
+ :preselect def
+ :def def
+ :history history
+ :keymap nil
+ :dynamic-collection ivy-completing-read-dynamic-collection
+ :extra-props '(:caller ivy-completing-read)
+ :caller (if (and collection (symbolp collection))
+ collection
+ this-command))))
+ (if (string= str "")
+ ;; For `completing-read' compat, return the first element of
+ ;; DEFAULT, if it is a list; "", if DEFAULT is nil; or DEFAULT.
+ (or def "")
+ str)))))
+
+(defun ivy-completing-read-with-empty-string-def
+ (prompt collection
+ &optional predicate require-match initial-input
+ history def inherit-input-method)
+ "Same as `ivy-completing-read' but with different handling of DEF.
+
+Specifically, if DEF is nil, it is treated the same as if DEF was
+the empty string. This mimics the behavior of
+`completing-read-default'. This function can therefore be used in
+place of `ivy-completing-read' for commands that rely on this
+behavior."
+ (ivy-completing-read
+ prompt collection predicate require-match initial-input
+ history (or def "") inherit-input-method))
+
+(declare-function mc/all-fake-cursors "ext:multiple-cursors-core")
+
+;; Kludge: Try to retain original minibuffer completion data.
+(defvar ivy--minibuffer-table)
+(defvar ivy--minibuffer-pred)
+(defvar ivy--minibuffer-try nil
+ "Store original `try-completion' result for sole completions.")
+
+(defun ivy-completion-in-region-action (str)
+ "Insert STR, erasing the previous one.
+The previous string is between `ivy-completion-beg' and `ivy-completion-end'."
+ (when (consp str)
+ (setq str (cdr str)))
+ (when (stringp str)
+ (let ((fake-cursors (and (require 'multiple-cursors-core nil t)
+ (mc/all-fake-cursors)))
+ (pt (point))
+ (beg ivy-completion-beg)
+ (end ivy-completion-end))
+ (when beg
+ (delete-region beg end))
+ (setq ivy-completion-beg (point))
+ (insert (substring-no-properties str))
+ (let ((minibuffer-completion-table (if (boundp 'ivy--minibuffer-table)
+ ivy--minibuffer-table
+ (ivy-state-collection ivy-last)))
+ (minibuffer-completion-predicate (if (boundp 'ivy--minibuffer-pred)
+ ivy--minibuffer-pred
+ (ivy-state-predicate ivy-last))))
+ (completion--done str (cond ((eq ivy--minibuffer-try t) 'finished)
+ ((eq ivy-exit 'done) 'unknown)
+ ('exact))))
+ (setq ivy-completion-end (point))
+ (save-excursion
+ (dolist (cursor fake-cursors)
+ (goto-char (overlay-start cursor))
+ (delete-region (+ (point) (- beg pt))
+ (+ (point) (- end pt)))
+ (insert (substring-no-properties str))
+ ;; manually move the fake cursor
+ (move-overlay cursor (point) (1+ (point)))
+ (set-marker (overlay-get cursor 'point) (point))
+ (set-marker (overlay-get cursor 'mark) (point)))))))
+
+(defun ivy-completion-common-length (str)
+ "Return the amount of characters that match in STR.
+
+`completion-all-completions' computes this and returns the result
+via text properties.
+
+The first non-matching part is propertized:
+- either with: (face (completions-first-difference))
+- or: (font-lock-face completions-first-difference)."
+ (let ((char-property-alias-alist '((face font-lock-face)))
+ (i (1- (length str))))
+ (catch 'done
+ (while (>= i 0)
+ (when (equal (get-text-property i 'face str)
+ '(completions-first-difference))
+ (throw 'done i))
+ (cl-decf i))
+ (throw 'done (length str)))))
+
+(defun ivy-completion-in-region (start end collection &optional predicate)
+ "An Ivy function suitable for `completion-in-region-function'.
+The function completes the text between START and END using COLLECTION.
+PREDICATE (a function called with no arguments) says when to exit.
+See `completion-in-region' for further information."
+ (let* ((enable-recursive-minibuffers t)
+ (str (buffer-substring-no-properties start end))
+ (completion-ignore-case (ivy--case-fold-p str))
+ (md (completion-metadata str collection predicate))
+ (reg (- end start))
+ (comps (completion-all-completions str collection predicate reg md))
+ (try (completion-try-completion str collection predicate reg md))
+ (ivy--minibuffer-table collection)
+ (ivy--minibuffer-pred predicate))
+ (cond ((null comps)
+ (message "No matches"))
+ ((progn
+ (nconc comps nil)
+ (and (null (cdr comps))
+ (string= str (car comps))))
+ (message "Sole match"))
+ (t
+ (when (eq collection 'crm--collection-fn)
+ (setq comps (delete-dups comps)))
+ (let* ((len (ivy-completion-common-length (car comps)))
+ (initial (cond ((= len 0)
+ "")
+ ((let ((str-len (length str)))
+ (when (> len str-len)
+ (setq len str-len)
+ str)))
+ (t
+ (substring str (- len))))))
+ (delete-region (- end len) end)
+ (setq ivy-completion-beg (- end len))
+ (setq ivy-completion-end ivy-completion-beg)
+ (if (null (cdr comps))
+ (progn
+ (unless (minibuffer-window-active-p (selected-window))
+ (setf (ivy-state-window ivy-last) (selected-window)))
+ (let ((ivy--minibuffer-try try))
+ (ivy-completion-in-region-action
+ (substring-no-properties (car comps)))))
+ (dolist (s comps)
+ ;; Remove face `completions-first-difference'.
+ (ivy--remove-props s 'face))
+ (setq ivy--old-re nil)
+ (unless (ivy--filter initial comps)
+ (setq initial nil)
+ (setq predicate nil)
+ (setq collection comps))
+ (unless (derived-mode-p #'emacs-lisp-mode)
+ (setq collection comps)
+ (setq predicate nil))
+ (ivy-read (format "(%s): " str) collection
+ :predicate predicate
+ :initial-input (concat
+ (and (derived-mode-p #'emacs-lisp-mode)
+ "^")
+ initial)
+ :action #'ivy-completion-in-region-action
+ :unwind (lambda ()
+ (unless (eq ivy-exit 'done)
+ (goto-char ivy-completion-beg)
+ (when initial
+ (insert initial))))
+ :caller 'ivy-completion-in-region)))
+ ;; Return value should be non-nil on valid completion;
+ ;; see `completion-in-region'.
+ t))))
+
+(defun ivy-completion-in-region-prompt ()
+ "Prompt function for `ivy-completion-in-region'.
+See `ivy-set-prompt'."
+ (and (window-minibuffer-p (ivy-state-window ivy-last))
+ (ivy-add-prompt-count (ivy-state-prompt ivy-last))))
+
+(ivy-set-prompt #'ivy-completion-in-region #'ivy-completion-in-region-prompt)
+
+(defcustom ivy-do-completion-in-region t
+ "When non-nil `ivy-mode' will set `completion-in-region-function'."
+ :type 'boolean)
+
+(defvar ivy--old-crf nil
+ "Store previous value of `completing-read-function'.")
+
+(defvar ivy--old-cirf nil
+ "Store previous value of `completion-in-region-function'.")
+
+;;;###autoload
+(define-minor-mode ivy-mode
+ "Toggle Ivy mode on or off.
+Turn Ivy mode on if ARG is positive, off otherwise.
+Turning on Ivy mode sets `completing-read-function' to
+`ivy-completing-read'.
+
+Global bindings:
+\\{ivy-mode-map}
+
+Minibuffer bindings:
+\\{ivy-minibuffer-map}"
+ :group 'ivy
+ :global t
+ :keymap ivy-mode-map
+ :lighter " ivy"
+ (if ivy-mode
+ (progn
+ (unless (eq completing-read-function #'ivy-completing-read)
+ (setq ivy--old-crf completing-read-function)
+ (setq completing-read-function #'ivy-completing-read))
+ (when ivy-do-completion-in-region
+ (unless (eq completion-in-region-function #'ivy-completion-in-region)
+ (setq ivy--old-cirf completion-in-region-function)
+ (setq completion-in-region-function #'ivy-completion-in-region))))
+ (when (eq completing-read-function #'ivy-completing-read)
+ (setq completing-read-function (or ivy--old-crf
+ #'completing-read-default))
+ (setq ivy--old-crf nil))
+ (when (eq completion-in-region-function #'ivy-completion-in-region)
+ (setq completion-in-region-function (or ivy--old-cirf
+ #'completion--in-region))
+ (setq ivy--old-cirf nil))))
+
+(defun ivy--preselect-index (preselect candidates)
+ "Return the index of PRESELECT in CANDIDATES."
+ (or (cond ((integerp preselect)
+ (if (integerp (car candidates))
+ (cl-position preselect candidates)
+ preselect))
+ ((cl-position preselect candidates :test #'equal))
+ ((ivy--regex-p preselect)
+ (cl-position preselect candidates :test #'string-match-p)))
+ 0))
+
+;;* Implementation
+;;** Regex
+(defun ivy-re-match (re-seq str)
+ "Return non-nil if RE-SEQ is matched by STR.
+
+RE-SEQ is a list of (RE . MATCH-P).
+
+RE is a regular expression.
+
+MATCH-P is t when RE should match STR and nil when RE should not
+match STR.
+
+Each element of RE-SEQ must match for the function to return true.
+
+This concept is used to generalize regular expressions for
+`ivy--regex-plus' and `ivy--regex-ignore-order'."
+ (let ((res t)
+ re)
+ (while (and res (setq re (pop re-seq)))
+ (setq res
+ (if (cdr re)
+ (string-match-p (car re) str)
+ (not (string-match-p (car re) str)))))
+ res))
+
+(defvar ivy--regex-hash
+ (make-hash-table :test #'equal)
+ "Store pre-computed regex.")
+
+(defvar ivy--input-garbage nil)
+
+(defun ivy--split (str)
+ "Split STR into list of substrings bounded by spaces.
+Single spaces act as splitting points. Consecutive spaces
+\"quote\" their preceding spaces, i.e., guard them from being
+split. This allows the literal interpretation of N spaces by
+inputting N+1 spaces. Any substring not constituting a valid
+regexp is passed to `regexp-quote'."
+ (let ((len (length str))
+ (i 0)
+ (start 0)
+ (res nil)
+ match-len
+ end
+ c)
+ (catch 'break
+ (while (< i len)
+ (setq c (aref str i))
+ (cond ((= ?\[ c)
+ (if (setq end (ivy--match-regex-brackets
+ (substring str i)))
+ (cl-incf i end)
+ (setq ivy--input-garbage (substring str i))
+ (throw 'break nil)))
+ ((= ?\\ c)
+ (if (and (< (1+ i) len) (= ?\( (aref str (1+ i))))
+ (progn
+ (when (> i start)
+ (push (substring str start i) res))
+ (if (eq (string-match "\\\\([^\0]*?\\\\)" str i) i)
+ (progn
+ (push (match-string 0 str) res)
+ (setq i (match-end 0))
+ (setq start i))
+ (setq ivy--input-garbage (substring str i))
+ (throw 'break nil)))
+ (cl-incf i)))
+ ((= ?\ c)
+ (string-match " +" str i)
+ (setq match-len (- (match-end 0) (match-beginning 0)))
+ (if (= match-len 1)
+ (progn
+ (when (> i start)
+ (push (substring str start i) res))
+ (setq start (1+ i)))
+ (setq str (replace-match
+ (make-string (1- match-len) ?\ )
+ nil nil str))
+ (setq len (length str))
+ (cl-incf i (1- match-len)))
+ (cl-incf i))
+ (t
+ (cl-incf i)))))
+ (when (< start i)
+ (push (substring str start) res))
+ (mapcar #'ivy--regex-or-literal (nreverse res))))
+
+(defun ivy--match-regex-brackets (str)
+ (let ((len (length str))
+ (i 1)
+ (open-count 1)
+ c)
+ (while (and (< i len)
+ (> open-count 0))
+ (setq c (aref str i))
+ (cond ((= c ?\[)
+ (cl-incf open-count))
+ ((= c ?\])
+ (cl-decf open-count)))
+ (cl-incf i))
+ (when (= open-count 0)
+ (if (eq (string-match "[+*?]" str i) i)
+ (match-end 0)
+ i))))
+
+(defun ivy--trim-trailing-re (regex)
+ "Trim incomplete REGEX.
+If REGEX ends with \\|, trim it, since then it matches an empty string."
+ (if (string-match "\\`\\(.*\\)[\\]|\\'" regex)
+ (match-string 1 regex)
+ regex))
+
+(defun ivy--regex (str &optional greedy)
+ "Re-build regex pattern from STR in case it has a space.
+When GREEDY is non-nil, join words in a greedy way."
+ (let ((hashed (unless greedy
+ (gethash str ivy--regex-hash))))
+ (if hashed
+ (progn
+ (setq ivy--subexps (car hashed))
+ (cdr hashed))
+ (when (string-match-p "\\(?:[^\\]\\|^\\)\\\\\\'" str)
+ (setq str (substring str 0 -1)))
+ (setq str (ivy--trim-trailing-re str))
+ (cdr (puthash str
+ (let ((subs (ivy--split str)))
+ (if (= (length subs) 1)
+ (cons
+ (setq ivy--subexps 0)
+ (if (string-match-p "\\`\\.[^.]" (car subs))
+ (concat "\\." (substring (car subs) 1))
+ (car subs)))
+ (cons
+ (setq ivy--subexps (length subs))
+ (replace-regexp-in-string
+ "\\.\\*\\??\\\\( "
+ "\\( "
+ (mapconcat
+ (lambda (x)
+ (if (string-match-p "\\`\\\\([^?][^\0]*\\\\)\\'" x)
+ x
+ (format "\\(%s\\)" x)))
+ subs
+ (if greedy ".*" ".*?"))
+ nil t))))
+ ivy--regex-hash)))))
+
+(defun ivy--regex-p (object)
+ "Return OBJECT if it is a valid regular expression, else nil."
+ (ignore-errors (string-match-p object "") object))
+
+(defun ivy--regex-or-literal (str)
+ "If STR isn't a legal regexp, escape it."
+ (or (ivy--regex-p str) (regexp-quote str)))
+
+(defun ivy--split-negation (str)
+ "Split STR into text before and after ! delimiter.
+Do not split if the delimiter is escaped as \\!.
+
+Assumes there is at most one un-escaped delimiter and discards
+text after delimiter if it is empty. Modifies match data."
+ (unless (string= str "")
+ (let ((delim "\\(?:\\`\\|[^\\]\\)\\(!\\)"))
+ (mapcar (lambda (split)
+ ;; Store "\!" as "!".
+ (replace-regexp-in-string "\\\\!" "!" split t t))
+ (if (string-match delim str)
+ ;; Ignore everything past first un-escaped ! rather than
+ ;; crashing. We can't warn or error because the minibuffer is
+ ;; already active.
+ (let* ((i (match-beginning 1))
+ (j (and (string-match delim str (1+ i))
+ (match-beginning 1)))
+ (neg (substring str (1+ i) j)))
+ (cons (substring str 0 i)
+ (and (not (string= neg ""))
+ (list neg))))
+ (list str))))))
+
+(defun ivy--split-spaces (str)
+ "Split STR on spaces, unless they're preceded by \\.
+No un-escaped spaces are left in the output. Any substring not
+constituting a valid regexp is passed to `regexp-quote'."
+ (when str
+ (let ((i 0) ; End of last search.
+ (j 0) ; End of last delimiter.
+ parts)
+ (while (string-match "\\(\\\\ \\)\\| +" str i)
+ (setq i (match-end 0))
+ (if (not (match-beginning 1))
+ ;; Un-escaped space(s).
+ (let ((delim (match-beginning 0)))
+ (when (< j delim)
+ (push (substring str j delim) parts))
+ (setq j i))
+ ;; Store "\ " as " ".
+ (setq str (replace-match " " t t str 1))
+ (setq i (1- i))))
+ (when (< j (length str))
+ (push (substring str j) parts))
+ (mapcar #'ivy--regex-or-literal (nreverse parts)))))
+
+(defun ivy--regex-ignore-order (str)
+ "Re-build regex from STR by splitting at spaces and using ! for negation.
+
+Examples:
+foo -> matches \"foo\"
+foo bar -> matches if both \"foo\" and \"bar\" match (any order)
+foo !bar -> matches if \"foo\" matches and \"bar\" does not match
+foo !bar baz -> matches if \"foo\" matches and neither \"bar\" nor \"baz\" match
+foo[a-z] -> matches \"foo[a-z]\"
+
+Escaping examples:
+foo\\!bar -> matches \"foo!bar\"
+foo\\ bar -> matches \"foo bar\"
+
+Returns a list suitable for `ivy-re-match'."
+ (setq str (ivy--trim-trailing-re str))
+ (let* (regex-parts
+ (raw-parts (ivy--split-negation str)))
+ (dolist (part (ivy--split-spaces (car raw-parts)))
+ (push (cons part t) regex-parts))
+ (when (cdr raw-parts)
+ (dolist (part (ivy--split-spaces (cadr raw-parts)))
+ (push (cons part nil) regex-parts)))
+ (if regex-parts (nreverse regex-parts)
+ "")))
+
+(defun ivy--regex-plus (str)
+ "Build a regex sequence from STR.
+Spaces are wild card characters, everything before \"!\" should
+match. Everything after \"!\" should not match."
+ (let ((parts (ivy--split-negation str)))
+ (cl-case (length parts)
+ (0
+ "")
+ (1
+ (if (= (aref str 0) ?!)
+ (list (cons "" t)
+ (list (ivy--regex (car parts))))
+ (ivy--regex (car parts))))
+ (2
+ (cons
+ (cons (ivy--regex (car parts)) t)
+ (mapcar #'list (split-string (cadr parts) " " t))))
+ (t (error "Unexpected: use only one !")))))
+
+(defun ivy--regex-fuzzy (str)
+ "Build a regex sequence from STR.
+Insert .* between each char."
+ (setq str (ivy--trim-trailing-re str))
+ (if (string-match "\\`\\(\\^?\\)\\(.*?\\)\\(\\$?\\)\\'" str)
+ (prog1
+ (concat (match-string 1 str)
+ (let ((lst (string-to-list (match-string 2 str))))
+ (apply #'concat
+ (cl-mapcar
+ #'concat
+ (cons "" (cdr (mapcar (lambda (c) (format "[^%c\n]*" c))
+ lst)))
+ (mapcar (lambda (x) (format "\\(%s\\)" (regexp-quote (char-to-string x))))
+ lst))))
+ (match-string 3 str))
+ (setq ivy--subexps (length (match-string 2 str))))
+ str))
+
+(defcustom ivy-fixed-height-minibuffer nil
+ "When non nil, fix the height of the minibuffer during ivy completion.
+This effectively sets the minimum height at this level to `ivy-height' and
+tries to ensure that it does not change depending on the number of candidates."
+ :type 'boolean)
+
+;;** Rest
+(defcustom ivy-truncate-lines t
+ "Minibuffer setting for `truncate-lines'."
+ :type 'boolean)
+
+(defun ivy--minibuffer-setup ()
+ "Setup ivy completion in the minibuffer."
+ ;; Guard for --without-x builds where `mwheel' is not preloaded.
+ (when (boundp 'mwheel-scroll-up-function)
+ (setq-local mwheel-scroll-up-function 'ivy-next-line))
+ (when (boundp 'mwheel-scroll-down-function)
+ (setq-local mwheel-scroll-down-function 'ivy-previous-line))
+ (setq-local completion-show-inline-help nil)
+ (setq-local line-spacing nil)
+ (setq-local minibuffer-default-add-function
+ (lambda ()
+ (list ivy--default)))
+ (setq-local inhibit-field-text-motion nil)
+ (setq truncate-lines ivy-truncate-lines)
+ (setq-local max-mini-window-height ivy-height)
+ (let ((height (cond ((and ivy-fixed-height-minibuffer
+ (not (eq (ivy-state-caller ivy-last)
+ #'ivy-completion-in-region)))
+ (+ ivy-height (if ivy-add-newline-after-prompt 1 0)))
+ (ivy-add-newline-after-prompt 2))))
+ (when height
+ (set-window-text-height nil height)))
+ (add-hook 'post-command-hook #'ivy--queue-exhibit nil t)
+ (add-hook 'window-size-change-functions #'ivy--window-size-changed nil t)
+ (let ((hook (ivy-alist-setting ivy-hooks-alist)))
+ (when (functionp hook)
+ (funcall hook))))
+
+(defun ivy--input ()
+ "Return the current minibuffer input."
+ ;; assume one-line minibuffer input
+ (save-excursion
+ (goto-char (minibuffer-prompt-end))
+ (let ((inhibit-field-text-motion t))
+ (buffer-substring-no-properties
+ (point)
+ (line-end-position)))))
+
+(defun ivy--minibuffer-cleanup ()
+ "Delete the displayed completion candidates."
+ (save-excursion
+ (goto-char (minibuffer-prompt-end))
+ (delete-region (line-end-position) (point-max))))
+
+(defun ivy-cleanup-string (str)
+ "Destructively remove unwanted text properties from STR."
+ (ivy--remove-props str 'field))
+
+(defvar ivy-set-prompt-text-properties-function
+ #'ivy-set-prompt-text-properties-default
+ "Function to set the text properties of the default ivy prompt.
+Called with two arguments, PROMPT and PROPS, where PROMPT is the
+string to be propertized and PROPS is a plist of default text
+properties that may be applied to PROMPT. The function should
+return the propertized PROMPT, which may be modified in-place.")
+
+(defun ivy-set-prompt-text-properties-default (prompt props)
+ "Propertize (confirm) and (match required) parts of PROMPT.
+PROPS is a plist of default text properties to apply to these
+parts beyond their respective faces `ivy-confirm-face' and
+`ivy-match-required-face'."
+ (dolist (pair '(("confirm" . ivy-confirm-face)
+ ("match required" . ivy-match-required-face)))
+ (let ((i (string-match-p (car pair) prompt)))
+ (when i
+ (add-text-properties i (+ i (length (car pair)))
+ `(face ,(cdr pair) ,@props)
+ prompt))))
+ prompt)
+
+(defun ivy-prompt ()
+ "Return the current prompt."
+ (let* ((caller (ivy-state-caller ivy-last))
+ (fn (plist-get ivy--prompts-list caller)))
+ (if fn
+ (condition-case err
+ (funcall fn)
+ (wrong-number-of-arguments
+ (lwarn 'ivy :error "%s
+ Prompt function set via `ivy-set-prompt' for caller `%s'
+ should take no arguments."
+ (error-message-string err)
+ caller)
+ ;; Old behavior.
+ (funcall fn (ivy-state-prompt ivy-last))))
+ ivy--prompt)))
+
+(defun ivy--break-lines (str width)
+ "Break each line in STR with newlines to fit into WIDTH columns."
+ (if (<= width 0)
+ str
+ (let (lines)
+ (dolist (line (split-string str "\n"))
+ (while (and line (> (string-width line) width))
+ (let ((prefix "") (extra 0))
+ (while (string-empty-p prefix)
+ ;; Grow `width' until it fits at least one char from `line'.
+ (setq prefix (truncate-string-to-width line (+ width extra)))
+ (setq extra (1+ extra)))
+ ;; Avoid introducing spurious newline if `prefix' and `line' are
+ ;; equal, i.e., if `line' couldn't be truncated to `width'.
+ (setq line (and (> (length line) (length prefix))
+ (substring line (length prefix))))
+ (push prefix lines)))
+ (when line (push line lines)))
+ (string-join (nreverse lines) "\n"))))
+
+(defun ivy--insert-prompt ()
+ "Update the prompt according to `ivy--prompt'."
+ (when (setq ivy--prompt (ivy-prompt))
+ (unless (memq this-command '(ivy-done ivy-alt-done ivy-partial-or-done
+ counsel-find-symbol))
+ (setq ivy--prompt-extra ""))
+ (let (head tail)
+ (if (string-match "\\(.*?\\)\\(:? ?\\)\\'" ivy--prompt)
+ (progn
+ (setq head (match-string 1 ivy--prompt))
+ (setq tail (match-string 2 ivy--prompt)))
+ (setq head ivy--prompt)
+ (setq tail ""))
+ (let ((inhibit-read-only t)
+ (std-props '(front-sticky t rear-nonsticky t field t read-only t))
+ (n-str
+ (concat
+ (if (and (bound-and-true-p minibuffer-depth-indicate-mode)
+ (> (minibuffer-depth) 1))
+ (format "[%d] " (minibuffer-depth))
+ "")
+ (concat
+ (if (string-match "%d.*%d" ivy-count-format)
+ (format head
+ (1+ ivy--index)
+ (or (and (ivy-state-dynamic-collection ivy-last)
+ ivy--full-length)
+ ivy--length))
+ (format head
+ (or (and (ivy-state-dynamic-collection ivy-last)
+ ivy--full-length)
+ ivy--length)))
+ ivy--prompt-extra
+ tail)))
+ (d-str (if ivy--directory
+ (abbreviate-file-name ivy--directory)
+ "")))
+ (save-excursion
+ (goto-char (point-min))
+ (delete-region (point-min) (minibuffer-prompt-end))
+ (let ((wid-n (string-width n-str))
+ (wid-d (string-width d-str))
+ (ww (window-width)))
+ (setq n-str
+ (cond ((> (+ wid-n wid-d) ww)
+ (concat n-str "\n" d-str "\n"))
+ ((> (+ wid-n wid-d (string-width ivy-text)) ww)
+ (concat n-str d-str "\n"))
+ (t
+ (concat n-str d-str)))))
+ (when ivy-pre-prompt-function
+ (setq n-str (concat (funcall ivy-pre-prompt-function) n-str)))
+ (when ivy-add-newline-after-prompt
+ (setq n-str (concat n-str "\n")))
+ (setq n-str (ivy--break-lines n-str (window-width)))
+ (set-text-properties 0 (length n-str)
+ `(face minibuffer-prompt ,@std-props)
+ n-str)
+ (setq n-str (funcall ivy-set-prompt-text-properties-function
+ n-str std-props))
+ (insert n-str))
+ ;; Mark prompt as selected if the user moves there or it is the only
+ ;; option left. Since the user input stays put, we have to manually
+ ;; remove the face as well.
+ (when ivy--use-selectable-prompt
+ (if (= ivy--index -1)
+ (add-face-text-property
+ (minibuffer-prompt-end) (line-end-position) 'ivy-prompt-match)
+ (remove-list-of-text-properties
+ (minibuffer-prompt-end) (line-end-position) '(face))))
+ ;; get out of the prompt area
+ (constrain-to-field nil (point-max))))))
+
+(defun ivy--sort-maybe (collection)
+ "Sort COLLECTION if needed."
+ (let ((sort (ivy-state-sort ivy-last)))
+ (if (and sort
+ (or (functionp sort)
+ (functionp (setq sort (ivy--sort-function
+ (ivy-state-collection ivy-last))))))
+ (sort (copy-sequence collection) sort)
+ collection)))
+
+(defcustom ivy-magic-slash-non-match-action 'ivy-magic-slash-non-match-cd-selected
+ "Action to take when a slash is added to the end of a non existing directory.
+Possible choices are 'ivy-magic-slash-non-match-cd-selected,
+'ivy-magic-slash-non-match-create, or nil"
+ :type '(choice
+ (const :tag "Use currently selected directory"
+ ivy-magic-slash-non-match-cd-selected)
+ (const :tag "Create and use new directory"
+ ivy-magic-slash-non-match-create)
+ (const :tag "Do nothing"
+ nil)))
+
+(defun ivy--create-and-cd (dir)
+ "When completing file names, create directory DIR and move there."
+ (make-directory dir)
+ (ivy--cd dir))
+
+(defun ivy--magic-file-doubleslash-directory ()
+ "Return an appropriate directory for when two slashes are entered."
+ (let (remote)
+ (cond
+ ;; Windows
+ ;; ((string-match "\\`[[:alpha:]]:/" ivy--directory)
+ ;; (match-string 0 ivy--directory))
+ ;; Remote root if on remote
+ ((setq remote (file-remote-p ivy--directory))
+ (concat remote "/"))
+ ;; Local root
+ (t
+ "/"))))
+
+(defun ivy--magic-file-slash ()
+ "Handle slash when completing file names."
+ (when (or (and (eq this-command #'self-insert-command)
+ (eolp))
+ (eq this-command #'ivy-partial-or-done))
+ (let ((canonical (expand-file-name ivy-text ivy--directory))
+ (magic (not (string= ivy-text "/"))))
+ (cond ((member ivy-text ivy--all-candidates)
+ (ivy--cd canonical))
+ ((and (eq system-type 'windows-nt) (string= ivy-text "//")))
+ ((string-suffix-p "//" ivy-text)
+ (ivy--cd
+ (ivy--magic-file-doubleslash-directory)))
+ ((string-match-p "\\`/ssh:" ivy-text)
+ (ivy--cd (file-name-directory ivy-text)))
+ ((string-match "[[:alpha:]]:/\\'" ivy-text)
+ (let ((drive-root (match-string 0 ivy-text)))
+ (when (file-exists-p drive-root)
+ (ivy--cd drive-root))))
+ ((and magic (file-directory-p canonical))
+ (ivy--cd canonical))
+ ((let ((default-directory ivy--directory))
+ (and (or (> ivy--index 0)
+ (= ivy--length 1)
+ magic)
+ (not (ivy--prompt-selected-p))
+ (not (equal (ivy-state-current ivy-last) ""))
+ (file-directory-p (ivy-state-current ivy-last))
+ (or (eq ivy-magic-slash-non-match-action
+ 'ivy-magic-slash-non-match-cd-selected)
+ (eq this-command #'ivy-partial-or-done))))
+ (ivy--cd
+ (expand-file-name (ivy-state-current ivy-last) ivy--directory)))
+ ((and (eq ivy-magic-slash-non-match-action
+ 'ivy-magic-slash-non-match-create)
+ magic)
+ (ivy--create-and-cd canonical))))))
+
+(defun ivy-magic-read-file-env ()
+ "If reading filename, jump to environment variable location."
+ (interactive)
+ (if (and ivy--directory
+ (equal ivy-text ""))
+ (let* ((cands (cl-loop for pair in process-environment
+ for (var val) = (split-string pair "=" t)
+ if (and val (not (equal "" val)))
+ if (file-exists-p
+ (if (file-name-absolute-p val)
+ val
+ (setq val
+ (expand-file-name val ivy--directory))))
+ collect (cons var val)))
+ (enable-recursive-minibuffers t)
+ (x (ivy-read "Env: " cands))
+ (path (cdr (assoc x cands))))
+ (insert (if (file-accessible-directory-p path)
+ (file-name-as-directory path)
+ path))
+ (ivy--cd-maybe))
+ (insert last-input-event)))
+
+(defun ivy-make-magic-action (caller key)
+ "Return a command that does the equivalent of `ivy-read-action' and KEY.
+This happens only when the input is empty.
+The intention is to bind the result to keys that are typically
+bound to `self-insert-command'."
+ (let* ((alist (assoc key
+ (plist-get
+ ivy--actions-list
+ caller)))
+ (doc (format "%s (`%S')"
+ (nth 2 alist)
+ (nth 1 alist))))
+ `(lambda (&optional arg)
+ ,doc
+ (interactive "p")
+ (if (string= "" ivy-text)
+ (execute-kbd-macro
+ (kbd ,(concat "M-o " key)))
+ (self-insert-command arg)))))
+
+(defcustom ivy-magic-tilde t
+ "When non-nil, ~ will move home when selecting files.
+Otherwise, ~/ will move home."
+ :type 'boolean)
+
+(defcustom ivy-dynamic-exhibit-delay-ms 0
+ "Delay in ms before dynamic collections are refreshed"
+ :type 'integer)
+
+(defvar ivy--exhibit-timer nil)
+
+(defun ivy--queue-exhibit ()
+ "Insert Ivy completions display, possibly after a timeout for
+dynamic collections.
+Should be run via minibuffer `post-command-hook'."
+ (if (and (> ivy-dynamic-exhibit-delay-ms 0)
+ (ivy-state-dynamic-collection ivy-last))
+ (progn
+ (when ivy--exhibit-timer (cancel-timer ivy--exhibit-timer))
+ (setq ivy--exhibit-timer
+ (run-with-timer
+ (/ ivy-dynamic-exhibit-delay-ms 1000.0)
+ nil
+ 'ivy--exhibit)))
+ (ivy--exhibit)))
+
+(defalias 'ivy--file-local-name
+ (if (fboundp 'file-local-name)
+ #'file-local-name
+ (lambda (file)
+ (or (file-remote-p file 'localname) file)))
+ "Compatibility shim for `file-local-name'.
+The function was added in Emacs 26.1.")
+
+(defun ivy--magic-tilde-directory (dir)
+ "Return an appropriate home for DIR for when ~ or ~/ are entered."
+ (file-name-as-directory
+ (expand-file-name
+ (let* ((home (expand-file-name (concat (file-remote-p dir) "~/")))
+ (dir-path (ivy--file-local-name dir))
+ (home-path (ivy--file-local-name home)))
+ (if (string= dir-path home-path)
+ "~"
+ home)))))
+
+(defun ivy-update-candidates (cands)
+ (ivy--insert-minibuffer
+ (ivy--format
+ (setq ivy--all-candidates cands))))
+
+(defun ivy--exhibit ()
+ "Insert Ivy completions display.
+Should be run via minibuffer `post-command-hook'."
+ (when (memq 'ivy--queue-exhibit post-command-hook)
+ (let ((inhibit-field-text-motion nil))
+ (constrain-to-field nil (point-max)))
+ (ivy-set-text (ivy--input))
+ (let ((new-minibuffer (ivy--update-minibuffer)))
+ (when new-minibuffer
+ (ivy--insert-minibuffer new-minibuffer)))
+ t))
+
+(defun ivy--dynamic-collection-cands (input)
+ (let ((coll (condition-case nil
+ (funcall (ivy-state-collection ivy-last) input)
+ (error
+ (funcall (ivy-state-collection ivy-last) input nil nil)))))
+ (if (listp coll)
+ (mapcar (lambda (x) (if (consp x) (car x) x)) coll)
+ coll)))
+
+(defun ivy--update-minibuffer ()
+ (prog1
+ (if (ivy-state-dynamic-collection ivy-last)
+ ;; while-no-input would cause annoying
+ ;; "Waiting for process to die...done" message interruptions
+ (let ((inhibit-message t)
+ coll in-progress)
+ (unless (or (equal ivy--old-text ivy-text)
+ (eq this-command 'ivy-resume))
+ (while-no-input
+ (setq coll (ivy--dynamic-collection-cands ivy-text))
+ (when (eq coll 0)
+ (setq coll nil)
+ (setq ivy--old-re nil)
+ (setq in-progress t))
+ (setq ivy--all-candidates (ivy--sort-maybe coll))))
+ (when (eq ivy--all-candidates 0)
+ (setq ivy--all-candidates nil)
+ (setq ivy--old-re nil)
+ (setq in-progress t))
+ (when (or ivy--all-candidates
+ (and (not (get-process " *counsel*"))
+ (not in-progress)))
+ (ivy--set-index-dynamic-collection)
+ (ivy--format ivy--all-candidates)))
+ (cond (ivy--directory
+ (cond ((or (string= "~/" ivy-text)
+ (and (string= "~" ivy-text)
+ ivy-magic-tilde))
+ (ivy--cd (ivy--magic-tilde-directory ivy--directory)))
+ ((string-match "/\\'" ivy-text)
+ (ivy--magic-file-slash))))
+ ((eq (ivy-state-collection ivy-last) #'internal-complete-buffer)
+ (when (or (and (string-match "\\` " ivy-text)
+ (not (string-match "\\` " ivy--old-text)))
+ (and (string-match "\\` " ivy--old-text)
+ (not (string-match "\\` " ivy-text))))
+ (setq ivy--all-candidates
+ (if (= (string-to-char ivy-text) ?\s)
+ (ivy--buffer-list " ")
+ (ivy--buffer-list "" ivy-use-virtual-buffers)))
+ (setq ivy--old-re nil))))
+ (with-current-buffer (ivy-state-buffer ivy-last)
+ (ivy--format
+ (ivy--filter ivy-text ivy--all-candidates))))
+ (setq ivy--old-text ivy-text)))
+
+(defun ivy-display-function-fallback (str)
+ (let ((buffer-undo-list t))
+ (save-excursion
+ (forward-line 1)
+ (insert str))))
+
+(defun ivy--insert-minibuffer (text)
+ "Insert TEXT into minibuffer with appropriate cleanup."
+ (let ((resize-mini-windows nil)
+ (update-fn (ivy-state-update-fn ivy-last))
+ (old-mark (marker-position (mark-marker)))
+ (win (active-minibuffer-window))
+ deactivate-mark)
+ (when win
+ (with-selected-window win
+ (ivy--minibuffer-cleanup)
+ (when update-fn
+ (funcall update-fn))
+ (ivy--insert-prompt)
+ ;; Do nothing if while-no-input was aborted.
+ (when (stringp text)
+ (if ivy--display-function
+ (funcall ivy--display-function text)
+ (ivy-display-function-fallback text)))
+ (ivy--resize-minibuffer-to-fit)
+ ;; prevent region growing due to text remove/add
+ (when (region-active-p)
+ (set-mark old-mark))))))
+
+(defvar ivy-auto-shrink-minibuffer nil
+ "When non-nil and the height < `ivy-height', auto-shrink the minibuffer.")
+
+(make-obsolete-variable 'ivy-auto-shrink-minibuffer
+ 'ivy-auto-shrink-minibuffer-alist
+ "<2020-04-28 Tue>")
+
+(defcustom ivy-auto-shrink-minibuffer-alist nil
+ "An alist to configure auto-shrinking of the minibuffer.
+
+Each key is a caller symbol. When the value is non-nil, and the
+height < `ivy-height', auto-shrink the minibuffer."
+ :type '(alist
+ :key-type symbol
+ :value-type boolean))
+
+(defun ivy--do-shrink-window ()
+ (let ((h (save-excursion
+ (goto-char (minibuffer-prompt-end))
+ (let ((inhibit-field-text-motion t))
+ (line-number-at-pos)))))
+ (shrink-window (-
+ (/ (window-body-height nil t)
+ (frame-char-height))
+ ivy--length h))))
+
+(defun ivy--resize-minibuffer-to-fit ()
+ "Resize the minibuffer window size to fit the text in the minibuffer."
+ (unless (or (frame-root-window-p (minibuffer-window))
+ (memq this-command '(ivy-read-action
+ ivy-dispatching-done
+ ivy-dispatching-call)))
+ (with-selected-window (minibuffer-window)
+ (if (fboundp 'window-text-pixel-size)
+ (let ((text-height (cdr (window-text-pixel-size)))
+ (body-height (window-body-height nil t)))
+ (cond ((> text-height body-height)
+ ;; Note: the size increment needs to be at least
+ ;; frame-char-height, otherwise resizing won't do
+ ;; anything.
+ (let ((delta (max (- text-height body-height)
+ (frame-char-height))))
+ (window-resize nil delta nil t t)))
+ ((and (or ivy-auto-shrink-minibuffer
+ (ivy-alist-setting
+ ivy-auto-shrink-minibuffer-alist))
+ (< ivy--length ivy-height))
+ (ivy--do-shrink-window))))
+ (let ((text-height (count-screen-lines))
+ (body-height (window-body-height)))
+ (when (> text-height body-height)
+ (window-resize nil (- text-height body-height) nil t)))))))
+
+(defun ivy--window-size-changed (&rest _)
+ "Resize ivy window to fit with current frame's size."
+ (when ivy-mode
+ (ivy--resize-minibuffer-to-fit)))
+
+(defun ivy--add-face (str face)
+ "Propertize STR with FACE."
+ (let ((len (length str)))
+ (condition-case nil
+ (progn
+ (colir-blend-face-background 0 len face str)
+ (let ((foreground (face-foreground face)))
+ (when foreground
+ (add-face-text-property
+ 0 len (list :foreground foreground) nil str))))
+ (error
+ (ignore-errors
+ (font-lock-append-text-property 0 len 'face face str)))))
+ str)
+
+(declare-function flx-make-string-cache "ext:flx")
+(declare-function flx-score "ext:flx")
+
+(defvar ivy--flx-cache nil)
+
+(with-eval-after-load 'flx
+ (setq ivy--flx-cache (flx-make-string-cache)))
+
+(defun ivy-toggle-case-fold ()
+ "Toggle `case-fold-search' for Ivy operations.
+
+Instead of modifying `case-fold-search' directly, this command
+toggles `ivy-case-fold-search', which can take on more values
+than the former, between nil and either `auto' or t. See
+`ivy-case-fold-search-default' for the meaning of these values.
+
+In any Ivy completion session, the case folding starts with
+`ivy-case-fold-search-default'."
+ (interactive)
+ (setq ivy-case-fold-search
+ (and (not ivy-case-fold-search)
+ (or ivy-case-fold-search-default 'auto)))
+ ;; Reset cache so that the candidate list updates.
+ (setq ivy--old-re nil))
+
+(defun ivy--re-filter (re candidates &optional mkpred)
+ "Return all RE matching CANDIDATES.
+RE is a list of cons cells, with a regexp car and a boolean cdr.
+When the cdr is t, the car must match.
+Otherwise, the car must not match."
+ (if (equal re "")
+ candidates
+ (ignore-errors
+ (dolist (re (if (stringp re) (list (cons re t)) re))
+ (let* ((re-str (car re))
+ (pred
+ (if mkpred
+ (funcall mkpred re-str)
+ (lambda (x) (string-match-p re-str x)))))
+ (setq candidates
+ (cl-remove nil candidates
+ (if (cdr re) :if-not :if)
+ pred))))
+ candidates)))
+
+(defun ivy--filter (name candidates)
+ "Return all items that match NAME in CANDIDATES.
+CANDIDATES are assumed to be static."
+ (let ((re (funcall ivy--regex-function name)))
+ (if (and
+ ivy--old-re
+ ivy--old-cands
+ (equal re ivy--old-re))
+ ;; quick caching for "C-n", "C-p" etc.
+ ivy--old-cands
+ (let* ((re-str (ivy-re-to-str re))
+ (matcher (ivy-state-matcher ivy-last))
+ (case-fold-search (ivy--case-fold-p name))
+ (cands (cond
+ (matcher
+ (funcall matcher re candidates))
+ ((and ivy--old-re
+ (stringp re)
+ (stringp ivy--old-re)
+ (not (string-match-p "\\\\" ivy--old-re))
+ (not (equal ivy--old-re ""))
+ (memq (cl-search
+ (if (string-match-p "\\\\)\\'" ivy--old-re)
+ (substring ivy--old-re 0 -2)
+ ivy--old-re)
+ re)
+ '(0 2))
+ ivy--old-cands
+ (ivy--re-filter re ivy--old-cands)))
+ (t
+ (ivy--re-filter re candidates)))))
+ (if (memq (cdr (assq (ivy-state-caller ivy-last)
+ ivy-index-functions-alist))
+ '(ivy-recompute-index-swiper
+ ivy-recompute-index-swiper-async
+ ivy-recompute-index-swiper-async-backward
+ ivy-recompute-index-swiper-backward))
+ (progn
+ (ivy--recompute-index re-str cands)
+ (setq ivy--old-cands (ivy--sort name cands)))
+ (setq ivy--old-cands (ivy--sort name cands))
+ (ivy--recompute-index re-str ivy--old-cands))
+ (setq ivy--old-re re)
+ ivy--old-cands))))
+
+(defun ivy--set-candidates (x)
+ "Update `ivy--all-candidates' with X."
+ (let (res
+ ;; (ivy--recompute-index-inhibit t)
+ )
+ (dolist (source ivy--extra-candidates)
+ (if (equal source '(original-source))
+ (if (null res)
+ (setq res x)
+ (setq res (append x res)))
+ (setq ivy--old-re nil)
+ (setq res (append
+ (ivy--filter ivy-text (cadr source))
+ res))))
+ (setq ivy--all-candidates
+ (if (cdr ivy--extra-candidates)
+ (delete-dups res)
+ res))))
+
+(defun ivy--shorter-matches-first (_name cands)
+ "Sort CANDS according to their length."
+ (if (nthcdr ivy-sort-max-size cands)
+ cands
+ (cl-sort (copy-sequence cands) #'< :key #'length)))
+
+(defcustom ivy-sort-matches-functions-alist
+ '((t . nil)
+ (ivy-completion-in-region . ivy--shorter-matches-first)
+ (ivy-switch-buffer . ivy-sort-function-buffer))
+ "An alist of functions for sorting matching candidates.
+
+Unlike `ivy-sort-functions-alist', which is used to sort the
+whole collection only once, this alist of functions are used to
+sort only matching candidates after each change in input.
+
+The alist KEY is either a collection function or t to match
+previously unmatched collection functions.
+
+The alist VAL is a sorting function with the signature of
+`ivy--prefix-sort'."
+ :type '(alist
+ :key-type (choice
+ (const :tag "Fall-through" t)
+ (symbol :tag "Collection"))
+ :value-type
+ (choice
+ (const :tag "Don't sort" nil)
+ (const :tag "Put prefix matches ahead" ivy--prefix-sort)
+ (function :tag "Custom sort function"))))
+
+(defun ivy--sort-files-by-date (_name candidates)
+ "Re-sort CANDIDATES according to file modification date."
+ (let ((default-directory ivy--directory))
+ (sort (copy-sequence candidates) #'file-newer-than-file-p)))
+
+(defvar ivy--flx-featurep (require 'flx nil 'noerror))
+
+(defun ivy--sort (name candidates)
+ "Re-sort candidates by NAME.
+All CANDIDATES are assumed to match NAME."
+ (let (fun)
+ (cond ((setq fun (ivy-alist-setting ivy-sort-matches-functions-alist))
+ (funcall fun name candidates))
+ ((and ivy--flx-featurep
+ (eq ivy--regex-function 'ivy--regex-fuzzy))
+ (ivy--flx-sort name candidates))
+ (t
+ candidates))))
+
+(defun ivy--prefix-sort (name candidates)
+ "Re-sort candidates by NAME.
+All CANDIDATES are assumed to match NAME.
+Prefix matches to NAME are put ahead of the list."
+ (if (or (string= name "")
+ (= (aref name 0) ?^))
+ candidates
+ (let ((re-prefix (concat "\\`" (funcall ivy--regex-function name)))
+ res-prefix
+ res-noprefix)
+ (dolist (s candidates)
+ (if (string-match-p re-prefix s)
+ (push s res-prefix)
+ (push s res-noprefix)))
+ (nconc
+ (nreverse res-prefix)
+ (nreverse res-noprefix)))))
+
+(defvar ivy--virtual-buffers nil
+ "Store the virtual buffers alist.")
+
+(defun ivy-re-to-str (re)
+ "Transform RE to a string.
+
+Functions like `ivy--regex-ignore-order' return a cons list.
+This function extracts a string from the cons list."
+ (if (consp re) (caar re) re))
+
+(defun ivy-sort-function-buffer (name candidates)
+ "Re-sort candidates by NAME.
+CANDIDATES is a list of buffer names each containing NAME.
+Sort open buffers before virtual buffers, and prefix matches
+before substring matches."
+ (if (or (string= name "")
+ (= (aref name 0) ?^))
+ candidates
+ (let* ((base-re (ivy-re-to-str (funcall ivy--regex-function name)))
+ (re-star-prefix (concat "\\`\\*" base-re))
+ (re-prefix (concat "\\`" base-re))
+ res-prefix
+ res-noprefix
+ res-virtual-prefix
+ res-virtual-noprefix)
+ (dolist (s candidates)
+ (cond
+ ((and (assoc s ivy--virtual-buffers)
+ (or (string-match-p re-star-prefix s)
+ (string-match-p re-prefix s)))
+ (push s res-virtual-prefix))
+ ((assoc s ivy--virtual-buffers)
+ (push s res-virtual-noprefix))
+ ((or (string-match-p re-star-prefix s)
+ (string-match-p re-prefix s))
+ (push s res-prefix))
+ (t
+ (push s res-noprefix))))
+ (nconc
+ (nreverse res-prefix)
+ (nreverse res-noprefix)
+ (nreverse res-virtual-prefix)
+ (nreverse res-virtual-noprefix)))))
+
+(defvar ivy-flx-limit 200
+ "Used to conditionally turn off flx sorting.
+
+When the amount of matching candidates exceeds this limit, then
+no sorting is done.")
+
+(defvar ivy--recompute-index-inhibit nil
+ "When non-nil, `ivy--recompute-index' is a no-op.")
+
+(defun ivy--recompute-index (re-str cands)
+ "Recompute index of selected candidate matching RE-STR.
+CANDS are the current candidates."
+ (let ((caller (ivy-state-caller ivy-last))
+ (func (or (ivy-alist-setting ivy-index-functions-alist)
+ #'ivy-recompute-index-zero))
+ (case-fold-search (ivy--case-fold-p re-str))
+ (preselect (ivy-state-preselect ivy-last))
+ (current (ivy-state-current ivy-last))
+ (empty (string= re-str "")))
+ (unless (or (memq this-command '(ivy-resume ivy-partial-or-done))
+ ivy--recompute-index-inhibit)
+ (let ((index (cond
+ ((or empty (string= re-str "^"))
+ (ivy--preselect-index preselect cands))
+ ((and (> (length cands) 10000) (eq func #'ivy-recompute-index-zero))
+ 0)
+ ((cl-position (string-remove-prefix "^" re-str)
+ cands
+ :test #'ivy--case-fold-string=))
+ ((and (ivy--completing-fname-p)
+ (cl-position (concat re-str "/")
+ cands
+ :test #'ivy--case-fold-string=)))
+ ((and (eq caller 'ivy-switch-buffer)
+ (not empty))
+ (or (cl-position current cands :test #'string=)
+ 0))
+ ((and (not empty)
+ (not (eq caller 'swiper))
+ (not (and ivy--flx-featurep
+ (eq ivy--regex-function 'ivy--regex-fuzzy)
+ ;; Limit to configured number of candidates
+ (null (nthcdr ivy-flx-limit cands))))
+ ;; If there was a preselected candidate, don't try to
+ ;; keep it selected even if the regexp still matches it.
+ ;; See issue #1563. See also `ivy--preselect-index',
+ ;; which this logic roughly mirrors.
+ (not (or
+ (and (integerp preselect)
+ (= ivy--index preselect))
+ (equal current preselect)
+ (and (ivy--regex-p preselect)
+ (stringp current)
+ (string-match-p preselect current))))
+ ivy--old-cands
+ (cl-position current cands :test #'equal)))
+ ((funcall func re-str cands))
+ (t 0))))
+ (ivy-set-index index)))))
+
+(defun ivy-recompute-index-swiper (_re-str cands)
+ "Recompute index of selected candidate when using `swiper'.
+CANDS are the current candidates."
+ (condition-case nil
+ (let ((tail (nthcdr ivy--index ivy--old-cands))
+ idx)
+ (if (and tail ivy--old-cands (not (equal "^" ivy--old-re)))
+ (progn
+ (while (and tail (null idx))
+ ;; Compare with eq to handle equal duplicates in cands
+ (setq idx (cl-position (pop tail) cands)))
+ (or
+ idx
+ (1- (length cands))))
+ (if ivy--old-cands
+ ivy--index
+ ;; already in ivy-state-buffer
+ (let ((n (line-number-at-pos))
+ (res 0)
+ (i 0))
+ (dolist (c cands)
+ (when (eq n (get-text-property 0 'swiper-line-number c))
+ (setq res i))
+ (cl-incf i))
+ res))))
+ (error 0)))
+
+(defun ivy-recompute-index-swiper-backward (re-str cands)
+ "Recompute index of selected candidate when using `swiper-backward'.
+CANDS are the current candidates."
+ (let ((idx (ivy-recompute-index-swiper re-str cands)))
+ (if (or (= idx -1)
+ (<= (get-text-property 0 'swiper-line-number (nth idx cands))
+ (line-number-at-pos)))
+ idx
+ (- idx 1))))
+
+(defun ivy-recompute-index-swiper-async (_re-str cands)
+ "Recompute index of selected candidate when using `swiper' asynchronously.
+CANDS are the current candidates."
+ (if (null ivy--old-cands)
+ (let ((ln (with-ivy-window
+ (line-number-at-pos))))
+ (or
+ ;; closest to current line going forwards
+ (cl-position-if (lambda (x)
+ (>= (string-to-number x) ln))
+ cands)
+ ;; closest to current line going backwards
+ (1- (length cands))))
+ (let ((tail (nthcdr ivy--index ivy--old-cands))
+ idx)
+ (if (and tail ivy--old-cands (not (equal "^" ivy--old-re)))
+ (progn
+ (while (and tail (null idx))
+ ;; Compare with `equal', since the collection is re-created
+ ;; each time with `split-string'
+ (setq idx (cl-position (pop tail) cands :test #'equal)))
+ (or idx 0))
+ ivy--index))))
+
+(defun ivy-recompute-index-swiper-async-backward (re-str cands)
+ "Recompute index of selected candidate when using `swiper-backward'
+asynchronously. CANDS are the current candidates."
+ (if (= (length cands) 0)
+ 0
+ (let ((idx (ivy-recompute-index-swiper-async re-str cands)))
+ (if
+ (<= (string-to-number (nth idx cands))
+ (with-ivy-window (line-number-at-pos)))
+ idx
+ (- idx 1)))))
+
+(defun ivy-recompute-index-zero (_re-str _cands)
+ "Recompute index of selected candidate.
+This function serves as a fallback when nothing else is available."
+ 0)
+
+(defcustom ivy-minibuffer-faces
+ '(ivy-minibuffer-match-face-1
+ ivy-minibuffer-match-face-2
+ ivy-minibuffer-match-face-3
+ ivy-minibuffer-match-face-4)
+ "List of `ivy' faces for minibuffer group matches."
+ :type '(repeat :tag "Faces"
+ (choice
+ (const ivy-minibuffer-match-face-1)
+ (const ivy-minibuffer-match-face-2)
+ (const ivy-minibuffer-match-face-3)
+ (const ivy-minibuffer-match-face-4)
+ (face :tag "Other face"))))
+
+(defun ivy--minibuffer-face (n)
+ "Return Nth face from `ivy-minibuffer-faces'.
+N wraps around, but skips the first element of the list."
+ (let ((tail (cdr ivy-minibuffer-faces)))
+ (nth (mod (+ n 2) (length tail)) tail)))
+
+(defun ivy--flx-propertize (x)
+ "X is (cons (flx-score STR ...) STR)."
+ (let ((str (copy-sequence (cdr x)))
+ (i 0)
+ (last-j -2))
+ (dolist (j (cdar x))
+ (unless (eq j (1+ last-j))
+ (cl-incf i))
+ (setq last-j j)
+ (add-face-text-property j (1+ j) (ivy--minibuffer-face i) nil str))
+ str))
+
+(defun ivy--flx-sort (name cands)
+ "Sort according to closeness to string NAME the string list CANDS."
+ (condition-case nil
+ (let* ((bolp (= (string-to-char name) ?^))
+ ;; An optimized regex for fuzzy matching
+ ;; "abc" → "^[^a]*a[^b]*b[^c]*c"
+ (fuzzy-regex (concat "\\`"
+ (and bolp (regexp-quote (substring name 1 2)))
+ (mapconcat
+ (lambda (x)
+ (setq x (char-to-string x))
+ (concat "[^" x "]*" (regexp-quote x)))
+ (if bolp (substring name 2) name)
+ "")))
+ ;; Strip off the leading "^" for flx matching
+ (flx-name (if bolp (substring name 1) name))
+ cands-left
+ cands-to-sort)
+
+ ;; Filter out non-matching candidates
+ (dolist (cand cands)
+ (when (string-match-p fuzzy-regex cand)
+ (push cand cands-left)))
+
+ ;; pre-sort the candidates by length before partitioning
+ (setq cands-left (cl-sort cands-left #'< :key #'length))
+
+ ;; partition the candidates into sorted and unsorted groups
+ (dotimes (_ (min (length cands-left) ivy-flx-limit))
+ (push (pop cands-left) cands-to-sort))
+
+ (nconc
+ ;; Compute all of the flx scores in one pass and sort
+ (mapcar #'car
+ (sort (mapcar
+ (lambda (cand)
+ (cons cand
+ (car (flx-score cand flx-name ivy--flx-cache))))
+ cands-to-sort)
+ (lambda (c1 c2)
+ ;; Break ties by length
+ (if (/= (cdr c1) (cdr c2))
+ (> (cdr c1)
+ (cdr c2))
+ (< (length (car c1))
+ (length (car c2)))))))
+
+ ;; Add the unsorted candidates
+ cands-left))
+ (error cands)))
+
+(defun ivy--truncate-string (str width)
+ "Truncate STR to WIDTH."
+ (truncate-string-to-width str width nil nil t))
+
+(defun ivy--format-function-generic (selected-fn other-fn cands separator)
+ "Transform candidates into a string for minibuffer.
+SELECTED-FN is called for the selected candidate, OTHER-FN for the others.
+Both functions take one string argument each. CANDS is a list of candidates
+and SEPARATOR is used to join them."
+ (let ((i -1))
+ (mapconcat
+ (lambda (str)
+ (let ((curr (eq (cl-incf i) ivy--window-index)))
+ (if curr
+ (funcall selected-fn str)
+ (funcall other-fn str))))
+ cands
+ separator)))
+
+(defun ivy-format-function-default (cands)
+ "Transform CANDS into a multiline string for the minibuffer.
+Add the face `ivy-current-match' to the selected candidate."
+ (ivy--format-function-generic
+ (lambda (str)
+ (ivy--add-face str 'ivy-current-match))
+ #'identity
+ cands
+ "\n"))
+
+(defun ivy-format-function-arrow (cands)
+ "Transform CANDS into a multiline string for the minibuffer.
+Like `ivy-format-function-default', but also prefix the selected
+candidate with an arrow \">\"."
+ (ivy--format-function-generic
+ (lambda (str)
+ (concat "> " (ivy--add-face str 'ivy-current-match)))
+ (lambda (str)
+ (concat " " str))
+ cands
+ "\n"))
+
+(defun ivy-format-function-line (cands)
+ "Transform CANDS into a multiline string for the minibuffer.
+Like `ivy-format-function-default', but extend highlighting of
+the selected candidate to the window edge.
+
+Note that since Emacs 27, `ivy-current-match' needs to have a
+non-nil :extend attribute. This is the case by default, but it
+also needs to be preserved by the current theme."
+ (ivy--format-function-generic
+ (lambda (str)
+ (ivy--add-face (concat str "\n") 'ivy-current-match))
+ (lambda (str)
+ (concat str "\n"))
+ cands
+ ""))
+
+(defun ivy-format-function-arrow-line (cands)
+ "Transform CANDS into a multiline string for the minibuffer.
+This combines the \">\" prefix of `ivy-format-function-arrow'
+with the extended highlighting of `ivy-format-function-line'."
+ (ivy--format-function-generic
+ (lambda (str)
+ (concat "> " (ivy--add-face (concat str "\n") 'ivy-current-match)))
+ (lambda (str)
+ (concat " " str "\n"))
+ cands
+ ""))
+
+(defun ivy--highlight-ignore-order (str)
+ "Highlight STR, using the ignore-order method."
+ (when (consp ivy--old-re)
+ (let ((i 1))
+ (dolist (re ivy--old-re)
+ (when (string-match (car re) str)
+ (add-face-text-property
+ (match-beginning 0) (match-end 0)
+ (ivy--minibuffer-face i)
+ nil str))
+ (cl-incf i))))
+ str)
+
+(defun ivy--highlight-fuzzy (str)
+ "Highlight STR, using the fuzzy method."
+ (if (and ivy--flx-featurep
+ (eq (ivy-alist-setting ivy-re-builders-alist) 'ivy--regex-fuzzy))
+ (let ((flx-name (string-remove-prefix "^" ivy-text)))
+ (ivy--flx-propertize
+ (cons (flx-score str flx-name ivy--flx-cache) str)))
+ (ivy--highlight-default str)))
+
+(defcustom ivy-use-group-face-if-no-groups t
+ "If t, and the expression has no subgroups, highlight whole match as a group.
+
+It will then use the second face (first of the \"group\" faces)
+of `ivy-minibuffer-faces'. Otherwise, always use the first face
+in this case."
+ :type 'boolean)
+
+(defun ivy--highlight-default (str)
+ "Highlight STR, using the default method."
+ (let ((regexps
+ (if (listp ivy-regex)
+ (mapcar #'car (cl-remove-if-not #'cdr ivy-regex))
+ (list ivy-regex)))
+ start)
+ (dolist (re regexps)
+ (ignore-errors
+ (while (and (string-match re str start)
+ (> (- (match-end 0) (match-beginning 0)) 0))
+ (setq start (match-end 0))
+ (let ((i 0)
+ (n 0)
+ prev)
+ (while (<= i ivy--subexps)
+ (let ((beg (match-beginning i))
+ (end (match-end i)))
+ (when (and beg end)
+ (unless (or (and prev (= prev beg))
+ (zerop i))
+ (cl-incf n))
+ (let ((face
+ (cond ((and ivy-use-group-face-if-no-groups
+ (zerop ivy--subexps))
+ (cadr ivy-minibuffer-faces))
+ ((zerop i)
+ (car ivy-minibuffer-faces))
+ (t
+ (ivy--minibuffer-face n)))))
+ (add-face-text-property beg end face nil str))
+ (unless (zerop i)
+ (setq prev end))))
+ (cl-incf i)))))))
+ str)
+
+(defun ivy--format-minibuffer-line (str annot)
+ "Format line STR for use in minibuffer."
+ (let* ((str (ivy-cleanup-string (copy-sequence str)))
+ (str (if (eq ivy-display-style 'fancy)
+ (if (memq (ivy-state-caller ivy-last)
+ ivy-highlight-grep-commands)
+ (let* ((start (if (string-match "\\`[^:]+:\\(?:[^:]+:\\)?" str)
+ (match-end 0) 0))
+ (file (substring str 0 start))
+ (match (substring str start)))
+ (concat file (funcall ivy--highlight-function match)))
+ (funcall ivy--highlight-function str))
+ str))
+ (olen (length str)))
+ (add-text-properties
+ 0 olen
+ '(mouse-face
+ ivy-minibuffer-match-highlight
+ help-echo
+ (format
+ (if tooltip-mode
+ "mouse-1: %s\nmouse-3: %s"
+ "mouse-1: %s mouse-3: %s")
+ ivy-mouse-1-tooltip ivy-mouse-3-tooltip))
+ str)
+ (when annot
+ (setq str (concat str (funcall annot str)))
+ (add-face-text-property
+ olen (length str) 'ivy-completions-annotations t str))
+ str))
+
+(defun ivy-read-file-transformer (str)
+ "Transform candidate STR when reading files."
+ (if (ivy--dirname-p str)
+ (propertize str 'face 'ivy-subdir)
+ str))
+
+(defun ivy--minibuffer-index-bounds (idx len wnd-len)
+ (let* ((half-height (/ wnd-len 2))
+ (start (max 0
+ (min (- idx half-height)
+ (- len (1- wnd-len)))))
+ (end (min (+ start (1- wnd-len)) len)))
+ (list start end (- idx start))))
+
+(defun ivy--format (cands)
+ "Return a string for CANDS suitable for display in the minibuffer.
+CANDS is a list of candidates that :display-transformer can turn into strings."
+ (setq ivy--length (length cands))
+ (when (>= ivy--index ivy--length)
+ (ivy-set-index (max (1- ivy--length) 0)))
+ (if (null cands)
+ (setf (ivy-state-current ivy-last) "")
+ (let ((cur (nth ivy--index cands)))
+ (setf (ivy-state-current ivy-last) (if (stringp cur)
+ (copy-sequence cur)
+ cur)))
+ (let* ((bnd (ivy--minibuffer-index-bounds
+ ivy--index ivy--length ivy-height))
+ (wnd-cands (cl-subseq cands (car bnd) (cadr bnd)))
+ (case-fold-search (ivy--case-fold-p (ivy-re-to-str ivy-regex)))
+ transformer-fn)
+ (setq ivy--window-index (nth 2 bnd))
+ (when (setq transformer-fn (ivy-state-display-transformer-fn ivy-last))
+ (with-ivy-window
+ (with-current-buffer (ivy-state-buffer ivy-last)
+ (setq wnd-cands (mapcar transformer-fn wnd-cands)))))
+ (ivy--wnd-cands-to-str wnd-cands))))
+
+(defun ivy--wnd-cands-to-str (wnd-cands)
+ (let* ((metadata (unless (ivy-state-dynamic-collection ivy-last)
+ (completion-metadata "" minibuffer-completion-table
+ minibuffer-completion-predicate)))
+ (annot (or (completion-metadata-get metadata 'annotation-function)
+ (plist-get completion-extra-properties :annotation-function)))
+ (str (concat "\n"
+ (funcall (ivy-alist-setting ivy-format-functions-alist)
+ (condition-case nil
+ (mapcar
+ (lambda (cand) (ivy--format-minibuffer-line cand annot))
+ wnd-cands)
+ (error wnd-cands))))))
+ (put-text-property 0 (length str) 'read-only nil str)
+ str))
+
+(defvar recentf-list)
+(defvar bookmark-alist)
+
+(defcustom ivy-virtual-abbreviate 'name
+ "The mode of abbreviation for virtual buffer names."
+ :type '(choice
+ (const :tag "Only name" name)
+ (const :tag "Abbreviated path" abbreviate)
+ (const :tag "Full path" full)
+ ;; eventually, uniquify
+ ))
+(declare-function bookmark-maybe-load-default-file "bookmark")
+(declare-function bookmark-get-filename "bookmark")
+
+(defun ivy--virtual-buffers ()
+ "Adapted from `ido-add-virtual-buffers-to-list'."
+ (require 'bookmark)
+ (unless recentf-mode
+ (recentf-mode 1))
+ (bookmark-maybe-load-default-file)
+ (let* ((vb-bkm (delete " - no file -"
+ (delq nil (mapcar #'bookmark-get-filename
+ bookmark-alist))))
+ (vb-list (cond ((eq ivy-use-virtual-buffers 'recentf)
+ recentf-list)
+ ((eq ivy-use-virtual-buffers 'bookmarks)
+ vb-bkm)
+ (ivy-use-virtual-buffers
+ (append recentf-list vb-bkm))
+ (t nil)))
+ virtual-buffers)
+ (dolist (head vb-list)
+ (let* ((file-name (if (stringp head)
+ head
+ (cdr head)))
+ (name (cond ((eq ivy-virtual-abbreviate 'name)
+ (file-name-nondirectory file-name))
+ ((eq ivy-virtual-abbreviate 'abbreviate)
+ (abbreviate-file-name file-name))
+ (t
+ (expand-file-name file-name)))))
+ (when (equal name "")
+ (setq name
+ (if (consp head)
+ (car head)
+ (file-name-nondirectory (directory-file-name file-name)))))
+ (unless (or (equal name "")
+ (get-file-buffer file-name)
+ (assoc name virtual-buffers))
+ (push (cons (copy-sequence name) file-name) virtual-buffers))))
+ (when virtual-buffers
+ (dolist (comp virtual-buffers)
+ (put-text-property 0 (length (car comp))
+ 'face 'ivy-virtual
+ (car comp)))
+ (setq ivy--virtual-buffers (nreverse virtual-buffers))
+ (mapcar #'car ivy--virtual-buffers))))
+
+(defcustom ivy-ignore-buffers '("\\` " "\\`\\*tramp/")
+ "List of regexps or functions matching buffer names to ignore."
+ :type '(repeat (choice regexp function)))
+
+(defvar ivy-switch-buffer-faces-alist '((dired-mode . ivy-subdir)
+ (org-mode . ivy-org))
+ "Store face customizations for `ivy-switch-buffer'.
+Each KEY is `major-mode', each VALUE is a face name.")
+
+(defun ivy--buffer-list (str &optional virtual predicate)
+ "Return the buffers that match STR.
+If VIRTUAL is non-nil, add virtual buffers.
+If optional argument PREDICATE is non-nil, use it to test each
+possible match. See `all-completions' for further information."
+ (delete-dups
+ (nconc
+ (all-completions str #'internal-complete-buffer predicate)
+ (and virtual
+ (ivy--virtual-buffers)))))
+
+(defvar ivy-views (and nil
+ `(("ivy + *scratch* {}"
+ (vert
+ (file ,(expand-file-name "ivy.el"))
+ (buffer "*scratch*")))
+ ("swiper + *scratch* {}"
+ (horz
+ (file ,(expand-file-name "swiper.el"))
+ (buffer "*scratch*")))))
+ "Store window configurations selectable by `ivy-switch-buffer'.
+
+The default value is given as an example.
+
+Each element is a list of (NAME VIEW). NAME is a string, it's
+recommended to end it with a distinctive snippet e.g. \"{}\" so
+that it's easy to distinguish the window configurations.
+
+VIEW is either a TREE or a window-configuration (see
+`ivy--get-view-config').
+
+TREE is a nested list with the following valid cars:
+- vert: split the window vertically
+- horz: split the window horizontally
+- file: open the specified file
+- buffer: open the specified buffer
+
+TREE can be nested multiple times to have multiple window splits.")
+
+(defun ivy-default-view-name ()
+ "Return default name for new view."
+ (let* ((default-view-name
+ (concat "{} "
+ (mapconcat #'identity
+ (sort
+ (mapcar (lambda (w)
+ (let* ((b (window-buffer w))
+ (f (buffer-file-name b)))
+ (if f
+ (file-name-nondirectory f)
+ (buffer-name b))))
+ (window-list))
+ #'string-lessp)
+ " ")))
+ (view-name-re (concat "\\`"
+ (regexp-quote default-view-name)
+ " \\([0-9]+\\)"))
+ old-view)
+ (cond ((setq old-view
+ (cl-find-if
+ (lambda (x)
+ (string-match view-name-re (car x)))
+ ivy-views))
+ (format "%s %d"
+ default-view-name
+ (1+ (string-to-number
+ (match-string 1 (car old-view))))))
+ ((assoc default-view-name ivy-views)
+ (concat default-view-name " 1"))
+ (t
+ default-view-name))))
+
+(defun ivy--get-view-config ()
+ "Get `current-window-configuration' for `ivy-views'."
+ (dolist (w (window-list))
+ (set-window-parameter w 'ivy-view-data
+ (with-current-buffer (window-buffer w)
+ (cond (buffer-file-name
+ (list 'file buffer-file-name (point)))
+ ((eq major-mode 'dired-mode)
+ (list 'file default-directory (point)))
+ (t
+ (list 'buffer (buffer-name) (point)))))))
+ (let ((window-persistent-parameters
+ (append window-persistent-parameters
+ (list (cons 'ivy-view-data t)))))
+ (current-window-configuration)))
+
+(defun ivy-push-view (&optional arg)
+ "Push the current window tree on `ivy-views'.
+
+When ARG is non-nil, replace a selected item on `ivy-views'.
+
+Currently, the split configuration (i.e. horizontal or vertical)
+and point positions are saved, but the split positions aren't.
+Use `ivy-pop-view' to delete any item from `ivy-views'."
+ (interactive "P")
+ (let* ((view (ivy--get-view-config))
+ (view-name
+ (if arg
+ (ivy-read "Update view: " ivy-views)
+ (ivy-read "Name view: " nil
+ :initial-input (ivy-default-view-name)))))
+ (when view-name
+ (let ((x (assoc view-name ivy-views)))
+ (if x
+ (setcdr x (list view))
+ (push (list view-name view) ivy-views))))))
+
+(defun ivy-pop-view-action (view)
+ "Delete VIEW from `ivy-views'."
+ (setq ivy-views (delete view ivy-views))
+ (setq ivy--all-candidates
+ (delete (car view) ivy--all-candidates))
+ (setq ivy--old-cands nil))
+
+(defun ivy-pop-view ()
+ "Delete a view to delete from `ivy-views'."
+ (interactive)
+ (ivy-read "Pop view: " ivy-views
+ :preselect (caar ivy-views)
+ :action #'ivy-pop-view-action
+ :caller 'ivy-pop-view))
+
+(defun ivy-source-views ()
+ "Return the name of the views saved in `ivy-views'."
+ (mapcar #'car ivy-views))
+
+(ivy-set-sources
+ 'ivy-switch-buffer
+ '((original-source)
+ (ivy-source-views)))
+
+(defun ivy-set-view-recur (view)
+ "Set VIEW recursively."
+ (cond ((window-configuration-p view)
+ (set-window-configuration view)
+ (dolist (w (window-list))
+ (with-selected-window w
+ (ivy-set-view-recur
+ (window-parameter w 'ivy-view-data)))))
+ ((eq (car view) 'vert)
+ (let* ((wnd1 (selected-window))
+ (wnd2 (split-window-vertically))
+ (views (cdr view))
+ (v (pop views))
+ (temp-wnd))
+ (with-selected-window wnd1
+ (ivy-set-view-recur v))
+ (while (setq v (pop views))
+ (with-selected-window wnd2
+ (when views
+ (setq temp-wnd (split-window-vertically)))
+ (ivy-set-view-recur v)
+ (when views
+ (setq wnd2 temp-wnd))))))
+ ((eq (car view) 'horz)
+ (let* ((wnd1 (selected-window))
+ (wnd2 (split-window-horizontally))
+ (views (cdr view))
+ (v (pop views))
+ (temp-wnd))
+ (with-selected-window wnd1
+ (ivy-set-view-recur v))
+ (while (setq v (pop views))
+ (with-selected-window wnd2
+ (when views
+ (setq temp-wnd (split-window-horizontally)))
+ (ivy-set-view-recur v)
+ (when views
+ (setq wnd2 temp-wnd))))))
+ ((eq (car view) 'file)
+ (let* ((name (nth 1 view))
+ (virtual (assoc name ivy--virtual-buffers))
+ buffer)
+ (cond ((setq buffer (get-buffer name))
+ (switch-to-buffer buffer nil 'force-same-window))
+ (virtual
+ (find-file (cdr virtual)))
+ ((file-exists-p name)
+ (find-file name))))
+ (when (and (> (length view) 2)
+ (numberp (nth 2 view)))
+ (goto-char (nth 2 view))))
+ ((eq (car view) 'buffer)
+ (switch-to-buffer (nth 1 view))
+ (when (and (> (length view) 2)
+ (numberp (nth 2 view)))
+ (goto-char (nth 2 view))))
+ ((eq (car view) 'sexp)
+ (eval (nth 1 view)))))
+
+(defun ivy--switch-buffer-action (buffer)
+ "Switch to BUFFER.
+BUFFER may be a string or nil."
+ (if (zerop (length buffer))
+ (switch-to-buffer
+ ivy-text nil 'force-same-window)
+ (let ((virtual (assoc buffer ivy--virtual-buffers))
+ (view (assoc buffer ivy-views)))
+ (cond ((and virtual
+ (not (get-buffer buffer)))
+ (find-file (cdr virtual)))
+ (view
+ (delete-other-windows)
+ (let (
+ ;; silence "Directory has changed on disk"
+ (inhibit-message t))
+ (ivy-set-view-recur (cadr view))))
+ (t
+ (switch-to-buffer
+ buffer nil 'force-same-window))))))
+
+(defun ivy--switch-buffer-other-window-action (buffer)
+ "Switch to BUFFER in other window.
+BUFFER may be a string or nil."
+ (if (zerop (length buffer))
+ (switch-to-buffer-other-window ivy-text)
+ (let ((virtual (assoc buffer ivy--virtual-buffers)))
+ (if (and virtual
+ (not (get-buffer buffer)))
+ (find-file-other-window (cdr virtual))
+ (switch-to-buffer-other-window buffer)))))
+
+(defun ivy--rename-buffer-action (buffer)
+ "Rename BUFFER."
+ (let ((new-name (read-string "Rename buffer (to new name): ")))
+ (with-current-buffer buffer
+ (rename-buffer new-name))))
+
+(defun ivy--find-file-action (buffer)
+ "Find file from BUFFER's directory."
+ (let* ((virtual (assoc buffer ivy--virtual-buffers))
+ (default-directory (if virtual
+ (file-name-directory (cdr virtual))
+ (buffer-local-value 'default-directory
+ (or (get-buffer buffer)
+ (current-buffer))))))
+ (call-interactively (if (functionp 'counsel-find-file)
+ #'counsel-find-file
+ #'find-file))))
+
+(defun ivy--kill-buffer-or-virtual (buffer)
+ (if (get-buffer buffer)
+ (kill-buffer buffer)
+ (setq recentf-list (delete
+ (cdr (assoc buffer ivy--virtual-buffers))
+ recentf-list))))
+
+(defun ivy--kill-current-candidate ()
+ (setf (ivy-state-preselect ivy-last) ivy--index)
+ (setq ivy--old-re nil)
+ (setq ivy--all-candidates (delete (ivy-state-current ivy-last) ivy--all-candidates))
+ (let ((ivy--recompute-index-inhibit t))
+ (ivy--exhibit)))
+
+(defun ivy--kill-current-candidate-buffer ()
+ (setf (ivy-state-preselect ivy-last) ivy--index)
+ (setq ivy--old-re nil)
+ (setq ivy--all-candidates (ivy--buffer-list "" ivy-use-virtual-buffers
+ (ivy-state-predicate ivy-last)))
+ (let ((ivy--recompute-index-inhibit t))
+ (ivy--exhibit)))
+
+(defun ivy--kill-buffer-action (buffer)
+ "Kill BUFFER."
+ (ivy--kill-buffer-or-virtual buffer)
+ (unless (buffer-live-p (ivy-state-buffer ivy-last))
+ (setf (ivy-state-buffer ivy-last)
+ (with-ivy-window (current-buffer))))
+ (ivy--kill-current-candidate-buffer))
+
+(defvar ivy-switch-buffer-map
+ (let ((map (make-sparse-keymap)))
+ (ivy-define-key map (kbd "C-k") 'ivy-switch-buffer-kill)
+ map))
+
+(defun ivy-switch-buffer-kill ()
+ "When at end-of-line, kill the current buffer in `ivy-switch-buffer'.
+Otherwise, forward to `ivy-kill-line'."
+ (interactive)
+ (if (not (eolp))
+ (ivy-kill-line)
+ (ivy--kill-buffer-action
+ (ivy-state-current ivy-last))))
+
+(ivy-set-actions
+ 'ivy-switch-buffer
+ '(("f"
+ ivy--find-file-action
+ "find file")
+ ("j"
+ ivy--switch-buffer-other-window-action
+ "other window")
+ ("k"
+ ivy--kill-buffer-action
+ "kill")
+ ("r"
+ ivy--rename-buffer-action
+ "rename")))
+
+(ivy-set-actions
+ t
+ '(("i" ivy--action-insert "insert")
+ ("w" ivy--action-copy "copy")))
+
+(defun ivy--trim-grep-line-number (x)
+ (if (string-match ":[0-9]+:" x)
+ (substring x (match-end 0))
+ x))
+
+(defun ivy--action-insert (x)
+ (insert
+ (if (stringp x)
+ (ivy--trim-grep-line-number x)
+ x (car x))))
+
+(defun ivy--action-copy (x)
+ (kill-new
+ (if (stringp x)
+ (ivy--trim-grep-line-number x)
+ (car x))))
+
+(defun ivy--switch-buffer-matcher (regexp candidates)
+ "Return REGEXP matching CANDIDATES.
+Skip buffers that match `ivy-ignore-buffers'."
+ (if (string-match-p "^:" ivy-text)
+ (delete-dups
+ (cl-remove-if-not
+ (lambda (s)
+ (let ((b (get-buffer s)))
+ (and b
+ (string-match-p regexp (buffer-local-value 'default-directory b))
+ (not (string-match-p "^\\*" s)))))
+ candidates))
+ (let ((res (ivy--re-filter regexp candidates)))
+ (if (or (null ivy-use-ignore)
+ (null ivy-ignore-buffers))
+ res
+ (or (cl-remove-if
+ (lambda (buf)
+ (cl-find-if
+ (lambda (f-or-r)
+ (if (functionp f-or-r)
+ (funcall f-or-r buf)
+ (string-match-p f-or-r buf)))
+ ivy-ignore-buffers))
+ res)
+ (and (eq ivy-use-ignore t)
+ res))))))
+
+(defun ivy-append-face (str face)
+ "Append to STR the property FACE."
+ (when face
+ (setq str (copy-sequence str))
+ (add-face-text-property 0 (length str) face t str))
+ str)
+
+(defun ivy--remote-buffer-p (buffer)
+ "Return non-nil if BUFFER object is visiting a remote file.
+If that is the case, value is a string identifying the remote
+connection."
+ (let ((dir (buffer-local-value 'default-directory buffer)))
+ (ignore-errors (file-remote-p dir))))
+
+(defun ivy-switch-buffer-transformer (str)
+ "Transform candidate STR when switching buffers."
+ (let ((buf (get-buffer str)))
+ (cond ((not buf) str)
+ ((let ((remote (ivy--remote-buffer-p buf)))
+ (when remote
+ (format "%s (%s)" (ivy-append-face str 'ivy-remote) remote))))
+ ((not (verify-visited-file-modtime buf))
+ (ivy-append-face str 'ivy-modified-outside-buffer))
+ ((buffer-modified-p buf)
+ (ivy-append-face str 'ivy-modified-buffer))
+ (t
+ (let* ((mode (buffer-local-value 'major-mode buf))
+ (face (cdr (assq mode ivy-switch-buffer-faces-alist))))
+ (ivy-append-face str face))))))
+
+(defun ivy-switch-buffer-occur (cands)
+ "Occur function for `ivy-switch-buffer' using `ibuffer'.
+CANDS are the candidates to be displayed."
+ (unless cands
+ (setq cands (all-completions ivy-text #'internal-complete-buffer)))
+ (ibuffer
+ nil (buffer-name)
+ `((or ,@(cl-mapcan
+ (lambda (cand)
+ (unless (eq (get-text-property 0 'face cand) 'ivy-virtual)
+ `((name . ,(format "\\_<%s\\_>" (regexp-quote cand))))))
+ cands)))))
+
+;;;###autoload
+(defun ivy-switch-buffer ()
+ "Switch to another buffer."
+ (interactive)
+ (ivy-read "Switch to buffer: " #'internal-complete-buffer
+ :keymap ivy-switch-buffer-map
+ :preselect (buffer-name (other-buffer (current-buffer)))
+ :action #'ivy--switch-buffer-action
+ :matcher #'ivy--switch-buffer-matcher
+ :caller 'ivy-switch-buffer))
+
+(ivy-configure 'ivy-switch-buffer
+ :parent 'internal-complete-buffer
+ :occur #'ivy-switch-buffer-occur)
+
+;;;###autoload
+(defun ivy-switch-view ()
+ "Switch to one of the window views stored by `ivy-push-view'."
+ (interactive)
+ (let ((ivy-initial-inputs-alist
+ '((ivy-switch-buffer . "{}"))))
+ (ivy-switch-buffer)))
+
+;;;###autoload
+(defun ivy-switch-buffer-other-window ()
+ "Switch to another buffer in another window."
+ (interactive)
+ (ivy-read "Switch to buffer in other window: " #'internal-complete-buffer
+ :matcher #'ivy--switch-buffer-matcher
+ :preselect (buffer-name (other-buffer (current-buffer)))
+ :action #'ivy--switch-buffer-other-window-action
+ :keymap ivy-switch-buffer-map
+ :caller 'ivy-switch-buffer-other-window))
+
+(ivy-configure 'ivy-switch-buffer-other-window
+ :parent 'ivy-switch-buffer)
+
+(defun ivy--yank-handle-case-fold (text)
+ (if (and (> (length ivy-text) 0)
+ (string= (downcase ivy-text) ivy-text))
+ (downcase text)
+ text))
+
+(defun ivy--yank-by (fn &rest args)
+ "Pull buffer text from current line into search string.
+The region to extract is determined by the respective values of
+point before and after applying FN to ARGS."
+ (let (text)
+ (with-ivy-window
+ (let ((beg (point))
+ (bol (line-beginning-position))
+ (eol (line-end-position))
+ end)
+ (unwind-protect
+ (progn (apply fn args)
+ (setq end (goto-char (max bol (min (point) eol))))
+ (setq text (buffer-substring-no-properties beg end))
+ (ivy--pulse-region beg end))
+ (unless text
+ (goto-char beg)))))
+ (when text
+ (insert (replace-regexp-in-string
+ " +" " "
+ (ivy--yank-handle-case-fold text)
+ t t)))))
+
+(defun ivy-yank-word (&optional arg)
+ "Pull next word from buffer into search string.
+If optional ARG is non-nil, pull in the next ARG
+words (previous if ARG is negative)."
+ (interactive "p")
+ (ivy--yank-by #'forward-word arg))
+
+(defun ivy-yank-symbol (&optional arg)
+ "Pull next symbol from buffer into search string.
+If optional ARG is non-nil, pull in the next ARG
+symbols (previous if ARG is negative)."
+ (interactive "p")
+ (ivy--yank-by #'forward-symbol (or arg 1)))
+
+(defun ivy-yank-char (&optional arg)
+ "Pull next character from buffer into search string.
+If optional ARG is non-nil, pull in the next ARG
+characters (previous if ARG is negative)."
+ (interactive "p")
+ (ivy--yank-by #'forward-char arg))
+
+(defvar ivy--pulse-overlay nil
+ "Overlay used to highlight yanked word.")
+
+(defvar ivy--pulse-timer nil
+ "Timer used to dispose of `ivy--pulse-overlay'.")
+
+(defcustom ivy-pulse-delay 0.5
+ "Number of seconds to display `ivy-yanked-word' highlight.
+When nil, disable highlighting."
+ :type '(choice
+ (number :tag "Delay in seconds")
+ (const :tag "Disable" nil)))
+
+(defun ivy--pulse-region (start end)
+ "Temporarily highlight text between START and END.
+The \"pulse\" duration is determined by `ivy-pulse-delay'."
+ (when ivy-pulse-delay
+ (if ivy--pulse-overlay
+ (let ((ostart (overlay-start ivy--pulse-overlay))
+ (oend (overlay-end ivy--pulse-overlay)))
+ (when (< end start)
+ (cl-rotatef start end))
+ ;; Extend the existing overlay's region to include START..END,
+ ;; but only if the two regions are contiguous.
+ (move-overlay ivy--pulse-overlay
+ (if (= start oend) ostart start)
+ (if (= end ostart) oend end)))
+ (setq ivy--pulse-overlay (make-overlay start end))
+ (overlay-put ivy--pulse-overlay 'face 'ivy-yanked-word))
+ (when ivy--pulse-timer
+ (cancel-timer ivy--pulse-timer))
+ (setq ivy--pulse-timer
+ (run-at-time ivy-pulse-delay nil #'ivy--pulse-cleanup))))
+
+(defun ivy--pulse-cleanup ()
+ "Cancel `ivy--pulse-timer' and delete `ivy--pulse-overlay'."
+ (when ivy--pulse-timer
+ (cancel-timer ivy--pulse-timer)
+ (setq ivy--pulse-timer nil))
+ (when ivy--pulse-overlay
+ (delete-overlay ivy--pulse-overlay)
+ (setq ivy--pulse-overlay nil)))
+
+(defun ivy-kill-ring-save ()
+ "Store the current candidates into the kill ring.
+If the region is active, forward to `kill-ring-save' instead."
+ (interactive)
+ (if (region-active-p)
+ (call-interactively 'kill-ring-save)
+ (kill-new
+ (mapconcat
+ #'identity
+ ivy--old-cands
+ "\n"))))
+
+(defun ivy-insert-current ()
+ "Make the current candidate into current input.
+Don't finish completion."
+ (interactive)
+ (delete-minibuffer-contents)
+ (let ((end (and ivy--directory
+ (ivy--dirname-p (ivy-state-current ivy-last))
+ -1)))
+ (insert (substring-no-properties
+ (ivy-state-current ivy-last) 0 end))))
+
+(defun ivy-insert-current-full ()
+ "Insert the full Yank the current directory into the minibuffer."
+ (interactive)
+ (insert ivy--directory))
+
+(defcustom ivy-preferred-re-builders
+ '((ivy--regex-plus . "ivy")
+ (ivy--regex-ignore-order . "order")
+ (ivy--regex-fuzzy . "fuzzy"))
+ "Alist of preferred re-builders with display names.
+This list can be rotated with `ivy-rotate-preferred-builders'."
+ :type '(alist :key-type function :value-type string))
+
+(defun ivy-rotate-preferred-builders ()
+ "Switch to the next re builder in `ivy-preferred-re-builders'."
+ (interactive)
+ (when ivy-preferred-re-builders
+ (setq ivy--old-re nil)
+ (setq ivy--regex-function
+ (let ((cell (assq ivy--regex-function ivy-preferred-re-builders)))
+ (car (or (cadr (memq cell ivy-preferred-re-builders))
+ (car ivy-preferred-re-builders)))))))
+
+(defun ivy-toggle-fuzzy ()
+ "Toggle the re builder between `ivy--regex-fuzzy' and `ivy--regex-plus'."
+ (interactive)
+ (setq ivy--old-re nil)
+ (if (eq ivy--regex-function 'ivy--regex-fuzzy)
+ (setq ivy--regex-function 'ivy--regex-plus)
+ (setq ivy--regex-function 'ivy--regex-fuzzy)))
+
+(defun ivy--label-and-delete-dups (entries)
+ "Label ENTRIES with history indices."
+ (let ((ht (and entries (make-hash-table :test #'equal)))
+ (idx 0)
+ entry
+ accum)
+ (while (setq entry (pop entries))
+ (unless (gethash entry ht)
+ (puthash entry t ht)
+ (push `(,entry . ,idx) accum))
+ (cl-incf idx))
+ (nreverse accum)))
+
+(defvar ivy--reverse-i-search-history nil
+ "Store the minibuffer history variable.")
+
+(defun ivy-reverse-i-search-kill ()
+ "Remove the current item from minibuffer history."
+ (interactive)
+ (if (not (eolp))
+ (ivy-kill-line)
+ (let ((current (ivy-state-current ivy-last))
+ (history ivy--reverse-i-search-history))
+ (cond ((booleanp history))
+ ((symbolp history)
+ (set history (delete current (symbol-value history))))
+ ((ring-p history)
+ (ring-remove history (ring-member history current)))))
+ (ivy--kill-current-candidate)))
+
+(defvar ivy-reverse-i-search-map
+ (let ((map (make-sparse-keymap)))
+ (ivy-define-key map (kbd "C-k") 'ivy-reverse-i-search-kill)
+ map))
+
+(defun ivy-history-contents (history)
+ "Copy contents of HISTORY.
+A copy is necessary so that we don't clobber any string attributes.
+Also set `ivy--reverse-i-search-history' to HISTORY."
+ (prog1 (ivy--label-and-delete-dups
+ (cond ((booleanp history) ())
+ ((symbolp history)
+ (copy-sequence (symbol-value history)))
+ ((ring-p history)
+ (ring-elements history))
+ ((sequencep history)
+ (copy-sequence history))
+ ((error "Expected a symbol, ring, or sequence: %S" history))))
+ (setq ivy--reverse-i-search-history history)))
+
+(defun ivy-reverse-i-search ()
+ "Enter a recursive `ivy-read' session using the current history.
+The selected history element will be inserted into the minibuffer.
+\\<ivy-reverse-i-search-map>
+You can also delete an element from history with \\[ivy-reverse-i-search-kill]."
+ (interactive)
+ (cond
+ ((= (minibuffer-depth) 0)
+ (user-error
+ "This command is intended to be called from within `ivy-read'"))
+ ;; don't recur
+ ((and (> (minibuffer-depth) 1)
+ (eq (ivy-state-caller ivy-last) 'ivy-reverse-i-search)))
+ (t
+ (let ((enable-recursive-minibuffers t)
+ (old-last ivy-last))
+ (ivy-read "Reverse-i-search: "
+ (ivy-history-contents (ivy-state-history ivy-last))
+ :keymap ivy-reverse-i-search-map
+ :action (lambda (x)
+ (ivy--reset-state
+ (setq ivy-last old-last))
+ (delete-minibuffer-contents)
+ (insert (substring-no-properties (car x)))
+ (ivy--cd-maybe))
+ :caller 'ivy-reverse-i-search)))))
+
+(defun ivy-restrict-to-matches ()
+ "Restrict candidates to current input and erase input."
+ (interactive)
+ (delete-minibuffer-contents)
+ (if (ivy-state-dynamic-collection ivy-last)
+ (progn
+ ;; By disabling `ivy-state-dynamic-collection', we lose the ability
+ ;; to clearly differentiate between ternary programmed completion
+ ;; functions and Ivy's unary dynamic collections (short of using
+ ;; `func-arity' or otherwise redesigning things). So we must also
+ ;; update the dynamic binding of `minibuffer-completion-table' to no
+ ;; longer hold a dynamic collection.
+ (setq minibuffer-completion-table ivy--old-cands)
+ (setq ivy--all-candidates ivy--old-cands)
+ (setf (ivy-state-collection ivy-last) ivy--old-cands)
+ (setf (ivy-state-dynamic-collection ivy-last) nil))
+ (setq ivy--all-candidates
+ (ivy--filter ivy-text ivy--all-candidates))))
+
+;;* Occur
+(defvar-local ivy-occur-last nil
+ "Buffer-local value of `ivy-last'.
+Can't re-use `ivy-last' because using e.g. `swiper' in the same
+buffer would modify `ivy-last'.")
+
+(defvar ivy-occur-mode-map
+ (let ((map (make-sparse-keymap)))
+ (ivy-define-key map [mouse-1] 'ivy-occur-click)
+ (ivy-define-key map (kbd "RET") 'ivy-occur-press-and-switch)
+ (ivy-define-key map (kbd "j") 'ivy-occur-next-line)
+ (ivy-define-key map (kbd "k") 'ivy-occur-previous-line)
+ (define-key map (kbd "h") 'backward-char)
+ (define-key map (kbd "l") 'forward-char)
+ (ivy-define-key map (kbd "f") 'ivy-occur-press)
+ (ivy-define-key map (kbd "g") 'ivy-occur-revert-buffer)
+ (ivy-define-key map (kbd "a") 'ivy-occur-read-action)
+ (ivy-define-key map (kbd "o") 'ivy-occur-dispatch)
+ (ivy-define-key map (kbd "c") 'ivy-occur-toggle-calling)
+ (define-key map (kbd "q") 'quit-window)
+ (define-key map (kbd "R") 'read-only-mode)
+ (ivy-define-key map (kbd "C-d") 'ivy-occur-delete-candidate)
+ map)
+ "Keymap for Ivy Occur mode.")
+
+(defun ivy-occur-toggle-calling ()
+ "Toggle `ivy-calling'."
+ (interactive)
+ (if (setq ivy-calling (not ivy-calling))
+ (progn
+ (setq mode-name "Ivy-Occur [calling]")
+ (ivy-occur-press))
+ (setq mode-name "Ivy-Occur"))
+ (force-mode-line-update))
+
+(defun ivy--find-occur-buffer ()
+ (let ((cb (current-buffer)))
+ (cl-find-if
+ (lambda (b)
+ (with-current-buffer b
+ (and (eq major-mode 'ivy-occur-grep-mode)
+ (equal cb (ivy-state-buffer ivy-occur-last)))))
+ (buffer-list))))
+
+(defun ivy--select-occur-buffer ()
+ (let* ((ob (ivy--find-occur-buffer))
+ (ow (cl-find-if (lambda (w) (equal ob (window-buffer w)))
+ (window-list))))
+ (if ow
+ (select-window ow)
+ (pop-to-buffer ob))))
+
+(defun ivy-occur-next-line (&optional arg)
+ "Move the cursor down ARG lines.
+When `ivy-calling' isn't nil, call `ivy-occur-press'."
+ (interactive "p")
+ (let ((offset (cond ((derived-mode-p 'ivy-occur-grep-mode) 5)
+ ((derived-mode-p 'ivy-occur-mode) 2))))
+ (if offset
+ (progn
+ (if (< (line-number-at-pos) offset)
+ (progn
+ (goto-char (point-min))
+ (forward-line (1- offset)))
+ (forward-line arg)
+ (when (eolp)
+ (forward-line -1)))
+ (when ivy-calling
+ (ivy-occur-press)))
+ (ivy--select-occur-buffer)
+ (ivy-occur-next-line arg)
+ (ivy-occur-press-and-switch))))
+
+(defun ivy-occur-previous-line (&optional arg)
+ "Move the cursor up ARG lines.
+When `ivy-calling' isn't nil, call `ivy-occur-press'."
+ (interactive "p")
+ (let ((offset (cond ((derived-mode-p 'ivy-occur-grep-mode) 5)
+ ((derived-mode-p 'ivy-occur-mode) 2))))
+ (if offset
+ (progn
+ (forward-line (- arg))
+ (when (< (line-number-at-pos) offset)
+ (goto-char (point-min))
+ (forward-line (1- offset)))
+ (when ivy-calling
+ (ivy-occur-press)))
+ (ivy--select-occur-buffer)
+ (ivy-occur-previous-line arg)
+ (ivy-occur-press-and-switch))))
+
+(defun ivy-occur-next-error (n &optional reset)
+ "A `next-error-function' for `ivy-occur-mode'."
+ (interactive "p")
+ (when reset
+ (goto-char (point-min)))
+ (setq n (or n 1))
+ (let ((ivy-calling t))
+ (cond ((< n 0) (ivy-occur-previous-line (- n)))
+ (t (ivy-occur-next-line n))))
+ ;; The window's point overrides the buffer's point every time it's redisplayed
+ (dolist (window (get-buffer-window-list nil nil t))
+ (set-window-point window (point))))
+
+(define-derived-mode ivy-occur-mode fundamental-mode "Ivy-Occur"
+ "Major mode for output from \\[ivy-occur].
+
+\\{ivy-occur-mode-map}"
+ (setq-local view-read-only nil))
+
+(defvar ivy-occur-grep-mode-map
+ (let ((map (copy-keymap ivy-occur-mode-map)))
+ (ivy-define-key map (kbd "C-x C-q") 'ivy-wgrep-change-to-wgrep-mode)
+ (ivy-define-key map "w" 'ivy-wgrep-change-to-wgrep-mode)
+ map)
+ "Keymap for Ivy Occur Grep mode.")
+
+(defun ivy-occur-delete-candidate ()
+ (interactive)
+ (let ((inhibit-read-only t))
+ (delete-region (line-beginning-position)
+ (1+ (line-end-position)))))
+
+(define-derived-mode ivy-occur-grep-mode grep-mode "Ivy-Occur"
+ "Major mode for output from \\[ivy-occur].
+
+\\{ivy-occur-grep-mode-map}"
+ (setq-local view-read-only nil)
+ (when (fboundp 'wgrep-setup)
+ (wgrep-setup)))
+
+(defun ivy--starts-with-dotslash (str)
+ (string-match-p "\\`\\.[/\\]" str))
+
+(defun ivy--occur-insert-lines (cands)
+ "Insert CANDS into `ivy-occur' buffer."
+ (font-lock-mode -1)
+ (dolist (cand cands)
+ (setq cand
+ (if (string-match "\\`\\(.*:[0-9]+:\\)\\(.*\\)\\'" cand)
+ (let ((file-and-line (match-string 1 cand))
+ (grep-line (match-string 2 cand)))
+ (concat
+ (propertize file-and-line 'face 'ivy-grep-info)
+ (ivy--highlight-fuzzy grep-line)))
+ (ivy--highlight-fuzzy (copy-sequence cand))))
+ (add-text-properties
+ 0 (length cand)
+ '(mouse-face
+ highlight
+ help-echo "mouse-1: call ivy-action")
+ cand)
+ (insert (if (ivy--starts-with-dotslash cand) "" " ")
+ cand ?\n)))
+
+(defun ivy--occur-default (cands)
+ "Insert CANDS into the current occur buffer."
+ (unless cands
+ (let ((coll (ivy-state-collection ivy-last)))
+ (when (arrayp coll)
+ (setq coll (all-completions "" coll (ivy-state-predicate ivy-last))))
+ (setq cands (ivy--filter (ivy-state-text ivy-last) coll))))
+ (ivy-occur-mode)
+ (insert (format "%d candidates:\n" (length cands)))
+ (ivy--occur-insert-lines cands)
+ (read-only-mode))
+
+(defun ivy-occur ()
+ "Stop completion and put the current candidates into a new buffer.
+
+The new buffer remembers current action(s).
+
+While in the *ivy-occur* buffer, selecting a candidate with RET or
+a mouse click will call the appropriate action for that candidate.
+
+There is no limit on the number of *ivy-occur* buffers."
+ (interactive)
+ (if (not (window-minibuffer-p))
+ (user-error "No completion session is active")
+ (let* ((caller (ivy-state-caller ivy-last))
+ (occur-fn (or (plist-get ivy--occurs-list caller)
+ #'ivy--occur-default))
+ (buffer
+ (generate-new-buffer
+ (format "*ivy-occur%s \"%s\"*"
+ (if caller
+ (concat " " (prin1-to-string caller))
+ "")
+ ivy-text))))
+ (with-current-buffer buffer
+ (funcall occur-fn
+ (if (ivy-state-dynamic-collection ivy-last)
+ (funcall (ivy-state-collection ivy-last) ivy-text)
+ ivy--old-cands))
+ (setf (ivy-state-text ivy-last) ivy-text)
+ (setq ivy-occur-last ivy-last))
+ (ivy-exit-with-action
+ (lambda (_)
+ (pop-to-buffer buffer)
+ (setq next-error-last-buffer buffer)
+ (setq-local next-error-function #'ivy-occur-next-error))))))
+
+(defun ivy-occur-revert-buffer ()
+ "Refresh the buffer making it up-to date with the collection.
+
+Currently only works for `swiper'. In that specific case, the
+*ivy-occur* buffer becomes nearly useless as the original buffer
+is updated, since the line numbers no longer match.
+
+Calling this function is as if you called `ivy-occur' on the
+updated original buffer."
+ (interactive)
+ (let ((caller (ivy-state-caller ivy-occur-last))
+ (ivy-last ivy-occur-last))
+ (let ((inhibit-read-only t)
+ (line (line-number-at-pos))
+ (text (ivy-state-text ivy-last)))
+ (erase-buffer)
+ (ivy-set-text text)
+ (funcall (or (plist-get ivy--occurs-list caller)
+ #'ivy--occur-default)
+ (and (ivy-state-dynamic-collection ivy-last)
+ (funcall (ivy-state-collection ivy-last)
+ text)))
+ (goto-char (point-min))
+ (forward-line (1- line)))
+ (setq ivy-occur-last ivy-last)))
+
+(declare-function wgrep-change-to-wgrep-mode "ext:wgrep")
+
+(defun ivy-wgrep-change-to-wgrep-mode ()
+ "Forward to `wgrep-change-to-wgrep-mode'."
+ (interactive)
+ (if (require 'wgrep nil 'noerror)
+ (wgrep-change-to-wgrep-mode)
+ (error "Package wgrep isn't installed")))
+
+(defun ivy-occur-read-action ()
+ "Select one of the available actions as the current one."
+ (interactive)
+ (let ((ivy-last ivy-occur-last))
+ (ivy-read-action)))
+
+(defun ivy-occur-dispatch ()
+ "Call one of the available actions on the current item."
+ (interactive)
+ (let* ((state-action (ivy-state-action ivy-occur-last))
+ (actions (if (symbolp state-action)
+ state-action
+ (copy-sequence state-action))))
+ (unwind-protect
+ (progn
+ (ivy-occur-read-action)
+ (ivy-occur-press))
+ (setf (ivy-state-action ivy-occur-last) actions))))
+
+(defun ivy-occur-click (event)
+ "Execute action for the current candidate.
+EVENT gives the mouse position."
+ (interactive "e")
+ (let ((window (posn-window (event-end event)))
+ (pos (posn-point (event-end event))))
+ (with-current-buffer (window-buffer window)
+ (goto-char pos)
+ (ivy-occur-press))))
+
+(declare-function swiper--cleanup "swiper")
+(declare-function swiper--add-overlays "swiper")
+(defvar ivy-occur-timer nil)
+
+(defun ivy--occur-press-update-window ()
+ (cond
+ ((memq (ivy-state-caller ivy-occur-last)
+ (append '(swiper swiper-isearch) ivy-highlight-grep-commands))
+ (let ((window (ivy-state-window ivy-occur-last))
+ (buffer (ivy-state-buffer ivy-occur-last)))
+ (when (buffer-live-p buffer)
+ (cond ((or (not (window-live-p window))
+ (equal window (selected-window)))
+ (save-selected-window
+ (setf (ivy-state-window ivy-occur-last)
+ (display-buffer buffer))))
+ ((not (equal (window-buffer window) buffer))
+ (with-selected-window window
+ (switch-to-buffer buffer)))))))
+
+ ((memq (ivy-state-caller ivy-occur-last)
+ '(counsel-describe-function
+ counsel-describe-variable
+ counsel-describe-symbol))
+ (setf (ivy-state-window ivy-occur-last)
+ (selected-window))
+ (selected-window))))
+
+(defun ivy--occur-press-buffer ()
+ (let ((buffer (ivy-state-buffer ivy-last)))
+ (if (buffer-live-p buffer)
+ buffer
+ (current-buffer))))
+
+(defun ivy-occur-press ()
+ "Execute action for the current candidate."
+ (interactive)
+ (ivy--occur-press-update-window)
+ (when (save-excursion
+ (beginning-of-line)
+ (looking-at "\\(?:.[/\\]\\| \\)\\(.*\\)$"))
+ (let* ((ivy-last ivy-occur-last)
+ (ivy-text (ivy-state-text ivy-last))
+ (str (buffer-substring
+ (match-beginning 1)
+ (match-end 1)))
+ (offset (or (get-text-property 0 'offset str) 0))
+ (coll (ivy-state-collection ivy-last))
+ (action (ivy--get-action ivy-last))
+ (ivy-exit 'done))
+ (with-ivy-window
+ (with-current-buffer (ivy--occur-press-buffer)
+ (save-restriction
+ (widen)
+ (funcall action
+ (if (and (consp coll)
+ (consp (car coll)))
+ (assoc str coll)
+ (substring str offset)))))
+ (if (memq (ivy-state-caller ivy-last)
+ (append '(swiper swiper-isearch) ivy-highlight-grep-commands))
+ (with-current-buffer (window-buffer (selected-window))
+ (swiper--cleanup)
+ (swiper--add-overlays
+ (ivy--regex ivy-text)
+ (line-beginning-position)
+ (line-end-position)
+ (selected-window))
+ (when (timerp ivy-occur-timer)
+ (cancel-timer ivy-occur-timer))
+ (setq ivy-occur-timer
+ (run-at-time 1.0 nil 'swiper--cleanup))))))))
+
+(defun ivy-occur-press-and-switch ()
+ "Execute action for the current candidate and switch window."
+ (interactive)
+ (ivy-occur-press)
+ (select-window (ivy--get-window ivy-occur-last)))
+
+(defun ivy--marked-p ()
+ (member (ivy-state-current ivy-last) ivy-marked-candidates))
+
+(defun ivy--unmark (cand)
+ (setcar (member cand ivy--all-candidates)
+ (setcar (member cand ivy--old-cands)
+ (substring cand (length ivy-mark-prefix))))
+ (setq ivy-marked-candidates
+ (delete cand ivy-marked-candidates)))
+
+(defun ivy--mark (cand)
+ (let ((marked-cand (copy-sequence (concat ivy-mark-prefix cand))))
+ ;; Primarily for preserving `idx'. FIXME: the mark
+ ;; prefix shouldn't become part of the candidate!
+ (add-text-properties 0 (length ivy-mark-prefix)
+ (text-properties-at 0 cand)
+ marked-cand)
+ (setcar (member cand ivy--all-candidates)
+ (setcar (member cand ivy--old-cands) marked-cand))
+ (setq ivy-marked-candidates
+ (nconc ivy-marked-candidates (list marked-cand)))))
+
+(defun ivy-mark ()
+ "Mark the selected candidate and move to the next one.
+
+In `ivy-call', :action will be called in turn for all marked
+candidates.
+
+However, if :multi-action was supplied to `ivy-read', then it
+will be called with `ivy-marked-candidates'. This way, it can
+make decisions based on the whole marked list."
+ (interactive)
+ (unless (ivy--marked-p)
+ (ivy--mark (ivy-state-current ivy-last)))
+ (ivy-next-line))
+
+(defun ivy-unmark ()
+ "Unmark the selected candidate and move to the next one."
+ (interactive)
+ (when (ivy--marked-p)
+ (ivy--unmark (ivy-state-current ivy-last)))
+ (ivy-next-line))
+
+(defun ivy-unmark-backward ()
+ "Move to the previous candidate and unmark it."
+ (interactive)
+ (ivy-previous-line)
+ (ivy--exhibit)
+ (when (ivy--marked-p)
+ (ivy--unmark (ivy-state-current ivy-last))))
+
+(defun ivy-toggle-marks ()
+ "Toggle mark for all narrowed candidates."
+ (interactive)
+ (dolist (cand ivy--old-cands)
+ (if (member cand ivy-marked-candidates)
+ (ivy--unmark cand)
+ (ivy--mark cand))))
+
+(defconst ivy-help-file (let ((default-directory
+ (if load-file-name
+ (file-name-directory load-file-name)
+ default-directory)))
+ (if (file-exists-p "ivy-help.org")
+ (expand-file-name "ivy-help.org")
+ (if (file-exists-p "doc/ivy-help.org")
+ (expand-file-name "doc/ivy-help.org"))))
+ "The file for `ivy-help'.")
+
+(defvar org-hide-emphasis-markers)
+
+(defun ivy-help ()
+ "Help for `ivy'."
+ (interactive)
+ (let ((buf (get-buffer "*Ivy Help*"))
+ (inhibit-read-only t))
+ (unless buf
+ (setq buf (get-buffer-create "*Ivy Help*"))
+ (cl-letf (((symbol-function #'help-buffer) (lambda () buf)))
+ (describe-mode))
+ (with-current-buffer buf
+ (goto-char (point-min))
+ (insert "* describe-mode\n")
+ (goto-char (point-min))
+ (insert-file-contents ivy-help-file)
+ (org-mode)
+ (setq-local org-hide-emphasis-markers t)
+ (view-mode)
+ (goto-char (point-min))
+ (let ((inhibit-message t))
+ (org-cycle '(64)))))
+ (if (eq this-command 'ivy-help)
+ (switch-to-buffer buf)
+ (with-ivy-window
+ (pop-to-buffer buf)))
+ (view-mode)
+ (goto-char (point-min))))
+
+(declare-function ffap-url-p "ffap")
+(defvar ffap-url-fetcher)
+
+(defun ivy-ffap-url-p (string)
+ "Forward to `ffap-url-p'."
+ (require 'ffap)
+ (ffap-url-p string))
+
+(defun ivy-ffap-url-fetcher (url)
+ "Calls `ffap-url-fetcher'."
+ (require 'ffap)
+ (funcall ffap-url-fetcher url))
+
+(ivy-configure 'read-file-name-internal
+ :sort-fn #'ivy-sort-file-function-default
+ :display-transformer-fn #'ivy-read-file-transformer
+ :alt-done-fn #'ivy--directory-done)
+
+(ivy-configure 'internal-complete-buffer
+ :display-transformer-fn #'ivy-switch-buffer-transformer)
+
+(ivy-configure 'Info-read-node-name-1
+ :alt-done-fn #'ivy--info-alt-done)
+
+(provide 'ivy)
+
+;;; ivy.el ends here
diff --git a/elpa/ivy-20220406.1052/ivy.elc b/elpa/ivy-20220406.1052/ivy.elc
new file mode 100644
index 0000000..81e8cf8
--- /dev/null
+++ b/elpa/ivy-20220406.1052/ivy.elc
Binary files differ
diff --git a/elpa/ivy-20220406.1052/ivy.info b/elpa/ivy-20220406.1052/ivy.info
new file mode 100644
index 0000000..4b1f252
--- /dev/null
+++ b/elpa/ivy-20220406.1052/ivy.info
@@ -0,0 +1,1973 @@
+This is ivy.info, produced by makeinfo version 6.7 from ivy.texi.
+
+Ivy manual, version 0.13.4
+
+ Ivy is an interactive interface for completion in Emacs. Emacs uses
+completion mechanism in a variety of contexts: code, menus, commands,
+variables, functions, etc. Completion entails listing, sorting,
+filtering, previewing, and applying actions on selected items. When
+active, ‘ivy-mode’ completes the selection process by narrowing
+available choices while previewing in the minibuffer. Selecting the
+final candidate is either through simple keyboard character inputs or
+through powerful regular expressions.
+
+ Copyright (C) 2015–2021 Free Software Foundation, Inc.
+
+ Permission is granted to copy, distribute and/or modify this
+ document under the terms of the GNU Free Documentation License,
+ Version 1.3 or any later version published by the Free Software
+ Foundation; with no Invariant Sections, no Front-Cover Texts, and
+ no Back-Cover Texts. A copy of the license is included in the
+ section entitled "GNU Free Documentation License".
+
+INFO-DIR-SECTION Emacs
+START-INFO-DIR-ENTRY
+* Ivy: (ivy). Using Ivy for completion.
+END-INFO-DIR-ENTRY
+
+
+File: ivy.info, Node: Top, Next: Introduction, Up: (dir)
+
+Ivy User Manual
+***************
+
+* Menu:
+
+* Introduction::
+* Installation::
+* Getting started::
+* Key bindings::
+* Completion Styles::
+* Customization::
+* Commands::
+* API::
+* Variable Index::
+* Keystroke Index::
+
+— The Detailed Node Listing —
+
+Installation
+
+* Installing from Emacs Package Manager::
+* Installing from the Git repository::
+
+Getting started
+
+* Basic customization::
+
+Key bindings
+
+* Global key bindings::
+* Minibuffer key bindings::
+
+Minibuffer key bindings
+
+* Key bindings for navigation::
+* Key bindings for single selection, action, then exit minibuffer: Key bindings for single selection action then exit minibuffer.
+* Key bindings for multiple selections and actions, keep minibuffer open: Key bindings for multiple selections and actions keep minibuffer open.
+* Key bindings that alter the minibuffer input::
+* Other key bindings::
+* Hydra in the minibuffer::
+* Saving the current completion session to a buffer::
+
+Completion Styles
+
+* ivy--regex-plus::
+* ivy--regex-ignore-order::
+* ivy--regex-fuzzy::
+
+Customization
+
+* Faces::
+* Defcustoms::
+* Actions::
+* Packages::
+
+Actions
+
+* What are actions?::
+* How can different actions be called?::
+* How to modify the actions list?::
+* Example - add two actions to each command::
+* Example - define a new command with several actions::
+
+Example - add two actions to each command
+
+* How to undo adding the two actions::
+* How to add actions to a specific command::
+
+Example - define a new command with several actions
+
+* Test the above function with ivy-occur::
+
+Commands
+
+* File Name Completion::
+* Buffer Name Completion::
+* Counsel commands::
+
+File Name Completion
+
+* Using TRAMP::
+
+API
+
+* Required arguments for ivy-read::
+* Optional arguments for ivy-read::
+* Example - counsel-describe-function::
+* Example - counsel-locate::
+* Example - ivy-read-with-extra-properties::
+
+
+
+File: ivy.info, Node: Introduction, Next: Installation, Prev: Top, Up: Top
+
+1 Introduction
+**************
+
+Ivy is for quick and easy selection from a list. When Emacs prompts for
+a string from a list of several possible choices, Ivy springs into
+action to assist in narrowing and picking the right string from a vast
+number of choices.
+
+ Ivy strives for minimalism, simplicity, customizability and
+discoverability.
+
+Minimalism
+..........
+
+ Uncluttered minibuffer is minimalism. Ivy shows the completion
+ defaults, the number of matches, and 10 candidate matches below the
+ input line. Customize ‘ivy-height’ to adjust the number of
+ candidate matches displayed in the minibuffer.
+
+Simplicity
+..........
+
+ Simplicity is about Ivy’s behavior in the minibuffer. It is also
+ about the code interface to extend Ivy’s functionality. The
+ minibuffer area behaves as close to ‘fundamental-mode’ as possible.
+ ‘SPC’ inserts a space, for example, instead of being bound to the
+ more complex ‘minibuffer-complete-word’. Ivy’s code uses
+ easy-to-examine global variables; avoids needless complications
+ with branch-introducing custom macros.
+
+Customizability
+...............
+
+ Customizability is about being able to use different methods and
+ interfaces of completion to tailor the selection process. For
+ example, adding a custom display function that points to a selected
+ candidate with ‘>’, instead of highlighting the selected candidate
+ with the ‘ivy-current-match’ face (see
+ ‘ivy-format-functions-alist’). Or take the customization of
+ actions, say after the candidate function is selected. ‘RET’ uses
+ ‘counsel-describe-function’ to describe the function, whereas ‘M-o
+ d’ jumps to that function’s definition in the code. The ‘M-o’
+ prefix can be uniformly used with characters like ‘d’ to group
+ similar actions.
+
+Discoverability
+...............
+
+ Ivy displays easily discoverable commands through the hydra
+ facility. ‘C-o’ in the minibuffer displays a hydra menu. It opens
+ up within an expanded minibuffer area. Each menu item comes with
+ short documentation strings and highlighted one-key completions.
+ So discovering even seldom used keys is simply a matter of ‘C-o’ in
+ the minibuffer while in the midst of the Ivy interaction. This
+ discoverability minimizes exiting Ivy interface for documentation
+ look-ups.
+
+
+File: ivy.info, Node: Installation, Next: Getting started, Prev: Introduction, Up: Top
+
+2 Installation
+**************
+
+Install Ivy automatically through Emacs’s package manager, or manually
+from Ivy’s development repository.
+
+ Emacs 24.3 is the oldest version to run Ivy. Emacs 24.4 is the
+oldest version that runs Ivy with fancy faces display.
+
+* Menu:
+
+* Installing from Emacs Package Manager::
+* Installing from the Git repository::
+
+
+File: ivy.info, Node: Installing from Emacs Package Manager, Next: Installing from the Git repository, Up: Installation
+
+2.1 Installing from Emacs Package Manager
+=========================================
+
+‘M-x’ ‘package-install’ ‘RET’ ‘counsel’ ‘RET’
+
+ Ivy is installed alongside the ‘counsel’ package, which is available
+from two different package archives, GNU ELPA and MELPA. For the latest
+stable version, use the GNU ELPA archive. For the latest development
+snaphshot, use the GNU-devel ELPA archive.
+
+ Ivy is split into three packages: ‘ivy’, ‘swiper’ and ‘counsel’; by
+installing ‘counsel’, the other two are brought in as dependencies. If
+you are not interested in the extra functionality provided by ‘swiper’
+and ‘counsel’, you can install only ‘ivy’.
+
+ See the code below for adding GNU-devel ELPA to your list of package
+archives:
+
+ (require 'package)
+ (add-to-list 'package-archives
+ '("gnu-devel" . "https://elpa.gnu.org/devel/"))
+
+ After this do ‘M-x’ ‘package-refresh-contents’ ‘RET’, followed by
+‘M-x’ ‘package-install’ ‘RET’ ‘counsel’ ‘RET’.
+
+ For package manager details, see *note (emacs)Packages::.
+
+
+File: ivy.info, Node: Installing from the Git repository, Prev: Installing from Emacs Package Manager, Up: Installation
+
+2.2 Installing from the Git repository
+======================================
+
+Why install from Git?
+.....................
+
+ • No need to wait for GNU ELPA / MELPA builds
+ • Easy to revert to previous versions
+ • Contribute to Ivy’s development; send patches; pull requests
+
+Configuration steps
+...................
+
+ First clone the Swiper repository with:
+
+ cd ~/git && git clone https://github.com/abo-abo/swiper
+ cd swiper && make compile
+
+ Second, add these lines to the Emacs init file:
+
+ (add-to-list 'load-path "~/git/swiper/")
+ (require 'ivy)
+
+ Then, update the code with:
+
+ git pull
+ make
+
+
+File: ivy.info, Node: Getting started, Next: Key bindings, Prev: Installation, Up: Top
+
+3 Getting started
+*****************
+
+First enable Ivy completion everywhere:
+
+ (ivy-mode 1)
+
+ Note: ‘ivy-mode’ can be toggled on and off with ‘M-x’ ‘ivy-mode’.
+
+* Menu:
+
+* Basic customization::
+
+
+File: ivy.info, Node: Basic customization, Up: Getting started
+
+3.1 Basic customization
+=======================
+
+Here are some basic settings particularly useful for new Ivy users:
+
+ (setq ivy-use-virtual-buffers t)
+ (setq ivy-count-format "(%d/%d) ")
+
+ If you want, you can go without any customizations at all. The above
+settings are the most bang for the buck in terms of customization. So
+users that typically don’t like customize a lot are advised to look at
+these settings first.
+
+ For more advanced customizations, refer to ‘M-x describe-variable’
+documentation.
+
+
+File: ivy.info, Node: Key bindings, Next: Completion Styles, Prev: Getting started, Up: Top
+
+4 Key bindings
+**************
+
+* Menu:
+
+* Global key bindings::
+* Minibuffer key bindings::
+
+
+File: ivy.info, Node: Global key bindings, Next: Minibuffer key bindings, Up: Key bindings
+
+4.1 Global key bindings
+=======================
+
+Here is a list of commands that are useful to be bound globally, along
+with some sample bindings:
+
+Ivy-based interface to standard commands
+........................................
+
+ (global-set-key (kbd "C-s") 'swiper-isearch)
+ (global-set-key (kbd "M-x") 'counsel-M-x)
+ (global-set-key (kbd "C-x C-f") 'counsel-find-file)
+ (global-set-key (kbd "M-y") 'counsel-yank-pop)
+ (global-set-key (kbd "<f1> f") 'counsel-describe-function)
+ (global-set-key (kbd "<f1> v") 'counsel-describe-variable)
+ (global-set-key (kbd "<f1> l") 'counsel-find-library)
+ (global-set-key (kbd "<f2> i") 'counsel-info-lookup-symbol)
+ (global-set-key (kbd "<f2> u") 'counsel-unicode-char)
+ (global-set-key (kbd "<f2> j") 'counsel-set-variable)
+ (global-set-key (kbd "C-x b") 'ivy-switch-buffer)
+ (global-set-key (kbd "C-c v") 'ivy-push-view)
+ (global-set-key (kbd "C-c V") 'ivy-pop-view)
+
+Ivy-based interface to shell and system tools
+.............................................
+
+ (global-set-key (kbd "C-c c") 'counsel-compile)
+ (global-set-key (kbd "C-c g") 'counsel-git)
+ (global-set-key (kbd "C-c j") 'counsel-git-grep)
+ (global-set-key (kbd "C-c L") 'counsel-git-log)
+ (global-set-key (kbd "C-c k") 'counsel-rg)
+ (global-set-key (kbd "C-c m") 'counsel-linux-app)
+ (global-set-key (kbd "C-c n") 'counsel-fzf)
+ (global-set-key (kbd "C-x l") 'counsel-locate)
+ (global-set-key (kbd "C-c J") 'counsel-file-jump)
+ (global-set-key (kbd "C-S-o") 'counsel-rhythmbox)
+ (global-set-key (kbd "C-c w") 'counsel-wmctrl)
+
+Ivy-resume and other commands
+.............................
+
+ ‘ivy-resume’ resumes the last Ivy-based completion.
+
+ (global-set-key (kbd "C-c C-r") 'ivy-resume)
+ (global-set-key (kbd "C-c b") 'counsel-bookmark)
+ (global-set-key (kbd "C-c d") 'counsel-descbinds)
+ (global-set-key (kbd "C-c g") 'counsel-git)
+ (global-set-key (kbd "C-c o") 'counsel-outline)
+ (global-set-key (kbd "C-c t") 'counsel-load-theme)
+ (global-set-key (kbd "C-c F") 'counsel-org-file)
+
+ You can also enable ‘counsel-mode’ to make some global key binding
+remapping for you.
+
+
+File: ivy.info, Node: Minibuffer key bindings, Prev: Global key bindings, Up: Key bindings
+
+4.2 Minibuffer key bindings
+===========================
+
+Ivy includes several minibuffer bindings, which are defined in the
+‘ivy-minibuffer-map’ keymap variable. The most frequently used ones are
+described here.
+
+ ‘swiper’ or ‘counsel-M-x’ add more key bindings through the ‘keymap’
+argument to ‘ivy-read’. These keys, also active in the minibuffer, are
+described under their respective commands.
+
+ A key feature of ‘ivy-minibuffer-map’ is its full editing capability
+where the familiar ‘C-a’, ‘C-f’, ‘M-d’, ‘M-DEL’, ‘M-b’, ‘M-w’, ‘C-k’,
+‘C-y’ key bindings work the same as in ‘fundamental-mode’.
+
+* Menu:
+
+* Key bindings for navigation::
+* Key bindings for single selection, action, then exit minibuffer: Key bindings for single selection action then exit minibuffer.
+* Key bindings for multiple selections and actions, keep minibuffer open: Key bindings for multiple selections and actions keep minibuffer open.
+* Key bindings that alter the minibuffer input::
+* Other key bindings::
+* Hydra in the minibuffer::
+* Saving the current completion session to a buffer::
+
+
+File: ivy.info, Node: Key bindings for navigation, Next: Key bindings for single selection action then exit minibuffer, Up: Minibuffer key bindings
+
+4.2.1 Key bindings for navigation
+---------------------------------
+
+ • ‘C-n’ (‘ivy-next-line’) selects the next candidate
+ • ‘C-p’ (‘ivy-previous-line’) selects the previous candidate
+ • ‘M-<’ (‘ivy-beginning-of-buffer’) selects the first candidate
+ • ‘M->’ (‘ivy-end-of-buffer’) selects the last candidate
+ • ‘C-v’ (‘ivy-scroll-up-command’) scrolls up by ‘ivy-height’ lines
+ • ‘M-v’ (‘ivy-scroll-down-command’) scrolls down by ‘ivy-height’
+ lines
+
+ -- User Option: ivy-wrap
+ Specifies the wrap-around behavior for ‘C-n’ and ‘C-p’. When
+ ‘ivy-wrap’ is set to ‘t’, ‘ivy-next-line’ and ‘ivy-previous-line’
+ will cycle past the last and the first candidates respectively.
+
+ Wrap-around behavior is off by default.
+
+ -- User Option: ivy-height
+ Use this option to adjust the minibuffer height, which also affects
+ scroll size when using ‘C-v’ and ‘M-v’ key bindings.
+
+ ‘ivy-height’ is 10 lines by default.
+
+
+File: ivy.info, Node: Key bindings for single selection action then exit minibuffer, Next: Key bindings for multiple selections and actions keep minibuffer open, Prev: Key bindings for navigation, Up: Minibuffer key bindings
+
+4.2.2 Key bindings for single selection, action, then exit minibuffer
+---------------------------------------------------------------------
+
+Ivy can offer several actions from which to choose which action to run.
+This "calling an action" operates on the selected candidate. For
+example, when viewing a list of files, one action could open it for
+editing, one to view it, another to invoke a special function, and so
+on. Custom actions can be added to this interface. The precise action
+to call on the selected candidate can be delayed until after the
+narrowing is completed. No need to exit the interface if unsure which
+action to run. This delayed flexibility and customization of actions
+extends usability of lists in Emacs.
+
+‘C-m’ or ‘RET’ (‘ivy-done’)
+...........................
+
+ Calls the default action and then exits the minibuffer.
+
+‘M-o’ (‘ivy-dispatching-done’)
+..............................
+
+ Presents valid actions from which to choose. When only one action
+ is available, there is no difference between ‘M-o’ and ‘C-m’.
+
+‘C-j’ (‘ivy-alt-done’)
+......................
+
+ When completing file names, selects the current directory candidate
+ and starts a new completion session there. Otherwise, it is the
+ same as ‘ivy-done’.
+
+‘TAB’ (‘ivy-partial-or-done’)
+.............................
+
+ Attempts partial completion, extending current input as much as
+ possible. ‘TAB TAB’ is the same as ‘C-j’ (‘ivy-alt-done’).
+
+ Example ERT test:
+
+ (should
+ (equal (ivy-with
+ '(progn
+ (ivy-read "Test: " '("can do" "can't, sorry" "other"))
+ ivy-text)
+ "c <tab>")
+ "can"))
+
+‘C-M-j’ (‘ivy-immediate-done’)
+..............................
+
+ Exits with _the current input_ instead of _the current candidate_
+ (like other commands).
+
+ This is useful e.g. when you call ‘find-file’ to create a new
+ file, but the desired name matches an existing file. In that case,
+ using ‘C-j’ would select that existing file, which isn’t what you
+ want - use this command instead.
+
+‘C-'’ (‘ivy-avy’)
+.................
+
+ Uses avy to select one of the candidates on the current candidate
+ page. This can often be faster than multiple ‘C-n’ or ‘C-p’
+ keystrokes followed by ‘C-m’.
+
+
+File: ivy.info, Node: Key bindings for multiple selections and actions keep minibuffer open, Next: Key bindings that alter the minibuffer input, Prev: Key bindings for single selection action then exit minibuffer, Up: Minibuffer key bindings
+
+4.2.3 Key bindings for multiple selections and actions, keep minibuffer open
+----------------------------------------------------------------------------
+
+For repeatedly applying multiple actions or acting on multiple
+candidates, Ivy does not close the minibuffer between commands. It
+keeps the minibuffer open for applying subsequent actions.
+
+ Adding an extra meta key to the normal key chord invokes the special
+version of the regular commands that enables applying multiple actions.
+
+ Note that these operations are supported only by completion sessions
+that use the ‘ivy-read’ API, rather than the built-in ‘completing-read’.
+
+‘C-M-m’ (‘ivy-call’)
+....................
+
+ Is the non-exiting version of ‘C-m’ (‘ivy-done’).
+
+ Instead of closing the minibuffer, ‘C-M-m’ allows selecting another
+ candidate or another action. For example, ‘C-M-m’ on functions
+ list invokes ‘describe-function’. When combined with ‘C-n’,
+ function descriptions can be invoked quickly in succession.
+
+‘C-M-o’ (‘ivy-dispatching-call’)
+................................
+
+ Is the non-exiting version of ‘M-o’ (‘ivy-dispatching-done’).
+
+ For example, during the ‘counsel-rhythmbox’ completion, press
+ ‘C-M-o e’ to en-queue the selected candidate, followed by ‘C-n C-m’
+ to play the next candidate - the current action reverts to the
+ default one after ‘C-M-o’.
+
+‘C-M-n’ (‘ivy-next-line-and-call’)
+..................................
+
+ Combines ‘C-n’ and ‘C-M-m’. Moves to next line and applies an
+ action.
+
+ Comes in handy when opening multiple files from
+ ‘counsel-find-file’, ‘counsel-git-grep’, ‘counsel-ag’,
+ ‘counsel-rg’, or ‘counsel-locate’ lists. Just hold ‘C-M-n’ for
+ rapid-fire default action on each successive element of the list.
+
+‘C-M-p’ (‘ivy-previous-line-and-call’)
+......................................
+
+ Combines ‘C-p’ and ‘C-M-m’.
+
+ Similar to the above except it moves through the list in the other
+ direction.
+
+‘ivy-resume’
+............
+
+ Recalls the state of the completion session just before its last
+ exit.
+
+ Useful after an accidental ‘C-m’ (‘ivy-done’). Use it with
+ ‘universal-argument’ to resume any previous session.
+
+
+File: ivy.info, Node: Key bindings that alter the minibuffer input, Next: Other key bindings, Prev: Key bindings for multiple selections and actions keep minibuffer open, Up: Minibuffer key bindings
+
+4.2.4 Key bindings that alter the minibuffer input
+--------------------------------------------------
+
+‘M-n’ (‘ivy-next-history-element’)
+..................................
+
+ Cycles forward through the Ivy command history.
+
+ Ivy updates an internal history list after each action. When this
+ history list is empty, ‘M-n’ inserts symbol (or URL) at point into
+ the minibuffer.
+
+‘M-p’ (‘ivy-previous-history-element’)
+......................................
+
+ Cycles backwards through the Ivy command history.
+
+‘M-i’ (‘ivy-insert-current’)
+............................
+
+ Inserts the current candidate into the minibuffer.
+
+ Useful for copying and renaming files, for example: ‘M-i’ to insert
+ the original file name string, edit it, and then ‘C-m’ to complete
+ the renaming.
+
+‘M-j’ (‘ivy-yank-word’)
+.......................
+
+ Inserts the sub-word at point into the minibuffer.
+
+ This is similar to ‘C-s C-w’ with ‘isearch’. Ivy reserves ‘C-w’
+ for ‘kill-region’. See also ‘ivy-yank-symbol’ and ‘ivy-yank-char’.
+
+‘S-SPC’ (‘ivy-restrict-to-matches’)
+...................................
+
+ Deletes the current input, and resets the candidates list to the
+ currently restricted matches.
+
+ This is how Ivy provides narrowing in successive tiers.
+
+‘C-r’ (‘ivy-reverse-i-search’)
+..............................
+
+ Starts a recursive completion session through the command’s
+ history.
+
+ This works just like ‘C-r’ at the bash command prompt, where the
+ completion candidates are the history items. Upon completion, the
+ selected candidate string is inserted into the minibuffer.
+
+
+File: ivy.info, Node: Other key bindings, Next: Hydra in the minibuffer, Prev: Key bindings that alter the minibuffer input, Up: Minibuffer key bindings
+
+4.2.5 Other key bindings
+------------------------
+
+‘M-w’ (‘ivy-kill-ring-save’)
+............................
+
+ Copies selected candidates to the kill ring.
+
+ Copies the region if the region is active.
+
+
+File: ivy.info, Node: Hydra in the minibuffer, Next: Saving the current completion session to a buffer, Prev: Other key bindings, Up: Minibuffer key bindings
+
+4.2.6 Hydra in the minibuffer
+-----------------------------
+
+‘C-o’ (‘hydra-ivy/body’)
+........................
+
+ Invokes the hydra menu with short key bindings.
+
+ When Hydra is active, minibuffer editing is disabled and menus
+display short aliases:
+
+Short Normal Command name
+------------------------------------------------
+‘o’ ‘C-g’ ‘keyboard-escape-quit’
+‘j’ ‘C-n’ ‘ivy-next-line’
+‘k’ ‘C-p’ ‘ivy-previous-line’
+‘h’ ‘M-<’ ‘ivy-beginning-of-buffer’
+‘l’ ‘M->’ ‘ivy-end-of-buffer’
+‘d’ ‘C-m’ ‘ivy-done’
+‘f’ ‘C-j’ ‘ivy-alt-done’
+‘g’ ‘C-M-m’ ‘ivy-call’
+‘u’ ‘C-c C-o’ ‘ivy-occur’
+
+ Hydra reduces key strokes, for example: ‘C-n C-n C-n C-n’ is ‘C-o
+jjjj’ in Hydra.
+
+ Hydra menu offers these additional bindings:
+
+‘c’ (‘ivy-toggle-calling’)
+..........................
+
+ Toggle calling the action after each candidate change. It modifies
+ ‘j’ to ‘jg’, ‘k’ to ‘kg’ etc.
+
+‘M’ (‘ivy-rotate-preferred-builders’)
+.....................................
+
+ Rotate the current regexp matcher.
+
+‘>’ (‘ivy-minibuffer-grow’)
+...........................
+
+ Increase ‘ivy-height’ for the current minibuffer.
+
+‘<’ (‘ivy-minibuffer-shrink’)
+.............................
+
+ Decrease ‘ivy-height’ for the current minibuffer.
+
+‘w’ (‘ivy-prev-action’)
+.......................
+
+ Select the previous action.
+
+‘s’ (‘ivy-next-action’)
+.......................
+
+ Select the next action.
+
+‘a’ (‘ivy-read-action’)
+.......................
+
+ Use a menu to select an action.
+
+‘C’ (‘ivy-toggle-case-fold’)
+............................
+
+ Toggle case folding (match both upper and lower case characters for
+ lower case input).
+
+ Hydra menu also offers bindings for marking multiple candidates:
+
+Key Command name
+--------------------------------
+‘m’ ‘ivy-mark’
+‘u’ ‘ivy-unmark’
+‘DEL’ ‘ivy-unmark-backward’
+‘t’ ‘ivy-toggle-marks’
+
+ The action is called on each marked candidate one by one.
+
+
+File: ivy.info, Node: Saving the current completion session to a buffer, Prev: Hydra in the minibuffer, Up: Minibuffer key bindings
+
+4.2.7 Saving the current completion session to a buffer
+-------------------------------------------------------
+
+‘C-c C-o’ (‘ivy-occur’)
+.......................
+
+ Saves the current candidates to a new buffer and exits completion.
+
+ The new buffer is read-only and has a few useful bindings defined.
+
+‘RET’ or ‘f’ (‘ivy-occur-press’)
+................................
+
+ Call the current action on the selected candidate.
+
+‘mouse-1’ (‘ivy-occur-click’)
+.............................
+
+ Call the current action on the selected candidate.
+
+‘j’ (‘next-line’)
+.................
+
+ Move to next line.
+
+‘k’ (‘previous-line’)
+.....................
+
+ Move to previous line.
+
+‘a’ (‘ivy-occur-read-action’)
+.............................
+
+ Read an action and make it current for this buffer.
+
+‘o’ (‘ivy-occur-dispatch’)
+..........................
+
+ Read an action and call it on the selected candidate.
+
+‘q’ (‘quit-window’)
+...................
+
+ Bury the current buffer.
+
+ Ivy has no limit on the number of active buffers like these.
+
+ Ivy takes care of naming buffers uniquely by constructing descriptive
+names. For example: ‘*ivy-occur counsel-describe-variable "function$*’.
+
+
+File: ivy.info, Node: Completion Styles, Next: Customization, Prev: Key bindings, Up: Top
+
+5 Completion Styles
+*******************
+
+Ivy’s completion functions rely on a regex builder - a function that
+transforms a string input to a string regex. All current candidates
+simply have to match this regex. Each collection can be assigned its
+own regex builder by customizing ‘ivy-re-builders-alist’.
+
+ The keys of this alist are collection names, and the values are one
+of the following:
+ • ‘ivy--regex’
+ • ‘ivy--regex-plus’
+ • ‘ivy--regex-ignore-order’
+ • ‘ivy--regex-fuzzy’
+ • ‘regexp-quote’
+
+ A catch-all key, ‘t’, applies to all collections that don’t have
+their own key.
+
+ The default is:
+
+ (setq ivy-re-builders-alist
+ '((t . ivy--regex-plus)))
+
+ This example shows a custom regex builder assigned to file name
+completion:
+
+ (setq ivy-re-builders-alist
+ '((read-file-name-internal . ivy--regex-fuzzy)
+ (t . ivy--regex-plus)))
+
+ Here, ‘read-file-name-internal’ is a function that is passed as the
+second argument to ‘completing-read’ for file name completion.
+
+ The regex builder resolves as follows (in order of priority):
+ 1. ‘re-builder’ argument passed to ‘ivy-read’.
+ 2. ‘collection’ argument passed to ‘ivy-read’ is a function and has an
+ entry on ‘ivy-re-builders-alist’.
+ 3. ‘caller’ argument passed to ‘ivy-read’ has an entry on
+ ‘ivy-re-builders-alist’.
+ 4. ‘this-command’ has an entry on ‘ivy-re-builders-alist’.
+ 5. ‘t’ has an entry on ‘ivy-re-builders-alist’.
+ 6. ‘ivy--regex’.
+
+* Menu:
+
+* ivy--regex-plus::
+* ivy--regex-ignore-order::
+* ivy--regex-fuzzy::
+
+
+File: ivy.info, Node: ivy--regex-plus, Next: ivy--regex-ignore-order, Up: Completion Styles
+
+5.1 ivy–regex-plus
+==================
+
+‘ivy--regex-plus’ is Ivy’s default completion method.
+
+ ‘ivy--regex-plus’ matches by splitting the input by spaces and
+rebuilding it into a regex.
+
+ As the search string is typed in Ivy’s minibuffer, it is transformed
+into valid regex syntax. If the string is ‘"for example"’, it is
+transformed into
+
+ "\\(for\\).*\\(example\\)"
+
+ which in regex terminology matches ‘"for"’ followed by a wild card
+and then ‘"example"’. Note how Ivy uses the space character to build
+wild cards. To match a literal white space, use an extra space. So to
+match one space type two spaces, to match two spaces type three spaces,
+and so on.
+
+ As Ivy transforms typed characters into regex strings, it provides an
+intuitive feedback through font highlights.
+
+ Ivy supports regexp negation with ‘"!"’. For example, ‘"define key !
+ivy quit"’ first selects everything matching ‘"define.*key"’, then
+removes everything matching ‘"ivy"’, and finally removes everything
+matching ‘"quit"’. What remains is the final result set of the negation
+regexp.
+
+ Since Ivy treats minibuffer input as a regexp, the standard regexp
+identifiers work: ‘"^"’, ‘"$"’, ‘"\b"’ or ‘"[a-z]"’. The exceptions are
+spaces, which translate to ‘".*"’, and ‘"!"’ that signal the beginning
+of a negation group.
+
+
+File: ivy.info, Node: ivy--regex-ignore-order, Next: ivy--regex-fuzzy, Prev: ivy--regex-plus, Up: Completion Styles
+
+5.2 ivy–regex-ignore-order
+==========================
+
+‘ivy--regex-ignore-order’ ignores the order of regexp tokens when
+searching for matching candidates. For instance, the input ‘"for
+example"’ will match ‘"example test for"’.
+
+
+File: ivy.info, Node: ivy--regex-fuzzy, Prev: ivy--regex-ignore-order, Up: Completion Styles
+
+5.3 ivy–regex-fuzzy
+===================
+
+‘ivy--regex-fuzzy’ splits each character with a wild card. Searching
+for ‘"for"’ returns all ‘"f.*o.*r"’ matches, resulting in a large number
+of hits. Yet some searches need these extra hits. Ivy sorts such large
+lists using ‘flx’ package’s scoring mechanism, if it’s installed.
+
+ ‘C-o m’ toggles the current regexp builder.
+
+
+File: ivy.info, Node: Customization, Next: Commands, Prev: Completion Styles, Up: Top
+
+6 Customization
+***************
+
+* Menu:
+
+* Faces::
+* Defcustoms::
+* Actions::
+* Packages::
+
+
+File: ivy.info, Node: Faces, Next: Defcustoms, Up: Customization
+
+6.1 Faces
+=========
+
+‘ivy-current-match’
+...................
+
+ Highlights the currently selected candidate.
+
+‘ivy-minibuffer-match-face-1’
+.............................
+
+ Highlights the background of the match.
+
+‘ivy-minibuffer-match-face-2’
+.............................
+
+ Highlights the first (modulo 3) matched group.
+
+‘ivy-minibuffer-match-face-3’
+.............................
+
+ Highlights the second (modulo 3) matched group.
+
+‘ivy-minibuffer-match-face-4’
+.............................
+
+ Highlights the third (modulo 3) matched group.
+
+‘ivy-confirm-face’
+..................
+
+ Highlights the "(confirm)" part of the prompt.
+
+ When ‘confirm-nonexistent-file-or-buffer’ set to ‘t’, then
+ confirming non-existent files in ‘ivy-mode’ requires an additional
+ ‘RET’.
+
+ The confirmation prompt will use this face.
+
+ For example:
+
+ (setq confirm-nonexistent-file-or-buffer t)
+
+ Then call ‘find-file’, enter "eldorado" and press ‘RET’ - the
+ prompt will be appended with "(confirm)". Press ‘RET’ once more to
+ confirm, or any key to continue the completion.
+
+‘ivy-match-required-face’
+.........................
+
+ Highlights the "(match required)" part of the prompt.
+
+ When completions have to match available candidates and cannot take
+ random input, the "(match required)" prompt signals this
+ constraint.
+
+ For example, call ‘describe-variable’, enter "waldo" and press
+ ‘RET’ - "(match required)" is prompted. Press any key for the
+ prompt to disappear.
+
+‘ivy-subdir’
+............
+
+ Highlights directories when completing file names.
+
+‘ivy-remote’
+............
+
+ Highlights remote files when completing file names.
+
+‘ivy-virtual’
+.............
+
+ Highlights virtual buffers when completing buffer names.
+
+ Virtual buffers correspond to bookmarks and recent files list,
+ ‘recentf’.
+
+ Enable virtual buffers with:
+
+ (setq ivy-use-virtual-buffers t)
+
+‘ivy-modified-buffer’
+.....................
+
+ Highlights modified buffers when switching buffer.
+
+‘ivy-modified-outside-buffer’
+.............................
+
+ Highlights buffers modified outside Emacs when switching buffer.
+
+ This takes precedence over ‘ivy-modified-buffer’.
+
+
+File: ivy.info, Node: Defcustoms, Next: Actions, Prev: Faces, Up: Customization
+
+6.2 Defcustoms
+==============
+
+ -- User Option: ivy-count-format
+ A string that specifies display of number of candidates and current
+ candidate, if one exists.
+
+ The number of matching candidates by default is shown as a right-
+ padded integer value.
+
+ To disable showing the number of candidates:
+
+ (setq ivy-count-format "")
+
+ To also display the current candidate:
+
+ (setq ivy-count-format "(%d/%d) ")
+
+ The ‘format’-style switches this variable uses are described in the
+ ‘format’ documentation.
+
+ -- User Option: ivy-display-style
+ Specifies highlighting candidates in the minibuffer.
+
+ The default setting is ‘'fancy’ in Emacs versions 24.4 or newer.
+
+ Set ‘ivy-display-style’ to ‘nil’ for a plain minibuffer.
+
+ -- User Option: ivy-on-del-error-function
+ Specifies what to do when ‘DEL’ (‘ivy-backward-delete-char’) fails.
+
+ This is usually the case when there is no text left to delete,
+ i.e., when ‘DEL’ is typed at the beginning of the minibuffer.
+
+ The default behavior is to quit the completion after ‘DEL’ – a
+ handy key to invoke after mistakenly triggering a completion.
+
+ Another common option is ‘ignore’, which does nothing.
+
+
+File: ivy.info, Node: Actions, Next: Packages, Prev: Defcustoms, Up: Customization
+
+6.3 Actions
+===========
+
+* Menu:
+
+* What are actions?::
+* How can different actions be called?::
+* How to modify the actions list?::
+* Example - add two actions to each command::
+* Example - define a new command with several actions::
+
+
+File: ivy.info, Node: What are actions?, Next: How can different actions be called?, Up: Actions
+
+6.3.1 What are actions?
+-----------------------
+
+An action is a function that is called after you select a candidate
+during completion. This function takes a single string argument, which
+is the selected candidate.
+
+Window context when calling an action
+.....................................
+
+ Currently, the action is executed in the minibuffer window context.
+ This means e.g. that if you call ‘insert’ the text will be
+ inserted into the minibuffer.
+
+ If you want to execute the action in the initial window from which
+ the completion started, use the ‘with-ivy-window’ wrapper macro.
+
+ (defun ivy-insert-action (x)
+ (with-ivy-window
+ (insert x)))
+
+
+File: ivy.info, Node: How can different actions be called?, Next: How to modify the actions list?, Prev: What are actions?, Up: Actions
+
+6.3.2 How can different actions be called?
+------------------------------------------
+
+ • ‘C-m’ (‘ivy-done’) calls the current action.
+ • ‘M-o’ (‘ivy-dispatching-done’) presents available actions for
+ selection, calls it after selection, and then exits.
+ • ‘C-M-o’ (‘ivy-dispatching-call’) presents available actions for
+ selection, calls it after selection, and then does not exit.
+
+
+File: ivy.info, Node: How to modify the actions list?, Next: Example - add two actions to each command, Prev: How can different actions be called?, Up: Actions
+
+6.3.3 How to modify the actions list?
+-------------------------------------
+
+Currently, you can append any amount of your own actions to the default
+list of actions. This can be done either for a specific command, or for
+all commands at once.
+
+ Usually, the command has only one default action. The convention is
+to use single letters when selecting a command, and the letter ‘o’ is
+designated for the default command. This way, ‘M-o o’ should be always
+equivalent to ‘C-m’.
+
+
+File: ivy.info, Node: Example - add two actions to each command, Next: Example - define a new command with several actions, Prev: How to modify the actions list?, Up: Actions
+
+6.3.4 Example - add two actions to each command
+-----------------------------------------------
+
+The first action inserts the current candidate into the Ivy window - the
+window from which ‘ivy-read’ was called.
+
+ The second action copies the current candidate to the kill ring.
+
+ (defun ivy-yank-action (x)
+ (kill-new x))
+
+ (defun ivy-copy-to-buffer-action (x)
+ (with-ivy-window
+ (insert x)))
+
+ (ivy-set-actions
+ t
+ '(("i" ivy-copy-to-buffer-action "insert")
+ ("y" ivy-yank-action "yank")))
+
+ Then in any completion session, ‘M-o y’ invokes ‘ivy-yank-action’,
+and ‘M-o i’ invokes ‘ivy-copy-to-buffer-action’.
+
+* Menu:
+
+* How to undo adding the two actions::
+* How to add actions to a specific command::
+
+
+File: ivy.info, Node: How to undo adding the two actions, Next: How to add actions to a specific command, Up: Example - add two actions to each command
+
+6.3.4.1 How to undo adding the two actions
+..........................................
+
+Since ‘ivy-set-actions’ modifies the internal dictionary with new data,
+set the extra actions list to ‘nil’ by assigning ‘nil’ value to the ‘t’
+key as follows:
+
+ (ivy-set-actions t nil)
+
+
+File: ivy.info, Node: How to add actions to a specific command, Prev: How to undo adding the two actions, Up: Example - add two actions to each command
+
+6.3.4.2 How to add actions to a specific command
+................................................
+
+Use the command name as the key:
+
+ (ivy-set-actions
+ 'swiper
+ '(("i" ivy-copy-to-buffer-action "insert")
+ ("y" ivy-yank-action "yank")))
+
+
+File: ivy.info, Node: Example - define a new command with several actions, Prev: Example - add two actions to each command, Up: Actions
+
+6.3.5 Example - define a new command with several actions
+---------------------------------------------------------
+
+ (defun my-action-1 (x)
+ (message "action-1: %s" x))
+
+ (defun my-action-2 (x)
+ (message "action-2: %s" x))
+
+ (defun my-action-3 (x)
+ (message "action-3: %s" x))
+
+ (defun my-command-with-3-actions ()
+ (interactive)
+ (ivy-read "test: " '("foo" "bar" "baz")
+ :action '(1
+ ("o" my-action-1 "action 1")
+ ("j" my-action-2 "action 2")
+ ("k" my-action-3 "action 3"))))
+
+ The number 1 above is the index of the default action. Each action
+has its own string description for easy selection.
+
+* Menu:
+
+* Test the above function with ivy-occur::
+
+
+File: ivy.info, Node: Test the above function with ivy-occur, Up: Example - define a new command with several actions
+
+6.3.5.1 Test the above function with ‘ivy-occur’
+................................................
+
+To examine each action with each candidate in a key-efficient way, try:
+
+ • Call ‘my-command-with-3-actions’
+ • Press ‘C-c C-o’ to close the completion window and move to an
+ ivy-occur buffer
+ • Press ‘kkk’ to move to the first candidate, since the point is most
+ likely at the end of the buffer
+ • Press ‘oo’ to call the first action
+ • Press ‘oj’ and ‘ok’ to call the second and the third actions
+ • Press ‘j’ to move to the next candidate
+ • Press ‘oo’, ‘oj’, ‘ok’
+ • Press ‘j’ to move to the next candidate
+ • and so on...
+
+
+File: ivy.info, Node: Packages, Prev: Actions, Up: Customization
+
+6.4 Packages
+============
+
+‘org-mode’
+..........
+
+ ‘org-mode’ versions 8.3.3 or later obey ‘completing-read-function’
+ (which ‘ivy-mode’ sets). Try refiling headings with similar names
+ to appreciate ‘ivy-mode’.
+
+‘magit’
+.......
+
+ Uses ivy by default if Ivy is installed.
+
+‘find-file-in-project’
+......................
+
+ Uses ivy by default if Ivy is installed.
+
+‘projectile’
+............
+
+ Projectile requires this setting for ivy completion:
+
+ (setq projectile-completion-system 'ivy)
+
+‘helm-make’
+...........
+
+ Helm-make requires this setting for ivy completion.
+
+ (setq helm-make-completion-method 'ivy)
+
+automatically integrated packages
+.................................
+
+ Ivy re-uses the following packages if they are installed: ‘avy’,
+ ‘amx’ or ‘smex’, ‘flx’, and ‘wgrep’.
+
+
+File: ivy.info, Node: Commands, Next: API, Prev: Customization, Up: Top
+
+7 Commands
+**********
+
+* Menu:
+
+* File Name Completion::
+* Buffer Name Completion::
+* Counsel commands::
+
+
+File: ivy.info, Node: File Name Completion, Next: Buffer Name Completion, Up: Commands
+
+7.1 File Name Completion
+========================
+
+Since file name completion is ubiquitous, Ivy provides extra bindings
+that work here:
+
+‘C-j’ (‘ivy-alt-done’)
+......................
+
+ On a directory, restarts completion from that directory.
+
+ On a file or ‘./’, exit completion with the selected candidate.
+
+‘DEL’ (‘ivy-backward-delete-char’)
+..................................
+
+ Restart the completion in the parent directory if current input is
+ empty.
+
+‘//’ (‘self-insert-command’)
+............................
+
+ Switch to the root directory.
+
+‘~’ (‘self-insert-command’)
+...........................
+
+ Switch to the home directory.
+
+‘/’ (‘self-insert-command’)
+...........................
+
+ If the current input matches an existing directory name exactly,
+ switch the completion to that directory.
+
+‘C-M-y’ (‘ivy-insert-current-full’)
+...................................
+
+ Insert the current full path, in case you want to edit a part of
+ it.
+
+‘M-r’ (‘ivy-toggle-regexp-quote’)
+.................................
+
+ Toggle between input as regexp or not.
+
+ Switch to matching literally since file names include ‘.’, which is
+ for matching any char in regexp mode.
+ -- User Option: ivy-extra-directories
+ Decide if you want to see ‘../’ and ‘./’ during file name
+ completion.
+
+ Reason to remove: ‘../’ is the same as ‘DEL’.
+
+ Reason not to remove: navigate anywhere with only ‘C-n’, ‘C-p’ and
+ ‘C-j’.
+
+ Likewise, ‘./’ can be removed.
+
+History
+.......
+
+ File history works the same with ‘M-p’, ‘M-n’, and ‘C-r’, but uses
+ a custom code for file name completion that cycles through files
+ previously opened. It also works with TRAMP files.
+
+* Menu:
+
+* Using TRAMP::
+
+
+File: ivy.info, Node: Using TRAMP, Up: File Name Completion
+
+7.1.1 Using TRAMP
+-----------------
+
+‘~’ (tilde)
+...........
+
+ Move to the home directory. Either the local or the remote one,
+ depending on the current directory. The boolean option
+ ‘ivy-magic-tilde’ decides whether the binding to do this is ‘~’ or
+ ‘~/’.
+
+‘//’ (double slash)
+...................
+
+ Move to the root directory. Either the local or the remote one,
+ depending on the current directory. Here, you can also select a
+ TRAMP connection method, such as ‘ssh’ or ‘scpx’.
+
+‘/ C-j’
+.......
+
+ Move the the local root directory.
+
+‘~~’
+....
+
+ Move to the local home directory.
+
+ From any directory, with the empty input, inputting ‘/ssh:’ and
+pressing ‘C-j’ (or ‘RET’, which is the same thing) completes for host
+and user names.
+
+ For ‘/ssh:user@’ input, completes the domain name.
+
+ ‘C-i’ works in a similar way to the default completion.
+
+ You can also get sudo access for the current directory by inputting
+‘/sudo::’ ‘RET’. Using ‘/sudo:’ (i.e. single colon instead of double)
+will result in a completion session for the desired user.
+
+ Multi-hopping is possible, although a bit complex.
+
+Example : connect to a remote host ‘cloud’ and open a file with ‘sudo’ there
+............................................................................
+
+ • ‘C-x C-f’ ‘/ssh:cloud|sudo:root:/’.
+
+
+File: ivy.info, Node: Buffer Name Completion, Next: Counsel commands, Prev: File Name Completion, Up: Commands
+
+7.2 Buffer Name Completion
+==========================
+
+ -- User Option: ivy-use-virtual-buffers
+ When non-nil, add ‘recentf-mode’ and bookmarks to
+ ‘ivy-switch-buffer’ completion candidates.
+
+ Adding this to Emacs init file:
+
+ (setq ivy-use-virtual-buffers t)
+ will add additional virtual buffers to the buffers list for recent
+ files. Selecting such virtual buffers, which are highlighted with
+ ‘ivy-virtual’ face, will open the corresponding file.
+
+
+File: ivy.info, Node: Counsel commands, Prev: Buffer Name Completion, Up: Commands
+
+7.3 Counsel commands
+====================
+
+The main advantages of ‘counsel-’ functions over their basic equivalents
+in ‘ivy-mode’ are:
+
+ 1. Multi-actions and non-exiting actions work.
+ 2. ‘ivy-resume’ can resume the last completion session.
+ 3. Customize ‘ivy-set-actions’, ‘ivy-re-builders-alist’.
+ 4. Customize individual keymaps, such as ‘counsel-describe-map’,
+ ‘counsel-git-grep-map’, or ‘counsel-find-file-map’, instead of
+ customizing ‘ivy-minibuffer-map’ that applies to all completion
+ sessions.
+
+
+File: ivy.info, Node: API, Next: Variable Index, Prev: Commands, Up: Top
+
+8 API
+*****
+
+The main (and only) entry point is the ‘ivy-read’ function. It takes
+two required arguments and many optional arguments that can be passed by
+a key. The optional ‘:action’ argument is highly recommended for
+features such as multi-actions, non-exiting actions, ‘ivy-occur’ and
+‘ivy-resume’.
+
+* Menu:
+
+* Required arguments for ivy-read::
+* Optional arguments for ivy-read::
+* Example - counsel-describe-function::
+* Example - counsel-locate::
+* Example - ivy-read-with-extra-properties::
+
+
+File: ivy.info, Node: Required arguments for ivy-read, Next: Optional arguments for ivy-read, Up: API
+
+8.1 Required arguments for ‘ivy-read’
+=====================================
+
+‘prompt’
+........
+
+ A prompt string normally ending in a colon and a space.
+ ‘ivy-count-format’ is prepended to it during completion.
+
+‘collection’
+............
+
+ Either a list of strings, a function, an alist or a hash table.
+
+ If a function, then it has to be compatible with ‘all-completions’.
+
+
+File: ivy.info, Node: Optional arguments for ivy-read, Next: Example - counsel-describe-function, Prev: Required arguments for ivy-read, Up: API
+
+8.2 Optional arguments for ‘ivy-read’
+=====================================
+
+‘predicate’
+...........
+
+ Is a function to filter the initial collection. It has to be
+ compatible with ‘all-completions’. Tip: most of the time, it’s
+ simpler to just apply this filter to the ‘collection’ argument
+ itself, e.g. ‘(cl-remove-if-not predicate collection)’.
+
+‘require-match’
+...............
+
+ When set to a non-nil value, input must match one of the
+ candidates. Custom input is not accepted.
+
+‘initial-input’
+...............
+
+ This string argument is included for compatibility with
+ ‘completing-read’, which inserts it into the minibuffer.
+
+ It’s recommended to use the ‘preselect’ argument instead of this.
+
+‘history’
+.........
+
+ Name of the symbol to store history. See ‘completing-read’.
+
+‘preselect’
+...........
+
+ Determines which one of the candidates to initially select.
+
+ When set to an integer value, select the candidate with that index
+ value.
+
+ When set to any other non-nil value, select the first candidate
+ matching this value. Comparison is first done with ‘equal’. If
+ this fails, and when applicable, match ‘preselect’ as a regular
+ expression.
+
+ Every time the input becomes empty, the item corresponding to
+ ‘preselect’ is selected.
+
+‘keymap’
+........
+
+ A keymap to be composed with ‘ivy-minibuffer-map’. This keymap has
+ priority over ‘ivy-minibuffer-map’ and can be modified at any later
+ stage.
+
+‘update-fn’
+...........
+
+ Is the function called each time the current candidate changes.
+ This function takes no arguments and is called in the minibuffer’s
+ ‘post-command-hook’. See ‘swiper’ for an example usage.
+
+‘sort’
+......
+
+ When non-nil, use ‘ivy-sort-functions-alist’ to sort the collection
+ as long as the collection is not larger than ‘ivy-sort-max-size’.
+
+‘action’
+........
+
+ Is the function to call after selection. It takes a string
+ argument.
+
+‘unwind’
+........
+
+ Is the function to call before exiting completion. It takes no
+ arguments. This function is called even if the completion is
+ interrupted with ‘C-g’. See ‘swiper’ for an example usage.
+
+‘re-builder’
+............
+
+ Is a function that takes a string and returns a valid regex. See
+ ‘Completion Styles’ for details.
+
+‘matcher’
+.........
+
+ Is a function that takes a regex string and a list of strings and
+ returns a list of strings matching the regex. Any ordinary Emacs
+ matching function will suffice, yet finely tuned matching functions
+ can be used. See ‘counsel-find-file’ for an example usage.
+
+‘dynamic-collection’
+....................
+
+ When non-nil, ‘collection’ will be used to dynamically generate the
+ candidates each time the input changes, instead of being used once
+ statically with ‘all-completions’ to generate a list of strings.
+ See ‘counsel-locate’ for an example usage.
+
+‘caller’
+........
+
+ Is a symbol that uniquely identifies the function that called
+ ‘ivy-read’, which may be useful for further customizations.
+
+
+File: ivy.info, Node: Example - counsel-describe-function, Next: Example - counsel-locate, Prev: Optional arguments for ivy-read, Up: API
+
+8.3 Example - ‘counsel-describe-function’
+=========================================
+
+This is a typical example of a function with a non-async collection,
+which is a collection where all the strings in the collection are known
+prior to any input from the user.
+
+ Only the first two arguments (along with ‘action’) are essential -
+the rest of the arguments are for fine-tuning, and could be omitted.
+
+ The ‘action’ argument could also be omitted - but then ‘ivy-read’
+would do nothing except returning the string result, which you could
+later use yourself. However, it’s recommended that you use the ‘action’
+argument.
+
+ (defun counsel-describe-function ()
+ "Forward to `describe-function'."
+ (interactive)
+ (ivy-read "Describe function: "
+ (let (cands)
+ (mapatoms
+ (lambda (x)
+ (when (fboundp x)
+ (push (symbol-name x) cands))))
+ cands)
+ :keymap counsel-describe-map
+ :preselect (ivy-thing-at-point)
+ :history 'counsel-describe-symbol-history
+ :require-match t
+ :action (lambda (x)
+ (describe-function
+ (intern x)))
+ :caller 'counsel-describe-function))
+
+ Here are the interesting features of the above function, in the order
+that they appear:
+
+ • The ‘prompt’ argument is a simple string ending in ": ".
+ • The ‘collection’ argument evaluates to a (large) list of strings.
+ • The ‘keymap’ argument is for a custom keymap to supplement
+ ‘ivy-minibuffer-map’.
+ • The ‘preselect’ is provided by ‘ivy-thing-at-point’, which returns
+ a symbol near the point. Ivy then selects the first candidate from
+ the collection that matches this symbol. To select this
+ pre-selected candidate, a ‘RET’ will suffice. No further user
+ input is necessary.
+ • The ‘history’ argument is for keeping the history of this command
+ separate from the common history in ‘ivy-history’.
+ • The ‘require-match’ is set to ‘t’ since it doesn’t make sense to
+ call ‘describe-function’ on an un-interned symbol.
+ • The ‘action’ argument calls ‘describe-function’ on the interned
+ selected candidate.
+ • The ‘caller’ argument identifies this completion session. This is
+ important, since with the collection being a list of strings and
+ not a function name, the only other way for ‘ivy-read’ to identify
+ "who’s calling" and to apply the appropriate customizations is to
+ examine ‘this-command’. But ‘this-command’ would be modified if
+ another command called ‘counsel-describe-function’.
+
+
+File: ivy.info, Node: Example - counsel-locate, Next: Example - ivy-read-with-extra-properties, Prev: Example - counsel-describe-function, Up: API
+
+8.4 Example - ‘counsel-locate’
+==============================
+
+This is a typical example of a function with an async collection. Since
+the collection function cannot pre-compute all the locatable files in
+memory within reasonable limits (time or memory), it relies on user
+input to filter the universe of possible candidates to a manageable size
+while also continuing to search asynchronously for possible candidates.
+Both the filtering and searching continues with each character change of
+the input with rapid updates to the collection presented without idle
+waiting times. This live update will continue as long as there are
+likely candidates. Eventually updates to the minibuffer will stop after
+user input, filtering, and searching have exhausted looking for possible
+candidates.
+
+ Async collections suit long-running shell commands, such as ‘locate’.
+With each new input, a new process starts while the old process is
+killed. The collection is refreshed anew with each new process.
+Meanwhile the user can provide more input characters (for further
+narrowing) or select a candidate from the visible collection.
+
+ (defun counsel-locate-function (str)
+ (or
+ (ivy-more-chars)
+ (progn
+ (counsel--async-command
+ (format "locate %s '%s'"
+ (mapconcat #'identity counsel-locate-options " ")
+ (counsel--elisp-to-pcre
+ (ivy--regex str))))
+ '("" "working..."))))
+
+ ;;;###autoload
+ (defun counsel-locate (&optional initial-input)
+ "Call the \"locate\" shell command.
+ INITIAL-INPUT can be given as the initial minibuffer input."
+ (interactive)
+ (ivy-read "Locate: " #'counsel-locate-function
+ :initial-input initial-input
+ :dynamic-collection t
+ :history 'counsel-locate-history
+ :action (lambda (file)
+ (with-ivy-window
+ (when file
+ (find-file file))))
+ :unwind #'counsel-delete-process
+ :caller 'counsel-locate))
+
+ Here are the interesting features of the above functions, in the
+order that they appear:
+
+ • ‘counsel-locate-function’ takes a string argument and returns a
+ list of strings. Note that it’s not compatible with
+ ‘all-completions’, but since we’re not using that here, might as
+ well use one argument instead of three.
+ • ‘ivy-more-chars’ is a simple function that returns e.g. ‘'("2
+ chars more")’ asking the user for more input.
+ • ‘counsel--async-command’ is a very easy API simplification that
+ takes a single string argument suitable for
+ ‘shell-command-to-string’. So you could prototype your function as
+ non-async using ‘shell-command-to-string’ and ‘split-string’ to
+ produce a collection, then decide that you want async and simply
+ swap in ‘counsel--async-command’.
+ • ‘counsel-locate’ is an interactive function with an optional
+ ‘initial-input’.
+ • ‘#'counsel-locate-function’ is passed as the ‘collection’ argument.
+ • ‘dynamic-collection’ is set to t, since this is an async
+ collection.
+ • ‘action’ argument uses ‘with-ivy-window’ wrapper, since we want to
+ open the selected file in the same window from which
+ ‘counsel-locate’ was called.
+ • ‘unwind’ argument is set to ‘#'counsel-delete-process’: when we
+ press ‘C-g’ we want to kill the running process created by
+ ‘counsel--async-command’.
+ • ‘caller’ argument identifies this command for easier customization.
+
+
+File: ivy.info, Node: Example - ivy-read-with-extra-properties, Prev: Example - counsel-locate, Up: API
+
+8.5 Example - ‘ivy-read-with-extra-properties’
+==============================================
+
+This is another example to show how to associate additional values to
+each displayed strings.
+
+ (defun find-candidates-function (str pred _)
+ (let ((props '(1 2))
+ (strs '("foo" "foo2")))
+ (cl-mapcar (lambda (s p) (propertize s 'property p))
+ strs
+ props)))
+
+ (defun find-candidates ()
+ (interactive)
+ (ivy-read "Find symbols: "
+ #'find-candidates-function
+ :action (lambda (x)
+ (message "Value: %s"
+ (get-text-property 0 'property x)))))
+
+ Here are the interesting features of the above function:
+
+ • ‘find-candidates-function’ builds up a list of strings and
+ associates "foo" with the value 1 and "foo2" with 2.
+ • ‘find-candidates’ is an interactive function.
+ • ‘#'find-candidates’ is passed as the ‘collection’ argument.
+ • ‘action’ gets passed the selected string with the associated value.
+ It then retrieves that value and displays it.
+
+
+File: ivy.info, Node: Variable Index, Next: Keystroke Index, Prev: API, Up: Top
+
+9 Variable Index
+****************
+
+
+* Menu:
+
+* ivy-alt-done: Key bindings for single selection action then exit minibuffer.
+ (line 30)
+* ivy-alt-done <1>: File Name Completion. (line 12)
+* ivy-avy: Key bindings for single selection action then exit minibuffer.
+ (line 64)
+* ivy-backward-delete-char: File Name Completion. (line 19)
+* ivy-call: Key bindings for multiple selections and actions keep minibuffer open.
+ (line 19)
+* ivy-confirm-face: Faces. (line 34)
+* ivy-count-format: Defcustoms. (line 6)
+* ivy-current-match: Faces. (line 9)
+* ivy-dispatching-call: Key bindings for multiple selections and actions keep minibuffer open.
+ (line 29)
+* ivy-dispatching-done: Key bindings for single selection action then exit minibuffer.
+ (line 24)
+* ivy-display-style: Defcustoms. (line 24)
+* ivy-done: Key bindings for single selection action then exit minibuffer.
+ (line 19)
+* ivy-extra-directories: File Name Completion. (line 51)
+* ivy-height: Key bindings for navigation.
+ (line 21)
+* ivy-immediate-done: Key bindings for single selection action then exit minibuffer.
+ (line 53)
+* ivy-insert-current: Key bindings that alter the minibuffer input.
+ (line 23)
+* ivy-insert-current-full: File Name Completion. (line 41)
+* ivy-kill-ring-save: Other key bindings. (line 9)
+* ivy-match-required-face: Faces. (line 53)
+* ivy-minibuffer-grow: Hydra in the minibuffer.
+ (line 45)
+* ivy-minibuffer-map: Minibuffer key bindings.
+ (line 6)
+* ivy-minibuffer-match-face-1: Faces. (line 14)
+* ivy-minibuffer-match-face-2: Faces. (line 19)
+* ivy-minibuffer-match-face-3: Faces. (line 24)
+* ivy-minibuffer-match-face-4: Faces. (line 29)
+* ivy-minibuffer-shrink: Hydra in the minibuffer.
+ (line 50)
+* ivy-modified-buffer: Faces. (line 88)
+* ivy-modified-outside-buffer: Faces. (line 93)
+* ivy-next-action: Hydra in the minibuffer.
+ (line 60)
+* ivy-next-history-element: Key bindings that alter the minibuffer input.
+ (line 9)
+* ivy-next-line-and-call: Key bindings for multiple selections and actions keep minibuffer open.
+ (line 39)
+* ivy-occur: Saving the current completion session to a buffer.
+ (line 9)
+* ivy-occur-click: Saving the current completion session to a buffer.
+ (line 21)
+* ivy-occur-dispatch: Saving the current completion session to a buffer.
+ (line 41)
+* ivy-occur-press: Saving the current completion session to a buffer.
+ (line 16)
+* ivy-occur-read-action: Saving the current completion session to a buffer.
+ (line 36)
+* ivy-on-del-error-function: Defcustoms. (line 31)
+* ivy-partial-or-done: Key bindings for single selection action then exit minibuffer.
+ (line 37)
+* ivy-prev-action: Hydra in the minibuffer.
+ (line 55)
+* ivy-previous-history-element: Key bindings that alter the minibuffer input.
+ (line 18)
+* ivy-previous-line-and-call: Key bindings for multiple selections and actions keep minibuffer open.
+ (line 50)
+* ivy-read-action: Hydra in the minibuffer.
+ (line 65)
+* ivy-remote: Faces. (line 71)
+* ivy-restrict-to-matches: Key bindings that alter the minibuffer input.
+ (line 40)
+* ivy-resume: Key bindings for multiple selections and actions keep minibuffer open.
+ (line 58)
+* ivy-reverse-i-search: Key bindings that alter the minibuffer input.
+ (line 48)
+* ivy-rotate-preferred-builders: Hydra in the minibuffer.
+ (line 40)
+* ivy-subdir: Faces. (line 66)
+* ivy-toggle-calling: Hydra in the minibuffer.
+ (line 34)
+* ivy-toggle-case-fold: Hydra in the minibuffer.
+ (line 70)
+* ivy-toggle-regexp-quote: File Name Completion. (line 47)
+* ivy-use-virtual-buffers: Buffer Name Completion.
+ (line 6)
+* ivy-virtual: Faces. (line 76)
+* ivy-wrap: Key bindings for navigation.
+ (line 14)
+* ivy-yank-word: Key bindings that alter the minibuffer input.
+ (line 32)
+
+
+File: ivy.info, Node: Keystroke Index, Prev: Variable Index, Up: Top
+
+10 Keystroke Index
+******************
+
+
+* Menu:
+
+* /: File Name Completion. (line 35)
+* / C-j: Using TRAMP. (line 24)
+* //: File Name Completion. (line 25)
+* // <1>: Using TRAMP. (line 17)
+* <: Hydra in the minibuffer.
+ (line 50)
+* >: Hydra in the minibuffer.
+ (line 45)
+* ~: File Name Completion. (line 30)
+* ~ <1>: Using TRAMP. (line 9)
+* ~~: Using TRAMP. (line 29)
+* a: Hydra in the minibuffer.
+ (line 65)
+* a <1>: Saving the current completion session to a buffer.
+ (line 36)
+* c: Hydra in the minibuffer.
+ (line 34)
+* C: Hydra in the minibuffer.
+ (line 70)
+* C-': Key bindings for single selection action then exit minibuffer.
+ (line 64)
+* C-c C-o: Saving the current completion session to a buffer.
+ (line 9)
+* C-j: Key bindings for single selection action then exit minibuffer.
+ (line 30)
+* C-j <1>: File Name Completion. (line 12)
+* C-m: Key bindings for single selection action then exit minibuffer.
+ (line 19)
+* C-M-j: Key bindings for single selection action then exit minibuffer.
+ (line 53)
+* C-M-m: Key bindings for multiple selections and actions keep minibuffer open.
+ (line 19)
+* C-M-n: Key bindings for multiple selections and actions keep minibuffer open.
+ (line 39)
+* C-M-o: Key bindings for multiple selections and actions keep minibuffer open.
+ (line 29)
+* C-M-p: Key bindings for multiple selections and actions keep minibuffer open.
+ (line 50)
+* C-M-y: File Name Completion. (line 41)
+* C-o: Hydra in the minibuffer.
+ (line 9)
+* C-r: Key bindings that alter the minibuffer input.
+ (line 48)
+* DEL: File Name Completion. (line 19)
+* f: Saving the current completion session to a buffer.
+ (line 16)
+* j: Saving the current completion session to a buffer.
+ (line 26)
+* k: Saving the current completion session to a buffer.
+ (line 31)
+* M: Hydra in the minibuffer.
+ (line 40)
+* M-i: Key bindings that alter the minibuffer input.
+ (line 23)
+* M-j: Key bindings that alter the minibuffer input.
+ (line 32)
+* M-n: Key bindings that alter the minibuffer input.
+ (line 9)
+* M-o: Key bindings for single selection action then exit minibuffer.
+ (line 24)
+* M-p: Key bindings that alter the minibuffer input.
+ (line 18)
+* M-r: File Name Completion. (line 47)
+* M-w: Other key bindings. (line 9)
+* mouse-1: Saving the current completion session to a buffer.
+ (line 21)
+* o: Saving the current completion session to a buffer.
+ (line 41)
+* q: Saving the current completion session to a buffer.
+ (line 46)
+* RET: Key bindings for single selection action then exit minibuffer.
+ (line 19)
+* RET <1>: Saving the current completion session to a buffer.
+ (line 16)
+* s: Hydra in the minibuffer.
+ (line 60)
+* S-SPC: Key bindings that alter the minibuffer input.
+ (line 40)
+* TAB: Key bindings for single selection action then exit minibuffer.
+ (line 37)
+* w: Hydra in the minibuffer.
+ (line 55)
+
+
+
+Tag Table:
+Node: Top1192
+Node: Introduction3103
+Node: Installation5626
+Node: Installing from Emacs Package Manager6076
+Node: Installing from the Git repository7324
+Node: Getting started8144
+Node: Basic customization8451
+Node: Key bindings9046
+Node: Global key bindings9238
+Node: Minibuffer key bindings11712
+Node: Key bindings for navigation12944
+Node: Key bindings for single selection action then exit minibuffer14151
+Node: Key bindings for multiple selections and actions keep minibuffer open16835
+Node: Key bindings that alter the minibuffer input19456
+Node: Other key bindings21403
+Node: Hydra in the minibuffer21781
+Node: Saving the current completion session to a buffer24199
+Node: Completion Styles25611
+Node: ivy--regex-plus27369
+Node: ivy--regex-ignore-order28855
+Node: ivy--regex-fuzzy29223
+Node: Customization29720
+Node: Faces29906
+Node: Defcustoms32335
+Node: Actions33694
+Node: What are actions?34020
+Node: How can different actions be called?34838
+Node: How to modify the actions list?35409
+Node: Example - add two actions to each command36069
+Node: How to undo adding the two actions37028
+Node: How to add actions to a specific command37480
+Node: Example - define a new command with several actions37896
+Node: Test the above function with ivy-occur38833
+Node: Packages39675
+Node: Commands40640
+Node: File Name Completion40825
+Node: Using TRAMP42782
+Node: Buffer Name Completion44284
+Node: Counsel commands44899
+Node: API45546
+Node: Required arguments for ivy-read46144
+Node: Optional arguments for ivy-read46663
+Node: Example - counsel-describe-function50089
+Node: Example - counsel-locate53073
+Node: Example - ivy-read-with-extra-properties56942
+Node: Variable Index58220
+Node: Keystroke Index65344
+
+End Tag Table
+
+
+Local Variables:
+coding: utf-8
+End:
diff --git a/elpa/key-chord-20201222.2030/key-chord-autoloads.el b/elpa/key-chord-20201222.2030/key-chord-autoloads.el
new file mode 100644
index 0000000..612fd50
--- /dev/null
+++ b/elpa/key-chord-20201222.2030/key-chord-autoloads.el
@@ -0,0 +1,97 @@
+;;; key-chord-autoloads.el --- automatically extracted autoloads -*- lexical-binding: t -*-
+;;
+;;; Code:
+
+(add-to-list 'load-path (directory-file-name
+ (or (file-name-directory #$) (car load-path))))
+
+
+;;;### (autoloads nil "key-chord" "key-chord.el" (0 0 0 0))
+;;; Generated autoloads from key-chord.el
+
+(defvar key-chord-mode nil "\
+Non-nil if Key-Chord mode is enabled.
+See the `key-chord-mode' command
+for a description of this minor mode.
+Setting this variable directly does not take effect;
+either customize it (see the info node `Easy Customization')
+or call the function `key-chord-mode'.")
+
+(custom-autoload 'key-chord-mode "key-chord" nil)
+
+(autoload 'key-chord-mode "key-chord" "\
+Map pairs of simultaneously pressed keys to commands.
+
+This is a minor mode. If called interactively, toggle the
+`Key-Chord mode' mode. If the prefix argument is positive,
+enable the mode, and if it is zero or negative, disable the mode.
+
+If called from Lisp, toggle the mode if ARG is `toggle'. Enable
+the mode if ARG is nil, omitted, or is a positive number.
+Disable the mode if ARG is a negative number.
+
+To check whether the minor mode is enabled in the current buffer,
+evaluate `(default-value \\='key-chord-mode)'.
+
+The mode's hook is called both when the mode is enabled and when
+it is disabled.
+
+See functions `key-chord-define-global', `key-chord-define-local',
+and `key-chord-define' and variables `key-chord-two-keys-delay'
+and `key-chord-one-key-delay'.
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'key-chord-define-global "key-chord" "\
+Define a key-chord of the two keys in KEYS starting a COMMAND.
+
+KEYS can be a string or a vector of two elements. Currently only
+elements that corresponds to ascii codes in the range 32 to 126
+can be used.
+
+COMMAND can be an interactive function, a string, or nil.
+If COMMAND is nil, the key-chord is removed.
+
+Note that KEYS defined locally in the current buffer will have
+precedence.
+
+\(fn KEYS COMMAND)" t nil)
+
+(autoload 'key-chord-define-local "key-chord" "\
+Locally define a key-chord of the two keys in KEYS starting a COMMAND.
+
+KEYS can be a string or a vector of two elements. Currently only
+elements that corresponds to ascii codes in the range 32 to 126
+can be used.
+
+COMMAND can be an interactive function, a string, or nil.
+If COMMAND is nil, the key-chord is removed.
+
+The binding goes in the current buffer's local map, which in most
+cases is shared with all other buffers in the same major mode.
+
+\(fn KEYS COMMAND)" t nil)
+
+(autoload 'key-chord-define "key-chord" "\
+Define in KEYMAP, a key-chord of the two keys in KEYS starting a COMMAND.
+
+KEYS can be a string or a vector of two elements. Currently only
+elements that corresponds to ascii codes in the range 32 to 126
+can be used.
+
+COMMAND can be an interactive function, a string, or nil.
+If COMMAND is nil, the key-chord is removed.
+
+\(fn KEYMAP KEYS COMMAND)" nil nil)
+
+(register-definition-prefixes "key-chord" '("key-chord-"))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; coding: utf-8
+;; End:
+;;; key-chord-autoloads.el ends here
diff --git a/elpa/key-chord-20201222.2030/key-chord-pkg.el b/elpa/key-chord-20201222.2030/key-chord-pkg.el
new file mode 100644
index 0000000..811e1e3
--- /dev/null
+++ b/elpa/key-chord-20201222.2030/key-chord-pkg.el
@@ -0,0 +1,2 @@
+;;; Generated package description from key-chord.el -*- no-byte-compile: t -*-
+(define-package "key-chord" "20201222.2030" "map pairs of simultaneously pressed keys to commands" '((emacs "24")) :commit "7f7fd7c5bd2b996fa054779357e1566f7989e07d" :authors '(("David Andersson <l.david.andersson(at)sverige.nu>")) :maintainer '("David Andersson <l.david.andersson(at)sverige.nu>") :keywords '("keyboard" "chord" "input"))
diff --git a/elpa/key-chord-20201222.2030/key-chord.el b/elpa/key-chord-20201222.2030/key-chord.el
new file mode 100644
index 0000000..fc4716d
--- /dev/null
+++ b/elpa/key-chord-20201222.2030/key-chord.el
@@ -0,0 +1,218 @@
+;;; key-chord.el --- map pairs of simultaneously pressed keys to commands -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2003, 2005, 2008, 2012 David Andersson
+
+;; Author: David Andersson <l.david.andersson(at)sverige.nu>
+;; Package-Requires: ((emacs "24"))
+;; Package-Version: 20201222.2030
+;; Package-Commit: 7f7fd7c5bd2b996fa054779357e1566f7989e07d
+;; Keywords: keyboard chord input
+
+;; 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 2 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, write to the Free
+;; Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+;; MA 02111-1307 USA
+
+;;; Commentary:
+
+;; This package implements support for mapping a pair of simultaneously
+;; pressed keys to a command and for mapping the same key being pressed
+;; twice in quick succession to a command. Such bindings are called
+;; "key chords".
+
+;;; Code:
+
+(defgroup key-chord nil
+ "Map pairs of simultaneously pressed keys to commands."
+ :group 'bindings)
+
+(defcustom key-chord-two-keys-delay 0.1
+ "Max time delay between two key press to be considered a key chord."
+ :type 'float)
+
+(defcustom key-chord-one-key-delay 0.2
+ "Max time delay between two press of the same key to be considered a key chord.
+This should normally be a little longer than `key-chord-two-keys-delay'."
+ :type 'float)
+
+(defcustom key-chord-in-macros t
+ "If nil, don't expand key chords when executing keyboard macros.
+
+If non-nil, expand chord sequenses in macros, but only if a
+similar chord was entered during the last interactive macro
+recording. (This carries a bit of guesswork. We can't know for
+sure when executing whether two keys were typed quickly or slowly
+when recorded.)"
+ :type 'boolean)
+
+;; Internal vars
+(defvar key-chord-mode nil)
+
+;; Shortcut for key-chord-input-method: no need to test a key again if it
+;; didn't matched a chord the last time. Improves feedback during autorepeat.
+(defvar key-chord-last-unmatched nil)
+
+;; Macro heuristics: Keep track of which chords was used when the last macro
+;; was defined. Or rather, only the first-char of the chords. Only expand
+;; matching chords during macro execution.
+(defvar key-chord-in-last-kbd-macro nil)
+(defvar key-chord-defining-kbd-macro nil)
+
+;;;###autoload
+(define-minor-mode key-chord-mode
+ "Map pairs of simultaneously pressed keys to commands.
+
+See functions `key-chord-define-global', `key-chord-define-local',
+and `key-chord-define' and variables `key-chord-two-keys-delay'
+and `key-chord-one-key-delay'."
+ :global t
+ (setq input-method-function
+ (and key-chord-mode
+ 'key-chord-input-method)))
+
+;;;###autoload
+(defun key-chord-define-global (keys command)
+ "Define a key-chord of the two keys in KEYS starting a COMMAND.
+
+KEYS can be a string or a vector of two elements. Currently only
+elements that corresponds to ascii codes in the range 32 to 126
+can be used.
+
+COMMAND can be an interactive function, a string, or nil.
+If COMMAND is nil, the key-chord is removed.
+
+Note that KEYS defined locally in the current buffer will have
+precedence."
+ (interactive "sSet key chord globally (2 keys): \nCSet chord \"%s\" to command: ")
+ (key-chord-define (current-global-map) keys command))
+
+;;;###autoload
+(defun key-chord-define-local (keys command)
+ "Locally define a key-chord of the two keys in KEYS starting a COMMAND.
+
+KEYS can be a string or a vector of two elements. Currently only
+elements that corresponds to ascii codes in the range 32 to 126
+can be used.
+
+COMMAND can be an interactive function, a string, or nil.
+If COMMAND is nil, the key-chord is removed.
+
+The binding goes in the current buffer's local map, which in most
+cases is shared with all other buffers in the same major mode."
+ (interactive "sSet key chord locally (2 keys): \nCSet chord \"%s\" to command: ")
+ (key-chord-define (current-local-map) keys command))
+
+(defun key-chord-unset-global (keys)
+ "Remove global key-chord of the two keys in KEYS."
+ (interactive "sUnset key chord globally (2 keys): ")
+ (key-chord-define (current-global-map) keys nil))
+
+(defun key-chord-unset-local (keys)
+ "Remove local key-chord of the two keys in KEYS."
+ (interactive "sUnset key chord locally (2 keys): ")
+ (key-chord-define (current-local-map) keys nil))
+
+;;;###autoload
+(defun key-chord-define (keymap keys command)
+ "Define in KEYMAP, a key-chord of the two keys in KEYS starting a COMMAND.
+
+KEYS can be a string or a vector of two elements. Currently only
+elements that corresponds to ascii codes in the range 32 to 126
+can be used.
+
+COMMAND can be an interactive function, a string, or nil.
+If COMMAND is nil, the key-chord is removed."
+ (if (/= 2 (length keys))
+ (error "Key-chord keys must have two elements"))
+ ;; Exotic chars in a string are >255 but define-key wants 128..255
+ ;; for those.
+ (let ((key1 (logand 255 (aref keys 0)))
+ (key2 (logand 255 (aref keys 1))))
+ (if (eq key1 key2)
+ (define-key keymap (vector 'key-chord key1 key2) command)
+ (define-key keymap (vector 'key-chord key1 key2) command)
+ (define-key keymap (vector 'key-chord key2 key1) command))))
+
+(defun key-chord-lookup-key1 (keymap key)
+ "Like lookup-key but no third arg and no numeric return value."
+ (let ((res (lookup-key keymap key)))
+ (and (not (numberp res))
+ res)))
+
+(defun key-chord-lookup-key (key)
+ "Lookup KEY in all current key maps."
+ (let ((maps (current-minor-mode-maps))
+ res)
+ (while (and maps (not res))
+ (setq res (key-chord-lookup-key1 (car maps) key))
+ (setq maps (cdr maps)))
+ (or res
+ (and (current-local-map)
+ (key-chord-lookup-key1 (current-local-map) key))
+ (key-chord-lookup-key1 (current-global-map) key))))
+
+(defun key-chord-describe ()
+ "List key chord bindings in a help buffer.
+
+Two key chords will be listed twice and there will be Prefix
+Commands. Please ignore that."
+ (interactive)
+ (describe-bindings [key-chord]))
+
+(defun key-chord-input-method (first-char)
+ "Input method controlled by key bindings with the prefix `key-chord'."
+ (cond
+ ((and (not (eq first-char key-chord-last-unmatched))
+ (key-chord-lookup-key (vector 'key-chord first-char)))
+ (let ((delay (if (key-chord-lookup-key
+ (vector 'key-chord first-char first-char))
+ key-chord-one-key-delay
+ key-chord-two-keys-delay)))
+ (cond ((if executing-kbd-macro
+ (not (memq first-char key-chord-in-last-kbd-macro))
+ (when (bound-and-true-p eldoc-mode)
+ (eldoc-pre-command-refresh-echo-area))
+ (sit-for delay 'no-redisplay))
+ (setq key-chord-last-unmatched nil)
+ (list first-char))
+ (t ; input-pending-p
+ (let* ((input-method-function nil)
+ (next-char (read-event))
+ (res (vector 'key-chord first-char next-char)))
+ (cond ((key-chord-lookup-key res)
+ (setq key-chord-defining-kbd-macro
+ (cons first-char key-chord-defining-kbd-macro))
+ (list 'key-chord first-char next-char))
+ (t ;put back next-char and return first-char
+ (setq unread-command-events
+ (cons next-char unread-command-events))
+ (when (eq first-char next-char)
+ (setq key-chord-last-unmatched first-char))
+ (list first-char))))))))
+ (t ; no key-chord keymap
+ (setq key-chord-last-unmatched first-char)
+ (list first-char))))
+
+(defun key-chord--start-kbd-macro (_append &optional _no-exec)
+ (setq key-chord-defining-kbd-macro nil))
+(advice-add 'start-kbd-macro :after #'key-chord--start-kbd-macro)
+
+(defun key-chord--end-kbd-macro (&optional _repeat _loopfunc)
+ (setq key-chord-in-last-kbd-macro key-chord-defining-kbd-macro))
+(advice-add 'end-kbd-macro :after #'key-chord--end-kbd-macro)
+
+(provide 'key-chord)
+;; Local Variables:
+;; indent-tabs-mode: nil
+;; End:
+;;; key-chord.el ends here
diff --git a/elpa/key-chord-20201222.2030/key-chord.elc b/elpa/key-chord-20201222.2030/key-chord.elc
new file mode 100644
index 0000000..2324b03
--- /dev/null
+++ b/elpa/key-chord-20201222.2030/key-chord.elc
Binary files differ
diff --git a/elpa/lsp-mode-20220505.630/lsp-actionscript.el b/elpa/lsp-mode-20220505.630/lsp-actionscript.el
new file mode 100644
index 0000000..f82e669
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-actionscript.el
@@ -0,0 +1,134 @@
+;;; lsp-actionscript.el --- ActionScript Client settings -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2021 Jen-Chieh Shen
+
+;; Author: Jen-Chieh Shen <jcs090218@gmail.com>
+;; Keywords: actionscript lsp
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; LSP client for ActionScript
+
+;;; Code:
+
+(require 'lsp-mode)
+
+(defgroup lsp-actionscript nil
+ "LSP support for ActionScript."
+ :group 'lsp-mode
+ :link '(url-link "https://github.com/BowlerHatLLC/vscode-as3mxml")
+ :package-version `(lsp-mode . "8.0.0"))
+
+(defcustom lsp-actionscript-java-path "java"
+ "Path of the java executable."
+ :group 'lsp-actionscript
+ :type 'string)
+
+(defcustom lsp-actionscript-sdk-path ""
+ "Path to supported SDK.
+See https://github.com/BowlerHatLLC/vscode-as3mxml/wiki/Choose-an-ActionScript-SDK-for-the-current-workspace-in-Visual-Studio-Code."
+ :type 'string
+ :group 'lsp-actionscript
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-actionscript-version "1.5.0"
+ "Version of ActionScript language server."
+ :type 'string
+ :group 'lsp-actionscript
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-actionscript-extension-name
+ (format "vscode-nextgenas-%s.vsix" lsp-actionscript-version)
+ "File name of the extension file from language server."
+ :type 'string
+ :group 'lsp-actionscript
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-actionscript-server-download-url
+ (format "https://github.com/BowlerHatLLC/vscode-as3mxml/releases/download/v%s/%s"
+ lsp-actionscript-version lsp-actionscript-extension-name)
+ "Automatic download url for lsp-actionscript."
+ :type 'string
+ :group 'lsp-actionscript
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-actionscript-server-store-path
+ (f-join lsp-server-install-dir "as3mxml")
+ "The path to the file in which `lsp-actionscript' will be stored."
+ :type 'file
+ :group 'lsp-actionscript
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-actionscript-option-charset "UTF8"
+ "The charset to use by the ActionScript Language server."
+ :type 'string
+ :group 'lsp-actionscript
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defun lsp-actionscript--extension-root ()
+ "The path that the downloaded extension will extract to."
+ (f-join lsp-actionscript-server-store-path
+ (format "vscode-nextgenas-%s" lsp-actionscript-version)))
+
+(defun lsp-actionscript--extension-path ()
+ "Return full path of the downloaded extension."
+ (f-join lsp-actionscript-server-store-path lsp-actionscript-extension-name))
+
+(defun lsp-actionscript--extension-dir ()
+ "Return as3mxml extension path."
+ (f-join (lsp-actionscript--extension-root) "extension"))
+
+(defun lsp-actionscript--server-command ()
+ "Startup command for ActionScript language server."
+ (list lsp-actionscript-java-path
+ (format "-Droyalelib=%s" lsp-actionscript-sdk-path)
+ (format "-Dfile.encoding=%s" lsp-actionscript-option-charset)
+ "-cp"
+ (format "%s/bundled-compiler/*;%s/bin/*"
+ (lsp-actionscript--extension-dir) (lsp-actionscript--extension-dir))
+ "com.as3mxml.vscode.Main"))
+
+(defun lsp-actionscript--extension-path-zip ()
+ "Change extension path from .vsix to .zip."
+ (concat (f-no-ext (lsp-actionscript--extension-path)) ".zip"))
+
+(lsp-dependency
+ 'as3mxml
+ '(:system "as3mxml")
+ `(:download :url lsp-actionscript-server-download-url
+ :store-path ,(lsp-actionscript--extension-path-zip)))
+
+(lsp-register-client
+ (make-lsp-client
+ :new-connection (lsp-stdio-connection
+ #'lsp-actionscript--server-command
+ (lambda () (f-exists? (lsp-actionscript--extension-path-zip))))
+ :major-modes '(actionscript-mode)
+ :priority -1
+ :server-id 'as3mxml-ls
+ :download-server-fn (lambda (_client _callback error-callback _update?)
+ (lsp-package-ensure
+ 'as3mxml
+ (lambda ()
+ ;; TODO: Error handling when unzip failed
+ (lsp-unzip (lsp-actionscript--extension-path-zip)
+ (lsp-actionscript--extension-root)))
+ error-callback))))
+
+(lsp-consistency-check lsp-actionscript)
+
+(provide 'lsp-actionscript)
+;;; lsp-actionscript.el ends here
diff --git a/elpa/lsp-mode-20220505.630/lsp-actionscript.elc b/elpa/lsp-mode-20220505.630/lsp-actionscript.elc
new file mode 100644
index 0000000..700518d
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-actionscript.elc
Binary files differ
diff --git a/elpa/lsp-mode-20220505.630/lsp-ada.el b/elpa/lsp-mode-20220505.630/lsp-ada.el
new file mode 100644
index 0000000..0de430a
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-ada.el
@@ -0,0 +1,106 @@
+;;; lsp-ada.el --- description -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2020 emacs-lsp maintainers
+
+;; Author: emacs-lsp maintainers
+;; Keywords: lsp, ada
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; LSP Clients for the Ada Programming Language
+
+;;; Code:
+
+(require 'lsp-mode)
+
+(defgroup lsp-ada nil
+ "Settings for Ada Language Server."
+ :group 'tools
+ :tag "Language Server"
+ :package-version '(lsp-mode . "6.2"))
+
+(defcustom-lsp lsp-ada-project-file "default.gpr"
+ "Set the project file full path to configure the language server with.
+ The ~ prefix (for the user home directory) is supported.
+ See https://github.com/AdaCore/ada_language_server for a per-project
+ configuration example."
+ :type 'string
+ :group 'lsp-ada
+ :package-version '(lsp-mode . "6.2")
+ :lsp-path "ada.projectFile")
+
+(defcustom-lsp lsp-ada-option-charset "UTF-8"
+ "The charset to use by the Ada Language server. Defaults to 'UTF-8'."
+ :type 'string
+ :group 'lsp-ada
+ :package-version '(lsp-mode . "6.2")
+ :lsp-path "ada.defaultCharset")
+
+(defcustom-lsp lsp-ada-enable-diagnostics t
+ "A boolean to disable diagnostics. Defaults to true."
+ :type 'boolean
+ :group 'lsp-ada
+ :package-version '(lsp-mode . "6.2")
+ :lsp-path "ada.enableDiagnostics")
+
+(defcustom lsp-ada-als-executable "ada_language_server"
+ "Command to start the Ada language server."
+ :group 'lsp-ada
+ :risky t
+ :type 'file)
+
+(defcustom lsp-ada-alire-executable "alr"
+ "The alire executable to run when a project is detected."
+ :type 'string
+ :group 'lsp-ada
+ :package-version '(lsp-mode "8.0.1"))
+
+(defun lsp-ada--environment ()
+ "Add environmental variables if needed."
+ (let ((project-root (lsp-workspace-root)))
+ ;; When there is an alire project, include its environment
+ (when (file-exists-p
+ (concat (file-name-as-directory project-root)
+ "alire.toml"))
+ (let ((alr-executable (executable-find lsp-ada-alire-executable)))
+ (if alr-executable
+ ;; Transform output variables to environment
+ (let ((env-output (shell-command-to-string (concat alr-executable " printenv --unix"))))
+ (let ((var-strings (split-string env-output "\n")))
+ (mapcar (lambda (string)
+ (if (string-match (rx "export" space (group (one-or-more ascii)) "=" "\"" (group (one-or-more ascii)) "\"") string)
+ (let ((var-name (match-string 1 string))
+ (var-value (match-string 2 string)))
+ (cons var-name var-value))))
+ var-strings)))
+ (lsp--error "Found alire.toml but the executable %s could not be found" alr-executable))))))
+
+(lsp-register-client
+ (make-lsp-client :new-connection (lsp-stdio-connection lsp-ada-als-executable)
+ :major-modes '(ada-mode)
+ :priority -1
+ :initialized-fn (lambda (workspace)
+ (with-lsp-workspace workspace
+ (lsp--set-configuration
+ (lsp-configuration-section "ada"))))
+ :server-id 'ada-ls
+ :synchronize-sections '("ada")
+ :environment-fn 'lsp-ada--environment))
+
+(lsp-consistency-check lsp-ada)
+
+(provide 'lsp-ada)
+;;; lsp-ada.el ends here
diff --git a/elpa/lsp-mode-20220505.630/lsp-ada.elc b/elpa/lsp-mode-20220505.630/lsp-ada.elc
new file mode 100644
index 0000000..3988eff
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-ada.elc
Binary files differ
diff --git a/elpa/lsp-mode-20220505.630/lsp-angular.el b/elpa/lsp-mode-20220505.630/lsp-angular.el
new file mode 100644
index 0000000..f09aa87
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-angular.el
@@ -0,0 +1,101 @@
+;;; lsp-angular.el --- description -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2020 emacs-lsp maintainers
+
+;; Author: emacs-lsp maintainers
+;; Keywords: lsp,
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; LSP Clients for the Angular Web application framework.
+
+;;; Code:
+
+(require 'lsp-mode)
+(require 'f)
+
+
+;;; Angular
+(defgroup lsp-angular nil
+ "Angular LSP client, provided by the Angular Language Service Server."
+ :group 'lsp-mode
+ :version "8.0.0"
+ :link '(url-link "https://github.com/angular/vscode-ng-language-service"))
+
+(defcustom lsp-clients-angular-language-server-command
+ nil
+ "The command that starts the angular language server."
+ :group 'lsp-angular
+ :type '(choice
+ (string :tag "Single string value")
+ (repeat :tag "List of string values"
+ string)))
+
+(defcustom lsp-clients-angular-node-get-prefix-command
+ "npm config get --global prefix"
+ "The shell command that returns the path of NodeJS's prefix.
+Has no effects when `lsp-clients-angular-language-server-command' is set."
+ :group 'lsp-angular
+ :type 'string)
+
+(defun lsp-client--angular-start-loading (_workspace params)
+ (lsp--info "Started loading project %s" params))
+
+(defun lsp-client--angular-finished-loading (_workspace params)
+ (lsp--info "Finished loading project %s" params))
+
+(lsp-register-client
+ (make-lsp-client
+ :new-connection
+ (lsp-stdio-connection
+ (lambda ()
+ (if lsp-clients-angular-language-server-command
+ lsp-clients-angular-language-server-command
+ (let ((node-modules-path
+ (f-join
+ (string-trim
+ (shell-command-to-string lsp-clients-angular-node-get-prefix-command))
+ "lib/node_modules")))
+ ;; The shell command takes a significant time to run,
+ ;; so we "cache" its results after running once
+ (setq lsp-clients-angular-language-server-command
+ (list
+ "node"
+ (f-join node-modules-path "@angular/language-server")
+ "--ngProbeLocations"
+ node-modules-path
+ "--tsProbeLocations"
+ node-modules-path
+ "--stdio"))
+ lsp-clients-angular-language-server-command))))
+ :activation-fn
+ (lambda (&rest _args)
+ (and (string-match-p "\\(\\.html\\|\\.ts\\)\\'" (buffer-file-name))
+ (lsp-workspace-root)
+ (file-exists-p (f-join (lsp-workspace-root) "angular.json"))))
+ :priority -1
+ :notification-handlers
+ (ht ("angular/projectLoadingStart" #'lsp-client--angular-start-loading)
+ ("angular/projectLoadingFinish" #'lsp-client--angular-finished-loading)
+ ("angular/projectLanguageService" #'ignore))
+ :add-on? t
+ :server-id 'angular-ls))
+
+
+(lsp-consistency-check lsp-angular)
+
+(provide 'lsp-angular)
+;;; lsp-angular.el ends here
diff --git a/elpa/lsp-mode-20220505.630/lsp-angular.elc b/elpa/lsp-mode-20220505.630/lsp-angular.elc
new file mode 100644
index 0000000..4b988a3
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-angular.elc
Binary files differ
diff --git a/elpa/lsp-mode-20220505.630/lsp-ansible.el b/elpa/lsp-mode-20220505.630/lsp-ansible.el
new file mode 100644
index 0000000..8917b65
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-ansible.el
@@ -0,0 +1,186 @@
+;;; lsp-ansible.el --- lsp-mode ansible integration -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2022 emacs-lsp maintainers
+
+;; Author: lsp-mode maintainers
+;; Keywords: lsp, yaml, ansible
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; LSP Client for the Ansible Language
+
+;;; Code:
+
+(require 'lsp-mode)
+
+;;; Ansible
+(defgroup lsp-ansible nil
+ "Settings for the Ansible Language Server."
+ :group 'lsp-mode
+ :link '(url-link "https://github.com/ansible/ansible-language-server")
+ :package-version '(lsp-mode . "8.0.1"))
+
+(defcustom lsp-ansible-language-server-command
+ '("ansible-language-server" "--stdio")
+ "The command that starts the ansible language server."
+ :type '(repeat :tag "List of string values" string)
+ :group 'lsp-ansible
+ :package-version '(lsp-mode . "8.0.1"))
+
+(defcustom lsp-ansible-ansible-path "ansible"
+ "Path to the ansible executable.
+$PATH is searched for the executable."
+ :type 'string
+ :group 'lsp-ansible
+ :package-version '(lsp-mode . "8.0.1"))
+
+(defcustom lsp-ansible-use-fully-qualified-collection-names t
+ "Toggles use of fully qualified collection names when inserting a module name.
+Disabling it will only use FQCNs when necessary, that is when the collection is
+not configured for the task."
+ :type 'boolean
+ :group 'lsp-ansible
+ :package-version '(lsp-mode . "8.0.1"))
+
+(defcustom lsp-ansible-ansible-lint-arguments ""
+ "Optional command line arguments to be appended to ansible-lint invocation.
+See ansible-lint documentation."
+ :type 'string
+ :group 'lsp-ansible
+ :package-version '(lsp-mode . "8.0.1"))
+
+(defcustom lsp-ansible-ansible-lint-enabled t
+ "Enables/disables use of ansible-lint."
+ :type 'boolean
+ :group 'lsp-ansible
+ :package-version '(lsp-mode . "8.0.1"))
+
+(defcustom lsp-ansible-ansible-lint-path "ansible-lint"
+ "Path to the ansible-lint executable.
+$PATH is searched for the executable."
+ :type 'string
+ :group 'lsp-ansible
+ :package-version '(lsp-mode . "8.0.1"))
+
+(defcustom lsp-ansible-ansible-navigator-path "ansible-navigator"
+ "Path to the ansible-navigator executable."
+ :type 'string
+ :group 'lsp-ansible
+ :package-version '(lsp-mode . "8.0.1"))
+
+(defcustom lsp-ansible-ansible-playbook-path "ansible-playbook"
+ "Path to the ansible-playbook executable."
+ :type 'string
+ :group 'lsp-ansible
+ :package-version '(lsp-mode . "8.0.1"))
+
+(defcustom lsp-ansible-execution-environment-container-engine "auto"
+ "The container engine to be used while running with execution environment.
+Valid values are auto, podman and docker. For auto it will look for podman then
+docker."
+ :type '(choice (const "auto")
+ (const "podman")
+ (const "docker"))
+ :group 'lsp-ansible
+ :package-version '(lsp-mode . "8.0.1"))
+
+(defcustom lsp-ansible-execution-environment-enabled nil
+ "Enable or disable the use of an execution environment."
+ :type 'boolean
+ :group 'lsp-ansible
+ :package-version '(lsp-mode . "8.0.1"))
+
+(defcustom lsp-ansible-execution-environment-image "quay.io/ansible/creator-ee:latest"
+ "Specify the name of the execution environment image."
+ :type 'string
+ :group 'lsp-ansible
+ :package-version '(lsp-mode . "8.0.1"))
+
+(defcustom lsp-ansible-execution-environment-pull-policy "missing"
+ "Specify the image pull policy.
+Valid values are always, missing, never and tag. Setting always will always
+pull the image when extension is activated or reloaded. Setting missing will
+pull if not locally available. Setting never will never pull the image and
+setting tag will always pull if the image tag is ‘latest’, otherwise pull
+if not locally available."
+ :type '(choice (const "always")
+ (const "missing")
+ (const "never")
+ (const "tag"))
+ :group 'lsp-ansible
+ :package-version '(lsp-mode . "8.0.1"))
+
+(defcustom lsp-ansible-python-interpreter-path ""
+ "Path to the python/python3 executable.
+This setting may be used to make the extension work with ansible and
+ansible-lint installations in a Python virtual environment."
+ :type 'string
+ :group 'lsp-ansible
+ :package-version '(lsp-mode . "8.0.1"))
+
+(defcustom lsp-ansible-python-activation-script ""
+ "Path to a custom activate script.
+It will be used instead of `lsp-ansible-python-interpreter-path' to run in a
+Python virtual environment."
+ :type 'string
+ :group 'lsp-ansible
+ :package-version '(lsp-mode . "8.0.1"))
+
+(lsp-dependency 'ansible-language-server
+ '(:system "ansible-language-server")
+ '(:npm :package "@ansible/ansible-language-server"
+ :path "ansible-language-server"))
+
+(lsp-register-custom-settings
+ '(("ansible.ansible.path" lsp-ansible-ansible-path)
+ ("ansible.ansible.useFullyQualifiedCollectionNames" lsp-ansible-use-fully-qualified-collection-names t)
+ ("ansible.ansibleLint.arguments" lsp-ansible-ansible-lint-arguments)
+ ("ansible.ansibleLint.enabled" lsp-ansible-ansible-lint-enabled t)
+ ("ansible.ansibleLint.path" lsp-ansible-ansible-lint-path)
+ ("ansible.ansibleNavigator.path" lsp-ansible-ansible-navigator-path)
+ ("ansible.ansiblePlaybook.path" lsp-ansible-ansible-playbook-path)
+ ("ansible.executionEnvironment.containerEngine" lsp-ansible-execution-environment-container-engine)
+ ("ansible.executionEnvironment.enabled" lsp-ansible-execution-environment-enabled t)
+ ("ansible.executionEnvironment.image" lsp-ansible-execution-environment-image)
+ ("ansible.executionEnvironment.pullPolicy" lsp-ansible-execution-environment-pull-policy)
+ ("ansible.python.interpreterPath" lsp-ansible-python-interpreter-path)
+ ("ansible.python.activationScript" lsp-ansible-python-activation-script)))
+
+(defun lsp-ansible-check-ansible-minor-mode (&rest _)
+ "Check whether ansible minor mode is active.
+This prevents the Ansible server from being turned on in all yaml files."
+ (and (eq major-mode 'yaml-mode)
+ ;; emacs-ansible provides ansible, not ansible-mode
+ (with-no-warnings (bound-and-true-p ansible))))
+
+(lsp-register-client
+ (make-lsp-client
+ :new-connection (lsp-stdio-connection
+ (lambda ()
+ `(,(or (executable-find
+ (cl-first lsp-ansible-language-server-command))
+ (lsp-package-path 'ansible-language-server))
+ ,@(cl-rest lsp-ansible-language-server-command))))
+ :priority 1
+ :activation-fn #'lsp-ansible-check-ansible-minor-mode
+ :server-id 'ansible-ls
+ :download-server-fn (lambda (_client callback error-callback _update?)
+ (lsp-package-ensure 'ansible-language-server callback error-callback))))
+
+(lsp-consistency-check lsp-ansible)
+
+(provide 'lsp-ansible)
+;;; lsp-ansible.el ends here
diff --git a/elpa/lsp-mode-20220505.630/lsp-ansible.elc b/elpa/lsp-mode-20220505.630/lsp-ansible.elc
new file mode 100644
index 0000000..ac9f272
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-ansible.elc
Binary files differ
diff --git a/elpa/lsp-mode-20220505.630/lsp-bash.el b/elpa/lsp-mode-20220505.630/lsp-bash.el
new file mode 100644
index 0000000..ee8a28e
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-bash.el
@@ -0,0 +1,90 @@
+;;; lsp-bash.el --- description -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2020 emacs-lsp maintainers
+
+;; Author: emacs-lsp maintainers
+;; Keywords: lsp, bash, shell-script
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; LSP Clients for the Bash Programming Language
+
+;;; Code:
+
+(require 'lsp-mode)
+
+;;; Bash
+(defgroup lsp-bash nil
+ "Settings for the Bash Language Server."
+ :group 'lsp-mode
+ :link '(url-link "https://github.com/bash-lsp/bash-language-server")
+ :package-version '(lsp-mode . "6.2"))
+
+(defcustom lsp-bash-explainshell-endpoint nil
+ "The endpoint to use explainshell.com to answer 'onHover' queries.
+See instructions at https://marketplace.visualstudio.com/items?itemName=mads-hartmann.bash-ide-vscode"
+ :type 'string
+ :risky t
+ :group 'lsp-bash
+ :package-version '(lsp-mode . "6.2"))
+
+(defcustom lsp-bash-highlight-parsing-errors nil
+ "Consider parsing errors in scripts as 'problems'."
+ :type 'boolean
+ :group 'lsp-bash
+ :package-version '(lsp-mode . "6.2"))
+
+(defcustom lsp-bash-glob-pattern nil
+ "Glob pattern used to find shell script files to parse."
+ :type 'string
+ :group 'lsp-bash
+ :package-version '(lsp-mode . "6.3"))
+
+(defun lsp-bash--bash-ls-server-command ()
+ "Startup command for Bash language server."
+ (list (lsp-package-path 'bash-language-server) "start"))
+
+(lsp-dependency 'bash-language-server
+ '(:system "bash-language-server")
+ '(:npm :package "bash-language-server"
+ :path "bash-language-server"))
+
+(defvar sh-shell)
+
+(defun lsp-bash-check-sh-shell (&rest _)
+ "Check whether `sh-shell' is sh or bash.
+
+This prevents the Bash server from being turned on in zsh files."
+ (and (eq major-mode 'sh-mode)
+ (memq sh-shell '(sh bash))))
+
+(lsp-register-client
+ (make-lsp-client
+ :new-connection (lsp-stdio-connection #'lsp-bash--bash-ls-server-command)
+ :priority -1
+ :activation-fn #'lsp-bash-check-sh-shell
+ :environment-fn (lambda ()
+ '(("EXPLAINSHELL_ENDPOINT" . lsp-bash-explainshell-endpoint)
+ ("HIGHLIGHT_PARSING_ERRORS" . lsp-bash-highlight-parsing-errors)
+ ("GLOB_PATTERN" . lsp-bash-glob-pattern)))
+ :server-id 'bash-ls
+ :download-server-fn (lambda (_client callback error-callback _update?)
+ (lsp-package-ensure 'bash-language-server callback error-callback))))
+
+(lsp-consistency-check lsp-bash)
+
+(provide 'lsp-bash)
+;;; lsp-bash.el ends here
diff --git a/elpa/lsp-mode-20220505.630/lsp-bash.elc b/elpa/lsp-mode-20220505.630/lsp-bash.elc
new file mode 100644
index 0000000..c508441
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-bash.elc
Binary files differ
diff --git a/elpa/lsp-mode-20220505.630/lsp-beancount.el b/elpa/lsp-mode-20220505.630/lsp-beancount.el
new file mode 100644
index 0000000..d2125e8
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-beancount.el
@@ -0,0 +1,71 @@
+;;; lsp-beancount.el --- Beancount Client settings -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2021 emacs-lsp maintainers
+
+;; Author: emacs-lsp maintainers
+;; Keywords: lsp, beancount
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; LSP client for Beancount
+
+;;; Code:
+
+(require 'lsp-mode)
+
+(defgroup lsp-beancount nil
+ "Settings for the Beancount Language Server."
+ :group 'lsp-mode
+ :link '(url-link "https://github.com/polarmutex/beancount-language-server")
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-beancount-langserver-executable "beancount-langserver"
+ "Command to start Beancount language server."
+ :type 'string
+ :group 'lsp-beancount
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-beancount-python-interpreter nil
+ "Path to Python executable."
+ :type 'string
+ :group 'lsp-beancount
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-beancount-journal-file nil
+ "Pathg to Beancount journal file."
+ :type 'string
+ :group 'lsp-beancount
+ :package-version '(lsp-mode . "8.0.0"))
+
+(lsp-register-client
+ (make-lsp-client
+ :new-connection
+ (lsp-stdio-connection
+ (lambda ()
+ (when (null lsp-beancount-python-interpreter)
+ (setq lsp-beancount-python-interpreter (or (executable-find "python3")
+ (executable-find "python"))))
+ `(,lsp-beancount-langserver-executable "--stdio")))
+ :major-modes '(beancount-mode)
+ :initialization-options
+ `((journalFile . ,lsp-beancount-journal-file)
+ (pythonPath . ,lsp-beancount-python-interpreter))
+ :server-id 'beancount-ls))
+
+(lsp-consistency-check lsp-beancount)
+
+(provide 'lsp-beancount)
+;;; lsp-beancount.el ends here
diff --git a/elpa/lsp-mode-20220505.630/lsp-beancount.elc b/elpa/lsp-mode-20220505.630/lsp-beancount.elc
new file mode 100644
index 0000000..20afeb5
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-beancount.elc
Binary files differ
diff --git a/elpa/lsp-mode-20220505.630/lsp-clangd.el b/elpa/lsp-mode-20220505.630/lsp-clangd.el
new file mode 100644
index 0000000..1a88877
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-clangd.el
@@ -0,0 +1,315 @@
+;;; lsp-clangd.el --- LSP clients for the C Languages Family -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2020 Daniel Martn & emacs-lsp maintainers
+;; URL: https://github.com/emacs-lsp/lsp-mode
+;; Keywords: languages, c, cpp, clang
+
+;; 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:
+
+;; LSP clients for the C Languages Family.
+
+;; ** Clang-tidy Flycheck integration (Clangd) **
+;;
+;; If you invoke `flycheck-display-error-explanation' on a
+;; `clang-tidy' error (if Clangd is configured to show `clang-tidy'
+;; diagnostics), Emacs will open a detailed explanation about the
+;; message by querying the LLVM website. As an embedded web browser is
+;; used to show the documentation, this feature requires that Emacs is
+;; compiled with libxml2 support.
+
+;;; Code:
+
+(require 'lsp-mode)
+(require 'cl-lib)
+(require 'rx)
+(require 'seq)
+(require 'dom)
+(eval-when-compile (require 'subr-x))
+
+(require 'dash)
+(require 's)
+
+(defvar flycheck-explain-error-buffer)
+(declare-function flycheck-error-id "ext:flycheck" (err) t)
+(declare-function flycheck-error-group "ext:flycheck" (err) t)
+(declare-function flycheck-error-message "ext:flycheck" (err) t)
+
+(defcustom lsp-clangd-version "13.0.0"
+ "Clangd version to download.
+It has to be set before `lsp-clangd.el' is loaded and it has to
+be available here: https://github.com/clangd/clangd/releases/"
+ :type 'string
+ :group 'lsp-clangd
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-clangd-download-url
+ (format (pcase system-type
+ ('darwin "https://github.com/clangd/clangd/releases/download/%s/clangd-mac-%s.zip")
+ ('windows-nt "https://github.com/clangd/clangd/releases/download/%s/clangd-windows-%s.zip")
+ (_ "https://github.com/clangd/clangd/releases/download/%s/clangd-linux-%s.zip"))
+ lsp-clangd-version
+ lsp-clangd-version)
+ "Automatic download url for clangd"
+ :type 'string
+ :group 'lsp-clangd
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-clangd-binary-path
+ (f-join lsp-server-install-dir (format "clangd/clangd_%s/bin"
+ lsp-clangd-version)
+ (pcase system-type
+ ('windows-nt "clangd.exe")
+ (_ "clangd")))
+ "The path to `clangd' binary."
+ :type 'file
+ :group 'lsp-clangd
+ :package-version '(lsp-mode . "8.0.0"))
+
+(lsp-dependency
+ 'clangd
+ `(:download :url lsp-clangd-download-url
+ :decompress :zip
+ :store-path ,(f-join lsp-server-install-dir "clangd" "clangd.zip")
+ :binary-path lsp-clangd-binary-path
+ :set-executable? t))
+
+(defun lsp-cpp-flycheck-clang-tidy--skip-http-headers ()
+ "Position point just after HTTP headers."
+ (re-search-forward "^$"))
+
+(defun lsp-cpp-flycheck-clang-tidy--narrow-to-http-body ()
+ "Narrow the current buffer to contain the body of an HTTP response."
+ (lsp-cpp-flycheck-clang-tidy--skip-http-headers)
+ (narrow-to-region (point) (point-max)))
+
+(defun lsp-cpp-flycheck-clang-tidy--decode-region-as-utf8 (start end)
+ "Decode a region from START to END in UTF-8."
+ (condition-case nil
+ (decode-coding-region start end 'utf-8)
+ (coding-system-error nil)))
+
+(defun lsp-cpp-flycheck-clang-tidy--remove-crlf ()
+ "Remove carriage return and line feeds from the current buffer."
+ (save-excursion
+ (while (re-search-forward "\r$" nil t)
+ (replace-match "" t t))))
+
+(defun lsp-cpp-flycheck-clang-tidy--extract-relevant-doc-section ()
+ "Extract the parts of the LLVM clang-tidy documentation that are relevant.
+
+This function assumes that the current buffer contains the result
+of browsing 'clang.llvm.org', as returned by `url-retrieve'.
+More concretely, this function returns the main <div> element
+with class 'section', and also removes 'headerlinks'."
+ (goto-char (point-min))
+ (lsp-cpp-flycheck-clang-tidy--narrow-to-http-body)
+ (lsp-cpp-flycheck-clang-tidy--decode-region-as-utf8 (point-min) (point-max))
+ (lsp-cpp-flycheck-clang-tidy--remove-crlf)
+ (let* ((dom (libxml-parse-html-region (point-min) (point-max)))
+ (section (dom-by-class dom "section")))
+ (dolist (headerlink (dom-by-class section "headerlink"))
+ (dom-remove-node section headerlink))
+ section))
+
+(defun lsp-cpp-flycheck-clang-tidy--explain-error (explanation &rest args)
+ "Explain an error in the Flycheck error explanation buffer using EXPLANATION.
+
+EXPLANATION is a function with optional ARGS that, when
+evaluated, inserts the content in the appropriate Flycheck
+buffer."
+ (with-current-buffer flycheck-explain-error-buffer
+ (let ((inhibit-read-only t)
+ (inhibit-modification-hooks t))
+ (erase-buffer)
+ (apply explanation args)
+ (goto-char (point-min)))))
+
+(defun lsp-cpp-flycheck-clang-tidy--show-loading-status ()
+ "Show a loading string while clang-tidy documentation is fetched from llvm.org.
+Recent versions of `flycheck' call `display-message-or-buffer' to
+display error explanations. `display-message-or-buffer' displays
+the documentation string either in the echo area or in a separate
+window, depending on the string's height. This function forces to
+always display it in a separate window by appending the required
+number of newlines."
+ (let* ((num-lines-threshold
+ (round (if resize-mini-windows
+ (cond ((floatp max-mini-window-height)
+ (* (frame-height)
+ max-mini-window-height))
+ ((integerp max-mini-window-height)
+ max-mini-window-height)
+ (t
+ 1))
+ 1)))
+ (extra-new-lines (make-string (1+ num-lines-threshold) ?\n)))
+ (concat "Loading documentation..." extra-new-lines)))
+
+(defun lsp-cpp-flycheck-clang-tidy--show-documentation (error-id)
+ "Show clang-tidy documentation about ERROR-ID.
+
+Information comes from the clang.llvm.org website."
+ (url-retrieve (format
+ "https://clang.llvm.org/extra/clang-tidy/checks/%s.html" error-id)
+ (lambda (status)
+ (if-let ((error-status (plist-get status :error)))
+ (lsp-cpp-flycheck-clang-tidy--explain-error
+ #'insert
+ (format
+ "Error accessing clang-tidy documentation: %s"
+ (error-message-string error-status)))
+ (let ((doc-contents
+ (lsp-cpp-flycheck-clang-tidy--extract-relevant-doc-section)))
+ (lsp-cpp-flycheck-clang-tidy--explain-error
+ #'shr-insert-document doc-contents)))))
+ (lsp-cpp-flycheck-clang-tidy--show-loading-status))
+
+;;;###autoload
+(defun lsp-cpp-flycheck-clang-tidy-error-explainer (error)
+ "Explain a clang-tidy ERROR by scraping documentation from llvm.org."
+ (unless (fboundp 'libxml-parse-html-region)
+ (error "This function requires Emacs to be compiled with libxml2"))
+ (if-let ((clang-tidy-error-id (flycheck-error-id error)))
+ (condition-case err
+ (lsp-cpp-flycheck-clang-tidy--show-documentation clang-tidy-error-id)
+ (error
+ (format
+ "Error accessing clang-tidy documentation: %s"
+ (error-message-string err))))
+ (error "The clang-tidy error message does not contain an [error-id]")))
+
+
+;;; lsp-clangd
+(defgroup lsp-clangd nil
+ "LSP support for C-family languages (C, C++, Objective-C, Objective-C++), using clangd."
+ :group 'lsp-mode
+ :link '(url-link "https://clang.llvm.org/extra/clangd"))
+
+(defcustom lsp-clients-clangd-executable nil
+ "The clangd executable to use.
+When `'non-nil' use the name of the clangd executable file
+available in your path to use. Otherwise the system will try to
+find a suitable one. Set this variable before loading lsp."
+ :group 'lsp-clangd
+ :risky t
+ :type '(choice (file :tag "Path")
+ (const :tag "Auto" nil)))
+
+(defvar lsp-clients--clangd-default-executable nil
+ "Clang default executable full path when found.
+This must be set only once after loading the clang client.")
+
+(defcustom lsp-clients-clangd-args '("--header-insertion-decorators=0")
+ "Extra arguments for the clangd executable."
+ :group 'lsp-clangd
+ :risky t
+ :type '(repeat string))
+
+(defcustom lsp-clients-clangd-library-directories '("/usr")
+ "List of directories which will be considered to be libraries."
+ :risky t
+ :type '(repeat string)
+ :group 'lsp-clangd
+ :package-version '(lsp-mode . "8.0.1"))
+
+(defun lsp-clients--clangd-command ()
+ "Generate the language server startup command."
+ (unless lsp-clients--clangd-default-executable
+ (setq lsp-clients--clangd-default-executable
+ (or (lsp-package-path 'clangd)
+ (-first #'executable-find
+ (-map (lambda (version)
+ (concat "clangd" version))
+ ;; Prefer `clangd` without a version number appended.
+ (cl-list* "" (-map
+ (lambda (vernum) (format "-%d" vernum))
+ (number-sequence 14 6 -1)))))
+ (lsp-clients-executable-find "xcodebuild" "-find-executable" "clangd")
+ (lsp-clients-executable-find "xcrun" "--find" "clangd"))))
+
+ `(,(or lsp-clients-clangd-executable lsp-clients--clangd-default-executable "clangd")
+ ,@lsp-clients-clangd-args))
+
+(lsp-register-client
+ (make-lsp-client :new-connection (lsp-stdio-connection
+ 'lsp-clients--clangd-command)
+ :activation-fn (lsp-activate-on "c" "cpp" "objective-c")
+ :priority -1
+ :server-id 'clangd
+ :library-folders-fn (lambda (_workspace) lsp-clients-clangd-library-directories)
+ :download-server-fn (lambda (_client callback error-callback _update?)
+ (lsp-package-ensure 'clangd callback error-callback))))
+
+(defun lsp-clangd-join-region (beg end)
+ "Apply join-line from BEG to END.
+This function is useful when an indented function prototype needs
+to be shown in a single line."
+ (save-excursion
+ (let ((end (copy-marker end)))
+ (goto-char beg)
+ (while (< (point) end)
+ (join-line 1)))
+ (s-trim (buffer-string))))
+
+(cl-defmethod lsp-clients-extract-signature-on-hover (contents (_server-id (eql clangd)))
+ "Extract a representative line from clangd's CONTENTS, to show in the echo area.
+This function tries to extract the type signature from CONTENTS,
+or the first line if it cannot do so. A single line is always
+returned to avoid that the echo area grows uncomfortably."
+ (with-temp-buffer
+ (-let [value (lsp:markup-content-value contents)]
+ (insert value)
+ (goto-char (point-min))
+ (if (re-search-forward (rx (seq "```cpp\n"
+ (opt (group "//"
+ (zero-or-more nonl)
+ "\n"))
+ (group
+ (one-or-more
+ (not (any "`")))
+ "\n")
+ "```")) nil t nil)
+ (progn (narrow-to-region (match-beginning 2) (match-end 2))
+ (lsp--render-element (lsp-make-marked-string
+ :language "cpp"
+ :value (lsp-clangd-join-region (point-min) (point-max)))))
+ (car (s-lines (lsp--render-element contents)))))))
+
+(cl-defmethod lsp-diagnostics-flycheck-error-explainer (e (_server-id (eql clangd)))
+ "Explain a `flycheck-error' E that was generated by the Clangd language server."
+ (cond ((string-equal "clang-tidy" (flycheck-error-group e))
+ (lsp-cpp-flycheck-clang-tidy-error-explainer e))
+ (t (flycheck-error-message e))))
+
+(defun lsp-clangd-find-other-file (&optional new-window)
+ "Switch between the corresponding C/C++ source and header file.
+If NEW-WINDOW (interactively the prefix argument) is non-nil,
+open in a new window.
+
+Only works with clangd."
+ (interactive "P")
+ (let ((other (lsp-send-request (lsp-make-request
+ "textDocument/switchSourceHeader"
+ (lsp--text-document-identifier)))))
+ (unless (s-present? other)
+ (user-error "Could not find other file"))
+ (funcall (if new-window #'find-file-other-window #'find-file)
+ (lsp--uri-to-path other))))
+
+(lsp-consistency-check lsp-clangd)
+
+(provide 'lsp-clangd)
+;;; lsp-clangd.el ends here
diff --git a/elpa/lsp-mode-20220505.630/lsp-clangd.elc b/elpa/lsp-mode-20220505.630/lsp-clangd.elc
new file mode 100644
index 0000000..0357087
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-clangd.elc
Binary files differ
diff --git a/elpa/lsp-mode-20220505.630/lsp-clojure.el b/elpa/lsp-mode-20220505.630/lsp-clojure.el
new file mode 100644
index 0000000..d0d9439
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-clojure.el
@@ -0,0 +1,448 @@
+;;; lsp-clojure.el --- Clojure Client settings -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2019 Benedek Fazekas
+
+;; Author: Benedek Fazekas <benedek.fazekas@gmail.com>
+;; Keywords: languages,tools
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; lsp-clojure client
+
+;;; Code:
+
+(require 'lsp-mode)
+(require 'lsp-protocol)
+(require 'cl-lib)
+(require 'lsp-semantic-tokens)
+
+(defgroup lsp-clojure nil
+ "LSP support for Clojure."
+ :link '(url-link "https://github.com/snoe/clojure-lsp")
+ :group 'lsp-mode
+ :tag "Lsp Clojure")
+
+(define-obsolete-variable-alias 'lsp-clojure-server-command
+ 'lsp-clojure-custom-server-command "lsp-mode 8.0.0")
+
+(defcustom lsp-clojure-custom-server-command nil
+ "The clojure-lisp server command."
+ :group 'lsp-clojure
+ :risky t
+ :type '(repeat string))
+
+(defcustom lsp-clojure-server-download-url
+ (format "https://github.com/clojure-lsp/clojure-lsp/releases/latest/download/clojure-lsp-native-%s-amd64.zip"
+ (pcase system-type
+ ('gnu/linux "linux")
+ ('darwin "macos")
+ ('windows-nt "windows")))
+ "Automatic download url for lsp-clojure."
+ :type 'string
+ :group 'lsp-clojure
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-clojure-server-store-path
+ (f-join lsp-server-install-dir
+ "clojure"
+ (if (eq system-type 'windows-nt)
+ "clojure-lsp.exe"
+ "clojure-lsp"))
+ "The path to the file in which `clojure-lsp' will be stored."
+ :type 'file
+ :group 'lsp-clojure
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-clojure-workspace-dir (expand-file-name (locate-user-emacs-file "workspace/"))
+ "LSP clojure workspace directory."
+ :group 'lsp-clojure
+ :risky t
+ :type 'directory)
+
+(defcustom lsp-clojure-workspace-cache-dir (expand-file-name ".cache/" lsp-clojure-workspace-dir)
+ "LSP clojure workspace cache directory."
+ :group 'lsp-clojure
+ :risky t
+ :type 'directory)
+
+(defcustom lsp-clojure-test-tree-position-params nil
+ "The optional test tree position params.
+Defaults to side following treemacs default."
+ :type 'list
+ :group 'lsp-clojure)
+
+;; Internal
+
+(lsp-interface
+ (Clojure:CursorInfoParams (:textDocument :position) nil))
+
+(lsp-dependency
+ 'clojure-lsp
+ `(:download :url lsp-clojure-server-download-url
+ :decompress :zip
+ :store-path lsp-clojure-server-store-path
+ :set-executable? t)
+ '(:system "clojure-lsp"))
+
+;; Refactorings
+
+(defun lsp-clojure--execute-command (command &optional args)
+ "Send an executeCommand request for COMMAND with ARGS."
+ (lsp--cur-workspace-check)
+ (lsp-send-execute-command command (apply #'vector args)))
+
+(defun lsp-clojure--refactoring-call (refactor-name &rest additional-args)
+ "Send an executeCommand request for REFACTOR-NAME with ADDITIONAL-ARGS.
+If there are more arguments expected after the line and column numbers."
+ (lsp--cur-workspace-check)
+ (lsp-clojure--execute-command refactor-name (cl-list* (lsp--buffer-uri)
+ (- (line-number-at-pos) 1) ;; clojure-lsp expects line numbers to start at 0
+ (current-column)
+ additional-args)))
+
+(defun lsp-clojure-add-import-to-namespace (import-name)
+ "Add to IMPORT-NAME to :import form."
+ (interactive "MImport name: ")
+ (lsp-clojure--refactoring-call "add-import-to-namespace" import-name))
+
+(defun lsp-clojure-add-missing-libspec ()
+ "Apply add-missing-libspec refactoring at point."
+ (interactive)
+ (lsp-clojure--refactoring-call "add-missing-libspec"))
+
+(defun lsp-clojure-clean-ns ()
+ "Apply clean-ns refactoring at point."
+ (interactive)
+ (lsp-clojure--refactoring-call "clean-ns"))
+
+(defun lsp-clojure-cycle-coll ()
+ "Apply cycle-coll refactoring at point."
+ (interactive)
+ (lsp-clojure--refactoring-call "cycle-coll"))
+
+(defun lsp-clojure-cycle-privacy ()
+ "Apply cycle-privacy refactoring at point."
+ (interactive)
+ (lsp-clojure--refactoring-call "cycle-privacy"))
+
+(defun lsp-clojure-expand-let ()
+ "Apply expand-let refactoring at point."
+ (interactive)
+ (lsp-clojure--refactoring-call "expand-let"))
+
+(defun lsp-clojure-extract-function (function-name)
+ "Move form at point into a new function named FUNCTION-NAME."
+ (interactive "MFunction name: ") ;; Name of the function
+ (lsp-clojure--refactoring-call "extract-function" function-name))
+
+(defun lsp-clojure-inline-symbol ()
+ "Apply inline-symbol refactoring at point."
+ (interactive)
+ (lsp-clojure--refactoring-call "inline-symbol"))
+
+(defun lsp-clojure-introduce-let (binding-name)
+ "Move form at point into a new let binding as BINDING-NAME."
+ (interactive "MBinding name: ") ;; Name of the let binding
+ (lsp-clojure--refactoring-call "introduce-let" binding-name))
+
+(defun lsp-clojure-move-to-let (binding-name)
+ "Move form at point into nearest existing let binding as BINDING-NAME."
+ (interactive "MBinding name: ") ;; Name of the let binding
+ (lsp-clojure--refactoring-call "move-to-let" binding-name))
+
+(defun lsp-clojure-thread-first ()
+ "Apply thread-first refactoring at point."
+ (interactive)
+ (lsp-clojure--refactoring-call "thread-first"))
+
+(defun lsp-clojure-thread-first-all ()
+ "Apply thread-first-all refactoring at point."
+ (interactive)
+ (lsp-clojure--refactoring-call "thread-first-all"))
+
+(defun lsp-clojure-thread-last ()
+ "Apply thread-last refactoring at point."
+ (interactive)
+ (lsp-clojure--refactoring-call "thread-last"))
+
+(defun lsp-clojure-thread-last-all ()
+ "Apply thread-last-all refactoring at point."
+ (interactive)
+ (lsp-clojure--refactoring-call "thread-last-all"))
+
+(defun lsp-clojure-unwind-all ()
+ "Apply unwind-all refactoring at point."
+ (interactive)
+ (lsp-clojure--refactoring-call "unwind-all"))
+
+(defun lsp-clojure-unwind-thread ()
+ "Apply unwind-thread refactoring at point."
+ (interactive)
+ (lsp-clojure--refactoring-call "unwind-thread"))
+
+(defun lsp-clojure-create-function ()
+ "Apply create-function refactoring at point."
+ (interactive)
+ (lsp-clojure--refactoring-call "create-function"))
+
+(defun lsp-clojure-create-test ()
+ "Apply create-test refactoring at point."
+ (interactive)
+ (lsp-clojure--refactoring-call "create-test"))
+
+(defun lsp-clojure-sort-map ()
+ "Apply sort-map refactoring at point."
+ (interactive)
+ (lsp-clojure--refactoring-call "sort-map"))
+
+(defun lsp-clojure-move-coll-entry-up ()
+ "Apply move coll entry up refactoring at point."
+ (interactive)
+ (lsp-clojure--refactoring-call "move-coll-entry-up"))
+
+(defun lsp-clojure-move-coll-entry-down ()
+ "Apply move coll entry down refactoring at point."
+ (interactive)
+ (lsp-clojure--refactoring-call "move-coll-entry-down"))
+
+(defun lsp-clojure-move-form ()
+ "Apply move-form refactoring at point."
+ (interactive)
+ (lsp-clojure--refactoring-call "move-form" "/home/greg/dev/clojure-lsp/lib/src/clojure_lsp/shared.clj"))
+
+(defun lsp-clojure-server-info ()
+ "Request server info."
+ (interactive)
+ (lsp--cur-workspace-check)
+ (lsp-notify "clojure/serverInfo/log" nil))
+
+(defvar lsp-clojure-server-buffer-name "*lsp-clojure-server-log*")
+
+(defun lsp-clojure--server-log-revert-function (original-file-log-buffer &rest _)
+ "Spit contents to ORIGINAL-FILE-LOG-BUFFER."
+ (with-current-buffer (get-buffer-create lsp-clojure-server-buffer-name)
+ (erase-buffer)
+ (insert (with-current-buffer original-file-log-buffer (buffer-string)))
+ (goto-char (point-max))
+ (read-only-mode)))
+
+(defun lsp-clojure-server-log ()
+ "Open a buffer with the server logs."
+ (interactive)
+ (lsp--cur-workspace-check)
+ (let* ((log-path (-> (lsp--json-serialize (lsp-request "clojure/serverInfo/raw" nil))
+ (lsp--read-json)
+ (lsp-get :log-path)))
+ (original-file-log-buffer (find-file-noselect log-path)))
+ (with-current-buffer original-file-log-buffer
+ (add-hook 'after-revert-hook (-partial #'lsp-clojure--server-log-revert-function original-file-log-buffer) nil t)
+ (auto-revert-tail-mode)
+ (read-only-mode))
+ (lsp-clojure--server-log-revert-function original-file-log-buffer)
+ (switch-to-buffer lsp-clojure-server-buffer-name)))
+
+(defun lsp-clojure-server-info-raw ()
+ "Request server info raw data."
+ (interactive)
+ (lsp--cur-workspace-check)
+ (message "%s" (lsp--json-serialize (lsp-request "clojure/serverInfo/raw" nil))))
+
+(defun lsp-clojure-cursor-info ()
+ "Request cursor info at point."
+ (interactive)
+ (lsp--cur-workspace-check)
+ (lsp-notify "clojure/cursorInfo/log"
+ (lsp-make-clojure-cursor-info-params
+ :textDocument (lsp-make-text-document-identifier :uri (lsp--buffer-uri))
+ :position (lsp-make-position :line (- (line-number-at-pos) 1)
+ :character (current-column)))))
+
+(defun lsp-clojure-resolve-macro-as ()
+ "Ask to user how the unresolved macro should be resolved."
+ (interactive)
+ (lsp--cur-workspace-check)
+ (lsp-clojure--execute-command "resolve-macro-as"
+ (list (lsp--buffer-uri)
+ (- (line-number-at-pos) 1) ;; clojure-lsp expects line numbers to start at 0
+ (current-column))))
+
+(defun lsp-clojure--ensure-dir (path)
+ "Ensure that directory PATH exists."
+ (unless (file-directory-p path)
+ (make-directory path t)))
+
+(defun lsp-clojure--get-metadata-location (file-location)
+ "Given a FILE-LOCATION return the file containing the metadata for the file."
+ (format "%s.%s.metadata"
+ (file-name-directory file-location)
+ (file-name-base file-location)))
+
+(defun lsp-clojure--file-in-jar (uri)
+ "Check URI for a valid jar and include it in workspace."
+ (string-match "^\\(jar\\|zip\\):\\(file:.+\\)!/\\(.+\\)" uri)
+ (let* ((ns-path (match-string 3 uri))
+ (ns (s-replace "/" "." ns-path))
+ (file-location (concat lsp-clojure-workspace-cache-dir ns)))
+ (unless (file-readable-p file-location)
+ (lsp-clojure--ensure-dir (file-name-directory file-location))
+ (with-lsp-workspace (lsp-find-workspace 'clojure-lsp nil)
+ (let ((content (lsp-send-request (lsp-make-request "clojure/dependencyContents" (list :uri uri)))))
+ (with-temp-file file-location
+ (insert content))
+ (with-temp-file (lsp-clojure--get-metadata-location file-location)
+ (insert uri)))))
+ file-location))
+
+(defun lsp-clojure--server-executable-path ()
+ "Return the clojure-lsp server command."
+ (or (executable-find "clojure-lsp")
+ (lsp-package-path 'clojure-lsp)))
+
+(lsp-defun lsp-clojure--show-references ((&Command :arguments? args))
+ "Show references for command with ARGS.
+ARGS is a vector which the first element is the uri, the second the line
+and the third the column."
+ (lsp-show-xrefs
+ (lsp--locations-to-xref-items
+ (lsp-request "textDocument/references"
+ (lsp--make-reference-params
+ (lsp--text-document-position-params
+ (list :uri (seq-elt args 0))
+ (list :line (1- (seq-elt args 1))
+ :character (1- (seq-elt args 2)))))))
+ t
+ t))
+
+(defvar-local lsp-clojure--test-tree-data nil)
+(defconst lsp-clojure--test-tree-buffer-name "*Clojure Test Tree*")
+
+(defvar treemacs-position)
+(defvar treemacs-width)
+(declare-function lsp-treemacs-render "ext:lsp-treemacs" (tree title expand-depth &optional buffer-name))
+(declare-function lsp-treemacs--open-file-in-mru "ext:lsp-treemacs" (file))
+
+(defun lsp-clojure--test-tree-ret-action (uri range)
+ "Build the ret action for an item in the test tree view.
+URI is the source of the item.
+RANGE is the range of positions to where this item should point."
+ (interactive)
+ (lsp-treemacs--open-file-in-mru (lsp--uri-to-path uri))
+ (goto-char (lsp--position-to-point (lsp:range-start range)))
+ (run-hooks 'xref-after-jump-hook))
+
+(lsp-defun lsp-clojure--test-tree-data->tree (uri (&clojure-lsp:TestTreeNode :name :range :kind :children?))
+ "Builds a test tree.
+URI is the source of the test tree.
+NODE is the node with all test children data."
+ (-let* ((icon (cl-case kind
+ (1 'namespace)
+ (2 'method)
+ (3 'field)))
+ (base-tree (list :key name
+ :label name
+ :icon icon
+ :ret-action (lambda (&rest _) (lsp-clojure--test-tree-ret-action uri range))
+ :uri uri)))
+ (if (seq-empty-p children?)
+ base-tree
+ base-tree
+ (plist-put base-tree :children (seq-map (-partial #'lsp-clojure--test-tree-data->tree uri) children?)))))
+
+(lsp-defun lsp-clojure--render-test-tree ((&clojure-lsp:TestTreeParams :uri :tree))
+ "Render a test tree view for current test tree buffer data."
+ (save-excursion
+ (lsp-treemacs-render
+ (list (lsp-clojure--test-tree-data->tree uri tree))
+ "Clojure Test Tree"
+ t
+ lsp-clojure--test-tree-buffer-name)))
+
+(defun lsp-clojure--show-test-tree (ignore-focus?)
+ "Show a test tree for current buffer.
+Focus on it if IGNORE-FOCUS? is nil."
+ (if lsp-clojure--test-tree-data
+ (-let* ((tree-buffer (lsp-clojure--render-test-tree lsp-clojure--test-tree-data))
+ (position-params (or lsp-clojure-test-tree-position-params
+ `((side . ,treemacs-position)
+ (slot . 2)
+ (window-width . ,treemacs-width))))
+ (window (display-buffer-in-side-window tree-buffer position-params)))
+ (unless ignore-focus?
+ (select-window window)
+ (set-window-dedicated-p window t)))
+ (unless ignore-focus?
+ (lsp-log "No Clojure test tree data found."))))
+
+(lsp-defun lsp-clojure--handle-test-tree (_workspace (notification &as &clojure-lsp:TestTreeParams :uri))
+ "Test tree notification handler for workspace WORKSPACE.
+NOTIFICATION is the test tree notification data received from server.
+It updates the test tree view data."
+ (when (require 'lsp-treemacs nil t)
+ (when-let (buffer (find-buffer-visiting (lsp--uri-to-path uri)))
+ (with-current-buffer buffer
+ (setq lsp-clojure--test-tree-data notification)
+ (when (get-buffer-window lsp-clojure--test-tree-buffer-name)
+ (lsp-clojure--show-test-tree t))))))
+
+;;;###autoload
+(defun lsp-clojure-show-test-tree (ignore-focus?)
+ "Show a test tree and focus on it if IGNORE-FOCUS? is nil."
+ (interactive "P")
+ (if (require 'lsp-treemacs nil t)
+ (lsp-clojure--show-test-tree ignore-focus?)
+ (error "The package lsp-treemacs is not installed")))
+
+(lsp-register-client
+ (make-lsp-client
+ :download-server-fn (lambda (_client callback error-callback _update?)
+ (lsp-package-ensure 'clojure-lsp callback error-callback))
+ :semantic-tokens-faces-overrides '(:types (("macro" . font-lock-keyword-face)
+ ("keyword" . clojure-keyword-face)
+ ("event" . default)))
+ :new-connection (lsp-stdio-connection
+ (lambda ()
+ (or lsp-clojure-custom-server-command
+ `(,(lsp-clojure--server-executable-path))))
+ (lambda ()
+ (or lsp-clojure-custom-server-command
+ (lsp-clojure--server-executable-path))))
+ :major-modes '(clojure-mode clojurec-mode clojurescript-mode)
+ :library-folders-fn (lambda (_workspace) (list lsp-clojure-workspace-cache-dir))
+ :uri-handlers (lsp-ht ("jar" #'lsp-clojure--file-in-jar))
+ :action-handlers (lsp-ht ("code-lens-references" #'lsp-clojure--show-references))
+ :notification-handlers (lsp-ht ("clojure/textDocument/testTree" #'lsp-clojure--handle-test-tree))
+ :initialization-options '(:dependency-scheme "jar"
+ :show-docs-arity-on-same-line? t)
+ :custom-capabilities `((experimental . ((testTree . ,(and (require 'lsp-treemacs nil t) t)))))
+ :server-id 'clojure-lsp))
+
+(lsp-consistency-check lsp-clojure)
+
+;; Cider integration
+
+(defun lsp-clojure-semantic-tokens-refresh (&rest _)
+ "Force refresh semantic tokens."
+ (when (and lsp-semantic-tokens-enable
+ (lsp-find-workspace 'clojure-lsp (buffer-file-name)))
+ (lsp-semantic-tokens--enable)))
+
+(with-eval-after-load 'cider
+ (when lsp-semantic-tokens-enable
+ ;; refresh tokens as cider flush font-faces after disconnected
+ (add-hook 'cider-mode-hook #'lsp-clojure-semantic-tokens-refresh)))
+
+(provide 'lsp-clojure)
+;;; lsp-clojure.el ends here
diff --git a/elpa/lsp-mode-20220505.630/lsp-clojure.elc b/elpa/lsp-mode-20220505.630/lsp-clojure.elc
new file mode 100644
index 0000000..f3f6e90
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-clojure.elc
Binary files differ
diff --git a/elpa/lsp-mode-20220505.630/lsp-cmake.el b/elpa/lsp-mode-20220505.630/lsp-cmake.el
new file mode 100644
index 0000000..beffa5d
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-cmake.el
@@ -0,0 +1,43 @@
+;;; lsp-cmake.el --- description -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2020 emacs-lsp maintainers
+
+;; Author: emacs-lsp maintainers
+;; Keywords: lsp, cmake
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; LSP Clients for the CMake build tool.
+
+;;; Code:
+
+(require 'lsp-mode)
+
+(defgroup lsp-cmake nil
+ "LSP support for CMake, using cmake-language-server."
+ :group 'lsp-mode
+ :link '(url-link "https://github.com/regen100/cmake-language-server"))
+
+(lsp-register-client
+ (make-lsp-client :new-connection (lsp-stdio-connection "cmake-language-server")
+ :major-modes '(cmake-mode)
+ :priority -1
+ :server-id 'cmakels))
+
+(lsp-consistency-check lsp-cmake)
+
+(provide 'lsp-cmake)
+;;; lsp-cmake.el ends here
diff --git a/elpa/lsp-mode-20220505.630/lsp-cmake.elc b/elpa/lsp-mode-20220505.630/lsp-cmake.elc
new file mode 100644
index 0000000..a30fa1d
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-cmake.elc
Binary files differ
diff --git a/elpa/lsp-mode-20220505.630/lsp-completion.el b/elpa/lsp-mode-20220505.630/lsp-completion.el
new file mode 100644
index 0000000..3fb1bbc
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-completion.el
@@ -0,0 +1,818 @@
+;;; lsp-completion.el --- LSP completion -*- lexical-binding: t; -*-
+;;
+;; Copyright (C) 2020 emacs-lsp maintainers
+;;
+;; 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 <https://www.gnu.org/licenses/>.
+;;
+;;; Commentary:
+;;
+;; LSP completion
+;;
+;;; Code:
+
+(require 'lsp-mode)
+
+(defgroup lsp-completion nil
+ "LSP support for completion"
+ :prefix "lsp-completion-"
+ :group 'lsp-mode
+ :tag "LSP Completion")
+
+;;;###autoload
+(define-obsolete-variable-alias 'lsp-prefer-capf
+ 'lsp-completion-provider "lsp-mode 7.0.1")
+
+(defcustom lsp-completion-provider :capf
+ "The completion backend provider."
+ :type '(choice
+ (const :tag "Use company-capf" :capf)
+ (const :tag "None" :none))
+ :group 'lsp-completion
+ :package-version '(lsp-mode . "7.0.1"))
+
+;;;###autoload
+(define-obsolete-variable-alias 'lsp-enable-completion-at-point
+ 'lsp-completion-enable "lsp-mode 7.0.1")
+
+(defcustom lsp-completion-enable t
+ "Enable `completion-at-point' integration."
+ :type 'boolean
+ :group 'lsp-completion)
+
+(defcustom lsp-completion-enable-additional-text-edit t
+ "Whether or not to apply additional text edit when performing completion.
+
+If set to non-nil, `lsp-mode' will apply additional text edits
+from the server. Otherwise, the additional text edits are
+ignored."
+ :type 'boolean
+ :group 'lsp-completion
+ :package-version '(lsp-mode . "6.3.2"))
+
+(defcustom lsp-completion-show-kind t
+ "Whether or not to show kind of completion candidates."
+ :type 'boolean
+ :group 'lsp-completion
+ :package-version '(lsp-mode . "7.0.1"))
+
+(defcustom lsp-completion-show-detail t
+ "Whether or not to show detail of completion candidates."
+ :type 'boolean
+ :group 'lsp-completion)
+
+(defcustom lsp-completion-show-label-description t
+ "Whether or not to show description of completion candidates."
+ :type 'boolean
+ :group 'lsp-completion
+ :package-version '(lsp-mode . "8.0.1"))
+
+(defcustom lsp-completion-no-cache nil
+ "Whether or not caching the returned completions from server."
+ :type 'boolean
+ :group 'lsp-completion
+ :package-version '(lsp-mode . "7.0.1"))
+
+(defcustom lsp-completion-filter-on-incomplete t
+ "Whether or not filter incomplete results."
+ :type 'boolean
+ :group 'lsp-completion
+ :package-version '(lsp-mode . "7.0.1"))
+
+(defcustom lsp-completion-sort-initial-results t
+ "Whether or not filter initial results from server."
+ :type 'boolean
+ :group 'lsp-completion
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-completion-use-last-result t
+ "Temporarily use last server result when interrupted by keyboard.
+This will help minimize popup flickering issue in `company-mode'."
+ :type 'boolean
+ :group 'lsp-completion
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defconst lsp-completion--item-kind
+ [nil
+ "Text"
+ "Method"
+ "Function"
+ "Constructor"
+ "Field"
+ "Variable"
+ "Class"
+ "Interface"
+ "Module"
+ "Property"
+ "Unit"
+ "Value"
+ "Enum"
+ "Keyword"
+ "Snippet"
+ "Color"
+ "File"
+ "Reference"
+ "Folder"
+ "EnumMember"
+ "Constant"
+ "Struct"
+ "Event"
+ "Operator"
+ "TypeParameter"])
+
+(defvar yas-indent-line)
+(defvar company-backends)
+(defvar company-abort-on-unique-match)
+
+(defvar lsp-completion--no-reordering nil
+ "Dont do client-side reordering completion items when set.")
+
+(declare-function company-mode "ext:company")
+(declare-function yas-expand-snippet "ext:yasnippet")
+
+(defun lsp-doc-buffer (&optional string)
+ (with-current-buffer (get-buffer-create "*lsp-documentation*")
+ (erase-buffer)
+ (fundamental-mode)
+ (when string
+ (save-excursion
+ (insert string)
+ (visual-line-mode)))
+ (current-buffer)))
+
+(defun lsp-falsy? (val)
+ "Non-nil if VAL is falsy."
+ ;; https://developer.mozilla.org/en-US/docs/Glossary/Falsy
+ (or (not val) (equal val "") (equal val 0)))
+
+(cl-defun lsp-completion--make-item (item &key markers prefix)
+ "Make completion item from lsp ITEM and with MARKERS and PREFIX."
+ (-let (((&CompletionItem :label
+ :sort-text?
+ :_emacsStartPoint start-point)
+ item))
+ (propertize label
+ 'lsp-completion-item item
+ 'lsp-sort-text sort-text?
+ 'lsp-completion-start-point start-point
+ 'lsp-completion-markers markers
+ 'lsp-completion-prefix prefix)))
+
+(defun lsp-completion--annotate (item)
+ "Annotate ITEM detail."
+ (-let (((&CompletionItem :detail? :kind? :label-details?) (plist-get (text-properties-at 0 item)
+ 'lsp-completion-item)))
+ (concat (when (and lsp-completion-show-detail detail?)
+ (concat " " (s-replace "\r" "" detail?)))
+ (when (and lsp-completion-show-label-description label-details?)
+ (when-let ((description (and label-details? (lsp:label-details-description label-details?))))
+ (format " %s" description)))
+ (when lsp-completion-show-kind
+ (when-let ((kind-name (and kind? (aref lsp-completion--item-kind kind?))))
+ (format " (%s)" kind-name))))))
+
+(defun lsp-completion--looking-back-trigger-characterp (trigger-characters)
+ "Return trigger character if text before point match any of the TRIGGER-CHARACTERS."
+ (unless (= (point) (point-at-bol))
+ (seq-some
+ (lambda (trigger-char)
+ (and (equal (buffer-substring-no-properties (- (point) (length trigger-char)) (point))
+ trigger-char)
+ trigger-char))
+ trigger-characters)))
+
+(defvar lsp-completion--cache nil
+ "Cached candidates for completion at point function.
+In the form of plist (prefix-pos items :lsp-items :prefix ...).
+When the completion is incomplete, `items' contains value of :incomplete.")
+
+(defvar lsp-completion--last-result nil
+ "Last completion result.")
+
+(defun lsp-completion--clear-cache (&optional keep-last-result)
+ "Clear completion caches.
+KEEP-LAST-RESULT if specified."
+ (-some-> lsp-completion--cache
+ (cddr)
+ (plist-get :markers)
+ (cl-second)
+ (set-marker nil))
+ (setq lsp-completion--cache nil)
+ (unless keep-last-result (setq lsp-completion--last-result nil)))
+
+(defcustom lsp-completion-default-behaviour :replace
+ "Default behaviour of `InsertReplaceEdit'."
+ :type '(choice
+ (const :insert :tag "Default completion inserts")
+ (const :replace :tag "Default completion replaces"))
+ :group 'lsp-mode
+ :package-version '(lsp-mode . "8.0.0"))
+
+(lsp-defun lsp-completion--guess-prefix ((item &as &CompletionItem :text-edit?))
+ "Guess ITEM's prefix start point according to following heuristics:
+- If `textEdit' exists, use insertion range start as prefix start point.
+- Else, find the point before current point is longest prefix match of
+`insertText' or `label'. And:
+ - The character before prefix is not word constitute
+Return `nil' when fails to guess prefix."
+ (cond
+ ((lsp-insert-replace-edit? text-edit?)
+ (lsp--position-to-point (lsp:range-start (lsp:insert-replace-edit-insert text-edit?))))
+ (text-edit?
+ (lsp--position-to-point (lsp:range-start (lsp:text-edit-range text-edit?))))
+ (t
+ (-let* (((&CompletionItem :label :insert-text?) item)
+ (text (or (unless (lsp-falsy? insert-text?) insert-text?) label))
+ (point (point))
+ (start (max 1 (- point (length text))))
+ (char-before (char-before start))
+ start-point)
+ (while (and (< start point) (not start-point))
+ (unless (or (and char-before (equal (char-syntax char-before) ?w))
+ (not (string-prefix-p (buffer-substring-no-properties start point)
+ text)))
+ (setq start-point start))
+ (cl-incf start)
+ (setq char-before (char-before start)))
+ start-point))))
+
+(defun lsp-completion--to-internal (items)
+ "Convert ITEMS into internal form."
+ (--> items
+ (-map (-lambda ((item &as &CompletionItem
+ :label
+ :filter-text?
+ :_emacsStartPoint start-point
+ :score?))
+ `( :label ,(or (unless (lsp-falsy? filter-text?) filter-text?) label)
+ :item ,item
+ :start-point ,start-point
+ :score ,score?))
+ it)))
+
+(cl-defun lsp-completion--filter-candidates (items &key
+ lsp-items
+ markers
+ prefix
+ &allow-other-keys)
+ "List all possible completions in cached ITEMS with their prefixes.
+We can pass LSP-ITEMS, which will be used when there's no cache.
+The MARKERS and PREFIX value will be attached to each candidate."
+ (lsp--while-no-input
+ (->>
+ (if items
+ (-->
+ (let (queries fuz-queries)
+ (-keep (-lambda ((cand &as &plist :label :start-point :score))
+ (let* ((query (or (plist-get queries start-point)
+ (let ((s (buffer-substring-no-properties
+ start-point (point))))
+ (setq queries (plist-put queries start-point s))
+ s)))
+ (fuz-query (or (plist-get fuz-queries start-point)
+ (let ((s (lsp-completion--regex-fuz query)))
+ (setq fuz-queries
+ (plist-put fuz-queries start-point s))
+ s)))
+ (label-len (length label)))
+ (when (string-match fuz-query label)
+ (put-text-property 0 label-len 'match-data (match-data) label)
+ (plist-put cand
+ :sort-score
+ (* (or (lsp-completion--fuz-score query label) 1e-05)
+ (or score 0.001)))
+ cand)))
+ items))
+ (if lsp-completion--no-reordering
+ it
+ (sort it (lambda (o1 o2)
+ (> (plist-get o1 :sort-score)
+ (plist-get o2 :sort-score)))))
+ ;; TODO: pass additional function to sort the candidates
+ (-map (-rpartial #'plist-get :item) it))
+ lsp-items)
+ (-map (lambda (item) (lsp-completion--make-item item
+ :markers markers
+ :prefix prefix))))))
+
+(defconst lsp-completion--kind->symbol
+ '((1 . text)
+ (2 . method)
+ (3 . function)
+ (4 . constructor)
+ (5 . field)
+ (6 . variable)
+ (7 . class)
+ (8 . interface)
+ (9 . module)
+ (10 . property)
+ (11 . unit)
+ (12 . value)
+ (13 . enum)
+ (14 . keyword)
+ (15 . snippet)
+ (16 . color)
+ (17 . file)
+ (18 . reference)
+ (19 . folder)
+ (20 . enum-member)
+ (21 . constant)
+ (22 . struct)
+ (23 . event)
+ (24 . operator)
+ (25 . type-parameter)))
+
+(defun lsp-completion--candidate-kind (item)
+ "Return ITEM's kind."
+ (alist-get (lsp:completion-item-kind? (get-text-property 0 'lsp-completion-item item))
+ lsp-completion--kind->symbol))
+
+(defun lsp-completion--candidate-deprecated (item)
+ "Return if ITEM is deprecated."
+ (let ((completion-item (get-text-property 0 'lsp-completion-item item)))
+ (or (lsp:completion-item-deprecated? completion-item)
+ (seq-position (lsp:completion-item-tags? completion-item)
+ lsp/completion-item-tag-deprecated))))
+
+(defun lsp-completion--company-match (candidate)
+ "Return highlight of typed prefix inside CANDIDATE."
+ (let* ((prefix (downcase
+ (buffer-substring-no-properties
+ (plist-get (text-properties-at 0 candidate) 'lsp-completion-start-point)
+ (point))))
+ (prefix-len (length prefix))
+ (prefix-pos 0)
+ (label (downcase candidate))
+ (label-len (length label))
+ (label-pos 0)
+ matches start)
+ (while (and (not matches)
+ (< prefix-pos prefix-len))
+ (while (and (< prefix-pos prefix-len)
+ (< label-pos label-len))
+ (if (equal (aref prefix prefix-pos) (aref label label-pos))
+ (progn
+ (unless start (setq start label-pos))
+ (cl-incf prefix-pos))
+ (when start
+ (setq matches (nconc matches `((,start . ,label-pos))))
+ (setq start nil)))
+ (cl-incf label-pos))
+ (when start (setq matches (nconc matches `((,start . ,label-pos)))))
+ ;; Search again when the whole prefix is not matched
+ (when (< prefix-pos prefix-len)
+ (setq matches nil))
+ ;; Start search from next offset of prefix to find a match with label
+ (unless matches
+ (cl-incf prefix-pos)
+ (setq label-pos 0)))
+ matches))
+
+(defun lsp-completion--get-documentation (item)
+ "Get doc comment for completion ITEM."
+ (unless (get-text-property 0 'lsp-completion-resolved item)
+ (let ((resolved-item
+ (-some->> item
+ (get-text-property 0 'lsp-completion-item)
+ (lsp-completion--resolve)))
+ (len (length item)))
+ (put-text-property 0 len 'lsp-completion-item resolved-item item)
+ (put-text-property 0 len 'lsp-completion-resolved t item)))
+ (-some->> item
+ (get-text-property 0 'lsp-completion-item)
+ (lsp:completion-item-documentation?)
+ (lsp--render-element)))
+
+(defun lsp-completion--get-context (trigger-characters)
+ "Get completion context with provided TRIGGER-CHARACTERS."
+ (let* ((triggered-by-char non-essential)
+ (trigger-char (when triggered-by-char
+ (lsp-completion--looking-back-trigger-characterp
+ trigger-characters)))
+ (trigger-kind (cond
+ (trigger-char
+ lsp/completion-trigger-kind-trigger-character)
+ ((equal (cl-second lsp-completion--cache) :incomplete)
+ lsp/completion-trigger-kind-trigger-for-incomplete-completions)
+ (t lsp/completion-trigger-kind-invoked))))
+ (apply #'lsp-make-completion-context
+ (nconc
+ `(:trigger-kind ,trigger-kind)
+ (when trigger-char
+ `(:trigger-character? ,trigger-char))))))
+
+(defun lsp-completion--sort-completions (completions)
+ "Sort COMPLETIONS."
+ (sort
+ completions
+ (-lambda ((&CompletionItem :sort-text? sort-text-left :label label-left)
+ (&CompletionItem :sort-text? sort-text-right :label label-right))
+ (if (equal sort-text-left sort-text-right)
+ (string-lessp label-left label-right)
+ (string-lessp sort-text-left sort-text-right)))))
+
+;;;###autoload
+(defun lsp-completion-at-point ()
+ "Get lsp completions."
+ (when (or (--some (lsp--client-completion-in-comments? (lsp--workspace-client it))
+ (lsp-workspaces))
+ (not (nth 4 (syntax-ppss))))
+ (let* ((trigger-chars (->> (lsp--server-capabilities)
+ (lsp:server-capabilities-completion-provider?)
+ (lsp:completion-options-trigger-characters?)))
+ (bounds-start (or (-some--> (cl-first (bounds-of-thing-at-point 'symbol))
+ (save-excursion
+ (ignore-errors
+ (goto-char (+ it 1))
+ (while (lsp-completion--looking-back-trigger-characterp
+ trigger-chars)
+ (cl-incf it)
+ (forward-char))
+ it)))
+ (point)))
+ result done?
+ (candidates
+ (lambda ()
+ (lsp--catch 'input
+ (let ((lsp--throw-on-input lsp-completion-use-last-result)
+ (same-session? (and lsp-completion--cache
+ ;; Special case for empty prefix and empty result
+ (or (cl-second lsp-completion--cache)
+ (not (string-empty-p
+ (plist-get (cddr lsp-completion--cache) :prefix))))
+ (equal (cl-first lsp-completion--cache) bounds-start)
+ (s-prefix?
+ (plist-get (cddr lsp-completion--cache) :prefix)
+ (buffer-substring-no-properties bounds-start (point))))))
+ (cond
+ ((or done? result) result)
+ ((and (not lsp-completion-no-cache)
+ same-session?
+ (listp (cl-second lsp-completion--cache)))
+ (setf result (apply #'lsp-completion--filter-candidates
+ (cdr lsp-completion--cache))))
+ (t
+ (-let* ((resp (lsp-request-while-no-input
+ "textDocument/completion"
+ (plist-put (lsp--text-document-position-params)
+ :context (lsp-completion--get-context trigger-chars))))
+ (completed (and resp
+ (not (and (lsp-completion-list? resp)
+ (lsp:completion-list-is-incomplete resp)))))
+ (items (lsp--while-no-input
+ (--> (cond
+ ((lsp-completion-list? resp)
+ (lsp:completion-list-items resp))
+ (t resp))
+ (if (or completed
+ (seq-some #'lsp:completion-item-sort-text? it))
+ (lsp-completion--sort-completions it)
+ it)
+ (-map (lambda (item)
+ (lsp-put item
+ :_emacsStartPoint
+ (or (lsp-completion--guess-prefix item)
+ bounds-start)))
+ it))))
+ (markers (list bounds-start (copy-marker (point) t)))
+ (prefix (buffer-substring-no-properties bounds-start (point)))
+ (lsp-completion--no-reordering (not lsp-completion-sort-initial-results)))
+ (lsp-completion--clear-cache same-session?)
+ (setf done? completed
+ lsp-completion--cache (list bounds-start
+ (cond
+ ((and done? (not (seq-empty-p items)))
+ (lsp-completion--to-internal items))
+ ((not done?) :incomplete))
+ :lsp-items nil
+ :markers markers
+ :prefix prefix)
+ result (lsp-completion--filter-candidates
+ (cond (done?
+ (cl-second lsp-completion--cache))
+ (lsp-completion-filter-on-incomplete
+ (lsp-completion--to-internal items)))
+ :lsp-items items
+ :markers markers
+ :prefix prefix))))))
+ (:interrupted lsp-completion--last-result)
+ (`,res (setq lsp-completion--last-result res))))))
+ (list
+ bounds-start
+ (point)
+ (lambda (probe pred action)
+ (cond
+ ;; metadata
+ ((equal action 'metadata)
+ `(metadata (category . lsp-capf)
+ (display-sort-function . identity)
+ (cycle-sort-function . identity)))
+ ;; boundaries
+ ((equal (car-safe action) 'boundaries) nil)
+ ;; try-completion
+ ((null action)
+ (when-let ((cands (funcall candidates)))
+ (if (cl-rest cands) probe (cl-first cands))))
+ ;; test-completion: not return exact match so that the selection will
+ ;; always be shown
+ ((equal action 'lambda) nil)
+ ;; retrieve candidates
+ ((equal action t)
+ (all-completions probe (funcall candidates) pred))))
+ :annotation-function #'lsp-completion--annotate
+ :company-kind #'lsp-completion--candidate-kind
+ :company-deprecated #'lsp-completion--candidate-deprecated
+ :company-require-match 'never
+ :company-prefix-length
+ (save-excursion
+ (goto-char bounds-start)
+ (and (lsp-completion--looking-back-trigger-characterp trigger-chars) t))
+ :company-match #'lsp-completion--company-match
+ :company-doc-buffer (-compose #'lsp-doc-buffer
+ #'lsp-completion--get-documentation)
+ :exit-function
+ (-rpartial #'lsp-completion--exit-fn candidates)))))
+
+(defun lsp-completion--exit-fn (candidate _status &optional candidates)
+ "Exit function of `completion-at-point'.
+CANDIDATE is the selected completion item.
+Others: CANDIDATES"
+ (unwind-protect
+ (-let* ((candidate (if (plist-member (text-properties-at 0 candidate)
+ 'lsp-completion-item)
+ candidate
+ (cl-find candidate (funcall candidates) :test #'equal)))
+ ((&plist 'lsp-completion-item item
+ 'lsp-completion-start-point start-point
+ 'lsp-completion-markers markers
+ 'lsp-completion-prefix prefix)
+ (text-properties-at 0 candidate))
+ ((&CompletionItem? :label :insert-text? :text-edit? :insert-text-format?
+ :additional-text-edits? :insert-text-mode? :command?)
+ item))
+ (cond
+ (text-edit?
+ (apply #'delete-region markers)
+ (insert prefix)
+ (pcase text-edit?
+ ((TextEdit) (lsp--apply-text-edit text-edit?))
+ ((InsertReplaceEdit :insert :replace :new-text)
+ (lsp--apply-text-edit
+ (lsp-make-text-edit
+ :new-text new-text
+ :range (if (or (and current-prefix-arg (eq lsp-completion-default-behaviour :replace))
+ (and (not current-prefix-arg) (eq lsp-completion-default-behaviour :insert)))
+ insert
+ replace))))))
+ ((or (unless (lsp-falsy? insert-text?) insert-text?) label)
+ (apply #'delete-region markers)
+ (insert prefix)
+ (delete-region start-point (point))
+ (insert (or (unless (lsp-falsy? insert-text?) insert-text?) label))))
+
+ (lsp--indent-lines start-point (point) insert-text-mode?)
+ (when (equal insert-text-format? lsp/insert-text-format-snippet)
+ (lsp--expand-snippet (buffer-substring start-point (point))
+ start-point
+ (point)))
+
+ (when lsp-completion-enable-additional-text-edit
+ (if (or (get-text-property 0 'lsp-completion-resolved candidate)
+ (not (seq-empty-p additional-text-edits?)))
+ (lsp--apply-text-edits additional-text-edits? 'completion)
+ (-let [(callback cleanup-fn) (lsp--create-apply-text-edits-handlers)]
+ (lsp-completion--resolve-async
+ item
+ (-compose callback #'lsp:completion-item-additional-text-edits?)
+ cleanup-fn))))
+
+ (if (or (get-text-property 0 'lsp-completion-resolved candidate)
+ command?)
+ (when command? (lsp--execute-command command?))
+ (lsp-completion--resolve-async
+ item
+ (-lambda ((&CompletionItem? :command?))
+ (when command? (lsp--execute-command command?)))))
+
+ (when (and (or
+ (equal lsp-signature-auto-activate t)
+ (memq :after-completion lsp-signature-auto-activate)
+ (and (memq :on-trigger-char lsp-signature-auto-activate)
+ (-when-let ((&SignatureHelpOptions? :trigger-characters?)
+ (lsp--capability :signatureHelpProvider))
+ (lsp-completion--looking-back-trigger-characterp
+ trigger-characters?))))
+ (lsp-feature? "textDocument/signatureHelp"))
+ (lsp-signature-activate))
+
+ (setq-local lsp-inhibit-lsp-hooks nil))
+ (lsp-completion--clear-cache)))
+
+(defun lsp-completion--regex-fuz (str)
+ "Build a regex sequence from STR. Insert .* between each char."
+ (apply #'concat
+ (cl-mapcar
+ #'concat
+ (cons "" (cdr (seq-map (lambda (c) (format "[^%c]*" c)) str)))
+ (seq-map (lambda (c)
+ (format "\\(%s\\)" (regexp-quote (char-to-string c))))
+ str))))
+
+(defun lsp-completion--fuz-score (query str)
+ "Calculate fuzzy score for STR with query QUERY.
+The return is nil or in range of (0, inf)."
+ (-when-let* ((md (cddr (or (get-text-property 0 'match-data str)
+ (let ((re (lsp-completion--regex-fuz query)))
+ (when (string-match re str)
+ (match-data))))))
+ (start (pop md))
+ (len (length str))
+ ;; To understand how this works, consider these bad ascii(tm)
+ ;; diagrams showing how the pattern "foo" flex-matches
+ ;; "fabrobazo", "fbarbazoo" and "barfoobaz":
+
+ ;; f abr o baz o
+ ;; + --- + --- +
+
+ ;; f barbaz oo
+ ;; + ------ ++
+
+ ;; bar foo baz
+ ;; --- +++ ---
+
+ ;; "+" indicates parts where the pattern matched. A "hole" in
+ ;; the middle of the string is indicated by "-". Note that there
+ ;; are no "holes" near the edges of the string. The completion
+ ;; score is a number bound by ]0..1]: the higher the better and
+ ;; only a perfect match (pattern equals string) will have score
+ ;; 1. The formula takes the form of a quotient. For the
+ ;; numerator, we use the number of +, i.e. the length of the
+ ;; pattern. For the denominator, it first computes
+ ;;
+ ;; hole_i_contrib = 1 + (Li-1)^1.05 for first hole
+ ;; hole_i_contrib = 1 + (Li-1)^0.25 for hole i of length Li
+ ;;
+ ;; The final value for the denominator is then given by:
+ ;;
+ ;; (SUM_across_i(hole_i_contrib) + 1)
+ ;;
+ (score-numerator 0)
+ (score-denominator 0)
+ (last-b -1)
+ (q-ind 0)
+ (update-score
+ (lambda (a b)
+ "Update score variables given match range (A B)."
+ (setq score-numerator (+ score-numerator (- b a)))
+ (unless (= a len)
+ ;; case mis-match will be pushed to near next rank
+ (unless (equal (aref query q-ind) (aref str a))
+ (cl-incf a 0.9))
+ (setq score-denominator
+ (+ score-denominator
+ (if (= a last-b) 0
+ (+ 1 (* (if (< 0 (- a last-b 1)) 1 -1)
+ (expt (abs (- a last-b 1))
+ ;; Give a higher score for match near start
+ (if (eq last-b -1) 0.75 0.25))))))))
+ (setq last-b b))))
+ (while md
+ (funcall update-score start (cl-first md))
+ ;; Due to the way completion regex is constructed, `(eq end (+ start 1))`
+ (cl-incf q-ind)
+ (pop md)
+ (setq start (pop md)))
+ (unless (zerop len)
+ (/ score-numerator (1+ score-denominator) 1.0))))
+
+(defun lsp-completion--fix-resolve-data (item)
+ ;; patch `CompletionItem' for rust-analyzer otherwise resolve will fail
+ ;; see #2675
+ (let ((data (lsp:completion-item-data? item)))
+ (when (lsp-member? data :import_for_trait_assoc_item)
+ (unless (lsp-get data :import_for_trait_assoc_item)
+ (lsp-put data :import_for_trait_assoc_item :json-false)))))
+
+(defun lsp-completion--resolve (item)
+ "Resolve completion ITEM."
+ (cl-assert item nil "Completion item must not be nil")
+ (lsp-completion--fix-resolve-data item)
+ (or (ignore-errors
+ (when (lsp-feature? "completionItem/resolve")
+ (lsp-request "completionItem/resolve" item)))
+ item))
+
+(defun lsp-completion--resolve-async (item callback &optional cleanup-fn)
+ "Resolve completion ITEM asynchronously with CALLBACK.
+The CLEANUP-FN will be called to cleanup."
+ (cl-assert item nil "Completion item must not be nil")
+ (lsp-completion--fix-resolve-data item)
+ (ignore-errors
+ (if (lsp-feature? "completionItem/resolve")
+ (lsp-request-async "completionItem/resolve" item
+ (lambda (result)
+ (funcall callback result)
+ (when cleanup-fn (funcall cleanup-fn)))
+ :error-handler (lambda (err)
+ (when cleanup-fn (funcall cleanup-fn))
+ (error (lsp:json-error-message err)))
+ :cancel-handler cleanup-fn
+ :mode 'alive)
+ (funcall callback item)
+ (when cleanup-fn (funcall cleanup-fn)))))
+
+
+;;;###autoload
+(defun lsp-completion--enable ()
+ "Enable LSP completion support."
+ (when (and lsp-completion-enable
+ (lsp-feature? "textDocument/completion"))
+ (lsp-completion-mode 1)))
+
+(defun lsp-completion--disable ()
+ "Disable LSP completion support."
+ (lsp-completion-mode -1))
+
+(defun lsp-completion-passthrough-all-completions (_string table pred _point)
+ "Like `completion-basic-all-completions' but have prefix ignored."
+ (completion-basic-all-completions "" table pred 0))
+
+;;;###autoload
+(define-minor-mode lsp-completion-mode
+ "Toggle LSP completion support."
+ :group 'lsp-completion
+ :global nil
+ :lighter ""
+ (let ((completion-started-fn (lambda (&rest _)
+ (setq-local lsp-inhibit-lsp-hooks t)))
+ (after-completion-fn (lambda (result)
+ (when (stringp result)
+ (lsp-completion--clear-cache))
+ (setq-local lsp-inhibit-lsp-hooks nil))))
+ (cond
+ (lsp-completion-mode
+ (setq-local completion-at-point-functions nil)
+ (add-hook 'completion-at-point-functions #'lsp-completion-at-point nil t)
+ (make-local-variable 'completion-category-defaults)
+ (setf (alist-get 'lsp-capf completion-category-defaults) '((styles . (lsp-passthrough))))
+ (make-local-variable 'completion-styles-alist)
+ (setf (alist-get 'lsp-passthrough completion-styles-alist)
+ '(completion-basic-try-completion
+ lsp-completion-passthrough-all-completions
+ "Passthrough completion."))
+
+ (cond
+ ((equal lsp-completion-provider :none))
+ ((and (not (equal lsp-completion-provider :none))
+ (fboundp 'company-mode))
+ (setq-local company-abort-on-unique-match nil)
+ (company-mode 1)
+ (setq-local company-backends (cl-adjoin 'company-capf company-backends :test #'equal)))
+ (t
+ (lsp--warn "Unable to autoconfigure company-mode.")))
+
+ (when (bound-and-true-p company-mode)
+ (add-hook 'company-completion-started-hook
+ completion-started-fn
+ nil
+ t)
+ (add-hook 'company-after-completion-hook
+ after-completion-fn
+ nil
+ t))
+ (add-hook 'lsp-unconfigure-hook #'lsp-completion--disable nil t))
+ (t
+ (remove-hook 'completion-at-point-functions #'lsp-completion-at-point t)
+ (setq-local completion-category-defaults
+ (cl-remove 'lsp-capf completion-category-defaults :key #'cl-first))
+ (setq-local completion-styles-alist
+ (cl-remove 'lsp-passthrough completion-styles-alist :key #'cl-first))
+ (remove-hook 'lsp-unconfigure-hook #'lsp-completion--disable t)
+ (when (featurep 'company)
+ (remove-hook 'company-completion-started-hook
+ completion-started-fn
+ t)
+ (remove-hook 'company-after-completion-hook
+ after-completion-fn
+ t))))))
+
+;;;###autoload
+(add-hook 'lsp-configure-hook (lambda ()
+ (when (and lsp-auto-configure
+ lsp-completion-enable)
+ (lsp-completion--enable))))
+
+(lsp-consistency-check lsp-completion)
+
+(provide 'lsp-completion)
+;;; lsp-completion.el ends here
diff --git a/elpa/lsp-mode-20220505.630/lsp-completion.elc b/elpa/lsp-mode-20220505.630/lsp-completion.elc
new file mode 100644
index 0000000..878f814
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-completion.elc
Binary files differ
diff --git a/elpa/lsp-mode-20220505.630/lsp-crystal.el b/elpa/lsp-mode-20220505.630/lsp-crystal.el
new file mode 100644
index 0000000..f0aca59
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-crystal.el
@@ -0,0 +1,48 @@
+;;; lsp-crystal.el --- description -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2020 emacs-lsp maintainers
+
+;; Author: emacs-lsp maintainers
+;; Keywords: lsp, crystal
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; LSP Clients for the Crystal Programming Language.
+
+;;; Code:
+
+(require 'lsp-mode)
+
+(defgroup lsp-scry nil
+ "LSP support for Crystal via scry."
+ :group 'lsp-mode
+ :link '(url-link "https://github.com/crystal-lang-tools/scry"))
+
+(defcustom lsp-clients-crystal-executable '("scry" "--stdio")
+ "Command to start the scry language server."
+ :group 'lsp-scry
+ :risky t
+ :type 'file)
+
+(lsp-register-client
+ (make-lsp-client :new-connection (lsp-stdio-connection lsp-clients-crystal-executable)
+ :major-modes '(crystal-mode)
+ :server-id 'scry))
+
+(lsp-consistency-check lsp-crystal)
+
+(provide 'lsp-crystal)
+;;; lsp-crystal.el ends here
diff --git a/elpa/lsp-mode-20220505.630/lsp-crystal.elc b/elpa/lsp-mode-20220505.630/lsp-crystal.elc
new file mode 100644
index 0000000..83c7e3b
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-crystal.elc
Binary files differ
diff --git a/elpa/lsp-mode-20220505.630/lsp-csharp.el b/elpa/lsp-mode-20220505.630/lsp-csharp.el
new file mode 100644
index 0000000..a9ca0d8
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-csharp.el
@@ -0,0 +1,472 @@
+;;; lsp-csharp.el --- description -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2019 Jostein Kjønigsen, Saulius Menkevicius
+
+;; Author: Saulius Menkevicius <saulius.menkevicius@fastmail.com>
+;; Keywords:
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; lsp-csharp client
+
+;;; Code:
+
+(require 'lsp-mode)
+(require 'gnutls)
+(require 'f)
+
+(defgroup lsp-csharp nil
+ "LSP support for C#, using the Omnisharp Language Server.
+Version 1.34.3 minimum is required."
+ :group 'lsp-mode
+ :link '(url-link "https://github.com/OmniSharp/omnisharp-roslyn"))
+
+(defgroup lsp-csharp-omnisharp nil
+ "LSP support for C#, using the Omnisharp Language Server.
+Version 1.34.3 minimum is required."
+ :group 'lsp-mode
+ :link '(url-link "https://github.com/OmniSharp/omnisharp-roslyn")
+ :package-version '(lsp-mode . "8.0.1"))
+
+(defcustom lsp-csharp-server-install-dir
+ (f-join lsp-server-install-dir "omnisharp-roslyn/")
+ "Installation directory for OmniSharp Roslyn server."
+ :group 'lsp-csharp-omnisharp
+ :type 'directory)
+
+(defcustom lsp-csharp-server-path
+ nil
+ "The path to the OmniSharp Roslyn language-server binary.
+Set this if you have the binary installed or have it built yourself."
+ :group 'lsp-csharp-omnisharp
+ :type '(string :tag "Single string value or nil"))
+
+(defcustom lsp-csharp-test-run-buffer-name
+ "*lsp-csharp test run*"
+ "The name of buffer used for outputing lsp-csharp test run results."
+ :group 'lsp-csharp-omnisharp
+ :type 'string)
+
+(defcustom lsp-csharp-solution-file
+ nil
+ "Solution to load when starting the server.
+Usually this is to be set in your .dir-locals.el on the project root directory."
+ :group 'lsp-csharp-omnisharp
+ :type 'string)
+
+(defcustom lsp-csharp-omnisharp-roslyn-download-url
+ (concat "https://github.com/omnisharp/omnisharp-roslyn/releases/latest/download/"
+ (cond ((eq system-type 'windows-nt)
+ ; On Windows we're trying to avoid a crash starting 64bit .NET PE binaries in
+ ; Emacs by using x86 version of omnisharp-roslyn on older (<= 26.4) versions
+ ; of Emacs. See https://lists.nongnu.org/archive/html/bug-gnu-emacs/2017-06/msg00893.html"
+ (if (and (string-match "^x86_64-.*" system-configuration)
+ (version<= "26.4" emacs-version))
+ "omnisharp-win-x64.zip"
+ "omnisharp-win-x86.zip"))
+
+ ((eq system-type 'darwin)
+ "omnisharp-osx.zip")
+
+ ((and (eq system-type 'gnu/linux)
+ (or (eq (string-match "^x86_64" system-configuration) 0)
+ (eq (string-match "^i[3-6]86" system-configuration) 0)))
+ "omnisharp-linux-x64.zip")
+
+ (t "omnisharp-mono.zip")))
+ "Automatic download url for omnisharp-roslyn."
+ :group 'lsp-csharp-omnisharp
+ :type 'string)
+
+(defcustom lsp-csharp-omnisharp-roslyn-store-path
+ (f-join lsp-csharp-server-install-dir "latest" "omnisharp-roslyn.zip")
+ "The path where omnisharp-roslyn .zip archive will be stored."
+ :group 'lsp-csharp-omnisharp
+ :type 'file)
+
+(defcustom lsp-csharp-omnisharp-roslyn-server-dir
+ (f-join lsp-csharp-server-install-dir "latest" "omnisharp-roslyn")
+ "The path where omnisharp-roslyn .zip archive will be extracted."
+ :group 'lsp-csharp-omnisharp
+ :type 'file)
+
+(lsp-dependency
+ 'omnisharp-roslyn
+ `(:download :url lsp-csharp-omnisharp-roslyn-download-url
+ :store-path lsp-csharp-omnisharp-roslyn-store-path))
+
+(defun lsp-csharp--download-server (_client callback error-callback _update?)
+ "Download zip package for omnisharp-roslyn and install it.
+Will invoke CALLBACK on success, ERROR-CALLBACK on error."
+ (lsp-package-ensure
+ 'omnisharp-roslyn
+ (lambda ()
+ (lsp-unzip lsp-csharp-omnisharp-roslyn-store-path
+ lsp-csharp-omnisharp-roslyn-server-dir)
+ (unless (eq system-type 'windows-nt)
+ (let ((run-script (f-join lsp-csharp-omnisharp-roslyn-server-dir "run")))
+ (when (not (f-exists-p run-script))
+ ; create the `run' script when missing (e.g. when server binaries are extracted from omnisharp-mono.zip)
+ ; NOTE: we do not check for presence or version of mono in the system
+ (with-temp-file run-script
+ (insert "#!/bin/bash\n")
+ (insert "BASEDIR=$(dirname \"$0\")\n")
+ (insert "exec mono $BASEDIR/OmniSharp.exe $@\n")))
+ (set-file-modes run-script #o755)))
+ (funcall callback))
+ error-callback))
+
+(defun lsp-csharp--language-server-path ()
+ "Resolve path to use to start the server."
+ (if lsp-csharp-server-path
+ lsp-csharp-server-path
+ (let ((server-dir lsp-csharp-omnisharp-roslyn-server-dir))
+ (when (f-exists? server-dir)
+ (f-join server-dir (cond ((eq system-type 'windows-nt) "OmniSharp.exe")
+ (t "run")))))))
+
+(lsp-defun lsp-csharp-open-project-file ()
+ "Open corresponding project file (.csproj) for the current file."
+ (interactive)
+ (-let* ((project-info-req (lsp-make-omnisharp-project-information-request :file-name (buffer-file-name)))
+ (project-info (lsp-request "o#/project" project-info-req))
+ ((&omnisharp:ProjectInformation :ms-build-project) project-info)
+ ((&omnisharp:MsBuildProject :path) ms-build-project))
+ (find-file path)))
+
+(defun lsp-csharp--get-buffer-code-elements ()
+ "Retrieve code structure by calling into the /v2/codestructure endpoint.
+Returns :elements from omnisharp:CodeStructureResponse."
+ (-let* ((code-structure (lsp-request "o#/v2/codestructure"
+ (lsp-make-omnisharp-code-structure-request :file-name (buffer-file-name))))
+ ((&omnisharp:CodeStructureResponse :elements) code-structure))
+ elements))
+
+(defun lsp-csharp--inspect-code-elements-recursively (fn elements)
+ "Invoke FN for every omnisharp:CodeElement found recursively in ELEMENTS."
+ (seq-each
+ (lambda (el)
+ (funcall fn el)
+ (-let (((&omnisharp:CodeElement :children) el))
+ (lsp-csharp--inspect-code-elements-recursively fn children)))
+ elements))
+
+(defun lsp-csharp--collect-code-elements-recursively (predicate elements)
+ "Flatten the omnisharp:CodeElement tree in ELEMENTS matching PREDICATE."
+ (let ((results nil))
+ (lsp-csharp--inspect-code-elements-recursively (lambda (el)
+ (when (funcall predicate el)
+ (setq results (cons el results))))
+ elements)
+ results))
+
+(lsp-defun lsp-csharp--l-c-within-range (l c (&omnisharp:Range :start :end))
+ "Determine if L (line) and C (column) are within RANGE."
+ (-let* (((&omnisharp:Point :line start-l :column start-c) start)
+ ((&omnisharp:Point :line end-l :column end-c) end))
+ (or (and (= l start-l) (>= c start-c) (or (> end-l start-l) (<= c end-c)))
+ (and (> l start-l) (< l end-l))
+ (and (= l end-l) (<= c end-c)))))
+
+(defun lsp-csharp--code-element-stack-on-l-c (l c elements)
+ "Return omnisharp:CodeElement stack at L (line) and C (column) in ELEMENTS tree."
+ (when-let ((matching-element (seq-find (lambda (el)
+ (-when-let* (((&omnisharp:CodeElement :ranges) el)
+ ((&omnisharp:RangeList :full?) ranges))
+ (lsp-csharp--l-c-within-range l c full?)))
+ elements)))
+ (-let (((&omnisharp:CodeElement :children) matching-element))
+ (cons matching-element (lsp-csharp--code-element-stack-on-l-c l c children)))))
+
+(defun lsp-csharp--code-element-stack-at-point ()
+ "Return omnisharp:CodeElement stack at point as a list."
+ (let ((pos-line (plist-get (lsp--cur-position) :line))
+ (pos-col (plist-get (lsp--cur-position) :character)))
+ (lsp-csharp--code-element-stack-on-l-c pos-line
+ pos-col
+ (lsp-csharp--get-buffer-code-elements))))
+
+(lsp-defun lsp-csharp--code-element-test-method-p (element)
+ "Return test method name and test framework for a given ELEMENT."
+ (when element
+ (-when-let* (((&omnisharp:CodeElement :properties) element)
+ ((&omnisharp:CodeElementProperties :test-method-name? :test-framework?) properties))
+ (list test-method-name? test-framework?))))
+
+(defun lsp-csharp--reset-test-buffer (present-buffer)
+ "Create new or reuse an existing test result output buffer.
+PRESENT-BUFFER will make the buffer be presented to the user."
+ (with-current-buffer (get-buffer-create lsp-csharp-test-run-buffer-name)
+ (compilation-mode)
+ (read-only-mode)
+ (let ((inhibit-read-only t))
+ (erase-buffer)))
+
+ (when present-buffer
+ (display-buffer lsp-csharp-test-run-buffer-name)))
+
+(defun lsp-csharp--start-tests (test-method-framework test-method-names)
+ "Run test(s) identified by TEST-METHOD-NAMES using TEST-METHOD-FRAMEWORK."
+ (if (and test-method-framework test-method-names)
+ (let ((request-message (lsp-make-omnisharp-run-tests-in-class-request
+ :file-name (buffer-file-name)
+ :test-frameworkname test-method-framework
+ :method-names (vconcat test-method-names))))
+ (lsp-csharp--reset-test-buffer t)
+ (lsp-session-set-metadata "last-test-method-framework" test-method-framework)
+ (lsp-session-set-metadata "last-test-method-names" test-method-names)
+ (lsp-request-async "o#/v2/runtestsinclass"
+ request-message
+ (-lambda ((&omnisharp:RunTestResponse))
+ (message "lsp-csharp: Test run has started"))))
+ (message "lsp-csharp: No test methods to run")))
+
+(defun lsp-csharp--test-message (message)
+ "Emit a MESSAGE to lsp-csharp test run buffer."
+ (when-let ((existing-buffer (get-buffer lsp-csharp-test-run-buffer-name))
+ (inhibit-read-only t))
+ (with-current-buffer existing-buffer
+ (save-excursion
+ (goto-char (point-max))
+ (insert message "\n")))))
+
+(defun lsp-csharp-run-test-at-point ()
+ "Start test run at current point (if any)."
+ (interactive)
+ (let* ((stack (lsp-csharp--code-element-stack-at-point))
+ (element-on-point (car (last stack)))
+ (test-method (lsp-csharp--code-element-test-method-p element-on-point))
+ (test-method-name (car test-method))
+ (test-method-framework (car (cdr test-method))))
+ (lsp-csharp--start-tests test-method-framework (list test-method-name))))
+
+(defun lsp-csharp-run-all-tests-in-buffer ()
+ "Run all test methods in the current buffer."
+ (interactive)
+ (let* ((elements (lsp-csharp--get-buffer-code-elements))
+ (test-methods (lsp-csharp--collect-code-elements-recursively 'lsp-csharp--code-element-test-method-p elements))
+ (test-method-framework (car (cdr (lsp-csharp--code-element-test-method-p (car test-methods)))))
+ (test-method-names (mapcar (lambda (method)
+ (car (lsp-csharp--code-element-test-method-p method)))
+ test-methods)))
+ (lsp-csharp--start-tests test-method-framework test-method-names)))
+
+(defun lsp-csharp-run-test-in-buffer ()
+ "Run selected test in current buffer."
+ (interactive)
+ (when-let* ((elements (lsp-csharp--get-buffer-code-elements))
+ (test-methods (lsp-csharp--collect-code-elements-recursively 'lsp-csharp--code-element-test-method-p elements))
+ (test-method-framework (car (cdr (lsp-csharp--code-element-test-method-p (car test-methods)))))
+ (test-method-names (mapcar (lambda (method)
+ (car (lsp-csharp--code-element-test-method-p method)))
+ test-methods))
+ (selected-test-method-name (lsp--completing-read "Select test:" test-method-names 'identity)))
+ (lsp-csharp--start-tests test-method-framework (list selected-test-method-name))))
+
+(defun lsp-csharp-run-last-tests ()
+ "Re-run test(s) that were run last time."
+ (interactive)
+ (if-let ((last-test-method-framework (lsp-session-get-metadata "last-test-method-framework"))
+ (last-test-method-names (lsp-session-get-metadata "last-test-method-names")))
+ (lsp-csharp--start-tests last-test-method-framework last-test-method-names)
+ (message "lsp-csharp: No test method(s) found to be ran previously on this workspace")))
+
+(lsp-defun lsp-csharp--handle-os-error (_workspace (&omnisharp:ErrorMessage :file-name :text))
+ "Handle the 'o#/error' (interop) notification by displaying a message with lsp-warn."
+ (lsp-warn "%s: %s" file-name text))
+
+(lsp-defun lsp-csharp--handle-os-testmessage (_workspace (&omnisharp:TestMessageEvent :message))
+ "Handle the 'o#/testmessage and display test message on lsp-csharp
+test output buffer."
+ (lsp-csharp--test-message message))
+
+(lsp-defun lsp-csharp--handle-os-testcompleted (_workspace (&omnisharp:DotNetTestResult
+ :method-name
+ :outcome
+ :error-message
+ :error-stack-trace
+ :standard-output
+ :standard-error))
+ "Handle the 'o#/testcompleted' message from the server.
+
+Will display the results of the test on the lsp-csharp test output buffer."
+ (let ((passed (string-equal "passed" outcome)))
+ (lsp-csharp--test-message
+ (format "[%s] %s "
+ (propertize (upcase outcome) 'font-lock-face (if passed 'success 'error))
+ method-name))
+
+ (unless passed
+ (lsp-csharp--test-message error-message)
+
+ (when error-stack-trace
+ (lsp-csharp--test-message error-stack-trace))
+
+ (unless (seq-empty-p standard-output)
+ (lsp-csharp--test-message "STANDARD OUTPUT:")
+ (seq-doseq (stdout-line standard-output)
+ (lsp-csharp--test-message stdout-line)))
+
+ (unless (seq-empty-p standard-error)
+ (lsp-csharp--test-message "STANDARD ERROR:")
+ (seq-doseq (stderr-line standard-error)
+ (lsp-csharp--test-message stderr-line))))))
+
+(lsp-defun lsp-csharp--action-client-find-references ((&Command :arguments?))
+ "Read first argument from ACTION as Location and display xrefs for that location
+using the `textDocument/references' request."
+ (-if-let* (((&Location :uri :range) (lsp-seq-first arguments?))
+ ((&Range :start range-start) range)
+ (find-refs-params (append (lsp--text-document-position-params (list :uri uri) range-start)
+ (list :context (list :includeDeclaration json-false))))
+ (locations-found (lsp-request "textDocument/references" find-refs-params)))
+ (lsp-show-xrefs (lsp--locations-to-xref-items locations-found) nil t)
+ (message "No references found")))
+
+(lsp-register-client
+ (make-lsp-client :new-connection
+ (lsp-stdio-connection
+ #'(lambda ()
+ (append
+ (list (lsp-csharp--language-server-path) "-lsp")
+ (when lsp-csharp-solution-file
+ (list "-s" (expand-file-name lsp-csharp-solution-file)))))
+ #'(lambda ()
+ (when-let ((binary (lsp-csharp--language-server-path)))
+ (f-exists? binary))))
+ :major-modes '(csharp-mode csharp-tree-sitter-mode)
+ :server-id 'omnisharp
+ :priority -1
+ :action-handlers (ht ("omnisharp/client/findReferences" 'lsp-csharp--action-client-find-references))
+ :notification-handlers (ht ("o#/projectadded" 'ignore)
+ ("o#/projectchanged" 'ignore)
+ ("o#/projectremoved" 'ignore)
+ ("o#/packagerestorestarted" 'ignore)
+ ("o#/msbuildprojectdiagnostics" 'ignore)
+ ("o#/packagerestorefinished" 'ignore)
+ ("o#/unresolveddependencies" 'ignore)
+ ("o#/error" 'lsp-csharp--handle-os-error)
+ ("o#/testmessage" 'lsp-csharp--handle-os-testmessage)
+ ("o#/testcompleted" 'lsp-csharp--handle-os-testcompleted)
+ ("o#/projectconfiguration" 'ignore)
+ ("o#/projectdiagnosticstatus" 'ignore))
+ :download-server-fn #'lsp-csharp--download-server))
+
+;;
+;; Alternative "csharp-ls" language server support
+;; see https://github.com/razzmatazz/csharp-language-server
+;;
+(lsp-defun lsp-csharp--cls-metadata-uri-handler (uri)
+ "Handle `csharp:/(metadata)' uri from csharp-ls server.
+
+'csharp/metadata' request is issued to retrieve metadata from the server.
+A cache file is created on project root dir that stores this metadata and filename
+is returned so lsp-mode can display this file."
+
+ (-when-let* ((metadata-req (lsp-make-csharp-ls-c-sharp-metadata
+ :text-document (lsp-make-text-document-identifier :uri uri)))
+ (metadata (lsp-request "csharp/metadata" metadata-req))
+ ((&csharp-ls:CSharpMetadataResponse :project-name
+ :assembly-name
+ :symbol-name
+ :source) metadata)
+ (filename (f-join ".cache"
+ "lsp-csharp"
+ "metadata"
+ "projects" project-name
+ "assemblies" assembly-name
+ (concat symbol-name ".cs")))
+ (file-location (expand-file-name filename (lsp-workspace-root)))
+ (metadata-file-location (concat file-location ".metadata-uri"))
+ (path (f-dirname file-location)))
+
+ (unless (file-exists-p file-location)
+ (unless (file-directory-p path)
+ (make-directory path t))
+
+ (with-temp-file metadata-file-location
+ (insert uri))
+
+ (with-temp-file file-location
+ (insert source)))
+
+ file-location))
+
+(defun lsp-csharp--cls-before-file-open (_workspace)
+ "Set `lsp-buffer-uri' variable after C# file is open from *.metadata-uri file."
+
+ (let ((metadata-file-name (concat buffer-file-name ".metadata-uri")))
+ (setq-local lsp-buffer-uri
+ (when (file-exists-p metadata-file-name)
+ (with-temp-buffer (insert-file-contents metadata-file-name)
+ (buffer-string))))))
+
+(defun lsp-csharp--cls-make-launch-cmd ()
+ "Return command line to invoke csharp-ls."
+
+ ;; latest emacs-28 (on macOS) and master (as of Sat Feb 12 EET 2022) has an issue
+ ;; that it launches processes using posix_spawn but does not reset sigmask properly
+ ;; thus causing dotnet runtime to lockup awaiting a SIGCHLD signal that never comes
+ ;; from subprocesses that quit
+ ;;
+ ;; as a workaround we will wrap csharp-ls invocation in "/usr/bin/env --default-signal"
+ ;; (on linux) and "/bin/ksh -c" (on macos) so it launches with proper sigmask
+ ;;
+ ;; see https://lists.gnu.org/archive/html/emacs-devel/2022-02/msg00461.html
+
+ (let ((startup-wrapper (cond ((and (eq 'darwin system-type)
+ (version<= "28.0" emacs-version))
+ (list "/bin/ksh" "-c"))
+
+ ((and (eq 'gnu/linux system-type)
+ (version<= "29.0" emacs-version))
+ (list "/usr/bin/env" "--default-signal"))
+
+ (t nil)))
+ (solution-file-params (when lsp-csharp-solution-file
+ (list "-s" lsp-csharp-solution-file))))
+ (append startup-wrapper
+ (list "csharp-ls")
+ solution-file-params)))
+
+(defun lsp-csharp--cls-test-csharp-ls-present ()
+ "Return non-nil if dotnet tool csharp-ls is installed globally."
+ (string-match-p "csharp-ls"
+ (shell-command-to-string "dotnet tool list -g")))
+
+(defun lsp-csharp--cls-download-server (_client callback error-callback update?)
+ "Install/update csharp-ls language server using `dotnet tool'.
+
+Will invoke CALLBACK or ERROR-CALLBACK based on result. Will update if UPDATE? is t"
+ (lsp-async-start-process
+ callback
+ error-callback
+ "dotnet" "tool" (if update? "update" "install") "-g" "csharp-ls"))
+
+(lsp-register-client
+ (make-lsp-client :new-connection (lsp-stdio-connection #'lsp-csharp--cls-make-launch-cmd
+ #'lsp-csharp--cls-test-csharp-ls-present)
+ :priority -2
+ :server-id 'csharp-ls
+ :major-modes '(csharp-mode csharp-tree-sitter-mode)
+ :before-file-open-fn #'lsp-csharp--cls-before-file-open
+ :uri-handlers (ht ("csharp" #'lsp-csharp--cls-metadata-uri-handler))
+ :download-server-fn #'lsp-csharp--cls-download-server))
+
+(lsp-consistency-check lsp-csharp)
+
+(provide 'lsp-csharp)
+;;; lsp-csharp.el ends here
diff --git a/elpa/lsp-mode-20220505.630/lsp-csharp.elc b/elpa/lsp-mode-20220505.630/lsp-csharp.elc
new file mode 100644
index 0000000..6654b37
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-csharp.elc
Binary files differ
diff --git a/elpa/lsp-mode-20220505.630/lsp-css.el b/elpa/lsp-mode-20220505.630/lsp-css.el
new file mode 100644
index 0000000..b825a36
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-css.el
@@ -0,0 +1,254 @@
+;;; lsp-css.el --- CSS language server configuration -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2019 Ivan Yonchovski
+
+;; Author: Ivan Yonchovski <yyoncho@gmail.com>
+;; Keywords:
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'lsp-protocol)
+(require 'lsp-mode)
+
+(defgroup lsp-css nil
+ "LSP support for CSS."
+ :group 'lsp-mode
+ :link '(url-link
+ "https://github.com/microsoft/vscode/tree/main/extensions/css-language-features/server"))
+
+(defcustom lsp-css-experimental-custom-data nil
+ "A list of JSON file paths that define custom CSS data that
+loads custom properties, at directives, pseudo classes /
+elements."
+ :type '(repeat string))
+
+(defcustom lsp-css-completion-trigger-property-value-completion t
+ "By default, VS Code triggers property value completion after
+selecting a CSS property. Use this setting to disable this
+behavior."
+ :type 'boolean)
+
+(defcustom lsp-css-validate t
+ "Enables or disables all validations."
+ :type 'boolean)
+
+(defcustom lsp-css-lint-compatible-vendor-prefixes "ignore"
+ "When using a vendor-specific prefix make sure to also include
+all other vendor-specific properties."
+ :type '(choice
+ (const "ignore")
+ (const "warning")
+ (const "error")))
+
+(defcustom lsp-css-lint-vendor-prefix "warning"
+ "When using a vendor-specific prefix, also include the standard
+property."
+ :type '(choice
+ (const "ignore")
+ (const "warning")
+ (const "error")))
+
+(defcustom lsp-css-lint-duplicate-properties "ignore"
+ "Do not use duplicate style definitions."
+ :type '(choice
+ (const "ignore")
+ (const "warning")
+ (const "error")))
+
+(defcustom lsp-css-lint-empty-rules "warning"
+ "Do not use empty rulesets."
+ :type '(choice
+ (const "ignore")
+ (const "warning")
+ (const "error")))
+
+(defcustom lsp-css-lint-import-statement "ignore"
+ "Import statements do not load in parallel."
+ :type '(choice
+ (const "ignore")
+ (const "warning")
+ (const "error")))
+
+(defcustom lsp-css-lint-box-model "ignore"
+ nil
+ :type '(choice
+ (const "ignore")
+ (const "warning")
+ (const "error")))
+
+(defcustom lsp-css-lint-universal-selector "ignore"
+ nil
+ :type '(choice
+ (const "ignore")
+ (const "warning")
+ (const "error")))
+
+(defcustom lsp-css-lint-zero-units "ignore"
+ "No unit for zero needed."
+ :type '(choice
+ (const "ignore")
+ (const "warning")
+ (const "error")))
+
+(defcustom lsp-css-lint-font-face-properties "warning"
+ nil
+ :type '(choice
+ (const "ignore")
+ (const "warning")
+ (const "error")))
+
+(defcustom lsp-css-lint-hex-color-length "error"
+ "Hex colors must consist of three or six hex numbers."
+ :type '(choice
+ (const "ignore")
+ (const "warning")
+ (const "error")))
+
+(defcustom lsp-css-lint-arguments-in-color-function "error"
+ "Invalid number of parameters."
+ :type '(choice
+ (const "ignore")
+ (const "warning")
+ (const "error")))
+
+(defcustom lsp-css-lint-unknown-properties "warning"
+ "Unknown property."
+ :type '(choice
+ (const "ignore")
+ (const "warning")
+ (const "error")))
+
+(defcustom lsp-css-lint-valid-properties nil
+ "A list of properties that are not validated against the
+`unknownProperties` rule."
+ :type '(repeat string))
+
+(defcustom lsp-css-lint-ie-hack "ignore"
+ "IE hacks are only necessary when supporting IE7 and older."
+ :type '(choice
+ (const "ignore")
+ (const "warning")
+ (const "error")))
+
+(defcustom lsp-css-lint-unknown-vendor-specific-properties "ignore"
+ "Unknown vendor specific property."
+ :type '(choice
+ (const "ignore")
+ (const "warning")
+ (const "error")))
+
+(defcustom lsp-css-lint-property-ignored-due-to-display "warning"
+ nil
+ :type '(choice
+ (const "ignore")
+ (const "warning")
+ (const "error")))
+
+(defcustom lsp-css-lint-important "ignore"
+ nil
+ :type '(choice
+ (const "ignore")
+ (const "warning")
+ (const "error")))
+
+(defcustom lsp-css-lint-float "ignore"
+ nil
+ :type '(choice
+ (const "ignore")
+ (const "warning")
+ (const "error")))
+
+(defcustom lsp-css-lint-id-selector "ignore"
+ "Selectors should not contain IDs because these rules are too
+tightly coupled with the HTML."
+ :type '(choice
+ (const "ignore")
+ (const "warning")
+ (const "error")))
+
+(defcustom lsp-css-lint-unknown-at-rules "warning"
+ "Unknown at-rule."
+ :type '(choice
+ (const "ignore")
+ (const "warning")
+ (const "error")))
+
+(defcustom lsp-css-trace-server "off"
+ "Traces the communication between VS Code and the CSS language
+server."
+ :type '(choice
+ (const "off")
+ (const "messages")
+ (const "verbose")))
+
+(lsp-register-custom-settings
+ '(("css.trace.server" lsp-css-trace-server)
+ ("css.lint.unknownAtRules" lsp-css-lint-unknown-at-rules)
+ ("css.lint.idSelector" lsp-css-lint-id-selector)
+ ("css.lint.float" lsp-css-lint-float)
+ ("css.lint.important" lsp-css-lint-important)
+ ("css.lint.propertyIgnoredDueToDisplay" lsp-css-lint-property-ignored-due-to-display)
+ ("css.lint.unknownVendorSpecificProperties" lsp-css-lint-unknown-vendor-specific-properties)
+ ("css.lint.ieHack" lsp-css-lint-ie-hack)
+ ("css.lint.validProperties" lsp-css-lint-valid-properties)
+ ("css.lint.unknownProperties" lsp-css-lint-unknown-properties)
+ ("css.lint.argumentsInColorFunction" lsp-css-lint-arguments-in-color-function)
+ ("css.lint.hexColorLength" lsp-css-lint-hex-color-length)
+ ("css.lint.fontFaceProperties" lsp-css-lint-font-face-properties)
+ ("css.lint.zeroUnits" lsp-css-lint-zero-units)
+ ("css.lint.universalSelector" lsp-css-lint-universal-selector)
+ ("css.lint.boxModel" lsp-css-lint-box-model)
+ ("css.lint.importStatement" lsp-css-lint-import-statement)
+ ("css.lint.emptyRules" lsp-css-lint-empty-rules)
+ ("css.lint.duplicateProperties" lsp-css-lint-duplicate-properties)
+ ("css.lint.vendorPrefix" lsp-css-lint-vendor-prefix)
+ ("css.lint.compatibleVendorPrefixes" lsp-css-lint-compatible-vendor-prefixes)
+ ("css.validate" lsp-css-validate t)
+ ("css.completion.triggerPropertyValueCompletion" lsp-css-completion-trigger-property-value-completion t)
+ ("css.experimental.customData" lsp-css-experimental-custom-data)))
+
+(defun lsp-css--server-command ()
+ "Generate startup command for CSS language server."
+ (list (lsp-package-path 'css-languageserver) "--stdio"))
+
+;;; CSS
+(lsp-defun lsp-css--apply-code-action ((&Command :arguments?))
+ "Apply ACTION as workspace edit command."
+ (lsp--apply-text-edits (cl-caddr arguments?) 'code-action))
+
+(lsp-dependency 'css-languageserver
+ '(:system "vscode-css-language-server")
+ '(:npm :package "vscode-langservers-extracted"
+ :path "vscode-css-language-server"))
+
+(lsp-register-client
+ (make-lsp-client
+ :new-connection (lsp-stdio-connection #'lsp-css--server-command)
+ :activation-fn (lsp-activate-on "css" "scss" "sass" "less")
+ :priority -1
+ :action-handlers (lsp-ht ("_css.applyCodeAction" #'lsp-css--apply-code-action))
+ :server-id 'css-ls
+ :download-server-fn (lambda (_client callback error-callback _update?)
+ (lsp-package-ensure 'css-languageserver callback error-callback))))
+
+(lsp-consistency-check lsp-css)
+
+(provide 'lsp-css)
+;;; lsp-css.el ends here
diff --git a/elpa/lsp-mode-20220505.630/lsp-css.elc b/elpa/lsp-mode-20220505.630/lsp-css.elc
new file mode 100644
index 0000000..ca3a85c
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-css.elc
Binary files differ
diff --git a/elpa/lsp-mode-20220505.630/lsp-d.el b/elpa/lsp-mode-20220505.630/lsp-d.el
new file mode 100644
index 0000000..d26369a
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-d.el
@@ -0,0 +1,41 @@
+;;; lsp-d.el --- lsp-mode dlang integration -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2021 lsp-mode maintainers
+
+;; Author: lsp-mode maintainers
+;; Keywords: languages
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; client for serve-d
+
+;;; Code:
+
+(require 'lsp-mode)
+(require 'ht)
+
+(lsp-register-client
+ (make-lsp-client :new-connection (lsp-stdio-connection "serve-d")
+ :major-modes '(d-mode)
+ :notification-handlers
+ (ht ("coded/changedSelectedWorkspace" #'ignore)
+ ("coded/initDubTree" #'ignore))
+ :server-id 'serve-d))
+
+(lsp-consistency-check lsp-d)
+
+(provide 'lsp-d)
+;;; lsp-d.el ends here
diff --git a/elpa/lsp-mode-20220505.630/lsp-d.elc b/elpa/lsp-mode-20220505.630/lsp-d.elc
new file mode 100644
index 0000000..044dc44
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-d.elc
Binary files differ
diff --git a/elpa/lsp-mode-20220505.630/lsp-dhall.el b/elpa/lsp-mode-20220505.630/lsp-dhall.el
new file mode 100644
index 0000000..7b10597
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-dhall.el
@@ -0,0 +1,43 @@
+;;; lsp-dhall.el --- description -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2020 emacs-lsp maintainers
+
+;; Author: emacs-lsp maintainers
+;; Keywords: lsp, dhall
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; LSP Clients for the Dhall Programming Language.
+
+;;; Code:
+
+(require 'lsp-mode)
+
+(defgroup lsp-dhall nil
+ "LSP support for Dhall, using dhall-lsp-server."
+ :group 'lsp-mode
+ :link '(url-link "https://github.com/dhall-lang/dhall-haskell"))
+
+(lsp-register-client
+ (make-lsp-client :new-connection (lsp-stdio-connection "dhall-lsp-server")
+ :major-modes '(dhall-mode)
+ :priority -1
+ :server-id 'dhallls))
+
+(lsp-consistency-check lsp-dhall)
+
+(provide 'lsp-dhall)
+;;; lsp-dhall.el ends here
diff --git a/elpa/lsp-mode-20220505.630/lsp-dhall.elc b/elpa/lsp-mode-20220505.630/lsp-dhall.elc
new file mode 100644
index 0000000..646ef4c
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-dhall.elc
Binary files differ
diff --git a/elpa/lsp-mode-20220505.630/lsp-diagnostics.el b/elpa/lsp-mode-20220505.630/lsp-diagnostics.el
new file mode 100644
index 0000000..f82ef56
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-diagnostics.el
@@ -0,0 +1,370 @@
+;;; lsp-diagnostics.el --- LSP diagnostics integration -*- lexical-binding: t; -*-
+;;
+;; Copyright (C) 2020 emacs-lsp maintainers
+;;
+;; 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 <https://www.gnu.org/licenses/>.
+;;
+;;; Commentary:
+;;
+;; LSP diagnostics integration
+;;
+;;; Code:
+
+(require 'lsp-mode)
+
+(defgroup lsp-diagnostics nil
+ "LSP support for diagnostics"
+ :prefix "lsp-disagnostics-"
+ :group 'lsp-mode
+ :tag "LSP Diagnostics")
+
+;;;###autoload
+(define-obsolete-variable-alias 'lsp-diagnostic-package
+ 'lsp-diagnostics-provider "lsp-mode 7.0.1")
+
+(defcustom lsp-diagnostics-provider :auto
+ "The checker backend provider."
+ :type
+ '(choice
+ (const :tag "Pick flycheck if present and fallback to flymake" :auto)
+ (const :tag "Pick flycheck" :flycheck)
+ (const :tag "Pick flymake" :flymake)
+ (const :tag "Use neither flymake nor lsp" :none)
+ (const :tag "Prefer flymake" t)
+ (const :tag "Prefer flycheck" nil))
+ :group 'lsp-diagnostics
+ :package-version '(lsp-mode . "6.3"))
+
+;;;###autoload
+(define-obsolete-variable-alias 'lsp-flycheck-default-level
+ 'lsp-diagnostics-flycheck-default-level "lsp-mode 7.0.1")
+
+(defcustom lsp-diagnostics-flycheck-default-level 'error
+ "Error level to use when the server does not report back a diagnostic level."
+ :type '(choice
+ (const error)
+ (const warning)
+ (const info))
+ :group 'lsp-diagnostics)
+
+(defcustom lsp-diagnostics-attributes
+ `((unnecessary :foreground "gray")
+ (deprecated :strike-through t))
+ "The Attributes used on the diagnostics.
+List containing (tag attributes) where tag is the LSP diagnostic tag and
+attributes is a `plist' containing face attributes which will be applied
+on top the flycheck face for that error level."
+ :type '(repeat list)
+ :group 'lsp-diagnostics)
+
+(defcustom lsp-diagnostics-disabled-modes nil
+ "A list of major models for which `lsp-diagnostics-mode' should be disabled."
+ :type '(repeat symbol)
+ :group 'lsp-diagnostics
+ :package-version '(lsp-mode . "8.0.0"))
+
+;; Flycheck integration
+
+(declare-function flycheck-mode "ext:flycheck")
+(declare-function flycheck-define-generic-checker
+ "ext:flycheck" (symbol docstring &rest properties))
+(declare-function flycheck-error-new "ext:flycheck" t t)
+(declare-function flycheck-error-message "ext:flycheck" (err) t)
+(declare-function flycheck-define-error-level "ext:flycheck" (level &rest properties))
+(declare-function flycheck-buffer "ext:flycheck")
+(declare-function flycheck-valid-checker-p "ext:flycheck")
+(declare-function flycheck-stop "ext:flycheck")
+
+(defvar flycheck-mode)
+(defvar flycheck-check-syntax-automatically)
+(defvar flycheck-checker)
+(defvar flycheck-checkers)
+
+
+(defvar-local lsp-diagnostics--flycheck-enabled nil
+ "True when lsp diagnostics flycheck integration has been enabled in this buffer.")
+
+(defvar-local lsp-diagnostics--flycheck-checker nil
+ "The value of flycheck-checker before lsp diagnostics was activated.")
+
+(defun lsp-diagnostics--flycheck-level (flycheck-level tags)
+ "Generate flycheck level from the original FLYCHECK-LEVEL (e.
+g. `error', `warning') and list of LSP TAGS."
+ (let ((name (format "lsp-flycheck-%s-%s"
+ flycheck-level
+ (mapconcat #'symbol-name tags "-"))))
+ (or (intern-soft name)
+ (let* ((face (--doto (intern (format "lsp-%s-face" name))
+ (copy-face (-> flycheck-level
+ (get 'flycheck-overlay-category)
+ (get 'face))
+ it)
+ (mapc (lambda (tag)
+ (apply #'set-face-attribute it nil
+ (cl-rest (assoc tag lsp-diagnostics-attributes))))
+ tags)))
+ (category (--doto (intern (format "lsp-%s-category" name))
+ (setf (get it 'face) face
+ (get it 'priority) 100)))
+ (new-level (intern name))
+ (bitmap (or (get flycheck-level 'flycheck-fringe-bitmaps)
+ (get flycheck-level 'flycheck-fringe-bitmap-double-arrow))))
+ (flycheck-define-error-level new-level
+ :severity (get flycheck-level 'flycheck-error-severity)
+ :compilation-level (get flycheck-level 'flycheck-compilation-level)
+ :overlay-category category
+ :fringe-bitmap bitmap
+ :fringe-face (get flycheck-level 'flycheck-fringe-face)
+ :error-list-face face)
+ new-level))))
+
+(defun lsp-diagnostics--flycheck-calculate-level (severity tags)
+ "Calculate flycheck level by SEVERITY and TAGS."
+ (let ((level (pcase severity
+ (1 'error)
+ (2 'warning)
+ (3 'info)
+ (4 'info)
+ (_ lsp-flycheck-default-level)))
+ ;; materialize only first tag.
+ (tags (seq-map (lambda (tag)
+ (cond
+ ((= tag lsp/diagnostic-tag-unnecessary) 'unnecessary)
+ ((= tag lsp/diagnostic-tag-deprecated) 'deprecated)))
+ tags)))
+ (if tags
+ (lsp-diagnostics--flycheck-level level tags)
+ level)))
+
+(defun lsp-diagnostics--flycheck-start (checker callback)
+ "Start an LSP syntax check with CHECKER.
+
+CALLBACK is the status callback passed by Flycheck."
+
+ (remove-hook 'lsp-on-idle-hook #'lsp-diagnostics--flycheck-buffer t)
+
+ (->> (lsp--get-buffer-diagnostics)
+ (-map (-lambda ((&Diagnostic :message :severity? :tags? :code? :source?
+ :range (&Range :start (&Position :line start-line
+ :character start-character)
+ :end (&Position :line end-line
+ :character end-character))))
+ (flycheck-error-new
+ :buffer (current-buffer)
+ :checker checker
+ :filename buffer-file-name
+ :message message
+ :level (lsp-diagnostics--flycheck-calculate-level severity? tags?)
+ :id code?
+ :group source?
+ :line (lsp-translate-line (1+ start-line))
+ :column (1+ (lsp-translate-column start-character))
+ :end-line (lsp-translate-line (1+ end-line))
+ :end-column (1+ (lsp-translate-column end-character)))))
+ (funcall callback 'finished)))
+
+(defun lsp-diagnostics--flycheck-buffer ()
+ "Trigger flyckeck on buffer."
+ (remove-hook 'lsp-on-idle-hook #'lsp-diagnostics--flycheck-buffer t)
+ (when (bound-and-true-p flycheck-mode)
+ (flycheck-buffer)))
+
+(defun lsp-diagnostics--flycheck-report ()
+ "Report flycheck.
+This callback is invoked when new diagnostics are received
+from the language server."
+ (when (and (or (memq 'idle-change flycheck-check-syntax-automatically)
+ (and (memq 'save flycheck-check-syntax-automatically)
+ (not (buffer-modified-p))))
+ lsp--cur-workspace)
+ ;; make sure diagnostics are published even if the diagnostics
+ ;; have been received after idle-change has been triggered
+ (->> lsp--cur-workspace
+ (lsp--workspace-buffers)
+ (mapc (lambda (buffer)
+ (when (and (lsp-buffer-live-p buffer)
+ (or
+ (not (bufferp buffer))
+ (and (get-buffer-window buffer)
+ (not (-contains? (buffer-local-value 'lsp-on-idle-hook buffer)
+ 'lsp-diagnostics--flycheck-buffer)))))
+ (lsp-with-current-buffer buffer
+ (add-hook 'lsp-on-idle-hook #'lsp-diagnostics--flycheck-buffer nil t)
+ (lsp--idle-reschedule (current-buffer)))))))))
+
+(cl-defgeneric lsp-diagnostics-flycheck-error-explainer (e _server-id)
+ "Explain a `flycheck-error' E in a generic way depending on the SERVER-ID."
+ (flycheck-error-message e))
+
+(defvar lsp-diagnostics-mode) ;; properly defined by define-minor-mode below
+
+;;;###autoload
+(defun lsp-diagnostics-lsp-checker-if-needed ()
+ (unless (flycheck-valid-checker-p 'lsp)
+ (flycheck-define-generic-checker 'lsp
+ "A syntax checker using the Language Server Protocol (LSP)
+provided by lsp-mode.
+See https://github.com/emacs-lsp/lsp-mode."
+ :start #'lsp-diagnostics--flycheck-start
+ :modes '(lsp-placeholder-mode) ;; placeholder
+ :predicate (lambda () lsp-diagnostics-mode)
+ :error-explainer (lambda (e)
+ (lsp-diagnostics-flycheck-error-explainer
+ e (lsp--workspace-server-id (car-safe (lsp-workspaces))))))))
+
+(defun lsp-diagnostics-flycheck-enable (&rest _)
+ "Enable flycheck integration for the current buffer."
+ (require 'flycheck)
+ (lsp-diagnostics-lsp-checker-if-needed)
+ (and (not lsp-diagnostics--flycheck-enabled)
+ (not (eq flycheck-checker 'lsp))
+ (setq lsp-diagnostics--flycheck-checker flycheck-checker))
+ (setq-local lsp-diagnostics--flycheck-enabled t)
+ (flycheck-mode 1)
+ (flycheck-stop)
+ (setq-local flycheck-checker 'lsp)
+ (lsp-flycheck-add-mode major-mode)
+ (add-to-list 'flycheck-checkers 'lsp)
+ (add-hook 'lsp-diagnostics-updated-hook #'lsp-diagnostics--flycheck-report nil t)
+ (add-hook 'lsp-managed-mode-hook #'lsp-diagnostics--flycheck-report nil t))
+
+(defun lsp-diagnostics-flycheck-disable ()
+ "Disable flycheck integration for the current buffer is it was enabled."
+ (when lsp-diagnostics--flycheck-enabled
+ (flycheck-stop)
+ (when (eq flycheck-checker 'lsp)
+ (setq-local flycheck-checker lsp-diagnostics--flycheck-checker))
+ (setq lsp-diagnostics--flycheck-checker nil)
+ (setq-local lsp-diagnostics--flycheck-enabled nil)
+ (when flycheck-mode
+ (flycheck-mode 1))))
+
+;; Flymake integration
+
+(declare-function flymake-mode "ext:flymake")
+(declare-function flymake-make-diagnostic "ext:flymake")
+(declare-function flymake-diag-region "ext:flymake")
+
+(defvar flymake-diagnostic-functions)
+(defvar flymake-mode)
+(defvar-local lsp-diagnostics--flymake-report-fn nil)
+
+(defun lsp-diagnostics--flymake-setup ()
+ "Setup flymake."
+ (setq lsp-diagnostics--flymake-report-fn nil)
+ (add-hook 'flymake-diagnostic-functions 'lsp-diagnostics--flymake-backend nil t)
+ (add-hook 'lsp-diagnostics-updated-hook 'lsp-diagnostics--flymake-after-diagnostics nil t)
+ (flymake-mode 1))
+
+(defun lsp-diagnostics--flymake-after-diagnostics ()
+ "Handler for `lsp-diagnostics-updated-hook'."
+ (cond
+ ((and lsp-diagnostics--flymake-report-fn flymake-mode)
+ (lsp-diagnostics--flymake-update-diagnostics))
+ ((not flymake-mode)
+ (setq lsp-diagnostics--flymake-report-fn nil))))
+
+(defun lsp-diagnostics--flymake-backend (report-fn &rest _args)
+ "Flymake backend using REPORT-FN."
+ (let ((first-run (null lsp-diagnostics--flymake-report-fn)))
+ (setq lsp-diagnostics--flymake-report-fn report-fn)
+ (when first-run
+ (lsp-diagnostics--flymake-update-diagnostics))))
+
+(defun lsp-diagnostics--flymake-update-diagnostics ()
+ "Report new diagnostics to flymake."
+ (funcall lsp-diagnostics--flymake-report-fn
+ (-some->> (lsp-diagnostics t)
+ (gethash (lsp--fix-path-casing buffer-file-name))
+ (--map (-let* (((&Diagnostic :message :severity?
+ :range (range &as &Range
+ :start (&Position :line start-line :character)
+ :end (&Position :line end-line))) it)
+ ((start . end) (lsp--range-to-region range)))
+ (when (= start end)
+ (if-let ((region (flymake-diag-region (current-buffer)
+ (1+ start-line)
+ character)))
+ (setq start (car region)
+ end (cdr region))
+ (lsp-save-restriction-and-excursion
+ (goto-char (point-min))
+ (setq start (point-at-bol (1+ start-line))
+ end (point-at-eol (1+ end-line))))))
+ (flymake-make-diagnostic (current-buffer)
+ start
+ end
+ (cl-case severity?
+ (1 :error)
+ (2 :warning)
+ (t :note))
+ message))))
+ ;; This :region keyword forces flymake to delete old diagnostics in
+ ;; case the buffer hasn't changed since the last call to the report
+ ;; function. See https://github.com/joaotavora/eglot/issues/159
+ :region (cons (point-min) (point-max))))
+
+
+
+;;;###autoload
+(defun lsp-diagnostics--enable ()
+ "Enable LSP checker support."
+ (when (and (member lsp-diagnostics-provider '(:auto :none :flycheck :flymake t nil))
+ (not (member major-mode lsp-diagnostics-disabled-modes)))
+ (lsp-diagnostics-mode 1)))
+
+(defun lsp-diagnostics--disable ()
+ "Disable LSP checker support."
+ (lsp-diagnostics-mode -1))
+
+;;;###autoload
+(define-minor-mode lsp-diagnostics-mode
+ "Toggle LSP diagnostics integration."
+ :group 'lsp-diagnostics
+ :global nil
+ :lighter ""
+ (cond
+ (lsp-diagnostics-mode
+ (cond
+ ((and (or
+ (and (eq lsp-diagnostics-provider :auto)
+ (functionp 'flycheck-mode))
+ (and (eq lsp-diagnostics-provider :flycheck)
+ (or (functionp 'flycheck-mode)
+ (user-error "The lsp-diagnostics-provider is set to :flycheck but flycheck is not installed?")))
+ ;; legacy
+ (null lsp-diagnostics-provider))
+ (require 'flycheck nil t))
+ (lsp-diagnostics-flycheck-enable))
+ ((or (eq lsp-diagnostics-provider :auto)
+ (eq lsp-diagnostics-provider :flymake)
+ (eq lsp-diagnostics-provider t))
+ (require 'flymake)
+ (lsp-diagnostics--flymake-setup))
+ ((not (eq lsp-diagnostics-provider :none))
+ (lsp--warn "Unable to autoconfigure flycheck/flymake. The diagnostics won't be rendered.")))
+
+ (add-hook 'lsp-unconfigure-hook #'lsp-diagnostics--disable nil t))
+ (t (lsp-diagnostics-flycheck-disable)
+ (remove-hook 'lsp-unconfigure-hook #'lsp-diagnostics--disable t))))
+
+;;;###autoload
+(add-hook 'lsp-configure-hook (lambda ()
+ (when lsp-auto-configure
+ (lsp-diagnostics--enable))))
+
+(lsp-consistency-check lsp-diagnostics)
+
+(provide 'lsp-diagnostics)
+;;; lsp-diagnostics.el ends here
diff --git a/elpa/lsp-mode-20220505.630/lsp-diagnostics.elc b/elpa/lsp-mode-20220505.630/lsp-diagnostics.elc
new file mode 100644
index 0000000..2f77b5e
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-diagnostics.elc
Binary files differ
diff --git a/elpa/lsp-mode-20220505.630/lsp-dired.el b/elpa/lsp-mode-20220505.630/lsp-dired.el
new file mode 100644
index 0000000..8b84af7
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-dired.el
@@ -0,0 +1,178 @@
+;;; lsp-dired.el --- `lsp-mode' diagnostics integrated into `dired' -*- lexical-binding: t -*-
+
+;; Copyright (C) 2021
+
+;; Author: Alexander Miller <alexanderm@web.de>
+;; Author: Ivan Yonchovski <yyoncho@gmail.com>
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;; `lsp-mode' diagnostics integrated into `dired'
+
+;;; Code:
+
+(require 'dired)
+(require 'pcase)
+(require 'lsp-mode)
+
+(defgroup lsp-dired nil
+ "LSP support for dired"
+ :prefix "lsp-dired-"
+ :group 'lsp-mode
+ :tag "LSP Dired")
+
+(defvar lsp-dired--ranger-adjust nil)
+(with-eval-after-load 'ranger (setf lsp-dired--ranger-adjust t))
+
+(defvar-local lsp-dired-displayed nil
+ "Flags whether icons have been added.")
+
+(defvar-local lsp-dired--covered-subdirs nil
+ "List of subdirs icons were already added for.")
+
+(defun lsp-dired--display ()
+ "Display the icons of files in a dired buffer."
+ (when (and (display-graphic-p)
+ (not lsp-dired-displayed)
+ dired-subdir-alist)
+ (setq-local lsp-dired-displayed t)
+ (pcase-dolist (`(,path . ,pos) dired-subdir-alist)
+ (lsp-dired--insert-for-subdir path pos))))
+
+(defun lsp-dired--insert-for-subdir (path pos)
+ "Display icons for subdir PATH at given POS."
+ (let ((buf (current-buffer)))
+ ;; run the function after current to make sure that we are creating the
+ ;; overlays after `treemacs-icons-dired' has run.
+ (run-with-idle-timer
+ 0.0 nil
+ (lambda ()
+ (unless (and (member path lsp-dired--covered-subdirs)
+ (not (buffer-live-p buf)))
+ (with-current-buffer buf
+ (add-to-list 'lsp-dired--covered-subdirs path)
+ (let (buffer-read-only)
+ (save-excursion
+ (goto-char pos)
+ (forward-line (if lsp-dired--ranger-adjust 1 2))
+ (cl-block :file
+ (while (not (eobp))
+ (if (dired-move-to-filename nil)
+ (let* ((file (dired-get-filename nil t))
+ (bol (progn
+ (point-at-bol)
+ (search-forward-regexp "^[[:space:]]*" (line-end-position) t)
+ (point)))
+ (face (lsp-dired--face-for-path file)))
+ (when face
+ (-doto (make-overlay bol (point-at-eol))
+ (overlay-put 'evaporate t)
+ (overlay-put 'face face))))
+ (cl-return-from :file nil))
+ (forward-line 1)))))))))))
+
+(defface lsp-dired-path-face '((t :inherit font-lock-string-face))
+ "Face used for breadcrumb paths on headerline."
+ :group 'lsp-dired)
+
+(defface lsp-dired-path-error-face
+ '((t :underline (:style wave :color "Red1")))
+ "Face used for breadcrumb paths on headerline when there is an error under that path"
+ :group 'lsp-dired)
+
+(defface lsp-dired-path-warning-face
+ '((t :underline (:style wave :color "Yellow")))
+ "Face used for breadcrumb paths on headerline when there is an warning under that path"
+ :group 'lsp-dired)
+
+(defface lsp-dired-path-info-face
+ '((t :underline (:style wave :color "Green")))
+ "Face used for breadcrumb paths on headerline when there is an info under that path"
+ :group 'lsp-dired)
+
+(defface lsp-dired-path-hint-face
+ '((t :underline (:style wave :color "Green")))
+ "Face used for breadcrumb paths on headerline when there is an hint under that path"
+ :group 'lsp-dired)
+
+(defun lsp-dired--face-for-path (dir)
+ "Calculate the face for DIR."
+ (when-let ((diags (lsp-diagnostics-stats-for (directory-file-name dir))))
+ (cl-labels ((check-severity
+ (severity)
+ (not (zerop (aref diags severity)))))
+ (cond
+ ((check-severity lsp/diagnostic-severity-error)
+ 'lsp-dired-path-error-face)
+ ((check-severity lsp/diagnostic-severity-warning)
+ 'lsp-dired-path-warning-face)
+ ((check-severity lsp/diagnostic-severity-information)
+ 'lsp-dired-path-info-face)
+ ((check-severity lsp/diagnostic-severity-hint)
+ 'lsp-dired-path-hint-face)))))
+
+(defun lsp-dired--insert-subdir-advice (&rest args)
+ "Advice to dired & dired+ insert-subdir commands.
+Will add icons for the subdir in the `car' of ARGS."
+ (let* ((path (car args))
+ (pos (cdr (assoc path dired-subdir-alist))))
+ (when pos
+ (lsp-dired--insert-for-subdir path pos))))
+
+(defun lsp-dired--kill-subdir-advice (&rest _args)
+ "Advice to dired kill-subdir commands.
+Will remove the killed subdir from `lsp-dired--covered-subdirs'."
+ (setf lsp-dired--covered-subdirs (delete (dired-current-directory)
+ lsp-dired--covered-subdirs)))
+
+(defun lsp-dired--reset (&rest _args)
+ "Reset metadata on revert."
+ (setq-local lsp-dired--covered-subdirs nil)
+ (setq-local lsp-dired-displayed nil))
+
+;;;###autoload
+(define-minor-mode lsp-dired-mode
+ "Display `lsp-mode' icons for each file in a dired buffer."
+ :require 'lsp-dired
+ :init-value nil
+ :global t
+ :group 'lsp-dired
+ (cond
+ (lsp-dired-mode
+ (add-hook 'dired-after-readin-hook #'lsp-dired--display)
+ (advice-add 'dired-kill-subdir :before #'lsp-dired--kill-subdir-advice)
+ (advice-add 'dired-insert-subdir :after #'lsp-dired--insert-subdir-advice)
+ (advice-add 'diredp-insert-subdirs :after #'lsp-dired--insert-subdir-advice)
+ (advice-add 'dired-revert :before #'lsp-dired--reset)
+ (dolist (buffer (buffer-list))
+ (with-current-buffer buffer
+ (when (derived-mode-p 'dired-mode)
+ (lsp-dired--display)))))
+ (t
+ (advice-remove 'dired-kill-subdir #'lsp-dired--kill-subdir-advice)
+ (advice-remove 'dired-insert-subdir #'lsp-dired--insert-subdir-advice)
+ (advice-remove 'diredp-insert-subdirs #'lsp-dired--insert-subdir-advice)
+ (advice-remove 'dired-revert #'lsp-dired--reset)
+ (remove-hook 'dired-after-readin-hook #'lsp-dired--display)
+ (dolist (buffer (buffer-list))
+ (with-current-buffer buffer
+ (when (derived-mode-p 'dired-mode)
+ (dired-revert)))))))
+
+
+(lsp-consistency-check lsp-dired)(provide 'lsp-dired)
+
+
+;;; lsp-dired.el ends here
diff --git a/elpa/lsp-mode-20220505.630/lsp-dired.elc b/elpa/lsp-mode-20220505.630/lsp-dired.elc
new file mode 100644
index 0000000..b3c56cb
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-dired.elc
Binary files differ
diff --git a/elpa/lsp-mode-20220505.630/lsp-dockerfile.el b/elpa/lsp-mode-20220505.630/lsp-dockerfile.el
new file mode 100644
index 0000000..1d0075d
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-dockerfile.el
@@ -0,0 +1,66 @@
+;;; lsp-dockerfile.el --- description -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2020 emacs-lsp maintainers
+
+;; Author: emacs-lsp maintainers
+;; Keywords: lsp, dockerfile
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; LSP Clients for Dockerfile documents.
+
+;;; Code:
+
+(require 'lsp-mode)
+
+
+;;; Dockerfile
+
+(defgroup lsp-dockerfile nil
+ "Dockerfile LSP client, provided by the Dockerfile Language Server."
+ :group 'lsp-mode
+ :version "8.0.0"
+ :link '(url-link "https://github.com/rcjsuen/dockerfile-language-server-nodejs"))
+
+(defcustom lsp-dockerfile-language-server-command
+ '("docker-langserver" "--stdio")
+ "The command that starts the docker language server."
+ :group 'lsp-dockerfile
+ :type '(repeat :tag "List of string values" string))
+
+(lsp-dependency 'docker-langserver
+ '(:system "docker-langserver")
+ '(:npm :package "dockerfile-language-server-nodejs"
+ :path "docker-langserver"))
+
+(lsp-register-client
+ (make-lsp-client :new-connection (lsp-stdio-connection
+ (lambda ()
+ `(,(or (executable-find
+ (cl-first lsp-dockerfile-language-server-command))
+ (lsp-package-path 'docker-langserver))
+ ,@(cl-rest lsp-dockerfile-language-server-command))))
+ :major-modes '(dockerfile-mode)
+ :priority -1
+ :server-id 'dockerfile-ls
+ :download-server-fn (lambda (_client callback error-callback _update?)
+ (lsp-package-ensure 'docker-langserver
+ callback error-callback))))
+
+(lsp-consistency-check lsp-dockerfile)
+
+(provide 'lsp-dockerfile)
+;;; lsp-dockerfile.el ends here
diff --git a/elpa/lsp-mode-20220505.630/lsp-dockerfile.elc b/elpa/lsp-mode-20220505.630/lsp-dockerfile.elc
new file mode 100644
index 0000000..774cfc2
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-dockerfile.elc
Binary files differ
diff --git a/elpa/lsp-mode-20220505.630/lsp-elixir.el b/elpa/lsp-mode-20220505.630/lsp-elixir.el
new file mode 100644
index 0000000..a5fb7fc
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-elixir.el
@@ -0,0 +1,213 @@
+;;; lsp-elixir.el --- description -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2021 emacs-lsp maintainers
+
+;; Author: emacs-lsp maintainers
+;; Keywords: lsp, elixir
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; LSP Clients for the Elixir Programming Language.
+
+;;; Code:
+
+(require 'lsp-mode)
+(require 'ht)
+
+(defcustom lsp-elixir-dialyzer-enabled t
+ "Run ElixirLS's rapid Dialyzer when code is saved."
+ :type 'boolean
+ :group 'lsp-elixir
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-elixir-dialyzer-warn-opts '()
+ "Dialyzer options to enable or disable warnings.
+
+See Dialyzer's documentation for options. Note that the \"race_conditions\"
+option is unsupported"
+ :type '(repeat string)
+ :group 'lsp-elixir
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-elixir-dialyzer-format "dialyxir_long"
+ "Formatter to use for Dialyzer warnings."
+ :type 'string
+ :group 'lsp-elixir
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-elixir-mix-env "test"
+ "Mix environment to use for compilation."
+ :type 'string
+ :group 'lsp-elixir
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-elixir-mix-target nil
+ "Mix target to use for compilation (requires Elixir >= 1.8)."
+ :type 'string
+ :group 'lsp-elixir
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-elixir-project-dir nil
+ "Subdirectory containing Mix project if not in the project root.
+
+If value is `\"\"` then defaults to the workspace rootUri."
+ :type 'string
+ :group 'lsp-elixir
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-elixir-fetch-deps t
+ "Automatically fetch project dependencies when compiling."
+ :type 'boolean
+ :group 'lsp-elixir
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-elixir-suggest-specs t
+ "Suggest @spec annotations inline using Dialyzer's inferred success typings.
+This requires Dialyzer."
+ :type 'boolean
+ :group 'lsp-elixir
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-elixir-signature-after-complete t
+ "Show signature help after confirming autocomplete."
+ :type 'boolean
+ :group 'lsp-elixir
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defgroup lsp-elixir nil
+ "LSP support for Elixir, using elixir-ls."
+ :group 'lsp-mode
+ :link '(url-link "https://github.com/elixir-lsp/elixir-ls"))
+
+(define-obsolete-variable-alias 'lsp-clients-elixir-server-executable 'lsp-elixir-server-command "2021-04-05")
+
+(defcustom lsp-elixir-server-command
+ (if (equal system-type 'windows-nt)
+ '("language_server.bat")
+ '("language_server.sh"))
+ "Command to start elixir-ls.
+
+Leave as default to let `executable-find' search for it."
+ :group 'lsp-elixir
+ :type '(repeat string)
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-elixir-ls-version "v0.9.0"
+ "Elixir-Ls version to download.
+It has to be set before `lsp-elixir.el' is loaded and it has to
+be available here: https://github.com/elixir-lsp/elixir-ls/releases/"
+ :type 'string
+ :group 'lsp-elixir
+ :package-version '(lsp-mode . "8.0.1"))
+
+(defcustom lsp-elixir-ls-download-url
+ (format "https://github.com/elixir-lsp/elixir-ls/releases/download/%s/elixir-ls.zip"
+ lsp-elixir-ls-version)
+ "Automatic download url for elixir-ls"
+ :type 'string
+ :group 'lsp-elixir
+ :package-version '(lsp-mode . "8.0.1"))
+
+
+(defconst lsp-elixir-ls-server-dir
+ (f-join lsp-server-install-dir "elixir-ls")
+ "Elixir-ls local server Directory.")
+
+(defcustom lsp-elixir-local-server-command
+ (f-join lsp-elixir-ls-server-dir
+ (cl-first lsp-elixir-server-command))
+ "Command to start local elixir-ls binary."
+ :group 'lsp-elixir
+ :type '(repeat string)
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-elixir-enable-test-lenses t
+ "Suggest Tests."
+ :type 'boolean
+ :group 'lsp-elixir
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defun lsp-elixir--build-test-command (argument)
+ "Builds the test command from the ARGUMENT."
+ (let ((test-name (lsp-get argument :testName))
+ (module (lsp-get argument :module))
+ (describe (lsp-get argument :describe)))
+ (cond (module (concat "\"" "module:" module "\""))
+ ((not test-name) (concat "\"" "describe:" describe "\""))
+ (describe (concat "\"" "test:test " describe " " test-name "\"" ))
+ (t (concat "\"" "test:test " test-name "\"" )))))
+
+(lsp-defun lsp-elixir--run-test ((&Command :arguments?))
+ "Runs tests."
+ (let* ((argument (lsp-seq-first arguments?))
+ (file-path (lsp-get argument :filePath))
+ (test-command (lsp-elixir--build-test-command argument)))
+ (compile
+ (concat "cd " (lsp-workspace-root file-path) " && "
+ "mix test --exclude test --include " test-command " " file-path
+ " --no-color"))
+ file-path))
+
+(lsp-dependency
+ 'elixir-ls
+ `(:download :url lsp-elixir-ls-download-url
+ :decompress :zip
+ :store-path ,(f-join lsp-server-install-dir "elixir-ls" "elixir-ls.zip")
+ :binary-path lsp-elixir-server-command
+ :set-executable? t))
+
+(lsp-register-custom-settings
+ '(("elixirLS.dialyzerEnabled" lsp-elixir-dialyzer-enabled t)
+ ("elixirLS.dialyzerWarnOpts" lsp-elixir-dialyzer-warn-opts)
+ ("elixirLS.dialyzerFormat" lsp-elixir-dialyzer-format)
+ ("elixirLS.mixEnv" lsp-elixir-mix-env)
+ ("elixirLS.mixTarget" lsp-elixir-mix-target)
+ ("elixirLS.projectDir" lsp-elixir-project-dir)
+ ("elixirLS.fetchDeps" lsp-elixir-fetch-deps t)
+ ("elixirLS.suggestSpecs" lsp-elixir-suggest-specs t)
+ ("elixirLS.signatureAfterComplete" lsp-elixir-signature-after-complete t)
+ ("elixirLS.enableTestLenses" lsp-elixir-enable-test-lenses t)))
+
+(lsp-register-client
+ (make-lsp-client :new-connection (lsp-stdio-connection
+ (lambda ()
+ `(,(or (when (f-exists? lsp-elixir-local-server-command)
+ lsp-elixir-local-server-command)
+ (or (executable-find
+ (cl-first lsp-elixir-server-command))
+ (lsp-package-path 'elixir-ls))
+ "language_server.bat")
+ ,@(cl-rest lsp-elixir-server-command))))
+ :major-modes '(elixir-mode)
+ :priority -1
+ :server-id 'elixir-ls
+ :action-handlers (ht ("elixir.lens.test.run" 'lsp-elixir--run-test))
+ :download-server-fn (lambda (_client callback error-callback _update?)
+ (lsp-package-ensure 'elixir-ls callback error-callback))
+ :initialized-fn (lambda (workspace)
+ (with-lsp-workspace workspace
+ (lsp--set-configuration
+ (lsp-configuration-section "elixirLS")))
+ (puthash
+ "textDocumentSync"
+ (ht ("save" t)
+ ("change" 2))
+ (lsp--workspace-server-capabilities workspace)))))
+
+(lsp-consistency-check lsp-elixir)
+
+(provide 'lsp-elixir)
+;;; lsp-elixir.el ends here
diff --git a/elpa/lsp-mode-20220505.630/lsp-elixir.elc b/elpa/lsp-mode-20220505.630/lsp-elixir.elc
new file mode 100644
index 0000000..0a2725f
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-elixir.elc
Binary files differ
diff --git a/elpa/lsp-mode-20220505.630/lsp-elm.el b/elpa/lsp-mode-20220505.630/lsp-elm.el
new file mode 100644
index 0000000..55f9f27
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-elm.el
@@ -0,0 +1,137 @@
+;;; lsp-elm.el --- Elm Client settings -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2019 Daniel V
+
+;; Author: Daniel V
+;; Keywords: elm lsp
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; lsp-elm client
+
+;;; Code:
+
+(require 'lsp-mode)
+
+(defgroup lsp-elm nil
+ "LSP support for the Elm programming language, using the server from https://github.com/elm-tooling/elm-language-server"
+ :group 'lsp-mode
+ :link '(url-link "https://github.com/elm-tooling/elm-language-server"))
+
+(defcustom lsp-elm-elm-language-server-path nil
+ "Path for elm-language-server.
+Can be installed globally with: npm i -g @elm-tooling/elm-language-server,
+or manually by cloning the repo and following the installing instructions."
+ :group 'lsp-elm
+ :risky t
+ :type 'file)
+
+(defcustom lsp-elm-trace-server
+ nil
+ "Enable/disable trace logging of client and server communication."
+ :type 'boolean
+ :group 'lsp-elm)
+
+(defcustom lsp-elm-elm-path
+ ""
+ "The path to your elm executable.
+
+Should be empty by default, in that case it will assume the name and try
+to first get it from a local npm installation or a global one. If you
+set it manually it will not try to load from the npm folder."
+ :type 'file
+ :group 'lsp-elm)
+
+(defcustom lsp-elm-elm-format-path
+ ""
+ "The path to your elm-format executable.
+
+Should be empty by default, in that case it will assume the name and try
+to first get it from a local npm installation or a global one. If you
+set it manually it will not try to load from the npm folder."
+ :type 'file
+ :group 'lsp-elm)
+
+(defcustom lsp-elm-elm-test-path
+ ""
+ "The path to your elm-test executable.
+
+Should be empty by default, in that case it will assume the name and try
+to first get it from a local npm installation or a global one. If you
+set it manually it will not try to load from the npm folder."
+ :type 'file
+ :group 'lsp-elm)
+
+(defcustom lsp-elm-disable-elmls-diagnostics
+ nil
+ "Enable/Disable linting diagnostics from the language server."
+ :type 'boolean
+ :group 'lsp-elm)
+
+(defcustom lsp-elm-only-update-diagnostics-on-save
+ nil
+ "Only update compiler diagnostics on save, not on document change."
+ :type 'boolean
+ :group 'lsp-elm)
+
+(defcustom lsp-elm-skip-install-package-confirmation
+ nil
+ "Skip confirmation for the Install Package code action."
+ :type 'boolean
+ :group 'lsp-elm)
+
+(defcustom lsp-elm-server-args
+ '("--stdio")
+ "Arguments to pass to the server."
+ :type '(repeat string)
+ :group 'lsp-elm)
+
+(defun lsp-elm--elm-language-server-command ()
+ "Generate LSP startup command for the Elm Language Server."
+ (cons
+ (or lsp-elm-elm-language-server-path
+ (lsp-package-path 'elm-language-server))
+ lsp-elm-server-args))
+
+(defun lsp-clients-elm--make-init-options ()
+ "Init options for elm-language-server."
+ `(:elmPath ,lsp-elm-elm-path
+ :elmFormatPath ,lsp-elm-elm-format-path
+ :elmTestPath ,lsp-elm-elm-test-path
+ :disableElmLSDiagnostics ,(lsp-json-bool lsp-elm-disable-elmls-diagnostics)
+ :onlyUpdateDiagnosticsOnSave ,(lsp-json-bool lsp-elm-only-update-diagnostics-on-save)
+ :skipInstallPackageConfirmation ,(lsp-json-bool lsp-elm-skip-install-package-confirmation)
+ :trace.server ,(lsp-json-bool lsp-elm-trace-server)))
+
+(lsp-dependency 'elm-language-server
+ '(:system "elm-language-server")
+ '(:npm :package "@elm-tooling/elm-language-server"
+ :path "elm-language-server"))
+
+(lsp-register-client
+ (make-lsp-client
+ :new-connection (lsp-stdio-connection #'lsp-elm--elm-language-server-command)
+ :major-modes '(elm-mode)
+ :priority -1
+ :initialization-options #'lsp-clients-elm--make-init-options
+ :server-id 'elm-ls
+ :download-server-fn (lambda (_client callback error-callback _update?)
+ (lsp-package-ensure 'elm-language-server callback error-callback))))
+
+(lsp-consistency-check lsp-elm)
+
+(provide 'lsp-elm)
+;;; lsp-elm.el ends here
diff --git a/elpa/lsp-mode-20220505.630/lsp-elm.elc b/elpa/lsp-mode-20220505.630/lsp-elm.elc
new file mode 100644
index 0000000..42fadef
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-elm.elc
Binary files differ
diff --git a/elpa/lsp-mode-20220505.630/lsp-emmet.el b/elpa/lsp-mode-20220505.630/lsp-emmet.el
new file mode 100644
index 0000000..4795812
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-emmet.el
@@ -0,0 +1,65 @@
+;;; lsp-emmet.el --- lsp-mode Emmet integration -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2022 emacs-lsp maintainers
+
+;; Author: lsp-mode maintainers
+;; Keywords: lsp, emmet
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; LSP Client for Emmet
+
+;;; Code:
+
+(require 'lsp-mode)
+
+;;; emmet-ls
+(defgroup lsp-emmet-ls nil
+ "Settings for emmet-ls."
+ :group 'lsp-mode
+ :link '(url-link "https://github.com/aca/emmet-ls")
+ :package-version '(lsp-mode . "8.0.1"))
+
+(defcustom lsp-emmet-ls-command '("emmet-ls" "--stdio")
+ "The command that starts emmet-ls."
+ :type '(repeat :tag "List of string values" string)
+ :group 'lsp-emmet-ls
+ :package-version '(lsp-mode . "8.0.1"))
+
+(lsp-dependency 'emmet-ls
+ '(:system "emmet-ls")
+ '(:npm :package "emmet-ls"
+ :path "emmet-ls"))
+
+(lsp-register-client
+ (make-lsp-client
+ :new-connection (lsp-stdio-connection
+ (lambda ()
+ `(,(or (executable-find (cl-first lsp-emmet-ls-command))
+ (lsp-package-path 'emmet-ls))
+ ,@(cl-rest lsp-emmet-ls-command))))
+ :activation-fn (lsp-activate-on "html" "css" "scss" "less" "javascriptreact" "typescriptreact")
+ :priority -1
+ :add-on? t
+ :multi-root t
+ :server-id 'emmet-ls
+ :download-server-fn (lambda (_client callback error-callback _update?)
+ (lsp-package-ensure 'emmet-ls callback error-callback))))
+
+(lsp-consistency-check lsp-emmet)
+
+(provide 'lsp-emmet)
+;;; lsp-emmet.el ends here
diff --git a/elpa/lsp-mode-20220505.630/lsp-emmet.elc b/elpa/lsp-mode-20220505.630/lsp-emmet.elc
new file mode 100644
index 0000000..77eb868
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-emmet.elc
Binary files differ
diff --git a/elpa/lsp-mode-20220505.630/lsp-erlang.el b/elpa/lsp-mode-20220505.630/lsp-erlang.el
new file mode 100644
index 0000000..2deae83
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-erlang.el
@@ -0,0 +1,67 @@
+;;; lsp-erlang.el --- Erlang Client settings -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2019 Roberto Aloi
+
+;; Author: Roberto Aloi
+;; Keywords: erlang lsp
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; lsp-erlang client
+
+;;; Code:
+
+(require 'lsp-mode)
+
+(defgroup lsp-erlang nil
+ "LSP support for the Erlang programming language, using erlang-ls"
+ :group 'lsp-mode
+ :link '(url-link "https://github.com/erlang-ls/erlang_ls"))
+
+(defcustom lsp-erlang-server-path
+ "erlang_ls"
+ "Path to the Erlang Language Server binary."
+ :group 'lsp-erlang
+ :risky t
+ :type 'file)
+
+(defcustom lsp-erlang-server-connection-type
+ 'stdio
+ "Type of connection to use with the Erlang Language Server: tcp or stdio"
+ :group 'lsp-erlang
+ :risky t
+ :type 'symbol)
+
+(defun lsp-erlang-server-start-fun (port)
+ `(,lsp-erlang-server-path
+ "--transport" "tcp"
+ "--port" ,(number-to-string port)))
+
+(defun lsp-erlang-server-connection ()
+ (if (eq lsp-erlang-server-connection-type 'tcp)
+ (lsp-tcp-connection 'lsp-erlang-server-start-fun)
+ (lsp-stdio-connection `(,lsp-erlang-server-path "--transport" "stdio"))))
+
+(lsp-register-client
+ (make-lsp-client :new-connection (lsp-erlang-server-connection)
+ :major-modes '(erlang-mode)
+ :priority -1
+ :server-id 'erlang-ls))
+
+(lsp-consistency-check lsp-erlang)
+
+(provide 'lsp-erlang)
+;;; lsp-erlang.el ends here
diff --git a/elpa/lsp-mode-20220505.630/lsp-erlang.elc b/elpa/lsp-mode-20220505.630/lsp-erlang.elc
new file mode 100644
index 0000000..65a9619
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-erlang.elc
Binary files differ
diff --git a/elpa/lsp-mode-20220505.630/lsp-eslint.el b/elpa/lsp-mode-20220505.630/lsp-eslint.el
new file mode 100644
index 0000000..74df3dd
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-eslint.el
@@ -0,0 +1,408 @@
+;;; lsp-eslint.el --- lsp-mode eslint integration -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2019 Ivan Yonchovski
+
+;; Author: Ivan Yonchovski <yyoncho@gmail.com>
+;; Keywords: languages
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'lsp-protocol)
+(require 'lsp-mode)
+
+(defconst lsp-eslint/status-ok 1)
+(defconst lsp-eslint/status-warn 2)
+(defconst lsp-eslint/status-error 3)
+
+(defgroup lsp-eslint nil
+ "ESlint language server group."
+ :group 'lsp-mode
+ :link '(url-link "https://github.com/Microsoft/vscode-eslint"))
+
+(defcustom lsp-eslint-unzipped-path (f-join lsp-server-install-dir "eslint/unzipped")
+ "The path to the file in which `eslint' will be stored."
+ :type 'file
+ :group 'lsp-eslint
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-eslint-download-url "https://github.com/emacs-lsp/lsp-server-binaries/blob/master/dbaeumer.vscode-eslint-2.2.2.vsix?raw=true"
+ "Eslint language server download url."
+ :type 'string
+ :group 'lsp-eslint
+ :package-version '(lsp-mode . "8.0.1"))
+
+(defcustom lsp-eslint-server-command `("node"
+ "~/server/out/eslintServer.js"
+ "--stdio")
+ "Command to start eslint server."
+ :risky t
+ :type '(repeat string)
+ :package-version '(lsp-mode . "6.3"))
+
+(defcustom lsp-eslint-enable t
+ "Controls whether eslint is enabled for JavaScript files or not."
+ :type 'boolean
+ :package-version '(lsp-mode . "6.3"))
+
+(defcustom lsp-eslint-package-manager "npm"
+ "The package manager you use to install node modules."
+ :type '(choice (const :tag "npm" "npm")
+ (const :tag "yarn" "yarn")
+ (const :tag "pnpm" "pnpm")
+ (string :tag "other"))
+ :package-version '(lsp-mode . "6.3"))
+
+(defcustom lsp-eslint-format t
+ "Whether to perform format."
+ :type 'boolean
+ :package-version '(lsp-mode . "6.3"))
+
+(defcustom lsp-eslint-node-path nil
+ "A path added to NODE_PATH when resolving the eslint module."
+ :type '(repeat string)
+ :package-version '(lsp-mode . "6.3"))
+
+(defcustom lsp-eslint-node "node"
+ "Path to nodejs."
+ :type 'file
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-eslint-options nil
+ "The eslint options object to provide args normally passed to
+ eslint when executed from a command line (see
+ http://eslint.org/docs/developer-guide/nodejs-api#cliengine)."
+ :type 'alist)
+
+(defcustom lsp-eslint-trace-server "off"
+ "Traces the communication between VSCode and the eslint linter service."
+ :type 'string)
+
+(defcustom lsp-eslint-run "onType"
+ "Run the linter on save (onSave) or on type (onType)"
+ :type '(choice (const :tag "onSave" "onSave")
+ (const :tag "onType" "onType"))
+ :package-version '(lsp-mode . "6.3"))
+
+(defcustom lsp-eslint-auto-fix-on-save nil
+ "Turns auto fix on save on or off."
+ :type 'boolean
+ :package-version '(lsp-mode . "6.3"))
+
+(defcustom lsp-eslint-fix-all-problem-type "all"
+ "Determines which problems are fixed when running the
+source.fixAll code action."
+ :type '(choice
+ (const "all")
+ (const "problems")
+ string)
+ :package-version '(lsp-mode . "7.0.1"))
+
+(defcustom lsp-eslint-quiet nil
+ "Turns on quiet mode, which ignores warnings."
+ :type 'boolean
+ :package-version '(lsp-mode . "6.3"))
+
+(defcustom lsp-eslint-working-directories []
+ ""
+ :type 'lsp-string-vector
+ :package-version '(lsp-mode . "6.3"))
+
+(defcustom lsp-eslint-validate '("svelte")
+ "An array of language ids which should always be validated by eslint."
+ :type '(repeat string)
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-eslint-provide-lint-task nil
+ "Controls whether a task for linting the whole workspace will be available."
+ :type 'boolean
+ :package-version '(lsp-mode . "6.3"))
+
+(defcustom lsp-eslint-lint-task-enable nil
+ "Controls whether a task for linting the whole workspace will be available."
+ :type 'boolean
+ :package-version '(lsp-mode . "6.3"))
+
+(defcustom lsp-eslint-lint-task-options "."
+ "Command line options applied when running the task for linting the whole
+workspace (see https://eslint.org/docs/user-guide/command-line-interface)."
+ :type 'string
+ :package-version '(lsp-mode . "6.3"))
+
+(defcustom lsp-eslint-runtime nil
+ "The location of the node binary to run ESLint under."
+ :type '(repeat string)
+ :package-version '(lsp-mode . "6.3"))
+
+(defcustom lsp-eslint-code-action-disable-rule-comment t
+ "Controls whether code actions to add a rule-disabling comment should be shown."
+ :type 'bool
+ :package-version '(lsp-mode . "6.3"))
+
+(defcustom lsp-eslint-code-action-disable-rule-comment-location "separateLine"
+ "Controls where the disable rule code action places comments.
+
+Accepts the following values:
+- \"separateLine\": Add the comment above the line to be disabled (default).
+- \"sameLine\": Add the comment on the same line that will be disabled."
+ :type '(choice
+ (const "separateLine")
+ (const "sameLine"))
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-eslint-code-action-show-documentation t
+ "Controls whether code actions to show documentation for an eslint rule should
+be shown."
+ :type 'bool
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-eslint-warn-on-ignored-files nil
+ "Controls whether a warning should be emitted when a file is ignored."
+ :type 'bool
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-eslint-rules-customizations []
+ "Controls severity overrides for eslint rules.
+
+The value is a vector of alists, with each alist containing the following keys:
+- rule - The rule to match. Can match wildcards with *, or be prefixed with !
+ to negate the match.
+- severity - The severity to report this rule as. Can be one of the following:
+ - \"off\": Disable the rule.
+ - \"info\": Report as informational.
+ - \"warn\": Report as a warning.
+ - \"error\": Report as an error.
+ - \"upgrade\": Increase by 1 severity level (eg. warning -> error).
+ - \"downgrade\": Decrease by 1 severity level (eg. warning -> info).
+ - \"default\": Report as the same severity specified in the eslint config."
+ :type '(lsp-repeatable-vector
+ (alist :options ((rule string)
+ (severity (choice
+ (const "off")
+ (const "info")
+ (const "warn")
+ (const "error")
+ (const "upgrade")
+ (const "downgrade")
+ (const "default"))))))
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-eslint-experimental-incremental-sync t
+ "Controls whether the new incremental text document synchronization should
+be used."
+ :type 'boolean
+ :package-version '(lsp-mode . "6.3"))
+
+(defcustom lsp-eslint-save-library-choices t
+ "Controls whether to remember choices made to permit or deny ESLint libraries
+from running."
+ :type 'boolean
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-eslint-library-choices-file (expand-file-name (locate-user-emacs-file ".lsp-eslint-choices"))
+ "The file where choices to permit or deny ESLint libraries from running is
+stored."
+ :type 'string
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defun lsp--find-eslint ()
+ (or
+ (when-let ((workspace-folder (lsp-find-session-folder (lsp-session) default-directory)))
+ (let ((eslint-local-path (f-join workspace-folder "node_modules" ".bin"
+ (if (eq system-type 'windows-nt) "eslint.cmd" "eslint"))))
+ (when (f-exists? eslint-local-path)
+ eslint-local-path)))
+ "eslint"))
+
+(defun lsp-eslint-create-default-configuration ()
+ "Create default eslint configuration."
+ (interactive)
+ (unless (lsp-session-folders (lsp-session))
+ (user-error "There are no workspace folders"))
+ (pcase (->> (lsp-session)
+ lsp-session-folders
+ (-filter (lambda (dir)
+ (-none?
+ (lambda (file) (f-exists? (f-join dir file)))
+ '(".eslintrc.js" ".eslintrc.yaml" ".eslintrc.yml" ".eslintrc" ".eslintrc.json")))))
+ (`nil (user-error "All workspace folders contain eslint configuration"))
+ (folders (let ((default-directory (completing-read "Select project folder: " folders nil t)))
+ (async-shell-command (format "%s --init" (lsp--find-eslint)))))))
+
+(lsp-defun lsp-eslint-status-handler (workspace (&eslint:StatusParams :state))
+ (setf (lsp--workspace-status-string workspace)
+ (propertize "ESLint"
+ 'face (cond
+ ((eq state lsp-eslint/status-error) 'error)
+ ((eq state lsp-eslint/status-warn) 'warn)
+ (t 'success)))))
+
+(lsp-defun lsp-eslint--configuration (_workspace (&ConfigurationParams :items))
+ (->> items
+ (seq-map (-lambda ((&ConfigurationItem :scope-uri?))
+ (-when-let* ((file (lsp--uri-to-path scope-uri?))
+ (buffer (find-buffer-visiting file))
+ (workspace-folder (lsp-find-session-folder (lsp-session) file)))
+ (with-current-buffer buffer
+ (list :validate (if (member (lsp-buffer-language) lsp-eslint-validate) "on" "probe")
+ :packageManager lsp-eslint-package-manager
+ :codeAction (list
+ :disableRuleComment (list
+ :enable (lsp-json-bool lsp-eslint-code-action-disable-rule-comment)
+ :location lsp-eslint-code-action-disable-rule-comment-location)
+ :showDocumentation (list
+ :enable (lsp-json-bool lsp-eslint-code-action-show-documentation)))
+ :codeActionOnSave (list :enable (lsp-json-bool lsp-eslint-auto-fix-on-save)
+ :mode lsp-eslint-fix-all-problem-type)
+ :format (lsp-json-bool lsp-eslint-format)
+ :quiet (lsp-json-bool lsp-eslint-quiet)
+ :onIgnoredFiles (if lsp-eslint-warn-on-ignored-files "warn" "off")
+ :options (or lsp-eslint-options (ht))
+ :rulesCustomizations lsp-eslint-rules-customizations
+ :run lsp-eslint-run
+ :nodePath lsp-eslint-node-path
+ :workspaceFolder (list :uri (lsp--path-to-uri workspace-folder)
+ :name (f-filename workspace-folder)))))))
+ (apply #'vector)))
+
+(lsp-defun lsp-eslint--open-doc (_workspace (&eslint:OpenESLintDocParams :url))
+ "Open documentation."
+ (browse-url url))
+
+(defun lsp-eslint-apply-all-fixes ()
+ "Apply all autofixes in the current buffer."
+ (interactive)
+ (lsp-send-execute-command "eslint.applyAllFixes" (vector (lsp--versioned-text-document-identifier))))
+
+;; XXX: replace with `lsp-make-interactive-code-action' macro
+;; (lsp-make-interactive-code-action eslint-fix-all "source.fixAll.eslint")
+
+(defun lsp-eslint-fix-all ()
+ "Perform the source.fixAll.eslint code action, if available."
+ (interactive)
+ (condition-case nil
+ (lsp-execute-code-action-by-kind "source.fixAll.eslint")
+ (lsp-no-code-actions
+ (when (called-interactively-p 'any)
+ (lsp--info "source.fixAll.eslint action not available")))))
+
+(defun lsp-eslint-server-command ()
+ (if (lsp-eslint-server-exists? lsp-eslint-server-command)
+ lsp-eslint-server-command
+ `(,lsp-eslint-node ,(f-join lsp-eslint-unzipped-path
+ "extension/server/out/eslintServer.js")
+ "--stdio")))
+
+(defun lsp-eslint-server-exists? (eslint-server-command)
+ (let* ((command-name (f-base (f-filename (cl-first eslint-server-command))))
+ (first-argument (cl-second eslint-server-command))
+ (first-argument-exist (and first-argument (file-exists-p first-argument))))
+ (if (equal command-name lsp-eslint-node)
+ first-argument-exist
+ (executable-find (cl-first eslint-server-command)))))
+
+(defvar lsp-eslint--stored-libraries (ht)
+ "Hash table defining if a given path to an ESLint library is allowed to run.
+If the value for a key is 4, it will be allowed. If it is 1, it will not. If a
+value does not exist for the key, or the value is nil, the user will be prompted
+to allow or deny it.")
+
+(when (and (file-exists-p lsp-eslint-library-choices-file)
+ lsp-eslint-save-library-choices)
+ (setq lsp-eslint--stored-libraries (lsp--read-from-file lsp-eslint-library-choices-file)))
+
+(lsp-defun lsp-eslint--confirm-local (_workspace (&eslint:ConfirmExecutionParams :library-path) callback)
+ (if-let ((option-alist '(("Always" 4 . t)
+ ("Yes" 4 . nil)
+ ("No" 1 . nil)
+ ("Never" 1 . t)))
+ (remembered-answer (gethash library-path lsp-eslint--stored-libraries)))
+ (funcall callback remembered-answer)
+ (lsp-ask-question
+ (format
+ "Allow lsp-mode to execute %s? Note: The latest versions of the ESLint language server no longer create this prompt."
+ library-path)
+ (mapcar 'car option-alist)
+ (lambda (response)
+ (let ((option (cdr (assoc response option-alist))))
+ (when (cdr option)
+ (puthash library-path (car option) lsp-eslint--stored-libraries)
+ (when lsp-eslint-save-library-choices
+ (lsp--persist lsp-eslint-library-choices-file lsp-eslint--stored-libraries)))
+ (funcall callback (car option)))))))
+
+(defun lsp-eslint--probe-failed (_workspace _message)
+ "Called when the server detects a misconfiguration in ESLint."
+ (lsp--error "ESLint is not configured correctly. Please ensure your eslintrc is set up for the languages you are using."))
+
+(lsp-register-client
+ (make-lsp-client
+ :new-connection
+ (lsp-stdio-connection
+ (lambda () (lsp-eslint-server-command))
+ (lambda () (lsp-eslint-server-exists? (lsp-eslint-server-command))))
+ :activation-fn (lambda (filename &optional _)
+ (when lsp-eslint-enable
+ (or (string-match-p (rx (one-or-more anything) "."
+ (or "ts" "js" "jsx" "tsx" "html" "vue" "svelte")eos)
+ filename)
+ (and (derived-mode-p 'js-mode 'js2-mode 'typescript-mode 'html-mode 'svelte-mode)
+ (not (string-match-p "\\.json\\'" filename))))))
+ :priority -1
+ :completion-in-comments? t
+ :add-on? t
+ :multi-root t
+ :notification-handlers (ht ("eslint/status" #'lsp-eslint-status-handler))
+ :request-handlers (ht ("workspace/configuration" #'lsp-eslint--configuration)
+ ("eslint/openDoc" #'lsp-eslint--open-doc)
+ ("eslint/probeFailed" #'lsp-eslint--probe-failed))
+ :async-request-handlers (ht ("eslint/confirmESLintExecution" #'lsp-eslint--confirm-local))
+ :server-id 'eslint
+ :initialized-fn (lambda (workspace)
+ (with-lsp-workspace workspace
+ (lsp--server-register-capability
+ (lsp-make-registration
+ :id "random-id"
+ :method "workspace/didChangeWatchedFiles"
+ :register-options? (lsp-make-did-change-watched-files-registration-options
+ :watchers
+ `[,(lsp-make-file-system-watcher
+ :glob-pattern "**/.eslintr{c.js,c.yaml,c.yml,c,c.json}")
+ ,(lsp-make-file-system-watcher
+ :glob-pattern "**/.eslintignore")
+ ,(lsp-make-file-system-watcher
+ :glob-pattern "**/package.json")])))))
+ :download-server-fn (lambda (_client callback error-callback _update?)
+ (let ((tmp-zip (make-temp-file "ext" nil ".zip")))
+ (delete-file tmp-zip)
+ (lsp-download-install
+ (lambda (&rest _)
+ (condition-case err
+ (progn
+ (lsp-unzip tmp-zip lsp-eslint-unzipped-path)
+ (funcall callback))
+ (error (funcall error-callback err))))
+ error-callback
+ :url lsp-eslint-download-url
+ :store-path tmp-zip)))))
+
+(lsp-consistency-check lsp-eslint)
+
+(provide 'lsp-eslint)
+;;; lsp-eslint.el ends here
diff --git a/elpa/lsp-mode-20220505.630/lsp-eslint.elc b/elpa/lsp-mode-20220505.630/lsp-eslint.elc
new file mode 100644
index 0000000..5a31405
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-eslint.elc
Binary files differ
diff --git a/elpa/lsp-mode-20220505.630/lsp-fortran.el b/elpa/lsp-mode-20220505.630/lsp-fortran.el
new file mode 100644
index 0000000..c9ffb7a
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-fortran.el
@@ -0,0 +1,61 @@
+;;; lsp-fortran.el --- description -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2020 emacs-lsp maintainers
+
+;; Author: emacs-lsp maintainers
+;; Keywords: lsp, fortran
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; LSP Clients for the Fortran Programming Language.
+
+;;; Code:
+
+(require 'lsp-mode)
+
+(defgroup lsp-fortran nil
+ "LSP support for Fortran, using the Fortran Language Server."
+ :group 'lsp-mode
+ :link '(url-link "https://github.com/hansec/fortran-language-server"))
+
+(defcustom lsp-clients-fortls-executable "fortls"
+ "The fortls executable to use.
+Leave as just the executable name to use the default behavior of
+finding the executable with `exec-path'."
+ :group 'lsp-fortran
+ :risky t
+ :type 'file)
+
+(defcustom lsp-clients-fortls-args '()
+ "Extra arguments for the fortls executable"
+ :group 'lsp-fortran
+ :risky t
+ :type '(repeat string))
+
+(defun lsp-clients--fortls-command ()
+ "Generate the language server startup command."
+ `(,lsp-clients-fortls-executable,@lsp-clients-fortls-args))
+
+(lsp-register-client
+ (make-lsp-client :new-connection (lsp-stdio-connection 'lsp-clients--fortls-command)
+ :major-modes '(f90-mode fortran-mode)
+ :priority -1
+ :server-id 'fortls))
+
+(lsp-consistency-check lsp-fortran)
+
+(provide 'lsp-fortran)
+;;; lsp-fortran.el ends here
diff --git a/elpa/lsp-mode-20220505.630/lsp-fortran.elc b/elpa/lsp-mode-20220505.630/lsp-fortran.elc
new file mode 100644
index 0000000..d65cb29
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-fortran.elc
Binary files differ
diff --git a/elpa/lsp-mode-20220505.630/lsp-fsharp.el b/elpa/lsp-mode-20220505.630/lsp-fsharp.el
new file mode 100644
index 0000000..f1f2a18
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-fsharp.el
@@ -0,0 +1,298 @@
+;;; lsp-fsharp.el --- description -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2019 Reed Mullanix
+
+;; Author: Reed Mullanix <reedmullanix@gmail.com>
+;; Keywords:
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; lsp-fsharp client
+
+;;; Code:
+
+(require 'lsp-mode)
+
+(defgroup lsp-fsharp nil
+ "LSP support for the F# Programming Language, using the FsharpAutoComplete server."
+ :link '(url-link "https://github.com/fsharp/FsAutoComplete")
+ :group 'lsp-mode
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-fsharp-server-install-dir (f-join lsp-server-install-dir "fsautocomplete/")
+ "Install directory for fsautocomplete server.
+The slash is expected at the end."
+ :group 'lsp-fsharp
+ :risky t
+ :type 'directory
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-fsharp-server-args nil
+ "Extra arguments for the F# language server."
+ :type '(repeat string)
+ :group 'lsp-fsharp
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-fsharp-keywords-autocomplete t
+ "Provides keywords in autocomplete list."
+ :group 'lsp-fsharp
+ :type 'boolean
+ :package-version '(lsp-mode . "6.2"))
+
+(defcustom lsp-fsharp-external-autocomplete nil
+ "Provides autocompletion for symbols from not opened namespaces/modules;
+inserts open on accept."
+ :group 'lsp-fsharp
+ :type 'boolean
+ :package-version '(lsp-mode . "6.2"))
+
+(defcustom lsp-fsharp-linter t
+ "Enables FSharpLint integration, provides additional warnings and code
+action fixes."
+ :group 'lsp-fsharp
+ :type 'boolean
+ :package-version '(lsp-mode . "6.2"))
+
+(defcustom lsp-fsharp-union-case-stub-generation t
+ "Enables a code action to generate pattern matching cases."
+ :group 'lsp-fsharp
+ :type 'boolean
+ :package-version '(lsp-mode . "6.2"))
+
+(defcustom lsp-fsharp-union-case-stub-generation-body "failwith \"Not Implemented\""
+ "Defines dummy body used by pattern matching generator."
+ :group 'lsp-fsharp
+ :type 'string
+ :risky t
+ :package-version '(lsp-mode . "6.2"))
+
+(defcustom lsp-fsharp-record-stub-generation t
+ "Enables code action to generate record stub."
+ :group 'lsp-fsharp
+ :type 'boolean
+ :package-version '(lsp-mode . "6.2"))
+
+(defcustom lsp-fsharp-record-stub-generation-body "failwith \"Not Implemented\""
+ "Defines dummy body used by record stub generator."
+ :group 'lsp-fsharp
+ :type 'string
+ :risky t
+ :package-version '(lsp-mode . "6.2"))
+
+(defcustom lsp-fsharp-interface-stub-generation t
+ "Enables code action to generate an interface stub."
+ :group 'lsp-fsharp
+ :type 'boolean
+ :package-version '(lsp-mode . "6.2"))
+
+(defcustom lsp-fsharp-interface-stub-generation-object-identifier "this"
+ "Defines object identifier used by interface stub generator,
+e.g. `this' or `self'."
+ :group 'lsp-fsharp
+ :type 'string
+ :package-version '(lsp-mode . "6.2"))
+
+(defcustom lsp-fsharp-interface-stub-generation-method-body "failwith \"Not Implemented\""
+ "Defines dummy body used by interface stub generator."
+ :group 'lsp-fsharp
+ :type 'string
+ :risky t
+ :package-version '(lsp-mode . "6.2"))
+
+(defcustom lsp-fsharp-unused-opens-analyzer t
+ "Enables unused open detection."
+ :group 'lsp-fsharp
+ :type 'boolean
+ :package-version '(lsp-mode . "6.2"))
+
+(defcustom lsp-fsharp-unused-declarations-analyzer t
+ "Enables unused symbol detection."
+ :group 'lsp-fsharp
+ :type 'boolean
+ :package-version '(lsp-mode . "6.2"))
+
+(defcustom lsp-fsharp-simplify-name-analyzer nil
+ "Enables simplify name analyzer and remove redundant qualifier quick fix."
+ :group 'lsp-fsharp
+ :type 'boolean
+ :package-version '(lsp-mode . "6.2"))
+
+(defcustom lsp-fsharp-resolve-namespaces t
+ "Enables resolve namespace quick fix; adds `open' if symbol is from not yet
+opened module/namespace."
+ :group 'lsp-fsharp
+ :type 'boolean
+ :package-version '(lsp-mode . "6.2"))
+
+(defcustom lsp-fsharp-enable-reference-code-lens t
+ "Enables reference count code lenses.
+It is recommended to disable if `--background-service-enabled' is not used."
+ :group 'lsp-fsharp
+ :type 'boolean
+ :package-version '(lsp-mode . "6.2"))
+
+(defcustom lsp-fsharp-auto-workspace-init nil
+ "Enable automatic workspace initialization.
+Do note that this can cause unexpected or challenging behaviors, as solutions
+with test projects are not autoloaded by FSharpAutoComplete."
+ :group 'lsp-fsharp
+ :type 'boolean
+ :risky t)
+
+(defcustom lsp-fsharp-generate-binlog nil
+ "Generate a binlog for debugging project cracking."
+ :group 'lsp-fsharp
+ :type 'boolean
+ :package-version '(lsp-mode . "8.0.1"))
+
+(defun lsp-fsharp--fsac-install (_client callback error-callback update?)
+ "Install/update fsautocomplete language server using `dotnet tool'.
+
+Will invoke CALLBACK or ERROR-CALLBACK based on result. Will update if UPDATE? is t"
+ (lsp-async-start-process
+ callback
+ error-callback
+ "dotnet" "tool" (if update? "update" "install") "-g" "fsautocomplete"))
+
+(defun lsp-fsharp--make-launch-cmd ()
+ "Build the command required to launch fsautocomplete."
+
+ ;; latest emacs-28 (on macOS) and master (as of Sat Feb 12 2022) has an issue
+ ;; that it launches processes using posix_spawn but does not reset sigmask properly
+ ;; thus causing dotnet runtime to lockup awaiting a SIGCHLD signal that never comes
+ ;; from subprocesses that quit
+ ;;
+ ;; as a workaround we will wrap fsautocomplete invocation in "/usr/bin/env --default-signal"
+ ;; (on linux) and "/bin/ksh -c" (on macos) so it launches with proper sigmask
+ ;;
+ ;; see https://lists.gnu.org/archive/html/emacs-devel/2022-02/msg00461.html
+ ;; --
+ ;; we also try to resolve full path to fsautocomplete using `executable-find' as
+ ;; our `startup-wrapper' may use $PATH to interpret the location of fsautocomplete
+ ;; and we want to actually use `exec-path' here
+
+ (let ((startup-wrapper (cond ((and (eq 'darwin system-type)
+ (version<= "28.0" emacs-version))
+ (list "/bin/ksh" "-c"))
+
+ ((and (eq 'gnu/linux system-type)
+ (version<= "29.0" emacs-version))
+ (list "/usr/bin/env" "--default-signal"))
+
+ (t nil)))
+ (fsautocomplete-exec (or (executable-find "fsautocomplete")
+ (f-join (or (getenv "USERPROFILE") (getenv "HOME"))
+ ".dotnet" "tools" "fsautocomplete"))))
+ (append startup-wrapper
+ (list fsautocomplete-exec "--background-service-enabled")
+ lsp-fsharp-server-args)))
+
+(defun lsp-fsharp--test-fsautocomplete-present ()
+ "Return non-nil if dotnet tool fsautocomplete is installed globally."
+ (string-match-p "fsautocomplete"
+ (shell-command-to-string "dotnet tool list -g")))
+
+(defun lsp-fsharp--project-list ()
+ "Get the list of files we need to send to fsharp/workspaceLoad."
+ (let* ((response (lsp-request "fsharp/workspacePeek"
+ `(:directory ,(lsp-workspace-root)
+ :deep 10
+ :excludedDirs ["paket-files" ".git" "packages" "node_modules"])))
+ (data (lsp--read-json (lsp-get response :content)))
+ (found (-> data (lsp-get :Data) (lsp-get :Found)))
+ (directory (seq-find (lambda (d) (equal "directory" (lsp-get d :Type))) found)))
+ (-> directory (lsp-get :Data) (lsp-get :Fsprojs))))
+
+;;;###autoload
+(defun lsp-fsharp--workspace-load (projects)
+ "Load all of the provided PROJECTS."
+ (lsp-request-async "fsharp/workspaceLoad"
+ `(:textDocuments ,(vconcat [] (mapcar (lambda (p) `(:uri ,p)) projects)))
+ (lambda (_)
+ (lsp--info "Workspace Loaded!"))))
+
+(defvar lsp-fsharp--default-init-options (list)
+ "Default init options to be passed to FSharpAutoComplete,
+ updated conditionally by `lsp-fsharp--make-init-options'.")
+
+(defun lsp-fsharp--make-init-options ()
+ "Init options for F#."
+ (-let [opts lsp-fsharp--default-init-options]
+ (if lsp-fsharp-auto-workspace-init
+ (push '(:AutomaticWorkspaceInit . t) opts)
+ opts)))
+
+(lsp-register-custom-settings
+ `(("FSharp.KeywordsAutocomplete" lsp-fsharp-keywords-autocomplete t)
+ ("FSharp.ExternalAutocomplete" lsp-fsharp-external-autocomplete t)
+ ("FSharp.Linter" lsp-fsharp-linter t)
+ ("FSharp.UnionCaseStubGeneration" lsp-fsharp-union-case-stub-generation t)
+ ("FSharp.UnionCaseStubGenerationBody" lsp-fsharp-union-case-stub-generation-body)
+ ("FSharp.RecordStubGeneration" lsp-fsharp-record-stub-generation t)
+ ("FSharp.RecordStubGenerationBody" lsp-fsharp-record-stub-generation-body)
+ ("FSharp.InterfaceStubGeneration" lsp-fsharp-interface-stub-generation t)
+ ("FSharp.InterfaceStubGenerationObjectIdentifier" lsp-fsharp-interface-stub-generation-object-identifier)
+ ("FSharp.InterfaceStubGenerationMethodBody" lsp-fsharp-interface-stub-generation-method-body)
+ ("FSharp.UnusedOpensAnalyzer" lsp-fsharp-unused-opens-analyzer t)
+ ("FSharp.UnusedDeclarationsAnalyzer" lsp-fsharp-unused-declarations-analyzer t)
+ ("FSharp.SimplifyNameAnalyzer" lsp-fsharp-simplify-name-analyzer t)
+ ("FSharp.ResolveNamespaces" lsp-fsharp-resolve-namespaces t)
+ ("FSharp.EnableReferenceCodeLens" lsp-fsharp-enable-reference-code-lens t)
+ ("FSharp.GenerateBinlog" lsp-fsharp-generate-binlog t)))
+
+(lsp-register-client
+ (make-lsp-client :new-connection (lsp-stdio-connection
+ #'lsp-fsharp--make-launch-cmd
+ #'lsp-fsharp--test-fsautocomplete-present)
+ :major-modes '(fsharp-mode)
+ :notification-handlers (ht ("fsharp/notifyCancel" #'ignore)
+ ("fsharp/notifyWorkspace" #'ignore)
+ ("fsharp/fileParsed" #'ignore)
+ ("fsharp/notifyWorkspacePeek" #'ignore)
+ ("fsharp/documentAnalyzed" #'ignore)
+ ("fsharp/testDetected" #'ignore))
+ :initialization-options 'lsp-fsharp--make-init-options
+ :initialized-fn (lambda (workspace)
+ (with-lsp-workspace workspace
+ ;; Something needs to be calling lsp--set-configuration
+ (progn
+ (lsp--set-configuration
+ (lsp-configuration-section "fsharp"))
+ (lsp-fsharp--workspace-load
+ (lsp-fsharp--project-list)))))
+ :after-open-fn ;; workaround https://github.com/fsharp/FsAutoComplete/issues/833
+ (lambda ()
+ (setq-local lsp-default-create-error-handler-fn
+ (lambda (method)
+ (lambda (error)
+ (when
+ (not
+ (seq-find (lambda (s)
+ (string= s (lsp-get error :message)))
+ '("Index was outside the bounds of the array."
+ "No symbol information found"
+ "No ident at this location")))
+ (lsp--warn
+ "%s"
+ (or (lsp--error-string error)
+ (format "%s Request has failed" method))))))))
+ :server-id 'fsac
+ :download-server-fn #'lsp-fsharp--fsac-install))
+
+(lsp-consistency-check lsp-fsharp)
+
+(provide 'lsp-fsharp)
+;;; lsp-fsharp.el ends here
diff --git a/elpa/lsp-mode-20220505.630/lsp-fsharp.elc b/elpa/lsp-mode-20220505.630/lsp-fsharp.elc
new file mode 100644
index 0000000..590ce05
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-fsharp.elc
Binary files differ
diff --git a/elpa/lsp-mode-20220505.630/lsp-gdscript.el b/elpa/lsp-mode-20220505.630/lsp-gdscript.el
new file mode 100644
index 0000000..4a52ec8
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-gdscript.el
@@ -0,0 +1,61 @@
+;;; lsp-gdscript.el --- LSP mode -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2020 Oliver Frank
+
+;; Author: Oliver Frank <oliverfrank321@gmail.com>
+;; Keywords: languages
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; lsp-gdscript client
+
+;;; Code:
+(require 'lsp-mode)
+
+(defgroup lsp-gdscript nil
+ "LSP support for GDScript, using godot's language server."
+ :group 'lsp-mode
+ :link '(url-link "https://github.com/godotengine/godot")
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-gdscript-port 6008
+ "Port to connect server to"
+ :type 'integer
+ :group 'lsp-gdscript)
+
+(defun lsp-gdscript-tcp-connect-to-port ()
+ (list
+ :connect (lambda (filter sentinel name _environment-fn)
+ (let* ((host "localhost")
+ (port lsp-gdscript-port)
+ (tcp-proc (lsp--open-network-stream host port (concat name "::tcp"))))
+
+ (set-process-query-on-exit-flag tcp-proc nil)
+ (set-process-filter tcp-proc filter)
+ (set-process-sentinel tcp-proc sentinel)
+ (cons tcp-proc tcp-proc)))
+ :test? (lambda () t)))
+
+(lsp-register-client
+ (make-lsp-client :new-connection (lsp-gdscript-tcp-connect-to-port)
+ :major-modes '(gdscript-mode)
+ :server-id 'gdscript))
+
+
+(lsp-consistency-check lsp-gdscript)(provide 'lsp-gdscript)
+
+
+;;; lsp-gdscript.el ends here
diff --git a/elpa/lsp-mode-20220505.630/lsp-gdscript.elc b/elpa/lsp-mode-20220505.630/lsp-gdscript.elc
new file mode 100644
index 0000000..151ec23
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-gdscript.elc
Binary files differ
diff --git a/elpa/lsp-mode-20220505.630/lsp-go.el b/elpa/lsp-mode-20220505.630/lsp-go.el
new file mode 100644
index 0000000..874b576
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-go.el
@@ -0,0 +1,337 @@
+;;; lsp-go.el --- Go Client settings -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2019 Muir Manders
+
+;; Author: Muir Manders <muir@mnd.rs>
+;; Keywords:
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; lsp-go client
+
+;;; Code:
+
+(require 'lsp-mode)
+(require 'lsp-completion)
+
+(defgroup lsp-go nil
+ "LSP support for the Go Programming Language, using the gopls language server."
+ :link '(url-link "https://github.com/golang/tools/blob/master/gopls/README.md")
+ :group 'lsp-mode
+ :package-version '(lsp-mode . "6.3.2"))
+
+(define-obsolete-variable-alias
+ 'lsp-gopls-server-path
+ 'lsp-go-gopls-server-path
+ "lsp-mode 7.0.1")
+
+(defcustom lsp-go-gopls-server-path "gopls"
+ "Path to gopls server binary."
+ :type 'string
+ :group 'lsp-go)
+
+(define-obsolete-variable-alias
+ 'lsp-gopls-server-args
+ 'lsp-go-gopls-server-args
+ "lsp-mode 7.0.1")
+
+(defcustom lsp-go-gopls-server-args nil
+ "Extra CLI arguments for gopls."
+ :type '(repeat string)
+ :group 'lsp-go)
+
+(define-obsolete-variable-alias
+ 'lsp-gopls-use-placeholders
+ 'lsp-go-use-placeholders
+ "lsp-mode 7.0.1")
+
+(defcustom lsp-go-use-placeholders t
+ "Cause gopls to provide placeholder parameter snippets when
+completing function calls."
+ :type 'boolean
+ :group 'lsp-go)
+
+(define-obsolete-variable-alias
+ 'lsp-gopls-build-flags
+ 'lsp-go-build-flags
+ "lsp-mode 7.0.1")
+
+(defcustom lsp-go-build-flags []
+ "A vector of flags passed on to the build system when invoked,
+ applied to queries like `go list'."
+ :type 'lsp-string-vector
+ :group 'lsp-go
+ :risky t
+ :package-version '(lsp-mode "6.2"))
+
+(define-obsolete-variable-alias
+ 'lsp-gopls-env
+ 'lsp-go-env
+ "lsp-mode 7.0.1")
+
+(defcustom lsp-go-env nil
+ "`gopls' has the unusual ability to set environment variables,
+ intended to affect the behavior of commands invoked by `gopls'
+ on the user's behalf. This variable takes a hash table of env
+ var names to desired values."
+ :type '(alist :key-type (symbol :tag "env var name") :value-type (string :tag "value"))
+ :group 'lsp-go
+ :risky t
+ :package-version '(lsp-mode "6.2"))
+
+(defcustom lsp-go-directory-filters []
+ "A vector of directory filters."
+ :link '(url-link "https://github.com/golang/tools/blob/67e49ef2d0f326051e22a4a55bdf9344ae1a8ed8/gopls/doc/settings.md#directoryfilters-string")
+ :group 'lsp-go
+ :type 'lsp-string-vector
+ :package-version '(lsp-mode "8.0.0"))
+
+(define-obsolete-variable-alias
+ 'lsp-gopls-hover-kind
+ 'lsp-go-hover-kind
+ "lsp-mode 7.0.1")
+
+(defcustom lsp-go-hover-kind "SynopsisDocumentation"
+ "`gopls' allows the end user to select the desired amount of
+ documentation returned during e.g. hover and thing-at-point
+ operations."
+ :type '(choice (const "SynopsisDocumentation")
+ (const "NoDocumentation")
+ (const "FullDocumentation")
+ (const "SingleLine")
+ (const "Structured"))
+ :group 'lsp-go
+ :risky t
+ :package-version '(lsp-mode "6.2"))
+
+(define-obsolete-variable-alias
+ 'lsp-gopls-available-codelens
+ 'lsp-go-available-codelenses
+ "lsp-mode 7.0.1")
+
+(define-obsolete-variable-alias
+ 'lsp-go-available-codelens
+ 'lsp-go-available-codelenses
+ "lsp-mode 7.0.1")
+
+(defvar lsp-go-available-codelenses
+ '(
+ (gc_details . "Toggle the calculation of gc annotations")
+ (generate . "Run `go generate` for a directory")
+ (regenerate_cgo . "Regenerate cgo definitions")
+ (test . "Run `go test` for a specific set of test or benchmark functions (lgeacy)")
+ (tidy . "Run `go mod tidy` for a module")
+ (upgrade_dependency . "Upgrade a dependency")
+ (vendor . "Runs `go mod vendor' for a module"))
+ "Available codelenses that can be further enabled or disabled
+ through `lsp-go-codelenses'.")
+
+(defun lsp-go--defcustom-available-as-alist-type (alist)
+ "Returns a list suitable for the `:type' field in a `defcustom' used to populate an alist.
+
+The input ALIST has the form `((\"name\" . \"documentation sentence\") [...])'
+
+The returned type provides a tri-state that either:
+ - does not include the element in the alist
+ - sets element to false (actually, :json-false)
+ - sets element to true (actually, t)
+"
+ (let ((list '()))
+ (dolist (v alist)
+ (push `(cons
+ :tag ,(cdr v)
+ (const :format "" ,(car v))
+ (choice (const :tag "Enable" t) (const :tag "Disable" :json-false)))
+ list))
+ (push 'set list)
+ list))
+
+(define-obsolete-variable-alias
+ 'lsp-gopls-codelens
+ 'lsp-go-codelenses
+ "lsp-mode 7.0.1")
+
+(define-obsolete-variable-alias
+ 'lsp-go-codelens
+ 'lsp-go-codelenses
+ "lsp-mode 7.0.1")
+
+(defcustom lsp-go-codelenses '((gc_details . :json-false)
+ (generate . t)
+ (regenerate_cgo . t)
+ (tidy . t)
+ (upgrade_dependency . t)
+ (test . t)
+ (vendor . t))
+ "Select what codelenses should be enabled or not.
+
+The codelenses can be found at https://github.com/golang/tools/blob/3fa0e8f87c1aae0a9adc2a63af1a1945d16d9359/internal/lsp/source/options.go#L106-L112."
+ :type (lsp-go--defcustom-available-as-alist-type lsp-go-available-codelenses)
+ :group 'lsp-go
+ :risky t
+ :package-version '(lsp-mode "7.0"))
+
+(define-obsolete-variable-alias
+ 'lsp-clients-go-library-directories
+ 'lsp-go-library-directories
+ "lsp-mode 7.0.1")
+
+(defcustom lsp-go-library-directories '("/usr")
+ "List of directories which will be considered to be libraries."
+ :group 'lsp-go
+ :risky t
+ :type '(repeat string))
+
+(define-obsolete-variable-alias
+ 'lsp-clients-go-library-directories-include-go-modules
+ 'lsp-go-library-directories-include-go-modules
+ "lsp-mode 7.0.1")
+
+(defcustom lsp-go-library-directories-include-go-modules t
+ "Whether or not $GOPATH/pkg/mod should be included as a library directory."
+ :type 'boolean
+ :group 'lsp-go)
+
+(defun lsp-go--library-default-directories (_workspace)
+ "Calculate go library directories.
+
+If `lsp-go-library-directories-include-go-modules' is non-nil
+and the environment variable GOPATH is set this function will return
+$GOPATH/pkg/mod along with the value of
+`lsp-go-library-directories'."
+ (let ((library-dirs lsp-go-library-directories))
+ (when (and lsp-go-library-directories-include-go-modules
+ (or (and (not (file-remote-p default-directory)) (executable-find "go"))
+ (and (version<= "27.0" emacs-version) (with-no-warnings (executable-find "go" (file-remote-p default-directory))))))
+ (with-temp-buffer
+ (when (zerop (process-file "go" nil t nil "env" "GOPATH"))
+ (setq library-dirs
+ (append
+ library-dirs
+ (list
+ (concat
+ (string-trim-right (buffer-substring (point-min) (point-max)))
+ "/pkg/mod")))))))
+ (if (file-remote-p default-directory)
+ (mapcar (lambda (path) (concat (file-remote-p default-directory) path)) library-dirs)
+ library-dirs)))
+
+(defcustom lsp-go-link-target "pkg.go.dev"
+ "Which website to use for displaying Go documentation."
+ :type '(choice (const "pkg.go.dev")
+ (string :tag "A custom website"))
+ :group 'lsp-go
+ :package-version '(lsp-mode "7.0.1"))
+
+(defcustom lsp-go-links-in-hover t
+ "If non-nil, hover documentation includes links."
+ :type 'boolean
+ :group 'lsp-go
+ :package-version '(lsp-mode "8.0.0"))
+
+(defcustom lsp-go-use-gofumpt nil
+ "If non-nil, use gofumpt formatting."
+ :type 'boolean
+ :group 'lsp-go
+ :package-version '(lsp-mode "8.0.0"))
+
+(defcustom lsp-go-goimports-local ""
+ "Equivalent of the goimports -local flag, which puts imports beginning with
+ this string after third-party packages. It should be the prefix of the import
+ path whose imports should be grouped separately."
+ :type 'string
+ :group 'lsp-go
+ :package-version '(lsp-mode "8.0.0"))
+
+(defcustom lsp-go-analyses nil
+ "Specify analyses that the user would like to enable or disable. A map of the
+ names of analysis passes that should be enabled/disabled. A full list of
+ analyzers that gopls uses can be found at
+ https://github.com/golang/tools/blob/master/gopls/doc/analyzers.md"
+ :type '(alist :key-type (string :tag "analyzer name") :value-type (boolean :tag "value"))
+ :group 'lsp-go
+ :risky t
+ :package-version '(lsp-mode "8.0.0"))
+
+(defcustom lsp-go-import-shortcut "Both"
+ "Specifies whether import statements should link to documentation or go to
+ definitions."
+ :type '(choice (const "Both")
+ (const "Link")
+ (const "Definition"))
+ :group 'lsp-go
+ :risky t
+ :package-version '(lsp-mode "8.0.0"))
+
+(defcustom lsp-go-symbol-matcher "Fuzzy"
+ "Sets the algorithm that is used when finding workspace symbols."
+ :type '(choice (const "Fuzzy")
+ (const "CaseInsensitive")
+ (const "CaseSensitive"))
+ :group 'lsp-go
+ :risky t
+ :package-version '(lsp-mode "8.0.0"))
+
+(defcustom lsp-go-symbol-style "Dynamic"
+ "Controls how symbols are qualified in symbol responses.
+
+ 'Dynamic' uses whichever qualifier results in the highest scoring match for
+ the given symbol query. Here a 'qualifier' is any '/' or '.' delimited suffix
+ of the fully qualified symbol. i.e. 'to/pkg.Foo.Field' or just 'Foo.Field'.
+
+ 'Full' is fully qualified symbols, i.e. 'path/to/pkg.Foo.Field'.
+
+ 'Package' is package qualified symbols i.e. 'pkg.Foo.Field'."
+ :type '(choice (const "Dynamic")
+ (const "Full")
+ (const "Package"))
+ :group 'lsp-go
+ :risky t
+ :package-version '(lsp-mode "8.0.0"))
+
+(lsp-register-custom-settings
+ '(("gopls.usePlaceholders" lsp-go-use-placeholders t)
+ ("gopls.hoverKind" lsp-go-hover-kind)
+ ("gopls.buildFlags" lsp-go-build-flags)
+ ("gopls.env" lsp-go-env)
+ ("gopls.linkTarget" lsp-go-link-target)
+ ("gopls.codelenses" lsp-go-codelenses)
+ ("gopls.linksInHover" lsp-go-links-in-hover t)
+ ("gopls.gofumpt" lsp-go-use-gofumpt t)
+ ("gopls.local" lsp-go-goimports-local)
+ ("gopls.directoryFilters" lsp-go-directory-filters)
+ ("gopls.analyses" lsp-go-analyses)
+ ("gopls.importShortcut" lsp-go-import-shortcut)
+ ("gopls.symbolMatcher" lsp-go-symbol-matcher)
+ ("gopls.symbolStyle" lsp-go-symbol-style)))
+
+(lsp-register-client
+ (make-lsp-client :new-connection (lsp-stdio-connection
+ (lambda () (cons lsp-go-gopls-server-path lsp-go-gopls-server-args)))
+ :major-modes '(go-mode go-dot-mod-mode)
+ :language-id "go"
+ :priority 0
+ :server-id 'gopls
+ :completion-in-comments? t
+ :library-folders-fn #'lsp-go--library-default-directories
+ :after-open-fn (lambda ()
+ ;; https://github.com/golang/tools/commit/b2d8b0336
+ (setq-local lsp-completion-filter-on-incomplete nil))))
+
+(lsp-consistency-check lsp-go)
+
+(provide 'lsp-go)
+;;; lsp-go.el ends here
diff --git a/elpa/lsp-mode-20220505.630/lsp-go.elc b/elpa/lsp-mode-20220505.630/lsp-go.elc
new file mode 100644
index 0000000..d14d530
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-go.elc
Binary files differ
diff --git a/elpa/lsp-mode-20220505.630/lsp-graphql.el b/elpa/lsp-mode-20220505.630/lsp-graphql.el
new file mode 100644
index 0000000..3b1bfba
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-graphql.el
@@ -0,0 +1,73 @@
+;;; lsp-graphql.el --- lsp client for graphql -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2021 Binbin Ye
+
+;; Author: Binbin Ye
+;; Keywords: lsp, graphql
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Support for running graphql lsp. Support multiple server running at the same time when editing tsx/jsx.
+
+;;; Code:
+
+(require 'lsp-mode)
+
+(lsp-dependency 'graphql-language-service-cli
+ '(:npm :package "graphql-language-service-cli"
+ :path "graphql-lsp"))
+
+
+(defgroup lsp-graphql nil
+ "LSP support for the GraphQL, using the graphql-language-service-cli as language server."
+ :link '(url-link "https://github.com/graphql/graphiql/tree/main/packages/graphql-language-service-cli#readme")
+ :group 'lsp-mode)
+
+(defcustom lsp-clients-graphql-server-args '("server" "--method=stream")
+ "CLI arguments for graphql language server."
+ :type '(repeat string)
+ :risky t
+ :group 'lsp-graphql)
+
+(defun lsp-graphql-activate-p (filename &optional _)
+ "Check if the GraphQL language server should be enabled based on FILENAME."
+ (or (string-match-p (rx (one-or-more anything) "."
+ (or "ts" "js" "jsx" "tsx" "vue" "graphql" "gql")eos)
+ filename)
+ (and (derived-mode-p 'js-mode 'js2-mode 'typescript-mode)
+ (not (derived-mode-p 'json-mode)))))
+
+(lsp-register-client
+ (make-lsp-client :new-connection (lsp-stdio-connection (lambda()
+ (cons (lsp-package-path 'graphql-language-service-cli)
+ lsp-clients-graphql-server-args)))
+ :major-modes '(graphql-mode)
+ :language-id "graphql"
+ :server-id 'graphql-lsp
+ :priority -3
+ :add-on? t
+ :multi-root t
+ :activation-fn 'lsp-graphql-activate-p
+ :download-server-fn (lambda (_client callback error-callback _update?)
+ (lsp-package-ensure
+ 'graphql-language-service-cli
+ callback
+ error-callback))))
+
+(lsp-consistency-check lsp-graphql)
+
+(provide 'lsp-graphql)
+;;; lsp-graphql.el ends here
diff --git a/elpa/lsp-mode-20220505.630/lsp-graphql.elc b/elpa/lsp-mode-20220505.630/lsp-graphql.elc
new file mode 100644
index 0000000..6aea36d
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-graphql.elc
Binary files differ
diff --git a/elpa/lsp-mode-20220505.630/lsp-groovy.el b/elpa/lsp-mode-20220505.630/lsp-groovy.el
new file mode 100644
index 0000000..c1fcaaf
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-groovy.el
@@ -0,0 +1,66 @@
+;;; lsp-groovy.el --- description -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2020 emacs-lsp maintainers
+
+;; Author: emacs-lsp maintainers
+;; Keywords: lsp, groovy
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; LSP Clients for the Groovy Programming Language.
+
+;;; Code:
+
+(require 'lsp-mode)
+(require 'f)
+
+(defgroup lsp-groovy nil
+ "LSP support for Groovy, using groovy-language-server."
+ :group 'lsp-mode
+ :link '(url-link "https://github.com/prominic/groovy-language-server"))
+
+(defcustom lsp-groovy-server-file (f-join lsp-server-install-dir "groovy-language-server-all.jar")
+ "JAR file path for groovy-language-server-all.jar."
+ :group 'lsp-groovy
+ :risky t
+ :type 'file)
+
+(defun lsp-groovy--lsp-command ()
+ "Generate LSP startup command."
+ `("java" "-jar" ,(expand-file-name lsp-groovy-server-file)))
+
+(defcustom lsp-groovy-classpath ["/usr/local/opt/groovy/libexec/lib"]
+ "List of paths to Groovy JARs."
+ :group 'lsp-groovy
+ :risky t
+ :type 'lsp-string-vector)
+
+(lsp-register-custom-settings
+ '(("groovy.classpath" lsp-groovy-classpath)))
+
+(lsp-register-client
+ (make-lsp-client :new-connection (lsp-stdio-connection 'lsp-groovy--lsp-command)
+ :major-modes '(groovy-mode)
+ :priority -1
+ :server-id 'groovy-ls
+ :initialized-fn (lambda (workspace)
+ (with-lsp-workspace workspace
+ (lsp--set-configuration (lsp-configuration-section "groovy"))))))
+
+(lsp-consistency-check lsp-groovy)
+
+(provide 'lsp-groovy)
+;;; lsp-groovy.el ends here
diff --git a/elpa/lsp-mode-20220505.630/lsp-groovy.elc b/elpa/lsp-mode-20220505.630/lsp-groovy.elc
new file mode 100644
index 0000000..8903ed3
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-groovy.elc
Binary files differ
diff --git a/elpa/lsp-mode-20220505.630/lsp-hack.el b/elpa/lsp-mode-20220505.630/lsp-hack.el
new file mode 100644
index 0000000..161659a
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-hack.el
@@ -0,0 +1,54 @@
+;;; lsp-xxx.el --- description -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2020 emacs-lsp maintainers
+
+;; Author: emacs-lsp maintainers
+;; Keywords: lsp, hack
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; LSP Clients for the Hack Programming Language.
+
+;;; Code:
+
+(require 'lsp-mode)
+
+(defgroup lsp-hack nil
+ "LSP support for Hack, using HHVM."
+ :group 'lsp-mode
+ :link '(url-link "https://docs.hhvm.com/hhvm"))
+
+(defcustom lsp-clients-hack-command '("hh_client" "lsp" "--from" "emacs")
+ "Command to start hh_client."
+ :group 'lsp-hack
+ :risky t
+ :type '(repeat string))
+
+(lsp-register-client
+ (make-lsp-client :new-connection (lsp-stdio-connection (lambda () lsp-clients-hack-command))
+ :major-modes '(hack-mode)
+ :priority -1
+ :server-id 'hack
+ ;; ignore some unsupported messages from Nuclide
+ :notification-handlers (lsp-ht ("telemetry/event" 'ignore)
+ ("$/cancelRequest" 'ignore))
+ :request-handlers (lsp-ht ("window/showStatus" 'ignore))))
+
+
+(lsp-consistency-check lsp-hack)
+
+(provide 'lsp-hack)
+;;; lsp-hack.el ends here
diff --git a/elpa/lsp-mode-20220505.630/lsp-hack.elc b/elpa/lsp-mode-20220505.630/lsp-hack.elc
new file mode 100644
index 0000000..8070f0e
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-hack.elc
Binary files differ
diff --git a/elpa/lsp-mode-20220505.630/lsp-haxe.el b/elpa/lsp-mode-20220505.630/lsp-haxe.el
new file mode 100644
index 0000000..62707be
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-haxe.el
@@ -0,0 +1,226 @@
+;;; lsp-haxe.el --- Haxe Client settings -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2019 Yannik Böttcher
+
+;; Author: Yannik Böttcher <yannikboettcher@outlook.de>
+;; Keywords:
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; lsp-haxe client
+
+;;; Code:
+
+
+;; adapted from lsp-clangd configuration
+(require 'lsp-protocol)
+(require 'lsp-mode)
+
+(defgroup lsp-haxe nil
+ "LSP support for Haxe using the language server provided by vshaxe"
+ :group 'lsp-mode
+ :link '(url-link "https://github.com/vshaxe/vshaxe"))
+
+
+;; Haxe ls is executed via node
+(defcustom lsp-clients--haxe-executable "node"
+ "Haxe ls is executed via node."
+ :group 'lsp-haxe
+ :risky t
+ :type 'file)
+
+;; The server.js is being passed to node as an argument
+(defcustom lsp-clients--haxe-server-path (expand-file-name "~/.haxe-language-server/bin/server.js")
+ "The path to the server.js file."
+ :group 'lsp-haxe
+ :risky t
+ :type 'file)
+
+;; Build the actual Haxe ls command.
+(defun lsp-clients--haxe-command ()
+ "Haxe ls startup command."
+ `(,lsp-clients--haxe-executable ,lsp-clients--haxe-server-path))
+
+;; https://github.com/yyoncho/lsp-mode/commit/72186e1adc089d772c87ed8f287eb3333b66bfa7
+;; This is to force the client to send a didChangeConfiguration Message. Without this, the server won't start, https://github.com/vshaxe/vshaxe/issues/328#issuecomment-471809093
+(defcustom lsp-clients--haxe-settings (list :haxe.executable "haxe")
+ "Lsp clients configuration settings."
+ :group 'lsp-haxe
+ :risky t
+ :type '(repeat string))
+
+;; The build spec for the project.
+(defcustom lsp-haxe-hxml "build.hxml"
+ "The compile file for the haxe project."
+ :type 'file
+ :group 'lsp-haxe
+ :package-version '(lsp-mode . "7.0"))
+
+;; https://github.com/emacs-lsp/lsp-mode/blob/150a933694349df960dc8fd7a15e04f5727e6433/lsp-rust.el#L251
+(lsp-defun lsp-clients--haxe-processStart (_workspace (&haxe:ProcessStartNotification :title))
+ "Handle processStart notification. Just logs PARAMS."
+ (lsp-log title))
+
+(defcustom lsp-haxe-executable "haxe"
+ nil
+ :type 'file
+ :group 'lsp-haxe)
+
+(defcustom lsp-haxe-configurations nil
+ nil
+ :type '(repeat string)
+ :group 'lsp-haxe)
+
+(defcustom lsp-haxe-display-configurations nil
+ nil
+ :type '(repeat string)
+ :group 'lsp-haxe)
+
+(defcustom lsp-haxe-display-server nil
+ nil
+ :type 'string
+ :group 'lsp-haxe)
+
+(defcustom lsp-haxe-display-port "auto"
+ nil
+ :type 'number
+ :group 'lsp-haxe)
+
+(defcustom lsp-haxe-enable-compilation-server t
+ nil
+ :type 'boolean
+ :group 'lsp-haxe)
+
+(defcustom lsp-haxe-task-presentation
+ '((echo . t)
+ (reveal . "always")
+ (focus . :json-false)
+ (panel . "shared")
+ (showReuseMessage . t)
+ (clear . :json-false))
+ nil
+ :type 'plist
+ :group 'lsp-haxe)
+
+(defcustom lsp-haxe-enable-code-lens t
+ nil
+ :type 'boolean
+ :group 'lsp-haxe)
+
+(defcustom lsp-haxe-enable-diagnostics t
+ nil
+ :type 'boolean
+ :group 'lsp-haxe)
+
+(defcustom lsp-haxe-enable-server-view nil
+ nil
+ :type 'boolean
+ :group 'lsp-haxe)
+
+(defcustom lsp-haxe-enable-methods-view nil
+ nil
+ :type 'boolean
+ :group 'lsp-haxe)
+
+(defcustom lsp-haxe-enable-signature-help-documentation t
+ nil
+ :type 'boolean
+ :group 'lsp-haxe)
+
+(defcustom lsp-haxe-diagnostics-path-filter "${workspaceRoot}"
+ nil
+ :type 'string
+ :group 'lsp-haxe)
+
+(defcustom lsp-haxe-build-completion-cache t
+ nil
+ :type 'boolean
+ :group 'lsp-haxe)
+
+(defcustom lsp-haxe-enable-completion-cache-warning t
+ nil
+ :type 'boolean
+ :group 'lsp-haxe)
+
+(defcustom lsp-haxe-code-generation nil
+ nil
+ :type 'string
+ :group 'lsp-haxe)
+
+(defcustom lsp-haxe-exclude ["zpp_nape"]
+ nil
+ :type '(repeat string)
+ :group 'lsp-haxe)
+
+(defcustom lsp-haxe-postfix-completion nil
+ nil
+ :type 'string
+ :group 'lsp-haxe)
+
+(lsp-register-custom-settings
+ '(("haxe.hxml" lsp-haxe-hxml)
+ ("haxe.postfixCompletion" lsp-haxe-postfix-completion)
+ ("haxe.exclude" lsp-haxe-exclude)
+ ("haxe.codeGeneration" lsp-haxe-code-generation)
+ ("haxe.enableCompletionCacheWarning" lsp-haxe-enable-completion-cache-warning t)
+ ("haxe.buildCompletionCache" lsp-haxe-build-completion-cache t)
+ ("haxe.diagnosticsPathFilter" lsp-haxe-diagnostics-path-filter)
+ ("haxe.enableSignatureHelpDocumentation" lsp-haxe-enable-signature-help-documentation t)
+ ("haxe.enableMethodsView" lsp-haxe-enable-methods-view t)
+ ("haxe.enableServerView" lsp-haxe-enable-server-view t)
+ ("haxe.enableDiagnostics" lsp-haxe-enable-diagnostics t)
+ ("haxe.enableCodeLens" lsp-haxe-enable-code-lens t)
+ ("haxe.taskPresentation" lsp-haxe-task-presentation)
+ ("haxe.enableCompilationServer" lsp-haxe-enable-compilation-server t)
+ ("haxe.displayPort" lsp-haxe-display-port)
+ ("haxe.displayServer" lsp-haxe-display-server)
+ ("haxe.displayConfigurations" lsp-haxe-display-configurations)
+ ("haxe.configurations" lsp-haxe-configurations)
+ ("haxe.executable" lsp-haxe-executable)))
+
+(lsp-register-client
+ (make-lsp-client
+ :new-connection (lsp-stdio-connection #'lsp-clients--haxe-command)
+ :major-modes '(haxe-mode) ; force didChangeConfiguration message
+ :initialized-fn
+ (lambda (workspace)
+ (with-lsp-workspace workspace
+ (lsp--set-configuration (lsp-configuration-section "haxe"))))
+ :priority -1
+ :server-id 'haxe
+ :initialization-options
+ (lambda ()
+ `(:sendMethodResults t
+ :haxelibConfig (:executable "haxelib")
+ :displayServerConfig
+ ( :print (:reusing :json-false :completion :json-false)
+ :arguments []
+ :env nil
+ :path "haxe")
+ :displayArguments [,lsp-haxe-hxml]))
+ :notification-handlers
+ (lsp-ht ("haxe/progressStart" 'lsp-clients--haxe-processStart)
+ ("haxe/progressStop" 'ignore)
+ ("haxe/didDetectOldPreview" 'ignore)
+ ("haxe/didChangeDisplayPort" 'ignore)
+ ("haxe/didRunHaxeMethod" 'ignore)
+ ("haxe/didChangeRequestQueue" 'ignore)
+ ("haxe/cacheBuildFailed" 'ignore))))
+
+(lsp-consistency-check lsp-haxe)
+
+(provide 'lsp-haxe)
+;;; lsp-haxe.el ends here
diff --git a/elpa/lsp-mode-20220505.630/lsp-haxe.elc b/elpa/lsp-mode-20220505.630/lsp-haxe.elc
new file mode 100644
index 0000000..edfccc0
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-haxe.elc
Binary files differ
diff --git a/elpa/lsp-mode-20220505.630/lsp-headerline.el b/elpa/lsp-mode-20220505.630/lsp-headerline.el
new file mode 100644
index 0000000..7d42654
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-headerline.el
@@ -0,0 +1,478 @@
+;;; lsp-headerline.el --- LSP headerline features -*- lexical-binding: t; -*-
+;;
+;; Copyright (C) 2020 emacs-lsp maintainers
+;;
+;; 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 <https://www.gnu.org/licenses/>.
+;;
+;;; Commentary:
+;;
+;; LSP headerline features
+;;
+;;; Code:
+
+(require 'lsp-icons)
+(require 'lsp-mode)
+
+(defgroup lsp-headerline nil
+ "LSP support for headerline"
+ :prefix "lsp-headerline-"
+ :group 'lsp-mode
+ :tag "LSP Headerline")
+
+(defcustom lsp-headerline-breadcrumb-segments '(path-up-to-project file symbols)
+ "Segments used in breadcrumb text on headerline."
+ :type '(repeat
+ (choice (const :tag "Include the project name." project)
+ (const :tag "Include the open file name." file)
+ (const :tag "Include the directories up to project." path-up-to-project)
+ (const :tag "Include document symbols if server supports it." symbols)))
+ :group 'lsp-headerline)
+
+(defcustom lsp-headerline-breadcrumb-enable-symbol-numbers nil
+ "Whether to label symbols with numbers on the breadcrumb."
+ :type 'boolean
+ :group 'lsp-headerline)
+
+(defcustom lsp-headerline-breadcrumb-enable-diagnostics t
+ "If non-nil, apply different face on the breadcrumb based on the errors."
+ :type 'boolean
+ :group 'lsp-headerline
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defface lsp-headerline-breadcrumb-separator-face '((t :inherit shadow :height 0.8))
+ "Face used for breadcrumb separator on headerline."
+ :group 'lsp-headerline)
+
+(defface lsp-headerline-breadcrumb-path-face '((t :inherit font-lock-string-face))
+ "Face used for breadcrumb paths on headerline."
+ :group 'lsp-headerline)
+
+(defface lsp-headerline-breadcrumb-path-error-face
+ '((t :underline (:style wave :color "Red1")
+ :inherit lsp-headerline-breadcrumb-path-face))
+ "Face used for breadcrumb paths on headerline when there is an error under that path"
+ :group 'lsp-headerline)
+
+(defface lsp-headerline-breadcrumb-path-warning-face
+ '((t :underline (:style wave :color "Yellow")
+ :inherit lsp-headerline-breadcrumb-path-face))
+ "Face used for breadcrumb paths on headerline when there is an warning under that path"
+ :group 'lsp-headerline)
+
+(defface lsp-headerline-breadcrumb-path-info-face
+ '((t :underline (:style wave :color "Green")
+ :inherit lsp-headerline-breadcrumb-path-face))
+ "Face used for breadcrumb paths on headerline when there is an info under that path"
+ :group 'lsp-headerline)
+
+(defface lsp-headerline-breadcrumb-path-hint-face
+ '((t :underline (:style wave :color "Green")
+ :inherit lsp-headerline-breadcrumb-path-face))
+ "Face used for breadcrumb paths on headerline when there is an hint under that path"
+ :group 'lsp-headerline)
+
+(defface lsp-headerline-breadcrumb-project-prefix-face
+ '((t :inherit font-lock-string-face :weight bold))
+ "Face used for breadcrumb prefix on headerline.
+Only if `lsp-headerline-breadcrumb-prefix` is `project-name-only`."
+ :group 'lsp-headerline)
+
+(defface lsp-headerline-breadcrumb-unknown-project-prefix-face
+ '((t :inherit shadow :weight bold))
+ "Face used for breadcrumb prefix on headerline.
+Only if `lsp-headerline-breadcrumb-prefix` is `project-name-only`."
+ :group 'lsp-headerline)
+
+(defface lsp-headerline-breadcrumb-symbols-face
+ '((t :inherit font-lock-doc-face :weight bold))
+ "Face used for breadcrumb symbols text on headerline."
+ :group 'lsp-headerline)
+
+(defface lsp-headerline-breadcrumb-symbols-error-face
+ '((t :inherit lsp-headerline-breadcrumb-symbols-face
+ :underline (:style wave :color "Red1")))
+ "Face used for breadcrumb symbols text on headerline when there
+is an error in symbols range."
+ :group 'lsp-headerline)
+
+(defface lsp-headerline-breadcrumb-symbols-warning-face
+ '((t :inherit lsp-headerline-breadcrumb-symbols-face
+ :underline (:style wave :color "Yellow")))
+ "Face used for breadcrumb symbols text on headerline when there
+is an warning in symbols range."
+ :group 'lsp-headerline)
+
+(defface lsp-headerline-breadcrumb-symbols-info-face
+ '((t :inherit lsp-headerline-breadcrumb-symbols-face
+ :underline (:style wave :color "Green")))
+ "Face used for breadcrumb symbols text on headerline when there
+is an info in symbols range."
+ :group 'lsp-headerline)
+
+(defface lsp-headerline-breadcrumb-symbols-hint-face
+ '((t :inherit lsp-headerline-breadcrumb-symbols-face
+ :underline (:style wave :color "Green")))
+ "Face used for breadcrumb symbols text on headerline when there
+is an hints in symbols range."
+ :group 'lsp-headerline)
+
+(defface lsp-headerline-breadcrumb-deprecated-face
+ '((t :inherit lsp-headerline-breadcrumb-symbols-face
+ :strike-through t))
+ "Face used on breadcrumb deprecated text on modeline."
+ :group 'lsp-headerline)
+
+(defvar-local lsp-headerline--string nil
+ "Holds the current breadcrumb string on headerline.")
+
+(defvar lsp-headerline-arrow nil
+ "Holds the current breadcrumb string on headerline.")
+
+(defvar-local lsp-headerline--path-up-to-project-segments nil
+ "Holds the current breadcrumb path-up-to-project segments for
+caching purposes.")
+
+(defun lsp-headerline--arrow-icon ()
+ "Build the arrow icon for headerline breadcrumb."
+ (or
+ lsp-headerline-arrow
+ (setq lsp-headerline-arrow (lsp-icons-all-the-icons-material-icon
+ "chevron_right"
+ 'lsp-headerline-breadcrumb-separator-face
+ ">"
+ 'headerline-breadcrumb))))
+
+(lsp-defun lsp-headerline--symbol-icon ((&DocumentSymbol :kind))
+ "Build the SYMBOL icon for headerline breadcrumb."
+ (concat (lsp-icons-get-by-symbol-kind kind 'headerline-breadcrumb)
+ " "))
+
+(lsp-defun lsp-headerline--go-to-symbol ((&DocumentSymbol
+ :selection-range (&RangeToPoint :start selection-start)
+ :range (&RangeToPoint :start narrowing-start
+ :end narrowing-end)))
+ "Go to breadcrumb symbol.
+If the buffer is narrowed and the target symbol lies before the
+minimum reachable point in the narrowed buffer, then widen and
+narrow to the outer symbol."
+ (when (buffer-narrowed-p)
+ (narrow-to-region
+ (min (point-min) narrowing-start)
+ (max (point-max) narrowing-end)))
+ (goto-char selection-start))
+
+(lsp-defun lsp-headerline--narrow-to-symbol ((&DocumentSymbol :range (&RangeToPoint :start :end)))
+ "Narrow to breadcrumb symbol range."
+ (narrow-to-region start end))
+
+(defun lsp-headerline--with-action (local-map help-echo-string display-string)
+ "Assign LOCAL-MAP and HELP-ECHO-STRING to the region around the DISPLAY-STRING."
+ (propertize display-string
+ 'mouse-face 'header-line-highlight
+ 'help-echo help-echo-string
+ 'local-map local-map))
+
+(defmacro lsp-headerline--make-mouse-handler (&rest body)
+ "Making mouse event handler.
+Switch to current mouse interacting window before doing BODY."
+ (declare (debug t) (indent 0))
+ `(lambda (event)
+ (interactive "e")
+ (select-window (posn-window (elt event 1)))
+ ,@body))
+
+(defun lsp-headerline--directory-with-action (full-path directory-display-string)
+ "Build action for FULL-PATH and DIRECTORY-DISPLAY-STRING."
+ (lsp-headerline--with-action (let ((map (make-sparse-keymap)))
+ (define-key map [header-line mouse-1]
+ (lsp-headerline--make-mouse-handler
+ (dired full-path)))
+ (define-key map [header-line mouse-2]
+ (lsp-headerline--make-mouse-handler
+ (dired-other-window full-path)))
+ map)
+ (format "mouse-1: browse '%s' with Dired\nmouse-2: browse '%s' with Dired in other window"
+ directory-display-string
+ directory-display-string)
+ (propertize directory-display-string
+ 'lsp-full-path full-path)))
+
+(declare-function evil-set-jump "ext:evil-jumps")
+
+(lsp-defun lsp-headerline--symbol-with-action ((symbol &as &DocumentSymbol :name) symbol-display-string)
+ "Build action for SYMBOL and SYMBOL-STRING."
+ (lsp-headerline--with-action (let ((map (make-sparse-keymap)))
+ (define-key map [header-line mouse-1]
+ (lsp-headerline--make-mouse-handler
+ (when (bound-and-true-p evil-mode)
+ (evil-set-jump))
+ (lsp-headerline--go-to-symbol symbol)))
+ (define-key map [header-line mouse-2]
+ (lsp-headerline--make-mouse-handler
+ (-let (((&DocumentSymbol :range (&RangeToPoint :start :end)) symbol))
+ (if (and (eq (point-min) start) (eq (point-max) end))
+ (widen)
+ (lsp-headerline--narrow-to-symbol symbol)))))
+ map)
+ (format "mouse-1: go to '%s' symbol\nmouse-2: %s"
+ name
+ (-let (((&DocumentSymbol :range (&RangeToPoint :start :end)) symbol))
+ (if (and (eq (point-min) start) (eq (point-max) end))
+ "widen"
+ (format "narrow to '%s' range" name))))
+ symbol-display-string))
+
+(defun lsp-headerline--path-up-to-project-root (root-path path)
+ "Find recursively the folders until the project ROOT-PATH.
+PATH is the current folder to be checked."
+ (let ((current-path path)
+ headerline-path-components)
+ (while (not (lsp-f-same? root-path current-path))
+ (push (lsp-headerline--directory-with-action current-path
+ (f-filename current-path))
+ headerline-path-components)
+ (setq current-path (lsp-f-parent current-path)))
+ headerline-path-components))
+
+(defun lsp-headerline--build-project-string ()
+ "Build the project-segment string for the breadcrumb."
+ (-if-let (root (lsp-workspace-root))
+ (propertize (lsp-headerline--directory-with-action
+ root
+ (f-filename root))
+ 'font-lock-face
+ 'lsp-headerline-breadcrumb-project-prefix-face)
+ (propertize "<unknown>"
+ 'font-lock-face
+ 'lsp-headerline-breadcrumb-unknown-project-prefix-face)))
+
+(defun lsp-headerline--build-file-string ()
+ "Build the file-segment string for the breadcrumb."
+ (let* ((file-path (or (buffer-file-name) ""))
+ (filename (f-filename file-path)))
+ (if-let ((file-ext (f-ext file-path)))
+ (concat (lsp-icons-get-by-file-ext file-ext 'headerline-breadcrumb)
+ " "
+ (propertize filename
+ 'font-lock-face
+ (lsp-headerline--face-for-path file-path)))
+ filename)))
+
+
+(defun lsp-headerline--face-for-path (dir)
+ "Calculate the face for DIR."
+ (if-let ((diags (lsp-diagnostics-stats-for (directory-file-name dir))))
+ (cl-labels ((check-severity
+ (severity)
+ (not (zerop (aref diags severity)))))
+ (cond
+ ((not lsp-headerline-breadcrumb-enable-diagnostics)
+ 'lsp-headerline-breadcrumb-path-face)
+ ((check-severity lsp/diagnostic-severity-error)
+ 'lsp-headerline-breadcrumb-path-error-face)
+ ((check-severity lsp/diagnostic-severity-warning)
+ 'lsp-headerline-breadcrumb-path-warning-face)
+ ((check-severity lsp/diagnostic-severity-information)
+ 'lsp-headerline-breadcrumb-path-info-face)
+ ((check-severity lsp/diagnostic-severity-hint)
+ 'lsp-headerline-breadcrumb-path-hint-face)
+ (t 'lsp-headerline-breadcrumb-path-face)))
+ 'lsp-headerline-breadcrumb-path-face))
+
+(defun lsp-headerline--severity-level-for-range (range)
+ "Get the severiy level for RANGE."
+ (let ((range-severity 10))
+ (mapc (-lambda ((&Diagnostic :range (&Range :start) :severity?))
+ (when (lsp-point-in-range? start range)
+ (setq range-severity (min range-severity severity?))))
+ (lsp--get-buffer-diagnostics))
+ range-severity))
+
+(defun lsp-headerline--build-path-up-to-project-string ()
+ "Build the path-up-to-project segment for the breadcrumb."
+ (if-let ((root (lsp-workspace-root)))
+ (let ((segments (or
+ lsp-headerline--path-up-to-project-segments
+ (setq lsp-headerline--path-up-to-project-segments
+ (lsp-headerline--path-up-to-project-root
+ root
+ (lsp-f-parent (buffer-file-name)))))))
+ (mapconcat (lambda (next-dir)
+ (propertize next-dir
+ 'font-lock-face
+ (lsp-headerline--face-for-path
+ (get-text-property
+ 0 'lsp-full-path next-dir))))
+ segments
+ (concat " " (lsp-headerline--arrow-icon) " ")))
+ ""))
+
+(lsp-defun lsp-headerline--face-for-symbol ((&DocumentSymbol :deprecated?
+ :range))
+ "Get the face for SYMBOL."
+ (let ((range-severity (lsp-headerline--severity-level-for-range range)))
+ (cond
+ (deprecated? 'lsp-headerline-breadcrumb-deprecated-face)
+ ((not lsp-headerline-breadcrumb-enable-diagnostics)
+ 'lsp-headerline-breadcrumb-symbols-face)
+ ((= range-severity lsp/diagnostic-severity-error)
+ 'lsp-headerline-breadcrumb-symbols-error-face)
+ ((= range-severity lsp/diagnostic-severity-warning)
+ 'lsp-headerline-breadcrumb-symbols-warning-face)
+ ((= range-severity lsp/diagnostic-severity-information)
+ 'lsp-headerline-breadcrumb-symbols-info-face)
+ ((= range-severity lsp/diagnostic-severity-hint)
+ 'lsp-headerline-breadcrumb-symbols-hint-face)
+ (t 'lsp-headerline-breadcrumb-symbols-face))))
+
+(defun lsp-headerline--build-symbol-string ()
+ "Build the symbol segment for the breadcrumb."
+ (if (lsp-feature? "textDocument/documentSymbol")
+ (-if-let* ((lsp--document-symbols-request-async t)
+ (symbols (lsp--get-document-symbols))
+ (symbols-hierarchy (lsp--symbols->document-symbols-hierarchy symbols))
+ (enumerated-symbols-hierarchy
+ (-map-indexed (lambda (index elt)
+ (cons elt (1+ index)))
+ symbols-hierarchy)))
+ (mapconcat
+ (-lambda (((symbol &as &DocumentSymbol :name)
+ . index))
+ (let* ((symbol2-name
+ (propertize name
+ 'font-lock-face
+ (lsp-headerline--face-for-symbol symbol)))
+ (symbol2-icon (lsp-headerline--symbol-icon symbol))
+ (full-symbol-2
+ (concat
+ (if lsp-headerline-breadcrumb-enable-symbol-numbers
+ (concat
+ (propertize (number-to-string index)
+ 'face
+ 'lsp-headerline-breadcrumb-symbols-face)
+ " ")
+ "")
+ (if symbol2-icon
+ (concat symbol2-icon symbol2-name)
+ symbol2-name))))
+ (lsp-headerline--symbol-with-action symbol full-symbol-2)))
+ enumerated-symbols-hierarchy
+ (concat " " (lsp-headerline--arrow-icon) " "))
+ "")
+ ""))
+
+(defun lsp-headerline--build-string ()
+ "Build the header-line string."
+ (string-trim-right
+ (mapconcat
+ (lambda (segment)
+ (let ((segment-string
+ (pcase segment
+ ('project (lsp-headerline--build-project-string))
+ ('file (lsp-headerline--build-file-string))
+ ('path-up-to-project (lsp-headerline--build-path-up-to-project-string))
+ ('symbols (lsp-headerline--build-symbol-string))
+ (_ (lsp-log "'%s' is not a valid entry for `lsp-headerline-breadcrumb-segments'"
+ (symbol-name segment))
+ ""))))
+ (if (eq segment-string "")
+ ""
+ (concat (lsp-headerline--arrow-icon)
+ " "
+ segment-string
+ " "))))
+ lsp-headerline-breadcrumb-segments
+ "")))
+
+(defun lsp-headerline--check-breadcrumb (&rest _)
+ "Request for document symbols to build the breadcrumb."
+ (setq lsp-headerline--string (lsp-headerline--build-string))
+ (force-mode-line-update))
+
+(defun lsp-headerline--enable-breadcrumb ()
+ "Enable headerline breadcrumb mode."
+ (when (and lsp-headerline-breadcrumb-enable
+ (lsp-feature? "textDocument/documentSymbol"))
+ (lsp-headerline-breadcrumb-mode 1)))
+
+(defun lsp-headerline--disable-breadcrumb ()
+ "Disable headerline breadcrumb mode."
+ (lsp-headerline-breadcrumb-mode -1))
+
+;;;###autoload
+(define-minor-mode lsp-headerline-breadcrumb-mode
+ "Toggle breadcrumb on headerline."
+ :group 'lsp-headerline
+ :global nil
+ (cond
+ (lsp-headerline-breadcrumb-mode
+ ;; make sure header-line-format, if non-nil, is a list. as
+ ;; mode-line-format says: "The value may be nil, a string, a
+ ;; symbol or a list."
+ (unless (listp header-line-format)
+ (setq header-line-format (list header-line-format)))
+ (add-to-list 'header-line-format '(t (:eval lsp-headerline--string)))
+
+ (add-hook 'xref-after-jump-hook #'lsp-headerline--check-breadcrumb nil t)
+
+ (add-hook 'lsp-on-idle-hook #'lsp-headerline--check-breadcrumb nil t)
+ (add-hook 'lsp-configure-hook #'lsp-headerline--enable-breadcrumb nil t)
+ (add-hook 'lsp-unconfigure-hook #'lsp-headerline--disable-breadcrumb nil t))
+ (t
+ (remove-hook 'lsp-on-idle-hook #'lsp-headerline--check-breadcrumb t)
+ (remove-hook 'lsp-configure-hook #'lsp-headerline--enable-breadcrumb t)
+ (remove-hook 'lsp-unconfigure-hook #'lsp-headerline--disable-breadcrumb t)
+
+ (remove-hook 'xref-after-jump-hook #'lsp-headerline--check-breadcrumb t)
+
+ (setq lsp-headerline--path-up-to-project-segments nil)
+ (setq header-line-format (remove '(t (:eval lsp-headerline--string)) header-line-format)))))
+
+;;;###autoload
+(defun lsp-breadcrumb-go-to-symbol (symbol-position)
+ "Go to the symbol on breadcrumb at SYMBOL-POSITION."
+ (interactive "P")
+ (if (numberp symbol-position)
+ (if (lsp-feature? "textDocument/documentSymbol")
+ (-if-let* ((lsp--document-symbols-request-async t)
+ (symbols (lsp--get-document-symbols))
+ (symbols-hierarchy (lsp--symbols->document-symbols-hierarchy symbols)))
+ (lsp-headerline--go-to-symbol (nth (1- symbol-position) symbols-hierarchy))
+ (lsp--info "Symbol not found for position %s" symbol-position))
+ (lsp--info "Server does not support breadcrumb."))
+ (lsp--info "Call this function with a number representing the symbol position on breadcrumb")))
+
+(declare-function evil-set-command-property "ext:evil-common")
+
+(with-eval-after-load 'evil
+ (evil-set-command-property 'lsp-breadcrumb-go-to-symbol :jump t))
+
+;;;###autoload
+(defun lsp-breadcrumb-narrow-to-symbol (symbol-position)
+ "Narrow to the symbol range on breadcrumb at SYMBOL-POSITION."
+ (interactive "P")
+ (if (numberp symbol-position)
+ (if (lsp-feature? "textDocument/documentSymbol")
+ (-if-let* ((lsp--document-symbols-request-async t)
+ (symbols (lsp--get-document-symbols))
+ (symbols-hierarchy (lsp--symbols->document-symbols-hierarchy symbols)))
+ (lsp-headerline--narrow-to-symbol (nth (1- symbol-position) symbols-hierarchy))
+ (lsp--info "Symbol not found for position %s" symbol-position))
+ (lsp--info "Server does not support breadcrumb."))
+ (lsp--info "Call this function with a number representing the symbol position on breadcrumb")))
+
+(lsp-consistency-check lsp-headerline)
+
+(provide 'lsp-headerline)
+;;; lsp-headerline.el ends here
diff --git a/elpa/lsp-mode-20220505.630/lsp-headerline.elc b/elpa/lsp-mode-20220505.630/lsp-headerline.elc
new file mode 100644
index 0000000..7bef254
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-headerline.elc
Binary files differ
diff --git a/elpa/lsp-mode-20220505.630/lsp-html.el b/elpa/lsp-mode-20220505.630/lsp-html.el
new file mode 100644
index 0000000..00b526a
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-html.el
@@ -0,0 +1,200 @@
+;;; lsp-html.el --- vscode-html-languageserver configuration -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2019 Vibhav Pant
+
+;; Author: Vibhav Pant <vibhavp@gmail.com>
+;; Keywords:
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;; Code:
+
+(require 'lsp-mode)
+
+(defgroup lsp-html nil
+ "LSP support for HTML, using vscode's built-in language server."
+ :group 'lsp-mode
+ :link '(url-link "https://github.com/microsoft/vscode/tree/main/extensions/html-language-features/server")
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-html-experimental-custom-data nil
+ "A list of JSON file paths that define custom tags, properties and other HTML
+syntax constructs. Only workspace folder setting will be read."
+ :type '(choice (const nil) string)
+ :group 'lsp-html
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-html-format-enable t
+ "Enable/disable default HTML formatter."
+ :type 'boolean
+ :group 'lsp-html
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-html-format-wrap-line-length 120
+ "Maximum amount of characters per line (0 = disable)."
+ :type 'number
+ :group 'lsp-html
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-html-format-unformatted "wbr"
+ nil
+ :type '(choice (const nil) string)
+ :group 'lsp-html
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-html-format-content-unformatted "pre,code,textarea"
+ nil
+ :group 'lsp-html
+ :type '(choice (const nil) string)
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-html-format-indent-inner-html nil
+ nil
+ :type 'boolean
+ :group 'lsp-html
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-html-format-preserve-new-lines t
+ "Controls whether existing line breaks before elements should be preserved.
+Only works before elements, not inside tags or for text."
+ :type 'boolean
+ :group 'lsp-html
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-html-format-max-preserve-new-lines nil
+ nil
+ :type '(choice (const nil) integer)
+ :group 'lsp-html
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-html-format-indent-handlebars nil nil
+ :type 'boolean
+ :group 'lsp-html
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-html-format-end-with-newline nil
+ "End with a newline."
+ :type 'boolean
+ :group 'lsp-html
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-html-format-extra-liners "head, body, /html"
+ nil
+ :type '(choice (const nil) string)
+ :group 'lsp-html
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-html-format-wrap-attributes "auto"
+ "Wrap attributes."
+ :type '(choice
+ (const "auto")
+ (const "force")
+ (const "force-aligned")
+ (const "force-expand-multiline")
+ (const "aligned-multiple")
+ (const "preserve")
+ (const "preserve-aligned"))
+ :group 'lsp-html
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-html-suggest-html5 t
+ "Controls whether the built-in HTML language support suggests HTML5 tags,
+properties and values."
+ :type 'boolean
+ :group 'lsp-html
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-html-validate-scripts t
+ "Controls whether the built-in HTML language support validates embedded
+scripts."
+ :type 'boolean
+ :group 'lsp-html
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-html-validate-styles t
+ "Controls whether the built-in HTML language support validates embedded
+styles."
+ :type 'boolean
+ :group 'lsp-html
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-html-auto-closing-tags t
+ "Enable/disable autoclosing of HTML tags."
+ :type 'boolean
+ :group 'lsp-html
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-html-trace-server "off"
+ "Traces the communication between VS Code and the HTML language server."
+ :type '(choice
+ (const "off")
+ (const "messages")
+ (const "verbose"))
+ :group 'lsp-html
+ :package-version '(lsp-mode . "6.1"))
+
+(lsp-register-custom-settings
+ '(("html.trace.server" lsp-html-trace-server)
+ ("html.autoClosingTags" lsp-html-auto-closing-tags t)
+ ("html.validate.styles" lsp-html-validate-styles t)
+ ("html.validate.scripts" lsp-html-validate-scripts t)
+ ("html.suggest.html5" lsp-html-suggest-html5 t)
+ ("html.format.wrapAttributes" lsp-html-format-wrap-attributes)
+ ("html.format.extraLiners" lsp-html-format-extra-liners)
+ ("html.format.endWithNewline" lsp-html-format-end-with-newline t)
+ ("html.format.indentHandlebars" lsp-html-format-indent-handlebars t)
+ ("html.format.maxPreserveNewLines" lsp-html-format-max-preserve-new-lines)
+ ("html.format.preserveNewLines" lsp-html-format-preserve-new-lines t)
+ ("html.format.indentInnerHtml" lsp-html-format-indent-inner-html t)
+ ("html.format.contentUnformatted" lsp-html-format-content-unformatted)
+ ("html.format.unformatted" lsp-html-format-unformatted)
+ ("html.format.wrapLineLength" lsp-html-format-wrap-line-length)
+ ("html.format.enable" lsp-html-format-enable t)
+ ("html.experimental.customData" lsp-html-experimental-custom-data)))
+
+(defcustom lsp-html-server-command-args '("--stdio")
+ "Command to start html-languageserver."
+ :type '(repeat string)
+ :group 'lsp-html
+ :package-version '(lsp-mode . "6.3"))
+
+(lsp-dependency 'html-language-server
+ '(:system "vscode-html-language-server")
+ '(:npm :package "vscode-langservers-extracted"
+ :path "vscode-html-language-server"))
+
+(lsp-register-client
+ (make-lsp-client :new-connection (lsp-stdio-connection
+ (lambda ()
+ (cons (lsp-package-path 'html-language-server)
+ lsp-html-server-command-args)))
+ :activation-fn (lsp-activate-on "html")
+ :priority -4
+ :completion-in-comments? t
+ :server-id 'html-ls
+ :initialized-fn (lambda (w)
+ (with-lsp-workspace w
+ (lsp--set-configuration
+ (lsp-configuration-section "html"))))
+ :download-server-fn (lambda (_client callback error-callback _update?)
+ (lsp-package-ensure
+ 'html-language-server callback
+ error-callback))))
+
+(lsp-consistency-check lsp-html)
+
+(provide 'lsp-html)
+;;; lsp-html.el ends here
diff --git a/elpa/lsp-mode-20220505.630/lsp-html.elc b/elpa/lsp-mode-20220505.630/lsp-html.elc
new file mode 100644
index 0000000..0727608
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-html.elc
Binary files differ
diff --git a/elpa/lsp-mode-20220505.630/lsp-icons.el b/elpa/lsp-mode-20220505.630/lsp-icons.el
new file mode 100644
index 0000000..7bd8bc6
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-icons.el
@@ -0,0 +1,96 @@
+;;; lsp-icons.el --- LSP icons management -*- lexical-binding: t; -*-
+;;
+;; Copyright (C) 2020 emacs-lsp maintainers
+;;
+;; 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 <https://www.gnu.org/licenses/>.
+;;
+;;; Commentary:
+;;
+;; LSP icons management
+;;
+;;; Code:
+(require 'lsp-mode)
+
+(defgroup lsp-icons nil
+ "LSP icons"
+ :group 'lsp-mode
+ :tag "LSP Icons")
+
+(defcustom lsp-headerline-breadcrumb-icons-enable t
+ "If non-nil, icons support is enabled for headerline-breadcrumb."
+ :type 'boolean
+ :group 'lsp-icons)
+
+(declare-function all-the-icons-material "ext:all-the-icons" t t)
+(declare-function lsp-treemacs-symbol-icon "ext:lsp-treemacs" (kind))
+(declare-function lsp-treemacs-get-icon "ext:lsp-treemacs" (icon-name))
+
+(defun lsp-icons--enabled-for-feature (feature)
+ "Check if icons support is enabled for FEATURE."
+ (cond
+ ((eq feature 'headerline-breadcrumb) lsp-headerline-breadcrumb-icons-enable)
+ (t t)))
+
+(defun lsp-icons--fix-image-background (image)
+ "Fix IMAGE background if it is a file otherwise return as an icon."
+ (if image
+ (let ((display-image (get-text-property 0 'display image)))
+ (if (and (listp display-image)
+ (plist-member (cl-copy-list (cl-rest display-image)) :type))
+ (propertize " " 'display
+ (cl-list* 'image
+ (plist-put
+ (cl-copy-list
+ (cl-rest display-image))
+ :background (face-attribute 'header-line :background nil t))))
+ (if (stringp display-image)
+ (replace-regexp-in-string "\s\\|\t" "" display-image)
+ (replace-regexp-in-string "\s\\|\t" "" image))))
+ ""))
+
+(defun lsp-icons-get-by-file-ext (file-ext &optional feature)
+ "Get an icon by file FILE-EXT.
+FEATURE is the feature that will use the icon which we should check
+if its enabled."
+ (when (and file-ext
+ (lsp-icons--enabled-for-feature feature)
+ (functionp 'lsp-treemacs-get-icon))
+ (lsp-icons--fix-image-background
+ (lsp-treemacs-get-icon file-ext))))
+
+(defun lsp-icons-get-by-symbol-kind (kind &optional feature)
+ "Get an icon by symbol KIND.
+FEATURE is the feature that will use the icon which we should check
+if its enabled."
+ (when (and kind
+ (lsp-icons--enabled-for-feature feature)
+ (functionp 'lsp-treemacs-symbol-icon))
+ (lsp-icons--fix-image-background
+ (lsp-treemacs-symbol-icon kind))))
+
+(defun lsp-icons-all-the-icons-material-icon (icon-name face fallback &optional feature)
+ "Get a material icon from all-the-icons by ICON-NAME using FACE.
+Fallback to FALLBACK string if not found or not available.
+FEATURE is the feature that will use the icon which we should check
+if its enabled."
+ (if (and (functionp 'all-the-icons-material)
+ (lsp-icons--enabled-for-feature feature))
+ (all-the-icons-material icon-name
+ :face face)
+ (propertize fallback 'face face)))
+
+(lsp-consistency-check lsp-icons)
+
+(provide 'lsp-icons)
+;;; lsp-icons.el ends here
diff --git a/elpa/lsp-mode-20220505.630/lsp-icons.elc b/elpa/lsp-mode-20220505.630/lsp-icons.elc
new file mode 100644
index 0000000..11e6b95
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-icons.elc
Binary files differ
diff --git a/elpa/lsp-mode-20220505.630/lsp-ido.el b/elpa/lsp-mode-20220505.630/lsp-ido.el
new file mode 100644
index 0000000..ac34dd7
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-ido.el
@@ -0,0 +1,142 @@
+;;; lsp-ido.el --- `ido' integration -*- lexical-binding: t -*-
+;;
+;; Copyright (C) 2021 emacs-lsp maintainers
+;;
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This module provides an interactive ido interface to the workspace symbol
+;; functionality offered by lsp-mode.
+
+;;; Code:
+
+(require 'ido)
+(require 'lsp-protocol)
+(require 'lsp-mode)
+
+(defgroup lsp-ido nil
+ "LSP support for ido-based symbol completion"
+ :group 'lsp-mode
+ :tag "LSP ido")
+
+(defcustom lsp-ido-symbol-kind-to-string
+ [" " ; Unknown - 0
+ "File" ; File - 1
+ "Modu" ; Module - 2
+ "Nmsp" ; Namespace - 3
+ "Pack" ; Package - 4
+ "Clss" ; Class - 5
+ "Meth" ; Method - 6
+ "Prop" ; Property - 7
+ "Fld " ; Field - 8
+ "Cons" ; Constructor - 9
+ "Enum" ; Enum - 10
+ "Intf" ; Interface - 11
+ "Func" ; Function - 12
+ "Var " ; Variable - 13
+ "Cnst" ; Constant - 14
+ "Str " ; String - 15
+ "Num " ; Number - 16
+ "Bool " ; Boolean - 17
+ "Arr " ; Array - 18
+ "Obj " ; Object - 19
+ "Key " ; Key - 20
+ "Null" ; Null - 21
+ "EmMm" ; EnumMember - 22
+ "Srct" ; Struct - 23
+ "Evnt" ; Event - 24
+ "Op " ; Operator - 25
+ "TPar"] ; TypeParameter - 26
+ "A vector of 26 itens representing the SymbolKind."
+ :group 'lsp-ido
+ :type 'vector)
+
+(defcustom lsp-ido-show-symbol-filename
+ t
+ "Whether to show the project-relative path to a symbol's point of definition."
+ :group 'lsp-ido
+ :type 'boolean)
+
+(defcustom lsp-ido-show-symbol-kind
+ t
+ "Whether to show the symbol's kind when showing lsp symbols."
+ :group 'lsp-ido
+ :type 'boolean)
+
+(eval-when-compile
+ (lsp-interface
+ (lsp-ido:FormattedSymbolInformation
+ (:kind :name :location :textualRepresentation)
+ (:containerName :deprecated))))
+
+(lsp-defun lsp-ido--transform-candidate
+ ((symbol-information &as &SymbolInformation :kind :location (&Location :uri))
+ lsp-ido--results project-root)
+ (let* ((sanitized-kind (if (< kind (length lsp-ido-symbol-kind-to-string)) kind 0))
+ (type (elt lsp-ido-symbol-kind-to-string sanitized-kind))
+ (typestr (if lsp-ido-show-symbol-kind
+ (format "[%s] " type)
+ ""))
+ (pathstr (if lsp-ido-show-symbol-filename
+ (propertize (format " . %s" (file-relative-name (lsp--uri-to-path uri) project-root))
+ 'face 'font-lock-comment-face)
+ ""))
+ (textual-representation
+ (lsp-render-symbol-information symbol-information "."))
+ (entry (concat typestr textual-representation pathstr)))
+ (puthash entry symbol-information lsp-ido--results)))
+
+(lsp-defun lsp-ido--jump-selected-candidate
+ ((&SymbolInformation
+ :location (&Location :uri :range (&Range :start (&Position :line :character)))))
+ "Jump to selected candidate."
+ (find-file (lsp--uri-to-path uri))
+ (goto-char (point-min))
+ (forward-line line)
+ (forward-char character))
+
+(defun lsp-ido--workspace-symbol (workspaces query)
+ "Search against WORKSPACES based on QUERY."
+ (let* ((lsp-ido--results (make-hash-table :test 'equal))
+ (workspace-root (lsp-workspace-root))
+ (raw-choices
+ (with-lsp-workspaces workspaces
+ (lsp-request
+ "workspace/symbol"
+ (lsp-make-workspace-symbol-params :query query)))))
+ (mapc (lambda (it)
+ (lsp-ido--transform-candidate it lsp-ido--results workspace-root))
+ raw-choices)
+ lsp-ido--results))
+
+;;;###autoload
+(defun lsp-ido-workspace-symbol (arg)
+ "`ido' for lsp workspace/symbol.
+When called with prefix ARG the default selection will be symbol at point."
+ (interactive "P")
+ (let* ((query (if arg "" (read-string "Workspace symbol: ")))
+ (hash-table-candidates (lsp-ido--workspace-symbol (lsp-workspaces) query))
+ (choice (ido-completing-read
+ "Workspace symbol: "
+ (hash-table-keys hash-table-candidates)
+ nil
+ nil
+ (when arg (thing-at-point 'symbol)))))
+ (lsp-ido--jump-selected-candidate (gethash choice hash-table-candidates))))
+
+(lsp-consistency-check lsp-ido)
+
+(provide 'lsp-ido)
+;;; lsp-ido.el ends here
diff --git a/elpa/lsp-mode-20220505.630/lsp-ido.elc b/elpa/lsp-mode-20220505.630/lsp-ido.elc
new file mode 100644
index 0000000..81a3a01
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-ido.elc
Binary files differ
diff --git a/elpa/lsp-mode-20220505.630/lsp-idris.el b/elpa/lsp-mode-20220505.630/lsp-idris.el
new file mode 100644
index 0000000..f13e501
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-idris.el
@@ -0,0 +1,67 @@
+;;; lsp-idris.el --- Description -*- lexical-binding: t; -*-
+;;
+;; Copyright (C) 2022 skykanin
+;;
+;; Author: skykanin <https://github.com/skykanin>
+;; Keywords: idris lsp
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;; This file is not part of GNU Emacs.
+;;
+;;; Commentary:
+
+;; LSP Client for the Idris2 Programming Language.
+
+;;; Code:
+
+(require 'lsp-mode)
+(require 'lsp-semantic-tokens)
+
+(defgroup lsp-idris nil
+ "LSP support for Idris."
+ :link '(url-link "https://github.com/idris-community/idris2-lsp")
+ :group 'lsp-mode
+ :tag "Lsp Idirs"
+ :package-version '(lsp-mode . "8.0.1"))
+
+(defcustom lsp-idris2-lsp-path "idris2-lsp"
+ "Command to start Idris 2 language server process."
+ :group 'lsp-idris
+ :type 'string
+ :package-version '(lsp-mode . "8.0.1"))
+
+(defcustom lsp-idris2-lsp-trace-server "off"
+ "Traces the communication between VS Code and the language server."
+ :group 'lsp-idris
+ :type '(choice (:tag "off" "messages" "verbose"))
+ :package-version '(lsp-mode . "8.0.1"))
+
+(lsp-register-custom-settings
+ '(("idris2-lsp.trace.server" lsp-idris2-lsp-trace-server)
+ ("idris2-lsp.path" lsp-idris2-lsp-path)))
+
+;; Register the client itself
+(lsp-register-client
+ (make-lsp-client
+ :new-connection (lsp-stdio-connection lsp-idris2-lsp-path)
+ ;; Activate lsp on idris or idris2 buffers
+ :activation-fn (lsp-activate-on "idris" "idris2")
+ ;; This should run under idris-mode and idris2-mode.
+ :major-modes '(idris-mode idris2-mode)
+ :language-id "idris"
+ :server-id 'idris2-lsp))
+
+(provide 'lsp-idris)
+;;; lsp-idris.el ends here
diff --git a/elpa/lsp-mode-20220505.630/lsp-idris.elc b/elpa/lsp-mode-20220505.630/lsp-idris.elc
new file mode 100644
index 0000000..149f92b
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-idris.elc
Binary files differ
diff --git a/elpa/lsp-mode-20220505.630/lsp-iedit.el b/elpa/lsp-mode-20220505.630/lsp-iedit.el
new file mode 100644
index 0000000..55ae0a9
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-iedit.el
@@ -0,0 +1,149 @@
+;;; lsp-iedit.el --- `iedit' integration -*- lexical-binding: t -*-
+;;
+;; Copyright (C) 2020 emacs-lsp maintainers
+;;
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This module provides features that allow starting `iedit' on various
+;; different lsp-based, semantic units (like documentHighlights, and
+;; linkedEditingRanges in the future).
+
+;;; Code:
+
+(require 'lsp-mode)
+(require 'dash)
+
+(declare-function iedit-make-occurrence-overlay "iedit-lib" (begin end))
+(declare-function iedit-start-buffering "iedit-lib" ())
+(declare-function iedit-lib-start "iedit-lib" (mode-exit-func))
+(declare-function iedit-done "iedit" ())
+(declare-function evil-multiedit-mode "evil-multiedit" (mode))
+(declare-function evil-iedit-state "evil-iedit-state" ())
+
+(defvar iedit-mode)
+(defvar iedit-auto-buffering)
+(defvar iedit-occurrences-overlays)
+(defvar iedit-occurrence-keymap)
+(defvar iedit-mode-occurrence-keymap)
+(defvar evil-multiedit--dont-recall)
+
+(defun lsp-iedit--on-ranges (ranges)
+ "Start an `iedit' operation using RANGES.
+RANGES shall be a list of lsp-`&Range's. They can be acquired
+from various lsp protocol requests, e.g.
+`textDocument/documentHighlight', ...."
+ (require 'iedit)
+ (unless (seq-empty-p ranges)
+ (mapc (-lambda ((&RangeToPoint :start :end))
+ (push (iedit-make-occurrence-overlay start end)
+ iedit-occurrences-overlays))
+ ranges)
+ ;; See `iedit-start'; TODO: upstream this
+ (setq iedit-occurrence-keymap iedit-mode-occurrence-keymap)
+ (setq iedit-mode t)
+ (when iedit-auto-buffering
+ (iedit-start-buffering))
+ (iedit-lib-start 'iedit-done)
+ (run-hooks 'iedit-mode-hook)
+ (add-hook 'before-revert-hook 'iedit-done nil t)
+ (add-hook 'kbd-macro-termination-hook 'iedit-done nil t)
+ (add-hook 'change-major-mode-hook 'iedit-done nil t)
+ (add-hook 'iedit-aborting-hook 'iedit-done nil t)
+ (message "%d occurrences of \"%s\""
+ (seq-length ranges)
+ (lsp--range-text (lsp-seq-first ranges)))))
+
+;; iedit
+
+;;;###autoload
+(defun lsp-iedit-highlights ()
+ "Start an `iedit' operation on the documentHighlights at point.
+This can be used as a primitive `lsp-rename' replacement if the
+language server doesn't support renaming.
+
+See also `lsp-enable-symbol-highlighting'."
+ (interactive)
+ (let ((highlights (lsp-request "textDocument/documentHighlight"
+ (lsp--text-document-position-params)))
+ (-compare-fn (-lambda ((&Location :range (&Range :start l-start :end l-end))
+ (&Location :range (&Range :start r-start :end r-end)))
+ (and (lsp--position-equal l-start r-start)
+ (lsp--position-equal l-end r-end)))))
+ (lsp-iedit--on-ranges (mapcar #'lsp:document-highlight-range (-distinct highlights)))))
+
+;;;###autoload
+(defun lsp-iedit-linked-ranges ()
+ "Start an `iedit' for `textDocument/linkedEditingRange'"
+ (interactive)
+ (unless (lsp-feature? "textDocument/linkedEditingRange")
+ (user-error "`textDocument/linkedEditingRange' is not supported by current server"))
+
+ (-> (lsp-request "textDocument/linkedEditingRange" (lsp--text-document-position-params))
+ (lsp:linked-editing-ranges-ranges)
+ (or (user-error "No editing ranges found"))
+ (lsp-iedit--on-ranges)))
+
+
+;; evil-multi-edit
+
+;;;###autoload
+(defun lsp-evil-multiedit-highlights ()
+ "Start an `evil-multiedit' operation on the documentHighlights at point.
+This can be used as a primitive `lsp-rename' replacement if the
+language server doesn't support renaming.
+
+See also `lsp-enable-symbol-highlighting'."
+ (interactive)
+ (require 'evil-multiedit)
+ (when (fboundp 'ahs-clear) (ahs-clear))
+ (setq evil-multiedit--dont-recall t)
+ (lsp-iedit-highlights)
+ (evil-multiedit-mode +1))
+
+;;;###autoload
+(defun lsp-evil-multiedit-linked-ranges ()
+ "Start an `evil-multiedit' for `textDocument/linkedEditingRange'"
+ (interactive)
+ (require 'evil-multiedit)
+ (when (fboundp 'ahs-clear) (ahs-clear))
+ (setq evil-multiedit--dont-recall t)
+ (lsp-iedit-linked-ranges)
+ (evil-multiedit-mode +1))
+
+;; evil-evil-state
+
+;;;###autoload
+(defun lsp-evil-state-highlights ()
+ "Start `iedit-mode'. for `textDocument/documentHighlight'"
+ (interactive "P")
+ (if (fboundp 'ahs-clear) (ahs-clear))
+ (lsp-iedit-highlights)
+ (evil-iedit-state))
+
+;;;###autoload
+(defun lsp-evil-state-linked-ranges ()
+ "Start `iedit-mode'. for `textDocument/linkedEditingRange'"
+ (interactive "P")
+ (if (fboundp 'ahs-clear) (ahs-clear))
+ (lsp-iedit-linked-ranges)
+ (evil-iedit-state))
+
+
+
+(lsp-consistency-check lsp-iedit)
+
+(provide 'lsp-iedit)
+;;; lsp-iedit.el ends here
diff --git a/elpa/lsp-mode-20220505.630/lsp-iedit.elc b/elpa/lsp-mode-20220505.630/lsp-iedit.elc
new file mode 100644
index 0000000..2118f6d
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-iedit.elc
Binary files differ
diff --git a/elpa/lsp-mode-20220505.630/lsp-javascript.el b/elpa/lsp-mode-20220505.630/lsp-javascript.el
new file mode 100644
index 0000000..9fa570a
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-javascript.el
@@ -0,0 +1,1119 @@
+;;; lsp-javascript.el --- description -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2020 emacs-lsp maintainers
+
+;; Author: emacs-lsp maintainers
+;; Keywords: lsp,
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; LSP Clients for the JavaScript and TypeScript Programming Languages.
+
+;;; Code:
+
+(require 'lsp-mode)
+
+(lsp-dependency 'javascript-typescript-langserver
+ '(:system "javascript-typescript-stdio")
+ '(:npm :package "javascript-typescript-langserver"
+ :path "javascript-typescript-stdio"))
+
+(defgroup lsp-typescript-javascript nil
+ "Support for TypeScript/JavaScript, using Sourcegraph's JavaScript/TypeScript language server."
+ :group 'lsp-mode
+ :link '(url-link "https://github.com/sourcegraph/javascript-typescript-langserver"))
+
+;; Original name can be confused with initializationOptions. Preferences is just one option of initializationOptions.
+(define-obsolete-variable-alias
+ 'lsp-clients-typescript-init-opts
+ 'lsp-clients-typescript-preferences
+ "lsp-mode 8.0.1")
+
+(defcustom lsp-clients-typescript-javascript-server-args '()
+ "Extra arguments for the typescript-language-server language server."
+ :group 'lsp-typescript-javascript
+ :risky t
+ :type '(repeat string))
+
+(defun lsp-typescript-javascript-tsx-jsx-activate-p (filename &optional _)
+ "Check if the javascript-typescript language server should be enabled based on FILENAME."
+ (or (string-match-p "\\.mjs\\|\\.[jt]sx?\\'" filename)
+ (and (derived-mode-p 'js-mode 'typescript-mode)
+ (not (derived-mode-p 'json-mode)))))
+
+;; Unmaintained sourcegraph server
+(lsp-register-client
+ (make-lsp-client :new-connection (lsp-stdio-connection (lambda ()
+ (cons (lsp-package-path 'javascript-typescript-langserver)
+ lsp-clients-typescript-javascript-server-args)))
+ :activation-fn 'lsp-typescript-javascript-tsx-jsx-activate-p
+ :priority -3
+ :completion-in-comments? t
+ :server-id 'jsts-ls
+ :download-server-fn (lambda (_client callback error-callback _update?)
+ (lsp-package-ensure
+ 'javascript-typescript-langserver
+ callback
+ error-callback))
+ :initialized-fn (lambda (_workspace)
+ (warn (concat "The javascript-typescript-langserver (jsts-ls) is unmaintained; "
+ "it is recommended to use ts-ls or deno-ls instead.")))))
+
+(defgroup lsp-typescript nil
+ "LSP support for TypeScript, using Theia/Typefox's TypeScript Language Server."
+ :group 'lsp-mode
+ :link '(url-link "https://github.com/theia-ide/typescript-language-server"))
+
+(defcustom lsp-clients-typescript-tls-path "typescript-language-server"
+ "Path to the typescript-language-server binary."
+ :group 'lsp-typescript
+ :risky t
+ :type 'string)
+
+(defcustom lsp-clients-typescript-server-args '("--stdio")
+ "Extra arguments for the typescript-language-server language server."
+ :group 'lsp-typescript
+ :risky t
+ :type '(repeat string))
+
+(defcustom lsp-clients-typescript-disable-automatic-typing-acquisition nil
+ "Disables tsserver from automatically fetching missing type
+definitions (@types packages) for external modules."
+ :group 'lsp-typescript
+ :type 'boolean)
+
+(defcustom lsp-clients-typescript-log-verbosity "info"
+ "The verbosity level of the information printed in the log by tsserver."
+ :group 'lsp-typescript
+ :type '(choice
+ (const "off")
+ (const "terse")
+ (const "normal")
+ (const "requesttime")
+ (const "verbose")))
+
+(defcustom lsp-clients-typescript-max-ts-server-memory nil
+ "The maximum size of the V8's old memory section in megabytes (for
+example 4096 means 4GB). The default value is dynamically configured
+by Node so can differ per system. Increase for very big projects that
+exceed allowed memory usage."
+ :group 'lsp-typescript
+ :type 'integer)
+
+(defcustom lsp-clients-typescript-npm-location nil
+ "Specifies the path to the NPM executable used for Automatic Type
+Acquisition."
+ :group 'lsp-typescript
+ :type 'string)
+
+(defcustom lsp-clients-typescript-plugins (vector)
+ "The list of plugins to load.
+It should be a vector of plist with keys `:location' and `:name'
+where `:name' is the name of the package and `:location' is the
+directory containing the package. Example:
+\(vector
+ \(list :name \"@vsintellicode/typescript-intellicode-plugin\"
+ :location \"<path>.vscode/extensions/visualstudioexptteam.
+ vscodeintellicode-1.1.9/\"))"
+ :group 'lsp-typescript
+ :type '(restricted-sexp :tag "Vector"
+ :match-alternatives
+ (lambda (xs)
+ (and (vectorp xs) (seq-every-p
+ (-lambda ((&plist :name :location))
+ (and name location))
+ xs)))))
+
+(defcustom lsp-clients-typescript-preferences nil
+ "Preferences passed to the Typescript (tsserver) process.
+See https://github.com/typescript-language-server/typescript-language-server#initializationoptions for the list of preferences available in the latest version of TypeScript."
+ :group 'lsp-typescript
+ :type 'plist)
+
+(defcustom lsp-typescript-tsdk nil
+ "Specifies the folder path containing the tsserver and
+lib*.d.ts files to use."
+ :type '(repeat string)
+ :group 'lsp-vetur
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-typescript-disable-automatic-type-acquisition nil
+ "Disables automatic type acquisition. Automatic type
+acquisition fetches `@types` packages from npm to improve
+IntelliSense for external libraries."
+ :type 'boolean
+ :group 'lsp-vetur
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-typescript-npm nil
+ "Specifies the path to the NPM executable used for Automatic
+Type Acquisition. Requires using TypeScript 2.3.4 or newer in the
+workspace."
+ :type '(repeat string)
+ :group 'lsp-vetur
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-typescript-check-npm-is-installed t
+ "Check if NPM is installed for Automatic Type Acquisition."
+ :type 'boolean
+ :group 'lsp-vetur
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-javascript-references-code-lens-enabled nil
+ "Enable/disable references CodeLens in JavaScript files."
+ :type 'boolean
+ :group 'lsp-vetur
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-typescript-references-code-lens-enabled nil
+ "Enable/disable references CodeLens in TypeScript files."
+ :type 'boolean
+ :group 'lsp-vetur
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-typescript-implementations-code-lens-enabled nil
+ "Enable/disable implementations CodeLens. This CodeLens shows
+the implementers of an interface."
+ :type 'boolean
+ :group 'lsp-vetur
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-typescript-tsserver-log "off"
+ "Enables logging of the TS server to a file. This log can be
+used to diagnose TS Server issues. The log may contain file
+paths, source code, and other potentially sensitive information
+from your project."
+ :type '(choice
+ (const "off")
+ (const "terse")
+ (const "normal")
+ (const "verbose"))
+ :group 'lsp-vetur
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-typescript-tsserver-plugin-paths nil
+ "Additional paths to discover Typescript Language Service
+plugins. Requires using TypeScript 2.3.0 or newer in the
+workspace."
+ :type '(repeat string)
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-typescript-tsserver-trace "off"
+ "Enables tracing of messages sent to the TS server. This trace
+can be used to diagnose TS Server issues. The trace may contain
+file paths, source code, and other potentially sensitive
+information from your project."
+ :type '(choice
+ (const "off")
+ (const "messages")
+ (const "verbose"))
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-javascript-suggest-complete-function-calls nil
+ "Complete functions with their parameter signature."
+ :type 'boolean
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-typescript-suggest-complete-function-calls nil
+ "Complete functions with their parameter signature."
+ :type 'boolean
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-typescript-report-style-checks-as-warnings t
+ "Report style checks as warnings."
+ :type 'boolean
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-typescript-validate-enable t
+ "Enable/disable TypeScript validation."
+ :type 'boolean
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-typescript-format-enable t
+ "Enable/disable default TypeScript formatter."
+ :type 'boolean
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-typescript-format-insert-space-after-comma-delimiter t
+ "Defines space handling after a comma delimiter."
+ :type 'boolean
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-typescript-format-insert-space-after-constructor nil
+ "Defines space handling after the constructor keyword. Requires
+using TypeScript 2.3.0 or newer in the workspace."
+ :type 'boolean
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-typescript-format-insert-space-after-semicolon-in-for-statements t
+ "Defines space handling after a semicolon in a for statement."
+ :type 'boolean
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-typescript-format-insert-space-before-and-after-binary-operators t
+ "Defines space handling after a binary operator."
+ :type 'boolean
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-typescript-format-insert-space-after-keywords-in-control-flow-statements t
+ "Defines space handling after keywords in a control flow
+statement."
+ :type 'boolean
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-typescript-format-insert-space-after-function-keyword-for-anonymous-functions t
+ "Defines space handling after function keyword for anonymous
+functions."
+ :type 'boolean
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-typescript-format-insert-space-before-function-parenthesis nil
+ "Defines space handling before function argument parentheses."
+ :type 'boolean
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-typescript-format-insert-space-after-opening-and-before-closing-nonempty-parenthesis nil
+ "Defines space handling after opening and before closing
+non-empty parenthesis."
+ :type 'boolean
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-typescript-format-insert-space-after-opening-and-before-closing-nonempty-brackets nil
+ "Defines space handling after opening and before closing
+non-empty brackets."
+ :type 'boolean
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-typescript-format-insert-space-after-opening-and-before-closing-nonempty-braces t
+ "Defines space handling after opening and before closing
+non-empty braces. Requires using TypeScript 2.3.0 or newer in the
+workspace."
+ :type 'boolean
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-typescript-format-insert-space-after-opening-and-before-closing-template-string-braces nil
+ "Defines space handling after opening and before closing
+template string braces."
+ :type 'boolean
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-typescript-format-insert-space-after-opening-and-before-closing-jsx-expression-braces nil
+ "Defines space handling after opening and before closing JSX
+expression braces."
+ :type 'boolean
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-typescript-format-insert-space-after-type-assertion nil
+ "Defines space handling after type assertions in TypeScript.
+Requires using TypeScript 2.4 or newer in the workspace."
+ :type 'boolean
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-typescript-format-place-open-brace-on-new-line-for-functions nil
+ "Defines whether an open brace is put onto a new line for
+functions or not."
+ :type 'boolean
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-typescript-format-place-open-brace-on-new-line-for-control-blocks nil
+ "Defines whether an open brace is put onto a new line for
+control blocks or not."
+ :type 'boolean
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-javascript-validate-enable t
+ "Enable/disable JavaScript validation."
+ :type 'boolean
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-javascript-format-enable t
+ "Enable/disable default JavaScript formatter."
+ :type 'boolean
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-javascript-format-insert-space-after-comma-delimiter t
+ "Defines space handling after a comma delimiter."
+ :type 'boolean
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-javascript-format-insert-space-after-constructor nil
+ "Defines space handling after the constructor keyword. Requires
+using TypeScript 2.3.0 or newer in the workspace."
+ :type 'boolean
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-javascript-format-insert-space-after-semicolon-in-for-statements t
+ "Defines space handling after a semicolon in a for statement."
+ :type 'boolean
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-javascript-format-insert-space-before-and-after-binary-operators t
+ "Defines space handling after a binary operator."
+ :type 'boolean
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-javascript-format-insert-space-after-keywords-in-control-flow-statements t
+ "Defines space handling after keywords in a control flow
+statement."
+ :type 'boolean
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-javascript-format-insert-space-after-function-keyword-for-anonymous-functions t
+ "Defines space handling after function keyword for anonymous
+functions."
+ :type 'boolean
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-javascript-format-insert-space-before-function-parenthesis nil
+ "Defines space handling before function argument parentheses."
+ :type 'boolean
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-javascript-format-insert-space-after-opening-and-before-closing-nonempty-parenthesis nil
+ "Defines space handling after opening and before closing
+non-empty parenthesis."
+ :type 'boolean
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-javascript-format-insert-space-after-opening-and-before-closing-nonempty-brackets nil
+ "Defines space handling after opening and before closing
+non-empty brackets."
+ :type 'boolean
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-javascript-format-insert-space-after-opening-and-before-closing-nonempty-braces t
+ "Defines space handling after opening and before closing
+non-empty braces. Requires using TypeScript 2.3.0 or newer in the
+workspace."
+ :type 'boolean
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-javascript-format-insert-space-after-opening-and-before-closing-template-string-braces nil
+ "Defines space handling after opening and before closing
+template string braces."
+ :type 'boolean
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-javascript-format-insert-space-after-opening-and-before-closing-jsx-expression-braces nil
+ "Defines space handling after opening and before closing JSX
+expression braces."
+ :type 'boolean
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-javascript-format-place-open-brace-on-new-line-for-functions nil
+ "Defines whether an open brace is put onto a new line for
+functions or not."
+ :type 'boolean
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-javascript-format-place-open-brace-on-new-line-for-control-blocks nil
+ "Defines whether an open brace is put onto a new line for
+control blocks or not."
+ :type 'boolean
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-javascript-implicit-project-config-check-js nil
+ "Enable/disable semantic checking of JavaScript files. Existing
+jsconfig.json or tsconfig.json files override this setting.
+Requires using TypeScript 2.3.1 or newer in the workspace."
+ :type 'boolean
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-javascript-implicit-project-config-experimental-decorators nil
+ nil
+ :type 'boolean
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-javascript-suggest-names t
+ "Enable/disable including unique names from the file in
+JavaScript suggestions."
+ :type 'boolean
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-typescript-tsc-auto-detect "on"
+ "Controls auto detection of tsc tasks."
+ :type '(choice
+ (const "on")
+ (const "off")
+ (const "build")
+ (const "watch"))
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-javascript-suggest-paths t
+ "Enable/disable suggestions for paths in import statements and
+require calls."
+ :type 'boolean
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-typescript-suggest-paths t
+ "Enable/disable suggestions for paths in import statements and
+require calls."
+ :type 'boolean
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-javascript-suggest-auto-imports t
+ "Enable/disable auto import suggestions. Requires using
+TypeScript 2.6.1 or newer in the workspace."
+ :type 'boolean
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-typescript-suggest-auto-imports t
+ "Enable/disable auto import suggestions. Requires using
+TypeScript 2.6.1 or newer in the workspace."
+ :type 'boolean
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-javascript-suggest-complete-js-docs t
+ "Enable/disable suggestion to complete JSDoc comments."
+ :type 'boolean
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-typescript-suggest-complete-js-docs t
+ "Enable/disable suggestion to complete JSDoc comments."
+ :type 'boolean
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-typescript-locale nil
+ nil
+ :type '(choice
+ (const "de")
+ (const "es")
+ (const "en")
+ (const "fr")
+ (const "it")
+ (const "ja")
+ (const "ko")
+ (const "ru")
+ (const "zh-CN")
+ (const "zh-TW")
+ nil)
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-javascript-suggestion-actions-enabled t
+ "Enable/disable suggestion diagnostics for JavaScript files in
+the editor. Requires using TypeScript 2.8 or newer in the
+workspace."
+ :type 'boolean
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-typescript-suggestion-actions-enabled t
+ "Enable/disable suggestion diagnostics for TypeScript files in
+the editor. Requires using TypeScript 2.8 or newer in the
+workspace."
+ :type 'boolean
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-javascript-preferences-quote-style "auto" nil
+ :type '(choice
+ (const "auto")
+ (const "single")
+ (const "double"))
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-typescript-preferences-quote-style "auto" nil
+ :type '(choice
+ (const "auto")
+ (const "single")
+ (const "double"))
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-javascript-preferences-import-module-specifier "auto"
+ "Preferred path style for auto imports."
+ :type '(choice
+ (const "auto")
+ (const "relative")
+ (const "non-relative"))
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-typescript-preferences-import-module-specifier "auto"
+ "Infer the shortest path type."
+ :type '(choice
+ (const "auto")
+ (const "relative")
+ (const "non-relative"))
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-javascript-preferences-rename-shorthand-properties t
+ "Enable/disable introducing aliases for object shorthand
+properties during renames. Requires using TypeScript 3.4 or newer
+in the workspace."
+ :type 'boolean
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-typescript-preferences-rename-shorthand-properties t
+ "Enable/disable introducing aliases for object shorthand
+properties during renames. Requires using TypeScript 3.4 or newer
+in the workspace."
+ :type 'boolean
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-typescript-update-imports-on-file-move-enabled "prompt"
+ "Enable/disable automatic updating of import paths when you
+rename or move a file in VS Code. Requires using TypeScript 2.9
+or newer in the workspace."
+ :type '(choice
+ (const "prompt")
+ (const "always")
+ (const "never"))
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-javascript-update-imports-on-file-move-enabled "prompt"
+ "Prompt on each rename."
+ :type '(choice
+ (const "prompt")
+ (const "always")
+ (const "never"))
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-typescript-auto-closing-tags t
+ "Enable/disable automatic closing of JSX tags. Requires using
+TypeScript 3.0 or newer in the workspace."
+ :type 'boolean
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-javascript-auto-closing-tags t
+ "Enable/disable automatic closing of JSX tags. Requires using
+TypeScript 3.0 or newer in the workspace."
+ :type 'boolean
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-javascript-suggest-enabled t
+ "Enabled/disable autocomplete suggestions."
+ :type 'boolean
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-typescript-suggest-enabled t
+ "Enabled/disable autocomplete suggestions."
+ :type 'boolean
+ :package-version '(lsp-mode . "6.1"))
+
+;; inlay hints
+
+(defface lsp-javascript-inlay-face
+ '((t :inherit font-lock-comment-face))
+ "The face to use for the JavaScript inlays."
+ :group 'lsp-javascript
+ :package-version '(lsp-mode . "8.0.1"))
+
+(defface lsp-javascript-inlay-type-face
+ '((t :inherit lsp-javascript-inlay-face))
+ "Face for inlay type hints (e.g. inferred variable types)."
+ :group 'lsp-javascript
+ :package-version '(lsp-mode . "8.0.1"))
+
+(defcustom lsp-javascript-inlay-type-format ": %s"
+ "Format string for variable inlays (part of the inlay face)."
+ :type '(string :tag "String")
+ :group 'lsp-javascript
+ :package-version '(lsp-mode . "8.0.1"))
+
+(defface lsp-javascript-inlay-parameter-face
+ '((t :inherit lsp-javascript-inlay-face))
+ "Face for inlay parameter hints (e.g. function parameter names at
+call-site)."
+ :group 'lsp-javascript
+ :package-version '(lsp-mode . "8.0.1"))
+
+(defcustom lsp-javascript-inlay-param-format "%s:"
+ "Format string for parameter inlays (part of the inlay face)."
+ :type '(string :tag "String")
+ :group 'lsp-javascript
+ :package-version '(lsp-mode . "8.0.1"))
+
+(defcustom lsp-typescript-surveys-enabled t
+ "Enabled/disable occasional surveys that help us improve VS
+Code's JavaScript and TypeScript support."
+ :type 'boolean
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-javascript-display-inlay-hints nil
+ "Whether to display inlay hints."
+ :type 'boolean
+ :package-version '(lsp-mode . "8.0.1"))
+
+(defcustom lsp-javascript-display-enum-member-value-hints nil
+ "Show inlay hints for enum member values."
+ :type 'boolean
+ :package-version '(lsp-mode . "8.0.1"))
+
+(defcustom lsp-javascript-display-return-type-hints nil
+ "Show inlay hints for function return types."
+ :type 'boolean
+ :package-version '(lsp-mode . "8.0.1"))
+
+(defcustom lsp-javascript-display-parameter-type-hints nil
+ "Show inlay hints for function parameters."
+ :type 'boolean
+ :package-version '(lsp-mode . "8.0.1"))
+
+(defcustom lsp-javascript-display-parameter-name-hints "none"
+ "Level of hinting for parameter types."
+ :type '(choice (const :tag "none" "none")
+ (const :tag "literals" "literals")
+ (const :tag "all" "all"))
+ :package-version '(lsp-mode . "8.0.1"))
+
+(defcustom lsp-javascript-display-parameter-name-hints-when-argument-matches-name nil
+ "Show inlay hints for function parameters even when argument matches
+name (e.g. `data' variable passed as `data' parameter)."
+ :type 'boolean
+ :package-version '(lsp-mode . "8.0.1"))
+
+(defcustom lsp-javascript-display-property-declaration-type-hints nil
+ "Show inlay hints for property declaration types."
+ :type 'boolean
+ :package-version '(lsp-mode . "8.0.1"))
+
+(defcustom lsp-javascript-display-variable-type-hints nil
+ "Show inlay hints for variable types."
+ :type 'boolean
+ :package-version '(lsp-mode . "8.0.1"))
+
+(defcustom lsp-javascript-update-inlay-hints-on-scroll t
+ "Update inlay hints immediately when scrolling or modifying window sizes."
+ :type 'boolean
+ :package-version '(lsp-mode . "8.0.1"))
+
+(lsp-register-custom-settings
+ '(("javascript.autoClosingTags" lsp-javascript-auto-closing-tags t)
+ ("javascript.implicitProjectConfig.checkJs" lsp-javascript-implicit-project-config-check-js t)
+ ("javascript.implicitProjectConfig.experimentalDecorators" lsp-javascript-implicit-project-config-experimental-decorators t)
+ ("javascript.preferences.importModuleSpecifier" lsp-javascript-preferences-import-module-specifier)
+ ("javascript.preferences.quoteStyle" lsp-javascript-preferences-quote-style)
+ ("javascript.preferences.renameShorthandProperties" lsp-javascript-preferences-rename-shorthand-properties t)
+ ("javascript.referencesCodeLens.enabled" lsp-javascript-references-code-lens-enabled t)
+ ("javascript.suggest.autoImports" lsp-javascript-suggest-auto-imports t)
+ ("javascript.suggest.completeFunctionCalls" lsp-javascript-suggest-complete-function-calls t)
+ ("javascript.suggest.completeJSDocs" lsp-javascript-suggest-complete-js-docs t)
+ ("javascript.suggest.enabled" lsp-javascript-suggest-enabled t)
+ ("javascript.suggest.names" lsp-javascript-suggest-names t)
+ ("javascript.suggest.paths" lsp-javascript-suggest-paths t)
+ ("javascript.suggestionActions.enabled" lsp-javascript-suggestion-actions-enabled t)
+ ("javascript.updateImportsOnFileMove.enabled" lsp-javascript-update-imports-on-file-move-enabled)
+ ("javascript.validate.enable" lsp-javascript-validate-enable t)
+ ("javascript.format.enable" lsp-javascript-format-enable t)
+ ("javascript.format.insertSpaceAfterCommaDelimiter" lsp-javascript-format-insert-space-after-comma-delimiter t)
+ ("javascript.format.insertSpaceAfterConstructor" lsp-javascript-format-insert-space-after-constructor t)
+ ("javascript.format.insertSpaceAfterFunctionKeywordForAnonymousFunctions" lsp-javascript-format-insert-space-after-function-keyword-for-anonymous-functions t)
+ ("javascript.format.insertSpaceAfterKeywordsInControlFlowStatements" lsp-javascript-format-insert-space-after-keywords-in-control-flow-statements t)
+ ("javascript.format.insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces" lsp-javascript-format-insert-space-after-opening-and-before-closing-jsx-expression-braces t)
+ ("javascript.format.insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces" lsp-javascript-format-insert-space-after-opening-and-before-closing-nonempty-braces t)
+ ("javascript.format.insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets" lsp-javascript-format-insert-space-after-opening-and-before-closing-nonempty-brackets t)
+ ("javascript.format.insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis" lsp-javascript-format-insert-space-after-opening-and-before-closing-nonempty-parenthesis t)
+ ("javascript.format.insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces" lsp-javascript-format-insert-space-after-opening-and-before-closing-template-string-braces t)
+ ("javascript.format.insertSpaceAfterSemicolonInForStatements" lsp-javascript-format-insert-space-after-semicolon-in-for-statements t)
+ ("javascript.format.insertSpaceBeforeAndAfterBinaryOperators" lsp-javascript-format-insert-space-before-and-after-binary-operators t)
+ ("javascript.format.insertSpaceBeforeFunctionParenthesis" lsp-javascript-format-insert-space-before-function-parenthesis t)
+ ("javascript.format.placeOpenBraceOnNewLineForControlBlocks" lsp-javascript-format-place-open-brace-on-new-line-for-control-blocks t)
+ ("javascript.format.placeOpenBraceOnNewLineForFunctions" lsp-javascript-format-place-open-brace-on-new-line-for-functions t)
+ ("typescript.autoClosingTags" lsp-typescript-auto-closing-tags t)
+ ("typescript.check.npmIsInstalled" lsp-typescript-check-npm-is-installed t)
+ ("typescript.disableAutomaticTypeAcquisition" lsp-typescript-disable-automatic-type-acquisition t)
+ ("typescript.implementationsCodeLens.enabled" lsp-typescript-implementations-code-lens-enabled t)
+ ("typescript.locale" lsp-typescript-locale)
+ ("typescript.npm" lsp-typescript-npm)
+ ("typescript.preferences.importModuleSpecifier" lsp-typescript-preferences-import-module-specifier)
+ ("typescript.preferences.quoteStyle" lsp-typescript-preferences-quote-style)
+ ("typescript.preferences.renameShorthandProperties" lsp-typescript-preferences-rename-shorthand-properties t)
+ ("typescript.referencesCodeLens.enabled" lsp-typescript-references-code-lens-enabled t)
+ ("typescript.reportStyleChecksAsWarnings" lsp-typescript-report-style-checks-as-warnings t)
+ ("typescript.suggest.autoImports" lsp-typescript-suggest-auto-imports t)
+ ("typescript.suggest.completeFunctionCalls" lsp-typescript-suggest-complete-function-calls t)
+ ("typescript.suggest.completeJSDocs" lsp-typescript-suggest-complete-js-docs t)
+ ("typescript.suggest.enabled" lsp-typescript-suggest-enabled t)
+ ("typescript.suggest.paths" lsp-typescript-suggest-paths t)
+ ("typescript.suggestionActions.enabled" lsp-typescript-suggestion-actions-enabled t)
+ ("typescript.surveys.enabled" lsp-typescript-surveys-enabled t)
+ ("typescript.tsc.autoDetect" lsp-typescript-tsc-auto-detect)
+ ("typescript.tsdk" lsp-typescript-tsdk)
+ ("typescript.tsserver.log" lsp-typescript-tsserver-log)
+ ("typescript.tsserver.pluginPaths" lsp-typescript-tsserver-plugin-paths)
+ ("typescript.tsserver.trace" lsp-typescript-tsserver-trace)
+ ("typescript.updateImportsOnFileMove.enabled" lsp-typescript-update-imports-on-file-move-enabled)
+ ("typescript.validate.enable" lsp-typescript-validate-enable t)
+ ("typescript.format.enable" lsp-typescript-format-enable t)
+ ("typescript.format.insertSpaceAfterCommaDelimiter" lsp-typescript-format-insert-space-after-comma-delimiter t)
+ ("typescript.format.insertSpaceAfterConstructor" lsp-typescript-format-insert-space-after-constructor t)
+ ("typescript.format.insertSpaceAfterFunctionKeywordForAnonymousFunctions" lsp-typescript-format-insert-space-after-function-keyword-for-anonymous-functions t)
+ ("typescript.format.insertSpaceAfterKeywordsInControlFlowStatements" lsp-typescript-format-insert-space-after-keywords-in-control-flow-statements t)
+ ("typescript.format.insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces" lsp-typescript-format-insert-space-after-opening-and-before-closing-jsx-expression-braces t)
+ ("typescript.format.insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces" lsp-typescript-format-insert-space-after-opening-and-before-closing-nonempty-braces t)
+ ("typescript.format.insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets" lsp-typescript-format-insert-space-after-opening-and-before-closing-nonempty-brackets t)
+ ("typescript.format.insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis" lsp-typescript-format-insert-space-after-opening-and-before-closing-nonempty-parenthesis t)
+ ("typescript.format.insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces" lsp-typescript-format-insert-space-after-opening-and-before-closing-template-string-braces t)
+ ("typescript.format.insertSpaceAfterSemicolonInForStatements" lsp-typescript-format-insert-space-after-semicolon-in-for-statements t)
+ ("typescript.format.insertSpaceAfterTypeAssertion" lsp-typescript-format-insert-space-after-type-assertion t)
+ ("typescript.format.insertSpaceBeforeAndAfterBinaryOperators" lsp-typescript-format-insert-space-before-and-after-binary-operators t)
+ ("typescript.format.insertSpaceBeforeFunctionParenthesis" lsp-typescript-format-insert-space-before-function-parenthesis t)
+ ("typescript.format.placeOpenBraceOnNewLineForControlBlocks" lsp-typescript-format-place-open-brace-on-new-line-for-control-blocks t)
+ ("typescript.format.placeOpenBraceOnNewLineForFunctions" lsp-typescript-format-place-open-brace-on-new-line-for-functions t)
+ ("typescript.inlayHints.includeInlayEnumMemberValueHints" lsp-javascript-display-enum-member-value-hints t)
+ ("typescript.inlayHints.includeInlayFunctionLikeReturnTypeHints" lsp-javascript-display-return-type-hints t)
+ ("typescript.inlayHints.includeInlayFunctionParameterTypeHints" lsp-javascript-display-parameter-type-hints t)
+ ("typescript.inlayHints.includeInlayParameterNameHints" lsp-javascript-display-parameter-name-hints nil)
+ ("typescript.inlayHints.includeInlayParameterNameHintsWhenArgumentMatchesName" lsp-javascript-display-parameter-name-hints-when-argument-matches-name t)
+ ("typescript.inlayHints.includeInlayPropertyDeclarationTypeHints" lsp-javascript-display-property-declaration-type-hints t)
+ ("typescript.inlayHints.includeInlayVariableTypeHints" lsp-javascript-display-variable-type-hints t)
+ ("javascript.inlayHints.includeInlayEnumMemberValueHints" lsp-javascript-display-enum-member-value-hints t)
+ ("javascript.inlayHints.includeInlayFunctionLikeReturnTypeHints" lsp-javascript-display-return-type-hints t)
+ ("javascript.inlayHints.includeInlayFunctionParameterTypeHints" lsp-javascript-display-parameter-type-hints t)
+ ("javascript.inlayHints.includeInlayParameterNameHints" lsp-javascript-display-parameter-name-hints nil)
+ ("javascript.inlayHints.includeInlayParameterNameHintsWhenArgumentMatchesName" lsp-javascript-display-parameter-name-hints-when-argument-matches-name t)
+ ("javascript.inlayHints.includeInlayPropertyDeclarationTypeHints" lsp-javascript-display-property-declaration-type-hints t)
+ ("javascript.inlayHints.includeInlayVariableTypeHints" lsp-javascript-display-variable-type-hints t)))
+
+(lsp-dependency 'typescript-language-server
+ '(:system lsp-clients-typescript-tls-path)
+ '(:npm :package "typescript-language-server"
+ :path "typescript-language-server"))
+
+(lsp-dependency 'typescript
+ '(:system "tsserver")
+ '(:npm :package "typescript"
+ :path "tsserver"))
+
+(defun lsp-javascript--rename (_workspace args)
+ (let ((path (lsp--uri-to-path (lsp-get (lsp-get args :textDocument) :uri))))
+ (if (f-exists? path)
+ (with-current-buffer (find-file path)
+ (goto-char (lsp--position-to-point
+ (lsp-get args :position))))
+ (error "There is no file %s" path)))
+ (call-interactively #'lsp-rename)
+ nil)
+
+(defun lsp-javascript-rename-file ()
+ "Rename current file and all it's references in other files."
+ (interactive)
+ (let* ((name (buffer-name))
+ (old (buffer-file-name))
+ (basename (file-name-nondirectory old)))
+ (unless (and old (file-exists-p old))
+ (error "Buffer '%s' is not visiting a file." name))
+ (let ((new (read-file-name "New name: " (file-name-directory old) basename nil basename)))
+ (when (get-file-buffer new)
+ (error "A buffer named '%s' already exists." new))
+ (when (file-exists-p new)
+ (error "A file named '%s' already exists." new))
+ (lsp--send-execute-command
+ "_typescript.applyRenameFile"
+ (vector (list :sourceUri (lsp--buffer-uri)
+ :targetUri (lsp--path-to-uri new))))
+ (mkdir (file-name-directory new) t)
+ (rename-file old new)
+ (rename-buffer new)
+ (set-visited-file-name new)
+ (set-buffer-modified-p nil)
+ (lsp-disconnect)
+ (setq-local lsp-buffer-uri nil)
+ (lsp)
+ (lsp--info "Renamed '%s' to '%s'." name (file-name-nondirectory new)))))
+
+(defun lsp-javascript-update-inlay-hints-scroll-function (window start)
+ (lsp-javascript--update-inlay-hints start (window-end window t)))
+
+(defun lsp-javascript-update-inlay-hints ()
+ (lsp-javascript--update-inlay-hints (window-start) (window-end nil t)))
+
+(defun lsp-javascript--update-inlay-hints (start end)
+ (if (lsp-javascript-initialized?)
+ (lsp-request-async
+ "typescript/inlayHints"
+ (lsp-make-javascript-inlay-hints-params
+ :text-document (lsp--text-document-identifier)
+ :range (lsp-make-range :start
+ (lsp-point-to-position start)
+ :end
+ (lsp-point-to-position end)))
+ (lambda (res)
+ (lsp--remove-overlays 'lsp-javascript-inlay-hint)
+ (let ((hints (lsp-get res :inlayHints)))
+ (unless (seq-empty-p hints)
+ (overlay-recenter
+ (-let* (([hint] hints)
+ ((&javascript:InlayHint :position) hint))
+ (lsp--position-to-point position))))
+ (-each hints
+ (lambda (hint)
+ (-let* (((&javascript:InlayHint :text :position :kind :whitespace-before? :whitespace-after?) hint)
+ (pos (lsp--position-to-point position))
+ (overlay (make-overlay pos pos nil 'front-advance 'end-advance)))
+ (overlay-put overlay 'lsp-javascript-inlay-hint t)
+ (overlay-put overlay 'before-string
+ (format "%s%s%s"
+ (if (and whitespace-before? (not (string= kind lsp/javascript-inlay-hint-kind-type-hint))) " " "")
+ (propertize (lsp-javascript-format-inlay text kind)
+ 'font-lock-face (lsp-javascript-face-for-inlay kind))
+ (if whitespace-after? " " ""))))))))
+ :mode 'tick)))
+
+(defun lsp-javascript-column-at-pos (pos)
+ (save-excursion
+ (goto-char pos)
+ (current-column)))
+
+(defun lsp-javascript-format-inlay (text kind)
+ (cond
+ ((eql kind lsp/javascript-inlay-hint-kind-type-hint) (format lsp-javascript-inlay-type-format text))
+ ((eql kind lsp/javascript-inlay-hint-kind-parameter-hint) (format lsp-javascript-inlay-param-format text))
+ ;; ((eql kind lsp/javascript-inlay-hint-kind-enum-hint) (format lsp-javascript-inlay-enum-format text))
+ (t text)))
+
+(defun lsp-javascript-face-for-inlay (kind)
+ (cond
+ ((eql kind lsp/javascript-inlay-hint-kind-type-hint) 'lsp-javascript-inlay-type-face)
+ ((eql kind lsp/javascript-inlay-hint-kind-parameter-hint) 'lsp-javascript-inlay-parameter-face)
+ (t 'lsp-javascript-inlay-face)))
+
+(defun lsp-javascript-initialized? ()
+ (when-let ((workspace (lsp-find-workspace 'ts-ls (buffer-file-name))))
+ (eq 'initialized (lsp--workspace-status workspace))))
+
+(define-minor-mode lsp-javascript-inlay-hints-mode
+ "Mode for displaying inlay hints."
+ :lighter nil
+ (cond
+ (lsp-javascript-inlay-hints-mode
+ (lsp-javascript-update-inlay-hints)
+ (add-hook 'lsp-on-idle-hook #'lsp-javascript-update-inlay-hints nil t)
+ (when lsp-javascript-update-inlay-hints-on-scroll
+ (add-to-list (make-local-variable 'window-scroll-functions) #'lsp-javascript-update-inlay-hints-scroll-function)))
+ (t
+ (lsp--remove-overlays 'lsp-javascript-inlay-hint)
+ (remove-hook 'lsp-on-idle-hook #'lsp-javascript-update-inlay-hints t)
+ (when lsp-javascript-update-inlay-hints-on-scroll
+ (setf window-scroll-functions (delete #'lsp-javascript-update-inlay-hints-scroll-function window-scroll-functions))))))
+
+(lsp-register-client
+ (make-lsp-client :new-connection (lsp-stdio-connection (lambda ()
+ `(,(lsp-package-path 'typescript-language-server)
+ "--tsserver-path"
+ ,(lsp-package-path 'typescript)
+ ,@lsp-clients-typescript-server-args)))
+ :activation-fn 'lsp-typescript-javascript-tsx-jsx-activate-p
+ :priority -2
+ :completion-in-comments? t
+ :initialization-options (lambda ()
+ (list :disableAutomaticTypingAcquisition lsp-clients-typescript-disable-automatic-typing-acquisition
+ :logVerbosity lsp-clients-typescript-log-verbosity
+ :maxTsServerMemory lsp-clients-typescript-max-ts-server-memory
+ :npmLocation lsp-clients-typescript-npm-location
+ :plugins lsp-clients-typescript-plugins
+ :preferences lsp-clients-typescript-preferences))
+ :initialized-fn (lambda (workspace)
+ (with-lsp-workspace workspace
+ (lsp--set-configuration
+ (ht-merge (lsp-configuration-section "javascript")
+ (lsp-configuration-section "typescript")))))
+ :after-open-fn (lambda ()
+ (when lsp-javascript-display-inlay-hints
+ (lsp-javascript-inlay-hints-mode)))
+ :ignore-messages '("readFile .*? requested by TypeScript but content not available")
+ :server-id 'ts-ls
+ :request-handlers (ht ("_typescript.rename" #'lsp-javascript--rename))
+ :download-server-fn (lambda (_client callback error-callback _update?)
+ (lsp-package-ensure
+ 'typescript
+ (-partial #'lsp-package-ensure
+ 'typescript-language-server
+ callback
+ error-callback)
+ error-callback))))
+
+
+(defgroup lsp-flow nil
+ "LSP support for the Flow Javascript type checker."
+ :group 'lsp-mode
+ :link '(url-link "https://flow.org"))
+
+(defcustom lsp-clients-flow-server "flow"
+ "The Flow executable to use.
+Leave as just the executable name to use the default behavior of
+finding the executable with variable `exec-path'."
+ :group 'lsp-flow
+ :risky t
+ :type 'file)
+
+(defcustom lsp-clients-flow-server-args '("lsp")
+ "Extra arguments for starting the Flow language server."
+ :group 'lsp-flow
+ :risky t
+ :type '(repeat string))
+
+(defun lsp-clients-flow-tag-file-present-p (file-name)
+ "Check if the '// @flow' or `/* @flow */' tag is present in
+the contents of FILE-NAME."
+ (if-let ((buffer (find-buffer-visiting file-name)))
+ (with-current-buffer buffer
+ (lsp-clients-flow-tag-string-present-p))
+ (with-temp-buffer
+ (insert-file-contents file-name)
+ (lsp-clients-flow-tag-string-present-p))))
+
+(defun lsp-clients-flow-tag-string-present-p ()
+ "Helper for `lsp-clients-flow-tag-file-present-p' that works
+with the file contents."
+ (save-excursion
+ (goto-char (point-min))
+ (let (stop found)
+ (while (not stop)
+ (unless (re-search-forward "[^\n[:space:]]" nil t)
+ (setq stop t))
+ (if (= (point) (point-min)) (setq stop t) (backward-char))
+ (cond ((or (looking-at "//+[ ]*@flow")
+ (looking-at "/\\**[ ]*@flow")
+ (looking-at "[ ]*\\*[ ]*@flow"))
+ (setq found t) (setq stop t))
+ ((or (looking-at "//") (looking-at "*"))
+ (forward-line))
+ ((looking-at "/\\*")
+ (save-excursion
+ (unless (re-search-forward "*/" nil t) (setq stop t)))
+ (forward-line))
+ (t (setq stop t))))
+ found)))
+
+(defun lsp-clients-flow-project-p (file-name)
+ "Check if FILE-NAME is part of a Flow project, that is, if
+there is a .flowconfig file in the folder hierarchy."
+ (locate-dominating-file file-name ".flowconfig"))
+
+(defun lsp-clients-flow-activate-p (file-name _mode)
+ "Check if the Flow language server should be enabled for a
+particular FILE-NAME and MODE."
+ (and (derived-mode-p 'js-mode 'web-mode 'js2-mode 'flow-js2-mode 'rjsx-mode)
+ (not (derived-mode-p 'json-mode))
+ (or (lsp-clients-flow-project-p file-name)
+ (lsp-clients-flow-tag-file-present-p file-name))))
+
+(lsp-register-client
+ (make-lsp-client :new-connection
+ (lsp-stdio-connection (lambda ()
+ (cons lsp-clients-flow-server
+ lsp-clients-flow-server-args)))
+ :priority -1
+ :activation-fn 'lsp-clients-flow-activate-p
+ :server-id 'flow-ls))
+
+(defgroup lsp-deno nil
+ "LSP support for the Deno language server."
+ :group 'lsp-mode
+ :link '(url-link "https://deno.land/"))
+
+(defcustom lsp-clients-deno-server "deno"
+ "The Deno executable to use.
+Leave as just the executable name to use the default behavior of
+finding the executable with variable `exec-path'."
+ :group 'lsp-deno
+ :risky t
+ :type 'file
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-clients-deno-server-args '("lsp")
+ "Extra arguments for starting the Deno language server."
+ :group 'lsp-deno
+ :risky t
+ :type '(repeat string)
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-clients-deno-enable-lint t
+ "Controls if linting information will be provided by the Deno Language Server."
+ :group 'lsp-deno
+ :risky t
+ :type 'boolean
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-clients-deno-enable-code-lens-references t
+ "Enables or disables the display of code lens information."
+ :group 'lsp-deno
+ :risky t
+ :type 'boolean
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-clients-deno-enable-code-lens-references-all-functions t
+ "Enables or disables the display of code lens information for all functions.
+Setting this variable to `non-nil' implicitly enables
+`lsp-clients-deno-enable-code-lens-references'."
+ :group 'lsp-deno
+ :risky t
+ :type 'boolean
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-clients-deno-enable-code-lens-implementations t
+ "Enables or disables the display of code lens information for implementations."
+ :group 'lsp-deno
+ :risky t
+ :type 'boolean
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-clients-deno-config nil
+ "The file path to a tsconfig.json file.
+The path can be either be relative to the workspace, or an
+absolute path.
+
+Examples: `./tsconfig.json',
+`/path/to/tsconfig.json', `C:\\path\\to\\tsconfig.json'"
+ :group 'lsp-deno
+ :risky t
+ :type 'file
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-clients-deno-import-map nil
+ "The file path to an import map.
+Import maps provide a way to relocate modules based on their
+specifiers. The path can either be relative to the workspace, or
+an absolute path.
+
+Examples: `./import-map.json',
+`/path/to/import-map.json', `C:\\path\\to\\import-map.json'."
+ :group 'lsp-deno
+ :risky t
+ :type 'file
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-clients-deno-enable-unstable nil
+ "Controls if code will be type checked with Deno's unstable APIs."
+ :group 'lsp-deno
+ :risky t
+ :type 'boolean
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defun lsp-clients-deno--make-init-options ()
+ "Initialization options for the Deno language server."
+ `(:enable t
+ :config ,lsp-clients-deno-config
+ :importMap ,lsp-clients-deno-import-map
+ :lint ,(lsp-json-bool lsp-clients-deno-enable-lint)
+ :unstable ,(lsp-json-bool lsp-clients-deno-enable-unstable)
+ :codeLens (:implementations ,(lsp-json-bool lsp-clients-deno-enable-code-lens-implementations)
+ :references ,(lsp-json-bool (or lsp-clients-deno-enable-code-lens-references
+ lsp-clients-deno-enable-code-lens-references-all-functions))
+ :referencesAllFunctions ,(lsp-json-bool lsp-clients-deno-enable-code-lens-references-all-functions))))
+
+(lsp-register-client
+ (make-lsp-client :new-connection
+ (lsp-stdio-connection (lambda ()
+ (cons lsp-clients-deno-server
+ lsp-clients-deno-server-args)))
+ :initialization-options #'lsp-clients-deno--make-init-options
+ :priority -5
+ :activation-fn #'lsp-typescript-javascript-tsx-jsx-activate-p
+ :server-id 'deno-ls))
+
+(lsp-consistency-check lsp-javascript)
+
+(provide 'lsp-javascript)
+;;; lsp-javascript.el ends here
diff --git a/elpa/lsp-mode-20220505.630/lsp-javascript.elc b/elpa/lsp-mode-20220505.630/lsp-javascript.elc
new file mode 100644
index 0000000..9a2a054
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-javascript.elc
Binary files differ
diff --git a/elpa/lsp-mode-20220505.630/lsp-json.el b/elpa/lsp-mode-20220505.630/lsp-json.el
new file mode 100644
index 0000000..8380001
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-json.el
@@ -0,0 +1,131 @@
+;;; lsp-json.el --- vscode-json-languageserver integration -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2019 Kien Nguyen
+
+;; Author: kien.n.quang at gmail.com
+;; Keywords: lsp
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'lsp-mode)
+(require 'ht)
+(require 'url)
+(require 'url-util)
+
+(defgroup lsp-json nil
+ "LSP support for JSON, using vscode's built-in language server."
+ :group 'lsp-mode
+ :link '(url-link "https://github.com/microsoft/vscode/tree/main/extensions/json-language-features/server")
+ :package-version '(lsp-mode . "6.3"))
+
+(defcustom lsp-json-schemas nil
+ "Associate schemas to JSON files in the current project"
+ :type '(repeat alist)
+ :group 'lsp-json
+ :package-version '(lsp-mode . "6.3"))
+
+(defcustom lsp-http-proxy nil
+ "The URL of the proxy server to use when fetching schema."
+ :type 'string
+ :group 'lsp-json
+ :package-version '(lsp-mode . "6.3"))
+
+(defcustom lsp-http-proxyStrictSSL t
+ "The URL of the proxy server to use when fetching schema."
+ :type 'boolean
+ :group 'lsp-json
+ :package-version '(lsp-mode . "6.3"))
+
+(lsp-register-custom-settings
+ '(("json.schemas" lsp-json-schemas)
+ ("http.proxy" lsp-http-proxy)
+ ("http.proxyStrictSSL" lsp-http-proxyStrictSSL)))
+
+(defvar lsp-json--extra-init-params
+ `(:provideFormatter t
+ :handledSchemaProtocols ["file" "http" "https"]))
+
+(defvar lsp-json--schema-associations
+ `(:/*.css-data.json ["https://raw.githubusercontent.com/Microsoft/vscode-css-languageservice/master/docs/customData.schema.json"]
+ :/package.json ["http://json.schemastore.org/package"]
+ :/*.html-data.json ["https://raw.githubusercontent.com/Microsoft/vscode-html-languageservice/master/docs/customData.schema.json"]
+ :/*.schema.json ["http://json-schema.org/draft-07/schema#"]
+ :/bower.json ["http://json.schemastore.org/bower"]
+ :/composer.json ["http://json.schemastore.org/composer"]
+ :/tsconfig.json ["http://json.schemastore.org/tsconfig"]
+ :/tsconfig.*.json ["http://json.schemastore.org/tsconfig"]
+ :/typings.json ["http://json.schemastore.org/typings"]
+ :/.bowerrc ["http://json.schemastore.org/bowerrc"]
+ :/.babelrc ["http://json.schemastore.org/babelrc"]
+ :/.babelrc.json ["http://json.schemastore.org/babelrc"]
+ :/babel.config.json ["http://json.schemastore.org/babelrc"]
+ :/jsconfig.json ["http://json.schemastore.org/jsconfig"]
+ :/jsconfig.*.json ["http://json.schemastore.org/jsconfig"]
+ :/project.json ["http://json.schemastore.org/project"]
+ :/omnisharp.json ["http://json.schemastore.org/omnisharp"]
+ :/.eslintrc.json ["http://json.schemastore.org/eslintrc"]
+ :/.eslintrc ["http://json.schemastore.org/eslintrc"])
+ "Default json schemas.")
+
+(defun lsp-json--get-content (_workspace uri callback)
+ "Get content from URI."
+ (ignore-errors
+ (url-retrieve uri
+ (lambda (_status callback)
+ (goto-char (point-min))
+ (re-search-forward "\n\n" nil 'noerror)
+ (funcall
+ callback
+ (decode-coding-string (buffer-substring (point) (point-max))
+ 'utf-8-unix)))
+ (list callback))))
+
+(lsp-dependency 'vscode-json-languageserver
+ '(:system "vscode-json-language-server")
+ '(:npm :package "vscode-langservers-extracted"
+ :path "vscode-json-language-server"))
+
+(lsp-register-client
+ (make-lsp-client
+ :new-connection
+ (lsp-stdio-connection
+ (lambda () (list (lsp-package-path 'vscode-json-languageserver) "--stdio")))
+ :activation-fn (lsp-activate-on "json" "jsonc")
+ :server-id 'json-ls
+ :priority 0
+ :multi-root t
+ :completion-in-comments? t
+ :initialization-options lsp-json--extra-init-params
+ :async-request-handlers (ht ("vscode/content" #'lsp-json--get-content))
+ :initialized-fn
+ (lambda (w)
+ (with-lsp-workspace w
+ (lsp--set-configuration
+ (ht-merge (lsp-configuration-section "json")
+ (lsp-configuration-section "http")))
+ (lsp-notify "json/schemaAssociations" lsp-json--schema-associations)))
+ :download-server-fn
+ (lambda (_client callback error-callback _update?)
+ (lsp-package-ensure 'vscode-json-languageserver callback error-callback))))
+
+(lsp-consistency-check lsp-json)
+
+(provide 'lsp-json)
+;;; lsp-json.el ends here
diff --git a/elpa/lsp-mode-20220505.630/lsp-json.elc b/elpa/lsp-mode-20220505.630/lsp-json.elc
new file mode 100644
index 0000000..2dcbf3e
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-json.elc
Binary files differ
diff --git a/elpa/lsp-mode-20220505.630/lsp-kotlin.el b/elpa/lsp-mode-20220505.630/lsp-kotlin.el
new file mode 100644
index 0000000..1b71a99
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-kotlin.el
@@ -0,0 +1,154 @@
+;;; lsp-kotlin.el --- description -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2020 emacs-lsp maintainers
+
+;; Author: emacs-lsp maintainers
+;; Keywords: lsp, kotlin
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; LSP Clients for the Kotlin Programming Language.
+
+;;; Code:
+
+(require 'lsp-mode)
+
+(defgroup lsp-kotlin nil
+ "LSP support for Kotlin, using KotlinLanguageServer."
+ :group 'lsp-mode
+ :link '(url-link "https://github.com/fwcd/KotlinLanguageServer"))
+
+(define-obsolete-variable-alias
+ 'lsp-kotlin-language-server-path
+ 'lsp-clients-kotlin-server-executable
+ "lsp-mode 6.4")
+
+(defcustom lsp-clients-kotlin-server-executable
+ (if (eq system-type 'windows-nt)
+ "kotlin-language-server.bat"
+ "kotlin-language-server")
+ "The kotlin-language-server executable to use.
+Leave as just the executable name to use the default behavior of finding the
+executable with `exec-path'."
+ :type 'string
+ :group 'lsp-kotlin)
+
+(defcustom lsp-kotlin-trace-server "off"
+ "Traces the communication between VSCode and the Kotlin language server."
+ :type '(choice (:tag "off" "messages" "verbose"))
+ :group 'lsp-kotlin
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-kotlin-compiler-jvm-target "1.8"
+ "Specifies the JVM target, e.g. \"1.6\" or \"1.8\"."
+ :type 'string
+ :group 'lsp-kotlin
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-kotlin-linting-debounce-time 250
+ "[DEBUG] Specifies the debounce time limit.
+Lower to increase responsiveness at the cost of possible stability issues."
+ :type 'number
+ :group 'lsp-kotlin
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-kotlin-completion-snippets-enabled t
+ "Specifies whether code completion should provide snippets (true) or
+plain-text items (false)."
+ :type 'boolean
+ :group 'lsp-kotlin
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-kotlin-debug-adapter-enabled t
+ "[Recommended] Specifies whether the debug adapter should be used.
+When enabled a debugger for Kotlin will be available."
+ :type 'boolean)
+
+(defcustom lsp-kotlin-debug-adapter-path ""
+ "Optionally a custom path to the debug adapter executable."
+ :type 'string
+ :group 'lsp-kotlin
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-kotlin-external-sources-use-kls-scheme t
+ "[Recommended] Specifies whether URIs inside JARs should be represented
+using the 'kls'-scheme."
+ :type 'boolean
+ :group 'lsp-kotlin
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-kotlin-external-sources-auto-convert-to-kotlin t
+ "Specifies whether decompiled/external classes should be auto-converted
+to Kotlin."
+ :type 'boolean
+ :group 'lsp-kotlin
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-kotlin-server-download-url
+ "https://github.com/fwcd/kotlin-language-server/releases/latest/download/server.zip"
+ "The URL for the language server download."
+ :type 'string
+ :group 'lsp-kotlin
+ :package-version '(lsp-mode . "8.0.1"))
+
+(lsp-register-custom-settings
+ '(("kotlin.externalSources.autoConvertToKotlin" lsp-kotlin-external-sources-auto-convert-to-kotlin t)
+ ("kotlin.externalSources.useKlsScheme" lsp-kotlin-external-sources-use-kls-scheme t)
+ ("kotlin.debugAdapter.path" lsp-kotlin-debug-adapter-path)
+ ("kotlin.debugAdapter.enabled" lsp-kotlin-debug-adapter-enabled t)
+ ("kotlin.completion.snippets.enabled" lsp-kotlin-completion-snippets-enabled t)
+ ("kotlin.linting.debounceTime" lsp-kotlin-linting-debounce-time)
+ ("kotlin.compiler.jvm.target" lsp-kotlin-compiler-jvm-target)
+ ("kotlin.trace.server" lsp-kotlin-trace-server)
+ ("kotlin.languageServer.path" lsp-clients-kotlin-server-executable)))
+
+(defvar lsp-kotlin--language-server-path
+ (f-join lsp-server-install-dir
+ "kotlin" "server" "bin" (if (eq system-type 'windows-nt)
+ "kotlin-language-server.bat"
+ "kotlin-language-server"))
+ "The path to store the language server at if necessary.")
+
+(lsp-dependency
+ 'kotlin-language-server
+ `(:system ,lsp-clients-kotlin-server-executable)
+ `(:download :url lsp-kotlin-server-download-url
+ :decompress :zip
+ :store-path ,(f-join lsp-server-install-dir "kotlin" "kotlin-language-server.zip")
+ :binary-path lsp-clients-kotlin-server-executable
+ :set-executable? t))
+
+(lsp-register-client
+ (make-lsp-client
+ :new-connection (lsp-stdio-connection (lambda ()
+ `(,(or (when (f-exists? lsp-kotlin--language-server-path)
+ lsp-kotlin--language-server-path)
+ (or (executable-find lsp-clients-kotlin-server-executable)
+ (lsp-package-path 'kotlin-language-server))
+ "kotlin-language-server"))))
+ :major-modes '(kotlin-mode)
+ :priority -1
+ :server-id 'kotlin-ls
+ :initialized-fn (lambda (workspace)
+ (with-lsp-workspace workspace
+ (lsp--set-configuration (lsp-configuration-section "kotlin"))))
+ :download-server-fn (lambda (_client callback error-callback _update?)
+ (lsp-package-ensure 'kotlin-language-server callback error-callback))))
+
+(lsp-consistency-check lsp-kotlin)
+
+(provide 'lsp-kotlin)
+;;; lsp-kotlin.el ends here
diff --git a/elpa/lsp-mode-20220505.630/lsp-kotlin.elc b/elpa/lsp-mode-20220505.630/lsp-kotlin.elc
new file mode 100644
index 0000000..1bedee3
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-kotlin.elc
Binary files differ
diff --git a/elpa/lsp-mode-20220505.630/lsp-lens.el b/elpa/lsp-mode-20220505.630/lsp-lens.el
new file mode 100644
index 0000000..5cecff4
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-lens.el
@@ -0,0 +1,448 @@
+;;; lsp-lens.el --- LSP lens -*- lexical-binding: t; -*-
+;;
+;; Copyright (C) 2020 emacs-lsp maintainers
+;;
+;; 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 <https://www.gnu.org/licenses/>.
+;;
+;;; Commentary:
+;;
+;; LSP lens
+;;
+;;; Code:
+
+(require 'lsp-mode)
+
+(defgroup lsp-lens nil
+ "LSP support for lens"
+ :prefix "lsp-lens-"
+ :group 'lsp-mode
+ :tag "LSP Lens")
+
+(defcustom lsp-lens-debounce-interval 0.001
+ "Debounce interval for loading lenses."
+ :group 'lsp-lens
+ :type 'number)
+
+(defcustom lsp-lens-place-position 'end-of-line
+ "The position to place lens relative to returned lens position."
+ :group 'lsp-lens
+ :type '(choice (const above-line)
+ (const end-of-line))
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defface lsp-lens-mouse-face
+ '((t :height 0.8 :inherit link))
+ "The face used for code lens overlays."
+ :group 'lsp-lens)
+
+(defface lsp-lens-face
+ '((t :inherit lsp-details-face))
+ "The face used for code lens overlays."
+ :group 'lsp-lens)
+
+(defvar-local lsp-lens--modified? nil)
+
+(defvar-local lsp-lens--overlays nil
+ "Current lenses.")
+
+(defvar-local lsp-lens--page nil
+ "Pair of points which holds the last window location the lenses were loaded.")
+
+(defvar-local lsp-lens--last-count nil
+ "The number of lenses the last time they were rendered.")
+
+(defvar lsp-lens-backends '(lsp-lens--backend)
+ "Backends providing lenses.")
+
+(defvar-local lsp-lens--refresh-timer nil
+ "Refresh timer for the lenses.")
+
+(defvar-local lsp-lens--data nil
+ "Pair of points which holds the last window location the lenses were loaded.")
+
+(defvar-local lsp-lens--backend-cache nil)
+
+(defun lsp-lens--text-width (from to)
+ "Measure the width of the text between FROM and TO.
+Results are meaningful only if FROM and TO are on the same line."
+ ;; `current-column' takes prettification into account
+ (- (save-excursion (goto-char to) (current-column))
+ (save-excursion (goto-char from) (current-column))))
+
+(defun lsp-lens--update (ov)
+ "Redraw quick-peek overlay OV."
+ (let* ((offset (lsp-lens--text-width (save-excursion
+ (beginning-of-visual-line)
+ (point))
+ (save-excursion
+ (beginning-of-line-text)
+ (point))))
+ (str (if (eq 'end-of-line lsp-lens-place-position)
+ (overlay-get ov 'lsp--lens-contents)
+ (concat (make-string offset ?\s)
+ (overlay-get ov 'lsp--lens-contents)))))
+ (save-excursion
+ (goto-char (overlay-start ov))
+ (if (eq 'end-of-line lsp-lens-place-position)
+ (overlay-put ov 'after-string (propertize (concat " " str) 'cursor t))
+ (overlay-put ov 'before-string (concat str "\n")))
+ (overlay-put ov 'lsp-original str))))
+
+(defun lsp-lens--overlay-ensure-at (pos)
+ "Find or create a lens for the line at POS."
+ (-doto (save-excursion
+ (goto-char pos)
+ (if (eq 'end-of-line lsp-lens-place-position)
+ (make-overlay (point-at-eol) -1 nil t t)
+ (make-overlay (point-at-bol) (1+ (point-at-eol)) nil t t)))
+ (overlay-put 'lsp-lens t)
+ (overlay-put 'evaporate t)
+ (overlay-put 'lsp-lens-position pos)))
+
+(defun lsp-lens--show (str pos metadata)
+ "Show STR in an inline window at POS including METADATA."
+ (let ((ov (lsp-lens--overlay-ensure-at pos)))
+ (save-excursion
+ (goto-char pos)
+ (setf (overlay-get ov 'lsp--lens-contents) str)
+ (setf (overlay-get ov 'lsp--metadata) metadata)
+ (lsp-lens--update ov)
+ ov)))
+
+(defun lsp-lens--idle-function (&optional buffer)
+ "Create idle function for buffer BUFFER."
+ (when (and (or (not buffer) (eq (current-buffer) buffer))
+ (not (equal (cons (window-start) (window-end)) lsp-lens--page)))
+ (lsp-lens--schedule-refresh nil)))
+
+(defun lsp-lens--overlay-matches-pos (ov pos)
+ "Check if OV is a lens covering POS."
+ (and (overlay-get ov 'lsp-lens)
+ (overlay-start ov)
+ (<= (overlay-start ov) pos)
+ (< pos (overlay-end ov))))
+
+(defun lsp-lens--after-save ()
+ "Handler for `after-save-hook' for lens mode."
+ (lsp-lens--schedule-refresh t))
+
+(defun lsp-lens--schedule-refresh (&optional buffer-modified?)
+ "Call each of the backend.
+BUFFER-MODIFIED? determines whether the buffer was modified or
+not."
+ (-some-> lsp-lens--refresh-timer cancel-timer)
+
+ (setq lsp-lens--page (cons (window-start) (window-end)))
+ (setq lsp-lens--refresh-timer
+ (run-with-timer lsp-lens-debounce-interval
+ nil
+ #'lsp-lens-refresh
+ (or lsp-lens--modified? buffer-modified?)
+ (current-buffer))))
+
+(defun lsp-lens--schedule-refresh-modified ()
+ "Schedule a lens refresh due to a buffer-modification.
+See `lsp-lens--schedule-refresh' for details."
+ (lsp-lens--schedule-refresh t))
+
+(defun lsp-lens--keymap (command)
+ "Build the lens keymap for COMMAND."
+ (-doto (make-sparse-keymap)
+ (define-key [mouse-1] (lsp-lens--create-interactive-command command))))
+
+(defun lsp-lens--create-interactive-command (command?)
+ "Create an interactive COMMAND? for the lens.
+COMMAND? shall be an `&Command' (e.g. `&CodeLens' :command?) and
+mustn't be nil."
+ (if (functionp (lsp:command-command command?))
+ (lsp:command-command command?)
+ (lambda ()
+ (interactive)
+ (lsp--execute-command command?))))
+
+(defun lsp-lens--display (lenses)
+ "Show LENSES."
+ ;; rerender only if there are lenses which are not processed or if their count
+ ;; has changed(e. g. delete lens should trigger redisplay).
+ (let ((scroll-preserve-screen-position t))
+ (setq lsp-lens--modified? nil)
+ (when (or (-any? (-lambda ((&CodeLens :_processed processed))
+ (not processed))
+ lenses)
+ (eq (length lenses) lsp-lens--last-count)
+ (not lenses))
+ (setq lsp-lens--last-count (length lenses))
+ (mapc #'delete-overlay lsp-lens--overlays)
+ (setq lsp-lens--overlays
+ (->> lenses
+ (-filter #'lsp:code-lens-command?)
+ (--map (prog1 it (lsp-put it :_processed t)))
+ (-group-by (-compose #'lsp:position-line #'lsp:range-start #'lsp:code-lens-range))
+ (-map
+ (-lambda ((_ . lenses))
+ (let* ((sorted (-sort (-on #'< (-compose #'lsp:position-character
+ #'lsp:range-start
+ #'lsp:code-lens-range))
+ lenses))
+ (data (-map
+ (-lambda ((lens &as &CodeLens
+ :command? (command &as
+ &Command :title :_face face)))
+ (propertize
+ title
+ 'face (or face 'lsp-lens-face)
+ 'action (lsp-lens--create-interactive-command command)
+ 'pointer 'hand
+ 'mouse-face 'lsp-lens-mouse-face
+ 'local-map (lsp-lens--keymap command)))
+ sorted)))
+ (lsp-lens--show
+ (s-join (propertize "|" 'face 'lsp-lens-face) data)
+ (-> sorted cl-first lsp:code-lens-range lsp:range-start lsp--position-to-point)
+ data)))))))))
+
+(defun lsp-lens-refresh (buffer-modified? &optional buffer)
+ "Refresh lenses using lenses backend.
+BUFFER-MODIFIED? determines whether the BUFFER is modified or not."
+ (let ((buffer (or buffer (current-buffer))))
+ (when (buffer-live-p buffer)
+ (with-current-buffer buffer
+ (dolist (backend lsp-lens-backends)
+ (funcall backend buffer-modified?
+ (lambda (lenses version)
+ (when (buffer-live-p buffer)
+ (with-current-buffer buffer
+ (lsp-lens--process backend lenses version))))))))))
+
+(defun lsp-lens--process (backend lenses version)
+ "Process LENSES originated from BACKEND.
+VERSION is the version of the file. The lenses has to be
+refreshed only when all backends have reported for the same
+version."
+ (setq lsp-lens--data (or lsp-lens--data (make-hash-table)))
+ (puthash backend (cons version (append lenses nil)) lsp-lens--data)
+
+ (-let [backend-data (->> lsp-lens--data ht-values (-filter #'cl-rest))]
+ (when (and
+ (= (length lsp-lens-backends) (ht-size lsp-lens--data))
+ (seq-every-p (-lambda ((version))
+ (or (not version) (eq version lsp--cur-version)))
+ backend-data))
+ ;; display the data only when the backends have reported data for the
+ ;; current version of the file
+ (lsp-lens--display (apply #'append (-map #'cl-rest backend-data)))))
+ version)
+
+(lsp-defun lsp--lens-backend-not-loaded? ((&CodeLens :range
+ (&Range :start)
+ :command?
+ :_pending pending))
+ "Return t if LENS has to be loaded."
+ (and (< (window-start) (lsp--position-to-point start) (window-end))
+ (not command?)
+ (not pending)))
+
+(lsp-defun lsp--lens-backend-present? ((&CodeLens :range (&Range :start) :command?))
+ "Return t if LENS has to be loaded."
+ (or command?
+ (not (< (window-start) (lsp--position-to-point start) (window-end)))))
+
+(defun lsp-lens--backend-fetch-missing (lenses callback file-version)
+ "Fetch LENSES without command in for the current window.
+
+TICK is the buffer modified tick. If it does not match
+`buffer-modified-tick' at the time of receiving the updates the
+updates must be discarded..
+CALLBACK - the callback for the lenses.
+FILE-VERSION - the version of the file."
+ (seq-each
+ (lambda (it)
+ (with-lsp-workspace (lsp-get it :_workspace)
+ (lsp-put it :_pending t)
+ (lsp-put it :_workspace nil)
+ (lsp-request-async "codeLens/resolve" it
+ (-lambda ((&CodeLens :command?))
+ (lsp-put it :_pending nil)
+ (lsp-put it :command command?)
+ (when (seq-every-p #'lsp--lens-backend-present? lenses)
+ (funcall callback lenses file-version)))
+ :mode 'tick)))
+ (seq-filter #'lsp--lens-backend-not-loaded? lenses)))
+
+(defun lsp-lens--backend (modified? callback)
+ "Lenses backend using `textDocument/codeLens'.
+MODIFIED? - t when buffer is modified since the last invocation.
+CALLBACK - callback for the lenses."
+ (when (lsp--find-workspaces-for "textDocument/codeLens")
+ (if modified?
+ (progn
+ (setq lsp-lens--backend-cache nil)
+ (lsp-request-async "textDocument/codeLens"
+ `(:textDocument (:uri ,(lsp--buffer-uri)))
+ (lambda (lenses)
+ (setq lsp-lens--backend-cache
+ (seq-mapcat
+ (-lambda ((workspace . workspace-lenses))
+ ;; preserve the original workspace so we can later use it to resolve the lens
+ (seq-do (-rpartial #'lsp-put :_workspace workspace) workspace-lenses)
+ workspace-lenses)
+ lenses))
+ (if (-every? #'lsp:code-lens-command? lsp-lens--backend-cache)
+ (funcall callback lsp-lens--backend-cache lsp--cur-version)
+ (lsp-lens--backend-fetch-missing lsp-lens--backend-cache callback lsp--cur-version)))
+ :error-handler #'ignore
+ :mode 'tick
+ :no-merge t
+ :cancel-token (concat (buffer-name (current-buffer)) "-lenses")))
+ (if (-all? #'lsp--lens-backend-present? lsp-lens--backend-cache)
+ (funcall callback lsp-lens--backend-cache lsp--cur-version)
+ (lsp-lens--backend-fetch-missing lsp-lens--backend-cache callback lsp--cur-version)))))
+
+(defun lsp-lens--refresh-buffer ()
+ "Trigger lens refresh on buffer."
+ (remove-hook 'lsp-on-idle-hook #'lsp-lens--refresh-buffer t)
+ (when (bound-and-true-p lsp-lens-mode)
+ (lsp-lens-refresh t)))
+
+(defun lsp--lens-on-refresh (workspace)
+ "Clear lens within all buffers of WORKSPACE, refreshing all workspace buffers."
+ (cl-assert (not (eq nil workspace)))
+ (->> (lsp--workspace-buffers workspace)
+ (mapc (lambda (buffer)
+ (lsp-with-current-buffer buffer
+ (if (lsp--buffer-visible-p)
+ (when (bound-and-true-p lsp-lens-mode)
+ (lsp-lens-refresh t))
+ (progn
+ (add-hook 'lsp-on-idle-hook #'lsp-lens--refresh-buffer nil t)
+ (lsp--idle-reschedule (current-buffer)))))))))
+
+;;;###autoload
+(defun lsp-lens--enable ()
+ "Enable lens mode."
+ (when (and lsp-lens-enable
+ (lsp-feature? "textDocument/codeLens"))
+ (lsp-lens-mode 1)))
+
+(defun lsp-lens--disable ()
+ "Disable lens mode."
+ (lsp-lens-mode -1))
+
+;;;###autoload
+(defun lsp-lens-show ()
+ "Display lenses in the buffer."
+ (interactive)
+ (->> (lsp-request "textDocument/codeLens"
+ `(:textDocument (:uri
+ ,(lsp--path-to-uri buffer-file-name))))
+ (seq-map (-lambda ((lens &as &CodeAction :command?))
+ (if command?
+ lens
+ (lsp-request "codeLens/resolve" lens))))
+ lsp-lens--display))
+
+;;;###autoload
+(defun lsp-lens-hide ()
+ "Delete all lenses."
+ (interactive)
+ (let ((scroll-preserve-screen-position t))
+ (seq-do #'delete-overlay lsp-lens--overlays)
+ (setq lsp-lens--overlays nil)))
+
+;;;###autoload
+(define-minor-mode lsp-lens-mode
+ "Toggle code-lens overlays."
+ :group 'lsp-lens
+ :global nil
+ :init-value nil
+ :lighter " Lens"
+ (cond
+ (lsp-lens-mode
+ (add-hook 'lsp-unconfigure-hook #'lsp-lens--disable nil t)
+ (add-hook 'lsp-configure-hook #'lsp-lens--enable nil t)
+ (add-hook 'lsp-on-idle-hook #'lsp-lens--idle-function nil t)
+ (add-hook 'lsp-on-change-hook #'lsp-lens--schedule-refresh-modified nil t)
+ (add-hook 'after-save-hook #'lsp-lens--after-save nil t)
+ (add-hook 'before-revert-hook #'lsp-lens-hide nil t)
+ (lsp-lens-refresh t))
+ (t
+ (remove-hook 'lsp-on-idle-hook #'lsp-lens--idle-function t)
+ (remove-hook 'lsp-on-change-hook #'lsp-lens--schedule-refresh-modified t)
+ (remove-hook 'after-save-hook #'lsp-lens--after-save t)
+ (remove-hook 'before-revert-hook #'lsp-lens-hide t)
+ (when lsp-lens--refresh-timer
+ (cancel-timer lsp-lens--refresh-timer))
+ (setq lsp-lens--refresh-timer nil)
+ (lsp-lens-hide)
+ (setq lsp-lens--last-count nil)
+ (setq lsp-lens--backend-cache nil)
+ (remove-hook 'lsp-configure-hook #'lsp-lens--enable t)
+ (remove-hook 'lsp-unconfigure-hook #'lsp-lens--disable t))))
+
+
+;; avy integration
+
+(declare-function avy-process "ext:avy" (candidates &optional overlay-fn cleanup-fn))
+(declare-function avy--key-to-char "ext:avy" (c))
+(defvar avy-action)
+
+;;;###autoload
+(defun lsp-avy-lens ()
+ "Click lsp lens using `avy' package."
+ (interactive)
+ (unless lsp-lens--overlays
+ (user-error "No lenses in current buffer"))
+ (let* ((avy-action 'identity)
+ (position (if (eq lsp-lens-place-position 'end-of-line)
+ 'after-string
+ 'before-string))
+ (action (cl-third
+ (avy-process
+ (-mapcat
+ (lambda (overlay)
+ (-map-indexed
+ (lambda (index lens-token)
+ (list overlay index
+ (get-text-property 0 'action lens-token)))
+ (overlay-get overlay 'lsp--metadata)))
+ lsp-lens--overlays)
+ (-lambda (path ((ov index) . _win))
+ (let* ((path (mapcar #'avy--key-to-char path))
+ (str (propertize (string (car (last path)))
+ 'face 'avy-lead-face))
+ (old-str (overlay-get ov position))
+ (old-str-tokens (s-split "|" old-str))
+ (old-token (seq-elt old-str-tokens index))
+ (tokens `(,@(-take index old-str-tokens)
+ ,(-if-let ((_ prefix suffix)
+ (s-match "\\(^[[:space:]]+\\)\\(.*\\)" old-token))
+ (concat prefix str suffix)
+ (concat str old-token))
+ ,@(-drop (1+ index) old-str-tokens)))
+ (new-str (s-join (propertize "|" 'face 'lsp-lens-face) tokens))
+ (new-str (if (or (s-ends-with? "\n" new-str)
+ (eq lsp-lens-place-position 'end-of-line))
+ new-str
+ (concat new-str "\n"))))
+ (overlay-put ov position new-str)))
+ (lambda ()
+ (--map (overlay-put it position
+ (overlay-get it 'lsp-original))
+ lsp-lens--overlays))))))
+ (when action (funcall-interactively action))))
+
+(lsp-consistency-check lsp-lens)
+
+(provide 'lsp-lens)
+;;; lsp-lens.el ends here
diff --git a/elpa/lsp-mode-20220505.630/lsp-lens.elc b/elpa/lsp-mode-20220505.630/lsp-lens.elc
new file mode 100644
index 0000000..e3be599
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-lens.elc
Binary files differ
diff --git a/elpa/lsp-mode-20220505.630/lsp-lua.el b/elpa/lsp-mode-20220505.630/lsp-lua.el
new file mode 100644
index 0000000..3349a61
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-lua.el
@@ -0,0 +1,678 @@
+;;; lsp-lua.el --- description -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2020 E. Alexander Barbosa
+
+;; Author: E. Alexander Barbosa <elxbarbosa@outlook.com>
+;; Keywords:
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; LSP Clients for the Lua Programming Language
+
+;;; Code:
+
+(require 'lsp-mode)
+(require 'f)
+(require 'files)
+
+(defgroup lsp-emmy-lua nil
+ "Lua LSP client, provided by the EmmyLua Language Server."
+ :group 'lsp-mode
+ :version "8.0.0"
+ :link '(url-link "https://github.com/EmmyLua/EmmyLua-LanguageServer"))
+
+(defcustom lsp-clients-emmy-lua-java-path "java"
+ "Java Runtime binary location."
+ :group 'lsp-emmy-lua
+ :version "8.0.0"
+ :risky t
+ :type 'file)
+
+(defcustom lsp-clients-emmy-lua-jar-path (f-join lsp-server-install-dir "EmmyLua-LS-all.jar")
+ "Emmy Lua language server jar file."
+ :group 'lsp-emmy-lua
+ :version "8.0.0"
+ :risky t
+ :type 'file)
+
+(defcustom lsp-clients-emmy-lua-args '("-jar")
+ "Arguments to the Lua Language server."
+ :group 'lsp-emmy-lua
+ :version "8.0.0"
+ :risky t
+ :type '(repeat string))
+
+(defcustom lsp-clients-emmy-lua-command nil
+ "Final command to call the Lua Language server."
+ :group 'lsp-emmy-lua
+ :version "8.0.0"
+ :risky t
+ :type '(repeat string))
+
+(defun lsp-clients-emmy-lua-test ()
+ "Test the Emmy Lua binaries and files."
+ (and (executable-find lsp-clients-emmy-lua-java-path)
+ (f-exists? lsp-clients-emmy-lua-jar-path)))
+
+(lsp-register-client
+ (make-lsp-client
+ :new-connection (lsp-stdio-connection (lambda () (or lsp-clients-emmy-lua-command
+ `(,lsp-clients-emmy-lua-java-path
+ ,@lsp-clients-emmy-lua-args
+ ,lsp-clients-emmy-lua-jar-path)))
+ #'lsp-clients-emmy-lua-test)
+ :major-modes '(lua-mode)
+ :server-id 'emmy-lua
+ :priority -1
+ :notification-handlers (lsp-ht ("emmy/progressReport" #'ignore))))
+
+
+;;; lua-language-server
+(defgroup lsp-lua-language-server nil
+ "Lua LSP client, provided by the Lua Language Server."
+ :group 'lsp-mode
+ :version "8.0.0"
+ :link '(url-link "https://github.com/sumneko/lua-language-server"))
+
+(defcustom lsp-clients-lua-language-server-install-dir (f-join lsp-server-install-dir "lua-language-server/")
+ "Installation directory for Lua Language Server."
+ :group 'lsp-lua-language-server
+ :version "8.0.0"
+ :risky t
+ :type 'directory)
+
+(defcustom lsp-clients-lua-language-server-bin
+ (f-join lsp-clients-lua-language-server-install-dir
+ "extension/server/bin/"
+ (pcase system-type
+ ('gnu/linux "Linux/lua-language-server")
+ ('darwin "macOS/lua-language-server")
+ ('windows-nt "Windows/lua-language-server.exe")
+ (_ "Linux/lua-language-server")))
+ "Location of Lua Language Server."
+ :group 'lsp-lua-language-server
+ :version "8.0.0"
+ :risky t
+ :type 'file)
+
+(defcustom lsp-clients-lua-language-server-main-location
+ (f-join lsp-clients-lua-language-server-install-dir
+ "extension/server/main.lua")
+ "Location of Lua Language Server main.lua."
+ :group 'lsp-lua-language-server
+ :version "8.0.0"
+ :risky t
+ :type 'file)
+
+(defcustom lsp-clients-lua-language-server-args '("-E")
+ "Arguments to run the Lua Language server."
+ :group 'lsp-lua-language-server
+ :version "8.0.0"
+ :risky t
+ :type '(repeat string))
+
+(defcustom lsp-clients-lua-language-server-command nil
+ "Command to start Lua Language server."
+ :group 'lsp-lua-language-server
+ :type '(repeat string))
+
+
+(defun lsp-clients-lua-language-server-test ()
+ "Test Lua language server binaries and files."
+ (and (f-exists? lsp-clients-lua-language-server-main-location)
+ (f-exists? lsp-clients-lua-language-server-bin)))
+
+(defcustom lsp-lua-color-mode "Semantic"
+ "Color mode."
+ :type '(choice (:tag "Grammar" "Semantic"))
+ :package-version '(lsp-mode . "8.0.0")
+ :group 'lsp-lua-language-server)
+
+(defcustom lsp-lua-completion-call-snippet "Disable"
+ "Shows function call snippets."
+ :type '(choice (:tag "Disable" "Both" "Replace"))
+ :package-version '(lsp-mode . "8.0.0")
+ :group 'lsp-lua-language-server)
+
+(defcustom lsp-lua-completion-display-context 6
+ "Previewing the relevant code snippet of the suggestion may help you
+understand the usage of the suggestion.
+
+The number set indicates the number of intercepted lines in the code
+fragment. If it is set to `0`, this feature can be disabled."
+ :type 'number
+ :package-version '(lsp-mode . "8.0.0")
+ :group 'lsp-lua-language-server)
+
+(defcustom lsp-lua-completion-enable t
+ "Enable completion."
+ :type 'boolean
+ :package-version '(lsp-mode . "8.0.0")
+ :group 'lsp-lua-language-server)
+
+(defcustom lsp-lua-completion-keyword-snippet "Replace"
+ "Shows keyword syntax snippets."
+ :type '(choice (:tag "Disable" "Both" "Replace"))
+ :package-version '(lsp-mode . "8.0.0")
+ :group 'lsp-lua-language-server)
+
+(defcustom lsp-lua-completion-workspace-word t
+ "Show words within the workspace."
+ :type 'boolean
+ :package-version '(lsp-mode . "8.0.0")
+ :group 'lsp-lua-language-server)
+
+(defcustom lsp-lua-develop-debugger-port 11412
+ "Listen port of debugger."
+ :type 'number
+ :package-version '(lsp-mode . "8.0.0")
+ :group 'lsp-lua-language-server)
+
+(defcustom lsp-lua-develop-debugger-wait nil
+ "Suspend before debugger connects."
+ :type 'boolean
+ :package-version '(lsp-mode . "8.0.0")
+ :group 'lsp-lua-language-server)
+
+(defcustom lsp-lua-develop-enable nil
+ "Developer mode. Do not enable, performance will be affected."
+ :type 'boolean
+ :package-version '(lsp-mode . "8.0.0")
+ :group 'lsp-lua-language-server)
+
+(defcustom lsp-lua-diagnostics-disable nil
+ "Disabled diagnostic (Use code in hover brackets).
+```json
+\"Lua.diagnostics.disable\" : [
+\"unused-local\",
+\"lowercase-global\"
+]
+```"
+ :type 'lsp-string-vector
+ :package-version '(lsp-mode . "8.0.0")
+ :group 'lsp-lua-language-server)
+
+(defcustom lsp-lua-diagnostics-enable t
+ "Enable diagnostics."
+ :type 'boolean
+ :package-version '(lsp-mode . "8.0.0")
+ :group 'lsp-lua-language-server)
+
+(defcustom lsp-lua-diagnostics-globals nil
+ "Defined global variables.
+```json
+\"Lua.diagnostics.globals\" : [
+\"GLOBAL1\",
+\"GLOBAL2\"
+]
+```"
+ :type 'lsp-string-vector
+ :package-version '(lsp-mode . "8.0.0")
+ :group 'lsp-lua-language-server)
+
+(defcustom lsp-lua-diagnostics-needed-file-status nil
+ "If you want to check only opened files, choice Opened; else choice Any.
+```json
+\"Lua.diagnostics.neededFileStatus\" : {
+\"ambiguity-1\" : \"Any\",
+\"circle-doc-class\" : \"Opened\"
+}
+```"
+ :type 'alist
+ :package-version '(lsp-mode . "8.0.0")
+ :group 'lsp-lua-language-server)
+
+(defcustom lsp-lua-diagnostics-severity nil
+ "Modified diagnostic severity.
+```json
+\"Lua.diagnostics.severity\" : {
+\"redefined-local\" : \"Warning\",
+\"emmy-lua\" : \"Hint\"
+}
+```"
+ :type 'alist
+ :package-version '(lsp-mode . "8.0.0")
+ :group 'lsp-lua-language-server)
+
+(defcustom lsp-lua-diagnostics-workspace-delay 0
+ "Latency (milliseconds) for workspace diagnostics. When you start the
+workspace, or edit any file, the entire workspace will be re-diagnosed in the
+background. Set to negative to disable workspace diagnostics."
+ :type 'number
+ :package-version '(lsp-mode . "8.0.0")
+ :group 'lsp-lua-language-server)
+
+(defcustom lsp-lua-diagnostics-workspace-rate 100
+ "Workspace diagnostics run rate (%). Decreasing this value reduces CPU usage,
+but also reduces the speed of workspace diagnostics. The diagnosis of the file
+you are currently editing is always done at full speed and is not affected by
+this setting."
+ :type 'number
+ :package-version '(lsp-mode . "8.0.0")
+ :group 'lsp-lua-language-server)
+
+(defcustom lsp-lua-hint-enable nil
+ "Enable hint."
+ :type 'boolean
+ :package-version '(lsp-mmode . "8.0.0")
+ :group 'lsp-lua-language-server)
+
+(defcustom lsp-lua-hint-param-name t
+ "Hint parameter name when the parameter called is literal."
+ :type 'boolean
+ :package-version '(lsp-mode . "8.0.0")
+ :group 'lsp-lua-language-server)
+
+(defcustom lsp-lua-hint-param-type t
+ "Show type hints at the parameter of the function."
+ :type 'boolean
+ :package-version '(lsp-mode . "8.0.0")
+ :group 'lsp-lua-language-server)
+
+(defcustom lsp-lua-hint-set-type nil
+ "Hint type at assignment operation."
+ :type 'boolean
+ :package-version '(lsp-mode . "8.0.0")
+ :group 'lsp-lua-language-server)
+
+(defcustom lsp-lua-hover-enable t
+ "Enable hover."
+ :type 'boolean
+ :package-version '(lsp-mode . "8.0.0")
+ :group 'lsp-lua-language-server)
+
+(defcustom lsp-lua-hover-field-infer 3000
+ "When hovering to view a table, type infer will be performed for each field.
+When the accumulated time of type infer reaches the set value (MS), the type
+infer of subsequent fields will be skipped."
+ :type 'number
+ :package-version '(lsp-mode . "8.0.0")
+ :group 'lsp-lua-language-server)
+
+(defcustom lsp-lua-hover-preview-fields 100
+ "When hovering to view a table, limits the maximum number of previews for
+fields."
+ :type 'number
+ :package-version '(lsp-mode . "8.0.0")
+ :group 'lsp-lua-language-server)
+
+(defcustom lsp-lua-hover-view-number t
+ "Hover to view numeric content (only if literal is not decimal)."
+ :type 'boolean
+ :package-version '(lsp-mode . "8.0.0")
+ :group 'lsp-lua-language-server)
+
+(defcustom lsp-lua-hover-view-string t
+ "Hover to view the contents of a string (only if the literal contains an
+escape character)."
+ :type 'boolean
+ :package-version '(lsp-mode . "8.0.0")
+ :group 'lsp-lua-language-server)
+
+(defcustom lsp-lua-hover-view-string-max 1000
+ "The maximum length of a hover to view the contents of a string."
+ :type 'number
+ :package-version '(lsp-mode . "8.0.0")
+ :group 'lsp-lua-language-server)
+
+(defcustom lsp-lua-intelli-sense-search-depth 0
+ "Set the search depth for IntelliSense. Increasing this value increases
+accuracy, but decreases performance. Different workspace have different
+tolerance for this setting. Please adjust it to the appropriate value."
+ :type 'number
+ :package-version '(lsp-mode . "8.0.0")
+ :group 'lsp-lua-language-server)
+
+(defcustom lsp-lua-runtime-file-encoding "utf8"
+ "File encoding. The 'ansi' option is only available under the 'Windows'
+platform."
+ :type '(choice (:tag "utf8" "ansi"))
+ :package-version '(lsp-mode . "8.0.0")
+ :group 'lsp-lua-language-server)
+
+(defcustom lsp-lua-runtime-nonstandard-symbol nil
+ "Supports non-standard symbols. Make sure that your runtime environment
+supports these symbols."
+ :type 'lsp-string-vector
+ :package-version '(lsp-mode . "8.0.0")
+ :group 'lsp-lua-language-server)
+
+(defcustom lsp-lua-runtime-path
+ ["?.lua" "?/init.lua" "?/?.lua"]
+ "`package.path`."
+ :type 'lsp-string-vector
+ :package-version '(lsp-mode . "8.0.0")
+ :group 'lsp-lua-language-server)
+
+(defcustom lsp-lua-runtime-plugin nil
+ "(Proposed) Plugin path. Default is `.vscode/lua/plugin.lua`"
+ :type 'file
+ :package-version '(lsp-mode . "8.0.0")
+ :group 'lsp-lua-language-server)
+
+(defcustom lsp-lua-runtime-special nil
+ "The custom global variables are regarded as some special built-in variables,
+and the language server will provide special support.
+```json
+\"Lua.runtime.special\" : {
+\"include\" : \"require\"
+}
+```"
+ :type 'alist
+ :package-version '(lsp-mode . "8.0.0")
+ :group 'lsp-lua-language-server)
+
+(defcustom lsp-lua-runtime-unicode-name nil
+ "Allows Unicode characters in name."
+ :type 'boolean
+ :package-version '(lsp-mode . "8.0.0")
+ :group 'lsp-lua-language-server)
+
+(defcustom lsp-lua-runtime-version "Lua 5.4"
+ "Lua runtime version."
+ :type '(choice (:tag "Lua 5.1" "Lua 5.2" "Lua 5.3" "Lua 5.4" "LuaJIT"))
+ :package-version '(lsp-mode . "8.0.0")
+ :group 'lsp-lua-language-server)
+
+(defcustom lsp-lua-signature-help-enable t
+ "Enable signature help."
+ :type 'boolean
+ :package-version '(lsp-mode . "8.0.0")
+ :group 'lsp-lua-language-server)
+
+(defcustom lsp-lua-telemetry-enable nil
+ "Enable telemetry to send your editor information and error logs over the
+network."
+ :type 'boolean
+ :package-version '(lsp-mode . "8.0.0")
+ :group 'lsp-lua-language-server)
+
+(defcustom lsp-lua-window-progress-bar t
+ "Show progress bar in status bar."
+ :type 'boolean
+ :package-version '(lsp-mode . "8.0.0")
+ :group 'lsp-lua-language-server)
+
+(defcustom lsp-lua-window-status-bar t
+ "Show extension status in status bar."
+ :type 'boolean
+ :package-version '(lsp-mode . "8.0.0")
+ :group 'lsp-lua-language-server)
+
+(defcustom lsp-lua-workspace-ignore-dir
+ [".vscode"]
+ "Ignored directories (Use `.gitignore` grammar).
+```json
+\"Lua.workspace.ignoreDir\" : [
+\"temp/*.*\",
+\"!temp/*.lua\"
+]
+```"
+ :type 'lsp-string-vector
+ :package-version '(lsp-mode . "8.0.0")
+ :group 'lsp-lua-language-server)
+
+(defcustom lsp-lua-workspace-ignore-submodules t
+ "Ignore submodules."
+ :type 'boolean
+ :package-version '(lsp-mode . "8.0.0")
+ :group 'lsp-lua-language-server)
+
+(defcustom lsp-lua-workspace-library nil
+ "Load external library.
+
+This feature can load external Lua files, which can be used for definition,
+automatic completion and other functions. Note that the language server does
+not monitor changes in external files and needs to restart if the external
+files are modified. The following example shows loaded files in `C:/lua`
+and `../lib` ,exclude `../lib/temp`.
+
+```json
+\"Lua.workspace.library\": {
+\"C:/lua\": true,
+\"../lib\": [
+\"temp/*\"
+]
+}
+```"
+ :type 'alist
+ :package-version '(lsp-mode . "8.0.0")
+ :group 'lsp-lua-language-server)
+
+(defcustom lsp-lua-workspace-max-preload 1000
+ "Max preloaded files."
+ :type 'number
+ :package-version '(lsp-mode . "8.0.0")
+ :group 'lsp-lua-language-server)
+
+(defcustom lsp-lua-workspace-preload-file-size 100
+ "Skip files larger than this value (KB) when preloading."
+ :type 'number
+ :package-version '(lsp-mode . "8.0.0")
+ :group 'lsp-lua-language-server)
+
+(defcustom lsp-lua-workspace-use-git-ignore t
+ "Ignore files list in `.gitignore` ."
+ :type 'boolean
+ :package-version '(lsp-mode . "8.0.0")
+ :group 'lsp-lua-language-server)
+
+(defcustom lsp-lua-files-associations nil
+ "Files.associations."
+ :type 'alist
+ :package-version '(lsp-mode . "8.0.0")
+ :group 'lsp-lua-language-server)
+
+(defcustom lsp-lua-files-exclude nil
+ "Files.exclude."
+ :type 'alist
+ :package-version '(lsp-mode . "8.0.0")
+ :group 'lsp-lua-language-server)
+
+(lsp-register-custom-settings
+ '(("files.associations" lsp-lua-files-associations t)
+ ("files.exclude" lsp-lua-files-exclude t)
+ ("Lua.workspace.useGitIgnore" lsp-lua-workspace-use-git-ignore t)
+ ("Lua.workspace.preloadFileSize" lsp-lua-workspace-preload-file-size)
+ ("Lua.workspace.maxPreload" lsp-lua-workspace-max-preload)
+ ("Lua.workspace.library" lsp-lua-workspace-library)
+ ("Lua.workspace.ignoreSubmodules" lsp-lua-workspace-ignore-submodules t)
+ ("Lua.workspace.ignoreDir" lsp-lua-workspace-ignore-dir)
+ ("Lua.window.statusBar" lsp-lua-window-status-bar t)
+ ("Lua.window.progressBar" lsp-lua-window-progress-bar t)
+ ("Lua.telemetry.enable" lsp-lua-telemetry-enable t)
+ ("Lua.signatureHelp.enable" lsp-lua-signature-help-enable t)
+ ("Lua.runtime.version" lsp-lua-runtime-version)
+ ("Lua.runtime.unicodeName" lsp-lua-runtime-unicode-name nil)
+ ("Lua.runtime.special" lsp-lua-runtime-special)
+ ("Lua.runtime.plugin" lsp-lua-runtime-plugin)
+ ("Lua.runtime.path" lsp-lua-runtime-path)
+ ("Lua.runtime.nonstandardSymbol" lsp-lua-runtime-nonstandard-symbol)
+ ("Lua.runtime.fileEncoding" lsp-lua-runtime-file-encoding)
+ ("Lua.intelliSense.searchDepth" lsp-lua-intelli-sense-search-depth)
+ ("Lua.hover.viewStringMax" lsp-lua-hover-view-string-max)
+ ("Lua.hover.viewString" lsp-lua-hover-view-string t)
+ ("Lua.hover.viewNumber" lsp-lua-hover-view-number t)
+ ("Lua.hover.previewFields" lsp-lua-hover-preview-fields)
+ ("Lua.hover.fieldInfer" lsp-lua-hover-field-infer)
+ ("Lua.hover.enable" lsp-lua-hover-enable t)
+ ("Lua.hint.setType" lsp-lua-hint-set-type nil)
+ ("Lua.hint.paramType" lsp-lua-hint-param-type t)
+ ("Lua.hint.paramName" lsp-lua-hint-param-name t)
+ ("Lua.hint.enable" lsp-lua-hint-enable t)
+ ("Lua.diagnostics.workspaceRate" lsp-lua-diagnostics-workspace-rate)
+ ("Lua.diagnostics.workspaceDelay" lsp-lua-diagnostics-workspace-delay)
+ ("Lua.diagnostics.severity" lsp-lua-diagnostics-severity)
+ ("Lua.diagnostics.neededFileStatus" lsp-lua-diagnostics-needed-file-status)
+ ("Lua.diagnostics.globals" lsp-lua-diagnostics-globals)
+ ("Lua.diagnostics.enable" lsp-lua-diagnostics-enable t)
+ ("Lua.diagnostics.disable" lsp-lua-diagnostics-disable)
+ ("Lua.develop.enable" lsp-lua-develop-enable t)
+ ("Lua.develop.debuggerWait" lsp-lua-develop-debugger-wait t)
+ ("Lua.develop.debuggerPort" lsp-lua-develop-debugger-port)
+ ("Lua.completion.workspaceWord" lsp-lua-completion-workspace-word t)
+ ("Lua.completion.keywordSnippet" lsp-lua-completion-keyword-snippet)
+ ("Lua.completion.enable" lsp-lua-completion-enable t)
+ ("Lua.completion.displayContext" lsp-lua-completion-display-context)
+ ("Lua.completion.callSnippet" lsp-lua-completion-call-snippet)
+ ("Lua.color.mode" lsp-lua-color-mode)))
+
+(defun lsp-lua-language-server-install (client callback error-callback update?)
+ "Download the latest version of lua-language-server and extract it to
+`lsp-lua-language-server-install-dir'."
+ (ignore client update?)
+ (let ((store-path (expand-file-name "vs-lua" lsp-clients-lua-language-server-install-dir)))
+ (lsp-download-install
+ (lambda (&rest _)
+ (set-file-modes lsp-clients-lua-language-server-bin #o0700)
+ (funcall callback))
+ error-callback
+ :url (lsp-vscode-extension-url "sumneko" "lua" "1.17.4")
+ :store-path store-path
+ :decompress :zip)))
+
+(lsp-register-client
+ (make-lsp-client
+ :new-connection (lsp-stdio-connection (lambda () (or lsp-clients-lua-language-server-command
+ `(,lsp-clients-lua-language-server-bin
+ ,@lsp-clients-lua-language-server-args
+ ,lsp-clients-lua-language-server-main-location)))
+ #'lsp-clients-lua-language-server-test)
+ :major-modes '(lua-mode)
+ :priority -2
+ :server-id 'lua-language-server
+ :download-server-fn #'lsp-lua-language-server-install))
+
+
+;;; lua-lsp
+(defgroup lsp-lua-lsp nil
+ "Lua LSP client, provided by the Lua-Lsp."
+ :group 'lsp-mode
+ :version "8.0.0"
+ :link '(url-link "https://github.com/Alloyed/lua-lsp"))
+
+(defcustom lsp-clients-luarocks-bin-dir (f-join (getenv "HOME") ".luarocks/bin/")
+ "LuaRocks bin directory."
+ :group 'lsp-lua-lsp
+ :version "8.0.0"
+ :risky t
+ :type 'directory)
+
+(defcustom lsp-clients-lua-lsp-server-install-dir nil
+ "Installation directory for Lua-Lsp Language Server."
+ :group 'lsp-lua-lsp
+ :version "8.0.0"
+ :risky t
+ :type 'file)
+
+(defun lsp-clients-lua-lsp-test ()
+ "Test Lua-lsp language server files."
+ (and (f-exists? lsp-clients-lua-lsp-server-install-dir)))
+
+(lsp-register-client
+ (make-lsp-client
+ :new-connection (lsp-stdio-connection (lambda ()
+ (or lsp-clients-lua-lsp-server-install-dir
+ (f-join lsp-clients-luarocks-bin-dir "lua-lsp")))
+ #'lsp-clients-lua-lsp-test)
+ :major-modes '(lua-mode)
+ :priority -3
+ :server-id 'lsp-lua-lsp))
+
+;;; lua-roblox-language-server
+(defgroup lsp-lua-roblox-language-server nil
+ "Roblox Lua LSP client, provided by the Roblox Lua Language Server."
+ :group 'lsp-mode
+ :version "8.0.0"
+ :link '(url-link "https://github.com/NightrainsRbx/RobloxLsp"))
+
+(defcustom lsp-lua-roblox-language-server-install-dir (f-join lsp-server-install-dir "lua-roblox-language-server/")
+ "Installation directory for Lua Language Server."
+ :group 'lsp-lua-roblox-language-server
+ :version "8.0.0"
+ :risky t
+ :type 'directory)
+
+(defcustom lsp-lua-roblox-language-server-bin
+ (f-join lsp-lua-roblox-language-server-install-dir
+ "extension/server/bin/"
+ (pcase system-type
+ ('gnu/linux "Linux/lua-language-server")
+ ('darwin "macOS/lua-language-server")
+ ('windows-nt "Windows/lua-language-server.exe")
+ (_ "Linux/lua-language-server")))
+ "Location of Roblox Lua Language Server."
+ :group 'lsp-lua-roblox-language-server
+ :version "8.0.0"
+ :risky t
+ :type 'file)
+
+(defcustom lsp-lua-roblox-language-server-main-location
+ (f-join lsp-lua-roblox-language-server-install-dir
+ "extension/server/main.lua")
+ "Location of Roblox Lua Language Server main.lua."
+ :group 'lsp-lua-roblox-language-server
+ :version "8.0.0"
+ :risky t
+ :type 'file)
+
+(defcustom lsp-lua-roblox-server-download-url
+ (lsp-vscode-extension-url "Nightrains" "robloxlsp" "0.15.8")
+ "Download url for Roblox Lua vscode extension."
+ :group 'lsp-lua-roblox-language-server
+ :version "8.0.0"
+ :type 'string)
+
+(defcustom lsp-lua-roblox-server-store-path
+ (expand-file-name "vs-lua-roblox" lsp-lua-roblox-language-server-install-dir)
+ "Server file name for the vscode extension."
+ :group 'lsp-lua-roblox-language-server
+ :version "8.0.0"
+ :type 'string)
+
+(defun lsp-lua-roblox-language-server-test ()
+ "Test Lua language server binaries and files."
+ (and (f-exists? lsp-lua-roblox-language-server-main-location)
+ (f-exists? lsp-lua-roblox-language-server-bin)))
+
+(defun lsp-lua-roblox-language-server-install (_client callback error-callback _update?)
+ "Download the latest version of lua-language-server and extract it to
+`lsp-lua-roblox-language-server-download-url'."
+ (lsp-download-install
+ (lambda (&rest _)
+ (set-file-modes lsp-lua-roblox-language-server-bin #o0700)
+ (funcall callback))
+ error-callback
+ :url lsp-lua-roblox-server-download-url
+ :store-path lsp-lua-roblox-server-store-path
+ :decompress :zip))
+
+(lsp-register-client
+ (make-lsp-client
+ :new-connection (lsp-stdio-connection (lambda () (or lsp-clients-lua-language-server-command
+ `(,lsp-lua-roblox-language-server-bin
+ ,@lsp-clients-lua-language-server-args
+ ,lsp-lua-roblox-language-server-main-location)))
+ #'lsp-lua-roblox-language-server-test)
+ :major-modes '(lua-mode)
+ :priority -4
+ :server-id 'lua-roblox-language-server
+ :download-server-fn #'lsp-lua-roblox-language-server-install))
+
+(lsp-consistency-check lsp-lua)
+
+(provide 'lsp-lua)
+;;; lsp-lua.el ends here
diff --git a/elpa/lsp-mode-20220505.630/lsp-lua.elc b/elpa/lsp-mode-20220505.630/lsp-lua.elc
new file mode 100644
index 0000000..d2a8bed
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-lua.elc
Binary files differ
diff --git a/elpa/lsp-mode-20220505.630/lsp-magik.el b/elpa/lsp-mode-20220505.630/lsp-magik.el
new file mode 100644
index 0000000..5e3a32a
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-magik.el
@@ -0,0 +1,124 @@
+;;; lsp-magik.el --- Language server client for Magik -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2022 Keronic
+
+;; Author: <robin.putters@keronic.com>
+;; Keywords: lsp, magik
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; LSP client for the Magik programming language
+;; https://github.com/StevenLooman/magik-tools
+
+;;; Code:
+
+(require `lsp-mode)
+
+(defgroup lsp-magik nil
+ "LSP support for Magik."
+ :link '(url-link "https://github.com/StevenLooman/magik-tools")
+ :group 'lsp-mode
+ :tag "Lsp Magik"
+ :package-version '(lsp-mode . "8.0.1"))
+
+(defcustom lsp-magik-java-home nil
+ "Path to Java Runtime, Java 11 minimum."
+ :type `string
+ :group `lsp-magik
+ :package-version '(lsp-mode . "8.0.1"))
+
+(defcustom lsp-magik-smallworld-gis nil
+ "Path to Smallworld Core."
+ :type `string
+ :group `lsp-magik
+ :package-version '(lsp-mode . "8.0.1"))
+
+(defcustom lsp-magik-aliases nil
+ "Path to gis_aliases file."
+ :type `string
+ :group `lsp-magik
+ :package-version '(lsp-mode . "8.0.1"))
+
+(defcustom lsp-magik-environment nil
+ "Path to environment file."
+ :type `string
+ :group `lsp-magik
+ :package-version '(lsp-mode . "8.0.1"))
+
+(defcustom lsp-magik-typing-type-database-paths []
+ "Paths to type databases."
+ :type `lsp-string-vector
+ :group `lsp-magik
+ :package-version '(lsp-mode . "8.0.1"))
+
+(defcustom lsp-magik-typing-enable-checks nil
+ "Enable typing checks."
+ :type `boolean
+ :group `lsp-magik
+ :package-version '(lsp-mode . "8.0.1"))
+
+(defcustom lsp-magik-trace-server "off"
+ "Traces the communication between VS Code and the Magik language server."
+ :type `(choice (const "off") (const "message") (const "verbose"))
+ :group `lsp-magik
+ :package-version '(lsp-mode . "8.0.1"))
+
+(defcustom lsp-magik-java-path (cond ((eq system-type 'windows-nt) "$JAVA_HOME/bin/java")
+ (t "java"))
+ "Path of the java executable."
+ :type 'string
+ :group `lsp-magik
+ :package-version '(lsp-mode . "8.0.1"))
+
+(defcustom lsp-magik-lsp-path (expand-file-name "magik-lsp/magik-language-server-0.5.1.jar" user-emacs-directory)
+ "Path of the language server."
+ :type 'string
+ :group `lsp-magik
+ :package-version '(lsp-mode . "8.0.1"))
+
+(defcustom lsp-magik-lint-override-config-file nil
+ "Override path to magiklintrc.properties."
+ :type 'string
+ :group `lsp-magik
+ :package-version '(lsp-mode . "8.0.1"))
+
+(lsp-register-client
+ (make-lsp-client :new-connection (lsp-stdio-connection
+ (lambda ()
+ (list
+ (substitute-in-file-name lsp-magik-java-path)
+ "-jar"
+ (substitute-in-file-name lsp-magik-lsp-path)
+ "--debug")))
+ :activation-fn (lsp-activate-on "magik")
+ :initialized-fn (lambda (workspace)
+ (with-lsp-workspace workspace
+ (lsp--set-configuration (lsp-configuration-section "magik"))))
+ :server-id 'magik))
+
+(lsp-register-custom-settings `(("magik.javaHome" lsp-magik-java-home)
+ ("magik.smallworldGis" lsp-magik-smallworld-gis)
+ ("magik.aliases" lsp-magik-aliases)
+ ("magik.environment" lsp-magik-environment)
+ ("magik.typing.typeDatabasePaths" lsp-magik-typing-type-database-paths)
+ ("magik.typing.enableChecks" lsp-magik-typing-enable-checks)
+ ("magik.trace.server" lsp-magik-trace-server)
+ ("magik.lint.overrideConfigFile" lsp-magik-lint-override-config-file)))
+
+(lsp-consistency-check lsp-magik)
+
+(provide 'lsp-magik)
+;;; lsp-magik.el ends here
diff --git a/elpa/lsp-mode-20220505.630/lsp-magik.elc b/elpa/lsp-mode-20220505.630/lsp-magik.elc
new file mode 100644
index 0000000..87945ed
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-magik.elc
Binary files differ
diff --git a/elpa/lsp-mode-20220505.630/lsp-markdown.el b/elpa/lsp-mode-20220505.630/lsp-markdown.el
new file mode 100644
index 0000000..08f1b20
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-markdown.el
@@ -0,0 +1,103 @@
+;;; lsp-markdown.el --- lsp-mode markdown integration -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2021 lsp-mode maintainers
+
+;; Author: lsp-mode maintainers
+;; Keywords: languages
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; LSP client for unified-language-server
+
+;;; Code:
+
+(require 'lsp-mode)
+
+;;; Markdown
+(defgroup lsp-markdown nil
+ "Settings for the markdown language server client."
+ :group 'lsp-mode
+ :link '(url-link "https://github.com/unifiedjs/unified-language-server")
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-markdown-server-command "unified-language-server"
+ "The binary (or full path to binary) which executes the server."
+ :type 'string
+ :group 'lsp-markdown
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-markdown-server-command-args '("--parser=remark-parse" "--stdio")
+ "Command-line arguments for the markdown lsp server."
+ :type '(repeat 'string)
+ :group 'lsp-markdown
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-markdown-remark-plugins [["#remark-preset-lint-markdown-style-guide"]]
+ "The JSON configuration object for plugins.
+
+For a complete list of plugins, check:
+ https://github.com/unifiedjs/unified-language-server/blob/main/CONFIGURATION.md#re-using-settings"
+ :type 'lsp-string-vector
+ :group 'lsp-markdown
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-markdown-remark-check-text-with-setting "retext-english"
+ "Configure `checkTextWith' subproperty.
+
+For a complete list of plugins, check:
+ https://github.com/unifiedjs/unified-language-server/blob/main/CONFIGURATION.md#re-using-settings"
+ :type '(choice (
+ (const "retext-english")
+ (const "remark-parse")))
+ :group 'lsp-markdown
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-markdown-remark-check-text-with-mutator ["#remark-retext" "#parse-latin"]
+ "Vector of additional mutators.
+
+For a complete list of plugins, check:
+ https://github.com/unifiedjs/unified-language-server/blob/main/CONFIGURATION.md#re-using-settings"
+ :type 'lsp-string-vector
+ :group 'lsp-markdown
+ :package-version '(lsp-mode . "8.0.0"))
+
+(lsp-dependency 'unified-language-server
+ '(:system "unified-language-server")
+ '(:npm :package "unified-language-server"
+ :path "unified-language-server"))
+
+(lsp-register-custom-settings
+ `(("unified-language-server.remark-parse.plugins" lsp-markdown-remark-plugins)
+ ("unified-language-server.remark-parse.checkTextWith.setting" lsp-markdown-remark-check-text-with-setting)
+ ("unified-language-server.remark-parse.checkTextWith.mutator" lsp-markdown-remark-check-text-with-mutator)))
+
+(lsp-register-client
+ (make-lsp-client :new-connection (lsp-stdio-connection
+ (lambda ()
+ (cons (or (executable-find lsp-markdown-server-command)
+ (lsp-package-path 'unified-language-server))
+ lsp-markdown-server-command-args)))
+ :activation-fn (lsp-activate-on "markdown")
+ :initialized-fn (lambda (workspace)
+ (with-lsp-workspace workspace
+ (lsp--set-configuration (lsp-configuration-section "unified-language-server"))))
+ :priority -1
+ :server-id 'unified))
+
+(lsp-consistency-check lsp-markdown)
+
+(provide 'lsp-markdown)
+;;; lsp-markdown.el ends here
diff --git a/elpa/lsp-mode-20220505.630/lsp-markdown.elc b/elpa/lsp-mode-20220505.630/lsp-markdown.elc
new file mode 100644
index 0000000..28a9d5d
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-markdown.elc
Binary files differ
diff --git a/elpa/lsp-mode-20220505.630/lsp-mode-autoloads.el b/elpa/lsp-mode-20220505.630/lsp-mode-autoloads.el
new file mode 100644
index 0000000..2b9f86b
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-mode-autoloads.el
@@ -0,0 +1,963 @@
+;;; lsp-mode-autoloads.el --- automatically extracted autoloads -*- lexical-binding: t -*-
+;;
+;;; Code:
+
+(add-to-list 'load-path (directory-file-name
+ (or (file-name-directory #$) (car load-path))))
+
+
+;;;### (autoloads nil "lsp-actionscript" "lsp-actionscript.el" (0
+;;;;;; 0 0 0))
+;;; Generated autoloads from lsp-actionscript.el
+
+(register-definition-prefixes "lsp-actionscript" '("lsp-actionscript-"))
+
+;;;***
+
+;;;### (autoloads nil "lsp-ada" "lsp-ada.el" (0 0 0 0))
+;;; Generated autoloads from lsp-ada.el
+
+(register-definition-prefixes "lsp-ada" '("lsp-ada-"))
+
+;;;***
+
+;;;### (autoloads nil "lsp-angular" "lsp-angular.el" (0 0 0 0))
+;;; Generated autoloads from lsp-angular.el
+
+(register-definition-prefixes "lsp-angular" '("lsp-client"))
+
+;;;***
+
+;;;### (autoloads nil "lsp-ansible" "lsp-ansible.el" (0 0 0 0))
+;;; Generated autoloads from lsp-ansible.el
+
+(register-definition-prefixes "lsp-ansible" '("lsp-ansible-"))
+
+;;;***
+
+;;;### (autoloads nil "lsp-bash" "lsp-bash.el" (0 0 0 0))
+;;; Generated autoloads from lsp-bash.el
+
+(register-definition-prefixes "lsp-bash" '("lsp-bash-"))
+
+;;;***
+
+;;;### (autoloads nil "lsp-beancount" "lsp-beancount.el" (0 0 0 0))
+;;; Generated autoloads from lsp-beancount.el
+
+(register-definition-prefixes "lsp-beancount" '("lsp-beancount-"))
+
+;;;***
+
+;;;### (autoloads nil "lsp-clangd" "lsp-clangd.el" (0 0 0 0))
+;;; Generated autoloads from lsp-clangd.el
+
+(autoload 'lsp-cpp-flycheck-clang-tidy-error-explainer "lsp-clangd" "\
+Explain a clang-tidy ERROR by scraping documentation from llvm.org.
+
+\(fn ERROR)" nil nil)
+
+(register-definition-prefixes "lsp-clangd" '("lsp-c"))
+
+;;;***
+
+;;;### (autoloads nil "lsp-clojure" "lsp-clojure.el" (0 0 0 0))
+;;; Generated autoloads from lsp-clojure.el
+
+(autoload 'lsp-clojure-show-test-tree "lsp-clojure" "\
+Show a test tree and focus on it if IGNORE-FOCUS? is nil.
+
+\(fn IGNORE-FOCUS\\=\\?)" t nil)
+
+(register-definition-prefixes "lsp-clojure" '("lsp-clojure-"))
+
+;;;***
+
+;;;### (autoloads nil "lsp-completion" "lsp-completion.el" (0 0 0
+;;;;;; 0))
+;;; Generated autoloads from lsp-completion.el
+
+(define-obsolete-variable-alias 'lsp-prefer-capf 'lsp-completion-provider "lsp-mode 7.0.1")
+
+(define-obsolete-variable-alias 'lsp-enable-completion-at-point 'lsp-completion-enable "lsp-mode 7.0.1")
+
+(autoload 'lsp-completion-at-point "lsp-completion" "\
+Get lsp completions." nil nil)
+
+(autoload 'lsp-completion--enable "lsp-completion" "\
+Enable LSP completion support." nil nil)
+
+(autoload 'lsp-completion-mode "lsp-completion" "\
+Toggle LSP completion support.
+
+This is a minor mode. If called interactively, toggle the
+`Lsp-Completion mode' mode. If the prefix argument is positive,
+enable the mode, and if it is zero or negative, disable the mode.
+
+If called from Lisp, toggle the mode if ARG is `toggle'. Enable
+the mode if ARG is nil, omitted, or is a positive number.
+Disable the mode if ARG is a negative number.
+
+To check whether the minor mode is enabled in the current buffer,
+evaluate `lsp-completion-mode'.
+
+The mode's hook is called both when the mode is enabled and when
+it is disabled.
+
+\(fn &optional ARG)" t nil)
+
+(add-hook 'lsp-configure-hook (lambda nil (when (and lsp-auto-configure lsp-completion-enable) (lsp-completion--enable))))
+
+(register-definition-prefixes "lsp-completion" '("lsp-"))
+
+;;;***
+
+;;;### (autoloads nil "lsp-crystal" "lsp-crystal.el" (0 0 0 0))
+;;; Generated autoloads from lsp-crystal.el
+
+(register-definition-prefixes "lsp-crystal" '("lsp-clients-crystal-executable"))
+
+;;;***
+
+;;;### (autoloads nil "lsp-csharp" "lsp-csharp.el" (0 0 0 0))
+;;; Generated autoloads from lsp-csharp.el
+
+(register-definition-prefixes "lsp-csharp" '("lsp-csharp-"))
+
+;;;***
+
+;;;### (autoloads nil "lsp-css" "lsp-css.el" (0 0 0 0))
+;;; Generated autoloads from lsp-css.el
+
+(register-definition-prefixes "lsp-css" '("lsp-css-"))
+
+;;;***
+
+;;;### (autoloads nil "lsp-diagnostics" "lsp-diagnostics.el" (0 0
+;;;;;; 0 0))
+;;; Generated autoloads from lsp-diagnostics.el
+
+(define-obsolete-variable-alias 'lsp-diagnostic-package 'lsp-diagnostics-provider "lsp-mode 7.0.1")
+
+(define-obsolete-variable-alias 'lsp-flycheck-default-level 'lsp-diagnostics-flycheck-default-level "lsp-mode 7.0.1")
+
+(autoload 'lsp-diagnostics-lsp-checker-if-needed "lsp-diagnostics" nil nil nil)
+
+(autoload 'lsp-diagnostics--enable "lsp-diagnostics" "\
+Enable LSP checker support." nil nil)
+
+(autoload 'lsp-diagnostics-mode "lsp-diagnostics" "\
+Toggle LSP diagnostics integration.
+
+This is a minor mode. If called interactively, toggle the
+`Lsp-Diagnostics mode' mode. If the prefix argument is positive,
+enable the mode, and if it is zero or negative, disable the mode.
+
+If called from Lisp, toggle the mode if ARG is `toggle'. Enable
+the mode if ARG is nil, omitted, or is a positive number.
+Disable the mode if ARG is a negative number.
+
+To check whether the minor mode is enabled in the current buffer,
+evaluate `lsp-diagnostics-mode'.
+
+The mode's hook is called both when the mode is enabled and when
+it is disabled.
+
+\(fn &optional ARG)" t nil)
+
+(add-hook 'lsp-configure-hook (lambda nil (when lsp-auto-configure (lsp-diagnostics--enable))))
+
+(register-definition-prefixes "lsp-diagnostics" '("lsp-diagnostics-"))
+
+;;;***
+
+;;;### (autoloads nil "lsp-dired" "lsp-dired.el" (0 0 0 0))
+;;; Generated autoloads from lsp-dired.el
+
+(defvar lsp-dired-mode nil "\
+Non-nil if Lsp-Dired mode is enabled.
+See the `lsp-dired-mode' command
+for a description of this minor mode.
+Setting this variable directly does not take effect;
+either customize it (see the info node `Easy Customization')
+or call the function `lsp-dired-mode'.")
+
+(custom-autoload 'lsp-dired-mode "lsp-dired" nil)
+
+(autoload 'lsp-dired-mode "lsp-dired" "\
+Display `lsp-mode' icons for each file in a dired buffer.
+
+This is a minor mode. If called interactively, toggle the
+`Lsp-Dired mode' mode. If the prefix argument is positive,
+enable the mode, and if it is zero or negative, disable the mode.
+
+If called from Lisp, toggle the mode if ARG is `toggle'. Enable
+the mode if ARG is nil, omitted, or is a positive number.
+Disable the mode if ARG is a negative number.
+
+To check whether the minor mode is enabled in the current buffer,
+evaluate `(default-value \\='lsp-dired-mode)'.
+
+The mode's hook is called both when the mode is enabled and when
+it is disabled.
+
+\(fn &optional ARG)" t nil)
+
+(register-definition-prefixes "lsp-dired" '("lsp-dired-"))
+
+;;;***
+
+;;;### (autoloads nil "lsp-dockerfile" "lsp-dockerfile.el" (0 0 0
+;;;;;; 0))
+;;; Generated autoloads from lsp-dockerfile.el
+
+(register-definition-prefixes "lsp-dockerfile" '("lsp-dockerfile-language-server-command"))
+
+;;;***
+
+;;;### (autoloads nil "lsp-elixir" "lsp-elixir.el" (0 0 0 0))
+;;; Generated autoloads from lsp-elixir.el
+
+(register-definition-prefixes "lsp-elixir" '("lsp-elixir-"))
+
+;;;***
+
+;;;### (autoloads nil "lsp-elm" "lsp-elm.el" (0 0 0 0))
+;;; Generated autoloads from lsp-elm.el
+
+(register-definition-prefixes "lsp-elm" '("lsp-"))
+
+;;;***
+
+;;;### (autoloads nil "lsp-emmet" "lsp-emmet.el" (0 0 0 0))
+;;; Generated autoloads from lsp-emmet.el
+
+(register-definition-prefixes "lsp-emmet" '("lsp-emmet-ls-command"))
+
+;;;***
+
+;;;### (autoloads nil "lsp-erlang" "lsp-erlang.el" (0 0 0 0))
+;;; Generated autoloads from lsp-erlang.el
+
+(register-definition-prefixes "lsp-erlang" '("lsp-erlang-server-"))
+
+;;;***
+
+;;;### (autoloads nil "lsp-eslint" "lsp-eslint.el" (0 0 0 0))
+;;; Generated autoloads from lsp-eslint.el
+
+(register-definition-prefixes "lsp-eslint" '("lsp-"))
+
+;;;***
+
+;;;### (autoloads nil "lsp-fortran" "lsp-fortran.el" (0 0 0 0))
+;;; Generated autoloads from lsp-fortran.el
+
+(register-definition-prefixes "lsp-fortran" '("lsp-clients-"))
+
+;;;***
+
+;;;### (autoloads nil "lsp-fsharp" "lsp-fsharp.el" (0 0 0 0))
+;;; Generated autoloads from lsp-fsharp.el
+
+(autoload 'lsp-fsharp--workspace-load "lsp-fsharp" "\
+Load all of the provided PROJECTS.
+
+\(fn PROJECTS)" nil nil)
+
+(register-definition-prefixes "lsp-fsharp" '("lsp-fsharp-"))
+
+;;;***
+
+;;;### (autoloads nil "lsp-gdscript" "lsp-gdscript.el" (0 0 0 0))
+;;; Generated autoloads from lsp-gdscript.el
+
+(register-definition-prefixes "lsp-gdscript" '("lsp-gdscript-"))
+
+;;;***
+
+;;;### (autoloads nil "lsp-go" "lsp-go.el" (0 0 0 0))
+;;; Generated autoloads from lsp-go.el
+
+(register-definition-prefixes "lsp-go" '("lsp-go-"))
+
+;;;***
+
+;;;### (autoloads nil "lsp-graphql" "lsp-graphql.el" (0 0 0 0))
+;;; Generated autoloads from lsp-graphql.el
+
+(register-definition-prefixes "lsp-graphql" '("lsp-"))
+
+;;;***
+
+;;;### (autoloads nil "lsp-groovy" "lsp-groovy.el" (0 0 0 0))
+;;; Generated autoloads from lsp-groovy.el
+
+(register-definition-prefixes "lsp-groovy" '("lsp-groovy-"))
+
+;;;***
+
+;;;### (autoloads nil "lsp-hack" "lsp-hack.el" (0 0 0 0))
+;;; Generated autoloads from lsp-hack.el
+
+(register-definition-prefixes "lsp-hack" '("lsp-clients-hack-command"))
+
+;;;***
+
+;;;### (autoloads nil "lsp-haxe" "lsp-haxe.el" (0 0 0 0))
+;;; Generated autoloads from lsp-haxe.el
+
+(register-definition-prefixes "lsp-haxe" '("lsp-"))
+
+;;;***
+
+;;;### (autoloads nil "lsp-headerline" "lsp-headerline.el" (0 0 0
+;;;;;; 0))
+;;; Generated autoloads from lsp-headerline.el
+
+(autoload 'lsp-headerline-breadcrumb-mode "lsp-headerline" "\
+Toggle breadcrumb on headerline.
+
+This is a minor mode. If called interactively, toggle the
+`Lsp-Headerline-Breadcrumb mode' mode. If the prefix argument is
+positive, enable the mode, and if it is zero or negative, disable
+the mode.
+
+If called from Lisp, toggle the mode if ARG is `toggle'. Enable
+the mode if ARG is nil, omitted, or is a positive number.
+Disable the mode if ARG is a negative number.
+
+To check whether the minor mode is enabled in the current buffer,
+evaluate `lsp-headerline-breadcrumb-mode'.
+
+The mode's hook is called both when the mode is enabled and when
+it is disabled.
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'lsp-breadcrumb-go-to-symbol "lsp-headerline" "\
+Go to the symbol on breadcrumb at SYMBOL-POSITION.
+
+\(fn SYMBOL-POSITION)" t nil)
+
+(autoload 'lsp-breadcrumb-narrow-to-symbol "lsp-headerline" "\
+Narrow to the symbol range on breadcrumb at SYMBOL-POSITION.
+
+\(fn SYMBOL-POSITION)" t nil)
+
+(register-definition-prefixes "lsp-headerline" '("lsp-headerline-"))
+
+;;;***
+
+;;;### (autoloads nil "lsp-html" "lsp-html.el" (0 0 0 0))
+;;; Generated autoloads from lsp-html.el
+
+(register-definition-prefixes "lsp-html" '("lsp-html-"))
+
+;;;***
+
+;;;### (autoloads nil "lsp-icons" "lsp-icons.el" (0 0 0 0))
+;;; Generated autoloads from lsp-icons.el
+
+(register-definition-prefixes "lsp-icons" '("lsp-"))
+
+;;;***
+
+;;;### (autoloads nil "lsp-ido" "lsp-ido.el" (0 0 0 0))
+;;; Generated autoloads from lsp-ido.el
+
+(autoload 'lsp-ido-workspace-symbol "lsp-ido" "\
+`ido' for lsp workspace/symbol.
+When called with prefix ARG the default selection will be symbol at point.
+
+\(fn ARG)" t nil)
+
+(register-definition-prefixes "lsp-ido" '("lsp-ido-"))
+
+;;;***
+
+;;;### (autoloads nil "lsp-idris" "lsp-idris.el" (0 0 0 0))
+;;; Generated autoloads from lsp-idris.el
+
+(register-definition-prefixes "lsp-idris" '("lsp-idris2-lsp-"))
+
+;;;***
+
+;;;### (autoloads nil "lsp-iedit" "lsp-iedit.el" (0 0 0 0))
+;;; Generated autoloads from lsp-iedit.el
+
+(autoload 'lsp-iedit-highlights "lsp-iedit" "\
+Start an `iedit' operation on the documentHighlights at point.
+This can be used as a primitive `lsp-rename' replacement if the
+language server doesn't support renaming.
+
+See also `lsp-enable-symbol-highlighting'." t nil)
+
+(autoload 'lsp-iedit-linked-ranges "lsp-iedit" "\
+Start an `iedit' for `textDocument/linkedEditingRange'" t nil)
+
+(autoload 'lsp-evil-multiedit-highlights "lsp-iedit" "\
+Start an `evil-multiedit' operation on the documentHighlights at point.
+This can be used as a primitive `lsp-rename' replacement if the
+language server doesn't support renaming.
+
+See also `lsp-enable-symbol-highlighting'." t nil)
+
+(autoload 'lsp-evil-multiedit-linked-ranges "lsp-iedit" "\
+Start an `evil-multiedit' for `textDocument/linkedEditingRange'" t nil)
+
+(autoload 'lsp-evil-state-highlights "lsp-iedit" "\
+Start `iedit-mode'. for `textDocument/documentHighlight'" t nil)
+
+(autoload 'lsp-evil-state-linked-ranges "lsp-iedit" "\
+Start `iedit-mode'. for `textDocument/linkedEditingRange'" t nil)
+
+(register-definition-prefixes "lsp-iedit" '("lsp-iedit--on-ranges"))
+
+;;;***
+
+;;;### (autoloads nil "lsp-javascript" "lsp-javascript.el" (0 0 0
+;;;;;; 0))
+;;; Generated autoloads from lsp-javascript.el
+
+(register-definition-prefixes "lsp-javascript" '("lsp-"))
+
+;;;***
+
+;;;### (autoloads nil "lsp-json" "lsp-json.el" (0 0 0 0))
+;;; Generated autoloads from lsp-json.el
+
+(register-definition-prefixes "lsp-json" '("lsp-"))
+
+;;;***
+
+;;;### (autoloads nil "lsp-kotlin" "lsp-kotlin.el" (0 0 0 0))
+;;; Generated autoloads from lsp-kotlin.el
+
+(register-definition-prefixes "lsp-kotlin" '("lsp-"))
+
+;;;***
+
+;;;### (autoloads nil "lsp-lens" "lsp-lens.el" (0 0 0 0))
+;;; Generated autoloads from lsp-lens.el
+
+(autoload 'lsp-lens--enable "lsp-lens" "\
+Enable lens mode." nil nil)
+
+(autoload 'lsp-lens-show "lsp-lens" "\
+Display lenses in the buffer." t nil)
+
+(autoload 'lsp-lens-hide "lsp-lens" "\
+Delete all lenses." t nil)
+
+(autoload 'lsp-lens-mode "lsp-lens" "\
+Toggle code-lens overlays.
+
+This is a minor mode. If called interactively, toggle the
+`Lsp-Lens mode' mode. If the prefix argument is positive, enable
+the mode, and if it is zero or negative, disable the mode.
+
+If called from Lisp, toggle the mode if ARG is `toggle'. Enable
+the mode if ARG is nil, omitted, or is a positive number.
+Disable the mode if ARG is a negative number.
+
+To check whether the minor mode is enabled in the current buffer,
+evaluate `lsp-lens-mode'.
+
+The mode's hook is called both when the mode is enabled and when
+it is disabled.
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'lsp-avy-lens "lsp-lens" "\
+Click lsp lens using `avy' package." t nil)
+
+(register-definition-prefixes "lsp-lens" '("lsp-"))
+
+;;;***
+
+;;;### (autoloads nil "lsp-lua" "lsp-lua.el" (0 0 0 0))
+;;; Generated autoloads from lsp-lua.el
+
+(register-definition-prefixes "lsp-lua" '("lsp-"))
+
+;;;***
+
+;;;### (autoloads nil "lsp-magik" "lsp-magik.el" (0 0 0 0))
+;;; Generated autoloads from lsp-magik.el
+
+(register-definition-prefixes "lsp-magik" '("lsp-magik-"))
+
+;;;***
+
+;;;### (autoloads nil "lsp-markdown" "lsp-markdown.el" (0 0 0 0))
+;;; Generated autoloads from lsp-markdown.el
+
+(register-definition-prefixes "lsp-markdown" '("lsp-markdown-"))
+
+;;;***
+
+;;;### (autoloads nil "lsp-mode" "lsp-mode.el" (0 0 0 0))
+;;; Generated autoloads from lsp-mode.el
+(put 'lsp-enable-file-watchers 'safe-local-variable #'booleanp)
+(put 'lsp-file-watch-ignored-directories 'safe-local-variable 'lsp--string-listp)
+(put 'lsp-file-watch-ignored-files 'safe-local-variable 'lsp--string-listp)
+(put 'lsp-file-watch-threshold 'safe-local-variable (lambda (i) (or (numberp i) (not i))))
+
+(autoload 'lsp--string-listp "lsp-mode" "\
+Return t if all elements of SEQUENCE are strings, else nil.
+
+\(fn SEQUENCE)" nil nil)
+
+(autoload 'lsp-load-vscode-workspace "lsp-mode" "\
+Load vscode workspace from FILE
+
+\(fn FILE)" t nil)
+
+(autoload 'lsp-save-vscode-workspace "lsp-mode" "\
+Save vscode workspace to FILE
+
+\(fn FILE)" t nil)
+
+(autoload 'lsp-install-server "lsp-mode" "\
+Interactively install or re-install server.
+When prefix UPDATE? is t force installation even if the server is present.
+
+\(fn UPDATE\\=\\? &optional SERVER-ID)" t nil)
+
+(autoload 'lsp-update-server "lsp-mode" "\
+Interactively update a server.
+
+\(fn &optional SERVER-ID)" t nil)
+
+(autoload 'lsp-ensure-server "lsp-mode" "\
+Ensure server SERVER-ID
+
+\(fn SERVER-ID)" nil nil)
+
+(autoload 'lsp "lsp-mode" "\
+Entry point for the server startup.
+When ARG is t the lsp mode will start new language server even if
+there is language server which can handle current language. When
+ARG is nil current file will be opened in multi folder language
+server if there is such. When `lsp' is called with prefix
+argument ask the user to select which language server to start.
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'lsp-deferred "lsp-mode" "\
+Entry point that defers server startup until buffer is visible.
+`lsp-deferred' will wait until the buffer is visible before invoking `lsp'.
+This avoids overloading the server with many files when starting Emacs." nil nil)
+
+(autoload 'lsp-start-plain "lsp-mode" "\
+Start `lsp-mode' using mininal configuration using the latest `melpa' version of the packages.
+
+In case the major-mode that you are using for " t nil)
+
+(register-definition-prefixes "lsp-mode" '("defcustom-lsp" "lsp-" "make-lsp-client" "when-lsp-workspace" "with-lsp-workspace"))
+
+;;;***
+
+;;;### (autoloads nil "lsp-modeline" "lsp-modeline.el" (0 0 0 0))
+;;; Generated autoloads from lsp-modeline.el
+
+(define-obsolete-variable-alias 'lsp-diagnostics-modeline-scope 'lsp-modeline-diagnostics-scope "lsp-mode 7.0.1")
+
+(autoload 'lsp-modeline-code-actions-mode "lsp-modeline" "\
+Toggle code actions on modeline.
+
+This is a minor mode. If called interactively, toggle the
+`Lsp-Modeline-Code-Actions mode' mode. If the prefix argument is
+positive, enable the mode, and if it is zero or negative, disable
+the mode.
+
+If called from Lisp, toggle the mode if ARG is `toggle'. Enable
+the mode if ARG is nil, omitted, or is a positive number.
+Disable the mode if ARG is a negative number.
+
+To check whether the minor mode is enabled in the current buffer,
+evaluate `lsp-modeline-code-actions-mode'.
+
+The mode's hook is called both when the mode is enabled and when
+it is disabled.
+
+\(fn &optional ARG)" t nil)
+
+(define-obsolete-function-alias 'lsp-diagnostics-modeline-mode 'lsp-modeline-diagnostics-mode "lsp-mode 7.0.1")
+
+(autoload 'lsp-modeline-diagnostics-mode "lsp-modeline" "\
+Toggle diagnostics modeline.
+
+This is a minor mode. If called interactively, toggle the
+`Lsp-Modeline-Diagnostics mode' mode. If the prefix argument is
+positive, enable the mode, and if it is zero or negative, disable
+the mode.
+
+If called from Lisp, toggle the mode if ARG is `toggle'. Enable
+the mode if ARG is nil, omitted, or is a positive number.
+Disable the mode if ARG is a negative number.
+
+To check whether the minor mode is enabled in the current buffer,
+evaluate `lsp-modeline-diagnostics-mode'.
+
+The mode's hook is called both when the mode is enabled and when
+it is disabled.
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'lsp-modeline-workspace-status-mode "lsp-modeline" "\
+Toggle workspace status on modeline.
+
+This is a minor mode. If called interactively, toggle the
+`Lsp-Modeline-Workspace-Status mode' mode. If the prefix
+argument is positive, enable the mode, and if it is zero or
+negative, disable the mode.
+
+If called from Lisp, toggle the mode if ARG is `toggle'. Enable
+the mode if ARG is nil, omitted, or is a positive number.
+Disable the mode if ARG is a negative number.
+
+To check whether the minor mode is enabled in the current buffer,
+evaluate `lsp-modeline-workspace-status-mode'.
+
+The mode's hook is called both when the mode is enabled and when
+it is disabled.
+
+\(fn &optional ARG)" t nil)
+
+(register-definition-prefixes "lsp-modeline" '("lsp-"))
+
+;;;***
+
+;;;### (autoloads nil "lsp-nginx" "lsp-nginx.el" (0 0 0 0))
+;;; Generated autoloads from lsp-nginx.el
+
+(register-definition-prefixes "lsp-nginx" '("lsp-nginx-server-command"))
+
+;;;***
+
+;;;### (autoloads nil "lsp-nim" "lsp-nim.el" (0 0 0 0))
+;;; Generated autoloads from lsp-nim.el
+
+(register-definition-prefixes "lsp-nim" '("lsp-nim-"))
+
+;;;***
+
+;;;### (autoloads nil "lsp-nix" "lsp-nix.el" (0 0 0 0))
+;;; Generated autoloads from lsp-nix.el
+
+(register-definition-prefixes "lsp-nix" '("lsp-nix-server-path"))
+
+;;;***
+
+;;;### (autoloads nil "lsp-ocaml" "lsp-ocaml.el" (0 0 0 0))
+;;; Generated autoloads from lsp-ocaml.el
+
+(register-definition-prefixes "lsp-ocaml" '("lsp-ocaml-l"))
+
+;;;***
+
+;;;### (autoloads nil "lsp-openscad" "lsp-openscad.el" (0 0 0 0))
+;;; Generated autoloads from lsp-openscad.el
+
+(register-definition-prefixes "lsp-openscad" '("lsp-openscad-server"))
+
+;;;***
+
+;;;### (autoloads nil "lsp-perl" "lsp-perl.el" (0 0 0 0))
+;;; Generated autoloads from lsp-perl.el
+
+(register-definition-prefixes "lsp-perl" '("lsp-perl-"))
+
+;;;***
+
+;;;### (autoloads nil "lsp-perlnavigator" "lsp-perlnavigator.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from lsp-perlnavigator.el
+
+(register-definition-prefixes "lsp-perlnavigator" '("lsp-perlnavigator-"))
+
+;;;***
+
+;;;### (autoloads nil "lsp-php" "lsp-php.el" (0 0 0 0))
+;;; Generated autoloads from lsp-php.el
+
+(register-definition-prefixes "lsp-php" '("lsp-"))
+
+;;;***
+
+;;;### (autoloads nil "lsp-prolog" "lsp-prolog.el" (0 0 0 0))
+;;; Generated autoloads from lsp-prolog.el
+
+(register-definition-prefixes "lsp-prolog" '("lsp-prolog-server-command"))
+
+;;;***
+
+;;;### (autoloads nil "lsp-protocol" "lsp-protocol.el" (0 0 0 0))
+;;; Generated autoloads from lsp-protocol.el
+
+(register-definition-prefixes "lsp-protocol" '("dash-expand:&RangeToPoint" "lsp"))
+
+;;;***
+
+;;;### (autoloads nil "lsp-purescript" "lsp-purescript.el" (0 0 0
+;;;;;; 0))
+;;; Generated autoloads from lsp-purescript.el
+
+(register-definition-prefixes "lsp-purescript" '("lsp-purescript-"))
+
+;;;***
+
+;;;### (autoloads nil "lsp-pwsh" "lsp-pwsh.el" (0 0 0 0))
+;;; Generated autoloads from lsp-pwsh.el
+
+(register-definition-prefixes "lsp-pwsh" '("lsp-pwsh-"))
+
+;;;***
+
+;;;### (autoloads nil "lsp-pyls" "lsp-pyls.el" (0 0 0 0))
+;;; Generated autoloads from lsp-pyls.el
+
+(register-definition-prefixes "lsp-pyls" '("lsp-"))
+
+;;;***
+
+;;;### (autoloads nil "lsp-pylsp" "lsp-pylsp.el" (0 0 0 0))
+;;; Generated autoloads from lsp-pylsp.el
+
+(register-definition-prefixes "lsp-pylsp" '("lsp-"))
+
+;;;***
+
+;;;### (autoloads nil "lsp-r" "lsp-r.el" (0 0 0 0))
+;;; Generated autoloads from lsp-r.el
+
+(register-definition-prefixes "lsp-r" '("lsp-clients-r-server-command"))
+
+;;;***
+
+;;;### (autoloads nil "lsp-racket" "lsp-racket.el" (0 0 0 0))
+;;; Generated autoloads from lsp-racket.el
+
+(register-definition-prefixes "lsp-racket" '("lsp-racket-lang"))
+
+;;;***
+
+;;;### (autoloads nil "lsp-remark" "lsp-remark.el" (0 0 0 0))
+;;; Generated autoloads from lsp-remark.el
+
+(register-definition-prefixes "lsp-remark" '("lsp-remark-server-command"))
+
+;;;***
+
+;;;### (autoloads nil "lsp-rf" "lsp-rf.el" (0 0 0 0))
+;;; Generated autoloads from lsp-rf.el
+
+(register-definition-prefixes "lsp-rf" '("expand-start-command" "lsp-rf-language-server-" "parse-rf-language-server-"))
+
+;;;***
+
+;;;### (autoloads nil "lsp-rust" "lsp-rust.el" (0 0 0 0))
+;;; Generated autoloads from lsp-rust.el
+
+(register-definition-prefixes "lsp-rust" '("lsp-"))
+
+;;;***
+
+;;;### (autoloads nil "lsp-semantic-tokens" "lsp-semantic-tokens.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from lsp-semantic-tokens.el
+
+(autoload 'lsp--semantic-tokens-initialize-buffer "lsp-semantic-tokens" "\
+Initialize the buffer for semantic tokens.
+IS-RANGE-PROVIDER is non-nil when server supports range requests." nil nil)
+
+(autoload 'lsp--semantic-tokens-initialize-workspace "lsp-semantic-tokens" "\
+Initialize semantic tokens for WORKSPACE.
+
+\(fn WORKSPACE)" nil nil)
+
+(autoload 'lsp-semantic-tokens--warn-about-deprecated-setting "lsp-semantic-tokens" "\
+Warn about deprecated semantic highlighting variable." nil nil)
+
+(autoload 'lsp-semantic-tokens--enable "lsp-semantic-tokens" "\
+Enable semantic tokens mode." nil nil)
+
+(autoload 'lsp-semantic-tokens-mode "lsp-semantic-tokens" "\
+Toggle semantic-tokens support.
+
+This is a minor mode. If called interactively, toggle the
+`Lsp-Semantic-Tokens mode' mode. If the prefix argument is
+positive, enable the mode, and if it is zero or negative, disable
+the mode.
+
+If called from Lisp, toggle the mode if ARG is `toggle'. Enable
+the mode if ARG is nil, omitted, or is a positive number.
+Disable the mode if ARG is a negative number.
+
+To check whether the minor mode is enabled in the current buffer,
+evaluate `lsp-semantic-tokens-mode'.
+
+The mode's hook is called both when the mode is enabled and when
+it is disabled.
+
+\(fn &optional ARG)" t nil)
+
+(register-definition-prefixes "lsp-semantic-tokens" '("lsp-"))
+
+;;;***
+
+;;;### (autoloads nil "lsp-solargraph" "lsp-solargraph.el" (0 0 0
+;;;;;; 0))
+;;; Generated autoloads from lsp-solargraph.el
+
+(register-definition-prefixes "lsp-solargraph" '("lsp-solargraph-"))
+
+;;;***
+
+;;;### (autoloads nil "lsp-sorbet" "lsp-sorbet.el" (0 0 0 0))
+;;; Generated autoloads from lsp-sorbet.el
+
+(register-definition-prefixes "lsp-sorbet" '("lsp-sorbet-"))
+
+;;;***
+
+;;;### (autoloads nil "lsp-sqls" "lsp-sqls.el" (0 0 0 0))
+;;; Generated autoloads from lsp-sqls.el
+
+(register-definition-prefixes "lsp-sqls" '("lsp-sql"))
+
+;;;***
+
+;;;### (autoloads nil "lsp-steep" "lsp-steep.el" (0 0 0 0))
+;;; Generated autoloads from lsp-steep.el
+
+(register-definition-prefixes "lsp-steep" '("lsp-steep-"))
+
+;;;***
+
+;;;### (autoloads nil "lsp-svelte" "lsp-svelte.el" (0 0 0 0))
+;;; Generated autoloads from lsp-svelte.el
+
+(register-definition-prefixes "lsp-svelte" '("lsp-svelte-plugin-"))
+
+;;;***
+
+;;;### (autoloads nil "lsp-terraform" "lsp-terraform.el" (0 0 0 0))
+;;; Generated autoloads from lsp-terraform.el
+
+(register-definition-prefixes "lsp-terraform" '("lsp-terraform-"))
+
+;;;***
+
+;;;### (autoloads nil "lsp-tex" "lsp-tex.el" (0 0 0 0))
+;;; Generated autoloads from lsp-tex.el
+
+(register-definition-prefixes "lsp-tex" '("lsp-"))
+
+;;;***
+
+;;;### (autoloads nil "lsp-toml" "lsp-toml.el" (0 0 0 0))
+;;; Generated autoloads from lsp-toml.el
+
+(register-definition-prefixes "lsp-toml" '("lsp-toml-"))
+
+;;;***
+
+;;;### (autoloads nil "lsp-ttcn3" "lsp-ttcn3.el" (0 0 0 0))
+;;; Generated autoloads from lsp-ttcn3.el
+
+(register-definition-prefixes "lsp-ttcn3" '("lsp-ttcn3-lsp-server-command"))
+
+;;;***
+
+;;;### (autoloads nil "lsp-typeprof" "lsp-typeprof.el" (0 0 0 0))
+;;; Generated autoloads from lsp-typeprof.el
+
+(register-definition-prefixes "lsp-typeprof" '("lsp-typeprof-"))
+
+;;;***
+
+;;;### (autoloads nil "lsp-v" "lsp-v.el" (0 0 0 0))
+;;; Generated autoloads from lsp-v.el
+
+(register-definition-prefixes "lsp-v" '("lsp-v-vls-executable"))
+
+;;;***
+
+;;;### (autoloads nil "lsp-vala" "lsp-vala.el" (0 0 0 0))
+;;; Generated autoloads from lsp-vala.el
+
+(register-definition-prefixes "lsp-vala" '("lsp-clients-vala-ls-executable"))
+
+;;;***
+
+;;;### (autoloads nil "lsp-verilog" "lsp-verilog.el" (0 0 0 0))
+;;; Generated autoloads from lsp-verilog.el
+
+(register-definition-prefixes "lsp-verilog" '("lsp-clients-"))
+
+;;;***
+
+;;;### (autoloads nil "lsp-vetur" "lsp-vetur.el" (0 0 0 0))
+;;; Generated autoloads from lsp-vetur.el
+
+(register-definition-prefixes "lsp-vetur" '("lsp-vetur-"))
+
+;;;***
+
+;;;### (autoloads nil "lsp-vhdl" "lsp-vhdl.el" (0 0 0 0))
+;;; Generated autoloads from lsp-vhdl.el
+
+(register-definition-prefixes "lsp-vhdl" '("ghdl-ls-bin-name" "hdl-checker-bin-name" "lsp-vhdl-" "vhdl-"))
+
+;;;***
+
+;;;### (autoloads nil "lsp-vimscript" "lsp-vimscript.el" (0 0 0 0))
+;;; Generated autoloads from lsp-vimscript.el
+
+(register-definition-prefixes "lsp-vimscript" '("lsp-clients-vim-"))
+
+;;;***
+
+;;;### (autoloads nil "lsp-volar" "lsp-volar.el" (0 0 0 0))
+;;; Generated autoloads from lsp-volar.el
+
+(register-definition-prefixes "lsp-volar" '("lsp-volar-"))
+
+;;;***
+
+;;;### (autoloads nil "lsp-xml" "lsp-xml.el" (0 0 0 0))
+;;; Generated autoloads from lsp-xml.el
+
+(register-definition-prefixes "lsp-xml" '("lsp-xml-"))
+
+;;;***
+
+;;;### (autoloads nil "lsp-yaml" "lsp-yaml.el" (0 0 0 0))
+;;; Generated autoloads from lsp-yaml.el
+
+(register-definition-prefixes "lsp-yaml" '("lsp-yaml-"))
+
+;;;***
+
+;;;### (autoloads nil "lsp-zig" "lsp-zig.el" (0 0 0 0))
+;;; Generated autoloads from lsp-zig.el
+
+(register-definition-prefixes "lsp-zig" '("lsp-zig-zls-executable"))
+
+;;;***
+
+;;;### (autoloads nil nil ("lsp-cmake.el" "lsp-d.el" "lsp-dhall.el"
+;;;;;; "lsp-mode-pkg.el" "lsp.el") (0 0 0 0))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; coding: utf-8
+;; End:
+;;; lsp-mode-autoloads.el ends here
diff --git a/elpa/lsp-mode-20220505.630/lsp-mode-pkg.el b/elpa/lsp-mode-20220505.630/lsp-mode-pkg.el
new file mode 100644
index 0000000..e470a6f
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-mode-pkg.el
@@ -0,0 +1,18 @@
+(define-package "lsp-mode" "20220505.630" "LSP mode"
+ '((emacs "26.1")
+ (dash "2.18.0")
+ (f "0.20.0")
+ (ht "2.3")
+ (spinner "1.7.3")
+ (markdown-mode "2.3")
+ (lv "0"))
+ :commit "6327359f3b5e19aeaa1c9ee6bd9b80b51f95f843" :authors
+ '(("Vibhav Pant, Fangrui Song, Ivan Yonchovski"))
+ :maintainer
+ '("Vibhav Pant, Fangrui Song, Ivan Yonchovski")
+ :keywords
+ '("languages")
+ :url "https://github.com/emacs-lsp/lsp-mode")
+;; Local Variables:
+;; no-byte-compile: t
+;; End:
diff --git a/elpa/lsp-mode-20220505.630/lsp-mode.el b/elpa/lsp-mode-20220505.630/lsp-mode.el
new file mode 100644
index 0000000..f560295
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-mode.el
@@ -0,0 +1,8997 @@
+;;; lsp-mode.el --- LSP mode -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2020 emacs-lsp maintainers
+
+;; Author: Vibhav Pant, Fangrui Song, Ivan Yonchovski
+;; Keywords: languages
+;; Package-Requires: ((emacs "26.1") (dash "2.18.0") (f "0.20.0") (ht "2.3") (spinner "1.7.3") (markdown-mode "2.3") (lv "0"))
+;; Version: 8.0.1
+
+;; URL: https://github.com/emacs-lsp/lsp-mode
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Emacs client/library for the Language Server Protocol
+
+;;; Code:
+
+(require 'cl-generic)
+(require 'cl-lib)
+(require 'compile)
+(require 'dash)
+(require 'epg)
+(require 'ewoc)
+(require 'f)
+(require 'filenotify)
+(require 'files)
+(require 'ht)
+(require 'imenu)
+(require 'inline)
+(require 'json)
+(require 'lv)
+(require 'markdown-mode)
+(require 'network-stream)
+(require 'pcase)
+(require 'rx)
+(require 's)
+(require 'seq)
+(require 'spinner)
+(require 'subr-x)
+(require 'tree-widget)
+(require 'url-parse)
+(require 'url-util)
+(require 'widget)
+(require 'xref)
+(require 'minibuffer)
+(require 'yasnippet nil t)
+(require 'lsp-protocol)
+
+(defgroup lsp-mode nil
+ "Language Server Protocol client."
+ :group 'tools
+ :tag "Language Server (lsp-mode)")
+
+(declare-function evil-set-command-property "ext:evil-common")
+(declare-function projectile-project-root "ext:projectile")
+(declare-function yas-expand-snippet "ext:yasnippet")
+(declare-function dap-mode "ext:dap-mode")
+(declare-function dap-auto-configure-mode "ext:dap-mode")
+
+(defvar yas-inhibit-overlay-modification-protection)
+(defvar yas-indent-line)
+(defvar yas-wrap-around-region)
+(defvar yas-also-auto-indent-first-line)
+(defvar dap-auto-configure-mode)
+(defvar dap-ui-menu-items)
+(defvar company-minimum-prefix-length)
+
+(defconst lsp--message-type-face
+ `((1 . ,compilation-error-face)
+ (2 . ,compilation-warning-face)
+ (3 . ,compilation-message-face)
+ (4 . ,compilation-info-face)))
+
+(defconst lsp--errors
+ '((-32700 "Parse Error")
+ (-32600 "Invalid Request")
+ (-32601 "Method not Found")
+ (-32602 "Invalid Parameters")
+ (-32603 "Internal Error")
+ (-32099 "Server Start Error")
+ (-32000 "Server End Error")
+ (-32002 "Server Not Initialized")
+ (-32001 "Unknown Error Code")
+ (-32800 "Request Cancelled"))
+ "Alist of error codes to user friendly strings.")
+
+(defconst lsp--empty-ht (make-hash-table))
+
+(eval-and-compile
+ (defun dash-expand:&lsp-wks (key source)
+ `(,(intern-soft (format "lsp--workspace-%s" (eval key))) ,source))
+
+ (defun dash-expand:&lsp-cln (key source)
+ `(,(intern-soft (format "lsp--client-%s" (eval key))) ,source)))
+
+(define-obsolete-variable-alias 'lsp-print-io 'lsp-log-io "lsp-mode 6.1")
+
+(defcustom lsp-log-io nil
+ "If non-nil, log all messages from the language server to a *lsp-log* buffer."
+ :group 'lsp-mode
+ :type 'boolean)
+
+(defcustom lsp-log-io-allowlist-methods '()
+ "The methods to filter before print to lsp-log-io."
+ :group 'lsp-mode
+ :type '(repeat string)
+ :package-version '(lsp-mode . "8.0.1"))
+
+(defcustom lsp-log-max message-log-max
+ "Maximum number of lines to keep in the log buffer.
+If nil, disable message logging. If t, log messages but don’t truncate
+the buffer when it becomes large."
+ :group 'lsp-mode
+ :type '(choice (const :tag "Disable" nil)
+ (integer :tag "lines")
+ (const :tag "Unlimited" t))
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-io-messages-max t
+ "Maximum number of messages that can be locked in a `lsp-io' buffer."
+ :group 'lsp-mode
+ :type '(choice (const :tag "Unlimited" t)
+ (integer :tag "Messages"))
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-keep-workspace-alive t
+ "If non nil keep workspace alive when the last workspace buffer is closed."
+ :group 'lsp-mode
+ :type 'boolean)
+
+(defcustom lsp-enable-snippet t
+ "Enable/disable snippet completion support."
+ :group 'lsp-completion
+ :type 'boolean)
+
+(defcustom lsp-enable-folding t
+ "Enable/disable code folding support."
+ :group 'lsp-mode
+ :type 'boolean
+ :package-version '(lsp-mode . "6.1"))
+
+(define-obsolete-variable-alias 'lsp-enable-semantic-highlighting 'lsp-semantic-tokens-enable "lsp-mode 8.0.0")
+
+(defcustom lsp-semantic-tokens-enable nil
+ "Enable/disable support for semantic tokens.
+As defined by the Language Server Protocol 3.16."
+ :group 'lsp-semantic-tokens
+ :type 'boolean)
+
+(defcustom lsp-folding-range-limit nil
+ "The maximum number of folding ranges to receive from the language server."
+ :group 'lsp-mode
+ :type '(choice (const :tag "No limit." nil)
+ (integer :tag "Number of lines."))
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-folding-line-folding-only nil
+ "If non-nil, only fold complete lines."
+ :group 'lsp-mode
+ :type 'boolean
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-client-packages
+ '(ccls lsp-actionscript lsp-ada lsp-angular lsp-ansible lsp-bash lsp-beancount lsp-clangd lsp-clojure
+ lsp-cmake lsp-crystal lsp-csharp lsp-css lsp-d lsp-dart lsp-dhall lsp-docker lsp-dockerfile
+ lsp-elm lsp-elixir lsp-emmet lsp-erlang lsp-eslint lsp-fortran lsp-fsharp lsp-gdscript lsp-go
+ lsp-graphql lsp-hack lsp-grammarly lsp-groovy lsp-haskell lsp-haxe lsp-idris lsp-java lsp-javascript
+ lsp-json lsp-kotlin lsp-latex lsp-ltex lsp-lua lsp-markdown lsp-nginx lsp-nim lsp-nix lsp-magik
+ lsp-metals lsp-mssql lsp-ocaml lsp-openscad lsp-pascal lsp-perl lsp-perlnavigator lsp-php lsp-pwsh lsp-pyls lsp-pylsp
+ lsp-pyright lsp-python-ms lsp-purescript lsp-r lsp-remark lsp-rf lsp-rust lsp-solargraph
+ lsp-sorbet lsp-sourcekit lsp-sonarlint lsp-tailwindcss lsp-tex lsp-terraform lsp-toml
+ lsp-ttcn3 lsp-typeprof lsp-v lsp-vala lsp-verilog lsp-vetur lsp-volar lsp-vhdl lsp-vimscript
+ lsp-xml lsp-yaml lsp-sqls lsp-svelte lsp-steep lsp-zig)
+ "List of the clients to be automatically required."
+ :group 'lsp-mode
+ :type '(repeat symbol))
+
+(defcustom lsp-progress-via-spinner t
+ "If non-nil, display LSP $/progress reports via a spinner in the modeline."
+ :group 'lsp-mode
+ :type 'boolean)
+
+(defvar-local lsp--cur-workspace nil)
+
+(defvar-local lsp--cur-version 0)
+(defvar-local lsp--virtual-buffer-connections nil)
+(defvar-local lsp--virtual-buffer nil)
+(defvar lsp--virtual-buffer-mappings (ht))
+
+(defvar lsp--uri-file-prefix (pcase system-type
+ (`windows-nt "file:///")
+ (_ "file://"))
+ "Prefix for a file-uri.")
+
+(defvar-local lsp-buffer-uri nil
+ "If set, return it instead of calculating it using `buffer-file-name'.")
+
+(define-error 'lsp-error "Unknown lsp-mode error")
+(define-error 'lsp-empty-response-error
+ "Empty response from the language server" 'lsp-error)
+(define-error 'lsp-timed-out-error
+ "Timed out while waiting for a response from the language server" 'lsp-error)
+(define-error 'lsp-capability-not-supported
+ "Capability not supported by the language server" 'lsp-error)
+(define-error 'lsp-file-scheme-not-supported
+ "Unsupported file scheme" 'lsp-error)
+(define-error 'lsp-client-already-exists-error
+ "A client with this server-id already exists" 'lsp-error)
+(define-error 'lsp-no-code-actions
+ "No code actions" 'lsp-error)
+
+(defcustom lsp-auto-guess-root nil
+ "Automatically guess the project root using projectile/project.
+Do *not* use this setting unless you are familiar with `lsp-mode'
+internals and you are sure that all of your projects are
+following `projectile'/`project.el' conventions."
+ :group 'lsp-mode
+ :type 'boolean)
+
+(defcustom lsp-restart 'interactive
+ "Defines how server-exited events must be handled."
+ :group 'lsp-mode
+ :type '(choice (const interactive)
+ (const auto-restart)
+ (const ignore)))
+
+(defcustom lsp-session-file (expand-file-name (locate-user-emacs-file ".lsp-session-v1"))
+ "File where session information is stored."
+ :group 'lsp-mode
+ :type 'file)
+
+(defcustom lsp-auto-configure t
+ "Auto configure `lsp-mode' main features.
+When set to t `lsp-mode' will auto-configure completion,
+code-actions, breadcrumb, `flycheck', `flymake', `imenu', symbol highlighting,
+lenses, links, and so on.
+
+For finer granularity you may use `lsp-enable-*' properties."
+ :group 'lsp-mode
+ :type 'boolean
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-disabled-clients nil
+ "A list of disabled/blacklisted clients.
+Each entry in the list can be either:
+a symbol, the server-id for the LSP client, or
+a cons pair (MAJOR-MODE . CLIENTS), where MAJOR-MODE is the major-mode,
+and CLIENTS is either a client or a list of clients.
+
+This option can also be used as a file- or directory-local variable to
+disable a language server for individual files or directories/projects
+respectively."
+ :group 'lsp-mode
+ :type '(repeat (symbol))
+ :safe 'listp
+ :package-version '(lsp-mode . "6.1"))
+
+(defvar lsp-clients (make-hash-table :test 'eql)
+ "Hash table server-id -> client.
+It contains all of the clients that are currently registered.")
+
+(defvar lsp-enabled-clients nil
+ "List of clients allowed to be used for projects.
+When nil, all registered clients are considered candidates.")
+
+(defvar lsp-last-id 0
+ "Last request id.")
+
+(defcustom lsp-before-initialize-hook nil
+ "List of functions to be called before a Language Server has been initialized
+for a new workspace."
+ :type 'hook
+ :group 'lsp-mode)
+
+(defcustom lsp-after-initialize-hook nil
+ "List of functions to be called after a Language Server has been initialized
+for a new workspace."
+ :type 'hook
+ :group 'lsp-mode)
+
+(defcustom lsp-before-open-hook nil
+ "List of functions to be called before a new file with LSP support is opened."
+ :type 'hook
+ :group 'lsp-mode)
+
+(defcustom lsp-after-open-hook nil
+ "List of functions to be called after a new file with LSP support is opened."
+ :type 'hook
+ :group 'lsp-mode)
+
+(defcustom lsp-enable-file-watchers t
+ "If non-nil lsp-mode will watch the files in the workspace if
+the server has requested that."
+ :type 'boolean
+ :group 'lsp-mode
+ :package-version '(lsp-mode . "6.1"))
+;;;###autoload(put 'lsp-enable-file-watchers 'safe-local-variable #'booleanp)
+
+(define-obsolete-variable-alias 'lsp-file-watch-ignored 'lsp-file-watch-ignored-directories "8.0.0")
+
+(defcustom lsp-file-watch-ignored-directories
+ '(; SCM tools
+ "[/\\\\]\\.git\\'"
+ "[/\\\\]\\.github\\'"
+ "[/\\\\]\\.circleci\\'"
+ "[/\\\\]\\.hg\\'"
+ "[/\\\\]\\.bzr\\'"
+ "[/\\\\]_darcs\\'"
+ "[/\\\\]\\.svn\\'"
+ "[/\\\\]_FOSSIL_\\'"
+ ;; IDE or build tools
+ "[/\\\\]\\.idea\\'"
+ "[/\\\\]\\.ensime_cache\\'"
+ "[/\\\\]\\.eunit\\'"
+ "[/\\\\]node_modules"
+ "[/\\\\]\\.yarn\\'"
+ "[/\\\\]\\.fslckout\\'"
+ "[/\\\\]\\.tox\\'"
+ "[/\\\\]dist\\'"
+ "[/\\\\]dist-newstyle\\'"
+ "[/\\\\]\\.stack-work\\'"
+ "[/\\\\]\\.bloop\\'"
+ "[/\\\\]\\.metals\\'"
+ "[/\\\\]target\\'"
+ "[/\\\\]\\.ccls-cache\\'"
+ "[/\\\\]\\.vscode\\'"
+ "[/\\\\]\\.venv\\'"
+ "[/\\\\]\\.mypy_cache\\'"
+ ;; Autotools output
+ "[/\\\\]\\.deps\\'"
+ "[/\\\\]build-aux\\'"
+ "[/\\\\]autom4te.cache\\'"
+ "[/\\\\]\\.reference\\'"
+ ;; Clojure
+ "[/\\\\]\\.lsp\\'"
+ "[/\\\\]\\.clj-kondo\\'"
+ "[/\\\\]\\.shadow-cljs\\'"
+ "[/\\\\]\\.babel_cache\\'"
+ "[/\\\\]\\.cpcache\\'"
+ "[/\\\\]\\checkouts\\'"
+ ;; Maven
+ "[/\\\\]\\.m2\\'"
+ ;; .Net Core build-output
+ "[/\\\\]bin/Debug\\'"
+ "[/\\\\]obj\\'"
+ ;; OCaml and Dune
+ "[/\\\\]_opam\\'"
+ "[/\\\\]_build\\'"
+ ;; Elixir
+ "[/\\\\]\\.elixir_ls\\'"
+ ;; nix-direnv
+ "[/\\\\]\\.direnv\\'")
+ "List of regexps matching directory paths which won't be monitored when
+creating file watches. Customization of this variable is only honored at
+the global level or at a root of an lsp workspace."
+ :group 'lsp-mode
+ :type '(repeat string)
+ :package-version '(lsp-mode . "8.0.0"))
+
+(define-obsolete-function-alias 'lsp-file-watch-ignored 'lsp-file-watch-ignored-directories "7.0.1")
+
+(defun lsp-file-watch-ignored-directories ()
+ lsp-file-watch-ignored-directories)
+
+;; Allow lsp-file-watch-ignored-directories as a file or directory-local variable
+;;;###autoload(put 'lsp-file-watch-ignored-directories 'safe-local-variable 'lsp--string-listp)
+
+(defcustom lsp-file-watch-ignored-files
+ '(
+ ;; Flycheck tempfiles
+ "[/\\\\]flycheck_[^/\\\\]+\\'"
+ ;; lockfiles
+ "[/\\\\]\\.#[^/\\\\]+\\'"
+ ;; backup files
+ "[/\\\\][^/\\\\]+~\\'" )
+ "List of regexps matching files for which change events will
+not be sent to the server.
+
+This setting has no impact on whether a file-watch is created for
+a directory; it merely prevents notifications pertaining to
+matched files from being sent to the server. To prevent a
+file-watch from being created for a directory, customize
+`lsp-file-watch-ignored-directories'
+
+Customization of this variable is only honored at the global
+level or at a root of an lsp workspace."
+ :group 'lsp-mode
+ :type '(repeat string)
+ :package-version '(lsp-mode . "8.0.0"))
+
+;; Allow lsp-file-watch-ignored-files as a file or directory-local variable
+;;;###autoload(put 'lsp-file-watch-ignored-files 'safe-local-variable 'lsp--string-listp)
+
+(defcustom lsp-after-uninitialized-functions nil
+ "List of functions to be called after a Language Server has been uninitialized."
+ :type 'hook
+ :group 'lsp-mode
+ :package-version '(lsp-mode . "6.3"))
+
+(defconst lsp--sync-none 0)
+(defconst lsp--sync-full 1)
+(defconst lsp--sync-incremental 2)
+
+(defcustom lsp-debounce-full-sync-notifications t
+ "If non-nil debounce full sync events.
+This flag affects only servers which do not support incremental updates."
+ :type 'boolean
+ :group 'lsp-mode
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-debounce-full-sync-notifications-interval 1.0
+ "Time to wait before sending full sync synchronization after buffer modification."
+ :type 'float
+ :group 'lsp-mode
+ :package-version '(lsp-mode . "6.1"))
+
+(defvar lsp--stderr-index 0)
+
+(defvar lsp--delayed-requests nil)
+(defvar lsp--delay-timer nil)
+
+(defcustom lsp-document-sync-method nil
+ "How to sync the document with the language server."
+ :type '(choice (const :tag "Documents should not be synced at all." nil)
+ (const :tag "Documents are synced by always sending the full content of the document." lsp--sync-full)
+ (const :tag "Documents are synced by always sending incremental changes to the document." lsp--sync-incremental)
+ (const :tag "Use the method recommended by the language server." nil))
+ :group 'lsp-mode)
+
+(defcustom lsp-auto-execute-action t
+ "Auto-execute single action."
+ :type 'boolean
+ :group 'lsp-mode)
+
+(defcustom lsp-enable-links t
+ "If non-nil, all references to links in a file will be made clickable, if
+supported by the language server."
+ :type 'boolean
+ :group 'lsp-mode
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-enable-imenu t
+ "If non-nil, automatically enable `imenu' integration when server provides
+`textDocument/documentSymbol'."
+ :type 'boolean
+ :group 'lsp-mode
+ :package-version '(lsp-mode . "6.2"))
+
+(defcustom lsp-enable-dap-auto-configure t
+ "If non-nil, enable `dap-auto-configure-mode`."
+ :type 'boolean
+ :group 'lsp-mode
+ :package-version '(lsp-mode . "7.0"))
+
+(defcustom lsp-eldoc-enable-hover t
+ "If non-nil, `eldoc' will display hover info when it is present."
+ :type 'boolean
+ :group 'lsp-mode)
+
+(defcustom lsp-eldoc-render-all nil
+ "Display all of the info returned by document/onHover.
+If this is set to nil, `eldoc' will show only the symbol information."
+ :type 'boolean
+ :group 'lsp-mode)
+
+(define-obsolete-variable-alias 'lsp-enable-completion-at-point
+ 'lsp-completion-enable "lsp-mode 7.0.1")
+
+(defcustom lsp-completion-enable t
+ "Enable `completion-at-point' integration."
+ :type 'boolean
+ :group 'lsp-completion)
+
+(defcustom lsp-enable-symbol-highlighting t
+ "Highlight references of the symbol at point."
+ :type 'boolean
+ :group 'lsp-mode)
+
+(defcustom lsp-enable-xref t
+ "Enable xref integration."
+ :type 'boolean
+ :group 'lsp-mode)
+
+(defcustom lsp-enable-indentation t
+ "Indent regions using the file formatting functionality provided by the
+language server."
+ :type 'boolean
+ :group 'lsp-mode)
+
+(defcustom lsp-enable-on-type-formatting t
+ "Enable `textDocument/onTypeFormatting' integration."
+ :type 'boolean
+ :group 'lsp-mode)
+
+(defcustom lsp-enable-text-document-color t
+ "Enable `textDocument/documentColor' integration."
+ :type 'boolean
+ :group 'lsp-mode)
+
+(defcustom lsp-before-save-edits t
+ "If non-nil, `lsp-mode' will apply edits suggested by the language server
+before saving a document."
+ :type 'boolean
+ :group 'lsp-mode)
+
+(defcustom lsp-after-apply-edits-hook nil
+ "Hooks to run when text edit is applied.
+It contains the operation source."
+ :type 'hook
+ :group 'lsp-mode
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-apply-edits-after-file-operations t
+ "Whether to apply edits returned by server after file operations if any.
+Applicable only if server supports workspace.fileOperations for operations:
+`workspace/willRenameFiles', `workspace/willCreateFiles' and
+`workspace/willDeleteFiles'."
+ :group 'lsp-mode
+ :type 'boolean)
+
+(defcustom lsp-modeline-code-actions-enable t
+ "Whether to show code actions on modeline."
+ :type 'boolean
+ :group 'lsp-modeline)
+
+(defcustom lsp-modeline-diagnostics-enable t
+ "Whether to show diagnostics on modeline."
+ :type 'boolean
+ :group 'lsp-modeline)
+
+(defcustom lsp-modeline-workspace-status-enable t
+ "Whether to show workspace status on modeline."
+ :type 'boolean
+ :group 'lsp-modeline
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-headerline-breadcrumb-enable t
+ "Whether to enable breadcrumb on headerline."
+ :type 'boolean
+ :group 'lsp-headerline)
+
+(defcustom lsp-configure-hook nil
+ "Hooks to run when `lsp-configure-buffer' is called."
+ :type 'hook
+ :group 'lsp-mode)
+
+(defcustom lsp-unconfigure-hook nil
+ "Hooks to run when `lsp-unconfig-buffer' is called."
+ :type 'hook
+ :group 'lsp-mode)
+
+(defcustom lsp-after-diagnostics-hook nil
+ "Hooks to run after diagnostics are received.
+Note: it runs only if the receiving buffer is open. Use
+`lsp-diagnostics-updated-hook'if you want to be notified when
+diagnostics have changed."
+ :type 'hook
+ :group 'lsp-mode)
+
+(define-obsolete-variable-alias 'lsp-after-diagnostics-hook
+ 'lsp-diagnostics-updated-hook "lsp-mode 6.4")
+
+(defcustom lsp-diagnostics-updated-hook nil
+ "Hooks to run after diagnostics are received."
+ :type 'hook
+ :group 'lsp-mode)
+
+(define-obsolete-variable-alias 'lsp-workspace-folders-changed-hook
+ 'lsp-workspace-folders-changed-functions "lsp-mode 6.3")
+
+(defcustom lsp-workspace-folders-changed-functions nil
+ "Hooks to run after the folders has changed.
+The hook will receive two parameters list of added and removed folders."
+ :type 'hook
+ :group 'lsp-mode)
+
+(defcustom lsp-eldoc-hook '(lsp-hover)
+ "Hooks to run for eldoc."
+ :type 'hook
+ :group 'lsp-mode)
+
+(defcustom lsp-before-apply-edits-hook nil
+ "Hooks to run before applying edits."
+ :type 'hook
+ :group 'lsp-mode)
+
+(defgroup lsp-imenu nil
+ "LSP Imenu."
+ :group 'lsp-mode
+ :tag "LSP Imenu")
+
+(defcustom lsp-imenu-show-container-name t
+ "Display the symbol's container name in an imenu entry."
+ :type 'boolean
+ :group 'lsp-imenu)
+
+(defcustom lsp-imenu-container-name-separator "/"
+ "Separator string to use to separate the container name from the symbol while
+displaying imenu entries."
+ :type 'string
+ :group 'lsp-imenu)
+
+(defcustom lsp-imenu-sort-methods '(kind name)
+ "How to sort the imenu items.
+
+The value is a list of `kind' `name' or `position'. Priorities
+are determined by the index of the element."
+ :type '(repeat (choice (const name)
+ (const position)
+ (const kind)))
+ :group 'lsp-imenu)
+
+(defcustom lsp-imenu-index-symbol-kinds nil
+ "Which symbol kinds to show in imenu."
+ :type '(repeat (choice (const :tag "Miscellaneous" nil)
+ (const :tag "File" File)
+ (const :tag "Module" Module)
+ (const :tag "Namespace" Namespace)
+ (const :tag "Package" Package)
+ (const :tag "Class" Class)
+ (const :tag "Method" Method)
+ (const :tag "Property" Property)
+ (const :tag "Field" Field)
+ (const :tag "Constructor" Constuctor)
+ (const :tag "Enum" Enum)
+ (const :tag "Interface" Interface)
+ (const :tag "Function" Function)
+ (const :tag "Variable" Variable)
+ (const :tag "Constant" Constant)
+ (const :tag "String" String)
+ (const :tag "Number" Number)
+ (const :tag "Boolean" Boolean)
+ (const :tag "Array" Array)
+ (const :tag "Object" Object)
+ (const :tag "Key" Key)
+ (const :tag "Null" Null)
+ (const :tag "Enum Member" EnumMember)
+ (const :tag "Struct" Struct)
+ (const :tag "Event" Event)
+ (const :tag "Operator" Operator)
+ (const :tag "Type Parameter" TypeParameter)))
+ :group 'lsp-imenu)
+
+;; vibhavp: Should we use a lower value (5)?
+(defcustom lsp-response-timeout 10
+ "Number of seconds to wait for a response from the language server before
+timing out. Nil if no timeout."
+ :type '(choice
+ (number :tag "Seconds")
+ (const :tag "No timeout" nil))
+ :group 'lsp-mode)
+
+(defcustom lsp-tcp-connection-timeout 2
+ "The timeout for tcp connection in seconds."
+ :type 'number
+ :group 'lsp-mode
+ :package-version '(lsp-mode . "6.2"))
+
+(defconst lsp--imenu-compare-function-alist
+ (list (cons 'name #'lsp--imenu-compare-name)
+ (cons 'kind #'lsp--imenu-compare-kind)
+ (cons 'position #'lsp--imenu-compare-line-col))
+ "An alist of (METHOD . FUNCTION).
+METHOD is one of the symbols accepted by
+`lsp-imenu-sort-methods'.
+
+FUNCTION takes two hash tables representing DocumentSymbol. It
+returns a negative number, 0, or a positive number indicating
+whether the first parameter is less than, equal to, or greater
+than the second parameter.")
+
+(defcustom lsp-diagnostic-clean-after-change nil
+ "When non-nil, clean the diagnostics on change.
+
+Note that when that setting is nil, `lsp-mode' will show stale
+diagnostics until server publishes the new set of diagnostics"
+ :type 'boolean
+ :group 'lsp-diagnostics
+ :package-version '(lsp-mode . "7.0.1"))
+
+(defcustom lsp-server-trace nil
+ "Request tracing on the server side.
+The actual trace output at each level depends on the language server in use.
+Changes take effect only when a new session is started."
+ :type '(choice (const :tag "Disabled" "off")
+ (const :tag "Messages only" "messages")
+ (const :tag "Verbose" "verbose")
+ (const :tag "Default (disabled)" nil))
+ :group 'lsp-mode
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-auto-touch-files t
+ "If non-nil ensure the files exist before sending
+`textDocument/didOpen' notification."
+ :type 'boolean
+ :group 'lsp-mode
+ :package-version '(lsp-mode . "8.0.1"))
+
+(defvar lsp-language-id-configuration '((".*\\.vue$" . "vue")
+ (".*\\.tsx$" . "typescriptreact")
+ (".*\\.ts$" . "typescript")
+ (".*\\.jsx$" . "javascriptreact")
+ (".*\\.js$" . "javascript")
+ (".*\\.xml$" . "xml")
+ (".*\\.hx$" . "haxe")
+ (".*\\.lua$" . "lua")
+ (".*\\.sql$" . "sql")
+ (".*\\.html$" . "html")
+ (".*\\.css" . "css")
+ (".*/settings.json$" . "jsonc")
+ (".*\\.json$" . "json")
+ (".*\\.jsonc$" . "jsonc")
+ (".*\\.php$" . "php")
+ (".*\\.svelte$" . "svelte")
+ (".*\\.ebuild$" . "shellscript")
+ (".*/PKGBUILD$" . "shellscript")
+ (".*\\.ttcn3$" . "ttcn3")
+ (ada-mode . "ada")
+ (nxml-mode . "xml")
+ (sql-mode . "sql")
+ (vimrc-mode . "vim")
+ (sh-mode . "shellscript")
+ (ebuild-mode . "shellscript")
+ (pkgbuild-mode . "shellscript")
+ (scala-mode . "scala")
+ (julia-mode . "julia")
+ (clojure-mode . "clojure")
+ (clojurec-mode . "clojure")
+ (clojurescript-mode . "clojurescript")
+ (java-mode . "java")
+ (jdee-mode . "java")
+ (groovy-mode . "groovy")
+ (python-mode . "python")
+ (cython-mode . "python")
+ (lsp--render-markdown . "markdown")
+ (rust-mode . "rust")
+ (rustic-mode . "rust")
+ (kotlin-mode . "kotlin")
+ (css-mode . "css")
+ (less-mode . "less")
+ (less-css-mode . "less")
+ (lua-mode . "lua")
+ (sass-mode . "sass")
+ (ssass-mode . "sass")
+ (scss-mode . "scss")
+ (scad-mode . "openscad")
+ (xml-mode . "xml")
+ (c-mode . "c")
+ (c++-mode . "cpp")
+ (objc-mode . "objective-c")
+ (html-mode . "html")
+ (sgml-mode . "html")
+ (mhtml-mode . "html")
+ (go-dot-mod-mode . "go.mod")
+ (go-mode . "go")
+ (graphql-mode . "graphql")
+ (haskell-mode . "haskell")
+ (hack-mode . "hack")
+ (php-mode . "php")
+ (powershell-mode . "powershell")
+ (powershell-mode . "PowerShell")
+ (json-mode . "json")
+ (jsonc-mode . "jsonc")
+ (rjsx-mode . "javascript")
+ (js2-mode . "javascript")
+ (js-mode . "javascript")
+ (typescript-mode . "typescript")
+ (fsharp-mode . "fsharp")
+ (reason-mode . "reason")
+ (caml-mode . "ocaml")
+ (tuareg-mode . "ocaml")
+ (swift-mode . "swift")
+ (elixir-mode . "elixir")
+ (conf-javaprop-mode . "spring-boot-properties")
+ (yaml-mode . "spring-boot-properties-yaml")
+ (ruby-mode . "ruby")
+ (enh-ruby-mode . "ruby")
+ (fortran-mode . "fortran")
+ (f90-mode . "fortran")
+ (elm-mode . "elm")
+ (dart-mode . "dart")
+ (erlang-mode . "erlang")
+ (dockerfile-mode . "dockerfile")
+ (csharp-mode . "csharp")
+ (csharp-tree-sitter-mode . "csharp")
+ (plain-tex-mode . "plaintex")
+ (latex-mode . "latex")
+ (v-mode . "v")
+ (vhdl-mode . "vhdl")
+ (verilog-mode . "verilog")
+ (terraform-mode . "terraform")
+ (ess-julia-mode . "julia")
+ (ess-r-mode . "r")
+ (crystal-mode . "crystal")
+ (nim-mode . "nim")
+ (dhall-mode . "dhall")
+ (cmake-mode . "cmake")
+ (purescript-mode . "purescript")
+ (gdscript-mode . "gdscript")
+ (perl-mode . "perl")
+ (cperl-mode . "perl")
+ (robot-mode . "robot")
+ (racket-mode . "racket")
+ (nix-mode . "nix")
+ (prolog-mode . "prolog")
+ (vala-mode . "vala")
+ (actionscript-mode . "actionscript")
+ (d-mode . "d")
+ (zig-mode . "zig")
+ (text-mode . "plaintext")
+ (markdown-mode . "markdown")
+ (gfm-mode . "markdown")
+ (beancount-mode . "beancount")
+ (conf-toml-mode . "toml")
+ (org-mode . "org")
+ (org-journal-mode . "org")
+ (nginx-mode . "nginx")
+ (magik-mode . "magik")
+ (idris-mode . "idris")
+ (idris2-mode . "idris2"))
+ "Language id configuration.")
+
+(defvar lsp--last-active-workspaces nil
+ "Keep track of last active workspace.
+We want to try the last workspace first when jumping into a library
+directory")
+
+(defvar lsp-method-requirements
+ '(("textDocument/callHierarchy" :capability :callHierarchyProvider)
+ ("textDocument/codeAction" :capability :codeActionProvider)
+ ("codeAction/resolve"
+ :check-command (lambda (workspace)
+ (with-lsp-workspace workspace
+ (lsp:code-action-options-resolve-provider?
+ (or (lsp--capability :codeActionProvider)
+ (when-let ((maybe-capability (lsp--registered-capability "textDocument/codeAction"))
+ (capability-options (lsp--registered-capability-options maybe-capability)))
+ capability-options))))))
+ ("textDocument/codeLens" :capability :codeLensProvider)
+ ("textDocument/completion" :capability :completionProvider)
+ ("completionItem/resolve"
+ :check-command (lambda (wk)
+ (with-lsp-workspace wk
+ (lsp:completion-options-resolve-provider?
+ (lsp--capability :completionProvider)))))
+ ("textDocument/declaration" :capability :declarationProvider)
+ ("textDocument/definition" :capability :definitionProvider)
+ ("textDocument/documentColor" :capability :colorProvider)
+ ("textDocument/documentLink" :capability :documentLinkProvider)
+ ("textDocument/documentHighlight" :capability :documentHighlightProvider)
+ ("textDocument/documentSymbol" :capability :documentSymbolProvider)
+ ("textDocument/foldingRange" :capability :foldingRangeProvider)
+ ("textDocument/formatting" :capability :documentFormattingProvider)
+ ("textDocument/hover" :capability :hoverProvider)
+ ("textDocument/implementation" :capability :implementationProvider)
+ ("textDocument/linkedEditingRange" :capability :linkedEditingRangeProvider)
+ ("textDocument/onTypeFormatting" :capability :documentOnTypeFormattingProvider)
+ ("textDocument/prepareRename"
+ :check-command (lambda (workspace)
+ (with-lsp-workspace workspace
+ (lsp:rename-options-prepare-provider?
+ (or (lsp--capability :renameProvider)
+ (when-let ((maybe-capability (lsp--registered-capability "textDocument/rename")))
+ (lsp--registered-capability-options maybe-capability)))))))
+ ("textDocument/rangeFormatting" :capability :documentRangeFormattingProvider)
+ ("textDocument/references" :capability :referencesProvider)
+ ("textDocument/rename" :capability :renameProvider)
+ ("textDocument/selectionRange" :capability :selectionRangeProvider)
+ ("textDocument/semanticTokens" :capability :semanticTokensProvider)
+ ("textDocument/semanticTokensFull"
+ :check-command (lambda (workspace)
+ (with-lsp-workspace workspace
+ (lsp-get (lsp--capability :semanticTokensProvider) :full))))
+ ("textDocument/semanticTokensFull/Delta"
+ :check-command (lambda (workspace)
+ (with-lsp-workspace workspace
+ (let ((capFull (lsp-get (lsp--capability :semanticTokensProvider) :full)))
+ (and (not (booleanp capFull)) (lsp-get capFull :delta))))))
+ ("textDocument/semanticTokensRangeProvider"
+ :check-command (lambda (workspace)
+ (with-lsp-workspace workspace
+ (lsp-get (lsp--capability :semanticTokensProvider) :range))))
+ ("textDocument/signatureHelp" :capability :signatureHelpProvider)
+ ("textDocument/typeDefinition" :capability :typeDefinitionProvider)
+ ("workspace/executeCommand" :capability :executeCommandProvider)
+ ("workspace/symbol" :capability :workspaceSymbolProvider))
+
+ "Map methods to requirements.
+It is used by request-sending functions to determine which server
+must be used for handling a particular message.")
+
+(defconst lsp--file-change-type
+ `((created . 1)
+ (changed . 2)
+ (deleted . 3)))
+
+(defconst lsp--watch-kind
+ `((create . 1)
+ (change . 2)
+ (delete . 4)))
+
+(defvar lsp-window-body-width 40
+ "Window body width when rendering doc.")
+
+(defface lsp-face-highlight-textual
+ '((t :inherit highlight))
+ "Face used for textual occurrences of symbols."
+ :group 'lsp-mode)
+
+(defface lsp-face-highlight-read
+ '((t :inherit highlight :underline t))
+ "Face used for highlighting symbols being read."
+ :group 'lsp-mode)
+
+(defface lsp-face-highlight-write
+ '((t :inherit highlight :weight bold))
+ "Face used for highlighting symbols being written to."
+ :group 'lsp-mode)
+
+(define-obsolete-variable-alias 'lsp-lens-auto-enable
+ 'lsp-lens-enable "lsp-mode 7.0.1")
+
+(defcustom lsp-lens-enable t
+ "Auto enable lenses if server supports."
+ :group 'lsp-lens
+ :type 'boolean
+ :package-version '(lsp-mode . "6.3"))
+
+(defcustom lsp-symbol-highlighting-skip-current nil
+ "If non-nil skip current symbol when setting symbol highlights."
+ :group 'lsp-mode
+ :type 'boolean)
+
+(defcustom lsp-file-watch-threshold 1000
+ "Show warning if the files to watch are more than.
+Set to nil to disable the warning."
+ :type 'number
+ :group 'lsp-mode)
+;;;###autoload(put 'lsp-file-watch-threshold 'safe-local-variable (lambda (i) (or (numberp i) (not i))))
+
+(defvar lsp-custom-markup-modes
+ '((rust-mode "no_run" "rust,no_run" "rust,ignore" "rust,should_panic"))
+ "Mode to uses with markdown code blocks.
+They are added to `markdown-code-lang-modes'")
+
+(defcustom lsp-signature-render-documentation t
+ "Display signature documentation in `eldoc'."
+ :type 'boolean
+ :group 'lsp-mode
+ :package-version '(lsp-mode . "6.2"))
+
+(defcustom lsp-signature-auto-activate '(:on-trigger-char :on-server-request)
+ "Auto activate signature conditions."
+ :type '(repeat (choice (const :tag "On trigger chars pressed." :on-trigger-char)
+ (const :tag "After selected completion." :after-completion)
+ (const :tag "When the server has sent show signature help." :on-server-request)))
+ :group 'lsp-mode
+ :package-version '(lsp-mode . "6.2"))
+
+(defcustom lsp-signature-doc-lines 20
+ "If number, limit the number of lines to show in the docs."
+ :type 'number
+ :group 'lsp-mode
+ :package-version '(lsp-mode . "6.3"))
+
+(defcustom lsp-signature-function 'lsp-lv-message
+ "The function used for displaying signature info.
+It will be called with one param - the signature info. When
+called with nil the signature info must be cleared."
+ :type 'function
+ :group 'lsp-mode
+ :package-version '(lsp-mode . "6.3"))
+
+(defcustom lsp-keymap-prefix "s-l"
+ "LSP-mode keymap prefix."
+ :group 'lsp-mode
+ :type 'string
+ :package-version '(lsp-mode . "6.3"))
+
+(defvar-local lsp--buffer-workspaces ()
+ "List of the buffer workspaces.")
+
+(defvar lsp--session nil
+ "Contain the `lsp-session' for the current Emacs instance.")
+
+(defvar lsp--tcp-port 10000)
+
+(defvar lsp--client-packages-required nil
+ "If nil, `lsp-client-packages' are yet to be required.")
+
+(defvar lsp--tcp-server-port 0
+ "The server socket which is opened when using `lsp-tcp-server' (a server
+socket is opened in Emacs and the language server connects to it). The
+default value of 0 ensures that a random high port is used. Set it to a positive
+integer to use a specific port.")
+
+(defvar lsp--tcp-server-wait-seconds 10
+ "Wait this amount of time for the client to connect to our server socket
+when using `lsp-tcp-server'.")
+
+(defvar-local lsp--document-symbols nil
+ "The latest document symbols.")
+
+(defvar-local lsp--document-selection-range-cache nil
+ "The document selection cache.")
+
+(defvar-local lsp--document-symbols-request-async nil
+ "If non-nil, request document symbols asynchronously.")
+
+(defvar-local lsp--document-symbols-tick -1
+ "The value of `buffer-chars-modified-tick' when document
+ symbols were last retrieved.")
+
+(defvar-local lsp--have-document-highlights nil
+ "Set to `t' on symbol highlighting, cleared on
+`lsp--cleanup-highlights-if-needed'. Checking a separately
+defined flag is substantially faster than unconditionally
+calling `remove-overlays'.")
+
+;; Buffer local variable for storing number of lines.
+(defvar lsp--log-lines)
+
+(defvar-local lsp--eldoc-saved-message nil)
+
+(defvar lsp--on-change-timer nil)
+(defvar lsp--on-idle-timer nil)
+
+(defvar-local lsp--signature-last nil)
+(defvar-local lsp--signature-last-index nil)
+(defvar lsp--signature-last-buffer nil)
+
+(defvar-local lsp--virtual-buffer-point-max nil)
+
+(cl-defgeneric lsp-execute-command (server command arguments)
+ "Ask SERVER to execute COMMAND with ARGUMENTS.")
+
+(defun lsp-elt (sequence n)
+ "Return Nth element of SEQUENCE or nil if N is out of range."
+ (cond
+ ((listp sequence) (elt sequence n))
+ ((arrayp sequence)
+ (and (> (length sequence) n) (aref sequence n)))
+ (t (and (> (length sequence) n) (elt sequence n)))))
+
+;; define seq-first and seq-rest for older emacs
+(defun lsp-seq-first (sequence)
+ "Return the first element of SEQUENCE."
+ (lsp-elt sequence 0))
+
+(defun lsp-seq-rest (sequence)
+ "Return a sequence of the elements of SEQUENCE except the first one."
+ (seq-drop sequence 1))
+
+;;;###autoload
+(defun lsp--string-listp (sequence)
+ "Return t if all elements of SEQUENCE are strings, else nil."
+ (not (seq-find (lambda (x) (not (stringp x))) sequence)))
+
+(defun lsp--string-vector-p (candidate)
+ "Returns true if CANDIDATE is a vector data structure and
+every element of it is of type string, else nil."
+ (and
+ (vectorp candidate)
+ (seq-every-p #'stringp candidate)))
+
+(make-obsolete 'lsp--string-vector-p nil "lsp-mode 8.0.0")
+
+(defun lsp--editable-vector-match (widget value)
+ "Function for `lsp-editable-vector' :match."
+ ;; Value must be a list or a vector and all the members must match the type.
+ (and (or (listp value) (vectorp value))
+ (length (cdr (lsp--editable-vector-match-inline widget value)))))
+
+(defun lsp--editable-vector-match-inline (widget value)
+ "Value for `lsp-editable-vector' :match-inline."
+ (let ((type (nth 0 (widget-get widget :args)))
+ (ok t)
+ found)
+ (while (and value ok)
+ (let ((answer (widget-match-inline type value)))
+ (if answer
+ (let ((head (if (vectorp answer) (aref answer 0) (car answer)))
+ (tail (if (vectorp answer) (seq-drop 1 answer) (cdr answer))))
+ (setq found (append found head)
+ value tail))
+ (setq ok nil))))
+ (cons found value)))
+
+(defun lsp--editable-vector-value-to-external (_widget internal-value)
+ "Convert the internal list value to a vector."
+ (if (listp internal-value)
+ (apply 'vector internal-value)
+ internal-value))
+
+(defun lsp--editable-vector-value-to-internal (_widget external-value)
+ "Convert the external vector value to a list."
+ (if (vectorp external-value)
+ (append external-value nil)
+ external-value))
+
+(define-widget 'lsp--editable-vector 'editable-list
+ "A subclass of `editable-list' that accepts and returns a
+vector instead of a list."
+ :value-to-external 'lsp--editable-vector-value-to-external
+ :value-to-internal 'lsp--editable-vector-value-to-internal
+ :match 'lsp--editable-vector-match
+ :match-inline 'lsp--editable-vector-match-inline)
+
+(define-widget 'lsp-repeatable-vector 'lsp--editable-vector
+ "A variable length homogeneous vector."
+ :tag "Repeat"
+ :format "%{%t%}:\n%v%i\n")
+
+(define-widget 'lsp-string-vector 'lazy
+ "A vector of zero or more elements, every element of which is a string.
+Appropriate for any language-specific `defcustom' that needs to
+serialize as a JSON array of strings.
+
+Deprecated. Use `lsp-repeatable-vector' instead. "
+ :offset 4
+ :tag "Vector"
+ :type '(lsp-repeatable-vector string))
+
+(make-obsolete 'lsp-string-vector nil "lsp-mode 8.0.0")
+
+(defvar lsp--show-message t
+ "If non-nil, show debug message from `lsp-mode'.")
+
+(defun lsp--message (format &rest args)
+ "Wrapper for `message'
+
+We `inhibit-message' the message when the cursor is in the
+minibuffer and when emacs version is before emacs 27 due to the
+fact that we often use `lsp--info', `lsp--warn' and `lsp--error'
+in async context and the call to these function is removing the
+minibuffer prompt. The issue with async messages is already fixed
+in emacs 27.
+
+See #2049"
+ (when lsp--show-message
+ (let ((inhibit-message (and (minibufferp)
+ (version< emacs-version "27.0"))))
+ (apply #'message format args))))
+
+(defun lsp--info (format &rest args)
+ "Display lsp info message with FORMAT with ARGS."
+ (lsp--message "%s :: %s" (propertize "LSP" 'face 'success) (apply #'format format args)))
+
+(defun lsp--warn (format &rest args)
+ "Display lsp warn message with FORMAT with ARGS."
+ (lsp--message "%s :: %s" (propertize "LSP" 'face 'warning) (apply #'format format args)))
+
+(defun lsp--error (format &rest args)
+ "Display lsp error message with FORMAT with ARGS."
+ (lsp--message "%s :: %s" (propertize "LSP" 'face 'error) (apply #'format format args)))
+
+(defun lsp--eldoc-message (&optional msg)
+ "Show MSG in eldoc."
+ (setq lsp--eldoc-saved-message msg)
+ (run-with-idle-timer 0 nil (lambda ()
+ ;; XXX: new eldoc in Emacs 28
+ ;; recommends running the hook variable
+ ;; `eldoc-documentation-functions'
+ ;; instead of using eldoc-message
+ (with-no-warnings
+ (eldoc-message msg)))))
+
+(defun lsp-log (format &rest args)
+ "Log message to the ’*lsp-log*’ buffer.
+
+FORMAT and ARGS i the same as for `message'."
+ (when lsp-log-max
+ (let ((log-buffer (get-buffer "*lsp-log*"))
+ (inhibit-read-only t))
+ (unless log-buffer
+ (setq log-buffer (get-buffer-create "*lsp-log*"))
+ (with-current-buffer log-buffer
+ (buffer-disable-undo)
+ (view-mode 1)
+ (set (make-local-variable 'lsp--log-lines) 0)))
+ (with-current-buffer log-buffer
+ (save-excursion
+ (let* ((message (apply 'format format args))
+ ;; Count newlines in message.
+ (newlines (1+ (cl-loop with start = 0
+ for count from 0
+ while (string-match "\n" message start)
+ do (setq start (match-end 0))
+ finally return count))))
+ (goto-char (point-max))
+
+ ;; in case the buffer is not empty insert before last \n to preserve
+ ;; the point position(in case it is in the end)
+ (if (eq (point) (point-min))
+ (progn
+ (insert "\n")
+ (backward-char))
+ (backward-char)
+ (insert "\n"))
+ (insert message)
+
+ (setq lsp--log-lines (+ lsp--log-lines newlines))
+
+ (when (and (integerp lsp-log-max) (> lsp--log-lines lsp-log-max))
+ (let ((to-delete (- lsp--log-lines lsp-log-max)))
+ (goto-char (point-min))
+ (forward-line to-delete)
+ (delete-region (point-min) (point))
+ (setq lsp--log-lines lsp-log-max)))))))))
+
+(defalias 'lsp-message 'lsp-log)
+
+(defalias 'lsp-ht 'ht)
+
+(defalias 'lsp-file-local-name 'file-local-name)
+
+(defun lsp-f-canonical (file-name)
+ "Return the canonical FILE-NAME, without a trailing slash."
+ (directory-file-name (expand-file-name file-name)))
+
+(defalias 'lsp-canonical-file-name 'lsp-f-canonical)
+
+(defun lsp-f-same? (path-a path-b)
+ "Return t if PATH-A and PATH-B are references to the same file.
+Symlinks are not followed."
+ (when (and (f-exists? path-a)
+ (f-exists? path-b))
+ (equal
+ (lsp-f-canonical (directory-file-name (f-expand path-a)))
+ (lsp-f-canonical (directory-file-name (f-expand path-b))))))
+
+(defun lsp-f-parent (path)
+ "Return the parent directory to PATH.
+Symlinks are not followed."
+ (let ((parent (file-name-directory
+ (directory-file-name (f-expand path default-directory)))))
+ (unless (lsp-f-same? path parent)
+ (if (f-relative? path)
+ (f-relative parent)
+ (directory-file-name parent)))))
+
+(defun lsp-f-ancestor-of? (path-a path-b)
+ "Return t if PATH-A is an ancestor of PATH-B.
+Symlinks are not followed."
+ (unless (lsp-f-same? path-a path-b)
+ (s-prefix? (concat (lsp-f-canonical path-a) (f-path-separator))
+ (lsp-f-canonical path-b))))
+
+(defun lsp--merge-results (results method)
+ "Merge RESULTS by filtering the empty hash-tables and merging
+the lists according to METHOD."
+ (pcase (--map (if (vectorp it)
+ (append it nil) it)
+ (-filter #'identity results))
+ (`() ())
+ ;; only one result - simply return it
+ (`(,fst) fst)
+ ;; multiple results merge it based on strategy
+ (results
+ (pcase method
+ ("textDocument/hover" (pcase (seq-filter
+ (-compose #'not #'lsp-empty?)
+ results)
+ (`(,hover) hover)
+ (hovers (lsp-make-hover
+ :contents
+ (-mapcat
+ (-lambda ((&Hover :contents))
+ (if (and (sequencep contents)
+ (not (stringp contents)))
+ (append contents ())
+ (list contents)))
+ hovers)))))
+ ("textDocument/completion"
+ (lsp-make-completion-list
+ :is-incomplete (seq-some
+ #'lsp:completion-list-is-incomplete
+ results)
+ :items (cl-mapcan (lambda (it) (append (if (lsp-completion-list? it)
+ (lsp:completion-list-items it)
+ it)
+ nil))
+ results)))
+ ("completionItem/resolve"
+ (let ((item (cl-first results)))
+ (when-let ((details (seq-filter #'identity
+ (seq-map #'lsp:completion-item-detail? results))))
+ (lsp:set-completion-item-detail?
+ item
+ (string-join details " ")))
+ (when-let ((docs (seq-filter #'identity
+ (seq-map #'lsp:completion-item-documentation? results))))
+ (lsp:set-completion-item-documentation?
+ item
+ (lsp-make-markup-content
+ :kind (or (seq-some (lambda (it)
+ (when (equal (lsp:markup-content-kind it)
+ lsp/markup-kind-markdown)
+ lsp/markup-kind-markdown))
+ docs)
+ lsp/markup-kind-plain-text)
+ :value (string-join (seq-map (lambda (doc)
+ (or (lsp:markup-content-value doc)
+ (and (stringp doc) doc)))
+ docs)
+ "\n"))))
+ (when-let ((edits (seq-filter #'identity
+ (seq-map #'lsp:completion-item-additional-text-edits? results))))
+ (lsp:set-completion-item-additional-text-edits?
+ item
+ (cl-mapcan (lambda (it) (if (seqp it) it (list it))) edits)))
+ item))
+ (_ (cl-mapcan (lambda (it) (if (seqp it) it (list it))) results))))))
+
+(defun lsp--spinner-start ()
+ "Start spinner indication."
+ (condition-case _err (spinner-start 'progress-bar-filled) (error)))
+
+(defun lsp--propertize (str type)
+ "Propertize STR as per TYPE."
+ (propertize str 'face (alist-get type lsp--message-type-face)))
+
+(defun lsp-workspaces ()
+ "Return the lsp workspaces associated with the current project."
+ (if lsp--cur-workspace (list lsp--cur-workspace) lsp--buffer-workspaces))
+
+(defun lsp--completing-read (prompt collection transform-fn &optional predicate
+ require-match initial-input
+ hist def inherit-input-method)
+ "Wrap `completing-read' to provide transformation function and disable sort.
+
+TRANSFORM-FN will be used to transform each of the items before displaying.
+
+PROMPT COLLECTION PREDICATE REQUIRE-MATCH INITIAL-INPUT HIST DEF
+INHERIT-INPUT-METHOD will be proxied to `completing-read' without changes."
+ (let* ((col (--map (cons (funcall transform-fn it) it) collection))
+ (completion (completing-read prompt
+ (lambda (string pred action)
+ (if (eq action 'metadata)
+ `(metadata (display-sort-function . identity))
+ (complete-with-action action col string pred)))
+ predicate require-match initial-input hist
+ def inherit-input-method)))
+ (cdr (assoc completion col))))
+
+(defmacro lsp-with-current-buffer (buffer-id &rest body)
+ (declare (indent 1) (debug t))
+ `(if-let ((wcb (plist-get ,buffer-id :with-current-buffer)))
+ (with-lsp-workspaces (plist-get ,buffer-id :workspaces)
+ (funcall wcb (lambda () ,@body)))
+ (with-current-buffer ,buffer-id
+ ,@body)))
+
+(defvar lsp--throw-on-input nil
+ "Make `lsp-*-while-no-input' throws `input' on interrupted.")
+
+(defmacro lsp--catch (tag bodyform &rest handlers)
+ "Catch TAG thrown in BODYFORM.
+The return value from TAG will be handled in HANDLERS by `pcase'."
+ (declare (debug (form form &rest (pcase-PAT body))) (indent 2))
+ (let ((re-sym (make-symbol "re")))
+ `(let ((,re-sym (catch ,tag ,bodyform)))
+ (pcase ,re-sym
+ ,@handlers))))
+
+(defmacro lsp--while-no-input (&rest body)
+ "Wrap BODY in `while-no-input' and respecting `non-essential'.
+If `lsp--throw-on-input' is set, will throw if input is pending, else
+return value of `body' or nil if interrupted."
+ (declare (debug t) (indent 0))
+ `(if non-essential
+ (let ((res (while-no-input ,@body)))
+ (cond
+ ((and lsp--throw-on-input (equal res t))
+ (throw 'input :interrupted))
+ ((booleanp res) nil)
+ (t res)))
+ ,@body))
+
+;; A ‘lsp--client’ object describes the client-side behavior of a language
+;; server. It is used to start individual server processes, each of which is
+;; represented by a ‘lsp--workspace’ object. Client objects are normally
+;; created using ‘lsp-define-stdio-client’ or ‘lsp-define-tcp-client’. Each
+;; workspace refers to exactly one client, but there can be multiple workspaces
+;; for a single client.
+(cl-defstruct lsp--client
+ ;; ‘language-id’ is a function that receives a buffer as a single argument
+ ;; and should return the language identifier for that buffer. See
+ ;; https://microsoft.github.io/language-server-protocol/specification#textdocumentitem
+ ;; for a list of language identifiers. Also consult the documentation for
+ ;; the language server represented by this client to find out what language
+ ;; identifiers it supports or expects.
+ (language-id nil)
+
+ ;; ‘add-on?’ when set to t the server will be started no matter whether there
+ ;; is another server handling the same mode.
+ (add-on? nil)
+ ;; ‘new-connection’ is a function that should start a language server process
+ ;; and return a cons (COMMAND-PROCESS . COMMUNICATION-PROCESS).
+ ;; COMMAND-PROCESS must be a process object representing the server process
+ ;; just started. COMMUNICATION-PROCESS must be a process (including pipe and
+ ;; network processes) that ‘lsp-mode’ uses to communicate with the language
+ ;; server using the language server protocol. COMMAND-PROCESS and
+ ;; COMMUNICATION-PROCESS may be the same process; in that case
+ ;; ‘new-connection’ may also return that process as a single
+ ;; object. ‘new-connection’ is called with two arguments, FILTER and
+ ;; SENTINEL. FILTER should be used as process filter for
+ ;; COMMUNICATION-PROCESS, and SENTINEL should be used as process sentinel for
+ ;; COMMAND-PROCESS.
+ (new-connection nil)
+
+ ;; ‘ignore-regexps’ is a list of regexps. When a data packet from the
+ ;; language server matches any of these regexps, it will be ignored. This is
+ ;; intended for dealing with language servers that output non-protocol data.
+ (ignore-regexps nil)
+
+ ;; ‘ignore-messages’ is a list of regexps. When a message from the language
+ ;; server matches any of these regexps, it will be ignored. This is useful
+ ;; for filtering out unwanted messages; such as servers that send nonstandard
+ ;; message types, or extraneous log messages.
+ (ignore-messages nil)
+
+ ;; ‘notification-handlers’ is a hash table mapping notification method names
+ ;; (strings) to functions handling the respective notifications. Upon
+ ;; receiving a notification, ‘lsp-mode’ will call the associated handler
+ ;; function passing two arguments, the ‘lsp--workspace’ object and the
+ ;; deserialized notification parameters.
+ (notification-handlers (make-hash-table :test 'equal))
+
+ ;; ‘request-handlers’ is a hash table mapping request method names
+ ;; (strings) to functions handling the respective notifications. Upon
+ ;; receiving a request, ‘lsp-mode’ will call the associated handler function
+ ;; passing two arguments, the ‘lsp--workspace’ object and the deserialized
+ ;; request parameters.
+ (request-handlers (make-hash-table :test 'equal))
+
+ ;; ‘response-handlers’ is a hash table mapping integral JSON-RPC request
+ ;; identifiers for pending asynchronous requests to functions handling the
+ ;; respective responses. Upon receiving a response from the language server,
+ ;; ‘lsp-mode’ will call the associated response handler function with a
+ ;; single argument, the deserialized response parameters.
+ (response-handlers (make-hash-table :test 'eql))
+
+ ;; ‘prefix-function’ is called for getting the prefix for completion.
+ ;; The function takes no parameter and returns a cons (start . end) representing
+ ;; the start and end bounds of the prefix. If it's not set, the client uses a
+ ;; default prefix function."
+ (prefix-function nil)
+
+ ;; Contains mapping of scheme to the function that is going to be used to load
+ ;; the file.
+ (uri-handlers (make-hash-table :test #'equal))
+
+ ;; ‘action-handlers’ is a hash table mapping action to a handler function. It
+ ;; can be used in `lsp-execute-code-action' to determine whether the action
+ ;; current client is interested in executing the action instead of sending it
+ ;; to the server.
+ (action-handlers (make-hash-table :test 'equal))
+
+ ;; major modes supported by the client.
+ major-modes
+ ;; Function that will be called to decide if this language client
+ ;; should manage a particular buffer. The function will be passed
+ ;; the file name and major mode to inform the decision. Setting
+ ;; `activation-fn' will override `major-modes', if
+ ;; present.
+ activation-fn
+ ;; Break the tie when major-mode is supported by multiple clients.
+ (priority 0)
+ ;; Unique identifier for representing the client object.
+ server-id
+ ;; defines whether the client supports multi root workspaces.
+ multi-root
+ ;; Initialization options or a function that returns initialization options.
+ initialization-options
+ ;; Overrides semantic tokens faces for specific clients
+ semantic-tokens-faces-overrides
+ ;; Provides support for registering LSP Server specific capabilities.
+ custom-capabilities
+ ;; Function which returns the folders that are considered to be not projects but library files.
+ ;; The function accepts one parameter currently active workspace.
+ ;; See: https://github.com/emacs-lsp/lsp-mode/issues/225.
+ library-folders-fn
+ ;; function which will be called when opening file in the workspace to perform
+ ;; client specific initialization. The function accepts one parameter
+ ;; currently active workspace.
+ before-file-open-fn
+ ;; Function which will be called right after a workspace has been initialized.
+ initialized-fn
+ ;; ‘remote?’ indicate whether the client can be used for LSP server over TRAMP.
+ (remote? nil)
+
+ ;; ‘completion-in-comments?’ t if the client supports completion in comments.
+ (completion-in-comments? nil)
+
+ ;; ‘path->uri-fn’ the function to use for path->uri conversion for the client.
+ (path->uri-fn nil)
+
+ ;; ‘uri->path-fn’ the function to use for uri->path conversion for the client.
+ (uri->path-fn nil)
+ ;; Function that returns an environment structure that will be used
+ ;; to set some environment variables when starting the language
+ ;; server process. These environment variables enable some
+ ;; additional features in the language server. The environment
+ ;; structure is an alist of the form (KEY . VALUE), where KEY is a
+ ;; string (regularly in all caps), and VALUE may be a string, a
+ ;; boolean, or a sequence of strings.
+ environment-fn
+
+ ;; ‘after-open-fn’ workspace after open specific hooks.
+ (after-open-fn nil)
+
+ ;; ‘async-request-handlers’ is a hash table mapping request method names
+ ;; (strings) to functions handling the respective requests that may take
+ ;; time to finish. Upon receiving a request, ‘lsp-mode’ will call the
+ ;; associated handler function passing three arguments, the ‘lsp--workspace’
+ ;; object, the deserialized request parameters and the callback which accept
+ ;; result as its parameter.
+ (async-request-handlers (make-hash-table :test 'equal))
+ download-server-fn
+ download-in-progress?
+ buffers
+ synchronize-sections)
+
+(defun lsp-clients-executable-find (find-command &rest args)
+ "Finds an executable by invoking a search command.
+
+FIND-COMMAND is the executable finder that searches for the
+actual language server executable. ARGS is a list of arguments to
+give to FIND-COMMAND to find the language server. Returns the
+output of FIND-COMMAND if it exits successfully, nil otherwise.
+
+Typical uses include finding an executable by invoking 'find' in
+a project, finding LLVM commands on macOS with 'xcrun', or
+looking up project-specific language servers for projects written
+in the various dynamic languages, e.g. 'nvm', 'pyenv' and 'rbenv'
+etc."
+ (when-let* ((find-command-path (executable-find find-command))
+ (executable-path
+ (with-temp-buffer
+ (when (zerop (apply 'call-process find-command-path nil t nil args))
+ (buffer-substring-no-properties (point-min) (point-max))))))
+ (string-trim executable-path)))
+
+(defvar lsp--already-widened nil)
+
+(defmacro lsp-save-restriction-and-excursion (&rest form)
+ (declare (indent 0) (debug t))
+ `(if lsp--already-widened
+ (save-excursion ,@form)
+ (-let [lsp--already-widened t]
+ (save-restriction
+ (widen)
+ (save-excursion ,@form)))))
+
+;; from http://emacs.stackexchange.com/questions/8082/how-to-get-buffer-position-given-line-number-and-column-number
+(defun lsp--line-character-to-point (line character)
+ "Return the point for character CHARACTER on line LINE."
+ (or (lsp-virtual-buffer-call :line/character->point line character)
+ (let ((inhibit-field-text-motion t))
+ (lsp-save-restriction-and-excursion
+ (goto-char (point-min))
+ (forward-line line)
+ ;; server may send character position beyond the current line and we
+ ;; should fallback to line end.
+ (-let [line-end (line-end-position)]
+ (if (> character (- line-end (point)))
+ line-end
+ (forward-char character)
+ (point)))))))
+
+(lsp-defun lsp--position-to-point ((&Position :line :character))
+ "Convert `Position' object in PARAMS to a point."
+ (lsp--line-character-to-point line character))
+
+(lsp-defun lsp--range-to-region ((&RangeToPoint :start :end))
+ (cons start end))
+
+(lsp-defun lsp--range-text ((&RangeToPoint :start :end))
+ (buffer-substring start end))
+
+(lsp-defun lsp--find-wrapping-range ((&SelectionRange :parent? :range (&RangeToPoint :start :end)))
+ (cond
+ ((and
+ (region-active-p)
+ (<= start (region-beginning) end)
+ (<= start (region-end) end)
+ (or (not (= start (region-beginning)))
+ (not (= end (region-end)))))
+ (cons start end))
+ ((and (<= start (point) end)
+ (not (region-active-p)))
+ (cons start end))
+ (parent? (lsp--find-wrapping-range parent?))))
+
+(defun lsp--get-selection-range ()
+ (or
+ (-when-let ((cache . cache-tick) lsp--document-selection-range-cache)
+ (when (= cache-tick (buffer-modified-tick)) cache))
+ (let ((response (cl-first
+ (lsp-request
+ "textDocument/selectionRange"
+ (list :textDocument (lsp--text-document-identifier)
+ :positions (vector (lsp--cur-position)))))))
+ (setq lsp--document-selection-range-cache
+ (cons response (buffer-modified-tick)))
+ response)))
+
+(defun lsp-extend-selection ()
+ "Extend selection."
+ (interactive)
+ (unless (lsp--capability :selectionRangeProvider)
+ (signal 'lsp-capability-not-supported (list "selectionRangeProvider")))
+ (-when-let ((start . end) (lsp--find-wrapping-range (lsp--get-selection-range)))
+ (goto-char start)
+ (set-mark (point))
+ (goto-char end)
+ (exchange-point-and-mark)))
+
+(defun lsp-warn (message &rest args)
+ "Display a warning message made from (`format-message' MESSAGE ARGS...).
+This is equivalent to `display-warning', using `lsp-mode' as the type and
+`:warning' as the level."
+ (display-warning 'lsp-mode (apply #'format-message message args)))
+
+(defun lsp--get-uri-handler (scheme)
+ "Get uri handler for SCHEME in the current workspace."
+ (--some (gethash scheme (lsp--client-uri-handlers (lsp--workspace-client it)))
+ (or (lsp-workspaces) (lsp--session-workspaces (lsp-session)))))
+
+(defun lsp--fix-path-casing (path)
+ "On windows, downcases path because the windows file system is
+case-insensitive.
+
+On other systems, returns path without change."
+ (if (eq system-type 'windows-nt) (downcase path) path))
+
+(defun lsp--uri-to-path (uri)
+ "Convert URI to a file path."
+ (if-let ((fn (->> (lsp-workspaces)
+ (-keep (-compose #'lsp--client-uri->path-fn #'lsp--workspace-client))
+ (cl-first))))
+ (funcall fn uri)
+ (lsp--uri-to-path-1 uri)))
+
+(defun lsp-remap-path-if-needed (file-name)
+ (-if-let ((virtual-buffer &as &plist :buffer) (gethash file-name lsp--virtual-buffer-mappings))
+ (propertize (buffer-local-value 'buffer-file-name buffer)
+ 'lsp-virtual-buffer virtual-buffer)
+ file-name))
+
+(defun lsp--uri-to-path-1 (uri)
+ "Convert URI to a file path."
+ (let* ((url (url-generic-parse-url (url-unhex-string uri)))
+ (type (url-type url))
+ (target (url-target url))
+ (file
+ (concat (decode-coding-string (url-filename url)
+ (or locale-coding-system 'utf-8))
+ (when target
+ (concat "#" target))))
+ (file-name (if (and type (not (string= type "file")))
+ (if-let ((handler (lsp--get-uri-handler type)))
+ (funcall handler uri)
+ uri)
+ ;; `url-generic-parse-url' is buggy on windows:
+ ;; https://github.com/emacs-lsp/lsp-mode/pull/265
+ (or (and (eq system-type 'windows-nt)
+ (eq (elt file 0) ?\/)
+ (substring file 1))
+ file))))
+ (->> file-name
+ (concat (-some #'lsp--workspace-host-root (lsp-workspaces)))
+ (lsp-remap-path-if-needed))))
+
+(defun lsp--buffer-uri ()
+ "Return URI of the current buffer."
+ (or lsp-buffer-uri
+ (plist-get lsp--virtual-buffer :buffer-uri)
+ (lsp--path-to-uri
+ (or (buffer-file-name) (buffer-file-name (buffer-base-buffer))))))
+
+(defun lsp-register-client-capabilities (&rest _args)
+ "Implemented only to make `company-lsp' happy.
+DELETE when `lsp-mode.el' is deleted.")
+
+(defconst lsp--url-path-allowed-chars
+ (url--allowed-chars (append '(?/) url-unreserved-chars))
+ "`url-unreserved-chars' with additional delim ?/.
+This set of allowed chars is enough for hexifying local file paths.")
+
+(defun lsp--path-to-uri-1 (path)
+ (concat lsp--uri-file-prefix
+ (--> path
+ (expand-file-name it)
+ (or (file-remote-p it 'localname t) it)
+ (url-hexify-string it lsp--url-path-allowed-chars))))
+
+(defun lsp--path-to-uri (path)
+ "Convert PATH to a uri."
+ (if-let ((uri-fn (->> (lsp-workspaces)
+ (-keep (-compose #'lsp--client-path->uri-fn #'lsp--workspace-client))
+ (cl-first))))
+ (funcall uri-fn path)
+ (lsp--path-to-uri-1 path)))
+
+(defun lsp--string-match-any (regex-list str)
+ "Return the first regex, if any, within REGEX-LIST matching STR."
+ (--first (string-match it str) regex-list))
+
+(cl-defstruct lsp-watch
+ (descriptors (make-hash-table :test 'equal))
+ root-directory)
+
+(defun lsp--folder-watch-callback (event callback watch ignored-files ignored-directories)
+ (let ((file-name (cl-third event))
+ (event-type (cl-second event)))
+ (cond
+ ((and (file-directory-p file-name)
+ (equal 'created event-type)
+ (not (lsp--string-match-any ignored-directories file-name)))
+
+ (lsp-watch-root-folder (file-truename file-name) callback ignored-files ignored-directories watch)
+
+ ;; process the files that are already present in
+ ;; the directory.
+ (->> (directory-files-recursively file-name ".*" t)
+ (seq-do (lambda (f)
+ (unless (file-directory-p f)
+ (funcall callback (list nil 'created f)))))))
+ ((and (memq event-type '(created deleted changed))
+ (not (file-directory-p file-name))
+ (not (lsp--string-match-any ignored-files file-name)))
+ (funcall callback event))
+ ((and (memq event-type '(renamed))
+ (not (file-directory-p file-name))
+ (not (lsp--string-match-any ignored-files file-name)))
+ (funcall callback `(,(cl-first event) deleted ,(cl-third event)))
+ (funcall callback `(,(cl-first event) created ,(cl-fourth event)))))))
+
+(defun lsp--ask-about-watching-big-repo (number-of-directories dir)
+ "Ask the user if they want to watch NUMBER-OF-DIRECTORIES from a repository DIR.
+This is useful when there is a lot of files in a repository, as
+that may slow Emacs down. Returns t if the user wants to watch
+the entire repository, nil otherwise."
+ (prog1
+ (yes-or-no-p
+ (format
+ "Watching all the files in %s would require adding watches to %s directories, so watching the repo may slow Emacs down.
+Do you want to watch all files in %s? "
+ dir
+ number-of-directories
+ dir))
+ (lsp--info
+ (concat "You can configure this warning with the `lsp-enable-file-watchers' "
+ "and `lsp-file-watch-threshold' variables"))))
+
+
+(defun lsp--path-is-watchable-directory (path dir ignored-directories)
+ "Figure out whether PATH (inside of DIR) is meant to have a file watcher set.
+IGNORED-DIRECTORIES is a list of regexes to filter out directories we don't want to watch."
+ (let
+ ((full-path (f-join dir path)))
+ (and (f-dir-p full-path)
+ (not (equal path "."))
+ (not (equal path ".."))
+ (not (lsp--string-match-any ignored-directories full-path)))))
+
+
+(defun lsp--all-watchable-directories (dir ignored-directories)
+ "Traverse DIR recursively and return a list of paths that should have watchers set on them.
+IGNORED-DIRECTORIES will be used for exclusions"
+ (let* ((dir (if (f-symlink? dir)
+ (file-truename dir)
+ dir)))
+ (apply #'nconc
+ ;; the directory itself is assumed to be part of the set
+ (list dir)
+ ;; collect all subdirectories that are watchable
+ (-map
+ (lambda (path) (lsp--all-watchable-directories (f-join dir path) ignored-directories))
+ ;; but only look at subdirectories that are watchable
+ (-filter (lambda (path) (lsp--path-is-watchable-directory path dir ignored-directories))
+ (directory-files dir))))))
+
+(defun lsp-watch-root-folder (dir callback ignored-files ignored-directories &optional watch warn-big-repo?)
+ "Create recursive file notification watch in DIR.
+CALLBACK will be called when there are changes in any of
+the monitored files. WATCHES is a hash table directory->file
+notification handle which contains all of the watch that
+already have been created. Watches will not be created for
+any directory that matches any regex in IGNORED-DIRECTORIES.
+Watches will not be created for any file that matches any
+regex in IGNORED-FILES."
+ (let* ((dir (if (f-symlink? dir)
+ (file-truename dir)
+ dir))
+ (watch (or watch (make-lsp-watch :root-directory dir)))
+ (dirs-to-watch (lsp--all-watchable-directories dir ignored-directories)))
+ (lsp-log "Creating watchers for following %s folders:\n %s"
+ (length dirs-to-watch)
+ (s-join "\n " dirs-to-watch))
+ (when (or
+ (not warn-big-repo?)
+ (not lsp-file-watch-threshold)
+ (let ((number-of-directories (length dirs-to-watch)))
+ (or
+ (< number-of-directories lsp-file-watch-threshold)
+ (condition-case _err
+ (lsp--ask-about-watching-big-repo number-of-directories dir)
+ ('quit)))))
+ (dolist (current-dir dirs-to-watch)
+ (condition-case err
+ (progn
+ (puthash
+ current-dir
+ (file-notify-add-watch current-dir
+ '(change)
+ (lambda (event)
+ (lsp--folder-watch-callback event callback watch ignored-files ignored-directories)))
+ (lsp-watch-descriptors watch)))
+ (error (lsp-log "Failed to create a watch for %s: message" (error-message-string err)))
+ (file-missing (lsp-log "Failed to create a watch for %s: message" (error-message-string err))))))
+ watch))
+
+(defun lsp-kill-watch (watch)
+ "Delete WATCH."
+ (-> watch lsp-watch-descriptors hash-table-values (-each #'file-notify-rm-watch))
+ (ht-clear! (lsp-watch-descriptors watch)))
+
+(defun lsp-json-bool (val)
+ "Convert VAL to JSON boolean."
+ (if val t :json-false))
+
+(defmacro with-lsp-workspace (workspace &rest body)
+ "Helper macro for invoking BODY in WORKSPACE context."
+ (declare (debug (form body))
+ (indent 1))
+ `(let ((lsp--cur-workspace ,workspace)) ,@body))
+
+(defmacro with-lsp-workspaces (workspaces &rest body)
+ "Helper macro for invoking BODY against multiple WORKSPACES."
+ (declare (debug (form body))
+ (indent 1))
+ `(let ((lsp--buffer-workspaces ,workspaces)) ,@body))
+
+
+
+(defconst lsp-downstream-deps
+ '(;; external packages
+ ccls consult-lsp dap-mode helm-lsp lsp-dart lsp-docker lsp-focus lsp-grammarly
+ lsp-haskell lsp-ivy lsp-java lsp-javacomp lsp-jedi lsp-julia lsp-latex lsp-ltex
+ lsp-metals lsp-mssql lsp-origami lsp-p4 lsp-pascal lsp-pyre lsp-pyright
+ lsp-python-ms lsp-rescript lsp-sonarlint lsp-sourcekit lsp-tailwindcss lsp-treemacs
+ lsp-ui swift-helpful
+ ;; clients
+ lsp-actionscript lsp-ada lsp-angular lsp-bash lsp-beancount lsp-clangd
+ lsp-clojure lsp-cmake lsp-crystal lsp-csharp lsp-css lsp-d lsp-dhall
+ lsp-dockerfile lsp-elixir lsp-elm lsp-erlang lsp-eslint lsp-fortran lsp-fsharp lsp-gdscript
+ lsp-go lsp-graphql lsp-groovy lsp-hack lsp-haxe lsp-html lsp-idris lsp-javascript lsp-json lsp-kotlin lsp-lua
+ lsp-markdown lsp-nginx lsp-nim lsp-nix lsp-ocaml lsp-perl lsp-perlnavigator lsp-php lsp-prolog lsp-purescript lsp-pwsh
+ lsp-pyls lsp-pylsp lsp-racket lsp-r lsp-rf lsp-rust lsp-solargraph lsp-sorbet lsp-sqls
+ lsp-steep lsp-svelte lsp-terraform lsp-tex lsp-toml lsp-ttcn3 lsp-typeprof lsp-v lsp-vala lsp-verilog
+ lsp-vetur lsp-volar lsp-vhdl lsp-vimscript lsp-xml lsp-yaml lsp-zig)
+ "List of downstream deps.")
+
+(defmacro lsp-consistency-check (package)
+ `(defconst ,(intern (concat (symbol-name package)
+ "-plist-value-when-compiled"))
+ (eval-when-compile lsp-use-plists)))
+
+;; (mapc
+;; (lambda (package)
+;; (with-eval-after-load package
+;; (let ((symbol-name (intern
+;; (concat (symbol-name package)
+;; "-plist-value-when-compiled"))))
+;; (cond
+;; ((not (boundp symbol-name))
+;; (warn "We have detected that you are using version of %s that is not compatible with current version of lsp-mode.el, please update it." (propertize (symbol-name package)
+;; 'face 'bold)))
+;; ((not (eq (symbol-value symbol-name) lsp-use-plists))
+;; (warn "Package %s is inconsistent with lsp-mode.el. This is indication of race during installation. In order to solve that please delete all packages related to lsp-mode, restar Emacs and install them again." (propertize (symbol-name package) 'face 'bold)))))))
+;; lsp-downstream-deps)
+
+
+;; loading code-workspace files
+
+;;;###autoload
+(defun lsp-load-vscode-workspace (file)
+ "Load vscode workspace from FILE"
+ (interactive "fSelect file to import: ")
+ (mapc #'lsp-workspace-folders-remove (lsp-session-folders (lsp-session)))
+
+ (let ((dir (f-dirname file)))
+ (->> file
+ (json-read-file)
+ (alist-get 'folders)
+ (-map (-lambda ((&alist 'path))
+ (lsp-workspace-folders-add (expand-file-name path dir)))))))
+
+;;;###autoload
+(defun lsp-save-vscode-workspace (file)
+ "Save vscode workspace to FILE"
+ (interactive "FSelect file to save to: ")
+
+ (let ((json-encoding-pretty-print t))
+ (f-write-text (json-encode
+ `((folders . ,(->> (lsp-session)
+ (lsp-session-folders)
+ (--map `((path . ,it)))))))
+ 'utf-8
+ file)))
+
+
+(defmacro lsp-foreach-workspace (&rest body)
+ "Execute BODY for each of the current workspaces."
+ (declare (debug (form body)))
+ `(--map (with-lsp-workspace it ,@body) (lsp-workspaces)))
+
+(defmacro when-lsp-workspace (workspace &rest body)
+ "Helper macro for invoking BODY in WORKSPACE context if present."
+ (declare (debug (form body))
+ (indent 1))
+ `(when-let ((lsp--cur-workspace ,workspace)) ,@body))
+
+(lsp-defun lsp--window-show-quick-pick (_workspace (&ShowQuickPickParams :place-holder :can-pick-many :items))
+ (if-let* ((selectfunc (if can-pick-many #'completing-read-multiple #'completing-read))
+ (itemLabels (seq-map (-lambda ((item &as &QuickPickItem :label)) (format "%s" label))
+ items))
+ (result (funcall-interactively
+ selectfunc
+ (format "%s%s " place-holder (if can-pick-many " (* for all)" "")) itemLabels))
+ (choices (if (listp result)
+ (if (equal result '("*"))
+ itemLabels
+ result)
+ (list result))))
+ (vconcat (seq-filter #'identity (seq-map (-lambda ((item &as &QuickPickItem :label :user-data))
+ (if (member label choices)
+ (lsp-make-quick-pick-item :label label :picked t :user-data user-data)
+ nil))
+ items)))))
+
+(lsp-defun lsp--window-show-input-box (_workspace (&ShowInputBoxParams :prompt :value?))
+ (read-string (format "%s: " prompt) (or value? "")))
+
+(lsp-defun lsp--window-show-message (_workspace (&ShowMessageRequestParams :message :type))
+ "Send the server's messages to log.
+PARAMS - the data sent from _WORKSPACE."
+ (funcall (cl-case type
+ (1 'lsp--error)
+ (2 'lsp--warn)
+ (t 'lsp--info))
+ "%s"
+ message))
+
+(lsp-defun lsp--window-log-message (workspace (&ShowMessageRequestParams :message :type))
+ "Send the server's messages to log.
+PARAMS - the data sent from WORKSPACE."
+ (ignore
+ (let ((client (lsp--workspace-client workspace)))
+ (when (or (not client)
+ (cl-notany (-rpartial #'string-match-p message)
+ (lsp--client-ignore-messages client)))
+ (lsp-log "%s" (lsp--propertize message type))))))
+
+(lsp-defun lsp--window-log-message-request ((&ShowMessageRequestParams :message :type :actions?))
+ "Display a message request to the user and send the user's selection back to the server."
+ (let* ((message (lsp--propertize message type))
+ (choices (seq-map #'lsp:message-action-item-title actions?)))
+ (if choices
+ (completing-read (concat message " ") (seq-into choices 'list) nil t)
+ (lsp-log message))))
+
+(lsp-defun lsp--window-show-document ((&ShowDocumentParams :uri :selection?))
+ "Show document URI in a buffer and go to SELECTION if any."
+ (let ((path (lsp--uri-to-path uri)))
+ (when (f-exists? path)
+ (with-current-buffer (find-file path)
+ (when selection?
+ (goto-char (lsp--position-to-point (lsp:range-start selection?))))
+ t))))
+
+(defcustom lsp-progress-prefix " ⌛ "
+ "Progress prefix."
+ :group 'lsp-mode
+ :type 'string
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-progress-function #'lsp-on-progress-modeline
+ "Function for handling the progress notifications."
+ :group 'lsp-mode
+ :type '(choice
+ (const :tag "Use modeline" lsp-on-progress-modeline)
+ (const :tag "Legacy(uses either `progress-reporter' or `spinner' based on `lsp-progress-via-spinner')"
+ lsp-on-progress-legacy)
+ (const ignore :tag "Ignore")
+ (function :tag "Other function"))
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defun lsp--progress-status ()
+ "Returns the status of the progress for the current workspaces."
+ (-let ((progress-status
+ (s-join
+ "|"
+ (-keep
+ (lambda (workspace)
+ (let ((tokens (lsp--workspace-work-done-tokens workspace)))
+ (unless (ht-empty? tokens)
+ (mapconcat
+ (-lambda ((&WorkDoneProgressBegin :message? :title :percentage?))
+ (concat (if percentage?
+ (if (numberp percentage?)
+ (format "%.0f%%%% " percentage?)
+ (format "%s%%%% " percentage?))
+ "")
+ (or message? title)))
+ (ht-values tokens)
+ "|"))))
+ (lsp-workspaces)))))
+ (unless (s-blank? progress-status)
+ (concat lsp-progress-prefix progress-status))))
+
+(lsp-defun lsp-on-progress-modeline (workspace (&ProgressParams :token :value
+ (value &as &WorkDoneProgress :kind)))
+ "PARAMS contains the progress data.
+WORKSPACE is the workspace that contains the progress token."
+ (add-to-list 'global-mode-string '(t (:eval (lsp--progress-status))))
+ (pcase kind
+ ("begin" (lsp-workspace-set-work-done-token token value workspace))
+ ("report" (lsp-workspace-set-work-done-token token value workspace))
+ ("end" (lsp-workspace-rem-work-done-token token workspace)))
+ (force-mode-line-update))
+
+(lsp-defun lsp-on-progress-legacy (workspace (&ProgressParams :token :value
+ (value &as &WorkDoneProgress :kind)))
+ "PARAMS contains the progress data.
+WORKSPACE is the workspace that contains the progress token."
+ (pcase kind
+ ("begin"
+ (-let* (((&WorkDoneProgressBegin :title :percentage?) value)
+ (reporter
+ (if lsp-progress-via-spinner
+ (let* ((spinner-strings (alist-get 'progress-bar spinner-types))
+ ;; Set message as a tooltip for the spinner strings
+ (propertized-strings
+ (seq-map (lambda (string) (propertize string 'help-echo title))
+ spinner-strings))
+ (spinner-type (vconcat propertized-strings)))
+ ;; The progress relates to the server as a whole,
+ ;; display it on all buffers.
+ (mapcar (lambda (buffer)
+ (lsp-with-current-buffer buffer
+ (spinner-start spinner-type))
+ buffer)
+ (lsp--workspace-buffers workspace)))
+ (if percentage?
+ (make-progress-reporter title 0 100 percentage?)
+ ;; No percentage, just progress
+ (make-progress-reporter title nil nil)))))
+ (lsp-workspace-set-work-done-token token reporter workspace)))
+ ("report"
+ (when-let ((reporter (lsp-workspace-get-work-done-token token workspace)))
+ (unless lsp-progress-via-spinner
+ (progress-reporter-update reporter (lsp:work-done-progress-report-percentage? value)))))
+
+ ("end"
+ (when-let ((reporter (lsp-workspace-get-work-done-token token workspace)))
+ (if lsp-progress-via-spinner
+ (mapc (lambda (buffer)
+ (when (lsp-buffer-live-p buffer)
+ (lsp-with-current-buffer buffer
+ (spinner-stop))))
+ reporter)
+ (progress-reporter-done reporter))
+ (lsp-workspace-rem-work-done-token token workspace)))))
+
+
+;; diagnostics
+
+(defvar lsp-diagnostic-filter nil
+ "A a function which will be called with
+ `&PublishDiagnosticsParams' and `workspace' which can be used
+ to filter out the diagnostics. The function should return
+ `&PublishDiagnosticsParams'.
+
+Common usecase are:
+1. Filter the diagnostics for a particular language server.
+2. Filter out the diagnostics under specific level.")
+
+(defvar lsp-diagnostic-stats (ht))
+
+(defun lsp-diagnostics (&optional current-workspace?)
+ "Return the diagnostics from all workspaces."
+ (or (pcase (if current-workspace?
+ (lsp-workspaces)
+ (lsp--session-workspaces (lsp-session)))
+ (`() ())
+ (`(,workspace) (lsp--workspace-diagnostics workspace))
+ (`,workspaces (let ((result (make-hash-table :test 'equal)))
+ (mapc (lambda (workspace)
+ (->> workspace
+ (lsp--workspace-diagnostics)
+ (maphash (lambda (file-name diagnostics)
+ (puthash file-name
+ (append (gethash file-name result) diagnostics)
+ result)))))
+ workspaces)
+ result)))
+ (ht)))
+
+(defun lsp-diagnostics-stats-for (path)
+ "Get diagnostics statistics for PATH.
+The result format is vector [_ errors warnings infos hints] or nil."
+ (gethash (lsp--fix-path-casing path) lsp-diagnostic-stats))
+
+(defun lsp-diagnostics--update-path (path new-stats)
+ (let ((new-stats (copy-sequence new-stats))
+ (path (lsp--fix-path-casing (directory-file-name path))))
+ (if-let ((old-data (gethash path lsp-diagnostic-stats)))
+ (dotimes (idx 5)
+ (cl-callf + (aref old-data idx)
+ (aref new-stats idx)))
+ (puthash path new-stats lsp-diagnostic-stats))))
+
+(lsp-defun lsp--on-diagnostics-update-stats (workspace
+ (&PublishDiagnosticsParams :uri :diagnostics))
+ (let ((path (lsp--fix-path-casing (lsp--uri-to-path uri)))
+ (new-stats (make-vector 5 0)))
+ (mapc (-lambda ((&Diagnostic :severity?))
+ (cl-incf (aref new-stats (or severity? 1))))
+ diagnostics)
+ (when-let ((old-diags (gethash path (lsp--workspace-diagnostics workspace))))
+ (mapc (-lambda ((&Diagnostic :severity?))
+ (cl-decf (aref new-stats (or severity? 1))))
+ old-diags))
+ (lsp-diagnostics--update-path path new-stats)
+ (while (not (string= path (setf path (file-name-directory
+ (directory-file-name path)))))
+ (lsp-diagnostics--update-path path new-stats))))
+
+(defun lsp--on-diagnostics (workspace params)
+ "Callback for textDocument/publishDiagnostics.
+interface PublishDiagnosticsParams {
+ uri: string;
+ diagnostics: Diagnostic[];
+}
+PARAMS contains the diagnostics data.
+WORKSPACE is the workspace that contains the diagnostics."
+ (when lsp-diagnostic-filter
+ (setf params (funcall lsp-diagnostic-filter params workspace)))
+
+ (lsp--on-diagnostics-update-stats workspace params)
+
+ (-let* (((&PublishDiagnosticsParams :uri :diagnostics) params)
+ (lsp--virtual-buffer-mappings (ht))
+ (file (lsp--fix-path-casing (lsp--uri-to-path uri)))
+ (workspace-diagnostics (lsp--workspace-diagnostics workspace)))
+
+ (if (seq-empty-p diagnostics)
+ (remhash file workspace-diagnostics)
+ (puthash file (append diagnostics nil) workspace-diagnostics))
+
+ (run-hooks 'lsp-diagnostics-updated-hook)))
+
+(defun lsp-diagnostics--workspace-cleanup (workspace)
+ (->> workspace
+ (lsp--workspace-diagnostics)
+ (maphash (lambda (key _)
+ (lsp--on-diagnostics-update-stats
+ workspace
+ (lsp-make-publish-diagnostics-params
+ :uri (lsp--path-to-uri key)
+ :diagnostics [])))))
+ (clrhash (lsp--workspace-diagnostics workspace)))
+
+
+
+;; textDocument/foldingRange support
+
+(cl-defstruct lsp--folding-range beg end kind children)
+
+(defvar-local lsp--cached-folding-ranges nil)
+(defvar-local lsp--cached-nested-folding-ranges nil)
+
+(defun lsp--folding-range-width (range)
+ (- (lsp--folding-range-end range)
+ (lsp--folding-range-beg range)))
+
+(defun lsp--get-folding-ranges ()
+ "Get the folding ranges for the current buffer."
+ (unless (eq (buffer-chars-modified-tick) (car lsp--cached-folding-ranges))
+ (let* ((ranges (lsp-request "textDocument/foldingRange"
+ `(:textDocument ,(lsp--text-document-identifier))))
+ (sorted-line-col-pairs (->> ranges
+ (cl-mapcan (-lambda ((&FoldingRange :start-line
+ :start-character?
+ :end-line
+ :end-character?))
+ (list (cons start-line start-character?)
+ (cons end-line end-character?))))
+ (-sort #'lsp--line-col-comparator)))
+ (line-col-to-point-map (lsp--convert-line-col-to-points-batch
+ sorted-line-col-pairs)))
+ (setq lsp--cached-folding-ranges
+ (cons (buffer-chars-modified-tick)
+ (--> ranges
+ (seq-map (-lambda ((range &as
+ &FoldingRange :start-line
+ :start-character?
+ :end-line
+ :end-character?
+ :kind?))
+ (make-lsp--folding-range
+ :beg (ht-get line-col-to-point-map
+ (cons start-line start-character?))
+ :end (ht-get line-col-to-point-map
+ (cons end-line end-character?))
+ :kind kind?))
+ it)
+ (seq-filter (lambda (folding-range)
+ (< (lsp--folding-range-beg folding-range)
+ (lsp--folding-range-end folding-range)))
+ it)
+ (seq-into it 'list)
+ (delete-dups it))))))
+ (cdr lsp--cached-folding-ranges))
+
+(defun lsp--get-nested-folding-ranges ()
+ "Get a list of nested folding ranges for the current buffer."
+ (-let [(tick . _) lsp--cached-folding-ranges]
+ (if (and (eq tick (buffer-chars-modified-tick))
+ lsp--cached-nested-folding-ranges)
+ lsp--cached-nested-folding-ranges
+ (setq lsp--cached-nested-folding-ranges
+ (lsp--folding-range-build-trees (lsp--get-folding-ranges))))))
+
+(defun lsp--folding-range-build-trees (ranges)
+ (setq ranges (seq-sort #'lsp--range-before-p ranges))
+ (let* ((dummy-node (make-lsp--folding-range
+ :beg most-negative-fixnum
+ :end most-positive-fixnum))
+ (stack (list dummy-node)))
+ (dolist (range ranges)
+ (while (not (lsp--range-inside-p range (car stack)))
+ (pop stack))
+ (push range (lsp--folding-range-children (car stack)))
+ (push range stack))
+ (lsp--folding-range-children dummy-node)))
+
+(defun lsp--range-inside-p (r1 r2)
+ "Return non-nil if folding range R1 lies inside R2"
+ (and (>= (lsp--folding-range-beg r1) (lsp--folding-range-beg r2))
+ (<= (lsp--folding-range-end r1) (lsp--folding-range-end r2))))
+
+(defun lsp--range-before-p (r1 r2)
+ "Return non-nil if folding range R1 ends before R2"
+ ;; Ensure r1 comes before r2
+ (or (< (lsp--folding-range-beg r1)
+ (lsp--folding-range-beg r2))
+ ;; If beg(r1) == beg(r2) make sure r2 ends first
+ (and (= (lsp--folding-range-beg r1)
+ (lsp--folding-range-beg r2))
+ (< (lsp--folding-range-end r2)
+ (lsp--folding-range-end r1)))))
+
+(defun lsp--point-inside-range-p (point range)
+ "Return non-nil if POINT lies inside folding range RANGE."
+ (and (>= point (lsp--folding-range-beg range))
+ (<= point (lsp--folding-range-end range))))
+
+(cl-defun lsp--get-current-innermost-folding-range (&optional (point (point)))
+ "Return the innermost folding range POINT lies in."
+ (seq-reduce (lambda (innermost-range curr-range)
+ (if (and (lsp--point-inside-range-p point curr-range)
+ (or (null innermost-range)
+ (lsp--range-inside-p curr-range innermost-range)))
+ curr-range
+ innermost-range))
+ (lsp--get-folding-ranges)
+ nil))
+
+(cl-defun lsp--get-current-outermost-folding-range (&optional (point (point)))
+ "Return the outermost folding range POINT lies in."
+ (cdr (seq-reduce (-lambda ((best-pair &as outermost-width . _) curr-range)
+ (let ((curr-width (lsp--folding-range-width curr-range)))
+ (if (and (lsp--point-inside-range-p point curr-range)
+ (or (null best-pair)
+ (> curr-width outermost-width)))
+ (cons curr-width curr-range)
+ best-pair)))
+ (lsp--get-folding-ranges)
+ nil)))
+
+(defun lsp--folding-range-at-point-bounds ()
+ (if (and (or (lsp--capability :foldingRangeProvider)
+ (lsp--registered-capability "textDocument/foldingRange"))
+ lsp-enable-folding)
+ (if-let ((range (lsp--get-current-innermost-folding-range)))
+ (cons (lsp--folding-range-beg range)
+ (lsp--folding-range-end range)))
+ nil))
+(put 'lsp--folding-range 'bounds-of-thing-at-point
+ #'lsp--folding-range-at-point-bounds)
+
+(defun lsp--get-nearest-folding-range (&optional backward)
+ (let ((point (point))
+ (found nil))
+ (while (not
+ (or found
+ (if backward
+ (<= point (point-min))
+ (>= point (point-max)))))
+ (if backward (cl-decf point) (cl-incf point))
+ (setq found (lsp--get-current-innermost-folding-range point)))
+ found))
+
+(defun lsp--folding-range-at-point-forward-op (n)
+ (when (and (or (lsp--capability :foldingRangeProvider)
+ (lsp--registered-capability "textDocument/foldingRange"))
+ lsp-enable-folding
+ (not (zerop n)))
+ (cl-block break
+ (dotimes (_ (abs n))
+ (if-let ((range (lsp--get-nearest-folding-range (< n 0))))
+ (goto-char (if (< n 0)
+ (lsp--folding-range-beg range)
+ (lsp--folding-range-end range)))
+ (cl-return-from break))))))
+(put 'lsp--folding-range 'forward-op
+ #'lsp--folding-range-at-point-forward-op)
+
+(defun lsp--folding-range-at-point-beginning-op ()
+ (goto-char (car (lsp--folding-range-at-point-bounds))))
+(put 'lsp--folding-range 'beginning-op
+ #'lsp--folding-range-at-point-beginning-op)
+
+(defun lsp--folding-range-at-point-end-op ()
+ (goto-char (cdr (lsp--folding-range-at-point-bounds))))
+(put 'lsp--folding-range 'end-op
+ #'lsp--folding-range-at-point-end-op)
+
+(defun lsp--range-at-point-bounds ()
+ (or (lsp--folding-range-at-point-bounds)
+ (when-let ((range (and
+ (lsp--capability :hoverProvider)
+ (->> (lsp--text-document-position-params)
+ (lsp-request "textDocument/hover")
+ (lsp:hover-range?)))))
+ (lsp--range-to-region range))))
+
+;; A more general purpose "thing", useful for applications like focus.el
+(put 'lsp--range 'bounds-of-thing-at-point
+ #'lsp--range-at-point-bounds)
+
+(defun lsp--log-io-p (method)
+ "Return non nil if should log for METHOD."
+ (and lsp-log-io
+ (or (not lsp-log-io-allowlist-methods)
+ (member method lsp-log-io-allowlist-methods))))
+
+
+;; toggles
+
+(defun lsp-toggle-trace-io ()
+ "Toggle client-server protocol logging."
+ (interactive)
+ (setq lsp-log-io (not lsp-log-io))
+ (lsp--info "Server logging %s." (if lsp-log-io "enabled" "disabled")))
+
+(defun lsp-toggle-signature-auto-activate ()
+ "Toggle signature auto activate."
+ (interactive)
+ (setq lsp-signature-auto-activate
+ (unless lsp-signature-auto-activate '(:on-trigger-char)))
+ (lsp--info "Signature autoactivate %s." (if lsp-signature-auto-activate "enabled" "disabled"))
+ (lsp--update-signature-help-hook))
+
+(defun lsp-toggle-on-type-formatting ()
+ "Toggle on type formatting."
+ (interactive)
+ (setq lsp-enable-on-type-formatting (not lsp-enable-on-type-formatting))
+ (lsp--info "On type formatting is %s." (if lsp-enable-on-type-formatting "enabled" "disabled"))
+ (lsp--update-on-type-formatting-hook))
+
+(defun lsp-toggle-symbol-highlight ()
+ "Toggle symbol highlighting."
+ (interactive)
+ (setq lsp-enable-symbol-highlighting (not lsp-enable-symbol-highlighting))
+
+ (cond
+ ((and lsp-enable-symbol-highlighting
+ (lsp-feature? "textDocument/documentHighlight"))
+ (add-hook 'lsp-on-idle-hook #'lsp--document-highlight nil t)
+ (lsp--info "Symbol highlighting enabled in current buffer."))
+ ((not lsp-enable-symbol-highlighting)
+ (remove-hook 'lsp-on-idle-hook #'lsp--document-highlight t)
+ (lsp--remove-overlays 'lsp-highlight)
+ (lsp--info "Symbol highlighting disabled in current buffer."))))
+
+
+;; keybindings
+(defvar lsp--binding-descriptions nil
+ "List of key binding/short description pair.")
+
+(defmacro lsp-define-conditional-key (keymap key def desc cond &rest bindings)
+ "In KEYMAP, define key sequence KEY as DEF conditionally.
+This is like `define-key', except the definition disappears
+whenever COND evaluates to nil.
+DESC is the short-description for the binding.
+BINDINGS is a list of (key def desc cond)."
+ (declare (indent defun)
+ (debug (form form form form form &rest sexp)))
+ (->> (cl-list* key def desc cond bindings)
+ (-partition 4)
+ (-mapcat (-lambda ((key def desc cond))
+ `((define-key ,keymap ,key
+ '(menu-item
+ ,(format "maybe-%s" def)
+ ,def
+ :filter
+ (lambda (item)
+ (when (with-current-buffer (or (when (buffer-live-p lsp--describe-buffer)
+ lsp--describe-buffer)
+ (current-buffer))
+ ,cond)
+ item))))
+ (when (stringp ,key)
+ (setq lsp--binding-descriptions
+ (append lsp--binding-descriptions '(,key ,desc)))))))
+ macroexp-progn))
+
+(defvar lsp--describe-buffer nil)
+
+(defun lsp-describe-buffer-bindings-advice (fn buffer &optional prefix menus)
+ (let ((lsp--describe-buffer buffer))
+ (funcall fn buffer prefix menus)))
+
+(advice-add 'describe-buffer-bindings
+ :around
+ #'lsp-describe-buffer-bindings-advice)
+
+(defun lsp--prepend-prefix (mappings)
+ (->> mappings
+ (-partition 2)
+ (-mapcat (-lambda ((key description))
+ (list (concat lsp-keymap-prefix " " key)
+ description)))))
+
+(defvar lsp-command-map
+ (-doto (make-sparse-keymap)
+ (lsp-define-conditional-key
+ ;; workspaces
+ "wD" lsp-disconnect "disconnect" (lsp-workspaces)
+ "wd" lsp-describe-session "describe session" t
+ "wq" lsp-workspace-shutdown "shutdown server" (lsp-workspaces)
+ "wr" lsp-workspace-restart "restart server" (lsp-workspaces)
+ "ws" lsp "start server" t
+
+ ;; formatting
+ "==" lsp-format-buffer "format buffer" (or (lsp-feature? "textDocument/rangeFormatting")
+ (lsp-feature? "textDocument/formatting"))
+ "=r" lsp-format-region "format region" (lsp-feature? "textDocument/rangeFormatting")
+
+ ;; folders
+ "Fa" lsp-workspace-folders-add "add folder" t
+ "Fb" lsp-workspace-blacklist-remove "un-blacklist folder" t
+ "Fr" lsp-workspace-folders-remove "remove folder" t
+
+ ;; toggles
+ "TD" lsp-modeline-diagnostics-mode "toggle modeline diagnostics" (lsp-feature?
+ "textDocument/publishDiagnostics")
+ "TL" lsp-toggle-trace-io "toggle log io" t
+ "TS" lsp-ui-sideline-mode "toggle sideline" (featurep 'lsp-ui-sideline)
+ "TT" lsp-treemacs-sync-mode "toggle treemacs integration" (featurep 'lsp-treemacs)
+ "Ta" lsp-modeline-code-actions-mode "toggle modeline code actions" (lsp-feature?
+ "textDocument/codeAction")
+ "Tb" lsp-headerline-breadcrumb-mode "toggle breadcrumb" (lsp-feature?
+ "textDocument/documentSymbol")
+ "Td" lsp-ui-doc-mode "toggle documentation popup" (featurep 'lsp-ui-doc)
+ "Tf" lsp-toggle-on-type-formatting "toggle on type formatting" (lsp-feature?
+ "textDocument/onTypeFormatting")
+ "Th" lsp-toggle-symbol-highlight "toggle highlighting" (lsp-feature? "textDocument/documentHighlight")
+ "Tl" lsp-lens-mode "toggle lenses" (lsp-feature? "textDocument/codeLens")
+ "Ts" lsp-toggle-signature-auto-activate "toggle signature" (lsp-feature? "textDocument/signatureHelp")
+
+ ;; goto
+ "ga" xref-find-apropos "find symbol in workspace" (lsp-feature? "workspace/symbol")
+ "gd" lsp-find-declaration "find declarations" (lsp-feature? "textDocument/declaration")
+ "ge" lsp-treemacs-errors-list "show errors" (fboundp 'lsp-treemacs-errors-list)
+ "gg" lsp-find-definition "find definitions" (lsp-feature? "textDocument/definition")
+ "gh" lsp-treemacs-call-hierarchy "call hierarchy" (and (lsp-feature? "callHierarchy/incomingCalls")
+ (fboundp 'lsp-treemacs-call-hierarchy))
+ "gi" lsp-find-implementation "find implementations" (lsp-feature? "textDocument/implementation")
+ "gr" lsp-find-references "find references" (lsp-feature? "textDocument/references")
+ "gt" lsp-find-type-definition "find type definition" (lsp-feature? "textDocument/typeDefinition")
+
+ ;; help
+ "hg" lsp-ui-doc-glance "glance symbol" (and (featurep 'lsp-ui-doc)
+ (lsp-feature? "textDocument/hover"))
+ "hh" lsp-describe-thing-at-point "describe symbol at point" (lsp-feature? "textDocument/hover")
+ "hs" lsp-signature-activate "signature help" (lsp-feature? "textDocument/signatureHelp")
+
+ ;; refactoring
+ "ro" lsp-organize-imports "organize imports" (lsp-feature? "textDocument/codeAction")
+ "rr" lsp-rename "rename" (lsp-feature? "textDocument/rename")
+
+ ;; actions
+ "aa" lsp-execute-code-action "code actions" (lsp-feature? "textDocument/codeAction")
+ "ah" lsp-document-highlight "highlight symbol" (lsp-feature? "textDocument/documentHighlight")
+ "al" lsp-avy-lens "lens" (and (bound-and-true-p lsp-lens-mode) (featurep 'avy))
+
+ ;; peeks
+ "Gg" lsp-ui-peek-find-definitions "peek definitions" (and (lsp-feature? "textDocument/definition")
+ (fboundp 'lsp-ui-peek-find-definitions))
+ "Gi" lsp-ui-peek-find-implementation "peek implementations" (and
+ (fboundp 'lsp-ui-peek-find-implementation)
+ (lsp-feature? "textDocument/implementation"))
+ "Gr" lsp-ui-peek-find-references "peek references" (and (fboundp 'lsp-ui-peek-find-references)
+ (lsp-feature? "textDocument/references"))
+ "Gs" lsp-ui-peek-find-workspace-symbol "peek workspace symbol" (and (fboundp
+ 'lsp-ui-peek-find-workspace-symbol)
+ (lsp-feature? "workspace/symbol")))))
+
+
+;; which-key integration
+
+(declare-function which-key-add-major-mode-key-based-replacements "ext:which-key")
+(declare-function which-key-add-key-based-replacements "ext:which-key")
+
+(defun lsp-enable-which-key-integration (&optional all-modes)
+ "Adds descriptions for `lsp-mode-map' to `which-key-mode' for the current
+active `major-mode', or for all major modes when ALL-MODES is t."
+ (cl-flet ((which-key-fn (if all-modes
+ 'which-key-add-key-based-replacements
+ (apply-partially 'which-key-add-major-mode-key-based-replacements major-mode))))
+ (apply
+ #'which-key-fn
+ (lsp--prepend-prefix
+ (cl-list*
+ "" "lsp"
+ "w" "workspaces"
+ "F" "folders"
+ "=" "formatting"
+ "T" "toggle"
+ "g" "goto"
+ "h" "help"
+ "r" "refactor"
+ "a" "code actions"
+ "G" "peek"
+ lsp--binding-descriptions)))))
+
+
+;; Globbing syntax
+
+;; We port VSCode's glob-to-regexp code
+;; (https://github.com/Microsoft/vscode/blob/466da1c9013c624140f6d1473b23a870abc82d44/src/vs/base/common/glob.ts)
+;; since the LSP globbing syntax seems to be the same as that of
+;; VSCode.
+
+(defconst lsp-globstar "**"
+ "Globstar pattern.")
+
+(defconst lsp-glob-split ?/
+ "The character by which we split path components in a glob
+pattern.")
+
+(defconst lsp-path-regexp "[/\\\\]"
+ "Forward or backslash to be used as a path separator in
+computed regexps.")
+
+(defconst lsp-non-path-regexp "[^/\\\\]"
+ "A regexp matching anything other than a slash.")
+
+(defconst lsp-globstar-regexp
+ (format "\\(?:%s\\|%s+%s\\|%s%s+\\)*?"
+ lsp-path-regexp
+ lsp-non-path-regexp lsp-path-regexp
+ lsp-path-regexp lsp-non-path-regexp)
+ "Globstar in regexp form.")
+
+(defun lsp-split-glob-pattern (pattern split-char)
+ "Split PATTERN at SPLIT-CHAR while respecting braces and brackets."
+ (when pattern
+ (let ((segments nil)
+ (in-braces nil)
+ (in-brackets nil)
+ (current-segment ""))
+ (dolist (char (string-to-list pattern))
+ (cl-block 'exit-point
+ (if (eq char split-char)
+ (when (and (null in-braces)
+ (null in-brackets))
+ (push current-segment segments)
+ (setq current-segment "")
+ (cl-return-from 'exit-point))
+ (pcase char
+ (?{
+ (setq in-braces t))
+ (?}
+ (setq in-braces nil))
+ (?\[
+ (setq in-brackets t))
+ (?\]
+ (setq in-brackets nil))))
+ (setq current-segment (concat current-segment
+ (char-to-string char)))))
+ (unless (string-empty-p current-segment)
+ (push current-segment segments))
+ (nreverse segments))))
+
+(defun lsp--glob-to-regexp (pattern)
+ "Helper function to convert a PATTERN from LSP's glob syntax to
+an Elisp regexp."
+ (if (string-empty-p pattern)
+ ""
+ (let ((current-regexp "")
+ (glob-segments (lsp-split-glob-pattern pattern lsp-glob-split)))
+ (if (-all? (lambda (segment) (eq segment lsp-globstar))
+ glob-segments)
+ ".*"
+ (let ((prev-segment-was-globstar nil))
+ (seq-do-indexed
+ (lambda (segment index)
+ (if (string-equal segment lsp-globstar)
+ (unless prev-segment-was-globstar
+ (setq current-regexp (concat current-regexp
+ lsp-globstar-regexp))
+ (setq prev-segment-was-globstar t))
+ (let ((in-braces nil)
+ (brace-val "")
+ (in-brackets nil)
+ (bracket-val ""))
+ (dolist (char (string-to-list segment))
+ (cond
+ ((and (not (char-equal char ?\}))
+ in-braces)
+ (setq brace-val (concat brace-val
+ (char-to-string char))))
+ ((and in-brackets
+ (or (not (char-equal char ?\]))
+ (string-empty-p bracket-val)))
+ (let ((curr (cond
+ ((char-equal char ?-)
+ "-")
+ ;; NOTE: ?\^ and ?^ are different characters
+ ((and (memq char '(?^ ?!))
+ (string-empty-p bracket-val))
+ "^")
+ ((char-equal char lsp-glob-split)
+ "")
+ (t
+ (regexp-quote (char-to-string char))))))
+ (setq bracket-val (concat bracket-val curr))))
+ (t
+ (cl-case char
+ (?{
+ (setq in-braces t))
+ (?\[
+ (setq in-brackets t))
+ (?}
+ (let* ((choices (lsp-split-glob-pattern brace-val ?\,))
+ (brace-regexp (concat "\\(?:"
+ (mapconcat #'lsp--glob-to-regexp choices "\\|")
+ "\\)")))
+ (setq current-regexp (concat current-regexp
+ brace-regexp))
+ (setq in-braces nil)
+ (setq brace-val "")))
+ (?\]
+ (setq current-regexp
+ (concat current-regexp
+ "[" bracket-val "]"))
+ (setq in-brackets nil)
+ (setq bracket-val ""))
+ (??
+ (setq current-regexp
+ (concat current-regexp
+ lsp-non-path-regexp)))
+ (?*
+ (setq current-regexp
+ (concat current-regexp
+ lsp-non-path-regexp "*?")))
+ (t
+ (setq current-regexp
+ (concat current-regexp
+ (regexp-quote (char-to-string char)))))))))
+ (when (and (< index (1- (length glob-segments)))
+ (or (not (string-equal (nth (1+ index) glob-segments)
+ lsp-globstar))
+ (< (+ index 2)
+ (length glob-segments))))
+ (setq current-regexp
+ (concat current-regexp
+ lsp-path-regexp)))
+ (setq prev-segment-was-globstar nil))))
+ glob-segments)
+ current-regexp)))))
+
+;; See https://github.com/emacs-lsp/lsp-mode/issues/2365
+(defun lsp-glob-unbrace-at-top-level (glob-pattern)
+ "If GLOB-PATTERN does not start with a brace, return a singleton list containing GLOB-PATTERN.
+
+If GLOB-PATTERN does start with a brace, return a list of the
+comma-separated globs within the top-level braces."
+ (if (not (string-prefix-p "{" glob-pattern))
+ (list glob-pattern)
+ (lsp-split-glob-pattern (substring glob-pattern 1 -1) ?\,)))
+
+(defun lsp-glob-convert-to-wrapped-regexp (glob-pattern)
+ "Convert GLOB-PATTERN to a regexp wrapped with the beginning-
+and end-of-string meta-characters."
+ (concat "\\`" (lsp--glob-to-regexp (string-trim glob-pattern)) "\\'"))
+
+(defun lsp-glob-to-regexps (glob-pattern)
+ "Convert a GLOB-PATTERN to a list of Elisp regexps."
+ (let* ((trimmed-pattern (string-trim glob-pattern))
+ (top-level-unbraced-patterns (lsp-glob-unbrace-at-top-level trimmed-pattern)))
+ (seq-map #'lsp-glob-convert-to-wrapped-regexp
+ top-level-unbraced-patterns)))
+
+
+
+(defvar lsp-mode-menu)
+
+(defun lsp-mouse-click (event)
+ (interactive "e")
+ (let* ((ec (event-start event))
+ (choice (x-popup-menu event lsp-mode-menu))
+ (action (lookup-key lsp-mode-menu (apply 'vector choice))))
+
+ (select-window (posn-window ec))
+
+ (unless (and (region-active-p) (eq action 'lsp-execute-code-action))
+ (goto-char (posn-point ec)))
+ (run-with-idle-timer
+ 0.001 nil
+ (lambda ()
+ (cl-labels ((check (value) (not (null value))))
+ (when choice
+ (call-interactively action)))))))
+
+(defvar lsp-mode-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map (kbd "C-<down-mouse-1>") #'lsp-find-definition-mouse)
+ (define-key map (kbd "C-<mouse-1>") #'ignore)
+ (define-key map (kbd "<mouse-3>") #'lsp-mouse-click)
+ (define-key map (kbd "C-S-SPC") #'lsp-signature-activate)
+ (when lsp-keymap-prefix
+ (define-key map (kbd lsp-keymap-prefix) lsp-command-map))
+ map)
+ "Keymap for `lsp-mode'.")
+
+(define-minor-mode lsp-mode "Mode for LSP interaction."
+ :keymap lsp-mode-map
+ :lighter
+ (" LSP["
+ (lsp--buffer-workspaces
+ (:eval (mapconcat #'lsp--workspace-print lsp--buffer-workspaces "]["))
+ (:propertize "Disconnected" face warning))
+ "]")
+ :group 'lsp-mode)
+
+(defvar lsp-mode-menu
+ (easy-menu-create-menu
+ nil
+ `(["Go to definition" lsp-find-definition
+ :active (lsp-feature? "textDocument/definition")]
+ ["Find references" lsp-find-references
+ :active (lsp-feature? "textDocument/references")]
+ ["Find implementations" lsp-find-implementation
+ :active (lsp-feature? "textDocument/implementation")]
+ ["Find declarations" lsp-find-declaration
+ :active (lsp-feature? "textDocument/declaration")]
+ ["Go to type declaration" lsp-find-type-definition
+ :active (lsp-feature? "textDocument/typeDefinition")]
+ "--"
+ ["Describe" lsp-describe-thing-at-point]
+ ["Code action" lsp-execute-code-action]
+ ["Format" lsp-format-buffer]
+ ["Highlight references" lsp-document-highlight]
+ ["Type Hierarchy" lsp-java-type-hierarchy
+ :visible (lsp-can-execute-command? "java.navigate.resolveTypeHierarchy")]
+ ["Type Hierarchy" lsp-treemacs-type-hierarchy
+ :visible (and (not (lsp-can-execute-command? "java.navigate.resolveTypeHierarchy"))
+ (functionp 'lsp-treemacs-type-hierarchy)
+ (lsp-feature? "textDocument/typeHierarchy"))]
+ ["Call Hierarchy" lsp-treemacs-call-hierarchy
+ :visible (and (functionp 'lsp-treemacs-call-hierarchy)
+ (lsp-feature? "textDocument/callHierarchy"))]
+ ["Rename" lsp-rename
+ :active (lsp-feature? "textDocument/rename")]
+ "--"
+ ("Session"
+ ["View logs" lsp-workspace-show-log]
+ ["Describe" lsp-describe-session]
+ ["Shutdown" lsp-shutdown-workspace]
+ ["Restart" lsp-restart-workspace])
+ ("Workspace Folders"
+ ["Add" lsp-workspace-folders-add]
+ ["Remove" lsp-workspace-folders-remove]
+ ["Open" lsp-workspace-folders-open])
+ ("Toggle features"
+ ["Lenses" lsp-lens-mode]
+ ["Headerline breadcrumb" lsp-headerline-breadcrumb-mode]
+ ["Modeline code actions" lsp-modeline-code-actions-mode]
+ ["Modeline diagnostics" lsp-modeline-diagnostics-mode])
+ "---"
+ ("Debug"
+ :active (bound-and-true-p dap-ui-mode)
+ :filter ,(lambda (_)
+ (and (boundp 'dap-ui-menu-items)
+ (nthcdr 3 dap-ui-menu-items))))))
+ "Menu for lsp-mode.")
+
+(defalias 'make-lsp-client 'make-lsp--client)
+
+(cl-defstruct lsp--registered-capability
+ (id "")
+ (method " ")
+ (options nil))
+
+;; A ‘lsp--workspace’ object represents exactly one language server process.
+(cl-defstruct lsp--workspace
+ ;; the `ewoc' object for displaying I/O to and from the server
+ (ewoc nil)
+
+ ;; ‘server-capabilities’ is a hash table of the language server capabilities.
+ ;; It is the hash table representation of a LSP ServerCapabilities structure;
+ ;; cf. https://microsoft.github.io/language-server-protocol/specification#initialize.
+ (server-capabilities nil)
+
+ ;; ‘registered-server-capabilities’ is a list of hash tables that represent
+ ;; dynamically-registered Registration objects. See
+ ;; https://microsoft.github.io/language-server-protocol/specification#client_registerCapability.
+ (registered-server-capabilities nil)
+
+ ;; ‘root’ is a directory name or a directory file name for the workspace
+ ;; root. ‘lsp-mode’ passes this directory to the ‘initialize’ method of the
+ ;; language server; see
+ ;; https://microsoft.github.io/language-server-protocol/specification#initialize.
+ (root nil)
+
+ ;; ‘client’ is the ‘lsp--client’ object associated with this workspace.
+ (client nil)
+
+ ;; ‘host-root’ contains the host root info as derived from `file-remote-p'. It
+ ;; used to derive the file path in `lsp--uri-to-path' when using tramp
+ ;; connection.
+ (host-root nil)
+
+ ;; ‘proc’ is a process object; it may represent a regular process, a pipe, or
+ ;; a network connection. ‘lsp-mode’ communicates with ‘proc’ using the
+ ;; language server protocol. ‘proc’ corresponds to the COMMUNICATION-PROCESS
+ ;; element of the return value of the client’s ‘get-root’ field, which see.
+ (proc nil)
+
+ ;; ‘proc’ is a process object; it must represent a regular process, not a
+ ;; pipe or network process. It represents the actual server process that
+ ;; corresponds to this workspace. ‘cmd-proc’ corresponds to the
+ ;; COMMAND-PROCESS element of the return value of the client’s ‘get-root’
+ ;; field, which see.
+ (cmd-proc nil)
+
+ ;; ‘buffers’ is a list of buffers associated with this workspace.
+ (buffers nil)
+
+ ;; if semantic tokens is enabled, `semantic-tokens-faces' contains
+ ;; one face (or nil) for each token type supported by the language server.
+ (semantic-tokens-faces nil)
+
+ ;; If semantic highlighting is enabled, `semantic-tokens-modifier-faces'
+ ;; contains one face (or nil) for each modifier type supported by the language
+ ;; server
+ (semantic-tokens-modifier-faces nil)
+
+ ;; Extra client capabilities provided by third-party packages using
+ ;; `lsp-register-client-capabilities'. It's value is an alist of (PACKAGE-NAME
+ ;; . CAPS), where PACKAGE-NAME is a symbol of the third-party package name,
+ ;; and CAPS is either a plist of the client capabilities, or a function that
+ ;; takes no argument and returns a plist of the client capabilities or nil.")
+ (extra-client-capabilities nil)
+
+ ;; Workspace status
+ (status nil)
+
+ ;; ‘metadata’ is a generic storage for workspace specific data. It is
+ ;; accessed via `lsp-workspace-set-metadata' and `lsp-workspace-set-metadata'
+ (metadata (make-hash-table :test 'equal))
+
+ ;; contains all the file notification watches that have been created for the
+ ;; current workspace in format filePath->file notification handle.
+ (watches (make-hash-table :test 'equal))
+
+ ;; list of workspace folders
+ (workspace-folders nil)
+
+ ;; ‘last-id’ the last request id for the current workspace.
+ (last-id 0)
+
+ ;; ‘status-string’ allows extensions to specify custom status string based on
+ ;; the Language Server specific messages.
+ (status-string nil)
+
+ ;; ‘shutdown-action’ flag used to mark that workspace should not be restarted (e.g. it
+ ;; was stopped).
+ shutdown-action
+
+ ;; ‘diagnostics’ a hashmap with workspace diagnostics.
+ (diagnostics (make-hash-table :test 'equal))
+
+ ;; contains all the workDone progress tokens that have been created
+ ;; for the current workspace.
+ (work-done-tokens (make-hash-table :test 'equal)))
+
+
+(cl-defstruct lsp-session
+ ;; contains the folders that are part of the current session
+ folders
+ ;; contains the folders that must not be imported in the current workspace.
+ folders-blacklist
+ ;; contains the list of folders that must be imported in a project in case of
+ ;; multi root LSP server.
+ (server-id->folders (make-hash-table :test 'equal))
+ ;; folder to list of the servers that are associated with the folder.
+ (folder->servers (make-hash-table :test 'equal))
+ ;; ‘metadata’ is a generic storage for workspace specific data. It is
+ ;; accessed via `lsp-workspace-set-metadata' and `lsp-workspace-set-metadata'
+ (metadata (make-hash-table :test 'equal)))
+
+(defun lsp-workspace-status (status-string &optional workspace)
+ "Set current workspace status to STATUS-STRING.
+If WORKSPACE is not specified defaults to lsp--cur-workspace."
+ (let ((status-string (when status-string (replace-regexp-in-string "%" "%%" status-string))))
+ (setf (lsp--workspace-status-string (or workspace lsp--cur-workspace)) status-string)))
+
+(defun lsp-session-set-metadata (key value &optional _workspace)
+ "Associate KEY with VALUE in the WORKSPACE metadata.
+If WORKSPACE is not provided current workspace will be used."
+ (puthash key value (lsp-session-metadata (lsp-session))))
+
+(defalias 'lsp-workspace-set-metadata 'lsp-session-set-metadata)
+
+(defun lsp-session-get-metadata (key &optional _workspace)
+ "Lookup KEY in WORKSPACE metadata.
+If WORKSPACE is not provided current workspace will be used."
+ (gethash key (lsp-session-metadata (lsp-session))))
+
+(defalias 'lsp-workspace-get-metadata 'lsp-session-get-metadata)
+
+(defun lsp-workspace-set-work-done-token (token value workspace)
+ "Associate TOKEN with VALUE in the WORKSPACE work-done-tokens."
+ (puthash token value (lsp--workspace-work-done-tokens workspace)))
+
+(defun lsp-workspace-get-work-done-token (token workspace)
+ "Lookup TOKEN in the WORKSPACE work-done-tokens."
+ (gethash token (lsp--workspace-work-done-tokens workspace)))
+
+(defun lsp-workspace-rem-work-done-token (token workspace)
+ "Remove TOKEN from the WORKSPACE work-done-tokens."
+ (remhash token (lsp--workspace-work-done-tokens workspace)))
+
+
+(defun lsp--make-notification (method &optional params)
+ "Create notification body for method METHOD and parameters PARAMS."
+ (list :jsonrpc "2.0" :method method :params params))
+
+(defalias 'lsp--make-request 'lsp--make-notification)
+(defalias 'lsp-make-request 'lsp--make-notification)
+
+(defun lsp--make-response (id result)
+ "Create response for REQUEST with RESULT."
+ `(:jsonrpc "2.0" :id ,id :result ,result))
+
+(defun lsp-make-notification (method &optional params)
+ "Create notification body for method METHOD and parameters PARAMS."
+ (lsp--make-notification method params))
+
+(defmacro lsp--json-serialize (params)
+ (if (progn
+ (require 'json)
+ (fboundp 'json-serialize))
+ `(json-serialize ,params
+ :null-object nil
+ :false-object :json-false)
+ `(let ((json-false :json-false))
+ (json-encode ,params))))
+
+(defun lsp--make-message (params)
+ "Create a LSP message from PARAMS, after encoding it to a JSON string."
+ (let ((body (lsp--json-serialize params)))
+ (concat "Content-Length: "
+ (number-to-string (1+ (string-bytes body)))
+ "\r\n\r\n"
+ body
+ "\n")))
+
+(cl-defstruct lsp--log-entry timestamp process-time type method id body)
+
+(defun lsp--make-log-entry (method id body type &optional process-time)
+ "Create an outgoing log object from BODY with method METHOD and id ID.
+If ID is non-nil, then the body is assumed to be a notification.
+TYPE can either be 'incoming or 'outgoing"
+ (cl-assert (memq type '(incoming-req outgoing-req incoming-notif
+ outgoing-notif incoming-resp
+ outgoing-resp)))
+ (make-lsp--log-entry
+ :timestamp (format-time-string "%I:%M:%S %p")
+ :process-time process-time
+ :method method
+ :id id
+ :type type
+ :body body))
+
+(defun lsp--log-entry-pp (entry)
+ (cl-assert (lsp--log-entry-p entry))
+ (pcase-let (((cl-struct lsp--log-entry timestamp method id type process-time
+ body)
+ entry)
+ (json-false :json-false)
+ (json-encoding-pretty-print t)
+ (str nil))
+ (setq str
+ (concat (format "[Trace - %s] " timestamp)
+ (pcase type
+ ('incoming-req (format "Received request '%s - (%s)." method id))
+ ('outgoing-req (format "Sending request '%s - (%s)'." method id))
+
+ ('incoming-notif (format "Received notification '%s'." method))
+ ('outgoing-notif (format "Sending notification '%s'." method))
+
+ ('incoming-resp (format "Received response '%s - (%s)' in %dms."
+ method id process-time))
+ ('outgoing-resp
+ (format
+ "Sending response '%s - (%s)'. Processing request took %dms"
+ method id process-time)))
+ "\n"
+ (if (memq type '(incoming-resp ougoing-resp))
+ "Result: "
+ "Params: ")
+ (json-encode body)
+ "\n\n\n"))
+ (setq str (propertize str 'mouse-face 'highlight 'read-only t))
+ (insert str)))
+
+(defvar-local lsp--log-io-ewoc nil)
+
+(defun lsp--get-create-io-ewoc (workspace)
+ (if (and (lsp--workspace-ewoc workspace)
+ (buffer-live-p (ewoc-buffer (lsp--workspace-ewoc workspace))))
+ (lsp--workspace-ewoc workspace)
+ (with-current-buffer (lsp--get-log-buffer-create workspace)
+ (unless (eq 'lsp-log-io-mode major-mode) (lsp-log-io-mode))
+ (setq-local window-point-insertion-type t)
+ (setq lsp--log-io-ewoc (ewoc-create #'lsp--log-entry-pp nil nil t))
+ (setf (lsp--workspace-ewoc workspace) lsp--log-io-ewoc))
+ (lsp--workspace-ewoc workspace)))
+
+(defun lsp--ewoc-count (ewoc)
+ (let* ((count 0)
+ (count-fn (lambda (_) (setq count (1+ count)))))
+ (ewoc-map count-fn ewoc)
+ count))
+
+(defun lsp--log-entry-new (entry workspace)
+ (let* ((ewoc (lsp--get-create-io-ewoc workspace))
+ (count (and (not (eq lsp-io-messages-max t)) (lsp--ewoc-count ewoc)))
+ (node (if (or (eq lsp-io-messages-max t)
+ (>= lsp-io-messages-max count))
+ nil
+ (ewoc-nth ewoc (1- lsp-io-messages-max))))
+ (prev nil)
+ (inhibit-read-only t))
+ (while node
+ (setq prev (ewoc-prev ewoc node))
+ (ewoc-delete ewoc node)
+ (setq node prev))
+ (ewoc-enter-last ewoc entry)))
+
+(defun lsp--send-notification (body)
+ "Send BODY as a notification to the language server."
+ (lsp-foreach-workspace
+ (when (lsp--log-io-p (plist-get body :method))
+ (lsp--log-entry-new (lsp--make-log-entry
+ (plist-get body :method)
+ nil (plist-get body :params) 'outgoing-notif)
+ lsp--cur-workspace))
+ (lsp--send-no-wait (lsp--make-message body)
+ (lsp--workspace-proc lsp--cur-workspace))))
+
+(defalias 'lsp-send-notification 'lsp--send-notification)
+
+(defun lsp-notify (method params)
+ "Send notification METHOD with PARAMS."
+ (lsp--send-notification (lsp--make-notification method params)))
+
+(defun lsp--cur-workspace-check ()
+ "Check whether buffer lsp workspace(s) are set."
+ (cl-assert (lsp-workspaces) nil
+ "No language server(s) is associated with this buffer."))
+
+(defun lsp--send-request (body &optional no-wait no-merge)
+ "Send BODY as a request to the language server, get the response.
+If NO-WAIT is non-nil, don't synchronously wait for a response.
+If NO-MERGE is non-nil, don't merge the results but return an
+alist mapping workspace->result."
+ (lsp-request (plist-get body :method)
+ (plist-get body :params)
+ :no-wait no-wait
+ :no-merge no-merge))
+
+(defalias 'lsp-send-request 'lsp--send-request
+ "Send BODY as a request to the language server and return the response
+synchronously.
+\n(fn BODY)")
+
+(cl-defun lsp-request (method params &key no-wait no-merge)
+ "Send request METHOD with PARAMS.
+If NO-MERGE is non-nil, don't merge the results but return alist
+workspace->result.
+If NO-WAIT is non-nil send the request as notification."
+ (if no-wait
+ (lsp-notify method params)
+ (let* ((send-time (time-to-seconds (current-time)))
+ ;; max time by which we must get a response
+ (expected-time
+ (and
+ lsp-response-timeout
+ (+ send-time lsp-response-timeout)))
+ resp-result resp-error done?)
+ (unwind-protect
+ (progn
+ (lsp-request-async method params
+ (lambda (res) (setf resp-result (or res :finished)) (throw 'lsp-done '_))
+ :error-handler (lambda (err) (setf resp-error err) (throw 'lsp-done '_))
+ :no-merge no-merge
+ :mode 'detached
+ :cancel-token :sync-request)
+ (while (not (or resp-error resp-result))
+ (catch 'lsp-done
+ (accept-process-output
+ nil
+ (if expected-time (- expected-time send-time) 1)))
+ (setq send-time (time-to-seconds (current-time)))
+ (when (and expected-time (< expected-time send-time))
+ (error "Timeout while waiting for response. Method: %s" method)))
+ (setq done? t)
+ (cond
+ ((eq resp-result :finished) nil)
+ (resp-result resp-result)
+ ((lsp-json-error? resp-error) (error (lsp:json-error-message resp-error)))
+ ((lsp-json-error? (cl-first resp-error))
+ (error (lsp:json-error-message (cl-first resp-error))))))
+ (unless done?
+ (lsp-cancel-request-by-token :sync-request))))))
+
+(cl-defun lsp-request-while-no-input (method params)
+ "Send request METHOD with PARAMS and waits until there is no input.
+Return same value as `lsp--while-no-input' and respecting `non-essential'."
+ (if non-essential
+ (let* ((send-time (time-to-seconds (current-time)))
+ ;; max time by which we must get a response
+ (expected-time
+ (and
+ lsp-response-timeout
+ (+ send-time lsp-response-timeout)))
+ resp-result resp-error done?)
+ (unwind-protect
+ (progn
+ (lsp-request-async method params
+ (lambda (res) (setf resp-result (or res :finished)) (throw 'lsp-done '_))
+ :error-handler (lambda (err) (setf resp-error err) (throw 'lsp-done '_))
+ :mode 'detached
+ :cancel-token :sync-request)
+ (while (not (or resp-error resp-result (input-pending-p)))
+ (catch 'lsp-done
+ (sit-for
+ (if expected-time (- expected-time send-time) 1)))
+ (setq send-time (time-to-seconds (current-time)))
+ (when (and expected-time (< expected-time send-time))
+ (error "Timeout while waiting for response. Method: %s" method)))
+ (setq done? (or resp-error resp-result))
+ (cond
+ ((eq resp-result :finished) nil)
+ (resp-result resp-result)
+ ((lsp-json-error? resp-error) (error (lsp:json-error-message resp-error)))
+ ((lsp-json-error? (cl-first resp-error))
+ (error (lsp:json-error-message (cl-first resp-error))))))
+ (unless done?
+ (lsp-cancel-request-by-token :sync-request))
+ (when (and (input-pending-p) lsp--throw-on-input)
+ (throw 'input :interrupted))))
+ (lsp-request method params)))
+
+(defvar lsp--cancelable-requests (ht))
+
+(cl-defun lsp-request-async (method params callback
+ &key mode error-handler cancel-handler no-merge cancel-token)
+ "Send METHOD with PARAMS as a request to the language server.
+Call CALLBACK with the response received from the server
+asynchronously.
+MODE determines when the callback will be called depending on the
+condition of the original buffer. It could be:
+- `detached' which means that the callback will be executed no
+matter what has happened to the buffer.
+- `alive' - the callback will be executed only if the buffer from
+which the call was executed is still alive.
+- `current' the callback will be executed only if the original buffer
+is still selected.
+- `tick' - the callback will be executed only if the buffer was not modified.
+- `unchanged' - the callback will be executed only if the buffer hasn't
+changed and if the buffer is not modified.
+
+ERROR-HANDLER will be called in case the request has failed.
+CANCEL-HANDLER will be called in case the request is being canceled.
+If NO-MERGE is non-nil, don't merge the results but return alist
+workspace->result.
+CANCEL-TOKEN is the token that can be used to cancel request."
+ (lsp--send-request-async `(:jsonrpc "2.0" :method ,method :params ,params)
+ callback mode error-handler cancel-handler no-merge cancel-token))
+
+(defun lsp--create-request-cancel (id workspaces hook buf method cancel-callback)
+ (lambda (&rest _)
+ (unless (and (equal 'post-command-hook hook)
+ (equal (current-buffer) buf))
+ (lsp--request-cleanup-hooks id)
+ (with-lsp-workspaces workspaces
+ (lsp--cancel-request id)
+ (when cancel-callback (funcall cancel-callback)))
+ (lsp-log "Cancelling %s(%s) in hook %s" method id hook))))
+
+(defun lsp--create-async-callback
+ (callback method no-merge workspaces)
+ "Create async handler expecting COUNT results, merge them and call CALLBACK.
+MODE determines when the callback will be called depending on the
+condition of the original buffer. METHOD is the invoked method.
+If NO-MERGE is non-nil, don't merge the results but return alist workspace->result.
+ID is the request id. "
+ (let (results errors)
+ (lambda (result)
+ (push (cons lsp--cur-workspace result)
+ (if (eq result :error) errors results))
+ (when (and (not (eq (length errors) (length workspaces)))
+ (eq (+ (length errors) (length results)) (length workspaces)))
+ (funcall callback
+ (if no-merge
+ results
+ (lsp--merge-results (-map #'cl-rest results) method)))))))
+
+(defcustom lsp-default-create-error-handler-fn nil
+ "Default error handler customization.
+Handler should give METHOD as argument and return function of one argument
+ERROR."
+ :type 'function
+ :group 'lsp-mode
+ :package-version '(lsp-mode . "8.0.1"))
+
+(defun lsp--create-default-error-handler (method)
+ "Default error handler.
+METHOD is the executed method."
+ (if lsp-default-create-error-handler-fn
+ (funcall lsp-default-create-error-handler-fn method)
+ (lambda (error)
+ (lsp--warn "%s" (or (lsp--error-string error)
+ (format "%s Request has failed" method))))))
+
+(defvar lsp--request-cleanup-hooks (ht))
+
+(defun lsp--request-cleanup-hooks (request-id)
+ (when-let ((cleanup-function (gethash request-id lsp--request-cleanup-hooks)))
+ (funcall cleanup-function)
+ (remhash request-id lsp--request-cleanup-hooks)))
+
+(defun lsp-cancel-request-by-token (cancel-token)
+ "Cancel request using CANCEL-TOKEN."
+ (-when-let ((request-id . workspaces) (gethash cancel-token lsp--cancelable-requests))
+ (with-lsp-workspaces workspaces
+ (lsp--cancel-request request-id))
+ (remhash cancel-token lsp--cancelable-requests)
+ (lsp--request-cleanup-hooks request-id)))
+
+(defun lsp--send-request-async (body callback
+ &optional mode error-callback cancel-callback
+ no-merge cancel-token)
+ "Send BODY as a request to the language server.
+Call CALLBACK with the response received from the server
+asynchronously.
+MODE determines when the callback will be called depending on the
+condition of the original buffer. It could be:
+- `detached' which means that the callback will be executed no
+matter what has happened to the buffer.
+- `alive' - the callback will be executed only if the buffer from
+which the call was executed is still alive.
+- `current' the callback will be executed only if the original buffer
+is still selected.
+- `tick' - the callback will be executed only if the buffer was not modified.
+- `unchanged' - the callback will be executed only if the buffer hasn't
+changed and if the buffer is not modified.
+
+ERROR-CALLBACK will be called in case the request has failed.
+CANCEL-CALLBACK will be called in case the request is being canceled.
+If NO-MERGE is non-nil, don't merge the results but return alist
+workspace->result.
+CANCEL-TOKEN is the token that can be used to cancel request."
+ (when cancel-token
+ (lsp-cancel-request-by-token cancel-token))
+
+ (if-let ((target-workspaces (lsp--find-workspaces-for body)))
+ (let* ((start-time (current-time))
+ (method (plist-get body :method))
+ (id (cl-incf lsp-last-id))
+ ;; calculate what are the (hook . local) pairs which will cancel
+ ;; the request
+ (hooks (pcase mode
+ ('alive '((kill-buffer-hook . t)))
+ ('tick '((kill-buffer-hook . t) (after-change-functions . t)))
+ ('unchanged '((after-change-functions . t) (post-command-hook . nil)))
+ ('current '((post-command-hook . nil)))))
+ (buf (current-buffer))
+ ;; note: lambdas in emacs can be compared but we should make sure
+ ;; that all of the captured arguments are the same - in our case
+ ;; `lsp--create-request-cancel' will return the same lambda when
+ ;; called with the same params.
+ (cleanup-hooks
+ (lambda () (mapc
+ (-lambda ((hook . local))
+ (if local
+ (when (buffer-live-p buf)
+ (with-current-buffer buf
+ (remove-hook hook
+ (lsp--create-request-cancel
+ id target-workspaces hook buf method cancel-callback)
+ t)))
+ (remove-hook hook (lsp--create-request-cancel
+ id target-workspaces hook buf method cancel-callback))))
+ hooks)
+ (remhash cancel-token lsp--cancelable-requests)))
+ (callback (pcase mode
+ ((or 'alive 'tick) (lambda (&rest args)
+ (with-current-buffer buf
+ (apply callback args))))
+ (_ callback)))
+ (callback (lsp--create-async-callback callback
+ method
+ no-merge
+ target-workspaces))
+ (callback (lambda (result)
+ (lsp--request-cleanup-hooks id)
+ (funcall callback result)))
+ (error-callback (lsp--create-async-callback
+ (or error-callback
+ (lsp--create-default-error-handler method))
+ method
+ nil
+ target-workspaces))
+ (error-callback (lambda (error)
+ (funcall callback :error)
+ (lsp--request-cleanup-hooks id)
+ (funcall error-callback error)))
+ (cancel-callback (when cancel-callback
+ (pcase mode
+ ((or 'alive 'tick 'unchanged)
+ (lambda ()
+ (with-current-buffer buf
+ (funcall cancel-callback))))
+ (_ cancel-callback))))
+ (body (plist-put body :id id)))
+
+ ;; cancel request in any of the hooks
+ (mapc (-lambda ((hook . local))
+ (add-hook hook
+ (lsp--create-request-cancel
+ id target-workspaces hook buf method cancel-callback)
+ nil local))
+ hooks)
+ (puthash id cleanup-hooks lsp--request-cleanup-hooks)
+
+ (setq lsp--last-active-workspaces target-workspaces)
+
+ (when cancel-token
+ (puthash cancel-token (cons id target-workspaces) lsp--cancelable-requests))
+
+ (seq-doseq (workspace target-workspaces)
+ (when (lsp--log-io-p method)
+ (lsp--log-entry-new (lsp--make-log-entry method id
+ (plist-get body :params)
+ 'outgoing-req)
+ workspace))
+ (let ((message (lsp--make-message body)))
+ (puthash id
+ (list callback error-callback method start-time (current-time))
+ (-> workspace
+ (lsp--workspace-client)
+ (lsp--client-response-handlers)))
+ (lsp--send-no-wait message (lsp--workspace-proc workspace))))
+ body)
+ (error "The connected server(s) does not support method %s.
+To find out what capabilities support your server use `M-x lsp-describe-session'
+and expand the capabilities section"
+ (plist-get body :method))))
+
+;; deprecated, use lsp-request-async.
+(defalias 'lsp-send-request-async 'lsp--send-request-async)
+(make-obsolete 'lsp-send-request-async 'lsp-request-async "lsp-mode 7.0.1")
+
+;; Clean up the entire state of lsp mode when Emacs is killed, to get rid of any
+;; pending language servers.
+(add-hook 'kill-emacs-hook #'lsp--global-teardown)
+
+(defun lsp--global-teardown ()
+ "Unload working workspaces."
+ (lsp-foreach-workspace (lsp--shutdown-workspace)))
+
+(defun lsp--shutdown-workspace (&optional restart)
+ "Shut down the language server process for ‘lsp--cur-workspace’."
+ (with-demoted-errors "LSP error: %S"
+ (let ((lsp-response-timeout 0.5))
+ (condition-case _err
+ (lsp-request "shutdown" lsp--empty-ht)
+ (error (lsp--error "Timeout while sending shutdown request"))))
+ (lsp-notify "exit" nil))
+ (setf (lsp--workspace-shutdown-action lsp--cur-workspace) (or (and restart 'restart) 'shutdown))
+ (lsp--uninitialize-workspace))
+
+(defun lsp--uninitialize-workspace ()
+ "Cleanup buffer state.
+When a workspace is shut down, by request or from just
+disappearing, unset all the variables related to it."
+ (let ((proc (lsp--workspace-cmd-proc lsp--cur-workspace))
+ (buffers (lsp--workspace-buffers lsp--cur-workspace)))
+ (when (process-live-p proc)
+ (kill-process proc))
+ (mapc (lambda (buf)
+ (when (lsp-buffer-live-p buf)
+ (lsp-with-current-buffer buf
+ (lsp-managed-mode -1))))
+ buffers)
+ (lsp-diagnostics--workspace-cleanup lsp--cur-workspace)))
+
+(defun lsp--client-capabilities (&optional custom-capabilities)
+ "Return the client capabilities appending CUSTOM-CAPABILITIES."
+ (append
+ `((workspace . ((workspaceEdit . ((documentChanges . t)
+ (resourceOperations . ["create" "rename" "delete"])))
+ (applyEdit . t)
+ (symbol . ((symbolKind . ((valueSet . ,(apply 'vector (number-sequence 1 26)))))))
+ (executeCommand . ((dynamicRegistration . :json-false)))
+ ,@(when lsp-enable-file-watchers '((didChangeWatchedFiles . ((dynamicRegistration . t)))))
+ (workspaceFolders . t)
+ (configuration . t)
+ ,@(when lsp-semantic-tokens-enable
+ `((semanticTokens . ((refreshSupport . ,(or (and (boundp 'lsp-semantic-tokens-honor-refresh-requests)
+ lsp-semantic-tokens-honor-refresh-requests)
+ :json-false))))))
+ ,@(when lsp-lens-enable '((codeLens . ((refreshSupport . t)))))
+ (fileOperations . ((didCreate . :json-false)
+ (willCreate . :json-false)
+ (didRename . t)
+ (willRename . t)
+ (didDelete . :json-false)
+ (willDelete . :json-false)))))
+ (textDocument . ((declaration . ((linkSupport . t)))
+ (definition . ((linkSupport . t)))
+ (implementation . ((linkSupport . t)))
+ (typeDefinition . ((linkSupport . t)))
+ (synchronization . ((willSave . t) (didSave . t) (willSaveWaitUntil . t)))
+ (documentSymbol . ((symbolKind . ((valueSet . ,(apply 'vector (number-sequence 1 26)))))
+ (hierarchicalDocumentSymbolSupport . t)))
+ (formatting . ((dynamicRegistration . t)))
+ (rangeFormatting . ((dynamicRegistration . t)))
+ ,@(when (and lsp-semantic-tokens-enable
+ (boundp 'lsp-semantic-tokens-capabilities))
+ lsp-semantic-tokens-capabilities)
+ (rename . ((dynamicRegistration . t) (prepareSupport . t)))
+ (codeAction . ((dynamicRegistration . t)
+ (isPreferredSupport . t)
+ (codeActionLiteralSupport . ((codeActionKind . ((valueSet . [""
+ "quickfix"
+ "refactor"
+ "refactor.extract"
+ "refactor.inline"
+ "refactor.rewrite"
+ "source"
+ "source.organizeImports"])))))
+ (resolveSupport . ((properties . ["edit" "command"])))
+ (dataSupport . t)))
+ (completion . ((completionItem . ((snippetSupport . ,(cond
+ ((and lsp-enable-snippet (not (featurep 'yasnippet)) t)
+ (lsp--warn (concat
+ "Yasnippet is not installed, but `lsp-enable-snippet' is set to `t'. "
+ "You must either install yasnippet, or disable snippet support."))
+ :json-false)
+ (lsp-enable-snippet t)
+ (t :json-false)))
+ (documentationFormat . ["markdown" "plaintext"])
+ ;; Remove this after jdtls support resolveSupport
+ (resolveAdditionalTextEditsSupport . t)
+ (insertReplaceSupport . t)
+ (deprecatedSupport . t)
+ (resolveSupport
+ . ((properties . ["documentation"
+ "detail"
+ "additionalTextEdits"
+ "command"])))
+ (insertTextModeSupport . ((valueSet . [1 2])))))
+ (contextSupport . t)))
+ (signatureHelp . ((signatureInformation . ((parameterInformation . ((labelOffsetSupport . t)))))))
+ (documentLink . ((dynamicRegistration . t)
+ (tooltipSupport . t)))
+ (hover . ((contentFormat . ["markdown" "plaintext"])))
+ (foldingRange . ,(when lsp-enable-folding
+ `((dynamicRegistration . t)
+ ,@(when lsp-folding-range-limit
+ `((rangeLimit . ,lsp-folding-range-limit)))
+ ,@(when lsp-folding-line-folding-only
+ `((lineFoldingOnly . t))))))
+ (callHierarchy . ((dynamicRegistration . :json-false)))
+ (publishDiagnostics . ((relatedInformation . t)
+ (tagSupport . ((valueSet . [1 2])))
+ (versionSupport . t)))
+ (linkedEditingRange . ((dynamicRegistration . t)))))
+ (window . ((workDoneProgress . t)
+ (showMessage . nil)
+ (showDocument . ((support . t))))))
+ custom-capabilities))
+
+(defun lsp-find-roots-for-workspace (workspace session)
+ "Get all roots for the WORKSPACE."
+ (-filter #'identity (ht-map (lambda (folder workspaces)
+ (when (-contains? workspaces workspace)
+ folder))
+ (lsp-session-folder->servers session))))
+
+(defun lsp-session-watches (&optional session)
+ "Get watches created for SESSION."
+ (or (gethash "__watches" (lsp-session-metadata (or session (lsp-session))))
+ (-let [res (make-hash-table :test 'equal)]
+ (puthash "__watches" res (lsp-session-metadata (or session (lsp-session))))
+ res)))
+
+(defun lsp--file-process-event (session root-folder event)
+ "Process file event."
+ (let* ((changed-file (cl-third event))
+ (rel-changed-file (f-relative changed-file root-folder))
+ (event-numeric-kind (alist-get (cl-second event) lsp--file-change-type))
+ (bit-position (1- event-numeric-kind))
+ (watch-bit (ash 1 bit-position)))
+ (->>
+ session
+ lsp-session-folder->servers
+ (gethash root-folder)
+ (seq-do (lambda (workspace)
+ (when (->>
+ workspace
+ lsp--workspace-registered-server-capabilities
+ (-any?
+ (lambda (capability)
+ (and
+ (equal (lsp--registered-capability-method capability)
+ "workspace/didChangeWatchedFiles")
+ (->>
+ capability
+ lsp--registered-capability-options
+ (lsp:did-change-watched-files-registration-options-watchers)
+ (seq-find
+ (-lambda ((fs-watcher &as &FileSystemWatcher :glob-pattern :kind? :_cachedRegexp cached-regexp))
+ (when (or (null kind?)
+ (> (logand kind? watch-bit) 0))
+ (-let [regexes (or cached-regexp
+ (let ((regexp (lsp-glob-to-regexps glob-pattern)))
+ (lsp-put fs-watcher :_cachedRegexp regexp)
+ regexp))]
+ (-any? (lambda (re)
+ (or (string-match re changed-file)
+ (string-match re rel-changed-file)))
+ regexes))))))))))
+ (with-lsp-workspace workspace
+ (lsp-notify
+ "workspace/didChangeWatchedFiles"
+ `((changes . [((type . ,event-numeric-kind)
+ (uri . ,(lsp--path-to-uri changed-file)))]))))))))))
+
+(lsp-defun lsp--server-register-capability ((&Registration :method :id :register-options?))
+ "Register capability REG."
+ (when (and lsp-enable-file-watchers
+ (equal method "workspace/didChangeWatchedFiles"))
+ (-let* ((created-watches (lsp-session-watches (lsp-session)))
+ (root-folders (cl-set-difference
+ (lsp-find-roots-for-workspace lsp--cur-workspace (lsp-session))
+ (ht-keys created-watches))))
+ ;; create watch for each root folder without such
+ (dolist (folder root-folders)
+ (let* ((watch (make-lsp-watch :root-directory folder))
+ (ignored-things (lsp--get-ignored-regexes-for-workspace-root folder))
+ (ignored-files-regex-list (car ignored-things))
+ (ignored-directories-regex-list (cadr ignored-things)))
+ (puthash folder watch created-watches)
+ (lsp-watch-root-folder (file-truename folder)
+ (-partial #'lsp--file-process-event (lsp-session) folder)
+ ignored-files-regex-list
+ ignored-directories-regex-list
+ watch
+ t)))))
+
+ (push
+ (make-lsp--registered-capability :id id :method method :options register-options?)
+ (lsp--workspace-registered-server-capabilities lsp--cur-workspace)))
+
+(defmacro lsp--with-workspace-temp-buffer (workspace-root &rest body)
+ "With a temp-buffer under `WORKSPACE-ROOT' and evaluate `BODY', useful to access dir-local variables."
+ (declare (indent 1) (debug t))
+ `(with-temp-buffer
+ ;; Set the buffer's name to something under the root so that we can hack the local variables
+ ;; This file doesn't need to exist and will not be created due to this.
+ (setq-local buffer-file-name (expand-file-name "lsp-mode-temp" (expand-file-name ,workspace-root)))
+ (hack-local-variables)
+ (prog1 ,@body
+ (setq-local buffer-file-name nil))))
+
+(defun lsp--get-ignored-regexes-for-workspace-root (workspace-root)
+ "Return a list of the form (lsp-file-watch-ignored-files lsp-file-watch-ignored-directories) for the given WORKSPACE-ROOT."
+ ;; The intent of this function is to provide per-root workspace-level customization of the
+ ;; lsp-file-watch-ignored-directories and lsp-file-watch-ignored-files variables.
+ (lsp--with-workspace-temp-buffer workspace-root
+ (list lsp-file-watch-ignored-files (lsp-file-watch-ignored-directories))))
+
+
+(defun lsp--cleanup-hanging-watches ()
+ "Cleanup watches in case there are no more workspaces that are interested
+in that particular folder."
+ (let* ((session (lsp-session))
+ (watches (lsp-session-watches session)))
+ (dolist (watched-folder (ht-keys watches))
+ (when (-none? (lambda (workspace)
+ (with-lsp-workspace workspace
+ (lsp--registered-capability "workspace/didChangeWatchedFiles")))
+ (gethash watched-folder (lsp-session-folder->servers (lsp-session))))
+ (lsp-log "Cleaning up watches for folder %s. There is no workspace watching this folder..." watched-folder)
+ (lsp-kill-watch (gethash watched-folder watches))
+ (remhash watched-folder watches)))))
+
+(lsp-defun lsp--server-unregister-capability ((&Unregistration :id :method))
+ "Unregister capability UNREG."
+ (setf (lsp--workspace-registered-server-capabilities lsp--cur-workspace)
+ (seq-remove (lambda (e) (equal (lsp--registered-capability-id e) id))
+ (lsp--workspace-registered-server-capabilities lsp--cur-workspace)))
+ (when (equal method "workspace/didChangeWatchedFiles")
+ (lsp--cleanup-hanging-watches)))
+
+(defun lsp--server-capabilities ()
+ "Return the capabilities of the language server associated with the buffer."
+ (->> (lsp-workspaces)
+ (-keep #'lsp--workspace-server-capabilities)
+ (apply #'lsp-merge)))
+
+(defun lsp--send-open-close-p ()
+ "Return whether open and close notifications should be sent to the server."
+ (let ((sync (lsp:server-capabilities-text-document-sync? (lsp--server-capabilities))))
+ (or (memq sync '(1 2))
+ (lsp:text-document-sync-options-open-close? sync))))
+
+(defun lsp--send-will-save-p ()
+ "Return whether willSave notifications should be sent to the server."
+ (-> (lsp--server-capabilities)
+ (lsp:server-capabilities-text-document-sync?)
+ (lsp:text-document-sync-options-will-save?)))
+
+(defun lsp--send-will-save-wait-until-p ()
+ "Return whether willSaveWaitUntil notifications should be sent to the server."
+ (-> (lsp--server-capabilities)
+ (lsp:server-capabilities-text-document-sync?)
+ (lsp:text-document-sync-options-will-save-wait-until?)))
+
+(defun lsp--send-did-save-p ()
+ "Return whether didSave notifications should be sent to the server."
+ (let ((sync (lsp:server-capabilities-text-document-sync? (lsp--server-capabilities))))
+ (or (memq sync '(1 2))
+ (lsp:text-document-sync-options-save? sync))))
+
+(defun lsp--save-include-text-p ()
+ "Return whether save notifications should include the text document's contents."
+ (->> (lsp--server-capabilities)
+ (lsp:server-capabilities-text-document-sync?)
+ (lsp:text-document-sync-options-save?)
+ (lsp:text-document-save-registration-options-include-text?)))
+
+(defun lsp--send-will-rename-files-p (path)
+ "Return whether willRenameFiles request should be sent to the server.
+If any filters, checks if it applies for PATH."
+ (let* ((will-rename (-> (lsp--server-capabilities)
+ (lsp:server-capabilities-workspace?)
+ (lsp:workspace-server-capabilities-file-operations?)
+ (lsp:workspace-file-operations-will-rename?)))
+ (filters (seq-into (lsp:file-operation-registration-options-filters will-rename) 'list)))
+ (and will-rename
+ (or (seq-empty-p filters)
+ (-any? (-lambda ((&FileOperationFilter :scheme? :pattern (&FileOperationPattern :glob)))
+ (-let [regexes (lsp-glob-to-regexps glob)]
+ (and (or (not scheme?)
+ (string-prefix-p scheme? (lsp--path-to-uri path)))
+ (-any? (lambda (re)
+ (string-match re path))
+ regexes))))
+ filters)))))
+
+(defun lsp--send-did-rename-files-p ()
+ "Return whether didRenameFiles notification should be sent to the server."
+ (-> (lsp--server-capabilities)
+ (lsp:server-capabilities-workspace?)
+ (lsp:workspace-server-capabilities-file-operations?)
+ (lsp:workspace-file-operations-did-rename?)))
+
+(declare-function project-roots "ext:project" (project) t)
+(declare-function project-root "ext:project" (project) t)
+
+(defun lsp--suggest-project-root ()
+ "Get project root."
+ (or
+ (when (featurep 'projectile) (condition-case nil
+ (projectile-project-root)
+ (error nil)))
+ (when (featurep 'project)
+ (when-let ((project (project-current)))
+ (if (fboundp 'project-root)
+ (project-root project)
+ (car (with-no-warnings
+ (project-roots project))))))
+ default-directory))
+
+(defun lsp--read-from-file (file)
+ "Read FILE content."
+ (when (file-exists-p file)
+ (cl-first (read-from-string (f-read-text file 'utf-8)))))
+
+(defun lsp--persist (file-name to-persist)
+ "Persist TO-PERSIST in FILE-NAME.
+
+This function creates the parent directories if they don't exist
+yet."
+ (let ((print-length nil)
+ (print-level nil))
+ ;; Create all parent directories:
+ (make-directory (f-parent file-name) t)
+ (f-write-text (prin1-to-string to-persist) 'utf-8 file-name)))
+
+(defun lsp-workspace-folders-add (project-root)
+ "Add PROJECT-ROOT to the list of workspace folders."
+ (interactive
+ (list (read-directory-name "Select folder to add: "
+ (or (lsp--suggest-project-root) default-directory) nil t)))
+ (cl-pushnew (lsp-f-canonical project-root)
+ (lsp-session-folders (lsp-session)) :test 'equal)
+ (lsp--persist-session (lsp-session))
+
+ (run-hook-with-args 'lsp-workspace-folders-changed-functions (list project-root) nil))
+
+(defun lsp-workspace-folders-remove (project-root)
+ "Remove PROJECT-ROOT from the list of workspace folders."
+ (interactive (list (completing-read "Select folder to remove: "
+ (lsp-session-folders (lsp-session))
+ nil t nil nil
+ (lsp-find-session-folder (lsp-session) default-directory))))
+
+ (setq project-root (lsp-f-canonical project-root))
+
+ ;; send remove folder to each multiroot workspace associated with the folder
+ (dolist (wks (->> (lsp-session)
+ (lsp-session-folder->servers)
+ (gethash project-root)
+ (--filter (lsp--client-multi-root (lsp--workspace-client it)))))
+ (with-lsp-workspace wks
+ (lsp-notify "workspace/didChangeWorkspaceFolders"
+ (lsp-make-did-change-workspace-folders-params
+ :event (lsp-make-workspace-folders-change-event
+ :removed (vector (lsp-make-workspace-folder
+ :uri (lsp--path-to-uri project-root)
+ :name (f-filename project-root)))
+ :added [])))))
+
+ ;; turn off servers in the removed directory
+ (let* ((session (lsp-session))
+ (folder->servers (lsp-session-folder->servers session))
+ (server-id->folders (lsp-session-server-id->folders session))
+ (workspaces (gethash project-root folder->servers)))
+
+ (remhash project-root folder->servers)
+
+ ;; turn off the servers without root folders
+ (dolist (workspace workspaces)
+ (when (--none? (-contains? it workspace) (ht-values folder->servers))
+ (lsp--info "Shutdown %s since folder %s is removed..."
+ (lsp--workspace-print workspace) project-root)
+ (with-lsp-workspace workspace (lsp--shutdown-workspace))))
+
+ (setf (lsp-session-folders session)
+ (-remove-item project-root (lsp-session-folders session)))
+
+ (ht-aeach (puthash key
+ (-remove-item project-root value)
+ server-id->folders)
+ server-id->folders)
+ (lsp--persist-session (lsp-session)))
+
+ (run-hook-with-args 'lsp-workspace-folders-changed-functions nil (list project-root)))
+
+(defun lsp-workspace-blacklist-remove (project-root)
+ "Remove PROJECT-ROOT from the workspace blacklist."
+ (interactive (list (completing-read "Select folder to remove:"
+ (lsp-session-folders-blacklist (lsp-session))
+ nil t)))
+ (setf (lsp-session-folders-blacklist (lsp-session))
+ (delete project-root
+ (lsp-session-folders-blacklist (lsp-session))))
+ (lsp--persist-session (lsp-session)))
+
+(define-obsolete-function-alias 'lsp-workspace-folders-switch
+ 'lsp-workspace-folders-open "lsp-mode 6.1")
+
+(defun lsp-workspace-folders-open (project-root)
+ "Open the directory located at PROJECT-ROOT"
+ (interactive (list (completing-read "Open folder: "
+ (lsp-session-folders (lsp-session))
+ nil t)))
+ (find-file project-root))
+
+(defun lsp--maybe-enable-signature-help (trigger-characters)
+ (let ((ch last-command-event))
+ (when (cl-find ch trigger-characters :key #'string-to-char)
+ (lsp-signature-activate))))
+
+(defun lsp--on-type-formatting-handler-create ()
+ (when-let ((provider (lsp--capability :documentOnTypeFormattingProvider)))
+ (-let [(&DocumentOnTypeFormattingOptions :more-trigger-character?
+ :first-trigger-character) provider]
+ (lambda ()
+ (lsp--on-type-formatting first-trigger-character
+ more-trigger-character?)))))
+
+(defun lsp--update-on-type-formatting-hook (&optional cleanup?)
+ (let ((on-type-formatting-handler (lsp--on-type-formatting-handler-create)))
+ (cond
+ ((and lsp-enable-on-type-formatting on-type-formatting-handler (not cleanup?))
+ (add-hook 'post-self-insert-hook on-type-formatting-handler nil t))
+ ((or cleanup?
+ (not lsp-enable-on-type-formatting))
+ (remove-hook 'post-self-insert-hook on-type-formatting-handler t)))))
+
+(defun lsp--signature-help-handler-create ()
+ (-when-let ((&SignatureHelpOptions? :trigger-characters?)
+ (lsp--capability :signatureHelpProvider))
+ (lambda ()
+ (lsp--maybe-enable-signature-help trigger-characters?))))
+
+(defun lsp--update-signature-help-hook (&optional cleanup?)
+ (let ((signature-help-handler (lsp--signature-help-handler-create)))
+ (cond
+ ((and (or (equal lsp-signature-auto-activate t)
+ (memq :on-trigger-char lsp-signature-auto-activate))
+ signature-help-handler)
+ (add-hook 'post-self-insert-hook signature-help-handler nil t))
+
+ ((or cleanup?
+ (not (or (equal lsp-signature-auto-activate t)
+ (memq :on-trigger-char lsp-signature-auto-activate))))
+ (remove-hook 'post-self-insert-hook signature-help-handler t)))))
+
+(defun lsp--after-set-visited-file-name ()
+ (lsp-disconnect)
+ (lsp))
+
+(define-minor-mode lsp-managed-mode
+ "Mode for source buffers managed by lsp-mode."
+ :lighter nil
+ (cond
+ (lsp-managed-mode
+ (when (lsp-feature? "textDocument/hover")
+ (add-function :before-until (local 'eldoc-documentation-function) #'lsp-eldoc-function)
+ (eldoc-mode 1))
+
+ (add-hook 'after-change-functions #'lsp-on-change nil t)
+ (add-hook 'after-revert-hook #'lsp-on-revert nil t)
+ (add-hook 'after-save-hook #'lsp-on-save nil t)
+ (add-hook 'auto-save-hook #'lsp--on-auto-save nil t)
+ (add-hook 'before-change-functions #'lsp-before-change nil t)
+ (add-hook 'before-save-hook #'lsp--before-save nil t)
+ (add-hook 'kill-buffer-hook #'lsp--text-document-did-close nil t)
+ (add-hook 'post-command-hook #'lsp--post-command nil t)
+
+ (lsp--update-on-type-formatting-hook)
+ (lsp--update-signature-help-hook)
+
+ (when lsp-enable-xref
+ (add-hook 'xref-backend-functions #'lsp--xref-backend nil t))
+
+ (lsp-configure-buffer)
+
+ ;; make sure we turn off lsp-mode in case major mode changes, because major
+ ;; mode change will wipe the buffer locals.
+ (add-hook 'change-major-mode-hook #'lsp-disconnect nil t)
+ (add-hook 'after-set-visited-file-name-hook #'lsp--after-set-visited-file-name nil t)
+
+ (let ((buffer (lsp-current-buffer)))
+ (run-with-idle-timer
+ 0.0 nil
+ (lambda ()
+ (when (lsp-buffer-live-p buffer)
+ (lsp-with-current-buffer buffer
+ (lsp--on-change-debounce buffer)
+ (lsp--on-idle buffer)))))))
+ (t
+ (lsp-unconfig-buffer)
+ (remove-function (local 'eldoc-documentation-function) #'lsp-eldoc-function)
+
+ (remove-hook 'post-command-hook #'lsp--post-command t)
+ (remove-hook 'after-change-functions #'lsp-on-change t)
+ (remove-hook 'after-revert-hook #'lsp-on-revert t)
+ (remove-hook 'after-save-hook #'lsp-on-save t)
+ (remove-hook 'auto-save-hook #'lsp--on-auto-save t)
+ (remove-hook 'before-change-functions #'lsp-before-change t)
+ (remove-hook 'before-save-hook #'lsp--before-save t)
+ (remove-hook 'kill-buffer-hook #'lsp--text-document-did-close t)
+
+ (lsp--update-on-type-formatting-hook :cleanup)
+ (lsp--update-signature-help-hook :cleanup)
+
+ (when lsp--on-idle-timer
+ (cancel-timer lsp--on-idle-timer)
+ (setq lsp--on-idle-timer nil))
+
+ (remove-hook 'lsp-on-idle-hook #'lsp--document-links t)
+ (remove-hook 'lsp-on-idle-hook #'lsp--document-highlight t)
+
+ (lsp--remove-overlays 'lsp-highlight)
+ (lsp--remove-overlays 'lsp-links)
+
+ (remove-hook 'xref-backend-functions #'lsp--xref-backend t)
+ (remove-hook 'change-major-mode-hook #'lsp-disconnect t)
+ (remove-hook 'after-set-visited-file-name-hook #'lsp--after-set-visited-file-name t)
+ (setq-local lsp-buffer-uri nil))))
+
+(defun lsp-configure-buffer ()
+ "Configure LSP features for current buffer."
+ ;; make sure the core is running in the context of all available workspaces
+ ;; to avoid misconfiguration in case we are running in `with-lsp-workspace' context
+ (let ((lsp--buffer-workspaces (cond
+ (lsp--buffer-workspaces)
+ (lsp--cur-workspace (list lsp--cur-workspace))))
+ lsp--cur-workspace)
+ (when lsp-auto-configure
+ (when (and lsp-enable-text-document-color
+ (lsp-feature? "textDocument/documentColor"))
+ (add-hook 'lsp-on-change-hook #'lsp--document-color nil t))
+
+ (when (and lsp-enable-imenu
+ (lsp-feature? "textDocument/documentSymbol"))
+ (lsp-enable-imenu))
+
+ (when (and lsp-enable-indentation
+ (lsp-feature? "textDocument/rangeFormatting"))
+ (setq-local indent-region-function #'lsp-format-region))
+
+ (when (and lsp-enable-symbol-highlighting
+ (lsp-feature? "textDocument/documentHighlight"))
+ (add-hook 'lsp-on-idle-hook #'lsp--document-highlight nil t))
+
+ (when (and lsp-enable-links
+ (lsp-feature? "textDocument/documentLink"))
+ (add-hook 'lsp-on-idle-hook #'lsp--document-links nil t))
+
+ (when (and lsp-enable-dap-auto-configure
+ (functionp 'dap-mode))
+ (dap-auto-configure-mode 1)))
+ (run-hooks 'lsp-configure-hook)))
+
+(defun lsp-unconfig-buffer ()
+ "Unconfigure LSP features for buffer."
+ (run-hooks 'lsp-unconfigure-hook)
+
+ (lsp--remove-overlays 'lsp-color)
+ (when (eq indent-region-function #'lsp-format-region)
+ (setq-local indent-region-function nil))
+ (remove-hook 'lsp-on-change-hook #'lsp--document-color t)
+ (remove-hook 'lsp-on-idle-hook #'lsp--document-highlight t)
+ (remove-hook 'lsp-on-idle-hook #'lsp--document-links t))
+
+(defun lsp--buffer-content ()
+ (lsp-save-restriction-and-excursion
+ (or (lsp-virtual-buffer-call :buffer-string)
+ (buffer-substring-no-properties (point-min)
+ (point-max)))))
+
+(defun lsp--text-document-did-open ()
+ "'document/didOpen' event."
+ (run-hooks 'lsp-before-open-hook)
+ (when (and lsp-auto-touch-files
+ (not (f-exists? (lsp--uri-to-path (lsp--buffer-uri)))))
+ (lsp--info "Saving file '%s' because it is not present on the disk." (lsp--buffer-uri))
+ (save-buffer))
+
+ (setq lsp--cur-version (or lsp--cur-version 0))
+ (cl-pushnew (lsp-current-buffer) (lsp--workspace-buffers lsp--cur-workspace))
+ (lsp-notify
+ "textDocument/didOpen"
+ (list :textDocument
+ (list :uri (lsp--buffer-uri)
+ :languageId (lsp-buffer-language)
+ :version lsp--cur-version
+ :text (lsp--buffer-content))))
+
+ (lsp-managed-mode 1)
+
+ (run-hooks 'lsp-after-open-hook)
+ (when-let ((client (-some-> lsp--cur-workspace (lsp--workspace-client))))
+ (-some-> (lsp--client-after-open-fn client)
+ (funcall))
+ (-some-> (format "lsp-%s-after-open-hook" (lsp--client-server-id client))
+ (intern-soft)
+ (run-hooks))))
+
+(defun lsp--text-document-identifier ()
+ "Make TextDocumentIdentifier."
+ (list :uri (lsp--buffer-uri)))
+
+(defun lsp--versioned-text-document-identifier ()
+ "Make VersionedTextDocumentIdentifier."
+ (plist-put (lsp--text-document-identifier) :version lsp--cur-version))
+
+(defun lsp--cur-line (&optional point)
+ (1- (line-number-at-pos point)))
+
+(defun lsp--cur-position ()
+ "Make a Position object for the current point."
+ (or (lsp-virtual-buffer-call :cur-position)
+ (lsp-save-restriction-and-excursion
+ (list :line (lsp--cur-line)
+ :character (- (point) (line-beginning-position))))))
+
+(defun lsp--point-to-position (point)
+ "Convert POINT to Position."
+ (lsp-save-restriction-and-excursion
+ (goto-char point)
+ (lsp--cur-position)))
+
+(defun lsp--range (start end)
+ "Make Range body from START and END."
+ ;; make sure start and end are Position objects
+ (list :start start :end end))
+
+(defun lsp--region-to-range (start end)
+ "Make Range object for the current region."
+ (lsp--range (lsp--point-to-position start)
+ (lsp--point-to-position end)))
+
+(defun lsp--region-or-line ()
+ "The active region or the current line."
+ (if (use-region-p)
+ (lsp--region-to-range (region-beginning) (region-end))
+ (lsp--region-to-range (point-at-bol) (point-at-eol))))
+
+(defun lsp--check-document-changes-version (document-changes)
+ "Verify that DOCUMENT-CHANGES have the proper version."
+ (unless (seq-every-p
+ (-lambda ((&TextDocumentEdit :text-document))
+ (or
+ (not text-document)
+ (let* ((filename (-> text-document
+ lsp:versioned-text-document-identifier-uri
+ lsp--uri-to-path))
+ (version (lsp:versioned-text-document-identifier-version? text-document)))
+ (with-current-buffer (find-file-noselect filename)
+ (or (null version) (zerop version) (= -1 version)
+ (equal version lsp--cur-version))))))
+ document-changes)
+ (error "Document changes cannot be applied")))
+
+(defun lsp--apply-workspace-edit (workspace-edit &optional operation)
+ "Apply the WorkspaceEdit object WORKSPACE-EDIT.
+OPERATION is symbol representing the source of this text edit."
+ (-let (((&WorkspaceEdit :document-changes? :changes?) workspace-edit))
+ (if-let ((document-changes (seq-reverse document-changes?)))
+ (progn
+ (lsp--check-document-changes-version document-changes)
+ (->> document-changes
+ (seq-filter (-lambda ((&CreateFile :kind)) (equal kind "create")))
+ (seq-do (lambda (change) (lsp--apply-text-document-edit change operation))))
+ (->> document-changes
+ (seq-filter (-lambda ((&CreateFile :kind))
+ (and (or (not kind) (equal kind "edit"))
+ (not (equal kind "create")))))
+ (seq-do (lambda (change) (lsp--apply-text-document-edit change operation))))
+ (->> document-changes
+ (seq-filter (-lambda ((&CreateFile :kind))
+ (and (not (or (not kind) (equal kind "edit")))
+ (not (equal kind "create")))))
+ (seq-do (lambda (change) (lsp--apply-text-document-edit change operation)))))
+ (lsp-map
+ (lambda (uri text-edits)
+ (with-current-buffer (-> uri lsp--uri-to-path find-file-noselect)
+ (lsp--apply-text-edits text-edits operation)))
+ changes?))))
+
+(defmacro lsp-with-filename (file &rest body)
+ "Execute BODY with FILE as a context.
+Need to handle the case when FILE indicates virtual buffer."
+ (declare (indent 1) (debug t))
+ `(if-let ((lsp--virtual-buffer (get-text-property 0 'lsp-virtual-buffer ,file)))
+ (lsp-with-current-buffer lsp--virtual-buffer
+ ,@body)
+ ,@body))
+
+(defun lsp--apply-text-document-edit (edit &optional operation)
+ "Apply the TextDocumentEdit object EDIT.
+OPERATION is symbol representing the source of this text edit.
+If the file is not being visited by any buffer, it is opened with
+`find-file-noselect'.
+Because lsp-mode does not store previous document versions, the edit is only
+applied if the version of the textDocument matches the version of the
+corresponding file.
+
+interface TextDocumentEdit {
+ textDocument: VersionedTextDocumentIdentifier;
+ edits: TextEdit[];
+}"
+ (pcase (lsp:edit-kind edit)
+ ("create" (-let* (((&CreateFile :uri :options?) edit)
+ (file-name (lsp--uri-to-path uri)))
+ (mkdir (f-dirname file-name) t)
+ (f-touch file-name)
+ (when (lsp:create-file-options-overwrite? options?)
+ (f-write-text "" nil file-name))
+ (find-file-noselect file-name)))
+ ("delete" (-let (((&DeleteFile :uri :options? (&DeleteFileOptions? :recursive?)) edit))
+ (f-delete (lsp--uri-to-path uri) recursive?)))
+ ("rename" (-let* (((&RenameFile :old-uri :new-uri :options? (&RenameFileOptions? :overwrite?)) edit)
+ (old-file-name (lsp--uri-to-path old-uri))
+ (new-file-name (lsp--uri-to-path new-uri))
+ (buf (find-buffer-visiting old-file-name)))
+ (when buf
+ (lsp-with-current-buffer buf
+ (save-buffer)
+ (lsp--text-document-did-close)))
+ (mkdir (f-dirname new-file-name) t)
+ (rename-file old-file-name new-file-name overwrite?)
+ (when buf
+ (lsp-with-current-buffer buf
+ (set-buffer-modified-p nil)
+ (setq lsp-buffer-uri nil)
+ (set-visited-file-name new-file-name)
+ (lsp)))))
+ (_ (let ((file-name (->> edit
+ (lsp:text-document-edit-text-document)
+ (lsp:versioned-text-document-identifier-uri)
+ (lsp--uri-to-path))))
+ (lsp-with-current-buffer (find-buffer-visiting file-name)
+ (lsp-with-filename file-name
+ (lsp--apply-text-edits (lsp:text-document-edit-edits edit) operation)))))))
+
+(lsp-defun lsp--position-compare ((&Position :line left-line
+ :character left-character)
+ (&Position :line right-line
+ :character right-character))
+ "Return t if position LEFT is greater than RIGHT."
+ (if (= left-line right-line)
+ (> left-character right-character)
+ (> left-line right-line)))
+
+(lsp-defun lsp-point-in-range? (position (&Range :start :end))
+ "Returns if POINT is in RANGE."
+ (not (or (lsp--position-compare start position)
+ (lsp--position-compare position end))))
+
+(lsp-defun lsp--position-equal ((&Position :line left-line
+ :character left-character)
+ (&Position :line right-line
+ :character right-character))
+ "Return whether LEFT and RIGHT positions are equal."
+ (and (= left-line right-line)
+ (= left-character right-character)))
+
+(lsp-defun lsp--text-edit-sort-predicate ((&TextEdit :range (&Range :start left-start :end left-end))
+ (&TextEdit :range (&Range :start right-start :end right-end)))
+ (if (lsp--position-equal left-start right-start)
+ (lsp--position-compare left-end right-end)
+ (lsp--position-compare left-start right-start)))
+
+(lsp-defun lsp--apply-text-edit ((edit &as &TextEdit :range (&RangeToPoint :start :end) :new-text))
+ "Apply the edits described in the TextEdit object in TEXT-EDIT."
+ ;; We sort text edits so as to apply edits that modify latter parts of the
+ ;; document first. Furthermore, because the LSP spec dictates that:
+ ;; "If multiple inserts have the same position, the order in the array
+ ;; defines which edit to apply first."
+ ;; We reverse the initial list and sort stably to make sure the order among
+ ;; edits with the same position is preserved.
+ (setq new-text (s-replace "\r" "" (or new-text "")))
+ (lsp:set-text-edit-new-text edit new-text)
+ (goto-char start)
+ (delete-region start end)
+ (insert new-text))
+
+;; WORKAROUND: typescript-language might send -1 when applying code actions.
+;; see https://github.com/emacs-lsp/lsp-mode/issues/1582
+(lsp-defun lsp--fix-point ((point &as &Position :character :line))
+ (-doto point
+ (lsp:set-position-line (max 0 line))
+ (lsp:set-position-character (max 0 character))))
+
+(lsp-defun lsp--apply-text-edit-replace-buffer-contents ((edit &as
+ &TextEdit
+ :range (&Range :start :end)
+ :new-text))
+ "Apply the edits described in the TextEdit object in TEXT-EDIT.
+The method uses `replace-buffer-contents'."
+ (setq new-text (s-replace "\r" "" (or new-text "")))
+ (lsp:set-text-edit-new-text edit new-text)
+ (-let* ((source (current-buffer))
+ ((beg . end) (lsp--range-to-region (lsp-make-range :start (lsp--fix-point start)
+ :end (lsp--fix-point end)))))
+ (with-temp-buffer
+ (insert new-text)
+ (let ((temp (current-buffer)))
+ (with-current-buffer source
+ (save-excursion
+ (save-restriction
+ (narrow-to-region beg end)
+
+ ;; On emacs versions < 26.2,
+ ;; `replace-buffer-contents' is buggy - it calls
+ ;; change functions with invalid arguments - so we
+ ;; manually call the change functions here.
+ ;;
+ ;; See emacs bugs #32237, #32278:
+ ;; https://debbugs.gnu.org/cgi/bugreport.cgi?bug=32237
+ ;; https://debbugs.gnu.org/cgi/bugreport.cgi?bug=32278
+ (let ((inhibit-modification-hooks t)
+ (length (- end beg)))
+ (run-hook-with-args 'before-change-functions
+ beg end)
+ (replace-buffer-contents temp)
+ (run-hook-with-args 'after-change-functions
+ beg (+ beg (length new-text))
+ length)))))))))
+
+(defun lsp--to-yasnippet-snippet (snippet)
+ "Convert LSP SNIPPET to yasnippet snippet."
+ ;; LSP snippet doesn't escape "{" and "`", but yasnippet requires escaping it.
+ (replace-regexp-in-string (rx (or bos (not (any "$" "\\"))) (group (or "{" "`")))
+ (rx "\\" (backref 1))
+ snippet
+ nil nil 1))
+
+(defvar-local lsp-enable-relative-indentation nil
+ "Enable relative indentation when insert texts, snippets ...
+from language server.")
+
+(defun lsp--expand-snippet (snippet &optional start end expand-env)
+ "Wrapper of `yas-expand-snippet' with all of it arguments.
+The snippet will be convert to LSP style and indent according to
+LSP server result."
+ (let* ((inhibit-field-text-motion t)
+ (yas-wrap-around-region nil)
+ (yas-indent-line 'none)
+ (yas-also-auto-indent-first-line nil))
+ (yas-expand-snippet
+ (lsp--to-yasnippet-snippet snippet)
+ start end expand-env)))
+
+(defun lsp--indent-lines (start end &optional insert-text-mode?)
+ "Indent from START to END based on INSERT-TEXT-MODE? value.
+- When INSERT-TEXT-MODE? is provided
+ - if it's `lsp/insert-text-mode-as-it', do no editor indentation.
+ - if it's `lsp/insert-text-mode-adjust-indentation', adjust leading
+ whitespaces to match the line where text is inserted.
+- When it's not provided, using `indent-line-function' for each line."
+ (save-excursion
+ (goto-char end)
+ (let* ((end-line (line-number-at-pos))
+ (offset (save-excursion
+ (goto-char start)
+ (current-indentation)))
+ (indent-line-function
+ (cond ((equal insert-text-mode? lsp/insert-text-mode-as-it)
+ #'ignore)
+ ((or (equal insert-text-mode? lsp/insert-text-mode-adjust-indentation)
+ lsp-enable-relative-indentation
+ ;; Indenting snippets is extremely slow in `org-mode' buffers
+ ;; since it has to calculate indentation based on SRC block
+ ;; position. Thus we use relative indentation as default.
+ (derived-mode-p 'org-mode))
+ (lambda () (save-excursion
+ (beginning-of-line)
+ (indent-to-column offset))))
+ (t indent-line-function))))
+ (goto-char start)
+ (forward-line)
+ (while (and (not (eobp))
+ (<= (line-number-at-pos) end-line))
+ (funcall indent-line-function)
+ (forward-line)))))
+
+(defun lsp--apply-text-edits (edits &optional operation)
+ "Apply the EDITS described in the TextEdit[] object.
+OPERATION is symbol representing the source of this text edit."
+ (unless (seq-empty-p edits)
+ (atomic-change-group
+ (run-hooks 'lsp-before-apply-edits-hook)
+ (let* ((change-group (prepare-change-group))
+ (howmany (length edits))
+ (message (format "Applying %s edits to `%s' ..." howmany (current-buffer)))
+ (_ (lsp--info message))
+ (reporter (make-progress-reporter message 0 howmany))
+ (done 0)
+ (apply-edit (if (not lsp--virtual-buffer)
+ #'lsp--apply-text-edit-replace-buffer-contents
+ #'lsp--apply-text-edit)))
+ (unwind-protect
+ (->> edits
+ (nreverse)
+ (seq-sort #'lsp--text-edit-sort-predicate)
+ (mapc (lambda (edit)
+ (progress-reporter-update reporter (cl-incf done))
+ (funcall apply-edit edit)
+ (when (lsp:snippet-text-edit-insert-text-format? edit)
+ (-when-let ((&SnippetTextEdit :range (&RangeToPoint :start)
+ :insert-text-format? :new-text) edit)
+ (when (eq insert-text-format? lsp/insert-text-format-snippet)
+ ;; No `save-excursion' needed since expand snippet will change point anyway
+ (goto-char (+ start (length new-text)))
+ (lsp--indent-lines start (point))
+ (lsp--expand-snippet new-text start (point)))))
+ (run-hook-with-args 'lsp-after-apply-edits-hook operation))))
+ (undo-amalgamate-change-group change-group)
+ (progress-reporter-done reporter))))))
+
+(defun lsp--create-apply-text-edits-handlers ()
+ "Create (handler cleanup-fn) for applying text edits in async request.
+Only works when mode is 'tick or 'alive."
+ (let* (first-edited
+ (func (lambda (start &rest _)
+ (setq first-edited (if first-edited
+ (min start first-edited)
+ start)))))
+ (add-hook 'before-change-functions func nil t)
+ (list
+ (lambda (edits)
+ (if (and first-edited
+ (seq-find (-lambda ((&TextEdit :range (&RangeToPoint :end)))
+ ;; Text edit region is overlapped
+ (> end first-edited))
+ edits))
+ (lsp--warn "TextEdits will not be applied since document has been modified before of them.")
+ (lsp--apply-text-edits edits 'completion-cleanup)))
+ (lambda ()
+ (remove-hook 'before-change-functions func t)))))
+
+(defun lsp--capability (cap &optional capabilities)
+ "Get the value of capability CAP. If CAPABILITIES is non-nil, use them instead."
+ (when (stringp cap)
+ (setq cap (intern (concat ":" cap))))
+
+ (lsp-get (or capabilities
+ (lsp--server-capabilities))
+ cap))
+
+(defun lsp--registered-capability (method)
+ "Check whether there is workspace providing METHOD."
+ (->> (lsp-workspaces)
+ (--keep (seq-find (lambda (reg)
+ (equal (lsp--registered-capability-method reg) method))
+ (lsp--workspace-registered-server-capabilities it)))
+ cl-first))
+
+(defvar-local lsp--before-change-vals nil
+ "Store the positions from the `lsp-before-change' function call, for
+validation and use in the `lsp-on-change' function.")
+
+(defun lsp--text-document-content-change-event (start end length)
+ "Make a TextDocumentContentChangeEvent body for START to END, of length LENGTH."
+ ;; So (47 54 0) means add 7 chars starting at pos 47
+ ;; must become
+ ;; {"range":{"start":{"line":5,"character":6}
+ ;; ,"end" :{"line":5,"character":6}}
+ ;; ,"rangeLength":0
+ ;; ,"text":"\nbb = 5"}
+ ;;
+ ;; And (47 47 7) means delete 7 chars starting at pos 47
+ ;; must become
+ ;; {"range":{"start":{"line":6,"character":0}
+ ;; ,"end" :{"line":7,"character":0}}
+ ;; ,"rangeLength":7
+ ;; ,"text":""}
+ ;;
+ ;; (208 221 3) means delete 3 chars starting at pos 208, and replace them with
+ ;; 13 chars. So it must become
+ ;; {"range":{"start":{"line":5,"character":8}
+ ;; ,"end" :{"line":5,"character":11}}
+ ;; ,"rangeLength":3
+ ;; ,"text":"new-chars-xxx"}
+ ;;
+
+ ;; Adding text:
+ ;; lsp-before-change:(start,end)=(33,33)
+ ;; lsp-on-change:(start,end,length)=(33,34,0)
+ ;;
+ ;; Changing text:
+ ;; lsp-before-change:(start,end)=(208,211)
+ ;; lsp-on-change:(start,end,length)=(208,221,3)
+ ;;
+ ;; Deleting text:
+ ;; lsp-before-change:(start,end)=(19,27)
+ ;; lsp-on-change:(start,end,length)=(19,19,8)
+ (if (zerop length)
+ ;; Adding something only, work from start only
+ `( :range ,(lsp--range
+ (lsp--point-to-position start)
+ (lsp--point-to-position start))
+ :rangeLength 0
+ :text ,(buffer-substring-no-properties start end))
+
+ (if (eq start end)
+ ;; Deleting something only
+ (if (lsp--bracketed-change-p start length)
+ ;; The before-change value is bracketed, use it
+ `( :range ,(lsp--range
+ (lsp--point-to-position start)
+ (plist-get lsp--before-change-vals :end-pos))
+ :rangeLength ,length
+ :text "")
+ ;; If the change is not bracketed, send a full change event instead.
+ (lsp--full-change-event))
+
+ ;; Deleting some things, adding others
+ (if (lsp--bracketed-change-p start length)
+ ;; The before-change value is valid, use it
+ `( :range ,(lsp--range
+ (lsp--point-to-position start)
+ (plist-get lsp--before-change-vals :end-pos))
+ :rangeLength ,length
+ :text ,(buffer-substring-no-properties start end))
+ (lsp--full-change-event)))))
+
+(defun lsp--bracketed-change-p (start length)
+ "If the before and after positions are the same, and the length
+is the size of the start range, we are probably good."
+ (-let [(&plist :end before-end :start before-start) lsp--before-change-vals]
+ (and (eq start before-start)
+ (eq length (- before-end before-start)))))
+
+(defun lsp--full-change-event ()
+ `(:text ,(lsp--buffer-content)))
+
+(defun lsp-before-change (start end)
+ "Executed before a file is changed.
+Added to `before-change-functions'."
+ ;; Note:
+ ;;
+ ;; This variable holds a list of functions to call when Emacs is about to
+ ;; modify a buffer. Each function gets two arguments, the beginning and end of
+ ;; the region that is about to change, represented as integers. The buffer
+ ;; that is about to change is always the current buffer when the function is
+ ;; called.
+ ;;
+ ;; WARNING:
+ ;;
+ ;; Do not expect the before-change hooks and the after-change hooks be called
+ ;; in balanced pairs around each buffer change. Also don't expect the
+ ;; before-change hooks to be called for every chunk of text Emacs is about to
+ ;; delete. These hooks are provided on the assumption that Lisp programs will
+ ;; use either before- or the after-change hooks, but not both, and the
+ ;; boundaries of the region where the changes happen might include more than
+ ;; just the actual changed text, or even lump together several changes done
+ ;; piecemeal.
+ (save-match-data
+ (lsp-save-restriction-and-excursion
+ (setq lsp--before-change-vals
+ (list :start start
+ :end end
+ :end-pos (lsp--point-to-position end))))))
+
+(defun lsp--flush-delayed-changes ()
+ (let ((inhibit-quit t))
+ (when lsp--delay-timer
+ (cancel-timer lsp--delay-timer))
+ (mapc (-lambda ((workspace buffer document change))
+ (with-current-buffer buffer
+ (with-lsp-workspace workspace
+ (lsp-notify "textDocument/didChange"
+ (list :textDocument document
+ :contentChanges (vector change))))))
+ (prog1 (nreverse lsp--delayed-requests)
+ (setq lsp--delayed-requests nil)))))
+
+(defun lsp--workspace-sync-method (workspace)
+ (let* ((sync (-> workspace
+ (lsp--workspace-server-capabilities)
+ (lsp:server-capabilities-text-document-sync?))))
+ (if (lsp-text-document-sync-options? sync)
+ (lsp:text-document-sync-options-change? sync)
+ sync)))
+
+(defun lsp-on-change (start end length &optional content-change-event-fn)
+ "Executed when a file is changed.
+Added to `after-change-functions'."
+ ;; Note:
+ ;;
+ ;; Each function receives three arguments: the beginning and end of the region
+ ;; just changed, and the length of the text that existed before the change.
+ ;; All three arguments are integers. The buffer that has been changed is
+ ;; always the current buffer when the function is called.
+ ;;
+ ;; The length of the old text is the difference between the buffer positions
+ ;; before and after that text as it was before the change. As for the
+ ;; changed text, its length is simply the difference between the first two
+ ;; arguments.
+ ;;
+ ;; So (47 54 0) means add 7 chars starting at pos 47
+ ;; So (47 47 7) means delete 7 chars starting at pos 47
+ (save-match-data
+ (let ((inhibit-quit t)
+ ;; make sure that `lsp-on-change' is called in multi-workspace context
+ ;; see #2901
+ lsp--cur-workspace)
+ ;; A (revert-buffer) call with the 'preserve-modes parameter (eg, as done
+ ;; by auto-revert-mode) will cause this handler to get called with a nil
+ ;; buffer-file-name. We need the buffer-file-name to send notifications;
+ ;; so we skip handling revert-buffer-caused changes and instead handle
+ ;; reverts separately in lsp-on-revert
+ (when (not revert-buffer-in-progress-p)
+ (cl-incf lsp--cur-version)
+ (mapc
+ (lambda (workspace)
+ (pcase (or lsp-document-sync-method
+ (lsp--workspace-sync-method workspace))
+ (1
+ (if lsp-debounce-full-sync-notifications
+ (setq lsp--delayed-requests
+ (->> lsp--delayed-requests
+ (-remove (-lambda ((_ buffer))
+ (equal (current-buffer) buffer)))
+ (cons (list workspace
+ (current-buffer)
+ (lsp--versioned-text-document-identifier)
+ (lsp--full-change-event)))))
+ (with-lsp-workspace workspace
+ (lsp-notify "textDocument/didChange"
+ (list :contentChanges (vector (lsp--full-change-event))
+ :textDocument (lsp--versioned-text-document-identifier))))))
+ (2
+ (with-lsp-workspace workspace
+ (lsp-notify
+ "textDocument/didChange"
+ (list :textDocument (lsp--versioned-text-document-identifier)
+ :contentChanges (vector
+ (if content-change-event-fn
+ (funcall content-change-event-fn start end length)
+ (lsp--text-document-content-change-event
+ start end length)))))))))
+ (lsp-workspaces))
+ (when lsp--delay-timer (cancel-timer lsp--delay-timer))
+ (setq lsp--delay-timer (run-with-idle-timer
+ lsp-debounce-full-sync-notifications-interval
+ nil
+ #'lsp--flush-delayed-changes))
+ ;; force cleanup overlays after each change
+ (lsp--remove-overlays 'lsp-highlight)
+ (lsp--after-change (current-buffer))
+ (setq lsp--signature-last-index nil
+ lsp--signature-last nil)
+ ;; cleanup diagnostics
+ (when lsp-diagnostic-clean-after-change
+ (lsp-foreach-workspace
+ (-let [diagnostics (lsp--workspace-diagnostics lsp--cur-workspace)]
+ (remhash (lsp--fix-path-casing (buffer-file-name)) diagnostics))))))))
+
+
+
+;; facilities for on change hooks. We do not want to make lsp calls on each
+;; change event so we add debounce to avoid flooding the server with events.
+;; Additionally, we want to have a mechanism for stopping the server calls in
+;; particular cases like, e. g. when performing completion.
+
+(defvar lsp-inhibit-lsp-hooks nil
+ "Flag to control.")
+
+(defcustom lsp-on-change-hook nil
+ "Hooks to run when buffer has changed."
+ :type 'hook
+ :group 'lsp-mode)
+
+(defcustom lsp-idle-delay 0.500
+ "Debounce interval for `after-change-functions'."
+ :type 'number
+ :group 'lsp-mode)
+
+(defcustom lsp-on-idle-hook nil
+ "Hooks to run after `lsp-idle-delay'."
+ :type 'hook
+ :group 'lsp-mode)
+
+(defun lsp--idle-reschedule (buffer)
+ (when lsp--on-idle-timer
+ (cancel-timer lsp--on-idle-timer))
+
+ (setq lsp--on-idle-timer (run-with-idle-timer
+ lsp-idle-delay
+ nil
+ #'lsp--on-idle
+ buffer)))
+
+(defun lsp--post-command ()
+ (lsp--cleanup-highlights-if-needed)
+ (lsp--idle-reschedule (current-buffer)))
+
+(defun lsp--on-idle (buffer)
+ "Start post command loop."
+ (when (and (buffer-live-p buffer)
+ (equal buffer (current-buffer))
+ (not lsp-inhibit-lsp-hooks)
+ lsp-managed-mode)
+ (run-hooks 'lsp-on-idle-hook)))
+
+(defun lsp--on-change-debounce (buffer)
+ (when (and (buffer-live-p buffer)
+ (equal buffer (current-buffer))
+ (not lsp-inhibit-lsp-hooks)
+ lsp-managed-mode)
+ (run-hooks 'lsp-on-change-hook)))
+
+(defun lsp--after-change (buffer)
+ (when (fboundp 'lsp--semantic-tokens-refresh-if-enabled)
+ (lsp--semantic-tokens-refresh-if-enabled buffer))
+ (when lsp--on-change-timer
+ (cancel-timer lsp--on-change-timer))
+ (setq lsp--on-change-timer (run-with-idle-timer
+ lsp-idle-delay
+ nil
+ #'lsp--on-change-debounce
+ buffer))
+ (lsp--idle-reschedule buffer))
+
+
+
+(defun lsp--on-type-formatting (first-trigger-characters more-trigger-characters)
+ "Self insert handling.
+Applies on type formatting."
+ (let ((ch last-command-event))
+ (when (or (eq (string-to-char first-trigger-characters) ch)
+ (cl-find ch more-trigger-characters :key #'string-to-char))
+ (lsp-request-async "textDocument/onTypeFormatting"
+ (lsp-make-document-on-type-formatting-params
+ :text-document (lsp--text-document-identifier)
+ :options (lsp-make-formatting-options
+ :tab-size (symbol-value (lsp--get-indent-width major-mode))
+ :insert-spaces (if indent-tabs-mode :json-false t))
+ :ch (char-to-string ch)
+ :position (lsp--cur-position))
+ (lambda (data) (lsp--apply-text-edits data 'format))
+ :mode 'tick))))
+
+
+;; links
+(defun lsp--document-links ()
+ (when (lsp-feature? "textDocument/documentLink")
+ (lsp-request-async
+ "textDocument/documentLink"
+ `(:textDocument ,(lsp--text-document-identifier))
+ (lambda (links)
+ (lsp--remove-overlays 'lsp-link)
+ (seq-do
+ (-lambda ((link &as &DocumentLink :range (&Range :start :end)))
+ (-doto (make-button (lsp--position-to-point start)
+ (lsp--position-to-point end)
+ 'action (lsp--document-link-keymap link)
+ 'keymap (let ((map (make-sparse-keymap)))
+ (define-key map [M-return] 'push-button)
+ (define-key map [mouse-2] 'push-button)
+ map)
+ 'help-echo "mouse-2, M-RET: Visit this link")
+ (overlay-put 'lsp-link t)))
+ links))
+ :mode 'unchanged)))
+
+(defun lsp--document-link-handle-target (url)
+ (let* ((parsed-url (url-generic-parse-url (url-unhex-string url)))
+ (type (url-type parsed-url)))
+ (pcase type
+ ("file"
+ (find-file (lsp--uri-to-path url))
+ (-when-let ((_ line column) (s-match (rx "#" (group (1+ num)) "," (group (1+ num))) url))
+ (goto-char (lsp--position-to-point
+ (lsp-make-position :character (1- (string-to-number column))
+ :line (1- (string-to-number line)))))))
+ ((or "http" "https") (browse-url url))
+ (type (if-let ((handler (lsp--get-uri-handler type)))
+ (funcall handler url)
+ (signal 'lsp-file-scheme-not-supported (list url)))))))
+
+(lsp-defun lsp--document-link-keymap ((link &as &DocumentLink :target?))
+ (if target?
+ (lambda (_)
+ (interactive)
+ (lsp--document-link-handle-target target?))
+ (lambda (_)
+ (interactive)
+ (when (lsp:document-link-registration-options-resolve-provider?
+ (lsp--capability :documentLinkProvider))
+ (lsp-request-async
+ "documentLink/resolve"
+ link
+ (-lambda ((&DocumentLink :target?))
+ (lsp--document-link-handle-target target?)))))))
+
+
+
+(defun lsp-buffer-language ()
+ "Get language corresponding current buffer."
+ (or (->> lsp-language-id-configuration
+ (-first (-lambda ((mode-or-pattern . language))
+ (cond
+ ((and (stringp mode-or-pattern)
+ (s-matches? mode-or-pattern (buffer-file-name))) language)
+ ((eq mode-or-pattern major-mode) language))))
+ cl-rest)
+ (lsp-warn "Unable to calculate the languageId for buffer `%s'. Take a look at `lsp-language-id-configuration'. The `major-mode' is %s"
+ (buffer-name)
+ major-mode)))
+
+(defun lsp-activate-on (&rest languages)
+ "Returns language activation function.
+The function will return t when the `lsp-buffer-language' returns
+one of the LANGUAGES."
+ (lambda (_file-name _mode)
+ (-contains? languages (lsp-buffer-language))))
+
+(defun lsp-workspace-root (&optional path)
+ "Find the workspace root for the current file or PATH."
+ (-when-let* ((file-name (or path (buffer-file-name)))
+ (file-name (lsp-f-canonical file-name)))
+ (->> (lsp-session)
+ (lsp-session-folders)
+ (--filter (and (lsp--files-same-host it file-name)
+ (or (lsp-f-ancestor-of? it file-name)
+ (equal it file-name))))
+ (--max-by (> (length it) (length other))))))
+
+(defun lsp-on-revert ()
+ "Executed when a file is reverted.
+Added to `after-revert-hook'."
+ (let ((n (buffer-size))
+ (revert-buffer-in-progress-p nil))
+ (lsp-on-change 0 n n)))
+
+(defun lsp--text-document-did-close (&optional keep-workspace-alive)
+ "Executed when the file is closed, added to `kill-buffer-hook'.
+
+If KEEP-WORKSPACE-ALIVE is non-nil, do not shutdown the workspace
+if it's closing the last buffer in the workspace."
+ (lsp-foreach-workspace
+ (cl-callf2 delq (lsp-current-buffer) (lsp--workspace-buffers lsp--cur-workspace))
+ (with-demoted-errors "Error sending didClose notification in ‘lsp--text-document-did-close’: %S"
+ (lsp-notify "textDocument/didClose"
+ `(:textDocument ,(lsp--text-document-identifier))))
+ (when (and (not lsp-keep-workspace-alive)
+ (not keep-workspace-alive)
+ (not (lsp--workspace-buffers lsp--cur-workspace)))
+ (lsp--shutdown-workspace))))
+
+(defun lsp--will-save-text-document-params (reason)
+ (list :textDocument (lsp--text-document-identifier)
+ :reason reason))
+
+(defun lsp--before-save ()
+ "Before save handler."
+ (with-demoted-errors "Error in ‘lsp--before-save’: %S"
+ (let ((params (lsp--will-save-text-document-params 1)))
+ (when (lsp--send-will-save-p)
+ (lsp-notify "textDocument/willSave" params))
+ (when (and (lsp--send-will-save-wait-until-p) lsp-before-save-edits)
+ (let ((lsp-response-timeout 0.1))
+ (condition-case nil
+ (lsp--apply-text-edits
+ (lsp-request "textDocument/willSaveWaitUntil"
+ params)
+ 'before-save)
+ (error)))))))
+
+(defun lsp--on-auto-save ()
+ "Handler for auto-save."
+ (when (lsp--send-will-save-p)
+ (with-demoted-errors "Error in ‘lsp--on-auto-save’: %S"
+ (lsp-notify "textDocument/willSave" (lsp--will-save-text-document-params 2)))))
+
+(defun lsp--text-document-did-save ()
+ "Executed when the file is closed, added to `after-save-hook''."
+ (when (lsp--send-did-save-p)
+ (with-demoted-errors "Error on ‘lsp--text-document-did-save: %S’"
+ (lsp-notify "textDocument/didSave"
+ `( :textDocument ,(lsp--versioned-text-document-identifier)
+ ,@(when (lsp--save-include-text-p)
+ (list :text (lsp--buffer-content))))))))
+
+(defun lsp--text-document-position-params (&optional identifier position)
+ "Make TextDocumentPositionParams for the current point in the current document.
+If IDENTIFIER and POSITION are non-nil, they will be used as the document identifier
+and the position respectively."
+ (list :textDocument (or identifier (lsp--text-document-identifier))
+ :position (or position (lsp--cur-position))))
+
+(defun lsp--get-buffer-diagnostics ()
+ "Return buffer diagnostics."
+ (gethash (or
+ (plist-get lsp--virtual-buffer :buffer-file-name)
+ (lsp--fix-path-casing (buffer-file-name)))
+ (lsp-diagnostics t)))
+
+(defun lsp-cur-line-diagnostics ()
+ "Return any diagnostics that apply to the current line."
+ (-let [(&plist :start (&plist :line start) :end (&plist :line end)) (lsp--region-or-line)]
+ (cl-coerce (-filter
+ (-lambda ((&Diagnostic :range (&Range :start (&Position :line))))
+ (and (>= line start) (<= line end)))
+ (lsp--get-buffer-diagnostics))
+ 'vector)))
+
+(defalias 'lsp--cur-line-diagnotics 'lsp-cur-line-diagnostics)
+
+(defun lsp--extract-line-from-buffer (pos)
+ "Return the line pointed to by POS (a Position object) in the current buffer."
+ (let* ((point (lsp--position-to-point pos))
+ (inhibit-field-text-motion t))
+ (save-excursion
+ (goto-char point)
+ (buffer-substring (line-beginning-position) (line-end-position)))))
+
+(lsp-defun lsp--xref-make-item (filename (&Range :start (start &as &Position :character start-char :line start-line)
+ :end (end &as &Position :character end-char)))
+ "Return a xref-item from a RANGE in FILENAME."
+ (let* ((line (lsp--extract-line-from-buffer start))
+ (len (length line)))
+ (add-face-text-property (max (min start-char len) 0)
+ (max (min end-char len) 0)
+ 'highlight t line)
+ ;; LINE is nil when FILENAME is not being current visited by any buffer.
+ (xref-make (or line filename)
+ (xref-make-file-location
+ filename
+ (lsp-translate-line (1+ start-line))
+ (lsp-translate-column start-char)))))
+
+(defun lsp--location-uri (loc)
+ (if (lsp-location? loc)
+ (lsp:location-uri loc)
+ (lsp:location-link-target-uri loc)))
+
+(lsp-defun lsp-goto-location ((loc &as &Location :uri :range (&Range :start)))
+ "Go to location."
+ (let ((path (lsp--uri-to-path uri)))
+ (if (f-exists? path)
+ (with-current-buffer (find-file path)
+ (goto-char (lsp--position-to-point start)))
+ (error "There is no file %s" path))))
+
+(defun lsp--location-range (loc)
+ (if (lsp-location? loc)
+ (lsp:location-range loc)
+ (lsp:location-link-target-selection-range loc)))
+
+(defun lsp--locations-to-xref-items (locations)
+ "Return a list of `xref-item' given LOCATIONS, which can be of
+type Location, LocationLink, Location[] or LocationLink[]."
+ (setq locations
+ (pcase locations
+ ((seq (or (Location)
+ (LocationLink)))
+ (append locations nil))
+ ((or (Location)
+ (LocationLink))
+ (list locations))))
+
+ (cl-labels ((get-xrefs-in-file
+ (file-locs)
+ (-let [(filename . matches) file-locs]
+ (condition-case err
+ (let ((visiting (find-buffer-visiting filename))
+ (fn (lambda (loc)
+ (lsp-with-filename filename
+ (lsp--xref-make-item filename
+ (lsp--location-range loc))))))
+ (if visiting
+ (with-current-buffer visiting
+ (seq-map fn matches))
+ (when (file-readable-p filename)
+ (with-temp-buffer
+ (insert-file-contents-literally filename)
+ (seq-map fn matches)))))
+ (error (lsp-warn "Failed to process xref entry for filename '%s': %s"
+ filename (error-message-string err)))
+ (file-error (lsp-warn "Failed to process xref entry, file-error, '%s': %s"
+ filename (error-message-string err)))))))
+
+ (->> locations
+ (seq-sort #'lsp--location-before-p)
+ (seq-group-by (-compose #'lsp--uri-to-path #'lsp--location-uri))
+ (seq-map #'get-xrefs-in-file)
+ (apply #'nconc))))
+
+(defun lsp--location-before-p (left right)
+ "Sort first by file, then by line, then by column."
+ (let ((left-uri (lsp--location-uri left))
+ (right-uri (lsp--location-uri right)))
+ (if (not (string= left-uri right-uri))
+ (string< left-uri right-uri)
+ (-let (((&Range :start left-start) (lsp--location-range left))
+ ((&Range :start right-start) (lsp--location-range right)))
+ (lsp--position-compare right-start left-start)))))
+
+(defun lsp--make-reference-params (&optional td-position include-declaration)
+ "Make a ReferenceParam object.
+If TD-POSITION is non-nil, use it as TextDocumentPositionParams object instead.
+If INCLUDE-DECLARATION is non-nil, request the server to include declarations."
+ (let ((json-false :json-false))
+ (plist-put (or td-position (lsp--text-document-position-params))
+ :context `(:includeDeclaration ,(or include-declaration json-false)))))
+
+(defun lsp--cancel-request (id)
+ "Cancel request with ID in all workspaces."
+ (lsp-foreach-workspace
+ (->> lsp--cur-workspace lsp--workspace-client lsp--client-response-handlers (remhash id))
+ (lsp-notify "$/cancelRequest" `(:id ,id))))
+
+(defun lsp-eldoc-function ()
+ "`lsp-mode' eldoc function."
+ (run-hooks 'lsp-eldoc-hook)
+ eldoc-last-message)
+
+(defun lsp--point-on-highlight? ()
+ (-some? (lambda (overlay)
+ (overlay-get overlay 'lsp-highlight))
+ (overlays-at (point))))
+
+(defun lsp--cleanup-highlights-if-needed ()
+ (when (and lsp-enable-symbol-highlighting
+ lsp--have-document-highlights
+ (not (lsp--point-on-highlight?)))
+ (lsp--remove-overlays 'lsp-highlight)
+ (setq lsp--have-document-highlights nil)
+ (lsp-cancel-request-by-token :highlights)))
+
+(defvar-local lsp--symbol-bounds-of-last-highlight-invocation nil
+ "The bounds of the symbol from which `lsp--document-highlight'
+ most recently requested highlights.")
+
+(defun lsp--document-highlight ()
+ (when (lsp-feature? "textDocument/documentHighlight")
+ (let ((curr-sym-bounds (bounds-of-thing-at-point 'symbol)))
+ (unless (or (looking-at "[[:space:]\n]")
+ (not lsp-enable-symbol-highlighting)
+ (and lsp--have-document-highlights
+ curr-sym-bounds
+ (equal curr-sym-bounds
+ lsp--symbol-bounds-of-last-highlight-invocation)))
+ (setq lsp--symbol-bounds-of-last-highlight-invocation
+ curr-sym-bounds)
+ (lsp-request-async "textDocument/documentHighlight"
+ (lsp--text-document-position-params)
+ #'lsp--document-highlight-callback
+ :mode 'tick
+ :cancel-token :highlights)))))
+
+(defun lsp-describe-thing-at-point ()
+ "Display the type signature and documentation of the thing at
+point."
+ (interactive)
+ (let ((contents (-some->> (lsp--text-document-position-params)
+ (lsp--make-request "textDocument/hover")
+ (lsp--send-request)
+ (lsp:hover-contents))))
+ (if (and contents (not (equal contents "")))
+ (let ((lsp-help-buf-name "*lsp-help*"))
+ (with-current-buffer (get-buffer-create lsp-help-buf-name)
+ (with-help-window lsp-help-buf-name
+ (insert (string-trim-right (lsp--render-on-hover-content contents t))))))
+ (lsp--info "No content at point."))))
+
+(defun lsp--point-in-bounds-p (bounds)
+ "Return whether the current point is within BOUNDS."
+ (and (<= (car bounds) (point)) (< (point) (cdr bounds))))
+
+(defun lsp-get-renderer (language)
+ "Get renderer for LANGUAGE."
+ (lambda (str)
+ (lsp--render-string str language)))
+
+(defun lsp--setup-markdown (mode)
+ "Setup the ‘markdown-mode’ in the frame.
+MODE is the mode used in the parent frame."
+ (make-local-variable 'markdown-code-lang-modes)
+ (dolist (mark (alist-get mode lsp-custom-markup-modes))
+ (add-to-list 'markdown-code-lang-modes (cons mark mode)))
+ (setq-local markdown-fontify-code-blocks-natively t)
+ (setq-local markdown-fontify-code-block-default-mode mode)
+ (setq-local markdown-hide-markup t)
+
+ ;; Render some common HTML entities.
+ ;; This should really happen in markdown-mode instead,
+ ;; but it doesn't, so we do it here for now.
+ (setq prettify-symbols-alist
+ (cl-loop for i from 0 to 255
+ collect (cons (format "&#x%02X;" i) i)))
+ (push '("&lt;" . ?<) prettify-symbols-alist)
+ (push '("&gt;" . ?>) prettify-symbols-alist)
+ (push '("&amp;" . ?&) prettify-symbols-alist)
+ (push '("&nbsp;" . ? ) prettify-symbols-alist)
+ (setq prettify-symbols-compose-predicate
+ (lambda (_start _end _match) t))
+ (prettify-symbols-mode 1))
+
+(defun lsp--buffer-string-visible ()
+ "Return visible buffer string.
+Stolen from `org-copy-visible'."
+ (let ((temp (generate-new-buffer " *temp*"))
+ (beg (point-min))
+ (end (point-max)))
+ (while (/= beg end)
+ (when (get-char-property beg 'invisible)
+ (setq beg (next-single-char-property-change beg 'invisible nil end)))
+ (let* ((next (next-single-char-property-change beg 'invisible nil end))
+ (substring (buffer-substring beg next)))
+ (with-current-buffer temp (insert substring))
+ ;; (setq result (concat result substring))
+ (setq beg next)))
+ (setq deactivate-mark t)
+ (prog1 (with-current-buffer temp
+ (s-chop-suffix "\n" (buffer-string)))
+ (kill-buffer temp))))
+
+(defvar lsp-buffer-major-mode nil
+ "Holds the major mode when fontification function is running.
+See #2588")
+
+(defvar view-inhibit-help-message)
+
+(defun lsp--render-markdown ()
+ "Render markdown."
+
+ (let ((markdown-enable-math nil))
+ (goto-char (point-min))
+ (while (re-search-forward
+ (rx (and "\\" (group (or "\\" "`" "*" "_" ":" "/"
+ "{" "}" "[" "]" "(" ")"
+ "#" "+" "-" "." "!" "|"))))
+ nil t)
+ (replace-match (rx (backref 1))))
+
+ ;; markdown-mode v2.3 does not yet provide gfm-view-mode
+ (if (fboundp 'gfm-view-mode)
+ (let ((view-inhibit-help-message t))
+ (gfm-view-mode))
+ (gfm-mode))
+
+ (lsp--setup-markdown lsp-buffer-major-mode)))
+
+(defvar lsp--display-inline-image-alist
+ '((lsp--render-markdown
+ (:regexp
+ "!\\[.*?\\](data:image/[a-zA-Z]+;base64,\\([A-Za-z0-9+/\n]+?=*?\\)\\(|[^)]+\\)?)"
+ :sexp
+ (create-image
+ (base64-decode-string
+ (buffer-substring-no-properties (match-beginning 1) (match-end 1)))
+ nil t))))
+ "Replaced string regexp and function returning image.
+Each element should have the form (MODE . (PROPERTY-LIST...)).
+MODE (car) is function which is defined in `lsp-language-id-configuration'.
+Cdr should be list of PROPERTY-LIST.
+
+Each PROPERTY-LIST should have properties:
+:regexp Regexp which determines what string is relpaced to image.
+ You should also get information of image, by parenthesis constructs.
+ By default, all matched string is replaced to image, but you can
+ change index of replaced string by keyword :replaced-index.
+
+:sexp Return image when evaluated. You can use information of regexp
+ by using (match-beggining N), (match-end N) or (match-substring N).
+
+In addition, each can have property:
+:replaced-index Determine index which is used to replace regexp to image.
+ The value means first argument of `match-beginning' and
+ `match-end'. If omitted, interpreted as index 0.")
+
+(defcustom lsp-display-inline-image t
+ "Showing inline image or not."
+ :group 'lsp-mode
+ :type 'boolean)
+
+(defcustom lsp-enable-suggest-server-download t
+ "When non-nil enable server downloading suggestions."
+ :group 'lsp-mode
+ :type 'boolean
+ :package-version '(lsp-mode . "8.0.1"))
+
+(defun lsp--display-inline-image (mode)
+ "Add image property if available."
+ (let ((plist-list (cdr (assq mode lsp--display-inline-image-alist))))
+ (when (and (display-images-p) lsp-display-inline-image)
+ (cl-loop
+ for plist in plist-list
+ with regexp with replaced-index
+ do
+ (setq regexp (plist-get plist :regexp))
+ (setq replaced-index (or (plist-get plist :replaced-index) 0))
+
+ (font-lock-remove-keywords nil (list regexp replaced-index))
+ (let ((inhibit-read-only t))
+ (save-excursion
+ (goto-char (point-min))
+ (while (re-search-forward regexp nil t)
+ (set-text-properties
+ (match-beginning replaced-index) (match-end replaced-index)
+ nil)
+ (add-text-properties
+ (match-beginning replaced-index) (match-end replaced-index)
+ `(display ,(eval (plist-get plist :sexp)))))))))))
+
+(defun lsp--fontlock-with-mode (str mode)
+ "Fontlock STR with MODE."
+ (let ((lsp-buffer-major-mode major-mode))
+ (condition-case nil
+ (with-temp-buffer
+ (insert str)
+ (delay-mode-hooks (funcall mode))
+ (cl-flet ((window-body-width () lsp-window-body-width))
+ ;; This can go wrong in some cases, and the fontification would
+ ;; not work as expected.
+ ;;
+ ;; See #2984
+ (ignore-errors (font-lock-ensure))
+ (lsp--display-inline-image mode))
+ (lsp--buffer-string-visible))
+ (error str))))
+
+(defun lsp--render-string (str language)
+ "Render STR using `major-mode' corresponding to LANGUAGE.
+When language is nil render as markup if `markdown-mode' is loaded."
+ (setq str (s-replace "\r" "" (or str "")))
+ (if-let ((mode (-some (-lambda ((mode . lang))
+ (when (and (equal lang language) (functionp mode))
+ mode))
+ lsp-language-id-configuration)))
+ (lsp--fontlock-with-mode str mode)
+ str))
+
+(defun lsp--render-element (content)
+ "Render CONTENT element."
+ (let ((inhibit-message t))
+ (or
+ (pcase content
+ ((MarkedString :value :language)
+ (lsp--render-string value language))
+ ((MarkupContent :value :kind)
+ (lsp--render-string value kind))
+ ;; plain string
+ ((pred stringp) (lsp--render-string content "markdown"))
+ ((pred null) "")
+ (_ (error "Failed to handle %s" content)))
+ "")))
+
+(defun lsp--create-unique-string-fn ()
+ (let (elements)
+ (lambda (element)
+ (let ((count (cl-count element elements :test #'string=)))
+ (prog1 (if (zerop count)
+ element
+ (format "%s (%s)" element count))
+ (push element elements))))))
+
+(defun lsp--select-action (actions)
+ "Select an action to execute from ACTIONS."
+ (cond
+ ((seq-empty-p actions) (signal 'lsp-no-code-actions nil))
+ ((and (eq (seq-length actions) 1) lsp-auto-execute-action)
+ (lsp-seq-first actions))
+ (t (let ((completion-ignore-case t))
+ (lsp--completing-read "Select code action: "
+ (seq-into actions 'list)
+ (-compose (lsp--create-unique-string-fn)
+ #'lsp:code-action-title)
+ nil t)))))
+
+(defun lsp--workspace-server-id (workspace)
+ "Return the server ID of WORKSPACE."
+ (-> workspace lsp--workspace-client lsp--client-server-id))
+
+(defun lsp--handle-rendered-for-echo-area (contents)
+ "Return a single line from RENDERED, appropriate for display in the echo area."
+ (pcase (lsp-workspaces)
+ (`(,workspace)
+ (lsp-clients-extract-signature-on-hover contents (lsp--workspace-server-id workspace)))
+ ;; For projects with multiple active workspaces we also default to
+ ;; render the first line.
+ (_ (lsp-clients-extract-signature-on-hover contents nil))))
+
+(cl-defgeneric lsp-clients-extract-signature-on-hover (contents _server-id)
+ "Extract a representative line from CONTENTS, to show in the echo area."
+ (car (s-lines (s-trim (lsp--render-element contents)))))
+
+(defun lsp--render-on-hover-content (contents render-all)
+ "Render the content received from 'document/onHover' request.
+CONTENTS - MarkedString | MarkedString[] | MarkupContent
+RENDER-ALL - nil if only the signature should be rendered."
+ (cond
+ ((lsp-markup-content? contents)
+ ;; MarkupContent.
+ ;; It tends to be long and is not suitable to display fully in the echo area.
+ ;; Just display the first line which is typically the signature.
+ (if render-all
+ (lsp--render-element contents)
+ (lsp--handle-rendered-for-echo-area contents)))
+ ((and (stringp contents) (not (string-match-p "\n" contents)))
+ ;; If the contents is a single string containing a single line,
+ ;; render it always.
+ (lsp--render-element contents))
+ (t
+ ;; MarkedString -> MarkedString[]
+ (when (or (lsp-marked-string? contents) (stringp contents))
+ (setq contents (list contents)))
+ ;; Consider the signature consisting of the elements who have a renderable
+ ;; "language" property. When render-all is nil, ignore other elements.
+ (string-join
+ (seq-map
+ #'lsp--render-element
+ (if render-all
+ contents
+ ;; Only render contents that have an available renderer.
+ (seq-take
+ (seq-filter
+ (-andfn #'lsp-marked-string?
+ (-compose #'lsp-get-renderer #'lsp:marked-string-language))
+ contents)
+ 1)))
+ (if (bound-and-true-p page-break-lines-mode)
+ "\n \n"
+ "\n")))))
+
+
+
+(defvar lsp-signature-mode-map
+ (-doto (make-sparse-keymap)
+ (define-key (kbd "M-n") #'lsp-signature-next)
+ (define-key (kbd "M-p") #'lsp-signature-previous)
+ (define-key (kbd "M-a") #'lsp-signature-toggle-full-docs)
+ (define-key (kbd "C-c C-k") #'lsp-signature-stop)
+ (define-key (kbd "C-g") #'lsp-signature-stop))
+ "Keymap for `lsp-signature-mode-map'.")
+
+(define-minor-mode lsp-signature-mode
+ "Mode used to show signature popup."
+ :keymap lsp-signature-mode-map
+ :lighter ""
+ :group 'lsp-mode)
+
+(defun lsp-signature-stop ()
+ "Stop showing current signature help."
+ (interactive)
+ (lsp-cancel-request-by-token :signature)
+ (remove-hook 'post-command-hook #'lsp-signature)
+ (funcall lsp-signature-function nil)
+ (lsp-signature-mode -1))
+
+(declare-function page-break-lines--update-display-tables "ext:page-break-lines")
+
+(defun lsp--setup-page-break-mode-if-present ()
+ "Enable `page-break-lines-mode' in current buffer."
+ (when (fboundp 'page-break-lines-mode)
+ (page-break-lines-mode)
+ ;; force page-break-lines-mode to update the display tables.
+ (page-break-lines--update-display-tables)))
+
+(defun lsp-lv-message (message)
+ (add-hook 'lv-window-hook #'lsp--setup-page-break-mode-if-present)
+ (if message
+ (progn
+ (setq lsp--signature-last-buffer (current-buffer))
+ (let ((lv-force-update t))
+ (lv-message "%s" message)))
+ (lv-delete-window)
+ (remove-hook 'lv-window-hook #'lsp--setup-page-break-mode-if-present)))
+
+(declare-function posframe-show "ext:posframe")
+(declare-function posframe-hide "ext:posframe")
+(declare-function posframe-poshandler-point-bottom-left-corner-upward "ext:posframe")
+
+(defface lsp-signature-posframe
+ '((t :inherit tooltip))
+ "Background and foreground for `lsp-signature-posframe'."
+ :group 'lsp-mode)
+
+(defvar lsp-signature-posframe-params
+ (list :poshandler #'posframe-poshandler-point-bottom-left-corner-upward
+ :height 10
+ :width 60
+ :border-width 1
+ :min-width 60)
+ "Params for signature and `posframe-show'.")
+
+(defun lsp-signature-posframe (str)
+ "Use posframe to show the STR signatureHelp string."
+ (if str
+ (apply #'posframe-show
+ (with-current-buffer (get-buffer-create " *lsp-signature*")
+ (erase-buffer)
+ (insert str)
+ (visual-line-mode 1)
+ (lsp--setup-page-break-mode-if-present)
+ (current-buffer))
+ (append
+ lsp-signature-posframe-params
+ (list :position (point)
+ :background-color (face-attribute 'lsp-signature-posframe :background nil t)
+ :foreground-color (face-attribute 'lsp-signature-posframe :foreground nil t)
+ :border-color (face-attribute 'font-lock-comment-face :foreground nil t))))
+ (posframe-hide " *lsp-signature*")))
+
+(defun lsp--handle-signature-update (signature)
+ (let ((message
+ (if (lsp-signature-help? signature)
+ (lsp--signature->message signature)
+ (mapconcat #'lsp--signature->message signature "\n"))))
+ (if (s-present? message)
+ (funcall lsp-signature-function message)
+ (lsp-signature-stop))))
+
+(defun lsp-signature-activate ()
+ "Activate signature help.
+It will show up only if current point has signature help."
+ (interactive)
+ (setq lsp--signature-last nil
+ lsp--signature-last-index nil
+ lsp--signature-last-buffer (current-buffer))
+ (add-hook 'post-command-hook #'lsp-signature)
+ (lsp-signature-mode t))
+
+(defcustom lsp-signature-cycle t
+ "Whether `lsp-signature-next' and prev should cycle."
+ :type 'boolean
+ :group 'lsp-mode)
+
+(defun lsp-signature-next ()
+ "Show next signature."
+ (interactive)
+ (let ((nsigs (length (lsp:signature-help-signatures lsp--signature-last))))
+ (when (and lsp--signature-last-index
+ lsp--signature-last
+ (or lsp-signature-cycle (< (1+ lsp--signature-last-index) nsigs)))
+ (setq lsp--signature-last-index (% (1+ lsp--signature-last-index) nsigs))
+ (funcall lsp-signature-function (lsp--signature->message lsp--signature-last)))))
+
+(defun lsp-signature-previous ()
+ "Next signature."
+ (interactive)
+ (when (and lsp--signature-last-index
+ lsp--signature-last
+ (or lsp-signature-cycle (not (zerop lsp--signature-last-index))))
+ (setq lsp--signature-last-index (1- (if (zerop lsp--signature-last-index)
+ (length (lsp:signature-help-signatures lsp--signature-last))
+ lsp--signature-last-index)))
+ (funcall lsp-signature-function (lsp--signature->message lsp--signature-last))))
+
+(defun lsp-signature-toggle-full-docs ()
+ "Toggle full/partial signature documentation."
+ (interactive)
+ (let ((all? (not (numberp lsp-signature-doc-lines))))
+ (setq lsp-signature-doc-lines (if all?
+ (or (car-safe lsp-signature-doc-lines)
+ 20)
+ (list lsp-signature-doc-lines))))
+ (lsp-signature-activate))
+
+(defun lsp--signature->message (signature-help)
+ "Generate eldoc message from SIGNATURE-HELP response."
+ (setq lsp--signature-last signature-help)
+
+ (when (and signature-help (not (seq-empty-p (lsp:signature-help-signatures signature-help))))
+ (-let* (((&SignatureHelp :active-signature?
+ :active-parameter?
+ :signatures) signature-help)
+ (active-signature? (or lsp--signature-last-index active-signature? 0))
+ (_ (setq lsp--signature-last-index active-signature?))
+ ((signature &as &SignatureInformation? :label :parameters?) (seq-elt signatures active-signature?))
+ (prefix (if (= (length signatures) 1)
+ ""
+ (concat (propertize (format " %s/%s"
+ (1+ active-signature?)
+ (length signatures))
+ 'face 'success)
+ " ")))
+ (method-docs (when
+ (and lsp-signature-render-documentation
+ (or (not (numberp lsp-signature-doc-lines)) (< 0 lsp-signature-doc-lines)))
+ (let ((docs (lsp--render-element
+ (lsp:parameter-information-documentation? signature))))
+ (when (s-present? docs)
+ (concat
+ "\n"
+ (if (fboundp 'page-break-lines-mode)
+ " \n"
+ "")
+ (if (and (numberp lsp-signature-doc-lines)
+ (> (length (s-lines docs)) lsp-signature-doc-lines))
+ (concat (s-join "\n" (-take lsp-signature-doc-lines (s-lines docs)))
+ (propertize "\nTruncated..." 'face 'highlight))
+ docs)))))))
+ (when (and active-parameter? (not (seq-empty-p parameters?)))
+ (-when-let* ((param (when (and (< -1 active-parameter? (length parameters?)))
+ (seq-elt parameters? active-parameter?)))
+ (selected-param-label (let ((label (lsp:parameter-information-label param)))
+ (if (stringp label) label (append label nil))))
+ (start (if (stringp selected-param-label)
+ (s-index-of selected-param-label label)
+ (cl-first selected-param-label)))
+ (end (if (stringp selected-param-label)
+ (+ start (length selected-param-label))
+ (cl-second selected-param-label))))
+ (add-face-text-property start end 'eldoc-highlight-function-argument nil label)))
+ (concat prefix label method-docs))))
+
+(defun lsp-signature ()
+ "Display signature info (based on `textDocument/signatureHelp')"
+ (if (and lsp--signature-last-buffer
+ (not (equal (current-buffer) lsp--signature-last-buffer)))
+ (lsp-signature-stop)
+ (lsp-request-async "textDocument/signatureHelp"
+ (lsp--text-document-position-params)
+ #'lsp--handle-signature-update
+ :cancel-token :signature)))
+
+
+(defcustom lsp-overlay-document-color-char "■"
+ "Display the char represent the document color in overlay"
+ :type 'string
+ :group 'lsp-mode)
+
+;; color presentation
+(defun lsp--color-create-interactive-command (color range)
+ (lambda ()
+ (interactive)
+ (-let [(&ColorPresentation? :text-edit?
+ :additional-text-edits?)
+ (lsp--completing-read
+ "Select color presentation: "
+ (lsp-request
+ "textDocument/colorPresentation"
+ `( :textDocument ,(lsp--text-document-identifier)
+ :color ,color
+ :range ,range))
+ #'lsp:color-presentation-label
+ nil
+ t)]
+ (when text-edit?
+ (lsp--apply-text-edit text-edit?))
+ (when additional-text-edits?
+ (lsp--apply-text-edits additional-text-edits? 'color-presentation)))))
+
+(defun lsp--number->color (number)
+ (let ((result (format "%x"
+ (round (* (or number 0) 255.0)))))
+ (if (= 1 (length result))
+ (concat "0" result)
+ result)))
+
+(defun lsp--document-color ()
+ "Document color handler."
+ (when (lsp-feature? "textDocument/documentColor")
+ (lsp-request-async
+ "textDocument/documentColor"
+ `(:textDocument ,(lsp--text-document-identifier))
+ (lambda (result)
+ (lsp--remove-overlays 'lsp-color)
+ (seq-do
+ (-lambda ((&ColorInformation :color (color &as &Color :red :green :blue)
+ :range))
+ (-let* (((beg . end) (lsp--range-to-region range))
+ (overlay (make-overlay beg end))
+ (command (lsp--color-create-interactive-command color range)))
+ (overlay-put overlay 'lsp-color t)
+ (overlay-put overlay 'evaporate t)
+ (overlay-put overlay
+ 'before-string
+ (propertize
+ lsp-overlay-document-color-char
+ 'face `((:foreground ,(format
+ "#%s%s%s"
+ (lsp--number->color red)
+ (lsp--number->color green)
+ (lsp--number->color blue))))
+ 'action command
+ 'mouse-face 'lsp-lens-mouse-face
+ 'local-map (-doto (make-sparse-keymap)
+ (define-key [mouse-1] command))))))
+ result))
+ :mode 'unchanged
+ :cancel-token :document-color-token)))
+
+
+;; hover
+
+(defvar-local lsp--hover-saved-bounds nil)
+
+(defun lsp-hover ()
+ "Display hover info (based on `textDocument/signatureHelp')."
+ (if (and lsp--hover-saved-bounds
+ (lsp--point-in-bounds-p lsp--hover-saved-bounds))
+ (lsp--eldoc-message lsp--eldoc-saved-message)
+ (setq lsp--hover-saved-bounds nil
+ lsp--eldoc-saved-message nil)
+ (if (looking-at "[[:space:]\n]")
+ (lsp--eldoc-message nil)
+ (when (and lsp-eldoc-enable-hover (lsp--capability :hoverProvider))
+ (lsp-request-async
+ "textDocument/hover"
+ (lsp--text-document-position-params)
+ (-lambda ((hover &as &Hover? :range? :contents))
+ (when hover
+ (when range?
+ (setq lsp--hover-saved-bounds (lsp--range-to-region range?)))
+ (lsp--eldoc-message (and contents
+ (lsp--render-on-hover-content
+ contents
+ lsp-eldoc-render-all)))))
+ :error-handler #'ignore
+ :mode 'tick
+ :cancel-token :eldoc-hover)))))
+
+
+
+(defun lsp--action-trigger-parameter-hints (_command)
+ "Handler for editor.action.triggerParameterHints."
+ (when (member :on-server-request lsp-signature-auto-activate)
+ (lsp-signature-activate)))
+
+(defun lsp--action-trigger-suggest (_command)
+ "Handler for editor.action.triggerSuggest."
+ (cond
+ ((and (bound-and-true-p company-mode)
+ (fboundp 'company-auto-begin)
+ (fboundp 'company-post-command))
+ (run-at-time 0 nil
+ (lambda ()
+ (let ((this-command 'company-idle-begin)
+ (company-minimum-prefix-length 0))
+ (company-auto-begin)
+ (company-post-command)))))
+ (t
+ (completion-at-point))))
+
+(defconst lsp--default-action-handlers
+ (ht ("editor.action.triggerParameterHints" #'lsp--action-trigger-parameter-hints)
+ ("editor.action.triggerSuggest" #'lsp--action-trigger-suggest))
+ "Default action handlers.")
+
+(defun lsp--find-action-handler (command)
+ "Find action handler for particular COMMAND."
+ (or
+ (--some (-some->> it
+ (lsp--workspace-client)
+ (lsp--client-action-handlers)
+ (gethash command))
+ (lsp-workspaces))
+ (gethash command lsp--default-action-handlers)))
+
+(defun lsp--text-document-code-action-params (&optional kind)
+ "Code action params."
+ (list :textDocument (lsp--text-document-identifier)
+ :range (if (use-region-p)
+ (lsp--region-to-range (region-beginning) (region-end))
+ (lsp--region-to-range (point) (point)))
+ :context `( :diagnostics ,(lsp-cur-line-diagnostics)
+ ,@(when kind (list :only (vector kind))))))
+
+(defun lsp-code-actions-at-point (&optional kind)
+ "Retrieve the code actions for the active region or the current line.
+It will filter by KIND if non nil."
+ (lsp-request "textDocument/codeAction" (lsp--text-document-code-action-params kind)))
+
+(defun lsp-execute-code-action-by-kind (command-kind)
+ "Execute code action by COMMAND-KIND."
+ (if-let ((action (->> (lsp-get-or-calculate-code-actions command-kind)
+ (-filter (-lambda ((&CodeAction :kind?))
+ (and kind? (s-prefix? command-kind kind?))))
+ lsp--select-action)))
+ (lsp-execute-code-action action)
+ (signal 'lsp-no-code-actions '(command-kind))))
+
+(defalias 'lsp-get-or-calculate-code-actions 'lsp-code-actions-at-point)
+
+(lsp-defun lsp--execute-command ((action &as &Command :command :arguments?))
+ "Parse and execute a code ACTION represented as a Command LSP type."
+ (let ((server-id (->> (lsp-workspaces)
+ (cl-first)
+ (or lsp--cur-workspace)
+ (lsp--workspace-client)
+ (lsp--client-server-id))))
+ (condition-case nil
+ (with-no-warnings
+ (lsp-execute-command server-id (intern command) arguments?))
+ (cl-no-applicable-method
+ (if-let ((action-handler (lsp--find-action-handler command)))
+ (funcall action-handler action)
+ (lsp-send-execute-command command arguments?))))))
+
+(lsp-defun lsp-execute-code-action ((action &as &CodeAction :command? :edit?))
+ "Execute code action ACTION.
+If ACTION is not set it will be selected from `lsp-code-actions-at-point'.
+Request codeAction/resolve for more info if server supports."
+ (interactive (list (lsp--select-action (lsp-code-actions-at-point))))
+ (if (and (lsp-feature? "codeAction/resolve")
+ (not command?)
+ (not edit?))
+ (lsp--execute-code-action (lsp-request "codeAction/resolve" action))
+ (lsp--execute-code-action action)))
+
+(lsp-defun lsp--execute-code-action ((action &as &CodeAction :command? :edit?))
+ "Execute code action ACTION."
+ (when edit?
+ (lsp--apply-workspace-edit edit? 'code-action))
+
+ (cond
+ ((stringp command?) (lsp--execute-command action))
+ ((lsp-command? command?) (lsp--execute-command command?))))
+
+(defvar lsp--formatting-indent-alist
+ ;; Taken from `dtrt-indent-mode'
+ '((c-mode . c-basic-offset) ; C
+ (c++-mode . c-basic-offset) ; C++
+ (csharp-mode . c-basic-offset) ; C#
+ (csharp-tree-sitter-mode . csharp-tree-sitter-indent-offset) ; C#
+ (d-mode . c-basic-offset) ; D
+ (java-mode . c-basic-offset) ; Java
+ (jde-mode . c-basic-offset) ; Java (JDE)
+ (js-mode . js-indent-level) ; JavaScript
+ (js2-mode . js2-basic-offset) ; JavaScript-IDE
+ (js3-mode . js3-indent-level) ; JavaScript-IDE
+ (json-mode . js-indent-level) ; JSON
+ (lua-mode . lua-indent-level) ; Lua
+ (objc-mode . c-basic-offset) ; Objective C
+ (php-mode . c-basic-offset) ; PHP
+ (perl-mode . perl-indent-level) ; Perl
+ (cperl-mode . cperl-indent-level) ; Perl
+ (raku-mode . raku-indent-offset) ; Perl6/Raku
+ (erlang-mode . erlang-indent-level) ; Erlang
+ (ada-mode . ada-indent) ; Ada
+ (sgml-mode . sgml-basic-offset) ; SGML
+ (nxml-mode . nxml-child-indent) ; XML
+ (pascal-mode . pascal-indent-level) ; Pascal
+ (typescript-mode . typescript-indent-level) ; Typescript
+ (sh-mode . sh-basic-offset) ; Shell Script
+ (ruby-mode . ruby-indent-level) ; Ruby
+ (enh-ruby-mode . enh-ruby-indent-level) ; Ruby
+ (crystal-mode . crystal-indent-level) ; Crystal (Ruby)
+ (css-mode . css-indent-offset) ; CSS
+ (rust-mode . rust-indent-offset) ; Rust
+ (rustic-mode . rustic-indent-offset) ; Rust
+ (scala-mode . scala-indent:step) ; Scala
+ (powershell-mode . powershell-indent) ; PowerShell
+ (ess-mode . ess-indent-offset) ; ESS (R)
+ (yaml-mode . yaml-indent-offset) ; YAML
+ (hack-mode . hack-indent-offset) ; Hack
+
+ (default . standard-indent)) ; default fallback
+ "A mapping from `major-mode' to its indent variable.")
+
+(defun lsp--get-indent-width (mode)
+ "Get indentation offset for MODE."
+ (or (alist-get mode lsp--formatting-indent-alist)
+ (lsp--get-indent-width (or (get mode 'derived-mode-parent) 'default))))
+
+(defun lsp--make-document-formatting-params ()
+ "Create document formatting params."
+ (lsp-make-document-formatting-params
+ :text-document (lsp--text-document-identifier)
+ :options (lsp-make-formatting-options
+ :tab-size (symbol-value (lsp--get-indent-width major-mode))
+ :insert-spaces (if indent-tabs-mode :json-false t))))
+
+(defun lsp-format-buffer ()
+ "Ask the server to format this document."
+ (interactive "*")
+ (cond ((lsp-feature? "textDocument/formatting")
+ (let ((edits (lsp-request "textDocument/formatting"
+ (lsp--make-document-formatting-params))))
+ (if (seq-empty-p edits)
+ (lsp--info "No formatting changes provided")
+ (lsp--apply-text-edits edits 'format))))
+ ((lsp-feature? "textDocument/rangeFormatting")
+ (save-restriction
+ (widen)
+ (lsp-format-region (point-min) (point-max))))
+ (t (signal 'lsp-capability-not-supported (list "documentFormattingProvider")))))
+
+(defun lsp-format-region (s e)
+ "Ask the server to format the region, or if none is selected, the current line."
+ (interactive "r")
+ (let ((edits (lsp-request
+ "textDocument/rangeFormatting"
+ (lsp--make-document-range-formatting-params s e))))
+ (if (seq-empty-p edits)
+ (lsp--info "No formatting changes provided")
+ (lsp--apply-text-edits edits 'format))))
+
+(defmacro lsp-make-interactive-code-action (func-name code-action-kind)
+ "Define an interactive function FUNC-NAME that attempts to
+execute a CODE-ACTION-KIND action."
+ `(defun ,(intern (concat "lsp-" (symbol-name func-name))) ()
+ ,(format "Perform the %s code action, if available." code-action-kind)
+ (interactive)
+ (condition-case nil
+ (lsp-execute-code-action-by-kind ,code-action-kind)
+ (lsp-no-code-actions
+ (when (called-interactively-p 'any)
+ (lsp--info ,(format "%s action not available" code-action-kind)))))))
+
+(lsp-make-interactive-code-action organize-imports "source.organizeImports")
+
+(defun lsp--make-document-range-formatting-params (start end)
+ "Make DocumentRangeFormattingParams for selected region."
+ (lsp:set-document-range-formatting-params-range (lsp--make-document-formatting-params)
+ (lsp--region-to-range start end)))
+
+(defconst lsp--highlight-kind-face
+ '((1 . lsp-face-highlight-textual)
+ (2 . lsp-face-highlight-read)
+ (3 . lsp-face-highlight-write)))
+
+(defun lsp--remove-overlays (name)
+ (save-restriction
+ (widen)
+ (remove-overlays (point-min) (point-max) name t)))
+
+(defun lsp-document-highlight ()
+ "Highlight all relevant references to the symbol under point."
+ (interactive)
+ (lsp--remove-overlays 'lsp-highlight) ;; clear any previous highlights
+ (setq lsp--have-document-highlights nil
+ lsp--symbol-bounds-of-last-highlight-invocation nil)
+ (let ((lsp-enable-symbol-highlighting t))
+ (lsp--document-highlight)))
+
+(defun lsp--document-highlight-callback (highlights)
+ "Create a callback to process the reply of a
+'textDocument/documentHighlight' message for the buffer BUF.
+A reference is highlighted only if it is visible in a window."
+ (lsp--remove-overlays 'lsp-highlight)
+
+ (let* ((wins-visible-pos (-map (lambda (win)
+ (cons (1- (line-number-at-pos (window-start win) t))
+ (1+ (line-number-at-pos (window-end win) t))))
+ (get-buffer-window-list nil nil 'visible))))
+ (setq lsp--have-document-highlights t)
+ (-map
+ (-lambda ((&DocumentHighlight :range (&Range :start (start &as &Position :line start-line)
+ :end (end &as &Position :line end-line))
+ :kind?))
+ (-map
+ (-lambda ((start-window . end-window))
+ ;; Make the overlay only if the reference is visible
+ (let ((start-point (lsp--position-to-point start))
+ (end-point (lsp--position-to-point end)))
+ (when (and (> (1+ start-line) start-window)
+ (< (1+ end-line) end-window)
+ (not (and lsp-symbol-highlighting-skip-current
+ (<= start-point (point) end-point))))
+ (-doto (make-overlay start-point end-point)
+ (overlay-put 'face (cdr (assq (or kind? 1) lsp--highlight-kind-face)))
+ (overlay-put 'lsp-highlight t)))))
+ wins-visible-pos))
+ highlights)))
+
+(defcustom lsp-symbol-kinds
+ '((1 . "File")
+ (2 . "Module")
+ (3 . "Namespace")
+ (4 . "Package")
+ (5 . "Class")
+ (6 . "Method")
+ (7 . "Property")
+ (8 . "Field")
+ (9 . "Constructor")
+ (10 . "Enum")
+ (11 . "Interface")
+ (12 . "Function")
+ (13 . "Variable")
+ (14 . "Constant")
+ (15 . "String")
+ (16 . "Number")
+ (17 . "Boolean")
+ (18 . "Array")
+ (19 . "Object")
+ (20 . "Key")
+ (21 . "Null")
+ (22 . "Enum Member")
+ (23 . "Struct")
+ (24 . "Event")
+ (25 . "Operator")
+ (26 . "Type Parameter"))
+ "Alist mapping SymbolKinds to human-readable strings.
+Various Symbol objects in the LSP protocol have an integral type,
+specifying what they are. This alist maps such type integrals to
+readable representations of them. See
+`https://microsoft.github.io/language-server-protocol/specifications/specification-current/',
+namespace SymbolKind."
+ :group 'lsp-mode
+ :type '(alist :key-type integer :value-type string))
+(defalias 'lsp--symbol-kind 'lsp-symbol-kinds)
+
+(lsp-defun lsp--symbol-information-to-xref
+ ((&SymbolInformation :kind :name
+ :location (&Location :uri :range (&Range :start
+ (&Position :line :character)))))
+ "Return a `xref-item' from SYMBOL information."
+ (xref-make (format "[%s] %s" (alist-get kind lsp-symbol-kinds) name)
+ (xref-make-file-location (lsp--uri-to-path uri)
+ line
+ character)))
+
+(defun lsp--get-document-symbols ()
+ "Get document symbols.
+
+If the buffer has not been modified since symbols were last
+retrieved, simply return the latest result.
+
+Else, if the request was initiated by Imenu updating its menu-bar
+entry, perform it asynchronously; i.e., give Imenu the latest
+result and then force a refresh when a new one is available.
+
+Else (e.g., due to interactive use of `imenu' or `xref'),
+perform the request synchronously."
+ (if (= (buffer-chars-modified-tick) lsp--document-symbols-tick)
+ lsp--document-symbols
+ (let ((method "textDocument/documentSymbol")
+ (params `(:textDocument ,(lsp--text-document-identifier)))
+ (tick (buffer-chars-modified-tick)))
+ (if (not lsp--document-symbols-request-async)
+ (prog1
+ (setq lsp--document-symbols (lsp-request method params))
+ (setq lsp--document-symbols-tick tick))
+ (lsp-request-async method params
+ (lambda (document-symbols)
+ (setq lsp--document-symbols document-symbols
+ lsp--document-symbols-tick tick)
+ (lsp--imenu-refresh))
+ :mode 'alive)
+ lsp--document-symbols))))
+
+(advice-add 'imenu-update-menubar :around
+ (lambda (oldfun &rest r)
+ (let ((lsp--document-symbols-request-async t))
+ (apply oldfun r))))
+
+(defun lsp--document-symbols->document-symbols-hierarchy (document-symbols current-position)
+ "Convert DOCUMENT-SYMBOLS to symbols hierarchy on CURRENT-POSITION."
+ (-let (((symbol &as &DocumentSymbol? :children?)
+ (seq-find (-lambda ((&DocumentSymbol :range))
+ (lsp-point-in-range? current-position range))
+ document-symbols)))
+ (if children?
+ (cons symbol (lsp--document-symbols->document-symbols-hierarchy children? current-position))
+ (when symbol
+ (list symbol)))))
+
+(lsp-defun lsp--symbol-information->document-symbol ((&SymbolInformation :name :kind :location :container-name? :deprecated?))
+ "Convert a SymbolInformation to a DocumentInformation"
+ (lsp-make-document-symbol :name name
+ :kind kind
+ :range (lsp:location-range location)
+ :children? nil
+ :deprecated? deprecated?
+ :selection-range (lsp:location-range location)
+ :detail? container-name?))
+
+(defun lsp--symbols-informations->document-symbols-hierarchy (symbols-informations current-position)
+ "Convert SYMBOLS-INFORMATIONS to symbols hierarchy on CURRENT-POSITION."
+ (--> symbols-informations
+ (-keep (-lambda ((symbol &as &SymbolInformation :location (&Location :range)))
+ (when (lsp-point-in-range? current-position range)
+ (lsp--symbol-information->document-symbol symbol)))
+ it)
+ (sort it (-lambda ((&DocumentSymbol :range (&Range :start a-start-position :end a-end-position))
+ (&DocumentSymbol :range (&Range :start b-start-position :end b-end-position)))
+ (and (lsp--position-compare b-start-position a-start-position)
+ (lsp--position-compare a-end-position b-end-position))))))
+
+(defun lsp--symbols->document-symbols-hierarchy (symbols)
+ "Convert SYMBOLS to symbols-hierarchy."
+ (when-let ((first-symbol (lsp-seq-first symbols)))
+ (let ((cur-position (lsp-make-position :line (plist-get (lsp--cur-position) :line)
+ :character (plist-get (lsp--cur-position) :character))))
+ (if (lsp-symbol-information? first-symbol)
+ (lsp--symbols-informations->document-symbols-hierarchy symbols cur-position)
+ (lsp--document-symbols->document-symbols-hierarchy symbols cur-position)))))
+
+(defun lsp--xref-backend () 'xref-lsp)
+
+(cl-defmethod xref-backend-identifier-at-point ((_backend (eql xref-lsp)))
+ (propertize (or (thing-at-point 'symbol) "")
+ 'identifier-at-point t))
+
+(defun lsp--xref-elements-index (symbols path)
+ (-mapcat
+ (-lambda (sym)
+ (pcase-exhaustive sym
+ ((DocumentSymbol :name :children? :selection-range (Range :start))
+ (cons (cons (concat path name)
+ (lsp--position-to-point start))
+ (lsp--xref-elements-index children? (concat path name " / "))))
+ ((SymbolInformation :name :location (Location :range (Range :start)))
+ (list (cons (concat path name)
+ (lsp--position-to-point start))))))
+ symbols))
+
+(defvar-local lsp--symbols-cache nil)
+
+(cl-defmethod xref-backend-identifier-completion-table ((_backend (eql xref-lsp)))
+ (if (lsp--find-workspaces-for "textDocument/documentSymbol")
+ (progn
+ (setq lsp--symbols-cache (lsp--xref-elements-index
+ (lsp--get-document-symbols) nil))
+ lsp--symbols-cache)
+ (list (propertize (or (thing-at-point 'symbol) "")
+ 'identifier-at-point t))))
+
+(cl-defmethod xref-backend-definitions ((_backend (eql xref-lsp)) identifier)
+ (save-excursion
+ (unless (get-text-property 0 'identifier-at-point identifier)
+ (goto-char (cl-rest (or (assoc identifier lsp--symbols-cache)
+ (user-error "Unable to find symbol %s in current document" identifier)))))
+ (lsp--locations-to-xref-items (lsp-request "textDocument/definition"
+ (lsp--text-document-position-params)))))
+
+(cl-defmethod xref-backend-references ((_backend (eql xref-lsp)) identifier)
+ (save-excursion
+ (unless (get-text-property 0 'identifier-at-point identifier)
+ (goto-char (cl-rest (or (assoc identifier lsp--symbols-cache)
+ (user-error "Unable to find symbol %s" identifier)))))
+ (lsp--locations-to-xref-items (lsp-request "textDocument/references"
+ (lsp--make-reference-params)))))
+
+(cl-defmethod xref-backend-apropos ((_backend (eql xref-lsp)) pattern)
+ (seq-map #'lsp--symbol-information-to-xref
+ (lsp-request "workspace/symbol" `(:query ,pattern))))
+
+(defcustom lsp-rename-use-prepare t
+ "Whether `lsp-rename' should do a prepareRename first.
+For some language servers, textDocument/prepareRename might be
+too slow, in which case this variable may be set to nil.
+`lsp-rename' will then use `thing-at-point' `symbol' to determine
+the symbol to rename at point."
+ :group 'lsp-mode
+ :type 'boolean)
+
+(defun lsp--get-symbol-to-rename ()
+ "Get a symbol to rename and placeholder at point.
+Returns a cons ((START . END) . PLACEHOLDER?), and nil if
+renaming is generally supported but cannot be done at point.
+START and END are the bounds of the identifiers being renamed,
+while PLACEHOLDER?, is either nil or a string suggested by the
+language server as the initial input of a new-name prompt."
+ (unless (lsp-feature? "textDocument/rename")
+ (error "The connected server(s) doesn't support renaming"))
+ (if (and lsp-rename-use-prepare (lsp-feature? "textDocument/prepareRename"))
+ (when-let ((response
+ (lsp-request "textDocument/prepareRename"
+ (lsp--text-document-position-params))))
+ (let* ((bounds (lsp--range-to-region
+ (if (lsp-range? response)
+ response
+ (lsp:prepare-rename-result-range response))))
+ (placeholder
+ (and (not (lsp-range? response))
+ (lsp:prepare-rename-result-placeholder response))))
+ (cons bounds placeholder)))
+ (when-let ((bounds (bounds-of-thing-at-point 'symbol)))
+ (cons bounds nil))))
+
+(defface lsp-face-rename '((t :underline t))
+ "Face used to highlight the identifier being renamed.
+Renaming can be done using `lsp-rename'."
+ :group 'lsp-mode)
+
+(defface lsp-rename-placeholder-face '((t :inherit font-lock-variable-name-face))
+ "Face used to display the rename placeholder in.
+When calling `lsp-rename' interactively, this will be the face of
+the new name."
+ :group 'lsp-mode)
+
+(defvar lsp-rename-history '()
+ "History for `lsp--read-rename'.")
+
+(defun lsp--read-rename (at-point)
+ "Read a new name for a `lsp-rename' at `point' from the user.
+AT-POINT shall be a structure as returned by
+`lsp--get-symbol-to-rename'.
+
+Returns a string, which should be the new name for the identifier
+at point. If renaming cannot be done at point (as determined from
+AT-POINT), throw a `user-error'.
+
+This function is for use in `lsp-rename' only, and shall not be
+relied upon."
+ (unless at-point
+ (user-error "`lsp-rename' is invalid here"))
+ (-let* ((((start . end) . placeholder?) at-point)
+ ;; Do the `buffer-substring' first to not include `lsp-face-rename'
+ (rename-me (buffer-substring start end))
+ (placeholder (or placeholder? rename-me))
+ (placeholder (propertize placeholder 'face 'lsp-rename-placeholder-face))
+
+ overlay)
+ ;; We need unwind protect, as the user might cancel here, causing the
+ ;; overlay to linger.
+ (unwind-protect
+ (progn
+ (setq overlay (make-overlay start end))
+ (overlay-put overlay 'face 'lsp-face-rename)
+
+ (read-string (format "Rename %s to: " rename-me) placeholder
+ 'lsp-rename-history))
+ (and overlay (delete-overlay overlay)))))
+
+(defun lsp-rename (newname)
+ "Rename the symbol (and all references to it) under point to NEWNAME."
+ (interactive (list (lsp--read-rename (lsp--get-symbol-to-rename))))
+ (when-let ((edits (lsp-request "textDocument/rename"
+ `( :textDocument ,(lsp--text-document-identifier)
+ :position ,(lsp--cur-position)
+ :newName ,newname))))
+ (lsp--apply-workspace-edit edits 'rename)))
+
+(defun lsp--on-rename-file (old-func old-name new-name &optional ok-if-already-exists?)
+ "Advice around function `rename-file'.
+Applies OLD-FUNC with OLD-NAME, NEW-NAME and OK-IF-ALREADY-EXISTS?.
+
+This advice sends workspace/willRenameFiles before renaming file
+to check if server wants to apply any workspaceEdits after renamed."
+ (if (and lsp-apply-edits-after-file-operations
+ (lsp--send-will-rename-files-p old-name))
+ (let ((params (lsp-make-rename-files-params
+ :files (vector (lsp-make-file-rename
+ :oldUri (lsp--path-to-uri old-name)
+ :newUri (lsp--path-to-uri new-name))))))
+ (when-let ((edits (lsp-request "workspace/willRenameFiles" params)))
+ (lsp--apply-workspace-edit edits 'rename-file)
+ (funcall old-func old-name new-name ok-if-already-exists?)
+ (when (lsp--send-did-rename-files-p)
+ (lsp-notify "workspace/didRenameFiles" params))))
+ (funcall old-func old-name new-name ok-if-already-exists?)))
+
+(advice-add 'rename-file :around #'lsp--on-rename-file)
+
+(defun lsp-show-xrefs (xrefs display-action references?)
+ (unless (region-active-p) (push-mark nil t))
+ (if (boundp 'xref-show-definitions-function)
+ (with-no-warnings
+ (xref-push-marker-stack)
+ (funcall (if references? xref-show-xrefs-function xref-show-definitions-function)
+ (-const xrefs)
+ `((window . ,(selected-window))
+ (display-action . ,display-action))))
+ (xref--show-xrefs xrefs display-action)))
+
+(cl-defmethod seq-empty-p ((ht hash-table))
+ "Function `seq-empty-p' for hash-table."
+ (hash-table-empty-p ht))
+
+(cl-defun lsp-find-locations (method &optional extra &key display-action references?)
+ "Send request named METHOD and get cross references of the symbol under point.
+EXTRA is a plist of extra parameters.
+REFERENCES? t when METHOD returns references."
+ (let ((loc (lsp-request method
+ (append (lsp--text-document-position-params) extra))))
+ (if (seq-empty-p loc)
+ (lsp--error "Not found for: %s" (or (thing-at-point 'symbol t) ""))
+ (lsp-show-xrefs (lsp--locations-to-xref-items loc) display-action references?))))
+
+(cl-defun lsp-find-declaration (&key display-action)
+ "Find declarations of the symbol under point."
+ (interactive)
+ (lsp-find-locations "textDocument/declaration" nil :display-action display-action))
+
+(cl-defun lsp-find-definition (&key display-action)
+ "Find definitions of the symbol under point."
+ (interactive)
+ (lsp-find-locations "textDocument/definition" nil :display-action display-action))
+
+(defun lsp-find-definition-mouse (click)
+ "Click to start `lsp-find-definition' at clicked point."
+ (interactive "e")
+ (let* ((ec (event-start click))
+ (p1 (posn-point ec))
+ (w1 (posn-window ec)))
+ (select-window w1)
+ (goto-char p1)
+ (lsp-find-definition)))
+
+(cl-defun lsp-find-implementation (&key display-action)
+ "Find implementations of the symbol under point."
+ (interactive)
+ (lsp-find-locations "textDocument/implementation"
+ nil
+ :display-action display-action
+ :references? t))
+
+(cl-defun lsp-find-references (&optional include-declaration &key display-action)
+ "Find references of the symbol under point."
+ (interactive "P")
+ (lsp-find-locations "textDocument/references"
+ (list :context `(:includeDeclaration ,(lsp-json-bool include-declaration)))
+ :display-action display-action
+ :references? t))
+
+(cl-defun lsp-find-type-definition (&key display-action)
+ "Find type definitions of the symbol under point."
+ (interactive)
+ (lsp-find-locations "textDocument/typeDefinition" nil :display-action display-action))
+
+(defalias 'lsp-find-custom #'lsp-find-locations)
+(defalias 'lsp-goto-implementation #'lsp-find-implementation)
+(defalias 'lsp-goto-type-definition #'lsp-find-type-definition)
+
+(with-eval-after-load 'evil
+ (evil-set-command-property 'lsp-find-definition :jump t)
+ (evil-set-command-property 'lsp-find-implementation :jump t)
+ (evil-set-command-property 'lsp-find-references :jump t)
+ (evil-set-command-property 'lsp-find-type-definition :jump t))
+
+(defun lsp--find-workspaces-for (msg-or-method)
+ "Find all workspaces in the current project that can handle MSG."
+ (let ((method (if (stringp msg-or-method)
+ msg-or-method
+ (plist-get msg-or-method :method))))
+ (-if-let (reqs (cdr (assoc method lsp-method-requirements)))
+ (-let (((&plist :capability :check-command) reqs))
+ (--filter
+ (with-lsp-workspace it
+ (or
+ (when check-command (funcall check-command it))
+ (when capability (lsp--capability capability))
+ (lsp--registered-capability method)
+ (and (not capability) (not check-command))))
+ (lsp-workspaces)))
+ (lsp-workspaces))))
+
+(defun lsp-can-execute-command? (command-name)
+ "Returns non-nil if current language server(s) can execute COMMAND-NAME.
+The command is executed via `workspace/executeCommand'"
+ (cl-position
+ command-name
+ (lsp:execute-command-options-commands
+ (lsp:server-capabilities-execute-command-provider?
+ (lsp--server-capabilities)))
+ :test #'equal))
+
+(defalias 'lsp-feature? 'lsp--find-workspaces-for)
+
+(cl-defmethod lsp-execute-command (_server _command _arguments)
+ "Dispatch COMMAND execution."
+ (signal 'cl-no-applicable-method nil))
+
+(defun lsp-workspace-command-execute (command &optional args)
+ "Execute workspace COMMAND with ARGS."
+ (condition-case-unless-debug err
+ (let ((params (if args
+ (list :command command :arguments args)
+ (list :command command))))
+ (lsp-request "workspace/executeCommand" params))
+ (error
+ (error "`workspace/executeCommand' with `%s' failed.\n\n%S"
+ command err))))
+
+(defun lsp-send-execute-command (command &optional args)
+ "Create and send a 'workspace/executeCommand' message having command COMMAND and optional ARGS."
+ (lsp-workspace-command-execute command args))
+
+(defalias 'lsp-point-to-position #'lsp--point-to-position)
+(defalias 'lsp-text-document-identifier #'lsp--text-document-identifier)
+(defalias 'lsp--send-execute-command #'lsp-send-execute-command)
+(defalias 'lsp-on-open #'lsp--text-document-did-open)
+(defalias 'lsp-on-save #'lsp--text-document-did-save)
+
+(defun lsp--set-configuration (settings)
+ "Set the SETTINGS for the lsp server."
+ (lsp-notify "workspace/didChangeConfiguration" `(:settings ,settings)))
+
+(defun lsp-current-buffer ()
+ (or lsp--virtual-buffer
+ (current-buffer)))
+
+(defun lsp-buffer-live-p (buffer-id)
+ (if-let ((buffer-live (plist-get buffer-id :buffer-live?)))
+ (funcall buffer-live buffer-id)
+ (buffer-live-p buffer-id)))
+
+(defun lsp--on-set-visited-file-name (old-func &rest args)
+ "Advice around function `set-visited-file-name'.
+
+This advice sends textDocument/didClose for the old file and
+textDocument/didOpen for the new file."
+ (when lsp--cur-workspace
+ (lsp--text-document-did-close t))
+ (prog1 (apply old-func args)
+ (when lsp--cur-workspace
+ (lsp--text-document-did-open))))
+
+(advice-add 'set-visited-file-name :around #'lsp--on-set-visited-file-name)
+
+(defvar lsp--flushing-delayed-changes nil)
+
+(defun lsp--send-no-wait (message proc)
+ "Send MESSAGE to PROC without waiting for further output."
+
+ (unless lsp--flushing-delayed-changes
+ (let ((lsp--flushing-delayed-changes t))
+ (lsp--flush-delayed-changes)))
+
+ (condition-case err
+ (process-send-string proc message)
+ ('error (lsp--error "Sending to process failed with the following error: %s"
+ (error-message-string err)))))
+
+(define-error 'lsp-parse-error
+ "Error parsing message from language server" 'lsp-error)
+(define-error 'lsp-unknown-message-type
+ "Unknown message type" '(lsp-error lsp-parse-error))
+(define-error 'lsp-unknown-json-rpc-version
+ "Unknown JSON-RPC protocol version" '(lsp-error lsp-parse-error))
+(define-error 'lsp-no-content-length
+ "Content-Length header missing in message" '(lsp-error lsp-parse-error))
+(define-error 'lsp-invalid-header-name
+ "Invalid header name" '(lsp-error lsp-parse-error))
+
+;; id method
+;; x x request
+;; x . response
+;; . x notification
+(defun lsp--get-message-type (json-data)
+ "Get the message type from JSON-DATA."
+ (if (lsp:json-message-id? json-data)
+ (if (lsp:json-message-error? json-data)
+ 'response-error
+ (if (lsp:json-message-method? json-data)
+ 'request
+ 'response))
+ 'notification))
+
+(defconst lsp--default-notification-handlers
+ (ht ("window/showMessage" #'lsp--window-show-message)
+ ("window/logMessage" #'lsp--window-log-message)
+ ("window/showInputBox" #'lsp--window-show-input-box)
+ ("window/showQuickPick" #'lsp--window-show-quick-pick)
+ ("textDocument/publishDiagnostics" #'lsp--on-diagnostics)
+ ("textDocument/diagnosticsEnd" #'ignore)
+ ("textDocument/diagnosticsBegin" #'ignore)
+ ("telemetry/event" #'ignore)
+ ("$/progress" (lambda (workspace params)
+ (funcall lsp-progress-function workspace params)))))
+
+(lsp-defun lsp--on-notification (workspace (&JSONNotification :params :method))
+ "Call the appropriate handler for NOTIFICATION."
+ (-let ((client (lsp--workspace-client workspace)))
+ (when (lsp--log-io-p method)
+ (lsp--log-entry-new (lsp--make-log-entry method nil params 'incoming-notif)
+ lsp--cur-workspace))
+ (if-let ((handler (or (gethash method (lsp--client-notification-handlers client))
+ (gethash method lsp--default-notification-handlers))))
+ (funcall handler workspace params)
+ (when (and method (not (string-prefix-p "$" method)))
+ (lsp-warn "Unknown notification: %s" method)))))
+
+(lsp-defun lsp--build-workspace-configuration-response ((&ConfigurationParams :items))
+ "Get section configuration.
+PARAMS are the `workspace/configuration' request params"
+ (->> items
+ (-map (-lambda ((&ConfigurationItem :section?))
+ (-let* ((path-parts (split-string section? "\\."))
+ (path-without-last (s-join "." (-slice path-parts 0 -1)))
+ (path-parts-len (length path-parts)))
+ (cond
+ ((<= path-parts-len 1)
+ (ht-get (lsp-configuration-section section?)
+ (car-safe path-parts)
+ (ht-create)))
+ ((> path-parts-len 1)
+ (when-let ((section (lsp-configuration-section path-without-last))
+ (keys path-parts))
+ (while (and keys section)
+ (setf section (ht-get section (pop keys))))
+ section))))))
+ (apply #'vector)))
+
+(defun lsp--send-request-response (workspace recv-time request response)
+ "Send the RESPONSE for REQUEST in WORKSPACE and log if needed."
+ (-let* (((&JSONResponse :params :method :id) request)
+ (process (lsp--workspace-proc workspace))
+ (response (lsp--make-response id response))
+ (req-entry (and lsp-log-io
+ (lsp--make-log-entry method id params 'incoming-req)))
+ (resp-entry (and lsp-log-io
+ (lsp--make-log-entry method id response 'outgoing-resp
+ (/ (nth 2 (time-since recv-time)) 1000)))))
+ ;; Send response to the server.
+ (when (lsp--log-io-p method)
+ (lsp--log-entry-new req-entry workspace)
+ (lsp--log-entry-new resp-entry workspace))
+ (lsp--send-no-wait (lsp--make-message response) process)))
+
+(lsp-defun lsp--on-request (workspace (request &as &JSONRequest :params :method))
+ "Call the appropriate handler for REQUEST, and send the return value to the server.
+WORKSPACE is the active workspace."
+ (-let* ((recv-time (current-time))
+ (client (lsp--workspace-client workspace))
+ (buffers (lsp--workspace-buffers workspace))
+ handler
+ (response (cond
+ ((setq handler (gethash method (lsp--client-request-handlers client) nil))
+ (funcall handler workspace params))
+ ((setq handler (gethash method (lsp--client-async-request-handlers client) nil))
+ (funcall handler workspace params
+ (-partial #'lsp--send-request-response
+ workspace recv-time request))
+ 'delay-response)
+ ((equal method "client/registerCapability")
+ (mapc #'lsp--server-register-capability
+ (lsp:registration-params-registrations params))
+ (mapc (lambda (buf)
+ (when (lsp-buffer-live-p buf)
+ (lsp-with-current-buffer buf
+ (lsp-unconfig-buffer)
+ (lsp-configure-buffer))))
+ buffers)
+ nil)
+ ((equal method "window/showMessageRequest")
+ (let ((choice (lsp--window-log-message-request params)))
+ `(:title ,choice)))
+ ((equal method "window/showDocument")
+ (let ((success? (lsp--window-show-document params)))
+ (lsp-make-show-document-result :success (or success?
+ :json-false))))
+ ((equal method "client/unregisterCapability")
+ (mapc #'lsp--server-unregister-capability
+ (lsp:unregistration-params-unregisterations params))
+ (mapc (lambda (buf)
+ (when (lsp-buffer-live-p buf)
+ (lsp-with-current-buffer buf
+ (lsp-unconfig-buffer)
+ (lsp-configure-buffer))))
+ buffers)
+ nil)
+ ((equal method "workspace/applyEdit")
+ (list :applied (condition-case err
+ (prog1 t
+ (lsp--apply-workspace-edit (lsp:apply-workspace-edit-params-edit params) 'server-requested))
+ (error
+ (lsp--error "Failed to apply edits with message %s"
+ (error-message-string err))
+ :json-false))))
+ ((equal method "workspace/configuration")
+ (with-lsp-workspace workspace
+ (if-let ((buf (car buffers)))
+ (lsp-with-current-buffer buf
+ (lsp--build-workspace-configuration-response params))
+ (lsp--with-workspace-temp-buffer (lsp--workspace-root workspace)
+ (lsp--build-workspace-configuration-response params)))))
+ ((equal method "workspace/workspaceFolders")
+ (let ((folders (or (-> workspace
+ (lsp--workspace-client)
+ (lsp--client-server-id)
+ (gethash (lsp-session-server-id->folders (lsp-session))))
+ (lsp-session-folders (lsp-session)))))
+ (->> folders
+ (-distinct)
+ (-map (lambda (folder)
+ (list :uri (lsp--path-to-uri folder))))
+ (apply #'vector))))
+ ((equal method "window/workDoneProgress/create")
+ nil ;; no specific reply, no processing required
+ )
+ ((equal method "workspace/semanticTokens/refresh")
+ (when (and lsp-semantic-tokens-enable
+ (fboundp 'lsp--semantic-tokens-on-refresh))
+ (lsp--semantic-tokens-on-refresh workspace))
+ nil)
+ ((equal method "workspace/codeLens/refresh")
+ (when (and lsp-lens-enable
+ (fboundp 'lsp--lens-on-refresh))
+ (lsp--lens-on-refresh workspace))
+ nil)
+ (t (lsp-warn "Unknown request method: %s" method) nil))))
+ ;; Send response to the server.
+ (unless (eq response 'delay-response)
+ (lsp--send-request-response workspace recv-time request response))))
+
+(lsp-defun lsp--error-string ((&JSONError :message :code))
+ "Format ERR as a user friendly string."
+ (format "Error from the Language Server: %s (%s)"
+ message
+ (or (car (alist-get code lsp--errors)) "Unknown error")))
+
+(defun lsp--get-body-length (headers)
+ (let ((content-length (cdr (assoc "Content-Length" headers))))
+ (if content-length
+ (string-to-number content-length)
+
+ ;; This usually means either the server or our parser is
+ ;; screwed up with a previous Content-Length
+ (error "No Content-Length header"))))
+
+(defun lsp--parse-header (s)
+ "Parse string S as a LSP (KEY . VAL) header."
+ (let ((pos (string-match "\:" s))
+ key val)
+ (unless pos
+ (signal 'lsp-invalid-header-name (list s)))
+ (setq key (substring s 0 pos)
+ val (s-trim-left (substring s (+ 1 pos))))
+ (when (equal key "Content-Length")
+ (cl-assert (cl-loop for c across val
+ when (or (> c ?9) (< c ?0)) return nil
+ finally return t)
+ nil (format "Invalid Content-Length value: %s" val)))
+ (cons key val)))
+
+(defmacro lsp--read-json (str)
+ "Read json string STR."
+ (if (progn
+ (require 'json)
+ (fboundp 'json-parse-string))
+ `(json-parse-string ,str
+ :object-type (if lsp-use-plists
+ 'plist
+ 'hash-table)
+ :null-object nil
+ :false-object nil)
+ `(let ((json-array-type 'vector)
+ (json-object-type (if lsp-use-plists
+ 'plist
+ 'hash-table))
+ (json-false nil))
+ (json-read-from-string ,str))))
+
+(defmacro lsp-json-read-buffer ()
+ "Read json from the current buffer."
+ (if (progn
+ (require 'json)
+ (fboundp 'json-parse-string))
+ `(json-parse-buffer :object-type (if lsp-use-plists
+ 'plist
+ 'hash-table)
+ :null-object nil
+ :false-object nil)
+ `(let ((json-array-type 'vector)
+ (json-object-type (if lsp-use-plists
+ 'plist
+ 'hash-table))
+ (json-false nil))
+ (json-read))))
+
+(defun lsp--read-json-file (file-path)
+ "Read json file."
+ (-> file-path
+ (f-read-text)
+ (lsp--read-json)))
+
+(defun lsp--parser-on-message (json-data workspace)
+ "Called when the parser P read a complete MSG from the server."
+ (with-demoted-errors "Error processing message %S."
+ (with-lsp-workspace workspace
+ (let* ((client (lsp--workspace-client workspace))
+ (id (--when-let (lsp:json-response-id json-data)
+ (if (stringp it) (string-to-number it) it)))
+ (data (lsp:json-response-result json-data)))
+ (pcase (lsp--get-message-type json-data)
+ ('response
+ (cl-assert id)
+ (-let [(callback _ method _ before-send) (gethash id (lsp--client-response-handlers client))]
+ (when (lsp--log-io-p method)
+ (lsp--log-entry-new
+ (lsp--make-log-entry method id data 'incoming-resp
+ (/ (nth 2 (time-since before-send)) 1000))
+ workspace))
+ (when callback
+ (remhash id (lsp--client-response-handlers client))
+ (funcall callback (lsp:json-response-result json-data)))))
+ ('response-error
+ (cl-assert id)
+ (-let [(_ callback method _ before-send) (gethash id (lsp--client-response-handlers client))]
+ (when (lsp--log-io-p method)
+ (lsp--log-entry-new
+ (lsp--make-log-entry method id (lsp:json-response-error-error json-data)
+ 'incoming-resp (/ (nth 2 (time-since before-send)) 1000))
+ workspace))
+ (when callback
+ (remhash id (lsp--client-response-handlers client))
+ (funcall callback (lsp:json-response-error-error json-data)))))
+ ('notification
+ (lsp--on-notification workspace json-data))
+ ('request (lsp--on-request workspace json-data)))))))
+
+(defvar lsp-parsed-message nil
+ "This will store the string representation of the json message.
+
+In some cases like #1807 we lose information during json
+deserialization.")
+
+(defun lsp--create-filter-function (workspace)
+ "Make filter for the workspace."
+ (let ((body-received 0)
+ leftovers body-length body chunk)
+ (lambda (_proc input)
+ (setf chunk (if (s-blank? leftovers)
+ input
+ (concat leftovers input)))
+
+ (let (messages)
+ (while (not (s-blank? chunk))
+ (if (not body-length)
+ ;; Read headers
+ (if-let ((body-sep-pos (string-match-p "\r\n\r\n" chunk)))
+ ;; We've got all the headers, handle them all at once:
+ (setf body-length (lsp--get-body-length
+ (mapcar #'lsp--parse-header
+ (split-string
+ (substring-no-properties chunk
+ (or (string-match-p "Content-Length" chunk)
+ (error "Unable to find Content-Length header."))
+ body-sep-pos)
+ "\r\n")))
+ body-received 0
+ leftovers nil
+ chunk (substring-no-properties chunk (+ body-sep-pos 4)))
+
+ ;; Haven't found the end of the headers yet. Save everything
+ ;; for when the next chunk arrives and await further input.
+ (setf leftovers chunk
+ chunk nil))
+ (let* ((chunk-length (string-bytes chunk))
+ (left-to-receive (- body-length body-received))
+ (this-body (if (< left-to-receive chunk-length)
+ (prog1 (substring-no-properties chunk 0 left-to-receive)
+ (setf chunk (substring-no-properties chunk left-to-receive)))
+ (prog1 chunk
+ (setf chunk nil))))
+ (body-bytes (string-bytes this-body)))
+ (push this-body body)
+ (setf body-received (+ body-received body-bytes))
+ (when (>= chunk-length left-to-receive)
+ (condition-case err
+ (with-temp-buffer
+ (apply #'insert
+ (nreverse
+ (prog1 body
+ (setf leftovers nil
+ body-length nil
+ body-received nil
+ body nil))))
+ (decode-coding-region (point-min)
+ (point-max)
+ 'utf-8)
+ (goto-char (point-min))
+ (push (lsp-json-read-buffer) messages))
+
+ (error
+ (lsp-warn "Failed to parse the following chunk:\n'''\n%s\n'''\nwith message %s"
+ (concat leftovers input)
+ err)))))))
+ (mapc (lambda (msg)
+ (lsp--parser-on-message msg workspace))
+ (nreverse messages))))))
+
+(defvar-local lsp--line-col-to-point-hash-table nil
+ "Hash table with keys (line . col) and values that are either point positions
+or markers.")
+
+(defcustom lsp-imenu-detailed-outline t
+ "Whether `lsp-imenu' should include signatures.
+This will be ignored if the server doesn't provide the necessary
+information, for example if it doesn't support DocumentSymbols."
+ :group 'lsp-imenu
+ :type 'boolean)
+
+(defface lsp-details-face '((t :height 0.8 :inherit shadow))
+ "Used to display additional information troughout `lsp'.
+Things like line numbers, signatures, ... are considered
+additional information. Often, additional faces are defined that
+inherit from this face by default, like `lsp-signature-face', and
+they may be customized for finer control."
+ :group 'lsp-mode)
+
+(defface lsp-signature-face '((t :inherit lsp-details-face))
+ "Used to display signatures in `imenu', ...."
+ :group 'lsp-mode)
+
+(lsp-defun lsp-render-symbol ((&DocumentSymbol :name :detail? :deprecated?)
+ show-detail?)
+ "Render INPUT0, an `&DocumentSymbol', to a string.
+If SHOW-DETAIL? is set, make use of its `:detail?' field (often
+the signature)."
+ (let ((detail (and show-detail? (s-present? detail?)
+ (propertize (concat " " (s-trim-left detail?))
+ 'face 'lsp-signature-face)))
+ (name (if deprecated?
+ (propertize name 'face 'lsp-face-semhl-deprecated) name)))
+ (concat name detail)))
+
+(lsp-defun lsp-render-symbol-information ((&SymbolInformation :name :deprecated? :container-name?)
+ separator)
+ "Render a piece of SymbolInformation.
+Handle :deprecated?. If SEPARATOR is non-nil, the
+symbol's (optional) parent, SEPARATOR and the symbol itself are
+concatenated."
+ (when (and separator container-name? (not (string-empty-p container-name?)))
+ (setq name (concat name separator container-name?)))
+ (if deprecated? (propertize name 'face 'lsp-face-semhl-deprecated) name))
+
+(defun lsp--symbol-to-imenu-elem (sym)
+ "Convert SYM to imenu element.
+
+SYM is a SymbolInformation message.
+
+Return a cons cell (full-name . start-point)."
+ (let ((start-point (ht-get lsp--line-col-to-point-hash-table
+ (lsp--get-line-and-col sym))))
+ (cons (lsp-render-symbol-information
+ sym (and lsp-imenu-show-container-name
+ lsp-imenu-container-name-separator))
+ start-point)))
+
+(lsp-defun lsp--symbol-to-hierarchical-imenu-elem ((sym &as &DocumentSymbol :children?))
+ "Convert SYM to hierarchical imenu elements.
+
+SYM is a DocumentSymbol message.
+
+Return cons cell (\"symbol-name (symbol-kind)\" . start-point) if
+SYM doesn't have any children. Otherwise return a cons cell with
+an alist
+
+ (\"symbol-name\" . ((\"(symbol-kind)\" . start-point)
+ cons-cells-from-children))"
+ (let ((filtered-children (lsp--imenu-filter-symbols children?))
+ (signature (lsp-render-symbol sym lsp-imenu-detailed-outline)))
+ (if (seq-empty-p filtered-children)
+ (cons signature
+ (ht-get lsp--line-col-to-point-hash-table
+ (lsp--get-line-and-col sym)))
+ (cons signature
+ (lsp--imenu-create-hierarchical-index filtered-children)))))
+
+(lsp-defun lsp--symbol-ignore ((&SymbolInformation :kind))
+ "Determine if SYM is for the current document and is to be shown."
+ ;; It's a SymbolInformation or DocumentSymbol, which is always in the
+ ;; current buffer file.
+ (and lsp-imenu-index-symbol-kinds
+ (numberp kind)
+ (let ((clamped-kind (if (< 0 kind (length lsp/symbol-kind-lookup))
+ kind
+ 0)))
+ (not (memql (aref lsp/symbol-kind-lookup clamped-kind)
+ lsp-imenu-index-symbol-kinds)))))
+
+(lsp-defun lsp--get-symbol-type ((&SymbolInformation :kind))
+ "The string name of the kind of SYM."
+ (alist-get kind lsp-symbol-kinds "Other"))
+
+(defun lsp--get-line-and-col (sym)
+ "Obtain the line and column corresponding to SYM."
+ (-let* ((location (lsp:symbol-information-location sym))
+ (name-range (or (and location (lsp:location-range location))
+ (lsp:document-symbol-selection-range sym)))
+ ((&Range :start (&Position :line :character)) name-range))
+ (cons line character)))
+
+(defun lsp--collect-lines-and-cols (symbols)
+ "Return a sorted list ((line . col) ...) of the locations of SYMBOLS."
+ (let ((stack (mapcar 'identity symbols))
+ line-col-list)
+ (while stack
+ (let ((sym (pop stack)))
+ (push (lsp--get-line-and-col sym) line-col-list)
+ (unless (seq-empty-p (lsp:document-symbol-children? sym))
+ (setf stack (nconc (lsp--imenu-filter-symbols (lsp:document-symbol-children? sym)) stack)))))
+ (-sort #'lsp--line-col-comparator line-col-list)))
+
+(defun lsp--convert-line-col-to-points-batch (line-col-list)
+ "Convert a sorted list of positions from line-column
+representation to point representation."
+ (let ((line-col-to-point-map (ht-create))
+ (inhibit-field-text-motion t)
+ (curr-line 0))
+ (lsp-save-restriction-and-excursion
+ (goto-char (point-min))
+ (cl-loop for (line . col) in line-col-list do
+ (forward-line (- line curr-line))
+ (setq curr-line line)
+ (let ((line-end (line-end-position)))
+ (if (or (not col) (> col (- line-end (point))))
+ (goto-char line-end)
+ (forward-char col)))
+ (ht-set! line-col-to-point-map (cons line col) (if imenu-use-markers
+ (point-marker)
+ (point)))))
+ line-col-to-point-map))
+
+(cl-defun lsp--line-col-comparator ((l1 . c1) (l2 . c2))
+ (or (< l1 l2)
+ (and (= l1 l2)
+ (cond ((and c1 c2)
+ (< c1 c2))
+ (c1 t)))))
+
+(defun lsp-imenu-create-uncategorized-index (symbols)
+ "Create imenu index from document SYMBOLS.
+This function, unlike `lsp-imenu-create-categorized-index', does
+not categorize by type, but instead returns an `imenu' index
+corresponding to the symbol hierarchy returned by the server
+directly."
+ (let* ((lsp--line-col-to-point-hash-table (-> symbols
+ lsp--collect-lines-and-cols
+ lsp--convert-line-col-to-points-batch)))
+ (if (lsp--imenu-hierarchical-p symbols)
+ (lsp--imenu-create-hierarchical-index symbols)
+ (lsp--imenu-create-non-hierarchical-index symbols))))
+
+(defcustom lsp-imenu-symbol-kinds
+ '((1 . "Files")
+ (2 . "Modules")
+ (3 . "Namespaces")
+ (4 . "Packages")
+ (5 . "Classes")
+ (6 . "Methods")
+ (7 . "Properties")
+ (8 . "Fields")
+ (9 . "Constructors")
+ (10 . "Enums")
+ (11 . "Interfaces")
+ (12 . "Functions")
+ (13 . "Variables")
+ (14 . "Constants")
+ (15 . "Strings")
+ (16 . "Numbers")
+ (17 . "Booleans")
+ (18 . "Arrays")
+ (19 . "Objects")
+ (20 . "Keys")
+ (21 . "Nulls")
+ (22 . "Enum Members")
+ (23 . "Structs")
+ (24 . "Events")
+ (25 . "Operators")
+ (26 . "Type Parameters"))
+ "`lsp-symbol-kinds', but only used by `imenu'.
+A new variable is needed, as it is `imenu' convention to use
+pluralized categories, which `lsp-symbol-kinds' doesn't. If the
+non-pluralized names are preferred, this can be set to
+`lsp-symbol-kinds'."
+ :type '(alist :key-type integer :value-type string))
+
+(defun lsp--imenu-kind->name (kind)
+ (alist-get kind lsp-imenu-symbol-kinds "?"))
+
+(defun lsp-imenu-create-top-level-categorized-index (symbols)
+ "Create an `imenu' index categorizing SYMBOLS by type.
+Only root symbols are categorized.
+
+See `lsp-symbol-kinds' to customize the category naming. SYMBOLS
+shall be a list of DocumentSymbols or SymbolInformation."
+ (mapcan
+ (-lambda ((type . symbols))
+ (let ((cat (lsp--imenu-kind->name type))
+ (symbols (lsp-imenu-create-uncategorized-index symbols)))
+ ;; If there is no :kind (this is being defensive), or we couldn't look it
+ ;; up, just display the symbols inline, without categories.
+ (if cat (list (cons cat symbols)) symbols)))
+ (sort (seq-group-by #'lsp:document-symbol-kind symbols)
+ (-lambda ((kinda) (kindb)) (< kinda kindb)))))
+
+(lsp-defun lsp--symbol->imenu ((sym &as &DocumentSymbol :selection-range (&RangeToPoint :start)))
+ "Convert an `&DocumentSymbol' to an `imenu' entry."
+ (cons (lsp-render-symbol sym lsp-imenu-detailed-outline) start))
+
+(defun lsp--imenu-create-categorized-index-1 (symbols)
+ "Returns an `imenu' index from SYMBOLS categorized by type.
+The result looks like this: ((\"Variables\" . (...)))."
+ (->>
+ symbols
+ (mapcan
+ (-lambda ((sym &as &DocumentSymbol :kind :children?))
+ (if (seq-empty-p children?)
+ (list (list kind (lsp--symbol->imenu sym)))
+ (let ((parent (lsp-render-symbol sym lsp-imenu-detailed-outline)))
+ (cons
+ (list kind (lsp--symbol->imenu sym))
+ (mapcar (-lambda ((type . imenu-items))
+ (list type (cons parent (mapcan #'cdr imenu-items))))
+ (-group-by #'car (lsp--imenu-create-categorized-index-1 children?))))))))
+ (-group-by #'car)
+ (mapcar
+ (-lambda ((kind . syms))
+ (cons kind (mapcan #'cdr syms))))))
+
+(defun lsp--imenu-create-categorized-index (symbols)
+ (let ((syms (lsp--imenu-create-categorized-index-1 symbols)))
+ (dolist (sym syms)
+ (setcar sym (lsp--imenu-kind->name (car sym))))
+ syms))
+
+(lsp-defun lsp--symbol-information->imenu ((sym &as &SymbolInformation :location (&Location :range (&RangeToPoint :start))))
+ (cons (lsp-render-symbol-information sym nil) start))
+
+(defun lsp--imenu-create-categorized-index-flat (symbols)
+ "Create a kind-categorized index for SymbolInformation."
+ (mapcar (-lambda ((kind . syms))
+ (cons (lsp--imenu-kind->name kind)
+ (mapcan (-lambda ((parent . children))
+ (let ((children (mapcar #'lsp--symbol-information->imenu children)))
+ (if parent (list (cons parent children)) children)))
+ (-group-by #'lsp:symbol-information-container-name? syms))))
+ (seq-group-by #'lsp:symbol-information-kind symbols)))
+
+(defun lsp-imenu-create-categorized-index (symbols)
+ (if (lsp--imenu-hierarchical-p symbols)
+ (lsp--imenu-create-categorized-index symbols)
+ (lsp--imenu-create-categorized-index-flat symbols)))
+
+(defcustom lsp-imenu-index-function #'lsp-imenu-create-uncategorized-index
+ "Function that should create an `imenu' index.
+It will be called with a list of SymbolInformation or
+DocumentSymbols, whose first level is already filtered. It shall
+then return an appropriate `imenu' index (see
+`imenu-create-index-function').
+
+Note that this interface is not stable, and subject to change any
+time."
+ :group 'lsp-imenu
+ :type '(radio
+ (const :tag "Categorize by type"
+ lsp-imenu-create-categorized-index)
+ (const :tag "Categorize root symbols by type"
+ lsp-imenu-create-top-level-categorized-index)
+ (const :tag "Uncategorized, inline entries"
+ lsp-imenu-create-uncategorized-index)
+ (function :tag "Custom function")))
+
+(defun lsp--imenu-create-index ()
+ "Create an `imenu' index based on the language server.
+Respects `lsp-imenu-index-function'."
+ (let ((symbols (lsp--imenu-filter-symbols (lsp--get-document-symbols))))
+ (funcall lsp-imenu-index-function symbols)))
+
+(defun lsp--imenu-filter-symbols (symbols)
+ "Filter out unsupported symbols from SYMBOLS."
+ (seq-remove #'lsp--symbol-ignore symbols))
+
+(defun lsp--imenu-hierarchical-p (symbols)
+ "Determine whether any element in SYMBOLS has children."
+ (seq-some #'lsp-document-symbol? symbols))
+
+(defun lsp--imenu-create-non-hierarchical-index (symbols)
+ "Create imenu index for non-hierarchical SYMBOLS.
+
+SYMBOLS are a list of DocumentSymbol messages.
+
+Return a nested alist keyed by symbol names. e.g.
+
+ ((\"SomeClass\" (\"(Class)\" . 10)
+ (\"someField (Field)\" . 20)
+ (\"someFunction (Function)\" . 25)
+ (\"SomeSubClass\" (\"(Class)\" . 30)
+ (\"someSubField (Field)\" . 35))
+ (\"someFunction (Function)\" . 40))"
+ (seq-map (lambda (nested-alist)
+ (cons (car nested-alist)
+ (seq-map #'lsp--symbol-to-imenu-elem (cdr nested-alist))))
+ (seq-group-by #'lsp--get-symbol-type symbols)))
+
+(defun lsp--imenu-create-hierarchical-index (symbols)
+ "Create imenu index for hierarchical SYMBOLS.
+
+SYMBOLS are a list of DocumentSymbol messages.
+
+Return a nested alist keyed by symbol names. e.g.
+
+ ((\"SomeClass\" (\"(Class)\" . 10)
+ (\"someField (Field)\" . 20)
+ (\"someFunction (Function)\" . 25)
+ (\"SomeSubClass\" (\"(Class)\" . 30)
+ (\"someSubField (Field)\" . 35))
+ (\"someFunction (Function)\" . 40))"
+ (seq-map #'lsp--symbol-to-hierarchical-imenu-elem
+ (seq-sort #'lsp--imenu-symbol-lessp symbols)))
+
+(defun lsp--imenu-symbol-lessp (sym1 sym2)
+ (let* ((compare-results (mapcar (lambda (method)
+ (funcall (alist-get method lsp--imenu-compare-function-alist)
+ sym1 sym2))
+ lsp-imenu-sort-methods))
+ (result (seq-find (lambda (result)
+ (not (= result 0)))
+ compare-results
+ 0)))
+ (and (numberp result) (< result 0))))
+
+(lsp-defun lsp--imenu-compare-kind ((&SymbolInformation :kind left)
+ (&SymbolInformation :kind right))
+ "Compare SYM1 and SYM2 by kind."
+ (- left right))
+
+(defun lsp--imenu-compare-line-col (sym1 sym2)
+ (if (lsp--line-col-comparator
+ (lsp--get-line-and-col sym1)
+ (lsp--get-line-and-col sym2))
+ -1
+ 1))
+
+(lsp-defun lsp--imenu-compare-name ((&SymbolInformation :name name1)
+ (&SymbolInformation :name name2))
+ "Compare SYM1 and SYM2 by name."
+ (let ((result (compare-strings name1 0 (length name1) name2 0 (length name2))))
+ (if (numberp result) result 0)))
+
+(defun lsp--imenu-refresh ()
+ "Force Imenu to refresh itself."
+ (imenu--menubar-select imenu--rescan-item))
+
+(defun lsp-enable-imenu ()
+ "Use lsp-imenu for the current buffer."
+ (imenu--cleanup)
+ (setq-local imenu-create-index-function #'lsp--imenu-create-index)
+ (setq-local imenu-menubar-modified-tick -1)
+ (setq-local imenu--index-alist nil)
+ (when menu-bar-mode
+ (lsp--imenu-refresh)))
+
+(defun lsp-resolve-final-function (command)
+ "Resolve final function COMMAND."
+ (-let [command (if (functionp command) (funcall command) command)]
+ (cl-etypecase command
+ (list
+ (cl-assert (seq-every-p (apply-partially #'stringp) command) nil
+ "Invalid command list")
+ command)
+ (string (list command)))))
+
+(defun lsp-server-present? (final-command)
+ "Check whether FINAL-COMMAND is present."
+ ;; executable-find only gained support for remote checks after 27 release
+ (or (and (cond
+ ((not (file-remote-p default-directory))
+ (executable-find (cl-first final-command)))
+ ((version<= "27.0" emacs-version)
+ (with-no-warnings (executable-find (cl-first final-command) (file-remote-p default-directory))))
+ (t))
+ (prog1 t
+ (lsp-log "Command \"%s\" is present on the path." (s-join " " final-command))))
+ (ignore (lsp-log "Command \"%s\" is not present on the path." (s-join " " final-command)))))
+
+(defun lsp--value-to-string (value)
+ "Convert VALUE to a string that can be set as value in an environment variable."
+ (cond
+ ((stringp value) value)
+ ((booleanp value) (if value
+ "1"
+ "0"))
+ ((and (sequencep value)
+ (seq-every-p #'stringp value)) (string-join value ":"))
+ (t (user-error "Only strings, booleans, and sequences of strings are supported as environment variables"))))
+
+(defun lsp--compute-process-environment (environment-fn)
+ "Append a list of KEY=VALUE from the alist ENVIRONMENT to `process-environment'.
+Ignore non-boolean keys whose value is nil."
+ (let ((environment (if environment-fn
+ (funcall environment-fn)
+ nil)))
+ (-flatten (cons (cl-loop for (key . value) in environment
+ if (or (eval value)
+ (eq (get value 'custom-type) 'boolean))
+ collect (concat key "=" (lsp--value-to-string
+ (eval value))))
+ process-environment))))
+
+(defun lsp-stdio-connection (command &optional test-command)
+ "Returns a connection property list using COMMAND.
+COMMAND can be: A string, denoting the command to launch the
+language server. A list of strings, denoting an executable with
+its command line arguments. A function, that either returns a
+string or a list of strings. In all cases, the launched language
+server should send and receive messages on standard I/O.
+TEST-COMMAND is a function with no arguments which returns
+whether the command is present or not. When not specified
+`lsp-mode' will check whether the first element of the list
+returned by COMMAND is available via `executable-find'"
+ (cl-check-type command (or string
+ function
+ (and list
+ (satisfies (lambda (l)
+ (seq-every-p (lambda (el)
+ (stringp el))
+ l))))))
+ (list :connect (lambda (filter sentinel name environment-fn)
+ (let ((final-command (lsp-resolve-final-function command))
+ (process-name (generate-new-buffer-name name))
+ (process-environment
+ (lsp--compute-process-environment environment-fn)))
+ (let* ((stderr-buf (format "*%s::stderr*" process-name))
+ (proc (make-process
+ :name process-name
+ :connection-type 'pipe
+ :buffer (format "*%s*" process-name)
+ :coding 'no-conversion
+ :command final-command
+ :filter filter
+ :sentinel sentinel
+ :stderr stderr-buf
+ :noquery t)))
+ (set-process-query-on-exit-flag proc nil)
+ (set-process-query-on-exit-flag (get-buffer-process stderr-buf) nil)
+ (with-current-buffer (get-buffer stderr-buf)
+ ;; Make the *NAME::stderr* buffer buffer-read-only, q to bury, etc.
+ (special-mode))
+ (cons proc proc))))
+ :test? (or
+ test-command
+ (lambda () (-> command lsp-resolve-final-function lsp-server-present?)))))
+
+(defun lsp--open-network-stream (host port name)
+ "Open network stream to HOST:PORT.
+ NAME will be passed to `open-network-stream'.
+ RETRY-COUNT is the number of the retries.
+ SLEEP-INTERVAL is the sleep interval between each retry."
+ (let* ((retries 0)
+ (sleep-interval 0.01)
+ (number-of-retries (/ lsp-tcp-connection-timeout sleep-interval))
+ connection)
+ (while (and (not connection) (< retries number-of-retries))
+ (condition-case err
+ (setq connection (open-network-stream name nil host port
+ :type 'plain
+ :coding 'no-conversion))
+ (file-error
+ (let ((inhibit-message t))
+ (lsp--warn "Failed to connect to %s:%s with error message %s"
+ host
+ port
+ (error-message-string err))
+ (sleep-for sleep-interval)
+ (cl-incf retries)))))
+ (or connection (error "Port %s was never taken. Consider increasing `lsp-tcp-connection-timeout'." port))))
+
+(defun lsp--find-available-port (host starting-port)
+ "Find available port on HOST starting from STARTING-PORT."
+ (let ((success nil)
+ (port starting-port))
+ (while (and (not success))
+ (condition-case _err
+ (progn
+ (delete-process (open-network-stream "*connection-test*" nil host port :type 'plain))
+ (cl-incf port))
+ (file-error (setq success t))))
+ port))
+
+(defun lsp-tcp-connection (command-fn)
+ "Returns a connection property list similar to `lsp-stdio-connection'.
+COMMAND-FN can only be a function that takes a single argument, a
+port number. It should return a command for launches a language server
+process listening for TCP connections on the provided port."
+ (cl-check-type command-fn function)
+ (list
+ :connect (lambda (filter sentinel name environment-fn)
+ (let* ((host "localhost")
+ (port (lsp--find-available-port host (cl-incf lsp--tcp-port)))
+ (command (funcall command-fn port))
+ (final-command (if (consp command) command (list command)))
+ (_ (unless (executable-find (cl-first final-command))
+ (user-error (format "Couldn't find executable %s" (cl-first final-command)))))
+ (process-environment
+ (lsp--compute-process-environment environment-fn))
+ (proc (make-process :name name :connection-type 'pipe :coding 'no-conversion
+ :command final-command :sentinel sentinel :stderr (format "*%s::stderr*" name) :noquery t))
+ (tcp-proc (lsp--open-network-stream host port (concat name "::tcp"))))
+
+ ;; TODO: Same :noquery issue (see above)
+ (set-process-query-on-exit-flag proc nil)
+ (set-process-query-on-exit-flag tcp-proc nil)
+ (set-process-filter tcp-proc filter)
+ (cons tcp-proc proc)))
+ :test? (lambda () (executable-find (cl-first (funcall command-fn 0))))))
+
+(defalias 'lsp-tcp-server 'lsp-tcp-server-command)
+
+(defun lsp-tcp-server-command (command-fn)
+ "Create tcp server connection.
+In this mode Emacs is TCP server and the language server connects
+to it. COMMAND is function with one parameter(the port) and it
+should return the command to start the LS server."
+ (cl-check-type command-fn function)
+ (list
+ :connect (lambda (filter sentinel name environment-fn)
+ (let* (tcp-client-connection
+ (tcp-server (make-network-process :name (format "*tcp-server-%s*" name)
+ :buffer (format "*tcp-server-%s*" name)
+ :family 'ipv4
+ :service lsp--tcp-server-port
+ :sentinel (lambda (proc _string)
+ (lsp-log "Language server %s is connected." name)
+ (setf tcp-client-connection proc))
+ :server 't))
+ (port (process-contact tcp-server :service))
+ (final-command (funcall command-fn port))
+ (process-environment
+ (lsp--compute-process-environment environment-fn))
+ (cmd-proc (make-process :name name
+ :connection-type 'pipe
+ :coding 'no-conversion
+ :command final-command
+ :stderr (format "*tcp-server-%s*::stderr" name)
+ :noquery t)))
+ (let ((retries 0))
+ ;; wait for the client to connect (we sit-for 500 ms, so have to double lsp--tcp-server-wait-seconds)
+ (while (and (not tcp-client-connection) (< retries (* 2 lsp--tcp-server-wait-seconds)))
+ (lsp--info "Waiting for connection for %s, retries: %s" name retries)
+ (sit-for 0.500)
+ (cl-incf retries)))
+
+ (unless tcp-client-connection
+ (condition-case nil (delete-process tcp-server) (error))
+ (condition-case nil (delete-process cmd-proc) (error))
+ (error "Failed to create connection to %s on port %s" name port))
+ (lsp--info "Successfully connected to %s" name)
+
+ (set-process-query-on-exit-flag cmd-proc nil)
+ (set-process-query-on-exit-flag tcp-client-connection nil)
+ (set-process-query-on-exit-flag tcp-server nil)
+
+ (set-process-filter tcp-client-connection filter)
+ (set-process-sentinel tcp-client-connection sentinel)
+ (cons tcp-client-connection cmd-proc)))
+ :test? (lambda () (executable-find (cl-first (funcall command-fn 0))))))
+
+(defun lsp-tramp-connection (local-command &optional generate-error-file-fn)
+ "Create LSP stdio connection named name.
+LOCAL-COMMAND is either list of strings, string or function which
+returns the command to execute."
+ (list :connect (lambda (filter sentinel name environment-fn)
+ (let* ((final-command (lsp-resolve-final-function local-command))
+ ;; wrap with stty to disable converting \r to \n
+ (process-name (generate-new-buffer-name name))
+ (wrapped-command (s-join
+ " "
+ (append '("stty" "raw" ";")
+ final-command
+ (list
+ (concat "2>"
+ (or (when generate-error-file-fn
+ (funcall generate-error-file-fn name))
+ (format "/tmp/%s-%s-stderr" name
+ (cl-incf lsp--stderr-index))))))))
+ (process-environment
+ (lsp--compute-process-environment environment-fn)))
+ (let ((proc (start-file-process-shell-command process-name
+ (format "*%s*" process-name)
+ wrapped-command)))
+ (set-process-sentinel proc sentinel)
+ (set-process-filter proc filter)
+ (set-process-query-on-exit-flag proc nil)
+ (set-process-coding-system proc 'binary 'binary)
+ (cons proc proc))))
+ :test? (lambda () (-> local-command lsp-resolve-final-function lsp-server-present?))))
+
+(defun lsp--auto-configure ()
+ "Autoconfigure `company', `flycheck', `lsp-ui', etc if they are installed."
+ (when (functionp 'lsp-ui-mode)
+ (lsp-ui-mode))
+
+ (when lsp-headerline-breadcrumb-enable
+ (add-hook 'lsp-configure-hook 'lsp-headerline-breadcrumb-mode))
+ (when lsp-modeline-code-actions-enable
+ (add-hook 'lsp-configure-hook 'lsp-modeline-code-actions-mode))
+ (when lsp-modeline-diagnostics-enable
+ (add-hook 'lsp-configure-hook 'lsp-modeline-diagnostics-mode))
+ (when lsp-modeline-workspace-status-enable
+ (add-hook 'lsp-configure-hook 'lsp-modeline-workspace-status-mode))
+ (when lsp-lens-enable
+ (add-hook 'lsp-configure-hook 'lsp-lens--enable))
+ (when lsp-semantic-tokens-enable
+ (add-hook 'lsp-configure-hook 'lsp-semantic-tokens--enable))
+
+ ;; yas-snippet config
+ (setq-local yas-inhibit-overlay-modification-protection t))
+
+(defvar-local lsp--buffer-deferred nil
+ "Whether buffer was loaded via `lsp-deferred'.")
+
+(defun lsp--restart-if-needed (workspace)
+ "Handler restart for WORKSPACE."
+ (when (or (eq lsp-restart 'auto-restart)
+ (eq (lsp--workspace-shutdown-action workspace) 'restart)
+ (and (eq lsp-restart 'interactive)
+ (let ((query (format
+ "Server %s exited with status %s(check corresponding stderr buffer for details). Do you want to restart it?"
+ (lsp--workspace-print workspace)
+ (process-status (lsp--workspace-proc workspace)))))
+ (y-or-n-p query))))
+ (--each (lsp--workspace-buffers workspace)
+ (when (lsp-buffer-live-p it)
+ (lsp-with-current-buffer it
+ (if lsp--buffer-deferred
+ (lsp-deferred)
+ (lsp--info "Restarting LSP in buffer %s" (buffer-name))
+ (lsp)))))))
+
+(defun lsp--update-key (table key fn)
+ "Apply FN on value corresponding to KEY in TABLE."
+ (let ((existing-value (gethash key table)))
+ (if-let ((new-value (funcall fn existing-value)))
+ (puthash key new-value table)
+ (remhash key table))))
+
+(defun lsp--process-sentinel (workspace process exit-str)
+ "Create the sentinel for WORKSPACE."
+ (unless (process-live-p process)
+ (let* ((status (process-status process))
+ (folder->workspaces (lsp-session-folder->servers (lsp-session)))
+ (stderr (-> workspace lsp--workspace-proc process-name get-buffer)))
+
+ (lsp--warn "%s has exited (%s)"
+ (process-name (lsp--workspace-proc workspace))
+ (string-trim-right exit-str))
+
+ (with-lsp-workspace workspace
+ ;; Clean workspace related data in each of the buffers
+ ;; in the workspace.
+ (--each (lsp--workspace-buffers workspace)
+ (when (lsp-buffer-live-p it)
+ (lsp-with-current-buffer it
+ (setq lsp--buffer-workspaces (delete workspace lsp--buffer-workspaces))
+ (lsp--uninitialize-workspace)
+ (lsp--spinner-stop)
+ (lsp--remove-overlays 'lsp-highlight))))
+
+ ;; Cleanup session from references to the closed workspace.
+ (--each (hash-table-keys folder->workspaces)
+ (lsp--update-key folder->workspaces it (apply-partially 'delete workspace)))
+
+ ;; Kill standard error buffer only if the process exited normally.
+ ;; Leave it intact otherwise for debugging purposes.
+ (when (and (eq status 'exit) (zerop (process-exit-status process)) (buffer-live-p stderr))
+ (kill-buffer stderr)))
+
+ (run-hook-with-args 'lsp-after-uninitialized-functions workspace)
+
+ (if (eq (lsp--workspace-shutdown-action workspace) 'shutdown)
+ (lsp--info "Workspace %s shutdown." (lsp--workspace-print workspace))
+ (lsp--restart-if-needed workspace))
+ (lsp--cleanup-hanging-watches))))
+
+(defun lsp-workspace-folders (workspace)
+ "Return all folders associated with WORKSPACE."
+ (let (result)
+ (->> (lsp-session)
+ (lsp-session-folder->servers)
+ (maphash (lambda (folder workspaces)
+ (when (-contains? workspaces workspace)
+ (push folder result)))))
+ result))
+
+(defun lsp--start-workspace (session client-template root &optional initialization-options)
+ "Create new workspace for CLIENT-TEMPLATE with project root ROOT.
+INITIALIZATION-OPTIONS are passed to initialize function.
+SESSION is the active session."
+ (lsp--spinner-start)
+ (-let* ((default-directory root)
+ (client (copy-lsp--client client-template))
+ (workspace (make-lsp--workspace
+ :root root
+ :client client
+ :status 'starting
+ :buffers (list (lsp-current-buffer))
+ :host-root (file-remote-p root)))
+ ((&lsp-cln 'server-id 'environment-fn 'new-connection 'custom-capabilities
+ 'multi-root 'initialized-fn) client)
+ ((proc . cmd-proc) (funcall
+ (or (plist-get new-connection :connect)
+ (user-error "Client %s is configured incorrectly" client))
+ (lsp--create-filter-function workspace)
+ (apply-partially #'lsp--process-sentinel workspace)
+ (format "%s" server-id)
+ environment-fn))
+ (workspace-folders (gethash server-id (lsp-session-server-id->folders session))))
+ (setf (lsp--workspace-proc workspace) proc
+ (lsp--workspace-cmd-proc workspace) cmd-proc)
+
+ ;; update (lsp-session-folder->servers) depending on whether we are starting
+ ;; multi/single folder workspace
+ (mapc (lambda (project-root)
+ (->> session
+ (lsp-session-folder->servers)
+ (gethash project-root)
+ (cl-pushnew workspace)))
+ (or workspace-folders (list root)))
+
+ (with-lsp-workspace workspace
+ (run-hooks 'lsp-before-initialize-hook)
+ (lsp-request-async
+ "initialize"
+ (append
+ (list :processId nil
+ :rootPath (lsp-file-local-name (expand-file-name root))
+ :clientInfo (list :name "emacs"
+ :version (emacs-version))
+ :rootUri (lsp--path-to-uri root)
+ :capabilities (lsp--client-capabilities custom-capabilities)
+ :initializationOptions initialization-options
+ :workDoneToken "1")
+ (when lsp-server-trace
+ (list :trace lsp-server-trace))
+ (when multi-root
+ (->> workspace-folders
+ (-distinct)
+ (-map (lambda (folder)
+ (list :uri (lsp--path-to-uri folder)
+ :name (f-filename folder))))
+ (apply 'vector)
+ (list :workspaceFolders))))
+ (lambda (response)
+ (unless response
+ (lsp--spinner-stop)
+ (signal 'lsp-empty-response-error (list "initialize")))
+
+ (let* ((capabilities (lsp:initialize-result-capabilities response))
+ (json-object-type 'hash-table)
+ (text-document-sync (-some-> lsp-parsed-message
+ (json-read-from-string)
+ (ht-get "result")
+ (ht-get "capabilities")
+ (ht-get "textDocumentSync")))
+ (save (when (ht? text-document-sync)
+ (ht-get text-document-sync "save"))))
+ ;; see #1807
+ (when (and (ht? save) (ht-empty? save))
+ (-> capabilities
+ (lsp:server-capabilities-text-document-sync?)
+ (lsp:set-text-document-sync-options-save? save)))
+
+ (setf (lsp--workspace-server-capabilities workspace) capabilities
+ (lsp--workspace-status workspace) 'initialized)
+
+ (with-lsp-workspace workspace
+ (lsp-notify "initialized" lsp--empty-ht))
+
+ (when initialized-fn (funcall initialized-fn workspace))
+
+ (cl-callf2 -filter #'lsp-buffer-live-p (lsp--workspace-buffers workspace))
+ (->> workspace
+ (lsp--workspace-buffers)
+ (mapc (lambda (buffer)
+ (lsp-with-current-buffer buffer
+ (lsp--open-in-workspace workspace)))))
+
+ (with-lsp-workspace workspace
+ (run-hooks 'lsp-after-initialize-hook))
+ (lsp--info "%s initialized successfully in folders: %s"
+ (lsp--workspace-print workspace)
+ (lsp-workspace-folders workspace))))
+ :mode 'detached))
+ workspace))
+
+(defun lsp--load-default-session ()
+ "Load default session."
+ (setq lsp--session (or (condition-case err
+ (lsp--read-from-file lsp-session-file)
+ (error (lsp--error "Failed to parse the session %s, starting with clean one."
+ (error-message-string err))
+ nil))
+ (make-lsp-session))))
+
+(defun lsp-session ()
+ "Get the session associated with the current buffer."
+ (or lsp--session (setq lsp--session (lsp--load-default-session))))
+
+(defun lsp--client-disabled-p (buffer-major-mode client)
+ (seq-some
+ (lambda (entry)
+ (pcase entry
+ ((pred symbolp) (eq entry client))
+ (`(,mode . ,client-or-list)
+ (and (eq mode buffer-major-mode)
+ (if (listp client-or-list)
+ (memq client client-or-list)
+ (eq client client-or-list))))))
+ lsp-disabled-clients))
+
+
+;; download server
+
+(defcustom lsp-server-install-dir (expand-file-name
+ (locate-user-emacs-file (f-join ".cache" "lsp")))
+ "Directory in which the servers will be installed."
+ :risky t
+ :type 'directory
+ :package-version '(lsp-mode . "6.3")
+ :group 'lsp-mode)
+
+(defcustom lsp-verify-signature t
+ "Whether to check GPG signatures of downloaded files."
+ :type 'boolean
+ :package-version '(lsp-mode . "8.0.0")
+ :group 'lsp-mode)
+
+(defvar lsp--dependencies (ht))
+
+(defun lsp-dependency (name &rest definitions)
+ "Used to specify a language server DEPENDENCY, the server
+executable or other required file path. Typically, the
+DEPENDENCY is found by locating it on the system path using
+`executable-find'.
+
+You can explicitly call lsp-dependency in your environment to
+specify the absolute path to the DEPENDENCY. For example, the
+typescript-language-server requires both the server and the
+typescript compiler. If you've installed them in a team shared
+read-only location, you can instruct lsp-mode to use them via
+
+ (eval-after-load 'lsp-mode
+ '(progn
+ (require 'lsp-javascript)
+ (lsp-dependency 'typescript-language-server `(:system ,tls-exe))
+ (lsp-dependency 'typescript `(:system ,ts-js))))
+
+where tls-exe is the absolute path to the typescript-language-server
+executable and ts-js is the absolute path to the typescript compiler
+JavaScript file, tsserver.js (the *.js is required for Windows)."
+ (ht-set lsp--dependencies name definitions))
+
+(defun lsp--server-binary-present? (client)
+ (unless (equal (lsp--client-server-id client) 'lsp-pwsh)
+ (condition-case ()
+ (-some-> client lsp--client-new-connection (plist-get :test?) funcall)
+ (error nil)
+ (args-out-of-range nil))))
+
+(define-minor-mode lsp-installation-buffer-mode
+ "Mode used in *lsp-installation* buffers.
+It can be used to set-up keybindings, etc. Disabling this mode
+detaches the installation buffer from commands like
+`lsp-select-installation-buffer'."
+ :init-value nil
+ :lighter nil)
+
+(defface lsp-installation-finished-buffer-face '((t :foreground "orange"))
+ "Face used for finished installation buffers.
+Used in `lsp-select-installation-buffer'."
+ :group 'lsp-mode)
+
+(defface lsp-installation-buffer-face '((t :foreground "green"))
+ "Face used for installation buffers still in progress.
+Used in `lsp-select-installation-buffer'."
+ :group 'lsp-mode)
+
+(defun lsp--installation-buffer? (buf)
+ "Check whether BUF is an `lsp-async-start-process' buffer."
+ (buffer-local-value 'lsp-installation-buffer-mode buf))
+
+(defun lsp-select-installation-buffer (&optional show-finished)
+ "Interactively choose an installation buffer.
+If SHOW-FINISHED is set, leftover (finished) installation buffers
+are still shown."
+ (interactive "P")
+ (let ((bufs (--filter (and (lsp--installation-buffer? it)
+ (or show-finished (get-buffer-process it)))
+ (buffer-list))))
+ (pcase bufs
+ (`nil (user-error "No installation buffers"))
+ (`(,buf) (pop-to-buffer buf))
+ (bufs (pop-to-buffer (completing-read "Select installation buffer: "
+ (--map (propertize (buffer-name it) 'face
+ (if (get-buffer-process it)
+ 'lsp-installation-buffer-face
+ 'lsp-installation-finished-buffer-face))
+ bufs)))))))
+
+(defun lsp-cleanup-installation-buffers ()
+ "Delete finished *lsp-installation* buffers."
+ (interactive)
+ (dolist (buf (buffer-list))
+ (when (and (lsp--installation-buffer? buf) (not (get-buffer-process buf)))
+ (kill-buffer buf))))
+
+(defun lsp--download-status ()
+ (-some--> #'lsp--client-download-in-progress?
+ (lsp--filter-clients it)
+ (-map (-compose #'symbol-name #'lsp--client-server-id) it)
+ (format "%s" it)
+ (propertize it 'face 'success)
+ (format " Installing following servers: %s" it)
+ (propertize it
+ 'local-map (make-mode-line-mouse-map
+ 'mouse-1 #'lsp-select-installation-buffer)
+ 'mouse-face 'highlight)))
+
+(defun lsp--install-server-internal (client &optional update?)
+ (unless (lsp--client-download-server-fn client)
+ (user-error "There is no automatic installation for `%s', you have to install it manually following lsp-mode's documentation."
+ (lsp--client-server-id client)))
+
+ (setf (lsp--client-download-in-progress? client) t)
+ (add-to-list 'global-mode-string '(t (:eval (lsp--download-status))))
+ (cl-flet ((done
+ (success? &optional error-message)
+ ;; run with idle timer to make sure the lsp command is executed in
+ ;; the main thread, see #2739.
+ (run-with-timer
+ 0.0
+ nil
+ (lambda ()
+ (-let [(&lsp-cln 'server-id 'buffers) client]
+ (setf (lsp--client-download-in-progress? client) nil
+ (lsp--client-buffers client) nil)
+ (if success?
+ (lsp--info "Server %s downloaded, auto-starting in %s buffers." server-id
+ (length buffers))
+ (lsp--error "Server %s install process failed with the following error message: %s.
+Check `*lsp-install*' and `*lsp-log*' buffer."
+ server-id
+ error-message))
+ (seq-do
+ (lambda (buffer)
+ (when (lsp-buffer-live-p buffer)
+ (lsp-with-current-buffer buffer
+ (cl-callf2 -remove-item '(t (:eval (lsp--download-status)))
+ global-mode-string)
+ (when success? (lsp)))))
+ buffers)
+ (unless (lsp--filter-clients #'lsp--client-download-in-progress?)
+ (cl-callf2 -remove-item '(t (:eval (lsp--download-status)))
+ global-mode-string)))))))
+ (lsp--info "Download %s started." (lsp--client-server-id client))
+ (condition-case err
+ (funcall
+ (lsp--client-download-server-fn client)
+ client
+ (lambda () (done t))
+ (lambda (msg) (done nil msg))
+ update?)
+ (error
+ (done nil (error-message-string err))))))
+
+(defun lsp--require-packages ()
+ "Load `lsp-client-packages' if needed."
+ (when (and lsp-auto-configure (not lsp--client-packages-required))
+ (seq-do (lambda (package)
+ ;; loading client is slow and `lsp' can be called repeatedly
+ (unless (featurep package)
+ (require package nil t)))
+ lsp-client-packages)
+ (setq lsp--client-packages-required t)))
+
+;;;###autoload
+(defun lsp-install-server (update? &optional server-id)
+ "Interactively install or re-install server.
+When prefix UPDATE? is t force installation even if the server is present."
+ (interactive "P")
+ (lsp--require-packages)
+ (let* ((chosen-client (or (gethash server-id lsp-clients)
+ (lsp--completing-read
+ "Select server to install/re-install: "
+ (or (->> lsp-clients
+ (ht-values)
+ (-filter (-andfn
+ (-not #'lsp--client-download-in-progress?)
+ #'lsp--client-download-server-fn)))
+ (user-error "There are no servers with automatic installation"))
+ (lambda (client)
+ (let ((server-name (-> client lsp--client-server-id symbol-name)))
+ (if (lsp--server-binary-present? client)
+ (concat server-name " (Already installed)")
+ server-name)))
+ nil
+ t)))
+ (update? (or update?
+ (and (not (lsp--client-download-in-progress? chosen-client))
+ (lsp--server-binary-present? chosen-client)))))
+ (lsp--install-server-internal chosen-client update?)))
+
+;;;###autoload
+(defun lsp-update-server (&optional server-id)
+ "Interactively update a server."
+ (interactive)
+ (lsp--require-packages)
+ (let ((chosen-client (or (gethash server-id lsp-clients)
+ (lsp--completing-read
+ "Select server to update (if not on the list, probably you need to `lsp-install-server`): "
+ (or (->> lsp-clients
+ (ht-values)
+ (-filter (-andfn
+ (-not #'lsp--client-download-in-progress?)
+ #'lsp--client-download-server-fn
+ #'lsp--server-binary-present?)))
+ (user-error "There are no servers to update"))
+ (lambda (client)
+ (-> client lsp--client-server-id symbol-name))
+ nil
+ t))))
+ (lsp--install-server-internal chosen-client t)))
+
+;;;###autoload
+(defun lsp-ensure-server (server-id)
+ "Ensure server SERVER-ID"
+ (lsp--require-packages)
+ (if-let ((client (gethash server-id lsp-clients)))
+ (unless (lsp--server-binary-present? client)
+ (lsp--info "Server `%s' is not preset, installing..." server-id)
+ (lsp-install-server nil server-id))
+ (warn "Unable to find server registration with id %s" server-id)))
+
+(defun lsp-async-start-process (callback error-callback &rest command)
+ "Start async process COMMAND with CALLBACK and ERROR-CALLBACK."
+ (let ((name (cl-first command)))
+ (with-current-buffer (compilation-start (mapconcat #'shell-quote-argument command " ") t
+ (lambda (&rest _)
+ (generate-new-buffer-name (format "*lsp-install: %s*" name))))
+ (lsp-installation-buffer-mode +1)
+ (view-mode +1)
+ (add-hook
+ 'compilation-finish-functions
+ (lambda (_buf status)
+ (if (string= "finished\n" status)
+ (condition-case err
+ (funcall callback)
+ (error
+ (funcall error-callback (error-message-string err))))
+ (funcall error-callback (s-trim-right status))))
+ nil t))))
+
+(defun lsp-resolve-value (value)
+ "Resolve VALUE's value.
+If it is function - call it.
+If it is symbol - return it's value
+Otherwise returns value itself."
+ (cond
+ ((functionp value) (funcall value))
+ ((symbolp value) (symbol-value value))
+ (value)))
+
+(defvar lsp-deps-providers
+ (list :npm (list :path #'lsp--npm-dependency-path
+ :install #'lsp--npm-dependency-install)
+ :system (list :path #'lsp--system-path)
+ :download (list :path #'lsp-download-path
+ :install #'lsp-download-install)))
+
+(defun lsp--system-path (path)
+ "If PATH is absolute and exists return it as is. Otherwise,
+return the absolute path to the executable defined by PATH or
+nil."
+ ;; For node.js 'sub-packages' PATH may point to a *.js file. Consider the
+ ;; typescript-language-server. When lsp invokes the server, lsp needs to
+ ;; supply the path to the typescript compiler, tsserver.js, as an argument. To
+ ;; make code platform independent, one must pass the absolute path to the
+ ;; tsserver.js file (Windows requires a *.js file - see help on the JavaScript
+ ;; child process spawn command that is invoked by the
+ ;; typescript-language-server). This is why we check for existence and not
+ ;; that the path is executable.
+ (let ((path (lsp-resolve-value path)))
+ (if (and (f-absolute? path)
+ (f-exists? path))
+ path
+ (executable-find path))))
+
+(defun lsp-package-path (dependency)
+ "Path to the DEPENDENCY each of the registered providers."
+ (let (path)
+ (-first (-lambda ((provider . rest))
+ (setq path (-some-> lsp-deps-providers
+ (plist-get provider)
+ (plist-get :path)
+ (apply rest))))
+ (gethash dependency lsp--dependencies))
+ path))
+
+(defun lsp-package-ensure (dependency callback error-callback)
+ "Asynchronously ensure a package."
+ (or (-first (-lambda ((provider . rest))
+ (-some-> lsp-deps-providers
+ (plist-get provider)
+ (plist-get :install)
+ (apply (cl-list* callback error-callback rest))))
+ (gethash dependency lsp--dependencies))
+ (funcall error-callback (format "Unable to find a way to install %s" dependency))))
+
+
+;; npm handling
+
+;; https://docs.npmjs.com/files/folders#executables
+(cl-defun lsp--npm-dependency-path (&key package path &allow-other-keys)
+ "Return npm dependency PATH for PACKAGE."
+ (let ((path (executable-find
+ (f-join lsp-server-install-dir "npm" package
+ (cond ((eq system-type 'windows-nt) "")
+ (t "bin"))
+ path))))
+ (unless (and path (f-exists? path))
+ (error "The package %s is not installed. Unable to find %s" package path))
+ path))
+
+(cl-defun lsp--npm-dependency-install (callback error-callback &key package &allow-other-keys)
+ (if-let ((npm-binary (executable-find "npm")))
+ (progn
+ ;; Explicitly `make-directory' to work around NPM bug in
+ ;; versions 7.0.0 through 7.4.1. See
+ ;; https://github.com/emacs-lsp/lsp-mode/issues/2364 for
+ ;; discussion.
+ (make-directory (f-join lsp-server-install-dir "npm" package "lib") 'parents)
+ (lsp-async-start-process callback
+ error-callback
+ npm-binary
+ "-g"
+ "--prefix"
+ (f-join lsp-server-install-dir "npm" package)
+ "install"
+ package))
+ (lsp-log "Unable to install %s via `npm' because it is not present" package)
+ nil))
+
+
+;; Download URL handling
+(cl-defun lsp-download-install (callback error-callback &key url asc-url pgp-key store-path decompress &allow-other-keys)
+ (let* ((url (lsp-resolve-value url))
+ (store-path (lsp-resolve-value store-path))
+ ;; (decompress (lsp-resolve-value decompress))
+ (download-path
+ (pcase decompress
+ (:gzip (concat store-path ".gz"))
+ (:zip (concat store-path ".zip"))
+ (`nil store-path)
+ (_ (error ":decompress must be `:gzip', `:zip' or `nil'")))))
+ (make-thread
+ (lambda ()
+ (condition-case err
+ (progn
+ (when (f-exists? download-path)
+ (f-delete download-path))
+ (when (f-exists? store-path)
+ (f-delete store-path))
+ (lsp--info "Starting to download %s to %s..." url download-path)
+ (mkdir (f-parent download-path) t)
+ (url-copy-file url download-path)
+ (lsp--info "Finished downloading %s..." download-path)
+ (when (and lsp-verify-signature asc-url pgp-key)
+ (if (executable-find epg-gpg-program)
+ (let ((asc-download-path (concat download-path ".asc"))
+ (context (epg-make-context))
+ (fingerprint)
+ (signature))
+ (when (f-exists? asc-download-path)
+ (f-delete asc-download-path))
+ (lsp--info "Starting to download %s to %s..." asc-url asc-download-path)
+ (url-copy-file asc-url asc-download-path)
+ (lsp--info "Finished downloading %s..." asc-download-path)
+ (epg-import-keys-from-string context pgp-key)
+ (setq fingerprint (epg-import-status-fingerprint
+ (car
+ (epg-import-result-imports
+ (epg-context-result-for context 'import)))))
+ (lsp--info "Verifying signature %s..." asc-download-path)
+ (epg-verify-file context asc-download-path download-path)
+ (setq signature (car (epg-context-result-for context 'verify)))
+ (unless (and
+ (eq (epg-signature-status signature) 'good)
+ (equal (epg-signature-fingerprint signature) fingerprint))
+ (error "Failed to verify GPG signature: %s" (epg-signature-to-string signature))))
+ (lsp--warn "GPG is not installed, skipping the signature check.")))
+ (when decompress
+ (lsp--info "Decompressing %s..." download-path)
+ (pcase decompress
+ (:gzip
+ (lsp-gunzip download-path))
+ (:zip (lsp-unzip download-path (f-parent store-path))))
+ (lsp--info "Decompressed %s..." store-path))
+ (funcall callback))
+ (error (funcall error-callback err)))))))
+
+(cl-defun lsp-download-path (&key store-path binary-path set-executable? &allow-other-keys)
+ "Download URL and store it into STORE-PATH.
+
+SET-EXECUTABLE? when non-nil change the executable flags of
+STORE-PATH to make it executable. BINARY-PATH can be specified
+when the binary to start does not match the name of the
+archieve(e. g. when the archieve has multiple files)"
+ (let ((store-path (or (lsp-resolve-value binary-path)
+ (lsp-resolve-value store-path))))
+ (cond
+ ((executable-find store-path) store-path)
+ ((and set-executable? (f-exists? store-path))
+ (set-file-modes store-path #o0700)
+ store-path)
+ ((f-exists? store-path) store-path))))
+
+;; unzip
+
+(defconst lsp-ext-pwsh-script "powershell -noprofile -noninteractive \
+-nologo -ex bypass Expand-Archive -path '%s' -dest '%s'"
+ "Powershell script to unzip file.")
+
+(defconst lsp-ext-unzip-script "bash -c 'mkdir -p %2$s && unzip -qq -o %1$s -d %2$s'"
+ "Unzip script to unzip file.")
+
+(defcustom lsp-unzip-script (cond ((executable-find "powershell") lsp-ext-pwsh-script)
+ ((executable-find "unzip") lsp-ext-unzip-script)
+ (t nil))
+ "The script to unzip."
+ :group 'lsp-mode
+ :type 'string
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defun lsp-unzip (zip-file dest)
+ "Unzip ZIP-FILE to DEST."
+ (unless lsp-unzip-script
+ (error "Unable to find `unzip' or `powershell' on the path, please customize `lsp-unzip-script'"))
+ (shell-command (format lsp-unzip-script zip-file dest)))
+
+;; gunzip
+
+(defconst lsp-ext-gunzip-script "gzip -d %1$s"
+ "Script to decompress a gzippped file with gzip.")
+
+(defcustom lsp-gunzip-script (cond ((executable-find "gzip") lsp-ext-gunzip-script)
+ (t nil))
+ "The script to decompress a gzipped file.
+Should be a format string with one argument for the file to be decompressed
+in place."
+ :group 'lsp-mode
+ :type 'string
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defun lsp-gunzip (gz-file)
+ "Decompress GZ-FILE in place."
+ (unless lsp-gunzip-script
+ (error "Unable to find `gzip' on the path, please either customize `lsp-gunzip-script' or manually decompress %s" gz-file))
+ (shell-command (format lsp-gunzip-script gz-file)))
+
+;; VSCode marketplace
+
+(defcustom lsp-vscode-ext-url
+ "https://marketplace.visualstudio.com/_apis/public/gallery/publishers/%s/vsextensions/%s/%s/vspackage"
+ "Vscode extension template url."
+ :group 'lsp-mode
+ :type 'string
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defun lsp-vscode-extension-url (publisher name &optional version)
+ "Return the URL to vscode extension.
+PUBLISHER is the extension publisher.
+NAME is the name of the extension.
+VERSION is the version of the extension, defaults to `latest'"
+ (format lsp-vscode-ext-url publisher name (or version "latest")))
+
+
+
+;; Queueing prompts
+
+(defvar lsp--question-queue nil
+ "List of questions yet to be asked by `lsp-ask-question'.")
+
+(defun lsp-ask-question (question options callback)
+ "Prompt the user to answer the QUESTION with one of the OPTIONS from the
+minibuffer. Once the user selects an option, the CALLBACK function will be
+called, passing the selected option to it.
+
+If the user is currently being shown a question, the question will be stored in
+`lsp--question-queue', and will be asked once the user has answered the current
+question."
+ (add-to-list 'lsp--question-queue `(("question" . ,question)
+ ("options" . ,options)
+ ("callback" . ,callback)) t)
+ (when (eq (length lsp--question-queue) 1)
+ (lsp--process-question-queue)))
+
+(defun lsp--process-question-queue ()
+ "Take the first question from `lsp--question-queue', process it, then process
+the next question until the queue is empty."
+ (-let* (((&alist "question" "options" "callback") (car lsp--question-queue))
+ (answer (completing-read question options nil t)))
+ (pop lsp--question-queue)
+ (funcall callback answer)
+ (when lsp--question-queue
+ (lsp--process-question-queue))))
+
+(defun lsp--supports-buffer? (client)
+ (and
+ ;; both file and client remote or both local
+ (eq (---truthy? (file-remote-p (buffer-file-name)))
+ (---truthy? (lsp--client-remote? client)))
+
+ ;; activation function or major-mode match.
+ (if-let ((activation-fn (lsp--client-activation-fn client)))
+ (funcall activation-fn (buffer-file-name) major-mode)
+ (-contains? (lsp--client-major-modes client) major-mode))
+
+ ;; check whether it is enabled if `lsp-enabled-clients' is not null
+ (or (null lsp-enabled-clients)
+ (or (member (lsp--client-server-id client) lsp-enabled-clients)
+ (ignore (lsp--info "Client %s is not in lsp-enabled-clients"
+ (lsp--client-server-id client)))))
+
+ ;; check whether it is not disabled.
+ (not (lsp--client-disabled-p major-mode (lsp--client-server-id client)))))
+
+(defun lsp--filter-clients (pred)
+ (->> lsp-clients hash-table-values (-filter pred)))
+
+(defun lsp--find-clients ()
+ "Find clients which can handle BUFFER-MAJOR-MODE.
+SESSION is the currently active session. The function will also
+pick only remote enabled clients in case the FILE-NAME is on
+remote machine and vice versa."
+ (-when-let (matching-clients (lsp--filter-clients (-andfn #'lsp--supports-buffer?
+ #'lsp--server-binary-present?)))
+ (lsp-log "Found the following clients for %s: %s"
+ (buffer-file-name)
+ (s-join ", "
+ (-map (lambda (client)
+ (format "(server-id %s, priority %s)"
+ (lsp--client-server-id client)
+ (lsp--client-priority client)))
+ matching-clients)))
+ (-let* (((add-on-clients main-clients) (-separate #'lsp--client-add-on? matching-clients))
+ (selected-clients (if-let ((main-client (and main-clients
+ (--max-by (> (lsp--client-priority it)
+ (lsp--client-priority other))
+ main-clients))))
+ (cons main-client add-on-clients)
+ add-on-clients)))
+ (lsp-log "The following clients were selected based on priority: %s"
+ (s-join ", "
+ (-map (lambda (client)
+ (format "(server-id %s, priority %s)"
+ (lsp--client-server-id client)
+ (lsp--client-priority client)))
+ selected-clients)))
+ selected-clients)))
+
+(defun lsp-register-client (client)
+ "Registers LSP client CLIENT."
+ (cl-assert (symbolp (lsp--client-server-id client)) t)
+ (cl-assert (or
+ (functionp (lsp--client-activation-fn client))
+ (and (listp (lsp--client-major-modes client))
+ (seq-every-p (apply-partially #'symbolp)
+ (lsp--client-major-modes client))))
+ nil "Invalid activation-fn and/or major-modes.")
+ (let ((client-id (lsp--client-server-id client)))
+ (puthash client-id client lsp-clients)
+ (setplist (intern (format "lsp-%s-after-open-hook" client-id))
+ `( standard-value (nil) custom-type hook
+ custom-package-version (lsp-mode . "7.0.1")
+ variable-documentation ,(format "Hooks to run after `%s' server is run." client-id)
+ custom-requests nil))))
+
+(defun lsp--create-initialization-options (_session client)
+ "Create initialization-options from SESSION and CLIENT.
+Add workspace folders depending on server being multiroot and
+session workspace folder configuration for the server."
+ (let* ((initialization-options-or-fn (lsp--client-initialization-options client)))
+ (if (functionp initialization-options-or-fn)
+ (funcall initialization-options-or-fn)
+ initialization-options-or-fn)))
+
+(defvar lsp-client-settings nil
+ "For internal use, any external users please use
+ `lsp-register-custom-settings' function instead")
+
+(defun lsp--compare-setting-path (a b)
+ (equal (car a) (car b)))
+
+(defun lsp-register-custom-settings (props)
+ "Register PROPS.
+PROPS is list of triple (path value boolean?) where PATH is the path to the
+property; VALUE can be a literal value, symbol to be evaluated, or either a
+function or lambda function to be called without arguments; BOOLEAN? is an
+optional flag that should be non-nil for boolean settings, when it is nil the
+property will be ignored if the VALUE is nil.
+
+Example: `(lsp-register-custom-settings '((\"foo.bar.buzz.enabled\" t t)))'
+\(note the double parentheses)"
+ (let ((-compare-fn #'lsp--compare-setting-path))
+ (setq lsp-client-settings (-uniq (append props lsp-client-settings)))))
+
+(defun lsp-region-text (region)
+ "Get the text for REGION in current buffer."
+ (-let (((start . end) (lsp--range-to-region region)))
+ (buffer-substring-no-properties start end)))
+
+(defun lsp-ht-set (tbl paths value)
+ "Set nested hash table value.
+TBL - a hash table, PATHS is the path to the nested VALUE."
+ (pcase paths
+ (`(,path) (ht-set! tbl path value))
+ (`(,path . ,rst) (let ((nested-tbl (or (gethash path tbl)
+ (let ((temp-tbl (ht)))
+ (ht-set! tbl path temp-tbl)
+ temp-tbl))))
+ (lsp-ht-set nested-tbl rst value)))))
+
+;; sections
+
+(defmacro defcustom-lsp (symbol standard doc &rest args)
+ "Defines `lsp-mode' server property."
+ (let ((path (plist-get args :lsp-path)))
+ (cl-remf args :lsp-path)
+ `(progn
+ (lsp-register-custom-settings
+ (quote ((,path ,symbol ,(equal ''boolean (plist-get args :type))))))
+
+ (defcustom ,symbol ,standard ,doc
+ :set (lambda (sym val)
+ (lsp--set-custom-property sym val ,path))
+ ,@args))))
+
+(defun lsp--set-custom-property (sym val path)
+ (set sym val)
+ (let ((section (cl-first (s-split "\\." path))))
+ (mapc (lambda (workspace)
+ (when (-contains? (lsp--client-synchronize-sections (lsp--workspace-client workspace))
+ section)
+ (with-lsp-workspace workspace
+ (lsp--set-configuration (lsp-configuration-section section)))))
+ (lsp--session-workspaces (lsp-session)))))
+
+(defun lsp-configuration-section (section)
+ "Get settings for SECTION."
+ (let ((ret (ht-create)))
+ (mapc (-lambda ((path variable boolean?))
+ (when (s-matches? (concat (regexp-quote section) "\\..*") path)
+ (let* ((symbol-value (-> variable
+ lsp-resolve-value
+ lsp-resolve-value))
+ (value (if (and boolean? (not symbol-value))
+ :json-false
+ symbol-value)))
+ (when (or boolean? value)
+ (lsp-ht-set ret (s-split "\\." path) value)))))
+ lsp-client-settings)
+ ret))
+
+
+(defun lsp--start-connection (session client project-root)
+ "Initiates connection created from CLIENT for PROJECT-ROOT.
+SESSION is the active session."
+ (when (lsp--client-multi-root client)
+ (cl-pushnew project-root (gethash (lsp--client-server-id client)
+ (lsp-session-server-id->folders session))))
+ (run-hook-with-args 'lsp-workspace-folders-changed-functions (list project-root) nil)
+
+ (unwind-protect
+ (lsp--start-workspace session client project-root (lsp--create-initialization-options session client))
+ (lsp--spinner-stop)))
+
+;; lsp-log-io-mode
+
+(defvar lsp-log-io-mode-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map (kbd "M-n") #'lsp-log-io-next)
+ (define-key map (kbd "M-p") #'lsp-log-io-prev)
+ (define-key map (kbd "k") #'lsp--erase-log-buffer)
+ (define-key map (kbd "K") #'lsp--erase-session-log-buffers)
+ map)
+ "Keymap for lsp log buffer mode.")
+
+(define-derived-mode lsp-log-io-mode special-mode "LspLogIo"
+ "Special mode for viewing IO logs.")
+
+(defun lsp-workspace-show-log (workspace)
+ "Display the log buffer of WORKSPACE."
+ (interactive
+ (list (if lsp-log-io
+ (if (eq (length (lsp-workspaces)) 1)
+ (cl-first (lsp-workspaces))
+ (lsp--completing-read "Workspace: " (lsp-workspaces)
+ #'lsp--workspace-print nil t))
+ (user-error "IO logging is disabled"))))
+ (pop-to-buffer (lsp--get-log-buffer-create workspace)))
+
+(defalias 'lsp-switch-to-io-log-buffer 'lsp-workspace-show-log)
+
+(defun lsp--get-log-buffer-create (workspace)
+ "Return the lsp log buffer of WORKSPACE, creating a new one if needed."
+ (let ((server-id (-> workspace lsp--workspace-client lsp--client-server-id symbol-name))
+ (pid (format "%s" (process-id (lsp--workspace-cmd-proc workspace)))))
+ (get-buffer-create (format "*lsp-log: %s:%s*" server-id pid))))
+
+(defun lsp--erase-log-buffer (&optional all)
+ "Delete contents of current lsp log buffer.
+When ALL is t, erase all log buffers of the running session."
+ (interactive)
+ (let* ((workspaces (lsp--session-workspaces (lsp-session)))
+ (current-log-buffer (current-buffer)))
+ (dolist (w workspaces)
+ (let ((b (lsp--get-log-buffer-create w)))
+ (when (or all (eq b current-log-buffer))
+ (with-current-buffer b
+ (let ((inhibit-read-only t))
+ (erase-buffer))))))))
+
+(defun lsp--erase-session-log-buffers ()
+ "Erase log buffers of the running session."
+ (interactive)
+ (lsp--erase-log-buffer t))
+
+(defun lsp-log-io-next (arg)
+ "Move to next log entry."
+ (interactive "P")
+ (ewoc-goto-next lsp--log-io-ewoc (or arg 1)))
+
+(defun lsp-log-io-prev (arg)
+ "Move to previous log entry."
+ (interactive "P")
+ (ewoc-goto-prev lsp--log-io-ewoc (or arg 1)))
+
+(defun lsp--workspace-print (workspace)
+ "Visual representation WORKSPACE."
+ (let* ((proc (lsp--workspace-cmd-proc workspace))
+ (status (lsp--workspace-status workspace))
+ (server-id (-> workspace lsp--workspace-client lsp--client-server-id symbol-name))
+ (pid (process-id proc)))
+
+ (if (eq 'initialized status)
+ (format "%s:%s" server-id pid)
+ (format "%s:%s/%s" server-id pid status))))
+
+(defun lsp--map-tree-widget (m)
+ "Build `tree-widget' from a hash-table M."
+ (when (hash-table-p m)
+ (let (nodes)
+ (maphash (lambda (k v)
+ (push `(tree-widget
+ :tag ,(if (hash-table-p v)
+ (format "%s:" k)
+ (format "%s: %s" k
+ (propertize (format "%s" v)
+ 'face
+ 'font-lock-string-face)))
+ :open t
+ ,@(lsp--map-tree-widget v))
+ nodes))
+ m)
+ nodes)))
+
+(defun lsp-buffer-name (buffer-id)
+ (if-let ((buffer-name (plist-get buffer-id :buffer-name)))
+ (funcall buffer-name buffer-id)
+ (buffer-name buffer-id)))
+
+(defun lsp--render-workspace (workspace)
+ "Tree node representation of WORKSPACE."
+ `(tree-widget :tag ,(lsp--workspace-print workspace)
+ :open t
+ (tree-widget :tag ,(propertize "Buffers" 'face 'font-lock-function-name-face)
+ :open t
+ ,@(->> workspace
+ (lsp--workspace-buffers)
+ (--map `(tree-widget
+ :tag ,(when (lsp-buffer-live-p it)
+ (let ((buffer-name (lsp-buffer-name it)))
+ (if (lsp-with-current-buffer it buffer-read-only)
+ (propertize buffer-name 'face 'font-lock-constant-face)
+ buffer-name)))))))
+ (tree-widget :tag ,(propertize "Capabilities" 'face 'font-lock-function-name-face)
+ ,@(-> workspace lsp--workspace-server-capabilities lsp--map-tree-widget))))
+
+(define-derived-mode lsp-browser-mode special-mode "LspBrowser"
+ "Define mode for displaying lsp sessions."
+ (setq-local display-buffer-base-action '(nil . ((inhibit-same-window . t)))))
+
+(defun lsp-describe-session ()
+ "Describes current `lsp-session'."
+ (interactive)
+ (let ((session (lsp-session))
+ (buf (get-buffer-create "*lsp session*")))
+ (with-current-buffer buf
+ (lsp-browser-mode)
+ (let ((inhibit-read-only t))
+ (erase-buffer)
+ (--each (lsp-session-folders session)
+ (widget-create
+ `(tree-widget
+ :tag ,(propertize it 'face 'font-lock-keyword-face)
+ :open t
+ ,@(->> session
+ (lsp-session-folder->servers)
+ (gethash it)
+ (-map 'lsp--render-workspace)))))))
+ (pop-to-buffer buf)))
+
+(defun lsp--session-workspaces (session)
+ "Get all workspaces that are part of the SESSION."
+ (-> session lsp-session-folder->servers hash-table-values -flatten -uniq))
+
+(defun lsp--find-multiroot-workspace (session client project-root)
+ "Look for a multiroot connection in SESSION created from CLIENT for PROJECT-ROOT and BUFFER-MAJOR-MODE."
+ (when (lsp--client-multi-root client)
+ (-when-let (multi-root-workspace (->> session
+ (lsp--session-workspaces)
+ (--first (eq (-> it lsp--workspace-client lsp--client-server-id)
+ (lsp--client-server-id client)))))
+ (with-lsp-workspace multi-root-workspace
+ (lsp-notify "workspace/didChangeWorkspaceFolders"
+ (lsp-make-did-change-workspace-folders-params
+ :event (lsp-make-workspace-folders-change-event
+ :added (vector (lsp-make-workspace-folder
+ :uri (lsp--path-to-uri project-root)
+ :name (f-filename project-root)))
+ :removed []))))
+
+ (->> session (lsp-session-folder->servers) (gethash project-root) (cl-pushnew multi-root-workspace))
+ (->> session (lsp-session-server-id->folders) (gethash (lsp--client-server-id client)) (cl-pushnew project-root))
+
+ (lsp--persist-session session)
+
+ (lsp--info "Opened folder %s in workspace %s" project-root (lsp--workspace-print multi-root-workspace))
+ (lsp--open-in-workspace multi-root-workspace)
+
+ multi-root-workspace)))
+
+(defun lsp--ensure-lsp-servers (session clients project-root ignore-multi-folder)
+ "Ensure that SESSION contain server CLIENTS created for PROJECT-ROOT.
+IGNORE-MULTI-FOLDER to ignore multi folder server."
+ (-map (lambda (client)
+ (or
+ (lsp--find-workspace session client project-root)
+ (unless ignore-multi-folder
+ (lsp--find-multiroot-workspace session client project-root))
+ (lsp--start-connection session client project-root)))
+ clients))
+
+(defun lsp--spinner-stop ()
+ "Stop the spinner in case all of the workspaces are started."
+ (when (--all? (eq (lsp--workspace-status it) 'initialized)
+ lsp--buffer-workspaces)
+ (spinner-stop)))
+
+(defun lsp--open-in-workspace (workspace)
+ "Open in existing WORKSPACE."
+ (if (eq 'initialized (lsp--workspace-status workspace))
+ ;; when workspace is initialized just call document did open.
+ (progn
+ (with-lsp-workspace workspace
+ (when-let ((before-document-open-fn (-> workspace
+ lsp--workspace-client
+ lsp--client-before-file-open-fn)))
+ (funcall before-document-open-fn workspace))
+ (lsp--text-document-did-open))
+ (lsp--spinner-stop))
+ ;; when it is not initialized
+ (lsp--spinner-start)
+ (cl-pushnew (lsp-current-buffer) (lsp--workspace-buffers workspace))))
+
+(defun lsp--find-workspace (session client project-root)
+ "Find server connection created with CLIENT in SESSION for PROJECT-ROOT."
+ (when-let ((workspace (->> session
+ (lsp-session-folder->servers)
+ (gethash project-root)
+ (--first (eql (-> it lsp--workspace-client lsp--client-server-id)
+ (lsp--client-server-id client))))))
+ (lsp--open-in-workspace workspace)
+ workspace))
+
+(defun lsp--read-char (prompt &optional options)
+ "Wrapper for `read-char-from-minibuffer' if Emacs +27.
+Fallback to `read-key' otherwise.
+PROMPT is the message and OPTIONS the available options."
+ (if (fboundp 'read-char-from-minibuffer)
+ (read-char-from-minibuffer prompt options)
+ (read-key prompt)))
+
+(defun lsp--find-root-interactively (session)
+ "Find project interactively.
+Returns nil if the project should not be added to the current SESSION."
+ (condition-case nil
+ (let* ((project-root-suggestion (or (lsp--suggest-project-root) default-directory))
+ (action (lsp--read-char
+ (format
+ "%s is not part of any project.
+
+%s ==> Import project root %s
+%s ==> Import project by selecting root directory interactively
+%s ==> Import project at current directory %s
+%s ==> Do not ask again for the current project by adding %s to lsp-session-folders-blacklist
+%s ==> Do not ask again for the current project by selecting ignore path interactively
+%s ==> Do nothing: ask again when opening other files from the current project
+
+Select action: "
+ (propertize (buffer-name) 'face 'bold)
+ (propertize "i" 'face 'success)
+ (propertize project-root-suggestion 'face 'bold)
+ (propertize "I" 'face 'success)
+ (propertize "." 'face 'success)
+ (propertize default-directory 'face 'bold)
+ (propertize "d" 'face 'warning)
+ (propertize project-root-suggestion 'face 'bold)
+ (propertize "D" 'face 'warning)
+ (propertize "n" 'face 'warning))
+ '(?i ?\r ?I ?. ?d ?D ?n))))
+ (cl-case action
+ (?i project-root-suggestion)
+ (?\r project-root-suggestion)
+ (?I (read-directory-name "Select workspace folder to add: "
+ (or project-root-suggestion default-directory)
+ nil
+ t))
+ (?. default-directory)
+ (?d (push project-root-suggestion (lsp-session-folders-blacklist session))
+ (lsp--persist-session session)
+ nil)
+ (?D (push (read-directory-name "Select folder to blacklist: "
+ (or project-root-suggestion default-directory)
+ nil
+ t)
+ (lsp-session-folders-blacklist session))
+ (lsp--persist-session session)
+ nil)
+ (t nil)))
+ ('quit)))
+
+(declare-function tramp-file-name-host "ext:tramp" (file) t)
+(declare-function tramp-dissect-file-name "ext:tramp" (file &optional nodefault))
+
+(defun lsp--files-same-host (f1 f2)
+ "Predicate on whether or not two files are on the same host."
+ (or (not (or (file-remote-p f1) (file-remote-p f2)))
+ (and (file-remote-p f1)
+ (file-remote-p f2)
+ (progn (require 'tramp)
+ (equal (tramp-file-name-host (tramp-dissect-file-name f1))
+ (tramp-file-name-host (tramp-dissect-file-name f2)))))))
+
+(defun lsp-find-session-folder (session file-name)
+ "Look in the current SESSION for folder containing FILE-NAME."
+ (let ((file-name-canonical (lsp-f-canonical file-name)))
+ (->> session
+ (lsp-session-folders)
+ (--filter (and (lsp--files-same-host it file-name-canonical)
+ (or (lsp-f-same? it file-name-canonical)
+ (and (f-dir? it)
+ (lsp-f-ancestor-of? it file-name-canonical)))))
+ (--max-by (> (length it)
+ (length other))))))
+
+(defun lsp-find-workspace (server-id &optional file-name)
+ "Find workspace for SERVER-ID for FILE-NAME."
+ (-when-let* ((session (lsp-session))
+ (folder->servers (lsp-session-folder->servers session))
+ (workspaces (if file-name
+ (gethash (lsp-find-session-folder session file-name) folder->servers)
+ (lsp--session-workspaces session))))
+
+ (--first (eq (lsp--client-server-id (lsp--workspace-client it)) server-id) workspaces)))
+
+(defun lsp--calculate-root (session file-name)
+ "Calculate project root for FILE-NAME in SESSION."
+ (and
+ (->> session
+ (lsp-session-folders-blacklist)
+ (--first (and (lsp--files-same-host it file-name)
+ (lsp-f-ancestor-of? it file-name)
+ (prog1 t
+ (lsp--info "File %s is in blacklisted directory %s" file-name it))))
+ not)
+ (or
+ (when lsp-auto-guess-root
+ (lsp--suggest-project-root))
+ (lsp-find-session-folder session file-name)
+ (unless lsp-auto-guess-root
+ (when-let ((root-folder (lsp--find-root-interactively session)))
+ (if (or (not (f-equal? root-folder (expand-file-name "~/")))
+ (yes-or-no-p
+ (concat
+ (propertize "[WARNING] " 'face 'warning)
+ "You are trying to import your home folder as project root. This may cause performance issue because some language servers (python, lua, etc) will try to scan all files under project root. To avoid that you may:
+
+1. Use `I' option from the interactive project import to select subfolder(e. g. `~/foo/bar' instead of `~/').
+2. If your file is under `~/' then create a subfolder and move that file in this folder.
+
+Type `No' to go back to project selection.
+Type `Yes' to confirm `HOME' as project root.
+Type `C-g' to cancel project import process and stop `lsp'")))
+ root-folder
+ (lsp--calculate-root session file-name)))))))
+
+(defun lsp--try-open-in-library-workspace ()
+ "Try opening current file as library file in any of the active workspace.
+The library folders are defined by each client for each of the active workspace."
+ (when-let ((workspace (->> (lsp-session)
+ (lsp--session-workspaces)
+ ;; Sort the last active workspaces first as they are more likely to be
+ ;; the correct ones, especially when jumping to a definition.
+ (-sort (lambda (a _b)
+ (-contains? lsp--last-active-workspaces a)))
+ (--first
+ (and (-> it lsp--workspace-client lsp--supports-buffer?)
+ (when-let ((library-folders-fn
+ (-> it lsp--workspace-client lsp--client-library-folders-fn)))
+ (-first (lambda (library-folder)
+ (lsp-f-ancestor-of? library-folder (buffer-file-name)))
+ (funcall library-folders-fn it))))))))
+ (lsp--open-in-workspace workspace)
+ (view-mode t)
+ (lsp--info "Opening read-only library file %s." (buffer-file-name))
+ (list workspace)))
+
+(defun lsp--persist-session (session)
+ "Persist SESSION to `lsp-session-file'."
+ (lsp--persist lsp-session-file (make-lsp-session
+ :folders (lsp-session-folders session)
+ :folders-blacklist (lsp-session-folders-blacklist session)
+ :server-id->folders (lsp-session-server-id->folders session))))
+
+(defun lsp--try-project-root-workspaces (ask-for-client ignore-multi-folder)
+ "Try create opening file as a project file.
+When IGNORE-MULTI-FOLDER is t the lsp mode will start new
+language server even if there is language server which can handle
+current language. When IGNORE-MULTI-FOLDER is nil current file
+will be opened in multi folder language server if there is
+such."
+ (-let ((session (lsp-session)))
+ (-if-let (clients (if ask-for-client
+ (list (lsp--completing-read "Select server to start: "
+ (ht-values lsp-clients)
+ (-compose 'symbol-name 'lsp--client-server-id) nil t))
+ (lsp--find-clients)))
+ (-if-let (project-root (-some-> session
+ (lsp--calculate-root (buffer-file-name))
+ (lsp-f-canonical)))
+ (progn
+ ;; update project roots if needed and persist the lsp session
+ (unless (-contains? (lsp-session-folders session) project-root)
+ (cl-pushnew project-root (lsp-session-folders session))
+ (lsp--persist-session session))
+ (lsp--ensure-lsp-servers session clients project-root ignore-multi-folder))
+ (lsp--warn "%s not in project or it is blacklisted." (buffer-name))
+ nil)
+ (lsp--warn "No LSP server for %s(check *lsp-log*)." major-mode)
+ nil)))
+
+(defun lsp-shutdown-workspace ()
+ "Shutdown language server."
+ (interactive)
+ (--when-let (pcase (lsp-workspaces)
+ (`nil (user-error "There are no active servers in the current buffer"))
+ (`(,workspace) (when (y-or-n-p (format "Are you sure you want to stop the server %s?"
+ (lsp--workspace-print workspace)))
+ workspace))
+ (workspaces (lsp--completing-read "Select server: "
+ workspaces
+ 'lsp--workspace-print nil t)))
+ (lsp-workspace-shutdown it)))
+
+(make-obsolete 'lsp-shutdown-workspace 'lsp-workspace-shutdown "lsp-mode 6.1")
+
+(defcustom lsp-auto-select-workspace t
+ "Shutdown or restart a single workspace.
+If set and the current buffer has only a single workspace
+associated with it, `lsp-shutdown-workspace' and
+`lsp-restart-workspace' will act on it without asking."
+ :type 'boolean
+ :group 'lsp-mode)
+
+(defun lsp--read-workspace ()
+ "Ask the user to select a workspace.
+Errors if there are none."
+ (pcase (lsp-workspaces)
+ (`nil (error "No workspaces associated with the current buffer"))
+ ((and `(,workspace) (guard lsp-auto-select-workspace)) workspace)
+ (workspaces (lsp--completing-read "Select workspace: " workspaces
+ #'lsp--workspace-print nil t))))
+
+(defun lsp-workspace-shutdown (workspace)
+ "Shut the workspace WORKSPACE and the language server associated with it"
+ (interactive (list (lsp--read-workspace)))
+ (lsp--warn "Stopping %s" (lsp--workspace-print workspace))
+ (with-lsp-workspace workspace (lsp--shutdown-workspace)))
+
+(defun lsp-disconnect ()
+ "Disconnect the buffer from the language server."
+ (interactive)
+ (lsp--text-document-did-close t)
+ (lsp-managed-mode -1)
+ (lsp-mode -1)
+ (setq lsp--buffer-workspaces nil)
+ (lsp--info "Disconnected"))
+
+(defun lsp-restart-workspace ()
+ (interactive)
+ (--when-let (pcase (lsp-workspaces)
+ (`nil (user-error "There are no active servers in the current buffer"))
+ (`(,workspace) workspace)
+ (workspaces (lsp--completing-read "Select server: "
+ workspaces
+ 'lsp--workspace-print nil t)))
+ (lsp-workspace-restart it)))
+
+(make-obsolete 'lsp-restart-workspace 'lsp-workspace-restart "lsp-mode 6.1")
+
+(defun lsp-workspace-restart (workspace)
+ "Restart the workspace WORKSPACE and the language server associated with it"
+ (interactive (list (lsp--read-workspace)))
+ (lsp--warn "Restarting %s" (lsp--workspace-print workspace))
+ (with-lsp-workspace workspace (lsp--shutdown-workspace t)))
+
+;;;###autoload
+(defun lsp (&optional arg)
+ "Entry point for the server startup.
+When ARG is t the lsp mode will start new language server even if
+there is language server which can handle current language. When
+ARG is nil current file will be opened in multi folder language
+server if there is such. When `lsp' is called with prefix
+argument ask the user to select which language server to start."
+ (interactive "P")
+
+ (lsp--require-packages)
+
+ (when (buffer-file-name)
+ (let (clients
+ (matching-clients (lsp--filter-clients
+ (-andfn #'lsp--supports-buffer?
+ #'lsp--server-binary-present?))))
+ (cond
+ (matching-clients
+ (when (setq lsp--buffer-workspaces
+ (or (and
+ ;; Don't open as library file if file is part of a project.
+ (not (lsp-find-session-folder (lsp-session) (buffer-file-name)))
+ (lsp--try-open-in-library-workspace))
+ (lsp--try-project-root-workspaces (equal arg '(4))
+ (and arg (not (equal arg 1))))))
+ (lsp-mode 1)
+ (when lsp-auto-configure (lsp--auto-configure))
+ (setq lsp-buffer-uri (lsp--buffer-uri))
+ (lsp--info "Connected to %s."
+ (apply 'concat (--map (format "[%s]" (lsp--workspace-print it))
+ lsp--buffer-workspaces)))))
+ ;; look for servers which are currently being downloaded.
+ ((setq clients (lsp--filter-clients (-andfn #'lsp--supports-buffer?
+ #'lsp--client-download-in-progress?)))
+ (lsp--info "There are language server(%s) installation in progress.
+The server(s) will be started in the buffer when it has finished."
+ (-map #'lsp--client-server-id clients))
+ (seq-do (lambda (client)
+ (cl-pushnew (current-buffer) (lsp--client-buffers client)))
+ clients))
+ ;; look for servers to install
+ ((setq clients (lsp--filter-clients
+ (-andfn #'lsp--supports-buffer?
+ (-const lsp-enable-suggest-server-download)
+ #'lsp--client-download-server-fn
+ (-not #'lsp--client-download-in-progress?))))
+ (let ((client (lsp--completing-read
+ (concat "Unable to find installed server supporting this file. "
+ "The following servers could be installed automatically: ")
+ clients
+ (-compose #'symbol-name #'lsp--client-server-id)
+ nil
+ t)))
+ (cl-pushnew (current-buffer) (lsp--client-buffers client))
+ (lsp--install-server-internal client)))
+ ;; automatic installation disabled
+ ((setq clients (unless matching-clients
+ (lsp--filter-clients (-andfn #'lsp--supports-buffer?
+ #'lsp--client-download-server-fn
+ (-not (-const lsp-enable-suggest-server-download))
+ (-not #'lsp--server-binary-present?)))))
+ (lsp--warn "The following servers support current file but automatic download is disabled: %s
+\(If you have already installed the server check *lsp-log*)."
+ (mapconcat (lambda (client)
+ (symbol-name (lsp--client-server-id client)))
+ clients
+ " ")))
+ ;; no clients present
+ ((setq clients (unless matching-clients
+ (lsp--filter-clients (-andfn #'lsp--supports-buffer?
+ (-not #'lsp--server-binary-present?)))))
+ (lsp--warn "The following servers support current file but do not have automatic installation: %s
+You may find the installation instructions at https://emacs-lsp.github.io/lsp-mode/page/languages.
+\(If you have already installed the server check *lsp-log*)."
+ (mapconcat (lambda (client)
+ (symbol-name (lsp--client-server-id client)))
+ clients
+ " ")))
+ ;; no matches
+ ((-> #'lsp--supports-buffer? lsp--filter-clients not)
+ (lsp--error "There are no language servers supporting current mode `%s' registered with `lsp-mode'.
+This issue might be caused by:
+1. The language you are trying to use does not have built-in support in `lsp-mode'. You must install the required support manually. Examples of this are `lsp-java' or `lsp-metals'.
+2. The language server that you expect to run is not configured to run for major mode `%s'. You may check that by checking the `:major-modes' that are passed to `lsp-register-client'.
+3. `lsp-mode' doesn't have any integration for the language behind `%s'. Refer to https://emacs-lsp.github.io/lsp-mode/page/languages and https://langserver.org/ .
+4. You are over `tramp'. In this case follow https://emacs-lsp.github.io/lsp-mode/page/remote/.
+5. You have disabled the `lsp-mode' clients for that file. (Check `lsp-enabled-clients' and `lsp-disabled-clients')."
+ major-mode major-mode major-mode))))))
+
+(defun lsp--buffer-visible-p ()
+ "Return non nil if current buffer is visible."
+ (or (buffer-modified-p) (get-buffer-window nil t)))
+
+(defun lsp--init-if-visible ()
+ "Run `lsp' for the current buffer if the buffer is visible.
+Returns non nil if `lsp' was run for the buffer."
+ (when (lsp--buffer-visible-p)
+ (remove-hook 'window-configuration-change-hook #'lsp--init-if-visible t)
+ (lsp)
+ t))
+
+;;;###autoload
+(defun lsp-deferred ()
+ "Entry point that defers server startup until buffer is visible.
+`lsp-deferred' will wait until the buffer is visible before invoking `lsp'.
+This avoids overloading the server with many files when starting Emacs."
+ ;; Workspace may not be initialized yet. Use a buffer local variable to
+ ;; remember that we deferred loading of this buffer.
+ (setq lsp--buffer-deferred t)
+ (let ((buffer (current-buffer)))
+ ;; Avoid false positives as desktop-mode restores buffers by deferring
+ ;; visibility check until the stack clears.
+ (run-with-idle-timer 0 nil (lambda ()
+ (when (buffer-live-p buffer)
+ (with-current-buffer buffer
+ (unless (lsp--init-if-visible)
+ (add-hook 'window-configuration-change-hook #'lsp--init-if-visible nil t))))))))
+
+
+
+(defvar lsp-file-truename-cache (ht))
+
+(defmacro lsp-with-cached-filetrue-name (&rest body)
+ "Executes BODY caching the `file-truename' calls."
+ `(let ((old-fn (symbol-function 'file-truename)))
+ (unwind-protect
+ (progn
+ (fset 'file-truename
+ (lambda (file-name &optional counter prev-dirs)
+ (or (gethash file-name lsp-file-truename-cache)
+ (puthash file-name (apply old-fn (list file-name counter prev-dirs))
+ lsp-file-truename-cache))))
+ ,@body)
+ (fset 'file-truename old-fn))))
+
+
+(defun lsp-virtual-buffer-call (key &rest args)
+ (when lsp--virtual-buffer
+ (when-let ((fn (plist-get lsp--virtual-buffer key)))
+ (apply fn args))))
+
+(defun lsp-translate-column (column)
+ "Translate COLUMN taking into account virtual buffers."
+ (or (lsp-virtual-buffer-call :real->virtual-char column)
+ column))
+
+(defun lsp-translate-line (line)
+ "Translate LINE taking into account virtual buffers."
+ (or (lsp-virtual-buffer-call :real->virtual-line line)
+ line))
+
+
+;; lsp internal validation.
+
+(defmacro lsp--doctor (&rest checks)
+ `(-let [buf (current-buffer)]
+ (with-current-buffer (get-buffer-create "*lsp-performance*")
+ (with-help-window (current-buffer)
+ ,@(-map (-lambda ((msg form))
+ `(insert (format "%s: %s\n" ,msg
+ (let ((res (with-current-buffer buf
+ ,form)))
+ (cond
+ ((eq res :optional) (propertize "OPTIONAL" 'face 'warning))
+ (res (propertize "OK" 'face 'success))
+ (t (propertize "ERROR" 'face 'error)))))))
+ (-partition 2 checks))))))
+
+(define-obsolete-function-alias 'lsp-diagnose
+ 'lsp-doctor "lsp-mode 8.0.0")
+
+(defun lsp-doctor ()
+ "Validate performance settings."
+ (interactive)
+ (lsp--doctor
+ "Checking for Native JSON support" (functionp 'json-serialize)
+ "Check emacs supports `read-process-output-max'" (boundp 'read-process-output-max)
+ "Check `read-process-output-max' default has been changed from 4k"
+ (and (boundp 'read-process-output-max)
+ (> read-process-output-max 4096))
+ "Byte compiled against Native JSON (recompile lsp-mode if failing when Native JSON available)"
+ (condition-case _err
+ (progn (lsp--make-message (list "a" "b"))
+ nil)
+ (error t))
+ "`gc-cons-threshold' increased?" (> gc-cons-threshold 800000)
+ "Using `plist' for deserialized objects? (refer to https://emacs-lsp.github.io/lsp-mode/page/performance/#use-plists-for-deserialization)" (or lsp-use-plists :optional)
+ "Using emacs 28+ with native compilation?"
+ (or (and (fboundp 'native-comp-available-p)
+ (native-comp-available-p))
+ :optional)))
+
+(declare-function package-version-join "ext:package")
+(declare-function package-desc-version "ext:package")
+(declare-function package--alist "ext:package")
+
+(defun lsp-version ()
+ "Return string describing current version of `lsp-mode'."
+ (interactive)
+ (unless (featurep 'package)
+ (require 'package))
+ (let ((ver (format "lsp-mode %s, Emacs %s, %s"
+ (package-version-join
+ (package-desc-version
+ (car (alist-get 'lsp-mode (package--alist)))))
+ emacs-version
+ system-type)))
+ (if (called-interactively-p 'interactive)
+ (lsp--info "%s" ver)
+ ver)))
+
+
+
+;; org-mode/virtual-buffer
+
+(declare-function org-babel-get-src-block-info "ext:ob-core")
+(declare-function org-do-remove-indentation "ext:org-macs")
+(declare-function org-src-get-lang-mode "ext:org-src")
+(declare-function org-element-context "ext:org-element")
+
+(defun lsp--virtual-buffer-update-position ()
+ (-if-let (virtual-buffer (-first (-lambda ((&plist :in-range))
+ (funcall in-range))
+ lsp--virtual-buffer-connections))
+ (unless (equal virtual-buffer lsp--virtual-buffer)
+ (lsp-org))
+ (when lsp-managed-mode
+ (lsp-managed-mode -1)
+ (lsp-mode -1)
+ (setq lsp--buffer-workspaces nil)
+ (setq lsp--virtual-buffer nil)
+ (setq lsp-buffer-uri nil)
+
+ ;; force refresh of diagnostics
+ (run-hooks 'lsp-after-diagnostics-hook))))
+
+(defun lsp-virtual-buffer-on-change (start end length)
+ "Adjust on change event to be executed against the proper language server."
+ (let ((max-point (max end
+ (or (plist-get lsp--before-change-vals :end) 0)
+ (+ start length))))
+ (when-let ((virtual-buffer (-first (lambda (vb)
+ (let ((lsp--virtual-buffer vb))
+ (and (lsp-virtual-buffer-call :in-range start)
+ (lsp-virtual-buffer-call :in-range max-point))))
+ lsp--virtual-buffer-connections)))
+ (lsp-with-current-buffer virtual-buffer
+ (lsp-on-change start end length
+ (lambda (&rest _)
+ (list :range (lsp--range (list :character 0 :line 0)
+ lsp--virtual-buffer-point-max)
+ :text (lsp--buffer-content))))))))
+
+(defun lsp-virtual-buffer-before-change (start _end)
+ (when-let ((virtual-buffer (-first (lambda (vb)
+ (lsp-with-current-buffer vb
+ (lsp-virtual-buffer-call :in-range start)))
+ lsp--virtual-buffer-connections)))
+ (lsp-with-current-buffer virtual-buffer
+ (setq lsp--virtual-buffer-point-max
+ (lsp--point-to-position (lsp-virtual-buffer-call :last-point))))))
+
+(defun lsp-patch-on-change-event ()
+ (remove-hook 'after-change-functions #'lsp-on-change t)
+ (add-hook 'after-change-functions #'lsp-virtual-buffer-on-change nil t)
+ (add-hook 'before-change-functions #'lsp-virtual-buffer-before-change nil t))
+
+(defun lsp-kill-virtual-buffers ()
+ (mapc #'lsp-virtual-buffer-disconnect lsp--virtual-buffer-connections))
+
+(defun lsp--move-point-in-indentation (point indentation)
+ (save-excursion
+ (goto-char point)
+ (if (<= point (+ (point-at-bol) indentation))
+ (point-at-bol)
+ point)))
+
+(declare-function flycheck-checker-supports-major-mode-p "ext:flycheck")
+(declare-function flycheck-add-mode "ext:flycheck")
+(declare-function lsp-diagnostics-lsp-checker-if-needed "lsp-diagnostics")
+
+(defalias 'lsp-client-download-server-fn 'lsp--client-download-server-fn)
+
+(defun lsp-flycheck-add-mode (mode)
+ "Register flycheck support for MODE."
+ (lsp-diagnostics-lsp-checker-if-needed)
+ (unless (flycheck-checker-supports-major-mode-p 'lsp mode)
+ (flycheck-add-mode 'lsp mode)))
+
+(defun lsp-org ()
+ (interactive)
+ (-if-let ((virtual-buffer &as &plist :workspaces) (-first (-lambda ((&plist :in-range))
+ (funcall in-range))
+ lsp--virtual-buffer-connections))
+ (unless (equal lsp--virtual-buffer virtual-buffer)
+ (setq lsp--buffer-workspaces workspaces)
+ (setq lsp--virtual-buffer virtual-buffer)
+ (setq lsp-buffer-uri nil)
+ (lsp-mode 1)
+ (lsp-managed-mode 1)
+ (lsp-patch-on-change-event))
+
+ (save-excursion
+ (-let* (virtual-buffer
+ (wcb (lambda (f)
+ (with-current-buffer (plist-get virtual-buffer :buffer)
+ (-let* (((&plist :major-mode :buffer-file-name
+ :goto-buffer :workspaces) virtual-buffer)
+ (lsp--virtual-buffer virtual-buffer)
+ (lsp--buffer-workspaces workspaces))
+ (save-excursion
+ (funcall goto-buffer)
+ (funcall f))))))
+ ((&plist :begin :end :post-blank :language) (cl-second (org-element-context)))
+ ((&alist :tangle file-name) (cl-third (org-babel-get-src-block-info 'light)))
+
+ (file-name (if file-name
+ (f-expand file-name)
+ (user-error "You should specify file name in the src block header.")))
+ (begin-marker (progn
+ (goto-char begin)
+ (forward-line)
+ (set-marker (make-marker) (point))))
+ (end-marker (progn
+ (goto-char end)
+ (forward-line (1- (- post-blank)))
+ (set-marker (make-marker) (1+ (point)))))
+ (buf (current-buffer))
+ (src-block (buffer-substring-no-properties begin-marker
+ (1- end-marker)))
+ (indentation (with-temp-buffer
+ (insert src-block)
+
+ (goto-char (point-min))
+ (let ((indentation (current-indentation)))
+ (plist-put lsp--virtual-buffer :indentation indentation)
+ (org-do-remove-indentation)
+ (goto-char (point-min))
+ (- indentation (current-indentation))))))
+ (add-hook 'post-command-hook #'lsp--virtual-buffer-update-position nil t)
+
+ (when (fboundp 'flycheck-add-mode)
+ (lsp-flycheck-add-mode 'org-mode))
+
+ (setq lsp--virtual-buffer
+ (list
+ :in-range (lambda (&optional point)
+ (<= begin-marker (or point (point)) (1- end-marker)))
+ :goto-buffer (lambda () (goto-char begin-marker))
+ :buffer-string
+ (lambda ()
+ (let ((src-block (buffer-substring-no-properties
+ begin-marker
+ (1- end-marker))))
+ (with-temp-buffer
+ (insert src-block)
+
+ (goto-char (point-min))
+ (while (not (eobp))
+ (delete-region (point) (if (> (+ (point) indentation) (point-at-eol))
+ (point-at-eol)
+ (+ (point) indentation)))
+ (forward-line))
+ (buffer-substring-no-properties (point-min)
+ (point-max)))))
+ :buffer buf
+ :begin begin-marker
+ :end end-marker
+ :indentation indentation
+ :last-point (lambda () (1- end-marker))
+ :cur-position (lambda ()
+ (lsp-save-restriction-and-excursion
+ (list :line (- (lsp--cur-line)
+ (lsp--cur-line begin-marker))
+ :character (let ((character (- (point)
+ (line-beginning-position)
+ indentation)))
+ (if (< character 0)
+ 0
+ character)))))
+ :line/character->point (-lambda (line character)
+ (-let [inhibit-field-text-motion t]
+ (+ indentation
+ (lsp-save-restriction-and-excursion
+ (goto-char begin-marker)
+ (forward-line line)
+ (-let [line-end (line-end-position)]
+ (if (> character (- line-end (point)))
+ line-end
+ (forward-char character)
+ (point)))))))
+ :major-mode (org-src-get-lang-mode language)
+ :buffer-file-name file-name
+ :buffer-uri (lsp--path-to-uri file-name)
+ :with-current-buffer wcb
+ :buffer-live? (lambda (_) (buffer-live-p buf))
+ :buffer-name (lambda (_)
+ (propertize (format "%s(%s:%s)%s"
+ (buffer-name buf)
+ begin-marker
+ end-marker
+ language)
+ 'face 'italic))
+ :real->virtual-line (lambda (line)
+ (+ line (line-number-at-pos begin-marker) -1))
+ :real->virtual-char (lambda (char) (+ char indentation))
+ :cleanup (lambda ()
+ (set-marker begin-marker nil)
+ (set-marker end-marker nil))))
+ (setf virtual-buffer lsp--virtual-buffer)
+ (puthash file-name virtual-buffer lsp--virtual-buffer-mappings)
+ (push virtual-buffer lsp--virtual-buffer-connections)
+
+ ;; TODO: tangle only connected sections
+ (add-hook 'after-save-hook 'org-babel-tangle nil t)
+ (add-hook 'lsp-after-open-hook #'lsp-patch-on-change-event nil t)
+ (add-hook 'kill-buffer-hook #'lsp-kill-virtual-buffers nil t)
+
+ (setq lsp--buffer-workspaces
+ (lsp-with-current-buffer virtual-buffer
+ (lsp)
+ (plist-put virtual-buffer :workspaces (lsp-workspaces))
+ (lsp-workspaces)))))))
+
+(defun lsp-virtual-buffer-disconnect (virtual-buffer)
+ (interactive (list (or
+ lsp--virtual-buffer
+ (when lsp--virtual-buffer-connections
+ (lsp--completing-read "Select virtual buffer to disconnect: "
+ lsp--virtual-buffer-connections
+ (-lambda ((&plist :buffer-file-name))
+ buffer-file-name))))))
+ (-if-let ((&plist :buffer-file-name file-name :cleanup) virtual-buffer)
+ (progn
+ (lsp-with-current-buffer virtual-buffer
+ (lsp--text-document-did-close))
+ (setq lsp--virtual-buffer-connections (-remove-item virtual-buffer lsp--virtual-buffer-connections))
+ (when (eq virtual-buffer lsp--virtual-buffer)
+ (setf lsp--virtual-buffer nil))
+ (when cleanup (funcall cleanup))
+ (remhash file-name lsp--virtual-buffer-mappings)
+
+ (lsp--virtual-buffer-update-position)
+ (lsp--info "Disconnected from buffer %s" file-name))
+ (lsp--error "Nothing to disconnect from?")))
+
+
+
+;;;###autoload
+(defun lsp-start-plain ()
+ "Start `lsp-mode' using mininal configuration using the latest `melpa' version of the packages.
+
+In case the major-mode that you are using for "
+ (interactive)
+ (let ((start-plain (make-temp-file "plain" nil ".el")))
+ (url-copy-file "https://raw.githubusercontent.com/emacs-lsp/lsp-mode/master/scripts/lsp-start-plain.el"
+ start-plain t)
+ (async-shell-command
+ (format "%s -q -l %s %s"
+ (expand-file-name invocation-name invocation-directory)
+ start-plain
+ (or (buffer-file-name) ""))
+ (generate-new-buffer " *lsp-start-plain*"))))
+
+
+
+(provide 'lsp-mode)
+;;; lsp-mode.el ends here
diff --git a/elpa/lsp-mode-20220505.630/lsp-mode.elc b/elpa/lsp-mode-20220505.630/lsp-mode.elc
new file mode 100644
index 0000000..278536b
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-mode.elc
Binary files differ
diff --git a/elpa/lsp-mode-20220505.630/lsp-modeline.el b/elpa/lsp-mode-20220505.630/lsp-modeline.el
new file mode 100644
index 0000000..9449f5c
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-modeline.el
@@ -0,0 +1,354 @@
+;;; lsp-modeline.el --- LSP modeline features -*- lexical-binding: t; -*-
+;;
+;; Copyright (C) 2020 emacs-lsp maintainers
+;;
+;; 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 <https://www.gnu.org/licenses/>.
+;;
+;;; Commentary:
+;;
+;; LSP modeline
+;;
+;;; Code:
+
+(require 'lsp-mode)
+
+(defgroup lsp-modeline nil
+ "LSP support for modeline"
+ :prefix "lsp-modeline-"
+ :group 'lsp-mode
+ :tag "LSP Modeline")
+
+(defcustom lsp-modeline-code-actions-kind-regex "$\\|quickfix.*\\|refactor.*"
+ "Regex for the code actions kinds to show in the modeline."
+ :type 'string
+ :group 'lsp-modeline)
+
+(defcustom lsp-modeline-code-actions-segments '(count icon)
+ "Define what should display on the modeline when code actions are available."
+ :type '(repeat (choice
+ (const :tag "Show the lightbulb icon" icon)
+ (const :tag "Show the name of the preferred code action" name)
+ (const :tag "Show the count of how many code actions available" count)))
+ :group 'lsp-modeline
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-modeline-code-action-fallback-icon "💡"
+ "Define what should display on the modeline when code actions are available."
+ :type 'string
+ :group 'lsp-modeline
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defface lsp-modeline-code-actions-face
+ '((t :inherit homoglyph))
+ "Face used to code action text on modeline."
+ :group 'lsp-modeline)
+
+(defface lsp-modeline-code-actions-preferred-face
+ '((t :foreground "yellow"))
+ "Face used to code action text on modeline."
+ :group 'lsp-modeline)
+
+;;;###autoload
+(define-obsolete-variable-alias 'lsp-diagnostics-modeline-scope
+ 'lsp-modeline-diagnostics-scope "lsp-mode 7.0.1")
+
+(defcustom lsp-modeline-diagnostics-scope :workspace
+ "The modeline diagnostics scope."
+ :group 'lsp-modeline
+ :type '(choice (const :tag "File" :file)
+ (const :tag "Project" :workspace)
+ (const :tag "All Projects" :global))
+ :package-version '(lsp-mode . "6.3"))
+
+(declare-function all-the-icons-octicon "ext:all-the-icons" t t)
+(declare-function lsp-treemacs-errors-list "ext:lsp-treemacs" t)
+
+
+;; code actions
+
+(defvar-local lsp-modeline--code-actions-string nil
+ "Holds the current code action string on modeline.")
+
+(defun lsp-modeline--code-action-face (preferred-code-action)
+ "Return the face checking if there is any PREFERRED-CODE-ACTION."
+ (if preferred-code-action
+ 'lsp-modeline-code-actions-preferred-face
+ 'lsp-modeline-code-actions-face))
+
+(defun lsp-modeline--code-actions-icon (face)
+ "Build the icon for modeline code actions using FACE."
+ (if (require 'all-the-icons nil t)
+ (all-the-icons-octicon "light-bulb"
+ :face face
+ :v-adjust -0.0575)
+ (propertize lsp-modeline-code-action-fallback-icon 'face face)))
+
+(defun lsp-modeline--code-action-name (actions preferred-code-action-title)
+ "Return the code action name from ACTIONS and PREFERRED-CODE-ACTION-TITLE."
+ (or preferred-code-action-title
+ (->> actions
+ lsp-seq-first
+ lsp-modeline--code-action->string)))
+
+(defun lsp-modeline--code-action->string (action)
+ "Convert code ACTION to friendly string."
+ (->> action
+ lsp:code-action-title
+ (replace-regexp-in-string "[\n\t ]+" " ")))
+
+(defun lsp-modeline--build-code-actions-segments (actions)
+ "Build the code ACTIONS string from the defined segments."
+ (let* ((preferred-code-action (-some->> actions
+ (-first #'lsp:code-action-is-preferred?)
+ lsp-modeline--code-action->string))
+ (face (lsp-modeline--code-action-face preferred-code-action)))
+ (mapconcat
+ (lambda (segment)
+ (pcase segment
+ ('icon (lsp-modeline--code-actions-icon face))
+ ('name (propertize (lsp-modeline--code-action-name actions preferred-code-action)
+ 'face face))
+ ('count (propertize (number-to-string (seq-length actions))
+ 'face face))))
+ lsp-modeline-code-actions-segments " ")))
+
+(defun lsp-modeline--build-code-actions-string (actions)
+ "Build the string to be presented on modeline for code ACTIONS."
+ (-let* ((single-action? (= (length actions) 1))
+ (keybinding (concat "("
+ (-some->> #'lsp-execute-code-action
+ where-is-internal
+ (-find (lambda (o)
+ (not (member (aref o 0) '(menu-bar normal-state)))))
+ key-description)
+ ")"))
+ (built-string (lsp-modeline--build-code-actions-segments actions))
+ (preferred-code-action (-some->> actions
+ (-first #'lsp:code-action-is-preferred?)
+ lsp-modeline--code-action->string)))
+ (add-text-properties 0 (length built-string)
+ (list 'help-echo
+ (concat (format "Apply code actions %s\nmouse-1: " keybinding)
+ (if single-action?
+ (lsp-modeline--code-action-name actions preferred-code-action)
+ "select from multiple code actions"))
+ 'mouse-face 'mode-line-highlight
+ 'local-map (make-mode-line-mouse-map
+ 'mouse-1 (lambda ()
+ (interactive)
+ (if single-action?
+ (lsp-execute-code-action (lsp-seq-first actions))
+ (lsp-execute-code-action (lsp--select-action actions))))))
+ built-string)
+ (unless (string= "" built-string)
+ (concat built-string " "))))
+
+(defun lsp--modeline-update-code-actions (actions)
+ "Update modeline with new code ACTIONS."
+ (when lsp-modeline-code-actions-kind-regex
+ (setq actions (seq-filter (-lambda ((&CodeAction :kind?))
+ (or (not kind?)
+ (s-match lsp-modeline-code-actions-kind-regex kind?)))
+ actions)))
+ (setq lsp-modeline--code-actions-string
+ (if (seq-empty-p actions) ""
+ (lsp-modeline--build-code-actions-string actions)))
+ (force-mode-line-update))
+
+(defun lsp-modeline--check-code-actions (&rest _)
+ "Request code actions to update modeline for given BUFFER."
+ (when (lsp-feature? "textDocument/codeAction")
+ (lsp-request-async
+ "textDocument/codeAction"
+ (lsp--text-document-code-action-params)
+ #'lsp--modeline-update-code-actions
+ :mode 'unchanged
+ :cancel-token :lsp-modeline-code-actions)))
+
+(defun lsp-modeline--enable-code-actions ()
+ "Enable code actions on modeline mode."
+ (when (and lsp-modeline-code-actions-enable
+ (lsp-feature? "textDocument/codeAction"))
+ (lsp-modeline-code-actions-mode 1)))
+
+(defun lsp-modeline--disable-code-actions ()
+ "Disable code actions on modeline mode."
+ (lsp-modeline-code-actions-mode -1))
+
+;;;###autoload
+(define-minor-mode lsp-modeline-code-actions-mode
+ "Toggle code actions on modeline."
+ :group 'lsp-modeline
+ :global nil
+ :lighter ""
+ (cond
+ (lsp-modeline-code-actions-mode
+ (add-to-list 'global-mode-string '(t (:eval lsp-modeline--code-actions-string)))
+
+ (add-hook 'lsp-on-idle-hook 'lsp-modeline--check-code-actions nil t)
+ (add-hook 'lsp-configure-hook #'lsp-modeline--enable-code-actions nil t)
+ (add-hook 'lsp-unconfigure-hook #'lsp-modeline--disable-code-actions nil t))
+ (t
+ (remove-hook 'lsp-on-idle-hook 'lsp-modeline--check-code-actions t)
+ (remove-hook 'lsp-configure-hook #'lsp-modeline--enable-code-actions t)
+ (remove-hook 'lsp-unconfigure-hook #'lsp-modeline--disable-code-actions t)
+ (setq global-mode-string (remove '(t (:eval lsp-modeline--code-actions-string)) global-mode-string)))))
+
+
+;; diagnostics
+
+(defvar-local lsp-modeline--diagnostics-string nil
+ "Value of current buffer diagnostics statistics.")
+
+(defvar lsp-modeline--diagnostics-wks->strings nil
+ "Plist of workspaces to their modeline strings.
+The `:global' workspace is global one.")
+
+(defun lsp-modeline-diagnostics-statistics ()
+ "Calculate diagnostics statistics based on `lsp-modeline-diagnostics-scope'."
+ (let ((diagnostics (cond
+ ((equal :file lsp-modeline-diagnostics-scope)
+ (list (lsp--get-buffer-diagnostics)))
+ (t (->> (eq :workspace lsp-modeline-diagnostics-scope)
+ (lsp-diagnostics)
+ (ht-values)))))
+ (stats (make-vector lsp/diagnostic-severity-max 0))
+ strs
+ (i 0))
+ (mapc (lambda (buf-diags)
+ (mapc (lambda (diag)
+ (-let [(&Diagnostic? :severity?) diag]
+ (when severity?
+ (cl-incf (aref stats severity?)))))
+ buf-diags))
+ diagnostics)
+ (while (< i lsp/diagnostic-severity-max)
+ (when (> (aref stats i) 0)
+ (setq strs
+ (nconc strs
+ `(,(propertize
+ (format "%s" (aref stats i))
+ 'face
+ (cond
+ ((= i lsp/diagnostic-severity-error) 'error)
+ ((= i lsp/diagnostic-severity-warning) 'warning)
+ ((= i lsp/diagnostic-severity-information) 'success)
+ ((= i lsp/diagnostic-severity-hint) 'success)))))))
+ (cl-incf i))
+ (-> (s-join "/" strs)
+ (propertize 'mouse-face 'mode-line-highlight
+ 'help-echo "mouse-1: Show diagnostics"
+ 'local-map (when (require 'lsp-treemacs nil t)
+ (make-mode-line-mouse-map
+ 'mouse-1 #'lsp-treemacs-errors-list))))))
+
+(defun lsp-modeline--diagnostics-reset-modeline-cache ()
+ "Reset the modeline diagnostics cache."
+ (plist-put lsp-modeline--diagnostics-wks->strings (car (lsp-workspaces)) nil)
+ (plist-put lsp-modeline--diagnostics-wks->strings :global nil)
+ (setq lsp-modeline--diagnostics-string nil))
+
+(defun lsp-modeline--diagnostics-update-modeline ()
+ "Update diagnostics modeline string."
+ (cl-labels ((calc-modeline ()
+ (let ((str (lsp-modeline-diagnostics-statistics)))
+ (if (string-empty-p str) ""
+ (concat str " ")))))
+ (setq lsp-modeline--diagnostics-string
+ (cl-case lsp-modeline-diagnostics-scope
+ (:file (or lsp-modeline--diagnostics-string
+ (calc-modeline)))
+ (:workspace
+ (let ((wk (car (lsp-workspaces))))
+ (or (plist-get lsp-modeline--diagnostics-wks->strings wk)
+ (let ((ml (calc-modeline)))
+ (setq lsp-modeline--diagnostics-wks->strings
+ (plist-put lsp-modeline--diagnostics-wks->strings wk ml))
+ ml))))
+ (:global
+ (or (plist-get lsp-modeline--diagnostics-wks->strings :global)
+ (let ((ml (calc-modeline)))
+ (setq lsp-modeline--diagnostics-wks->strings
+ (plist-put lsp-modeline--diagnostics-wks->strings :global ml))
+ ml)))))))
+
+(defun lsp-modeline--enable-diagnostics ()
+ "Enable diagnostics on modeline mode."
+ (when (and lsp-modeline-diagnostics-enable
+ (lsp-feature? "textDocument/publishDiagnostics"))
+ (lsp-modeline-diagnostics-mode 1)))
+
+(defun lsp-modeline--disable-diagnostics ()
+ "Disable diagnostics on modeline mode."
+ (lsp-modeline-diagnostics-mode -1))
+
+;;;###autoload
+(define-obsolete-function-alias 'lsp-diagnostics-modeline-mode
+ 'lsp-modeline-diagnostics-mode "lsp-mode 7.0.1")
+
+;;;###autoload
+(define-minor-mode lsp-modeline-diagnostics-mode
+ "Toggle diagnostics modeline."
+ :group 'lsp-modeline
+ :global nil
+ :lighter ""
+ (cond
+ (lsp-modeline-diagnostics-mode
+ (add-hook 'lsp-configure-hook #'lsp-modeline--enable-diagnostics nil t)
+ (add-hook 'lsp-unconfigure-hook #'lsp-modeline--disable-diagnostics nil t)
+ (add-to-list 'global-mode-string '(t (:eval (lsp-modeline--diagnostics-update-modeline))))
+ (add-hook 'lsp-diagnostics-updated-hook 'lsp-modeline--diagnostics-reset-modeline-cache))
+ (t
+ (remove-hook 'lsp-configure-hook #'lsp-modeline--enable-diagnostics t)
+ (remove-hook 'lsp-unconfigure-hook #'lsp-modeline--disable-diagnostics t)
+ (remove-hook 'lsp-diagnostics-updated-hook 'lsp-modeline--diagnostics-reset-modeline-cache)
+ (setq global-mode-string (remove '(t (:eval (lsp-modeline--diagnostics-update-modeline))) global-mode-string)))))
+
+
+;; workspace status
+
+(defun lsp-modeline--workspace-status-string ()
+ "Build the workspace status string."
+ '(t (:eval (-keep #'lsp--workspace-status-string (lsp-workspaces)))))
+
+(defun lsp-modeline--enable-workspace-status ()
+ "Enable workspace status on modeline."
+ (let ((status (lsp-modeline--workspace-status-string)))
+ (setq-local global-mode-string (if (-contains? global-mode-string status)
+ global-mode-string
+ (cons status global-mode-string)))))
+
+(defun lsp-modeline--disable-workspace-status ()
+ "Disable workspace status on modeline."
+ (let ((status (lsp-modeline--workspace-status-string)))
+ (setq-local global-mode-string (remove status global-mode-string))))
+
+;;;###autoload
+(define-minor-mode lsp-modeline-workspace-status-mode
+ "Toggle workspace status on modeline."
+ :group 'lsp-modeline
+ :global nil
+ :lighter ""
+ (cond
+ (lsp-modeline-workspace-status-mode
+ (add-hook 'lsp-configure-hook #'lsp-modeline--enable-workspace-status nil t)
+ (add-hook 'lsp-unconfigure-hook #'lsp-modeline--disable-workspace-status nil t))
+ (t
+ (remove-hook 'lsp-configure-hook #'lsp-modeline--enable-workspace-status t)
+ (remove-hook 'lsp-unconfigure-hook #'lsp-modeline--disable-workspace-status t))))
+
+(lsp-consistency-check lsp-modeline)
+
+(provide 'lsp-modeline)
+;;; lsp-modeline.el ends here
diff --git a/elpa/lsp-mode-20220505.630/lsp-modeline.elc b/elpa/lsp-mode-20220505.630/lsp-modeline.elc
new file mode 100644
index 0000000..2c3f7fc
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-modeline.elc
Binary files differ
diff --git a/elpa/lsp-mode-20220505.630/lsp-nginx.el b/elpa/lsp-mode-20220505.630/lsp-nginx.el
new file mode 100644
index 0000000..b2e184b
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-nginx.el
@@ -0,0 +1,53 @@
+;;; lsp-nginx.el --- Nginx Client settings -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2021 Shen, Jen-Chieh
+
+;; Author: Jen-Chieh Shen <jcs090218@gmail.com>
+;; Keywords: nginx lsp
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;
+;; LSP client for Nginx
+;;
+
+;;; Code:
+
+(require 'lsp-mode)
+
+(defgroup lsp-nginx nil
+ "LSP support for Nginx."
+ :group 'lsp-mode
+ :link '(url-link "https://github.com/pappasam/nginx-language-server")
+ :package-version `(lsp-mode . "8.0.1"))
+
+(defcustom lsp-nginx-server-command '("nginx-language-server")
+ "Command to start Nginx Language Server."
+ :risky t
+ :group 'lsp-nginx
+ :type '(repeat string)
+ :package-version `(lsp-mode . "8.0.1"))
+
+(lsp-register-client
+ (make-lsp-client :new-connection (lsp-stdio-connection
+ (lambda () lsp-nginx-server-command))
+ :major-modes '(nginx-mode)
+ :priority -1
+ :server-id 'nginx-ls))
+
+(lsp-consistency-check lsp-nginx)
+
+(provide 'lsp-nginx)
+;;; lsp-nginx.el ends here
diff --git a/elpa/lsp-mode-20220505.630/lsp-nginx.elc b/elpa/lsp-mode-20220505.630/lsp-nginx.elc
new file mode 100644
index 0000000..f16f2fc
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-nginx.elc
Binary files differ
diff --git a/elpa/lsp-mode-20220505.630/lsp-nim.el b/elpa/lsp-mode-20220505.630/lsp-nim.el
new file mode 100644
index 0000000..c98d565
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-nim.el
@@ -0,0 +1,81 @@
+;;; lsp-nim.el --- description -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2020 emacs-lsp maintainers
+
+;; Author: emacs-lsp maintainers
+;; Keywords: lsp, nim
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; LSP Clients for the Nim Programming Language.
+
+;;; Code:
+
+(require 'lsp-mode)
+
+;; Nim
+(defgroup lsp-nimlsp nil
+ "LSP support for Nim, using nimlsp."
+ :group 'lsp-mode
+ :link '(url-link "https://github.com/PMunch/nimlsp"))
+
+(defcustom-lsp lsp-nim-project-mapping []
+ "Nimsuggest project mapping. Sample value
+
+[(:projectFile \"root.nim\"
+ :fileRegex \".*\\.nim\")]"
+
+ :type '(lsp-repeatable-vector plist)
+ :group 'lsp-nim
+ :package-version '(lsp-mode . "8.0.1")
+ :lsp-path "nim.projectMapping")
+
+(defcustom-lsp lsp-nim-timeout 120000
+ "Timeout for restarting `nimsuggest'"
+ :type 'number
+ :group 'lsp-nim
+ :package-version '(lsp-mode . "8.0.1")
+ :lsp-path "nim.timeout")
+
+(defcustom-lsp lsp-nim-nimsuggest-path "nimsuggest"
+ "Path to `nimsuggest' to use."
+ :type 'number
+ :group 'lsp-nim
+ :package-version '(lsp-mode . "8.0.1")
+ :lsp-path "nim.nimsuggestPath")
+
+(defcustom lsp-nim-langserver "nimlangserver"
+ "Path to `nimlangserver'"
+ :type 'number
+ :group 'lsp-nim
+ :package-version '(lsp-mode . "8.0.1"))
+
+(lsp-register-client
+ (make-lsp-client :new-connection (lsp-stdio-connection "nimlsp")
+ :activation-fn (lsp-activate-on "nim")
+ :priority -1
+ :server-id 'nimls))
+
+(lsp-register-client
+ (make-lsp-client :new-connection (lsp-stdio-connection
+ (lambda () lsp-nim-langserver))
+ :activation-fn (lsp-activate-on "nim")
+ :server-id 'nimlangserver))
+
+(lsp-consistency-check lsp-nim)
+
+(provide 'lsp-nim)
+;;; lsp-nim.el ends here
diff --git a/elpa/lsp-mode-20220505.630/lsp-nim.elc b/elpa/lsp-mode-20220505.630/lsp-nim.elc
new file mode 100644
index 0000000..c5f4d60
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-nim.elc
Binary files differ
diff --git a/elpa/lsp-mode-20220505.630/lsp-nix.el b/elpa/lsp-mode-20220505.630/lsp-nix.el
new file mode 100644
index 0000000..d19151c
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-nix.el
@@ -0,0 +1,48 @@
+;;; lsp-nix.el --- lsp-mode nix integration -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2020 lsp-mode maintainers
+
+;; Author: Seong Yong-ju <sei40kr@gmail.com>
+;; Keywords: languages
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Client for the rnix language server.
+
+;;; Code:
+
+(require 'lsp-mode)
+
+(defgroup lsp-nix nil
+ "LSP support for Nix, using rnix-lsp."
+ :group 'lsp-mode
+ :link '(url-link "https://github.com/nix-community/rnix-lsp"))
+
+(defcustom lsp-nix-server-path "rnix-lsp"
+ "Executable path for the server."
+ :group 'lsp-nix
+ :type 'string
+ :package-version '(lsp-mode . "8.0.0"))
+
+(lsp-register-client
+ (make-lsp-client :new-connection (lsp-stdio-connection (lambda () lsp-nix-server-path))
+ :major-modes '(nix-mode)
+ :server-id 'rnix-lsp))
+
+(lsp-consistency-check lsp-nix)
+
+(provide 'lsp-nix)
+;;; lsp-nix.el ends here
diff --git a/elpa/lsp-mode-20220505.630/lsp-nix.elc b/elpa/lsp-mode-20220505.630/lsp-nix.elc
new file mode 100644
index 0000000..6977d9b
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-nix.elc
Binary files differ
diff --git a/elpa/lsp-mode-20220505.630/lsp-ocaml.el b/elpa/lsp-mode-20220505.630/lsp-ocaml.el
new file mode 100644
index 0000000..b1e1003
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-ocaml.el
@@ -0,0 +1,84 @@
+;;; lsp-ocaml.el --- description -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2020 emacs-lsp maintainers
+
+;; Author: emacs-lsp maintainers
+;; Keywords: lsp, ocaml
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; LSP Clients for the Ocaml Programming Language.
+
+;;; Code:
+
+(require 'lsp-mode)
+
+(defgroup lsp-ocaml nil
+ "LSP support for OCaml, using ocaml-language-server."
+ :group 'lsp-mode
+ :link '(url-link "https://github.com/freebroccolo/ocaml-language-server"))
+
+(define-obsolete-variable-alias
+ 'lsp-ocaml-ocaml-lang-server-command
+ 'lsp-ocaml-lang-server-command
+ "lsp-mode 6.1")
+
+(defcustom lsp-ocaml-lang-server-command
+ '("ocaml-language-server" "--stdio")
+ "Command to start ocaml-language-server."
+ :group 'lsp-ocaml
+ :type '(choice
+ (string :tag "Single string value")
+ (repeat :tag "List of string values"
+ string)))
+
+(lsp-register-client
+ (make-lsp-client :new-connection (lsp-stdio-connection
+ (lambda () lsp-ocaml-lang-server-command))
+ :major-modes '(reason-mode caml-mode tuareg-mode)
+ :priority -1
+ :server-id 'ocaml-ls))
+
+(defgroup lsp-ocaml-lsp-server nil
+ "LSP support for OCaml, using ocaml-lsp-server."
+ :group 'lsp-mode
+ :link '(url-link "https://github.com/ocaml/ocaml-lsp"))
+
+(define-obsolete-variable-alias 'lsp-merlin 'lsp-ocaml-lsp-server "lsp-mode 6.1")
+(define-obsolete-variable-alias 'lsp-merlin-command 'lsp-ocaml-lsp-server-command "lsp-mode 6.1")
+
+(defcustom lsp-ocaml-lsp-server-command
+ '("ocamllsp")
+ "Command to start ocaml-language-server."
+ :group 'lsp-ocaml
+ :type '(choice
+ (string :tag "Single string value")
+ (repeat :tag "List of string values"
+ string)))
+
+(lsp-register-client
+ (make-lsp-client
+ :new-connection
+ (lsp-stdio-connection (lambda () lsp-ocaml-lsp-server-command))
+ :major-modes '(reason-mode caml-mode tuareg-mode)
+ :priority 0
+ :server-id 'ocaml-lsp-server))
+
+
+(lsp-consistency-check lsp-ocaml)
+
+(provide 'lsp-ocaml)
+;;; lsp-ocaml.el ends here
diff --git a/elpa/lsp-mode-20220505.630/lsp-ocaml.elc b/elpa/lsp-mode-20220505.630/lsp-ocaml.elc
new file mode 100644
index 0000000..56f060e
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-ocaml.elc
Binary files differ
diff --git a/elpa/lsp-mode-20220505.630/lsp-openscad.el b/elpa/lsp-mode-20220505.630/lsp-openscad.el
new file mode 100644
index 0000000..a090e10
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-openscad.el
@@ -0,0 +1,49 @@
+;;; lsp-openscad.el --- openscad client -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2022 Len Trigg
+
+;; Author: Len Trigg
+;; Keywords: openscad lsp
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; lsp-openscad client
+
+;;; Code:
+
+(require 'lsp-mode)
+
+(defgroup lsp-openscad nil
+ "LSP support for openscad."
+ :group 'lsp-mode
+ :link '(url-link "https://github.com/dzhu/openscad-language-server"))
+
+(defcustom lsp-openscad-server
+ "openscad-language-server"
+ "Path to the openscad language server."
+ :group 'lsp-openscad
+ :risky t
+ :type 'file)
+
+
+(lsp-register-client
+ (make-lsp-client :new-connection (lsp-stdio-connection lsp-openscad-server)
+ :major-modes '(scad-mode)
+ :priority -1
+ :server-id 'openscad))
+
+(provide 'lsp-openscad)
+;;; lsp-openscad.el ends here
diff --git a/elpa/lsp-mode-20220505.630/lsp-openscad.elc b/elpa/lsp-mode-20220505.630/lsp-openscad.elc
new file mode 100644
index 0000000..f6d39e8
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-openscad.elc
Binary files differ
diff --git a/elpa/lsp-mode-20220505.630/lsp-perl.el b/elpa/lsp-mode-20220505.630/lsp-perl.el
new file mode 100644
index 0000000..4126e0d
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-perl.el
@@ -0,0 +1,117 @@
+;;; lsp-perl.el --- lsp-perl config -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2020 lsp-mode developers
+
+;; Author: Hiroki Noda <kubo39@gmail.com>
+;; Keywords:
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; lsp-perl client
+
+;;; Code:
+
+(require 'lsp-mode)
+
+(defgroup lsp-perl nil
+ "LSP support for Perl"
+ :group 'lsp-mode
+ :link '(url-link "https://github.com/richterger/Perl-LanguageServer")
+ :package-version '(lsp-mode . "6.3"))
+
+(defcustom lsp-perl-language-server-path "perl"
+ "Path to perl interpreter."
+ :type 'string
+ :group 'lsp-perl
+ :package-version '(lsp-mode . "6.3"))
+
+(defcustom lsp-perl-language-server-port 13603
+ "Choose listen port."
+ :type 'integer
+ :group 'lsp-perl
+ :package-version '(lsp-mode . "6.3"))
+
+(defcustom lsp-perl-language-server-client-version "2.1.0"
+ "Choose client version."
+ :type 'string
+ :group 'lsp-perl
+ :package-version '(lsp-mode . "6.3"))
+
+(defcustom lsp-perl-perl-cmd nil
+ "Path to perl interpreter used in Perl Language Server.
+Defaults to `perl' if nil."
+ :type 'string
+ :group 'lsp-perl
+ :package-version '(lsp-mode . "7.0.1"))
+(defcustom lsp-perl-perl-inc nil
+ "A vector of paths to add to perl library path."
+ :type 'lsp-string-vector
+ :group 'lsp-perl
+ :package-version '(lsp-mode . "7.0.1"))
+(defcustom lsp-perl-file-filter nil
+ "A vector of directories filtering perl file.
+Defaults to `[\".pm\" \".pl\"]' if nil."
+ :type 'lsp-string-vector
+ :group 'lsp-perl
+ :package-version '(lsp-mode . "7.0.1"))
+(defcustom lsp-perl-ignore-dirs nil
+ "A vector of directories to ignore.
+Defaults to `[\".vscode\" \".git\" \".svn\"]' if nil."
+ :type 'lsp-string-vector
+ :group 'lsp-perl
+ :package-version '(lsp-mode . "7.0.1"))
+
+(defcustom lsp-perl-show-local-vars nil
+ "If true, show also local variables in symbol view.
+Defaults to false if nil"
+ :type 'boolean
+ :group 'lsp-perl
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-perl-log-level nil
+ "Log level 0-2.
+Defaults to 0."
+ :type 'integer
+ :group 'lsp-perl
+ :package-version '(lsp-mode . "8.0.0"))
+
+(lsp-register-custom-settings
+ '(("perl.perlCmd" lsp-perl-perl-cmd)
+ ("perl.perlInc" lsp-perl-perl-inc)
+ ("perl.fileFilter" lsp-perl-file-filter)
+ ("perl.ignoreDirs" lsp-perl-ignore-dirs)
+ ("perl.showLocalVars" lsp-perl-show-local-vars t)
+ ("perl.logLevel" lsp-perl-log-level)))
+
+(lsp-register-client
+ (make-lsp-client :new-connection (lsp-stdio-connection
+ (lambda ()
+ (list lsp-perl-language-server-path
+ "-MPerl::LanguageServer" "-e" "Perl::LanguageServer::run" "--"
+ (format "--port %d --version %s"
+ lsp-perl-language-server-port lsp-perl-language-server-client-version))))
+ :major-modes '(perl-mode cperl-mode)
+ :initialized-fn (lambda (workspace)
+ (with-lsp-workspace workspace
+ (lsp--set-configuration
+ (lsp-configuration-section "perl"))))
+ :priority -1
+ :server-id 'perl-language-server))
+
+(lsp-consistency-check lsp-perl)
+
+(provide 'lsp-perl)
+;;; lsp-perl.el ends here
diff --git a/elpa/lsp-mode-20220505.630/lsp-perl.elc b/elpa/lsp-mode-20220505.630/lsp-perl.elc
new file mode 100644
index 0000000..0092a84
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-perl.elc
Binary files differ
diff --git a/elpa/lsp-mode-20220505.630/lsp-perlnavigator.el b/elpa/lsp-mode-20220505.630/lsp-perlnavigator.el
new file mode 100644
index 0000000..d5a6afa
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-perlnavigator.el
@@ -0,0 +1,197 @@
+;;; lsp-perlnavigator.el --- Integrates the Perl Navigator LSP Server with lsp-mode -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2022 Matthew Feinberg
+
+;; Author: Matthew Feinberg <matthew.feinberg@gmail.com>
+;; Keywords: lsp, perl
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'lsp-mode)
+
+(defgroup lsp-perlnavigator nil
+ "LSP support for Perl Navigator."
+ :group 'lsp-mode
+ :link '(url-link "https://github.com/bscan/PerlNavigator")
+ :package-version '(lsp-mode . "8.0.1"))
+
+(defcustom lsp-perlnavigator-perl-path "perl"
+ "Full path to the perl executable (no aliases, .bat files or ~/)."
+ :type 'string
+ :group 'lsp-perlnavigator
+ :package-version '(lsp-mode . "8.0.1"))
+
+(defcustom lsp-perlnavigator-enable-warnings t
+ "Enable warnings using -Mwarnings command switch."
+ :type 'boolean
+ :group 'lsp-perlnavigator
+ :package-version '(lsp-mode . "8.0.1"))
+
+(defcustom lsp-perlnavigator-perltidy-profile nil
+ "Path to perl tidy profile (no aliases, .bat files or ~/)."
+ :type 'string
+ :group 'lsp-perlnavigator
+ :package-version '(lsp-mode . "8.0.1"))
+
+(defcustom lsp-perlnavigator-perlcritic-profile nil
+ "Path to perl critic profile. Otherwise perlcritic itself will
+default to ~/.perlcriticrc. (no aliases, .bat files or ~/)."
+ :type 'string
+ :group 'lsp-perlnavigator
+ :package-version '(lsp-mode . "8.0.1"))
+
+(defcustom lsp-perlnavigator-perlcritic-enabled t
+ "Enable perl critic."
+ :type 'boolean
+ :group 'lsp-perlnavigator
+ :package-version '(lsp-mode . "8.0.1"))
+
+(defcustom lsp-perlnavigator-severity5 "warning"
+ "Editor Diagnostic severity level for Critic severity 5."
+ :type '(choice (:tag "error" "warning" "info" "hint" "none"))
+ :group 'lsp-perlnavigator
+ :package-version '(lsp-mode . "8.0.1"))
+
+(defcustom lsp-perlnavigator-severity4 "info"
+ "Editor Diagnostic severity level for Critic severity 4."
+ :type '(choice (:tag "error" "warning" "info" "hint" "none"))
+ :group 'lsp-perlnavigator
+ :package-version '(lsp-mode . "8.0.1"))
+
+(defcustom lsp-perlnavigator-severity3 "hint"
+ "Editor Diagnostic severity level for Critic severity 3."
+ :type '(choice (:tag "error" "warning" "info" "hint" "none"))
+ :group 'lsp-perlnavigator
+ :package-version '(lsp-mode . "8.0.1"))
+
+(defcustom lsp-perlnavigator-severity2 "hint"
+ "Editor Diagnostic severity level for Critic severity 2."
+ :type '(choice (:tag "error" "warning" "info" "hint" "none"))
+ :group 'lsp-perlnavigator
+ :package-version '(lsp-mode . "8.0.1"))
+
+(defcustom lsp-perlnavigator-severity1 "hint"
+ "Editor Diagnostic severity level for Critic severity 1."
+ :type '(choice (:tag "error" "warning" "info" "hint" "none"))
+ :group 'lsp-perlnavigator
+ :package-version '(lsp-mode . "8.0.1"))
+
+(defcustom lsp-perlnavigator-include-paths nil
+ "Array of paths added to @INC. You can use $workspaceRoot as a placeholder."
+ :type 'lsp-string-vector
+ :group 'lsp-perlnavigator
+ :package-version '(lsp-mode . "8.0.1"))
+
+(defcustom lsp-perlnavigator-logging t
+ "Log to stdout from the navigator. Viewable in the Perl Navigator LSP log."
+ :type 'boolean
+ :group 'lsp-perlnavigator
+ :package-version '(lsp-mode . "8.0.1"))
+
+(defcustom lsp-perlnavigator-trace-server "messages"
+ "Traces the communication between VS Code and the language server."
+ :type '(choice (:tag "off" "messages" "verbose"))
+ :group 'lsp-perlnavigator
+ :package-version '(lsp-mode . "8.0.1"))
+
+(lsp-register-custom-settings
+ '(("perlnavigator.trace.server" lsp-perlnavigator-trace-server)
+ ("perlnavigator.logging" lsp-perlnavigator-logging t)
+ ("perlnavigator.includePaths" lsp-perlnavigator-include-paths)
+ ("perlnavigator.severity1" lsp-perlnavigator-severity1)
+ ("perlnavigator.severity2" lsp-perlnavigator-severity2)
+ ("perlnavigator.severity3" lsp-perlnavigator-severity3)
+ ("perlnavigator.severity4" lsp-perlnavigator-severity4)
+ ("perlnavigator.severity5" lsp-perlnavigator-severity5)
+ ("perlnavigator.perlcriticEnabled" lsp-perlnavigator-perlcritic-enabled t)
+ ("perlnavigator.perlcriticProfile" lsp-perlnavigator-perlcritic-profile)
+ ("perlnavigator.perltidyProfile" lsp-perlnavigator-perltidy-profile)
+ ("perlnavigator.enableWarnings" lsp-perlnavigator-enable-warnings t)
+ ("perlnavigator.perlPath" lsp-perlnavigator-perl-path)))
+
+(defcustom lsp-perlnavigator-executable "perlnavigator"
+ "Location of the perlnavigator binary."
+ :group 'lsp-perlnavigator
+ :risky t
+ :type 'file)
+
+(defvar lsp-perlnavigator--os-suffix
+ (let ((x86_64 (eq (string-match "^x86_64" system-configuration) 0)))
+ (cond ((and x86_64 (eq system-type 'windows-nt))
+ "-win-x86_64")
+
+ ((and x86_64 (eq system-type 'darwin))
+ "-macos-x86_64")
+
+ ((and x86_64 (eq system-type 'gnu/linux))
+ "-linux-x86_64")))
+
+ "The suffix used to specify the download for this operating system.")
+
+(defcustom lsp-perlnavigator-download-url
+ (let ((base-url "https://github.com/bscan/PerlNavigator/releases/latest/download/"))
+ (if lsp-perlnavigator--os-suffix
+ (concat base-url "perlnavigator" lsp-perlnavigator--os-suffix ".zip")))
+
+ "Automatic download url for PerlNavigator."
+ :group 'lsp-perlnavigator
+ :type 'string)
+
+(defcustom lsp-perlnavigator-autoinstall-dir
+ (f-join lsp-server-install-dir "perlnavigator")
+ "Automatic installation directory for Perl Navigator."
+ :group 'lsp-perlnavigator
+ :type 'directory)
+
+(defvar lsp-perlnavigator--autoinstall-store-path
+ (f-join lsp-perlnavigator-autoinstall-dir "latest" (concat "perlnavigator" lsp-perlnavigator--os-suffix ".zip"))
+ "The path where the downloaded PerlNavigator .zip archive will be stored.")
+
+
+(defvar lsp-perlnavigator--autoinstall-binary-path
+ (let ((exe-name (if (eq system-type 'windows-nt) "perlnavigator.exe" "perlnavigator")))
+ (f-join lsp-perlnavigator-autoinstall-dir "latest" (concat "perlnavigator" lsp-perlnavigator--os-suffix) exe-name))
+ "The path to the automatically installed language server executable.")
+
+(lsp-dependency
+ 'perlnavigator
+ '(:system lsp-perlnavigator-executable)
+ `(:download
+ :decompress
+ :zip
+ :binary-path lsp-perlnavigator--autoinstall-binary-path
+ :url lsp-perlnavigator-download-url
+ :store-path lsp-perlnavigator--autoinstall-store-path
+ :set-executable? t))
+
+(lsp-register-client
+(make-lsp-client :new-connection (lsp-stdio-connection (lambda ()
+ (list
+ (or (executable-find lsp-perlnavigator-executable)
+ (lsp-package-path 'perlnavigator))
+ "--stdio")))
+ :activation-fn (lsp-activate-on "perl")
+ :priority 0
+ :download-server-fn (lambda (_client callback error-callback _update?)
+ (lsp-package-ensure 'perlnavigator callback error-callback))
+ :server-id 'perlnavigator))
+
+(provide 'lsp-perlnavigator)
+;;; lsp-perlnavigator.el ends here
diff --git a/elpa/lsp-mode-20220505.630/lsp-perlnavigator.elc b/elpa/lsp-mode-20220505.630/lsp-perlnavigator.elc
new file mode 100644
index 0000000..9357596
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-perlnavigator.elc
Binary files differ
diff --git a/elpa/lsp-mode-20220505.630/lsp-php.el b/elpa/lsp-mode-20220505.630/lsp-php.el
new file mode 100644
index 0000000..bfb7d2a
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-php.el
@@ -0,0 +1,449 @@
+;;; lsp-php.el --- description -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2020 emacs-lsp maintainers
+
+;; Author: emacs-lsp maintainers
+;; Keywords: lsp, php
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; LSP Clients for the PHP Programming Language.
+
+;;; Code:
+
+(require 'lsp-mode)
+(require 'lsp-protocol)
+
+;; PHP Language Server
+(defgroup lsp-php nil
+ "LSP support for PHP, using php-language-server."
+ :link '(url-link "https://github.com/felixfbecker/php-language-server")
+ :group 'lsp-mode)
+
+(defun lsp-php-get-composer-dir ()
+ "Get composer home directory if possible."
+ (if (executable-find "composer")
+ (replace-regexp-in-string "\n$" "" (shell-command-to-string "composer config --global home"))
+ "~/.composer"))
+
+(defcustom lsp-php-composer-dir nil
+ "Home directory of composer."
+ :group 'lsp-php
+ :type 'string)
+
+(defcustom lsp-clients-php-server-command nil
+ "Install directory for php-language-server."
+ :group 'lsp-php
+ :type '(repeat string))
+
+(defun lsp-php--create-connection ()
+ "Create lsp connection."
+ (lsp-stdio-connection
+ (lambda ()
+ (unless lsp-php-composer-dir
+ (setq lsp-php-composer-dir (lsp-php-get-composer-dir)))
+ (unless lsp-clients-php-server-command
+ (setq lsp-clients-php-server-command
+ `("php",
+ (expand-file-name
+ (f-join lsp-php-composer-dir "vendor/felixfbecker/language-server/bin/php-language-server.php")))))
+ lsp-clients-php-server-command)
+ (lambda ()
+ (if (and (cdr lsp-clients-php-server-command)
+ (eq (string-match-p "php[0-9.]*\\'" (car lsp-clients-php-server-command)) 0))
+ ;; Start with the php command and the list has more elems. Test the existence of the PHP script.
+ (let ((php-file (nth 1 lsp-clients-php-server-command)))
+ (or (file-exists-p php-file)
+ (progn
+ (lsp-log "%s is not present." php-file)
+ nil)))
+ t))))
+
+(lsp-register-client
+ (make-lsp-client :new-connection (lsp-php--create-connection)
+ :activation-fn (lsp-activate-on "php")
+ :priority -3
+ :server-id 'php-ls))
+
+;;; Intelephense
+(defgroup lsp-intelephense nil
+ "LSP support for PHP, using Intelephense."
+ :group 'lsp-mode
+ :link '(url-link "https://github.com/bmewburn/vscode-intelephense")
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom-lsp lsp-intelephense-php-version "8.0.1"
+ "Minimum version of PHP to refer to. Affects code actions, diagnostic &
+completions."
+ :type 'string
+ :group 'lsp-intelephense
+ :package-version '(lsp-mode . "6.1")
+ :lsp-path "intelephense.environment.phpVersion")
+
+(defcustom-lsp lsp-intelephense-files-max-size 1000000
+ "Maximum file size in bytes."
+ :type 'number
+ :group 'lsp-intelephense
+ :package-version '(lsp-mode . "6.1")
+ :lsp-path "intelephense-files.maxSize")
+
+(defcustom-lsp lsp-intelephense-files-associations
+ ["*.php" "*.phtml"]
+ "Configure glob patterns to make files available for language
+server features."
+ :type '(repeat string)
+ :group 'lsp-intelephense
+ :package-version '(lsp-mode . "6.1")
+ :lsp-path "intelephense.files.associations")
+
+(defcustom-lsp lsp-intelephense-files-exclude
+ ["**/.git/**" "**/.svn/**" "**/.hg/**" "**/CVS/**" "**/.DS_Store/**"
+ "**/node_modules/**" "**/bower_components/**" "**/vendor/**/{Test,test,Tests,tests}/**"]
+ "Configure glob patterns to exclude certain files and folders
+from all language server features."
+ :type '(repeat string)
+ :group 'lsp-intelephense
+ :package-version '(lsp-mode . "6.1")
+ :lsp-path "intelephense.files.exclude")
+
+(defcustom-lsp lsp-intelephense-stubs
+ ["apache" "bcmath" "bz2" "calendar"
+ "com_dotnet" "Core" "ctype" "curl" "date" "dba" "dom" "enchant"
+ "exif" "fileinfo" "filter" "fpm" "ftp" "gd" "hash" "iconv" "imap" "interbase"
+ "intl" "json" "ldap" "libxml" "mbstring" "mcrypt" "meta" "mssql" "mysqli"
+ "oci8" "odbc" "openssl" "pcntl" "pcre" "PDO" "pdo_ibm" "pdo_mysql"
+ "pdo_pgsql" "pdo_sqlite" "pgsql" "Phar" "posix" "pspell" "readline" "recode"
+ "Reflection" "regex" "session" "shmop" "SimpleXML" "snmp" "soap" "sockets"
+ "sodium" "SPL" "sqlite3" "standard" "superglobals" "sybase" "sysvmsg"
+ "sysvsem" "sysvshm" "tidy" "tokenizer" "wddx" "xml" "xmlreader" "xmlrpc"
+ "xmlwriter" "Zend OPcache" "zip" "zlib"]
+ "Configure stub files for built in symbols and common
+extensions. The default setting includes PHP core and all
+bundled extensions."
+ :type '(repeat string)
+ :group 'lsp-intelephense
+ :package-version '(lsp-mode . "6.1")
+ :lsp-path "intelephense.stubs")
+
+(defcustom-lsp lsp-intelephense-completion-insert-use-declaration t
+ "Use declarations will be automatically inserted for namespaced
+classes, traits, interfaces, functions, and constants."
+ :type 'boolean
+ :group 'lsp-intelephense
+ :package-version '(lsp-mode . "6.1")
+ :lsp-path "intelephense.completion.insertUseDeclaration")
+
+(defcustom-lsp lsp-intelephense-completion-fully-qualify-global-constants-and-functions nil
+ "Global namespace constants and functions will be fully
+qualified (prefixed with a backslash)."
+ :type 'boolean
+ :group 'lsp-intelephense
+ :package-version '(lsp-mode . "6.1")
+ :lsp-path "intelephense.completion.fullyQualifyGlobalConstantsAndFunctions")
+
+(defcustom-lsp lsp-intelephense-completion-trigger-parameter-hints t
+ "Method and function completions will include parentheses and
+trigger parameter hints."
+ :type 'boolean
+ :group 'lsp-intelephense
+ :package-version '(lsp-mode . "6.2")
+ :lsp-path "intelephense.completion.triggerParameterHints")
+
+(defcustom-lsp lsp-intelephense-completion-max-items 100
+ "The maximum number of completion items returned per request."
+ :type 'number
+ :group 'lsp-intelephense
+ :package-version '(lsp-mode . "6.2")
+ :lsp-path "intelephense.completion.maxItems")
+
+(defcustom-lsp lsp-intelephense-format-enable t
+ "Enables formatting."
+ :type 'boolean
+ :group 'lsp-intelephense
+ :package-version '(lsp-mode . "6.1")
+ :lsp-path "intelephense.format.enable")
+
+(defcustom lsp-intelephense-licence-key nil
+ "Enter your intelephense licence key here to access premium
+features."
+ :type 'string
+ :group 'lsp-intelephense
+ :package-version '(lsp-mode . "6.2"))
+
+(defcustom-lsp lsp-intelephense-telemetry-enabled nil
+ "Anonymous usage and crash data will be sent to Azure
+Application Insights."
+ :type 'boolean
+ :group 'lsp-intelephense
+ :package-version '(lsp-mode . "6.2")
+ :lsp-path "intelephense.telemetry.enabled")
+
+(defcustom-lsp lsp-intelephense-rename-exclude
+ ["**/vendor/**"]
+ "Glob patterns to exclude files and folders from having symbols
+renamed. Rename operation will fail if references and/or
+definitions are found in excluded files/folders."
+ :type '(repeat string)
+ :group 'lsp-intelephense
+ :package-version '(lsp-mode . "6.2")
+ :lsp-path "intelephense.rename.exclude")
+
+(defcustom-lsp lsp-intelephense-trace-server "off"
+ "Traces the communication between VSCode and the intelephense
+language server."
+ :type '(choice (:tag "off" "messages" "verbose"))
+ :group 'lsp-intelephense
+ :package-version '(lsp-mode . "6.1")
+ :lsp-path "intelephense.trace.server")
+
+(defcustom lsp-intelephense-storage-path
+ (expand-file-name (locate-user-emacs-file "lsp-cache"))
+ "Optional absolute path to storage dir."
+ :type 'directory
+ :group 'lsp-intelephense
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-intelephense-global-storage-path
+ (expand-file-name (locate-user-emacs-file "intelephense"))
+ "Optional absolute path to global storage dir."
+ :type 'directory
+ :group 'lsp-intelephense
+ :package-version '(lsp-mode . "8.0.1"))
+
+(defcustom lsp-intelephense-clear-cache nil
+ "Optional flag to clear server state."
+ :type 'boolean
+ :group 'lsp-intelephense
+ :package-version '(lsp-mode . "6.2"))
+
+(defcustom lsp-intelephense-multi-root t
+ "Flag to control if the server supports multi-root projects."
+ :type 'boolean
+ :group 'lsp-intelephense
+ :package-version '(lsp-mode . "6.3"))
+
+(define-obsolete-variable-alias
+ 'lsp-clients-php-iph-server-command
+ 'lsp-intelephense-server-command
+ "lsp-mode 6.1")
+
+(defcustom lsp-intelephense-server-command
+ `("intelephense" "--stdio")
+ "Command to start Intelephense."
+ :type '(repeat string)
+ :group 'lsp-intelephense
+ :package-version '(lsp-mode . "6.1"))
+
+(lsp-dependency 'intelephense
+ '(:system "intelephense")
+ '(:npm :package "intelephense"
+ :path "intelephense"))
+
+(lsp-register-client
+ (make-lsp-client :new-connection (lsp-stdio-connection
+ (lambda ()
+ `(,(or (executable-find
+ (cl-first lsp-intelephense-server-command))
+ (lsp-package-path 'intelephense))
+ ,@(cl-rest lsp-intelephense-server-command))))
+ :activation-fn (lsp-activate-on "php")
+ :priority -1
+ :notification-handlers (ht ("indexingStarted" #'ignore)
+ ("indexingEnded" #'ignore))
+ :initialization-options (lambda ()
+ (list :storagePath lsp-intelephense-storage-path
+ :globalStoragePath lsp-intelephense-global-storage-path
+ :licenceKey lsp-intelephense-licence-key
+ :clearCache lsp-intelephense-clear-cache))
+ :multi-root lsp-intelephense-multi-root
+ :completion-in-comments? t
+ :server-id 'iph
+ :download-server-fn (lambda (_client callback error-callback _update?)
+ (lsp-package-ensure 'intelephense
+ callback error-callback))
+ :synchronize-sections '("intelephense")))
+
+
+;;; Serenata
+(defgroup lsp-serenata nil
+ "LSP support for the PHP programming language, using serenata."
+ :group 'lsp-mode
+ :link '(url-link "https://gitlab.com/Serenata/Serenata")
+ :package-version '(lsp-mode . "7.0"))
+
+(defcustom lsp-serenata-server-path
+ "serenata.phar"
+ "Path to the Serenata Language Server phar file.
+It can be downloaded from https://gitlab.com/Serenata/Serenata/-/releases."
+ :group 'lsp-serenata
+ :type 'file)
+
+(defcustom lsp-serenata-uris
+ []
+ "A list of folders to index for your project.
+This does not have to include the root of the project itself, in
+case you have need of an exotic configuration where the root of
+the project is at some location but your actual PHP code is
+somewhere else. Note that if you are running Serenata in a
+container, you will have to ensure that these URI's are mapped
+inside it. Avoid using file paths containing spaces. This is
+currently broken due to apparent PHP quirks. By default, the
+value is taken from the lsp workspace location."
+ :group 'lsp-serenata
+ :type 'lsp-string-vector)
+
+(defcustom lsp-serenata-php-version
+ 7.3
+ "Allows you to specify the PHP version your project is written in.
+At the moment this directive is still ignored, but it will
+influence functionality such as refactoring in the future, where
+older PHP versions may not support scalar type hints, which may
+then be omitted from places such as getters and setters."
+ :group 'lsp-serenata
+ :type 'number)
+
+(defcustom lsp-serenata-file-extensions
+ ["php"]
+ "List of file extensions (without dot) to process.
+Files that do not match this whitelist will be ignored during
+indexing. Usually you'll want to set this to at least include
+php, as it is the most common PHP extension. phpt is not
+included by default as it is often used to contain test code that
+is not directly part of the code. Note that for existing
+projects, removing extensions will not not automatically prune
+files having them from the index if they are already present.
+Adding new ones will cause the files having them to be picked up
+on the next project initialization."
+ :group 'lsp-serenata
+ :type 'lsp-string-vector)
+
+(defcustom lsp-serenata-index-database-uri (lsp--path-to-uri (f-join user-emacs-directory "index.sqlite"))
+ "The location to store the index database.
+Note that, as the index database uses SQLite and WAL mode,
+additional files (usually two) may be generated and used in the
+same folder. Note also that Serenata relies on the Doctrine DBAL
+library as well as the SQLite backends in PHP, which may not
+support non-file URI's, which may prevent you from using these."
+ :group 'lsp-serenata
+ :type 'file)
+
+(defcustom lsp-serenata-exclude-path-expressions ["/.+Test.php$/"]
+ "One or more expressions of paths to ignore.
+This uses Symfony's Finder in the background, so this means you
+can configure anything here that can also be passed to the name
+function, which includes plain strings, globs, as well as regular
+expressions. Note that for existing projects, modifying these
+will not not automatically prune them from the index if they are
+already present."
+ :group 'lsp-serenata
+ :type 'lsp-string-vector)
+
+(defun lsp-serenata-server-start-fun (port)
+ "Define serenata start function, it requires a PORT."
+ `(,lsp-serenata-server-path
+ "-u" ,(number-to-string port)))
+
+(defun lsp-serenata-init-options ()
+ "Init options for lsp-serenata."
+ `( :configuration ( :uris ,lsp-serenata-uris
+ :indexDatabaseUri ,lsp-serenata-index-database-uri
+ :phpVersion ,lsp-serenata-php-version
+ :excludedPathExpressions ,lsp-serenata-exclude-path-expressions
+ :fileExtensions ,lsp-serenata-file-extensions)))
+
+
+(lsp-interface (serenata:didProgressIndexing (:sequenceOfIndexedItem :totalItemsToIndex :progressPercentage :folderUri :fileUri :info) nil ))
+
+(lsp-register-client
+ (make-lsp-client
+ :new-connection (lsp-tcp-connection 'lsp-serenata-server-start-fun)
+ :activation-fn (lsp-activate-on "php")
+ :priority -2
+ :notification-handlers (ht ("serenata/didProgressIndexing"
+ (lambda (_server data)
+ (lsp-log "%s" (lsp:serenata-did-progress-indexing-info data)))))
+
+ :initialization-options #'lsp-serenata-init-options
+ :initialized-fn (lambda (workspace)
+ (when (equal (length lsp-serenata-uris) 0)
+ (let* ((lsp-root (lsp--path-to-uri (lsp-workspace-root))))
+ (setq lsp-serenata-uris (vector lsp-root))))
+ (with-lsp-workspace workspace
+ (lsp--set-configuration
+ (lsp-configuration-section "serenata"))))
+ :server-id 'serenata))
+
+;;; phpactor
+
+(defgroup lsp-phpactor nil
+ "LSP support for Phpactor."
+ :link '(url-link "https://github.com/phpactor/phpactor")
+ :group 'lsp-mode)
+
+(defcustom lsp-phpactor-path nil
+ "Path to the `phpactor' command."
+ :group 'lsp-phpactor
+ :type "string")
+
+(lsp-register-client
+ (make-lsp-client
+ :new-connection (lsp-stdio-connection
+ (lambda ()
+ (unless lsp-php-composer-dir
+ (setq lsp-php-composer-dir (lsp-php-get-composer-dir)))
+ (unless lsp-phpactor-path
+ (setq lsp-phpactor-path (or (executable-find "phpactor")
+ (f-join lsp-php-composer-dir "vendor/phpactor/phpactor/bin/phpactor"))))
+ (list lsp-phpactor-path "language-server")))
+ :activation-fn (lsp-activate-on "php")
+ ;; `phpactor' is not really that feature-complete: it doesn't support
+ ;; `textDocument/showOccurence' and sometimes errors (e.g. find references on
+ ;; a global free-standing function).
+ :priority -4
+ ;; Even though `phpactor' itself supports no options, this needs to be
+ ;; serialized as an empty object (otherwise the LS won't even start, due to a
+ ;; type error).
+ :initialization-options (ht)
+ :server-id 'phpactor))
+
+(defcustom lsp-phpactor-extension-alist '(("Phpstan" . "phpactor/language-server-phpstan-extension")
+ ("Behat" . "phpactor/behat-extension")
+ ("PHPUnit" . "phpactor/phpunit-extension"))
+ "Alist mapping extension names to `composer' packages.
+These extensions can be installed using
+`lsp-phpactor-install-extension'."
+ :type '(alist :key-type "string" :value-type "string")
+ :group 'lsp-phpactor)
+
+(defun lsp-phpactor-install-extension (extension)
+ "Install a `phpactor' EXTENSION.
+See `lsp-phpactor-extension-alist' and
+https://phpactor.readthedocs.io/en/develop/extensions.html."
+ (interactive (list (completing-read "Select extension: "
+ lsp-phpactor-extension-alist)))
+ (compilation-start
+ (format "%s extension:install %s"
+ (shell-quote-argument (expand-file-name lsp-phpactor-path))
+ (shell-quote-argument
+ (cdr (assoc extension lsp-phpactor-extension-alist))))
+ nil
+ (lambda (_mode)
+ (format "*Phpactor install %s*" extension))))
+
+(lsp-consistency-check lsp-php)
+
+(provide 'lsp-php)
+;;; lsp-php.el ends here
diff --git a/elpa/lsp-mode-20220505.630/lsp-php.elc b/elpa/lsp-mode-20220505.630/lsp-php.elc
new file mode 100644
index 0000000..2a24575
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-php.elc
Binary files differ
diff --git a/elpa/lsp-mode-20220505.630/lsp-prolog.el b/elpa/lsp-mode-20220505.630/lsp-prolog.el
new file mode 100644
index 0000000..084f0ee
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-prolog.el
@@ -0,0 +1,55 @@
+;;; lsp-prolog.el --- Prolog Client settings -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2020 James Cash
+
+;; Author: James Cash <james.nvc@gmail.com>
+;; Keywords: languages,tools
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; lsp-prolog client
+
+;;; Code:
+
+(require 'lsp-mode)
+
+(defgroup lsp-prolog nil
+ "LSP support for Prolog."
+ :link '(url-link "https://github.com/jamesnvc/lsp_server")
+ :group 'lsp-mode
+ :tag "Lsp Prolog")
+
+(defcustom lsp-prolog-server-command '("swipl"
+ "-g" "use_module(library(lsp_server))."
+ "-g" "lsp_server:main"
+ "-t" "halt"
+ "--" "stdio")
+ "The prolog-lsp server command."
+ :group 'lsp-prolog
+ :risky t
+ :type 'list)
+
+(lsp-register-client
+ (make-lsp-client
+ :new-connection (lsp-stdio-connection (lambda () lsp-prolog-server-command))
+ :major-modes '(prolog-mode)
+ :multi-root t
+ :server-id 'prolog-lsp))
+
+(lsp-consistency-check lsp-prolog)
+
+(provide 'lsp-prolog)
+;;; lsp-prolog.el ends here
diff --git a/elpa/lsp-mode-20220505.630/lsp-prolog.elc b/elpa/lsp-mode-20220505.630/lsp-prolog.elc
new file mode 100644
index 0000000..5496e1b
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-prolog.elc
Binary files differ
diff --git a/elpa/lsp-mode-20220505.630/lsp-protocol.el b/elpa/lsp-mode-20220505.630/lsp-protocol.el
new file mode 100644
index 0000000..1879aeb
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-protocol.el
@@ -0,0 +1,783 @@
+;;; lsp-protocol.el --- Language Sever Protocol Bindings -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2020 Ivan Yonchovski
+
+;; Author: Ivan Yonchovski <yyoncho@gmail.com>
+;; Keywords: convenience
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Autogenerated bindings from lsp4j using
+;; https://github.com/victools/jsonschema-generator+scrips to generate
+;; scripts/generated.protocol.schema.json and then
+;; scripts/lsp-generate-bindings.el
+
+;;; Code:
+
+(require 'cl-lib)
+(require 'dash)
+(require 'ht)
+(require 's)
+
+(eval-and-compile
+ (defun lsp-keyword->symbol (keyword)
+ "Convert a KEYWORD to symbol."
+ (intern (substring (symbol-name keyword) 1)))
+
+ (defun lsp-keyword->string (keyword)
+ "Convert a KEYWORD to string."
+ (substring (symbol-name keyword) 1))
+
+ (defvar lsp-use-plists (getenv "LSP_USE_PLISTS")))
+
+(defmacro lsp-interface (&rest interfaces)
+ "Generate LSP bindings from INTERFACES triplet.
+
+Example usage with `dash`.
+
+\(-let [(&ApplyWorkspaceEditResponse
+ :failure-reason?) (ht (\"failureReason\" \"...\"))]
+ failure-reason?)
+
+\(fn (INTERFACE-NAME-1 REQUIRED-FIELDS-1 OPTIONAL-FIELDS-1) (INTERFACE-NAME-2 REQUIRED-FIELDS-2 OPTIONAL-FIELDS-2) ...)"
+ (with-case-table ascii-case-table
+ (->> interfaces
+ (-map (-lambda ((interface required optional))
+ (let ((params (nconc
+ (-map (lambda (param-name)
+ (cons
+ (intern (concat ":" (s-dashed-words (symbol-name param-name)) "?"))
+ param-name))
+ optional)
+ (-map (lambda (param-name)
+ (cons (intern (concat ":" (s-dashed-words (symbol-name param-name))))
+ param-name))
+ required))))
+ (cl-list*
+ `(defun ,(intern (format "dash-expand:&%s" interface)) (key source)
+ (unless (or (member key ',(-map #'cl-first params))
+ (s-starts-with? ":_" (symbol-name key)))
+ (error "Unknown key: %s. Available keys: %s" key ',(-map #'cl-first params)))
+ ,(if lsp-use-plists
+ ``(plist-get ,source
+ ,(if (s-starts-with? ":_" (symbol-name key))
+ key
+ (cl-rest (assoc key ',params))))
+ ``(gethash ,(if (s-starts-with? ":_" (symbol-name key))
+ (substring (symbol-name key) 1)
+ (substring (symbol-name
+ (cl-rest (assoc key ',params)))
+ 1))
+ ,source)))
+ `(defun ,(intern (format "dash-expand:&%s?" interface)) (key source)
+ (unless (member key ',(-map #'cl-first params))
+ (error "Unknown key: %s. Available keys: %s" key ',(-map #'cl-first params)))
+ ,(if lsp-use-plists
+ ``(plist-get ,source
+ ,(if (s-starts-with? ":_" (symbol-name key))
+ key
+ (cl-rest (assoc key ',params))))
+ ``(when (ht? ,source)
+ (gethash ,(substring (symbol-name
+ (cl-rest (assoc key ',params)))
+ 1)
+ ,source))))
+
+ `(defun ,(intern (format "lsp-%s?" (s-dashed-words (symbol-name interface)))) (object)
+ (cond
+ ((ht? object)
+ (-all? (let ((keys (ht-keys object)))
+ (lambda (prop)
+ (member prop keys)))
+ ',(-map (lambda (field-name)
+ (substring (symbol-name field-name) 1))
+ required)))
+ ((listp object) (-all? (lambda (prop)
+ (plist-member object prop))
+ ',required))))
+ `(cl-defun ,(intern (format "lsp-make-%s" (s-dashed-words (symbol-name interface))))
+ (&rest plist &key ,@(-map (-lambda ((key))
+ (intern (substring (symbol-name key) 1))) params)
+ &allow-other-keys)
+ (ignore ,@(-map (-lambda ((key))
+ (intern (substring (symbol-name key) 1))) params))
+ ,(format "Constructs %s from `plist.'
+Allowed params: %s" interface (reverse (-map #'cl-first params)))
+ ,(if lsp-use-plists
+ `(-mapcat (-lambda ((key value))
+ (list (or (cl-rest (assoc key ',params)) key) value))
+ (-partition 2 plist))
+ `(let (($$result (ht)))
+ (mapc (-lambda ((key value))
+ (puthash (lsp-keyword->string (or (cl-rest (assoc key ',params))
+ key))
+ value
+ $$result))
+ (-partition 2 plist))
+ $$result)))
+ `(pcase-defmacro ,interface (&rest property-bindings)
+ ,(if lsp-use-plists
+ ``(and
+ (pred listp)
+ ;; Check if all the types required by the
+ ;; interface exist in the expr-val.
+ ,@(-map
+ (lambda (key)
+ `(pred
+ (lambda (plist)
+ (plist-member plist ,key))))
+ ',required)
+ ;; Recursively generate the bindings.
+ ,@(let ((current-list property-bindings)
+ (output-bindings nil))
+ ;; Invariant: while current-list is
+ ;; non-nil, the car of current-list is
+ ;; always of the form :key, while the
+ ;; cadr of current-list is either a)
+ ;; nil, b) of the form :key-next or c)
+ ;; a pcase pattern that can
+ ;; recursively match an expression.
+ (while current-list
+ (-let* (((curr-binding-as-keyword next-entry . _) current-list)
+ (curr-binding-as-camelcased-symbol
+ (or (alist-get curr-binding-as-keyword ',params)
+ (error "Unknown key: %s. Available keys: %s"
+ (symbol-name curr-binding-as-keyword)
+ ',(-map #'cl-first params))))
+ (bound-name (lsp-keyword->symbol curr-binding-as-keyword))
+ (next-entry-is-key-or-nil
+ (and (symbolp next-entry)
+ (or (null next-entry)
+ (s-starts-with? ":" (symbol-name next-entry))))))
+ (cond
+ ;; If the next-entry is either a
+ ;; plist-key or nil, then bind to
+ ;; bound-name the value corresponding
+ ;; to the camelcased symbol. Pop
+ ;; current-list once.
+ (next-entry-is-key-or-nil
+ (push `(app (lambda (plist)
+ (plist-get plist ,curr-binding-as-camelcased-symbol))
+ ,bound-name)
+ output-bindings)
+ (setf current-list (cdr current-list)))
+ ;; Otherwise, next-entry is a pcase
+ ;; pattern we recursively match to the
+ ;; expression. This can in general
+ ;; create additional bindings that we
+ ;; persist in the top level of
+ ;; bindings. We pop current-list
+ ;; twice.
+ (t
+ (push `(app (lambda (plist)
+ (plist-get plist ,curr-binding-as-camelcased-symbol))
+ ,next-entry)
+ output-bindings)
+ (setf current-list (cddr current-list))))))
+ output-bindings))
+ ``(and
+ (pred ht?)
+ ,@(-map
+ (lambda (key)
+ `(pred
+ (lambda (hash-table)
+ (ht-contains? hash-table ,(lsp-keyword->string key)))))
+ ',required)
+ ,@(let ((current-list property-bindings)
+ (output-bindings nil))
+ (while current-list
+ (-let* (((curr-binding-as-keyword next-entry . _) current-list)
+ (curr-binding-as-camelcased-string
+ (lsp-keyword->string (or (alist-get curr-binding-as-keyword ',params)
+ (error "Unknown key: %s. Available keys: %s"
+ (symbol-name curr-binding-as-keyword)
+ ',(-map #'cl-first params)))))
+ (bound-name (lsp-keyword->symbol curr-binding-as-keyword))
+ (next-entry-is-key-or-nil
+ (and (symbolp next-entry)
+ (or (null next-entry)
+ (s-starts-with? ":" (symbol-name next-entry))))))
+ (cond
+ (next-entry-is-key-or-nil
+ (push `(app (lambda (hash-table)
+ (ht-get hash-table ,curr-binding-as-camelcased-string))
+ ,bound-name)
+ output-bindings)
+ (setf current-list (cdr current-list)))
+ (t
+ (push `(app (lambda (hash-table)
+ (ht-get hash-table ,curr-binding-as-camelcased-string))
+ ,next-entry)
+ output-bindings)
+ (setf current-list (cddr current-list))))))
+ output-bindings))))
+ (-mapcat (-lambda ((label . name))
+ (list
+ `(defun ,(intern (format "lsp:%s-%s"
+ (s-dashed-words (symbol-name interface))
+ (substring (symbol-name label) 1)))
+ (object)
+ ,(if lsp-use-plists
+ `(plist-get object ,name)
+ `(when (ht? object) (gethash ,(lsp-keyword->string name) object))))
+ `(defun ,(intern (format "lsp:set-%s-%s"
+ (s-dashed-words (symbol-name interface))
+ (substring (symbol-name label) 1)))
+ (object value)
+ ,@(if lsp-use-plists
+ `((plist-put object ,name value))
+ `((puthash ,(lsp-keyword->string name) value object)
+ object)))))
+ params)))))
+ (apply #'append)
+ (cl-list* 'progn))))
+
+(if lsp-use-plists
+ (progn
+ (defun lsp-get (from key)
+ (plist-get from key))
+ (defun lsp-put (where key value)
+ (plist-put where key value))
+ (defun lsp-map (fn value)
+ (-map (-lambda ((k v))
+ (funcall fn (lsp-keyword->string k) v))
+ (-partition 2 value )))
+ (defalias 'lsp-merge 'append)
+ (defalias 'lsp-empty? 'null)
+ (defalias 'lsp-copy 'copy-sequence)
+ (defun lsp-member? (from key)
+ (when (listp from)
+ (plist-member from key))))
+ (defun lsp-get (from key)
+ (when from
+ (gethash (lsp-keyword->string key) from)))
+ (defun lsp-put (where key value)
+ (prog1 where
+ (puthash (lsp-keyword->string key) value where)))
+ (defun lsp-map (fn value)
+ (when value
+ (maphash fn value)))
+ (defalias 'lsp-merge 'ht-merge)
+ (defalias 'lsp-empty? 'ht-empty?)
+ (defalias 'lsp-copy 'ht-copy)
+ (defun lsp-member? (from key)
+ (when (hash-table-p from)
+ (not (eq (gethash (lsp-keyword->string key) from :__lsp_default)
+ :__lsp_default)))))
+
+(defmacro lsp-defun (name match-form &rest body)
+ "Define a function named NAME.
+The function destructures its input as MATCH-FORM then executes BODY.
+
+Note that you have to enclose the MATCH-FORM in a pair of parens,
+such that:
+
+ (-defun (x) body)
+ (-defun (x y ...) body)
+
+has the usual semantics of `defun'. Furthermore, these get
+translated into a normal `defun', so there is no performance
+penalty.
+
+See `-let' for a description of the destructuring mechanism."
+ (declare (doc-string 3) (indent defun)
+ (debug (&define name sexp
+ [&optional stringp]
+ [&optional ("declare" &rest sexp)]
+ [&optional ("interactive" interactive)]
+ def-body)))
+ (cond
+ ((nlistp match-form)
+ (signal 'wrong-type-argument (list #'listp match-form)))
+ ;; no destructuring, so just return regular defun to make things faster
+ ((-all? #'symbolp match-form)
+ `(defun ,name ,match-form ,@body))
+ (t
+ (-let* ((inputs (--map-indexed (list it (make-symbol (format "input%d" it-index))) match-form))
+ ((body docs) (cond
+ ;; only docs
+ ((and (stringp (car body))
+ (not (cdr body)))
+ (list body (car body)))
+ ;; docs + body
+ ((stringp (car body))
+ (list (cdr body) (car body)))
+ ;; no docs
+ (t (list body))))
+ ((body interactive-form) (cond
+ ;; interactive form
+ ((and (listp (car body))
+ (eq (caar body) 'interactive))
+ (list (cdr body) (car body)))
+ ;; no interactive form
+ (t (list body)))))
+ ;; TODO: because inputs to the defun are evaluated only once,
+ ;; -let* need not to create the extra bindings to ensure that.
+ ;; We should find a way to optimize that. Not critical however.
+ `(defun ,name ,(-map #'cadr inputs)
+ ,@(when docs (list docs))
+ ,@(when interactive-form (list interactive-form))
+ (-let* ,inputs ,@body))))))
+
+
+
+
+;; manually defined interfaces
+(defconst lsp/markup-kind-plain-text "plaintext")
+(defconst lsp/markup-kind-markdown "markdown")
+
+(lsp-interface (JSONResponse (:params :id :method :result) nil)
+ (JSONResponseError (:error) nil)
+ (JSONMessage nil (:params :id :method :result :error))
+ (JSONResult nil (:params :id :method))
+ (JSONNotification (:params :method) nil)
+ (JSONRequest (:params :method) nil)
+ (JSONError (:message :code) (:data))
+ (ProgressParams (:token :value) nil)
+ (Edit (:kind) nil)
+ (WorkDoneProgress (:kind) nil)
+ (WorkDoneProgressBegin (:kind :title) (:cancellable :message :percentage))
+ (WorkDoneProgressReport (:kind) (:cancellable :message :percentage))
+ (WorkDoneProgressEnd (:kind) (:message))
+ (WorkDoneProgressOptions nil (:workDoneProgress))
+ (SemanticTokensOptions (:legend) (:rangeProvider :documentProvider))
+ (SemanticTokensLegend (:tokenTypes :tokenModifiers))
+ (SemanticTokensResult (:resultId) (:data))
+ (SemanticTokensPartialResult nil (:data))
+ (SemanticTokensEdit (:start :deleteCount) (:data))
+ (SemanticTokensDelta (:resultId) (:edits))
+ (SemanticTokensDeltaPartialResult nil (:edits)))
+
+(lsp-interface (v1:ProgressParams (:id :title) (:message :percentage :done)))
+
+(defun dash-expand:&RangeToPoint (key source)
+ "Convert the position KEY from SOURCE into a point."
+ `(lsp--position-to-point
+ (lsp-get ,source ,key)))
+
+(lsp-interface (eslint:StatusParams (:state) nil)
+ (eslint:OpenESLintDocParams (:url) nil)
+ (eslint:ConfirmExecutionParams (:scope :file :libraryPath) nil))
+
+(lsp-interface (haxe:ProcessStartNotification (:title) nil))
+
+(lsp-interface (pwsh:ScriptRegion (:StartLineNumber :EndLineNumber :StartColumnNumber :EndColumnNumber :Text) nil))
+
+(lsp-interface (omnisharp:ErrorMessage (:Text :FileName :Line :Column))
+ (omnisharp:ProjectInformationRequest (:FileName))
+ (omnisharp:MsBuildProject (:IsUnitProject :IsExe :Platform :Configuration :IntermediateOutputPath :OutputPath :TargetFrameworks :SourceFiles :TargetFramework :TargetPath :AssemblyName :Path :ProjectGuid))
+ (omnisharp:ProjectInformation (:ScriptProject :MsBuildProject))
+ (omnisharp:CodeStructureRequest (:FileName))
+ (omnisharp:CodeStructureResponse (:Elements))
+ (omnisharp:CodeElement (:Kind :Name :DisplayName :Children :Ranges :Properties))
+ (omnisharp:CodeElementProperties () (:static :accessibility :testMethodName :testFramework))
+ (omnisharp:Range (:Start :End))
+ (omnisharp:RangeList () (:attributes :full :name))
+ (omnisharp:Point (:Line :Column))
+ (omnisharp:RunTestsInClassRequest (:MethodNames :RunSettings :TestFrameworkname :TargetFrameworkVersion :NoBuild :Line :Column :Buffer :FileName))
+ (omnisharp:RunTestResponse (:Results :Pass :Failure :ContextHadNoTests))
+ (omnisharp:TestMessageEvent (:MessageLevel :Message))
+ (omnisharp:DotNetTestResult (:MethodName :Outcome :ErrorMessage :ErrorStackTrace :StandardOutput :StandardError)))
+
+(lsp-interface (csharp-ls:CSharpMetadata (:textDocument))
+ (csharp-ls:CSharpMetadataResponse (:source :projectName :assemblyName :symbolName)))
+
+(lsp-interface (rls:Cmd (:args :binary :env :cwd) nil))
+
+(defconst lsp/rust-analyzer-inlay-hint-kind-type-hint 1)
+(defconst lsp/rust-analyzer-inlay-hint-kind-param-hint 2)
+(defconst lsp/rust-analyzer-inlay-hint-kind-nonstandard-hint nil)
+(lsp-interface (rust-analyzer:AnalyzerStatusParams (:textDocument))
+ (rust-analyzer:SyntaxTreeParams (:textDocument) (:range))
+ (rust-analyzer:ExpandMacroParams (:textDocument :position) nil)
+ (rust-analyzer:ExpandedMacro (:name :expansion) nil)
+ (rust-analyzer:MatchingBraceParams (:textDocument :positions) nil)
+ (rust-analyzer:OpenCargoTomlParams (:textDocument) nil)
+ (rust-analyzer:OpenExternalDocsParams (:textDocument :position) nil)
+ (rust-analyzer:ResovedCodeActionParams (:id :codeActionParams) nil)
+ (rust-analyzer:JoinLinesParams (:textDocument :ranges) nil)
+ (rust-analyzer:MoveItemParams (:textDocument :range :direction) nil)
+ (rust-analyzer:RunnablesParams (:textDocument) (:position))
+ (rust-analyzer:Runnable (:label :kind :args) (:location))
+ (rust-analyzer:RunnableArgs (:cargoArgs :executableArgs) (:workspaceRoot))
+ (rust-analyzer:RelatedTestsParams (:textDocument :position) nil)
+ (rust-analyzer:RelatedTests (:runnable) nil)
+ (rust-analyzer:InlayHint (:position :label :kind :paddingLeft :paddingRight) nil)
+ (rust-analyzer:InlayHintsParams (:textDocument :range) nil)
+ (rust-analyzer:SsrParams (:query :parseOnly) nil)
+ (rust-analyzer:CommandLink (:title :command) (:arguments :tooltip))
+ (rust-analyzer:CommandLinkGroup (:commands) (:title)))
+
+(defconst lsp/javascript-inlay-hint-kind-type-hint "Type")
+(defconst lsp/javascript-inlay-hint-kind-parameter-hint "Parameter")
+(defconst lsp/javascript-inlay-hint-kind-enum-hint "Enum")
+(lsp-interface (javascript:InlayHint (:text :position :kind) (:whitespaceBefore :whitespaceAfter))
+ (javascript:InlayHintsParams (:textDocument) (:range)))
+
+(lsp-interface (clojure-lsp:TestTreeParams (:uri :tree) nil)
+ (clojure-lsp:TestTreeNode (:name :range :nameRange :kind) (:children)))
+
+
+;; begin autogenerated code
+
+(defvar lsp/completion-item-kind-lookup
+ [nil Text Method Function Constructor Field Variable Class Interface Module Property Unit Value Enum Keyword Snippet Color File Reference Folder EnumMember Constant Struct Event Operator TypeParameter])
+(defconst lsp/completion-item-kind-text 1)
+(defconst lsp/completion-item-kind-method 2)
+(defconst lsp/completion-item-kind-function 3)
+(defconst lsp/completion-item-kind-constructor 4)
+(defconst lsp/completion-item-kind-field 5)
+(defconst lsp/completion-item-kind-variable 6)
+(defconst lsp/completion-item-kind-class 7)
+(defconst lsp/completion-item-kind-interface 8)
+(defconst lsp/completion-item-kind-module 9)
+(defconst lsp/completion-item-kind-property 10)
+(defconst lsp/completion-item-kind-unit 11)
+(defconst lsp/completion-item-kind-value 12)
+(defconst lsp/completion-item-kind-enum 13)
+(defconst lsp/completion-item-kind-keyword 14)
+(defconst lsp/completion-item-kind-snippet 15)
+(defconst lsp/completion-item-kind-color 16)
+(defconst lsp/completion-item-kind-file 17)
+(defconst lsp/completion-item-kind-reference 18)
+(defconst lsp/completion-item-kind-folder 19)
+(defconst lsp/completion-item-kind-enum-member 20)
+(defconst lsp/completion-item-kind-constant 21)
+(defconst lsp/completion-item-kind-struct 22)
+(defconst lsp/completion-item-kind-event 23)
+(defconst lsp/completion-item-kind-operator 24)
+(defconst lsp/completion-item-kind-type-parameter 25)
+(defvar lsp/completion-trigger-kind-lookup
+ [nil Invoked TriggerCharacter TriggerForIncompleteCompletions])
+(defconst lsp/completion-trigger-kind-invoked 1)
+(defconst lsp/completion-trigger-kind-trigger-character 2)
+(defconst lsp/completion-trigger-kind-trigger-for-incomplete-completions 3)
+(defvar lsp/diagnostic-severity-lookup
+ [nil Error Warning Information Hint Max])
+(defconst lsp/diagnostic-severity-error 1)
+(defconst lsp/diagnostic-severity-warning 2)
+(defconst lsp/diagnostic-severity-information 3)
+(defconst lsp/diagnostic-severity-hint 4)
+(defconst lsp/diagnostic-severity-max 5)
+(defvar lsp/diagnostic-tag-lookup
+ [nil Unnecessary Deprecated])
+(defconst lsp/diagnostic-tag-unnecessary 1)
+(defconst lsp/diagnostic-tag-deprecated 2)
+(defvar lsp/completion-item-tag-lookup
+ [nil Deprecated])
+(defconst lsp/completion-item-tag-deprecated 1)
+(defvar lsp/document-highlight-kind-lookup
+ [nil Text Read Write])
+(defconst lsp/document-highlight-kind-text 1)
+(defconst lsp/document-highlight-kind-read 2)
+(defconst lsp/document-highlight-kind-write 3)
+(defvar lsp/file-change-type-lookup
+ [nil Created Changed Deleted])
+(defconst lsp/file-change-type-created 1)
+(defconst lsp/file-change-type-changed 2)
+(defconst lsp/file-change-type-deleted 3)
+(defvar lsp/insert-text-format-lookup
+ [nil PlainText Snippet])
+(defconst lsp/insert-text-format-plain-text 1)
+(defconst lsp/insert-text-format-snippet 2)
+(defvar lsp/insert-text-mode-lookup
+ [nil AsIs AdjustIndentation])
+(defconst lsp/insert-text-mode-as-it 1)
+(defconst lsp/insert-text-mode-adjust-indentation 2)
+(defvar lsp/message-type-lookup
+ [nil Error Warning Info Log])
+(defconst lsp/message-type-error 1)
+(defconst lsp/message-type-warning 2)
+(defconst lsp/message-type-info 3)
+(defconst lsp/message-type-log 4)
+(defvar lsp/signature-help-trigger-kind-lookup
+ [nil Invoked TriggerCharacter ContentChange])
+(defconst lsp/signature-help-trigger-kind-invoked 1)
+(defconst lsp/signature-help-trigger-kind-trigger-character 2)
+(defconst lsp/signature-help-trigger-kind-content-change 3)
+(defvar lsp/symbol-kind-lookup
+ [nil File Module Namespace Package Class Method Property Field Constructor Enum Interface Function Variable Constant String Number Boolean Array Object Key Null EnumMember Struct Event Operator TypeParameter])
+(defconst lsp/symbol-kind-file 1)
+(defconst lsp/symbol-kind-module 2)
+(defconst lsp/symbol-kind-namespace 3)
+(defconst lsp/symbol-kind-package 4)
+(defconst lsp/symbol-kind-class 5)
+(defconst lsp/symbol-kind-method 6)
+(defconst lsp/symbol-kind-property 7)
+(defconst lsp/symbol-kind-field 8)
+(defconst lsp/symbol-kind-constructor 9)
+(defconst lsp/symbol-kind-enum 10)
+(defconst lsp/symbol-kind-interface 11)
+(defconst lsp/symbol-kind-function 12)
+(defconst lsp/symbol-kind-variable 13)
+(defconst lsp/symbol-kind-constant 14)
+(defconst lsp/symbol-kind-string 15)
+(defconst lsp/symbol-kind-number 16)
+(defconst lsp/symbol-kind-boolean 17)
+(defconst lsp/symbol-kind-array 18)
+(defconst lsp/symbol-kind-object 19)
+(defconst lsp/symbol-kind-key 20)
+(defconst lsp/symbol-kind-null 21)
+(defconst lsp/symbol-kind-enum-member 22)
+(defconst lsp/symbol-kind-struct 23)
+(defconst lsp/symbol-kind-event 24)
+(defconst lsp/symbol-kind-operator 25)
+(defconst lsp/symbol-kind-type-parameter 26)
+(defvar lsp/text-document-save-reason-lookup
+ [nil Manual AfterDelay FocusOut])
+(defconst lsp/text-document-save-reason-manual 1)
+(defconst lsp/text-document-save-reason-after-delay 2)
+(defconst lsp/text-document-save-reason-focus-out 3)
+(defvar lsp/text-document-sync-kind-lookup
+ [None Full Incremental])
+(defconst lsp/text-document-sync-kind-none 0)
+(defconst lsp/text-document-sync-kind-full 1)
+(defconst lsp/text-document-sync-kind-incremental 2)
+(defvar lsp/type-hierarchy-direction-lookup
+ [nil Children Parents Both])
+(defconst lsp/type-hierarchy-direction-children 1)
+(defconst lsp/type-hierarchy-direction-parents 2)
+(defconst lsp/type-hierarchy-direction-both 3)
+(defvar lsp/call-hierarchy-direction-lookup
+ [nil CallsFrom CallsTo])
+(defconst lsp/call-hierarchy-direction-calls-from 1)
+(defconst lsp/call-hierarchy-direction-calls-to 2)
+(defvar lsp/response-error-code-lookup
+ [nil ParseError InvalidRequest MethodNotFound InvalidParams InternalError serverErrorStart serverErrorEnd])
+(defconst lsp/response-error-code-parse-error 1)
+(defconst lsp/response-error-code-invalid-request 2)
+(defconst lsp/response-error-code-method-not-found 3)
+(defconst lsp/response-error-code-invalid-params 4)
+(defconst lsp/response-error-code-internal-error 5)
+(defconst lsp/response-error-code-server-error-start 6)
+(defconst lsp/response-error-code-server-error-end 7)
+
+(lsp-interface
+ (CallHierarchyCapabilities nil (:dynamicRegistration))
+ (CallHierarchyItem (:kind :name :range :selectionRange :uri) (:detail :tags))
+ (ClientCapabilities nil (:experimental :textDocument :workspace))
+ (ClientInfo (:name) (:version))
+ (CodeActionCapabilities nil (:codeActionLiteralSupport :dynamicRegistration :isPreferredSupport :dataSupport :resolveSupport))
+ (CodeActionContext (:diagnostics) (:only))
+ (CodeActionKindCapabilities (:valueSet) nil)
+ (CodeActionLiteralSupportCapabilities nil (:codeActionKind))
+ (CodeActionOptions nil (:codeActionKinds :resolveProvider))
+ (CodeLensCapabilities nil (:dynamicRegistration))
+ (CodeLensOptions (:resolveProvider) nil)
+ (Color (:red :green :blue :alpha) nil)
+ (ColorProviderCapabilities nil (:dynamicRegistration))
+ (ColorProviderOptions nil (:documentSelector :id))
+ (ColoringInformation (:range :styles) nil)
+ (Command (:title :command) (:arguments))
+ (CompletionCapabilities nil (:completionItem :completionItemKind :contextSupport :dynamicRegistration))
+ (CompletionContext (:triggerKind) (:triggerCharacter))
+ (CompletionItem (:label) (:additionalTextEdits :command :commitCharacters :data :deprecated :detail :documentation :filterText :insertText :insertTextFormat :insertTextMode :kind :preselect :sortText :tags :textEdit :score :labelDetails))
+ (CompletionItemCapabilities nil (:commitCharactersSupport :deprecatedSupport :documentationFormat :preselectSupport :snippetSupport :tagSupport :insertReplaceSupport :resolveSupport))
+ (CompletionItemKindCapabilities nil (:valueSet))
+ (CompletionItemTagSupportCapabilities (:valueSet) nil)
+ (CompletionOptions nil (:resolveProvider :triggerCharacters :allCommitCharacters))
+ (ConfigurationItem nil (:scopeUri :section))
+ (CreateFileOptions nil (:ignoreIfExists :overwrite))
+ (DeclarationCapabilities nil (:dynamicRegistration :linkSupport))
+ (DefinitionCapabilities nil (:dynamicRegistration :linkSupport))
+ (DeleteFileOptions nil (:ignoreIfNotExists :recursive))
+ (Diagnostic (:range :message) (:code :relatedInformation :severity :source :tags))
+ (DiagnosticRelatedInformation (:location :message) nil)
+ (DiagnosticsTagSupport (:valueSet) nil)
+ (DidChangeConfigurationCapabilities nil (:dynamicRegistration))
+ (DidChangeWatchedFilesCapabilities nil (:dynamicRegistration))
+ (DocumentFilter nil (:language :pattern :scheme))
+ (DocumentHighlightCapabilities nil (:dynamicRegistration))
+ (DocumentLinkCapabilities nil (:dynamicRegistration :tooltipSupport))
+ (DocumentLinkOptions nil (:resolveProvider))
+ (DocumentOnTypeFormattingOptions (:firstTriggerCharacter) (:moreTriggerCharacter))
+ (DocumentSymbol (:kind :name :range :selectionRange) (:children :deprecated :detail))
+ (DocumentSymbolCapabilities nil (:dynamicRegistration :hierarchicalDocumentSymbolSupport :symbolKind))
+ (ExecuteCommandCapabilities nil (:dynamicRegistration))
+ (ExecuteCommandOptions (:commands) nil)
+ (FileEvent (:type :uri) nil)
+ (FileSystemWatcher (:globPattern) (:kind))
+ (FileOperationFilter (:pattern) (:scheme))
+ (FileOperationPattern (:glob) (:matches :options))
+ (FileOperationPatternOptions nil (:ignoreCase))
+ (FileOperationRegistrationOptions (:filters) nil)
+ (FoldingRangeCapabilities nil (:dynamicRegistration :lineFoldingOnly :rangeLimit))
+ (FoldingRangeProviderOptions nil (:documentSelector :id))
+ (FormattingCapabilities nil (:dynamicRegistration))
+ (FormattingOptions (:tabSize :insertSpaces) (:trimTrailingWhitespace :insertFinalNewline :trimFinalNewlines))
+ (HoverCapabilities nil (:contentFormat :dynamicRegistration))
+ (ImplementationCapabilities nil (:dynamicRegistration :linkSupport))
+ (LabelDetails (:detail :description) nil)
+ (LinkedEditingRanges (:ranges) (:wordPattern))
+ (Location (:range :uri) nil)
+ (MarkedString (:language :value) nil)
+ (MarkupContent (:kind :value) nil)
+ (MessageActionItem (:title) nil)
+ (OnTypeFormattingCapabilities nil (:dynamicRegistration))
+ (ParameterInformation (:label) (:documentation))
+ (ParameterInformationCapabilities nil (:labelOffsetSupport))
+ (Position (:character :line) nil)
+ (PublishDiagnosticsCapabilities nil (:relatedInformation :tagSupport :versionSupport))
+ (Range (:start :end) nil)
+ (RangeFormattingCapabilities nil (:dynamicRegistration))
+ (ReferenceContext (:includeDeclaration) nil)
+ (ReferencesCapabilities nil (:dynamicRegistration))
+ (Registration (:method :id) (:registerOptions))
+ (RenameCapabilities nil (:dynamicRegistration :prepareSupport))
+ (RenameFileOptions nil (:ignoreIfExists :overwrite))
+ (RenameOptions nil (:documentSelector :id :prepareProvider))
+ (ResourceChange nil (:current :newUri))
+ (ResourceOperation (:kind) nil)
+ (SaveOptions nil (:includeText))
+ (SelectionRange (:range) (:parent))
+ (SelectionRangeCapabilities nil (:dynamicRegistration))
+ (SemanticHighlightingCapabilities nil (:semanticHighlighting))
+ (SemanticHighlightingInformation (:line) (:tokens))
+ (SemanticHighlightingServerCapabilities nil (:scopes))
+ (ServerCapabilities nil (:callHierarchyProvider :codeActionProvider :codeLensProvider :colorProvider :completionProvider :declarationProvider :definitionProvider :documentFormattingProvider :documentHighlightProvider :documentLinkProvider :documentOnTypeFormattingProvider :documentRangeFormattingProvider :documentSymbolProvider :executeCommandProvider :experimental :foldingRangeProvider :hoverProvider :implementationProvider :referencesProvider :renameProvider :selectionRangeProvider :semanticHighlighting :signatureHelpProvider :textDocumentSync :typeDefinitionProvider :typeHierarchyProvider :workspace :workspaceSymbolProvider :semanticTokensProvider))
+ (ServerInfo (:name) (:version))
+ (SignatureHelp (:signatures) (:activeParameter :activeSignature))
+ (SignatureHelpCapabilities nil (:contextSupport :dynamicRegistration :signatureInformation))
+ (SignatureHelpContext (:triggerKind :isRetrigger) (:activeSignatureHelp :triggerCharacter))
+ (SignatureHelpOptions nil (:retriggerCharacters :triggerCharacters))
+ (SignatureInformation (:label) (:documentation :parameters))
+ (SignatureInformationCapabilities nil (:documentationFormat :parameterInformation))
+ (StaticRegistrationOptions nil (:documentSelector :id))
+ (SymbolCapabilities nil (:dynamicRegistration :symbolKind))
+ (SymbolKindCapabilities nil (:valueSet))
+ (SynchronizationCapabilities nil (:didSave :dynamicRegistration :willSave :willSaveWaitUntil))
+ (TextDocumentClientCapabilities nil (:callHierarchy :codeAction :codeLens :colorProvider :completion :declaration :definition :documentHighlight :documentLink :documentSymbol :foldingRange :formatting :hover :implementation :onTypeFormatting :publishDiagnostics :rangeFormatting :references :rename :selectionRange :semanticHighlightingCapabilities :signatureHelp :synchronization :typeDefinition :typeHierarchyCapabilities))
+ (TextDocumentContentChangeEvent (:text) (:range :rangeLength))
+ (TextDocumentEdit (:textDocument :edits) nil)
+ (TextDocumentIdentifier (:uri) nil)
+ (TextDocumentItem (:languageId :text :uri :version) nil)
+ (TextDocumentSyncOptions nil (:change :openClose :save :willSave :willSaveWaitUntil))
+ (TextEdit (:newText :range) nil)
+ (InsertReplaceEdit (:newText :insert :replace) nil)
+ (SnippetTextEdit (:newText :range) (:insertTextFormat))
+ (TypeDefinitionCapabilities nil (:dynamicRegistration :linkSupport))
+ (TypeHierarchyCapabilities nil (:dynamicRegistration))
+ (TypeHierarchyItem (:kind :name :range :selectionRange :uri) (:children :data :deprecated :detail :parents))
+ (Unregistration (:method :id) nil)
+ (VersionedTextDocumentIdentifier (:uri) (:version))
+ (WorkspaceClientCapabilities nil (:applyEdit :configuration :didChangeConfiguration :didChangeWatchedFiles :executeCommand :symbol :workspaceEdit :workspaceFolders))
+ (WorkspaceEdit nil (:changes :documentChanges :resourceChanges))
+ (WorkspaceEditCapabilities nil (:documentChanges :failureHandling :resourceChanges :resourceOperations))
+ (WorkspaceFolder (:uri :name) nil)
+ (WorkspaceFoldersChangeEvent (:removed :added) nil)
+ (WorkspaceFoldersOptions nil (:changeNotifications :supported))
+ (WorkspaceServerCapabilities nil (:workspaceFolders :fileOperations))
+ (WorkspaceFileOperations nil (:didCreate :willCreate :didRename :willRename :didDelete :willDelete))
+ (ApplyWorkspaceEditParams (:edit) (:label))
+ (ApplyWorkspaceEditResponse (:applied) nil)
+ (CallHierarchyIncomingCall (:from :fromRanges) nil)
+ (CallHierarchyIncomingCallsParams (:item) nil)
+ (CallHierarchyOutgoingCall (:to :fromRanges) nil)
+ (CallHierarchyOutgoingCallsParams (:item) nil)
+ (CallHierarchyPrepareParams (:textDocument :position) (:uri))
+ (CodeAction (:title) (:command :diagnostics :edit :isPreferred :kind :data))
+ (CodeActionKind nil nil)
+ (CodeActionParams (:textDocument :context :range) nil)
+ (CodeLens (:range) (:command :data))
+ (CodeLensParams (:textDocument) nil)
+ (CodeLensRegistrationOptions nil (:documentSelector :resolveProvider))
+ (ColorInformation (:color :range) nil)
+ (ColorPresentation (:label) (:additionalTextEdits :textEdit))
+ (ColorPresentationParams (:color :textDocument :range) nil)
+ (ColoringParams (:uri :infos) nil)
+ (ColoringStyle nil nil)
+ (CompletionList (:items :isIncomplete) nil)
+ (CompletionParams (:textDocument :position) (:context :uri))
+ (CompletionRegistrationOptions nil (:documentSelector :resolveProvider :triggerCharacters))
+ (ConfigurationParams (:items) nil)
+ (CreateFile (:kind :uri) (:options))
+ (DeclarationParams (:textDocument :position) (:uri))
+ (DefinitionParams (:textDocument :position) (:uri))
+ (DeleteFile (:kind :uri) (:options))
+ (DidChangeConfigurationParams (:settings) nil)
+ (DidChangeTextDocumentParams (:contentChanges :textDocument) (:uri))
+ (DidChangeWatchedFilesParams (:changes) nil)
+ (DidChangeWatchedFilesRegistrationOptions (:watchers) nil)
+ (DidChangeWorkspaceFoldersParams (:event) nil)
+ (DidCloseTextDocumentParams (:textDocument) nil)
+ (DidOpenTextDocumentParams (:textDocument) (:text))
+ (DidSaveTextDocumentParams (:textDocument) (:text))
+ (DocumentColorParams (:textDocument) nil)
+ (DocumentFormattingParams (:textDocument :options) nil)
+ (DocumentHighlight (:range) (:kind))
+ (DocumentHighlightParams (:textDocument :position) (:uri))
+ (DocumentLink (:range) (:data :target :tooltip))
+ (DocumentLinkParams (:textDocument) nil)
+ (DocumentLinkRegistrationOptions nil (:documentSelector :resolveProvider))
+ (DocumentOnTypeFormattingParams (:ch :textDocument :options :position) nil)
+ (DocumentOnTypeFormattingRegistrationOptions (:firstTriggerCharacter) (:documentSelector :moreTriggerCharacter))
+ (DocumentRangeFormattingParams (:textDocument :options :range) nil)
+ (DocumentSymbolParams (:textDocument) nil)
+ (DynamicRegistrationCapabilities nil (:dynamicRegistration))
+ (ExecuteCommandParams (:command) (:arguments))
+ (ExecuteCommandRegistrationOptions (:commands) nil)
+ (FailureHandlingKind nil nil)
+ (FileRename (:oldUri :newUri) nil)
+ (FoldingRange (:endLine :startLine) (:endCharacter :kind :startCharacter))
+ (FoldingRangeKind nil nil)
+ (FoldingRangeRequestParams (:textDocument) nil)
+ (Hover (:contents) (:range))
+ (HoverParams (:textDocument :position) (:uri))
+ (ImplementationParams (:textDocument :position) (:uri))
+ (InitializeError (:retry) nil)
+ (InitializeErrorCode nil nil)
+ (InitializeParams nil (:capabilities :clientInfo :clientName :initializationOptions :processId :rootPath :rootUri :trace :workspaceFolders))
+ (InitializeResult (:capabilities) (:serverInfo))
+ (InitializedParams nil nil)
+ (LocationLink (:targetSelectionRange :targetUri :targetRange) (:originSelectionRange))
+ (MarkupKind nil nil)
+ (MessageParams (:type :message) nil)
+ (PrepareRenameParams (:textDocument :position) (:uri))
+ (PrepareRenameResult (:range :placeholder) nil)
+ (PublishDiagnosticsParams (:diagnostics :uri) (:version))
+ (QuickPickItem (:label :picked :userData) nil)
+ (ReferenceParams (:textDocument :context :position) (:uri))
+ (RegistrationParams (:registrations) nil)
+ (RenameFile (:kind :newUri :oldUri) (:options))
+ (RenameFilesParams (:files) nil)
+ (RenameParams (:newName :textDocument :position) (:uri))
+ (ResolveTypeHierarchyItemParams (:item :resolve :direction) nil)
+ (ResourceOperationKind nil nil)
+ (SelectionRangeParams (:textDocument :positions) nil)
+ (SemanticHighlightingParams (:textDocument :lines) nil)
+ (ShowDocumentParams (:uri) (:external :takeFocus :selection))
+ (ShowDocumentResult (:success) nil)
+ (ShowInputBoxParams (:prompt) (:value))
+ (ShowMessageRequestParams (:type :message) (:actions))
+ (ShowQuickPickParams (:placeHolder :canPickMany :items) nil)
+ (SignatureHelpParams (:textDocument :position) (:context :uri))
+ (SignatureHelpRegistrationOptions nil (:documentSelector :triggerCharacters))
+ (SymbolInformation (:kind :name :location) (:containerName :deprecated))
+ (TextDocumentChangeRegistrationOptions (:syncKind) (:documentSelector))
+ (TextDocumentPositionParams (:textDocument :position) (:uri))
+ (TextDocumentRegistrationOptions nil (:documentSelector))
+ (TextDocumentSaveRegistrationOptions nil (:documentSelector :includeText))
+ (TypeDefinitionParams (:textDocument :position) (:uri))
+ (TypeHierarchyParams (:resolve :textDocument :position) (:direction :uri))
+ (UnregistrationParams (:unregisterations) nil)
+ (WatchKind nil nil)
+ (WillSaveTextDocumentParams (:reason :textDocument) nil)
+ (WorkspaceSymbolParams (:query) nil))
+
+
+(provide 'lsp-protocol)
+
+;;; lsp-protocol.el ends here
diff --git a/elpa/lsp-mode-20220505.630/lsp-protocol.elc b/elpa/lsp-mode-20220505.630/lsp-protocol.elc
new file mode 100644
index 0000000..daecf26
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-protocol.elc
Binary files differ
diff --git a/elpa/lsp-mode-20220505.630/lsp-purescript.el b/elpa/lsp-mode-20220505.630/lsp-purescript.el
new file mode 100644
index 0000000..7099eae
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-purescript.el
@@ -0,0 +1,86 @@
+;;; lsp-purescript.el --- description -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2020 emacs-lsp maintainers
+
+;; Author: emacs-lsp maintainers
+;; Keywords: lsp, purescript
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; LSP Clients for the PureScript Programming Language.
+
+;;; Code:
+
+(require 'lsp-mode)
+
+(defgroup lsp-purescript nil
+ "LSP support for PureScript, using purescript-language-server."
+ :group 'lsp-mode
+ :link '(url-link "https://github.com/nwolverson/purescript-language-server"))
+
+(defcustom lsp-purescript-server-executable nil
+ "Path to server executable."
+ :type 'string
+ :risky t
+ :group 'lsp-purescript)
+
+(defcustom lsp-purescript-server-args
+ '("--stdio")
+ "Arguments to pass to the server."
+ :type '(repeat string)
+ :risky t
+ :group 'lsp-purescript)
+
+(defun lsp-purescript--server-command ()
+ "Generate LSP startup command for purescript-language-server."
+ (cons (or lsp-purescript-server-executable
+ (lsp-package-path 'purescript-language-server))
+ lsp-purescript-server-args))
+
+(defcustom-lsp lsp-purescript-add-spago-sources t
+ "Whether to add spago sources to the globs passed to the IDE server for source locations."
+ :type 'boolean
+ :group 'lsp-purescript
+ :package-version '(lsp-mode . "8.0.1")
+ :lsp-path "purescript.addSpagoSources")
+
+(defcustom-lsp lsp-purescript-add-npm-path nil
+ "Whether to add the local npm bin directory to the PATH."
+ :type 'boolean
+ :group 'lsp-purescript
+ :package-version '(lsp-mode . "8.0.1")
+ :lsp-path "purescript.addNpmPath")
+
+(lsp-dependency 'purescript-language-server
+ '(:system "purescript-language-server")
+ '(:npm :package "purescript-language-server"
+ :path "purescript-language-server"))
+
+(lsp-register-client
+ (make-lsp-client
+ :new-connection (lsp-stdio-connection
+ #'lsp-purescript--server-command)
+ :major-modes '(purescript-mode)
+ :priority -1
+ :server-id 'pursls
+ :download-server-fn (lambda (_client callback error-callback _update?)
+ (lsp-package-ensure 'purescript-language-server callback error-callback))))
+
+
+(lsp-consistency-check lsp-purescript)
+
+(provide 'lsp-purescript)
+;;; lsp-purescript.el ends here
diff --git a/elpa/lsp-mode-20220505.630/lsp-purescript.elc b/elpa/lsp-mode-20220505.630/lsp-purescript.elc
new file mode 100644
index 0000000..a23ef11
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-purescript.elc
Binary files differ
diff --git a/elpa/lsp-mode-20220505.630/lsp-pwsh.el b/elpa/lsp-mode-20220505.630/lsp-pwsh.el
new file mode 100644
index 0000000..7b39bba
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-pwsh.el
@@ -0,0 +1,363 @@
+;;; lsp-pwsh.el --- client for PowerShellEditorServices -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2019 Kien Nguyen
+
+;; Author: kien.n.quang at gmail.com
+;; Keywords: lsp
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'f)
+(require 'dash)
+(require 's)
+(require 'ht)
+
+(require 'lsp-protocol)
+(require 'lsp-mode)
+
+(defgroup lsp-pwsh nil
+ "LSP support for PowerShell, using the PowerShellEditorServices."
+ :group 'lsp-mode
+ :package-version '(lsp-mode . "6.2"))
+
+;; PowerShell vscode flags
+(defcustom lsp-pwsh-help-completion "BlockComment"
+ "Controls the comment-based help completion behavior triggered by typing '##'.
+Set the generated help style with 'BlockComment' or 'LineComment'.
+Disable the feature with 'Disabled'."
+ :type
+ '(choice
+ (:tag "Disabled" "BlockComment" "LineComment"))
+ :group 'lsp-pwsh
+ :package-version '(lsp-mode . "6.2"))
+
+(defcustom lsp-pwsh-script-analysis-enable t
+ "Enables real-time script analysis from PowerShell Script Analyzer.
+Uses the newest installed version of the PSScriptAnalyzer module or the
+version bundled with this extension, if it is newer."
+ :type 'boolean
+ :group 'lsp-pwsh
+ :package-version '(lsp-mode . "6.2"))
+
+(defcustom lsp-pwsh-script-analysis-settings-path ""
+ "Specifies the path to a PowerShell Script Analyzer settings file.
+To override the default settings for all projects, enter an absolute path,
+or enter a path relative to your workspace."
+ :type 'string
+ :group 'lsp-pwsh
+ :package-version '(lsp-mode . "6.2"))
+
+(defcustom lsp-pwsh-code-folding-enable t
+ "Enables syntax based code folding.
+When disabled, the default indentation based code folding is used."
+ :type 'boolean
+ :group 'lsp-pwsh
+ :package-version '(lsp-mode . "6.2"))
+
+(defcustom lsp-pwsh-code-folding-show-last-line t
+ "Shows the last line of a folded section.
+Similar to the default VSCode folding style.
+When disabled, the entire folded region is hidden."
+ :type 'boolean
+ :group 'lsp-pwsh
+ :package-version '(lsp-mode . "6.2"))
+
+(defcustom lsp-pwsh-code-formatting-preset "Custom"
+ "Sets the codeformatting options to follow the given indent style.
+Sets in a way that is compatible with PowerShell syntax.
+For more information about the brace styles please refer to https://github.com/PoshCode/PowerShellPracticeAndStyle/issues/81."
+ :type
+ '(choice
+ (:tag "Custom" "Allman" "OTBS" "Stroustrup"))
+ :group 'lsp-pwsh
+ :package-version '(lsp-mode . "6.2"))
+
+(defcustom lsp-pwsh-code-formatting-open-brace-on-same-line t
+ "Places open brace on the same line as its associated statement."
+ :type 'boolean
+ :group 'lsp-pwsh
+ :package-version '(lsp-mode . "6.2"))
+
+(defcustom lsp-pwsh-code-formatting-new-line-after-open-brace t
+ "Adds a newline (line break) after an open brace."
+ :type 'boolean
+ :group 'lsp-pwsh
+ :package-version '(lsp-mode . "6.2"))
+
+(defcustom lsp-pwsh-code-formatting-new-line-after-close-brace t
+ "Adds a newline (line break) after a closing brace."
+ :type 'boolean
+ :group 'lsp-pwsh
+ :package-version '(lsp-mode . "6.2"))
+
+(defcustom lsp-pwsh-code-formatting-pipeline-indentation-style "NoIndentation"
+ "Multi-line pipeline style settings."
+ :type
+ '(choice
+ (:tag "IncreaseIndentationForFirstPipeline" "IncreaseIndentationAfterEveryPipeline" "NoIndentation"))
+ :group 'lsp-pwsh
+ :package-version '(lsp-mode . "6.2"))
+
+(defcustom lsp-pwsh-code-formatting-whitespace-before-open-brace t
+ "Adds a space between a keyword and its associated scriptblock expression."
+ :type 'boolean
+ :group 'lsp-pwsh
+ :package-version '(lsp-mode . "6.2"))
+
+(defcustom lsp-pwsh-code-formatting-whitespace-before-open-paren t
+ "Adds a space between a keyword (if, elseif, while, switch, etc) and its
+associated conditional expression."
+ :type 'boolean
+ :group 'lsp-pwsh
+ :package-version '(lsp-mode . "6.2"))
+
+(defcustom lsp-pwsh-code-formatting-whitespace-around-operator t
+ "Adds spaces before and after an operator ('=', '+', '-', etc.)."
+ :type 'boolean
+ :group 'lsp-pwsh
+ :package-version '(lsp-mode . "6.2"))
+
+(defcustom lsp-pwsh-code-formatting-whitespace-after-separator t
+ "Adds a space after a separator (',' and ';')."
+ :type 'boolean
+ :group 'lsp-pwsh
+ :package-version '(lsp-mode . "6.2"))
+
+(defcustom lsp-pwsh-code-formatting-whitespace-inside-brace t
+ "Adds a space after an opening brace ('{') and before a closing brace ('}')."
+ :type 'boolean
+ :group 'lsp-pwsh
+ :package-version '(lsp-mode . "6.2"))
+
+(defcustom lsp-pwsh-code-formatting-whitespace-around-pipe t
+ "Adds a space before and after the pipeline operator ('|')."
+ :type 'boolean
+ :group 'lsp-pwsh
+ :package-version '(lsp-mode . "6.2"))
+
+(defcustom lsp-pwsh-code-formatting-ignore-one-line-block t
+ "Does not reformat one-line code blocks, such as \"if (...) {...} else
+{...}\"."
+ :type 'boolean
+ :group 'lsp-pwsh
+ :package-version '(lsp-mode . "6.2"))
+
+(defcustom lsp-pwsh-code-formatting-align-property-value-pairs t
+ "Align assignment statements in a hashtable or a DSC Configuration."
+ :type 'boolean
+ :group 'lsp-pwsh
+ :package-version '(lsp-mode . "6.2"))
+
+(defcustom lsp-pwsh-code-formatting-use-correct-casing nil
+ "Use correct casing for cmdlets."
+ :type 'boolean
+ :group 'lsp-pwsh
+ :package-version '(lsp-mode . "6.2"))
+
+(defcustom lsp-pwsh-developer-editor-services-log-level "Normal"
+ "Sets the log level for the PowerShell Editor Services host executable.
+Valid values are 'Diagnostic', 'Verbose', 'Normal', 'Warning', and 'Error'"
+ :type
+ '(choice
+ (:tag "Diagnostic" "Verbose" "Normal" "Warning" "Error"))
+ :group 'lsp-pwsh
+ :package-version '(lsp-mode . "6.2"))
+
+(defcustom lsp-pwsh-developer-editor-services-wait-for-debugger nil
+ "Launches the language service with the /waitForDebugger flag to force it to
+wait for a .NET debugger to attach before proceeding."
+ :type 'boolean
+ :group 'lsp-pwsh
+ :package-version '(lsp-mode . "6.2"))
+
+(defcustom lsp-pwsh-developer-feature-flags nil
+ "An array of strings that enable experimental features in the PowerShell
+extension."
+ :type
+ '(repeat string)
+ :group 'lsp-pwsh
+ :package-version '(lsp-mode . "6.2"))
+
+(lsp-register-custom-settings
+ '(("powershell.developer.featureFlags" lsp-pwsh-developer-feature-flags)
+ ("powershell.developer.editorServicesWaitForDebugger" lsp-pwsh-developer-editor-services-wait-for-debugger t)
+ ("powershell.codeFormatting.useCorrectCasing" lsp-pwsh-code-formatting-use-correct-casing t)
+ ("powershell.codeFormatting.alignPropertyValuePairs" lsp-pwsh-code-formatting-align-property-value-pairs t)
+ ("powershell.codeFormatting.ignoreOneLineBlock" lsp-pwsh-code-formatting-ignore-one-line-block t)
+ ("powershell.codeFormatting.whitespaceAroundPipe" lsp-pwsh-code-formatting-whitespace-around-pipe t)
+ ("powershell.codeFormatting.whitespaceInsideBrace" lsp-pwsh-code-formatting-whitespace-inside-brace t)
+ ("powershell.codeFormatting.whitespaceAfterSeparator" lsp-pwsh-code-formatting-whitespace-after-separator t)
+ ("powershell.codeFormatting.whitespaceAroundOperator" lsp-pwsh-code-formatting-whitespace-around-operator t)
+ ("powershell.codeFormatting.whitespaceBeforeOpenParen" lsp-pwsh-code-formatting-whitespace-before-open-paren t)
+ ("powershell.codeFormatting.whitespaceBeforeOpenBrace" lsp-pwsh-code-formatting-whitespace-before-open-brace t)
+ ("powershell.codeFormatting.pipelineIndentationStyle" lsp-pwsh-code-formatting-pipeline-indentation-style)
+ ("powershell.codeFormatting.newLineAfterCloseBrace" lsp-pwsh-code-formatting-new-line-after-close-brace t)
+ ("powershell.codeFormatting.newLineAfterOpenBrace" lsp-pwsh-code-formatting-new-line-after-open-brace t)
+ ("powershell.codeFormatting.openBraceOnSameLine" lsp-pwsh-code-formatting-open-brace-on-same-line t)
+ ("powershell.codeFormatting.preset" lsp-pwsh-code-formatting-preset)
+ ("powershell.codeFolding.showLastLine" lsp-pwsh-code-folding-show-last-line t)
+ ("powershell.codeFolding.enable" lsp-pwsh-code-folding-enable t)
+ ("powershell.scriptAnalysis.settingsPath" lsp-pwsh-script-analysis-settings-path)
+ ("powershell.scriptAnalysis.enable" lsp-pwsh-script-analysis-enable t)
+ ("powershell.helpCompletion" lsp-pwsh-help-completion)))
+
+;; lsp-pwsh custom variables
+(defcustom lsp-pwsh-ext-path (expand-file-name "pwsh" lsp-server-install-dir)
+ "The path to powershell vscode extension."
+ :type 'string
+ :group 'lsp-pwsh
+ :package-version '(lsp-mode . "6.2"))
+
+(defcustom lsp-pwsh-exe (or (executable-find "pwsh") (executable-find "powershell"))
+ "PowerShell executable."
+ :type 'string
+ :group 'lsp-pwsh
+ :package-version '(lsp-mode . "6.2"))
+
+(defcustom lsp-pwsh-dir lsp-pwsh-ext-path
+ "Path to PowerShellEditorServices without last slash."
+ :type 'string
+ :group 'lsp-pwsh
+ :package-version '(lsp-mode . "6.2"))
+
+(defvar lsp-pwsh-pses-script (expand-file-name "PowerShellEditorServices/Start-EditorServices.ps1"
+ lsp-pwsh-dir)
+ "Main script to start PSES.")
+
+(defvar lsp-pwsh-log-path (expand-file-name "logs" lsp-pwsh-ext-path)
+ "Path to directory where server will write log files.
+Must not nil.")
+
+(defvar lsp-pwsh--sess-id (emacs-pid))
+
+(defun lsp-pwsh--command ()
+ "Return the command to start server."
+ `(,lsp-pwsh-exe "-NoProfile" "-NonInteractive" "-NoLogo"
+ ,@(if (eq system-type 'windows-nt) '("-ExecutionPolicy" "Bypass"))
+ "-OutputFormat" "Text"
+ "-File"
+ ,lsp-pwsh-pses-script
+ "-HostName" "\"Emacs Host\""
+ "-HostProfileId" "'Emacs.LSP'"
+ "-HostVersion" "8.0.1"
+ "-LogPath" ,(expand-file-name "emacs-powershell.log" lsp-pwsh-log-path)
+ "-LogLevel" ,lsp-pwsh-developer-editor-services-log-level
+ "-SessionDetailsPath" ,(expand-file-name (format "PSES-VSCode-%d" lsp-pwsh--sess-id)
+ lsp-pwsh-log-path)
+ ;; "-AdditionalModules" "@('PowerShellEditorServices.VSCode')"
+ "-Stdio"
+ "-BundledModulesPath" ,lsp-pwsh-dir
+ "-FeatureFlags" "@()"))
+
+(defun lsp-pwsh--extra-init-params ()
+ "Return form describing parameters for language server.")
+
+(lsp-defun lsp-pwsh--apply-code-action-edits ((&Command :command :arguments?))
+ "Handle ACTION for PowerShell.ApplyCodeActionEdits."
+ (-if-let* (((&pwsh:ScriptRegion :start-line-number :end-line-number
+ :start-column-number :end-column-number :text)
+ (lsp-seq-first arguments?))
+ (start-position (lsp-make-position :line (1- start-line-number)
+ :character (1- start-column-number)))
+ (end-position (lsp-make-position :line (1- end-line-number)
+ :character (1- end-column-number)))
+ (edits `[,(lsp-make-text-edit :range (lsp-make-range :start start-position
+ :end end-position)
+ :newText text)]))
+ (lsp--apply-text-edits edits 'code-action)
+ (lsp-send-execute-command command arguments?)))
+
+(lsp-defun lsp-pwsh--show-code-action-document ((&Command :arguments?))
+ "Handle ACTION for PowerShell.ShowCodeActionDocumentation."
+ (-if-let* ((rule-raw (lsp-seq-first arguments?))
+ (rule-id (if (s-prefix-p "PS" rule-raw) (substring rule-raw 2) rule-raw)))
+ (browse-url
+ (concat "https://github.com/PowerShell/PSScriptAnalyzer/blob/master/RuleDocumentation/"
+ rule-id
+ ".md"))
+ (lsp-warn "Cannot show documentation for code action, no ruleName was supplied")))
+
+(defvar lsp-pwsh--major-modes '(powershell-mode))
+
+(lsp-register-client
+ (make-lsp-client
+ :new-connection (lsp-stdio-connection #'lsp-pwsh--command
+ (lambda ()
+ (f-exists? lsp-pwsh-pses-script)))
+ :major-modes lsp-pwsh--major-modes
+ :server-id 'pwsh-ls
+ :priority -1
+ :multi-root t
+ :initialization-options #'lsp-pwsh--extra-init-params
+ :notification-handlers (ht ("powerShell/executionStatusChanged" #'ignore)
+ ("output" #'ignore))
+ :action-handlers (ht ("PowerShell.ApplyCodeActionEdits"
+ #'lsp-pwsh--apply-code-action-edits)
+ ("PowerShell.ShowCodeActionDocumentation"
+ #'lsp-pwsh--show-code-action-document))
+ :initialized-fn (lambda (w)
+ (with-lsp-workspace w
+ (lsp--set-configuration
+ (lsp-configuration-section "powershell")))
+ (let ((caps (lsp--workspace-server-capabilities w)))
+ (lsp:set-server-capabilities-document-range-formatting-provider? caps t)
+ (lsp:set-server-capabilities-document-formatting-provider? caps t)))
+ :download-server-fn #'lsp-pwsh-setup))
+
+(defcustom lsp-pwsh-github-asset-url
+ "https://github.com/%s/%s/releases/latest/download/%s"
+ "GitHub latest asset template url."
+ :type 'string
+ :group 'lsp-pwsh
+ :package-version '(lsp-mode . "6.2"))
+
+(defun lsp-pwsh-setup (_client callback error-callback update)
+ "Downloads PowerShellEditorServices to `lsp-pwsh-dir'.
+CALLBACK is called when the download finish successfully otherwise
+ERROR-CALLBACK is called.
+UPDATE is non-nil if it is already downloaded.
+FORCED if specified with prefix argument."
+
+ (unless (and lsp-pwsh-exe (file-executable-p lsp-pwsh-exe))
+ (user-error "Use `lsp-pwsh-exe' with the value of `%s' is not a valid powershell binary"
+ lsp-pwsh-exe))
+
+ (let ((url (format lsp-pwsh-github-asset-url "PowerShell"
+ "PowerShellEditorServices" "PowerShellEditorServices.zip"))
+ (temp-file (make-temp-file "ext" nil ".zip")))
+ (unless (f-exists? lsp-pwsh-log-path)
+ (mkdir lsp-pwsh-log-path 'create-parent))
+ (unless (and (not update) (f-exists? lsp-pwsh-pses-script))
+ ;; since we know it's installed, use powershell to download the file
+ ;; (and avoid url.el bugginess or additional libraries)
+ (when (f-exists? lsp-pwsh-dir) (delete-directory lsp-pwsh-dir 'recursive))
+ (lsp-async-start-process
+ callback
+ error-callback
+ lsp-pwsh-exe "-noprofile" "-noninteractive" "-nologo"
+ "-ex" "bypass" "-command"
+ "Invoke-WebRequest" "-UseBasicParsing" "-uri" url "-outfile" temp-file ";"
+ "Expand-Archive" "-Path" temp-file
+ "-DestinationPath" lsp-pwsh-dir))))
+
+(lsp-consistency-check lsp-pwsh)
+
+(provide 'lsp-pwsh)
+;;; lsp-pwsh.el ends here
diff --git a/elpa/lsp-mode-20220505.630/lsp-pwsh.elc b/elpa/lsp-mode-20220505.630/lsp-pwsh.elc
new file mode 100644
index 0000000..c405ef0
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-pwsh.elc
Binary files differ
diff --git a/elpa/lsp-mode-20220505.630/lsp-pyls.el b/elpa/lsp-mode-20220505.630/lsp-pyls.el
new file mode 100644
index 0000000..7213749
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-pyls.el
@@ -0,0 +1,504 @@
+;;; lsp-pyls.el --- pyls configuration -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2019 Ivan Yonchovski
+
+;; Author: Ivan Yonchovski <yyoncho@gmail.com>
+;; Keywords:
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; PYLS configuration
+
+;;; Code:
+
+(require 'lsp-mode)
+
+(defgroup lsp-pyls nil
+ "LSP support for Python, using Palantir's Python Language Server."
+ :group 'lsp-mode
+ :link '(url-link "https://github.com/palantir/python-language-server")
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-clients-python-library-directories '("/usr/")
+ "List of directories which will be considered to be libraries."
+ :risky t
+ :type '(repeat string)
+ :group 'lsp-pyls
+ :package-version '(lsp-mode . "6.1"))
+
+(define-obsolete-variable-alias
+ 'lsp-clients-python-command
+ 'lsp-pyls-server-command
+ "6.1")
+
+(defcustom lsp-pyls-disable-warning nil
+ "Disable Palantir python-language-server deprecation warning"
+ :group 'lsp-pyls
+ :type 'boolean
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-pyls-server-command '("pyls")
+ "Command to start pyls."
+ :risky t
+ :group 'lsp-pyls
+ :type '(repeat string)
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-pyls-configuration-sources ["pycodestyle"]
+ "List of configuration sources to use."
+ :type '(repeat string)
+ :group 'lsp-pyls
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-pyls-plugins-jedi-completion-enabled t
+ "Enable or disable the plugin."
+ :type 'boolean
+ :group 'lsp-pyls
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-pyls-plugins-jedi-completion-include-params t
+ "Auto-completes methods and classes with tabstops for each
+parameter."
+ :type 'boolean
+ :group 'lsp-pyls
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-pyls-plugins-jedi-definition-enabled t
+ "Enable or disable the plugin."
+ :type 'boolean
+ :group 'lsp-pyls
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-pyls-plugins-jedi-definition-follow-imports t
+ "The goto call will follow imports."
+ :type 'boolean
+ :group 'lsp-pyls
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-pyls-plugins-jedi-definition-follow-builtin-imports t
+ "If follow_imports is True will decide if it follow builtin
+imports."
+ :type 'boolean
+ :group 'lsp-pyls
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-pyls-plugins-jedi-hover-enabled t
+ "Enable or disable the plugin."
+ :type 'boolean
+ :group 'lsp-pyls
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-pyls-plugins-jedi-references-enabled t
+ "Enable or disable the plugin."
+ :type 'boolean
+ :group 'lsp-pyls
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-pyls-plugins-jedi-signature-help-enabled t
+ "Enable or disable the plugin."
+ :type 'boolean
+ :group 'lsp-pyls
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-pyls-plugins-jedi-symbols-enabled t
+ "Enable or disable the plugin."
+ :type 'boolean
+ :group 'lsp-pyls
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-pyls-plugins-jedi-symbols-all-scopes t
+ "If True lists the names of all scopes instead of only the
+module namespace."
+ :type 'boolean
+ :group 'lsp-pyls
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-pyls-plugins-mccabe-enabled t
+ "Enable or disable the plugin."
+ :type 'boolean
+ :group 'lsp-pyls
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-pyls-plugins-mccabe-threshold 15
+ "The minimum threshold that triggers warnings about cyclomatic
+complexity."
+ :type 'number
+ :group 'lsp-pyls
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-pyls-plugins-preload-enabled t
+ "Enable or disable the plugin."
+ :type 'boolean
+ :group 'lsp-pyls
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-pyls-plugins-preload-modules nil
+ "List of modules to import on startup"
+ :type '(repeat string)
+ :group 'lsp-pyls
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-pyls-plugins-pylint-enabled nil
+ "Enable or disable the plugin."
+ :type 'boolean
+ :group 'lsp-pyls
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-pyls-plugins-pylint-args []
+ "Arguments, passed to pylint"
+ :risky t
+ :type 'lsp-string-vector
+ :group 'lsp-pyls
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-pyls-plugins-pycodestyle-enabled t
+ "Enable or disable the plugin."
+ :type 'boolean
+ :group 'lsp-pyls
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-pyls-plugins-pycodestyle-exclude nil
+ "Exclude files or directories which match these patterns."
+ :type '(repeat string)
+ :group 'lsp-pyls
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-pyls-plugins-pycodestyle-filename nil
+ "When parsing directories, only check filenames matching these
+patterns."
+ :type '(repeat string)
+ :group 'lsp-pyls
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-pyls-plugins-pycodestyle-select nil
+ "Select errors and warnings"
+ :type '(repeat string)
+ :group 'lsp-pyls
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-pyls-plugins-pycodestyle-ignore nil
+ "Ignore errors and warnings"
+ :type '(repeat string)
+ :group 'lsp-pyls
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-pyls-plugins-pycodestyle-hang-closing nil
+ "Hang closing bracket instead of matching indentation of
+opening bracket's line."
+ :type 'boolean
+ :group 'lsp-pyls
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-pyls-plugins-pycodestyle-max-line-length nil
+ "Set maximum allowed line length."
+ :type 'number
+ :group 'lsp-pyls
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-pyls-plugins-pydocstyle-enabled nil
+ "Enable or disable the plugin."
+ :type 'boolean
+ :group 'lsp-pyls
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-pyls-plugins-pydocstyle-convention nil
+ "Choose the basic list of checked errors by specifying an
+existing convention."
+ :type '(choice (:tag "pep257" "numpy"))
+ :group 'lsp-pyls
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-pyls-plugins-pydocstyle-add-ignore nil
+ "Ignore errors and warnings in addition to the specified
+convention."
+ :type '(repeat string)
+ :group 'lsp-pyls
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-pyls-plugins-pydocstyle-add-select nil
+ "Select errors and warnings in addition to the specified
+convention."
+ :type '(repeat string)
+ :group 'lsp-pyls
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-pyls-plugins-pydocstyle-ignore nil
+ "Ignore errors and warnings"
+ :type '(repeat string)
+ :group 'lsp-pyls
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-pyls-plugins-pydocstyle-select nil
+ "Select errors and warnings"
+ :type '(repeat string)
+ :group 'lsp-pyls
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-pyls-plugins-pydocstyle-match "(?!test_).*\\.py"
+ "Check only files that exactly match the given regular
+expression; default is to match files that don't start with
+'test_' but end with '.py'."
+ :type 'string
+ :group 'lsp-pyls
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-pyls-plugins-pydocstyle-match-dir "[^\\.].*"
+ "Search only dirs that exactly match the given regular
+expression; default is to match dirs which do not begin with a
+dot."
+ :type 'string
+ :group 'lsp-pyls
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-pyls-plugins-pyflakes-enabled t
+ "Enable or disable the plugin."
+ :type 'boolean
+ :group 'lsp-pyls
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-pyls-plugins-rope-completion-enabled nil
+ "Enable or disable the plugin."
+ :type 'boolean
+ :group 'lsp-pyls
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-pyls-plugins-autopep8-enabled t
+ "Enable or disable the plugin."
+ :type 'boolean
+ :group 'lsp-pyls
+ :package-version '(lsp-mode . "6.2"))
+
+(defcustom lsp-pyls-plugins-yapf-enabled nil
+ "Enable or disable the plugin."
+ :type 'boolean
+ :group 'lsp-pyls
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-pyls-rope-extension-modules nil
+ "Builtin and c-extension modules that are allowed to be
+imported and inspected by rope."
+ :type 'string
+ :group 'lsp-pyls
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-pyls-rope-rope-folder nil
+ "The name of the folder in which rope stores project
+configurations and data. Pass `nil` for not using such a folder
+at all."
+ :type '(repeat string)
+ :group 'lsp-pyls
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-pyls-plugins-flake8-enabled nil
+ "Enable or disable the plugin."
+ :type 'boolean
+ :group 'lsp-pyls
+ :package-version '(lsp-mode . "6.2"))
+
+(defcustom lsp-pyls-plugins-flake8-exclude nil
+ "List of glob patterns to exclude from checks."
+ :type '(repeat string)
+ :group 'lsp-pyls
+ :package-version '(lsp-mode . "6.2"))
+
+(defcustom lsp-pyls-plugins-flake8-filename nil
+ "List of glob patterns to include for checks."
+ :type '(repeat string)
+ :group 'lsp-pyls
+ :package-version '(lsp-mode . "6.2"))
+
+(defcustom lsp-pyls-plugins-flake8-hang-closing nil
+ "Toggle whether pycodestyle should enforce matching the indentation of the
+opening bracket’s line. When you specify this, it will prefer that you hang the
+closing bracket rather than match the indentation."
+ :type 'boolean
+ :group 'lsp-pyls
+ :package-version '(lsp-mode . "6.2"))
+
+(defcustom lsp-pyls-plugins-flake8-ignore nil
+ "A list of codes to ignore."
+ :type '(repeat string)
+ :group 'lsp-pyls
+ :package-version '(lsp-mode . "6.2"))
+
+(defcustom lsp-pyls-plugins-flake8-max-line-length nil
+ "Set the maximum length that any line (with some exceptions) may be.
+Exceptions include lines that are either strings or comments which are
+entirely URLs."
+ :type 'integer
+ :group 'lsp-pyls
+ :package-version '(lsp-mode . "6.2"))
+
+(defcustom lsp-pyls-plugins-flake8-select nil
+ "Specify the list of error codes you wish Flake8 to report. Similarly to
+`lsp-pyls-plugins-flake8-ignore'. You can specify a portion of an error code to
+get all that start with that string. For example, you can use E, E4, E43, and
+E431"
+ :type '(repeat string)
+ :group 'lsp-pyls
+ :package-version '(lsp-mode . "6.2"))
+
+(defcustom lsp-pyls-plugins-flake8-config nil
+ "A path to a config file that will be the only config file read and used.
+This will cause Flake8 to ignore all other config files that exist.
+
+NOTE: other parameters as `lsp-pyls-plugins-flake8-max-line-length' take
+precedence over parameters referenced in config."
+ :type 'string
+ :group 'lsp-pyls
+ :package-version '(lsp-mode . "6.3"))
+
+(defcustom lsp-pyls-plugins-jedi-use-pyenv-environment nil
+ "If enabled, pass the environment got by pyenv to jedi"
+ :type 'boolean
+ :group 'lsp-pyls
+ :package-version '(lsp-mode . "6.3"))
+
+(defcustom lsp-pyls-plugins-jedi-environment nil
+ "Specify the environment that jedi runs on where <environment>/bin/python
+should be the python executable. This option will be prioritized over
+`lsp-pyls-plugins-jedi-use-pyenv-environment'."
+ :type 'string
+ :group 'lsp-pyls
+ :package-version '(lsp-mode . "6.3"))
+
+(defcustom lsp-pyls-plugins-jedi-completion-fuzzy nil
+ "If enabled, uses fuzzy completion in jedi. Requires pyls >= 0.32.0
+Can hit performance, as well as lsp-mode implements its own fuzzy search on
+completion items."
+ :type 'boolean
+ :group 'lsp-pyls
+ :package-version '(lsp-mode . "7.0"))
+
+(defcustom lsp-pyls-plugins-jedi-completion-include-class-objects t
+ "If enabled, adds class objects to completion in order to avoid snippet
+with init args.
+
+Has no effect if `lsp-pyls-plugins-jedi-completion-include-params' is disabled.
+Requires pyls >= 0.33.0"
+ :type 'boolean
+ :group 'lsp-pyls
+ :package-version '(lsp-mode . "7.0"))
+
+(defcustom lsp-pyls-rename-backend 'jedi
+ "Choose renaming backend.
+
+Jedi is preferred but only works for python >= 3.6 and pyls >= 0.32.0
+Beware that Jedi is lazy and doesn't scan the whole project.
+So it will rename only references it can find."
+ :type '(choice (const :tag "jedi" jedi)
+ (const :tag "rope" rope))
+ :group 'lsp-pyls
+ :package-version '(lsp-mode . "7.0"))
+
+
+(defun lsp-pyls-get-pyenv-environment ()
+ "Get the pyenv-managed environment for current workspace, where
+<ENV>/bin/python is the corresponding Python executable"
+ (if lsp-pyls-plugins-jedi-environment
+ lsp-pyls-plugins-jedi-environment
+ (when lsp-pyls-plugins-jedi-use-pyenv-environment
+ (let ((pyenv-version (getenv "PYENV_VERSION"))
+ (root (lsp-seq-first (lsp-find-roots-for-workspace lsp--cur-workspace (lsp-session)))))
+ (when root
+ (setenv "PYENV_VERSION" nil)
+ (let* ((pyenv-command-path (executable-find "pyenv"))
+ (python-env (when pyenv-command-path
+ (f-parent
+ (f-parent
+ (shell-command-to-string
+ (format "PYENV_DIR='%s' %s which python"
+ root pyenv-command-path)))))))
+ (if python-env (lsp--info "Configure pyls with environment: %s" python-env)
+ (lsp--warn "Can't find the python environment for
+ %s even if
+ `lsp-pyls-plugins-jedi-use-pyenv-environment` is
+ enabled") root)
+ (setenv "PYENV_VERSION" pyenv-version)
+ python-env))))))
+
+(lsp-register-custom-settings
+ '(("pyls.rope.ropeFolder" lsp-pyls-rope-rope-folder)
+ ("pyls.rope.extensionModules" lsp-pyls-rope-extension-modules)
+ ("pyls.plugins.rope_rename.enabled" (lambda () (eq lsp-pyls-rename-backend 'rope)) t)
+ ("pyls.plugins.autopep8.enabled" lsp-pyls-plugins-autopep8-enabled t)
+ ("pyls.plugins.yapf.enabled" lsp-pyls-plugins-yapf-enabled t)
+ ("pyls.plugins.rope_completion.enabled" lsp-pyls-plugins-rope-completion-enabled t)
+ ("pyls.plugins.pyflakes.enabled" lsp-pyls-plugins-pyflakes-enabled t)
+ ("pyls.plugins.pydocstyle.matchDir" lsp-pyls-plugins-pydocstyle-match-dir)
+ ("pyls.plugins.pydocstyle.match" lsp-pyls-plugins-pydocstyle-match)
+ ("pyls.plugins.pydocstyle.select" lsp-pyls-plugins-pydocstyle-select)
+ ("pyls.plugins.pydocstyle.ignore" lsp-pyls-plugins-pydocstyle-ignore)
+ ("pyls.plugins.pydocstyle.addSelect" lsp-pyls-plugins-pydocstyle-add-select)
+ ("pyls.plugins.pydocstyle.addIgnore" lsp-pyls-plugins-pydocstyle-add-ignore)
+ ("pyls.plugins.pydocstyle.convention" lsp-pyls-plugins-pydocstyle-convention)
+ ("pyls.plugins.pydocstyle.enabled" lsp-pyls-plugins-pydocstyle-enabled t)
+ ("pyls.plugins.pycodestyle.maxLineLength" lsp-pyls-plugins-pycodestyle-max-line-length)
+ ("pyls.plugins.pycodestyle.hangClosing" lsp-pyls-plugins-pycodestyle-hang-closing t)
+ ("pyls.plugins.pycodestyle.ignore" lsp-pyls-plugins-pycodestyle-ignore)
+ ("pyls.plugins.pycodestyle.select" lsp-pyls-plugins-pycodestyle-select)
+ ("pyls.plugins.pycodestyle.filename" lsp-pyls-plugins-pycodestyle-filename)
+ ("pyls.plugins.pycodestyle.exclude" lsp-pyls-plugins-pycodestyle-exclude)
+ ("pyls.plugins.pycodestyle.enabled" lsp-pyls-plugins-pycodestyle-enabled t)
+ ("pyls.plugins.pylint.enabled" lsp-pyls-plugins-pylint-enabled t)
+ ("pyls.plugins.pylint.args" lsp-pyls-plugins-pylint-args)
+ ("pyls.plugins.flake8.enabled" lsp-pyls-plugins-flake8-enabled)
+ ("pyls.plugins.flake8.exclude" lsp-pyls-plugins-flake8-exclude)
+ ("pyls.plugins.flake8.filename" lsp-pyls-plugins-flake8-filename)
+ ("pyls.plugins.flake8.hangClosing" lsp-pyls-plugins-flake8-hang-closing)
+ ("pyls.plugins.flake8.ignore" lsp-pyls-plugins-flake8-ignore)
+ ("pyls.plugins.flake8.maxLineLength" lsp-pyls-plugins-flake8-max-line-length)
+ ("pyls.plugins.flake8.select" lsp-pyls-plugins-flake8-select)
+ ("pyls.plugins.flake8.config" lsp-pyls-plugins-flake8-config)
+ ("pyls.plugins.preload.modules" lsp-pyls-plugins-preload-modules)
+ ("pyls.plugins.preload.enabled" lsp-pyls-plugins-preload-enabled t)
+ ("pyls.plugins.mccabe.threshold" lsp-pyls-plugins-mccabe-threshold)
+ ("pyls.plugins.mccabe.enabled" lsp-pyls-plugins-mccabe-enabled t)
+ ("pyls.plugins.jedi_symbols.all_scopes" lsp-pyls-plugins-jedi-symbols-all-scopes t)
+ ("pyls.plugins.jedi_symbols.enabled" lsp-pyls-plugins-jedi-symbols-enabled t)
+ ("pyls.plugins.jedi_signature_help.enabled" lsp-pyls-plugins-jedi-signature-help-enabled t)
+ ("pyls.plugins.jedi_references.enabled" lsp-pyls-plugins-jedi-references-enabled t)
+ ("pyls.plugins.jedi_hover.enabled" lsp-pyls-plugins-jedi-hover-enabled t)
+ ("pyls.plugins.jedi_definition.follow_builtin_imports" lsp-pyls-plugins-jedi-definition-follow-builtin-imports t)
+ ("pyls.plugins.jedi_definition.follow_imports" lsp-pyls-plugins-jedi-definition-follow-imports t)
+ ("pyls.plugins.jedi_definition.enabled" lsp-pyls-plugins-jedi-definition-enabled t)
+ ("pyls.plugins.jedi_completion.include_params" lsp-pyls-plugins-jedi-completion-include-params t)
+ ("pyls.plugins.jedi_completion.enabled" lsp-pyls-plugins-jedi-completion-enabled t)
+ ("pyls.plugins.jedi_completion.include_class_objects" lsp-pyls-plugins-jedi-completion-include-class-objects t)
+ ("pyls.plugins.jedi.environment" lsp-pyls-get-pyenv-environment)
+ ("pyls.plugins.jedi_completion.fuzzy" lsp-pyls-plugins-jedi-completion-fuzzy t)
+ ("pyls.plugins.jedi_rename.enabled" (lambda () (eq lsp-pyls-rename-backend 'jedi)) t)
+ ("pyls.configurationSources" lsp-pyls-configuration-sources)))
+
+(lsp-register-client
+ (make-lsp-client :new-connection (lsp-stdio-connection
+ (lambda () lsp-clients-python-command))
+ :major-modes '(python-mode cython-mode)
+ :priority -2
+ :server-id 'pyls
+ :library-folders-fn (lambda (_workspace) lsp-clients-python-library-directories)
+ :initialized-fn (lambda (workspace)
+ (unless lsp-pyls-disable-warning
+ (warn (concat "The palantir python-language-server (pyls) is unmaintained; "
+ "a maintained fork is the python-lsp-server (pylsp) project; "
+ "you can install it with pip via: pip install python-lsp-server")))
+ (with-lsp-workspace workspace
+ (lsp--set-configuration (lsp-configuration-section "pyls"))))))
+
+(lsp-consistency-check lsp-pyls)
+
+(provide 'lsp-pyls)
+;;; lsp-pyls.el ends here
diff --git a/elpa/lsp-mode-20220505.630/lsp-pyls.elc b/elpa/lsp-mode-20220505.630/lsp-pyls.elc
new file mode 100644
index 0000000..a00b6d5
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-pyls.elc
Binary files differ
diff --git a/elpa/lsp-mode-20220505.630/lsp-pylsp.el b/elpa/lsp-mode-20220505.630/lsp-pylsp.el
new file mode 100644
index 0000000..511745f
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-pylsp.el
@@ -0,0 +1,434 @@
+;;; lsp-pylsp.el --- python-lsp-server support -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2021 Doug Davis
+
+;; Author: Doug Davis <ddavis@ddavis.io>
+;; Keywords: language tools
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; pylsp configuration
+
+;;; Code:
+
+(require 'lsp-mode)
+
+(defgroup lsp-pylsp nil
+ "LSP support for Python, using python-lsp's Python Language Server."
+ :group 'lsp-mode
+ :link '(url-link "https://github.com/python-lsp/python-lsp-server"))
+
+(defcustom lsp-clients-pylsp-library-directories '("/usr/")
+ "List of directories which will be considered to be libraries."
+ :risky t
+ :type '(repeat string)
+ :group 'lsp-pylsp)
+
+(defcustom lsp-pylsp-server-command '("pylsp")
+ "Command to start pylsp."
+ :risky t
+ :group 'lsp-pylsp
+ :type '(repeat string))
+
+(defcustom lsp-pylsp-configuration-sources ["flake8"]
+ "List of configuration sources to use."
+ :type 'lsp-string-vector
+ :group 'lsp-pylsp)
+
+(defcustom lsp-pylsp-plugins-jedi-completion-enabled t
+ "Enable or disable the plugin."
+ :type 'boolean
+ :group 'lsp-pylsp)
+
+(defcustom lsp-pylsp-plugins-jedi-completion-include-params t
+ "Auto-completes methods and classes with tabstops for each
+parameter."
+ :type 'boolean
+ :group 'lsp-pylsp)
+
+(defcustom lsp-pylsp-plugins-jedi-definition-enabled t
+ "Enable or disable the plugin."
+ :type 'boolean
+ :group 'lsp-pylsp)
+
+(defcustom lsp-pylsp-plugins-jedi-definition-follow-imports t
+ "The goto call will follow imports."
+ :type 'boolean
+ :group 'lsp-pylsp)
+
+(defcustom lsp-pylsp-plugins-jedi-definition-follow-builtin-imports t
+ "If follow_imports is True will decide if it follow builtin
+imports."
+ :type 'boolean
+ :group 'lsp-pylsp)
+
+(defcustom lsp-pylsp-plugins-jedi-hover-enabled t
+ "Enable or disable the plugin."
+ :type 'boolean
+ :group 'lsp-pylsp)
+
+(defcustom lsp-pylsp-plugins-jedi-references-enabled t
+ "Enable or disable the plugin."
+ :type 'boolean
+ :group 'lsp-pylsp)
+
+(defcustom lsp-pylsp-plugins-jedi-signature-help-enabled t
+ "Enable or disable the plugin."
+ :type 'boolean
+ :group 'lsp-pylsp)
+
+(defcustom lsp-pylsp-plugins-jedi-symbols-enabled t
+ "Enable or disable the plugin."
+ :type 'boolean
+ :group 'lsp-pylsp)
+
+(defcustom lsp-pylsp-plugins-jedi-symbols-all-scopes t
+ "If True lists the names of all scopes instead of only the
+module namespace."
+ :type 'boolean
+ :group 'lsp-pylsp)
+
+(defcustom lsp-pylsp-plugins-mccabe-enabled t
+ "Enable or disable the plugin."
+ :type 'boolean
+ :group 'lsp-pylsp)
+
+(defcustom lsp-pylsp-plugins-mccabe-threshold 15
+ "The minimum threshold that triggers warnings about cyclomatic
+complexity."
+ :type 'number
+ :group 'lsp-pylsp)
+
+(defcustom lsp-pylsp-plugins-preload-enabled t
+ "Enable or disable the plugin."
+ :type 'boolean
+ :group 'lsp-pylsp)
+
+(defcustom lsp-pylsp-plugins-preload-modules nil
+ "List of modules to import on startup"
+ :type 'lsp-string-vector
+ :group 'lsp-pylsp)
+
+(defcustom lsp-pylsp-plugins-pylint-enabled nil
+ "Enable or disable the plugin."
+ :type 'boolean
+ :group 'lsp-pylsp)
+
+(defcustom lsp-pylsp-plugins-pylint-args []
+ "Arguments, passed to pylint"
+ :risky t
+ :type 'lsp-string-vector
+ :group 'lsp-pylsp)
+
+(defcustom lsp-pylsp-plugins-pycodestyle-enabled nil
+ "Enable or disable the plugin."
+ :type 'boolean
+ :group 'lsp-pylsp)
+
+(defcustom lsp-pylsp-plugins-pycodestyle-exclude nil
+ "Exclude files or directories which match these patterns."
+ :type 'lsp-string-vector
+ :group 'lsp-pylsp)
+
+(defcustom lsp-pylsp-plugins-pycodestyle-filename nil
+ "When parsing directories, only check filenames matching these
+patterns."
+ :type 'lsp-string-vector
+ :group 'lsp-pylsp)
+
+(defcustom lsp-pylsp-plugins-pycodestyle-select nil
+ "Select errors and warnings"
+ :type 'lsp-string-vector
+ :group 'lsp-pylsp)
+
+(defcustom lsp-pylsp-plugins-pycodestyle-ignore nil
+ "Ignore errors and warnings"
+ :type 'lsp-string-vector
+ :group 'lsp-pylsp)
+
+(defcustom lsp-pylsp-plugins-pycodestyle-hang-closing nil
+ "Hang closing bracket instead of matching indentation of
+opening bracket's line."
+ :type 'boolean
+ :group 'lsp-pylsp)
+
+(defcustom lsp-pylsp-plugins-pycodestyle-max-line-length nil
+ "Set maximum allowed line length."
+ :type 'number
+ :group 'lsp-pylsp)
+
+(defcustom lsp-pylsp-plugins-pydocstyle-enabled t
+ "Enable or disable the plugin."
+ :type 'boolean
+ :group 'lsp-pylsp)
+
+(defcustom lsp-pylsp-plugins-pydocstyle-convention nil
+ "Choose the basic list of checked errors by specifying an
+existing convention."
+ :type '(choice (:tag "pep257" "numpy"))
+ :group 'lsp-pylsp)
+
+(defcustom lsp-pylsp-plugins-pydocstyle-add-ignore nil
+ "Ignore errors and warnings in addition to the specified
+convention."
+ :type 'lsp-string-vector
+ :group 'lsp-pylsp)
+
+(defcustom lsp-pylsp-plugins-pydocstyle-add-select nil
+ "Select errors and warnings in addition to the specified
+convention."
+ :type 'lsp-string-vector
+ :group 'lsp-pylsp)
+
+(defcustom lsp-pylsp-plugins-pydocstyle-ignore nil
+ "Ignore errors and warnings"
+ :type 'lsp-string-vector
+ :group 'lsp-pylsp)
+
+(defcustom lsp-pylsp-plugins-pydocstyle-select nil
+ "Select errors and warnings"
+ :type 'lsp-string-vector
+ :group 'lsp-pylsp)
+
+(defcustom lsp-pylsp-plugins-pydocstyle-match "(?!test_).*\\.py"
+ "Check only files that exactly match the given regular
+expression; default is to match files that don't start with
+'test_' but end with '.py'."
+ :type 'string
+ :group 'lsp-pylsp)
+
+(defcustom lsp-pylsp-plugins-pydocstyle-match-dir "[^\\.].*"
+ "Search only dirs that exactly match the given regular
+expression; default is to match dirs which do not begin with a
+dot."
+ :type 'string
+ :group 'lsp-pylsp)
+
+(defcustom lsp-pylsp-plugins-pyflakes-enabled nil
+ "Enable or disable the plugin."
+ :type 'boolean
+ :group 'lsp-pylsp)
+
+(defcustom lsp-pylsp-plugins-rope-completion-enabled nil
+ "Enable or disable the plugin."
+ :type 'boolean
+ :group 'lsp-pylsp)
+
+(defcustom lsp-pylsp-plugins-autopep8-enabled nil
+ "Enable or disable the plugin."
+ :type 'boolean
+ :group 'lsp-pylsp)
+
+(defcustom lsp-pylsp-plugins-yapf-enabled nil
+ "Enable or disable the plugin."
+ :type 'boolean
+ :group 'lsp-pylsp)
+
+(defcustom lsp-pylsp-rope-extension-modules nil
+ "Builtin and c-extension modules that are allowed to be
+imported and inspected by rope."
+ :type 'string
+ :group 'lsp-pylsp)
+
+(defcustom lsp-pylsp-rope-rope-folder nil
+ "The name of the folder in which rope stores project
+configurations and data. Pass `nil` for not using such a folder
+at all."
+ :type 'lsp-string-vector
+ :group 'lsp-pylsp)
+
+(defcustom lsp-pylsp-plugins-flake8-enabled t
+ "Enable or disable the plugin."
+ :type 'boolean
+ :group 'lsp-pylsp)
+
+(defcustom lsp-pylsp-plugins-flake8-exclude nil
+ "List of glob patterns to exclude from checks."
+ :type 'lsp-string-vector
+ :group 'lsp-pylsp)
+
+(defcustom lsp-pylsp-plugins-flake8-filename nil
+ "List of glob patterns to include for checks."
+ :type 'lsp-string-vector
+ :group 'lsp-pylsp)
+
+(defcustom lsp-pylsp-plugins-flake8-hang-closing nil
+ "Toggle whether pycodestyle should enforce matching the indentation of the
+opening bracket’s line. When you specify this, it will prefer that you hang the
+closing bracket rather than match the indentation."
+ :type 'boolean
+ :group 'lsp-pylsp)
+
+(defcustom lsp-pylsp-plugins-flake8-ignore nil
+ "A list of codes to ignore."
+ :type 'lsp-string-vector
+ :group 'lsp-pylsp)
+
+(defcustom lsp-pylsp-plugins-flake8-max-line-length nil
+ "Set the maximum length that any line (with some exceptions) may be.
+Exceptions include lines that are either strings or comments which are
+entirely URLs."
+ :type 'integer
+ :group 'lsp-pylsp)
+
+(defcustom lsp-pylsp-plugins-flake8-select nil
+ "Specify the list of error codes you wish Flake8 to report. Similarly to
+`lsp-pylsp-plugins-flake8-ignore'. You can specify a portion of an error code to
+get all that start with that string. For example, you can use E, E4, E43, and
+E431"
+ :type 'lsp-string-vector
+ :group 'lsp-pylsp)
+
+(defcustom lsp-pylsp-plugins-flake8-config nil
+ "A path to a config file that will be the only config file read and used.
+This will cause Flake8 to ignore all other config files that exist.
+
+NOTE: other parameters as `lsp-pylsp-plugins-flake8-max-line-length' take
+precedence over parameters referenced in config."
+ :type 'string
+ :group 'lsp-pylsp)
+
+(defcustom lsp-pylsp-plugins-jedi-use-pyenv-environment nil
+ "If enabled, pass the environment got by pyenv to jedi"
+ :type 'boolean
+ :group 'lsp-pylsp)
+
+(defcustom lsp-pylsp-plugins-jedi-environment nil
+ "Specify the environment that jedi runs on where <environment>/bin/python
+should be the python executable. This option will be prioritized over
+`lsp-pylsp-plugins-jedi-use-pyenv-environment'."
+ :type 'string
+ :group 'lsp-pylsp)
+
+(defcustom lsp-pylsp-plugins-jedi-completion-fuzzy nil
+ "If enabled, uses fuzzy completion in jedi. Requires pylsp >= 0.32.0
+Can hit performance, as well as lsp-mode implements its own fuzzy search on
+completion items."
+ :type 'boolean
+ :group 'lsp-pylsp)
+
+(defcustom lsp-pylsp-plugins-jedi-completion-include-class-objects t
+ "If enabled, adds class objects to completion in order to avoid snippet
+with init args.
+
+Has no effect if `lsp-pylsp-plugins-jedi-completion-include-params' is disabled.
+Requires pylsp >= 0.33.0"
+ :type 'boolean
+ :group 'lsp-pylsp)
+
+(defcustom lsp-pylsp-rename-backend 'jedi
+ "Choose renaming backend.
+
+Jedi is preferred but only works for python >= 3.6 and pylsp >= 0.32.0
+Beware that Jedi is lazy and doesn't scan the whole project.
+So it will rename only references it can find."
+ :type '(choice (const :tag "jedi" jedi)
+ (const :tag "rope" rope))
+ :group 'lsp-pylsp)
+
+(defun lsp-pylsp-get-pyenv-environment ()
+ "Get the pyenv-managed environment for current workspace, where
+<ENV>/bin/python is the corresponding Python executable"
+ (if lsp-pylsp-plugins-jedi-environment
+ lsp-pylsp-plugins-jedi-environment
+ (when lsp-pylsp-plugins-jedi-use-pyenv-environment
+ (let ((pyenv-version (getenv "PYENV_VERSION"))
+ (root (lsp-seq-first (lsp-find-roots-for-workspace lsp--cur-workspace (lsp-session)))))
+ (when root
+ (setenv "PYENV_VERSION" nil)
+ (let* ((pyenv-command-path (executable-find "pyenv"))
+ (python-env (when pyenv-command-path
+ (f-parent
+ (f-parent
+ (shell-command-to-string
+ (format "PYENV_DIR='%s' %s which python"
+ root pyenv-command-path)))))))
+ (if python-env (lsp--info "Configure pylsp with environment: %s" python-env)
+ (lsp--warn "Can't find the python environment for
+ %s even if
+ `lsp-pylsp-plugins-jedi-use-pyenv-environment` is
+ enabled") root)
+ (setenv "PYENV_VERSION" pyenv-version)
+ python-env))))))
+
+(lsp-register-custom-settings
+ '(("pylsp.rope.ropeFolder" lsp-pylsp-rope-rope-folder)
+ ("pylsp.rope.extensionModules" lsp-pylsp-rope-extension-modules)
+ ("pylsp.plugins.rope_rename.enabled" (lambda () (eq lsp-pylsp-rename-backend 'rope)) t)
+ ("pylsp.plugins.autopep8.enabled" lsp-pylsp-plugins-autopep8-enabled t)
+ ("pylsp.plugins.yapf.enabled" lsp-pylsp-plugins-yapf-enabled t)
+ ("pylsp.plugins.rope_completion.enabled" lsp-pylsp-plugins-rope-completion-enabled t)
+ ("pylsp.plugins.pyflakes.enabled" lsp-pylsp-plugins-pyflakes-enabled t)
+ ("pylsp.plugins.pydocstyle.matchDir" lsp-pylsp-plugins-pydocstyle-match-dir)
+ ("pylsp.plugins.pydocstyle.match" lsp-pylsp-plugins-pydocstyle-match)
+ ("pylsp.plugins.pydocstyle.select" lsp-pylsp-plugins-pydocstyle-select)
+ ("pylsp.plugins.pydocstyle.ignore" lsp-pylsp-plugins-pydocstyle-ignore)
+ ("pylsp.plugins.pydocstyle.addSelect" lsp-pylsp-plugins-pydocstyle-add-select)
+ ("pylsp.plugins.pydocstyle.addIgnore" lsp-pylsp-plugins-pydocstyle-add-ignore)
+ ("pylsp.plugins.pydocstyle.convention" lsp-pylsp-plugins-pydocstyle-convention)
+ ("pylsp.plugins.pydocstyle.enabled" lsp-pylsp-plugins-pydocstyle-enabled t)
+ ("pylsp.plugins.pycodestyle.maxLineLength" lsp-pylsp-plugins-pycodestyle-max-line-length)
+ ("pylsp.plugins.pycodestyle.hangClosing" lsp-pylsp-plugins-pycodestyle-hang-closing t)
+ ("pylsp.plugins.pycodestyle.ignore" lsp-pylsp-plugins-pycodestyle-ignore)
+ ("pylsp.plugins.pycodestyle.select" lsp-pylsp-plugins-pycodestyle-select)
+ ("pylsp.plugins.pycodestyle.filename" lsp-pylsp-plugins-pycodestyle-filename)
+ ("pylsp.plugins.pycodestyle.exclude" lsp-pylsp-plugins-pycodestyle-exclude)
+ ("pylsp.plugins.pycodestyle.enabled" lsp-pylsp-plugins-pycodestyle-enabled t)
+ ("pylsp.plugins.pylint.enabled" lsp-pylsp-plugins-pylint-enabled t)
+ ("pylsp.plugins.pylint.args" lsp-pylsp-plugins-pylint-args)
+ ("pylsp.plugins.flake8.enabled" lsp-pylsp-plugins-flake8-enabled)
+ ("pylsp.plugins.flake8.exclude" lsp-pylsp-plugins-flake8-exclude)
+ ("pylsp.plugins.flake8.filename" lsp-pylsp-plugins-flake8-filename)
+ ("pylsp.plugins.flake8.hangClosing" lsp-pylsp-plugins-flake8-hang-closing)
+ ("pylsp.plugins.flake8.ignore" lsp-pylsp-plugins-flake8-ignore)
+ ("pylsp.plugins.flake8.maxLineLength" lsp-pylsp-plugins-flake8-max-line-length)
+ ("pylsp.plugins.flake8.select" lsp-pylsp-plugins-flake8-select)
+ ("pylsp.plugins.flake8.config" lsp-pylsp-plugins-flake8-config)
+ ("pylsp.plugins.preload.modules" lsp-pylsp-plugins-preload-modules)
+ ("pylsp.plugins.preload.enabled" lsp-pylsp-plugins-preload-enabled t)
+ ("pylsp.plugins.mccabe.threshold" lsp-pylsp-plugins-mccabe-threshold)
+ ("pylsp.plugins.mccabe.enabled" lsp-pylsp-plugins-mccabe-enabled t)
+ ("pylsp.plugins.jedi_symbols.all_scopes" lsp-pylsp-plugins-jedi-symbols-all-scopes t)
+ ("pylsp.plugins.jedi_symbols.enabled" lsp-pylsp-plugins-jedi-symbols-enabled t)
+ ("pylsp.plugins.jedi_signature_help.enabled" lsp-pylsp-plugins-jedi-signature-help-enabled t)
+ ("pylsp.plugins.jedi_references.enabled" lsp-pylsp-plugins-jedi-references-enabled t)
+ ("pylsp.plugins.jedi_hover.enabled" lsp-pylsp-plugins-jedi-hover-enabled t)
+ ("pylsp.plugins.jedi_definition.follow_builtin_imports" lsp-pylsp-plugins-jedi-definition-follow-builtin-imports t)
+ ("pylsp.plugins.jedi_definition.follow_imports" lsp-pylsp-plugins-jedi-definition-follow-imports t)
+ ("pylsp.plugins.jedi_definition.enabled" lsp-pylsp-plugins-jedi-definition-enabled t)
+ ("pylsp.plugins.jedi_completion.include_params" lsp-pylsp-plugins-jedi-completion-include-params t)
+ ("pylsp.plugins.jedi_completion.enabled" lsp-pylsp-plugins-jedi-completion-enabled t)
+ ("pylsp.plugins.jedi_completion.include_class_objects" lsp-pylsp-plugins-jedi-completion-include-class-objects t)
+ ("pylsp.plugins.jedi.environment" lsp-pylsp-get-pyenv-environment)
+ ("pylsp.plugins.jedi_completion.fuzzy" lsp-pylsp-plugins-jedi-completion-fuzzy t)
+ ("pylsp.plugins.jedi_rename.enabled" (lambda () (eq lsp-pylsp-rename-backend 'jedi)) t)
+ ("pylsp.configurationSources" lsp-pylsp-configuration-sources)))
+
+(lsp-register-client
+ (make-lsp-client :new-connection (lsp-stdio-connection
+ (lambda () lsp-pylsp-server-command))
+ :major-modes '(python-mode cython-mode)
+ :priority -1
+ :server-id 'pylsp
+ :library-folders-fn (lambda (_workspace) lsp-clients-pylsp-library-directories)
+ :initialized-fn (lambda (workspace)
+ (with-lsp-workspace workspace
+ (lsp--set-configuration (lsp-configuration-section "pylsp"))))))
+
+(lsp-consistency-check lsp-pylsp)
+
+(provide 'lsp-pylsp)
+;;; lsp-pylsp.el ends here
diff --git a/elpa/lsp-mode-20220505.630/lsp-pylsp.elc b/elpa/lsp-mode-20220505.630/lsp-pylsp.elc
new file mode 100644
index 0000000..0a0d15b
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-pylsp.elc
Binary files differ
diff --git a/elpa/lsp-mode-20220505.630/lsp-r.el b/elpa/lsp-mode-20220505.630/lsp-r.el
new file mode 100644
index 0000000..da54bc3
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-r.el
@@ -0,0 +1,49 @@
+;;; lsp-r.el --- description -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2020 emacs-lsp maintainers
+
+;; Author: emacs-lsp maintainers
+;; Keywords: lsp, r
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; LSP Clients for the R Programming Language.
+
+;;; Code:
+
+(require 'lsp-mode)
+
+(defgroup lsp-r nil
+ "LSP support for R."
+ :group 'lsp-mode
+ :link '(url-link "https://github.com/REditorSupport/languageserver"))
+
+(defcustom lsp-clients-r-server-command '("R" "--slave" "-e" "languageserver::run()")
+ "Command to start the R language server."
+ :group 'lsp-r
+ :risky t
+ :type '(repeat string))
+
+(lsp-register-client
+ (make-lsp-client :new-connection (lsp-stdio-connection lsp-clients-r-server-command)
+ :major-modes '(ess-r-mode)
+ :server-id 'lsp-r))
+
+
+(lsp-consistency-check lsp-r)
+
+(provide 'lsp-r)
+;;; lsp-r.el ends here
diff --git a/elpa/lsp-mode-20220505.630/lsp-r.elc b/elpa/lsp-mode-20220505.630/lsp-r.elc
new file mode 100644
index 0000000..064237c
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-r.elc
Binary files differ
diff --git a/elpa/lsp-mode-20220505.630/lsp-racket.el b/elpa/lsp-mode-20220505.630/lsp-racket.el
new file mode 100644
index 0000000..be00ba9
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-racket.el
@@ -0,0 +1,77 @@
+;;; lsp-racket.el --- lsp-mode racket integration -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2020 lsp-mode maintainers
+
+;; Author: lsp-mode maintainers
+;; Keywords: languages
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Client for the Racket language server.
+
+;;; Code:
+
+(require 'ht)
+(require 'lsp-mode)
+
+
+;; racket-langserver
+
+(defgroup lsp-racket-langserver nil
+ "LSP support for Racket, using racket-langserver"
+ :group 'lsp-mode
+ :link '(url-link "https://github.com/jeapostrophe/racket-langserver"))
+
+(defcustom lsp-racket-langserver-command '("racket" "--lib" "racket-langserver")
+ "Command to start the server."
+ :type 'string
+ :package-version '(lsp-mode . "8.0.0"))
+
+(lsp-register-client
+ (make-lsp-client :new-connection (lsp-stdio-connection (lambda () lsp-racket-langserver-command))
+ :major-modes '(racket-mode)
+ :priority 1
+ :server-id 'racket-langserver))
+
+
+;; Theia
+
+(defgroup lsp-racket-language-server nil
+ "LSP support for Racket, using racket-language-server."
+ :group 'lsp-mode
+ :link '(url-link "https://github.com/theia-ide/racket-language-server"))
+
+(defcustom lsp-racket-language-server-path "racket-language-server"
+ "Executable path for the server."
+ :type 'string
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defun lsp-racket-language-server-colorize-handler (&rest _args)
+ "Handler for the colorize notification."
+ ;; TODO:
+ nil)
+
+(lsp-register-client
+ (make-lsp-client :new-connection (lsp-stdio-connection (lambda () lsp-racket-language-server-path))
+ :major-modes '(racket-mode)
+ :priority -1
+ :notification-handlers (ht ("racket/colorize" #'lsp-racket-language-server-colorize-handler))
+ :server-id 'racket-language-server))
+
+(lsp-consistency-check lsp-racket)
+
+(provide 'lsp-racket)
+;;; lsp-racket.el ends here
diff --git a/elpa/lsp-mode-20220505.630/lsp-racket.elc b/elpa/lsp-mode-20220505.630/lsp-racket.elc
new file mode 100644
index 0000000..2a87dcd
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-racket.elc
Binary files differ
diff --git a/elpa/lsp-mode-20220505.630/lsp-remark.el b/elpa/lsp-mode-20220505.630/lsp-remark.el
new file mode 100644
index 0000000..19cdaa7
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-remark.el
@@ -0,0 +1,69 @@
+;;; lsp-remark.el --- lsp-mode remark integration -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2021 lsp-mode maintainers
+
+;; Author: lsp-mode maintainers
+;; Keywords: languages
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; LSP client for remark-language-server
+
+;;; Code:
+
+(require 'lsp-mode)
+
+;;; Markdown
+(defgroup lsp-remark nil
+ "Settings for the markdown language server client."
+ :group 'lsp-mode
+ :link '(url-link "https://github.com/remarkjs/remark-language-server")
+ :package-version '(lsp-mode . "8.0.1"))
+
+(defcustom lsp-remark-server-command "remark-language-server"
+ "The binary (or full path to binary) which executes the server."
+ :type 'string
+ :group 'lsp-remark
+ :package-version '(lsp-mode . "8.0.1"))
+
+(defcustom lsp-remark-server-command-args '("--stdio")
+ "Command-line arguments for the markdown lsp server."
+ :type '(repeat 'string)
+ :group 'lsp-remark
+ :package-version '(lsp-mode . "8.0.1"))
+
+(lsp-dependency 'remark-language-server
+ '(:system "remark-language-server")
+ '(:npm :package "remark-language-server"
+ :path "remark-language-server"))
+
+(lsp-register-client
+ (make-lsp-client :new-connection (lsp-stdio-connection
+ (lambda ()
+ (cons (or (executable-find lsp-remark-server-command)
+ (lsp-package-path 'remark-language-server))
+ lsp-remark-server-command-args)))
+ :activation-fn (lsp-activate-on "markdown")
+ :initialized-fn (lambda (workspace)
+ (with-lsp-workspace workspace
+ (lsp--set-configuration (lsp-configuration-section "remark-language-server"))))
+ :priority 0
+ :server-id 'remark))
+
+(lsp-consistency-check lsp-remark)
+
+(provide 'lsp-remark)
+;;; lsp-remark.el ends here
diff --git a/elpa/lsp-mode-20220505.630/lsp-remark.elc b/elpa/lsp-mode-20220505.630/lsp-remark.elc
new file mode 100644
index 0000000..b20a5b8
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-remark.elc
Binary files differ
diff --git a/elpa/lsp-mode-20220505.630/lsp-rf.el b/elpa/lsp-mode-20220505.630/lsp-rf.el
new file mode 100644
index 0000000..eee0a16
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-rf.el
@@ -0,0 +1,147 @@
+;;; lsp-rf.el --- description -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2020 emacs-lsp maintainers
+
+;; Author: emacs-lsp maintainers
+;; Keywords: lsp, rf, robot
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; LSP Clients for the Robot Framework.
+
+;;; Code:
+
+(require 'lsp-mode)
+
+(defgroup lsp-rf nil
+ "Settings for Robot Framework Language Server."
+ :group 'lsp-mode
+ :link '(url-link "https://github.com/tomi/vscode-rf-language-server"))
+
+(defcustom lsp-rf-language-server-start-command '("~/.nvm/versions/node/v9.11.2/bin/node" "~/.vscode/extensions/tomiturtiainen.rf-intellisense-2.8.0/server/server.js")
+ "Path to the server.js file of the rf-intellisense server.
+Accepts a list of strings (path/to/interpreter path/to/server.js)"
+ :type 'list
+ :group 'lsp-rf)
+
+(defcustom lsp-rf-language-server-include-paths []
+ "An array of files that should be included by the parser.
+Glob patterns as strings are accepted (eg. *.robot between double quotes)"
+ :type 'lsp-string-vector
+ :group 'lsp-rf)
+
+(defcustom lsp-rf-language-server-exclude-paths []
+ "An array of files that should be ignored by the parser.
+Glob patterns as strings are accepted (eg. *bad.robot between double quotes)"
+ :type 'lsp-string-vector
+ :group 'lsp-rf)
+
+(defcustom lsp-rf-language-server-dir "~/.vscode/extensions/tomiturtiainen.rf-intellisense-2.8.0/server/library-docs/"
+ "Libraries directory for libraries in `lsp-rf-language-server-libraries'"
+ :type 'string
+ :group 'lsp-rf)
+
+(defcustom lsp-rf-language-server-libraries ["BuiltIn-3.1.1" "Collections-3.0.4"]
+ "Libraries whose keywords are suggested with `auto-complete'."
+ :type '(repeat string)
+ ;; :type 'lsp-string-vector
+ :group 'lsp-rf)
+
+(defcustom lsp-rf-language-server-log-level "debug"
+ "What language server log messages are printed."
+ :type 'string
+ ;; :type '(choice (:tag "off" "errors" "info" "debug"))
+ :group 'lsp-rf)
+
+(defcustom lsp-rf-language-server-trace-server "verbose"
+ "Traces the communication between VSCode and the rfLanguageServer service."
+ :type 'string
+ ;; :type '(choice (:tag "off" "messages" "verbose"))
+ :group 'lsp-rf)
+
+(defun parse-rf-language-server-library-dirs (dirs)
+ (vconcat (mapcar
+ (lambda (x)
+ (concat
+ (expand-file-name
+ lsp-rf-language-server-dir)
+ x
+ ".json"))
+ dirs)))
+
+(defun expand-start-command ()
+ (mapcar 'expand-file-name lsp-rf-language-server-start-command))
+
+(defun parse-rf-language-server-globs-to-regex (vector)
+ "Convert a VECTOR of globs to a regex."
+ (--> (mapcan #'lsp-glob-to-regexps vector)
+ (s-join "\\|" it)
+ (concat "\\(?:" it "\\)")))
+
+(defun parse-rf-language-server-include-path-regex (vector)
+ "Creates regexp to select files from workspace directory."
+ (let ((globs (if (eq vector [])
+ ["*.robot" "*.resource"]
+ vector)))
+ (parse-rf-language-server-globs-to-regex globs)))
+
+(defun parse-rf-language-server-exclude-paths (seq)
+ "Creates regexp to select files from workspace directory."
+ (if (eq lsp-rf-language-server-exclude-paths [])
+ seq
+ (cl-delete-if (lambda (x) (string-match-p
+ (parse-rf-language-server-globs-to-regex
+ lsp-rf-language-server-exclude-paths)
+ x))
+ seq)))
+
+(lsp-register-custom-settings
+ '(
+ ("rfLanguageServer.trace.server" lsp-rf-language-server-trace-server)
+ ("rfLanguageServer.logLevel" lsp-rf-language-server-log-level)
+ ("rfLanguageServer.libraries" lsp-rf-language-server-libraries)
+ ("rfLanguageServer.excludePaths" lsp-rf-language-server-exclude-paths)
+ ("rfLanguageServer.includePaths" lsp-rf-language-server-include-paths)))
+
+(lsp-register-client
+ (make-lsp-client :new-connection (lsp-stdio-connection
+ (expand-start-command))
+ :major-modes '(robot-mode)
+ :server-id 'rf-intellisense
+ ;; :library-folders-fn (lambda (_workspace)
+ ;; lsp-rf-language-server-libraries)
+ :library-folders-fn (lambda (_workspace)
+ (parse-rf-language-server-library-dirs
+ lsp-rf-language-server-libraries))
+ :initialized-fn (lambda (workspace)
+ (with-lsp-workspace workspace
+ (lsp--set-configuration
+ (lsp-configuration-section "rfLanguageServer"))
+ (lsp-request "buildFromFiles"
+ (list :files
+ (vconcat
+ (parse-rf-language-server-exclude-paths
+ (directory-files-recursively
+ (lsp--workspace-root workspace)
+ (parse-rf-language-server-include-path-regex
+ lsp-rf-language-server-include-paths))))))))))
+
+
+
+(lsp-consistency-check lsp-rf)
+
+(provide 'lsp-rf)
+;;; lsp-rf.el ends here
diff --git a/elpa/lsp-mode-20220505.630/lsp-rf.elc b/elpa/lsp-mode-20220505.630/lsp-rf.elc
new file mode 100644
index 0000000..106a741
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-rf.elc
Binary files differ
diff --git a/elpa/lsp-mode-20220505.630/lsp-rust.el b/elpa/lsp-mode-20220505.630/lsp-rust.el
new file mode 100644
index 0000000..a5c6daa
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-rust.el
@@ -0,0 +1,1203 @@
+;;; lsp-rust.el --- Rust Client settings -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2019 Ivan Yonchovski
+
+;; Author: Ivan Yonchovski <yyoncho@gmail.com>
+;; Keywords:
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; lsp-rust client
+
+;;; Code:
+
+(require 'lsp-mode)
+(require 'ht)
+(require 'dash)
+
+(defgroup lsp-rust nil
+ "LSP support for Rust, using Rust Language Server or rust-analyzer."
+ :group 'lsp-mode
+ :link '(url-link "https://github.com/rust-lang/rls")
+ :package-version '(lsp-mode . "6.1"))
+
+(defgroup lsp-rust-rls nil
+ "LSP support for Rust, using Rust Language Server."
+ :group 'lsp-mode
+ :link '(url-link "https://github.com/rust-lang/rls")
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defgroup lsp-rust-analyzer nil
+ "LSP support for Rust, using rust-analyzer."
+ :group 'lsp-mode
+ :link '(url-link "https://github.com/rust-analyzer/rust-analyzer")
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-rust-server 'rust-analyzer
+ "Choose LSP server."
+ :type '(choice (const :tag "rls" rls)
+ (const :tag "rust-analyzer" rust-analyzer))
+ :group 'lsp-rust
+ :package-version '(lsp-mode . "6.2"))
+
+;; RLS
+
+(defcustom lsp-rust-rls-server-command '("rls")
+ "Command to start RLS."
+ :type '(repeat string)
+ :group 'lsp-rust-rls
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-rust-library-directories '("~/.cargo/registry/src" "~/.rustup/toolchains")
+ "List of directories which will be considered to be libraries."
+ :risky t
+ :type '(repeat string)
+ :group 'lsp-rust-rls
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-rust-sysroot nil
+ "If non-nil, use the given path as the sysroot for all rustc invocations
+instead of trying to detect the sysroot automatically."
+ :type '(choice
+ (const :tag "None" nil)
+ (string :tag "Sysroot"))
+ :group 'lsp-rust-rls
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-rust-target nil
+ "If non-nil, use the given target triple for all rustc invocations."
+ :type '(choice
+ (const :tag "None" nil)
+ (string :tag "Target"))
+ :group 'lsp-rust-rls
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-rust-rustflags nil
+ "Flags added to RUSTFLAGS."
+ :type '(choice
+ (const :tag "None" nil)
+ (string :tag "Flags"))
+ :group 'lsp-rust-rls
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-rust-clear-env-rust-log t
+ "Clear the RUST_LOG environment variable before running rustc or cargo."
+ :type 'boolean
+ :group 'lsp-rust-rls
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-rust-build-lib nil
+ "If non-nil, checks the project as if you passed the `--lib' argument to
+cargo.
+
+Mutually exclusive with, and preferred over, `lsp-rust-build-bin'. (Unstable)"
+ :type 'boolean
+ :group 'lsp-rust-rls
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-rust-build-bin nil
+ "If non-nil, checks the project as if you passed `-- bin <build_bin>'
+argument to cargo.
+
+Mutually exclusive with `lsp-rust-build-lib'. (Unstable)"
+ :type '(choice
+ (const :tag "None" nil)
+ (string :tag "Binary"))
+ :group 'lsp-rust-rls
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-rust-cfg-test nil
+ "If non-nil, checks the project as if you were running `cargo test' rather
+than cargo build.
+
+I.e., compiles (but does not run) test code."
+ :type 'boolean
+ :group 'lsp-rust-rls
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-rust-unstable-features nil
+ "Enable unstable features."
+ :type 'boolean
+ :group 'lsp-rust-rls
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-rust-wait-to-build nil
+ "Time in milliseconds between receiving a change notification
+and starting build. If not specified, automatically inferred by
+the latest build duration."
+ :type '(choice
+ (const :tag "Auto" nil)
+ (number :tag "Time"))
+ :group 'lsp-rust-rls
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-rust-show-warnings t
+ "Show warnings."
+ :type 'boolean
+ :group 'lsp-rust-rls
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-rust-crate-blacklist [
+ "cocoa"
+ "gleam"
+ "glium"
+ "idna"
+ "libc"
+ "openssl"
+ "rustc_serialize"
+ "serde"
+ "serde_json"
+ "typenum"
+ "unicode_normalization"
+ "unicode_segmentation"
+ "winapi"
+ ]
+ "A list of Cargo crates to blacklist."
+ :type 'lsp-string-vector
+ :group 'lsp-rust-rls
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-rust-build-on-save nil
+ "Only index the project when a file is saved and not on change."
+ :type 'boolean
+ :group 'lsp-rust-rls
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-rust-features []
+ "List of Cargo features to enable."
+ :type 'lsp-string-vector
+ :group 'lsp-rust-rls
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-rust-all-features nil
+ "Enable all Cargo features."
+ :type 'boolean
+ :group 'lsp-rust-rls
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-rust-no-default-features nil
+ "Do not enable default Cargo features."
+ :type 'boolean
+ :group 'lsp-rust-rls
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-rust-racer-completion t
+ "Enables code completion using racer."
+ :type 'boolean
+ :group 'lsp-rust-rls
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-rust-clippy-preference "opt-in"
+ "Controls eagerness of clippy diagnostics when available.
+Valid values are (case-insensitive):
+ - \"off\": Disable clippy lints.
+ - \"opt-in\": Clippy lints are shown when crates specify `#![warn(clippy)]'.
+ - \"on\": Clippy lints enabled for all crates in workspace.
+
+You need to install clippy via rustup if you haven't already."
+ :type '(choice
+ (const "on")
+ (const "opt-in")
+ (const "off"))
+ :group 'lsp-rust-rls
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-rust-jobs nil
+ "Number of Cargo jobs to be run in parallel."
+ :type '(choice
+ (const :tag "Auto" nil)
+ (number :tag "Jobs"))
+ :group 'lsp-rust-rls
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-rust-all-targets t
+ "Checks the project as if you were running cargo check --all-targets.
+I.e., check all targets and integration tests too."
+ :type 'boolean
+ :group 'lsp-rust-rls
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-rust-target-dir nil
+ "When specified, it places the generated analysis files at the
+specified target directory. By default it is placed target/rls
+directory."
+ :type '(choice
+ (const :tag "Default" nil)
+ (string :tag "Directory"))
+ :group 'lsp-rust-rls
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-rust-rustfmt-path nil
+ "When specified, RLS will use the Rustfmt pointed at the path
+instead of the bundled one"
+ :type '(choice
+ (const :tag "Bundled" nil)
+ (string :tag "Path"))
+ :group 'lsp-rust-rls
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-rust-build-command nil
+ "EXPERIMENTAL (requires `rust.unstable_features')
+If set, executes a given program responsible for rebuilding save-analysis to be
+loaded by the RLS. The program given should output a list of resulting .json
+files on stdout.
+
+Implies `rust.build_on_save': true."
+ :type '(choice
+ (const :tag "None" nil)
+ (string :tag "Command"))
+ :group 'lsp-rust-rls
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-rust-full-docs nil
+ "Instructs cargo to enable full documentation extraction during
+save-analysis while building the crate."
+ :type 'boolean
+ :group 'lsp-rust-rls
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-rust-show-hover-context t
+ "Show additional context in hover tooltips when available. This
+is often the type local variable declaration."
+ :type 'boolean
+ :group 'lsp-rust-rls
+ :package-version '(lsp-mode . "6.1"))
+
+(lsp-register-custom-settings
+ '(("rust.show_hover_context" lsp-rust-show-hover-context t)
+ ("rust.full_docs" lsp-rust-full-docs t)
+ ("rust.build_command" lsp-rust-build-command)
+ ("rust.rustfmt_path" lsp-rust-rustfmt-path)
+ ("rust.target_dir" lsp-rust-target-dir)
+ ("rust.all_targets" lsp-rust-all-targets t)
+ ("rust.jobs" lsp-rust-jobs)
+ ("rust.clippy_preference" lsp-rust-clippy-preference)
+ ("rust.racer_completion" lsp-rust-racer-completion t)
+ ("rust.no_default_features" lsp-rust-no-default-features t)
+ ("rust.all_features" lsp-rust-all-features t)
+ ("rust.features" lsp-rust-features)
+ ("rust.build_on_save" lsp-rust-build-on-save t)
+ ("rust.crate_blacklist" lsp-rust-crate-blacklist)
+ ("rust.show_warnings" lsp-rust-show-warnings t)
+ ("rust.wait_to_build" lsp-rust-wait-to-build)
+ ("rust.unstable_features" lsp-rust-unstable-features t)
+ ("rust.cfg_test" lsp-rust-cfg-test t)
+ ("rust.build_bin" lsp-rust-build-bin)
+ ("rust.build_lib" lsp-rust-build-lib t)
+ ("rust.clear_env_rust_log" lsp-rust-clear-env-rust-log t)
+ ("rust.rustflags" lsp-rust-rustflags)
+ ("rust.target" lsp-rust-target)
+ ("rust.sysroot" lsp-rust-sysroot)))
+
+(defun lsp-clients--rust-window-progress (workspace params)
+ "Progress report handling.
+PARAMS progress report notification data."
+ (-let [(&v1:ProgressParams :done? :message? :title) params]
+ (if (or done? (s-blank-str? message?))
+ (lsp-workspace-status nil workspace)
+ (lsp-workspace-status (format "%s - %s" title (or message? "")) workspace))))
+
+(lsp-defun lsp-rust--rls-run ((&Command :arguments? params))
+ (-let* (((&rls:Cmd :env :binary :args :cwd) (lsp-seq-first params))
+ (default-directory (or cwd (lsp-workspace-root) default-directory) ))
+ (compile
+ (format "%s %s %s"
+ (s-join " " (ht-amap (format "%s=%s" key value) env))
+ binary
+ (s-join " " args)))))
+
+(lsp-register-client
+ (make-lsp-client :new-connection (lsp-stdio-connection (lambda () lsp-rust-rls-server-command))
+ :major-modes '(rust-mode rustic-mode)
+ :priority (if (eq lsp-rust-server 'rls) 1 -1)
+ :initialization-options '((omitInitBuild . t)
+ (cmdRun . t))
+ :notification-handlers (ht ("window/progress" 'lsp-clients--rust-window-progress))
+ :action-handlers (ht ("rls.run" 'lsp-rust--rls-run))
+ :library-folders-fn (lambda (_workspace) lsp-rust-library-directories)
+ :initialized-fn (lambda (workspace)
+ (with-lsp-workspace workspace
+ (lsp--set-configuration
+ (lsp-configuration-section "rust"))))
+ :server-id 'rls))
+
+
+;; rust-analyzer
+(defcustom lsp-rust-analyzer-server-command '("rust-analyzer")
+ "Command to start rust-analyzer."
+ :type '(repeat string)
+ :group 'lsp-rust-analyzer
+ :package-version '(lsp-mode . "6.2"))
+
+(defcustom lsp-rust-analyzer-server-format-inlay-hints t
+ "Whether to ask rust-analyzer to format inlay hints itself. If
+active, the various inlay format settings are not used."
+ :type 'boolean
+ :group 'lsp-rust-analyzer
+ :package-version '(lsp-mode . "8.0.1"))
+
+(defcustom lsp-rust-analyzer-server-display-inlay-hints nil
+ "Show inlay hints."
+ :type 'boolean
+ :group 'lsp-rust-analyzer
+ :package-version '(lsp-mode . "6.2"))
+
+(defcustom lsp-rust-analyzer-max-inlay-hint-length nil
+ "Max inlay hint length."
+ :type 'integer
+ :group 'lsp-rust-analyzer
+ :package-version '(lsp-mode . "6.2.2"))
+
+(defcustom lsp-rust-analyzer-display-chaining-hints nil
+ "Whether to show inlay type hints for method chains. These
+hints will be formatted with the type hint formatting options, if
+the mode is not configured to ask the server to format them."
+ :type 'boolean
+ :group 'lsp-rust-analyzer
+ :package-version '(lsp-mode . "6.2.2"))
+
+(defcustom lsp-rust-analyzer-display-lifetime-elision-hints-enable "never"
+ "Whether to show elided lifetime inlay hints."
+ :type '(choice
+ (const "never")
+ (const "always")
+ (const "skip_trivial"))
+ :group 'lsp-rust-analyzer
+ :package-version '(lsp-mode . "8.0.1"))
+
+(defcustom lsp-rust-analyzer-display-lifetime-elision-hints-use-parameter-names nil
+ "When showing elided lifetime inlay hints, whether to use
+parameter names or numeric placeholder names for the lifetimes."
+ :type 'boolean
+ :group 'lsp-rust-analyzer
+ :package-version '(lsp-mode . "8.0.1"))
+
+(defcustom lsp-rust-analyzer-display-closure-return-type-hints nil
+ "Whether to show closure return type inlay hints for closures
+with block bodies."
+ :type 'boolean
+ :group 'lsp-rust-analyzer
+ :package-version '(lsp-mode . "8.0.1"))
+
+(defcustom lsp-rust-analyzer-display-parameter-hints nil
+ "Whether to show function parameter name inlay hints at the call site."
+ :type 'boolean
+ :group 'lsp-rust-analyzer
+ :package-version '(lsp-mode . "6.2.2"))
+
+(defcustom lsp-rust-analyzer-display-reborrow-hints nil
+ "Whether to show reborrowing inlay hints."
+ :type 'boolean
+ :group 'lsp-rust-analyzer
+ :package-version '(lsp-mode . "8.0.1"))
+
+(defcustom lsp-rust-analyzer-lru-capacity nil
+ "Number of syntax trees rust-analyzer keeps in memory."
+ :type 'integer
+ :group 'lsp-rust-analyzer
+ :package-version '(lsp-mode . "6.2.2"))
+
+(defcustom lsp-rust-analyzer-cargo-target nil
+ "Compilation target (target triple)."
+ :type '(choice
+ (string :tag "Target")
+ (const :tag "None" nil))
+ :group 'lsp-rust-analyzer
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-rust-analyzer-cargo-watch-enable t
+ "Enable Cargo watch."
+ :type 'boolean
+ :group 'lsp-rust-analyzer
+ :package-version '(lsp-mode . "6.2.2"))
+
+(defcustom lsp-rust-analyzer-cargo-watch-command "check"
+ "Cargo watch command."
+ :type 'string
+ :group 'lsp-rust-analyzer
+ :package-version '(lsp-mode . "6.2.2"))
+
+(defcustom lsp-rust-analyzer-cargo-watch-args []
+ "Cargo watch args."
+ :type 'lsp-string-vector
+ :group 'lsp-rust-analyzer
+ :package-version '(lsp-mode . "6.2.2"))
+
+(defcustom lsp-rust-analyzer-cargo-override-command []
+ "Advanced option, fully override the command rust-analyzer uses for checking.
+The command should include `--message=format=json` or similar option."
+ :type 'lsp-string-vector
+ :group 'lsp-rust-analyzer
+ :package-version '(lsp-mode . "6.2.2"))
+
+(defcustom lsp-rust-analyzer-cargo-all-targets t
+ "Cargo watch all targets or not."
+ :type 'boolean
+ :group 'lsp-rust-analyzer
+ :package-version '(lsp-mode . "6.2.2"))
+
+(defcustom lsp-rust-analyzer-cargo-unset-test []
+ "force rust-analyzer to unset `#[cfg(test)]` for the specified crates."
+ :type 'lsp-string-vector
+ :group 'lsp-rust-analyzer
+ :package-version '(lsp-mode . "8.0.1"))
+
+(defcustom lsp-rust-analyzer-use-client-watching t
+ "Use client watching"
+ :type 'boolean
+ :group 'lsp-rust-analyzer
+ :package-version '(lsp-mode . "6.2.2"))
+
+(defcustom lsp-rust-analyzer-exclude-globs []
+ "Exclude globs"
+ :type 'lsp-string-vector
+ :group 'lsp-rust-analyzer
+ :package-version '(lsp-mode . "6.2.2"))
+
+(defcustom lsp-rust-analyzer-exclude-dirs []
+ "These directories will be ignored by rust-analyzer."
+ :type 'lsp-string-vector
+ :group 'lsp-rust-analyzer
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-rust-analyzer-macro-expansion-method 'lsp-rust-analyzer-macro-expansion-default
+ "Use a different function if you want formatted macro expansion results and
+syntax highlighting."
+ :type 'function
+ :group 'lsp-rust-analyzer
+ :package-version '(lsp-mode . "6.2.2"))
+
+(defcustom lsp-rust-analyzer-diagnostics-enable t
+ "Whether to show native rust-analyzer diagnostics."
+ :type 'boolean
+ :group 'lsp-rust-analyzer
+ :package-version '(lsp-mode . "6.3.2"))
+
+(defcustom lsp-rust-analyzer-diagnostics-enable-experimental nil
+ "Whether to show native rust-analyzer diagnostics that are still experimental
+\(might have more false positives than usual)."
+ :type 'boolean
+ :group 'lsp-rust-analyzer
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-rust-analyzer-diagnostics-disabled []
+ "List of native rust-analyzer diagnostics to disable."
+ :type 'lsp-string-vector
+ :group 'lsp-rust-analyzer
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-rust-analyzer-diagnostics-warnings-as-hint []
+ "List of warnings that should be displayed with hint severity."
+ :type 'lsp-string-vector
+ :group 'lsp-rust-analyzer
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-rust-analyzer-diagnostics-warnings-as-info []
+ "List of warnings that should be displayed with info severity."
+ :type 'lsp-string-vector
+ :group 'lsp-rust-analyzer
+ :package-version '(lsp-mode . "8.0.0"))
+
+(define-obsolete-variable-alias
+ 'lsp-rust-analyzer-cargo-load-out-dirs-from-check
+ 'lsp-rust-analyzer-cargo-run-build-scripts
+ "8.0.0")
+
+(defcustom lsp-rust-analyzer-cargo-run-build-scripts t
+ "Whether to run build scripts (`build.rs`) for more precise code analysis."
+ :type 'boolean
+ :group 'lsp-rust-analyzer
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-rust-analyzer-rustfmt-extra-args []
+ "Additional arguments to rustfmt."
+ :type 'lsp-string-vector
+ :group 'lsp-rust-analyzer
+ :package-version '(lsp-mode . "6.3.2"))
+
+(defcustom lsp-rust-analyzer-rustfmt-override-command []
+ "Advanced option, fully override the command rust-analyzer uses
+for formatting."
+ :type 'lsp-string-vector
+ :group 'lsp-rust-analyzer
+ :package-version '(lsp-mode . "6.3.2"))
+
+(defcustom lsp-rust-analyzer-completion-add-call-parenthesis t
+ "Whether to add parenthesis when completing functions."
+ :type 'boolean
+ :group 'lsp-rust-analyzer
+ :package-version '(lsp-mode . "6.3.2"))
+
+(defcustom lsp-rust-analyzer-completion-add-call-argument-snippets t
+ "Whether to add argument snippets when completing functions."
+ :type 'boolean
+ :group 'lsp-rust-analyzer
+ :package-version '(lsp-mode . "6.3.2"))
+
+(defcustom lsp-rust-analyzer-completion-postfix-enable t
+ "Whether to show postfix snippets like `dbg`, `if`, `not`, etc."
+ :type 'boolean
+ :group 'lsp-rust-analyzer
+ :package-version '(lsp-mode . "6.3.2"))
+
+(defcustom lsp-rust-analyzer-call-info-full t
+ "Whether to show function name and docs in parameter hints."
+ :type 'boolean
+ :group 'lsp-rust-analyzer
+ :package-version '(lsp-mode . "6.3.2"))
+
+(defcustom lsp-rust-analyzer-proc-macro-enable t
+ "Enable Proc macro support.
+Implies `lsp-rust-analyzer-cargo-run-build-scripts'"
+ :type 'boolean
+ :group 'lsp-rust-analyzer
+ :package-version '(lsp-mode . "6.3.2"))
+
+(defcustom lsp-rust-analyzer-import-merge-behaviour "full"
+ "The strategy to use when inserting new imports or merging imports.
+Valid values are:
+ - \"none\": No merging
+ - \"full\": Merge all layers of the import trees
+ - \"last\": Only merge the last layer of the import trees"
+ :type '(choice
+ (const "none")
+ (const "full")
+ (const "last"))
+ :group 'lsp-rust-analyzer
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-rust-analyzer-import-prefix "plain"
+ "The path structure for newly inserted paths to use.
+Valid values are:
+ - \"plain\": Insert import paths relative to the current module, using up to
+one `super' prefix if the parent module contains the requested item.
+ - \"by_self\": Prefix all import paths with `self' if they don't begin with
+`self', `super', `crate' or a crate name.
+ - \"by_crate\": Force import paths to be absolute by always starting
+them with `crate' or the crate name they refer to."
+ :type '(choice
+ (const "plain")
+ (const "by_self")
+ (const "by_crate"))
+ :group 'lsp-rust-analyzer
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-rust-analyzer-import-granularity "crate"
+ "How imports should be grouped into use statements."
+ :type '(choice
+ (const "crate" :doc "Merge imports from the same crate into a single use statement. This kind of nesting is only supported in Rust versions later than 1.24.")
+ (const "module" :doc "Merge imports from the same module into a single use statement.")
+ (const "item" :doc "Don’t merge imports at all, creating one import per item.")
+ (const "preserve" :doc "Do not change the granularity of any imports. For auto-import this has the same effect as `\"item\"'"))
+ :group 'lsp-rust-analyzer
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-rust-analyzer-cargo-auto-reload t
+ "Automatically refresh project info via `cargo metadata' on `Cargo.toml' changes."
+ :type 'boolean
+ :group 'lsp-rust-analyzer
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-rust-analyzer-use-rustc-wrapper-for-build-scripts t
+ "Use `RUSTC_WRAPPER=rust-analyzer' when running build scripts to avoid
+compiling unnecessary things."
+ :type 'boolean
+ :group 'lsp-rust-analyzer
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-rust-analyzer-completion-auto-import-enable t
+ "Toggles the additional completions that automatically add imports when
+completed. `lsp-completion-enable-additional-text-edit' must be non-nil
+ for this feature to be fully enabled."
+ :type 'boolean
+ :group 'lsp-rust-analyzer
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-rust-analyzer-completion-auto-self-enable t
+ "Toggles the additional completions that automatically show method calls
+and field accesses with self prefixed to them when inside a method."
+ :type 'boolean
+ :group 'lsp-rust-analyzer
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-rust-analyzer-import-enforce-granularity nil
+ "Whether to enforce the import granularity setting for all files.
+ If set to nil rust-analyzer will try to keep import styles consistent per file."
+ :type 'boolean
+ :group 'lsp-rust-analyzer
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-rust-analyzer-import-group t
+ "Group inserted imports by the following order:
+https://rust-analyzer.github.io/manual.html#auto-import.
+ Groups are separated by newlines."
+ :type 'boolean
+ :group 'lsp-rust-analyzer
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-rust-analyzer-highlighting-strings t
+ "Use semantic tokens for strings."
+ :type 'boolean
+ :group 'lsp-rust-analyzer
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-rust-analyzer-rustc-source nil
+ "Path to the Cargo.toml of the rust compiler workspace."
+ :type '(choice
+ (file :tag "Path")
+ (const :tag "None" nil))
+ :group 'lsp-rust-analyzer
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-rust-analyzer-linked-projects []
+ "Disable project auto-discovery in favor of explicitly specified set of
+projects. Elements must be paths pointing to `Cargo.toml`, `rust-project.json`,
+or JSON objects in `rust-project.json` format."
+ :type 'lsp-string-vector
+ :group 'lsp-rust-analyzer
+ :package-version '(lsp-mode . "8.0.1"))
+
+(defcustom lsp-rust-analyzer-experimental-proc-attr-macros t
+ "Whether to enable experimental support for expanding proc macro attributes."
+ :type 'boolean
+ :group 'lsp-rust-analyzer
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defun lsp-rust-analyzer--make-init-options ()
+ "Init options for rust-analyzer"
+ `(:diagnostics (:enable ,(lsp-json-bool lsp-rust-analyzer-diagnostics-enable)
+ :enableExperimental ,(lsp-json-bool lsp-rust-analyzer-diagnostics-enable-experimental)
+ :disabled ,lsp-rust-analyzer-diagnostics-disabled
+ :warningsAsHint ,lsp-rust-analyzer-diagnostics-warnings-as-hint
+ :warningsAsInfo ,lsp-rust-analyzer-diagnostics-warnings-as-info)
+ :assist (:importMergeBehaviour ,lsp-rust-analyzer-import-merge-behaviour
+ :importPrefix ,lsp-rust-analyzer-import-prefix
+ :importGranularity ,lsp-rust-analyzer-import-granularity
+ :importEnforceGranularity ,(lsp-json-bool lsp-rust-analyzer-import-enforce-granularity)
+ :importGroup ,(lsp-json-bool lsp-rust-analyzer-import-group))
+ :lruCapacity ,lsp-rust-analyzer-lru-capacity
+ :checkOnSave (:enable ,(lsp-json-bool lsp-rust-analyzer-cargo-watch-enable)
+ :command ,lsp-rust-analyzer-cargo-watch-command
+ :extraArgs ,lsp-rust-analyzer-cargo-watch-args
+ :allTargets ,(lsp-json-bool lsp-rust-analyzer-cargo-all-targets)
+ :overrideCommand ,lsp-rust-analyzer-cargo-override-command)
+ :files (:exclude ,lsp-rust-analyzer-exclude-globs
+ :watcher ,(if lsp-rust-analyzer-use-client-watching "client" "notify")
+ :excludeDirs ,lsp-rust-analyzer-exclude-dirs)
+ :cargo (:allFeatures ,(lsp-json-bool lsp-rust-all-features)
+ :noDefaultFeatures ,(lsp-json-bool lsp-rust-no-default-features)
+ :features ,lsp-rust-features
+ :target ,lsp-rust-analyzer-cargo-target
+ :runBuildScripts ,(lsp-json-bool lsp-rust-analyzer-cargo-run-build-scripts)
+ ; Obsolete, but used by old Rust-Analyzer versions
+ :loadOutDirsFromCheck ,(lsp-json-bool lsp-rust-analyzer-cargo-run-build-scripts)
+ :autoreload ,(lsp-json-bool lsp-rust-analyzer-cargo-auto-reload)
+ :useRustcWrapperForBuildScripts ,(lsp-json-bool lsp-rust-analyzer-use-rustc-wrapper-for-build-scripts)
+ :unsetTest ,lsp-rust-analyzer-cargo-unset-test)
+ :rustfmt (:extraArgs ,lsp-rust-analyzer-rustfmt-extra-args
+ :overrideCommand ,lsp-rust-analyzer-rustfmt-override-command)
+ :inlayHints (:renderColons ,(lsp-json-bool lsp-rust-analyzer-server-format-inlay-hints)
+ :typeHints ,(lsp-json-bool lsp-rust-analyzer-server-display-inlay-hints)
+ :chainingHints ,(lsp-json-bool lsp-rust-analyzer-display-chaining-hints)
+ :closureReturnTypeHints ,(lsp-json-bool lsp-rust-analyzer-display-closure-return-type-hints)
+ :lifetimeElisionHints (:enable ,lsp-rust-analyzer-display-lifetime-elision-hints-enable
+ :useParameterNames ,(lsp-json-bool lsp-rust-analyzer-display-lifetime-elision-hints-use-parameter-names))
+ :parameterHints ,(lsp-json-bool lsp-rust-analyzer-display-parameter-hints)
+ :reborrowHints ,(lsp-json-bool lsp-rust-analyzer-display-reborrow-hints)
+ :maxLength ,lsp-rust-analyzer-max-inlay-hint-length)
+ :completion (:addCallParenthesis ,(lsp-json-bool lsp-rust-analyzer-completion-add-call-parenthesis)
+ :addCallArgumentSnippets ,(lsp-json-bool lsp-rust-analyzer-completion-add-call-argument-snippets)
+ :postfix (:enable ,(lsp-json-bool lsp-rust-analyzer-completion-postfix-enable))
+ :autoimport (:enable ,(lsp-json-bool lsp-rust-analyzer-completion-auto-import-enable))
+ :autoself (:enable ,(lsp-json-bool lsp-rust-analyzer-completion-auto-self-enable)))
+ :callInfo (:full ,(lsp-json-bool lsp-rust-analyzer-call-info-full))
+ :procMacro (:enable ,(lsp-json-bool lsp-rust-analyzer-proc-macro-enable))
+ :rustcSource ,lsp-rust-analyzer-rustc-source
+ :linkedProjects ,lsp-rust-analyzer-linked-projects
+ :highlighting (:strings ,(lsp-json-bool lsp-rust-analyzer-highlighting-strings))
+ :experimental (:procAttrMacros ,(lsp-json-bool lsp-rust-analyzer-experimental-proc-attr-macros))))
+
+(defconst lsp-rust-notification-handlers
+ '(("rust-analyzer/publishDecorations" . (lambda (_w _p)))))
+
+(defconst lsp-rust-action-handlers
+ '())
+
+(define-derived-mode lsp-rust-analyzer-syntax-tree-mode special-mode "Rust-Analyzer-Syntax-Tree"
+ "Mode for the rust-analyzer syntax tree buffer.")
+
+(defun lsp-rust-analyzer-syntax-tree ()
+ "Display syntax tree for current buffer."
+ (interactive)
+ (-let* ((root (lsp-workspace-root default-directory))
+ (params (lsp-make-rust-analyzer-syntax-tree-params
+ :text-document (lsp--text-document-identifier)
+ :range? (if (use-region-p)
+ (lsp--region-to-range (region-beginning) (region-end))
+ (lsp--region-to-range (point-min) (point-max)))))
+ (results (lsp-send-request (lsp-make-request
+ "rust-analyzer/syntaxTree"
+ params))))
+ (let ((buf (get-buffer-create (format "*rust-analyzer syntax tree %s*" root)))
+ (inhibit-read-only t))
+ (with-current-buffer buf
+ (lsp-rust-analyzer-syntax-tree-mode)
+ (erase-buffer)
+ (insert results)
+ (goto-char (point-min)))
+ (pop-to-buffer buf))))
+
+(define-derived-mode lsp-rust-analyzer-status-mode special-mode "Rust-Analyzer-Status"
+ "Mode for the rust-analyzer status buffer.")
+
+(defun lsp-rust-analyzer-status ()
+ "Displays status information for rust-analyzer."
+ (interactive)
+ (-let* ((root (lsp-workspace-root default-directory))
+ (params (lsp-make-rust-analyzer-analyzer-status-params
+ :text-document (lsp--text-document-identifier)))
+ (results (lsp-send-request (lsp-make-request
+ "rust-analyzer/analyzerStatus"
+ params))))
+ (let ((buf (get-buffer-create (format "*rust-analyzer status %s*" root)))
+ (inhibit-read-only t))
+ (with-current-buffer buf
+ (lsp-rust-analyzer-status-mode)
+ (erase-buffer)
+ (insert results)
+ (pop-to-buffer buf)))))
+
+(defun lsp-rust-analyzer-join-lines ()
+ "Join selected lines into one, smartly fixing up whitespace and trailing commas."
+ (interactive)
+ (let* ((params (lsp-make-rust-analyzer-join-lines-params
+ :text-document (lsp--text-document-identifier)
+ :ranges (vector (if (use-region-p)
+ (lsp--region-to-range (region-beginning) (region-end))
+ (lsp--region-to-range (point) (point))))))
+ (result (lsp-send-request (lsp-make-request "experimental/joinLines" params))))
+ (lsp--apply-text-edits result 'code-action)))
+
+(defun lsp-rust-analyzer-reload-workspace ()
+ "Reload workspace, picking up changes from Cargo.toml"
+ (interactive)
+ (lsp--cur-workspace-check)
+ (lsp-send-request (lsp-make-request "rust-analyzer/reloadWorkspace")))
+
+(defcustom lsp-rust-analyzer-download-url
+ (format "https://github.com/rust-analyzer/rust-analyzer/releases/latest/download/%s"
+ (pcase system-type
+ ('gnu/linux "rust-analyzer-x86_64-unknown-linux-gnu.gz")
+ ('darwin "rust-analyzer-x86_64-apple-darwin.gz")
+ ('windows-nt "rust-analyzer-x86_64-pc-windows-msvc.gz")))
+ "Automatic download url for Rust Analyzer"
+ :type 'string
+ :group 'lsp-rust-analyzer
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-rust-analyzer-store-path (f-join lsp-server-install-dir
+ "rust"
+ (if (eq system-type 'windows-nt)
+ "rust-analyzer.exe"
+ "rust-analyzer"))
+ "The path to the file in which `rust-analyzer' will be stored."
+ :type 'file
+ :group 'lsp-rust-analyzer
+ :package-version '(lsp-mode . "8.0.0"))
+
+(lsp-dependency
+ 'rust-analyzer
+ `(:download :url lsp-rust-analyzer-download-url
+ :decompress :gzip
+ :store-path lsp-rust-analyzer-store-path
+ :set-executable? t)
+ '(:system "rust-analyzer"))
+
+(lsp-defun lsp-rust--analyzer-run-single ((&Command :arguments?))
+ (lsp-rust-analyzer-run (lsp-seq-first arguments?)))
+
+(lsp-defun lsp-rust--analyzer-show-references
+ ((&Command :title :arguments? [_uri _filepos references]))
+ (lsp-show-xrefs (lsp--locations-to-xref-items references) nil
+ (s-contains-p "reference" title)))
+
+(declare-function dap-debug "ext:dap-mode" (template) t)
+
+(lsp-defun lsp-rust--analyzer-debug-lens ((&Command :arguments? [args]))
+ (lsp-rust-analyzer-debug args))
+
+(lsp-register-client
+ (make-lsp-client
+ :new-connection (lsp-stdio-connection
+ (lambda ()
+ `(,(or (executable-find
+ (cl-first lsp-rust-analyzer-server-command))
+ (lsp-package-path 'rust-analyzer)
+ "rust-analyzer")
+ ,@(cl-rest lsp-rust-analyzer-server-command))))
+ :major-modes '(rust-mode rustic-mode)
+ :priority (if (eq lsp-rust-server 'rust-analyzer) 1 -1)
+ :initialization-options 'lsp-rust-analyzer--make-init-options
+ :notification-handlers (ht<-alist lsp-rust-notification-handlers)
+ :action-handlers (ht ("rust-analyzer.runSingle" #'lsp-rust--analyzer-run-single)
+ ("rust-analyzer.debugSingle" #'lsp-rust--analyzer-debug-lens)
+ ("rust-analyzer.showReferences" #'lsp-rust--analyzer-show-references))
+ :library-folders-fn (lambda (_workspace) lsp-rust-library-directories)
+ :after-open-fn (lambda ()
+ (when lsp-rust-analyzer-server-display-inlay-hints
+ (lsp-rust-analyzer-inlay-hints-mode)))
+ :ignore-messages nil
+ :server-id 'rust-analyzer
+ :custom-capabilities `((experimental . ((snippetTextEdit . ,(and lsp-enable-snippet (featurep 'yasnippet))))))
+ :download-server-fn (lambda (_client callback error-callback _update?)
+ (lsp-package-ensure 'rust-analyzer callback error-callback))))
+
+(defun lsp-rust-switch-server (&optional lsp-server)
+ "Switch priorities of lsp servers, unless LSP-SERVER is already active."
+ (interactive)
+ (let ((current-server (if (> (lsp--client-priority (gethash 'rls lsp-clients)) 0)
+ 'rls
+ 'rust-analyzer)))
+ (unless (eq lsp-server current-server)
+ (dolist (server '(rls rust-analyzer))
+ (when (natnump (setf (lsp--client-priority (gethash server lsp-clients))
+ (* (lsp--client-priority (gethash server lsp-clients)) -1)))
+ (message (format "Switched to server %s." server)))))))
+
+;; inlay hints
+
+(defvar-local lsp-rust-analyzer-inlay-hints-timer nil)
+
+(defface lsp-rust-analyzer-inlay-face
+ '((t :inherit font-lock-comment-face))
+ "The face to use for the Rust Analyzer inlays."
+ :group 'lsp-rust-analyzer
+ :package-version '(lsp-mode . "7.0"))
+
+(defface lsp-rust-analyzer-inlay-type-face
+ '((t :inherit lsp-rust-analyzer-inlay-face))
+ "Face for inlay type hints (e.g. inferred variable types)."
+ :group 'lsp-rust-analyzer
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-rust-analyzer-inlay-type-format ": %s"
+ "Format string for variable inlays (part of the inlay face,
+used only if lsp-rust-analyzer-server-format-inlay-hints is
+non-nil)."
+ :type '(string :tag "String")
+ :group 'lsp-rust-analyzer
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defface lsp-rust-analyzer-inlay-param-face
+ '((t :inherit lsp-rust-analyzer-inlay-face))
+ "Face for inlay parameter hints (e.g. function parameter names at call-site)."
+ :group 'lsp-rust-analyzer
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-rust-analyzer-inlay-param-format "%s:"
+ "Format string for parameter inlays (part of the inlay face,
+used only if lsp-rust-analyzer-server-format-inlay-hints is
+non-nil)."
+ :type '(string :tag "String")
+ :group 'lsp-rust-analyzer
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-rust-analyzer-debug-lens-extra-dap-args
+ '(:MIMode "gdb" :miDebuggerPath "gdb" :stopAtEntry t :externalConsole :json-false)
+ "Extra arguments to pass to DAP template when debugging a test from code lens.
+
+As a rule of the thumb, do not add extra keys to this plist unless you exactly
+what you are doing, it might break the \"Debug test\" lens otherwise.
+
+See dap-mode documentation and cpptools documentation for the extra variables
+meaning."
+ :type 'plist
+ :group 'lsp-rust-analyzer
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defun lsp-rust-analyzer-update-inlay-hints (buffer)
+ (if (and (lsp-rust-analyzer-initialized?)
+ (eq buffer (current-buffer)))
+ (lsp-request-async
+ "textDocument/inlayHint"
+ (lsp-make-rust-analyzer-inlay-hints-params
+ :text-document (lsp--text-document-identifier)
+ :range (if (use-region-p)
+ (lsp--region-to-range (region-beginning) (region-end))
+ (lsp--region-to-range (point-min) (point-max))))
+ (lambda (res)
+ (remove-overlays (point-min) (point-max) 'lsp-rust-analyzer-inlay-hint t)
+ (dolist (hint res)
+ (-let* (((&rust-analyzer:InlayHint :position :label :kind :padding-left :padding-right) hint)
+ (pos (lsp--position-to-point position))
+ (overlay (make-overlay pos pos nil 'front-advance 'end-advance)))
+ (overlay-put overlay 'lsp-rust-analyzer-inlay-hint t)
+ (overlay-put overlay 'before-string
+ (format "%s%s%s"
+ (if padding-left " " "")
+ (propertize (lsp-rust-analyzer-format-inlay label kind)
+ 'font-lock-face (lsp-rust-analyzer-face-for-inlay kind))
+ (if padding-right " " ""))))))
+ :mode 'tick))
+ nil)
+
+(defun lsp-rust-analyzer-format-inlay (label kind)
+ (if lsp-rust-analyzer-server-format-inlay-hints
+ label
+ (cond
+ ((eql kind lsp/rust-analyzer-inlay-hint-kind-type-hint) (format lsp-rust-analyzer-inlay-type-format label))
+ ((eql kind lsp/rust-analyzer-inlay-hint-kind-type-hint) (format lsp-rust-analyzer-inlay-param-format label))
+ (t label))))
+
+(defun lsp-rust-analyzer-face-for-inlay (kind)
+ (cond
+ ((eql kind lsp/rust-analyzer-inlay-hint-kind-type-hint) 'lsp-rust-analyzer-inlay-type-face)
+ ((eql kind lsp/rust-analyzer-inlay-hint-kind-type-hint) 'lsp-rust-analyzer-inlay-param-face)
+ (t 'lsp-rust-analyzer-inlay-face)))
+
+(defun lsp-rust-analyzer-initialized? ()
+ (when-let ((workspace (lsp-find-workspace 'rust-analyzer (buffer-file-name))))
+ (eq 'initialized (lsp--workspace-status workspace))))
+
+(defun lsp-rust-analyzer-inlay-hints-change-handler (&rest _rest)
+ (when lsp-rust-analyzer-inlay-hints-timer
+ (cancel-timer lsp-rust-analyzer-inlay-hints-timer))
+ (setq lsp-rust-analyzer-inlay-hints-timer
+ (run-with-idle-timer 0.1 nil #'lsp-rust-analyzer-update-inlay-hints (current-buffer))))
+
+(define-minor-mode lsp-rust-analyzer-inlay-hints-mode
+ "Mode for displaying inlay hints."
+ :lighter nil
+ (cond
+ (lsp-rust-analyzer-inlay-hints-mode
+ (lsp-rust-analyzer-update-inlay-hints (current-buffer))
+ (add-hook 'lsp-on-change-hook #'lsp-rust-analyzer-inlay-hints-change-handler nil t))
+ (t
+ (remove-overlays (point-min) (point-max) 'lsp-rust-analyzer-inlay-hint t)
+ (remove-hook 'lsp-on-change-hook #'lsp-rust-analyzer-inlay-hints-change-handler t))))
+
+(defun lsp-rust-analyzer-expand-macro ()
+ "Expands the macro call at point recursively."
+ (interactive)
+ (-if-let* ((params (lsp-make-rust-analyzer-expand-macro-params
+ :text-document (lsp--text-document-identifier)
+ :position (lsp--cur-position)))
+ (response (lsp-request
+ "rust-analyzer/expandMacro"
+ params))
+ ((&rust-analyzer:ExpandedMacro :expansion) response))
+ (funcall lsp-rust-analyzer-macro-expansion-method expansion)
+ (lsp--error "No macro found at point, or it could not be expanded.")))
+
+(defun lsp-rust-analyzer-macro-expansion-default (result)
+ "Default method for displaying macro expansion."
+ (let* ((root (lsp-workspace-root default-directory))
+ (buf (get-buffer-create (get-buffer-create (format "*rust-analyzer macro expansion %s*" root)))))
+ (with-current-buffer buf
+ (let ((inhibit-read-only t))
+ (erase-buffer)
+ (insert (lsp--render-string result "rust"))
+ (special-mode)))
+ (pop-to-buffer buf)))
+
+;; runnables
+(defvar lsp-rust-analyzer--last-runnable nil)
+
+(defun lsp-rust-analyzer--runnables ()
+ (lsp-send-request (lsp-make-request
+ "experimental/runnables"
+ (lsp-make-rust-analyzer-runnables-params
+ :text-document (lsp--text-document-identifier)
+ :position? (lsp--cur-position)))))
+
+(defun lsp-rust-analyzer--select-runnable ()
+ (lsp--completing-read
+ "Select runnable:"
+ (if lsp-rust-analyzer--last-runnable
+ (cons lsp-rust-analyzer--last-runnable
+ (-remove (-lambda ((&rust-analyzer:Runnable :label))
+ (equal label (lsp-get lsp-rust-analyzer--last-runnable :label)))
+ (lsp-rust-analyzer--runnables)))
+ (lsp-rust-analyzer--runnables))
+ (-lambda ((&rust-analyzer:Runnable :label)) label)))
+
+
+(defun lsp-rust-analyzer--common-runner (runnable)
+ "Execute a given RUNNABLE.
+
+Extract the arguments, prepare the minor mode (cargo-process-mode if possible)
+and run a compilation"
+ (-let* (((&rust-analyzer:Runnable :kind :label :args) runnable)
+ ((&rust-analyzer:RunnableArgs :cargo-args :executable-args :workspace-root?) args)
+ (default-directory (or workspace-root? default-directory)))
+ (if (not (string-equal kind "cargo"))
+ (lsp--error "'%s' runnable is not supported" kind)
+ (compilation-start
+ (string-join (append (list "cargo") cargo-args (when executable-args '("--")) executable-args '()) " ")
+ ;; cargo-process-mode is nice, but try to work without it...
+ (if (functionp 'cargo-process-mode) 'cargo-process-mode nil)
+ (lambda (_) (concat "*" label "*"))))))
+
+
+(defun lsp-rust-analyzer-run (runnable)
+ "Select and run a RUNNABLE action."
+ (interactive (list (lsp-rust-analyzer--select-runnable)))
+ (when (lsp-rust-analyzer--common-runner runnable)
+ (setq lsp-rust-analyzer--last-runnable runnable)))
+
+(defun lsp-rust-analyzer-debug (runnable)
+ "Select and debug a RUNNABLE action."
+ (interactive (list (lsp-rust-analyzer--select-runnable)))
+ (unless (featurep 'dap-cpptools)
+ (user-error "You must require `dap-cpptools'"))
+ (-let (((&rust-analyzer:Runnable
+ :args (&rust-analyzer:RunnableArgs :cargo-args :workspace-root? :executable-args)
+ :label) runnable))
+ (pcase (aref cargo-args 0)
+ ("run" (aset cargo-args 0 "build"))
+ ("test" (when (-contains? (append cargo-args ()) "--no-run")
+ (cl-callf append cargo-args (list "--no-run")))))
+ (->> (append (list (executable-find "cargo"))
+ cargo-args
+ (list "--message-format=json"))
+ (s-join " ")
+ (shell-command-to-string)
+ (s-lines)
+ (-keep (lambda (s)
+ (condition-case nil
+ (-let* ((json-object-type 'plist)
+ ((msg &as &plist :reason :executable) (json-read-from-string s)))
+ (when (and executable (string= "compiler-artifact" reason))
+ executable))
+ (error))))
+ (funcall
+ (lambda (artifact-spec)
+ (pcase artifact-spec
+ (`() (user-error "No compilation artifacts or obtaining the runnable artifacts failed"))
+ (`(,spec) spec)
+ (_ (user-error "Multiple compilation artifacts are not supported")))))
+ (list :type "cppdbg"
+ :request "launch"
+ :name label
+ :args executable-args
+ :cwd workspace-root?
+ :sourceLanguages ["rust"]
+ :program)
+ (append lsp-rust-analyzer-debug-lens-extra-dap-args)
+ (dap-debug))))
+
+(defun lsp-rust-analyzer-rerun (&optional runnable)
+ (interactive (list (or lsp-rust-analyzer--last-runnable
+ (lsp-rust-analyzer--select-runnable))))
+ (lsp-rust-analyzer-run (or runnable lsp-rust-analyzer--last-runnable)))
+
+;; goto parent module
+(cl-defun lsp-rust-find-parent-module (&key display-action)
+ "Find parent module of current module."
+ (interactive)
+ (lsp-find-locations "experimental/parentModule" nil :display-action display-action))
+
+(defun lsp-rust-analyzer-open-cargo-toml (&optional new-window)
+ "Open the closest Cargo.toml from the current file.
+
+Rust-Analyzer LSP protocol documented here and added in November 2020
+https://github.com/rust-analyzer/rust-analyzer/blob/master/docs/dev/lsp-extensions.md#open-cargotoml
+
+If NEW-WINDOW (interactively the prefix argument) is non-nil,
+open in a new window."
+ (interactive "P")
+ (-if-let (workspace (lsp-find-workspace 'rust-analyzer (buffer-file-name)))
+ (-if-let* ((response (with-lsp-workspace workspace
+ (lsp-send-request (lsp-make-request
+ "experimental/openCargoToml"
+ (lsp-make-rust-analyzer-open-cargo-toml-params
+ :text-document (lsp--text-document-identifier))))))
+ ((&Location :uri :range) response))
+ (funcall (if new-window #'find-file-other-window #'find-file)
+ (lsp--uri-to-path uri))
+ (lsp--warn "Couldn't find a Cargo.toml file or your version of rust-analyzer doesn't support this extension"))
+ (lsp--error "OpenCargoToml is an extension available only with rust-analyzer")))
+
+(defun lsp-rust-analyzer-open-external-docs ()
+ "Open a URL for documentation related to the current TextDocumentPosition.
+
+Rust-Analyzer LSP protocol documented here
+https://github.com/rust-analyzer/rust-analyzer/blob/master/docs/dev/lsp-extensions.md#open-external-documentation"
+ (interactive)
+ (-if-let* ((params (lsp-make-rust-analyzer-open-external-docs-params
+ :text-document (lsp--text-document-identifier)
+ :position (lsp--cur-position)))
+ (url (lsp-request "experimental/externalDocs" params)))
+ (browse-url url)
+ (lsp--warn "Couldn't find documentation URL or your version of rust-analyzer doesn't support this extension")))
+
+(defun lsp-rust-analyzer--related-tests ()
+ "Get runnable test items related to the current TextDocumentPosition.
+Calls a rust-analyzer LSP extension endpoint that returns a wrapper over Runnable[]"
+ (lsp-send-request (lsp-make-request
+ "rust-analyzer/relatedTests"
+ (lsp--text-document-position-params))))
+
+(defun lsp-rust-analyzer--select-related-test ()
+ "Call the endpoint and ask for user selection.
+
+Cannot reuse `lsp-rust-analyzer--select-runnable' because the runnables endpoint
+responds with Runnable[], while relatedTests responds with TestInfo[], which is a wrapper
+over runnable. Also, this method doesn't set the `lsp-rust-analyzer--last-runnable' variable"
+ (-if-let* ((resp (lsp-rust-analyzer--related-tests))
+ (runnables (seq-map
+ #'lsp:rust-analyzer-related-tests-runnable
+ resp)))
+ (lsp--completing-read
+ "Select test: "
+ runnables
+ #'lsp:rust-analyzer-runnable-label)))
+
+(defun lsp-rust-analyzer-related-tests (runnable)
+ "Execute a RUNNABLE test related to the current document position.
+
+Rust-Analyzer LSP protocol extension
+https://github.com/rust-analyzer/rust-analyzer/blob/master/docs/dev/lsp-extensions.md#related-tests"
+ (interactive (list (lsp-rust-analyzer--select-related-test)))
+ (if runnable
+ (lsp-rust-analyzer--common-runner runnable)
+ (lsp--info "There are no tests related to the symbol at point")))
+
+(defun lsp-rust-analyzer-move-item (direction)
+ "Move item under cursor or selection in some DIRECTION"
+ (let* ((params (lsp-make-rust-analyzer-move-item-params
+ :text-document (lsp--text-document-identifier)
+ :range (if (use-region-p)
+ (lsp--region-to-range (region-beginning) (region-end))
+ (lsp--region-to-range (point) (point)))
+ :direction direction))
+ (edits (lsp-request "experimental/moveItem" params)))
+ (lsp--apply-text-edits edits 'code-action)))
+
+(defun lsp-rust-analyzer-move-item-up ()
+ "Move item under cursor or selection up"
+ (interactive)
+ (lsp-rust-analyzer-move-item "Up"))
+
+(defun lsp-rust-analyzer-move-item-down ()
+ "Move item under cursor or selection down"
+ (interactive)
+ (lsp-rust-analyzer-move-item "Down"))
+
+(lsp-consistency-check lsp-rust)
+
+(provide 'lsp-rust)
+;;; lsp-rust.el ends here
diff --git a/elpa/lsp-mode-20220505.630/lsp-rust.elc b/elpa/lsp-mode-20220505.630/lsp-rust.elc
new file mode 100644
index 0000000..284ba36
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-rust.elc
Binary files differ
diff --git a/elpa/lsp-mode-20220505.630/lsp-semantic-tokens.el b/elpa/lsp-mode-20220505.630/lsp-semantic-tokens.el
new file mode 100644
index 0000000..35fb8ba
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-semantic-tokens.el
@@ -0,0 +1,876 @@
+;;; lsp-semantic-tokens.el --- Semantic tokens -*- lexical-binding: t; -*-
+;;
+;; Copyright (C) 2020 emacs-lsp maintainers
+;;
+;; 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 <https://www.gnu.org/licenses/>.
+;;
+;;; Commentary:
+;;
+;; Semantic tokens
+;; https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_semanticTokens
+;;
+;;; Code:
+
+(require 'lsp-mode)
+(require 'dash)
+
+(defgroup lsp-semantic-tokens nil
+ "LSP support for semantic-tokens."
+ :prefix "lsp-semantic-tokens-"
+ :group 'lsp-mode
+ :tag "LSP Semantic tokens")
+
+(define-obsolete-variable-alias 'lsp-semantic-highlighting-warn-on-missing-face 'lsp-semantic-tokens-warn-on-missing-face "lsp-mode 8.0.0")
+
+(defcustom lsp-semantic-tokens-warn-on-missing-face nil
+ "Warning on missing face for token type/modifier.
+When non-nil, this option will emit a warning any time a token
+or modifier type returned by a language server has no face associated with it."
+ :group 'lsp-semantic-tokens
+ :type 'boolean)
+
+(defcustom lsp-semantic-tokens-apply-modifiers t
+ "Whether semantic tokens should take token modifiers into account."
+ :group 'lsp-semantic-tokens
+ :type 'boolean)
+
+(defcustom lsp-semantic-tokens-allow-ranged-requests t
+ "Whether to use ranged semantic token requests when available.
+
+Note that even when this is set to t, delta requests will
+be preferred whenever possible, unless
+`lsp-semantic-tokens-allow-delta-requests' is false."
+ :group 'lsp-semantic-tokens
+ :type 'boolean)
+
+(defcustom lsp-semantic-tokens-allow-delta-requests t
+ "Whether to use semantic token delta requests when available.
+
+When supported by the language server, delta requests are always
+preferred over both full and ranged token requests."
+ :group 'lsp-semantic-tokens
+ :type 'boolean)
+
+(defcustom lsp-semantic-tokens-honor-refresh-requests nil
+ "Whether to honor semanticTokens/refresh requests.
+
+When set to nil, refresh requests will be silently discarded.
+When set to t, semantic tokens will be re-requested for all buffers
+associated with the requesting language server."
+ :group 'lsp-semantic-tokens
+ :type 'boolean)
+
+(defface lsp-face-semhl-constant
+ '((t :inherit font-lock-constant-face))
+ "Face used for semantic highlighting scopes matching constant scopes."
+ :group 'lsp-semantic-tokens)
+
+(defface lsp-face-semhl-variable
+ '((t :inherit font-lock-variable-name-face))
+ "Face used for semantic highlighting scopes matching variable.*.
+Unless overridden by a more specific face association."
+ :group 'lsp-semantic-tokens)
+
+(defface lsp-face-semhl-function
+ '((t :inherit font-lock-function-name-face))
+ "Face used for semantic highlighting scopes matching entity.name.function.*.
+Unless overridden by a more specific face association."
+ :group 'lsp-semantic-tokens)
+
+(defface lsp-face-semhl-method
+ '((t :inherit lsp-face-semhl-function))
+ "Face used for semantic highlighting scopes matching entity.name.method.*.
+Unless overridden by a more specific face association."
+ :group 'lsp-semantic-tokens)
+
+(defface lsp-face-semhl-namespace
+ '((t :inherit font-lock-type-face :weight bold))
+ "Face used for semantic highlighting scopes matching entity.name.namespace.*.
+Unless overridden by a more specific face association."
+ :group 'lsp-semantic-tokens)
+
+(defface lsp-face-semhl-comment
+ '((t (:inherit font-lock-comment-face)))
+ "Face used for comments."
+ :group 'lsp-semantic-tokens)
+
+(defface lsp-face-semhl-keyword
+ '((t (:inherit font-lock-keyword-face)))
+ "Face used for keywords."
+ :group 'lsp-semantic-tokens)
+
+(defface lsp-face-semhl-string
+ '((t (:inherit font-lock-string-face)))
+ "Face used for keywords."
+ :group 'lsp-semantic-tokens)
+
+(defface lsp-face-semhl-number
+ '((t (:inherit font-lock-constant-face)))
+ "Face used for numbers."
+ :group 'lsp-semantic-tokens)
+
+(defface lsp-face-semhl-regexp
+ '((t (:inherit font-lock-string-face :slant italic)))
+ "Face used for regexps."
+ :group 'lsp-semantic-tokens)
+
+(defface lsp-face-semhl-operator
+ '((t (:inherit font-lock-function-name-face)))
+ "Face used for operators."
+ :group 'lsp-semantic-tokens)
+
+(defface lsp-face-semhl-namespace
+ '((t (:inherit font-lock-keyword-face)))
+ "Face used for namespaces."
+ :group 'lsp-semantic-tokens)
+
+(defface lsp-face-semhl-type
+ '((t (:inherit font-lock-type-face)))
+ "Face used for types."
+ :group 'lsp-semantic-tokens)
+
+(defface lsp-face-semhl-struct
+ '((t (:inherit font-lock-type-face)))
+ "Face used for structs."
+ :group 'lsp-semantic-tokens)
+
+(defface lsp-face-semhl-class
+ '((t (:inherit font-lock-type-face)))
+ "Face used for classes."
+ :group 'lsp-semantic-tokens)
+
+(defface lsp-face-semhl-interface
+ '((t (:inherit font-lock-type-face)))
+ "Face used for interfaces."
+ :group 'lsp-semantic-tokens)
+
+(defface lsp-face-semhl-enum
+ '((t (:inherit font-lock-type-face)))
+ "Face used for enums."
+ :group 'lsp-semantic-tokens)
+
+(defface lsp-face-semhl-type-parameter
+ '((t (:inherit font-lock-type-face)))
+ "Face used for type parameters."
+ :group 'lsp-semantic-tokens)
+
+;; function face already defined, move here when support
+;; for theia highlighting gets removed
+(defface lsp-face-semhl-member
+ '((t (:inherit font-lock-variable-name-face)))
+ "Face used for members."
+ :group 'lsp-semantic-tokens)
+
+(defface lsp-face-semhl-property
+ '((t (:inherit font-lock-variable-name-face)))
+ "Face used for properties."
+ :group 'lsp-semantic-tokens)
+
+(defface lsp-face-semhl-event
+ '((t (:inherit font-lock-variable-name-face)))
+ "Face used for event properties."
+ :group 'lsp-semantic-tokens)
+
+(defface lsp-face-semhl-macro
+ '((t (:inherit font-lock-preprocessor-face)))
+ "Face used for macros."
+ :group 'lsp-semantic-tokens)
+
+(defface lsp-face-semhl-variable
+ '((t (:inherit font-lock-variable-name-face)))
+ "Face used for variables."
+ :group 'lsp-semantic-tokens)
+
+(defface lsp-face-semhl-parameter
+ '((t (:inherit font-lock-variable-name-face)))
+ "Face used for parameters."
+ :group 'lsp-semantic-tokens)
+
+(defface lsp-face-semhl-label
+ '((t (:inherit font-lock-comment-face)))
+ "Face used for labels."
+ :group 'lsp-semantic-tokens)
+
+(defface lsp-face-semhl-deprecated
+ '((t :strike-through t))
+ "Face used for semantic highlighting scopes matching constant scopes."
+ :group 'lsp-semantic-tokens)
+
+(defface lsp-face-semhl-definition
+ '((t :inherit font-lock-function-name-face :weight bold))
+ "Face used for definition modifier."
+ :group 'lsp-semantic-tokens)
+
+(defface lsp-face-semhl-implementation
+ '((t :inherit font-lock-function-name-face :weight bold))
+ "Face used for implementation modifier."
+ :group 'lsp-semantic-tokens)
+
+(defface lsp-face-semhl-default-library
+ '((t :inherit font-lock-builtin-face))
+ "Face used for defaultLibrary modifier."
+ :group 'lsp-semantic-tokens)
+
+(defface lsp-face-semhl-static
+ '((t :inherit font-lock-keyword-face))
+ "Face used for static modifier."
+ :group 'lsp-semantic-tokens)
+
+(defvar lsp-semantic-token-faces
+ '(("comment" . lsp-face-semhl-comment)
+ ("keyword" . lsp-face-semhl-keyword)
+ ("string" . lsp-face-semhl-string)
+ ("number" . lsp-face-semhl-number)
+ ("regexp" . lsp-face-semhl-regexp)
+ ("operator" . lsp-face-semhl-operator)
+ ("namespace" . lsp-face-semhl-namespace)
+ ("type" . lsp-face-semhl-type)
+ ("struct" . lsp-face-semhl-struct)
+ ("class" . lsp-face-semhl-class)
+ ("interface" . lsp-face-semhl-interface)
+ ("enum" . lsp-face-semhl-enum)
+ ("typeParameter" . lsp-face-semhl-type-parameter)
+ ("function" . lsp-face-semhl-function)
+ ("method" . lsp-face-semhl-method)
+ ("member" . lsp-face-semhl-member)
+ ("property" . lsp-face-semhl-property)
+ ("event" . lsp-face-semhl-event)
+ ("macro" . lsp-face-semhl-macro)
+ ("variable" . lsp-face-semhl-variable)
+ ("parameter" . lsp-face-semhl-parameter)
+ ("label" . lsp-face-semhl-label)
+ ("enumConstant" . lsp-face-semhl-constant)
+ ("enumMember" . lsp-face-semhl-constant)
+ ("dependent" . lsp-face-semhl-type)
+ ("concept" . lsp-face-semhl-interface))
+ "Faces to use for semantic tokens.")
+
+(defvar lsp-semantic-token-modifier-faces
+ '(("declaration" . lsp-face-semhl-interface)
+ ("definition" . lsp-face-semhl-definition)
+ ("implementation" . lsp-face-semhl-implementation)
+ ("readonly" . lsp-face-semhl-constant)
+ ("static" . lsp-face-semhl-static)
+ ("deprecated" . lsp-face-semhl-deprecated)
+ ("abstract" . lsp-face-semhl-keyword)
+ ("async" . lsp-face-semhl-macro)
+ ("modification" . lsp-face-semhl-operator)
+ ("documentation" . lsp-face-semhl-comment)
+ ("defaultLibrary" . lsp-face-semhl-default-library))
+ "Semantic tokens modifier faces.
+Faces to use for semantic token modifiers if
+`lsp-semantic-tokens-apply-modifiers' is non-nil.")
+
+(defvar lsp-semantic-tokens-capabilities
+ `((semanticTokens
+ . ((dynamicRegistration . t)
+ (requests . ((range . t) (full . t)))
+ (tokenModifiers . ,(if lsp-semantic-tokens-apply-modifiers
+ (apply 'vector (mapcar #'car lsp-semantic-token-modifier-faces))
+ []))
+ (tokenTypes . ,(apply 'vector (mapcar #'car lsp-semantic-token-faces)))
+ (formats . ["relative"])))))
+
+(defvar lsp--semantic-tokens-pending-full-token-requests '()
+ "Buffers which should have their semantic tokens refreshed on idle.
+
+This is an alist of the form ((buffer_i . fontify_immediately_i) ...); entries
+with fontify_immediately set to t will immediately refontify once their
+token request is answered.")
+
+;; NOTE: doesn't keep track of outstanding requests, so might still produce large latency outliers
+;; if the language server doesn't process all outstanding token requests within one lsp-idle-delay
+(defcustom lsp-semantic-tokens-max-concurrent-idle-requests 1
+ "Maximum number of on-idle token requests to be dispatched simultaneously."
+ :group 'lsp-semantic-tokens
+ :type 'integer)
+
+(defvar lsp--semantic-tokens-idle-timer nil)
+
+(defun lsp--semantic-tokens-process-pending-requests ()
+ (let ((fuel lsp-semantic-tokens-max-concurrent-idle-requests))
+ (while (and lsp--semantic-tokens-pending-full-token-requests (> fuel 0))
+ (-let (((buffer . fontify-immediately) (pop lsp--semantic-tokens-pending-full-token-requests)))
+ (when (buffer-live-p buffer)
+ (setq fuel (1- fuel))
+ (with-current-buffer buffer
+ (lsp--semantic-tokens-request nil fontify-immediately))))))
+ (unless lsp--semantic-tokens-pending-full-token-requests
+ (cancel-timer lsp--semantic-tokens-idle-timer)
+ (setq lsp--semantic-tokens-idle-timer nil)))
+
+(defun lsp--semantic-tokens-sort-pending-requests (pending-requests)
+ ;; service currently visible buffers first, otherwise prefer immediate-fontification requests
+ (-sort (lambda (entry-a entry-b)
+ (let ((a-hidden (eq nil (get-buffer-window (car entry-a))))
+ (b-hidden (eq nil (get-buffer-window (car entry-b)))))
+ (cond ((and b-hidden (not a-hidden)) t) ; sort a before b
+ ((and a-hidden (not b-hidden)) nil) ; sort b before a
+ ((and (not (cdr entry-a)) (cdr entry-b)) nil) ; otherwise sort b before a only if b is immediate and a is not
+ (t t))))
+ (--filter (buffer-live-p (car it)) pending-requests)))
+
+(defun lsp--semantic-tokens-request-full-token-set-when-idle (buffer fontify-immediately)
+ "Request full token set after an idle timeout of `lsp-idle-delay'.
+
+If FONTIFY-IMMEDIATELY is non-nil, fontification will be performed immediately
+ once the corresponding response is received."
+ (let ((do-fontify-immediately (or fontify-immediately
+ (cdr (assoc buffer lsp--semantic-tokens-pending-full-token-requests)))))
+ (setq lsp--semantic-tokens-pending-full-token-requests
+ (lsp--semantic-tokens-sort-pending-requests
+ (cons (cons buffer do-fontify-immediately)
+ (--remove (eq buffer (car it)) lsp--semantic-tokens-pending-full-token-requests)))))
+ (unless lsp--semantic-tokens-idle-timer
+ (setq lsp--semantic-tokens-idle-timer
+ (run-with-idle-timer lsp-idle-delay t #'lsp--semantic-tokens-process-pending-requests))))
+
+(defun lsp--semantic-tokens-refresh-if-enabled (buffer)
+ (when (buffer-local-value 'lsp-semantic-tokens-mode buffer)
+ (lsp--semantic-tokens-request-full-token-set-when-idle buffer t)))
+
+(defvar-local lsp--semantic-tokens-cache nil
+ "Previously returned token set.
+
+When non-nil, `lsp--semantic-tokens-cache' should adhere to the
+following lsp-interface:
+`(_SemanticTokensCache
+ (:_documentVersion)
+ (:response :_region :_truncated))'.")
+
+(defsubst lsp--semantic-tokens-putcache (k v)
+ "Set key K of `lsp--semantic-tokens-cache' to V."
+ (setq lsp--semantic-tokens-cache
+ (plist-put lsp--semantic-tokens-cache k v)))
+
+(defvar-local lsp--semantic-tokens-teardown nil)
+
+(defun lsp--semantic-tokens-ingest-range-response (response)
+ "Handle RESPONSE to semanticTokens/range request."
+ (lsp--semantic-tokens-putcache :response response)
+ (cl-assert (plist-get lsp--semantic-tokens-cache :_region))
+ (lsp--semantic-tokens-request-full-token-set-when-idle (current-buffer) nil))
+
+(defun lsp--semantic-tokens-ingest-full-response (response)
+ "Handle RESPONSE to semanticTokens/full request."
+ (lsp--semantic-tokens-putcache :response response)
+ (cl-assert (not (plist-get lsp--semantic-tokens-cache :_region))))
+
+(defsubst lsp--semantic-tokens-apply-delta-edits (old-data edits)
+ "Apply EDITS obtained from full/delta request to OLD-DATA."
+ (let* ((old-token-count (length old-data))
+ (old-token-index 0)
+ (substrings))
+ (cl-loop
+ for edit across edits
+ do
+ (when (< old-token-index (lsp-get edit :start))
+ (push (substring old-data old-token-index (lsp-get edit :start)) substrings))
+ (push (lsp-get edit :data) substrings)
+ (setq old-token-index (+ (lsp-get edit :start) (lsp-get edit :deleteCount)))
+ finally do (push (substring old-data old-token-index old-token-count) substrings))
+ (apply #'vconcat (nreverse substrings))))
+
+(defun lsp--semantic-tokens-ingest-full/delta-response (response)
+ "Handle RESPONSE to semanticTokens/full/delta request."
+ (if (lsp-get response :edits)
+ (let ((old-data (--> lsp--semantic-tokens-cache (plist-get it :response) (lsp-get it :data))))
+ (cl-assert (not (plist-get lsp--semantic-tokens-cache :_region)))
+ (when old-data
+ (lsp--semantic-tokens-putcache
+ :response (lsp-put response
+ :data (lsp--semantic-tokens-apply-delta-edits
+ old-data (lsp-get response :edits))))))
+ ;; server decided to send full response instead
+ (lsp--semantic-tokens-ingest-full-response response)))
+
+
+(defun lsp--semantic-tokens-request (region fontify-immediately)
+ "Send semantic tokens request to the language server.
+
+A full/delta request will be sent if delta requests are supported by
+the language server, allowed via `lsp-semantic-tokens-allow-delta-requests',
+and if a full set of tokens had previously been received.
+Otherwise, a ranged request will be dispatched if REGION is non-nil,
+ranged requests are supported by the language server, and allowed via
+`lsp-semantic-tokens-allow-delta-requests'. In all other cases, a full
+tokens request will be dispatched.
+
+If FONTIFY-IMMEDIATELY is non-nil, fontification will be performed immediately
+ upon receiving the response."
+ (let ((request-type "textDocument/semanticTokens/full")
+ (request `(:textDocument ,(lsp--text-document-identifier)))
+ (response-handler nil)
+ (final-region nil))
+ (cond
+ ((and lsp-semantic-tokens-allow-delta-requests
+ (lsp-feature? "textDocument/semanticTokensFull/Delta")
+ (--> lsp--semantic-tokens-cache
+ (plist-get it :response)
+ (and (lsp-get it :resultId) (lsp-get it :data)
+ (not (plist-get lsp--semantic-tokens-cache :_region)))))
+ (setq request-type "textDocument/semanticTokens/full/delta")
+ (setq response-handler #'lsp--semantic-tokens-ingest-full/delta-response)
+ (setq request
+ (plist-put request :previousResultId
+ (lsp-get (plist-get lsp--semantic-tokens-cache :response) :resultId))))
+ ((and lsp-semantic-tokens-allow-ranged-requests region
+ (lsp-feature? "textDocument/semanticTokensRangeProvider"))
+ (setq request-type "textDocument/semanticTokens/range")
+ (setq final-region region)
+ (setq request
+ (plist-put request :range (lsp--region-to-range (car final-region) (cdr final-region))))
+ (setq response-handler #'lsp--semantic-tokens-ingest-range-response))
+ (t (setq response-handler #'lsp--semantic-tokens-ingest-full-response)))
+ (lsp-request-async
+ request-type request
+ (lambda (response)
+ (lsp--semantic-tokens-putcache :_documentVersion lsp--cur-version)
+ (lsp--semantic-tokens-putcache :_region final-region)
+ (funcall response-handler response)
+ (when (or fontify-immediately (plist-get lsp--semantic-tokens-cache :_truncated)) (font-lock-flush)))
+ :error-handler ;; buffer is not captured in `error-handler', it is in `callback'
+ (let ((buf (current-buffer)))
+ (lambda (&rest _)
+ (when (buffer-live-p buf)
+ (lsp--semantic-tokens-request-full-token-set-when-idle buf t))))
+ :mode 'tick
+ :cancel-token (format "semantic-tokens-%s" (lsp--buffer-uri)))))
+
+
+(defun lsp-semantic-tokens--fontify (old-fontify-region beg-orig end-orig &optional loudly)
+ "Apply fonts to retrieved semantic tokens.
+OLD-FONTIFY-REGION is the underlying region fontification function,
+e.g., `font-lock-fontify-region'.
+BEG-ORIG and END-ORIG deliminate the requested fontification region and maybe
+modified by OLD-FONTIFY-REGION.
+LOUDLY will be forwarded to OLD-FONTIFY-REGION as-is."
+ ;; TODO: support multiple language servers per buffer?
+ (let ((faces (seq-some #'lsp--workspace-semantic-tokens-faces lsp--buffer-workspaces))
+ (modifier-faces
+ (when lsp-semantic-tokens-apply-modifiers
+ (seq-some #'lsp--workspace-semantic-tokens-modifier-faces lsp--buffer-workspaces)))
+ old-bounds
+ beg end)
+ (cond
+ ((or (eq nil faces)
+ (eq nil lsp--semantic-tokens-cache)
+ (eq nil (plist-get lsp--semantic-tokens-cache :response)))
+ ;; default to non-semantic highlighting until first response has arrived
+ (funcall old-fontify-region beg-orig end-orig loudly))
+ ((not (= lsp--cur-version (plist-get lsp--semantic-tokens-cache :_documentVersion)))
+ ;; delay fontification until we have fresh tokens
+ '(jit-lock-bounds 0 . 0))
+ (t
+ (setq old-bounds (funcall old-fontify-region beg-orig end-orig loudly))
+ ;; this is to prevent flickering when semantic token highlighting
+ ;; is layered on top of, e.g., tree-sitter-hl, or clojure-mode's syntax highlighting.
+ (setq beg (min beg-orig (cadr old-bounds))
+ end (max end-orig (cddr old-bounds)))
+ ;; if we're using the response to a ranged request, we'll only be able to fontify within
+ ;; that range (and hence shouldn't clear any highlights outside of that range)
+ (let ((token-region (plist-get lsp--semantic-tokens-cache :_region)))
+ (if token-region
+ (progn
+ (lsp--semantic-tokens-putcache :_truncated (or (< beg (car token-region))
+ (> end (cdr token-region))))
+ (setq beg (max beg (car token-region)))
+ (setq end (min end (cdr token-region))))
+ (lsp--semantic-tokens-putcache :_truncated nil)))
+ (-let* ((inhibit-field-text-motion t)
+ (data (lsp-get (plist-get lsp--semantic-tokens-cache :response) :data))
+ (i0 0)
+ (i-max (1- (length data)))
+ (current-line 1)
+ (line-delta)
+ (column 0)
+ (face)
+ (line-start-pos)
+ (line-min)
+ (line-max-inclusive)
+ (text-property-beg)
+ (text-property-end))
+ (save-mark-and-excursion
+ (save-restriction
+ (widen)
+ (goto-char beg)
+ (goto-char (line-beginning-position))
+ (setq line-min (line-number-at-pos))
+ (with-silent-modifications
+ (goto-char end)
+ (goto-char (line-end-position))
+ (setq line-max-inclusive (line-number-at-pos))
+ (forward-line (- line-min line-max-inclusive))
+ (let ((skip-lines (- line-min current-line)))
+ (while (and (<= i0 i-max) (< (aref data i0) skip-lines))
+ (setq skip-lines (- skip-lines (aref data i0)))
+ (setq i0 (+ i0 5)))
+ (setq current-line (- line-min skip-lines)))
+ (forward-line (- current-line line-min))
+ (setq line-start-pos (point))
+ (cl-loop
+ for i from i0 to i-max by 5 do
+ (setq line-delta (aref data i))
+ (unless (= line-delta 0)
+ (forward-line line-delta)
+ (setq line-start-pos (point))
+ (setq column 0)
+ (setq current-line (+ current-line line-delta)))
+ (setq column (+ column (aref data (1+ i))))
+ (setq face (aref faces (aref data (+ i 3))))
+ (setq text-property-beg (+ line-start-pos column))
+ (setq text-property-end (+ text-property-beg (aref data (+ i 2))))
+ (when face
+ (put-text-property text-property-beg text-property-end 'face face))
+ (cl-loop for j from 0 to (1- (length modifier-faces)) do
+ (when (and (aref modifier-faces j)
+ (> (logand (aref data (+ i 4)) (lsh 1 j)) 0))
+ (add-face-text-property text-property-beg text-property-end
+ (aref modifier-faces j))))
+ when (> current-line line-max-inclusive) return nil)))))
+ `(jit-lock-bounds ,beg . ,end)))))
+
+(defun lsp-semantic-tokens--request-update ()
+ "Request semantic-tokens update."
+ ;; when dispatching ranged requests, we'll over-request by several chunks in both directions,
+ ;; which should minimize those occasions where font-lock region extension extends beyond the
+ ;; region covered by our freshly requested tokens (see lsp-mode issue #3154), while still limiting
+ ;; requests to fairly small regions even if the underlying buffer is large
+ (lsp--semantic-tokens-request
+ (cons (max (point-min) (- (window-start) (* 5 jit-lock-chunk-size)))
+ (min (point-max) (+ (window-end) (* 5 jit-lock-chunk-size)))) t))
+
+(defun lsp--semantic-tokens-as-defined-by-workspace (workspace)
+ "Return plist of token-types and token-modifiers defined by WORKSPACE,
+or nil if none are defined."
+ (when-let ((token-capabilities
+ (or
+ (-some->
+ (lsp--registered-capability "textDocument/semanticTokens")
+ (lsp--registered-capability-options))
+ (lsp:server-capabilities-semantic-tokens-provider?
+ (lsp--workspace-server-capabilities workspace)))))
+ (-let* (((&SemanticTokensOptions :legend) token-capabilities))
+ `(:token-types ,(lsp:semantic-tokens-legend-token-types legend)
+ :token-modifiers ,(lsp:semantic-tokens-legend-token-modifiers legend)))))
+
+(defun lsp-semantic-tokens-suggest-overrides ()
+ "Suggest face overrides that best match the faces
+chosen by `font-lock-fontify-region'."
+ (interactive)
+ (-when-let* ((token-info (-some #'lsp--semantic-tokens-as-defined-by-workspace lsp--buffer-workspaces))
+ ((&plist :token-types token-types :token-modifiers token-modifiers) token-info))
+ (let* ((tokens (lsp-request
+ "textDocument/semanticTokens/full"
+ `(:textDocument, (lsp--text-document-identifier))))
+ (inhibit-field-text-motion t)
+ (data (lsp-get tokens :data))
+ (associated-faces '())
+ (line-delta)
+ ;; KLUDGE: clear cache so our font-lock advice won't apply semantic-token faces
+ (old-cache lsp--semantic-tokens-cache)
+ (face-or-faces))
+ (setq lsp--semantic-tokens-cache nil)
+ (save-restriction
+ (save-excursion
+ (widen)
+ (font-lock-fontify-region (point-min) (point-max) t)
+ (save-mark-and-excursion
+ (save-restriction
+ (widen)
+ (goto-char (point-min))
+ (cl-loop
+ for i from 0 to (1- (length data)) by 5 do
+ (setq line-delta (aref data i))
+ (unless (= line-delta 0) (forward-line line-delta))
+ (forward-char (aref data (+ i 1)))
+ (setq face-or-faces (get-text-property (point) 'face))
+ ;; TODO: consider modifiers?
+ (when face-or-faces
+ (--each (if (listp face-or-faces) face-or-faces (list face-or-faces))
+ (cl-pushnew `(,(aref data (+ i 3)) . ,it) associated-faces :test #'equal))))
+ (setq lsp--semantic-tokens-cache old-cache)
+ (font-lock-flush)))))
+ (switch-to-buffer (get-buffer-create "*Suggested Overrides*"))
+ (insert "(")
+ ;; TODO: sort alternatives by frequency
+ (--each-indexed (-group-by #'car associated-faces)
+ (insert (if (= it-index 0) "(" "\n ("))
+ (insert (format "%s . " (aref token-types (car it))))
+ (--each-indexed (mapcar #'cdr (cdr it))
+ (insert (if (= it-index 0) (format "%s)" (prin1-to-string it))
+ (format " ; Alternative: %s" (prin1-to-string it))))))
+ (insert ")"))))
+
+(declare-function tree-sitter-hl-mode "ext:tree-sitter-hl")
+
+(with-eval-after-load 'tree-sitter-hl
+ (add-hook
+ 'tree-sitter-hl-mode-hook
+ (lambda ()
+ (when (and lsp-mode lsp--semantic-tokens-teardown
+ (boundp 'tree-sitter-hl-mode) tree-sitter-hl-mode)
+ (lsp-warn "It seems you have configured tree-sitter-hl to activate after lsp-mode.
+To prevent tree-sitter-hl from overriding lsp-mode's semantic token highlighting, lsp-mode
+will now disable both semantic highlighting and tree-sitter-hl mode and subsequently re-enable both,
+starting with tree-sitter-hl-mode.
+
+Please adapt your config to prevent unnecessary mode reinitialization in the future.")
+ (tree-sitter-hl-mode -1)
+ (funcall lsp--semantic-tokens-teardown)
+ (setq lsp--semantic-tokens-teardown nil)
+ (tree-sitter-hl-mode t)
+ (lsp--semantic-tokens-initialize-buffer)))))
+
+;;;###autoload
+(defun lsp--semantic-tokens-initialize-buffer ()
+ "Initialize the buffer for semantic tokens.
+IS-RANGE-PROVIDER is non-nil when server supports range requests."
+ (let* ((old-extend-region-functions font-lock-extend-region-functions)
+ ;; make sure font-lock always fontifies entire lines (TODO: do we also have
+ ;; to change some jit-lock-...-region functions/variables?)
+ (new-extend-region-functions
+ (if (memq 'font-lock-extend-region-wholelines old-extend-region-functions)
+ old-extend-region-functions
+ (cons 'font-lock-extend-region-wholelines old-extend-region-functions)))
+ (buffer (current-buffer)))
+ (setq lsp--semantic-tokens-cache nil)
+ (setq font-lock-extend-region-functions new-extend-region-functions)
+ (add-function :around (local 'font-lock-fontify-region-function) #'lsp-semantic-tokens--fontify)
+ (add-hook 'lsp-on-change-hook #'lsp-semantic-tokens--request-update nil t)
+ (lsp-semantic-tokens--request-update)
+ (setq lsp--semantic-tokens-teardown
+ (lambda ()
+ (setq lsp--semantic-tokens-pending-full-token-requests
+ (--remove (eq buffer (car it)) lsp--semantic-tokens-pending-full-token-requests))
+ (setq font-lock-extend-region-functions old-extend-region-functions)
+ (setq lsp--semantic-tokens-cache nil)
+ (remove-function (local 'font-lock-fontify-region-function)
+ #'lsp-semantic-tokens--fontify)
+ (remove-hook 'lsp-on-change-hook #'lsp-semantic-tokens--request-update t)))))
+
+(defun lsp--semantic-tokens-build-face-map (identifiers faces category varname)
+ "Build map of FACES for IDENTIFIERS using CATEGORY and VARNAME."
+ (apply 'vector
+ (mapcar (lambda (id)
+ (let ((maybe-face (cdr (assoc id faces))))
+ (when (and lsp-semantic-tokens-warn-on-missing-face (not maybe-face))
+ (lsp-warn "No face has been associated to the %s '%s': consider adding a corresponding definition to %s"
+ category id varname)) maybe-face)) identifiers)))
+
+(defun lsp-semantic-tokens--replace-alist-values (a b)
+ "Replace alist A values with B ones where available."
+ (-map
+ (-lambda ((ak . av))
+ (cons ak (alist-get ak b av nil #'string=)))
+ a))
+
+(defun lsp-semantic-tokens--type-faces-for (client)
+ "Return the semantic token type faces for CLIENT."
+ (lsp-semantic-tokens--replace-alist-values lsp-semantic-token-faces
+ (plist-get (lsp--client-semantic-tokens-faces-overrides client) :types)))
+
+(defun lsp-semantic-tokens--modifier-faces-for (client)
+ "Return the semantic token type faces for CLIENT."
+ (lsp-semantic-tokens--replace-alist-values lsp-semantic-token-modifier-faces
+ (plist-get (lsp--client-semantic-tokens-faces-overrides client) :modifiers)))
+
+(defun lsp--semantic-tokens-on-refresh (workspace)
+ "Clear semantic tokens within all buffers of WORKSPACE,
+refresh in currently active buffer."
+ (cl-assert (not (eq nil workspace)))
+ (when lsp-semantic-tokens-honor-refresh-requests
+ (cl-loop
+ for ws-buffer in (lsp--workspace-buffers workspace) do
+ (let ((fontify-immediately (equal (current-buffer) ws-buffer)))
+ (with-current-buffer ws-buffer (lsp--semantic-tokens-request nil fontify-immediately))))))
+
+;;;###autoload
+(defun lsp--semantic-tokens-initialize-workspace (workspace)
+ "Initialize semantic tokens for WORKSPACE."
+ (cl-assert workspace)
+ (-let (((&plist :token-types types :token-modifiers modifiers)
+ (lsp--semantic-tokens-as-defined-by-workspace workspace))
+ (client (lsp--workspace-client workspace)))
+ (setf (lsp--workspace-semantic-tokens-faces workspace)
+ (lsp--semantic-tokens-build-face-map
+ types (lsp-semantic-tokens--type-faces-for client)
+ "semantic token" "lsp-semantic-token-faces"))
+ (setf (lsp--workspace-semantic-tokens-modifier-faces workspace)
+ (lsp--semantic-tokens-build-face-map
+ modifiers (lsp-semantic-tokens--modifier-faces-for client)
+ "semantic token modifier" "lsp-semantic-token-modifier-faces"))))
+
+;;;###autoload
+(defun lsp-semantic-tokens--warn-about-deprecated-setting ()
+ "Warn about deprecated semantic highlighting variable."
+ (when (boundp 'lsp-semantic-highlighting)
+ (pcase lsp-semantic-highlighting
+ (:semantic-tokens
+ (lsp-warn "It seems you wish to use semanticTokens-based
+ highlighting. To do so, please remove any references to the
+ deprecated variable `lsp-semantic-highlighting' from your
+ configuration and set `lsp-semantic-tokens-enable' to `t'
+ instead.")
+ (setq lsp-semantic-tokens-enable t))
+ ((or :immediate :deferred)
+ (lsp-warn "It seems you wish to use Theia-based semantic
+ highlighting. This protocol has been superseded by the
+ semanticTokens protocol specified by LSP v3.16 and is no longer
+ supported by lsp-mode. If your language server provides
+ semanticToken support, please set
+ `lsp-semantic-tokens-enable' to `t' to use it.")))))
+
+;;;###autoload
+(defun lsp-semantic-tokens--enable ()
+ "Enable semantic tokens mode."
+ (when (and lsp-semantic-tokens-enable
+ (lsp-feature? "textDocument/semanticTokens"))
+ (lsp-semantic-tokens--warn-about-deprecated-setting)
+ (lsp-semantic-tokens-mode 1)))
+
+(defun lsp-semantic-tokens--disable ()
+ "Disable semantic tokens mode."
+ (lsp-semantic-tokens-mode -1))
+
+;;;###autoload
+(define-minor-mode lsp-semantic-tokens-mode
+ "Toggle semantic-tokens support."
+ :group 'lsp-semantic-tokens
+ :global nil
+ (cond
+ (lsp-semantic-tokens-mode
+ (add-hook 'lsp-configure-hook #'lsp-semantic-tokens--enable nil t)
+ (add-hook 'lsp-unconfigure-hook #'lsp-semantic-tokens--disable nil t)
+ (mapc #'lsp--semantic-tokens-initialize-workspace
+ (lsp--find-workspaces-for "textDocument/semanticTokens"))
+ (lsp--semantic-tokens-initialize-buffer))
+ (t
+ (remove-hook 'lsp-configure-hook #'lsp-semantic-tokens--enable t)
+ (remove-hook 'lsp-unconfigure-hook #'lsp-semantic-tokens--disable t)
+ (when lsp--semantic-tokens-teardown
+ (funcall lsp--semantic-tokens-teardown))
+ (lsp-semantic-tokens--request-update)
+ (setq lsp--semantic-tokens-cache nil
+ lsp--semantic-tokens-teardown nil))))
+
+;; debugging helpers
+(defun lsp--semantic-tokens-verify ()
+ "Store current token set and compare with the response to a full token request."
+ (interactive)
+ (let ((old-tokens (--> lsp--semantic-tokens-cache (plist-get it :response) (lsp-get it :data)))
+ (old-version (--> lsp--semantic-tokens-cache (plist-get it :_documentVersion))))
+ (if (not (equal lsp--cur-version old-version))
+ (message "Stored documentVersion %d differs from current version %d" old-version lsp--cur-version)
+ (lsp-request-async
+ "textDocument/semanticTokens/full" `(:textDocument ,(lsp--text-document-identifier))
+ (lambda (response)
+ (let ((new-tokens (lsp-get response :data)))
+ (if (equal old-tokens new-tokens)
+ (message "New tokens (total count %d) are identical to previously held token set"
+ (length new-tokens))
+ (message "Newly returned tokens differ from old token set")
+ (print old-tokens)
+ (print new-tokens))))
+ :mode 'tick
+ :cancel-token (format "semantic-tokens-%s" (lsp--buffer-uri))))))
+
+(defvar-local lsp-semantic-tokens--log '())
+
+(defvar-local lsp-semantic-tokens--prev-response nil)
+
+(defun lsp-semantic-tokens--log-buffer-contents (tag)
+ "Log buffer contents for TAG."
+ (save-restriction
+ (save-excursion
+ (widen) (push `(:tag ,tag
+ :buffer-contents ,(buffer-substring (point-min) (point-max))
+ :prev-response ,lsp-semantic-tokens--prev-response)
+ lsp-semantic-tokens--log))))
+
+(defun lsp-semantic-tokens-enable-log ()
+ "Enable logging of intermediate fontification states.
+
+This is a debugging tool, and may incur significant performance penalties."
+ (setq lsp-semantic-tokens--log '())
+ (defadvice lsp-semantic-tokens--fontify (around advice-tokens-fontify activate)
+ (lsp-semantic-tokens--log-buffer-contents 'before)
+ (let ((result ad-do-it))
+ (lsp-semantic-tokens--log-buffer-contents 'after)
+ result))
+ (defadvice lsp--semantic-tokens-ingest-full/delta-response
+ (before log-delta-response (response) activate)
+ (setq lsp-semantic-tokens--prev-response `(:request-type "delta"
+ :response ,response
+ :version ,lsp--cur-version)))
+ (defadvice lsp--semantic-tokens-ingest-full-response
+ (before log-full-response (response) activate)
+ (setq lsp-semantic-tokens--prev-response `(:request-type "full"
+ :response ,response
+ :version ,lsp--cur-version)))
+ (defadvice lsp--semantic-tokens-ingest-range-response
+ (before log-range-response (response) activate)
+ (setq lsp-semantic-tokens--prev-response `(:request-type "range"
+ :response ,response
+ :version ,lsp--cur-version))))
+
+(defun lsp-semantic-tokens-disable-log ()
+ "Disable logging of intermediate fontification states."
+ (ad-unadvise 'lsp-semantic-tokens--fontify)
+ (ad-unadvise 'lsp--semantic-tokens-ingest-full/delta-response)
+ (ad-unadvise 'lsp--semantic-tokens-ingest-full-response)
+ (ad-unadvise 'lsp--semantic-tokens-ingest-range-response))
+
+(declare-function htmlize-buffer "ext:htmlize")
+
+(defun lsp-semantic-tokens-export-log ()
+ "Write HTML-formatted snapshots of previous fontification results to /tmp."
+ (require 'htmlize)
+ (let* ((outdir (f-join "/tmp" "semantic-token-snapshots"))
+ (progress-reporter
+ (make-progress-reporter
+ (format "Writing buffer snapshots to %s..." outdir)
+ 0 (length lsp-semantic-tokens--log))))
+ (f-mkdir outdir)
+ (--each-indexed (reverse lsp-semantic-tokens--log)
+ (-let* (((&plist :tag tag
+ :buffer-contents buffer-contents
+ :prev-response prev-response) it)
+ (html-buffer))
+ ;; FIXME: doesn't update properly; sit-for helps... somewhat,
+ ;; but unreliably
+ (when (= (% it-index 5) 0)
+ (progress-reporter-update progress-reporter it-index)
+ (sit-for 0.01))
+ ;; we're emitting 2 snapshots (before & after) per update, so request
+ ;; parameters should only change on every 2nd invocation
+ (when (cl-evenp it-index)
+ (with-temp-buffer
+ (insert (prin1-to-string prev-response))
+ (write-file (f-join outdir (format "parameters_%d.el" (/ it-index 2))))))
+ (with-temp-buffer
+ (insert buffer-contents)
+ (setq html-buffer (htmlize-buffer))
+ (with-current-buffer html-buffer
+ ;; some configs such as emacs-doom may autoformat on save; switch to
+ ;; fundamental-mode to avoid this
+ (fundamental-mode)
+ (write-file (f-join outdir (format "buffer_%d_%s.html" (/ it-index 2) tag)))))
+ (kill-buffer html-buffer)))
+ (progress-reporter-done progress-reporter)))
+
+(lsp-consistency-check lsp-semantic-tokens)
+
+(provide 'lsp-semantic-tokens)
+;;; lsp-semantic-tokens.el ends here
diff --git a/elpa/lsp-mode-20220505.630/lsp-semantic-tokens.elc b/elpa/lsp-mode-20220505.630/lsp-semantic-tokens.elc
new file mode 100644
index 0000000..b18b71d
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-semantic-tokens.elc
Binary files differ
diff --git a/elpa/lsp-mode-20220505.630/lsp-solargraph.el b/elpa/lsp-mode-20220505.630/lsp-solargraph.el
new file mode 100644
index 0000000..968b32a
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-solargraph.el
@@ -0,0 +1,166 @@
+;;; lsp-solargraph.el --- Solargraph server configuration -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2019 Ivan Yonchovski
+
+;; Author: Ivan Yonchovski <yyoncho@gmail.com>
+;; Keywords:
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'lsp-mode)
+
+(defgroup lsp-solargraph nil
+ "LSP support for Ruby, using the Solargraph language server."
+ :group 'lsp-mode
+ :link '(url-link "https://github.com/castwide/solargraph")
+ :package-version '(lsp-mode . "6.1"))
+
+;; (defcustom lsp-solargraph-check-gem-version t
+;; "Automatically check if a new version of the Solargraph gem is available."
+;; :type 'boolean)
+
+(defcustom lsp-solargraph-completion t
+ "Enable completion"
+ :type 'boolean
+ :group 'lsp-solargraph
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-solargraph-hover t
+ "Enable hover"
+ :type 'boolean
+ :group 'lsp-solargraph
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-solargraph-diagnostics t
+ "Enable diagnostics"
+ :type 'boolean
+ :group 'lsp-solargraph
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-solargraph-autoformat nil
+ "Enable automatic formatting while typing (WARNING: experimental)"
+ :type 'boolean
+ :group 'lsp-solargraph
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-solargraph-formatting t
+ "Enable document formatting"
+ :type 'boolean
+ :group 'lsp-solargraph
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-solargraph-symbols t
+ "Enable symbols"
+ :type 'boolean
+ :group 'lsp-solargraph
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-solargraph-definitions t
+ "Enable definitions (go to, etc.)"
+ :type 'boolean
+ :group 'lsp-solargraph
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-solargraph-rename t
+ "Enable symbol renaming"
+ :type 'boolean
+ :group 'lsp-solargraph
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-solargraph-references t
+ "Enable finding references"
+ :type 'boolean
+ :group 'lsp-solargraph
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-solargraph-folding t
+ "Enable folding ranges"
+ :type 'boolean
+ :group 'lsp-solargraph
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-solargraph-log-level "warn"
+ "Level of debug info to log. `warn` is least and `debug` is most."
+ :type '(choice (const :tag "warn" "info" "debug"))
+ :group 'lsp-solargraph
+ :package-version '(lsp-mode . "6.1"))
+
+;; https://github.com/castwide/solargraph#solargraph-and-bundler
+(defcustom lsp-solargraph-use-bundler nil
+ "Run solargraph under bundler"
+ :type 'boolean
+ :safe #'booleanp
+ :group 'lsp-solargraph
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-solargraph-multi-root t
+ "If non nil, `solargraph' will be started in multi-root mode."
+ :type 'boolean
+ :safe #'booleanp
+ :group 'lsp-solargraph
+ :package-version '(lsp-mode . "6.3"))
+
+(defcustom lsp-solargraph-library-directories
+ '("~/.rbenv/" "/usr/lib/ruby/" "~/.rvm/" "~/.gem/")
+ "List of directories which will be considered to be libraries."
+ :type '(repeat string)
+ :group 'lsp-solargraph
+ :package-version '(lsp-mode . "7.0.1"))
+
+(defun lsp-solargraph--build-command ()
+ "Build solargraph command"
+ (let ((lsp-command '("solargraph" "stdio")))
+ (if lsp-solargraph-use-bundler
+ (append '("bundle" "exec") lsp-command)
+ lsp-command)))
+
+(lsp-register-custom-settings
+ '(("solargraph.logLevel" lsp-solargraph-log-level)
+ ("solargraph.folding" lsp-solargraph-folding t)
+ ("solargraph.references" lsp-solargraph-references t)
+ ("solargraph.rename" lsp-solargraph-rename t)
+ ("solargraph.definitions" lsp-solargraph-definitions t)
+ ("solargraph.symbols" lsp-solargraph-symbols t)
+ ("solargraph.formatting" lsp-solargraph-formatting t)
+ ("solargraph.autoformat" lsp-solargraph-autoformat t)
+ ("solargraph.diagnostics" lsp-solargraph-diagnostics t)
+ ("solargraph.hover" lsp-solargraph-hover t)
+ ("solargraph.completion" lsp-solargraph-completion t)
+ ("solargraph.useBundler" lsp-solargraph-use-bundler t)))
+
+;; Ruby
+(lsp-register-client
+ (make-lsp-client
+ :new-connection (lsp-stdio-connection
+ #'lsp-solargraph--build-command)
+ :major-modes '(ruby-mode enh-ruby-mode)
+ :priority -1
+ :multi-root lsp-solargraph-multi-root
+ :library-folders-fn (lambda (_workspace) lsp-solargraph-library-directories)
+ :server-id 'ruby-ls
+ :initialized-fn (lambda (workspace)
+ (with-lsp-workspace workspace
+ (lsp--set-configuration
+ (lsp-configuration-section "solargraph"))))))
+
+(lsp-consistency-check lsp-solargraph)
+
+(provide 'lsp-solargraph)
+;;; lsp-solargraph.el ends here
diff --git a/elpa/lsp-mode-20220505.630/lsp-solargraph.elc b/elpa/lsp-mode-20220505.630/lsp-solargraph.elc
new file mode 100644
index 0000000..94d0254
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-solargraph.elc
Binary files differ
diff --git a/elpa/lsp-mode-20220505.630/lsp-sorbet.el b/elpa/lsp-mode-20220505.630/lsp-sorbet.el
new file mode 100644
index 0000000..58040a7
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-sorbet.el
@@ -0,0 +1,59 @@
+;;; lsp-sorbet.el --- Sorbet server configuration -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2020
+
+;; Author: Christopher Wilson <chris@sencjw.com>
+;; Keywords:
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; lsp-sorbet client
+
+;;; Code:
+
+(require 'lsp-mode)
+
+(defgroup lsp-sorbet nil
+ "LSP support for Ruby, using the Sorbet language server."
+ :group 'lsp-mode
+ :link '(url-link "https://github.com/sorbet/sorbet")
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-sorbet-use-bundler nil
+ "Run sorbet under bundler"
+ :type 'boolean
+ :group 'lsp-sorbet
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defun lsp-sorbet--build-command ()
+ "Build sorbet command"
+ (let ((lsp-command '("srb" "typecheck" "--lsp" "--disable-watchman")))
+ (if lsp-sorbet-use-bundler
+ (append '("bundle" "exec") lsp-command)
+ lsp-command)))
+
+(lsp-register-client
+ (make-lsp-client
+ :new-connection (lsp-stdio-connection
+ #'lsp-sorbet--build-command)
+ :priority -2
+ :major-modes '(ruby-mode enh-ruby-mode)
+ :server-id 'sorbet-ls))
+
+(lsp-consistency-check lsp-sorbet)
+
+(provide 'lsp-sorbet)
+;;; lsp-sorbet.el ends here
diff --git a/elpa/lsp-mode-20220505.630/lsp-sorbet.elc b/elpa/lsp-mode-20220505.630/lsp-sorbet.elc
new file mode 100644
index 0000000..9f17c5e
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-sorbet.elc
Binary files differ
diff --git a/elpa/lsp-mode-20220505.630/lsp-sqls.el b/elpa/lsp-mode-20220505.630/lsp-sqls.el
new file mode 100644
index 0000000..f1c6404
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-sqls.el
@@ -0,0 +1,191 @@
+;;; lsp-sqls.el --- SQL Client settings -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2020 Shunya Ishii
+
+;; Author: Shunya Ishii
+;; Keywords: sql lsp
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; LSP client for SQL
+
+;;; Code:
+
+(require 'lsp-mode)
+
+(defgroup lsp-sqls nil
+ "LSP support for SQL, using sqls"
+ :group 'lsp-mode
+ :link '(url-link "https://github.com/lighttiger2505/sqls")
+ :package-version `(lsp-mode . "7.0"))
+
+(defcustom lsp-sqls-server "sqls"
+ "Path to the `sqls` binary."
+ :group 'lsp-sqls
+ :risky t
+ :type 'file
+ :package-version `(lsp-mode . "7.0"))
+
+(defcustom lsp-sqls-workspace-config-path "workspace"
+ "If non-nil then setup workspace configuration with json file path."
+ :group 'lsp-sqls
+ :risky t
+ :type '(choice (const "workspace")
+ (const "root"))
+ :package-version `(lsp-mode . "7.0"))
+
+(defun lsp-sqls--make-launch-cmd ()
+ (-let [base `(,lsp-sqls-server)]
+ ;; we can add some options to command. (e.g. "-config")
+ base))
+
+
+(defcustom lsp-sqls-timeout 0.5
+ "Timeout to use for `sqls' requests."
+ :type 'number
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-sqls-connections nil
+ "The connections to the SQL server(s)."
+ :type '(repeat (alist :key-type (choice
+ (const :tag "Driver" driver)
+ (const :tag "Connection String" dataSourceName))
+ :value-type string)))
+
+(defun lsp-sqls-setup-workspace-configuration ()
+ "Setup workspace configuration using json file depending on `lsp-sqls-workspace-config-path'."
+
+ (if lsp-sqls-connections
+ (lsp--set-configuration `(:sqls (:connections ,(apply #'vector lsp-sqls-connections))))
+ (when-let ((config-json-path (cond
+ ((equal lsp-sqls-workspace-config-path "workspace")
+ ".sqls/config.json")
+ ((equal lsp-sqls-workspace-config-path "root")
+ (-> (lsp-workspace-root)
+ (f-join ".sqls/config.json"))))))
+ (when (file-exists-p config-json-path)
+ (lsp--set-configuration (lsp--read-json-file config-json-path))))))
+
+(defun lsp-sqls--show-results (result)
+ (with-current-buffer (get-buffer-create "*sqls results*")
+ (with-help-window (buffer-name)
+ (erase-buffer)
+ (insert result))))
+
+(defun lsp-sql-execute-query (&optional command start end)
+ "Execute COMMAND on buffer text against current database.
+Buffer text is between START and END. If START and END are nil,
+use the current region if set, otherwise the entire buffer."
+ (interactive)
+ (lsp-sqls--show-results
+ (lsp-request
+ "workspace/executeCommand"
+ (list :command "executeQuery"
+ :arguments (or
+ (when command
+ (lsp:command-arguments? command))
+ (vector (lsp--buffer-uri)))
+ :timeout lsp-sqls-timeout
+ :range (list
+ :start (lsp--point-to-position
+ (cond
+ (start start)
+ ((use-region-p) (region-beginning))
+ (t (point-min))))
+ :end (lsp--point-to-position
+ (cond
+ (end end)
+ ((use-region-p) (region-end))
+ (t (point-max)))))))))
+
+(defun lsp-sql-execute-paragraph (&optional command)
+ "Execute COMMAND on paragraph against current database."
+ (interactive)
+ (let ((start (save-excursion (backward-paragraph) (point)))
+ (end (save-excursion (forward-paragraph) (point))))
+ (lsp-sql-execute-query command start end)))
+
+(defun lsp-sql-show-databases (&optional _command)
+ "Show databases."
+ (interactive)
+ (lsp-sqls--show-results
+ (lsp-request
+ "workspace/executeCommand"
+ (list :command "showDatabases" :timeout lsp-sqls-timeout))))
+
+(defun lsp-sql-show-schemas (&optional _command)
+ "Show schemas."
+ (interactive)
+ (lsp-sqls--show-results
+ (lsp-request
+ "workspace/executeCommand"
+ (list :command "showSchemas" :timeout lsp-sqls-timeout))))
+
+(defun lsp-sql-show-connections (&optional _command)
+ "Show connections."
+ (interactive)
+ (lsp-sqls--show-results
+ (lsp-request
+ "workspace/executeCommand"
+ (list :command "showConnections" :timeout lsp-sqls-timeout))))
+
+(defun lsp-sql-switch-database (&optional _command)
+ "Switch database."
+ (interactive)
+ (lsp-workspace-command-execute
+ "switchDatabase"
+ (vector (completing-read
+ "Select database: "
+ (s-lines (lsp-workspace-command-execute "showDatabases"))
+ nil
+ t))))
+
+(defun lsp-sql-switch-connection (&optional _command)
+ "Switch connection."
+ (interactive)
+ (lsp-workspace-command-execute
+ "switchConnections"
+ (vector (cl-first
+ (s-match "\\([[:digit:]]*\\)"
+ (completing-read
+ "Select connection: "
+ (s-lines (lsp-workspace-command-execute "showConnections"))
+ nil
+ t))))))
+
+(lsp-register-client
+ (make-lsp-client :new-connection (lsp-stdio-connection #'lsp-sqls--make-launch-cmd)
+ :major-modes '(sql-mode)
+ :priority -1
+ :action-handlers (ht ("executeParagraph" #'lsp-sql-execute-paragraph)
+ ("executeQuery" #'lsp-sql-execute-query)
+ ("showDatabases" #'lsp-sql-show-databases)
+ ("showSchemas" #'lsp-sql-show-schemas)
+ ("showConnections" #'lsp-sql-show-connections)
+ ("switchDatabase" #'lsp-sql-switch-database)
+ ("switchConnections" #'lsp-sql-switch-connection))
+ :server-id 'sqls
+ :initialized-fn (lambda (workspace)
+ (-> workspace
+ (lsp--workspace-server-capabilities)
+ (lsp:set-server-capabilities-execute-command-provider? t))
+ (with-lsp-workspace workspace
+ (lsp-sqls-setup-workspace-configuration)))))
+
+(lsp-consistency-check lsp-sqls)
+
+(provide 'lsp-sqls)
+;;; lsp-sqls.el ends here
diff --git a/elpa/lsp-mode-20220505.630/lsp-sqls.elc b/elpa/lsp-mode-20220505.630/lsp-sqls.elc
new file mode 100644
index 0000000..28ce564
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-sqls.elc
Binary files differ
diff --git a/elpa/lsp-mode-20220505.630/lsp-steep.el b/elpa/lsp-mode-20220505.630/lsp-steep.el
new file mode 100644
index 0000000..4e0e22f
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-steep.el
@@ -0,0 +1,73 @@
+;;; lsp-steep.el --- lsp-mode for Steep -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2020 Masafumi Koba
+
+;; Author: Masafumi Koba <ybiquitous@gmail.com>
+;; Keywords: languages
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; LSP client for Steep which is a Ruby type checker.
+
+;;; Code:
+
+(require 'lsp-mode)
+
+(defgroup lsp-steep nil
+ "LSP support for Steep, using the Steep language server."
+ :group 'lsp-mode
+ :link '(url-link "https://github.com/soutaro/steep"))
+
+(defcustom lsp-steep-log-level "warn"
+ "Log level of Steep."
+ :type '(choice
+ (const "fatal")
+ (const "error")
+ (const "warn")
+ (const "info")
+ (const "debug"))
+ :group 'lsp-steep)
+
+(defcustom lsp-steep-use-bundler nil
+ "Run Steep using Bunder."
+ :type 'boolean
+ :safe #'booleanp
+ :group 'lsp-steep)
+
+(defcustom lsp-steep-server-path nil
+ "Path of the Steep language server executable.
+If specified, `lsp-steep-use-bundler' is ignored."
+ :type 'file
+ :group 'lsp-steep
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defun lsp-steep--build-command ()
+ "Build a command to start the Steep language server."
+ (append
+ (if (and lsp-steep-use-bundler (not lsp-steep-server-path)) '("bundle" "exec"))
+ (list (or lsp-steep-server-path "steep") "langserver" "--log-level" lsp-steep-log-level)))
+
+(lsp-register-client
+ (make-lsp-client
+ :new-connection (lsp-stdio-connection #'lsp-steep--build-command)
+ :major-modes '(ruby-mode enh-ruby-mode)
+ :priority -3
+ :server-id 'steep-ls))
+
+(lsp-consistency-check lsp-steep)
+
+(provide 'lsp-steep)
+;;; lsp-steep.el ends here
diff --git a/elpa/lsp-mode-20220505.630/lsp-steep.elc b/elpa/lsp-mode-20220505.630/lsp-steep.elc
new file mode 100644
index 0000000..89f2b80
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-steep.elc
Binary files differ
diff --git a/elpa/lsp-mode-20220505.630/lsp-svelte.el b/elpa/lsp-mode-20220505.630/lsp-svelte.el
new file mode 100644
index 0000000..723b8fc
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-svelte.el
@@ -0,0 +1,307 @@
+;;; lsp-svelte.el --- LSP Svelte integration -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2020 Stepan Lusnikov
+
+;; Author: Stepan Lusnikov <endenwer@gmail.com>
+;; Keywords: lsp svelte
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; LSP client for Svelte
+
+;;; Code:
+
+(require 'lsp-mode)
+
+(defgroup lsp-svelte nil
+ "LSP support for Svelte."
+ :group 'lsp-mode
+ :link '(url-link
+ "https://github.com/sveltejs/language-tools"))
+
+(lsp-dependency 'svelte-language-server
+ '(:system "svelteserver")
+ '(:npm :package "svelte-language-server"
+ :path "svelteserver"))
+
+(defcustom lsp-svelte-plugin-typescript-enable t
+ "Enable the TypeScript plugin"
+ :type 'boolean
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-svelte-plugin-typescript-diagnostics-enable t
+ "Enable diagnostic messages for TypeScript"
+ :type 'boolean
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-svelte-plugin-typescript-hover-enable t
+ "Enable hover info for TypeScript"
+ :type 'boolean
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-svelte-plugin-typescript-document-symbols-enable t
+ "Enable document symbols for TypeScript"
+ :type 'boolean
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-svelte-plugin-typescript-completions-enable t
+ "Enable completions for TypeScript"
+ :type 'boolean
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-svelte-plugin-typescript-find-references-enable t
+ "Enable find-references for TypeScript"
+ :type 'boolean
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-svelte-plugin-typescript-definitions-enable t
+ "Enable go to definition for TypeScript"
+ :type 'boolean
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-svelte-plugin-typescript-code-actions-enable t
+ "Enable code actions for TypeScript"
+ :type 'boolean
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-svelte-plugin-typescript-selection-range-enable t
+ "Enable selection range for TypeScript"
+ :type 'boolean
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-svelte-plugin-typescript-signature-help-enable t
+ "Enable signature help (parameter hints) for TypeScript"
+ :type 'boolean
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-svelte-plugin-typescript-rename-enable t
+ "Enable rename functionality for JS/TS variables inside Svelte files"
+ :type 'boolean
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-svelte-plugin-css-enable t
+ "Enable the CSS plugin"
+ :type 'boolean
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-svelte-plugin-css-globals ""
+ "Which css files should be checked for global variables
+(`--global-var: value;`).
+
+These variables are added to the css completions. String of comma-separated
+file paths or globs relative to workspace root."
+ :type 'string
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-svelte-plugin-css-diagnostics-enable t
+ "Enable diagnostic messages for CSS"
+ :type 'boolean
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-svelte-plugin-css-hover-enable t
+ "Enable hover info for CSS"
+ :type 'boolean
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-svelte-plugin-css-completions-enable t
+ "Enable auto completions for CSS"
+ :type 'boolean
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-svelte-plugin-css-completions-emmet t
+ "Enable emmet auto completions for CSS"
+ :type 'boolean
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-svelte-plugin-css-document-colors-enable t
+ "Enable document colors for CSS"
+ :type 'boolean
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-svelte-plugin-css-color-presentations-enable t
+ "Enable color picker for CSS"
+ :type 'boolean
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-svelte-plugin-css-document-symbols-enable t
+ "Enable document symbols for CSS"
+ :type 'boolean
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-svelte-plugin-css-selection-range-enable t
+ "Enable selection range for CSS"
+ :type 'boolean
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-svelte-plugin-html-enable t
+ "Enable the HTML plugin"
+ :type 'boolean
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-svelte-plugin-html-hover-enable t
+ "Enable hover info for HTML"
+ :type 'boolean
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-svelte-plugin-html-completions-enable t
+ "Enable auto completions for HTML"
+ :type 'boolean
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-svelte-plugin-html-completions-emmet t
+ "Enable emmet auto completions for HTML"
+ :type 'boolean
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-svelte-plugin-html-tag-complete-enable t
+ "Enable HTML tag auto closing"
+ :type 'boolean
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-svelte-plugin-html-document-symbols-enable t
+ "Enable document symbols for HTML"
+ :type 'boolean
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-svelte-plugin-svelte-enable t
+ "Enable the Svelte plugin"
+ :type 'boolean
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-svelte-plugin-svelte-diagnostics-enable t
+ "Enable diagnostic messages for Svelte"
+ :type 'boolean
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-svelte-plugin-svelte-compiler-warnings nil
+ "Svelte compiler warning codes to ignore or to treat as errors.
+Example: '((css-unused-selector . ignore) (unused-export-let . error))"
+ :type '(alist :key-type (symbol :tag "Warning code")
+ :value-type (choice
+ (const :tag "Ignore" ignore)
+ (const :tag "Treat as error" error)))
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-svelte-plugin-svelte-format-enable t
+ "Enable formatting for Svelte (includes css & js)"
+ :type 'boolean
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-svelte-plugin-svelte-completions-enable t
+ "Enable auto completions for Svelte"
+ :type 'boolean
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-svelte-plugin-svelte-hover-enable t
+ "Enable hover information for Svelte"
+ :type 'boolean
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-svelte-plugin-svelte-code-actions-enable t
+ "Enable Code Actions for Svelte"
+ :type 'boolean
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-svelte-plugin-svelte-selection-range-enable t
+ "Enable selection range for Svelte"
+ :type 'boolean
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-svelte-plugin-svelte-rename-enable t
+ "Enable rename/move Svelte files functionality"
+ :type 'boolean
+ :package-version '(lsp-mode . "8.0.0"))
+
+(lsp-register-custom-settings
+ '(("svelte.plugin.svelte.rename.enable" lsp-svelte-plugin-svelte-rename-enable t)
+ ("svelte.plugin.svelte.selectionRange.enable" lsp-svelte-plugin-svelte-selection-range-enable t)
+ ("svelte.plugin.svelte.codeActions.enable" lsp-svelte-plugin-svelte-code-actions-enable t)
+ ("svelte.plugin.svelte.hover.enable" lsp-svelte-plugin-svelte-hover-enable t)
+ ("svelte.plugin.svelte.completions.enable" lsp-svelte-plugin-svelte-completions-enable t)
+ ("svelte.plugin.svelte.format.enable" lsp-svelte-plugin-svelte-format-enable t)
+ ("svelte.plugin.svelte.compilerWarnings" lsp-svelte-plugin-svelte-compiler-warnings)
+ ("svelte.plugin.svelte.diagnostics.enable" lsp-svelte-plugin-svelte-diagnostics-enable t)
+ ("svelte.plugin.svelte.enable" lsp-svelte-plugin-svelte-enable t)
+ ("svelte.plugin.html.documentSymbols.enable" lsp-svelte-plugin-html-document-symbols-enable t)
+ ("svelte.plugin.html.tagComplete.enable" lsp-svelte-plugin-html-tag-complete-enable t)
+ ("svelte.plugin.html.completions.emmet" lsp-svelte-plugin-html-completions-emmet t)
+ ("svelte.plugin.html.completions.enable" lsp-svelte-plugin-html-completions-enable t)
+ ("svelte.plugin.html.hover.enable" lsp-svelte-plugin-html-hover-enable t)
+ ("svelte.plugin.html.enable" lsp-svelte-plugin-html-enable t)
+ ("svelte.plugin.css.selectionRange.enable" lsp-svelte-plugin-css-selection-range-enable t)
+ ("svelte.plugin.css.documentSymbols.enable" lsp-svelte-plugin-css-document-symbols-enable t)
+ ("svelte.plugin.css.colorPresentations.enable" lsp-svelte-plugin-css-color-presentations-enable t)
+ ("svelte.plugin.css.documentColors.enable" lsp-svelte-plugin-css-document-colors-enable t)
+ ("svelte.plugin.css.completions.emmet" lsp-svelte-plugin-css-completions-emmet t)
+ ("svelte.plugin.css.completions.enable" lsp-svelte-plugin-css-completions-enable t)
+ ("svelte.plugin.css.hover.enable" lsp-svelte-plugin-css-hover-enable t)
+ ("svelte.plugin.css.diagnostics.enable" lsp-svelte-plugin-css-diagnostics-enable t)
+ ("svelte.plugin.css.globals" lsp-svelte-plugin-css-globals)
+ ("svelte.plugin.css.enable" lsp-svelte-plugin-css-enable t)
+ ("svelte.plugin.typescript.rename.enable" lsp-svelte-plugin-typescript-rename-enable t)
+ ("svelte.plugin.typescript.signatureHelp.enable" lsp-svelte-plugin-typescript-signature-help-enable t)
+ ("svelte.plugin.typescript.selectionRange.enable" lsp-svelte-plugin-typescript-selection-range-enable t)
+ ("svelte.plugin.typescript.codeActions.enable" lsp-svelte-plugin-typescript-code-actions-enable t)
+ ("svelte.plugin.typescript.definitions.enable" lsp-svelte-plugin-typescript-definitions-enable t)
+ ("svelte.plugin.typescript.findReferences.enable" lsp-svelte-plugin-typescript-find-references-enable t)
+ ("svelte.plugin.typescript.completions.enable" lsp-svelte-plugin-typescript-completions-enable t)
+ ("svelte.plugin.typescript.documentSymbols.enable" lsp-svelte-plugin-typescript-document-symbols-enable t)
+ ("svelte.plugin.typescript.hover.enable" lsp-svelte-plugin-typescript-hover-enable t)
+ ("svelte.plugin.typescript.diagnostics.enable" lsp-svelte-plugin-typescript-diagnostics-enable t)
+ ("svelte.plugin.typescript.enable" lsp-svelte-plugin-typescript-enable t)))
+
+(lsp-register-client
+ (make-lsp-client
+ :new-connection (lsp-stdio-connection
+ (lambda ()
+ `(,(lsp-package-path 'svelte-language-server)
+ "--stdio")))
+ :activation-fn (lambda (file-name _mode)
+ (string= (f-ext file-name)
+ "svelte"))
+ :initialization-options
+ (lambda ()
+ (list :config (ht-get* (lsp-configuration-section "svelte.plugin")
+ "svelte"
+ "plugin")
+ :prettierConfig (lsp-configuration-section "prettier")
+ :emmetConfig (lsp-configuration-section "emmet")
+ :typescriptConfig: (list :typescript (lsp-configuration-section "typescript")
+ :javascript (lsp-configuration-section "javascript"))
+ :dontFilterIncompleteCompletions t))
+ :server-id 'svelte-ls
+ :download-server-fn (lambda (_client callback error-callback _update?)
+ (lsp-package-ensure 'svelte-language-server callback error-callback))
+ :initialized-fn
+ (lambda (workspace)
+ (with-lsp-workspace workspace
+ (lsp--set-configuration
+ (ht-merge (lsp-configuration-section "svelte")
+ (lsp-configuration-section "javascript")
+ (lsp-configuration-section "typescript")))
+ (lsp--server-register-capability
+ (lsp-make-registration
+ :id "js/ts/id"
+ :method "workspace/didChangeWatchedFiles"
+ :register-options? (lsp-make-did-change-watched-files-registration-options
+ :watchers
+ (vector (lsp-make-file-system-watcher :glob-pattern "**/*.js")
+ (lsp-make-file-system-watcher :glob-pattern "**/*.ts")))))))))
+
+(lsp-consistency-check lsp-svelte)
+
+(provide 'lsp-svelte)
+;;; lsp-svelte.el ends here
diff --git a/elpa/lsp-mode-20220505.630/lsp-svelte.elc b/elpa/lsp-mode-20220505.630/lsp-svelte.elc
new file mode 100644
index 0000000..cdae2cd
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-svelte.elc
Binary files differ
diff --git a/elpa/lsp-mode-20220505.630/lsp-terraform.el b/elpa/lsp-mode-20220505.630/lsp-terraform.el
new file mode 100644
index 0000000..9309fd9
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-terraform.el
@@ -0,0 +1,122 @@
+;;; lsp-terraform.el --- Terraform Client settings -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2019 Ross Donaldson
+
+;; Author: Ross Donaldson
+;; Keywords: terraform lsp
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; LSP client for Terraform
+
+;;; Code:
+
+(require 'lsp-mode)
+
+
+;; terraform-lsp
+
+(defgroup lsp-terraform nil
+ "LSP support for Terraform, using terraform-lsp"
+ :group 'lsp-mode
+ :link '(url-link "https://github.com/juliosueiras/terraform-lsp")
+ :package-version `(lsp-mode . "6.2"))
+
+(defcustom lsp-terraform-server "terraform-lsp"
+ "Path to the `terraform-lsp' binary."
+ :group 'lsp-terraform
+ :risky t
+ :type '(choice
+ (file :tag "File")
+ (repeat string))
+ :package-version `(lsp-mode . "6.2"))
+
+(defcustom lsp-terraform-enable-logging nil
+ "If non-nil, enable `terraform-ls''s native logging."
+ :group 'lsp-terraform
+ :risky t
+ :type 'boolean
+ :package-version `(lsp-mode . "6.2"))
+
+
+(defun lsp-terraform--make-launch-cmd ()
+ (-let [base (if (stringp lsp-terraform-server)
+ `(,lsp-terraform-server)
+ lsp-terraform-server)]
+ (when lsp-terraform-enable-logging
+ (push "-enable-log-file" base))
+ base))
+
+(lsp-register-client
+ (make-lsp-client :new-connection (lsp-stdio-connection #'lsp-terraform--make-launch-cmd)
+ :major-modes '(terraform-mode)
+ :priority -1
+ :server-id 'tfls))
+
+
+;; terraform-ls
+
+(defgroup lsp-terraform-ls nil
+ "LSP support for Terraform, using terraform-ls from Hashicorp."
+ :group 'lsp-mode
+ :link '(url-link "https://github.com/hashicorp/terraform-ls")
+ :package-version `(lsp-mode . "8.0.1"))
+
+(defcustom lsp-terraform-ls-server "terraform-ls"
+ "Path to the `terraform-ls' binary."
+ :group 'lsp-terraform-ls
+ :risky t
+ :type '(choice
+ (file :tag "File")
+ (repeat string))
+ :package-version `(lsp-mode . "8.0.1"))
+
+(defun lsp-terraform-ls--make-launch-cmd ()
+ `(,lsp-terraform-ls-server "serve"))
+
+(lsp-register-client
+ (make-lsp-client :new-connection (lsp-stdio-connection #'lsp-terraform-ls--make-launch-cmd)
+ :major-modes '(terraform-mode)
+ :priority 1
+ :server-id 'tfmls))
+
+(defun lsp-terraform-ls-validate ()
+ "Execute terraform validate on project root."
+ (interactive)
+ (lsp-request
+ "workspace/executeCommand"
+ (list :command "terraform-ls.terraform.validate"
+ :arguments (vector (format "uri=%s" (lsp--path-to-uri (lsp-workspace-root))))
+ )
+ :no-wait t
+ :no-merge t))
+
+(defun lsp-terraform-ls-init ()
+ "Execute terraform init on project root.
+
+This is a synchronous action."
+ (interactive)
+ (lsp-request
+ "workspace/executeCommand"
+ (list :command "terraform-ls.terraform.init"
+ :arguments (vector (format "uri=%s" (lsp--path-to-uri (lsp-workspace-root)))))
+ :no-wait nil
+ :no-merge t))
+
+(lsp-consistency-check lsp-terraform)
+
+(provide 'lsp-terraform)
+;;; lsp-terraform.el ends here
diff --git a/elpa/lsp-mode-20220505.630/lsp-terraform.elc b/elpa/lsp-mode-20220505.630/lsp-terraform.elc
new file mode 100644
index 0000000..0befc30
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-terraform.elc
Binary files differ
diff --git a/elpa/lsp-mode-20220505.630/lsp-tex.el b/elpa/lsp-mode-20220505.630/lsp-tex.el
new file mode 100644
index 0000000..3cd6d08
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-tex.el
@@ -0,0 +1,68 @@
+;;; lsp-tex.el --- description -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2020 emacs-lsp maintainers
+
+;; Author: emacs-lsp maintainers
+;; Keywords: lsp, tex
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; LSP Clients for the Tex Typesetting Language.
+
+;;; Code:
+
+(require 'lsp-mode)
+
+(defgroup lsp-tex nil
+ "LSP support for TeX and friends, using Digestif and texlab."
+ :group 'lsp-mode
+ :link '(url-link "https://github.com/astoff/digestif/")
+ :link '(url-link "https://github.com/latex-lsp/texlab"))
+
+(defcustom lsp-tex-server 'texlab
+ "Choose LSP tex server."
+ :type '(choice (const :tag "texlab" texlab)
+ (const :tag "digestif" digestif))
+ :group 'lsp-tex)
+
+(defcustom lsp-clients-digestif-executable "digestif"
+ "Command to start the Digestif language server."
+ :group 'lsp-tex
+ :risky t
+ :type 'file)
+
+(lsp-register-client
+ (make-lsp-client :new-connection (lsp-stdio-connection lsp-clients-digestif-executable)
+ :major-modes '(plain-tex-mode latex-mode context-mode texinfo-mode)
+ :priority (if (eq lsp-tex-server 'digestif) 1 -1)
+ :server-id 'digestif))
+
+(defcustom lsp-clients-texlab-executable "texlab"
+ "Command to start the texlab language server."
+ :group 'lsp-tex
+ :risky t
+ :type 'file)
+
+(lsp-register-client
+ (make-lsp-client :new-connection (lsp-stdio-connection lsp-clients-texlab-executable)
+ :major-modes '(plain-tex-mode latex-mode)
+ :priority (if (eq lsp-tex-server 'texlab) 1 -1)
+ :server-id 'texlab))
+
+(lsp-consistency-check lsp-tex)
+
+(provide 'lsp-tex)
+;;; lsp-tex.el ends here
diff --git a/elpa/lsp-mode-20220505.630/lsp-tex.elc b/elpa/lsp-mode-20220505.630/lsp-tex.elc
new file mode 100644
index 0000000..50030c9
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-tex.elc
Binary files differ
diff --git a/elpa/lsp-mode-20220505.630/lsp-toml.el b/elpa/lsp-mode-20220505.630/lsp-toml.el
new file mode 100644
index 0000000..00ba4a2
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-toml.el
@@ -0,0 +1,172 @@
+;;; lsp-toml.el --- lsp-mode TOML integration -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2021 Taiki Sugawara
+
+;; Author: Taiki Sugawara <buzz.taiki@gmail.com>
+;; Keywords: lsp, toml
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Client for taplo.
+
+;;; Code:
+
+(require 'lsp-mode)
+(require 'ht)
+(require 'f)
+
+(defgroup lsp-toml nil
+ "LSP support for TOML, using Taplo."
+ :group 'lsp-mode
+ :link '(url-link "https://github.com/tamasfe/taplo"))
+
+(defcustom lsp-toml-command "taplo"
+ "Path to taplo command."
+ :type 'string
+ :group 'lsp-toml
+ :package-version '(lsp-mode . "8.0.1"))
+
+(defcustom lsp-toml-cache-path (expand-file-name
+ (locate-user-emacs-file (f-join ".cache" "lsp-toml")))
+ "Path to cache."
+ :type 'string
+ :group 'lsp-toml
+ :package-version '(lsp-mode . "8.0.1"))
+
+(defcustom-lsp lsp-toml-taplo-config-file-path nil
+ "An absolute, or workspace relative path to the Taplo configuration file."
+ :type 'string
+ :group 'lsp-toml
+ :package-version '(lsp-mode . "8.0.1")
+ :lsp-path "evenBetterToml.taplo.configFile.path")
+
+(defcustom-lsp lsp-toml-taplo-config-file-enabled t
+ "Whether to enable the usage of a Taplo configuration file."
+ :type 'boolean
+ :group 'lsp-toml
+ :package-version '(lsp-mode . "8.0.1")
+ :lsp-path "evenBetterToml.taplo.configFile.enabled")
+
+(defcustom-lsp lsp-toml-semantic-tokens nil
+ "Enable semantic tokens for inline table and array keys."
+ :type 'boolean
+ :group 'lsp-toml
+ :package-version '(lsp-mode . "8.0.1")
+ :lsp-path "evenBetterToml.semanticTokens")
+
+(defcustom-lsp lsp-toml-schema-enabled t
+ "Enable completion and validation based on JSON schemas."
+ :type 'boolean
+ :group 'lsp-toml
+ :package-version '(lsp-mode . "8.0.1")
+ :lsp-path "evenBetterToml.schema.enabled")
+
+(defcustom-lsp lsp-toml-schema-links nil
+ "Whether to show clickable links for keys in the editor."
+ :type 'boolean
+ :group 'lsp-toml
+ :package-version '(lsp-mode . "8.0.1")
+ :lsp-path "evenBetterToml.schema.links")
+
+(defcustom-lsp lsp-toml-schema-catalogs
+ ["https://taplo.tamasfe.dev/schema_index.json"
+ "https://www.schemastore.org/api/json/catalog.json"]
+ "A list of URLs to schema catalogs where schemas and associations
+can be fetched from"
+ :type 'lsp-string-vector
+ :group 'lsp-toml
+ :package-version '(lsp-mode . "8.0.1")
+ :lsp-path "evenBetterToml.schema.catalogs")
+
+(defcustom-lsp lsp-toml-schema-associations nil
+ "Additional document and schema associations.
+
+The key must be a regular expression, this pattern is used to
+associate schemas with absolute document URIs.
+
+The value must be an absolute URI to the JSON schema"
+ :type '(alist :key-type symbol :value-type string)
+ :group 'lsp-toml
+ :package-version '(lsp-mode . "8.0.1")
+ :lsp-path "evenBetterToml.schema.associations")
+
+(defcustom-lsp lsp-toml-schema-cache-memory-expiration 60
+ "The amount of seconds after which schemas will be invalidated from memory."
+ :type 'number
+ :group 'lsp-toml
+ :package-version '(lsp-mode . "8.0.1")
+ :lsp-path "evenBetterToml.schema.cache.memoryExpiration")
+
+(defcustom-lsp lsp-toml-schema-cache-disk-expiration 600
+ "The amount of seconds after which cached catalogs and schemas
+expire and will be attempted to be fetched again."
+ :type 'number
+ :group 'lsp-toml
+ :package-version '(lsp-mode . "8.0.1")
+ :lsp-path "evenBetterToml.schema.cache.diskExpiration")
+
+(defcustom-lsp lsp-toml-completion-max-keys 5
+ "The maximum amount of keys in a dotted key to display during
+completion, 0 effectively disables key completions."
+ :type 'number
+ :group 'lsp-toml
+ :package-version '(lsp-mode . "8.0.1")
+ :lsp-path "evenBetterToml.completion.maxKeys")
+
+(defcustom-lsp lsp-toml-syntax-semantic-tokens t
+ "Whether to enable semantic tokens for tables and arrays."
+ :type 'boolean
+ :group 'lsp-toml
+ :package-version '(lsp-mode . "8.0.1")
+ :lsp-path "evenBetterToml.syntax.semanticTokens")
+
+
+(defun lsp-toml--initialization-options ()
+ "Initialization options for taplo."
+ (list :configurationSection "evenBetterToml"
+ :cachePath lsp-toml-cache-path))
+
+(defun lsp-toml--handle-message-with-output (_workspace params)
+ "Handle taplo/messageWithOutput notification with PARAMS."
+ (funcall (pcase (ht-get params "kind")
+ ("error" 'lsp--error)
+ ("warn" 'lsp--warn)
+ ("info" 'lsp--info)
+ (_ 'lsp--info))
+ "lsp-toml: %s"
+ (ht-get params "message")))
+
+(defun lsp-toml--check-enabled (_file-name _mode)
+ "Check if the taplo language server should be enabled in this buffer."
+ (when (string= (lsp-buffer-language) "toml")
+ (make-directory lsp-toml-cache-path t)
+ t))
+
+(lsp-register-client
+ (make-lsp-client
+ :new-connection (lsp-stdio-connection (lambda () (list lsp-toml-command "lsp" "stdio")))
+ :activation-fn #'lsp-toml--check-enabled
+ :initialization-options #'lsp-toml--initialization-options
+ :notification-handlers (ht ("taplo/messageWithOutput" #'lsp-toml--handle-message-with-output)
+ ("taplo/didChangeSchemaAssociation" #'ignore))
+ :multi-root t
+ :server-id 'taplo
+ :priority -1))
+
+(lsp-consistency-check lsp-toml)
+
+(provide 'lsp-toml)
+;;; lsp-toml.el ends here
diff --git a/elpa/lsp-mode-20220505.630/lsp-toml.elc b/elpa/lsp-mode-20220505.630/lsp-toml.elc
new file mode 100644
index 0000000..538a356
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-toml.elc
Binary files differ
diff --git a/elpa/lsp-mode-20220505.630/lsp-ttcn3.el b/elpa/lsp-mode-20220505.630/lsp-ttcn3.el
new file mode 100644
index 0000000..f7d2b66
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-ttcn3.el
@@ -0,0 +1,51 @@
+;;; lsp-ttcn3.el --- description -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2022 emacs-lsp maintainers
+
+;; Author: emacs-lsp maintainers
+;; Keywords: lsp, ttcn3
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; LSP Clients for the TTCN3 Programming Language.
+
+;;; Code:
+
+(require 'lsp-mode)
+
+(defgroup lsp-ttcn3 nil
+ "LSP support for TTCN3, using ntt-language-server."
+ :group 'lsp-mode
+ :link '(url-link "https://github.com/nokia/ntt"))
+
+(defcustom lsp-ttcn3-lsp-server-command
+ '("ntt" "langserver")
+ "Command to start ttcn3-language-server."
+ :group 'lsp-ttcn3
+ :type '(choice
+ (string :tag "Single string value")
+ (repeat :tag "List of string values"
+ string)))
+
+(lsp-register-client
+ (make-lsp-client :new-connection (lsp-stdio-connection lsp-ttcn3-lsp-server-command)
+ :activation-fn (lsp-activate-on "ttcn3")
+ :priority -1
+ :server-id 'ntt))
+
+(provide 'lsp-ttcn3)
+;;; lsp-ttcn3.el ends here
+
diff --git a/elpa/lsp-mode-20220505.630/lsp-ttcn3.elc b/elpa/lsp-mode-20220505.630/lsp-ttcn3.elc
new file mode 100644
index 0000000..8356519
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-ttcn3.elc
Binary files differ
diff --git a/elpa/lsp-mode-20220505.630/lsp-typeprof.el b/elpa/lsp-mode-20220505.630/lsp-typeprof.el
new file mode 100644
index 0000000..7807d44
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-typeprof.el
@@ -0,0 +1,60 @@
+;;; lsp-typeprof.el --- TypeProf server configuration -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2022 Taiki Sugawara
+
+;; Author: Taiki Sugawara <buzz.taiki@gmail.com>
+;; Keywords: lsp, ruby
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Client for TypeProf.
+
+;;; Code:
+
+(require 'lsp-mode)
+
+(defgroup lsp-typeprof nil
+ "LSP support for Ruby, using the TypeProf language server."
+ :group 'lsp-mode
+ :link '(url-link "https://github.com/ruby/typeprof")
+ :package-version '(lsp-mode . "8.0.1"))
+
+(defcustom lsp-typeprof-use-bundler nil
+ "Run typeprof under bundler."
+ :type 'boolean
+ :safe #'booleanp
+ :group 'lsp-typeprof
+ :package-version '(lsp-mode . "8.0.1"))
+
+(defun lsp-typeprof--build-command ()
+ "Build typeprof command."
+ (let ((lsp-command '("typeprof" "--lsp" "--stdio")))
+ (if lsp-typeprof-use-bundler
+ (append '("bundle" "exec") lsp-command)
+ lsp-command)))
+
+(lsp-register-client
+ (make-lsp-client
+ :new-connection (lsp-stdio-connection
+ #'lsp-typeprof--build-command)
+ :priority -4
+ :major-modes '(ruby-mode enh-ruby-mode)
+ :server-id 'typeprof-ls))
+
+(lsp-consistency-check lsp-typeprof)
+
+(provide 'lsp-typeprof)
+;;; lsp-typeprof.el ends here
diff --git a/elpa/lsp-mode-20220505.630/lsp-typeprof.elc b/elpa/lsp-mode-20220505.630/lsp-typeprof.elc
new file mode 100644
index 0000000..7b3b4ec
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-typeprof.elc
Binary files differ
diff --git a/elpa/lsp-mode-20220505.630/lsp-v.el b/elpa/lsp-mode-20220505.630/lsp-v.el
new file mode 100644
index 0000000..a809a07
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-v.el
@@ -0,0 +1,50 @@
+;;; lsp-v.el --- lsp-mode V integration -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2021 remimimimi
+
+;; Author: remimimimi
+;; Keywords: languages,tools
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; client for vls, the V language server
+
+;;; Code:
+
+(require 'lsp-mode)
+
+(defgroup lsp-v nil
+ "LSP support for V via vls."
+ :group 'lsp-mode
+ :link '(url-link "https://github.com/vlang/vls/tree/master"))
+
+(defcustom lsp-v-vls-executable "vls"
+ "The vls executable to use.
+Leave as just the executable name to use the default behavior of
+finding the executable with variable `exec-path'."
+ :group 'lsp-v
+ :type 'string)
+
+(lsp-register-client
+ (make-lsp-client
+ :new-connection (lsp-stdio-connection (lambda () lsp-v-vls-executable))
+ :activation-fn (lsp-activate-on "V")
+ :server-id 'v-ls))
+
+(lsp-consistency-check lsp-v)
+
+(provide 'lsp-v)
+;;; lsp-v.el ends here
diff --git a/elpa/lsp-mode-20220505.630/lsp-v.elc b/elpa/lsp-mode-20220505.630/lsp-v.elc
new file mode 100644
index 0000000..3c4199e
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-v.elc
Binary files differ
diff --git a/elpa/lsp-mode-20220505.630/lsp-vala.el b/elpa/lsp-mode-20220505.630/lsp-vala.el
new file mode 100644
index 0000000..479743b
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-vala.el
@@ -0,0 +1,51 @@
+;;; lsp-vala.el --- Vala Client settings -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2020 Daniel Svensson
+
+;; Author: Daniel Svensson
+;; Keywords: vala lsp
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; LSP client for Vala
+
+;;; Code:
+
+(require 'lsp-mode)
+
+(defgroup lsp-vala nil
+ "LSP support for Vala, using vala-language-server"
+ :group 'lsp-mode
+ :link '(url-link "https://github.com/benwaffle/vala-language-server")
+ :package-version `(lsp-mode . "8.0.0"))
+
+(defcustom lsp-clients-vala-ls-executable "vala-language-server"
+ "Path to the `vala-language-server' binary."
+ :group 'lsp-vala
+ :risky t
+ :type 'file
+ :package-version `(lsp-mode . "8.0.0"))
+
+(lsp-register-client
+ (make-lsp-client :new-connection (lsp-stdio-connection (lambda () lsp-clients-vala-ls-executable))
+ :major-modes '(vala-mode)
+ :priority -1
+ :server-id 'valals))
+
+(lsp-consistency-check lsp-vala)
+
+(provide 'lsp-vala)
+;;; lsp-vala.el ends here
diff --git a/elpa/lsp-mode-20220505.630/lsp-vala.elc b/elpa/lsp-mode-20220505.630/lsp-vala.elc
new file mode 100644
index 0000000..cf25583
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-vala.elc
Binary files differ
diff --git a/elpa/lsp-mode-20220505.630/lsp-verilog.el b/elpa/lsp-mode-20220505.630/lsp-verilog.el
new file mode 100644
index 0000000..62e2930
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-verilog.el
@@ -0,0 +1,194 @@
+;;; lsp-verilog.el --- Verilog Client settings -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2019 Patrick Grogan
+
+;; Author: Patrick Grogan <pogrogan@gmail.com>
+;; Created: 7 December 2019
+;; Keywords: languages, lsp, verilog
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;; LSP client support for Verilog/SystemVerilog. Two language servers
+;; are available:
+;; 1) HDL Checker. See https://github.com/suoto/hdl_checker
+;; 2) SVLangserver. See https://github.com/imc-trading/svlangserver
+;;
+;; This file is based on the lsp-vhdl.el file.
+;;
+
+;;; Code:
+
+(require 'lsp-mode)
+
+(defgroup lsp-svlangserver nil
+ "Settings for the SystemVerilog language server client."
+ :group 'lsp-mode
+ :link '(url-link "https://github.com/imc-trading/svlangserver")
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-clients-svlangserver-includeIndexing '["**/*.{sv,svh}"]
+ "Files included for indexing (glob pattern)"
+ :group 'lsp-svlangserver
+ :type '(lsp-repeatable-vector string)
+ :safe (lambda (x) (seq-every-p #'stringp x)))
+
+(defcustom lsp-clients-svlangserver-excludeIndexing '["test/**/*.{sv,svh}"]
+ "Files excluded for indexing (glob pattern)"
+ :group 'lsp-svlangserver
+ :type '(lsp-repeatable-vector string)
+ :safe (lambda (x) (seq-every-p #'stringp x)))
+
+(defcustom lsp-clients-svlangserver-defines nil
+ "Defines needed for linting"
+ :group 'lsp-svlangserver
+ :type '(lsp-repeatable-vector string)
+ :safe (lambda (x) (seq-every-p #'stringp x)))
+
+(defcustom lsp-clients-svlangserver-launchConfiguration "verilator -sv --lint-only -Wall"
+ "Verilator command used for linting"
+ :group 'lsp-svlangserver
+ :type 'string
+ :safe (lambda (x) (stringp x)))
+
+(defcustom lsp-clients-svlangserver-lintOnUnsaved t
+ "Enable linting on unsaved files"
+ :group 'lsp-svlangserver
+ :type 'boolean
+ :safe (lambda (x) (booleanp x)))
+
+(defcustom lsp-clients-svlangserver-formatCommand "verible-verilog-format"
+ "Verible verilog format command"
+ :group 'lsp-svlangserver
+ :type 'string
+ :safe (lambda (x) (stringp x)))
+
+(defcustom lsp-clients-svlangserver-disableCompletionProvider nil
+ "Disable auto completion provided by the language server"
+ :group 'lsp-svlangserver
+ :type 'boolean
+ :safe (lambda (x) (booleanp x)))
+
+(defcustom lsp-clients-svlangserver-disableHoverProvider nil
+ "Disable hover over help provided by the language server"
+ :group 'lsp-svlangserver
+ :type 'boolean
+ :safe (lambda (x) (booleanp x)))
+
+(defcustom lsp-clients-svlangserver-disableSignatureHelpProvider nil
+ "Disable signature help provided by the language server"
+ :group 'lsp-svlangserver
+ :type 'boolean
+ :safe (lambda (x) (booleanp x)))
+
+(defcustom lsp-clients-svlangserver-disableLinting nil
+ "Disable verilator linting"
+ :group 'lsp-svlangserver
+ :type 'boolean
+ :safe (lambda (x) (booleanp x)))
+
+(defcustom lsp-clients-svlangserver-workspace-additional-dirs nil
+ "Additional directories to be managed by this instance of svlangserver"
+ :group 'lsp-svlangserver
+ :type '(lsp-repeatable-vector string)
+ :safe (lambda (x) (seq-every-p #'stringp x)))
+
+(defcustom lsp-clients-svlangserver-bin-path "svlangserver"
+ "svlangserver binary path"
+ :group 'lsp-svlangserver
+ :type 'string
+ :safe (lambda (x) (stringp x)))
+
+(defcustom lsp-clients-svlangserver-bin-args nil
+ "command line arguments for svlangserver binary"
+ :group 'lsp-svlangserver
+ :type '(lsp-repeatable-vector string)
+ :safe (lambda (x) (seq-every-p #'stringp x)))
+
+(defcustom lsp-clients-svlangserver-node-command "node"
+ "node binary path"
+ :group 'lsp-svlangserver
+ :type 'string
+ :safe (lambda (x) (stringp x)))
+
+(defcustom lsp-clients-svlangserver-module-path "svlangserver.js"
+ "svlangserver module path"
+ :group 'lsp-svlangserver
+ :type 'string
+ :safe (lambda (x) (stringp x)))
+
+(defun lsp-clients-svlangserver-build-index ()
+ (interactive)
+ (lsp-send-execute-command "systemverilog.build_index"))
+
+(defun lsp-clients-svlangserver-report-hierarchy (container-name)
+ (interactive (list (read-string "Module/interface: " (cond ((use-region-p) (buffer-substring (region-beginning) (region-end))) (t "")))))
+ (lsp-send-execute-command "systemverilog.report_hierarchy" (vector container-name)))
+
+(lsp-dependency 'svlangserver
+ '(:system "svlangserver"))
+
+(defun lsp-clients-svlangserver-get-workspace-additional-dirs (_workspace)
+ lsp-clients-svlangserver-workspace-additional-dirs)
+
+(defun lsp-clients-svlangserver-command ()
+ (let ((svlangserver-bin-path (lsp-package-path 'svlangserver)))
+ (if svlangserver-bin-path
+ (cons svlangserver-bin-path lsp-clients-svlangserver-bin-args)
+ (if (file-exists-p lsp-clients-svlangserver-bin-path)
+ (cons lsp-clients-svlangserver-bin-path lsp-clients-svlangserver-bin-args)
+ (if (file-exists-p lsp-clients-svlangserver-module-path)
+ `(,lsp-clients-svlangserver-node-command ,lsp-clients-svlangserver-module-path ,"--stdio")
+ `(,"svlangserver"))))))
+
+(lsp-register-client
+ (make-lsp-client :new-connection (lsp-stdio-connection 'lsp-clients-svlangserver-command)
+ :major-modes '(verilog-mode)
+ :priority -1
+ :library-folders-fn 'lsp-clients-svlangserver-get-workspace-additional-dirs
+ :server-id 'svlangserver))
+
+(lsp-register-custom-settings '(("systemverilog.includeIndexing" lsp-clients-svlangserver-includeIndexing)
+ ("systemverilog.excludeIndexing" lsp-clients-svlangserver-excludeIndexing)
+ ("systemverilog.defines" lsp-clients-svlangserver-defines)
+ ("systemverilog.launchConfiguration" lsp-clients-svlangserver-launchConfiguration)
+ ("systemverilog.lintOnUnsaved" lsp-clients-svlangserver-lintOnUnsaved)
+ ("systemverilog.formatCommand" lsp-clients-svlangserver-formatCommand)
+ ("systemverilog.disableCompletionProvider" lsp-clients-svlangserver-disableCompletionProvider)
+ ("systemverilog.disableHoverProvider" lsp-clients-svlangserver-disableHoverProvider)
+ ("systemverilog.disableSignatureHelpProvider" lsp-clients-svlangserver-disableSignatureHelpProvider)
+ ("systemverilog.disableLinting" lsp-clients-svlangserver-disableLinting)))
+
+(defgroup lsp-verilog nil
+ "LSP support for Verilog/SystemVerilog."
+ :group 'lsp-mode
+ :link '(url-link "https://github.com/suoto/hdl_checker"))
+
+(defcustom lsp-clients-verilog-executable '("hdl_checker" "--lsp")
+ "Command to start the hdl_checker language server."
+ :group 'lsp-verilog
+ :risky t
+ :type 'file)
+
+(lsp-register-client
+ (make-lsp-client :new-connection (lsp-stdio-connection lsp-clients-verilog-executable)
+ :major-modes '(verilog-mode)
+ :language-id "verilog"
+ :priority -2
+ :server-id 'lsp-verilog))
+
+(lsp-consistency-check lsp-verilog)
+
+(provide 'lsp-verilog)
+;;; lsp-verilog.el ends here
diff --git a/elpa/lsp-mode-20220505.630/lsp-verilog.elc b/elpa/lsp-mode-20220505.630/lsp-verilog.elc
new file mode 100644
index 0000000..d64d277
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-verilog.elc
Binary files differ
diff --git a/elpa/lsp-mode-20220505.630/lsp-vetur.el b/elpa/lsp-mode-20220505.630/lsp-vetur.el
new file mode 100644
index 0000000..f8d0afc
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-vetur.el
@@ -0,0 +1,353 @@
+;;; lsp-vetur.el --- vls configuration -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2019 Ivan Yonchovski
+
+;; Author: Ivan Yonchovski <yyoncho@gmail.com>
+;; Keywords:
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; VLS configuration
+
+;;; Code:
+
+(require 'lsp-mode)
+(require 'lsp-html)
+;; vls shares the same format configurations with ts-ls.
+(require 'lsp-javascript)
+
+(defgroup lsp-vetur nil
+ "LSP support for Vue, using the Vue Language Server."
+ :group 'lsp-mode
+ :link '(url-link "https://github.com/vuejs/vetur/tree/master/server")
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-vetur-ignore-project-warning nil
+ "Ignore projects without jsconfig.json or tsconfig.json warnings."
+ :type 'boolean
+ :group 'lsp-vetur
+ :package-version '(lsp-mode . "8.0.1"))
+
+(defcustom lsp-vetur-use-workspace-dependencies nil
+ "Use dependencies from workspace. Currently only for
+TypeScript."
+ :type 'boolean
+ :group 'lsp-vetur
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-vetur-completion-auto-import t
+ "Include completion for module export and auto import them"
+ :type 'boolean
+ :group 'lsp-vetur
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-vetur-completion-scaffold-snippet-sources
+ '((workspace . "(W)")
+ (user . "(U)")
+ (vetur . "(V)"))
+ "Where Vetur source Scaffold Snippets from and how to indicate them.
+- workspace: <WORKSPACE>/.vscode/vetur/snippets.
+- user: <USER-DATA-DIR>/User/snippets/vetur.
+- vetur: Bundled in Vetur.
+The source value can be a string \"(User)\" or an emoji \"✌\".
+Set a source to \"\" to disable it.
+"
+ :type 'alist
+ :group 'lsp-vetur
+ :link '(url-link "https://vuejs.github.io/vetur/guide/snippet.html")
+ :package-version '(lsp-mode. "8.0.1"))
+
+(defcustom lsp-vetur-completion-tag-casing "kebab"
+ "Casing conversion for tag completion"
+ :type '(choice
+ (const "initial")
+ (const "kebab"))
+ :group 'lsp-vetur
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-vetur-grammar-custom-blocks '((docs . "md") (i18n . "json"))
+ "Mapping from custom block tag name to language name. Used for
+ generating grammar to support syntax highlighting for custom
+ blocks."
+ :type 'alist
+ :group 'lsp-vetur
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-vetur-validation-template t
+ "Validate vue-html in <template> using eslint-plugin-vue"
+ :type 'boolean
+ :group 'lsp-vetur
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-vetur-language-features-code-actions t
+ "Enable/disable code actions."
+ :type 'boolean
+ :group 'lsp-vetur
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-vetur-validation-style t
+ "Validate css/scss/less/postcss in <style>"
+ :type 'boolean
+ :group 'lsp-vetur
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-vetur-validation-script t
+ "Validate js/ts in <script>"
+ :type 'boolean
+ :group 'lsp-vetur
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-vetur-format-enable t
+ "Enable/disable the Vetur document formatter."
+ :type 'boolean
+ :group 'lsp-vetur
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-vetur-format-options-tab-size 2
+ "Number of spaces per indentation level. Inherited by all formatters."
+ :type 'number
+ :group 'lsp-vetur
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-vetur-format-options-use-tabs nil
+ "Use tabs for indentation. Inherited by all formatters."
+ :type 'boolean
+ :group 'lsp-vetur
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-vetur-format-default-formatter-html "prettyhtml"
+ "Default formatter for <template> region"
+ :type '(choice
+ (const "none")
+ (const "prettyhtml")
+ (const "js-beautify-html")
+ (const "prettier"))
+ :group 'lsp-vetur
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-vetur-format-default-formatter-css "prettier"
+ "Default formatter for <style> region"
+ :type '(choice
+ (const "none")
+ (const "prettier"))
+ :group 'lsp-vetur
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-vetur-format-default-formatter-postcss "prettier"
+ "Default formatter for <style lang='postcss'> region"
+ :type '(choice
+ (const "none")
+ (const "prettier"))
+ :group 'lsp-vetur
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-vetur-format-default-formatter-scss "prettier"
+ "Default formatter for <style lang='scss'> region"
+ :type '(choice
+ (const "none")
+ (const "prettier"))
+ :group 'lsp-vetur
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-vetur-format-default-formatter-less "prettier"
+ "Default formatter for <style lang='less'> region"
+ :type '(choice
+ (const "none")
+ (const "prettier"))
+ :group 'lsp-vetur
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-vetur-format-default-formatter-stylus "stylus-supremacy"
+ "Default formatter for <style lang='stylus'> region"
+ :type '(choice
+ (const "none")
+ (const "stylus-supremacy"))
+ :group 'lsp-vetur
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-vetur-format-default-formatter-js "prettier"
+ "Default formatter for <script> region"
+ :type '(choice
+ (const "none")
+ (const "prettier")
+ (const "prettier-eslint")
+ (const "vscode-typescript"))
+ :group 'lsp-vetur
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-vetur-format-default-formatter-ts "prettier"
+ "Default formatter for <script> region"
+ :type '(choice
+ (const "none")
+ (const "prettier")
+ (const "vscode-typescript"))
+ :group 'lsp-vetur
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-vetur-format-default-formatter-options
+ '((js-beautify-html (wrap_attributes . "force-expand-multiline"))
+ (prettyhtml (printWidth . 100)
+ (singleQuote . :json-false)
+ (wrapAttributes . :json-false)
+ (sortAttributes . :json-false)))
+ "Options for all default formatters"
+ :type 'alist
+ :group 'lsp-vetur
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-vetur-format-style-initial-indent nil
+ "Whether to have initial indent for <style> region"
+ :type 'boolean
+ :group 'lsp-vetur
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-vetur-format-script-initial-indent nil
+ "Whether to have initial indent for <script> region"
+ :type 'boolean
+ :group 'lsp-vetur
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-vetur-trace-server "off"
+ "Traces the communication between VS Code and Vue Language Server."
+ :type '(choice
+ (const "off")
+ (const "messages")
+ (const "verbose"))
+ :group 'lsp-vetur
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-vetur-dev-vls-path ""
+ "The vls path for development"
+ :type 'string
+ :group 'lsp-vetur
+ :package-version '(lsp-mode . "6.3"))
+
+(defcustom lsp-vetur-dev-vls-port -1
+ "The vls port for development"
+ :type 'integer
+ :group 'lsp-vetur
+ :package-version '(lsp-mode . "6.3"))
+
+(defcustom lsp-vetur-dev-log-level "INFO"
+ "The vls log level for development"
+ :type '(choice
+ (const "INFO")
+ (const "DEBUG"))
+ :group 'lsp-vetur
+ :package-version '(lsp-mode . "6.3"))
+
+(defcustom lsp-vetur-experimental-template-interpolation-service nil
+ "Whether to have template interpolation service"
+ :type 'boolean
+ :group 'lsp-vetur
+ :package-version '(lsp-mode . "6.3"))
+
+(defcustom lsp-vetur-emmet "never"
+ "Controls the Emmet suggestions that show up in the suggestion/completion list."
+ :type '(choice
+ (const "never")
+ (const "inMarkupAndStylesheetFilesOnly")
+ (const "always" ))
+ :group 'lsp-vetur
+ :package-version '(lsp-mode . "6.1"))
+
+(lsp-register-custom-settings
+ '(("vetur.trace.server" lsp-vetur-trace-server)
+ ("vetur.ignoreProjectWarning" lsp-vetur-ignore-project-warning t)
+ ("vetur.format.scriptInitialIndent" lsp-vetur-format-script-initial-indent t)
+ ("vetur.format.styleInitialIndent" lsp-vetur-format-style-initial-indent t)
+ ("vetur.format.defaultFormatterOptions" lsp-vetur-format-default-formatter-options)
+ ("vetur.format.defaultFormatter.ts" lsp-vetur-format-default-formatter-ts)
+ ("vetur.format.defaultFormatter.js" lsp-vetur-format-default-formatter-js)
+ ("vetur.format.defaultFormatter.stylus" lsp-vetur-format-default-formatter-stylus)
+ ("vetur.format.defaultFormatter.less" lsp-vetur-format-default-formatter-less)
+ ("vetur.format.defaultFormatter.scss" lsp-vetur-format-default-formatter-scss)
+ ("vetur.format.defaultFormatter.postcss" lsp-vetur-format-default-formatter-postcss)
+ ("vetur.format.defaultFormatter.css" lsp-vetur-format-default-formatter-css)
+ ("vetur.format.defaultFormatter.html" lsp-vetur-format-default-formatter-html)
+ ("vetur.format.options.useTabs" lsp-vetur-format-options-use-tabs t)
+ ("vetur.format.options.tabSize" lsp-vetur-format-options-tab-size)
+ ("vetur.format.enable" lsp-vetur-format-enable t)
+ ("vetur.validation.script" lsp-vetur-validation-script t)
+ ("vetur.validation.style" lsp-vetur-validation-style t)
+ ("vetur.validation.template" lsp-vetur-validation-template t)
+ ("vetur.languageFeatures.codeActions" lsp-vetur-language-features-code-actions t)
+ ("vetur.grammar.customBlocks" lsp-vetur-grammar-custom-blocks)
+ ("vetur.completion.tagCasing" lsp-vetur-completion-tag-casing)
+ ("vetur.completion.scaffoldSnippetSources" lsp-vetur-completion-scaffold-snippet-sources)
+ ("vetur.completion.autoImport" lsp-vetur-completion-auto-import t)
+ ("vetur.useWorkspaceDependencies" lsp-vetur-use-workspace-dependencies t)
+ ("vetur.dev.vlsPath" lsp-vetur-dev-vls-path)
+ ("vetur.dev.vlsPort" lsp-vetur-dev-vls-port)
+ ("vetur.dev.logLevel" lsp-vetur-dev-log-level)
+ ("vetur.experimental.templateInterpolationService" lsp-vetur-experimental-template-interpolation-service t)
+ ("emmet.showExpandedAbbreviation" lsp-vetur-emmet)))
+
+(define-obsolete-variable-alias
+ 'lsp-vetur-server
+ 'lsp-vetur-server-command
+ "lsp-mode 6.1")
+
+(defcustom lsp-vetur-global-snippets-dir (expand-file-name (locate-user-emacs-file ".snippets/vetur"))
+ "Path to snippets dir."
+ :type 'file
+ :risky t
+ :package-version '(lsp-mode . "6.2"))
+
+(defcustom lsp-vetur-server-command '("vls")
+ "Command to start vetur."
+ :type '(repeat string)
+ :risky t
+ :package-version '(lsp-mode . "6.1"))
+
+(lsp-dependency 'vetur-language-server
+ '(:system "vls")
+ '(:npm :package "vls" :path "vls"))
+
+(lsp-register-client
+ (make-lsp-client :new-connection (lsp-stdio-connection
+ (lambda ()
+ `(,(or (executable-find (cl-first lsp-vetur-server-command))
+ (lsp-package-path 'vetur-language-server))
+ ,@(cl-rest lsp-vetur-server-command))))
+ :activation-fn (lambda (filename _mode)
+ (string= (file-name-extension filename) "vue"))
+ :priority -1
+ :multi-root t
+ :ignore-messages '("readFile .*? requested by Vue but content not available")
+ :server-id 'vls
+ :initialization-options (lambda () (ht-merge (lsp-configuration-section "vetur")
+ (lsp-configuration-section "html")
+ (lsp-configuration-section "javascript")
+ (lsp-configuration-section "typescript")
+ (lsp-configuration-section "emmet")
+ (ht ("globalSnippetDir" lsp-vetur-global-snippets-dir))))
+ :initialized-fn (lambda (workspace)
+ (with-lsp-workspace workspace
+ (lsp--set-configuration
+ (ht-merge (lsp-configuration-section "vetur")
+ (lsp-configuration-section "html")
+ (lsp-configuration-section "javascript")
+ (lsp-configuration-section "emmet")
+ (lsp-configuration-section "typescript")))))
+ :download-server-fn (lambda (_client callback error-callback _update?)
+ (lsp-package-ensure 'vetur-language-server
+ callback error-callback))))
+
+(lsp-consistency-check lsp-vetur)
+
+(provide 'lsp-vetur)
+;;; lsp-vetur.el ends here
diff --git a/elpa/lsp-mode-20220505.630/lsp-vetur.elc b/elpa/lsp-mode-20220505.630/lsp-vetur.elc
new file mode 100644
index 0000000..d328097
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-vetur.elc
Binary files differ
diff --git a/elpa/lsp-mode-20220505.630/lsp-vhdl.el b/elpa/lsp-mode-20220505.630/lsp-vhdl.el
new file mode 100644
index 0000000..aa55e0e
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-vhdl.el
@@ -0,0 +1,121 @@
+;;; lsp-vhdl.el --- VHDL Client settings -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2019 Christian Birk Sørensen
+
+;; Author: Christian Birk Sørensen <chrbirks+emacs@gmail.com>
+;; Created: 6 October 2019
+;; Keywords: languages, lsp, vhdl
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; LSP support for VHDL using using an external language server. Currently
+;; the supported servers are:
+;;
+;; VHDL-tool. See http://www.vhdltool.com/configuration for setting up the
+;; project file.
+;;
+;; HDL Checker. See https://github.com/suoto/hdl_checker/wiki/setting-up-a-project
+;; for setting up the project file.
+;;
+;; VHDL LS. See https://github.com/kraigher/rust_hdl#configuration for setting
+;; up the project file.
+;;
+;; GHDL LS. See https://github.com/ghdl/ghdl-language-server for setting up the
+;; project file.
+;;
+;; Set the symbol lsp-vhdl-server to select the language server and set
+;; lsp-vhdl-server-path if the binary is not in the user PATH.
+
+;;; Code:
+
+(require 'lsp-mode)
+
+(defvar vhdl-tool-bin-name "vhdl-tool"
+ "Name of the VHDL Tool binary.")
+
+(defvar hdl-checker-bin-name "hdl_checker"
+ "Name of HDL Checker binary.")
+
+(defvar vhdl-ls-bin-name "vhdl_ls"
+ "Name of the VHDL LS binary.")
+
+(defvar ghdl-ls-bin-name "ghdl-ls"
+ "Name of the GHDL LS binary.")
+
+(defgroup lsp-vhdl nil
+ "LSP support for VHDL. Set lsp-vhdl-server to select server. The default is to use VHDL-tool."
+ :group 'lsp-mode)
+
+(defcustom lsp-vhdl-server 'vhdl-tool
+ "Select which server to use:
+VHDL-tool: A syntax checking, type checking and linting tool (http://vhdltool.com).
+HDL Checker: A wrapper for third party tools such as GHDL, ModelSim, Vivado Simulator (https://github.com/suoto/hdl_checker).
+VHDL LS: A complete VHDL language server protocol implementation with diagnostics, navigate to symbol, find all references etc. (https://github.com/kraigher/rust_hdl)."
+ :type '(choice (const :tag "VHDL-tool" vhdl-tool)
+ (const :tag "HDL Checker" hdl-checker)
+ (const :tag "VHDL LS" vhdl-ls)
+ (const :tag "GHDL LS" ghdl-ls))
+ :group 'lsp-vhdl)
+
+(defcustom lsp-vhdl-server-path nil
+ "Path to binary server file."
+ :group 'lsp-vhdl
+ :risky t
+ :type 'file)
+
+(defvar lsp-vhdl--params nil)
+
+(defun lsp-vhdl--create-connection ()
+ "Returns lsp-stdio-connection based on the selected server"
+ (lsp-vhdl--set-server-path)
+ (lsp-vhdl--set-server-args)
+ (lsp-stdio-connection
+ (lambda () (cons (plist-get lsp-vhdl--params 'server-path) (plist-get lsp-vhdl--params 'server-args)))
+ (lambda () (executable-find (plist-get lsp-vhdl--params 'server-path)))))
+
+(defun lsp-vhdl--set-server-path()
+ "Set path to server binary based on selection in lsp-vhdl-server."
+ (cond ((eq lsp-vhdl-server 'hdl-checker) (if (eq lsp-vhdl-server-path nil)
+ (setq lsp-vhdl--params (plist-put lsp-vhdl--params 'server-path hdl-checker-bin-name))
+ (setq lsp-vhdl--params (plist-put lsp-vhdl--params 'server-path lsp-vhdl-server-path))))
+ ((eq lsp-vhdl-server 'vhdl-tool) (if (eq lsp-vhdl-server-path nil)
+ (setq lsp-vhdl--params (plist-put lsp-vhdl--params 'server-path vhdl-tool-bin-name))
+ (setq lsp-vhdl--params (plist-put lsp-vhdl--params 'server-path lsp-vhdl-server-path))))
+ ((eq lsp-vhdl-server 'vhdl-ls) (if (eq lsp-vhdl-server-path nil)
+ (setq lsp-vhdl--params (plist-put lsp-vhdl--params 'server-path vhdl-ls-bin-name))
+ (setq lsp-vhdl--params (plist-put lsp-vhdl--params 'server-path lsp-vhdl-server-path))))
+ ((eq lsp-vhdl-server 'ghdl-ls) (if (eq lsp-vhdl-server-path nil)
+ (setq lsp-vhdl--params (plist-put lsp-vhdl--params 'server-path ghdl-ls-bin-name))
+ (setq lsp-vhdl--params (plist-put lsp-vhdl--params 'server-path lsp-vhdl-server-path))))))
+
+(defun lsp-vhdl--set-server-args()
+ "Set server arguments based on server selection."
+ (cond ((eq lsp-vhdl-server 'hdl-checker) (setq lsp-vhdl--params (plist-put lsp-vhdl--params 'server-args '("--lsp"))))
+ ((eq lsp-vhdl-server 'vhdl-tool) (setq lsp-vhdl--params (plist-put lsp-vhdl--params 'server-args '("lsp"))))
+ ((eq lsp-vhdl-server 'vhdl-ls) (setq lsp-vhdl--params (plist-put lsp-vhdl--params 'server-args '())))
+ ((eq lsp-vhdl-server 'ghdl-ls) (setq lsp-vhdl--params (plist-put lsp-vhdl--params 'server-args '())))))
+
+(lsp-register-client
+ (make-lsp-client :new-connection (lsp-vhdl--create-connection)
+ :major-modes '(vhdl-mode)
+ :language-id "VHDL"
+ :priority -1
+ :server-id 'lsp-vhdl))
+
+(lsp-consistency-check lsp-vhdl)
+
+(provide 'lsp-vhdl)
+;;; lsp-vhdl.el ends here
diff --git a/elpa/lsp-mode-20220505.630/lsp-vhdl.elc b/elpa/lsp-mode-20220505.630/lsp-vhdl.elc
new file mode 100644
index 0000000..eec53ce
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-vhdl.elc
Binary files differ
diff --git a/elpa/lsp-mode-20220505.630/lsp-vimscript.el b/elpa/lsp-mode-20220505.630/lsp-vimscript.el
new file mode 100644
index 0000000..9f1fec2
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-vimscript.el
@@ -0,0 +1,75 @@
+;;; lsp-vimscript.el --- description -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2020 emacs-lsp maintainers
+
+;; Author: emacs-lsp maintainers
+;; Keywords: lsp, vim, vimscript
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; LSP Clients for the VimScript Programming Language.
+
+;;; Code:
+
+(require 'lsp-mode)
+
+(defgroup lsp-vim nil
+ "LSP support for viml using vim-language-server."
+ :group 'lsp-mode
+ :link '(url-link "https://github.com/iamcco/vim-language-server"))
+
+(defcustom lsp-clients-vim-executable '("vim-language-server" "--stdio")
+ "Command to start the vim language server."
+ :group 'lsp-vim
+ :risky t
+ :type 'file)
+
+(defcustom lsp-clients-vim-initialization-options '((iskeyword . "vim iskeyword option")
+ (vimruntime . "/usr/bin/vim")
+ (runtimepath . "/usr/bin/vim")
+ (diagnostic . ((enable . t)))
+ (indexes . ((runtimepath . t)
+ (gap . 100)
+ (count . 3)))
+ (suggest . ((fromVimruntime . t)
+ (fromRuntimepath . :json-false))))
+ "Initialization options for vim language server."
+ :group 'lsp-vim
+ :type 'alist)
+
+(lsp-dependency 'vim-language-server
+ '(:system "vim-language-server")
+ '(:npm :package "vim-language-server"
+ :path "vim-language-server"))
+
+(lsp-register-client
+ (make-lsp-client :new-connection (lsp-stdio-connection
+ (lambda ()
+ `(,(or (executable-find (cl-first lsp-clients-vim-executable))
+ (lsp-package-path 'vim-language-server))
+ ,@(cl-rest lsp-clients-vim-executable))))
+ :major-modes '(vimrc-mode)
+ :priority -1
+ :server-id 'vimls
+ :initialization-options (lambda () lsp-clients-vim-initialization-options)
+ :download-server-fn (lambda (_client callback error-callback _update?)
+ (lsp-package-ensure 'vim-language-server
+ callback error-callback))))
+
+(lsp-consistency-check lsp-vimscript)
+
+(provide 'lsp-vimscript)
+;;; lsp-vimscript.el ends here
diff --git a/elpa/lsp-mode-20220505.630/lsp-vimscript.elc b/elpa/lsp-mode-20220505.630/lsp-vimscript.elc
new file mode 100644
index 0000000..a2569d7
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-vimscript.elc
Binary files differ
diff --git a/elpa/lsp-mode-20220505.630/lsp-volar.el b/elpa/lsp-mode-20220505.630/lsp-volar.el
new file mode 100644
index 0000000..9a1ae71
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-volar.el
@@ -0,0 +1,225 @@
+;;; lsp-volar.el --- A lsp-mode client for Vue3 -*- lexical-binding: t; -*-
+;;
+;; Copyright (C) 2021 JadeStrong
+;;
+;; Author: JadeStrong <https://github.com/jadestrong>
+;; Maintainer: JadeStrong <jadestrong@163.com>
+;; Created: November 08, 2021
+;; Modified: November 08, 2021
+;; Version: 0.0.1
+;; Keywords: abbrev bib c calendar comm convenience data docs emulations extensions faces files frames games hardware help hypermedia i18n internal languages lisp local maint mail matching mouse multimedia news outlines processes terminals tex tools unix vc wp
+;; Homepage: https://github.com/jadestrong/lsp-volar
+;; Package-Requires: ((emacs "25.1"))
+;;
+;; This file is not part of GNU 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 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.
+
+;; For a full copy of the GNU General Public License
+;; see <http://www.gnu.org/licenses/>.
+
+;;
+;;; Commentary:
+;;
+;; provide the connection to lsp-mode and volar language server
+;;
+;;; Code:
+(require 'lsp-mode)
+(require 'json)
+
+(defgroup lsp-volar nil
+ "Lsp support for vue3."
+ :group 'lsp-volar
+ :link '(url-link "https://github.com/johnsoncodehk/volar")
+ :package-version '(lsp-mode . "8.0.1"))
+
+(defcustom lsp-volar-take-over-mode t
+ "Enable Take Over Mode."
+ :type 'boolean
+ :group 'lsp-volar
+ :package-version '(lsp-mode . "8.0.1"))
+
+(defcustom lsp-volar-activate-file ".volarrc"
+ "A file with a custom name placed in WORKSPACE-ROOT is used to force enable
+ volar when there is no package.json in the WORKSPACE-ROOT."
+ :type 'string
+ :group 'lsp-volar
+ :package-version '(lsp-mode . "8.0.1"))
+
+(defconst lsp-volar--is-windows (memq system-type '(cygwin windows-nt ms-dos)))
+(defun lsp-volar-get-typescript-server-path ()
+ "Get tsserver.js file path."
+ (if-let ((package-path (lsp-package-path 'typescript))
+ (system-server-path (apply #'f-join (if lsp-volar--is-windows
+ (append (cl-subseq (f-split (file-truename (lsp-package-path 'typescript))) 0 -1) '("node_modules" "typescript" "lib" "tsserver.js"))
+ (append (cl-subseq (f-split (file-truename (lsp-package-path 'typescript))) 0 -2) '("lib" "tsserver.js")))))
+ (is-exist (f-file-p system-server-path)))
+ system-server-path
+ (progn (lsp--error "[lsp-volar] Typescript is not detected correctly. Please ensure the npm package typescript is installed in your project or system (npm install -g typescript), otherwise open an issue") "")))
+
+(lsp-dependency 'typescript
+ '(:system "tsserver")
+ '(:npm :package "typescript"
+ :path "tsserver"))
+
+(lsp-dependency 'volar-language-server
+ '(:system "vue-language-server")
+ '(:npm :package "@volar/vue-language-server" :path "vue-language-server"))
+
+(lsp-register-custom-settings
+ '(("typescript.serverPath" (lambda () (if-let ((project-root (lsp-workspace-root))
+ (server-path (f-join project-root "node_modules/typescript/lib/tsserverlibrary.js"))
+ (is-exist (file-exists-p server-path)))
+ server-path
+ (lsp-volar-get-typescript-server-path))) t)
+ ("languageFeatures.references" t t)
+ ("languageFeatures.implementation" t t)
+ ("languageFeatures.definition" t t)
+ ("languageFeatures.typeDefinition" t t)
+ ("languageFeatures.callHierarchy" t t)
+ ("languageFeatures.hover" t t)
+ ("languageFeatures.rename" t t)
+ ("languageFeatures.renameFileRefactoring" t t)
+ ("languageFeatures.signatureHelp" t t)
+ ("languageFeatures.codeAction" t t)
+ ("languageFeatures.workspaceSymbol" t t)
+ ("languageFeatures.completion.defaultTagNameCase" "both" t)
+ ("languageFeatures.completion.defaultAttrNameCase" "kebabCase" t t)
+ ("languageFeatures.completion.getDocumentNameCasesRequest" nil t)
+ ("languageFeatures.completion.getDocumentSelectionRequest" nil t)
+ ("languageFeatures.schemaRequestService.getDocumentContentRequest" nil t)
+
+ ("documentFeatures.selectionRange" t t)
+ ("documentFeatures.foldingRange" t t)
+ ("documentFeatures.linkedEditingRange" t t)
+ ("documentFeatures.documentSymbol" t t)
+ ("documentFeatures.documentColor" t t)
+ ("documentFeatures.documentFormatting.defaultPrintWidth" 100 t)
+ ("documentFeatures.documentFormatting.getDocumentPrintWidthRequest" nil t)))
+
+(defun lsp-volar--vue-project-p (workspace-root)
+ "Check if the 'vue' package is present in the package.json file
+in the WORKSPACE-ROOT."
+ (if-let ((package-json (f-join workspace-root "package.json"))
+ (exist (f-file-p package-json))
+ (config (json-read-file package-json))
+ (dependencies (alist-get 'dependencies config)))
+ (alist-get 'vue dependencies)
+ nil))
+
+(defun lsp-volar--activate-p (filename &optional _)
+ "Check if the volar-language-server should be enabled base on FILENAME."
+ (if lsp-volar-take-over-mode
+ (and (or
+ (and (lsp-workspace-root) (lsp-volar--vue-project-p (lsp-workspace-root)))
+ (and (lsp-workspace-root) lsp-volar-activate-file (f-file-p (f-join (lsp-workspace-root) lsp-volar-activate-file))))
+ (or (or (string-match-p "\\.mjs\\|\\.[jt]sx?\\'" filename)
+ (and (derived-mode-p 'js-mode 'typescript-mode)
+ (not (derived-mode-p 'json-mode))))
+ (string= (file-name-extension filename) "vue")))
+ (string= (file-name-extension filename) "vue")))
+
+(lsp-register-client
+ (make-lsp-client
+ :new-connection (lsp-stdio-connection
+ (lambda ()
+ `(,(lsp-package-path 'volar-language-server) "--stdio")))
+ :activation-fn 'lsp-volar--activate-p
+ :priority 0
+ :multi-root nil
+ :server-id 'volar-api
+ :initialization-options (lambda () (ht-merge (lsp-configuration-section "typescript")
+ (lsp-configuration-section "languageFeatures")))
+ :initialized-fn (lambda (workspace)
+ (with-lsp-workspace workspace
+ (lsp--server-register-capability
+ (lsp-make-registration
+ :id "random-id"
+ :method "workspace/didChangeWatchedFiles"
+ :register-options? (lsp-make-did-change-watched-files-registration-options
+ :watchers
+ `[,(lsp-make-file-system-watcher :glob-pattern "**/*.js")
+ ,(lsp-make-file-system-watcher :glob-pattern "**/*.ts")
+ ,(lsp-make-file-system-watcher :glob-pattern "**/*.vue")
+ ,(lsp-make-file-system-watcher :glob-pattern "**/*.jsx")
+ ,(lsp-make-file-system-watcher :glob-pattern "**/*.tsx")
+ ,(lsp-make-file-system-watcher :glob-pattern "**/*.json")])))))
+ :download-server-fn (lambda (_client callback error-callback _update?)
+ (lsp-package-ensure 'volar-language-server
+ callback error-callback))))
+
+(lsp-register-client
+ (make-lsp-client
+ :new-connection (lsp-stdio-connection
+ (lambda ()
+ `(,(lsp-package-path 'volar-language-server) "--stdio")))
+ :activation-fn 'lsp-volar--activate-p
+ :priority 0
+ :multi-root nil
+ :add-on? t
+ :server-id 'volar-doc
+ :initialization-options (lambda () (ht-merge (lsp-configuration-section "typescript")
+ (ht ("languageFeatures" (ht-merge (ht ("documentHighlight" t))
+ (ht ("documentLink" t))
+ (ht ("codeLens" (ht ("showReferencesNotification" t))))
+ (ht ("semanticTokens" t))
+ (ht ("diagnostics" (ht ("getDocumentVersionRequest" nil))))
+ (ht ("schemaRequestService" (ht ("getDocumentContentRequest" nil)))))))))
+ :initialized-fn (lambda (workspace)
+ (with-lsp-workspace workspace
+ (lsp--server-register-capability
+ (lsp-make-registration
+ :id "random-id"
+ :method "workspace/didChangeWatchedFiles"
+ :register-options? (lsp-make-did-change-watched-files-registration-options
+ :watchers
+ `[,(lsp-make-file-system-watcher :glob-pattern "**/*.js")
+ ,(lsp-make-file-system-watcher :glob-pattern "**/*.ts")
+ ,(lsp-make-file-system-watcher :glob-pattern "**/*.vue")
+ ,(lsp-make-file-system-watcher :glob-pattern "**/*.jsx")
+ ,(lsp-make-file-system-watcher :glob-pattern "**/*.tsx")
+ ,(lsp-make-file-system-watcher :glob-pattern "**/*.json")])))))
+ :download-server-fn (lambda (_client callback error-callback _update?)
+ (lsp-package-ensure 'volar-language-server
+ callback error-callback))))
+
+(lsp-register-client
+ (make-lsp-client
+ :new-connection (lsp-stdio-connection
+ (lambda ()
+ `(,(lsp-package-path 'volar-language-server) "--stdio")))
+ :activation-fn 'lsp-volar--activate-p
+ :priority 0
+ :multi-root nil
+ :add-on? t
+ :server-id 'volar-html
+ :initialization-options (lambda () (ht-merge (lsp-configuration-section "typescript")
+ (lsp-configuration-section "documentFeatures")))
+ :initialized-fn (lambda (workspace)
+ (with-lsp-workspace workspace
+ (lsp--server-register-capability
+ (lsp-make-registration
+ :id "random-id"
+ :method "workspace/didChangeWatchedFiles"
+ :register-options? (lsp-make-did-change-watched-files-registration-options
+ :watchers
+ `[,(lsp-make-file-system-watcher :glob-pattern "**/*.js")
+ ,(lsp-make-file-system-watcher :glob-pattern "**/*.ts")
+ ,(lsp-make-file-system-watcher :glob-pattern "**/*.vue")
+ ,(lsp-make-file-system-watcher :glob-pattern "**/*.jsx")
+ ,(lsp-make-file-system-watcher :glob-pattern "**/*.tsx")
+ ,(lsp-make-file-system-watcher :glob-pattern "**/*.json")])))))
+ :download-server-fn (lambda (_client callback error-callback _update?)
+ (lsp-package-ensure 'volar-language-server
+ callback error-callback))))
+
+(provide 'lsp-volar)
+;;; lsp-volar.el ends here
diff --git a/elpa/lsp-mode-20220505.630/lsp-volar.elc b/elpa/lsp-mode-20220505.630/lsp-volar.elc
new file mode 100644
index 0000000..c4a9ab4
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-volar.elc
Binary files differ
diff --git a/elpa/lsp-mode-20220505.630/lsp-xml.el b/elpa/lsp-mode-20220505.630/lsp-xml.el
new file mode 100644
index 0000000..209fa09
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-xml.el
@@ -0,0 +1,245 @@
+;;; lsp-xml.el --- LSP XML server integration -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2019 Ivan Yonchovski
+
+;; Author: Ivan Yonchovski <yyoncho@gmail.com>
+;; Keywords:
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'lsp-mode)
+
+(defgroup lsp-xml nil
+ "Settings for rls."
+ :group 'tools
+ :tag "Language Server"
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-xml-trace-server "off"
+ "Traces the communication between VS Code and the XML language server."
+ :type '(choice
+ (const "off")
+ (const "messages")
+ (const "verbose"))
+ :group 'lsp-xml
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-xml-catalogs nil
+ "Array of XML Catalogs"
+ :type '(repeat string)
+ :group 'lsp-xml
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-xml-logs-client t
+ "Should the server log to client output"
+ :type 'boolean
+ :group 'lsp-xml
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-xml-format-split-attributes nil
+ "Split multiple attributes each onto a new line"
+ :type 'boolean
+ :group 'lsp-xml
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-xml-format-join-cdata-lines nil
+ "Join lines in a CDATA tag's content"
+ :type 'boolean
+ :group 'lsp-xml
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-xml-format-join-comment-lines nil
+ "Join comment content on format"
+ :type 'boolean
+ :group 'lsp-xml
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-xml-format-space-before-empty-close-tag t
+ "Insert space before end of self closing tag.
+Example: <tag/> -> <tag />"
+ :type 'boolean
+ :group 'lsp-xml
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-xml-format-join-content-lines nil
+ "Normalize the whitespace of content inside an element.
+Newlines and excess whitespace are removed."
+ :type 'boolean
+ :group 'lsp-xml
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-xml-format-preserve-empty-content nil
+ "Preserve empty content/whitespace in a tag."
+ :type 'boolean
+ :group 'lsp-xml
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-xml-format-enabled t
+ "Enable/disable ability to format document"
+ :type 'boolean
+ :group 'lsp-xml
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-xml-format-quotations "doubleQuotes"
+ "Which type of quotes to use for attribute values when
+ formatting."
+ :type '(choice
+ (const "doubleQuotes")
+ (const "singleQuotes"))
+ :group 'lsp-xml
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-xml-file-associations nil
+ "Allows XML schemas to be associated to file name patterns.
+ Example: [{ \"systemId\":\"path/to/file.xsd\",\"pattern\":
+ \"file1.xml\" },{ \"systemId\":
+ \"http://www.w3.org/2001/XMLSchema.xsd\",\"pattern\":
+ \"**/*.xsd\" }]"
+ :type '(repeat string)
+ :group 'lsp-xml
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-xml-completion-auto-close-tags t
+ "Enable/disable autoclosing of XML tags. IMPORTANT: Turn off
+ editor.autoClosingTags for this to work"
+ :type 'boolean
+ :group 'lsp-xml
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-xml-server-vmargs ["-noverify" "-Xmx64M" "-XX:+UseG1GC"
+ "-XX:+UseStringDeduplication"]
+ "Specifies extra VM arguments used to launch the XML Language
+ Server. Eg. use `-noverify -Xmx1G -XX:+UseG1GC
+ -XX:+UseStringDeduplication` to bypass class verification,
+ increase the heap size to 1GB and enable String deduplication
+ with the G1 Garbage collector"
+ :type 'lsp-string-vector
+ :group 'lsp-xml
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-xml-server-work-dir (expand-file-name ".lsp4xml" "~")
+ "Set a custom folder path for cached XML Schemas. An absolute
+ path is expected, although the ~ prefix (for the user home
+ directory) is supported."
+ :type 'string
+ :group 'lsp-xml
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-xml-validation-no-grammar "hint"
+ "The message severity when a document has no associated
+ grammar."
+ :type '(choice (:tag "ignore" "hint" "info" "warning" "error"))
+ :group 'lsp-xml
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-xml-validation-enabled t
+ "Enable/disable all validation."
+ :type 'boolean
+ :group 'lsp-xml
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-xml-validation-resolve-external-entities nil
+ "Enable/disable resolution (downloading) of external entities from the internet."
+ :type 'boolean
+ :group 'lsp-xml
+ :package-version '(lsp-mode . "8.0.0"))
+
+(defcustom lsp-xml-validation-schema t
+ "Enable/disable schema based validation. Ignored if
+ \"xml.validation.enabled\": false."
+ :type 'boolean
+ :group 'lsp-xml
+ :package-version '(lsp-mode . "6.1"))
+
+(lsp-register-custom-settings '
+ (("xml.validation.schema" lsp-xml-validation-schema t)
+ ("xml.validation.resolveExternalEntities" lsp-xml-validation-resolve-external-entities)
+ ("xml.validation.enabled" lsp-xml-validation-enabled t)
+ ("xml.validation.noGrammar" lsp-xml-validation-no-grammar)
+ ("xml.server.workDir" lsp-xml-server-work-dir)
+ ("xml.server.vmargs" lsp-xml-server-vmargs)
+ ("xml.completion.autoCloseTags" lsp-xml-completion-auto-close-tags t)
+ ("xml.fileAssociations" lsp-xml-file-associations)
+ ("xml.format.quotations" lsp-xml-format-quotations)
+ ("xml.format.enabled" lsp-xml-format-enabled t)
+ ("xml.format.preserveEmptyContent" lsp-xml-format-preserve-empty-content t)
+ ("xml.format.joinContentLines" lsp-xml-format-join-content-lines t)
+ ("xml.format.spaceBeforeEmptyCloseTag" lsp-xml-format-space-before-empty-close-tag t)
+ ("xml.format.joinCommentLines" lsp-xml-format-join-comment-lines t)
+ ("xml.format.joinCDATALines" lsp-xml-format-join-cdata-lines t)
+ ("xml.format.splitAttributes" lsp-xml-format-split-attributes t)
+ ("xml.logs.client" lsp-xml-logs-client t)
+ ("xml.catalogs" lsp-xml-catalogs)
+ ("xml.trace.server" lsp-xml-trace-server)))
+
+(defconst lsp-xml-jar-version "0.18.0")
+
+(defconst lsp-xml-jar-name (format "org.eclipse.lemminx-%s-uber.jar" lsp-xml-jar-version))
+
+(defcustom lsp-xml-jar-file (f-join lsp-server-install-dir "xmlls" lsp-xml-jar-name)
+ "Xml server jar command."
+ :type 'string
+ :group 'lsp-xml
+ :type 'file
+ :package-version '(lsp-mode . "6.1"))
+
+(defcustom lsp-xml-jar-download-url
+ (format
+ "https://repo.eclipse.org/content/repositories/lemminx-releases/org/eclipse/lemminx/org.eclipse.lemminx/%s/%s"
+ lsp-xml-jar-version
+ lsp-xml-jar-name)
+ "Automatic download url for lsp-xml."
+ :type 'string
+ :group 'lsp-xml
+ :package-version '(lsp-mode . "8.0.0"))
+
+(lsp-dependency
+ 'xmlls
+ '(:system lsp-xml-jar-file)
+ `(:download :url lsp-xml-jar-download-url
+ :store-path lsp-xml-jar-file))
+
+(defcustom lsp-xml-server-command `("java" "-jar" ,lsp-xml-jar-file)
+ "Xml server command."
+ :type '(repeat string)
+ :group 'lsp-xml
+ :package-version '(lsp-mode . "6.1"))
+
+(defun lsp-xml--create-connection ()
+ (lsp-stdio-connection
+ (lambda () lsp-xml-server-command)
+ (lambda () (f-exists? lsp-xml-jar-file))))
+
+(lsp-register-client
+ (make-lsp-client :new-connection (lsp-xml--create-connection)
+ :activation-fn (lsp-activate-on "xml")
+ :priority 0
+ :server-id 'xmlls
+ :multi-root t
+ :initialized-fn (lambda (workspace)
+ (with-lsp-workspace workspace
+ (lsp--set-configuration (lsp-configuration-section "xml"))))
+ :download-server-fn (lambda (_client callback error-callback _update?)
+ (lsp-package-ensure 'xmlls callback error-callback))))
+
+(lsp-consistency-check lsp-xml)
+
+(provide 'lsp-xml)
+;;; lsp-xml.el ends here
diff --git a/elpa/lsp-mode-20220505.630/lsp-xml.elc b/elpa/lsp-mode-20220505.630/lsp-xml.elc
new file mode 100644
index 0000000..af2954b
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-xml.elc
Binary files differ
diff --git a/elpa/lsp-mode-20220505.630/lsp-yaml.el b/elpa/lsp-mode-20220505.630/lsp-yaml.el
new file mode 100644
index 0000000..76ef4ba
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-yaml.el
@@ -0,0 +1,242 @@
+;;; lsp-yaml.el --- LSP YAML server integration -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2019 Aya Igarashi
+
+;; Author: Aya Igarashi <ladiclexxx@gmail.com>
+;; Keywords:
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'lsp-mode)
+(require 'dash)
+
+(defgroup lsp-yaml nil
+ "LSP support for YAML, using yaml-language-server."
+ :group 'lsp-mode
+ :link '(url-link "https://github.com/redhat-developer/yaml-language-server")
+ :package-version '(lsp-mode . "6.2"))
+
+(defcustom lsp-yaml-format-enable t
+ "Enable/disable default YAML formatter."
+ :type 'boolean
+ :group 'lsp-yaml
+ :package-version '(lsp-mode . "6.2"))
+
+(defcustom lsp-yaml-single-quote nil
+ "Use single quote instead of double quotes."
+ :type 'boolean
+ :group 'lsp-yaml
+ :package-version '(lsp-mode . "6.2"))
+
+(defcustom lsp-yaml-bracket-spacing t
+ "Print spaces between brackets in objects."
+ :type 'boolean
+ :group 'lsp-yaml
+ :package-version '(lsp-mode . "6.2"))
+
+(defcustom lsp-yaml-prose-wrap "preserve"
+ "Options for prose-wrap.
+ Always: wrap prose if it exceeds the print width.
+ Never: never wrap the prose.
+ Preserve: wrap prose as-is."
+ :type '(choice
+ (const "always")
+ (const "never")
+ (const "preserve"))
+ :group 'lsp-yaml
+ :package-version '(lsp-mode . "6.2"))
+
+(defcustom lsp-yaml-print-width 80
+ "Specify the line length that the printer will wrap on."
+ :type 'number
+ :group 'lsp-yaml
+ :package-version '(lsp-mode . "6.2"))
+
+(defcustom lsp-yaml-validate t
+ "Enable/disable validation feature."
+ :type 'boolean
+ :group 'lsp-yaml
+ :package-version '(lsp-mode . "6.2"))
+
+(defcustom lsp-yaml-hover t
+ "Enable/disable hover feature."
+ :type 'boolean
+ :group 'lsp-yaml
+ :package-version '(lsp-mode . "6.2"))
+
+(defcustom lsp-yaml-completion t
+ "Enable/disable completion feature."
+ :type 'boolean
+ :group 'lsp-yaml
+ :package-version '(lsp-mode . "6.2"))
+
+(defcustom lsp-yaml-schemas '()
+ "Associate schemas to YAML files in a glob pattern."
+ :type '(alist :key-type (symbol :tag "schema") :value-type (lsp-string-vector :tag "files (glob)"))
+ :group 'lsp-yaml
+ :package-version '(lsp-mode . "6.2"))
+
+(defcustom lsp-yaml-schema-store-enable t
+ "Enable/disable JSON Schema store. When set to true, available YAML
+ schemas will be automatically pulled from the store."
+ :type 'boolean
+ :group 'lsp-yaml
+ :package-version '(lsp-mode . "6.2"))
+
+(defcustom lsp-yaml-custom-tags nil
+ "Custom tags for the parser to use."
+ :type '(lsp-repeatable-vector string)
+ :group 'lsp-yaml
+ :package-version '(lsp-mode . "6.2"))
+
+(defcustom lsp-yaml-schema-store-uri "https://www.schemastore.org/api/json/catalog.json"
+ "URL of schema store catalog to use."
+ :type 'string
+ :group 'lsp-yaml)
+
+(defcustom lsp-yaml-schema-store-local-db (expand-file-name
+ (locate-user-emacs-file
+ (f-join ".cache" "lsp" "lsp-yaml-schemas.json")))
+ "Cached databse of schema store."
+ :type 'file
+ :group 'lsp-yaml)
+
+(defcustom lsp-yaml-max-items-computed 5000
+ "The maximum number of outline symbols and folding regions computed.
+Limited for performance reasons."
+ :type 'number
+ :group 'lsp-yaml
+ :package-version '(lsp-mode . "8.0.0"))
+
+
+(defvar lsp-yaml--schema-store-schemas-alist nil
+ "A list of schemas fetched from schema stores.")
+
+(lsp-register-custom-settings
+ '(("yaml.format.enable" lsp-yaml-format-enable t)
+ ("yaml.format.singleQuote" lsp-yaml-single-quote t)
+ ("yaml.format.bracketSpacing" lsp-yaml-bracket-spacing)
+ ("yaml.format.proseWrap" lsp-yaml-prose-wrap)
+ ("yaml.format.printWidth" lsp-yaml-print-width)
+ ("yaml.validate" lsp-yaml-validate t)
+ ("yaml.hover" lsp-yaml-hover t)
+ ("yaml.completion" lsp-yaml-completion t)
+ ("yaml.schemas" lsp-yaml-schemas)
+ ("yaml.schemaStore.enable" lsp-yaml-schema-store-enable t)
+ ("yaml.schemaStore.url" lsp-yaml-schema-store-uri)
+ ("yaml.customTags" lsp-yaml-custom-tags)
+ ("yaml.maxItemsComputed" lsp-yaml-max-items-computed)))
+
+(defcustom lsp-yaml-server-command '("yaml-language-server" "--stdio")
+ "Command to start yaml-languageserver."
+ :type '(repeat string)
+ :group 'lsp-yaml
+ :package-version '(lsp-mode . "6.2"))
+
+(lsp-dependency 'yaml-language-server
+ '(:system "yaml-language-server")
+ '(:npm :package "yaml-language-server"
+ :path "yaml-language-server"))
+
+(lsp-register-client
+ (make-lsp-client :new-connection (lsp-stdio-connection
+ (lambda ()
+ `(,(or (executable-find (cl-first lsp-yaml-server-command))
+ (lsp-package-path 'yaml-language-server))
+ ,@(cl-rest lsp-yaml-server-command))))
+ :major-modes '(yaml-mode k8s-mode)
+ :priority 0
+ :server-id 'yamlls
+ :initialized-fn (lambda (workspace)
+ (with-lsp-workspace workspace
+ (lsp--set-configuration
+ (lsp-configuration-section "yaml"))))
+ :download-server-fn (lambda (_client callback error-callback _update?)
+ (lsp-package-ensure 'yaml-language-server
+ callback error-callback))))
+
+(defconst lsp-yaml--built-in-kubernetes-schema
+ '((name . "Kubernetes")
+ (description . "Built-in kubernetes manifest schema definition")
+ (url . "kubernetes")
+ (fileMatch . ["*-k8s.yaml" "*-k8s.yml"])))
+
+(defun lsp-yaml-download-schema-store-db (&optional force-downloading)
+ "Download the remote schema store at `lsp-yaml-schema-store-uri' into local cache.
+Set FORCE-DOWNLOADING to non-nil to force re-download the database."
+ (interactive "P")
+ (when (or force-downloading (not (file-exists-p lsp-yaml-schema-store-local-db)))
+ (unless (file-directory-p (file-name-directory lsp-yaml-schema-store-local-db))
+ (mkdir (file-name-directory lsp-yaml-schema-store-local-db) t))
+ (url-copy-file lsp-yaml-schema-store-uri lsp-yaml-schema-store-local-db force-downloading)))
+
+(defun lsp-yaml--get-supported-schemas ()
+ "Get out the list of supported schemas."
+ (when (and lsp-yaml-schema-store-enable
+ (not lsp-yaml--schema-store-schemas-alist))
+ (lsp-yaml-download-schema-store-db)
+ (setq lsp-yaml--schema-store-schemas-alist
+ (alist-get 'schemas (json-read-file lsp-yaml-schema-store-local-db))))
+ (seq-concatenate 'list (list lsp-yaml--built-in-kubernetes-schema) lsp-yaml--schema-store-schemas-alist))
+
+(defun lsp-yaml-set-buffer-schema (uri-string)
+ "Set yaml schema for the current buffer to URI-STRING."
+ (interactive "MURI: ")
+ (let* ((uri (intern uri-string))
+ (workspace-path (file-relative-name
+ (lsp--uri-to-path (lsp--buffer-uri))
+ (lsp-workspace-root (lsp--buffer-uri))))
+ (glob (concat "/" workspace-path))
+ (current-config (assoc uri lsp-yaml-schemas))
+ (current-patterns (and current-config (cdr current-config))))
+ (if current-config
+ (or (member glob (append current-patterns nil))
+ (setq lsp-yaml-schemas
+ (cl-acons uri
+ (vconcat (vector glob) current-patterns)
+ (assq-delete-all uri
+ (mapcar (lambda (x) (lsp-yaml--remove-glob x glob))
+ lsp-yaml-schemas)))))
+ (setq lsp-yaml-schemas
+ (cl-acons uri (vector glob) (mapcar (lambda (x) (lsp-yaml--remove-glob x glob))
+ lsp-yaml-schemas))))
+ (lsp--set-configuration (lsp-configuration-section "yaml"))))
+
+(defun lsp-yaml-select-buffer-schema ()
+ "Select schema for the current buffer based on the list of supported schemas."
+ (interactive)
+ (let* ((schema (lsp--completing-read "Select buffer schema: "
+ (lsp-yaml--get-supported-schemas)
+ (lambda (schema)
+ (format "%s: %s" (alist-get 'name schema)(alist-get 'description schema)))
+ nil t))
+ (uri (alist-get 'url schema)))
+ (lsp-yaml-set-buffer-schema uri)))
+
+(defun lsp-yaml--remove-glob (mapping glob)
+ (let ((patterns (cdr mapping)))
+ (cons (car mapping)
+ (vconcat (-filter (lambda (p) (not (equal p glob)))
+ (append patterns nil)) nil))))
+
+(lsp-consistency-check lsp-yaml)
+
+(provide 'lsp-yaml)
+;;; lsp-yaml.el ends here
diff --git a/elpa/lsp-mode-20220505.630/lsp-yaml.elc b/elpa/lsp-mode-20220505.630/lsp-yaml.elc
new file mode 100644
index 0000000..9c218f2
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-yaml.elc
Binary files differ
diff --git a/elpa/lsp-mode-20220505.630/lsp-zig.el b/elpa/lsp-mode-20220505.630/lsp-zig.el
new file mode 100644
index 0000000..0d19acd
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-zig.el
@@ -0,0 +1,50 @@
+;;; lsp-zig.el --- lsp-mode Zig integration -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2021 Riccardo Binetti
+
+;; Author: Riccardo Binetti <rbino@gmx.com>
+;; Keywords: languages,tools
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; client for zls, the Zig language server
+
+;;; Code:
+
+(require 'lsp-mode)
+
+(defgroup lsp-zig nil
+ "LSP support for Zig via zls."
+ :group 'lsp-mode
+ :link '(url-link "https://github.com/zigtools/zls"))
+
+(defcustom lsp-zig-zls-executable "zls"
+ "The zls executable to use.
+Leave as just the executable name to use the default behavior of
+finding the executable with variable `exec-path'."
+ :group 'lsp-zig
+ :type 'string)
+
+(lsp-register-client
+ (make-lsp-client
+ :new-connection (lsp-stdio-connection (lambda () lsp-zig-zls-executable))
+ :activation-fn (lsp-activate-on "zig")
+ :server-id 'zls))
+
+(lsp-consistency-check lsp-zig)
+
+(provide 'lsp-zig)
+;;; lsp-zig.el ends here
diff --git a/elpa/lsp-mode-20220505.630/lsp-zig.elc b/elpa/lsp-mode-20220505.630/lsp-zig.elc
new file mode 100644
index 0000000..c70ede5
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp-zig.elc
Binary files differ
diff --git a/elpa/lsp-mode-20220505.630/lsp.el b/elpa/lsp-mode-20220505.630/lsp.el
new file mode 100644
index 0000000..e4f4b5d
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp.el
@@ -0,0 +1,8 @@
+;; The code was moved into lsp-mode.el. This file is kept only for backward compatibility.
+(require 'lsp-mode)
+
+;; (warn "Replace (require 'lsp) with (require 'lsp-mode)")
+
+(provide 'lsp)
+
+;;; lsp.el ends here
diff --git a/elpa/lsp-mode-20220505.630/lsp.elc b/elpa/lsp-mode-20220505.630/lsp.elc
new file mode 100644
index 0000000..9e9fe77
--- /dev/null
+++ b/elpa/lsp-mode-20220505.630/lsp.elc
Binary files differ
diff --git a/elpa/lsp-pyright-20220411.1753/lsp-pyright-autoloads.el b/elpa/lsp-pyright-20220411.1753/lsp-pyright-autoloads.el
new file mode 100644
index 0000000..5b9ae3c
--- /dev/null
+++ b/elpa/lsp-pyright-20220411.1753/lsp-pyright-autoloads.el
@@ -0,0 +1,22 @@
+;;; lsp-pyright-autoloads.el --- automatically extracted autoloads -*- lexical-binding: t -*-
+;;
+;;; Code:
+
+(add-to-list 'load-path (directory-file-name
+ (or (file-name-directory #$) (car load-path))))
+
+
+;;;### (autoloads nil "lsp-pyright" "lsp-pyright.el" (0 0 0 0))
+;;; Generated autoloads from lsp-pyright.el
+
+(register-definition-prefixes "lsp-pyright" '("lsp-pyright-"))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; coding: utf-8
+;; End:
+;;; lsp-pyright-autoloads.el ends here
diff --git a/elpa/lsp-pyright-20220411.1753/lsp-pyright-pkg.el b/elpa/lsp-pyright-20220411.1753/lsp-pyright-pkg.el
new file mode 100644
index 0000000..a1de15a
--- /dev/null
+++ b/elpa/lsp-pyright-20220411.1753/lsp-pyright-pkg.el
@@ -0,0 +1,2 @@
+;;; Generated package description from lsp-pyright.el -*- no-byte-compile: t -*-
+(define-package "lsp-pyright" "20220411.1753" "Python LSP client using Pyright" '((emacs "26.1") (lsp-mode "7.0") (dash "2.18.0") (ht "2.0")) :commit "ab7369d96f4d7d058d0e06e743f86fda8ecc191c" :authors '(("Arif Rezai, Vincent Zhang, Andrew Christianson")) :maintainer '("Arif Rezai, Vincent Zhang, Andrew Christianson") :keywords '("languages" "tools" "lsp") :url "https://github.com/emacs-lsp/lsp-pyright")
diff --git a/elpa/lsp-pyright-20220411.1753/lsp-pyright.el b/elpa/lsp-pyright-20220411.1753/lsp-pyright.el
new file mode 100644
index 0000000..2778ebf
--- /dev/null
+++ b/elpa/lsp-pyright-20220411.1753/lsp-pyright.el
@@ -0,0 +1,253 @@
+;;; lsp-pyright.el --- Python LSP client using Pyright -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2020 emacs-lsp maintainers
+
+;; Author: Arif Rezai, Vincent Zhang, Andrew Christianson
+;; Version: 0.2.0
+;; Package-Version: 20220411.1753
+;; Package-Commit: ab7369d96f4d7d058d0e06e743f86fda8ecc191c
+;; Package-Requires: ((emacs "26.1") (lsp-mode "7.0") (dash "2.18.0") (ht "2.0"))
+;; Homepage: https://github.com/emacs-lsp/lsp-pyright
+;; Keywords: languages, tools, lsp
+
+
+;; This file is not part of GNU 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 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.
+
+;; For a full copy of the GNU General Public License
+;; see <https://www.gnu.org/licenses/>.
+;;
+;;; Commentary:
+;;
+;; Pyright language server.
+;;
+;;; Code:
+
+(require 'lsp-mode)
+(require 'dash)
+(require 'ht)
+
+;; Group declaration
+(defgroup lsp-pyright nil
+ "LSP support for python using the Pyright Language Server."
+ :group 'lsp-mode
+ :link '(url-link "https://github.com/microsoft/pyright"))
+
+(defcustom lsp-pyright-langserver-command-args '("--stdio")
+ "Command to start pyright-langserver."
+ :type '(repeat string)
+ :group 'lsp-pyright)
+
+(defcustom lsp-pyright-disable-language-services nil
+ "Disables all language services except for \"hover\"."
+ :type 'boolean
+ :group 'lsp-pyright)
+
+(defcustom lsp-pyright-disable-organize-imports nil
+ "Disables the \"Organize Imports\" command."
+ :type 'boolean
+ :group 'lsp-pyright)
+
+(defcustom lsp-pyright-use-library-code-for-types t
+ "Determines whether to analyze library code.
+In order to extract type information in the absence of type stub files.
+This can add significant overhead and may result in
+poor-quality type information.
+The default value for this option is true."
+ :type 'boolean
+ :group 'lsp-pyright)
+
+(defcustom lsp-pyright-diagnostic-mode "openFilesOnly"
+ "Determines pyright diagnostic mode.
+Whether pyright analyzes (and reports errors for) all files
+in the workspace, as indicated by the config file.
+If this option is set to \"openFilesOnly\", pyright analyzes only open files."
+ :type '(choice
+ (const "openFilesOnly")
+ (const "workspace"))
+ :group 'lsp-pyright)
+
+(defcustom lsp-pyright-typechecking-mode "basic"
+ "Determines the default type-checking level used by pyright.
+This can be overridden in the configuration file."
+ :type '(choice
+ (const "off")
+ (const "basic")
+ (const "strict"))
+ :group 'lsp-pyright)
+
+(defcustom lsp-pyright-log-level "info"
+ "Determines the default log level used by pyright.
+This can be overridden in the configuration file."
+ :type '(choice
+ (const "error")
+ (const "warning")
+ (const "info")
+ (const "trace"))
+ :group 'lsp-pyright)
+
+(defcustom lsp-pyright-auto-search-paths t
+ "Determines whether pyright automatically adds common search paths.
+i.e: Paths like \"src\" if there are no execution environments defined in the
+config file."
+ :type 'boolean
+ :group 'lsp-pyright)
+
+(defcustom lsp-pyright-extra-paths []
+ "Paths to add to the default execution environment extra paths.
+If there are no execution environments defined in the config file."
+ :type 'lsp-string-vector
+ :group 'lsp-pyright)
+(make-variable-buffer-local 'lsp-pyright-extra-paths)
+
+(defcustom lsp-pyright-auto-import-completions t
+ "Determines whether pyright offers auto-import completions."
+ :type 'boolean
+ :group 'lsp-pyright)
+
+(defcustom lsp-pyright-stub-path ""
+ "Path to directory containing custom type stub files."
+ :type 'directory
+ :group 'lsp-pyright)
+
+(defcustom lsp-pyright-venv-path nil
+ "Path to folder with subdirectories that contain virtual environments.
+Virtual Envs specified in pyrightconfig.json will be looked up in this path."
+ :type '(choice (const :tag "None" nil) file)
+ :group 'lsp-pyright)
+
+(defcustom lsp-pyright-venv-directory nil
+ "Folder with subdirectories that contain virtual environments.
+Virtual Envs specified in pyrightconfig.json will be looked up in this path."
+ :type '(choice (const :tag "None" nil) directory)
+ :group 'lsp-pyright)
+
+(defcustom lsp-pyright-typeshed-paths []
+ "Paths to look for typeshed modules.
+Pyright currently honors only the first path in the array."
+ :type 'lsp-string-vector
+ :group 'lsp-pyright)
+
+(defcustom lsp-pyright-multi-root t
+ "If non nil, lsp-pyright will be started in multi-root mode."
+ :type 'boolean
+ :group 'lsp-pyright)
+
+(defcustom lsp-pyright-python-executable-cmd "python"
+ "Command to specify the Python command for pyright.
+Similar to the `python-shell-interpreter', but used only with mspyls.
+Useful when there are multiple python versions in system.
+e.g, there are `python2' and `python3', both in system PATH,
+and the default `python' links to python2,
+set as `python3' to let ms-pyls use python 3 environments."
+ :type 'string
+ :group 'lsp-pyright)
+
+(defcustom lsp-pyright-prefer-remote-env t
+ "If non nil, lsp-pyright will perfer remote python environment.
+Only available in Emacs 27 and above."
+ :type 'boolean
+ :group 'lsp-pyright)
+
+(defun lsp-pyright-locate-venv ()
+ "Look for virtual environments local to the workspace."
+ (or lsp-pyright-venv-path
+ (and lsp-pyright-venv-directory
+ (-when-let (venv-base-directory (locate-dominating-file default-directory lsp-pyright-venv-directory))
+ (concat venv-base-directory lsp-pyright-venv-directory)))
+ (-when-let (venv-base-directory (locate-dominating-file default-directory "venv/"))
+ (concat venv-base-directory "venv"))
+ (-when-let (venv-base-directory (locate-dominating-file default-directory ".venv/"))
+ (concat venv-base-directory ".venv"))))
+
+(defun lsp-pyright-locate-python ()
+ "Look for python executable cmd to the workspace."
+ (or (executable-find (f-expand "bin/python" (lsp-pyright-locate-venv)))
+ (with-no-warnings
+ (if (>= emacs-major-version 27)
+ (executable-find lsp-pyright-python-executable-cmd lsp-pyright-prefer-remote-env)
+ (executable-find lsp-pyright-python-executable-cmd)))))
+
+(defun lsp-pyright--begin-progress-callback (workspace &rest _)
+ "Log begin progress information.
+Current LSP WORKSPACE should be passed in."
+ (when lsp-progress-via-spinner
+ (with-lsp-workspace workspace
+ (--each (lsp--workspace-buffers workspace)
+ (when (buffer-live-p it)
+ (with-current-buffer it
+ (lsp--spinner-start)))))
+ )
+ (lsp-log "Pyright language server is analyzing..."))
+
+(defun lsp-pyright--report-progress-callback (_workspace params)
+ "Log report progress information.
+First element of PARAMS will be passed into `lsp-log'."
+ (when (and (arrayp params) (> (length params) 0))
+ (lsp-log (aref params 0))))
+
+(defun lsp-pyright--end-progress-callback (workspace &rest _)
+ "Log end progress information.
+Current LSP WORKSPACE should be passed in."
+ (when lsp-progress-via-spinner
+ (with-lsp-workspace workspace
+ (--each (lsp--workspace-buffers workspace)
+ (when (buffer-live-p it)
+ (with-current-buffer it
+ (lsp--spinner-stop)))))
+ )
+ (lsp-log "Pyright language server is analyzing...done"))
+
+(lsp-register-custom-settings
+ `(("pyright.disableLanguageServices" lsp-pyright-disable-language-services t)
+ ("pyright.disableOrganizeImports" lsp-pyright-disable-organize-imports t)
+ ("python.analysis.autoImportCompletions" lsp-pyright-auto-import-completions t)
+ ("python.analysis.typeshedPaths" lsp-pyright-typeshed-paths)
+ ("python.analysis.stubPath" lsp-pyright-stub-path)
+ ("python.analysis.useLibraryCodeForTypes" lsp-pyright-use-library-code-for-types t)
+ ("python.analysis.diagnosticMode" lsp-pyright-diagnostic-mode)
+ ("python.analysis.typeCheckingMode" lsp-pyright-typechecking-mode)
+ ("python.analysis.logLevel" lsp-pyright-log-level)
+ ("python.analysis.autoSearchPaths" lsp-pyright-auto-search-paths t)
+ ("python.analysis.extraPaths" lsp-pyright-extra-paths)
+ ("python.pythonPath" lsp-pyright-locate-python)
+ ;; We need to send empty string, otherwise pyright-langserver fails with parse error
+ ("python.venvPath" (lambda () (or lsp-pyright-venv-path "")))))
+
+(lsp-dependency 'pyright
+ '(:system "pyright-langserver")
+ '(:npm :package "pyright"
+ :path "pyright-langserver"))
+
+(lsp-register-client
+ (make-lsp-client
+ :new-connection (lsp-stdio-connection (lambda ()
+ (cons (lsp-package-path 'pyright)
+ lsp-pyright-langserver-command-args)))
+ :major-modes '(python-mode)
+ :server-id 'pyright
+ :multi-root lsp-pyright-multi-root
+ :priority 3
+ :initialized-fn (lambda (workspace)
+ (with-lsp-workspace workspace
+ ;; we send empty settings initially, LSP server will ask for the
+ ;; configuration of each workspace folder later separately
+ (lsp--set-configuration
+ (make-hash-table :test 'equal))))
+ :download-server-fn (lambda (_client callback error-callback _update?)
+ (lsp-package-ensure 'pyright callback error-callback))
+ :notification-handlers (lsp-ht ("pyright/beginProgress" 'lsp-pyright--begin-progress-callback)
+ ("pyright/reportProgress" 'lsp-pyright--report-progress-callback)
+ ("pyright/endProgress" 'lsp-pyright--end-progress-callback))))
+
+(provide 'lsp-pyright)
+;;; lsp-pyright.el ends here
diff --git a/elpa/lsp-pyright-20220411.1753/lsp-pyright.elc b/elpa/lsp-pyright-20220411.1753/lsp-pyright.elc
new file mode 100644
index 0000000..f9722b2
--- /dev/null
+++ b/elpa/lsp-pyright-20220411.1753/lsp-pyright.elc
Binary files differ
diff --git a/elpa/lsp-ui-20220425.1046/lsp-ui-autoloads.el b/elpa/lsp-ui-20220425.1046/lsp-ui-autoloads.el
new file mode 100644
index 0000000..0d7ec22
--- /dev/null
+++ b/elpa/lsp-ui-20220425.1046/lsp-ui-autoloads.el
@@ -0,0 +1,80 @@
+;;; lsp-ui-autoloads.el --- automatically extracted autoloads -*- lexical-binding: t -*-
+;;
+;;; Code:
+
+(add-to-list 'load-path (directory-file-name
+ (or (file-name-directory #$) (car load-path))))
+
+
+;;;### (autoloads nil "lsp-ui" "lsp-ui.el" (0 0 0 0))
+;;; Generated autoloads from lsp-ui.el
+
+(autoload 'lsp-ui-mode "lsp-ui" "\
+Toggle language server UI mode on or off.
+‘lsp-ui-mode’ is a minor mode that contains a series of useful UI
+integrations for ‘lsp-mode’. With a prefix argument ARG, enable
+language server UI mode if ARG is positive, and disable it
+otherwise. If called from Lisp, enable the mode if ARG is
+omitted or nil, and toggle it if ARG is ‘toggle’.
+
+\(fn &optional ARG)" t nil)
+
+(register-definition-prefixes "lsp-ui" '("lsp-ui-"))
+
+;;;***
+
+;;;### (autoloads nil "lsp-ui-doc" "lsp-ui-doc.el" (0 0 0 0))
+;;; Generated autoloads from lsp-ui-doc.el
+
+(register-definition-prefixes "lsp-ui-doc" '("lsp-ui-doc-"))
+
+;;;***
+
+;;;### (autoloads nil "lsp-ui-flycheck" "lsp-ui-flycheck.el" (0 0
+;;;;;; 0 0))
+;;; Generated autoloads from lsp-ui-flycheck.el
+
+(register-definition-prefixes "lsp-ui-flycheck" '("lsp-ui-flycheck-"))
+
+;;;***
+
+;;;### (autoloads nil "lsp-ui-imenu" "lsp-ui-imenu.el" (0 0 0 0))
+;;; Generated autoloads from lsp-ui-imenu.el
+
+(register-definition-prefixes "lsp-ui-imenu" '("lsp-ui-imenu"))
+
+;;;***
+
+;;;### (autoloads nil "lsp-ui-peek" "lsp-ui-peek.el" (0 0 0 0))
+;;; Generated autoloads from lsp-ui-peek.el
+
+(register-definition-prefixes "lsp-ui-peek" '("lsp-"))
+
+;;;***
+
+;;;### (autoloads nil "lsp-ui-sideline" "lsp-ui-sideline.el" (0 0
+;;;;;; 0 0))
+;;; Generated autoloads from lsp-ui-sideline.el
+
+(register-definition-prefixes "lsp-ui-sideline" '("lsp-ui-sideline"))
+
+;;;***
+
+;;;### (autoloads nil "lsp-ui-util" "lsp-ui-util.el" (0 0 0 0))
+;;; Generated autoloads from lsp-ui-util.el
+
+(register-definition-prefixes "lsp-ui-util" '("lsp-ui-util-"))
+
+;;;***
+
+;;;### (autoloads nil nil ("lsp-ui-pkg.el") (0 0 0 0))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; coding: utf-8
+;; End:
+;;; lsp-ui-autoloads.el ends here
diff --git a/elpa/lsp-ui-20220425.1046/lsp-ui-doc.el b/elpa/lsp-ui-20220425.1046/lsp-ui-doc.el
new file mode 100644
index 0000000..1a1a666
--- /dev/null
+++ b/elpa/lsp-ui-20220425.1046/lsp-ui-doc.el
@@ -0,0 +1,1220 @@
+;;; lsp-ui-doc.el --- Lsp-Ui-Doc -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 Sebastien Chapuis
+
+;; Author: Sebastien Chapuis <sebastien@chapu.is>
+;; URL: https://github.com/emacs-lsp/lsp-ui
+;; Keywords: languagues, tools
+;; Version: 6.2
+
+;;; License
+;;
+;; 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:
+;;
+;; Show documentation of the symbol at point in a child frame
+
+;;; Code:
+
+(require 'lsp-ui-util)
+
+(require 'lsp-protocol)
+(require 'lsp-mode)
+(require 'dash)
+(require 'goto-addr)
+(require 'markdown-mode)
+
+(require 'cl-lib)
+(require 'face-remap)
+(require 'subr-x)
+
+(when (featurep 'xwidget-internal)
+ (require 'xwidget))
+
+(declare-function make-xwidget "ext:xwidget" (type title width height arguments &optional buffer))
+(declare-function set-xwidget-query-on-exit-flag "ext:xwidget")
+(declare-function xwidget-webkit-mode "ext:xwidget")
+(declare-function xwidget-webkit-goto-uri "ext:xwidget" (xwidget uri))
+(declare-function xwidget-at "ext:xwidget" (pos))
+(declare-function xwidget-webkit-execute-script "ext:xwidget" (xwidget script &optional callback))
+(declare-function xwidget-webkit-execute-script-rv "ext:xwidget" (xwidget script &optional default))
+(declare-function xwidget-resize "ext:xwidget" (xwidget new-width new-height))
+
+(defgroup lsp-ui-doc nil
+ "Display informations of the current line."
+ :group 'tools
+ :group 'convenience
+ :group 'lsp-ui
+ :link '(custom-manual "(lsp-ui-doc) Top")
+ :link '(info-link "(lsp-ui-doc) Customizing"))
+
+(defcustom lsp-ui-doc-enable t
+ "Whether or not to enable lsp-ui-doc.
+Displays documentation of the symbol at point on hover. This only takes effect when a buffer is started."
+ :type 'boolean
+ :group 'lsp-ui)
+
+(defcustom lsp-ui-doc-show-with-mouse t
+ "Move the mouse pointer over a symbol to show its documentation."
+ :type 'boolean
+ :group 'lsp-ui-doc)
+
+(defcustom lsp-ui-doc-show-with-cursor nil
+ "Move the cursor over a symbol to show its documentation."
+ :type 'boolean
+ :group 'lsp-ui-doc)
+
+(defcustom lsp-ui-doc-header nil
+ "Whether or not to enable the header which display the symbol string."
+ :type 'boolean
+ :group 'lsp-ui-doc)
+
+(defcustom lsp-ui-doc-include-signature nil
+ "Whether or not to include the object signature/type in the frame."
+ :type 'boolean
+ :group 'lsp-ui-doc)
+
+(defcustom lsp-ui-doc-position 'top
+ "Where to display the doc when moving the point cursor.
+This affect the position of the documentation when `lsp-ui-doc-show-with-cursor'
+is non-nil."
+ :type '(choice (const :tag "Top" top)
+ (const :tag "Bottom" bottom)
+ (const :tag "At point" at-point))
+ :group 'lsp-ui-doc)
+
+(defcustom lsp-ui-doc-alignment 'frame
+ "How to align the doc.
+This only takes effect when `lsp-ui-doc-position' is 'top or 'bottom."
+ :type '(choice (const :tag "Frame" frame)
+ (const :tag "Window" window))
+ :group 'lsp-ui-doc)
+
+(defcustom lsp-ui-doc-border "white"
+ "Border color of the frame."
+ :type 'color
+ :group 'lsp-ui-doc)
+
+(defcustom lsp-ui-doc-max-width 150
+ "Maximum number of columns of the frame."
+ :type 'integer
+ :group 'lsp-ui-doc)
+
+(defcustom lsp-ui-doc-webkit-max-width-px 600
+ "Maximum width in pixels for the webkit frame."
+ :type 'integer
+ :group 'lsp-ui-doc)
+
+(defcustom lsp-ui-doc-max-height 13
+ "Maximum number of lines in the frame."
+ :type 'integer
+ :group 'lsp-ui-doc)
+
+(defcustom lsp-ui-doc-use-childframe t
+ "Whether to display documentation in a child-frame or the current frame.
+Child frames requires GNU/Emacs version >= 26 and graphical frames."
+ :type 'boolean
+ :group 'lsp-ui-doc)
+
+(defcustom lsp-ui-doc-use-webkit nil
+ "Whether to display documentation in a WebKit widget in a child-frame.
+This requires GNU/Emacs version >= 26 and built with the `--with-xwidgets`
+option."
+ :type 'boolean
+ :group 'lsp-ui-doc)
+
+(defcustom lsp-ui-doc-delay 0.2
+ "Number of seconds before showing the doc."
+ :type 'number
+ :group 'lsp-ui-doc)
+
+(defcustom lsp-ui-doc-winum-ignore t
+ "Whether to ignore lsp-ui-doc buffers in winum."
+ :type 'boolean
+ :group 'lsp-ui-doc)
+
+(defcustom lsp-ui-doc-enhanced-markdown t
+ "Lsp-ui-doc will attempt to better format the markdown documentation."
+ :type 'boolean
+ :group 'lsp-ui-doc)
+
+(defcustom lsp-ui-doc-text-scale-level 0
+ "Text scale amount for doc buffer."
+ :type 'integer
+ :group 'lsp-ui-doc)
+
+(defface lsp-ui-doc-background
+ '((((background light)) :background "#b3b3b3")
+ (t :background "#272A36"))
+ "Background color of the documentation.
+Only the `background' is used in this face."
+ :group 'lsp-ui-doc)
+
+(defface lsp-ui-doc-header
+ '((t :foreground "black"
+ :background "deep sky blue"))
+ "Face used on the header."
+ :group 'lsp-ui-doc)
+
+(defface lsp-ui-doc-highlight-hover
+ '((t :inherit region))
+ "Face used to highlight the hover symbol/region when using mouse."
+ :group 'lsp-ui-doc)
+
+(defface lsp-ui-doc-url
+ '((t :inherit link))
+ "Face used on links."
+ :group 'lsp-ui-doc)
+
+(defvar lsp-ui-doc-frame-parameters
+ '((left . -1)
+ (no-focus-on-map . t)
+ (min-width . 0)
+ (width . 0)
+ (min-height . 0)
+ (height . 0)
+ (internal-border-width . 1)
+ (vertical-scroll-bars . nil)
+ (horizontal-scroll-bars . nil)
+ (right-fringe . 0)
+ (menu-bar-lines . 0)
+ (tool-bar-lines . 0)
+ (tab-bar-lines . 0)
+ (tab-bar-lines-keep-state . 0)
+ (line-spacing . 0)
+ (unsplittable . t)
+ (undecorated . t)
+ (top . -1)
+ (visibility . nil)
+ (mouse-wheel-frame . nil)
+ (no-other-frame . t)
+ (inhibit-double-buffering . t)
+ (drag-internal-border . t)
+ (no-special-glyphs . t)
+ (desktop-dont-save . t))
+ "Frame parameters used to create the frame.")
+
+(defvar lsp-ui-doc-render-function nil
+ "Function called to format the documentation.
+The function takes a string as parameter and should return a string.
+If this variable is nil (the default), the documentation will be rendered
+as markdown.")
+
+(defvar lsp-ui-doc-frame-hook nil
+ "Hooks run on child-frame creation.
+The functions receive 2 parameters: the frame and its window.")
+
+(defvar lsp-ui-doc-webkit-client-path
+ (concat "file://"
+ (file-name-directory (or load-file-name buffer-file-name))
+ "lsp-ui-doc.html")
+ "Path to the page loaded when a WebKit widget is created.")
+
+;; Avoid warning with emacs < 26
+(declare-function display-buffer-in-child-frame "window.el")
+
+(defvar-local lsp-ui-doc--parent-vars nil
+ "Variables from the parents frame that we want to access in the child.
+Because some variables are buffer local.")
+
+(defvar-local lsp-ui-doc--inline-ov nil
+ "Overlay used to display the documentation in the buffer.")
+
+(defvar-local lsp-ui-doc--highlight-ov nil
+ "Overlay used to highlight the hover symbol.")
+
+(defvar-local lsp-ui-doc--bounds nil)
+(defvar-local lsp-ui-doc--timer nil)
+(defvar-local lsp-ui-doc--from-mouse nil
+ "Non nil when the doc was triggered by a mouse event.")
+(defvar-local lsp-ui-doc--from-mouse-current nil
+ "Non nil when the current call is triggered by a mouse event")
+
+(defconst lsp-ui-doc--buffer-prefix " *lsp-ui-doc-")
+
+(defmacro lsp-ui-doc--with-buffer (&rest body)
+ "Execute BODY in the lsp-ui-doc buffer."
+ (declare (indent 0) (debug t))
+ `(let ((parent-vars (list :buffer (current-buffer)
+ :window (get-buffer-window)))
+ (buffer-list-update-hook nil))
+ (with-current-buffer (get-buffer-create (lsp-ui-doc--make-buffer-name))
+ (setq lsp-ui-doc--parent-vars parent-vars)
+ (prog1 (let ((buffer-read-only nil)
+ (inhibit-modification-hooks t)
+ (inhibit-point-motion-hooks t)
+ (inhibit-redisplay t))
+ ,@body)
+ (setq buffer-read-only t)
+ (let ((text-scale-mode-step 1.1))
+ (text-scale-set lsp-ui-doc-text-scale-level))))))
+
+(defmacro lsp-ui-doc--get-parent (var)
+ "Return VAR in `lsp-ui-doc--parent-vars'."
+ `(plist-get lsp-ui-doc--parent-vars ,var))
+
+(defmacro lsp-ui-doc--set-frame (frame)
+ "Set the frame parameter ‘lsp-ui-doc-frame’ to FRAME."
+ `(set-frame-parameter nil 'lsp-ui-doc-frame ,frame))
+
+(defun lsp-ui-doc--get-frame (&optional _)
+ "Return the child frame."
+ (let ((frame (frame-parameter nil 'lsp-ui-doc-frame)))
+ (and (frame-live-p frame) frame)))
+
+(defsubst lsp-ui-doc--frame-visible-p ()
+ "Return child frame visibility."
+ (let ((frame (lsp-ui-doc--get-frame)))
+ (and frame (frame-visible-p frame))))
+
+(defun lsp-ui-doc--make-buffer-name ()
+ "Construct the buffer name, it should be unique for each frame."
+ (concat lsp-ui-doc--buffer-prefix
+ (or (frame-parameter nil 'window-id)
+ (frame-parameter nil 'name))
+ "*"))
+
+;; ‘markdown-fontify-code-block-default-mode’ isn’t yet available in
+;; Markdown 2.3.
+(defvar markdown-fontify-code-block-default-mode)
+
+(defun lsp-ui-doc--inline-wrapped-line (string)
+ "Wraps a line of text (STRING) for inline display."
+ (cond ((string-empty-p string) "")
+ (t string)))
+
+(defun lsp-ui-doc--inline-formatted-string (string)
+ "Formats STRING for inline rendering."
+ (mapconcat (lambda (line)
+ (lsp-ui-doc--inline-wrapped-line (string-trim-right line)))
+ (split-string string "[\n\v\f\r]")
+ "\n"))
+
+(defun lsp-ui-doc--extract-marked-string (marked-string &optional language)
+ "Render the MARKED-STRING with LANGUAGE."
+ (string-trim-right
+ (let* ((string (if (stringp marked-string)
+ marked-string
+ (lsp:markup-content-value marked-string)))
+ (with-lang (lsp-marked-string? marked-string))
+ (language (or (and with-lang
+ (or (lsp:marked-string-language marked-string)
+ (lsp:markup-content-kind marked-string)))
+ language))
+ (markdown-hr-display-char nil))
+ (cond
+ (lsp-ui-doc-use-webkit
+ (if (and language
+ (not (string= "text" language))
+ (not (string= lsp/markup-kind-markdown language)))
+ (format "```%s\n%s\n```" language string)
+ string))
+ ;; For other programming languages
+ (language (lsp--render-string (lsp-ui-doc--inline-formatted-string string) language))
+ ;; For default element content
+ (t (lsp--render-element (lsp-ui-doc--inline-formatted-string string)))))))
+
+(defun lsp-ui-doc--filter-marked-string (list-marked-string)
+ "Filter the LIST-MARKED-STRING."
+ (let ((groups (--separate (and (lsp-marked-string? it)
+ (lsp-get-renderer (lsp:marked-string-language it)))
+ (append list-marked-string nil))))
+ (if lsp-ui-doc-include-signature
+ list-marked-string
+ (cadr groups))))
+
+(defun lsp-ui-doc--extract (contents)
+ "Extract the documentation from CONTENTS.
+CONTENTS can be differents type of values:
+MarkedString | MarkedString[] | MarkupContent (as defined in the LSP).
+We don't extract the string that `lps-line' is already displaying."
+ (cond
+ ((vectorp contents) ;; MarkedString[]
+ (mapconcat 'lsp-ui-doc--extract-marked-string
+ (lsp-ui-doc--filter-marked-string (seq-filter #'identity contents))
+ "\n\n"
+ ;;(propertize "\n\n" 'face '(:height 0.4))
+ ))
+ ;; when we get markdown contents, render using emacs gfm-view-mode / markdown-mode
+ ((and (lsp-marked-string? contents)
+ (lsp:marked-string-language contents))
+ (lsp-ui-doc--extract-marked-string (lsp:marked-string-value contents)
+ (lsp:marked-string-language contents)))
+ ;; The specification for MarkedString also includes raw strings of
+ ;; markdown, which is not reflected by `lsp-marked-string?'
+ ((stringp contents)
+ (lsp-ui-doc--extract-marked-string contents lsp/markup-kind-markdown))
+ ((lsp-marked-string? contents) (lsp-ui-doc--extract-marked-string contents))
+ ((and (lsp-markup-content? contents)
+ (string= (lsp:markup-content-kind contents) lsp/markup-kind-markdown))
+ (lsp-ui-doc--extract-marked-string (lsp:markup-content-value contents) lsp/markup-kind-markdown))
+ ((and (lsp-markup-content? contents)
+ (string= (lsp:markup-content-kind contents) lsp/markup-kind-plain-text))
+ (lsp:markup-content-value contents))))
+
+(defun lsp-ui-doc--webkit-run-xwidget ()
+ "Launch embedded WebKit instance."
+ (lsp-ui-doc--with-buffer
+ (let ((inhibit-read-only t))
+ (insert " ")
+ (goto-char 1)
+ (let ((id (make-xwidget 'webkit nil 1 1 nil (buffer-name))))
+ (set-xwidget-query-on-exit-flag id nil)
+ (put-text-property (point) (+ 1 (point))
+ 'display (list 'xwidget ':xwidget id))
+ (xwidget-webkit-mode)
+ (xwidget-webkit-goto-uri (xwidget-at 1)
+ lsp-ui-doc-webkit-client-path)
+ (lsp-ui-doc--webkit-set-width)
+ (lsp-ui-doc--webkit-set-background)
+ (lsp-ui-doc--webkit-set-foreground)))))
+
+(defun lsp-ui-doc--webkit-set-width ()
+ "Set webkit document max-width CSS property."
+ (lsp-ui-doc--webkit-execute-script
+ (format "document.documentElement.style.setProperty('--webkit-max-width-px', %d + 'px');"
+ lsp-ui-doc-webkit-max-width-px)))
+
+(defun lsp-ui-doc--webkit-set-background ()
+ "Set background color of the WebKit widget."
+ (lsp-ui-doc--webkit-execute-script
+ (format "document.body.style.background = '%s';"
+ "#fdfdfd"
+ ;; (face-attribute 'lsp-ui-doc-background :background)
+ )))
+
+(defun lsp-ui-doc--webkit-set-foreground ()
+ "Set foreground color of the WebKit widget."
+ (lsp-ui-doc--webkit-execute-script
+ (format "document.body.style.color = '%s';"
+ (face-attribute 'default :foreground))))
+
+(defun lsp-ui-doc--webkit-get-xwidget ()
+ "Return Xwidget instance."
+ (lsp-ui-doc--with-buffer
+ (xwidget-at 1)))
+
+(defun lsp-ui-doc--webkit-execute-script (script &optional fn)
+ "Execute SCRIPT in embedded Xwidget and run optional callback FN."
+ (-when-let* ((xw (lsp-ui-doc--webkit-get-xwidget)))
+ (xwidget-webkit-execute-script xw script fn)))
+
+(defun lsp-ui-doc--webkit-execute-script-rv (script)
+ "Execute SCRIPT in embedded Xwidget synchronously."
+ (-when-let* ((xw (lsp-ui-doc--webkit-get-xwidget)))
+ (xwidget-webkit-execute-script-rv xw script)))
+
+(defun lsp-ui-doc--hide-frame (&optional _win)
+ "Hide the frame."
+ (setq lsp-ui-doc--bounds nil
+ lsp-ui-doc--from-mouse nil)
+ (lsp-ui-util-safe-delete-overlay lsp-ui-doc--inline-ov)
+ (lsp-ui-util-safe-delete-overlay lsp-ui-doc--highlight-ov)
+ (when-let ((frame (lsp-ui-doc--get-frame)))
+ (when (frame-visible-p frame)
+ (make-frame-invisible frame))))
+
+(defun lsp-ui-doc--buffer-width ()
+ "Calcul the max width of the buffer."
+ (lsp-ui-doc--with-buffer
+ (save-excursion
+ (let ((max 0))
+ (goto-char (point-min))
+ (while (not (eobp))
+ (let* ((len (- (line-end-position) (line-beginning-position))))
+ (when (> len max)
+ (setq max len)))
+ (forward-line 1))
+ max))))
+
+(defun lsp-ui-doc--line-height (&optional line)
+ "Return the pos-y of the LINE on screen, in pixel."
+ (or
+ (nth 2 (or (window-line-height line)
+ (and (redisplay t)
+ (window-line-height line))))
+ 0))
+
+(defun lsp-ui-doc--sideline-pos-y ()
+ "Mark as unused function."
+ (-> (when (bound-and-true-p lsp-ui-sideline--occupied-lines)
+ (-min lsp-ui-sideline--occupied-lines))
+ (line-number-at-pos)
+ (lsp-ui-doc--line-height)))
+
+(defun lsp-ui-doc--webkit-resize-callback (size)
+ "Callback when resizing using webkit depends on the SIZE."
+ (let ((offset-width (round (aref size 0)))
+ (offset-height (round (aref size 1))))
+ (xwidget-resize (lsp-ui-doc--webkit-get-xwidget) offset-width offset-height))
+ (lsp-ui-doc--move-frame (lsp-ui-doc--get-frame)))
+
+(defun lsp-ui-doc--scale-column-width (width)
+ "Return WIDTH adjusted relative to the text scale."
+ (floor (/ width (expt 1.1 lsp-ui-doc-text-scale-level))))
+
+(defun lsp-ui-doc--resize-buffer ()
+ "If the buffer's width is larger than the current frame, resize it."
+ (if lsp-ui-doc-use-webkit
+ (lsp-ui-doc--webkit-execute-script
+ "[document.querySelector('#lsp-ui-webkit').offsetWidth, document.querySelector('#lsp-ui-webkit').offsetHeight];"
+ 'lsp-ui-doc--webkit-resize-callback)
+
+ (let* ((frame-width (frame-width))
+ (fill-column (lsp-ui-doc--scale-column-width (min lsp-ui-doc-max-width (- frame-width 5)))))
+ (when (> (lsp-ui-doc--buffer-width) (min lsp-ui-doc-max-width frame-width))
+ (lsp-ui-doc--with-buffer
+ (fill-region (point-min) (point-max)))))))
+
+(defun lsp-ui-doc--mv-at-point (width height start-x start-y)
+ "Return position of FRAME to be where the point is.
+WIDTH is the child frame width.
+HEIGHT is the child frame height.
+START-X is the position x of the current window.
+START-Y is the position y of the current window.
+The algorithm prefers to position FRAME just above the
+symbol at point, to not obstruct the view of the code that follows.
+If there's no space above in the current window, it places
+FRAME just below the symbol at point."
+ (-let* (((x . y) (--> (or lsp-ui-doc--bounds (bounds-of-thing-at-point 'symbol))
+ (or (posn-x-y (posn-at-point (car it)))
+ (if (< (car it) (window-start))
+ (cons 0 0)
+ (posn-x-y (posn-at-point (1- (window-end))))))))
+ (frame-relative-symbol-x (+ start-x x (* (frame-char-width) 2)))
+ (frame-relative-symbol-y (+ start-y y))
+ (char-height (frame-char-height))
+ ;; Make sure the frame is positioned horizontally such that
+ ;; it does not go beyond the frame boundaries.
+ (frame-x (or (and (<= (frame-outer-width) (+ frame-relative-symbol-x width))
+ (- x (- (+ frame-relative-symbol-x width)
+ (frame-outer-width))))
+ x))
+ (frame-y (+ (or (and (<= height frame-relative-symbol-y)
+ (- y height))
+ (+ y char-height))
+ (if (fboundp 'window-tab-line-height) (window-tab-line-height) 0))))
+ (cons (+ start-x frame-x) (+ start-y frame-y))))
+
+(defun lsp-ui-doc--size-and-pos-changed (frame left top width height)
+ (-let (((prev-left . prev-top) (frame-position frame)))
+ (not (and (= left prev-left)
+ (= top prev-top)
+ (= height (frame-text-height frame))
+ (= width (frame-text-width frame))))))
+
+(defun lsp-ui-doc--move-frame (frame)
+ "Place our FRAME on screen."
+ (-let* (((left top right _bottom) (window-edges nil t nil t))
+ (window (frame-root-window frame))
+ (char-h (frame-char-height frame))
+ (char-w (frame-char-width frame))
+ ((width . height) (window-text-pixel-size window nil nil 10000 10000 t))
+ (width (+ width (* char-w 1))) ;; margins
+ (height (min (- (* lsp-ui-doc-max-height char-h) (/ char-h 2)) height))
+ (width (min width (* lsp-ui-doc-max-width char-w)))
+ (frame-right (pcase lsp-ui-doc-alignment
+ ('frame (frame-pixel-width))
+ ('window right)))
+ ((left . top) (if (eq lsp-ui-doc-position 'at-point)
+ (lsp-ui-doc--mv-at-point width height left top)
+ (cons (max (- frame-right width char-w) 10)
+ (pcase lsp-ui-doc-position
+ ('top (+ top char-w))
+ ('bottom (- (lsp-ui-doc--line-height 'mode-line)
+ height
+ 10))))))
+ (frame-resize-pixelwise t)
+ (move-frame-functions nil)
+ (window-size-change-functions nil)
+ (window-state-change-hook nil)
+ (window-state-change-functions nil)
+ (window-configuration-change-hook nil)
+ (inhibit-redisplay t))
+ ;; Dirty way to fix unused variable in emacs 26
+ (and window-state-change-functions
+ window-state-change-hook)
+ ;; Make frame invisible before moving/resizing it to avoid flickering:
+ ;; We set the position and size in 1 call, modify-frame-parameters, but
+ ;; internally emacs makes 2 different calls, which can be visible
+ ;; to the user
+ (and (frame-visible-p frame)
+ (lsp-ui-doc--size-and-pos-changed frame left top width height)
+ (make-frame-invisible frame))
+ (modify-frame-parameters
+ frame
+ `((width . (text-pixels . ,width))
+ (height . (text-pixels . ,height))
+ (user-size . t)
+ (left . (+ ,left))
+ (top . (+ ,top))
+ (user-position . t)
+ (lsp-ui-doc--window-origin . ,(selected-window))
+ (lsp-ui-doc--buffer-origin . ,(current-buffer))
+ (lsp-ui-doc--no-focus . t)
+ (right-fringe . 0)
+ (left-fringe . 0)))
+ ;; Insert hr lines after width is computed
+ (lsp-ui-doc--fix-hr-props)
+ (unless (frame-visible-p frame)
+ (make-frame-visible frame))))
+
+(defun lsp-ui-doc--visit-file (filename)
+ "Visit FILENAME in the parent frame."
+ (-some->> (find-file-noselect filename)
+ (set-window-buffer (lsp-ui-doc--get-parent :window))))
+
+(defun lsp-ui-doc--put-click (start end fn)
+ "Add text properties on text to make it clickable.
+The text delimiters bound from START to END.
+FN is the function to call on click."
+ (let ((map (make-sparse-keymap)))
+ (define-key map [down-mouse-1] fn)
+ (put-text-property start end 'keymap map)
+ (put-text-property start end 'mouse-face
+ (list :inherit 'lsp-ui-doc-url
+ :box (list :line-width -1
+ :color (face-foreground 'lsp-ui-doc-url))))
+ (add-face-text-property start end 'lsp-ui-doc-url)))
+
+(defun lsp-ui-doc--open-markdown-link (&rest _)
+ (interactive "P")
+ (let ((buffer-list-update-hook nil))
+ (-let [(buffer point) (if-let* ((valid (and (listp last-input-event)
+ (eq (car last-input-event) 'mouse-2)))
+ (event (cadr last-input-event))
+ (win (posn-window event))
+ (buffer (window-buffer win)))
+ `(,buffer ,(posn-point event))
+ `(,(current-buffer) ,(point)))]
+ (with-current-buffer buffer
+ ;; Markdown-mode puts the url in 'help-echo
+ (-some--> (get-text-property point 'help-echo)
+ (and (string-match-p goto-address-url-regexp it)
+ (browse-url it)))))))
+
+(defun lsp-ui-doc--make-clickable-link ()
+ "Find paths and urls in the buffer and make them clickable."
+ (goto-char (point-min))
+ (save-excursion
+ (goto-char (point-min))
+ (let (case-fold-search)
+ (while (re-search-forward goto-address-url-regexp nil t)
+ (goto-char (1+ (match-end 0)))
+ (lsp-ui-doc--put-click (match-beginning 0) (match-end 0)
+ 'browse-url-at-mouse)))))
+
+(defun lsp-ui-doc--buffer-pre-command (&rest _)
+ (and (not (eq this-command 'mwheel-scroll))
+ (frame-parameter nil 'lsp-ui-doc--no-focus)
+ (select-frame (frame-parent) t)))
+
+(defun lsp-ui-doc--fill-document ()
+ "Better wrap the document so it fits the doc window."
+ (let ((fill-column (lsp-ui-doc--scale-column-width (- lsp-ui-doc-max-width 5)))
+ start ; record start for `fill-region'
+ first-line) ; first line in paragraph
+ (save-excursion
+ (goto-char (point-min))
+ (setq start (point)
+ first-line (thing-at-point 'line))
+ (while (re-search-forward "^[ \t]*\n" nil t)
+ (setq first-line (thing-at-point 'line))
+ (when (< fill-column (length first-line))
+ (fill-region start (point)))
+ (setq start (point)))
+ ;; Fill the last paragraph
+ (when (< fill-column (length first-line))
+ (fill-region start (point-max))))))
+
+(defun lsp-ui-doc--make-smaller-empty-lines nil
+ "Make empty lines half normal lines."
+ (progn ; Customize line before header
+ (goto-char 1)
+ (insert (propertize "\n" 'face '(:height 0.3))))
+ (progn ; Customize line after header
+ (forward-line 1)
+ (insert (propertize " " 'face '(:height 0.1))))
+ (while (not (eobp))
+ (when (and (eolp) (not (bobp)))
+ (save-excursion
+ (delete-region (point) (progn (forward-visible-line 1) (point))))
+ (when (or (and (not (get-text-property (point) 'markdown-heading))
+ (not (get-text-property (max (- (point) 2) 1) 'markdown-heading)))
+ (get-text-property (point) 'markdown-hr))
+ (insert (propertize " " 'face `(:height 0.2))
+ (propertize "\n" 'face '(:height 0.4)))))
+ (forward-line))
+ (insert (propertize "\n\n" 'face '(:height 0.3))))
+
+(defun lsp-ui-doc--fix-hr-props nil
+ ;; We insert the right display prop after window-text-pixel-size
+ (lsp-ui-doc--with-buffer
+ (let (next)
+ (while (setq next (next-single-property-change (or next 1) 'lsp-ui-doc--replace-hr))
+ (when (get-text-property next 'lsp-ui-doc--replace-hr)
+ (put-text-property next (1+ next) 'display
+ '(space :align-to (- right-fringe 1) :height (1)))
+ (put-text-property (1+ next) (+ next 2) 'display
+ '(space :align-to right-fringe :height (1))))))))
+
+(defun lsp-ui-doc--handle-hr-lines nil
+ (let (bolp next before after)
+ (goto-char 1)
+ (while (setq next (next-single-property-change (or next 1) 'markdown-hr))
+ (when (get-text-property next 'markdown-hr)
+ (goto-char next)
+ (setq bolp (bolp)
+ before (char-before))
+ (delete-region (point) (save-excursion (forward-visible-line 1) (point)))
+ (setq after (char-after (1+ (point))))
+ (insert
+ (concat
+ (and bolp (not (equal before ?\n)) (propertize "\n" 'face '(:height 0.5)))
+ (propertize " "
+ ;; :align-to is added with lsp-ui-doc--fix-hr-props
+ 'display '(space :height (1))
+ 'lsp-ui-doc--replace-hr t
+ 'face '(:background "dark grey"))
+ ;; :align-to is added here too
+ (propertize " " 'display '(space :height (1)))
+ (and (not (equal after ?\n)) (propertize " \n" 'face '(:height 0.2)))))))))
+
+(defun lsp-ui-doc--render-buffer (string symbol)
+ "Set the buffer with STRING and SYMBOL."
+ (lsp-ui-doc--with-buffer
+ (if lsp-ui-doc-use-webkit
+ (progn
+ (lsp-ui-doc--webkit-execute-script
+ (format "renderMarkdown('%s', '%s');"
+ symbol
+ (url-hexify-string string))
+ 'lsp-ui-doc--webkit-resize-callback))
+ (erase-buffer)
+ (insert (s-trim string))
+ (unless (or (lsp-ui-doc--inline-p) (not lsp-ui-doc-enhanced-markdown))
+ (lsp-ui-doc--fill-document)
+ (lsp-ui-doc--make-smaller-empty-lines)
+ (lsp-ui-doc--handle-hr-lines))
+ (add-text-properties 1 (point) '(line-height 1))
+ (lsp-ui-doc--make-clickable-link)
+ (add-text-properties 1 (point-max) '(pointer arrow)))
+ (lsp-ui-doc-frame-mode 1)
+ (setq wrap-prefix '(space :height (1) :width 1)
+ line-prefix '(space :height (1) :width 1))
+ (setq-local face-remapping-alist `((header-line lsp-ui-doc-header)))
+ (setq-local window-min-height 1)
+ (setq-local show-trailing-whitespace nil)
+ (setq-local window-configuration-change-hook nil)
+ (add-hook 'pre-command-hook 'lsp-ui-doc--buffer-pre-command nil t)
+ (when (boundp 'window-state-change-functions)
+ (setq-local window-state-change-functions nil))
+ (when (boundp 'window-state-change-hook)
+ (setq-local window-state-change-hook nil))
+ (setq-local window-size-change-functions nil)
+ (setq header-line-format (when lsp-ui-doc-header (concat " " symbol))
+ mode-line-format nil
+ cursor-type nil)))
+
+(defun lsp-ui-doc--inline-height ()
+ (lsp-ui-doc--with-buffer
+ (length (split-string (buffer-string) "\n"))))
+
+(defun lsp-ui-doc--remove-invisibles (string)
+ "Remove invisible characters in STRING."
+ (let* ((start (text-property-not-all 0 (length string) 'invisible nil string)))
+ (while start
+ (setq string (concat (substring string 0 start)
+ (-some->> (next-single-property-change start 'invisible string)
+ (substring string))))
+ (setq start (text-property-not-all 0 (length string) 'invisible nil string)))
+ string))
+
+(defvar-local lsp-ui-doc--inline-width nil)
+
+(defun lsp-ui-doc--inline-window-width nil
+ (- (min (window-text-width) (window-body-width))
+ (if (bound-and-true-p display-line-numbers-mode)
+ (+ 2 (line-number-display-width))
+ 0)
+ 1))
+
+(defun lsp-ui-doc--inline-zip (s1 s2)
+ (let* ((width (lsp-ui-doc--inline-window-width))
+ (max-s1 (- width lsp-ui-doc--inline-width 2)))
+ (truncate-string-to-width
+ (concat (truncate-string-to-width s1 max-s1 nil ?\s) s2)
+ width nil ?\s)))
+
+(defun lsp-ui-doc--inline-padding (string len)
+ (let ((string (concat " " string (make-string (- len (string-width string)) ?\s) " ")))
+ (add-face-text-property 0 (length string) (list :background (face-background 'lsp-ui-doc-background nil t)) t string)
+ string))
+
+(defun lsp-ui-doc--inline-faking-frame (doc-strings)
+ (let* ((len-max (-max-by '> (-map 'string-width doc-strings))))
+ (setq lsp-ui-doc--inline-width len-max)
+ (--map (lsp-ui-doc--inline-padding it len-max) doc-strings)))
+
+(defun lsp-ui-doc--inline-untab (string)
+ (replace-regexp-in-string "\t" (make-string tab-width ?\s) string nil t))
+
+(defun lsp-ui-doc--inline-merge (strings)
+ (let* ((buffer-strings (-> (lsp-ui-doc--inline-untab strings)
+ (lsp-ui-doc--remove-invisibles)
+ (split-string "\n")))
+ (doc-strings (-> (lsp-ui-doc--with-buffer (buffer-string))
+ (lsp-ui-doc--inline-untab)
+ (lsp-ui-doc--remove-invisibles)
+ (split-string "\n")))
+ (merged (--> (lsp-ui-doc--inline-faking-frame doc-strings)
+ (-zip-with 'lsp-ui-doc--inline-zip buffer-strings it)
+ (string-join it "\n")
+ (concat it "\n"))))
+ merged))
+
+(defun lsp-ui-doc--inline-pos-at (start lines)
+ "Calcul the position at START + forward n LINES."
+ (save-excursion (goto-char start) (forward-line lines) (point)))
+
+(defun lsp-ui-doc--inline-pos (height)
+ "Return a cons of positions where to place the doc.
+HEIGHT is the documentation number of lines."
+ (let* ((w-start (window-start))
+ (w-end (lsp-ui-doc--inline-pos-at w-start (window-body-height)))
+ (ov-end (lsp-ui-doc--inline-pos-at w-start height)))
+ (cond
+ ;; Display on top ?
+ ((< (lsp-ui-doc--inline-pos-at ov-end 1) (point))
+ (cons w-start ov-end))
+ ;; Display at the bottom ?
+ ((>= (lsp-ui-doc--inline-pos-at w-end (- height))
+ (lsp-ui-doc--inline-pos-at (point) 2))
+ (cons (lsp-ui-doc--inline-pos-at w-end (- height))
+ w-end))
+ ;; The doc is too long to display it fixed to the bottom ?
+ ;; Then display 2 lines after `point'
+ ;; The end of the documentation won't be visible in the window
+ (t (cons (lsp-ui-doc--inline-pos-at (point) 2)
+ (lsp-ui-doc--inline-pos-at (point) (+ height 2)))))))
+
+(defun lsp-ui-doc--inline ()
+ "Display the doc in the buffer."
+ (-let* ((height (lsp-ui-doc--inline-height))
+ ((start . end) (lsp-ui-doc--inline-pos height))
+ (buffer-string (buffer-substring start end))
+ (ov (if (overlayp lsp-ui-doc--inline-ov) lsp-ui-doc--inline-ov
+ (setq lsp-ui-doc--inline-ov (make-overlay start end)))))
+ (move-overlay ov start end)
+ (overlay-put ov 'face 'default)
+ (overlay-put ov 'display (lsp-ui-doc--inline-merge buffer-string))
+ (overlay-put ov 'lsp-ui-doc-inline t)
+ (overlay-put ov 'window (selected-window))))
+
+(defun lsp-ui-doc--inline-p ()
+ "Return non-nil when the documentation should be display without a child frame."
+ (or (not lsp-ui-doc-use-childframe)
+ (not (display-graphic-p))
+ (not (fboundp 'display-buffer-in-child-frame))))
+
+(defun lsp-ui-doc--highlight-hover nil
+ (when lsp-ui-doc--from-mouse-current
+ (-let* (((start . end) lsp-ui-doc--bounds)
+ (ov (if (overlayp lsp-ui-doc--highlight-ov) lsp-ui-doc--highlight-ov
+ (setq lsp-ui-doc--highlight-ov (make-overlay start end)))))
+ (move-overlay ov start end)
+ (overlay-put ov 'face 'lsp-ui-doc-highlight-hover)
+ (overlay-put ov 'window (selected-window)))))
+
+(defun lsp-ui-doc--display (symbol string)
+ "Display the documentation."
+ (when (and lsp-ui-doc-use-webkit (not (featurep 'xwidget-internal)))
+ (setq lsp-ui-doc-use-webkit nil))
+ (if (or (null string) (string-empty-p string))
+ (lsp-ui-doc--hide-frame)
+ (lsp-ui-doc--highlight-hover)
+ (lsp-ui-doc--render-buffer string symbol)
+ (if (lsp-ui-doc--inline-p)
+ (lsp-ui-doc--inline)
+ (unless (lsp-ui-doc--get-frame)
+ (lsp-ui-doc--set-frame (lsp-ui-doc--make-frame)))
+ (unless lsp-ui-doc-use-webkit
+ (lsp-ui-doc--resize-buffer)
+ (lsp-ui-doc--move-frame (lsp-ui-doc--get-frame))))
+ (setq lsp-ui-doc--from-mouse lsp-ui-doc--from-mouse-current)))
+
+(defun lsp-ui-doc--make-frame ()
+ "Create the child frame and return it."
+ (lsp-ui-doc--delete-frame)
+ (let* ((after-make-frame-functions nil)
+ (before-make-frame-hook nil)
+ (name-buffer (lsp-ui-doc--make-buffer-name))
+ (buffer (get-buffer name-buffer))
+ (params (append lsp-ui-doc-frame-parameters
+ `((name . "")
+ (default-minibuffer-frame . ,(selected-frame))
+ (minibuffer . ,(minibuffer-window))
+ (left-fringe . 0)
+ (right-fringe . 0)
+ (cursor-type . nil)
+ (lsp-ui-doc--no-focus . t)
+ (background-color . ,(face-background 'lsp-ui-doc-background nil t)))))
+ (window (display-buffer-in-child-frame
+ buffer
+ `((child-frame-parameters . ,params))))
+ (frame (window-frame window)))
+ (with-current-buffer buffer
+ (lsp-ui-doc-frame-mode 1))
+ (set-frame-parameter nil 'lsp-ui-doc-buffer buffer)
+ (set-window-dedicated-p window t)
+ ;;(redirect-frame-focus frame (frame-parent frame))
+ (set-face-background 'internal-border lsp-ui-doc-border frame)
+ (when (facep 'child-frame-border)
+ (set-face-background 'child-frame-border lsp-ui-doc-border frame))
+ (set-face-background 'fringe nil frame)
+ (run-hook-with-args 'lsp-ui-doc-frame-hook frame window)
+ (when lsp-ui-doc-use-webkit
+ (define-key (current-global-map) [xwidget-event]
+ (lambda ()
+ (interactive)
+ (let ((xwidget-event-type (nth 1 last-input-event)))
+ ;; (when (eq xwidget-event-type 'load-changed)
+ ;; (lsp-ui-doc--move-frame (lsp-ui-doc--get-frame)))
+ (when (eq xwidget-event-type 'javascript-callback)
+ (let ((proc (nth 3 last-input-event))
+ (arg (nth 4 last-input-event)))
+ (funcall proc arg))))))
+ (lsp-ui-doc--webkit-run-xwidget))
+ frame))
+
+(defconst lsp-ui-doc--ignore-commands
+ '(lsp-ui-doc-hide
+ lsp-ui-doc--handle-mouse-movement
+ keyboard-quit
+ ignore
+ handle-switch-frame
+ mwheel-scroll))
+
+(defun lsp-ui-doc--make-request nil
+ "Request the documentation to the LS."
+ (and (not track-mouse) lsp-ui-doc-show-with-mouse (setq-local track-mouse t))
+ (when (and lsp-ui-doc-show-with-cursor
+ (not (memq this-command lsp-ui-doc--ignore-commands))
+ (not (bound-and-true-p lsp-ui-peek-mode))
+ (lsp--capability "hoverProvider"))
+ (-if-let (bounds (or (and (symbol-at-point) (bounds-of-thing-at-point 'symbol))
+ (and (looking-at "[[:graph:]]") (cons (point) (1+ (point))))))
+ (unless (equal lsp-ui-doc--bounds bounds)
+ (lsp-ui-doc--hide-frame)
+ (lsp-ui-util-safe-kill-timer lsp-ui-doc--timer)
+ (setq lsp-ui-doc--timer
+ (run-with-idle-timer
+ lsp-ui-doc-delay nil
+ (let ((buf (current-buffer)))
+ (lambda nil
+ (when (equal buf (current-buffer))
+ (lsp-request-async
+ "textDocument/hover"
+ (lsp--text-document-position-params)
+ (lambda (hover)
+ (when (equal buf (current-buffer))
+ (lsp-ui-doc--callback hover bounds (current-buffer))))
+ :mode 'tick
+ :cancel-token :lsp-ui-doc-hover)))))))
+ (lsp-ui-doc--hide-frame))))
+
+(defun lsp-ui-doc--extract-bounds (hover)
+ (-when-let* ((hover hover)
+ (data (lsp-get hover :range))
+ (start (-some-> (lsp:range-start data) lsp--position-to-point))
+ (end (-some-> (lsp:range-end data) lsp--position-to-point)))
+ (cons start end)))
+
+(lsp-defun lsp-ui-doc--callback ((hover &as &Hover? :contents) bounds buffer)
+ "Process the received documentation.
+HOVER is the doc returned by the LS.
+BOUNDS are points of the symbol that have been requested.
+BUFFER is the buffer where the request has been made."
+ (let ((bounds (or (lsp-ui-doc--extract-bounds hover) bounds)))
+ (if (and hover
+ (>= (point) (car bounds))
+ (<= (point) (cdr bounds))
+ (eq buffer (current-buffer)))
+ (progn
+ (setq lsp-ui-doc--bounds bounds)
+ (lsp-ui-doc--display
+ (thing-at-point 'symbol t)
+ (-some->> contents
+ lsp-ui-doc--extract
+ (replace-regexp-in-string "\r" "")
+ (replace-regexp-in-string " " " "))))
+ (lsp-ui-doc--hide-frame))))
+
+(defun lsp-ui-doc--delete-frame ()
+ "Delete the child frame if it exists."
+ (-when-let (frame (lsp-ui-doc--get-frame))
+ (delete-frame frame)
+ (lsp-ui-doc--set-frame nil)))
+
+(defun lsp-ui-doc--visible-p ()
+ "Return whether the LSP UI doc is visible"
+ (or (overlayp lsp-ui-doc--inline-ov)
+ (and (lsp-ui-doc--get-frame)
+ (frame-visible-p (lsp-ui-doc--get-frame)))))
+
+(defun lsp-ui-doc-hide-frame-on-window-change (fun window &optional no-record)
+ "Delete the child frame if currently selected window changes.
+Does nothing if the newly-selected window is the same window as
+before, or if the new window is the minibuffer."
+ (let ((initial-window (selected-window)))
+ (prog1 (funcall fun window no-record)
+ (unless no-record
+ (when (lsp-ui-doc--visible-p)
+ (let* ((current-window (selected-window))
+ (doc-buffer (get-buffer (lsp-ui-doc--make-buffer-name))))
+ (unless (or (window-minibuffer-p current-window)
+ (equal current-window initial-window)
+ (and doc-buffer
+ (equal (window-buffer initial-window) doc-buffer)))
+ (lsp-ui-doc--hide-frame))))))))
+
+(unless (boundp 'window-state-change-functions)
+ (advice-add #'select-window :around #'lsp-ui-doc-hide-frame-on-window-change)
+ (add-hook 'window-configuration-change-hook #'lsp-ui-doc--hide-frame))
+
+(defvar-local lsp-ui-doc--timer-on-changes nil)
+
+(defun lsp-ui-doc--on-state-changed (_frame &optional on-idle)
+ (-when-let* ((frame (lsp-ui-doc--get-frame)))
+ (and (frame-live-p frame)
+ (frame-visible-p frame)
+ (not (minibufferp (window-buffer)))
+ (or (not (eq (selected-window) (frame-parameter frame 'lsp-ui-doc--window-origin)))
+ (not (eq (window-buffer) (frame-parameter frame 'lsp-ui-doc--buffer-origin))))
+ (if on-idle (lsp-ui-doc--hide-frame)
+ (and (timerp lsp-ui-doc--timer-on-changes)
+ (cancel-timer lsp-ui-doc--timer-on-changes))
+ (setq lsp-ui-doc--timer-on-changes
+ (run-with-idle-timer 0 nil (lambda nil (lsp-ui-doc--on-state-changed frame t))))))))
+
+(advice-add 'load-theme :before (lambda (&rest _) (lsp-ui-doc--delete-frame)))
+
+(advice-add #'keyboard-quit :before #'lsp-ui-doc--hide-frame)
+
+(defun lsp-ui-doc--on-delete (frame)
+ "Function called when a FRAME is deleted."
+ (-some--> (frame-parameter frame 'lsp-ui-doc-buffer)
+ (get-buffer it)
+ (and (buffer-live-p it) it)
+ (kill-buffer it)))
+
+(defun lsp-ui-doc--handle-scroll (win _new-start)
+ "Handle scrolling to the document frame.
+
+This function is apply to hook `window-scroll-functions'.
+
+Argument WIN is current applying window."
+ (let ((frame (lsp-ui-doc--get-frame)))
+ (if (minibufferp (window-buffer))
+ (lsp-ui-doc--hide-frame)
+ (when (and frame
+ (eq lsp-ui-doc-position 'at-point)
+ (frame-visible-p frame)
+ (eq win (selected-window))) ; This resolved #524
+ (if (and lsp-ui-doc--bounds
+ (eq (window-buffer) (frame-parameter frame 'lsp-ui-doc--buffer-origin))
+ (>= (point) (car lsp-ui-doc--bounds))
+ (<= (point) (cdr lsp-ui-doc--bounds)))
+ (lsp-ui-doc--move-frame frame)
+ ;; The point might have changed if the window was scrolled
+ ;; too far
+ (lsp-ui-doc--hide-frame))))))
+
+(defvar-local lsp-ui-doc--timer-mouse-movement nil)
+(defvar-local lsp-ui-doc--last-event nil)
+
+(defun lsp-ui-doc--mouse-display nil
+ (when (and lsp-ui-doc--last-event
+ (lsp-feature? "textDocument/hover"))
+ (save-excursion
+ (goto-char lsp-ui-doc--last-event)
+ (-when-let* ((valid (not (eolp)))
+ (bounds (or (and (symbol-at-point) (bounds-of-thing-at-point 'symbol))
+ (and (looking-at "[[:graph:]]") (cons (point) (1+ (point)))))))
+ (unless (equal bounds lsp-ui-doc--bounds)
+ (lsp-request-async
+ "textDocument/hover"
+ (lsp--text-document-position-params)
+ (lambda (hover)
+ (save-excursion
+ (goto-char lsp-ui-doc--last-event)
+ (let ((lsp-ui-doc-position 'at-point)
+ (lsp-ui-doc--from-mouse-current t))
+ (lsp-ui-doc--callback hover bounds (current-buffer)))))
+ :mode 'tick
+ :cancel-token :lsp-ui-doc-hover))))))
+
+(defun lsp-ui-doc--handle-mouse-movement (event)
+ "Show the documentation corresponding to the text under EVENT."
+ (interactive "e")
+ (when lsp-ui-doc-show-with-mouse
+ (and (timerp lsp-ui-doc--timer-mouse-movement)
+ (cancel-timer lsp-ui-doc--timer-mouse-movement))
+ (let* ((e (cadr event))
+ (point (posn-point e))
+ (same-win (eq (selected-window) (posn-window e))))
+ (and lsp-ui-doc--from-mouse
+ lsp-ui-doc--bounds
+ point
+ (or (< point (car lsp-ui-doc--bounds))
+ (> point (cdr lsp-ui-doc--bounds))
+ (not same-win)
+ (equal (char-after point) ?\n))
+ (lsp-ui-doc--hide-frame))
+ (when same-win
+ (setq lsp-ui-doc--last-event point
+ lsp-ui-doc--timer-mouse-movement
+ (run-with-idle-timer lsp-ui-doc-delay nil 'lsp-ui-doc--mouse-display))))))
+
+(defun lsp-ui-doc--disable-mouse-on-prefix nil
+ (and (bound-and-true-p lsp-ui-doc-mode)
+ (bound-and-true-p lsp-ui-doc--mouse-tracked-by-us)
+ track-mouse
+ (> (length (this-single-command-keys)) 0)
+ (setq-local track-mouse nil)))
+
+(defvar lsp-ui-doc--timer-mouse-idle nil)
+
+(defvar-local lsp-ui-doc--mouse-tracked-by-us nil
+ "Nil if `track-mouse' was set by another package.
+If nil, do not prevent mouse on prefix keys.")
+
+(defun lsp-ui-doc--setup-mouse nil
+ (when lsp-ui-doc-show-with-mouse
+ (setq lsp-ui-doc--mouse-tracked-by-us (not track-mouse))
+ (setq-local track-mouse t)
+ (unless lsp-ui-doc--timer-mouse-idle
+ ;; Set only 1 timer for all buffers
+ (setq lsp-ui-doc--timer-mouse-idle
+ (run-with-idle-timer 0 t 'lsp-ui-doc--disable-mouse-on-prefix)))))
+
+(defun lsp-ui-doc--prevent-focus-doc (e)
+ (not (frame-parameter (cadr e) 'lsp-ui-doc--no-focus)))
+
+(define-minor-mode lsp-ui-doc-mode
+ "Minor mode for showing hover information in child frame."
+ :init-value nil
+ :keymap `((,(kbd "<mouse-movement>") . lsp-ui-doc--handle-mouse-movement))
+ :group lsp-ui-doc
+ (cond
+ (lsp-ui-doc-mode
+ (with-eval-after-load 'frameset
+ ;; The documentation frame can’t be properly restored. Especially
+ ;; ‘desktop-save’ will misbehave and save a bogus string "Unprintable
+ ;; entity" in the desktop file. Therefore we have to prevent
+ ;; ‘frameset-save’ from saving the parameter.
+ (unless (assq 'lsp-ui-doc-frame frameset-filter-alist)
+ ;; Copy the variable first. See the documentation of
+ ;; ‘frameset-filter-alist’ for explanation.
+ (cl-callf copy-tree frameset-filter-alist)
+ (push '(lsp-ui-doc-frame . :never) frameset-filter-alist)))
+ (when (boundp 'window-state-change-functions)
+ (add-hook 'window-state-change-functions 'lsp-ui-doc--on-state-changed))
+ (lsp-ui-doc--setup-mouse)
+ (advice-add 'handle-switch-frame :before-while 'lsp-ui-doc--prevent-focus-doc)
+ (add-hook 'post-command-hook 'lsp-ui-doc--make-request nil t)
+ (add-hook 'window-scroll-functions 'lsp-ui-doc--handle-scroll nil t)
+ (add-hook 'delete-frame-functions 'lsp-ui-doc--on-delete nil t))
+ (t
+ (lsp-ui-doc-hide)
+ (when (boundp 'window-state-change-functions)
+ (remove-hook 'window-state-change-functions 'lsp-ui-doc--on-state-changed))
+ (remove-hook 'window-scroll-functions 'lsp-ui-doc--handle-scroll t)
+ (remove-hook 'post-command-hook 'lsp-ui-doc--make-request t)
+ (remove-hook 'delete-frame-functions 'lsp-ui-doc--on-delete t))))
+
+(defun lsp-ui-doc-enable (enable)
+ "Enable/disable ‘lsp-ui-doc-mode’.
+It is supposed to be called from `lsp-ui--toggle'"
+ (lsp-ui-doc-mode (if enable 1 -1)))
+
+(defun lsp-ui-doc-show ()
+ "Trigger display hover information popup."
+ (interactive)
+ (lsp-ui-doc--callback (lsp-request "textDocument/hover" (lsp--text-document-position-params))
+ (or (bounds-of-thing-at-point 'symbol) (cons (point) (1+ (point))))
+ (current-buffer)))
+
+(defun lsp-ui-doc-hide ()
+ "Hide hover information popup."
+ (interactive)
+ (lsp-ui-doc--hide-frame))
+
+(defvar-local lsp-ui-doc--unfocus-frame-timer nil)
+(defun lsp-ui-doc--glance-hide-frame ()
+ "Hook to hide hover information popup for `lsp-ui-doc-glance'."
+ (when (or (overlayp lsp-ui-doc--inline-ov)
+ (lsp-ui-doc--frame-visible-p))
+ (lsp-ui-doc--hide-frame)
+ (remove-hook 'post-command-hook 'lsp-ui-doc--glance-hide-frame)
+ ;; make sure child frame is unfocused
+ (setq lsp-ui-doc--unfocus-frame-timer
+ (run-at-time 1 nil #'lsp-ui-doc-unfocus-frame))))
+
+(defun lsp-ui-doc-glance ()
+ "Trigger display hover information popup and hide it on next typing."
+ (interactive)
+ (let ((lsp-ui-doc-show-with-cursor t))
+ (lsp-ui-doc--make-request))
+ (when lsp-ui-doc--unfocus-frame-timer
+ (cancel-timer lsp-ui-doc--unfocus-frame-timer))
+ (add-hook 'post-command-hook 'lsp-ui-doc--glance-hide-frame))
+
+(define-minor-mode lsp-ui-doc-frame-mode
+ "Marker mode to add additional key bind for lsp-ui-doc-frame."
+ :init-value nil
+ :lighter ""
+ :group lsp-ui-doc
+ :keymap `(([?q] . lsp-ui-doc-unfocus-frame)
+ ([remap markdown-follow-thing-at-point] . lsp-ui-doc--open-markdown-link)
+ ([remap mouse-drag-region] . ignore)))
+
+(defun lsp-ui-doc-focus-frame ()
+ "Focus into lsp-ui-doc-frame."
+ (interactive)
+ (when-let* ((frame (lsp-ui-doc--get-frame))
+ (visible (lsp-ui-doc--frame-visible-p)))
+ (set-frame-parameter frame 'lsp-ui-doc--no-focus nil)
+ (set-frame-parameter frame 'cursor-type t)
+ (lsp-ui-doc--with-buffer
+ (setq cursor-type 'box))
+ (select-frame-set-input-focus frame)))
+
+(defun lsp-ui-doc-unfocus-frame ()
+ "Unfocus from lsp-ui-doc-frame."
+ (interactive)
+ (-some-> (frame-parent) select-frame-set-input-focus)
+ (when-let* ((frame (lsp-ui-doc--get-frame)))
+ (set-frame-parameter frame 'lsp-ui-doc--no-focus t)
+ (set-frame-parameter frame 'cursor-type nil)
+ (lsp-ui-doc--with-buffer
+ (setq cursor-type nil))
+ (when lsp-ui-doc--from-mouse
+ (make-frame-invisible frame))))
+
+(provide 'lsp-ui-doc)
+;;; lsp-ui-doc.el ends here
diff --git a/elpa/lsp-ui-20220425.1046/lsp-ui-doc.elc b/elpa/lsp-ui-20220425.1046/lsp-ui-doc.elc
new file mode 100644
index 0000000..48c4856
--- /dev/null
+++ b/elpa/lsp-ui-20220425.1046/lsp-ui-doc.elc
Binary files differ
diff --git a/elpa/lsp-ui-20220425.1046/lsp-ui-doc.html b/elpa/lsp-ui-20220425.1046/lsp-ui-doc.html
new file mode 100644
index 0000000..4c39adf
--- /dev/null
+++ b/elpa/lsp-ui-20220425.1046/lsp-ui-doc.html
@@ -0,0 +1,52 @@
+<html>
+ <head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/showdown/1.9.0/showdown.min.js"></script>
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.13.1/highlight.min.js"></script>
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/github-markdown-css/2.10.0/github-markdown.css">
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.13.1/styles/default.min.css">
+ <style>
+
+ :root {
+ --webkit-max-width-px: 600px;
+ }
+
+ .markdown-body {
+ box-sizing: border-box;
+ min-width: var(--webkit-max-width-px);
+ max-width: var(--webkit-max-width-px);
+ margin: 0 auto;
+ padding: 10px;
+ }
+
+ .markdown-body pre code {
+ white-space: pre-wrap;
+ }
+ </style>
+ </head>
+ <body>
+ <div id="lsp-ui-webkit" class="markdown-body">
+ </div>
+ <script>
+ var converter = new showdown.Converter({simpleLineBreaks: true});
+ var lastSymbol = "";
+ var elem = document.getElementById('lsp-ui-webkit');
+
+ function renderMarkdown(symbol, markedString) {
+ if (symbol == lastSymbol) return [elem.offsetWidth, elem.offsetHeight];
+ decodedString = decodeURIComponent(markedString);
+ html = converter.makeHtml(decodedString);
+ elem.innerHTML = html;
+ lastSymbol = symbol;
+
+ document.querySelectorAll('pre code').forEach(function(codeBlock) {
+ hljs.highlightBlock(codeBlock);
+ });
+
+ return [elem.offsetWidth, elem.offsetHeight];
+ }
+
+ </script>
+ </body>
+</html>
diff --git a/elpa/lsp-ui-20220425.1046/lsp-ui-flycheck.el b/elpa/lsp-ui-20220425.1046/lsp-ui-flycheck.el
new file mode 100644
index 0000000..e3ac831
--- /dev/null
+++ b/elpa/lsp-ui-20220425.1046/lsp-ui-flycheck.el
@@ -0,0 +1,171 @@
+;;; lsp-ui-flycheck.el --- Flycheck support for lsp-mode -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2017 fmdkdd
+;; URL: https://github.com/emacs-lsp/lsp-ui
+;; Keywords: languagues, tools
+;; Version: 6.2
+
+;; 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:
+
+;; Flycheck integration for lsp-mode.
+
+;;; Code:
+
+(require 'flycheck nil 'noerror) ; Temporary solution, see #514
+(require 'pcase)
+(require 'dash)
+
+(require 'lsp-protocol)
+(require 'lsp-mode)
+
+(defgroup lsp-ui-flycheck nil
+ "The LSP extension to display syntax checking."
+ :group 'tools
+ :group 'convenience
+ :group 'lsp-ui
+ :link '(custom-manual "(lsp-ui-flycheck) Top")
+ :link '(info-link "(lsp-ui-flycheck) Customizing"))
+
+(defcustom lsp-ui-flycheck-list-position 'bottom
+ "Position where `lsp-ui-flycheck-list' will show diagnostics for the
+whole workspace."
+ :type '(choice (const :tag "Bottom" bottom)
+ (const :tag "Right" right))
+ :group 'lsp-ui-flycheck)
+
+(defvar-local lsp-ui-flycheck-list--buffer nil)
+(defvar-local lsp-ui-flycheck--save-mode nil)
+
+(defun lsp-ui-flycheck-list--post-command ()
+ (when (eobp)
+ (forward-line -1)))
+
+(defun lsp-ui-flycheck-list--update (window workspace)
+ "Update flycheck buffer in WINDOW belonging to WORKSPACE.
+Use `lsp-diagnostics' to receive diagnostics from your LSP server."
+ (let ((buffer-read-only nil)
+ (lsp--cur-workspace workspace))
+ (erase-buffer)
+ (remove-overlays)
+ (maphash (lambda (file diagnostic)
+ (when diagnostic
+ (overlay-put
+ (make-overlay (point) (point))
+ 'after-string
+ (concat (propertize "\n" 'face '(:height 0.2))
+ (propertize (lsp-ui--workspace-path file)
+ 'face 'dired-directory)
+ (propertize "\n" 'face '(:height 0.2)))))
+ (dolist (diag diagnostic)
+ (-let* (((&Diagnostic :message :severity? :source?
+ :range (&Range :start (&Position :line start-line))) diag)
+ (formatted-message (or (if source? (format "%s: %s" source? message) message) "???"))
+ (severity (or severity? 1))
+ (line (1+ start-line))
+ (face (cond ((= severity 1) 'error)
+ ((= severity 2) 'warning)
+ (t 'success)))
+ (text (concat (propertize (number-to-string line) 'face face)
+ ": "
+ (car (split-string formatted-message "\n")))))
+ (add-text-properties 0 (length text) `(diag ,diag file ,file window ,window) text)
+ (insert (concat text "\n")))))
+ (lsp-diagnostics)))
+ (if (= (point) 1)
+ (overlay-put (make-overlay 1 1)
+ 'after-string "No diagnostic available\n")
+ (goto-char 1))
+ (lsp-ui-flycheck-list-mode))
+
+(defun lsp-ui-flycheck-list ()
+ "List all the diagnostics in the whole workspace."
+ (interactive)
+ (let ((buffer (get-buffer-create "*lsp-diagnostics*"))
+ (workspace lsp--cur-workspace)
+ (window (selected-window)))
+ (with-current-buffer buffer
+ (lsp-ui-flycheck-list--update window workspace))
+ (add-hook 'lsp-diagnostics-updated-hook 'lsp-ui-flycheck-list--refresh nil t)
+ (setq lsp-ui-flycheck-list--buffer buffer)
+ (let ((win (display-buffer-in-side-window
+ buffer `((side . ,lsp-ui-flycheck-list-position) (slot . 5) (window-width . 0.20)))))
+ (set-window-dedicated-p win t)
+ (select-window win)
+ (fit-window-to-buffer nil nil 10))))
+
+(defun lsp-ui-flycheck-list--refresh ()
+ (let ((workspace lsp--cur-workspace)
+ (current-window (selected-window)))
+ (when (and (buffer-live-p lsp-ui-flycheck-list--buffer)
+ (get-buffer-window lsp-ui-flycheck-list--buffer)
+ workspace)
+ (with-selected-window (get-buffer-window lsp-ui-flycheck-list--buffer)
+ (lsp-ui-flycheck-list--update current-window workspace)
+ (fit-window-to-buffer nil nil 10)))))
+
+(defun lsp-ui-flycheck-list--open ()
+ (-when-let* ((diag (get-text-property (point) 'diag))
+ ((&Diagnostic :range (&Range :start (&Position :line start-line
+ :character start-column))) diag)
+ (file (get-text-property (point) 'file))
+ (window (get-text-property (point) 'window))
+ (marker (with-current-buffer
+ (or (get-file-buffer file)
+ (find-file-noselect file))
+ (save-restriction
+ (widen)
+ (save-excursion
+ (goto-char 1)
+ (forward-line start-line)
+ (forward-char start-column)
+ (point-marker))))))
+ (set-window-buffer window (marker-buffer marker) t)
+ (with-selected-window window
+ (goto-char marker)
+ (recenter)
+ (pulse-momentary-highlight-one-line (marker-position marker) 'next-error))
+ window))
+
+(defun lsp-ui-flycheck-list--view ()
+ (interactive)
+ (lsp-ui-flycheck-list--open))
+
+(defun lsp-ui-flycheck-list--visit ()
+ (interactive)
+ (select-window (lsp-ui-flycheck-list--open)))
+
+(defun lsp-ui-flycheck-list--quit ()
+ (interactive)
+ (kill-buffer))
+
+(defvar lsp-ui-flycheck-list-mode-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map (kbd "q") 'lsp-ui-flycheck-list--quit)
+ (define-key map (kbd "<return>") 'lsp-ui-flycheck-list--view)
+ (define-key map (kbd "<M-return>") 'lsp-ui-flycheck-list--visit)
+ map)
+ "Keymap for ‘lsp-ui-flycheck-list-mode’.")
+
+(define-derived-mode lsp-ui-flycheck-list-mode special-mode "lsp-ui-flycheck-list"
+ "Mode showing flycheck diagnostics for the whole workspace."
+ (setq truncate-lines t)
+ (setq mode-line-format nil)
+ (add-hook 'post-command-hook 'lsp-ui-flycheck-list--post-command nil t))
+
+(declare-function lsp-ui--workspace-path "lsp-ui" (path))
+
+(provide 'lsp-ui-flycheck)
+;;; lsp-ui-flycheck.el ends here
diff --git a/elpa/lsp-ui-20220425.1046/lsp-ui-flycheck.elc b/elpa/lsp-ui-20220425.1046/lsp-ui-flycheck.elc
new file mode 100644
index 0000000..ef5fcf4
--- /dev/null
+++ b/elpa/lsp-ui-20220425.1046/lsp-ui-flycheck.elc
Binary files differ
diff --git a/elpa/lsp-ui-20220425.1046/lsp-ui-imenu.el b/elpa/lsp-ui-20220425.1046/lsp-ui-imenu.el
new file mode 100644
index 0000000..3c628da
--- /dev/null
+++ b/elpa/lsp-ui-20220425.1046/lsp-ui-imenu.el
@@ -0,0 +1,412 @@
+;;; lsp-ui-imenu.el --- Lsp-Ui-Imenu -*- lexical-binding: t -*-
+
+;; Copyright (C) 2018 Sebastien Chapuis
+
+;; Author: Sebastien Chapuis <sebastien@chapu.is>
+;; URL: https://github.com/emacs-lsp/lsp-ui
+;; Keywords: languages, tools
+;; Version: 6.3
+
+;;; License
+;;
+;; 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:
+
+;; Show imenu entries
+;; Call the function `lsp-ui-imenu'
+;;
+;; (define-key lsp-ui-mode-map (kbd "C-c l") 'lsp-ui-imenu)
+
+;;; Code:
+
+(require 'lsp-mode)
+(require 'dash)
+(require 'lsp-ui-util)
+
+(defgroup lsp-ui-imenu nil
+ "Display imenu entries."
+ :group 'tools
+ :group 'convenience
+ :group 'lsp-ui
+ :link '(custom-manual "(lsp-ui-imenu) Top")
+ :link '(info-link "(lsp-ui-imenu) Customizing"))
+
+(defcustom lsp-ui-imenu-enable t
+ "Whether or not to enable ‘lsp-ui-imenu’."
+ :type 'boolean
+ :group 'lsp-ui)
+
+(defcustom lsp-ui-imenu-kind-position 'top
+ "Where to show the entries kind."
+ :type '(choice (const :tag "Top" top)
+ (const :tag "Left" left))
+ :group 'lsp-ui-imenu)
+
+(defcustom lsp-ui-imenu-colors '("deep sky blue" "green3")
+ "Color list to cycle through for entry groups."
+ :type '(repeat color)
+ :group 'lsp-ui-imenu)
+
+(defcustom lsp-ui-imenu-window-width 0
+ "When not 0, don't fit window to buffer and use value as window-width."
+ :type 'number
+ :group 'lsp-ui-imenu)
+
+(defcustom lsp-ui-imenu-auto-refresh nil
+ "Automatically refresh imenu when certain conditions meet."
+ :type '(choice (const :tag "Enable" t)
+ (const :tag "Active only when after save" after-save)
+ (const :tag "Disable" nil))
+ :group 'lsp-ui-imenu)
+
+(defcustom lsp-ui-imenu-auto-refresh-delay 1.0
+ "Delay time to refresh imenu."
+ :type 'float
+ :group 'lsp-ui-imenu)
+
+(defcustom lsp-ui-imenu--custom-mode-line-format nil
+ "Custom mode line format to be used in `lsp-ui-menu-mode'."
+ :type 'sexp
+ :group 'lsp-ui-menu)
+
+(defconst lsp-ui-imenu--max-bars 8)
+
+(declare-function imenu--make-index-alist 'imenu)
+(declare-function imenu--subalist-p 'imenu)
+(defvar imenu--index-alist)
+
+(defvar-local lsp-ui-imenu--refresh-timer nil
+ "Auto refresh timer for imenu.")
+
+(defun lsp-ui-imenu--pad (s len bars depth color-index for-title is-last)
+ (let ((n (- len (length s))))
+ (apply #'concat
+ (make-string n ?\s)
+ (propertize s 'face `(:foreground ,(lsp-ui-imenu--get-color color-index)))
+ (let (bar-strings)
+ (dotimes (i depth)
+ (push
+ (propertize (lsp-ui-imenu--get-bar bars i depth for-title is-last)
+ 'face `(:foreground
+ ,(lsp-ui-imenu--get-color (+ color-index i))))
+ bar-strings))
+ (reverse bar-strings)))))
+
+(defun lsp-ui-imenu--get-bar (bars index depth for-title is-last)
+ (cond
+ ;; Exceeding maximum bars
+ ((>= index lsp-ui-imenu--max-bars) " ")
+ ;; No bar for this level
+ ((not (aref bars index)) " ")
+ ;; For the first level, the title is rendered differently, so leaf items are
+ ;; decorated with the full height bar regardless if it's the last item or
+ ;; not.
+ ((and (= depth 1) (not for-title)) " ┃ ")
+ ;; Full height bar for levels other than the rightmost one.
+ ((< (1+ index) depth) " ┃ ")
+ ;; The rightmost bar for the last item.
+ (is-last " ┗ " )
+ ;; The rightmost bar for the title items other than the last one.
+ (for-title " ┣ ")
+ ;; The rightmost bar for the leaf items other than the last one.
+ (t " ┃ ")))
+
+(defun lsp-ui-imenu--get-color (index)
+ (nth (mod index (length lsp-ui-imenu-colors)) lsp-ui-imenu-colors))
+
+(defun lsp-ui-imenu--make-line (title index entry padding bars depth color-index is-last)
+ (let* ((prefix (if (and (= index 0) (eq lsp-ui-imenu-kind-position 'left)) title " "))
+ (text (concat (lsp-ui-imenu--pad prefix padding bars depth color-index nil is-last)
+ (propertize (car entry) 'face 'default)
+ "\n"))
+ (len (length text)))
+ (add-text-properties 0 len `(index ,index title ,title marker ,(cdr entry)
+ padding ,padding depth, depth)
+ text)
+ text))
+
+(defvar-local lsp-ui-imenu-ov nil
+ "Variable that holds overlay for imenu.")
+
+(defun lsp-ui-imenu--make-ov nil
+ "Make imenu overlay."
+ (or (and (overlayp lsp-ui-imenu-ov) lsp-ui-imenu-ov)
+ (setq lsp-ui-imenu-ov (make-overlay 1 1))))
+
+(defun lsp-ui-imenu--post-command nil
+ "Post command hook for imenu."
+ (when (eobp) (forward-line -1))
+ (lsp-ui-imenu--move-to-name-beginning)
+ (when (eq lsp-ui-imenu-kind-position 'left)
+ (save-excursion
+ (when (overlayp lsp-ui-imenu-ov)
+ (overlay-put lsp-ui-imenu-ov 'display nil))
+ (redisplay)
+ (goto-char (window-start))
+ (if (= (get-text-property (point) 'index) 0)
+ (when (overlayp lsp-ui-imenu-ov) (delete-overlay lsp-ui-imenu-ov))
+ (let* ((ov (lsp-ui-imenu--make-ov))
+ (padding (get-text-property (point) 'padding))
+ (title (get-text-property (point) 'title))
+ (text (buffer-substring (+ (line-beginning-position) padding) (line-end-position))))
+ (move-overlay ov (line-beginning-position) (line-end-position))
+ (overlay-put ov 'display `(string ,(concat (let ((n (- padding (length title))))
+ (propertize (concat (make-string n ?\s) title)))
+ text))))))))
+
+(defun lsp-ui-imenu--move-to-name-beginning ()
+ (-when-let* ((padding (get-char-property (point) 'padding))
+ (depth (get-char-property (point) 'depth)))
+ (goto-char (+ (* depth 3) (line-beginning-position) padding))))
+
+(defvar lsp-ui-imenu--origin nil)
+
+(defun lsp-ui-imenu--put-separator nil
+ (let ((ov (make-overlay (point) (point))))
+ (overlay-put ov 'after-string (propertize "\n" 'face '(:height 0.6)))))
+
+(defun lsp-ui-imenu--put-toplevel-title (title color-index)
+ (if (eq lsp-ui-imenu-kind-position 'top)
+ (let ((ov (make-overlay (point) (point)))
+ (color (lsp-ui-imenu--get-color color-index)))
+ (overlay-put
+ ov 'after-string
+ (concat (propertize "\n" 'face '(:height 0.6))
+ (propertize title 'face `(:foreground ,color))
+ "\n"
+ (propertize "\n" 'face '(:height 0.6)))))
+ ;; Left placement, title is put with the first sub item. Only put a separator here.
+ (lsp-ui-imenu--put-separator)))
+
+(defun lsp-ui-imenu--put-subtitle (title padding bars depth color-index is-last)
+ (let ((ov (make-overlay (point) (point)))
+ (title-color (lsp-ui-imenu--get-color (+ color-index depth))))
+ (overlay-put
+ ov 'after-string
+ (concat (lsp-ui-imenu--pad " " padding bars depth color-index t is-last)
+ (propertize title 'face `(:foreground ,title-color))
+ (propertize "\n" 'face '(:height 1))))))
+
+(defun lsp-ui-imenu--insert-items (title items padding bars depth color-index)
+ "Insert ITEMS for TITLE.
+
+PADDING is the length of whitespaces to the left of the first bar.
+
+BARS is a bool vector of length `lsp-ui-imenu--max-bars'. The ith
+value indicates whether the ith bar from the left is visible.
+
+DEPTH is the depth of the items in the index tree, starting from 0.
+
+COLOR-INDEX is the index of the color of the leftmost bar.
+
+Return the updated COLOR-INDEX."
+ (let ((len (length items)))
+ (--each-indexed items
+ (let ((is-last (= (1+ it-index) len)))
+ (if (imenu--subalist-p it)
+ (-let* (((sub-title . entries) it))
+ (if (= depth 0)
+ (lsp-ui-imenu--put-toplevel-title sub-title color-index)
+ (lsp-ui-imenu--put-subtitle sub-title padding bars depth color-index is-last))
+ (when (and is-last (> depth 0))
+ (aset bars (1- depth) nil))
+ (let ((lsp-ui-imenu-kind-position (if (> depth 0) 'top
+ lsp-ui-imenu-kind-position)))
+ (lsp-ui-imenu--insert-items sub-title
+ entries
+ padding
+ bars
+ (1+ depth)
+ color-index))
+ (when (and is-last (> depth 0))
+ (aset bars (1- depth) t))
+ (when (= depth 0)
+ (setq color-index (1+ color-index))))
+ (insert (lsp-ui-imenu--make-line title it-index it
+ padding bars depth color-index
+ is-last))))))
+ color-index)
+
+(defun lsp-ui-imenu--get-padding (items)
+ "Get imenu padding determined by `lsp-ui-imenu-kind-position'.
+ITEMS are used when the kind position is 'left."
+ (cl-case lsp-ui-imenu-kind-position
+ (top 1)
+ (left (--> (-filter 'imenu--subalist-p items)
+ (--map (length (car it)) it)
+ (-max (or it '(1)))))
+ (t (user-error "Invalid value for imenu's kind position: %s" lsp-ui-imenu-kind-position))))
+
+(defun lsp-ui-imenu--put-bit (bits offset)
+ (logior bits (lsh 1 offset)))
+
+(defun lsp-ui-imenu--clear-bit (bits offset)
+ (logand bits (lognot (lsh 1 offset))))
+
+(defvar lsp-ui-imenu-buffer-name "*lsp-ui-imenu*"
+ "Buffer name for imenu buffers.")
+
+(defun lsp-ui-imenu--refresh-content ()
+ "Refresh imenu content menu"
+ (let ((imenu-auto-rescan t))
+ (setq lsp-ui-imenu--origin (current-buffer))
+ (imenu--make-index-alist)
+ (let ((imenu-buffer (get-buffer-create lsp-ui-imenu-buffer-name))
+ (list imenu--index-alist))
+ (with-current-buffer imenu-buffer
+ (let* ((padding (lsp-ui-imenu--get-padding list))
+ (grouped-by-subs (-partition-by 'imenu--subalist-p list))
+ (color-index 0)
+ (bars (make-bool-vector lsp-ui-imenu--max-bars t))
+ (inhibit-read-only t))
+ (remove-overlays)
+ (erase-buffer)
+ (dolist (group grouped-by-subs)
+ (if (imenu--subalist-p (car group))
+ (setq color-index (lsp-ui-imenu--insert-items "" group padding bars 0 color-index))
+ (lsp-ui-imenu--put-separator)
+ (lsp-ui-imenu--insert-items "" group padding bars 1 color-index)
+ (setq color-index (1+ color-index))))
+ (lsp-ui-imenu-mode)
+ (when lsp-ui-imenu--custom-mode-line-format
+ (setq mode-line-format lsp-ui-imenu--custom-mode-line-format))
+ (goto-char (point-min))
+ (add-hook 'post-command-hook 'lsp-ui-imenu--post-command nil t))))))
+
+(defun lsp-ui-imenu nil
+ "Open ui-imenu in side window."
+ (interactive)
+ (lsp-ui-imenu-buffer-mode 1)
+ (setq lsp-ui-imenu--origin (current-buffer))
+ (imenu--make-index-alist)
+ (let ((imenu-buffer (get-buffer-create lsp-ui-imenu-buffer-name)))
+ (lsp-ui-imenu--refresh-content)
+ (let ((win (display-buffer-in-side-window imenu-buffer '((side . right)))))
+ (set-window-margins win 1)
+ (select-window win)
+ (set-window-start win 1)
+ (lsp-ui-imenu--move-to-name-beginning)
+ (set-window-dedicated-p win t)
+ ;; when `lsp-ui-imenu-window-width' is 0, fit window to buffer
+ (if (= lsp-ui-imenu-window-width 0)
+ (let ((fit-window-to-buffer-horizontally 'only))
+ (fit-window-to-buffer win)
+ (window-resize win 3 t))
+ (let ((x (- lsp-ui-imenu-window-width (window-width))))
+ (window-resize (selected-window) x t))))))
+
+(defun lsp-ui-imenu--kill nil
+ "Kill imenu window."
+ (interactive)
+ (lsp-ui-imenu-buffer-mode -1)
+ (kill-buffer-and-window))
+
+(defun lsp-ui-imenu--jump (direction)
+ (let ((current (get-text-property (point) 'title)))
+ (forward-line direction)
+ (while (and current
+ (not (= (line-number-at-pos) 1))
+ (equal current (get-text-property (point) 'title)))
+ (forward-line direction))))
+
+(defun lsp-ui-imenu--next-kind nil
+ "Jump to next kind of imenu."
+ (interactive)
+ (lsp-ui-imenu--jump 1))
+
+(defun lsp-ui-imenu--prev-kind nil
+ "Jump to previous kind of imenu."
+ (interactive)
+ (lsp-ui-imenu--jump -1)
+ (while (not (= (get-text-property (point) 'index) 0))
+ (forward-line -1)))
+
+(defun lsp-ui-imenu--visit nil
+ (interactive)
+ (let ((marker (get-text-property (point) 'marker)))
+ (select-window (get-buffer-window lsp-ui-imenu--origin))
+ (goto-char marker)
+ (pulse-momentary-highlight-one-line (point) 'next-error)))
+
+(defun lsp-ui-imenu--view nil
+ (interactive)
+ (let ((marker (get-text-property (point) 'marker)))
+ (with-selected-window (get-buffer-window lsp-ui-imenu--origin)
+ (goto-char marker)
+ (recenter)
+ (pulse-momentary-highlight-one-line (point) 'next-error))))
+
+(defvar lsp-ui-imenu-mode-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map (kbd "q") 'lsp-ui-imenu--kill)
+ (define-key map (kbd "r") 'lsp-ui-imenu--refresh)
+ (define-key map (kbd "<right>") 'lsp-ui-imenu--next-kind)
+ (define-key map (kbd "<left>") 'lsp-ui-imenu--prev-kind)
+ (define-key map (kbd "<return>") 'lsp-ui-imenu--view)
+ (define-key map (kbd "<M-return>") 'lsp-ui-imenu--visit)
+ (define-key map (kbd "RET") 'lsp-ui-imenu--view)
+ (define-key map (kbd "M-RET") 'lsp-ui-imenu--visit)
+ map)
+ "Keymap for ‘lsp-ui-peek-mode’.")
+
+(define-derived-mode lsp-ui-imenu-mode special-mode "lsp-ui-imenu"
+ "Mode showing imenu entries.")
+
+(defun lsp-ui-imenu--refresh ()
+ "Safe refresh imenu content."
+ (interactive)
+ (let ((imenu-buffer (get-buffer lsp-ui-imenu-buffer-name)))
+ (when imenu-buffer
+ (save-selected-window
+ (if (equal (current-buffer) imenu-buffer)
+ (select-window (get-buffer-window lsp-ui-imenu--origin))
+ (setq lsp-ui-imenu--origin (current-buffer)))
+ (lsp-ui-imenu--refresh-content)))))
+
+(defun lsp-ui-imenu--start-refresh (&rest _)
+ "Starts the auto refresh timer."
+ (lsp-ui-util-safe-kill-timer lsp-ui-imenu--refresh-timer)
+ (setq lsp-ui-imenu--refresh-timer
+ (run-with-idle-timer lsp-ui-imenu-auto-refresh-delay nil #'lsp-ui-imenu--refresh)))
+
+(defun lsp-ui-imenu-buffer--enable ()
+ "Enable `lsp-ui-imenu-buffer'."
+ (when lsp-ui-imenu-auto-refresh
+ (cl-case lsp-ui-imenu-auto-refresh
+ (after-save
+ (add-hook 'after-save-hook #'lsp-ui-imenu--start-refresh nil t))
+ (t
+ (add-hook 'after-change-functions #'lsp-ui-imenu--start-refresh nil t)
+ (add-hook 'after-save-hook #'lsp-ui-imenu--start-refresh nil t)))))
+
+(defun lsp-ui-imenu-buffer--disable ()
+ "Disable `lsp-ui-imenu-buffer'."
+ (when lsp-ui-imenu-auto-refresh
+ (cl-case lsp-ui-imenu-auto-refresh
+ (after-save
+ (remove-hook 'after-save-hook #'lsp-ui-imenu--start-refresh t))
+ (t
+ (remove-hook 'after-change-functions #'lsp-ui-imenu--start-refresh t)
+ (remove-hook 'after-save-hook #'lsp-ui-imenu--start-refresh t)))))
+
+(define-minor-mode lsp-ui-imenu-buffer-mode
+ "Minor mode 'lsp-ui-imenu-buffer-mode'."
+ :group lsp-ui-imenu
+ (if lsp-ui-imenu-buffer-mode (lsp-ui-imenu-buffer--enable) (lsp-ui-imenu-buffer--disable)))
+
+(provide 'lsp-ui-imenu)
+;;; lsp-ui-imenu.el ends here
diff --git a/elpa/lsp-ui-20220425.1046/lsp-ui-imenu.elc b/elpa/lsp-ui-20220425.1046/lsp-ui-imenu.elc
new file mode 100644
index 0000000..195dc2d
--- /dev/null
+++ b/elpa/lsp-ui-20220425.1046/lsp-ui-imenu.elc
Binary files differ
diff --git a/elpa/lsp-ui-20220425.1046/lsp-ui-peek.el b/elpa/lsp-ui-20220425.1046/lsp-ui-peek.el
new file mode 100644
index 0000000..b0fb2fe
--- /dev/null
+++ b/elpa/lsp-ui-20220425.1046/lsp-ui-peek.el
@@ -0,0 +1,760 @@
+;;; lsp-ui-peek.el --- Lsp-Ui-Peek -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 Sebastien Chapuis
+
+;; Author: Sebastien Chapuis <sebastien@chapu.is>
+;; URL: https://github.com/emacs-lsp/lsp-ui
+;; Keywords: languagues, tools
+;; Version: 0.0.1
+
+;;; License
+;;
+;; 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:
+;;
+;; Load this file and execute `lsp-ui-peek-find-references'
+;; on a symbol to find its references
+;; or `lsp-ui-peek-find-definitions'.
+;; Type 'q' to close the window.
+;;
+
+;;; Code:
+
+(require 'lsp-protocol)
+(require 'lsp-mode)
+(require 'xref)
+(require 'dash)
+
+(defgroup lsp-ui-peek nil
+ "Improve version of xref with peek feature."
+ :group 'tools
+ :group 'convenience
+ :group 'lsp-ui
+ :link '(custom-manual "(lsp-ui-peek) Top")
+ :link '(info-link "(lsp-ui-peek) Customizing"))
+
+(defcustom lsp-ui-peek-enable t
+ "Whether or not to enable ‘lsp-ui-peek’."
+ :type 'boolean
+ :group 'lsp-ui)
+
+(defcustom lsp-ui-peek-show-directory t
+ "Whether or not to show the directory of files."
+ :type 'boolean
+ :safe t
+ :group 'lsp-ui-peek)
+
+(defcustom lsp-ui-peek-peek-height 20
+ "Height of the peek code."
+ :type 'integer
+ :group 'lsp-ui-peek)
+
+(defcustom lsp-ui-peek-list-width 50
+ "Width of the right panel."
+ :type 'integer
+ :group 'lsp-ui-peek)
+
+(defcustom lsp-ui-peek-fontify 'on-demand
+ "Whether to fontify chunks of code (use semantics colors).
+WARNING: 'always can heavily slow the processing when
+`lsp-ui-peek-expand-function' expands more than 1 file.
+It is recommended to keep the default value of `lsp-ui-peek-expand-function'
+when this variable is set to 'always."
+ :type '(choice (const :tag "Never" never)
+ (const :tag "On demand" on-demand)
+ (const :tag "Always" always))
+ :group 'lsp-ui-peek)
+
+(defcustom lsp-ui-peek-always-show nil
+ "Show the peek view even if there is only 1 cross reference.
+By default, the peek view isn't shown if there is 1 xref."
+ :type 'boolean
+ :group 'lsp-ui-peek)
+
+(defface lsp-ui-peek-peek
+ '((((background light)) :background "light gray")
+ (t :background "#031A25"))
+ "Face used for the peek."
+ :group 'lsp-ui-peek)
+
+(defface lsp-ui-peek-list
+ '((((background light)) :background "light gray")
+ (t :background "#181818"))
+ "Face used to list references."
+ :group 'lsp-ui-peek)
+
+(defface lsp-ui-peek-filename
+ '((((background light)) :foreground "red")
+ (t :foreground "dark orange"))
+ "Face used for the filename's reference in the list."
+ :group 'lsp-ui-peek)
+
+(defface lsp-ui-peek-line-number
+ '((t :foreground "grey25"))
+ "Line number face."
+ :group 'lsp-ui-peek)
+
+(defface lsp-ui-peek-highlight
+ '((((background light)) :background "yellow"
+ :box (:line-width -1 :color "red"))
+ (t :background "white"
+ :foreground "black"
+ :distant-foreground "white"
+ :box (:line-width -1 :color "red")))
+ "Face used to highlight the reference/definition.
+Do not use box, underline or overline prop. If you want to use
+box, use a negative value for its width. Those properties deform
+the whole overlay."
+ :group 'lsp-ui-peek)
+
+(defface lsp-ui-peek-header
+ '((((background light)) :background "grey30" :foreground "white")
+ (t :background "white" :foreground "black"))
+ "Face used for the headers."
+ :group 'lsp-ui-peek)
+
+(defface lsp-ui-peek-footer
+ '((t :inherit lsp-ui-peek-header))
+ "Face used for the footers. Only the background of this face is used."
+ :group 'lsp-ui-peek)
+
+(defface lsp-ui-peek-selection
+ '((((background light)) :background "grey30" :foreground "white")
+ (t :background "white" :foreground "black"))
+ "Face used for the current selection.
+Do not use box, underline or overline prop. If you want to use
+box, use a negative value for its width. Those properties
+deform the whole overlay."
+ :group 'lsp-ui-peek)
+
+(defvar lsp-ui-peek-expand-function 'lsp-ui-peek--expand-buffer
+ "A function used to determinate which file(s) to expand in the list of xrefs.
+The function takes one parameter: a list of cons where the car is the
+filename and the cdr is the number of references in that file.
+It should returns a list of filenames to expand.
+WARNING: If you change this variable and expand more than 1 file, it is
+recommended to set `lsp-ui-peek-fontify' to 'never or 'on-demand, otherwise it
+will cause performances issues.")
+
+(defvar-local lsp-ui-peek--overlay nil)
+(defvar-local lsp-ui-peek--list nil)
+(defvar-local lsp-ui-peek--last-xref nil)
+(defvar-local lsp-ui-peek--selection 0)
+(defvar-local lsp-ui-peek--offset 0)
+(defvar-local lsp-ui-peek--size-list 0)
+(defvar-local lsp-ui-peek--win-start nil)
+(defvar-local lsp-ui-peek--method nil)
+(defvar-local lsp-ui-peek--deactivate-keymap-fn nil)
+
+(defvar lsp--peek-save-major-mode nil
+ "Stores the major mode for lsp ui peek.")
+
+(defvar lsp-ui-peek--jumps (make-hash-table)
+ "Hashtable which stores all jumps on a per window basis.")
+
+(defvar evil--jumps-window-jumps) ; defined in evil-jumps.el
+
+(defmacro lsp-ui-peek--with-evil-jumps (&rest body)
+ "Make `evil-jumps.el' commands work on `lsp-ui-peek--jumps'."
+ (declare (indent 1))
+ `(let ((evil--jumps-window-jumps lsp-ui-peek--jumps))
+ ,@body))
+
+(with-eval-after-load 'evil-jumps
+ ;; We need to jump through some hoops to prevent the byte-compiler from
+ ;; compiling this code. We can’t compile the code without requiring
+ ;; ‘evil-macros’.
+ (eval '(progn
+ (evil-define-motion lsp-ui-peek-jump-backward (count)
+ (lsp-ui-peek--with-evil-jumps
+ (evil--jump-backward count)
+ (run-hooks 'xref-after-return-hook)))
+ (evil-define-motion lsp-ui-peek-jump-forward (count)
+ (lsp-ui-peek--with-evil-jumps
+ (evil--jump-forward count)
+ (run-hooks 'xref-after-return-hook))))
+ t))
+
+(defmacro lsp-ui-peek--prop (prop &optional string)
+ `(get-text-property 0 ,prop (or ,string (lsp-ui-peek--get-text-selection) "")))
+
+(defmacro lsp-ui-peek--add-prop (prop &optional string)
+ `(let ((obj (or ,string (lsp-ui-peek--get-text-selection))))
+ (add-text-properties 0 (length obj) ,prop obj)
+ obj))
+
+(defun lsp-ui-peek--truncate (len s)
+ (if (> (string-width s) len)
+ (concat (truncate-string-to-width s (max (- len 2) 0)) "..")
+ s))
+
+(defun lsp-ui-peek--get-text-selection (&optional n)
+ (nth (or n lsp-ui-peek--selection)
+ (--remove (get-text-property 0 'lsp-ui-peek-hidden it) lsp-ui-peek--list)))
+
+(defun lsp-ui-peek--get-selection ()
+ (get-text-property 0 'lsp-ui-peek (or (lsp-ui-peek--get-text-selection) "")))
+
+(defun lsp-ui-peek--visual-index ()
+ (- lsp-ui-peek--selection lsp-ui-peek--offset))
+
+(defun lsp-ui-peek--make-line (index src)
+ (-let* (((s1 . s2) src)
+ (len-s1 (length s1))
+ (len-s2 (length s2))
+ (on-selection (= (1+ (lsp-ui-peek--visual-index)) index))
+ (face-left (if (= index 0) 'lsp-ui-peek-header 'lsp-ui-peek-peek))
+ (face-right (cond (on-selection 'lsp-ui-peek-selection)
+ ((= index 0) 'lsp-ui-peek-header)
+ (t 'lsp-ui-peek-list))))
+ (when on-selection
+ (setq s2 (copy-sequence s2))
+ (add-face-text-property 0 len-s2 face-right nil s2))
+ (unless (get-text-property 0 'lsp-ui-peek-faced s2)
+ (add-face-text-property 0 len-s2 face-right t s2)
+ (add-text-properties 0 len-s2 '(lsp-ui-peek-faced t) s2)
+ (add-face-text-property 0 len-s2 'default t s2))
+ (add-face-text-property 0 len-s1 face-left t s1)
+ (add-face-text-property 0 len-s1 'default t s1)
+ (concat
+ s1
+ (propertize "_" 'face face-left 'display `(space :align-to (- right-fringe ,(1+ lsp-ui-peek-list-width))))
+ " "
+ s2
+ (propertize "_" 'face face-right 'display `(space :align-to (- right-fringe 1)))
+ (propertize "\n" 'face face-right))))
+
+(defun lsp-ui-peek--adjust (width strings)
+ (-let* (((s1 . s2) strings))
+ (cons (lsp-ui-peek--truncate (- width (1+ lsp-ui-peek-list-width)) s1)
+ (lsp-ui-peek--truncate (- lsp-ui-peek-list-width 2) s2))))
+
+(defun lsp-ui-peek--make-footer ()
+ ;; Character-only terminals don't support characters of different height
+ (when (display-graphic-p)
+ (list
+ (concat
+ (propertize " "
+ 'face `(:background ,(face-background 'lsp-ui-peek-footer nil t) :height 1)
+ 'display `(space :align-to (- right-fringe ,(1+ lsp-ui-peek-list-width))))
+ (propertize " " 'face '(:height 1)
+ 'display `(space :align-to (- right-fringe ,lsp-ui-peek-list-width)))
+ (propertize " "
+ 'face `(:background ,(face-background 'lsp-ui-peek-footer nil t) :height 1)
+ 'display `(space :align-to (- right-fringe 0)))
+ (propertize "\n" 'face '(:height 1))
+ (propertize "\n" 'face '(:height 0.5))))))
+
+(defun lsp-ui-peek--peek-new (src1 src2)
+ (-let* ((win-width (- (window-text-width)
+ (if (bound-and-true-p display-line-numbers-mode)
+ (+ 2 (line-number-display-width))
+ 0)))
+ (string (-some--> (-zip-fill "" src1 src2)
+ (--map (lsp-ui-peek--adjust win-width it) it)
+ (-map-indexed 'lsp-ui-peek--make-line it)
+ (-concat it (lsp-ui-peek--make-footer))))
+ (next-line (line-beginning-position 2))
+ (ov (or (when (overlayp lsp-ui-peek--overlay) lsp-ui-peek--overlay)
+ (make-overlay next-line next-line))))
+ (setq lsp-ui-peek--overlay ov)
+ (overlay-put ov 'after-string (mapconcat 'identity string ""))
+ (overlay-put ov 'display-line-numbers-disable t)
+ (overlay-put ov 'window (get-buffer-window))))
+
+(defun lsp-ui-peek--expand-buffer (files)
+ (if (--any? (equal (car it) buffer-file-name) files)
+ (list buffer-file-name)
+ (list (caar files))))
+
+(defun lsp-ui-peek--expand (xrefs)
+ (let* ((to-expand (->> (--map (cons (plist-get it :file) (plist-get it :count)) xrefs)
+ (funcall lsp-ui-peek-expand-function)))
+ first)
+ (while (nth lsp-ui-peek--selection lsp-ui-peek--list)
+ (when (and (lsp-ui-peek--prop 'xrefs)
+ (member (lsp-ui-peek--prop 'file) to-expand))
+ (unless first
+ (setq first (1+ lsp-ui-peek--selection)))
+ (lsp-ui-peek--toggle-file t))
+ (setq lsp-ui-peek--selection (1+ lsp-ui-peek--selection)))
+ (setq lsp-ui-peek--selection (or first 0))
+ (lsp-ui-peek--recenter)))
+
+(defun lsp-ui-peek--show (xrefs)
+ "Create a window to list references/defintions.
+XREFS is a list of references/definitions."
+ (setq lsp-ui-peek--win-start (window-start)
+ lsp-ui-peek--selection 0
+ lsp-ui-peek--offset 0
+ lsp-ui-peek--size-list 0
+ lsp-ui-peek--list nil)
+ (when (eq (logand lsp-ui-peek-peek-height 1) 1)
+ (setq lsp-ui-peek-peek-height (1+ lsp-ui-peek-peek-height)))
+ (when (< (- (line-number-at-pos (window-end)) (line-number-at-pos))
+ (+ lsp-ui-peek-peek-height 3))
+ (recenter 15))
+ (setq xrefs (--sort (string< (plist-get it :file) (plist-get other :file)) xrefs))
+ (--each xrefs
+ (-let* (((&plist :file filename :xrefs xrefs :count count) it)
+ (len-str (number-to-string count)))
+ (setq lsp-ui-peek--size-list (+ lsp-ui-peek--size-list count))
+ (push (concat (propertize (if lsp-ui-peek-show-directory
+ (lsp-ui--workspace-path filename)
+ (file-name-nondirectory filename))
+ 'face 'lsp-ui-peek-filename
+ 'file filename
+ 'xrefs xrefs)
+ (propertize " " 'display `(space :align-to (- right-fringe
+ ;; Account for Emacs TTY's window divider
+ ;; Without this leeway, the reference count
+ ;; string goes to next line - impairs readability
+ ,(if (display-graphic-p) 0 1)
+ ,(1+ (length len-str)))))
+ (propertize len-str 'face 'lsp-ui-peek-filename))
+ lsp-ui-peek--list)))
+ (setq lsp-ui-peek--list (nreverse lsp-ui-peek--list))
+ (lsp-ui-peek--expand xrefs)
+ (lsp-ui-peek--peek))
+
+(defun lsp-ui-peek--recenter ()
+ (let ((half-height (/ lsp-ui-peek-peek-height 2)))
+ (when (> lsp-ui-peek--selection half-height)
+ (setq lsp-ui-peek--offset (- lsp-ui-peek--selection (1- half-height))))))
+
+(defun lsp-ui-peek--fill (min-len list)
+ (let ((len (length list)))
+ (if (< len min-len)
+ (append list (-repeat (- min-len len) ""))
+ list)))
+
+(defun lsp-ui-peek--render (major string)
+ (with-temp-buffer
+ (insert string)
+ (delay-mode-hooks
+ (let ((inhibit-message t))
+ (funcall major))
+ (ignore-errors
+ (font-lock-ensure)))
+ (buffer-string)))
+
+(defun lsp-ui-peek--peek ()
+ "Show reference's chunk of code."
+ (-let* ((xref (lsp-ui-peek--get-selection))
+ ((&plist :file file :chunk chunk) (or xref lsp-ui-peek--last-xref))
+ (header (concat " " (lsp-ui--workspace-path file) "\n"))
+ (header2 (format " %s %s" lsp-ui-peek--size-list
+ (string-remove-prefix "workspace/" (string-remove-prefix "textDocument/" lsp-ui-peek--method))))
+ (ref-view (--> chunk
+ (subst-char-in-string ?\t ?\s it)
+ (concat header it)
+ (split-string it "\n")))
+ (list-refs (->> lsp-ui-peek--list
+ (--remove (lsp-ui-peek--prop 'lsp-ui-peek-hidden it))
+ (-drop lsp-ui-peek--offset)
+ (-take (1- lsp-ui-peek-peek-height))
+ (lsp-ui-peek--fill (1- lsp-ui-peek-peek-height))
+ (-concat (list header2)))))
+ (setq lsp-ui-peek--last-xref (or xref lsp-ui-peek--last-xref))
+ (lsp-ui-peek--peek-new ref-view list-refs)
+ (and (fboundp 'lsp-ui-doc--hide-frame)
+ (lsp-ui-doc--hide-frame))))
+
+(defun lsp-ui-peek--toggle-text-prop (s)
+ (let ((state (lsp-ui-peek--prop 'lsp-ui-peek-hidden s)))
+ (lsp-ui-peek--add-prop `(lsp-ui-peek-hidden ,(not state)) s)))
+
+(defun lsp-ui-peek--toggle-hidden (file)
+ (setq lsp-ui-peek--list
+ (--map-when (string= (plist-get (lsp-ui-peek--prop 'lsp-ui-peek it) :file) file)
+ (prog1 it (lsp-ui-peek--toggle-text-prop it))
+ lsp-ui-peek--list)))
+
+(defun lsp-ui-peek--remove-hidden (file)
+ (setq lsp-ui-peek--list
+ (--map-when (string= (plist-get (lsp-ui-peek--prop 'lsp-ui-peek it) :file) file)
+ (prog1 it (lsp-ui-peek--add-prop '(lsp-ui-peek-hidden nil) it))
+ lsp-ui-peek--list)))
+
+(defun lsp-ui-peek--make-ref-line (xref)
+ (-let* (((&plist :summary summary :line line :file file) xref)
+ (string (format "%-3s %s"
+ (propertize (number-to-string (1+ line))
+ 'face 'lsp-ui-peek-line-number)
+ (string-trim summary))))
+ (lsp-ui-peek--add-prop `(lsp-ui-peek ,xref file ,file) string)))
+
+(defun lsp-ui-peek--insert-xrefs (xrefs filename index)
+ (setq lsp-ui-peek--list (--> (lsp-ui-peek--get-xrefs-in-file (cons filename xrefs))
+ (-map 'lsp-ui-peek--make-ref-line it)
+ (-insert-at (1+ index) it lsp-ui-peek--list)
+ (-flatten it)))
+ (lsp-ui-peek--add-prop '(xrefs nil)))
+
+(defun lsp-ui-peek--toggle-file (&optional no-update)
+ (interactive)
+ (-if-let* ((xrefs (lsp-ui-peek--prop 'xrefs))
+ (filename (lsp-ui-peek--prop 'file))
+ (index (--find-index (equal (lsp-ui-peek--prop 'file it) filename)
+ lsp-ui-peek--list)))
+ (lsp-ui-peek--insert-xrefs xrefs filename index)
+ (let ((file (lsp-ui-peek--prop 'file)))
+ (lsp-ui-peek--toggle-hidden file)
+ (while (not (equal file (lsp-ui-peek--prop 'file)))
+ (lsp-ui-peek--select-prev t))))
+ (unless no-update
+ (lsp-ui-peek--peek)))
+
+(defun lsp-ui-peek--select (index)
+ (setq lsp-ui-peek--selection (+ lsp-ui-peek--selection index)))
+
+(defun lsp-ui-peek--select-next (&optional no-update)
+ (interactive)
+ (when (lsp-ui-peek--get-text-selection (1+ lsp-ui-peek--selection))
+ (lsp-ui-peek--select 1)
+ (while (> (lsp-ui-peek--visual-index) (- lsp-ui-peek-peek-height 2))
+ (setq lsp-ui-peek--offset (1+ lsp-ui-peek--offset)))
+ (unless no-update
+ (lsp-ui-peek--peek))))
+
+(defun lsp-ui-peek--select-prev (&optional no-update)
+ (interactive)
+ (when (> lsp-ui-peek--selection 0)
+ (lsp-ui-peek--select -1)
+ (while (< (lsp-ui-peek--visual-index) 0)
+ (setq lsp-ui-peek--offset (1- lsp-ui-peek--offset))))
+ (unless no-update
+ (lsp-ui-peek--peek)))
+
+(defun lsp-ui-peek--skip-refs (fn)
+ (let ((last-file (lsp-ui-peek--prop 'file))
+ last-selection)
+ (when (lsp-ui-peek--get-selection)
+ (while (and (equal (lsp-ui-peek--prop 'file) last-file)
+ (not (equal last-selection lsp-ui-peek--selection)))
+ (setq last-selection lsp-ui-peek--selection)
+ (funcall fn t)))))
+
+(defun lsp-ui-peek--select-prev-file ()
+ (interactive)
+ (if (not (lsp-ui-peek--get-selection))
+ (lsp-ui-peek--select-prev)
+ (lsp-ui-peek--skip-refs 'lsp-ui-peek--select-prev)
+ (when (lsp-ui-peek--get-selection)
+ (lsp-ui-peek--skip-refs 'lsp-ui-peek--select-prev)
+ (unless (= lsp-ui-peek--selection 0)
+ (lsp-ui-peek--select-next t))))
+ (if (lsp-ui-peek--prop 'xrefs)
+ (lsp-ui-peek--toggle-file)
+ (lsp-ui-peek--remove-hidden (lsp-ui-peek--prop 'file)))
+ (lsp-ui-peek--select-next t)
+ (lsp-ui-peek--recenter)
+ (lsp-ui-peek--peek))
+
+(defun lsp-ui-peek--select-next-file ()
+ (interactive)
+ (lsp-ui-peek--skip-refs 'lsp-ui-peek--select-next)
+ (if (lsp-ui-peek--prop 'xrefs)
+ (lsp-ui-peek--toggle-file)
+ (lsp-ui-peek--remove-hidden (lsp-ui-peek--prop 'file)))
+ (lsp-ui-peek--select-next t)
+ (lsp-ui-peek--recenter)
+ (lsp-ui-peek--peek))
+
+(defun lsp-ui-peek--peek-hide ()
+ "Hide the chunk of code and restore previous state."
+ (when (overlayp lsp-ui-peek--overlay)
+ (delete-overlay lsp-ui-peek--overlay))
+ (setq lsp-ui-peek--overlay nil
+ lsp-ui-peek--last-xref nil)
+ (when lsp-ui-peek--win-start
+ (set-window-start (get-buffer-window) lsp-ui-peek--win-start)))
+
+(defun lsp-ui-peek--deactivate-keymap ()
+ "Deactivate keymap."
+ (-when-let (fn lsp-ui-peek--deactivate-keymap-fn)
+ (setq lsp-ui-peek--deactivate-keymap-fn nil)
+ (funcall fn)))
+
+(defun lsp-ui-peek--goto-xref (&optional x other-window)
+ "Go to a reference/definition."
+ (interactive)
+ (-if-let (xref (or x (lsp-ui-peek--get-selection)))
+ (-let (((&plist :file file :line line :column column) xref)
+ (buffer (current-buffer)))
+ (if (not (file-readable-p file))
+ (user-error "File not readable: %s" file)
+ (setq lsp-ui-peek--win-start nil)
+ (lsp-ui-peek--abort)
+ (let ((marker (with-current-buffer
+ (or (get-file-buffer file)
+ (find-file-noselect file))
+ (save-restriction
+ (widen)
+ (save-excursion
+ ;; When we jump to a file with line/column unspecified,
+ ;; we do not want to move the point if the buffer exists.
+ ;; We interpret line=column=0 differently here.
+ (when (> (+ line column) 0)
+ (goto-char 1)
+ (forward-line line)
+ (forward-char column))
+ (point-marker)))))
+ (cur-buffer-workspaces (and (boundp 'lsp--buffer-workspaces) lsp--buffer-workspaces)))
+ (if other-window
+ (pop-to-buffer (marker-buffer marker) t)
+ (switch-to-buffer (marker-buffer marker)))
+ (with-current-buffer buffer
+ (lsp-ui-peek-mode -1))
+ (unless lsp--buffer-workspaces
+ (setq lsp--buffer-workspaces cur-buffer-workspaces)
+ (lsp-mode 1)
+ (dolist (workspace cur-buffer-workspaces)
+ (lsp--open-in-workspace workspace)))
+ (goto-char marker)
+ (run-hooks 'xref-after-jump-hook))))
+ (lsp-ui-peek--toggle-file)))
+
+(defun lsp-ui-peek--goto-xref-other-window ()
+ (interactive)
+ (lsp-ui-peek--goto-xref nil t))
+
+(defvar lsp-ui-peek-mode-map
+ (let ((map (make-sparse-keymap)))
+ (suppress-keymap map t)
+ (define-key map "\e\e\e" 'lsp-ui-peek--abort)
+ (define-key map "\C-g" 'lsp-ui-peek--abort)
+ (define-key map (kbd "M-n") 'lsp-ui-peek--select-next-file)
+ (define-key map (kbd "<right>") 'lsp-ui-peek--select-next-file)
+ (define-key map (kbd "M-p") 'lsp-ui-peek--select-prev-file)
+ (define-key map (kbd "<left>") 'lsp-ui-peek--select-prev-file)
+ (define-key map (kbd "C-n") 'lsp-ui-peek--select-next)
+ (define-key map (kbd "n") 'lsp-ui-peek--select-next)
+ (define-key map (kbd "<down>") 'lsp-ui-peek--select-next)
+ (define-key map (kbd "C-p") 'lsp-ui-peek--select-prev)
+ (define-key map (kbd "p") 'lsp-ui-peek--select-prev)
+ (define-key map (kbd "<up>") 'lsp-ui-peek--select-prev)
+ (define-key map (kbd "TAB") 'lsp-ui-peek--toggle-file)
+ (define-key map (kbd "<tab>") 'lsp-ui-peek--toggle-file)
+ (define-key map (kbd "q") 'lsp-ui-peek--abort)
+ (define-key map (kbd "RET") 'lsp-ui-peek--goto-xref)
+ (define-key map (kbd "M-RET") 'lsp-ui-peek--goto-xref-other-window)
+ map)
+ "Keymap for ‘lsp-ui-peek-mode’.")
+
+(defun lsp-ui-peek--disable ()
+ "Do not call this function, call `lsp-ui-peek--abort' instead."
+ (when (bound-and-true-p lsp-ui-peek-mode)
+ (lsp-ui-peek-mode -1)
+ (lsp-ui-peek--peek-hide)))
+
+(defun lsp-ui-peek--abort ()
+ "Abort peek."
+ (interactive)
+ ;; The timer fixes https://github.com/emacs-lsp/lsp-ui/issues/33
+ (run-with-idle-timer 0 nil 'lsp-ui-peek--disable))
+
+(define-minor-mode lsp-ui-peek-mode
+ "Mode for lsp-ui-peek."
+ :init-value nil
+ (if lsp-ui-peek-mode
+ (setq lsp-ui-peek--deactivate-keymap-fn (set-transient-map lsp-ui-peek-mode-map t 'lsp-ui-peek--abort))
+ (lsp-ui-peek--deactivate-keymap)
+ (lsp-ui-peek--peek-hide)))
+
+(defun lsp-ui-peek--find-xrefs (input method param)
+ "Find INPUT references.
+METHOD is ‘references’, ‘definitions’, `implementation` or a custom kind.
+PARAM is the request params."
+ (setq lsp-ui-peek--method method)
+ (let ((xrefs (lsp-ui-peek--get-references method param)))
+ (unless xrefs
+ (user-error "Not found for: %s" input))
+ (xref-push-marker-stack)
+ (when (featurep 'evil-jumps)
+ (lsp-ui-peek--with-evil-jumps (evil-set-jump)))
+ (if (and (not lsp-ui-peek-always-show)
+ (not (cdr xrefs))
+ (= (length (plist-get (car xrefs) :xrefs)) 1))
+ (let ((x (car (plist-get (car xrefs) :xrefs))))
+ (-if-let (uri (lsp:location-uri x))
+ (-let (((&Range :start (&Position :line :character)) (lsp:location-range x)))
+ (lsp-ui-peek--goto-xref `(:file ,(lsp--uri-to-path uri) :line ,line :column ,character)))
+ (-let (((&Range :start (&Position :line :character)) (or (lsp:location-link-target-selection-range x)
+ (lsp:location-link-target-range x))))
+ (lsp-ui-peek--goto-xref `(:file ,(lsp--uri-to-path (lsp:location-link-target-uri x)) :line ,line :column ,character)))))
+ (lsp-ui-peek-mode)
+ (lsp-ui-peek--show xrefs))))
+
+(defun lsp-ui-peek-find-references (&optional include-declaration extra)
+ "Find references to the IDENTIFIER at point."
+ (interactive)
+ (lsp-ui-peek--find-xrefs (symbol-at-point) "textDocument/references"
+ (append extra (lsp--make-reference-params nil include-declaration))))
+
+(defun lsp-ui-peek-find-definitions (&optional extra)
+ "Find definitions to the IDENTIFIER at point."
+ (interactive)
+ (lsp-ui-peek--find-xrefs (symbol-at-point) "textDocument/definition"
+ (append extra (lsp--text-document-position-params))))
+
+(defun lsp-ui-peek-find-implementation (&optional extra)
+ "Find implementation locations of the symbol at point."
+ (interactive)
+ (lsp-ui-peek--find-xrefs (symbol-at-point) "textDocument/implementation"
+ (append extra (lsp--text-document-position-params))))
+
+(defun lsp-ui-peek-find-workspace-symbol (pattern &optional extra)
+ "Find symbols in the worskpace.
+The symbols are found matching PATTERN."
+ (interactive (list (read-string "workspace/symbol: "
+ nil 'xref--read-pattern-history)))
+ (lsp-ui-peek--find-xrefs pattern "workspace/symbol"
+ (append extra (lsp-make-workspace-symbol-params :query pattern))))
+
+(defun lsp-ui-peek-find-custom (method &optional extra)
+ "Find custom references.
+KIND is a symbol to name the references (definition, reference, ..).
+REQUEST is the method string to send the the language server.
+EXTRA is a plist of extra parameters."
+ (lsp-ui-peek--find-xrefs (symbol-at-point) method
+ (append extra (lsp--text-document-position-params))))
+
+(defun lsp-ui-peek--extract-chunk-from-buffer (pos start end)
+ "Return the chunk of code pointed to by POS (a Position object) in the current buffer.
+START and END are delimiters."
+ (let* ((point (lsp--position-to-point pos))
+ (inhibit-field-text-motion t)
+ (line-start (1+ (- 1 (/ lsp-ui-peek-peek-height 2))))
+ (line-end (/ lsp-ui-peek-peek-height 2)))
+ (save-excursion
+ (goto-char point)
+ (let* ((before (buffer-substring (line-beginning-position line-start) (line-beginning-position)))
+ (line (buffer-substring (line-beginning-position) (line-end-position)))
+ (after (buffer-substring (line-end-position) (line-end-position line-end)))
+ (len (length line))
+ (chunk (concat before line after))
+ (start-in-chunk (length before)))
+
+ (when (eq lsp-ui-peek-fontify 'on-demand)
+ (setq chunk (lsp-ui-peek--render lsp--peek-save-major-mode chunk)))
+
+ (remove-text-properties (+ (min start len) start-in-chunk)
+ (+ (if (null end) len (min end len)) start-in-chunk) '(face nil)
+ chunk)
+
+ (add-face-text-property (+ (min start len) start-in-chunk)
+ (+ (if (null end) len (min end len)) start-in-chunk)
+ 'lsp-ui-peek-highlight t chunk)
+
+ `(,(substring chunk start-in-chunk (+ start-in-chunk len)) . ,chunk)))))
+
+(defun lsp-ui-peek--xref-make-item (filename loc)
+ "Return an item from FILENAME given a LOC.
+LOCATION can be either a LSP Location or SymbolInformation."
+ ;; TODO: Read more informations from SymbolInformation.
+ ;; For now, only the location is used.
+ (-let* ((loc (or (lsp:symbol-information-location loc) loc))
+ (range (or (lsp:location-range loc)
+ (lsp:location-link-target-selection-range loc)
+ (lsp:location-link-target-range loc)))
+ ((&Range :start pos-start :end pos-end) range)
+ ((&Position :line start-line :character start-col) pos-start)
+ ((&Position :line end-line :character end-col) pos-end)
+ ((line . chunk) (lsp-ui-peek--extract-chunk-from-buffer pos-start start-col
+ (when (= start-line end-line) end-col))))
+ (list :summary (or line filename)
+ :chunk (or chunk filename)
+ :file filename
+ :line start-line
+ :column start-col)))
+
+(defun lsp-ui-peek--fontify-buffer (filename)
+ (when (eq lsp-ui-peek-fontify 'always)
+ (unless buffer-file-name
+ (make-local-variable 'delay-mode-hooks)
+ (let ((buffer-file-name filename)
+ (enable-local-variables nil)
+ (inhibit-message t)
+ (delay-mode-hooks t))
+ (set-auto-mode)))
+ (font-lock-ensure)))
+
+(defun lsp-ui-peek--get-xrefs-in-file (file)
+ "Return all references that contain a file.
+FILE is a cons where its car is the filename and the cdr is a list of Locations
+within the file. We open and/or create the file/buffer only once for all
+references. The function returns a list of `ls-xref-item'."
+ (let* ((filename (car file))
+ (visiting (find-buffer-visiting filename))
+ (fn (lambda (loc) (lsp-ui-peek--xref-make-item filename loc))))
+ (setq lsp--peek-save-major-mode major-mode)
+ (cond
+ (visiting
+ (with-temp-buffer
+ (insert-buffer-substring-no-properties visiting)
+ (lsp-ui-peek--fontify-buffer filename)
+ (mapcar fn (cdr file))))
+ ((file-readable-p filename)
+ (with-temp-buffer
+ (insert-file-contents-literally filename)
+ (lsp-ui-peek--fontify-buffer filename)
+ (mapcar fn (cdr file))))
+ (t (user-error "Cannot read %s" filename)))))
+
+(defun lsp-ui-peek--get-xrefs-list (file)
+ "Return a list of xrefs in FILE."
+ (-let* (((filename . xrefs) file))
+ `(:file ,filename :xrefs ,xrefs :count ,(length xrefs))))
+
+(defun lsp-ui-peek--get-references (method params)
+ "Get all references/definitions for the symbol under point.
+Returns item(s)."
+ (-when-let* ((locs (lsp-request method params))
+ (locs (if (listp locs)
+ locs
+ (if (vectorp locs)
+ (append locs nil)
+ (list locs)))))
+ (-filter
+ (-lambda ((&plist :file))
+ (or (f-file? file)
+ (ignore
+ (lsp-log "The following file %s is missing, ignoring from the results."
+ file))))
+ (mapcar #'lsp-ui-peek--get-xrefs-list
+ (if (lsp:location-uri (car locs))
+ ;; Location[]
+ (--group-by (lsp--uri-to-path (lsp:location-uri it)) locs)
+ ;; LocationLink[]
+ (--group-by (lsp--uri-to-path (lsp:location-link-target-uri it)) locs))))))
+
+(defvar lsp-ui-mode-map)
+
+(defun lsp-ui-peek-enable (_enable)
+ (interactive)
+ (unless (bound-and-true-p lsp-ui-mode-map)
+ (user-error "Please load lsp-ui before trying to enable lsp-ui-peek")))
+
+;; lsp-ui.el loads lsp-ui-peek.el, so we can’t ‘require’ lsp-ui.
+;; FIXME: Remove this cyclic dependency.
+(declare-function lsp-ui--workspace-path "lsp-ui" (path))
+
+(declare-function evil-set-jump "ext:evil-jumps.el" (&optional pos))
+
+(provide 'lsp-ui-peek)
+;;; lsp-ui-peek.el ends here
diff --git a/elpa/lsp-ui-20220425.1046/lsp-ui-peek.elc b/elpa/lsp-ui-20220425.1046/lsp-ui-peek.elc
new file mode 100644
index 0000000..e154483
--- /dev/null
+++ b/elpa/lsp-ui-20220425.1046/lsp-ui-peek.elc
Binary files differ
diff --git a/elpa/lsp-ui-20220425.1046/lsp-ui-pkg.el b/elpa/lsp-ui-20220425.1046/lsp-ui-pkg.el
new file mode 100644
index 0000000..73b31c8
--- /dev/null
+++ b/elpa/lsp-ui-20220425.1046/lsp-ui-pkg.el
@@ -0,0 +1,15 @@
+(define-package "lsp-ui" "20220425.1046" "UI modules for lsp-mode"
+ '((emacs "26.1")
+ (dash "2.18.0")
+ (lsp-mode "6.0")
+ (markdown-mode "2.3"))
+ :commit "6cd0409de6ca59c02d752b8e543bb5eaa61357e4" :authors
+ '(("Sebastien Chapuis <sebastien@chapu.is>, Fangrui Song" . "i@maskray.me"))
+ :maintainer
+ '("Sebastien Chapuis <sebastien@chapu.is>, Fangrui Song" . "i@maskray.me")
+ :keywords
+ '("languages" "tools")
+ :url "https://github.com/emacs-lsp/lsp-ui")
+;; Local Variables:
+;; no-byte-compile: t
+;; End:
diff --git a/elpa/lsp-ui-20220425.1046/lsp-ui-sideline.el b/elpa/lsp-ui-20220425.1046/lsp-ui-sideline.el
new file mode 100644
index 0000000..f627a6a
--- /dev/null
+++ b/elpa/lsp-ui-20220425.1046/lsp-ui-sideline.el
@@ -0,0 +1,768 @@
+;;; lsp-ui-sideline.el --- Lsp-Ui-Sideline -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 Sebastien Chapuis
+
+;; Author: Sebastien Chapuis <sebastien@chapu.is>
+;; URL: https://github.com/emacs-lsp/lsp-ui
+;; Keywords: languages, tools
+;; Version: 6.2
+
+;;; License
+;;
+;; 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:
+;;
+;; Utility to show information for the current line
+
+;;; Code:
+
+(require 'lsp-ui-util)
+(require 'lsp-protocol)
+(require 'lsp-mode)
+(require 'flycheck nil 'noerror)
+(require 'dash)
+(require 'seq)
+(require 'subr-x)
+(require 'face-remap)
+
+(defvar flycheck-display-errors-function)
+(declare-function flycheck-overlay-errors-in "ext:flycheck.el")
+(declare-function flycheck-error-format-message-and-id "ext:flycheck.el")
+(declare-function flycheck-error-level "ext:flycheck.el")
+
+(defgroup lsp-ui-sideline nil
+ "Display information for the current line."
+ :group 'tools
+ :group 'convenience
+ :group 'lsp-ui
+ :link '(custom-manual "(lsp-ui-sideline) Top")
+ :link '(info-link "(lsp-ui-sideline) Customizing"))
+
+(defcustom lsp-ui-sideline-enable t
+ "Whether or not to enable ‘lsp-ui-sideline’."
+ :type 'boolean
+ :group 'lsp-ui)
+
+(defcustom lsp-ui-sideline-ignore-duplicate nil
+ "Ignore duplicates when there is a same symbol with the same contents."
+ :type 'boolean
+ :group 'lsp-ui-sideline)
+
+(defcustom lsp-ui-sideline-show-symbol t
+ "When t, show the symbol name on the right of the information."
+ :type 'boolean
+ :group 'lsp-ui-sideline)
+
+(defcustom lsp-ui-sideline-show-hover nil
+ "Whether to show hover messages in sideline."
+ :type 'boolean
+ :group 'lsp-ui-sideline)
+
+(defcustom lsp-ui-sideline-show-diagnostics t
+ "Whether to show diagnostics messages in sideline."
+ :type 'boolean
+ :group 'lsp-ui-sideline)
+
+(defcustom lsp-ui-sideline-show-code-actions nil
+ "Whether to show code actions in sideline."
+ :type 'boolean
+ :group 'lsp-ui-sideline)
+
+(defcustom lsp-ui-sideline-update-mode 'point
+ "Define the mode for updating sideline actions.
+
+When set to `line' the actions will be updated when user
+changes current line otherwise the actions will be updated
+when user changes current point."
+ :type '(choice (const line)
+ (const point))
+ :group 'lsp-ui-sideline)
+
+(defcustom lsp-ui-sideline-delay 0.2
+ "Number of seconds to wait before showing sideline."
+ :type 'number
+ :group 'lsp-ui-sideline)
+
+(defcustom lsp-ui-sideline-diagnostic-max-lines 1
+ "Maximum number of lines to show of diagnostics in sideline."
+ :type 'integer
+ :group 'lsp-ui-sideline)
+
+(defcustom lsp-ui-sideline-diagnostic-max-line-length 100
+ "Maximum line length of diagnostics in sideline."
+ :type 'integer
+ :group 'lsp-ui-sideline)
+
+(defconst lsp-ui-sideline-actions-icon-default
+ (and (bound-and-true-p lsp-ui-resources-dir)
+ (image-type-available-p 'png)
+ (expand-file-name "lightbulb.png" lsp-ui-resources-dir)))
+
+;; TODO: Set the default actions to `nil' temporarily due to image
+;; scale issue on Emacs version 26.3 or below.
+;;
+;; See #573
+(defcustom lsp-ui-sideline-actions-icon nil
+ "Image file for actions. It must be a png file."
+ :type '(choice file (const :tag "Disable" nil))
+ :group 'lsp-ui-sideline)
+
+(defcustom lsp-ui-sideline-wait-for-all-symbols t
+ "Wait for all symbols before displaying info in sideline."
+ :type 'boolean
+ :group 'lsp-ui-sideline)
+
+(defcustom lsp-ui-sideline-actions-kind-regex "quickfix.*\\|refactor.*"
+ "Regex for the code actions kinds to show in the sideline."
+ :type 'string
+ :group 'lsp-ui-sideline)
+
+(defvar lsp-ui-sideline-code-actions-prefix ""
+ "Prefix to insert before the code action title.
+This can be used to insert, for example, an unicode character: 💡")
+
+(defvar-local lsp-ui-sideline--ovs nil
+ "Overlays used by `lsp-ui-sideline'.")
+
+(defvar-local lsp-ui-sideline--occupied-lines nil
+ "List of lines occupied by an overlay of `lsp-ui-sideline'.")
+
+(defvar-local lsp-ui-sideline--first-line-pushed nil
+ "Record weather if we display sideline in the first line.
+
+If we do, then sideline will always look downward instead of the upward
+direction.
+
+This prevent sideline displays below than the first line, which it will cause
+weird looking user interface.")
+
+(defvar-local lsp-ui-sideline--tag nil
+ "Tag marking where the last operation was based.
+It is used to know when the cursor has changed its line or point.")
+
+(defvar-local lsp-ui-sideline--last-width nil
+ "Value of window's width on the last operation.
+It is used to know when the window has changed of width.")
+
+(defvar-local lsp-ui-sideline--last-line-number nil
+ "Line number on the last operation.
+Used to avoid calling `line-number-at-pos' when we're on the same line.")
+
+(defvar-local lsp-ui-sideline--timer nil)
+
+(defvar-local lsp-ui-sideline--code-actions nil
+ "Holds the latest code actions.")
+
+(defvar-local lsp-ui-sideline--cached-infos nil
+ "Cache of rendered line when `lsp-ui-sideline-wait-for-all-symbols'
+is nil. Used to not re-render the same line multiple times.")
+
+(defface lsp-ui-sideline-symbol
+ '((t :foreground "grey"
+ :box (:line-width -1 :color "grey")
+ :height 0.99))
+ "Face used to highlight symbols."
+ :group 'lsp-ui-sideline)
+
+(defface lsp-ui-sideline-current-symbol
+ '((((background light))
+ :foreground "black"
+ :weight ultra-bold
+ :box (:line-width -1 :color "black")
+ :height 0.99)
+ (t :foreground "white"
+ :weight ultra-bold
+ :box (:line-width -1 :color "white")
+ :height 0.99))
+ "Face used to highlight the symbol on point."
+ :group 'lsp-ui-sideline)
+
+(defface lsp-ui-sideline-code-action
+ '((((background light)) :foreground "DarkOrange")
+ (t :foreground "yellow"))
+ "Face used to highlight code action text."
+ :group 'lsp-ui-sideline)
+
+(defface lsp-ui-sideline-symbol-info
+ '((t :slant italic :height 0.99))
+ "Face used to highlight the symbols informations (LSP hover)."
+ :group 'lsp-ui-sideline)
+
+(defface lsp-ui-sideline-global
+ '((t))
+ "Face which apply to all overlays.
+This face have a low priority over the others."
+ :group 'lsp-ui-sideline)
+
+(defun lsp-ui-sideline--first-line-p (pos)
+ "Return non-nil if POS is on the first line."
+ (when (integerp pos)
+ (save-excursion (goto-char 1) (forward-line 1) (> (point) pos))))
+
+(defun lsp-ui-sideline--calc-space (win-width str-len index)
+ "Calculate whether there is enough space on line.
+If there is enough space, it returns the point of the last
+character on the line.
+
+WIN-WIDTH is the window width.
+STR-LEN is the string size.
+INDEX is the line number (relative to the current line)."
+ (let ((eol (line-end-position index)))
+ (unless (member eol lsp-ui-sideline--occupied-lines)
+ (save-excursion
+ (goto-char eol)
+ (end-of-line)
+ (when (>= (- win-width (current-column)) str-len)
+ eol)))))
+
+(defun lsp-ui-sideline--find-line (str-len bol eol &optional up offset)
+ "Find a line where the string can be inserted.
+
+It loops on the nexts lines to find enough space. Returns the point
+of the last character on the line.
+
+Argument STR-LEN is the string size.
+Argument BOL and EOL are beginning and ending of the user point line.
+If optional argument UP is non-nil, it loops on the previous lines.
+If optional argument OFFSET is non-nil, it starts search OFFSET lines
+from user point line."
+ (let ((win-width (lsp-ui-sideline--window-width))
+ (inhibit-field-text-motion t)
+ (index (if (null offset) 1 offset))
+ pos)
+ (while (and (null pos) (<= (abs index) 30))
+ (setq index (if up (1- index) (1+ index)))
+ (setq pos (lsp-ui-sideline--calc-space win-width str-len index)))
+ (if (and up (or (null pos) (and (<= pos 1) lsp-ui-sideline--first-line-pushed)))
+ (lsp-ui-sideline--find-line str-len bol eol nil offset)
+ (when (and (null lsp-ui-sideline--first-line-pushed)
+ (lsp-ui-sideline--first-line-p pos))
+ (setq lsp-ui-sideline--first-line-pushed t)) ; mark first line push
+ (and pos (or (> pos eol) (< pos bol))
+ (push pos lsp-ui-sideline--occupied-lines)
+ (list pos (1- index))))))
+
+(defun lsp-ui-sideline--delete-ov ()
+ "Delete overlays."
+ (seq-do 'delete-overlay lsp-ui-sideline--ovs)
+ (setq lsp-ui-sideline--tag nil
+ lsp-ui-sideline--cached-infos nil
+ lsp-ui-sideline--occupied-lines nil
+ lsp-ui-sideline--first-line-pushed (lsp-ui-sideline--first-line-p (point))
+ lsp-ui-sideline--ovs nil))
+
+(defun lsp-ui-sideline--extract-info (contents)
+ "Extract the line to print from CONTENTS.
+CONTENTS can be differents type of values:
+MarkedString | MarkedString[] | MarkupContent (as defined in the LSP).
+We prioritize string with a language (which is probably a type or a
+function signature)."
+ (when contents
+ (cond
+ ((lsp-marked-string? contents) contents)
+ ((vectorp contents)
+ (seq-find (lambda (it) (and (lsp-marked-string? it)
+ (lsp-get-renderer (lsp:marked-string-language it))))
+ contents))
+ ((lsp-markup-content? contents) contents))))
+
+(defun lsp-ui-sideline--format-info (marked-string win-width)
+ "Format MARKED-STRING.
+If the string has a language, we fontify it with the function provided
+by `lsp-mode'.
+MARKED-STRING is the string returned by `lsp-ui-sideline--extract-info'."
+ (when (and marked-string (or (lsp-marked-string? marked-string) (lsp-markup-content? marked-string)))
+ (setq marked-string (lsp--render-element marked-string))
+ (add-face-text-property 0 (length marked-string) 'lsp-ui-sideline-symbol-info nil marked-string)
+ (add-face-text-property 0 (length marked-string) 'default t marked-string)
+ (->> (if (> (length marked-string) (/ win-width 2))
+ (car (split-string (string-trim-left marked-string) "[\r\n]+"))
+ marked-string)
+ (replace-regexp-in-string "[\n\r\t ]+" " "))))
+
+(defun lsp-ui-sideline--align (&rest lengths)
+ "Align sideline string by LENGTHS from the right of the window."
+ (+ (apply '+ lengths)
+ (if (display-graphic-p) 1 2)))
+
+(defun lsp-ui-sideline--compute-height nil
+ "Return a fixed size for text in sideline."
+ (if (null text-scale-mode-remapping)
+ '(height 1)
+ ;; Readjust height when text-scale-mode is used
+ (list 'height
+ (/ 1 (or (plist-get (cdr text-scale-mode-remapping) :height)
+ 1)))))
+
+(defun lsp-ui-sideline--make-display-string (info symbol current)
+ "Make final string to display in buffer.
+INFO is the information to display.
+SYMBOL is the symbol associated with the info.
+CURRENT is non-nil when the point is on the symbol."
+ (let* ((face (if current 'lsp-ui-sideline-current-symbol 'lsp-ui-sideline-symbol))
+ (str (if lsp-ui-sideline-show-symbol
+ (concat info " " (propertize (concat " " symbol " ") 'face face))
+ info))
+ (len (length str))
+ (margin (lsp-ui-sideline--margin-width)))
+ (add-face-text-property 0 len 'lsp-ui-sideline-global nil str)
+ (concat
+ (propertize " " 'display `(space :align-to (- right-fringe ,(lsp-ui-sideline--align len margin))))
+ (propertize str 'display (lsp-ui-sideline--compute-height)))))
+
+(defun lsp-ui-sideline--check-duplicate (symbol info)
+ "Check if there's already a SYMBOL containing INFO, unless `lsp-ui-sideline-ignore-duplicate'
+is set to t."
+ (not (when lsp-ui-sideline-ignore-duplicate
+ (--any (and (string= (overlay-get it 'symbol) symbol)
+ (string= (overlay-get it 'info) info))
+ lsp-ui-sideline--ovs))))
+
+(defun lsp-ui-sideline--margin-width ()
+ (+ (if fringes-outside-margins right-margin-width 0)
+ (or (and (boundp 'fringe-mode)
+ (consp fringe-mode)
+ (or (equal (car fringe-mode) 0)
+ (equal (cdr fringe-mode) 0))
+ 1)
+ (and (boundp 'fringe-mode) (equal fringe-mode 0) 1)
+ 0)
+ (let ((win-fringes (window-fringes)))
+ (if (or (equal (car win-fringes) 0)
+ (equal (cadr win-fringes) 0))
+ 2
+ 0))
+ (if (< emacs-major-version 27)
+ ;; This was necessary with emacs < 27, recent versions take
+ ;; into account the display-line width with :align-to
+ (lsp-ui-util-line-number-display-width)
+ 0)
+ (if (or
+ (bound-and-true-p whitespace-mode)
+ (bound-and-true-p global-whitespace-mode))
+ 1
+ 0)))
+
+(defun lsp-ui-sideline--window-width ()
+ (- (min (window-text-width) (window-body-width))
+ (lsp-ui-sideline--margin-width)
+ (or (and (>= emacs-major-version 27)
+ ;; We still need this number when calculating available space
+ ;; even with emacs >= 27
+ (lsp-ui-util-line-number-display-width))
+ 0)))
+
+(defun lsp-ui-sideline--valid-tag-p (tag mode)
+ (when tag
+ (-let ((inhibit-field-text-motion t)
+ ((p bol _eol buffer) tag))
+ (when (and (= bol (line-beginning-position))
+ (eq buffer (current-buffer)))
+ (pcase mode
+ ('point (eq p (point)))
+ ('line t) ;; For 'line only bol is relevant
+ (_ (error "Wrong tag mode")))))))
+
+(defun lsp-ui-sideline--display-all-info (list-infos tag bol eol)
+ (when (and (lsp-ui-sideline--valid-tag-p tag 'line)
+ (not (lsp-ui-sideline--stop-p)))
+ (let ((inhibit-modification-hooks t)
+ (win-width (window-body-width))
+ ;; sort by bounds
+ (list-infos (--sort (< (caadr it) (caadr other)) list-infos)))
+ (lsp-ui-sideline--delete-kind 'info)
+ (--each list-infos
+ (-let (((symbol bounds info) it))
+ (lsp-ui-sideline--push-info win-width symbol bounds info bol eol))))))
+
+(defun lsp-ui-sideline--push-info (win-width symbol bounds info bol eol)
+ (let* ((markdown-hr-display-char nil)
+ (info (or (alist-get info lsp-ui-sideline--cached-infos)
+ (-some--> (lsp:hover-contents info)
+ (lsp-ui-sideline--extract-info it)
+ (lsp-ui-sideline--format-info it win-width)
+ (progn (push (cons info it) lsp-ui-sideline--cached-infos) it))))
+ (current (and (>= (point) (car bounds)) (<= (point) (cdr bounds)))))
+ (when (and (> (length info) 0)
+ (lsp-ui-sideline--check-duplicate symbol info))
+ (let* ((final-string (lsp-ui-sideline--make-display-string info symbol current))
+ (pos-ov (lsp-ui-sideline--find-line (length final-string) bol eol))
+ (ov (when pos-ov (make-overlay (car pos-ov) (car pos-ov)))))
+ (when pos-ov
+ (overlay-put ov 'info info)
+ (overlay-put ov 'symbol symbol)
+ (overlay-put ov 'bounds bounds)
+ (overlay-put ov 'current current)
+ (overlay-put ov 'after-string final-string)
+ (overlay-put ov 'before-string " ")
+ (overlay-put ov 'window (get-buffer-window))
+ (overlay-put ov 'kind 'info)
+ (overlay-put ov 'position (car pos-ov))
+ (push ov lsp-ui-sideline--ovs))))))
+
+(defun lsp-ui-sideline--toggle-current (ov current)
+ "Toggle the OV face according to CURRENT."
+ (let* ((info (overlay-get ov 'info))
+ (symbol (overlay-get ov 'symbol))
+ (string (lsp-ui-sideline--make-display-string info symbol current)))
+ (overlay-put ov 'current current)
+ (overlay-put ov 'after-string string)))
+
+(defun lsp-ui-sideline--highlight-current (point)
+ "Update the symbol's face according to POINT."
+ (dolist (ov lsp-ui-sideline--ovs)
+ (let* ((bounds (overlay-get ov 'bounds))
+ (start (car bounds))
+ (end (cdr bounds)))
+ (if (and bounds (>= point start) (<= point end))
+ (unless (overlay-get ov 'current)
+ (lsp-ui-sideline--toggle-current ov t))
+ (when (overlay-get ov 'current)
+ (lsp-ui-sideline--toggle-current ov nil))))))
+
+(defun lsp-ui-sideline--split-long-lines (lines)
+ "Fill LINES so that they are not longer than `lsp-ui-sideline-diagnostic-max-line-length' characters."
+ (cl-mapcan (lambda (line)
+ (if (< (length line) lsp-ui-sideline-diagnostic-max-line-length)
+ (list line)
+ (with-temp-buffer
+ (let ((fill-column lsp-ui-sideline-diagnostic-max-line-length))
+ (insert line)
+ (fill-region (point-min) (point-max))
+ (split-string (buffer-string) "\n")))))
+ lines))
+
+(defun lsp-ui-sideline--diagnostics (buffer bol eol)
+ "Show diagnostics belonging to the current line.
+Loop over flycheck errors with `flycheck-overlay-errors-in'.
+Find appropriate position for sideline overlays with `lsp-ui-sideline--find-line'.
+Push sideline overlays on `lsp-ui-sideline--ovs'."
+ (when (and (bound-and-true-p flycheck-mode)
+ (bound-and-true-p lsp-ui-sideline-mode)
+ lsp-ui-sideline-show-diagnostics
+ (eq (current-buffer) buffer))
+ (lsp-ui-sideline--delete-kind 'diagnostics)
+ (dolist (e (flycheck-overlay-errors-in bol (1+ eol)))
+ (let* ((lines (--> (flycheck-error-format-message-and-id e)
+ (split-string it "\n")
+ (lsp-ui-sideline--split-long-lines it)))
+ (display-lines (butlast lines (- (length lines) lsp-ui-sideline-diagnostic-max-lines)))
+ (offset 1))
+ (dolist (line (nreverse display-lines))
+ (let* ((msg (string-trim (replace-regexp-in-string "[\t ]+" " " line)))
+ (msg (replace-regexp-in-string " " " " msg))
+ (len (length msg))
+ (level (flycheck-error-level e))
+ (face (if (eq level 'info) 'success level))
+ (margin (lsp-ui-sideline--margin-width))
+ (msg (progn (add-face-text-property 0 len 'lsp-ui-sideline-global nil msg)
+ (add-face-text-property 0 len face nil msg)
+ msg))
+ (string (concat (propertize " " 'display `(space :align-to (- right-fringe ,(lsp-ui-sideline--align len margin))))
+ (propertize msg 'display (lsp-ui-sideline--compute-height))))
+ (pos-ov (lsp-ui-sideline--find-line len bol eol t offset))
+ (ov (and pos-ov (make-overlay (car pos-ov) (car pos-ov)))))
+ (when pos-ov
+ (setq offset (1+ (car (cdr pos-ov))))
+ (overlay-put ov 'after-string string)
+ (overlay-put ov 'kind 'diagnostics)
+ (overlay-put ov 'before-string " ")
+ (overlay-put ov 'position (car pos-ov))
+ (push ov lsp-ui-sideline--ovs))))))))
+
+(defun lsp-ui-sideline-apply-code-actions nil
+ "Choose and apply code action(s) on the current line."
+ (interactive)
+ (unless lsp-ui-sideline--code-actions
+ (user-error "No code actions on the current line"))
+ (lsp-execute-code-action (lsp--select-action lsp-ui-sideline--code-actions)))
+
+(defun lsp-ui-sideline-set-default-icon ()
+ "Set default icon for sideline actions."
+ (setq lsp-ui-sideline-actions-icon lsp-ui-sideline-actions-icon-default))
+
+(defun lsp-ui-sideline--scale-lightbulb (height)
+ "Scale the lightbulb image to character height.
+
+Argument HEIGHT is an actual image height in pixel."
+ (--> (- (frame-char-height) 1)
+ (/ (float it) height)))
+
+(defun lsp-ui-sideline--code-actions-make-image nil
+ (let ((is-default (equal lsp-ui-sideline-actions-icon lsp-ui-sideline-actions-icon-default)))
+ (--> `(image :type png :file ,lsp-ui-sideline-actions-icon :ascent center)
+ (append it `(:scale ,(->> (cond (is-default 128)
+ ((fboundp 'image-size) (cdr (image-size it t)))
+ (t (error "Function image-size undefined. Use default icon")))
+ (lsp-ui-sideline--scale-lightbulb)))))))
+
+(defun lsp-ui-sideline--code-actions-image nil
+ (when lsp-ui-sideline-actions-icon
+ (with-demoted-errors "[lsp-ui-sideline]: Error with actions icon: %s"
+ (concat
+ (propertize " " 'display (lsp-ui-sideline--code-actions-make-image))
+ (propertize " " 'display '(space :width 0.3))))))
+
+(defun lsp-ui-sideline--code-actions (actions bol eol)
+ "Show code ACTIONS."
+ (let ((inhibit-modification-hooks t))
+ (when lsp-ui-sideline-actions-kind-regex
+ (setq actions (seq-filter (-lambda ((&CodeAction :kind?))
+ (or (not kind?)
+ (s-match lsp-ui-sideline-actions-kind-regex kind?)))
+ actions)))
+ (setq lsp-ui-sideline--code-actions actions)
+ (lsp-ui-sideline--delete-kind 'actions)
+ (seq-doseq (action actions)
+ (-let* ((title (->> (lsp:code-action-title action)
+ (replace-regexp-in-string "[\n\t ]+" " ")
+ (replace-regexp-in-string " " " ")
+ (concat (unless lsp-ui-sideline-actions-icon
+ lsp-ui-sideline-code-actions-prefix))))
+ (image (lsp-ui-sideline--code-actions-image))
+ (margin (lsp-ui-sideline--margin-width))
+ (keymap (let ((map (make-sparse-keymap)))
+ (define-key map [down-mouse-1] (lambda () (interactive)
+ (save-excursion
+ (lsp-execute-code-action action))))
+ map))
+ (len (length title))
+ (title (progn (add-face-text-property 0 len 'lsp-ui-sideline-global nil title)
+ (add-face-text-property 0 len 'lsp-ui-sideline-code-action nil title)
+ (add-text-properties 0 len `(keymap ,keymap mouse-face highlight) title)
+ title))
+ (string (concat (propertize " " 'display `(space :align-to (- right-fringe ,(lsp-ui-sideline--align (+ len (length image)) margin))))
+ image
+ (propertize title 'display (lsp-ui-sideline--compute-height))))
+ (pos-ov (lsp-ui-sideline--find-line (+ 1 (length title) (length image)) bol eol t))
+ (ov (and pos-ov (make-overlay (car pos-ov) (car pos-ov)))))
+ (when pos-ov
+ (overlay-put ov 'after-string string)
+ (overlay-put ov 'before-string " ")
+ (overlay-put ov 'kind 'actions)
+ (overlay-put ov 'position (car pos-ov))
+ (push ov lsp-ui-sideline--ovs))))))
+
+(defun lsp-ui-sideline--calculate-tag nil
+ "Calculate the tag used to determine whether to update sideline information."
+ (let ((inhibit-field-text-motion t))
+ (list (point) (line-beginning-position) (line-end-position) (current-buffer))))
+
+(defun lsp-ui-sideline--delete-kind (kind)
+ (->> (--remove
+ (when (eq (overlay-get it 'kind) kind)
+ (--> (overlay-get it 'position)
+ (remq it lsp-ui-sideline--occupied-lines)
+ (setq lsp-ui-sideline--occupied-lines it))
+ (delete-overlay it)
+ t)
+ lsp-ui-sideline--ovs)
+ (setq lsp-ui-sideline--ovs)))
+
+(defvar-local lsp-ui-sideline--last-tick-info nil)
+(defvar-local lsp-ui-sideline--previous-line nil)
+
+(defun lsp-ui-sideline--get-line (bol eol)
+ (buffer-substring-no-properties bol eol))
+
+(defun lsp-ui-sideline--line-diags (line)
+ (->> (--filter
+ (let ((range (lsp-get it :range)))
+ (or (-some-> range (lsp-get :start) (lsp-get :line) (= line))
+ (-some-> range (lsp-get :end) (lsp-get :line) (= line))))
+ (lsp--get-buffer-diagnostics))
+ (apply 'vector)))
+
+(defun lsp-ui-sideline--run (&optional buffer bol eol this-line)
+ "Show information (flycheck + lsp).
+It loops on the symbols of the current line and requests information
+from the language server."
+ (when buffer-file-name
+ (let* ((inhibit-field-text-motion t)
+ (tag (lsp-ui-sideline--calculate-tag))
+ (eol (or eol (nth 2 tag)))
+ (bol (or bol (nth 1 tag)))
+ (this-tick (buffer-modified-tick))
+ (line-changed (not (lsp-ui-sideline--valid-tag-p lsp-ui-sideline--tag 'line)))
+ (line-widen (or (and (not line-changed) lsp-ui-sideline--last-line-number)
+ (and (buffer-narrowed-p) (save-restriction (widen) (line-number-at-pos)))
+ (line-number-at-pos)))
+ (new-tick (unless line-changed (not (equal this-tick lsp-ui-sideline--last-tick-info))))
+ (this-line (or this-line (lsp-ui-sideline--get-line bol eol)))
+ (line-modified (and new-tick (not (equal this-line lsp-ui-sideline--previous-line))))
+ (doc-id (lsp--text-document-identifier))
+ (inhibit-modification-hooks t)
+ symbols)
+ (setq lsp-ui-sideline--tag tag
+ lsp-ui-sideline--last-line-number line-widen
+ lsp-ui-sideline--last-width (window-text-width))
+ (when (and line-changed lsp-ui-sideline-show-diagnostics)
+ (lsp-ui-sideline--diagnostics buffer bol eol))
+ (when (and lsp-ui-sideline-show-code-actions
+ (or (lsp--capability "codeActionProvider")
+ (lsp--registered-capability "textDocument/codeAction")))
+ (lsp-request-async
+ "textDocument/codeAction"
+ (-let (((start . end) (if (eq lsp-ui-sideline-update-mode 'line)
+ (cons 0 (- eol bol))
+ (--> (- (point) bol) (cons it it)))))
+ (list :textDocument doc-id
+ :range (list :start (list :line (1- line-widen) :character start)
+ :end (list :line (1- line-widen) :character end))
+ :context (list :diagnostics (lsp-ui-sideline--line-diags (1- line-widen)))))
+ (lambda (actions)
+ (when (eq (current-buffer) buffer)
+ (lsp-ui-sideline--code-actions actions bol eol)))
+ :mode 'tick
+ :error-handler
+ (lambda (&rest _)
+ (lsp-ui-sideline--delete-kind 'actions))
+ :cancel-token :lsp-ui-code-actions))
+ ;; Go through all symbols and request hover information. Note that the symbols are
+ ;; traversed backwards as `forward-symbol' with a positive argument will jump just past the
+ ;; current symbol. By going from the end of the line towards the front, point will be placed
+ ;; at the beginning of each symbol. As the requests are first collected in a list before
+ ;; being processed they are still sent in order from left to right.
+ (when (and lsp-ui-sideline-show-hover (or line-changed line-modified) (lsp--capability "hoverProvider"))
+ (setq lsp-ui-sideline--last-tick-info this-tick
+ lsp-ui-sideline--previous-line this-line)
+ (save-excursion
+ (goto-char eol)
+ (while (and (> (point) bol)
+ (progn (forward-symbol -1)
+ (>= (point) bol)))
+ (let* ((symbol (thing-at-point 'symbol t))
+ (bounds (bounds-of-thing-at-point 'symbol))
+ (parsing-state (syntax-ppss))
+ (in-string (nth 3 parsing-state))
+ (outside-comment (eq (nth 4 parsing-state) nil)))
+ ;; Skip strings and comments
+ (when (and symbol (not in-string) outside-comment)
+ (push (list symbol bounds (list :line (1- line-widen) :character (- (point) bol))) symbols))))
+ (if (null symbols)
+ (lsp-ui-sideline--delete-kind 'info)
+ (let ((length-symbols (length symbols))
+ (current-index 0)
+ list-infos)
+ (--each symbols
+ (-let (((symbol bounds position) it))
+ (lsp-request-async
+ "textDocument/hover"
+ (lsp-make-hover-params :text-document doc-id :position position)
+ (lambda (info)
+ (cl-incf current-index)
+ (and info (push (list symbol bounds info) list-infos))
+ (when (or (= current-index length-symbols) (not lsp-ui-sideline-wait-for-all-symbols))
+ (lsp-ui-sideline--display-all-info list-infos tag bol eol)))
+ :error-handler
+ (lambda (&rest _)
+ (cl-incf current-index)
+ (when (or (= current-index length-symbols) (not lsp-ui-sideline-wait-for-all-symbols))
+ (lsp-ui-sideline--display-all-info list-infos tag bol eol)))
+ :mode 'tick))))))))))
+
+(defun lsp-ui-sideline--stop-p ()
+ "Return non-nil if the sideline should not be display."
+ (or (region-active-p)
+ (bound-and-true-p company-pseudo-tooltip-overlay)
+ (bound-and-true-p lsp-ui-peek--overlay)))
+
+(defun lsp-ui-sideline--hide-before-company (command)
+ "Disable the sideline before company's overlay appears.
+COMMAND is `company-pseudo-tooltip-frontend' parameter."
+ (when (memq command '(post-command update))
+ (lsp-ui-sideline--delete-ov)))
+
+(defun lsp-ui-sideline ()
+ "Show information for the current line."
+ (if (lsp-ui-sideline--stop-p)
+ (lsp-ui-sideline--delete-ov)
+ (let* ((inhibit-field-text-motion t)
+ (same-line (lsp-ui-sideline--valid-tag-p lsp-ui-sideline--tag 'line))
+ (same-width (equal (window-text-width) lsp-ui-sideline--last-width))
+ (new-tick (and same-line (not (equal (buffer-modified-tick) lsp-ui-sideline--last-tick-info))))
+ (bol (and new-tick (line-beginning-position)))
+ (eol (and new-tick (line-end-position)))
+ (this-line (and new-tick (lsp-ui-sideline--get-line bol eol)))
+ (unmodified (if new-tick (equal this-line lsp-ui-sideline--previous-line) t))
+ (buffer (current-buffer))
+ (point (point)))
+ (cond ((and unmodified same-line same-width)
+ (lsp-ui-sideline--highlight-current (point)))
+ ((not (and same-line same-width))
+ (lsp-ui-sideline--delete-ov)))
+ (when lsp-ui-sideline--timer
+ (cancel-timer lsp-ui-sideline--timer))
+ (setq lsp-ui-sideline--timer
+ (run-with-idle-timer
+ lsp-ui-sideline-delay nil
+ (lambda nil
+ ;; run lsp-ui only if current-buffer is the same.
+ (and (eq buffer (current-buffer))
+ (= point (point))
+ (lsp-ui-sideline--run buffer bol eol this-line))))))))
+
+(defun lsp-ui-sideline-toggle-symbols-info ()
+ "Toggle display of symbols information.
+This does not toggle display of flycheck diagnostics or code actions."
+ (interactive)
+ (when (bound-and-true-p lsp-ui-sideline-mode)
+ (setq lsp-ui-sideline-show-hover (not lsp-ui-sideline-show-hover))
+ (lsp-ui-sideline--run (current-buffer))))
+
+(defun lsp-ui-sideline--diagnostics-changed ()
+ "Handler for flycheck notifications."
+ (when lsp-ui-sideline-show-diagnostics
+ (let* ((buffer (current-buffer))
+ (inhibit-field-text-motion t)
+ (eol (line-end-position))
+ (bol (line-beginning-position)))
+ (lsp-ui-sideline--diagnostics buffer bol eol))))
+
+(defun lsp-ui-sideline--erase (&rest _)
+ "Remove all sideline overlays and delete last tag."
+ (when (bound-and-true-p lsp-ui-sideline-mode)
+ (ignore-errors (lsp-ui-sideline--delete-ov))))
+
+(define-minor-mode lsp-ui-sideline-mode
+ "Minor mode for showing information for current line."
+ :init-value nil
+ :group lsp-ui-sideline
+ (cond
+ (lsp-ui-sideline-mode
+ (add-hook 'post-command-hook 'lsp-ui-sideline nil t)
+ (advice-add 'company-pseudo-tooltip-frontend :before 'lsp-ui-sideline--hide-before-company)
+ (add-hook 'flycheck-after-syntax-check-hook 'lsp-ui-sideline--diagnostics-changed nil t)
+ (when lsp-ui-sideline-show-diagnostics
+ (setq-local flycheck-display-errors-function nil)))
+ (t
+ (advice-remove 'company-pseudo-tooltip-frontend 'lsp-ui-sideline--hide-before-company)
+ (lsp-ui-sideline--delete-ov)
+ (remove-hook 'flycheck-after-syntax-check-hook 'lsp-ui-sideline--diagnostics-changed t)
+ (remove-hook 'post-command-hook 'lsp-ui-sideline t)
+ (when lsp-ui-sideline-show-diagnostics
+ (kill-local-variable 'flycheck-display-errors-function)))))
+
+(defun lsp-ui-sideline-enable (enable)
+ "Enable/disable `lsp-ui-sideline-mode'."
+ (lsp-ui-sideline-mode (if enable 1 -1))
+ (if enable
+ (add-hook 'before-revert-hook 'lsp-ui-sideline--delete-ov nil t)
+ (remove-hook 'before-revert-hook 'lsp-ui-sideline--delete-ov t)))
+
+(provide 'lsp-ui-sideline)
+;;; lsp-ui-sideline.el ends here
diff --git a/elpa/lsp-ui-20220425.1046/lsp-ui-sideline.elc b/elpa/lsp-ui-20220425.1046/lsp-ui-sideline.elc
new file mode 100644
index 0000000..914b9f0
--- /dev/null
+++ b/elpa/lsp-ui-20220425.1046/lsp-ui-sideline.elc
Binary files differ
diff --git a/elpa/lsp-ui-20220425.1046/lsp-ui-util.el b/elpa/lsp-ui-20220425.1046/lsp-ui-util.el
new file mode 100644
index 0000000..a5d92f2
--- /dev/null
+++ b/elpa/lsp-ui-20220425.1046/lsp-ui-util.el
@@ -0,0 +1,71 @@
+;;; lsp-ui-util.el --- Utility module for Lsp-Ui -*- lexical-binding: t -*-
+
+;; Copyright (C) 2020 Shen, Jen-Chieh
+
+;; Author: Jen-Chieh Shen <jcs090218@gmail.com>
+;; URL: https://github.com/emacs-lsp/lsp-ui
+;; Keywords: languages, tools
+;; Version: 6.2
+
+;;; License
+;;
+;; 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:
+
+;;
+;; Utility module for Lsp-Ui.
+;;
+
+;;; Code:
+
+(require 'face-remap)
+
+(defun lsp-ui-util-safe-kill-timer (timer)
+ "Safely kill the TIMER."
+ (when (timerp timer) (cancel-timer timer)))
+
+(defun lsp-ui-util-safe-delete-overlay (overlay)
+ "Safely delete the OVERLAY."
+ (when (overlayp overlay) (delete-overlay overlay)))
+
+(defun lsp-ui-util-line-number-display-width ()
+ "Safe way to get value from function `line-number-display-width'."
+ (if (bound-and-true-p display-line-numbers-mode)
+ ;; For some reason, function `line-number-display-width' gave
+ ;; us error `args-out-of-range' even we do not pass anything towards
+ ;; to it function. See the following links,
+ ;;
+ ;; - https://github.com/emacs-lsp/lsp-ui/issues/294
+ ;; - https://github.com/emacs-lsp/lsp-ui/issues/533 (duplicate)
+ (+ (or (ignore-errors (line-number-display-width)) 0) 2)
+ 0))
+
+(defun lsp-ui-util-line-string (pos)
+ "Return string at POS."
+ (when (integerp pos) (save-excursion (goto-char pos) (thing-at-point 'line))))
+
+(defun lsp-ui-util-column (&optional pos)
+ "Return column at POS."
+ (setq pos (or pos (point)))
+ (save-excursion (goto-char pos) (current-column)))
+
+(defun lsp-ui-util-text-scale-factor ()
+ "Return the factor effect by `text-scale-mode'."
+ (or (plist-get (cdr text-scale-mode-remapping) :height) 1))
+
+(provide 'lsp-ui-util)
+;;; lsp-ui-util.el ends here
diff --git a/elpa/lsp-ui-20220425.1046/lsp-ui-util.elc b/elpa/lsp-ui-20220425.1046/lsp-ui-util.elc
new file mode 100644
index 0000000..a0f1f41
--- /dev/null
+++ b/elpa/lsp-ui-20220425.1046/lsp-ui-util.elc
Binary files differ
diff --git a/elpa/lsp-ui-20220425.1046/lsp-ui.el b/elpa/lsp-ui-20220425.1046/lsp-ui.el
new file mode 100644
index 0000000..bed2de7
--- /dev/null
+++ b/elpa/lsp-ui-20220425.1046/lsp-ui.el
@@ -0,0 +1,177 @@
+;;; lsp-ui.el --- UI modules for lsp-mode -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2017 Tobias Pisani
+;; Copyright (C) 2018 Sebastien Chapuis, Fangrui Song
+
+;; Author: Sebastien Chapuis <sebastien@chapu.is>, Fangrui Song <i@maskray.me>
+;; Keywords: languages, tools
+;; URL: https://github.com/emacs-lsp/lsp-ui
+;; Package-Requires: ((emacs "26.1") (dash "2.18.0") (lsp-mode "6.0") (markdown-mode "2.3"))
+;; Version: 8.0.0
+
+;;; License
+;;
+;; 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:
+
+;; lsp-ui contains a series of useful UI integrations for lsp-mode, like
+;; flycheck support and code lenses.
+
+;;; Code:
+
+(require 'dash)
+(require 'lsp-protocol)
+(require 'find-func)
+
+(defconst lsp-ui-resources-dir
+ (--> (or load-file-name (buffer-file-name))
+ (file-name-directory it)
+ (expand-file-name "resources" it)
+ (file-name-as-directory it)
+ (and (file-directory-p it) it))
+ "Resource folder for package `lsp-ui'.")
+
+(require 'lsp-ui-sideline)
+(require 'lsp-ui-peek)
+(require 'lsp-ui-imenu)
+(require 'lsp-ui-doc)
+
+(defgroup lsp-ui nil
+ "‘lsp-ui’ contains a series of useful UI integrations for ‘lsp-mode’."
+ :group 'tools
+ :group 'convenience
+ :link '(custom-manual "(lsp-ui) Top")
+ :link '(info-link "(lsp-ui) Customizing"))
+
+(with-eval-after-load 'flycheck
+ (require 'lsp-ui-flycheck))
+
+(with-eval-after-load 'winum
+ (when (and (boundp 'winum-ignored-buffers-regexp) lsp-ui-doc-winum-ignore)
+ (add-to-list 'winum-ignored-buffers-regexp lsp-ui-doc--buffer-prefix)))
+
+(defun lsp-ui-peek--render (major string)
+ (with-temp-buffer
+ (insert string)
+ (delay-mode-hooks
+ (let ((inhibit-message t)) (funcall major))
+ (ignore-errors (font-lock-ensure)))
+ (buffer-string)))
+
+(defun lsp-ui--workspace-path (path)
+ "Return the PATH relative to the workspace.
+If the PATH is not in the workspace, it returns the original PATH."
+ (let* ((path (file-truename path))
+ (root (lsp-workspace-root path))
+ (in-workspace (and root (string-prefix-p root path))))
+ (if in-workspace
+ (substring path (length root))
+ path)))
+
+(defun lsp-ui--toggle (enable)
+ (dolist (feature '(lsp-ui-peek lsp-ui-sideline lsp-ui-doc lsp-ui-imenu))
+ (let* ((sym (--> (intern-soft (concat (symbol-name feature) "-enable"))
+ (and (boundp it) it)))
+ (value (symbol-value sym))
+ (fn (symbol-function sym)))
+ (and (or value (not enable))
+ (functionp fn)
+ (funcall fn enable)))))
+
+(defvar lsp-ui-mode-map (make-sparse-keymap))
+
+;;;###autoload
+(define-minor-mode lsp-ui-mode
+ "Toggle language server UI mode on or off.
+‘lsp-ui-mode’ is a minor mode that contains a series of useful UI
+integrations for ‘lsp-mode’. With a prefix argument ARG, enable
+language server UI mode if ARG is positive, and disable it
+otherwise. If called from Lisp, enable the mode if ARG is
+omitted or nil, and toggle it if ARG is ‘toggle’."
+ :init-value nil
+ :group lsp-ui
+ :keymap lsp-ui-mode-map
+ (lsp-ui--toggle lsp-ui-mode))
+
+;; The request is delegated to xref-backend-apropos defined in lsp-mode.
+;; xref-find-apropos does similar job but is less appealing because it splits and
+;; regex quotes the pattern. The language server likely knows more about how
+;; to do fuzzy matching.
+(defun lsp-ui-find-workspace-symbol (pattern)
+ "List project-wide symbols matching the query string PATTERN."
+ (interactive (list (read-string
+ "workspace/symbol: "
+ nil 'xref--read-pattern-history)))
+ (xref--find-xrefs pattern 'apropos pattern nil))
+
+(defun lsp-ui--location< (x y)
+ "Compares two triples X and Y.
+Both should have the form (FILENAME LINE COLUMN)."
+ (if (not (string= (car x) (car y)))
+ (string< (car x) (car y))
+ (if (not (= (cadr x) (cadr y)))
+ (< (cadr x) (cadr y))
+ (< (caddr x) (caddr y)))))
+
+(defun lsp-ui--reference-triples (include-declaration)
+ "Return references as a list of (FILENAME LINE COLUMN) triples given EXTRA."
+ (let ((refs (lsp-request "textDocument/references"
+ (lsp--make-reference-params nil include-declaration))))
+ (sort
+ (mapcar
+ (-lambda ((&Location :uri :range (&Range :start (&Position :line :character))))
+ (list (lsp--uri-to-path uri) line character))
+ refs)
+ #'lsp-ui--location<)))
+
+;; TODO Make it efficient
+(defun lsp-ui-find-next-reference (&optional include-declaration)
+ "Find next reference of the symbol at point."
+ (interactive)
+ (let* ((cur (list buffer-file-name (1- (line-number-at-pos)) (- (point) (line-beginning-position))))
+ (refs (lsp-ui--reference-triples include-declaration))
+ (idx -1)
+ (res (-first (lambda (ref) (cl-incf idx) (lsp-ui--location< cur ref)) refs)))
+ (if res
+ (progn
+ (find-file (car res))
+ (goto-char 1)
+ (forward-line (cadr res))
+ (forward-char (caddr res))
+ (cons idx (length refs)))
+ (cons 0 0))))
+
+;; TODO Make it efficient
+(defun lsp-ui-find-prev-reference (&optional include-declaration)
+ "Find previous reference of the symbol at point."
+ (interactive)
+ (let* ((cur (list buffer-file-name (1- (line-number-at-pos)) (- (point) (line-beginning-position))))
+ (refs (lsp-ui--reference-triples include-declaration))
+ (idx -1)
+ (res (-last (lambda (ref) (and (lsp-ui--location< ref cur) (cl-incf idx))) refs)))
+ (if res
+ (progn
+ (find-file (car res))
+ (goto-char 1)
+ (forward-line (cadr res))
+ (forward-char (caddr res))
+ (cons idx (length refs)))
+ (cons 0 0))))
+
+
+(provide 'lsp-ui)
+;;; lsp-ui.el ends here
diff --git a/elpa/lsp-ui-20220425.1046/lsp-ui.elc b/elpa/lsp-ui-20220425.1046/lsp-ui.elc
new file mode 100644
index 0000000..bba4345
--- /dev/null
+++ b/elpa/lsp-ui-20220425.1046/lsp-ui.elc
Binary files differ
diff --git a/elpa/lsp-ui-20220425.1046/resources/lightbulb.png b/elpa/lsp-ui-20220425.1046/resources/lightbulb.png
new file mode 100644
index 0000000..7c1ad08
--- /dev/null
+++ b/elpa/lsp-ui-20220425.1046/resources/lightbulb.png
Binary files differ
diff --git a/elpa/lv-20200507.1518/lv-autoloads.el b/elpa/lv-20200507.1518/lv-autoloads.el
new file mode 100644
index 0000000..992b227
--- /dev/null
+++ b/elpa/lv-20200507.1518/lv-autoloads.el
@@ -0,0 +1,22 @@
+;;; lv-autoloads.el --- automatically extracted autoloads -*- lexical-binding: t -*-
+;;
+;;; Code:
+
+(add-to-list 'load-path (directory-file-name
+ (or (file-name-directory #$) (car load-path))))
+
+
+;;;### (autoloads nil "lv" "lv.el" (0 0 0 0))
+;;; Generated autoloads from lv.el
+
+(register-definition-prefixes "lv" '("lv-"))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; coding: utf-8
+;; End:
+;;; lv-autoloads.el ends here
diff --git a/elpa/lv-20200507.1518/lv-pkg.el b/elpa/lv-20200507.1518/lv-pkg.el
new file mode 100644
index 0000000..b196d26
--- /dev/null
+++ b/elpa/lv-20200507.1518/lv-pkg.el
@@ -0,0 +1,2 @@
+;;; Generated package description from lv.el -*- no-byte-compile: t -*-
+(define-package "lv" "20200507.1518" "Other echo area" 'nil :commit "9e9e00cb240ea1903ffd36a54956b3902c379d29" :authors '(("Oleh Krehel")) :maintainer '("Oleh Krehel"))
diff --git a/elpa/lv-20200507.1518/lv.el b/elpa/lv-20200507.1518/lv.el
new file mode 100644
index 0000000..1e62477
--- /dev/null
+++ b/elpa/lv-20200507.1518/lv.el
@@ -0,0 +1,150 @@
+;;; lv.el --- Other echo area
+;; Package-Version: 20200507.1518
+;; Package-Commit: 9e9e00cb240ea1903ffd36a54956b3902c379d29
+
+;; Copyright (C) 2015 Free Software Foundation, Inc.
+
+;; Author: Oleh Krehel
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs 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.
+
+;; GNU Emacs 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 GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;
+;; This package provides `lv-message' intended to be used in place of
+;; `message' when semi-permanent hints are needed, in order to not
+;; interfere with Echo Area.
+;;
+;; "Я тихо-тихо пiдглядаю,
+;; І тiшуся собi, як бачу то,
+;; Шо страшить i не пiдпускає,
+;; А iншi п’ють тебе, як воду пiсок."
+;; -- Андрій Кузьменко, L.V.
+
+;;; Code:
+
+(require 'cl-lib)
+
+(defgroup lv nil
+ "The other echo area."
+ :group 'minibuffer
+ :group 'hydra)
+
+(defcustom lv-use-separator nil
+ "Whether to draw a line between the LV window and the Echo Area."
+ :group 'lv
+ :type 'boolean)
+
+(defcustom lv-use-padding nil
+ "Whether to use horizontal padding in the LV window."
+ :group 'lv
+ :type 'boolean)
+
+(defface lv-separator
+ '((((class color) (background light)) :background "grey80")
+ (((class color) (background dark)) :background "grey30"))
+ "Face used to draw line between the lv window and the echo area.
+This is only used if option `lv-use-separator' is non-nil.
+Only the background color is significant."
+ :group 'lv)
+
+(defvar lv-wnd nil
+ "Holds the current LV window.")
+
+(defvar display-line-numbers)
+(defvar display-fill-column-indicator)
+(defvar tab-line-format)
+
+(defvar lv-window-hook nil
+ "Hook to run by `lv-window' when a new window is created.")
+
+(defun lv-window ()
+ "Ensure that LV window is live and return it."
+ (if (window-live-p lv-wnd)
+ lv-wnd
+ (let ((ori (selected-window))
+ buf)
+ (prog1 (setq lv-wnd
+ (select-window
+ (let ((ignore-window-parameters t))
+ (split-window
+ (frame-root-window) -1 'below))
+ 'norecord))
+ (if (setq buf (get-buffer " *LV*"))
+ (switch-to-buffer buf 'norecord)
+ (switch-to-buffer " *LV*" 'norecord)
+ (fundamental-mode)
+ (set-window-hscroll lv-wnd 0)
+ (setq window-size-fixed t)
+ (setq mode-line-format nil)
+ (setq header-line-format nil)
+ (setq tab-line-format nil)
+ (setq cursor-type nil)
+ (setq display-line-numbers nil)
+ (setq display-fill-column-indicator nil)
+ (set-window-dedicated-p lv-wnd t)
+ (set-window-parameter lv-wnd 'no-other-window t)
+ (run-hooks 'lv-window-hook))
+ (select-window ori 'norecord)))))
+
+(defvar golden-ratio-mode)
+
+(defvar lv-force-update nil
+ "When non-nil, `lv-message' will refresh even for the same string.")
+
+(defun lv--pad-to-center (str width)
+ "Pad STR with spaces on the left to be centered to WIDTH."
+ (let* ((strs (split-string str "\n"))
+ (padding (make-string
+ (/ (- width (length (car strs))) 2)
+ ?\ )))
+ (mapconcat (lambda (s) (concat padding s)) strs "\n")))
+
+(defun lv-message (format-string &rest args)
+ "Set LV window contents to (`format' FORMAT-STRING ARGS)."
+ (let* ((str (apply #'format format-string args))
+ (n-lines (cl-count ?\n str))
+ deactivate-mark
+ golden-ratio-mode)
+ (with-selected-window (lv-window)
+ (when lv-use-padding
+ (setq str (lv--pad-to-center str (window-width))))
+ (unless (and (string= (buffer-string) str)
+ (null lv-force-update))
+ (delete-region (point-min) (point-max))
+ (insert str)
+ (when (and (window-system) lv-use-separator)
+ (unless (looking-back "\n" nil)
+ (insert "\n"))
+ (insert
+ (propertize "__" 'face 'lv-separator 'display '(space :height (1)))
+ (propertize "\n" 'face 'lv-separator 'line-height t)))
+ (set (make-local-variable 'window-min-height) n-lines)
+ (setq truncate-lines (> n-lines 1))
+ (let ((window-resize-pixelwise t)
+ (window-size-fixed nil))
+ (fit-window-to-buffer nil nil 1)))
+ (goto-char (point-min)))))
+
+(defun lv-delete-window ()
+ "Delete LV window and kill its buffer."
+ (when (window-live-p lv-wnd)
+ (let ((buf (window-buffer lv-wnd)))
+ (delete-window lv-wnd)
+ (kill-buffer buf))))
+
+(provide 'lv)
+
+;;; lv.el ends here
diff --git a/elpa/lv-20200507.1518/lv.elc b/elpa/lv-20200507.1518/lv.elc
new file mode 100644
index 0000000..b7ef959
--- /dev/null
+++ b/elpa/lv-20200507.1518/lv.elc
Binary files differ
diff --git a/elpa/magit-20220503.1245/AUTHORS.md b/elpa/magit-20220503.1245/AUTHORS.md
new file mode 100644
index 0000000..5eba575
--- /dev/null
+++ b/elpa/magit-20220503.1245/AUTHORS.md
@@ -0,0 +1,386 @@
+The following people have contributed to Magit, including the
+libraries `git-commit.el`, `magit-popup.el`, and `with-editor.el`
+which are distributed as separate Elpa packages.
+
+For statistics see https://magit.vc/stats/magit/authors.html.
+
+Authors
+-------
+
+- Marius Vollmer
+- Jonas Bernoulli
+
+Active Maintainers
+------------------
+
+- Jonas Bernoulli
+- Kyle Meyer
+
+Former Maintainers
+------------------
+
+- Nicolas Dudebout
+- Noam Postavsky
+- Peter J. Weisberg
+- Phil Jackson
+- Rémi Vanicat
+- Yann Hodique
+
+All Contributors
+----------------
+
+- Aaron Culich
+- Aaron L. Zeng
+- Aaron Madlon-Kay
+- Abdo Roig-Maranges
+- Adam Benanti
+- Adam Kruszewski
+- Adam Porter
+- Adam Spiers
+- Adeodato Simó
+- Ævar Arnfjörð Bjarmason
+- Alan Falloon
+- Alban Gruin
+- Aleksey Uimanov
+- Alexander Gramiak
+- Alexander Miller
+- Alex Branham
+- Alex Dunn
+- Alexey Voinov
+- Alex Kost
+- Alex Ott
+- Allen Li
+- Andreas Fuchs
+- Andreas Liljeqvist
+- Andreas Rottmann
+- Andrei Chițu
+- Andrew Eggenberger
+- Andrew Kirkpatrick
+- Andrew Psaltis
+- Andrew Schwartzmeyer
+- Andrey Smirnov
+- Andriy Kmit'
+- Andy Sawyer
+- Angel de Vicente
+- Aria Edmonds
+- Arialdo Martini
+- Arnau Roig Ninerola
+- Ashlynn Anderson
+- Barak A. Pearlmutter
+- Bar Magal
+- Bart Bakker
+- Basil L. Contovounesios
+- Bastian Beischer
+- Bastian Beranek
+- Benjamin Motz
+- Ben North
+- Ben Walton
+- Bob Uhl
+- Boruch Baum
+- Bradley Wright
+- Brandon W Maister
+- Brennan Vincent
+- Brian Leung
+- Brian Warner
+- Bryan Shell
+- Buster Copley
+- Cameron Chaparro
+- Carl Lieberman
+- Chillar Anand
+- Chris Bernard
+- Chris Done
+- Chris LaRose
+- Chris Moore
+- Chris Ring
+- Chris Shoemaker
+- Christian Dietrich
+- Christian Kluge
+- Christophe Junke
+- Christopher Monsanto
+- Clément Pit-Claudel
+- Cornelius Mika
+- Craig Andera
+- Dale Hagglund
+- Damien Cassou
+- Dan Davison
+- Dan Erikson
+- Daniel Brockman
+- Daniel Farina
+- Daniel Fleischer
+- Daniel Gröber
+- Daniel Hackney
+- Daniel Kraus
+- Daniel Mai
+- Daniel Martín
+- Daniel Nagy
+- Dan Kessler
+- Dan LaManna
+- Danny Zhu
+- Dato Simó
+- David Abrahams
+- David Ellison
+- David Hull
+- David L. Rager
+- David Wallin
+- Dean Kariniemi
+- Dennis Paskorz
+- Divye Kapoor
+- Dominique Quatravaux
+- Duianto Vebotci
+- Eli Barzilay
+- Eric
+- Eric Davis
+- Eric Prud'hommeaux
+- Eric Schulte
+- Erik Anderson
+- Evan Torrie
+- Evgkeni Sampelnikof
+- Eyal Lotem
+- Fabian Wiget
+- Felix Geller
+- Felix Yan
+- Feng Li
+- Florian Ragwitz
+- Franklin Delehelle
+- Frédéric Giquel
+- Fritz Grabo
+- Fritz Stelzer
+- Geoff Shannon
+- George Kadianakis
+- Géza Herman
+- Graham Clark
+- Graham Dobbins
+- Greg A. Woods
+- Greg Lucas
+- Gregory Heytings
+- Greg Sexton
+- Greg Steuck
+- Guillaume Martres
+- Hannu Koivisto
+- Hans-Peter Deifel
+- Hussein Ait-Lahcen
+- Ian Eure
+- Ian Milligan
+- Ilya Grigoriev
+- Ingmar Sittl
+- Ingo Lohmar
+- Ioan-Adrian Ratiu
+- Ivan Brennan
+- Jan Tatarik
+- Jasper St. Pierre
+- Jean-Louis Giordano
+- Jeff Bellegarde
+- Jeff Dairiki
+- Jeremy Meng
+- Jesse Alama
+- Jim Blandy
+- Joakim Jalap
+- Johannes Altmanninger
+- Johann Klähn
+- John Mastro
+- John Morris
+- John Wiegley
+- Jonas Bernoulli
+- Jonas Galvão Xavier
+- Jonathan Arnett
+- Jonathan del Strother
+- Jonathan Leech-Pepin
+- Jonathan Roes
+- Jonathon McKitrick
+- Jon Vanderwijk
+- Jordan Galby
+- Jordan Greenberg
+- Jorge Israel Peña
+- Josh Elsasser
+- Josiah Schwab
+- Julien Danjou
+- Justin Burkett
+- Justin Caratzas
+- Justin Guenther
+- Justin Thomas
+- Kan-Ru Chen
+- Kenny Ballou
+- Keshav Kini
+- Kevin Brubeck Unhammer
+- Kevin J. Foley
+- Kévin Le Gouguec
+- Kimberly Wolk
+- Knut Olav Bøhmer
+- Kyle Meyer
+- Laurent Laffont
+- Laverne Schrock
+- Leandro Facchinetti
+- Lele Gaifax
+- Leo Liu
+- Leonardo Etcheverry
+- Leo Vivier
+- Lingchao Xin
+- Lin Sun
+- Li-Yun Chang
+- Lluís Vilanova
+- Loic Dachary
+- Louis Roché
+- Luís Oliveira
+- Luke Amdor
+- Magnus Malm
+- Mak Kolybabi
+- Manuel Vázquez Acosta
+- Marcel Wolf
+- Marc Herbert
+- Marcin Bachry
+- Marco Craveiro
+- Marco Wahl
+- Marc Sherry
+- Marian Schubert
+- Mario Rodas
+- Marius Vollmer
+- Mark Hepburn
+- Mark Karpov
+- Mark Oteiza
+- Martin Joerg
+- Martin Polden
+- Matthew Fluet
+- Matthew Kraai
+- Matthieu Hauglustaine
+- Matus Goljer
+- Maxim Cournoyer
+- Michael Fogleman
+- Michael Griffiths
+- Michael Heerdegen
+- Michal Sojka
+- Miciah Masters
+- Miles Bader
+- Miloš Mošić
+- Mitchel Humpherys
+- Moritz Bunkus
+- Naoya Yamashita
+- Natalie Weizenbaum
+- Nguyễn Tuấn Anh
+- Nic Ferier
+- Nick Alcock
+- Nick Alexander
+- Nick Dimiduk
+- Nicklas Lindgren
+- Nicolas Dudebout
+- Nicolas Petton
+- Nicolas Richard
+- Nikolay Martynov
+- Noam Postavsky
+- N. Troy de Freitas
+- Ola x Nilsson
+- Ole Arndt
+- Oleh Krehel
+- Orivej Desh
+- Óscar Fuentes
+- Pancho Horrillo
+- Paul Stadig
+- Pavel Holejsovsky
+- Pekka Pessi
+- Peter Eisentraut
+- Peter Jaros
+- Peter J. Weisberg
+- Peter Vasil
+- Philippe Cavalaria
+- Philippe Vaucher
+- Philipp Fehre
+- Philipp Haselwarter
+- Philipp Stephani
+- Philip Weaver
+- Phil Jackson
+- Phil Sainty
+- Pierre Neidhardt
+- Pieter Praet
+- Prathamesh Sonpatki
+- Pritam Baral
+- rabio
+- Radon Rosborough
+- Rafael Laboissiere
+- Raimon Grau
+- Ramkumar Ramachandra
+- Remco van 't Veer
+- Rémi Vanicat
+- René Stadler
+- Richard Kim
+- Robert Boone
+- Robert Irelan
+- Robin Green
+- Roey Darwish Dror
+- Roger Crew
+- Romain Francoise
+- Ron Parker
+- Roy Crihfield
+- Rüdiger Sonderfeld
+- Russell Black
+- Ryan C. Thompson
+- Sam Cedarbaum
+- Samuel Bronson
+- Samuel W. Flint
+- Sanjoy Das
+- Sean Allred
+- Sean Bryant
+- Sean Whitton
+- Sebastian Wiesner
+- Sébastien Gross
+- Seong-Kook Shin
+- Sergey Pashinin
+- Sergey Vinokurov
+- Servilio Afre Puentes
+- Shuguang Sun
+- Siavash Askari Nasr
+- Silent Sphere
+- Simon Pintarelli
+- Stefan Kangas
+- Štěpán Němec
+- Steven Chow
+- Steven E. Harris
+- Steven Thomas
+- Steven Vancoillie
+- Steve Purcell
+- Suhail Shergill
+- Sylvain Rousseau
+- Syohei Yoshida
+- Szunti
+- Takafumi Arakaki
+- Tassilo Horn
+- TEC
+- Teemu Likonen
+- Teruki Shigitani
+- Thierry Volpiatto
+- Thomas A Caswell
+- Thomas Fini Hansen
+- Thomas Frössman
+- Thomas Jost
+- Thomas Riccardi
+- Tibor Simko
+- Timo Juhani Lindfors
+- Tim Perkins
+- Tim Wraight
+- Ting-Yu Lin
+- Tom Feist
+- Toon Claes
+- Topi Miettinen
+- Troy Hinckley
+- Tsuyoshi Kitamoto
+- Tunc Uzlu
+- Vineet Naik
+- Vitaly Ostashov
+- Vladimir Ivanov
+- Vladimir Panteleev
+- Vladimir Sedach
+- Wei Huang
+- Wilfred Hughes
+- Win Treese
+- Wojciech Siewierski
+- Wouter Bolsterlee
+- Xavier Noria
+- Xu Chunyang
+- Yann Herklotz
+- Yann Hodique
+- Ynilu
+- York Zhao
+- Yuichi Higashi
+- Yuri Khan
+- Zach Latta
+- zakora
+- Zhu Zihao
+- zilongshanren
diff --git a/elpa/magit-20220503.1245/LICENSE b/elpa/magit-20220503.1245/LICENSE
new file mode 100644
index 0000000..f288702
--- /dev/null
+++ b/elpa/magit-20220503.1245/LICENSE
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ 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 <https://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ <program> Copyright (C) <year> <name of author>
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<https://www.gnu.org/licenses/>.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+<https://www.gnu.org/licenses/why-not-lgpl.html>.
diff --git a/elpa/magit-20220503.1245/dir b/elpa/magit-20220503.1245/dir
new file mode 100644
index 0000000..dfdbd71
--- /dev/null
+++ b/elpa/magit-20220503.1245/dir
@@ -0,0 +1,18 @@
+This is the file .../info/dir, which contains the
+topmost node of the Info hierarchy, called (dir)Top.
+The first time you invoke Info you start off looking at this node.
+
+File: dir, Node: Top This is the top of the INFO tree
+
+ This (the Directory node) gives a menu of major topics.
+ Typing "q" exits, "H" lists all Info commands, "d" returns here,
+ "h" gives a primer for first-timers,
+ "mEmacs<Return>" visits the Emacs manual, etc.
+
+ In Emacs, you can click mouse button 2 on a menu item or cross reference
+ to select it.
+
+* Menu:
+
+Emacs
+* Magit: (magit). Using Git from Emacs with Magit.
diff --git a/elpa/magit-20220503.1245/git-rebase.el b/elpa/magit-20220503.1245/git-rebase.el
new file mode 100644
index 0000000..0feb9d0
--- /dev/null
+++ b/elpa/magit-20220503.1245/git-rebase.el
@@ -0,0 +1,848 @@
+;;; git-rebase.el --- Edit Git rebase files -*- lexical-binding:t -*-
+
+;; Copyright (C) 2008-2022 The Magit Project Contributors
+
+;; Author: Phil Jackson <phil@shellarchive.co.uk>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+
+;; SPDX-License-Identifier: GPL-3.0-or-later
+
+;; Magit 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.
+;;
+;; Magit 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 Magit. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This package assists the user in editing the list of commits to be
+;; rewritten during an interactive rebase.
+
+;; When the user initiates an interactive rebase, e.g. using "r e" in
+;; a Magit buffer or on the command line using "git rebase -i REV",
+;; Git invokes the `$GIT_SEQUENCE_EDITOR' (or if that is undefined
+;; `$GIT_EDITOR' or even `$EDITOR') letting the user rearrange, drop,
+;; reword, edit, and squash commits.
+
+;; This package provides the major-mode `git-rebase-mode' which makes
+;; doing so much more fun, by making the buffer more colorful and
+;; providing the following commands:
+;;
+;; C-c C-c Tell Git to make it happen.
+;; C-c C-k Tell Git that you changed your mind, i.e. abort.
+;;
+;; p Move point to previous line.
+;; n Move point to next line.
+;;
+;; M-p Move the commit at point up.
+;; M-n Move the commit at point down.
+;;
+;; k Drop the commit at point.
+;; c Don't drop the commit at point.
+;; r Change the message of the commit at point.
+;; e Edit the commit at point.
+;; s Squash the commit at point, into the one above.
+;; f Like "s" but don't also edit the commit message.
+;; b Break for editing at this point in the sequence.
+;; x Add a script to be run with the commit at point
+;; being checked out.
+;; z Add noop action at point.
+;;
+;; SPC Show the commit at point in another buffer.
+;; RET Show the commit at point in another buffer and
+;; select its window.
+;; C-/ Undo last change.
+;;
+;; Commands for --rebase-merges:
+;; l Associate label with current HEAD in sequence.
+;; MM Merge specified revisions into HEAD.
+;; Mt Toggle whether the merge will invoke an editor
+;; before committing.
+;; t Reset HEAD to the specified label.
+
+;; You should probably also read the `git-rebase' manpage.
+
+;;; Code:
+
+(require 'magit)
+
+(require 'easymenu)
+(require 'server)
+(require 'with-editor)
+
+(defvar recentf-exclude)
+
+;;; Options
+;;;; Variables
+
+(defgroup git-rebase nil
+ "Edit Git rebase sequences."
+ :link '(info-link "(magit)Editing Rebase Sequences")
+ :group 'tools)
+
+(defcustom git-rebase-auto-advance t
+ "Whether to move to next line after changing a line."
+ :group 'git-rebase
+ :type 'boolean)
+
+(defcustom git-rebase-show-instructions t
+ "Whether to show usage instructions inside the rebase buffer."
+ :group 'git-rebase
+ :type 'boolean)
+
+(defcustom git-rebase-confirm-cancel t
+ "Whether confirmation is required to cancel."
+ :group 'git-rebase
+ :type 'boolean)
+
+;;;; Faces
+
+(defgroup git-rebase-faces nil
+ "Faces used by Git-Rebase mode."
+ :group 'faces
+ :group 'git-rebase)
+
+(defface git-rebase-hash '((t :inherit magit-hash))
+ "Face for commit hashes."
+ :group 'git-rebase-faces)
+
+(defface git-rebase-label '((t :inherit magit-refname))
+ "Face for labels in label, merge, and reset lines."
+ :group 'git-rebase-faces)
+
+(defface git-rebase-description '((t nil))
+ "Face for commit descriptions."
+ :group 'git-rebase-faces)
+
+(defface git-rebase-action
+ '((t :inherit font-lock-keyword-face))
+ "Face for action keywords."
+ :group 'git-rebase-faces)
+
+(defface git-rebase-killed-action
+ '((t :inherit font-lock-comment-face :strike-through t))
+ "Face for commented commit action lines."
+ :group 'git-rebase-faces)
+
+(defface git-rebase-comment-hash
+ '((t :inherit git-rebase-hash :weight bold))
+ "Face for commit hashes in commit message comments."
+ :group 'git-rebase-faces)
+
+(defface git-rebase-comment-heading
+ '((t :inherit font-lock-keyword-face))
+ "Face for headings in rebase message comments."
+ :group 'git-rebase-faces)
+
+;;; Keymaps
+
+(defvar git-rebase-mode-map
+ (let ((map (make-sparse-keymap)))
+ (set-keymap-parent map special-mode-map)
+ (define-key map (kbd "C-m") #'git-rebase-show-commit)
+ (define-key map (kbd "p") #'git-rebase-backward-line)
+ (define-key map (kbd "n") #'forward-line)
+ (define-key map (kbd "M-p") #'git-rebase-move-line-up)
+ (define-key map (kbd "M-n") #'git-rebase-move-line-down)
+ (define-key map (kbd "c") #'git-rebase-pick)
+ (define-key map (kbd "k") #'git-rebase-kill-line)
+ (define-key map (kbd "C-k") #'git-rebase-kill-line)
+ (define-key map (kbd "b") #'git-rebase-break)
+ (define-key map (kbd "e") #'git-rebase-edit)
+ (define-key map (kbd "l") #'git-rebase-label)
+ (define-key map (kbd "MM") #'git-rebase-merge)
+ (define-key map (kbd "Mt") #'git-rebase-merge-toggle-editmsg)
+ (define-key map (kbd "m") #'git-rebase-edit)
+ (define-key map (kbd "f") #'git-rebase-fixup)
+ (define-key map (kbd "q") #'undefined)
+ (define-key map (kbd "r") #'git-rebase-reword)
+ (define-key map (kbd "w") #'git-rebase-reword)
+ (define-key map (kbd "s") #'git-rebase-squash)
+ (define-key map (kbd "t") #'git-rebase-reset)
+ (define-key map (kbd "x") #'git-rebase-exec)
+ (define-key map (kbd "y") #'git-rebase-insert)
+ (define-key map (kbd "z") #'git-rebase-noop)
+ (define-key map (kbd "SPC") #'git-rebase-show-or-scroll-up)
+ (define-key map (kbd "DEL") #'git-rebase-show-or-scroll-down)
+ (define-key map (kbd "C-x C-t") #'git-rebase-move-line-up)
+ (define-key map [M-up] #'git-rebase-move-line-up)
+ (define-key map [M-down] #'git-rebase-move-line-down)
+ (define-key map [remap undo] #'git-rebase-undo)
+ map)
+ "Keymap for Git-Rebase mode.")
+
+(put 'git-rebase-reword :advertised-binding (kbd "r"))
+(put 'git-rebase-move-line-up :advertised-binding (kbd "M-p"))
+(put 'git-rebase-kill-line :advertised-binding (kbd "k"))
+
+(easy-menu-define git-rebase-mode-menu git-rebase-mode-map
+ "Git-Rebase mode menu"
+ '("Rebase"
+ ["Pick" git-rebase-pick t]
+ ["Reword" git-rebase-reword t]
+ ["Edit" git-rebase-edit t]
+ ["Squash" git-rebase-squash t]
+ ["Fixup" git-rebase-fixup t]
+ ["Kill" git-rebase-kill-line t]
+ ["Noop" git-rebase-noop t]
+ ["Execute" git-rebase-exec t]
+ ["Move Down" git-rebase-move-line-down t]
+ ["Move Up" git-rebase-move-line-up t]
+ "---"
+ ["Cancel" with-editor-cancel t]
+ ["Finish" with-editor-finish t]))
+
+(defvar git-rebase-command-descriptions
+ '((with-editor-finish . "tell Git to make it happen")
+ (with-editor-cancel . "tell Git that you changed your mind, i.e. abort")
+ (git-rebase-backward-line . "move point to previous line")
+ (forward-line . "move point to next line")
+ (git-rebase-move-line-up . "move the commit at point up")
+ (git-rebase-move-line-down . "move the commit at point down")
+ (git-rebase-show-or-scroll-up . "show the commit at point in another buffer")
+ (git-rebase-show-commit
+ . "show the commit at point in another buffer and select its window")
+ (undo . "undo last change")
+ (git-rebase-kill-line . "drop the commit at point")
+ (git-rebase-insert . "insert a line for an arbitrary commit")
+ (git-rebase-noop . "add noop action at point")))
+
+;;; Commands
+
+(defun git-rebase-pick ()
+ "Use commit on current line.
+If the region is active, act on all lines touched by the region."
+ (interactive)
+ (git-rebase-set-action "pick"))
+
+(defun git-rebase-reword ()
+ "Edit message of commit on current line.
+If the region is active, act on all lines touched by the region."
+ (interactive)
+ (git-rebase-set-action "reword"))
+
+(defun git-rebase-edit ()
+ "Stop at the commit on the current line.
+If the region is active, act on all lines touched by the region."
+ (interactive)
+ (git-rebase-set-action "edit"))
+
+(defun git-rebase-squash ()
+ "Meld commit on current line into previous commit, edit message.
+If the region is active, act on all lines touched by the region."
+ (interactive)
+ (git-rebase-set-action "squash"))
+
+(defun git-rebase-fixup ()
+ "Meld commit on current line into previous commit, discard its message.
+If the region is active, act on all lines touched by the region."
+ (interactive)
+ (git-rebase-set-action "fixup"))
+
+(defvar-local git-rebase-comment-re nil)
+
+(defvar git-rebase-short-options
+ '((?b . "break")
+ (?e . "edit")
+ (?f . "fixup")
+ (?l . "label")
+ (?m . "merge")
+ (?p . "pick")
+ (?r . "reword")
+ (?s . "squash")
+ (?t . "reset")
+ (?x . "exec"))
+ "Alist mapping single key of an action to the full name.")
+
+(defclass git-rebase-action ()
+ (;; action-type: commit, exec, bare, label, merge
+ (action-type :initarg :action-type :initform nil)
+ ;; Examples for each action type:
+ ;; | action | action options | target | trailer |
+ ;; |--------+----------------+---------+---------|
+ ;; | pick | | hash | subject |
+ ;; | exec | | command | |
+ ;; | noop | | | |
+ ;; | reset | | name | subject |
+ ;; | merge | -C hash | name | subject |
+ (action :initarg :action :initform nil)
+ (action-options :initarg :action-options :initform nil)
+ (target :initarg :target :initform nil)
+ (trailer :initarg :trailer :initform nil)
+ (comment-p :initarg :comment-p :initform nil)))
+
+(defvar git-rebase-line-regexps
+ `((commit . ,(concat
+ (regexp-opt '("e" "edit"
+ "f" "fixup"
+ "p" "pick"
+ "r" "reword"
+ "s" "squash")
+ "\\(?1:")
+ " \\(?3:[^ \n]+\\) ?\\(?4:.*\\)"))
+ (exec . "\\(?1:x\\|exec\\) \\(?3:.*\\)")
+ (bare . ,(concat (regexp-opt '("b" "break" "noop") "\\(?1:")
+ " *$"))
+ (label . ,(concat (regexp-opt '("l" "label"
+ "t" "reset")
+ "\\(?1:")
+ " \\(?3:[^ \n]+\\) ?\\(?4:.*\\)"))
+ (merge . ,(concat "\\(?1:m\\|merge\\) "
+ "\\(?:\\(?2:-[cC] [^ \n]+\\) \\)?"
+ "\\(?3:[^ \n]+\\)"
+ " ?\\(?4:.*\\)"))))
+
+;;;###autoload
+(defun git-rebase-current-line ()
+ "Parse current line into a `git-rebase-action' instance.
+If the current line isn't recognized as a rebase line, an
+instance with all nil values is returned."
+ (save-excursion
+ (goto-char (line-beginning-position))
+ (if-let ((re-start (concat "^\\(?5:" (regexp-quote comment-start)
+ "\\)? *"))
+ (type (seq-some (lambda (arg)
+ (let ((case-fold-search nil))
+ (and (looking-at (concat re-start (cdr arg)))
+ (car arg))))
+ git-rebase-line-regexps)))
+ (git-rebase-action
+ :action-type type
+ :action (and-let* ((action (match-string-no-properties 1)))
+ (or (cdr (assoc action git-rebase-short-options))
+ action))
+ :action-options (match-string-no-properties 2)
+ :target (match-string-no-properties 3)
+ :trailer (match-string-no-properties 4)
+ :comment-p (and (match-string 5) t))
+ ;; Use default empty class rather than nil to ease handling.
+ (git-rebase-action))))
+
+(defun git-rebase-set-action (action)
+ "Set action of commit line to ACTION.
+If the region is active, operate on all lines that it touches.
+Otherwise, operate on the current line. As a special case, an
+ACTION of nil comments the rebase line, regardless of its action
+type."
+ (pcase (git-rebase-region-bounds t)
+ (`(,beg ,end)
+ (let ((end-marker (copy-marker end))
+ (pt-below-p (and mark-active (< (mark) (point)))))
+ (set-marker-insertion-type end-marker t)
+ (goto-char beg)
+ (while (< (point) end-marker)
+ (with-slots (action-type target trailer comment-p)
+ (git-rebase-current-line)
+ (cond
+ ((and action (eq action-type 'commit))
+ (let ((inhibit-read-only t))
+ (magit-delete-line)
+ (insert (concat action " " target " " trailer "\n"))))
+ ((and action-type (not (or action comment-p)))
+ (let ((inhibit-read-only t))
+ (insert comment-start " "))
+ (forward-line))
+ (t
+ ;; In the case of --rebase-merges, commit lines may have
+ ;; other lines with other action types, empty lines, and
+ ;; "Branch" comments interspersed. Move along.
+ (forward-line)))))
+ (goto-char
+ (if git-rebase-auto-advance
+ end-marker
+ (if pt-below-p (1- end-marker) beg)))
+ (goto-char (line-beginning-position))))
+ (_ (ding))))
+
+(defun git-rebase-line-p (&optional pos)
+ (save-excursion
+ (when pos (goto-char pos))
+ (and (oref (git-rebase-current-line) action-type)
+ t)))
+
+(defun git-rebase-region-bounds (&optional fallback)
+ "Return region bounds if both ends touch rebase lines.
+Each bound is extended to include the entire line touched by the
+point or mark. If the region isn't active and FALLBACK is
+non-nil, return the beginning and end of the current rebase line,
+if any."
+ (cond
+ ((use-region-p)
+ (let ((beg (save-excursion (goto-char (region-beginning))
+ (line-beginning-position)))
+ (end (save-excursion (goto-char (region-end))
+ (line-end-position))))
+ (when (and (git-rebase-line-p beg)
+ (git-rebase-line-p end))
+ (list beg (1+ end)))))
+ ((and fallback (git-rebase-line-p))
+ (list (line-beginning-position)
+ (1+ (line-end-position))))))
+
+(defun git-rebase-move-line-down (n)
+ "Move the current commit (or command) N lines down.
+If N is negative, move the commit up instead. With an active
+region, move all the lines that the region touches, not just the
+current line."
+ (interactive "p")
+ (pcase-let* ((`(,beg ,end)
+ (or (git-rebase-region-bounds)
+ (list (line-beginning-position)
+ (1+ (line-end-position)))))
+ (pt-offset (- (point) beg))
+ (mark-offset (and mark-active (- (mark) beg))))
+ (save-restriction
+ (narrow-to-region
+ (point-min)
+ (1-
+ (if git-rebase-show-instructions
+ (save-excursion
+ (goto-char (point-min))
+ (while (or (git-rebase-line-p)
+ ;; The output for --rebase-merges has empty
+ ;; lines and "Branch" comments interspersed.
+ (looking-at-p "^$")
+ (looking-at-p (concat git-rebase-comment-re
+ " Branch")))
+ (forward-line))
+ (line-beginning-position))
+ (point-max))))
+ (if (or (and (< n 0) (= beg (point-min)))
+ (and (> n 0) (= end (point-max)))
+ (> end (point-max)))
+ (ding)
+ (goto-char (if (< n 0) beg end))
+ (forward-line n)
+ (atomic-change-group
+ (let ((inhibit-read-only t))
+ (insert (delete-and-extract-region beg end)))
+ (let ((new-beg (- (point) (- end beg))))
+ (when (use-region-p)
+ (setq deactivate-mark nil)
+ (set-mark (+ new-beg mark-offset)))
+ (goto-char (+ new-beg pt-offset))))))))
+
+(defun git-rebase-move-line-up (n)
+ "Move the current commit (or command) N lines up.
+If N is negative, move the commit down instead. With an active
+region, move all the lines that the region touches, not just the
+current line."
+ (interactive "p")
+ (git-rebase-move-line-down (- n)))
+
+(defun git-rebase-highlight-region (start end window rol)
+ (let ((inhibit-read-only t)
+ (deactivate-mark nil)
+ (bounds (git-rebase-region-bounds)))
+ (mapc #'delete-overlay magit-section-highlight-overlays)
+ (when bounds
+ (magit-section-make-overlay (car bounds) (cadr bounds)
+ 'magit-section-heading-selection))
+ (if (and bounds (not magit-section-keep-region-overlay))
+ (funcall (default-value 'redisplay-unhighlight-region-function) rol)
+ (funcall (default-value 'redisplay-highlight-region-function)
+ start end window rol))))
+
+(defun git-rebase-unhighlight-region (rol)
+ (mapc #'delete-overlay magit-section-highlight-overlays)
+ (funcall (default-value 'redisplay-unhighlight-region-function) rol))
+
+(defun git-rebase-kill-line ()
+ "Kill the current action line.
+If the region is active, act on all lines touched by the region."
+ (interactive)
+ (git-rebase-set-action nil))
+
+(defun git-rebase-insert (rev)
+ "Read an arbitrary commit and insert it below current line."
+ (interactive (list (magit-read-branch-or-commit "Insert revision")))
+ (forward-line)
+ (--if-let (magit-rev-format "%h %s" rev)
+ (let ((inhibit-read-only t))
+ (insert "pick " it ?\n))
+ (user-error "Unknown revision")))
+
+(defun git-rebase-set-noncommit-action (action value-fn arg)
+ (goto-char (line-beginning-position))
+ (pcase-let* ((inhibit-read-only t)
+ (`(,initial ,trailer ,comment-p)
+ (and (not arg)
+ (with-slots ((ln-action action)
+ target trailer comment-p)
+ (git-rebase-current-line)
+ (and (equal ln-action action)
+ (list target trailer comment-p)))))
+ (value (funcall value-fn initial)))
+ (pcase (list value initial comment-p)
+ (`("" nil ,_)
+ (ding))
+ (`("" ,_ ,_)
+ (magit-delete-line))
+ (_
+ (if initial
+ (magit-delete-line)
+ (forward-line))
+ (insert (concat action " " value
+ (and (equal value initial)
+ trailer
+ (concat " " trailer))
+ "\n"))
+ (unless git-rebase-auto-advance
+ (forward-line -1))))))
+
+(defun git-rebase-exec (arg)
+ "Insert a shell command to be run after the current commit.
+
+If there already is such a command on the current line, then edit
+that instead. With a prefix argument insert a new command even
+when there already is one on the current line. With empty input
+remove the command on the current line, if any."
+ (interactive "P")
+ (git-rebase-set-noncommit-action
+ "exec"
+ (lambda (initial) (read-shell-command "Execute: " initial))
+ arg))
+
+(defun git-rebase-label (arg)
+ "Add a label after the current commit.
+If there already is a label on the current line, then edit that
+instead. With a prefix argument, insert a new label even when
+there is already a label on the current line. With empty input,
+remove the label on the current line, if any."
+ (interactive "P")
+ (git-rebase-set-noncommit-action
+ "label"
+ (lambda (initial)
+ (read-from-minibuffer
+ "Label: " initial magit-minibuffer-local-ns-map))
+ arg))
+
+(defun git-rebase-buffer-labels ()
+ (let (labels)
+ (save-excursion
+ (goto-char (point-min))
+ (while (re-search-forward "^\\(?:l\\|label\\) \\([^ \n]+\\)" nil t)
+ (push (match-string-no-properties 1) labels)))
+ (nreverse labels)))
+
+(defun git-rebase-reset (arg)
+ "Reset the current HEAD to a label.
+If there already is a reset command on the current line, then
+edit that instead. With a prefix argument, insert a new reset
+line even when point is already on a reset line. With empty
+input, remove the reset command on the current line, if any."
+ (interactive "P")
+ (git-rebase-set-noncommit-action
+ "reset"
+ (lambda (initial)
+ (or (magit-completing-read "Label" (git-rebase-buffer-labels)
+ nil t initial)
+ ""))
+ arg))
+
+(defun git-rebase-merge (arg)
+ "Add a merge command after the current commit.
+If there is already a merge command on the current line, then
+replace that command instead. With a prefix argument, insert a
+new merge command even when there is already one on the current
+line. With empty input, remove the merge command on the current
+line, if any."
+ (interactive "P")
+ (git-rebase-set-noncommit-action
+ "merge"
+ (lambda (_)
+ (or (magit-completing-read "Merge" (git-rebase-buffer-labels))
+ ""))
+ arg))
+
+(defun git-rebase-merge-toggle-editmsg ()
+ "Toggle whether an editor is invoked when performing the merge at point.
+When a merge command uses a lower-case -c, the message for the
+specified commit will be opened in an editor before creating the
+commit. For an upper-case -C, the message will be used as is."
+ (interactive)
+ (with-slots (action-type target action-options trailer)
+ (git-rebase-current-line)
+ (if (eq action-type 'merge)
+ (let ((inhibit-read-only t))
+ (magit-delete-line)
+ (insert
+ (format "merge %s %s %s\n"
+ (replace-regexp-in-string
+ "-[cC]" (lambda (c)
+ (if (equal c "-c") "-C" "-c"))
+ action-options t t)
+ target
+ trailer)))
+ (ding))))
+
+(defun git-rebase-set-bare-action (action arg)
+ (goto-char (line-beginning-position))
+ (with-slots ((ln-action action) comment-p)
+ (git-rebase-current-line)
+ (let ((same-action-p (equal action ln-action))
+ (inhibit-read-only t))
+ (when (or arg
+ (not ln-action)
+ (not same-action-p)
+ (and same-action-p comment-p))
+ (unless (or arg (not same-action-p))
+ (magit-delete-line))
+ (insert action ?\n)
+ (unless git-rebase-auto-advance
+ (forward-line -1))))))
+
+(defun git-rebase-noop (&optional arg)
+ "Add noop action at point.
+
+If the current line already contains a noop action, leave it
+unchanged. If there is a commented noop action present, remove
+the comment. Otherwise add a new noop action. With a prefix
+argument insert a new noop action regardless of what is already
+present on the current line.
+
+A noop action can be used to make git perform a rebase even if
+no commits are selected. Without the noop action present, git
+would see an empty file and therefore do nothing."
+ (interactive "P")
+ (git-rebase-set-bare-action "noop" arg))
+
+(defun git-rebase-break (&optional arg)
+ "Add break action at point.
+
+If there is a commented break action present, remove the comment.
+If the current line already contains a break action, add another
+break action only if a prefix argument is given.
+
+A break action can be used to interrupt the rebase at the
+specified point. It is particularly useful for pausing before
+the first commit in the sequence. For other cases, the
+equivalent behavior can be achieved with `git-rebase-edit'."
+ (interactive "P")
+ (git-rebase-set-bare-action "break" arg))
+
+(defun git-rebase-undo (&optional arg)
+ "Undo some previous changes.
+Like `undo' but works in read-only buffers."
+ (interactive "P")
+ (let ((inhibit-read-only t))
+ (undo arg)))
+
+(defun git-rebase--show-commit (&optional scroll)
+ (let ((disable-magit-save-buffers t))
+ (save-excursion
+ (goto-char (line-beginning-position))
+ (--if-let (with-slots (action-type target) (git-rebase-current-line)
+ (and (eq action-type 'commit)
+ target))
+ (pcase scroll
+ ('up (magit-diff-show-or-scroll-up))
+ ('down (magit-diff-show-or-scroll-down))
+ (_ (apply #'magit-show-commit it
+ (magit-diff-arguments 'magit-revision-mode))))
+ (ding)))))
+
+(defun git-rebase-show-commit ()
+ "Show the commit on the current line if any."
+ (interactive)
+ (git-rebase--show-commit))
+
+(defun git-rebase-show-or-scroll-up ()
+ "Update the commit buffer for commit on current line.
+
+Either show the commit at point in the appropriate buffer, or if
+that buffer is already being displayed in the current frame and
+contains information about that commit, then instead scroll the
+buffer up."
+ (interactive)
+ (git-rebase--show-commit 'up))
+
+(defun git-rebase-show-or-scroll-down ()
+ "Update the commit buffer for commit on current line.
+
+Either show the commit at point in the appropriate buffer, or if
+that buffer is already being displayed in the current frame and
+contains information about that commit, then instead scroll the
+buffer down."
+ (interactive)
+ (git-rebase--show-commit 'down))
+
+(defun git-rebase-backward-line (&optional n)
+ "Move N lines backward (forward if N is negative).
+Like `forward-line' but go into the opposite direction."
+ (interactive "p")
+ (forward-line (- (or n 1))))
+
+;;; Mode
+
+;;;###autoload
+(define-derived-mode git-rebase-mode special-mode "Git Rebase"
+ "Major mode for editing of a Git rebase file.
+
+Rebase files are generated when you run 'git rebase -i' or run
+`magit-interactive-rebase'. They describe how Git should perform
+the rebase. See the documentation for git-rebase (e.g., by
+running 'man git-rebase' at the command line) for details."
+ :group 'git-rebase
+ (setq comment-start (or (magit-get "core.commentChar") "#"))
+ (setq git-rebase-comment-re (concat "^" (regexp-quote comment-start)))
+ (setq font-lock-defaults (list (git-rebase-mode-font-lock-keywords) t t))
+ (unless git-rebase-show-instructions
+ (let ((inhibit-read-only t))
+ (flush-lines git-rebase-comment-re)))
+ (unless with-editor-mode
+ ;; Maybe already enabled when using `shell-command' or an Emacs shell.
+ (with-editor-mode 1))
+ (when git-rebase-confirm-cancel
+ (add-hook 'with-editor-cancel-query-functions
+ #'git-rebase-cancel-confirm nil t))
+ (setq-local redisplay-highlight-region-function #'git-rebase-highlight-region)
+ (setq-local redisplay-unhighlight-region-function #'git-rebase-unhighlight-region)
+ (add-hook 'with-editor-pre-cancel-hook #'git-rebase-autostash-save nil t)
+ (add-hook 'with-editor-post-cancel-hook #'git-rebase-autostash-apply nil t)
+ (setq imenu-prev-index-position-function
+ #'magit-imenu--rebase-prev-index-position-function)
+ (setq imenu-extract-index-name-function
+ #'magit-imenu--rebase-extract-index-name-function)
+ (when (boundp 'save-place)
+ (setq save-place nil)))
+
+(defun git-rebase-cancel-confirm (force)
+ (or (not (buffer-modified-p))
+ force
+ (magit-confirm 'abort-rebase "Abort this rebase" nil 'noabort)))
+
+(defun git-rebase-autostash-save ()
+ (--when-let (magit-file-line (magit-git-dir "rebase-merge/autostash"))
+ (push (cons 'stash it) with-editor-cancel-alist)))
+
+(defun git-rebase-autostash-apply ()
+ (--when-let (cdr (assq 'stash with-editor-cancel-alist))
+ (magit-stash-apply it)))
+
+(defun git-rebase-match-comment-line (limit)
+ (re-search-forward (concat git-rebase-comment-re ".*") limit t))
+
+(defun git-rebase-mode-font-lock-keywords ()
+ "Font lock keywords for Git-Rebase mode."
+ `((,(concat "^" (cdr (assq 'commit git-rebase-line-regexps)))
+ (1 'git-rebase-action)
+ (3 'git-rebase-hash)
+ (4 'git-rebase-description))
+ (,(concat "^" (cdr (assq 'exec git-rebase-line-regexps)))
+ (1 'git-rebase-action)
+ (3 'git-rebase-description))
+ (,(concat "^" (cdr (assq 'bare git-rebase-line-regexps)))
+ (1 'git-rebase-action))
+ (,(concat "^" (cdr (assq 'label git-rebase-line-regexps)))
+ (1 'git-rebase-action)
+ (3 'git-rebase-label)
+ (4 'font-lock-comment-face))
+ ("^\\(m\\(?:erge\\)?\\) -[Cc] \\([^ \n]+\\) \\([^ \n]+\\)\\( #.*\\)?"
+ (1 'git-rebase-action)
+ (2 'git-rebase-hash)
+ (3 'git-rebase-label)
+ (4 'font-lock-comment-face))
+ ("^\\(m\\(?:erge\\)?\\) \\([^ \n]+\\)"
+ (1 'git-rebase-action)
+ (2 'git-rebase-label))
+ (,(concat git-rebase-comment-re " *"
+ (cdr (assq 'commit git-rebase-line-regexps)))
+ 0 'git-rebase-killed-action t)
+ (git-rebase-match-comment-line 0 'font-lock-comment-face)
+ ("\\[[^[]*\\]"
+ 0 'magit-keyword t)
+ ("\\(?:fixup!\\|squash!\\)"
+ 0 'magit-keyword-squash t)
+ (,(format "^%s Rebase \\([^ ]*\\) onto \\([^ ]*\\)" comment-start)
+ (1 'git-rebase-comment-hash t)
+ (2 'git-rebase-comment-hash t))
+ (,(format "^%s \\(Commands:\\)" comment-start)
+ (1 'git-rebase-comment-heading t))
+ (,(format "^%s Branch \\(.*\\)" comment-start)
+ (1 'git-rebase-label t))))
+
+(defun git-rebase-mode-show-keybindings ()
+ "Modify the \"Commands:\" section of the comment Git generates
+at the bottom of the file so that in place of the one-letter
+abbreviation for the command, it shows the command's keybinding.
+By default, this is the same except for the \"pick\" command."
+ (let ((inhibit-read-only t))
+ (save-excursion
+ (goto-char (point-min))
+ (when (and git-rebase-show-instructions
+ (re-search-forward
+ (concat git-rebase-comment-re "\\s-+p, pick")
+ nil t))
+ (goto-char (line-beginning-position))
+ (pcase-dolist (`(,cmd . ,desc) git-rebase-command-descriptions)
+ (insert (format "%s %-8s %s\n"
+ comment-start
+ (substitute-command-keys (format "\\[%s]" cmd))
+ desc)))
+ (while (re-search-forward (concat git-rebase-comment-re
+ "\\( ?\\)\\([^\n,],\\) "
+ "\\([^\n ]+\\) ")
+ nil t)
+ (let ((cmd (intern (concat "git-rebase-" (match-string 3)))))
+ (if (not (fboundp cmd))
+ (delete-region (line-beginning-position) (1+ (line-end-position)))
+ (replace-match " " t t nil 1)
+ (replace-match
+ (format "%-8s"
+ (mapconcat #'key-description
+ (--remove (eq (elt it 0) 'menu-bar)
+ (reverse (where-is-internal
+ cmd git-rebase-mode-map)))
+ ", "))
+ t t nil 2))))))))
+
+(add-hook 'git-rebase-mode-hook #'git-rebase-mode-show-keybindings t)
+
+(defun git-rebase-mode-disable-before-save-hook ()
+ (set (make-local-variable 'before-save-hook) nil))
+
+(add-hook 'git-rebase-mode-hook #'git-rebase-mode-disable-before-save-hook)
+
+;;;###autoload
+(defconst git-rebase-filename-regexp "/git-rebase-todo\\'")
+;;;###autoload
+(add-to-list 'auto-mode-alist
+ (cons git-rebase-filename-regexp #'git-rebase-mode))
+
+(add-to-list 'with-editor-server-window-alist
+ (cons git-rebase-filename-regexp #'switch-to-buffer))
+
+(with-eval-after-load 'recentf
+ (add-to-list 'recentf-exclude git-rebase-filename-regexp))
+
+(add-to-list 'with-editor-file-name-history-exclude git-rebase-filename-regexp)
+
+;;; Imenu Support
+
+(defun magit-imenu--rebase-prev-index-position-function ()
+ "Move point to previous commit in git-rebase buffer.
+Used as a value for `imenu-prev-index-position-function'."
+ (catch 'found
+ (while (not (bobp))
+ (git-rebase-backward-line)
+ (when (git-rebase-line-p)
+ (throw 'found t)))))
+
+(defun magit-imenu--rebase-extract-index-name-function ()
+ "Return imenu name for line at point.
+Point should be at the beginning of the line. This function
+is used as a value for `imenu-extract-index-name-function'."
+ (buffer-substring-no-properties (line-beginning-position)
+ (line-end-position)))
+
+;;; _
+(provide 'git-rebase)
+;;; git-rebase.el ends here
diff --git a/elpa/magit-20220503.1245/git-rebase.elc b/elpa/magit-20220503.1245/git-rebase.elc
new file mode 100644
index 0000000..6d9317a
--- /dev/null
+++ b/elpa/magit-20220503.1245/git-rebase.elc
Binary files differ
diff --git a/elpa/magit-20220503.1245/magit-apply.el b/elpa/magit-20220503.1245/magit-apply.el
new file mode 100644
index 0000000..7bc825e
--- /dev/null
+++ b/elpa/magit-20220503.1245/magit-apply.el
@@ -0,0 +1,806 @@
+;;; magit-apply.el --- Apply Git diffs -*- lexical-binding:t -*-
+
+;; Copyright (C) 2008-2022 The Magit Project Contributors
+
+;; Author: Jonas Bernoulli <jonas@bernoul.li>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+
+;; SPDX-License-Identifier: GPL-3.0-or-later
+
+;; Magit 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.
+;;
+;; Magit 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 Magit. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This library implements commands for applying Git diffs or parts
+;; of such a diff. The supported "apply variants" are apply, stage,
+;; unstage, discard, and reverse - more than Git itself knows about,
+;; at least at the porcelain level.
+
+;;; Code:
+
+(require 'magit-core)
+(require 'magit-diff)
+(require 'magit-wip)
+
+(require 'transient) ; See #3732.
+
+;; For `magit-apply'
+(declare-function magit-am "magit-sequence" () t)
+(declare-function magit-patch-apply "magit-patch" () t)
+;; For `magit-discard-files'
+(declare-function magit-checkout-stage "magit-merge" (file arg))
+(declare-function magit-checkout-read-stage "magit-merge" (file))
+(defvar auto-revert-verbose)
+;; For `magit-stage-untracked'
+(declare-function magit-submodule-add-1 "magit-submodule"
+ (url &optional path name args))
+(declare-function magit-submodule-read-name-for-path "magit-submodule"
+ (path &optional prefer-short))
+(declare-function borg--maybe-absorb-gitdir "borg" (pkg))
+(declare-function borg--sort-submodule-sections "borg" (file))
+(declare-function borg-assimilate "borg" (package url &optional partially))
+(defvar borg-user-emacs-directory)
+
+(cl-eval-when (compile load)
+ (when (< emacs-major-version 26)
+ (defalias 'smerge-keep-upper 'smerge-keep-mine)
+ (defalias 'smerge-keep-lower 'smerge-keep-other)))
+
+;;; Options
+
+(defcustom magit-delete-by-moving-to-trash t
+ "Whether Magit uses the system's trash can.
+
+You should absolutely not disable this and also remove `discard'
+from `magit-no-confirm'. You shouldn't do that even if you have
+all of the Magit-Wip modes enabled, because those modes do not
+track any files that are not tracked in the proper branch."
+ :package-version '(magit . "2.1.0")
+ :group 'magit-essentials
+ :type 'boolean)
+
+(defcustom magit-unstage-committed t
+ "Whether unstaging a committed change reverts it instead.
+
+A committed change cannot be unstaged, because staging and
+unstaging are actions that are concerned with the differences
+between the index and the working tree, not with committed
+changes.
+
+If this option is non-nil (the default), then typing \"u\"
+\(`magit-unstage') on a committed change, causes it to be
+reversed in the index but not the working tree. For more
+information see command `magit-reverse-in-index'."
+ :package-version '(magit . "2.4.1")
+ :group 'magit-commands
+ :type 'boolean)
+
+(defcustom magit-reverse-atomically nil
+ "Whether to reverse changes atomically.
+
+If some changes can be reversed while others cannot, then nothing
+is reversed if the value of this option is non-nil. But when it
+is nil, then the changes that can be reversed are reversed and
+for the other changes diff files are created that contain the
+rejected reversals."
+ :package-version '(magit . "2.7.0")
+ :group 'magit-commands
+ :type 'boolean)
+
+(defcustom magit-post-stage-hook nil
+ "Hook run after staging changes.
+This hook is run by `magit-refresh' if `this-command'
+is a member of `magit-post-stage-hook-commands'."
+ :package-version '(magit . "2.90.0")
+ :group 'magit-commands
+ :type 'hook)
+
+(defvar magit-post-stage-hook-commands
+ '(magit-stage magit-stage-file magit-stage-modified))
+
+(defcustom magit-post-unstage-hook nil
+ "Hook run after unstaging changes.
+This hook is run by `magit-refresh' if `this-command'
+is a member of `magit-post-unstage-hook-commands'."
+ :package-version '(magit . "2.90.0")
+ :group 'magit-commands
+ :type 'hook)
+
+(defvar magit-post-unstage-hook-commands
+ '(magit-unstage magit-unstage-file magit-unstage-all))
+
+;;; Commands
+;;;; Apply
+
+(defun magit-apply (&rest args)
+ "Apply the change at point to the working tree.
+With a prefix argument fallback to a 3-way merge. Doing
+so causes the change to be applied to the index as well."
+ (interactive (and current-prefix-arg (list "--3way")))
+ (--when-let (magit-apply--get-selection)
+ (pcase (list (magit-diff-type) (magit-diff-scope))
+ (`(,(or 'unstaged 'staged) ,_)
+ (user-error "Change is already in the working tree"))
+ (`(untracked ,(or 'file 'files))
+ (call-interactively #'magit-am))
+ (`(,_ region) (magit-apply-region it args))
+ (`(,_ hunk) (magit-apply-hunk it args))
+ (`(,_ hunks) (magit-apply-hunks it args))
+ (`(rebase-sequence file)
+ (call-interactively #'magit-patch-apply))
+ (`(,_ file) (magit-apply-diff it args))
+ (`(,_ files) (magit-apply-diffs it args)))))
+
+(defun magit-apply--section-content (section)
+ (buffer-substring-no-properties (if (magit-hunk-section-p section)
+ (oref section start)
+ (oref section content))
+ (oref section end)))
+
+(defun magit-apply-diffs (sections &rest args)
+ (setq sections (magit-apply--get-diffs sections))
+ (magit-apply-patch sections args
+ (mapconcat
+ (lambda (s)
+ (concat (magit-diff-file-header s)
+ (magit-apply--section-content s)))
+ sections "")))
+
+(defun magit-apply-diff (section &rest args)
+ (setq section (car (magit-apply--get-diffs (list section))))
+ (magit-apply-patch section args
+ (concat (magit-diff-file-header section)
+ (magit-apply--section-content section))))
+
+(defun magit-apply--adjust-hunk-new-starts (hunks)
+ "Adjust new line numbers in headers of HUNKS for partial application.
+HUNKS should be a list of ordered, contiguous hunks to be applied
+from a file. For example, if there is a sequence of hunks with
+the headers
+
+ @@ -2,6 +2,7 @@
+ @@ -10,6 +11,7 @@
+ @@ -18,6 +20,7 @@
+
+and only the second and third are to be applied, they would be
+adjusted as \"@@ -10,6 +10,7 @@\" and \"@@ -18,6 +19,7 @@\"."
+ (let* ((first-hunk (car hunks))
+ (offset (if (string-match diff-hunk-header-re-unified first-hunk)
+ (- (string-to-number (match-string 3 first-hunk))
+ (string-to-number (match-string 1 first-hunk)))
+ (error "Header hunks have to be applied individually"))))
+ (if (= offset 0)
+ hunks
+ (mapcar (lambda (hunk)
+ (if (string-match diff-hunk-header-re-unified hunk)
+ (replace-match (number-to-string
+ (- (string-to-number (match-string 3 hunk))
+ offset))
+ t t hunk 3)
+ (error "Hunk does not have expected header")))
+ hunks))))
+
+(defun magit-apply--adjust-hunk-new-start (hunk)
+ (car (magit-apply--adjust-hunk-new-starts (list hunk))))
+
+(defun magit-apply-hunks (sections &rest args)
+ (let ((section (oref (car sections) parent)))
+ (when (string-match "^diff --cc" (oref section value))
+ (user-error "Cannot un-/stage resolution hunks. Stage the whole file"))
+ (magit-apply-patch
+ section args
+ (concat (oref section header)
+ (mapconcat #'identity
+ (magit-apply--adjust-hunk-new-starts
+ (mapcar #'magit-apply--section-content sections))
+ "")))))
+
+(defun magit-apply-hunk (section &rest args)
+ (when (string-match "^diff --cc" (magit-section-parent-value section))
+ (user-error "Cannot un-/stage resolution hunks. Stage the whole file"))
+ (let* ((header (car (oref section value)))
+ (header (and (symbolp header) header))
+ (content (magit-apply--section-content section)))
+ (magit-apply-patch
+ (oref section parent) args
+ (concat (magit-diff-file-header section (not (eq header 'rename)))
+ (if header
+ content
+ (magit-apply--adjust-hunk-new-start content))))))
+
+(defun magit-apply-region (section &rest args)
+ (when (string-match "^diff --cc" (magit-section-parent-value section))
+ (user-error "Cannot un-/stage resolution hunks. Stage the whole file"))
+ (magit-apply-patch (oref section parent) args
+ (concat (magit-diff-file-header section)
+ (magit-apply--adjust-hunk-new-start
+ (magit-diff-hunk-region-patch section args)))))
+
+(defun magit-apply-patch (section:s args patch)
+ (let* ((files (if (atom section:s)
+ (list (oref section:s value))
+ (--map (oref it value) section:s)))
+ (command (symbol-name this-command))
+ (command (if (and command (string-match "^magit-\\([^-]+\\)" command))
+ (match-string 1 command)
+ "apply"))
+ (ignore-context (magit-diff-ignore-any-space-p)))
+ (unless (magit-diff-context-p)
+ (user-error "Not enough context to apply patch. Increase the context"))
+ (when (and magit-wip-before-change-mode (not magit-inhibit-refresh))
+ (magit-wip-commit-before-change files (concat " before " command)))
+ (with-temp-buffer
+ (insert patch)
+ (magit-run-git-with-input
+ "apply" args "-p0"
+ (and ignore-context "-C0")
+ "--ignore-space-change" "-"))
+ (unless magit-inhibit-refresh
+ (when magit-wip-after-apply-mode
+ (magit-wip-commit-after-apply files (concat " after " command)))
+ (magit-refresh))))
+
+(defun magit-apply--get-selection ()
+ (or (magit-region-sections '(hunk file module) t)
+ (let ((section (magit-current-section)))
+ (pcase (oref section type)
+ ((or 'hunk 'file 'module) section)
+ ((or 'staged 'unstaged 'untracked
+ 'stashed-index 'stashed-worktree 'stashed-untracked)
+ (oref section children))
+ (_ (user-error "Cannot apply this, it's not a change"))))))
+
+(defun magit-apply--get-diffs (sections)
+ (magit-section-case
+ ([file diffstat]
+ (--map (or (magit-get-section
+ (append `((file . ,(oref it value)))
+ (magit-section-ident magit-root-section)))
+ (error "Cannot get required diff headers"))
+ sections))
+ (t sections)))
+
+(defun magit-apply--diff-ignores-whitespace-p ()
+ (and (cl-intersection magit-buffer-diff-args
+ '("--ignore-space-at-eol"
+ "--ignore-space-change"
+ "--ignore-all-space"
+ "--ignore-blank-lines")
+ :test #'equal)
+ t))
+
+;;;; Stage
+
+(defun magit-stage (&optional intent)
+ "Add the change at point to the staging area.
+With a prefix argument, INTENT, and an untracked file (or files)
+at point, stage the file but not its content."
+ (interactive "P")
+ (--if-let (and (derived-mode-p 'magit-mode) (magit-apply--get-selection))
+ (pcase (list (magit-diff-type)
+ (magit-diff-scope)
+ (magit-apply--diff-ignores-whitespace-p))
+ (`(untracked ,_ ,_) (magit-stage-untracked intent))
+ (`(unstaged region ,_) (magit-apply-region it "--cached"))
+ (`(unstaged hunk ,_) (magit-apply-hunk it "--cached"))
+ (`(unstaged hunks ,_) (magit-apply-hunks it "--cached"))
+ ('(unstaged file t) (magit-apply-diff it "--cached"))
+ ('(unstaged files t) (magit-apply-diffs it "--cached"))
+ ('(unstaged list t) (magit-apply-diffs it "--cached"))
+ ('(unstaged file nil) (magit-stage-1 "-u" (list (oref it value))))
+ ('(unstaged files nil) (magit-stage-1 "-u" (magit-region-values nil t)))
+ ('(unstaged list nil) (magit-stage-modified))
+ (`(staged ,_ ,_) (user-error "Already staged"))
+ (`(committed ,_ ,_) (user-error "Cannot stage committed changes"))
+ (`(undefined ,_ ,_) (user-error "Cannot stage this change")))
+ (call-interactively #'magit-stage-file)))
+
+;;;###autoload
+(defun magit-stage-file (file)
+ "Stage all changes to FILE.
+With a prefix argument or when there is no file at point ask for
+the file to be staged. Otherwise stage the file at point without
+requiring confirmation."
+ (interactive
+ (let* ((atpoint (magit-section-value-if 'file))
+ (current (magit-file-relative-name))
+ (choices (nconc (magit-unstaged-files)
+ (magit-untracked-files)))
+ (default (car (member (or atpoint current) choices))))
+ (list (if (or current-prefix-arg (not default))
+ (magit-completing-read "Stage file" choices
+ nil t nil nil default)
+ default))))
+ (magit-with-toplevel
+ (magit-stage-1 nil (list file))))
+
+;;;###autoload
+(defun magit-stage-modified (&optional all)
+ "Stage all changes to files modified in the worktree.
+Stage all new content of tracked files and remove tracked files
+that no longer exist in the working tree from the index also.
+With a prefix argument also stage previously untracked (but not
+ignored) files."
+ (interactive "P")
+ (when (magit-anything-staged-p)
+ (magit-confirm 'stage-all-changes))
+ (magit-with-toplevel
+ (magit-stage-1 (if all "--all" "-u") magit-buffer-diff-files)))
+
+(defun magit-stage-1 (arg &optional files)
+ (magit-wip-commit-before-change files " before stage")
+ (magit-run-git "add" arg (if files (cons "--" files) "."))
+ (when magit-auto-revert-mode
+ (mapc #'magit-turn-on-auto-revert-mode-if-desired files))
+ (magit-wip-commit-after-apply files " after stage"))
+
+(defun magit-stage-untracked (&optional intent)
+ (let* ((section (magit-current-section))
+ (files (pcase (magit-diff-scope)
+ ('file (list (oref section value)))
+ ('files (magit-region-values nil t))
+ ('list (magit-untracked-files))))
+ plain repos)
+ (dolist (file files)
+ (if (and (not (file-symlink-p file))
+ (magit-git-repo-p file t))
+ (push file repos)
+ (push file plain)))
+ (magit-wip-commit-before-change files " before stage")
+ (when plain
+ (magit-run-git "add" (and intent "--intent-to-add")
+ "--" plain)
+ (when magit-auto-revert-mode
+ (mapc #'magit-turn-on-auto-revert-mode-if-desired plain)))
+ (dolist (repo repos)
+ (save-excursion
+ (goto-char (oref (magit-get-section
+ `((file . ,repo) (untracked) (status)))
+ start))
+ (let* ((topdir (magit-toplevel))
+ (url (let ((default-directory
+ (file-name-as-directory (expand-file-name repo))))
+ (or (magit-get "remote" (magit-get-some-remote) "url")
+ (concat (file-name-as-directory ".") repo))))
+ (package
+ (and (equal (bound-and-true-p borg-user-emacs-directory)
+ topdir)
+ (file-name-nondirectory (directory-file-name repo)))))
+ (if (and package
+ (y-or-n-p (format "Also assimilate `%s' drone?" package)))
+ (borg-assimilate package url)
+ (magit-submodule-add-1
+ url repo (magit-submodule-read-name-for-path repo package))
+ (when package
+ (borg--sort-submodule-sections
+ (expand-file-name ".gitmodules" topdir))
+ (let ((default-directory borg-user-emacs-directory))
+ (borg--maybe-absorb-gitdir package)))))))
+ (magit-wip-commit-after-apply files " after stage")))
+
+;;;; Unstage
+
+(defun magit-unstage ()
+ "Remove the change at point from the staging area."
+ (interactive)
+ (--when-let (magit-apply--get-selection)
+ (pcase (list (magit-diff-type)
+ (magit-diff-scope)
+ (magit-apply--diff-ignores-whitespace-p))
+ (`(untracked ,_ ,_) (user-error "Cannot unstage untracked changes"))
+ (`(unstaged file ,_) (magit-unstage-intent (list (oref it value))))
+ (`(unstaged files ,_) (magit-unstage-intent (magit-region-values nil t)))
+ (`(unstaged ,_ ,_) (user-error "Already unstaged"))
+ (`(staged region ,_) (magit-apply-region it "--reverse" "--cached"))
+ (`(staged hunk ,_) (magit-apply-hunk it "--reverse" "--cached"))
+ (`(staged hunks ,_) (magit-apply-hunks it "--reverse" "--cached"))
+ ('(staged file t) (magit-apply-diff it "--reverse" "--cached"))
+ ('(staged files t) (magit-apply-diffs it "--reverse" "--cached"))
+ ('(staged list t) (magit-apply-diffs it "--reverse" "--cached"))
+ ('(staged file nil) (magit-unstage-1 (list (oref it value))))
+ ('(staged files nil) (magit-unstage-1 (magit-region-values nil t)))
+ ('(staged list nil) (magit-unstage-all))
+ (`(committed ,_ ,_) (if magit-unstage-committed
+ (magit-reverse-in-index)
+ (user-error "Cannot unstage committed changes")))
+ (`(undefined ,_ ,_) (user-error "Cannot unstage this change")))))
+
+;;;###autoload
+(defun magit-unstage-file (file)
+ "Unstage all changes to FILE.
+With a prefix argument or when there is no file at point ask for
+the file to be unstaged. Otherwise unstage the file at point
+without requiring confirmation."
+ (interactive
+ (let* ((atpoint (magit-section-value-if 'file))
+ (current (magit-file-relative-name))
+ (choices (magit-staged-files))
+ (default (car (member (or atpoint current) choices))))
+ (list (if (or current-prefix-arg (not default))
+ (magit-completing-read "Unstage file" choices
+ nil t nil nil default)
+ default))))
+ (magit-with-toplevel
+ (magit-unstage-1 (list file))))
+
+(defun magit-unstage-1 (files)
+ (magit-wip-commit-before-change files " before unstage")
+ (if (magit-no-commit-p)
+ (magit-run-git "rm" "--cached" "--" files)
+ (magit-run-git "reset" "HEAD" "--" files))
+ (magit-wip-commit-after-apply files " after unstage"))
+
+(defun magit-unstage-intent (files)
+ (if-let ((staged (magit-staged-files))
+ (intent (--filter (member it staged) files)))
+ (magit-unstage-1 intent)
+ (user-error "Already unstaged")))
+
+;;;###autoload
+(defun magit-unstage-all ()
+ "Remove all changes from the staging area."
+ (interactive)
+ (unless (magit-anything-staged-p)
+ (user-error "Nothing to unstage"))
+ (when (or (magit-anything-unstaged-p)
+ (magit-untracked-files))
+ (magit-confirm 'unstage-all-changes))
+ (magit-wip-commit-before-change nil " before unstage")
+ (magit-run-git "reset" "HEAD" "--" magit-buffer-diff-files)
+ (magit-wip-commit-after-apply nil " after unstage"))
+
+;;;; Discard
+
+(defun magit-discard ()
+ "Remove the change at point.
+
+On a hunk or file with unresolved conflicts prompt which side to
+keep (while discarding the other). If point is within the text
+of a side, then keep that side without prompting."
+ (interactive)
+ (--when-let (magit-apply--get-selection)
+ (pcase (list (magit-diff-type) (magit-diff-scope))
+ (`(committed ,_) (user-error "Cannot discard committed changes"))
+ (`(undefined ,_) (user-error "Cannot discard this change"))
+ (`(,_ region) (magit-discard-region it))
+ (`(,_ hunk) (magit-discard-hunk it))
+ (`(,_ hunks) (magit-discard-hunks it))
+ (`(,_ file) (magit-discard-file it))
+ (`(,_ files) (magit-discard-files it))
+ (`(,_ list) (magit-discard-files it)))))
+
+(defun magit-discard-region (section)
+ (magit-confirm 'discard "Discard region")
+ (magit-discard-apply section 'magit-apply-region))
+
+(defun magit-discard-hunk (section)
+ (magit-confirm 'discard "Discard hunk")
+ (let ((file (magit-section-parent-value section)))
+ (pcase (cddr (car (magit-file-status file)))
+ ('(?U ?U) (magit-smerge-keep-current))
+ (_ (magit-discard-apply section #'magit-apply-hunk)))))
+
+(defun magit-discard-apply (section apply)
+ (if (eq (magit-diff-type section) 'unstaged)
+ (funcall apply section "--reverse")
+ (if (magit-anything-unstaged-p
+ nil (if (magit-file-section-p section)
+ (oref section value)
+ (magit-section-parent-value section)))
+ (progn (let ((magit-inhibit-refresh t))
+ (funcall apply section "--reverse" "--cached")
+ (funcall apply section "--reverse" "--reject"))
+ (magit-refresh))
+ (funcall apply section "--reverse" "--index"))))
+
+(defun magit-discard-hunks (sections)
+ (magit-confirm 'discard (format "Discard %s hunks from %s"
+ (length sections)
+ (magit-section-parent-value (car sections))))
+ (magit-discard-apply-n sections #'magit-apply-hunks))
+
+(defun magit-discard-apply-n (sections apply)
+ (let ((section (car sections)))
+ (if (eq (magit-diff-type section) 'unstaged)
+ (funcall apply sections "--reverse")
+ (if (magit-anything-unstaged-p
+ nil (if (magit-file-section-p section)
+ (oref section value)
+ (magit-section-parent-value section)))
+ (progn (let ((magit-inhibit-refresh t))
+ (funcall apply sections "--reverse" "--cached")
+ (funcall apply sections "--reverse" "--reject"))
+ (magit-refresh))
+ (funcall apply sections "--reverse" "--index")))))
+
+(defun magit-discard-file (section)
+ (magit-discard-files (list section)))
+
+(defun magit-discard-files (sections)
+ (let ((auto-revert-verbose nil)
+ (type (magit-diff-type (car sections)))
+ (status (magit-file-status))
+ files delete resurrect rename discard discard-new resolve)
+ (dolist (section sections)
+ (let ((file (oref section value)))
+ (push file files)
+ (pcase (cons (pcase type
+ (`staged ?X)
+ (`unstaged ?Y)
+ (`untracked ?Z))
+ (cddr (assoc file status)))
+ ('(?Z) (dolist (f (magit-untracked-files nil file))
+ (push f delete)))
+ ((or '(?Z ?? ??) '(?Z ?! ?!)) (push file delete))
+ ('(?Z ?D ? ) (push file delete))
+ (`(,_ ?D ?D) (push file resolve))
+ ((or `(,_ ?U ,_) `(,_ ,_ ?U)) (push file resolve))
+ (`(,_ ?A ?A) (push file resolve))
+ (`(?X ?M ,(or ? ?M ?D)) (push section discard))
+ (`(?Y ,_ ?M ) (push section discard))
+ ('(?X ?A ?M ) (push file discard-new))
+ ('(?X ?C ?M ) (push file discard-new))
+ (`(?X ?A ,(or ? ?D)) (push file delete))
+ (`(?X ?C ,(or ? ?D)) (push file delete))
+ (`(?X ?D ,(or ? ?M )) (push file resurrect))
+ (`(?Y ,_ ?D ) (push file resurrect))
+ (`(?X ?R ,(or ? ?M ?D)) (push file rename)))))
+ (unwind-protect
+ (let ((magit-inhibit-refresh t))
+ (magit-wip-commit-before-change files " before discard")
+ (when resolve
+ (magit-discard-files--resolve (nreverse resolve)))
+ (when resurrect
+ (magit-discard-files--resurrect (nreverse resurrect)))
+ (when delete
+ (magit-discard-files--delete (nreverse delete) status))
+ (when rename
+ (magit-discard-files--rename (nreverse rename) status))
+ (when (or discard discard-new)
+ (magit-discard-files--discard (nreverse discard)
+ (nreverse discard-new)))
+ (magit-wip-commit-after-apply files " after discard"))
+ (magit-refresh))))
+
+(defun magit-discard-files--resolve (files)
+ (if-let ((arg (and (cdr files)
+ (magit-read-char-case
+ (format "For these %i files\n%s\ncheckout:\n"
+ (length files)
+ (mapconcat (lambda (file)
+ (concat " " file))
+ files "\n"))
+ t
+ (?o "[o]ur stage" "--ours")
+ (?t "[t]heir stage" "--theirs")
+ (?c "[c]onflict" "--merge")
+ (?i "decide [i]ndividually" nil)))))
+ (dolist (file files)
+ (magit-checkout-stage file arg))
+ (dolist (file files)
+ (magit-checkout-stage file (magit-checkout-read-stage file)))))
+
+(defun magit-discard-files--resurrect (files)
+ (magit-confirm-files 'resurrect files)
+ (if (eq (magit-diff-type) 'staged)
+ (magit-call-git "reset" "--" files)
+ (magit-call-git "checkout" "--" files)))
+
+(defun magit-discard-files--delete (files status)
+ (magit-confirm-files (if magit-delete-by-moving-to-trash 'trash 'delete)
+ files)
+ (let ((delete-by-moving-to-trash magit-delete-by-moving-to-trash))
+ (dolist (file files)
+ (when (string-match-p "\\`\\\\?~" file)
+ (error "Refusing to delete %S, too dangerous" file))
+ (pcase (nth 3 (assoc file status))
+ ((guard (memq (magit-diff-type) '(unstaged untracked)))
+ (dired-delete-file file dired-recursive-deletes
+ magit-delete-by-moving-to-trash)
+ (dired-clean-up-after-deletion file))
+ (?\s (delete-file file t)
+ (magit-call-git "rm" "--cached" "--" file))
+ (?M (let ((temp (magit-git-string "checkout-index" "--temp" file)))
+ (string-match
+ (format "\\(.+?\\)\t%s" (regexp-quote file)) temp)
+ (rename-file (match-string 1 temp)
+ (setq temp (concat file ".~{index}~")))
+ (delete-file temp t))
+ (magit-call-git "rm" "--cached" "--force" "--" file))
+ (?D (magit-call-git "checkout" "--" file)
+ (delete-file file t)
+ (magit-call-git "rm" "--cached" "--force" "--" file))))))
+
+(defun magit-discard-files--rename (files status)
+ (magit-confirm 'rename "Undo rename %s" "Undo %i renames" nil
+ (mapcar (lambda (file)
+ (setq file (assoc file status))
+ (format "%s -> %s" (cadr file) (car file)))
+ files))
+ (dolist (file files)
+ (let ((orig (cadr (assoc file status))))
+ (if (file-exists-p file)
+ (progn
+ (--when-let (file-name-directory orig)
+ (make-directory it t))
+ (magit-call-git "mv" file orig))
+ (magit-call-git "rm" "--cached" "--" file)
+ (magit-call-git "reset" "--" orig)))))
+
+(defun magit-discard-files--discard (sections new-files)
+ (let ((files (--map (oref it value) sections)))
+ (magit-confirm-files 'discard (append files new-files)
+ (format "Discard %s changes in" (magit-diff-type)))
+ (if (eq (magit-diff-type (car sections)) 'unstaged)
+ (magit-call-git "checkout" "--" files)
+ (when new-files
+ (magit-call-git "add" "--" new-files)
+ (magit-call-git "reset" "--" new-files))
+ (let ((binaries (magit-binary-files "--cached")))
+ (when binaries
+ (setq sections
+ (--remove (member (oref it value) binaries)
+ sections)))
+ (cond ((length= sections 1)
+ (magit-discard-apply (car sections) 'magit-apply-diff))
+ (sections
+ (magit-discard-apply-n sections #'magit-apply-diffs)))
+ (when binaries
+ (let ((modified (magit-unstaged-files t)))
+ (setq binaries (--separate (member it modified) binaries)))
+ (when (cadr binaries)
+ (magit-call-git "reset" "--" (cadr binaries)))
+ (when (car binaries)
+ (user-error
+ (concat
+ "Cannot discard staged changes to binary files, "
+ "which also have unstaged changes. Unstage instead."))))))))
+
+;;;; Reverse
+
+(defun magit-reverse (&rest args)
+ "Reverse the change at point in the working tree.
+With a prefix argument fallback to a 3-way merge. Doing
+so causes the change to be applied to the index as well."
+ (interactive (and current-prefix-arg (list "--3way")))
+ (--when-let (magit-apply--get-selection)
+ (pcase (list (magit-diff-type) (magit-diff-scope))
+ (`(untracked ,_) (user-error "Cannot reverse untracked changes"))
+ (`(unstaged ,_) (user-error "Cannot reverse unstaged changes"))
+ (`(,_ region) (magit-reverse-region it args))
+ (`(,_ hunk) (magit-reverse-hunk it args))
+ (`(,_ hunks) (magit-reverse-hunks it args))
+ (`(,_ file) (magit-reverse-file it args))
+ (`(,_ files) (magit-reverse-files it args))
+ (`(,_ list) (magit-reverse-files it args)))))
+
+(defun magit-reverse-region (section args)
+ (magit-confirm 'reverse "Reverse region")
+ (magit-reverse-apply section #'magit-apply-region args))
+
+(defun magit-reverse-hunk (section args)
+ (magit-confirm 'reverse "Reverse hunk")
+ (magit-reverse-apply section #'magit-apply-hunk args))
+
+(defun magit-reverse-hunks (sections args)
+ (magit-confirm 'reverse
+ (format "Reverse %s hunks from %s"
+ (length sections)
+ (magit-section-parent-value (car sections))))
+ (magit-reverse-apply sections #'magit-apply-hunks args))
+
+(defun magit-reverse-file (section args)
+ (magit-reverse-files (list section) args))
+
+(defun magit-reverse-files (sections args)
+ (pcase-let ((`(,binaries ,sections)
+ (let ((bs (magit-binary-files
+ (cond ((derived-mode-p 'magit-revision-mode)
+ magit-buffer-range)
+ ((derived-mode-p 'magit-diff-mode)
+ magit-buffer-range)
+ (t
+ "--cached")))))
+ (--separate (member (oref it value) bs)
+ sections))))
+ (magit-confirm-files 'reverse (--map (oref it value) sections))
+ (cond ((length= sections 1)
+ (magit-reverse-apply (car sections) #'magit-apply-diff args))
+ (sections
+ (magit-reverse-apply sections #'magit-apply-diffs args)))
+ (when binaries
+ (user-error "Cannot reverse binary files"))))
+
+(defun magit-reverse-apply (section:s apply args)
+ (funcall apply section:s "--reverse" args
+ (and (not magit-reverse-atomically)
+ (not (member "--3way" args))
+ "--reject")))
+
+(defun magit-reverse-in-index (&rest args)
+ "Reverse the change at point in the index but not the working tree.
+
+Use this command to extract a change from `HEAD', while leaving
+it in the working tree, so that it can later be committed using
+a separate commit. A typical workflow would be:
+
+0. Optionally make sure that there are no uncommitted changes.
+1. Visit the `HEAD' commit and navigate to the change that should
+ not have been included in that commit.
+2. Type \"u\" (`magit-unstage') to reverse it in the index.
+ This assumes that `magit-unstage-committed-changes' is non-nil.
+3. Type \"c e\" to extend `HEAD' with the staged changes,
+ including those that were already staged before.
+4. Optionally stage the remaining changes using \"s\" or \"S\"
+ and then type \"c c\" to create a new commit."
+ (interactive)
+ (magit-reverse (cons "--cached" args)))
+
+;;; Smerge Support
+
+(defun magit-smerge-keep-current ()
+ "Keep the current version of the conflict at point."
+ (interactive)
+ (magit-call-smerge #'smerge-keep-current))
+
+(defun magit-smerge-keep-upper ()
+ "Keep the upper/our version of the conflict at point."
+ (interactive)
+ (magit-call-smerge #'smerge-keep-upper))
+
+(defun magit-smerge-keep-base ()
+ "Keep the base version of the conflict at point."
+ (interactive)
+ (magit-call-smerge #'smerge-keep-base))
+
+(defun magit-smerge-keep-lower ()
+ "Keep the lower/their version of the conflict at point."
+ (interactive)
+ (magit-call-smerge #'smerge-keep-lower))
+
+(defun magit-call-smerge (fn)
+ (pcase-let* ((file (magit-file-at-point t t))
+ (keep (get-file-buffer file))
+ (`(,buf ,pos)
+ (let ((magit-diff-visit-jump-to-change nil))
+ (magit-diff-visit-file--noselect file))))
+ (with-current-buffer buf
+ (save-excursion
+ (save-restriction
+ (unless (<= (point-min) pos (point-max))
+ (widen))
+ (goto-char pos)
+ (condition-case nil
+ (smerge-match-conflict)
+ (error
+ (if (eq fn #'smerge-keep-current)
+ (when (eq this-command #'magit-discard)
+ (re-search-forward smerge-begin-re nil t)
+ (setq fn
+ (magit-read-char-case "Keep side: " t
+ (?o "[o]urs/upper" #'smerge-keep-upper)
+ (?b "[b]ase" #'smerge-keep-base)
+ (?t "[t]heirs/lower" #'smerge-keep-lower))))
+ (re-search-forward smerge-begin-re nil t))))
+ (funcall fn)))
+ (when (and keep (magit-anything-unmerged-p file))
+ (smerge-start-session))
+ (save-buffer))
+ (unless keep
+ (kill-buffer buf))
+ (magit-refresh)))
+
+;;; _
+(provide 'magit-apply)
+;;; magit-apply.el ends here
diff --git a/elpa/magit-20220503.1245/magit-apply.elc b/elpa/magit-20220503.1245/magit-apply.elc
new file mode 100644
index 0000000..3dbfeae
--- /dev/null
+++ b/elpa/magit-20220503.1245/magit-apply.elc
Binary files differ
diff --git a/elpa/magit-20220503.1245/magit-autoloads.el b/elpa/magit-20220503.1245/magit-autoloads.el
new file mode 100644
index 0000000..8eb6727
--- /dev/null
+++ b/elpa/magit-20220503.1245/magit-autoloads.el
@@ -0,0 +1,2601 @@
+;;; magit-autoloads.el --- automatically extracted autoloads -*- lexical-binding: t -*-
+;;
+;;; Code:
+
+(add-to-list 'load-path (directory-file-name
+ (or (file-name-directory #$) (car load-path))))
+
+
+;;;### (autoloads nil "git-rebase" "git-rebase.el" (0 0 0 0))
+;;; Generated autoloads from git-rebase.el
+
+(autoload 'git-rebase-current-line "git-rebase" "\
+Parse current line into a `git-rebase-action' instance.
+If the current line isn't recognized as a rebase line, an
+instance with all nil values is returned." nil nil)
+
+(autoload 'git-rebase-mode "git-rebase" "\
+Major mode for editing of a Git rebase file.
+
+Rebase files are generated when you run 'git rebase -i' or run
+`magit-interactive-rebase'. They describe how Git should perform
+the rebase. See the documentation for git-rebase (e.g., by
+running 'man git-rebase' at the command line) for details.
+
+\(fn)" t nil)
+
+(defconst git-rebase-filename-regexp "/git-rebase-todo\\'")
+
+(add-to-list 'auto-mode-alist (cons git-rebase-filename-regexp #'git-rebase-mode))
+
+(register-definition-prefixes "git-rebase" '("git-rebase-" "magit-imenu--rebase-"))
+
+;;;***
+
+;;;### (autoloads nil "magit" "magit.el" (0 0 0 0))
+;;; Generated autoloads from magit.el
+
+(define-obsolete-variable-alias 'global-magit-file-mode 'magit-define-global-key-bindings "Magit 3.0.0")
+
+(defvar magit-define-global-key-bindings t "\
+Whether to bind some Magit commands in the global keymap.
+
+If this variable is non-nil, then the following bindings may
+be added to the global keymap. The default is t.
+
+key binding
+--- -------
+C-x g magit-status
+C-x M-g magit-dispatch
+C-c M-g magit-file-dispatch
+
+These bindings may be added when `after-init-hook' is run.
+Each binding is added if and only if at that time no other key
+is bound to the same command and no other command is bound to
+the same key. In other words we try to avoid adding bindings
+that are unnecessary, as well as bindings that conflict with
+other bindings.
+
+Adding the above bindings is delayed until `after-init-hook'
+is called to allow users to set the variable anywhere in their
+init file (without having to make sure to do so before `magit'
+is loaded or autoloaded) and to increase the likelihood that
+all the potentially conflicting user bindings have already
+been added.
+
+To set this variable use either `setq' or the Custom interface.
+Do not use the function `customize-set-variable' because doing
+that would cause Magit to be loaded immediately when that form
+is evaluated (this differs from `custom-set-variables', which
+doesn't load the libraries that define the customized variables).
+
+Setting this variable to nil has no effect if that is done after
+the key bindings have already been added.
+
+We recommend that you bind \"C-c g\" instead of \"C-c M-g\" to
+`magit-file-dispatch'. The former is a much better binding
+but the \"C-c <letter>\" namespace is strictly reserved for
+users; preventing Magit from using it by default.
+
+Also see info node `(magit)Commands for Buffers Visiting Files'.")
+
+(custom-autoload 'magit-define-global-key-bindings "magit" t)
+
+(defun magit-maybe-define-global-key-bindings (&optional force) (when magit-define-global-key-bindings (let ((map (current-global-map))) (dolist (elt '(("C-x g" . magit-status) ("C-x M-g" . magit-dispatch) ("C-c M-g" . magit-file-dispatch))) (let ((key (kbd (car elt))) (def (cdr elt))) (when (or force (not (or (lookup-key map key) (where-is-internal def (make-sparse-keymap) t)))) (define-key map key def)))))))
+
+(if after-init-time (magit-maybe-define-global-key-bindings) (add-hook 'after-init-hook #'magit-maybe-define-global-key-bindings t))
+ (autoload 'magit-dispatch "magit" nil t)
+ (autoload 'magit-run "magit" nil t)
+
+(autoload 'magit-git-command "magit" "\
+Execute COMMAND asynchronously; display output.
+
+Interactively, prompt for COMMAND in the minibuffer. \"git \" is
+used as initial input, but can be deleted to run another command.
+
+With a prefix argument COMMAND is run in the top-level directory
+of the current working tree, otherwise in `default-directory'.
+
+\(fn COMMAND)" t nil)
+
+(autoload 'magit-git-command-topdir "magit" "\
+Execute COMMAND asynchronously; display output.
+
+Interactively, prompt for COMMAND in the minibuffer. \"git \" is
+used as initial input, but can be deleted to run another command.
+
+COMMAND is run in the top-level directory of the current
+working tree.
+
+\(fn COMMAND)" t nil)
+
+(autoload 'magit-shell-command "magit" "\
+Execute COMMAND asynchronously; display output.
+
+Interactively, prompt for COMMAND in the minibuffer. With a
+prefix argument COMMAND is run in the top-level directory of
+the current working tree, otherwise in `default-directory'.
+
+\(fn COMMAND)" t nil)
+
+(autoload 'magit-shell-command-topdir "magit" "\
+Execute COMMAND asynchronously; display output.
+
+Interactively, prompt for COMMAND in the minibuffer. COMMAND
+is run in the top-level directory of the current working tree.
+
+\(fn COMMAND)" t nil)
+
+(autoload 'magit-version "magit" "\
+Return the version of Magit currently in use.
+If optional argument PRINT-DEST is non-nil, output
+stream (interactively, the echo area, or the current buffer with
+a prefix argument), also print the used versions of Magit, Git,
+and Emacs to it.
+
+\(fn &optional PRINT-DEST)" t nil)
+
+(register-definition-prefixes "magit" '("magit-"))
+
+;;;***
+
+;;;### (autoloads nil "magit-apply" "magit-apply.el" (0 0 0 0))
+;;; Generated autoloads from magit-apply.el
+
+(autoload 'magit-stage-file "magit-apply" "\
+Stage all changes to FILE.
+With a prefix argument or when there is no file at point ask for
+the file to be staged. Otherwise stage the file at point without
+requiring confirmation.
+
+\(fn FILE)" t nil)
+
+(autoload 'magit-stage-modified "magit-apply" "\
+Stage all changes to files modified in the worktree.
+Stage all new content of tracked files and remove tracked files
+that no longer exist in the working tree from the index also.
+With a prefix argument also stage previously untracked (but not
+ignored) files.
+
+\(fn &optional ALL)" t nil)
+
+(autoload 'magit-unstage-file "magit-apply" "\
+Unstage all changes to FILE.
+With a prefix argument or when there is no file at point ask for
+the file to be unstaged. Otherwise unstage the file at point
+without requiring confirmation.
+
+\(fn FILE)" t nil)
+
+(autoload 'magit-unstage-all "magit-apply" "\
+Remove all changes from the staging area." t nil)
+
+(register-definition-prefixes "magit-apply" '("magit-"))
+
+;;;***
+
+;;;### (autoloads nil "magit-autorevert" "magit-autorevert.el" (0
+;;;;;; 0 0 0))
+;;; Generated autoloads from magit-autorevert.el
+
+(put 'magit-auto-revert-mode 'globalized-minor-mode t)
+
+(defvar magit-auto-revert-mode (not (or global-auto-revert-mode noninteractive)) "\
+Non-nil if Magit-Auto-Revert mode is enabled.
+See the `magit-auto-revert-mode' command
+for a description of this minor mode.
+Setting this variable directly does not take effect;
+either customize it (see the info node `Easy Customization')
+or call the function `magit-auto-revert-mode'.")
+
+(custom-autoload 'magit-auto-revert-mode "magit-autorevert" nil)
+
+(autoload 'magit-auto-revert-mode "magit-autorevert" "\
+Toggle Auto-Revert mode in all buffers.
+With prefix ARG, enable Magit-Auto-Revert mode if ARG is positive;
+otherwise, disable it.
+
+If called from Lisp, toggle the mode if ARG is `toggle'.
+Enable the mode if ARG is nil, omitted, or is a positive number.
+Disable the mode if ARG is a negative number.
+
+Auto-Revert mode is enabled in all buffers where
+`magit-turn-on-auto-revert-mode-if-desired' would do it.
+
+See `auto-revert-mode' for more information on Auto-Revert mode.
+
+\(fn &optional ARG)" t nil)
+
+(register-definition-prefixes "magit-autorevert" '("auto-revert-buffer" "magit-"))
+
+;;;***
+
+;;;### (autoloads nil "magit-base" "magit-base.el" (0 0 0 0))
+;;; Generated autoloads from magit-base.el
+
+(autoload 'magit-emacs-Q-command "magit-base" "\
+Show a shell command that runs an uncustomized Emacs with only Magit loaded.
+See info node `(magit)Debugging Tools' for more information." t nil)
+
+(autoload 'Info-follow-nearest-node--magit-gitman "magit-base" "\
+
+
+\(fn FN &optional FORK)" nil nil)
+
+(advice-add 'Info-follow-nearest-node :around #'Info-follow-nearest-node--magit-gitman)
+
+(advice-add 'org-man-export :around #'org-man-export--magit-gitman)
+
+(autoload 'org-man-export--magit-gitman "magit-base" "\
+
+
+\(fn FN LINK DESCRIPTION FORMAT)" nil nil)
+
+(register-definition-prefixes "magit-base" '("magit-"))
+
+;;;***
+
+;;;### (autoloads nil "magit-bisect" "magit-bisect.el" (0 0 0 0))
+;;; Generated autoloads from magit-bisect.el
+ (autoload 'magit-bisect "magit-bisect" nil t)
+
+(autoload 'magit-bisect-start "magit-bisect" "\
+Start a bisect session.
+
+Bisecting a bug means to find the commit that introduced it.
+This command starts such a bisect session by asking for a known
+good and a known bad commit. To move the session forward use the
+other actions from the bisect transient command (\\<magit-status-mode-map>\\[magit-bisect]).
+
+\(fn BAD GOOD ARGS)" t nil)
+
+(autoload 'magit-bisect-reset "magit-bisect" "\
+After bisecting, cleanup bisection state and return to original `HEAD'." t nil)
+
+(autoload 'magit-bisect-good "magit-bisect" "\
+While bisecting, mark the current commit as good.
+Use this after you have asserted that the commit does not contain
+the bug in question." t nil)
+
+(autoload 'magit-bisect-bad "magit-bisect" "\
+While bisecting, mark the current commit as bad.
+Use this after you have asserted that the commit does contain the
+bug in question." t nil)
+
+(autoload 'magit-bisect-mark "magit-bisect" "\
+While bisecting, mark the current commit with a bisect term.
+During a bisect using alternate terms, commits can still be
+marked with `magit-bisect-good' and `magit-bisect-bad', as those
+commands map to the correct term (\"good\" to --term-old's value
+and \"bad\" to --term-new's). However, in some cases, it can be
+difficult to keep that mapping straight in your head; this
+command provides an interface that exposes the underlying terms." t nil)
+
+(autoload 'magit-bisect-skip "magit-bisect" "\
+While bisecting, skip the current commit.
+Use this if for some reason the current commit is not a good one
+to test. This command lets Git choose a different one." t nil)
+
+(autoload 'magit-bisect-run "magit-bisect" "\
+Bisect automatically by running commands after each step.
+
+Unlike `git bisect run' this can be used before bisecting has
+begun. In that case it behaves like `git bisect start; git
+bisect run'.
+
+\(fn CMDLINE &optional BAD GOOD ARGS)" t nil)
+
+(register-definition-prefixes "magit-bisect" '("magit-"))
+
+;;;***
+
+;;;### (autoloads nil "magit-blame" "magit-blame.el" (0 0 0 0))
+;;; Generated autoloads from magit-blame.el
+ (autoload 'magit-blame-echo "magit-blame" nil t)
+ (autoload 'magit-blame-addition "magit-blame" nil t)
+ (autoload 'magit-blame-removal "magit-blame" nil t)
+ (autoload 'magit-blame-reverse "magit-blame" nil t)
+ (autoload 'magit-blame "magit-blame" nil t)
+
+(register-definition-prefixes "magit-blame" '("magit-"))
+
+;;;***
+
+;;;### (autoloads nil "magit-bookmark" "magit-bookmark.el" (0 0 0
+;;;;;; 0))
+;;; Generated autoloads from magit-bookmark.el
+
+(autoload 'magit--handle-bookmark "magit-bookmark" "\
+Open a bookmark created by `magit--make-bookmark'.
+Call the `magit-*-setup-buffer' function of the the major-mode
+with the variables' values as arguments, which were recorded by
+`magit--make-bookmark'. Ignore `magit-display-buffer-function'.
+
+\(fn BOOKMARK)" nil nil)
+
+(register-definition-prefixes "magit-bookmark" '("magit--make-bookmark"))
+
+;;;***
+
+;;;### (autoloads nil "magit-branch" "magit-branch.el" (0 0 0 0))
+;;; Generated autoloads from magit-branch.el
+ (autoload 'magit-branch "magit" nil t)
+
+(autoload 'magit-checkout "magit-branch" "\
+Checkout REVISION, updating the index and the working tree.
+If REVISION is a local branch, then that becomes the current
+branch. If it is something else, then `HEAD' becomes detached.
+Checkout fails if the working tree or the staging area contain
+changes.
+
+\(git checkout REVISION).
+
+\(fn REVISION &optional ARGS)" t nil)
+
+(autoload 'magit-branch-create "magit-branch" "\
+Create BRANCH at branch or revision START-POINT.
+
+\(fn BRANCH START-POINT)" t nil)
+
+(autoload 'magit-branch-and-checkout "magit-branch" "\
+Create and checkout BRANCH at branch or revision START-POINT.
+
+\(fn BRANCH START-POINT &optional ARGS)" t nil)
+
+(autoload 'magit-branch-or-checkout "magit-branch" "\
+Hybrid between `magit-checkout' and `magit-branch-and-checkout'.
+
+Ask the user for an existing branch or revision. If the user
+input actually can be resolved as a branch or revision, then
+check that out, just like `magit-checkout' would.
+
+Otherwise create and checkout a new branch using the input as
+its name. Before doing so read the starting-point for the new
+branch. This is similar to what `magit-branch-and-checkout'
+does.
+
+\(fn ARG &optional START-POINT)" t nil)
+
+(autoload 'magit-branch-checkout "magit-branch" "\
+Checkout an existing or new local branch.
+
+Read a branch name from the user offering all local branches and
+a subset of remote branches as candidates. Omit remote branches
+for which a local branch by the same name exists from the list
+of candidates. The user can also enter a completely new branch
+name.
+
+- If the user selects an existing local branch, then check that
+ out.
+
+- If the user selects a remote branch, then create and checkout
+ a new local branch with the same name. Configure the selected
+ remote branch as push target.
+
+- If the user enters a new branch name, then create and check
+ that out, after also reading the starting-point from the user.
+
+In the latter two cases the upstream is also set. Whether it is
+set to the chosen START-POINT or something else depends on the
+value of `magit-branch-adjust-remote-upstream-alist', just like
+when using `magit-branch-and-checkout'.
+
+\(fn BRANCH &optional START-POINT)" t nil)
+
+(autoload 'magit-branch-orphan "magit-branch" "\
+Create and checkout an orphan BRANCH with contents from revision START-POINT.
+
+\(fn BRANCH START-POINT)" t nil)
+
+(autoload 'magit-branch-spinout "magit-branch" "\
+Create new branch from the unpushed commits.
+Like `magit-branch-spinoff' but remain on the current branch.
+If there are any uncommitted changes, then behave exactly like
+`magit-branch-spinoff'.
+
+\(fn BRANCH &optional FROM)" t nil)
+
+(autoload 'magit-branch-spinoff "magit-branch" "\
+Create new branch from the unpushed commits.
+
+Create and checkout a new branch starting at and tracking the
+current branch. That branch in turn is reset to the last commit
+it shares with its upstream. If the current branch has no
+upstream or no unpushed commits, then the new branch is created
+anyway and the previously current branch is not touched.
+
+This is useful to create a feature branch after work has already
+began on the old branch (likely but not necessarily \"master\").
+
+If the current branch is a member of the value of option
+`magit-branch-prefer-remote-upstream' (which see), then the
+current branch will be used as the starting point as usual, but
+the upstream of the starting-point may be used as the upstream
+of the new branch, instead of the starting-point itself.
+
+If optional FROM is non-nil, then the source branch is reset
+to `FROM~', instead of to the last commit it shares with its
+upstream. Interactively, FROM is only ever non-nil, if the
+region selects some commits, and among those commits, FROM is
+the commit that is the fewest commits ahead of the source
+branch.
+
+The commit at the other end of the selection actually does not
+matter, all commits between FROM and `HEAD' are moved to the new
+branch. If FROM is not reachable from `HEAD' or is reachable
+from the source branch's upstream, then an error is raised.
+
+\(fn BRANCH &optional FROM)" t nil)
+
+(autoload 'magit-branch-reset "magit-branch" "\
+Reset a branch to the tip of another branch or any other commit.
+
+When the branch being reset is the current branch, then do a
+hard reset. If there are any uncommitted changes, then the user
+has to confirm the reset because those changes would be lost.
+
+This is useful when you have started work on a feature branch but
+realize it's all crap and want to start over.
+
+When resetting to another branch and a prefix argument is used,
+then also set the target branch as the upstream of the branch
+that is being reset.
+
+\(fn BRANCH TO &optional SET-UPSTREAM)" t nil)
+
+(autoload 'magit-branch-delete "magit-branch" "\
+Delete one or multiple branches.
+If the region marks multiple branches, then offer to delete
+those, otherwise prompt for a single branch to be deleted,
+defaulting to the branch at point.
+
+\(fn BRANCHES &optional FORCE)" t nil)
+
+(autoload 'magit-branch-rename "magit-branch" "\
+Rename the branch named OLD to NEW.
+
+With a prefix argument FORCE, rename even if a branch named NEW
+already exists.
+
+If `branch.OLD.pushRemote' is set, then unset it. Depending on
+the value of `magit-branch-rename-push-target' (which see) maybe
+set `branch.NEW.pushRemote' and maybe rename the push-target on
+the remote.
+
+\(fn OLD NEW &optional FORCE)" t nil)
+
+(autoload 'magit-branch-shelve "magit-branch" "\
+Shelve a BRANCH.
+Rename \"refs/heads/BRANCH\" to \"refs/shelved/BRANCH\",
+and also rename the respective reflog file.
+
+\(fn BRANCH)" t nil)
+
+(autoload 'magit-branch-unshelve "magit-branch" "\
+Unshelve a BRANCH
+Rename \"refs/shelved/BRANCH\" to \"refs/heads/BRANCH\",
+and also rename the respective reflog file.
+
+\(fn BRANCH)" t nil)
+ (autoload 'magit-branch-configure "magit-branch" nil t)
+
+(register-definition-prefixes "magit-branch" '("magit-"))
+
+;;;***
+
+;;;### (autoloads nil "magit-bundle" "magit-bundle.el" (0 0 0 0))
+;;; Generated autoloads from magit-bundle.el
+ (autoload 'magit-bundle "magit-bundle" nil t)
+ (autoload 'magit-bundle-import "magit-bundle" nil t)
+
+(autoload 'magit-bundle-create-tracked "magit-bundle" "\
+Create and track a new bundle.
+
+\(fn FILE TAG BRANCH REFS ARGS)" t nil)
+
+(autoload 'magit-bundle-update-tracked "magit-bundle" "\
+Update a bundle that is being tracked using TAG.
+
+\(fn TAG)" t nil)
+
+(autoload 'magit-bundle-verify "magit-bundle" "\
+Check whether FILE is valid and applies to the current repository.
+
+\(fn FILE)" t nil)
+
+(autoload 'magit-bundle-list-heads "magit-bundle" "\
+List the refs in FILE.
+
+\(fn FILE)" t nil)
+
+(register-definition-prefixes "magit-bundle" '("magit-"))
+
+;;;***
+
+;;;### (autoloads nil "magit-clone" "magit-clone.el" (0 0 0 0))
+;;; Generated autoloads from magit-clone.el
+ (autoload 'magit-clone "magit-clone" nil t)
+
+(autoload 'magit-clone-regular "magit-clone" "\
+Create a clone of REPOSITORY in DIRECTORY.
+Then show the status buffer for the new repository.
+
+\(fn REPOSITORY DIRECTORY ARGS)" t nil)
+
+(autoload 'magit-clone-shallow "magit-clone" "\
+Create a shallow clone of REPOSITORY in DIRECTORY.
+Then show the status buffer for the new repository.
+With a prefix argument read the DEPTH of the clone;
+otherwise use 1.
+
+\(fn REPOSITORY DIRECTORY ARGS DEPTH)" t nil)
+
+(autoload 'magit-clone-shallow-since "magit-clone" "\
+Create a shallow clone of REPOSITORY in DIRECTORY.
+Then show the status buffer for the new repository.
+Exclude commits before DATE, which is read from the
+user.
+
+\(fn REPOSITORY DIRECTORY ARGS DATE)" t nil)
+
+(autoload 'magit-clone-shallow-exclude "magit-clone" "\
+Create a shallow clone of REPOSITORY in DIRECTORY.
+Then show the status buffer for the new repository.
+Exclude commits reachable from EXCLUDE, which is a
+branch or tag read from the user.
+
+\(fn REPOSITORY DIRECTORY ARGS EXCLUDE)" t nil)
+
+(autoload 'magit-clone-bare "magit-clone" "\
+Create a bare clone of REPOSITORY in DIRECTORY.
+Then show the status buffer for the new repository.
+
+\(fn REPOSITORY DIRECTORY ARGS)" t nil)
+
+(autoload 'magit-clone-mirror "magit-clone" "\
+Create a mirror of REPOSITORY in DIRECTORY.
+Then show the status buffer for the new repository.
+
+\(fn REPOSITORY DIRECTORY ARGS)" t nil)
+
+(autoload 'magit-clone-sparse "magit-clone" "\
+Clone REPOSITORY into DIRECTORY and create a sparse checkout.
+
+\(fn REPOSITORY DIRECTORY ARGS)" t nil)
+
+(register-definition-prefixes "magit-clone" '("magit-clone-"))
+
+;;;***
+
+;;;### (autoloads nil "magit-commit" "magit-commit.el" (0 0 0 0))
+;;; Generated autoloads from magit-commit.el
+ (autoload 'magit-commit "magit-commit" nil t)
+
+(autoload 'magit-commit-create "magit-commit" "\
+Create a new commit on `HEAD'.
+With a prefix argument, amend to the commit at `HEAD' instead.
+
+\(git commit [--amend] ARGS)
+
+\(fn &optional ARGS)" t nil)
+
+(autoload 'magit-commit-amend "magit-commit" "\
+Amend the last commit.
+
+\(git commit --amend ARGS)
+
+\(fn &optional ARGS)" t nil)
+
+(autoload 'magit-commit-extend "magit-commit" "\
+Amend the last commit, without editing the message.
+
+With a prefix argument keep the committer date, otherwise change
+it. The option `magit-commit-extend-override-date' can be used
+to inverse the meaning of the prefix argument.
+\(git commit
+--amend --no-edit)
+
+\(fn &optional ARGS OVERRIDE-DATE)" t nil)
+
+(autoload 'magit-commit-reword "magit-commit" "\
+Reword the last commit, ignoring staged changes.
+
+With a prefix argument keep the committer date, otherwise change
+it. The option `magit-commit-reword-override-date' can be used
+to inverse the meaning of the prefix argument.
+
+Non-interactively respect the optional OVERRIDE-DATE argument
+and ignore the option.
+
+\(git commit --amend --only)
+
+\(fn &optional ARGS OVERRIDE-DATE)" t nil)
+
+(autoload 'magit-commit-fixup "magit-commit" "\
+Create a fixup commit.
+
+With a prefix argument the target COMMIT has to be confirmed.
+Otherwise the commit at point may be used without confirmation
+depending on the value of option `magit-commit-squash-confirm'.
+
+\(fn &optional COMMIT ARGS)" t nil)
+
+(autoload 'magit-commit-squash "magit-commit" "\
+Create a squash commit, without editing the squash message.
+
+With a prefix argument the target COMMIT has to be confirmed.
+Otherwise the commit at point may be used without confirmation
+depending on the value of option `magit-commit-squash-confirm'.
+
+If you want to immediately add a message to the squash commit,
+then use `magit-commit-augment' instead of this command.
+
+\(fn &optional COMMIT ARGS)" t nil)
+
+(autoload 'magit-commit-augment "magit-commit" "\
+Create a squash commit, editing the squash message.
+
+With a prefix argument the target COMMIT has to be confirmed.
+Otherwise the commit at point may be used without confirmation
+depending on the value of option `magit-commit-squash-confirm'.
+
+\(fn &optional COMMIT ARGS)" t nil)
+
+(autoload 'magit-commit-instant-fixup "magit-commit" "\
+Create a fixup commit targeting COMMIT and instantly rebase.
+
+\(fn &optional COMMIT ARGS)" t nil)
+
+(autoload 'magit-commit-instant-squash "magit-commit" "\
+Create a squash commit targeting COMMIT and instantly rebase.
+
+\(fn &optional COMMIT ARGS)" t nil)
+
+(autoload 'magit-commit-reshelve "magit-commit" "\
+Change the committer date and possibly the author date of `HEAD'.
+
+The current time is used as the initial minibuffer input and the
+original author or committer date is available as the previous
+history element.
+
+Both the author and the committer dates are changes, unless one
+of the following is true, in which case only the committer date
+is updated:
+- You are not the author of the commit that is being reshelved.
+- The command was invoked with a prefix argument.
+- Non-interactively if UPDATE-AUTHOR is nil.
+
+\(fn DATE UPDATE-AUTHOR &optional ARGS)" t nil)
+
+(autoload 'magit-commit-absorb-modules "magit-commit" "\
+Spread modified modules across recent commits.
+
+\(fn PHASE COMMIT)" t nil)
+ (autoload 'magit-commit-absorb "magit-commit" nil t)
+ (autoload 'magit-commit-autofixup "magit-commit" nil t)
+
+(register-definition-prefixes "magit-commit" '("magit-"))
+
+;;;***
+
+;;;### (autoloads nil "magit-diff" "magit-diff.el" (0 0 0 0))
+;;; Generated autoloads from magit-diff.el
+ (autoload 'magit-diff "magit-diff" nil t)
+ (autoload 'magit-diff-refresh "magit-diff" nil t)
+
+(autoload 'magit-diff-dwim "magit-diff" "\
+Show changes for the thing at point.
+
+\(fn &optional ARGS FILES)" t nil)
+
+(autoload 'magit-diff-range "magit-diff" "\
+Show differences between two commits.
+
+REV-OR-RANGE should be a range or a single revision. If it is a
+revision, then show changes in the working tree relative to that
+revision. If it is a range, but one side is omitted, then show
+changes relative to `HEAD'.
+
+If the region is active, use the revisions on the first and last
+line of the region as the two sides of the range. With a prefix
+argument, instead of diffing the revisions, choose a revision to
+view changes along, starting at the common ancestor of both
+revisions (i.e., use a \"...\" range).
+
+\(fn REV-OR-RANGE &optional ARGS FILES)" t nil)
+
+(autoload 'magit-diff-working-tree "magit-diff" "\
+Show changes between the current working tree and the `HEAD' commit.
+With a prefix argument show changes between the working tree and
+a commit read from the minibuffer.
+
+\(fn &optional REV ARGS FILES)" t nil)
+
+(autoload 'magit-diff-staged "magit-diff" "\
+Show changes between the index and the `HEAD' commit.
+With a prefix argument show changes between the index and
+a commit read from the minibuffer.
+
+\(fn &optional REV ARGS FILES)" t nil)
+
+(autoload 'magit-diff-unstaged "magit-diff" "\
+Show changes between the working tree and the index.
+
+\(fn &optional ARGS FILES)" t nil)
+
+(autoload 'magit-diff-unmerged "magit-diff" "\
+Show changes that are being merged.
+
+\(fn &optional ARGS FILES)" t nil)
+
+(autoload 'magit-diff-while-committing "magit-diff" "\
+While committing, show the changes that are about to be committed.
+While amending, invoking the command again toggles between
+showing just the new changes or all the changes that will
+be committed.
+
+\(fn &optional ARGS)" t nil)
+
+(autoload 'magit-diff-buffer-file "magit-diff" "\
+Show diff for the blob or file visited in the current buffer.
+
+When the buffer visits a blob, then show the respective commit.
+When the buffer visits a file, then show the differenced between
+`HEAD' and the working tree. In both cases limit the diff to
+the file or blob." t nil)
+
+(autoload 'magit-diff-paths "magit-diff" "\
+Show changes between any two files on disk.
+
+\(fn A B)" t nil)
+
+(autoload 'magit-show-commit "magit-diff" "\
+Visit the revision at point in another buffer.
+If there is no revision at point or with a prefix argument prompt
+for a revision.
+
+\(fn REV &optional ARGS FILES MODULE)" t nil)
+
+(register-definition-prefixes "magit-diff" '("magit-"))
+
+;;;***
+
+;;;### (autoloads nil "magit-ediff" "magit-ediff.el" (0 0 0 0))
+;;; Generated autoloads from magit-ediff.el
+ (autoload 'magit-ediff "magit-ediff" nil)
+
+(autoload 'magit-ediff-resolve "magit-ediff" "\
+Resolve outstanding conflicts in FILE using Ediff.
+FILE has to be relative to the top directory of the repository.
+
+In the rare event that you want to manually resolve all
+conflicts, including those already resolved by Git, use
+`ediff-merge-revisions-with-ancestor'.
+
+\(fn FILE)" t nil)
+
+(autoload 'magit-ediff-stage "magit-ediff" "\
+Stage and unstage changes to FILE using Ediff.
+FILE has to be relative to the top directory of the repository.
+
+\(fn FILE)" t nil)
+
+(autoload 'magit-ediff-compare "magit-ediff" "\
+Compare REVA:FILEA with REVB:FILEB using Ediff.
+
+FILEA and FILEB have to be relative to the top directory of the
+repository. If REVA or REVB is nil, then this stands for the
+working tree state.
+
+If the region is active, use the revisions on the first and last
+line of the region. With a prefix argument, instead of diffing
+the revisions, choose a revision to view changes along, starting
+at the common ancestor of both revisions (i.e., use a \"...\"
+range).
+
+\(fn REVA REVB FILEA FILEB)" t nil)
+
+(autoload 'magit-ediff-dwim "magit-ediff" "\
+Compare, stage, or resolve using Ediff.
+This command tries to guess what file, and what commit or range
+the user wants to compare, stage, or resolve using Ediff. It
+might only be able to guess either the file, or range or commit,
+in which case the user is asked about the other. It might not
+always guess right, in which case the appropriate `magit-ediff-*'
+command has to be used explicitly. If it cannot read the user's
+mind at all, then it asks the user for a command to run." t nil)
+
+(autoload 'magit-ediff-show-staged "magit-ediff" "\
+Show staged changes using Ediff.
+
+This only allows looking at the changes; to stage, unstage,
+and discard changes using Ediff, use `magit-ediff-stage'.
+
+FILE must be relative to the top directory of the repository.
+
+\(fn FILE)" t nil)
+
+(autoload 'magit-ediff-show-unstaged "magit-ediff" "\
+Show unstaged changes using Ediff.
+
+This only allows looking at the changes; to stage, unstage,
+and discard changes using Ediff, use `magit-ediff-stage'.
+
+FILE must be relative to the top directory of the repository.
+
+\(fn FILE)" t nil)
+
+(autoload 'magit-ediff-show-working-tree "magit-ediff" "\
+Show changes between `HEAD' and working tree using Ediff.
+FILE must be relative to the top directory of the repository.
+
+\(fn FILE)" t nil)
+
+(autoload 'magit-ediff-show-commit "magit-ediff" "\
+Show changes introduced by COMMIT using Ediff.
+
+\(fn COMMIT)" t nil)
+
+(autoload 'magit-ediff-show-stash "magit-ediff" "\
+Show changes introduced by STASH using Ediff.
+`magit-ediff-show-stash-with-index' controls whether a
+three-buffer Ediff is used in order to distinguish changes in the
+stash that were staged.
+
+\(fn STASH)" t nil)
+
+(register-definition-prefixes "magit-ediff" '("magit-ediff-"))
+
+;;;***
+
+;;;### (autoloads nil "magit-extras" "magit-extras.el" (0 0 0 0))
+;;; Generated autoloads from magit-extras.el
+ (autoload 'magit-git-mergetool "magit-extras" nil t)
+
+(autoload 'magit-run-git-gui-blame "magit-extras" "\
+Run `git gui blame' on the given FILENAME and COMMIT.
+Interactively run it for the current file and the `HEAD', with a
+prefix or when the current file cannot be determined let the user
+choose. When the current buffer is visiting FILENAME instruct
+blame to center around the line point is on.
+
+\(fn COMMIT FILENAME &optional LINENUM)" t nil)
+
+(autoload 'magit-run-git-gui "magit-extras" "\
+Run `git gui' for the current git repository." t nil)
+
+(autoload 'magit-run-gitk "magit-extras" "\
+Run `gitk' in the current repository." t nil)
+
+(autoload 'magit-run-gitk-branches "magit-extras" "\
+Run `gitk --branches' in the current repository." t nil)
+
+(autoload 'magit-run-gitk-all "magit-extras" "\
+Run `gitk --all' in the current repository." t nil)
+
+(autoload 'ido-enter-magit-status "magit-extras" "\
+Drop into `magit-status' from file switching.
+
+This command does not work in Emacs 26.1.
+See https://github.com/magit/magit/issues/3634
+and https://debbugs.gnu.org/cgi/bugreport.cgi?bug=31707.
+
+To make this command available use something like:
+
+ (add-hook \\='ido-setup-hook
+ (lambda ()
+ (define-key ido-completion-map
+ (kbd \"C-x g\") \\='ido-enter-magit-status)))
+
+Starting with Emacs 25.1 the Ido keymaps are defined just once
+instead of every time Ido is invoked, so now you can modify it
+like pretty much every other keymap:
+
+ (define-key ido-common-completion-map
+ (kbd \"C-x g\") \\='ido-enter-magit-status)" t nil)
+
+(autoload 'magit-project-status "magit-extras" "\
+Run `magit-status' in the current project's root." t nil)
+
+(autoload 'magit-dired-jump "magit-extras" "\
+Visit file at point using Dired.
+With a prefix argument, visit in another window. If there
+is no file at point, then instead visit `default-directory'.
+
+\(fn &optional OTHER-WINDOW)" t nil)
+
+(autoload 'magit-dired-log "magit-extras" "\
+Show log for all marked files, or the current file.
+
+\(fn &optional FOLLOW)" t nil)
+
+(autoload 'magit-dired-am-apply-patches "magit-extras" "\
+In Dired, apply the marked (or next ARG) files as patches.
+If inside a repository, then apply in that. Otherwise prompt
+for a repository.
+
+\(fn REPO &optional ARG)" t nil)
+
+(autoload 'magit-do-async-shell-command "magit-extras" "\
+Open FILE with `dired-do-async-shell-command'.
+Interactively, open the file at point.
+
+\(fn FILE)" t nil)
+
+(autoload 'magit-previous-line "magit-extras" "\
+Like `previous-line' but with Magit-specific shift-selection.
+
+Magit's selection mechanism is based on the region but selects an
+area that is larger than the region. This causes `previous-line'
+when invoked while holding the shift key to move up one line and
+thereby select two lines. When invoked inside a hunk body this
+command does not move point on the first invocation and thereby
+it only selects a single line. Which inconsistency you prefer
+is a matter of preference.
+
+\(fn &optional ARG TRY-VSCROLL)" t nil)
+
+(function-put 'magit-previous-line 'interactive-only '"use `forward-line' with negative argument instead.")
+
+(autoload 'magit-next-line "magit-extras" "\
+Like `next-line' but with Magit-specific shift-selection.
+
+Magit's selection mechanism is based on the region but selects
+an area that is larger than the region. This causes `next-line'
+when invoked while holding the shift key to move down one line
+and thereby select two lines. When invoked inside a hunk body
+this command does not move point on the first invocation and
+thereby it only selects a single line. Which inconsistency you
+prefer is a matter of preference.
+
+\(fn &optional ARG TRY-VSCROLL)" t nil)
+
+(function-put 'magit-next-line 'interactive-only 'forward-line)
+
+(autoload 'magit-clean "magit-extras" "\
+Remove untracked files from the working tree.
+With a prefix argument also remove ignored files,
+with two prefix arguments remove ignored files only.
+
+\(git clean -f -d [-x|-X])
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'magit-generate-changelog "magit-extras" "\
+Insert ChangeLog entries into the current buffer.
+
+The entries are generated from the diff being committed.
+If prefix argument, AMENDING, is non-nil, include changes
+in HEAD as well as staged changes in the diff to check.
+
+\(fn &optional AMENDING)" t nil)
+
+(autoload 'magit-add-change-log-entry "magit-extras" "\
+Find change log file and add date entry and item for current change.
+This differs from `add-change-log-entry' (which see) in that
+it acts on the current hunk in a Magit buffer instead of on
+a position in a file-visiting buffer.
+
+\(fn &optional WHOAMI FILE-NAME OTHER-WINDOW)" t nil)
+
+(autoload 'magit-add-change-log-entry-other-window "magit-extras" "\
+Find change log file in other window and add entry and item.
+This differs from `add-change-log-entry-other-window' (which see)
+in that it acts on the current hunk in a Magit buffer instead of
+on a position in a file-visiting buffer.
+
+\(fn &optional WHOAMI FILE-NAME)" t nil)
+
+(autoload 'magit-edit-line-commit "magit-extras" "\
+Edit the commit that added the current line.
+
+With a prefix argument edit the commit that removes the line,
+if any. The commit is determined using `git blame' and made
+editable using `git rebase --interactive' if it is reachable
+from `HEAD', or by checking out the commit (or a branch that
+points at it) otherwise.
+
+\(fn &optional TYPE)" t nil)
+
+(autoload 'magit-diff-edit-hunk-commit "magit-extras" "\
+From a hunk, edit the respective commit and visit the file.
+
+First visit the file being modified by the hunk at the correct
+location using `magit-diff-visit-file'. This actually visits a
+blob. When point is on a diff header, not within an individual
+hunk, then this visits the blob the first hunk is about.
+
+Then invoke `magit-edit-line-commit', which uses an interactive
+rebase to make the commit editable, or if that is not possible
+because the commit is not reachable from `HEAD' by checking out
+that commit directly. This also causes the actual worktree file
+to be visited.
+
+Neither the blob nor the file buffer are killed when finishing
+the rebase. If that is undesirable, then it might be better to
+use `magit-rebase-edit-command' instead of this command.
+
+\(fn FILE)" t nil)
+
+(autoload 'magit-reshelve-since "magit-extras" "\
+Change the author and committer dates of the commits since REV.
+
+Ask the user for the first reachable commit whose dates should
+be changed. Then read the new date for that commit. The initial
+minibuffer input and the previous history element offer good
+values. The next commit will be created one minute later and so
+on.
+
+This command is only intended for interactive use and should only
+be used on highly rearranged and unpublished history.
+
+If KEYID is non-nil, then use that to sign all reshelved commits.
+Interactively use the value of the \"--gpg-sign\" option in the
+list returned by `magit-rebase-arguments'.
+
+\(fn REV KEYID)" t nil)
+
+(autoload 'magit-pop-revision-stack "magit-extras" "\
+Insert a representation of a revision into the current buffer.
+
+Pop a revision from the `magit-revision-stack' and insert it into
+the current buffer according to `magit-pop-revision-stack-format'.
+Revisions can be put on the stack using `magit-copy-section-value'
+and `magit-copy-buffer-revision'.
+
+If the stack is empty or with a prefix argument, instead read a
+revision in the minibuffer. By using the minibuffer history this
+allows selecting an item which was popped earlier or to insert an
+arbitrary reference or revision without first pushing it onto the
+stack.
+
+When reading the revision from the minibuffer, then it might not
+be possible to guess the correct repository. When this command
+is called inside a repository (e.g. while composing a commit
+message), then that repository is used. Otherwise (e.g. while
+composing an email) then the repository recorded for the top
+element of the stack is used (even though we insert another
+revision). If not called inside a repository and with an empty
+stack, or with two prefix arguments, then read the repository in
+the minibuffer too.
+
+\(fn REV TOPLEVEL)" t nil)
+
+(autoload 'magit-copy-section-value "magit-extras" "\
+Save the value of the current section for later use.
+
+Save the section value to the `kill-ring', and, provided that
+the current section is a commit, branch, or tag section, push
+the (referenced) revision to the `magit-revision-stack' for use
+with `magit-pop-revision-stack'.
+
+When `magit-copy-revision-abbreviated' is non-nil, save the
+abbreviated revision to the `kill-ring' and the
+`magit-revision-stack'.
+
+When the current section is a branch or a tag, and a prefix
+argument is used, then save the revision at its tip to the
+`kill-ring' instead of the reference name.
+
+When the region is active, then save that to the `kill-ring',
+like `kill-ring-save' would, instead of behaving as described
+above. If a prefix argument is used and the region is within
+a hunk, then strip the diff marker column and keep only either
+the added or removed lines, depending on the sign of the prefix
+argument.
+
+\(fn ARG)" t nil)
+
+(autoload 'magit-copy-buffer-revision "magit-extras" "\
+Save the revision of the current buffer for later use.
+
+Save the revision shown in the current buffer to the `kill-ring'
+and push it to the `magit-revision-stack'.
+
+This command is mainly intended for use in `magit-revision-mode'
+buffers, the only buffers where it is always unambiguous exactly
+which revision should be saved.
+
+Most other Magit buffers usually show more than one revision, in
+some way or another, so this command has to select one of them,
+and that choice might not always be the one you think would have
+been the best pick.
+
+In such buffers it is often more useful to save the value of
+the current section instead, using `magit-copy-section-value'.
+
+When the region is active, then save that to the `kill-ring',
+like `kill-ring-save' would, instead of behaving as described
+above.
+
+When `magit-copy-revision-abbreviated' is non-nil, save the
+abbreviated revision to the `kill-ring' and the
+`magit-revision-stack'." t nil)
+
+(autoload 'magit-display-repository-buffer "magit-extras" "\
+Display a Magit buffer belonging to the current Git repository.
+The buffer is displayed using `magit-display-buffer', which see.
+
+\(fn BUFFER)" t nil)
+
+(autoload 'magit-switch-to-repository-buffer "magit-extras" "\
+Switch to a Magit buffer belonging to the current Git repository.
+
+\(fn BUFFER)" t nil)
+
+(autoload 'magit-switch-to-repository-buffer-other-window "magit-extras" "\
+Switch to a Magit buffer belonging to the current Git repository.
+
+\(fn BUFFER)" t nil)
+
+(autoload 'magit-switch-to-repository-buffer-other-frame "magit-extras" "\
+Switch to a Magit buffer belonging to the current Git repository.
+
+\(fn BUFFER)" t nil)
+
+(autoload 'magit-abort-dwim "magit-extras" "\
+Abort current operation.
+Depending on the context, this will abort a merge, a rebase, a
+patch application, a cherry-pick, a revert, or a bisect." t nil)
+
+(register-definition-prefixes "magit-extras" '("magit-"))
+
+;;;***
+
+;;;### (autoloads nil "magit-fetch" "magit-fetch.el" (0 0 0 0))
+;;; Generated autoloads from magit-fetch.el
+ (autoload 'magit-fetch "magit-fetch" nil t)
+ (autoload 'magit-fetch-from-pushremote "magit-fetch" nil t)
+ (autoload 'magit-fetch-from-upstream "magit-fetch" nil t)
+
+(autoload 'magit-fetch-other "magit-fetch" "\
+Fetch from another repository.
+
+\(fn REMOTE ARGS)" t nil)
+
+(autoload 'magit-fetch-branch "magit-fetch" "\
+Fetch a BRANCH from a REMOTE.
+
+\(fn REMOTE BRANCH ARGS)" t nil)
+
+(autoload 'magit-fetch-refspec "magit-fetch" "\
+Fetch a REFSPEC from a REMOTE.
+
+\(fn REMOTE REFSPEC ARGS)" t nil)
+
+(autoload 'magit-fetch-all "magit-fetch" "\
+Fetch from all remotes.
+
+\(fn ARGS)" t nil)
+
+(autoload 'magit-fetch-all-prune "magit-fetch" "\
+Fetch from all remotes, and prune.
+Prune remote tracking branches for branches that have been
+removed on the respective remote." t nil)
+
+(autoload 'magit-fetch-all-no-prune "magit-fetch" "\
+Fetch from all remotes." t nil)
+ (autoload 'magit-fetch-modules "magit-fetch" nil t)
+
+(register-definition-prefixes "magit-fetch" '("magit-"))
+
+;;;***
+
+;;;### (autoloads nil "magit-files" "magit-files.el" (0 0 0 0))
+;;; Generated autoloads from magit-files.el
+
+(autoload 'magit-find-file "magit-files" "\
+View FILE from REV.
+Switch to a buffer visiting blob REV:FILE, creating one if none
+already exists. If prior to calling this command the current
+buffer and/or cursor position is about the same file, then go
+to the line and column corresponding to that location.
+
+\(fn REV FILE)" t nil)
+
+(autoload 'magit-find-file-other-window "magit-files" "\
+View FILE from REV, in another window.
+Switch to a buffer visiting blob REV:FILE, creating one if none
+already exists. If prior to calling this command the current
+buffer and/or cursor position is about the same file, then go to
+the line and column corresponding to that location.
+
+\(fn REV FILE)" t nil)
+
+(autoload 'magit-find-file-other-frame "magit-files" "\
+View FILE from REV, in another frame.
+Switch to a buffer visiting blob REV:FILE, creating one if none
+already exists. If prior to calling this command the current
+buffer and/or cursor position is about the same file, then go to
+the line and column corresponding to that location.
+
+\(fn REV FILE)" t nil)
+ (autoload 'magit-file-dispatch "magit" nil t)
+
+(autoload 'magit-blob-visit-file "magit-files" "\
+View the file from the worktree corresponding to the current blob.
+When visiting a blob or the version from the index, then go to
+the same location in the respective file in the working tree." t nil)
+
+(autoload 'magit-file-checkout "magit-files" "\
+Checkout FILE from REV.
+
+\(fn REV FILE)" t nil)
+
+(register-definition-prefixes "magit-files" '("magit-"))
+
+;;;***
+
+;;;### (autoloads nil "magit-git" "magit-git.el" (0 0 0 0))
+;;; Generated autoloads from magit-git.el
+
+(register-definition-prefixes "magit-git" '("magit-"))
+
+;;;***
+
+;;;### (autoloads nil "magit-gitignore" "magit-gitignore.el" (0 0
+;;;;;; 0 0))
+;;; Generated autoloads from magit-gitignore.el
+ (autoload 'magit-gitignore "magit-gitignore" nil t)
+
+(autoload 'magit-gitignore-in-topdir "magit-gitignore" "\
+Add the Git ignore RULE to the top-level \".gitignore\" file.
+Since this file is tracked, it is shared with other clones of the
+repository. Also stage the file.
+
+\(fn RULE)" t nil)
+
+(autoload 'magit-gitignore-in-subdir "magit-gitignore" "\
+Add the Git ignore RULE to a \".gitignore\" file in DIRECTORY.
+Prompt the user for a directory and add the rule to the
+\".gitignore\" file in that directory. Since such files are
+tracked, they are shared with other clones of the repository.
+Also stage the file.
+
+\(fn RULE DIRECTORY)" t nil)
+
+(autoload 'magit-gitignore-in-gitdir "magit-gitignore" "\
+Add the Git ignore RULE to \"$GIT_DIR/info/exclude\".
+Rules in that file only affects this clone of the repository.
+
+\(fn RULE)" t nil)
+
+(autoload 'magit-gitignore-on-system "magit-gitignore" "\
+Add the Git ignore RULE to the file specified by `core.excludesFile'.
+Rules that are defined in that file affect all local repositories.
+
+\(fn RULE)" t nil)
+
+(autoload 'magit-skip-worktree "magit-gitignore" "\
+Call \"git update-index --skip-worktree -- FILE\".
+
+\(fn FILE)" t nil)
+
+(autoload 'magit-no-skip-worktree "magit-gitignore" "\
+Call \"git update-index --no-skip-worktree -- FILE\".
+
+\(fn FILE)" t nil)
+
+(autoload 'magit-assume-unchanged "magit-gitignore" "\
+Call \"git update-index --assume-unchanged -- FILE\".
+
+\(fn FILE)" t nil)
+
+(autoload 'magit-no-assume-unchanged "magit-gitignore" "\
+Call \"git update-index --no-assume-unchanged -- FILE\".
+
+\(fn FILE)" t nil)
+
+(register-definition-prefixes "magit-gitignore" '("magit-"))
+
+;;;***
+
+;;;### (autoloads nil "magit-log" "magit-log.el" (0 0 0 0))
+;;; Generated autoloads from magit-log.el
+ (autoload 'magit-log "magit-log" nil t)
+ (autoload 'magit-log-refresh "magit-log" nil t)
+
+(autoload 'magit-log-current "magit-log" "\
+Show log for the current branch.
+When `HEAD' is detached or with a prefix argument show log for
+one or more revs read from the minibuffer.
+
+\(fn REVS &optional ARGS FILES)" t nil)
+
+(autoload 'magit-log-head "magit-log" "\
+Show log for `HEAD'.
+
+\(fn &optional ARGS FILES)" t nil)
+
+(autoload 'magit-log-related "magit-log" "\
+Show log for the current branch, its upstream and its push target.
+When the upstream is a local branch, then also show its own
+upstream. When `HEAD' is detached, then show log for that, the
+previously checked out branch and its upstream and push-target.
+
+\(fn REVS &optional ARGS FILES)" t nil)
+
+(autoload 'magit-log-other "magit-log" "\
+Show log for one or more revs read from the minibuffer.
+The user can input any revision or revisions separated by a
+space, or even ranges, but only branches and tags, and a
+representation of the commit at point, are available as
+completion candidates.
+
+\(fn REVS &optional ARGS FILES)" t nil)
+
+(autoload 'magit-log-branches "magit-log" "\
+Show log for all local branches and `HEAD'.
+
+\(fn &optional ARGS FILES)" t nil)
+
+(autoload 'magit-log-matching-branches "magit-log" "\
+Show log for all branches matching PATTERN and `HEAD'.
+
+\(fn PATTERN &optional ARGS FILES)" t nil)
+
+(autoload 'magit-log-matching-tags "magit-log" "\
+Show log for all tags matching PATTERN and `HEAD'.
+
+\(fn PATTERN &optional ARGS FILES)" t nil)
+
+(autoload 'magit-log-all-branches "magit-log" "\
+Show log for all local and remote branches and `HEAD'.
+
+\(fn &optional ARGS FILES)" t nil)
+
+(autoload 'magit-log-all "magit-log" "\
+Show log for all references and `HEAD'.
+
+\(fn &optional ARGS FILES)" t nil)
+
+(autoload 'magit-log-buffer-file "magit-log" "\
+Show log for the blob or file visited in the current buffer.
+With a prefix argument or when `--follow' is an active log
+argument, then follow renames. When the region is active,
+restrict the log to the lines that the region touches.
+
+\(fn &optional FOLLOW BEG END)" t nil)
+
+(autoload 'magit-log-trace-definition "magit-log" "\
+Show log for the definition at point.
+
+\(fn FILE FN REV)" t nil)
+
+(autoload 'magit-log-merged "magit-log" "\
+Show log for the merge of COMMIT into BRANCH.
+
+More precisely, find merge commit M that brought COMMIT into
+BRANCH, and show the log of the range \"M^1..M\". If COMMIT is
+directly on BRANCH, then show approximately twenty surrounding
+commits instead.
+
+This command requires git-when-merged, which is available from
+https://github.com/mhagger/git-when-merged.
+
+\(fn COMMIT BRANCH &optional ARGS FILES)" t nil)
+
+(autoload 'magit-log-move-to-parent "magit-log" "\
+Move to the Nth parent of the current commit.
+
+\(fn &optional N)" t nil)
+ (autoload 'magit-shortlog "magit-log" nil t)
+
+(autoload 'magit-shortlog-since "magit-log" "\
+Show a history summary for commits since REV.
+
+\(fn REV ARGS)" t nil)
+
+(autoload 'magit-shortlog-range "magit-log" "\
+Show a history summary for commit or range REV-OR-RANGE.
+
+\(fn REV-OR-RANGE ARGS)" t nil)
+
+(autoload 'magit-cherry "magit-log" "\
+Show commits in a branch that are not merged in the upstream branch.
+
+\(fn HEAD UPSTREAM)" t nil)
+
+(register-definition-prefixes "magit-log" '("magit-"))
+
+;;;***
+
+;;;### (autoloads nil "magit-margin" "magit-margin.el" (0 0 0 0))
+;;; Generated autoloads from magit-margin.el
+
+(register-definition-prefixes "magit-margin" '("magit-"))
+
+;;;***
+
+;;;### (autoloads nil "magit-merge" "magit-merge.el" (0 0 0 0))
+;;; Generated autoloads from magit-merge.el
+ (autoload 'magit-merge "magit" nil t)
+
+(autoload 'magit-merge-plain "magit-merge" "\
+Merge commit REV into the current branch; using default message.
+
+Unless there are conflicts or a prefix argument is used create a
+merge commit using a generic commit message and without letting
+the user inspect the result. With a prefix argument pretend the
+merge failed to give the user the opportunity to inspect the
+merge.
+
+\(git merge --no-edit|--no-commit [ARGS] REV)
+
+\(fn REV &optional ARGS NOCOMMIT)" t nil)
+
+(autoload 'magit-merge-editmsg "magit-merge" "\
+Merge commit REV into the current branch; and edit message.
+Perform the merge and prepare a commit message but let the user
+edit it.
+
+\(git merge --edit --no-ff [ARGS] REV)
+
+\(fn REV &optional ARGS)" t nil)
+
+(autoload 'magit-merge-nocommit "magit-merge" "\
+Merge commit REV into the current branch; pretending it failed.
+Pretend the merge failed to give the user the opportunity to
+inspect the merge and change the commit message.
+
+\(git merge --no-commit --no-ff [ARGS] REV)
+
+\(fn REV &optional ARGS)" t nil)
+
+(autoload 'magit-merge-into "magit-merge" "\
+Merge the current branch into BRANCH and remove the former.
+
+Before merging, force push the source branch to its push-remote,
+provided the respective remote branch already exists, ensuring
+that the respective pull-request (if any) won't get stuck on some
+obsolete version of the commits that are being merged. Finally
+if `forge-branch-pullreq' was used to create the merged branch,
+then also remove the respective remote branch.
+
+\(fn BRANCH &optional ARGS)" t nil)
+
+(autoload 'magit-merge-absorb "magit-merge" "\
+Merge BRANCH into the current branch and remove the former.
+
+Before merging, force push the source branch to its push-remote,
+provided the respective remote branch already exists, ensuring
+that the respective pull-request (if any) won't get stuck on some
+obsolete version of the commits that are being merged. Finally
+if `forge-branch-pullreq' was used to create the merged branch,
+then also remove the respective remote branch.
+
+\(fn BRANCH &optional ARGS)" t nil)
+
+(autoload 'magit-merge-squash "magit-merge" "\
+Squash commit REV into the current branch; don't create a commit.
+
+\(git merge --squash REV)
+
+\(fn REV)" t nil)
+
+(autoload 'magit-merge-preview "magit-merge" "\
+Preview result of merging REV into the current branch.
+
+\(fn REV)" t nil)
+
+(autoload 'magit-merge-abort "magit-merge" "\
+Abort the current merge operation.
+
+\(git merge --abort)" t nil)
+
+(register-definition-prefixes "magit-merge" '("magit-"))
+
+;;;***
+
+;;;### (autoloads nil "magit-mode" "magit-mode.el" (0 0 0 0))
+;;; Generated autoloads from magit-mode.el
+
+(autoload 'magit-info "magit-mode" "\
+Visit the Magit manual." t nil)
+
+(register-definition-prefixes "magit-mode" '("disable-magit-save-buffers" "magit-"))
+
+;;;***
+
+;;;### (autoloads nil "magit-notes" "magit-notes.el" (0 0 0 0))
+;;; Generated autoloads from magit-notes.el
+ (autoload 'magit-notes "magit" nil t)
+
+(register-definition-prefixes "magit-notes" '("magit-notes-"))
+
+;;;***
+
+;;;### (autoloads nil "magit-obsolete" "magit-obsolete.el" (0 0 0
+;;;;;; 0))
+;;; Generated autoloads from magit-obsolete.el
+
+(register-definition-prefixes "magit-obsolete" '("magit--magit-popup-warning"))
+
+;;;***
+
+;;;### (autoloads nil "magit-patch" "magit-patch.el" (0 0 0 0))
+;;; Generated autoloads from magit-patch.el
+ (autoload 'magit-patch "magit-patch" nil t)
+ (autoload 'magit-patch-create "magit-patch" nil t)
+ (autoload 'magit-patch-apply "magit-patch" nil t)
+
+(autoload 'magit-patch-save "magit-patch" "\
+Write current diff into patch FILE.
+
+What arguments are used to create the patch depends on the value
+of `magit-patch-save-arguments' and whether a prefix argument is
+used.
+
+If the value is the symbol `buffer', then use the same arguments
+as the buffer. With a prefix argument use no arguments.
+
+If the value is a list beginning with the symbol `exclude', then
+use the same arguments as the buffer except for those matched by
+entries in the cdr of the list. The comparison is done using
+`string-prefix-p'. With a prefix argument use the same arguments
+as the buffer.
+
+If the value is a list of strings (including the empty list),
+then use those arguments. With a prefix argument use the same
+arguments as the buffer.
+
+Of course the arguments that are required to actually show the
+same differences as those shown in the buffer are always used.
+
+\(fn FILE &optional ARG)" t nil)
+
+(autoload 'magit-request-pull "magit-patch" "\
+Request upstream to pull from your public repository.
+
+URL is the url of your publicly accessible repository.
+START is a commit that already is in the upstream repository.
+END is the last commit, usually a branch name, which upstream
+is asked to pull. START has to be reachable from that commit.
+
+\(fn URL START END)" t nil)
+
+(register-definition-prefixes "magit-patch" '("magit-"))
+
+;;;***
+
+;;;### (autoloads nil "magit-process" "magit-process.el" (0 0 0 0))
+;;; Generated autoloads from magit-process.el
+
+(register-definition-prefixes "magit-process" '("magit-" "tramp-sh-handle-"))
+
+;;;***
+
+;;;### (autoloads nil "magit-pull" "magit-pull.el" (0 0 0 0))
+;;; Generated autoloads from magit-pull.el
+ (autoload 'magit-pull "magit-pull" nil t)
+ (autoload 'magit-pull-from-pushremote "magit-pull" nil t)
+ (autoload 'magit-pull-from-upstream "magit-pull" nil t)
+
+(autoload 'magit-pull-branch "magit-pull" "\
+Pull from a branch read in the minibuffer.
+
+\(fn SOURCE ARGS)" t nil)
+
+(register-definition-prefixes "magit-pull" '("magit-pull-"))
+
+;;;***
+
+;;;### (autoloads nil "magit-push" "magit-push.el" (0 0 0 0))
+;;; Generated autoloads from magit-push.el
+ (autoload 'magit-push "magit-push" nil t)
+ (autoload 'magit-push-current-to-pushremote "magit-push" nil t)
+ (autoload 'magit-push-current-to-upstream "magit-push" nil t)
+
+(autoload 'magit-push-current "magit-push" "\
+Push the current branch to a branch read in the minibuffer.
+
+\(fn TARGET ARGS)" t nil)
+
+(autoload 'magit-push-other "magit-push" "\
+Push an arbitrary branch or commit somewhere.
+Both the source and the target are read in the minibuffer.
+
+\(fn SOURCE TARGET ARGS)" t nil)
+
+(autoload 'magit-push-refspecs "magit-push" "\
+Push one or multiple REFSPECS to a REMOTE.
+Both the REMOTE and the REFSPECS are read in the minibuffer. To
+use multiple REFSPECS, separate them with commas. Completion is
+only available for the part before the colon, or when no colon
+is used.
+
+\(fn REMOTE REFSPECS ARGS)" t nil)
+
+(autoload 'magit-push-matching "magit-push" "\
+Push all matching branches to another repository.
+If multiple remotes exist, then read one from the user.
+If just one exists, use that without requiring confirmation.
+
+\(fn REMOTE &optional ARGS)" t nil)
+
+(autoload 'magit-push-tags "magit-push" "\
+Push all tags to another repository.
+If only one remote exists, then push to that. Otherwise prompt
+for a remote, offering the remote configured for the current
+branch as default.
+
+\(fn REMOTE &optional ARGS)" t nil)
+
+(autoload 'magit-push-tag "magit-push" "\
+Push a tag to another repository.
+
+\(fn TAG REMOTE &optional ARGS)" t nil)
+
+(autoload 'magit-push-notes-ref "magit-push" "\
+Push a notes ref to another repository.
+
+\(fn REF REMOTE &optional ARGS)" t nil)
+ (autoload 'magit-push-implicitly "magit-push" nil t)
+
+(autoload 'magit-push-to-remote "magit-push" "\
+Push to REMOTE without using an explicit refspec.
+The REMOTE is read in the minibuffer.
+
+This command simply runs \"git push -v [ARGS] REMOTE\". ARGS
+are the arguments specified in the popup buffer. No refspec
+arguments are used. Instead the behavior depends on at least
+these Git variables: `push.default', `remote.pushDefault',
+`branch.<branch>.pushRemote', `branch.<branch>.remote',
+`branch.<branch>.merge', and `remote.<remote>.push'.
+
+\(fn REMOTE ARGS)" t nil)
+
+(register-definition-prefixes "magit-push" '("magit-"))
+
+;;;***
+
+;;;### (autoloads nil "magit-reflog" "magit-reflog.el" (0 0 0 0))
+;;; Generated autoloads from magit-reflog.el
+
+(autoload 'magit-reflog-current "magit-reflog" "\
+Display the reflog of the current branch.
+If `HEAD' is detached, then show the reflog for that instead." t nil)
+
+(autoload 'magit-reflog-other "magit-reflog" "\
+Display the reflog of a branch or another ref.
+
+\(fn REF)" t nil)
+
+(autoload 'magit-reflog-head "magit-reflog" "\
+Display the `HEAD' reflog." t nil)
+
+(register-definition-prefixes "magit-reflog" '("magit-reflog-"))
+
+;;;***
+
+;;;### (autoloads nil "magit-refs" "magit-refs.el" (0 0 0 0))
+;;; Generated autoloads from magit-refs.el
+ (autoload 'magit-show-refs "magit-refs" nil t)
+
+(autoload 'magit-show-refs-head "magit-refs" "\
+List and compare references in a dedicated buffer.
+Compared with `HEAD'.
+
+\(fn &optional ARGS)" t nil)
+
+(autoload 'magit-show-refs-current "magit-refs" "\
+List and compare references in a dedicated buffer.
+Compare with the current branch or `HEAD' if it is detached.
+
+\(fn &optional ARGS)" t nil)
+
+(autoload 'magit-show-refs-other "magit-refs" "\
+List and compare references in a dedicated buffer.
+Compared with a branch read from the user.
+
+\(fn &optional REF ARGS)" t nil)
+
+(register-definition-prefixes "magit-refs" '("magit-"))
+
+;;;***
+
+;;;### (autoloads nil "magit-remote" "magit-remote.el" (0 0 0 0))
+;;; Generated autoloads from magit-remote.el
+ (autoload 'magit-remote "magit-remote" nil t)
+
+(autoload 'magit-remote-add "magit-remote" "\
+Add a remote named REMOTE and fetch it.
+
+\(fn REMOTE URL &optional ARGS)" t nil)
+
+(autoload 'magit-remote-rename "magit-remote" "\
+Rename the remote named OLD to NEW.
+
+\(fn OLD NEW)" t nil)
+
+(autoload 'magit-remote-remove "magit-remote" "\
+Delete the remote named REMOTE.
+
+\(fn REMOTE)" t nil)
+
+(autoload 'magit-remote-prune "magit-remote" "\
+Remove stale remote-tracking branches for REMOTE.
+
+\(fn REMOTE)" t nil)
+
+(autoload 'magit-remote-prune-refspecs "magit-remote" "\
+Remove stale refspecs for REMOTE.
+
+A refspec is stale if there no longer exists at least one branch
+on the remote that would be fetched due to that refspec. A stale
+refspec is problematic because its existence causes Git to refuse
+to fetch according to the remaining non-stale refspecs.
+
+If only stale refspecs remain, then offer to either delete the
+remote or to replace the stale refspecs with the default refspec.
+
+Also remove the remote-tracking branches that were created due to
+the now stale refspecs. Other stale branches are not removed.
+
+\(fn REMOTE)" t nil)
+
+(autoload 'magit-remote-set-head "magit-remote" "\
+Set the local representation of REMOTE's default branch.
+Query REMOTE and set the symbolic-ref refs/remotes/<remote>/HEAD
+accordingly. With a prefix argument query for the branch to be
+used, which allows you to select an incorrect value if you fancy
+doing that.
+
+\(fn REMOTE &optional BRANCH)" t nil)
+
+(autoload 'magit-remote-unset-head "magit-remote" "\
+Unset the local representation of REMOTE's default branch.
+Delete the symbolic-ref \"refs/remotes/<remote>/HEAD\".
+
+\(fn REMOTE)" t nil)
+
+(autoload 'magit-remote-unshallow "magit-remote" "\
+Convert a shallow remote into a full one.
+If only a single refspec is set and it does not contain a
+wildcard, then also offer to replace it with the standard
+refspec.
+
+\(fn REMOTE)" t nil)
+ (autoload 'magit-remote-configure "magit-remote" nil t)
+
+(register-definition-prefixes "magit-remote" '("magit-"))
+
+;;;***
+
+;;;### (autoloads nil "magit-repos" "magit-repos.el" (0 0 0 0))
+;;; Generated autoloads from magit-repos.el
+
+(autoload 'magit-list-repositories "magit-repos" "\
+Display a list of repositories.
+
+Use the options `magit-repository-directories' to control which
+repositories are displayed." t nil)
+
+(register-definition-prefixes "magit-repos" '("magit-"))
+
+;;;***
+
+;;;### (autoloads nil "magit-reset" "magit-reset.el" (0 0 0 0))
+;;; Generated autoloads from magit-reset.el
+ (autoload 'magit-reset "magit" nil t)
+
+(autoload 'magit-reset-mixed "magit-reset" "\
+Reset the `HEAD' and index to COMMIT, but not the working tree.
+
+\(git reset --mixed COMMIT)
+
+\(fn COMMIT)" t nil)
+
+(autoload 'magit-reset-soft "magit-reset" "\
+Reset the `HEAD' to COMMIT, but not the index and working tree.
+
+\(git reset --soft REVISION)
+
+\(fn COMMIT)" t nil)
+
+(autoload 'magit-reset-hard "magit-reset" "\
+Reset the `HEAD', index, and working tree to COMMIT.
+
+\(git reset --hard REVISION)
+
+\(fn COMMIT)" t nil)
+
+(autoload 'magit-reset-keep "magit-reset" "\
+Reset the `HEAD' and index to COMMIT, while keeping uncommitted changes.
+
+\(git reset --keep REVISION)
+
+\(fn COMMIT)" t nil)
+
+(autoload 'magit-reset-index "magit-reset" "\
+Reset the index to COMMIT.
+Keep the `HEAD' and working tree as-is, so if COMMIT refers to the
+head this effectively unstages all changes.
+
+\(git reset COMMIT .)
+
+\(fn COMMIT)" t nil)
+
+(autoload 'magit-reset-worktree "magit-reset" "\
+Reset the worktree to COMMIT.
+Keep the `HEAD' and index as-is.
+
+\(fn COMMIT)" t nil)
+
+(autoload 'magit-reset-quickly "magit-reset" "\
+Reset the `HEAD' and index to COMMIT, and possibly the working tree.
+With a prefix argument reset the working tree otherwise don't.
+
+\(git reset --mixed|--hard COMMIT)
+
+\(fn COMMIT &optional HARD)" t nil)
+
+(register-definition-prefixes "magit-reset" '("magit-reset-"))
+
+;;;***
+
+;;;### (autoloads nil "magit-sequence" "magit-sequence.el" (0 0 0
+;;;;;; 0))
+;;; Generated autoloads from magit-sequence.el
+
+(autoload 'magit-sequencer-continue "magit-sequence" "\
+Resume the current cherry-pick or revert sequence." t nil)
+
+(autoload 'magit-sequencer-skip "magit-sequence" "\
+Skip the stopped at commit during a cherry-pick or revert sequence." t nil)
+
+(autoload 'magit-sequencer-abort "magit-sequence" "\
+Abort the current cherry-pick or revert sequence.
+This discards all changes made since the sequence started." t nil)
+ (autoload 'magit-cherry-pick "magit-sequence" nil t)
+
+(autoload 'magit-cherry-copy "magit-sequence" "\
+Copy COMMITS from another branch onto the current branch.
+Prompt for a commit, defaulting to the commit at point. If
+the region selects multiple commits, then pick all of them,
+without prompting.
+
+\(fn COMMITS &optional ARGS)" t nil)
+
+(autoload 'magit-cherry-apply "magit-sequence" "\
+Apply the changes in COMMITS but do not commit them.
+Prompt for a commit, defaulting to the commit at point. If
+the region selects multiple commits, then apply all of them,
+without prompting.
+
+\(fn COMMITS &optional ARGS)" t nil)
+
+(autoload 'magit-cherry-harvest "magit-sequence" "\
+Move COMMITS from another BRANCH onto the current branch.
+Remove the COMMITS from BRANCH and stay on the current branch.
+If a conflict occurs, then you have to fix that and finish the
+process manually.
+
+\(fn COMMITS BRANCH &optional ARGS)" t nil)
+
+(autoload 'magit-cherry-donate "magit-sequence" "\
+Move COMMITS from the current branch onto another existing BRANCH.
+Remove COMMITS from the current branch and stay on that branch.
+If a conflict occurs, then you have to fix that and finish the
+process manually. `HEAD' is allowed to be detached initially.
+
+\(fn COMMITS BRANCH &optional ARGS)" t nil)
+
+(autoload 'magit-cherry-spinout "magit-sequence" "\
+Move COMMITS from the current branch onto a new BRANCH.
+Remove COMMITS from the current branch and stay on that branch.
+If a conflict occurs, then you have to fix that and finish the
+process manually.
+
+\(fn COMMITS BRANCH START-POINT &optional ARGS)" t nil)
+
+(autoload 'magit-cherry-spinoff "magit-sequence" "\
+Move COMMITS from the current branch onto a new BRANCH.
+Remove COMMITS from the current branch and checkout BRANCH.
+If a conflict occurs, then you have to fix that and finish
+the process manually.
+
+\(fn COMMITS BRANCH START-POINT &optional ARGS)" t nil)
+ (autoload 'magit-revert "magit-sequence" nil t)
+
+(autoload 'magit-revert-and-commit "magit-sequence" "\
+Revert COMMIT by creating a new commit.
+Prompt for a commit, defaulting to the commit at point. If
+the region selects multiple commits, then revert all of them,
+without prompting.
+
+\(fn COMMIT &optional ARGS)" t nil)
+
+(autoload 'magit-revert-no-commit "magit-sequence" "\
+Revert COMMIT by applying it in reverse to the worktree.
+Prompt for a commit, defaulting to the commit at point. If
+the region selects multiple commits, then revert all of them,
+without prompting.
+
+\(fn COMMIT &optional ARGS)" t nil)
+ (autoload 'magit-am "magit-sequence" nil t)
+
+(autoload 'magit-am-apply-patches "magit-sequence" "\
+Apply the patches FILES.
+
+\(fn &optional FILES ARGS)" t nil)
+
+(autoload 'magit-am-apply-maildir "magit-sequence" "\
+Apply the patches from MAILDIR.
+
+\(fn &optional MAILDIR ARGS)" t nil)
+
+(autoload 'magit-am-continue "magit-sequence" "\
+Resume the current patch applying sequence." t nil)
+
+(autoload 'magit-am-skip "magit-sequence" "\
+Skip the stopped at patch during a patch applying sequence." t nil)
+
+(autoload 'magit-am-abort "magit-sequence" "\
+Abort the current patch applying sequence.
+This discards all changes made since the sequence started." t nil)
+ (autoload 'magit-rebase "magit-sequence" nil t)
+ (autoload 'magit-rebase-onto-pushremote "magit-sequence" nil t)
+ (autoload 'magit-rebase-onto-upstream "magit-sequence" nil t)
+
+(autoload 'magit-rebase-branch "magit-sequence" "\
+Rebase the current branch onto a branch read in the minibuffer.
+All commits that are reachable from `HEAD' but not from the
+selected branch TARGET are being rebased.
+
+\(fn TARGET ARGS)" t nil)
+
+(autoload 'magit-rebase-subset "magit-sequence" "\
+Rebase a subset of the current branch's history onto a new base.
+Rebase commits from START to `HEAD' onto NEWBASE.
+START has to be selected from a list of recent commits.
+
+\(fn NEWBASE START ARGS)" t nil)
+
+(autoload 'magit-rebase-interactive "magit-sequence" "\
+Start an interactive rebase sequence.
+
+\(fn COMMIT ARGS)" t nil)
+
+(autoload 'magit-rebase-autosquash "magit-sequence" "\
+Combine squash and fixup commits with their intended targets.
+
+\(fn ARGS)" t nil)
+
+(autoload 'magit-rebase-edit-commit "magit-sequence" "\
+Edit a single older commit using rebase.
+
+\(fn COMMIT ARGS)" t nil)
+
+(autoload 'magit-rebase-reword-commit "magit-sequence" "\
+Reword a single older commit using rebase.
+
+\(fn COMMIT ARGS)" t nil)
+
+(autoload 'magit-rebase-remove-commit "magit-sequence" "\
+Remove a single older commit using rebase.
+
+\(fn COMMIT ARGS)" t nil)
+
+(autoload 'magit-rebase-continue "magit-sequence" "\
+Restart the current rebasing operation.
+In some cases this pops up a commit message buffer for you do
+edit. With a prefix argument the old message is reused as-is.
+
+\(fn &optional NOEDIT)" t nil)
+
+(autoload 'magit-rebase-skip "magit-sequence" "\
+Skip the current commit and restart the current rebase operation." t nil)
+
+(autoload 'magit-rebase-edit "magit-sequence" "\
+Edit the todo list of the current rebase operation." t nil)
+
+(autoload 'magit-rebase-abort "magit-sequence" "\
+Abort the current rebase operation, restoring the original branch." t nil)
+
+(register-definition-prefixes "magit-sequence" '("magit-"))
+
+;;;***
+
+;;;### (autoloads nil "magit-sparse-checkout" "magit-sparse-checkout.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from magit-sparse-checkout.el
+ (autoload 'magit-sparse-checkout "magit-sparse-checkout" nil t)
+
+(autoload 'magit-sparse-checkout-enable "magit-sparse-checkout" "\
+Convert the working tree to a sparse checkout.
+
+\(fn &optional ARGS)" t nil)
+
+(autoload 'magit-sparse-checkout-set "magit-sparse-checkout" "\
+Restrict working tree to DIRECTORIES.
+To extend rather than override the currently configured
+directories, call `magit-sparse-checkout-add' instead.
+
+\(fn DIRECTORIES)" t nil)
+
+(autoload 'magit-sparse-checkout-add "magit-sparse-checkout" "\
+Add DIRECTORIES to the working tree.
+To override rather than extend the currently configured
+directories, call `magit-sparse-checkout-set' instead.
+
+\(fn DIRECTORIES)" t nil)
+
+(autoload 'magit-sparse-checkout-reapply "magit-sparse-checkout" "\
+Reapply the sparse checkout rules to the working tree.
+Some operations such as merging or rebasing may need to check out
+files that aren't included in the sparse checkout. Call this
+command to reset to the sparse checkout state." t nil)
+
+(autoload 'magit-sparse-checkout-disable "magit-sparse-checkout" "\
+Convert sparse checkout to full checkout.
+Note that disabling the sparse checkout does not clear the
+configured directories. Call `magit-sparse-checkout-enable' to
+restore the previous sparse checkout." t nil)
+
+(register-definition-prefixes "magit-sparse-checkout" '("magit-sparse-checkout-"))
+
+;;;***
+
+;;;### (autoloads nil "magit-stash" "magit-stash.el" (0 0 0 0))
+;;; Generated autoloads from magit-stash.el
+ (autoload 'magit-stash "magit-stash" nil t)
+
+(autoload 'magit-stash-both "magit-stash" "\
+Create a stash of the index and working tree.
+Untracked files are included according to infix arguments.
+One prefix argument is equivalent to `--include-untracked'
+while two prefix arguments are equivalent to `--all'.
+
+\(fn MESSAGE &optional INCLUDE-UNTRACKED)" t nil)
+
+(autoload 'magit-stash-index "magit-stash" "\
+Create a stash of the index only.
+Unstaged and untracked changes are not stashed. The stashed
+changes are applied in reverse to both the index and the
+worktree. This command can fail when the worktree is not clean.
+Applying the resulting stash has the inverse effect.
+
+\(fn MESSAGE)" t nil)
+
+(autoload 'magit-stash-worktree "magit-stash" "\
+Create a stash of unstaged changes in the working tree.
+Untracked files are included according to infix arguments.
+One prefix argument is equivalent to `--include-untracked'
+while two prefix arguments are equivalent to `--all'.
+
+\(fn MESSAGE &optional INCLUDE-UNTRACKED)" t nil)
+
+(autoload 'magit-stash-keep-index "magit-stash" "\
+Create a stash of the index and working tree, keeping index intact.
+Untracked files are included according to infix arguments.
+One prefix argument is equivalent to `--include-untracked'
+while two prefix arguments are equivalent to `--all'.
+
+\(fn MESSAGE &optional INCLUDE-UNTRACKED)" t nil)
+
+(autoload 'magit-snapshot-both "magit-stash" "\
+Create a snapshot of the index and working tree.
+Untracked files are included according to infix arguments.
+One prefix argument is equivalent to `--include-untracked'
+while two prefix arguments are equivalent to `--all'.
+
+\(fn &optional INCLUDE-UNTRACKED)" t nil)
+
+(autoload 'magit-snapshot-index "magit-stash" "\
+Create a snapshot of the index only.
+Unstaged and untracked changes are not stashed." t nil)
+
+(autoload 'magit-snapshot-worktree "magit-stash" "\
+Create a snapshot of unstaged changes in the working tree.
+Untracked files are included according to infix arguments.
+One prefix argument is equivalent to `--include-untracked'
+while two prefix arguments are equivalent to `--all'.
+
+\(fn &optional INCLUDE-UNTRACKED)" t nil)
+ (autoload 'magit-stash-push "magit-stash" nil t)
+
+(autoload 'magit-stash-apply "magit-stash" "\
+Apply a stash to the working tree.
+Try to preserve the stash index. If that fails because there
+are staged changes, apply without preserving the stash index.
+
+\(fn STASH)" t nil)
+
+(autoload 'magit-stash-pop "magit-stash" "\
+Apply a stash to the working tree and remove it from stash list.
+Try to preserve the stash index. If that fails because there
+are staged changes, apply without preserving the stash index
+and forgo removing the stash.
+
+\(fn STASH)" t nil)
+
+(autoload 'magit-stash-drop "magit-stash" "\
+Remove a stash from the stash list.
+When the region is active offer to drop all contained stashes.
+
+\(fn STASH)" t nil)
+
+(autoload 'magit-stash-clear "magit-stash" "\
+Remove all stashes saved in REF's reflog by deleting REF.
+
+\(fn REF)" t nil)
+
+(autoload 'magit-stash-branch "magit-stash" "\
+Create and checkout a new BRANCH from STASH.
+
+\(fn STASH BRANCH)" t nil)
+
+(autoload 'magit-stash-branch-here "magit-stash" "\
+Create and checkout a new BRANCH and apply STASH.
+The branch is created using `magit-branch-and-checkout', using the
+current branch or `HEAD' as the start-point.
+
+\(fn STASH BRANCH)" t nil)
+
+(autoload 'magit-stash-format-patch "magit-stash" "\
+Create a patch from STASH
+
+\(fn STASH)" t nil)
+
+(autoload 'magit-stash-list "magit-stash" "\
+List all stashes in a buffer." t nil)
+
+(autoload 'magit-stash-show "magit-stash" "\
+Show all diffs of a stash in a buffer.
+
+\(fn STASH &optional ARGS FILES)" t nil)
+
+(register-definition-prefixes "magit-stash" '("magit-"))
+
+;;;***
+
+;;;### (autoloads nil "magit-status" "magit-status.el" (0 0 0 0))
+;;; Generated autoloads from magit-status.el
+
+(autoload 'magit-init "magit-status" "\
+Initialize a Git repository, then show its status.
+
+If the directory is below an existing repository, then the user
+has to confirm that a new one should be created inside. If the
+directory is the root of the existing repository, then the user
+has to confirm that it should be reinitialized.
+
+Non-interactively DIRECTORY is (re-)initialized unconditionally.
+
+\(fn DIRECTORY)" t nil)
+
+(autoload 'magit-status "magit-status" "\
+Show the status of the current Git repository in a buffer.
+
+If the current directory isn't located within a Git repository,
+then prompt for an existing repository or an arbitrary directory,
+depending on option `magit-repository-directories', and show the
+status of the selected repository instead.
+
+* If that option specifies any existing repositories, then offer
+ those for completion and show the status buffer for the
+ selected one.
+
+* Otherwise read an arbitrary directory using regular file-name
+ completion. If the selected directory is the top-level of an
+ existing working tree, then show the status buffer for that.
+
+* Otherwise offer to initialize the selected directory as a new
+ repository. After creating the repository show its status
+ buffer.
+
+These fallback behaviors can also be forced using one or more
+prefix arguments:
+
+* With two prefix arguments (or more precisely a numeric prefix
+ value of 16 or greater) read an arbitrary directory and act on
+ it as described above. The same could be accomplished using
+ the command `magit-init'.
+
+* With a single prefix argument read an existing repository, or
+ if none can be found based on `magit-repository-directories',
+ then fall back to the same behavior as with two prefix
+ arguments.
+
+\(fn &optional DIRECTORY CACHE)" t nil)
+
+(defalias 'magit #'magit-status "\
+An alias for `magit-status' for better discoverability.
+
+Instead of invoking this alias for `magit-status' using
+\"M-x magit RET\", you should bind a key to `magit-status'
+and read the info node `(magit)Getting Started', which
+also contains other useful hints.")
+
+(autoload 'magit-status-here "magit-status" "\
+Like `magit-status' but with non-nil `magit-status-goto-file-position'." t nil)
+
+(autoload 'magit-status-quick "magit-status" "\
+Show the status of the current Git repository, maybe without refreshing.
+
+If the status buffer of the current Git repository exists but
+isn't being displayed in the selected frame, then display it
+without refreshing it.
+
+If the status buffer is being displayed in the selected frame,
+then also refresh it.
+
+Prefix arguments have the same meaning as for `magit-status',
+and additionally cause the buffer to be refresh.
+
+To use this function instead of `magit-status', add this to your
+init file: (global-set-key (kbd \"C-x g\") 'magit-status-quick)." t nil)
+
+(autoload 'magit-status-setup-buffer "magit-status" "\
+
+
+\(fn &optional DIRECTORY)" nil nil)
+
+(register-definition-prefixes "magit-status" '("magit-"))
+
+;;;***
+
+;;;### (autoloads nil "magit-submodule" "magit-submodule.el" (0 0
+;;;;;; 0 0))
+;;; Generated autoloads from magit-submodule.el
+ (autoload 'magit-submodule "magit-submodule" nil t)
+ (autoload 'magit-submodule-add "magit-submodule" nil t)
+
+(autoload 'magit-submodule-read-name-for-path "magit-submodule" "\
+
+
+\(fn PATH &optional PREFER-SHORT)" nil nil)
+ (autoload 'magit-submodule-register "magit-submodule" nil t)
+ (autoload 'magit-submodule-populate "magit-submodule" nil t)
+ (autoload 'magit-submodule-update "magit-submodule" nil t)
+ (autoload 'magit-submodule-synchronize "magit-submodule" nil t)
+ (autoload 'magit-submodule-unpopulate "magit-submodule" nil t)
+
+(autoload 'magit-submodule-remove "magit-submodule" "\
+Unregister MODULES and remove their working directories.
+
+For safety reasons, do not remove the gitdirs and if a module has
+uncommitted changes, then do not remove it at all. If a module's
+gitdir is located inside the working directory, then move it into
+the gitdir of the superproject first.
+
+With the \"--force\" argument offer to remove dirty working
+directories and with a prefix argument offer to delete gitdirs.
+Both actions are very dangerous and have to be confirmed. There
+are additional safety precautions in place, so you might be able
+to recover from making a mistake here, but don't count on it.
+
+\(fn MODULES ARGS TRASH-GITDIRS)" t nil)
+
+(autoload 'magit-insert-modules "magit-submodule" "\
+Insert submodule sections.
+Hook `magit-module-sections-hook' controls which module sections
+are inserted, and option `magit-module-sections-nested' controls
+whether they are wrapped in an additional section." nil nil)
+
+(autoload 'magit-insert-modules-overview "magit-submodule" "\
+Insert sections for all modules.
+For each section insert the path and the output of `git describe --tags',
+or, failing that, the abbreviated HEAD commit hash." nil nil)
+
+(autoload 'magit-insert-modules-unpulled-from-upstream "magit-submodule" "\
+Insert sections for modules that haven't been pulled from the upstream.
+These sections can be expanded to show the respective commits." nil nil)
+
+(autoload 'magit-insert-modules-unpulled-from-pushremote "magit-submodule" "\
+Insert sections for modules that haven't been pulled from the push-remote.
+These sections can be expanded to show the respective commits." nil nil)
+
+(autoload 'magit-insert-modules-unpushed-to-upstream "magit-submodule" "\
+Insert sections for modules that haven't been pushed to the upstream.
+These sections can be expanded to show the respective commits." nil nil)
+
+(autoload 'magit-insert-modules-unpushed-to-pushremote "magit-submodule" "\
+Insert sections for modules that haven't been pushed to the push-remote.
+These sections can be expanded to show the respective commits." nil nil)
+
+(autoload 'magit-list-submodules "magit-submodule" "\
+Display a list of the current repository's submodules." t nil)
+
+(register-definition-prefixes "magit-submodule" '("magit-"))
+
+;;;***
+
+;;;### (autoloads nil "magit-subtree" "magit-subtree.el" (0 0 0 0))
+;;; Generated autoloads from magit-subtree.el
+ (autoload 'magit-subtree "magit-subtree" nil t)
+ (autoload 'magit-subtree-import "magit-subtree" nil t)
+ (autoload 'magit-subtree-export "magit-subtree" nil t)
+
+(autoload 'magit-subtree-add "magit-subtree" "\
+Add REF from REPOSITORY as a new subtree at PREFIX.
+
+\(fn PREFIX REPOSITORY REF ARGS)" t nil)
+
+(autoload 'magit-subtree-add-commit "magit-subtree" "\
+Add COMMIT as a new subtree at PREFIX.
+
+\(fn PREFIX COMMIT ARGS)" t nil)
+
+(autoload 'magit-subtree-merge "magit-subtree" "\
+Merge COMMIT into the PREFIX subtree.
+
+\(fn PREFIX COMMIT ARGS)" t nil)
+
+(autoload 'magit-subtree-pull "magit-subtree" "\
+Pull REF from REPOSITORY into the PREFIX subtree.
+
+\(fn PREFIX REPOSITORY REF ARGS)" t nil)
+
+(autoload 'magit-subtree-push "magit-subtree" "\
+Extract the history of the subtree PREFIX and push it to REF on REPOSITORY.
+
+\(fn PREFIX REPOSITORY REF ARGS)" t nil)
+
+(autoload 'magit-subtree-split "magit-subtree" "\
+Extract the history of the subtree PREFIX.
+
+\(fn PREFIX COMMIT ARGS)" t nil)
+
+(register-definition-prefixes "magit-subtree" '("magit-"))
+
+;;;***
+
+;;;### (autoloads nil "magit-tag" "magit-tag.el" (0 0 0 0))
+;;; Generated autoloads from magit-tag.el
+ (autoload 'magit-tag "magit" nil t)
+
+(autoload 'magit-tag-create "magit-tag" "\
+Create a new tag with the given NAME at REV.
+With a prefix argument annotate the tag.
+
+\(git tag [--annotate] NAME REV)
+
+\(fn NAME REV &optional ARGS)" t nil)
+
+(autoload 'magit-tag-delete "magit-tag" "\
+Delete one or more tags.
+If the region marks multiple tags (and nothing else), then offer
+to delete those, otherwise prompt for a single tag to be deleted,
+defaulting to the tag at point.
+
+\(git tag -d TAGS)
+
+\(fn TAGS)" t nil)
+
+(autoload 'magit-tag-prune "magit-tag" "\
+Offer to delete tags missing locally from REMOTE, and vice versa.
+
+\(fn TAGS REMOTE-TAGS REMOTE)" t nil)
+
+(autoload 'magit-tag-release "magit-tag" "\
+Create a release tag for `HEAD'.
+
+Assume that release tags match `magit-release-tag-regexp'.
+
+If `HEAD's message matches `magit-release-commit-regexp', then
+base the tag on the version string specified by that. Otherwise
+prompt for the name of the new tag using the highest existing
+tag as initial input and leaving it to the user to increment the
+desired part of the version string.
+
+If `--annotate' is enabled, then prompt for the message of the
+new tag. Base the proposed tag message on the message of the
+highest tag, provided that that contains the corresponding
+version string and substituting the new version string for that.
+Otherwise propose something like \"Foo-Bar 1.2.3\", given, for
+example, a TAG \"v1.2.3\" and a repository located at something
+like \"/path/to/foo-bar\".
+
+\(fn TAG MSG &optional ARGS)" t nil)
+
+(register-definition-prefixes "magit-tag" '("magit-"))
+
+;;;***
+
+;;;### (autoloads nil "magit-transient" "magit-transient.el" (0 0
+;;;;;; 0 0))
+;;; Generated autoloads from magit-transient.el
+
+(register-definition-prefixes "magit-transient" '("magit-"))
+
+;;;***
+
+;;;### (autoloads nil "magit-wip" "magit-wip.el" (0 0 0 0))
+;;; Generated autoloads from magit-wip.el
+
+(defvar magit-wip-mode nil "\
+Non-nil if Magit-Wip mode is enabled.
+See the `magit-wip-mode' command
+for a description of this minor mode.
+Setting this variable directly does not take effect;
+either customize it (see the info node `Easy Customization')
+or call the function `magit-wip-mode'.")
+
+(custom-autoload 'magit-wip-mode "magit-wip" nil)
+
+(autoload 'magit-wip-mode "magit-wip" "\
+Save uncommitted changes to work-in-progress refs.
+
+This is a minor mode. If called interactively, toggle the
+`Magit-Wip mode' mode. If the prefix argument is positive,
+enable the mode, and if it is zero or negative, disable the mode.
+
+If called from Lisp, toggle the mode if ARG is `toggle'. Enable
+the mode if ARG is nil, omitted, or is a positive number.
+Disable the mode if ARG is a negative number.
+
+To check whether the minor mode is enabled in the current buffer,
+evaluate `(default-value \\='magit-wip-mode)'.
+
+The mode's hook is called both when the mode is enabled and when
+it is disabled.
+
+Whenever appropriate (i.e. when dataloss would be a possibility
+otherwise) this mode causes uncommitted changes to be committed
+to dedicated work-in-progress refs.
+
+For historic reasons this mode is implemented on top of four
+other `magit-wip-*' modes, which can also be used individually,
+if you want finer control over when the wip refs are updated;
+but that is discouraged.
+
+\(fn &optional ARG)" t nil)
+
+(put 'magit-wip-after-save-mode 'globalized-minor-mode t)
+
+(defvar magit-wip-after-save-mode nil "\
+Non-nil if Magit-Wip-After-Save mode is enabled.
+See the `magit-wip-after-save-mode' command
+for a description of this minor mode.
+Setting this variable directly does not take effect;
+either customize it (see the info node `Easy Customization')
+or call the function `magit-wip-after-save-mode'.")
+
+(custom-autoload 'magit-wip-after-save-mode "magit-wip" nil)
+
+(autoload 'magit-wip-after-save-mode "magit-wip" "\
+Toggle Magit-Wip-After-Save-Local mode in all buffers.
+With prefix ARG, enable Magit-Wip-After-Save mode if ARG is positive;
+otherwise, disable it.
+
+If called from Lisp, toggle the mode if ARG is `toggle'.
+Enable the mode if ARG is nil, omitted, or is a positive number.
+Disable the mode if ARG is a negative number.
+
+Magit-Wip-After-Save-Local mode is enabled in all buffers where
+`magit-wip-after-save-local-mode-turn-on' would do it.
+
+See `magit-wip-after-save-local-mode' for more information on
+Magit-Wip-After-Save-Local mode.
+
+\(fn &optional ARG)" t nil)
+
+(defvar magit-wip-after-apply-mode nil "\
+Non-nil if Magit-Wip-After-Apply mode is enabled.
+See the `magit-wip-after-apply-mode' command
+for a description of this minor mode.")
+
+(custom-autoload 'magit-wip-after-apply-mode "magit-wip" nil)
+
+(autoload 'magit-wip-after-apply-mode "magit-wip" "\
+Commit to work-in-progress refs.
+
+This is a minor mode. If called interactively, toggle the
+`Magit-Wip-After-Apply mode' mode. If the prefix argument is
+positive, enable the mode, and if it is zero or negative, disable
+the mode.
+
+If called from Lisp, toggle the mode if ARG is `toggle'. Enable
+the mode if ARG is nil, omitted, or is a positive number.
+Disable the mode if ARG is a negative number.
+
+To check whether the minor mode is enabled in the current buffer,
+evaluate `(default-value \\='magit-wip-after-apply-mode)'.
+
+The mode's hook is called both when the mode is enabled and when
+it is disabled.
+
+After applying a change using any \"apply variant\"
+command (apply, stage, unstage, discard, and reverse) commit the
+affected files to the current wip refs. For each branch there
+may be two wip refs; one contains snapshots of the files as found
+in the worktree and the other contains snapshots of the entries
+in the index.
+
+\(fn &optional ARG)" t nil)
+
+(defvar magit-wip-before-change-mode nil "\
+Non-nil if Magit-Wip-Before-Change mode is enabled.
+See the `magit-wip-before-change-mode' command
+for a description of this minor mode.")
+
+(custom-autoload 'magit-wip-before-change-mode "magit-wip" nil)
+
+(autoload 'magit-wip-before-change-mode "magit-wip" "\
+Commit to work-in-progress refs before certain destructive changes.
+
+This is a minor mode. If called interactively, toggle the
+`Magit-Wip-Before-Change mode' mode. If the prefix argument is
+positive, enable the mode, and if it is zero or negative, disable
+the mode.
+
+If called from Lisp, toggle the mode if ARG is `toggle'. Enable
+the mode if ARG is nil, omitted, or is a positive number.
+Disable the mode if ARG is a negative number.
+
+To check whether the minor mode is enabled in the current buffer,
+evaluate `(default-value \\='magit-wip-before-change-mode)'.
+
+The mode's hook is called both when the mode is enabled and when
+it is disabled.
+
+Before invoking a revert command or an \"apply variant\"
+command (apply, stage, unstage, discard, and reverse) commit the
+affected tracked files to the current wip refs. For each branch
+there may be two wip refs; one contains snapshots of the files
+as found in the worktree and the other contains snapshots of the
+entries in the index.
+
+Only changes to files which could potentially be affected by the
+command which is about to be called are committed.
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'magit-wip-commit-initial-backup "magit-wip" "\
+Before saving, commit current file to a worktree wip ref.
+
+The user has to add this function to `before-save-hook'.
+
+Commit the current state of the visited file before saving the
+current buffer to that file. This backs up the same version of
+the file as `backup-buffer' would, but stores the backup in the
+worktree wip ref, which is also used by the various Magit Wip
+modes, instead of in a backup file as `backup-buffer' would.
+
+This function ignores the variables that affect `backup-buffer'
+and can be used along-side that function, which is recommended
+because this function only backs up files that are tracked in
+a Git repository." nil nil)
+
+(register-definition-prefixes "magit-wip" '("magit-"))
+
+;;;***
+
+;;;### (autoloads nil "magit-worktree" "magit-worktree.el" (0 0 0
+;;;;;; 0))
+;;; Generated autoloads from magit-worktree.el
+ (autoload 'magit-worktree "magit-worktree" nil t)
+
+(autoload 'magit-worktree-checkout "magit-worktree" "\
+Checkout BRANCH in a new worktree at PATH.
+
+\(fn PATH BRANCH)" t nil)
+
+(autoload 'magit-worktree-branch "magit-worktree" "\
+Create a new BRANCH and check it out in a new worktree at PATH.
+
+\(fn PATH BRANCH START-POINT &optional FORCE)" t nil)
+
+(autoload 'magit-worktree-move "magit-worktree" "\
+Move WORKTREE to PATH.
+
+\(fn WORKTREE PATH)" t nil)
+
+(register-definition-prefixes "magit-worktree" '("magit-"))
+
+;;;***
+
+;;;### (autoloads nil nil ("magit-core.el" "magit-pkg.el") (0 0 0
+;;;;;; 0))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; coding: utf-8
+;; End:
+;;; magit-autoloads.el ends here
diff --git a/elpa/magit-20220503.1245/magit-autorevert.el b/elpa/magit-20220503.1245/magit-autorevert.el
new file mode 100644
index 0000000..68fc07b
--- /dev/null
+++ b/elpa/magit-20220503.1245/magit-autorevert.el
@@ -0,0 +1,261 @@
+;;; magit-autorevert.el --- Revert buffers when files in repository change -*- lexical-binding:t -*-
+
+;; Copyright (C) 2008-2022 The Magit Project Contributors
+
+;; Author: Jonas Bernoulli <jonas@bernoul.li>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+
+;; SPDX-License-Identifier: GPL-3.0-or-later
+
+;; Magit 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.
+;;
+;; Magit 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 Magit. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Code:
+
+(require 'magit-git)
+
+(require 'autorevert)
+
+;;; Options
+
+(defgroup magit-auto-revert nil
+ "Revert buffers when files in repository change."
+ :link '(custom-group-link auto-revert)
+ :link '(info-link "(magit)Automatic Reverting of File-Visiting Buffers")
+ :group 'auto-revert
+ :group 'magit-essentials
+ :group 'magit-modes)
+
+(defcustom auto-revert-buffer-list-filter nil
+ "Filter that determines which buffers `auto-revert-buffers' reverts.
+
+This option is provided by Magit, which also advises
+`auto-revert-buffers' to respect it. Magit users who do not turn
+on the local mode `auto-revert-mode' themselves, are best served
+by setting the value to `magit-auto-revert-repository-buffer-p'.
+
+However the default is nil, so as not to disturb users who do use
+the local mode directly. If you experience delays when running
+Magit commands, then you should consider using one of the
+predicates provided by Magit - especially if you also use Tramp.
+
+Users who do turn on `auto-revert-mode' in buffers in which Magit
+doesn't do that for them, should likely not use any filter.
+Users who turn on `global-auto-revert-mode', do not have to worry
+about this option, because it is disregarded if the global mode
+is enabled."
+ :package-version '(magit . "2.4.2")
+ :group 'auto-revert
+ :group 'magit-auto-revert
+ :group 'magit-related
+ :type '(radio (const :tag "No filter" nil)
+ (function-item magit-auto-revert-buffer-p)
+ (function-item magit-auto-revert-repository-buffer-p)
+ function))
+
+(defcustom magit-auto-revert-tracked-only t
+ "Whether `magit-auto-revert-mode' only reverts tracked files."
+ :package-version '(magit . "2.4.0")
+ :group 'magit-auto-revert
+ :type 'boolean
+ :set (lambda (var val)
+ (set var val)
+ (when (and (bound-and-true-p magit-auto-revert-mode)
+ (featurep 'magit-autorevert))
+ (magit-auto-revert-mode -1)
+ (magit-auto-revert-mode))))
+
+(defcustom magit-auto-revert-immediately t
+ "Whether Magit reverts buffers immediately.
+
+If this is non-nil and either `global-auto-revert-mode' or
+`magit-auto-revert-mode' is enabled, then Magit immediately
+reverts buffers by explicitly calling `auto-revert-buffers'
+after running Git for side-effects.
+
+If `auto-revert-use-notify' is non-nil (and file notifications
+are actually supported), then `magit-auto-revert-immediately'
+does not have to be non-nil, because the reverts happen
+immediately anyway.
+
+If `magit-auto-revert-immediately' and `auto-revert-use-notify'
+are both nil, then reverts happen after `auto-revert-interval'
+seconds of user inactivity. That is not desirable."
+ :package-version '(magit . "2.4.0")
+ :group 'magit-auto-revert
+ :type 'boolean)
+
+;;; Mode
+
+(defun magit-turn-on-auto-revert-mode-if-desired (&optional file)
+ (if file
+ (--when-let (find-buffer-visiting file)
+ (with-current-buffer it
+ (magit-turn-on-auto-revert-mode-if-desired)))
+ (when (and (not auto-revert-mode) ; see #3014
+ (not global-auto-revert-mode) ; see #3460
+ buffer-file-name
+ (file-readable-p buffer-file-name)
+ (compat-executable-find (magit-git-executable) t)
+ (magit-toplevel)
+ (or (not magit-auto-revert-tracked-only)
+ (magit-file-tracked-p buffer-file-name)))
+ (auto-revert-mode 1))))
+
+;;;###autoload
+(define-globalized-minor-mode magit-auto-revert-mode auto-revert-mode
+ magit-turn-on-auto-revert-mode-if-desired
+ :package-version '(magit . "2.4.0")
+ :link '(info-link "(magit)Automatic Reverting of File-Visiting Buffers")
+ :group 'magit-auto-revert
+ :group 'magit-essentials
+ ;; - When `global-auto-revert-mode' is enabled, then this mode is
+ ;; redundant.
+ ;; - In all other cases enable the mode because if buffers are not
+ ;; automatically reverted that would make many very common tasks
+ ;; much more cumbersome.
+ :init-value (not (or global-auto-revert-mode
+ noninteractive)))
+;; - Unfortunately `:init-value t' only sets the value of the mode
+;; variable but does not cause the mode function to be called.
+;; - I don't think it works like this on purpose, but since one usually
+;; should not enable global modes by default, it is understandable.
+;; - If the user has set the variable `magit-auto-revert-mode' to nil
+;; after loading magit (instead of doing so before loading magit or
+;; by using the function), then we should still respect that setting.
+;; - If the user sets one of these variables after loading magit and
+;; after `after-init-hook' has run, then that won't have an effect
+;; and there is nothing we can do about it.
+(defun magit-auto-revert-mode--init-kludge ()
+ "This is an internal kludge to be used on `after-init-hook'.
+Do not use this function elsewhere, and don't remove it from
+the `after-init-hook'. For more information see the comments
+and code surrounding the definition of this function."
+ (if magit-auto-revert-mode
+ (let ((start (current-time)))
+ (magit-message "Turning on magit-auto-revert-mode...")
+ (magit-auto-revert-mode 1)
+ (magit-message
+ "Turning on magit-auto-revert-mode...done%s"
+ (let ((elapsed (float-time (time-subtract nil start))))
+ (if (> elapsed 0.2)
+ (format " (%.3fs, %s buffers checked)" elapsed
+ (length (buffer-list)))
+ ""))))
+ (magit-auto-revert-mode -1)))
+(if after-init-time
+ ;; Since `after-init-hook' has already been
+ ;; run, turn the mode on or off right now.
+ (magit-auto-revert-mode--init-kludge)
+ ;; By the time the init file has been fully loaded the
+ ;; values of the relevant variables might have changed.
+ (add-hook 'after-init-hook #'magit-auto-revert-mode--init-kludge t))
+
+(put 'magit-auto-revert-mode 'function-documentation
+ "Toggle Magit Auto Revert mode.
+If called interactively, enable Magit Auto Revert mode if ARG is
+positive, and disable it if ARG is zero or negative. If called
+from Lisp, also enable the mode if ARG is omitted or nil, and
+toggle it if ARG is `toggle'; disable the mode otherwise.
+
+Magit Auto Revert mode is a global minor mode that reverts
+buffers associated with a file that is located inside a Git
+repository when the file changes on disk. Use `auto-revert-mode'
+to revert a particular buffer. Or use `global-auto-revert-mode'
+to revert all file-visiting buffers, not just those that visit
+a file located inside a Git repository.
+
+This global mode works by turning on the buffer-local mode
+`auto-revert-mode' at the time a buffer is first created. The
+local mode is turned on if the visited file is being tracked in
+a Git repository at the time when the buffer is created.
+
+If `magit-auto-revert-tracked-only' is non-nil (the default),
+then only tracked files are reverted. But if you stage a
+previously untracked file using `magit-stage', then this mode
+notices that.
+
+Unlike `global-auto-revert-mode', this mode never reverts any
+buffers that are not visiting files.
+
+The behavior of this mode can be customized using the options
+in the `autorevert' and `magit-autorevert' groups.
+
+This function calls the hook `magit-auto-revert-mode-hook'.
+
+Like nearly every mode, this mode should be enabled or disabled
+by calling the respective mode function, the reason being that
+changing the state of a mode involves more than merely toggling
+a single switch, so setting the mode variable is not enough.
+Also, you should not use `after-init-hook' to disable this mode.")
+
+(defun magit-auto-revert-buffers ()
+ (when (and magit-auto-revert-immediately
+ (or global-auto-revert-mode
+ (and magit-auto-revert-mode auto-revert-buffer-list)))
+ (let ((auto-revert-buffer-list-filter
+ (or auto-revert-buffer-list-filter
+ #'magit-auto-revert-repository-buffer-p)))
+ (auto-revert-buffers))))
+
+(defvar magit-auto-revert-toplevel nil)
+
+(defvar magit-auto-revert-counter 1
+ "Incremented each time `auto-revert-buffers' is called.")
+
+(defun magit-auto-revert-buffer-p (buffer)
+ "Return non-nil if BUFFER visits a file inside the current repository.
+The current repository is the one containing `default-directory'.
+If there is no current repository, then return t for any BUFFER."
+ (magit-auto-revert-repository-buffer-p buffer t))
+
+(defun magit-auto-revert-repository-buffer-p (buffer &optional fallback)
+ "Return non-nil if BUFFER visits a file inside the current repository.
+The current repository is the one containing `default-directory'.
+If there is no current repository, then return FALLBACK (which
+defaults to nil) for any BUFFER."
+ ;; Call `magit-toplevel' just once per cycle.
+ (unless (and magit-auto-revert-toplevel
+ (= (cdr magit-auto-revert-toplevel)
+ magit-auto-revert-counter))
+ (setq magit-auto-revert-toplevel
+ (cons (or (magit-toplevel) 'no-repo)
+ magit-auto-revert-counter)))
+ (let ((top (car magit-auto-revert-toplevel)))
+ (if (eq top 'no-repo)
+ fallback
+ (let ((dir (buffer-local-value 'default-directory buffer)))
+ (and (equal (file-remote-p dir)
+ (file-remote-p top))
+ ;; ^ `tramp-handle-file-in-directory-p' lacks this optimization.
+ (file-in-directory-p dir top))))))
+
+(defun auto-revert-buffers--buffer-list-filter (fn)
+ (cl-incf magit-auto-revert-counter)
+ (if (or global-auto-revert-mode
+ (not auto-revert-buffer-list)
+ (not auto-revert-buffer-list-filter))
+ (funcall fn)
+ (let ((auto-revert-buffer-list
+ (-filter auto-revert-buffer-list-filter
+ auto-revert-buffer-list)))
+ (funcall fn))
+ (unless auto-revert-timer
+ (auto-revert-set-timer))))
+
+(advice-add 'auto-revert-buffers :around
+ #'auto-revert-buffers--buffer-list-filter)
+
+;;; _
+(provide 'magit-autorevert)
+;;; magit-autorevert.el ends here
diff --git a/elpa/magit-20220503.1245/magit-autorevert.elc b/elpa/magit-20220503.1245/magit-autorevert.elc
new file mode 100644
index 0000000..b465632
--- /dev/null
+++ b/elpa/magit-20220503.1245/magit-autorevert.elc
Binary files differ
diff --git a/elpa/magit-20220503.1245/magit-base.el b/elpa/magit-20220503.1245/magit-base.el
new file mode 100644
index 0000000..cb9ad67
--- /dev/null
+++ b/elpa/magit-20220503.1245/magit-base.el
@@ -0,0 +1,1274 @@
+;;; magit-base.el --- Early birds -*- lexical-binding:t; coding:utf-8 -*-
+
+;; Copyright (C) 2008-2022 The Magit Project Contributors
+
+;; Author: Jonas Bernoulli <jonas@bernoul.li>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+
+;; SPDX-License-Identifier: GPL-3.0-or-later
+
+;; Magit 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.
+;;
+;; Magit 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 Magit. If not, see <https://www.gnu.org/licenses/>.
+
+;; This file contains code taken from GNU Emacs, which is
+;; Copyright (C) 1976-2022 Free Software Foundation, Inc.
+
+;;; Commentary:
+
+;; This library defines utility functions, options and other things that
+;; have to be available early on because they are used by several other
+;; libraries, which cannot depend on one another, because that would lead
+;; to circular dependencies.
+
+;;; Code:
+
+(defconst magit--minimal-git "2.2.0")
+(defconst magit--minimal-emacs "25.1")
+
+(require 'cl-lib)
+(require 'compat)
+(require 'compat-26)
+(require 'compat-27)
+(require 'dash)
+(require 'eieio)
+(require 'seq)
+(require 'subr-x)
+
+(require 'crm)
+
+(require 'magit-section)
+
+(eval-when-compile (require 'ido))
+(declare-function Info-get-token "info" (pos start all &optional errorstring))
+
+(eval-when-compile (require 'vc-git))
+(declare-function vc-git--run-command-string "vc-git" (file &rest args))
+
+(eval-when-compile (require 'which-func))
+(declare-function which-function "which-func" ())
+
+(defvar magit-wip-before-change-mode)
+
+;;; Options
+
+(defcustom magit-completing-read-function #'magit-builtin-completing-read
+ "Function to be called when requesting input from the user.
+
+If you have enabled `ivy-mode' or `helm-mode', then you don't
+have to customize this option; `magit-builtin-completing-read'
+will work just fine. However, if you use Ido completion, then
+you do have to use `magit-ido-completing-read', because Ido is
+less well behaved than the former, more modern alternatives.
+
+If you would like to use Ivy or Helm completion with Magit but
+not enable the respective modes globally, then customize this
+option to use `ivy-completing-read' or
+`helm--completing-read-default'. If you choose to use
+`ivy-completing-read', note that the items may always be shown in
+alphabetical order, depending on your version of Ivy."
+ :group 'magit-essentials
+ :type '(radio (function-item magit-builtin-completing-read)
+ (function-item magit-ido-completing-read)
+ (function-item ivy-completing-read)
+ (function-item helm--completing-read-default)
+ (function :tag "Other function")))
+
+(defcustom magit-dwim-selection
+ '((magit-stash-apply nil t)
+ (magit-stash-branch nil t)
+ (magit-stash-branch-here nil t)
+ (magit-stash-format-patch nil t)
+ (magit-stash-drop nil ask)
+ (magit-stash-pop nil ask)
+ (forge-browse-dwim nil t)
+ (forge-browse-commit nil t)
+ (forge-browse-branch nil t)
+ (forge-browse-remote nil t)
+ (forge-browse-issue nil t)
+ (forge-browse-pullreq nil t)
+ (forge-edit-topic-title nil t)
+ (forge-edit-topic-state nil t)
+ (forge-edit-topic-milestone nil t)
+ (forge-edit-topic-labels nil t)
+ (forge-edit-topic-marks nil t)
+ (forge-edit-topic-assignees nil t)
+ (forge-edit-topic-review-requests nil t)
+ (forge-edit-topic-note nil t)
+ (forge-pull-pullreq nil t)
+ (forge-visit-issue nil t)
+ (forge-visit-pullreq nil t)
+ (forge-visit-topic nil t))
+ "When not to offer alternatives and ask for confirmation.
+
+Many commands by default ask the user to select from a list of
+possible candidates. They do so even when there is a thing at
+point that they can act on, which is then offered as the default.
+
+This option can be used to tell certain commands to use the thing
+at point instead of asking the user to select a candidate to act
+on, with or without confirmation.
+
+The value has the form ((COMMAND nil|PROMPT DEFAULT)...).
+
+- COMMAND is the command that should not prompt for a choice.
+ To have an effect, the command has to use the function
+ `magit-completing-read' or a utility function which in turn uses
+ that function.
+
+- If the command uses `magit-completing-read' multiple times, then
+ PROMPT can be used to only affect one of these uses. PROMPT, if
+ non-nil, is a regular expression that is used to match against
+ the PROMPT argument passed to `magit-completing-read'.
+
+- DEFAULT specifies how to use the default. If it is t, then
+ the DEFAULT argument passed to `magit-completing-read' is used
+ without confirmation. If it is `ask', then the user is given
+ a chance to abort. DEFAULT can also be nil, in which case the
+ entry has no effect."
+ :package-version '(magit . "2.12.0")
+ :group 'magit-commands
+ :type '(repeat
+ (list (symbol :tag "Command") ; It might not be fboundp yet.
+ (choice (const :tag "for all prompts" nil)
+ (regexp :tag "for prompts matching regexp"))
+ (choice (const :tag "offer other choices" nil)
+ (const :tag "require confirmation" ask)
+ (const :tag "use default without confirmation" t)))))
+
+(defconst magit--confirm-actions
+ '((const discard)
+ (const reverse)
+ (const stage-all-changes)
+ (const unstage-all-changes)
+ (const delete)
+ (const trash)
+ (const resurrect)
+ (const untrack)
+ (const rename)
+ (const reset-bisect)
+ (const abort-rebase)
+ (const abort-merge)
+ (const merge-dirty)
+ (const delete-unmerged-branch)
+ (const delete-branch-on-remote)
+ (const delete-pr-remote)
+ (const drop-stashes)
+ (const set-and-push)
+ (const amend-published)
+ (const rebase-published)
+ (const edit-published)
+ (const remove-modules)
+ (const remove-dirty-modules)
+ (const trash-module-gitdirs)
+ (const kill-process)
+ (const safe-with-wip)))
+
+(defcustom magit-no-confirm '(set-and-push)
+ "A list of symbols for actions Magit should not confirm, or t.
+
+Many potentially dangerous commands by default ask the user for
+confirmation. Each of the below symbols stands for an action
+which, when invoked unintentionally or without being fully aware
+of the consequences, could lead to tears. In many cases there
+are several commands that perform variations of a certain action,
+so we don't use the command names but more generic symbols.
+
+Applying changes:
+
+ `discard' Discarding one or more changes (i.e. hunks or the
+ complete diff for a file) loses that change, obviously.
+
+ `reverse' Reverting one or more changes can usually be undone
+ by reverting the reversion.
+
+ `stage-all-changes', `unstage-all-changes' When there are both
+ staged and unstaged changes, then un-/staging everything would
+ destroy that distinction. Of course that also applies when
+ un-/staging a single change, but then less is lost and one does
+ that so often that having to confirm every time would be
+ unacceptable.
+
+Files:
+
+ `delete' When a file that isn't yet tracked by Git is deleted
+ then it is completely lost, not just the last changes. Very
+ dangerous.
+
+ `trash' Instead of deleting a file it can also be move to the
+ system trash. Obviously much less dangerous than deleting it.
+
+ Also see option `magit-delete-by-moving-to-trash'.
+
+ `resurrect' A deleted file can easily be resurrected by
+ \"deleting\" the deletion, which is done using the same command
+ that was used to delete the same file in the first place.
+
+ `untrack' Untracking a file can be undone by tracking it again.
+
+ `rename' Renaming a file can easily be undone.
+
+Sequences:
+
+ `reset-bisect' Aborting (known to Git as \"resetting\") a
+ bisect operation loses all information collected so far.
+
+ `abort-rebase' Aborting a rebase throws away all already
+ modified commits, but it's possible to restore those from the
+ reflog.
+
+ `abort-merge' Aborting a merge throws away all conflict
+ resolutions which has already been carried out by the user.
+
+ `merge-dirty' Merging with a dirty worktree can make it hard to
+ go back to the state before the merge was initiated.
+
+References:
+
+ `delete-unmerged-branch' Once a branch has been deleted it can
+ only be restored using low-level recovery tools provided by
+ Git. And even then the reflog is gone. The user always has
+ to confirm the deletion of a branch by accepting the default
+ choice (or selecting another branch), but when a branch has
+ not been merged yet, also make sure the user is aware of that.
+
+ `delete-branch-on-remote' Deleting a \"remote branch\" may mean
+ deleting the (local) \"remote-tracking\" branch only, or also
+ removing it from the remote itself. The latter often makes more
+ sense because otherwise simply fetching from the remote would
+ restore the remote-tracking branch, but doing that can be
+ surprising and hard to recover from, so we ask.
+
+ `delete-pr-remote' When deleting a branch that was created from
+ a pull-request and if no other branches still exist on that
+ remote, then `magit-branch-delete' offers to delete the remote
+ as well. This should be safe because it only happens if no
+ other refs exist in the remotes namespace, and you can recreate
+ the remote if necessary.
+
+ `drop-stashes' Dropping a stash is dangerous because Git stores
+ stashes in the reflog. Once a stash is removed, there is no
+ going back without using low-level recovery tools provided by
+ Git. When a single stash is dropped, then the user always has
+ to confirm by accepting the default (or selecting another).
+ This action only concerns the deletion of multiple stashes at
+ once.
+
+Publishing:
+
+ `set-and-push' When pushing to the upstream or the push-remote
+ and that isn't actually configured yet, then the user can first
+ set the target. If s/he confirms the default too quickly, then
+ s/he might end up pushing to the wrong branch and if the remote
+ repository is configured to disallow fixing such mistakes, then
+ that can be quite embarrassing and annoying.
+
+Edit published history:
+
+ Without adding these symbols here, you will be warned before
+ editing commits that have already been pushed to one of the
+ branches listed in `magit-published-branches'.
+
+ `amend-published' Affects most commands that amend to `HEAD'.
+
+ `rebase-published' Affects commands that perform interactive
+ rebases. This includes commands from the commit popup that
+ modify a commit other than `HEAD', namely the various fixup
+ and squash variants.
+
+ `edit-published' Affects the commands `magit-edit-line-commit'
+ and `magit-diff-edit-hunk-commit'. These two commands make
+ it quite easy to accidentally edit a published commit, so you
+ should think twice before configuring them not to ask for
+ confirmation.
+
+ To disable confirmation completely, add all three symbols here
+ or set `magit-published-branches' to nil.
+
+Removing modules:
+
+ `remove-modules' When you remove the working directory of a
+ module that does not contain uncommitted changes, then that is
+ safer than doing so when there are uncommitted changes and/or
+ when you also remove the gitdir. Still, you don't want to do
+ that by accident.
+
+ `remove-dirty-modules' When you remove the working directory of
+ a module that contains uncommitted changes, then those changes
+ are gone for good. It is better to go to the module, inspect
+ these changes and only if appropriate discard them manually.
+
+ `trash-module-gitdirs' When you remove the gitdir of a module,
+ then all unpushed changes are gone for good. It is very easy
+ to forget that you have some unfinished work on an unpublished
+ feature branch or even in a stash.
+
+ Actually there are some safety precautions in place, that might
+ help you out if you make an unwise choice here, but don't count
+ on it. In case of emergency, stay calm and check the stash and
+ the `trash-directory' for traces of lost work.
+
+Various:
+
+ `kill-process' There seldom is a reason to kill a process.
+
+Global settings:
+
+ Instead of adding all of the above symbols to the value of this
+ option you can also set it to the atom `t', which has the same
+ effect as adding all of the above symbols. Doing that most
+ certainly is a bad idea, especially because other symbols might
+ be added in the future. So even if you don't want to be asked
+ for confirmation for any of these actions, you are still better
+ of adding all of the respective symbols individually.
+
+ When `magit-wip-before-change-mode' is enabled then these actions
+ can fairly easily be undone: `discard', `reverse',
+ `stage-all-changes', and `unstage-all-changes'. If and only if
+ this mode is enabled, then `safe-with-wip' has the same effect
+ as adding all of these symbols individually."
+ :package-version '(magit . "2.1.0")
+ :group 'magit-essentials
+ :group 'magit-commands
+ :type `(choice (const :tag "Always require confirmation" nil)
+ (const :tag "Never require confirmation" t)
+ (set :tag "Require confirmation except for"
+ ;; `remove-dirty-modules' and
+ ;; `trash-module-gitdirs' intentionally
+ ;; omitted.
+ ,@magit--confirm-actions)))
+
+(defcustom magit-slow-confirm '(drop-stashes)
+ "Whether to ask user \"y or n\" or \"yes or no\" questions.
+
+When this is nil, then `y-or-n-p' is used when the user has to
+confirm a potentially destructive action. When this is t, then
+`yes-or-no-p' is used instead. If this is a list of symbols
+identifying actions, then `yes-or-no-p' is used for those,
+`y-or-no-p' for all others. The list of actions is the same as
+for `magit-no-confirm' (which see)."
+ :package-version '(magit . "2.9.0")
+ :group 'magit-miscellaneous
+ :type `(choice (const :tag "Always ask \"yes or no\" questions" t)
+ (const :tag "Always ask \"y or n\" questions" nil)
+ (set :tag "Ask \"yes or no\" questions only for"
+ ,@magit--confirm-actions)))
+
+(defcustom magit-no-message nil
+ "A list of messages Magit should not display.
+
+Magit displays most echo area messages using `message', but a few
+are displayed using `magit-message' instead, which takes the same
+arguments as the former, FORMAT-STRING and ARGS. `magit-message'
+forgoes printing a message if any member of this list is a prefix
+of the respective FORMAT-STRING.
+
+If Magit prints a message which causes you grief, then please
+first investigate whether there is another option which can be
+used to suppress it. If that is not the case, then ask the Magit
+maintainers to start using `magit-message' instead of `message'
+in that case. We are not proactively replacing all uses of
+`message' with `magit-message', just in case someone *might* find
+some of these messages useless.
+
+Messages which can currently be suppressed using this option are:
+* \"Turning on magit-auto-revert-mode...\""
+ :package-version '(magit . "2.8.0")
+ :group 'magit-miscellaneous
+ :type '(repeat string))
+
+(defcustom magit-ellipsis (if (char-displayable-p ?…) "…" "...")
+ "String used to abbreviate text in process buffers.
+
+Currently this is only used to elide `magit-git-global-arguments'
+in process buffers. In the future it may be used in other places
+as well, but not the following:
+
+- Author names in the log margin are always abbreviated using
+ \"…\" or if that is not displayable, then \">\".
+
+- Whether collapsed sections are indicated using ellipsis is
+ controlled by `magit-section-visibility-indicator'."
+ :package-version '(magit . "3.0.0")
+ :group 'magit-miscellaneous
+ :type 'string)
+
+(defcustom magit-update-other-window-delay 0.2
+ "Delay before automatically updating the other window.
+
+When moving around in certain buffers, then certain other
+buffers, which are being displayed in another window, may
+optionally be updated to display information about the
+section at point.
+
+When holding down a key to move by more than just one section,
+then that would update that buffer for each section on the way.
+To prevent that, updating the revision buffer is delayed, and
+this option controls for how long. For optimal experience you
+might have to adjust this delay and/or the keyboard repeat rate
+and delay of your graphical environment or operating system."
+ :package-version '(magit . "2.3.0")
+ :group 'magit-miscellaneous
+ :type 'number)
+
+(defcustom magit-view-git-manual-method 'info
+ "How links to Git documentation are followed from Magit's Info manuals.
+
+`info' Follow the link to the node in the `gitman' Info manual
+ as usual. Unfortunately that manual is not installed by
+ default on some platforms, and when it is then the nodes
+ look worse than the actual manpages.
+
+`man' View the respective man-page using the `man' package.
+
+`woman' View the respective man-page using the `woman' package."
+ :package-version '(magit . "2.9.0")
+ :group 'magit-miscellaneous
+ :type '(choice (const :tag "view info manual" info)
+ (const :tag "view manpage using `man'" man)
+ (const :tag "view manpage using `woman'" woman)))
+
+;;; Section Classes
+
+(defclass magit-commit-section (magit-section) ())
+
+(setf (alist-get 'commit magit--section-type-alist) 'magit-commit-section)
+
+(defclass magit-diff-section (magit-section) () :abstract t)
+
+(defclass magit-file-section (magit-diff-section)
+ ((keymap :initform 'magit-file-section-map)
+ (source :initform nil)
+ (header :initform nil)))
+
+(defclass magit-module-section (magit-file-section)
+ ((keymap :initform 'magit-module-section-map)
+ (range :initform nil)))
+
+(defclass magit-hunk-section (magit-diff-section)
+ ((keymap :initform 'magit-hunk-section-map)
+ (refined :initform nil)
+ (combined :initform nil)
+ (from-range :initform nil)
+ (from-ranges :initform nil)
+ (to-range :initform nil)
+ (about :initform nil)))
+
+(setf (alist-get 'file magit--section-type-alist) 'magit-file-section)
+(setf (alist-get 'module magit--section-type-alist) 'magit-module-section)
+(setf (alist-get 'hunk magit--section-type-alist) 'magit-hunk-section)
+
+(defclass magit-log-section (magit-section) () :abstract t)
+(defclass magit-unpulled-section (magit-log-section) ())
+(defclass magit-unpushed-section (magit-log-section) ())
+(defclass magit-unmerged-section (magit-log-section) ())
+
+(setf (alist-get 'unpulled magit--section-type-alist) 'magit-unpulled-section)
+(setf (alist-get 'unpushed magit--section-type-alist) 'magit-unpushed-section)
+(setf (alist-get 'unmerged magit--section-type-alist) 'magit-unmerged-section)
+
+;;; User Input
+
+(defvar helm-completion-in-region-default-sort-fn)
+(defvar helm-crm-default-separator)
+(defvar ivy-sort-functions-alist)
+(defvar ivy-sort-matches-functions-alist)
+
+(defvar magit-completing-read--silent-default nil)
+
+(defun magit-completing-read (prompt collection &optional
+ predicate require-match initial-input
+ hist def fallback)
+ "Read a choice in the minibuffer, or use the default choice.
+
+This is the function that Magit commands use when they need the
+user to select a single thing to act on. The arguments have the
+same meaning as for `completing-read', except for FALLBACK, which
+is unique to this function and is described below.
+
+Instead of asking the user to choose from a list of possible
+candidates, this function may instead just return the default
+specified by DEF, with or without requiring user confirmation.
+Whether that is the case depends on PROMPT, `this-command' and
+`magit-dwim-selection'. See the documentation of the latter for
+more information.
+
+If it does use the default without the user even having to
+confirm that, then `magit-completing-read--silent-default' is set
+to t, otherwise nil.
+
+If it does read a value in the minibuffer, then this function
+acts similarly to `completing-read', except for the following:
+
+- COLLECTION must be a list of choices. A function is not
+ supported.
+
+- If REQUIRE-MATCH is nil and the user exits without a choice,
+ then nil is returned instead of an empty string.
+
+- If REQUIRE-MATCH is non-nil and the user exits without a
+ choice, `user-error' is raised.
+
+- FALLBACK specifies a secondary default that is only used if
+ the primary default DEF is nil. The secondary default is not
+ subject to `magit-dwim-selection' — if DEF is nil but FALLBACK
+ is not, then this function always asks the user to choose a
+ candidate, just as if both defaults were nil.
+
+- \": \" is appended to PROMPT.
+
+- PROMPT is modified to end with \" (default DEF|FALLBACK): \"
+ provided that DEF or FALLBACK is non-nil, that neither
+ `ivy-mode' nor `helm-mode' is enabled, and that
+ `magit-completing-read-function' is set to its default value of
+ `magit-builtin-completing-read'."
+ (setq magit-completing-read--silent-default nil)
+ (if-let ((dwim (and def
+ (nth 2 (-first (pcase-lambda (`(,cmd ,re ,_))
+ (and (eq this-command cmd)
+ (or (not re)
+ (string-match-p re prompt))))
+ magit-dwim-selection)))))
+ (if (eq dwim 'ask)
+ (if (y-or-n-p (format "%s %s? " prompt def))
+ def
+ (user-error "Abort"))
+ (setq magit-completing-read--silent-default t)
+ def)
+ (unless def
+ (setq def fallback))
+ (let ((command this-command)
+ (reply (funcall magit-completing-read-function
+ (concat prompt ": ")
+ (if (and def (not (member def collection)))
+ (cons def collection)
+ collection)
+ predicate
+ require-match initial-input hist def)))
+ (setq this-command command)
+ ;; Note: Avoid `string=' to support `helm-comp-read-use-marked'.
+ (if (equal reply "")
+ (if require-match
+ (user-error "Nothing selected")
+ nil)
+ reply))))
+
+(defun magit--completion-table (collection)
+ (lambda (string pred action)
+ (if (eq action 'metadata)
+ '(metadata (display-sort-function . identity))
+ (complete-with-action action collection string pred))))
+
+(defun magit-builtin-completing-read
+ (prompt choices &optional predicate require-match initial-input hist def)
+ "Magit wrapper for standard `completing-read' function."
+ (unless (or (bound-and-true-p helm-mode)
+ (bound-and-true-p ivy-mode)
+ (bound-and-true-p vertico-mode)
+ (bound-and-true-p selectrum-mode))
+ (setq prompt (magit-prompt-with-default prompt def)))
+ (unless (or (bound-and-true-p helm-mode)
+ (bound-and-true-p ivy-mode))
+ (setq choices (magit--completion-table choices)))
+ (cl-letf (((symbol-function #'completion-pcm--all-completions)))
+ (when (< emacs-major-version 26)
+ (fset 'completion-pcm--all-completions
+ 'magit-completion-pcm--all-completions))
+ (let ((ivy-sort-functions-alist nil))
+ (completing-read prompt choices
+ predicate require-match
+ initial-input hist def))))
+
+(defun magit-completing-read-multiple
+ (prompt choices &optional sep default hist keymap)
+ "Read multiple items from CHOICES, separated by SEP.
+
+Set up the `crm' variables needed to read multiple values with
+`read-from-minibuffer'.
+
+SEP is a regexp matching characters that can separate choices.
+When SEP is nil, it defaults to `crm-default-separator'.
+DEFAULT, HIST, and KEYMAP are passed to `read-from-minibuffer'.
+When KEYMAP is nil, it defaults to `crm-local-completion-map'.
+
+Unlike `completing-read-multiple', the return value is not split
+into a list."
+ (declare (obsolete magit-completing-read-multiple* "Magit 3.1.0"))
+ (let* ((crm-separator (or sep crm-default-separator))
+ (crm-completion-table (magit--completion-table choices))
+ (choose-completion-string-functions
+ '(crm--choose-completion-string))
+ (minibuffer-completion-table #'crm--collection-fn)
+ (minibuffer-completion-confirm t)
+ (helm-completion-in-region-default-sort-fn nil)
+ (helm-crm-default-separator nil)
+ (ivy-sort-matches-functions-alist nil)
+ (input
+ (cl-letf (((symbol-function #'completion-pcm--all-completions)))
+ (when (< emacs-major-version 26)
+ (fset 'completion-pcm--all-completions
+ 'magit-completion-pcm--all-completions))
+ (read-from-minibuffer
+ (concat prompt (and default (format " (%s)" default)) ": ")
+ nil (or keymap crm-local-completion-map)
+ nil hist default))))
+ (when (string-equal input "")
+ (or (setq input default)
+ (user-error "Nothing selected")))
+ input))
+
+(defun magit-completing-read-multiple*
+ (prompt table &optional predicate require-match initial-input
+ hist def inherit-input-method
+ no-split)
+ "Read multiple strings in the minibuffer, with completion.
+Like `completing-read-multiple' but don't mess with order of
+TABLE and take an additional argument NO-SPLIT, which causes
+the user input to be returned as a single unmodified string.
+Also work around various incompatible features of various
+third-party completion frameworks."
+ (cl-letf*
+ (;; To implement NO-SPLIT we have to manipulate the respective
+ ;; `split-string' invocation. We cannot simply advice it to
+ ;; return the input string because `SELECTRUM' would choke on
+ ;; that string. Use a variable to pass along the raw user
+ ;; input string. aa5f098ab
+ (input nil)
+ (split-string (symbol-function #'split-string))
+ ((symbol-function #'split-string)
+ (lambda (string &optional separators omit-nulls trim)
+ (when (and no-split
+ (equal separators crm-separator)
+ (equal omit-nulls t))
+ (setq input string))
+ (funcall split-string string separators omit-nulls trim)))
+ ;; In Emacs 25 this function has a bug, so we use a copy of the
+ ;; version from Emacs 26. bef9c7aa3
+ ((symbol-function #'completion-pcm--all-completions)
+ (if (< emacs-major-version 26)
+ 'magit-completion-pcm--all-completions
+ (symbol-function #'completion-pcm--all-completions)))
+ ;; Prevent `BUILT-IN' completion from messing up our existing
+ ;; order of the completion candidates. aa5f098ab
+ (table (magit--completion-table table))
+ ;; Prevent `IVY' from messing up our existing order. c7af78726
+ (ivy-sort-matches-functions-alist nil)
+ ;; Prevent `HELM' from messing up our existing order. 6fcf994bd
+ (helm-completion-in-region-default-sort-fn nil)
+ ;; Prevent `HELM' from automatically appending the separator,
+ ;; which is counterproductive when NO-SPLIT is non-nil and/or
+ ;; when reading commit ranges. 798aff564
+ (helm-crm-default-separator
+ (if no-split nil (bound-and-true-p helm-crm-default-separator)))
+ (values
+ (if (and no-split
+ (advice-member-p 'consult-completing-read-multiple
+ 'completing-read-multiple))
+ ;; Our NO-SPLIT hack is not compatible with `CONSULT's
+ ;; implementation so fall back to the original function.
+ ;; #4437
+ (unwind-protect
+ (progn
+ (advice-remove 'completing-read-multiple
+ 'consult-completing-read-multiple)
+ (completing-read-multiple
+ prompt table predicate require-match initial-input
+ hist def inherit-input-method))
+ (advice-add 'completing-read-multiple :override
+ 'consult-completing-read-multiple))
+ (completing-read-multiple
+ prompt table predicate require-match initial-input
+ hist def inherit-input-method))))
+ (if no-split input values)))
+
+(defun magit-ido-completing-read
+ (prompt choices &optional predicate require-match initial-input hist def)
+ "Ido-based `completing-read' almost-replacement.
+
+Unfortunately `ido-completing-read' is not suitable as a
+drop-in replacement for `completing-read', instead we use
+`ido-completing-read+' from the third-party package by the
+same name."
+ (if (and (require 'ido-completing-read+ nil t)
+ (fboundp 'ido-completing-read+))
+ (ido-completing-read+ prompt choices predicate require-match
+ initial-input hist
+ (or def (and require-match (car choices))))
+ (display-warning 'magit "ido-completing-read+ is not installed
+
+To use Ido completion with Magit you need to install the
+third-party `ido-completing-read+' packages. Falling
+back to built-in `completing-read' for now." :error)
+ (magit-builtin-completing-read prompt choices predicate require-match
+ initial-input hist def)))
+
+(defun magit-prompt-with-default (prompt def)
+ (if (and def (length> prompt 2)
+ (string-equal ": " (substring prompt -2)))
+ (format "%s (default %s): " (substring prompt 0 -2) def)
+ prompt))
+
+(defvar magit-minibuffer-local-ns-map
+ (let ((map (make-sparse-keymap)))
+ (set-keymap-parent map minibuffer-local-map)
+ (define-key map "\s" #'magit-whitespace-disallowed)
+ (define-key map "\t" #'magit-whitespace-disallowed)
+ map))
+
+(defun magit-whitespace-disallowed ()
+ "Beep to tell the user that whitespace is not allowed."
+ (interactive)
+ (ding)
+ (message "Whitespace isn't allowed here")
+ (setq defining-kbd-macro nil)
+ (force-mode-line-update))
+
+(defun magit-read-string (prompt &optional initial-input history default-value
+ inherit-input-method no-whitespace)
+ "Read a string from the minibuffer, prompting with string PROMPT.
+
+This is similar to `read-string', but
+* empty input is only allowed if DEFAULT-VALUE is non-nil in
+ which case that is returned,
+* whitespace is not allowed and leading and trailing whitespace is
+ removed automatically if NO-WHITESPACE is non-nil,
+* \": \" is appended to PROMPT, and
+* an invalid DEFAULT-VALUE is silently ignored."
+ (when default-value
+ (when (consp default-value)
+ (setq default-value (car default-value)))
+ (unless (stringp default-value)
+ (setq default-value nil)))
+ (let* ((minibuffer-completion-table nil)
+ (val (read-from-minibuffer
+ (magit-prompt-with-default (concat prompt ": ") default-value)
+ initial-input (and no-whitespace magit-minibuffer-local-ns-map)
+ nil history default-value inherit-input-method))
+ (trim (lambda (regexp string)
+ (save-match-data
+ (if (string-match regexp string)
+ (replace-match "" t t string)
+ string)))))
+ (when (and (string= val "") default-value)
+ (setq val default-value))
+ (when no-whitespace
+ (setq val (funcall trim "\\`\\(?:[ \t\n\r]+\\)"
+ (funcall trim "\\(?:[ \t\n\r]+\\)\\'" val))))
+ (cond ((string= val "")
+ (user-error "Need non-empty input"))
+ ((and no-whitespace (string-match-p "[\s\t\n]" val))
+ (user-error "Input contains whitespace"))
+ (t val))))
+
+(defun magit-read-string-ns (prompt &optional initial-input history
+ default-value inherit-input-method)
+ "Call `magit-read-string' with non-nil NO-WHITESPACE."
+ (magit-read-string prompt initial-input history default-value
+ inherit-input-method t))
+
+(defmacro magit-read-char-case (prompt verbose &rest clauses)
+ (declare (indent 2)
+ (debug (form form &rest (characterp form body))))
+ `(prog1 (pcase (read-char-choice
+ (concat ,prompt
+ (mapconcat #'identity
+ (list ,@(mapcar #'cadr clauses))
+ ", ")
+ ,(if verbose ", or [C-g] to abort " " "))
+ ',(mapcar #'car clauses))
+ ,@(--map `(,(car it) ,@(cddr it)) clauses))
+ (message "")))
+
+(defun magit-y-or-n-p (prompt &optional action)
+ "Ask user a \"y or n\" or a \"yes or no\" question using PROMPT.
+Which kind of question is used depends on whether
+ACTION is a member of option `magit-slow-confirm'."
+ (if (or (eq magit-slow-confirm t)
+ (and action (member action magit-slow-confirm)))
+ (yes-or-no-p prompt)
+ (y-or-n-p prompt)))
+
+(defvar magit--no-confirm-alist
+ '((safe-with-wip magit-wip-before-change-mode
+ discard reverse stage-all-changes unstage-all-changes)))
+
+(cl-defun magit-confirm (action &optional prompt prompt-n noabort
+ (items nil sitems))
+ (declare (indent defun))
+ (setq prompt-n (format (concat (or prompt-n prompt) "? ") (length items)))
+ (setq prompt (format (concat (or prompt (magit-confirm-make-prompt action))
+ "? ")
+ (car items)))
+ (or (cond ((and (not (eq action t))
+ (or (eq magit-no-confirm t)
+ (memq action magit-no-confirm)
+ (cl-member-if (pcase-lambda (`(,key ,var . ,sub))
+ (and (memq key magit-no-confirm)
+ (memq action sub)
+ (or (not var)
+ (and (boundp var)
+ (symbol-value var)))))
+ magit--no-confirm-alist)))
+ (or (not sitems) items))
+ ((not sitems)
+ (magit-y-or-n-p prompt action))
+ ((length= items 1)
+ (and (magit-y-or-n-p prompt action) items))
+ ((length> items 1)
+ (and (magit-y-or-n-p (concat (mapconcat #'identity items "\n")
+ "\n\n" prompt-n)
+ action)
+ items)))
+ (if noabort nil (user-error "Abort"))))
+
+(defun magit-confirm-files (action files &optional prompt)
+ (when files
+ (unless prompt
+ (setq prompt (magit-confirm-make-prompt action)))
+ (magit-confirm action
+ (concat prompt " %s")
+ (concat prompt " %i files")
+ nil files)))
+
+(defun magit-confirm-make-prompt (action)
+ (let ((prompt (symbol-name action)))
+ (string-replace "-" " "
+ (concat (upcase (substring prompt 0 1))
+ (substring prompt 1)))))
+
+(defun magit-read-number-string (prompt &optional default _history)
+ "Like `read-number' but return value is a string.
+DEFAULT may be a number or a numeric string."
+ (number-to-string
+ (read-number prompt (if (stringp default)
+ (string-to-number default)
+ default))))
+
+;;; Debug Utilities
+
+;;;###autoload
+(defun magit-emacs-Q-command ()
+ "Show a shell command that runs an uncustomized Emacs with only Magit loaded.
+See info node `(magit)Debugging Tools' for more information."
+ (interactive)
+ (let ((cmd (mapconcat
+ #'shell-quote-argument
+ `(,(concat invocation-directory invocation-name)
+ "-Q" "--eval" "(setq debug-on-error t)"
+ ,@(cl-mapcan
+ (lambda (dir) (list "-L" dir))
+ (delete-dups
+ (cl-mapcan
+ (lambda (lib)
+ (let ((path (locate-library lib)))
+ (cond
+ (path
+ (list (file-name-directory path)))
+ ((not (equal lib "libgit"))
+ (error "Cannot find mandatory dependency %s" lib)))))
+ '(;; Like `LOAD_PATH' in `default.mk'.
+ "compat"
+ "dash"
+ "libgit"
+ "transient"
+ "with-editor"
+ ;; Obviously `magit' itself is needed too.
+ "magit"
+ ;; While these are part of the Magit repository,
+ ;; they are distributed as separate packages.
+ "magit-section"
+ "git-commit"
+ ))))
+ ;; Avoid Emacs bug#16406 by using full path.
+ "-l" ,(file-name-sans-extension (locate-library "magit")))
+ " ")))
+ (message "Uncustomized Magit command saved to kill-ring, %s"
+ "please run it in a terminal.")
+ (kill-new cmd)))
+
+;;; Text Utilities
+
+(defmacro magit-bind-match-strings (varlist string &rest body)
+ "Bind variables to submatches according to VARLIST then evaluate BODY.
+Bind the symbols in VARLIST to submatches of the current match
+data, starting with 1 and incrementing by 1 for each symbol. If
+the last match was against a string, then that has to be provided
+as STRING."
+ (declare (indent 2) (debug (listp form body)))
+ (let ((s (cl-gensym "string"))
+ (i 0))
+ `(let ((,s ,string))
+ (let ,(save-match-data
+ (cl-mapcan (lambda (sym)
+ (cl-incf i)
+ (and (not (eq (aref (symbol-name sym) 0) ?_))
+ (list (list sym (list 'match-string i s)))))
+ varlist))
+ ,@body))))
+
+(defun magit-delete-line ()
+ "Delete the rest of the current line."
+ (delete-region (point) (1+ (line-end-position))))
+
+(defun magit-delete-match (&optional num)
+ "Delete text matched by last search.
+If optional NUM is specified, only delete that subexpression."
+ (delete-region (match-beginning (or num 0))
+ (match-end (or num 0))))
+
+(defun magit-file-line (file)
+ "Return the first line of FILE as a string."
+ (when (file-regular-p file)
+ (with-temp-buffer
+ (insert-file-contents file)
+ (buffer-substring-no-properties (point-min)
+ (line-end-position)))))
+
+(defun magit-file-lines (file &optional keep-empty-lines)
+ "Return a list of strings containing one element per line in FILE.
+Unless optional argument KEEP-EMPTY-LINES is t, trim all empty lines."
+ (when (file-regular-p file)
+ (with-temp-buffer
+ (insert-file-contents file)
+ (split-string (buffer-string) "\n" (not keep-empty-lines)))))
+
+(defun magit-set-header-line-format (string)
+ "Set the header-line using STRING.
+Propertize STRING with the `magit-header-line'. If the `face'
+property of any part of STRING is already set, then that takes
+precedence. Also pad the left side of STRING so that it aligns
+with the text area."
+ (setq header-line-format
+ (concat (propertize " " 'display '(space :align-to 0))
+ string)))
+
+(defun magit--format-spec (format specification)
+ "Like `format-spec' but preserve text properties in SPECIFICATION."
+ (with-temp-buffer
+ (insert format)
+ (goto-char (point-min))
+ (while (search-forward "%" nil t)
+ (cond
+ ;; Quoted percent sign.
+ ((eq (char-after) ?%)
+ (delete-char 1))
+ ;; Valid format spec.
+ ((looking-at "\\([-0-9.]*\\)\\([a-zA-Z]\\)")
+ (let* ((num (match-string 1))
+ (spec (string-to-char (match-string 2)))
+ (val (assq spec specification)))
+ (unless val
+ (error "Invalid format character: `%%%c'" spec))
+ (setq val (cdr val))
+ ;; Pad result to desired length.
+ (let ((text (format (concat "%" num "s") val)))
+ ;; Insert first, to preserve text properties.
+ (if (next-property-change 0 (concat " " text))
+ ;; If the inserted text has properties, then preserve those.
+ (insert text)
+ ;; Otherwise preserve FORMAT's properties, like `format-spec'.
+ (insert-and-inherit text))
+ ;; Delete the specifier body.
+ (delete-region (+ (match-beginning 0) (length text))
+ (+ (match-end 0) (length text)))
+ ;; Delete the percent sign.
+ (delete-region (1- (match-beginning 0)) (match-beginning 0)))))
+ ;; Signal an error on bogus format strings.
+ (t
+ (error "Invalid format string"))))
+ (buffer-string)))
+
+;;; Missing from Emacs
+
+(defun magit-kill-this-buffer ()
+ "Kill the current buffer."
+ (interactive)
+ (kill-buffer (current-buffer)))
+
+(defun magit--buffer-string (&optional min max trim)
+ "Like `buffer-substring-no-properties' but the arguments are optional.
+
+This combines the benefits of `buffer-string', `buffer-substring'
+and `buffer-substring-no-properties' into one function that is
+not as painful to use as the latter. I.e. you can write
+ (magit--buffer-string)
+instead of
+ (buffer-substring-no-properties (point-min)
+ (point-max))
+
+Optional MIN defaults to the value of `point-min'.
+Optional MAX defaults to the value of `point-max'.
+
+If optional TRIM is non-nil, then all leading and trailing
+whitespace is remove. If it is the newline character, then
+one trailing newline is added."
+ ;; Lets write that one last time and be done with it:
+ (let ((str (buffer-substring-no-properties (or min (point-min))
+ (or max (point-max)))))
+ (if trim
+ (concat (string-trim str)
+ (and (eq trim ?\n) "\n"))
+ str)))
+
+(defun magit--version> (v1 v2)
+ "Return t if version V1 is higher (younger) than V2.
+This function should be named `version>' and be part of Emacs."
+ (version-list-< (version-to-list v2) (version-to-list v1)))
+
+(defun magit--version>= (v1 v2)
+ "Return t if version V1 is higher (younger) than or equal to V2.
+This function should be named `version>=' and be part of Emacs."
+ (version-list-<= (version-to-list v2) (version-to-list v1)))
+
+;;; Kludges for Emacs Bugs
+
+(defun magit-file-accessible-directory-p (filename)
+ "Like `file-accessible-directory-p' but work around an Apple bug.
+See http://debbugs.gnu.org/cgi/bugreport.cgi?bug=21573#17
+and https://github.com/magit/magit/issues/2295."
+ (and (file-directory-p filename)
+ (file-accessible-directory-p filename)))
+
+(when (< emacs-major-version 27)
+ ;; Work around https://debbugs.gnu.org/cgi/bugreport.cgi?bug=21559.
+ ;; Fixed by cb55ccae8be946f1562d74718086a4c8c8308ee5 in Emacs 27.1.
+ (with-eval-after-load 'vc-git
+ (defun vc-git-conflicted-files (directory)
+ "Return the list of files with conflicts in DIRECTORY."
+ (let* ((status
+ (vc-git--run-command-string directory "diff-files"
+ "--name-status"))
+ (lines (when status (split-string status "\n" 'omit-nulls)))
+ files)
+ (dolist (line lines files)
+ (when (string-match "\\([ MADRCU?!]\\)[ \t]+\\(.+\\)" line)
+ (let ((state (match-string 1 line))
+ (file (match-string 2 line)))
+ (when (equal state "U")
+ (push (expand-file-name file directory) files)))))))))
+
+(when (< emacs-major-version 27)
+ (defun vc-git--call@bug21559 (fn buffer command &rest args)
+ "Backport https://debbugs.gnu.org/cgi/bugreport.cgi?bug=21559."
+ (let ((process-environment process-environment))
+ (when revert-buffer-in-progress-p
+ (push "GIT_OPTIONAL_LOCKS=0" process-environment))
+ (apply fn buffer command args)))
+ (advice-add 'vc-git--call :around 'vc-git--call@bug21559)
+
+ (defun vc-git-command@bug21559
+ (fn buffer okstatus file-or-list &rest flags)
+ "Backport https://debbugs.gnu.org/cgi/bugreport.cgi?bug=21559."
+ (let ((process-environment process-environment))
+ (when revert-buffer-in-progress-p
+ (push "GIT_OPTIONAL_LOCKS=0" process-environment))
+ (apply fn buffer okstatus file-or-list flags)))
+ (advice-add 'vc-git-command :around 'vc-git-command@bug21559)
+
+ (defun auto-revert-handler@bug21559 (fn)
+ "Backport https://debbugs.gnu.org/cgi/bugreport.cgi?bug=21559."
+ (let ((revert-buffer-in-progress-p t))
+ (funcall fn)))
+ (advice-add 'auto-revert-handler :around 'auto-revert-handler@bug21559)
+ )
+
+(when (< emacs-major-version 26)
+ ;; In Emacs 25 `completion-pcm--all-completions' reverses the
+ ;; completion list. This is the version from Emacs 26, which
+ ;; fixes that issue. bug#24676
+ (defun magit-completion-pcm--all-completions (prefix pattern table pred)
+ (if (completion-pcm--pattern-trivial-p pattern)
+ (all-completions (concat prefix (car pattern)) table pred)
+ (let* ((regex (completion-pcm--pattern->regex pattern))
+ (case-fold-search completion-ignore-case)
+ (completion-regexp-list (cons regex completion-regexp-list))
+ (compl (all-completions
+ (concat prefix
+ (if (stringp (car pattern)) (car pattern) ""))
+ table pred)))
+ (if (not (functionp table))
+ compl
+ (let ((poss ()))
+ (dolist (c compl)
+ (when (string-match-p regex c) (push c poss)))
+ (nreverse poss)))))))
+
+(defun magit-which-function ()
+ "Return current function name based on point.
+
+This is a simple wrapper around `which-function', that resets
+Imenu's potentially outdated and therefore unreliable cache by
+setting `imenu--index-alist' to nil before calling that function."
+ (setq imenu--index-alist nil)
+ (which-function))
+
+;;; Kludges for Custom
+
+(defun magit-custom-initialize-reset (symbol exp)
+ "Initialize SYMBOL based on EXP.
+Set the symbol, using `set-default' (unlike
+`custom-initialize-reset' which uses the `:set' function if any.)
+The value is either the symbol's current value
+ (as obtained using the `:get' function), if any,
+or the value in the symbol's `saved-value' property if any,
+or (last of all) the value of EXP."
+ (set-default-toplevel-value
+ symbol
+ (condition-case nil
+ (let ((def (default-toplevel-value symbol))
+ (getter (get symbol 'custom-get)))
+ (if getter (funcall getter symbol) def))
+ (error
+ (eval (let ((sv (get symbol 'saved-value)))
+ (if sv (car sv) exp)))))))
+
+(defun magit-hook-custom-get (symbol)
+ (if (symbol-file symbol 'defvar)
+ (default-toplevel-value symbol)
+ ;;
+ ;; Called by `custom-initialize-reset' on behalf of `symbol's
+ ;; `defcustom', which is being evaluated for the first time to
+ ;; set the initial value, but there's already a default value,
+ ;; which most likely was established by one or more `add-hook'
+ ;; calls.
+ ;;
+ ;; We combine the `standard-value' and the current value, while
+ ;; preserving the order established by `:options', and return
+ ;; the result of that to be used as the "initial" default value.
+ ;;
+ (let ((standard (eval (car (get symbol 'standard-value))))
+ (current (default-toplevel-value symbol))
+ (value nil))
+ (dolist (fn (get symbol 'custom-options))
+ (when (or (memq fn standard)
+ (memq fn current))
+ (push fn value)))
+ (dolist (fn current)
+ (unless (memq fn value)
+ (push fn value)))
+ (nreverse value))))
+
+;;; Kludges for Info Manuals
+
+;;;###autoload
+(defun Info-follow-nearest-node--magit-gitman (fn &optional fork)
+ (let ((node (Info-get-token
+ (point) "\\*note[ \n\t]+"
+ "\\*note[ \n\t]+\\([^:]*\\):\\(:\\|[ \n\t]*(\\)?")))
+ (if (and node (string-match "^(gitman)\\(.+\\)" node))
+ (pcase magit-view-git-manual-method
+ ('info (funcall fn fork))
+ ('man (require 'man)
+ (man (match-string 1 node)))
+ ('woman (require 'woman)
+ (woman (match-string 1 node)))
+ (_
+ (user-error "Invalid value for `magit-view-git-manual-method'")))
+ (funcall fn fork))))
+
+;;;###autoload
+(advice-add 'Info-follow-nearest-node :around
+ #'Info-follow-nearest-node--magit-gitman)
+
+;; When making changes here, then also adjust the copy in docs/Makefile.
+;;;###autoload
+(advice-add 'org-man-export :around #'org-man-export--magit-gitman)
+;;;###autoload
+(defun org-man-export--magit-gitman (fn link description format)
+ (if (and (eq format 'texinfo)
+ (string-prefix-p "git" link))
+ (string-replace "%s" link "
+@ifinfo
+@ref{%s,,,gitman,}.
+@end ifinfo
+@ifhtml
+@html
+the <a href=\"http://git-scm.com/docs/%s\">%s(1)</a> manpage.
+@end html
+@end ifhtml
+@iftex
+the %s(1) manpage.
+@end iftex
+")
+ (funcall fn link description format)))
+
+;;; Kludges for Package Managers
+
+(defun magit--straight-chase-links (filename)
+ "Chase links in FILENAME until a name that is not a link.
+
+This is the same as `file-chase-links', except that it also
+handles fake symlinks that are created by the package manager
+straight.el on Windows.
+
+See <https://github.com/raxod502/straight.el/issues/520>."
+ (when (and (bound-and-true-p straight-symlink-emulation-mode)
+ (fboundp 'straight-chase-emulated-symlink))
+ (when-let ((target (straight-chase-emulated-symlink filename)))
+ (unless (eq target 'broken)
+ (setq filename target))))
+ (file-chase-links filename))
+
+;;; Kludges for older Emacs versions
+
+(if (fboundp 'with-connection-local-variables)
+ (defalias 'magit--with-connection-local-variables
+ #'with-connection-local-variables)
+ (defmacro magit--with-connection-local-variables (&rest body)
+ "Abridged `with-connection-local-variables' for pre Emacs 27 compatibility.
+Bind shell file name and switch for remote execution.
+`with-connection-local-variables' isn't available until Emacs 27.
+This kludge provides the minimal functionality required by
+Magit."
+ `(if (file-remote-p default-directory)
+ (pcase-let ((`(,shell-file-name ,shell-command-switch)
+ (with-no-warnings ; about unknown tramp functions
+ (require 'tramp)
+ (let ((vec (tramp-dissect-file-name
+ default-directory)))
+ (list (tramp-get-method-parameter
+ vec 'tramp-remote-shell)
+ (mapconcat #'identity
+ (tramp-get-method-parameter
+ vec 'tramp-remote-shell-args)
+ " "))))))
+ ,@body)
+ ,@body)))
+
+;;; Miscellaneous
+
+(defun magit-message (format-string &rest args)
+ "Display a message at the bottom of the screen, or not.
+Like `message', except that if the users configured option
+`magit-no-message' to prevent the message corresponding to
+FORMAT-STRING to be displayed, then don't."
+ (unless (--first (string-prefix-p it format-string) magit-no-message)
+ (apply #'message format-string args)))
+
+(defun magit-msg (format-string &rest args)
+ "Display a message at the bottom of the screen, but don't log it.
+Like `message', except that `message-log-max' is bound to nil."
+ (let ((message-log-max nil))
+ (apply #'message format-string args)))
+
+(defmacro magit--with-temp-position (buf pos &rest body)
+ (declare (indent 2))
+ `(with-current-buffer ,buf
+ (save-excursion
+ (save-restriction
+ (widen)
+ (goto-char (or ,pos 1))
+ ,@body))))
+
+;;; _
+(provide 'magit-base)
+;;; magit-base.el ends here
diff --git a/elpa/magit-20220503.1245/magit-base.elc b/elpa/magit-20220503.1245/magit-base.elc
new file mode 100644
index 0000000..107d3ae
--- /dev/null
+++ b/elpa/magit-20220503.1245/magit-base.elc
Binary files differ
diff --git a/elpa/magit-20220503.1245/magit-bisect.el b/elpa/magit-20220503.1245/magit-bisect.el
new file mode 100644
index 0000000..92dc6ab
--- /dev/null
+++ b/elpa/magit-20220503.1245/magit-bisect.el
@@ -0,0 +1,307 @@
+;;; magit-bisect.el --- Bisect support for Magit -*- lexical-binding:t -*-
+
+;; Copyright (C) 2008-2022 The Magit Project Contributors
+
+;; Author: Jonas Bernoulli <jonas@bernoul.li>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+
+;; SPDX-License-Identifier: GPL-3.0-or-later
+
+;; Magit 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.
+;;
+;; Magit 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 Magit. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Use a binary search to find the commit that introduced a bug.
+
+;;; Code:
+
+(require 'magit)
+
+;;; Options
+
+(defcustom magit-bisect-show-graph t
+ "Whether to use `--graph' in the log showing commits yet to be bisected."
+ :package-version '(magit . "2.8.0")
+ :group 'magit-status
+ :type 'boolean)
+
+(defface magit-bisect-good
+ '((t :foreground "DarkOliveGreen"))
+ "Face for good bisect revisions."
+ :group 'magit-faces)
+
+(defface magit-bisect-skip
+ '((t :foreground "DarkGoldenrod"))
+ "Face for skipped bisect revisions."
+ :group 'magit-faces)
+
+(defface magit-bisect-bad
+ '((t :foreground "IndianRed4"))
+ "Face for bad bisect revisions."
+ :group 'magit-faces)
+
+;;; Commands
+
+;;;###autoload (autoload 'magit-bisect "magit-bisect" nil t)
+(transient-define-prefix magit-bisect ()
+ "Narrow in on the commit that introduced a bug."
+ :man-page "git-bisect"
+ [:class transient-subgroups
+ :if-not magit-bisect-in-progress-p
+ ["Arguments"
+ ("-n" "Don't checkout commits" "--no-checkout")
+ ("-p" "Follow only first parent of a merge" "--first-parent"
+ :if (lambda () (magit-git-version>= "2.29")))
+ (6 magit-bisect:--term-old
+ :if (lambda () (magit-git-version>= "2.7")))
+ (6 magit-bisect:--term-new
+ :if (lambda () (magit-git-version>= "2.7")))]
+ ["Actions"
+ ("B" "Start" magit-bisect-start)
+ ("s" "Start script" magit-bisect-run)]]
+ ["Actions"
+ :if magit-bisect-in-progress-p
+ ("B" "Bad" magit-bisect-bad)
+ ("g" "Good" magit-bisect-good)
+ (6 "m" "Mark" magit-bisect-mark
+ :if (lambda () (magit-git-version>= "2.7")))
+ ("k" "Skip" magit-bisect-skip)
+ ("r" "Reset" magit-bisect-reset)
+ ("s" "Run script" magit-bisect-run)])
+
+(transient-define-argument magit-bisect:--term-old ()
+ :description "Old/good term"
+ :class 'transient-option
+ :key "=o"
+ :argument "--term-old=")
+
+(transient-define-argument magit-bisect:--term-new ()
+ :description "New/bad term"
+ :class 'transient-option
+ :key "=n"
+ :argument "--term-new=")
+
+;;;###autoload
+(defun magit-bisect-start (bad good args)
+ "Start a bisect session.
+
+Bisecting a bug means to find the commit that introduced it.
+This command starts such a bisect session by asking for a known
+good and a known bad commit. To move the session forward use the
+other actions from the bisect transient command (\
+\\<magit-status-mode-map>\\[magit-bisect])."
+ (interactive (if (magit-bisect-in-progress-p)
+ (user-error "Already bisecting")
+ (magit-bisect-start-read-args)))
+ (unless (magit-rev-ancestor-p good bad)
+ (user-error
+ "The %s revision (%s) has to be an ancestor of the %s one (%s)"
+ (or (transient-arg-value "--term-old=" args) "good")
+ good
+ (or (transient-arg-value "--term-new=" args) "bad")
+ bad))
+ (when (magit-anything-modified-p)
+ (user-error "Cannot bisect with uncommitted changes"))
+ (magit-git-bisect "start" (list args bad good) t))
+
+(defun magit-bisect-start-read-args ()
+ (let* ((args (transient-args 'magit-bisect))
+ (bad (magit-read-branch-or-commit
+ (format "Start bisect with %s revision"
+ (or (transient-arg-value "--term-new=" args)
+ "bad")))))
+ (list bad
+ (magit-read-other-branch-or-commit
+ (format "%s revision" (or (transient-arg-value "--term-old=" args)
+ "Good"))
+ bad)
+ args)))
+
+;;;###autoload
+(defun magit-bisect-reset ()
+ "After bisecting, cleanup bisection state and return to original `HEAD'."
+ (interactive)
+ (magit-confirm 'reset-bisect)
+ (magit-run-git "bisect" "reset")
+ (ignore-errors (delete-file (magit-git-dir "BISECT_CMD_OUTPUT"))))
+
+;;;###autoload
+(defun magit-bisect-good ()
+ "While bisecting, mark the current commit as good.
+Use this after you have asserted that the commit does not contain
+the bug in question."
+ (interactive)
+ (magit-git-bisect (or (cadr (magit-bisect-terms))
+ (user-error "Not bisecting"))))
+
+;;;###autoload
+(defun magit-bisect-bad ()
+ "While bisecting, mark the current commit as bad.
+Use this after you have asserted that the commit does contain the
+bug in question."
+ (interactive)
+ (magit-git-bisect (or (car (magit-bisect-terms))
+ (user-error "Not bisecting"))))
+
+;;;###autoload
+(defun magit-bisect-mark ()
+ "While bisecting, mark the current commit with a bisect term.
+During a bisect using alternate terms, commits can still be
+marked with `magit-bisect-good' and `magit-bisect-bad', as those
+commands map to the correct term (\"good\" to --term-old's value
+and \"bad\" to --term-new's). However, in some cases, it can be
+difficult to keep that mapping straight in your head; this
+command provides an interface that exposes the underlying terms."
+ (interactive)
+ (magit-git-bisect
+ (pcase-let ((`(,term-new ,term-old) (or (magit-bisect-terms)
+ (user-error "Not bisecting"))))
+ (pcase (read-char-choice
+ (format "Mark HEAD as %s ([n]ew) or %s ([o]ld)"
+ term-new term-old)
+ (list ?n ?o))
+ (?n term-new)
+ (?o term-old)))))
+
+;;;###autoload
+(defun magit-bisect-skip ()
+ "While bisecting, skip the current commit.
+Use this if for some reason the current commit is not a good one
+to test. This command lets Git choose a different one."
+ (interactive)
+ (magit-git-bisect "skip"))
+
+;;;###autoload
+(defun magit-bisect-run (cmdline &optional bad good args)
+ "Bisect automatically by running commands after each step.
+
+Unlike `git bisect run' this can be used before bisecting has
+begun. In that case it behaves like `git bisect start; git
+bisect run'."
+ (interactive (let ((args (and (not (magit-bisect-in-progress-p))
+ (magit-bisect-start-read-args))))
+ (cons (read-shell-command "Bisect shell command: ") args)))
+ (when (and bad good)
+ ;; Avoid `magit-git-bisect' because it's asynchronous, but the
+ ;; next `git bisect run' call requires the bisect to be started.
+ (magit-with-toplevel
+ (magit-process-git
+ (list :file (magit-git-dir "BISECT_CMD_OUTPUT"))
+ (magit-process-git-arguments
+ (list "bisect" "start" bad good args)))
+ (magit-refresh)))
+ (magit--with-connection-local-variables
+ (magit-git-bisect "run" (list shell-file-name
+ shell-command-switch cmdline))))
+
+(defun magit-git-bisect (subcommand &optional args no-assert)
+ (unless (or no-assert (magit-bisect-in-progress-p))
+ (user-error "Not bisecting"))
+ (message "Bisecting...")
+ (magit-with-toplevel
+ (magit-run-git-async "bisect" subcommand args))
+ (set-process-sentinel
+ magit-this-process
+ (lambda (process event)
+ (when (memq (process-status process) '(exit signal))
+ (if (> (process-exit-status process) 0)
+ (magit-process-sentinel process event)
+ (process-put process 'inhibit-refresh t)
+ (magit-process-sentinel process event)
+ (when (buffer-live-p (process-buffer process))
+ (with-current-buffer (process-buffer process)
+ (when-let* ((section (magit-section-at))
+ (output (buffer-substring-no-properties
+ (oref section content)
+ (oref section end))))
+ (with-temp-file (magit-git-dir "BISECT_CMD_OUTPUT")
+ (insert output)))))
+ (magit-refresh))
+ (message "Bisecting...done")))))
+
+;;; Sections
+
+(defun magit-bisect-in-progress-p ()
+ (file-exists-p (magit-git-dir "BISECT_LOG")))
+
+(defun magit-bisect-terms ()
+ (magit-file-lines (magit-git-dir "BISECT_TERMS")))
+
+(defun magit-insert-bisect-output ()
+ "While bisecting, insert section with output from `git bisect'."
+ (when (magit-bisect-in-progress-p)
+ (let* ((lines
+ (or (magit-file-lines (magit-git-dir "BISECT_CMD_OUTPUT"))
+ (list "Bisecting: (no saved bisect output)"
+ "It appears you have invoked `git bisect' from a shell."
+ "There is nothing wrong with that, we just cannot display"
+ "anything useful here. Consult the shell output instead.")))
+ (done-re "^\\([a-z0-9]\\{40,\\}\\) is the first bad commit$")
+ (bad-line (or (and (string-match done-re (car lines))
+ (pop lines))
+ (--first (string-match done-re it) lines))))
+ (magit-insert-section ((eval (if bad-line 'commit 'bisect-output))
+ (and bad-line (match-string 1 bad-line)))
+ (magit-insert-heading
+ (propertize (or bad-line (pop lines))
+ 'font-lock-face 'magit-section-heading))
+ (dolist (line lines)
+ (insert line "\n"))))
+ (insert "\n")))
+
+(defun magit-insert-bisect-rest ()
+ "While bisecting, insert section visualizing the bisect state."
+ (when (magit-bisect-in-progress-p)
+ (magit-insert-section (bisect-view)
+ (magit-insert-heading "Bisect Rest:")
+ (magit-git-wash (apply-partially #'magit-log-wash-log 'bisect-vis)
+ "bisect" "visualize" "git" "log"
+ "--format=%h%x00%D%x00%s" "--decorate=full"
+ (and magit-bisect-show-graph "--graph")))))
+
+(defun magit-insert-bisect-log ()
+ "While bisecting, insert section logging bisect progress."
+ (when (magit-bisect-in-progress-p)
+ (magit-insert-section (bisect-log)
+ (magit-insert-heading "Bisect Log:")
+ (magit-git-wash #'magit-wash-bisect-log "bisect" "log")
+ (insert ?\n))))
+
+(defun magit-wash-bisect-log (_args)
+ (let (beg)
+ (while (progn (setq beg (point-marker))
+ (re-search-forward "^\\(git bisect [^\n]+\n\\)" nil t))
+ (magit-bind-match-strings (heading) nil
+ (magit-delete-match)
+ (save-restriction
+ (narrow-to-region beg (point))
+ (goto-char (point-min))
+ (magit-insert-section (bisect-item heading t)
+ (insert (propertize heading 'font-lock-face
+ 'magit-section-secondary-heading))
+ (magit-insert-heading)
+ (magit-wash-sequence
+ (apply-partially #'magit-log-wash-rev 'bisect-log
+ (magit-abbrev-length)))
+ (insert ?\n)))))
+ (when (re-search-forward
+ "# first bad commit: \\[\\([a-z0-9]\\{40,\\}\\)\\] [^\n]+\n" nil t)
+ (magit-bind-match-strings (hash) nil
+ (magit-delete-match)
+ (magit-insert-section (bisect-item)
+ (insert hash " is the first bad commit\n"))))))
+
+;;; _
+(provide 'magit-bisect)
+;;; magit-bisect.el ends here
diff --git a/elpa/magit-20220503.1245/magit-bisect.elc b/elpa/magit-20220503.1245/magit-bisect.elc
new file mode 100644
index 0000000..196fc8d
--- /dev/null
+++ b/elpa/magit-20220503.1245/magit-bisect.elc
Binary files differ
diff --git a/elpa/magit-20220503.1245/magit-blame.el b/elpa/magit-20220503.1245/magit-blame.el
new file mode 100644
index 0000000..d26765b
--- /dev/null
+++ b/elpa/magit-20220503.1245/magit-blame.el
@@ -0,0 +1,984 @@
+;;; magit-blame.el --- Blame support for Magit -*- lexical-binding:t -*-
+
+;; Copyright (C) 2008-2022 The Magit Project Contributors
+
+;; Author: Jonas Bernoulli <jonas@bernoul.li>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+
+;; SPDX-License-Identifier: GPL-3.0-or-later
+
+;; Magit 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.
+;;
+;; Magit 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 Magit. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Annotates each line in file-visiting buffer with information from
+;; the revision which last modified the line.
+
+;;; Code:
+
+(require 'magit)
+
+;;; Options
+
+(defgroup magit-blame nil
+ "Blame support for Magit."
+ :link '(info-link "(magit)Blaming")
+ :group 'magit-modes)
+
+(defcustom magit-blame-styles
+ '((headings
+ (heading-format . "%-20a %C %s\n"))
+ (highlight
+ (highlight-face . magit-blame-highlight))
+ (lines
+ (show-lines . t)
+ (show-message . t)))
+ "List of styles used to visualize blame information.
+
+The style used in the current buffer can be cycled from the blame
+popup. Blame commands (except `magit-blame-echo') use the first
+style as the initial style when beginning to blame in a buffer.
+
+Each entry has the form (IDENT (KEY . VALUE)...). IDENT has
+to be a symbol uniquely identifying the style. The following
+KEYs are recognized:
+
+ `show-lines'
+ Whether to prefix each chunk of lines with a thin line.
+ This has no effect if `heading-format' is non-nil.
+ `show-message'
+ Whether to display a commit's summary line in the echo area
+ when crossing chunks.
+ `highlight-face'
+ Face used to highlight the first line of each chunk.
+ If this is nil, then those lines are not highlighted.
+ `heading-format'
+ String specifying the information to be shown above each
+ chunk of lines. It must end with a newline character.
+ `margin-format'
+ String specifying the information to be shown in the left
+ buffer margin. It must NOT end with a newline character.
+ This can also be a list of formats used for the lines at
+ the same positions within the chunk. If the chunk has
+ more lines than formats are specified, then the last is
+ repeated. WARNING: Adding this key affects performance;
+ see the note at the end of this docstring.
+ `margin-width'
+ Width of the margin, provided `margin-format' is non-nil.
+ `margin-face'
+ Face used in the margin, provided `margin-format' is
+ non-nil. This face is used in combination with the faces
+ that are specific to the used %-specs. If this is nil,
+ then `magit-blame-margin' is used.
+ `margin-body-face'
+ Face used in the margin for all but first line of a chunk.
+ This face is used in combination with the faces that are
+ specific to the used %-specs. This can also be a list of
+ faces (usually one face), in which case only these faces
+ are used and the %-spec faces are ignored. A good value
+ might be `(magit-blame-dimmed)'. If this is nil, then
+ the same face as for the first line is used.
+
+The following %-specs can be used in `heading-format' and
+`margin-format':
+
+ %H hash using face `magit-blame-hash'
+ %s summary using face `magit-blame-summary'
+ %a author using face `magit-blame-name'
+ %A author time using face `magit-blame-date'
+ %c committer using face `magit-blame-name'
+ %C committer time using face `magit-blame-date'
+
+Additionally if `margin-format' ends with %f, then the string
+that is displayed in the margin is made at least `margin-width'
+characters wide, which may be desirable if the used face sets
+the background color.
+
+Blame information is displayed using overlays. Such extensive
+use of overlays is known to slow down even basic operations, such
+as moving the cursor. To reduce the number of overlays the margin
+style had to be removed from the default value of this option.
+
+Note that the margin overlays are created even if another style
+is currently active. This can only be prevented by not even
+defining a style that uses the margin. If you want to use this
+style anyway, you can restore this definition, which used to be
+part of the default value:
+
+ (margin
+ (margin-format . (\" %s%f\" \" %C %a\" \" %H\"))
+ (margin-width . 42)
+ (margin-face . magit-blame-margin)
+ (margin-body-face . (magit-blame-dimmed)))"
+ :package-version '(magit . "2.13.0")
+ :group 'magit-blame
+ :type 'string)
+
+(defcustom magit-blame-echo-style 'lines
+ "The blame visualization style used by `magit-blame-echo'.
+A symbol that has to be used as the identifier for one of the
+styles defined in `magit-blame-styles'."
+ :package-version '(magit . "2.13.0")
+ :group 'magit-blame
+ :type 'symbol)
+
+(defcustom magit-blame-time-format "%F %H:%M"
+ "Format for time strings in blame headings."
+ :group 'magit-blame
+ :type 'string)
+
+(defcustom magit-blame-read-only t
+ "Whether to initially make the blamed buffer read-only."
+ :package-version '(magit . "2.13.0")
+ :group 'magit-blame
+ :type 'boolean)
+
+(defcustom magit-blame-disable-modes '(fci-mode yascroll-bar-mode)
+ "List of modes not compatible with Magit-Blame mode.
+This modes are turned off when Magit-Blame mode is turned on,
+and then turned on again when turning off the latter."
+ :group 'magit-blame
+ :type '(repeat (symbol :tag "Mode")))
+
+(defcustom magit-blame-mode-lighter " Blame"
+ "The mode-line lighter of the Magit-Blame mode."
+ :group 'magit-blame
+ :type '(choice (const :tag "No lighter" "") string))
+
+(defcustom magit-blame-goto-chunk-hook
+ '(magit-blame-maybe-update-revision-buffer
+ magit-blame-maybe-show-message)
+ "Hook run after point entered another chunk."
+ :package-version '(magit . "2.13.0")
+ :group 'magit-blame
+ :type 'hook
+ :get #'magit-hook-custom-get
+ :options '(magit-blame-maybe-update-revision-buffer
+ magit-blame-maybe-show-message))
+
+;;; Faces
+
+(defface magit-blame-highlight
+ `((((class color) (background light))
+ ,@(and (>= emacs-major-version 27) '(:extend t))
+ :background "grey80"
+ :foreground "black")
+ (((class color) (background dark))
+ ,@(and (>= emacs-major-version 27) '(:extend t))
+ :background "grey25"
+ :foreground "white"))
+ "Face used for highlighting when blaming.
+Also see option `magit-blame-styles'."
+ :group 'magit-faces)
+
+(defface magit-blame-margin
+ '((t :inherit magit-blame-highlight
+ :weight normal
+ :slant normal))
+ "Face used for the blame margin by default when blaming.
+Also see option `magit-blame-styles'."
+ :group 'magit-faces)
+
+(defface magit-blame-dimmed
+ '((t :inherit magit-dimmed
+ :weight normal
+ :slant normal))
+ "Face used for the blame margin in some cases when blaming.
+Also see option `magit-blame-styles'."
+ :group 'magit-faces)
+
+(defface magit-blame-heading
+ `((t ,@(and (>= emacs-major-version 27) '(:extend t))
+ :inherit magit-blame-highlight
+ :weight normal
+ :slant normal))
+ "Face used for blame headings by default when blaming.
+Also see option `magit-blame-styles'."
+ :group 'magit-faces)
+
+(defface magit-blame-summary '((t nil))
+ "Face used for commit summaries when blaming."
+ :group 'magit-faces)
+
+(defface magit-blame-hash '((t nil))
+ "Face used for commit hashes when blaming."
+ :group 'magit-faces)
+
+(defface magit-blame-name '((t nil))
+ "Face used for author and committer names when blaming."
+ :group 'magit-faces)
+
+(defface magit-blame-date '((t nil))
+ "Face used for dates when blaming."
+ :group 'magit-faces)
+
+;;; Chunks
+
+(defclass magit-blame-chunk ()
+ (;; <orig-rev> <orig-line> <final-line> <num-lines>
+ (orig-rev :initarg :orig-rev)
+ (orig-line :initarg :orig-line)
+ (final-line :initarg :final-line)
+ (num-lines :initarg :num-lines)
+ ;; previous <prev-rev> <prev-file>
+ (prev-rev :initform nil)
+ (prev-file :initform nil)
+ ;; filename <orig-file>
+ (orig-file)))
+
+(defun magit-current-blame-chunk (&optional type noerror)
+ (or (and (not (and type (not (eq type magit-blame-type))))
+ (magit-blame-chunk-at (point)))
+ (and type
+ (let ((rev (or magit-buffer-refname magit-buffer-revision))
+ (file (and (not (derived-mode-p 'dired-mode))
+ (magit-file-relative-name
+ nil (not magit-buffer-file-name))))
+ (line (format "%i,+1" (line-number-at-pos))))
+ (cond (file (with-temp-buffer
+ (magit-with-toplevel
+ (magit-git-insert
+ "blame" "--porcelain"
+ (if (memq magit-blame-type '(final removal))
+ (cons "--reverse" (magit-blame-arguments))
+ (magit-blame-arguments))
+ "-L" line rev "--" file)
+ (goto-char (point-min))
+ (if (eobp)
+ (unless noerror
+ (error "Cannot get blame chunk at eob"))
+ (car (magit-blame--parse-chunk type))))))
+ (noerror nil)
+ (t (error "Buffer does not visit a tracked file")))))))
+
+(defun magit-blame-chunk-at (pos)
+ (--some (overlay-get it 'magit-blame-chunk)
+ (overlays-at pos)))
+
+(defun magit-blame--overlay-at (&optional pos key)
+ (unless pos
+ (setq pos (point)))
+ (--first (overlay-get it (or key 'magit-blame-chunk))
+ (nconc (overlays-at pos)
+ (overlays-in pos pos))))
+
+;;; Keymaps
+
+(defvar magit-blame-mode-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map (kbd "C-c C-q") 'magit-blame-quit)
+ map)
+ "Keymap for `magit-blame-mode'.
+Note that most blaming key bindings are defined
+in `magit-blame-read-only-mode-map' instead.")
+
+(defvar magit-blame-read-only-mode-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map (kbd "C-m") #'magit-show-commit)
+ (define-key map (kbd "p") #'magit-blame-previous-chunk)
+ (define-key map (kbd "P") #'magit-blame-previous-chunk-same-commit)
+ (define-key map (kbd "n") #'magit-blame-next-chunk)
+ (define-key map (kbd "N") #'magit-blame-next-chunk-same-commit)
+ (define-key map (kbd "b") #'magit-blame-addition)
+ (define-key map (kbd "r") #'magit-blame-removal)
+ (define-key map (kbd "f") #'magit-blame-reverse)
+ (define-key map (kbd "B") #'magit-blame)
+ (define-key map (kbd "c") #'magit-blame-cycle-style)
+ (define-key map (kbd "q") #'magit-blame-quit)
+ (define-key map (kbd "M-w") #'magit-blame-copy-hash)
+ (define-key map (kbd "SPC") #'magit-diff-show-or-scroll-up)
+ (define-key map (kbd "S-SPC") #'magit-diff-show-or-scroll-down)
+ (define-key map (kbd "DEL") #'magit-diff-show-or-scroll-down)
+ map)
+ "Keymap for `magit-blame-read-only-mode'.")
+
+;;; Modes
+;;;; Variables
+
+(defvar-local magit-blame-buffer-read-only nil)
+(defvar-local magit-blame-cache nil)
+(defvar-local magit-blame-disabled-modes nil)
+(defvar-local magit-blame-process nil)
+(defvar-local magit-blame-recursive-p nil)
+(defvar-local magit-blame-type nil)
+(defvar-local magit-blame-separator nil)
+(defvar-local magit-blame-previous-chunk nil)
+
+(defvar-local magit-blame--make-margin-overlays nil)
+(defvar-local magit-blame--style nil)
+
+(defsubst magit-blame--style-get (key)
+ (cdr (assoc key (cdr magit-blame--style))))
+
+;;;; Base Mode
+
+(define-minor-mode magit-blame-mode
+ "Display blame information inline."
+ :lighter magit-blame-mode-lighter
+ (cond (magit-blame-mode
+ (when (called-interactively-p 'any)
+ (setq magit-blame-mode nil)
+ (user-error
+ (concat "Don't call `magit-blame-mode' directly; "
+ "instead use `magit-blame'")))
+ (add-hook 'after-save-hook #'magit-blame--refresh t t)
+ (add-hook 'post-command-hook #'magit-blame-goto-chunk-hook t t)
+ (add-hook 'before-revert-hook #'magit-blame--remove-overlays t t)
+ (add-hook 'after-revert-hook #'magit-blame--refresh t t)
+ (add-hook 'read-only-mode-hook #'magit-blame-toggle-read-only t t)
+ (setq magit-blame-buffer-read-only buffer-read-only)
+ (when (or magit-blame-read-only magit-buffer-file-name)
+ (read-only-mode 1))
+ (dolist (mode magit-blame-disable-modes)
+ (when (and (boundp mode) (symbol-value mode))
+ (funcall mode -1)
+ (push mode magit-blame-disabled-modes)))
+ (setq magit-blame-separator (magit-blame--format-separator))
+ (unless magit-blame--style
+ (setq magit-blame--style (car magit-blame-styles)))
+ (setq magit-blame--make-margin-overlays
+ (and (cl-find-if (lambda (style)
+ (assq 'margin-format (cdr style)))
+ magit-blame-styles)))
+ (magit-blame--update-margin))
+ (t
+ (when (process-live-p magit-blame-process)
+ (kill-process magit-blame-process)
+ (while magit-blame-process
+ (sit-for 0.01))) ; avoid racing the sentinel
+ (remove-hook 'after-save-hook #'magit-blame--refresh t)
+ (remove-hook 'post-command-hook #'magit-blame-goto-chunk-hook t)
+ (remove-hook 'before-revert-hook #'magit-blame--remove-overlays t)
+ (remove-hook 'after-revert-hook #'magit-blame--refresh t)
+ (remove-hook 'read-only-mode-hook #'magit-blame-toggle-read-only t)
+ (unless magit-blame-buffer-read-only
+ (read-only-mode -1))
+ (magit-blame-read-only-mode -1)
+ (dolist (mode magit-blame-disabled-modes)
+ (funcall mode 1))
+ (kill-local-variable 'magit-blame-disabled-modes)
+ (kill-local-variable 'magit-blame-type)
+ (kill-local-variable 'magit-blame--style)
+ (magit-blame--update-margin)
+ (magit-blame--remove-overlays))))
+
+(defun magit-blame--refresh ()
+ (magit-blame--run (magit-blame-arguments)))
+
+(defun magit-blame-goto-chunk-hook ()
+ (let ((chunk (magit-blame-chunk-at (point))))
+ (when (cl-typep chunk 'magit-blame-chunk)
+ (unless (eq chunk magit-blame-previous-chunk)
+ (run-hooks 'magit-blame-goto-chunk-hook))
+ (setq magit-blame-previous-chunk chunk))))
+
+(defun magit-blame-toggle-read-only ()
+ (magit-blame-read-only-mode (if buffer-read-only 1 -1)))
+
+;;;; Read-Only Mode
+
+(define-minor-mode magit-blame-read-only-mode
+ "Provide keybindings for Magit-Blame mode.
+
+This minor-mode provides the key bindings for Magit-Blame mode,
+but only when Read-Only mode is also enabled because these key
+bindings would otherwise conflict badly with regular bindings.
+
+When both Magit-Blame mode and Read-Only mode are enabled, then
+this mode gets automatically enabled too and when one of these
+modes is toggled, then this mode also gets toggled automatically.
+
+\\{magit-blame-read-only-mode-map}")
+
+;;;; Kludges
+
+(defun magit-blame-put-keymap-before-view-mode ()
+ "Put `magit-blame-read-only-mode' ahead of `view-mode' in `minor-mode-map-alist'."
+ (--when-let (assq 'magit-blame-read-only-mode
+ (cl-member 'view-mode minor-mode-map-alist :key #'car))
+ (setq minor-mode-map-alist
+ (cons it (delq it minor-mode-map-alist))))
+ (remove-hook 'view-mode-hook #'magit-blame-put-keymap-before-view-mode))
+
+(add-hook 'view-mode-hook #'magit-blame-put-keymap-before-view-mode)
+
+;;; Process
+
+(defun magit-blame--run (args)
+ (magit-with-toplevel
+ (unless magit-blame-mode
+ (magit-blame-mode 1))
+ (message "Blaming...")
+ (magit-blame-run-process
+ (or magit-buffer-refname magit-buffer-revision)
+ (magit-file-relative-name nil (not magit-buffer-file-name))
+ (if (memq magit-blame-type '(final removal))
+ (cons "--reverse" args)
+ args)
+ (list (line-number-at-pos (window-start))
+ (line-number-at-pos (1- (window-end nil t)))))
+ (set-process-sentinel magit-this-process
+ #'magit-blame-process-quickstart-sentinel)))
+
+(defun magit-blame-run-process (revision file args &optional lines)
+ (let ((process (magit-parse-git-async
+ "blame" "--incremental" args
+ (and lines (list "-L" (apply #'format "%s,%s" lines)))
+ revision "--" file)))
+ (set-process-filter process #'magit-blame-process-filter)
+ (set-process-sentinel process #'magit-blame-process-sentinel)
+ (process-put process 'arguments (list revision file args))
+ (setq magit-blame-cache (make-hash-table :test #'equal))
+ (setq magit-blame-process process)))
+
+(defun magit-blame-process-quickstart-sentinel (process event)
+ (when (memq (process-status process) '(exit signal))
+ (magit-blame-process-sentinel process event t)
+ (magit-blame-assert-buffer process)
+ (with-current-buffer (process-get process 'command-buf)
+ (when magit-blame-mode
+ (let ((default-directory (magit-toplevel)))
+ (apply #'magit-blame-run-process
+ (process-get process 'arguments)))))))
+
+(defun magit-blame-process-sentinel (process _event &optional quiet)
+ (let ((status (process-status process)))
+ (when (memq status '(exit signal))
+ (kill-buffer (process-buffer process))
+ (if (and (eq status 'exit)
+ (zerop (process-exit-status process)))
+ (unless quiet
+ (message "Blaming...done"))
+ (magit-blame-assert-buffer process)
+ (with-current-buffer (process-get process 'command-buf)
+ (if magit-blame-mode
+ (progn (magit-blame-mode -1)
+ (message "Blaming...failed"))
+ (message "Blaming...aborted"))))
+ (kill-local-variable 'magit-blame-process))))
+
+(defun magit-blame-process-filter (process string)
+ (internal-default-process-filter process string)
+ (let ((buf (process-get process 'command-buf))
+ (pos (process-get process 'parsed))
+ (mark (process-mark process))
+ type cache)
+ (with-current-buffer buf
+ (setq type magit-blame-type)
+ (setq cache magit-blame-cache))
+ (with-current-buffer (process-buffer process)
+ (goto-char pos)
+ (while (and (< (point) mark)
+ (save-excursion (re-search-forward "^filename .+\n" nil t)))
+ (pcase-let* ((`(,chunk ,revinfo)
+ (magit-blame--parse-chunk type))
+ (rev (oref chunk orig-rev)))
+ (if revinfo
+ (puthash rev revinfo cache)
+ (setq revinfo
+ (or (gethash rev cache)
+ (puthash rev (magit-blame--commit-alist rev) cache))))
+ (magit-blame--make-overlays buf chunk revinfo))
+ (process-put process 'parsed (point))))))
+
+(defun magit-blame--parse-chunk (type)
+ (let (chunk revinfo)
+ (unless (looking-at "^\\(.\\{40,\\}\\) \\([0-9]+\\) \\([0-9]+\\) \\([0-9]+\\)")
+ (error "Blaming failed due to unexpected output: %s"
+ (buffer-substring-no-properties (point) (line-end-position))))
+ (with-slots (orig-rev orig-file prev-rev prev-file)
+ (setq chunk (magit-blame-chunk
+ :orig-rev (match-string 1)
+ :orig-line (string-to-number (match-string 2))
+ :final-line (string-to-number (match-string 3))
+ :num-lines (string-to-number (match-string 4))))
+ (forward-line)
+ (let (done)
+ (while (not done)
+ (cond ((looking-at "^filename \\(.+\\)")
+ (setq done t)
+ (setf orig-file (magit-decode-git-path (match-string 1))))
+ ((looking-at "^previous \\(.\\{40,\\}\\) \\(.+\\)")
+ (setf prev-rev (match-string 1))
+ (setf prev-file (magit-decode-git-path (match-string 2))))
+ ((looking-at "^\\([^ ]+\\) \\(.+\\)")
+ (push (cons (match-string 1)
+ (match-string 2)) revinfo)))
+ (forward-line)))
+ (when (and (eq type 'removal) prev-rev)
+ (cl-rotatef orig-rev prev-rev)
+ (cl-rotatef orig-file prev-file)
+ (setq revinfo nil)))
+ (list chunk revinfo)))
+
+(defun magit-blame--commit-alist (rev)
+ (cl-mapcar 'cons
+ '("summary"
+ "author" "author-time" "author-tz"
+ "committer" "committer-time" "committer-tz")
+ (split-string (magit-rev-format "%s\v%an\v%ad\v%cn\v%cd" rev
+ "--date=format:%s\v%z")
+ "\v")))
+
+(defun magit-blame-assert-buffer (process)
+ (unless (buffer-live-p (process-get process 'command-buf))
+ (kill-process process)
+ (user-error "Buffer being blamed has been killed")))
+
+;;; Display
+
+(defun magit-blame--make-overlays (buf chunk revinfo)
+ (with-current-buffer buf
+ (save-excursion
+ (save-restriction
+ (widen)
+ (let* ((line (oref chunk final-line))
+ (beg (magit-blame--line-beginning-position line))
+ (end (magit-blame--line-beginning-position
+ (+ line (oref chunk num-lines))))
+ (before (magit-blame-chunk-at (1- beg))))
+ (when (and before
+ (equal (oref before orig-rev)
+ (oref chunk orig-rev)))
+ (setq beg (magit-blame--line-beginning-position
+ (oset chunk final-line (oref before final-line))))
+ (cl-incf (oref chunk num-lines)
+ (oref before num-lines)))
+ (magit-blame--remove-overlays beg end)
+ (when magit-blame--make-margin-overlays
+ (magit-blame--make-margin-overlays chunk revinfo beg end))
+ (magit-blame--make-heading-overlay chunk revinfo beg end)
+ (magit-blame--make-highlight-overlay chunk beg))))))
+
+(defun magit-blame--line-beginning-position (line)
+ (save-excursion
+ (goto-char (point-min))
+ (forward-line (1- line))
+ (point)))
+
+(defun magit-blame--make-margin-overlays (chunk revinfo _beg end)
+ (save-excursion
+ (let ((line 0))
+ (while (< (point) end)
+ (magit-blame--make-margin-overlay chunk revinfo line)
+ (forward-line)
+ (cl-incf line)))))
+
+(defun magit-blame--make-margin-overlay (chunk revinfo line)
+ (let* ((end (line-end-position))
+ ;; If possible avoid putting this on the first character
+ ;; of the line to avoid a conflict with the line overlay.
+ (beg (min (1+ (line-beginning-position)) end))
+ (ov (make-overlay beg end)))
+ (overlay-put ov 'magit-blame-chunk chunk)
+ (overlay-put ov 'magit-blame-revinfo revinfo)
+ (overlay-put ov 'magit-blame-margin line)
+ (magit-blame--update-margin-overlay ov)))
+
+(defun magit-blame--make-heading-overlay (chunk revinfo beg end)
+ (let ((ov (make-overlay beg end)))
+ (overlay-put ov 'magit-blame-chunk chunk)
+ (overlay-put ov 'magit-blame-revinfo revinfo)
+ (overlay-put ov 'magit-blame-heading t)
+ (magit-blame--update-heading-overlay ov)))
+
+(defun magit-blame--make-highlight-overlay (chunk beg)
+ (let ((ov (make-overlay beg (save-excursion
+ (goto-char beg)
+ (1+ (line-end-position))))))
+ (overlay-put ov 'magit-blame-chunk chunk)
+ (overlay-put ov 'magit-blame-highlight t)
+ (magit-blame--update-highlight-overlay ov)))
+
+(defun magit-blame--update-margin ()
+ (setq left-margin-width (or (magit-blame--style-get 'margin-width) 0))
+ (set-window-buffer (selected-window) (current-buffer)))
+
+(defun magit-blame--update-overlays ()
+ (save-restriction
+ (widen)
+ (dolist (ov (overlays-in (point-min) (point-max)))
+ (cond ((overlay-get ov 'magit-blame-heading)
+ (magit-blame--update-heading-overlay ov))
+ ((overlay-get ov 'magit-blame-margin)
+ (magit-blame--update-margin-overlay ov))
+ ((overlay-get ov 'magit-blame-highlight)
+ (magit-blame--update-highlight-overlay ov))))))
+
+(defun magit-blame--update-margin-overlay (ov)
+ (overlay-put
+ ov 'before-string
+ (and (magit-blame--style-get 'margin-width)
+ (propertize
+ "o" 'display
+ (list (list 'margin 'left-margin)
+ (let ((line (overlay-get ov 'magit-blame-margin))
+ (format (magit-blame--style-get 'margin-format))
+ (face (magit-blame--style-get 'margin-face)))
+ (magit-blame--format-string
+ ov
+ (or (and (atom format)
+ format)
+ (nth line format)
+ (car (last format)))
+ (or (and (not (zerop line))
+ (magit-blame--style-get 'margin-body-face))
+ face
+ 'magit-blame-margin))))))))
+
+(defun magit-blame--update-heading-overlay (ov)
+ (overlay-put
+ ov 'before-string
+ (--if-let (magit-blame--style-get 'heading-format)
+ (magit-blame--format-string ov it 'magit-blame-heading)
+ (and (magit-blame--style-get 'show-lines)
+ (or (not (magit-blame--style-get 'margin-format))
+ (save-excursion
+ (goto-char (overlay-start ov))
+ ;; Special case of the special case described in
+ ;; `magit-blame--make-margin-overlay'. For empty
+ ;; lines it is not possible to show both overlays
+ ;; without the line being to high.
+ (not (= (point) (line-end-position)))))
+ magit-blame-separator))))
+
+(defun magit-blame--update-highlight-overlay (ov)
+ (overlay-put ov 'font-lock-face (magit-blame--style-get 'highlight-face)))
+
+(defun magit-blame--format-string (ov format face)
+ (let* ((chunk (overlay-get ov 'magit-blame-chunk))
+ (revinfo (overlay-get ov 'magit-blame-revinfo))
+ (key (list format face))
+ (string (cdr (assoc key revinfo))))
+ (unless string
+ (setq string
+ (and format
+ (magit-blame--format-string-1 (oref chunk orig-rev)
+ revinfo format face)))
+ (nconc revinfo (list (cons key string))))
+ string))
+
+(defun magit-blame--format-string-1 (rev revinfo format face)
+ (let ((str
+ (if (string-match-p "\\`0\\{40,\\}\\'" rev)
+ (propertize (concat (if (string-prefix-p "\s" format) "\s" "")
+ "Not Yet Committed"
+ (if (string-suffix-p "\n" format) "\n" ""))
+ 'font-lock-face face)
+ (magit--format-spec
+ (propertize format 'font-lock-face face)
+ (cl-flet* ((p0 (s f)
+ (propertize s 'font-lock-face
+ (if face
+ (if (listp face)
+ face
+ (list f face))
+ f)))
+ (p1 (k f)
+ (p0 (cdr (assoc k revinfo)) f))
+ (p2 (k1 k2 f)
+ (p0 (magit-blame--format-time-string
+ (cdr (assoc k1 revinfo))
+ (cdr (assoc k2 revinfo)))
+ f)))
+ `((?H . ,(p0 rev 'magit-blame-hash))
+ (?s . ,(p1 "summary" 'magit-blame-summary))
+ (?a . ,(p1 "author" 'magit-blame-name))
+ (?c . ,(p1 "committer" 'magit-blame-name))
+ (?A . ,(p2 "author-time" "author-tz" 'magit-blame-date))
+ (?C . ,(p2 "committer-time" "committer-tz" 'magit-blame-date))
+ (?f . "")))))))
+ (if-let ((width (and (string-suffix-p "%f" format)
+ (magit-blame--style-get 'margin-width))))
+ (concat str
+ (propertize (make-string (max 0 (- width (length str))) ?\s)
+ 'font-lock-face face))
+ str)))
+
+(defun magit-blame--format-separator ()
+ (propertize
+ (concat (propertize "\s" 'display '(space :height (2)))
+ (propertize "\n" 'line-height t))
+ 'font-lock-face `(:background
+ ,(face-attribute 'magit-blame-heading
+ :background nil t)
+ ,@(and (>= emacs-major-version 27) '(:extend t)))))
+
+(defun magit-blame--format-time-string (time tz)
+ (let* ((time-format (or (magit-blame--style-get 'time-format)
+ magit-blame-time-format))
+ (tz-in-second (and (string-search "%z" time-format)
+ (car (last (parse-time-string tz))))))
+ (format-time-string time-format
+ (seconds-to-time (string-to-number time))
+ tz-in-second)))
+
+(defun magit-blame--remove-overlays (&optional beg end)
+ (save-restriction
+ (widen)
+ (dolist (ov (overlays-in (or beg (point-min))
+ (or end (point-max))))
+ (when (overlay-get ov 'magit-blame-chunk)
+ (delete-overlay ov)))))
+
+(defun magit-blame-maybe-show-message ()
+ (when (magit-blame--style-get 'show-message)
+ (let ((message-log-max 0))
+ (if-let ((msg (cdr (assoc "summary"
+ (gethash (oref (magit-current-blame-chunk)
+ orig-rev)
+ magit-blame-cache)))))
+ (progn (set-text-properties 0 (length msg) nil msg)
+ (message msg))
+ (message "Commit data not available yet. Still blaming.")))))
+
+;;; Commands
+
+;;;###autoload (autoload 'magit-blame-echo "magit-blame" nil t)
+(transient-define-suffix magit-blame-echo (args)
+ "For each line show the revision in which it was added.
+Show the information about the chunk at point in the echo area
+when moving between chunks. Unlike other blaming commands, do
+not turn on `read-only-mode'."
+ :if (lambda ()
+ (and buffer-file-name
+ (or (not magit-blame-mode)
+ buffer-read-only)))
+ (interactive (list (magit-blame-arguments)))
+ (when magit-buffer-file-name
+ (user-error "Blob buffers aren't supported"))
+ (setq-local magit-blame--style
+ (assq magit-blame-echo-style magit-blame-styles))
+ (setq-local magit-blame-disable-modes
+ (cons 'eldoc-mode magit-blame-disable-modes))
+ (if (not magit-blame-mode)
+ (let ((magit-blame-read-only nil))
+ (magit-blame--pre-blame-assert 'addition)
+ (magit-blame--pre-blame-setup 'addition)
+ (magit-blame--run args))
+ (read-only-mode -1)
+ (magit-blame--update-overlays)))
+
+;;;###autoload (autoload 'magit-blame-addition "magit-blame" nil t)
+(transient-define-suffix magit-blame-addition (args)
+ "For each line show the revision in which it was added."
+ (interactive (list (magit-blame-arguments)))
+ (magit-blame--pre-blame-assert 'addition)
+ (magit-blame--pre-blame-setup 'addition)
+ (magit-blame--run args))
+
+;;;###autoload (autoload 'magit-blame-removal "magit-blame" nil t)
+(transient-define-suffix magit-blame-removal (args)
+ "For each line show the revision in which it was removed."
+ :if-nil 'buffer-file-name
+ (interactive (list (magit-blame-arguments)))
+ (unless magit-buffer-file-name
+ (user-error "Only blob buffers can be blamed in reverse"))
+ (magit-blame--pre-blame-assert 'removal)
+ (magit-blame--pre-blame-setup 'removal)
+ (magit-blame--run args))
+
+;;;###autoload (autoload 'magit-blame-reverse "magit-blame" nil t)
+(transient-define-suffix magit-blame-reverse (args)
+ "For each line show the last revision in which it still exists."
+ :if-nil 'buffer-file-name
+ (interactive (list (magit-blame-arguments)))
+ (unless magit-buffer-file-name
+ (user-error "Only blob buffers can be blamed in reverse"))
+ (magit-blame--pre-blame-assert 'final)
+ (magit-blame--pre-blame-setup 'final)
+ (magit-blame--run args))
+
+(defun magit-blame--pre-blame-assert (type)
+ (unless (magit-toplevel)
+ (magit--not-inside-repository-error))
+ (if (and magit-blame-mode
+ (eq type magit-blame-type))
+ (if-let ((chunk (magit-current-blame-chunk)))
+ (unless (oref chunk prev-rev)
+ (user-error "Chunk has no further history"))
+ (user-error "Commit data not available yet. Still blaming."))
+ (unless (magit-file-relative-name nil (not magit-buffer-file-name))
+ (if buffer-file-name
+ (user-error "Buffer isn't visiting a tracked file")
+ (user-error "Buffer isn't visiting a file")))))
+
+(defun magit-blame--pre-blame-setup (type)
+ (when magit-blame-mode
+ (if (eq type magit-blame-type)
+ (let ((style magit-blame--style))
+ (magit-blame-visit-other-file)
+ (setq-local magit-blame--style style)
+ (setq-local magit-blame-recursive-p t)
+ ;; Set window-start for the benefit of quickstart.
+ (redisplay))
+ (magit-blame--remove-overlays)))
+ (setq magit-blame-type type))
+
+(defun magit-blame-visit-other-file ()
+ "Visit another blob related to the current chunk."
+ (interactive)
+ (with-slots (prev-rev prev-file orig-line)
+ (magit-current-blame-chunk)
+ (unless prev-rev
+ (user-error "Chunk has no further history"))
+ (magit-with-toplevel
+ (magit-find-file prev-rev prev-file))
+ ;; TODO Adjust line like magit-diff-visit-file.
+ (goto-char (point-min))
+ (forward-line (1- orig-line))))
+
+(defun magit-blame-visit-file ()
+ "Visit the blob related to the current chunk."
+ (interactive)
+ (with-slots (orig-rev orig-file orig-line)
+ (magit-current-blame-chunk)
+ (magit-with-toplevel
+ (magit-find-file orig-rev orig-file))
+ (goto-char (point-min))
+ (forward-line (1- orig-line))))
+
+(transient-define-suffix magit-blame-quit ()
+ "Turn off Magit-Blame mode.
+If the buffer was created during a recursive blame,
+then also kill the buffer."
+ :if-non-nil 'magit-blame-mode
+ (interactive)
+ (magit-blame-mode -1)
+ (when magit-blame-recursive-p
+ (kill-buffer)))
+
+(defun magit-blame-next-chunk ()
+ "Move to the next chunk."
+ (interactive)
+ (--if-let (next-single-char-property-change (point) 'magit-blame-chunk)
+ (goto-char it)
+ (user-error "No more chunks")))
+
+(defun magit-blame-previous-chunk ()
+ "Move to the previous chunk."
+ (interactive)
+ (--if-let (previous-single-char-property-change (point) 'magit-blame-chunk)
+ (goto-char it)
+ (user-error "No more chunks")))
+
+(defun magit-blame-next-chunk-same-commit (&optional previous)
+ "Move to the next chunk from the same commit.\n\n(fn)"
+ (interactive)
+ (if-let ((rev (oref (magit-current-blame-chunk) orig-rev)))
+ (let ((pos (point)) ov)
+ (save-excursion
+ (while (and (not ov)
+ (not (= pos (if previous (point-min) (point-max))))
+ (setq pos (funcall
+ (if previous
+ #'previous-single-char-property-change
+ #'next-single-char-property-change)
+ pos 'magit-blame-chunk)))
+ (--when-let (magit-blame--overlay-at pos)
+ (when (equal (oref (magit-blame-chunk-at pos) orig-rev) rev)
+ (setq ov it)))))
+ (if ov
+ (goto-char (overlay-start ov))
+ (user-error "No more chunks from same commit")))
+ (user-error "This chunk hasn't been blamed yet")))
+
+(defun magit-blame-previous-chunk-same-commit ()
+ "Move to the previous chunk from the same commit."
+ (interactive)
+ (magit-blame-next-chunk-same-commit #'previous-single-char-property-change))
+
+(defun magit-blame-cycle-style ()
+ "Change how blame information is visualized.
+Cycle through the elements of option `magit-blame-styles'."
+ (interactive)
+ (setq magit-blame--style
+ (or (cadr (cl-member (car magit-blame--style)
+ magit-blame-styles :key #'car))
+ (car magit-blame-styles)))
+ (magit-blame--update-margin)
+ (magit-blame--update-overlays))
+
+(defun magit-blame-copy-hash ()
+ "Save hash of the current chunk's commit to the kill ring.
+
+When the region is active, then save the region's content
+instead of the hash, like `kill-ring-save' would."
+ (interactive)
+ (if (use-region-p)
+ (call-interactively #'copy-region-as-kill)
+ (kill-new (message "%s" (oref (magit-current-blame-chunk) orig-rev)))))
+
+;;; Popup
+
+;;;###autoload (autoload 'magit-blame "magit-blame" nil t)
+(transient-define-prefix magit-blame ()
+ "Show the commits that added or removed lines in the visited file."
+ :man-page "git-blame"
+ :value '("-w")
+ ["Arguments"
+ ("-w" "Ignore whitespace" "-w")
+ ("-r" "Do not treat root commits as boundaries" "--root")
+ ("-P" "Follow only first parent" "--first-parent")
+ (magit-blame:-M)
+ (magit-blame:-C)]
+ ["Actions"
+ ("b" "Show commits adding lines" magit-blame-addition)
+ ("r" "Show commits removing lines" magit-blame-removal)
+ ("f" "Show last commits that still have lines" magit-blame-reverse)
+ ("m" "Blame echo" magit-blame-echo)
+ ("q" "Quit blaming" magit-blame-quit)]
+ ["Refresh"
+ :if-non-nil magit-blame-mode
+ ("c" "Cycle style" magit-blame-cycle-style :transient t)])
+
+(defun magit-blame-arguments ()
+ (transient-args 'magit-blame))
+
+(transient-define-argument magit-blame:-M ()
+ :description "Detect lines moved or copied within a file"
+ :class 'transient-option
+ :argument "-M"
+ :allow-empty t
+ :reader #'transient-read-number-N+)
+
+(transient-define-argument magit-blame:-C ()
+ :description "Detect lines moved or copied between files"
+ :class 'transient-option
+ :argument "-C"
+ :allow-empty t
+ :reader #'transient-read-number-N+)
+
+;;; Utilities
+
+(defun magit-blame-maybe-update-revision-buffer ()
+ (when-let* ((chunk (magit-current-blame-chunk))
+ (commit (oref chunk orig-rev))
+ (buffer (magit-get-mode-buffer 'magit-revision-mode nil t)))
+ (if magit--update-revision-buffer
+ (setq magit--update-revision-buffer (list commit buffer))
+ (setq magit--update-revision-buffer (list commit buffer))
+ (run-with-idle-timer
+ magit-update-other-window-delay nil
+ (lambda ()
+ (pcase-let ((`(,rev ,buf) magit--update-revision-buffer))
+ (setq magit--update-revision-buffer nil)
+ (when (buffer-live-p buf)
+ (let ((magit-display-buffer-noselect t))
+ (apply #'magit-show-commit rev
+ (magit-diff-arguments 'magit-revision-mode))))))))))
+
+;;; _
+(provide 'magit-blame)
+;;; magit-blame.el ends here
diff --git a/elpa/magit-20220503.1245/magit-blame.elc b/elpa/magit-20220503.1245/magit-blame.elc
new file mode 100644
index 0000000..796b92a
--- /dev/null
+++ b/elpa/magit-20220503.1245/magit-blame.elc
Binary files differ
diff --git a/elpa/magit-20220503.1245/magit-bookmark.el b/elpa/magit-20220503.1245/magit-bookmark.el
new file mode 100644
index 0000000..0a42741
--- /dev/null
+++ b/elpa/magit-20220503.1245/magit-bookmark.el
@@ -0,0 +1,205 @@
+;;; magit-bookmark.el --- Bookmark support for Magit -*- lexical-binding:t -*-
+
+;; Copyright (C) 2008-2022 The Magit Project Contributors
+
+;; Inspired by an earlier implementation by Yuri Khan.
+
+;; Author: Jonas Bernoulli <jonas@bernoul.li>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+
+;; SPDX-License-Identifier: GPL-3.0-or-later
+
+;; Magit 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.
+;;
+;; Magit 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 Magit. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Support for bookmarks for most Magit buffers.
+
+;;; Code:
+
+(require 'magit)
+(require 'bookmark)
+
+;;; Core
+
+(defun magit--make-bookmark ()
+ "Create a bookmark for the current Magit buffer.
+Input values are the major-mode's `magit-bookmark-name' method,
+and the buffer-local values of the variables referenced in its
+`magit-bookmark-variables' property."
+ (if (plist-member (symbol-plist major-mode) 'magit-bookmark-variables)
+ ;; `bookmark-make-record-default's return value does not match
+ ;; (NAME . ALIST), even though it is used as the default value
+ ;; of `bookmark-make-record-function', which states that such
+ ;; functions must do that. See #4356.
+ (let ((bookmark (cons nil (bookmark-make-record-default 'no-file))))
+ (bookmark-prop-set bookmark 'handler #'magit--handle-bookmark)
+ (bookmark-prop-set bookmark 'mode major-mode)
+ (bookmark-prop-set bookmark 'filename (magit-toplevel))
+ (bookmark-prop-set bookmark 'defaults (list (magit-bookmark-name)))
+ (dolist (var (get major-mode 'magit-bookmark-variables))
+ (bookmark-prop-set bookmark var (symbol-value var)))
+ (bookmark-prop-set
+ bookmark 'magit-hidden-sections
+ (--keep (and (oref it hidden)
+ (cons (oref it type)
+ (if (derived-mode-p 'magit-stash-mode)
+ (string-replace magit-buffer-revision
+ magit-buffer-revision-hash
+ (oref it value))
+ (oref it value))))
+ (oref magit-root-section children)))
+ bookmark)
+ (user-error "Bookmarking is not implemented for %s buffers" major-mode)))
+
+;;;###autoload
+(defun magit--handle-bookmark (bookmark)
+ "Open a bookmark created by `magit--make-bookmark'.
+Call the `magit-*-setup-buffer' function of the the major-mode
+with the variables' values as arguments, which were recorded by
+`magit--make-bookmark'. Ignore `magit-display-buffer-function'."
+ (let ((buffer (let ((default-directory (bookmark-get-filename bookmark))
+ (mode (bookmark-prop-get bookmark 'mode))
+ (magit-display-buffer-function #'identity)
+ (magit-display-buffer-noselect t))
+ (apply (intern (format "%s-setup-buffer"
+ (substring (symbol-name mode) 0 -5)))
+ (--map (bookmark-prop-get bookmark it)
+ (get mode 'magit-bookmark-variables))))))
+ (set-buffer buffer) ; That is the interface we have to adhere to.
+ (when-let ((hidden (bookmark-prop-get bookmark 'magit-hidden-sections)))
+ (with-current-buffer buffer
+ (dolist (child (oref magit-root-section children))
+ (if (member (cons (oref child type)
+ (oref child value))
+ hidden)
+ (magit-section-hide child)
+ (magit-section-show child)))))
+ ;; Compatibility with `bookmark+' package. See #4356.
+ (when (bound-and-true-p bmkp-jump-display-function)
+ (funcall bmkp-jump-display-function (current-buffer)))
+ nil))
+
+(cl-defgeneric magit-bookmark-name ()
+ "Return name for bookmark to current buffer."
+ (format "%s%s"
+ (substring (symbol-name major-mode) 0 -5)
+ (if-let ((vars (get major-mode 'magit-bookmark-variables)))
+ (cl-mapcan (lambda (var)
+ (let ((val (symbol-value var)))
+ (if (and val (atom val))
+ (list val)
+ val)))
+ vars)
+ "")))
+
+;;; Diff
+;;;; Diff
+
+(put 'magit-diff-mode 'magit-bookmark-variables
+ '(magit-buffer-range-hashed
+ magit-buffer-typearg
+ magit-buffer-diff-args
+ magit-buffer-diff-files))
+
+(cl-defmethod magit-bookmark-name (&context (major-mode magit-diff-mode))
+ (format "magit-diff(%s%s)"
+ (pcase (magit-diff-type)
+ ('staged "staged")
+ ('unstaged "unstaged")
+ ('committed magit-buffer-range)
+ ('undefined
+ (delq nil (list magit-buffer-typearg magit-buffer-range-hashed))))
+ (if magit-buffer-diff-files
+ (concat " -- " (mapconcat #'identity magit-buffer-diff-files " "))
+ "")))
+
+;;;; Revision
+
+(put 'magit-revision-mode 'magit-bookmark-variables
+ '(magit-buffer-revision-hash
+ magit-buffer-diff-args
+ magit-buffer-diff-files))
+
+(cl-defmethod magit-bookmark-name (&context (major-mode magit-revision-mode))
+ (format "magit-revision(%s %s)"
+ (magit-rev-abbrev magit-buffer-revision)
+ (if magit-buffer-diff-files
+ (mapconcat #'identity magit-buffer-diff-files " ")
+ (magit-rev-format "%s" magit-buffer-revision))))
+
+;;;; Stash
+
+(put 'magit-stash-mode 'magit-bookmark-variables
+ '(magit-buffer-revision-hash
+ magit-buffer-diff-args
+ magit-buffer-diff-files))
+
+(cl-defmethod magit-bookmark-name (&context (major-mode magit-stash-mode))
+ (format "magit-stash(%s %s)"
+ (magit-rev-abbrev magit-buffer-revision)
+ (if magit-buffer-diff-files
+ (mapconcat #'identity magit-buffer-diff-files " ")
+ (magit-rev-format "%s" magit-buffer-revision))))
+
+;;; Log
+;;;; Log
+
+(put 'magit-log-mode 'magit-bookmark-variables
+ '(magit-buffer-revisions
+ magit-buffer-log-args
+ magit-buffer-log-files))
+
+(cl-defmethod magit-bookmark-name (&context (major-mode magit-log-mode))
+ (format "magit-log(%s%s)"
+ (mapconcat #'identity magit-buffer-revisions " ")
+ (if magit-buffer-log-files
+ (concat " -- " (mapconcat #'identity magit-buffer-log-files " "))
+ "")))
+
+;;;; Cherry
+
+(put 'magit-cherry-mode 'magit-bookmark-variables
+ '(magit-buffer-refname
+ magit-buffer-upstream))
+
+(cl-defmethod magit-bookmark-name (&context (major-mode magit-cherry-mode))
+ (format "magit-cherry(%s > %s)"
+ magit-buffer-refname
+ magit-buffer-upstream))
+
+;;;; Reflog
+
+(put 'magit-reflog-mode 'magit-bookmark-variables
+ '(magit-buffer-refname))
+
+(cl-defmethod magit-bookmark-name (&context (major-mode magit-reflog-mode))
+ (format "magit-reflog(%s)" magit-buffer-refname))
+
+;;; Misc
+
+(put 'magit-status-mode 'magit-bookmark-variables nil)
+
+(put 'magit-refs-mode 'magit-bookmark-variables
+ '(magit-buffer-upstream
+ magit-buffer-arguments))
+
+(put 'magit-stashes-mode 'magit-bookmark-variables nil)
+
+(cl-defmethod magit-bookmark-name (&context (major-mode magit-stashes-mode))
+ (format "magit-states(%s)" magit-buffer-refname))
+
+;;; _
+(provide 'magit-bookmark)
+;;; magit-bookmark.el ends here
diff --git a/elpa/magit-20220503.1245/magit-bookmark.elc b/elpa/magit-20220503.1245/magit-bookmark.elc
new file mode 100644
index 0000000..39b096a
--- /dev/null
+++ b/elpa/magit-20220503.1245/magit-bookmark.elc
Binary files differ
diff --git a/elpa/magit-20220503.1245/magit-branch.el b/elpa/magit-20220503.1245/magit-branch.el
new file mode 100644
index 0000000..724d4c5
--- /dev/null
+++ b/elpa/magit-20220503.1245/magit-branch.el
@@ -0,0 +1,934 @@
+;;; magit-branch.el --- Branch support -*- lexical-binding:t -*-
+
+;; Copyright (C) 2008-2022 The Magit Project Contributors
+
+;; Author: Jonas Bernoulli <jonas@bernoul.li>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+
+;; SPDX-License-Identifier: GPL-3.0-or-later
+
+;; Magit 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.
+;;
+;; Magit 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 Magit. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This library implements support for branches. It defines commands
+;; for creating, checking out, manipulating, and configuring branches.
+;; Commands defined here are mainly concerned with branches as
+;; pointers, commands that deal with what a branch points at, are
+;; defined elsewhere.
+
+;;; Code:
+
+(require 'magit)
+(require 'magit-reset)
+
+;;; Options
+
+(defcustom magit-branch-read-upstream-first t
+ "Whether to read upstream before name of new branch when creating a branch.
+
+`nil' Read the branch name first.
+`t' Read the upstream first.
+`fallback' Read the upstream first, but if it turns out that the chosen
+ value is not a valid upstream (because it cannot be resolved
+ as an existing revision), then treat it as the name of the
+ new branch and continue by reading the upstream next."
+ :package-version '(magit . "2.2.0")
+ :group 'magit-commands
+ :type '(choice (const :tag "read branch name first" nil)
+ (const :tag "read upstream first" t)
+ (const :tag "read upstream first, with fallback" fallback)))
+
+(defcustom magit-branch-prefer-remote-upstream nil
+ "Whether to favor remote upstreams when creating new branches.
+
+When a new branch is created, then the branch, commit, or stash
+at point is suggested as the default starting point of the new
+branch, or if there is no such revision at point the current
+branch. In either case the user may choose another starting
+point.
+
+If the chosen starting point is a branch, then it may also be set
+as the upstream of the new branch, depending on the value of the
+Git variable `branch.autoSetupMerge'. By default this is done
+for remote branches, but not for local branches.
+
+You might prefer to always use some remote branch as upstream.
+If the chosen starting point is (1) a local branch, (2) whose
+name matches a member of the value of this option, (3) the
+upstream of that local branch is a remote branch with the same
+name, and (4) that remote branch can be fast-forwarded to the
+local branch, then the chosen branch is used as starting point,
+but its own upstream is used as the upstream of the new branch.
+
+Members of this option's value are treated as branch names that
+have to match exactly unless they contain a character that makes
+them invalid as a branch name. Recommended characters to use
+to trigger interpretation as a regexp are \"*\" and \"^\". Some
+other characters which you might expect to be invalid, actually
+are not, e.g. \".+$\" are all perfectly valid. More precisely,
+if `git check-ref-format --branch STRING' exits with a non-zero
+status, then treat STRING as a regexp.
+
+Assuming the chosen branch matches these conditions you would end
+up with with e.g.:
+
+ feature --upstream--> origin/master
+
+instead of
+
+ feature --upstream--> master --upstream--> origin/master
+
+Which you prefer is a matter of personal preference. If you do
+prefer the former, then you should add branches such as \"master\",
+\"next\", and \"maint\" to the value of this options."
+ :package-version '(magit . "2.4.0")
+ :group 'magit-commands
+ :type '(repeat string))
+
+(defcustom magit-branch-adjust-remote-upstream-alist nil
+ "Alist of upstreams to be used when branching from remote branches.
+
+When creating a local branch from an ephemeral branch located
+on a remote, e.g. a feature or hotfix branch, then that remote
+branch should usually not be used as the upstream branch, since
+the push-remote already allows accessing it and having both the
+upstream and the push-remote reference the same related branch
+would be wasteful. Instead a branch like \"maint\" or \"master\"
+should be used as the upstream.
+
+This option allows specifying the branch that should be used as
+the upstream when branching certain remote branches. The value
+is an alist of the form ((UPSTREAM . RULE)...). The first
+element is used whose UPSTREAM exists and whose RULE matches
+the name of the new branch. Subsequent elements are ignored.
+
+UPSTREAM is the branch to be used as the upstream for branches
+specified by RULE. It can be a local or a remote branch.
+
+RULE can either be a regular expression, matching branches whose
+upstream should be the one specified by UPSTREAM. Or it can be
+a list of the only branches that should *not* use UPSTREAM; all
+other branches will. Matching is done after stripping the remote
+part of the name of the branch that is being branched from.
+
+If you use a finite set of non-ephemeral branches across all your
+repositories, then you might use something like:
+
+ ((\"origin/master\" . (\"master\" \"next\" \"maint\")))
+
+Or if the names of all your ephemeral branches contain a slash,
+at least in some repositories, then a good value could be:
+
+ ((\"origin/master\" . \"/\"))
+
+Of course you can also fine-tune:
+
+ ((\"origin/maint\" . \"\\\\\\=`hotfix/\")
+ (\"origin/master\" . \"\\\\\\=`feature/\"))
+
+UPSTREAM can be a local branch:
+
+ ((\"master\" . (\"master\" \"next\" \"maint\")))
+
+Because the main branch is no longer almost always named \"master\"
+you should also account for other common names:
+
+ ((\"main\" . (\"main\" \"master\" \"next\" \"maint\"))
+ (\"master\" . (\"main\" \"master\" \"next\" \"maint\")))
+
+If you use remote branches as UPSTREAM, then you might also want
+to set `magit-branch-prefer-remote-upstream' to a non-nil value.
+However, I recommend that you use local branches as UPSTREAM."
+ :package-version '(magit . "2.9.0")
+ :group 'magit-commands
+ :type '(repeat (cons (string :tag "Use upstream")
+ (choice :tag "for branches"
+ (regexp :tag "matching")
+ (repeat :tag "except"
+ (string :tag "branch"))))))
+
+(defcustom magit-branch-rename-push-target t
+ "Whether the push-remote setup is preserved when renaming a branch.
+
+The command `magit-branch-rename' renames a branch named OLD to
+NEW. This option controls how much of the push-remote setup is
+preserved when doing so.
+
+When nil, then preserve nothing and unset `branch.OLD.pushRemote'.
+
+When `local-only', then first set `branch.NEW.pushRemote' to the
+ same value as `branch.OLD.pushRemote', provided the latter is
+ actually set and unless the former already has another value.
+
+When t, then rename the branch named OLD on the remote specified
+ by `branch.OLD.pushRemote' to NEW, provided OLD exists on that
+ remote and unless NEW already exists on the remote.
+
+When `forge-only' and the `forge' package is available, then
+ behave like `t' if the remote points to a repository on a forge
+ (currently Github or Gitlab), otherwise like `local-only'.
+
+Another supported but obsolete value is `github-only'. It is a
+ misnomer because it now treated as an alias for `forge-only'."
+ :package-version '(magit . "2.90.0")
+ :group 'magit-commands
+ :type '(choice
+ (const :tag "Don't preserve push-remote setup" nil)
+ (const :tag "Preserve push-remote setup" local-only)
+ (const :tag "... and rename corresponding branch on remote" t)
+ (const :tag "... but only if remote is on a forge" forge-only)))
+
+(defcustom magit-branch-direct-configure t
+ "Whether the command `magit-branch' shows Git variables.
+When set to nil, no variables are displayed by this transient
+command, instead the sub-transient `magit-branch-configure'
+has to be used to view and change branch related variables."
+ :package-version '(magit . "2.7.0")
+ :group 'magit-commands
+ :type 'boolean)
+
+(defcustom magit-published-branches '("origin/master")
+ "List of branches that are considered to be published."
+ :package-version '(magit . "2.13.0")
+ :group 'magit-commands
+ :type '(repeat string))
+
+;;; Commands
+
+;;;###autoload (autoload 'magit-branch "magit" nil t)
+(transient-define-prefix magit-branch (branch)
+ "Add, configure or remove a branch."
+ :man-page "git-branch"
+ ["Arguments"
+ (7 "-r" "Recurse submodules when checking out an existing branch"
+ "--recurse-submodules"
+ :if (lambda () (magit-git-version>= "2.13")))]
+ ["Variables"
+ :if (lambda ()
+ (and magit-branch-direct-configure
+ (oref transient--prefix scope)))
+ ("d" magit-branch.<branch>.description)
+ ("u" magit-branch.<branch>.merge/remote)
+ ("r" magit-branch.<branch>.rebase)
+ ("p" magit-branch.<branch>.pushRemote)]
+ [["Checkout"
+ ("b" "branch/revision" magit-checkout)
+ ("l" "local branch" magit-branch-checkout)
+ (6 "o" "new orphan" magit-branch-orphan)]
+ [""
+ ("c" "new branch" magit-branch-and-checkout)
+ ("s" "new spin-off" magit-branch-spinoff)
+ (5 "w" "new worktree" magit-worktree-checkout)]
+ ["Create"
+ ("n" "new branch" magit-branch-create)
+ ("S" "new spin-out" magit-branch-spinout)
+ (5 "W" "new worktree" magit-worktree-branch)]
+ ["Do"
+ ("C" "configure..." magit-branch-configure)
+ ("m" "rename" magit-branch-rename)
+ ("x" "reset" magit-branch-reset)
+ ("k" "delete" magit-branch-delete)]
+ [""
+ (7 "h" "shelve" magit-branch-shelve)
+ (7 "H" "unshelve" magit-branch-unshelve)]]
+ (interactive (list (magit-get-current-branch)))
+ (transient-setup 'magit-branch nil nil :scope branch))
+
+(defun magit-branch-arguments ()
+ (transient-args 'magit-branch))
+
+;;;###autoload
+(defun magit-checkout (revision &optional args)
+ "Checkout REVISION, updating the index and the working tree.
+If REVISION is a local branch, then that becomes the current
+branch. If it is something else, then `HEAD' becomes detached.
+Checkout fails if the working tree or the staging area contain
+changes.
+\n(git checkout REVISION)."
+ (interactive (list (magit-read-other-branch-or-commit "Checkout")
+ (magit-branch-arguments)))
+ (when (string-match "\\`heads/\\(.+\\)" revision)
+ (setq revision (match-string 1 revision)))
+ (magit-run-git "checkout" args revision))
+
+;;;###autoload
+(defun magit-branch-create (branch start-point)
+ "Create BRANCH at branch or revision START-POINT."
+ (interactive (magit-branch-read-args "Create branch"))
+ (magit-call-git "branch" branch start-point)
+ (magit-branch-maybe-adjust-upstream branch start-point)
+ (magit-refresh))
+
+;;;###autoload
+(defun magit-branch-and-checkout (branch start-point &optional args)
+ "Create and checkout BRANCH at branch or revision START-POINT."
+ (interactive (append (magit-branch-read-args "Create and checkout branch")
+ (list (magit-branch-arguments))))
+ (if (string-match-p "^stash@{[0-9]+}$" start-point)
+ (magit-run-git "stash" "branch" branch start-point)
+ (magit-call-git "checkout" args "-b" branch start-point)
+ (magit-branch-maybe-adjust-upstream branch start-point)
+ (magit-refresh)))
+
+;;;###autoload
+(defun magit-branch-or-checkout (arg &optional start-point)
+ "Hybrid between `magit-checkout' and `magit-branch-and-checkout'.
+
+Ask the user for an existing branch or revision. If the user
+input actually can be resolved as a branch or revision, then
+check that out, just like `magit-checkout' would.
+
+Otherwise create and checkout a new branch using the input as
+its name. Before doing so read the starting-point for the new
+branch. This is similar to what `magit-branch-and-checkout'
+does."
+ (interactive
+ (let ((arg (magit-read-other-branch-or-commit "Checkout")))
+ (list arg
+ (and (not (magit-commit-p arg))
+ (magit-read-starting-point "Create and checkout branch" arg)))))
+ (when (string-match "\\`heads/\\(.+\\)" arg)
+ (setq arg (match-string 1 arg)))
+ (if start-point
+ (magit-branch-and-checkout arg start-point)
+ (magit-checkout arg)))
+
+;;;###autoload
+(defun magit-branch-checkout (branch &optional start-point)
+ "Checkout an existing or new local branch.
+
+Read a branch name from the user offering all local branches and
+a subset of remote branches as candidates. Omit remote branches
+for which a local branch by the same name exists from the list
+of candidates. The user can also enter a completely new branch
+name.
+
+- If the user selects an existing local branch, then check that
+ out.
+
+- If the user selects a remote branch, then create and checkout
+ a new local branch with the same name. Configure the selected
+ remote branch as push target.
+
+- If the user enters a new branch name, then create and check
+ that out, after also reading the starting-point from the user.
+
+In the latter two cases the upstream is also set. Whether it is
+set to the chosen START-POINT or something else depends on the
+value of `magit-branch-adjust-remote-upstream-alist', just like
+when using `magit-branch-and-checkout'."
+ (interactive
+ (let* ((current (magit-get-current-branch))
+ (local (magit-list-local-branch-names))
+ (remote (--filter (and (string-match "[^/]+/" it)
+ (not (member (substring it (match-end 0))
+ (cons "HEAD" local))))
+ (magit-list-remote-branch-names)))
+ (choices (nconc (delete current local) remote))
+ (atpoint (magit-branch-at-point))
+ (choice (magit-completing-read
+ "Checkout branch" choices
+ nil nil nil 'magit-revision-history
+ (or (car (member atpoint choices))
+ (and atpoint
+ (car (member (and (string-match "[^/]+/" atpoint)
+ (substring atpoint (match-end 0)))
+ choices)))))))
+ (cond ((member choice remote)
+ (list (and (string-match "[^/]+/" choice)
+ (substring choice (match-end 0)))
+ choice))
+ ((member choice local)
+ (list choice))
+ (t
+ (list choice (magit-read-starting-point "Create" choice))))))
+ (if (not start-point)
+ (magit-checkout branch (magit-branch-arguments))
+ (when (magit-anything-modified-p t)
+ (user-error "Cannot checkout when there are uncommitted changes"))
+ (let ((magit-inhibit-refresh t))
+ (magit-branch-and-checkout branch start-point))
+ (when (magit-remote-branch-p start-point)
+ (pcase-let ((`(,remote . ,remote-branch)
+ (magit-split-branch-name start-point)))
+ (when (and (equal branch remote-branch)
+ (not (equal remote (magit-get "remote.pushDefault"))))
+ (magit-set remote "branch" branch "pushRemote"))))
+ (magit-refresh)))
+
+(defun magit-branch-maybe-adjust-upstream (branch start-point)
+ (--when-let
+ (or (and (magit-get-upstream-branch branch)
+ (magit-get-indirect-upstream-branch start-point))
+ (and (magit-remote-branch-p start-point)
+ (let ((name (cdr (magit-split-branch-name start-point))))
+ (-some (pcase-lambda (`(,upstream . ,rule))
+ (and (magit-branch-p upstream)
+ (if (listp rule)
+ (not (member name rule))
+ (string-match-p rule name))
+ upstream))
+ magit-branch-adjust-remote-upstream-alist))))
+ (magit-call-git "branch" (concat "--set-upstream-to=" it) branch)))
+
+;;;###autoload
+(defun magit-branch-orphan (branch start-point)
+ "Create and checkout an orphan BRANCH with contents from revision START-POINT."
+ (interactive (magit-branch-read-args "Create and checkout orphan branch"))
+ (magit-run-git "checkout" "--orphan" branch start-point))
+
+(defun magit-branch-read-args (prompt &optional default-start)
+ (if magit-branch-read-upstream-first
+ (let ((choice (magit-read-starting-point prompt nil default-start)))
+ (if (magit-rev-verify choice)
+ (list (magit-read-string-ns
+ (if magit-completing-read--silent-default
+ (format "%s (starting at `%s')" prompt choice)
+ "Name for new branch")
+ (let ((def (mapconcat #'identity
+ (cdr (split-string choice "/"))
+ "/")))
+ (and (member choice (magit-list-remote-branch-names))
+ (not (member def (magit-list-local-branch-names)))
+ def)))
+ choice)
+ (if (eq magit-branch-read-upstream-first 'fallback)
+ (list choice
+ (magit-read-starting-point prompt choice default-start))
+ (user-error "Not a valid starting-point: %s" choice))))
+ (let ((branch (magit-read-string-ns (concat prompt " named"))))
+ (list branch (magit-read-starting-point prompt branch default-start)))))
+
+;;;###autoload
+(defun magit-branch-spinout (branch &optional from)
+ "Create new branch from the unpushed commits.
+Like `magit-branch-spinoff' but remain on the current branch.
+If there are any uncommitted changes, then behave exactly like
+`magit-branch-spinoff'."
+ (interactive (list (magit-read-string-ns "Spin out branch")
+ (car (last (magit-region-values 'commit)))))
+ (magit--branch-spinoff branch from nil))
+
+;;;###autoload
+(defun magit-branch-spinoff (branch &optional from)
+ "Create new branch from the unpushed commits.
+
+Create and checkout a new branch starting at and tracking the
+current branch. That branch in turn is reset to the last commit
+it shares with its upstream. If the current branch has no
+upstream or no unpushed commits, then the new branch is created
+anyway and the previously current branch is not touched.
+
+This is useful to create a feature branch after work has already
+began on the old branch (likely but not necessarily \"master\").
+
+If the current branch is a member of the value of option
+`magit-branch-prefer-remote-upstream' (which see), then the
+current branch will be used as the starting point as usual, but
+the upstream of the starting-point may be used as the upstream
+of the new branch, instead of the starting-point itself.
+
+If optional FROM is non-nil, then the source branch is reset
+to `FROM~', instead of to the last commit it shares with its
+upstream. Interactively, FROM is only ever non-nil, if the
+region selects some commits, and among those commits, FROM is
+the commit that is the fewest commits ahead of the source
+branch.
+
+The commit at the other end of the selection actually does not
+matter, all commits between FROM and `HEAD' are moved to the new
+branch. If FROM is not reachable from `HEAD' or is reachable
+from the source branch's upstream, then an error is raised."
+ (interactive (list (magit-read-string-ns "Spin off branch")
+ (car (last (magit-region-values 'commit)))))
+ (magit--branch-spinoff branch from t))
+
+(defun magit--branch-spinoff (branch from checkout)
+ (when (magit-branch-p branch)
+ (user-error "Cannot spin off %s. It already exists" branch))
+ (when (and (not checkout)
+ (magit-anything-modified-p))
+ (message "Staying on HEAD due to uncommitted changes")
+ (setq checkout t))
+ (if-let ((current (magit-get-current-branch)))
+ (let ((tracked (magit-get-upstream-branch current))
+ base)
+ (when from
+ (unless (magit-rev-ancestor-p from current)
+ (user-error "Cannot spin off %s. %s is not reachable from %s"
+ branch from current))
+ (when (and tracked
+ (magit-rev-ancestor-p from tracked))
+ (user-error "Cannot spin off %s. %s is ancestor of upstream %s"
+ branch from tracked)))
+ (let ((magit-process-raise-error t))
+ (if checkout
+ (magit-call-git "checkout" "-b" branch current)
+ (magit-call-git "branch" branch current)))
+ (--when-let (magit-get-indirect-upstream-branch current)
+ (magit-call-git "branch" "--set-upstream-to" it branch))
+ (when (and tracked
+ (setq base
+ (if from
+ (concat from "^")
+ (magit-git-string "merge-base" current tracked)))
+ (not (magit-rev-eq base current)))
+ (if checkout
+ (magit-call-git "update-ref" "-m"
+ (format "reset: moving to %s" base)
+ (concat "refs/heads/" current) base)
+ (magit-call-git "reset" "--hard" base))))
+ (if checkout
+ (magit-call-git "checkout" "-b" branch)
+ (magit-call-git "branch" branch)))
+ (magit-refresh))
+
+;;;###autoload
+(defun magit-branch-reset (branch to &optional set-upstream)
+ "Reset a branch to the tip of another branch or any other commit.
+
+When the branch being reset is the current branch, then do a
+hard reset. If there are any uncommitted changes, then the user
+has to confirm the reset because those changes would be lost.
+
+This is useful when you have started work on a feature branch but
+realize it's all crap and want to start over.
+
+When resetting to another branch and a prefix argument is used,
+then also set the target branch as the upstream of the branch
+that is being reset."
+ (interactive
+ (let* ((atpoint (magit-local-branch-at-point))
+ (branch (magit-read-local-branch "Reset branch" atpoint)))
+ (list branch
+ (magit-completing-read (format "Reset %s to" branch)
+ (delete branch (magit-list-branch-names))
+ nil nil nil 'magit-revision-history
+ (or (and (not (equal branch atpoint)) atpoint)
+ (magit-get-upstream-branch branch)))
+ current-prefix-arg)))
+ (let ((magit-inhibit-refresh t))
+ (if (equal branch (magit-get-current-branch))
+ (if (and (magit-anything-modified-p)
+ (not (yes-or-no-p
+ "Uncommitted changes will be lost. Proceed? ")))
+ (user-error "Abort")
+ (magit-reset-hard to))
+ (magit-call-git "update-ref"
+ "-m" (format "reset: moving to %s" to)
+ (magit-git-string "rev-parse" "--symbolic-full-name"
+ branch)
+ to))
+ (when (and set-upstream (magit-branch-p to))
+ (magit-set-upstream-branch branch to)
+ (magit-branch-maybe-adjust-upstream branch to)))
+ (magit-refresh))
+
+(defvar magit-branch-delete-never-verify nil
+ "Whether `magit-branch-delete' always pushes with \"--no-verify\".")
+
+;;;###autoload
+(defun magit-branch-delete (branches &optional force)
+ "Delete one or multiple branches.
+If the region marks multiple branches, then offer to delete
+those, otherwise prompt for a single branch to be deleted,
+defaulting to the branch at point."
+ ;; One would expect this to be a command as simple as, for example,
+ ;; `magit-branch-rename'; but it turns out everyone wants to squeeze
+ ;; a bit of extra functionality into this one, including myself.
+ (interactive
+ (let ((branches (magit-region-values 'branch t))
+ (force current-prefix-arg))
+ (if (length> branches 1)
+ (magit-confirm t nil "Delete %i branches" nil branches)
+ (setq branches
+ (list (magit-read-branch-prefer-other
+ (if force "Force delete branch" "Delete branch")))))
+ (unless force
+ (when-let ((unmerged (-remove #'magit-branch-merged-p branches)))
+ (if (magit-confirm 'delete-unmerged-branch
+ "Delete unmerged branch %s"
+ "Delete %i unmerged branches"
+ 'noabort unmerged)
+ (setq force branches)
+ (or (setq branches (-difference branches unmerged))
+ (user-error "Abort")))))
+ (list branches force)))
+ (let* ((refs (mapcar #'magit-ref-fullname branches))
+ (ambiguous (--remove it refs)))
+ (when ambiguous
+ (user-error
+ "%s ambiguous. Please cleanup using git directly."
+ (let ((len (length ambiguous)))
+ (cond
+ ((= len 1)
+ (format "%s is" (-first #'magit-ref-ambiguous-p branches)))
+ ((= len (length refs))
+ (format "These %s names are" len))
+ (t
+ (format "%s of these names are" len))))))
+ (cond
+ ((string-match "^refs/remotes/\\([^/]+\\)" (car refs))
+ (let* ((remote (match-string 1 (car refs)))
+ (offset (1+ (length remote))))
+ (cond
+ ((magit-confirm 'delete-branch-on-remote
+ "Delete %s on the remote (not just locally)"
+ "Delete %i branches on the remote (not just locally)"
+ 'noabort branches)
+ ;; The ref may actually point at another rev on the remote,
+ ;; but this is better than nothing.
+ (dolist (ref refs)
+ (message "Delete %s (was %s)" ref
+ (magit-rev-parse "--short" ref)))
+ ;; Assume the branches actually still exist on the remote.
+ (magit-run-git-async
+ "push"
+ (and (or force magit-branch-delete-never-verify) "--no-verify")
+ remote
+ (--map (concat ":" (substring it offset)) branches))
+ ;; If that is not the case, then this deletes the tracking branches.
+ (set-process-sentinel
+ magit-this-process
+ (apply-partially #'magit-delete-remote-branch-sentinel remote refs)))
+ (t
+ (dolist (ref refs)
+ (message "Delete %s (was %s)" ref
+ (magit-rev-parse "--short" ref))
+ (magit-call-git "update-ref" "-d" ref))
+ (magit-refresh)))))
+ ((length> branches 1)
+ (setq branches (delete (magit-get-current-branch) branches))
+ (mapc #'magit-branch-maybe-delete-pr-remote branches)
+ (mapc #'magit-branch-unset-pushRemote branches)
+ (magit-run-git "branch" (if force "-D" "-d") branches))
+ (t ; And now for something completely different.
+ (let* ((branch (car branches))
+ (prompt (format "Branch %s is checked out. " branch))
+ (target (magit-get-upstream-branch)))
+ (when (equal branch (magit-get-current-branch))
+ (when (or (equal branch target)
+ (not target))
+ (setq target (magit-main-branch)))
+ (pcase (if (or (equal branch target)
+ (not target))
+ (magit-read-char-case prompt nil
+ (?d "[d]etach HEAD & delete" 'detach)
+ (?a "[a]bort" 'abort))
+ (magit-read-char-case prompt nil
+ (?d "[d]etach HEAD & delete" 'detach)
+ (?c (format "[c]heckout %s & delete" target) 'target)
+ (?a "[a]bort" 'abort)))
+ (`detach (unless (or (equal force '(4))
+ (member branch force)
+ (magit-branch-merged-p branch t))
+ (magit-confirm 'delete-unmerged-branch
+ "Delete unmerged branch %s" ""
+ nil (list branch)))
+ (magit-call-git "checkout" "--detach"))
+ (`target (unless (or (equal force '(4))
+ (member branch force)
+ (magit-branch-merged-p branch target))
+ (magit-confirm 'delete-unmerged-branch
+ "Delete unmerged branch %s" ""
+ nil (list branch)))
+ (magit-call-git "checkout" target))
+ (`abort (user-error "Abort")))
+ (setq force t))
+ (magit-branch-maybe-delete-pr-remote branch)
+ (magit-branch-unset-pushRemote branch)
+ (magit-run-git "branch" (if force "-D" "-d") branch))))))
+
+(put 'magit-branch-delete 'interactive-only t)
+
+(defun magit-branch-maybe-delete-pr-remote (branch)
+ (when-let ((remote (magit-get "branch" branch "pullRequestRemote")))
+ (let* ((variable (format "remote.%s.fetch" remote))
+ (refspecs (magit-get-all variable)))
+ (unless (member (format "+refs/heads/*:refs/remotes/%s/*" remote)
+ refspecs)
+ (let ((refspec
+ (if (equal (magit-get "branch" branch "pushRemote") remote)
+ (format "+refs/heads/%s:refs/remotes/%s/%s"
+ branch remote branch)
+ (let ((merge (magit-get "branch" branch "merge")))
+ (and merge
+ (string-prefix-p "refs/heads/" merge)
+ (setq merge (substring merge 11))
+ (format "+refs/heads/%s:refs/remotes/%s/%s"
+ merge remote merge))))))
+ (when (member refspec refspecs)
+ (if (and (length= refspecs 1)
+ (magit-confirm 'delete-pr-remote
+ (format "Also delete remote %s (%s)" remote
+ "no pull-request branch remains")
+ nil t))
+ (magit-call-git "remote" "rm" remote)
+ (magit-call-git "config" "--unset-all" variable
+ (format "^%s$" (regexp-quote refspec))))))))))
+
+(defun magit-branch-unset-pushRemote (branch)
+ (magit-set nil "branch" branch "pushRemote"))
+
+(defun magit-delete-remote-branch-sentinel (remote refs process event)
+ (when (memq (process-status process) '(exit signal))
+ (if (= (process-exit-status process) 1)
+ (if-let ((on-remote (--map (concat "refs/remotes/" remote "/" it)
+ (magit-remote-list-branches remote)))
+ (rest (--filter (and (not (member it on-remote))
+ (magit-ref-exists-p it))
+ refs)))
+ (progn
+ (process-put process 'inhibit-refresh t)
+ (magit-process-sentinel process event)
+ (setq magit-this-error nil)
+ (message "Some remote branches no longer exist. %s"
+ "Deleting just the local tracking refs instead...")
+ (dolist (ref rest)
+ (magit-call-git "update-ref" "-d" ref))
+ (magit-refresh)
+ (message "Deleting local remote-tracking refs...done"))
+ (magit-process-sentinel process event))
+ (magit-process-sentinel process event))))
+
+;;;###autoload
+(defun magit-branch-rename (old new &optional force)
+ "Rename the branch named OLD to NEW.
+
+With a prefix argument FORCE, rename even if a branch named NEW
+already exists.
+
+If `branch.OLD.pushRemote' is set, then unset it. Depending on
+the value of `magit-branch-rename-push-target' (which see) maybe
+set `branch.NEW.pushRemote' and maybe rename the push-target on
+the remote."
+ (interactive
+ (let ((branch (magit-read-local-branch "Rename branch")))
+ (list branch
+ (magit-read-string-ns (format "Rename branch '%s' to" branch)
+ nil 'magit-revision-history)
+ current-prefix-arg)))
+ (when (string-match "\\`heads/\\(.+\\)" old)
+ (setq old (match-string 1 old)))
+ (when (equal old new)
+ (user-error "Old and new branch names are the same"))
+ (magit-call-git "branch" (if force "-M" "-m") old new)
+ (when magit-branch-rename-push-target
+ (let ((remote (magit-get-push-remote old))
+ (old-specified (magit-get "branch" old "pushRemote"))
+ (new-specified (magit-get "branch" new "pushRemote")))
+ (when (and old-specified (or force (not new-specified)))
+ ;; Keep the target setting branch specified, even if that is
+ ;; redundant. But if a branch by the same name existed before
+ ;; and the rename isn't forced, then do not change a leftover
+ ;; setting. Such a leftover setting may or may not conform to
+ ;; what we expect here...
+ (magit-set old-specified "branch" new "pushRemote"))
+ (when (and (equal (magit-get-push-remote new) remote)
+ ;; ...and if it does not, then we must abort.
+ (not (eq magit-branch-rename-push-target 'local-only))
+ (or (not (memq magit-branch-rename-push-target
+ '(forge-only github-only)))
+ (and (require (quote forge) nil t)
+ (fboundp 'forge--forge-remote-p)
+ (forge--forge-remote-p remote))))
+ (let ((old-target (magit-get-push-branch old t))
+ (new-target (magit-get-push-branch new t))
+ (remote (magit-get-push-remote new)))
+ (when (and old-target
+ (not new-target)
+ (magit-y-or-n-p (format "Also rename %S to %S on \"%s\""
+ old new remote)))
+ ;; Rename on (i.e. within) the remote, but only if the
+ ;; destination ref doesn't exist yet. If that ref already
+ ;; exists, then it probably is of some value and we better
+ ;; not touch it. Ignore what the local ref points at,
+ ;; i.e. if the local and the remote ref didn't point at
+ ;; the same commit before the rename then keep it that way.
+ (magit-call-git "push" "-v" remote
+ (format "%s:refs/heads/%s" old-target new)
+ (format ":refs/heads/%s" old)))))))
+ (magit-branch-unset-pushRemote old)
+ (magit-refresh))
+
+;;;###autoload
+(defun magit-branch-shelve (branch)
+ "Shelve a BRANCH.
+Rename \"refs/heads/BRANCH\" to \"refs/shelved/BRANCH\",
+and also rename the respective reflog file."
+ (interactive (list (magit-read-other-local-branch "Shelve branch")))
+ (let ((old (concat "refs/heads/" branch))
+ (new (concat "refs/shelved/" branch)))
+ (magit-git "update-ref" new old "")
+ (magit--rename-reflog-file old new)
+ (magit-branch-unset-pushRemote branch)
+ (magit-run-git "branch" "-D" branch)))
+
+;;;###autoload
+(defun magit-branch-unshelve (branch)
+ "Unshelve a BRANCH
+Rename \"refs/shelved/BRANCH\" to \"refs/heads/BRANCH\",
+and also rename the respective reflog file."
+ (interactive
+ (list (magit-completing-read
+ "Unshelve branch"
+ (--map (substring it 8)
+ (magit-list-refnames "refs/shelved"))
+ nil t)))
+ (let ((old (concat "refs/shelved/" branch))
+ (new (concat "refs/heads/" branch)))
+ (magit-git "update-ref" new old "")
+ (magit--rename-reflog-file old new)
+ (magit-run-git "update-ref" "-d" old)))
+
+(defun magit--rename-reflog-file (old new)
+ (let ((old (magit-git-dir (concat "logs/" old)))
+ (new (magit-git-dir (concat "logs/" new))))
+ (when (file-exists-p old)
+ (make-directory (file-name-directory new) t)
+ (rename-file old new t))))
+
+;;; Configure
+
+;;;###autoload (autoload 'magit-branch-configure "magit-branch" nil t)
+(transient-define-prefix magit-branch-configure (branch)
+ "Configure a branch."
+ :man-page "git-branch"
+ [:description
+ (lambda ()
+ (concat
+ (propertize "Configure " 'face 'transient-heading)
+ (propertize (oref transient--prefix scope) 'face 'magit-branch-local)))
+ ("d" magit-branch.<branch>.description)
+ ("u" magit-branch.<branch>.merge/remote)
+ ("r" magit-branch.<branch>.rebase)
+ ("p" magit-branch.<branch>.pushRemote)]
+ ["Configure repository defaults"
+ ("R" magit-pull.rebase)
+ ("P" magit-remote.pushDefault)]
+ ["Configure branch creation"
+ ("a m" magit-branch.autoSetupMerge)
+ ("a r" magit-branch.autoSetupRebase)]
+ (interactive
+ (list (or (and (not current-prefix-arg)
+ (not (and magit-branch-direct-configure
+ (eq transient-current-command 'magit-branch)))
+ (magit-get-current-branch))
+ (magit--read-branch-scope))))
+ (transient-setup 'magit-branch-configure nil nil :scope branch))
+
+(defun magit--read-branch-scope (&optional obj)
+ (magit-read-local-branch
+ (if obj
+ (format "Set %s for branch"
+ (format (oref obj variable) "<name>"))
+ "Configure branch")))
+
+(transient-define-suffix magit-branch.<branch>.description (branch)
+ "Edit the description of BRANCH."
+ :class 'magit--git-variable
+ :transient nil
+ :variable "branch.%s.description"
+ (interactive (list (oref transient-current-prefix scope)))
+ (magit-run-git-with-editor "branch" "--edit-description" branch))
+
+(add-hook 'find-file-hook #'magit-branch-description-check-buffers)
+
+(defun magit-branch-description-check-buffers ()
+ (and buffer-file-name
+ (string-match-p "/\\(BRANCH\\|EDIT\\)_DESCRIPTION\\'" buffer-file-name)))
+
+(defclass magit--git-branch:upstream (magit--git-variable)
+ ((format :initform " %k %m %M\n %r %R")))
+
+(transient-define-infix magit-branch.<branch>.merge/remote ()
+ :class 'magit--git-branch:upstream)
+
+(cl-defmethod transient-init-value ((obj magit--git-branch:upstream))
+ (when-let* ((branch (oref transient--prefix scope))
+ (remote (magit-get "branch" branch "remote"))
+ (merge (magit-get "branch" branch "merge")))
+ (oset obj value (list remote merge))))
+
+(cl-defmethod transient-infix-read ((obj magit--git-branch:upstream))
+ (if (oref obj value)
+ (oset obj value nil)
+ (magit-read-upstream-branch (oref transient--prefix scope) "Upstream")))
+
+(cl-defmethod transient-infix-set ((obj magit--git-branch:upstream) refname)
+ (magit-set-upstream-branch (oref transient--prefix scope) refname)
+ (oset obj value
+ (and-let* ((branch (oref transient--prefix scope))
+ (r (magit-get "branch" branch "remote"))
+ (m (magit-get "branch" branch "merge")))
+ (list r m)))
+ (magit-refresh))
+
+(cl-defmethod transient-format ((obj magit--git-branch:upstream))
+ (let ((branch (oref transient--prefix scope)))
+ (format-spec
+ (oref obj format)
+ `((?k . ,(transient-format-key obj))
+ (?r . ,(format "branch.%s.remote" branch))
+ (?m . ,(format "branch.%s.merge" branch))
+ (?R . ,(transient-format-value obj #'car))
+ (?M . ,(transient-format-value obj #'cadr))))))
+
+(cl-defmethod transient-format-value ((obj magit--git-branch:upstream) key)
+ (if-let ((value (funcall key (oref obj value))))
+ (propertize value 'face 'transient-argument)
+ (propertize "unset" 'face 'transient-inactive-argument)))
+
+(transient-define-infix magit-branch.<branch>.rebase ()
+ :class 'magit--git-variable:choices
+ :scope #'magit--read-branch-scope
+ :variable "branch.%s.rebase"
+ :fallback "pull.rebase"
+ :choices '("true" "false")
+ :default "false")
+
+(transient-define-infix magit-branch.<branch>.pushRemote ()
+ :class 'magit--git-variable:choices
+ :scope #'magit--read-branch-scope
+ :variable "branch.%s.pushRemote"
+ :fallback "remote.pushDefault"
+ :choices #'magit-list-remotes)
+
+(transient-define-infix magit-pull.rebase ()
+ :class 'magit--git-variable:choices
+ :variable "pull.rebase"
+ :choices '("true" "false")
+ :default "false")
+
+(transient-define-infix magit-remote.pushDefault ()
+ :class 'magit--git-variable:choices
+ :variable "remote.pushDefault"
+ :choices #'magit-list-remotes)
+
+(transient-define-infix magit-branch.autoSetupMerge ()
+ :class 'magit--git-variable:choices
+ :variable "branch.autoSetupMerge"
+ :choices '("always" "true" "false")
+ :default "true")
+
+(transient-define-infix magit-branch.autoSetupRebase ()
+ :class 'magit--git-variable:choices
+ :variable "branch.autoSetupRebase"
+ :choices '("always" "local" "remote" "never")
+ :default "never")
+
+;;; _
+(provide 'magit-branch)
+;;; magit-branch.el ends here
diff --git a/elpa/magit-20220503.1245/magit-branch.elc b/elpa/magit-20220503.1245/magit-branch.elc
new file mode 100644
index 0000000..9027fb2
--- /dev/null
+++ b/elpa/magit-20220503.1245/magit-branch.elc
Binary files differ
diff --git a/elpa/magit-20220503.1245/magit-bundle.el b/elpa/magit-20220503.1245/magit-bundle.el
new file mode 100644
index 0000000..0310ed8
--- /dev/null
+++ b/elpa/magit-20220503.1245/magit-bundle.el
@@ -0,0 +1,132 @@
+;;; magit-bundle.el --- Bundle support for Magit -*- lexical-binding:t -*-
+
+;; Copyright (C) 2008-2022 The Magit Project Contributors
+
+;; Author: Jonas Bernoulli <jonas@bernoul.li>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+
+;; SPDX-License-Identifier: GPL-3.0-or-later
+
+;; Magit 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.
+;;
+;; Magit 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 Magit. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Code:
+
+(require 'magit)
+
+;;; Commands
+
+;;;###autoload (autoload 'magit-bundle "magit-bundle" nil t)
+(transient-define-prefix magit-bundle ()
+ "Create or verify Git bundles."
+ :man-page "git-bundle"
+ ["Actions"
+ ("c" "create" magit-bundle-create)
+ ("v" "verify" magit-bundle-verify)
+ ("l" "list-heads" magit-bundle-list-heads)])
+
+;;;###autoload (autoload 'magit-bundle-import "magit-bundle" nil t)
+(transient-define-prefix magit-bundle-create (&optional file refs args)
+ "Create a bundle."
+ :man-page "git-bundle"
+ ["Arguments"
+ ("-a" "Include all refs" "--all")
+ ("-b" "Include branches" "--branches=" :allow-empty t)
+ ("-t" "Include tags" "--tags=" :allow-empty t)
+ ("-r" "Include remotes" "--remotes=" :allow-empty t)
+ ("-g" "Include refs" "--glob=")
+ ("-e" "Exclude refs" "--exclude=")
+ (magit-log:-n)
+ (magit-log:--since)
+ (magit-log:--until)]
+ ["Actions"
+ ("c" "create regular bundle" magit-bundle-create)
+ ("t" "create tracked bundle" magit-bundle-create-tracked)
+ ("u" "update tracked bundle" magit-bundle-update-tracked)]
+ (interactive
+ (and (eq transient-current-command 'magit-bundle-create)
+ (list (read-file-name "Create bundle: " nil nil nil
+ (concat (file-name-nondirectory
+ (directory-file-name (magit-toplevel)))
+ ".bundle"))
+ (magit-completing-read-multiple* "Refnames (zero or more): "
+ (magit-list-refnames))
+ (transient-args 'magit-bundle-create))))
+ (if file
+ (magit-git-bundle "create" file refs args)
+ (transient-setup 'magit-bundle-create)))
+
+;;;###autoload
+(defun magit-bundle-create-tracked (file tag branch refs args)
+ "Create and track a new bundle."
+ (interactive
+ (let ((tag (magit-read-tag "Track bundle using tag"))
+ (branch (magit-read-branch "Bundle branch"))
+ (refs (magit-completing-read-multiple*
+ "Additional refnames (zero or more): "
+ (magit-list-refnames))))
+ (list (read-file-name "File: " nil nil nil (concat tag ".bundle"))
+ tag branch
+ (if (equal branch (magit-get-current-branch))
+ (cons "HEAD" refs)
+ refs)
+ (transient-args 'magit-bundle-create))))
+ (magit-git-bundle "create" file (cons branch refs) args)
+ (magit-git "tag" "--force" tag branch
+ "-m" (concat ";; git-bundle tracking\n"
+ (pp-to-string `((file . ,file)
+ (branch . ,branch)
+ (refs . ,refs)
+ (args . ,args))))))
+
+;;;###autoload
+(defun magit-bundle-update-tracked (tag)
+ "Update a bundle that is being tracked using TAG."
+ (interactive (list (magit-read-tag "Update bundle tracked by tag" t)))
+ (let (msg)
+ (let-alist (magit--with-temp-process-buffer
+ (save-excursion
+ (magit-git-insert "for-each-ref" "--format=%(contents)"
+ (concat "refs/tags/" tag)))
+ (setq msg (buffer-string))
+ (ignore-errors (read (current-buffer))))
+ (unless (and .file .branch)
+ (error "Tag %s does not appear to track a bundle" tag))
+ (magit-git-bundle "create" .file
+ (cons (concat tag ".." .branch) .refs)
+ .args)
+ (magit-git "tag" "--force" tag .branch "-m" msg))))
+
+;;;###autoload
+(defun magit-bundle-verify (file)
+ "Check whether FILE is valid and applies to the current repository."
+ (interactive (list (magit-bundle--read-file-name "Verify bundle: ")))
+ (magit-process-buffer)
+ (magit-git-bundle "verify" file))
+
+;;;###autoload
+(defun magit-bundle-list-heads (file)
+ "List the refs in FILE."
+ (interactive (list (magit-bundle--read-file-name "List heads of bundle: ")))
+ (magit-process-buffer)
+ (magit-git-bundle "list-heads" file))
+
+(defun magit-bundle--read-file-name (prompt)
+ (read-file-name prompt nil nil t (magit-file-at-point) #'file-regular-p))
+
+(defun magit-git-bundle (command file &optional refs args)
+ (magit-git "bundle" command (magit-convert-filename-for-git file) refs args))
+
+;;; _
+(provide 'magit-bundle)
+;;; magit-bundle.el ends here
diff --git a/elpa/magit-20220503.1245/magit-bundle.elc b/elpa/magit-20220503.1245/magit-bundle.elc
new file mode 100644
index 0000000..f7123ae
--- /dev/null
+++ b/elpa/magit-20220503.1245/magit-bundle.elc
Binary files differ
diff --git a/elpa/magit-20220503.1245/magit-clone.el b/elpa/magit-20220503.1245/magit-clone.el
new file mode 100644
index 0000000..302dcdd
--- /dev/null
+++ b/elpa/magit-20220503.1245/magit-clone.el
@@ -0,0 +1,327 @@
+;;; magit-clone.el --- Clone a repository -*- lexical-binding:t -*-
+
+;; Copyright (C) 2008-2022 The Magit Project Contributors
+
+;; Author: Jonas Bernoulli <jonas@bernoul.li>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+
+;; SPDX-License-Identifier: GPL-3.0-or-later
+
+;; Magit 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.
+;;
+;; Magit 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 Magit. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This library implements clone commands.
+
+;;; Code:
+
+(require 'magit)
+
+;;; Options
+
+(defcustom magit-clone-set-remote-head nil
+ "Whether cloning creates the symbolic-ref `<remote>/HEAD'."
+ :package-version '(magit . "2.4.2")
+ :group 'magit-commands
+ :type 'boolean)
+
+(defcustom magit-clone-set-remote.pushDefault 'ask
+ "Whether to set the value of `remote.pushDefault' after cloning.
+
+If t, then set without asking. If nil, then don't set. If
+`ask', then ask."
+ :package-version '(magit . "2.4.0")
+ :group 'magit-commands
+ :type '(choice (const :tag "set" t)
+ (const :tag "ask" ask)
+ (const :tag "don't set" nil)))
+
+(defcustom magit-clone-default-directory nil
+ "Default directory to use when `magit-clone' reads destination.
+If nil (the default), then use the value of `default-directory'.
+If a directory, then use that. If a function, then call that
+with the remote url as only argument and use the returned value."
+ :package-version '(magit . "2.90.0")
+ :group 'magit-commands
+ :type '(choice (const :tag "value of default-directory")
+ (directory :tag "constant directory")
+ (function :tag "function's value")))
+
+(defcustom magit-clone-always-transient nil
+ "Whether `magit-clone' always acts as a transient prefix command.
+If nil, then a prefix argument has to be used to show the transient
+popup instead of invoking the default suffix `magit-clone-regular'
+directly."
+ :package-version '(magit . "3.0.0")
+ :group 'magit-commands
+ :type 'boolean)
+
+(defcustom magit-clone-name-alist
+ '(("\\`\\(?:github:\\|gh:\\)?\\([^:]+\\)\\'" "github.com" "github.user")
+ ("\\`\\(?:gitlab:\\|gl:\\)\\([^:]+\\)\\'" "gitlab.com" "gitlab.user"))
+ "Alist mapping repository names to repository urls.
+
+Each element has the form (REGEXP HOSTNAME USER). When the user
+enters a name when a cloning command asks for a name or url, then
+that is looked up in this list. The first element whose REGEXP
+matches is used.
+
+The format specified by option `magit-clone-url-format' is used
+to turn the name into an url, using HOSTNAME and the repository
+name. If the provided name contains a slash, then that is used.
+Otherwise if the name omits the owner of the repository, then the
+default user specified in the matched entry is used.
+
+If USER contains a dot, then it is treated as a Git variable and
+the value of that is used as the username. Otherwise it is used
+as the username itself."
+ :package-version '(magit . "3.0.0")
+ :group 'magit-commands
+ :type '(repeat (list regexp
+ (string :tag "hostname")
+ (string :tag "user name or git variable"))))
+
+(defcustom magit-clone-url-format "git@%h:%n.git"
+ "Format used when turning repository names into urls.
+%h is the hostname and %n is the repository name, including
+the name of the owner. Also see `magit-clone-name-alist'."
+ :package-version '(magit . "3.0.0")
+ :group 'magit-commands
+ :type 'regexp)
+
+;;; Commands
+
+;;;###autoload (autoload 'magit-clone "magit-clone" nil t)
+(transient-define-prefix magit-clone (&optional transient)
+ "Clone a repository."
+ :man-page "git-clone"
+ ["Fetch arguments"
+ ("-B" "Clone a single branch" "--single-branch")
+ ("-n" "Do not clone tags" "--no-tags")
+ ("-S" "Clones submodules" "--recurse-submodules" :level 6)
+ ("-l" "Do not optimize" "--no-local" :level 7)]
+ ["Setup arguments"
+ ("-o" "Set name of remote" ("-o" "--origin="))
+ ("-b" "Set HEAD branch" ("-b" "--branch="))
+ (magit-clone:--filter
+ :if (lambda () (magit-git-version>= "2.17.0"))
+ :level 7)
+ ("-g" "Separate git directory" "--separate-git-dir="
+ transient-read-directory :level 7)
+ ("-t" "Use template directory" "--template="
+ transient-read-existing-directory :level 6)]
+ ["Local sharing arguments"
+ ("-s" "Share objects" ("-s" "--shared" :level 7))
+ ("-h" "Do not use hardlinks" "--no-hardlinks")]
+ ["Clone"
+ ("C" "regular" magit-clone-regular)
+ ("s" "shallow" magit-clone-shallow)
+ ("d" "shallow since date" magit-clone-shallow-since :level 7)
+ ("e" "shallow excluding" magit-clone-shallow-exclude :level 7)
+ (">" "sparse checkout" magit-clone-sparse
+ :if (lambda () (magit-git-version>= "2.25.0"))
+ :level 6)
+ ("b" "bare" magit-clone-bare)
+ ("m" "mirror" magit-clone-mirror)]
+ (interactive (list (or magit-clone-always-transient current-prefix-arg)))
+ (if transient
+ (transient-setup 'magit-clone)
+ (call-interactively #'magit-clone-regular)))
+
+(transient-define-argument magit-clone:--filter ()
+ :description "Filter some objects"
+ :class 'transient-option
+ :key "-f"
+ :argument "--filter="
+ :reader #'magit-clone-read-filter)
+
+(defun magit-clone-read-filter (prompt initial-input history)
+ (magit-completing-read prompt
+ (list "blob:none" "tree:0")
+ nil nil initial-input history))
+
+;;;###autoload
+(defun magit-clone-regular (repository directory args)
+ "Create a clone of REPOSITORY in DIRECTORY.
+Then show the status buffer for the new repository."
+ (interactive (magit-clone-read-args))
+ (magit-clone-internal repository directory args))
+
+;;;###autoload
+(defun magit-clone-shallow (repository directory args depth)
+ "Create a shallow clone of REPOSITORY in DIRECTORY.
+Then show the status buffer for the new repository.
+With a prefix argument read the DEPTH of the clone;
+otherwise use 1."
+ (interactive (append (magit-clone-read-args)
+ (list (if current-prefix-arg
+ (read-number "Depth: " 1)
+ 1))))
+ (magit-clone-internal repository directory
+ (cons (format "--depth=%s" depth) args)))
+
+;;;###autoload
+(defun magit-clone-shallow-since (repository directory args date)
+ "Create a shallow clone of REPOSITORY in DIRECTORY.
+Then show the status buffer for the new repository.
+Exclude commits before DATE, which is read from the
+user."
+ (interactive (append (magit-clone-read-args)
+ (list (transient-read-date "Exclude commits before: "
+ nil nil))))
+ (magit-clone-internal repository directory
+ (cons (format "--shallow-since=%s" date) args)))
+
+;;;###autoload
+(defun magit-clone-shallow-exclude (repository directory args exclude)
+ "Create a shallow clone of REPOSITORY in DIRECTORY.
+Then show the status buffer for the new repository.
+Exclude commits reachable from EXCLUDE, which is a
+branch or tag read from the user."
+ (interactive (append (magit-clone-read-args)
+ (list (read-string "Exclude commits reachable from: "))))
+ (magit-clone-internal repository directory
+ (cons (format "--shallow-exclude=%s" exclude) args)))
+
+;;;###autoload
+(defun magit-clone-bare (repository directory args)
+ "Create a bare clone of REPOSITORY in DIRECTORY.
+Then show the status buffer for the new repository."
+ (interactive (magit-clone-read-args))
+ (magit-clone-internal repository directory (cons "--bare" args)))
+
+;;;###autoload
+(defun magit-clone-mirror (repository directory args)
+ "Create a mirror of REPOSITORY in DIRECTORY.
+Then show the status buffer for the new repository."
+ (interactive (magit-clone-read-args))
+ (magit-clone-internal repository directory (cons "--mirror" args)))
+
+;;;###autoload
+(defun magit-clone-sparse (repository directory args)
+ "Clone REPOSITORY into DIRECTORY and create a sparse checkout."
+ (interactive (magit-clone-read-args))
+ (magit-clone-internal repository directory (cons "--no-checkout" args)
+ 'sparse))
+
+(defun magit-clone-internal (repository directory args &optional sparse)
+ (let* ((checkout (not (memq (car args) '("--bare" "--mirror"))))
+ (remote (or (transient-arg-value "--origin" args)
+ (magit-get "clone.defaultRemote")
+ "origin"))
+ (set-push-default
+ (and checkout
+ (or (eq magit-clone-set-remote.pushDefault t)
+ (and magit-clone-set-remote.pushDefault
+ (y-or-n-p (format "Set `remote.pushDefault' to %S? "
+ remote)))))))
+ (run-hooks 'magit-credential-hook)
+ (setq directory (file-name-as-directory (expand-file-name directory)))
+ (when (file-exists-p directory)
+ (if (file-directory-p directory)
+ (when (length> (directory-files directory) 2)
+ (let ((name (magit-clone--url-to-name repository)))
+ (unless (and name
+ (setq directory (file-name-as-directory
+ (expand-file-name name directory)))
+ (not (file-exists-p directory)))
+ (user-error "%s already exists" directory))))
+ (user-error "%s already exists and is not a directory" directory)))
+ (magit-run-git-async "clone" args "--" repository
+ (magit-convert-filename-for-git directory))
+ ;; Don't refresh the buffer we're calling from.
+ (process-put magit-this-process 'inhibit-refresh t)
+ (set-process-sentinel
+ magit-this-process
+ (lambda (process event)
+ (when (memq (process-status process) '(exit signal))
+ (let ((magit-process-raise-error t))
+ (magit-process-sentinel process event)))
+ (when (and (eq (process-status process) 'exit)
+ (= (process-exit-status process) 0))
+ (when checkout
+ (let ((default-directory directory))
+ (when set-push-default
+ (setf (magit-get "remote.pushDefault") remote))
+ (unless magit-clone-set-remote-head
+ (magit-remote-unset-head remote))))
+ (when (and sparse checkout)
+ (when (magit-git-version< "2.25.0")
+ (user-error
+ "`git sparse-checkout' not available until Git v2.25"))
+ (let ((default-directory directory))
+ (magit-call-git "sparse-checkout" "init" "--cone")
+ (magit-call-git "checkout" (magit-get-current-branch))))
+ (with-current-buffer (process-get process 'command-buf)
+ (magit-status-setup-buffer directory)))))))
+
+(defun magit-clone-read-args ()
+ (let ((repo (magit-clone-read-repository)))
+ (list repo
+ (read-directory-name
+ "Clone to: "
+ (if (functionp magit-clone-default-directory)
+ (funcall magit-clone-default-directory repo)
+ magit-clone-default-directory)
+ nil nil
+ (magit-clone--url-to-name repo))
+ (transient-args 'magit-clone))))
+
+(defun magit-clone-read-repository ()
+ (magit-read-char-case "Clone from " nil
+ (?u "[u]rl or name"
+ (let ((str (magit-read-string-ns "Clone from url or name")))
+ (if (string-match-p "\\(://\\|@\\)" str)
+ str
+ (magit-clone--name-to-url str))))
+ (?p "[p]ath"
+ (magit-convert-filename-for-git
+ (read-directory-name "Clone repository: ")))
+ (?l "[l]ocal url"
+ (concat "file://"
+ (magit-convert-filename-for-git
+ (read-directory-name "Clone repository: file://"))))
+ (?b "or [b]undle"
+ (magit-convert-filename-for-git
+ (read-file-name "Clone from bundle: ")))))
+
+(defun magit-clone--url-to-name (url)
+ (and (string-match "\\([^/:]+?\\)\\(/?\\.git\\)?$" url)
+ (match-string 1 url)))
+
+(defun magit-clone--name-to-url (name)
+ (or (seq-some
+ (pcase-lambda (`(,re ,host ,user))
+ (and (string-match re name)
+ (let ((repo (match-string 1 name)))
+ (magit-clone--format-url host user repo))))
+ magit-clone-name-alist)
+ (user-error "Not an url and no matching entry in `%s'"
+ 'magit-clone-name-alist)))
+
+(defun magit-clone--format-url (host user repo)
+ (format-spec
+ magit-clone-url-format
+ `((?h . ,host)
+ (?n . ,(if (string-search "/" repo)
+ repo
+ (if (string-search "." user)
+ (if-let ((user (magit-get user)))
+ (concat user "/" repo)
+ (user-error "Set %S or specify owner explicitly" user))
+ (concat user "/" repo)))))))
+
+;;; _
+(provide 'magit-clone)
+;;; magit-clone.el ends here
diff --git a/elpa/magit-20220503.1245/magit-clone.elc b/elpa/magit-20220503.1245/magit-clone.elc
new file mode 100644
index 0000000..cc56028
--- /dev/null
+++ b/elpa/magit-20220503.1245/magit-clone.elc
Binary files differ
diff --git a/elpa/magit-20220503.1245/magit-commit.el b/elpa/magit-20220503.1245/magit-commit.el
new file mode 100644
index 0000000..f28766a
--- /dev/null
+++ b/elpa/magit-20220503.1245/magit-commit.el
@@ -0,0 +1,717 @@
+;;; magit-commit.el --- Create Git commits -*- lexical-binding:t -*-
+
+;; Copyright (C) 2008-2022 The Magit Project Contributors
+
+;; Author: Jonas Bernoulli <jonas@bernoul.li>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+
+;; SPDX-License-Identifier: GPL-3.0-or-later
+
+;; Magit 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.
+;;
+;; Magit 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 Magit. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This library implements commands for creating Git commits. These
+;; commands just initiate the commit, support for writing the commit
+;; messages is implemented in `git-commit.el'.
+
+;;; Code:
+
+(require 'magit)
+(require 'magit-sequence)
+
+(eval-when-compile (require 'epa)) ; for `epa-protocol'
+(eval-when-compile (require 'epg))
+
+;;; Options
+
+(defcustom magit-commit-ask-to-stage 'verbose
+ "Whether to ask to stage everything when committing and nothing is staged."
+ :package-version '(magit . "2.3.0")
+ :group 'magit-commands
+ :type '(choice (const :tag "Ask" t)
+ (const :tag "Ask showing diff" verbose)
+ (const :tag "Stage without confirmation" stage)
+ (const :tag "Don't ask" nil)))
+
+(defcustom magit-commit-show-diff t
+ "Whether the relevant diff is automatically shown when committing."
+ :package-version '(magit . "2.3.0")
+ :group 'magit-commands
+ :type 'boolean)
+
+(defcustom magit-commit-extend-override-date t
+ "Whether using `magit-commit-extend' changes the committer date."
+ :package-version '(magit . "2.3.0")
+ :group 'magit-commands
+ :type 'boolean)
+
+(defcustom magit-commit-reword-override-date t
+ "Whether using `magit-commit-reword' changes the committer date."
+ :package-version '(magit . "2.3.0")
+ :group 'magit-commands
+ :type 'boolean)
+
+(defcustom magit-commit-squash-confirm t
+ "Whether the commit targeted by squash and fixup has to be confirmed.
+When non-nil then the commit at point (if any) is used as default
+choice, otherwise it has to be confirmed. This option only
+affects `magit-commit-squash' and `magit-commit-fixup'. The
+\"instant\" variants always require confirmation because making
+an error while using those is harder to recover from."
+ :package-version '(magit . "2.1.0")
+ :group 'magit-commands
+ :type 'boolean)
+
+(defcustom magit-post-commit-hook nil
+ "Hook run after creating a commit without the user editing a message.
+
+This hook is run by `magit-refresh' if `this-command' is a member
+of `magit-post-stage-hook-commands'. This only includes commands
+named `magit-commit-*' that do *not* require that the user edits
+the commit message in a buffer and then finishes by pressing
+\\<with-editor-mode-map>\\[with-editor-finish].
+
+Also see `git-commit-post-finish-hook'."
+ :package-version '(magit . "2.90.0")
+ :group 'magit-commands
+ :type 'hook)
+
+(defcustom magit-commit-diff-inhibit-same-window nil
+ "Whether to inhibit use of same window when showing diff while committing.
+
+When writing a commit, then a diff of the changes to be committed
+is automatically shown. The idea is that the diff is shown in a
+different window of the same frame and for most users that just
+works. In other words most users can completely ignore this
+option because its value doesn't make a difference for them.
+
+However for users who configured Emacs to never create a new
+window even when the package explicitly tries to do so, then
+displaying two new buffers necessarily means that the first is
+immediately replaced by the second. In our case the message
+buffer is immediately replaced by the diff buffer, which is of
+course highly undesirable.
+
+A workaround is to suppress this user configuration in this
+particular case. Users have to explicitly opt-in by toggling
+this option. We cannot enable the workaround unconditionally
+because that again causes issues for other users: if the frame
+is too tiny or the relevant settings too aggressive, then the
+diff buffer would end up being displayed in a new frame.
+
+Also see https://github.com/magit/magit/issues/4132."
+ :package-version '(magit . "3.3.0")
+ :group 'magit-commands
+ :type 'boolean)
+
+(defcustom magit-openpgp-default-signing-key nil
+ "Fingerprint of your default Openpgp key used for signing.
+If the specified primary key has signing capacity then it is used
+as the value of the `--gpg-sign' argument without prompting, even
+when other such keys exist. To be able to select another key you
+must then use a prefix argument."
+ :package-version '(magit . "3.4.0")
+ :group 'magit-commands
+ :type 'string)
+
+(defvar magit-post-commit-hook-commands
+ '(magit-commit-extend
+ magit-commit-fixup
+ magit-commit-augment
+ magit-commit-instant-fixup
+ magit-commit-instant-squash))
+
+;;; Popup
+
+;;;###autoload (autoload 'magit-commit "magit-commit" nil t)
+(transient-define-prefix magit-commit ()
+ "Create a new commit or replace an existing commit."
+ :info-manual "(magit)Initiating a Commit"
+ :man-page "git-commit"
+ ["Arguments"
+ ("-a" "Stage all modified and deleted files" ("-a" "--all"))
+ ("-e" "Allow empty commit" "--allow-empty")
+ ("-v" "Show diff of changes to be committed" ("-v" "--verbose"))
+ ("-n" "Disable hooks" ("-n" "--no-verify"))
+ ("-R" "Claim authorship and reset author date" "--reset-author")
+ (magit:--author :description "Override the author")
+ (7 "-D" "Override the author date" "--date=" transient-read-date)
+ ("-s" "Add Signed-off-by line" ("-s" "--signoff"))
+ (5 magit:--gpg-sign)
+ (magit-commit:--reuse-message)]
+ [["Create"
+ ("c" "Commit" magit-commit-create)]
+ ["Edit HEAD"
+ ("e" "Extend" magit-commit-extend)
+ ("w" "Reword" magit-commit-reword)
+ ("a" "Amend" magit-commit-amend)
+ (6 "n" "Reshelve" magit-commit-reshelve)]
+ ["Edit"
+ ("f" "Fixup" magit-commit-fixup)
+ ("s" "Squash" magit-commit-squash)
+ ("A" "Augment" magit-commit-augment)
+ (6 "x" "Absorb changes" magit-commit-autofixup)
+ (6 "X" "Absorb modules" magit-commit-absorb-modules)]
+ [""
+ ("F" "Instant fixup" magit-commit-instant-fixup)
+ ("S" "Instant squash" magit-commit-instant-squash)]]
+ (interactive)
+ (if-let ((buffer (magit-commit-message-buffer)))
+ (switch-to-buffer buffer)
+ (transient-setup 'magit-commit)))
+
+(defun magit-commit-arguments nil
+ (transient-args 'magit-commit))
+
+(transient-define-argument magit:--gpg-sign ()
+ :description "Sign using gpg"
+ :class 'transient-option
+ :shortarg "-S"
+ :argument "--gpg-sign="
+ :allow-empty t
+ :reader #'magit-read-gpg-signing-key)
+
+(defvar magit-gpg-secret-key-hist nil)
+
+(defun magit-read-gpg-secret-key
+ (prompt &optional initial-input history predicate default)
+ (require 'epa)
+ (let* ((keys (cl-mapcan
+ (lambda (cert)
+ (and (or (not predicate)
+ (funcall predicate cert))
+ (let* ((key (car (epg-key-sub-key-list cert)))
+ (fpr (epg-sub-key-fingerprint key))
+ (id (epg-sub-key-id key))
+ (author
+ (and-let* ((id-obj
+ (car (epg-key-user-id-list cert))))
+ (let ((id-str (epg-user-id-string id-obj)))
+ (if (stringp id-str)
+ id-str
+ (epg-decode-dn id-obj))))))
+ (list
+ (propertize fpr 'display
+ (concat (substring fpr 0 (- (length id)))
+ (propertize id 'face 'highlight)
+ " " author))))))
+ (epg-list-keys (epg-make-context epa-protocol) nil t)))
+ (choice (or (and (not current-prefix-arg)
+ (or (and (length= keys 1) (car keys))
+ (and default (car (member default keys)))))
+ (completing-read prompt keys nil nil nil
+ history nil initial-input))))
+ (set-text-properties 0 (length choice) nil choice)
+ choice))
+
+(defun magit-read-gpg-signing-key (prompt &optional initial-input history)
+ (magit-read-gpg-secret-key
+ prompt initial-input history
+ (lambda (cert)
+ (cl-some (lambda (key)
+ (memq 'sign (epg-sub-key-capability key)))
+ (epg-key-sub-key-list cert)))
+ magit-openpgp-default-signing-key))
+
+(transient-define-argument magit-commit:--reuse-message ()
+ :description "Reuse commit message"
+ :class 'transient-option
+ :shortarg "-C"
+ :argument "--reuse-message="
+ :reader #'magit-read-reuse-message
+ :history-key 'magit-revision-history)
+
+(defun magit-read-reuse-message (prompt &optional default history)
+ (magit-completing-read prompt (magit-list-refnames)
+ nil nil nil history
+ (or default
+ (and (magit-rev-verify "ORIG_HEAD")
+ "ORIG_HEAD"))))
+
+;;; Commands
+
+;;;###autoload
+(defun magit-commit-create (&optional args)
+ "Create a new commit on `HEAD'.
+With a prefix argument, amend to the commit at `HEAD' instead.
+\n(git commit [--amend] ARGS)"
+ (interactive (if current-prefix-arg
+ (list (cons "--amend" (magit-commit-arguments)))
+ (list (magit-commit-arguments))))
+ (when (member "--all" args)
+ (setq this-command 'magit-commit-all))
+ (when (setq args (magit-commit-assert args))
+ (let ((default-directory (magit-toplevel)))
+ (magit-run-git-with-editor "commit" args))))
+
+;;;###autoload
+(defun magit-commit-amend (&optional args)
+ "Amend the last commit.
+\n(git commit --amend ARGS)"
+ (interactive (list (magit-commit-arguments)))
+ (magit-commit-amend-assert)
+ (magit-run-git-with-editor "commit" "--amend" args))
+
+;;;###autoload
+(defun magit-commit-extend (&optional args override-date)
+ "Amend the last commit, without editing the message.
+
+With a prefix argument keep the committer date, otherwise change
+it. The option `magit-commit-extend-override-date' can be used
+to inverse the meaning of the prefix argument. \n(git commit
+--amend --no-edit)"
+ (interactive (list (magit-commit-arguments)
+ (if current-prefix-arg
+ (not magit-commit-extend-override-date)
+ magit-commit-extend-override-date)))
+ (when (setq args (magit-commit-assert args))
+ (magit-commit-amend-assert)
+ (if override-date
+ (magit-run-git-with-editor "commit" "--amend" "--no-edit" args)
+ (with-environment-variables
+ (("GIT_COMMITTER_DATE" (magit-rev-format "%cD")))
+ (magit-run-git-with-editor "commit" "--amend" "--no-edit" args)))))
+
+;;;###autoload
+(defun magit-commit-reword (&optional args override-date)
+ "Reword the last commit, ignoring staged changes.
+
+With a prefix argument keep the committer date, otherwise change
+it. The option `magit-commit-reword-override-date' can be used
+to inverse the meaning of the prefix argument.
+
+Non-interactively respect the optional OVERRIDE-DATE argument
+and ignore the option.
+\n(git commit --amend --only)"
+ (interactive (list (magit-commit-arguments)
+ (if current-prefix-arg
+ (not magit-commit-reword-override-date)
+ magit-commit-reword-override-date)))
+ (magit-commit-amend-assert)
+ (cl-pushnew "--allow-empty" args :test #'equal)
+ (if override-date
+ (magit-run-git-with-editor "commit" "--amend" "--only" args)
+ (with-environment-variables
+ (("GIT_COMMITTER_DATE" (magit-rev-format "%cD")))
+ (magit-run-git-with-editor "commit" "--amend" "--only" args))))
+
+;;;###autoload
+(defun magit-commit-fixup (&optional commit args)
+ "Create a fixup commit.
+
+With a prefix argument the target COMMIT has to be confirmed.
+Otherwise the commit at point may be used without confirmation
+depending on the value of option `magit-commit-squash-confirm'."
+ (interactive (list (magit-commit-at-point)
+ (magit-commit-arguments)))
+ (magit-commit-squash-internal "--fixup" commit args))
+
+;;;###autoload
+(defun magit-commit-squash (&optional commit args)
+ "Create a squash commit, without editing the squash message.
+
+With a prefix argument the target COMMIT has to be confirmed.
+Otherwise the commit at point may be used without confirmation
+depending on the value of option `magit-commit-squash-confirm'.
+
+If you want to immediately add a message to the squash commit,
+then use `magit-commit-augment' instead of this command."
+ (interactive (list (magit-commit-at-point)
+ (magit-commit-arguments)))
+ (magit-commit-squash-internal "--squash" commit args))
+
+;;;###autoload
+(defun magit-commit-augment (&optional commit args)
+ "Create a squash commit, editing the squash message.
+
+With a prefix argument the target COMMIT has to be confirmed.
+Otherwise the commit at point may be used without confirmation
+depending on the value of option `magit-commit-squash-confirm'."
+ (interactive (list (magit-commit-at-point)
+ (magit-commit-arguments)))
+ (magit-commit-squash-internal "--squash" commit args nil t))
+
+;;;###autoload
+(defun magit-commit-instant-fixup (&optional commit args)
+ "Create a fixup commit targeting COMMIT and instantly rebase."
+ (interactive (list (magit-commit-at-point)
+ (magit-commit-arguments)))
+ (magit-commit-squash-internal "--fixup" commit args t))
+
+;;;###autoload
+(defun magit-commit-instant-squash (&optional commit args)
+ "Create a squash commit targeting COMMIT and instantly rebase."
+ (interactive (list (magit-commit-at-point)
+ (magit-commit-arguments)))
+ (magit-commit-squash-internal "--squash" commit args t))
+
+(defun magit-commit-squash-internal
+ (option commit &optional args rebase edit confirmed)
+ (when-let ((args (magit-commit-assert args (not edit))))
+ (when commit
+ (when (and rebase (not (magit-rev-ancestor-p commit "HEAD")))
+ (magit-read-char-case
+ (format "%s isn't an ancestor of HEAD. " commit) nil
+ (?c "[c]reate without rebasing" (setq rebase nil))
+ (?s "[s]elect other" (setq commit nil))
+ (?a "[a]bort" (user-error "Quit")))))
+ (when commit
+ (setq commit (magit-rebase-interactive-assert commit t)))
+ (if (and commit
+ (or confirmed
+ (not (or rebase
+ current-prefix-arg
+ magit-commit-squash-confirm))))
+ (let ((magit-commit-show-diff nil))
+ (push (concat option "=" commit) args)
+ (unless edit
+ (push "--no-edit" args))
+ (if rebase
+ (magit-with-editor
+ (magit-call-git
+ "commit" "--no-gpg-sign"
+ (-remove-first
+ (apply-partially #'string-prefix-p "--gpg-sign=")
+ args)))
+ (magit-run-git-with-editor "commit" args))
+ t) ; The commit was created; used by below lambda.
+ (magit-log-select
+ (lambda (commit)
+ (when (and (magit-commit-squash-internal option commit args
+ rebase edit t)
+ rebase)
+ (magit-commit-amend-assert commit)
+ (magit-rebase-interactive-1 commit
+ (list "--autosquash" "--autostash" "--keep-empty")
+ "" "true" nil t)))
+ (format "Type %%p on a commit to %s into it,"
+ (substring option 2))
+ nil nil nil commit)
+ (when magit-commit-show-diff
+ (let ((magit-display-buffer-noselect t))
+ (apply #'magit-diff-staged nil (magit-diff-arguments)))))))
+
+(defun magit-commit-amend-assert (&optional commit)
+ (--when-let (magit-list-publishing-branches commit)
+ (let ((m1 "This commit has already been published to ")
+ (m2 ".\nDo you really want to modify it"))
+ (magit-confirm 'amend-published
+ (concat m1 "%s" m2)
+ (concat m1 "%i public branches" m2)
+ nil it))))
+
+(defun magit-commit-assert (args &optional strict)
+ (cond
+ ((or (magit-anything-staged-p)
+ (and (magit-anything-unstaged-p)
+ ;; ^ Everything of nothing is still nothing.
+ (member "--all" args))
+ (and (not strict)
+ ;; ^ For amend variants that don't make sense otherwise.
+ (or (member "--amend" args)
+ (member "--allow-empty" args)
+ (member "--reset-author" args)
+ (member "--signoff" args)
+ (transient-arg-value "--author=" args)
+ (transient-arg-value "--date=" args))))
+ (or args (list "--")))
+ ((and (magit-rebase-in-progress-p)
+ (not (magit-anything-unstaged-p))
+ (y-or-n-p "Nothing staged. Continue in-progress rebase? "))
+ (setq this-command #'magit-rebase-continue)
+ (magit-run-git-sequencer "rebase" "--continue")
+ nil)
+ ((and (file-exists-p (magit-git-dir "MERGE_MSG"))
+ (not (magit-anything-unstaged-p)))
+ (or args (list "--")))
+ ((not (magit-anything-unstaged-p))
+ (user-error "Nothing staged (or unstaged)"))
+ (magit-commit-ask-to-stage
+ (when (eq magit-commit-ask-to-stage 'verbose)
+ (magit-diff-unstaged))
+ (prog1 (when (or (eq magit-commit-ask-to-stage 'stage)
+ (y-or-n-p "Nothing staged. Stage and commit all unstaged changes? "))
+ (magit-run-git "add" "-u" ".")
+ (or args (list "--")))
+ (when (and (eq magit-commit-ask-to-stage 'verbose)
+ (derived-mode-p 'magit-diff-mode))
+ (magit-mode-bury-buffer))))
+ (t
+ (user-error "Nothing staged"))))
+
+(defvar magit--reshelve-history nil)
+
+;;;###autoload
+(defun magit-commit-reshelve (date update-author &optional args)
+ "Change the committer date and possibly the author date of `HEAD'.
+
+The current time is used as the initial minibuffer input and the
+original author or committer date is available as the previous
+history element.
+
+Both the author and the committer dates are changes, unless one
+of the following is true, in which case only the committer date
+is updated:
+- You are not the author of the commit that is being reshelved.
+- The command was invoked with a prefix argument.
+- Non-interactively if UPDATE-AUTHOR is nil."
+ (interactive
+ (let ((update-author (and (magit-rev-author-p "HEAD")
+ (not current-prefix-arg))))
+ (push (magit-rev-format (if update-author "%ad" "%cd") "HEAD"
+ (concat "--date=format:%F %T %z"))
+ magit--reshelve-history)
+ (list (read-string (if update-author
+ "Change author and committer dates to: "
+ "Change committer date to: ")
+ (cons (format-time-string "%F %T %z") 17)
+ 'magit--reshelve-history)
+ update-author
+ (magit-commit-arguments))))
+ (with-environment-variables (("GIT_COMMITTER_DATE" date))
+ (magit-run-git "commit" "--amend" "--no-edit"
+ (and update-author (concat "--date=" date))
+ args)))
+
+;;;###autoload
+(defun magit-commit-absorb-modules (phase commit)
+ "Spread modified modules across recent commits."
+ (interactive (list 'select (magit-get-upstream-branch)))
+ (let ((modules (magit-list-modified-modules)))
+ (unless modules
+ (user-error "There are no modified modules that could be absorbed"))
+ (when commit
+ (setq commit (magit-rebase-interactive-assert commit t)))
+ (if (and commit (eq phase 'run))
+ (progn
+ (dolist (module modules)
+ (when-let ((msg (magit-git-string
+ "log" "-1" "--format=%s"
+ (concat commit "..") "--" module)))
+ (magit-git "commit" "-m" (concat "fixup! " msg)
+ "--only" "--" module)))
+ (magit-refresh)
+ t)
+ (magit-log-select
+ (lambda (commit)
+ (magit-commit-absorb-modules 'run commit))
+ nil nil nil nil commit))))
+
+;;;###autoload (autoload 'magit-commit-absorb "magit-commit" nil t)
+(transient-define-prefix magit-commit-absorb (phase commit args)
+ "Spread staged changes across recent commits.
+With a prefix argument use a transient command to select infix
+arguments. This command requires git-absorb executable, which
+is available from https://github.com/tummychow/git-absorb.
+See `magit-commit-autofixup' for an alternative implementation."
+ ["Arguments"
+ ("-f" "Skip safety checks" ("-f" "--force"))
+ ("-v" "Display more output" ("-v" "--verbose"))]
+ ["Actions"
+ ("x" "Absorb" magit-commit-absorb)]
+ (interactive (if current-prefix-arg
+ (list 'transient nil nil)
+ (list 'select
+ (magit-get-upstream-branch)
+ (transient-args 'magit-commit-absorb))))
+ (if (eq phase 'transient)
+ (transient-setup 'magit-commit-absorb)
+ (unless (compat-executable-find "git-absorb" t)
+ (user-error "This command requires the git-absorb executable, which %s"
+ "is available from https://github.com/tummychow/git-absorb"))
+ (unless (magit-anything-staged-p)
+ (if (magit-anything-unstaged-p)
+ (if (y-or-n-p "Nothing staged. Absorb all unstaged changes? ")
+ (magit-with-toplevel
+ (magit-run-git "add" "-u" "."))
+ (user-error "Abort"))
+ (user-error "There are no changes that could be absorbed")))
+ (when commit
+ (setq commit (magit-rebase-interactive-assert commit t)))
+ (if (and commit (eq phase 'run))
+ (progn (magit-run-git-async "absorb" "-v" args "-b" commit) t)
+ (magit-log-select
+ (lambda (commit)
+ (with-no-warnings ; about non-interactive use
+ (magit-commit-absorb 'run commit args)))
+ nil nil nil nil commit))))
+
+;;;###autoload (autoload 'magit-commit-autofixup "magit-commit" nil t)
+(transient-define-prefix magit-commit-autofixup (phase commit args)
+ "Spread staged or unstaged changes across recent commits.
+
+If there are any staged then spread only those, otherwise
+spread all unstaged changes. With a prefix argument use a
+transient command to select infix arguments.
+
+This command requires the git-autofixup script, which is
+available from https://github.com/torbiak/git-autofixup.
+See `magit-commit-absorb' for an alternative implementation."
+ ["Arguments"
+ (magit-autofixup:--context)
+ (magit-autofixup:--strict)]
+ ["Actions"
+ ("x" "Absorb" magit-commit-autofixup)]
+ (interactive (if current-prefix-arg
+ (list 'transient nil nil)
+ (list 'select
+ (magit-get-upstream-branch)
+ (transient-args 'magit-commit-autofixup))))
+ (if (eq phase 'transient)
+ (transient-setup 'magit-commit-autofixup)
+ (unless (compat-executable-find "git-autofixup" t)
+ (user-error "This command requires the git-autofixup script, which %s"
+ "is available from https://github.com/torbiak/git-autofixup"))
+ (unless (magit-anything-modified-p)
+ (user-error "There are no changes that could be absorbed"))
+ (when commit
+ (setq commit (magit-rebase-interactive-assert commit t)))
+ (if (and commit (eq phase 'run))
+ (progn (magit-run-git-async "autofixup" "-vv" args commit) t)
+ (magit-log-select
+ (lambda (commit)
+ (with-no-warnings ; about non-interactive use
+ (magit-commit-autofixup 'run commit args)))
+ nil nil nil nil commit))))
+
+(transient-define-argument magit-autofixup:--context ()
+ :description "Diff context lines"
+ :class 'transient-option
+ :shortarg "-c"
+ :argument "--context="
+ :reader #'transient-read-number-N0)
+
+(transient-define-argument magit-autofixup:--strict ()
+ :description "Strictness"
+ :class 'transient-option
+ :shortarg "-s"
+ :argument "--strict="
+ :reader #'transient-read-number-N0)
+
+;;; Pending Diff
+
+(defun magit-commit-diff ()
+ (when (and git-commit-mode magit-commit-show-diff)
+ (when-let ((diff-buffer (magit-get-mode-buffer 'magit-diff-mode)))
+ ;; This window just started displaying the commit message
+ ;; buffer. Without this that buffer would immediately be
+ ;; replaced with the diff buffer. See #2632.
+ (unrecord-window-buffer nil diff-buffer))
+ (condition-case nil
+ (let ((args (car (magit-diff-arguments)))
+ (magit-inhibit-save-previous-winconf 'unset)
+ (magit-display-buffer-noselect t)
+ (inhibit-quit nil)
+ (display-buffer-overriding-action
+ display-buffer-overriding-action))
+ (when magit-commit-diff-inhibit-same-window
+ (setq display-buffer-overriding-action
+ '(nil (inhibit-same-window t))))
+ (message "Diffing changes to be committed (C-g to abort diffing)")
+ (cl-case last-command
+ (magit-commit
+ (magit-diff-staged nil args))
+ (magit-commit-all
+ (magit-diff-working-tree nil args))
+ ((magit-commit-amend
+ magit-commit-reword
+ magit-rebase-reword-commit)
+ (magit-diff-while-amending args))
+ (t (if (magit-anything-staged-p)
+ (magit-diff-staged nil args)
+ (magit-diff-while-amending args)))))
+ (quit))))
+
+;; Mention `magit-diff-while-committing' because that's
+;; always what I search for when I try to find this line.
+(add-hook 'server-switch-hook #'magit-commit-diff)
+(add-hook 'with-editor-filter-visit-hook #'magit-commit-diff)
+
+(add-to-list 'with-editor-server-window-alist
+ (cons git-commit-filename-regexp #'switch-to-buffer))
+
+;;; Message Utilities
+
+(defun magit-commit-message-buffer ()
+ (let* ((find-file-visit-truename t) ; git uses truename of COMMIT_EDITMSG
+ (topdir (magit-toplevel)))
+ (--first (equal topdir (with-current-buffer it
+ (and git-commit-mode (magit-toplevel))))
+ (append (buffer-list (selected-frame))
+ (buffer-list)))))
+
+(defvar magit-commit-add-log-insert-function #'magit-commit-add-log-insert
+ "Used by `magit-commit-add-log' to insert a single entry.")
+
+(defun magit-commit-add-log ()
+ "Add a stub for the current change into the commit message buffer.
+If no commit is in progress, then initiate it. Use the function
+specified by variable `magit-commit-add-log-insert-function' to
+actually insert the entry."
+ (interactive)
+ (pcase-let* ((hunk (and (magit-section-match 'hunk)
+ (magit-current-section)))
+ (log (magit-commit-message-buffer))
+ (`(,buf ,pos) (magit-diff-visit-file--noselect)))
+ (unless log
+ (unless (magit-commit-assert nil)
+ (user-error "Abort"))
+ (magit-commit-create)
+ (while (not (setq log (magit-commit-message-buffer)))
+ (sit-for 0.01)))
+ (magit--with-temp-position buf pos
+ (funcall magit-commit-add-log-insert-function log
+ (magit-file-relative-name)
+ (and hunk (add-log-current-defun))))))
+
+(defun magit-commit-add-log-insert (buffer file defun)
+ (with-current-buffer buffer
+ (undo-boundary)
+ (goto-char (point-max))
+ (while (re-search-backward (concat "^" comment-start) nil t))
+ (save-restriction
+ (narrow-to-region (point-min) (point))
+ (cond ((re-search-backward (format "* %s\\(?: (\\([^)]+\\))\\)?: " file)
+ nil t)
+ (when (equal (match-string 1) defun)
+ (setq defun nil))
+ (re-search-forward ": "))
+ (t
+ (when (re-search-backward "^[\\*(].+\n" nil t)
+ (goto-char (match-end 0)))
+ (while (re-search-forward "^[^\\*\n].*\n" nil t))
+ (if defun
+ (progn (insert (format "* %s (%s): \n" file defun))
+ (setq defun nil))
+ (insert (format "* %s: \n" file)))
+ (backward-char)
+ (unless (looking-at "\n[\n\\']")
+ (insert ?\n)
+ (backward-char))))
+ (when defun
+ (forward-line)
+ (let ((limit (save-excursion
+ (and (re-search-forward "^\\*" nil t)
+ (point)))))
+ (unless (or (looking-back (format "(%s): " defun)
+ (line-beginning-position))
+ (re-search-forward (format "^(%s): " defun) limit t))
+ (while (re-search-forward "^[^\\*\n].*\n" limit t))
+ (insert (format "(%s): \n" defun))
+ (backward-char)))))))
+
+;;; _
+(provide 'magit-commit)
+;;; magit-commit.el ends here
diff --git a/elpa/magit-20220503.1245/magit-commit.elc b/elpa/magit-20220503.1245/magit-commit.elc
new file mode 100644
index 0000000..96b73c2
--- /dev/null
+++ b/elpa/magit-20220503.1245/magit-commit.elc
Binary files differ
diff --git a/elpa/magit-20220503.1245/magit-core.el b/elpa/magit-20220503.1245/magit-core.el
new file mode 100644
index 0000000..d02b25b
--- /dev/null
+++ b/elpa/magit-20220503.1245/magit-core.el
@@ -0,0 +1,129 @@
+;;; magit-core.el --- Core functionality -*- lexical-binding:t -*-
+
+;; Copyright (C) 2008-2022 The Magit Project Contributors
+
+;; Author: Jonas Bernoulli <jonas@bernoul.li>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+
+;; SPDX-License-Identifier: GPL-3.0-or-later
+
+;; Magit 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.
+;;
+;; Magit 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 Magit. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This library requires several other libraries, so that yet other
+;; libraries can just require this one, instead of having to require
+;; all the other ones. In other words this separates the low-level
+;; stuff from the rest. It also defines some Custom groups.
+
+;;; Code:
+
+(require 'magit-base)
+(require 'magit-git)
+(require 'magit-mode)
+(require 'magit-margin)
+(require 'magit-process)
+(require 'magit-transient)
+(require 'magit-autorevert)
+
+(when (magit--libgit-available-p)
+ (condition-case err
+ (require 'magit-libgit)
+ (error
+ (setq magit-inhibit-libgit 'error)
+ (message "Error while loading `magit-libgit': %S" err)
+ (message "That is not fatal. The `libegit2' module just won't be used."))))
+
+(defgroup magit nil
+ "Controlling Git from Emacs."
+ :link '(url-link "https://magit.vc")
+ :link '(info-link "(magit)FAQ")
+ :link '(info-link "(magit)")
+ :group 'tools)
+
+(defgroup magit-essentials nil
+ "Options that every Magit user should briefly think about.
+
+Each of these options falls into one or more of these categories:
+
+* Options that affect Magit's behavior in fundamental ways.
+* Options that affect safety.
+* Options that affect performance.
+* Options that are of a personal nature."
+ :link '(info-link "(magit)Essential Settings")
+ :group 'magit)
+
+(defgroup magit-miscellaneous nil
+ "Miscellaneous Magit options."
+ :group 'magit)
+
+(defgroup magit-commands nil
+ "Options controlling behavior of certain commands."
+ :group 'magit)
+
+(defgroup magit-modes nil
+ "Modes used or provided by Magit."
+ :group 'magit)
+
+(defgroup magit-buffers nil
+ "Options concerning Magit buffers."
+ :link '(info-link "(magit)Modes and Buffers")
+ :group 'magit)
+
+(defgroup magit-refresh nil
+ "Options controlling how Magit buffers are refreshed."
+ :link '(info-link "(magit)Automatic Refreshing of Magit Buffers")
+ :group 'magit
+ :group 'magit-buffers)
+
+(defgroup magit-faces nil
+ "Faces used by Magit."
+ :group 'magit
+ :group 'faces)
+
+(custom-add-to-group 'magit-faces 'diff-refine-added 'custom-face)
+(custom-add-to-group 'magit-faces 'diff-refine-removed 'custom-face)
+
+(defgroup magit-extensions nil
+ "Extensions to Magit."
+ :group 'magit)
+
+(custom-add-to-group 'magit-modes 'git-commit 'custom-group)
+(custom-add-to-group 'magit-faces 'git-commit-faces 'custom-group)
+(custom-add-to-group 'magit-modes 'git-rebase 'custom-group)
+(custom-add-to-group 'magit-faces 'git-rebase-faces 'custom-group)
+(custom-add-to-group 'magit 'magit-section 'custom-group)
+(custom-add-to-group 'magit-faces 'magit-section-faces 'custom-group)
+(custom-add-to-group 'magit-process 'with-editor 'custom-group)
+
+(defgroup magit-related nil
+ "Options that are relevant to Magit but that are defined elsewhere."
+ :link '(custom-group-link vc)
+ :link '(custom-group-link smerge)
+ :link '(custom-group-link ediff)
+ :link '(custom-group-link auto-revert)
+ :group 'magit
+ :group 'magit-extensions
+ :group 'magit-essentials)
+
+(custom-add-to-group 'magit-related 'auto-revert-check-vc-info 'custom-variable)
+(custom-add-to-group 'magit-auto-revert 'auto-revert-check-vc-info 'custom-variable)
+
+(custom-add-to-group 'magit-related 'ediff-window-setup-function 'custom-variable)
+(custom-add-to-group 'magit-related 'smerge-refine-ignore-whitespace 'custom-variable)
+(custom-add-to-group 'magit-related 'vc-follow-symlinks 'custom-variable)
+
+;;; _
+(provide 'magit-core)
+;;; magit-core.el ends here
diff --git a/elpa/magit-20220503.1245/magit-core.elc b/elpa/magit-20220503.1245/magit-core.elc
new file mode 100644
index 0000000..63fc652
--- /dev/null
+++ b/elpa/magit-20220503.1245/magit-core.elc
Binary files differ
diff --git a/elpa/magit-20220503.1245/magit-diff.el b/elpa/magit-20220503.1245/magit-diff.el
new file mode 100644
index 0000000..9e78b52
--- /dev/null
+++ b/elpa/magit-20220503.1245/magit-diff.el
@@ -0,0 +1,3450 @@
+;;; magit-diff.el --- Inspect Git diffs -*- lexical-binding:t -*-
+
+;; Copyright (C) 2008-2022 The Magit Project Contributors
+
+;; Author: Jonas Bernoulli <jonas@bernoul.li>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+
+;; SPDX-License-Identifier: GPL-3.0-or-later
+
+;; Magit 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.
+;;
+;; Magit 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 Magit. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This library implements support for looking at Git diffs and
+;; commits.
+
+;;; Code:
+
+(require 'magit-core)
+(require 'git-commit)
+
+(eval-when-compile (require 'ansi-color))
+(require 'diff-mode)
+(require 'image)
+(require 'smerge-mode)
+
+;; For `magit-diff-popup'
+(declare-function magit-stash-show "magit-stash" (stash &optional args files))
+;; For `magit-diff-visit-file'
+(declare-function magit-find-file-noselect "magit-files" (rev file))
+(declare-function magit-status-setup-buffer "magit-status" (&optional directory))
+;; For `magit-diff-while-committing'
+(declare-function magit-commit-message-buffer "magit-commit" ())
+;; For `magit-insert-revision-gravatar'
+(defvar gravatar-size)
+;; For `magit-show-commit' and `magit-diff-show-or-scroll'
+(declare-function magit-current-blame-chunk "magit-blame" (&optional type noerror))
+(declare-function magit-blame-mode "magit-blame" (&optional arg))
+(defvar magit-blame-mode)
+;; For `magit-diff-show-or-scroll'
+(declare-function git-rebase-current-line "git-rebase" ())
+;; For `magit-diff-unmerged'
+(declare-function magit-merge-in-progress-p "magit-merge" ())
+(declare-function magit--merge-range "magit-merge" (&optional head))
+;; For `magit-diff--dwim'
+(declare-function forge--pullreq-range "forge-pullreq"
+ (pullreq &optional endpoints))
+(declare-function forge--pullreq-ref "forge-pullreq" (pullreq))
+;; For `magit-diff-wash-diff'
+(declare-function ansi-color-apply-on-region "ansi-color")
+;; For `magit-diff-wash-submodule'
+(declare-function magit-log-wash-log "magit-log" (style args))
+;; For keymaps and menus
+(declare-function magit-apply "magit-apply" (&rest args))
+(declare-function magit-stage "magit-apply" (&optional indent))
+(declare-function magit-unstage "magit-apply" ())
+(declare-function magit-discard "magit-apply" ())
+(declare-function magit-reverse "magit-apply" (&rest args))
+(declare-function magit-file-rename "magit-files" (file newname))
+(declare-function magit-file-untrack "magit-files" (files &optional force))
+(declare-function magit-commit-add-log "magit-commit" ())
+(declare-function magit-diff-trace-definition "magit-log" ())
+(declare-function magit-patch-save "magit-patch" (files &optional arg))
+(declare-function magit-do-async-shell-command "magit-extras" (file))
+(declare-function magit-add-change-log-entry "magit-extras"
+ (&optional whoami file-name other-window))
+(declare-function magit-add-change-log-entry-other-window "magit-extras"
+ (&optional whoami file-name))
+(declare-function magit-diff-edit-hunk-commit "magit-extras" (file))
+(declare-function magit-smerge-keep-current "magit-apply" ())
+(declare-function magit-smerge-keep-upper "magit-apply" ())
+(declare-function magit-smerge-keep-base "magit-apply" ())
+(declare-function magit-smerge-keep-lower "magit-apply" ())
+
+(eval-when-compile
+ (cl-pushnew 'orig-rev eieio--known-slot-names)
+ (cl-pushnew 'action-type eieio--known-slot-names)
+ (cl-pushnew 'target eieio--known-slot-names))
+
+;;; Options
+;;;; Diff Mode
+
+(defgroup magit-diff nil
+ "Inspect and manipulate Git diffs."
+ :link '(info-link "(magit)Diffing")
+ :group 'magit-commands
+ :group 'magit-modes)
+
+(defcustom magit-diff-mode-hook nil
+ "Hook run after entering Magit-Diff mode."
+ :group 'magit-diff
+ :type 'hook)
+
+(defcustom magit-diff-sections-hook
+ '(magit-insert-diff
+ magit-insert-xref-buttons)
+ "Hook run to insert sections into a `magit-diff-mode' buffer."
+ :package-version '(magit . "2.3.0")
+ :group 'magit-diff
+ :type 'hook)
+
+(defcustom magit-diff-expansion-threshold 60
+ "After how many seconds not to expand anymore diffs.
+
+Except in status buffers, diffs usually start out fully expanded.
+Because that can take a long time, all diffs that haven't been
+fontified during a refresh before the threshold defined here are
+instead displayed with their bodies collapsed.
+
+Note that this can cause sections that were previously expanded
+to be collapsed. So you should not pick a very low value here.
+
+The hook function `magit-diff-expansion-threshold' has to be a
+member of `magit-section-set-visibility-hook' for this option
+to have any effect."
+ :package-version '(magit . "2.9.0")
+ :group 'magit-diff
+ :type 'float)
+
+(defcustom magit-diff-highlight-hunk-body t
+ "Whether to highlight bodies of selected hunk sections.
+This only has an effect if `magit-diff-highlight' is a
+member of `magit-section-highlight-hook', which see."
+ :package-version '(magit . "2.1.0")
+ :group 'magit-diff
+ :type 'boolean)
+
+(defcustom magit-diff-highlight-hunk-region-functions
+ '(magit-diff-highlight-hunk-region-dim-outside
+ magit-diff-highlight-hunk-region-using-overlays)
+ "The functions used to highlight the hunk-internal region.
+
+`magit-diff-highlight-hunk-region-dim-outside' overlays the outside
+of the hunk internal selection with a face that causes the added and
+removed lines to have the same background color as context lines.
+This function should not be removed from the value of this option.
+
+`magit-diff-highlight-hunk-region-using-overlays' and
+`magit-diff-highlight-hunk-region-using-underline' emphasize the
+region by placing delimiting horizontal lines before and after it.
+The underline variant was implemented because Eli said that is
+how we should do it. However the overlay variant actually works
+better. Also see https://github.com/magit/magit/issues/2758.
+
+Instead of, or in addition to, using delimiting horizontal lines,
+to emphasize the boundaries, you may wish to emphasize the text
+itself, using `magit-diff-highlight-hunk-region-using-face'.
+
+In terminal frames it's not possible to draw lines as the overlay
+and underline variants normally do, so there they fall back to
+calling the face function instead."
+ :package-version '(magit . "2.9.0")
+ :set-after '(magit-diff-show-lines-boundaries)
+ :group 'magit-diff
+ :type 'hook
+ :options '(magit-diff-highlight-hunk-region-dim-outside
+ magit-diff-highlight-hunk-region-using-underline
+ magit-diff-highlight-hunk-region-using-overlays
+ magit-diff-highlight-hunk-region-using-face))
+
+(defcustom magit-diff-unmarked-lines-keep-foreground t
+ "Whether `magit-diff-highlight-hunk-region-dim-outside' preserves foreground.
+When this is set to nil, then that function only adjusts the
+foreground color but added and removed lines outside the region
+keep their distinct foreground colors."
+ :package-version '(magit . "2.9.0")
+ :group 'magit-diff
+ :type 'boolean)
+
+(defcustom magit-diff-refine-hunk nil
+ "Whether to show word-granularity differences within diff hunks.
+
+nil Never show fine differences.
+t Show fine differences for the current diff hunk only.
+`all' Show fine differences for all displayed diff hunks."
+ :group 'magit-diff
+ :safe (lambda (val) (memq val '(nil t all)))
+ :type '(choice (const :tag "Never" nil)
+ (const :tag "Current" t)
+ (const :tag "All" all)))
+
+(defcustom magit-diff-refine-ignore-whitespace smerge-refine-ignore-whitespace
+ "Whether to ignore whitespace changes in word-granularity differences."
+ :package-version '(magit . "3.0.0")
+ :set-after '(smerge-refine-ignore-whitespace)
+ :group 'magit-diff
+ :safe 'booleanp
+ :type 'boolean)
+
+(put 'magit-diff-refine-hunk 'permanent-local t)
+
+(defcustom magit-diff-adjust-tab-width nil
+ "Whether to adjust the width of tabs in diffs.
+
+Determining the correct width can be expensive if it requires
+opening large and/or many files, so the widths are cached in
+the variable `magit-diff--tab-width-cache'. Set that to nil
+to invalidate the cache.
+
+nil Never adjust tab width. Use `tab-width's value from
+ the Magit buffer itself instead.
+
+t If the corresponding file-visiting buffer exits, then
+ use `tab-width's value from that buffer. Doing this is
+ cheap, so this value is used even if a corresponding
+ cache entry exists.
+
+`always' If there is no such buffer, then temporarily visit the
+ file to determine the value.
+
+NUMBER Like `always', but don't visit files larger than NUMBER
+ bytes."
+ :package-version '(magit . "2.12.0")
+ :group 'magit-diff
+ :type '(choice (const :tag "Never" nil)
+ (const :tag "If file-visiting buffer exists" t)
+ (integer :tag "If file isn't larger than N bytes")
+ (const :tag "Always" always)))
+
+(defcustom magit-diff-paint-whitespace t
+ "Specify where to highlight whitespace errors.
+
+nil Never highlight whitespace errors.
+t Highlight whitespace errors everywhere.
+`uncommitted' Only highlight whitespace errors in diffs
+ showing uncommitted changes.
+
+For backward compatibility `status' is treated as a synonym
+for `uncommitted'.
+
+The option `magit-diff-paint-whitespace-lines' controls for
+what lines (added/remove/context) errors are highlighted.
+
+The options `magit-diff-highlight-trailing' and
+`magit-diff-highlight-indentation' control what kind of
+whitespace errors are highlighted."
+ :group 'magit-diff
+ :safe (lambda (val) (memq val '(t nil uncommitted status)))
+ :type '(choice (const :tag "In all diffs" t)
+ (const :tag "Only in uncommitted changes" uncommitted)
+ (const :tag "Never" nil)))
+
+(defcustom magit-diff-paint-whitespace-lines t
+ "Specify in what kind of lines to highlight whitespace errors.
+
+t Highlight only in added lines.
+`both' Highlight in added and removed lines.
+`all' Highlight in added, removed and context lines."
+ :package-version '(magit . "3.0.0")
+ :group 'magit-diff
+ :safe (lambda (val) (memq val '(t both all)))
+ :type '(choice (const :tag "in added lines" t)
+ (const :tag "in added and removed lines" both)
+ (const :tag "in added, removed and context lines" all)))
+
+(defcustom magit-diff-highlight-trailing t
+ "Whether to highlight whitespace at the end of a line in diffs.
+Used only when `magit-diff-paint-whitespace' is non-nil."
+ :group 'magit-diff
+ :safe 'booleanp
+ :type 'boolean)
+
+(defcustom magit-diff-highlight-indentation nil
+ "Highlight the \"wrong\" indentation style.
+Used only when `magit-diff-paint-whitespace' is non-nil.
+
+The value is an alist of the form ((REGEXP . INDENT)...). The
+path to the current repository is matched against each element
+in reverse order. Therefore if a REGEXP matches, then earlier
+elements are not tried.
+
+If the used INDENT is `tabs', highlight indentation with tabs.
+If INDENT is an integer, highlight indentation with at least
+that many spaces. Otherwise, highlight neither."
+ :group 'magit-diff
+ :type `(repeat (cons (string :tag "Directory regexp")
+ (choice (const :tag "Tabs" tabs)
+ (integer :tag "Spaces" :value ,tab-width)
+ (const :tag "Neither" nil)))))
+
+(defcustom magit-diff-hide-trailing-cr-characters
+ (and (memq system-type '(ms-dos windows-nt)) t)
+ "Whether to hide ^M characters at the end of a line in diffs."
+ :package-version '(magit . "2.6.0")
+ :group 'magit-diff
+ :type 'boolean)
+
+(defcustom magit-diff-highlight-keywords t
+ "Whether to highlight bracketed keywords in commit messages."
+ :package-version '(magit . "2.12.0")
+ :group 'magit-diff
+ :type 'boolean)
+
+(defcustom magit-diff-extra-stat-arguments nil
+ "Additional arguments to be used alongside `--stat'.
+
+A list of zero or more arguments or a function that takes no
+argument and returns such a list. These arguments are allowed
+here: `--stat-width', `--stat-name-width', `--stat-graph-width'
+and `--compact-summary'. See the git-diff(1) manpage."
+ :package-version '(magit . "3.0.0")
+ :group 'magit-diff
+ :type '(radio (function-item magit-diff-use-window-width-as-stat-width)
+ function
+ (list string)
+ (const :tag "None" nil)))
+
+;;;; File Diff
+
+(defcustom magit-diff-buffer-file-locked t
+ "Whether `magit-diff-buffer-file' uses a dedicated buffer."
+ :package-version '(magit . "2.7.0")
+ :group 'magit-commands
+ :group 'magit-diff
+ :type 'boolean)
+
+;;;; Revision Mode
+
+(defgroup magit-revision nil
+ "Inspect and manipulate Git commits."
+ :link '(info-link "(magit)Revision Buffer")
+ :group 'magit-modes)
+
+(defcustom magit-revision-mode-hook
+ '(bug-reference-mode
+ goto-address-mode)
+ "Hook run after entering Magit-Revision mode."
+ :group 'magit-revision
+ :type 'hook
+ :options '(bug-reference-mode
+ goto-address-mode))
+
+(defcustom magit-revision-sections-hook
+ '(magit-insert-revision-tag
+ magit-insert-revision-headers
+ magit-insert-revision-message
+ magit-insert-revision-notes
+ magit-insert-revision-diff
+ magit-insert-xref-buttons)
+ "Hook run to insert sections into a `magit-revision-mode' buffer."
+ :package-version '(magit . "2.3.0")
+ :group 'magit-revision
+ :type 'hook)
+
+(defcustom magit-revision-headers-format "\
+Author: %aN <%aE>
+AuthorDate: %ad
+Commit: %cN <%cE>
+CommitDate: %cd
+"
+ "Format string used to insert headers in revision buffers.
+
+All headers in revision buffers are inserted by the section
+inserter `magit-insert-revision-headers'. Some of the headers
+are created by calling `git show --format=FORMAT' where FORMAT
+is the format specified here. Other headers are hard coded or
+subject to option `magit-revision-insert-related-refs'."
+ :package-version '(magit . "2.3.0")
+ :group 'magit-revision
+ :type 'string)
+
+(defcustom magit-revision-insert-related-refs t
+ "Whether to show related branches in revision buffers
+
+`nil' Don't show any related branches.
+`t' Show related local branches.
+`all' Show related local and remote branches.
+`mixed' Show all containing branches and local merged branches."
+ :package-version '(magit . "2.1.0")
+ :group 'magit-revision
+ :type '(choice (const :tag "don't" nil)
+ (const :tag "local only" t)
+ (const :tag "all related" all)
+ (const :tag "all containing, local merged" mixed)))
+
+(defcustom magit-revision-use-hash-sections 'quicker
+ "Whether to turn hashes inside the commit message into sections.
+
+If non-nil, then hashes inside the commit message are turned into
+`commit' sections. There is a trade off to be made between
+performance and reliability:
+
+- `slow' calls git for every word to be absolutely sure.
+- `quick' skips words less than seven characters long.
+- `quicker' additionally skips words that don't contain a number.
+- `quickest' uses all words that are at least seven characters
+ long and which contain at least one number as well as at least
+ one letter.
+
+If nil, then no hashes are turned into sections, but you can
+still visit the commit at point using \"RET\"."
+ :package-version '(magit . "2.12.0")
+ :group 'magit-revision
+ :type '(choice (const :tag "Use sections, quickest" quickest)
+ (const :tag "Use sections, quicker" quicker)
+ (const :tag "Use sections, quick" quick)
+ (const :tag "Use sections, slow" slow)
+ (const :tag "Don't use sections" nil)))
+
+(defcustom magit-revision-show-gravatars nil
+ "Whether to show gravatar images in revision buffers.
+
+If nil, then don't insert any gravatar images. If t, then insert
+both images. If `author' or `committer', then insert only the
+respective image.
+
+If you have customized the option `magit-revision-header-format'
+and want to insert the images then you might also have to specify
+where to do so. In that case the value has to be a cons-cell of
+two regular expressions. The car specifies where to insert the
+author's image. The top half of the image is inserted right
+after the matched text, the bottom half on the next line in the
+same column. The cdr specifies where to insert the committer's
+image, accordingly. Either the car or the cdr may be nil."
+ :package-version '(magit . "2.3.0")
+ :group 'magit-revision
+ :type '(choice (const :tag "Don't show gravatars" nil)
+ (const :tag "Show gravatars" t)
+ (const :tag "Show author gravatar" author)
+ (const :tag "Show committer gravatar" committer)
+ (cons :tag "Show gravatars using custom pattern."
+ (regexp :tag "Author regexp" "^Author: ")
+ (regexp :tag "Committer regexp" "^Commit: "))))
+
+(defcustom magit-revision-use-gravatar-kludge nil
+ "Whether to work around a bug which affects display of gravatars.
+
+Gravatar images are spliced into two halves which are then
+displayed on separate lines. On OS X the splicing has a bug in
+some Emacs builds, which causes the top and bottom halves to be
+interchanged. Enabling this option works around this issue by
+interchanging the halves once more, which cancels out the effect
+of the bug.
+
+See https://github.com/magit/magit/issues/2265
+and https://debbugs.gnu.org/cgi/bugreport.cgi?bug=7847.
+
+Starting with Emacs 26.1 this kludge should not be required for
+any build."
+ :package-version '(magit . "2.3.0")
+ :group 'magit-revision
+ :type 'boolean)
+
+(defcustom magit-revision-fill-summary-line nil
+ "Whether to fill excessively long summary lines.
+
+If this is an integer, then the summary line is filled if it is
+longer than either the limit specified here or `window-width'.
+
+You may want to only set this locally in \".dir-locals-2.el\" for
+repositories known to contain bad commit messages.
+
+The body of the message is left alone because (a) most people who
+write excessively long summary lines usually don't add a body and
+(b) even people who have the decency to wrap their lines may have
+a good reason to include a long line in the body sometimes."
+ :package-version '(magit . "2.90.0")
+ :group 'magit-revision
+ :type '(choice (const :tag "Don't fill" nil)
+ (integer :tag "Fill if longer than")))
+
+(defcustom magit-revision-filter-files-on-follow nil
+ "Whether to honor file filter if log arguments include --follow.
+
+When a commit is displayed from a log buffer, the resulting
+revision buffer usually shares the log's file arguments,
+restricting the diff to those files. However, there's a
+complication when the log arguments include --follow: if the log
+follows a file across a rename event, keeping the file
+restriction would mean showing an empty diff in revision buffers
+for commits before the rename event.
+
+When this option is nil, the revision buffer ignores the log's
+filter if the log arguments include --follow. If non-nil, the
+log's file filter is always honored."
+ :package-version '(magit . "3.0.0")
+ :group 'magit-revision
+ :type 'boolean)
+
+;;;; Visit Commands
+
+(defcustom magit-diff-visit-previous-blob t
+ "Whether `magit-diff-visit-file' may visit the previous blob.
+
+When this is t and point is on a removed line in a diff for a
+committed change, then `magit-diff-visit-file' visits the blob
+from the last revision which still had that line.
+
+Currently this is only supported for committed changes, for
+staged and unstaged changes `magit-diff-visit-file' always
+visits the file in the working tree."
+ :package-version '(magit . "2.9.0")
+ :group 'magit-diff
+ :type 'boolean)
+
+(defcustom magit-diff-visit-avoid-head-blob nil
+ "Whether `magit-diff-visit-file' avoids visiting a blob from `HEAD'.
+
+By default `magit-diff-visit-file' always visits the blob that
+added the current line, while `magit-diff-visit-worktree-file'
+visits the respective file in the working tree. For the `HEAD'
+commit, the former command used to visit the worktree file too,
+but that made it impossible to visit a blob from `HEAD'.
+
+When point is on a removed line and that change has not been
+committed yet, then `magit-diff-visit-file' now visits the last
+blob that still had that line, which is a blob from `HEAD'.
+Previously this function used to visit the worktree file not
+only for added lines but also for such removed lines.
+
+If you prefer the old behaviors, then set this to t."
+ :package-version '(magit . "3.0.0")
+ :group 'magit-diff
+ :type 'boolean)
+
+;;; Faces
+
+(defface magit-diff-file-heading
+ `((t ,@(and (>= emacs-major-version 27) '(:extend t))
+ :weight bold))
+ "Face for diff file headings."
+ :group 'magit-faces)
+
+(defface magit-diff-file-heading-highlight
+ `((t ,@(and (>= emacs-major-version 27) '(:extend t))
+ :inherit magit-section-highlight))
+ "Face for current diff file headings."
+ :group 'magit-faces)
+
+(defface magit-diff-file-heading-selection
+ `((((class color) (background light))
+ ,@(and (>= emacs-major-version 27) '(:extend t))
+ :inherit magit-diff-file-heading-highlight
+ :foreground "salmon4")
+ (((class color) (background dark))
+ ,@(and (>= emacs-major-version 27) '(:extend t))
+ :inherit magit-diff-file-heading-highlight
+ :foreground "LightSalmon3"))
+ "Face for selected diff file headings."
+ :group 'magit-faces)
+
+(defface magit-diff-hunk-heading
+ `((((class color) (background light))
+ ,@(and (>= emacs-major-version 27) '(:extend t))
+ :background "grey90"
+ :foreground "grey20")
+ (((class color) (background dark))
+ ,@(and (>= emacs-major-version 27) '(:extend t))
+ :background "grey25"
+ :foreground "grey95"))
+ "Face for diff hunk headings."
+ :group 'magit-faces)
+
+(defface magit-diff-hunk-heading-highlight
+ `((((class color) (background light))
+ ,@(and (>= emacs-major-version 27) '(:extend t))
+ :background "grey80"
+ :foreground "grey20")
+ (((class color) (background dark))
+ ,@(and (>= emacs-major-version 27) '(:extend t))
+ :background "grey35"
+ :foreground "grey95"))
+ "Face for current diff hunk headings."
+ :group 'magit-faces)
+
+(defface magit-diff-hunk-heading-selection
+ `((((class color) (background light))
+ ,@(and (>= emacs-major-version 27) '(:extend t))
+ :inherit magit-diff-hunk-heading-highlight
+ :foreground "salmon4")
+ (((class color) (background dark))
+ ,@(and (>= emacs-major-version 27) '(:extend t))
+ :inherit magit-diff-hunk-heading-highlight
+ :foreground "LightSalmon3"))
+ "Face for selected diff hunk headings."
+ :group 'magit-faces)
+
+(defface magit-diff-hunk-region
+ `((t :inherit bold
+ ,@(and (>= emacs-major-version 27)
+ (list :extend (ignore-errors (face-attribute 'region :extend))))))
+ "Face used by `magit-diff-highlight-hunk-region-using-face'.
+
+This face is overlaid over text that uses other hunk faces,
+and those normally set the foreground and background colors.
+The `:foreground' and especially the `:background' properties
+should be avoided here. Setting the latter would cause the
+loss of information. Good properties to set here are `:weight'
+and `:slant'."
+ :group 'magit-faces)
+
+(defface magit-diff-revision-summary
+ '((t :inherit magit-diff-hunk-heading))
+ "Face for commit message summaries."
+ :group 'magit-faces)
+
+(defface magit-diff-revision-summary-highlight
+ '((t :inherit magit-diff-hunk-heading-highlight))
+ "Face for highlighted commit message summaries."
+ :group 'magit-faces)
+
+(defface magit-diff-lines-heading
+ `((((class color) (background light))
+ ,@(and (>= emacs-major-version 27) '(:extend t))
+ :inherit magit-diff-hunk-heading-highlight
+ :background "LightSalmon3")
+ (((class color) (background dark))
+ ,@(and (>= emacs-major-version 27) '(:extend t))
+ :inherit magit-diff-hunk-heading-highlight
+ :foreground "grey80"
+ :background "salmon4"))
+ "Face for diff hunk heading when lines are marked."
+ :group 'magit-faces)
+
+(defface magit-diff-lines-boundary
+ `((t ,@(and (>= emacs-major-version 27) '(:extend t)) ; !important
+ :inherit magit-diff-lines-heading))
+ "Face for boundary of marked lines in diff hunk."
+ :group 'magit-faces)
+
+(defface magit-diff-conflict-heading
+ '((t :inherit magit-diff-hunk-heading))
+ "Face for conflict markers."
+ :group 'magit-faces)
+
+(defface magit-diff-added
+ `((((class color) (background light))
+ ,@(and (>= emacs-major-version 27) '(:extend t))
+ :background "#ddffdd"
+ :foreground "#22aa22")
+ (((class color) (background dark))
+ ,@(and (>= emacs-major-version 27) '(:extend t))
+ :background "#335533"
+ :foreground "#ddffdd"))
+ "Face for lines in a diff that have been added."
+ :group 'magit-faces)
+
+(defface magit-diff-removed
+ `((((class color) (background light))
+ ,@(and (>= emacs-major-version 27) '(:extend t))
+ :background "#ffdddd"
+ :foreground "#aa2222")
+ (((class color) (background dark))
+ ,@(and (>= emacs-major-version 27) '(:extend t))
+ :background "#553333"
+ :foreground "#ffdddd"))
+ "Face for lines in a diff that have been removed."
+ :group 'magit-faces)
+
+(defface magit-diff-our
+ '((t :inherit magit-diff-removed))
+ "Face for lines in a diff for our side in a conflict."
+ :group 'magit-faces)
+
+(defface magit-diff-base
+ `((((class color) (background light))
+ ,@(and (>= emacs-major-version 27) '(:extend t))
+ :background "#ffffcc"
+ :foreground "#aaaa11")
+ (((class color) (background dark))
+ ,@(and (>= emacs-major-version 27) '(:extend t))
+ :background "#555522"
+ :foreground "#ffffcc"))
+ "Face for lines in a diff for the base side in a conflict."
+ :group 'magit-faces)
+
+(defface magit-diff-their
+ '((t :inherit magit-diff-added))
+ "Face for lines in a diff for their side in a conflict."
+ :group 'magit-faces)
+
+(defface magit-diff-context
+ `((((class color) (background light))
+ ,@(and (>= emacs-major-version 27) '(:extend t))
+ :foreground "grey50")
+ (((class color) (background dark))
+ ,@(and (>= emacs-major-version 27) '(:extend t))
+ :foreground "grey70"))
+ "Face for lines in a diff that are unchanged."
+ :group 'magit-faces)
+
+(defface magit-diff-added-highlight
+ `((((class color) (background light))
+ ,@(and (>= emacs-major-version 27) '(:extend t))
+ :background "#cceecc"
+ :foreground "#22aa22")
+ (((class color) (background dark))
+ ,@(and (>= emacs-major-version 27) '(:extend t))
+ :background "#336633"
+ :foreground "#cceecc"))
+ "Face for lines in a diff that have been added."
+ :group 'magit-faces)
+
+(defface magit-diff-removed-highlight
+ `((((class color) (background light))
+ ,@(and (>= emacs-major-version 27) '(:extend t))
+ :background "#eecccc"
+ :foreground "#aa2222")
+ (((class color) (background dark))
+ ,@(and (>= emacs-major-version 27) '(:extend t))
+ :background "#663333"
+ :foreground "#eecccc"))
+ "Face for lines in a diff that have been removed."
+ :group 'magit-faces)
+
+(defface magit-diff-our-highlight
+ '((t :inherit magit-diff-removed-highlight))
+ "Face for lines in a diff for our side in a conflict."
+ :group 'magit-faces)
+
+(defface magit-diff-base-highlight
+ `((((class color) (background light))
+ ,@(and (>= emacs-major-version 27) '(:extend t))
+ :background "#eeeebb"
+ :foreground "#aaaa11")
+ (((class color) (background dark))
+ ,@(and (>= emacs-major-version 27) '(:extend t))
+ :background "#666622"
+ :foreground "#eeeebb"))
+ "Face for lines in a diff for the base side in a conflict."
+ :group 'magit-faces)
+
+(defface magit-diff-their-highlight
+ '((t :inherit magit-diff-added-highlight))
+ "Face for lines in a diff for their side in a conflict."
+ :group 'magit-faces)
+
+(defface magit-diff-context-highlight
+ `((((class color) (background light))
+ ,@(and (>= emacs-major-version 27) '(:extend t))
+ :background "grey95"
+ :foreground "grey50")
+ (((class color) (background dark))
+ ,@(and (>= emacs-major-version 27) '(:extend t))
+ :background "grey20"
+ :foreground "grey70"))
+ "Face for lines in the current context in a diff."
+ :group 'magit-faces)
+
+(defface magit-diff-whitespace-warning
+ '((t :inherit trailing-whitespace))
+ "Face for highlighting whitespace errors added lines."
+ :group 'magit-faces)
+
+(defface magit-diffstat-added
+ '((((class color) (background light)) :foreground "#22aa22")
+ (((class color) (background dark)) :foreground "#448844"))
+ "Face for plus sign in diffstat."
+ :group 'magit-faces)
+
+(defface magit-diffstat-removed
+ '((((class color) (background light)) :foreground "#aa2222")
+ (((class color) (background dark)) :foreground "#aa4444"))
+ "Face for minus sign in diffstat."
+ :group 'magit-faces)
+
+;;; Arguments
+;;;; Prefix Classes
+
+(defclass magit-diff-prefix (transient-prefix)
+ ((history-key :initform 'magit-diff)
+ (major-mode :initform 'magit-diff-mode)))
+
+(defclass magit-diff-refresh-prefix (magit-diff-prefix)
+ ((history-key :initform 'magit-diff)
+ (major-mode :initform nil)))
+
+;;;; Prefix Methods
+
+(cl-defmethod transient-init-value ((obj magit-diff-prefix))
+ (pcase-let ((`(,args ,files)
+ (magit-diff--get-value 'magit-diff-mode
+ magit-prefix-use-buffer-arguments)))
+ (unless (eq transient-current-command 'magit-dispatch)
+ (when-let ((file (magit-file-relative-name)))
+ (setq files (list file))))
+ (oset obj value (if files `(("--" ,@files) ,args) args))))
+
+(cl-defmethod transient-init-value ((obj magit-diff-refresh-prefix))
+ (oset obj value (if magit-buffer-diff-files
+ `(("--" ,@magit-buffer-diff-files)
+ ,magit-buffer-diff-args)
+ magit-buffer-diff-args)))
+
+(cl-defmethod transient-set-value ((obj magit-diff-prefix))
+ (magit-diff--set-value obj))
+
+(cl-defmethod transient-save-value ((obj magit-diff-prefix))
+ (magit-diff--set-value obj 'save))
+
+;;;; Argument Access
+
+(defun magit-diff-arguments (&optional mode)
+ "Return the current diff arguments."
+ (if (memq transient-current-command '(magit-diff magit-diff-refresh))
+ (pcase-let ((`(,args ,alist)
+ (-separate #'atom (transient-get-value))))
+ (list args (cdr (assoc "--" alist))))
+ (magit-diff--get-value (or mode 'magit-diff-mode))))
+
+(defun magit-diff--get-value (mode &optional use-buffer-args)
+ (unless use-buffer-args
+ (setq use-buffer-args magit-direct-use-buffer-arguments))
+ (let (args files)
+ (cond
+ ((and (memq use-buffer-args '(always selected current))
+ (eq major-mode mode))
+ (setq args magit-buffer-diff-args)
+ (setq files magit-buffer-diff-files))
+ ((and (memq use-buffer-args '(always selected))
+ (when-let ((buffer (magit-get-mode-buffer
+ mode nil
+ (eq use-buffer-args 'selected))))
+ (setq args (buffer-local-value 'magit-buffer-diff-args buffer))
+ (setq files (buffer-local-value 'magit-buffer-diff-files buffer))
+ t)))
+ ((plist-member (symbol-plist mode) 'magit-diff-current-arguments)
+ (setq args (get mode 'magit-diff-current-arguments)))
+ ((when-let ((elt (assq (intern (format "magit-diff:%s" mode))
+ transient-values)))
+ (setq args (cdr elt))
+ t))
+ (t
+ (setq args (get mode 'magit-diff-default-arguments))))
+ (list args files)))
+
+(defun magit-diff--set-value (obj &optional save)
+ (pcase-let* ((obj (oref obj prototype))
+ (mode (or (oref obj major-mode) major-mode))
+ (key (intern (format "magit-diff:%s" mode)))
+ (`(,args ,alist)
+ (-separate #'atom (transient-get-value)))
+ (files (cdr (assoc "--" alist))))
+ (put mode 'magit-diff-current-arguments args)
+ (when save
+ (setf (alist-get key transient-values) args)
+ (transient-save-values))
+ (transient--history-push obj)
+ (setq magit-buffer-diff-args args)
+ (setq magit-buffer-diff-files files)
+ (magit-refresh)))
+
+;;; Commands
+;;;; Prefix Commands
+
+;;;###autoload (autoload 'magit-diff "magit-diff" nil t)
+(transient-define-prefix magit-diff ()
+ "Show changes between different versions."
+ :man-page "git-diff"
+ :class 'magit-diff-prefix
+ ["Limit arguments"
+ (magit:--)
+ (magit-diff:--ignore-submodules)
+ ("-b" "Ignore whitespace changes" ("-b" "--ignore-space-change"))
+ ("-w" "Ignore all whitespace" ("-w" "--ignore-all-space"))
+ (5 "-D" "Omit preimage for deletes" ("-D" "--irreversible-delete"))]
+ ["Context arguments"
+ (magit-diff:-U)
+ ("-W" "Show surrounding functions" ("-W" "--function-context"))]
+ ["Tune arguments"
+ (magit-diff:--diff-algorithm)
+ (magit-diff:-M)
+ (magit-diff:-C)
+ ("-x" "Disallow external diff drivers" "--no-ext-diff")
+ ("-s" "Show stats" "--stat")
+ ("=g" "Show signature" "--show-signature")
+ (5 "-R" "Reverse sides" "-R")
+ (5 magit-diff:--color-moved)
+ (5 magit-diff:--color-moved-ws)]
+ ["Actions"
+ [("d" "Dwim" magit-diff-dwim)
+ ("r" "Diff range" magit-diff-range)
+ ("p" "Diff paths" magit-diff-paths)]
+ [("u" "Diff unstaged" magit-diff-unstaged)
+ ("s" "Diff staged" magit-diff-staged)
+ ("w" "Diff worktree" magit-diff-working-tree)]
+ [("c" "Show commit" magit-show-commit)
+ ("t" "Show stash" magit-stash-show)]])
+
+;;;###autoload (autoload 'magit-diff-refresh "magit-diff" nil t)
+(transient-define-prefix magit-diff-refresh ()
+ "Change the arguments used for the diff(s) in the current buffer."
+ :man-page "git-diff"
+ :class 'magit-diff-refresh-prefix
+ ["Limit arguments"
+ (magit:--)
+ (magit-diff:--ignore-submodules)
+ ("-b" "Ignore whitespace changes" ("-b" "--ignore-space-change"))
+ ("-w" "Ignore all whitespace" ("-w" "--ignore-all-space"))
+ (5 "-D" "Omit preimage for deletes" ("-D" "--irreversible-delete"))]
+ ["Context arguments"
+ (magit-diff:-U)
+ ("-W" "Show surrounding functions" ("-W" "--function-context"))]
+ ["Tune arguments"
+ (magit-diff:--diff-algorithm)
+ (magit-diff:-M)
+ (magit-diff:-C)
+ ("-x" "Disallow external diff drivers" "--no-ext-diff")
+ ("-s" "Show stats" "--stat"
+ :if-derived magit-diff-mode)
+ ("=g" "Show signature" "--show-signature"
+ :if-derived magit-diff-mode)
+ (5 "-R" "Reverse sides" "-R"
+ :if-derived magit-diff-mode)
+ (5 magit-diff:--color-moved)
+ (5 magit-diff:--color-moved-ws)]
+ [["Refresh"
+ ("g" "buffer" magit-diff-refresh)
+ ("s" "buffer and set defaults" transient-set :transient nil)
+ ("w" "buffer and save defaults" transient-save :transient nil)]
+ ["Toggle"
+ ("t" "hunk refinement" magit-diff-toggle-refine-hunk)
+ ("F" "file filter" magit-diff-toggle-file-filter)
+ ("b" "buffer lock" magit-toggle-buffer-lock
+ :if-mode (magit-diff-mode magit-revision-mode magit-stash-mode))]
+ [:if-mode magit-diff-mode
+ :description "Do"
+ ("r" "switch range type" magit-diff-switch-range-type)
+ ("f" "flip revisions" magit-diff-flip-revs)]]
+ (interactive)
+ (if (not (eq transient-current-command 'magit-diff-refresh))
+ (transient-setup 'magit-diff-refresh)
+ (pcase-let ((`(,args ,files) (magit-diff-arguments)))
+ (setq magit-buffer-diff-args args)
+ (setq magit-buffer-diff-files files))
+ (magit-refresh)))
+
+;;;; Infix Commands
+
+(transient-define-argument magit:-- ()
+ :description "Limit to files"
+ :class 'transient-files
+ :key "--"
+ :argument "--"
+ :prompt "Limit to file,s: "
+ :reader #'magit-read-files
+ :multi-value t)
+
+(defun magit-read-files (prompt initial-input history &optional list-fn)
+ (magit-completing-read-multiple* prompt
+ (funcall (or list-fn #'magit-list-files))
+ nil nil
+ (or initial-input (magit-file-at-point))
+ history))
+
+(transient-define-argument magit-diff:-U ()
+ :description "Context lines"
+ :class 'transient-option
+ :argument "-U"
+ :reader #'transient-read-number-N0)
+
+(transient-define-argument magit-diff:-M ()
+ :description "Detect renames"
+ :class 'transient-option
+ :argument "-M"
+ :allow-empty t
+ :reader #'transient-read-number-N+)
+
+(transient-define-argument magit-diff:-C ()
+ :description "Detect copies"
+ :class 'transient-option
+ :argument "-C"
+ :allow-empty t
+ :reader #'transient-read-number-N+)
+
+(transient-define-argument magit-diff:--diff-algorithm ()
+ :description "Diff algorithm"
+ :class 'transient-option
+ :key "-A"
+ :argument "--diff-algorithm="
+ :reader #'magit-diff-select-algorithm)
+
+(defun magit-diff-select-algorithm (&rest _ignore)
+ (magit-read-char-case nil t
+ (?d "[d]efault" "default")
+ (?m "[m]inimal" "minimal")
+ (?p "[p]atience" "patience")
+ (?h "[h]istogram" "histogram")))
+
+(transient-define-argument magit-diff:--ignore-submodules ()
+ :description "Ignore submodules"
+ :class 'transient-option
+ :key "-i"
+ :argument "--ignore-submodules="
+ :reader #'magit-diff-select-ignore-submodules)
+
+(defun magit-diff-select-ignore-submodules (&rest _ignored)
+ (magit-read-char-case "Ignore submodules " t
+ (?u "[u]ntracked" "untracked")
+ (?d "[d]irty" "dirty")
+ (?a "[a]ll" "all")))
+
+(transient-define-argument magit-diff:--color-moved ()
+ :description "Color moved lines"
+ :class 'transient-option
+ :key "-m"
+ :argument "--color-moved="
+ :reader #'magit-diff-select-color-moved-mode)
+
+(defun magit-diff-select-color-moved-mode (&rest _ignore)
+ (magit-read-char-case "Color moved " t
+ (?d "[d]efault" "default")
+ (?p "[p]lain" "plain")
+ (?b "[b]locks" "blocks")
+ (?z "[z]ebra" "zebra")
+ (?Z "[Z] dimmed-zebra" "dimmed-zebra")))
+
+(transient-define-argument magit-diff:--color-moved-ws ()
+ :description "Whitespace treatment for --color-moved"
+ :class 'transient-option
+ :key "=w"
+ :argument "--color-moved-ws="
+ :reader #'magit-diff-select-color-moved-ws-mode)
+
+(defun magit-diff-select-color-moved-ws-mode (&rest _ignore)
+ (magit-read-char-case "Ignore whitespace " t
+ (?i "[i]ndentation" "allow-indentation-change")
+ (?e "[e]nd of line" "ignore-space-at-eol")
+ (?s "[s]pace change" "ignore-space-change")
+ (?a "[a]ll space" "ignore-all-space")
+ (?n "[n]o" "no")))
+
+;;;; Setup Commands
+
+;;;###autoload
+(defun magit-diff-dwim (&optional args files)
+ "Show changes for the thing at point."
+ (interactive (magit-diff-arguments))
+ (let ((default-directory default-directory)
+ (section (magit-current-section)))
+ (cond
+ ((magit-section-match 'module section)
+ (setq default-directory
+ (expand-file-name
+ (file-name-as-directory (oref section value))))
+ (magit-diff-range (oref section range)))
+ (t
+ (when (magit-section-match 'module-commit section)
+ (setq args nil)
+ (setq files nil)
+ (setq default-directory
+ (expand-file-name
+ (file-name-as-directory (magit-section-parent-value section)))))
+ (pcase (magit-diff--dwim)
+ ('unmerged (magit-diff-unmerged args files))
+ ('unstaged (magit-diff-unstaged args files))
+ ('staged
+ (let ((file (magit-file-at-point)))
+ (if (and file (equal (cddr (car (magit-file-status file))) '(?D ?U)))
+ ;; File was deleted by us and modified by them. Show the latter.
+ (magit-diff-unmerged args (list file))
+ (magit-diff-staged nil args files))))
+ (`(stash . ,value) (magit-stash-show value args))
+ (`(commit . ,value)
+ (magit-diff-range (format "%s^..%s" value value) args files))
+ ((and range (pred stringp))
+ (magit-diff-range range args files))
+ (_ (call-interactively #'magit-diff-range)))))))
+
+(defun magit-diff--dwim ()
+ "Return information for performing DWIM diff.
+
+The information can be in three forms:
+1. TYPE
+ A symbol describing a type of diff where no additional information
+ is needed to generate the diff. Currently, this includes `staged',
+ `unstaged' and `unmerged'.
+2. (TYPE . VALUE)
+ Like #1 but the diff requires additional information, which is
+ given by VALUE. Currently, this includes `commit' and `stash',
+ where VALUE is the given commit or stash, respectively.
+3. RANGE
+ A string indicating a diff range.
+
+If no DWIM context is found, nil is returned."
+ (cond
+ ((when-let* ((commits (magit-region-values '(commit branch) t)))
+ ;; Cannot use and-let* because of debbugs#31840.
+ (deactivate-mark)
+ (concat (car (last commits)) ".." (car commits))))
+ (magit-buffer-refname
+ (cons 'commit magit-buffer-refname))
+ ((derived-mode-p 'magit-stash-mode)
+ (cons 'commit
+ (magit-section-case
+ (commit (oref it value))
+ (file (thread-first it
+ (oref parent)
+ (oref value)))
+ (hunk (thread-first it
+ (oref parent)
+ (oref parent)
+ (oref value))))))
+ ((derived-mode-p 'magit-revision-mode)
+ (cons 'commit magit-buffer-revision))
+ ((derived-mode-p 'magit-diff-mode)
+ magit-buffer-range)
+ (t
+ (magit-section-case
+ ([* unstaged] 'unstaged)
+ ([* staged] 'staged)
+ (unmerged 'unmerged)
+ (unpushed (magit-diff--range-to-endpoints (oref it value)))
+ (unpulled (magit-diff--range-to-endpoints (oref it value)))
+ (branch (let ((current (magit-get-current-branch))
+ (atpoint (oref it value)))
+ (if (equal atpoint current)
+ (--if-let (magit-get-upstream-branch)
+ (format "%s...%s" it current)
+ (if (magit-anything-modified-p)
+ current
+ (cons 'commit current)))
+ (format "%s...%s"
+ (or current "HEAD")
+ atpoint))))
+ (commit (cons 'commit (oref it value)))
+ ([file commit] (cons 'commit (oref (oref it parent) value)))
+ ([hunk file commit]
+ (cons 'commit (oref (oref (oref it parent) parent) value)))
+ (stash (cons 'stash (oref it value)))
+ (pullreq (forge--pullreq-range (oref it value) t))))))
+
+(defun magit-diff--range-to-endpoints (range)
+ (cond ((string-match "\\.\\.\\." range) (replace-match ".." nil nil range))
+ ((string-match "\\.\\." range) (replace-match "..." nil nil range))
+ (t range)))
+
+(defun magit-diff--region-range (&optional interactive mbase)
+ (when-let* ((commits (magit-region-values '(commit branch) t)) ;debbugs#31840
+ (revA (car (last commits)))
+ (revB (car commits)))
+ (when interactive
+ (deactivate-mark))
+ (if mbase
+ (let ((base (magit-git-string "merge-base" revA revB)))
+ (cond
+ ((string= (magit-rev-parse revA) base)
+ (format "%s..%s" revA revB))
+ ((string= (magit-rev-parse revB) base)
+ (format "%s..%s" revB revA))
+ (interactive
+ (let ((main (magit-completing-read "View changes along"
+ (list revA revB)
+ nil t nil nil revB)))
+ (format "%s...%s"
+ (if (string= main revB) revA revB) main)))
+ (t "%s...%s" revA revB)))
+ (format "%s..%s" revA revB))))
+
+(defun magit-diff-read-range-or-commit (prompt &optional secondary-default mbase)
+ "Read range or revision with special diff range treatment.
+If MBASE is non-nil, prompt for which rev to place at the end of
+a \"revA...revB\" range. Otherwise, always construct
+\"revA..revB\" range."
+ (or (magit-diff--region-range t mbase)
+ (magit-read-range prompt
+ (or (pcase (magit-diff--dwim)
+ (`(commit . ,value)
+ (format "%s^..%s" value value))
+ ((and range (pred stringp))
+ range))
+ secondary-default
+ (magit-get-current-branch)))))
+
+;;;###autoload
+(defun magit-diff-range (rev-or-range &optional args files)
+ "Show differences between two commits.
+
+REV-OR-RANGE should be a range or a single revision. If it is a
+revision, then show changes in the working tree relative to that
+revision. If it is a range, but one side is omitted, then show
+changes relative to `HEAD'.
+
+If the region is active, use the revisions on the first and last
+line of the region as the two sides of the range. With a prefix
+argument, instead of diffing the revisions, choose a revision to
+view changes along, starting at the common ancestor of both
+revisions (i.e., use a \"...\" range)."
+ (interactive (cons (magit-diff-read-range-or-commit "Diff for range"
+ nil current-prefix-arg)
+ (magit-diff-arguments)))
+ (magit-diff-setup-buffer rev-or-range nil args files))
+
+;;;###autoload
+(defun magit-diff-working-tree (&optional rev args files)
+ "Show changes between the current working tree and the `HEAD' commit.
+With a prefix argument show changes between the working tree and
+a commit read from the minibuffer."
+ (interactive
+ (cons (and current-prefix-arg
+ (magit-read-branch-or-commit "Diff working tree and commit"))
+ (magit-diff-arguments)))
+ (magit-diff-setup-buffer (or rev "HEAD") nil args files))
+
+;;;###autoload
+(defun magit-diff-staged (&optional rev args files)
+ "Show changes between the index and the `HEAD' commit.
+With a prefix argument show changes between the index and
+a commit read from the minibuffer."
+ (interactive
+ (cons (and current-prefix-arg
+ (magit-read-branch-or-commit "Diff index and commit"))
+ (magit-diff-arguments)))
+ (magit-diff-setup-buffer rev "--cached" args files))
+
+;;;###autoload
+(defun magit-diff-unstaged (&optional args files)
+ "Show changes between the working tree and the index."
+ (interactive (magit-diff-arguments))
+ (magit-diff-setup-buffer nil nil args files))
+
+;;;###autoload
+(defun magit-diff-unmerged (&optional args files)
+ "Show changes that are being merged."
+ (interactive (magit-diff-arguments))
+ (unless (magit-merge-in-progress-p)
+ (user-error "No merge is in progress"))
+ (magit-diff-setup-buffer (magit--merge-range) nil args files))
+
+;;;###autoload
+(defun magit-diff-while-committing (&optional args)
+ "While committing, show the changes that are about to be committed.
+While amending, invoking the command again toggles between
+showing just the new changes or all the changes that will
+be committed."
+ (interactive (list (car (magit-diff-arguments))))
+ (unless (magit-commit-message-buffer)
+ (user-error "No commit in progress"))
+ (let ((magit-display-buffer-noselect t))
+ (if-let ((diff-buf (magit-get-mode-buffer 'magit-diff-mode 'selected)))
+ (with-current-buffer diff-buf
+ (cond ((and (equal magit-buffer-range "HEAD^")
+ (equal magit-buffer-typearg "--cached"))
+ (magit-diff-staged nil args))
+ ((and (equal magit-buffer-range nil)
+ (equal magit-buffer-typearg "--cached"))
+ (magit-diff-while-amending args))
+ ((magit-anything-staged-p)
+ (magit-diff-staged nil args))
+ (t
+ (magit-diff-while-amending args))))
+ (if (magit-anything-staged-p)
+ (magit-diff-staged nil args)
+ (magit-diff-while-amending args)))))
+
+(define-key git-commit-mode-map
+ (kbd "C-c C-d") #'magit-diff-while-committing)
+
+(defun magit-diff-while-amending (&optional args)
+ (magit-diff-setup-buffer "HEAD^" "--cached" args nil))
+
+;;;###autoload
+(defun magit-diff-buffer-file ()
+ "Show diff for the blob or file visited in the current buffer.
+
+When the buffer visits a blob, then show the respective commit.
+When the buffer visits a file, then show the differenced between
+`HEAD' and the working tree. In both cases limit the diff to
+the file or blob."
+ (interactive)
+ (require 'magit)
+ (if-let ((file (magit-file-relative-name)))
+ (if magit-buffer-refname
+ (magit-show-commit magit-buffer-refname
+ (car (magit-show-commit--arguments))
+ (list file))
+ (save-buffer)
+ (let ((line (line-number-at-pos))
+ (col (current-column)))
+ (with-current-buffer
+ (magit-diff-setup-buffer (or (magit-get-current-branch) "HEAD")
+ nil
+ (car (magit-diff-arguments))
+ (list file)
+ magit-diff-buffer-file-locked)
+ (magit-diff--goto-position file line col))))
+ (user-error "Buffer isn't visiting a file")))
+
+;;;###autoload
+(defun magit-diff-paths (a b)
+ "Show changes between any two files on disk."
+ (interactive (list (read-file-name "First file: " nil nil t)
+ (read-file-name "Second file: " nil nil t)))
+ (magit-diff-setup-buffer nil "--no-index"
+ nil (list (magit-convert-filename-for-git
+ (expand-file-name a))
+ (magit-convert-filename-for-git
+ (expand-file-name b)))))
+
+(defun magit-show-commit--arguments ()
+ (pcase-let ((`(,args ,diff-files)
+ (magit-diff-arguments 'magit-revision-mode)))
+ (list args (if (derived-mode-p 'magit-log-mode)
+ (and (or magit-revision-filter-files-on-follow
+ (not (member "--follow" magit-buffer-log-args)))
+ magit-buffer-log-files)
+ diff-files))))
+
+;;;###autoload
+(defun magit-show-commit (rev &optional args files module)
+ "Visit the revision at point in another buffer.
+If there is no revision at point or with a prefix argument prompt
+for a revision."
+ (interactive
+ (pcase-let* ((mcommit (magit-section-value-if 'module-commit))
+ (atpoint (or mcommit
+ (magit-thing-at-point 'git-revision t)
+ (magit-branch-or-commit-at-point)))
+ (`(,args ,files) (magit-show-commit--arguments)))
+ (list (or (and (not current-prefix-arg) atpoint)
+ (magit-read-branch-or-commit "Show commit" atpoint))
+ args
+ files
+ (and mcommit
+ (magit-section-parent-value (magit-current-section))))))
+ (require 'magit)
+ (let ((file (magit-file-relative-name)))
+ (magit-with-toplevel
+ (when module
+ (setq default-directory
+ (expand-file-name (file-name-as-directory module))))
+ (unless (magit-commit-p rev)
+ (user-error "%s is not a commit" rev))
+ (let ((buf (magit-revision-setup-buffer rev args files)))
+ (when file
+ (save-buffer)
+ (let ((line (magit-diff-visit--offset file (list "-R" rev)
+ (line-number-at-pos)))
+ (col (current-column)))
+ (with-current-buffer buf
+ (magit-diff--goto-position file line col))))))))
+
+(defun magit-diff--locate-hunk (file line &optional parent)
+ (and-let* ((diff (cl-find-if (lambda (section)
+ (and (cl-typep section 'magit-file-section)
+ (equal (oref section value) file)))
+ (oref (or parent magit-root-section) children))))
+ (let (hunk (hunks (oref diff children)))
+ (cl-block nil
+ (while (setq hunk (pop hunks))
+ (when-let ((range (oref hunk to-range)))
+ (pcase-let* ((`(,beg ,len) range)
+ (end (+ beg len)))
+ (cond ((> beg line) (cl-return (list diff nil)))
+ ((<= beg line end) (cl-return (list hunk t)))
+ ((null hunks) (cl-return (list hunk nil)))))))))))
+
+(defun magit-diff--goto-position (file line column &optional parent)
+ (when-let ((pos (magit-diff--locate-hunk file line parent)))
+ (pcase-let ((`(,section ,exact) pos))
+ (cond ((cl-typep section 'magit-file-section)
+ (goto-char (oref section start)))
+ (exact
+ (goto-char (oref section content))
+ (let ((pos (car (oref section to-range))))
+ (while (or (< pos line)
+ (= (char-after) ?-))
+ (unless (= (char-after) ?-)
+ (cl-incf pos))
+ (forward-line)))
+ (forward-char (1+ column)))
+ (t
+ (goto-char (oref section start))
+ (setq section (oref section parent))))
+ (while section
+ (when (oref section hidden)
+ (magit-section-show section))
+ (setq section (oref section parent))))
+ (magit-section-update-highlight)
+ t))
+
+;;;; Setting Commands
+
+(defun magit-diff-switch-range-type ()
+ "Convert diff range type.
+Change \"revA..revB\" to \"revA...revB\", or vice versa."
+ (interactive)
+ (if (and magit-buffer-range
+ (derived-mode-p 'magit-diff-mode)
+ (string-match magit-range-re magit-buffer-range))
+ (setq magit-buffer-range
+ (replace-match (if (string= (match-string 2 magit-buffer-range) "..")
+ "..."
+ "..")
+ t t magit-buffer-range 2))
+ (user-error "No range to change"))
+ (magit-refresh))
+
+(defun magit-diff-flip-revs ()
+ "Swap revisions in diff range.
+Change \"revA..revB\" to \"revB..revA\"."
+ (interactive)
+ (if (and magit-buffer-range
+ (derived-mode-p 'magit-diff-mode)
+ (string-match magit-range-re magit-buffer-range))
+ (progn
+ (setq magit-buffer-range
+ (concat (match-string 3 magit-buffer-range)
+ (match-string 2 magit-buffer-range)
+ (match-string 1 magit-buffer-range)))
+ (magit-refresh))
+ (user-error "No range to swap")))
+
+(defun magit-diff-toggle-file-filter ()
+ "Toggle the file restriction of the current buffer's diffs.
+If the current buffer's mode is derived from `magit-log-mode',
+toggle the file restriction in the repository's revision buffer
+instead."
+ (interactive)
+ (cl-flet ((toggle ()
+ (if (or magit-buffer-diff-files
+ magit-buffer-diff-files-suspended)
+ (cl-rotatef magit-buffer-diff-files
+ magit-buffer-diff-files-suspended)
+ (setq magit-buffer-diff-files
+ (transient-infix-read 'magit:--)))
+ (magit-refresh)))
+ (cond
+ ((derived-mode-p 'magit-log-mode
+ 'magit-cherry-mode
+ 'magit-reflog-mode)
+ (if-let ((buffer (magit-get-mode-buffer 'magit-revision-mode)))
+ (with-current-buffer buffer (toggle))
+ (message "No revision buffer")))
+ ((local-variable-p 'magit-buffer-diff-files)
+ (toggle))
+ (t
+ (user-error "Cannot toggle file filter in this buffer")))))
+
+(defun magit-diff-less-context (&optional count)
+ "Decrease the context for diff hunks by COUNT lines."
+ (interactive "p")
+ (magit-diff-set-context (lambda (cur) (max 0 (- (or cur 0) count)))))
+
+(defun magit-diff-more-context (&optional count)
+ "Increase the context for diff hunks by COUNT lines."
+ (interactive "p")
+ (magit-diff-set-context (lambda (cur) (+ (or cur 0) count))))
+
+(defun magit-diff-default-context ()
+ "Reset context for diff hunks to the default height."
+ (interactive)
+ (magit-diff-set-context #'ignore))
+
+(defun magit-diff-set-context (fn)
+ (let* ((def (--if-let (magit-get "diff.context") (string-to-number it) 3))
+ (val magit-buffer-diff-args)
+ (arg (--first (string-match "^-U\\([0-9]+\\)?$" it) val))
+ (num (--if-let (and arg (match-string 1 arg)) (string-to-number it) def))
+ (val (delete arg val))
+ (num (funcall fn num))
+ (arg (and num (not (= num def)) (format "-U%i" num)))
+ (val (if arg (cons arg val) val)))
+ (setq magit-buffer-diff-args val))
+ (magit-refresh))
+
+(defun magit-diff-context-p ()
+ (if-let ((arg (--first (string-match "^-U\\([0-9]+\\)$" it)
+ magit-buffer-diff-args)))
+ (not (equal arg "-U0"))
+ t))
+
+(defun magit-diff-ignore-any-space-p ()
+ (--any-p (member it magit-buffer-diff-args)
+ '("--ignore-cr-at-eol"
+ "--ignore-space-at-eol"
+ "--ignore-space-change" "-b"
+ "--ignore-all-space" "-w"
+ "--ignore-blank-space")))
+
+(defun magit-diff-toggle-refine-hunk (&optional style)
+ "Turn diff-hunk refining on or off.
+
+If hunk refining is currently on, then hunk refining is turned off.
+If hunk refining is off, then hunk refining is turned on, in
+`selected' mode (only the currently selected hunk is refined).
+
+With a prefix argument, the \"third choice\" is used instead:
+If hunk refining is currently on, then refining is kept on, but
+the refining mode (`selected' or `all') is switched.
+If hunk refining is off, then hunk refining is turned on, in
+`all' mode (all hunks refined).
+
+Customize variable `magit-diff-refine-hunk' to change the default mode."
+ (interactive "P")
+ (setq-local magit-diff-refine-hunk
+ (if style
+ (if (eq magit-diff-refine-hunk 'all) t 'all)
+ (not magit-diff-refine-hunk)))
+ (magit-diff-update-hunk-refinement))
+
+;;;; Visit Commands
+;;;;; Dwim Variants
+
+(defun magit-diff-visit-file (file &optional other-window)
+ "From a diff visit the appropriate version of FILE.
+
+Display the buffer in the selected window. With a prefix
+argument OTHER-WINDOW display the buffer in another window
+instead.
+
+Visit the worktree version of the appropriate file. The location
+of point inside the diff determines which file is being visited.
+The visited version depends on what changes the diff is about.
+
+1. If the diff shows uncommitted changes (i.e. stage or unstaged
+ changes), then visit the file in the working tree (i.e. the
+ same \"real\" file that `find-file' would visit. In all other
+ cases visit a \"blob\" (i.e. the version of a file as stored
+ in some commit).
+
+2. If point is on a removed line, then visit the blob for the
+ first parent of the commit that removed that line, i.e. the
+ last commit where that line still exists.
+
+3. If point is on an added or context line, then visit the blob
+ that adds that line, or if the diff shows from more than a
+ single commit, then visit the blob from the last of these
+ commits.
+
+In the file-visiting buffer also go to the line that corresponds
+to the line that point is on in the diff.
+
+Note that this command only works if point is inside a diff.
+In other cases `magit-find-file' (which see) has to be used."
+ (interactive (list (magit-file-at-point t t) current-prefix-arg))
+ (magit-diff-visit-file--internal file nil
+ (if other-window
+ #'switch-to-buffer-other-window
+ #'pop-to-buffer-same-window)))
+
+(defun magit-diff-visit-file-other-window (file)
+ "From a diff visit the appropriate version of FILE in another window.
+Like `magit-diff-visit-file' but use
+`switch-to-buffer-other-window'."
+ (interactive (list (magit-file-at-point t t)))
+ (magit-diff-visit-file--internal file nil #'switch-to-buffer-other-window))
+
+(defun magit-diff-visit-file-other-frame (file)
+ "From a diff visit the appropriate version of FILE in another frame.
+Like `magit-diff-visit-file' but use
+`switch-to-buffer-other-frame'."
+ (interactive (list (magit-file-at-point t t)))
+ (magit-diff-visit-file--internal file nil #'switch-to-buffer-other-frame))
+
+;;;;; Worktree Variants
+
+(defun magit-diff-visit-worktree-file (file &optional other-window)
+ "From a diff visit the worktree version of FILE.
+
+Display the buffer in the selected window. With a prefix
+argument OTHER-WINDOW display the buffer in another window
+instead.
+
+Visit the worktree version of the appropriate file. The location
+of point inside the diff determines which file is being visited.
+
+Unlike `magit-diff-visit-file' always visits the \"real\" file in
+the working tree, i.e the \"current version\" of the file.
+
+In the file-visiting buffer also go to the line that corresponds
+to the line that point is on in the diff. Lines that were added
+or removed in the working tree, the index and other commits in
+between are automatically accounted for."
+ (interactive (list (magit-file-at-point t t) current-prefix-arg))
+ (magit-diff-visit-file--internal file t
+ (if other-window
+ #'switch-to-buffer-other-window
+ #'pop-to-buffer-same-window)))
+
+(defun magit-diff-visit-worktree-file-other-window (file)
+ "From a diff visit the worktree version of FILE in another window.
+Like `magit-diff-visit-worktree-file' but use
+`switch-to-buffer-other-window'."
+ (interactive (list (magit-file-at-point t t)))
+ (magit-diff-visit-file--internal file t #'switch-to-buffer-other-window))
+
+(defun magit-diff-visit-worktree-file-other-frame (file)
+ "From a diff visit the worktree version of FILE in another frame.
+Like `magit-diff-visit-worktree-file' but use
+`switch-to-buffer-other-frame'."
+ (interactive (list (magit-file-at-point t t)))
+ (magit-diff-visit-file--internal file t #'switch-to-buffer-other-frame))
+
+;;;;; Internal
+
+(defun magit-diff-visit-file--internal (file force-worktree fn)
+ "From a diff visit the appropriate version of FILE.
+If FORCE-WORKTREE is non-nil, then visit the worktree version of
+the file, even if the diff is about a committed change. Use FN
+to display the buffer in some window."
+ (if (magit-file-accessible-directory-p file)
+ (magit-diff-visit-directory file force-worktree)
+ (pcase-let ((`(,buf ,pos)
+ (magit-diff-visit-file--noselect file force-worktree)))
+ (funcall fn buf)
+ (magit-diff-visit-file--setup buf pos)
+ buf)))
+
+(defun magit-diff-visit-directory (directory &optional other-window)
+ "Visit DIRECTORY in some window.
+Display the buffer in the selected window unless OTHER-WINDOW is
+non-nil. If DIRECTORY is the top-level directory of the current
+repository, then visit the containing directory using Dired and
+in the Dired buffer put point on DIRECTORY. Otherwise display
+the Magit-Status buffer for DIRECTORY."
+ (if (equal (magit-toplevel directory)
+ (magit-toplevel))
+ (dired-jump other-window (concat directory "/."))
+ (let ((display-buffer-overriding-action
+ (if other-window
+ '(nil (inhibit-same-window t))
+ '(display-buffer-same-window))))
+ (magit-status-setup-buffer directory))))
+
+(defun magit-diff-visit-file--setup (buf pos)
+ (if-let ((win (get-buffer-window buf 'visible)))
+ (with-selected-window win
+ (when pos
+ (unless (<= (point-min) pos (point-max))
+ (widen))
+ (goto-char pos))
+ (when (and buffer-file-name
+ (magit-anything-unmerged-p buffer-file-name))
+ (smerge-start-session))
+ (run-hooks 'magit-diff-visit-file-hook))
+ (error "File buffer is not visible")))
+
+(defun magit-diff-visit-file--noselect (&optional file goto-worktree)
+ (unless file
+ (setq file (magit-file-at-point t t)))
+ (let* ((hunk (magit-diff-visit--hunk))
+ (goto-from (and hunk
+ (magit-diff-visit--goto-from-p hunk goto-worktree)))
+ (line (and hunk (magit-diff-hunk-line hunk goto-from)))
+ (col (and hunk (magit-diff-hunk-column hunk goto-from)))
+ (spec (magit-diff--dwim))
+ (rev (if goto-from
+ (magit-diff-visit--range-from spec)
+ (magit-diff-visit--range-to spec)))
+ (buf (if (or goto-worktree
+ (and (not (stringp rev))
+ (or magit-diff-visit-avoid-head-blob
+ (not goto-from))))
+ (or (get-file-buffer file)
+ (find-file-noselect file))
+ (magit-find-file-noselect (if (stringp rev) rev "HEAD")
+ file))))
+ (if line
+ (with-current-buffer buf
+ (cond ((eq rev 'staged)
+ (setq line (magit-diff-visit--offset file nil line)))
+ ((and goto-worktree
+ (stringp rev))
+ (setq line (magit-diff-visit--offset file rev line))))
+ (list buf (save-restriction
+ (widen)
+ (goto-char (point-min))
+ (forward-line (1- line))
+ (move-to-column col)
+ (point))))
+ (list buf nil))))
+
+(defun magit-diff-visit--hunk ()
+ (when-let* ((scope (magit-diff-scope)) ;debbugs#31840
+ (section (magit-current-section)))
+ (cl-case scope
+ ((file files)
+ (setq section (car (oref section children))))
+ (list
+ (setq section (car (oref section children)))
+ (when section
+ (setq section (car (oref section children))))))
+ (and
+ ;; Unmerged files appear in the list of staged changes
+ ;; but unlike in the list of unstaged changes no diffs
+ ;; are shown here. In that case `section' is nil.
+ section
+ ;; Currently the `hunk' type is also abused for file
+ ;; mode changes, which we are not interested in here.
+ (not (equal (oref section value) '(chmod)))
+ section)))
+
+(defun magit-diff-visit--goto-from-p (section in-worktree)
+ (and magit-diff-visit-previous-blob
+ (not in-worktree)
+ (not (oref section combined))
+ (not (< (magit-point) (oref section content)))
+ (= (char-after (line-beginning-position)) ?-)))
+
+(defvar magit-diff-visit-jump-to-change t)
+
+(defun magit-diff-hunk-line (section goto-from)
+ (save-excursion
+ (goto-char (line-beginning-position))
+ (with-slots (content combined from-ranges from-range to-range) section
+ (when (or from-range to-range)
+ (when (and magit-diff-visit-jump-to-change (< (point) content))
+ (goto-char content)
+ (re-search-forward "^[-+]"))
+ (+ (car (if goto-from from-range to-range))
+ (let ((prefix (if combined (length from-ranges) 1))
+ (target (point))
+ (offset 0))
+ (goto-char content)
+ (while (< (point) target)
+ (unless (string-search
+ (if goto-from "+" "-")
+ (buffer-substring (point) (+ (point) prefix)))
+ (cl-incf offset))
+ (forward-line))
+ offset))))))
+
+(defun magit-diff-hunk-column (section goto-from)
+ (if (or (< (magit-point)
+ (oref section content))
+ (and (not goto-from)
+ (= (char-after (line-beginning-position)) ?-)))
+ 0
+ (max 0 (- (+ (current-column) 2)
+ (length (oref section value))))))
+
+(defun magit-diff-visit--range-from (spec)
+ (cond ((consp spec)
+ (concat (cdr spec) "^"))
+ ((stringp spec)
+ (car (magit-split-range spec)))
+ (t
+ spec)))
+
+(defun magit-diff-visit--range-to (spec)
+ (if (symbolp spec)
+ spec
+ (let ((rev (if (consp spec)
+ (cdr spec)
+ (cdr (magit-split-range spec)))))
+ (if (and magit-diff-visit-avoid-head-blob
+ (magit-rev-head-p rev))
+ 'unstaged
+ rev))))
+
+(defun magit-diff-visit--offset (file rev line)
+ (let ((offset 0))
+ (with-temp-buffer
+ (save-excursion
+ (magit-with-toplevel
+ (magit-git-insert "diff" rev "--" file)))
+ (catch 'found
+ (while (re-search-forward
+ "^@@ -\\([0-9]+\\),\\([0-9]+\\) \\+\\([0-9]+\\),\\([0-9]+\\) @@.*\n"
+ nil t)
+ (let ((from-beg (string-to-number (match-string 1)))
+ (from-len (string-to-number (match-string 2)))
+ ( to-len (string-to-number (match-string 4))))
+ (if (<= from-beg line)
+ (if (< (+ from-beg from-len) line)
+ (cl-incf offset (- to-len from-len))
+ (let ((rest (- line from-beg)))
+ (while (> rest 0)
+ (pcase (char-after)
+ (?\s (cl-decf rest))
+ (?- (cl-decf offset) (cl-decf rest))
+ (?+ (cl-incf offset)))
+ (forward-line))))
+ (throw 'found nil))))))
+ (+ line offset)))
+
+;;;; Scroll Commands
+
+(defun magit-diff-show-or-scroll-up ()
+ "Update the commit or diff buffer for the thing at point.
+
+Either show the commit or stash at point in the appropriate
+buffer, or if that buffer is already being displayed in the
+current frame and contains information about that commit or
+stash, then instead scroll the buffer up. If there is no
+commit or stash at point, then prompt for a commit."
+ (interactive)
+ (magit-diff-show-or-scroll #'scroll-up))
+
+(defun magit-diff-show-or-scroll-down ()
+ "Update the commit or diff buffer for the thing at point.
+
+Either show the commit or stash at point in the appropriate
+buffer, or if that buffer is already being displayed in the
+current frame and contains information about that commit or
+stash, then instead scroll the buffer down. If there is no
+commit or stash at point, then prompt for a commit."
+ (interactive)
+ (magit-diff-show-or-scroll #'scroll-down))
+
+(defun magit-diff-show-or-scroll (fn)
+ (let (rev cmd buf win)
+ (cond
+ (magit-blame-mode
+ (setq rev (oref (magit-current-blame-chunk) orig-rev))
+ (setq cmd #'magit-show-commit)
+ (setq buf (magit-get-mode-buffer 'magit-revision-mode)))
+ ((derived-mode-p 'git-rebase-mode)
+ (with-slots (action-type target)
+ (git-rebase-current-line)
+ (if (not (eq action-type 'commit))
+ (user-error "No commit on this line")
+ (setq rev target)
+ (setq cmd #'magit-show-commit)
+ (setq buf (magit-get-mode-buffer 'magit-revision-mode)))))
+ (t
+ (magit-section-case
+ (branch
+ (setq rev (magit-ref-maybe-qualify (oref it value)))
+ (setq cmd #'magit-show-commit)
+ (setq buf (magit-get-mode-buffer 'magit-revision-mode)))
+ (commit
+ (setq rev (oref it value))
+ (setq cmd #'magit-show-commit)
+ (setq buf (magit-get-mode-buffer 'magit-revision-mode)))
+ (stash
+ (setq rev (oref it value))
+ (setq cmd #'magit-stash-show)
+ (setq buf (magit-get-mode-buffer 'magit-stash-mode))))))
+ (if rev
+ (if (and buf
+ (setq win (get-buffer-window buf))
+ (with-current-buffer buf
+ (and (equal rev magit-buffer-revision)
+ (equal (magit-rev-parse rev)
+ magit-buffer-revision-hash))))
+ (with-selected-window win
+ (condition-case nil
+ (funcall fn)
+ (error
+ (goto-char (pcase fn
+ ('scroll-up (point-min))
+ ('scroll-down (point-max)))))))
+ (let ((magit-display-buffer-noselect t))
+ (if (eq cmd #'magit-show-commit)
+ (apply #'magit-show-commit rev (magit-show-commit--arguments))
+ (funcall cmd rev))))
+ (call-interactively #'magit-show-commit))))
+
+;;;; Section Commands
+
+(defun magit-section-cycle-diffs ()
+ "Cycle visibility of diff-related sections in the current buffer."
+ (interactive)
+ (when-let ((sections
+ (cond ((derived-mode-p 'magit-status-mode)
+ (--mapcat
+ (when it
+ (when (oref it hidden)
+ (magit-section-show it))
+ (oref it children))
+ (list (magit-get-section '((staged) (status)))
+ (magit-get-section '((unstaged) (status))))))
+ ((derived-mode-p 'magit-diff-mode)
+ (-filter #'magit-file-section-p
+ (oref magit-root-section children))))))
+ (if (--any-p (oref it hidden) sections)
+ (dolist (s sections)
+ (magit-section-show s)
+ (magit-section-hide-children s))
+ (let ((children (--mapcat (oref it children) sections)))
+ (cond ((and (--any-p (oref it hidden) children)
+ (--any-p (oref it children) children))
+ (mapc #'magit-section-show-headings sections))
+ ((seq-some #'magit-section-hidden-body children)
+ (mapc #'magit-section-show-children sections))
+ (t
+ (mapc #'magit-section-hide sections)))))))
+
+;;; Diff Mode
+
+(defvar magit-diff-mode-map
+ (let ((map (make-sparse-keymap)))
+ (set-keymap-parent map magit-mode-map)
+ (define-key map (kbd "C-c C-d") #'magit-diff-while-committing)
+ (define-key map (kbd "C-c C-b") #'magit-go-backward)
+ (define-key map (kbd "C-c C-f") #'magit-go-forward)
+ (define-key map (kbd "SPC") #'scroll-up)
+ (define-key map (kbd "DEL") #'scroll-down)
+ (define-key map (kbd "j") #'magit-jump-to-diffstat-or-diff)
+ (define-key map [remap write-file] #'magit-patch-save)
+ map)
+ "Keymap for `magit-diff-mode'.")
+
+(define-derived-mode magit-diff-mode magit-mode "Magit Diff"
+ "Mode for looking at a Git diff.
+
+This mode is documented in info node `(magit)Diff Buffer'.
+
+\\<magit-mode-map>\
+Type \\[magit-refresh] to refresh the current buffer.
+Type \\[magit-section-toggle] to expand or hide the section at point.
+Type \\[magit-visit-thing] to visit the hunk or file at point.
+
+Staging and applying changes is documented in info node
+`(magit)Staging and Unstaging' and info node `(magit)Applying'.
+
+\\<magit-hunk-section-map>Type \
+\\[magit-apply] to apply the change at point, \
+\\[magit-stage] to stage,
+\\[magit-unstage] to unstage, \
+\\[magit-discard] to discard, or \
+\\[magit-reverse] to reverse it.
+
+\\{magit-diff-mode-map}"
+ :group 'magit-diff
+ (hack-dir-local-variables-non-file-buffer)
+ (setq magit--imenu-item-types 'file))
+
+(put 'magit-diff-mode 'magit-diff-default-arguments
+ '("--stat" "--no-ext-diff"))
+
+(defun magit-diff-setup-buffer (range typearg args files &optional locked)
+ (require 'magit)
+ (magit-setup-buffer #'magit-diff-mode locked
+ (magit-buffer-range range)
+ (magit-buffer-typearg typearg)
+ (magit-buffer-diff-args args)
+ (magit-buffer-diff-files files)
+ (magit-buffer-diff-files-suspended nil)))
+
+(defun magit-diff-refresh-buffer ()
+ "Refresh the current `magit-diff-mode' buffer."
+ (magit-set-header-line-format
+ (if (equal magit-buffer-typearg "--no-index")
+ (apply #'format "Differences between %s and %s" magit-buffer-diff-files)
+ (concat (if magit-buffer-range
+ (cond
+ ((string-match-p "\\(\\.\\.\\|\\^-\\)"
+ magit-buffer-range)
+ (format "Changes in %s" magit-buffer-range))
+ ((member "-R" magit-buffer-diff-args)
+ (format "Changes from working tree to %s" magit-buffer-range))
+ (t
+ (format "Changes from %s to working tree" magit-buffer-range)))
+ (if (equal magit-buffer-typearg "--cached")
+ "Staged changes"
+ "Unstaged changes"))
+ (pcase (length magit-buffer-diff-files)
+ (0)
+ (1 (concat " in file " (car magit-buffer-diff-files)))
+ (_ (concat " in files "
+ (mapconcat #'identity magit-buffer-diff-files ", ")))))))
+ (setq magit-buffer-range-hashed
+ (and magit-buffer-range (magit-hash-range magit-buffer-range)))
+ (magit-insert-section (diffbuf)
+ (magit-run-section-hook 'magit-diff-sections-hook)))
+
+(cl-defmethod magit-buffer-value (&context (major-mode magit-diff-mode))
+ (nconc (cond (magit-buffer-range
+ (delq nil (list magit-buffer-range magit-buffer-typearg)))
+ ((equal magit-buffer-typearg "--cached")
+ (list 'staged))
+ (t
+ (list 'unstaged magit-buffer-typearg)))
+ (and magit-buffer-diff-files (cons "--" magit-buffer-diff-files))))
+
+(cl-defmethod magit-menu-common-value ((_section magit-diff-section))
+ (magit-diff-scope))
+
+(define-obsolete-variable-alias 'magit-diff-section-base-map
+ 'magit-diff-section-map "Magit-Section 3.4.0")
+(defvar magit-diff-section-map
+ (let ((map (make-sparse-keymap)))
+ (magit-menu-set map [magit-cherry-apply]
+ #'magit-apply "Apply %x"
+ '(:enable (not (memq (magit-diff-type) '(unstaged staged)))))
+ (magit-menu-set map [magit-stage-file]
+ #'magit-stage "Stage %x"
+ '(:enable (eq (magit-diff-type) 'unstaged)))
+ (magit-menu-set map [magit-unstage-file]
+ #'magit-unstage "Unstage %x"
+ '(:enable (eq (magit-diff-type) 'staged)))
+ (magit-menu-set map [magit-delete-thing]
+ #'magit-discard "Discard %x"
+ '(:enable (not (memq (magit-diff-type) '(committed undefined)))))
+ (magit-menu-set map [magit-revert-no-commit]
+ #'magit-reverse "Reverse %x"
+ '(:enable (not (memq (magit-diff-type) '(untracked unstaged)))))
+ (magit-menu-set map [magit-visit-thing]
+ #'magit-diff-visit-file "Visit file")
+ (magit-menu-set map [magit-file-untrack]
+ #'magit-file-untrack "Untrack %x"
+ '(:enable (memq (magit-diff-scope) '(file files))))
+ (magit-menu-set map [magit-file-rename]
+ #'magit-file-rename "Rename file"
+ '(:enable (eq (magit-diff-scope) 'file)))
+ (define-key map (kbd "C-j") #'magit-diff-visit-worktree-file)
+ (define-key map (kbd "C-<return>") #'magit-diff-visit-worktree-file)
+ (define-key map (kbd "C-x 4 <return>") #'magit-diff-visit-file-other-window)
+ (define-key map (kbd "C-x 5 <return>") #'magit-diff-visit-file-other-frame)
+ (define-key map "&" #'magit-do-async-shell-command)
+ (define-key map "C" #'magit-commit-add-log)
+ (define-key map (kbd "C-x a") #'magit-add-change-log-entry)
+ (define-key map (kbd "C-x 4 a") #'magit-add-change-log-entry-other-window)
+ (define-key map (kbd "C-c C-t") #'magit-diff-trace-definition)
+ (define-key map (kbd "C-c C-e") #'magit-diff-edit-hunk-commit)
+ map)
+ "Keymap for diff sections.
+The classes `magit-file-section' and `magit-hunk-section' derive
+from the abstract `magit-diff-section' class. Accordingly this
+keymap is the parent of their keymaps.")
+
+(defvar magit-file-section-map
+ (let ((map (make-sparse-keymap)))
+ (set-keymap-parent map magit-diff-section-base-map)
+ map)
+ "Keymap for `file' sections.")
+
+(defvar magit-hunk-section-map
+ (let ((map (make-sparse-keymap)))
+ (set-keymap-parent map magit-diff-section-base-map)
+ (let ((m (make-sparse-keymap)))
+ (define-key m (kbd "RET") #'magit-smerge-keep-current)
+ (define-key m (kbd "u") #'magit-smerge-keep-upper)
+ (define-key m (kbd "b") #'magit-smerge-keep-base)
+ (define-key m (kbd "l") #'magit-smerge-keep-lower)
+ (define-key map smerge-command-prefix m))
+ map)
+ "Keymap for `hunk' sections.")
+
+(defconst magit-diff-conflict-headline-re
+ (concat "^" (regexp-opt
+ ;; Defined in merge-tree.c in this order.
+ '("merged"
+ "added in remote"
+ "added in both"
+ "added in local"
+ "removed in both"
+ "changed in both"
+ "removed in local"
+ "removed in remote"))))
+
+(defconst magit-diff-headline-re
+ (concat "^\\(@@@?\\|diff\\|Submodule\\|"
+ "\\* Unmerged path\\|"
+ (substring magit-diff-conflict-headline-re 1)
+ "\\)"))
+
+(defconst magit-diff-statline-re
+ (concat "^ ?"
+ "\\(.*\\)" ; file
+ "\\( +| +\\)" ; separator
+ "\\([0-9]+\\|Bin\\(?: +[0-9]+ -> [0-9]+ bytes\\)?$\\) ?"
+ "\\(\\+*\\)" ; add
+ "\\(-*\\)$")) ; del
+
+(defvar magit-diff--reset-non-color-moved
+ (list
+ "-c" "color.diff.context=normal"
+ "-c" "color.diff.plain=normal" ; historical synonym for context
+ "-c" "color.diff.meta=normal"
+ "-c" "color.diff.frag=normal"
+ "-c" "color.diff.func=normal"
+ "-c" "color.diff.old=normal"
+ "-c" "color.diff.new=normal"
+ "-c" "color.diff.commit=normal"
+ "-c" "color.diff.whitespace=normal"
+ ;; "git-range-diff" does not support "--color-moved", so we don't
+ ;; need to reset contextDimmed, oldDimmed, newDimmed, contextBold,
+ ;; oldBold, and newBold.
+ ))
+
+(defun magit-insert-diff ()
+ "Insert the diff into this `magit-diff-mode' buffer."
+ (magit--insert-diff
+ "diff" magit-buffer-range "-p" "--no-prefix"
+ (and (member "--stat" magit-buffer-diff-args) "--numstat")
+ magit-buffer-typearg
+ magit-buffer-diff-args "--"
+ magit-buffer-diff-files))
+
+(defun magit--insert-diff (&rest args)
+ (declare (indent 0))
+ (pcase-let ((`(,cmd . ,args)
+ (flatten-tree args))
+ (magit-git-global-arguments
+ (remove "--literal-pathspecs" magit-git-global-arguments)))
+ ;; As of Git 2.19.0, we need to generate diffs with
+ ;; --ita-visible-in-index so that `magit-stage' can work with
+ ;; intent-to-add files (see #4026).
+ (when (and (not (equal cmd "merge-tree"))
+ (magit-git-version>= "2.19.0"))
+ (push "--ita-visible-in-index" args))
+ (setq args (magit-diff--maybe-add-stat-arguments args))
+ (when (cl-member-if (lambda (arg) (string-prefix-p "--color-moved" arg)) args)
+ (push "--color=always" args)
+ (setq magit-git-global-arguments
+ (append magit-diff--reset-non-color-moved
+ magit-git-global-arguments)))
+ (magit-git-wash #'magit-diff-wash-diffs cmd args)))
+
+(defun magit-diff--maybe-add-stat-arguments (args)
+ (if (member "--stat" args)
+ (append (if (functionp magit-diff-extra-stat-arguments)
+ (funcall magit-diff-extra-stat-arguments)
+ magit-diff-extra-stat-arguments)
+ args)
+ args))
+
+(defun magit-diff-use-window-width-as-stat-width ()
+ "Use the `window-width' as the value of `--stat-width'."
+ (and-let* ((window (get-buffer-window (current-buffer) 'visible)))
+ (list (format "--stat-width=%d" (window-width window)))))
+
+(defun magit-diff-wash-diffs (args &optional limit)
+ (run-hooks 'magit-diff-wash-diffs-hook)
+ (when (member "--show-signature" args)
+ (magit-diff-wash-signature magit-buffer-revision-hash))
+ (when (member "--stat" args)
+ (magit-diff-wash-diffstat))
+ (when (re-search-forward magit-diff-headline-re limit t)
+ (goto-char (line-beginning-position))
+ (magit-wash-sequence (apply-partially #'magit-diff-wash-diff args))
+ (insert ?\n)))
+
+(defun magit-jump-to-diffstat-or-diff ()
+ "Jump to the diffstat or diff.
+When point is on a file inside the diffstat section, then jump
+to the respective diff section, otherwise jump to the diffstat
+section or a child thereof."
+ (interactive)
+ (--if-let (magit-get-section
+ (append (magit-section-case
+ ([file diffstat] `((file . ,(oref it value))))
+ (file `((file . ,(oref it value)) (diffstat)))
+ (t '((diffstat))))
+ (magit-section-ident magit-root-section)))
+ (magit-section-goto it)
+ (user-error "No diffstat in this buffer")))
+
+(defun magit-diff-wash-signature (object)
+ (when (looking-at "^gpg: ")
+ (let (title end)
+ (save-excursion
+ (while (looking-at "^gpg: ")
+ (cond
+ ((looking-at "^gpg: Good signature from")
+ (setq title (propertize
+ (buffer-substring (point) (line-end-position))
+ 'face 'magit-signature-good)))
+ ((looking-at "^gpg: Can't check signature")
+ (setq title (propertize
+ (buffer-substring (point) (line-end-position))
+ 'face '(italic bold)))))
+ (forward-line))
+ (setq end (point-marker)))
+ (magit-insert-section (signature object title)
+ (when title
+ (magit-insert-heading title))
+ (goto-char end)
+ (set-marker end nil)
+ (insert "\n")))))
+
+(defun magit-diff-wash-diffstat ()
+ (let (heading (beg (point)))
+ (when (re-search-forward "^ ?\\([0-9]+ +files? change[^\n]*\n\\)" nil t)
+ (setq heading (match-string 1))
+ (magit-delete-match)
+ (goto-char beg)
+ (magit-insert-section (diffstat)
+ (insert (propertize heading 'font-lock-face 'magit-diff-file-heading))
+ (magit-insert-heading)
+ (let (files)
+ (while (looking-at "^[-0-9]+\t[-0-9]+\t\\(.+\\)$")
+ (push (magit-decode-git-path
+ (let ((f (match-string 1)))
+ (cond
+ ((string-match "\\`\\([^{]+\\){\\(.+\\) => \\(.+\\)}\\'" f)
+ (concat (match-string 1 f)
+ (match-string 3 f)))
+ ((string-match " => " f)
+ (substring f (match-end 0)))
+ (t f))))
+ files)
+ (magit-delete-line))
+ (setq files (nreverse files))
+ (while (looking-at magit-diff-statline-re)
+ (magit-bind-match-strings (file sep cnt add del) nil
+ (magit-delete-line)
+ (when (string-match " +$" file)
+ (setq sep (concat (match-string 0 file) sep))
+ (setq file (substring file 0 (match-beginning 0))))
+ (let ((le (length file)) ld)
+ (setq file (magit-decode-git-path file))
+ (setq ld (length file))
+ (when (> le ld)
+ (setq sep (concat (make-string (- le ld) ?\s) sep))))
+ (magit-insert-section (file (pop files))
+ (insert (propertize file 'font-lock-face 'magit-filename)
+ sep cnt " ")
+ (when add
+ (insert (propertize add 'font-lock-face
+ 'magit-diffstat-added)))
+ (when del
+ (insert (propertize del 'font-lock-face
+ 'magit-diffstat-removed)))
+ (insert "\n")))))
+ (if (looking-at "^$") (forward-line) (insert "\n"))))))
+
+(defun magit-diff-wash-diff (args)
+ (when (cl-member-if (lambda (arg) (string-prefix-p "--color-moved" arg)) args)
+ (require 'ansi-color)
+ (ansi-color-apply-on-region (point-min) (point-max)))
+ (cond
+ ((looking-at "^Submodule")
+ (magit-diff-wash-submodule))
+ ((looking-at "^\\* Unmerged path \\(.*\\)")
+ (let ((file (magit-decode-git-path (match-string 1))))
+ (magit-delete-line)
+ (unless (and (derived-mode-p 'magit-status-mode)
+ (not (member "--cached" args)))
+ (magit-insert-section (file file)
+ (insert (propertize
+ (format "unmerged %s%s" file
+ (pcase (cddr (car (magit-file-status file)))
+ ('(?D ?D) " (both deleted)")
+ ('(?D ?U) " (deleted by us)")
+ ('(?U ?D) " (deleted by them)")
+ ('(?A ?A) " (both added)")
+ ('(?A ?U) " (added by us)")
+ ('(?U ?A) " (added by them)")
+ ('(?U ?U) "")))
+ 'font-lock-face 'magit-diff-file-heading))
+ (insert ?\n))))
+ t)
+ ((looking-at magit-diff-conflict-headline-re)
+ (let ((long-status (match-string 0))
+ (status "BUG")
+ file orig base)
+ (if (equal long-status "merged")
+ (progn (setq status long-status)
+ (setq long-status nil))
+ (setq status (pcase-exhaustive long-status
+ ("added in remote" "new file")
+ ("added in both" "new file")
+ ("added in local" "new file")
+ ("removed in both" "removed")
+ ("changed in both" "changed")
+ ("removed in local" "removed")
+ ("removed in remote" "removed"))))
+ (magit-delete-line)
+ (while (looking-at
+ "^ \\([^ ]+\\) +[0-9]\\{6\\} \\([a-z0-9]\\{40,\\}\\) \\(.+\\)$")
+ (magit-bind-match-strings (side _blob name) nil
+ (pcase side
+ ("result" (setq file name))
+ ("our" (setq orig name))
+ ("their" (setq file name))
+ ("base" (setq base name))))
+ (magit-delete-line))
+ (when orig (setq orig (magit-decode-git-path orig)))
+ (when file (setq file (magit-decode-git-path file)))
+ (magit-diff-insert-file-section
+ (or file base) orig status nil nil nil long-status)))
+ ;; The files on this line may be ambiguous due to whitespace.
+ ;; That's okay. We can get their names from subsequent headers.
+ ((looking-at "^diff --\
+\\(?:\\(?1:git\\) \\(?:\\(?2:.+?\\) \\2\\)?\
+\\|\\(?:cc\\|combined\\) \\(?3:.+\\)\\)")
+ (let ((status (cond ((equal (match-string 1) "git") "modified")
+ ((derived-mode-p 'magit-revision-mode) "resolved")
+ (t "unmerged")))
+ (orig nil)
+ (file (or (match-string 2) (match-string 3)))
+ (header (list (buffer-substring-no-properties
+ (line-beginning-position) (1+ (line-end-position)))))
+ (modes nil)
+ (rename nil))
+ (magit-delete-line)
+ (while (not (or (eobp) (looking-at magit-diff-headline-re)))
+ (cond
+ ((looking-at "old mode \\(?:[^\n]+\\)\nnew mode \\(?:[^\n]+\\)\n")
+ (setq modes (match-string 0)))
+ ((looking-at "deleted file .+\n")
+ (setq status "deleted"))
+ ((looking-at "new file .+\n")
+ (setq status "new file"))
+ ((looking-at "rename from \\(.+\\)\nrename to \\(.+\\)\n")
+ (setq rename (match-string 0))
+ (setq orig (match-string 1))
+ (setq file (match-string 2))
+ (setq status "renamed"))
+ ((looking-at "copy from \\(.+\\)\ncopy to \\(.+\\)\n")
+ (setq orig (match-string 1))
+ (setq file (match-string 2))
+ (setq status "new file"))
+ ((looking-at "similarity index .+\n"))
+ ((looking-at "dissimilarity index .+\n"))
+ ((looking-at "index .+\n"))
+ ((looking-at "--- \\(.+?\\)\t?\n")
+ (unless (equal (match-string 1) "/dev/null")
+ (setq orig (match-string 1))))
+ ((looking-at "\\+\\+\\+ \\(.+?\\)\t?\n")
+ (unless (equal (match-string 1) "/dev/null")
+ (setq file (match-string 1))))
+ ((looking-at "Binary files .+ and .+ differ\n"))
+ ((looking-at "Binary files differ\n"))
+ ;; TODO Use all combined diff extended headers.
+ ((looking-at "mode .+\n"))
+ (t
+ (error "BUG: Unknown extended header: %S"
+ (buffer-substring (point) (line-end-position)))))
+ ;; These headers are treated as some sort of special hunk.
+ (unless (or (string-prefix-p "old mode" (match-string 0))
+ (string-prefix-p "rename" (match-string 0)))
+ (push (match-string 0) header))
+ (magit-delete-match))
+ (setq header (mapconcat #'identity (nreverse header) ""))
+ (when orig
+ (setq orig (magit-decode-git-path orig)))
+ (setq file (magit-decode-git-path file))
+ ;; KLUDGE `git-diff' ignores `--no-prefix' for new files and renames at
+ ;; least. And `git-log' ignores `--no-prefix' when `-L' is used.
+ (when (or (and file orig
+ (string-prefix-p "a/" orig)
+ (string-prefix-p "b/" file))
+ (and (derived-mode-p 'magit-log-mode)
+ (--first (string-prefix-p "-L" it)
+ magit-buffer-log-args)))
+ (setq file (substring file 2))
+ (when orig
+ (setq orig (substring orig 2))))
+ (magit-diff-insert-file-section file orig status modes rename header)))))
+
+(defun magit-diff-insert-file-section
+ (file orig status modes rename header &optional long-status)
+ (magit-insert-section section
+ (file file (or (equal status "deleted")
+ (derived-mode-p 'magit-status-mode)))
+ (insert (propertize (format "%-10s %s" status
+ (if (or (not orig) (equal orig file))
+ file
+ (format "%s -> %s" orig file)))
+ 'font-lock-face 'magit-diff-file-heading))
+ (when long-status
+ (insert (format " (%s)" long-status)))
+ (magit-insert-heading)
+ (unless (equal orig file)
+ (oset section source orig))
+ (oset section header header)
+ (when modes
+ (magit-insert-section (hunk '(chmod))
+ (insert modes)
+ (magit-insert-heading)))
+ (when rename
+ (magit-insert-section (hunk '(rename))
+ (insert rename)
+ (magit-insert-heading)))
+ (magit-wash-sequence #'magit-diff-wash-hunk)))
+
+(defun magit-diff-wash-submodule ()
+ ;; See `show_submodule_summary' in submodule.c and "this" commit.
+ (when (looking-at "^Submodule \\([^ ]+\\)")
+ (let ((module (match-string 1))
+ untracked modified)
+ (when (looking-at "^Submodule [^ ]+ contains untracked content$")
+ (magit-delete-line)
+ (setq untracked t))
+ (when (looking-at "^Submodule [^ ]+ contains modified content$")
+ (magit-delete-line)
+ (setq modified t))
+ (cond
+ ((and (looking-at "^Submodule \\([^ ]+\\) \\([^ :]+\\)\\( (rewind)\\)?:$")
+ (equal (match-string 1) module))
+ (magit-bind-match-strings (_module range rewind) nil
+ (magit-delete-line)
+ (while (looking-at "^ \\([<>]\\) \\(.*\\)$")
+ (magit-delete-line))
+ (when rewind
+ (setq range (replace-regexp-in-string "[^.]\\(\\.\\.\\)[^.]"
+ "..." range t t 1)))
+ (magit-insert-section (magit-module-section module t)
+ (magit-insert-heading
+ (propertize (concat "modified " module)
+ 'font-lock-face 'magit-diff-file-heading)
+ " ("
+ (cond (rewind "rewind")
+ ((string-search "..." range) "non-ff")
+ (t "new commits"))
+ (and (or modified untracked)
+ (concat ", "
+ (and modified "modified")
+ (and modified untracked " and ")
+ (and untracked "untracked")
+ " content"))
+ ")")
+ (let ((default-directory
+ (file-name-as-directory
+ (expand-file-name module (magit-toplevel)))))
+ (magit-git-wash (apply-partially #'magit-log-wash-log 'module)
+ "log" "--oneline" "--left-right" range)
+ (delete-char -1)))))
+ ((and (looking-at "^Submodule \\([^ ]+\\) \\([^ ]+\\) (\\([^)]+\\))$")
+ (equal (match-string 1) module))
+ (magit-bind-match-strings (_module _range msg) nil
+ (magit-delete-line)
+ (magit-insert-section (magit-module-section module)
+ (magit-insert-heading
+ (propertize (concat "submodule " module)
+ 'font-lock-face 'magit-diff-file-heading)
+ " (" msg ")"))))
+ (t
+ (magit-insert-section (magit-module-section module)
+ (magit-insert-heading
+ (propertize (concat "modified " module)
+ 'font-lock-face 'magit-diff-file-heading)
+ " ("
+ (and modified "modified")
+ (and modified untracked " and ")
+ (and untracked "untracked")
+ " content)")))))))
+
+(defun magit-diff-wash-hunk ()
+ (when (looking-at "^@\\{2,\\} \\(.+?\\) @\\{2,\\}\\(?: \\(.*\\)\\)?")
+ (let* ((heading (match-string 0))
+ (ranges (mapcar (lambda (str)
+ (mapcar #'string-to-number
+ (split-string (substring str 1) ",")))
+ (split-string (match-string 1))))
+ (about (match-string 2))
+ (combined (length= ranges 3))
+ (value (cons about ranges)))
+ (magit-delete-line)
+ (magit-insert-section section (hunk value)
+ (insert (propertize (concat heading "\n")
+ 'font-lock-face 'magit-diff-hunk-heading))
+ (magit-insert-heading)
+ (while (not (or (eobp) (looking-at "^[^-+\s\\]")))
+ (forward-line))
+ (oset section end (point))
+ (oset section washer #'magit-diff-paint-hunk)
+ (oset section combined combined)
+ (if combined
+ (oset section from-ranges (butlast ranges))
+ (oset section from-range (car ranges)))
+ (oset section to-range (car (last ranges)))
+ (oset section about about)))
+ t))
+
+(defun magit-diff-expansion-threshold (section)
+ "Keep new diff sections collapsed if washing takes too long."
+ (and (magit-file-section-p section)
+ (> (float-time (time-subtract (current-time) magit-refresh-start-time))
+ magit-diff-expansion-threshold)
+ 'hide))
+
+(add-hook 'magit-section-set-visibility-hook #'magit-diff-expansion-threshold)
+
+;;; Revision Mode
+
+(define-derived-mode magit-revision-mode magit-diff-mode "Magit Rev"
+ "Mode for looking at a Git commit.
+
+This mode is documented in info node `(magit)Revision Buffer'.
+
+\\<magit-mode-map>\
+Type \\[magit-refresh] to refresh the current buffer.
+Type \\[magit-section-toggle] to expand or hide the section at point.
+Type \\[magit-visit-thing] to visit the hunk or file at point.
+
+Staging and applying changes is documented in info node
+`(magit)Staging and Unstaging' and info node `(magit)Applying'.
+
+\\<magit-hunk-section-map>Type \
+\\[magit-apply] to apply the change at point, \
+\\[magit-stage] to stage,
+\\[magit-unstage] to unstage, \
+\\[magit-discard] to discard, or \
+\\[magit-reverse] to reverse it.
+
+\\{magit-revision-mode-map}"
+ :group 'magit-revision
+ (hack-dir-local-variables-non-file-buffer))
+
+(put 'magit-revision-mode 'magit-diff-default-arguments
+ '("--stat" "--no-ext-diff"))
+
+(defun magit-revision-setup-buffer (rev args files)
+ (magit-setup-buffer #'magit-revision-mode nil
+ (magit-buffer-revision rev)
+ (magit-buffer-range (format "%s^..%s" rev rev))
+ (magit-buffer-diff-args args)
+ (magit-buffer-diff-files files)
+ (magit-buffer-diff-files-suspended nil)))
+
+(defun magit-revision-refresh-buffer ()
+ (setq magit-buffer-revision-hash (magit-rev-hash magit-buffer-revision))
+ (magit-set-header-line-format
+ (concat (magit-object-type magit-buffer-revision-hash)
+ " " magit-buffer-revision
+ (pcase (length magit-buffer-diff-files)
+ (0)
+ (1 (concat " limited to file " (car magit-buffer-diff-files)))
+ (_ (concat " limited to files "
+ (mapconcat #'identity magit-buffer-diff-files ", "))))))
+ (magit-insert-section (commitbuf)
+ (magit-run-section-hook 'magit-revision-sections-hook)))
+
+(cl-defmethod magit-buffer-value (&context (major-mode magit-revision-mode))
+ (cons magit-buffer-revision magit-buffer-diff-files))
+
+(defun magit-insert-revision-diff ()
+ "Insert the diff into this `magit-revision-mode' buffer."
+ (magit--insert-diff
+ "show" "-p" "--cc" "--format=" "--no-prefix"
+ (and (member "--stat" magit-buffer-diff-args) "--numstat")
+ magit-buffer-diff-args
+ (magit--rev-dereference magit-buffer-revision)
+ "--" magit-buffer-diff-files))
+
+(defun magit-insert-revision-tag ()
+ "Insert tag message and headers into a revision buffer.
+This function only inserts anything when `magit-show-commit' is
+called with a tag as argument, when that is called with a commit
+or a ref which is not a branch, then it inserts nothing."
+ (when (equal (magit-object-type magit-buffer-revision) "tag")
+ (magit-insert-section (taginfo)
+ (let ((beg (point)))
+ ;; "git verify-tag -v" would output what we need, but the gpg
+ ;; output is send to stderr and we have no control over the
+ ;; order in which stdout and stderr are inserted, which would
+ ;; make parsing hard. We are forced to use "git cat-file tag"
+ ;; instead, which inserts the signature instead of verifying
+ ;; it. We remove that later and then insert the verification
+ ;; output using "git verify-tag" (without the "-v").
+ (magit-git-insert "cat-file" "tag" magit-buffer-revision)
+ (goto-char beg)
+ (forward-line 3)
+ (delete-region beg (point)))
+ (looking-at "^tagger \\([^<]+\\) <\\([^>]+\\)")
+ (let ((heading (format "Tagger: %s <%s>"
+ (match-string 1)
+ (match-string 2))))
+ (magit-delete-line)
+ (insert (propertize heading 'font-lock-face
+ 'magit-section-secondary-heading)))
+ (magit-insert-heading)
+ (forward-line)
+ (magit-insert-section section (message)
+ (oset section heading-highlight-face
+ 'magit-diff-revision-summary-highlight)
+ (let ((beg (point)))
+ (forward-line)
+ (magit--add-face-text-property
+ beg (point) 'magit-diff-revision-summary))
+ (magit-insert-heading)
+ (if (re-search-forward "-----BEGIN PGP SIGNATURE-----" nil t)
+ (goto-char (match-beginning 0))
+ (goto-char (point-max)))
+ (insert ?\n))
+ (if (re-search-forward "-----BEGIN PGP SIGNATURE-----" nil t)
+ (progn
+ (let ((beg (match-beginning 0)))
+ (re-search-forward "-----END PGP SIGNATURE-----\n")
+ (delete-region beg (point)))
+ (save-excursion
+ (magit-process-git t "verify-tag" magit-buffer-revision))
+ (magit-diff-wash-signature magit-buffer-revision))
+ (goto-char (point-max)))
+ (insert ?\n))))
+
+(defvar magit-commit-message-section-map
+ (let ((map (make-sparse-keymap)))
+ (magit-menu-set map [magit-visit-thing] #'magit-show-commit "Visit %t"
+ '(:enable (magit-thing-at-point 'git-revision t)))
+ map)
+ "Keymap for `commit-message' sections.")
+
+(defun magit-insert-revision-message ()
+ "Insert the commit message into a revision buffer."
+ (magit-insert-section section (commit-message)
+ (oset section heading-highlight-face 'magit-diff-revision-summary-highlight)
+ (let ((beg (point))
+ (rev magit-buffer-revision))
+ (insert (with-temp-buffer
+ (magit-rev-insert-format "%B" rev)
+ (magit-revision--wash-message)))
+ (if (= (point) (+ beg 2))
+ (progn (backward-delete-char 2)
+ (insert "(no message)\n"))
+ (goto-char beg)
+ (save-excursion
+ (while (search-forward "\r\n" nil t) ; Remove trailing CRs.
+ (delete-region (match-beginning 0) (1+ (match-beginning 0)))))
+ (when magit-revision-fill-summary-line
+ (let ((fill-column (min magit-revision-fill-summary-line
+ (window-width))))
+ (fill-region (point) (line-end-position))))
+ (when magit-revision-use-hash-sections
+ (save-excursion
+ ;; Start after beg to prevent a (commit text) section from
+ ;; starting at the same point as the (commit-message)
+ ;; section.
+ (goto-char (1+ beg))
+ (while (not (eobp))
+ (re-search-forward "\\_<" nil 'move)
+ (let ((beg (point)))
+ (re-search-forward "\\_>" nil t)
+ (when (> (point) beg)
+ (let ((text (buffer-substring-no-properties beg (point))))
+ (when (pcase magit-revision-use-hash-sections
+ ('quickest ; false negatives and positives
+ (and (>= (length text) 7)
+ (string-match-p "[0-9]" text)
+ (string-match-p "[a-z]" text)))
+ ('quicker ; false negatives (number-less hashes)
+ (and (>= (length text) 7)
+ (string-match-p "[0-9]" text)
+ (magit-commit-p text)))
+ ('quick ; false negatives (short hashes)
+ (and (>= (length text) 7)
+ (magit-commit-p text)))
+ ('slow
+ (magit-commit-p text)))
+ (put-text-property beg (point)
+ 'font-lock-face 'magit-hash)
+ (let ((end (point)))
+ (goto-char beg)
+ (magit-insert-section (commit text)
+ (goto-char end))))))))))
+ (save-excursion
+ (forward-line)
+ (magit--add-face-text-property
+ beg (point) 'magit-diff-revision-summary)
+ (magit-insert-heading))
+ (when magit-diff-highlight-keywords
+ (save-excursion
+ (while (re-search-forward "\\[[^[]*\\]" nil t)
+ (let ((beg (match-beginning 0))
+ (end (match-end 0)))
+ (put-text-property
+ beg end 'font-lock-face
+ (if-let ((face (get-text-property beg 'font-lock-face)))
+ (list face 'magit-keyword)
+ 'magit-keyword))))))
+ (goto-char (point-max))))))
+
+(defun magit-insert-revision-notes ()
+ "Insert commit notes into a revision buffer."
+ (let* ((var "core.notesRef")
+ (def (or (magit-get var) "refs/notes/commits")))
+ (dolist (ref (or (magit-list-active-notes-refs)))
+ (magit-insert-section section (notes ref (not (equal ref def)))
+ (oset section heading-highlight-face 'magit-diff-hunk-heading-highlight)
+ (let ((beg (point))
+ (rev magit-buffer-revision))
+ (insert (with-temp-buffer
+ (magit-git-insert "-c" (concat "core.notesRef=" ref)
+ "notes" "show" rev)
+ (magit-revision--wash-message)))
+ (if (= (point) beg)
+ (magit-cancel-section)
+ (goto-char beg)
+ (end-of-line)
+ (insert (format " (%s)"
+ (propertize (if (string-prefix-p "refs/notes/" ref)
+ (substring ref 11)
+ ref)
+ 'font-lock-face 'magit-refname)))
+ (forward-char)
+ (magit--add-face-text-property beg (point) 'magit-diff-hunk-heading)
+ (magit-insert-heading)
+ (goto-char (point-max))
+ (insert ?\n)))))))
+
+(defun magit-revision--wash-message ()
+ (let ((major-mode 'git-commit-mode))
+ (hack-dir-local-variables)
+ (hack-local-variables-apply))
+ (unless (memq git-commit-major-mode '(nil text-mode))
+ (funcall git-commit-major-mode)
+ (font-lock-ensure))
+ (buffer-string))
+
+(defun magit-insert-revision-headers ()
+ "Insert headers about the commit into a revision buffer."
+ (magit-insert-section (headers)
+ (--when-let (magit-rev-format "%D" magit-buffer-revision "--decorate=full")
+ (insert (magit-format-ref-labels it) ?\s))
+ (insert (propertize
+ (magit-rev-parse (magit--rev-dereference magit-buffer-revision))
+ 'font-lock-face 'magit-hash))
+ (magit-insert-heading)
+ (let ((beg (point)))
+ (magit-rev-insert-format magit-revision-headers-format
+ magit-buffer-revision)
+ (magit-insert-revision-gravatars magit-buffer-revision beg))
+ (when magit-revision-insert-related-refs
+ (dolist (parent (magit-commit-parents magit-buffer-revision))
+ (magit-insert-section (commit parent)
+ (let ((line (magit-rev-format "%h %s" parent)))
+ (string-match "^\\([^ ]+\\) \\(.*\\)" line)
+ (magit-bind-match-strings (hash msg) line
+ (insert "Parent: ")
+ (insert (propertize hash 'font-lock-face 'magit-hash))
+ (insert " " msg "\n")))))
+ (magit--insert-related-refs
+ magit-buffer-revision "--merged" "Merged"
+ (eq magit-revision-insert-related-refs 'all))
+ (magit--insert-related-refs
+ magit-buffer-revision "--contains" "Contained"
+ (memq magit-revision-insert-related-refs '(all mixed)))
+ (when-let ((follows (magit-get-current-tag magit-buffer-revision t)))
+ (let ((tag (car follows))
+ (cnt (cadr follows)))
+ (magit-insert-section (tag tag)
+ (insert
+ (format "Follows: %s (%s)\n"
+ (propertize tag 'font-lock-face 'magit-tag)
+ (propertize (number-to-string cnt)
+ 'font-lock-face 'magit-branch-local))))))
+ (when-let ((precedes (magit-get-next-tag magit-buffer-revision t)))
+ (let ((tag (car precedes))
+ (cnt (cadr precedes)))
+ (magit-insert-section (tag tag)
+ (insert (format "Precedes: %s (%s)\n"
+ (propertize tag 'font-lock-face 'magit-tag)
+ (propertize (number-to-string cnt)
+ 'font-lock-face 'magit-tag))))))
+ (insert ?\n))))
+
+(defun magit--insert-related-refs (rev arg title remote)
+ (when-let ((refs (magit-list-related-branches arg rev (and remote "-a"))))
+ (insert title ":" (make-string (- 10 (length title)) ?\s))
+ (dolist (branch refs)
+ (if (<= (+ (current-column) 1 (length branch))
+ (window-width))
+ (insert ?\s)
+ (insert ?\n (make-string 12 ?\s)))
+ (magit-insert-section (branch branch)
+ (insert (propertize branch 'font-lock-face
+ (if (string-prefix-p "remotes/" branch)
+ 'magit-branch-remote
+ 'magit-branch-local)))))
+ (insert ?\n)))
+
+(defun magit-insert-revision-gravatars (rev beg)
+ (when (and magit-revision-show-gravatars
+ (window-system))
+ (require 'gravatar)
+ (pcase-let ((`(,author . ,committer)
+ (pcase magit-revision-show-gravatars
+ ('t '("^Author: " . "^Commit: "))
+ ('author '("^Author: " . nil))
+ ('committer '(nil . "^Commit: "))
+ (_ magit-revision-show-gravatars))))
+ (--when-let (and author (magit-rev-format "%aE" rev))
+ (magit-insert-revision-gravatar beg rev it author))
+ (--when-let (and committer (magit-rev-format "%cE" rev))
+ (magit-insert-revision-gravatar beg rev it committer)))))
+
+(defun magit-insert-revision-gravatar (beg rev email regexp)
+ (save-excursion
+ (goto-char beg)
+ (when (re-search-forward regexp nil t)
+ (when-let ((window (get-buffer-window)))
+ (let* ((column (length (match-string 0)))
+ (font-obj (query-font (font-at (point) window)))
+ (size (* 2 (+ (aref font-obj 4)
+ (aref font-obj 5))))
+ (align-to (+ column
+ (ceiling (/ size (aref font-obj 7) 1.0))
+ 1))
+ (gravatar-size (- size 2)))
+ (ignore-errors ; service may be unreachable
+ (gravatar-retrieve email #'magit-insert-revision-gravatar-cb
+ (list gravatar-size rev
+ (point-marker)
+ align-to column))))))))
+
+(defun magit-insert-revision-gravatar-cb (image size rev marker align-to column)
+ (unless (eq image 'error)
+ (when-let ((buffer (marker-buffer marker)))
+ (with-current-buffer buffer
+ (save-excursion
+ (goto-char marker)
+ ;; The buffer might display another revision by now or
+ ;; it might have been refreshed, in which case another
+ ;; process might already have inserted the image.
+ (when (and (equal rev magit-buffer-revision)
+ (not (eq (car-safe
+ (car-safe
+ (get-text-property (point) 'display)))
+ 'image)))
+ (setf (image-property image :ascent) 'center)
+ (setf (image-property image :relief) 1)
+ (setf (image-property image :scale) 1)
+ (setf (image-property image :height) size)
+ (let ((top (list image '(slice 0.0 0.0 1.0 0.5)))
+ (bot (list image '(slice 0.0 0.5 1.0 1.0)))
+ (align `((space :align-to ,align-to))))
+ (when magit-revision-use-gravatar-kludge
+ (cl-rotatef top bot))
+ (let ((inhibit-read-only t))
+ (insert (propertize " " 'display top))
+ (insert (propertize " " 'display align))
+ (forward-line)
+ (forward-char column)
+ (insert (propertize " " 'display bot))
+ (insert (propertize " " 'display align))))))))))
+
+;;; Merge-Preview Mode
+
+(define-derived-mode magit-merge-preview-mode magit-diff-mode "Magit Merge"
+ "Mode for previewing a merge."
+ :group 'magit-diff
+ (hack-dir-local-variables-non-file-buffer))
+
+(put 'magit-merge-preview-mode 'magit-diff-default-arguments
+ '("--no-ext-diff"))
+
+(defun magit-merge-preview-setup-buffer (rev)
+ (magit-setup-buffer #'magit-merge-preview-mode nil
+ (magit-buffer-revision rev)
+ (magit-buffer-range (format "%s^..%s" rev rev))))
+
+(defun magit-merge-preview-refresh-buffer ()
+ (let* ((branch (magit-get-current-branch))
+ (head (or branch (magit-rev-verify "HEAD"))))
+ (magit-set-header-line-format (format "Preview merge of %s into %s"
+ magit-buffer-revision
+ (or branch "HEAD")))
+ (magit-insert-section (diffbuf)
+ (magit--insert-diff
+ "merge-tree" (magit-git-string "merge-base" head magit-buffer-revision)
+ head magit-buffer-revision))))
+
+(cl-defmethod magit-buffer-value (&context (major-mode magit-merge-preview-mode))
+ magit-buffer-revision)
+
+;;; Diff Sections
+
+(defun magit-hunk-set-window-start (section)
+ "When SECTION is a `hunk', ensure that its beginning is visible.
+It the SECTION has a different type, then do nothing."
+ (when (magit-hunk-section-p section)
+ (magit-section-set-window-start section)))
+
+(add-hook 'magit-section-movement-hook #'magit-hunk-set-window-start)
+
+(defun magit-hunk-goto-successor (section arg)
+ (and (magit-hunk-section-p section)
+ (and-let* ((parent (magit-get-section
+ (magit-section-ident
+ (oref section parent)))))
+ (let* ((children (oref parent children))
+ (siblings (magit-section-siblings section 'prev))
+ (previous (nth (length siblings) children)))
+ (if (not arg)
+ (--when-let (or previous (car (last children)))
+ (magit-section-goto it)
+ t)
+ (when previous
+ (magit-section-goto previous))
+ (if (and (stringp arg)
+ (re-search-forward arg (oref parent end) t))
+ (goto-char (match-beginning 0))
+ (goto-char (oref (car (last children)) end))
+ (forward-line -1)
+ (while (looking-at "^ ") (forward-line -1))
+ (while (looking-at "^[-+]") (forward-line -1))
+ (forward-line)))))))
+
+(add-hook 'magit-section-goto-successor-hook #'magit-hunk-goto-successor)
+
+(defvar magit-unstaged-section-map
+ (let ((map (make-sparse-keymap)))
+ (magit-menu-set map [magit-visit-thing] #'magit-diff-unstaged "Visit diff")
+ (magit-menu-set map [magit-stage-file] #'magit-stage "Stage all")
+ (magit-menu-set map [magit-delete-thing] #'magit-discard "Discard all")
+ map)
+ "Keymap for the `unstaged' section.")
+
+(magit-define-section-jumper magit-jump-to-unstaged "Unstaged changes" unstaged)
+
+(defun magit-insert-unstaged-changes ()
+ "Insert section showing unstaged changes."
+ (magit-insert-section (unstaged)
+ (magit-insert-heading "Unstaged changes:")
+ (magit--insert-diff
+ "diff" magit-buffer-diff-args "--no-prefix"
+ "--" magit-buffer-diff-files)))
+
+(defvar magit-staged-section-map
+ (let ((map (make-sparse-keymap)))
+ (magit-menu-set map [magit-visit-thing] #'magit-diff-staged "Visit diff")
+ (magit-menu-set map [magit-unstage-file] #'magit-unstage "Unstage all")
+ (magit-menu-set map [magit-delete-thing] #'magit-discard "Discard all")
+ (magit-menu-set map [magit-revert-no-commit] #'magit-reverse "Reverse all")
+ map)
+ "Keymap for the `staged' section.")
+
+(magit-define-section-jumper magit-jump-to-staged "Staged changes" staged)
+
+(defun magit-insert-staged-changes ()
+ "Insert section showing staged changes."
+ ;; Avoid listing all files as deleted when visiting a bare repo.
+ (unless (magit-bare-repo-p)
+ (magit-insert-section (staged)
+ (magit-insert-heading "Staged changes:")
+ (magit--insert-diff
+ "diff" "--cached" magit-buffer-diff-args "--no-prefix"
+ "--" magit-buffer-diff-files))))
+
+;;; Diff Type
+
+(defun magit-diff-type (&optional section)
+ "Return the diff type of SECTION.
+
+The returned type is one of the symbols `staged', `unstaged',
+`committed', or `undefined'. This type serves a similar purpose
+as the general type common to all sections (which is stored in
+the `type' slot of the corresponding `magit-section' struct) but
+takes additional information into account. When the SECTION
+isn't related to diffs and the buffer containing it also isn't
+a diff-only buffer, then return nil.
+
+Currently the type can also be one of `tracked' and `untracked'
+but these values are not handled explicitly everywhere they
+should be and a possible fix could be to just return nil here.
+
+The section has to be a `diff' or `hunk' section, or a section
+whose children are of type `diff'. If optional SECTION is nil,
+return the diff type for the current section. In buffers whose
+major mode is `magit-diff-mode' SECTION is ignored and the type
+is determined using other means. In `magit-revision-mode'
+buffers the type is always `committed'.
+
+Do not confuse this with `magit-diff-scope' (which see)."
+ (--when-let (or section (magit-current-section))
+ (cond ((derived-mode-p 'magit-revision-mode 'magit-stash-mode) 'committed)
+ ((derived-mode-p 'magit-diff-mode)
+ (let ((range magit-buffer-range)
+ (const magit-buffer-typearg))
+ (cond ((equal const "--no-index") 'undefined)
+ ((or (not range)
+ (magit-rev-eq range "HEAD"))
+ (if (equal const "--cached")
+ 'staged
+ 'unstaged))
+ ((equal const "--cached")
+ (if (magit-rev-head-p range)
+ 'staged
+ 'undefined)) ; i.e. committed and staged
+ (t 'committed))))
+ ((derived-mode-p 'magit-status-mode)
+ (let ((stype (oref it type)))
+ (if (memq stype '(staged unstaged tracked untracked))
+ stype
+ (pcase stype
+ ((or 'file 'module)
+ (let* ((parent (oref it parent))
+ (type (oref parent type)))
+ (if (memq type '(file module))
+ (magit-diff-type parent)
+ type)))
+ ('hunk (thread-first it
+ (oref parent)
+ (oref parent)
+ (oref type)))))))
+ ((derived-mode-p 'magit-log-mode)
+ (if (or (and (magit-section-match 'commit section)
+ (oref section children))
+ (magit-section-match [* file commit] section))
+ 'committed
+ 'undefined))
+ (t 'undefined))))
+
+(cl-defun magit-diff-scope (&optional (section nil ssection) strict)
+ "Return the diff scope of SECTION or the selected section(s).
+
+A diff's \"scope\" describes what part of a diff is selected, it is
+a symbol, one of `region', `hunk', `hunks', `file', `files', or
+`list'. Do not confuse this with the diff \"type\", as returned by
+`magit-diff-type'.
+
+If optional SECTION is non-nil, then return the scope of that,
+ignoring the sections selected by the region. Otherwise return
+the scope of the current section, or if the region is active and
+selects a valid group of diff related sections, the type of these
+sections, i.e. `hunks' or `files'. If SECTION, or if that is nil
+the current section, is a `hunk' section; and the region region
+starts and ends inside the body of a that section, then the type
+is `region'. If the region is empty after a mouse click, then
+`hunk' is returned instead of `region'.
+
+If optional STRICT is non-nil, then return nil if the diff type of
+the section at point is `untracked' or the section at point is not
+actually a `diff' but a `diffstat' section."
+ (let ((siblings (and (not ssection) (magit-region-sections nil t))))
+ (setq section (or section (car siblings) (magit-current-section)))
+ (when (and section
+ (or (not strict)
+ (and (not (eq (magit-diff-type section) 'untracked))
+ (not (eq (--when-let (oref section parent)
+ (oref it type))
+ 'diffstat)))))
+ (pcase (list (oref section type)
+ (and siblings t)
+ (magit-diff-use-hunk-region-p)
+ ssection)
+ (`(hunk nil t ,_)
+ (if (magit-section-internal-region-p section) 'region 'hunk))
+ ('(hunk t t nil) 'hunks)
+ (`(hunk ,_ ,_ ,_) 'hunk)
+ ('(file t t nil) 'files)
+ (`(file ,_ ,_ ,_) 'file)
+ ('(module t t nil) 'files)
+ (`(module ,_ ,_ ,_) 'file)
+ (`(,(or 'staged 'unstaged 'untracked) nil ,_ ,_) 'list)))))
+
+(defun magit-diff-use-hunk-region-p ()
+ (and (region-active-p)
+ ;; TODO implement this from first principals
+ ;; currently it's trial-and-error
+ (not (and (or (eq this-command #'mouse-drag-region)
+ (eq last-command #'mouse-drag-region)
+ ;; When another window was previously
+ ;; selected then the last-command is
+ ;; some byte-code function.
+ (byte-code-function-p last-command))
+ (eq (region-end) (region-beginning))))))
+
+;;; Diff Highlight
+
+(add-hook 'magit-section-unhighlight-hook #'magit-diff-unhighlight)
+(add-hook 'magit-section-highlight-hook #'magit-diff-highlight)
+
+(defun magit-diff-unhighlight (section selection)
+ "Remove the highlighting of the diff-related SECTION."
+ (when (magit-hunk-section-p section)
+ (magit-diff-paint-hunk section selection nil)
+ t))
+
+(defun magit-diff-highlight (section selection)
+ "Highlight the diff-related SECTION.
+If SECTION is not a diff-related section, then do nothing and
+return nil. If SELECTION is non-nil, then it is a list of sections
+selected by the region, including SECTION. All of these sections
+are highlighted."
+ (if (and (magit-section-match 'commit section)
+ (oref section children))
+ (progn (if selection
+ (dolist (section selection)
+ (magit-diff-highlight-list section selection))
+ (magit-diff-highlight-list section))
+ t)
+ (when-let ((scope (magit-diff-scope section t)))
+ (cond ((eq scope 'region)
+ (magit-diff-paint-hunk section selection t))
+ (selection
+ (dolist (section selection)
+ (magit-diff-highlight-recursive section selection)))
+ (t
+ (magit-diff-highlight-recursive section)))
+ t)))
+
+(defun magit-diff-highlight-recursive (section &optional selection)
+ (pcase (magit-diff-scope section)
+ ('list (magit-diff-highlight-list section selection))
+ ('file (magit-diff-highlight-file section selection))
+ ('hunk (magit-diff-highlight-heading section selection)
+ (magit-diff-paint-hunk section selection t))
+ (_ (magit-section-highlight section nil))))
+
+(defun magit-diff-highlight-list (section &optional selection)
+ (let ((beg (oref section start))
+ (cnt (oref section content))
+ (end (oref section end)))
+ (when (or (eq this-command #'mouse-drag-region)
+ (not selection))
+ (unless (and (region-active-p)
+ (<= (region-beginning) beg))
+ (magit-section-make-overlay beg cnt 'magit-section-highlight))
+ (if (oref section hidden)
+ (oset section washer #'ignore)
+ (dolist (child (oref section children))
+ (when (or (eq this-command #'mouse-drag-region)
+ (not (and (region-active-p)
+ (<= (region-beginning)
+ (oref child start)))))
+ (magit-diff-highlight-recursive child selection)))))
+ (when magit-diff-highlight-hunk-body
+ (magit-section-make-overlay (1- end) end 'magit-section-highlight))))
+
+(defun magit-diff-highlight-file (section &optional selection)
+ (magit-diff-highlight-heading section selection)
+ (when (or (not (oref section hidden))
+ (cl-typep section 'magit-module-section))
+ (dolist (child (oref section children))
+ (magit-diff-highlight-recursive child selection))))
+
+(defun magit-diff-highlight-heading (section &optional selection)
+ (magit-section-make-overlay
+ (oref section start)
+ (or (oref section content)
+ (oref section end))
+ (pcase (list (oref section type)
+ (and (member section selection)
+ (not (eq this-command #'mouse-drag-region))))
+ ('(file t) 'magit-diff-file-heading-selection)
+ ('(file nil) 'magit-diff-file-heading-highlight)
+ ('(module t) 'magit-diff-file-heading-selection)
+ ('(module nil) 'magit-diff-file-heading-highlight)
+ ('(hunk t) 'magit-diff-hunk-heading-selection)
+ ('(hunk nil) 'magit-diff-hunk-heading-highlight))))
+
+;;; Hunk Paint
+
+(cl-defun magit-diff-paint-hunk
+ (section &optional selection
+ (highlight (magit-section-selected-p section selection)))
+ (let (paint)
+ (unless magit-diff-highlight-hunk-body
+ (setq highlight nil))
+ (cond (highlight
+ (unless (oref section hidden)
+ (add-to-list 'magit-section-highlighted-sections section)
+ (cond ((memq section magit-section-unhighlight-sections)
+ (setq magit-section-unhighlight-sections
+ (delq section magit-section-unhighlight-sections)))
+ (magit-diff-highlight-hunk-body
+ (setq paint t)))))
+ (t
+ (cond ((and (oref section hidden)
+ (memq section magit-section-unhighlight-sections))
+ (add-to-list 'magit-section-highlighted-sections section)
+ (setq magit-section-unhighlight-sections
+ (delq section magit-section-unhighlight-sections)))
+ (t
+ (setq paint t)))))
+ (when paint
+ (save-excursion
+ (goto-char (oref section start))
+ (let ((end (oref section end))
+ (merging (looking-at "@@@"))
+ (diff-type (magit-diff-type))
+ (stage nil)
+ (tab-width (magit-diff-tab-width
+ (magit-section-parent-value section))))
+ (forward-line)
+ (while (< (point) end)
+ (when (and magit-diff-hide-trailing-cr-characters
+ (char-equal ?\r (char-before (line-end-position))))
+ (put-text-property (1- (line-end-position)) (line-end-position)
+ 'invisible t))
+ (put-text-property
+ (point) (1+ (line-end-position)) 'font-lock-face
+ (cond
+ ((looking-at "^\\+\\+?\\([<=|>]\\)\\{7\\}")
+ (setq stage (pcase (list (match-string 1) highlight)
+ ('("<" nil) 'magit-diff-our)
+ ('("<" t) 'magit-diff-our-highlight)
+ ('("|" nil) 'magit-diff-base)
+ ('("|" t) 'magit-diff-base-highlight)
+ ('("=" nil) 'magit-diff-their)
+ ('("=" t) 'magit-diff-their-highlight)
+ ('(">" nil) nil)))
+ 'magit-diff-conflict-heading)
+ ((looking-at (if merging "^\\(\\+\\| \\+\\)" "^\\+"))
+ (magit-diff-paint-tab merging tab-width)
+ (magit-diff-paint-whitespace merging 'added diff-type)
+ (or stage
+ (if highlight 'magit-diff-added-highlight 'magit-diff-added)))
+ ((looking-at (if merging "^\\(-\\| -\\)" "^-"))
+ (magit-diff-paint-tab merging tab-width)
+ (magit-diff-paint-whitespace merging 'removed diff-type)
+ (if highlight 'magit-diff-removed-highlight 'magit-diff-removed))
+ (t
+ (magit-diff-paint-tab merging tab-width)
+ (magit-diff-paint-whitespace merging 'context diff-type)
+ (if highlight 'magit-diff-context-highlight 'magit-diff-context))))
+ (forward-line))))))
+ (magit-diff-update-hunk-refinement section))
+
+(defvar magit-diff--tab-width-cache nil)
+
+(defun magit-diff-tab-width (file)
+ (setq file (expand-file-name file))
+ (cl-flet ((cache (value)
+ (let ((elt (assoc file magit-diff--tab-width-cache)))
+ (if elt
+ (setcdr elt value)
+ (setq magit-diff--tab-width-cache
+ (cons (cons file value)
+ magit-diff--tab-width-cache))))
+ value))
+ (cond
+ ((not magit-diff-adjust-tab-width)
+ tab-width)
+ ((and-let* ((buffer (find-buffer-visiting file)))
+ (cache (buffer-local-value 'tab-width buffer))))
+ ((and-let* ((elt (assoc file magit-diff--tab-width-cache)))
+ (or (cdr elt)
+ tab-width)))
+ ((or (eq magit-diff-adjust-tab-width 'always)
+ (and (numberp magit-diff-adjust-tab-width)
+ (>= magit-diff-adjust-tab-width
+ (nth 7 (file-attributes file)))))
+ (cache (buffer-local-value 'tab-width (find-file-noselect file))))
+ (t
+ (cache nil)
+ tab-width))))
+
+(defun magit-diff-paint-tab (merging width)
+ (save-excursion
+ (forward-char (if merging 2 1))
+ (while (= (char-after) ?\t)
+ (put-text-property (point) (1+ (point))
+ 'display (list (list 'space :width width)))
+ (forward-char))))
+
+(defun magit-diff-paint-whitespace (merging line-type diff-type)
+ (when (and magit-diff-paint-whitespace
+ (or (not (memq magit-diff-paint-whitespace '(uncommitted status)))
+ (memq diff-type '(staged unstaged)))
+ (cl-case line-type
+ (added t)
+ (removed (memq magit-diff-paint-whitespace-lines '(all both)))
+ (context (memq magit-diff-paint-whitespace-lines '(all)))))
+ (let ((prefix (if merging "^[-\\+\s]\\{2\\}" "^[-\\+\s]"))
+ (indent
+ (if (local-variable-p 'magit-diff-highlight-indentation)
+ magit-diff-highlight-indentation
+ (setq-local
+ magit-diff-highlight-indentation
+ (cdr (--first (string-match-p (car it) default-directory)
+ (nreverse
+ (default-value
+ 'magit-diff-highlight-indentation))))))))
+ (when (and magit-diff-highlight-trailing
+ (looking-at (concat prefix ".*?\\([ \t]+\\)$")))
+ (let ((ov (make-overlay (match-beginning 1) (match-end 1) nil t)))
+ (overlay-put ov 'font-lock-face 'magit-diff-whitespace-warning)
+ (overlay-put ov 'priority 2)
+ (overlay-put ov 'evaporate t)))
+ (when (or (and (eq indent 'tabs)
+ (looking-at (concat prefix "\\( *\t[ \t]*\\)")))
+ (and (integerp indent)
+ (looking-at (format "%s\\([ \t]* \\{%s,\\}[ \t]*\\)"
+ prefix indent))))
+ (let ((ov (make-overlay (match-beginning 1) (match-end 1) nil t)))
+ (overlay-put ov 'font-lock-face 'magit-diff-whitespace-warning)
+ (overlay-put ov 'priority 2)
+ (overlay-put ov 'evaporate t))))))
+
+(defun magit-diff-update-hunk-refinement (&optional section)
+ (if section
+ (unless (oref section hidden)
+ (pcase (list magit-diff-refine-hunk
+ (oref section refined)
+ (eq section (magit-current-section)))
+ ((or `(all nil ,_) '(t nil t))
+ (oset section refined t)
+ (save-excursion
+ (goto-char (oref section start))
+ ;; `diff-refine-hunk' does not handle combined diffs.
+ (unless (looking-at "@@@")
+ (let ((smerge-refine-ignore-whitespace
+ magit-diff-refine-ignore-whitespace)
+ ;; Avoid fsyncing many small temp files
+ (write-region-inhibit-fsync t))
+ (diff-refine-hunk)))))
+ ((or `(nil t ,_) '(t t nil))
+ (oset section refined nil)
+ (remove-overlays (oref section start)
+ (oref section end)
+ 'diff-mode 'fine))))
+ (cl-labels ((recurse (section)
+ (if (magit-section-match 'hunk section)
+ (magit-diff-update-hunk-refinement section)
+ (dolist (child (oref section children))
+ (recurse child)))))
+ (recurse magit-root-section))))
+
+
+;;; Hunk Region
+
+(defun magit-diff-hunk-region-beginning ()
+ (save-excursion (goto-char (region-beginning))
+ (line-beginning-position)))
+
+(defun magit-diff-hunk-region-end ()
+ (save-excursion (goto-char (region-end))
+ (line-end-position)))
+
+(defun magit-diff-update-hunk-region (section)
+ "Highlight the hunk-internal region if any."
+ (when (and (eq (oref section type) 'hunk)
+ (eq (magit-diff-scope section t) 'region))
+ (magit-diff--make-hunk-overlay
+ (oref section start)
+ (1- (oref section content))
+ 'font-lock-face 'magit-diff-lines-heading
+ 'display (magit-diff-hunk-region-header section)
+ 'after-string (magit-diff--hunk-after-string 'magit-diff-lines-heading))
+ (run-hook-with-args 'magit-diff-highlight-hunk-region-functions section)
+ t))
+
+(defun magit-diff-highlight-hunk-region-dim-outside (section)
+ "Dim the parts of the hunk that are outside the hunk-internal region.
+This is done by using the same foreground and background color
+for added and removed lines as for context lines."
+ (let ((face (if magit-diff-highlight-hunk-body
+ 'magit-diff-context-highlight
+ 'magit-diff-context)))
+ (when magit-diff-unmarked-lines-keep-foreground
+ (setq face `(,@(and (>= emacs-major-version 27) '(:extend t))
+ :background ,(face-attribute face :background))))
+ (magit-diff--make-hunk-overlay (oref section content)
+ (magit-diff-hunk-region-beginning)
+ 'font-lock-face face
+ 'priority 2)
+ (magit-diff--make-hunk-overlay (1+ (magit-diff-hunk-region-end))
+ (oref section end)
+ 'font-lock-face face
+ 'priority 2)))
+
+(defun magit-diff-highlight-hunk-region-using-face (_section)
+ "Highlight the hunk-internal region by making it bold.
+Or rather highlight using the face `magit-diff-hunk-region', though
+changing only the `:weight' and/or `:slant' is recommended for that
+face."
+ (magit-diff--make-hunk-overlay (magit-diff-hunk-region-beginning)
+ (1+ (magit-diff-hunk-region-end))
+ 'font-lock-face 'magit-diff-hunk-region))
+
+(defun magit-diff-highlight-hunk-region-using-overlays (section)
+ "Emphasize the hunk-internal region using delimiting horizontal lines.
+This is implemented as single-pixel newlines places inside overlays."
+ (if (window-system)
+ (let ((beg (magit-diff-hunk-region-beginning))
+ (end (magit-diff-hunk-region-end))
+ (str (propertize
+ (concat (propertize "\s" 'display '(space :height (1)))
+ (propertize "\n" 'line-height t))
+ 'font-lock-face 'magit-diff-lines-boundary)))
+ (magit-diff--make-hunk-overlay beg (1+ beg) 'before-string str)
+ (magit-diff--make-hunk-overlay end (1+ end) 'after-string str))
+ (magit-diff-highlight-hunk-region-using-face section)))
+
+(defun magit-diff-highlight-hunk-region-using-underline (section)
+ "Emphasize the hunk-internal region using delimiting horizontal lines.
+This is implemented by overlining and underlining the first and
+last (visual) lines of the region."
+ (if (window-system)
+ (let* ((beg (magit-diff-hunk-region-beginning))
+ (end (magit-diff-hunk-region-end))
+ (beg-eol (save-excursion (goto-char beg)
+ (end-of-visual-line)
+ (point)))
+ (end-bol (save-excursion (goto-char end)
+ (beginning-of-visual-line)
+ (point)))
+ (color (face-background 'magit-diff-lines-boundary nil t)))
+ (cl-flet ((ln (b e &rest face)
+ (magit-diff--make-hunk-overlay
+ b e 'font-lock-face face 'after-string
+ (magit-diff--hunk-after-string face))))
+ (if (= beg end-bol)
+ (ln beg beg-eol :overline color :underline color)
+ (ln beg beg-eol :overline color)
+ (ln end-bol end :underline color))))
+ (magit-diff-highlight-hunk-region-using-face section)))
+
+(defun magit-diff--make-hunk-overlay (start end &rest args)
+ (let ((ov (make-overlay start end nil t)))
+ (overlay-put ov 'evaporate t)
+ (while args (overlay-put ov (pop args) (pop args)))
+ (push ov magit-section--region-overlays)
+ ov))
+
+(defun magit-diff--hunk-after-string (face)
+ (propertize "\s"
+ 'font-lock-face face
+ 'display (list 'space :align-to
+ `(+ (0 . right)
+ ,(min (window-hscroll)
+ (- (line-end-position)
+ (line-beginning-position)))))
+ ;; This prevents the cursor from being rendered at the
+ ;; edge of the window.
+ 'cursor t))
+
+;;; Hunk Utilities
+
+(defun magit-diff-inside-hunk-body-p ()
+ "Return non-nil if point is inside the body of a hunk."
+ (and (magit-section-match 'hunk)
+ (and-let* ((content (oref (magit-current-section) content)))
+ (> (magit-point) content))))
+
+;;; Diff Extract
+
+(defun magit-diff-file-header (section &optional no-rename)
+ (when (magit-hunk-section-p section)
+ (setq section (oref section parent)))
+ (and (magit-file-section-p section)
+ (let ((header (oref section header)))
+ (if no-rename
+ (replace-regexp-in-string
+ "^--- \\(.+\\)" (oref section value) header t t 1)
+ header))))
+
+(defun magit-diff-hunk-region-header (section)
+ (let ((patch (magit-diff-hunk-region-patch section)))
+ (string-match "\n" patch)
+ (substring patch 0 (1- (match-end 0)))))
+
+(defun magit-diff-hunk-region-patch (section &optional args)
+ (let ((op (if (member "--reverse" args) "+" "-"))
+ (sbeg (oref section start))
+ (rbeg (magit-diff-hunk-region-beginning))
+ (rend (region-end))
+ (send (oref section end))
+ (patch nil))
+ (save-excursion
+ (goto-char sbeg)
+ (while (< (point) send)
+ (looking-at "\\(.\\)\\([^\n]*\n\\)")
+ (cond ((or (string-match-p "[@ ]" (match-string-no-properties 1))
+ (and (>= (point) rbeg)
+ (<= (point) rend)))
+ (push (match-string-no-properties 0) patch))
+ ((equal op (match-string-no-properties 1))
+ (push (concat " " (match-string-no-properties 2)) patch)))
+ (forward-line)))
+ (let ((buffer-list-update-hook nil)) ; #3759
+ (with-temp-buffer
+ (insert (mapconcat #'identity (reverse patch) ""))
+ (diff-fixup-modifs (point-min) (point-max))
+ (setq patch (buffer-string))))
+ patch))
+
+;;; _
+(provide 'magit-diff)
+;;; magit-diff.el ends here
diff --git a/elpa/magit-20220503.1245/magit-diff.elc b/elpa/magit-20220503.1245/magit-diff.elc
new file mode 100644
index 0000000..bba73dc
--- /dev/null
+++ b/elpa/magit-20220503.1245/magit-diff.elc
Binary files differ
diff --git a/elpa/magit-20220503.1245/magit-ediff.el b/elpa/magit-20220503.1245/magit-ediff.el
new file mode 100644
index 0000000..057c174
--- /dev/null
+++ b/elpa/magit-20220503.1245/magit-ediff.el
@@ -0,0 +1,483 @@
+;;; magit-ediff.el --- Ediff extension for Magit -*- lexical-binding:t -*-
+
+;; Copyright (C) 2008-2022 The Magit Project Contributors
+
+;; Author: Jonas Bernoulli <jonas@bernoul.li>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+
+;; SPDX-License-Identifier: GPL-3.0-or-later
+
+;; Magit 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.
+;;
+;; Magit 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 Magit. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This library provides basic support for Ediff.
+
+;;; Code:
+
+(require 'magit)
+
+(require 'ediff)
+(require 'smerge-mode)
+
+(defvar smerge-ediff-buf)
+(defvar smerge-ediff-windows)
+
+;;; Options
+
+(defgroup magit-ediff nil
+ "Ediff support for Magit."
+ :link '(info-link "(magit)Ediffing")
+ :group 'magit-extensions)
+
+(defcustom magit-ediff-quit-hook
+ '(magit-ediff-cleanup-auxiliary-buffers
+ magit-ediff-restore-previous-winconf)
+ "Hooks to run after finishing Ediff, when that was invoked using Magit.
+The hooks are run in the Ediff control buffer. This is similar
+to `ediff-quit-hook' but takes the needs of Magit into account.
+The `ediff-quit-hook' is ignored by Ediff sessions which were
+invoked using Magit."
+ :package-version '(magit . "2.2.0")
+ :group 'magit-ediff
+ :type 'hook
+ :get #'magit-hook-custom-get
+ :options '(magit-ediff-cleanup-auxiliary-buffers
+ magit-ediff-restore-previous-winconf))
+
+(defcustom magit-ediff-dwim-show-on-hunks nil
+ "Whether `magit-ediff-dwim' runs show variants on hunks.
+If non-nil, `magit-ediff-show-staged' or
+`magit-ediff-show-unstaged' are called based on what section the
+hunk is in. Otherwise, `magit-ediff-dwim' runs
+`magit-ediff-stage' when point is on an uncommitted hunk."
+ :package-version '(magit . "2.2.0")
+ :group 'magit-ediff
+ :type 'boolean)
+
+(defcustom magit-ediff-show-stash-with-index t
+ "Whether `magit-ediff-show-stash' shows the state of the index.
+
+If non-nil, use a third Ediff buffer to distinguish which changes
+in the stash were staged. In cases where the stash contains no
+staged changes, fall back to a two-buffer Ediff.
+
+More specifically, a stash is a merge commit, stash@{N}, with
+potentially three parents.
+
+* stash@{N}^1 represents the `HEAD' commit at the time the stash
+ was created.
+
+* stash@{N}^2 records any changes that were staged when the stash
+ was made.
+
+* stash@{N}^3, if it exists, contains files that were untracked
+ when stashing.
+
+If this option is non-nil, `magit-ediff-show-stash' will run
+Ediff on a file using three buffers: one for stash@{N}, another
+for stash@{N}^1, and a third for stash@{N}^2.
+
+Otherwise, Ediff uses two buffers, comparing
+stash@{N}^1..stash@{N}. Along with any unstaged changes, changes
+in the index commit, stash@{N}^2, will be shown in this
+comparison unless they conflicted with changes in the working
+tree at the time of stashing."
+ :package-version '(magit . "2.6.0")
+ :group 'magit-ediff
+ :type 'boolean)
+
+(defvar magit-ediff-use-indirect-buffers nil
+ "Whether to use indirect buffers.
+Ediff already does a lot of buffer and file shuffling and I
+recommend you do not further complicate that by enabling this.")
+
+;;; Commands
+
+(defvar magit-ediff-previous-winconf nil)
+
+;;;###autoload (autoload 'magit-ediff "magit-ediff" nil)
+(transient-define-prefix magit-ediff ()
+ "Show differences using the Ediff package."
+ :info-manual "(ediff)"
+ ["Ediff"
+ [("E" "Dwim" magit-ediff-dwim)
+ ("s" "Stage" magit-ediff-stage)
+ ("m" "Resolve" magit-ediff-resolve)
+ ("t" "Resolve using mergetool" magit-git-mergetool)]
+ [("u" "Show unstaged" magit-ediff-show-unstaged)
+ ("i" "Show staged" magit-ediff-show-staged)
+ ("w" "Show worktree" magit-ediff-show-working-tree)]
+ [("c" "Show commit" magit-ediff-show-commit)
+ ("r" "Show range" magit-ediff-compare)
+ ("z" "Show stash" magit-ediff-show-stash)]])
+
+;;;###autoload
+(defun magit-ediff-resolve (file)
+ "Resolve outstanding conflicts in FILE using Ediff.
+FILE has to be relative to the top directory of the repository.
+
+In the rare event that you want to manually resolve all
+conflicts, including those already resolved by Git, use
+`ediff-merge-revisions-with-ancestor'."
+ (interactive (list (magit-read-unmerged-file)))
+ (magit-with-toplevel
+ (with-current-buffer (find-file-noselect file)
+ (smerge-ediff)
+ (setq-local
+ ediff-quit-hook
+ (lambda ()
+ (let ((bufC ediff-buffer-C)
+ (bufS smerge-ediff-buf))
+ (with-current-buffer bufS
+ (when (yes-or-no-p (format "Conflict resolution finished; save %s? "
+ buffer-file-name))
+ (erase-buffer)
+ (insert-buffer-substring bufC)
+ (save-buffer))))
+ (when (buffer-live-p ediff-buffer-A) (kill-buffer ediff-buffer-A))
+ (when (buffer-live-p ediff-buffer-B) (kill-buffer ediff-buffer-B))
+ (when (buffer-live-p ediff-buffer-C) (kill-buffer ediff-buffer-C))
+ (when (buffer-live-p ediff-ancestor-buffer)
+ (kill-buffer ediff-ancestor-buffer))
+ (let ((magit-ediff-previous-winconf smerge-ediff-windows))
+ (run-hooks 'magit-ediff-quit-hook)))))))
+
+(defmacro magit-ediff-buffers (quit &rest spec)
+ (declare (indent 1))
+ (let ((fn (if (length= spec 3) 'ediff-buffers3 'ediff-buffers))
+ (char ?@)
+ get make kill)
+ (pcase-dolist (`(,g ,m) spec)
+ (let ((b (intern (format "buf%c" (cl-incf char)))))
+ (push `(,b ,g) get)
+ (push `(if ,b
+ (if magit-ediff-use-indirect-buffers
+ (prog1
+ (make-indirect-buffer
+ ,b (generate-new-buffer-name (buffer-name ,b)) t)
+ (setq ,b nil))
+ ,b)
+ ,m)
+ make)
+ (push `(unless ,b
+ (ediff-kill-buffer-carefully
+ ,(intern (format "ediff-buffer-%c" char))))
+ kill)))
+ (setq get (nreverse get))
+ (setq make (nreverse make))
+ (setq kill (nreverse kill))
+ `(magit-with-toplevel
+ (let ((conf (current-window-configuration))
+ ,@get)
+ (,fn
+ ,@make
+ (list (lambda ()
+ (setq-local
+ ediff-quit-hook
+ (list ,@(and quit (list quit))
+ (lambda ()
+ ,@kill
+ (let ((magit-ediff-previous-winconf conf))
+ (run-hooks 'magit-ediff-quit-hook)))))))
+ ',fn)))))
+
+;;;###autoload
+(defun magit-ediff-stage (file)
+ "Stage and unstage changes to FILE using Ediff.
+FILE has to be relative to the top directory of the repository."
+ (interactive
+ (let ((files (magit-tracked-files)))
+ (list (magit-completing-read "Selectively stage file" files nil t nil nil
+ (car (member (magit-current-file) files))))))
+ (magit-with-toplevel
+ (let* ((bufA (magit-get-revision-buffer "HEAD" file))
+ (bufB (magit-get-revision-buffer "{index}" file))
+ (lockB (and bufB (buffer-local-value 'buffer-read-only bufB)))
+ (bufC (get-file-buffer file))
+ ;; Use the same encoding for all three buffers or we
+ ;; may end up changing the file in an unintended way.
+ (bufC* (or bufC (find-file-noselect file)))
+ (coding-system-for-read
+ (buffer-local-value 'buffer-file-coding-system bufC*))
+ (bufA* (magit-find-file-noselect-1 "HEAD" file t))
+ (bufB* (magit-find-file-index-noselect file t)))
+ (setf (buffer-local-value 'buffer-read-only bufB*) nil)
+ (magit-ediff-buffers
+ (lambda ()
+ (when (buffer-live-p ediff-buffer-B)
+ (when lockB
+ (setf (buffer-local-value 'buffer-read-only bufB) t))
+ (when (buffer-modified-p ediff-buffer-B)
+ (with-current-buffer ediff-buffer-B
+ (magit-update-index))))
+ (when (and (buffer-live-p ediff-buffer-C)
+ (buffer-modified-p ediff-buffer-C))
+ (with-current-buffer ediff-buffer-C
+ (when (y-or-n-p (format "Save file %s? " buffer-file-name))
+ (save-buffer)))))
+ (bufA bufA*)
+ (bufB bufB*)
+ (bufC bufC*)))))
+
+;;;###autoload
+(defun magit-ediff-compare (revA revB fileA fileB)
+ "Compare REVA:FILEA with REVB:FILEB using Ediff.
+
+FILEA and FILEB have to be relative to the top directory of the
+repository. If REVA or REVB is nil, then this stands for the
+working tree state.
+
+If the region is active, use the revisions on the first and last
+line of the region. With a prefix argument, instead of diffing
+the revisions, choose a revision to view changes along, starting
+at the common ancestor of both revisions (i.e., use a \"...\"
+range)."
+ (interactive
+ (pcase-let ((`(,revA ,revB) (magit-ediff-compare--read-revisions
+ nil current-prefix-arg)))
+ (nconc (list revA revB)
+ (magit-ediff-read-files revA revB))))
+ (magit-ediff-buffers nil
+ ((if revA (magit-get-revision-buffer revA fileA) (get-file-buffer fileA))
+ (if revA (magit-find-file-noselect revA fileA) (find-file-noselect fileA)))
+ ((if revB (magit-get-revision-buffer revB fileB) (get-file-buffer fileB))
+ (if revB (magit-find-file-noselect revB fileB) (find-file-noselect fileB)))))
+
+(defun magit-ediff-compare--read-revisions (&optional arg mbase)
+ (let ((input (or arg (magit-diff-read-range-or-commit
+ "Compare range or commit"
+ nil mbase))))
+ (--if-let (magit-split-range input)
+ (-cons-to-list it)
+ (list input nil))))
+
+(defun magit-ediff-read-files (revA revB &optional fileB)
+ "Read file in REVB, return it and the corresponding file in REVA.
+When FILEB is non-nil, use this as REVB's file instead of
+prompting for it."
+ (unless (and fileB (member fileB (magit-revision-files revB)))
+ (setq fileB
+ (or (and fileB
+ magit-buffer-log-files
+ (derived-mode-p 'magit-log-mode)
+ (member "--follow" magit-buffer-log-args)
+ (cdr (assoc fileB
+ (magit-renamed-files
+ revB
+ (oref (car (oref magit-root-section children))
+ value)))))
+ (magit-read-file-choice
+ (format "File to compare between %s and %s"
+ revA (or revB "the working tree"))
+ (magit-changed-files revA revB)
+ (format "No changed files between %s and %s"
+ revA (or revB "the working tree"))))))
+ (list (or (car (member fileB (magit-revision-files revA)))
+ (cdr (assoc fileB (magit-renamed-files revB revA)))
+ (magit-read-file-choice
+ (format "File in %s to compare with %s in %s"
+ revA fileB (or revB "the working tree"))
+ (magit-changed-files revB revA)
+ (format "No files have changed between %s and %s"
+ revA revB)))
+ fileB))
+
+;;;###autoload
+(defun magit-ediff-dwim ()
+ "Compare, stage, or resolve using Ediff.
+This command tries to guess what file, and what commit or range
+the user wants to compare, stage, or resolve using Ediff. It
+might only be able to guess either the file, or range or commit,
+in which case the user is asked about the other. It might not
+always guess right, in which case the appropriate `magit-ediff-*'
+command has to be used explicitly. If it cannot read the user's
+mind at all, then it asks the user for a command to run."
+ (interactive)
+ (magit-section-case
+ (hunk (save-excursion
+ (goto-char (oref (oref it parent) start))
+ (magit-ediff-dwim)))
+ (t
+ (let ((range (magit-diff--dwim))
+ (file (magit-current-file))
+ command revA revB)
+ (pcase range
+ ((and (guard (not magit-ediff-dwim-show-on-hunks))
+ (or 'unstaged 'staged))
+ (setq command (if (magit-anything-unmerged-p)
+ #'magit-ediff-resolve
+ #'magit-ediff-stage)))
+ ('unstaged (setq command #'magit-ediff-show-unstaged))
+ ('staged (setq command #'magit-ediff-show-staged))
+ (`(commit . ,value)
+ (setq command #'magit-ediff-show-commit)
+ (setq revB value))
+ (`(stash . ,value)
+ (setq command #'magit-ediff-show-stash)
+ (setq revB value))
+ ((pred stringp)
+ (pcase-let ((`(,a ,b) (magit-ediff-compare--read-revisions range)))
+ (setq command #'magit-ediff-compare)
+ (setq revA a)
+ (setq revB b)))
+ (_
+ (when (derived-mode-p 'magit-diff-mode)
+ (pcase (magit-diff-type)
+ ('committed (pcase-let ((`(,a ,b)
+ (magit-ediff-compare--read-revisions
+ magit-buffer-range)))
+ (setq revA a)
+ (setq revB b)))
+ ((guard (not magit-ediff-dwim-show-on-hunks))
+ (setq command #'magit-ediff-stage))
+ ('unstaged (setq command #'magit-ediff-show-unstaged))
+ ('staged (setq command #'magit-ediff-show-staged))
+ ('undefined (setq command nil))
+ (_ (setq command nil))))))
+ (cond ((not command)
+ (call-interactively
+ (magit-read-char-case
+ "Failed to read your mind; do you want to " t
+ (?c "[c]ommit" #'magit-ediff-show-commit)
+ (?r "[r]ange" #'magit-ediff-compare)
+ (?s "[s]tage" #'magit-ediff-stage)
+ (?v "resol[v]e" #'magit-ediff-resolve))))
+ ((eq command #'magit-ediff-compare)
+ (apply #'magit-ediff-compare revA revB
+ (magit-ediff-read-files revA revB file)))
+ ((eq command #'magit-ediff-show-commit)
+ (magit-ediff-show-commit revB))
+ ((eq command #'magit-ediff-show-stash)
+ (magit-ediff-show-stash revB))
+ (file
+ (funcall command file))
+ (t
+ (call-interactively command)))))))
+
+;;;###autoload
+(defun magit-ediff-show-staged (file)
+ "Show staged changes using Ediff.
+
+This only allows looking at the changes; to stage, unstage,
+and discard changes using Ediff, use `magit-ediff-stage'.
+
+FILE must be relative to the top directory of the repository."
+ (interactive
+ (list (magit-read-file-choice "Show staged changes for file"
+ (magit-staged-files)
+ "No staged files")))
+ (magit-ediff-buffers nil
+ ((magit-get-revision-buffer "HEAD" file)
+ (magit-find-file-noselect "HEAD" file))
+ ((get-buffer (concat file ".~{index}~"))
+ (magit-find-file-index-noselect file t))))
+
+;;;###autoload
+(defun magit-ediff-show-unstaged (file)
+ "Show unstaged changes using Ediff.
+
+This only allows looking at the changes; to stage, unstage,
+and discard changes using Ediff, use `magit-ediff-stage'.
+
+FILE must be relative to the top directory of the repository."
+ (interactive
+ (list (magit-read-file-choice "Show unstaged changes for file"
+ (magit-unstaged-files)
+ "No unstaged files")))
+ (magit-ediff-buffers nil
+ ((get-buffer (concat file ".~{index}~"))
+ (magit-find-file-index-noselect file t))
+ ((get-file-buffer file)
+ (find-file-noselect file))))
+
+;;;###autoload
+(defun magit-ediff-show-working-tree (file)
+ "Show changes between `HEAD' and working tree using Ediff.
+FILE must be relative to the top directory of the repository."
+ (interactive
+ (list (magit-read-file-choice "Show changes in file"
+ (magit-changed-files "HEAD")
+ "No changed files")))
+ (magit-ediff-buffers nil
+ ((magit-get-revision-buffer "HEAD" file)
+ (magit-find-file-noselect "HEAD" file))
+ ((get-file-buffer file)
+ (find-file-noselect file))))
+
+;;;###autoload
+(defun magit-ediff-show-commit (commit)
+ "Show changes introduced by COMMIT using Ediff."
+ (interactive (list (magit-read-branch-or-commit "Revision")))
+ (let ((revA (concat commit "^"))
+ (revB commit))
+ (apply #'magit-ediff-compare
+ revA revB
+ (magit-ediff-read-files revA revB (magit-current-file)))))
+
+;;;###autoload
+(defun magit-ediff-show-stash (stash)
+ "Show changes introduced by STASH using Ediff.
+`magit-ediff-show-stash-with-index' controls whether a
+three-buffer Ediff is used in order to distinguish changes in the
+stash that were staged."
+ (interactive (list (magit-read-stash "Stash")))
+ (pcase-let* ((revA (concat stash "^1"))
+ (revB (concat stash "^2"))
+ (revC stash)
+ (`(,fileA ,fileC) (magit-ediff-read-files revA revC))
+ (fileB fileC))
+ (if (and magit-ediff-show-stash-with-index
+ (member fileA (magit-changed-files revB revA)))
+ (magit-ediff-buffers nil
+ ((magit-get-revision-buffer revA fileA)
+ (magit-find-file-noselect revA fileA))
+ ((magit-get-revision-buffer revB fileB)
+ (magit-find-file-noselect revB fileB))
+ ((magit-get-revision-buffer revC fileC)
+ (magit-find-file-noselect revC fileC)))
+ (magit-ediff-compare revA revC fileA fileC))))
+
+(defun magit-ediff-cleanup-auxiliary-buffers ()
+ (let* ((ctl-buf ediff-control-buffer)
+ (ctl-win (ediff-get-visible-buffer-window ctl-buf))
+ (ctl-frm ediff-control-frame)
+ (main-frame (cond ((window-live-p ediff-window-A)
+ (window-frame ediff-window-A))
+ ((window-live-p ediff-window-B)
+ (window-frame ediff-window-B)))))
+ (ediff-kill-buffer-carefully ediff-diff-buffer)
+ (ediff-kill-buffer-carefully ediff-custom-diff-buffer)
+ (ediff-kill-buffer-carefully ediff-fine-diff-buffer)
+ (ediff-kill-buffer-carefully ediff-tmp-buffer)
+ (ediff-kill-buffer-carefully ediff-error-buffer)
+ (ediff-kill-buffer-carefully ediff-msg-buffer)
+ (ediff-kill-buffer-carefully ediff-debug-buffer)
+ (when (boundp 'ediff-patch-diagnostics)
+ (ediff-kill-buffer-carefully ediff-patch-diagnostics))
+ (cond ((and (ediff-window-display-p)
+ (frame-live-p ctl-frm))
+ (delete-frame ctl-frm))
+ ((window-live-p ctl-win)
+ (delete-window ctl-win)))
+ (ediff-kill-buffer-carefully ctl-buf)
+ (when (frame-live-p main-frame)
+ (select-frame main-frame))))
+
+(defun magit-ediff-restore-previous-winconf ()
+ (set-window-configuration magit-ediff-previous-winconf))
+
+;;; _
+(provide 'magit-ediff)
+;;; magit-ediff.el ends here
diff --git a/elpa/magit-20220503.1245/magit-ediff.elc b/elpa/magit-20220503.1245/magit-ediff.elc
new file mode 100644
index 0000000..91322a5
--- /dev/null
+++ b/elpa/magit-20220503.1245/magit-ediff.elc
Binary files differ
diff --git a/elpa/magit-20220503.1245/magit-extras.el b/elpa/magit-20220503.1245/magit-extras.el
new file mode 100644
index 0000000..c1a11d8
--- /dev/null
+++ b/elpa/magit-20220503.1245/magit-extras.el
@@ -0,0 +1,916 @@
+;;; magit-extras.el --- Additional functionality for Magit -*- lexical-binding:t -*-
+
+;; Copyright (C) 2008-2022 The Magit Project Contributors
+
+;; Author: Jonas Bernoulli <jonas@bernoul.li>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+
+;; SPDX-License-Identifier: GPL-3.0-or-later
+
+;; Magit 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.
+;;
+;; Magit 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 Magit. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Additional functionality for Magit.
+
+;;; Code:
+
+(require 'magit)
+
+;; For `magit-do-async-shell-command'.
+(declare-function dired-read-shell-command "dired-aux" (prompt arg files))
+;; For `magit-project-status'.
+(declare-function vc-git-command "vc-git"
+ (buffer okstatus file-or-list &rest flags))
+
+(defvar ido-exit)
+(defvar ido-fallback)
+(defvar project-prefix-map)
+(defvar project-switch-commands)
+
+(defgroup magit-extras nil
+ "Additional functionality for Magit."
+ :group 'magit-extensions)
+
+;;; Git Tools
+;;;; Git-Mergetool
+
+;;;###autoload (autoload 'magit-git-mergetool "magit-extras" nil t)
+(transient-define-prefix magit-git-mergetool (file args &optional transient)
+ "Resolve conflicts in FILE using \"git mergetool --gui\".
+With a prefix argument allow changing ARGS using a transient
+popup."
+ :man-page "git-mergetool"
+ ["Settings"
+ ("-t" magit-git-mergetool:--tool)
+ ("=t" magit-merge.guitool)
+ ("=T" magit-merge.tool)
+ ("-r" magit-mergetool.hideResolved)
+ ("-b" magit-mergetool.keepBackup)
+ ("-k" magit-mergetool.keepTemporaries)
+ ("-w" magit-mergetool.writeToTemp)]
+ ["Actions"
+ (" m" "Invoke mergetool" magit-git-mergetool)]
+ (interactive
+ (if (and (not (eq transient-current-prefix 'magit-git-mergetool))
+ current-prefix-arg)
+ (list nil nil t)
+ (list (magit-read-unmerged-file "Resolve")
+ (transient-args 'magit-git-mergetool))))
+ (if transient
+ (transient-setup 'magit-git-mergetool)
+ (magit-run-git-async "mergetool" "--gui" args "--" file)))
+
+(transient-define-infix magit-git-mergetool:--tool ()
+ :description "Override mergetool"
+ :class 'transient-option
+ :shortarg "-t"
+ :argument "--tool="
+ :reader #'magit--read-mergetool)
+
+(transient-define-infix magit-merge.guitool ()
+ :class 'magit--git-variable
+ :variable "merge.guitool"
+ :global t
+ :reader #'magit--read-mergetool)
+
+(transient-define-infix magit-merge.tool ()
+ :class 'magit--git-variable
+ :variable "merge.tool"
+ :global t
+ :reader #'magit--read-mergetool)
+
+(defun magit--read-mergetool (prompt _initial-input history)
+ (let ((choices nil)
+ (lines (cdr (magit-git-lines "mergetool" "--tool-help"))))
+ (while (string-prefix-p "\t\t" (car lines))
+ (push (substring (pop lines) 2) choices))
+ (setq choices (nreverse choices))
+ (magit-completing-read (or prompt "Select mergetool")
+ choices nil t nil history)))
+
+(transient-define-infix magit-mergetool.hideResolved ()
+ :class 'magit--git-variable:boolean
+ :variable "mergetool.hideResolved"
+ :default "false"
+ :global t)
+
+(transient-define-infix magit-mergetool.keepBackup ()
+ :class 'magit--git-variable:boolean
+ :variable "mergetool.keepBackup"
+ :default "true"
+ :global t)
+
+(transient-define-infix magit-mergetool.keepTemporaries ()
+ :class 'magit--git-variable:boolean
+ :variable "mergetool.keepTemporaries"
+ :default "false"
+ :global t)
+
+(transient-define-infix magit-mergetool.writeToTemp ()
+ :class 'magit--git-variable:boolean
+ :variable "mergetool.writeToTemp"
+ :default "false"
+ :global t)
+
+;;;; Git-Gui
+
+;;;###autoload
+(defun magit-run-git-gui-blame (commit filename &optional linenum)
+ "Run `git gui blame' on the given FILENAME and COMMIT.
+Interactively run it for the current file and the `HEAD', with a
+prefix or when the current file cannot be determined let the user
+choose. When the current buffer is visiting FILENAME instruct
+blame to center around the line point is on."
+ (interactive
+ (let (revision filename)
+ (when (or current-prefix-arg
+ (not (setq revision "HEAD"
+ filename (magit-file-relative-name nil 'tracked))))
+ (setq revision (magit-read-branch-or-commit "Blame from revision"))
+ (setq filename (magit-read-file-from-rev revision "Blame file")))
+ (list revision filename
+ (and (equal filename
+ (ignore-errors
+ (magit-file-relative-name buffer-file-name)))
+ (line-number-at-pos)))))
+ (magit-with-toplevel
+ (magit-process-git 0 "gui" "blame"
+ (and linenum (list (format "--line=%d" linenum)))
+ commit
+ filename)))
+
+;;;; Gitk
+
+(defcustom magit-gitk-executable
+ (or (and (eq system-type 'windows-nt)
+ (let ((exe (magit-git-string
+ "-c" "alias.X=!x() { which \"$1\" | cygpath -mf -; }; x"
+ "X" "gitk.exe")))
+ (and exe (file-executable-p exe) exe)))
+ (executable-find "gitk") "gitk")
+ "The Gitk executable."
+ :group 'magit-extras
+ :set-after '(magit-git-executable)
+ :type 'string)
+
+;;;###autoload
+(defun magit-run-git-gui ()
+ "Run `git gui' for the current git repository."
+ (interactive)
+ (magit-with-toplevel (magit-process-git 0 "gui")))
+
+;;;###autoload
+(defun magit-run-gitk ()
+ "Run `gitk' in the current repository."
+ (interactive)
+ (magit-process-file magit-gitk-executable nil 0))
+
+;;;###autoload
+(defun magit-run-gitk-branches ()
+ "Run `gitk --branches' in the current repository."
+ (interactive)
+ (magit-process-file magit-gitk-executable nil 0 nil "--branches"))
+
+;;;###autoload
+(defun magit-run-gitk-all ()
+ "Run `gitk --all' in the current repository."
+ (interactive)
+ (magit-process-file magit-gitk-executable nil 0 nil "--all"))
+
+;;; Emacs Tools
+
+;;;###autoload
+(defun ido-enter-magit-status ()
+ "Drop into `magit-status' from file switching.
+
+This command does not work in Emacs 26.1.
+See https://github.com/magit/magit/issues/3634
+and https://debbugs.gnu.org/cgi/bugreport.cgi?bug=31707.
+
+To make this command available use something like:
+
+ (add-hook \\='ido-setup-hook
+ (lambda ()
+ (define-key ido-completion-map
+ (kbd \"C-x g\") \\='ido-enter-magit-status)))
+
+Starting with Emacs 25.1 the Ido keymaps are defined just once
+instead of every time Ido is invoked, so now you can modify it
+like pretty much every other keymap:
+
+ (define-key ido-common-completion-map
+ (kbd \"C-x g\") \\='ido-enter-magit-status)"
+ (interactive)
+ (setq ido-exit 'fallback)
+ (setq ido-fallback #'magit-status) ; for Emacs >= 26.2
+ (with-no-warnings (setq fallback #'magit-status)) ; for Emacs 25
+ (exit-minibuffer))
+
+;;;###autoload
+(defun magit-project-status ()
+ "Run `magit-status' in the current project's root."
+ (interactive)
+ (if (fboundp 'project-root)
+ (magit-status-setup-buffer (project-root (project-current t)))
+ (user-error "`magit-project-status' requires `project' 0.3.0 or greater")))
+
+(defvar magit-bind-magit-project-status t
+ "Whether to bind \"m\" to `magit-project-status' in `project-prefix-map'.
+If so, then an entry is added to `project-switch-commands' as
+well. If you want to use another key, then you must set this
+to nil before loading Magit to prevent \"m\" from being bound.")
+
+(with-eval-after-load 'project
+ ;; Only more recent versions of project.el have `project-prefix-map' and
+ ;; `project-switch-commands', though project.el is available in Emacs 25.
+ (when (and magit-bind-magit-project-status
+ (boundp 'project-prefix-map)
+ ;; Only modify if it hasn't already been modified.
+ (equal project-switch-commands
+ (eval (car (get 'project-switch-commands 'standard-value))
+ t)))
+ (define-key project-prefix-map "m" #'magit-project-status)
+ (add-to-list 'project-switch-commands '(magit-project-status "Magit") t)))
+
+;;;###autoload
+(defun magit-dired-jump (&optional other-window)
+ "Visit file at point using Dired.
+With a prefix argument, visit in another window. If there
+is no file at point, then instead visit `default-directory'."
+ (interactive "P")
+ (dired-jump other-window
+ (and-let* ((file (magit-file-at-point)))
+ (expand-file-name (if (file-directory-p file)
+ (file-name-as-directory file)
+ file)))))
+
+;;;###autoload
+(defun magit-dired-log (&optional follow)
+ "Show log for all marked files, or the current file."
+ (interactive "P")
+ (if-let ((topdir (magit-toplevel default-directory)))
+ (let ((args (car (magit-log-arguments)))
+ (files (compat-dired-get-marked-files
+ nil nil #'magit-file-tracked-p nil
+ "No marked file is being tracked by Git")))
+ (when (and follow
+ (not (member "--follow" args))
+ (not (cdr files)))
+ (push "--follow" args))
+ (magit-log-setup-buffer
+ (list (or (magit-get-current-branch) "HEAD"))
+ args
+ (let ((default-directory topdir))
+ (mapcar #'file-relative-name files))
+ magit-log-buffer-file-locked))
+ (magit--not-inside-repository-error)))
+
+;;;###autoload
+(defun magit-dired-am-apply-patches (repo &optional arg)
+ "In Dired, apply the marked (or next ARG) files as patches.
+If inside a repository, then apply in that. Otherwise prompt
+for a repository."
+ (interactive (list (or (magit-toplevel)
+ (magit-read-repository t))
+ current-prefix-arg))
+ (let ((files (compat-dired-get-marked-files nil arg nil nil t)))
+ (magit-status-setup-buffer repo)
+ (magit-am-apply-patches files)))
+
+;;;###autoload
+(defun magit-do-async-shell-command (file)
+ "Open FILE with `dired-do-async-shell-command'.
+Interactively, open the file at point."
+ (interactive (list (or (magit-file-at-point)
+ (completing-read "Act on file: "
+ (magit-list-files)))))
+ (require 'dired-aux)
+ (dired-do-async-shell-command
+ (dired-read-shell-command "& on %s: " current-prefix-arg (list file))
+ nil (list file)))
+
+;;; Shift Selection
+
+(defun magit--turn-on-shift-select-mode-p ()
+ (and shift-select-mode
+ this-command-keys-shift-translated
+ (not mark-active)
+ (not (eq (car-safe transient-mark-mode) 'only))))
+
+;;;###autoload
+(defun magit-previous-line (&optional arg try-vscroll)
+ "Like `previous-line' but with Magit-specific shift-selection.
+
+Magit's selection mechanism is based on the region but selects an
+area that is larger than the region. This causes `previous-line'
+when invoked while holding the shift key to move up one line and
+thereby select two lines. When invoked inside a hunk body this
+command does not move point on the first invocation and thereby
+it only selects a single line. Which inconsistency you prefer
+is a matter of preference."
+ (declare (interactive-only
+ "use `forward-line' with negative argument instead."))
+ (interactive "p\np")
+ (unless arg (setq arg 1))
+ (let ((stay (or (magit-diff-inside-hunk-body-p)
+ (magit-section-position-in-heading-p))))
+ (if (and stay (= arg 1) (magit--turn-on-shift-select-mode-p))
+ (push-mark nil nil t)
+ (with-no-warnings
+ (handle-shift-selection)
+ (previous-line (if stay (max (1- arg) 1) arg) try-vscroll)))))
+
+;;;###autoload
+(defun magit-next-line (&optional arg try-vscroll)
+ "Like `next-line' but with Magit-specific shift-selection.
+
+Magit's selection mechanism is based on the region but selects
+an area that is larger than the region. This causes `next-line'
+when invoked while holding the shift key to move down one line
+and thereby select two lines. When invoked inside a hunk body
+this command does not move point on the first invocation and
+thereby it only selects a single line. Which inconsistency you
+prefer is a matter of preference."
+ (declare (interactive-only forward-line))
+ (interactive "p\np")
+ (unless arg (setq arg 1))
+ (let ((stay (or (magit-diff-inside-hunk-body-p)
+ (magit-section-position-in-heading-p))))
+ (if (and stay (= arg 1) (magit--turn-on-shift-select-mode-p))
+ (push-mark nil nil t)
+ (with-no-warnings
+ (handle-shift-selection)
+ (next-line (if stay (max (1- arg) 1) arg) try-vscroll)))))
+
+;;; Clean
+
+;;;###autoload
+(defun magit-clean (&optional arg)
+ "Remove untracked files from the working tree.
+With a prefix argument also remove ignored files,
+with two prefix arguments remove ignored files only.
+\n(git clean -f -d [-x|-X])"
+ (interactive "p")
+ (when (yes-or-no-p (format "Remove %s files? "
+ (pcase arg
+ (1 "untracked")
+ (4 "untracked and ignored")
+ (_ "ignored"))))
+ (magit-wip-commit-before-change)
+ (magit-run-git "clean" "-f" "-d" (pcase arg (4 "-x") (16 "-X")))))
+
+(put 'magit-clean 'disabled t)
+
+;;; ChangeLog
+
+;;;###autoload
+(defun magit-generate-changelog (&optional amending)
+ "Insert ChangeLog entries into the current buffer.
+
+The entries are generated from the diff being committed.
+If prefix argument, AMENDING, is non-nil, include changes
+in HEAD as well as staged changes in the diff to check."
+ (interactive "P")
+ (unless (magit-commit-message-buffer)
+ (user-error "No commit in progress"))
+ (require 'diff-mode) ; `diff-add-log-current-defuns'.
+ (require 'vc-git) ; `vc-git-diff'.
+ (require 'add-log) ; `change-log-insert-entries'.
+ (cond
+ ((and (fboundp 'change-log-insert-entries)
+ (fboundp 'diff-add-log-current-defuns))
+ (setq default-directory
+ (if (and (file-regular-p "gitdir")
+ (not (magit-git-true "rev-parse" "--is-inside-work-tree"))
+ (magit-git-true "rev-parse" "--is-inside-git-dir"))
+ (file-name-directory (magit-file-line "gitdir"))
+ (magit-toplevel)))
+ (let ((rev1 (if amending "HEAD^1" "HEAD"))
+ (rev2 nil))
+ ;; Magit may have updated the files without notifying vc, but
+ ;; `diff-add-log-current-defuns' relies on vc being up-to-date.
+ (mapc #'vc-file-clearprops (magit-staged-files))
+ (change-log-insert-entries
+ (with-temp-buffer
+ (vc-git-command (current-buffer) 1 nil
+ "diff-index" "--exit-code" "--patch"
+ (and (magit-anything-staged-p) "--cached")
+ rev1 "--")
+ ;; `diff-find-source-location' consults these vars.
+ (defvar diff-vc-revisions)
+ (setq-local diff-vc-revisions (list rev1 rev2))
+ (setq-local diff-vc-backend 'Git)
+ (diff-add-log-current-defuns)))))
+ (t (user-error "`magit-generate-changelog' requires Emacs 27 or greater"))))
+
+;;;###autoload
+(defun magit-add-change-log-entry (&optional whoami file-name other-window)
+ "Find change log file and add date entry and item for current change.
+This differs from `add-change-log-entry' (which see) in that
+it acts on the current hunk in a Magit buffer instead of on
+a position in a file-visiting buffer."
+ (interactive (list current-prefix-arg
+ (prompt-for-change-log-name)))
+ (pcase-let ((`(,buf ,pos) (magit-diff-visit-file--noselect)))
+ (magit--with-temp-position buf pos
+ (let ((add-log-buffer-file-name-function
+ (lambda ()
+ (or magit-buffer-file-name
+ (buffer-file-name)))))
+ (add-change-log-entry whoami file-name other-window)))))
+
+;;;###autoload
+(defun magit-add-change-log-entry-other-window (&optional whoami file-name)
+ "Find change log file in other window and add entry and item.
+This differs from `add-change-log-entry-other-window' (which see)
+in that it acts on the current hunk in a Magit buffer instead of
+on a position in a file-visiting buffer."
+ (interactive (and current-prefix-arg
+ (list current-prefix-arg
+ (prompt-for-change-log-name))))
+ (magit-add-change-log-entry whoami file-name t))
+
+;;; Edit Line Commit
+
+;;;###autoload
+(defun magit-edit-line-commit (&optional type)
+ "Edit the commit that added the current line.
+
+With a prefix argument edit the commit that removes the line,
+if any. The commit is determined using `git blame' and made
+editable using `git rebase --interactive' if it is reachable
+from `HEAD', or by checking out the commit (or a branch that
+points at it) otherwise."
+ (interactive (list (and current-prefix-arg 'removal)))
+ (let* ((chunk (magit-current-blame-chunk (or type 'addition)))
+ (rev (oref chunk orig-rev)))
+ (if (string-match-p "\\`0\\{40,\\}\\'" rev)
+ (message "This line has not been committed yet")
+ (let ((rebase (magit-rev-ancestor-p rev "HEAD"))
+ (file (expand-file-name (oref chunk orig-file)
+ (magit-toplevel))))
+ (if rebase
+ (let ((magit--rebase-published-symbol 'edit-published))
+ (magit-rebase-edit-commit rev (magit-rebase-arguments)))
+ (magit-checkout (or (magit-rev-branch rev) rev)))
+ (unless (and buffer-file-name
+ (file-equal-p file buffer-file-name))
+ (let ((blame-type (and magit-blame-mode magit-blame-type)))
+ (if rebase
+ (set-process-sentinel
+ magit-this-process
+ (lambda (process event)
+ (magit-sequencer-process-sentinel process event)
+ (when (eq (process-status process) 'exit)
+ (find-file file)
+ (when blame-type
+ (magit-blame--pre-blame-setup blame-type)
+ (magit-blame--run (magit-blame-arguments))))))
+ (find-file file)
+ (when blame-type
+ (magit-blame--pre-blame-setup blame-type)
+ (magit-blame--run (magit-blame-arguments))))))))))
+
+(put 'magit-edit-line-commit 'disabled t)
+
+;;;###autoload
+(defun magit-diff-edit-hunk-commit (file)
+ "From a hunk, edit the respective commit and visit the file.
+
+First visit the file being modified by the hunk at the correct
+location using `magit-diff-visit-file'. This actually visits a
+blob. When point is on a diff header, not within an individual
+hunk, then this visits the blob the first hunk is about.
+
+Then invoke `magit-edit-line-commit', which uses an interactive
+rebase to make the commit editable, or if that is not possible
+because the commit is not reachable from `HEAD' by checking out
+that commit directly. This also causes the actual worktree file
+to be visited.
+
+Neither the blob nor the file buffer are killed when finishing
+the rebase. If that is undesirable, then it might be better to
+use `magit-rebase-edit-command' instead of this command."
+ (interactive (list (magit-file-at-point t t)))
+ (let ((magit-diff-visit-previous-blob nil))
+ (with-current-buffer
+ (magit-diff-visit-file--internal file nil #'pop-to-buffer-same-window)
+ (magit-edit-line-commit))))
+
+(put 'magit-diff-edit-hunk-commit 'disabled t)
+
+;;; Reshelve
+
+(defcustom magit-reshelve-since-committer-only nil
+ "Whether `magit-reshelve-since' changes only the committer dates.
+Otherwise the author dates are also changed."
+ :package-version '(magit . "3.0.0")
+ :group 'magit-commands
+ :type 'boolean)
+
+;;;###autoload
+(defun magit-reshelve-since (rev keyid)
+ "Change the author and committer dates of the commits since REV.
+
+Ask the user for the first reachable commit whose dates should
+be changed. Then read the new date for that commit. The initial
+minibuffer input and the previous history element offer good
+values. The next commit will be created one minute later and so
+on.
+
+This command is only intended for interactive use and should only
+be used on highly rearranged and unpublished history.
+
+If KEYID is non-nil, then use that to sign all reshelved commits.
+Interactively use the value of the \"--gpg-sign\" option in the
+list returned by `magit-rebase-arguments'."
+ (interactive (list nil
+ (transient-arg-value "--gpg-sign="
+ (magit-rebase-arguments))))
+ (let* ((current (or (magit-get-current-branch)
+ (user-error "Refusing to reshelve detached head")))
+ (backup (concat "refs/original/refs/heads/" current)))
+ (cond
+ ((not rev)
+ (when (and (magit-ref-p backup)
+ (not (magit-y-or-n-p
+ (format "Backup ref %s already exists. Override? " backup))))
+ (user-error "Abort"))
+ (magit-log-select
+ (lambda (rev)
+ (magit-reshelve-since rev keyid))
+ "Type %p on a commit to reshelve it and the commits above it,"))
+ (t
+ (cl-flet ((adjust (time offset)
+ (format-time-string
+ "%F %T %z"
+ (+ (floor time)
+ (* offset 60)
+ (- (car (decode-time time)))))))
+ (let* ((start (concat rev "^"))
+ (range (concat start ".." current))
+ (time-rev (adjust (float-time (string-to-number
+ (magit-rev-format "%at" start)))
+ 1))
+ (time-now (adjust (float-time)
+ (- (string-to-number
+ (magit-git-string "rev-list" "--count"
+ range))))))
+ (push time-rev magit--reshelve-history)
+ (let ((date (floor
+ (float-time
+ (date-to-time
+ (read-string "Date for first commit: "
+ time-now 'magit--reshelve-history))))))
+ (with-environment-variables (("FILTER_BRANCH_SQUELCH_WARNING" "1"))
+ (magit-with-toplevel
+ (magit-run-git-async
+ "filter-branch" "--force" "--env-filter"
+ (format
+ "case $GIT_COMMIT in %s\nesac"
+ (mapconcat
+ (lambda (rev)
+ (prog1
+ (concat
+ (format "%s) " rev)
+ (and (not magit-reshelve-since-committer-only)
+ (format "export GIT_AUTHOR_DATE=\"%s\"; " date))
+ (format "export GIT_COMMITTER_DATE=\"%s\";;" date))
+ (cl-incf date 60)))
+ (magit-git-lines "rev-list" "--reverse" range)
+ " "))
+ (and keyid
+ (list "--commit-filter"
+ (format "git commit-tree --gpg-sign=%s \"$@\";"
+ keyid)))
+ range "--"))
+ (set-process-sentinel
+ magit-this-process
+ (lambda (process event)
+ (when (memq (process-status process) '(exit signal))
+ (if (> (process-exit-status process) 0)
+ (magit-process-sentinel process event)
+ (process-put process 'inhibit-refresh t)
+ (magit-process-sentinel process event)
+ (magit-run-git "update-ref" "-d" backup)))))))))))))
+
+;;; Revision Stack
+
+(defvar magit-revision-stack nil)
+
+(defcustom magit-pop-revision-stack-format
+ '("[%N: %h] "
+ "%N: %cs %H\n %s\n"
+ "\\[\\([0-9]+\\)[]:]")
+ "Control how `magit-pop-revision-stack' inserts a revision.
+
+The command `magit-pop-revision-stack' inserts a representation
+of the revision last pushed to the `magit-revision-stack' into
+the current buffer. It inserts text at point and/or near the end
+of the buffer, and removes the consumed revision from the stack.
+
+The entries on the stack have the format (HASH TOPLEVEL) and this
+option has the format (POINT-FORMAT EOB-FORMAT INDEX-REGEXP), all
+of which may be nil or a string (though either one of EOB-FORMAT
+or POINT-FORMAT should be a string, and if INDEX-REGEXP is
+non-nil, then the two formats should be too).
+
+First INDEX-REGEXP is used to find the previously inserted entry,
+by searching backward from point. The first submatch must match
+the index number. That number is incremented by one, and becomes
+the index number of the entry to be inserted. If you don't want
+to number the inserted revisions, then use nil for INDEX-REGEXP.
+
+If INDEX-REGEXP is non-nil, then both POINT-FORMAT and EOB-FORMAT
+should contain \"%N\", which is replaced with the number that was
+determined in the previous step.
+
+Both formats, if non-nil and after removing %N, are then expanded
+using `git show --format=FORMAT ...' inside TOPLEVEL.
+
+The expansion of POINT-FORMAT is inserted at point, and the
+expansion of EOB-FORMAT is inserted at the end of the buffer (if
+the buffer ends with a comment, then it is inserted right before
+that)."
+ :package-version '(magit . "3.2.0")
+ :group 'magit-commands
+ :type '(list (choice (string :tag "Insert at point format")
+ (cons (string :tag "Insert at point format")
+ (repeat (string :tag "Argument to git show")))
+ (const :tag "Don't insert at point" nil))
+ (choice (string :tag "Insert at eob format")
+ (cons (string :tag "Insert at eob format")
+ (repeat (string :tag "Argument to git show")))
+ (const :tag "Don't insert at eob" nil))
+ (choice (regexp :tag "Find index regexp")
+ (const :tag "Don't number entries" nil))))
+
+(defcustom magit-copy-revision-abbreviated nil
+ "Whether to save abbreviated revision to `kill-ring' and `magit-revision-stack'."
+ :package-version '(magit . "3.0.0")
+ :group 'magit-miscellaneous
+ :type 'boolean)
+
+;;;###autoload
+(defun magit-pop-revision-stack (rev toplevel)
+ "Insert a representation of a revision into the current buffer.
+
+Pop a revision from the `magit-revision-stack' and insert it into
+the current buffer according to `magit-pop-revision-stack-format'.
+Revisions can be put on the stack using `magit-copy-section-value'
+and `magit-copy-buffer-revision'.
+
+If the stack is empty or with a prefix argument, instead read a
+revision in the minibuffer. By using the minibuffer history this
+allows selecting an item which was popped earlier or to insert an
+arbitrary reference or revision without first pushing it onto the
+stack.
+
+When reading the revision from the minibuffer, then it might not
+be possible to guess the correct repository. When this command
+is called inside a repository (e.g. while composing a commit
+message), then that repository is used. Otherwise (e.g. while
+composing an email) then the repository recorded for the top
+element of the stack is used (even though we insert another
+revision). If not called inside a repository and with an empty
+stack, or with two prefix arguments, then read the repository in
+the minibuffer too."
+ (interactive
+ (if (or current-prefix-arg (not magit-revision-stack))
+ (let ((default-directory
+ (or (and (not (= (prefix-numeric-value current-prefix-arg) 16))
+ (or (magit-toplevel)
+ (cadr (car magit-revision-stack))))
+ (magit-read-repository))))
+ (list (magit-read-branch-or-commit "Insert revision")
+ default-directory))
+ (push (caar magit-revision-stack) magit-revision-history)
+ (pop magit-revision-stack)))
+ (if rev
+ (pcase-let ((`(,pnt-format ,eob-format ,idx-format)
+ magit-pop-revision-stack-format))
+ (let ((default-directory toplevel)
+ (idx (and idx-format
+ (save-excursion
+ (if (re-search-backward idx-format nil t)
+ (number-to-string
+ (1+ (string-to-number (match-string 1))))
+ "1"))))
+ pnt-args eob-args)
+ (when (listp pnt-format)
+ (setq pnt-args (cdr pnt-format))
+ (setq pnt-format (car pnt-format)))
+ (when (listp eob-format)
+ (setq eob-args (cdr eob-format))
+ (setq eob-format (car eob-format)))
+ (when pnt-format
+ (when idx-format
+ (setq pnt-format
+ (string-replace "%N" idx pnt-format)))
+ (magit-rev-insert-format pnt-format rev pnt-args)
+ (backward-delete-char 1))
+ (when eob-format
+ (when idx-format
+ (setq eob-format
+ (string-replace "%N" idx eob-format)))
+ (save-excursion
+ (goto-char (point-max))
+ (skip-syntax-backward ">s-")
+ (beginning-of-line)
+ (if (and comment-start (looking-at comment-start))
+ (while (looking-at comment-start)
+ (forward-line -1))
+ (forward-line)
+ (unless (= (current-column) 0)
+ (insert ?\n)))
+ (insert ?\n)
+ (magit-rev-insert-format eob-format rev eob-args)
+ (backward-delete-char 1)))))
+ (user-error "Revision stack is empty")))
+
+(define-key git-commit-mode-map
+ (kbd "C-c C-w") #'magit-pop-revision-stack)
+
+;;;###autoload
+(defun magit-copy-section-value (arg)
+ "Save the value of the current section for later use.
+
+Save the section value to the `kill-ring', and, provided that
+the current section is a commit, branch, or tag section, push
+the (referenced) revision to the `magit-revision-stack' for use
+with `magit-pop-revision-stack'.
+
+When `magit-copy-revision-abbreviated' is non-nil, save the
+abbreviated revision to the `kill-ring' and the
+`magit-revision-stack'.
+
+When the current section is a branch or a tag, and a prefix
+argument is used, then save the revision at its tip to the
+`kill-ring' instead of the reference name.
+
+When the region is active, then save that to the `kill-ring',
+like `kill-ring-save' would, instead of behaving as described
+above. If a prefix argument is used and the region is within
+a hunk, then strip the diff marker column and keep only either
+the added or removed lines, depending on the sign of the prefix
+argument."
+ (interactive "P")
+ (cond
+ ((and arg
+ (magit-section-internal-region-p)
+ (magit-section-match 'hunk))
+ (kill-new
+ (thread-last (buffer-substring-no-properties
+ (region-beginning)
+ (region-end))
+ (replace-regexp-in-string
+ (format "^\\%c.*\n?" (if (< (prefix-numeric-value arg) 0) ?+ ?-))
+ "")
+ (replace-regexp-in-string "^[ \\+\\-]" "")))
+ (deactivate-mark))
+ ((use-region-p)
+ (call-interactively #'copy-region-as-kill))
+ (t
+ (when-let* ((section (magit-current-section))
+ (value (oref section value)))
+ (magit-section-case
+ ((branch commit module-commit tag)
+ (let ((default-directory default-directory) ref)
+ (magit-section-case
+ ((branch tag)
+ (setq ref value))
+ (module-commit
+ (setq default-directory
+ (file-name-as-directory
+ (expand-file-name (magit-section-parent-value section)
+ (magit-toplevel))))))
+ (setq value (magit-rev-parse
+ (and magit-copy-revision-abbreviated "--short")
+ value))
+ (push (list value default-directory) magit-revision-stack)
+ (kill-new (message "%s" (or (and current-prefix-arg ref)
+ value)))))
+ (t (kill-new (message "%s" value))))))))
+
+;;;###autoload
+(defun magit-copy-buffer-revision ()
+ "Save the revision of the current buffer for later use.
+
+Save the revision shown in the current buffer to the `kill-ring'
+and push it to the `magit-revision-stack'.
+
+This command is mainly intended for use in `magit-revision-mode'
+buffers, the only buffers where it is always unambiguous exactly
+which revision should be saved.
+
+Most other Magit buffers usually show more than one revision, in
+some way or another, so this command has to select one of them,
+and that choice might not always be the one you think would have
+been the best pick.
+
+In such buffers it is often more useful to save the value of
+the current section instead, using `magit-copy-section-value'.
+
+When the region is active, then save that to the `kill-ring',
+like `kill-ring-save' would, instead of behaving as described
+above.
+
+When `magit-copy-revision-abbreviated' is non-nil, save the
+abbreviated revision to the `kill-ring' and the
+`magit-revision-stack'."
+ (interactive)
+ (if (use-region-p)
+ (call-interactively #'copy-region-as-kill)
+ (when-let ((rev (or magit-buffer-revision
+ (cl-case major-mode
+ (magit-diff-mode
+ (if (string-match "\\.\\.\\.?\\(.+\\)"
+ magit-buffer-range)
+ (match-string 1 magit-buffer-range)
+ magit-buffer-range))
+ (magit-status-mode "HEAD")))))
+ (when (magit-commit-p rev)
+ (setq rev (magit-rev-parse
+ (and magit-copy-revision-abbreviated "--short")
+ rev))
+ (push (list rev default-directory) magit-revision-stack)
+ (kill-new (message "%s" rev))))))
+
+;;; Buffer Switching
+
+;;;###autoload
+(defun magit-display-repository-buffer (buffer)
+ "Display a Magit buffer belonging to the current Git repository.
+The buffer is displayed using `magit-display-buffer', which see."
+ (interactive (list (magit--read-repository-buffer
+ "Display magit buffer: ")))
+ (magit-display-buffer buffer))
+
+;;;###autoload
+(defun magit-switch-to-repository-buffer (buffer)
+ "Switch to a Magit buffer belonging to the current Git repository."
+ (interactive (list (magit--read-repository-buffer
+ "Switch to magit buffer: ")))
+ (switch-to-buffer buffer))
+
+;;;###autoload
+(defun magit-switch-to-repository-buffer-other-window (buffer)
+ "Switch to a Magit buffer belonging to the current Git repository."
+ (interactive (list (magit--read-repository-buffer
+ "Switch to magit buffer in another window: ")))
+ (switch-to-buffer-other-window buffer))
+
+;;;###autoload
+(defun magit-switch-to-repository-buffer-other-frame (buffer)
+ "Switch to a Magit buffer belonging to the current Git repository."
+ (interactive (list (magit--read-repository-buffer
+ "Switch to magit buffer in another frame: ")))
+ (switch-to-buffer-other-frame buffer))
+
+(defun magit--read-repository-buffer (prompt)
+ (if-let ((topdir (magit-rev-parse-safe "--show-toplevel")))
+ (read-buffer
+ prompt (magit-get-mode-buffer 'magit-status-mode) t
+ (pcase-lambda (`(,_ . ,buf))
+ (and buf
+ (with-current-buffer buf
+ (and (or (derived-mode-p 'magit-mode
+ 'magit-repolist-mode
+ 'magit-submodule-list-mode
+ 'git-rebase-mode)
+ (and buffer-file-name
+ (string-match-p git-commit-filename-regexp
+ buffer-file-name)))
+ (equal (magit-rev-parse-safe "--show-toplevel")
+ topdir))))))
+ (user-error "Not inside a Git repository")))
+
+;;; Miscellaneous
+
+;;;###autoload
+(defun magit-abort-dwim ()
+ "Abort current operation.
+Depending on the context, this will abort a merge, a rebase, a
+patch application, a cherry-pick, a revert, or a bisect."
+ (interactive)
+ (cond ((magit-merge-in-progress-p) (magit-merge-abort))
+ ((magit-rebase-in-progress-p) (magit-rebase-abort))
+ ((magit-am-in-progress-p) (magit-am-abort))
+ ((magit-sequencer-in-progress-p) (magit-sequencer-abort))
+ ((magit-bisect-in-progress-p) (magit-bisect-reset))))
+
+;;; _
+(provide 'magit-extras)
+;;; magit-extras.el ends here
diff --git a/elpa/magit-20220503.1245/magit-extras.elc b/elpa/magit-20220503.1245/magit-extras.elc
new file mode 100644
index 0000000..1a461a3
--- /dev/null
+++ b/elpa/magit-20220503.1245/magit-extras.elc
Binary files differ
diff --git a/elpa/magit-20220503.1245/magit-fetch.el b/elpa/magit-20220503.1245/magit-fetch.el
new file mode 100644
index 0000000..6c97d18
--- /dev/null
+++ b/elpa/magit-20220503.1245/magit-fetch.el
@@ -0,0 +1,199 @@
+;;; magit-fetch.el --- Download objects and refs -*- lexical-binding:t -*-
+
+;; Copyright (C) 2008-2022 The Magit Project Contributors
+
+;; Author: Jonas Bernoulli <jonas@bernoul.li>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+
+;; SPDX-License-Identifier: GPL-3.0-or-later
+
+;; Magit 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.
+;;
+;; Magit 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 Magit. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This library implements fetch commands.
+
+;;; Code:
+
+(require 'magit)
+
+(defvar magit-fetch-modules-jobs nil)
+(make-obsolete-variable
+ 'magit-fetch-modules-jobs
+ "invoke `magit-fetch-modules' with a prefix argument instead."
+ "Magit 3.0.0")
+
+;;; Commands
+
+;;;###autoload (autoload 'magit-fetch "magit-fetch" nil t)
+(transient-define-prefix magit-fetch ()
+ "Fetch from another repository."
+ :man-page "git-fetch"
+ ["Arguments"
+ ("-p" "Prune deleted branches" ("-p" "--prune"))
+ ("-t" "Fetch all tags" ("-t" "--tags"))
+ (7 "-u" "Fetch full history" "--unshallow")]
+ ["Fetch from"
+ ("p" magit-fetch-from-pushremote)
+ ("u" magit-fetch-from-upstream)
+ ("e" "elsewhere" magit-fetch-other)
+ ("a" "all remotes" magit-fetch-all)]
+ ["Fetch"
+ ("o" "another branch" magit-fetch-branch)
+ ("r" "explicit refspec" magit-fetch-refspec)
+ ("m" "submodules" magit-fetch-modules)]
+ ["Configure"
+ ("C" "variables..." magit-branch-configure)])
+
+(defun magit-fetch-arguments ()
+ (transient-args 'magit-fetch))
+
+(defun magit-git-fetch (remote args)
+ (run-hooks 'magit-credential-hook)
+ (magit-run-git-async "fetch" remote args))
+
+;;;###autoload (autoload 'magit-fetch-from-pushremote "magit-fetch" nil t)
+(transient-define-suffix magit-fetch-from-pushremote (args)
+ "Fetch from the current push-remote.
+
+With a prefix argument or when the push-remote is either not
+configured or unusable, then let the user first configure the
+push-remote."
+ :description #'magit-fetch--pushremote-description
+ (interactive (list (magit-fetch-arguments)))
+ (let ((remote (magit-get-push-remote)))
+ (when (or current-prefix-arg
+ (not (member remote (magit-list-remotes))))
+ (let ((var (magit--push-remote-variable)))
+ (setq remote
+ (magit-read-remote (format "Set %s and fetch from there" var)))
+ (magit-set remote var)))
+ (magit-git-fetch remote args)))
+
+(defun magit-fetch--pushremote-description ()
+ (let* ((branch (magit-get-current-branch))
+ (remote (magit-get-push-remote branch))
+ (v (magit--push-remote-variable branch t)))
+ (cond
+ ((member remote (magit-list-remotes)) remote)
+ (remote
+ (format "%s, replacing invalid" v))
+ (t
+ (format "%s, setting that" v)))))
+
+;;;###autoload (autoload 'magit-fetch-from-upstream "magit-fetch" nil t)
+(transient-define-suffix magit-fetch-from-upstream (remote args)
+ "Fetch from the \"current\" remote, usually the upstream.
+
+If the upstream is configured for the current branch and names
+an existing remote, then use that. Otherwise try to use another
+remote: If only a single remote is configured, then use that.
+Otherwise if a remote named \"origin\" exists, then use that.
+
+If no remote can be determined, then this command is not available
+from the `magit-fetch' transient prefix and invoking it directly
+results in an error."
+ :if (lambda () (magit-get-current-remote t))
+ :description (lambda () (magit-get-current-remote t))
+ (interactive (list (magit-get-current-remote t)
+ (magit-fetch-arguments)))
+ (unless remote
+ (error "The \"current\" remote could not be determined"))
+ (magit-git-fetch remote args))
+
+;;;###autoload
+(defun magit-fetch-other (remote args)
+ "Fetch from another repository."
+ (interactive (list (magit-read-remote "Fetch remote")
+ (magit-fetch-arguments)))
+ (magit-git-fetch remote args))
+
+;;;###autoload
+(defun magit-fetch-branch (remote branch args)
+ "Fetch a BRANCH from a REMOTE."
+ (interactive
+ (let ((remote (magit-read-remote-or-url "Fetch from remote or url")))
+ (list remote
+ (magit-read-remote-branch "Fetch branch" remote)
+ (magit-fetch-arguments))))
+ (magit-git-fetch remote (cons branch args)))
+
+;;;###autoload
+(defun magit-fetch-refspec (remote refspec args)
+ "Fetch a REFSPEC from a REMOTE."
+ (interactive
+ (let ((remote (magit-read-remote-or-url "Fetch from remote or url")))
+ (list remote
+ (magit-read-refspec "Fetch using refspec" remote)
+ (magit-fetch-arguments))))
+ (magit-git-fetch remote (cons refspec args)))
+
+;;;###autoload
+(defun magit-fetch-all (args)
+ "Fetch from all remotes."
+ (interactive (list (magit-fetch-arguments)))
+ (magit-git-fetch nil (cons "--all" args)))
+
+;;;###autoload
+(defun magit-fetch-all-prune ()
+ "Fetch from all remotes, and prune.
+Prune remote tracking branches for branches that have been
+removed on the respective remote."
+ (interactive)
+ (run-hooks 'magit-credential-hook)
+ (magit-run-git-async "remote" "update" "--prune"))
+
+;;;###autoload
+(defun magit-fetch-all-no-prune ()
+ "Fetch from all remotes."
+ (interactive)
+ (run-hooks 'magit-credential-hook)
+ (magit-run-git-async "remote" "update"))
+
+;;;###autoload (autoload 'magit-fetch-modules "magit-fetch" nil t)
+(transient-define-prefix magit-fetch-modules (&optional transient args)
+ "Fetch all submodules.
+
+Fetching is done using \"git fetch --recurse-submodules\", which
+means that the super-repository and recursively all submodules
+are also fetched.
+
+To set and potentially save other arguments invoke this command
+with a prefix argument."
+ :man-page "git-fetch"
+ :value (list "--verbose"
+ (cond (magit-fetch-modules-jobs
+ (format "--jobs=%s" magit-fetch-modules-jobs))
+ (t "--jobs=4")))
+ ["Arguments"
+ ("-v" "verbose" "--verbose")
+ ("-j" "number of jobs" "--jobs=" :reader transient-read-number-N+)]
+ ["Action"
+ ("m" "fetch modules" magit-fetch-modules)]
+ (interactive (if current-prefix-arg
+ (list t)
+ (list nil (transient-args 'magit-fetch-modules))))
+ (if transient
+ (transient-setup 'magit-fetch-modules)
+ (when (magit-git-version< "2.8.0")
+ (when-let ((value (transient-arg-value "--jobs=" args)))
+ (message "Dropping --jobs; not supported by Git v%s"
+ (magit-git-version))
+ (setq args (remove (format "--jobs=%s" value) args))))
+ (magit-with-toplevel
+ (magit-run-git-async "fetch" "--recurse-submodules" args))))
+
+;;; _
+(provide 'magit-fetch)
+;;; magit-fetch.el ends here
diff --git a/elpa/magit-20220503.1245/magit-fetch.elc b/elpa/magit-20220503.1245/magit-fetch.elc
new file mode 100644
index 0000000..d474d19
--- /dev/null
+++ b/elpa/magit-20220503.1245/magit-fetch.elc
Binary files differ
diff --git a/elpa/magit-20220503.1245/magit-files.el b/elpa/magit-20220503.1245/magit-files.el
new file mode 100644
index 0000000..2660898
--- /dev/null
+++ b/elpa/magit-20220503.1245/magit-files.el
@@ -0,0 +1,535 @@
+;;; magit-files.el --- Finding files -*- lexical-binding:t -*-
+
+;; Copyright (C) 2008-2022 The Magit Project Contributors
+
+;; Author: Jonas Bernoulli <jonas@bernoul.li>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+
+;; SPDX-License-Identifier: GPL-3.0-or-later
+
+;; Magit 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.
+;;
+;; Magit 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 Magit. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This library implements support for finding blobs, staged files,
+;; and Git configuration files. It also implements modes useful in
+;; buffers visiting files and blobs, and the commands used by those
+;; modes.
+
+;;; Code:
+
+(require 'magit)
+
+;;; Find Blob
+
+(defvar magit-find-file-hook nil)
+(add-hook 'magit-find-file-hook #'magit-blob-mode)
+
+;;;###autoload
+(defun magit-find-file (rev file)
+ "View FILE from REV.
+Switch to a buffer visiting blob REV:FILE, creating one if none
+already exists. If prior to calling this command the current
+buffer and/or cursor position is about the same file, then go
+to the line and column corresponding to that location."
+ (interactive (magit-find-file-read-args "Find file"))
+ (magit-find-file--internal rev file #'pop-to-buffer-same-window))
+
+;;;###autoload
+(defun magit-find-file-other-window (rev file)
+ "View FILE from REV, in another window.
+Switch to a buffer visiting blob REV:FILE, creating one if none
+already exists. If prior to calling this command the current
+buffer and/or cursor position is about the same file, then go to
+the line and column corresponding to that location."
+ (interactive (magit-find-file-read-args "Find file in other window"))
+ (magit-find-file--internal rev file #'switch-to-buffer-other-window))
+
+;;;###autoload
+(defun magit-find-file-other-frame (rev file)
+ "View FILE from REV, in another frame.
+Switch to a buffer visiting blob REV:FILE, creating one if none
+already exists. If prior to calling this command the current
+buffer and/or cursor position is about the same file, then go to
+the line and column corresponding to that location."
+ (interactive (magit-find-file-read-args "Find file in other frame"))
+ (magit-find-file--internal rev file #'switch-to-buffer-other-frame))
+
+(defun magit-find-file-read-args (prompt)
+ (let ((pseudo-revs '("{worktree}" "{index}")))
+ (if-let ((rev (magit-completing-read "Find file from revision"
+ (append pseudo-revs
+ (magit-list-refnames nil t))
+ nil nil nil 'magit-revision-history
+ (or (magit-branch-or-commit-at-point)
+ (magit-get-current-branch)))))
+ (list rev (magit-read-file-from-rev (if (member rev pseudo-revs)
+ "HEAD"
+ rev)
+ prompt))
+ (user-error "Nothing selected"))))
+
+(defun magit-find-file--internal (rev file fn)
+ (let ((buf (magit-find-file-noselect rev file))
+ line col)
+ (when-let ((visited-file (magit-file-relative-name)))
+ (setq line (line-number-at-pos))
+ (setq col (current-column))
+ (cond
+ ((not (equal visited-file file)))
+ ((equal magit-buffer-revision rev))
+ ((equal rev "{worktree}")
+ (setq line (magit-diff-visit--offset file magit-buffer-revision line)))
+ ((equal rev "{index}")
+ (setq line (magit-diff-visit--offset file nil line)))
+ (magit-buffer-revision
+ (setq line (magit-diff-visit--offset
+ file (concat magit-buffer-revision ".." rev) line)))
+ (t
+ (setq line (magit-diff-visit--offset file (list "-R" rev) line)))))
+ (funcall fn buf)
+ (when line
+ (with-current-buffer buf
+ (widen)
+ (goto-char (point-min))
+ (forward-line (1- line))
+ (move-to-column col)))
+ buf))
+
+(defun magit-find-file-noselect (rev file)
+ "Read FILE from REV into a buffer and return the buffer.
+REV is a revision or one of \"{worktree}\" or \"{index}\".
+FILE must be relative to the top directory of the repository."
+ (magit-find-file-noselect-1 rev file))
+
+(defun magit-find-file-noselect-1 (rev file &optional revert)
+ "Read FILE from REV into a buffer and return the buffer.
+REV is a revision or one of \"{worktree}\" or \"{index}\".
+FILE must be relative to the top directory of the repository.
+Non-nil REVERT means to revert the buffer. If `ask-revert',
+then only after asking. A non-nil value for REVERT is ignored if REV is
+\"{worktree}\"."
+ (if (equal rev "{worktree}")
+ (find-file-noselect (expand-file-name file (magit-toplevel)))
+ (let ((topdir (magit-toplevel)))
+ (when (file-name-absolute-p file)
+ (setq file (file-relative-name file topdir)))
+ (with-current-buffer (magit-get-revision-buffer-create rev file)
+ (when (or (not magit-buffer-file-name)
+ (if (eq revert 'ask-revert)
+ (y-or-n-p (format "%s already exists; revert it? "
+ (buffer-name))))
+ revert)
+ (setq magit-buffer-revision
+ (if (equal rev "{index}")
+ "{index}"
+ (magit-rev-format "%H" rev)))
+ (setq magit-buffer-refname rev)
+ (setq magit-buffer-file-name (expand-file-name file topdir))
+ (setq default-directory
+ (let ((dir (file-name-directory magit-buffer-file-name)))
+ (if (file-exists-p dir) dir topdir)))
+ (setq-local revert-buffer-function #'magit-revert-rev-file-buffer)
+ (revert-buffer t t)
+ (run-hooks (if (equal rev "{index}")
+ 'magit-find-index-hook
+ 'magit-find-file-hook)))
+ (current-buffer)))))
+
+(defun magit-get-revision-buffer-create (rev file)
+ (magit-get-revision-buffer rev file t))
+
+(defun magit-get-revision-buffer (rev file &optional create)
+ (funcall (if create #'get-buffer-create #'get-buffer)
+ (format "%s.~%s~" file (subst-char-in-string ?/ ?_ rev))))
+
+(defun magit-revert-rev-file-buffer (_ignore-auto noconfirm)
+ (when (or noconfirm
+ (and (not (buffer-modified-p))
+ (catch 'found
+ (dolist (regexp revert-without-query)
+ (when (string-match regexp magit-buffer-file-name)
+ (throw 'found t)))))
+ (yes-or-no-p (format "Revert buffer from Git %s? "
+ (if (equal magit-buffer-refname "{index}")
+ "index"
+ (concat "revision " magit-buffer-refname)))))
+ (let* ((inhibit-read-only t)
+ (default-directory (magit-toplevel))
+ (file (file-relative-name magit-buffer-file-name))
+ (coding-system-for-read (or coding-system-for-read 'undecided)))
+ (erase-buffer)
+ (magit-git-insert "cat-file" "-p"
+ (if (equal magit-buffer-refname "{index}")
+ (concat ":" file)
+ (concat magit-buffer-refname ":" file)))
+ (setq buffer-file-coding-system last-coding-system-used))
+ (let ((buffer-file-name magit-buffer-file-name)
+ (after-change-major-mode-hook
+ (remq 'global-diff-hl-mode-enable-in-buffers
+ after-change-major-mode-hook)))
+ (normal-mode t))
+ (setq buffer-read-only t)
+ (set-buffer-modified-p nil)
+ (goto-char (point-min))))
+
+;;; Find Index
+
+(defvar magit-find-index-hook nil)
+
+(defun magit-find-file-index-noselect (file &optional revert)
+ "Read FILE from the index into a buffer and return the buffer.
+FILE must to be relative to the top directory of the repository."
+ (magit-find-file-noselect-1 "{index}" file (or revert 'ask-revert)))
+
+(defun magit-update-index ()
+ "Update the index with the contents of the current buffer.
+The current buffer has to be visiting a file in the index, which
+is done using `magit-find-index-noselect'."
+ (interactive)
+ (let ((file (magit-file-relative-name)))
+ (unless (equal magit-buffer-refname "{index}")
+ (user-error "%s isn't visiting the index" file))
+ (if (y-or-n-p (format "Update index with contents of %s" (buffer-name)))
+ (let ((index (make-temp-name (magit-git-dir "magit-update-index-")))
+ (buffer (current-buffer)))
+ (when magit-wip-before-change-mode
+ (magit-wip-commit-before-change (list file) " before un-/stage"))
+ (unwind-protect
+ (progn
+ (let ((coding-system-for-write buffer-file-coding-system))
+ (with-temp-file index
+ (insert-buffer-substring buffer)))
+ (magit-with-toplevel
+ (magit-call-git
+ "update-index" "--cacheinfo"
+ (substring (magit-git-string "ls-files" "-s" file)
+ 0 6)
+ (magit-git-string "hash-object" "-t" "blob" "-w"
+ (concat "--path=" file)
+ "--" (magit-convert-filename-for-git index))
+ file)))
+ (ignore-errors (delete-file index)))
+ (set-buffer-modified-p nil)
+ (when magit-wip-after-apply-mode
+ (magit-wip-commit-after-apply (list file) " after un-/stage")))
+ (message "Abort")))
+ (--when-let (magit-get-mode-buffer 'magit-status-mode)
+ (with-current-buffer it (magit-refresh)))
+ t)
+
+;;; Find Config File
+
+(defun magit-find-git-config-file (filename &optional wildcards)
+ "Edit a file located in the current repository's git directory.
+
+When \".git\", located at the root of the working tree, is a
+regular file, then that makes it cumbersome to open a file
+located in the actual git directory.
+
+This command is like `find-file', except that it temporarily
+binds `default-directory' to the actual git directory, while
+reading the FILENAME."
+ (interactive
+ (let ((default-directory (magit-git-dir)))
+ (find-file-read-args "Find file: "
+ (confirm-nonexistent-file-or-buffer))))
+ (find-file filename wildcards))
+
+(defun magit-find-git-config-file-other-window (filename &optional wildcards)
+ "Edit a file located in the current repo's git directory, in another window.
+
+When \".git\", located at the root of the working tree, is a
+regular file, then that makes it cumbersome to open a file
+located in the actual git directory.
+
+This command is like `find-file-other-window', except that it
+temporarily binds `default-directory' to the actual git
+directory, while reading the FILENAME."
+ (interactive
+ (let ((default-directory (magit-git-dir)))
+ (find-file-read-args "Find file in other window: "
+ (confirm-nonexistent-file-or-buffer))))
+ (find-file-other-window filename wildcards))
+
+(defun magit-find-git-config-file-other-frame (filename &optional wildcards)
+ "Edit a file located in the current repo's git directory, in another frame.
+
+When \".git\", located at the root of the working tree, is a
+regular file, then that makes it cumbersome to open a file
+located in the actual git directory.
+
+This command is like `find-file-other-frame', except that it
+temporarily binds `default-directory' to the actual git
+directory, while reading the FILENAME."
+ (interactive
+ (let ((default-directory (magit-git-dir)))
+ (find-file-read-args "Find file in other frame: "
+ (confirm-nonexistent-file-or-buffer))))
+ (find-file-other-frame filename wildcards))
+
+;;; File Dispatch
+
+;;;###autoload (autoload 'magit-file-dispatch "magit" nil t)
+(transient-define-prefix magit-file-dispatch ()
+ "Invoke a Magit command that acts on the visited file.
+When invoked outside a file-visiting buffer, then fall back
+to `magit-dispatch'."
+ :info-manual "(magit) Minor Mode for Buffers Visiting Files"
+ ["Actions"
+ [("s" "Stage" magit-stage-file)
+ ("u" "Unstage" magit-unstage-file)
+ ("c" "Commit" magit-commit)
+ ("e" "Edit line" magit-edit-line-commit)]
+ [("D" "Diff..." magit-diff)
+ ("d" "Diff" magit-diff-buffer-file)
+ ("g" "Status" magit-status-here)]
+ [("L" "Log..." magit-log)
+ ("l" "Log" magit-log-buffer-file)
+ ("t" "Trace" magit-log-trace-definition)
+ (7 "M" "Merged" magit-log-merged)]
+ [("B" "Blame..." magit-blame)
+ ("b" "Blame" magit-blame-addition)
+ ("r" "...removal" magit-blame-removal)
+ ("f" "...reverse" magit-blame-reverse)
+ ("m" "Blame echo" magit-blame-echo)
+ ("q" "Quit blame" magit-blame-quit)]
+ [("p" "Prev blob" magit-blob-previous)
+ ("n" "Next blob" magit-blob-next)
+ ("v" "Goto blob" magit-find-file)
+ ("V" "Goto file" magit-blob-visit-file)]
+ [(5 "C-c r" "Rename file" magit-file-rename)
+ (5 "C-c d" "Delete file" magit-file-delete)
+ (5 "C-c u" "Untrack file" magit-file-untrack)
+ (5 "C-c c" "Checkout file" magit-file-checkout)]]
+ (interactive)
+ (transient-setup
+ (if (magit-file-relative-name)
+ 'magit-file-dispatch
+ 'magit-dispatch)))
+
+;;; Blob Mode
+
+(defvar magit-blob-mode-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map "p" #'magit-blob-previous)
+ (define-key map "n" #'magit-blob-next)
+ (define-key map "b" #'magit-blame-addition)
+ (define-key map "r" #'magit-blame-removal)
+ (define-key map "f" #'magit-blame-reverse)
+ (define-key map "q" #'magit-kill-this-buffer)
+ map)
+ "Keymap for `magit-blob-mode'.")
+
+(define-minor-mode magit-blob-mode
+ "Enable some Magit features in blob-visiting buffers.
+
+Currently this only adds the following key bindings.
+\n\\{magit-blob-mode-map}"
+ :package-version '(magit . "2.3.0"))
+
+(defun magit-blob-next ()
+ "Visit the next blob which modified the current file."
+ (interactive)
+ (if magit-buffer-file-name
+ (magit-blob-visit (or (magit-blob-successor magit-buffer-revision
+ magit-buffer-file-name)
+ magit-buffer-file-name))
+ (if (buffer-file-name (buffer-base-buffer))
+ (user-error "You have reached the end of time")
+ (user-error "Buffer isn't visiting a file or blob"))))
+
+(defun magit-blob-previous ()
+ "Visit the previous blob which modified the current file."
+ (interactive)
+ (if-let ((file (or magit-buffer-file-name
+ (buffer-file-name (buffer-base-buffer)))))
+ (--if-let (magit-blob-ancestor magit-buffer-revision file)
+ (magit-blob-visit it)
+ (user-error "You have reached the beginning of time"))
+ (user-error "Buffer isn't visiting a file or blob")))
+
+;;;###autoload
+(defun magit-blob-visit-file ()
+ "View the file from the worktree corresponding to the current blob.
+When visiting a blob or the version from the index, then go to
+the same location in the respective file in the working tree."
+ (interactive)
+ (if-let ((file (magit-file-relative-name)))
+ (magit-find-file--internal "{worktree}" file #'pop-to-buffer-same-window)
+ (user-error "Not visiting a blob")))
+
+(defun magit-blob-visit (blob-or-file)
+ (if (stringp blob-or-file)
+ (find-file blob-or-file)
+ (pcase-let ((`(,rev ,file) blob-or-file))
+ (magit-find-file rev file)
+ (apply #'message "%s (%s %s ago)"
+ (magit-rev-format "%s" rev)
+ (magit--age (magit-rev-format "%ct" rev))))))
+
+(defun magit-blob-ancestor (rev file)
+ (let ((lines (magit-with-toplevel
+ (magit-git-lines "log" "-2" "--format=%H" "--name-only"
+ "--follow" (or rev "HEAD") "--" file))))
+ (if rev (cddr lines) (butlast lines 2))))
+
+(defun magit-blob-successor (rev file)
+ (let ((lines (magit-with-toplevel
+ (magit-git-lines "log" "--format=%H" "--name-only" "--follow"
+ "HEAD" "--" file))))
+ (catch 'found
+ (while lines
+ (if (equal (nth 2 lines) rev)
+ (throw 'found (list (nth 0 lines) (nth 1 lines)))
+ (setq lines (nthcdr 2 lines)))))))
+
+;;; File Commands
+
+(defun magit-file-rename (file newname)
+ "Rename or move FILE to NEWNAME.
+NEWNAME may be a file or directory name. If FILE isn't tracked in
+Git, fallback to using `rename-file'."
+ (interactive
+ (let* ((file (magit-read-file "Rename file"))
+ (dir (file-name-directory file))
+ (newname (read-file-name (format "Move %s to destination: " file)
+ (and dir (expand-file-name dir)))))
+ (list (expand-file-name file (magit-toplevel))
+ (expand-file-name newname))))
+ (let ((oldbuf (get-file-buffer file))
+ (dstdir (file-name-directory newname))
+ (dstfile (if (directory-name-p newname)
+ (concat newname (file-name-nondirectory file))
+ newname)))
+ (when (and oldbuf (buffer-modified-p oldbuf))
+ (user-error "Save %s before moving it" file))
+ (when (file-exists-p dstfile)
+ (user-error "%s already exists" dstfile))
+ (unless (file-exists-p dstdir)
+ (user-error "Destination directory %s does not exist" dstdir))
+ (if (magit-file-tracked-p (magit-convert-filename-for-git file))
+ (magit-call-git "mv"
+ (magit-convert-filename-for-git file)
+ (magit-convert-filename-for-git newname))
+ (rename-file file newname current-prefix-arg))
+ (when oldbuf
+ (with-current-buffer oldbuf
+ (let ((buffer-read-only buffer-read-only))
+ (set-visited-file-name dstfile nil t))
+ (if (fboundp 'vc-refresh-state)
+ (vc-refresh-state)
+ (with-no-warnings
+ (vc-find-file-hook))))))
+ (magit-refresh))
+
+(defun magit-file-untrack (files &optional force)
+ "Untrack the selected FILES or one file read in the minibuffer.
+
+With a prefix argument FORCE do so even when the files have
+staged as well as unstaged changes."
+ (interactive (list (or (--if-let (magit-region-values 'file t)
+ (progn
+ (unless (magit-file-tracked-p (car it))
+ (user-error "Already untracked"))
+ (magit-confirm-files 'untrack it "Untrack"))
+ (list (magit-read-tracked-file "Untrack file"))))
+ current-prefix-arg))
+ (magit-with-toplevel
+ (magit-run-git "rm" "--cached" (and force "--force") "--" files)))
+
+(defun magit-file-delete (files &optional force)
+ "Delete the selected FILES or one file read in the minibuffer.
+
+With a prefix argument FORCE do so even when the files have
+uncommitted changes. When the files aren't being tracked in
+Git, then fallback to using `delete-file'."
+ (interactive (list (--if-let (magit-region-values 'file t)
+ (magit-confirm-files 'delete it "Delete")
+ (list (magit-read-file "Delete file")))
+ current-prefix-arg))
+ (if (magit-file-tracked-p (car files))
+ (magit-call-git "rm" (and force "--force") "--" files)
+ (let ((topdir (magit-toplevel)))
+ (dolist (file files)
+ (delete-file (expand-file-name file topdir) t))))
+ (magit-refresh))
+
+;;;###autoload
+(defun magit-file-checkout (rev file)
+ "Checkout FILE from REV."
+ (interactive
+ (let ((rev (magit-read-branch-or-commit
+ "Checkout from revision" magit-buffer-revision)))
+ (list rev (magit-read-file-from-rev rev "Checkout file"))))
+ (magit-with-toplevel
+ (magit-run-git "checkout" rev "--" file)))
+
+;;; Read File
+
+(defvar magit-read-file-hist nil)
+
+(defun magit-read-file-from-rev (rev prompt &optional default)
+ (let ((files (magit-revision-files rev)))
+ (magit-completing-read
+ prompt files nil t nil 'magit-read-file-hist
+ (car (member (or default (magit-current-file)) files)))))
+
+(defun magit-read-file (prompt &optional tracked-only)
+ (let ((choices (nconc (magit-list-files)
+ (unless tracked-only (magit-untracked-files)))))
+ (magit-completing-read
+ prompt choices nil t nil nil
+ (car (member (or (magit-section-value-if '(file submodule))
+ (magit-file-relative-name nil tracked-only))
+ choices)))))
+
+(defun magit-read-tracked-file (prompt)
+ (magit-read-file prompt t))
+
+(defun magit-read-unmerged-file (&optional prompt)
+ (let ((current (magit-current-file))
+ (unmerged (magit-unmerged-files)))
+ (unless unmerged
+ (user-error "There are no unresolved conflicts"))
+ (magit-completing-read (or prompt "Resolve file")
+ unmerged nil t nil nil
+ (car (member current unmerged)))))
+
+(defun magit-read-file-choice (prompt files &optional error default)
+ "Read file from FILES.
+
+If FILES has only one member, return that instead of prompting.
+If FILES has no members, give a user error. ERROR can be given
+to provide a more informative error.
+
+If DEFAULT is non-nil, use this as the default value instead of
+`magit-current-file'."
+ (pcase (length files)
+ (0 (user-error (or error "No file choices")))
+ (1 (car files))
+ (_ (magit-completing-read
+ prompt files nil t nil 'magit-read-file-hist
+ (car (member (or default (magit-current-file)) files))))))
+
+(defun magit-read-changed-file (rev-or-range prompt &optional default)
+ (magit-read-file-choice
+ prompt
+ (magit-changed-files rev-or-range)
+ default
+ (concat "No file changed in " rev-or-range)))
+
+;;; _
+(provide 'magit-files)
+;;; magit-files.el ends here
diff --git a/elpa/magit-20220503.1245/magit-files.elc b/elpa/magit-20220503.1245/magit-files.elc
new file mode 100644
index 0000000..33b5414
--- /dev/null
+++ b/elpa/magit-20220503.1245/magit-files.elc
Binary files differ
diff --git a/elpa/magit-20220503.1245/magit-git.el b/elpa/magit-20220503.1245/magit-git.el
new file mode 100644
index 0000000..b238fe5
--- /dev/null
+++ b/elpa/magit-20220503.1245/magit-git.el
@@ -0,0 +1,2650 @@
+;;; magit-git.el --- Git functionality -*- lexical-binding:t -*-
+
+;; Copyright (C) 2008-2022 The Magit Project Contributors
+
+;; Author: Jonas Bernoulli <jonas@bernoul.li>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+
+;; SPDX-License-Identifier: GPL-3.0-or-later
+
+;; Magit 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.
+;;
+;; Magit 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 Magit. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This library implements wrappers for various Git plumbing commands.
+
+;;; Code:
+
+(require 'magit-base)
+
+(require 'format-spec)
+
+;; From `magit-branch'.
+(defvar magit-branch-prefer-remote-upstream)
+(defvar magit-published-branches)
+
+;; From `magit-margin'.
+(declare-function magit-maybe-make-margin-overlay "magit-margin" ())
+
+;; From `magit-mode'.
+(declare-function magit-get-mode-buffer "magit-mode"
+ (mode &optional value frame))
+(declare-function magit-refresh "magit-mode" ())
+(defvar magit-buffer-diff-args)
+(defvar magit-buffer-file-name)
+(defvar magit-buffer-log-args)
+(defvar magit-buffer-log-files)
+(defvar magit-buffer-refname)
+(defvar magit-buffer-revision)
+
+;; From `magit-process'.
+(declare-function magit-call-git "magit-process" (&rest args))
+(declare-function magit-process-buffer "magit-process" (&optional nodisplay))
+(declare-function magit-process-file "magit-process"
+ (process &optional infile buffer display &rest args))
+(declare-function magit-process-git "magit-process" (destination &rest args))
+(declare-function magit-process-insert-section "magit-process"
+ (pwd program args &optional errcode errlog))
+(defvar magit-this-error)
+(defvar magit-process-error-message-regexps)
+
+;; From later in `magit-git'.
+(defvar magit-tramp-process-environment nil)
+
+;; From `magit-blame'.
+(declare-function magit-current-blame-chunk "magit-blame"
+ (&optional type noerror))
+
+(eval-when-compile
+ (cl-pushnew 'orig-rev eieio--known-slot-names)
+ (cl-pushnew 'number eieio--known-slot-names))
+
+;;; Git implementations
+
+(defvar magit-inhibit-libgit nil
+ "Whether to inhibit the use of libgit.")
+
+(defvar magit--libgit-available-p 'unknown
+ "Whether libgit is available.
+Use the function by the same name instead of this variable.")
+
+(defun magit--libgit-available-p ()
+ (if (eq magit--libgit-available-p 'unknown)
+ (setq magit--libgit-available-p
+ (and module-file-suffix
+ (let ((libgit (locate-library "libgit")))
+ (and libgit
+ (or (locate-library "libegit2")
+ (let ((load-path
+ (cons (expand-file-name
+ (convert-standard-filename "build")
+ (file-name-directory libgit))
+ load-path)))
+ (locate-library "libegit2")))))))
+ magit--libgit-available-p))
+
+(defun magit-gitimpl ()
+ "Return the Git implementation used in this repository."
+ (if (and (not magit-inhibit-libgit)
+ (not (file-remote-p default-directory))
+ (magit--libgit-available-p))
+ 'libgit
+ 'git))
+
+;;; Options
+
+;; For now this is shared between `magit-process' and `magit-git'.
+(defgroup magit-process nil
+ "Git and other external processes used by Magit."
+ :group 'magit)
+
+(defvar magit-git-environment
+ (list (format "INSIDE_EMACS=%s,magit" emacs-version))
+ "Prepended to `process-environment' while running git.")
+
+(defcustom magit-git-output-coding-system
+ (and (eq system-type 'windows-nt) 'utf-8)
+ "Coding system for receiving output from Git.
+
+If non-nil, the Git config value `i18n.logOutputEncoding' should
+be set via `magit-git-global-arguments' to value consistent with
+this."
+ :package-version '(magit . "2.9.0")
+ :group 'magit-process
+ :type '(choice (coding-system :tag "Coding system to decode Git output")
+ (const :tag "Use system default" nil)))
+
+(defvar magit-git-w32-path-hack nil
+ "Alist of (EXE . (PATHENTRY)).
+This specifies what additional PATH setting needs to be added to
+the environment in order to run the non-wrapper git executables
+successfully.")
+
+(defcustom magit-git-executable
+ (or (and (eq system-type 'windows-nt)
+ ;; Avoid the wrappers "cmd/git.exe" and "cmd/git.cmd",
+ ;; which are much slower than using "bin/git.exe" directly.
+ (and-let* ((exec (executable-find "git")))
+ (ignore-errors
+ ;; Git for Windows 2.x provides cygpath so we can
+ ;; ask it for native paths.
+ (let* ((core-exe
+ (car
+ (process-lines
+ exec "-c"
+ "alias.X=!x() { which \"$1\" | cygpath -mf -; }; x"
+ "X" "git")))
+ (hack-entry (assoc core-exe magit-git-w32-path-hack))
+ ;; Running the libexec/git-core executable
+ ;; requires some extra PATH entries.
+ (path-hack
+ (list (concat "PATH="
+ (car (process-lines
+ exec "-c"
+ "alias.P=!cygpath -wp \"$PATH\""
+ "P"))))))
+ ;; The defcustom STANDARD expression can be
+ ;; evaluated many times, so make sure it is
+ ;; idempotent.
+ (if hack-entry
+ (setcdr hack-entry path-hack)
+ (push (cons core-exe path-hack) magit-git-w32-path-hack))
+ core-exe))))
+ (and (eq system-type 'darwin)
+ (executable-find "git"))
+ "git")
+ "The Git executable used by Magit on the local host.
+On remote machines `magit-remote-git-executable' is used instead."
+ :package-version '(magit . "3.2.0")
+ :group 'magit-process
+ :type 'string)
+
+(defcustom magit-remote-git-executable "git"
+ "The Git executable used by Magit on remote machines.
+On the local host `magit-git-executable' is used instead.
+Consider customizing `tramp-remote-path' instead of this
+option."
+ :package-version '(magit . "3.2.0")
+ :group 'magit-process
+ :type 'string)
+
+(defcustom magit-git-global-arguments
+ `("--no-pager" "--literal-pathspecs"
+ "-c" "core.preloadindex=true"
+ "-c" "log.showSignature=false"
+ "-c" "color.ui=false"
+ "-c" "color.diff=false"
+ ,@(and (eq system-type 'windows-nt)
+ (list "-c" "i18n.logOutputEncoding=UTF-8")))
+ "Global Git arguments.
+
+The arguments set here are used every time the git executable is
+run as a subprocess. They are placed right after the executable
+itself and before the git command - as in `git HERE... COMMAND
+REST'. See the manpage `git(1)' for valid arguments.
+
+Be careful what you add here, especially if you are using Tramp
+to connect to servers with ancient Git versions. Never remove
+anything that is part of the default value, unless you really
+know what you are doing. And think very hard before adding
+something; it will be used every time Magit runs Git for any
+purpose."
+ :package-version '(magit . "2.9.0")
+ :group 'magit-commands
+ :group 'magit-process
+ :type '(repeat string))
+
+(defcustom magit-prefer-remote-upstream nil
+ "Whether to favor remote branches when reading the upstream branch.
+
+This controls whether commands that read a branch from the user
+and then set it as the upstream branch, offer a local or a remote
+branch as default completion candidate, when they have the choice.
+
+This affects all commands that use `magit-read-upstream-branch'
+or `magit-read-starting-point', which includes most commands
+that change the upstream and many that create new branches."
+ :package-version '(magit . "2.4.2")
+ :group 'magit-commands
+ :type 'boolean)
+
+(defcustom magit-list-refs-namespaces
+ '("refs/heads"
+ "refs/remotes"
+ "refs/tags"
+ "refs/pullreqs")
+ "List of ref namespaces considered when reading a ref.
+
+This controls the order of refs returned by `magit-list-refs',
+which is called by functions like `magit-list-branch-names' to
+generate the collection of refs."
+ :package-version '(magit . "3.1.0")
+ :group 'magit-commands
+ :type '(repeat string))
+
+(defcustom magit-list-refs-sortby nil
+ "How to sort the ref collection in the prompt.
+
+This affects commands that read a ref. More specifically, it
+controls the order of refs returned by `magit-list-refs', which
+is called by functions like `magit-list-branch-names' to generate
+the collection of refs. By default, refs are sorted according to
+their full refname (i.e., 'refs/...').
+
+Any value accepted by the `--sort' flag of `git for-each-ref' can
+be used. For example, \"-creatordate\" places refs with more
+recent committer or tagger dates earlier in the list. A list of
+strings can also be given in order to pass multiple sort keys to
+`git for-each-ref'.
+
+Note that, depending on the completion framework you use, this
+may not be sufficient to change the order in which the refs are
+displayed. It only controls the order of the collection passed
+to `magit-completing-read' or, for commands that support reading
+multiple strings, `read-from-minibuffer'. The completion
+framework ultimately determines how the collection is displayed."
+ :package-version '(magit . "2.11.0")
+ :group 'magit-miscellaneous
+ :type '(choice string (repeat string)))
+
+;;; Git
+
+(defvar magit-git-debug nil
+ "Whether to enable additional reporting of git errors.
+
+Magit basically calls git for one of these two reasons: for
+side-effects or to do something with its standard output.
+
+When git is run for side-effects then its output, including error
+messages, go into the process buffer which is shown when using \
+\\<magit-status-mode-map>\\[magit-process].
+
+When git's output is consumed in some way, then it would be too
+expensive to also insert it into this buffer, but when this
+option is non-nil and git returns with a non-zero exit status,
+then at least its standard error is inserted into this buffer.
+
+This is only intended for debugging purposes. Do not enable this
+permanently, that would negatively affect performance. Also note
+that just because git exits with a non-zero exit status and prints
+an error message that usually doesn't mean that it is an error as
+far as Magit is concerned, which is another reason we usually hide
+these error messages. Whether some error message is relevant in
+the context of some unexpected behavior has to be judged on a case
+by case basis.
+
+The command `magit-toggle-git-debug' changes the value of this
+variable.
+
+Also see `magit-process-extreme-logging'.")
+
+(defun magit-toggle-git-debug ()
+ "Toggle whether additional git errors are reported.
+See info node `(magit)Debugging Tools' for more information."
+ (interactive)
+ (setq magit-git-debug (not magit-git-debug))
+ (message "Additional reporting of Git errors %s"
+ (if magit-git-debug "enabled" "disabled")))
+
+(defvar magit--refresh-cache nil)
+
+(defmacro magit--with-refresh-cache (key &rest body)
+ (declare (indent 1) (debug (form body)))
+ (let ((k (cl-gensym)))
+ `(if magit--refresh-cache
+ (let ((,k ,key))
+ (--if-let (assoc ,k (cdr magit--refresh-cache))
+ (progn (cl-incf (caar magit--refresh-cache))
+ (cdr it))
+ (cl-incf (cdar magit--refresh-cache))
+ (let ((value ,(macroexp-progn body)))
+ (push (cons ,k value)
+ (cdr magit--refresh-cache))
+ value)))
+ ,@body)))
+
+(defvar magit-with-editor-envvar "GIT_EDITOR"
+ "The environment variable exported by `magit-with-editor'.
+Set this to \"GIT_SEQUENCE_EDITOR\" if you do not want to use
+Emacs to edit commit messages but would like to do so to edit
+rebase sequences.")
+
+(defmacro magit-with-editor (&rest body)
+ "Like `with-editor' but let-bind some more variables.
+Also respect the value of `magit-with-editor-envvar'."
+ (declare (indent 0) (debug (body)))
+ `(let ((magit-process-popup-time -1)
+ ;; The user may have customized `shell-file-name' to
+ ;; something which results in `w32-shell-dos-semantics' nil
+ ;; (which changes the quoting style used by
+ ;; `shell-quote-argument'), but Git for Windows expects shell
+ ;; quoting in the dos style.
+ (shell-file-name (if (and (eq system-type 'windows-nt)
+ ;; If we have Cygwin mount points,
+ ;; the git flavor is cygwin, so dos
+ ;; shell quoting is probably wrong.
+ (not magit-cygwin-mount-points))
+ "cmdproxy"
+ shell-file-name)))
+ (with-editor* magit-with-editor-envvar
+ ,@body)))
+
+(defmacro magit--with-temp-process-buffer (&rest body)
+ "Like `with-temp-buffer', but always propagate `process-environment'.
+When that var is buffer-local in the calling buffer, it is not
+propagated by `with-temp-buffer', so we explicitly ensure that
+happens, so that processes will be invoked consistently. BODY is
+as for that macro."
+ (declare (indent 0) (debug (body)))
+ (let ((p (cl-gensym)))
+ `(let ((,p process-environment))
+ (with-temp-buffer
+ (setq-local process-environment ,p)
+ ,@body))))
+
+(defsubst magit-git-executable ()
+ "Return value of `magit-git-executable' or `magit-remote-git-executable'.
+The variable is chosen depending on whether `default-directory'
+is remote."
+ (if (file-remote-p default-directory)
+ magit-remote-git-executable
+ magit-git-executable))
+
+(defun magit-process-git-arguments (args)
+ "Prepare ARGS for a function that invokes Git.
+
+Magit has many specialized functions for running Git; they all
+pass arguments through this function before handing them to Git,
+to do the following.
+
+* Flatten ARGS, removing nil arguments.
+* Prepend `magit-git-global-arguments' to ARGS.
+* On w32 systems, encode to `w32-ansi-code-page'."
+ (setq args (append magit-git-global-arguments (flatten-tree args)))
+ (if (and (eq system-type 'windows-nt) (boundp 'w32-ansi-code-page))
+ ;; On w32, the process arguments *must* be encoded in the
+ ;; current code-page (see #3250).
+ (mapcar (lambda (arg)
+ (encode-coding-string
+ arg (intern (format "cp%d" w32-ansi-code-page))))
+ args)
+ args))
+
+(defun magit-git-exit-code (&rest args)
+ "Execute Git with ARGS, returning its exit code."
+ (magit-process-git nil args))
+
+(defun magit-git-success (&rest args)
+ "Execute Git with ARGS, returning t if its exit code is 0."
+ (= (magit-git-exit-code args) 0))
+
+(defun magit-git-failure (&rest args)
+ "Execute Git with ARGS, returning t if its exit code is 1."
+ (= (magit-git-exit-code args) 1))
+
+(defun magit-git-string-p (&rest args)
+ "Execute Git with ARGS, returning the first line of its output.
+If the exit code isn't zero or if there is no output, then return
+nil. Neither of these results is considered an error; if that is
+what you want, then use `magit-git-string-ng' instead.
+
+This is an experimental replacement for `magit-git-string', and
+still subject to major changes."
+ (magit--with-refresh-cache (cons default-directory args)
+ (magit--with-temp-process-buffer
+ (and (zerop (magit-process-git t args))
+ (not (bobp))
+ (progn
+ (goto-char (point-min))
+ (buffer-substring-no-properties (point) (line-end-position)))))))
+
+(defun magit-git-string-ng (&rest args)
+ "Execute Git with ARGS, returning the first line of its output.
+If the exit code isn't zero or if there is no output, then that
+is considered an error, but instead of actually signaling an
+error, return nil. Additionally the output is put in the process
+buffer (creating it if necessary) and the error message is shown
+in the status buffer (provided it exists).
+
+This is an experimental replacement for `magit-git-string', and
+still subject to major changes. Also see `magit-git-string-p'."
+ (magit--with-refresh-cache
+ (list default-directory 'magit-git-string-ng args)
+ (magit--with-temp-process-buffer
+ (let* ((args (magit-process-git-arguments args))
+ (status (magit-process-git t args)))
+ (if (zerop status)
+ (and (not (bobp))
+ (progn
+ (goto-char (point-min))
+ (buffer-substring-no-properties
+ (point) (line-end-position))))
+ (let ((buf (current-buffer)))
+ (with-current-buffer (magit-process-buffer t)
+ (magit-process-insert-section default-directory
+ magit-git-executable args
+ status buf)))
+ (when-let ((status-buf (magit-get-mode-buffer 'magit-status-mode)))
+ (let ((msg (magit--locate-error-message)))
+ (with-current-buffer status-buf
+ (setq magit-this-error msg))))
+ nil)))))
+
+(defun magit-git-str (&rest args)
+ "Execute Git with ARGS, returning the first line of its output.
+If there is no output, return nil. If the output begins with a
+newline, return an empty string. Like `magit-git-string' but
+ignore `magit-git-debug'."
+ (setq args (flatten-tree args))
+ (magit--with-refresh-cache (cons default-directory args)
+ (magit--with-temp-process-buffer
+ (magit-process-git (list t nil) args)
+ (unless (bobp)
+ (goto-char (point-min))
+ (buffer-substring-no-properties (point) (line-end-position))))))
+
+(defun magit-git-output (&rest args)
+ "Execute Git with ARGS, returning its output."
+ (setq args (flatten-tree args))
+ (magit--with-refresh-cache (cons default-directory args)
+ (magit--with-temp-process-buffer
+ (magit-process-git (list t nil) args)
+ (buffer-substring-no-properties (point-min) (point-max)))))
+
+(define-error 'magit-invalid-git-boolean "Not a Git boolean")
+
+(defun magit-git-true (&rest args)
+ "Execute Git with ARGS, returning t if it prints \"true\".
+If it prints \"false\", then return nil. For any other output
+signal `magit-invalid-git-boolean'."
+ (pcase (magit-git-output args)
+ ((or "true" "true\n") t)
+ ((or "false" "false\n") nil)
+ (output (signal 'magit-invalid-git-boolean (list output)))))
+
+(defun magit-git-false (&rest args)
+ "Execute Git with ARGS, returning t if it prints \"false\".
+If it prints \"true\", then return nil. For any other output
+signal `magit-invalid-git-boolean'."
+ (pcase (magit-git-output args)
+ ((or "true" "true\n") nil)
+ ((or "false" "false\n") t)
+ (output (signal 'magit-invalid-git-boolean (list output)))))
+
+(defun magit-git-config-p (variable &optional default)
+ "Return the boolean value of the Git variable VARIABLE.
+VARIABLE has to be specified as a string. Return DEFAULT (which
+defaults to nil) if VARIABLE is unset. If VARIABLE's value isn't
+a boolean, then raise an error."
+ (let ((args (list "config" "--bool" "--default" (if default "true" "false")
+ variable)))
+ (magit--with-refresh-cache (cons default-directory args)
+ (magit--with-temp-process-buffer
+ (let ((status (magit-process-git t args))
+ (output (buffer-substring (point-min) (1- (point-max)))))
+ (if (zerop status)
+ (equal output "true")
+ (signal 'magit-invalid-git-boolean (list output))))))))
+
+(defun magit-git-insert (&rest args)
+ "Execute Git with ARGS, inserting its output at point.
+If Git exits with a non-zero exit status, then show a message and
+add a section in the respective process buffer."
+ (setq args (magit-process-git-arguments args))
+ (if magit-git-debug
+ (let (log)
+ (unwind-protect
+ (progn
+ (setq log (make-temp-file "magit-stderr"))
+ (delete-file log)
+ (let ((exit (magit-process-git (list t log) args)))
+ (when (> exit 0)
+ (let ((msg "Git failed"))
+ (when (file-exists-p log)
+ (setq msg (with-temp-buffer
+ (insert-file-contents log)
+ (goto-char (point-max))
+ (if (functionp magit-git-debug)
+ (funcall magit-git-debug (buffer-string))
+ (magit--locate-error-message))))
+ (let ((magit-git-debug nil))
+ (with-current-buffer (magit-process-buffer t)
+ (magit-process-insert-section default-directory
+ magit-git-executable
+ args exit log))))
+ (message "%s" msg)))
+ exit))
+ (ignore-errors (delete-file log))))
+ (magit-process-git (list t nil) args)))
+
+(defun magit--locate-error-message ()
+ (goto-char (point-max))
+ (and (run-hook-wrapped 'magit-process-error-message-regexps
+ (lambda (re) (re-search-backward re nil t)))
+ (match-string-no-properties 1)))
+
+(defun magit-git-string (&rest args)
+ "Execute Git with ARGS, returning the first line of its output.
+If there is no output, return nil. If the output begins with a
+newline, return an empty string."
+ (setq args (flatten-tree args))
+ (magit--with-refresh-cache (cons default-directory args)
+ (magit--with-temp-process-buffer
+ (apply #'magit-git-insert args)
+ (unless (bobp)
+ (goto-char (point-min))
+ (buffer-substring-no-properties (point) (line-end-position))))))
+
+(defun magit-git-lines (&rest args)
+ "Execute Git with ARGS, returning its output as a list of lines.
+Empty lines anywhere in the output are omitted.
+
+If Git exits with a non-zero exit status, then report show a
+message and add a section in the respective process buffer."
+ (magit--with-temp-process-buffer
+ (apply #'magit-git-insert args)
+ (split-string (buffer-string) "\n" t)))
+
+(defun magit-git-items (&rest args)
+ "Execute Git with ARGS, returning its null-separated output as a list.
+Empty items anywhere in the output are omitted.
+
+If Git exits with a non-zero exit status, then report show a
+message and add a section in the respective process buffer."
+ (magit--with-temp-process-buffer
+ (apply #'magit-git-insert args)
+ (split-string (buffer-string) "\0" t)))
+
+(defun magit-git-wash (washer &rest args)
+ "Execute Git with ARGS, inserting washed output at point.
+Actually first insert the raw output at point. If there is no
+output, call `magit-cancel-section'. Otherwise temporarily narrow
+the buffer to the inserted text, move to its beginning, and then
+call function WASHER with ARGS as its sole argument."
+ (declare (indent 1))
+ (let ((beg (point)))
+ (setq args (flatten-tree args))
+ (magit-git-insert args)
+ (if (= (point) beg)
+ (magit-cancel-section)
+ (unless (bolp)
+ (insert "\n"))
+ (save-restriction
+ (narrow-to-region beg (point))
+ (goto-char beg)
+ (funcall washer args))
+ (when (or (= (point) beg)
+ (= (point) (1+ beg)))
+ (magit-cancel-section))
+ (magit-maybe-make-margin-overlay))))
+
+;;; Git Version
+
+(defconst magit--git-version-regexp
+ "\\`git version \\([0-9]+\\(\\.[0-9]+\\)\\{1,2\\}\\)")
+
+(defvar magit--host-git-version-cache nil)
+
+(defun magit-git-version>= (n)
+ "Return t if `magit-git-version's value is greater than or equal to N."
+ (magit--version>= (magit-git-version) n))
+
+(defun magit-git-version< (n)
+ "Return t if `magit-git-version's value is smaller than N."
+ (version< (magit-git-version) n))
+
+(defun magit-git-version ()
+ "Return the Git version used for `default-directory'.
+Raise an error if Git cannot be found, if it exits with a
+non-zero status, or the output does not have the expected
+format."
+ (magit--with-refresh-cache default-directory
+ (let ((host (file-remote-p default-directory)))
+ (or (cdr (assoc host magit--host-git-version-cache))
+ (magit--with-temp-process-buffer
+ ;; Unset global arguments for ancient Git versions.
+ (let* ((magit-git-global-arguments nil)
+ (status (magit-process-git t "version"))
+ (output (buffer-string)))
+ (cond
+ ((not (zerop status))
+ (display-warning
+ 'magit
+ (format "%S\n\nRunning \"%s --version\" failed with output:\n\n%s"
+ (if host
+ (format "Magit cannot find Git on host %S.\n
+Check the value of `magit-remote-git-executable' using
+`magit-debug-git-executable' and consult the info node
+`(tramp)Remote programs'." host)
+ "Magit cannot find Git.\n
+Check the values of `magit-git-executable' and `exec-path'
+using `magit-debug-git-executable'.")
+ (magit-git-executable)
+ output)))
+ ((save-match-data
+ (and (string-match magit--git-version-regexp output)
+ (let ((version (match-string 1 output)))
+ (push (cons host version)
+ magit--host-git-version-cache)
+ version))))
+ (t (error "Unexpected \"%s --version\" output: %S"
+ (magit-git-executable)
+ output)))))))))
+
+(defun magit-git-version-assert (&optional minimal who)
+ "Assert that the used Git version is greater than or equal to MINIMAL.
+If optional MINIMAL is nil, compare with `magit--minimal-git'
+instead. Optional WHO if non-nil specifies what functionality
+needs at least MINIMAL, otherwise it defaults to \"Magit\"."
+ (when (magit-git-version< (or minimal magit--minimal-git))
+ (let* ((host (file-remote-p default-directory))
+ (msg (format-spec
+ (cond (host "\
+%w requires Git %m or greater, but on %h the version is %m.
+
+If multiple Git versions are installed on the host, then the
+problem might be that TRAMP uses the wrong executable.
+
+Check the value of `magit-remote-git-executable' and consult
+the info node `(tramp)Remote programs'.\n")
+ (t "\
+%w requires Git %m or greater, but you are using %v.
+
+If you have multiple Git versions installed, then check the
+values of `magit-remote-git-executable' and `exec-path'.\n"))
+ `((?w . ,(or who "Magit"))
+ (?m . ,(or minimal magit--minimal-git))
+ (?v . ,(magit-git-version))
+ (?h . ,host)))))
+ (display-warning 'magit msg :error))))
+
+(defun magit--safe-git-version ()
+ "Return the Git version used for `default-directory' or an error message."
+ (magit--with-temp-process-buffer
+ (let* ((magit-git-global-arguments nil)
+ (status (magit-process-git t "version"))
+ (output (buffer-string)))
+ (cond ((not (zerop status)) output)
+ ((save-match-data
+ (and (string-match magit--git-version-regexp output)
+ (match-string 1 output))))
+ (t output)))))
+
+(defun magit-debug-git-executable ()
+ "Display a buffer with information about `magit-git-executable'.
+Also include information about `magit-remote-git-executable'.
+See info node `(magit)Debugging Tools' for more information."
+ (interactive)
+ (with-current-buffer (get-buffer-create "*magit-git-debug*")
+ (pop-to-buffer (current-buffer))
+ (erase-buffer)
+ (insert (format "magit-remote-git-executable: %S\n"
+ magit-remote-git-executable))
+ (insert (concat
+ (format "magit-git-executable: %S" magit-git-executable)
+ (and (not (file-name-absolute-p magit-git-executable))
+ (format " [%S]" (executable-find magit-git-executable)))
+ (format " (%s)\n" (magit--safe-git-version))))
+ (insert (format "exec-path: %S\n" exec-path))
+ (--when-let (cl-set-difference
+ (-filter #'file-exists-p (remq nil (parse-colon-path
+ (getenv "PATH"))))
+ (-filter #'file-exists-p (remq nil exec-path))
+ :test #'file-equal-p)
+ (insert (format " entries in PATH, but not in exec-path: %S\n" it)))
+ (dolist (execdir exec-path)
+ (insert (format " %s (%s)\n" execdir (car (file-attributes execdir))))
+ (when (file-directory-p execdir)
+ (dolist (exec (directory-files
+ execdir t (concat
+ "\\`git" (regexp-opt exec-suffixes) "\\'")))
+ (insert (format " %s (%s)\n" exec
+ (magit--safe-git-version))))))))
+
+;;; Variables
+
+(defun magit-config-get-from-cached-list (key)
+ (gethash
+ ;; `git config --list' downcases first and last components of the key.
+ (let* ((key (replace-regexp-in-string "\\`[^.]+" #'downcase key t t))
+ (key (replace-regexp-in-string "[^.]+\\'" #'downcase key t t)))
+ key)
+ (magit--with-refresh-cache (cons (magit-toplevel) 'config)
+ (let ((configs (make-hash-table :test #'equal)))
+ (dolist (conf (magit-git-items "config" "--list" "-z"))
+ (let* ((nl-pos (cl-position ?\n conf))
+ (key (substring conf 0 nl-pos))
+ (val (if nl-pos (substring conf (1+ nl-pos)) "")))
+ (puthash key (nconc (gethash key configs) (list val)) configs)))
+ configs))))
+
+(defun magit-get (&rest keys)
+ "Return the value of the Git variable specified by KEYS."
+ (car (last (apply #'magit-get-all keys))))
+
+(defun magit-get-all (&rest keys)
+ "Return all values of the Git variable specified by KEYS."
+ (let ((magit-git-debug nil)
+ (arg (and (or (null (car keys))
+ (string-prefix-p "--" (car keys)))
+ (pop keys)))
+ (key (mapconcat #'identity keys ".")))
+ (if (and magit--refresh-cache (not arg))
+ (magit-config-get-from-cached-list key)
+ (magit-git-items "config" arg "-z" "--get-all" key))))
+
+(defun magit-get-boolean (&rest keys)
+ "Return the boolean value of the Git variable specified by KEYS.
+Also see `magit-git-config-p'."
+ (let ((arg (and (or (null (car keys))
+ (string-prefix-p "--" (car keys)))
+ (pop keys)))
+ (key (mapconcat #'identity keys ".")))
+ (equal (if magit--refresh-cache
+ (car (last (magit-config-get-from-cached-list key)))
+ (magit-git-str "config" arg "--bool" key))
+ "true")))
+
+(defun magit-set (value &rest keys)
+ "Set the value of the Git variable specified by KEYS to VALUE."
+ (let ((arg (and (or (null (car keys))
+ (string-prefix-p "--" (car keys)))
+ (pop keys)))
+ (key (mapconcat #'identity keys ".")))
+ (if value
+ (magit-git-success "config" arg key value)
+ (magit-git-success "config" arg "--unset" key))
+ value))
+
+(gv-define-setter magit-get (val &rest keys)
+ `(magit-set ,val ,@keys))
+
+(defun magit-set-all (values &rest keys)
+ "Set all values of the Git variable specified by KEYS to VALUES."
+ (let ((arg (and (or (null (car keys))
+ (string-prefix-p "--" (car keys)))
+ (pop keys)))
+ (var (mapconcat #'identity keys ".")))
+ (when (magit-get var)
+ (magit-call-git "config" arg "--unset-all" var))
+ (dolist (v values)
+ (magit-call-git "config" arg "--add" var v))))
+
+;;; Files
+
+(defun magit--safe-default-directory (&optional file)
+ (catch 'unsafe-default-dir
+ (let ((dir (file-name-as-directory
+ (expand-file-name (or file default-directory))))
+ (previous nil))
+ (while (not (magit-file-accessible-directory-p dir))
+ (setq dir (file-name-directory (directory-file-name dir)))
+ (when (equal dir previous)
+ (throw 'unsafe-default-dir nil))
+ (setq previous dir))
+ dir)))
+
+(defmacro magit--with-safe-default-directory (file &rest body)
+ (declare (indent 1) (debug (form body)))
+ `(when-let ((default-directory (magit--safe-default-directory ,file)))
+ ,@body))
+
+(defun magit-gitdir (&optional directory)
+ "Return the absolute and resolved path of the .git directory.
+
+If the `GIT_DIR' environment variable is define then return that.
+Otherwise return the .git directory for DIRECTORY, or if that is
+nil, then for `default-directory' instead. If the directory is
+not located inside a Git repository, then return nil."
+ (let ((default-directory (or directory default-directory)))
+ (magit-git-dir)))
+
+(defun magit-git-dir (&optional path)
+ "Return the absolute and resolved path of the .git directory.
+
+If the `GIT_DIR' environment variable is define then return that.
+Otherwise return the .git directory for `default-directory'. If
+the directory is not located inside a Git repository, then return
+nil."
+ (magit--with-refresh-cache (list default-directory 'magit-git-dir path)
+ (magit--with-safe-default-directory nil
+ (and-let* ((dir (magit-rev-parse-safe "--git-dir"))
+ (dir (file-name-as-directory (magit-expand-git-file-name dir)))
+ (dir (if (file-remote-p dir)
+ dir
+ (concat (file-remote-p default-directory) dir))))
+ (if path (expand-file-name (convert-standard-filename path) dir) dir)))))
+
+(defvar magit--separated-gitdirs nil)
+
+(defun magit--record-separated-gitdir ()
+ (let ((topdir (magit-toplevel))
+ (gitdir (magit-git-dir)))
+ ;; Kludge: git-annex converts submodule gitdirs to symlinks. See #3599.
+ (when (file-symlink-p (directory-file-name gitdir))
+ (setq gitdir (file-truename gitdir)))
+ ;; We want to delete the entry for `topdir' here, rather than within
+ ;; (unless ...), in case a `--separate-git-dir' repository was switched to
+ ;; the standard structure (i.e., "topdir/.git/").
+ (setq magit--separated-gitdirs (cl-delete topdir
+ magit--separated-gitdirs
+ :key #'car :test #'equal))
+ (unless (equal (file-name-as-directory (expand-file-name ".git" topdir))
+ gitdir)
+ (push (cons topdir gitdir) magit--separated-gitdirs))))
+
+(defun magit-toplevel (&optional directory)
+ "Return the absolute path to the toplevel of the current repository.
+
+From within the working tree or control directory of a repository
+return the absolute path to the toplevel directory of the working
+tree. As a special case, from within a bare repository return
+the control directory instead. When called outside a repository
+then return nil.
+
+When optional DIRECTORY is non-nil then return the toplevel for
+that directory instead of the one for `default-directory'.
+
+Try to respect the option `find-file-visit-truename', i.e. when
+the value of that option is nil, then avoid needlessly returning
+the truename. When a symlink to a sub-directory of the working
+tree is involved, or when called from within a sub-directory of
+the gitdir or from the toplevel of a gitdir, which itself is not
+located within the working tree, then it is not possible to avoid
+returning the truename."
+ (magit--with-refresh-cache
+ (cons (or directory default-directory) 'magit-toplevel)
+ (magit--with-safe-default-directory directory
+ (if-let ((topdir (magit-rev-parse-safe "--show-toplevel")))
+ (let (updir)
+ (setq topdir (magit-expand-git-file-name topdir))
+ (if (and
+ ;; Always honor these settings.
+ (not find-file-visit-truename)
+ (not (getenv "GIT_WORK_TREE"))
+ ;; `--show-cdup' is the relative path to the toplevel
+ ;; from `(file-truename default-directory)'. Here we
+ ;; pretend it is relative to `default-directory', and
+ ;; go to that directory. Then we check whether
+ ;; `--show-toplevel' still returns the same value and
+ ;; whether `--show-cdup' now is the empty string. If
+ ;; both is the case, then we are at the toplevel of
+ ;; the same working tree, but also avoided needlessly
+ ;; following any symlinks.
+ (progn
+ (setq updir (file-name-as-directory
+ (magit-rev-parse-safe "--show-cdup")))
+ (setq updir (if (file-name-absolute-p updir)
+ (concat (file-remote-p default-directory) updir)
+ (expand-file-name updir)))
+ (and-let*
+ ((default-directory updir)
+ (top (and (string-equal
+ (magit-rev-parse-safe "--show-cdup") "")
+ (magit-rev-parse-safe "--show-toplevel"))))
+ (string-equal (magit-expand-git-file-name top) topdir))))
+ updir
+ (concat (file-remote-p default-directory)
+ (file-name-as-directory topdir))))
+ (and-let* ((gitdir (magit-rev-parse-safe "--git-dir"))
+ (gitdir (file-name-as-directory
+ (if (file-name-absolute-p gitdir)
+ ;; We might have followed a symlink.
+ (concat (file-remote-p default-directory)
+ (magit-expand-git-file-name gitdir))
+ (expand-file-name gitdir)))))
+ (if (magit-bare-repo-p)
+ gitdir
+ (let* ((link (expand-file-name "gitdir" gitdir))
+ (wtree (and (file-exists-p link)
+ (magit-file-line link))))
+ (cond
+ ((and wtree
+ ;; Ignore .git/gitdir files that result from a
+ ;; Git bug. See #2364.
+ (not (equal wtree ".git")))
+ ;; Return the linked working tree.
+ (concat (file-remote-p default-directory)
+ (file-name-directory wtree)))
+ ;; The working directory may not be the parent directory of
+ ;; .git if it was set up with `git init --separate-git-dir'.
+ ;; See #2955.
+ ((car (rassoc gitdir magit--separated-gitdirs)))
+ (t
+ ;; Step outside the control directory to enter the working tree.
+ (file-name-directory (directory-file-name gitdir)))))))))))
+
+(defmacro magit-with-toplevel (&rest body)
+ (declare (indent defun) (debug (body)))
+ (let ((toplevel (cl-gensym "toplevel")))
+ `(let ((,toplevel (magit-toplevel)))
+ (if ,toplevel
+ (let ((default-directory ,toplevel))
+ ,@body)
+ (magit--not-inside-repository-error)))))
+
+(define-error 'magit-outside-git-repo "Not inside Git repository")
+(define-error 'magit-corrupt-git-config "Corrupt Git configuration")
+(define-error 'magit-git-executable-not-found
+ "Git executable cannot be found (see https://magit.vc/goto/e6a78ed2)")
+
+(defun magit--assert-usable-git ()
+ (if (not (compat-executable-find (magit-git-executable) t))
+ (signal 'magit-git-executable-not-found (magit-git-executable))
+ (let ((magit-git-debug
+ (lambda (err)
+ (signal 'magit-corrupt-git-config
+ (format "%s: %s" default-directory err)))))
+ ;; This should always succeed unless there's a corrupt config
+ ;; (or at least a similarly severe failing state). Note that
+ ;; git-config's --default is avoided because it's not available
+ ;; until Git 2.18.
+ (magit-git-string "config" "--get-color" "" "reset"))
+ nil))
+
+(defun magit--not-inside-repository-error ()
+ (magit--assert-usable-git)
+ (signal 'magit-outside-git-repo default-directory))
+
+(defun magit-inside-gitdir-p (&optional noerror)
+ "Return t if `default-directory' is below the repository directory.
+If it is below the working directory, then return nil.
+If it isn't below either, then signal an error unless NOERROR
+is non-nil, in which case return nil."
+ (and (magit--assert-default-directory noerror)
+ ;; Below a repository directory that is not located below the
+ ;; working directory "git rev-parse --is-inside-git-dir" prints
+ ;; "false", which is wrong.
+ (let ((gitdir (magit-git-dir)))
+ (cond (gitdir (file-in-directory-p default-directory gitdir))
+ (noerror nil)
+ (t (signal 'magit-outside-git-repo default-directory))))))
+
+(defun magit-inside-worktree-p (&optional noerror)
+ "Return t if `default-directory' is below the working directory.
+If it is below the repository directory, then return nil.
+If it isn't below either, then signal an error unless NOERROR
+is non-nil, in which case return nil."
+ (and (magit--assert-default-directory noerror)
+ (condition-case nil
+ (magit-rev-parse-true "--is-inside-work-tree")
+ (magit-invalid-git-boolean
+ (and (not noerror)
+ (signal 'magit-outside-git-repo default-directory))))))
+
+(cl-defgeneric magit-bare-repo-p (&optional noerror)
+ "Return t if the current repository is bare.
+If it is non-bare, then return nil. If `default-directory'
+isn't below a Git repository, then signal an error unless
+NOERROR is non-nil, in which case return nil."
+ (and (magit--assert-default-directory noerror)
+ (condition-case nil
+ (magit-rev-parse-true "--is-bare-repository")
+ (magit-invalid-git-boolean
+ (and (not noerror)
+ (signal 'magit-outside-git-repo default-directory))))))
+
+(defun magit--assert-default-directory (&optional noerror)
+ (or (file-directory-p default-directory)
+ (and (not noerror)
+ (let ((exists (file-exists-p default-directory)))
+ (signal (if exists 'file-error 'file-missing)
+ (list "Running git in directory"
+ (if exists
+ "Not a directory"
+ "No such file or directory")
+ default-directory))))))
+
+(defun magit-git-repo-p (directory &optional non-bare)
+ "Return t if DIRECTORY is a Git repository.
+When optional NON-BARE is non-nil also return nil if DIRECTORY is
+a bare repository."
+ (and (file-directory-p directory) ; Avoid archives, see #3397.
+ (or (file-regular-p (expand-file-name ".git" directory))
+ (file-directory-p (expand-file-name ".git" directory))
+ (and (not non-bare)
+ (file-regular-p (expand-file-name "HEAD" directory))
+ (file-directory-p (expand-file-name "refs" directory))
+ (file-directory-p (expand-file-name "objects" directory))))))
+
+(defun magit-file-relative-name (&optional file tracked)
+ "Return the path of FILE relative to the repository root.
+
+If optional FILE is nil or omitted, return the relative path of
+the file being visited in the current buffer, if any, else nil.
+If the file is not inside a Git repository, then return nil.
+
+If TRACKED is non-nil, return the path only if it matches a
+tracked file."
+ (unless file
+ (with-current-buffer (or (buffer-base-buffer)
+ (current-buffer))
+ (setq file (or magit-buffer-file-name buffer-file-name
+ (and (derived-mode-p 'dired-mode) default-directory)))))
+ (when (and file (or (not tracked)
+ (magit-file-tracked-p (file-relative-name file))))
+ (and-let* ((dir (magit-toplevel
+ (magit--safe-default-directory
+ (directory-file-name (file-name-directory file))))))
+ (file-relative-name file dir))))
+
+(defun magit-file-tracked-p (file)
+ (magit-git-success "ls-files" "--error-unmatch" file))
+
+(defun magit-list-files (&rest args)
+ (apply #'magit-git-items "ls-files" "-z" "--full-name" args))
+
+(defun magit-tracked-files ()
+ (magit-list-files "--cached"))
+
+(defun magit-untracked-files (&optional all files)
+ (magit-list-files "--other" (unless all "--exclude-standard") "--" files))
+
+(defun magit-modified-files (&optional nomodules files)
+ (magit-git-items "diff-index" "-z" "--name-only"
+ (and nomodules "--ignore-submodules")
+ (magit-headish) "--" files))
+
+(defun magit-unstaged-files (&optional nomodules files)
+ (magit-git-items "diff-files" "-z" "--name-only"
+ (and nomodules "--ignore-submodules")
+ "--" files))
+
+(defun magit-staged-files (&optional nomodules files)
+ (magit-git-items "diff-index" "-z" "--name-only" "--cached"
+ (and nomodules "--ignore-submodules")
+ (magit-headish) "--" files))
+
+(defun magit-binary-files (&rest args)
+ (--mapcat (and (string-match "^-\t-\t\\(.+\\)" it)
+ (list (match-string 1 it)))
+ (apply #'magit-git-items
+ "diff" "-z" "--numstat" "--ignore-submodules"
+ args)))
+
+(defun magit-unmerged-files ()
+ (magit-git-items "diff-files" "-z" "--name-only" "--diff-filter=U"))
+
+(defun magit-ignored-files ()
+ (magit-git-items "ls-files" "-z" "--others" "--ignored"
+ "--exclude-standard" "--directory"))
+
+(defun magit-skip-worktree-files ()
+ (--keep (and (and (= (aref it 0) ?S)
+ (substring it 2)))
+ (magit-list-files "-t")))
+
+(defun magit-assume-unchanged-files ()
+ (--keep (and (and (memq (aref it 0) '(?h ?s ?m ?r ?c ?k))
+ (substring it 2)))
+ (magit-list-files "-v")))
+
+(defun magit-revision-files (rev)
+ (magit-with-toplevel
+ (magit-git-items "ls-tree" "-z" "-r" "--name-only" rev)))
+
+(defun magit-revision-directories (rev)
+ "List directories that contain a tracked file in revision REV."
+ (magit-with-toplevel
+ (mapcar #'file-name-as-directory
+ (magit-git-items "ls-tree" "-z" "-r" "-d" "--name-only" rev))))
+
+(defun magit-changed-files (rev-or-range &optional other-rev)
+ "Return list of files the have changed between two revisions.
+If OTHER-REV is non-nil, REV-OR-RANGE should be a revision, not a
+range. Otherwise, it can be any revision or range accepted by
+\"git diff\" (i.e., <rev>, <revA>..<revB>, or <revA>...<revB>)."
+ (magit-with-toplevel
+ (magit-git-items "diff" "-z" "--name-only" rev-or-range other-rev)))
+
+(defun magit-renamed-files (revA revB)
+ (--map (cons (nth 1 it) (nth 2 it))
+ (-partition 3 (magit-git-items
+ "diff-tree" "-r" "--diff-filter=R" "-z" "-M"
+ revA revB))))
+
+(defun magit-file-status (&rest args)
+ (magit--with-temp-process-buffer
+ (save-excursion (magit-git-insert "status" "-z" args))
+ (let ((pos (point)) status)
+ (while (> (skip-chars-forward "[:print:]") 0)
+ (let ((x (char-after pos))
+ (y (char-after (1+ pos)))
+ (file (buffer-substring (+ pos 3) (point))))
+ (forward-char)
+ (if (memq x '(?R ?C))
+ (progn
+ (setq pos (point))
+ (skip-chars-forward "[:print:]")
+ (push (list file (buffer-substring pos (point)) x y) status)
+ (forward-char))
+ (push (list file nil x y) status)))
+ (setq pos (point)))
+ status)))
+
+(defcustom magit-cygwin-mount-points
+ (when (eq system-type 'windows-nt)
+ (cl-sort (--map (if (string-match "^\\(.*\\) on \\(.*\\) type" it)
+ (cons (file-name-as-directory (match-string 2 it))
+ (file-name-as-directory (match-string 1 it)))
+ (lwarn '(magit) :error
+ "Failed to parse Cygwin mount: %S" it))
+ ;; If --exec-path is not a native Windows path,
+ ;; then we probably have a cygwin git.
+ (let ((process-environment
+ (append magit-git-environment process-environment)))
+ (and (not (string-match-p
+ "\\`[a-zA-Z]:"
+ (car (process-lines
+ magit-git-executable "--exec-path"))))
+ (ignore-errors (process-lines "mount")))))
+ #'> :key (pcase-lambda (`(,cyg . ,_win)) (length cyg))))
+ "Alist of (CYGWIN . WIN32) directory names.
+Sorted from longest to shortest CYGWIN name."
+ :package-version '(magit . "2.3.0")
+ :group 'magit-process
+ :type '(alist :key-type string :value-type directory))
+
+(defun magit-expand-git-file-name (filename)
+ (unless (file-name-absolute-p filename)
+ (setq filename (expand-file-name filename)))
+ (if-let ((cyg:win (cl-assoc filename magit-cygwin-mount-points
+ :test (lambda (f cyg) (string-prefix-p cyg f)))))
+ (concat (cdr cyg:win)
+ (substring filename (length (car cyg:win))))
+ filename))
+
+(defun magit-convert-filename-for-git (filename)
+ "Convert FILENAME so that it can be passed to git.
+1. If it's a absolute filename, then pass through `expand-file-name'
+ to replace things such as \"~/\" that Git does not understand.
+2. If it's a remote filename, then remove the remote part.
+3. Deal with an `windows-nt' Emacs vs. Cygwin Git incompatibility."
+ (if (file-name-absolute-p filename)
+ (if-let ((cyg:win (cl-rassoc filename magit-cygwin-mount-points
+ :test (lambda (f win) (string-prefix-p win f)))))
+ (concat (car cyg:win)
+ (substring filename (length (cdr cyg:win))))
+ (let ((expanded (expand-file-name filename)))
+ (or (file-remote-p expanded 'localname)
+ expanded)))
+ filename))
+
+(defun magit-decode-git-path (path)
+ (if (eq (aref path 0) ?\")
+ (decode-coding-string (read path)
+ (or magit-git-output-coding-system
+ (car default-process-coding-system))
+ t)
+ path))
+
+(defun magit-file-at-point (&optional expand assert)
+ (if-let ((file (magit-section-case
+ (file (oref it value))
+ (hunk (magit-section-parent-value it)))))
+ (if expand
+ (expand-file-name file (magit-toplevel))
+ file)
+ (when assert
+ (user-error "No file at point"))))
+
+(defun magit-current-file ()
+ (or (magit-file-relative-name)
+ (magit-file-at-point)
+ (and (derived-mode-p 'magit-log-mode)
+ (car magit-buffer-log-files))))
+
+;;; Predicates
+
+(defun magit-no-commit-p ()
+ "Return t if there is no commit in the current Git repository."
+ (not (magit-rev-verify "HEAD")))
+
+(defun magit-merge-commit-p (commit)
+ "Return t if COMMIT is a merge commit."
+ (length> (magit-commit-parents commit) 1))
+
+(defun magit-anything-staged-p (&optional ignore-submodules &rest files)
+ "Return t if there are any staged changes.
+If optional FILES is non-nil, then only changes to those files
+are considered."
+ (magit-git-failure "diff" "--quiet" "--cached"
+ (and ignore-submodules "--ignore-submodules")
+ "--" files))
+
+(defun magit-anything-unstaged-p (&optional ignore-submodules &rest files)
+ "Return t if there are any unstaged changes.
+If optional FILES is non-nil, then only changes to those files
+are considered."
+ (magit-git-failure "diff" "--quiet"
+ (and ignore-submodules "--ignore-submodules")
+ "--" files))
+
+(defun magit-anything-modified-p (&optional ignore-submodules &rest files)
+ "Return t if there are any staged or unstaged changes.
+If optional FILES is non-nil, then only changes to those files
+are considered."
+ (or (apply #'magit-anything-staged-p ignore-submodules files)
+ (apply #'magit-anything-unstaged-p ignore-submodules files)))
+
+(defun magit-anything-unmerged-p (&rest files)
+ "Return t if there are any merge conflicts.
+If optional FILES is non-nil, then only conflicts in those files
+are considered."
+ (and (magit-git-string "ls-files" "--unmerged" files) t))
+
+(defun magit-module-worktree-p (module)
+ (magit-with-toplevel
+ (file-exists-p (expand-file-name (expand-file-name ".git" module)))))
+
+(defun magit-module-no-worktree-p (module)
+ (not (magit-module-worktree-p module)))
+
+(defun magit-ignore-submodules-p (&optional return-argument)
+ (or (cl-find-if (lambda (arg)
+ (string-prefix-p "--ignore-submodules" arg))
+ magit-buffer-diff-args)
+ (and-let* ((value (magit-get "diff.ignoreSubmodules")))
+ (if return-argument
+ (concat "--ignore-submodules=" value)
+ (concat "diff.ignoreSubmodules=" value)))))
+
+;;; Revisions and References
+
+(defun magit-rev-parse (&rest args)
+ "Execute `git rev-parse ARGS', returning first line of output.
+If there is no output, return nil."
+ (apply #'magit-git-string "rev-parse" args))
+
+(defun magit-rev-parse-safe (&rest args)
+ "Execute `git rev-parse ARGS', returning first line of output.
+If there is no output, return nil. Like `magit-rev-parse' but
+ignore `magit-git-debug'."
+ (apply #'magit-git-str "rev-parse" args))
+
+(defun magit-rev-parse-true (&rest args)
+ "Execute `git rev-parse ARGS', returning t if it prints \"true\".
+If it prints \"false\", then return nil. For any other output
+signal an error."
+ (magit-git-true "rev-parse" args))
+
+(defun magit-rev-parse-false (&rest args)
+ "Execute `git rev-parse ARGS', returning t if it prints \"false\".
+If it prints \"true\", then return nil. For any other output
+signal an error."
+ (magit-git-false "rev-parse" args))
+
+(defun magit-rev-parse-p (&rest args)
+ "Execute `git rev-parse ARGS', returning t if it prints \"true\".
+Return t if the first (and usually only) output line is the
+string \"true\", otherwise return nil."
+ (equal (magit-git-str "rev-parse" args) "true"))
+
+(defun magit-rev-verify (rev)
+ (magit-git-string-p "rev-parse" "--verify" rev))
+
+(defun magit-commit-p (rev)
+ "Return full hash for REV if it names an existing commit."
+ (magit-rev-verify (magit--rev-dereference rev)))
+
+(defalias 'magit-rev-verify-commit #'magit-commit-p)
+
+(defalias 'magit-rev-hash #'magit-commit-p)
+
+(defun magit--rev-dereference (rev)
+ "Return a rev that forces Git to interpret REV as a commit.
+If REV is nil or has the form \":/TEXT\", return REV itself."
+ (cond ((not rev) nil)
+ ((string-match-p "^:/" rev) rev)
+ (t (concat rev "^{commit}"))))
+
+(defun magit-rev-equal (a b)
+ "Return t if there are no differences between the commits A and B."
+ (magit-git-success "diff" "--quiet" a b))
+
+(defun magit-rev-eq (a b)
+ "Return t if A and B refer to the same commit."
+ (let ((a (magit-commit-p a))
+ (b (magit-commit-p b)))
+ (and a b (equal a b))))
+
+(defun magit-rev-ancestor-p (a b)
+ "Return non-nil if commit A is an ancestor of commit B."
+ (magit-git-success "merge-base" "--is-ancestor" a b))
+
+(defun magit-rev-head-p (rev)
+ (or (equal rev "HEAD")
+ (and rev
+ (not (string-search ".." rev))
+ (equal (magit-rev-parse rev)
+ (magit-rev-parse "HEAD")))))
+
+(defun magit-rev-author-p (rev)
+ "Return t if the user is the author of REV.
+More precisely return t if `user.name' is equal to the author
+name of REV and/or `user.email' is equal to the author email
+of REV."
+ (or (equal (magit-get "user.name") (magit-rev-format "%an" rev))
+ (equal (magit-get "user.email") (magit-rev-format "%ae" rev))))
+
+(defun magit-rev-name (rev &optional pattern not-anchored)
+ "Return a symbolic name for REV using `git-name-rev'.
+
+PATTERN can be used to limit the result to a matching ref.
+Unless NOT-ANCHORED is non-nil, the beginning of the ref must
+match PATTERN.
+
+An anchored lookup is done using the arguments
+\"--exclude=*/<PATTERN> --exclude=*/HEAD\" in addition to
+\"--refs=<PATTERN>\", provided at least version v2.13 of Git is
+used. Older versions did not support the \"--exclude\" argument.
+When \"--exclude\" cannot be used and `git-name-rev' returns a
+ref that should have been excluded, then that is discarded and
+this function returns nil instead. This is unfortunate because
+there might be other refs that do match. To fix that, update
+Git."
+ (if (magit-git-version< "2.13")
+ (and-let*
+ ((ref (magit-git-string "name-rev" "--name-only" "--no-undefined"
+ (and pattern (concat "--refs=" pattern))
+ rev)))
+ (if (and pattern
+ (string-match-p "\\`refs/[^/]+/\\*\\'" pattern))
+ (let ((namespace (substring pattern 0 -1)))
+ (and (not (or (string-suffix-p "HEAD" ref)
+ (and (string-match-p namespace ref)
+ (not (magit-rev-verify
+ (concat namespace ref))))))
+ ref))
+ ref))
+ (magit-git-string "name-rev" "--name-only" "--no-undefined"
+ (and pattern (concat "--refs=" pattern))
+ (and pattern
+ (not not-anchored)
+ (list "--exclude=*/HEAD"
+ (concat "--exclude=*/" pattern)))
+ rev)))
+
+(defun magit-rev-branch (rev)
+ (and-let* ((name (magit-rev-name rev "refs/heads/*")))
+ (and (not (string-match-p "[~^]" name)) name)))
+
+(defun magit-get-shortname (rev)
+ (let* ((fn (apply-partially #'magit-rev-name rev))
+ (name (or (funcall fn "refs/tags/*")
+ (funcall fn "refs/heads/*")
+ (funcall fn "refs/remotes/*"))))
+ (cond ((not name)
+ (magit-rev-parse "--short" rev))
+ ((string-match "^\\(?:tags\\|remotes\\)/\\(.+\\)" name)
+ (if (magit-ref-ambiguous-p (match-string 1 name))
+ name
+ (match-string 1 name)))
+ (t (magit-ref-maybe-qualify name)))))
+
+(defun magit-name-branch (rev &optional lax)
+ (or (magit-name-local-branch rev)
+ (magit-name-remote-branch rev)
+ (and lax (or (magit-name-local-branch rev t)
+ (magit-name-remote-branch rev t)))))
+
+(defun magit-name-local-branch (rev &optional lax)
+ (and-let* ((name (magit-rev-name rev "refs/heads/*")))
+ (and (or lax (not (string-match-p "[~^]" name))) name)))
+
+(defun magit-name-remote-branch (rev &optional lax)
+ (and-let* ((name (magit-rev-name rev "refs/remotes/*")))
+ (and (or lax (not (string-match-p "[~^]" name)))
+ (substring name 8))))
+
+(defun magit-name-tag (rev &optional lax)
+ (when-let* ((name (magit-rev-name rev "refs/tags/*"))) ;debbugs#31840
+ (when (string-suffix-p "^0" name)
+ (setq name (substring name 0 -2)))
+ (and (or lax (not (string-match-p "[~^]" name)))
+ (substring name 5))))
+
+(defun magit-ref-abbrev (refname)
+ "Return an unambiguous abbreviation of REFNAME."
+ (magit-rev-parse "--verify" "--abbrev-ref" refname))
+
+(defun magit-ref-fullname (refname)
+ "Return fully qualified refname for REFNAME.
+If REFNAME is ambiguous, return nil."
+ (magit-rev-parse "--verify" "--symbolic-full-name" refname))
+
+(defun magit-ref-ambiguous-p (refname)
+ (save-match-data
+ (if (string-match "\\`\\([^^~]+\\)\\(.*\\)" refname)
+ (not (magit-ref-fullname (match-string 1 refname)))
+ (error "%S has an unrecognized format" refname))))
+
+(defun magit-ref-maybe-qualify (refname &optional prefix)
+ "If REFNAME is ambiguous, try to disambiguate it by prepend PREFIX to it.
+Return an unambiguous refname, either REFNAME or that prefixed
+with PREFIX, nil otherwise. If REFNAME has an offset suffix
+such as \"~1\", then that is preserved. If optional PREFIX is
+nil, then use \"heads/\". "
+ (if (magit-ref-ambiguous-p refname)
+ (let ((refname (concat (or prefix "heads/") refname)))
+ (and (not (magit-ref-ambiguous-p refname)) refname))
+ refname))
+
+(defun magit-ref-exists-p (ref)
+ (magit-git-success "show-ref" "--verify" ref))
+
+(defun magit-ref-equal (a b)
+ "Return t if the refnames A and B are `equal'.
+A symbolic-ref pointing to some ref, is `equal' to that ref,
+as are two symbolic-refs pointing to the same ref. Refnames
+may be abbreviated."
+ (let ((a (magit-ref-fullname a))
+ (b (magit-ref-fullname b)))
+ (and a b (equal a b))))
+
+(defun magit-ref-eq (a b)
+ "Return t if the refnames A and B are `eq'.
+A symbolic-ref is `eq' to itself, but not to the ref it points
+to, or to some other symbolic-ref that points to the same ref."
+ (let ((symbolic-a (magit-symbolic-ref-p a))
+ (symbolic-b (magit-symbolic-ref-p b)))
+ (or (and symbolic-a
+ symbolic-b
+ (equal a b))
+ (and (not symbolic-a)
+ (not symbolic-b)
+ (magit-ref-equal a b)))))
+
+(defun magit-headish ()
+ "Return the `HEAD' or if that doesn't exist the hash of the empty tree."
+ (if (magit-no-commit-p)
+ (magit-git-string "mktree")
+ "HEAD"))
+
+(defun magit-branch-at-point ()
+ (magit-section-case
+ (branch (oref it value))
+ (commit (or (magit--painted-branch-at-point)
+ (magit-name-branch (oref it value))))))
+
+(defun magit--painted-branch-at-point (&optional type)
+ (or (and (not (eq type 'remote))
+ (memq (get-text-property (magit-point) 'font-lock-face)
+ (list 'magit-branch-local
+ 'magit-branch-current))
+ (and-let* ((branch (magit-thing-at-point 'git-revision t)))
+ (cdr (magit-split-branch-name branch))))
+ (and (not (eq type 'local))
+ (memq (get-text-property (magit-point) 'font-lock-face)
+ (list 'magit-branch-remote
+ 'magit-branch-remote-head))
+ (thing-at-point 'git-revision t))))
+
+(defun magit-local-branch-at-point ()
+ (magit-section-case
+ (branch (let ((branch (magit-ref-maybe-qualify (oref it value))))
+ (when (member branch (magit-list-local-branch-names))
+ branch)))
+ (commit (or (magit--painted-branch-at-point 'local)
+ (magit-name-local-branch (oref it value))))))
+
+(defun magit-remote-branch-at-point ()
+ (magit-section-case
+ (branch (let ((branch (oref it value)))
+ (when (member branch (magit-list-remote-branch-names))
+ branch)))
+ (commit (or (magit--painted-branch-at-point 'remote)
+ (magit-name-remote-branch (oref it value))))))
+
+(defun magit-commit-at-point ()
+ (or (magit-section-value-if 'commit)
+ (magit-thing-at-point 'git-revision t)
+ (and-let* ((chunk (magit-current-blame-chunk 'addition t)))
+ (oref chunk orig-rev))
+ (and (derived-mode-p 'magit-stash-mode
+ 'magit-merge-preview-mode
+ 'magit-revision-mode)
+ magit-buffer-revision)))
+
+(defun magit-branch-or-commit-at-point ()
+ (or (magit-section-case
+ (branch (magit-ref-maybe-qualify (oref it value)))
+ (commit (or (magit--painted-branch-at-point)
+ (let ((rev (oref it value)))
+ (or (magit-name-branch rev) rev))))
+ (tag (magit-ref-maybe-qualify (oref it value) "tags/"))
+ (pullreq (or (and (fboundp 'forge--pullreq-branch)
+ (magit-branch-p
+ (forge--pullreq-branch (oref it value))))
+ (magit-ref-p (format "refs/pullreqs/%s"
+ (oref (oref it value) number))))))
+ (magit-thing-at-point 'git-revision t)
+ (and-let* ((chunk (magit-current-blame-chunk 'addition t)))
+ (oref chunk orig-rev))
+ (and magit-buffer-file-name
+ magit-buffer-refname)
+ (and (derived-mode-p 'magit-stash-mode
+ 'magit-merge-preview-mode
+ 'magit-revision-mode)
+ magit-buffer-revision)))
+
+(defun magit-tag-at-point ()
+ (magit-section-case
+ (tag (oref it value))
+ (commit (magit-name-tag (oref it value)))))
+
+(defun magit-stash-at-point ()
+ (magit-section-value-if 'stash))
+
+(defun magit-remote-at-point ()
+ (magit-section-case
+ (remote (oref it value))
+ ([branch remote] (magit-section-parent-value it))))
+
+(defun magit-module-at-point (&optional predicate)
+ (when (magit-section-match 'magit-module-section)
+ (let ((module (oref (magit-current-section) value)))
+ (and (or (not predicate)
+ (funcall predicate module))
+ module))))
+
+(defun magit-get-current-branch ()
+ "Return the refname of the currently checked out branch.
+Return nil if no branch is currently checked out."
+ (magit-git-string "symbolic-ref" "--short" "HEAD"))
+
+(defvar magit-get-previous-branch-timeout 0.5
+ "Maximum time to spend in `magit-get-previous-branch'.
+Given as a number of seconds.")
+
+(defun magit-get-previous-branch ()
+ "Return the refname of the previously checked out branch.
+Return nil if no branch can be found in the `HEAD' reflog
+which is different from the current branch and still exists.
+The amount of time spent searching is limited by
+`magit-get-previous-branch-timeout'."
+ (let ((t0 (float-time))
+ (current (magit-get-current-branch))
+ (i 1) prev)
+ (while (if (> (- (float-time) t0) magit-get-previous-branch-timeout)
+ (setq prev nil) ;; Timed out.
+ (and (setq prev (magit-rev-verify (format "@{-%i}" i)))
+ (or (not (setq prev (magit-rev-branch prev)))
+ (equal prev current))))
+ (cl-incf i))
+ prev))
+
+(defun magit-set-upstream-branch (branch upstream)
+ "Set UPSTREAM as the upstream of BRANCH.
+If UPSTREAM is nil, then unset BRANCH's upstream.
+Otherwise UPSTREAM has to be an existing branch."
+ (if upstream
+ (magit-call-git "branch" "--set-upstream-to" upstream branch)
+ (magit-call-git "branch" "--unset-upstream" branch)))
+
+(defun magit-get-upstream-ref (&optional branch)
+ "Return the upstream branch of BRANCH as a fully qualified ref.
+It BRANCH is nil, then return the upstream of the current branch,
+if any, nil otherwise. If the upstream is not configured, the
+configured remote is an url, or the named branch does not exist,
+then return nil. I.e. return an existing local or
+remote-tracking branch ref."
+ (and-let* ((branch (or branch (magit-get-current-branch))))
+ (magit-ref-fullname (concat branch "@{upstream}"))))
+
+(defun magit-get-upstream-branch (&optional branch)
+ "Return the name of the upstream branch of BRANCH.
+It BRANCH is nil, then return the upstream of the current branch
+if any, nil otherwise. If the upstream is not configured, the
+configured remote is an url, or the named branch does not exist,
+then return nil. I.e. return the name of an existing local or
+remote-tracking branch. The returned string is colorized
+according to the branch type."
+ (magit--with-refresh-cache
+ (list default-directory 'magit-get-upstream-branch branch)
+ (and-let* ((branch (or branch (magit-get-current-branch)))
+ (upstream (magit-ref-abbrev (concat branch "@{upstream}"))))
+ (magit--propertize-face
+ upstream (if (equal (magit-get "branch" branch "remote") ".")
+ 'magit-branch-local
+ 'magit-branch-remote)))))
+
+(defun magit-get-indirect-upstream-branch (branch &optional force)
+ (let ((remote (magit-get "branch" branch "remote")))
+ (and remote (not (equal remote "."))
+ ;; The user has opted in...
+ (or force
+ (--some (if (magit-git-success "check-ref-format" "--branch" it)
+ (equal it branch)
+ (string-match-p it branch))
+ magit-branch-prefer-remote-upstream))
+ ;; and local BRANCH tracks a remote branch...
+ (let ((upstream (magit-get-upstream-branch branch)))
+ ;; whose upstream...
+ (and upstream
+ ;; has the same name as BRANCH...
+ (equal (substring upstream (1+ (length remote))) branch)
+ ;; and can be fast-forwarded to BRANCH.
+ (magit-rev-ancestor-p upstream branch)
+ upstream)))))
+
+(defun magit-get-upstream-remote (&optional branch allow-unnamed)
+ (and-let* ((branch (or branch (magit-get-current-branch)))
+ (remote (magit-get "branch" branch "remote")))
+ (and (not (equal remote "."))
+ (cond ((member remote (magit-list-remotes))
+ (magit--propertize-face remote 'magit-branch-remote))
+ ((and allow-unnamed
+ (string-match-p "\\(\\`.\\{0,2\\}/\\|[:@]\\)" remote))
+ (magit--propertize-face remote 'bold))))))
+
+(defun magit-get-unnamed-upstream (&optional branch)
+ (and-let* ((branch (or branch (magit-get-current-branch)))
+ (remote (magit-get "branch" branch "remote"))
+ (merge (magit-get "branch" branch "merge")))
+ (and (magit--unnamed-upstream-p remote merge)
+ (list (magit--propertize-face remote 'bold)
+ (magit--propertize-face merge 'magit-branch-remote)))))
+
+(defun magit--unnamed-upstream-p (remote merge)
+ (and remote (string-match-p "\\(\\`\\.\\{0,2\\}/\\|[:@]\\)" remote)
+ merge (string-prefix-p "refs/" merge)))
+
+(defun magit--valid-upstream-p (remote merge)
+ (and (or (equal remote ".")
+ (member remote (magit-list-remotes)))
+ (string-prefix-p "refs/" merge)))
+
+(defun magit-get-current-remote (&optional allow-unnamed)
+ (or (magit-get-upstream-remote nil allow-unnamed)
+ (and-let* ((remotes (magit-list-remotes))
+ (remote (if (length= remotes 1)
+ (car remotes)
+ (magit-primary-remote))))
+ (magit--propertize-face remote 'magit-branch-remote))))
+
+(defun magit-get-push-remote (&optional branch)
+ (and-let* ((remote
+ (or (and (or branch (setq branch (magit-get-current-branch)))
+ (magit-get "branch" branch "pushRemote"))
+ (magit-get "remote.pushDefault"))))
+ (magit--propertize-face remote 'magit-branch-remote)))
+
+(defun magit-get-push-branch (&optional branch verify)
+ (magit--with-refresh-cache
+ (list default-directory 'magit-get-push-branch branch verify)
+ (and-let* ((branch (or branch (setq branch (magit-get-current-branch))))
+ (remote (magit-get-push-remote branch))
+ (target (concat remote "/" branch)))
+ (and (or (not verify)
+ (magit-rev-verify target))
+ (magit--propertize-face target 'magit-branch-remote)))))
+
+(defun magit-get-@{push}-branch (&optional branch)
+ (let ((ref (magit-rev-parse "--symbolic-full-name"
+ (concat branch "@{push}"))))
+ (when (and ref (string-prefix-p "refs/remotes/" ref))
+ (substring ref 13))))
+
+(defun magit-get-remote (&optional branch)
+ (when (or branch (setq branch (magit-get-current-branch)))
+ (let ((remote (magit-get "branch" branch "remote")))
+ (unless (equal remote ".")
+ remote))))
+
+(defun magit-get-some-remote (&optional branch)
+ (or (magit-get-remote branch)
+ (and-let* ((main (magit-main-branch)))
+ (magit-get-remote main))
+ (magit-primary-remote)
+ (car (magit-list-remotes))))
+
+(defvar magit-primary-remote-names
+ '("upstream" "origin"))
+
+(defun magit-primary-remote ()
+ "Return the primary remote.
+
+The primary remote is the remote that tracks the repository that
+other repositories are forked from. It often is called \"origin\"
+but because many people name their own fork \"origin\", using that
+term would be ambiguous. Likewise we avoid the term \"upstream\"
+because a branch's @{upstream} branch may be a local branch or a
+branch from a remote other than the primary remote.
+
+If a remote exists whose name matches `magit.primaryRemote', then
+that is considered the primary remote. If no remote by that name
+exists, then remotes in `magit-primary-remote-names' are tried in
+order and the first remote from that list that actually exists in
+the current repository is considered its primary remote."
+ (let ((remotes (magit-list-remotes)))
+ (seq-find (lambda (name)
+ (member name remotes))
+ (delete-dups
+ (delq nil
+ (cons (magit-get "magit.primaryRemote")
+ magit-primary-remote-names))))))
+
+(defun magit-branch-merged-p (branch &optional target)
+ "Return non-nil if BRANCH is merged into its upstream and TARGET.
+
+TARGET defaults to the current branch. If `HEAD' is detached and
+TARGET is nil, then always return nil. As a special case, if
+TARGET is t, then return non-nil if BRANCH is merged into any one
+of the other local branches.
+
+If, and only if, BRANCH has an upstream, then only return non-nil
+if BRANCH is merged into both TARGET (as described above) as well
+as into its upstream."
+ (and (--if-let (and (magit-branch-p branch)
+ (magit-get-upstream-branch branch))
+ (magit-git-success "merge-base" "--is-ancestor" branch it)
+ t)
+ (if (eq target t)
+ (delete (magit-name-local-branch branch)
+ (magit-list-containing-branches branch))
+ (and-let* ((target (or target (magit-get-current-branch))))
+ (magit-git-success "merge-base" "--is-ancestor" branch target)))))
+
+(defun magit-get-tracked (refname)
+ "Return the remote branch tracked by the remote-tracking branch REFNAME.
+The returned value has the form (REMOTE . REF), where REMOTE is
+the name of a remote and REF is the ref local to the remote."
+ (and-let* ((ref (magit-ref-fullname refname)))
+ (save-match-data
+ (seq-some (lambda (line)
+ (and (string-match "\
+\\`remote\\.\\([^.]+\\)\\.fetch=\\+?\\([^:]+\\):\\(.+\\)" line)
+ (let ((rmt (match-string 1 line))
+ (src (match-string 2 line))
+ (dst (match-string 3 line)))
+ (and (string-match (format "\\`%s\\'"
+ (string-replace
+ "*" "\\(.+\\)" dst))
+ ref)
+ (cons rmt (string-replace
+ "*" (match-string 1 ref) src))))))
+ (magit-git-lines "config" "--local" "--list")))))
+
+(defun magit-split-branch-name (branch)
+ (cond ((member branch (magit-list-local-branch-names))
+ (cons "." branch))
+ ((string-match "/" branch)
+ (or (seq-some (lambda (remote)
+ (and (string-match
+ (format "\\`\\(%s\\)/\\(.+\\)\\'" remote)
+ branch)
+ (cons (match-string 1 branch)
+ (match-string 2 branch))))
+ (magit-list-remotes))
+ (error "Invalid branch name %s" branch)))))
+
+(defun magit-get-current-tag (&optional rev with-distance)
+ "Return the closest tag reachable from REV.
+
+If optional REV is nil, then default to `HEAD'.
+If optional WITH-DISTANCE is non-nil then return (TAG COMMITS),
+if it is `dirty' return (TAG COMMIT DIRTY). COMMITS is the number
+of commits in `HEAD' but not in TAG and DIRTY is t if there are
+uncommitted changes, nil otherwise."
+ (and-let* ((str (magit-git-str "describe" "--long" "--tags"
+ (and (eq with-distance 'dirty) "--dirty")
+ rev)))
+ (save-match-data
+ (string-match
+ "\\(.+\\)-\\(?:0[0-9]*\\|\\([0-9]+\\)\\)-g[0-9a-z]+\\(-dirty\\)?$" str)
+ (if with-distance
+ `(,(match-string 1 str)
+ ,(string-to-number (or (match-string 2 str) "0"))
+ ,@(and (match-string 3 str) (list t)))
+ (match-string 1 str)))))
+
+(defun magit-get-next-tag (&optional rev with-distance)
+ "Return the closest tag from which REV is reachable.
+
+If optional REV is nil, then default to `HEAD'.
+If no such tag can be found or if the distance is 0 (in which
+case it is the current tag, not the next), return nil instead.
+If optional WITH-DISTANCE is non-nil, then return (TAG COMMITS)
+where COMMITS is the number of commits in TAG but not in REV."
+ (and-let* ((str (magit-git-str "describe" "--contains" (or rev "HEAD"))))
+ (save-match-data
+ (when (string-match "^[^^~]+" str)
+ (setq str (match-string 0 str))
+ (unless (equal str (magit-get-current-tag rev))
+ (if with-distance
+ (list str (car (magit-rev-diff-count str rev)))
+ str))))))
+
+(defun magit-list-refs (&optional namespaces format sortby)
+ "Return list of references.
+
+When NAMESPACES is non-nil, list refs from these namespaces
+rather than those from `magit-list-refs-namespaces'.
+
+FORMAT is passed to the `--format' flag of `git for-each-ref'
+and defaults to \"%(refname)\". If the format is \"%(refname)\"
+or \"%(refname:short)\", then drop the symbolic-ref `HEAD'.
+
+SORTBY is a key or list of keys to pass to the `--sort' flag of
+`git for-each-ref'. When nil, use `magit-list-refs-sortby'"
+ (unless format
+ (setq format "%(refname)"))
+ (let ((refs (magit-git-lines "for-each-ref"
+ (concat "--format=" format)
+ (--map (concat "--sort=" it)
+ (pcase (or sortby magit-list-refs-sortby)
+ ((and val (pred stringp)) (list val))
+ ((and val (pred listp)) val)))
+ (or namespaces magit-list-refs-namespaces))))
+ (if (member format '("%(refname)" "%(refname:short)"))
+ (let ((case-fold-search nil))
+ (--remove (string-match-p "\\(\\`\\|/\\)HEAD\\'" it)
+ refs))
+ refs)))
+
+(defun magit-list-branches ()
+ (magit-list-refs (list "refs/heads" "refs/remotes")))
+
+(defun magit-list-local-branches ()
+ (magit-list-refs "refs/heads"))
+
+(defun magit-list-remote-branches (&optional remote)
+ (magit-list-refs (concat "refs/remotes/" remote)))
+
+(defun magit-list-related-branches (relation &optional commit &rest args)
+ (--remove (string-match-p "\\(\\`(HEAD\\|HEAD -> \\)" it)
+ (--map (substring it 2)
+ (magit-git-lines "branch" args relation commit))))
+
+(defun magit-list-containing-branches (&optional commit &rest args)
+ (magit-list-related-branches "--contains" commit args))
+
+(defun magit-list-publishing-branches (&optional commit)
+ (--filter (magit-rev-ancestor-p (or commit "HEAD") it)
+ magit-published-branches))
+
+(defun magit-list-merged-branches (&optional commit &rest args)
+ (magit-list-related-branches "--merged" commit args))
+
+(defun magit-list-unmerged-branches (&optional commit &rest args)
+ (magit-list-related-branches "--no-merged" commit args))
+
+(defun magit-list-unmerged-to-upstream-branches ()
+ (--filter (and-let* ((upstream (magit-get-upstream-branch it)))
+ (member it (magit-list-unmerged-branches upstream)))
+ (magit-list-local-branch-names)))
+
+(defun magit-list-branches-pointing-at (commit)
+ (let ((re (format "\\`%s refs/\\(heads\\|remotes\\)/\\(.*\\)\\'"
+ (magit-rev-verify commit))))
+ (--keep (and (string-match re it)
+ (let ((name (match-string 2 it)))
+ (and (not (string-suffix-p "HEAD" name))
+ name)))
+ (magit-git-lines "show-ref"))))
+
+(defun magit-list-refnames (&optional namespaces include-special)
+ (nconc (magit-list-refs namespaces "%(refname:short)")
+ (and include-special
+ (magit-list-special-refnames))))
+
+(defvar magit-special-refnames
+ '("HEAD" "ORIG_HEAD" "FETCH_HEAD" "MERGE_HEAD" "CHERRY_PICK_HEAD"))
+
+(defun magit-list-special-refnames ()
+ (let ((gitdir (magit-gitdir)))
+ (cl-mapcan (lambda (name)
+ (and (file-exists-p (expand-file-name name gitdir))
+ (list name)))
+ magit-special-refnames)))
+
+(defun magit-list-branch-names ()
+ (magit-list-refnames (list "refs/heads" "refs/remotes")))
+
+(defun magit-list-local-branch-names ()
+ (magit-list-refnames "refs/heads"))
+
+(defun magit-list-remote-branch-names (&optional remote relative)
+ (if (and remote relative)
+ (let ((regexp (format "^refs/remotes/%s/\\(.+\\)" remote)))
+ (--mapcat (when (string-match regexp it)
+ (list (match-string 1 it)))
+ (magit-list-remote-branches remote)))
+ (magit-list-refnames (concat "refs/remotes/" remote))))
+
+(defun magit-format-refs (format &rest args)
+ (let ((lines (magit-git-lines
+ "for-each-ref" (concat "--format=" format)
+ (or args (list "refs/heads" "refs/remotes" "refs/tags")))))
+ (if (string-search "\f" format)
+ (--map (split-string it "\f") lines)
+ lines)))
+
+(defun magit-list-remotes ()
+ (magit-git-lines "remote"))
+
+(defun magit-list-tags ()
+ (magit-git-lines "tag"))
+
+(defun magit-list-stashes (&optional format)
+ (magit-git-lines "stash" "list" (concat "--format=" (or format "%gd"))))
+
+(defun magit-list-active-notes-refs ()
+ "Return notes refs according to `core.notesRef' and `notes.displayRef'."
+ (magit-git-lines "for-each-ref" "--format=%(refname)"
+ (or (magit-get "core.notesRef") "refs/notes/commits")
+ (magit-get-all "notes.displayRef")))
+
+(defun magit-list-notes-refnames ()
+ (--map (substring it 6) (magit-list-refnames "refs/notes")))
+
+(defun magit-remote-list-tags (remote)
+ (--keep (and (not (string-suffix-p "^{}" it))
+ (substring it 51))
+ (magit-git-lines "ls-remote" "--tags" remote)))
+
+(defun magit-remote-list-branches (remote)
+ (--keep (and (not (string-suffix-p "^{}" it))
+ (substring it 52))
+ (magit-git-lines "ls-remote" "--heads" remote)))
+
+(defun magit-remote-list-refs (remote)
+ (--keep (and (not (string-suffix-p "^{}" it))
+ (substring it 41))
+ (magit-git-lines "ls-remote" remote)))
+
+(defun magit-list-modified-modules ()
+ (--keep (and (string-match "\\`\\+\\([^ ]+\\) \\(.+\\) (.+)\\'" it)
+ (match-string 2 it))
+ (magit-git-lines "submodule" "status")))
+
+(defun magit-list-module-paths ()
+ (--mapcat (and (string-match "^160000 [0-9a-z]\\{40,\\} 0\t\\(.+\\)$" it)
+ (list (match-string 1 it)))
+ (magit-git-items "ls-files" "-z" "--stage")))
+
+(defun magit-list-module-names ()
+ (mapcar #'magit-get-submodule-name (magit-list-module-paths)))
+
+(defun magit-get-submodule-name (path)
+ "Return the name of the submodule at PATH.
+PATH has to be relative to the super-repository."
+ (magit-git-string "submodule--helper" "name" path))
+
+(defun magit-list-worktrees ()
+ (let ((remote (file-remote-p default-directory))
+ worktrees worktree)
+ (dolist (line (let ((magit-git-global-arguments
+ ;; KLUDGE At least in v2.8.3 this triggers a segfault.
+ (remove "--no-pager" magit-git-global-arguments)))
+ (magit-git-lines "worktree" "list" "--porcelain")))
+ (cond ((string-prefix-p "worktree" line)
+ (let ((path (substring line 9)))
+ (when remote
+ (setq path (concat remote path)))
+ ;; If the git directory is separate from the main
+ ;; worktree, then "git worktree" returns the git
+ ;; directory instead of the worktree, which isn't
+ ;; what it is supposed to do and not what we want.
+ (setq path (magit-toplevel path))
+ (setq worktree (list path nil nil nil))
+ (push worktree worktrees)))
+ ((string-equal line "bare")
+ (let* ((default-directory (car worktree))
+ (wt (and (not (magit-get-boolean "core.bare"))
+ (magit-get "core.worktree"))))
+ (if (and wt (file-exists-p (expand-file-name wt)))
+ (progn (setf (nth 0 worktree) (expand-file-name wt))
+ (setf (nth 2 worktree) (magit-rev-parse "HEAD"))
+ (setf (nth 3 worktree) (magit-get-current-branch)))
+ (setf (nth 1 worktree) t))))
+ ((string-prefix-p "HEAD" line)
+ (setf (nth 2 worktree) (substring line 5)))
+ ((string-prefix-p "branch" line)
+ (setf (nth 3 worktree) (substring line 18)))
+ ((string-equal line "detached"))))
+ (nreverse worktrees)))
+
+(defun magit-symbolic-ref-p (name)
+ (magit-git-success "symbolic-ref" "--quiet" name))
+
+(defun magit-ref-p (rev)
+ (or (car (member rev (magit-list-refs "refs/")))
+ (car (member rev (magit-list-refnames "refs/")))))
+
+(defun magit-branch-p (rev)
+ (or (car (member rev (magit-list-branches)))
+ (car (member rev (magit-list-branch-names)))))
+
+(defun magit-local-branch-p (rev)
+ (or (car (member rev (magit-list-local-branches)))
+ (car (member rev (magit-list-local-branch-names)))))
+
+(defun magit-remote-branch-p (rev)
+ (or (car (member rev (magit-list-remote-branches)))
+ (car (member rev (magit-list-remote-branch-names)))))
+
+(defun magit-branch-set-face (branch)
+ (magit--propertize-face branch (if (magit-local-branch-p branch)
+ 'magit-branch-local
+ 'magit-branch-remote)))
+
+(defun magit-tag-p (rev)
+ (car (member rev (magit-list-tags))))
+
+(defun magit-remote-p (string)
+ (car (member string (magit-list-remotes))))
+
+(defvar magit-main-branch-names
+ ;; These are the names that Git suggests
+ ;; if `init.defaultBranch' is undefined.
+ '("main" "master" "trunk" "development"))
+
+(defun magit-main-branch ()
+ "Return the main branch.
+
+If a branch exists whose name matches `init.defaultBranch', then
+that is considered the main branch. If no branch by that name
+exists, then the branch names in `magit-main-branch-names' are
+tried in order. The first branch from that list that actually
+exists in the current repository is considered its main branch."
+ (let ((branches (magit-list-local-branch-names)))
+ (seq-find (lambda (name)
+ (member name branches))
+ (delete-dups
+ (delq nil
+ (cons (magit-get "init.defaultBranch")
+ magit-main-branch-names))))))
+
+(defun magit-rev-diff-count (a b)
+ "Return the commits in A but not B and vice versa.
+Return a list of two integers: (A>B B>A)."
+ (mapcar #'string-to-number
+ (split-string (magit-git-string "rev-list"
+ "--count" "--left-right"
+ (concat a "..." b))
+ "\t")))
+
+(defun magit-abbrev-length ()
+ (let ((abbrev (magit-get "core.abbrev")))
+ (if (and abbrev (not (equal abbrev "auto")))
+ (string-to-number abbrev)
+ ;; Guess the length git will be using based on an example
+ ;; abbreviation. Actually HEAD's abbreviation might be an
+ ;; outlier, so use the shorter of the abbreviations for two
+ ;; commits. See #3034.
+ (if-let ((head (magit-rev-parse "--short" "HEAD"))
+ (head-len (length head)))
+ (min head-len
+ (--if-let (magit-rev-parse "--short" "HEAD~")
+ (length it)
+ head-len))
+ ;; We're on an unborn branch, but perhaps the repository has
+ ;; other commits. See #4123.
+ (if-let ((commits (magit-git-lines "rev-list" "-n2" "--all"
+ "--abbrev-commit")))
+ (apply #'min (mapcar #'length commits))
+ ;; A commit does not exist. Fall back to the default of 7.
+ 7)))))
+
+(defun magit-abbrev-arg (&optional arg)
+ (format "--%s=%d" (or arg "abbrev") (magit-abbrev-length)))
+
+(defun magit-rev-abbrev (rev)
+ (magit-rev-parse (magit-abbrev-arg "short") rev))
+
+(defun magit-commit-children (commit &optional args)
+ (mapcar #'car
+ (--filter (member commit (cdr it))
+ (--map (split-string it " ")
+ (magit-git-lines
+ "log" "--format=%H %P"
+ (or args (list "--branches" "--tags" "--remotes"))
+ "--not" commit)))))
+
+(defun magit-commit-parents (commit)
+ (and-let* ((str (magit-git-string "rev-list" "-1" "--parents" commit)))
+ (cdr (split-string str))))
+
+(defun magit-patch-id (rev)
+ (magit--with-connection-local-variables
+ (magit--with-temp-process-buffer
+ (magit-process-file
+ shell-file-name nil '(t nil) nil shell-command-switch
+ (let ((exec (shell-quote-argument (magit-git-executable))))
+ (format "%s diff-tree -u %s | %s patch-id" exec rev exec)))
+ (car (split-string (buffer-string))))))
+
+(defun magit-rev-format (format &optional rev args)
+ (let ((str (magit-git-string "show" "--no-patch"
+ (concat "--format=" format) args
+ (if rev (magit--rev-dereference rev) "HEAD")
+ "--")))
+ (unless (string-equal str "")
+ str)))
+
+(defun magit-rev-insert-format (format &optional rev args)
+ (magit-git-insert "show" "--no-patch"
+ (concat "--format=" format) args
+ (if rev (magit--rev-dereference rev) "HEAD")
+ "--"))
+
+(defun magit-format-rev-summary (rev)
+ (when-let* ((str (magit-rev-format "%h %s" rev))) ;debbugs#31840
+ (magit--put-face 0 (string-match " " str) 'magit-hash str)
+ str))
+
+(defvar magit-ref-namespaces
+ '(("\\`HEAD\\'" . magit-head)
+ ("\\`refs/tags/\\(.+\\)" . magit-tag)
+ ("\\`refs/heads/\\(.+\\)" . magit-branch-local)
+ ("\\`refs/remotes/\\(.+\\)" . magit-branch-remote)
+ ("\\`refs/bisect/\\(bad\\)" . magit-bisect-bad)
+ ("\\`refs/bisect/\\(skip.*\\)" . magit-bisect-skip)
+ ("\\`refs/bisect/\\(good.*\\)" . magit-bisect-good)
+ ("\\`refs/stash$" . magit-refname-stash)
+ ("\\`refs/wip/\\(.+\\)" . magit-refname-wip)
+ ("\\`refs/pullreqs/\\(.+\\)" . magit-refname-pullreq)
+ ("\\`\\(bad\\):" . magit-bisect-bad)
+ ("\\`\\(skip\\):" . magit-bisect-skip)
+ ("\\`\\(good\\):" . magit-bisect-good)
+ ("\\`\\(.+\\)" . magit-refname))
+ "How refs are formatted for display.
+
+Each entry controls how a certain type of ref is displayed, and
+has the form (REGEXP . FACE). REGEXP is a regular expression
+used to match full refs. The first entry whose REGEXP matches
+the reference is used.
+
+In log and revision buffers the first regexp submatch becomes the
+\"label\" that represents the ref and is propertized with FONT.
+In refs buffers the displayed text is controlled by other means
+and this option only controls what face is used.")
+
+(defun magit-format-ref-labels (string)
+ (save-match-data
+ (let ((regexp "\\(, \\|tag: \\|HEAD -> \\)")
+ names)
+ (if (and (derived-mode-p 'magit-log-mode)
+ (member "--simplify-by-decoration" magit-buffer-log-args))
+ (let ((branches (magit-list-local-branch-names))
+ (re (format "^%s/.+" (regexp-opt (magit-list-remotes)))))
+ (setq names
+ (--map (cond ((string-equal it "HEAD") it)
+ ((string-prefix-p "refs/" it) it)
+ ((member it branches) (concat "refs/heads/" it))
+ ((string-match re it) (concat "refs/remotes/" it))
+ (t (concat "refs/" it)))
+ (split-string
+ (string-replace "tag: " "refs/tags/" string)
+ regexp t))))
+ (setq names (split-string string regexp t)))
+ (let (state head upstream tags branches remotes other combined)
+ (dolist (ref names)
+ (let* ((face (cdr (--first (string-match (car it) ref)
+ magit-ref-namespaces)))
+ (name (magit--propertize-face
+ (or (match-string 1 ref) ref) face)))
+ (cl-case face
+ ((magit-bisect-bad magit-bisect-skip magit-bisect-good)
+ (setq state name))
+ (magit-head
+ (setq head (magit--propertize-face "@" 'magit-head)))
+ (magit-tag (push name tags))
+ (magit-branch-local (push name branches))
+ (magit-branch-remote (push name remotes))
+ (t (push name other)))))
+ (setq remotes
+ (-keep
+ (lambda (name)
+ (if (string-match "\\`\\([^/]*\\)/\\(.*\\)\\'" name)
+ (let ((r (match-string 1 name))
+ (b (match-string 2 name)))
+ (and (not (equal b "HEAD"))
+ (if (equal (concat "refs/remotes/" name)
+ (magit-git-string
+ "symbolic-ref"
+ (format "refs/remotes/%s/HEAD" r)))
+ (magit--propertize-face
+ name 'magit-branch-remote-head)
+ name)))
+ name))
+ remotes))
+ (let* ((current (magit-get-current-branch))
+ (target (magit-get-upstream-branch current)))
+ (dolist (name branches)
+ (let ((push (car (member (magit-get-push-branch name) remotes))))
+ (when push
+ (setq remotes (delete push remotes))
+ (string-match "^[^/]*/" push)
+ (setq push (substring push 0 (match-end 0))))
+ (cond
+ ((equal name current)
+ (setq head
+ (concat push
+ (magit--propertize-face
+ name 'magit-branch-current))))
+ ((equal name target)
+ (setq upstream
+ (concat push
+ (magit--propertize-face
+ name '(magit-branch-upstream
+ magit-branch-local)))))
+ (t
+ (push (concat push name) combined)))))
+ (when (and target (not upstream))
+ (if (member target remotes)
+ (progn
+ (magit--add-face-text-property
+ 0 (length target) 'magit-branch-upstream nil target)
+ (setq upstream target)
+ (setq remotes (delete target remotes)))
+ (when-let ((target (car (member target combined))))
+ (magit--add-face-text-property
+ 0 (length target) 'magit-branch-upstream nil target)
+ (setq upstream target)
+ (setq combined (delete target combined))))))
+ (mapconcat #'identity
+ (flatten-tree `(,state
+ ,head
+ ,upstream
+ ,@(nreverse tags)
+ ,@(nreverse combined)
+ ,@(nreverse remotes)
+ ,@other))
+ " ")))))
+
+(defun magit-object-type (object)
+ (magit-git-string "cat-file" "-t" object))
+
+(defmacro magit-with-blob (commit file &rest body)
+ (declare (indent 2)
+ (debug (form form body)))
+ `(magit--with-temp-process-buffer
+ (let ((buffer-file-name ,file))
+ (save-excursion
+ (magit-git-insert "cat-file" "-p"
+ (concat ,commit ":" buffer-file-name)))
+ (decode-coding-inserted-region
+ (point-min) (point-max) buffer-file-name t nil nil t)
+ ,@body)))
+
+(defmacro magit-with-temp-index (tree arg &rest body)
+ (declare (indent 2) (debug (form form body)))
+ (let ((file (cl-gensym "file")))
+ `(let ((magit--refresh-cache nil)
+ (,file (magit-convert-filename-for-git
+ (make-temp-name (magit-git-dir "index.magit.")))))
+ (unwind-protect
+ (magit-with-toplevel
+ (--when-let ,tree
+ (or (magit-git-success "read-tree" ,arg it
+ (concat "--index-output=" ,file))
+ (error "Cannot read tree %s" it)))
+ (if (file-remote-p default-directory)
+ (let ((magit-tramp-process-environment
+ (cons (concat "GIT_INDEX_FILE=" ,file)
+ magit-tramp-process-environment)))
+ ,@body)
+ (with-environment-variables (("GIT_INDEX_FILE" ,file))
+ ,@body)))
+ (ignore-errors
+ (delete-file (concat (file-remote-p default-directory) ,file)))))))
+
+(defun magit-commit-tree (message &optional tree &rest parents)
+ (magit-git-string "commit-tree" "--no-gpg-sign" "-m" message
+ (--mapcat (list "-p" it) (delq nil parents))
+ (or tree
+ (magit-git-string "write-tree")
+ (error "Cannot write tree"))))
+
+(defun magit-commit-worktree (message &optional arg &rest other-parents)
+ (magit-with-temp-index "HEAD" arg
+ (and (magit-update-files (magit-unstaged-files))
+ (apply #'magit-commit-tree message nil "HEAD" other-parents))))
+
+(defun magit-update-files (files)
+ (magit-git-success "update-index" "--add" "--remove" "--" files))
+
+(defun magit-update-ref (ref message rev &optional stashish)
+ (let ((magit--refresh-cache nil))
+ (or (if (magit-git-version>= "2.6.0")
+ (zerop (magit-call-git "update-ref" "--create-reflog"
+ "-m" message ref rev
+ (or (magit-rev-verify ref) "")))
+ ;; `--create-reflog' didn't exist before v2.6.0
+ (let ((oldrev (magit-rev-verify ref))
+ (logfile (magit-git-dir (concat "logs/" ref))))
+ (unless (file-exists-p logfile)
+ (when oldrev
+ (magit-git-success "update-ref" "-d" ref oldrev))
+ (make-directory (file-name-directory logfile) t)
+ (with-temp-file logfile)
+ (when (and oldrev (not stashish))
+ (magit-git-success "update-ref" "-m" "enable reflog"
+ ref oldrev ""))))
+ (magit-git-success "update-ref" "-m" message ref rev
+ (or (magit-rev-verify ref) "")))
+ (error "Cannot update %s with %s" ref rev))))
+
+(defconst magit-range-re
+ (concat "\\`\\([^ \t]*[^.]\\)?" ; revA
+ "\\(\\.\\.\\.?\\)" ; range marker
+ "\\([^.][^ \t]*\\)?\\'")) ; revB
+
+(defun magit-split-range (range)
+ (and (string-match magit-range-re range)
+ (let ((beg (or (match-string 1 range) "HEAD"))
+ (end (or (match-string 3 range) "HEAD")))
+ (cons (if (string-equal (match-string 2 range) "...")
+ (magit-git-string "merge-base" beg end)
+ beg)
+ end))))
+
+(defun magit-hash-range (range)
+ (if (string-match magit-range-re range)
+ (concat (magit-rev-hash (match-string 1 range))
+ (match-string 2 range)
+ (magit-rev-hash (match-string 3 range)))
+ (magit-rev-hash range)))
+
+(put 'git-revision 'thing-at-point #'magit-thingatpt--git-revision)
+(defun magit-thingatpt--git-revision ()
+ (and-let* ((bounds
+ (let ((c "\s\n\t~^:?*[\\"))
+ (cl-letf (((get 'git-revision 'beginning-op)
+ (lambda ()
+ (if (re-search-backward (format "[%s]" c) nil t)
+ (forward-char)
+ (goto-char (point-min)))))
+ ((get 'git-revision 'end-op)
+ (lambda ()
+ (re-search-forward (format "\\=[^%s]*" c) nil t))))
+ (bounds-of-thing-at-point 'git-revision))))
+ (string (buffer-substring-no-properties (car bounds) (cdr bounds))))
+ (and (or (and (>= (length string) 7)
+ (string-match-p "[a-z]" string)
+ (magit-commit-p string))
+ (magit-ref-p string))
+ string)))
+
+;;; Completion
+
+(defvar magit-revision-history nil)
+
+(defun magit--minibuf-default-add-commit ()
+ (let ((fn minibuffer-default-add-function))
+ (lambda ()
+ (if-let ((commit (with-selected-window (minibuffer-selected-window)
+ (magit-commit-at-point))))
+ (cons commit (delete commit (funcall fn)))
+ (funcall fn)))))
+
+(defun magit-read-branch (prompt &optional secondary-default)
+ (magit-completing-read prompt (magit-list-branch-names)
+ nil t nil 'magit-revision-history
+ (or (magit-branch-at-point)
+ secondary-default
+ (magit-get-current-branch))))
+
+(defun magit-read-branch-or-commit (prompt &optional secondary-default)
+ (let ((minibuffer-default-add-function (magit--minibuf-default-add-commit)))
+ (or (magit-completing-read prompt (magit-list-refnames nil t)
+ nil nil nil 'magit-revision-history
+ (or (magit-branch-or-commit-at-point)
+ secondary-default
+ (magit-get-current-branch)))
+ (user-error "Nothing selected"))))
+
+(defun magit-read-range-or-commit (prompt &optional secondary-default)
+ (magit-read-range
+ prompt
+ (or (--when-let (magit-region-values '(commit branch) t)
+ (deactivate-mark)
+ (concat (car (last it)) ".." (car it)))
+ (magit-branch-or-commit-at-point)
+ secondary-default
+ (magit-get-current-branch))))
+
+(defun magit-read-range (prompt &optional default)
+ (let ((minibuffer-default-add-function (magit--minibuf-default-add-commit))
+ (crm-separator "\\.\\.\\.?"))
+ (magit-completing-read-multiple*
+ (concat prompt ": ")
+ (magit-list-refnames)
+ nil nil nil 'magit-revision-history default nil t)))
+
+(defun magit-read-remote-branch
+ (prompt &optional remote default local-branch require-match)
+ (let ((choice (magit-completing-read
+ prompt
+ (-union (and local-branch
+ (if remote
+ (concat remote "/" local-branch)
+ (--map (concat it "/" local-branch)
+ (magit-list-remotes))))
+ (magit-list-remote-branch-names remote t))
+ nil require-match nil 'magit-revision-history default)))
+ (if (or remote (string-match "\\`\\([^/]+\\)/\\(.+\\)" choice))
+ choice
+ (user-error "`%s' doesn't have the form REMOTE/BRANCH" choice))))
+
+(defun magit-read-refspec (prompt remote)
+ (magit-completing-read prompt
+ (prog2 (message "Determining available refs...")
+ (magit-remote-list-refs remote)
+ (message "Determining available refs...done"))))
+
+(defun magit-read-local-branch (prompt &optional secondary-default)
+ (magit-completing-read prompt (magit-list-local-branch-names)
+ nil t nil 'magit-revision-history
+ (or (magit-local-branch-at-point)
+ secondary-default
+ (magit-get-current-branch))))
+
+(defun magit-read-local-branch-or-commit (prompt)
+ (let ((minibuffer-default-add-function (magit--minibuf-default-add-commit))
+ (choices (nconc (magit-list-local-branch-names)
+ (magit-list-special-refnames)))
+ (commit (magit-commit-at-point)))
+ (when commit
+ (push commit choices))
+ (or (magit-completing-read prompt choices
+ nil nil nil 'magit-revision-history
+ (or (magit-local-branch-at-point) commit))
+ (user-error "Nothing selected"))))
+
+(defun magit-read-local-branch-or-ref (prompt &optional secondary-default)
+ (magit-completing-read prompt (nconc (magit-list-local-branch-names)
+ (magit-list-refs "refs/"))
+ nil t nil 'magit-revision-history
+ (or (magit-local-branch-at-point)
+ secondary-default
+ (magit-get-current-branch))))
+
+(defun magit-read-other-branch
+ (prompt &optional exclude secondary-default no-require-match)
+ (let* ((current (magit-get-current-branch))
+ (atpoint (magit-branch-at-point))
+ (exclude (or exclude current))
+ (default (or (and (not (equal atpoint exclude)) atpoint)
+ (and (not (equal current exclude)) current)
+ secondary-default
+ (magit-get-previous-branch))))
+ (magit-completing-read prompt (delete exclude (magit-list-branch-names))
+ nil (not no-require-match)
+ nil 'magit-revision-history default)))
+
+(defun magit-read-other-branch-or-commit
+ (prompt &optional exclude secondary-default)
+ (let* ((minibuffer-default-add-function (magit--minibuf-default-add-commit))
+ (current (magit-get-current-branch))
+ (atpoint (magit-branch-or-commit-at-point))
+ (exclude (or exclude current))
+ (default (or (and (not (equal atpoint exclude))
+ (not (and (not current)
+ (magit-rev-equal atpoint "HEAD")))
+ atpoint)
+ (and (not (equal current exclude)) current)
+ secondary-default
+ (magit-get-previous-branch))))
+ (or (magit-completing-read prompt (delete exclude (magit-list-refnames))
+ nil nil nil 'magit-revision-history default)
+ (user-error "Nothing selected"))))
+
+(defun magit-read-other-local-branch
+ (prompt &optional exclude secondary-default no-require-match)
+ (let* ((current (magit-get-current-branch))
+ (atpoint (magit-local-branch-at-point))
+ (exclude (or exclude current))
+ (default (or (and (not (equal atpoint exclude)) atpoint)
+ (and (not (equal current exclude)) current)
+ secondary-default
+ (magit-get-previous-branch))))
+ (magit-completing-read prompt
+ (delete exclude (magit-list-local-branch-names))
+ nil (not no-require-match)
+ nil 'magit-revision-history default)))
+
+(defun magit-read-branch-prefer-other (prompt)
+ (let* ((current (magit-get-current-branch))
+ (commit (magit-commit-at-point))
+ (atrev (and commit (magit-list-branches-pointing-at commit)))
+ (atpoint (magit--painted-branch-at-point)))
+ (magit-completing-read prompt (magit-list-branch-names)
+ nil t nil 'magit-revision-history
+ (or (magit-section-value-if 'branch)
+ atpoint
+ (and (not (cdr atrev)) (car atrev))
+ (--first (not (equal it current)) atrev)
+ (magit-get-previous-branch)
+ (car atrev)))))
+
+(defun magit-read-upstream-branch (&optional branch prompt)
+ "Read the upstream for BRANCH using PROMPT.
+If optional BRANCH is nil, then read the upstream for the
+current branch, or raise an error if no branch is checked
+out. Only existing branches can be selected."
+ (unless branch
+ (setq branch (or (magit-get-current-branch)
+ (error "Need a branch to set its upstream"))))
+ (let ((branches (delete branch (magit-list-branch-names))))
+ (magit-completing-read
+ (or prompt (format "Change upstream of %s to" branch))
+ branches nil t nil 'magit-revision-history
+ (or (let ((r (car (member (magit-remote-branch-at-point) branches)))
+ (l (car (member (magit-local-branch-at-point) branches))))
+ (if magit-prefer-remote-upstream (or r l) (or l r)))
+ (and-let* ((main (magit-main-branch)))
+ (let ((r (car (member (concat "origin/" main) branches)))
+ (l (car (member main branches))))
+ (if magit-prefer-remote-upstream (or r l) (or l r))))
+ (car (member (magit-get-previous-branch) branches))))))
+
+(defun magit-read-starting-point (prompt &optional branch default)
+ (or (magit-completing-read
+ (concat prompt
+ (and branch
+ (if (bound-and-true-p ivy-mode)
+ ;; Ivy-mode strips faces from prompt.
+ (format " `%s'" branch)
+ (concat " " (magit--propertize-face
+ branch 'magit-branch-local))))
+ " starting at")
+ (nconc (list "HEAD")
+ (magit-list-refnames)
+ (directory-files (magit-git-dir) nil "_HEAD\\'"))
+ nil nil nil 'magit-revision-history
+ (or default (magit--default-starting-point)))
+ (user-error "Nothing selected")))
+
+(defun magit--default-starting-point ()
+ (or (let ((r (magit-remote-branch-at-point))
+ (l (magit-local-branch-at-point)))
+ (if magit-prefer-remote-upstream (or r l) (or l r)))
+ (magit-commit-at-point)
+ (magit-stash-at-point)
+ (magit-get-current-branch)))
+
+(defun magit-read-tag (prompt &optional require-match)
+ (magit-completing-read prompt (magit-list-tags) nil
+ require-match nil 'magit-revision-history
+ (magit-tag-at-point)))
+
+(defun magit-read-stash (prompt)
+ (let* ((atpoint (magit-stash-at-point))
+ (default (and atpoint
+ (concat atpoint (magit-rev-format " %s" atpoint))))
+ (choices (mapcar (lambda (c)
+ (pcase-let ((`(,rev ,msg) (split-string c "\0")))
+ (concat (propertize rev 'face 'magit-hash)
+ " " msg)))
+ (magit-list-stashes "%gd%x00%s")))
+ (choice (magit-completing-read prompt choices
+ nil t nil nil
+ default
+ (car choices))))
+ (and choice
+ (string-match "^\\([^ ]+\\) \\(.+\\)" choice)
+ (substring-no-properties (match-string 1 choice)))))
+
+(defun magit-read-remote (prompt &optional default use-only)
+ (let ((remotes (magit-list-remotes)))
+ (if (and use-only (length= remotes 1))
+ (car remotes)
+ (magit-completing-read prompt remotes
+ nil t nil nil
+ (or default
+ (magit-remote-at-point)
+ (magit-get-remote))))))
+
+(defun magit-read-remote-or-url (prompt &optional default)
+ (magit-completing-read prompt
+ (nconc (magit-list-remotes)
+ (list "https://" "git://" "git@"))
+ nil nil nil nil
+ (or default
+ (magit-remote-at-point)
+ (magit-get-remote))))
+
+(defun magit-read-module-path (prompt &optional predicate)
+ (magit-completing-read prompt (magit-list-module-paths)
+ predicate t nil nil
+ (magit-module-at-point predicate)))
+
+(defun magit-module-confirm (verb &optional predicate)
+ (let (modules)
+ (if current-prefix-arg
+ (progn
+ (setq modules (magit-list-module-paths))
+ (when predicate
+ (setq modules (-filter predicate modules)))
+ (unless modules
+ (if predicate
+ (user-error "No modules satisfying %s available" predicate)
+ (user-error "No modules available"))))
+ (setq modules (magit-region-values 'magit-module-section))
+ (when modules
+ (when predicate
+ (setq modules (-filter predicate modules)))
+ (unless modules
+ (user-error "No modules satisfying %s selected" predicate))))
+ (if (length> modules 1)
+ (magit-confirm t nil (format "%s %%i modules" verb) nil modules)
+ (list (magit-read-module-path (format "%s module" verb) predicate)))))
+
+;;; _
+(provide 'magit-git)
+;;; magit-git.el ends here
diff --git a/elpa/magit-20220503.1245/magit-git.elc b/elpa/magit-20220503.1245/magit-git.elc
new file mode 100644
index 0000000..b827115
--- /dev/null
+++ b/elpa/magit-20220503.1245/magit-git.elc
Binary files differ
diff --git a/elpa/magit-20220503.1245/magit-gitignore.el b/elpa/magit-20220503.1245/magit-gitignore.el
new file mode 100644
index 0000000..d53f149
--- /dev/null
+++ b/elpa/magit-20220503.1245/magit-gitignore.el
@@ -0,0 +1,195 @@
+;;; magit-gitignore.el --- Intentionally untracked files -*- lexical-binding:t -*-
+
+;; Copyright (C) 2008-2022 The Magit Project Contributors
+
+;; Author: Jonas Bernoulli <jonas@bernoul.li>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+
+;; SPDX-License-Identifier: GPL-3.0-or-later
+
+;; Magit 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.
+;;
+;; Magit 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 Magit. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This library implements gitignore commands.
+
+;;; Code:
+
+(require 'magit)
+
+;;; Transient
+
+;;;###autoload (autoload 'magit-gitignore "magit-gitignore" nil t)
+(transient-define-prefix magit-gitignore ()
+ "Instruct Git to ignore a file or pattern."
+ :man-page "gitignore"
+ ["Gitignore"
+ ("t" "shared at toplevel (.gitignore)"
+ magit-gitignore-in-topdir)
+ ("s" "shared in subdirectory (path/to/.gitignore)"
+ magit-gitignore-in-subdir)
+ ("p" "privately (.git/info/exclude)"
+ magit-gitignore-in-gitdir)
+ ("g" magit-gitignore-on-system
+ :if (lambda () (magit-get "core.excludesfile"))
+ :description (lambda ()
+ (format "privately for all repositories (%s)"
+ (magit-get "core.excludesfile"))))]
+ ["Skip worktree"
+ (7 "w" "do skip worktree" magit-skip-worktree)
+ (7 "W" "do not skip worktree" magit-no-skip-worktree)]
+ ["Assume unchanged"
+ (7 "u" "do assume unchanged" magit-assume-unchanged)
+ (7 "U" "do not assume unchanged" magit-no-assume-unchanged)])
+
+;;; Gitignore Commands
+
+;;;###autoload
+(defun magit-gitignore-in-topdir (rule)
+ "Add the Git ignore RULE to the top-level \".gitignore\" file.
+Since this file is tracked, it is shared with other clones of the
+repository. Also stage the file."
+ (interactive (list (magit-gitignore-read-pattern)))
+ (magit-with-toplevel
+ (magit--gitignore rule ".gitignore")
+ (magit-run-git "add" ".gitignore")))
+
+;;;###autoload
+(defun magit-gitignore-in-subdir (rule directory)
+ "Add the Git ignore RULE to a \".gitignore\" file in DIRECTORY.
+Prompt the user for a directory and add the rule to the
+\".gitignore\" file in that directory. Since such files are
+tracked, they are shared with other clones of the repository.
+Also stage the file."
+ (interactive (list (magit-gitignore-read-pattern)
+ (read-directory-name "Limit rule to files in: ")))
+ (magit-with-toplevel
+ (let ((file (expand-file-name ".gitignore" directory)))
+ (magit--gitignore rule file)
+ (magit-run-git "add" (magit-convert-filename-for-git file)))))
+
+;;;###autoload
+(defun magit-gitignore-in-gitdir (rule)
+ "Add the Git ignore RULE to \"$GIT_DIR/info/exclude\".
+Rules in that file only affects this clone of the repository."
+ (interactive (list (magit-gitignore-read-pattern)))
+ (magit--gitignore rule (magit-git-dir "info/exclude"))
+ (magit-refresh))
+
+;;;###autoload
+(defun magit-gitignore-on-system (rule)
+ "Add the Git ignore RULE to the file specified by `core.excludesFile'.
+Rules that are defined in that file affect all local repositories."
+ (interactive (list (magit-gitignore-read-pattern)))
+ (magit--gitignore rule
+ (or (magit-get "core.excludesFile")
+ (error "Variable `core.excludesFile' isn't set")))
+ (magit-refresh))
+
+(defun magit--gitignore (rule file)
+ (when-let ((directory (file-name-directory file)))
+ (make-directory directory t))
+ (with-temp-buffer
+ (when (file-exists-p file)
+ (insert-file-contents file))
+ (goto-char (point-max))
+ (unless (bolp)
+ (insert "\n"))
+ (insert (replace-regexp-in-string "\\(\\\\*\\)" "\\1\\1" rule))
+ (insert "\n")
+ (write-region nil nil file)))
+
+(defun magit-gitignore-read-pattern ()
+ (let* ((default (magit-current-file))
+ (base (car magit-buffer-diff-files))
+ (base (and base (file-directory-p base) base))
+ (choices
+ (delete-dups
+ (--mapcat
+ (cons (concat "/" it)
+ (and-let* ((ext (file-name-extension it)))
+ (list (concat "/" (file-name-directory it) "*." ext)
+ (concat "*." ext))))
+ (sort (nconc
+ (magit-untracked-files nil base)
+ ;; The untracked section of the status buffer lists
+ ;; directories containing only untracked files.
+ ;; Add those as candidates.
+ (-filter #'directory-name-p
+ (magit-list-files
+ "--other" "--exclude-standard" "--directory"
+ "--no-empty-directory" "--" base)))
+ #'string-lessp)))))
+ (when default
+ (setq default (concat "/" default))
+ (unless (member default choices)
+ (setq default (concat "*." (file-name-extension default)))
+ (unless (member default choices)
+ (setq default nil))))
+ (magit-completing-read "File or pattern to ignore"
+ choices nil nil nil nil default)))
+
+;;; Skip Worktree Commands
+
+;;;###autoload
+(defun magit-skip-worktree (file)
+ "Call \"git update-index --skip-worktree -- FILE\"."
+ (interactive
+ (list (magit-read-file-choice "Skip worktree for"
+ (magit-with-toplevel
+ (cl-set-difference
+ (magit-list-files)
+ (magit-skip-worktree-files)
+ :test #'equal)))))
+ (magit-with-toplevel
+ (magit-run-git "update-index" "--skip-worktree" "--" file)))
+
+;;;###autoload
+(defun magit-no-skip-worktree (file)
+ "Call \"git update-index --no-skip-worktree -- FILE\"."
+ (interactive
+ (list (magit-read-file-choice "Do not skip worktree for"
+ (magit-with-toplevel
+ (magit-skip-worktree-files)))))
+ (magit-with-toplevel
+ (magit-run-git "update-index" "--no-skip-worktree" "--" file)))
+
+;;; Assume Unchanged Commands
+
+;;;###autoload
+(defun magit-assume-unchanged (file)
+ "Call \"git update-index --assume-unchanged -- FILE\"."
+ (interactive
+ (list (magit-read-file-choice "Assume file to be unchanged"
+ (magit-with-toplevel
+ (cl-set-difference
+ (magit-list-files)
+ (magit-assume-unchanged-files)
+ :test #'equal)))))
+ (magit-with-toplevel
+ (magit-run-git "update-index" "--assume-unchanged" "--" file)))
+
+;;;###autoload
+(defun magit-no-assume-unchanged (file)
+ "Call \"git update-index --no-assume-unchanged -- FILE\"."
+ (interactive
+ (list (magit-read-file-choice "Do not assume file to be unchanged"
+ (magit-with-toplevel
+ (magit-assume-unchanged-files)))))
+ (magit-with-toplevel
+ (magit-run-git "update-index" "--no-assume-unchanged" "--" file)))
+
+;;; _
+(provide 'magit-gitignore)
+;;; magit-gitignore.el ends here
diff --git a/elpa/magit-20220503.1245/magit-gitignore.elc b/elpa/magit-20220503.1245/magit-gitignore.elc
new file mode 100644
index 0000000..c6eb8e0
--- /dev/null
+++ b/elpa/magit-20220503.1245/magit-gitignore.elc
Binary files differ
diff --git a/elpa/magit-20220503.1245/magit-log.el b/elpa/magit-20220503.1245/magit-log.el
new file mode 100644
index 0000000..47c3fb6
--- /dev/null
+++ b/elpa/magit-20220503.1245/magit-log.el
@@ -0,0 +1,1938 @@
+;;; magit-log.el --- Inspect Git history -*- lexical-binding:t -*-
+
+;; Copyright (C) 2008-2022 The Magit Project Contributors
+
+;; Author: Jonas Bernoulli <jonas@bernoul.li>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+
+;; SPDX-License-Identifier: GPL-3.0-or-later
+
+;; Magit 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.
+;;
+;; Magit 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 Magit. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This library implements support for looking at Git logs, including
+;; special logs like cherry-logs, as well as for selecting a commit
+;; from a log.
+
+;;; Code:
+
+(require 'magit-core)
+(require 'magit-diff)
+
+(declare-function magit-blob-visit "magit-files" (blob-or-file))
+(declare-function magit-cherry-apply "magit-sequence" (commit &optional args))
+(declare-function magit-insert-head-branch-header "magit-status"
+ (&optional branch))
+(declare-function magit-insert-upstream-branch-header "magit-status"
+ (&optional branch pull keyword))
+(declare-function magit-read-file-from-rev "magit-files"
+ (rev prompt &optional default))
+(declare-function magit-rebase--get-state-lines "magit-sequence"
+ (file))
+(declare-function magit-show-commit "magit-diff"
+ (arg1 &optional arg2 arg3 arg4))
+(declare-function magit-reflog-format-subject "magit-reflog" (subject))
+(defvar magit-refs-focus-column-width)
+(defvar magit-refs-margin)
+(defvar magit-refs-show-commit-count)
+(defvar magit-buffer-margin)
+(defvar magit-status-margin)
+(defvar magit-status-sections-hook)
+
+(require 'ansi-color)
+(require 'crm)
+(require 'which-func)
+
+;;; Options
+;;;; Log Mode
+
+(defgroup magit-log nil
+ "Inspect and manipulate Git history."
+ :link '(info-link "(magit)Logging")
+ :group 'magit-commands
+ :group 'magit-modes)
+
+(defcustom magit-log-mode-hook nil
+ "Hook run after entering Magit-Log mode."
+ :group 'magit-log
+ :type 'hook)
+
+(defcustom magit-log-remove-graph-args '("--follow" "--grep" "-G" "-S" "-L")
+ "The log arguments that cause the `--graph' argument to be dropped."
+ :package-version '(magit . "2.3.0")
+ :group 'magit-log
+ :type '(repeat (string :tag "Argument"))
+ :options '("--follow" "--grep" "-G" "-S" "-L"))
+
+(defcustom magit-log-revision-headers-format "\
+%+b%+N
+Author: %aN <%aE>
+Committer: %cN <%cE>"
+ "Additional format string used with the `++header' argument."
+ :package-version '(magit . "3.2.0")
+ :group 'magit-log
+ :type 'string)
+
+(defcustom magit-log-auto-more nil
+ "Insert more log entries automatically when moving past the last entry.
+Only considered when moving past the last entry with
+`magit-goto-*-section' commands."
+ :group 'magit-log
+ :type 'boolean)
+
+(defcustom magit-log-margin '(t age magit-log-margin-width t 18)
+ "Format of the margin in `magit-log-mode' buffers.
+
+The value has the form (INIT STYLE WIDTH AUTHOR AUTHOR-WIDTH).
+
+If INIT is non-nil, then the margin is shown initially.
+STYLE controls how to format the author or committer date.
+ It can be one of `age' (to show the age of the commit),
+ `age-abbreviated' (to abbreviate the time unit to a character),
+ or a string (suitable for `format-time-string') to show the
+ actual date. Option `magit-log-margin-show-committer-date'
+ controls which date is being displayed.
+WIDTH controls the width of the margin. This exists for forward
+ compatibility and currently the value should not be changed.
+AUTHOR controls whether the name of the author is also shown by
+ default.
+AUTHOR-WIDTH has to be an integer. When the name of the author
+ is shown, then this specifies how much space is used to do so."
+ :package-version '(magit . "2.9.0")
+ :group 'magit-log
+ :group 'magit-margin
+ :type magit-log-margin--custom-type
+ :initialize #'magit-custom-initialize-reset
+ :set (apply-partially #'magit-margin-set-variable 'magit-log-mode))
+
+(defcustom magit-log-margin-show-committer-date nil
+ "Whether to show the committer date in the margin.
+
+This option only controls whether the committer date is displayed
+instead of the author date. Whether some date is displayed in
+the margin and whether the margin is displayed at all is
+controlled by other options."
+ :package-version '(magit . "3.0.0")
+ :group 'magit-log
+ :group 'magit-margin
+ :type 'boolean)
+
+(defcustom magit-log-show-refname-after-summary nil
+ "Whether to show refnames after commit summaries.
+This is useful if you use really long branch names."
+ :package-version '(magit . "2.2.0")
+ :group 'magit-log
+ :type 'boolean)
+
+(defcustom magit-log-highlight-keywords t
+ "Whether to highlight bracketed keywords in commit summaries."
+ :package-version '(magit . "2.12.0")
+ :group 'magit-log
+ :type 'boolean)
+
+(defcustom magit-log-header-line-function #'magit-log-header-line-sentence
+ "Function used to generate text shown in header line of log buffers."
+ :package-version '(magit . "2.12.0")
+ :group 'magit-log
+ :type '(choice (function-item magit-log-header-line-arguments)
+ (function-item magit-log-header-line-sentence)
+ function))
+
+(defcustom magit-log-trace-definition-function #'magit-which-function
+ "Function used to determine the function at point.
+This is used by the command `magit-log-trace-definition'.
+You should prefer `magit-which-function' over `which-function'
+because the latter may make use of Imenu's outdated cache."
+ :package-version '(magit . "3.0.0")
+ :group 'magit-log
+ :type '(choice (function-item magit-which-function)
+ (function-item which-function)
+ (function-item add-log-current-defun)
+ function))
+
+(defface magit-log-graph
+ '((((class color) (background light)) :foreground "grey30")
+ (((class color) (background dark)) :foreground "grey80"))
+ "Face for the graph part of the log output."
+ :group 'magit-faces)
+
+(defface magit-log-author
+ '((((class color) (background light))
+ :foreground "firebrick"
+ :slant normal
+ :weight normal)
+ (((class color) (background dark))
+ :foreground "tomato"
+ :slant normal
+ :weight normal))
+ "Face for the author part of the log output."
+ :group 'magit-faces)
+
+(defface magit-log-date
+ '((((class color) (background light))
+ :foreground "grey30"
+ :slant normal
+ :weight normal)
+ (((class color) (background dark))
+ :foreground "grey80"
+ :slant normal
+ :weight normal))
+ "Face for the date part of the log output."
+ :group 'magit-faces)
+
+(defface magit-header-line-log-select
+ '((t :inherit bold))
+ "Face for the `header-line' in `magit-log-select-mode'."
+ :group 'magit-faces)
+
+;;;; File Log
+
+(defcustom magit-log-buffer-file-locked t
+ "Whether `magit-log-buffer-file-quick' uses a dedicated buffer."
+ :package-version '(magit . "2.7.0")
+ :group 'magit-commands
+ :group 'magit-log
+ :type 'boolean)
+
+;;;; Select Mode
+
+(defcustom magit-log-select-show-usage 'both
+ "Whether to show usage information when selecting a commit from a log.
+The message can be shown in the `echo-area' or the `header-line', or in
+`both' places. If the value isn't one of these symbols, then it should
+be nil, in which case no usage information is shown."
+ :package-version '(magit . "2.1.0")
+ :group 'magit-log
+ :type '(choice (const :tag "in echo-area" echo-area)
+ (const :tag "in header-line" header-line)
+ (const :tag "in both places" both)
+ (const :tag "nowhere")))
+
+(defcustom magit-log-select-margin
+ (list (nth 0 magit-log-margin)
+ (nth 1 magit-log-margin)
+ 'magit-log-margin-width t
+ (nth 4 magit-log-margin))
+ "Format of the margin in `magit-log-select-mode' buffers.
+
+The value has the form (INIT STYLE WIDTH AUTHOR AUTHOR-WIDTH).
+
+If INIT is non-nil, then the margin is shown initially.
+STYLE controls how to format the author or committer date.
+ It can be one of `age' (to show the age of the commit),
+ `age-abbreviated' (to abbreviate the time unit to a character),
+ or a string (suitable for `format-time-string') to show the
+ actual date. Option `magit-log-margin-show-committer-date'
+ controls which date is being displayed.
+WIDTH controls the width of the margin. This exists for forward
+ compatibility and currently the value should not be changed.
+AUTHOR controls whether the name of the author is also shown by
+ default.
+AUTHOR-WIDTH has to be an integer. When the name of the author
+ is shown, then this specifies how much space is used to do so."
+ :package-version '(magit . "2.9.0")
+ :group 'magit-log
+ :group 'magit-margin
+ :type magit-log-margin--custom-type
+ :initialize #'magit-custom-initialize-reset
+ :set-after '(magit-log-margin)
+ :set (apply-partially #'magit-margin-set-variable 'magit-log-select-mode))
+
+;;;; Cherry Mode
+
+(defcustom magit-cherry-sections-hook
+ '(magit-insert-cherry-headers
+ magit-insert-cherry-commits)
+ "Hook run to insert sections into the cherry buffer."
+ :package-version '(magit . "2.1.0")
+ :group 'magit-log
+ :type 'hook)
+
+(defcustom magit-cherry-margin
+ (list (nth 0 magit-log-margin)
+ (nth 1 magit-log-margin)
+ 'magit-log-margin-width t
+ (nth 4 magit-log-margin))
+ "Format of the margin in `magit-cherry-mode' buffers.
+
+The value has the form (INIT STYLE WIDTH AUTHOR AUTHOR-WIDTH).
+
+If INIT is non-nil, then the margin is shown initially.
+STYLE controls how to format the author or committer date.
+ It can be one of `age' (to show the age of the commit),
+ `age-abbreviated' (to abbreviate the time unit to a character),
+ or a string (suitable for `format-time-string') to show the
+ actual date. Option `magit-log-margin-show-committer-date'
+ controls which date is being displayed.
+WIDTH controls the width of the margin. This exists for forward
+ compatibility and currently the value should not be changed.
+AUTHOR controls whether the name of the author is also shown by
+ default.
+AUTHOR-WIDTH has to be an integer. When the name of the author
+ is shown, then this specifies how much space is used to do so."
+ :package-version '(magit . "2.9.0")
+ :group 'magit-log
+ :group 'magit-margin
+ :type magit-log-margin--custom-type
+ :initialize #'magit-custom-initialize-reset
+ :set-after '(magit-log-margin)
+ :set (apply-partially #'magit-margin-set-variable 'magit-cherry-mode))
+
+;;;; Log Sections
+
+(defcustom magit-log-section-commit-count 10
+ "How many recent commits to show in certain log sections.
+How many recent commits `magit-insert-recent-commits' and
+`magit-insert-unpulled-from-upstream-or-recent' (provided
+the upstream isn't ahead of the current branch) show."
+ :package-version '(magit . "2.1.0")
+ :group 'magit-status
+ :type 'number)
+
+;;; Arguments
+;;;; Prefix Classes
+
+(defclass magit-log-prefix (transient-prefix)
+ ((history-key :initform 'magit-log)
+ (major-mode :initform 'magit-log-mode)))
+
+(defclass magit-log-refresh-prefix (magit-log-prefix)
+ ((history-key :initform 'magit-log)
+ (major-mode :initform nil)))
+
+;;;; Prefix Methods
+
+(cl-defmethod transient-init-value ((obj magit-log-prefix))
+ (pcase-let ((`(,args ,files)
+ (magit-log--get-value 'magit-log-mode
+ magit-prefix-use-buffer-arguments)))
+ (unless (eq transient-current-command 'magit-dispatch)
+ (when-let ((file (magit-file-relative-name)))
+ (setq files (list file))))
+ (oset obj value (if files `(("--" ,@files) ,args) args))))
+
+(cl-defmethod transient-init-value ((obj magit-log-refresh-prefix))
+ (oset obj value (if magit-buffer-log-files
+ `(("--" ,@magit-buffer-log-files)
+ ,magit-buffer-log-args)
+ magit-buffer-log-args)))
+
+(cl-defmethod transient-set-value ((obj magit-log-prefix))
+ (magit-log--set-value obj))
+
+(cl-defmethod transient-save-value ((obj magit-log-prefix))
+ (magit-log--set-value obj 'save))
+
+;;;; Argument Access
+
+(defun magit-log-arguments (&optional mode)
+ "Return the current log arguments."
+ (if (memq transient-current-command '(magit-log magit-log-refresh))
+ (pcase-let ((`(,args ,alist)
+ (-separate #'atom (transient-get-value))))
+ (list args (cdr (assoc "--" alist))))
+ (magit-log--get-value (or mode 'magit-log-mode))))
+
+(defun magit-log--get-value (mode &optional use-buffer-args)
+ (unless use-buffer-args
+ (setq use-buffer-args magit-direct-use-buffer-arguments))
+ (let (args files)
+ (cond
+ ((and (memq use-buffer-args '(always selected current))
+ (eq major-mode mode))
+ (setq args magit-buffer-log-args)
+ (setq files magit-buffer-log-files))
+ ((and (memq use-buffer-args '(always selected))
+ (when-let ((buffer (magit-get-mode-buffer
+ mode nil
+ (eq use-buffer-args 'selected))))
+ (setq args (buffer-local-value 'magit-buffer-log-args buffer))
+ (setq files (buffer-local-value 'magit-buffer-log-files buffer))
+ t)))
+ ((plist-member (symbol-plist mode) 'magit-log-current-arguments)
+ (setq args (get mode 'magit-log-current-arguments)))
+ ((when-let ((elt (assq (intern (format "magit-log:%s" mode))
+ transient-values)))
+ (setq args (cdr elt))
+ t))
+ (t
+ (setq args (get mode 'magit-log-default-arguments))))
+ (list args files)))
+
+(defun magit-log--set-value (obj &optional save)
+ (pcase-let* ((obj (oref obj prototype))
+ (mode (or (oref obj major-mode) major-mode))
+ (key (intern (format "magit-log:%s" mode)))
+ (`(,args ,alist)
+ (-separate #'atom (transient-get-value)))
+ (files (cdr (assoc "--" alist))))
+ (put mode 'magit-log-current-arguments args)
+ (when save
+ (setf (alist-get key transient-values) args)
+ (transient-save-values))
+ (transient--history-push obj)
+ (setq magit-buffer-log-args args)
+ (unless (derived-mode-p 'magit-log-select-mode)
+ (setq magit-buffer-log-files files))
+ (magit-refresh)))
+
+;;; Commands
+;;;; Prefix Commands
+
+;;;###autoload (autoload 'magit-log "magit-log" nil t)
+(transient-define-prefix magit-log ()
+ "Show a commit or reference log."
+ :man-page "git-log"
+ :class 'magit-log-prefix
+ ;; The grouping in git-log(1) appears to be guided by implementation
+ ;; details, so our logical grouping only follows it to an extend.
+ ;; Arguments that are "misplaced" here:
+ ;; 1. From "Commit Formatting".
+ ;; 2. From "Common Diff Options".
+ ;; 3. From unnamed first group.
+ ;; 4. Implemented by Magit.
+ ["Commit limiting"
+ (magit-log:-n)
+ (magit:--author)
+ (7 magit-log:--since)
+ (7 magit-log:--until)
+ (magit-log:--grep)
+ (7 "-i" "Search case-insensitive" ("-i" "--regexp-ignore-case"))
+ (7 "-I" "Invert search pattern" "--invert-grep")
+ (magit-log:-G) ;2
+ (magit-log:-S) ;2
+ (magit-log:-L) ;2
+ (7 "=m" "Omit merges" "--no-merges")
+ (7 "=p" "First parent" "--first-parent")]
+ ["History simplification"
+ ( "-D" "Simplify by decoration" "--simplify-by-decoration")
+ (magit:--)
+ ( "-f" "Follow renames when showing single-file log" "--follow") ;3
+ (6 "/s" "Only commits changing given paths" "--sparse")
+ (7 "/d" "Only selected commits plus meaningful history" "--dense")
+ (7 "/a" "Only commits existing directly on ancestry path" "--ancestry-path")
+ (6 "/f" "Do not prune history" "--full-history")
+ (7 "/m" "Prune some history" "--simplify-merges")]
+ ["Commit ordering"
+ (magit-log:--*-order)
+ ("-r" "Reverse order" "--reverse")]
+ ["Formatting"
+ ("-g" "Show graph" "--graph") ;1
+ ("-c" "Show graph in color" "--color") ;2
+ ("-d" "Show refnames" "--decorate") ;3
+ ("=S" "Show signatures" "--show-signature") ;1
+ ("-h" "Show header" "++header") ;4
+ ("-p" "Show diffs" ("-p" "--patch")) ;2
+ ("-s" "Show diffstats" "--stat")] ;2
+ [["Log"
+ ("l" "current" magit-log-current)
+ ("h" "HEAD" magit-log-head)
+ ("u" "related" magit-log-related)
+ ("o" "other" magit-log-other)]
+ [""
+ ("L" "local branches" magit-log-branches)
+ ("b" "all branches" magit-log-all-branches)
+ ("a" "all references" magit-log-all)
+ (7 "B" "matching branches" magit-log-matching-branches)
+ (7 "T" "matching tags" magit-log-matching-tags)
+ (7 "m" "merged" magit-log-merged)]
+ ["Reflog"
+ ("r" "current" magit-reflog-current)
+ ("H" "HEAD" magit-reflog-head)
+ ("O" "other" magit-reflog-other)]
+ [:if (lambda ()
+ (require 'magit-wip)
+ (magit--any-wip-mode-enabled-p))
+ :description "Wiplog"
+ ("i" "index" magit-wip-log-index)
+ ("w" "worktree" magit-wip-log-worktree)]
+ ["Other"
+ (5 "s" "shortlog" magit-shortlog)]])
+
+;;;###autoload (autoload 'magit-log-refresh "magit-log" nil t)
+(transient-define-prefix magit-log-refresh ()
+ "Change the arguments used for the log(s) in the current buffer."
+ :man-page "git-log"
+ :class 'magit-log-refresh-prefix
+ [:if-mode magit-log-mode
+ :class transient-subgroups
+ ["Commit limiting"
+ (magit-log:-n)
+ (magit:--author)
+ (magit-log:--grep)
+ (7 "-i" "Search case-insensitive" ("-i" "--regexp-ignore-case"))
+ (7 "-I" "Invert search pattern" "--invert-grep")
+ (magit-log:-G)
+ (magit-log:-S)
+ (magit-log:-L)]
+ ["History simplification"
+ ( "-D" "Simplify by decoration" "--simplify-by-decoration")
+ (magit:--)
+ ( "-f" "Follow renames when showing single-file log" "--follow") ;3
+ (6 "/s" "Only commits changing given paths" "--sparse")
+ (7 "/d" "Only selected commits plus meaningful history" "--dense")
+ (7 "/a" "Only commits existing directly on ancestry path" "--ancestry-path")
+ (6 "/f" "Do not prune history" "--full-history")
+ (7 "/m" "Prune some history" "--simplify-merges")]
+ ["Commit ordering"
+ (magit-log:--*-order)
+ ("-r" "Reverse order" "--reverse")]
+ ["Formatting"
+ ("-g" "Show graph" "--graph")
+ ("-c" "Show graph in color" "--color")
+ ("-d" "Show refnames" "--decorate")
+ ("=S" "Show signatures" "--show-signature")
+ ("-h" "Show header" "++header")
+ ("-p" "Show diffs" ("-p" "--patch"))
+ ("-s" "Show diffstats" "--stat")]]
+ [:if-not-mode magit-log-mode
+ :description "Arguments"
+ (magit-log:-n)
+ (magit-log:--*-order)
+ ("-g" "Show graph" "--graph")
+ ("-c" "Show graph in color" "--color")
+ ("-d" "Show refnames" "--decorate")]
+ [["Refresh"
+ ("g" "buffer" magit-log-refresh)
+ ("s" "buffer and set defaults" transient-set :transient nil)
+ ("w" "buffer and save defaults" transient-save :transient nil)]
+ ["Margin"
+ ("L" "toggle visibility" magit-toggle-margin)
+ ("l" "cycle style" magit-cycle-margin-style)
+ ("d" "toggle details" magit-toggle-margin-details)
+ ("x" "toggle shortstat" magit-toggle-log-margin-style)]
+ [:if-mode magit-log-mode
+ :description "Toggle"
+ ("b" "buffer lock" magit-toggle-buffer-lock)]]
+ (interactive)
+ (cond
+ ((not (eq transient-current-command 'magit-log-refresh))
+ (pcase major-mode
+ ('magit-reflog-mode
+ (user-error "Cannot change log arguments in reflog buffers"))
+ ('magit-cherry-mode
+ (user-error "Cannot change log arguments in cherry buffers")))
+ (transient-setup 'magit-log-refresh))
+ (t
+ (pcase-let ((`(,args ,files) (magit-log-arguments)))
+ (setq magit-buffer-log-args args)
+ (unless (derived-mode-p 'magit-log-select-mode)
+ (setq magit-buffer-log-files files)))
+ (magit-refresh))))
+
+;;;; Infix Commands
+
+(transient-define-argument magit-log:-n ()
+ :description "Limit number of commits"
+ :class 'transient-option
+ ;; For historic reasons (and because it easy to guess what "-n"
+ ;; stands for) this is the only argument where we do not use the
+ ;; long argument ("--max-count").
+ :shortarg "-n"
+ :argument "-n"
+ :reader #'transient-read-number-N+)
+
+(transient-define-argument magit:--author ()
+ :description "Limit to author"
+ :class 'transient-option
+ :key "-A"
+ :argument "--author="
+ :reader #'magit-transient-read-person)
+
+(transient-define-argument magit-log:--since ()
+ :description "Limit to commits since"
+ :class 'transient-option
+ :key "=s"
+ :argument "--since="
+ :reader #'transient-read-date)
+
+(transient-define-argument magit-log:--until ()
+ :description "Limit to commits until"
+ :class 'transient-option
+ :key "=u"
+ :argument "--until="
+ :reader #'transient-read-date)
+
+(transient-define-argument magit-log:--*-order ()
+ :description "Order commits by"
+ :class 'transient-switches
+ :key "-o"
+ :argument-format "--%s-order"
+ :argument-regexp "\\(--\\(topo\\|author-date\\|date\\)-order\\)"
+ :choices '("topo" "author-date" "date"))
+
+(transient-define-argument magit-log:--grep ()
+ :description "Search messages"
+ :class 'transient-option
+ :key "-F"
+ :argument "--grep=")
+
+(transient-define-argument magit-log:-G ()
+ :description "Search changes"
+ :class 'transient-option
+ :argument "-G")
+
+(transient-define-argument magit-log:-S ()
+ :description "Search occurrences"
+ :class 'transient-option
+ :argument "-S")
+
+(transient-define-argument magit-log:-L ()
+ :description "Trace line evolution"
+ :class 'transient-option
+ :argument "-L"
+ :reader #'magit-read-file-trace)
+
+(defun magit-read-file-trace (&rest _ignored)
+ (let ((file (magit-read-file-from-rev "HEAD" "File"))
+ (trace (magit-read-string "Trace")))
+ (concat trace ":" file)))
+
+;;;; Setup Commands
+
+(defvar magit-log-read-revs-map
+ (let ((map (make-sparse-keymap)))
+ (set-keymap-parent map crm-local-completion-map)
+ (define-key map "\s" #'self-insert-command)
+ map))
+
+(defun magit-log-read-revs (&optional use-current)
+ (or (and use-current (and-let* ((buf (magit-get-current-branch))) (list buf)))
+ (let ((crm-separator "\\(\\.\\.\\.?\\|[, ]\\)")
+ (crm-local-completion-map magit-log-read-revs-map))
+ (split-string (magit-completing-read-multiple*
+ "Log rev,s: "
+ (magit-list-refnames nil t)
+ nil nil nil 'magit-revision-history
+ (or (magit-branch-or-commit-at-point)
+ (unless use-current
+ (magit-get-previous-branch)))
+ nil t)
+ "[, ]" t))))
+
+(defun magit-log-read-pattern (option)
+ "Read a string from the user to pass as parameter to OPTION."
+ (magit-read-string (format "Type a pattern to pass to %s" option)))
+
+;;;###autoload
+(defun magit-log-current (revs &optional args files)
+ "Show log for the current branch.
+When `HEAD' is detached or with a prefix argument show log for
+one or more revs read from the minibuffer."
+ (interactive (cons (magit-log-read-revs t)
+ (magit-log-arguments)))
+ (magit-log-setup-buffer revs args files))
+
+;;;###autoload
+(defun magit-log-head (&optional args files)
+ "Show log for `HEAD'."
+ (interactive (magit-log-arguments))
+ (magit-log-setup-buffer (list "HEAD") args files))
+
+;;;###autoload
+(defun magit-log-related (revs &optional args files)
+ "Show log for the current branch, its upstream and its push target.
+When the upstream is a local branch, then also show its own
+upstream. When `HEAD' is detached, then show log for that, the
+previously checked out branch and its upstream and push-target."
+ (interactive
+ (cons (let ((current (magit-get-current-branch))
+ head rebase target upstream upup)
+ (unless current
+ (setq rebase (magit-rebase--get-state-lines "head-name"))
+ (cond (rebase
+ (setq rebase (magit-ref-abbrev rebase))
+ (setq current rebase)
+ (setq head "HEAD"))
+ (t (setq current (magit-get-previous-branch)))))
+ (cond (current
+ (setq current
+ (magit--propertize-face current'magit-branch-local))
+ (setq target (magit-get-push-branch current t))
+ (setq upstream (magit-get-upstream-branch current))
+ (when upstream
+ (setq upup (and (magit-local-branch-p upstream)
+ (magit-get-upstream-branch upstream)))))
+ (t (setq head "HEAD")))
+ (delq nil (list current head target upstream upup)))
+ (magit-log-arguments)))
+ (magit-log-setup-buffer revs args files))
+
+;;;###autoload
+(defun magit-log-other (revs &optional args files)
+ "Show log for one or more revs read from the minibuffer.
+The user can input any revision or revisions separated by a
+space, or even ranges, but only branches and tags, and a
+representation of the commit at point, are available as
+completion candidates."
+ (interactive (cons (magit-log-read-revs)
+ (magit-log-arguments)))
+ (magit-log-setup-buffer revs args files))
+
+;;;###autoload
+(defun magit-log-branches (&optional args files)
+ "Show log for all local branches and `HEAD'."
+ (interactive (magit-log-arguments))
+ (magit-log-setup-buffer (if (magit-get-current-branch)
+ (list "--branches")
+ (list "HEAD" "--branches"))
+ args files))
+
+;;;###autoload
+(defun magit-log-matching-branches (pattern &optional args files)
+ "Show log for all branches matching PATTERN and `HEAD'."
+ (interactive (cons (magit-log-read-pattern "--branches") (magit-log-arguments)))
+ (magit-log-setup-buffer
+ (list "HEAD" (format "--branches=%s" pattern))
+ args files))
+
+;;;###autoload
+(defun magit-log-matching-tags (pattern &optional args files)
+ "Show log for all tags matching PATTERN and `HEAD'."
+ (interactive (cons (magit-log-read-pattern "--tags") (magit-log-arguments)))
+ (magit-log-setup-buffer
+ (list "HEAD" (format "--tags=%s" pattern))
+ args files))
+
+;;;###autoload
+(defun magit-log-all-branches (&optional args files)
+ "Show log for all local and remote branches and `HEAD'."
+ (interactive (magit-log-arguments))
+ (magit-log-setup-buffer (if (magit-get-current-branch)
+ (list "--branches" "--remotes")
+ (list "HEAD" "--branches" "--remotes"))
+ args files))
+
+;;;###autoload
+(defun magit-log-all (&optional args files)
+ "Show log for all references and `HEAD'."
+ (interactive (magit-log-arguments))
+ (magit-log-setup-buffer (if (magit-get-current-branch)
+ (list "--all")
+ (list "HEAD" "--all"))
+ args files))
+
+;;;###autoload
+(defun magit-log-buffer-file (&optional follow beg end)
+ "Show log for the blob or file visited in the current buffer.
+With a prefix argument or when `--follow' is an active log
+argument, then follow renames. When the region is active,
+restrict the log to the lines that the region touches."
+ (interactive
+ (cons current-prefix-arg
+ (and (region-active-p)
+ (magit-file-relative-name)
+ (save-restriction
+ (widen)
+ (list (line-number-at-pos (region-beginning))
+ (line-number-at-pos
+ (let ((end (region-end)))
+ (if (char-after end)
+ end
+ ;; Ensure that we don't get the line number
+ ;; of a trailing newline.
+ (1- end)))))))))
+ (require 'magit)
+ (if-let ((file (magit-file-relative-name)))
+ (magit-log-setup-buffer
+ (list (or magit-buffer-refname
+ (magit-get-current-branch)
+ "HEAD"))
+ (let ((args (car (magit-log-arguments))))
+ (when (and follow (not (member "--follow" args)))
+ (push "--follow" args))
+ (when (and (file-regular-p
+ (expand-file-name file (magit-toplevel)))
+ beg end)
+ (setq args (cons (format "-L%s,%s:%s" beg end file)
+ (cl-delete "-L" args :test
+ #'string-prefix-p)))
+ (setq file nil))
+ args)
+ (and file (list file))
+ magit-log-buffer-file-locked)
+ (user-error "Buffer isn't visiting a file")))
+
+;;;###autoload
+(defun magit-log-trace-definition (file fn rev)
+ "Show log for the definition at point."
+ (interactive (list (or (magit-file-relative-name)
+ (user-error "Buffer isn't visiting a file"))
+ (or (funcall magit-log-trace-definition-function)
+ (user-error "No function at point found"))
+ (or magit-buffer-refname
+ (magit-get-current-branch)
+ "HEAD")))
+ (require 'magit)
+ (magit-log-setup-buffer
+ (list rev)
+ (cons (format "-L:%s%s:%s"
+ (string-replace ":" "\\:" (regexp-quote fn))
+ (if (derived-mode-p 'lisp-mode 'emacs-lisp-mode)
+ ;; Git doesn't treat "-" the same way as
+ ;; "_", leading to false-positives such as
+ ;; "foo-suffix" being considered a match
+ ;; for "foo". Wing it.
+ "\\( \\|$\\)"
+ ;; We could use "\\b" here, but since Git
+ ;; already does something equivalent, that
+ ;; isn't necessary.
+ "")
+ file)
+ (cl-delete "-L" (car (magit-log-arguments))
+ :test #'string-prefix-p))
+ nil magit-log-buffer-file-locked))
+
+(defun magit-diff-trace-definition ()
+ "Show log for the definition at point in a diff."
+ (interactive)
+ (pcase-let ((`(,buf ,pos) (magit-diff-visit-file--noselect)))
+ (magit--with-temp-position buf pos
+ (call-interactively #'magit-log-trace-definition))))
+
+;;;###autoload
+(defun magit-log-merged (commit branch &optional args files)
+ "Show log for the merge of COMMIT into BRANCH.
+
+More precisely, find merge commit M that brought COMMIT into
+BRANCH, and show the log of the range \"M^1..M\". If COMMIT is
+directly on BRANCH, then show approximately twenty surrounding
+commits instead.
+
+This command requires git-when-merged, which is available from
+https://github.com/mhagger/git-when-merged."
+ (interactive
+ (append (let ((commit (magit-read-branch-or-commit "Log merge of commit")))
+ (list commit
+ (magit-read-other-branch "Merged into" commit)))
+ (magit-log-arguments)))
+ (unless (compat-executable-find "git-when-merged" t)
+ (user-error "This command requires git-when-merged (%s)"
+ "https://github.com/mhagger/git-when-merged"))
+ (let (exit m)
+ (with-temp-buffer
+ (save-excursion
+ (setq exit (magit-process-git t "when-merged" "-c"
+ (magit-abbrev-arg)
+ commit branch)))
+ (setq m (buffer-substring-no-properties (point) (line-end-position))))
+ (if (zerop exit)
+ (magit-log-setup-buffer (list (format "%s^1..%s" m m))
+ args files nil commit)
+ (setq m (string-trim m))
+ (if (equal m "Commit is directly on this branch.")
+ (let* ((from (concat commit "~10"))
+ (to (- (car (magit-rev-diff-count branch commit)) 10))
+ (to (if (<= to 0)
+ branch
+ (format "%s~%s" branch to))))
+ (unless (magit-rev-verify-commit from)
+ (setq from (magit-git-string "rev-list" "--max-parents=0"
+ commit)))
+ (magit-log-setup-buffer (list (concat from ".." to))
+ (cons "--first-parent" args)
+ files nil commit))
+ (user-error "Could not find when %s was merged into %s: %s"
+ commit branch m)))))
+
+;;;; Limit Commands
+
+(defun magit-log-toggle-commit-limit ()
+ "Toggle the number of commits the current log buffer is limited to.
+If the number of commits is currently limited, then remove that
+limit. Otherwise set it to 256."
+ (interactive)
+ (magit-log-set-commit-limit (lambda (&rest _) nil)))
+
+(defun magit-log-double-commit-limit ()
+ "Double the number of commits the current log buffer is limited to."
+ (interactive)
+ (magit-log-set-commit-limit '*))
+
+(defun magit-log-half-commit-limit ()
+ "Half the number of commits the current log buffer is limited to."
+ (interactive)
+ (magit-log-set-commit-limit '/))
+
+(defun magit-log-set-commit-limit (fn)
+ (let* ((val magit-buffer-log-args)
+ (arg (--first (string-match "^-n\\([0-9]+\\)?$" it) val))
+ (num (and arg (string-to-number (match-string 1 arg))))
+ (num (if num (funcall fn num 2) 256)))
+ (setq val (delete arg val))
+ (setq magit-buffer-log-args
+ (if (and num (> num 0))
+ (cons (format "-n%i" num) val)
+ val)))
+ (magit-refresh))
+
+(defun magit-log-get-commit-limit ()
+ (and-let* ((str (--first (string-match "^-n\\([0-9]+\\)?$" it)
+ magit-buffer-log-args)))
+ (string-to-number (match-string 1 str))))
+
+;;;; Mode Commands
+
+(defun magit-log-bury-buffer (&optional arg)
+ "Bury the current buffer or the revision buffer in the same frame.
+Like `magit-mode-bury-buffer' (which see) but with a negative
+prefix argument instead bury the revision buffer, provided it
+is displayed in the current frame."
+ (interactive "p")
+ (if (< arg 0)
+ (let* ((buf (magit-get-mode-buffer 'magit-revision-mode))
+ (win (and buf (get-buffer-window buf (selected-frame)))))
+ (if win
+ (with-selected-window win
+ (with-current-buffer buf
+ (magit-mode-bury-buffer (> (abs arg) 1))))
+ (user-error "No revision buffer in this frame")))
+ (magit-mode-bury-buffer (> arg 1))))
+
+;;;###autoload
+(defun magit-log-move-to-parent (&optional n)
+ "Move to the Nth parent of the current commit."
+ (interactive "p")
+ (when (derived-mode-p 'magit-log-mode)
+ (when (magit-section-match 'commit)
+ (let* ((section (magit-current-section))
+ (parent-rev (format "%s^%s" (oref section value) (or n 1))))
+ (if-let ((parent-hash (magit-rev-parse "--short" parent-rev)))
+ (if-let ((parent (--first (equal (oref it value)
+ parent-hash)
+ (magit-section-siblings section 'next))))
+ (magit-section-goto parent)
+ (user-error
+ (substitute-command-keys
+ (concat "Parent " parent-hash " not found. Try typing "
+ "\\[magit-log-double-commit-limit] first"))))
+ (user-error "Parent %s does not exist" parent-rev))))))
+
+(defun magit-log-move-to-revision (rev)
+ "Read a revision and move to it in current log buffer.
+
+If the chosen reference or revision isn't being displayed in
+the current log buffer, then inform the user about that and do
+nothing else.
+
+If invoked outside any log buffer, then display the log buffer
+of the current repository first; creating it if necessary."
+ (interactive (list (magit-read-branch-or-commit "In log, jump to")))
+ (with-current-buffer
+ (cond ((derived-mode-p 'magit-log-mode)
+ (current-buffer))
+ ((and-let* ((buf (magit-get-mode-buffer 'magit-log-mode)))
+ (pop-to-buffer-same-window buf)))
+ (t
+ (apply #'magit-log-all-branches (magit-log-arguments))))
+ (unless (magit-log-goto-commit-section (magit-rev-abbrev rev))
+ (user-error "%s isn't visible in the current log buffer" rev))))
+
+;;;; Shortlog Commands
+
+;;;###autoload (autoload 'magit-shortlog "magit-log" nil t)
+(transient-define-prefix magit-shortlog ()
+ "Show a history summary."
+ :man-page "git-shortlog"
+ :value '("--numbered" "--summary")
+ ["Arguments"
+ ("-n" "Sort by number of commits" ("-n" "--numbered"))
+ ("-s" "Show commit count summary only" ("-s" "--summary"))
+ ("-e" "Show email addresses" ("-e" "--email"))
+ ("-g" "Group commits by" "--group="
+ :choices ("author" "committer" "trailer:"))
+ (7 "-f" "Format string" "--format=")
+ (7 "-w" "Linewrap" "-w" :class transient-option)]
+ ["Shortlog"
+ ("s" "since" magit-shortlog-since)
+ ("r" "range" magit-shortlog-range)])
+
+(defun magit-git-shortlog (rev args)
+ (let ((dir default-directory))
+ (with-current-buffer (get-buffer-create "*magit-shortlog*")
+ (setq default-directory dir)
+ (setq buffer-read-only t)
+ (let ((inhibit-read-only t))
+ (erase-buffer)
+ (save-excursion
+ (magit-git-insert "shortlog" args rev))
+ (switch-to-buffer-other-window (current-buffer))))))
+
+;;;###autoload
+(defun magit-shortlog-since (rev args)
+ "Show a history summary for commits since REV."
+ (interactive
+ (list (magit-read-branch-or-commit "Shortlog since" (magit-get-current-tag))
+ (transient-args 'magit-shortlog)))
+ (magit-git-shortlog (concat rev "..") args))
+
+;;;###autoload
+(defun magit-shortlog-range (rev-or-range args)
+ "Show a history summary for commit or range REV-OR-RANGE."
+ (interactive
+ (list (magit-read-range-or-commit "Shortlog for revision or range")
+ (transient-args 'magit-shortlog)))
+ (magit-git-shortlog rev-or-range args))
+
+;;; Log Mode
+
+(defvar magit-log-disable-graph-hack-args
+ '("-G" "--grep" "--author")
+ "Arguments which disable the graph speedup hack.")
+
+(defvar magit-log-mode-map
+ (let ((map (make-sparse-keymap)))
+ (set-keymap-parent map magit-mode-map)
+ (define-key map (kbd "C-c C-b") #'magit-go-backward)
+ (define-key map (kbd "C-c C-f") #'magit-go-forward)
+ (define-key map (kbd "C-c C-n") #'magit-log-move-to-parent)
+ (define-key map "j" #'magit-log-move-to-revision)
+ (define-key map "=" #'magit-log-toggle-commit-limit)
+ (define-key map "+" #'magit-log-double-commit-limit)
+ (define-key map "-" #'magit-log-half-commit-limit)
+ (define-key map "q" #'magit-log-bury-buffer)
+ map)
+ "Keymap for `magit-log-mode'.")
+
+(define-derived-mode magit-log-mode magit-mode "Magit Log"
+ "Mode for looking at Git log.
+
+This mode is documented in info node `(magit)Log Buffer'.
+
+\\<magit-mode-map>\
+Type \\[magit-refresh] to refresh the current buffer.
+Type \\[magit-visit-thing] or \\[magit-diff-show-or-scroll-up] \
+to visit the commit at point.
+
+Type \\[magit-branch] to see available branch commands.
+Type \\[magit-merge] to merge the branch or commit at point.
+Type \\[magit-cherry-pick] to apply the commit at point.
+Type \\[magit-reset] to reset `HEAD' to the commit at point.
+
+\\{magit-log-mode-map}"
+ :group 'magit-log
+ (hack-dir-local-variables-non-file-buffer)
+ (setq magit--imenu-item-types 'commit))
+
+(put 'magit-log-mode 'magit-log-default-arguments
+ '("--graph" "-n256" "--decorate"))
+
+(defun magit-log-setup-buffer (revs args files &optional locked focus)
+ (require 'magit)
+ (with-current-buffer
+ (magit-setup-buffer #'magit-log-mode locked
+ (magit-buffer-revisions revs)
+ (magit-buffer-log-args args)
+ (magit-buffer-log-files files))
+ (when (if focus
+ (magit-log-goto-commit-section focus)
+ (magit-log-goto-same-commit))
+ (magit-section-update-highlight))
+ (current-buffer)))
+
+(defun magit-log-refresh-buffer ()
+ (let ((revs magit-buffer-revisions)
+ (args magit-buffer-log-args)
+ (files magit-buffer-log-files))
+ (magit-set-header-line-format
+ (funcall magit-log-header-line-function revs args files))
+ (unless (length= files 1)
+ (setq args (remove "--follow" args)))
+ (when (and (car magit-log-remove-graph-args)
+ (--any-p (string-match-p
+ (concat "^" (regexp-opt magit-log-remove-graph-args)) it)
+ args))
+ (setq args (remove "--graph" args)))
+ (unless (member "--graph" args)
+ (setq args (remove "--color" args)))
+ (when-let* ((limit (magit-log-get-commit-limit))
+ (limit (* 2 limit)) ; increase odds for complete graph
+ (count (and (length= revs 1)
+ (> limit 1024) ; otherwise it's fast enough
+ (setq revs (car revs))
+ (not (string-search ".." revs))
+ (not (member revs '("--all" "--branches")))
+ (-none-p (lambda (arg)
+ (--any-p
+ (string-prefix-p it arg)
+ magit-log-disable-graph-hack-args))
+ args)
+ (magit-git-string "rev-list" "--count"
+ "--first-parent" args revs))))
+ (setq revs (if (< (string-to-number count) limit)
+ revs
+ (format "%s~%s..%s" revs limit revs))))
+ (magit-insert-section (logbuf)
+ (magit-insert-log revs args files))))
+
+(cl-defmethod magit-buffer-value (&context (major-mode magit-log-mode))
+ (append magit-buffer-revisions
+ (if (and magit-buffer-revisions magit-buffer-log-files)
+ (cons "--" magit-buffer-log-files)
+ magit-buffer-log-files)))
+
+(defun magit-log-header-line-arguments (revs args files)
+ "Return string describing some of the used arguments."
+ (mapconcat (lambda (arg)
+ (if (string-search " " arg)
+ (prin1 arg)
+ arg))
+ `("git" "log" ,@args ,@revs "--" ,@files)
+ " "))
+
+(defun magit-log-header-line-sentence (revs args files)
+ "Return string containing all arguments."
+ (concat "Commits in "
+ (mapconcat #'identity revs " ")
+ (and (member "--reverse" args)
+ " in reverse")
+ (and files (concat " touching "
+ (mapconcat #'identity files " ")))
+ (--some (and (string-prefix-p "-L" it)
+ (concat " " it))
+ args)))
+
+(defun magit-insert-log (revs &optional args files)
+ "Insert a log section.
+Do not add this to a hook variable."
+ (let ((magit-git-global-arguments
+ (remove "--literal-pathspecs" magit-git-global-arguments)))
+ (magit-git-wash (apply-partially #'magit-log-wash-log 'log)
+ "log"
+ (format "--format=%s%%h%%x0c%s%%x0c%s%%x0c%%aN%%x0c%s%%x0c%%s%s"
+ (if (and (member "--left-right" args)
+ (not (member "--graph" args)))
+ "%m "
+ "")
+ (if (member "--decorate" args) "%D" "")
+ (if (member "--show-signature" args)
+ (progn (setq args (remove "--show-signature" args)) "%G?")
+ "")
+ (if magit-log-margin-show-committer-date "%ct" "%at")
+ (if (member "++header" args)
+ (if (member "--graph" (setq args (remove "++header" args)))
+ (concat "\n" magit-log-revision-headers-format "\n")
+ (concat "\n" magit-log-revision-headers-format "\n"))
+ ""))
+ (progn
+ (--when-let (--first (string-match "^\\+\\+order=\\(.+\\)$" it) args)
+ (setq args (cons (format "--%s-order" (match-string 1 it))
+ (remove it args))))
+ (when (member "--decorate" args)
+ (setq args (cons "--decorate=full" (remove "--decorate" args))))
+ (when (member "--reverse" args)
+ (setq args (remove "--graph" args)))
+ (setq args (magit-diff--maybe-add-stat-arguments args))
+ args)
+ "--use-mailmap" "--no-prefix" revs "--" files)))
+
+(cl-defmethod magit-menu-common-value ((_section magit-commit-section))
+ (or (magit-diff--region-range)
+ (oref (magit-current-section) value)))
+
+(defvar magit-commit-section-map
+ (let ((map (make-sparse-keymap)))
+ ;; The second remapping overrides the first but we still get two menu
+ ;; items, though only one of them will be available at any given time.
+ (magit-menu-set map [magit-visit-thing]
+ #'magit-diff-range "Diff %x"
+ '(:visible (region-active-p)))
+ (magit-menu-set map [magit-visit-thing]
+ #'magit-show-commit "Show commit %x"
+ '(:visible (not (region-active-p))))
+ (magit-menu-set map [magit-cherry-apply]
+ #'magit-cherry-apply "Apply %x")
+ map)
+ "Keymap for `commit' sections.")
+
+(defvar magit-module-commit-section-map
+ (let ((map (make-sparse-keymap)))
+ (set-keymap-parent map magit-commit-section-map)
+ map)
+ "Keymap for `module-commit' sections.")
+
+(defconst magit-log-heading-re
+ ;; Note: A form feed instead of a null byte is used as the delimiter
+ ;; because using the latter interferes with the graph prefix when
+ ;; ++header is used.
+ (concat "^"
+ "\\(?4:[-_/|\\*o<>. ]*\\)" ; graph
+ "\\(?1:[0-9a-fA-F]+\\)? " ; hash
+ "\\(?3:[^ \n]+\\)? " ; refs
+ "\\(?7:[BGUXYREN]\\)? " ; gpg
+ "\\(?5:[^ \n]*\\) " ; author
+ ;; Note: Date is optional because, prior to Git v2.19.0,
+ ;; `git rebase -i --root` corrupts the root's author date.
+ "\\(?6:[^ \n]*\\) " ; date
+ "\\(?2:.*\\)$")) ; msg
+
+(defconst magit-log-cherry-re
+ (concat "^"
+ "\\(?8:[-+]\\) " ; cherry
+ "\\(?1:[0-9a-fA-F]+\\) " ; hash
+ "\\(?2:.*\\)$")) ; msg
+
+(defconst magit-log-module-re
+ (concat "^"
+ "\\(?:\\(?11:[<>]\\) \\)?" ; side
+ "\\(?1:[0-9a-fA-F]+\\) " ; hash
+ "\\(?2:.*\\)$")) ; msg
+
+(defconst magit-log-bisect-vis-re
+ (concat "^"
+ "\\(?4:[-_/|\\*o<>. ]*\\)" ; graph
+ "\\(?1:[0-9a-fA-F]+\\)?\0" ; hash
+ "\\(?3:[^\0\n]+\\)?\0" ; refs
+ "\\(?2:.*\\)$")) ; msg
+
+(defconst magit-log-bisect-log-re
+ (concat "^# "
+ "\\(?3:[^: \n]+:\\) " ; "refs"
+ "\\[\\(?1:[^]\n]+\\)\\] " ; hash
+ "\\(?2:.*\\)$")) ; msg
+
+(defconst magit-log-reflog-re
+ (concat "^"
+ "\\(?1:[^\0\n]+\\)\0" ; hash
+ "\\(?5:[^\0\n]*\\)\0" ; author
+ "\\(?:\\(?:[^@\n]+@{\\(?6:[^}\n]+\\)}\0" ; date
+ "\\(?10:merge \\|autosave \\|restart \\|[^:\n]+: \\)?" ; refsub
+ "\\(?2:.*\\)?\\)\\|\0\\)$")) ; msg
+
+(defconst magit-reflog-subject-re
+ (concat "\\(?1:[^ ]+\\) ?" ; command
+ "\\(?2:\\(?: ?-[^ ]+\\)+\\)?" ; option
+ "\\(?: ?(\\(?3:[^)]+\\))\\)?")) ; type
+
+(defconst magit-log-stash-re
+ (concat "^"
+ "\\(?1:[^\0\n]+\\)\0" ; "hash"
+ "\\(?5:[^\0\n]*\\)\0" ; author
+ "\\(?6:[^\0\n]+\\)\0" ; date
+ "\\(?2:.*\\)$")) ; msg
+
+(defvar magit-log-count nil)
+
+(defvar magit-log-format-message-function #'magit-log-propertize-keywords)
+
+(defun magit-log-wash-log (style args)
+ (setq args (flatten-tree args))
+ (when (and (member "--graph" args)
+ (member "--color" args))
+ (let ((ansi-color-apply-face-function
+ (lambda (beg end face)
+ (put-text-property beg end 'font-lock-face
+ (or face 'magit-log-graph)))))
+ (ansi-color-apply-on-region (point-min) (point-max))))
+ (when (eq style 'cherry)
+ (reverse-region (point-min) (point-max)))
+ (let ((magit-log-count 0))
+ (when (looking-at "^\\.\\.\\.")
+ (magit-delete-line))
+ (magit-wash-sequence (apply-partially #'magit-log-wash-rev style
+ (magit-abbrev-length)))
+ (if (derived-mode-p 'magit-log-mode 'magit-reflog-mode)
+ (when (eq magit-log-count (magit-log-get-commit-limit))
+ (magit-insert-section (longer)
+ (insert-text-button
+ (substitute-command-keys
+ (format "Type \\<%s>\\[%s] to show more history"
+ 'magit-log-mode-map
+ 'magit-log-double-commit-limit))
+ 'action (lambda (_button)
+ (magit-log-double-commit-limit))
+ 'follow-link t
+ 'mouse-face 'magit-section-highlight)))
+ (insert ?\n))))
+
+(cl-defun magit-log-wash-rev (style abbrev)
+ (when (derived-mode-p 'magit-log-mode 'magit-reflog-mode)
+ (cl-incf magit-log-count))
+ (looking-at (pcase style
+ ('log magit-log-heading-re)
+ ('cherry magit-log-cherry-re)
+ ('module magit-log-module-re)
+ ('reflog magit-log-reflog-re)
+ ('stash magit-log-stash-re)
+ ('bisect-vis magit-log-bisect-vis-re)
+ ('bisect-log magit-log-bisect-log-re)))
+ (magit-bind-match-strings
+ (hash msg refs graph author date gpg cherry _ refsub side) nil
+ (setq msg (substring-no-properties msg))
+ (when refs
+ (setq refs (substring-no-properties refs)))
+ (let ((align (or (eq style 'cherry)
+ (not (member "--stat" magit-buffer-log-args))))
+ (non-graph-re (if (eq style 'bisect-vis)
+ magit-log-bisect-vis-re
+ magit-log-heading-re)))
+ (magit-delete-line)
+ ;; If the reflog entries have been pruned, the output of `git
+ ;; reflog show' includes a partial line that refers to the hash
+ ;; of the youngest expired reflog entry.
+ (when (and (eq style 'reflog) (not date))
+ (cl-return-from magit-log-wash-rev t))
+ (magit-insert-section section (commit hash)
+ (pcase style
+ ('stash (oset section type 'stash))
+ ('module (oset section type 'module-commit))
+ ('bisect-log (setq hash (magit-rev-parse "--short" hash))))
+ (setq hash (propertize hash 'font-lock-face
+ (pcase (and gpg (aref gpg 0))
+ (?G 'magit-signature-good)
+ (?B 'magit-signature-bad)
+ (?U 'magit-signature-untrusted)
+ (?X 'magit-signature-expired)
+ (?Y 'magit-signature-expired-key)
+ (?R 'magit-signature-revoked)
+ (?E 'magit-signature-error)
+ (?N 'magit-hash)
+ (_ 'magit-hash))))
+ (when cherry
+ (when (and (derived-mode-p 'magit-refs-mode)
+ magit-refs-show-commit-count)
+ (insert (make-string (1- magit-refs-focus-column-width) ?\s)))
+ (insert (propertize cherry 'font-lock-face
+ (if (string= cherry "-")
+ 'magit-cherry-equivalent
+ 'magit-cherry-unmatched)))
+ (insert ?\s))
+ (when side
+ (insert (propertize side 'font-lock-face
+ (if (string= side "<")
+ 'magit-cherry-equivalent
+ 'magit-cherry-unmatched)))
+ (insert ?\s))
+ (when align
+ (insert hash ?\s))
+ (when graph
+ (insert graph))
+ (unless align
+ (insert hash ?\s))
+ (when (and refs (not magit-log-show-refname-after-summary))
+ (insert (magit-format-ref-labels refs) ?\s))
+ (when (eq style 'reflog)
+ (insert (format "%-2s " (1- magit-log-count)))
+ (when refsub
+ (insert (magit-reflog-format-subject
+ (substring refsub 0
+ (if (string-search ":" refsub) -2 -1))))))
+ (when msg
+ (insert (funcall magit-log-format-message-function hash msg)))
+ (when (and refs magit-log-show-refname-after-summary)
+ (insert ?\s)
+ (insert (magit-format-ref-labels refs)))
+ (insert ?\n)
+ (when (memq style '(log reflog stash))
+ (goto-char (line-beginning-position))
+ (when (and refsub
+ (string-match "\\`\\([^ ]\\) \\+\\(..\\)\\(..\\)" date))
+ (setq date (+ (string-to-number (match-string 1 date))
+ (* (string-to-number (match-string 2 date)) 60 60)
+ (* (string-to-number (match-string 3 date)) 60))))
+ (save-excursion
+ (backward-char)
+ (magit-log-format-margin hash author date)))
+ (when (and (eq style 'cherry)
+ (magit-buffer-margin-p))
+ (save-excursion
+ (backward-char)
+ (apply #'magit-log-format-margin hash
+ (split-string (magit-rev-format "%aN%x00%ct" hash) "\0"))))
+ (when (and graph
+ (not (eobp))
+ (not (looking-at non-graph-re)))
+ (when (looking-at "")
+ (magit-insert-heading)
+ (delete-char 1)
+ (magit-insert-section (commit-header)
+ (forward-line)
+ (magit-insert-heading)
+ (re-search-forward "")
+ (backward-delete-char 1)
+ (forward-char)
+ (insert ?\n))
+ (delete-char 1))
+ (if (looking-at "^\\(---\\|\n\s\\|\ndiff\\)")
+ (let ((limit (save-excursion
+ (and (re-search-forward non-graph-re nil t)
+ (match-beginning 0)))))
+ (unless (oref magit-insert-section--current content)
+ (magit-insert-heading))
+ (delete-char (if (looking-at "\n") 1 4))
+ (magit-diff-wash-diffs (list "--stat") limit))
+ (when align
+ (setq align (make-string (1+ abbrev) ? )))
+ (when (and (not (eobp)) (not (looking-at non-graph-re)))
+ (when align
+ (setq align (make-string (1+ abbrev) ? )))
+ (while (and (not (eobp)) (not (looking-at non-graph-re)))
+ (when align
+ (save-excursion (insert align)))
+ (magit-make-margin-overlay)
+ (forward-line))
+ ;; When `--format' is used and its value isn't one of the
+ ;; predefined formats, then `git-log' does not insert a
+ ;; separator line.
+ (save-excursion
+ (forward-line -1)
+ (looking-at "[-_/|\\*o<>. ]*"))
+ (setq graph (match-string 0))
+ (unless (string-match-p "[/\\.]" graph)
+ (insert graph ?\n))))))))
+ t)
+
+(defun magit-log-propertize-keywords (_rev msg)
+ (let ((boundary 0))
+ (when (string-match "^\\(?:squash\\|fixup\\)! " msg boundary)
+ (setq boundary (match-end 0))
+ (magit--put-face (match-beginning 0) (1- boundary)
+ 'magit-keyword-squash msg))
+ (when magit-log-highlight-keywords
+ (while (string-match "\\[[^[]*?]" msg boundary)
+ (setq boundary (match-end 0))
+ (magit--put-face (match-beginning 0) boundary
+ 'magit-keyword msg))))
+ msg)
+
+(defun magit-log-maybe-show-more-commits (section)
+ "When point is at the end of a log buffer, insert more commits.
+
+Log buffers end with a button \"Type + to show more history\".
+When the use of a section movement command puts point on that
+button, then automatically show more commits, without the user
+having to press \"+\".
+
+This function is called by `magit-section-movement-hook' and
+exists mostly for backward compatibility reasons."
+ (when (and (eq (oref section type) 'longer)
+ magit-log-auto-more)
+ (magit-log-double-commit-limit)
+ (forward-line -1)
+ (magit-section-forward)))
+
+(add-hook 'magit-section-movement-hook #'magit-log-maybe-show-more-commits)
+
+(defvar magit--update-revision-buffer nil)
+
+(defun magit-log-maybe-update-revision-buffer (&optional _)
+ "When moving in a log or cherry buffer, update the revision buffer.
+If there is no revision buffer in the same frame, then do nothing."
+ (when (derived-mode-p 'magit-log-mode 'magit-cherry-mode 'magit-reflog-mode)
+ (magit--maybe-update-revision-buffer)))
+
+(add-hook 'magit-section-movement-hook #'magit-log-maybe-update-revision-buffer)
+
+(defun magit--maybe-update-revision-buffer ()
+ (when-let* ((commit (magit-section-value-if 'commit))
+ (buffer (magit-get-mode-buffer 'magit-revision-mode nil t)))
+ (if magit--update-revision-buffer
+ (setq magit--update-revision-buffer (list commit buffer))
+ (setq magit--update-revision-buffer (list commit buffer))
+ (run-with-idle-timer
+ magit-update-other-window-delay nil
+ (let ((args (let ((magit-direct-use-buffer-arguments 'selected))
+ (magit-show-commit--arguments))))
+ (lambda ()
+ (pcase-let ((`(,rev ,buf) magit--update-revision-buffer))
+ (setq magit--update-revision-buffer nil)
+ (when (buffer-live-p buf)
+ (let ((magit-display-buffer-noselect t))
+ (apply #'magit-show-commit rev args))))
+ (setq magit--update-revision-buffer nil)))))))
+
+(defvar magit--update-blob-buffer nil)
+
+(defun magit-log-maybe-update-blob-buffer (&optional _)
+ "When moving in a log or cherry buffer, update the blob buffer.
+If there is no blob buffer in the same frame, then do nothing."
+ (when (derived-mode-p 'magit-log-mode 'magit-cherry-mode 'magit-reflog-mode)
+ (magit--maybe-update-blob-buffer)))
+
+(defun magit--maybe-update-blob-buffer ()
+ (when-let* ((commit (magit-section-value-if 'commit))
+ (buffer (--first (with-current-buffer it
+ (eq revert-buffer-function
+ 'magit-revert-rev-file-buffer))
+ (mapcar #'window-buffer (window-list)))))
+ (if magit--update-blob-buffer
+ (setq magit--update-blob-buffer (list commit buffer))
+ (setq magit--update-blob-buffer (list commit buffer))
+ (run-with-idle-timer
+ magit-update-other-window-delay nil
+ (lambda ()
+ (pcase-let ((`(,rev ,buf) magit--update-blob-buffer))
+ (setq magit--update-blob-buffer nil)
+ (when (buffer-live-p buf)
+ (with-selected-window (get-buffer-window buf)
+ (with-current-buffer buf
+ (save-excursion
+ (magit-blob-visit (list (magit-rev-parse rev)
+ (magit-file-relative-name
+ magit-buffer-file-name)))))))))))))
+
+(defun magit-log-goto-commit-section (rev)
+ (let ((abbrev (magit-rev-format "%h" rev)))
+ (when-let ((section (--first (equal (oref it value) abbrev)
+ (oref magit-root-section children))))
+ (goto-char (oref section start)))))
+
+(defun magit-log-goto-same-commit ()
+ (when (and magit-previous-section
+ (magit-section-match '(commit branch)
+ magit-previous-section))
+ (magit-log-goto-commit-section (oref magit-previous-section value))))
+
+;;; Log Margin
+
+(defvar-local magit-log-margin-show-shortstat nil)
+
+(defun magit-toggle-log-margin-style ()
+ "Toggle between the regular and the shortstat margin style.
+The shortstat style is experimental and rather slow."
+ (interactive)
+ (setq magit-log-margin-show-shortstat
+ (not magit-log-margin-show-shortstat))
+ (magit-set-buffer-margin nil t))
+
+(defun magit-log-format-margin (rev author date)
+ (when (magit-margin-option)
+ (if magit-log-margin-show-shortstat
+ (magit-log-format-shortstat-margin rev)
+ (magit-log-format-author-margin author date))))
+
+(defun magit-log-format-author-margin (author date &optional previous-line)
+ (pcase-let ((`(,_ ,style ,width ,details ,details-width)
+ (or magit-buffer-margin
+ (symbol-value (magit-margin-option)))))
+ (magit-make-margin-overlay
+ (concat (and details
+ (concat (magit--propertize-face
+ (truncate-string-to-width
+ (or author "")
+ details-width
+ nil ?\s
+ (if (char-displayable-p ?…) "…" ">"))
+ 'magit-log-author)
+ " "))
+ (magit--propertize-face
+ (if (stringp style)
+ (format-time-string
+ style
+ (seconds-to-time (string-to-number date)))
+ (pcase-let* ((abbr (eq style 'age-abbreviated))
+ (`(,cnt ,unit) (magit--age date abbr)))
+ (format (format (if abbr "%%2i%%-%ic" "%%2i %%-%is")
+ (- width (if details (1+ details-width) 0)))
+ cnt unit)))
+ 'magit-log-date))
+ previous-line)))
+
+(defun magit-log-format-shortstat-margin (rev)
+ (magit-make-margin-overlay
+ (if-let ((line (and rev (magit-git-string
+ "show" "--format=" "--shortstat" rev))))
+ (if (string-match "\
+\\([0-9]+\\) files? changed, \
+\\(?:\\([0-9]+\\) insertions?(\\+)\\)?\
+\\(?:\\(?:, \\)?\\([0-9]+\\) deletions?(-)\\)?\\'" line)
+ (magit-bind-match-strings (files add del) line
+ (format
+ "%5s %5s%4s"
+ (if add
+ (magit--propertize-face (format "%s+" add)
+ 'magit-diffstat-added)
+ "")
+ (if del
+ (magit--propertize-face (format "%s-" del)
+ 'magit-diffstat-removed)
+ "")
+ files))
+ "")
+ "")))
+
+(defun magit-log-margin-width (style details details-width)
+ (if magit-log-margin-show-shortstat
+ 16
+ (+ (if details (1+ details-width) 0)
+ (if (stringp style)
+ (length (format-time-string style))
+ (+ 2 ; two digits
+ 1 ; trailing space
+ (if (eq style 'age-abbreviated)
+ 1 ; single character
+ (+ 1 ; gap after digits
+ (apply #'max (--map (max (length (nth 1 it))
+ (length (nth 2 it)))
+ magit--age-spec)))))))))
+
+;;; Select Mode
+
+(defvar magit-log-select-mode-map
+ (let ((map (make-sparse-keymap)))
+ (set-keymap-parent map magit-log-mode-map)
+ (define-key map (kbd "C-c C-b") #'undefined)
+ (define-key map (kbd "C-c C-f") #'undefined)
+ (define-key map (kbd ".") #'magit-log-select-pick)
+ (define-key map (kbd "e") #'magit-log-select-pick)
+ (define-key map (kbd "C-c C-c") #'magit-log-select-pick)
+ (define-key map (kbd "q") #'magit-log-select-quit)
+ (define-key map (kbd "C-c C-k") #'magit-log-select-quit)
+ map)
+ "Keymap for `magit-log-select-mode'.")
+
+(put 'magit-log-select-pick :advertised-binding [?\C-c ?\C-c])
+(put 'magit-log-select-quit :advertised-binding [?\C-c ?\C-k])
+
+(define-derived-mode magit-log-select-mode magit-log-mode "Magit Select"
+ "Mode for selecting a commit from history.
+
+This mode is documented in info node `(magit)Select from Log'.
+
+\\<magit-mode-map>\
+Type \\[magit-refresh] to refresh the current buffer.
+Type \\[magit-visit-thing] or \\[magit-diff-show-or-scroll-up] \
+to visit the commit at point.
+
+\\<magit-log-select-mode-map>\
+Type \\[magit-log-select-pick] to select the commit at point.
+Type \\[magit-log-select-quit] to abort without selecting a commit."
+ :group 'magit-log
+ (hack-dir-local-variables-non-file-buffer))
+
+(put 'magit-log-select-mode 'magit-log-default-arguments
+ '("--graph" "-n256" "--decorate"))
+
+(defun magit-log-select-setup-buffer (revs args)
+ (magit-setup-buffer #'magit-log-select-mode nil
+ (magit-buffer-revisions revs)
+ (magit-buffer-log-args args)))
+
+(defun magit-log-select-refresh-buffer ()
+ (magit-insert-section (logbuf)
+ (magit-insert-log magit-buffer-revisions
+ magit-buffer-log-args)))
+
+(cl-defmethod magit-buffer-value (&context (major-mode magit-log-select-mode))
+ magit-buffer-revisions)
+
+(defvar-local magit-log-select-pick-function nil)
+(defvar-local magit-log-select-quit-function nil)
+
+(defun magit-log-select (pick &optional msg quit branch args initial)
+ (declare (indent defun))
+ (unless initial
+ (setq initial (magit-commit-at-point)))
+ (magit-log-select-setup-buffer
+ (or branch (magit-get-current-branch) "HEAD")
+ (append args
+ (car (magit-log--get-value 'magit-log-select-mode
+ magit-direct-use-buffer-arguments))))
+ (when initial
+ (magit-log-goto-commit-section initial))
+ (setq magit-log-select-pick-function pick)
+ (setq magit-log-select-quit-function quit)
+ (when magit-log-select-show-usage
+ (let ((pick (propertize (substitute-command-keys
+ "\\[magit-log-select-pick]")
+ 'font-lock-face
+ 'magit-header-line-key))
+ (quit (propertize (substitute-command-keys
+ "\\[magit-log-select-quit]")
+ 'font-lock-face
+ 'magit-header-line-key)))
+ (setq msg (format-spec
+ (if msg
+ (if (string-suffix-p "," msg)
+ (concat msg " or %q to abort")
+ msg)
+ "Type %p to select commit at point, or %q to abort")
+ `((?p . ,pick)
+ (?q . ,quit)))))
+ (magit--add-face-text-property
+ 0 (length msg) 'magit-header-line-log-select t msg)
+ (when (memq magit-log-select-show-usage '(both header-line))
+ (magit-set-header-line-format msg))
+ (when (memq magit-log-select-show-usage '(both echo-area))
+ (message "%s" (substring-no-properties msg)))))
+
+(defun magit-log-select-pick ()
+ "Select the commit at point and act on it.
+Call `magit-log-select-pick-function' with the selected
+commit as argument."
+ (interactive)
+ (let ((fun magit-log-select-pick-function)
+ (rev (magit-commit-at-point)))
+ (magit-mode-bury-buffer 'kill)
+ (funcall fun rev)))
+
+(defun magit-log-select-quit ()
+ "Abort selecting a commit, don't act on any commit.
+Call `magit-log-select-quit-function' if set."
+ (interactive)
+ (let ((fun magit-log-select-quit-function))
+ (magit-mode-bury-buffer 'kill)
+ (when fun (funcall fun))))
+
+;;; Cherry Mode
+
+(defvar magit-cherry-mode-map
+ (let ((map (make-sparse-keymap)))
+ (set-keymap-parent map magit-mode-map)
+ (define-key map "q" #'magit-log-bury-buffer)
+ (define-key map "L" #'magit-margin-settings)
+ map)
+ "Keymap for `magit-cherry-mode'.")
+
+(define-derived-mode magit-cherry-mode magit-mode "Magit Cherry"
+ "Mode for looking at commits not merged upstream.
+
+\\<magit-mode-map>\
+Type \\[magit-refresh] to refresh the current buffer.
+Type \\[magit-visit-thing] or \\[magit-diff-show-or-scroll-up] \
+to visit the commit at point.
+
+Type \\[magit-cherry-pick] to apply the commit at point.
+
+\\{magit-cherry-mode-map}"
+ :group 'magit-log
+ (hack-dir-local-variables-non-file-buffer)
+ (setq magit--imenu-group-types 'cherries))
+
+(defun magit-cherry-setup-buffer (head upstream)
+ (magit-setup-buffer #'magit-cherry-mode nil
+ (magit-buffer-refname head)
+ (magit-buffer-upstream upstream)
+ (magit-buffer-range (concat upstream ".." head))))
+
+(defun magit-cherry-refresh-buffer ()
+ (magit-insert-section (cherry)
+ (magit-run-section-hook 'magit-cherry-sections-hook)))
+
+(cl-defmethod magit-buffer-value (&context (major-mode magit-cherry-mode))
+ magit-buffer-range)
+
+;;;###autoload
+(defun magit-cherry (head upstream)
+ "Show commits in a branch that are not merged in the upstream branch."
+ (interactive
+ (let ((head (magit-read-branch "Cherry head")))
+ (list head (magit-read-other-branch "Cherry upstream" head
+ (magit-get-upstream-branch head)))))
+ (require 'magit)
+ (magit-cherry-setup-buffer head upstream))
+
+(defun magit-insert-cherry-headers ()
+ "Insert headers appropriate for `magit-cherry-mode' buffers."
+ (let ((branch (propertize magit-buffer-refname
+ 'font-lock-face 'magit-branch-local))
+ (upstream (propertize magit-buffer-upstream 'font-lock-face
+ (if (magit-local-branch-p magit-buffer-upstream)
+ 'magit-branch-local
+ 'magit-branch-remote))))
+ (magit-insert-head-branch-header branch)
+ (magit-insert-upstream-branch-header branch upstream "Upstream: ")
+ (insert ?\n)))
+
+(defun magit-insert-cherry-commits ()
+ "Insert commit sections into a `magit-cherry-mode' buffer."
+ (magit-insert-section (cherries)
+ (magit-insert-heading "Cherry commits:")
+ (magit-git-wash (apply-partially #'magit-log-wash-log 'cherry)
+ "cherry" "-v" "--abbrev"
+ magit-buffer-upstream
+ magit-buffer-refname)))
+
+;;; Log Sections
+;;;; Standard Log Sections
+
+(defvar magit-log-section-map
+ (let ((map (make-sparse-keymap)))
+ (magit-menu-set map [magit-visit-thing] #'magit-diff-dwim "Visit diff")
+ map)
+ "Keymap for log sections.
+The classes `magit-{unpulled,unpushed,unmerged}-section' derive
+from the abstract `magit-log-section' class. Accordingly this
+keymap is the parent of their keymaps.")
+
+(defvar magit-unpulled-section-map
+ (let ((map (make-sparse-keymap)))
+ (set-keymap-parent map magit-log-section-map)
+ map)
+ "Keymap for `unpulled' sections.")
+
+(cl-defmethod magit-section-ident-value ((section magit-unpulled-section))
+ "\"..@{push}\" cannot be used as the value because that is
+ambiguous if `push.default' does not allow a 1:1 mapping, and
+many commands would fail because of that. But here that does
+not matter and we need an unique value so we use that string
+in the pushremote case."
+ (let ((value (oref section value)))
+ (if (equal value "..@{upstream}") value "..@{push}")))
+
+(magit-define-section-jumper magit-jump-to-unpulled-from-upstream
+ "Unpulled from @{upstream}" unpulled "..@{upstream}")
+
+(defun magit-insert-unpulled-from-upstream ()
+ "Insert commits that haven't been pulled from the upstream yet."
+ (when-let ((upstream (magit-get-upstream-branch)))
+ (magit-insert-section (unpulled "..@{upstream}" t)
+ (magit-insert-heading
+ (format (propertize "Unpulled from %s."
+ 'font-lock-face 'magit-section-heading)
+ upstream))
+ (magit-insert-log "..@{upstream}" magit-buffer-log-args)
+ (magit-log-insert-child-count))))
+
+(magit-define-section-jumper magit-jump-to-unpulled-from-pushremote
+ "Unpulled from <push-remote>" unpulled
+ (concat ".." (magit-get-push-branch)))
+
+(defun magit-insert-unpulled-from-pushremote ()
+ "Insert commits that haven't been pulled from the push-remote yet."
+ (--when-let (magit-get-push-branch)
+ (when (magit--insert-pushremote-log-p)
+ (magit-insert-section (unpulled (concat ".." it) t)
+ (magit-insert-heading
+ (format (propertize "Unpulled from %s."
+ 'font-lock-face 'magit-section-heading)
+ (propertize it 'font-lock-face 'magit-branch-remote)))
+ (magit-insert-log (concat ".." it) magit-buffer-log-args)
+ (magit-log-insert-child-count)))))
+
+(defvar magit-unpushed-section-map
+ (let ((map (make-sparse-keymap)))
+ (set-keymap-parent map magit-log-section-map)
+ map)
+ "Keymap for `unpushed' sections.")
+
+(cl-defmethod magit-section-ident-value ((section magit-unpushed-section))
+ "\"..@{push}\" cannot be used as the value because that is
+ambiguous if `push.default' does not allow a 1:1 mapping, and
+many commands would fail because of that. But here that does
+not matter and we need an unique value so we use that string
+in the pushremote case."
+ (let ((value (oref section value)))
+ (if (equal value "@{upstream}..") value "@{push}..")))
+
+(magit-define-section-jumper magit-jump-to-unpushed-to-upstream
+ "Unpushed to @{upstream}" unpushed "@{upstream}..")
+
+(defun magit-insert-unpushed-to-upstream-or-recent ()
+ "Insert section showing unpushed or other recent commits.
+If an upstream is configured for the current branch and it is
+behind of the current branch, then show the commits that have
+not yet been pushed into the upstream branch. If no upstream is
+configured or if the upstream is not behind of the current branch,
+then show the last `magit-log-section-commit-count' commits."
+ (let ((upstream (magit-get-upstream-branch)))
+ (if (or (not upstream)
+ (magit-rev-ancestor-p "HEAD" upstream))
+ (magit-insert-recent-commits 'unpushed "@{upstream}..")
+ (magit-insert-unpushed-to-upstream))))
+
+(defun magit-insert-unpushed-to-upstream ()
+ "Insert commits that haven't been pushed to the upstream yet."
+ (when (magit-git-success "rev-parse" "@{upstream}")
+ (magit-insert-section (unpushed "@{upstream}..")
+ (magit-insert-heading
+ (format (propertize "Unmerged into %s."
+ 'font-lock-face 'magit-section-heading)
+ (magit-get-upstream-branch)))
+ (magit-insert-log "@{upstream}.." magit-buffer-log-args)
+ (magit-log-insert-child-count))))
+
+(defun magit-insert-recent-commits (&optional type value)
+ "Insert section showing recent commits.
+Show the last `magit-log-section-commit-count' commits."
+ (let* ((start (format "HEAD~%s" magit-log-section-commit-count))
+ (range (and (magit-rev-verify start)
+ (concat start "..HEAD"))))
+ (magit-insert-section ((eval (or type 'recent))
+ (or value range)
+ t)
+ (magit-insert-heading "Recent commits")
+ (magit-insert-log range
+ (cons (format "-n%d" magit-log-section-commit-count)
+ (--remove (string-prefix-p "-n" it)
+ magit-buffer-log-args))))))
+
+(magit-define-section-jumper magit-jump-to-unpushed-to-pushremote
+ "Unpushed to <push-remote>" unpushed
+ (concat (magit-get-push-branch) ".."))
+
+(defun magit-insert-unpushed-to-pushremote ()
+ "Insert commits that haven't been pushed to the push-remote yet."
+ (--when-let (magit-get-push-branch)
+ (when (magit--insert-pushremote-log-p)
+ (magit-insert-section (unpushed (concat it "..") t)
+ (magit-insert-heading
+ (format (propertize "Unpushed to %s."
+ 'font-lock-face 'magit-section-heading)
+ (propertize it 'font-lock-face 'magit-branch-remote)))
+ (magit-insert-log (concat it "..") magit-buffer-log-args)
+ (magit-log-insert-child-count)))))
+
+(defun magit--insert-pushremote-log-p ()
+ (magit--with-refresh-cache
+ (cons default-directory 'magit--insert-pushremote-log-p)
+ (not (and (equal (magit-get-push-branch)
+ (magit-get-upstream-branch))
+ (or (memq 'magit-insert-unpulled-from-upstream
+ magit-status-sections-hook)
+ (memq 'magit-insert-unpulled-from-upstream-or-recent
+ magit-status-sections-hook))))))
+
+(defun magit-log-insert-child-count ()
+ (when magit-section-show-child-count
+ (let ((count (length (oref magit-insert-section--current children))))
+ (when (> count 0)
+ (when (eq count (magit-log-get-commit-limit))
+ (setq count (format "%s+" count)))
+ (save-excursion
+ (goto-char (- (oref magit-insert-section--current content) 2))
+ (insert (format " (%s)" count))
+ (delete-char 1))))))
+
+;;;; Auxiliary Log Sections
+
+(defun magit-insert-unpulled-cherries ()
+ "Insert section showing unpulled commits.
+Like `magit-insert-unpulled-from-upstream' but prefix each commit
+which has not been applied yet (i.e. a commit with a patch-id
+not shared with any local commit) with \"+\", and all others with
+\"-\"."
+ (when (magit-git-success "rev-parse" "@{upstream}")
+ (magit-insert-section (unpulled "..@{upstream}")
+ (magit-insert-heading "Unpulled commits:")
+ (magit-git-wash (apply-partially #'magit-log-wash-log 'cherry)
+ "cherry" "-v" (magit-abbrev-arg)
+ (magit-get-current-branch) "@{upstream}"))))
+
+(defun magit-insert-unpushed-cherries ()
+ "Insert section showing unpushed commits.
+Like `magit-insert-unpushed-to-upstream' but prefix each commit
+which has not been applied to upstream yet (i.e. a commit with
+a patch-id not shared with any upstream commit) with \"+\", and
+all others with \"-\"."
+ (when (magit-git-success "rev-parse" "@{upstream}")
+ (magit-insert-section (unpushed "@{upstream}..")
+ (magit-insert-heading "Unpushed commits:")
+ (magit-git-wash (apply-partially #'magit-log-wash-log 'cherry)
+ "cherry" "-v" (magit-abbrev-arg) "@{upstream}"))))
+
+;;; _
+(provide 'magit-log)
+;;; magit-log.el ends here
diff --git a/elpa/magit-20220503.1245/magit-log.elc b/elpa/magit-20220503.1245/magit-log.elc
new file mode 100644
index 0000000..07a45b0
--- /dev/null
+++ b/elpa/magit-20220503.1245/magit-log.elc
Binary files differ
diff --git a/elpa/magit-20220503.1245/magit-margin.el b/elpa/magit-20220503.1245/magit-margin.el
new file mode 100644
index 0000000..4eb722a
--- /dev/null
+++ b/elpa/magit-20220503.1245/magit-margin.el
@@ -0,0 +1,239 @@
+;;; magit-margin.el --- Margins in Magit buffers -*- lexical-binding:t -*-
+
+;; Copyright (C) 2008-2022 The Magit Project Contributors
+
+;; Author: Jonas Bernoulli <jonas@bernoul.li>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+
+;; SPDX-License-Identifier: GPL-3.0-or-later
+
+;; Magit 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.
+;;
+;; Magit 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 Magit. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This library implements support for showing additional information
+;; in the margins of Magit buffers. Currently this is only used for
+;; commits, for which the committer date or age, and optionally the
+;; author name are shown.
+
+;;; Code:
+
+(require 'magit-base)
+(require 'magit-transient)
+(require 'magit-mode)
+
+(defgroup magit-margin nil
+ "Information Magit displays in the margin.
+
+You can change the STYLE and AUTHOR-WIDTH of all `magit-*-margin'
+options to the same values by customizing `magit-log-margin'
+*before* `magit' is loaded. If you do that, then the respective
+values for the other options will default to what you have set
+for that variable. Likewise if you set `magit-log-margin's INIT
+to nil, then that is used in the default of all other options. But
+setting it to t, i.e. re-enforcing the default for that option,
+does not carry to other options."
+ :link '(info-link "(magit)Log Margin")
+ :group 'magit-log)
+
+(defvar-local magit-buffer-margin nil)
+(put 'magit-buffer-margin 'permanent-local t)
+
+(defvar-local magit-set-buffer-margin-refresh nil)
+
+(defvar magit--age-spec)
+
+;;; Commands
+
+(transient-define-prefix magit-margin-settings ()
+ "Change what information is displayed in the margin."
+ :info-manual "(magit) Log Margin"
+ ["Margin"
+ ("L" "Toggle visibility" magit-toggle-margin)
+ ("l" "Cycle style" magit-cycle-margin-style)
+ ("d" "Toggle details" magit-toggle-margin-details)
+ ("v" "Change verbosity" magit-refs-set-show-commit-count
+ :if-derived magit-refs-mode)])
+
+(defun magit-toggle-margin ()
+ "Show or hide the Magit margin."
+ (interactive)
+ (unless (magit-margin-option)
+ (user-error "Magit margin isn't supported in this buffer"))
+ (setcar magit-buffer-margin (not (magit-buffer-margin-p)))
+ (magit-set-buffer-margin))
+
+(defvar magit-margin-default-time-format nil
+ "See https://github.com/magit/magit/pull/4605.")
+
+(defun magit-cycle-margin-style ()
+ "Cycle style used for the Magit margin."
+ (interactive)
+ (unless (magit-margin-option)
+ (user-error "Magit margin isn't supported in this buffer"))
+ ;; This is only suitable for commit margins (there are not others).
+ (setf (cadr magit-buffer-margin)
+ (pcase (cadr magit-buffer-margin)
+ ('age 'age-abbreviated)
+ ('age-abbreviated
+ (let ((default (or magit-margin-default-time-format
+ (cadr (symbol-value (magit-margin-option))))))
+ (if (stringp default) default "%Y-%m-%d %H:%M ")))
+ (_ 'age)))
+ (magit-set-buffer-margin nil t))
+
+(defun magit-toggle-margin-details ()
+ "Show or hide details in the Magit margin."
+ (interactive)
+ (unless (magit-margin-option)
+ (user-error "Magit margin isn't supported in this buffer"))
+ (setf (nth 3 magit-buffer-margin)
+ (not (nth 3 magit-buffer-margin)))
+ (magit-set-buffer-margin nil t))
+
+;;; Core
+
+(defun magit-buffer-margin-p ()
+ (car magit-buffer-margin))
+
+(defun magit-margin-option ()
+ (pcase major-mode
+ ('magit-cherry-mode 'magit-cherry-margin)
+ ('magit-log-mode 'magit-log-margin)
+ ('magit-log-select-mode 'magit-log-select-margin)
+ ('magit-reflog-mode 'magit-reflog-margin)
+ ('magit-refs-mode 'magit-refs-margin)
+ ('magit-stashes-mode 'magit-stashes-margin)
+ ('magit-status-mode 'magit-status-margin)
+ ('forge-notifications-mode 'magit-status-margin)))
+
+(defun magit-set-buffer-margin (&optional reset refresh)
+ (when-let ((option (magit-margin-option)))
+ (let* ((default (symbol-value option))
+ (default-width (nth 2 default)))
+ (when (or reset (not magit-buffer-margin))
+ (setq magit-buffer-margin (copy-sequence default)))
+ (pcase-let ((`(,enable ,style ,_width ,details ,details-width)
+ magit-buffer-margin))
+ (when (functionp default-width)
+ (setf (nth 2 magit-buffer-margin)
+ (funcall default-width style details details-width)))
+ (dolist (window (get-buffer-window-list nil nil 0))
+ (with-selected-window window
+ (magit-set-window-margin window)
+ (if enable
+ (add-hook 'window-configuration-change-hook
+ #'magit-set-window-margin nil t)
+ (remove-hook 'window-configuration-change-hook
+ #'magit-set-window-margin t))))
+ (when (and enable (or refresh magit-set-buffer-margin-refresh))
+ (magit-refresh-buffer))))))
+
+(defun magit-set-window-margin (&optional window)
+ (when (or window (setq window (get-buffer-window)))
+ (with-selected-window window
+ (set-window-margins
+ nil (car (window-margins))
+ (and (magit-buffer-margin-p)
+ (nth 2 magit-buffer-margin))))))
+
+(defun magit-make-margin-overlay (&optional string previous-line)
+ (if previous-line
+ (save-excursion
+ (forward-line -1)
+ (magit-make-margin-overlay string))
+ ;; Don't put the overlay on the complete line to work around #1880.
+ (let ((o (make-overlay (1+ (line-beginning-position))
+ (line-end-position)
+ nil t)))
+ (overlay-put o 'evaporate t)
+ (overlay-put o 'before-string
+ (propertize "o" 'display
+ (list (list 'margin 'right-margin)
+ (or string " ")))))))
+
+(defun magit-maybe-make-margin-overlay ()
+ (when (or (magit-section-match
+ '(unpulled unpushed recent stashes local cherries)
+ magit-insert-section--current)
+ (and (eq major-mode 'magit-refs-mode)
+ (magit-section-match
+ '(remote commit tags)
+ magit-insert-section--current)))
+ (magit-make-margin-overlay nil t)))
+
+;;; Custom Support
+
+(defun magit-margin-set-variable (mode symbol value)
+ (set-default symbol value)
+ (message "Updating margins in %s buffers..." mode)
+ (dolist (buffer (buffer-list))
+ (with-current-buffer buffer
+ (when (eq major-mode mode)
+ (magit-set-buffer-margin t)
+ (magit-refresh))))
+ (message "Updating margins in %s buffers...done" mode))
+
+(defconst magit-log-margin--custom-type
+ '(list (boolean :tag "Show margin initially")
+ (choice :tag "Show committer"
+ (string :tag "date using time-format" "%Y-%m-%d %H:%M ")
+ (const :tag "date's age" age)
+ (const :tag "date's age (abbreviated)" age-abbreviated))
+ (const :tag "Calculate width using magit-log-margin-width"
+ magit-log-margin-width)
+ (boolean :tag "Show author name by default")
+ (integer :tag "Show author name using width")))
+
+;;; Time Utilities
+
+(defvar magit--age-spec
+ `((?Y "year" "years" ,(round (* 60 60 24 365.2425)))
+ (?M "month" "months" ,(round (* 60 60 24 30.436875)))
+ (?w "week" "weeks" ,(* 60 60 24 7))
+ (?d "day" "days" ,(* 60 60 24))
+ (?h "hour" "hours" ,(* 60 60))
+ (?m "minute" "minutes" 60)
+ (?s "second" "seconds" 1))
+ "Time units used when formatting relative commit ages.
+
+The value is a list of time units, beginning with the longest.
+Each element has the form (CHAR UNIT UNITS SECONDS). UNIT is the
+time unit, UNITS is the plural of that unit. CHAR is a character
+abbreviation. And SECONDS is the number of seconds in one UNIT.
+
+This is defined as a variable to make it possible to use time
+units for a language other than English. It is not defined
+as an option, because most other parts of Magit are always in
+English.")
+
+(defun magit--age (date &optional abbreviate)
+ (cl-labels ((fn (age spec)
+ (pcase-let ((`(,char ,unit ,units ,weight) (car spec)))
+ (let ((cnt (round (/ age weight 1.0))))
+ (if (or (not (cdr spec))
+ (>= (/ age weight) 1))
+ (list cnt (cond (abbreviate char)
+ ((= cnt 1) unit)
+ (t units)))
+ (fn age (cdr spec)))))))
+ (fn (abs (- (float-time)
+ (if (stringp date)
+ (string-to-number date)
+ date)))
+ magit--age-spec)))
+
+;;; _
+(provide 'magit-margin)
+;;; magit-margin.el ends here
diff --git a/elpa/magit-20220503.1245/magit-margin.elc b/elpa/magit-20220503.1245/magit-margin.elc
new file mode 100644
index 0000000..0997479
--- /dev/null
+++ b/elpa/magit-20220503.1245/magit-margin.elc
Binary files differ
diff --git a/elpa/magit-20220503.1245/magit-merge.el b/elpa/magit-20220503.1245/magit-merge.el
new file mode 100644
index 0000000..ead4d21
--- /dev/null
+++ b/elpa/magit-20220503.1245/magit-merge.el
@@ -0,0 +1,318 @@
+;;; magit-merge.el --- Merge functionality -*- lexical-binding:t -*-
+
+;; Copyright (C) 2008-2022 The Magit Project Contributors
+
+;; Author: Jonas Bernoulli <jonas@bernoul.li>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+
+;; SPDX-License-Identifier: GPL-3.0-or-later
+
+;; Magit 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.
+;;
+;; Magit 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 Magit. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This library implements merge commands.
+
+;;; Code:
+
+(require 'magit)
+(require 'magit-diff)
+
+(declare-function magit-git-push "magit-push" (branch target args))
+
+;;; Commands
+
+;;;###autoload (autoload 'magit-merge "magit" nil t)
+(transient-define-prefix magit-merge ()
+ "Merge branches."
+ :man-page "git-merge"
+ :incompatible '(("--ff-only" "--no-ff"))
+ ["Arguments"
+ :if-not magit-merge-in-progress-p
+ ("-f" "Fast-forward only" "--ff-only")
+ ("-n" "No fast-forward" "--no-ff")
+ (magit-merge:--strategy)
+ (5 magit-merge:--strategy-option)
+ (5 "-b" "Ignore changes in amount of whitespace" "-Xignore-space-change")
+ (5 "-w" "Ignore whitespace when comparing lines" "-Xignore-all-space")
+ (5 magit-diff:--diff-algorithm :argument "-Xdiff-algorithm=")
+ (5 magit:--gpg-sign)]
+ ["Actions"
+ :if-not magit-merge-in-progress-p
+ [("m" "Merge" magit-merge-plain)
+ ("e" "Merge and edit message" magit-merge-editmsg)
+ ("n" "Merge but don't commit" magit-merge-nocommit)
+ ("a" "Absorb" magit-merge-absorb)]
+ [("p" "Preview merge" magit-merge-preview)
+ ""
+ ("s" "Squash merge" magit-merge-squash)
+ ("i" "Dissolve" magit-merge-into)]]
+ ["Actions"
+ :if magit-merge-in-progress-p
+ ("m" "Commit merge" magit-commit-create)
+ ("a" "Abort merge" magit-merge-abort)])
+
+(defun magit-merge-arguments ()
+ (transient-args 'magit-merge))
+
+(transient-define-argument magit-merge:--strategy ()
+ :description "Strategy"
+ :class 'transient-option
+ ;; key for merge and rebase: "-s"
+ ;; key for cherry-pick and revert: "=s"
+ ;; shortarg for merge and rebase: "-s"
+ ;; shortarg for cherry-pick and revert: none
+ :key "-s"
+ :argument "--strategy="
+ :choices '("resolve" "recursive" "octopus" "ours" "subtree"))
+
+(transient-define-argument magit-merge:--strategy-option ()
+ :description "Strategy Option"
+ :class 'transient-option
+ :key "-X"
+ :argument "--strategy-option="
+ :choices '("ours" "theirs" "patience"))
+
+;;;###autoload
+(defun magit-merge-plain (rev &optional args nocommit)
+ "Merge commit REV into the current branch; using default message.
+
+Unless there are conflicts or a prefix argument is used create a
+merge commit using a generic commit message and without letting
+the user inspect the result. With a prefix argument pretend the
+merge failed to give the user the opportunity to inspect the
+merge.
+
+\(git merge --no-edit|--no-commit [ARGS] REV)"
+ (interactive (list (magit-read-other-branch-or-commit "Merge")
+ (magit-merge-arguments)
+ current-prefix-arg))
+ (magit-merge-assert)
+ (magit-run-git-async "merge" (if nocommit "--no-commit" "--no-edit") args rev))
+
+;;;###autoload
+(defun magit-merge-editmsg (rev &optional args)
+ "Merge commit REV into the current branch; and edit message.
+Perform the merge and prepare a commit message but let the user
+edit it.
+\n(git merge --edit --no-ff [ARGS] REV)"
+ (interactive (list (magit-read-other-branch-or-commit "Merge")
+ (magit-merge-arguments)))
+ (magit-merge-assert)
+ (cl-pushnew "--no-ff" args :test #'equal)
+ (apply #'magit-run-git-with-editor "merge" "--edit"
+ (append (delete "--ff-only" args)
+ (list rev))))
+
+;;;###autoload
+(defun magit-merge-nocommit (rev &optional args)
+ "Merge commit REV into the current branch; pretending it failed.
+Pretend the merge failed to give the user the opportunity to
+inspect the merge and change the commit message.
+\n(git merge --no-commit --no-ff [ARGS] REV)"
+ (interactive (list (magit-read-other-branch-or-commit "Merge")
+ (magit-merge-arguments)))
+ (magit-merge-assert)
+ (cl-pushnew "--no-ff" args :test #'equal)
+ (magit-run-git-async "merge" "--no-commit" args rev))
+
+;;;###autoload
+(defun magit-merge-into (branch &optional args)
+ "Merge the current branch into BRANCH and remove the former.
+
+Before merging, force push the source branch to its push-remote,
+provided the respective remote branch already exists, ensuring
+that the respective pull-request (if any) won't get stuck on some
+obsolete version of the commits that are being merged. Finally
+if `forge-branch-pullreq' was used to create the merged branch,
+then also remove the respective remote branch."
+ (interactive
+ (list (magit-read-other-local-branch
+ (format "Merge `%s' into"
+ (or (magit-get-current-branch)
+ (magit-rev-parse "HEAD")))
+ nil
+ (and-let* ((upstream (magit-get-upstream-branch))
+ (upstream (cdr (magit-split-branch-name upstream))))
+ (and (magit-branch-p upstream) upstream)))
+ (magit-merge-arguments)))
+ (let ((current (magit-get-current-branch))
+ (head (magit-rev-parse "HEAD")))
+ (when (zerop (magit-call-git "checkout" branch))
+ (if current
+ (magit--merge-absorb current args)
+ (magit-run-git-with-editor "merge" args head)))))
+
+;;;###autoload
+(defun magit-merge-absorb (branch &optional args)
+ "Merge BRANCH into the current branch and remove the former.
+
+Before merging, force push the source branch to its push-remote,
+provided the respective remote branch already exists, ensuring
+that the respective pull-request (if any) won't get stuck on some
+obsolete version of the commits that are being merged. Finally
+if `forge-branch-pullreq' was used to create the merged branch,
+then also remove the respective remote branch."
+ (interactive (list (magit-read-other-local-branch "Absorb branch")
+ (magit-merge-arguments)))
+ (magit--merge-absorb branch args))
+
+(defun magit--merge-absorb (branch args)
+ (when (equal branch (magit-main-branch))
+ (unless (yes-or-no-p
+ (format "Do you really want to merge `%s' into another branch? "
+ branch))
+ (user-error "Abort")))
+ (if-let ((target (magit-get-push-branch branch t)))
+ (progn
+ (magit-git-push branch target (list "--force-with-lease"))
+ (set-process-sentinel
+ magit-this-process
+ (lambda (process event)
+ (when (memq (process-status process) '(exit signal))
+ (if (not (zerop (process-exit-status process)))
+ (magit-process-sentinel process event)
+ (process-put process 'inhibit-refresh t)
+ (magit-process-sentinel process event)
+ (magit--merge-absorb-1 branch args))))))
+ (magit--merge-absorb-1 branch args)))
+
+(defun magit--merge-absorb-1 (branch args)
+ (if-let ((pr (magit-get "branch" branch "pullRequest")))
+ (magit-run-git-async
+ "merge" args "-m"
+ (format "Merge branch '%s'%s [#%s]"
+ branch
+ (let ((current (magit-get-current-branch)))
+ (if (equal current (magit-main-branch))
+ ""
+ (format " into %s" current)))
+ pr)
+ branch)
+ (magit-run-git-async "merge" args "--no-edit" branch))
+ (set-process-sentinel
+ magit-this-process
+ (lambda (process event)
+ (when (memq (process-status process) '(exit signal))
+ (if (> (process-exit-status process) 0)
+ (magit-process-sentinel process event)
+ (process-put process 'inhibit-refresh t)
+ (magit-process-sentinel process event)
+ (magit-branch-maybe-delete-pr-remote branch)
+ (magit-branch-unset-pushRemote branch)
+ (magit-run-git "branch" "-D" branch))))))
+
+;;;###autoload
+(defun magit-merge-squash (rev)
+ "Squash commit REV into the current branch; don't create a commit.
+\n(git merge --squash REV)"
+ (interactive (list (magit-read-other-branch-or-commit "Squash")))
+ (magit-merge-assert)
+ (magit-run-git-async "merge" "--squash" rev))
+
+;;;###autoload
+(defun magit-merge-preview (rev)
+ "Preview result of merging REV into the current branch."
+ (interactive (list (magit-read-other-branch-or-commit "Preview merge")))
+ (magit-merge-preview-setup-buffer rev))
+
+;;;###autoload
+(defun magit-merge-abort ()
+ "Abort the current merge operation.
+\n(git merge --abort)"
+ (interactive)
+ (unless (file-exists-p (magit-git-dir "MERGE_HEAD"))
+ (user-error "No merge in progress"))
+ (magit-confirm 'abort-merge)
+ (magit-run-git-async "merge" "--abort"))
+
+(defun magit-checkout-stage (file arg)
+ "During a conflict checkout and stage side, or restore conflict."
+ (interactive
+ (let ((file (magit-completing-read "Checkout file"
+ (magit-tracked-files) nil nil nil
+ 'magit-read-file-hist
+ (magit-current-file))))
+ (cond ((member file (magit-unmerged-files))
+ (list file (magit-checkout-read-stage file)))
+ ((yes-or-no-p (format "Restore conflicts in %s? " file))
+ (list file "--merge"))
+ (t
+ (user-error "Quit")))))
+ (pcase (cons arg (cddr (car (magit-file-status file))))
+ ((or `("--ours" ?D ,_)
+ '("--ours" ?U ?A)
+ `("--theirs" ,_ ?D)
+ '("--theirs" ?A ?U))
+ (magit-run-git "rm" "--" file))
+ (_ (if (equal arg "--merge")
+ ;; This fails if the file was deleted on one
+ ;; side. And we cannot do anything about it.
+ (magit-run-git "checkout" "--merge" "--" file)
+ (magit-call-git "checkout" arg "--" file)
+ (magit-run-git "add" "-u" "--" file)))))
+
+;;; Utilities
+
+(defun magit-merge-in-progress-p ()
+ (file-exists-p (magit-git-dir "MERGE_HEAD")))
+
+(defun magit--merge-range (&optional head)
+ (unless head
+ (setq head (magit-get-shortname
+ (car (magit-file-lines (magit-git-dir "MERGE_HEAD"))))))
+ (and head
+ (concat (magit-git-string "merge-base" "--octopus" "HEAD" head)
+ ".." head)))
+
+(defun magit-merge-assert ()
+ (or (not (magit-anything-modified-p t))
+ (magit-confirm 'merge-dirty
+ "Merging with dirty worktree is risky. Continue")))
+
+(defun magit-checkout-read-stage (file)
+ (magit-read-char-case (format "For %s checkout: " file) t
+ (?o "[o]ur stage" "--ours")
+ (?t "[t]heir stage" "--theirs")
+ (?c "[c]onflict" "--merge")))
+
+;;; Sections
+
+(defvar magit-unmerged-section-map
+ (let ((map (make-sparse-keymap)))
+ (set-keymap-parent map magit-log-section-map)
+ map)
+ "Keymap for `unmerged' sections.")
+
+(defun magit-insert-merge-log ()
+ "Insert section for the on-going merge.
+Display the heads that are being merged.
+If no merge is in progress, do nothing."
+ (when (magit-merge-in-progress-p)
+ (let* ((heads (mapcar #'magit-get-shortname
+ (magit-file-lines (magit-git-dir "MERGE_HEAD"))))
+ (range (magit--merge-range (car heads))))
+ (magit-insert-section (unmerged range)
+ (magit-insert-heading
+ (format "Merging %s:" (mapconcat #'identity heads ", ")))
+ (magit-insert-log
+ range
+ (let ((args magit-buffer-log-args))
+ (unless (member "--decorate=full" magit-buffer-log-args)
+ (push "--decorate=full" args))
+ args))))))
+
+;;; _
+(provide 'magit-merge)
+;;; magit-merge.el ends here
diff --git a/elpa/magit-20220503.1245/magit-merge.elc b/elpa/magit-20220503.1245/magit-merge.elc
new file mode 100644
index 0000000..e0b5afe
--- /dev/null
+++ b/elpa/magit-20220503.1245/magit-merge.elc
Binary files differ
diff --git a/elpa/magit-20220503.1245/magit-mode.el b/elpa/magit-20220503.1245/magit-mode.el
new file mode 100644
index 0000000..d47768f
--- /dev/null
+++ b/elpa/magit-20220503.1245/magit-mode.el
@@ -0,0 +1,1547 @@
+;;; magit-mode.el --- Create and refresh Magit buffers -*- lexical-binding:t -*-
+
+;; Copyright (C) 2008-2022 The Magit Project Contributors
+
+;; Author: Jonas Bernoulli <jonas@bernoul.li>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+
+;; SPDX-License-Identifier: GPL-3.0-or-later
+
+;; Magit 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.
+;;
+;; Magit 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 Magit. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This library implements the abstract major-mode `magit-mode' from
+;; which almost all other Magit major-modes derive. The code in here
+;; is mostly concerned with creating and refreshing Magit buffers.
+
+;;; Code:
+
+(require 'magit-base)
+(require 'magit-git)
+
+(require 'format-spec)
+(require 'help-mode)
+(require 'transient)
+
+;; For `magit-display-buffer-fullcolumn-most-v1' from `git-commit'
+(defvar git-commit-mode)
+;; For `magit-refresh'
+(defvar magit-post-commit-hook-commands)
+(defvar magit-post-stage-hook-commands)
+(defvar magit-post-unstage-hook-commands)
+;; For `magit-refresh' and `magit-refresh-all'
+(declare-function magit-auto-revert-buffers "magit-autorevert" ())
+;; For `magit-refresh-buffer'
+(declare-function magit-process-unset-mode-line-error-status "magit-process" ())
+;; For `magit-refresh-get-relative-position'
+(declare-function magit-hunk-section-p "magit-diff" (section) t)
+;; For `magit-mode-setup-internal'
+(declare-function magit-status-goto-initial-section "magit-status" ())
+;; For `magit-mode'
+(defvar bookmark-make-record-function)
+(declare-function magit--make-bookmark "magit-bookmark" ())
+
+;;; Options
+
+(defcustom magit-mode-hook
+ '(magit-load-config-extensions)
+ "Hook run when entering a mode derived from Magit mode."
+ :package-version '(magit . "3.0.0")
+ :group 'magit-modes
+ :type 'hook
+ :options '(magit-load-config-extensions
+ bug-reference-mode))
+
+(defcustom magit-setup-buffer-hook
+ '(magit-maybe-save-repository-buffers
+ magit-set-buffer-margin)
+ "Hook run by `magit-setup-buffer'.
+
+This is run right after displaying the buffer and right before
+generating or updating its content. `magit-mode-hook' and other,
+more specific, `magit-mode-*-hook's on the other hand are run
+right before displaying the buffer. Usually one of these hooks
+should be used instead of this one."
+ :package-version '(magit . "2.3.0")
+ :group 'magit-modes
+ :type 'hook
+ :options '(magit-maybe-save-repository-buffers
+ magit-set-buffer-margin))
+
+(defcustom magit-pre-refresh-hook '(magit-maybe-save-repository-buffers)
+ "Hook run before refreshing in `magit-refresh'.
+
+This hook, or `magit-post-refresh-hook', should be used
+for functions that are not tied to a particular buffer.
+
+To run a function with a particular buffer current, use
+`magit-refresh-buffer-hook' and use `derived-mode-p'
+inside your function."
+ :package-version '(magit . "2.4.0")
+ :group 'magit-refresh
+ :type 'hook
+ :options '(magit-maybe-save-repository-buffers))
+
+(defcustom magit-post-refresh-hook nil
+ "Hook run after refreshing in `magit-refresh'.
+
+This hook, or `magit-pre-refresh-hook', should be used
+for functions that are not tied to a particular buffer.
+
+To run a function with a particular buffer current, use
+`magit-refresh-buffer-hook' and use `derived-mode-p'
+inside your function."
+ :package-version '(magit . "2.4.0")
+ :group 'magit-refresh
+ :type 'hook)
+
+(defcustom magit-display-buffer-function #'magit-display-buffer-traditional
+ "The function used to display a Magit buffer.
+
+All Magit buffers (buffers whose major-modes derive from
+`magit-mode') are displayed using `magit-display-buffer',
+which in turn uses the function specified here."
+ :package-version '(magit . "2.3.0")
+ :group 'magit-buffers
+ :type '(radio (function-item magit-display-buffer-traditional)
+ (function-item magit-display-buffer-same-window-except-diff-v1)
+ (function-item magit-display-buffer-fullframe-status-v1)
+ (function-item magit-display-buffer-fullframe-status-topleft-v1)
+ (function-item magit-display-buffer-fullcolumn-most-v1)
+ (function-item display-buffer)
+ (function :tag "Function")))
+
+(defcustom magit-pre-display-buffer-hook '(magit-save-window-configuration)
+ "Hook run by `magit-display-buffer' before displaying the buffer."
+ :package-version '(magit . "2.3.0")
+ :group 'magit-buffers
+ :type 'hook
+ :get #'magit-hook-custom-get
+ :options '(magit-save-window-configuration))
+
+(defcustom magit-post-display-buffer-hook '(magit-maybe-set-dedicated)
+ "Hook run by `magit-display-buffer' after displaying the buffer."
+ :package-version '(magit . "2.3.0")
+ :group 'magit-buffers
+ :type 'hook
+ :get #'magit-hook-custom-get
+ :options '(magit-maybe-set-dedicated))
+
+(defcustom magit-generate-buffer-name-function
+ #'magit-generate-buffer-name-default-function
+ "The function used to generate the name for a Magit buffer."
+ :package-version '(magit . "2.3.0")
+ :group 'magit-buffers
+ :type '(radio (function-item magit-generate-buffer-name-default-function)
+ (function :tag "Function")))
+
+(defcustom magit-buffer-name-format "%x%M%v: %t%x"
+ "The format string used to name Magit buffers.
+
+The following %-sequences are supported:
+
+`%m' The name of the major-mode, but with the `-mode' suffix
+ removed.
+
+`%M' Like \"%m\" but abbreviate `magit-status-mode' as `magit'.
+
+`%v' The value the buffer is locked to, in parentheses, or an
+ empty string if the buffer is not locked to a value.
+
+`%V' Like \"%v\", but the string is prefixed with a space, unless
+ it is an empty string.
+
+`%t' The top-level directory of the working tree of the
+ repository, or if `magit-uniquify-buffer-names' is non-nil
+ an abbreviation of that.
+
+`%x' If `magit-uniquify-buffer-names' is nil \"*\", otherwise the
+ empty string. Due to limitations of the `uniquify' package,
+ buffer names must end with the path.
+
+`%T' Obsolete, use \"%t%x\" instead. Like \"%t\", but append an
+ asterisk if and only if `magit-uniquify-buffer-names' is nil.
+
+The value should always contain \"%m\" or \"%M\", \"%v\" or
+\"%V\", and \"%t\" (or the obsolete \"%T\").
+
+If `magit-uniquify-buffer-names' is non-nil, then the value must
+end with \"%t\" or \"%t%x\" (or the obsolete \"%T\"). See issue
+#2841.
+
+This is used by `magit-generate-buffer-name-default-function'.
+If another `magit-generate-buffer-name-function' is used, then
+it may not respect this option, or on the contrary it may
+support additional %-sequences."
+ :package-version '(magit . "2.12.0")
+ :group 'magit-buffers
+ :type 'string)
+
+(defcustom magit-uniquify-buffer-names t
+ "Whether to uniquify the names of Magit buffers."
+ :package-version '(magit . "2.3.0")
+ :group 'magit-buffers
+ :type 'boolean)
+
+(defcustom magit-bury-buffer-function #'magit-mode-quit-window
+ "The function used to bury or kill the current Magit buffer."
+ :package-version '(magit . "3.2.0")
+ :group 'magit-buffers
+ :type '(radio (function-item quit-window)
+ (function-item magit-mode-quit-window)
+ (function-item magit-restore-window-configuration)
+ (function :tag "Function")))
+
+(defcustom magit-prefix-use-buffer-arguments 'selected
+ "Whether certain prefix commands reuse arguments active in relevant buffer.
+
+This affects the transient prefix commands `magit-diff',
+`magit-log' and `magit-show-refs'.
+
+Valid values are:
+
+`always': Always use the set of arguments that is currently
+ active in the respective buffer, provided that buffer exists
+ of course.
+`selected': Use the set of arguments from the respective
+ buffer, but only if it is displayed in a window of the current
+ frame. This is the default.
+`current': Use the set of arguments from the respective buffer,
+ but only if it is the current buffer.
+`never': Never use the set of arguments from the respective
+ buffer.
+
+For more information see info node `(magit)Transient Arguments
+and Buffer Variables'."
+ :package-version '(magit . "3.0.0")
+ :group 'magit-buffers
+ :group 'magit-commands
+ :group 'magit-diff
+ :group 'magit-log
+ :type '(choice
+ (const :tag "always use args from buffer" always)
+ (const :tag "use args from buffer if displayed in frame" selected)
+ (const :tag "use args from buffer if it is current" current)
+ (const :tag "never use args from buffer" never)))
+
+(defcustom magit-direct-use-buffer-arguments 'selected
+ "Whether certain commands reuse arguments active in relevant buffer.
+
+This affects certain commands such as `magit-show-commit' that
+are suffixes of the diff or log transient prefix commands, but
+only if they are invoked directly, i.e. *not* as a suffix.
+
+Valid values are:
+
+`always': Always use the set of arguments that is currently
+ active in the respective buffer, provided that buffer exists
+ of course.
+`selected': Use the set of arguments from the respective
+ buffer, but only if it is displayed in a window of the current
+ frame. This is the default.
+`current': Use the set of arguments from the respective buffer,
+ but only if it is the current buffer.
+`never': Never use the set of arguments from the respective
+ buffer.
+
+For more information see info node `(magit)Transient Arguments
+and Buffer Variables'."
+ :package-version '(magit . "3.0.0")
+ :group 'magit-buffers
+ :group 'magit-commands
+ :group 'magit-diff
+ :group 'magit-log
+ :type '(choice
+ (const :tag "always use args from buffer" always)
+ (const :tag "use args from buffer if displayed in frame" selected)
+ (const :tag "use args from buffer if it is current" current)
+ (const :tag "never use args from buffer" never)))
+
+(defcustom magit-region-highlight-hook '(magit-diff-update-hunk-region)
+ "Functions used to highlight the region.
+
+Each function is run with the current section as only argument
+until one of them returns non-nil. If all functions return nil,
+then fall back to regular region highlighting."
+ :package-version '(magit . "2.1.0")
+ :group 'magit-refresh
+ :type 'hook
+ :options '(magit-diff-update-hunk-region))
+
+(defcustom magit-create-buffer-hook nil
+ "Normal hook run after creating a new `magit-mode' buffer."
+ :package-version '(magit . "2.90.0")
+ :group 'magit-refresh
+ :type 'hook)
+
+(defcustom magit-refresh-buffer-hook nil
+ "Normal hook for `magit-refresh-buffer' to run after refreshing."
+ :package-version '(magit . "2.1.0")
+ :group 'magit-refresh
+ :type 'hook)
+
+(defcustom magit-refresh-status-buffer t
+ "Whether the status buffer is refreshed after running git.
+
+When this is non-nil, then the status buffer is automatically
+refreshed after running git for side-effects, in addition to the
+current Magit buffer, which is always refreshed automatically.
+
+Only set this to nil after exhausting all other options to
+improve performance."
+ :package-version '(magit . "2.4.0")
+ :group 'magit-refresh
+ :group 'magit-status
+ :type 'boolean)
+
+(defcustom magit-refresh-verbose nil
+ "Whether to revert Magit buffers verbosely."
+ :package-version '(magit . "2.1.0")
+ :group 'magit-refresh
+ :type 'boolean)
+
+(defcustom magit-save-repository-buffers t
+ "Whether to save file-visiting buffers when appropriate.
+
+If non-nil, then all modified file-visiting buffers belonging
+to the current repository may be saved before running Magit
+commands and before creating or refreshing Magit buffers.
+If `dontask', then this is done without user intervention, for
+any other non-nil value the user has to confirm each save.
+
+The default is t to avoid surprises, but `dontask' is the
+recommended value."
+ :group 'magit-essentials
+ :group 'magit-buffers
+ :type '(choice (const :tag "Never" nil)
+ (const :tag "Ask" t)
+ (const :tag "Save without asking" dontask)))
+
+;;; Key Bindings
+
+(defvar magit-mode-map
+ (let ((map (make-sparse-keymap)))
+ (set-keymap-parent map magit-section-mode-map)
+ ;; Don't function-quote but make sure all commands are autoloaded.
+ (define-key map [C-return] 'magit-visit-thing)
+ (define-key map (kbd "RET") 'magit-visit-thing)
+ (define-key map (kbd "M-TAB") 'magit-dired-jump)
+ (define-key map [M-tab] 'magit-section-cycle-diffs)
+ (define-key map (kbd "SPC") 'magit-diff-show-or-scroll-up)
+ (define-key map (kbd "S-SPC") 'magit-diff-show-or-scroll-down)
+ (define-key map (kbd "DEL") 'magit-diff-show-or-scroll-down)
+ (define-key map "+" 'magit-diff-more-context)
+ (define-key map "-" 'magit-diff-less-context)
+ (define-key map "0" 'magit-diff-default-context)
+ (define-key map "a" 'magit-cherry-apply)
+ (define-key map "A" 'magit-cherry-pick)
+ (define-key map "b" 'magit-branch)
+ (define-key map "B" 'magit-bisect)
+ (define-key map "c" 'magit-commit)
+ (define-key map "C" 'magit-clone)
+ (define-key map "d" 'magit-diff)
+ (define-key map "D" 'magit-diff-refresh)
+ (define-key map "e" 'magit-ediff-dwim)
+ (define-key map "E" 'magit-ediff)
+ (define-key map "f" 'magit-fetch)
+ (define-key map "F" 'magit-pull)
+ (define-key map "g" 'magit-refresh)
+ (define-key map "G" 'magit-refresh-all)
+ (define-key map "h" 'magit-dispatch)
+ (define-key map "?" 'magit-dispatch)
+ (define-key map "H" 'magit-describe-section)
+ (define-key map "i" 'magit-gitignore)
+ (define-key map "I" 'magit-init)
+ (define-key map "j" 'magit-status-quick)
+ (define-key map "J" 'magit-display-repository-buffer)
+ (define-key map "k" 'magit-delete-thing)
+ (define-key map "K" 'magit-file-untrack)
+ (define-key map "l" 'magit-log)
+ (define-key map "L" 'magit-log-refresh)
+ (define-key map "m" 'magit-merge)
+ (define-key map "M" 'magit-remote)
+ ;; section-map "n" magit-section-forward
+ ;; reserved "N" forge-dispatch
+ (define-key map "o" 'magit-submodule)
+ (define-key map "O" 'magit-subtree)
+ ;; section-map "p" magit-section-backward
+ (define-key map "P" 'magit-push)
+ (define-key map "q" 'magit-mode-bury-buffer)
+ (define-key map "Q" 'magit-git-command)
+ (define-key map ":" 'magit-git-command)
+ (define-key map "r" 'magit-rebase)
+ (define-key map "R" 'magit-file-rename)
+ (define-key map "s" 'magit-stage-file)
+ (define-key map "S" 'magit-stage-modified)
+ (define-key map "t" 'magit-tag)
+ (define-key map "T" 'magit-notes)
+ (define-key map "u" 'magit-unstage-file)
+ (define-key map "U" 'magit-unstage-all)
+ (define-key map "v" 'magit-revert-no-commit)
+ (define-key map "V" 'magit-revert)
+ (define-key map "w" 'magit-am)
+ (define-key map "W" 'magit-patch)
+ (define-key map "x" 'magit-reset-quickly)
+ (define-key map "X" 'magit-reset)
+ (define-key map "y" 'magit-show-refs)
+ (define-key map "Y" 'magit-cherry)
+ (define-key map "z" 'magit-stash)
+ (define-key map "Z" 'magit-worktree)
+ (define-key map "%" 'magit-worktree)
+ (define-key map "$" 'magit-process-buffer)
+ (define-key map "!" 'magit-run)
+ (define-key map ">" 'magit-sparse-checkout)
+ (define-key map (kbd "C-c C-c") 'magit-dispatch)
+ (define-key map (kbd "C-c C-e") 'magit-edit-thing)
+ (define-key map (kbd "C-c C-o") 'magit-browse-thing)
+ (define-key map (kbd "C-c C-w") 'magit-browse-thing)
+ (define-key map (kbd "C-w") 'magit-copy-section-value)
+ (define-key map (kbd "M-w") 'magit-copy-buffer-revision)
+ (define-key map [remap previous-line] 'magit-previous-line)
+ (define-key map [remap next-line] 'magit-next-line)
+ (define-key map [remap evil-previous-line] 'evil-previous-visual-line)
+ (define-key map [remap evil-next-line] 'evil-next-visual-line)
+ map)
+ "Parent keymap for all keymaps of modes derived from `magit-mode'.")
+
+(defun magit-delete-thing ()
+ "This is a placeholder command.
+Where applicable, section-specific keymaps bind another command
+which deletes the thing at point."
+ (interactive)
+ (user-error "There is no thing at point that could be deleted"))
+
+(defun magit-visit-thing ()
+ "This is a placeholder command.
+Where applicable, section-specific keymaps bind another command
+which visits the thing at point."
+ (interactive)
+ (if (eq transient-current-command 'magit-dispatch)
+ (call-interactively (key-binding (this-command-keys)))
+ (user-error "There is no thing at point that could be visited")))
+
+(defun magit-edit-thing ()
+ "This is a placeholder command.
+Where applicable, section-specific keymaps bind another command
+which lets you edit the thing at point, likely in another buffer."
+ (interactive)
+ (if (eq transient-current-command 'magit-dispatch)
+ (call-interactively (key-binding (this-command-keys)))
+ (user-error "There is no thing at point that could be edited")))
+
+(defun magit-browse-thing ()
+ "This is a placeholder command.
+Where applicable, section-specific keymaps bind another command
+which visits the thing at point using `browse-url'."
+ (interactive)
+ (user-error "There is no thing at point that could be browsed"))
+
+;;;###autoload
+(defun magit-info ()
+ "Visit the Magit manual."
+ (interactive)
+ (info "magit"))
+
+(defvar bug-reference-map)
+(with-eval-after-load 'bug-reference
+ (define-key bug-reference-map [remap magit-visit-thing]
+ 'bug-reference-push-button))
+
+(easy-menu-define magit-mode-menu magit-mode-map
+ "Magit menu"
+ ;; Similar to `magit-dispatch' but exclude:
+ ;; - commands that are available from context menus:
+ ;; apply, reverse, discard, stage, unstage,
+ ;; cherry-pick, revert, reset,
+ ;; describe-section
+ ;; - commands that are available from submenus:
+ ;; git-command, ediff-dwim
+ ;; - and: refresh-all, status-jump, status-quick.
+ '("Magit"
+ "---" "Inspect"
+ [" Bisect..." magit-bisect t]
+ [" Cherries..." magit-cherry t]
+ [" Diff..." magit-diff t]
+ [" Ediff..." magit-ediff t]
+ [" Log..." magit-log t]
+ [" References..." magit-show-refs t]
+ "---" "Manipulate"
+ [" Commit..." magit-commit t]
+ [" Stash..." magit-stash t]
+ [" Tag..." magit-tag t]
+ "---"
+ [" Branch..." magit-branch t]
+ [" Remote..." magit-remote t]
+ "---"
+ [" Merge..." magit-merge t]
+ [" Rebase..." magit-rebase t]
+ "---" "Transfer"
+ [" Fetch..." magit-fetch t]
+ [" Pull..." magit-pull t]
+ [" Push..." magit-push t]
+ "---" "Setup"
+ [" Clone..." magit-clone t]
+ [" Ignore..." magit-gitignore t]
+ [" Init..." magit-init t]
+ "---"
+ ("Advanced"
+ ["Run..." magit-run t]
+ "---"
+ ["Apply patches..." magit-am t]
+ ["Format patches..." magit-patch t]
+ "---"
+ ["Note..." magit-notes t]
+ "---"
+ ["Submodule..." magit-submodule t]
+ ["Subtree..." magit-subtree t]
+ ["Worktree..." magit-worktree t])
+ "---"
+ ["Show command dispatcher..." magit-dispatch t]
+ ["Show manual" magit-help t]
+ ["Show another buffer" magit-display-repository-buffer t]
+ "---"
+ ("Change buffer arguments"
+ ["Diff arguments" magit-diff-refresh t]
+ ["Log arguments" magit-log-refresh t])
+ ["Refresh buffer" magit-refresh t]
+ ["Bury buffer" magit-mode-bury-buffer t]))
+
+;;; Mode
+
+(defun magit-load-config-extensions ()
+ "Load Magit extensions that are defined at the Git config layer."
+ (dolist (ext (magit-get-all "magit.extension"))
+ (let ((sym (intern (format "magit-%s-mode" ext))))
+ (when (fboundp sym)
+ (funcall sym 1)))))
+
+(define-derived-mode magit-mode magit-section-mode "Magit"
+ "Parent major mode from which Magit major modes inherit.
+
+Magit is documented in info node `(magit)'."
+ :group 'magit
+ (hack-dir-local-variables-non-file-buffer)
+ (face-remap-add-relative 'header-line 'magit-header-line)
+ (setq mode-line-process (magit-repository-local-get 'mode-line-process))
+ (setq-local revert-buffer-function #'magit-refresh-buffer)
+ (setq-local bookmark-make-record-function #'magit--make-bookmark)
+ (setq-local imenu-create-index-function #'magit--imenu-create-index)
+ (setq-local isearch-filter-predicate #'magit-section--open-temporarily))
+
+;;; Local Variables
+
+(defvar-local magit-buffer-arguments nil)
+(defvar-local magit-buffer-diff-args nil)
+(defvar-local magit-buffer-diff-files nil)
+(defvar-local magit-buffer-diff-files-suspended nil)
+(defvar-local magit-buffer-file-name nil)
+(defvar-local magit-buffer-files nil)
+(defvar-local magit-buffer-log-args nil)
+(defvar-local magit-buffer-log-files nil)
+(defvar-local magit-buffer-range nil)
+(defvar-local magit-buffer-range-hashed nil)
+(defvar-local magit-buffer-refname nil)
+(defvar-local magit-buffer-revision nil)
+(defvar-local magit-buffer-revision-hash nil)
+(defvar-local magit-buffer-revisions nil)
+(defvar-local magit-buffer-typearg nil)
+(defvar-local magit-buffer-upstream nil)
+
+;; These variables are also used in file-visiting buffers.
+;; Because the user may change the major-mode, they have
+;; to be permanent buffer-local.
+(put 'magit-buffer-file-name 'permanent-local t)
+(put 'magit-buffer-refname 'permanent-local t)
+(put 'magit-buffer-revision 'permanent-local t)
+(put 'magit-buffer-revision-hash 'permanent-local t)
+
+;; `magit-status' re-enables mode function but its refresher
+;; function does not reinstate this.
+(put 'magit-buffer-diff-files-suspended 'permanent-local t)
+
+(defvar-local magit-refresh-args nil
+ "Obsolete. Possibly the arguments used to refresh the current buffer.
+Some third-party packages might still use this, but Magit does not.")
+(put 'magit-refresh-args 'permanent-local t)
+(make-obsolete-variable 'magit-refresh-args nil "Magit 3.0.0")
+
+(defvar magit-buffer-lock-functions nil
+ "Obsolete buffer-locking support for third-party modes.
+Implement the generic function `magit-buffer-value' for
+your mode instead of adding an entry to this variable.")
+(make-obsolete-variable 'magit-buffer-lock-functions nil "Magit 3.0.0")
+
+(cl-defgeneric magit-buffer-value ()
+ (and-let* ((fn (cdr (assq major-mode magit-buffer-lock-functions))))
+ (funcall fn (with-no-warnings magit-refresh-args))))
+
+(defvar-local magit-previous-section nil)
+(put 'magit-previous-section 'permanent-local t)
+
+(defvar-local magit--imenu-group-types nil)
+(defvar-local magit--imenu-item-types nil)
+
+;;; Setup Buffer
+
+(defmacro magit-setup-buffer (mode &optional locked &rest bindings)
+ (declare (indent 2))
+ `(magit-setup-buffer-internal
+ ,mode ,locked
+ ,(cons 'list (mapcar (pcase-lambda (`(,var ,form))
+ `(list ',var ,form))
+ bindings))))
+
+(defun magit-setup-buffer-internal (mode locked bindings)
+ (let* ((value (and locked
+ (with-temp-buffer
+ (pcase-dolist (`(,var ,val) bindings)
+ (set (make-local-variable var) val))
+ (let ((major-mode mode))
+ (magit-buffer-value)))))
+ (buffer (magit-get-mode-buffer mode value))
+ (section (and buffer (magit-current-section)))
+ (created (not buffer)))
+ (unless buffer
+ (setq buffer (magit-with-toplevel
+ (magit-generate-new-buffer mode value))))
+ (with-current-buffer buffer
+ (setq magit-previous-section section)
+ (funcall mode)
+ (magit-xref-setup #'magit-setup-buffer-internal bindings)
+ (pcase-dolist (`(,var ,val) bindings)
+ (set (make-local-variable var) val))
+ (when created
+ (magit-status-goto-initial-section)
+ (run-hooks 'magit-create-buffer-hook)))
+ (magit-display-buffer buffer)
+ (with-current-buffer buffer
+ (run-hooks 'magit-setup-buffer-hook)
+ (magit-refresh-buffer))
+ buffer))
+
+(defun magit-mode-setup (mode &rest args)
+ "Setup up a MODE buffer using ARGS to generate its content."
+ (declare (obsolete magit-setup-buffer "Magit 3.0.0"))
+ (with-no-warnings
+ (magit-mode-setup-internal mode args)))
+
+(defun magit-mode-setup-internal (mode args &optional locked)
+ "Setup up a MODE buffer using ARGS to generate its content.
+When optional LOCKED is non-nil, then create a buffer that is
+locked to its value, which is derived from MODE and ARGS."
+ (declare (obsolete magit-setup-buffer "Magit 3.0.0"))
+ (let* ((value (and locked
+ (with-temp-buffer
+ (with-no-warnings
+ (setq magit-refresh-args args))
+ (let ((major-mode mode))
+ (magit-buffer-value)))))
+ (buffer (magit-get-mode-buffer mode value))
+ (section (and buffer (magit-current-section)))
+ (created (not buffer)))
+ (unless buffer
+ (setq buffer (magit-with-toplevel
+ (magit-generate-new-buffer mode value))))
+ (with-current-buffer buffer
+ (setq magit-previous-section section)
+ (with-no-warnings
+ (setq magit-refresh-args args))
+ (funcall mode)
+ (magit-xref-setup 'magit-mode-setup-internal args)
+ (when created
+ (magit-status-goto-initial-section)
+ (run-hooks 'magit-create-buffer-hook)))
+ (magit-display-buffer buffer)
+ (with-current-buffer buffer
+ (run-hooks 'magit-mode-setup-hook)
+ (magit-refresh-buffer))))
+
+;;; Display Buffer
+
+(defvar magit-display-buffer-noselect nil
+ "If non-nil, then `magit-display-buffer' doesn't call `select-window'.")
+
+(defun magit-display-buffer (buffer &optional display-function)
+ "Display BUFFER in some window and maybe select it.
+
+If optional DISPLAY-FUNCTION is non-nil, then use that to display
+the buffer. Otherwise use `magit-display-buffer-function', which
+is the normal case.
+
+Then, unless `magit-display-buffer-noselect' is non-nil, select
+the window which was used to display the buffer.
+
+Also run the hooks `magit-pre-display-buffer-hook'
+and `magit-post-display-buffer-hook'."
+ (with-current-buffer buffer
+ (run-hooks 'magit-pre-display-buffer-hook))
+ (let ((window (funcall (or display-function magit-display-buffer-function)
+ buffer)))
+ (unless magit-display-buffer-noselect
+ (let* ((old-frame (selected-frame))
+ (new-frame (window-frame window)))
+ (select-window window)
+ (unless (eq old-frame new-frame)
+ (select-frame-set-input-focus new-frame)))))
+ (with-current-buffer buffer
+ (run-hooks 'magit-post-display-buffer-hook)))
+
+(defun magit-display-buffer-traditional (buffer)
+ "Display BUFFER the way this has traditionally been done."
+ (display-buffer
+ buffer (if (and (derived-mode-p 'magit-mode)
+ (not (memq (with-current-buffer buffer major-mode)
+ '(magit-process-mode
+ magit-revision-mode
+ magit-diff-mode
+ magit-stash-mode
+ magit-status-mode))))
+ '(display-buffer-same-window)
+ nil))) ; display in another window
+
+(defun magit-display-buffer-same-window-except-diff-v1 (buffer)
+ "Display BUFFER in the selected window except for some modes.
+If a buffer's `major-mode' derives from `magit-diff-mode' or
+`magit-process-mode', display it in another window. Display all
+other buffers in the selected window."
+ (display-buffer
+ buffer (if (with-current-buffer buffer
+ (derived-mode-p 'magit-diff-mode 'magit-process-mode))
+ '(nil (inhibit-same-window . t))
+ '(display-buffer-same-window))))
+
+(defun magit--display-buffer-fullframe (buffer alist)
+ (when-let ((window (or (display-buffer-reuse-window buffer alist)
+ (display-buffer-same-window buffer alist)
+ (display-buffer-pop-up-window buffer alist)
+ (display-buffer-use-some-window buffer alist))))
+ (delete-other-windows window)
+ window))
+
+(defun magit-display-buffer-fullframe-status-v1 (buffer)
+ "Display BUFFER, filling entire frame if BUFFER is a status buffer.
+Otherwise, behave like `magit-display-buffer-traditional'."
+ (if (eq (with-current-buffer buffer major-mode)
+ 'magit-status-mode)
+ (display-buffer buffer '(magit--display-buffer-fullframe))
+ (magit-display-buffer-traditional buffer)))
+
+(defun magit--display-buffer-topleft (buffer alist)
+ (or (display-buffer-reuse-window buffer alist)
+ (when-let ((window2 (display-buffer-pop-up-window buffer alist)))
+ (let ((window1 (get-buffer-window))
+ (buffer1 (current-buffer))
+ (buffer2 (window-buffer window2))
+ (w2-quit-restore (window-parameter window2 'quit-restore)))
+ (set-window-buffer window1 buffer2)
+ (set-window-buffer window2 buffer1)
+ (select-window window2)
+ ;; Swap some window state that `magit-mode-quit-window' and
+ ;; `quit-restore-window' inspect.
+ (set-window-prev-buffers window2 (cdr (window-prev-buffers window1)))
+ (set-window-prev-buffers window1 nil)
+ (set-window-parameter window2 'magit-dedicated
+ (window-parameter window1 'magit-dedicated))
+ (set-window-parameter window1 'magit-dedicated t)
+ (set-window-parameter window1 'quit-restore
+ (list 'window 'window
+ (nth 2 w2-quit-restore)
+ (nth 3 w2-quit-restore)))
+ (set-window-parameter window2 'quit-restore nil)
+ window1))))
+
+(defun magit-display-buffer-fullframe-status-topleft-v1 (buffer)
+ "Display BUFFER, filling entire frame if BUFFER is a status buffer.
+When BUFFER derives from `magit-diff-mode' or
+`magit-process-mode', try to display BUFFER to the top or left of
+the current buffer rather than to the bottom or right, as
+`magit-display-buffer-fullframe-status-v1' would. Whether the
+split is made vertically or horizontally is determined by
+`split-window-preferred-function'."
+ (display-buffer
+ buffer
+ (cond ((eq (with-current-buffer buffer major-mode)
+ 'magit-status-mode)
+ '(magit--display-buffer-fullframe))
+ ((with-current-buffer buffer
+ (derived-mode-p 'magit-diff-mode 'magit-process-mode))
+ '(magit--display-buffer-topleft))
+ (t
+ '(display-buffer-same-window)))))
+
+(defun magit--display-buffer-fullcolumn (buffer alist)
+ (when-let ((window (or (display-buffer-reuse-window buffer alist)
+ (display-buffer-same-window buffer alist)
+ (display-buffer-below-selected buffer alist))))
+ (delete-other-windows-vertically window)
+ window))
+
+(defun magit-display-buffer-fullcolumn-most-v1 (buffer)
+ "Display BUFFER using the full column except in some cases.
+For most cases where BUFFER's `major-mode' derives from
+`magit-mode', display it in the selected window and grow that
+window to the full height of the frame, deleting other windows in
+that column as necessary. However, display BUFFER in another
+window if 1) BUFFER's mode derives from `magit-process-mode', or
+2) BUFFER's mode derives from `magit-diff-mode', provided that
+the mode of the current buffer derives from `magit-log-mode' or
+`magit-cherry-mode'."
+ (display-buffer
+ buffer
+ (cond ((and (or git-commit-mode
+ (derived-mode-p 'magit-log-mode
+ 'magit-cherry-mode
+ 'magit-reflog-mode))
+ (with-current-buffer buffer
+ (derived-mode-p 'magit-diff-mode)))
+ nil)
+ ((with-current-buffer buffer
+ (derived-mode-p 'magit-process-mode))
+ nil)
+ (t
+ '(magit--display-buffer-fullcolumn)))))
+
+(defun magit-maybe-set-dedicated ()
+ "Mark the selected window as dedicated if appropriate.
+
+If a new window was created to display the buffer, then remember
+that fact. That information is used by `magit-mode-quit-window',
+to determine whether the window should be deleted when its last
+Magit buffer is buried."
+ (let ((window (get-buffer-window (current-buffer))))
+ (when (and (window-live-p window)
+ (not (window-prev-buffers window)))
+ (set-window-parameter window 'magit-dedicated t))))
+
+;;; Get Buffer
+
+(defvar-local magit--default-directory nil
+ "Value of `default-directory' when buffer is generated.
+This exists to prevent a let-bound `default-directory' from
+tricking `magit-get-mode-buffer' or `magit-mode-get-buffers'
+into thinking a buffer belongs to a repo that it doesn't.")
+(put 'magit--default-directory 'permanent-local t)
+
+(defun magit-mode-get-buffers ()
+ (let ((topdir (magit-toplevel)))
+ (--filter (with-current-buffer it
+ (and (derived-mode-p 'magit-mode)
+ (equal magit--default-directory topdir)))
+ (buffer-list))))
+
+(defvar-local magit-buffer-locked-p nil)
+(put 'magit-buffer-locked-p 'permanent-local t)
+
+(defun magit-get-mode-buffer (mode &optional value frame)
+ "Return buffer belonging to the current repository whose major-mode is MODE.
+
+If no such buffer exists then return nil. Multiple buffers with
+the same major-mode may exist for a repository but only one can
+exist that hasn't been locked to its value. Return that buffer
+\(or nil if there is no such buffer) unless VALUE is non-nil, in
+which case return the buffer that has been locked to that value.
+
+If FRAME is nil or omitted, then consider all buffers. Otherwise
+ only consider buffers that are displayed in some live window
+ on some frame.
+If `all', then consider all buffers on all frames.
+If `visible', then only consider buffers on all visible frames.
+If `selected' or t, then only consider buffers on the selected
+ frame.
+If a frame, then only consider buffers on that frame."
+ (if-let ((topdir (magit-toplevel)))
+ (cl-flet* ((b (buffer)
+ (with-current-buffer buffer
+ (and (eq major-mode mode)
+ (equal magit--default-directory topdir)
+ (if value
+ (and magit-buffer-locked-p
+ (equal (magit-buffer-value) value))
+ (not magit-buffer-locked-p))
+ buffer)))
+ (w (window)
+ (b (window-buffer window)))
+ (f (frame)
+ (seq-some #'w (window-list frame 'no-minibuf))))
+ (pcase-exhaustive frame
+ ('nil (seq-some #'b (buffer-list)))
+ ('all (seq-some #'f (frame-list)))
+ ('visible (seq-some #'f (visible-frame-list)))
+ ((or 'selected 't) (seq-some #'w (window-list (selected-frame))))
+ ((guard (framep frame)) (seq-some #'w (window-list frame)))))
+ (magit--not-inside-repository-error)))
+
+(defun magit-mode-get-buffer (mode &optional create frame value)
+ (declare (obsolete magit-get-mode-buffer "Magit 3.0.0"))
+ (when create
+ (error "`magit-mode-get-buffer's CREATE argument is obsolete"))
+ (if-let ((topdir (magit-toplevel)))
+ (--first (with-current-buffer it
+ (and (eq major-mode mode)
+ (equal magit--default-directory topdir)
+ (if value
+ (and magit-buffer-locked-p
+ (equal (magit-buffer-value) value))
+ (not magit-buffer-locked-p))))
+ (if frame
+ (mapcar #'window-buffer
+ (window-list (unless (eq frame t) frame)))
+ (buffer-list)))
+ (magit--not-inside-repository-error)))
+
+(defun magit-generate-new-buffer (mode &optional value)
+ (let* ((name (funcall magit-generate-buffer-name-function mode value))
+ (buffer (generate-new-buffer name)))
+ (with-current-buffer buffer
+ (setq magit--default-directory default-directory)
+ (setq magit-buffer-locked-p (and value t))
+ (magit-restore-section-visibility-cache mode))
+ (when magit-uniquify-buffer-names
+ (add-to-list 'uniquify-list-buffers-directory-modes mode)
+ (with-current-buffer buffer
+ (setq list-buffers-directory (abbreviate-file-name default-directory)))
+ (let ((uniquify-buffer-name-style
+ (if (memq uniquify-buffer-name-style '(nil forward))
+ 'post-forward-angle-brackets
+ uniquify-buffer-name-style)))
+ (uniquify-rationalize-file-buffer-names
+ name (file-name-directory (directory-file-name default-directory))
+ buffer)))
+ buffer))
+
+(defun magit-generate-buffer-name-default-function (mode &optional value)
+ "Generate buffer name for a MODE buffer in the current repository.
+The returned name is based on `magit-buffer-name-format' and
+takes `magit-uniquify-buffer-names' and VALUE, if non-nil, into
+account."
+ (let ((m (substring (symbol-name mode) 0 -5))
+ (v (and value (format "%s" (if (listp value) value (list value)))))
+ (n (if magit-uniquify-buffer-names
+ (file-name-nondirectory
+ (directory-file-name default-directory))
+ (abbreviate-file-name default-directory))))
+ (format-spec
+ magit-buffer-name-format
+ `((?m . ,m)
+ (?M . ,(if (eq mode 'magit-status-mode) "magit" m))
+ (?v . ,(or v ""))
+ (?V . ,(if v (concat " " v) ""))
+ (?t . ,n)
+ (?x . ,(if magit-uniquify-buffer-names "" "*"))
+ (?T . ,(if magit-uniquify-buffer-names n (concat n "*")))))))
+
+;;; Buffer Lock
+
+(defun magit-toggle-buffer-lock ()
+ "Lock the current buffer to its value or unlock it.
+
+Locking a buffer to its value prevents it from being reused to
+display another value. The name of a locked buffer contains its
+value, which allows telling it apart from other locked buffers
+and the unlocked buffer.
+
+Not all Magit buffers can be locked to their values, for example
+it wouldn't make sense to lock a status buffer.
+
+There can only be a single unlocked buffer using a certain
+major-mode per repository. So when a buffer is being unlocked
+and another unlocked buffer already exists for that mode and
+repository, then the former buffer is instead deleted and the
+latter is displayed in its place."
+ (interactive)
+ (if magit-buffer-locked-p
+ (if-let ((unlocked (magit-get-mode-buffer major-mode)))
+ (let ((locked (current-buffer)))
+ (switch-to-buffer unlocked nil t)
+ (kill-buffer locked))
+ (setq magit-buffer-locked-p nil)
+ (rename-buffer (funcall magit-generate-buffer-name-function
+ major-mode)))
+ (if-let ((value (magit-buffer-value)))
+ (if-let ((locked (magit-get-mode-buffer major-mode value)))
+ (let ((unlocked (current-buffer)))
+ (switch-to-buffer locked nil t)
+ (kill-buffer unlocked))
+ (setq magit-buffer-locked-p t)
+ (rename-buffer (funcall magit-generate-buffer-name-function
+ major-mode value)))
+ (user-error "Buffer has no value it could be locked to"))))
+
+;;; Bury Buffer
+
+(defun magit-mode-bury-buffer (&optional kill-buffer)
+ "Bury the current buffer.
+With a prefix argument, kill the buffer instead.
+With two prefix arguments, also kill all Magit buffers associated
+with this repository.
+This is done using `magit-bury-buffer-function'."
+ (interactive "P")
+ ;; Kill all associated Magit buffers when a double prefix arg is given.
+ (when (>= (prefix-numeric-value kill-buffer) 16)
+ (let ((current (current-buffer)))
+ (dolist (buf (magit-mode-get-buffers))
+ (unless (eq buf current)
+ (kill-buffer buf)))))
+ (funcall magit-bury-buffer-function kill-buffer))
+
+(defun magit-mode-quit-window (kill-buffer)
+ "Quit the selected window and bury its buffer.
+
+This behaves similar to `quit-window', but when the window
+was originally created to display a Magit buffer and the
+current buffer is the last remaining Magit buffer that was
+ever displayed in the selected window, then delete that
+window."
+ (if (or (one-window-p)
+ (--first (let ((buffer (car it)))
+ (and (not (eq buffer (current-buffer)))
+ (buffer-live-p buffer)
+ (or (not (window-parameter nil 'magit-dedicated))
+ (with-current-buffer buffer
+ (derived-mode-p 'magit-mode
+ 'magit-process-mode)))))
+ (window-prev-buffers)))
+ (quit-window kill-buffer)
+ (let ((window (selected-window)))
+ (quit-window kill-buffer)
+ (when (window-live-p window)
+ (delete-window window)))))
+
+;;; Refresh Buffers
+
+(defvar magit-inhibit-refresh nil)
+
+(defun magit-refresh ()
+ "Refresh some buffers belonging to the current repository.
+
+Refresh the current buffer if its major mode derives from
+`magit-mode', and refresh the corresponding status buffer.
+
+Run hooks `magit-pre-refresh-hook' and `magit-post-refresh-hook'."
+ (interactive)
+ (unless magit-inhibit-refresh
+ (unwind-protect
+ (let ((start (current-time))
+ (magit--refresh-cache (or magit--refresh-cache
+ (list (cons 0 0)))))
+ (when magit-refresh-verbose
+ (message "Refreshing magit..."))
+ (magit-run-hook-with-benchmark 'magit-pre-refresh-hook)
+ (cond ((derived-mode-p 'magit-mode)
+ (magit-refresh-buffer))
+ ((derived-mode-p 'tabulated-list-mode)
+ (revert-buffer)))
+ (--when-let (and magit-refresh-status-buffer
+ (not (derived-mode-p 'magit-status-mode))
+ (magit-get-mode-buffer 'magit-status-mode))
+ (with-current-buffer it
+ (magit-refresh-buffer)))
+ (magit-auto-revert-buffers)
+ (cond
+ ((and (not this-command)
+ (memq last-command magit-post-commit-hook-commands))
+ (magit-run-hook-with-benchmark 'magit-post-commit-hook))
+ ((memq this-command magit-post-stage-hook-commands)
+ (magit-run-hook-with-benchmark 'magit-post-stage-hook))
+ ((memq this-command magit-post-unstage-hook-commands)
+ (magit-run-hook-with-benchmark 'magit-post-unstage-hook)))
+ (magit-run-hook-with-benchmark 'magit-post-refresh-hook)
+ (when magit-refresh-verbose
+ (let* ((c (caar magit--refresh-cache))
+ (a (+ c (cdar magit--refresh-cache))))
+ (message "Refreshing magit...done (%.3fs, cached %s/%s (%.0f%%))"
+ (float-time (time-subtract (current-time) start))
+ c a (* (/ c (* a 1.0)) 100)))))
+ (run-hooks 'magit-unwind-refresh-hook))))
+
+(defun magit-refresh-all ()
+ "Refresh all buffers belonging to the current repository.
+
+Refresh all Magit buffers belonging to the current repository,
+and revert buffers that visit files located inside the current
+repository.
+
+Run hooks `magit-pre-refresh-hook' and `magit-post-refresh-hook'."
+ (interactive)
+ (magit-run-hook-with-benchmark 'magit-pre-refresh-hook)
+ (dolist (buffer (magit-mode-get-buffers))
+ (with-current-buffer buffer (magit-refresh-buffer)))
+ (magit-auto-revert-buffers)
+ (magit-run-hook-with-benchmark 'magit-post-refresh-hook))
+
+(defvar-local magit-refresh-start-time nil)
+
+(defun magit-refresh-buffer (&rest _ignore)
+ "Refresh the current Magit buffer."
+ (setq magit-refresh-start-time (current-time))
+ (let ((refresh (intern (format "%s-refresh-buffer"
+ (substring (symbol-name major-mode) 0 -5))))
+ (magit--refresh-cache (or magit--refresh-cache (list (cons 0 0)))))
+ (when (functionp refresh)
+ (when magit-refresh-verbose
+ (message "Refreshing buffer `%s'..." (buffer-name)))
+ (let* ((buffer (current-buffer))
+ (windows (cl-mapcan
+ (lambda (window)
+ (with-selected-window window
+ (with-current-buffer buffer
+ (and-let* ((section (magit-section-at)))
+ `(( ,window
+ ,section
+ ,@(magit-refresh-get-relative-position)))))))
+ ;; If it qualifies, then the selected window
+ ;; comes first, but we want to handle it last
+ ;; so that its `magit-section-movement-hook'
+ ;; run can override the effects of other runs.
+ (or (nreverse (get-buffer-window-list buffer nil t))
+ (list (selected-window))))))
+ (deactivate-mark)
+ (setq magit-section-pre-command-section nil)
+ (setq magit-section-highlight-overlays nil)
+ (setq magit-section-highlighted-sections nil)
+ (setq magit-section-unhighlight-sections nil)
+ (magit-process-unset-mode-line-error-status)
+ (let ((inhibit-read-only t))
+ (erase-buffer)
+ (save-excursion
+ (apply refresh (with-no-warnings magit-refresh-args))))
+ (pcase-dolist (`(,window . ,args) windows)
+ (if (eq buffer (window-buffer window))
+ (with-selected-window window
+ (apply #'magit-section-goto-successor args))
+ (with-current-buffer buffer
+ (let ((magit-section-movement-hook nil))
+ (apply #'magit-section-goto-successor args)))))
+ (run-hooks 'magit-refresh-buffer-hook)
+ (magit-section-update-highlight)
+ (set-buffer-modified-p nil))
+ (when magit-refresh-verbose
+ (message "Refreshing buffer `%s'...done (%.3fs)" (buffer-name)
+ (float-time (time-subtract (current-time)
+ magit-refresh-start-time)))))))
+
+(defun magit-refresh-get-relative-position ()
+ (and-let* ((section (magit-current-section))
+ (start (oref section start))
+ (point (magit-point)))
+ (list (- (line-number-at-pos point)
+ (line-number-at-pos start))
+ (- point (line-beginning-position))
+ (and (magit-hunk-section-p section)
+ (region-active-p)
+ (progn (goto-char (line-beginning-position))
+ (when (looking-at "^[-+]") (forward-line))
+ (while (looking-at "^[ @]") (forward-line))
+ (let ((beg point))
+ (cond ((looking-at "^[-+]")
+ (forward-line)
+ (while (looking-at "^[-+]") (forward-line))
+ (while (looking-at "^ ") (forward-line))
+ (forward-line -1)
+ (regexp-quote (buffer-substring-no-properties
+ beg (line-end-position))))
+ (t t))))))))
+
+;;; Save File-Visiting Buffers
+
+(defvar disable-magit-save-buffers nil)
+
+(defun magit-pre-command-hook ()
+ (setq disable-magit-save-buffers nil))
+(add-hook 'pre-command-hook #'magit-pre-command-hook)
+
+(defvar magit-after-save-refresh-buffers nil)
+
+(defun magit-after-save-refresh-buffers ()
+ (dolist (buffer magit-after-save-refresh-buffers)
+ (when (buffer-live-p buffer)
+ (with-current-buffer buffer
+ (magit-refresh-buffer))))
+ (setq magit-after-save-refresh-buffers nil)
+ (remove-hook 'post-command-hook #'magit-after-save-refresh-buffers))
+
+(defun magit-after-save-refresh-status ()
+ "Refresh the status buffer of the current repository.
+
+This function is intended to be added to `after-save-hook'.
+
+If the status buffer does not exist or the file being visited in
+the current buffer isn't inside the working tree of a repository,
+then do nothing.
+
+Note that refreshing a Magit buffer is done by re-creating its
+contents from scratch, which can be slow in large repositories.
+If you are not satisfied with Magit's performance, then you
+should obviously not add this function to that hook."
+ (when (and (not disable-magit-save-buffers)
+ (magit-inside-worktree-p t))
+ (--when-let (ignore-errors (magit-get-mode-buffer 'magit-status-mode))
+ (add-to-list 'magit-after-save-refresh-buffers it)
+ (add-hook 'post-command-hook #'magit-after-save-refresh-buffers))))
+
+(defun magit-maybe-save-repository-buffers ()
+ "Maybe save file-visiting buffers belonging to the current repository.
+Do so if `magit-save-repository-buffers' is non-nil. You should
+not remove this from any hooks, instead set that variable to nil
+if you so desire."
+ (when (and magit-save-repository-buffers
+ (not disable-magit-save-buffers))
+ (setq disable-magit-save-buffers t)
+ (let ((msg (current-message)))
+ (magit-save-repository-buffers
+ (eq magit-save-repository-buffers 'dontask))
+ (when (and msg
+ (current-message)
+ (not (equal msg (current-message))))
+ (message "%s" msg)))))
+
+(add-hook 'magit-pre-refresh-hook #'magit-maybe-save-repository-buffers)
+(add-hook 'magit-pre-call-git-hook #'magit-maybe-save-repository-buffers)
+(add-hook 'magit-pre-start-git-hook #'magit-maybe-save-repository-buffers)
+
+(defvar-local magit-inhibit-refresh-save nil)
+
+(defun magit-save-repository-buffers (&optional arg)
+ "Save file-visiting buffers belonging to the current repository.
+After any buffer where `buffer-save-without-query' is non-nil
+is saved without asking, the user is asked about each modified
+buffer which visits a file in the current repository. Optional
+argument (the prefix) non-nil means save all with no questions."
+ (interactive "P")
+ (when-let ((topdir (magit-rev-parse-safe "--show-toplevel")))
+ (let ((remote (file-remote-p default-directory))
+ (save-some-buffers-action-alist
+ `((?Y (lambda (buffer)
+ (with-current-buffer buffer
+ (setq buffer-save-without-query t)
+ (save-buffer)))
+ "to save the current buffer and remember choice")
+ (?N (lambda (buffer)
+ (with-current-buffer buffer
+ (setq magit-inhibit-refresh-save t)))
+ "to skip the current buffer and remember choice")
+ ,@save-some-buffers-action-alist)))
+ (save-some-buffers
+ arg (lambda ()
+ (and buffer-file-name
+ ;; - Check whether refreshing is disabled.
+ (not magit-inhibit-refresh-save)
+ ;; - Check whether the visited file is either on the
+ ;; same remote as the repository, or both are on
+ ;; the local system.
+ (equal (file-remote-p buffer-file-name) remote)
+ ;; Delayed checks that are more expensive for remote
+ ;; repositories, due to the required network access.
+ ;; - Check whether the file is inside the repository.
+ (equal (magit-rev-parse-safe "--show-toplevel") topdir)
+ ;; - Check whether the file is actually writable.
+ (file-writable-p buffer-file-name)))))))
+
+;;; Restore Window Configuration
+
+(defvar magit-inhibit-save-previous-winconf nil)
+
+(defvar-local magit-previous-window-configuration nil)
+(put 'magit-previous-window-configuration 'permanent-local t)
+
+(defun magit-save-window-configuration ()
+ "Save the current window configuration.
+
+Later, when the buffer is buried, it may be restored by
+`magit-restore-window-configuration'."
+ (if magit-inhibit-save-previous-winconf
+ (when (eq magit-inhibit-save-previous-winconf 'unset)
+ (setq magit-previous-window-configuration nil))
+ (unless (get-buffer-window (current-buffer) (selected-frame))
+ (setq magit-previous-window-configuration
+ (current-window-configuration)))))
+
+(defun magit-restore-window-configuration (&optional kill-buffer)
+ "Bury or kill the current buffer and restore previous window configuration."
+ (let ((winconf magit-previous-window-configuration)
+ (buffer (current-buffer))
+ (frame (selected-frame)))
+ (quit-window kill-buffer (selected-window))
+ (when (and winconf (equal frame (window-configuration-frame winconf)))
+ (set-window-configuration winconf)
+ (when (buffer-live-p buffer)
+ (with-current-buffer buffer
+ (setq magit-previous-window-configuration nil))))))
+
+;;; Buffer History
+
+(defun magit-go-backward ()
+ "Move backward in current buffer's history."
+ (interactive)
+ (if help-xref-stack
+ (help-xref-go-back (current-buffer))
+ (user-error "No previous entry in buffer's history")))
+
+(defun magit-go-forward ()
+ "Move forward in current buffer's history."
+ (interactive)
+ (if help-xref-forward-stack
+ (help-xref-go-forward (current-buffer))
+ (user-error "No next entry in buffer's history")))
+
+(defun magit-insert-xref-buttons ()
+ "Insert xref buttons."
+ (when (and (not magit-buffer-locked-p)
+ (or help-xref-stack help-xref-forward-stack))
+ (when help-xref-stack
+ (magit-xref-insert-button help-back-label 'magit-xref-backward))
+ (when help-xref-forward-stack
+ (when help-xref-stack
+ (insert " "))
+ (magit-xref-insert-button help-forward-label 'magit-xref-forward))))
+
+(defun magit-xref-insert-button (label type)
+ (magit-insert-section (button label)
+ (insert-text-button label 'type type
+ 'help-args (list (current-buffer)))))
+
+(define-button-type 'magit-xref-backward
+ :supertype 'help-back
+ 'mouse-face 'magit-section-highlight
+ 'help-echo (purecopy "mouse-2, RET: go back to previous history entry"))
+
+(define-button-type 'magit-xref-forward
+ :supertype 'help-forward
+ 'mouse-face 'magit-section-highlight
+ 'help-echo (purecopy "mouse-2, RET: go back to next history entry"))
+
+(defvar magit-xref-modes
+ '(magit-log-mode
+ magit-reflog-mode
+ magit-diff-mode
+ magit-revision-mode)
+ "List of modes for which to insert navigation buttons.")
+
+(defun magit-xref-setup (fn args)
+ (when (memq major-mode magit-xref-modes)
+ (when help-xref-stack-item
+ (push (cons (point) help-xref-stack-item) help-xref-stack)
+ (setq help-xref-forward-stack nil))
+ (when (called-interactively-p 'interactive)
+ (--when-let (nthcdr 10 help-xref-stack)
+ (setcdr it nil)))
+ (setq help-xref-stack-item
+ (list 'magit-xref-restore fn default-directory args))))
+
+(defun magit-xref-restore (fn dir args)
+ (setq default-directory dir)
+ (funcall fn major-mode nil args)
+ (magit-refresh-buffer))
+
+;;; Repository-Local Cache
+
+(defvar magit-repository-local-cache nil
+ "Alist mapping `magit-toplevel' paths to alists of key/value pairs.")
+
+(defun magit-repository-local-repository ()
+ "Return the key for the current repository."
+ (or (bound-and-true-p magit--default-directory)
+ (magit-toplevel)))
+
+(defun magit-repository-local-set (key value &optional repository)
+ "Set the repository-local VALUE for KEY.
+
+Unless specified, REPOSITORY is the current buffer's repository.
+
+If REPOSITORY is nil (meaning there is no current repository),
+then the value is not cached, and we return nil."
+ (let* ((repokey (or repository (magit-repository-local-repository)))
+ (cache (assoc repokey magit-repository-local-cache)))
+ ;; Don't cache values for a nil REPOSITORY, as the 'set' and 'get'
+ ;; calls for some KEY may happen in unrelated contexts.
+ (when repokey
+ (if cache
+ (let ((keyvalue (assoc key (cdr cache))))
+ (if keyvalue
+ ;; Update pre-existing value for key.
+ (setcdr keyvalue value)
+ ;; No such key in repository-local cache.
+ (push (cons key value) (cdr cache))))
+ ;; No cache for this repository.
+ (push (cons repokey (list (cons key value)))
+ magit-repository-local-cache)))))
+
+(defun magit-repository-local-exists-p (key &optional repository)
+ "Non-nil when a repository-local value exists for KEY.
+
+Return a (KEY . VALUE) cons cell.
+
+The KEY is matched using `equal'.
+
+Unless specified, REPOSITORY is the current buffer's repository."
+ (and-let* ((cache (assoc (or repository
+ (magit-repository-local-repository))
+ magit-repository-local-cache)))
+ (assoc key (cdr cache))))
+
+(defun magit-repository-local-get (key &optional default repository)
+ "Return the repository-local value for KEY.
+
+Return DEFAULT if no value for KEY exists.
+
+The KEY is matched using `equal'.
+
+Unless specified, REPOSITORY is the current buffer's repository."
+ (if-let ((keyvalue (magit-repository-local-exists-p key repository)))
+ (cdr keyvalue)
+ default))
+
+(defun magit-repository-local-delete (key &optional repository)
+ "Delete the repository-local value for KEY.
+
+Unless specified, REPOSITORY is the current buffer's repository."
+ (when-let ((cache (assoc (or repository
+ (magit-repository-local-repository))
+ magit-repository-local-cache)))
+ (setf cache (compat-assoc-delete-all key cache))))
+
+(defmacro magit--with-repository-local-cache (key &rest body)
+ (declare (indent 1) (debug (form body)))
+ (let ((k (cl-gensym)))
+ `(let ((,k ,key))
+ (if-let ((kv (magit-repository-local-exists-p ,k)))
+ (cdr kv)
+ (let ((v ,(macroexp-progn body)))
+ (magit-repository-local-set ,k v)
+ v)))))
+
+(defun magit-preserve-section-visibility-cache ()
+ (when (derived-mode-p 'magit-status-mode 'magit-refs-mode)
+ (magit-repository-local-set
+ (cons major-mode 'magit-section-visibility-cache)
+ magit-section-visibility-cache)))
+
+(defun magit-restore-section-visibility-cache (mode)
+ (setq magit-section-visibility-cache
+ (magit-repository-local-get
+ (cons mode 'magit-section-visibility-cache))))
+
+(defun magit-zap-caches (&optional all)
+ "Zap caches for the current repository.
+
+Remove the repository's entry from `magit-repository-local-cache',
+remove the host's entry from `magit--host-git-version-cache', set
+`magit-section-visibility-cache' to nil for all Magit buffers of
+the repository and set `magit--libgit-available-p' to `unknown'.
+
+With a prefix argument or if optional ALL is non-nil, discard the
+mentioned caches completely."
+ (interactive)
+ (cond (all
+ (setq magit-repository-local-cache nil)
+ (setq magit--host-git-version-cache nil)
+ (dolist (buffer (buffer-list))
+ (with-current-buffer buffer
+ (when (derived-mode-p 'magit-mode)
+ (setq magit-section-visibility-cache nil)))))
+ (t
+ (magit-with-toplevel
+ (setq magit-repository-local-cache
+ (cl-delete default-directory
+ magit-repository-local-cache
+ :key #'car :test #'equal))
+ (setq magit--host-git-version-cache
+ (cl-delete (file-remote-p default-directory)
+ magit--host-git-version-cache
+ :key #'car :test #'equal)))
+ (dolist (buffer (magit-mode-get-buffers))
+ (with-current-buffer buffer
+ (setq magit-section-visibility-cache nil)))))
+ (setq magit--libgit-available-p 'unknown))
+
+;;; Imenu Support
+
+(defun magit--imenu-create-index ()
+ ;; If `which-function-mode' is active, then the create-index
+ ;; function is called at the time the major-mode is being enabled.
+ ;; Modes that derive from `magit-mode' have not populated the buffer
+ ;; at that time yet, so we have to abort.
+ (and magit-root-section
+ (or magit--imenu-group-types
+ magit--imenu-item-types)
+ (let ((index
+ (cl-mapcan
+ (lambda (section)
+ (cond
+ (magit--imenu-group-types
+ (and (if (eq (car-safe magit--imenu-group-types) 'not)
+ (not (magit-section-match
+ (cdr magit--imenu-group-types)
+ section))
+ (magit-section-match magit--imenu-group-types section))
+ (and-let* ((children (oref section children)))
+ `((,(magit--imenu-index-name section)
+ ,@(mapcar (lambda (s)
+ (cons (magit--imenu-index-name s)
+ (oref s start)))
+ children))))))
+ (magit--imenu-item-types
+ (and (magit-section-match magit--imenu-item-types section)
+ `((,(magit--imenu-index-name section)
+ . ,(oref section start)))))))
+ (oref magit-root-section children))))
+ (if (and magit--imenu-group-types (symbolp magit--imenu-group-types))
+ (cdar index)
+ index))))
+
+(defun magit--imenu-index-name (section)
+ (let ((heading (buffer-substring-no-properties
+ (oref section start)
+ (1- (or (oref section content)
+ (oref section end))))))
+ (save-match-data
+ (cond
+ ((and (magit-section-match [commit logbuf] section)
+ (string-match "[^ ]+\\([ *|]*\\).+" heading))
+ (replace-match " " t t heading 1))
+ ((magit-section-match
+ '([branch local branchbuf] [tag tags branchbuf]) section)
+ (oref section value))
+ ((magit-section-match [branch remote branchbuf] section)
+ (concat (oref (oref section parent) value) "/"
+ (oref section value)))
+ ((string-match " ([0-9]+)\\'" heading)
+ (substring heading 0 (match-beginning 0)))
+ (t heading)))))
+
+;;; Utilities
+
+(defun magit-toggle-verbose-refresh ()
+ "Toggle whether Magit refreshes buffers verbosely.
+Enabling this helps figuring out which sections are bottlenecks.
+The additional output can be found in the *Messages* buffer."
+ (interactive)
+ (setq magit-refresh-verbose (not magit-refresh-verbose))
+ (message "%s verbose refreshing"
+ (if magit-refresh-verbose "Enabled" "Disabled")))
+
+(defun magit-run-hook-with-benchmark (hook)
+ (when hook
+ (if magit-refresh-verbose
+ (let ((start (current-time)))
+ (message "Running %s..." hook)
+ (run-hooks hook)
+ (message "Running %s...done (%.3fs)" hook
+ (float-time (time-subtract (current-time) start))))
+ (run-hooks hook))))
+
+;;; _
+(provide 'magit-mode)
+;;; magit-mode.el ends here
diff --git a/elpa/magit-20220503.1245/magit-mode.elc b/elpa/magit-20220503.1245/magit-mode.elc
new file mode 100644
index 0000000..bb155ab
--- /dev/null
+++ b/elpa/magit-20220503.1245/magit-mode.elc
Binary files differ
diff --git a/elpa/magit-20220503.1245/magit-notes.el b/elpa/magit-20220503.1245/magit-notes.el
new file mode 100644
index 0000000..8df09bb
--- /dev/null
+++ b/elpa/magit-20220503.1245/magit-notes.el
@@ -0,0 +1,201 @@
+;;; magit-notes.el --- Notes support -*- lexical-binding:t -*-
+
+;; Copyright (C) 2008-2022 The Magit Project Contributors
+
+;; Author: Jonas Bernoulli <jonas@bernoul.li>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+
+;; SPDX-License-Identifier: GPL-3.0-or-later
+
+;; Magit 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.
+;;
+;; Magit 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 Magit. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This library implements support for `git-notes'.
+
+;;; Code:
+
+(require 'magit)
+
+;;; Commands
+
+;;;###autoload (autoload 'magit-notes "magit" nil t)
+(transient-define-prefix magit-notes ()
+ "Edit notes attached to commits."
+ :man-page "git-notes"
+ ["Configure local settings"
+ ("c" magit-core.notesRef)
+ ("d" magit-notes.displayRef)]
+ ["Configure global settings"
+ ("C" magit-global-core.notesRef)
+ ("D" magit-global-notes.displayRef)]
+ ["Arguments for prune"
+ :if-not magit-notes-merging-p
+ ("-n" "Dry run" ("-n" "--dry-run"))]
+ ["Arguments for edit and remove"
+ :if-not magit-notes-merging-p
+ (magit-notes:--ref)]
+ ["Arguments for merge"
+ :if-not magit-notes-merging-p
+ (magit-notes:--strategy)]
+ ["Actions"
+ :if-not magit-notes-merging-p
+ ("T" "Edit" magit-notes-edit)
+ ("r" "Remove" magit-notes-remove)
+ ("m" "Merge" magit-notes-merge)
+ ("p" "Prune" magit-notes-prune)]
+ ["Actions"
+ :if magit-notes-merging-p
+ ("c" "Commit merge" magit-notes-merge-commit)
+ ("a" "Abort merge" magit-notes-merge-abort)])
+
+(defun magit-notes-merging-p ()
+ (let ((dir (magit-git-dir "NOTES_MERGE_WORKTREE")))
+ (and (file-directory-p dir)
+ (directory-files dir nil "^[^.]"))))
+
+(transient-define-infix magit-core.notesRef ()
+ :class 'magit--git-variable
+ :variable "core.notesRef"
+ :reader #'magit-notes-read-ref
+ :prompt "Set local core.notesRef")
+
+(transient-define-infix magit-notes.displayRef ()
+ :class 'magit--git-variable
+ :variable "notes.displayRef"
+ :multi-value t
+ :reader #'magit-notes-read-refs
+ :prompt "Set local notes.displayRef")
+
+(transient-define-infix magit-global-core.notesRef ()
+ :class 'magit--git-variable
+ :variable "core.notesRef"
+ :global t
+ :reader #'magit-notes-read-ref
+ :prompt "Set global core.notesRef")
+
+(transient-define-infix magit-global-notes.displayRef ()
+ :class 'magit--git-variable
+ :variable "notes.displayRef"
+ :global t
+ :multi-value t
+ :reader #'magit-notes-read-refs
+ :prompt "Set global notes.displayRef")
+
+(transient-define-argument magit-notes:--ref ()
+ :description "Manipulate ref"
+ :class 'transient-option
+ :key "-r"
+ :argument "--ref="
+ :reader #'magit-notes-read-ref)
+
+(transient-define-argument magit-notes:--strategy ()
+ :description "Merge strategy"
+ :class 'transient-option
+ :shortarg "-s"
+ :argument "--strategy="
+ :choices '("manual" "ours" "theirs" "union" "cat_sort_uniq"))
+
+(defun magit-notes-edit (commit &optional ref)
+ "Edit the note attached to COMMIT.
+REF is the notes ref used to store the notes.
+
+Interactively or when optional REF is nil use the value of Git
+variable `core.notesRef' or \"refs/notes/commits\" if that is
+undefined."
+ (interactive (magit-notes-read-args "Edit notes"))
+ (magit-run-git-with-editor "notes" (and ref (concat "--ref=" ref))
+ "edit" commit))
+
+(defun magit-notes-remove (commit &optional ref)
+ "Remove the note attached to COMMIT.
+REF is the notes ref from which the note is removed.
+
+Interactively or when optional REF is nil use the value of Git
+variable `core.notesRef' or \"refs/notes/commits\" if that is
+undefined."
+ (interactive (magit-notes-read-args "Remove notes"))
+ (magit-run-git-with-editor "notes" (and ref (concat "--ref=" ref))
+ "remove" commit))
+
+(defun magit-notes-merge (ref)
+ "Merge the notes ref REF into the current notes ref.
+
+The current notes ref is the value of Git variable
+`core.notesRef' or \"refs/notes/commits\" if that is undefined.
+
+When there are conflicts, then they have to be resolved in the
+temporary worktree \".git/NOTES_MERGE_WORKTREE\". When
+done use `magit-notes-merge-commit' to finish. To abort
+use `magit-notes-merge-abort'."
+ (interactive (list (magit-read-string-ns "Merge reference")))
+ (magit-run-git-with-editor "notes" "merge" ref))
+
+(defun magit-notes-merge-commit ()
+ "Commit the current notes ref merge.
+Also see `magit-notes-merge'."
+ (interactive)
+ (magit-run-git-with-editor "notes" "merge" "--commit"))
+
+(defun magit-notes-merge-abort ()
+ "Abort the current notes ref merge.
+Also see `magit-notes-merge'."
+ (interactive)
+ (magit-run-git-with-editor "notes" "merge" "--abort"))
+
+(defun magit-notes-prune (&optional dry-run)
+ "Remove notes about unreachable commits."
+ (interactive (list (and (member "--dry-run" (transient-args 'magit-notes)) t)))
+ (when dry-run
+ (magit-process-buffer))
+ (magit-run-git-with-editor "notes" "prune" (and dry-run "--dry-run")))
+
+;;; Readers
+
+(defun magit-notes-read-ref (prompt _initial-input history)
+ (and-let* ((ref (magit-completing-read
+ prompt (magit-list-notes-refnames) nil nil
+ (and-let* ((def (magit-get "core.notesRef")))
+ (if (string-prefix-p "refs/notes/" def)
+ (substring def 11)
+ def))
+ history)))
+ (if (string-prefix-p "refs/" ref)
+ ref
+ (concat "refs/notes/" ref))))
+
+(defun magit-notes-read-refs (prompt &optional _initial-input _history)
+ (mapcar (lambda (ref)
+ (if (string-prefix-p "refs/" ref)
+ ref
+ (concat "refs/notes/" ref)))
+ (completing-read-multiple
+ (concat prompt ": ")
+ (magit-list-notes-refnames) nil nil
+ (mapconcat (lambda (ref)
+ (if (string-prefix-p "refs/notes/" ref)
+ (substring ref 11)
+ ref))
+ (magit-get-all "notes.displayRef")
+ ","))))
+
+(defun magit-notes-read-args (prompt)
+ (list (magit-read-branch-or-commit prompt (magit-stash-at-point))
+ (and-let* ((str (--first (string-match "^--ref=\\(.+\\)" it)
+ (transient-args 'magit-notes))))
+ (match-string 1 str))))
+
+;;; _
+(provide 'magit-notes)
+;;; magit-notes.el ends here
diff --git a/elpa/magit-20220503.1245/magit-notes.elc b/elpa/magit-20220503.1245/magit-notes.elc
new file mode 100644
index 0000000..3baa517
--- /dev/null
+++ b/elpa/magit-20220503.1245/magit-notes.elc
Binary files differ
diff --git a/elpa/magit-20220503.1245/magit-obsolete.el b/elpa/magit-20220503.1245/magit-obsolete.el
new file mode 100644
index 0000000..4d27752
--- /dev/null
+++ b/elpa/magit-20220503.1245/magit-obsolete.el
@@ -0,0 +1,111 @@
+;;; magit-obsolete.el --- Obsolete definitions -*- lexical-binding:t -*-
+
+;; Copyright (C) 2008-2022 The Magit Project Contributors
+
+;; Author: Jonas Bernoulli <jonas@bernoul.li>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+
+;; SPDX-License-Identifier: GPL-3.0-or-later
+
+;; Magit 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.
+;;
+;; Magit 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 Magit. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This library defines aliases for obsolete variables and functions.
+
+;;; Code:
+
+(require 'magit)
+
+;;; Obsolete since v3.0.0
+
+(define-obsolete-function-alias 'magit-diff-visit-file-worktree
+ #'magit-diff-visit-worktree-file "Magit 3.0.0")
+
+(define-obsolete-function-alias 'magit-status-internal
+ #'magit-status-setup-buffer "Magit 3.0.0")
+
+(define-obsolete-variable-alias 'magit-mode-setup-hook
+ 'magit-setup-buffer-hook "Magit 3.0.0")
+
+(define-obsolete-variable-alias 'magit-branch-popup-show-variables
+ 'magit-branch-direct-configure "Magit 3.0.0")
+
+(define-obsolete-function-alias 'magit-dispatch-popup
+ #'magit-dispatch "Magit 3.0.0")
+
+(define-obsolete-function-alias 'magit-repolist-column-dirty
+ #'magit-repolist-column-flag "Magit 3.0.0")
+
+(define-obsolete-variable-alias 'magit-disable-line-numbers
+ 'magit-section-disable-line-numbers "Magit 3.0.0")
+
+(define-obsolete-variable-alias 'inhibit-magit-refresh
+ 'magit-inhibit-refresh "Magit 3.0.0")
+
+(defun magit--magit-popup-warning ()
+ (display-warning 'magit "\
+Magit no longer uses Magit-Popup.
+It now uses Transient.
+See https://emacsair.me/2019/02/14/transient-0.1.
+
+However your configuration and/or some third-party package that
+you use still depends on the `magit-popup' package. But because
+`magit' no longer depends on that, `package' has removed it from
+your system.
+
+If some package that you use still depends on `magit-popup' but
+does not declare it as a dependency, then please contact its
+maintainer about that and install `magit-popup' explicitly.
+
+If you yourself use functions that are defined in `magit-popup'
+in your configuration, then the next step depends on what you use
+that for.
+
+* If you use `magit-popup' to define your own popups but do not
+ modify any of Magit's old popups, then you have to install
+ `magit-popup' explicitly. (You can also migrate to Transient,
+ but there is no need to rush that.)
+
+* If you add additional arguments and/or actions to Magit's popups,
+ then you have to port that to modify the new \"transients\" instead.
+ See https://github.com/magit/magit/wiki/\
+Converting-popup-modifications-to-transient-modifications
+
+To find installed packages that still use `magit-popup' you can
+use e.g. \"M-x rgrep RET magit-popup RET RET ~/.emacs.d/ RET\"."))
+(cl-eval-when (eval load)
+ (unless (require (quote magit-popup) nil t)
+ (defun magit-define-popup-switch (&rest _)
+ (magit--magit-popup-warning))
+ (defun magit-define-popup-option (&rest _)
+ (magit--magit-popup-warning))
+ (defun magit-define-popup-variable (&rest _)
+ (magit--magit-popup-warning))
+ (defun magit-define-popup-action (&rest _)
+ (magit--magit-popup-warning))
+ (defun magit-define-popup-sequence-action (&rest _)
+ (magit--magit-popup-warning))
+ (defun magit-define-popup-key (&rest _)
+ (magit--magit-popup-warning))
+ (defun magit-define-popup-keys-deferred (&rest _)
+ (magit--magit-popup-warning))
+ (defun magit-change-popup-key (&rest _)
+ (magit--magit-popup-warning))
+ (defun magit-remove-popup-key (&rest _)
+ (magit--magit-popup-warning))))
+
+;;; _
+(provide 'magit-obsolete)
+;;; magit-obsolete.el ends here
diff --git a/elpa/magit-20220503.1245/magit-obsolete.elc b/elpa/magit-20220503.1245/magit-obsolete.elc
new file mode 100644
index 0000000..cb99c4a
--- /dev/null
+++ b/elpa/magit-20220503.1245/magit-obsolete.elc
Binary files differ
diff --git a/elpa/magit-20220503.1245/magit-patch.el b/elpa/magit-20220503.1245/magit-patch.el
new file mode 100644
index 0000000..c114cf2
--- /dev/null
+++ b/elpa/magit-20220503.1245/magit-patch.el
@@ -0,0 +1,326 @@
+;;; magit-patch.el --- Creating and applying patches -*- lexical-binding:t -*-
+
+;; Copyright (C) 2008-2022 The Magit Project Contributors
+
+;; Author: Jonas Bernoulli <jonas@bernoul.li>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+
+;; SPDX-License-Identifier: GPL-3.0-or-later
+
+;; Magit 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.
+;;
+;; Magit 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 Magit. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This library implements patch commands.
+
+;;; Code:
+
+(require 'magit)
+
+;;; Options
+
+(defcustom magit-patch-save-arguments '(exclude "--stat")
+ "Control arguments used by the command `magit-patch-save'.
+
+`magit-patch-save' (which see) saves a diff for the changes
+shown in the current buffer in a patch file. It may use the
+same arguments as used in the buffer or a subset thereof, or
+a constant list of arguments, depending on this option and
+the prefix argument."
+ :package-version '(magit . "2.12.0")
+ :group 'magit-diff
+ :type '(choice (const :tag "use buffer arguments" buffer)
+ (cons :tag "use buffer arguments except"
+ (const :format "" exclude)
+ (repeat :format "%v%i\n"
+ (string :tag "Argument")))
+ (repeat :tag "use constant arguments"
+ (string :tag "Argument"))))
+
+;;; Commands
+
+;;;###autoload (autoload 'magit-patch "magit-patch" nil t)
+(transient-define-prefix magit-patch ()
+ "Create or apply patches."
+ ["Actions"
+ [("c" "Create patches" magit-patch-create)
+ ("w" "Apply patches" magit-am)]
+ [("a" "Apply plain patch" magit-patch-apply)
+ ("s" "Save diff as patch" magit-patch-save)]
+ [("r" "Request pull" magit-request-pull)]])
+
+;;;###autoload (autoload 'magit-patch-create "magit-patch" nil t)
+(transient-define-prefix magit-patch-create (range args files)
+ "Create patches for the commits in RANGE.
+When a single commit is given for RANGE, create a patch for the
+changes introduced by that commit (unlike 'git format-patch'
+which creates patches for all commits that are reachable from
+`HEAD' but not from the specified commit)."
+ :man-page "git-format-patch"
+ :incompatible '(("--subject-prefix=" "--rfc"))
+ ["Mail arguments"
+ (6 magit-format-patch:--in-reply-to)
+ (6 magit-format-patch:--thread)
+ (6 magit-format-patch:--from)
+ (6 magit-format-patch:--to)
+ (6 magit-format-patch:--cc)]
+ ["Patch arguments"
+ (magit-format-patch:--base)
+ (magit-format-patch:--reroll-count)
+ (5 magit-format-patch:--interdiff)
+ (magit-format-patch:--range-diff)
+ (magit-format-patch:--subject-prefix)
+ ("C-m r " "RFC subject prefix" "--rfc")
+ ("C-m l " "Add cover letter" "--cover-letter")
+ (5 magit-format-patch:--cover-from-description)
+ (5 magit-format-patch:--notes)
+ (magit-format-patch:--output-directory)]
+ ["Diff arguments"
+ (magit-diff:-U)
+ (magit-diff:-M)
+ (magit-diff:-C)
+ (magit-diff:--diff-algorithm)
+ (magit:--)
+ (7 "-b" "Ignore whitespace changes" ("-b" "--ignore-space-change"))
+ (7 "-w" "Ignore all whitespace" ("-w" "--ignore-all-space"))]
+ ["Actions"
+ ("c" "Create patches" magit-patch-create)]
+ (interactive
+ (if (not (eq transient-current-command 'magit-patch-create))
+ (list nil nil nil)
+ (cons (if-let ((revs (magit-region-values 'commit t)))
+ (concat (car (last revs)) "^.." (car revs))
+ (let ((range (magit-read-range-or-commit
+ "Format range or commit")))
+ (if (string-search ".." range)
+ range
+ (format "%s~..%s" range range))))
+ (let ((args (transient-args 'magit-patch-create)))
+ (list (-filter #'stringp args)
+ (cdr (assoc "--" args)))))))
+ (if (not range)
+ (transient-setup 'magit-patch-create)
+ (magit-run-git "format-patch" range args "--" files)
+ (when (member "--cover-letter" args)
+ (save-match-data
+ (find-file
+ (expand-file-name
+ (concat (and-let* ((v (transient-arg-value "--reroll-count=" args)))
+ (format "v%s-" v))
+ "0000-cover-letter.patch")
+ (let ((topdir (magit-toplevel)))
+ (if-let ((dir (transient-arg-value "--output-directory=" args)))
+ (expand-file-name dir topdir)
+ topdir))))))))
+
+(transient-define-argument magit-format-patch:--in-reply-to ()
+ :description "In reply to"
+ :class 'transient-option
+ :key "C-m C-r"
+ :argument "--in-reply-to=")
+
+(transient-define-argument magit-format-patch:--thread ()
+ :description "Thread style"
+ :class 'transient-option
+ :key "C-m s "
+ :argument "--thread="
+ :reader #'magit-format-patch-select-thread-style)
+
+(defun magit-format-patch-select-thread-style (&rest _ignore)
+ (magit-read-char-case "Thread style " t
+ (?d "[d]eep" "deep")
+ (?s "[s]hallow" "shallow")))
+
+(transient-define-argument magit-format-patch:--base ()
+ :description "Insert base commit"
+ :class 'transient-option
+ :key "C-m b "
+ :argument "--base="
+ :reader #'magit-format-patch-select-base)
+
+(defun magit-format-patch-select-base (prompt initial-input history)
+ (or (magit-completing-read prompt (cons "auto" (magit-list-refnames))
+ nil nil initial-input history "auto")
+ (user-error "Nothing selected")))
+
+(transient-define-argument magit-format-patch:--reroll-count ()
+ :description "Reroll count"
+ :class 'transient-option
+ :key "C-m v "
+ :shortarg "-v"
+ :argument "--reroll-count="
+ :reader #'transient-read-number-N+)
+
+(transient-define-argument magit-format-patch:--interdiff ()
+ :description "Insert interdiff"
+ :class 'transient-option
+ :key "C-m d i"
+ :argument "--interdiff="
+ :reader #'magit-transient-read-revision)
+
+(transient-define-argument magit-format-patch:--range-diff ()
+ :description "Insert range-diff"
+ :class 'transient-option
+ :key "C-m d r"
+ :argument "--range-diff="
+ :reader #'magit-format-patch-select-range-diff)
+
+(defun magit-format-patch-select-range-diff (prompt _initial-input _history)
+ (magit-read-range-or-commit prompt))
+
+(transient-define-argument magit-format-patch:--subject-prefix ()
+ :description "Subject Prefix"
+ :class 'transient-option
+ :key "C-m p "
+ :argument "--subject-prefix=")
+
+(transient-define-argument magit-format-patch:--cover-from-description ()
+ :description "Use branch description"
+ :class 'transient-option
+ :key "C-m D "
+ :argument "--cover-from-description="
+ :reader #'magit-format-patch-select-description-mode)
+
+(defun magit-format-patch-select-description-mode (&rest _ignore)
+ (magit-read-char-case "Use description as " t
+ (?m "[m]essage" "message")
+ (?s "[s]ubject" "subject")
+ (?a "[a]uto" "auto")
+ (?n "[n]othing" "none")))
+
+(transient-define-argument magit-format-patch:--notes ()
+ :description "Insert commentary from notes"
+ :class 'transient-option
+ :key "C-m n "
+ :argument "--notes="
+ :reader #'magit-notes-read-ref)
+
+(transient-define-argument magit-format-patch:--from ()
+ :description "From"
+ :class 'transient-option
+ :key "C-m C-f"
+ :argument "--from="
+ :reader #'magit-transient-read-person)
+
+(transient-define-argument magit-format-patch:--to ()
+ :description "To"
+ :class 'transient-option
+ :key "C-m C-t"
+ :argument "--to="
+ :reader #'magit-transient-read-person)
+
+(transient-define-argument magit-format-patch:--cc ()
+ :description "CC"
+ :class 'transient-option
+ :key "C-m C-c"
+ :argument "--cc="
+ :reader #'magit-transient-read-person)
+
+(transient-define-argument magit-format-patch:--output-directory ()
+ :description "Output directory"
+ :class 'transient-option
+ :key "C-m o "
+ :shortarg "-o"
+ :argument "--output-directory="
+ :reader #'transient-read-existing-directory)
+
+;;;###autoload (autoload 'magit-patch-apply "magit-patch" nil t)
+(transient-define-prefix magit-patch-apply (file &rest args)
+ "Apply the patch file FILE."
+ :man-page "git-apply"
+ ["Arguments"
+ ("-i" "Also apply to index" "--index")
+ ("-c" "Only apply to index" "--cached")
+ ("-3" "Fall back on 3way merge" ("-3" "--3way"))]
+ ["Actions"
+ ("a" "Apply patch" magit-patch-apply)]
+ (interactive
+ (if (not (eq transient-current-command 'magit-patch-apply))
+ (list nil)
+ (list (expand-file-name
+ (read-file-name "Apply patch: "
+ default-directory nil nil
+ (and-let* ((file (magit-file-at-point)))
+ (file-relative-name file))))
+ (transient-args 'magit-patch-apply))))
+ (if (not file)
+ (transient-setup 'magit-patch-apply)
+ (magit-run-git "apply" args "--" (magit-convert-filename-for-git file))))
+
+;;;###autoload
+(defun magit-patch-save (file &optional arg)
+ "Write current diff into patch FILE.
+
+What arguments are used to create the patch depends on the value
+of `magit-patch-save-arguments' and whether a prefix argument is
+used.
+
+If the value is the symbol `buffer', then use the same arguments
+as the buffer. With a prefix argument use no arguments.
+
+If the value is a list beginning with the symbol `exclude', then
+use the same arguments as the buffer except for those matched by
+entries in the cdr of the list. The comparison is done using
+`string-prefix-p'. With a prefix argument use the same arguments
+as the buffer.
+
+If the value is a list of strings (including the empty list),
+then use those arguments. With a prefix argument use the same
+arguments as the buffer.
+
+Of course the arguments that are required to actually show the
+same differences as those shown in the buffer are always used."
+ (interactive (list (read-file-name "Write patch file: " default-directory)
+ current-prefix-arg))
+ (unless (derived-mode-p 'magit-diff-mode)
+ (user-error "Only diff buffers can be saved as patches"))
+ (let ((rev magit-buffer-range)
+ (typearg magit-buffer-typearg)
+ (args magit-buffer-diff-args)
+ (files magit-buffer-diff-files))
+ (cond ((eq magit-patch-save-arguments 'buffer)
+ (when arg
+ (setq args nil)))
+ ((eq (car-safe magit-patch-save-arguments) 'exclude)
+ (unless arg
+ (setq args (-difference args (cdr magit-patch-save-arguments)))))
+ ((not arg)
+ (setq args magit-patch-save-arguments)))
+ (with-temp-file file
+ (magit-git-insert "diff" rev "-p" typearg args "--" files)))
+ (magit-refresh))
+
+;;;###autoload
+(defun magit-request-pull (url start end)
+ "Request upstream to pull from your public repository.
+
+URL is the url of your publicly accessible repository.
+START is a commit that already is in the upstream repository.
+END is the last commit, usually a branch name, which upstream
+is asked to pull. START has to be reachable from that commit."
+ (interactive
+ (list (magit-get "remote" (magit-read-remote "Remote") "url")
+ (magit-read-branch-or-commit "Start" (magit-get-upstream-branch))
+ (magit-read-branch-or-commit "End")))
+ (let ((dir default-directory))
+ ;; mu4e changes default-directory
+ (compose-mail)
+ (setq default-directory dir))
+ (message-goto-body)
+ (magit-git-insert "request-pull" start url end)
+ (set-buffer-modified-p nil))
+
+;;; _
+(provide 'magit-patch)
+;;; magit-patch.el ends here
diff --git a/elpa/magit-20220503.1245/magit-patch.elc b/elpa/magit-20220503.1245/magit-patch.elc
new file mode 100644
index 0000000..ac80ae8
--- /dev/null
+++ b/elpa/magit-20220503.1245/magit-patch.elc
Binary files differ
diff --git a/elpa/magit-20220503.1245/magit-pkg.el b/elpa/magit-20220503.1245/magit-pkg.el
new file mode 100644
index 0000000..88d7a98
--- /dev/null
+++ b/elpa/magit-20220503.1245/magit-pkg.el
@@ -0,0 +1,19 @@
+(define-package "magit" "20220503.1245" "A Git porcelain inside Emacs."
+ '((emacs "25.1")
+ (compat "28.1.1.0")
+ (dash "20210826")
+ (git-commit "20220222")
+ (magit-section "20220325")
+ (transient "20220325")
+ (with-editor "20220318"))
+ :commit "476383fc8fb0f6ea4c6fc29d7057a1b5b5f95bd8" :authors
+ '(("Marius Vollmer" . "marius.vollmer@gmail.com")
+ ("Jonas Bernoulli" . "jonas@bernoul.li"))
+ :maintainer
+ '("Jonas Bernoulli" . "jonas@bernoul.li")
+ :keywords
+ '("git" "tools" "vc")
+ :url "https://github.com/magit/magit")
+;; Local Variables:
+;; no-byte-compile: t
+;; End:
diff --git a/elpa/magit-20220503.1245/magit-process.el b/elpa/magit-20220503.1245/magit-process.el
new file mode 100644
index 0000000..38eacd4
--- /dev/null
+++ b/elpa/magit-20220503.1245/magit-process.el
@@ -0,0 +1,1220 @@
+;;; magit-process.el --- Process functionality -*- lexical-binding:t -*-
+
+;; Copyright (C) 2008-2022 The Magit Project Contributors
+
+;; Author: Jonas Bernoulli <jonas@bernoul.li>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+
+;; SPDX-License-Identifier: GPL-3.0-or-later
+
+;; Magit 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.
+;;
+;; Magit 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 Magit. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This library implements the tools used to run Git for side-effects.
+
+;; Note that the functions used to run Git and then consume its
+;; output, are defined in `magit-git.el'. There's a bit of overlap
+;; though.
+
+;;; Code:
+
+(require 'magit-base)
+(require 'magit-git)
+(require 'magit-mode)
+
+(require 'ansi-color)
+(require 'with-editor)
+
+;;; Options
+
+(defcustom magit-process-connection-type (not (eq system-type 'cygwin))
+ "Connection type used for the Git process.
+
+If nil, use pipes: this is usually more efficient, and works on Cygwin.
+If t, use ptys: this enables Magit to prompt for passphrases when needed."
+ :group 'magit-process
+ :type '(choice (const :tag "pipe" nil)
+ (const :tag "pty" t)))
+
+(defcustom magit-need-cygwin-noglob
+ (and (eq system-type 'windows-nt)
+ (with-temp-buffer
+ (let ((process-environment
+ (append magit-git-environment process-environment)))
+ (condition-case e
+ (process-file magit-git-executable
+ nil (current-buffer) nil
+ "-c" "alias.echo=!echo" "echo" "x{0}")
+ (file-error
+ (lwarn 'magit-process :warning
+ "Could not run Git: %S" e))))
+ (equal "x0\n" (buffer-string))))
+ "Whether to use a workaround for Cygwin's globbing behavior.
+
+If non-nil, add environment variables to `process-environment' to
+prevent the git.exe distributed by Cygwin and MSYS2 from
+attempting to perform glob expansion when called from a native
+Windows build of Emacs. See #2246."
+ :package-version '(magit . "2.3.0")
+ :group 'magit-process
+ :type '(choice (const :tag "Yes" t)
+ (const :tag "No" nil)))
+
+(defcustom magit-process-popup-time -1
+ "Popup the process buffer if a command takes longer than this many seconds."
+ :group 'magit-process
+ :type '(choice (const :tag "Never" -1)
+ (const :tag "Immediately" 0)
+ (integer :tag "After this many seconds")))
+
+(defcustom magit-process-log-max 32
+ "Maximum number of sections to keep in a process log buffer.
+When adding a new section would go beyond the limit set here,
+then the older half of the sections are remove. Sections that
+belong to processes that are still running are never removed.
+When this is nil, no sections are ever removed."
+ :package-version '(magit . "2.1.0")
+ :group 'magit-process
+ :type '(choice (const :tag "Never remove old sections" nil) integer))
+
+(defvar magit-process-extreme-logging nil
+ "Whether `magit-process-file' logs to the *Messages* buffer.
+
+Only intended for temporary use when you try to figure out how
+Magit uses Git behind the scene. Output that normally goes to
+the magit-process buffer continues to go there. Not all output
+goes to either of these two buffers.
+
+Also see `magit-git-debug'.")
+
+(defcustom magit-process-error-tooltip-max-lines 20
+ "The number of lines for `magit-process-error-lines' to return.
+
+These are displayed in a tooltip for `mode-line-process' errors.
+
+If `magit-process-error-tooltip-max-lines' is nil, the tooltip
+displays the text of `magit-process-error-summary' instead."
+ :package-version '(magit . "2.12.0")
+ :group 'magit-process
+ :type '(choice (const :tag "Use summary line" nil)
+ integer))
+
+(defcustom magit-credential-cache-daemon-socket
+ (--some (pcase-let ((`(,prog . ,args) (split-string it)))
+ (if (and prog
+ (string-match-p
+ "\\`\\(?:\\(?:/.*/\\)?git-credential-\\)?cache\\'" prog))
+ (or (cl-loop for (opt val) on args
+ if (string= opt "--socket")
+ return val)
+ (expand-file-name "~/.git-credential-cache/socket"))))
+ ;; Note: `magit-process-file' is not yet defined when
+ ;; evaluating this form, so we use `process-lines'.
+ (ignore-errors
+ (let ((process-environment
+ (append magit-git-environment process-environment)))
+ (process-lines magit-git-executable
+ "config" "--get-all" "credential.helper"))))
+ "If non-nil, start a credential cache daemon using this socket.
+
+When using Git's cache credential helper in the normal way, Emacs
+sends a SIGHUP to the credential daemon after the git subprocess
+has exited, causing the daemon to also quit. This can be avoided
+by starting the `git-credential-cache--daemon' process directly
+from Emacs.
+
+The function `magit-maybe-start-credential-cache-daemon' takes
+care of starting the daemon if necessary, using the value of this
+option as the socket. If this option is nil, then it does not
+start any daemon. Likewise if another daemon is already running,
+then it starts no new daemon. This function has to be a member
+of the hook variable `magit-credential-hook' for this to work.
+If an error occurs while starting the daemon, most likely because
+the necessary executable is missing, then the function removes
+itself from the hook, to avoid further futile attempts."
+ :package-version '(magit . "2.3.0")
+ :group 'magit-process
+ :type '(choice (file :tag "Socket")
+ (const :tag "Don't start a cache daemon" nil)))
+
+(defcustom magit-process-yes-or-no-prompt-regexp
+ (concat " [\[(]"
+ "\\([Yy]\\(?:es\\)?\\)"
+ "[/|]"
+ "\\([Nn]o?\\)"
+ ;; OpenSSH v8 prints this. See #3969.
+ "\\(?:/\\[fingerprint\\]\\)?"
+ "[\])] ?[?:]? ?$")
+ "Regexp matching Yes-or-No prompts of Git and its subprocesses."
+ :package-version '(magit . "2.1.0")
+ :group 'magit-process
+ :type 'regexp)
+
+(defcustom magit-process-password-prompt-regexps
+ '("^\\(Enter \\)?[Pp]assphrase\\( for \\(RSA \\)?key '.*'\\)?: ?$"
+ ;; Match-group 99 is used to identify the "user@host" part.
+ "^\\(Enter \\)?[Pp]assword\\( for '?\\(https?://\\)?\\(?99:[^']*\\)'?\\)?: ?$"
+ "Please enter the passphrase for the ssh key"
+ "Please enter the passphrase to unlock the OpenPGP secret key"
+ "^.*'s password: ?$"
+ "^Token: $" ; For git-credential-manager-core (#4318).
+ "^Yubikey for .*: ?$"
+ "^Enter PIN for .*: ?$")
+ "List of regexps matching password prompts of Git and its subprocesses.
+Also see `magit-process-find-password-functions'."
+ :package-version '(magit . "3.0.0")
+ :group 'magit-process
+ :type '(repeat (regexp)))
+
+(defcustom magit-process-find-password-functions nil
+ "List of functions to try in sequence to get a password.
+
+These functions may be called when git asks for a password, which
+is detected using `magit-process-password-prompt-regexps'. They
+are called if and only if matching the prompt resulted in the
+value of the 99th submatch to be non-nil. Therefore users can
+control for which prompts these functions should be called by
+putting the host name in the 99th submatch, or not.
+
+If the functions are called, then they are called in the order
+given, with the host name as only argument, until one of them
+returns non-nil. If they are not called or none of them returns
+non-nil, then the password is read from the user instead."
+ :package-version '(magit . "2.3.0")
+ :group 'magit-process
+ :type 'hook
+ :options '(magit-process-password-auth-source))
+
+(defcustom magit-process-username-prompt-regexps
+ '("^Username for '.*': ?$")
+ "List of regexps matching username prompts of Git and its subprocesses."
+ :package-version '(magit . "2.1.0")
+ :group 'magit-process
+ :type '(repeat (regexp)))
+
+(defcustom magit-process-prompt-functions nil
+ "List of functions used to forward arbitrary questions to the user.
+
+Magit has dedicated support for forwarding username and password
+prompts and Yes-or-No questions asked by Git and its subprocesses
+to the user. This can be customized using other options in the
+`magit-process' customization group.
+
+If you encounter a new question that isn't handled by default,
+then those options should be used instead of this hook.
+
+However subprocesses may also ask questions that differ too much
+from what the code related to the above options assume, and this
+hook allows users to deal with such questions explicitly.
+
+Each function is called with the process and the output string
+as arguments until one of the functions returns non-nil. The
+function is responsible for asking the user the appropriate
+question using e.g. `read-char-choice' and then forwarding the
+answer to the process using `process-send-string'.
+
+While functions such as `magit-process-yes-or-no-prompt' may not
+be sufficient to handle some prompt, it may still be of benefit
+to look at the implementations to gain some insights on how to
+implement such functions."
+ :package-version '(magit . "3.0.0")
+ :group 'magit-process
+ :type 'hook)
+
+(defcustom magit-process-ensure-unix-line-ending t
+ "Whether Magit should ensure a unix coding system when talking to Git."
+ :package-version '(magit . "2.6.0")
+ :group 'magit-process
+ :type 'boolean)
+
+(defcustom magit-process-display-mode-line-error t
+ "Whether Magit should retain and highlight process errors in the mode line."
+ :package-version '(magit . "2.12.0")
+ :group 'magit-process
+ :type 'boolean)
+
+(defface magit-process-ok
+ '((t :inherit magit-section-heading :foreground "green"))
+ "Face for zero exit-status."
+ :group 'magit-faces)
+
+(defface magit-process-ng
+ '((t :inherit magit-section-heading :foreground "red"))
+ "Face for non-zero exit-status."
+ :group 'magit-faces)
+
+(defface magit-mode-line-process
+ '((t :inherit mode-line-emphasis))
+ "Face for `mode-line-process' status when Git is running for side-effects."
+ :group 'magit-faces)
+
+(defface magit-mode-line-process-error
+ '((t :inherit error))
+ "Face for `mode-line-process' error status.
+
+Used when `magit-process-display-mode-line-error' is non-nil."
+ :group 'magit-faces)
+
+;;; Process Mode
+
+(defvar magit-process-mode-map
+ (let ((map (make-sparse-keymap)))
+ (set-keymap-parent map magit-mode-map)
+ map)
+ "Keymap for `magit-process-mode'.")
+
+(define-derived-mode magit-process-mode magit-mode "Magit Process"
+ "Mode for looking at Git process output."
+ :group 'magit-process
+ (hack-dir-local-variables-non-file-buffer)
+ (setq magit--imenu-item-types 'process))
+
+(defun magit-process-buffer (&optional nodisplay)
+ "Display the current repository's process buffer.
+
+If that buffer doesn't exist yet, then create it.
+Non-interactively return the buffer and unless
+optional NODISPLAY is non-nil also display it."
+ (interactive)
+ (let ((topdir (magit-toplevel)))
+ (unless topdir
+ (magit--with-safe-default-directory nil
+ (setq topdir default-directory)
+ (let (prev)
+ (while (not (equal topdir prev))
+ (setq prev topdir)
+ (setq topdir (file-name-directory (directory-file-name topdir)))))))
+ (let ((buffer (or (--first (with-current-buffer it
+ (and (eq major-mode 'magit-process-mode)
+ (equal default-directory topdir)))
+ (buffer-list))
+ (let ((default-directory topdir))
+ (magit-generate-new-buffer 'magit-process-mode)))))
+ (with-current-buffer buffer
+ (if magit-root-section
+ (when magit-process-log-max
+ (magit-process-truncate-log))
+ (magit-process-mode)
+ (let ((inhibit-read-only t)
+ (magit-insert-section--parent nil)
+ (magit-insert-section--oldroot nil))
+ (make-local-variable 'text-property-default-nonsticky)
+ (magit-insert-section (processbuf)
+ (insert "\n")))))
+ (unless nodisplay
+ (magit-display-buffer buffer))
+ buffer)))
+
+(defun magit-process-kill ()
+ "Kill the process at point."
+ (interactive)
+ (when-let ((process (magit-section-value-if 'process)))
+ (unless (eq (process-status process) 'run)
+ (user-error "Process isn't running"))
+ (magit-confirm 'kill-process)
+ (kill-process process)))
+
+;;; Synchronous Processes
+
+(defvar magit-process-raise-error nil)
+
+(defun magit-git (&rest args)
+ "Call Git synchronously in a separate process, for side-effects.
+
+Option `magit-git-executable' specifies the Git executable.
+The arguments ARGS specify arguments to Git, they are flattened
+before use.
+
+Process output goes into a new section in the buffer returned by
+`magit-process-buffer'. If Git exits with a non-zero status,
+then raise an error."
+ (let ((magit-process-raise-error t))
+ (magit-call-git args)))
+
+(defun magit-run-git (&rest args)
+ "Call Git synchronously in a separate process, and refresh.
+
+Function `magit-git-executable' specifies the Git executable and
+option `magit-git-global-arguments' specifies constant arguments.
+The arguments ARGS specify arguments to Git, they are flattened
+before use.
+
+After Git returns, the current buffer (if it is a Magit buffer)
+as well as the current repository's status buffer are refreshed.
+
+Process output goes into a new section in the buffer returned by
+`magit-process-buffer'."
+ (let ((magit--refresh-cache (list (cons 0 0))))
+ (magit-call-git args)
+ (when (member (car args) '("init" "clone"))
+ ;; Creating a new repository invalidates the cache.
+ (setq magit--refresh-cache nil))
+ (magit-refresh)))
+
+(defvar magit-pre-call-git-hook nil)
+
+(defun magit-call-git (&rest args)
+ "Call Git synchronously in a separate process.
+
+Function `magit-git-executable' specifies the Git executable and
+option `magit-git-global-arguments' specifies constant arguments.
+The arguments ARGS specify arguments to Git, they are flattened
+before use.
+
+Process output goes into a new section in the buffer returned by
+`magit-process-buffer'."
+ (run-hooks 'magit-pre-call-git-hook)
+ (let ((default-process-coding-system (magit--process-coding-system)))
+ (apply #'magit-call-process
+ (magit-git-executable)
+ (magit-process-git-arguments args))))
+
+(defun magit-call-process (program &rest args)
+ "Call PROGRAM synchronously in a separate process.
+Process output goes into a new section in the buffer returned by
+`magit-process-buffer'."
+ (pcase-let ((`(,process-buf . ,section)
+ (magit-process-setup program args)))
+ (magit-process-finish
+ (let ((inhibit-read-only t))
+ (apply #'magit-process-file program nil process-buf nil args))
+ process-buf (current-buffer) default-directory section)))
+
+(defun magit-process-git (destination &rest args)
+ "Call Git synchronously in a separate process, returning its exit code.
+DESTINATION specifies how to handle the output, like for
+`call-process', except that file handlers are supported.
+Enable Cygwin's \"noglob\" option during the call and
+ensure unix eol conversion."
+ (apply #'magit-process-file
+ (magit-git-executable)
+ nil destination nil
+ (magit-process-git-arguments args)))
+
+(defun magit-process-file (process &optional infile buffer display &rest args)
+ "Process files synchronously in a separate process.
+Identical to `process-file' but temporarily enable Cygwin's
+\"noglob\" option during the call and ensure unix eol
+conversion."
+ (when magit-process-extreme-logging
+ (let ((inhibit-message t))
+ (message "$ %s" (magit-process--format-arguments process args))))
+ (let ((process-environment (magit-process-environment))
+ (default-process-coding-system (magit--process-coding-system)))
+ (apply #'process-file process infile buffer display args)))
+
+(defun magit-process-environment ()
+ ;; The various w32 hacks are only applicable when running on the
+ ;; local machine. As of Emacs 25.1, a local binding of
+ ;; process-environment different from the top-level value affects
+ ;; the environment used in
+ ;; tramp-sh-handle-{start-file-process,process-file}.
+ (let ((local (not (file-remote-p default-directory))))
+ (append magit-git-environment
+ (and local
+ (cdr (assoc magit-git-executable magit-git-w32-path-hack)))
+ (and local magit-need-cygwin-noglob
+ (mapcar (lambda (var)
+ (concat var "=" (--if-let (getenv var)
+ (concat it " noglob")
+ "noglob")))
+ '("CYGWIN" "MSYS")))
+ process-environment)))
+
+(defvar magit-this-process nil)
+
+(defun magit-run-git-with-input (&rest args)
+ "Call Git in a separate process.
+ARGS is flattened and then used as arguments to Git.
+
+The current buffer's content is used as the process's standard
+input. The buffer is assumed to be temporary and thus OK to
+modify.
+
+Function `magit-git-executable' specifies the Git executable and
+option `magit-git-global-arguments' specifies constant arguments.
+The remaining arguments ARGS specify arguments to Git, they are
+flattened before use."
+ (when (eq system-type 'windows-nt)
+ ;; On w32, git expects UTF-8 encoded input, ignore any user
+ ;; configuration telling us otherwise (see #3250).
+ (encode-coding-region (point-min) (point-max) 'utf-8-unix))
+ (if (file-remote-p default-directory)
+ ;; We lack `process-file-region', so fall back to asynch +
+ ;; waiting in remote case.
+ (progn
+ (magit-start-git (current-buffer) args)
+ (while (and magit-this-process
+ (eq (process-status magit-this-process) 'run))
+ (sleep-for 0.005)))
+ (run-hooks 'magit-pre-call-git-hook)
+ (pcase-let* ((process-environment (magit-process-environment))
+ (default-process-coding-system (magit--process-coding-system))
+ (flat-args (magit-process-git-arguments args))
+ (`(,process-buf . ,section)
+ (magit-process-setup (magit-git-executable) flat-args))
+ (inhibit-read-only t))
+ (magit-process-finish
+ (apply #'call-process-region (point-min) (point-max)
+ (magit-git-executable) nil process-buf nil flat-args)
+ process-buf nil default-directory section))))
+
+;;; Asynchronous Processes
+
+(defun magit-run-git-async (&rest args)
+ "Start Git, prepare for refresh, and return the process object.
+ARGS is flattened and then used as arguments to Git.
+
+Display the command line arguments in the echo area.
+
+After Git returns some buffers are refreshed: the buffer that was
+current when this function was called (if it is a Magit buffer
+and still alive), as well as the respective Magit status buffer.
+
+See `magit-start-process' for more information."
+ (message "Running %s %s" (magit-git-executable)
+ (let ((m (mapconcat #'identity (flatten-tree args) " ")))
+ (remove-list-of-text-properties 0 (length m) '(face) m)
+ m))
+ (magit-start-git nil args))
+
+(defun magit-run-git-with-editor (&rest args)
+ "Export GIT_EDITOR and start Git.
+Also prepare for refresh and return the process object.
+ARGS is flattened and then used as arguments to Git.
+
+Display the command line arguments in the echo area.
+
+After Git returns some buffers are refreshed: the buffer that was
+current when this function was called (if it is a Magit buffer
+and still alive), as well as the respective Magit status buffer.
+
+See `magit-start-process' and `with-editor' for more information."
+ (magit--record-separated-gitdir)
+ (magit-with-editor (magit-run-git-async args)))
+
+(defun magit-run-git-sequencer (&rest args)
+ "Export GIT_EDITOR and start Git.
+Also prepare for refresh and return the process object.
+ARGS is flattened and then used as arguments to Git.
+
+Display the command line arguments in the echo area.
+
+After Git returns some buffers are refreshed: the buffer that was
+current when this function was called (if it is a Magit buffer
+and still alive), as well as the respective Magit status buffer.
+If the sequence stops at a commit, make the section representing
+that commit the current section by moving `point' there.
+
+See `magit-start-process' and `with-editor' for more information."
+ (apply #'magit-run-git-with-editor args)
+ (set-process-sentinel magit-this-process #'magit-sequencer-process-sentinel)
+ magit-this-process)
+
+(defvar magit-pre-start-git-hook nil)
+
+(defun magit-start-git (input &rest args)
+ "Start Git, prepare for refresh, and return the process object.
+
+If INPUT is non-nil, it has to be a buffer or the name of an
+existing buffer. The buffer content becomes the processes
+standard input.
+
+Function `magit-git-executable' specifies the Git executable and
+option `magit-git-global-arguments' specifies constant arguments.
+The remaining arguments ARGS specify arguments to Git, they are
+flattened before use.
+
+After Git returns some buffers are refreshed: the buffer that was
+current when this function was called (if it is a Magit buffer
+and still alive), as well as the respective Magit status buffer.
+
+See `magit-start-process' for more information."
+ (run-hooks 'magit-pre-start-git-hook)
+ (let ((default-process-coding-system (magit--process-coding-system)))
+ (apply #'magit-start-process (magit-git-executable) input
+ (magit-process-git-arguments args))))
+
+(defun magit-start-process (program &optional input &rest args)
+ "Start PROGRAM, prepare for refresh, and return the process object.
+
+If optional argument INPUT is non-nil, it has to be a buffer or
+the name of an existing buffer. The buffer content becomes the
+processes standard input.
+
+The process is started using `start-file-process' and then setup
+to use the sentinel `magit-process-sentinel' and the filter
+`magit-process-filter'. Information required by these functions
+is stored in the process object. When this function returns the
+process has not started to run yet so it is possible to override
+the sentinel and filter.
+
+After the process returns, `magit-process-sentinel' refreshes the
+buffer that was current when `magit-start-process' was called (if
+it is a Magit buffer and still alive), as well as the respective
+Magit status buffer."
+ (pcase-let*
+ ((`(,process-buf . ,section)
+ (magit-process-setup program args))
+ (process
+ (let ((process-connection-type
+ ;; Don't use a pty, because it would set icrnl
+ ;; which would modify the input (issue #20).
+ (and (not input) magit-process-connection-type))
+ (process-environment (magit-process-environment))
+ (default-process-coding-system (magit--process-coding-system)))
+ (apply #'start-file-process
+ (file-name-nondirectory program)
+ process-buf program args))))
+ (with-editor-set-process-filter process #'magit-process-filter)
+ (set-process-sentinel process #'magit-process-sentinel)
+ (set-process-buffer process process-buf)
+ (when (eq system-type 'windows-nt)
+ ;; On w32, git expects UTF-8 encoded input, ignore any user
+ ;; configuration telling us otherwise.
+ (set-process-coding-system process nil 'utf-8-unix))
+ (process-put process 'section section)
+ (process-put process 'command-buf (current-buffer))
+ (process-put process 'default-dir default-directory)
+ (when magit-inhibit-refresh
+ (process-put process 'inhibit-refresh t))
+ (oset section process process)
+ (with-current-buffer process-buf
+ (set-marker (process-mark process) (point)))
+ (when input
+ (with-current-buffer input
+ (process-send-region process (point-min) (point-max))
+ (process-send-eof process)))
+ (setq magit-this-process process)
+ (oset section value process)
+ (magit-process-display-buffer process)
+ process))
+
+(defun magit-parse-git-async (&rest args)
+ (setq args (magit-process-git-arguments args))
+ (let ((command-buf (current-buffer))
+ (process-buf (generate-new-buffer " *temp*"))
+ (toplevel (magit-toplevel)))
+ (with-current-buffer process-buf
+ (setq default-directory toplevel)
+ (let ((process
+ (let ((process-connection-type nil)
+ (process-environment (magit-process-environment))
+ (default-process-coding-system
+ (magit--process-coding-system)))
+ (apply #'start-file-process "git" process-buf
+ (magit-git-executable) args))))
+ (process-put process 'command-buf command-buf)
+ (process-put process 'parsed (point))
+ (setq magit-this-process process)
+ process))))
+
+;;; Process Internals
+
+(defun magit-process-setup (program args)
+ (magit-process-set-mode-line program args)
+ (let ((pwd default-directory)
+ (buf (magit-process-buffer t)))
+ (cons buf (with-current-buffer buf
+ (prog1 (magit-process-insert-section pwd program args nil nil)
+ (backward-char 1))))))
+
+(defun magit-process-insert-section (pwd program args &optional errcode errlog)
+ (let ((inhibit-read-only t)
+ (magit-insert-section--parent magit-root-section)
+ (magit-insert-section--oldroot nil))
+ (goto-char (1- (point-max)))
+ (magit-insert-section (process)
+ (insert (if errcode
+ (format "%3s " (propertize (number-to-string errcode)
+ 'font-lock-face 'magit-process-ng))
+ "run "))
+ (unless (equal (expand-file-name pwd)
+ (expand-file-name default-directory))
+ (insert (file-relative-name pwd default-directory) ?\s))
+ (insert (magit-process--format-arguments program args))
+ (magit-insert-heading)
+ (when errlog
+ (if (bufferp errlog)
+ (insert (with-current-buffer errlog
+ (buffer-substring-no-properties (point-min) (point-max))))
+ (insert-file-contents errlog)
+ (goto-char (1- (point-max)))))
+ (insert "\n"))))
+
+(defun magit-process--format-arguments (program args)
+ (cond
+ ((and args (equal program (magit-git-executable)))
+ (setq args (-split-at (length magit-git-global-arguments) args))
+ (concat (propertize (file-name-nondirectory program)
+ 'font-lock-face 'magit-section-heading)
+ " "
+ (propertize (if (stringp magit-ellipsis)
+ magit-ellipsis
+ ;; For backward compatibility.
+ (char-to-string magit-ellipsis))
+ 'font-lock-face 'magit-section-heading
+ 'help-echo (mapconcat #'identity (car args) " "))
+ " "
+ (propertize (mapconcat #'shell-quote-argument (cadr args) " ")
+ 'font-lock-face 'magit-section-heading)))
+ ((and args (equal program shell-file-name))
+ (propertize (cadr args)
+ 'font-lock-face 'magit-section-heading))
+ (t
+ (concat (propertize (file-name-nondirectory program)
+ 'font-lock-face 'magit-section-heading)
+ " "
+ (propertize (mapconcat #'shell-quote-argument args " ")
+ 'font-lock-face 'magit-section-heading)))))
+
+(defun magit-process-truncate-log ()
+ (let* ((head nil)
+ (tail (oref magit-root-section children))
+ (count (length tail)))
+ (when (> (1+ count) magit-process-log-max)
+ (while (and (cdr tail)
+ (> count (/ magit-process-log-max 2)))
+ (let* ((inhibit-read-only t)
+ (section (car tail))
+ (process (oref section process)))
+ (cond ((not process))
+ ((memq (process-status process) '(exit signal))
+ (delete-region (oref section start)
+ (1+ (oref section end)))
+ (cl-decf count))
+ (t
+ (push section head))))
+ (pop tail))
+ (oset magit-root-section children
+ (nconc (reverse head) tail)))))
+
+(defun magit-process-sentinel (process event)
+ "Default sentinel used by `magit-start-process'."
+ (when (memq (process-status process) '(exit signal))
+ (setq event (substring event 0 -1))
+ (when (string-match "^finished" event)
+ (message (concat (capitalize (process-name process)) " finished")))
+ (magit-process-finish process)
+ (when (eq process magit-this-process)
+ (setq magit-this-process nil))
+ (unless (process-get process 'inhibit-refresh)
+ (let ((command-buf (process-get process 'command-buf)))
+ (if (buffer-live-p command-buf)
+ (with-current-buffer command-buf
+ (magit-refresh))
+ (with-temp-buffer
+ (setq default-directory (process-get process 'default-dir))
+ (magit-refresh)))))))
+
+(defun magit-sequencer-process-sentinel (process event)
+ "Special sentinel used by `magit-run-git-sequencer'."
+ (when (memq (process-status process) '(exit signal))
+ (magit-process-sentinel process event)
+ (when-let* ((process-buf (process-buffer process))
+ (- (buffer-live-p process-buf))
+ (status-buf (with-current-buffer process-buf
+ (magit-get-mode-buffer 'magit-status-mode))))
+ (with-current-buffer status-buf
+ (--when-let
+ (magit-get-section
+ `((commit . ,(magit-rev-parse "HEAD"))
+ (,(pcase (car (cadr (-split-at
+ (1+ (length magit-git-global-arguments))
+ (process-command process))))
+ ((or "rebase" "am") 'rebase-sequence)
+ ((or "cherry-pick" "revert") 'sequence)))
+ (status)))
+ (goto-char (oref it start))
+ (magit-section-update-highlight))))))
+
+(defun magit-process-filter (proc string)
+ "Default filter used by `magit-start-process'."
+ (with-current-buffer (process-buffer proc)
+ (let ((inhibit-read-only t))
+ (goto-char (process-mark proc))
+ ;; Find last ^M in string. If one was found, ignore
+ ;; everything before it and delete the current line.
+ (when-let ((ret-pos (cl-position ?\r string :from-end t)))
+ (cl-callf substring string (1+ ret-pos))
+ (delete-region (line-beginning-position) (point)))
+ (insert (propertize string 'magit-section
+ (process-get proc 'section)))
+ (set-marker (process-mark proc) (point))
+ ;; Make sure prompts are matched after removing ^M.
+ (magit-process-yes-or-no-prompt proc string)
+ (magit-process-username-prompt proc string)
+ (magit-process-password-prompt proc string)
+ (run-hook-with-args-until-success 'magit-process-prompt-functions
+ proc string))))
+
+(defmacro magit-process-kill-on-abort (proc &rest body)
+ (declare (indent 1) (debug (form body)))
+ (let ((map (cl-gensym)))
+ `(let ((,map (make-sparse-keymap)))
+ (set-keymap-parent ,map minibuffer-local-map)
+ ;; Note: Leaving (kbd ...) unevaluated leads to the
+ ;; magit-process:password-prompt test failing.
+ (define-key ,map ,(kbd "C-g")
+ (lambda ()
+ (interactive)
+ (ignore-errors (kill-process ,proc))
+ (abort-recursive-edit)))
+ (let ((minibuffer-local-map ,map))
+ ,@body))))
+
+(defun magit-process-yes-or-no-prompt (process string)
+ "Forward Yes-or-No prompts to the user."
+ (when-let ((beg (string-match magit-process-yes-or-no-prompt-regexp string)))
+ (let ((max-mini-window-height 30))
+ (process-send-string
+ process
+ (downcase
+ (concat
+ (match-string
+ (if (save-match-data
+ (magit-process-kill-on-abort process
+ (yes-or-no-p (substring string 0 beg)))) 1 2)
+ string)
+ "\n"))))))
+
+(defun magit-process-password-auth-source (key)
+ "Use `auth-source-search' to get a password.
+If found, return the password. Otherwise, return nil.
+
+To use this function add it to the appropriate hook
+ (add-hook 'magit-process-find-password-functions
+ 'magit-process-password-auth-source)
+
+KEY typically derives from a prompt such as:
+ Password for 'https://yourname@github.com'
+in which case it would be the string
+ yourname@github.com
+which matches the ~/.authinfo.gpg entry
+ machine github.com login yourname password 12345
+or iff that is undefined, for backward compatibility
+ machine yourname@github.com password 12345
+
+On github.com you should not use your password but a
+personal access token, see [1]. For information about
+the peculiarities of other forges, please consult the
+respective documentation.
+
+After manually editing ~/.authinfo.gpg you must reset
+the cache using
+ M-x auth-source-forget-all-cached RET
+
+The above will save you from having to repeatedly type
+your token or password, but you might still repeatedly
+be asked for your username. To prevent that, change an
+URL like
+ https://github.com/foo/bar.git
+to
+ https://yourname@github.com/foo/bar.git
+
+Instead of changing all such URLs manually, they can
+be translated on the fly by doing this once
+ git config --global \
+ url.https://yourname@github.com.insteadOf \
+ https://github.com
+
+[1]: https://docs.github.com/en/github/authenticating-to-github/creating-a-personal-access-token."
+ (require 'auth-source)
+ (and (fboundp 'auth-source-search)
+ (string-match "\\`\\(.+\\)@\\([^@]+\\)\\'" key)
+ (let* ((user (match-string 1 key))
+ (host (match-string 2 key))
+ (secret
+ (plist-get
+ (car (or (auth-source-search :max 1 :host host :user user)
+ (auth-source-search :max 1 :host key)))
+ :secret)))
+ (if (functionp secret)
+ (funcall secret)
+ secret))))
+
+(defun magit-process-git-credential-manager-core (process string)
+ "Authenticate using `git-credential-manager-core'.
+
+To use this function add it to the appropriate hook
+ (add-hook \\='magit-process-prompt-functions
+ \\='magit-process-git-credential-manager-core)"
+ (and (string-match "^option (enter for default): $" string)
+ (progn
+ (magit-process-buffer)
+ (let ((option (format "%c\n"
+ (read-char-choice "Option: " '(?\r ?\j ?1 ?2)))))
+ (insert-before-markers-and-inherit option)
+ (process-send-string process option)))))
+
+(defun magit-process-password-prompt (process string)
+ "Find a password based on prompt STRING and send it to git.
+Use `magit-process-password-prompt-regexps' to find a known
+prompt. If and only if one is found, then call functions in
+`magit-process-find-password-functions' until one of them returns
+the password. If all functions return nil, then read the password
+from the user."
+ (when-let ((prompt (magit-process-match-prompt
+ magit-process-password-prompt-regexps string)))
+ (process-send-string
+ process (magit-process-kill-on-abort process
+ (concat (or (and-let* ((key (match-string 99 string)))
+ (run-hook-with-args-until-success
+ 'magit-process-find-password-functions key))
+ (read-passwd prompt))
+ "\n")))))
+
+(defun magit-process-username-prompt (process string)
+ "Forward username prompts to the user."
+ (--when-let (magit-process-match-prompt
+ magit-process-username-prompt-regexps string)
+ (process-send-string
+ process (magit-process-kill-on-abort process
+ (concat (read-string it nil nil (user-login-name)) "\n")))))
+
+(defun magit-process-match-prompt (prompts string)
+ "Match STRING against PROMPTS and set match data.
+Return the matched string suffixed with \": \", if needed."
+ (when (--any-p (string-match it string) prompts)
+ (let ((prompt (match-string 0 string)))
+ (cond ((string-suffix-p ": " prompt) prompt)
+ ((string-suffix-p ":" prompt) (concat prompt " "))
+ (t (concat prompt ": "))))))
+
+(defun magit--process-coding-system ()
+ (let ((fro (or magit-git-output-coding-system
+ (car default-process-coding-system)))
+ (to (cdr default-process-coding-system)))
+ (if magit-process-ensure-unix-line-ending
+ (cons (coding-system-change-eol-conversion fro 'unix)
+ (coding-system-change-eol-conversion to 'unix))
+ (cons fro to))))
+
+(defvar magit-credential-hook nil
+ "Hook run before Git needs credentials.")
+
+(defvar magit-credential-cache-daemon-process nil)
+
+(defun magit-maybe-start-credential-cache-daemon ()
+ "Maybe start a `git-credential-cache--daemon' process.
+
+If such a process is already running or if the value of option
+`magit-credential-cache-daemon-socket' is nil, then do nothing.
+Otherwise start the process passing the value of that options
+as argument."
+ (unless (or (not magit-credential-cache-daemon-socket)
+ (process-live-p magit-credential-cache-daemon-process)
+ (memq magit-credential-cache-daemon-process
+ (list-system-processes)))
+ (setq magit-credential-cache-daemon-process
+ (or (--first (let* ((attr (process-attributes it))
+ (comm (cdr (assq 'comm attr)))
+ (user (cdr (assq 'user attr))))
+ (and (string= comm "git-credential-cache--daemon")
+ (string= user user-login-name)))
+ (list-system-processes))
+ (condition-case nil
+ (start-process "git-credential-cache--daemon"
+ " *git-credential-cache--daemon*"
+ (magit-git-executable)
+ "credential-cache--daemon"
+ magit-credential-cache-daemon-socket)
+ ;; Some Git implementations (e.g. Windows) won't have
+ ;; this program; if we fail the first time, stop trying.
+ ((debug error)
+ (remove-hook 'magit-credential-hook
+ #'magit-maybe-start-credential-cache-daemon)))))))
+
+(add-hook 'magit-credential-hook #'magit-maybe-start-credential-cache-daemon)
+
+(defun tramp-sh-handle-start-file-process--magit-tramp-process-environment
+ (fn name buffer program &rest args)
+ (if magit-tramp-process-environment
+ (apply fn name buffer
+ (car magit-tramp-process-environment)
+ (append (cdr magit-tramp-process-environment)
+ (cons program args)))
+ (apply fn name buffer program args)))
+
+(advice-add 'tramp-sh-handle-start-file-process :around
+ #'tramp-sh-handle-start-file-process--magit-tramp-process-environment)
+
+(defun tramp-sh-handle-process-file--magit-tramp-process-environment
+ (fn program &optional infile destination display &rest args)
+ (if magit-tramp-process-environment
+ (apply fn "env" infile destination display
+ (append magit-tramp-process-environment
+ (cons program args)))
+ (apply fn program infile destination display args)))
+
+(advice-add 'tramp-sh-handle-process-file :around
+ #'tramp-sh-handle-process-file--magit-tramp-process-environment)
+
+(defvar magit-mode-line-process-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map (kbd "<mode-line> <mouse-1>")
+ 'magit-process-buffer)
+ map)
+ "Keymap for `mode-line-process'.")
+
+(defun magit-process-set-mode-line (program args)
+ "Display the git command (sans arguments) in the mode line."
+ (when (equal program (magit-git-executable))
+ (setq args (nthcdr (length magit-git-global-arguments) args)))
+ (let ((str (concat " " (propertize
+ (concat (file-name-nondirectory program)
+ (and args (concat " " (car args))))
+ 'mouse-face 'highlight
+ 'keymap magit-mode-line-process-map
+ 'help-echo "mouse-1: Show process buffer"
+ 'font-lock-face 'magit-mode-line-process))))
+ (magit-repository-local-set 'mode-line-process str)
+ (dolist (buf (magit-mode-get-buffers))
+ (with-current-buffer buf
+ (setq mode-line-process str)))
+ (force-mode-line-update t)))
+
+(defun magit-process-set-mode-line-error-status (&optional error str)
+ "Apply an error face to the string set by `magit-process-set-mode-line'.
+
+If ERROR is supplied, include it in the `mode-line-process' tooltip.
+
+If STR is supplied, it replaces the `mode-line-process' text."
+ (setq str (or str (magit-repository-local-get 'mode-line-process)))
+ (when str
+ (setq error (format "%smouse-1: Show process buffer"
+ (if (stringp error)
+ (concat error "\n\n")
+ "")))
+ (setq str (concat " " (propertize
+ (substring-no-properties str 1)
+ 'mouse-face 'highlight
+ 'keymap magit-mode-line-process-map
+ 'help-echo error
+ 'font-lock-face 'magit-mode-line-process-error)))
+ (magit-repository-local-set 'mode-line-process str)
+ (dolist (buf (magit-mode-get-buffers))
+ (with-current-buffer buf
+ (setq mode-line-process str)))
+ (force-mode-line-update t)
+ ;; We remove any error status from the mode line when a magit
+ ;; buffer is refreshed (see `magit-refresh-buffer'), but we must
+ ;; ensure that we ignore any refreshes during the remainder of the
+ ;; current command -- otherwise a newly-set error status would be
+ ;; removed before it was seen. We set a flag which prevents the
+ ;; status from being removed prior to the next command, so that
+ ;; the error status is guaranteed to remain visible until then.
+ (let ((repokey (magit-repository-local-repository)))
+ ;; The following closure captures the repokey value, and is
+ ;; added to `pre-command-hook'.
+ (cl-labels ((enable-magit-process-unset-mode-line ()
+ ;; Remove ourself from the hook variable, so
+ ;; that we only run once.
+ (remove-hook 'pre-command-hook
+ #'enable-magit-process-unset-mode-line)
+ ;; Clear the inhibit flag for the repository in
+ ;; which we set it.
+ (magit-repository-local-set
+ 'inhibit-magit-process-unset-mode-line nil repokey)))
+ ;; Set the inhibit flag until the next command is invoked.
+ (magit-repository-local-set
+ 'inhibit-magit-process-unset-mode-line t repokey)
+ (add-hook 'pre-command-hook
+ #'enable-magit-process-unset-mode-line)))))
+
+(defun magit-process-unset-mode-line-error-status ()
+ "Remove any current error status from the mode line."
+ (let ((status (or mode-line-process
+ (magit-repository-local-get 'mode-line-process))))
+ (when (and status
+ (eq (get-text-property 1 'font-lock-face status)
+ 'magit-mode-line-process-error))
+ (magit-process-unset-mode-line))))
+
+(defun magit-process-unset-mode-line (&optional directory)
+ "Remove the git command from the mode line."
+ (let ((default-directory (or directory default-directory)))
+ (unless (magit-repository-local-get 'inhibit-magit-process-unset-mode-line)
+ (magit-repository-local-set 'mode-line-process nil)
+ (dolist (buf (magit-mode-get-buffers))
+ (with-current-buffer buf (setq mode-line-process nil)))
+ (force-mode-line-update t))))
+
+(defvar magit-process-error-message-regexps
+ (list "^\\*ERROR\\*: Canceled by user$"
+ "^\\(?:error\\|fatal\\|git\\): \\(.*\\)$"
+ "^\\(Cannot rebase:.*\\)$"))
+
+(define-error 'magit-git-error "Git error")
+
+(defun magit-process-error-summary (process-buf section)
+ "A one-line error summary from the given SECTION."
+ (or (and (buffer-live-p process-buf)
+ (with-current-buffer process-buf
+ (and (oref section content)
+ (save-excursion
+ (goto-char (oref section end))
+ (run-hook-wrapped
+ 'magit-process-error-message-regexps
+ (lambda (re)
+ (save-excursion
+ (and (re-search-backward
+ re (oref section start) t)
+ (or (match-string-no-properties 1)
+ (and (not magit-process-raise-error)
+ 'suppressed))))))))))
+ "Git failed"))
+
+(defun magit-process-error-tooltip (process-buf section)
+ "Returns the text from SECTION of the PROCESS-BUF buffer.
+
+Limited by `magit-process-error-tooltip-max-lines'."
+ (and (integerp magit-process-error-tooltip-max-lines)
+ (> magit-process-error-tooltip-max-lines 0)
+ (buffer-live-p process-buf)
+ (with-current-buffer process-buf
+ (save-excursion
+ (goto-char (or (oref section content)
+ (oref section start)))
+ (buffer-substring-no-properties
+ (point)
+ (save-excursion
+ (forward-line magit-process-error-tooltip-max-lines)
+ (goto-char
+ (if (> (point) (oref section end))
+ (oref section end)
+ (point)))
+ ;; Remove any trailing whitespace.
+ (when (re-search-backward "[^[:space:]\n]"
+ (oref section start) t)
+ (forward-char 1))
+ (point)))))))
+
+(defvar-local magit-this-error nil)
+
+(defvar magit-process-finish-apply-ansi-colors nil)
+
+(defun magit-process-finish (arg &optional process-buf command-buf
+ default-dir section)
+ (unless (integerp arg)
+ (setq process-buf (process-buffer arg))
+ (setq command-buf (process-get arg 'command-buf))
+ (setq default-dir (process-get arg 'default-dir))
+ (setq section (process-get arg 'section))
+ (setq arg (process-exit-status arg)))
+ (when (fboundp 'dired-uncache)
+ (dired-uncache default-dir))
+ (when (buffer-live-p process-buf)
+ (with-current-buffer process-buf
+ (let ((inhibit-read-only t)
+ (marker (oref section start)))
+ (goto-char marker)
+ (save-excursion
+ (delete-char 3)
+ (set-marker-insertion-type marker nil)
+ (insert (propertize (format "%3s" arg)
+ 'magit-section section
+ 'font-lock-face (if (= arg 0)
+ 'magit-process-ok
+ 'magit-process-ng)))
+ (set-marker-insertion-type marker t))
+ (when magit-process-finish-apply-ansi-colors
+ (ansi-color-apply-on-region (oref section content)
+ (oref section end)))
+ (if (= (oref section end)
+ (+ (line-end-position) 2))
+ (save-excursion
+ (goto-char (1+ (line-end-position)))
+ (delete-char -1)
+ (oset section content nil))
+ (let ((buf (magit-process-buffer t)))
+ (when (and (= arg 0)
+ (not (--any-p (eq (window-buffer it) buf)
+ (window-list))))
+ (magit-section-hide section)))))))
+ (if (= arg 0)
+ ;; Unset the `mode-line-process' value upon success.
+ (magit-process-unset-mode-line default-dir)
+ ;; Otherwise process the error.
+ (let ((msg (magit-process-error-summary process-buf section)))
+ ;; Change `mode-line-process' to an error face upon failure.
+ (if magit-process-display-mode-line-error
+ (magit-process-set-mode-line-error-status
+ (or (magit-process-error-tooltip process-buf section)
+ msg))
+ (magit-process-unset-mode-line default-dir))
+ ;; Either signal the error, or else display the error summary in
+ ;; the status buffer and with a message in the echo area.
+ (cond
+ (magit-process-raise-error
+ (signal 'magit-git-error (list (format "%s (in %s)" msg default-dir))))
+ ((not (eq msg 'suppressed))
+ (when (buffer-live-p process-buf)
+ (with-current-buffer process-buf
+ (when-let ((status-buf (magit-get-mode-buffer 'magit-status-mode)))
+ (with-current-buffer status-buf
+ (setq magit-this-error msg)))))
+ (message "%s ... [%s buffer %s for details]" msg
+ (if-let ((key (and (buffer-live-p command-buf)
+ (with-current-buffer command-buf
+ (car (where-is-internal
+ 'magit-process-buffer))))))
+ (format "Hit %s to see" (key-description key))
+ "See")
+ (buffer-name process-buf))))))
+ arg)
+
+(defun magit-process-display-buffer (process)
+ (when (process-live-p process)
+ (let ((buf (process-buffer process)))
+ (cond ((not (buffer-live-p buf)))
+ ((= magit-process-popup-time 0)
+ (if (minibufferp)
+ (switch-to-buffer-other-window buf)
+ (pop-to-buffer buf)))
+ ((> magit-process-popup-time 0)
+ (run-with-timer magit-process-popup-time nil
+ (lambda (p)
+ (when (eq (process-status p) 'run)
+ (let ((buf (process-buffer p)))
+ (when (buffer-live-p buf)
+ (if (minibufferp)
+ (switch-to-buffer-other-window buf)
+ (pop-to-buffer buf))))))
+ process))))))
+
+(defun magit--log-action (summary line list)
+ (let (heading lines)
+ (if (cdr list)
+ (progn (setq heading (funcall summary list))
+ (setq lines (mapcar line list)))
+ (setq heading (funcall line (car list))))
+ (with-current-buffer (magit-process-buffer t)
+ (goto-char (1- (point-max)))
+ (let ((inhibit-read-only t))
+ (magit-insert-section (message)
+ (magit-insert-heading (concat " * " heading))
+ (when lines
+ (dolist (line lines)
+ (insert line "\n"))
+ (insert "\n"))))
+ (let ((inhibit-message t))
+ (when heading
+ (setq lines (cons heading lines)))
+ (message (mapconcat #'identity lines "\n"))))))
+
+;;; _
+(provide 'magit-process)
+;;; magit-process.el ends here
diff --git a/elpa/magit-20220503.1245/magit-process.elc b/elpa/magit-20220503.1245/magit-process.elc
new file mode 100644
index 0000000..e25cb7e
--- /dev/null
+++ b/elpa/magit-20220503.1245/magit-process.elc
Binary files differ
diff --git a/elpa/magit-20220503.1245/magit-pull.el b/elpa/magit-20220503.1245/magit-pull.el
new file mode 100644
index 0000000..aad99a5
--- /dev/null
+++ b/elpa/magit-20220503.1245/magit-pull.el
@@ -0,0 +1,165 @@
+;;; magit-pull.el --- Update local objects and refs -*- lexical-binding:t -*-
+
+;; Copyright (C) 2008-2022 The Magit Project Contributors
+
+;; Author: Jonas Bernoulli <jonas@bernoul.li>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+
+;; SPDX-License-Identifier: GPL-3.0-or-later
+
+;; Magit 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.
+;;
+;; Magit 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 Magit. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This library implements pull commands.
+
+;;; Code:
+
+(require 'magit)
+
+;;; Options
+
+(defcustom magit-pull-or-fetch nil
+ "Whether `magit-pull' also offers some fetch suffixes."
+ :package-version '(magit . "3.0.0")
+ :group 'magit-commands
+ :type 'boolean)
+
+;;; Commands
+
+;;;###autoload (autoload 'magit-pull "magit-pull" nil t)
+(transient-define-prefix magit-pull ()
+ "Pull from another repository."
+ :man-page "git-pull"
+ :incompatible '(("--ff-only" "--rebase"))
+ [:description
+ (lambda () (if magit-pull-or-fetch "Pull arguments" "Arguments"))
+ ("-f" "Fast-forward only" "--ff-only")
+ ("-r" "Rebase local commits" ("-r" "--rebase"))
+ ("-A" "Autostash" "--autostash" :level 7)]
+ [:description
+ (lambda ()
+ (if-let ((branch (magit-get-current-branch)))
+ (concat
+ (propertize "Pull into " 'face 'transient-heading)
+ (propertize branch 'face 'magit-branch-local)
+ (propertize " from" 'face 'transient-heading))
+ (propertize "Pull from" 'face 'transient-heading)))
+ ("p" magit-pull-from-pushremote)
+ ("u" magit-pull-from-upstream)
+ ("e" "elsewhere" magit-pull-branch)]
+ ["Fetch from"
+ :if-non-nil magit-pull-or-fetch
+ ("f" "remotes" magit-fetch-all-no-prune)
+ ("F" "remotes and prune" magit-fetch-all-prune)]
+ ["Fetch"
+ :if-non-nil magit-pull-or-fetch
+ ("o" "another branch" magit-fetch-branch)
+ ("s" "explicit refspec" magit-fetch-refspec)
+ ("m" "submodules" magit-fetch-modules)]
+ ["Configure"
+ ("r" magit-branch.<branch>.rebase :if magit-get-current-branch)
+ ("C" "variables..." magit-branch-configure)]
+ (interactive)
+ (transient-setup 'magit-pull nil nil :scope (magit-get-current-branch)))
+
+(defun magit-pull-arguments ()
+ (transient-args 'magit-pull))
+
+;;;###autoload (autoload 'magit-pull-from-pushremote "magit-pull" nil t)
+(transient-define-suffix magit-pull-from-pushremote (args)
+ "Pull from the push-remote of the current branch.
+
+With a prefix argument or when the push-remote is either not
+configured or unusable, then let the user first configure the
+push-remote."
+ :if #'magit-get-current-branch
+ :description #'magit-pull--pushbranch-description
+ (interactive (list (magit-pull-arguments)))
+ (pcase-let ((`(,branch ,remote)
+ (magit--select-push-remote "pull from there")))
+ (run-hooks 'magit-credential-hook)
+ (magit-run-git-with-editor "pull" args remote branch)))
+
+(defun magit-pull--pushbranch-description ()
+ ;; Also used by `magit-rebase-onto-pushremote'.
+ (let* ((branch (magit-get-current-branch))
+ (target (magit-get-push-branch branch t))
+ (remote (magit-get-push-remote branch))
+ (v (magit--push-remote-variable branch t)))
+ (cond
+ (target)
+ ((member remote (magit-list-remotes))
+ (format "%s, replacing non-existent" v))
+ (remote
+ (format "%s, replacing invalid" v))
+ (t
+ (format "%s, setting that" v)))))
+
+;;;###autoload (autoload 'magit-pull-from-upstream "magit-pull" nil t)
+(transient-define-suffix magit-pull-from-upstream (args)
+ "Pull from the upstream of the current branch.
+
+With a prefix argument or when the upstream is either not
+configured or unusable, then let the user first configure
+the upstream."
+ :if #'magit-get-current-branch
+ :description #'magit-pull--upstream-description
+ (interactive (list (magit-pull-arguments)))
+ (let* ((branch (or (magit-get-current-branch)
+ (user-error "No branch is checked out")))
+ (remote (magit-get "branch" branch "remote"))
+ (merge (magit-get "branch" branch "merge")))
+ (when (or current-prefix-arg
+ (not (or (magit-get-upstream-branch branch)
+ (magit--unnamed-upstream-p remote merge))))
+ (magit-set-upstream-branch
+ branch (magit-read-upstream-branch
+ branch (format "Set upstream of %s and pull from there" branch)))
+ (setq remote (magit-get "branch" branch "remote"))
+ (setq merge (magit-get "branch" branch "merge")))
+ (run-hooks 'magit-credential-hook)
+ (magit-run-git-with-editor "pull" args remote merge)))
+
+(defun magit-pull--upstream-description ()
+ (and-let* ((branch (magit-get-current-branch)))
+ (or (magit-get-upstream-branch branch)
+ (let ((remote (magit-get "branch" branch "remote"))
+ (merge (magit-get "branch" branch "merge"))
+ (u (magit--propertize-face "@{upstream}" 'bold)))
+ (cond
+ ((magit--unnamed-upstream-p remote merge)
+ (format "%s of %s"
+ (magit--propertize-face merge 'magit-branch-remote)
+ (magit--propertize-face remote 'bold)))
+ ((magit--valid-upstream-p remote merge)
+ (concat u ", replacing non-existent"))
+ ((or remote merge)
+ (concat u ", replacing invalid"))
+ (t
+ (concat u ", setting that")))))))
+
+;;;###autoload
+(defun magit-pull-branch (source args)
+ "Pull from a branch read in the minibuffer."
+ (interactive (list (magit-read-remote-branch "Pull" nil nil nil t)
+ (magit-pull-arguments)))
+ (run-hooks 'magit-credential-hook)
+ (pcase-let ((`(,remote . ,branch)
+ (magit-get-tracked source)))
+ (magit-run-git-with-editor "pull" args remote branch)))
+
+;;; _
+(provide 'magit-pull)
+;;; magit-pull.el ends here
diff --git a/elpa/magit-20220503.1245/magit-pull.elc b/elpa/magit-20220503.1245/magit-pull.elc
new file mode 100644
index 0000000..e5b8f49
--- /dev/null
+++ b/elpa/magit-20220503.1245/magit-pull.elc
Binary files differ
diff --git a/elpa/magit-20220503.1245/magit-push.el b/elpa/magit-20220503.1245/magit-push.el
new file mode 100644
index 0000000..c28aca5
--- /dev/null
+++ b/elpa/magit-20220503.1245/magit-push.el
@@ -0,0 +1,341 @@
+;;; magit-push.el --- Update remote objects and refs -*- lexical-binding:t -*-
+
+;; Copyright (C) 2008-2022 The Magit Project Contributors
+
+;; Author: Jonas Bernoulli <jonas@bernoul.li>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+
+;; SPDX-License-Identifier: GPL-3.0-or-later
+
+;; Magit 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.
+;;
+;; Magit 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 Magit. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This library implements push commands.
+
+;;; Code:
+
+(require 'magit)
+
+;;; Commands
+
+;;;###autoload (autoload 'magit-push "magit-push" nil t)
+(transient-define-prefix magit-push ()
+ "Push to another repository."
+ :man-page "git-push"
+ ["Arguments"
+ ("-f" "Force with lease" (nil "--force-with-lease"))
+ ("-F" "Force" ("-f" "--force"))
+ ("-h" "Disable hooks" "--no-verify")
+ ("-n" "Dry run" ("-n" "--dry-run"))
+ (5 "-u" "Set upstream" "--set-upstream")
+ (7 "-t" "Follow tags" "--follow-tags")]
+ [:if magit-get-current-branch
+ :description (lambda ()
+ (format (propertize "Push %s to" 'face 'transient-heading)
+ (propertize (magit-get-current-branch)
+ 'face 'magit-branch-local)))
+ ("p" magit-push-current-to-pushremote)
+ ("u" magit-push-current-to-upstream)
+ ("e" "elsewhere" magit-push-current)]
+ ["Push"
+ [("o" "another branch" magit-push-other)
+ ("r" "explicit refspecs" magit-push-refspecs)
+ ("m" "matching branches" magit-push-matching)]
+ [("T" "a tag" magit-push-tag)
+ ("t" "all tags" magit-push-tags)
+ (6 "n" "a note ref" magit-push-notes-ref)]]
+ ["Configure"
+ ("C" "Set variables..." magit-branch-configure)])
+
+(defun magit-push-arguments ()
+ (transient-args 'magit-push))
+
+(defun magit-git-push (branch target args)
+ (run-hooks 'magit-credential-hook)
+ ;; If the remote branch already exists, then we do not have to
+ ;; qualify the target, which we prefer to avoid doing because
+ ;; using the default namespace is wrong in obscure cases.
+ (pcase-let ((namespace (if (magit-get-tracked target) "" "refs/heads/"))
+ (`(,remote . ,target)
+ (magit-split-branch-name target)))
+ (magit-run-git-async "push" "-v" args remote
+ (format "%s:%s%s" branch namespace target))))
+
+;;;###autoload (autoload 'magit-push-current-to-pushremote "magit-push" nil t)
+(transient-define-suffix magit-push-current-to-pushremote (args)
+ "Push the current branch to its push-remote.
+
+When the push-remote is not configured, then read the push-remote
+from the user, set it, and then push to it. With a prefix
+argument the push-remote can be changed before pushed to it."
+ :if #'magit-get-current-branch
+ :description #'magit-push--pushbranch-description
+ (interactive (list (magit-push-arguments)))
+ (pcase-let ((`(,branch ,remote ,changed)
+ (magit--select-push-remote "push there")))
+ (when changed
+ (magit-confirm 'set-and-push
+ (string-replace
+ "%" "%%"
+ (format "Really use \"%s\" as push-remote and push \"%s\" there"
+ remote branch))))
+ (run-hooks 'magit-credential-hook)
+ (magit-run-git-async "push" "-v" args remote
+ (format "refs/heads/%s:refs/heads/%s"
+ branch branch)))) ; see #3847 and #3872
+
+(defun magit-push--pushbranch-description ()
+ (let* ((branch (magit-get-current-branch))
+ (target (magit-get-push-branch branch t))
+ (remote (magit-get-push-remote branch))
+ (v (magit--push-remote-variable branch t)))
+ (cond
+ (target)
+ ((member remote (magit-list-remotes))
+ (format "%s, creating it"
+ (magit--propertize-face (concat remote "/" branch)
+ 'magit-branch-remote)))
+ (remote
+ (format "%s, replacing invalid" v))
+ (t
+ (format "%s, setting that" v)))))
+
+;;;###autoload (autoload 'magit-push-current-to-upstream "magit-push" nil t)
+(transient-define-suffix magit-push-current-to-upstream (args)
+ "Push the current branch to its upstream branch.
+
+With a prefix argument or when the upstream is either not
+configured or unusable, then let the user first configure
+the upstream."
+ :if #'magit-get-current-branch
+ :description #'magit-push--upstream-description
+ (interactive (list (magit-push-arguments)))
+ (let* ((branch (or (magit-get-current-branch)
+ (user-error "No branch is checked out")))
+ (remote (magit-get "branch" branch "remote"))
+ (merge (magit-get "branch" branch "merge")))
+ (when (or current-prefix-arg
+ (not (or (magit-get-upstream-branch branch)
+ (magit--unnamed-upstream-p remote merge)
+ (magit--valid-upstream-p remote merge))))
+ (let* ((branches (-union (--map (concat it "/" branch)
+ (magit-list-remotes))
+ (magit-list-remote-branch-names)))
+ (upstream (magit-completing-read
+ (format "Set upstream of %s and push there" branch)
+ branches nil nil nil 'magit-revision-history
+ (or (car (member (magit-remote-branch-at-point) branches))
+ (car (member "origin/master" branches)))))
+ (upstream* (or (magit-get-tracked upstream)
+ (magit-split-branch-name upstream))))
+ (setq remote (car upstream*))
+ (setq merge (cdr upstream*))
+ (unless (string-prefix-p "refs/" merge)
+ ;; User selected a non-existent remote-tracking branch.
+ ;; It is very likely, but not certain, that this is the
+ ;; correct thing to do. It is even more likely that it
+ ;; is what the user wants to happen.
+ (setq merge (concat "refs/heads/" merge)))
+ (magit-confirm 'set-and-push
+ (string-replace
+ "%" "%%"
+ (format "Really use \"%s\" as upstream and push \"%s\" there"
+ upstream branch))))
+ (cl-pushnew "--set-upstream" args :test #'equal))
+ (run-hooks 'magit-credential-hook)
+ (magit-run-git-async "push" "-v" args remote (concat branch ":" merge))))
+
+(defun magit-push--upstream-description ()
+ (and-let* ((branch (magit-get-current-branch)))
+ (or (magit-get-upstream-branch branch)
+ (let ((remote (magit-get "branch" branch "remote"))
+ (merge (magit-get "branch" branch "merge"))
+ (u (magit--propertize-face "@{upstream}" 'bold)))
+ (cond
+ ((magit--unnamed-upstream-p remote merge)
+ (format "%s as %s"
+ (magit--propertize-face remote 'bold)
+ (magit--propertize-face merge 'magit-branch-remote)))
+ ((magit--valid-upstream-p remote merge)
+ (format "%s creating %s"
+ (magit--propertize-face remote 'magit-branch-remote)
+ (magit--propertize-face merge 'magit-branch-remote)))
+ ((or remote merge)
+ (concat u ", creating it and replacing invalid"))
+ (t
+ (concat u ", creating it")))))))
+
+;;;###autoload
+(defun magit-push-current (target args)
+ "Push the current branch to a branch read in the minibuffer."
+ (interactive
+ (--if-let (magit-get-current-branch)
+ (list (magit-read-remote-branch (format "Push %s to" it)
+ nil nil it 'confirm)
+ (magit-push-arguments))
+ (user-error "No branch is checked out")))
+ (magit-git-push (magit-get-current-branch) target args))
+
+;;;###autoload
+(defun magit-push-other (source target args)
+ "Push an arbitrary branch or commit somewhere.
+Both the source and the target are read in the minibuffer."
+ (interactive
+ (let ((source (magit-read-local-branch-or-commit "Push")))
+ (list source
+ (magit-read-remote-branch
+ (format "Push %s to" source) nil
+ (if (magit-local-branch-p source)
+ (or (magit-get-push-branch source)
+ (magit-get-upstream-branch source))
+ (and (magit-rev-ancestor-p source "HEAD")
+ (or (magit-get-push-branch)
+ (magit-get-upstream-branch))))
+ source 'confirm)
+ (magit-push-arguments))))
+ (magit-git-push source target args))
+
+(defvar magit-push-refspecs-history nil)
+
+;;;###autoload
+(defun magit-push-refspecs (remote refspecs args)
+ "Push one or multiple REFSPECS to a REMOTE.
+Both the REMOTE and the REFSPECS are read in the minibuffer. To
+use multiple REFSPECS, separate them with commas. Completion is
+only available for the part before the colon, or when no colon
+is used."
+ (interactive
+ (list (magit-read-remote "Push to remote")
+ (magit-completing-read-multiple*
+ "Push refspec,s: "
+ (cons "HEAD" (magit-list-local-branch-names))
+ nil nil nil 'magit-push-refspecs-history)
+ (magit-push-arguments)))
+ (run-hooks 'magit-credential-hook)
+ (magit-run-git-async "push" "-v" args remote refspecs))
+
+;;;###autoload
+(defun magit-push-matching (remote &optional args)
+ "Push all matching branches to another repository.
+If multiple remotes exist, then read one from the user.
+If just one exists, use that without requiring confirmation."
+ (interactive (list (magit-read-remote "Push matching branches to" nil t)
+ (magit-push-arguments)))
+ (run-hooks 'magit-credential-hook)
+ (magit-run-git-async "push" "-v" args remote ":"))
+
+;;;###autoload
+(defun magit-push-tags (remote &optional args)
+ "Push all tags to another repository.
+If only one remote exists, then push to that. Otherwise prompt
+for a remote, offering the remote configured for the current
+branch as default."
+ (interactive (list (magit-read-remote "Push tags to remote" nil t)
+ (magit-push-arguments)))
+ (run-hooks 'magit-credential-hook)
+ (magit-run-git-async "push" remote "--tags" args))
+
+;;;###autoload
+(defun magit-push-tag (tag remote &optional args)
+ "Push a tag to another repository."
+ (interactive
+ (let ((tag (magit-read-tag "Push tag")))
+ (list tag (magit-read-remote (format "Push %s to remote" tag) nil t)
+ (magit-push-arguments))))
+ (run-hooks 'magit-credential-hook)
+ (magit-run-git-async "push" remote tag args))
+
+;;;###autoload
+(defun magit-push-notes-ref (ref remote &optional args)
+ "Push a notes ref to another repository."
+ (interactive
+ (let ((note (magit-notes-read-ref "Push notes" nil nil)))
+ (list note
+ (magit-read-remote (format "Push %s to remote" note) nil t)
+ (magit-push-arguments))))
+ (run-hooks 'magit-credential-hook)
+ (magit-run-git-async "push" remote ref args))
+
+;;;###autoload (autoload 'magit-push-implicitly "magit-push" nil t)
+(transient-define-suffix magit-push-implicitly (args)
+ "Push somewhere without using an explicit refspec.
+
+This command simply runs \"git push -v [ARGS]\". ARGS are the
+arguments specified in the popup buffer. No explicit refspec
+arguments are used. Instead the behavior depends on at least
+these Git variables: `push.default', `remote.pushDefault',
+`branch.<branch>.pushRemote', `branch.<branch>.remote',
+`branch.<branch>.merge', and `remote.<remote>.push'.
+
+If you add this suffix to a transient prefix without explicitly
+specifying the description, then an attempt is made to predict
+what this command will do. For example:
+
+ (transient-insert-suffix \\='magit-push \"p\"
+ \\='(\"i\" magit-push-implicitly))"
+ :description #'magit-push-implicitly--desc
+ (interactive (list (magit-push-arguments)))
+ (run-hooks 'magit-credential-hook)
+ (magit-run-git-async "push" "-v" args))
+
+(defun magit-push-implicitly--desc ()
+ (let ((default (magit-get "push.default")))
+ (unless (equal default "nothing")
+ (or (and-let* ((remote (or (magit-get-remote)
+ (magit-primary-remote)))
+ (refspec (magit-get "remote" remote "push")))
+ (format "%s using %s"
+ (magit--propertize-face remote 'magit-branch-remote)
+ (magit--propertize-face refspec 'bold)))
+ (and-let* ((upstream (and (not (magit-get-push-branch))
+ (magit-get-upstream-branch))))
+ (format "%s aka %s\n"
+ (magit-branch-set-face upstream)
+ (magit--propertize-face "@{upstream}" 'bold)))
+ (and-let* ((push-branch (magit-get-push-branch)))
+ (format "%s aka %s\n"
+ (magit-branch-set-face push-branch)
+ (magit--propertize-face "pushRemote" 'bold)))
+ (and-let* ((push-branch (magit-get-@{push}-branch)))
+ (format "%s aka %s\n"
+ (magit-branch-set-face push-branch)
+ (magit--propertize-face "@{push}" 'bold)))
+ (format "using %s (%s is %s)\n"
+ (magit--propertize-face "git push" 'bold)
+ (magit--propertize-face "push.default" 'bold)
+ (magit--propertize-face default 'bold))))))
+
+;;;###autoload
+(defun magit-push-to-remote (remote args)
+ "Push to REMOTE without using an explicit refspec.
+The REMOTE is read in the minibuffer.
+
+This command simply runs \"git push -v [ARGS] REMOTE\". ARGS
+are the arguments specified in the popup buffer. No refspec
+arguments are used. Instead the behavior depends on at least
+these Git variables: `push.default', `remote.pushDefault',
+`branch.<branch>.pushRemote', `branch.<branch>.remote',
+`branch.<branch>.merge', and `remote.<remote>.push'."
+ (interactive (list (magit-read-remote "Push to remote")
+ (magit-push-arguments)))
+ (run-hooks 'magit-credential-hook)
+ (magit-run-git-async "push" "-v" args remote))
+
+(defun magit-push-to-remote--desc ()
+ (format "using %s\n" (magit--propertize-face "git push <remote>" 'bold)))
+
+;;; _
+(provide 'magit-push)
+;;; magit-push.el ends here
diff --git a/elpa/magit-20220503.1245/magit-push.elc b/elpa/magit-20220503.1245/magit-push.elc
new file mode 100644
index 0000000..44b2d7f
--- /dev/null
+++ b/elpa/magit-20220503.1245/magit-push.elc
Binary files differ
diff --git a/elpa/magit-20220503.1245/magit-reflog.el b/elpa/magit-20220503.1245/magit-reflog.el
new file mode 100644
index 0000000..639a701
--- /dev/null
+++ b/elpa/magit-20220503.1245/magit-reflog.el
@@ -0,0 +1,210 @@
+;;; magit-reflog.el --- Inspect ref history -*- lexical-binding:t -*-
+
+;; Copyright (C) 2008-2022 The Magit Project Contributors
+
+;; Author: Jonas Bernoulli <jonas@bernoul.li>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+
+;; SPDX-License-Identifier: GPL-3.0-or-later
+
+;; Magit 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.
+;;
+;; Magit 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 Magit. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This library implements support for looking at Git reflogs.
+
+;;; Code:
+
+(require 'magit-core)
+(require 'magit-log)
+
+;;; Options
+
+(defcustom magit-reflog-limit 256
+ "Maximal number of entries initially shown in reflog buffers.
+The limit in the current buffer can be changed using \"+\"
+and \"-\"."
+ :package-version '(magit . "3.0.0")
+ :group 'magit-commands
+ :type 'number)
+
+(defcustom magit-reflog-margin
+ (list (nth 0 magit-log-margin)
+ (nth 1 magit-log-margin)
+ 'magit-log-margin-width nil
+ (nth 4 magit-log-margin))
+ "Format of the margin in `magit-reflog-mode' buffers.
+
+The value has the form (INIT STYLE WIDTH AUTHOR AUTHOR-WIDTH).
+
+If INIT is non-nil, then the margin is shown initially.
+STYLE controls how to format the author or committer date.
+ It can be one of `age' (to show the age of the commit),
+ `age-abbreviated' (to abbreviate the time unit to a character),
+ or a string (suitable for `format-time-string') to show the
+ actual date. Option `magit-log-margin-show-committer-date'
+ controls which date is being displayed.
+WIDTH controls the width of the margin. This exists for forward
+ compatibility and currently the value should not be changed.
+AUTHOR controls whether the name of the author is also shown by
+ default.
+AUTHOR-WIDTH has to be an integer. When the name of the author
+ is shown, then this specifies how much space is used to do so."
+ :package-version '(magit . "2.9.0")
+ :group 'magit-log
+ :group 'magit-margin
+ :type magit-log-margin--custom-type
+ :initialize #'magit-custom-initialize-reset
+ :set-after '(magit-log-margin)
+ :set (apply-partially #'magit-margin-set-variable 'magit-reflog-mode))
+
+;;; Faces
+
+(defface magit-reflog-commit '((t :foreground "green"))
+ "Face for commit commands in reflogs."
+ :group 'magit-faces)
+
+(defface magit-reflog-amend '((t :foreground "magenta"))
+ "Face for amend commands in reflogs."
+ :group 'magit-faces)
+
+(defface magit-reflog-merge '((t :foreground "green"))
+ "Face for merge, checkout and branch commands in reflogs."
+ :group 'magit-faces)
+
+(defface magit-reflog-checkout '((t :foreground "blue"))
+ "Face for checkout commands in reflogs."
+ :group 'magit-faces)
+
+(defface magit-reflog-reset '((t :foreground "red"))
+ "Face for reset commands in reflogs."
+ :group 'magit-faces)
+
+(defface magit-reflog-rebase '((t :foreground "magenta"))
+ "Face for rebase commands in reflogs."
+ :group 'magit-faces)
+
+(defface magit-reflog-cherry-pick '((t :foreground "green"))
+ "Face for cherry-pick commands in reflogs."
+ :group 'magit-faces)
+
+(defface magit-reflog-remote '((t :foreground "cyan"))
+ "Face for pull and clone commands in reflogs."
+ :group 'magit-faces)
+
+(defface magit-reflog-other '((t :foreground "cyan"))
+ "Face for other commands in reflogs."
+ :group 'magit-faces)
+
+;;; Commands
+
+;;;###autoload
+(defun magit-reflog-current ()
+ "Display the reflog of the current branch.
+If `HEAD' is detached, then show the reflog for that instead."
+ (interactive)
+ (magit-reflog-setup-buffer (or (magit-get-current-branch) "HEAD")))
+
+;;;###autoload
+(defun magit-reflog-other (ref)
+ "Display the reflog of a branch or another ref."
+ (interactive (list (magit-read-local-branch-or-ref "Show reflog for")))
+ (magit-reflog-setup-buffer ref))
+
+;;;###autoload
+(defun magit-reflog-head ()
+ "Display the `HEAD' reflog."
+ (interactive)
+ (magit-reflog-setup-buffer "HEAD"))
+
+;;; Mode
+
+(defvar magit-reflog-mode-map
+ (let ((map (make-sparse-keymap)))
+ (set-keymap-parent map magit-log-mode-map)
+ (define-key map (kbd "C-c C-n") #'undefined)
+ (define-key map (kbd "L") #'magit-margin-settings)
+ map)
+ "Keymap for `magit-reflog-mode'.")
+
+(define-derived-mode magit-reflog-mode magit-mode "Magit Reflog"
+ "Mode for looking at Git reflog.
+
+This mode is documented in info node `(magit)Reflog'.
+
+\\<magit-mode-map>\
+Type \\[magit-refresh] to refresh the current buffer.
+Type \\[magit-visit-thing] or \\[magit-diff-show-or-scroll-up] \
+to visit the commit at point.
+
+Type \\[magit-cherry-pick] to apply the commit at point.
+Type \\[magit-reset] to reset `HEAD' to the commit at point.
+
+\\{magit-reflog-mode-map}"
+ :group 'magit-log
+ (hack-dir-local-variables-non-file-buffer)
+ (setq magit--imenu-item-types 'commit))
+
+(defun magit-reflog-setup-buffer (ref)
+ (require 'magit)
+ (magit-setup-buffer #'magit-reflog-mode nil
+ (magit-buffer-refname ref)
+ (magit-buffer-log-args (list (format "-n%s" magit-reflog-limit)))))
+
+(defun magit-reflog-refresh-buffer ()
+ (magit-set-header-line-format (concat "Reflog for " magit-buffer-refname))
+ (magit-insert-section (reflogbuf)
+ (magit-git-wash (apply-partially #'magit-log-wash-log 'reflog)
+ "reflog" "show" "--format=%h%x00%aN%x00%gd%x00%gs" "--date=raw"
+ magit-buffer-log-args magit-buffer-refname "--")))
+
+(cl-defmethod magit-buffer-value (&context (major-mode magit-reflog-mode))
+ magit-buffer-refname)
+
+(defvar magit-reflog-labels
+ '(("commit" . magit-reflog-commit)
+ ("amend" . magit-reflog-amend)
+ ("merge" . magit-reflog-merge)
+ ("checkout" . magit-reflog-checkout)
+ ("branch" . magit-reflog-checkout)
+ ("reset" . magit-reflog-reset)
+ ("rebase" . magit-reflog-rebase)
+ ("cherry-pick" . magit-reflog-cherry-pick)
+ ("initial" . magit-reflog-commit)
+ ("pull" . magit-reflog-remote)
+ ("clone" . magit-reflog-remote)
+ ("autosave" . magit-reflog-commit)
+ ("restart" . magit-reflog-reset)))
+
+(defun magit-reflog-format-subject (subject)
+ (let* ((match (string-match magit-reflog-subject-re subject))
+ (command (and match (match-string 1 subject)))
+ (option (and match (match-string 2 subject)))
+ (type (and match (match-string 3 subject)))
+ (label (if (string= command "commit")
+ (or type command)
+ command))
+ (text (if (string= command "commit")
+ label
+ (mapconcat #'identity
+ (delq nil (list command option type))
+ " "))))
+ (format "%-16s "
+ (magit--propertize-face
+ text (or (cdr (assoc label magit-reflog-labels))
+ 'magit-reflog-other)))))
+
+;;; _
+(provide 'magit-reflog)
+;;; magit-reflog.el ends here
diff --git a/elpa/magit-20220503.1245/magit-reflog.elc b/elpa/magit-20220503.1245/magit-reflog.elc
new file mode 100644
index 0000000..eca275d
--- /dev/null
+++ b/elpa/magit-20220503.1245/magit-reflog.elc
Binary files differ
diff --git a/elpa/magit-20220503.1245/magit-refs.el b/elpa/magit-20220503.1245/magit-refs.el
new file mode 100644
index 0000000..07b03d7
--- /dev/null
+++ b/elpa/magit-20220503.1245/magit-refs.el
@@ -0,0 +1,774 @@
+;;; magit-refs.el --- Listing references -*- lexical-binding:t -*-
+
+;; Copyright (C) 2008-2022 The Magit Project Contributors
+
+;; Author: Jonas Bernoulli <jonas@bernoul.li>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+
+;; SPDX-License-Identifier: GPL-3.0-or-later
+
+;; Magit 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.
+;;
+;; Magit 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 Magit. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This library implements support for listing references in a buffer.
+
+;;; Code:
+
+(require 'magit)
+
+;;; Options
+
+(defgroup magit-refs nil
+ "Inspect and manipulate Git branches and tags."
+ :link '(info-link "(magit)References Buffer")
+ :group 'magit-modes)
+
+(defcustom magit-refs-mode-hook nil
+ "Hook run after entering Magit-Refs mode."
+ :package-version '(magit . "2.1.0")
+ :group 'magit-refs
+ :type 'hook)
+
+(defcustom magit-refs-sections-hook
+ '(magit-insert-error-header
+ magit-insert-branch-description
+ magit-insert-local-branches
+ magit-insert-remote-branches
+ magit-insert-tags)
+ "Hook run to insert sections into a references buffer."
+ :package-version '(magit . "2.1.0")
+ :group 'magit-refs
+ :type 'hook)
+
+(defcustom magit-refs-show-commit-count nil
+ "Whether to show commit counts in Magit-Refs mode buffers.
+
+all Show counts for branches and tags.
+branch Show counts for branches only.
+nil Never show counts.
+
+To change the value in an existing buffer use the command
+`magit-refs-set-show-commit-count'."
+ :package-version '(magit . "2.1.0")
+ :group 'magit-refs
+ :safe (lambda (val) (memq val '(all branch nil)))
+ :type '(choice (const all :tag "For branches and tags")
+ (const branch :tag "For branches only")
+ (const nil :tag "Never")))
+(put 'magit-refs-show-commit-count 'safe-local-variable 'symbolp)
+(put 'magit-refs-show-commit-count 'permanent-local t)
+
+(defcustom magit-refs-pad-commit-counts nil
+ "Whether to pad all counts on all sides in `magit-refs-mode' buffers.
+
+If this is nil, then some commit counts are displayed right next
+to one of the branches that appear next to the count, without any
+space in between. This might look bad if the branch name faces
+look too similar to `magit-dimmed'.
+
+If this is non-nil, then spaces are placed on both sides of all
+commit counts."
+ :package-version '(magit . "2.12.0")
+ :group 'magit-refs
+ :type 'boolean)
+
+(defvar magit-refs-show-push-remote nil
+ "Whether to show the push-remotes of local branches.
+Also show the commits that the local branch is ahead and behind
+the push-target. Unfortunately there is a bug in Git that makes
+this useless (the commits ahead and behind the upstream are
+shown), so this isn't enabled yet.")
+
+(defcustom magit-refs-show-remote-prefix nil
+ "Whether to show the remote prefix in lists of remote branches.
+
+This is redundant because the name of the remote is already shown
+in the heading preceding the list of its branches."
+ :package-version '(magit . "2.12.0")
+ :group 'magit-refs
+ :type 'boolean)
+
+(defcustom magit-refs-margin
+ (list nil
+ (nth 1 magit-log-margin)
+ 'magit-log-margin-width nil
+ (nth 4 magit-log-margin))
+ "Format of the margin in `magit-refs-mode' buffers.
+
+The value has the form (INIT STYLE WIDTH AUTHOR AUTHOR-WIDTH).
+
+If INIT is non-nil, then the margin is shown initially.
+STYLE controls how to format the author or committer date.
+ It can be one of `age' (to show the age of the commit),
+ `age-abbreviated' (to abbreviate the time unit to a character),
+ or a string (suitable for `format-time-string') to show the
+ actual date. Option `magit-log-margin-show-committer-date'
+ controls which date is being displayed.
+WIDTH controls the width of the margin. This exists for forward
+ compatibility and currently the value should not be changed.
+AUTHOR controls whether the name of the author is also shown by
+ default.
+AUTHOR-WIDTH has to be an integer. When the name of the author
+ is shown, then this specifies how much space is used to do so."
+ :package-version '(magit . "2.9.0")
+ :group 'magit-refs
+ :group 'magit-margin
+ :safe (lambda (val) (memq val '(all branch nil)))
+ :type magit-log-margin--custom-type
+ :initialize #'magit-custom-initialize-reset
+ :set-after '(magit-log-margin)
+ :set (apply-partially #'magit-margin-set-variable 'magit-refs-mode))
+
+(defcustom magit-refs-margin-for-tags nil
+ "Whether to show information about tags in the margin.
+
+This is disabled by default because it is slow if there are many
+tags."
+ :package-version '(magit . "2.9.0")
+ :group 'magit-refs
+ :group 'magit-margin
+ :type 'boolean)
+
+(defcustom magit-refs-primary-column-width (cons 16 32)
+ "Width of the focus column in `magit-refs-mode' buffers.
+
+The primary column is the column that contains the name of the
+branch that the current row is about.
+
+If this is an integer, then the column is that many columns wide.
+Otherwise it has to be a cons-cell of two integers. The first
+specifies the minimal width, the second the maximal width. In that
+case the actual width is determined using the length of the names
+of the shown local branches. (Remote branches and tags are not
+taken into account when calculating to optimal width.)"
+ :package-version '(magit . "2.12.0")
+ :group 'magit-refs
+ :type '(choice (integer :tag "Constant wide")
+ (cons :tag "Wide constrains"
+ (integer :tag "Minimum")
+ (integer :tag "Maximum"))))
+
+(defcustom magit-refs-focus-column-width 5
+ "Width of the focus column in `magit-refs-mode' buffers.
+
+The focus column is the first column, which marks one
+branch (usually the current branch) as the focused branch using
+\"*\" or \"@\". For each other reference, this column optionally
+shows how many commits it is ahead of the focused branch and \"<\", or
+if it isn't ahead then the commits it is behind and \">\", or if it
+isn't behind either, then a \"=\".
+
+This column may also display only \"*\" or \"@\" for the focused
+branch, in which case this option is ignored. Use \"L v\" to
+change the verbosity of this column."
+ :package-version '(magit . "2.12.0")
+ :group 'magit-refs
+ :type 'integer)
+
+(defcustom magit-refs-filter-alist nil
+ "Alist controlling which refs are omitted from `magit-refs-mode' buffers.
+
+The purpose of this option is to forgo displaying certain refs
+based on their name. If you want to not display any refs of a
+certain type, then you should remove the appropriate function
+from `magit-refs-sections-hook' instead.
+
+All keys are tried in order until one matches. Then its value
+is used and subsequent elements are ignored. If the value is
+non-nil, then the reference is displayed, otherwise it is not.
+If no element matches, then the reference is displayed.
+
+A key can either be a regular expression that the refname has to
+match, or a function that takes the refname as only argument and
+returns a boolean. A remote branch such as \"origin/master\" is
+displayed as just \"master\", however for this comparison the
+former is used."
+ :package-version '(magit . "2.12.0")
+ :group 'magit-refs
+ :type '(alist :key-type (choice :tag "Key" regexp function)
+ :value-type (boolean :tag "Value"
+ :on "show (non-nil)"
+ :off "omit (nil)")))
+
+(defcustom magit-visit-ref-behavior nil
+ "Control how `magit-visit-ref' behaves in `magit-refs-mode' buffers.
+
+By default `magit-visit-ref' behaves like `magit-show-commit',
+in all buffers, including `magit-refs-mode' buffers. When the
+type of the section at point is `commit' then \"RET\" is bound to
+`magit-show-commit', and when the type is either `branch' or
+`tag' then it is bound to `magit-visit-ref'.
+
+\"RET\" is one of Magit's most essential keys and at least by
+default it should behave consistently across all of Magit,
+especially because users quickly learn that it does something
+very harmless; it shows more information about the thing at point
+in another buffer.
+
+However \"RET\" used to behave differently in `magit-refs-mode'
+buffers, doing surprising things, some of which cannot really be
+described as \"visit this thing\". If you have grown accustomed
+to such inconsistent, but to you useful, behavior, then you can
+restore that by adding one or more of the below symbols to the
+value of this option. But keep in mind that by doing so you
+don't only introduce inconsistencies, you also lose some
+functionality and might have to resort to `M-x magit-show-commit'
+to get it back.
+
+`magit-visit-ref' looks for these symbols in the order in which
+they are described here. If the presence of a symbol applies to
+the current situation, then the symbols that follow do not affect
+the outcome.
+
+`focus-on-ref'
+
+ With a prefix argument update the buffer to show commit counts
+ and lists of cherry commits relative to the reference at point
+ instead of relative to the current buffer or `HEAD'.
+
+ Instead of adding this symbol, consider pressing \"C-u y o RET\".
+
+`create-branch'
+
+ If point is on a remote branch, then create a new local branch
+ with the same name, use the remote branch as its upstream, and
+ then check out the local branch.
+
+ Instead of adding this symbol, consider pressing \"b c RET RET\",
+ like you would do in other buffers.
+
+`checkout-any'
+
+ Check out the reference at point. If that reference is a tag
+ or a remote branch, then this results in a detached `HEAD'.
+
+ Instead of adding this symbol, consider pressing \"b b RET\",
+ like you would do in other buffers.
+
+`checkout-branch'
+
+ Check out the local branch at point.
+
+ Instead of adding this symbol, consider pressing \"b b RET\",
+ like you would do in other buffers."
+ :package-version '(magit . "2.9.0")
+ :group 'magit-refs
+ :group 'magit-commands
+ :options '(focus-on-ref create-branch checkout-any checkout-branch)
+ :type '(list :convert-widget custom-hook-convert-widget))
+
+;;; Mode
+
+(defvar magit-refs-mode-map
+ (let ((map (make-sparse-keymap)))
+ (set-keymap-parent map magit-mode-map)
+ (define-key map (kbd "C-y") #'magit-refs-set-show-commit-count)
+ (define-key map (kbd "L") #'magit-margin-settings)
+ map)
+ "Keymap for `magit-refs-mode'.")
+
+(define-derived-mode magit-refs-mode magit-mode "Magit Refs"
+ "Mode which lists and compares references.
+
+This mode is documented in info node `(magit)References Buffer'.
+
+\\<magit-mode-map>\
+Type \\[magit-refresh] to refresh the current buffer.
+Type \\[magit-section-toggle] to expand or hide the section at point.
+Type \\[magit-visit-thing] or \\[magit-diff-show-or-scroll-up] \
+to visit the commit or branch at point.
+
+Type \\[magit-branch] to see available branch commands.
+Type \\[magit-merge] to merge the branch or commit at point.
+Type \\[magit-cherry-pick] to apply the commit at point.
+Type \\[magit-reset] to reset `HEAD' to the commit at point.
+
+\\{magit-refs-mode-map}"
+ :group 'magit-refs
+ (hack-dir-local-variables-non-file-buffer)
+ (setq magit--imenu-group-types '(local remote tags)))
+
+(defun magit-refs-setup-buffer (ref args)
+ (magit-setup-buffer #'magit-refs-mode nil
+ (magit-buffer-upstream ref)
+ (magit-buffer-arguments args)))
+
+(defun magit-refs-refresh-buffer ()
+ (setq magit-set-buffer-margin-refresh (not (magit-buffer-margin-p)))
+ (unless (magit-rev-verify magit-buffer-upstream)
+ (setq magit-refs-show-commit-count nil))
+ (magit-set-header-line-format
+ (format "%s %s" magit-buffer-upstream
+ (mapconcat #'identity magit-buffer-arguments " ")))
+ (magit-insert-section (branchbuf)
+ (magit-run-section-hook 'magit-refs-sections-hook))
+ (add-hook 'kill-buffer-hook #'magit-preserve-section-visibility-cache))
+
+(cl-defmethod magit-buffer-value (&context (major-mode magit-refs-mode))
+ (cons magit-buffer-upstream magit-buffer-arguments))
+
+;;; Commands
+
+;;;###autoload (autoload 'magit-show-refs "magit-refs" nil t)
+(transient-define-prefix magit-show-refs (&optional transient)
+ "List and compare references in a dedicated buffer."
+ :man-page "git-branch"
+ :value (lambda ()
+ (magit-show-refs-arguments magit-prefix-use-buffer-arguments))
+ ["Arguments"
+ (magit-for-each-ref:--contains)
+ ("-M" "Merged" "--merged=" magit-transient-read-revision)
+ ("-m" "Merged to HEAD" "--merged")
+ ("-N" "Not merged" "--no-merged=" magit-transient-read-revision)
+ ("-n" "Not merged to HEAD" "--no-merged")
+ (magit-for-each-ref:--sort)]
+ ["Actions"
+ ("y" "Show refs, comparing them with HEAD" magit-show-refs-head)
+ ("c" "Show refs, comparing them with current branch" magit-show-refs-current)
+ ("o" "Show refs, comparing them with other branch" magit-show-refs-other)
+ ("r" "Show refs, changing commit count display"
+ magit-refs-set-show-commit-count)]
+ (interactive (list (or (derived-mode-p 'magit-refs-mode)
+ current-prefix-arg)))
+ (if transient
+ (transient-setup 'magit-show-refs)
+ (magit-refs-setup-buffer "HEAD" (magit-show-refs-arguments))))
+
+(defun magit-show-refs-arguments (&optional use-buffer-args)
+ (unless use-buffer-args
+ (setq use-buffer-args magit-direct-use-buffer-arguments))
+ (let (args)
+ (cond
+ ((eq transient-current-command 'magit-show-refs)
+ (setq args (transient-args 'magit-show-refs)))
+ ((eq major-mode 'magit-refs-mode)
+ (setq args magit-buffer-arguments))
+ ((and (memq use-buffer-args '(always selected))
+ (when-let* ((buffer (magit-get-mode-buffer ;debbugs#31840
+ 'magit-refs-mode nil
+ (eq use-buffer-args 'selected))))
+ (setq args (buffer-local-value 'magit-buffer-arguments buffer))
+ t)))
+ (t
+ (setq args (alist-get 'magit-show-refs transient-values))))
+ args))
+
+(transient-define-argument magit-for-each-ref:--contains ()
+ :description "Contains"
+ :class 'transient-option
+ :key "-c"
+ :argument "--contains="
+ :reader #'magit-transient-read-revision)
+
+(transient-define-argument magit-for-each-ref:--sort ()
+ :description "Sort"
+ :class 'transient-option
+ :key "-s"
+ :argument "--sort="
+ :reader #'magit-read-ref-sort)
+
+(defun magit-read-ref-sort (prompt initial-input _history)
+ (magit-completing-read prompt
+ '("-committerdate" "-authordate"
+ "committerdate" "authordate")
+ nil nil initial-input))
+
+;;;###autoload
+(defun magit-show-refs-head (&optional args)
+ "List and compare references in a dedicated buffer.
+Compared with `HEAD'."
+ (interactive (list (magit-show-refs-arguments)))
+ (magit-refs-setup-buffer "HEAD" args))
+
+;;;###autoload
+(defun magit-show-refs-current (&optional args)
+ "List and compare references in a dedicated buffer.
+Compare with the current branch or `HEAD' if it is detached."
+ (interactive (list (magit-show-refs-arguments)))
+ (magit-refs-setup-buffer (magit-get-current-branch) args))
+
+;;;###autoload
+(defun magit-show-refs-other (&optional ref args)
+ "List and compare references in a dedicated buffer.
+Compared with a branch read from the user."
+ (interactive (list (magit-read-other-branch "Compare with")
+ (magit-show-refs-arguments)))
+ (magit-refs-setup-buffer ref args))
+
+(defun magit-refs-set-show-commit-count ()
+ "Change for which refs the commit count is shown."
+ (interactive)
+ (setq-local magit-refs-show-commit-count
+ (magit-read-char-case "Show commit counts for " nil
+ (?a "[a]ll refs" 'all)
+ (?b "[b]ranches only" t)
+ (?n "[n]othing" nil)))
+ (magit-refresh))
+
+(defun magit-visit-ref ()
+ "Visit the reference or revision at point in another buffer.
+If there is no revision at point or with a prefix argument prompt
+for a revision.
+
+This command behaves just like `magit-show-commit', except if
+point is on a reference in a `magit-refs-mode' buffer (a buffer
+listing branches and tags), in which case the behavior may be
+different, but only if you have customized the option
+`magit-visit-ref-behavior' (which see). When invoked from a
+menu this command always behaves like `magit-show-commit'."
+ (interactive)
+ (if (and (derived-mode-p 'magit-refs-mode)
+ (magit-section-match '(branch tag))
+ (not (magit-menu-position)))
+ (let ((ref (oref (magit-current-section) value)))
+ (cond (current-prefix-arg
+ (cond ((memq 'focus-on-ref magit-visit-ref-behavior)
+ (magit-refs-setup-buffer ref (magit-show-refs-arguments)))
+ (magit-visit-ref-behavior
+ ;; Don't prompt for commit to visit.
+ (let ((current-prefix-arg nil))
+ (call-interactively #'magit-show-commit)))))
+ ((and (memq 'create-branch magit-visit-ref-behavior)
+ (magit-section-match [branch remote]))
+ (let ((branch (cdr (magit-split-branch-name ref))))
+ (if (magit-branch-p branch)
+ (if (magit-rev-eq branch ref)
+ (magit-call-git "checkout" branch)
+ (setq branch (propertize branch 'face 'magit-branch-local))
+ (setq ref (propertize ref 'face 'magit-branch-remote))
+ (pcase (prog1 (read-char-choice (format (propertize "\
+Branch %s already exists.
+ [c]heckout %s as-is
+ [r]reset %s to %s and checkout %s
+ [a]bort " 'face 'minibuffer-prompt) branch branch branch ref branch)
+ '(?c ?r ?a))
+ (message "")) ; otherwise prompt sticks
+ (?c (magit-call-git "checkout" branch))
+ (?r (magit-call-git "checkout" "-B" branch ref))
+ (?a (user-error "Abort"))))
+ (magit-call-git "checkout" "-b" branch ref))
+ (setq magit-buffer-upstream branch)
+ (magit-refresh)))
+ ((or (memq 'checkout-any magit-visit-ref-behavior)
+ (and (memq 'checkout-branch magit-visit-ref-behavior)
+ (magit-section-match [branch local])))
+ (magit-call-git "checkout" ref)
+ (setq magit-buffer-upstream ref)
+ (magit-refresh))
+ (t
+ (call-interactively #'magit-show-commit))))
+ (call-interactively #'magit-show-commit)))
+
+;;; Sections
+
+(defvar magit-remote-section-map
+ (let ((map (make-sparse-keymap)))
+ (magit-menu-set map [magit-delete-thing] #'magit-remote-remove "Remove %m")
+ (magit-menu-set map [magit-file-rename] #'magit-remote-rename "Rename %s")
+ map)
+ "Keymap for `remote' sections.")
+
+(defvar magit-branch-section-map
+ (let ((map (make-sparse-keymap)))
+ (magit-menu-set map [magit-visit-thing] #'magit-visit-ref "Visit commit")
+ (magit-menu-set map [magit-delete-thing] #'magit-branch-delete "Delete %m")
+ (magit-menu-set map [magit-file-rename] #'magit-branch-rename "Rename %s")
+ map)
+ "Keymap for `branch' sections.")
+
+(defvar magit-tag-section-map
+ (let ((map (make-sparse-keymap)))
+ (magit-menu-set map [magit-visit-thing] #'magit-visit-ref "Visit %s")
+ (magit-menu-set map [magit-delete-thing] #'magit-tag-delete "Delete %m")
+ map)
+ "Keymap for `tag' sections.")
+
+(defun magit--painted-branch-as-menu-section (section)
+ (and-let* ((branch (and (magit-section-match 'commit)
+ (magit--painted-branch-at-point))))
+ (let ((dummy (magit-section :type 'branch :value branch)))
+ (oset dummy keymap magit-branch-section-map)
+ (dolist (slot '(start content hidden parent children))
+ (when (slot-boundp section slot)
+ (setf (eieio-oref dummy slot)
+ (eieio-oref section slot))))
+ dummy)))
+
+(add-hook 'magit-menu-alternative-section-hook
+ #'magit--painted-branch-as-menu-section)
+
+(defun magit-insert-branch-description ()
+ "Insert header containing the description of the current branch.
+Insert a header line with the name and description of the
+current branch. The description is taken from the Git variable
+`branch.<NAME>.description'; if that is undefined then no header
+line is inserted at all."
+ (when-let* ((branch (magit-get-current-branch))
+ (desc (magit-get "branch" branch "description"))
+ (desc (split-string desc "\n")))
+ (when (equal (car (last desc)) "")
+ (setq desc (butlast desc)))
+ (magit-insert-section (branchdesc branch t)
+ (magit-insert-heading branch ": " (car desc))
+ (when (cdr desc)
+ (insert (mapconcat #'identity (cdr desc) "\n"))
+ (insert "\n\n")))))
+
+(defun magit-insert-tags ()
+ "Insert sections showing all tags."
+ (when-let ((tags (magit-git-lines "tag" "--list" "-n" magit-buffer-arguments)))
+ (let ((_head (magit-rev-parse "HEAD")))
+ (magit-insert-section (tags)
+ (magit-insert-heading "Tags:")
+ (dolist (tag tags)
+ (string-match "^\\([^ \t]+\\)[ \t]+\\([^ \t\n].*\\)?" tag)
+ (let ((tag (match-string 1 tag))
+ (msg (match-string 2 tag)))
+ (when (magit-refs--insert-refname-p tag)
+ (magit-insert-section (tag tag t)
+ (magit-insert-heading
+ (magit-refs--format-focus-column tag 'tag)
+ (propertize tag 'font-lock-face 'magit-tag)
+ (make-string
+ (max 1 (- (if (consp magit-refs-primary-column-width)
+ (car magit-refs-primary-column-width)
+ magit-refs-primary-column-width)
+ (length tag)))
+ ?\s)
+ (and msg (magit-log-propertize-keywords nil msg)))
+ (when (and magit-refs-margin-for-tags (magit-buffer-margin-p))
+ (magit-refs--format-margin tag))
+ (magit-refs--insert-cherry-commits tag)))))
+ (insert ?\n)
+ (magit-make-margin-overlay nil t)))))
+
+(defun magit-insert-remote-branches ()
+ "Insert sections showing all remote-tracking branches."
+ (dolist (remote (magit-list-remotes))
+ (magit-insert-section (remote remote)
+ (magit-insert-heading
+ (let ((pull (magit-get "remote" remote "url"))
+ (push (magit-get "remote" remote "pushurl")))
+ (format (propertize "Remote %s (%s):"
+ 'font-lock-face 'magit-section-heading)
+ (propertize remote 'font-lock-face 'magit-branch-remote)
+ (concat pull (and pull push ", ") push))))
+ (let (head)
+ (dolist (line (magit-git-lines "for-each-ref" "--format=\
+%(symref:short)%00%(refname:short)%00%(refname)%00%(subject)"
+ (concat "refs/remotes/" remote)
+ magit-buffer-arguments))
+ (pcase-let ((`(,head-branch ,branch ,ref ,msg)
+ (-replace "" nil (split-string line "\0"))))
+ (if head-branch
+ (progn (cl-assert (equal branch (concat remote "/HEAD")))
+ (setq head head-branch))
+ (when (magit-refs--insert-refname-p branch)
+ (magit-insert-section (branch branch t)
+ (let ((headp (equal branch head))
+ (abbrev (if magit-refs-show-remote-prefix
+ branch
+ (substring branch (1+ (length remote))))))
+ (magit-insert-heading
+ (magit-refs--format-focus-column branch)
+ (magit-refs--propertize-branch
+ abbrev ref (and headp 'magit-branch-remote-head))
+ (make-string
+ (max 1 (- (if (consp magit-refs-primary-column-width)
+ (car magit-refs-primary-column-width)
+ magit-refs-primary-column-width)
+ (length abbrev)))
+ ?\s)
+ (and msg (magit-log-propertize-keywords nil msg))))
+ (when (magit-buffer-margin-p)
+ (magit-refs--format-margin branch))
+ (magit-refs--insert-cherry-commits branch)))))))
+ (insert ?\n)
+ (magit-make-margin-overlay nil t))))
+
+(defun magit-insert-local-branches ()
+ "Insert sections showing all local branches."
+ (magit-insert-section (local nil)
+ (magit-insert-heading "Branches:")
+ (dolist (line (magit-refs--format-local-branches))
+ (pcase-let ((`(,branch . ,strings) line))
+ (magit-insert-section
+ ((eval (if branch 'branch 'commit))
+ (or branch (magit-rev-parse "HEAD"))
+ t)
+ (apply #'magit-insert-heading strings)
+ (when (magit-buffer-margin-p)
+ (magit-refs--format-margin branch))
+ (magit-refs--insert-cherry-commits branch))))
+ (insert ?\n)
+ (magit-make-margin-overlay nil t)))
+
+(defun magit-refs--format-local-branches ()
+ (let ((lines (-keep #'magit-refs--format-local-branch
+ (magit-git-lines
+ "for-each-ref"
+ (concat "--format=\
+%(HEAD)%00%(refname:short)%00%(refname)%00\
+%(upstream:short)%00%(upstream)%00%(upstream:track)%00"
+ (if magit-refs-show-push-remote "\
+%(push:remotename)%00%(push)%00%(push:track)%00%(subject)"
+ "%00%00%00%(subject)"))
+ "refs/heads"
+ magit-buffer-arguments))))
+ (unless (magit-get-current-branch)
+ (push (magit-refs--format-local-branch
+ (concat "*\0\0\0\0\0\0\0\0" (magit-rev-format "%s")))
+ lines))
+ (setq-local magit-refs-primary-column-width
+ (let ((def (default-value 'magit-refs-primary-column-width)))
+ (if (atom def)
+ def
+ (pcase-let ((`(,min . ,max) def))
+ (min max (apply #'max min (mapcar #'car lines)))))))
+ (mapcar (pcase-lambda (`(,_ ,branch ,focus ,branch-desc ,u:ahead ,p:ahead
+ ,u:behind ,upstream ,p:behind ,push ,msg))
+ (list branch focus branch-desc u:ahead p:ahead
+ (make-string (max 1 (- magit-refs-primary-column-width
+ (length (concat branch-desc
+ u:ahead
+ p:ahead
+ u:behind))))
+ ?\s)
+ u:behind upstream p:behind push
+ msg))
+ lines)))
+
+(defun magit-refs--format-local-branch (line)
+ (pcase-let ((`(,head ,branch ,ref ,upstream ,u:ref ,u:track
+ ,push ,p:ref ,p:track ,msg)
+ (-replace "" nil (split-string line "\0"))))
+ (when (or (not branch)
+ (magit-refs--insert-refname-p branch))
+ (let* ((headp (equal head "*"))
+ (pushp (and push
+ magit-refs-show-push-remote
+ (magit-rev-verify p:ref)
+ (not (equal p:ref u:ref))))
+ (branch-desc
+ (if branch
+ (magit-refs--propertize-branch
+ branch ref (and headp 'magit-branch-current))
+ (magit--propertize-face "(detached)" 'magit-branch-warning)))
+ (u:ahead (and u:track
+ (string-match "ahead \\([0-9]+\\)" u:track)
+ (magit--propertize-face
+ (concat (and magit-refs-pad-commit-counts " ")
+ (match-string 1 u:track)
+ ">")
+ 'magit-dimmed)))
+ (u:behind (and u:track
+ (string-match "behind \\([0-9]+\\)" u:track)
+ (magit--propertize-face
+ (concat "<"
+ (match-string 1 u:track)
+ (and magit-refs-pad-commit-counts " "))
+ 'magit-dimmed)))
+ (p:ahead (and pushp p:track
+ (string-match "ahead \\([0-9]+\\)" p:track)
+ (magit--propertize-face
+ (concat (match-string 1 p:track)
+ ">"
+ (and magit-refs-pad-commit-counts " "))
+ 'magit-branch-remote)))
+ (p:behind (and pushp p:track
+ (string-match "behind \\([0-9]+\\)" p:track)
+ (magit--propertize-face
+ (concat "<"
+ (match-string 1 p:track)
+ (and magit-refs-pad-commit-counts " "))
+ 'magit-dimmed))))
+ (list (1+ (length (concat branch-desc u:ahead p:ahead u:behind)))
+ branch
+ (magit-refs--format-focus-column branch headp)
+ branch-desc u:ahead p:ahead u:behind
+ (and upstream
+ (concat (if (equal u:track "[gone]")
+ (magit--propertize-face upstream 'error)
+ (magit-refs--propertize-branch upstream u:ref))
+ " "))
+ (and pushp
+ (concat p:behind
+ (magit--propertize-face
+ push 'magit-branch-remote)
+ " "))
+ (and msg (magit-log-propertize-keywords nil msg)))))))
+
+(defun magit-refs--format-focus-column (ref &optional type)
+ (let ((focus magit-buffer-upstream)
+ (width (if magit-refs-show-commit-count
+ magit-refs-focus-column-width
+ 1)))
+ (format
+ (format "%%%ss " width)
+ (cond ((or (equal ref focus)
+ (and (eq type t)
+ (equal focus "HEAD")))
+ (magit--propertize-face (concat (if (equal focus "HEAD") "@" "*")
+ (make-string (1- width) ?\s))
+ 'magit-section-heading))
+ ((if (eq type 'tag)
+ (eq magit-refs-show-commit-count 'all)
+ magit-refs-show-commit-count)
+ (pcase-let ((`(,behind ,ahead)
+ (magit-rev-diff-count magit-buffer-upstream ref)))
+ (magit--propertize-face
+ (cond ((> ahead 0) (concat "<" (number-to-string ahead)))
+ ((> behind 0) (concat (number-to-string behind) ">"))
+ (t "="))
+ 'magit-dimmed)))
+ (t "")))))
+
+(defun magit-refs--propertize-branch (branch ref &optional head-face)
+ (let ((face (cdr (cl-find-if (pcase-lambda (`(,re . ,_))
+ (string-match-p re ref))
+ magit-ref-namespaces))))
+ (magit--propertize-face
+ branch (if head-face (list face head-face) face))))
+
+(defun magit-refs--insert-refname-p (refname)
+ (--if-let (-first (pcase-lambda (`(,key . ,_))
+ (if (functionp key)
+ (funcall key refname)
+ (string-match-p key refname)))
+ magit-refs-filter-alist)
+ (cdr it)
+ t))
+
+(defun magit-refs--insert-cherry-commits (ref)
+ (magit-insert-section-body
+ (let ((start (point))
+ (magit-insert-section--current nil))
+ (magit-git-wash (apply-partially #'magit-log-wash-log 'cherry)
+ "cherry" "-v" (magit-abbrev-arg) magit-buffer-upstream ref)
+ (if (= (point) start)
+ (message "No cherries for %s" ref)
+ (magit-make-margin-overlay nil t)))))
+
+(defun magit-refs--format-margin (commit)
+ (save-excursion
+ (goto-char (line-beginning-position 0))
+ (let ((line (magit-rev-format "%ct%cN" commit)))
+ (magit-log-format-margin commit
+ (substring line 10)
+ (substring line 0 10)))))
+
+;;; _
+(provide 'magit-refs)
+;;; magit-refs.el ends here
diff --git a/elpa/magit-20220503.1245/magit-refs.elc b/elpa/magit-20220503.1245/magit-refs.elc
new file mode 100644
index 0000000..8d44f8e
--- /dev/null
+++ b/elpa/magit-20220503.1245/magit-refs.elc
Binary files differ
diff --git a/elpa/magit-20220503.1245/magit-remote.el b/elpa/magit-20220503.1245/magit-remote.el
new file mode 100644
index 0000000..8c9dc1e
--- /dev/null
+++ b/elpa/magit-20220503.1245/magit-remote.el
@@ -0,0 +1,368 @@
+;;; magit-remote.el --- Transfer Git commits -*- lexical-binding:t -*-
+
+;; Copyright (C) 2008-2022 The Magit Project Contributors
+
+;; Author: Jonas Bernoulli <jonas@bernoul.li>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+
+;; SPDX-License-Identifier: GPL-3.0-or-later
+
+;; Magit 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.
+;;
+;; Magit 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 Magit. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This library implements remote commands.
+
+;;; Code:
+
+(require 'magit)
+
+;;; Options
+
+(defcustom magit-remote-add-set-remote.pushDefault 'ask-if-unset
+ "Whether to set the value of `remote.pushDefault' after adding a remote.
+
+If `ask', then always ask. If `ask-if-unset', then ask, but only
+if the variable isn't set already. If nil, then don't ever set.
+If the value is a string, then set without asking, provided that
+the name of the added remote is equal to that string and the
+variable isn't already set."
+ :package-version '(magit . "2.4.0")
+ :group 'magit-commands
+ :type '(choice (const :tag "ask if unset" ask-if-unset)
+ (const :tag "always ask" ask)
+ (string :tag "set if named")
+ (const :tag "don't set")))
+
+(defcustom magit-remote-direct-configure t
+ "Whether the command `magit-remote' shows Git variables.
+When set to nil, no variables are displayed by this transient
+command, instead the sub-transient `magit-remote-configure'
+has to be used to view and change remote related variables."
+ :package-version '(magit . "2.12.0")
+ :group 'magit-commands
+ :type 'boolean)
+
+(defcustom magit-prefer-push-default nil
+ "Whether to prefer `remote.pushDefault' over per-branch variables."
+ :package-version '(magit . "3.0.0")
+ :group 'magit-commands
+ :type 'boolean)
+
+;;; Commands
+
+;;;###autoload (autoload 'magit-remote "magit-remote" nil t)
+(transient-define-prefix magit-remote (remote)
+ "Add, configure or remove a remote."
+ :man-page "git-remote"
+ :value '("-f")
+ ["Variables"
+ :if (lambda ()
+ (and magit-remote-direct-configure
+ (oref transient--prefix scope)))
+ ("u" magit-remote.<remote>.url)
+ ("U" magit-remote.<remote>.fetch)
+ ("s" magit-remote.<remote>.pushurl)
+ ("S" magit-remote.<remote>.push)
+ ("O" magit-remote.<remote>.tagopt)]
+ ["Arguments for add"
+ ("-f" "Fetch after add" "-f")]
+ ["Actions"
+ [("a" "Add" magit-remote-add)
+ ("r" "Rename" magit-remote-rename)
+ ("k" "Remove" magit-remote-remove)]
+ [("C" "Configure..." magit-remote-configure)
+ ("p" "Prune stale branches" magit-remote-prune)
+ ("P" "Prune stale refspecs" magit-remote-prune-refspecs)
+ (7 "z" "Unshallow remote" magit-remote-unshallow)]]
+ (interactive (list (magit-get-current-remote)))
+ (transient-setup 'magit-remote nil nil :scope remote))
+
+(defun magit-read-url (prompt &optional initial-input)
+ (let ((url (magit-read-string-ns prompt initial-input)))
+ (if (string-prefix-p "~" url)
+ (expand-file-name url)
+ url)))
+
+;;;###autoload
+(defun magit-remote-add (remote url &optional args)
+ "Add a remote named REMOTE and fetch it."
+ (interactive
+ (let ((origin (magit-get "remote.origin.url"))
+ (remote (magit-read-string-ns "Remote name")))
+ (list remote
+ (magit-read-url
+ "Remote url"
+ (and origin
+ (string-match "\\([^:/]+\\)/[^/]+\\(\\.git\\)?\\'" origin)
+ (replace-match remote t t origin 1)))
+ (transient-args 'magit-remote))))
+ (if (pcase (list magit-remote-add-set-remote.pushDefault
+ (magit-get "remote.pushDefault"))
+ (`(,(pred stringp) ,_) t)
+ ((or `(ask ,_) '(ask-if-unset nil))
+ (y-or-n-p (format "Set `remote.pushDefault' to \"%s\"? " remote))))
+ (progn (magit-call-git "remote" "add" args remote url)
+ (setf (magit-get "remote.pushDefault") remote)
+ (magit-refresh))
+ (magit-run-git-async "remote" "add" args remote url)))
+
+;;;###autoload
+(defun magit-remote-rename (old new)
+ "Rename the remote named OLD to NEW."
+ (interactive
+ (let ((remote (magit-read-remote "Rename remote")))
+ (list remote (magit-read-string-ns (format "Rename %s to" remote)))))
+ (unless (string= old new)
+ (magit-call-git "remote" "rename" old new)
+ (magit-remote--cleanup-push-variables old new)
+ (magit-refresh)))
+
+;;;###autoload
+(defun magit-remote-remove (remote)
+ "Delete the remote named REMOTE."
+ (interactive (list (magit-read-remote "Delete remote")))
+ (magit-call-git "remote" "rm" remote)
+ (magit-remote--cleanup-push-variables remote)
+ (magit-refresh))
+
+(defun magit-remote--cleanup-push-variables (remote &optional new-name)
+ (magit-with-toplevel
+ (when (equal (magit-get "remote.pushDefault") remote)
+ (magit-set new-name "remote.pushDefault"))
+ (dolist (var (magit-git-lines "config" "--name-only"
+ "--get-regexp" "^branch\.[^.]*\.pushRemote"
+ (format "^%s$" remote)))
+ (magit-call-git "config" (and (not new-name) "--unset") var new-name))))
+
+(defconst magit--refspec-re "\\`\\(\\+\\)?\\([^:]+\\):\\(.*\\)\\'")
+
+;;;###autoload
+(defun magit-remote-prune (remote)
+ "Remove stale remote-tracking branches for REMOTE."
+ (interactive (list (magit-read-remote "Prune stale branches of remote")))
+ (magit-run-git-async "remote" "prune" remote))
+
+;;;###autoload
+(defun magit-remote-prune-refspecs (remote)
+ "Remove stale refspecs for REMOTE.
+
+A refspec is stale if there no longer exists at least one branch
+on the remote that would be fetched due to that refspec. A stale
+refspec is problematic because its existence causes Git to refuse
+to fetch according to the remaining non-stale refspecs.
+
+If only stale refspecs remain, then offer to either delete the
+remote or to replace the stale refspecs with the default refspec.
+
+Also remove the remote-tracking branches that were created due to
+the now stale refspecs. Other stale branches are not removed."
+ (interactive (list (magit-read-remote "Prune refspecs of remote")))
+ (let* ((tracking-refs (magit-list-remote-branches remote))
+ (remote-refs (magit-remote-list-refs remote))
+ (variable (format "remote.%s.fetch" remote))
+ (refspecs (magit-get-all variable))
+ stale)
+ (dolist (refspec refspecs)
+ (when (string-match magit--refspec-re refspec)
+ (let ((theirs (match-string 2 refspec))
+ (ours (match-string 3 refspec)))
+ (unless (if (string-match "\\*" theirs)
+ (let ((re (replace-match ".*" t t theirs)))
+ (--some (string-match-p re it) remote-refs))
+ (member theirs remote-refs))
+ (push (cons refspec
+ (if (string-match "\\*" ours)
+ (let ((re (replace-match ".*" t t ours)))
+ (--filter (string-match-p re it) tracking-refs))
+ (list (car (member ours tracking-refs)))))
+ stale)))))
+ (if (not stale)
+ (message "No stale refspecs for remote %S" remote)
+ (if (= (length stale)
+ (length refspecs))
+ (magit-read-char-case
+ (format "All of %s's refspecs are stale. " remote) nil
+ (?s "replace with [d]efault refspec"
+ (magit-set-all
+ (list (format "+refs/heads/*:refs/remotes/%s/*" remote))
+ variable))
+ (?r "[r]emove remote"
+ (magit-call-git "remote" "rm" remote))
+ (?a "or [a]abort"
+ (user-error "Abort")))
+ (if (if (length= stale 1)
+ (pcase-let ((`(,refspec . ,refs) (car stale)))
+ (magit-confirm 'prune-stale-refspecs
+ (format "Prune stale refspec %s and branch %%s" refspec)
+ (format "Prune stale refspec %s and %%i branches" refspec)
+ nil refs))
+ (magit-confirm 'prune-stale-refspecs nil
+ (format "Prune %%i stale refspecs and %i branches"
+ (length (cl-mapcan (lambda (s) (copy-sequence (cdr s)))
+ stale)))
+ nil
+ (mapcar (pcase-lambda (`(,refspec . ,refs))
+ (concat refspec "\n"
+ (mapconcat (lambda (b) (concat " " b))
+ refs "\n")))
+ stale)))
+ (pcase-dolist (`(,refspec . ,refs) stale)
+ (magit-call-git "config" "--unset" variable
+ (regexp-quote refspec))
+ (magit--log-action
+ (lambda (refs)
+ (format "Deleting %i branches" (length refs)))
+ (lambda (ref)
+ (format "Deleting branch %s (was %s)" ref
+ (magit-rev-parse "--short" ref)))
+ refs)
+ (dolist (ref refs)
+ (magit-call-git "update-ref" "-d" ref)))
+ (user-error "Abort")))
+ (magit-refresh))))
+
+;;;###autoload
+(defun magit-remote-set-head (remote &optional branch)
+ "Set the local representation of REMOTE's default branch.
+Query REMOTE and set the symbolic-ref refs/remotes/<remote>/HEAD
+accordingly. With a prefix argument query for the branch to be
+used, which allows you to select an incorrect value if you fancy
+doing that."
+ (interactive
+ (let ((remote (magit-read-remote "Set HEAD for remote")))
+ (list remote
+ (and current-prefix-arg
+ (magit-read-remote-branch (format "Set %s/HEAD to" remote)
+ remote nil nil t)))))
+ (magit-run-git "remote" "set-head" remote (or branch "--auto")))
+
+;;;###autoload
+(defun magit-remote-unset-head (remote)
+ "Unset the local representation of REMOTE's default branch.
+Delete the symbolic-ref \"refs/remotes/<remote>/HEAD\"."
+ (interactive (list (magit-read-remote "Unset HEAD for remote")))
+ (magit-run-git "remote" "set-head" remote "--delete"))
+
+;;;###autoload
+(defun magit-remote-unshallow (remote)
+ "Convert a shallow remote into a full one.
+If only a single refspec is set and it does not contain a
+wildcard, then also offer to replace it with the standard
+refspec."
+ (interactive (list (or (magit-get-current-remote)
+ (magit-read-remote "Delete remote"))))
+ (let ((refspecs (magit-get-all "remote" remote "fetch"))
+ (standard (format "+refs/heads/*:refs/remotes/%s/*" remote)))
+ (when (and (length= refspecs 1)
+ (not (string-search "*" (car refspecs)))
+ (yes-or-no-p (format "Also replace refspec %s with %s? "
+ (car refspecs)
+ standard)))
+ (magit-set standard "remote" remote "fetch"))
+ (magit-git-fetch "--unshallow" remote)))
+
+;;; Configure
+
+;;;###autoload (autoload 'magit-remote-configure "magit-remote" nil t)
+(transient-define-prefix magit-remote-configure (remote)
+ "Configure a remote."
+ :man-page "git-remote"
+ [:description
+ (lambda ()
+ (concat
+ (propertize "Configure " 'face 'transient-heading)
+ (propertize (oref transient--prefix scope) 'face 'magit-branch-remote)))
+ ("u" magit-remote.<remote>.url)
+ ("U" magit-remote.<remote>.fetch)
+ ("s" magit-remote.<remote>.pushurl)
+ ("S" magit-remote.<remote>.push)
+ ("O" magit-remote.<remote>.tagopt)]
+ (interactive
+ (list (or (and (not current-prefix-arg)
+ (not (and magit-remote-direct-configure
+ (eq transient-current-command 'magit-remote)))
+ (magit-get-current-remote))
+ (magit--read-remote-scope))))
+ (transient-setup 'magit-remote-configure nil nil :scope remote))
+
+(defun magit--read-remote-scope (&optional obj)
+ (magit-read-remote
+ (if obj
+ (format "Set %s for remote"
+ (format (oref obj variable) "<name>"))
+ "Configure remote")))
+
+(transient-define-infix magit-remote.<remote>.url ()
+ :class 'magit--git-variable:urls
+ :scope #'magit--read-remote-scope
+ :variable "remote.%s.url"
+ :multi-value t
+ :history-key 'magit-remote.<remote>.*url)
+
+(transient-define-infix magit-remote.<remote>.fetch ()
+ :class 'magit--git-variable
+ :scope #'magit--read-remote-scope
+ :variable "remote.%s.fetch"
+ :multi-value t)
+
+(transient-define-infix magit-remote.<remote>.pushurl ()
+ :class 'magit--git-variable:urls
+ :scope #'magit--read-remote-scope
+ :variable "remote.%s.pushurl"
+ :multi-value t
+ :history-key 'magit-remote.<remote>.*url
+ :seturl-arg "--push")
+
+(transient-define-infix magit-remote.<remote>.push ()
+ :class 'magit--git-variable
+ :scope #'magit--read-remote-scope
+ :variable "remote.%s.push")
+
+(transient-define-infix magit-remote.<remote>.tagopt ()
+ :class 'magit--git-variable:choices
+ :scope #'magit--read-remote-scope
+ :variable "remote.%s.tagOpt"
+ :choices '("--no-tags" "--tags"))
+
+;;; Transfer Utilities
+
+(defun magit--push-remote-variable (&optional branch short)
+ (unless branch
+ (setq branch (magit-get-current-branch)))
+ (magit--propertize-face
+ (if (or (not branch) magit-prefer-push-default)
+ (if short "pushDefault" "remote.pushDefault")
+ (if short "pushRemote" (format "branch.%s.pushRemote" branch)))
+ 'bold))
+
+(defun magit--select-push-remote (prompt-suffix)
+ (let* ((branch (or (magit-get-current-branch)
+ (user-error "No branch is checked out")))
+ (remote (magit-get-push-remote branch))
+ (changed nil))
+ (when (or current-prefix-arg
+ (not remote)
+ (not (member remote (magit-list-remotes))))
+ (setq changed t)
+ (setq remote
+ (magit-read-remote (format "Set %s and %s"
+ (magit--push-remote-variable)
+ prompt-suffix)))
+ (setf (magit-get (magit--push-remote-variable branch)) remote))
+ (list branch remote changed)))
+
+;;; _
+(provide 'magit-remote)
+;;; magit-remote.el ends here
diff --git a/elpa/magit-20220503.1245/magit-remote.elc b/elpa/magit-20220503.1245/magit-remote.elc
new file mode 100644
index 0000000..2633fef
--- /dev/null
+++ b/elpa/magit-20220503.1245/magit-remote.elc
Binary files differ
diff --git a/elpa/magit-20220503.1245/magit-repos.el b/elpa/magit-20220503.1245/magit-repos.el
new file mode 100644
index 0000000..9dd924f
--- /dev/null
+++ b/elpa/magit-20220503.1245/magit-repos.el
@@ -0,0 +1,543 @@
+;;; magit-repos.el --- Listing repositories -*- lexical-binding:t -*-
+
+;; Copyright (C) 2008-2022 The Magit Project Contributors
+
+;; Author: Jonas Bernoulli <jonas@bernoul.li>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+
+;; SPDX-License-Identifier: GPL-3.0-or-later
+
+;; Magit 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.
+;;
+;; Magit 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 Magit. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This library implements support for listing repositories. This
+;; includes getting a Lisp list of known repositories as well as a
+;; mode for listing repositories in a buffer.
+
+;;; Code:
+
+(require 'magit-core)
+
+(declare-function magit-status-setup-buffer "magit-status" (&optional directory))
+
+(defvar x-stretch-cursor)
+
+;;; Options
+
+(defcustom magit-repository-directories nil
+ "List of directories that are or contain Git repositories.
+
+Each element has the form (DIRECTORY . DEPTH). DIRECTORY has
+to be a directory or a directory file-name, a string. DEPTH,
+an integer, specifies the maximum depth to look for Git
+repositories. If it is 0, then only add DIRECTORY itself.
+
+This option controls which repositories are being listed by
+`magit-list-repositories'. It also affects `magit-status'
+\(which see) in potentially surprising ways."
+ :package-version '(magit . "3.0.0")
+ :group 'magit-essentials
+ :type '(repeat (cons directory (integer :tag "Depth"))))
+
+(defgroup magit-repolist nil
+ "List repositories in a buffer."
+ :link '(info-link "(magit)Repository List")
+ :group 'magit-modes)
+
+(defcustom magit-repolist-mode-hook '(hl-line-mode)
+ "Hook run after entering Magit-Repolist mode."
+ :package-version '(magit . "2.9.0")
+ :group 'magit-repolist
+ :type 'hook
+ :get #'magit-hook-custom-get
+ :options '(hl-line-mode))
+
+(defcustom magit-repolist-columns
+ '(("Name" 25 magit-repolist-column-ident nil)
+ ("Version" 25 magit-repolist-column-version
+ ((:sort magit-repolist-version<)))
+ ("B<U" 3 magit-repolist-column-unpulled-from-upstream
+ (;; (:help-echo "Upstream changes not in branch")
+ (:right-align t)
+ (:sort <)))
+ ("B>U" 3 magit-repolist-column-unpushed-to-upstream
+ (;; (:help-echo "Local changes not in upstream")
+ (:right-align t)
+ (:sort <)))
+ ("Path" 99 magit-repolist-column-path nil))
+ "List of columns displayed by `magit-list-repositories'.
+
+Each element has the form (HEADER WIDTH FORMAT PROPS).
+
+HEADER is the string displayed in the header. WIDTH is the width
+of the column. FORMAT is a function that is called with one
+argument, the repository identification (usually its basename),
+and with `default-directory' bound to the toplevel of its working
+tree. It has to return a string to be inserted or nil. PROPS is
+an alist that supports the keys `:right-align', `:pad-right' and
+`:sort'.
+
+The `:sort' function has a weird interface described in the
+docstring of `tabulated-list--get-sort'. Alternatively `<' and
+`magit-repolist-version<' can be used as those functions are
+automatically replaced with functions that satisfy the interface.
+Set `:sort' to nil to inhibit sorting; if unspecifed, then the
+column is sortable using the default sorter.
+
+You may wish to display a range of numeric columns using just one
+character per column and without any padding between columns, in
+which case you should use an appropriat HEADER, set WIDTH to 1,
+and set `:pad-right' to 0. \"+\" is substituted for numbers higher
+than 9."
+ :package-version '(magit . "2.12.0")
+ :group 'magit-repolist
+ :type '(repeat (list :tag "Column"
+ (string :tag "Header Label")
+ (integer :tag "Column Width")
+ (function :tag "Inserter Function")
+ (repeat :tag "Properties"
+ (list (choice :tag "Property"
+ (const :right-align)
+ (const :pad-right)
+ (const :sort)
+ (symbol))
+ (sexp :tag "Value"))))))
+
+(defcustom magit-repolist-column-flag-alist
+ '((magit-untracked-files . "N")
+ (magit-unstaged-files . "U")
+ (magit-staged-files . "S"))
+ "Association list of predicates and flags for `magit-repolist-column-flag'.
+
+Each element is of the form (FUNCTION . FLAG). Each FUNCTION is
+called with no arguments, with `default-directory' bound to the
+top level of a repository working tree, until one of them returns
+a non-nil value. FLAG corresponding to that function is returned
+as the value of `magit-repolist-column-flag'."
+ :package-version '(magit . "3.0.0")
+ :group 'magit-repolist
+ :type '(alist :key-type (function :tag "Predicate Function")
+ :value-type (string :tag "Flag")))
+
+(defcustom magit-repolist-sort-key '("Path" . nil)
+ "Initial sort key for buffer created by `magit-list-repositories'.
+If nil, no additional sorting is performed. Otherwise, this
+should be a cons cell (NAME . FLIP). NAME is a string matching
+one of the column names in `magit-repolist-columns'. FLIP, if
+non-nil, means to invert the resulting sort."
+ :package-version '(magit . "3.2.0")
+ :group 'magit-repolist
+ :type '(choice (const nil)
+ (cons (string :tag "Column name")
+ (boolean :tag "Flip order"))))
+
+;;; List Repositories
+;;;; List Commands
+;;;###autoload
+(defun magit-list-repositories ()
+ "Display a list of repositories.
+
+Use the options `magit-repository-directories' to control which
+repositories are displayed."
+ (interactive)
+ (magit-repolist-setup (default-value 'magit-repolist-columns)))
+
+;;;; Mode Commands
+
+(defun magit-repolist-status (&optional _button)
+ "Show the status for the repository at point."
+ (interactive)
+ (--if-let (tabulated-list-get-id)
+ (magit-status-setup-buffer (expand-file-name it))
+ (user-error "There is no repository at point")))
+
+(defun magit-repolist-mark ()
+ "Mark a repository and move to the next line."
+ (interactive)
+ (magit-repolist--ensure-padding)
+ (tabulated-list-put-tag "*" t))
+
+(defun magit-repolist-unmark ()
+ "Unmark a repository and move to the next line."
+ (interactive)
+ (tabulated-list-put-tag " " t))
+
+(defun magit-repolist-fetch (repos)
+ "Fetch all marked or listed repositories."
+ (interactive (list (magit-repolist--get-repos ?*)))
+ (run-hooks 'magit-credential-hook)
+ (magit-repolist--mapc (apply-partially #'magit-run-git "remote" "update")
+ repos "Fetching in %s..."))
+
+(defun magit-repolist-find-file-other-frame (repos file)
+ "Find a file in all marked or listed repositories."
+ (interactive (list (magit-repolist--get-repos ?*)
+ (read-string "Find file in repositories: ")))
+ (magit-repolist--mapc (apply-partially #'find-file-other-frame file) repos))
+
+(defun magit-repolist--ensure-padding ()
+ "Set `tabulated-list-padding' to 2, unless that is already non-zero."
+ (when (zerop tabulated-list-padding)
+ (setq tabulated-list-padding 2)
+ (tabulated-list-init-header)
+ (tabulated-list-print t)))
+
+(defun magit-repolist--get-repos (&optional char)
+ "Return marked repositories or `all' if none are marked.
+If optional CHAR is non-nil, then only return repositories
+marked with that character. If no repositories are marked
+then ask whether to act on all repositories instead."
+ (or (magit-repolist--marked-repos char)
+ (if (magit-confirm 'repolist-all
+ "Nothing selected. Act on ALL displayed repositories")
+ 'all
+ (user-error "Abort"))))
+
+(defun magit-repolist--marked-repos (&optional char)
+ "Return marked repositories.
+If optional CHAR is non-nil, then only return repositories
+marked with that character."
+ (let (c list)
+ (save-excursion
+ (goto-char (point-min))
+ (while (not (eobp))
+ (setq c (char-after))
+ (unless (eq c ?\s)
+ (if char
+ (when (eq c char)
+ (push (tabulated-list-get-id) list))
+ (push (cons c (tabulated-list-get-id)) list)))
+ (forward-line)))
+ list))
+
+(defun magit-repolist--mapc (fn repos &optional msg)
+ "Apply FN to each directory in REPOS for side effects only.
+If REPOS is the symbol `all', then call FN for all displayed
+repositories. When FN is called, `default-directory' is bound to
+the top-level directory of the current repository. If optional
+MSG is non-nil then that is displayed around each call to FN.
+If it contains \"%s\" then the directory is substituted for that."
+ (when (eq repos 'all)
+ (setq repos nil)
+ (save-excursion
+ (goto-char (point-min))
+ (while (not (eobp))
+ (push (tabulated-list-get-id) repos)
+ (forward-line)))
+ (setq repos (nreverse repos)))
+ (let ((base default-directory)
+ (len (length repos))
+ (i 0))
+ (mapc (lambda (repo)
+ (let ((default-directory
+ (file-name-as-directory (expand-file-name repo base))))
+ (if msg
+ (let ((msg (concat (format "(%s/%s) " (cl-incf i) len)
+ (format msg default-directory))))
+ (message msg)
+ (funcall fn)
+ (message (concat msg "done")))
+ (funcall fn))))
+ repos)))
+
+;;;; Mode
+
+(defvar magit-repolist-mode-map
+ (let ((map (make-sparse-keymap)))
+ (set-keymap-parent map tabulated-list-mode-map)
+ (define-key map (kbd "C-m") #'magit-repolist-status)
+ (define-key map (kbd "m") #'magit-repolist-mark)
+ (define-key map (kbd "u") #'magit-repolist-unmark)
+ (define-key map (kbd "f") #'magit-repolist-fetch)
+ (define-key map (kbd "5") #'magit-repolist-find-file-other-frame)
+ map)
+ "Local keymap for Magit-Repolist mode buffers.")
+
+(define-derived-mode magit-repolist-mode tabulated-list-mode "Repos"
+ "Major mode for browsing a list of Git repositories."
+ (setq-local x-stretch-cursor nil)
+ (setq tabulated-list-padding 0)
+ (add-hook 'tabulated-list-revert-hook #'magit-repolist-refresh nil t)
+ (setq imenu-prev-index-position-function
+ #'magit-repolist--imenu-prev-index-position)
+ (setq imenu-extract-index-name-function #'tabulated-list-get-id))
+
+(defun magit-repolist-setup (columns)
+ (unless magit-repository-directories
+ (user-error "You need to customize `magit-repository-directories' %s"
+ "before you can list repositories"))
+ (with-current-buffer (get-buffer-create "*Magit Repositories*")
+ (magit-repolist-mode)
+ (setq-local magit-repolist-columns columns)
+ (magit-repolist-setup-1)
+ (magit-repolist-refresh)
+ (switch-to-buffer (current-buffer))))
+
+(defun magit-repolist-setup-1 ()
+ (unless tabulated-list-sort-key
+ (setq tabulated-list-sort-key
+ (pcase-let ((`(,column . ,flip) magit-repolist-sort-key))
+ (cons (or (car (assoc column magit-repolist-columns))
+ (caar magit-repolist-columns))
+ flip))))
+ (setq tabulated-list-format
+ (vconcat (-map-indexed
+ (lambda (idx column)
+ (pcase-let* ((`(,title ,width ,_fn ,props) column)
+ (sort-set (assoc :sort props))
+ (sort-fn (cadr sort-set)))
+ (nconc (list title width
+ (cond ((eq sort-fn '<)
+ (magit-repolist-make-sorter
+ sort-fn #'string-to-number idx))
+ ((eq sort-fn 'magit-repolist-version<)
+ (magit-repolist-make-sorter
+ sort-fn #'identity idx))
+ (sort-fn sort-fn)
+ (sort-set nil)
+ (t t)))
+ (flatten-tree props))))
+ magit-repolist-columns))))
+
+(defun magit-repolist-refresh ()
+ (setq tabulated-list-entries
+ (mapcar (pcase-lambda (`(,id . ,path))
+ (let ((default-directory path))
+ (list path
+ (vconcat
+ (mapcar (pcase-lambda (`(,title ,width ,fn ,props))
+ (or (funcall fn `((:id ,id)
+ (:title ,title)
+ (:width ,width)
+ ,@props))
+ ""))
+ magit-repolist-columns)))))
+ (magit-list-repos-uniquify
+ (--map (cons (file-name-nondirectory (directory-file-name it))
+ it)
+ (magit-list-repos)))))
+ (message "Listing repositories...")
+ (tabulated-list-init-header)
+ (tabulated-list-print t)
+ (message "Listing repositories...done"))
+
+(defun magit-repolist--imenu-prev-index-position ()
+ (and (not (bobp))
+ (forward-line -1)))
+
+;;;; Columns
+
+(defun magit-repolist-make-sorter (sort-predicate convert-cell column-idx)
+ "Return a function suitable as a sorter for tabulated lists.
+See `tabulated-list--get-sorter'. Given a more reasonable API
+this would not be necessary and one could just use SORT-PREDICATE
+directly. CONVERT-CELL can be used to turn the cell value, which
+is always a string back into e.g. a number. COLUMN-IDX has to be
+the index of the column that uses the returned sorter function."
+ (lambda (a b)
+ (funcall sort-predicate
+ (funcall convert-cell (aref (cadr a) column-idx))
+ (funcall convert-cell (aref (cadr b) column-idx)))))
+
+(defun magit-repolist-column-ident (spec)
+ "Insert the identification of the repository.
+Usually this is just its basename."
+ (cadr (assq :id spec)))
+
+(defun magit-repolist-column-path (_)
+ "Insert the absolute path of the repository."
+ (abbreviate-file-name default-directory))
+
+(defvar magit-repolist-column-version-regexp "\
+\\(?1:-\\(?2:[0-9]*\\)\
+\\(?3:-g[a-z0-9]*\\)\\)?\
+\\(?:-\\(?4:dirty\\)\\)\
+?\\'")
+
+(defvar magit-repolist-column-version-resume-regexp
+ "\\`Resume development\\'")
+
+(defun magit-repolist-column-version (_)
+ "Insert a description of the repository's `HEAD' revision."
+ (and-let* ((v (or (magit-git-string "describe" "--tags" "--dirty")
+ ;; If there are no tags, use the date in MELPA format.
+ (magit-git-string "show" "--no-patch" "--format=%cd-g%h"
+ "--date=format:%Y%m%d.%H%M"))))
+ (save-match-data
+ (when (string-match magit-repolist-column-version-regexp v)
+ (magit--put-face (match-beginning 0) (match-end 0) 'shadow v)
+ (when (match-end 2)
+ (magit--put-face (match-beginning 2) (match-end 2) 'bold v))
+ (when (match-end 4)
+ (magit--put-face (match-beginning 4) (match-end 4) 'error v))
+ (when (and (equal (match-string 2 v) "1")
+ (string-match-p magit-repolist-column-version-resume-regexp
+ (magit-rev-format "%s")))
+ (setq v (replace-match (propertize "+" 'face 'shadow) t t v 1))))
+ (if (and v (string-match "\\`[0-9]" v))
+ (concat " " v)
+ (when (and v (string-match "\\`[^0-9]+" v))
+ (magit--put-face 0 (match-end 0) 'shadow v))
+ v))))
+
+(defun magit-repolist-version< (a b)
+ (save-match-data
+ (let ((re "[0-9]+\\(\\.[0-9]*\\)*"))
+ (setq a (and (string-match re a) (match-string 0 a)))
+ (setq b (and (string-match re b) (match-string 0 b)))
+ (cond ((and a b) (version< a b))
+ (b nil)
+ (t t)))))
+
+(defun magit-repolist-column-branch (_)
+ "Insert the current branch."
+ (let ((branch (magit-get-current-branch)))
+ (if (member branch magit-main-branch-names)
+ (magit--propertize-face branch 'shadow)
+ branch)))
+
+(defun magit-repolist-column-upstream (_)
+ "Insert the upstream branch of the current branch."
+ (magit-get-upstream-branch))
+
+(defun magit-repolist-column-flag (_)
+ "Insert a flag as specified by `magit-repolist-column-flag-alist'.
+
+By default this indicates whether there are uncommitted changes.
+- N if there is at least one untracked file.
+- U if there is at least one unstaged file.
+- S if there is at least one staged file.
+Only one letter is shown, the first that applies."
+ (seq-some (pcase-lambda (`(,fun . ,flag))
+ (and (funcall fun) flag))
+ magit-repolist-column-flag-alist))
+
+(defun magit-repolist-column-flags (_)
+ "Insert all flags as specified by `magit-repolist-column-flag-alist'.
+This is an alternative to function `magit-repolist-column-flag',
+which only lists the first one found."
+ (mapconcat (pcase-lambda (`(,fun . ,flag))
+ (if (funcall fun) flag " "))
+ magit-repolist-column-flag-alist
+ ""))
+
+(defun magit-repolist-column-unpulled-from-upstream (spec)
+ "Insert number of upstream commits not in the current branch."
+ (and-let* ((br (magit-get-upstream-branch)))
+ (magit-repolist-insert-count (cadr (magit-rev-diff-count "HEAD" br)) spec)))
+
+(defun magit-repolist-column-unpulled-from-pushremote (spec)
+ "Insert number of commits in the push branch but not the current branch."
+ (and-let* ((br (magit-get-push-branch nil t)))
+ (magit-repolist-insert-count (cadr (magit-rev-diff-count "HEAD" br)) spec)))
+
+(defun magit-repolist-column-unpushed-to-upstream (spec)
+ "Insert number of commits in the current branch but not its upstream."
+ (and-let* ((br (magit-get-upstream-branch)))
+ (magit-repolist-insert-count (car (magit-rev-diff-count "HEAD" br)) spec)))
+
+(defun magit-repolist-column-unpushed-to-pushremote (spec)
+ "Insert number of commits in the current branch but not its push branch."
+ (and-let* ((br (magit-get-push-branch nil t)))
+ (magit-repolist-insert-count (car (magit-rev-diff-count "HEAD" br)) spec)))
+
+(defun magit-repolist-column-branches (spec)
+ "Insert number of branches."
+ (magit-repolist-insert-count (length (magit-list-local-branches))
+ `((:normal-count 1) ,@spec)))
+
+(defun magit-repolist-column-stashes (spec)
+ "Insert number of stashes."
+ (magit-repolist-insert-count (length (magit-list-stashes)) spec))
+
+(defun magit-repolist-insert-count (n spec)
+ (magit--propertize-face
+ (if (and (> n 9) (= (cadr (assq :width spec)) 1))
+ "+"
+ (number-to-string n))
+ (if (> n (or (cadr (assq :normal-count spec)) 0)) 'bold 'shadow)))
+
+;;; Read Repository
+
+(defun magit-read-repository (&optional read-directory-name)
+ "Read a Git repository in the minibuffer, with completion.
+
+The completion choices are the basenames of top-levels of
+repositories found in the directories specified by option
+`magit-repository-directories'. In case of name conflicts
+the basenames are prefixed with the name of the respective
+parent directories. The returned value is the actual path
+to the selected repository.
+
+If READ-DIRECTORY-NAME is non-nil or no repositories can be
+found based on the value of `magit-repository-directories',
+then read an arbitrary directory using `read-directory-name'
+instead."
+ (if-let ((repos (and (not read-directory-name)
+ magit-repository-directories
+ (magit-repos-alist))))
+ (let ((reply (magit-completing-read "Git repository" repos)))
+ (file-name-as-directory
+ (or (cdr (assoc reply repos))
+ (if (file-directory-p reply)
+ (expand-file-name reply)
+ (user-error "Not a repository or a directory: %s" reply)))))
+ (file-name-as-directory
+ (read-directory-name "Git repository: "
+ (or (magit-toplevel) default-directory)))))
+
+(defun magit-list-repos ()
+ (cl-mapcan (pcase-lambda (`(,dir . ,depth))
+ (magit-list-repos-1 dir depth))
+ magit-repository-directories))
+
+(defun magit-list-repos-1 (directory depth)
+ (cond ((file-readable-p (expand-file-name ".git" directory))
+ (list (file-name-as-directory directory)))
+ ((and (> depth 0) (magit-file-accessible-directory-p directory))
+ (--mapcat (and (file-directory-p it)
+ (magit-list-repos-1 it (1- depth)))
+ (directory-files directory t
+ directory-files-no-dot-files-regexp t)))))
+
+(defun magit-list-repos-uniquify (alist)
+ (let (result (dict (make-hash-table :test #'equal)))
+ (dolist (a (delete-dups alist))
+ (puthash (car a) (cons (cdr a) (gethash (car a) dict)) dict))
+ (maphash
+ (lambda (key value)
+ (if (length= value 1)
+ (push (cons key (car value)) result)
+ (setq result
+ (append result
+ (magit-list-repos-uniquify
+ (--map (cons (concat
+ key "\\"
+ (file-name-nondirectory
+ (directory-file-name
+ (substring it 0 (- (1+ (length key)))))))
+ it)
+ value))))))
+ dict)
+ result))
+
+(defun magit-repos-alist ()
+ (magit-list-repos-uniquify
+ (--map (cons (file-name-nondirectory (directory-file-name it)) it)
+ (magit-list-repos))))
+
+;;; _
+(provide 'magit-repos)
+;;; magit-repos.el ends here
diff --git a/elpa/magit-20220503.1245/magit-repos.elc b/elpa/magit-20220503.1245/magit-repos.elc
new file mode 100644
index 0000000..23ffed8
--- /dev/null
+++ b/elpa/magit-20220503.1245/magit-repos.elc
Binary files differ
diff --git a/elpa/magit-20220503.1245/magit-reset.el b/elpa/magit-20220503.1245/magit-reset.el
new file mode 100644
index 0000000..75f2f47
--- /dev/null
+++ b/elpa/magit-20220503.1245/magit-reset.el
@@ -0,0 +1,134 @@
+;;; magit-reset.el --- Reset fuctionality -*- lexical-binding:t -*-
+
+;; Copyright (C) 2008-2022 The Magit Project Contributors
+
+;; Author: Jonas Bernoulli <jonas@bernoul.li>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+
+;; SPDX-License-Identifier: GPL-3.0-or-later
+
+;; Magit 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.
+;;
+;; Magit 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 Magit. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This library implements reset commands.
+
+;;; Code:
+
+(require 'magit)
+
+;;;###autoload (autoload 'magit-reset "magit" nil t)
+(transient-define-prefix magit-reset ()
+ "Reset the `HEAD', index and/or worktree to a previous state."
+ :man-page "git-reset"
+ ["Reset"
+ ("m" "mixed (HEAD and index)" magit-reset-mixed)
+ ("s" "soft (HEAD only)" magit-reset-soft)
+ ("h" "hard (HEAD, index and files)" magit-reset-hard)
+ ("k" "keep (HEAD and index, keeping uncommitted)" magit-reset-keep)
+ ("i" "index (only)" magit-reset-index)
+ ("w" "worktree (only)" magit-reset-worktree)
+ ""
+ ("f" "a file" magit-file-checkout)])
+
+;;;###autoload
+(defun magit-reset-mixed (commit)
+ "Reset the `HEAD' and index to COMMIT, but not the working tree.
+\n(git reset --mixed COMMIT)"
+ (interactive (list (magit-reset-read-branch-or-commit "Reset %s to")))
+ (magit-reset-internal "--mixed" commit))
+
+;;;###autoload
+(defun magit-reset-soft (commit)
+ "Reset the `HEAD' to COMMIT, but not the index and working tree.
+\n(git reset --soft REVISION)"
+ (interactive (list (magit-reset-read-branch-or-commit "Soft reset %s to")))
+ (magit-reset-internal "--soft" commit))
+
+;;;###autoload
+(defun magit-reset-hard (commit)
+ "Reset the `HEAD', index, and working tree to COMMIT.
+\n(git reset --hard REVISION)"
+ (interactive (list (magit-reset-read-branch-or-commit
+ (concat (magit--propertize-face "Hard" 'bold)
+ " reset %s to"))))
+ (magit-reset-internal "--hard" commit))
+
+;;;###autoload
+(defun magit-reset-keep (commit)
+ "Reset the `HEAD' and index to COMMIT, while keeping uncommitted changes.
+\n(git reset --keep REVISION)"
+ (interactive (list (magit-reset-read-branch-or-commit "Reset %s to")))
+ (magit-reset-internal "--keep" commit))
+
+;;;###autoload
+(defun magit-reset-index (commit)
+ "Reset the index to COMMIT.
+Keep the `HEAD' and working tree as-is, so if COMMIT refers to the
+head this effectively unstages all changes.
+\n(git reset COMMIT .)"
+ (interactive (list (magit-read-branch-or-commit "Reset index to")))
+ (magit-reset-internal nil commit "."))
+
+;;;###autoload
+(defun magit-reset-worktree (commit)
+ "Reset the worktree to COMMIT.
+Keep the `HEAD' and index as-is."
+ (interactive (list (magit-read-branch-or-commit "Reset worktree to")))
+ (magit-wip-commit-before-change nil " before reset")
+ (magit-with-temp-index commit nil
+ (magit-call-git "checkout-index" "--all" "--force"))
+ (magit-wip-commit-after-apply nil " after reset")
+ (magit-refresh))
+
+;;;###autoload
+(defun magit-reset-quickly (commit &optional hard)
+ "Reset the `HEAD' and index to COMMIT, and possibly the working tree.
+With a prefix argument reset the working tree otherwise don't.
+\n(git reset --mixed|--hard COMMIT)"
+ (interactive (list (magit-reset-read-branch-or-commit
+ (if current-prefix-arg
+ (concat (magit--propertize-face "Hard" 'bold)
+ " reset %s to")
+ "Reset %s to"))
+ current-prefix-arg))
+ (magit-reset-internal (if hard "--hard" "--mixed") commit))
+
+(defun magit-reset-read-branch-or-commit (prompt)
+ "Prompt for and return a ref to reset HEAD to.
+
+PROMPT is a format string, where either the current branch name
+or \"detached head\" will be substituted for %s."
+ (magit-read-branch-or-commit
+ (format prompt (or (magit-get-current-branch) "detached head"))))
+
+(defun magit-reset-internal (arg commit &optional path)
+ (when (and (not (member arg '("--hard" nil)))
+ (equal (magit-rev-parse commit)
+ (magit-rev-parse "HEAD~")))
+ (with-temp-buffer
+ (magit-git-insert "show" "-s" "--format=%B" "HEAD")
+ (when git-commit-major-mode
+ (funcall git-commit-major-mode))
+ (git-commit-setup-font-lock)
+ (git-commit-save-message)))
+ (let ((cmd (if (and (equal commit "HEAD") (not arg)) "unstage" "reset")))
+ (magit-wip-commit-before-change nil (concat " before " cmd))
+ (magit-run-git "reset" arg commit "--" path)
+ (when (equal cmd "unstage")
+ (magit-wip-commit-after-apply nil " after unstage"))))
+
+;;; _
+(provide 'magit-reset)
+;;; magit-reset.el ends here
diff --git a/elpa/magit-20220503.1245/magit-reset.elc b/elpa/magit-20220503.1245/magit-reset.elc
new file mode 100644
index 0000000..b49d531
--- /dev/null
+++ b/elpa/magit-20220503.1245/magit-reset.elc
Binary files differ
diff --git a/elpa/magit-20220503.1245/magit-sequence.el b/elpa/magit-20220503.1245/magit-sequence.el
new file mode 100644
index 0000000..87cb072
--- /dev/null
+++ b/elpa/magit-20220503.1245/magit-sequence.el
@@ -0,0 +1,1087 @@
+;;; magit-sequence.el --- History manipulation in Magit -*- lexical-binding:t -*-
+
+;; Copyright (C) 2008-2022 The Magit Project Contributors
+
+;; Author: Jonas Bernoulli <jonas@bernoul.li>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+
+;; SPDX-License-Identifier: GPL-3.0-or-later
+
+;; Magit 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.
+;;
+;; Magit 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 Magit. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Support for Git commands that replay commits and help the user make
+;; changes along the way. Supports `cherry-pick', `revert', `rebase',
+;; `rebase--interactive' and `am'.
+
+;;; Code:
+
+(require 'magit)
+
+;; For `magit-rebase--todo'.
+(declare-function git-rebase-current-line "git-rebase" ())
+(eval-when-compile
+ (cl-pushnew 'action-type eieio--known-slot-names)
+ (cl-pushnew 'action eieio--known-slot-names)
+ (cl-pushnew 'action-options eieio--known-slot-names)
+ (cl-pushnew 'target eieio--known-slot-names))
+
+;;; Options
+;;;; Faces
+
+(defface magit-sequence-pick
+ '((t :inherit default))
+ "Face used in sequence sections."
+ :group 'magit-faces)
+
+(defface magit-sequence-stop
+ '((((class color) (background light)) :foreground "DarkOliveGreen4")
+ (((class color) (background dark)) :foreground "DarkSeaGreen2"))
+ "Face used in sequence sections."
+ :group 'magit-faces)
+
+(defface magit-sequence-part
+ '((((class color) (background light)) :foreground "Goldenrod4")
+ (((class color) (background dark)) :foreground "LightGoldenrod2"))
+ "Face used in sequence sections."
+ :group 'magit-faces)
+
+(defface magit-sequence-head
+ '((((class color) (background light)) :foreground "SkyBlue4")
+ (((class color) (background dark)) :foreground "LightSkyBlue1"))
+ "Face used in sequence sections."
+ :group 'magit-faces)
+
+(defface magit-sequence-drop
+ '((((class color) (background light)) :foreground "IndianRed")
+ (((class color) (background dark)) :foreground "IndianRed"))
+ "Face used in sequence sections."
+ :group 'magit-faces)
+
+(defface magit-sequence-done
+ '((t :inherit magit-hash))
+ "Face used in sequence sections."
+ :group 'magit-faces)
+
+(defface magit-sequence-onto
+ '((t :inherit magit-sequence-done))
+ "Face used in sequence sections."
+ :group 'magit-faces)
+
+(defface magit-sequence-exec
+ '((t :inherit magit-hash))
+ "Face used in sequence sections."
+ :group 'magit-faces)
+
+;;; Common
+
+;;;###autoload
+(defun magit-sequencer-continue ()
+ "Resume the current cherry-pick or revert sequence."
+ (interactive)
+ (if (magit-sequencer-in-progress-p)
+ (if (magit-anything-unmerged-p)
+ (user-error "Cannot continue due to unresolved conflicts")
+ (magit-run-git-sequencer
+ (if (magit-revert-in-progress-p) "revert" "cherry-pick") "--continue"))
+ (user-error "No cherry-pick or revert in progress")))
+
+;;;###autoload
+(defun magit-sequencer-skip ()
+ "Skip the stopped at commit during a cherry-pick or revert sequence."
+ (interactive)
+ (if (magit-sequencer-in-progress-p)
+ (progn (magit-call-git "reset" "--hard")
+ (magit-sequencer-continue))
+ (user-error "No cherry-pick or revert in progress")))
+
+;;;###autoload
+(defun magit-sequencer-abort ()
+ "Abort the current cherry-pick or revert sequence.
+This discards all changes made since the sequence started."
+ (interactive)
+ (if (magit-sequencer-in-progress-p)
+ (magit-run-git-sequencer
+ (if (magit-revert-in-progress-p) "revert" "cherry-pick") "--abort")
+ (user-error "No cherry-pick or revert in progress")))
+
+(defun magit-sequencer-in-progress-p ()
+ (or (magit-cherry-pick-in-progress-p)
+ (magit-revert-in-progress-p)))
+
+;;; Cherry-Pick
+
+(defvar magit-perl-executable "perl"
+ "The Perl executable.")
+
+;;;###autoload (autoload 'magit-cherry-pick "magit-sequence" nil t)
+(transient-define-prefix magit-cherry-pick ()
+ "Apply or transplant commits."
+ :man-page "git-cherry-pick"
+ :value '("--ff")
+ :incompatible '(("--ff" "-x"))
+ ["Arguments"
+ :if-not magit-sequencer-in-progress-p
+ (magit-cherry-pick:--mainline)
+ ("=s" magit-merge:--strategy)
+ ("-F" "Attempt fast-forward" "--ff")
+ ("-x" "Reference cherry in commit message" "-x")
+ ("-e" "Edit commit messages" ("-e" "--edit"))
+ ("-s" "Add Signed-off-by lines" ("-s" "--signoff"))
+ (5 magit:--gpg-sign)]
+ [:if-not magit-sequencer-in-progress-p
+ ["Apply here"
+ ("A" "Pick" magit-cherry-copy)
+ ("a" "Apply" magit-cherry-apply)
+ ("h" "Harvest" magit-cherry-harvest)
+ ("m" "Squash" magit-merge-squash)]
+ ["Apply elsewhere"
+ ("d" "Donate" magit-cherry-donate)
+ ("n" "Spinout" magit-cherry-spinout)
+ ("s" "Spinoff" magit-cherry-spinoff)]]
+ ["Actions"
+ :if magit-sequencer-in-progress-p
+ ("A" "Continue" magit-sequencer-continue)
+ ("s" "Skip" magit-sequencer-skip)
+ ("a" "Abort" magit-sequencer-abort)])
+
+(transient-define-argument magit-cherry-pick:--mainline ()
+ :description "Replay merge relative to parent"
+ :class 'transient-option
+ :shortarg "-m"
+ :argument "--mainline="
+ :reader #'transient-read-number-N+)
+
+(defun magit-cherry-pick-read-args (prompt)
+ (list (or (nreverse (magit-region-values 'commit))
+ (magit-read-other-branch-or-commit prompt))
+ (transient-args 'magit-cherry-pick)))
+
+(defun magit--cherry-move-read-args (verb away fn &optional allow-detached)
+ (declare (indent defun))
+ (let ((commits (or (nreverse (magit-region-values 'commit))
+ (list (funcall (if away
+ #'magit-read-branch-or-commit
+ #'magit-read-other-branch-or-commit)
+ (format "%s cherry" (capitalize verb))))))
+ (current (or (magit-get-current-branch)
+ (and allow-detached (magit-rev-parse "HEAD")))))
+ (unless current
+ (user-error "Cannot %s cherries while HEAD is detached" verb))
+ (let ((reachable (magit-rev-ancestor-p (car commits) current))
+ (msg "Cannot %s cherries that %s reachable from HEAD"))
+ (pcase (list away reachable)
+ ('(nil t) (user-error msg verb "are"))
+ ('(t nil) (user-error msg verb "are not"))))
+ `(,commits
+ ,@(funcall fn commits)
+ ,(transient-args 'magit-cherry-pick))))
+
+(defun magit--cherry-spinoff-read-args (verb)
+ (magit--cherry-move-read-args verb t
+ (lambda (commits)
+ (magit-branch-read-args
+ (format "Create branch from %s cherries" (length commits))
+ (magit-get-upstream-branch)))))
+
+;;;###autoload
+(defun magit-cherry-copy (commits &optional args)
+ "Copy COMMITS from another branch onto the current branch.
+Prompt for a commit, defaulting to the commit at point. If
+the region selects multiple commits, then pick all of them,
+without prompting."
+ (interactive (magit-cherry-pick-read-args "Cherry-pick"))
+ (magit--cherry-pick commits args))
+
+;;;###autoload
+(defun magit-cherry-apply (commits &optional args)
+ "Apply the changes in COMMITS but do not commit them.
+Prompt for a commit, defaulting to the commit at point. If
+the region selects multiple commits, then apply all of them,
+without prompting."
+ (interactive (magit-cherry-pick-read-args "Apply changes from commit"))
+ (magit--cherry-pick commits (cons "--no-commit" (remove "--ff" args))))
+
+;;;###autoload
+(defun magit-cherry-harvest (commits branch &optional args)
+ "Move COMMITS from another BRANCH onto the current branch.
+Remove the COMMITS from BRANCH and stay on the current branch.
+If a conflict occurs, then you have to fix that and finish the
+process manually."
+ (interactive
+ (magit--cherry-move-read-args "harvest" nil
+ (lambda (commits)
+ (list (let ((branches (magit-list-containing-branches (car commits))))
+ (pcase (length branches)
+ (0 nil)
+ (1 (car branches))
+ (_ (magit-completing-read
+ (let ((len (length commits)))
+ (if (= len 1)
+ "Remove 1 cherry from branch"
+ (format "Remove %s cherries from branch" len)))
+ branches nil t))))))))
+ (magit--cherry-move commits branch (magit-get-current-branch) args nil t))
+
+;;;###autoload
+(defun magit-cherry-donate (commits branch &optional args)
+ "Move COMMITS from the current branch onto another existing BRANCH.
+Remove COMMITS from the current branch and stay on that branch.
+If a conflict occurs, then you have to fix that and finish the
+process manually. `HEAD' is allowed to be detached initially."
+ (interactive
+ (magit--cherry-move-read-args "donate" t
+ (lambda (commits)
+ (list (magit-read-other-branch
+ (let ((len (length commits)))
+ (if (= len 1)
+ "Move 1 cherry to branch"
+ (format "Move %s cherries to branch" len))))))
+ 'allow-detached))
+ (magit--cherry-move commits
+ (or (magit-get-current-branch)
+ (magit-rev-parse "HEAD"))
+ branch args))
+
+;;;###autoload
+(defun magit-cherry-spinout (commits branch start-point &optional args)
+ "Move COMMITS from the current branch onto a new BRANCH.
+Remove COMMITS from the current branch and stay on that branch.
+If a conflict occurs, then you have to fix that and finish the
+process manually."
+ (interactive (magit--cherry-spinoff-read-args "spinout"))
+ (magit--cherry-move commits (magit-get-current-branch) branch args
+ start-point))
+
+;;;###autoload
+(defun magit-cherry-spinoff (commits branch start-point &optional args)
+ "Move COMMITS from the current branch onto a new BRANCH.
+Remove COMMITS from the current branch and checkout BRANCH.
+If a conflict occurs, then you have to fix that and finish
+the process manually."
+ (interactive (magit--cherry-spinoff-read-args "spinoff"))
+ (magit--cherry-move commits (magit-get-current-branch) branch args
+ start-point t))
+
+(defun magit--cherry-move (commits src dst args
+ &optional start-point checkout-dst)
+ (let ((current (magit-get-current-branch)))
+ (unless (magit-branch-p dst)
+ (let ((magit-process-raise-error t))
+ (magit-call-git "branch" dst start-point))
+ (--when-let (magit-get-indirect-upstream-branch start-point)
+ (magit-call-git "branch" "--set-upstream-to" it dst)))
+ (unless (equal dst current)
+ (let ((magit-process-raise-error t))
+ (magit-call-git "checkout" dst)))
+ (if (not src) ; harvest only
+ (magit--cherry-pick commits args)
+ (let ((tip (car (last commits)))
+ (keep (concat (car commits) "^")))
+ (magit--cherry-pick commits args)
+ (set-process-sentinel
+ magit-this-process
+ (lambda (process event)
+ (when (memq (process-status process) '(exit signal))
+ (if (> (process-exit-status process) 0)
+ (magit-process-sentinel process event)
+ (process-put process 'inhibit-refresh t)
+ (magit-process-sentinel process event)
+ (cond
+ ((magit-rev-equal tip src)
+ (magit-call-git "update-ref"
+ "-m" (format "reset: moving to %s" keep)
+ (magit-ref-fullname src)
+ keep tip)
+ (if (not checkout-dst)
+ (magit-run-git "checkout" src)
+ (magit-refresh)))
+ (t
+ (magit-git "checkout" src)
+ (with-environment-variables
+ (("GIT_SEQUENCE_EDITOR"
+ (format "%s -i -ne '/^pick (%s)/ or print'"
+ magit-perl-executable
+ (mapconcat #'magit-rev-abbrev commits "|"))))
+ (magit-run-git-sequencer "rebase" "-i" keep))
+ (when checkout-dst
+ (set-process-sentinel
+ magit-this-process
+ (lambda (process event)
+ (when (memq (process-status process) '(exit signal))
+ (if (> (process-exit-status process) 0)
+ (magit-process-sentinel process event)
+ (process-put process 'inhibit-refresh t)
+ (magit-process-sentinel process event)
+ (magit-run-git "checkout" dst))))))))))))))))
+
+(defun magit--cherry-pick (commits args &optional revert)
+ (let ((command (if revert "revert" "cherry-pick")))
+ (when (stringp commits)
+ (setq commits (if (string-search ".." commits)
+ (split-string commits "\\.\\.")
+ (list commits))))
+ (magit-run-git-sequencer
+ (if revert "revert" "cherry-pick")
+ (pcase-let ((`(,merge ,non-merge)
+ (-separate #'magit-merge-commit-p commits)))
+ (cond
+ ((not merge)
+ (--remove (string-prefix-p "--mainline=" it) args))
+ (non-merge
+ (user-error "Cannot %s merge and non-merge commits at once"
+ command))
+ ((--first (string-prefix-p "--mainline=" it) args)
+ args)
+ (t
+ (cons (format "--mainline=%s"
+ (read-number "Replay merges relative to parent: "))
+ args))))
+ commits)))
+
+(defun magit-cherry-pick-in-progress-p ()
+ ;; .git/sequencer/todo does not exist when there is only one commit left.
+ (or (file-exists-p (magit-git-dir "CHERRY_PICK_HEAD"))
+ ;; And CHERRY_PICK_HEAD does not exist when a conflict happens
+ ;; while picking a series of commits with --no-commit.
+ (when-let ((line (magit-file-line (magit-git-dir "sequencer/todo"))))
+ (string-prefix-p "pick" line))))
+
+;;; Revert
+
+;;;###autoload (autoload 'magit-revert "magit-sequence" nil t)
+(transient-define-prefix magit-revert ()
+ "Revert existing commits, with or without creating new commits."
+ :man-page "git-revert"
+ :value '("--edit")
+ ["Arguments"
+ :if-not magit-sequencer-in-progress-p
+ (magit-cherry-pick:--mainline)
+ ("-e" "Edit commit message" ("-e" "--edit"))
+ ("-E" "Don't edit commit message" "--no-edit")
+ ("=s" magit-merge:--strategy)
+ ("-s" "Add Signed-off-by lines" ("-s" "--signoff"))
+ (5 magit:--gpg-sign)]
+ ["Actions"
+ :if-not magit-sequencer-in-progress-p
+ ("V" "Revert commit(s)" magit-revert-and-commit)
+ ("v" "Revert changes" magit-revert-no-commit)]
+ ["Actions"
+ :if magit-sequencer-in-progress-p
+ ("V" "Continue" magit-sequencer-continue)
+ ("s" "Skip" magit-sequencer-skip)
+ ("a" "Abort" magit-sequencer-abort)])
+
+(defun magit-revert-read-args (prompt)
+ (list (or (magit-region-values 'commit)
+ (magit-read-branch-or-commit prompt))
+ (transient-args 'magit-revert)))
+
+;;;###autoload
+(defun magit-revert-and-commit (commit &optional args)
+ "Revert COMMIT by creating a new commit.
+Prompt for a commit, defaulting to the commit at point. If
+the region selects multiple commits, then revert all of them,
+without prompting."
+ (interactive (magit-revert-read-args "Revert commit"))
+ (magit--cherry-pick commit args t))
+
+;;;###autoload
+(defun magit-revert-no-commit (commit &optional args)
+ "Revert COMMIT by applying it in reverse to the worktree.
+Prompt for a commit, defaulting to the commit at point. If
+the region selects multiple commits, then revert all of them,
+without prompting."
+ (interactive (magit-revert-read-args "Revert changes"))
+ (magit--cherry-pick commit (cons "--no-commit" args) t))
+
+(defun magit-revert-in-progress-p ()
+ ;; .git/sequencer/todo does not exist when there is only one commit left.
+ (or (file-exists-p (magit-git-dir "REVERT_HEAD"))
+ ;; And REVERT_HEAD does not exist when a conflict happens while
+ ;; reverting a series of commits with --no-commit.
+ (when-let ((line (magit-file-line (magit-git-dir "sequencer/todo"))))
+ (string-prefix-p "revert" line))))
+
+;;; Patch
+
+;;;###autoload (autoload 'magit-am "magit-sequence" nil t)
+(transient-define-prefix magit-am ()
+ "Apply patches received by email."
+ :man-page "git-am"
+ :value '("--3way")
+ ["Arguments"
+ :if-not magit-am-in-progress-p
+ ("-3" "Fall back on 3way merge" ("-3" "--3way"))
+ (magit-apply:-p)
+ ("-c" "Remove text before scissors line" ("-c" "--scissors"))
+ ("-k" "Inhibit removal of email cruft" ("-k" "--keep"))
+ ("-b" "Limit removal of email cruft" "--keep-non-patch")
+ ("-d" "Use author date as committer date" "--committer-date-is-author-date")
+ ("-t" "Use current time as author date" "--ignore-date")
+ ("-s" "Add Signed-off-by lines" ("-s" "--signoff"))
+ (5 magit:--gpg-sign)]
+ ["Apply"
+ :if-not magit-am-in-progress-p
+ ("m" "maildir" magit-am-apply-maildir)
+ ("w" "patches" magit-am-apply-patches)
+ ("a" "plain patch" magit-patch-apply)]
+ ["Actions"
+ :if magit-am-in-progress-p
+ ("w" "Continue" magit-am-continue)
+ ("s" "Skip" magit-am-skip)
+ ("a" "Abort" magit-am-abort)])
+
+(defun magit-am-arguments ()
+ (transient-args 'magit-am))
+
+(transient-define-argument magit-apply:-p ()
+ :description "Remove leading slashes from paths"
+ :class 'transient-option
+ :argument "-p"
+ :allow-empty t
+ :reader #'transient-read-number-N+)
+
+;;;###autoload
+(defun magit-am-apply-patches (&optional files args)
+ "Apply the patches FILES."
+ (interactive (list (or (magit-region-values 'file)
+ (list (let ((default (magit-file-at-point)))
+ (read-file-name
+ (if default
+ (format "Apply patch (%s): " default)
+ "Apply patch: ")
+ nil default))))
+ (magit-am-arguments)))
+ (magit-run-git-sequencer "am" args "--"
+ (--map (magit-convert-filename-for-git
+ (expand-file-name it))
+ files)))
+
+;;;###autoload
+(defun magit-am-apply-maildir (&optional maildir args)
+ "Apply the patches from MAILDIR."
+ (interactive (list (read-file-name "Apply mbox or Maildir: ")
+ (magit-am-arguments)))
+ (magit-run-git-sequencer "am" args (magit-convert-filename-for-git
+ (expand-file-name maildir))))
+
+;;;###autoload
+(defun magit-am-continue ()
+ "Resume the current patch applying sequence."
+ (interactive)
+ (if (magit-am-in-progress-p)
+ (if (magit-anything-unstaged-p t)
+ (error "Cannot continue due to unstaged changes")
+ (magit-run-git-sequencer "am" "--continue"))
+ (user-error "Not applying any patches")))
+
+;;;###autoload
+(defun magit-am-skip ()
+ "Skip the stopped at patch during a patch applying sequence."
+ (interactive)
+ (if (magit-am-in-progress-p)
+ (magit-run-git-sequencer "am" "--skip")
+ (user-error "Not applying any patches")))
+
+;;;###autoload
+(defun magit-am-abort ()
+ "Abort the current patch applying sequence.
+This discards all changes made since the sequence started."
+ (interactive)
+ (if (magit-am-in-progress-p)
+ (magit-run-git "am" "--abort")
+ (user-error "Not applying any patches")))
+
+(defun magit-am-in-progress-p ()
+ (file-exists-p (magit-git-dir "rebase-apply/applying")))
+
+;;; Rebase
+
+;;;###autoload (autoload 'magit-rebase "magit-sequence" nil t)
+(transient-define-prefix magit-rebase ()
+ "Transplant commits and/or modify existing commits."
+ :man-page "git-rebase"
+ :value '("--autostash")
+ ["Arguments"
+ :if-not magit-rebase-in-progress-p
+ ("-k" "Keep empty commits" "--keep-empty")
+ ("-p" "Preserve merges" ("-p" "--preserve-merges")
+ :if (lambda () (magit-git-version< "2.33.0")))
+ ("-r" "Rebase merges" ("-r" "--rebase-merges=")
+ magit-rebase-merges-select-mode
+ :if (lambda () (magit-git-version>= "2.18.0")))
+ (7 magit-merge:--strategy)
+ (7 magit-merge:--strategy-option)
+ (7 "=X" magit-diff:--diff-algorithm :argument "-Xdiff-algorithm=")
+ (7 "-f" "Force rebase" ("-f" "--force-rebase"))
+ ("-d" "Use author date as committer date" "--committer-date-is-author-date")
+ ("-t" "Use current time as author date" "--ignore-date")
+ ("-a" "Autosquash" "--autosquash")
+ ("-A" "Autostash" "--autostash")
+ ("-i" "Interactive" ("-i" "--interactive"))
+ ("-h" "Disable hooks" "--no-verify")
+ (7 magit-rebase:--exec)
+ (5 magit:--gpg-sign)]
+ [:if-not magit-rebase-in-progress-p
+ :description (lambda ()
+ (format (propertize "Rebase %s onto" 'face 'transient-heading)
+ (propertize (or (magit-get-current-branch) "HEAD")
+ 'face 'magit-branch-local)))
+ ("p" magit-rebase-onto-pushremote)
+ ("u" magit-rebase-onto-upstream)
+ ("e" "elsewhere" magit-rebase-branch)]
+ ["Rebase"
+ :if-not magit-rebase-in-progress-p
+ [("i" "interactively" magit-rebase-interactive)
+ ("s" "a subset" magit-rebase-subset)]
+ [("m" "to modify a commit" magit-rebase-edit-commit)
+ ("w" "to reword a commit" magit-rebase-reword-commit)
+ ("k" "to remove a commit" magit-rebase-remove-commit)
+ ("f" "to autosquash" magit-rebase-autosquash)
+ (6 "t" "to change dates" magit-reshelve-since)]]
+ ["Actions"
+ :if magit-rebase-in-progress-p
+ ("r" "Continue" magit-rebase-continue)
+ ("s" "Skip" magit-rebase-skip)
+ ("e" "Edit" magit-rebase-edit)
+ ("a" "Abort" magit-rebase-abort)])
+
+(transient-define-argument magit-rebase:--exec ()
+ :description "Run command after commits"
+ :class 'transient-option
+ :shortarg "-x"
+ :argument "--exec="
+ :reader #'read-shell-command)
+
+(defun magit-rebase-merges-select-mode (&rest _ignore)
+ (magit-read-char-case nil t
+ (?n "[n]o-rebase-cousins" "no-rebase-cousins")
+ (?r "[r]ebase-cousins" "rebase-cousins")))
+
+(defun magit-rebase-arguments ()
+ (transient-args 'magit-rebase))
+
+(defun magit-git-rebase (target args)
+ (magit-run-git-sequencer "rebase" args target))
+
+;;;###autoload (autoload 'magit-rebase-onto-pushremote "magit-sequence" nil t)
+(transient-define-suffix magit-rebase-onto-pushremote (args)
+ "Rebase the current branch onto its push-remote branch.
+
+With a prefix argument or when the push-remote is either not
+configured or unusable, then let the user first configure the
+push-remote."
+ :if #'magit-get-current-branch
+ :description #'magit-pull--pushbranch-description
+ (interactive (list (magit-rebase-arguments)))
+ (pcase-let ((`(,branch ,remote)
+ (magit--select-push-remote "rebase onto that")))
+ (magit-git-rebase (concat remote "/" branch) args)))
+
+;;;###autoload (autoload 'magit-rebase-onto-upstream "magit-sequence" nil t)
+(transient-define-suffix magit-rebase-onto-upstream (args)
+ "Rebase the current branch onto its upstream branch.
+
+With a prefix argument or when the upstream is either not
+configured or unusable, then let the user first configure
+the upstream."
+ :if #'magit-get-current-branch
+ :description #'magit-rebase--upstream-description
+ (interactive (list (magit-rebase-arguments)))
+ (let* ((branch (or (magit-get-current-branch)
+ (user-error "No branch is checked out")))
+ (upstream (magit-get-upstream-branch branch)))
+ (when (or current-prefix-arg (not upstream))
+ (setq upstream
+ (magit-read-upstream-branch
+ branch (format "Set upstream of %s and rebase onto that" branch)))
+ (magit-set-upstream-branch branch upstream))
+ (magit-git-rebase upstream args)))
+
+(defun magit-rebase--upstream-description ()
+ (and-let* ((branch (magit-get-current-branch)))
+ (or (magit-get-upstream-branch branch)
+ (let ((remote (magit-get "branch" branch "remote"))
+ (merge (magit-get "branch" branch "merge"))
+ (u (magit--propertize-face "@{upstream}" 'bold)))
+ (cond
+ ((magit--unnamed-upstream-p remote merge)
+ (concat u ", replacing unnamed"))
+ ((magit--valid-upstream-p remote merge)
+ (concat u ", replacing non-existent"))
+ ((or remote merge)
+ (concat u ", replacing invalid"))
+ (t
+ (concat u ", setting that")))))))
+
+;;;###autoload
+(defun magit-rebase-branch (target args)
+ "Rebase the current branch onto a branch read in the minibuffer.
+All commits that are reachable from `HEAD' but not from the
+selected branch TARGET are being rebased."
+ (interactive (list (magit-read-other-branch-or-commit "Rebase onto")
+ (magit-rebase-arguments)))
+ (message "Rebasing...")
+ (magit-git-rebase target args)
+ (message "Rebasing...done"))
+
+;;;###autoload
+(defun magit-rebase-subset (newbase start args)
+ "Rebase a subset of the current branch's history onto a new base.
+Rebase commits from START to `HEAD' onto NEWBASE.
+START has to be selected from a list of recent commits."
+ (interactive (list (magit-read-other-branch-or-commit
+ "Rebase subset onto" nil
+ (magit-get-upstream-branch))
+ nil
+ (magit-rebase-arguments)))
+ (if start
+ (progn (message "Rebasing...")
+ (magit-run-git-sequencer "rebase" "--onto" newbase start args)
+ (message "Rebasing...done"))
+ (magit-log-select
+ `(lambda (commit)
+ (magit-rebase-subset ,newbase (concat commit "^") (list ,@args)))
+ (concat "Type %p on a commit to rebase it "
+ "and commits above it onto " newbase ","))))
+
+(defvar magit-rebase-interactive-include-selected t)
+
+(defun magit-rebase-interactive-1
+ (commit args message &optional editor delay-edit-confirm noassert confirm)
+ (declare (indent 2))
+ (when commit
+ (if (eq commit :merge-base)
+ (setq commit (--if-let (magit-get-upstream-branch)
+ (magit-git-string "merge-base" it "HEAD")
+ nil))
+ (unless (magit-rev-ancestor-p commit "HEAD")
+ (user-error "%s isn't an ancestor of HEAD" commit))
+ (if (magit-commit-parents commit)
+ (when (or (not (eq this-command 'magit-rebase-interactive))
+ magit-rebase-interactive-include-selected)
+ (setq commit (concat commit "^")))
+ (setq args (cons "--root" args)))))
+ (when (and commit (not noassert))
+ (setq commit (magit-rebase-interactive-assert
+ commit delay-edit-confirm
+ (--some (string-prefix-p "--rebase-merges" it) args))))
+ (if (and commit (not confirm))
+ (let ((process-environment process-environment))
+ (when editor
+ (push (concat "GIT_SEQUENCE_EDITOR="
+ (if (functionp editor)
+ (funcall editor commit)
+ editor))
+ process-environment))
+ (magit-run-git-sequencer "rebase" "-i" args
+ (unless (member "--root" args) commit)))
+ (magit-log-select
+ `(lambda (commit)
+ ;; In some cases (currently just magit-rebase-remove-commit), "-c
+ ;; commentChar=#" is added to the global arguments for git. Ensure
+ ;; that the same happens when we chose the commit via
+ ;; magit-log-select, below.
+ (let ((magit-git-global-arguments (list ,@magit-git-global-arguments)))
+ (magit-rebase-interactive-1 commit (list ,@args)
+ ,message ,editor ,delay-edit-confirm ,noassert)))
+ message)))
+
+(defvar magit--rebase-published-symbol nil)
+(defvar magit--rebase-public-edit-confirmed nil)
+
+(defun magit-rebase-interactive-assert
+ (since &optional delay-edit-confirm rebase-merges)
+ (let* ((commit (magit-rebase--target-commit since))
+ (branches (magit-list-publishing-branches commit)))
+ (setq magit--rebase-public-edit-confirmed
+ (delete (magit-toplevel) magit--rebase-public-edit-confirmed))
+ (when (and branches
+ (or (not delay-edit-confirm)
+ ;; The user might have stopped at a published commit
+ ;; merely to add new commits *after* it. Try not to
+ ;; ask users whether they really want to edit public
+ ;; commits, when they don't actually intend to do so.
+ (not (--all-p (magit-rev-equal it commit) branches))))
+ (let ((m1 "Some of these commits have already been published to ")
+ (m2 ".\nDo you really want to modify them"))
+ (magit-confirm (or magit--rebase-published-symbol 'rebase-published)
+ (concat m1 "%s" m2)
+ (concat m1 "%i public branches" m2)
+ nil branches))
+ (push (magit-toplevel) magit--rebase-public-edit-confirmed)))
+ (if (and (magit-git-lines "rev-list" "--merges" (concat since "..HEAD"))
+ (not rebase-merges))
+ (magit-read-char-case "Proceed despite merge in rebase range? " nil
+ (?c "[c]ontinue" since)
+ (?s "[s]elect other" nil)
+ (?a "[a]bort" (user-error "Quit")))
+ since))
+
+(defun magit-rebase--target-commit (since)
+ (if (string-suffix-p "^" since)
+ ;; If SINCE is "REV^", then the user selected
+ ;; "REV", which is the first commit that will
+ ;; be replaced. (from^..to] <=> [from..to]
+ (substring since 0 -1)
+ ;; The "--root" argument is being used.
+ since))
+
+;;;###autoload
+(defun magit-rebase-interactive (commit args)
+ "Start an interactive rebase sequence."
+ (interactive (list (magit-commit-at-point)
+ (magit-rebase-arguments)))
+ (magit-rebase-interactive-1 commit args
+ "Type %p on a commit to rebase it and all commits above it,"
+ nil t))
+
+;;;###autoload
+(defun magit-rebase-autosquash (args)
+ "Combine squash and fixup commits with their intended targets."
+ (interactive (list (magit-rebase-arguments)))
+ (magit-rebase-interactive-1 :merge-base
+ (nconc (list "--autosquash" "--keep-empty") args)
+ "Type %p on a commit to squash into it and then rebase as necessary,"
+ "true" nil t))
+
+;;;###autoload
+(defun magit-rebase-edit-commit (commit args)
+ "Edit a single older commit using rebase."
+ (interactive (list (magit-commit-at-point)
+ (magit-rebase-arguments)))
+ (magit-rebase-interactive-1 commit args
+ "Type %p on a commit to edit it,"
+ (apply-partially #'magit-rebase--perl-editor 'edit)
+ t))
+
+;;;###autoload
+(defun magit-rebase-reword-commit (commit args)
+ "Reword a single older commit using rebase."
+ (interactive (list (magit-commit-at-point)
+ (magit-rebase-arguments)))
+ (magit-rebase-interactive-1 commit args
+ "Type %p on a commit to reword its message,"
+ (apply-partially #'magit-rebase--perl-editor 'reword)))
+
+;;;###autoload
+(defun magit-rebase-remove-commit (commit args)
+ "Remove a single older commit using rebase."
+ (interactive (list (magit-commit-at-point)
+ (magit-rebase-arguments)))
+ ;; magit-rebase--perl-editor assumes that the comment character is "#".
+ (let ((magit-git-global-arguments
+ (nconc (list "-c" "core.commentChar=#")
+ magit-git-global-arguments)))
+ (magit-rebase-interactive-1 commit args
+ "Type %p on a commit to remove it,"
+ (apply-partially #'magit-rebase--perl-editor 'remove)
+ nil nil t)))
+
+(defun magit-rebase--perl-editor (action since)
+ (let ((commit (magit-rev-abbrev (magit-rebase--target-commit since))))
+ (format "%s -i -p -e '++$x if not $x and s/^pick %s/%s %s/'"
+ magit-perl-executable
+ commit
+ (cl-case action
+ (edit "edit")
+ (remove "noop\n# pick")
+ (reword "reword")
+ (t (error "unknown action: %s" action)))
+ commit)))
+
+;;;###autoload
+(defun magit-rebase-continue (&optional noedit)
+ "Restart the current rebasing operation.
+In some cases this pops up a commit message buffer for you do
+edit. With a prefix argument the old message is reused as-is."
+ (interactive "P")
+ (if (magit-rebase-in-progress-p)
+ (if (magit-anything-unstaged-p t)
+ (user-error "Cannot continue rebase with unstaged changes")
+ (when (and (magit-anything-staged-p)
+ (file-exists-p (magit-git-dir "rebase-merge"))
+ (not (member (magit-toplevel)
+ magit--rebase-public-edit-confirmed)))
+ (magit-commit-amend-assert
+ (magit-file-line (magit-git-dir "rebase-merge/orig-head"))))
+ (if noedit
+ (with-environment-variables (("GIT_EDITOR" "true"))
+ (magit-run-git-async (magit--rebase-resume-command) "--continue")
+ (set-process-sentinel magit-this-process
+ #'magit-sequencer-process-sentinel)
+ magit-this-process)
+ (magit-run-git-sequencer (magit--rebase-resume-command) "--continue")))
+ (user-error "No rebase in progress")))
+
+;;;###autoload
+(defun magit-rebase-skip ()
+ "Skip the current commit and restart the current rebase operation."
+ (interactive)
+ (unless (magit-rebase-in-progress-p)
+ (user-error "No rebase in progress"))
+ (magit-run-git-sequencer (magit--rebase-resume-command) "--skip"))
+
+;;;###autoload
+(defun magit-rebase-edit ()
+ "Edit the todo list of the current rebase operation."
+ (interactive)
+ (unless (magit-rebase-in-progress-p)
+ (user-error "No rebase in progress"))
+ (magit-run-git-sequencer "rebase" "--edit-todo"))
+
+;;;###autoload
+(defun magit-rebase-abort ()
+ "Abort the current rebase operation, restoring the original branch."
+ (interactive)
+ (unless (magit-rebase-in-progress-p)
+ (user-error "No rebase in progress"))
+ (magit-confirm 'abort-rebase "Abort this rebase")
+ (magit-run-git (magit--rebase-resume-command) "--abort"))
+
+(defun magit-rebase-in-progress-p ()
+ "Return t if a rebase is in progress."
+ (or (file-exists-p (magit-git-dir "rebase-merge"))
+ (file-exists-p (magit-git-dir "rebase-apply/onto"))))
+
+(defun magit--rebase-resume-command ()
+ (if (file-exists-p (magit-git-dir "rebase-recursive")) "rbr" "rebase"))
+
+(defun magit-rebase--get-state-lines (file)
+ (and (magit-rebase-in-progress-p)
+ (magit-file-line
+ (magit-git-dir
+ (concat (if (file-directory-p (magit-git-dir "rebase-merge"))
+ "rebase-merge/"
+ "rebase-apply/")
+ file)))))
+
+;;; Sections
+
+(defun magit-insert-sequencer-sequence ()
+ "Insert section for the on-going cherry-pick or revert sequence.
+If no such sequence is in progress, do nothing."
+ (let ((picking (magit-cherry-pick-in-progress-p)))
+ (when (or picking (magit-revert-in-progress-p))
+ (magit-insert-section (sequence)
+ (magit-insert-heading (if picking "Cherry Picking" "Reverting"))
+ (when-let ((lines
+ (cdr (magit-file-lines (magit-git-dir "sequencer/todo")))))
+ (dolist (line (nreverse lines))
+ (when (string-match
+ "^\\(pick\\|revert\\) \\([^ ]+\\) \\(.*\\)$" line)
+ (magit-bind-match-strings (cmd hash msg) line
+ (magit-insert-section (commit hash)
+ (insert (propertize cmd 'font-lock-face 'magit-sequence-pick)
+ " " (propertize hash 'font-lock-face 'magit-hash)
+ " " msg "\n"))))))
+ (magit-sequence-insert-sequence
+ (magit-file-line (magit-git-dir (if picking
+ "CHERRY_PICK_HEAD"
+ "REVERT_HEAD")))
+ (magit-file-line (magit-git-dir "sequencer/head")))
+ (insert "\n")))))
+
+(defun magit-insert-am-sequence ()
+ "Insert section for the on-going patch applying sequence.
+If no such sequence is in progress, do nothing."
+ (when (magit-am-in-progress-p)
+ (magit-insert-section (rebase-sequence)
+ (magit-insert-heading "Applying patches")
+ (let ((patches (nreverse (magit-rebase-patches)))
+ patch commit)
+ (while patches
+ (setq patch (pop patches))
+ (setq commit (magit-commit-p
+ (cadr (split-string (magit-file-line patch)))))
+ (cond ((and commit patches)
+ (magit-sequence-insert-commit
+ "pick" commit 'magit-sequence-pick))
+ (patches
+ (magit-sequence-insert-am-patch
+ "pick" patch 'magit-sequence-pick))
+ (commit
+ (magit-sequence-insert-sequence commit "ORIG_HEAD"))
+ (t
+ (magit-sequence-insert-am-patch
+ "stop" patch 'magit-sequence-stop)
+ (magit-sequence-insert-sequence nil "ORIG_HEAD")))))
+ (insert ?\n))))
+
+(defun magit-sequence-insert-am-patch (type patch face)
+ (magit-insert-section (file patch)
+ (let ((title
+ (with-temp-buffer
+ (insert-file-contents patch nil nil 4096)
+ (unless (re-search-forward "^Subject: " nil t)
+ (goto-char (point-min)))
+ (buffer-substring (point) (line-end-position)))))
+ (insert (propertize type 'font-lock-face face)
+ ?\s (propertize (file-name-nondirectory patch)
+ 'font-lock-face 'magit-hash)
+ ?\s title
+ ?\n))))
+
+(defun magit-insert-rebase-sequence ()
+ "Insert section for the on-going rebase sequence.
+If no such sequence is in progress, do nothing."
+ (when (magit-rebase-in-progress-p)
+ (let* ((interactive (file-directory-p (magit-git-dir "rebase-merge")))
+ (dir (if interactive "rebase-merge/" "rebase-apply/"))
+ (name (thread-first (concat dir "head-name")
+ magit-git-dir
+ magit-file-line))
+ (onto (thread-first (concat dir "onto")
+ magit-git-dir
+ magit-file-line))
+ (onto (or (magit-rev-name onto name)
+ (magit-rev-name onto "refs/heads/*") onto))
+ (name (or (magit-rev-name name "refs/heads/*") name)))
+ (magit-insert-section (rebase-sequence)
+ (magit-insert-heading (format "Rebasing %s onto %s" name onto))
+ (if interactive
+ (magit-rebase-insert-merge-sequence onto)
+ (magit-rebase-insert-apply-sequence onto))
+ (insert ?\n)))))
+
+(defun magit-rebase--todo ()
+ "Return `git-rebase-action' instances for remaining rebase actions.
+These are ordered in that the same way they'll be sorted in the
+status buffer (i.e. the reverse of how they will be applied)."
+ (let ((comment-start (or (magit-get "core.commentChar") "#"))
+ lines)
+ (with-temp-buffer
+ (insert-file-contents (magit-git-dir "rebase-merge/git-rebase-todo"))
+ (while (not (eobp))
+ (let ((ln (git-rebase-current-line)))
+ (when (oref ln action-type)
+ (push ln lines)))
+ (forward-line)))
+ lines))
+
+(defun magit-rebase-insert-merge-sequence (onto)
+ (dolist (line (magit-rebase--todo))
+ (with-slots (action-type action action-options target) line
+ (pcase action-type
+ ('commit
+ (magit-sequence-insert-commit action target 'magit-sequence-pick))
+ ((or (or `exec `label)
+ (and `merge (guard (not action-options))))
+ (insert (propertize action 'font-lock-face 'magit-sequence-onto) "\s"
+ (propertize target 'font-lock-face 'git-rebase-label) "\n"))
+ ('merge
+ (if-let ((hash (and (string-match "-[cC] \\([^ ]+\\)" action-options)
+ (match-string 1 action-options))))
+ (magit-insert-section (commit hash)
+ (magit-insert-heading
+ (propertize "merge" 'font-lock-face 'magit-sequence-pick)
+ "\s"
+ (magit-format-rev-summary hash) "\n"))
+ (error "failed to parse merge message hash"))))))
+ (magit-sequence-insert-sequence
+ (magit-file-line (magit-git-dir "rebase-merge/stopped-sha"))
+ onto
+ (and-let* ((lines (magit-file-lines (magit-git-dir "rebase-merge/done"))))
+ (cadr (split-string (car (last lines)))))))
+
+(defun magit-rebase-insert-apply-sequence (onto)
+ (let ((rewritten
+ (--map (car (split-string it))
+ (magit-file-lines (magit-git-dir "rebase-apply/rewritten"))))
+ (stop (magit-file-line (magit-git-dir "rebase-apply/original-commit"))))
+ (dolist (patch (nreverse (cdr (magit-rebase-patches))))
+ (let ((hash (cadr (split-string (magit-file-line patch)))))
+ (unless (or (member hash rewritten)
+ (equal hash stop))
+ (magit-sequence-insert-commit "pick" hash 'magit-sequence-pick)))))
+ (magit-sequence-insert-sequence
+ (magit-file-line (magit-git-dir "rebase-apply/original-commit"))
+ onto))
+
+(defun magit-rebase-patches ()
+ (directory-files (magit-git-dir "rebase-apply") t "^[0-9]\\{4\\}$"))
+
+(defun magit-sequence-insert-sequence (stop onto &optional orig)
+ (let ((head (magit-rev-parse "HEAD")) done)
+ (setq onto (if onto (magit-rev-parse onto) head))
+ (setq done (magit-git-lines "log" "--format=%H" (concat onto "..HEAD")))
+ (when (and stop (not (member (magit-rev-parse stop) done)))
+ (let ((id (magit-patch-id stop)))
+ (--if-let (--first (equal (magit-patch-id it) id) done)
+ (setq stop it)
+ (cond
+ ((--first (magit-rev-equal it stop) done)
+ ;; The commit's testament has been executed.
+ (magit-sequence-insert-commit "void" stop 'magit-sequence-drop))
+ ;; The faith of the commit is still undecided...
+ ((magit-anything-unmerged-p)
+ ;; ...and time travel isn't for the faint of heart.
+ (magit-sequence-insert-commit "join" stop 'magit-sequence-part))
+ ((magit-anything-modified-p t)
+ ;; ...and the dust hasn't settled yet...
+ (magit-sequence-insert-commit
+ (let* ((magit--refresh-cache nil)
+ (staged (magit-commit-tree "oO" nil "HEAD"))
+ (unstaged (magit-commit-worktree "oO" "--reset")))
+ (cond
+ ;; ...but we could end up at the same tree just by committing.
+ ((or (magit-rev-equal staged stop)
+ (magit-rev-equal unstaged stop)) "goal")
+ ;; ...but the changes are still there, untainted.
+ ((or (equal (magit-patch-id staged) id)
+ (equal (magit-patch-id unstaged) id)) "same")
+ ;; ...and some changes are gone and/or others were added.
+ (t "work")))
+ stop 'magit-sequence-part))
+ ;; The commit is definitely gone...
+ ((--first (magit-rev-equal it stop) done)
+ ;; ...but all of its changes are still in effect.
+ (magit-sequence-insert-commit "poof" stop 'magit-sequence-drop))
+ (t
+ ;; ...and some changes are gone and/or other changes were added.
+ (magit-sequence-insert-commit "gone" stop 'magit-sequence-drop)))
+ (setq stop nil))))
+ (dolist (rev done)
+ (apply #'magit-sequence-insert-commit
+ (cond ((equal rev stop)
+ ;; ...but its reincarnation lives on.
+ ;; Or it didn't die in the first place.
+ (list (if (and (equal rev head)
+ (equal (magit-patch-id rev)
+ (magit-patch-id orig)))
+ "stop" ; We haven't done anything yet.
+ "like") ; There are new commits.
+ rev (if (equal rev head)
+ 'magit-sequence-head
+ 'magit-sequence-stop)))
+ ((equal rev head)
+ (list "done" rev 'magit-sequence-head))
+ (t
+ (list "done" rev 'magit-sequence-done)))))
+ (magit-sequence-insert-commit "onto" onto
+ (if (equal onto head)
+ 'magit-sequence-head
+ 'magit-sequence-onto))))
+
+(defun magit-sequence-insert-commit (type hash face)
+ (magit-insert-section (commit hash)
+ (magit-insert-heading
+ (propertize type 'font-lock-face face) "\s"
+ (magit-format-rev-summary hash) "\n")))
+
+;;; _
+(provide 'magit-sequence)
+;;; magit-sequence.el ends here
diff --git a/elpa/magit-20220503.1245/magit-sequence.elc b/elpa/magit-20220503.1245/magit-sequence.elc
new file mode 100644
index 0000000..85e6eaa
--- /dev/null
+++ b/elpa/magit-20220503.1245/magit-sequence.elc
Binary files differ
diff --git a/elpa/magit-20220503.1245/magit-sparse-checkout.el b/elpa/magit-20220503.1245/magit-sparse-checkout.el
new file mode 100644
index 0000000..e9f761d
--- /dev/null
+++ b/elpa/magit-20220503.1245/magit-sparse-checkout.el
@@ -0,0 +1,170 @@
+;;; magit-sparse-checkout.el --- Sparse checkout support for Magit -*- lexical-binding:t -*-
+
+;; Copyright (C) 2008-2022 The Magit Project Contributors
+
+;; Author: Kyle Meyer <kyle@kyleam.com>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+
+;; SPDX-License-Identifier: GPL-3.0-or-later
+
+;; Magit 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.
+;;
+;; Magit 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 Magit. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This library provides an interface to the `git sparse-checkout'
+;; command. It's been possible to define sparse checkouts since Git
+;; v1.7.0 by adding patterns to $GIT_DIR/info/sparse-checkout and
+;; calling `git read-tree -mu HEAD' to update the index and working
+;; tree. However, Git v2.25 introduced the `git sparse-checkout'
+;; command along with "cone mode", which restricts the possible
+;; patterns to directories to provide better performance.
+;;
+;; The goal of this library is to support the `git sparse-checkout'
+;; command operating in cone mode.
+
+;;; Code:
+
+(require 'magit)
+
+;;; Utilities
+
+(defun magit-sparse-checkout-enabled-p ()
+ "Return non-nil if working tree is a sparse checkout."
+ (magit-get-boolean "core.sparsecheckout"))
+
+(defun magit-sparse-checkout--assert-version ()
+ ;; Older versions of Git have the ability to define sparse checkout
+ ;; patterns in .git/info/sparse-checkout, but the sparse-checkout
+ ;; command isn't available until 2.25.0.
+ (when (magit-git-version< "2.25.0")
+ (user-error "`git sparse-checkout' not available until Git v2.25")))
+
+(defun magit-sparse-checkout--auto-enable ()
+ (if (magit-sparse-checkout-enabled-p)
+ (unless (magit-get-boolean "core.sparsecheckoutcone")
+ (user-error
+ "Magit's sparse checkout functionality requires cone mode"))
+ ;; Note: Don't use `magit-sparse-checkout-enable' because it's
+ ;; asynchronous.
+ (magit-run-git "sparse-checkout" "init" "--cone")))
+
+(defun magit-sparse-checkout-directories ()
+ "Return directories that are recursively included in the sparse checkout.
+See the `git sparse-checkout' manpage for details about
+\"recursive\" versus \"parent\" directories in cone mode."
+ (and (magit-get-boolean "core.sparsecheckoutcone")
+ (mapcar #'file-name-as-directory
+ (magit-git-lines "sparse-checkout" "list"))))
+
+;;; Commands
+
+;;;###autoload (autoload 'magit-sparse-checkout "magit-sparse-checkout" nil t)
+(transient-define-prefix magit-sparse-checkout ()
+ "Create and manage sparse checkouts."
+ :man-page "git-sparse-checkout"
+ ["Arguments for enabling"
+ :if-not magit-sparse-checkout-enabled-p
+ ("-i" "Use sparse index" "--sparse-index")]
+ ["Actions"
+ [:if-not magit-sparse-checkout-enabled-p
+ ("e" "Enable sparse checkout" magit-sparse-checkout-enable)]
+ [:if magit-sparse-checkout-enabled-p
+ ("d" "Disable sparse checkout" magit-sparse-checkout-disable)
+ ("r" "Reapply rules" magit-sparse-checkout-reapply)]
+ [("s" "Set directories" magit-sparse-checkout-set)
+ ("a" "Add directories" magit-sparse-checkout-add)]])
+
+;;;###autoload
+(defun magit-sparse-checkout-enable (&optional args)
+ "Convert the working tree to a sparse checkout."
+ (interactive (list (transient-args 'magit-sparse-checkout)))
+ (magit-sparse-checkout--assert-version)
+ (magit-run-git-async "sparse-checkout" "init" "--cone" args))
+
+;;;###autoload
+(defun magit-sparse-checkout-set (directories)
+ "Restrict working tree to DIRECTORIES.
+To extend rather than override the currently configured
+directories, call `magit-sparse-checkout-add' instead."
+ (interactive
+ (list (magit-completing-read-multiple*
+ "Include these directories: "
+ ;; Note: Given that the appeal of sparse checkouts is
+ ;; dealing with very large trees, listing all subdirectories
+ ;; may need to be reconsidered.
+ (magit-revision-directories "HEAD"))))
+ (magit-sparse-checkout--assert-version)
+ (magit-sparse-checkout--auto-enable)
+ (magit-run-git-async "sparse-checkout" "set" directories))
+
+;;;###autoload
+(defun magit-sparse-checkout-add (directories)
+ "Add DIRECTORIES to the working tree.
+To override rather than extend the currently configured
+directories, call `magit-sparse-checkout-set' instead."
+ (interactive
+ (list (magit-completing-read-multiple*
+ "Add these directories: "
+ ;; Same performance note as in `magit-sparse-checkout-set',
+ ;; but even more so given the additional processing.
+ (seq-remove
+ (let ((re (concat
+ "\\`"
+ (regexp-opt (magit-sparse-checkout-directories)))))
+ (lambda (d) (string-match-p re d)))
+ (magit-revision-directories "HEAD")))))
+ (magit-sparse-checkout--assert-version)
+ (magit-sparse-checkout--auto-enable)
+ (magit-run-git-async "sparse-checkout" "add" directories))
+
+;;;###autoload
+(defun magit-sparse-checkout-reapply ()
+ "Reapply the sparse checkout rules to the working tree.
+Some operations such as merging or rebasing may need to check out
+files that aren't included in the sparse checkout. Call this
+command to reset to the sparse checkout state."
+ (interactive)
+ (magit-sparse-checkout--assert-version)
+ (magit-run-git-async "sparse-checkout" "reapply"))
+
+;;;###autoload
+(defun magit-sparse-checkout-disable ()
+ "Convert sparse checkout to full checkout.
+Note that disabling the sparse checkout does not clear the
+configured directories. Call `magit-sparse-checkout-enable' to
+restore the previous sparse checkout."
+ (interactive)
+ (magit-sparse-checkout--assert-version)
+ (magit-run-git-async "sparse-checkout" "disable"))
+
+;;; Miscellaneous
+
+(defun magit-sparse-checkout-insert-header ()
+ "Insert header line with sparse checkout information.
+This header is not inserted by default. To enable it, add it to
+`magit-status-headers-hook'."
+ (when (magit-sparse-checkout-enabled-p)
+ (insert (propertize (format "%-10s" "Sparse! ")
+ 'font-lock-face 'magit-section-heading))
+ (insert
+ (let ((dirs (magit-sparse-checkout-directories)))
+ (pcase (length dirs)
+ (0 "top-level directory")
+ (1 (car dirs))
+ (n (format "%d directories" n)))))
+ (insert ?\n)))
+
+;;; _
+(provide 'magit-sparse-checkout)
+;;; magit-sparse-checkout.el ends here
diff --git a/elpa/magit-20220503.1245/magit-sparse-checkout.elc b/elpa/magit-20220503.1245/magit-sparse-checkout.elc
new file mode 100644
index 0000000..8cdc5b1
--- /dev/null
+++ b/elpa/magit-20220503.1245/magit-sparse-checkout.elc
Binary files differ
diff --git a/elpa/magit-20220503.1245/magit-stash.el b/elpa/magit-20220503.1245/magit-stash.el
new file mode 100644
index 0000000..8aee060
--- /dev/null
+++ b/elpa/magit-20220503.1245/magit-stash.el
@@ -0,0 +1,566 @@
+;;; magit-stash.el --- Stash support for Magit -*- lexical-binding:t -*-
+
+;; Copyright (C) 2008-2022 The Magit Project Contributors
+
+;; Author: Jonas Bernoulli <jonas@bernoul.li>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+
+;; SPDX-License-Identifier: GPL-3.0-or-later
+
+;; Magit 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.
+;;
+;; Magit 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 Magit. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Support for Git stashes.
+
+;;; Code:
+
+(require 'magit)
+(require 'magit-reflog)
+(require 'magit-sequence)
+
+;;; Options
+
+(defgroup magit-stash nil
+ "List stashes and show stash diffs."
+ :group 'magit-modes)
+
+;;;; Diff options
+
+(defcustom magit-stash-sections-hook
+ '(magit-insert-stash-notes
+ magit-insert-stash-worktree
+ magit-insert-stash-index
+ magit-insert-stash-untracked)
+ "Hook run to insert sections into stash diff buffers."
+ :package-version '(magit . "2.1.0")
+ :group 'magit-stash
+ :type 'hook)
+
+;;;; Log options
+
+(defcustom magit-stashes-margin
+ (list (nth 0 magit-log-margin)
+ (nth 1 magit-log-margin)
+ 'magit-log-margin-width nil
+ (nth 4 magit-log-margin))
+ "Format of the margin in `magit-stashes-mode' buffers.
+
+The value has the form (INIT STYLE WIDTH AUTHOR AUTHOR-WIDTH).
+
+If INIT is non-nil, then the margin is shown initially.
+STYLE controls how to format the author or committer date.
+ It can be one of `age' (to show the age of the commit),
+ `age-abbreviated' (to abbreviate the time unit to a character),
+ or a string (suitable for `format-time-string') to show the
+ actual date. Option `magit-log-margin-show-committer-date'
+ controls which date is being displayed.
+WIDTH controls the width of the margin. This exists for forward
+ compatibility and currently the value should not be changed.
+AUTHOR controls whether the name of the author is also shown by
+ default.
+AUTHOR-WIDTH has to be an integer. When the name of the author
+ is shown, then this specifies how much space is used to do so."
+ :package-version '(magit . "2.9.0")
+ :group 'magit-stash
+ :group 'magit-margin
+ :type magit-log-margin--custom-type
+ :initialize #'magit-custom-initialize-reset
+ :set-after '(magit-log-margin)
+ :set (apply-partially #'magit-margin-set-variable 'magit-stashes-mode))
+
+;;; Commands
+
+;;;###autoload (autoload 'magit-stash "magit-stash" nil t)
+(transient-define-prefix magit-stash ()
+ "Stash uncommitted changes."
+ :man-page "git-stash"
+ ["Arguments"
+ ("-u" "Also save untracked files" ("-u" "--include-untracked"))
+ ("-a" "Also save untracked and ignored files" ("-a" "--all"))]
+ [["Stash"
+ ("z" "both" magit-stash-both)
+ ("i" "index" magit-stash-index)
+ ("w" "worktree" magit-stash-worktree)
+ ("x" "keeping index" magit-stash-keep-index)
+ ("P" "push" magit-stash-push :level 5)]
+ ["Snapshot"
+ ("Z" "both" magit-snapshot-both)
+ ("I" "index" magit-snapshot-index)
+ ("W" "worktree" magit-snapshot-worktree)
+ ("r" "to wip ref" magit-wip-commit)]
+ ["Use"
+ ("a" "Apply" magit-stash-apply)
+ ("p" "Pop" magit-stash-pop)
+ ("k" "Drop" magit-stash-drop)]
+ ["Inspect"
+ ("l" "List" magit-stash-list)
+ ("v" "Show" magit-stash-show)]
+ ["Transform"
+ ("b" "Branch" magit-stash-branch)
+ ("B" "Branch here" magit-stash-branch-here)
+ ("f" "Format patch" magit-stash-format-patch)]])
+
+(defun magit-stash-arguments ()
+ (transient-args 'magit-stash))
+
+;;;###autoload
+(defun magit-stash-both (message &optional include-untracked)
+ "Create a stash of the index and working tree.
+Untracked files are included according to infix arguments.
+One prefix argument is equivalent to `--include-untracked'
+while two prefix arguments are equivalent to `--all'."
+ (interactive
+ (progn (when (and (magit-merge-in-progress-p)
+ (not (magit-y-or-n-p "\
+Stashing and resetting during a merge conflict. \
+Applying the resulting stash won't restore the merge state. \
+Proceed anyway? ")))
+ (user-error "Abort"))
+ (magit-stash-read-args)))
+ (magit-stash-save message t t include-untracked t))
+
+;;;###autoload
+(defun magit-stash-index (message)
+ "Create a stash of the index only.
+Unstaged and untracked changes are not stashed. The stashed
+changes are applied in reverse to both the index and the
+worktree. This command can fail when the worktree is not clean.
+Applying the resulting stash has the inverse effect."
+ (interactive (list (magit-stash-read-message)))
+ (magit-stash-save message t nil nil t 'worktree))
+
+;;;###autoload
+(defun magit-stash-worktree (message &optional include-untracked)
+ "Create a stash of unstaged changes in the working tree.
+Untracked files are included according to infix arguments.
+One prefix argument is equivalent to `--include-untracked'
+while two prefix arguments are equivalent to `--all'."
+ (interactive (magit-stash-read-args))
+ (magit-stash-save message nil t include-untracked t 'index))
+
+;;;###autoload
+(defun magit-stash-keep-index (message &optional include-untracked)
+ "Create a stash of the index and working tree, keeping index intact.
+Untracked files are included according to infix arguments.
+One prefix argument is equivalent to `--include-untracked'
+while two prefix arguments are equivalent to `--all'."
+ (interactive (magit-stash-read-args))
+ (magit-stash-save message t t include-untracked t 'index))
+
+(defun magit-stash-read-args ()
+ (list (magit-stash-read-message)
+ (magit-stash-read-untracked)))
+
+(defun magit-stash-read-untracked ()
+ (let ((prefix (prefix-numeric-value current-prefix-arg))
+ (args (magit-stash-arguments)))
+ (cond ((or (= prefix 16) (member "--all" args)) 'all)
+ ((or (= prefix 4) (member "--include-untracked" args)) t))))
+
+(defun magit-stash-read-message ()
+ (let* ((default (format "On %s: "
+ (or (magit-get-current-branch) "(no branch)")))
+ (input (magit-read-string "Stash message" default)))
+ (if (equal input default)
+ (concat default (magit-rev-format "%h %s"))
+ input)))
+
+;;;###autoload
+(defun magit-snapshot-both (&optional include-untracked)
+ "Create a snapshot of the index and working tree.
+Untracked files are included according to infix arguments.
+One prefix argument is equivalent to `--include-untracked'
+while two prefix arguments are equivalent to `--all'."
+ (interactive (magit-snapshot-read-args))
+ (magit-snapshot-save t t include-untracked t))
+
+;;;###autoload
+(defun magit-snapshot-index ()
+ "Create a snapshot of the index only.
+Unstaged and untracked changes are not stashed."
+ (interactive)
+ (magit-snapshot-save t nil nil t))
+
+;;;###autoload
+(defun magit-snapshot-worktree (&optional include-untracked)
+ "Create a snapshot of unstaged changes in the working tree.
+Untracked files are included according to infix arguments.
+One prefix argument is equivalent to `--include-untracked'
+while two prefix arguments are equivalent to `--all'."
+ (interactive (magit-snapshot-read-args))
+ (magit-snapshot-save nil t include-untracked t))
+
+(defun magit-snapshot-read-args ()
+ (list (magit-stash-read-untracked)))
+
+(defun magit-snapshot-save (index worktree untracked &optional refresh)
+ (magit-stash-save (concat "WIP on " (magit-stash-summary))
+ index worktree untracked refresh t))
+
+;;;###autoload (autoload 'magit-stash-push "magit-stash" nil t)
+(transient-define-prefix magit-stash-push (&optional transient args)
+ "Create stash using \"git stash push\".
+
+This differs from Magit's other stashing commands, which don't
+use \"git stash\" and are generally more flexible but don't allow
+specifying a list of files to be stashed."
+ :man-page "git-stash"
+ ["Arguments"
+ (magit:-- :reader ,(-rpartial #'magit-read-files
+ #'magit-modified-files))
+ ("-u" "Also save untracked files" ("-u" "--include-untracked"))
+ ("-a" "Also save untracked and ignored files" ("-a" "--all"))
+ ("-k" "Keep index" ("-k" "--keep-index"))
+ ("-K" "Don't keep index" "--no-keep-index")]
+ ["Actions"
+ ("P" "push" magit-stash-push)]
+ (interactive (if (eq transient-current-command 'magit-stash-push)
+ (list nil (transient-args 'magit-stash-push))
+ (list t)))
+ (if transient
+ (transient-setup 'magit-stash-push)
+ (magit-run-git "stash" "push" args)))
+
+;;;###autoload
+(defun magit-stash-apply (stash)
+ "Apply a stash to the working tree.
+Try to preserve the stash index. If that fails because there
+are staged changes, apply without preserving the stash index."
+ (interactive (list (magit-read-stash "Apply stash")))
+ (if (= (magit-call-git "stash" "apply" "--index" stash) 0)
+ (magit-refresh)
+ (magit-run-git "stash" "apply" stash)))
+
+;;;###autoload
+(defun magit-stash-pop (stash)
+ "Apply a stash to the working tree and remove it from stash list.
+Try to preserve the stash index. If that fails because there
+are staged changes, apply without preserving the stash index
+and forgo removing the stash."
+ (interactive (list (magit-read-stash "Pop stash")))
+ (if (= (magit-call-git "stash" "apply" "--index" stash) 0)
+ (magit-stash-drop stash)
+ (magit-run-git "stash" "apply" stash)))
+
+;;;###autoload
+(defun magit-stash-drop (stash)
+ "Remove a stash from the stash list.
+When the region is active offer to drop all contained stashes."
+ (interactive
+ (list (--if-let (magit-region-values 'stash)
+ (magit-confirm 'drop-stashes nil "Drop %i stashes" nil it)
+ (magit-read-stash "Drop stash"))))
+ (dolist (stash (if (listp stash)
+ (nreverse (prog1 stash (setq stash (car stash))))
+ (list stash)))
+ (message "Deleted refs/%s (was %s)" stash
+ (magit-rev-parse "--short" stash))
+ (magit-call-git "rev-parse" stash)
+ (magit-call-git "stash" "drop" stash))
+ (magit-refresh))
+
+;;;###autoload
+(defun magit-stash-clear (ref)
+ "Remove all stashes saved in REF's reflog by deleting REF."
+ (interactive (let ((ref (or (magit-section-value-if 'stashes) "refs/stash")))
+ (magit-confirm t (format "Drop all stashes in %s" ref))
+ (list ref)))
+ (magit-run-git "update-ref" "-d" ref))
+
+;;;###autoload
+(defun magit-stash-branch (stash branch)
+ "Create and checkout a new BRANCH from STASH."
+ (interactive (list (magit-read-stash "Branch stash")
+ (magit-read-string-ns "Branch name")))
+ (magit-run-git "stash" "branch" branch stash))
+
+;;;###autoload
+(defun magit-stash-branch-here (stash branch)
+ "Create and checkout a new BRANCH and apply STASH.
+The branch is created using `magit-branch-and-checkout', using the
+current branch or `HEAD' as the start-point."
+ (interactive (list (magit-read-stash "Branch stash")
+ (magit-read-string-ns "Branch name")))
+ (let ((magit-inhibit-refresh t))
+ (magit-branch-and-checkout branch (or (magit-get-current-branch) "HEAD")))
+ (magit-stash-apply stash))
+
+;;;###autoload
+(defun magit-stash-format-patch (stash)
+ "Create a patch from STASH"
+ (interactive (list (magit-read-stash "Create patch from stash")))
+ (with-temp-file (magit-rev-format "0001-%f.patch" stash)
+ (magit-git-insert "stash" "show" "-p" stash))
+ (magit-refresh))
+
+;;; Plumbing
+
+(defun magit-stash-save (message index worktree untracked
+ &optional refresh keep noerror ref)
+ (if (or (and index (magit-staged-files t))
+ (and worktree (magit-unstaged-files t))
+ (and untracked (magit-untracked-files (eq untracked 'all))))
+ (magit-with-toplevel
+ (magit-stash-store message (or ref "refs/stash")
+ (magit-stash-create message index worktree untracked))
+ (if (eq keep 'worktree)
+ (with-temp-buffer
+ (magit-git-insert "diff" "--cached" "--no-ext-diff")
+ (magit-run-git-with-input
+ "apply" "--reverse" "--cached" "--ignore-space-change" "-")
+ (magit-run-git-with-input
+ "apply" "--reverse" "--ignore-space-change" "-"))
+ (unless (eq keep t)
+ (if (eq keep 'index)
+ (magit-call-git "checkout" "--" ".")
+ (magit-call-git "reset" "--hard" "HEAD" "--"))
+ (when untracked
+ (magit-call-git "clean" "--force" "-d"
+ (and (eq untracked 'all) "-x")))))
+ (when refresh
+ (magit-refresh)))
+ (unless noerror
+ (user-error "No %s changes to save" (cond ((not index) "unstaged")
+ ((not worktree) "staged")
+ (t "local"))))))
+
+(defun magit-stash-store (message ref commit)
+ (magit-update-ref ref message commit t))
+
+(defun magit-stash-create (message index worktree untracked)
+ (unless (magit-rev-parse "--verify" "HEAD")
+ (error "You do not have the initial commit yet"))
+ (let ((magit-git-global-arguments (nconc (list "-c" "commit.gpgsign=false")
+ magit-git-global-arguments))
+ (default-directory (magit-toplevel))
+ (summary (magit-stash-summary))
+ (head "HEAD"))
+ (when (and worktree (not index))
+ (setq head (or (magit-commit-tree "pre-stash index" nil "HEAD")
+ (error "Cannot save the current index state"))))
+ (or (setq index (magit-commit-tree (concat "index on " summary) nil head))
+ (error "Cannot save the current index state"))
+ (and untracked
+ (setq untracked (magit-untracked-files (eq untracked 'all)))
+ (setq untracked (magit-with-temp-index nil nil
+ (or (and (magit-update-files untracked)
+ (magit-commit-tree
+ (concat "untracked files on " summary)))
+ (error "Cannot save the untracked files")))))
+ (magit-with-temp-index index "-m"
+ (when worktree
+ (or (magit-update-files (magit-git-items "diff" "-z" "--name-only" head))
+ (error "Cannot save the current worktree state")))
+ (or (magit-commit-tree message nil head index untracked)
+ (error "Cannot save the current worktree state")))))
+
+(defun magit-stash-summary ()
+ (concat (or (magit-get-current-branch) "(no branch)")
+ ": " (magit-rev-format "%h %s")))
+
+;;; Sections
+
+(defvar magit-stashes-section-map
+ (let ((map (make-sparse-keymap)))
+ (magit-menu-set map [magit-visit-thing] #'magit-stash-list "List %t")
+ (magit-menu-set map [magit-delete-thing] #'magit-stash-clear "Clear %t")
+ map)
+ "Keymap for `stashes' section.")
+
+(defvar magit-stash-section-map
+ (let ((map (make-sparse-keymap)))
+ (magit-menu-set map [magit-visit-thing] #'magit-stash-show "Visit %v")
+ (magit-menu-set map [magit-delete-thing] #'magit-stash-drop "Delete %M")
+ (magit-menu-set map [magit-cherry-apply] #'magit-stash-apply "Apply %M")
+ (magit-menu-set map [magit-cherry-pick] #'magit-stash-pop "Pop %M")
+ map)
+ "Keymap for `stash' sections.")
+
+(magit-define-section-jumper magit-jump-to-stashes
+ "Stashes" stashes "refs/stash")
+
+(cl-defun magit-insert-stashes (&optional (ref "refs/stash")
+ (heading "Stashes:"))
+ "Insert `stashes' section showing reflog for \"refs/stash\".
+If optional REF is non-nil, show reflog for that instead.
+If optional HEADING is non-nil, use that as section heading
+instead of \"Stashes:\"."
+ (let ((verified (magit-rev-verify ref))
+ (autostash (magit-rebase--get-state-lines "autostash")))
+ (when (or autostash verified)
+ (magit-insert-section (stashes ref)
+ (magit-insert-heading heading)
+ (when autostash
+ (pcase-let ((`(,author ,date ,msg)
+ (split-string
+ (car (magit-git-lines
+ "show" "-q" "--format=%aN%x00%at%x00%s"
+ autostash))
+ "\0")))
+ (magit-insert-section (stash autostash)
+ (insert (propertize "AUTOSTASH" 'font-lock-face 'magit-hash))
+ (insert " " msg "\n")
+ (save-excursion
+ (backward-char)
+ (magit-log-format-margin autostash author date)))))
+ (if verified
+ (magit-git-wash (apply-partially #'magit-log-wash-log 'stash)
+ "reflog" "--format=%gd%x00%aN%x00%at%x00%gs" ref)
+ (insert ?\n)
+ (save-excursion
+ (backward-char)
+ (magit-make-margin-overlay)))))))
+
+;;; List Stashes
+
+;;;###autoload
+(defun magit-stash-list ()
+ "List all stashes in a buffer."
+ (interactive)
+ (magit-stashes-setup-buffer))
+
+(define-derived-mode magit-stashes-mode magit-reflog-mode "Magit Stashes"
+ "Mode for looking at lists of stashes."
+ :group 'magit-log
+ (hack-dir-local-variables-non-file-buffer))
+
+(defun magit-stashes-setup-buffer ()
+ (magit-setup-buffer #'magit-stashes-mode nil
+ (magit-buffer-refname "refs/stash")))
+
+(defun magit-stashes-refresh-buffer ()
+ (magit-insert-section (stashesbuf)
+ (magit-insert-heading (if (equal magit-buffer-refname "refs/stash")
+ "Stashes:"
+ (format "Stashes [%s]:" magit-buffer-refname)))
+ (magit-git-wash (apply-partially #'magit-log-wash-log 'stash)
+ "reflog" "--format=%gd%x00%aN%x00%at%x00%gs" magit-buffer-refname)))
+
+(cl-defmethod magit-buffer-value (&context (major-mode magit-stashes-mode))
+ magit-buffer-refname)
+
+(defvar magit--update-stash-buffer nil)
+
+(defun magit-stashes-maybe-update-stash-buffer (&optional _)
+ "When moving in the stashes buffer, update the stash buffer.
+If there is no stash buffer in the same frame, then do nothing."
+ (when (derived-mode-p 'magit-stashes-mode)
+ (magit--maybe-update-stash-buffer)))
+
+(defun magit--maybe-update-stash-buffer ()
+ (when-let* ((stash (magit-section-value-if 'stash))
+ (buffer (magit-get-mode-buffer 'magit-stash-mode nil t)))
+ (if magit--update-stash-buffer
+ (setq magit--update-stash-buffer (list stash buffer))
+ (setq magit--update-stash-buffer (list stash buffer))
+ (run-with-idle-timer
+ magit-update-other-window-delay nil
+ (let ((args (with-current-buffer buffer
+ (let ((magit-direct-use-buffer-arguments 'selected))
+ (magit-show-commit--arguments)))))
+ (lambda ()
+ (pcase-let ((`(,stash ,buf) magit--update-stash-buffer))
+ (setq magit--update-stash-buffer nil)
+ (when (buffer-live-p buf)
+ (let ((magit-display-buffer-noselect t))
+ (apply #'magit-stash-show stash args))))
+ (setq magit--update-stash-buffer nil)))))))
+
+;;; Show Stash
+
+;;;###autoload
+(defun magit-stash-show (stash &optional args files)
+ "Show all diffs of a stash in a buffer."
+ (interactive (cons (or (and (not current-prefix-arg)
+ (magit-stash-at-point))
+ (magit-read-stash "Show stash"))
+ (pcase-let ((`(,args ,files)
+ (magit-diff-arguments 'magit-stash-mode)))
+ (list (delete "--stat" args) files))))
+ (magit-stash-setup-buffer stash args files))
+
+(define-derived-mode magit-stash-mode magit-diff-mode "Magit Stash"
+ "Mode for looking at individual stashes."
+ :group 'magit-diff
+ (hack-dir-local-variables-non-file-buffer)
+ (setq magit--imenu-group-types '(commit)))
+
+(defun magit-stash-setup-buffer (stash args files)
+ (magit-setup-buffer #'magit-stash-mode nil
+ (magit-buffer-revision stash)
+ (magit-buffer-range (format "%s^..%s" stash stash))
+ (magit-buffer-diff-args args)
+ (magit-buffer-diff-files files)))
+
+(defun magit-stash-refresh-buffer ()
+ (magit-set-header-line-format
+ (concat (capitalize magit-buffer-revision) " "
+ (propertize (magit-rev-format "%s" magit-buffer-revision)
+ 'font-lock-face
+ (list :weight 'normal :foreground
+ (face-attribute 'default :foreground)))))
+ (setq magit-buffer-revision-hash (magit-rev-parse magit-buffer-revision))
+ (magit-insert-section (stash)
+ (magit-run-section-hook 'magit-stash-sections-hook)))
+
+(cl-defmethod magit-buffer-value (&context (major-mode magit-stash-mode))
+ magit-buffer-revision)
+
+(defun magit-stash-insert-section (commit range message &optional files)
+ (magit-insert-section (commit commit)
+ (magit-insert-heading message)
+ (magit--insert-diff "diff" range "-p" "--no-prefix" magit-buffer-diff-args
+ "--" (or files magit-buffer-diff-files))))
+
+(defun magit-insert-stash-notes ()
+ "Insert section showing notes for a stash.
+This shows the notes for stash@{N} but not for the other commits
+that make up the stash."
+ (magit-insert-section section (note)
+ (magit-insert-heading "Notes")
+ (magit-git-insert "notes" "show" magit-buffer-revision)
+ (if (= (point)
+ (oref section content))
+ (magit-cancel-section)
+ (insert "\n"))))
+
+(defun magit-insert-stash-index ()
+ "Insert section showing staged changes of the stash."
+ (magit-stash-insert-section
+ (format "%s^2" magit-buffer-revision)
+ (format "%s^..%s^2" magit-buffer-revision magit-buffer-revision)
+ "Staged"))
+
+(defun magit-insert-stash-worktree ()
+ "Insert section showing unstaged changes of the stash."
+ (magit-stash-insert-section
+ magit-buffer-revision
+ (format "%s^2..%s" magit-buffer-revision magit-buffer-revision)
+ "Unstaged"))
+
+(defun magit-insert-stash-untracked ()
+ "Insert section showing the untracked files commit of the stash."
+ (let ((stash magit-buffer-revision)
+ (rev (concat magit-buffer-revision "^3")))
+ (when (magit-rev-verify rev)
+ (magit-stash-insert-section (format "%s^3" stash)
+ (format "%s^..%s^3" stash stash)
+ "Untracked files"
+ (magit-git-items "ls-tree" "-z" "--name-only"
+ "-r" "--full-tree" rev)))))
+
+;;; _
+(provide 'magit-stash)
+;;; magit-stash.el ends here
diff --git a/elpa/magit-20220503.1245/magit-stash.elc b/elpa/magit-20220503.1245/magit-stash.elc
new file mode 100644
index 0000000..4a42fa4
--- /dev/null
+++ b/elpa/magit-20220503.1245/magit-stash.elc
Binary files differ
diff --git a/elpa/magit-20220503.1245/magit-status.el b/elpa/magit-20220503.1245/magit-status.el
new file mode 100644
index 0000000..e928e7c
--- /dev/null
+++ b/elpa/magit-20220503.1245/magit-status.el
@@ -0,0 +1,833 @@
+;;; magit-status.el --- The grand overview -*- lexical-binding:t -*-
+
+;; Copyright (C) 2008-2022 The Magit Project Contributors
+
+;; Author: Jonas Bernoulli <jonas@bernoul.li>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+
+;; SPDX-License-Identifier: GPL-3.0-or-later
+
+;; Magit 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.
+;;
+;; Magit 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 Magit. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This library implements the status buffer.
+
+;;; Code:
+
+(require 'magit)
+
+;;; Options
+
+(defgroup magit-status nil
+ "Inspect and manipulate Git repositories."
+ :link '(info-link "(magit)Status Buffer")
+ :group 'magit-modes)
+
+(defcustom magit-status-mode-hook nil
+ "Hook run after entering Magit-Status mode."
+ :group 'magit-status
+ :type 'hook)
+
+(defcustom magit-status-headers-hook
+ '(magit-insert-error-header
+ magit-insert-diff-filter-header
+ magit-insert-head-branch-header
+ magit-insert-upstream-branch-header
+ magit-insert-push-branch-header
+ magit-insert-tags-header)
+ "Hook run to insert headers into the status buffer.
+
+This hook is run by `magit-insert-status-headers', which in turn
+has to be a member of `magit-status-sections-hook' to be used at
+all."
+ :package-version '(magit . "2.1.0")
+ :group 'magit-status
+ :type 'hook
+ :options '(magit-insert-error-header
+ magit-insert-diff-filter-header
+ magit-insert-repo-header
+ magit-insert-remote-header
+ magit-insert-head-branch-header
+ magit-insert-upstream-branch-header
+ magit-insert-push-branch-header
+ magit-insert-tags-header))
+
+(defcustom magit-status-sections-hook
+ '(magit-insert-status-headers
+ magit-insert-merge-log
+ magit-insert-rebase-sequence
+ magit-insert-am-sequence
+ magit-insert-sequencer-sequence
+ magit-insert-bisect-output
+ magit-insert-bisect-rest
+ magit-insert-bisect-log
+ magit-insert-untracked-files
+ magit-insert-unstaged-changes
+ magit-insert-staged-changes
+ magit-insert-stashes
+ magit-insert-unpushed-to-pushremote
+ magit-insert-unpushed-to-upstream-or-recent
+ magit-insert-unpulled-from-pushremote
+ magit-insert-unpulled-from-upstream)
+ "Hook run to insert sections into a status buffer."
+ :package-version '(magit . "2.12.0")
+ :group 'magit-status
+ :type 'hook)
+
+(defcustom magit-status-initial-section '(1)
+ "The section point is placed on when a status buffer is created.
+
+When such a buffer is merely being refreshed or being shown again
+after it was merely buried, then this option has no effect.
+
+If this is nil, then point remains on the very first section as
+usual. Otherwise it has to be a list of integers and section
+identity lists. The members of that list are tried in order
+until a matching section is found.
+
+An integer means to jump to the nth section, 1 for example
+jumps over the headings. To get a section's \"identity list\"
+use \\[universal-argument] \\[magit-describe-section-briefly].
+
+If, for example, you want to jump to the commits that haven't
+been pulled from the upstream, or else the second section, then
+use: (((unpulled . \"..@{upstream}\") (status)) 1).
+
+See option `magit-section-initial-visibility-alist' for how to
+control the initial visibility of the jumped to section."
+ :package-version '(magit . "2.90.0")
+ :group 'magit-status
+ :type '(choice (const :tag "as usual" nil)
+ (repeat (choice (number :tag "nth top-level section")
+ (sexp :tag "section identity")))))
+
+(defcustom magit-status-goto-file-position nil
+ "Whether to go to position corresponding to file position.
+
+If this is non-nil and the current buffer is visiting a file,
+then `magit-status' tries to go to the position in the status
+buffer that corresponds to the position in the file-visiting
+buffer. This jumps into either the diff of unstaged changes
+or the diff of staged changes.
+
+If the previously current buffer does not visit a file, or if
+the file has neither unstaged nor staged changes then this has
+no effect.
+
+The command `magit-status-here' tries to go to that position,
+regardless of the value of this option."
+ :package-version '(magit . "3.0.0")
+ :group 'magit-status
+ :type 'boolean)
+
+(defcustom magit-status-show-hashes-in-headers nil
+ "Whether headers in the status buffer show hashes.
+The functions which respect this option are
+`magit-insert-head-branch-header',
+`magit-insert-upstream-branch-header', and
+`magit-insert-push-branch-header'."
+ :package-version '(magit . "2.4.0")
+ :group 'magit-status
+ :type 'boolean)
+
+(defcustom magit-status-margin
+ (list nil
+ (nth 1 magit-log-margin)
+ 'magit-log-margin-width nil
+ (nth 4 magit-log-margin))
+ "Format of the margin in `magit-status-mode' buffers.
+
+The value has the form (INIT STYLE WIDTH AUTHOR AUTHOR-WIDTH).
+
+If INIT is non-nil, then the margin is shown initially.
+STYLE controls how to format the author or committer date.
+ It can be one of `age' (to show the age of the commit),
+ `age-abbreviated' (to abbreviate the time unit to a character),
+ or a string (suitable for `format-time-string') to show the
+ actual date. Option `magit-log-margin-show-committer-date'
+ controls which date is being displayed.
+WIDTH controls the width of the margin. This exists for forward
+ compatibility and currently the value should not be changed.
+AUTHOR controls whether the name of the author is also shown by
+ default.
+AUTHOR-WIDTH has to be an integer. When the name of the author
+ is shown, then this specifies how much space is used to do so."
+ :package-version '(magit . "2.9.0")
+ :group 'magit-status
+ :group 'magit-margin
+ :type magit-log-margin--custom-type
+ :initialize #'magit-custom-initialize-reset
+ :set-after '(magit-log-margin)
+ :set (apply-partially #'magit-margin-set-variable 'magit-status-mode))
+
+(defcustom magit-status-use-buffer-arguments 'selected
+ "Whether `magit-status' reuses arguments when the buffer already exists.
+
+This option has no effect when merely refreshing the status
+buffer using `magit-refresh'.
+
+Valid values are:
+
+`always': Always use the set of arguments that is currently
+ active in the status buffer, provided that buffer exists
+ of course.
+`selected': Use the set of arguments from the status
+ buffer, but only if it is displayed in a window of the
+ current frame. This is the default.
+`current': Use the set of arguments from the status buffer,
+ but only if it is the current buffer.
+`never': Never use the set of arguments from the status
+ buffer."
+ :package-version '(magit . "3.0.0")
+ :group 'magit-buffers
+ :group 'magit-commands
+ :type '(choice
+ (const :tag "always use args from buffer" always)
+ (const :tag "use args from buffer if displayed in frame" selected)
+ (const :tag "use args from buffer if it is current" current)
+ (const :tag "never use args from buffer" never)))
+
+;;; Commands
+
+;;;###autoload
+(defun magit-init (directory)
+ "Initialize a Git repository, then show its status.
+
+If the directory is below an existing repository, then the user
+has to confirm that a new one should be created inside. If the
+directory is the root of the existing repository, then the user
+has to confirm that it should be reinitialized.
+
+Non-interactively DIRECTORY is (re-)initialized unconditionally."
+ (interactive
+ (let ((directory (file-name-as-directory
+ (expand-file-name
+ (read-directory-name "Create repository in: ")))))
+ (when-let ((toplevel (magit-toplevel directory)))
+ (setq toplevel (expand-file-name toplevel))
+ (unless (y-or-n-p (if (file-equal-p toplevel directory)
+ (format "Reinitialize existing repository %s? "
+ directory)
+ (format "%s is a repository. Create another in %s? "
+ toplevel directory)))
+ (user-error "Abort")))
+ (list directory)))
+ ;; `git init' does not understand the meaning of "~"!
+ (magit-call-git "init" (magit-convert-filename-for-git
+ (expand-file-name directory)))
+ (magit-status-setup-buffer directory))
+
+;;;###autoload
+(defun magit-status (&optional directory cache)
+ "Show the status of the current Git repository in a buffer.
+
+If the current directory isn't located within a Git repository,
+then prompt for an existing repository or an arbitrary directory,
+depending on option `magit-repository-directories', and show the
+status of the selected repository instead.
+
+* If that option specifies any existing repositories, then offer
+ those for completion and show the status buffer for the
+ selected one.
+
+* Otherwise read an arbitrary directory using regular file-name
+ completion. If the selected directory is the top-level of an
+ existing working tree, then show the status buffer for that.
+
+* Otherwise offer to initialize the selected directory as a new
+ repository. After creating the repository show its status
+ buffer.
+
+These fallback behaviors can also be forced using one or more
+prefix arguments:
+
+* With two prefix arguments (or more precisely a numeric prefix
+ value of 16 or greater) read an arbitrary directory and act on
+ it as described above. The same could be accomplished using
+ the command `magit-init'.
+
+* With a single prefix argument read an existing repository, or
+ if none can be found based on `magit-repository-directories',
+ then fall back to the same behavior as with two prefix
+ arguments."
+ (interactive
+ (let ((magit--refresh-cache (list (cons 0 0))))
+ (list (and (or current-prefix-arg (not (magit-toplevel)))
+ (progn (magit--assert-usable-git)
+ (magit-read-repository
+ (>= (prefix-numeric-value current-prefix-arg) 16))))
+ magit--refresh-cache)))
+ (let ((magit--refresh-cache (or cache (list (cons 0 0)))))
+ (if directory
+ (let ((toplevel (magit-toplevel directory)))
+ (setq directory (file-name-as-directory
+ (expand-file-name directory)))
+ (if (and toplevel (file-equal-p directory toplevel))
+ (magit-status-setup-buffer directory)
+ (when (y-or-n-p
+ (if toplevel
+ (format "%s is a repository. Create another in %s? "
+ toplevel directory)
+ (format "Create repository in %s? " directory)))
+ ;; Creating a new repository invalidates cached values.
+ (setq magit--refresh-cache nil)
+ (magit-init directory))))
+ (magit-status-setup-buffer default-directory))))
+
+(put 'magit-status 'interactive-only 'magit-status-setup-buffer)
+
+;;;###autoload
+(defalias 'magit #'magit-status
+ "An alias for `magit-status' for better discoverability.
+
+Instead of invoking this alias for `magit-status' using
+\"M-x magit RET\", you should bind a key to `magit-status'
+and read the info node `(magit)Getting Started', which
+also contains other useful hints.")
+
+;;;###autoload
+(defun magit-status-here ()
+ "Like `magit-status' but with non-nil `magit-status-goto-file-position'."
+ (interactive)
+ (let ((magit-status-goto-file-position t))
+ (call-interactively #'magit-status)))
+
+(put 'magit-status-here 'interactive-only 'magit-status-setup-buffer)
+
+;;;###autoload
+(defun magit-status-quick ()
+ "Show the status of the current Git repository, maybe without refreshing.
+
+If the status buffer of the current Git repository exists but
+isn't being displayed in the selected frame, then display it
+without refreshing it.
+
+If the status buffer is being displayed in the selected frame,
+then also refresh it.
+
+Prefix arguments have the same meaning as for `magit-status',
+and additionally cause the buffer to be refresh.
+
+To use this function instead of `magit-status', add this to your
+init file: (global-set-key (kbd \"C-x g\") 'magit-status-quick)."
+ (interactive)
+ (if-let ((buffer
+ (and (not current-prefix-arg)
+ (not (magit-get-mode-buffer 'magit-status-mode nil 'selected))
+ (magit-get-mode-buffer 'magit-status-mode))))
+ (magit-display-buffer buffer)
+ (call-interactively #'magit-status)))
+
+;;; Mode
+
+(defvar magit-status-mode-map
+ (let ((map (make-sparse-keymap)))
+ (set-keymap-parent map magit-mode-map)
+ (define-key map "j" #'magit-status-jump)
+ (define-key map [remap dired-jump] #'magit-dired-jump)
+ map)
+ "Keymap for `magit-status-mode'.")
+
+(transient-define-prefix magit-status-jump ()
+ "In a Magit-Status buffer, jump to a section."
+ ["Jump to"
+ [("z " "Stashes" magit-jump-to-stashes
+ :if (lambda () (memq 'magit-insert-stashes magit-status-sections-hook)))
+ ("t " "Tracked" magit-jump-to-tracked
+ :if (lambda () (memq 'magit-insert-tracked-files magit-status-sections-hook)))
+ ("n " "Untracked" magit-jump-to-untracked
+ :if (lambda () (memq 'magit-insert-untracked-files magit-status-sections-hook)))
+ ("u " "Unstaged" magit-jump-to-unstaged
+ :if (lambda () (memq 'magit-insert-unstaged-changes magit-status-sections-hook)))
+ ("s " "Staged" magit-jump-to-staged
+ :if (lambda () (memq 'magit-insert-staged-changes magit-status-sections-hook)))]
+ [("fu" "Unpulled from upstream" magit-jump-to-unpulled-from-upstream
+ :if (lambda () (memq 'magit-insert-unpulled-from-upstream magit-status-sections-hook)))
+ ("fp" "Unpulled from pushremote" magit-jump-to-unpulled-from-pushremote
+ :if (lambda () (memq 'magit-insert-unpulled-from-pushremote magit-status-sections-hook)))
+ ("pu" magit-jump-to-unpushed-to-upstream
+ :if (lambda ()
+ (or (memq 'magit-insert-unpushed-to-upstream-or-recent magit-status-sections-hook)
+ (memq 'magit-insert-unpushed-to-upstream magit-status-sections-hook)))
+ :description (lambda ()
+ (let ((upstream (magit-get-upstream-branch)))
+ (if (or (not upstream)
+ (magit-rev-ancestor-p "HEAD" upstream))
+ "Recent commits"
+ "Unmerged into upstream"))))
+ ("pp" "Unpushed to pushremote" magit-jump-to-unpushed-to-pushremote
+ :if (lambda () (memq 'magit-insert-unpushed-to-pushremote magit-status-sections-hook)))
+ ("a " "Assumed unstaged" magit-jump-to-assume-unchanged
+ :if (lambda () (memq 'magit-insert-assume-unchanged-files magit-status-sections-hook)))
+ ("w " "Skip worktree" magit-jump-to-skip-worktree
+ :if (lambda () (memq 'magit-insert-skip-worktree-files magit-status-sections-hook)))]
+ [("i" "Using Imenu" imenu)]])
+
+(define-derived-mode magit-status-mode magit-mode "Magit"
+ "Mode for looking at Git status.
+
+This mode is documented in info node `(magit)Status Buffer'.
+
+\\<magit-mode-map>\
+Type \\[magit-refresh] to refresh the current buffer.
+Type \\[magit-section-toggle] to expand or hide the section at point.
+Type \\[magit-visit-thing] to visit the change or commit at point.
+
+Type \\[magit-dispatch] to invoke major commands.
+
+Staging and applying changes is documented in info node
+`(magit)Staging and Unstaging' and info node `(magit)Applying'.
+
+\\<magit-hunk-section-map>Type \
+\\[magit-apply] to apply the change at point, \
+\\[magit-stage] to stage,
+\\[magit-unstage] to unstage, \
+\\[magit-discard] to discard, or \
+\\[magit-reverse] to reverse it.
+
+\\<magit-status-mode-map>\
+Type \\[magit-commit] to create a commit.
+
+\\{magit-status-mode-map}"
+ :group 'magit-status
+ (hack-dir-local-variables-non-file-buffer)
+ (setq magit--imenu-group-types '(not branch commit)))
+
+(put 'magit-status-mode 'magit-diff-default-arguments
+ '("--no-ext-diff"))
+(put 'magit-status-mode 'magit-log-default-arguments
+ '("-n256" "--decorate"))
+
+;;;###autoload
+(defun magit-status-setup-buffer (&optional directory)
+ (unless directory
+ (setq directory default-directory))
+ (when (file-remote-p directory)
+ (magit-git-version-assert))
+ (let* ((default-directory directory)
+ (d (magit-diff--get-value 'magit-status-mode
+ magit-status-use-buffer-arguments))
+ (l (magit-log--get-value 'magit-status-mode
+ magit-status-use-buffer-arguments))
+ (file (and magit-status-goto-file-position
+ (magit-file-relative-name)))
+ (line (and file (line-number-at-pos)))
+ (col (and file (current-column)))
+ (buf (magit-setup-buffer #'magit-status-mode nil
+ (magit-buffer-diff-args (nth 0 d))
+ (magit-buffer-diff-files (nth 1 d))
+ (magit-buffer-log-args (nth 0 l))
+ (magit-buffer-log-files (nth 1 l)))))
+ (when file
+ (with-current-buffer buf
+ (let ((staged (magit-get-section '((staged) (status)))))
+ (if (and staged
+ (cadr (magit-diff--locate-hunk file line staged)))
+ (magit-diff--goto-position file line col staged)
+ (let ((unstaged (magit-get-section '((unstaged) (status)))))
+ (unless (and unstaged
+ (magit-diff--goto-position file line col unstaged))
+ (when staged
+ (magit-diff--goto-position file line col staged))))))))
+ buf))
+
+(defun magit-status-refresh-buffer ()
+ (magit-git-exit-code "update-index" "--refresh")
+ (magit-insert-section (status)
+ (magit-run-section-hook 'magit-status-sections-hook)))
+
+(defun magit-status-goto-initial-section ()
+ "In a `magit-status-mode' buffer, jump `magit-status-initial-section'.
+Actually doing so is deferred until `magit-refresh-buffer-hook'
+runs `magit-status-goto-initial-section-1'. That function then
+removes itself from the hook, so that this only happens when the
+status buffer is first created."
+ (when (and magit-status-initial-section
+ (derived-mode-p 'magit-status-mode))
+ (add-hook 'magit-refresh-buffer-hook
+ #'magit-status-goto-initial-section-1 nil t)))
+
+(defun magit-status-goto-initial-section-1 ()
+ "In a `magit-status-mode' buffer, jump `magit-status-initial-section'.
+This function removes itself from `magit-refresh-buffer-hook'."
+ (when-let ((section
+ (--some (if (integerp it)
+ (nth (1- it)
+ (magit-section-siblings (magit-current-section)
+ 'next))
+ (magit-get-section it))
+ magit-status-initial-section)))
+ (goto-char (oref section start))
+ (when-let ((vis (cdr (assq 'magit-status-initial-section
+ magit-section-initial-visibility-alist))))
+ (if (eq vis 'hide)
+ (magit-section-hide section)
+ (magit-section-show section))))
+ (remove-hook 'magit-refresh-buffer-hook
+ #'magit-status-goto-initial-section-1 t))
+
+(defun magit-status-maybe-update-revision-buffer (&optional _)
+ "When moving in the status buffer, update the revision buffer.
+If there is no revision buffer in the same frame, then do nothing."
+ (when (derived-mode-p 'magit-status-mode)
+ (magit--maybe-update-revision-buffer)))
+
+(defun magit-status-maybe-update-stash-buffer (&optional _)
+ "When moving in the status buffer, update the stash buffer.
+If there is no stash buffer in the same frame, then do nothing."
+ (when (derived-mode-p 'magit-status-mode)
+ (magit--maybe-update-stash-buffer)))
+
+(defun magit-status-maybe-update-blob-buffer (&optional _)
+ "When moving in the status buffer, update the blob buffer.
+If there is no blob buffer in the same frame, then do nothing."
+ (when (derived-mode-p 'magit-status-mode)
+ (magit--maybe-update-blob-buffer)))
+
+;;; Sections
+;;;; Special Headers
+
+(defun magit-insert-status-headers ()
+ "Insert header sections appropriate for `magit-status-mode' buffers.
+The sections are inserted by running the functions on the hook
+`magit-status-headers-hook'."
+ (if (magit-rev-verify "HEAD")
+ (magit-insert-headers 'magit-status-headers-hook)
+ (insert "In the beginning there was darkness\n\n")))
+
+(defvar magit-error-section-map
+ (let ((map (make-sparse-keymap)))
+ (magit-menu-set map [magit-visit-thing]
+ #'magit-process-buffer "Visit process output")
+ map)
+ "Keymap for `error' sections.")
+
+(defun magit-insert-error-header ()
+ "Insert the message about the Git error that just occurred.
+
+This function is only aware of the last error that occur when Git
+was run for side-effects. If, for example, an error occurs while
+generating a diff, then that error won't be inserted. Refreshing
+the status buffer causes this section to disappear again."
+ (when magit-this-error
+ (magit-insert-section (error 'git)
+ (insert (propertize (format "%-10s" "GitError! ")
+ 'font-lock-face 'magit-section-heading))
+ (insert (propertize magit-this-error 'font-lock-face 'error))
+ (when-let ((key (car (where-is-internal 'magit-process-buffer))))
+ (insert (format " [Type `%s' for details]" (key-description key))))
+ (insert ?\n))
+ (setq magit-this-error nil)))
+
+(defun magit-insert-diff-filter-header ()
+ "Insert a header line showing the effective diff filters."
+ (let ((ignore-modules (magit-ignore-submodules-p)))
+ (when (or ignore-modules
+ magit-buffer-diff-files)
+ (insert (propertize (format "%-10s" "Filter! ")
+ 'font-lock-face 'magit-section-heading))
+ (when ignore-modules
+ (insert ignore-modules)
+ (when magit-buffer-diff-files
+ (insert " -- ")))
+ (when magit-buffer-diff-files
+ (insert (mapconcat #'identity magit-buffer-diff-files " ")))
+ (insert ?\n))))
+
+;;;; Reference Headers
+
+(defun magit-insert-head-branch-header (&optional branch)
+ "Insert a header line about the current branch.
+If `HEAD' is detached, then insert information about that commit
+instead. The optional BRANCH argument is for internal use only."
+ (let ((branch (or branch (magit-get-current-branch)))
+ (output (magit-rev-format "%h %s" (or branch "HEAD"))))
+ (string-match "^\\([^ ]+\\) \\(.*\\)" output)
+ (magit-bind-match-strings (commit summary) output
+ (when (equal summary "")
+ (setq summary "(no commit message)"))
+ (if branch
+ (magit-insert-section (branch branch)
+ (insert (format "%-10s" "Head: "))
+ (when magit-status-show-hashes-in-headers
+ (insert (propertize commit 'font-lock-face 'magit-hash) ?\s))
+ (insert (propertize branch 'font-lock-face 'magit-branch-local))
+ (insert ?\s)
+ (insert (funcall magit-log-format-message-function branch summary))
+ (insert ?\n))
+ (magit-insert-section (commit commit)
+ (insert (format "%-10s" "Head: "))
+ (insert (propertize commit 'font-lock-face 'magit-hash))
+ (insert ?\s)
+ (insert (funcall magit-log-format-message-function nil summary))
+ (insert ?\n))))))
+
+(defun magit-insert-upstream-branch-header (&optional branch upstream keyword)
+ "Insert a header line about the upstream of the current branch.
+If no branch is checked out, then insert nothing. The optional
+arguments are for internal use only."
+ (when-let ((branch (or branch (magit-get-current-branch))))
+ (let ((remote (magit-get "branch" branch "remote"))
+ (merge (magit-get "branch" branch "merge"))
+ (rebase (magit-get "branch" branch "rebase")))
+ (when (or remote merge)
+ (unless upstream
+ (setq upstream (magit-get-upstream-branch branch)))
+ (magit-insert-section (branch upstream)
+ (pcase rebase
+ ("true")
+ ("false" (setq rebase nil))
+ (_ (setq rebase (magit-get-boolean "pull.rebase"))))
+ (insert (format "%-10s" (or keyword (if rebase "Rebase: " "Merge: "))))
+ (insert
+ (if upstream
+ (concat (and magit-status-show-hashes-in-headers
+ (concat (propertize (magit-rev-format "%h" upstream)
+ 'font-lock-face 'magit-hash)
+ " "))
+ upstream " "
+ (funcall magit-log-format-message-function upstream
+ (funcall magit-log-format-message-function nil
+ (or (magit-rev-format "%s" upstream)
+ "(no commit message)"))))
+ (cond
+ ((magit--unnamed-upstream-p remote merge)
+ (concat (propertize merge 'font-lock-face 'magit-branch-remote)
+ " from "
+ (propertize remote 'font-lock-face 'bold)))
+ ((magit--valid-upstream-p remote merge)
+ (if (equal remote ".")
+ (concat
+ (propertize merge 'font-lock-face 'magit-branch-local) " "
+ (propertize "does not exist"
+ 'font-lock-face 'magit-branch-warning))
+ (format
+ "%s %s %s"
+ (propertize merge 'font-lock-face 'magit-branch-remote)
+ (propertize "does not exist on"
+ 'font-lock-face 'magit-branch-warning)
+ (propertize remote 'font-lock-face 'magit-branch-remote))))
+ (t
+ (propertize "invalid upstream configuration"
+ 'font-lock-face 'magit-branch-warning)))))
+ (insert ?\n))))))
+
+(defun magit-insert-push-branch-header ()
+ "Insert a header line about the branch the current branch is pushed to."
+ (when-let* ((branch (magit-get-current-branch))
+ (target (magit-get-push-branch branch)))
+ (magit-insert-section (branch target)
+ (insert (format "%-10s" "Push: "))
+ (insert
+ (if (magit-rev-verify target)
+ (concat (and magit-status-show-hashes-in-headers
+ (concat (propertize (magit-rev-format "%h" target)
+ 'font-lock-face 'magit-hash)
+ " "))
+ target " "
+ (funcall magit-log-format-message-function target
+ (funcall magit-log-format-message-function nil
+ (or (magit-rev-format "%s" target)
+ "(no commit message)"))))
+ (let ((remote (magit-get-push-remote branch)))
+ (if (magit-remote-p remote)
+ (concat target " "
+ (propertize "does not exist"
+ 'font-lock-face 'magit-branch-warning))
+ (concat remote " "
+ (propertize "remote does not exist"
+ 'font-lock-face 'magit-branch-warning))))))
+ (insert ?\n))))
+
+(defun magit-insert-tags-header ()
+ "Insert a header line about the current and/or next tag."
+ (let* ((this-tag (magit-get-current-tag nil t))
+ (next-tag (magit-get-next-tag nil t))
+ (this-cnt (cadr this-tag))
+ (next-cnt (cadr next-tag))
+ (this-tag (car this-tag))
+ (next-tag (car next-tag))
+ (both-tags (and this-tag next-tag t)))
+ (when (or this-tag next-tag)
+ (magit-insert-section (tag (or this-tag next-tag))
+ (insert (format "%-10s" (if both-tags "Tags: " "Tag: ")))
+ (cl-flet ((insert-count (tag count face)
+ (insert (concat (propertize tag 'font-lock-face 'magit-tag)
+ (and (> count 0)
+ (format " (%s)"
+ (propertize
+ (format "%s" count)
+ 'font-lock-face face)))))))
+ (when this-tag (insert-count this-tag this-cnt 'magit-branch-local))
+ (when both-tags (insert ", "))
+ (when next-tag (insert-count next-tag next-cnt 'magit-tag)))
+ (insert ?\n)))))
+
+;;;; Auxiliary Headers
+
+(defun magit-insert-user-header ()
+ "Insert a header line about the current user."
+ (let ((name (magit-get "user.name"))
+ (email (magit-get "user.email")))
+ (when (and name email)
+ (magit-insert-section (user name)
+ (insert (format "%-10s" "User: "))
+ (insert (propertize name 'font-lock-face 'magit-log-author))
+ (insert " <" email ">\n")))))
+
+(defun magit-insert-repo-header ()
+ "Insert a header line showing the path to the repository top-level."
+ (let ((topdir (magit-toplevel)))
+ (magit-insert-section (repo topdir)
+ (insert (format "%-10s%s\n" "Repo: " (abbreviate-file-name topdir))))))
+
+(defun magit-insert-remote-header ()
+ "Insert a header line about the remote of the current branch.
+
+If no remote is configured for the current branch, then fall back
+showing the \"origin\" remote, or if that does not exist the first
+remote in alphabetic order."
+ (when-let* ((name (magit-get-some-remote))
+ ;; Under certain configurations it's possible for
+ ;; url to be nil, when name is not, see #2858.
+ (url (magit-get "remote" name "url")))
+ (magit-insert-section (remote name)
+ (insert (format "%-10s" "Remote: "))
+ (insert (propertize name 'font-lock-face 'magit-branch-remote) ?\s)
+ (insert url ?\n))))
+
+;;;; File Sections
+
+(defvar magit-untracked-section-map
+ (let ((map (make-sparse-keymap)))
+ (magit-menu-set map [magit-stage-file] #'magit-stage "Stage files")
+ (magit-menu-set map [magit-delete-thing] #'magit-discard "Discard files")
+ map)
+ "Keymap for the `untracked' section.")
+
+(magit-define-section-jumper magit-jump-to-untracked "Untracked files" untracked)
+
+(defun magit-insert-untracked-files ()
+ "Maybe insert a list or tree of untracked files.
+
+Do so depending on the value of `status.showUntrackedFiles'.
+Note that even if the value is `all', Magit still initially
+only shows directories. But the directory sections can then
+be expanded using \"TAB\".
+
+If the first element of `magit-buffer-diff-files' is a
+directory, then limit the list to files below that. The value
+value of that variable can be set using \"D -- DIRECTORY RET g\"."
+ (let* ((show (or (magit-get "status.showUntrackedFiles") "normal"))
+ (base (car magit-buffer-diff-files))
+ (base (and base (file-directory-p base) base)))
+ (unless (equal show "no")
+ (if (equal show "all")
+ (when-let ((files (magit-untracked-files nil base)))
+ (magit-insert-section (untracked)
+ (magit-insert-heading "Untracked files:")
+ (magit-insert-files files base)
+ (insert ?\n)))
+ (when-let ((files
+ (--mapcat (and (eq (aref it 0) ??)
+ (list (substring it 3)))
+ (magit-git-items "status" "-z" "--porcelain"
+ (magit-ignore-submodules-p t)
+ "--" base))))
+ (magit-insert-section (untracked)
+ (magit-insert-heading "Untracked files:")
+ (dolist (file files)
+ (magit-insert-section (file file)
+ (insert (propertize file 'font-lock-face 'magit-filename) ?\n)))
+ (insert ?\n)))))))
+
+(magit-define-section-jumper magit-jump-to-tracked "Tracked files" tracked)
+
+(defun magit-insert-tracked-files ()
+ "Insert a tree of tracked files.
+
+If the first element of `magit-buffer-diff-files' is a
+directory, then limit the list to files below that. The value
+value of that variable can be set using \"D -- DIRECTORY RET g\"."
+ (when-let ((files (magit-list-files)))
+ (let* ((base (car magit-buffer-diff-files))
+ (base (and base (file-directory-p base) base)))
+ (magit-insert-section (tracked nil t)
+ (magit-insert-heading "Tracked files:")
+ (magit-insert-files files base)
+ (insert ?\n)))))
+
+(defun magit-insert-ignored-files ()
+ "Insert a tree of ignored files.
+
+If the first element of `magit-buffer-diff-files' is a
+directory, then limit the list to files below that. The value
+of that variable can be set using \"D -- DIRECTORY RET g\"."
+ (when-let ((files (magit-ignored-files)))
+ (let* ((base (car magit-buffer-diff-files))
+ (base (and base (file-directory-p base) base)))
+ (magit-insert-section (tracked nil t)
+ (magit-insert-heading "Ignored files:")
+ (magit-insert-files files base)
+ (insert ?\n)))))
+
+(magit-define-section-jumper magit-jump-to-skip-worktree "Skip-worktree files" skip-worktree)
+
+(defun magit-insert-skip-worktree-files ()
+ "Insert a tree of skip-worktree files.
+
+If the first element of `magit-buffer-diff-files' is a
+directory, then limit the list to files below that. The value
+of that variable can be set using \"D -- DIRECTORY RET g\"."
+ (when-let ((files (magit-skip-worktree-files)))
+ (let* ((base (car magit-buffer-diff-files))
+ (base (and base (file-directory-p base) base)))
+ (magit-insert-section (skip-worktree nil t)
+ (magit-insert-heading "Skip-worktree files:")
+ (magit-insert-files files base)
+ (insert ?\n)))))
+
+(magit-define-section-jumper magit-jump-to-assume-unchanged "Assume-unchanged files" assume-unchanged)
+
+(defun magit-insert-assume-unchanged-files ()
+ "Insert a tree of files that are assumed to be unchanged.
+
+If the first element of `magit-buffer-diff-files' is a
+directory, then limit the list to files below that. The value
+of that variable can be set using \"D -- DIRECTORY RET g\"."
+ (when-let ((files (magit-assume-unchanged-files)))
+ (let* ((base (car magit-buffer-diff-files))
+ (base (and base (file-directory-p base) base)))
+ (magit-insert-section (assume-unchanged nil t)
+ (magit-insert-heading "Assume-unchanged files:")
+ (magit-insert-files files base)
+ (insert ?\n)))))
+
+(defun magit-insert-files (files directory)
+ (while (and files (string-prefix-p (or directory "") (car files)))
+ (let ((dir (file-name-directory (car files))))
+ (if (equal dir directory)
+ (let ((file (pop files)))
+ (magit-insert-section (file file)
+ (insert (propertize file 'font-lock-face 'magit-filename) ?\n)))
+ (magit-insert-section (file dir t)
+ (insert (propertize dir 'file 'magit-filename) ?\n)
+ (magit-insert-heading)
+ (setq files (magit-insert-files files dir))))))
+ files)
+
+;;; _
+(provide 'magit-status)
+;;; magit-status.el ends here
diff --git a/elpa/magit-20220503.1245/magit-status.elc b/elpa/magit-20220503.1245/magit-status.elc
new file mode 100644
index 0000000..7651559
--- /dev/null
+++ b/elpa/magit-20220503.1245/magit-status.elc
Binary files differ
diff --git a/elpa/magit-20220503.1245/magit-submodule.el b/elpa/magit-20220503.1245/magit-submodule.el
new file mode 100644
index 0000000..2179fa1
--- /dev/null
+++ b/elpa/magit-20220503.1245/magit-submodule.el
@@ -0,0 +1,719 @@
+;;; magit-submodule.el --- Submodule support for Magit -*- lexical-binding:t -*-
+
+;; Copyright (C) 2008-2022 The Magit Project Contributors
+
+;; Author: Jonas Bernoulli <jonas@bernoul.li>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+
+;; SPDX-License-Identifier: GPL-3.0-or-later
+
+;; Magit 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.
+;;
+;; Magit 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 Magit. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Code:
+
+(require 'magit)
+
+(defvar x-stretch-cursor)
+
+;;; Options
+
+(defcustom magit-module-sections-hook
+ '(magit-insert-modules-overview
+ magit-insert-modules-unpulled-from-upstream
+ magit-insert-modules-unpulled-from-pushremote
+ magit-insert-modules-unpushed-to-upstream
+ magit-insert-modules-unpushed-to-pushremote)
+ "Hook run by `magit-insert-modules'.
+
+That function isn't part of `magit-status-sections-hook's default
+value, so you have to add it yourself for this hook to have any
+effect."
+ :package-version '(magit . "2.11.0")
+ :group 'magit-status
+ :type 'hook)
+
+(defcustom magit-module-sections-nested t
+ "Whether `magit-insert-modules' wraps inserted sections.
+
+If this is non-nil, then only a single top-level section
+is inserted. If it is nil, then all sections listed in
+`magit-module-sections-hook' become top-level sections."
+ :package-version '(magit . "2.11.0")
+ :group 'magit-status
+ :type 'boolean)
+
+(defcustom magit-submodule-list-mode-hook '(hl-line-mode)
+ "Hook run after entering Magit-Submodule-List mode."
+ :package-version '(magit . "2.9.0")
+ :group 'magit-repolist
+ :type 'hook
+ :get 'magit-hook-custom-get
+ :options '(hl-line-mode))
+
+(defcustom magit-submodule-list-columns
+ '(("Path" 25 magit-modulelist-column-path nil)
+ ("Version" 25 magit-repolist-column-version
+ ((:sort magit-repolist-version<)))
+ ("Branch" 20 magit-repolist-column-branch nil)
+ ("B<U" 3 magit-repolist-column-unpulled-from-upstream
+ ((:right-align t)
+ (:sort <)))
+ ("B>U" 3 magit-repolist-column-unpushed-to-upstream
+ ((:right-align t)
+ (:sort <)))
+ ("B<P" 3 magit-repolist-column-unpulled-from-pushremote
+ ((:right-align t)
+ (:sort <)))
+ ("B>P" 3 magit-repolist-column-unpushed-to-pushremote
+ ((:right-align t)
+ (:sort <)))
+ ("B" 3 magit-repolist-column-branches
+ ((:right-align t)
+ (:sort <)))
+ ("S" 3 magit-repolist-column-stashes
+ ((:right-align t)
+ (:sort <))))
+ "List of columns displayed by `magit-list-submodules'.
+
+Each element has the form (HEADER WIDTH FORMAT PROPS).
+
+HEADER is the string displayed in the header. WIDTH is the width
+of the column. FORMAT is a function that is called with one
+argument, the repository identification (usually its basename),
+and with `default-directory' bound to the toplevel of its working
+tree. It has to return a string to be inserted or nil. PROPS is
+an alist that supports the keys `:right-align', `:pad-right' and
+`:sort'.
+
+The `:sort' function has a weird interface described in the
+docstring of `tabulated-list--get-sort'. Alternatively `<' and
+`magit-repolist-version<' can be used as those functions are
+automatically replaced with functions that satisfy the interface.
+Set `:sort' to nil to inhibit sorting; if unspecifed, then the
+column is sortable using the default sorter.
+
+You may wish to display a range of numeric columns using just one
+character per column and without any padding between columns, in
+which case you should use an appropriat HEADER, set WIDTH to 1,
+and set `:pad-right' to 0. \"+\" is substituted for numbers higher
+than 9."
+ :package-version '(magit . "2.8.0")
+ :group 'magit-repolist
+ :type `(repeat (list :tag "Column"
+ (string :tag "Header Label")
+ (integer :tag "Column Width")
+ (function :tag "Inserter Function")
+ (repeat :tag "Properties"
+ (list (choice :tag "Property"
+ (const :right-align)
+ (const :pad-right)
+ (const :sort)
+ (symbol))
+ (sexp :tag "Value"))))))
+
+(defcustom magit-submodule-list-sort-key '("Path" . nil)
+ "Initial sort key for buffer created by `magit-list-submodules'.
+If nil, no additional sorting is performed. Otherwise, this
+should be a cons cell (NAME . FLIP). NAME is a string matching
+one of the column names in `magit-submodule-list-columns'. FLIP,
+if non-nil, means to invert the resulting sort."
+ :package-version '(magit . "3.2.0")
+ :group 'magit-repolist
+ :type '(choice (const nil)
+ (cons (string :tag "Column name")
+ (boolean :tag "Flip order"))))
+
+(defcustom magit-submodule-remove-trash-gitdirs nil
+ "Whether `magit-submodule-remove' offers to trash module gitdirs.
+
+If this is nil, then that command does not offer to do so unless
+a prefix argument is used. When this is t, then it does offer to
+do so even without a prefix argument.
+
+In both cases the action still has to be confirmed unless that is
+disabled using the option `magit-no-confirm'. Doing the latter
+and also setting this variable to t will lead to tears."
+ :package-version '(magit . "2.90.0")
+ :group 'magit-commands
+ :type 'boolean)
+
+;;; Popup
+
+;;;###autoload (autoload 'magit-submodule "magit-submodule" nil t)
+(transient-define-prefix magit-submodule ()
+ "Act on a submodule."
+ :man-page "git-submodule"
+ ["Arguments"
+ ("-f" "Force" ("-f" "--force"))
+ ("-r" "Recursive" "--recursive")
+ ("-N" "Do not fetch" ("-N" "--no-fetch"))
+ ("-C" "Checkout tip" "--checkout")
+ ("-R" "Rebase onto tip" "--rebase")
+ ("-M" "Merge tip" "--merge")
+ ("-U" "Use upstream tip" "--remote")]
+ ["One module actions"
+ ("a" magit-submodule-add)
+ ("r" magit-submodule-register)
+ ("p" magit-submodule-populate)
+ ("u" magit-submodule-update)
+ ("s" magit-submodule-synchronize)
+ ("d" magit-submodule-unpopulate)
+ ("k" "Remove" magit-submodule-remove)]
+ ["All modules actions"
+ ("l" "List all modules" magit-list-submodules)
+ ("f" "Fetch all modules" magit-fetch-modules)])
+
+(defun magit-submodule-arguments (&rest filters)
+ (--filter (and (member it filters) it)
+ (transient-args 'magit-submodule)))
+
+(defclass magit--git-submodule-suffix (transient-suffix)
+ ())
+
+(cl-defmethod transient-format-description ((obj magit--git-submodule-suffix))
+ (let ((value (delq nil (mapcar #'transient-infix-value transient--suffixes))))
+ (replace-regexp-in-string
+ "\\[--[^]]+\\]"
+ (lambda (match)
+ (format (propertize "[%s]" 'face 'transient-inactive-argument)
+ (mapconcat (lambda (arg)
+ (propertize arg 'face
+ (if (member arg value)
+ 'transient-argument
+ 'transient-inactive-argument)))
+ (save-match-data
+ (split-string (substring match 1 -1) "|"))
+ (propertize "|" 'face 'transient-inactive-argument))))
+ (cl-call-next-method obj))))
+
+;;;###autoload (autoload 'magit-submodule-add "magit-submodule" nil t)
+(transient-define-suffix magit-submodule-add (url &optional path name args)
+ "Add the repository at URL as a module.
+
+Optional PATH is the path to the module relative to the root of
+the superproject. If it is nil, then the path is determined
+based on the URL. Optional NAME is the name of the module. If
+it is nil, then PATH also becomes the name."
+ :class 'magit--git-submodule-suffix
+ :description "Add git submodule add [--force]"
+ (interactive
+ (magit-with-toplevel
+ (let* ((url (magit-read-string-ns "Add submodule (remote url)"))
+ (path (let ((read-file-name-function
+ (if (or (eq read-file-name-function 'ido-read-file-name)
+ (advice-function-member-p
+ 'ido-read-file-name
+ read-file-name-function))
+ ;; The Ido variant doesn't work properly here.
+ #'read-file-name-default
+ read-file-name-function)))
+ (directory-file-name
+ (file-relative-name
+ (read-directory-name
+ "Add submodules at path: " nil nil nil
+ (and (string-match "\\([^./]+\\)\\(\\.git\\)?$" url)
+ (match-string 1 url))))))))
+ (list url
+ (directory-file-name path)
+ (magit-submodule-read-name-for-path path)
+ (magit-submodule-arguments "--force")))))
+ (magit-submodule-add-1 url path name args))
+
+(defun magit-submodule-add-1 (url &optional path name args)
+ (magit-with-toplevel
+ (magit-submodule--maybe-reuse-gitdir name path)
+ (magit-run-git-async "submodule" "add"
+ (and name (list "--name" name))
+ args "--" url path)
+ (set-process-sentinel
+ magit-this-process
+ (lambda (process event)
+ (when (memq (process-status process) '(exit signal))
+ (if (> (process-exit-status process) 0)
+ (magit-process-sentinel process event)
+ (process-put process 'inhibit-refresh t)
+ (magit-process-sentinel process event)
+ (when (magit-git-version>= "2.12.0")
+ (magit-call-git "submodule" "absorbgitdirs" path))
+ (magit-refresh)))))))
+
+;;;###autoload
+(defun magit-submodule-read-name-for-path (path &optional prefer-short)
+ (let* ((path (directory-file-name (file-relative-name path)))
+ (name (file-name-nondirectory path)))
+ (push (if prefer-short path name) minibuffer-history)
+ (magit-read-string-ns
+ "Submodule name" nil (cons 'minibuffer-history 2)
+ (or (--keep (pcase-let ((`(,var ,val) (split-string it "=")))
+ (and (equal val path)
+ (cadr (split-string var "\\."))))
+ (magit-git-lines "config" "--list" "-f" ".gitmodules"))
+ (if prefer-short name path)))))
+
+;;;###autoload (autoload 'magit-submodule-register "magit-submodule" nil t)
+(transient-define-suffix magit-submodule-register (modules)
+ "Register MODULES.
+
+With a prefix argument act on all suitable modules. Otherwise,
+if the region selects modules, then act on those. Otherwise, if
+there is a module at point, then act on that. Otherwise read a
+single module from the user."
+ ;; This command and the underlying "git submodule init" do NOT
+ ;; "initialize" modules. They merely "register" modules in the
+ ;; super-projects $GIT_DIR/config file, the purpose of which is to
+ ;; allow users to change such values before actually initializing
+ ;; the modules.
+ :description "Register git submodule init"
+ (interactive
+ (list (magit-module-confirm "Register" 'magit-module-no-worktree-p)))
+ (magit-with-toplevel
+ (magit-run-git-async "submodule" "init" "--" modules)))
+
+;;;###autoload (autoload 'magit-submodule-populate "magit-submodule" nil t)
+(transient-define-suffix magit-submodule-populate (modules)
+ "Create MODULES working directories, checking out the recorded commits.
+
+With a prefix argument act on all suitable modules. Otherwise,
+if the region selects modules, then act on those. Otherwise, if
+there is a module at point, then act on that. Otherwise read a
+single module from the user."
+ ;; This is the command that actually "initializes" modules.
+ ;; A module is initialized when it has a working directory,
+ ;; a gitlink, and a .gitmodules entry.
+ :description "Populate git submodule update --init"
+ (interactive
+ (list (magit-module-confirm "Populate" 'magit-module-no-worktree-p)))
+ (magit-with-toplevel
+ (magit-run-git-async "submodule" "update" "--init" "--" modules)))
+
+;;;###autoload (autoload 'magit-submodule-update "magit-submodule" nil t)
+(transient-define-suffix magit-submodule-update (modules args)
+ "Update MODULES by checking out the recorded commits.
+
+With a prefix argument act on all suitable modules. Otherwise,
+if the region selects modules, then act on those. Otherwise, if
+there is a module at point, then act on that. Otherwise read a
+single module from the user."
+ ;; Unlike `git-submodule's `update' command ours can only update
+ ;; "initialized" modules by checking out other commits but not
+ ;; "initialize" modules by creating the working directories.
+ ;; To do the latter we provide the "setup" command.
+ :class 'magit--git-submodule-suffix
+ :description "Update git submodule update [--force] [--no-fetch]
+ [--remote] [--recursive] [--checkout|--rebase|--merge]"
+ (interactive
+ (list (magit-module-confirm "Update" 'magit-module-worktree-p)
+ (magit-submodule-arguments
+ "--force" "--remote" "--recursive" "--checkout" "--rebase" "--merge"
+ "--no-fetch")))
+ (magit-with-toplevel
+ (magit-run-git-async "submodule" "update" args "--" modules)))
+
+;;;###autoload (autoload 'magit-submodule-synchronize "magit-submodule" nil t)
+(transient-define-suffix magit-submodule-synchronize (modules args)
+ "Synchronize url configuration of MODULES.
+
+With a prefix argument act on all suitable modules. Otherwise,
+if the region selects modules, then act on those. Otherwise, if
+there is a module at point, then act on that. Otherwise read a
+single module from the user."
+ :class 'magit--git-submodule-suffix
+ :description "Synchronize git submodule sync [--recursive]"
+ (interactive
+ (list (magit-module-confirm "Synchronize" 'magit-module-worktree-p)
+ (magit-submodule-arguments "--recursive")))
+ (magit-with-toplevel
+ (magit-run-git-async "submodule" "sync" args "--" modules)))
+
+;;;###autoload (autoload 'magit-submodule-unpopulate "magit-submodule" nil t)
+(transient-define-suffix magit-submodule-unpopulate (modules args)
+ "Remove working directories of MODULES.
+
+With a prefix argument act on all suitable modules. Otherwise,
+if the region selects modules, then act on those. Otherwise, if
+there is a module at point, then act on that. Otherwise read a
+single module from the user."
+ ;; Even though a package is "uninitialized" (it has no worktree)
+ ;; the super-projects $GIT_DIR/config may never-the-less set the
+ ;; module's url. This may happen if you `deinit' and then `init'
+ ;; to register (NOT initialize). Because the purpose of `deinit'
+ ;; is to remove the working directory AND to remove the url, this
+ ;; command does not limit itself to modules that have no working
+ ;; directory.
+ :class 'magit--git-submodule-suffix
+ :description "Unpopulate git submodule deinit [--force]"
+ (interactive
+ (list (magit-module-confirm "Unpopulate")
+ (magit-submodule-arguments "--force")))
+ (magit-with-toplevel
+ (magit-run-git-async "submodule" "deinit" args "--" modules)))
+
+;;;###autoload
+(defun magit-submodule-remove (modules args trash-gitdirs)
+ "Unregister MODULES and remove their working directories.
+
+For safety reasons, do not remove the gitdirs and if a module has
+uncommitted changes, then do not remove it at all. If a module's
+gitdir is located inside the working directory, then move it into
+the gitdir of the superproject first.
+
+With the \"--force\" argument offer to remove dirty working
+directories and with a prefix argument offer to delete gitdirs.
+Both actions are very dangerous and have to be confirmed. There
+are additional safety precautions in place, so you might be able
+to recover from making a mistake here, but don't count on it."
+ (interactive
+ (list (if-let ((modules (magit-region-values 'magit-module-section t)))
+ (magit-confirm 'remove-modules nil "Remove %i modules" nil modules)
+ (list (magit-read-module-path "Remove module")))
+ (magit-submodule-arguments "--force")
+ current-prefix-arg))
+ (when (magit-git-version< "2.12.0")
+ (error "This command requires Git v2.12.0"))
+ (when magit-submodule-remove-trash-gitdirs
+ (setq trash-gitdirs t))
+ (magit-with-toplevel
+ (when-let
+ ((modified
+ (-filter (lambda (module)
+ (let ((default-directory (file-name-as-directory
+ (expand-file-name module))))
+ (and (cddr (directory-files default-directory))
+ (magit-anything-modified-p))))
+ modules)))
+ (if (member "--force" args)
+ (if (magit-confirm 'remove-dirty-modules
+ "Remove dirty module %s"
+ "Remove %i dirty modules"
+ t modified)
+ (dolist (module modified)
+ (let ((default-directory (file-name-as-directory
+ (expand-file-name module))))
+ (magit-git "stash" "push"
+ "-m" "backup before removal of this module")))
+ (setq modules (cl-set-difference modules modified :test #'equal)))
+ (if (cdr modified)
+ (message "Omitting %s modules with uncommitted changes: %s"
+ (length modified)
+ (mapconcat #'identity modified ", "))
+ (message "Omitting module %s, it has uncommitted changes"
+ (car modified)))
+ (setq modules (cl-set-difference modules modified :test #'equal))))
+ (when modules
+ (let ((alist
+ (and trash-gitdirs
+ (--map (split-string it "\0")
+ (magit-git-lines "submodule" "foreach" "-q"
+ "printf \"$sm_path\\0$name\n\"")))))
+ (magit-git "submodule" "absorbgitdirs" "--" modules)
+ (magit-git "submodule" "deinit" args "--" modules)
+ (magit-git "rm" args "--" modules)
+ (when (and trash-gitdirs
+ (magit-confirm 'trash-module-gitdirs
+ "Trash gitdir of module %s"
+ "Trash gitdirs of %i modules"
+ t modules))
+ (dolist (module modules)
+ (if-let ((name (cadr (assoc module alist))))
+ ;; Disregard if `magit-delete-by-moving-to-trash'
+ ;; is nil. Not doing so would be too dangerous.
+ (delete-directory (magit-git-dir
+ (convert-standard-filename
+ (concat "modules/" name)))
+ t t)
+ (error "BUG: Weird module name and/or path for %s" module)))))
+ (magit-refresh))))
+
+;;; Sections
+
+;;;###autoload
+(defun magit-insert-modules ()
+ "Insert submodule sections.
+Hook `magit-module-sections-hook' controls which module sections
+are inserted, and option `magit-module-sections-nested' controls
+whether they are wrapped in an additional section."
+ (when-let ((modules (magit-list-module-paths)))
+ (if magit-module-sections-nested
+ (magit-insert-section (modules nil t)
+ (magit-insert-heading
+ (format "%s (%s)"
+ (propertize "Modules"
+ 'font-lock-face 'magit-section-heading)
+ (length modules)))
+ (magit-insert-section-body
+ (magit--insert-modules)))
+ (magit--insert-modules))))
+
+(defun magit--insert-modules (&optional _section)
+ (magit-run-section-hook 'magit-module-sections-hook))
+
+;;;###autoload
+(defun magit-insert-modules-overview ()
+ "Insert sections for all modules.
+For each section insert the path and the output of `git describe --tags',
+or, failing that, the abbreviated HEAD commit hash."
+ (when-let ((modules (magit-list-module-paths)))
+ (magit-insert-section (modules nil t)
+ (magit-insert-heading
+ (format "%s (%s)"
+ (propertize "Modules overview"
+ 'font-lock-face 'magit-section-heading)
+ (length modules)))
+ (magit-insert-section-body
+ (magit--insert-modules-overview)))))
+
+(defvar magit-modules-overview-align-numbers t)
+
+(defun magit--insert-modules-overview (&optional _section)
+ (magit-with-toplevel
+ (let* ((modules (magit-list-module-paths))
+ (path-format (format "%%-%is "
+ (min (apply #'max (mapcar #'length modules))
+ (/ (window-width) 2))))
+ (branch-format (format "%%-%is " (min 25 (/ (window-width) 3)))))
+ (dolist (module modules)
+ (let ((default-directory
+ (expand-file-name (file-name-as-directory module))))
+ (magit-insert-section (magit-module-section module t)
+ (insert (propertize (format path-format module)
+ 'font-lock-face 'magit-diff-file-heading))
+ (if (not (file-exists-p ".git"))
+ (insert "(unpopulated)")
+ (insert (format
+ branch-format
+ (--if-let (magit-get-current-branch)
+ (propertize it 'font-lock-face 'magit-branch-local)
+ (propertize "(detached)" 'font-lock-face 'warning))))
+ (--if-let (magit-git-string "describe" "--tags")
+ (progn (when (and magit-modules-overview-align-numbers
+ (string-match-p "\\`[0-9]" it))
+ (insert ?\s))
+ (insert (propertize it 'font-lock-face 'magit-tag)))
+ (--when-let (magit-rev-format "%h")
+ (insert (propertize it 'font-lock-face 'magit-hash)))))
+ (insert ?\n))))))
+ (insert ?\n))
+
+(defvar magit-modules-section-map
+ (let ((map (make-sparse-keymap)))
+ (magit-menu-set map [remap magit-visit-thing]
+ #'magit-list-submodules "List %t")
+ map)
+ "Keymap for `modules' sections.")
+
+(defvar magit-module-section-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map (kbd "C-j") #'magit-submodule-visit)
+ (define-key map [C-return] #'magit-submodule-visit)
+ (magit-menu-set map [magit-visit-thing]
+ #'magit-submodule-visit "Visit %s")
+ (magit-menu-set map [magit-stage-file]
+ #'magit-stage "Stage %T"
+ '(:visible (eq (magit-diff-type) 'unstaged)))
+ (magit-menu-set map [magit-unstage-file]
+ #'magit-unstage "Unstage %T"
+ '(:visible (eq (magit-diff-type) 'staged)))
+ (define-key-after map [separator-magit-submodule] menu-bar-separator)
+ (magit-menu-set map [magit-submodule] #'magit-submodule "Module commands...")
+ map)
+ "Keymap for `module' sections.")
+
+(defun magit-submodule-visit (module &optional other-window)
+ "Visit MODULE by calling `magit-status' on it.
+Offer to initialize MODULE if it's not checked out yet.
+With a prefix argument, visit in another window."
+ (interactive (list (or (magit-section-value-if 'module)
+ (magit-read-module-path "Visit module"))
+ current-prefix-arg))
+ (magit-with-toplevel
+ (let ((path (expand-file-name module)))
+ (cond
+ ((file-exists-p (expand-file-name ".git" module))
+ (magit-diff-visit-directory path other-window))
+ ((y-or-n-p (format "Initialize submodule '%s' first?" module))
+ (magit-run-git-async "submodule" "update" "--init" "--" module)
+ (set-process-sentinel
+ magit-this-process
+ (lambda (process event)
+ (let ((magit-process-raise-error t))
+ (magit-process-sentinel process event))
+ (when (and (eq (process-status process) 'exit)
+ (= (process-exit-status process) 0))
+ (magit-diff-visit-directory path other-window)))))
+ ((file-exists-p path)
+ (dired-jump other-window (concat path "/.")))))))
+
+;;;###autoload
+(defun magit-insert-modules-unpulled-from-upstream ()
+ "Insert sections for modules that haven't been pulled from the upstream.
+These sections can be expanded to show the respective commits."
+ (magit--insert-modules-logs "Modules unpulled from @{upstream}"
+ 'modules-unpulled-from-upstream
+ "HEAD..@{upstream}"))
+
+;;;###autoload
+(defun magit-insert-modules-unpulled-from-pushremote ()
+ "Insert sections for modules that haven't been pulled from the push-remote.
+These sections can be expanded to show the respective commits."
+ (magit--insert-modules-logs "Modules unpulled from @{push}"
+ 'modules-unpulled-from-pushremote
+ "HEAD..@{push}"))
+
+;;;###autoload
+(defun magit-insert-modules-unpushed-to-upstream ()
+ "Insert sections for modules that haven't been pushed to the upstream.
+These sections can be expanded to show the respective commits."
+ (magit--insert-modules-logs "Modules unmerged into @{upstream}"
+ 'modules-unpushed-to-upstream
+ "@{upstream}..HEAD"))
+
+;;;###autoload
+(defun magit-insert-modules-unpushed-to-pushremote ()
+ "Insert sections for modules that haven't been pushed to the push-remote.
+These sections can be expanded to show the respective commits."
+ (magit--insert-modules-logs "Modules unpushed to @{push}"
+ 'modules-unpushed-to-pushremote
+ "@{push}..HEAD"))
+
+(defun magit--insert-modules-logs (heading type range)
+ "For internal use, don't add to a hook."
+ (unless (magit-ignore-submodules-p)
+ (when-let ((modules (magit-list-module-paths)))
+ (magit-insert-section section ((eval type) nil t)
+ (string-match "\\`\\(.+\\) \\([^ ]+\\)\\'" heading)
+ (magit-insert-heading
+ (propertize (match-string 1 heading)
+ 'font-lock-face 'magit-section-heading)
+ " "
+ (propertize (match-string 2 heading)
+ 'font-lock-face 'magit-branch-remote)
+ ":")
+ (magit-with-toplevel
+ (dolist (module modules)
+ (when (magit-module-worktree-p module)
+ (let ((default-directory
+ (expand-file-name (file-name-as-directory module))))
+ (when (magit-file-accessible-directory-p default-directory)
+ (magit-insert-section sec (magit-module-section module t)
+ (magit-insert-heading
+ (propertize module
+ 'font-lock-face 'magit-diff-file-heading)
+ ":")
+ (oset sec range range)
+ (magit-git-wash
+ (apply-partially #'magit-log-wash-log 'module)
+ "-c" "push.default=current" "log" "--oneline" range)
+ (when (> (point)
+ (oref sec content))
+ (delete-char -1))))))))
+ (if (> (point)
+ (oref section content))
+ (insert ?\n)
+ (magit-cancel-section))))))
+
+;;; List
+
+;;;###autoload
+(defun magit-list-submodules ()
+ "Display a list of the current repository's submodules."
+ (interactive)
+ (magit-submodule-list-setup magit-submodule-list-columns))
+
+(defvar magit-submodule-list-mode-map
+ (let ((map (make-sparse-keymap)))
+ (set-keymap-parent map magit-repolist-mode-map)
+ map)
+ "Local keymap for Magit-Submodule-List mode buffers.")
+
+(define-derived-mode magit-submodule-list-mode tabulated-list-mode "Modules"
+ "Major mode for browsing a list of Git submodules."
+ :group 'magit-repolist-mode
+ (setq-local x-stretch-cursor nil)
+ (setq tabulated-list-padding 0)
+ (add-hook 'tabulated-list-revert-hook #'magit-submodule-list-refresh nil t)
+ (setq imenu-prev-index-position-function
+ #'magit-repolist--imenu-prev-index-position)
+ (setq imenu-extract-index-name-function #'tabulated-list-get-id))
+
+(defvar-local magit-submodule-list-predicate nil)
+
+(defun magit-submodule-list-setup (columns &optional predicate)
+ (magit-display-buffer
+ (or (magit-get-mode-buffer 'magit-submodule-list-mode)
+ (magit-with-toplevel
+ (magit-generate-new-buffer 'magit-submodule-list-mode))))
+ (magit-submodule-list-mode)
+ (setq-local magit-repolist-columns columns)
+ (setq-local magit-repolist-sort-key magit-submodule-list-sort-key)
+ (setq-local magit-submodule-list-predicate predicate)
+ (magit-repolist-setup-1)
+ (magit-submodule-list-refresh))
+
+(defun magit-submodule-list-refresh ()
+ (setq tabulated-list-entries
+ (-keep (lambda (module)
+ (let ((default-directory
+ (expand-file-name (file-name-as-directory module))))
+ (and (file-exists-p ".git")
+ (or (not magit-submodule-list-predicate)
+ (funcall magit-submodule-list-predicate module))
+ (list module
+ (vconcat
+ (mapcar (pcase-lambda (`(,title ,width ,fn ,props))
+ (or (funcall fn `((:path ,module)
+ (:title ,title)
+ (:width ,width)
+ ,@props))
+ ""))
+ magit-repolist-columns))))))
+ (magit-list-module-paths)))
+ (message "Listing submodules...")
+ (tabulated-list-init-header)
+ (tabulated-list-print t)
+ (message "Listing submodules...done"))
+
+(defun magit-modulelist-column-path (spec)
+ "Insert the relative path of the submodule."
+ (cadr (assq :path spec)))
+
+;;; Utilities
+
+(defun magit-submodule--maybe-reuse-gitdir (name path)
+ (let ((gitdir
+ (magit-git-dir (convert-standard-filename (concat "modules/" name)))))
+ (when (and (file-exists-p gitdir)
+ (not (file-exists-p path)))
+ (pcase (read-char-choice
+ (concat
+ gitdir " already exists.\n"
+ "Type [u] to use the existing gitdir and create the working tree\n"
+ " [r] to rename the existing gitdir and clone again\n"
+ " [t] to trash the existing gitdir and clone again\n"
+ " [C-g] to abort ")
+ '(?u ?r ?t))
+ (?u (magit-submodule--restore-worktree (expand-file-name path) gitdir))
+ (?r (rename-file gitdir (concat gitdir "-"
+ (format-time-string "%F-%T"))))
+ (?t (delete-directory gitdir t t))))))
+
+(defun magit-submodule--restore-worktree (worktree gitdir)
+ (make-directory worktree t)
+ (with-temp-file (expand-file-name ".git" worktree)
+ (insert "gitdir: " (file-relative-name gitdir worktree) "\n"))
+ (let ((default-directory worktree))
+ (magit-call-git "reset" "--hard" "HEAD" "--")))
+
+;;; _
+(provide 'magit-submodule)
+;;; magit-submodule.el ends here
diff --git a/elpa/magit-20220503.1245/magit-submodule.elc b/elpa/magit-20220503.1245/magit-submodule.elc
new file mode 100644
index 0000000..c9e7953
--- /dev/null
+++ b/elpa/magit-20220503.1245/magit-submodule.elc
Binary files differ
diff --git a/elpa/magit-20220503.1245/magit-subtree.el b/elpa/magit-20220503.1245/magit-subtree.el
new file mode 100644
index 0000000..fec2aff
--- /dev/null
+++ b/elpa/magit-20220503.1245/magit-subtree.el
@@ -0,0 +1,181 @@
+;;; magit-subtree.el --- Subtree support for Magit -*- lexical-binding:t -*-
+
+;; Copyright (C) 2008-2022 The Magit Project Contributors
+
+;; Author: Jonas Bernoulli <jonas@bernoul.li>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+
+;; SPDX-License-Identifier: GPL-3.0-or-later
+
+;; Magit 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.
+;;
+;; Magit 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 Magit. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Code:
+
+(require 'magit)
+
+;;; Commands
+
+;;;###autoload (autoload 'magit-subtree "magit-subtree" nil t)
+(transient-define-prefix magit-subtree ()
+ "Import or export subtrees."
+ :man-page "git-subtree"
+ ["Actions"
+ ("i" "Import" magit-subtree-import)
+ ("e" "Export" magit-subtree-export)])
+
+;;;###autoload (autoload 'magit-subtree-import "magit-subtree" nil t)
+(transient-define-prefix magit-subtree-import ()
+ "Import subtrees."
+ :man-page "git-subtree"
+ ["Arguments"
+ (magit-subtree:--prefix)
+ (magit-subtree:--message)
+ ("-s" "Squash" "--squash")]
+ ["Actions"
+ [("a" "Add" magit-subtree-add)
+ ("c" "Add commit" magit-subtree-add-commit)]
+ [("m" "Merge" magit-subtree-merge)
+ ("f" "Pull" magit-subtree-pull)]])
+
+;;;###autoload (autoload 'magit-subtree-export "magit-subtree" nil t)
+(transient-define-prefix magit-subtree-export ()
+ "Export subtrees."
+ :man-page "git-subtree"
+ ["Arguments"
+ (magit-subtree:--prefix)
+ (magit-subtree:--annotate)
+ (magit-subtree:--branch)
+ (magit-subtree:--onto)
+ ("-i" "Ignore joins" "--ignore-joins")
+ ("-j" "Rejoin" "--rejoin")]
+ ["Actions"
+ ("p" "Push" magit-subtree-push)
+ ("s" "Split" magit-subtree-split)])
+
+(transient-define-argument magit-subtree:--prefix ()
+ :description "Prefix"
+ :class 'transient-option
+ :shortarg "-P"
+ :argument "--prefix="
+ :reader #'magit-subtree-read-prefix)
+
+(defun magit-subtree-read-prefix (prompt &optional default _history)
+ (let* ((insert-default-directory nil)
+ (topdir (magit-toplevel))
+ (prefix (read-directory-name (concat prompt ": ") topdir default)))
+ (if (file-name-absolute-p prefix)
+ ;; At least `ido-mode's variant is not compatible.
+ (if (string-prefix-p topdir prefix)
+ (file-relative-name prefix topdir)
+ (user-error "%s isn't inside the repository at %s" prefix topdir))
+ prefix)))
+
+(transient-define-argument magit-subtree:--message ()
+ :description "Message"
+ :class 'transient-option
+ :shortarg "-m"
+ :argument "--message=")
+
+(transient-define-argument magit-subtree:--annotate ()
+ :description "Annotate"
+ :class 'transient-option
+ :key "-a"
+ :argument "--annotate=")
+
+(transient-define-argument magit-subtree:--branch ()
+ :description "Branch"
+ :class 'transient-option
+ :shortarg "-b"
+ :argument "--branch=")
+
+(transient-define-argument magit-subtree:--onto ()
+ :description "Onto"
+ :class 'transient-option
+ :key "-o"
+ :argument "--onto="
+ :reader #'magit-transient-read-revision)
+
+(defun magit-subtree-prefix (transient prompt)
+ (--if-let (--first (string-prefix-p "--prefix=" it)
+ (transient-args transient))
+ (substring it 9)
+ (magit-subtree-read-prefix prompt)))
+
+(defun magit-subtree-arguments (transient)
+ (--remove (string-prefix-p "--prefix=" it)
+ (transient-args transient)))
+
+(defun magit-git-subtree (subcmd prefix &rest args)
+ (magit-run-git-async "subtree" subcmd (concat "--prefix=" prefix) args))
+
+;;;###autoload
+(defun magit-subtree-add (prefix repository ref args)
+ "Add REF from REPOSITORY as a new subtree at PREFIX."
+ (interactive
+ (cons (magit-subtree-prefix 'magit-subtree-import "Add subtree")
+ (let ((remote (magit-read-remote-or-url "From repository")))
+ (list remote
+ (magit-read-refspec "Ref" remote)
+ (magit-subtree-arguments 'magit-subtree-import)))))
+ (magit-git-subtree "add" prefix args repository ref))
+
+;;;###autoload
+(defun magit-subtree-add-commit (prefix commit args)
+ "Add COMMIT as a new subtree at PREFIX."
+ (interactive
+ (list (magit-subtree-prefix 'magit-subtree-import "Add subtree")
+ (magit-read-string-ns "Commit")
+ (magit-subtree-arguments 'magit-subtree-import)))
+ (magit-git-subtree "add" prefix args commit))
+
+;;;###autoload
+(defun magit-subtree-merge (prefix commit args)
+ "Merge COMMIT into the PREFIX subtree."
+ (interactive
+ (list (magit-subtree-prefix 'magit-subtree-import "Merge into subtree")
+ (magit-read-string-ns "Commit")
+ (magit-subtree-arguments 'magit-subtree-import)))
+ (magit-git-subtree "merge" prefix args commit))
+
+;;;###autoload
+(defun magit-subtree-pull (prefix repository ref args)
+ "Pull REF from REPOSITORY into the PREFIX subtree."
+ (interactive
+ (cons (magit-subtree-prefix 'magit-subtree-import "Pull into subtree")
+ (let ((remote (magit-read-remote-or-url "From repository")))
+ (list remote
+ (magit-read-refspec "Ref" remote)
+ (magit-subtree-arguments 'magit-subtree-import)))))
+ (magit-git-subtree "pull" prefix args repository ref))
+
+;;;###autoload
+(defun magit-subtree-push (prefix repository ref args)
+ "Extract the history of the subtree PREFIX and push it to REF on REPOSITORY."
+ (interactive (list (magit-subtree-prefix 'magit-subtree-export "Push subtree")
+ (magit-read-remote-or-url "To repository")
+ (magit-read-string-ns "To reference")
+ (magit-subtree-arguments 'magit-subtree-export)))
+ (magit-git-subtree "push" prefix args repository ref))
+
+;;;###autoload
+(defun magit-subtree-split (prefix commit args)
+ "Extract the history of the subtree PREFIX."
+ (interactive (list (magit-subtree-prefix 'magit-subtree-export "Split subtree")
+ (magit-read-string-ns "Commit")
+ (magit-subtree-arguments 'magit-subtree-export)))
+ (magit-git-subtree "split" prefix args commit))
+
+;;; _
+(provide 'magit-subtree)
+;;; magit-subtree.el ends here
diff --git a/elpa/magit-20220503.1245/magit-subtree.elc b/elpa/magit-20220503.1245/magit-subtree.elc
new file mode 100644
index 0000000..a234231
--- /dev/null
+++ b/elpa/magit-20220503.1245/magit-subtree.elc
Binary files differ
diff --git a/elpa/magit-20220503.1245/magit-tag.el b/elpa/magit-20220503.1245/magit-tag.el
new file mode 100644
index 0000000..95d2f9a
--- /dev/null
+++ b/elpa/magit-20220503.1245/magit-tag.el
@@ -0,0 +1,236 @@
+;;; magit-tag.el --- Tag functionality -*- lexical-binding:t -*-
+
+;; Copyright (C) 2008-2022 The Magit Project Contributors
+
+;; Author: Jonas Bernoulli <jonas@bernoul.li>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+
+;; SPDX-License-Identifier: GPL-3.0-or-later
+
+;; Magit 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.
+;;
+;; Magit 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 Magit. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This library implements tag commands.
+
+;;; Code:
+
+(require 'magit)
+
+;; For `magit-tag-delete'.
+(defvar helm-comp-read-use-marked)
+
+;;;###autoload (autoload 'magit-tag "magit" nil t)
+(transient-define-prefix magit-tag ()
+ "Create or delete a tag."
+ :man-page "git-tag"
+ ["Arguments"
+ ("-f" "Force" ("-f" "--force"))
+ ("-a" "Annotate" ("-a" "--annotate"))
+ ("-s" "Sign" ("-s" "--sign"))
+ (magit-tag:--local-user)]
+ [["Create"
+ ("t" "tag" magit-tag-create)
+ ("r" "release" magit-tag-release)]
+ ["Do"
+ ("k" "delete" magit-tag-delete)
+ ("p" "prune" magit-tag-prune)]])
+
+(defun magit-tag-arguments ()
+ (transient-args 'magit-tag))
+
+(transient-define-argument magit-tag:--local-user ()
+ :description "Sign as"
+ :class 'transient-option
+ :shortarg "-u"
+ :argument "--local-user="
+ :reader #'magit-read-gpg-signing-key
+ :history-key 'magit:--gpg-sign)
+
+;;;###autoload
+(defun magit-tag-create (name rev &optional args)
+ "Create a new tag with the given NAME at REV.
+With a prefix argument annotate the tag.
+\n(git tag [--annotate] NAME REV)"
+ (interactive (list (magit-read-tag "Tag name")
+ (magit-read-branch-or-commit "Place tag on")
+ (let ((args (magit-tag-arguments)))
+ (when current-prefix-arg
+ (cl-pushnew "--annotate" args))
+ args)))
+ (magit-run-git-with-editor "tag" args name rev))
+
+;;;###autoload
+(defun magit-tag-delete (tags)
+ "Delete one or more tags.
+If the region marks multiple tags (and nothing else), then offer
+to delete those, otherwise prompt for a single tag to be deleted,
+defaulting to the tag at point.
+\n(git tag -d TAGS)"
+ (interactive (list (--if-let (magit-region-values 'tag)
+ (magit-confirm t nil "Delete %i tags" nil it)
+ (let ((helm-comp-read-use-marked t))
+ (magit-read-tag "Delete tag" t)))))
+ (magit-run-git "tag" "-d" tags))
+
+;;;###autoload
+(defun magit-tag-prune (tags remote-tags remote)
+ "Offer to delete tags missing locally from REMOTE, and vice versa."
+ (interactive
+ (let* ((remote (magit-read-remote "Prune tags using remote"))
+ (tags (magit-list-tags))
+ (rtags (prog2 (message "Determining remote tags...")
+ (magit-remote-list-tags remote)
+ (message "Determining remote tags...done")))
+ (ltags (-difference tags rtags))
+ (rtags (-difference rtags tags)))
+ (unless (or ltags rtags)
+ (message "Same tags exist locally and remotely"))
+ (unless (magit-confirm t
+ "Delete %s locally"
+ "Delete %i tags locally"
+ 'noabort ltags)
+ (setq ltags nil))
+ (unless (magit-confirm t
+ "Delete %s from remote"
+ "Delete %i tags from remote"
+ 'noabort rtags)
+ (setq rtags nil))
+ (list ltags rtags remote)))
+ (when tags
+ (magit-call-git "tag" "-d" tags))
+ (when remote-tags
+ (magit-run-git-async "push" remote (--map (concat ":" it) remote-tags))))
+
+(defvar magit-tag-version-regexp-alist
+ '(("^[-._+ ]?snapshot\\.?$" . -4)
+ ("^[-._+]$" . -4)
+ ("^[-._+ ]?\\(cvs\\|git\\|bzr\\|svn\\|hg\\|darcs\\)\\.?$" . -4)
+ ("^[-._+ ]?unknown\\.?$" . -4)
+ ("^[-._+ ]?alpha\\.?$" . -3)
+ ("^[-._+ ]?beta\\.?$" . -2)
+ ("^[-._+ ]?\\(pre\\|rc\\)\\.?$" . -1))
+ "Overrides `version-regexp-alist' for `magit-tag-release'.
+See also `magit-release-tag-regexp'.")
+
+(defvar magit-release-tag-regexp "\\`\
+\\(?1:\\(?:v\\(?:ersion\\)?\\|r\\(?:elease\\)?\\)?[-_]?\\)?\
+\\(?2:[0-9]+\\(?:\\.[0-9]+\\)*\
+\\(?:-[a-zA-Z0-9-]+\\(?:\\.[a-zA-Z0-9-]+\\)*\\)?\\)\\'"
+ "Regexp used by `magit-tag-release' to parse release tags.
+
+The first submatch must match the prefix, if any. The second
+submatch must match the version string.
+
+If this matches versions that are not dot separated numbers,
+then `magit-tag-version-regexp-alist' has to contain entries
+for the separators allowed here.")
+
+(defvar magit-release-commit-regexp "\\`Release version \\(.+\\)\\'"
+ "Regexp used by `magit-tag-release' to parse release commit messages.
+The first submatch must match the version string.")
+
+;;;###autoload
+(defun magit-tag-release (tag msg &optional args)
+ "Create a release tag for `HEAD'.
+
+Assume that release tags match `magit-release-tag-regexp'.
+
+If `HEAD's message matches `magit-release-commit-regexp', then
+base the tag on the version string specified by that. Otherwise
+prompt for the name of the new tag using the highest existing
+tag as initial input and leaving it to the user to increment the
+desired part of the version string.
+
+If `--annotate' is enabled, then prompt for the message of the
+new tag. Base the proposed tag message on the message of the
+highest tag, provided that that contains the corresponding
+version string and substituting the new version string for that.
+Otherwise propose something like \"Foo-Bar 1.2.3\", given, for
+example, a TAG \"v1.2.3\" and a repository located at something
+like \"/path/to/foo-bar\"."
+ (interactive
+ (save-match-data
+ (pcase-let*
+ ((`(,pver ,ptag ,pmsg) (car (magit--list-releases)))
+ (msg (magit-rev-format "%s"))
+ (ver (and (string-match magit-release-commit-regexp msg)
+ (match-string 1 msg)))
+ (_ (and (not ver)
+ (require (quote sisyphus) nil t)
+ (string-match magit-release-commit-regexp
+ (magit-rev-format "%s" ptag))
+ (user-error "Use `sisyphus-create-release' first")))
+ (tag (if ver
+ (concat (and (string-match magit-release-tag-regexp ptag)
+ (match-string 1 ptag))
+ ver)
+ (read-string
+ (format "Create release tag (previous was %s): " ptag)
+ ptag)))
+ (ver (and (string-match magit-release-tag-regexp tag)
+ (match-string 2 tag)))
+ (args (magit-tag-arguments)))
+ (list tag
+ (and (member "--annotate" args)
+ (read-string
+ (format "Message for %S: " tag)
+ (cond ((and pver (string-match (regexp-quote pver) pmsg))
+ (replace-match ver t t pmsg))
+ ((and ptag (string-match (regexp-quote ptag) pmsg))
+ (replace-match tag t t pmsg))
+ (t (format "%s %s"
+ (capitalize
+ (file-name-nondirectory
+ (directory-file-name (magit-toplevel))))
+ ver)))))
+ args))))
+ (magit-run-git-async "tag" args (and msg (list "-m" msg)) tag)
+ (set-process-sentinel
+ magit-this-process
+ (lambda (process event)
+ (when (memq (process-status process) '(exit signal))
+ (magit-process-sentinel process event)
+ (magit-refs-setup-buffer "HEAD" (magit-show-refs-arguments))))))
+
+(defun magit--list-releases ()
+ "Return a list of releases.
+The list is ordered, beginning with the highest release.
+Each release element has the form (VERSION TAG MESSAGE).
+`magit-release-tag-regexp' is used to determine whether
+a tag qualifies as a release tag."
+ (save-match-data
+ (mapcar
+ #'cdr
+ (nreverse
+ (cl-sort (cl-mapcan
+ (lambda (line)
+ (and (string-match " +" line)
+ (let ((tag (substring line 0 (match-beginning 0)))
+ (msg (substring line (match-end 0))))
+ (and (string-match magit-release-tag-regexp tag)
+ (let ((ver (match-string 2 tag))
+ (version-regexp-alist
+ magit-tag-version-regexp-alist))
+ (list (list (version-to-list ver)
+ ver tag msg)))))))
+ ;; Cannot rely on "--sort=-version:refname" because
+ ;; that gets confused if the version prefix has changed.
+ (magit-git-lines "tag" "-n"))
+ ;; The inverse of this function does not exist.
+ #'version-list-< :key #'car)))))
+
+;;; _
+(provide 'magit-tag)
+;;; magit-tag.el ends here
diff --git a/elpa/magit-20220503.1245/magit-tag.elc b/elpa/magit-20220503.1245/magit-tag.elc
new file mode 100644
index 0000000..699861c
--- /dev/null
+++ b/elpa/magit-20220503.1245/magit-tag.elc
Binary files differ
diff --git a/elpa/magit-20220503.1245/magit-transient.el b/elpa/magit-20220503.1245/magit-transient.el
new file mode 100644
index 0000000..d7bca89
--- /dev/null
+++ b/elpa/magit-20220503.1245/magit-transient.el
@@ -0,0 +1,220 @@
+;;; magit-transient.el --- Support for transients -*- lexical-binding:t -*-
+
+;; Copyright (C) 2008-2022 The Magit Project Contributors
+
+;; Author: Jonas Bernoulli <jonas@bernoul.li>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+
+;; SPDX-License-Identifier: GPL-3.0-or-later
+
+;; Magit 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.
+;;
+;; Magit 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 Magit. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This library implements Magit-specific prefix and suffix classes,
+;; and their methods.
+
+;;; Code:
+
+(require 'magit-git)
+(require 'magit-mode)
+(require 'magit-process)
+
+(require 'transient)
+
+;;; Classes
+
+(defclass magit--git-variable (transient-variable)
+ ((scope :initarg :scope)
+ (global :initarg :global :initform nil)))
+
+(defclass magit--git-variable:choices (magit--git-variable)
+ ((choices :initarg :choices)
+ (fallback :initarg :fallback :initform nil)
+ (default :initarg :default :initform nil)))
+
+(defclass magit--git-variable:boolean (magit--git-variable:choices)
+ ((choices :initarg :choices :initform '("true" "false"))))
+
+(defclass magit--git-variable:urls (magit--git-variable)
+ ((seturl-arg :initarg :seturl-arg :initform nil)))
+
+;;; Methods
+;;;; Init
+
+(cl-defmethod transient-init-scope ((obj magit--git-variable))
+ (oset obj scope
+ (cond (transient--prefix
+ (oref transient--prefix scope))
+ ((slot-boundp obj 'scope)
+ (funcall (oref obj scope) obj)))))
+
+(cl-defmethod transient-init-value ((obj magit--git-variable))
+ (let ((variable (format (oref obj variable)
+ (oref obj scope)))
+ (arg (if (oref obj global) "--global" "--local")))
+ (oset obj variable variable)
+ (oset obj value
+ (cond ((oref obj multi-value)
+ (magit-get-all arg variable))
+ (t
+ (magit-get arg variable))))))
+
+(cl-defmethod transient-init-value ((obj magit--git-variable:boolean))
+ (let ((variable (format (oref obj variable)
+ (oref obj scope)))
+ (arg (if (oref obj global) "--global" "--local")))
+ (oset obj variable variable)
+ (oset obj value (if (magit-get-boolean arg variable) "true" "false"))))
+
+;;;; Read
+
+(cl-defmethod transient-infix-read :around ((obj magit--git-variable:urls))
+ (transient--with-emergency-exit
+ (transient--with-suspended-override
+ (mapcar (lambda (url)
+ (if (string-prefix-p "~" url)
+ (expand-file-name url)
+ url))
+ (cl-call-next-method obj)))))
+
+(cl-defmethod transient-infix-read ((obj magit--git-variable:choices))
+ (let ((choices (oref obj choices)))
+ (when (functionp choices)
+ (setq choices (funcall choices)))
+ (if-let ((value (oref obj value)))
+ (cadr (member value choices))
+ (car choices))))
+
+;;;; Readers
+
+(defun magit-transient-read-person (prompt initial-input history)
+ (magit-completing-read
+ prompt
+ (mapcar (lambda (line)
+ (save-excursion
+ (and (string-match "\\`[\s\t]+[0-9]+\t" line)
+ (list (substring line (match-end 0))))))
+ (magit-git-lines "shortlog" "-n" "-s" "-e" "HEAD"))
+ nil nil initial-input history))
+
+(defun magit-transient-read-revision (prompt initial-input history)
+ (or (magit-completing-read prompt (cons "HEAD" (magit-list-refnames))
+ nil nil initial-input history
+ (or (magit-branch-or-commit-at-point)
+ (magit-get-current-branch)))
+ (user-error "Nothing selected")))
+
+;;;; Set
+
+(cl-defmethod transient-infix-set ((obj magit--git-variable) value)
+ (let ((variable (oref obj variable))
+ (arg (if (oref obj global) "--global" "--local")))
+ (oset obj value value)
+ (if (oref obj multi-value)
+ (magit-set-all value arg variable)
+ (magit-set value arg variable))
+ (magit-refresh)
+ (unless (or value transient--prefix)
+ (message "Unset %s" variable))))
+
+(cl-defmethod transient-infix-set ((obj magit--git-variable:urls) values)
+ (let ((previous (oref obj value))
+ (seturl (oref obj seturl-arg))
+ (remote (oref transient--prefix scope)))
+ (oset obj value values)
+ (dolist (v (-difference values previous))
+ (magit-call-git "remote" "set-url" seturl "--add" remote v))
+ (dolist (v (-difference previous values))
+ (magit-call-git "remote" "set-url" seturl "--delete" remote
+ (concat "^" (regexp-quote v) "$")))
+ (magit-refresh)))
+
+;;;; Draw
+
+(cl-defmethod transient-format-description ((obj magit--git-variable))
+ (or (oref obj description)
+ (oref obj variable)))
+
+(cl-defmethod transient-format-value ((obj magit--git-variable))
+ (if-let ((value (oref obj value)))
+ (if (oref obj multi-value)
+ (if (cdr value)
+ (mapconcat (lambda (v)
+ (concat "\n "
+ (propertize v 'face 'transient-value)))
+ value "")
+ (propertize (car value) 'face 'transient-value))
+ (propertize (car (split-string value "\n"))
+ 'face 'transient-value))
+ (propertize "unset" 'face 'transient-inactive-value)))
+
+(cl-defmethod transient-format-value ((obj magit--git-variable:choices))
+ (let* ((variable (oref obj variable))
+ (choices (oref obj choices))
+ (globalp (oref obj global))
+ (value nil)
+ (global (magit-git-string "config" "--global" variable))
+ (defaultp (oref obj default))
+ (default (if (functionp defaultp) (funcall defaultp obj) defaultp))
+ (fallback (oref obj fallback))
+ (fallback (and fallback
+ (and-let* ((val (magit-get fallback)))
+ (concat fallback ":" val)))))
+ (if (not globalp)
+ (setq value (magit-git-string "config" "--local" variable))
+ (setq value global)
+ (setq global nil))
+ (when (functionp choices)
+ (setq choices (funcall choices)))
+ (concat
+ (propertize "[" 'face 'transient-inactive-value)
+ (mapconcat (lambda (choice)
+ (propertize choice 'face (if (equal choice value)
+ (if (member choice choices)
+ 'transient-value
+ 'font-lock-warning-face)
+ 'transient-inactive-value)))
+ (if (and value (not (member value choices)))
+ (cons value choices)
+ choices)
+ (propertize "|" 'face 'transient-inactive-value))
+ (and (or global fallback default)
+ (concat
+ (propertize "|" 'face 'transient-inactive-value)
+ (cond (global
+ (propertize (concat "global:" global)
+ 'face (cond (value
+ 'transient-inactive-value)
+ ((member global choices)
+ 'transient-value)
+ (t
+ 'font-lock-warning-face))))
+ (fallback
+ (propertize fallback
+ 'face (if value
+ 'transient-inactive-value
+ 'transient-value)))
+ (default
+ (propertize (if (functionp defaultp)
+ (concat "dwim:" default)
+ (concat "default:" default))
+ 'face (if value
+ 'transient-inactive-value
+ 'transient-value))))))
+ (propertize "]" 'face 'transient-inactive-value))))
+
+;;; _
+(provide 'magit-transient)
+;;; magit-transient.el ends here
diff --git a/elpa/magit-20220503.1245/magit-transient.elc b/elpa/magit-20220503.1245/magit-transient.elc
new file mode 100644
index 0000000..c9b89fa
--- /dev/null
+++ b/elpa/magit-20220503.1245/magit-transient.elc
Binary files differ
diff --git a/elpa/magit-20220503.1245/magit-wip.el b/elpa/magit-20220503.1245/magit-wip.el
new file mode 100644
index 0000000..ec6b0cc
--- /dev/null
+++ b/elpa/magit-20220503.1245/magit-wip.el
@@ -0,0 +1,453 @@
+;;; magit-wip.el --- Commit snapshots to work-in-progress refs -*- lexical-binding:t -*-
+
+;; Copyright (C) 2008-2022 The Magit Project Contributors
+
+;; Author: Jonas Bernoulli <jonas@bernoul.li>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+
+;; SPDX-License-Identifier: GPL-3.0-or-later
+
+;; Magit 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.
+;;
+;; Magit 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 Magit. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This library defines tree global modes which automatically commit
+;; snapshots to branch-specific work-in-progress refs before and after
+;; making changes, and two commands which can be used to do so on
+;; demand.
+
+;;; Code:
+
+(require 'magit-core)
+(require 'magit-log)
+
+;;; Options
+
+(defgroup magit-wip nil
+ "Automatically commit to work-in-progress refs."
+ :link '(info-link "(magit)Wip Modes")
+ :group 'magit-modes
+ :group 'magit-essentials)
+
+(defgroup magit-wip-legacy nil
+ "It is better to not use these modes individually."
+ :link '(info-link "(magit)Legacy Wip Modes")
+ :group 'magit-wip)
+
+(defcustom magit-wip-mode-lighter " Wip"
+ "Lighter for Magit-Wip mode."
+ :package-version '(magit . "2.90.0")
+ :group 'magit-wip
+ :type 'string)
+
+(defcustom magit-wip-after-save-local-mode-lighter ""
+ "Lighter for Magit-Wip-After-Save-Local mode."
+ :package-version '(magit . "2.1.0")
+ :group 'magit-wip-legacy
+ :type 'string)
+
+(defcustom magit-wip-after-apply-mode-lighter ""
+ "Lighter for Magit-Wip-After-Apply mode."
+ :package-version '(magit . "2.1.0")
+ :group 'magit-wip-legacy
+ :type 'string)
+
+(defcustom magit-wip-before-change-mode-lighter ""
+ "Lighter for Magit-Wip-Before-Change mode."
+ :package-version '(magit . "2.1.0")
+ :group 'magit-wip-legacy
+ :type 'string)
+
+(defcustom magit-wip-initial-backup-mode-lighter ""
+ "Lighter for Magit-Wip-Initial Backup mode."
+ :package-version '(magit . "2.1.0")
+ :group 'magit-wip-legacy
+ :type 'string)
+
+(defcustom magit-wip-merge-branch nil
+ "Whether to merge the current branch into its wip ref.
+
+If non-nil and the current branch has new commits, then it is
+merged into the wip ref before creating a new wip commit. This
+makes it easier to inspect wip history and the wip commits are
+never garbage collected.
+
+If nil and the current branch has new commits, then the wip ref
+is reset to the tip of the branch before creating a new wip
+commit. With this setting wip commits are eventually garbage
+collected. This is currently the default."
+ :package-version '(magit . "2.90.0")
+ :group 'magit-wip
+ :type 'boolean)
+
+(defcustom magit-wip-namespace "refs/wip/"
+ "Namespace used for work-in-progress refs.
+The wip refs are named \"<namespace/>index/<branchref>\"
+and \"<namespace/>wtree/<branchref>\". When snapshots
+are created while the `HEAD' is detached then \"HEAD\"
+is used as `branch-ref'."
+ :package-version '(magit . "2.1.0")
+ :group 'magit-wip
+ :type 'string)
+
+;;; Modes
+
+;;;###autoload
+(define-minor-mode magit-wip-mode
+ "Save uncommitted changes to work-in-progress refs.
+
+Whenever appropriate (i.e. when dataloss would be a possibility
+otherwise) this mode causes uncommitted changes to be committed
+to dedicated work-in-progress refs.
+
+For historic reasons this mode is implemented on top of four
+other `magit-wip-*' modes, which can also be used individually,
+if you want finer control over when the wip refs are updated;
+but that is discouraged."
+ :package-version '(magit . "2.90.0")
+ :lighter magit-wip-mode-lighter
+ :global t
+ (let ((arg (if magit-wip-mode 1 -1)))
+ (magit-wip-after-save-mode arg)
+ (magit-wip-after-apply-mode arg)
+ (magit-wip-before-change-mode arg)
+ (magit-wip-initial-backup-mode arg)))
+
+(define-minor-mode magit-wip-after-save-local-mode
+ "After saving, also commit to a worktree work-in-progress ref.
+
+After saving the current file-visiting buffer this mode also
+commits the changes to the worktree work-in-progress ref for
+the current branch.
+
+This mode should be enabled globally by turning on the globalized
+variant `magit-wip-after-save-mode'."
+ :package-version '(magit . "2.1.0")
+ :lighter magit-wip-after-save-local-mode-lighter
+ (if magit-wip-after-save-local-mode
+ (if (and buffer-file-name (magit-inside-worktree-p t))
+ (add-hook 'after-save-hook #'magit-wip-commit-buffer-file t t)
+ (setq magit-wip-after-save-local-mode nil)
+ (user-error "Need a worktree and a file"))
+ (remove-hook 'after-save-hook #'magit-wip-commit-buffer-file t)))
+
+(defun magit-wip-after-save-local-mode-turn-on ()
+ (and buffer-file-name
+ (magit-inside-worktree-p t)
+ (magit-file-tracked-p buffer-file-name)
+ (magit-wip-after-save-local-mode)))
+
+;;;###autoload
+(define-globalized-minor-mode magit-wip-after-save-mode
+ magit-wip-after-save-local-mode magit-wip-after-save-local-mode-turn-on
+ :package-version '(magit . "2.1.0")
+ :group 'magit-wip)
+
+(defun magit-wip-commit-buffer-file (&optional msg)
+ "Commit visited file to a worktree work-in-progress ref.
+
+Also see `magit-wip-after-save-mode' which calls this function
+automatically whenever a buffer visiting a tracked file is saved."
+ (interactive)
+ (--when-let (magit-wip-get-ref)
+ (magit-with-toplevel
+ (let ((file (file-relative-name buffer-file-name)))
+ (magit-wip-commit-worktree
+ it (list file)
+ (format (cond (msg)
+ ((called-interactively-p 'any)
+ "wip-save %s after save")
+ (t
+ "autosave %s after save"))
+ file))))))
+
+;;;###autoload
+(define-minor-mode magit-wip-after-apply-mode
+ "Commit to work-in-progress refs.
+
+After applying a change using any \"apply variant\"
+command (apply, stage, unstage, discard, and reverse) commit the
+affected files to the current wip refs. For each branch there
+may be two wip refs; one contains snapshots of the files as found
+in the worktree and the other contains snapshots of the entries
+in the index."
+ :package-version '(magit . "2.1.0")
+ :group 'magit-wip
+ :lighter magit-wip-after-apply-mode-lighter
+ :global t)
+
+(defun magit-wip-commit-after-apply (&optional files msg)
+ (when magit-wip-after-apply-mode
+ (magit-wip-commit files msg)))
+
+;;;###autoload
+(define-minor-mode magit-wip-before-change-mode
+ "Commit to work-in-progress refs before certain destructive changes.
+
+Before invoking a revert command or an \"apply variant\"
+command (apply, stage, unstage, discard, and reverse) commit the
+affected tracked files to the current wip refs. For each branch
+there may be two wip refs; one contains snapshots of the files
+as found in the worktree and the other contains snapshots of the
+entries in the index.
+
+Only changes to files which could potentially be affected by the
+command which is about to be called are committed."
+ :package-version '(magit . "2.1.0")
+ :group 'magit-wip
+ :lighter magit-wip-before-change-mode-lighter
+ :global t)
+
+(defun magit-wip-commit-before-change (&optional files msg)
+ (when magit-wip-before-change-mode
+ (magit-with-toplevel
+ (magit-wip-commit files msg))))
+
+(define-minor-mode magit-wip-initial-backup-mode
+ "Before saving a buffer for the first time, commit to a wip ref."
+ :package-version '(magit . "2.90.0")
+ :group 'magit-wip
+ :lighter magit-wip-initial-backup-mode-lighter
+ :global t
+ (if magit-wip-initial-backup-mode
+ (add-hook 'before-save-hook #'magit-wip-commit-initial-backup)
+ (remove-hook 'before-save-hook #'magit-wip-commit-initial-backup)))
+
+(defun magit--any-wip-mode-enabled-p ()
+ "Return non-nil if any global wip mode is enabled."
+ (or magit-wip-mode
+ magit-wip-after-save-mode
+ magit-wip-after-apply-mode
+ magit-wip-before-change-mode
+ magit-wip-initial-backup-mode))
+
+(defvar-local magit-wip-buffer-backed-up nil)
+(put 'magit-wip-buffer-backed-up 'permanent-local t)
+
+;;;###autoload
+(defun magit-wip-commit-initial-backup ()
+ "Before saving, commit current file to a worktree wip ref.
+
+The user has to add this function to `before-save-hook'.
+
+Commit the current state of the visited file before saving the
+current buffer to that file. This backs up the same version of
+the file as `backup-buffer' would, but stores the backup in the
+worktree wip ref, which is also used by the various Magit Wip
+modes, instead of in a backup file as `backup-buffer' would.
+
+This function ignores the variables that affect `backup-buffer'
+and can be used along-side that function, which is recommended
+because this function only backs up files that are tracked in
+a Git repository."
+ (when (and (not magit-wip-buffer-backed-up)
+ buffer-file-name
+ (magit-inside-worktree-p t)
+ (magit-file-tracked-p buffer-file-name))
+ (let ((magit-save-repository-buffers nil))
+ (magit-wip-commit-buffer-file "autosave %s before save"))
+ (setq magit-wip-buffer-backed-up t)))
+
+;;; Core
+
+(defun magit-wip-commit (&optional files msg)
+ "Commit all tracked files to the work-in-progress refs.
+
+Interactively, commit all changes to all tracked files using
+a generic commit message. With a prefix-argument the commit
+message is read in the minibuffer.
+
+Non-interactively, only commit changes to FILES using MSG as
+commit message."
+ (interactive (list nil (if current-prefix-arg
+ (magit-read-string "Wip commit message")
+ "wip-save tracked files")))
+ (--when-let (magit-wip-get-ref)
+ (magit-wip-commit-index it files msg)
+ (magit-wip-commit-worktree it files msg)))
+
+(defun magit-wip-commit-index (ref files msg)
+ (let* ((wipref (magit--wip-index-ref ref))
+ (parent (magit-wip-get-parent ref wipref))
+ (tree (magit-git-string "write-tree")))
+ (magit-wip-update-wipref ref wipref tree parent files msg "index")))
+
+(defun magit-wip-commit-worktree (ref files msg)
+ (when (or (not files)
+ ;; `update-index' will either ignore (before Git v2.32.0)
+ ;; or fail when passed directories (relevant for the
+ ;; untracked files code paths).
+ (setq files (seq-remove #'file-directory-p files)))
+ (let* ((wipref (magit--wip-wtree-ref ref))
+ (parent (magit-wip-get-parent ref wipref))
+ (tree (magit-with-temp-index parent (list "--reset" "-i")
+ (if files
+ ;; Note: `update-index' is used instead of `add'
+ ;; because `add' will fail if a file is already
+ ;; deleted in the temporary index.
+ (magit-call-git
+ "update-index" "--add" "--remove"
+ (and (magit-git-version>= "2.25.0")
+ "--ignore-skip-worktree-entries")
+ "--" files)
+ (magit-with-toplevel
+ (magit-call-git "add" "-u" ".")))
+ (magit-git-string "write-tree"))))
+ (magit-wip-update-wipref ref wipref tree parent files msg "worktree"))))
+
+(defun magit-wip-update-wipref (ref wipref tree parent files msg start-msg)
+ (cond
+ ((and (not (equal parent wipref))
+ (or (not magit-wip-merge-branch)
+ (not (magit-rev-verify wipref))))
+ (setq start-msg (concat "start autosaving " start-msg))
+ (magit-update-ref wipref start-msg
+ (magit-git-string "commit-tree" "--no-gpg-sign"
+ "-p" parent "-m" start-msg
+ (concat parent "^{tree}")))
+ (setq parent wipref))
+ ((and magit-wip-merge-branch
+ (or (not (magit-rev-ancestor-p ref wipref))
+ (not (magit-rev-ancestor-p
+ (concat (magit-git-string "log" "--format=%H"
+ "-1" "--merges" wipref)
+ "^2")
+ ref))))
+ (setq start-msg (format "merge %s into %s" ref start-msg))
+ (magit-update-ref wipref start-msg
+ (magit-git-string "commit-tree" "--no-gpg-sign"
+ "-p" wipref "-p" ref
+ "-m" start-msg
+ (concat ref "^{tree}")))
+ (setq parent wipref)))
+ (when (magit-git-failure "diff-tree" "--quiet" parent tree "--" files)
+ (unless (and msg (not (= (aref msg 0) ?\s)))
+ (let ((len (length files)))
+ (setq msg (concat
+ (cond ((= len 0) "autosave tracked files")
+ ((> len 1) (format "autosave %s files" len))
+ (t (concat "autosave "
+ (file-relative-name (car files)
+ (magit-toplevel)))))
+ msg))))
+ (magit-update-ref wipref msg
+ (magit-git-string "commit-tree" "--no-gpg-sign"
+ "-p" parent "-m" msg tree))))
+
+(defun magit-wip-get-ref ()
+ (let ((ref (or (magit-git-string "symbolic-ref" "HEAD") "HEAD")))
+ (and (magit-rev-verify ref)
+ ref)))
+
+(defun magit-wip-get-parent (ref wipref)
+ (if (and (magit-rev-verify wipref)
+ (equal (magit-git-string "merge-base" wipref ref)
+ (magit-rev-verify ref)))
+ wipref
+ ref))
+
+(defun magit--wip-index-ref (&optional ref)
+ (magit--wip-ref "index/" ref))
+
+(defun magit--wip-wtree-ref (&optional ref)
+ (magit--wip-ref "wtree/" ref))
+
+(defun magit--wip-ref (namespace &optional ref)
+ (concat magit-wip-namespace namespace
+ (or (and ref (string-prefix-p "refs/" ref) ref)
+ (and-let* ((branch (and (not (equal ref "HEAD"))
+ (or ref (magit-get-current-branch)))))
+ (concat "refs/heads/" branch))
+ "HEAD")))
+
+(defun magit-wip-maybe-add-commit-hook ()
+ (when (and magit-wip-merge-branch
+ (magit-wip-any-enabled-p))
+ (add-hook 'git-commit-post-finish-hook #'magit-wip-commit nil t)))
+
+(defun magit-wip-any-enabled-p ()
+ (or magit-wip-mode
+ magit-wip-after-save-local-mode
+ magit-wip-after-save-mode
+ magit-wip-after-apply-mode
+ magit-wip-before-change-mode
+ magit-wip-initial-backup-mode))
+
+;;; Log
+
+(defun magit-wip-log-index (args files)
+ "Show log for the index wip ref of the current branch."
+ (interactive (magit-log-arguments))
+ (magit-log-setup-buffer (list (magit--wip-index-ref)) args files))
+
+(defun magit-wip-log-worktree (args files)
+ "Show log for the worktree wip ref of the current branch."
+ (interactive (magit-log-arguments))
+ (magit-log-setup-buffer (list (magit--wip-wtree-ref)) args files))
+
+(defun magit-wip-log-current (branch args files count)
+ "Show log for the current branch and its wip refs.
+With a negative prefix argument only show the worktree wip ref.
+The absolute numeric value of the prefix argument controls how
+many \"branches\" of each wip ref are shown."
+ (interactive
+ (nconc (list (or (magit-get-current-branch) "HEAD"))
+ (magit-log-arguments)
+ (list (prefix-numeric-value current-prefix-arg))))
+ (magit-wip-log branch args files count))
+
+(defun magit-wip-log (branch args files count)
+ "Show log for a branch and its wip refs.
+With a negative prefix argument only show the worktree wip ref.
+The absolute numeric value of the prefix argument controls how
+many \"branches\" of each wip ref are shown."
+ (interactive
+ (nconc (list (magit-completing-read
+ "Log branch and its wip refs"
+ (-snoc (magit-list-local-branch-names) "HEAD")
+ nil t nil 'magit-revision-history
+ (or (magit-branch-at-point)
+ (magit-get-current-branch)
+ "HEAD")))
+ (magit-log-arguments)
+ (list (prefix-numeric-value current-prefix-arg))))
+ (magit-log-setup-buffer (nconc (list branch)
+ (magit-wip-log-get-tips
+ (magit--wip-wtree-ref branch)
+ (abs count))
+ (and (>= count 0)
+ (magit-wip-log-get-tips
+ (magit--wip-index-ref branch)
+ (abs count))))
+ args files))
+
+(defun magit-wip-log-get-tips (wipref count)
+ (and-let* ((reflog (magit-git-lines "reflog" wipref)))
+ (let (tips)
+ (while (and reflog (> count 1))
+ ;; "start autosaving ..." is the current message, but it used
+ ;; to be "restart autosaving ...", and those messages may
+ ;; still be around (e.g., if gc.reflogExpire is to "never").
+ (setq reflog (cl-member "^[^ ]+ [^:]+: \\(?:re\\)?start autosaving"
+ reflog :test #'string-match-p))
+ (when (and (cadr reflog)
+ (string-match "^[^ ]+ \\([^:]+\\)" (cadr reflog)))
+ (push (match-string 1 (cadr reflog)) tips))
+ (setq reflog (cddr reflog))
+ (cl-decf count))
+ (cons wipref (nreverse tips)))))
+
+;;; _
+(provide 'magit-wip)
+;;; magit-wip.el ends here
diff --git a/elpa/magit-20220503.1245/magit-wip.elc b/elpa/magit-20220503.1245/magit-wip.elc
new file mode 100644
index 0000000..32ef314
--- /dev/null
+++ b/elpa/magit-20220503.1245/magit-wip.elc
Binary files differ
diff --git a/elpa/magit-20220503.1245/magit-worktree.el b/elpa/magit-20220503.1245/magit-worktree.el
new file mode 100644
index 0000000..4a94c5b
--- /dev/null
+++ b/elpa/magit-20220503.1245/magit-worktree.el
@@ -0,0 +1,191 @@
+;;; magit-worktree.el --- Worktree support -*- lexical-binding:t -*-
+
+;; Copyright (C) 2008-2022 The Magit Project Contributors
+
+;; Author: Jonas Bernoulli <jonas@bernoul.li>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+
+;; SPDX-License-Identifier: GPL-3.0-or-later
+
+;; Magit 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.
+;;
+;; Magit 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 Magit. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This library implements support for `git-worktree'.
+
+;;; Code:
+
+(require 'magit)
+
+;;; Options
+
+(defcustom magit-worktree-read-directory-name-function #'read-directory-name
+ "Function used to read a directory for worktree commands.
+This is called with one argument, the prompt, and can be used
+to e.g. use a base directory other than `default-directory'.
+Used by `magit-worktree-checkout' and `magit-worktree-branch'."
+ :package-version '(magit . "3.0.0")
+ :group 'magit-commands
+ :type 'function)
+
+;;; Commands
+
+;;;###autoload (autoload 'magit-worktree "magit-worktree" nil t)
+(transient-define-prefix magit-worktree ()
+ "Act on a worktree."
+ :man-page "git-worktree"
+ [["Create new"
+ ("b" "worktree" magit-worktree-checkout)
+ ("c" "branch and worktree" magit-worktree-branch)]
+ ["Commands"
+ ("m" "Move worktree" magit-worktree-move)
+ ("k" "Delete worktree" magit-worktree-delete)
+ ("g" "Visit worktree" magit-worktree-status)]])
+
+;;;###autoload
+(defun magit-worktree-checkout (path branch)
+ "Checkout BRANCH in a new worktree at PATH."
+ (interactive
+ (let ((branch (magit-read-branch-or-commit "Checkout")))
+ (list (funcall magit-worktree-read-directory-name-function
+ (format "Checkout %s in new worktree: " branch))
+ branch)))
+ (magit-run-git "worktree" "add" (magit--expand-worktree path) branch)
+ (magit-diff-visit-directory path))
+
+;;;###autoload
+(defun magit-worktree-branch (path branch start-point &optional force)
+ "Create a new BRANCH and check it out in a new worktree at PATH."
+ (interactive
+ `(,(funcall magit-worktree-read-directory-name-function
+ "Create worktree: ")
+ ,@(magit-branch-read-args "Create and checkout branch")
+ ,current-prefix-arg))
+ (magit-run-git "worktree" "add" (if force "-B" "-b")
+ branch (magit--expand-worktree path) start-point)
+ (magit-diff-visit-directory path))
+
+;;;###autoload
+(defun magit-worktree-move (worktree path)
+ "Move WORKTREE to PATH."
+ (interactive
+ (list (magit-completing-read "Move worktree"
+ (cdr (magit-list-worktrees))
+ nil t nil nil
+ (magit-section-value-if 'worktree))
+ (funcall magit-worktree-read-directory-name-function
+ "Move worktree to: ")))
+ (if (file-directory-p (expand-file-name ".git" worktree))
+ (user-error "You may not move the main working tree")
+ (let ((preexisting-directory (file-directory-p path)))
+ (when (and (zerop (magit-call-git "worktree" "move" worktree
+ (magit--expand-worktree path)))
+ (not (file-exists-p default-directory))
+ (derived-mode-p 'magit-status-mode))
+ (kill-buffer)
+ (magit-diff-visit-directory
+ (if preexisting-directory
+ (concat (file-name-as-directory path)
+ (file-name-nondirectory worktree))
+ path)))
+ (magit-refresh))))
+
+(defun magit-worktree-delete (worktree)
+ "Delete a worktree, defaulting to the worktree at point.
+The primary worktree cannot be deleted."
+ (interactive
+ (list (magit-completing-read "Delete worktree"
+ (cdr (magit-list-worktrees))
+ nil t nil nil
+ (magit-section-value-if 'worktree))))
+ (if (file-directory-p (expand-file-name ".git" worktree))
+ (user-error "Deleting %s would delete the shared .git directory" worktree)
+ (let ((primary (file-name-as-directory (caar (magit-list-worktrees)))))
+ (magit-confirm-files (if magit-delete-by-moving-to-trash 'trash 'delete)
+ (list "worktree"))
+ (when (file-exists-p worktree)
+ (let ((delete-by-moving-to-trash magit-delete-by-moving-to-trash))
+ (delete-directory worktree t magit-delete-by-moving-to-trash)))
+ (if (file-exists-p default-directory)
+ (magit-run-git "worktree" "prune")
+ (let ((default-directory primary))
+ (magit-run-git "worktree" "prune"))
+ (when (derived-mode-p 'magit-status-mode)
+ (kill-buffer)
+ (magit-status-setup-buffer primary))))))
+
+(defun magit-worktree-status (worktree)
+ "Show the status for the worktree at point.
+If there is no worktree at point, then read one in the
+minibuffer. If the worktree at point is the one whose
+status is already being displayed in the current buffer,
+then show it in Dired instead."
+ (interactive
+ (list (or (magit-section-value-if 'worktree)
+ (magit-completing-read
+ "Show status for worktree"
+ (cl-delete (directory-file-name (magit-toplevel))
+ (magit-list-worktrees)
+ :test #'equal :key #'car)))))
+ (magit-diff-visit-directory worktree))
+
+(defun magit--expand-worktree (path)
+ (magit-convert-filename-for-git (expand-file-name path)))
+
+;;; Sections
+
+(defvar magit-worktree-section-map
+ (let ((map (make-sparse-keymap)))
+ (magit-menu-set map [magit-visit-thing] #'magit-worktree-status "Visit %s")
+ (magit-menu-set map [magit-delete-thing] #'magit-worktree-delete "Delete %m")
+ (define-key-after map [separator-magit-worktree] menu-bar-separator)
+ (magit-menu-set map [magit-worktree ] #'magit-worktree "Worktree commands...")
+ map)
+ "Keymap for `worktree' sections.")
+
+(defun magit-insert-worktrees ()
+ "Insert sections for all worktrees.
+If there is only one worktree, then insert nothing."
+ (let ((worktrees (magit-list-worktrees)))
+ (when (length> worktrees 1)
+ (magit-insert-section (worktrees)
+ (magit-insert-heading "Worktrees:")
+ (let* ((cols
+ (mapcar
+ (pcase-lambda (`(,path ,barep ,commit ,branch))
+ (cons (cond
+ (branch (propertize
+ branch 'font-lock-face
+ (if (equal branch (magit-get-current-branch))
+ 'magit-branch-current
+ 'magit-branch-local)))
+ (commit (propertize (magit-rev-abbrev commit)
+ 'font-lock-face 'magit-hash))
+ (barep "(bare)"))
+ path))
+ worktrees))
+ (align (1+ (-max (--map (string-width (car it)) cols)))))
+ (pcase-dolist (`(,head . ,path) cols)
+ (magit-insert-section (worktree path)
+ (insert head)
+ (insert (make-string (- align (length head)) ?\s))
+ (insert (let ((r (file-relative-name path))
+ (a (abbreviate-file-name path)))
+ (if (< (string-width r) (string-width a)) r a)))
+ (insert ?\n))))
+ (insert ?\n)))))
+
+;;; _
+(provide 'magit-worktree)
+;;; magit-worktree.el ends here
diff --git a/elpa/magit-20220503.1245/magit-worktree.elc b/elpa/magit-20220503.1245/magit-worktree.elc
new file mode 100644
index 0000000..81fdfec
--- /dev/null
+++ b/elpa/magit-20220503.1245/magit-worktree.elc
Binary files differ
diff --git a/elpa/magit-20220503.1245/magit.el b/elpa/magit-20220503.1245/magit.el
new file mode 100644
index 0000000..dc4a533
--- /dev/null
+++ b/elpa/magit-20220503.1245/magit.el
@@ -0,0 +1,683 @@
+;;; magit.el --- A Git porcelain inside Emacs -*- lexical-binding:t; coding:utf-8 -*-
+
+;; Copyright (C) 2008-2022 The Magit Project Contributors
+
+;; Author: Marius Vollmer <marius.vollmer@gmail.com>
+;; Jonas Bernoulli <jonas@bernoul.li>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+;; Kyle Meyer <kyle@kyleam.com>
+;; Former-Maintainers:
+;; Nicolas Dudebout <nicolas.dudebout@gatech.edu>
+;; Noam Postavsky <npostavs@users.sourceforge.net>
+;; Peter J. Weisberg <pj@irregularexpressions.net>
+;; Phil Jackson <phil@shellarchive.co.uk>
+;; Rémi Vanicat <vanicat@debian.org>
+;; Yann Hodique <yann.hodique@gmail.com>
+
+;; Homepage: https://github.com/magit/magit
+;; Keywords: git tools vc
+
+;; Package-Version: 3.3.0-git
+;; Package-Requires: (
+;; (emacs "25.1")
+;; (compat "28.1.1.0")
+;; (dash "2.19.1")
+;; (git-commit "3.3.0")
+;; (magit-section "3.3.0")
+;; (transient "0.3.6")
+;; (with-editor "3.0.5"))
+
+;; SPDX-License-Identifier: GPL-3.0-or-later
+
+;; Magit 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.
+;;
+;; Magit 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 Magit. If not, see <https://www.gnu.org/licenses/>.
+
+;; You should have received a copy of the AUTHORS.md file, which
+;; lists all contributors. If not, see https://magit.vc/authors.
+
+;;; Commentary:
+
+;; Magit is a text-based Git user interface that puts an unmatched focus
+;; on streamlining workflows. Commands are invoked using short mnemonic
+;; key sequences that take the cursor’s position in the highly actionable
+;; interface into account to provide context-sensitive behavior.
+
+;; With Magit you can do nearly everything that you can do when using Git
+;; on the command-line, but at greater speed and while taking advantage
+;; of advanced features that previously seemed too daunting to use on a
+;; daily basis. Many users will find that by using Magit they can become
+;; more effective Git user.
+
+;;; Code:
+
+(require 'magit-core)
+(require 'magit-diff)
+(require 'magit-log)
+(require 'magit-wip)
+(require 'magit-apply)
+(require 'magit-repos)
+(require 'git-commit)
+
+(require 'format-spec)
+(require 'package nil t) ; used in `magit-version'
+(require 'with-editor)
+
+;;; Faces
+
+(defface magit-header-line
+ '((t :inherit magit-section-heading))
+ "Face for the `header-line' in some Magit modes.
+Note that some modes, such as `magit-log-select-mode', have their
+own faces for the `header-line', or for parts of the
+`header-line'."
+ :group 'magit-faces)
+
+(defface magit-header-line-key
+ '((t :inherit font-lock-builtin-face))
+ "Face for keys in the `header-line'."
+ :group 'magit-faces)
+
+(defface magit-dimmed
+ '((((class color) (background light)) :foreground "grey50")
+ (((class color) (background dark)) :foreground "grey50"))
+ "Face for text that shouldn't stand out."
+ :group 'magit-faces)
+
+(defface magit-hash
+ '((((class color) (background light)) :foreground "grey60")
+ (((class color) (background dark)) :foreground "grey40"))
+ "Face for the commit object name in the log output."
+ :group 'magit-faces)
+
+(defface magit-tag
+ '((((class color) (background light)) :foreground "Goldenrod4")
+ (((class color) (background dark)) :foreground "LightGoldenrod2"))
+ "Face for tag labels shown in log buffer."
+ :group 'magit-faces)
+
+(defface magit-branch-remote
+ '((((class color) (background light)) :foreground "DarkOliveGreen4")
+ (((class color) (background dark)) :foreground "DarkSeaGreen2"))
+ "Face for remote branch head labels shown in log buffer."
+ :group 'magit-faces)
+
+(defface magit-branch-remote-head
+ '((((supports (:box t))) :inherit magit-branch-remote :box t)
+ (t :inherit magit-branch-remote :inverse-video t))
+ "Face for current branch."
+ :group 'magit-faces)
+
+(defface magit-branch-local
+ '((((class color) (background light)) :foreground "SkyBlue4")
+ (((class color) (background dark)) :foreground "LightSkyBlue1"))
+ "Face for local branches."
+ :group 'magit-faces)
+
+(defface magit-branch-current
+ '((((supports (:box t))) :inherit magit-branch-local :box t)
+ (t :inherit magit-branch-local :inverse-video t))
+ "Face for current branch."
+ :group 'magit-faces)
+
+(defface magit-branch-upstream
+ '((t :slant italic))
+ "Face for upstream branch.
+This face is only used in logs and it gets combined
+ with `magit-branch-local', `magit-branch-remote'
+and/or `magit-branch-remote-head'."
+ :group 'magit-faces)
+
+(defface magit-branch-warning
+ '((t :inherit warning))
+ "Face for warning about (missing) branch."
+ :group 'magit-faces)
+
+(defface magit-head
+ '((((class color) (background light)) :inherit magit-branch-local)
+ (((class color) (background dark)) :inherit magit-branch-local))
+ "Face for the symbolic ref `HEAD'."
+ :group 'magit-faces)
+
+(defface magit-refname
+ '((((class color) (background light)) :foreground "grey30")
+ (((class color) (background dark)) :foreground "grey80"))
+ "Face for refnames without a dedicated face."
+ :group 'magit-faces)
+
+(defface magit-refname-stash
+ '((t :inherit magit-refname))
+ "Face for stash refnames."
+ :group 'magit-faces)
+
+(defface magit-refname-wip
+ '((t :inherit magit-refname))
+ "Face for wip refnames."
+ :group 'magit-faces)
+
+(defface magit-refname-pullreq
+ '((t :inherit magit-refname))
+ "Face for pullreq refnames."
+ :group 'magit-faces)
+
+(defface magit-keyword
+ '((t :inherit font-lock-string-face))
+ "Face for parts of commit messages inside brackets."
+ :group 'magit-faces)
+
+(defface magit-keyword-squash
+ '((t :inherit font-lock-warning-face))
+ "Face for squash! and fixup! keywords in commit messages."
+ :group 'magit-faces)
+
+(defface magit-signature-good
+ '((t :foreground "green"))
+ "Face for good signatures."
+ :group 'magit-faces)
+
+(defface magit-signature-bad
+ '((t :foreground "red" :weight bold))
+ "Face for bad signatures."
+ :group 'magit-faces)
+
+(defface magit-signature-untrusted
+ '((t :foreground "medium aquamarine"))
+ "Face for good untrusted signatures."
+ :group 'magit-faces)
+
+(defface magit-signature-expired
+ '((t :foreground "orange"))
+ "Face for signatures that have expired."
+ :group 'magit-faces)
+
+(defface magit-signature-expired-key
+ '((t :inherit magit-signature-expired))
+ "Face for signatures made by an expired key."
+ :group 'magit-faces)
+
+(defface magit-signature-revoked
+ '((t :foreground "violet red"))
+ "Face for signatures made by a revoked key."
+ :group 'magit-faces)
+
+(defface magit-signature-error
+ '((t :foreground "light blue"))
+ "Face for signatures that cannot be checked (e.g. missing key)."
+ :group 'magit-faces)
+
+(defface magit-cherry-unmatched
+ '((t :foreground "cyan"))
+ "Face for unmatched cherry commits."
+ :group 'magit-faces)
+
+(defface magit-cherry-equivalent
+ '((t :foreground "magenta"))
+ "Face for equivalent cherry commits."
+ :group 'magit-faces)
+
+(defface magit-filename
+ '((t :weight normal))
+ "Face for filenames."
+ :group 'magit-faces)
+
+;;; Global Bindings
+
+;;;###autoload
+(define-obsolete-variable-alias 'global-magit-file-mode
+ 'magit-define-global-key-bindings "Magit 3.0.0")
+
+;;;###autoload
+(defcustom magit-define-global-key-bindings t
+ "Whether to bind some Magit commands in the global keymap.
+
+If this variable is non-nil, then the following bindings may
+be added to the global keymap. The default is t.
+
+key binding
+--- -------
+C-x g magit-status
+C-x M-g magit-dispatch
+C-c M-g magit-file-dispatch
+
+These bindings may be added when `after-init-hook' is run.
+Each binding is added if and only if at that time no other key
+is bound to the same command and no other command is bound to
+the same key. In other words we try to avoid adding bindings
+that are unnecessary, as well as bindings that conflict with
+other bindings.
+
+Adding the above bindings is delayed until `after-init-hook'
+is called to allow users to set the variable anywhere in their
+init file (without having to make sure to do so before `magit'
+is loaded or autoloaded) and to increase the likelihood that
+all the potentially conflicting user bindings have already
+been added.
+
+To set this variable use either `setq' or the Custom interface.
+Do not use the function `customize-set-variable' because doing
+that would cause Magit to be loaded immediately when that form
+is evaluated (this differs from `custom-set-variables', which
+doesn't load the libraries that define the customized variables).
+
+Setting this variable to nil has no effect if that is done after
+the key bindings have already been added.
+
+We recommend that you bind \"C-c g\" instead of \"C-c M-g\" to
+`magit-file-dispatch'. The former is a much better binding
+but the \"C-c <letter>\" namespace is strictly reserved for
+users; preventing Magit from using it by default.
+
+Also see info node `(magit)Commands for Buffers Visiting Files'."
+ :package-version '(magit . "3.0.0")
+ :group 'magit-essentials
+ :type 'boolean)
+
+;;;###autoload
+(progn
+ (defun magit-maybe-define-global-key-bindings (&optional force)
+ (when magit-define-global-key-bindings
+ (let ((map (current-global-map)))
+ (dolist (elt '(("C-x g" . magit-status)
+ ("C-x M-g" . magit-dispatch)
+ ("C-c M-g" . magit-file-dispatch)))
+ (let ((key (kbd (car elt)))
+ (def (cdr elt)))
+ (when (or force
+ (not (or (lookup-key map key)
+ (where-is-internal def (make-sparse-keymap) t))))
+ (define-key map key def)))))))
+ (if after-init-time
+ (magit-maybe-define-global-key-bindings)
+ (add-hook 'after-init-hook #'magit-maybe-define-global-key-bindings t)))
+
+;;; Dispatch Popup
+
+;;;###autoload (autoload 'magit-dispatch "magit" nil t)
+(transient-define-prefix magit-dispatch ()
+ "Invoke a Magit command from a list of available commands."
+ :info-manual "(magit)Top"
+ ["Transient and dwim commands"
+ ;; → bound in magit-mode-map or magit-section-mode-map
+ ;; ↓ bound below
+ [("A" "Apply" magit-cherry-pick)
+ ;; a ↓
+ ("b" "Branch" magit-branch)
+ ("B" "Bisect" magit-bisect)
+ ("c" "Commit" magit-commit)
+ ("C" "Clone" magit-clone)
+ ("d" "Diff" magit-diff)
+ ("D" "Diff (change)" magit-diff-refresh)
+ ("e" "Ediff (dwim)" magit-ediff-dwim)
+ ("E" "Ediff" magit-ediff)
+ ("f" "Fetch" magit-fetch)
+ ("F" "Pull" magit-pull)
+ ;; g ↓
+ ;; G → magit-refresh-all
+ ("h" "Help" magit-info)
+ ("H" "Section info" magit-describe-section :if-derived magit-mode)]
+ [("i" "Ignore" magit-gitignore)
+ ("I" "Init" magit-init)
+ ("j" "Jump to section"magit-status-jump :if-mode magit-status-mode)
+ ("j" "Display status" magit-status-quick :if-not-mode magit-status-mode)
+ ("J" "Display buffer" magit-display-repository-buffer)
+ ;; k ↓
+ ;; K → magit-file-untrack
+ ("l" "Log" magit-log)
+ ("L" "Log (change)" magit-log-refresh)
+ ("m" "Merge" magit-merge)
+ ("M" "Remote" magit-remote)
+ ;; n → magit-section-forward
+ ;; N reserved → forge-dispatch
+ ("o" "Submodule" magit-submodule)
+ ("O" "Subtree" magit-subtree)
+ ;; p → magit-section-backward
+ ("P" "Push" magit-push)
+ ;; q → magit-mode-bury-buffer
+ ("Q" "Command" magit-git-command)]
+ [("r" "Rebase" magit-rebase)
+ ;; R → magit-file-rename
+ ;; s ↓
+ ;; S ↓
+ ("t" "Tag" magit-tag)
+ ("T" "Note" magit-notes)
+ ;; u ↓
+ ;; U ↓
+ ;; v ↓
+ ("V" "Revert" magit-revert)
+ ("w" "Apply patches" magit-am)
+ ("W" "Format patches" magit-patch)
+ ;; x → magit-reset-quickly
+ ("X" "Reset" magit-reset)
+ ("y" "Show Refs" magit-show-refs)
+ ("Y" "Cherries" magit-cherry)
+ ("z" "Stash" magit-stash)
+ ("Z" "Worktree" magit-worktree)
+ ("!" "Run" magit-run)]]
+ ["Applying changes"
+ :if-derived magit-mode
+ [("a" "Apply" magit-apply)
+ ("v" "Reverse" magit-reverse)
+ ("k" "Discard" magit-discard)]
+ [("s" "Stage" magit-stage)
+ ("u" "Unstage" magit-unstage)]
+ [("S" "Stage all" magit-stage-modified)
+ ("U" "Unstage all" magit-unstage-all)]]
+ ["Essential commands"
+ :if-derived magit-mode
+ [("g" " refresh current buffer" magit-refresh)
+ ("q" " bury current buffer" magit-mode-bury-buffer)
+ ("<tab>" " toggle section at point" magit-section-toggle)
+ ("<return>" "visit thing at point" magit-visit-thing)]
+ [("C-x m" "show all key bindings" describe-mode)
+ ("C-x i" "show Info manual" magit-info)]])
+
+;;; Git Popup
+
+(defcustom magit-shell-command-verbose-prompt t
+ "Whether to show the working directory when reading a command.
+This affects `magit-git-command', `magit-git-command-topdir',
+`magit-shell-command', and `magit-shell-command-topdir'."
+ :package-version '(magit . "2.11.0")
+ :group 'magit-commands
+ :type 'boolean)
+
+(defvar magit-git-command-history nil)
+
+;;;###autoload (autoload 'magit-run "magit" nil t)
+(transient-define-prefix magit-run ()
+ "Run git or another command, or launch a graphical utility."
+ [["Run git subcommand"
+ ("!" "in repository root" magit-git-command-topdir)
+ ("p" "in working directory" magit-git-command)]
+ ["Run shell command"
+ ("s" "in repository root" magit-shell-command-topdir)
+ ("S" "in working directory" magit-shell-command)]
+ ["Launch"
+ ("k" "gitk" magit-run-gitk)
+ ("a" "gitk --all" magit-run-gitk-all)
+ ("b" "gitk --branches" magit-run-gitk-branches)
+ ("g" "git gui" magit-run-git-gui)
+ ("m" "git mergetool --gui" magit-git-mergetool)]])
+
+;;;###autoload
+(defun magit-git-command (command)
+ "Execute COMMAND asynchronously; display output.
+
+Interactively, prompt for COMMAND in the minibuffer. \"git \" is
+used as initial input, but can be deleted to run another command.
+
+With a prefix argument COMMAND is run in the top-level directory
+of the current working tree, otherwise in `default-directory'."
+ (interactive (list (magit-read-shell-command nil "git ")))
+ (magit--shell-command command))
+
+;;;###autoload
+(defun magit-git-command-topdir (command)
+ "Execute COMMAND asynchronously; display output.
+
+Interactively, prompt for COMMAND in the minibuffer. \"git \" is
+used as initial input, but can be deleted to run another command.
+
+COMMAND is run in the top-level directory of the current
+working tree."
+ (interactive (list (magit-read-shell-command t "git ")))
+ (magit--shell-command command (magit-toplevel)))
+
+;;;###autoload
+(defun magit-shell-command (command)
+ "Execute COMMAND asynchronously; display output.
+
+Interactively, prompt for COMMAND in the minibuffer. With a
+prefix argument COMMAND is run in the top-level directory of
+the current working tree, otherwise in `default-directory'."
+ (interactive (list (magit-read-shell-command)))
+ (magit--shell-command command))
+
+;;;###autoload
+(defun magit-shell-command-topdir (command)
+ "Execute COMMAND asynchronously; display output.
+
+Interactively, prompt for COMMAND in the minibuffer. COMMAND
+is run in the top-level directory of the current working tree."
+ (interactive (list (magit-read-shell-command t)))
+ (magit--shell-command command (magit-toplevel)))
+
+(defun magit--shell-command (command &optional directory)
+ (let ((default-directory (or directory default-directory)))
+ (with-environment-variables (("GIT_PAGER" "cat"))
+ (magit--with-connection-local-variables
+ (magit-start-process shell-file-name nil
+ shell-command-switch command))))
+ (magit-process-buffer))
+
+(defun magit-read-shell-command (&optional toplevel initial-input)
+ (let ((default-directory
+ (if (or toplevel current-prefix-arg)
+ (or (magit-toplevel)
+ (magit--not-inside-repository-error))
+ default-directory)))
+ (read-shell-command (if magit-shell-command-verbose-prompt
+ (format "Async shell command in %s: "
+ (abbreviate-file-name default-directory))
+ "Async shell command: ")
+ initial-input 'magit-git-command-history)))
+
+;;; Font-Lock Keywords
+
+(defconst magit-font-lock-keywords
+ (eval-when-compile
+ `((,(concat "(\\(magit-define-section-jumper\\)\\_>"
+ "[ \t'\(]*"
+ "\\(\\(?:\\sw\\|\\s_\\)+\\)?")
+ (1 'font-lock-keyword-face)
+ (2 'font-lock-function-name-face nil t))
+ (,(concat "(" (regexp-opt '("magit-insert-section"
+ "magit-section-case"
+ "magit-bind-match-strings"
+ "magit-with-temp-index"
+ "magit-with-blob"
+ "magit-with-toplevel") t)
+ "\\_>")
+ . 1))))
+
+(font-lock-add-keywords 'emacs-lisp-mode magit-font-lock-keywords)
+
+;;; Version
+
+(defvar magit-version #'undefined
+ "The version of Magit that you're using.
+Use the function by the same name instead of this variable.")
+
+;;;###autoload
+(defun magit-version (&optional print-dest)
+ "Return the version of Magit currently in use.
+If optional argument PRINT-DEST is non-nil, output
+stream (interactively, the echo area, or the current buffer with
+a prefix argument), also print the used versions of Magit, Git,
+and Emacs to it."
+ (interactive (list (if current-prefix-arg (current-buffer) t)))
+ (let ((magit-git-global-arguments nil)
+ (toplib (or load-file-name buffer-file-name))
+ debug)
+ (unless (and toplib
+ (member (file-name-nondirectory toplib)
+ '("magit.el" "magit.el.gz")))
+ (let ((load-suffixes (reverse load-suffixes))) ; prefer .el than .elc
+ (setq toplib (locate-library "magit"))))
+ (setq toplib (and toplib (magit--straight-chase-links toplib)))
+ (push toplib debug)
+ (when toplib
+ (let* ((topdir (file-name-directory toplib))
+ (gitdir (expand-file-name
+ ".git" (file-name-directory
+ (directory-file-name topdir))))
+ (static (locate-library "magit-version.el" nil (list topdir)))
+ (static (and static (magit--straight-chase-links static))))
+ (or (progn
+ (push 'repo debug)
+ (when (and (file-exists-p gitdir)
+ ;; It is a repo, but is it the Magit repo?
+ (file-exists-p
+ (expand-file-name "../lisp/magit.el" gitdir)))
+ (push t debug)
+ ;; Inside the repo the version file should only exist
+ ;; while running make.
+ (when (and static (not noninteractive))
+ (ignore-errors (delete-file static)))
+ (setq magit-version
+ (let ((default-directory topdir))
+ (magit-git-string "describe"
+ "--tags" "--dirty" "--always")))))
+ (progn
+ (push 'static debug)
+ (when (and static (file-exists-p static))
+ (push t debug)
+ (load-file static)
+ magit-version))
+ (when (featurep 'package)
+ (push 'elpa debug)
+ (ignore-errors
+ (--when-let (assq 'magit package-alist)
+ (push t debug)
+ (setq magit-version
+ (and (fboundp 'package-desc-version)
+ (package-version-join
+ (package-desc-version (cadr it))))))))
+ (progn
+ (push 'dirname debug)
+ (let ((dirname (file-name-nondirectory
+ (directory-file-name topdir))))
+ (when (string-match "\\`magit-\\([0-9].*\\)" dirname)
+ (setq magit-version (match-string 1 dirname)))))
+ ;; If all else fails, just report the commit hash. It's
+ ;; better than nothing and we cannot do better in the case
+ ;; of e.g. a shallow clone.
+ (progn
+ (push 'hash debug)
+ ;; Same check as above to see if it's really the Magit repo.
+ (when (and (file-exists-p gitdir)
+ (file-exists-p
+ (expand-file-name "../lisp/magit.el" gitdir)))
+ (setq magit-version
+ (let ((default-directory topdir))
+ (magit-git-string "rev-parse" "HEAD"))))))))
+ (if (stringp magit-version)
+ (when print-dest
+ (princ (format "Magit %s%s, Git %s, Emacs %s, %s"
+ (or magit-version "(unknown)")
+ (or (and (ignore-errors
+ (magit--version>= magit-version "2008"))
+ (ignore-errors
+ (require 'lisp-mnt)
+ (and (fboundp 'lm-header)
+ (format
+ " [>= %s]"
+ (with-temp-buffer
+ (insert-file-contents
+ (locate-library "magit.el" t))
+ (lm-header "Package-Version"))))))
+ "")
+ (magit--safe-git-version)
+ emacs-version
+ system-type)
+ print-dest))
+ (setq debug (reverse debug))
+ (setq magit-version 'error)
+ (when magit-version
+ (push magit-version debug))
+ (unless (equal (getenv "CI") "true")
+ ;; The repository is a sparse clone.
+ (message "Cannot determine Magit's version %S" debug)))
+ magit-version))
+
+;;; Startup Asserts
+
+(defun magit-startup-asserts ()
+ (when-let ((val (getenv "GIT_DIR")))
+ (setenv "GIT_DIR")
+ (message
+ "Magit unset $GIT_DIR (was %S). See %s" val
+ ;; Note: Pass URL as argument rather than embedding in the format
+ ;; string to prevent the single quote from being rendered
+ ;; according to `text-quoting-style'.
+ "https://github.com/magit/magit/wiki/Don't-set-$GIT_DIR-and-alike"))
+ (when-let ((val (getenv "GIT_WORK_TREE")))
+ (setenv "GIT_WORK_TREE")
+ (message
+ "Magit unset $GIT_WORK_TREE (was %S). See %s" val
+ ;; See comment above.
+ "https://github.com/magit/magit/wiki/Don't-set-$GIT_DIR-and-alike"))
+ ;; Git isn't required while building Magit.
+ (unless (bound-and-true-p byte-compile-current-file)
+ (magit-git-version-assert))
+ (when (version< emacs-version magit--minimal-emacs)
+ (display-warning 'magit (format "\
+Magit requires Emacs >= %s, you are using %s.
+
+If this comes as a surprise to you, because you do actually have
+a newer version installed, then that probably means that the
+older version happens to appear earlier on the `$PATH'. If you
+always start Emacs from a shell, then that can be fixed in the
+shell's init file. If you start Emacs by clicking on an icon,
+or using some sort of application launcher, then you probably
+have to adjust the environment as seen by graphical interface.
+For X11 something like ~/.xinitrc should work.\n"
+ magit--minimal-emacs emacs-version)
+ :error)))
+
+;;; Loading Libraries
+
+(provide 'magit)
+
+(cl-eval-when (load eval)
+ (require 'magit-status)
+ (require 'magit-refs)
+ (require 'magit-files)
+ (require 'magit-reset)
+ (require 'magit-branch)
+ (require 'magit-merge)
+ (require 'magit-tag)
+ (require 'magit-worktree)
+ (require 'magit-notes)
+ (require 'magit-sequence)
+ (require 'magit-commit)
+ (require 'magit-remote)
+ (require 'magit-clone)
+ (require 'magit-fetch)
+ (require 'magit-pull)
+ (require 'magit-push)
+ (require 'magit-bisect)
+ (require 'magit-stash)
+ (require 'magit-blame)
+ (require 'magit-obsolete)
+ (require 'magit-submodule)
+ (unless (load "magit-autoloads" t t)
+ (require 'magit-patch)
+ (require 'magit-subtree)
+ (require 'magit-ediff)
+ (require 'magit-gitignore)
+ (require 'magit-sparse-checkout)
+ (require 'magit-extras)
+ (require 'git-rebase)
+ (require 'magit-bookmark)))
+
+(with-eval-after-load 'bookmark
+ (require 'magit-bookmark))
+
+(unless (bound-and-true-p byte-compile-current-file)
+ (if after-init-time
+ (progn (magit-startup-asserts)
+ (magit-version))
+ (add-hook 'after-init-hook #'magit-startup-asserts t)
+ (add-hook 'after-init-hook #'magit-version t)))
+
+;;; magit.el ends here
diff --git a/elpa/magit-20220503.1245/magit.elc b/elpa/magit-20220503.1245/magit.elc
new file mode 100644
index 0000000..df8ad7e
--- /dev/null
+++ b/elpa/magit-20220503.1245/magit.elc
Binary files differ
diff --git a/elpa/magit-20220503.1245/magit.info b/elpa/magit-20220503.1245/magit.info
new file mode 100644
index 0000000..2f6966f
--- /dev/null
+++ b/elpa/magit-20220503.1245/magit.info
@@ -0,0 +1,11220 @@
+This is magit.info, produced by makeinfo version 6.7 from magit.texi.
+
+ Copyright (C) 2015-2022 Jonas Bernoulli <jonas@bernoul.li>
+
+ You can redistribute this document 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 document 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.
+
+INFO-DIR-SECTION Emacs
+START-INFO-DIR-ENTRY
+* Magit: (magit). Using Git from Emacs with Magit.
+END-INFO-DIR-ENTRY
+
+
+File: magit.info, Node: Top, Next: Introduction, Up: (dir)
+
+Magit User Manual
+*****************
+
+Magit is an interface to the version control system Git, implemented as
+an Emacs package. Magit aspires to be a complete Git porcelain. While
+we cannot (yet) claim that Magit wraps and improves upon each and every
+Git command, it is complete enough to allow even experienced Git users
+to perform almost all of their daily version control tasks directly from
+within Emacs. While many fine Git clients exist, only Magit and Git
+itself deserve to be called porcelains.
+
+This manual is for Magit version 3.3.0-git.
+
+ Copyright (C) 2015-2022 Jonas Bernoulli <jonas@bernoul.li>
+
+ You can redistribute this document 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 document 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.
+
+* Menu:
+
+* Introduction::
+* Installation::
+* Getting Started::
+* Interface Concepts::
+* Inspecting::
+* Manipulating::
+* Transferring::
+* Miscellaneous::
+* Customizing::
+* Plumbing::
+* FAQ::
+* Debugging Tools::
+* Keystroke Index::
+* Function and Command Index::
+* Variable Index::
+
+— The Detailed Node Listing —
+
+Installation
+
+* Installing from Melpa::
+* Installing from the Git Repository::
+* Post-Installation Tasks::
+
+Interface Concepts
+
+* Modes and Buffers::
+* Sections::
+* Transient Commands::
+* Transient Arguments and Buffer Variables::
+* Completion, Confirmation and the Selection: Completion Confirmation and the Selection.
+* Mouse Support::
+* Running Git::
+
+Modes and Buffers
+
+* Switching Buffers::
+* Naming Buffers::
+* Quitting Windows::
+* Automatic Refreshing of Magit Buffers::
+* Automatic Saving of File-Visiting Buffers::
+* Automatic Reverting of File-Visiting Buffers::
+
+
+Sections
+
+* Section Movement::
+* Section Visibility::
+* Section Hooks::
+* Section Types and Values::
+* Section Options::
+
+
+Completion, Confirmation and the Selection
+
+* Action Confirmation::
+* Completion and Confirmation::
+* The Selection::
+* The hunk-internal region::
+* Support for Completion Frameworks::
+* Additional Completion Options::
+
+
+Running Git
+
+* Viewing Git Output::
+* Git Process Status::
+* Running Git Manually::
+* Git Executable::
+* Global Git Arguments::
+
+
+Inspecting
+
+* Status Buffer::
+* Repository List::
+* Logging::
+* Diffing::
+* Ediffing::
+* References Buffer::
+* Bisecting::
+* Visiting Files and Blobs::
+* Blaming::
+
+Status Buffer
+
+* Status Sections::
+* Status Header Sections::
+* Status Module Sections::
+* Status Options::
+
+
+Logging
+
+* Refreshing Logs::
+* Log Buffer::
+* Log Margin::
+* Select from Log::
+* Reflog::
+* Cherries::
+
+
+Diffing
+
+* Refreshing Diffs::
+* Commands Available in Diffs::
+* Diff Options::
+* Revision Buffer::
+
+
+References Buffer
+
+* References Sections::
+
+
+Visiting Files and Blobs
+
+* General-Purpose Visit Commands::
+* Visiting Files and Blobs from a Diff::
+
+
+Manipulating
+
+* Creating Repository::
+* Cloning Repository::
+* Staging and Unstaging::
+* Applying::
+* Committing::
+* Branching::
+* Merging::
+* Resolving Conflicts::
+* Rebasing::
+* Cherry Picking::
+* Resetting::
+* Stashing::
+
+Staging and Unstaging
+
+* Staging from File-Visiting Buffers::
+
+
+Committing
+
+* Initiating a Commit::
+* Editing Commit Messages::
+
+
+Branching
+
+* The Two Remotes::
+* Branch Commands::
+* Branch Git Variables::
+* Auxiliary Branch Commands::
+
+
+Rebasing
+
+* Editing Rebase Sequences::
+* Information About In-Progress Rebase::
+
+
+Cherry Picking
+
+* Reverting::
+
+
+Transferring
+
+* Remotes::
+* Fetching::
+* Pulling::
+* Pushing::
+* Plain Patches::
+* Maildir Patches::
+
+Remotes
+
+* Remote Commands::
+* Remote Git Variables::
+
+
+Miscellaneous
+
+* Tagging::
+* Notes::
+* Submodules::
+* Subtree::
+* Worktree::
+* Sparse checkouts::
+* Bundle::
+* Common Commands::
+* Wip Modes::
+* Commands for Buffers Visiting Files::
+* Minor Mode for Buffers Visiting Blobs::
+
+Submodules
+
+* Listing Submodules::
+* Submodule Transient::
+
+
+Wip Modes
+
+* Wip Graph::
+* Legacy Wip Modes::
+
+
+Customizing
+
+* Per-Repository Configuration::
+* Essential Settings::
+
+Essential Settings
+
+* Safety::
+* Performance::
+* Default Bindings::
+
+
+Plumbing
+
+* Calling Git::
+* Section Plumbing::
+* Refreshing Buffers::
+* Conventions::
+
+Calling Git
+
+* Getting a Value from Git::
+* Calling Git for Effect::
+
+
+Section Plumbing
+
+* Creating Sections::
+* Section Selection::
+* Matching Sections::
+
+
+Conventions
+
+* Theming Faces::
+
+
+FAQ
+
+* FAQ - How to ...?::
+* FAQ - Issues and Errors::
+
+FAQ - How to ...?
+
+* How to pronounce Magit?::
+* How to show git's output?::
+* How to install the gitman info manual?::
+* How to show diffs for gpg-encrypted files?::
+* How does branching and pushing work?::
+* Can Magit be used as ediff-version-control-package?::
+* Should I disable VC?::
+
+
+FAQ - Issues and Errors
+
+* Magit is slow::
+* I changed several thousand files at once and now Magit is unusable::
+* I am having problems committing::
+* I am using MS Windows and cannot push with Magit::
+* I am using OS X and SOMETHING works in shell, but not in Magit: I am using OS X and SOMETHING works in shell but not in Magit.
+* Expanding a file to show the diff causes it to disappear::
+* Point is wrong in the COMMIT_EDITMSG buffer::
+* The mode-line information isn't always up-to-date::
+* A branch and tag sharing the same name breaks SOMETHING::
+* My Git hooks work on the command-line but not inside Magit::
+* git-commit-mode isn't used when committing from the command-line::
+* Point ends up inside invisible text when jumping to a file-visiting buffer::
+* I am unable to stage when using Tramp from MS Windows::
+* I am no longer able to save popup defaults::
+
+
+
+
+File: magit.info, Node: Introduction, Next: Installation, Prev: Top, Up: Top
+
+1 Introduction
+**************
+
+Magit is an interface to the version control system Git, implemented as
+an Emacs package. Magit aspires to be a complete Git porcelain. While
+we cannot (yet) claim that Magit wraps and improves upon each and every
+Git command, it is complete enough to allow even experienced Git users
+to perform almost all of their daily version control tasks directly from
+within Emacs. While many fine Git clients exist, only Magit and Git
+itself deserve to be called porcelains.
+
+ Staging and otherwise applying changes is one of the most important
+features in a Git porcelain and here Magit outshines anything else,
+including Git itself. Git’s own staging interface (‘git add --patch’)
+is so cumbersome that many users only use it in exceptional cases. In
+Magit staging a hunk or even just part of a hunk is as trivial as
+staging all changes made to a file.
+
+ The most visible part of Magit’s interface is the status buffer,
+which displays information about the current repository. Its content is
+created by running several Git commands and making their output
+actionable. Among other things, it displays information about the
+current branch, lists unpulled and unpushed changes and contains
+sections displaying the staged and unstaged changes. That might sound
+noisy, but, since sections are collapsible, it’s not.
+
+ To stage or unstage a change one places the cursor on the change and
+then types ‘s’ or ‘u’. The change can be a file or a hunk, or when the
+region is active (i.e. when there is a selection) several files or
+hunks, or even just part of a hunk. The change or changes that these
+commands - and many others - would act on are highlighted.
+
+ Magit also implements several other "apply variants" in addition to
+staging and unstaging. One can discard or reverse a change, or apply it
+to the working tree. Git’s own porcelain only supports this for staging
+and unstaging and you would have to do something like ‘git diff ... |
+??? | git apply ...’ to discard, revert, or apply a single hunk on the
+command line. In fact that’s exactly what Magit does internally (which
+is what lead to the term "apply variants").
+
+ Magit isn’t just for Git experts, but it does assume some prior
+experience with Git as well as Emacs. That being said, many users have
+reported that using Magit was what finally taught them what Git is
+capable of and how to use it to its fullest. Other users wished they
+had switched to Emacs sooner so that they would have gotten their hands
+on Magit earlier.
+
+ While one has to know the basic features of Emacs to be able to make
+full use of Magit, acquiring just enough Emacs skills doesn’t take long
+and is worth it, even for users who prefer other editors. Vim users are
+advised to give Evil (https://github.com/emacs-evil/evil), the
+"Extensible VI Layer for Emacs", and Spacemacs
+(https://github.com/syl20bnr/spacemacs), an "Emacs starter-kit focused
+on Evil" a try.
+
+ Magit provides a consistent and efficient Git porcelain. After a
+short learning period, you will be able to perform most of your daily
+version control tasks faster than you would on the command line. You
+will likely also start using features that seemed too daunting in the
+past.
+
+ Magit fully embraces Git. It exposes many advanced features using a
+simple but flexible interface instead of only wrapping the trivial ones
+like many GUI clients do. Of course Magit supports logging, cloning,
+pushing, and other commands that usually don’t fail in spectacular ways;
+but it also supports tasks that often cannot be completed in a single
+step. Magit fully supports tasks such as merging, rebasing,
+cherry-picking, reverting, and blaming by not only providing a command
+to initiate these tasks but also by displaying context sensitive
+information along the way and providing commands that are useful for
+resolving conflicts and resuming the sequence after doing so.
+
+ Magit wraps and in many cases improves upon at least the following
+Git porcelain commands: ‘add’, ‘am’, ‘bisect’, ‘blame’, ‘branch’,
+‘checkout’, ‘cherry’, ‘cherry-pick’, ‘clean’, ‘clone’, ‘commit’,
+‘config’, ‘describe’, ‘diff’, ‘fetch’, ‘format-patch’, ‘init’, ‘log’,
+‘merge’, ‘merge-tree’, ‘mv’, ‘notes’, ‘pull’, ‘rebase’, ‘reflog’,
+‘remote’, ‘request-pull’, ‘reset’, ‘revert’, ‘rm’, ‘show’, ‘stash’,
+‘submodule’, ‘subtree’, ‘tag’, and ‘worktree.’ Many more Magit porcelain
+commands are implemented on top of Git plumbing commands.
+
+
+File: magit.info, Node: Installation, Next: Getting Started, Prev: Introduction, Up: Top
+
+2 Installation
+**************
+
+Magit can be installed using Emacs’ package manager or manually from its
+development repository.
+
+* Menu:
+
+* Installing from Melpa::
+* Installing from the Git Repository::
+* Post-Installation Tasks::
+
+
+File: magit.info, Node: Installing from Melpa, Next: Installing from the Git Repository, Up: Installation
+
+2.1 Installing from Melpa
+=========================
+
+Magit is available from Melpa and Melpa-Stable. If you haven’t used
+Emacs’ package manager before, then it is high time you familiarize
+yourself with it by reading the documentation in the Emacs manual, see
+*note (emacs)Packages::. Then add one of the archives to
+‘package-archives’:
+
+ • To use Melpa:
+
+ (require 'package)
+ (add-to-list 'package-archives
+ '("melpa" . "http://melpa.org/packages/") t)
+
+ • To use Melpa-Stable:
+
+ (require 'package)
+ (add-to-list 'package-archives
+ '("melpa-stable" . "http://stable.melpa.org/packages/") t)
+
+ Once you have added your preferred archive, you need to update the
+local package list using:
+
+ M-x package-refresh-contents RET
+
+ Once you have done that, you can install Magit and its dependencies
+using:
+
+ M-x package-install RET magit RET
+
+ Now see *note Post-Installation Tasks::.
+
+
+File: magit.info, Node: Installing from the Git Repository, Next: Post-Installation Tasks, Prev: Installing from Melpa, Up: Installation
+
+2.2 Installing from the Git Repository
+======================================
+
+Magit depends on the ‘dash’, ‘transient’ and ‘with-editor’ libraries
+which are available from Melpa and Melpa-Stable. Install them using
+‘M-x package-install RET <package> RET’. Of course you may also install
+them manually from their repository.
+
+ Then clone the Magit repository:
+
+ $ git clone https://github.com/magit/magit.git ~/.emacs.d/site-lisp/magit
+ $ cd ~/.emacs.d/site-lisp/magit
+
+ Then compile the libraries and generate the info manuals:
+
+ $ make
+
+ If you haven’t installed ‘dash’, ‘transient’ and ‘with-editor’ from
+Melpa or at ‘/path/to/magit/../<package>’, then you have to tell ‘make’
+where to find them. To do so create the file ‘/path/to/magit/config.mk’
+with the following content before running ‘make’:
+
+ LOAD_PATH = -L ~/.emacs.d/site-lisp/magit/lisp
+ LOAD_PATH += -L ~/.emacs.d/site-lisp/dash
+ LOAD_PATH += -L ~/.emacs.d/site-lisp/transient/lisp
+ LOAD_PATH += -L ~/.emacs.d/site-lisp/with-editor
+
+ Finally add this to your init file:
+
+ (add-to-list 'load-path "~/.emacs.d/site-lisp/magit/lisp")
+ (require 'magit)
+
+ (with-eval-after-load 'info
+ (info-initialize)
+ (add-to-list 'Info-directory-list
+ "~/.emacs.d/site-lisp/magit/Documentation/"))
+
+ Of course if you installed the dependencies manually as well, then
+you have to tell Emacs about them too, by prefixing the above with:
+
+ (add-to-list 'load-path "~/.emacs.d/site-lisp/dash")
+ (add-to-list 'load-path "~/.emacs.d/site-lisp/transient/lisp")
+ (add-to-list 'load-path "~/.emacs.d/site-lisp/with-editor")
+
+ Note that you have to add the ‘lisp’ subdirectory to the ‘load-path’,
+not the top-level of the repository, and that elements of ‘load-path’
+should not end with a slash, while those of ‘Info-directory-list’
+should.
+
+ Instead of requiring the feature ‘magit’, you could load just the
+autoload definitions, by loading the file ‘magit-autoloads.el’.
+
+ (load "/path/to/magit/lisp/magit-autoloads")
+
+ Instead of running Magit directly from the repository by adding that
+to the ‘load-path’, you might want to instead install it in some other
+directory using ‘sudo make install’ and setting ‘load-path’ accordingly.
+
+ To update Magit use:
+
+ $ git pull
+ $ make
+
+ At times it might be necessary to run ‘make clean all’ instead.
+
+ To view all available targets use ‘make help’.
+
+ Now see *note Post-Installation Tasks::.
+
+
+File: magit.info, Node: Post-Installation Tasks, Prev: Installing from the Git Repository, Up: Installation
+
+2.3 Post-Installation Tasks
+===========================
+
+After installing Magit you should verify that you are indeed using the
+Magit, Git, and Emacs releases you think you are using. It’s best to
+restart Emacs before doing so, to make sure you are not using an
+outdated value for ‘load-path’.
+
+ M-x magit-version RET
+
+ should display something like
+
+ Magit 2.8.0, Git 2.10.2, Emacs 25.1.1, gnu/linux
+
+ Then you might also want to read about options that many users likely
+want to customize. See *note Essential Settings::.
+
+ To be able to follow cross references to Git manpages found in this
+manual, you might also have to manually install the ‘gitman’ info
+manual, or advice ‘Info-follow-nearest-node’ to instead open the actual
+manpage. See *note How to install the gitman info manual?::.
+
+ If you are completely new to Magit then see *note Getting Started::.
+
+ If you run into problems, then please see the *note FAQ::. Also see
+the *note Debugging Tools::.
+
+ And last but not least please consider making a donation, to ensure
+that I can keep working on Magit. See <https://magit.vc/donations>.
+for various donation options.
+
+
+File: magit.info, Node: Getting Started, Next: Interface Concepts, Prev: Installation, Up: Top
+
+3 Getting Started
+*****************
+
+This short tutorial describes the most essential features that many
+Magitians use on a daily basis. It only scratches the surface but
+should be enough to get you started.
+
+ IMPORTANT: It is safest if you clone some repository just for this
+tutorial. Alternatively you can use an existing local repository, but
+if you do that, then you should commit all uncommitted changes before
+proceeding.
+
+ Type ‘C-x g’ to display information about the current Git repository
+in a dedicated buffer, called the status buffer.
+
+ Most Magit commands are commonly invoked from the status buffer. It
+can be considered the primary interface for interacting with Git using
+Magit. Many other Magit buffers may exist at a given time, but they are
+often created from this buffer.
+
+ Depending on what state your repository is in, this buffer may
+contain sections titled "Staged changes", "Unstaged changes", "Unmerged
+into origin/master", "Unpushed to origin/master", and many others.
+
+ Since we are starting from a safe state, which you can easily return
+to (by doing a ‘git reset --hard PRE-MAGIT-STATE’), there currently are
+no staged or unstaged changes. Edit some files and save the changes.
+Then go back to the status buffer, while at the same time refreshing it,
+by typing ‘C-x g’. (When the status buffer, or any Magit buffer for
+that matter, is the current buffer, then you can also use just ‘g’ to
+refresh it).
+
+ Move between sections using ‘p’ and ‘n’. Note that the bodies of
+some sections are hidden. Type ‘TAB’ to expand or collapse the section
+at point. You can also use ‘C-tab’ to cycle the visibility of the
+current section and its children. Move to a file section inside the
+section named "Unstaged changes" and type ‘s’ to stage the changes you
+have made to that file. That file now appears under "Staged changes".
+
+ Magit can stage and unstage individual hunks, not just complete
+files. Move to the file you have just staged, expand it using ‘TAB’,
+move to one of the hunks using ‘n’, and unstage just that by typing ‘u’.
+Note how the staging (‘s’) and unstaging (‘u’) commands operate on the
+change at point. Many other commands behave the same way.
+
+ You can also un-/stage just part of a hunk. Inside the body of a
+hunk section (move there using ‘C-n’), set the mark using ‘C-SPC’ and
+move down until some added and/or removed lines fall inside the region
+but not all of them. Again type ‘s’ to stage.
+
+ It is also possible to un-/stage multiple files at once. Move to a
+file section, type ‘C-SPC’, move to the next file using ‘n’, and then
+‘s’ to stage both files. Note that both the mark and point have to be
+on the headings of sibling sections for this to work. If the region
+looks like it does in other buffers, then it doesn’t select Magit
+sections that can be acted on as a unit.
+
+ And then of course you want to commit your changes. Type ‘c’. This
+shows the available commit commands and arguments in a buffer at the
+bottom of the frame. Each command and argument is prefixed with the key
+that invokes/sets it. Do not worry about this for now. We want to
+create a "normal" commit, which is done by typing ‘c’ again.
+
+ Now two new buffers appear. One is for writing the commit message,
+the other shows a diff with the changes that you are about to commit.
+Write a message and then type ‘C-c C-c’ to actually create the commit.
+
+ You probably don’t want to push the commit you just created because
+you just committed some random changes, but if that is not the case you
+could push it by typing ‘P’ to show all the available push commands and
+arguments and then ‘p’ to push to a branch with the same name as the
+local branch onto the remote configured as the push-remote. (If the
+push-remote is not configured yet, then you would first be prompted for
+the remote to push to.)
+
+ So far we have mentioned the commit, push, and log menu commands.
+These are probably among the menus you will be using the most, but many
+others exist. To show a menu that lists all other menus (as well as the
+various apply commands and some other essential commands), type ‘h’.
+Try a few. (Such menus are also called "transient prefix commands" or
+just "transients".)
+
+ The key bindings in that menu correspond to the bindings in Magit
+buffers, including but not limited to the status buffer. So you could
+type ‘h d’ to bring up the diff menu, but once you remember that "d"
+stands for "diff", you would usually do so by just typing ‘d’. But this
+"prefix of prefixes" is useful even once you have memorized all the
+bindings, as it can provide easy access to Magit commands from non-Magit
+buffers. The global binding is ‘C-x M-g’.
+
+ In file visiting buffers ‘C-c M-g’ brings up a similar menu featuring
+commands that act on just the visited file, see *note Commands for
+Buffers Visiting Files::.
+
+ Magit also provides a context menu and other mouse commands, see
+*note Mouse Support::.
+
+ It is not necessary that you do so now, but if you stick with Magit,
+then it is highly recommended that you read the next section too.
+
+
+File: magit.info, Node: Interface Concepts, Next: Inspecting, Prev: Getting Started, Up: Top
+
+4 Interface Concepts
+********************
+
+* Menu:
+
+* Modes and Buffers::
+* Sections::
+* Transient Commands::
+* Transient Arguments and Buffer Variables::
+* Completion, Confirmation and the Selection: Completion Confirmation and the Selection.
+* Mouse Support::
+* Running Git::
+
+
+File: magit.info, Node: Modes and Buffers, Next: Sections, Up: Interface Concepts
+
+4.1 Modes and Buffers
+=====================
+
+Magit provides several major-modes. For each of these modes there
+usually exists only one buffer per repository. Separate modes and thus
+buffers exist for commits, diffs, logs, and some other things.
+
+ Besides these special purpose buffers, there also exists an overview
+buffer, called the *status buffer*. It’s usually from this buffer that
+the user invokes Git commands, or creates or visits other buffers.
+
+ In this manual we often speak about "Magit buffers". By that we mean
+buffers whose major-modes derive from ‘magit-mode’.
+
+‘M-x magit-toggle-buffer-lock’
+ This command locks the current buffer to its value or if the buffer
+ is already locked, then it unlocks it.
+
+ Locking a buffer to its value prevents it from being reused to
+ display another value. The name of a locked buffer contains its
+ value, which allows telling it apart from other locked buffers and
+ the unlocked buffer.
+
+ Not all Magit buffers can be locked to their values; for example,
+ it wouldn’t make sense to lock a status buffer.
+
+ There can only be a single unlocked buffer using a certain
+ major-mode per repository. So when a buffer is being unlocked and
+ another unlocked buffer already exists for that mode and
+ repository, then the former buffer is instead deleted and the
+ latter is displayed in its place.
+
+* Menu:
+
+* Switching Buffers::
+* Naming Buffers::
+* Quitting Windows::
+* Automatic Refreshing of Magit Buffers::
+* Automatic Saving of File-Visiting Buffers::
+* Automatic Reverting of File-Visiting Buffers::
+
+
+File: magit.info, Node: Switching Buffers, Next: Naming Buffers, Up: Modes and Buffers
+
+4.1.1 Switching Buffers
+-----------------------
+
+ -- Function: magit-display-buffer buffer &optional display-function
+ This function is a wrapper around ‘display-buffer’ and is used to
+ display any Magit buffer. It displays BUFFER in some window and,
+ unlike ‘display-buffer’, also selects that window, provided
+ ‘magit-display-buffer-noselect’ is ‘nil’. It also runs the hooks
+ mentioned below.
+
+ If optional DISPLAY-FUNCTION is non-nil, then that is used to
+ display the buffer. Usually that is ‘nil’ and the function
+ specified by ‘magit-display-buffer-function’ is used.
+
+ -- Variable: magit-display-buffer-noselect
+ When this is non-nil, then ‘magit-display-buffer’ only displays the
+ buffer but forgoes also selecting the window. This variable should
+ not be set globally, it is only intended to be let-bound, by code
+ that automatically updates "the other window". This is used for
+ example when the revision buffer is updated when you move inside
+ the log buffer.
+
+ -- User Option: magit-display-buffer-function
+ The function specified here is called by ‘magit-display-buffer’
+ with one argument, a buffer, to actually display that buffer. This
+ function should call ‘display-buffer’ with that buffer as first and
+ a list of display actions as second argument.
+
+ Magit provides several functions, listed below, that are suitable
+ values for this option. If you want to use different rules, then a
+ good way of doing that is to start with a copy of one of these
+ functions and then adjust it to your needs.
+
+ Instead of using a wrapper around ‘display-buffer’, that function
+ itself can be used here, in which case the display actions have to
+ be specified by adding them to ‘display-buffer-alist’ instead.
+
+ To learn about display actions, see *note (elisp)Choosing Window::.
+
+ -- Function: magit-display-buffer-traditional buffer
+ This function is the current default value of the option
+ ‘magit-display-buffer-function’. Before that option and this
+ function were added, the behavior was hard-coded in many places all
+ over the code base but now all the rules are contained in this one
+ function (except for the "noselect" special case mentioned above).
+
+ -- Function: magit-display-buffer-same-window-except-diff-v1
+ This function displays most buffers in the currently selected
+ window. If a buffer’s mode derives from ‘magit-diff-mode’ or
+ ‘magit-process-mode’, it is displayed in another window.
+
+ -- Function: magit-display-buffer-fullframe-status-v1
+ This function fills the entire frame when displaying a status
+ buffer. Otherwise, it behaves like
+ ‘magit-display-buffer-traditional’.
+
+ -- Function: magit-display-buffer-fullframe-status-topleft-v1
+ This function fills the entire frame when displaying a status
+ buffer. It behaves like ‘magit-display-buffer-fullframe-status-v1’
+ except that it displays buffers that derive from ‘magit-diff-mode’
+ or ‘magit-process-mode’ to the top or left of the current buffer
+ rather than to the bottom or right. As a result, Magit buffers
+ tend to pop up on the same side as they would if
+ ‘magit-display-buffer-traditional’ were in use.
+
+ -- Function: magit-display-buffer-fullcolumn-most-v1
+ This function displays most buffers so that they fill the entire
+ height of the frame. However, the buffer is displayed in another
+ window if (1) the buffer’s mode derives from ‘magit-process-mode’,
+ or (2) the buffer’s mode derives from ‘magit-diff-mode’, provided
+ that the mode of the current buffer derives from ‘magit-log-mode’
+ or ‘magit-cherry-mode’.
+
+ -- User Option: magit-pre-display-buffer-hook
+ This hook is run by ‘magit-display-buffer’ before displaying the
+ buffer.
+
+ -- Function: magit-save-window-configuration
+ This function saves the current window configuration. Later when
+ the buffer is buried, it may be restored by
+ ‘magit-restore-window-configuration’.
+
+ -- User Option: magit-post-display-buffer-hook
+ This hook is run by ‘magit-display-buffer’ after displaying the
+ buffer.
+
+ -- Function: magit-maybe-set-dedicated
+ This function remembers if a new window had to be created to
+ display the buffer, or whether an existing window was reused. This
+ information is later used by ‘magit-mode-quit-window’, to determine
+ whether the window should be deleted when its last Magit buffer is
+ buried.
+
+
+File: magit.info, Node: Naming Buffers, Next: Quitting Windows, Prev: Switching Buffers, Up: Modes and Buffers
+
+4.1.2 Naming Buffers
+--------------------
+
+ -- User Option: magit-generate-buffer-name-function
+ The function used to generate the names of Magit buffers.
+
+ Such a function should take the options
+ ‘magit-uniquify-buffer-names’ as well as ‘magit-buffer-name-format’
+ into account. If it doesn’t, then should be clearly stated in the
+ doc-string. And if it supports %-sequences beyond those mentioned
+ in the doc-string of the option ‘magit-buffer-name-format’, then
+ its own doc-string should describe the additions.
+
+ -- Function: magit-generate-buffer-name-default-function mode
+ This function returns a buffer name suitable for a buffer whose
+ major-mode is MODE and which shows information about the repository
+ in which ‘default-directory’ is located.
+
+ This function uses ‘magit-buffer-name-format’ and supporting all of
+ the %-sequences mentioned the documentation of that option. It
+ also respects the option ‘magit-uniquify-buffer-names’.
+
+ -- User Option: magit-buffer-name-format
+ The format string used to name Magit buffers.
+
+ At least the following %-sequences are supported:
+
+ • ‘%m’
+
+ The name of the major-mode, but with the ‘-mode’ suffix
+ removed.
+
+ • ‘%M’
+
+ Like ‘%m’ but abbreviate ‘magit-status-mode’ as ‘magit’.
+
+ • ‘%v’
+
+ The value the buffer is locked to, in parentheses, or an empty
+ string if the buffer is not locked to a value.
+
+ • ‘%V’
+
+ Like ‘%v’, but the string is prefixed with a space, unless it
+ is an empty string.
+
+ • ‘%t’
+
+ The top-level directory of the working tree of the repository,
+ or if ‘magit-uniquify-buffer-names’ is non-nil an abbreviation
+ of that.
+
+ • ‘%x’
+
+ If ‘magit-uniquify-buffer-names’ is nil "*", otherwise the
+ empty string. Due to limitations of the ‘uniquify’ package,
+ buffer names must end with the path.
+
+ • ‘%T’
+
+ Obsolete, use "%t%x" instead. Like ‘%t’, but append an
+ asterisk if and only if ‘magit-uniquify-buffer-names’ is nil.
+
+ The value should always contain ‘%m’ or ‘%M’, ‘%v’ or ‘%V’, and
+ ‘%t’ (or the obsolete ‘%T’). If ‘magit-uniquify-buffer-names’ is
+ non-nil, then the value must end with ‘%t’ or ‘%t%x’ (or the
+ obsolete ‘%T’). See issue #2841.
+
+ -- User Option: magit-uniquify-buffer-names
+ This option controls whether the names of Magit buffers are
+ uniquified. If the names are not being uniquified, then they
+ contain the full path of the top-level of the working tree of the
+ corresponding repository. If they are being uniquified, then they
+ end with the basename of the top-level, or if that would conflict
+ with the name used for other buffers, then the names of all these
+ buffers are adjusted until they no longer conflict.
+
+ This is done using the ‘uniquify’ package; customize its options to
+ control how buffer names are uniquified.
+
+
+File: magit.info, Node: Quitting Windows, Next: Automatic Refreshing of Magit Buffers, Prev: Naming Buffers, Up: Modes and Buffers
+
+4.1.3 Quitting Windows
+----------------------
+
+‘q’ (‘magit-mode-bury-buffer’)
+ This command buries the current Magit buffer.
+
+ With a prefix argument, it instead kills the buffer. With a double
+ prefix argument, also kills all other Magit buffers associated with
+ the current project.
+
+ -- User Option: magit-bury-buffer-function
+ The function used to actually bury or kill the current buffer.
+
+ ‘magit-mode-bury-buffer’ calls this function with one argument. If
+ the argument is non-nil, then the function has to kill the current
+ buffer. Otherwise it has to bury it alive. The default value
+ currently is ‘magit-restore-window-configuration’.
+
+ -- Function: magit-restore-window-configuration kill-buffer
+ Bury or kill the current buffer using ‘quit-window’, which is
+ called with KILL-BUFFER as first and the selected window as second
+ argument.
+
+ Then restore the window configuration that existed right before the
+ current buffer was displayed in the selected frame. Unfortunately
+ that also means that point gets adjusted in all the buffers, which
+ are being displayed in the selected frame.
+
+ -- Function: magit-mode-quit-window kill-buffer
+ Bury or kill the current buffer using ‘quit-window’, which is
+ called with KILL-BUFFER as first and the selected window as second
+ argument.
+
+ Then, if the window was originally created to display a Magit
+ buffer and the buried buffer was the last remaining Magit buffer
+ that was ever displayed in the window, then that is deleted.
+
+
+File: magit.info, Node: Automatic Refreshing of Magit Buffers, Next: Automatic Saving of File-Visiting Buffers, Prev: Quitting Windows, Up: Modes and Buffers
+
+4.1.4 Automatic Refreshing of Magit Buffers
+-------------------------------------------
+
+After running a command which may change the state of the current
+repository, the current Magit buffer and the corresponding status buffer
+are refreshed. The status buffer can be automatically refreshed
+whenever a buffer is saved to a file inside the respective repository by
+adding a hook, like so:
+
+ (with-eval-after-load 'magit-mode
+ (add-hook 'after-save-hook 'magit-after-save-refresh-status t))
+
+ Automatically refreshing Magit buffers ensures that the displayed
+information is up-to-date most of the time but can lead to a noticeable
+delay in big repositories. Other Magit buffers are not refreshed to
+keep the delay to a minimum and also because doing so can sometimes be
+undesirable.
+
+ Buffers can also be refreshed explicitly, which is useful in buffers
+that weren’t current during the last refresh and after changes were made
+to the repository outside of Magit.
+
+‘g’ (‘magit-refresh’)
+ This command refreshes the current buffer if its major mode derives
+ from ‘magit-mode’ as well as the corresponding status buffer.
+
+ If the option ‘magit-revert-buffers’ calls for it, then it also
+ reverts all unmodified buffers that visit files being tracked in
+ the current repository.
+
+‘G’ (‘magit-refresh-all’)
+ This command refreshes all Magit buffers belonging to the current
+ repository and also reverts all unmodified buffers that visit files
+ being tracked in the current repository.
+
+ The file-visiting buffers are always reverted, even if
+ ‘magit-revert-buffers’ is nil.
+
+ -- User Option: magit-refresh-buffer-hook
+ This hook is run in each Magit buffer that was refreshed during the
+ current refresh - normally the current buffer and the status
+ buffer.
+
+ -- User Option: magit-refresh-status-buffer
+ When this option is non-nil, then the status buffer is
+ automatically refreshed after running git for side-effects, in
+ addition to the current Magit buffer, which is always refreshed
+ automatically.
+
+ Only set this to nil after exhausting all other options to improve
+ performance.
+
+ -- Function: magit-after-save-refresh-status
+ This function is intended to be added to ‘after-save-hook’. After
+ doing that the corresponding status buffer is refreshed whenever a
+ buffer is saved to a file inside a repository.
+
+ Note that refreshing a Magit buffer is done by re-creating its
+ contents from scratch, which can be slow in large repositories. If
+ you are not satisfied with Magit’s performance, then you should
+ obviously not add this function to that hook.
+
+
+File: magit.info, Node: Automatic Saving of File-Visiting Buffers, Next: Automatic Reverting of File-Visiting Buffers, Prev: Automatic Refreshing of Magit Buffers, Up: Modes and Buffers
+
+4.1.5 Automatic Saving of File-Visiting Buffers
+-----------------------------------------------
+
+File-visiting buffers are by default saved at certain points in time.
+This doesn’t guarantee that Magit buffers are always up-to-date, but,
+provided one only edits files by editing them in Emacs and uses only
+Magit to interact with Git, one can be fairly confident. When in doubt
+or after outside changes, type ‘g’ (‘magit-refresh’) to save and refresh
+explicitly.
+
+ -- User Option: magit-save-repository-buffers
+ This option controls whether file-visiting buffers are saved before
+ certain events.
+
+ If this is non-nil then all modified file-visiting buffers
+ belonging to the current repository may be saved before running
+ commands, before creating new Magit buffers, and before explicitly
+ refreshing such buffers. If this is ‘dontask’ then this is done
+ without user intervention. If it is ‘t’ then the user has to
+ confirm each save.
+
+
+File: magit.info, Node: Automatic Reverting of File-Visiting Buffers, Prev: Automatic Saving of File-Visiting Buffers, Up: Modes and Buffers
+
+4.1.6 Automatic Reverting of File-Visiting Buffers
+--------------------------------------------------
+
+By default Magit automatically reverts buffers that are visiting files
+that are being tracked in a Git repository, after they have changed on
+disk. When using Magit one often changes files on disk by running Git,
+i.e. "outside Emacs", making this a rather important feature.
+
+ For example, if you discard a change in the status buffer, then that
+is done by running ‘git apply --reverse ...’, and Emacs considers the
+file to have "changed on disk". If Magit did not automatically revert
+the buffer, then you would have to type ‘M-x revert-buffer RET RET’ in
+the visiting buffer before you could continue making changes.
+
+ -- User Option: magit-auto-revert-mode
+ When this mode is enabled, then buffers that visit tracked files
+ are automatically reverted after the visited files change on disk.
+
+ -- User Option: global-auto-revert-mode
+ When this mode is enabled, then any file-visiting buffer is
+ automatically reverted after the visited file changes on disk.
+
+ If you like buffers that visit tracked files to be automatically
+ reverted, then you might also like any buffer to be reverted, not
+ just those visiting tracked files. If that is the case, then
+ enable this mode _instead of_ ‘magit-auto-revert-mode’.
+
+ -- User Option: magit-auto-revert-immediately
+ This option controls whether Magit reverts buffers immediately.
+
+ If this is non-nil and either ‘global-auto-revert-mode’ or
+ ‘magit-auto-revert-mode’ is enabled, then Magit immediately reverts
+ buffers by explicitly calling ‘auto-revert-buffers’ after running
+ Git for side-effects.
+
+ If ‘auto-revert-use-notify’ is non-nil (and file notifications are
+ actually supported), then ‘magit-auto-revert-immediately’ does not
+ have to be non-nil, because the reverts happen immediately anyway.
+
+ If ‘magit-auto-revert-immediately’ and ‘auto-revert-use-notify’ are
+ both ‘nil’, then reverts happen after ‘auto-revert-interval’
+ seconds of user inactivity. That is not desirable.
+
+ -- User Option: auto-revert-use-notify
+ This option controls whether file notification functions should be
+ used. Note that this variable unfortunately defaults to ‘t’ even
+ on systems on which file notifications cannot be used.
+
+ -- User Option: magit-auto-revert-tracked-only
+ This option controls whether ‘magit-auto-revert-mode’ only reverts
+ tracked files or all files that are located inside Git
+ repositories, including untracked files and files located inside
+ Git’s control directory.
+
+ -- User Option: auto-revert-mode
+ The global mode ‘magit-auto-revert-mode’ works by turning on this
+ local mode in the appropriate buffers (but
+ ‘global-auto-revert-mode’ is implemented differently). You can
+ also turn it on or off manually, which might be necessary if Magit
+ does not notice that a previously untracked file now is being
+ tracked or vice-versa.
+
+ -- User Option: auto-revert-stop-on-user-input
+ This option controls whether the arrival of user input suspends the
+ automatic reverts for ‘auto-revert-interval’ seconds.
+
+ -- User Option: auto-revert-interval
+ This option controls how many seconds Emacs waits for before
+ resuming suspended reverts.
+
+ -- User Option: auto-revert-buffer-list-filter
+ This option specifies an additional filter used by
+ ‘auto-revert-buffers’ to determine whether a buffer should be
+ reverted or not.
+
+ This option is provided by Magit, which also advises
+ ‘auto-revert-buffers’ to respect it. Magit users who do not turn
+ on the local mode ‘auto-revert-mode’ themselves, are best served by
+ setting the value to ‘magit-auto-revert-repository-buffer-p’.
+
+ However the default is nil, so as not to disturb users who do use
+ the local mode directly. If you experience delays when running
+ Magit commands, then you should consider using one of the
+ predicates provided by Magit - especially if you also use Tramp.
+
+ Users who do turn on ‘auto-revert-mode’ in buffers in which Magit
+ doesn’t do that for them, should likely not use any filter. Users
+ who turn on ‘global-auto-revert-mode’, do not have to worry about
+ this option, because it is disregarded if the global mode is
+ enabled.
+
+ -- User Option: auto-revert-verbose
+ This option controls whether Emacs reports when a buffer has been
+ reverted.
+
+ The options with the ‘auto-revert-’ prefix are located in the Custom
+group named ‘auto-revert’. The other, Magit-specific, options are
+located in the ‘magit’ group.
+
+* Menu:
+
+* Risk of Reverting Automatically::
+
+
+File: magit.info, Node: Risk of Reverting Automatically, Up: Automatic Reverting of File-Visiting Buffers
+
+Risk of Reverting Automatically
+...............................
+
+For the vast majority of users, automatically reverting file-visiting
+buffers after they have changed on disk is harmless.
+
+ If a buffer is modified (i.e. it contains changes that haven’t been
+saved yet), then Emacs will refuse to automatically revert it. If you
+save a previously modified buffer, then that results in what is seen by
+Git as an uncommitted change. Git will then refuse to carry out any
+commands that would cause these changes to be lost. In other words, if
+there is anything that could be lost, then either Git or Emacs will
+refuse to discard the changes.
+
+ However, if you use file-visiting buffers as a sort of ad hoc
+"staging area", then the automatic reverts could potentially cause data
+loss. So far I have heard from only one user who uses such a workflow.
+
+ An example: You visit some file in a buffer, edit it, and save the
+changes. Then, outside of Emacs (or at least not using Magit or by
+saving the buffer) you change the file on disk again. At this point the
+buffer is the only place where the intermediate version still exists.
+You have saved the changes to disk, but that has since been overwritten.
+Meanwhile Emacs considers the buffer to be unmodified (because you have
+not made any changes to it since you last saved it to the visited file)
+and therefore would not object to it being automatically reverted. At
+this point an Auto-Revert mode would kick in. It would check whether
+the buffer is modified and since that is not the case it would revert
+it. The intermediate version would be lost. (Actually you could still
+get it back using the ‘undo’ command.)
+
+ If your workflow depends on Emacs preserving the intermediate version
+in the buffer, then you have to disable all Auto-Revert modes. But
+please consider that such a workflow would be dangerous even without
+using an Auto-Revert mode, and should therefore be avoided. If Emacs
+crashes or if you quit Emacs by mistake, then you would also lose the
+buffer content. There would be no autosave file still containing the
+intermediate version (because that was deleted when you saved the
+buffer) and you would not be asked whether you want to save the buffer
+(because it isn’t modified).
+
+
+File: magit.info, Node: Sections, Next: Transient Commands, Prev: Modes and Buffers, Up: Interface Concepts
+
+4.2 Sections
+============
+
+Magit buffers are organized into nested sections, which can be collapsed
+and expanded, similar to how sections are handled in Org mode. Each
+section also has a type, and some sections also have a value. For each
+section type there can also be a local keymap, shared by all sections of
+that type.
+
+ Taking advantage of the section value and type, many commands operate
+on the current section, or when the region is active and selects
+sections of the same type, all of the selected sections. Commands that
+only make sense for a particular section type (as opposed to just
+behaving differently depending on the type) are usually bound in section
+type keymaps.
+
+* Menu:
+
+* Section Movement::
+* Section Visibility::
+* Section Hooks::
+* Section Types and Values::
+* Section Options::
+
+
+File: magit.info, Node: Section Movement, Next: Section Visibility, Up: Sections
+
+4.2.1 Section Movement
+----------------------
+
+To move within a section use the usual keys (‘C-p’, ‘C-n’, ‘C-b’, ‘C-f’
+etc), whose global bindings are not shadowed. To move to another
+section use the following commands.
+
+‘p’ (‘magit-section-backward’)
+ When not at the beginning of a section, then move to the beginning
+ of the current section. At the beginning of a section, instead
+ move to the beginning of the previous visible section.
+
+‘n’ (‘magit-section-forward’)
+ Move to the beginning of the next visible section.
+
+‘M-p’ (‘magit-section-backward-siblings’)
+ Move to the beginning of the previous sibling section. If there is
+ no previous sibling section, then move to the parent section
+ instead.
+
+‘M-n’ (‘magit-section-forward-siblings’)
+ Move to the beginning of the next sibling section. If there is no
+ next sibling section, then move to the parent section instead.
+
+‘^’ (‘magit-section-up’)
+ Move to the beginning of the parent of the current section.
+
+ The above commands all call the hook ‘magit-section-movement-hook’.
+Any of the functions listed below can be used as members of this hook.
+
+ You might want to remove some of the functions that Magit adds using
+‘add-hook’. In doing so you have to make sure you do not attempt to
+remove function that haven’t even been added yet, for example:
+
+ (with-eval-after-load 'magit-diff
+ (remove-hook 'magit-section-movement-hook
+ 'magit-hunk-set-window-start))
+
+ -- Variable: magit-section-movement-hook
+ This hook is run by all of the above movement commands, after
+ arriving at the destination.
+
+ -- Function: magit-hunk-set-window-start
+ This hook function ensures that the beginning of the current
+ section is visible, provided it is a ‘hunk’ section. Otherwise, it
+ does nothing.
+
+ Loading ‘magit-diff’ adds this function to the hook.
+
+ -- Function: magit-section-set-window-start
+ This hook function ensures that the beginning of the current
+ section is visible, regardless of the section’s type. If you add
+ this to ‘magit-section-movement-hook’, then you must remove the
+ hunk-only variant in turn.
+
+ -- Function: magit-log-maybe-show-more-commits
+ This hook function only has an effect in log buffers, and ‘point’
+ is on the "show more" section. If that is the case, then it
+ doubles the number of commits that are being shown.
+
+ Loading ‘magit-log’ adds this function to the hook.
+
+ -- Function: magit-log-maybe-update-revision-buffer
+ When moving inside a log buffer, then this function updates the
+ revision buffer, provided it is already being displayed in another
+ window of the same frame.
+
+ Loading ‘magit-log’ adds this function to the hook.
+
+ -- Function: magit-log-maybe-update-blob-buffer
+ When moving inside a log buffer and another window of the same
+ frame displays a blob buffer, then this function instead displays
+ the blob buffer for the commit at point in that window.
+
+ -- Function: magit-status-maybe-update-revision-buffer
+ When moving inside a status buffer, then this function updates the
+ revision buffer, provided it is already being displayed in another
+ window of the same frame.
+
+ -- Function: magit-status-maybe-update-stash-buffer
+ When moving inside a status buffer, then this function updates the
+ stash buffer, provided it is already being displayed in another
+ window of the same frame.
+
+ -- Function: magit-status-maybe-update-blob-buffer
+ When moving inside a status buffer and another window of the same
+ frame displays a blob buffer, then this function instead displays
+ the blob buffer for the commit at point in that window.
+
+ -- Function: magit-stashes-maybe-update-stash-buffer
+ When moving inside a buffer listing stashes, then this function
+ updates the stash buffer, provided it is already being displayed in
+ another window of the same frame.
+
+ -- User Option: magit-update-other-window-delay
+ Delay before automatically updating the other window.
+
+ When moving around in certain buffers, then certain other buffers,
+ which are being displayed in another window, may optionally be
+ updated to display information about the section at point.
+
+ When holding down a key to move by more than just one section, then
+ that would update that buffer for each section on the way. To
+ prevent that, updating the revision buffer is delayed, and this
+ option controls for how long. For optimal experience you might
+ have to adjust this delay and/or the keyboard repeat rate and delay
+ of your graphical environment or operating system.
+
+
+File: magit.info, Node: Section Visibility, Next: Section Hooks, Prev: Section Movement, Up: Sections
+
+4.2.2 Section Visibility
+------------------------
+
+Magit provides many commands for changing the visibility of sections,
+but all you need to get started are the next two.
+
+‘<TAB>’ (‘magit-section-toggle’)
+ Toggle the visibility of the body of the current section.
+
+‘C-<tab>’ (‘magit-section-cycle’)
+ Cycle the visibility of current section and its children.
+
+‘M-<tab>’ (‘magit-section-cycle-diffs’)
+ Cycle the visibility of diff-related sections in the current
+ buffer.
+
+‘S-<tab>’ (‘magit-section-cycle-global’)
+ Cycle the visibility of all sections in the current buffer.
+
+‘1’ (‘magit-section-show-level-1’)
+‘2’ (‘magit-section-show-level-2’)
+‘3’ (‘magit-section-show-level-3’)
+‘4’ (‘magit-section-show-level-4’)
+ Show sections surrounding the current section up to level N.
+
+‘M-1’ (‘magit-section-show-level-1-all’)
+‘M-2’ (‘magit-section-show-level-2-all’)
+‘M-3’ (‘magit-section-show-level-3-all’)
+‘M-4’ (‘magit-section-show-level-4-all’)
+ Show all sections up to level N.
+
+ Some functions, which are used to implement the above commands, are
+also exposed as commands themselves. By default no keys are bound to
+these commands, as they are generally perceived to be much less useful.
+But your mileage may vary.
+
+ -- Command: magit-section-show
+ Show the body of the current section.
+
+ -- Command: magit-section-hide
+ Hide the body of the current section.
+
+ -- Command: magit-section-show-headings
+ Recursively show headings of children of the current section. Only
+ show the headings. Previously shown text-only bodies are hidden.
+
+ -- Command: magit-section-show-children
+ Recursively show the bodies of children of the current section.
+ With a prefix argument show children down to the level of the
+ current section, and hide deeper children.
+
+ -- Command: magit-section-hide-children
+ Recursively hide the bodies of children of the current section.
+
+ -- Command: magit-section-toggle-children
+ Toggle visibility of bodies of children of the current section.
+
+ When a buffer is first created then some sections are shown expanded
+while others are not. This is hard coded. When a buffer is refreshed
+then the previous visibility is preserved. The initial visibility of
+certain sections can also be overwritten using the hook
+‘magit-section-set-visibility-hook’.
+
+ -- User Option: magit-section-initial-visibility-alist
+ This options can be used to override the initial visibility of
+ sections. In the future it will also be used to define the
+ defaults, but currently a section’s default is still hardcoded.
+
+ The value is an alist. Each element maps a section type or lineage
+ to the initial visibility state for such sections. The state has
+ to be one of ‘show’ or ‘hide’, or a function that returns one of
+ these symbols. A function is called with the section as the only
+ argument.
+
+ Use the command ‘magit-describe-section-briefly’ to determine a
+ section’s lineage or type. The vector in the output is the section
+ lineage and the type is the first element of that vector.
+ Wildcards can be used, see ‘magit-section-match’.
+
+ -- User Option: magit-section-cache-visibility
+ This option controls for which sections the previous visibility
+ state should be restored if a section disappears and later appears
+ again. The value is a boolean or a list of section types. If t,
+ then the visibility of all sections is cached. Otherwise this is
+ only done for sections whose type matches one of the listed types.
+
+ This requires that the function ‘magit-section-cached-visibility’
+ is a member of ‘magit-section-set-visibility-hook’.
+
+ -- Variable: magit-section-set-visibility-hook
+ This hook is run when first creating a buffer and also when
+ refreshing an existing buffer, and is used to determine the
+ visibility of the section currently being inserted.
+
+ Each function is called with one argument, the section being
+ inserted. It should return ‘hide’ or ‘show’, or to leave the
+ visibility undefined ‘nil’. If no function decides on the
+ visibility and the buffer is being refreshed, then the visibility
+ is preserved; or if the buffer is being created, then the hard
+ coded default is used.
+
+ Usually this should only be used to set the initial visibility but
+ not during refreshes. If ‘magit-insert-section--oldroot’ is
+ non-nil, then the buffer is being refreshed and these functions
+ should immediately return ‘nil’.
+
+ -- User Option: magit-section-visibility-indicator
+ This option controls whether and how to indicate that a section can
+ be expanded/collapsed.
+
+ If nil, then no visibility indicators are shown. Otherwise the
+ value has to have one of these two forms:
+
+ • ‘(EXPANDABLE-BITMAP . COLLAPSIBLE-BITMAP)’
+
+ Both values have to be variables whose values are fringe
+ bitmaps. In this case every section that can be expanded or
+ collapsed gets an indicator in the left fringe.
+
+ To provide extra padding around the indicator, set
+ ‘left-fringe-width’ in ‘magit-mode-hook’, e.g.:
+
+ (add-hook 'magit-mode-hook (lambda ()
+ (setq left-fringe-width 20)))
+
+ • ‘(STRING . BOOLEAN)’
+
+ In this case STRING (usually an ellipsis) is shown at the end
+ of the heading of every collapsed section. Expanded sections
+ get no indicator. The cdr controls whether the appearance of
+ these ellipsis take section highlighting into account. Doing
+ so might potentially have an impact on performance, while not
+ doing so is kinda ugly.
+
+
+File: magit.info, Node: Section Hooks, Next: Section Types and Values, Prev: Section Visibility, Up: Sections
+
+4.2.3 Section Hooks
+-------------------
+
+Which sections are inserted into certain buffers is controlled with
+hooks. This includes the status and the refs buffers. For other
+buffers, e.g. log and diff buffers, this is not possible. The command
+‘magit-describe-section’ can be used to see which hook (if any) was
+responsible for inserting the section at point.
+
+ For buffers whose sections can be customized by the user, a hook
+variable called ‘magit-TYPE-sections-hook’ exists. This hook should be
+changed using ‘magit-add-section-hook’. Avoid using ‘add-hooks’ or the
+Custom interface.
+
+ The various available section hook variables are described later in
+this manual along with the appropriate "section inserter functions".
+
+ -- Function: magit-add-section-hook hook function &optional at append
+ local
+ Add the function FUNCTION to the value of section hook HOOK.
+
+ Add FUNCTION at the beginning of the hook list unless optional
+ APPEND is non-nil, in which case FUNCTION is added at the end. If
+ FUNCTION already is a member then move it to the new location.
+
+ If optional AT is non-nil and a member of the hook list, then add
+ FUNCTION next to that instead. Add before or after AT, or replace
+ AT with FUNCTION depending on APPEND. If APPEND is the symbol
+ ‘replace’, then replace AT with FUNCTION. For any other non-nil
+ value place FUNCTION right after AT. If nil, then place FUNCTION
+ right before AT. If FUNCTION already is a member of the list but
+ AT is not, then leave FUNCTION where ever it already is.
+
+ If optional LOCAL is non-nil, then modify the hook’s buffer-local
+ value rather than its global value. This makes the hook local by
+ copying the default value. That copy is then modified.
+
+ HOOK should be a symbol. If HOOK is void, it is first set to nil.
+ HOOK’s value must not be a single hook function. FUNCTION should
+ be a function that takes no arguments and inserts one or multiple
+ sections at point, moving point forward. FUNCTION may choose not
+ to insert its section(s), when doing so would not make sense. It
+ should not be abused for other side-effects.
+
+ To remove a function from a section hook, use ‘remove-hook’.
+
+
+File: magit.info, Node: Section Types and Values, Next: Section Options, Prev: Section Hooks, Up: Sections
+
+4.2.4 Section Types and Values
+------------------------------
+
+Each section has a type, for example ‘hunk’, ‘file’, and ‘commit’.
+Instances of certain section types also have a value. The value of a
+section of type ‘file’, for example, is a file name.
+
+ Users usually do not have to worry about a section’s type and value,
+but knowing them can be handy at times.
+
+‘H’ (‘magit-describe-section’)
+ This command shows information about the section at point in a
+ separate buffer.
+
+ -- Command: magit-describe-section-briefly
+ This command shows information about the section at point in the
+ echo area, as ‘#<magit-section VALUE [TYPE PARENT-TYPE...]
+ BEGINNING-END>’.
+
+ Many commands behave differently depending on the type of the section
+at point and/or somehow consume the value of that section. But that is
+only one of the reasons why the same key may do something different,
+depending on what section is current.
+
+ Additionally for each section type a keymap *might* be defined, named
+‘magit-TYPE-section-map’. That keymap is used as text property keymap
+of all text belonging to any section of the respective type. If such a
+map does not exist for a certain type, then you can define it yourself,
+and it will automatically be used.
+
+
+File: magit.info, Node: Section Options, Prev: Section Types and Values, Up: Sections
+
+4.2.5 Section Options
+---------------------
+
+This section describes options that have an effect on more than just a
+certain type of sections. As you can see there are not many of those.
+
+ -- User Option: magit-section-show-child-count
+ Whether to append the number of children to section headings. This
+ only affects sections that could benefit from this information.
+
+
+File: magit.info, Node: Transient Commands, Next: Transient Arguments and Buffer Variables, Prev: Sections, Up: Interface Concepts
+
+4.3 Transient Commands
+======================
+
+Many Magit commands are implemented as *transient* commands. First the
+user invokes a *prefix* command, which causes its *infix* arguments and
+*suffix* commands to be displayed in the echo area. The user then
+optionally sets some infix arguments and finally invokes one of the
+suffix commands.
+
+ This is implemented in the library ‘transient’. Earlier Magit
+releases used the package ‘magit-popup’ and even earlier versions
+library ‘magit-key-mode’.
+
+ Transient is documented in *note (transient)Top::.
+
+‘C-c C-c’ (‘magit-dispatch’)
+ This transient prefix command binds most of Magit’s other prefix
+ commands as suffix commands and displays them in a temporary buffer
+ until one of them is invoked. Invoking such a sub-prefix causes
+ the suffixes of that command to be bound and displayed instead of
+ those of ‘magit-dispatch’.
+
+ This command is also, or especially, useful outside Magit buffers, so
+you should setup a global binding:
+
+ (global-set-key (kbd "C-x M-g") 'magit-dispatch)
+
+
+File: magit.info, Node: Transient Arguments and Buffer Variables, Next: Completion Confirmation and the Selection, Prev: Transient Commands, Up: Interface Concepts
+
+4.4 Transient Arguments and Buffer Variables
+============================================
+
+The infix arguments of many of Magit’s transient prefix commands cease
+to have an effect once the ‘git’ command that is called with those
+arguments has returned. Commands that create a commit are a good
+example for this. If the user changes the arguments, then that only
+affects the next invocation of a suffix command. If the same transient
+prefix command is later invoked again, then the arguments are initially
+reset to the default value. This default value can be set for the
+current Emacs session or saved permanently, see *note (transient)Saving
+Values::. It is also possible to cycle through previously used sets of
+arguments using ‘M-p’ and ‘M-n’, see *note (transient)Using History::.
+
+ However the infix arguments of many other transient commands continue
+to have an effect even after the ‘git’ command that was called with
+those arguments has returned. The most important commands like this are
+those that display a diff or log in a dedicated buffer. Their arguments
+obviously continue to have an effect for as long as the respective diff
+or log is being displayed. Furthermore the used arguments are stored in
+buffer-local variables for future reference.
+
+ For commands in the second group it isn’t always desirable to reset
+their arguments to the global value when the transient prefix command is
+invoked again.
+
+ As mentioned above, it is possible to cycle through previously used
+sets of arguments while a transient popup is visible. That means that
+we could always reset the infix arguments to the default because the set
+of arguments that is active in the existing buffer is only a few ‘M-p’
+away. Magit can be configured to behave like that, but because I expect
+that most users would not find that very convenient, it is not the
+default.
+
+ Also note that it is possible to change the diff and log arguments
+used in the current buffer (including the status buffer, which contains
+both diff and log sections) using the respective "refresh" transient
+prefix commands on ‘D’ and ‘L’. (‘d’ and ‘l’ on the other hand are
+intended to change *what* diff or log is being displayed. It is
+possible to also change *how* the diff or log is being displayed at the
+same time, but if you only want to do the latter, then you should use
+the refresh variants.) Because these secondary diff and log transient
+prefixes are about *changing* the arguments used in the current buffer,
+they *always* start out with the set of arguments that are currently in
+effect in that buffer.
+
+ Some commands are usually invoked directly even though they can also
+be invoked as the suffix of a transient prefix command. Most
+prominently ‘magit-show-commit’ is usually invoked by typing ‘RET’ while
+point is on a commit in a log, but it can also be invoked from the
+‘magit-diff’ transient prefix.
+
+ When such a command is invoked directly, then it is important to
+reuse the arguments as specified by the respective buffer-local values,
+instead of using the default arguments. Imagine you press ‘RET’ in a
+log to display the commit at point in a different buffer and then use
+‘D’ to change how the diff is displayed in that buffer. And then you
+press ‘RET’ on another commit to show that instead and the diff
+arguments are reset to the default. Not cool; so Magit does not do that
+by default.
+
+ -- User Option: magit-prefix-use-buffer-arguments
+ This option controls whether the infix arguments initially shown in
+ certain transient prefix commands are based on the arguments that
+ are currently in effect in the buffer that their suffixes update.
+
+ The ‘magit-diff’ and ‘magit-log’ transient prefix commands are
+ affected by this option.
+
+ -- User Option: magit-direct-use-buffer-arguments
+ This option controls whether certain commands, when invoked
+ directly (i.e. not as the suffix of a transient prefix command),
+ use the arguments that are currently active in the buffer that they
+ are about to update. The alternative is to use the default value
+ for these arguments, which might change the arguments that are used
+ in the buffer.
+
+Valid values for both of the above options are:
+
+ • ‘always’: Always use the set of arguments that is currently active
+ in the respective buffer, provided that buffer exists of course.
+ • ‘selected’ or ‘t’: Use the set of arguments from the respective
+ buffer, but only if it is displayed in a window of the current
+ frame. This is the default for both variables.
+ • ‘current’: Use the set of arguments from the respective buffer, but
+ only if it is the current buffer.
+ • ‘never’: Never use the set of arguments from the respective buffer.
+
+I am afraid it gets more complicated still:
+
+ • The global diff and log arguments are set for each supported mode
+ individually. The diff arguments for example have different values
+ in ‘magit-diff-mode’, ‘magit-revision-mode’,
+ ‘magit-merge-preview-mode’ and ‘magit-status-mode’ buffers.
+ Setting or saving the value for one mode does not change the value
+ for other modes. The history however is shared.
+
+ • When ‘magit-show-commit’ is invoked directly from a log buffer,
+ then the file filter is picked up from that buffer, not from the
+ revision buffer or the mode’s global diff arguments.
+
+ • Even though they are suffixes of the diff prefix
+ ‘magit-show-commit’ and ‘magit-stash-show’ do not use the diff
+ buffer used by the diff commands, instead they use the dedicated
+ revision and stash buffers.
+
+ At the time you invoke the diff prefix it is unknown to Magit which
+ of the suffix commands you are going to invoke. While not certain,
+ more often than not users invoke one of the commands that use the
+ diff buffer, so the initial infix arguments are those used in that
+ buffer. However if you invoke one of these commands directly, then
+ Magit knows that it should use the arguments from the revision
+ resp. stash buffer.
+
+ • The log prefix also features reflog commands, but these commands do
+ not use the log arguments.
+
+ • If ‘magit-show-refs’ is invoked from a ‘magit-refs-mode’ buffer,
+ then it acts as a refresh prefix and therefore unconditionally uses
+ the buffer’s arguments as initial arguments. If it is invoked
+ elsewhere with a prefix argument, then it acts as regular prefix
+ and therefore respects ‘magit-prefix-use-buffer-arguments’. If it
+ is invoked elsewhere without a prefix argument, then it acts as a
+ direct command and therefore respects
+ ‘magit-direct-use-buffer-arguments’.
+
+
+File: magit.info, Node: Completion Confirmation and the Selection, Next: Mouse Support, Prev: Transient Arguments and Buffer Variables, Up: Interface Concepts
+
+4.5 Completion, Confirmation and the Selection
+==============================================
+
+* Menu:
+
+* Action Confirmation::
+* Completion and Confirmation::
+* The Selection::
+* The hunk-internal region::
+* Support for Completion Frameworks::
+* Additional Completion Options::
+
+
+File: magit.info, Node: Action Confirmation, Next: Completion and Confirmation, Up: Completion Confirmation and the Selection
+
+4.5.1 Action Confirmation
+-------------------------
+
+By default many actions that could potentially lead to data loss have to
+be confirmed. This includes many very common actions, so this can
+quickly become annoying. Many of these actions can be undone and if you
+have thought about how to undo certain mistakes, then it should be safe
+to disable confirmation for the respective actions.
+
+ The option ‘magit-no-confirm’ can be used to tell Magit to perform
+certain actions without the user having to confirm them. Note that
+while this option can only be used to disable confirmation for a
+specific set of actions, the next section explains another way of
+telling Magit to ask fewer questions.
+
+ -- User Option: magit-no-confirm
+ The value of this option is a list of symbols, representing actions
+ that do not have to be confirmed by the user before being carried
+ out.
+
+ By default many potentially dangerous commands ask the user for
+ confirmation. Each of the below symbols stands for an action
+ which, when invoked unintentionally or without being fully aware of
+ the consequences, could lead to tears. In many cases there are
+ several commands that perform variations of a certain action, so we
+ don’t use the command names but more generic symbols.
+
+ • Applying changes:
+
+ • ‘discard’ Discarding one or more changes (i.e. hunks or
+ the complete diff for a file) loses that change,
+ obviously.
+
+ • ‘reverse’ Reverting one or more changes can usually be
+ undone by reverting the reversion.
+
+ • ‘stage-all-changes’, ‘unstage-all-changes’ When there are
+ both staged and unstaged changes, then un-/staging
+ everything would destroy that distinction. Of course
+ that also applies when un-/staging a single change, but
+ then less is lost and one does that so often that having
+ to confirm every time would be unacceptable.
+
+ • Files:
+
+ • ‘delete’ When a file that isn’t yet tracked by Git is
+ deleted, then it is completely lost, not just the last
+ changes. Very dangerous.
+
+ • ‘trash’ Instead of deleting a file it can also be move to
+ the system trash. Obviously much less dangerous than
+ deleting it.
+
+ Also see option ‘magit-delete-by-moving-to-trash’.
+
+ • ‘resurrect’ A deleted file can easily be resurrected by
+ "deleting" the deletion, which is done using the same
+ command that was used to delete the same file in the
+ first place.
+
+ • ‘untrack’ Untracking a file can be undone by tracking it
+ again.
+
+ • ‘rename’ Renaming a file can easily be undone.
+
+ • Sequences:
+
+ • ‘reset-bisect’ Aborting (known to Git as "resetting") a
+ bisect operation loses all information collected so far.
+
+ • ‘abort-rebase’ Aborting a rebase throws away all already
+ modified commits, but it’s possible to restore those from
+ the reflog.
+
+ • ‘abort-merge’ Aborting a merge throws away all conflict
+ resolutions which have already been carried out by the
+ user.
+
+ • ‘merge-dirty’ Merging with a dirty worktree can make it
+ hard to go back to the state before the merge was
+ initiated.
+
+ • References:
+
+ • ‘delete-unmerged-branch’ Once a branch has been deleted,
+ it can only be restored using low-level recovery tools
+ provided by Git. And even then the reflog is gone. The
+ user always has to confirm the deletion of a branch by
+ accepting the default choice (or selecting another
+ branch), but when a branch has not been merged yet, also
+ make sure the user is aware of that.
+
+ • ‘delete-pr-remote’ When deleting a branch that was
+ created from a pull-request and if no other branches
+ still exist on that remote, then ‘magit-branch-delete’
+ offers to delete the remote as well. This should be safe
+ because it only happens if no other refs exist in the
+ remotes namespace, and you can recreate the remote if
+ necessary.
+
+ • ‘drop-stashes’ Dropping a stash is dangerous because Git
+ stores stashes in the reflog. Once a stash is removed,
+ there is no going back without using low-level recovery
+ tools provided by Git. When a single stash is dropped,
+ then the user always has to confirm by accepting the
+ default (or selecting another). This action only
+ concerns the deletion of multiple stashes at once.
+
+ • Publishing:
+
+ • ‘set-and-push’ When pushing to the upstream or the
+ push-remote and that isn’t actually configured yet, then
+ the user can first set the target. If s/he confirms the
+ default too quickly, then s/he might end up pushing to
+ the wrong branch and if the remote repository is
+ configured to disallow fixing such mistakes, then that
+ can be quite embarrassing and annoying.
+
+ • Edit published history:
+
+ Without adding these symbols here, you will be warned before
+ editing commits that have already been pushed to one of the
+ branches listed in ‘magit-published-branches’.
+
+ • ‘amend-published’ Affects most commands that amend to
+ "HEAD".
+
+ • ‘rebase-published’ Affects commands that perform
+ interactive rebases. This includes commands from the
+ commit transient that modify a commit other than "HEAD",
+ namely the various fixup and squash variants.
+
+ • ‘edit-published’ Affects the commands
+ ‘magit-edit-line-commit’ and
+ ‘magit-diff-edit-hunk-commit’. These two commands make
+ it quite easy to accidentally edit a published commit, so
+ you should think twice before configuring them not to ask
+ for confirmation.
+
+ To disable confirmation completely, add all three symbols here
+ or set ‘magit-published-branches’ to ‘nil’.
+
+ • Various:
+
+ • ‘kill-process’ There seldom is a reason to kill a
+ process.
+
+ • Global settings:
+
+ Instead of adding all of the above symbols to the value of
+ this option, you can also set it to the atom ‘t’, which has
+ the same effect as adding all of the above symbols. Doing
+ that most certainly is a bad idea, especially because other
+ symbols might be added in the future. So even if you don’t
+ want to be asked for confirmation for any of these actions,
+ you are still better of adding all of the respective symbols
+ individually.
+
+ When ‘magit-wip-before-change-mode’ is enabled, then the
+ following actions can be undone fairly easily: ‘discard’,
+ ‘reverse’, ‘stage-all-changes’, and ‘unstage-all-changes’. If
+ and only if this mode is enabled, then ‘safe-with-wip’ has the
+ same effect as adding all of these symbols individually.
+
+
+File: magit.info, Node: Completion and Confirmation, Next: The Selection, Prev: Action Confirmation, Up: Completion Confirmation and the Selection
+
+4.5.2 Completion and Confirmation
+---------------------------------
+
+Many Magit commands ask the user to select from a list of possible
+things to act on, while offering the most likely choice as the default.
+For many of these commands the default is the thing at point, provided
+that it actually is a valid thing to act on. For many commands that act
+on a branch, the current branch serves as the default if there is no
+branch at point.
+
+ These commands combine asking for confirmation and asking for a
+target to act on into a single action. The user can confirm the default
+target using ‘RET’ or abort using ‘C-g’. This is similar to a
+‘y-or-n-p’ prompt, but the keys to confirm or abort differ.
+
+ At the same time the user is also given the opportunity to select
+another target, which is useful because for some commands and/or in some
+situations you might want to select the action before selecting the
+target by moving to it.
+
+ However you might find that for some commands you always want to use
+the default target, if any, or even that you want the command to act on
+the default without requiring any confirmation at all. The option
+‘magit-dwim-selection’ can be used to configure certain commands to that
+effect.
+
+ Note that when the region is active then many commands act on the
+things that are selected using a mechanism based on the region, in many
+cases after asking for confirmation. This region-based mechanism is
+called the "selection" and is described in detail in the next section.
+When a selection exists that is valid for the invoked command, then that
+command never offers to act on something else, and whether it asks for
+confirmation is not controlled by this option.
+
+ Also note that Magit asks for confirmation of certain actions that
+are not coupled with completion (or the selection). Such dialogs are
+also not affected by this option and are described in the previous
+section.
+
+ -- User Option: magit-dwim-selection
+ This option can be used to tell certain commands to use the thing at
+point instead of asking the user to select a candidate to act on, with
+or without confirmation.
+
+ The value has the form ‘((COMMAND nil|PROMPT DEFAULT)...)’.
+
+ • COMMAND is the command that should not prompt for a choice. To
+ have an effect, the command has to use the function
+ ‘magit-completing-read’ or a utility function which in turn uses
+ that function.
+
+ • If the command uses ‘magit-completing-read’ multiple times, then
+ PROMPT can be used to only affect one of these uses. PROMPT, if
+ non-nil, is a regular expression that is used to match against the
+ PROMPT argument passed to ‘magit-completing-read’.
+
+ • DEFAULT specifies how to use the default. If it is ‘t’, then the
+ DEFAULT argument passed to ‘magit-completing-read’ is used without
+ confirmation. If it is ‘ask’, then the user is given a chance to
+ abort. DEFAULT can also be ‘nil’, in which case the entry has no
+ effect.
+
+
+File: magit.info, Node: The Selection, Next: The hunk-internal region, Prev: Completion and Confirmation, Up: Completion Confirmation and the Selection
+
+4.5.3 The Selection
+-------------------
+
+If the region is active, then many Magit commands act on the things that
+are selected using a mechanism based on the region instead of one single
+thing. When the region is not active, then these commands act on the
+thing at point or read a single thing to act on. This is described in
+the previous section — this section only covers how multiple things are
+selected, how that is visualized, and how certain commands behave when
+that is the case.
+
+ Magit’s mechanism for selecting multiple things, or rather sections
+that represent these things, is based on the Emacs region, but the area
+that Magit considers to be selected is typically larger than the region
+and additional restrictions apply.
+
+ Magit makes a distinction between a region that qualifies as forming
+a valid Magit selection and a region that does not. If the region does
+not qualify, then it is displayed as it is in other Emacs buffers. If
+the region does qualify as a Magit selection, then the selection is
+always visualized, while the region itself is only visualized if it
+begins and ends on the same line.
+
+ For a region to qualify as a Magit selection, it must begin in the
+heading of one section and end in the heading of a sibling section.
+Note that if the end of the region is at the very beginning of section
+heading (i.e. at the very beginning of a line) then that section is
+considered to be *inside* the selection.
+
+ This is not consistent with how the region is normally treated in
+Emacs — if the region ends at the beginning of a line, then that line is
+outside the region. Due to how Magit visualizes the selection, it
+should be obvious that this difference exists.
+
+ Not every command acts on every valid selection. Some commands do
+not even consider the location of point, others may act on the section
+at point but not support acting on the selection, and even commands that
+do support the selection of course only do so if it selects things that
+they can act on.
+
+ This is the main reason why the selection must include the section at
+point. Even if a selection exists, the invoked command may disregard
+it, in which case it may act on the current section only. It is much
+safer to only act on the current section but not the other selected
+sections than it is to act on the current section *instead* of the
+selected sections. The latter would be much more surprising and if the
+current section always is part of the selection, then that cannot
+happen.
+
+ -- Variable: magit-keep-region-overlay
+ This variable controls whether the region is visualized as usual
+ even when a valid Magit selection or a hunk-internal region exists.
+ See the doc-string for more information.
+
+
+File: magit.info, Node: The hunk-internal region, Next: Support for Completion Frameworks, Prev: The Selection, Up: Completion Confirmation and the Selection
+
+4.5.4 The hunk-internal region
+------------------------------
+
+Somewhat related to the Magit selection described in the previous
+section is the hunk-internal region.
+
+ Like the selection, the hunk-internal region is based on the Emacs
+region but causes that region to not be visualized as it would in other
+Emacs buffers, and includes the line on which the region ends even if it
+ends at the very beginning of that line.
+
+ Unlike the selection, which is based on a region that must begin in
+the heading of one section and ends in the section of a sibling section,
+the hunk-internal region must begin inside the *body* of a hunk section
+and end in the body of the *same* section.
+
+ The hunk-internal region is honored by "apply" commands, which can,
+among other targets, act on a hunk. If the hunk-internal region is
+active, then such commands act only on the marked part of the hunk
+instead of on the complete hunk.
+
+
+File: magit.info, Node: Support for Completion Frameworks, Next: Additional Completion Options, Prev: The hunk-internal region, Up: Completion Confirmation and the Selection
+
+4.5.5 Support for Completion Frameworks
+---------------------------------------
+
+The built-in option ‘completing-read-function’ specifies the low-level
+function used by ‘completing-read’ to ask a user to select from a list
+of choices. Its default value is ‘completing-read-default’.
+Alternative completion frameworks typically activate themselves by
+substituting their own implementation.
+
+ Mostly for historic reasons Magit provides a similar option named
+‘magit-completing-read-function’, which only controls the low-level
+function used by ‘magit-completing-read’. This option also makes it
+possible to use a different completing mechanism for Magit than for the
+rest of Emacs, but doing that is not recommend.
+
+ You most likely don’t have to customize the magit-specific option to
+use an alternative completion framework. For example, if you enable
+‘ivy-mode’, then Magit will respect that, and if you enable ‘helm-mode’,
+then you are done too.
+
+ However if you want to use Ido, then ‘ido-mode’ won’t do the trick.
+You will also have to install the ‘ido-completing-read+’ package and use
+‘magit-ido-completing-read’ as ‘magit-completing-read-function’.
+
+ -- User Option: magit-completing-read-function
+ The value of this variable is the low-level function used to
+ perform completion by code that uses ‘magit-completing-read’ (as
+ opposed to the built-in ‘completing-read’).
+
+ The default value, ‘magit-builtin-completing-read’, is suitable for
+ the standard completion mechanism, ‘ivy-mode’, and ‘helm-mode’ at
+ least.
+
+ The built-in ‘completing-read’ and ‘completing-read-default’ are
+ *not* suitable to be used here. ‘magit-builtin-completing-read’
+ performs some additional work, and any function used in its place
+ has to do the same.
+
+ -- Function: magit-builtin-completing-read prompt choices &optional
+ predicate require-match initial-input hist def
+ This function performs completion using the built-in
+ ‘completing-read’ and does some additional magit-specific work.
+
+ -- Function: magit-ido-completing-read prompt choices &optional
+ predicate require-match initial-input hist def
+ This function performs completion using ‘ido-completing-read+’ from
+ the package by the same name (which you have to explicitly install)
+ and does some additional magit-specific work.
+
+ We have to use ‘ido-completing-read+’ instead of the
+ ‘ido-completing-read’ that comes with Ido itself, because the
+ latter, while intended as a drop-in replacement, cannot serve that
+ purpose because it violates too many of the implicit conventions.
+
+ -- Function: magit-completing-read prompt choices &optional predicate
+ require-match initial-input hist def fallback
+ This is the function that Magit commands use when they need the
+ user to select a single thing to act on. The arguments have the
+ same meaning as for ‘completing-read’, except for FALLBACK, which
+ is unique to this function and is described below.
+
+ Instead of asking the user to choose from a list of possible
+ candidates, this function may just return the default specified by
+ DEF, with or without requiring user confirmation. Whether that is
+ the case depends on PROMPT, ‘this-command’ and
+ ‘magit-dwim-selection’. See the documentation of the latter for
+ more information.
+
+ If it does read a value in the minibuffer, then this function acts
+ similar to ‘completing-read’, except for the following:
+
+ • COLLECTION must be a list of choices. A function is not
+ supported.
+
+ • If REQUIRE-MATCH is ‘nil’ and the user exits without a choice,
+ then ‘nil’ is returned instead of an empty string.
+
+ • If REQUIRE-MATCH is non-nil and the users exits without a
+ choice, an user-error is raised.
+
+ • FALLBACK specifies a secondary default that is only used if
+ the primary default DEF is ‘nil’. The secondary default is
+ not subject to ‘magit-dwim-selection’ — if DEF is ‘nil’ but
+ FALLBACK is not, then this function always asks the user to
+ choose a candidate, just as if both defaults were ‘nil’.
+
+ • ": " is appended to PROMPT.
+
+ • PROMPT is modified to end with \" (default DEF|FALLBACK): \"
+ provided that DEF or FALLBACK is non-nil, that neither
+ ‘ivy-mode’ nor ‘helm-mode’ is enabled, and that
+ ‘magit-completing-read-function’ is set to its default value
+ of ‘magit-builtin-completing-read’.
+
+
+File: magit.info, Node: Additional Completion Options, Prev: Support for Completion Frameworks, Up: Completion Confirmation and the Selection
+
+4.5.6 Additional Completion Options
+-----------------------------------
+
+ -- User Option: magit-list-refs-sortby
+ For many commands that read a ref or refs from the user, the value
+ of this option can be used to control the order of the refs. Valid
+ values include any key accepted by the ‘--sort’ flag of ‘git
+ for-each-ref’. By default, refs are sorted alphabetically by their
+ full name (e.g., "refs/heads/master").
+
+
+File: magit.info, Node: Mouse Support, Next: Running Git, Prev: Completion Confirmation and the Selection, Up: Interface Concepts
+
+4.6 Mouse Support
+=================
+
+Double clicking on a section heading toggles the visibility of its body,
+if any. Likewise clicking in the left fringe toggles the visibility of
+the appropriate section.
+
+ A context menu is provided but has to be enabled explicitly. In
+Emacs 28 and greater, enable the global mode ‘context-menu-mode’. If
+you use an older Emacs release, set
+‘magit-section-show-context-menu-for-emacs<28’.
+
+
+File: magit.info, Node: Running Git, Prev: Mouse Support, Up: Interface Concepts
+
+4.7 Running Git
+===============
+
+* Menu:
+
+* Viewing Git Output::
+* Git Process Status::
+* Running Git Manually::
+* Git Executable::
+* Global Git Arguments::
+
+
+File: magit.info, Node: Viewing Git Output, Next: Git Process Status, Up: Running Git
+
+4.7.1 Viewing Git Output
+------------------------
+
+Magit runs Git either for side-effects (e.g. when pushing) or to get
+some value (e.g. the name of the current branch).
+
+ When Git is run for side-effects, the process output is logged in a
+per-repository log buffer, which can be consulted using the
+‘magit-process’ command when things don’t go as expected.
+
+ The output/errors for up to ‘magit-process-log-max’ Git commands are
+retained.
+
+‘$’ (‘magit-process’)
+ This commands displays the process buffer for the current
+ repository.
+
+ Inside that buffer, the usual key bindings for navigating and showing
+sections are available. There is one additional command.
+
+‘k’ (‘magit-process-kill’)
+ This command kills the process represented by the section at point.
+
+ -- Variable: magit-git-debug
+ This option controls whether additional reporting of git errors is
+ enabled.
+
+ Magit basically calls git for one of these two reasons: for
+ side-effects or to do something with its standard output.
+
+ When git is run for side-effects then its output, including error
+ messages, go into the process buffer which is shown when using ‘$’.
+
+ When git’s output is consumed in some way, then it would be too
+ expensive to also insert it into this buffer, but when this option
+ is non-nil and git returns with a non-zero exit status, then at
+ least its standard error is inserted into this buffer.
+
+ This is only intended for debugging purposes. Do not enable this
+ permanently, that would negatively affect performance.
+
+ This is only intended for debugging purposes. Do not enable this
+ permanently, that would negatively affect performance. Also note
+ that just because git exits with a non-zero exit status and prints
+ an error message that usually doesn’t mean that it is an error as
+ far as Magit is concerned, which is another reason we usually hide
+ these error messages. Whether some error message is relevant in
+ the context of some unexpected behavior has to be judged on a case
+ by case basis.
+
+ The command ‘magit-toggle-git-debug’ changes the value of this
+ variable.
+
+ -- Variable: magit-process-extreme-logging
+ This option controls whether ‘magit-process-file’ logs to the
+ ‘*Messages*’ buffer.
+
+ Only intended for temporary use when you try to figure out how
+ Magit uses Git behind the scene. Output that normally goes to the
+ magit-process buffer continues to go there. Not all output goes to
+ either of these two buffers.
+
+
+File: magit.info, Node: Git Process Status, Next: Running Git Manually, Prev: Viewing Git Output, Up: Running Git
+
+4.7.2 Git Process Status
+------------------------
+
+When a Git process is running for side-effects, Magit displays an
+indicator in the mode line, using the ‘magit-mode-line-process’ face.
+
+ If the Git process exits successfully, the process indicator is
+removed from the mode line immediately.
+
+ In the case of a Git error, the process indicator is not removed, but
+is instead highlighted with the ‘magit-mode-line-process-error’ face,
+and the error details from the process buffer are provided as a tooltip
+for mouse users. This error indicator persists in the mode line until
+the next magit buffer refresh.
+
+ If you do not wish process errors to be indicated in the mode line,
+customize the ‘magit-process-display-mode-line-error’ user option.
+
+ Process errors are additionally indicated at the top of the status
+buffer.
+
+
+File: magit.info, Node: Running Git Manually, Next: Git Executable, Prev: Git Process Status, Up: Running Git
+
+4.7.3 Running Git Manually
+--------------------------
+
+While Magit provides many Emacs commands to interact with Git, it does
+not cover everything. In those cases your existing Git knowledge will
+come in handy. Magit provides some commands for running arbitrary Git
+commands by typing them into the minibuffer, instead of having to switch
+to a shell.
+
+‘!’ (‘magit-run’)
+ This transient prefix command binds the following suffix commands
+ and displays them in a temporary buffer until a suffix is invoked.
+
+‘! !’ (‘magit-git-command-topdir’)
+ This command reads a command from the user and executes it in the
+ top-level directory of the current working tree.
+
+ The string "git " is used as initial input when prompting the user
+ for the command. It can be removed to run another command.
+
+‘:’ (‘magit-git-command’)
+‘! p’
+ This command reads a command from the user and executes it in
+ ‘default-directory’. With a prefix argument the command is
+ executed in the top-level directory of the current working tree
+ instead.
+
+ The string "git " is used as initial input when prompting the user
+ for the command. It can be removed to run another command.
+
+‘! s’ (‘magit-shell-command-topdir’)
+ This command reads a command from the user and executes it in the
+ top-level directory of the current working tree.
+
+‘! S’ (‘magit-shell-command’)
+ This command reads a command from the user and executes it in
+ ‘default-directory’. With a prefix argument the command is
+ executed in the top-level directory of the current working tree
+ instead.
+
+ -- User Option: magit-shell-command-verbose-prompt
+ Whether the prompt, used by the above commands when reading a shell
+ command, shows the directory in which it will be run.
+
+ These suffix commands start external gui tools.
+
+‘! k’ (‘magit-run-gitk’)
+ This command runs ‘gitk’ in the current repository.
+
+‘! a’ (‘magit-run-gitk-all’)
+ This command runs ‘gitk --all’ in the current repository.
+
+‘! b’ (‘magit-run-gitk-branches’)
+ This command runs ‘gitk --branches’ in the current repository.
+
+‘! g’ (‘magit-run-git-gui’)
+ This command runs ‘git gui’ in the current repository.
+
+‘! m’ (‘magit-git-mergetool’)
+ This command runs ‘git mergetool --gui’ in the current repository.
+
+ With a prefix argument this acts as a transient prefix command,
+ allowing the user to select the mergetool and change some settings.
+
+
+File: magit.info, Node: Git Executable, Next: Global Git Arguments, Prev: Running Git Manually, Up: Running Git
+
+4.7.4 Git Executable
+--------------------
+
+When Magit calls Git, then it may do so using the absolute path to the
+‘git’ executable, or using just its name.
+
+ When running ‘git’ locally and the ‘system-type’ is ‘windows-nt’ (any
+Windows version) or ‘darwin’ (macOS) then ‘magit-git-executable’ is set
+to an absolute path when Magit is loaded.
+
+ On Windows it is necessary to use an absolute path because Git comes
+with several wrapper scripts for the actual ‘git’ binary, which are also
+placed on ‘$PATH’, and using one of these wrappers instead of the binary
+would degrade performance horribly. For some macOS users using just the
+name of the executable also performs horribly, so we avoid doing that on
+that platform as well. On other platforms, using just the name seems to
+work just fine.
+
+ Using an absolute path when running ‘git’ on a remote machine over
+Tramp, would be problematic to use an absolute path that is suitable on
+the local machine, so a separate option is used to control the name or
+path that is used on remote machines.
+
+ -- User Option: magit-git-executable
+ The ‘git’ executable used by Magit on the local host. This should
+ be either the absolute path to the executable, or the string "git"
+ to let Emacs find the executable itself, using the standard
+ mechanism for doing such things.
+
+ -- User Option: magit-remote-git-executable
+ The ‘git’ executable used by Magit on remote machines over Tramp.
+ Normally this should be just the string "git". Consider
+ customizing ‘tramp-remote-path’ instead of this option.
+
+ If Emacs is unable to find the correct executable, then you can work
+around that by explicitly setting the value of one of these two options.
+Doing that should be considered a kludge; it is better to make sure that
+the order in ‘exec-path’ or ‘tramp-remote-path’ is correct.
+
+ Note that ‘exec-path’ is set based on the value of the ‘PATH’
+environment variable that is in effect when Emacs is started. If you
+set ‘PATH’ in your shell’s init files, then that only has an effect on
+Emacs if you start it from that shell (because the environment of a
+process is only passed to its child processes, not to arbitrary other
+processes). If that is not how you start Emacs, then the
+‘exec-path-from-shell’ package can help; though honestly I consider that
+a kludge too.
+
+ The command ‘magit-debug-git-executable’ can be useful to find out
+where Emacs is searching for ‘git’.
+
+‘M-x magit-debug-git-executable’
+ This command displays a buffer with information about
+ ‘magit-git-executable’ and ‘magit-remote-git-executable’.
+
+‘M-x magit-version’
+ This command shows the currently used versions of Magit, Git, and
+ Emacs in the echo area. Non-interactively this just returns the
+ Magit version.
+
+
+File: magit.info, Node: Global Git Arguments, Prev: Git Executable, Up: Running Git
+
+4.7.5 Global Git Arguments
+--------------------------
+
+ -- User Option: magit-git-global-arguments
+ The arguments set here are used every time the git executable is
+ run as a subprocess. They are placed right after the executable
+ itself and before the git command - as in ‘git HERE... COMMAND
+ REST’. For valid arguments see *note (gitman)git::.
+
+ Be careful what you add here, especially if you are using Tramp to
+ connect to servers with ancient Git versions. Never remove
+ anything that is part of the default value, unless you really know
+ what you are doing. And think very hard before adding something;
+ it will be used every time Magit runs Git for any purpose.
+
+
+File: magit.info, Node: Inspecting, Next: Manipulating, Prev: Interface Concepts, Up: Top
+
+5 Inspecting
+************
+
+The functionality provided by Magit can be roughly divided into three
+groups: inspecting existing data, manipulating existing data or adding
+new data, and transferring data. Of course that is a rather crude
+distinction that often falls short, but it’s more useful than no
+distinction at all. This section is concerned with inspecting data, the
+next two with manipulating and transferring it. Then follows a section
+about miscellaneous functionality, which cannot easily be fit into this
+distinction.
+
+ Of course other distinctions make sense too, e.g. Git’s distinction
+between porcelain and plumbing commands, which for the most part is
+equivalent to Emacs’ distinction between interactive commands and
+non-interactive functions. All of the sections mentioned before are
+mainly concerned with the porcelain – Magit’s plumbing layer is
+described later.
+
+* Menu:
+
+* Status Buffer::
+* Repository List::
+* Logging::
+* Diffing::
+* Ediffing::
+* References Buffer::
+* Bisecting::
+* Visiting Files and Blobs::
+* Blaming::
+
+
+File: magit.info, Node: Status Buffer, Next: Repository List, Up: Inspecting
+
+5.1 Status Buffer
+=================
+
+While other Magit buffers contain e.g. one particular diff or one
+particular log, the status buffer contains the diffs for staged and
+unstaged changes, logs for unpushed and unpulled commits, lists of
+stashes and untracked files, and information related to the current
+branch.
+
+ During certain incomplete operations – for example when a merge
+resulted in a conflict – additional information is displayed that helps
+proceeding with or aborting the operation.
+
+ The command ‘magit-status’ displays the status buffer belonging to
+the current repository in another window. This command is used so often
+that it should be bound globally. We recommend using ‘C-x g’:
+
+ (global-set-key (kbd "C-x g") 'magit-status)
+
+‘C-x g’ (‘magit-status’)
+ When invoked from within an existing Git repository, then this
+ command shows the status of that repository in a buffer.
+
+ If the current directory isn’t located within a Git repository,
+ then this command prompts for an existing repository or an
+ arbitrary directory, depending on the option
+ ‘magit-repository-directories’, and the status for the selected
+ repository is shown instead.
+
+ • If that option specifies any existing repositories, then the
+ user is asked to select one of them.
+
+ • Otherwise the user is asked to select an arbitrary directory
+ using regular file-name completion. If the selected directory
+ is the top-level directory of an existing working tree, then
+ the status buffer for that is shown.
+
+ • Otherwise the user is offered to initialize the selected
+ directory as a new repository. After creating the repository
+ its status buffer is shown.
+
+ These fallback behaviors can also be forced using one or more
+ prefix arguments:
+
+ • With two prefix arguments (or more precisely a numeric prefix
+ value of 16 or greater) an arbitrary directory is read, which
+ is then acted on as described above. The same could be
+ accomplished using the command ‘magit-init’.
+
+ • With a single prefix argument an existing repository is read
+ from the user, or if no repository can be found based on the
+ value of ‘magit-repository-directories’, then the behavior is
+ the same as with two prefix arguments.
+
+ -- User Option: magit-repository-directories
+ List of directories that are Git repositories or contain Git
+ repositories.
+
+ Each element has the form ‘(DIRECTORY . DEPTH)’. DIRECTORY has to
+ be a directory or a directory file-name, a string. DEPTH, an
+ integer, specifies the maximum depth to look for Git repositories.
+ If it is 0, then only add DIRECTORY itself.
+
+ This option controls which repositories are being listed by
+ ‘magit-list-repositories’. It also affects ‘magit-status’ (which
+ see) in potentially surprising ways (see above).
+
+ -- Command: magit-status-quick
+ This command is an alternative to ‘magit-status’ that usually
+ avoids refreshing the status buffer.
+
+ If the status buffer of the current Git repository exists but isn’t
+ being displayed in the selected frame, then it is displayed without
+ being refreshed.
+
+ If the status buffer is being displayed in the selected frame, then
+ this command refreshes it.
+
+ Prefix arguments have the same meaning as for ‘magit-status’, and
+ additionally cause the buffer to be refresh.
+
+ To use this command add this to your init file:
+
+ (global-set-key (kbd "C-x g") 'magit-status-quick).
+
+ If you do that and then for once want to redisplay the buffer and
+ also immediately refresh it, then type ‘C-x g’ followed by ‘g’.
+
+ A possible alternative command is
+ ‘magit-display-repository-buffer’. It supports displaying any
+ existing Magit buffer that belongs to the current repository; not
+ just the status buffer.
+
+ -- Command: ido-enter-magit-status
+ From an Ido prompt used to open a file, instead drop into
+ ‘magit-status’. This is similar to ‘ido-magic-delete-char’, which,
+ despite its name, usually causes a Dired buffer to be created.
+
+ To make this command available, use something like:
+
+ (add-hook 'ido-setup-hook
+ (lambda ()
+ (define-key ido-completion-map
+ (kbd \"C-x g\") 'ido-enter-magit-status)))
+
+ Starting with Emacs 25.1 the Ido keymaps are defined just once
+ instead of every time Ido is invoked, so now you can modify it like
+ pretty much every other keymap:
+
+ (define-key ido-common-completion-map
+ (kbd \"C-x g\") 'ido-enter-magit-status)
+
+* Menu:
+
+* Status Sections::
+* Status Header Sections::
+* Status Module Sections::
+* Status Options::
+
+
+File: magit.info, Node: Status Sections, Next: Status Header Sections, Up: Status Buffer
+
+5.1.1 Status Sections
+---------------------
+
+The contents of status buffers is controlled using the hook
+‘magit-status-sections-hook’. See *note Section Hooks:: to learn about
+such hooks and how to customize them.
+
+ -- User Option: magit-status-sections-hook
+ Hook run to insert sections into a status buffer.
+
+ The first function on that hook by default is
+‘magit-insert-status-headers’; it is described in the next section. By
+default the following functions are also members of that hook:
+
+ -- Function: magit-insert-merge-log
+ Insert section for the on-going merge. Display the heads that are
+ being merged. If no merge is in progress, do nothing.
+
+ -- Function: magit-insert-rebase-sequence
+ Insert section for the on-going rebase sequence. If no such
+ sequence is in progress, do nothing.
+
+ -- Function: magit-insert-am-sequence
+ Insert section for the on-going patch applying sequence. If no
+ such sequence is in progress, do nothing.
+
+ -- Function: magit-insert-sequencer-sequence
+ Insert section for the on-going cherry-pick or revert sequence. If
+ no such sequence is in progress, do nothing.
+
+ -- Function: magit-insert-bisect-output
+ While bisecting, insert section with output from ‘git bisect’.
+
+ -- Function: magit-insert-bisect-rest
+ While bisecting, insert section visualizing the bisect state.
+
+ -- Function: magit-insert-bisect-log
+ While bisecting, insert section logging bisect progress.
+
+ -- Function: magit-insert-untracked-files
+ Maybe insert a list or tree of untracked files.
+
+ Do so depending on the value of ‘status.showUntrackedFiles’. Note
+ that even if the value is ‘all’, Magit still initially only shows
+ directories. But the directory sections can then be expanded using
+ ‘TAB’.
+
+ -- Function: magit-insert-unstaged-changes
+ Insert section showing unstaged changes.
+
+ -- Function: magit-insert-staged-changes
+ Insert section showing staged changes.
+
+ -- Function: magit-insert-stashes &optional ref heading
+ Insert the ‘stashes’ section showing reflog for "refs/stash". If
+ optional REF is non-nil show reflog for that instead. If optional
+ HEADING is non-nil use that as section heading instead of
+ "Stashes:".
+
+ -- Function: magit-insert-unpulled-from-upstream
+ Insert section showing commits that haven’t been pulled from the
+ upstream branch yet.
+
+ -- Function: magit-insert-unpulled-from-pushremote
+ Insert section showing commits that haven’t been pulled from the
+ push-remote branch yet.
+
+ -- Function: magit-insert-unpushed-to-upstream
+ Insert section showing commits that haven’t been pushed to the
+ upstream yet.
+
+ -- Function: magit-insert-unpushed-to-pushremote
+ Insert section showing commits that haven’t been pushed to the
+ push-remote yet.
+
+ The following functions can also be added to the above hook:
+
+ -- Function: magit-insert-tracked-files
+ Insert a tree of tracked files.
+
+ -- Function: magit-insert-ignored-files
+ Insert a tree of ignored files. Its possible to limit the logs in
+ the current buffer to a certain directory using ‘D = f <DIRECTORY>
+ RET g’. If you do that, then that that also affects this command.
+
+ The log filter can be used to limit to multiple files. In that
+ case this function only respects the first of the files and only if
+ it is a directory.
+
+ -- Function: magit-insert-skip-worktree-files
+ Insert a tree of skip-worktree files. If the first element of
+ ‘magit-buffer-diff-files’ is a directory, then limit the list to
+ files below that. The value of that variable can be set using ‘D
+ -- DIRECTORY RET g’.
+
+ -- Function: magit-insert-assumed-unchanged-files
+ Insert a tree of files that are assumed to be unchanged. If the
+ first element of ‘magit-buffer-diff-files’ is a directory, then
+ limit the list to files below that. The value of that variable can
+ be set using ‘D -- DIRECTORY RET g’.
+
+ -- Function: magit-insert-unpulled-or-recent-commits
+ Insert section showing unpulled or recent commits. If an upstream
+ is configured for the current branch and it is ahead of the current
+ branch, then show the missing commits. Otherwise, show the last
+ ‘magit-log-section-commit-count’ commits.
+
+ -- Function: magit-insert-recent-commits
+ Insert section showing the last ‘magit-log-section-commit-count’
+ commits.
+
+ -- User Option: magit-log-section-commit-count
+ How many recent commits ‘magit-insert-recent-commits’ and
+ ‘magit-insert-unpulled-or-recent-commits’ (provided there are no
+ unpulled commits) show.
+
+ -- Function: magit-insert-unpulled-cherries
+ Insert section showing unpulled commits. Like
+ ‘magit-insert-unpulled-commits’ but prefix each commit that has not
+ been applied yet (i.e. a commit with a patch-id not shared with
+ any local commit) with "+", and all others with "-".
+
+ -- Function: magit-insert-unpushed-cherries
+ Insert section showing unpushed commits. Like
+ ‘magit-insert-unpushed-commits’ but prefix each commit which has
+ not been applied to upstream yet (i.e. a commit with a patch-id
+ not shared with any upstream commit) with "+" and all others with
+ "-".
+
+ See *note References Buffer:: for some more section inserters, which
+could be used here.
+
+
+File: magit.info, Node: Status Header Sections, Next: Status Module Sections, Prev: Status Sections, Up: Status Buffer
+
+5.1.2 Status Header Sections
+----------------------------
+
+The contents of status buffers is controlled using the hook
+‘magit-status-sections-hook’ (see *note Status Sections::).
+
+ By default ‘magit-insert-status-headers’ is the first member of that
+hook variable.
+
+ -- Function: magit-insert-status-headers
+ Insert headers sections appropriate for ‘magit-status-mode’
+ buffers. The sections are inserted by running the functions on the
+ hook ‘magit-status-headers-hook’.
+
+ -- User Option: magit-status-headers-hook
+ Hook run to insert headers sections into the status buffer.
+
+ This hook is run by ‘magit-insert-status-headers’, which in turn
+ has to be a member of ‘magit-status-sections-hook’ to be used at
+ all.
+
+ By default the following functions are members of the above hook:
+
+ -- Function: magit-insert-error-header
+ Insert a header line showing the message about the Git error that
+ just occurred.
+
+ This function is only aware of the last error that occur when Git
+ was run for side-effects. If, for example, an error occurs while
+ generating a diff, then that error won’t be inserted. Refreshing
+ the status buffer causes this section to disappear again.
+
+ -- Function: magit-insert-diff-filter-header
+ Insert a header line showing the effective diff filters.
+
+ -- Function: magit-insert-head-branch-header
+ Insert a header line about the current branch or detached ‘HEAD’.
+
+ -- Function: magit-insert-upstream-branch-header
+ Insert a header line about the branch that is usually pulled into
+ the current branch.
+
+ -- Function: magit-insert-push-branch-header
+ Insert a header line about the branch that the current branch is
+ usually pushed to.
+
+ -- Function: magit-insert-tags-header
+ Insert a header line about the current and/or next tag, along with
+ the number of commits between the tag and ‘HEAD’.
+
+ The following functions can also be added to the above hook:
+
+ -- Function: magit-insert-repo-header
+ Insert a header line showing the path to the repository top-level.
+
+ -- Function: magit-insert-remote-header
+ Insert a header line about the remote of the current branch.
+
+ If no remote is configured for the current branch, then fall back
+ showing the "origin" remote, or if that does not exist the first
+ remote in alphabetic order.
+
+ -- Function: magit-insert-user-header
+ Insert a header line about the current user.
+
+
+File: magit.info, Node: Status Module Sections, Next: Status Options, Prev: Status Header Sections, Up: Status Buffer
+
+5.1.3 Status Module Sections
+----------------------------
+
+The contents of status buffers is controlled using the hook
+‘magit-status-sections-hook’ (see *note Status Sections::).
+
+ By default ‘magit-insert-modules’ is _not_ a member of that hook
+variable.
+
+ -- Function: magit-insert-modules
+ Insert submodule sections.
+
+ Hook ‘magit-module-sections-hook’ controls which module sections
+ are inserted, and option ‘magit-module-sections-nested’ controls
+ whether they are wrapped in an additional section.
+
+ -- User Option: magit-module-sections-hook
+ Hook run by ‘magit-insert-modules’.
+
+ -- User Option: magit-module-sections-nested
+ This option controls whether ‘magit-insert-modules’ wraps inserted
+ sections in an additional section.
+
+ If this is non-nil, then only a single top-level section is
+ inserted. If it is nil, then all sections listed in
+ ‘magit-module-sections-hook’ become top-level sections.
+
+ -- Function: magit-insert-modules-overview
+ Insert sections for all submodules. For each section insert the
+ path, the branch, and the output of ‘git describe --tags’, or,
+ failing that, the abbreviated HEAD commit hash.
+
+ Press ‘RET’ on such a submodule section to show its own status
+ buffer. Press ‘RET’ on the "Modules" section to display a list of
+ submodules in a separate buffer. This shows additional information
+ not displayed in the super-repository’s status buffer.
+
+ -- Function: magit-insert-modules-unpulled-from-upstream
+ Insert sections for modules that haven’t been pulled from the
+ upstream yet. These sections can be expanded to show the
+ respective commits.
+
+ -- Function: magit-insert-modules-unpulled-from-pushremote
+ Insert sections for modules that haven’t been pulled from the
+ push-remote yet. These sections can be expanded to show the
+ respective commits.
+
+ -- Function: magit-insert-modules-unpushed-to-upstream
+ Insert sections for modules that haven’t been pushed to the
+ upstream yet. These sections can be expanded to show the
+ respective commits.
+
+ -- Function: magit-insert-modules-unpushed-to-pushremote
+ Insert sections for modules that haven’t been pushed to the
+ push-remote yet. These sections can be expanded to show the
+ respective commits.
+
+
+File: magit.info, Node: Status Options, Prev: Status Module Sections, Up: Status Buffer
+
+5.1.4 Status Options
+--------------------
+
+ -- User Option: magit-status-refresh-hook
+ Hook run after a status buffer has been refreshed.
+
+ -- User Option: magit-status-margin
+ This option specifies whether the margin is initially shown in
+ Magit-Status mode buffers and how it is formatted.
+
+ The value has the form ‘(INIT STYLE WIDTH AUTHOR AUTHOR-WIDTH)’.
+
+ • If INIT is non-nil, then the margin is shown initially.
+ • STYLE controls how to format the author or committer date. It
+ can be one of ‘age’ (to show the age of the commit),
+ ‘age-abbreviated’ (to abbreviate the time unit to a
+ character), or a string (suitable for ‘format-time-string’) to
+ show the actual date. Option
+ ‘magit-log-margin-show-committer-date’ controls which date is
+ being displayed.
+ • WIDTH controls the width of the margin. This exists for
+ forward compatibility and currently the value should not be
+ changed.
+ • AUTHOR controls whether the name of the author is also shown
+ by default.
+ • AUTHOR-WIDTH has to be an integer. When the name of the
+ author is shown, then this specifies how much space is used to
+ do so.
+
+ Also see the proceeding section for more options concerning status
+buffers.
+
+
+File: magit.info, Node: Repository List, Next: Logging, Prev: Status Buffer, Up: Inspecting
+
+5.2 Repository List
+===================
+
+ -- Command: magit-list-repositories
+ This command displays a list of repositories in a separate buffer.
+
+ The options ‘magit-repository-directories’ and
+ ‘magit-repository-directories-depth’ control which repositories are
+ displayed.
+
+ -- User Option: magit-repolist-columns
+ This option controls what columns are displayed by the command
+ ‘magit-list-repositories’ and how they are displayed.
+
+ Each element has the form ‘(HEADER WIDTH FORMAT PROPS)’.
+
+ HEADER is the string displayed in the header. WIDTH is the width
+ of the column. FORMAT is a function that is called with one
+ argument, the repository identification (usually its basename), and
+ with ‘default-directory’ bound to the toplevel of its working tree.
+ It has to return a string to be inserted or nil. PROPS is an alist
+ that supports the keys ‘:right-align’, ‘:pad-right’ and ‘:sort’.
+
+ The ‘:sort’ function has a weird interface described in the
+ docstring of ‘tabulated-list--get-sort’. Alternatively ‘<’ and
+ ‘magit-repolist-version<’ can be used as those functions are
+ automatically replaced with functions that satisfy the interface.
+ Set ‘:sort’ to ‘nil’ to inhibit sorting; if unspecifed, then the
+ column is sortable using the default sorter.
+
+ You may wish to display a range of numeric columns using just one
+ character per column and without any padding between columns, in
+ which case you should use an appropriat HEADER, set WIDTH to 1, and
+ set ‘:pad-right’ to 9. ‘+’ is substituted for numbers higher than
+ 9.
+
+The following functions can be added to the above option:
+
+ -- Function: magit-repolist-column-ident
+ This function inserts the identification of the repository.
+ Usually this is just its basename.
+
+ -- Function: magit-repolist-column-path
+ This function inserts the absolute path of the repository.
+
+ -- Function: magit-repolist-column-version
+ This function inserts a description of the repository’s ‘HEAD’
+ revision.
+
+ -- Function: magit-repolist-column-branch
+ This function inserts the name of the current branch.
+
+ -- Function: magit-repolist-column-upstream
+ This function inserts the name of the upstream branch of the
+ current branch.
+
+ -- Function: magit-repolist-column-branches
+ This function inserts the number of branches.
+
+ -- Function: magit-repolist-column-stashes
+ This function inserts the number of stashes.
+
+ -- Function: magit-repolist-column-flag
+ This function inserts a flag as specified by
+ ‘magit-repolist-column-flag-alist’.
+
+ By default this indicates whether there are uncommitted changes.
+
+ • ‘N’ if there is at least one untracked file.
+ • ‘U’ if there is at least one unstaged file.
+ • ‘S’ if there is at least one staged file.
+
+ Only the first one of these that applies is shown.
+
+ -- Function: magit-repolist-column-unpulled-from-upstream
+ This function inserts the number of upstream commits not in the
+ current branch.
+
+ -- Function: magit-repolist-column-unpulled-from-pushremote
+ This function inserts the number of commits in the push branch but
+ not the current branch.
+
+ -- Function: magit-repolist-column-unpushed-to-upstream
+ This function inserts the number of commits in the current branch
+ but not its upstream.
+
+ -- Function: magit-repolist-column-unpushed-to-pushremote
+ This function inserts the number of commits in the current branch
+ but not its push branch.
+
+The following commands are available in repolist buffers:
+
+‘<RET>’ (‘magit-repolist-status’)
+ This command shows the status for the repository at point.
+
+‘m’ (‘magit-repolist-mark’)
+ This command marks the repository at point.
+
+‘u’ (‘magit-repolist-unmark’)
+ This command unmarks the repository at point.
+
+‘f’ (‘magit-repolist-fetch’)
+ This command fetches all marked repositories. If no repositories
+ are marked, then it offers to fetch all displayed repositories.
+
+‘5’ (‘magit-repolist-find-file-other-frame’)
+ This command reads a relative file-name (without completion) and
+ opens the respective file in each marked repository in a new frame.
+ If no repositories are marked, then it offers to do this for all
+ displayed repositories.
+
+
+File: magit.info, Node: Logging, Next: Diffing, Prev: Repository List, Up: Inspecting
+
+5.3 Logging
+===========
+
+The status buffer contains logs for the unpushed and unpulled commits,
+but that obviously isn’t enough. The transient prefix command
+‘magit-log’, on ‘l’, features several suffix commands, which show a
+specific log in a separate log buffer.
+
+ Like other transient prefix commands, ‘magit-log’ also features
+several infix arguments that can be changed before invoking one of the
+suffix commands. However, in the case of the log transient, these
+arguments may be taken from those currently in use in the current
+repository’s log buffer, depending on the value of
+‘magit-prefix-use-buffer-arguments’ (see *note Transient Arguments and
+Buffer Variables::).
+
+ For information about the various arguments, see *note
+(gitman)git-log::.
+
+ The switch ‘++order=VALUE’ is converted to one of
+‘--author-date-order’, ‘--date-order’, or ‘--topo-order’ before being
+passed to ‘git log’.
+
+ The log transient also features several reflog commands. See *note
+Reflog::.
+
+‘l’ (‘magit-log’)
+ This transient prefix command binds the following suffix commands
+ along with the appropriate infix arguments and displays them in a
+ temporary buffer until a suffix is invoked.
+
+‘l l’ (‘magit-log-current’)
+ Show log for the current branch. When ‘HEAD’ is detached or with a
+ prefix argument, show log for one or more revs read from the
+ minibuffer.
+
+‘l h’ (‘magit-log-head’)
+ Show log for ‘HEAD’.
+
+‘l u’ (‘magit-log-related’)
+ Show log for the current branch, its upstream and its push target.
+ When the upstream is a local branch, then also show its own
+ upstream. When ‘HEAD’ is detached, then show log for that, the
+ previously checked out branch and its upstream and push-target.
+
+‘l o’ (‘magit-log-other’)
+ Show log for one or more revs read from the minibuffer. The user
+ can input any revision or revisions separated by a space, or even
+ ranges, but only branches, tags, and a representation of the commit
+ at point are available as completion candidates.
+
+‘l L’ (‘magit-log-branches’)
+ Show log for all local branches and ‘HEAD’.
+
+‘l b’ (‘magit-log-all-branches’)
+ Show log for all local and remote branches and ‘HEAD’.
+
+‘l a’ (‘magit-log-all’)
+ Show log for all references and ‘HEAD’.
+
+ Two additional commands that show the log for the file or blob that
+is being visited in the current buffer exists, see *note Commands for
+Buffers Visiting Files::. The command ‘magit-cherry’ also shows a log,
+see *note Cherries::.
+
+* Menu:
+
+* Refreshing Logs::
+* Log Buffer::
+* Log Margin::
+* Select from Log::
+* Reflog::
+* Cherries::
+
+
+File: magit.info, Node: Refreshing Logs, Next: Log Buffer, Up: Logging
+
+5.3.1 Refreshing Logs
+---------------------
+
+The transient prefix command ‘magit-log-refresh’, on ‘L’, can be used to
+change the log arguments used in the current buffer, without changing
+which log is shown. This works in dedicated log buffers, but also in
+the status buffer.
+
+‘L’ (‘magit-log-refresh’)
+ This transient prefix command binds the following suffix commands
+ along with the appropriate infix arguments and displays them in a
+ temporary buffer until a suffix is invoked.
+
+‘L g’ (‘magit-log-refresh’)
+ This suffix command sets the local log arguments for the current
+ buffer.
+
+‘L s’ (‘magit-log-set-default-arguments’)
+ This suffix command sets the default log arguments for buffers of
+ the same type as that of the current buffer. Other existing
+ buffers of the same type are not affected because their local
+ values have already been initialized.
+
+‘L w’ (‘magit-log-save-default-arguments’)
+ This suffix command sets the default log arguments for buffers of
+ the same type as that of the current buffer, and saves the value
+ for future sessions. Other existing buffers of the same type are
+ not affected because their local values have already been
+ initialized.
+
+‘L t’ (‘magit-toggle-margin’)
+ Show or hide the margin.
+
+
+File: magit.info, Node: Log Buffer, Next: Log Margin, Prev: Refreshing Logs, Up: Logging
+
+5.3.2 Log Buffer
+----------------
+
+‘L’ (‘magit-log-refresh’)
+ This transient prefix command binds the following suffix commands
+ along with the appropriate infix arguments and displays them in a
+ temporary buffer until a suffix is invoked.
+
+ See *note Refreshing Logs::.
+
+‘q’ (‘magit-log-bury-buffer’)
+ Bury the current buffer or the revision buffer in the same frame.
+ Like ‘magit-mode-bury-buffer’ (which see) but with a negative
+ prefix argument instead bury the revision buffer, provided it is
+ displayed in the current frame.
+
+‘C-c C-b’ (‘magit-go-backward’)
+ Move backward in current buffer’s history.
+
+‘C-c C-f’ (‘magit-go-forward’)
+ Move forward in current buffer’s history.
+
+‘C-c C-n’ (‘magit-log-move-to-parent’)
+ Move to a parent of the current commit. By default, this is the
+ first parent, but a numeric prefix can be used to specify another
+ parent.
+
+‘j’ (‘magit-log-move-to-revision’)
+ Read a revision and move to it in current log buffer.
+
+ If the chosen reference or revision isn’t being displayed in the
+ current log buffer, then inform the user about that and do nothing
+ else.
+
+ If invoked outside any log buffer, then display the log buffer of
+ the current repository first; creating it if necessary.
+
+‘<SPC>’ (‘magit-diff-show-or-scroll-up’)
+ Update the commit or diff buffer for the thing at point.
+
+ Either show the commit or stash at point in the appropriate buffer,
+ or if that buffer is already being displayed in the current frame
+ and contains information about that commit or stash, then instead
+ scroll the buffer up. If there is no commit or stash at point,
+ then prompt for a commit.
+
+‘<DEL>’ (‘magit-diff-show-or-scroll-down’)
+ Update the commit or diff buffer for the thing at point.
+
+ Either show the commit or stash at point in the appropriate buffer,
+ or if that buffer is already being displayed in the current frame
+ and contains information about that commit or stash, then instead
+ scroll the buffer down. If there is no commit or stash at point,
+ then prompt for a commit.
+
+‘=’ (‘magit-log-toggle-commit-limit’)
+ Toggle the number of commits the current log buffer is limited to.
+ If the number of commits is currently limited, then remove that
+ limit. Otherwise set it to 256.
+
+‘+’ (‘magit-log-double-commit-limit’)
+ Double the number of commits the current log buffer is limited to.
+
+‘-’ (‘magit-log-half-commit-limit’)
+ Half the number of commits the current log buffer is limited to.
+
+ -- User Option: magit-log-auto-more
+ Insert more log entries automatically when moving past the last
+ entry. Only considered when moving past the last entry with
+ ‘magit-goto-*-section’ commands.
+
+ -- User Option: magit-log-show-refname-after-summary
+ Whether to show the refnames after the commit summaries. This is
+ useful if you use really long branch names.
+
+ Magit displays references in logs a bit differently from how Git does
+it.
+
+ Local branches are blue and remote branches are green. Of course
+that depends on the used theme, as do the colors used for other types of
+references. The current branch has a box around it, as do remote
+branches that are their respective remote’s ‘HEAD’ branch.
+
+ If a local branch and its push-target point at the same commit, then
+their names are combined to preserve space and to make that relationship
+visible. For example:
+
+ origin/feature
+ [green][blue-]
+
+ instead of
+
+ feature origin/feature
+ [blue-] [green-------]
+
+ Also note that while the transient features the ‘--show-signature’
+argument, that won’t actually be used when enabled, because Magit
+defaults to use just one line per commit. Instead the commit colorized
+to indicate the validity of the signed commit object, using the faces
+named ‘magit-signature-*’ (which see).
+
+ For a description of ‘magit-log-margin’ see *note Log Margin::.
+
+
+File: magit.info, Node: Log Margin, Next: Select from Log, Prev: Log Buffer, Up: Logging
+
+5.3.3 Log Margin
+----------------
+
+In buffers which show one or more logs, it is possible to show
+additional information about each commit in the margin. The options
+used to configure the margin are named ‘magit-INFIX-margin’, where INFIX
+is the same as in the respective major-mode ‘magit-INFIX-mode’. In
+regular log buffers that would be ‘magit-log-margin’.
+
+ -- User Option: magit-log-margin
+ This option specifies whether the margin is initially shown in
+ Magit-Log mode buffers and how it is formatted.
+
+ The value has the form ‘(INIT STYLE WIDTH AUTHOR AUTHOR-WIDTH)’.
+
+ • If INIT is non-nil, then the margin is shown initially.
+ • STYLE controls how to format the author or committer date. It
+ can be one of ‘age’ (to show the age of the commit),
+ ‘age-abbreviated’ (to abbreviate the time unit to a
+ character), or a string (suitable for ‘format-time-string’) to
+ show the actual date. Option
+ ‘magit-log-margin-show-committer-date’ controls which date is
+ being displayed.
+ • WIDTH controls the width of the margin. This exists for
+ forward compatibility and currently the value should not be
+ changed.
+ • AUTHOR controls whether the name of the author is also shown
+ by default.
+ • AUTHOR-WIDTH has to be an integer. When the name of the
+ author is shown, then this specifies how much space is used to
+ do so.
+
+ You can change the STYLE and AUTHOR-WIDTH of all ‘magit-INFIX-margin’
+options to the same values by customizing ‘magit-log-margin’ *before*
+‘magit’ is loaded. If you do that, then the respective values for the
+other options will default to what you have set for that variable.
+Likewise if you set INIT in ‘magit-log-margin’ to ‘nil’, then that is
+used in the default of all other options. But setting it to ‘t’, i.e.
+re-enforcing the default for that option, does not carry to other
+options.
+
+ -- User Option: magit-log-margin-show-committer-date
+ This option specifies whether to show the committer date in the
+ margin. This option only controls whether the committer date is
+ displayed instead of the author date. Whether some date is
+ displayed in the margin and whether the margin is displayed at all
+ is controlled by other options.
+
+‘L’ (‘magit-margin-settings’)
+ This transient prefix command binds the following suffix commands,
+ each of which changes the appearance of the margin in some way.
+
+ In some buffers that support the margin, ‘L’ is instead bound to
+‘magit-log-refresh’, but that transient features the same commands, and
+then some other unrelated commands.
+
+‘L L’ (‘magit-toggle-margin’)
+ This command shows or hides the margin.
+
+‘L l’ (‘magit-cycle-margin-style’)
+ This command cycles the style used for the margin.
+
+‘L d’ (‘magit-toggle-margin-details’)
+ This command shows or hides details in the margin.
+
+
+File: magit.info, Node: Select from Log, Next: Reflog, Prev: Log Margin, Up: Logging
+
+5.3.4 Select from Log
+---------------------
+
+When the user has to select a recent commit that is reachable from
+‘HEAD’, using regular completion would be inconvenient (because most
+humans cannot remember hashes or "HEAD~5", at least not without double
+checking). Instead a log buffer is used to select the commit, which has
+the advantage that commits are presented in order and with the commit
+message.
+
+ Such selection logs are used when selecting the beginning of a rebase
+and when selecting the commit to be squashed into.
+
+ In addition to the key bindings available in all log buffers, the
+following additional key bindings are available in selection log
+buffers:
+
+‘C-c C-c’ (‘magit-log-select-pick’)
+ Select the commit at point and act on it. Call
+ ‘magit-log-select-pick-function’ with the selected commit as
+ argument.
+
+‘C-c C-k’ (‘magit-log-select-quit’)
+ Abort selecting a commit, don’t act on any commit.
+
+ -- User Option: magit-log-select-margin
+ This option specifies whether the margin is initially shown in
+ Magit-Log-Select mode buffers and how it is formatted.
+
+ The value has the form ‘(INIT STYLE WIDTH AUTHOR AUTHOR-WIDTH)’.
+
+ • If INIT is non-nil, then the margin is shown initially.
+ • STYLE controls how to format the author or committer date. It
+ can be one of ‘age’ (to show the age of the commit),
+ ‘age-abbreviated’ (to abbreviate the time unit to a
+ character), or a string (suitable for ‘format-time-string’) to
+ show the actual date. Option
+ ‘magit-log-margin-show-committer-date’ controls which date is
+ being displayed.
+ • WIDTH controls the width of the margin. This exists for
+ forward compatibility and currently the value should not be
+ changed.
+ • AUTHOR controls whether the name of the author is also shown
+ by default.
+ • AUTHOR-WIDTH has to be an integer. When the name of the
+ author is shown, then this specifies how much space is used to
+ do so.
+
+
+File: magit.info, Node: Reflog, Next: Cherries, Prev: Select from Log, Up: Logging
+
+5.3.5 Reflog
+------------
+
+Also see *note (gitman)git-reflog::.
+
+ These reflog commands are available from the log transient. See
+*note Logging::.
+
+‘l r’ (‘magit-reflog-current’)
+ Display the reflog of the current branch.
+
+‘l O’ (‘magit-reflog-other’)
+ Display the reflog of a branch or another ref.
+
+‘l H’ (‘magit-reflog-head’)
+ Display the ‘HEAD’ reflog.
+
+ -- User Option: magit-reflog-margin
+ This option specifies whether the margin is initially shown in
+ Magit-Reflog mode buffers and how it is formatted.
+
+ The value has the form ‘(INIT STYLE WIDTH AUTHOR AUTHOR-WIDTH)’.
+
+ • If INIT is non-nil, then the margin is shown initially.
+ • STYLE controls how to format the author or committer date. It
+ can be one of ‘age’ (to show the age of the commit),
+ ‘age-abbreviated’ (to abbreviate the time unit to a
+ character), or a string (suitable for ‘format-time-string’) to
+ show the actual date. Option
+ ‘magit-log-margin-show-committer-date’ controls which date is
+ being displayed.
+ • WIDTH controls the width of the margin. This exists for
+ forward compatibility and currently the value should not be
+ changed.
+ • AUTHOR controls whether the name of the author is also shown
+ by default.
+ • AUTHOR-WIDTH has to be an integer. When the name of the
+ author is shown, then this specifies how much space is used to
+ do so.
+
+
+File: magit.info, Node: Cherries, Prev: Reflog, Up: Logging
+
+5.3.6 Cherries
+--------------
+
+Cherries are commits that haven’t been applied upstream (yet), and are
+usually visualized using a log. Each commit is prefixed with ‘-’ if it
+has an equivalent in the upstream and ‘+’ if it does not, i.e. if it is
+a cherry.
+
+ The command ‘magit-cherry’ shows cherries for a single branch, but
+the references buffer (see *note References Buffer::) can show cherries
+for multiple "upstreams" at once.
+
+ Also see *note (gitman)git-reflog::.
+
+‘Y’ (‘magit-cherry’)
+ Show commits that are in a certain branch but that have not been
+ merged in the upstream branch.
+
+ -- User Option: magit-cherry-margin
+ This option specifies whether the margin is initially shown in
+ Magit-Cherry mode buffers and how it is formatted.
+
+ The value has the form ‘(INIT STYLE WIDTH AUTHOR AUTHOR-WIDTH)’.
+
+ • If INIT is non-nil, then the margin is shown initially.
+ • STYLE controls how to format the author or committer date. It
+ can be one of ‘age’ (to show the age of the commit),
+ ‘age-abbreviated’ (to abbreviate the time unit to a
+ character), or a string (suitable for ‘format-time-string’) to
+ show the actual date. Option
+ ‘magit-log-margin-show-committer-date’ controls which date is
+ being displayed.
+ • WIDTH controls the width of the margin. This exists for
+ forward compatibility and currently the value should not be
+ changed.
+ • AUTHOR controls whether the name of the author is also shown
+ by default.
+ • AUTHOR-WIDTH has to be an integer. When the name of the
+ author is shown, then this specifies how much space is used to
+ do so.
+
+
+File: magit.info, Node: Diffing, Next: Ediffing, Prev: Logging, Up: Inspecting
+
+5.4 Diffing
+===========
+
+The status buffer contains diffs for the staged and unstaged commits,
+but that obviously isn’t enough. The transient prefix command
+‘magit-diff’, on ‘d’, features several suffix commands, which show a
+specific diff in a separate diff buffer.
+
+ Like other transient prefix commands, ‘magit-diff’ also features
+several infix arguments that can be changed before invoking one of the
+suffix commands. However, in the case of the diff transient, these
+arguments may be taken from those currently in use in the current
+repository’s diff buffer, depending on the value of
+‘magit-prefix-use-buffer-arguments’ (see *note Transient Arguments and
+Buffer Variables::).
+
+ Also see *note (gitman)git-diff::.
+
+‘d’ (‘magit-diff’)
+ This transient prefix command binds the following suffix commands
+ along with the appropriate infix arguments and displays them in a
+ temporary buffer until a suffix is invoked.
+
+‘d d’ (‘magit-diff-dwim’)
+ Show changes for the thing at point.
+
+‘d r’ (‘magit-diff-range’)
+ Show differences between two commits.
+
+ RANGE should be a range (A..B or A...B) but can also be a single
+ commit. If one side of the range is omitted, then it defaults to
+ ‘HEAD’. If just a commit is given, then changes in the working
+ tree relative to that commit are shown.
+
+ If the region is active, use the revisions on the first and last
+ line of the region. With a prefix argument, instead of diffing the
+ revisions, choose a revision to view changes along, starting at the
+ common ancestor of both revisions (i.e., use a "..." range).
+
+‘d w’ (‘magit-diff-working-tree’)
+ Show changes between the current working tree and the ‘HEAD’
+ commit. With a prefix argument show changes between the working
+ tree and a commit read from the minibuffer.
+
+‘d s’ (‘magit-diff-staged’)
+ Show changes between the index and the ‘HEAD’ commit. With a
+ prefix argument show changes between the index and a commit read
+ from the minibuffer.
+
+‘d u’ (‘magit-diff-unstaged’)
+ Show changes between the working tree and the index.
+
+‘d p’ (‘magit-diff-paths’)
+ Show changes between any two files on disk.
+
+ All of the above suffix commands update the repository’s diff buffer.
+The diff transient also features two commands which show differences in
+another buffer:
+
+‘d c’ (‘magit-show-commit’)
+ Show the commit at point. If there is no commit at point or with a
+ prefix argument, prompt for a commit.
+
+‘d t’ (‘magit-stash-show’)
+ Show all diffs of a stash in a buffer.
+
+ Two additional commands that show the diff for the file or blob that
+is being visited in the current buffer exists, see *note Commands for
+Buffers Visiting Files::.
+
+* Menu:
+
+* Refreshing Diffs::
+* Commands Available in Diffs::
+* Diff Options::
+* Revision Buffer::
+
+
+File: magit.info, Node: Refreshing Diffs, Next: Commands Available in Diffs, Up: Diffing
+
+5.4.1 Refreshing Diffs
+----------------------
+
+The transient prefix command ‘magit-diff-refresh’, on ‘D’, can be used
+to change the diff arguments used in the current buffer, without
+changing which diff is shown. This works in dedicated diff buffers, but
+also in the status buffer.
+
+‘D’ (‘magit-diff-refresh’)
+ This transient prefix command binds the following suffix commands
+ along with the appropriate infix arguments and displays them in a
+ temporary buffer until a suffix is invoked.
+
+‘D g’ (‘magit-diff-refresh’)
+ This suffix command sets the local diff arguments for the current
+ buffer.
+
+‘D s’ (‘magit-diff-set-default-arguments’)
+ This suffix command sets the default diff arguments for buffers of
+ the same type as that of the current buffer. Other existing
+ buffers of the same type are not affected because their local
+ values have already been initialized.
+
+‘D w’ (‘magit-diff-save-default-arguments’)
+ This suffix command sets the default diff arguments for buffers of
+ the same type as that of the current buffer, and saves the value
+ for future sessions. Other existing buffers of the same type are
+ not affected because their local values have already been
+ initialized.
+
+‘D t’ (‘magit-diff-toggle-refine-hunk’)
+ This command toggles hunk refinement on or off.
+
+‘D r’ (‘magit-diff-switch-range-type’)
+ This command converts the diff range type from "revA..revB" to
+ "revB...revA", or vice versa.
+
+‘D f’ (‘magit-diff-flip-revs’)
+ This command swaps revisions in the diff range from "revA..revB" to
+ "revB..revA", or vice versa.
+
+‘D F’ (‘magit-diff-toggle-file-filter’)
+ This command toggles the file restriction of the diffs in the
+ current buffer, allowing you to quickly switch between viewing all
+ the changes in the commit and the restricted subset. As a special
+ case, when this command is called from a log buffer, it toggles the
+ file restriction in the repository’s revision buffer, which is
+ useful when you display a revision from a log buffer that is
+ restricted to a file or files.
+
+ In addition to the above transient, which allows changing any of the
+supported arguments, there also exist some commands that change only a
+particular argument.
+
+‘-’ (‘magit-diff-less-context’)
+ This command decreases the context for diff hunks by COUNT lines.
+
+‘+’ (‘magit-diff-more-context’)
+ This command increases the context for diff hunks by COUNT lines.
+
+‘0’ (‘magit-diff-default-context’)
+ This command resets the context for diff hunks to the default
+ height.
+
+ The following commands quickly change what diff is being displayed
+without having to using one of the diff transient.
+
+‘C-c C-d’ (‘magit-diff-while-committing’)
+ While committing, this command shows the changes that are about to
+ be committed. While amending, invoking the command again toggles
+ between showing just the new changes or all the changes that will
+ be committed.
+
+ This binding is available in the diff buffer as well as the commit
+ message buffer.
+
+‘C-c C-b’ (‘magit-go-backward’)
+ This command moves backward in current buffer’s history.
+
+‘C-c C-f’ (‘magit-go-forward’)
+ This command moves forward in current buffer’s history.
+
+
+File: magit.info, Node: Commands Available in Diffs, Next: Diff Options, Prev: Refreshing Diffs, Up: Diffing
+
+5.4.2 Commands Available in Diffs
+---------------------------------
+
+Some commands are only available if point is inside a diff.
+
+ ‘magit-diff-visit-file’ and related commands visit the appropriate
+version of the file that the diff at point is about. Likewise
+‘magit-diff-visit-worktree-file’ and related commands visit the worktree
+version of the file that the diff at point is about. See *note Visiting
+Files and Blobs from a Diff:: for more information and the key bindings.
+
+‘C-c C-t’ (‘magit-diff-trace-definition’)
+ This command shows a log for the definition at point.
+
+ -- User Option: magit-log-trace-definition-function
+ The function specified by this option is used by
+ ‘magit-log-trace-definition’ to determine the function at point.
+ For major-modes that have special needs, you could set the local
+ value using the mode’s hook.
+
+‘C-c C-e’ (‘magit-diff-edit-hunk-commit’)
+ From a hunk, this command edits the respective commit and visits
+ the file.
+
+ First it visits the file being modified by the hunk at the correct
+ location using ‘magit-diff-visit-file’. This actually visits a
+ blob. When point is on a diff header, not within an individual
+ hunk, then this visits the blob the first hunk is about.
+
+ Then it invokes ‘magit-edit-line-commit’, which uses an interactive
+ rebase to make the commit editable, or if that is not possible
+ because the commit is not reachable from ‘HEAD’ by checking out
+ that commit directly. This also causes the actual worktree file to
+ be visited.
+
+ Neither the blob nor the file buffer are killed when finishing the
+ rebase. If that is undesirable, then it might be better to use
+ ‘magit-rebase-edit-command’ instead of this command.
+
+‘j’ (‘magit-jump-to-diffstat-or-diff’)
+ This command jumps to the diffstat or diff. When point is on a
+ file inside the diffstat section, then jump to the respective diff
+ section. Otherwise, jump to the diffstat section or a child
+ thereof.
+
+ The next two commands are not specific to Magit-Diff mode (or and
+Magit buffer for that matter), but it might be worth pointing out that
+they are available here too.
+
+‘<SPC>’ (‘scroll-up’)
+ This command scrolls text upward.
+
+‘<DEL>’ (‘scroll-down’)
+ This command scrolls text downward.
+
+
+File: magit.info, Node: Diff Options, Next: Revision Buffer, Prev: Commands Available in Diffs, Up: Diffing
+
+5.4.3 Diff Options
+------------------
+
+ -- User Option: magit-diff-refine-hunk
+ Whether to show word-granularity differences within diff hunks.
+
+ • ‘nil’ Never show fine differences.
+ • ‘t’ Show fine differences for the current diff hunk only.
+ • ‘all’ Show fine differences for all displayed diff hunks.
+
+ -- User Option: magit-diff-refine-ignore-whitespace
+ Whether to ignore whitespace changes in word-granularity
+ differences.
+
+ -- User Option: magit-diff-adjust-tab-width
+ Whether to adjust the width of tabs in diffs.
+
+ Determining the correct width can be expensive if it requires
+ opening large and/or many files, so the widths are cached in the
+ variable ‘magit-diff--tab-width-cache’. Set that to nil to
+ invalidate the cache.
+
+ • ‘nil’ Never adjust tab width. Use ‘tab-width’s value from the
+ Magit buffer itself instead.
+
+ • ‘t’ If the corresponding file-visiting buffer exits, then use
+ ‘tab-width’’s value from that buffer. Doing this is cheap, so
+ this value is used even if a corresponding cache entry exists.
+
+ • ‘always’ If there is no such buffer, then temporarily visit
+ the file to determine the value.
+
+ • NUMBER Like ‘always’, but don’t visit files larger than NUMBER
+ bytes.
+
+ -- User Option: magit-diff-paint-whitespace
+ Specify where to highlight whitespace errors.
+
+ See ‘magit-diff-highlight-trailing’,
+ ‘magit-diff-highlight-indentation’. The symbol ‘t’ means in all
+ diffs, ‘status’ means only in the status buffer, and nil means
+ nowhere.
+
+ • ‘nil’ Never highlight whitespace errors.
+ • ‘t’ Highlight whitespace errors everywhere.
+ • ‘uncommitted’ Only highlight whitespace errors in diffs
+ showing uncommitted changes. For backward compatibility
+ ‘status’ is treated as a synonym.
+
+ -- User Option: magit-diff-paint-whitespace-lines
+ Specify in what kind of lines to highlight whitespace errors.
+
+ • ‘t’ Highlight only in added lines.
+ • ‘both’ Highlight in added and removed lines.
+ • ‘all’ Highlight in added, removed and context lines.
+
+ -- User Option: magit-diff-highlight-trailing
+ Whether to highlight whitespace at the end of a line in diffs.
+ Used only when ‘magit-diff-paint-whitespace’ is non-nil.
+
+ -- User Option: magit-diff-highlight-indentation
+ This option controls whether to highlight the indentation in case
+ it used the "wrong" indentation style. Indentation is only
+ highlighted if ‘magit-diff-paint-whitespace’ is also non-nil.
+
+ The value is an alist of the form ‘((REGEXP . INDENT)...)’. The
+ path to the current repository is matched against each element in
+ reverse order. Therefore if a REGEXP matches, then earlier
+ elements are not tried.
+
+ If the used INDENT is ‘tabs’, highlight indentation with tabs. If
+ INDENT is an integer, highlight indentation with at least that many
+ spaces. Otherwise, highlight neither.
+
+ -- User Option: magit-diff-hide-trailing-cr-characters
+ Whether to hide ^M characters at the end of a line in diffs.
+
+ -- User Option: magit-diff-highlight-hunk-region-functions
+ This option specifies the functions used to highlight the
+ hunk-internal region.
+
+ ‘magit-diff-highlight-hunk-region-dim-outside’ overlays the outside
+ of the hunk internal selection with a face that causes the added
+ and removed lines to have the same background color as context
+ lines. This function should not be removed from the value of this
+ option.
+
+ ‘magit-diff-highlight-hunk-region-using-overlays’ and
+ ‘magit-diff-highlight-hunk-region-using-underline’ emphasize the
+ region by placing delimiting horizontal lines before and after it.
+ Both of these functions have glitches which cannot be fixed due to
+ limitations of Emacs’ display engine. For more information see
+ <https://github.com/magit/magit/issues/2758> ff.
+
+ Instead of, or in addition to, using delimiting horizontal lines,
+ to emphasize the boundaries, you may wish to emphasize the text
+ itself, using ‘magit-diff-highlight-hunk-region-using-face’.
+
+ In terminal frames it’s not possible to draw lines as the overlay
+ and underline variants normally do, so there they fall back to
+ calling the face function instead.
+
+ -- User Option: magit-diff-unmarked-lines-keep-foreground
+ This option controls whether added and removed lines outside the
+ hunk-internal region only lose their distinct background color or
+ also the foreground color. Whether the outside of the region is
+ dimmed at all depends on
+ ‘magit-diff-highlight-hunk-region-functions’.
+
+ -- User Option: magit-diff-extra-stat-arguments
+ This option specifies additional arguments to be used alongside
+ ‘--stat’.
+
+ The value is a list of zero or more arguments or a function that
+ takes no argument and returns such a list. These arguments are
+ allowed here: ‘--stat-width’, ‘--stat-name-width’,
+ ‘--stat-graph-width’ and ‘--compact-summary’. Also see *note
+ (gitman)git-diff::.
+
+
+File: magit.info, Node: Revision Buffer, Prev: Diff Options, Up: Diffing
+
+5.4.4 Revision Buffer
+---------------------
+
+ -- User Option: magit-revision-insert-related-refs
+ Whether to show related branches in revision buffers.
+
+ • ‘nil’ Don’t show any related branches.
+ • ‘t’ Show related local branches.
+ • ‘all’ Show related local and remote branches.
+ • ‘mixed’ Show all containing branches and local merged
+ branches.
+
+ -- User Option: magit-revision-show-gravatars
+ Whether to show gravatar images in revision buffers.
+
+ If ‘nil’, then don’t insert any gravatar images. If ‘t’, then
+ insert both images. If ‘author’ or ‘committer’, then insert only
+ the respective image.
+
+ If you have customized the option ‘magit-revision-headers-format’
+ and want to insert the images then you might also have to specify
+ where to do so. In that case the value has to be a cons-cell of
+ two regular expressions. The car specifies where to insert the
+ author’s image. The top half of the image is inserted right after
+ the matched text, the bottom half on the next line in the same
+ column. The cdr specifies where to insert the committer’s image,
+ accordingly. Either the car or the cdr may be nil."
+
+ -- User Option: magit-revision-use-hash-sections
+ Whether to turn hashes inside the commit message into sections.
+
+ If non-nil, then hashes inside the commit message are turned into
+ ‘commit’ sections. There is a trade off to be made between
+ performance and reliability:
+
+ • ‘slow’ calls git for every word to be absolutely sure.
+ • ‘quick’ skips words less than seven characters long.
+ • ‘quicker’ additionally skips words that don’t contain a
+ number.
+ • ‘quickest’ uses all words that are at least seven characters
+ long and which contain at least one number as well as at least
+ one letter.
+
+ If nil, then no hashes are turned into sections, but you can still
+ visit the commit at point using "RET".
+
+ The diffs shown in the revision buffer may be automatically
+restricted to a subset of the changed files. If the revision buffer is
+displayed from a log buffer, the revision buffer will share the same
+file restriction as that log buffer (also see the command
+‘magit-diff-toggle-file-filter’).
+
+ -- User Option: magit-revision-filter-files-on-follow
+ Whether showing a commit from a log buffer honors the log’s file
+ filter when the log arguments include ‘--follow’.
+
+ When this option is nil, displaying a commit from a log ignores the
+ log’s file filter if the log arguments include ‘--follow’. Doing
+ so avoids showing an empty diff in revision buffers for commits
+ before a rename event. In such cases, the ‘--patch’ argument of
+ the log transient can be used to show the file-restricted diffs
+ inline.
+
+ Set this option to non-nil to keep the log’s file restriction even
+ if ‘--follow’ is present in the log arguments.
+
+ If the revision buffer is not displayed from a log buffer, the file
+restriction is determined as usual (see *note Transient Arguments and
+Buffer Variables::).
+
+
+File: magit.info, Node: Ediffing, Next: References Buffer, Prev: Diffing, Up: Inspecting
+
+5.5 Ediffing
+============
+
+This section describes how to enter Ediff from Magit buffers. For
+information on how to use Ediff itself, see *note (ediff)Top::.
+
+‘e’ (‘magit-ediff-dwim’)
+ Compare, stage, or resolve using Ediff.
+
+ This command tries to guess what file, and what commit or range the
+ user wants to compare, stage, or resolve using Ediff. It might
+ only be able to guess either the file, or range/commit, in which
+ case the user is asked about the other. It might not always guess
+ right, in which case the appropriate ‘magit-ediff-*’ command has to
+ be used explicitly. If it cannot read the user’s mind at all, then
+ it asks the user for a command to run.
+
+‘E’ (‘magit-ediff’)
+ This transient prefix command binds the following suffix commands
+ and displays them in a temporary buffer until a suffix is invoked.
+
+‘E r’ (‘magit-ediff-compare’)
+ Compare two revisions of a file using Ediff.
+
+ If the region is active, use the revisions on the first and last
+ line of the region. With a prefix argument, instead of diffing the
+ revisions, choose a revision to view changes along, starting at the
+ common ancestor of both revisions (i.e., use a "..." range).
+
+‘E m’ (‘magit-ediff-resolve’)
+ Resolve outstanding conflicts in a file using Ediff, defaulting to
+ the file at point.
+
+ Provided that the value of ‘merge.conflictstyle’ is ‘diff3’, you
+ can view the file’s merge-base revision using ‘/’ in the Ediff
+ control buffer.
+
+ In the rare event that you want to manually resolve all conflicts,
+ including those already resolved by Git, use
+ ‘ediff-merge-revisions-with-ancestor’.
+
+‘E t’ (‘magit-git-mergetool’)
+ This command does not actually use Ediff. While it serves the same
+ purpose as ‘magit-ediff-resolve’, it uses ‘git mergetool --gui’ to
+ resolve conflicts.
+
+ With a prefix argument this acts as a transient prefix command,
+ allowing the user to select the mergetool and change some settings.
+
+‘E s’ (‘magit-ediff-stage’)
+ Stage and unstage changes to a file using Ediff, defaulting to the
+ file at point.
+
+‘E u’ (‘magit-ediff-show-unstaged’)
+ Show unstaged changes to a file using Ediff.
+
+‘E i’ (‘magit-ediff-show-staged’)
+ Show staged changes to a file using Ediff.
+
+‘E w’ (‘magit-ediff-show-working-tree’)
+ Show changes in a file between ‘HEAD’ and working tree using Ediff.
+
+‘E c’ (‘magit-ediff-show-commit’)
+ Show changes to a file introduced by a commit using Ediff.
+
+‘E z’ (‘magit-ediff-show-stash’)
+ Show changes to a file introduced by a stash using Ediff.
+
+ -- User Option: magit-ediff-dwim-show-on-hunks
+ This option controls what command ‘magit-ediff-dwim’ calls when
+ point is on uncommitted hunks. When nil, always run
+ ‘magit-ediff-stage’. Otherwise, use ‘magit-ediff-show-staged’ and
+ ‘magit-ediff-show-unstaged’ to show staged and unstaged changes,
+ respectively.
+
+ -- User Option: magit-ediff-show-stash-with-index
+ This option controls whether ‘magit-ediff-show-stash’ includes a
+ buffer containing the file’s state in the index at the time the
+ stash was created. This makes it possible to tell which changes in
+ the stash were staged.
+
+ -- User Option: magit-ediff-quit-hook
+ This hook is run after quitting an Ediff session that was created
+ using a Magit command. The hook functions are run inside the Ediff
+ control buffer, and should not change the current buffer.
+
+ This is similar to ‘ediff-quit-hook’ but takes the needs of Magit
+ into account. The regular ‘ediff-quit-hook’ is ignored by Ediff
+ sessions that were created using a Magit command.
+
+
+File: magit.info, Node: References Buffer, Next: Bisecting, Prev: Ediffing, Up: Inspecting
+
+5.6 References Buffer
+=====================
+
+‘y’ (‘magit-show-refs’)
+ This command lists branches and tags in a dedicated buffer.
+
+ However if this command is invoked again from this buffer or if it
+ is invoked with a prefix argument, then it acts as a transient
+ prefix command, which binds the following suffix commands and some
+ infix arguments.
+
+ All of the following suffix commands list exactly the same branches
+and tags. The only difference the optional feature that can be enabled
+by changing the value of ‘magit-refs-show-commit-count’ (see below).
+These commands specify a different branch or commit against which all
+the other references are compared.
+
+‘y y’ (‘magit-show-refs-head’)
+ This command lists branches and tags in a dedicated buffer. Each
+ reference is being compared with ‘HEAD’.
+
+‘y c’ (‘magit-show-refs-current’)
+ This command lists branches and tags in a dedicated buffer. Each
+ reference is being compared with the current branch or ‘HEAD’ if it
+ is detached.
+
+‘y o’ (‘magit-show-refs-other’)
+ This command lists branches and tags in a dedicated buffer. Each
+ reference is being compared with a branch read from the user.
+
+‘y r’ (‘magit-refs-set-show-commit-count’)
+ This command changes for which refs the commit count is shown.
+
+ -- User Option: magit-refs-show-commit-count
+ Whether to show commit counts in Magit-Refs mode buffers.
+
+ • ‘all’ Show counts for branches and tags.
+ • ‘branch’ Show counts for branches only.
+ • ‘nil’ Never show counts.
+
+ The default is ‘nil’ because anything else can be very expensive.
+
+ -- User Option: magit-refs-pad-commit-counts
+ Whether to pad all commit counts on all sides in Magit-Refs mode
+ buffers.
+
+ If this is nil, then some commit counts are displayed right next to
+ one of the branches that appear next to the count, without any
+ space in between. This might look bad if the branch name faces
+ look too similar to ‘magit-dimmed’.
+
+ If this is non-nil, then spaces are placed on both sides of all
+ commit counts.
+
+ -- User Option: magit-refs-show-remote-prefix
+ Whether to show the remote prefix in lists of remote branches.
+
+ Showing the prefix is redundant because the name of the remote is
+ already shown in the heading preceding the list of its branches.
+
+ -- User Option: magit-refs-primary-column-width
+ Width of the primary column in ‘magit-refs-mode’ buffers. The
+ primary column is the column that contains the name of the branch
+ that the current row is about.
+
+ If this is an integer, then the column is that many columns wide.
+ Otherwise it has to be a cons-cell of two integers. The first
+ specifies the minimal width, the second the maximal width. In that
+ case the actual width is determined using the length of the names
+ of the shown local branches. (Remote branches and tags are not
+ taken into account when calculating to optimal width.)
+
+ -- User Option: magit-refs-focus-column-width
+ Width of the focus column in ‘magit-refs-mode’ buffers.
+
+ The focus column is the first column, which marks one branch
+ (usually the current branch) as the focused branch using ‘*’ or
+ ‘@’. For each other reference, this column optionally shows how
+ many commits it is ahead of the focused branch and ‘<’, or if it
+ isn’t ahead then the commits it is behind and ‘>’, or if it isn’t
+ behind either, then a ‘=’.
+
+ This column may also display only ‘*’ or ‘@’ for the focused
+ branch, in which case this option is ignored. Use ‘L v’ to change
+ the verbosity of this column.
+
+ -- User Option: magit-refs-margin
+ This option specifies whether the margin is initially shown in
+ Magit-Refs mode buffers and how it is formatted.
+
+ The value has the form ‘(INIT STYLE WIDTH AUTHOR AUTHOR-WIDTH)’.
+
+ • If INIT is non-nil, then the margin is shown initially.
+ • STYLE controls how to format the author or committer date. It
+ can be one of ‘age’ (to show the age of the commit),
+ ‘age-abbreviated’ (to abbreviate the time unit to a
+ character), or a string (suitable for ‘format-time-string’) to
+ show the actual date. Option
+ ‘magit-log-margin-show-committer-date’ controls which date is
+ being displayed.
+ • WIDTH controls the width of the margin. This exists for
+ forward compatibility and currently the value should not be
+ changed.
+ • AUTHOR controls whether the name of the author is also shown
+ by default.
+ • AUTHOR-WIDTH has to be an integer. When the name of the
+ author is shown, then this specifies how much space is used to
+ do so.
+
+ -- User Option: magit-refs-margin-for-tags
+ This option specifies whether to show information about tags in the
+ margin. This is disabled by default because it is slow if there
+ are many tags.
+
+ The following variables control how individual refs are displayed.
+If you change one of these variables (especially the "%c" part), then
+you should also change the others to keep things aligned. The following
+%-sequences are supported:
+
+ • ‘%a’ Number of commits this ref has over the one we compare to.
+ • ‘%b’ Number of commits the ref we compare to has over this one.
+ • ‘%c’ Number of commits this ref has over the one we compare to.
+ For the ref which all other refs are compared this is instead "@",
+ if it is the current branch, or "#" otherwise.
+ • ‘%C’ For the ref which all other refs are compared this is "@", if
+ it is the current branch, or "#" otherwise. For all other refs "
+ ".
+ • ‘%h’ Hash of this ref’s tip.
+ • ‘%m’ Commit summary of the tip of this ref.
+ • ‘%n’ Name of this ref.
+ • ‘%u’ Upstream of this local branch.
+ • ‘%U’ Upstream of this local branch and additional local vs.
+ upstream information.
+
+ -- User Option: magit-refs-filter-alist
+ The purpose of this option is to forgo displaying certain refs
+ based on their name. If you want to not display any refs of a
+ certain type, then you should remove the appropriate function from
+ ‘magit-refs-sections-hook’ instead.
+
+ This alist controls which tags and branches are omitted from being
+ displayed in ‘magit-refs-mode’ buffers. If it is ‘nil’, then all
+ refs are displayed (subject to ‘magit-refs-sections-hook’).
+
+ All keys are tried in order until one matches. Then its value is
+ used and subsequent elements are ignored. If the value is non-nil,
+ then the reference is displayed, otherwise it is not. If no
+ element matches, then the reference is displayed.
+
+ A key can either be a regular expression that the refname has to
+ match, or a function that takes the refname as only argument and
+ returns a boolean. A remote branch such as "origin/master" is
+ displayed as just "master", however for this comparison the former
+ is used.
+
+‘<RET>’ (‘magit-visit-ref’)
+ This command visits the reference or revision at point in another
+ buffer. If there is no revision at point or with a prefix argument
+ then it prompts for a revision.
+
+ This command behaves just like ‘magit-show-commit’ as described
+ above, except if point is on a reference in a ‘magit-refs-mode’
+ buffer, in which case the behavior may be different, but only if
+ you have customized the option ‘magit-visit-ref-behavior’.
+
+ -- User Option: magit-visit-ref-behavior
+ This option controls how ‘magit-visit-ref’ behaves in
+ ‘magit-refs-mode’ buffers.
+
+ By default ‘magit-visit-ref’ behaves like ‘magit-show-commit’, in
+ all buffers, including ‘magit-refs-mode’ buffers. When the type of
+ the section at point is ‘commit’ then "RET" is bound to
+ ‘magit-show-commit’, and when the type is either ‘branch’ or ‘tag’
+ then it is bound to ‘magit-visit-ref’.
+
+ "RET" is one of Magit’s most essential keys and at least by default
+ it should behave consistently across all of Magit, especially
+ because users quickly learn that it does something very harmless;
+ it shows more information about the thing at point in another
+ buffer.
+
+ However "RET" used to behave differently in ‘magit-refs-mode’
+ buffers, doing surprising things, some of which cannot really be
+ described as "visit this thing". If you’ve grown accustomed this
+ behavior, you can restore it by adding one or more of the below
+ symbols to the value of this option. But keep in mind that by
+ doing so you don’t only introduce inconsistencies, you also lose
+ some functionality and might have to resort to ‘M-x
+ magit-show-commit’ to get it back.
+
+ ‘magit-visit-ref’ looks for these symbols in the order in which
+ they are described here. If the presence of a symbol applies to
+ the current situation, then the symbols that follow do not affect
+ the outcome.
+
+ • ‘focus-on-ref’
+
+ With a prefix argument update the buffer to show commit counts
+ and lists of cherry commits relative to the reference at point
+ instead of relative to the current buffer or ‘HEAD’.
+
+ Instead of adding this symbol, consider pressing "C-u y o
+ RET".
+
+ • ‘create-branch’
+
+ If point is on a remote branch, then create a new local branch
+ with the same name, use the remote branch as its upstream, and
+ then check out the local branch.
+
+ Instead of adding this symbol, consider pressing "b c RET
+ RET", like you would do in other buffers.
+
+ • ‘checkout-any’
+
+ Check out the reference at point. If that reference is a tag
+ or a remote branch, then this results in a detached ‘HEAD’.
+
+ Instead of adding this symbol, consider pressing "b b RET",
+ like you would do in other buffers.
+
+ • ‘checkout-branch’
+
+ Check out the local branch at point.
+
+ Instead of adding this symbol, consider pressing "b b RET",
+ like you would do in other buffers.
+
+* Menu:
+
+* References Sections::
+
+
+File: magit.info, Node: References Sections, Up: References Buffer
+
+5.6.1 References Sections
+-------------------------
+
+The contents of references buffers is controlled using the hook
+‘magit-refs-sections-hook’. See *note Section Hooks:: to learn about
+such hooks and how to customize them. All of the below functions are
+members of the default value. Note that it makes much less sense to
+customize this hook than it does for the respective hook used for the
+status buffer.
+
+ -- User Option: magit-refs-sections-hook
+ Hook run to insert sections into a references buffer.
+
+ -- Function: magit-insert-local-branches
+ Insert sections showing all local branches.
+
+ -- Function: magit-insert-remote-branches
+ Insert sections showing all remote-tracking branches.
+
+ -- Function: magit-insert-tags
+ Insert sections showing all tags.
+
+
+File: magit.info, Node: Bisecting, Next: Visiting Files and Blobs, Prev: References Buffer, Up: Inspecting
+
+5.7 Bisecting
+=============
+
+Also see *note (gitman)git-bisect::.
+
+‘B’ (‘magit-bisect’)
+ This transient prefix command binds the following suffix commands
+ and displays them in a temporary buffer until a suffix is invoked.
+
+ When bisecting is not in progress, then the transient features the
+following suffix commands.
+
+‘B B’ (‘magit-bisect-start’)
+ Start a bisect session.
+
+ Bisecting a bug means to find the commit that introduced it. This
+ command starts such a bisect session by asking for a known good
+ commit and a known bad commit. If you’re bisecting a change that
+ isn’t a regression, you can select alternate terms that are
+ conceptually more fitting than "bad" and "good", but the infix
+ arguments to do so are disabled by default.
+
+‘B s’ (‘magit-bisect-run’)
+ Bisect automatically by running commands after each step.
+
+ When bisecting in progress, then the transient instead features the
+following suffix commands.
+
+‘B b’ (‘magit-bisect-bad’)
+ Mark the current commit as bad. Use this after you have asserted
+ that the commit does contain the bug in question.
+
+‘B g’ (‘magit-bisect-good’)
+ Mark the current commit as good. Use this after you have asserted
+ that the commit does not contain the bug in question.
+
+‘B m’ (‘magit-bisect-mark’)
+ Mark the current commit with one of the bisect terms. This command
+ provides an alternative to ‘magit-bisect-bad’ and
+ ‘magit-bisect-good’ and is useful when using terms other than "bad"
+ and "good". This suffix is disabled by default.
+
+‘B k’ (‘magit-bisect-skip’)
+ Skip the current commit. Use this if for some reason the current
+ commit is not a good one to test. This command lets Git choose a
+ different one.
+
+‘B r’ (‘magit-bisect-reset’)
+ After bisecting, cleanup bisection state and return to original
+ ‘HEAD’.
+
+ By default the status buffer shows information about the ongoing
+bisect session.
+
+ -- User Option: magit-bisect-show-graph
+ This option controls whether a graph is displayed for the log of
+ commits that still have to be bisected.
+
+
+File: magit.info, Node: Visiting Files and Blobs, Next: Blaming, Prev: Bisecting, Up: Inspecting
+
+5.8 Visiting Files and Blobs
+============================
+
+Magit provides several commands that visit a file or blob (the version
+of a file that is stored in a certain commit). Actually it provides
+several *groups* of such commands and the several *variants* within each
+group.
+
+* Menu:
+
+* General-Purpose Visit Commands::
+* Visiting Files and Blobs from a Diff::
+
+
+File: magit.info, Node: General-Purpose Visit Commands, Next: Visiting Files and Blobs from a Diff, Up: Visiting Files and Blobs
+
+5.8.1 General-Purpose Visit Commands
+------------------------------------
+
+These commands can be used anywhere to open any blob. Currently no keys
+are bound to these commands by default, but that is likely to change.
+
+ -- Command: magit-find-file
+ This command reads a filename and revision from the user and visits
+ the respective blob in a buffer. The buffer is displayed in the
+ selected window.
+
+ -- Command: magit-find-file-other-window
+ This command reads a filename and revision from the user and visits
+ the respective blob in a buffer. The buffer is displayed in
+ another window.
+
+ -- Command: magit-find-file-other-frame
+ This command reads a filename and revision from the user and visits
+ the respective blob in a buffer. The buffer is displayed in
+ another frame.
+
+
+File: magit.info, Node: Visiting Files and Blobs from a Diff, Prev: General-Purpose Visit Commands, Up: Visiting Files and Blobs
+
+5.8.2 Visiting Files and Blobs from a Diff
+------------------------------------------
+
+These commands can only be used when point is inside a diff.
+
+‘<RET>’ (‘magit-diff-visit-file’)
+ This command visits the appropriate version of the file that the
+ diff at point is about.
+
+ This commands visits the worktree version of the appropriate file.
+ The location of point inside the diff determines which file is
+ being visited. The visited version depends on what changes the
+ diff is about.
+
+ 1. If the diff shows uncommitted changes (i.e. staged or
+ unstaged changes), then visit the file in the working tree
+ (i.e. the same "real" file that ‘find-file’ would visit. In
+ all other cases visit a "blob" (i.e. the version of a file as
+ stored in some commit).
+
+ 2. If point is on a removed line, then visit the blob for the
+ first parent of the commit that removed that line, i.e. the
+ last commit where that line still exists.
+
+ 3. If point is on an added or context line, then visit the blob
+ that adds that line, or if the diff shows from more than a
+ single commit, then visit the blob from the last of these
+ commits.
+
+ In the file-visiting buffer this command goes to the line that
+ corresponds to the line that point is on in the diff.
+
+ The buffer is displayed in the selected window. With a prefix
+ argument the buffer is displayed in another window instead.
+
+ -- User Option: magit-diff-visit-previous-blob
+ This option controls whether ‘magit-diff-visit-file’ may visit the
+ previous blob. When this is ‘t’ (the default) and point is on a
+ removed line in a diff for a committed change, then
+ ‘magit-diff-visit-file’ visits the blob from the last revision
+ which still had that line.
+
+ Currently this is only supported for committed changes, for staged
+ and unstaged changes ‘magit-diff-visit-file’ always visits the file
+ in the working tree.
+
+‘C-<return>’ (‘magit-diff-visit-file-worktree’)
+ This command visits the worktree version of the appropriate file.
+ The location of point inside the diff determines which file is
+ being visited. Unlike ‘magit-diff-visit-file’ it always visits the
+ "real" file in the working tree, i.e the "current version" of the
+ file.
+
+ In the file-visiting buffer this command goes to the line that
+ corresponds to the line that point is on in the diff. Lines that
+ were added or removed in the working tree, the index and other
+ commits in between are automatically accounted for.
+
+ The buffer is displayed in the selected window. With a prefix
+ argument the buffer is displayed in another window instead.
+
+ Variants of the above two commands exist that instead visit the file
+in another window or in another frame. If you prefer such behavior,
+then you may want to change the above key bindings, but note that the
+above commands also use another window when invoked with a prefix
+argument.
+
+ -- Command: magit-diff-visit-file-other-window
+ -- Command: magit-diff-visit-file-other-frame
+ -- Command: magit-diff-visit-worktree-file-other-window
+ -- Command: magit-diff-visit-worktree-file-other-frame
+
+
+File: magit.info, Node: Blaming, Prev: Visiting Files and Blobs, Up: Inspecting
+
+5.9 Blaming
+===========
+
+Also see *note (gitman)git-blame::.
+
+ To start blaming invoke the ‘magit-file-dispatch’ transient prefix
+command by pressing ‘C-c M-g’.
+
+ The blaming suffix commands can be invoked from the dispatch
+transient. However if you want to set an infix argument, then you have
+to enter the blaming sub-transient first.
+
+ The key bindings shown below assume that you enter the dispatch
+transient using the default binding.
+
+‘C-c M-g B’ (‘magit-blame’)
+ This transient prefix command binds the following suffix commands
+ along with the appropriate infix arguments and displays them in a
+ temporary buffer until a suffix is invoked.
+
+ Note that not all of the following suffixes are available at all
+times. For example if ‘magit-blame-mode’ is not enabled, then the
+command whose purpose is to turn off that mode would not be of any use
+and therefore isn’t available.
+
+‘C-c M-g b’ (‘magit-blame-addition’)
+‘C-c M-g B b’
+ This command augments each line or chunk of lines in the current
+ file-visiting or blob-visiting buffer with information about what
+ commits last touched these lines.
+
+ If the buffer visits a revision of that file, then history up to
+ that revision is considered. Otherwise, the file’s full history is
+ considered, including uncommitted changes.
+
+ If Magit-Blame mode is already turned on in the current buffer then
+ blaming is done recursively, by visiting REVISION:FILE (using
+ ‘magit-find-file’), where REVISION is a parent of the revision that
+ added the current line or chunk of lines.
+
+‘C-c M-g r’ (‘magit-blame-removal’)
+‘C-c M-g B r’
+ This command augments each line or chunk of lines in the current
+ blob-visiting buffer with information about the revision that
+ removes it. It cannot be used in file-visiting buffers.
+
+ Like ‘magit-blame-addition’, this command can be used recursively.
+
+‘C-c M-g f’ (‘magit-blame-reverse’)
+‘C-c M-g B f’
+ This command augments each line or chunk of lines in the current
+ file-visiting or blob-visiting buffer with information about the
+ last revision in which a line still existed.
+
+ Like ‘magit-blame-addition’, this command can be used recursively.
+
+‘C-c M-g e’ (‘magit-blame-echo’)
+‘C-c M-g B e’
+ This command is like ‘magit-blame-addition’ except that it doesn’t
+ turn on ‘read-only-mode’ and that it initially uses the
+ visualization style specified by option ‘magit-blame-echo-style’.
+
+ The following key bindings are available when Magit-Blame mode is
+enabled and Read-Only mode is not enabled. These commands are also
+available in other buffers; here only the behavior is described that is
+relevant in file-visiting buffers that are being blamed.
+
+‘<RET>’ (‘magit-show-commit’)
+ This command shows the commit that last touched the line at point.
+
+‘<SPC>’ (‘magit-diff-show-or-scroll-up’)
+ This command updates the commit buffer.
+
+ This either shows the commit that last touched the line at point in
+ the appropriate buffer, or if that buffer is already being
+ displayed in the current frame and if that buffer contains
+ information about that commit, then the buffer is scrolled up
+ instead.
+
+‘<DEL>’ (‘magit-diff-show-or-scroll-down’)
+ This command updates the commit buffer.
+
+ This either shows the commit that last touched the line at point in
+ the appropriate buffer, or if that buffer is already being
+ displayed in the current frame and if that buffer contains
+ information about that commit, then the buffer is scrolled down
+ instead.
+
+ The following key bindings are available when both Magit-Blame mode
+and Read-Only mode are enabled.
+
+‘b’ (‘magit-blame’)
+ See above.
+
+‘n’ (‘magit-blame-next-chunk’)
+ This command moves to the next chunk.
+
+‘N’ (‘magit-blame-next-chunk-same-commit’)
+ This command moves to the next chunk from the same commit.
+
+‘p’ (‘magit-blame-previous-chunk’)
+ This command moves to the previous chunk.
+
+‘P’ (‘magit-blame-previous-chunk-same-commit’)
+ This command moves to the previous chunk from the same commit.
+
+‘q’ (‘magit-blame-quit’)
+ This command turns off Magit-Blame mode. If the buffer was created
+ during a recursive blame, then it also kills the buffer.
+
+‘M-w’ (‘magit-blame-copy-hash’)
+ This command saves the hash of the current chunk’s commit to the
+ kill ring.
+
+ When the region is active, the command saves the region’s content
+ instead of the hash, like ‘kill-ring-save’ would.
+
+‘c’ (‘magit-blame-cycle-style’)
+ This command changes how blame information is visualized in the
+ current buffer by cycling through the styles specified using the
+ option ‘magit-blame-styles’.
+
+ Blaming is also controlled using the following options.
+
+ -- User Option: magit-blame-styles
+ This option defines a list of styles used to visualize blame
+ information. For now see its doc-string to learn more.
+
+ -- User Option: magit-blame-echo-style
+ This option specifies the blame visualization style used by the
+ command ‘magit-blame-echo’. This must be a symbol that is used as
+ the identifier for one of the styles defined in
+ ‘magit-blame-styles’.
+
+ -- User Option: magit-blame-time-format
+ This option specifies the format string used to display times when
+ showing blame information.
+
+ -- User Option: magit-blame-read-only
+ This option controls whether blaming a buffer also makes
+ temporarily read-only.
+
+ -- User Option: magit-blame-disable-modes
+ This option lists incompatible minor-modes that should be disabled
+ temporarily when a buffer contains blame information. They are
+ enabled again when the buffer no longer shows blame information.
+
+ -- User Option: magit-blame-goto-chunk-hook
+ This hook is run when moving between chunks.
+
+
+File: magit.info, Node: Manipulating, Next: Transferring, Prev: Inspecting, Up: Top
+
+6 Manipulating
+**************
+
+* Menu:
+
+* Creating Repository::
+* Cloning Repository::
+* Staging and Unstaging::
+* Applying::
+* Committing::
+* Branching::
+* Merging::
+* Resolving Conflicts::
+* Rebasing::
+* Cherry Picking::
+* Resetting::
+* Stashing::
+
+
+File: magit.info, Node: Creating Repository, Next: Cloning Repository, Up: Manipulating
+
+6.1 Creating Repository
+=======================
+
+‘I’ (‘magit-init’)
+ This command initializes a repository and then shows the status
+ buffer for the new repository.
+
+ If the directory is below an existing repository, then the user has
+ to confirm that a new one should be created inside. If the
+ directory is the root of the existing repository, then the user has
+ to confirm that it should be reinitialized.
+
+
+File: magit.info, Node: Cloning Repository, Next: Staging and Unstaging, Prev: Creating Repository, Up: Manipulating
+
+6.2 Cloning Repository
+======================
+
+To clone a remote or local repository use ‘C’, which is bound to the
+command ‘magit-clone’. This command either act as a transient prefix
+command, which binds several infix arguments and suffix commands, or it
+can invoke ‘git clone’ directly, depending on whether a prefix argument
+is used and on the value of ‘magit-clone-always-transient’.
+
+ -- User Option: magit-clone-always-transient
+ This option controls whether the command ‘magit-clone’ always acts
+ as a transient prefix command, regardless of whether a prefix
+ argument is used or not. If ‘t’, then that command always acts as
+ a transient prefix. If ‘nil’, then a prefix argument has to be
+ used for it to act as a transient.
+
+‘C’ (‘magit-clone’)
+ This command either acts as a transient prefix command as described
+ above or does the same thing as ‘transient-clone-regular’ as
+ described below.
+
+ If it acts as a transient prefix, then it binds the following
+ suffix commands and several infix arguments.
+
+‘C C’ (‘magit-clone-regular’)
+ This command creates a regular clone of an existing repository.
+ The repository and the target directory are read from the user.
+
+‘C s’ (‘magit-clone-shallow’)
+ This command creates a shallow clone of an existing repository.
+ The repository and the target directory are read from the user. By
+ default the depth of the cloned history is a single commit, but
+ with a prefix argument the depth is read from the user.
+
+‘C >’ (‘magit-clone-sparse’)
+ This command creates a clone of an existing repository and
+ initializes a sparse checkout, avoiding a checkout of the full
+ working tree. To add more directories, use the
+ ‘magit-sparse-checkout’ transient (see *note Sparse checkouts::).
+
+‘C b’ (‘magit-clone-bare’)
+ This command creates a bare clone of an existing repository. The
+ repository and the target directory are read from the user.
+
+‘C m’ (‘magit-clone-mirror’)
+ This command creates a mirror of an existing repository. The
+ repository and the target directory are read from the user.
+
+ The following suffixes are disabled by default. See *note
+(transient)Enabling and Disabling Suffixes:: for how to enable them.
+
+‘C d’ (‘magit-clone-shallow-since’)
+ This command creates a shallow clone of an existing repository.
+ Only commits that were committed after a date are cloned, which is
+ read from the user. The repository and the target directory are
+ also read from the user.
+
+‘C e’ (‘magit-clone-shallow-exclude’)
+ This command creates a shallow clone of an existing repository.
+ This reads a branch or tag from the user. Commits that are
+ reachable from that are not cloned. The repository and the target
+ directory are also read from the user.
+
+ -- User Option: magit-clone-set-remote-head
+ This option controls whether cloning causes the reference
+ ‘refs/remotes/<remote>/HEAD’ to be created in the clone. The
+ default is to delete the reference after running ‘git clone’, which
+ insists on creating it. This is because the reference has not been
+ found to be particularly useful as it is not automatically updated
+ when the ‘HEAD’ of the remote changes. Setting this option to ‘t’
+ preserves Git’s default behavior of creating the reference.
+
+ -- User Option: magit-clone-set-remote.pushDefault
+ This option controls whether the value of the Git variable
+ ‘remote.pushDefault’ is set after cloning.
+
+ • If ‘t’, then it is always set without asking.
+ • If ‘ask’, then the users are asked every time they clone a
+ repository.
+ • If ‘nil’, then it is never set.
+
+ -- User Option: magit-clone-default-directory
+ This option control the default directory name used when reading
+ the destination for a cloning operation.
+
+ • If ‘nil’ (the default), then the value of ‘default-directory’
+ is used.
+ • If a directory, then that is used.
+ • If a function, then that is called with the remote url as the
+ only argument and the returned value is used.
+
+ -- User Option: magit-clone-name-alist
+ This option maps regular expressions, which match repository names,
+ to repository urls, making it possible for users to enter short
+ names instead of urls when cloning repositories.
+
+ Each element has the form ‘(REGEXP HOSTNAME USER)’. When the user
+ enters a name when a cloning command asks for a name or url, then
+ that is looked up in this list. The first element whose REGEXP
+ matches is used.
+
+ The format specified by option ‘magit-clone-url-format’ is used to
+ turn the name into an url, using HOSTNAME and the repository name.
+ If the provided name contains a slash, then that is used.
+ Otherwise if the name omits the owner of the repository, then the
+ default user specified in the matched entry is used.
+
+ If USER contains a dot, then it is treated as a Git variable and
+ the value of that is used as the username. Otherwise it is used as
+ the username itself.
+
+ -- User Option: magit-clone-url-format
+ The format specified by this option is used when turning repository
+ names into urls. ‘%h’ is the hostname and ‘%n’ is the repository
+ name, including the name of the owner.
+
+
+File: magit.info, Node: Staging and Unstaging, Next: Applying, Prev: Cloning Repository, Up: Manipulating
+
+6.3 Staging and Unstaging
+=========================
+
+Like Git, Magit can of course stage and unstage complete files. Unlike
+Git, it also allows users to gracefully un-/stage individual hunks and
+even just part of a hunk. To stage individual hunks and parts of hunks
+using Git directly, one has to use the very modal and rather clumsy
+interface of a ‘git add --interactive’ session.
+
+ With Magit, on the other hand, one can un-/stage individual hunks by
+just moving point into the respective section inside a diff displayed in
+the status buffer or a separate diff buffer and typing ‘s’ or ‘u’. To
+operate on just parts of a hunk, mark the changes that should be
+un-/staged using the region and then press the same key that would be
+used to un-/stage. To stage multiple files or hunks at once use a
+region that starts inside the heading of such a section and ends inside
+the heading of a sibling section of the same type.
+
+ Besides staging and unstaging, Magit also provides several other
+"apply variants" that can also operate on a file, multiple files at
+once, a hunk, multiple hunks at once, and on parts of a hunk. These
+apply variants are described in the next section.
+
+ You can also use Ediff to stage and unstage. See *note Ediffing::.
+
+‘s’ (‘magit-stage’)
+ Add the change at point to the staging area.
+
+ With a prefix argument and an untracked file (or files) at point,
+ stage the file but not its content. This makes it possible to
+ stage only a subset of the new file’s changes.
+
+‘S’ (‘magit-stage-modified’)
+ Stage all changes to files modified in the worktree. Stage all new
+ content of tracked files and remove tracked files that no longer
+ exist in the working tree from the index also. With a prefix
+ argument also stage previously untracked (but not ignored) files.
+
+‘u’ (‘magit-unstage’)
+ Remove the change at point from the staging area.
+
+ Only staged changes can be unstaged. But by default this command
+ performs an action that is somewhat similar to unstaging, when it
+ is called on a committed change: it reverses the change in the
+ index but not in the working tree.
+
+‘U’ (‘magit-unstage-all’)
+ Remove all changes from the staging area.
+
+ -- User Option: magit-unstage-committed
+ This option controls whether ‘magit-unstage’ "unstages" committed
+ changes by reversing them in the index but not the working tree.
+ The alternative is to raise an error.
+
+‘M-x magit-reverse-in-index’
+ This command reverses the committed change at point in the index
+ but not the working tree. By default no key is bound directly to
+ this command, but it is indirectly called when ‘u’
+ (‘magit-unstage’) is pressed on a committed change.
+
+ This allows extracting a change from ‘HEAD’, while leaving it in
+ the working tree, so that it can later be committed using a
+ separate commit. A typical workflow would be:
+
+ 1. Optionally make sure that there are no uncommitted changes.
+ 2. Visit the ‘HEAD’ commit and navigate to the change that should
+ not have been included in that commit.
+ 3. Type ‘u’ (‘magit-unstage’) to reverse it in the index. This
+ assumes that ‘magit-unstage-committed-changes’ is non-nil.
+ 4. Type ‘c e’ to extend ‘HEAD’ with the staged changes, including
+ those that were already staged before.
+ 5. Optionally stage the remaining changes using ‘s’ or ‘S’ and
+ then type ‘c c’ to create a new commit.
+
+‘M-x magit-reset-index’
+ Reset the index to some commit. The commit is read from the user
+ and defaults to the commit at point. If there is no commit at
+ point, then it defaults to ‘HEAD’.
+
+* Menu:
+
+* Staging from File-Visiting Buffers::
+
+
+File: magit.info, Node: Staging from File-Visiting Buffers, Up: Staging and Unstaging
+
+6.3.1 Staging from File-Visiting Buffers
+----------------------------------------
+
+Fine-grained un-/staging has to be done from the status or a diff
+buffer, but it’s also possible to un-/stage all changes made to the file
+visited in the current buffer right from inside that buffer.
+
+‘M-x magit-stage-file’
+ When invoked inside a file-visiting buffer, then stage all changes
+ to that file. In a Magit buffer, stage the file at point if any.
+ Otherwise prompt for a file to be staged. With a prefix argument
+ always prompt the user for a file, even in a file-visiting buffer
+ or when there is a file section at point.
+
+‘M-x magit-unstage-file’
+ When invoked inside a file-visiting buffer, then unstage all
+ changes to that file. In a Magit buffer, unstage the file at point
+ if any. Otherwise prompt for a file to be unstaged. With a prefix
+ argument always prompt the user for a file, even in a file-visiting
+ buffer or when there is a file section at point.
+
+
+File: magit.info, Node: Applying, Next: Committing, Prev: Staging and Unstaging, Up: Manipulating
+
+6.4 Applying
+============
+
+Magit provides several "apply variants": stage, unstage, discard,
+reverse, and "regular apply". At least when operating on a hunk they
+are all implemented using ‘git apply’, which is why they are called
+"apply variants".
+
+ • Stage. Apply a change from the working tree to the index. The
+ change also remains in the working tree.
+
+ • Unstage. Remove a change from the index. The change remains in
+ the working tree.
+
+ • Discard. On a staged change, remove it from the working tree and
+ the index. On an unstaged change, remove it from the working tree
+ only.
+
+ • Reverse. Reverse a change in the working tree. Both committed and
+ staged changes can be reversed. Unstaged changes cannot be
+ reversed. Discard them instead.
+
+ • Apply. Apply a change to the working tree. Both committed and
+ staged changes can be applied. Unstaged changes cannot be applied
+ - as they already have been applied.
+
+ The previous section described the staging and unstaging commands.
+What follows are the commands which implement the remaining apply
+variants.
+
+‘a’ (‘magit-apply’)
+ Apply the change at point to the working tree.
+
+ With a prefix argument fallback to a 3-way merge. Doing so causes
+ the change to be applied to the index as well.
+
+‘k’ (‘magit-discard’)
+ Remove the change at point from the working tree.
+
+ On a hunk or file with unresolved conflicts prompt which side to
+ keep (while discarding the other). If point is within the text of
+ a side, then keep that side without prompting.
+
+‘v’ (‘magit-reverse’)
+ Reverse the change at point in the working tree.
+
+ With a prefix argument fallback to a 3-way merge. Doing so causes
+ the change to be applied to the index as well.
+
+ With a prefix argument all apply variants attempt a 3-way merge when
+appropriate (i.e. when ‘git apply’ is used internally).
+
+
+File: magit.info, Node: Committing, Next: Branching, Prev: Applying, Up: Manipulating
+
+6.5 Committing
+==============
+
+When the user initiates a commit, Magit calls ‘git commit’ without any
+arguments, so Git has to get it from the user. It creates the file
+‘.git/COMMIT_EDITMSG’ and then opens that file in an editor. Magit
+arranges for that editor to be the Emacsclient. Once the user finishes
+the editing session, the Emacsclient exits and Git creates the commit
+using the file’s content as message.
+
+* Menu:
+
+* Initiating a Commit::
+* Editing Commit Messages::
+
+
+File: magit.info, Node: Initiating a Commit, Next: Editing Commit Messages, Up: Committing
+
+6.5.1 Initiating a Commit
+-------------------------
+
+Also see *note (gitman)git-commit::.
+
+‘c’ (‘magit-commit’)
+ This transient prefix command binds the following suffix commands
+ along with the appropriate infix arguments and displays them in a
+ temporary buffer until a suffix is invoked.
+
+‘c c’ (‘magit-commit-create’)
+ Create a new commit on ‘HEAD’. With a prefix argument amend to the
+ commit at ‘HEAD’ instead.
+
+‘c a’ (‘magit-commit-amend’)
+ Amend the last commit.
+
+‘c e’ (‘magit-commit-extend’)
+ Amend the last commit, without editing the message. With a prefix
+ argument keep the committer date, otherwise change it. The option
+ ‘magit-commit-extend-override-date’ can be used to inverse the
+ meaning of the prefix argument.
+
+ Non-interactively respect the optional OVERRIDE-DATE argument and
+ ignore the option.
+
+‘c w’ (‘magit-commit-reword’)
+ Reword the last commit, ignoring staged changes. With a prefix
+ argument keep the committer date, otherwise change it. The option
+ ‘magit-commit-reword-override-date’ can be used to inverse the
+ meaning of the prefix argument.
+
+ Non-interactively respect the optional OVERRIDE-DATE argument and
+ ignore the option.
+
+‘c f’ (‘magit-commit-fixup’)
+ Create a fixup commit.
+
+ With a prefix argument the target commit has to be confirmed.
+ Otherwise the commit at point may be used without confirmation
+ depending on the value of option ‘magit-commit-squash-confirm’.
+
+‘c F’ (‘magit-commit-instant-fixup’)
+ Create a fixup commit and instantly rebase.
+
+‘c s’ (‘magit-commit-squash’)
+ Create a squash commit, without editing the squash message.
+
+ With a prefix argument the target commit has to be confirmed.
+ Otherwise the commit at point may be used without confirmation
+ depending on the value of option ‘magit-commit-squash-confirm’.
+
+‘c S’ (‘magit-commit-instant-squash’)
+ Create a squash commit and instantly rebase.
+
+‘c A’ (‘magit-commit-augment’)
+ Create a squash commit, editing the squash message.
+
+ With a prefix argument the target commit has to be confirmed.
+ Otherwise the commit at point may be used without confirmation
+ depending on the value of option ‘magit-commit-squash-confirm’.
+
+ -- User Option: magit-commit-ask-to-stage
+ Whether to ask to stage all unstaged changes when committing and
+ nothing is staged.
+
+ -- User Option: magit-commit-show-diff
+ Whether the relevant diff is automatically shown when committing.
+
+ -- User Option: magit-commit-extend-override-date
+ Whether using ‘magit-commit-extend’ changes the committer date.
+
+ -- User Option: magit-commit-reword-override-date
+ Whether using ‘magit-commit-reword’ changes the committer date.
+
+ -- User Option: magit-commit-squash-confirm
+ Whether the commit targeted by squash and fixup has to be
+ confirmed. When non-nil then the commit at point (if any) is used
+ as default choice. Otherwise it has to be confirmed. This option
+ only affects ‘magit-commit-squash’ and ‘magit-commit-fixup’. The
+ "instant" variants always require confirmation because making an
+ error while using those is harder to recover from.
+
+ -- User Option: magit-post-commit-hook
+ Hook run after creating a commit without the user editing a
+ message.
+
+ This hook is run by ‘magit-refresh’ if ‘this-command’ is a member
+ of ‘magit-post-stage-hook-commands’. This only includes commands
+ named ‘magit-commit-*’ that do *not* require that the user edits
+ the commit message in a buffer.
+
+ Also see ‘git-commit-post-finish-hook’.
+
+ -- User Option: magit-commit-diff-inhibit-same-window
+ Whether to inhibit use of same window when showing diff while
+ committing.
+
+ When writing a commit, then a diff of the changes to be committed
+ is automatically shown. The idea is that the diff is shown in a
+ different window of the same frame and for most users that just
+ works. In other words most users can completely ignore this option
+ because its value doesn’t make a difference for them.
+
+ However for users who configured Emacs to never create a new window
+ even when the package explicitly tries to do so, then displaying
+ two new buffers necessarily means that the first is immediately
+ replaced by the second. In our case the message buffer is
+ immediately replaced by the diff buffer, which is of course highly
+ undesirable.
+
+ A workaround is to suppress this user configuration in this
+ particular case. Users have to explicitly opt-in by toggling this
+ option. We cannot enable the workaround unconditionally because
+ that again causes issues for other users: if the frame is too tiny
+ or the relevant settings too aggressive, then the diff buffer would
+ end up being displayed in a new frame.
+
+ Also see <https://github.com/magit/magit/issues/4132>.
+
+
+File: magit.info, Node: Editing Commit Messages, Prev: Initiating a Commit, Up: Committing
+
+6.5.2 Editing Commit Messages
+-----------------------------
+
+After initiating a commit as described in the previous section, two new
+buffers appear. One shows the changes that are about to be committed,
+while the other is used to write the message.
+
+ Commit messages are edited in an edit session - in the background
+‘git’ is waiting for the editor, in our case ‘emacsclient’, to save the
+commit message in a file (in most cases ‘.git/COMMIT_EDITMSG’) and then
+return. If the editor returns with a non-zero exit status then ‘git’
+does not create the commit. So the most important commands are those
+for finishing and aborting the commit.
+
+‘C-c C-c’ (‘with-editor-finish’)
+ Finish the current editing session by returning with exit code 0.
+ Git then creates the commit using the message it finds in the file.
+
+‘C-c C-k’ (‘with-editor-cancel’)
+ Cancel the current editing session by returning with exit code 1.
+ Git then cancels the commit, but leaves the file untouched.
+
+ In addition to being used by ‘git commit’, messages may also be
+stored in a ring that persists until Emacs is closed. By default the
+message is stored at the beginning and the end of an edit session
+(regardless of whether the session is finished successfully or was
+canceled). It is sometimes useful to bring back messages from that
+ring.
+
+‘C-c M-s’ (‘git-commit-save-message’)
+ Save the current buffer content to the commit message ring.
+
+‘M-p’ (‘git-commit-prev-message’)
+ Cycle backward through the commit message ring, after saving the
+ current message to the ring. With a numeric prefix ARG, go back
+ ARG comments.
+
+‘M-n’ (‘git-commit-next-message’)
+ Cycle forward through the commit message ring, after saving the
+ current message to the ring. With a numeric prefix ARG, go back
+ ARG comments.
+
+ By default the diff for the changes that are about to be committed
+are automatically shown when invoking the commit. To prevent that,
+remove ‘magit-commit-diff’ from ‘server-switch-hook’.
+
+ When amending to an existing commit it may be useful to show either
+the changes that are about to be added to that commit or to show those
+changes alongside those that have already been committed.
+
+‘C-c C-d’ (‘magit-diff-while-committing’)
+ While committing, show the changes that are about to be committed.
+ While amending, invoking the command again toggles between showing
+ just the new changes or all the changes that will be committed.
+
+* Menu:
+
+* Using the Revision Stack::
+* Commit Pseudo Headers::
+* Commit Mode and Hooks::
+* Commit Message Conventions::
+
+
+File: magit.info, Node: Using the Revision Stack, Next: Commit Pseudo Headers, Up: Editing Commit Messages
+
+Using the Revision Stack
+........................
+
+‘C-c C-w’ (‘magit-pop-revision-stack’)
+ This command inserts a representation of a revision into the
+ current buffer. It can be used inside buffers used to write commit
+ messages but also in other buffers such as buffers used to edit
+ emails or ChangeLog files.
+
+ By default this command pops the revision which was last added to
+ the ‘magit-revision-stack’ and inserts it into the current buffer
+ according to ‘magit-pop-revision-stack-format’. Revisions can be
+ put on the stack using ‘magit-copy-section-value’ and
+ ‘magit-copy-buffer-revision’.
+
+ If the stack is empty or with a prefix argument it instead reads a
+ revision in the minibuffer. By using the minibuffer history this
+ allows selecting an item which was popped earlier or to insert an
+ arbitrary reference or revision without first pushing it onto the
+ stack.
+
+ When reading the revision from the minibuffer, then it might not be
+ possible to guess the correct repository. When this command is
+ called inside a repository (e.g. while composing a commit
+ message), then that repository is used. Otherwise (e.g. while
+ composing an email) then the repository recorded for the top
+ element of the stack is used (even though we insert another
+ revision). If not called inside a repository and with an empty
+ stack, or with two prefix arguments, then read the repository in
+ the minibuffer too.
+
+ -- User Option: magit-pop-revision-stack-format
+ This option controls how the command ‘magit-pop-revision-stack’
+ inserts a revision into the current buffer.
+
+ The entries on the stack have the format ‘(HASH TOPLEVEL)’ and this
+ option has the format ‘(POINT-FORMAT EOB-FORMAT INDEX-REGEXP)’, all
+ of which may be nil or a string (though either one of EOB-FORMAT or
+ POINT-FORMAT should be a string, and if INDEX-REGEXP is non-nil,
+ then the two formats should be too).
+
+ First INDEX-REGEXP is used to find the previously inserted entry,
+ by searching backward from point. The first submatch must match
+ the index number. That number is incremented by one, and becomes
+ the index number of the entry to be inserted. If you don’t want to
+ number the inserted revisions, then use nil for INDEX-REGEXP.
+
+ If INDEX-REGEXP is non-nil then both POINT-FORMAT and EOB-FORMAT
+ should contain \"%N\", which is replaced with the number that was
+ determined in the previous step.
+
+ Both formats, if non-nil and after removing %N, are then expanded
+ using ‘git show --format=FORMAT ...’ inside TOPLEVEL.
+
+ The expansion of POINT-FORMAT is inserted at point, and the
+ expansion of EOB-FORMAT is inserted at the end of the buffer (if
+ the buffer ends with a comment, then it is inserted right before
+ that).
+
+
+File: magit.info, Node: Commit Pseudo Headers, Next: Commit Mode and Hooks, Prev: Using the Revision Stack, Up: Editing Commit Messages
+
+Commit Pseudo Headers
+.....................
+
+Some projects use pseudo headers in commit messages. Magit colorizes
+such headers and provides some commands to insert such headers.
+
+ -- User Option: git-commit-known-pseudo-headers
+ A list of Git pseudo headers to be highlighted.
+
+‘C-c C-i’ (‘git-commit-insert-pseudo-header’)
+ Insert a commit message pseudo header.
+
+‘C-c C-a’ (‘git-commit-ack’)
+ Insert a header acknowledging that you have looked at the commit.
+
+‘C-c C-r’ (‘git-commit-review’)
+ Insert a header acknowledging that you have reviewed the commit.
+
+‘C-c C-s’ (‘git-commit-signoff’)
+ Insert a header to sign off the commit.
+
+‘C-c C-t’ (‘git-commit-test’)
+ Insert a header acknowledging that you have tested the commit.
+
+‘C-c C-o’ (‘git-commit-cc’)
+ Insert a header mentioning someone who might be interested.
+
+‘C-c C-p’ (‘git-commit-reported’)
+ Insert a header mentioning the person who reported the issue being
+ fixed by the commit.
+
+‘C-c M-i’ (‘git-commit-suggested’)
+ Insert a header mentioning the person who suggested the change.
+
+
+File: magit.info, Node: Commit Mode and Hooks, Next: Commit Message Conventions, Prev: Commit Pseudo Headers, Up: Editing Commit Messages
+
+Commit Mode and Hooks
+.....................
+
+‘git-commit-mode’ is a minor mode that is only used to establish certain
+key bindings. This makes it possible to use an arbitrary major mode in
+buffers used to edit commit messages. It is even possible to use
+different major modes in different repositories, which is useful when
+different projects impose different commit message conventions.
+
+ -- User Option: git-commit-major-mode
+ The value of this option is the major mode used to edit Git commit
+ messages.
+
+ Because ‘git-commit-mode’ is a minor mode, we don’t use its mode hook
+to setup the buffer, except for the key bindings. All other setup
+happens in the function ‘git-commit-setup’, which among other things
+runs the hook ‘git-commit-setup-hook’.
+
+ -- User Option: git-commit-setup-hook
+ Hook run at the end of ‘git-commit-setup’.
+
+The following functions are suitable for this hook:
+
+ -- Function: git-commit-save-message
+ Save the current buffer content to the commit message ring.
+
+ -- Function: git-commit-setup-changelog-support
+ After this function is called, ChangeLog entries are treated as
+ paragraphs.
+
+ -- Function: git-commit-turn-on-auto-fill
+ Turn on ‘auto-fill-mode’ and set ‘fill-column’ to the value of
+ ‘git-commit-fill-column’.
+
+ -- Function: git-commit-turn-on-flyspell
+ Turn on Flyspell mode. Also prevent comments from being checked
+ and finally check current non-comment text.
+
+ -- Function: git-commit-propertize-diff
+ Propertize the diff shown inside the commit message buffer. Git
+ inserts such diffs into the commit message template when the
+ ‘--verbose’ argument is used. ‘magit-commit’ by default does not
+ offer that argument because the diff that is shown in a separate
+ buffer is more useful. But some users disagree, which is why this
+ function exists.
+
+ -- Function: bug-reference-mode
+ Hyperlink bug references in the buffer.
+
+ -- Function: with-editor-usage-message
+ Show usage information in the echo area.
+
+ -- User Option: git-commit-post-finish-hook
+ Hook run after the user finished writing a commit message.
+
+ This hook is only run after pressing ‘C-c C-c’ in a buffer used to
+ edit a commit message. If a commit is created without the user
+ typing a message into a buffer, then this hook is not run.
+
+ This hook is not run until the new commit has been created. If
+ doing so takes Git longer than one second, then this hook isn’t run
+ at all. For certain commands such as ‘magit-rebase-continue’ this
+ hook is never run because doing so would lead to a race condition.
+
+ This hook is only run if ‘magit’ is available.
+
+ Also see ‘magit-post-commit-hook’.
+
+
+File: magit.info, Node: Commit Message Conventions, Prev: Commit Mode and Hooks, Up: Editing Commit Messages
+
+Commit Message Conventions
+..........................
+
+Git-Commit highlights certain violations of commonly accepted commit
+message conventions. Certain violations even cause Git-Commit to ask
+you to confirm that you really want to do that. This nagging can of
+course be turned off, but the result of doing that usually is that
+instead of some code it’s now the human who is reviewing your commits
+who has to waste some time telling you to fix your commits.
+
+ -- User Option: git-commit-summary-max-length
+ The intended maximal length of the summary line of commit messages.
+ Characters beyond this column are colorized to indicate that this
+ preference has been violated.
+
+ -- User Option: git-commit-fill-column
+ Column beyond which automatic line-wrapping should happen in commit
+ message buffers.
+
+ -- User Option: git-commit-finish-query-functions
+ List of functions called to query before performing commit.
+
+ The commit message buffer is current while the functions are
+ called. If any of them returns nil, then the commit is not
+ performed and the buffer is not killed. The user should then fix
+ the issue and try again.
+
+ The functions are called with one argument. If it is non-nil then
+ that indicates that the user used a prefix argument to force
+ finishing the session despite issues. Functions should usually
+ honor this wish and return non-nil.
+
+ By default the only member is ‘git-commit-check-style-conventions’.
+
+ -- Function: git-commit-check-style-conventions
+ This function checks for violations of certain basic style
+ conventions. For each violation it asks users if they want to
+ proceed anyway.
+
+ -- User Option: git-commit-style-convention-checks
+ This option controls what conventions the function by the same name
+ tries to enforce. The value is a list of self-explanatory symbols
+ identifying certain conventions; ‘non-empty-second-line’ and
+ ‘overlong-summary-line’.
+
+
+File: magit.info, Node: Branching, Next: Merging, Prev: Committing, Up: Manipulating
+
+6.6 Branching
+=============
+
+* Menu:
+
+* The Two Remotes::
+* Branch Commands::
+* Branch Git Variables::
+* Auxiliary Branch Commands::
+
+
+File: magit.info, Node: The Two Remotes, Next: Branch Commands, Up: Branching
+
+6.6.1 The Two Remotes
+---------------------
+
+The upstream branch of some local branch is the branch into which the
+commits on that local branch should eventually be merged, usually
+something like ‘origin/master’. For the ‘master’ branch itself the
+upstream branch and the branch it is being pushed to, are usually the
+same remote branch. But for a feature branch the upstream branch and
+the branch it is being pushed to should differ.
+
+ The commits on feature branches too should _eventually_ end up in a
+remote branch such as ‘origin/master’ or ‘origin/maint’. Such a branch
+should therefore be used as the upstream. But feature branches
+shouldn’t be pushed directly to such branches. Instead a feature branch
+‘my-feature’ is usually pushed to ‘my-fork/my-feature’ or if you are a
+contributor ‘origin/my-feature’. After the new feature has been
+reviewed, the maintainer merges the feature into ‘master’. And finally
+‘master’ (not ‘my-feature’ itself) is pushed to ‘origin/master’.
+
+ But new features seldom are perfect on the first try, and so feature
+branches usually have to be reviewed, improved, and re-pushed several
+times. Pushing should therefore be easy to do, and for that reason many
+Git users have concluded that it is best to use the remote branch to
+which the local feature branch is being pushed as its upstream.
+
+ But luckily Git has long ago gained support for a push-remote which
+can be configured separately from the upstream branch, using the
+variables ‘branch.<name>.pushRemote’ and ‘remote.pushDefault’. So we no
+longer have to choose which of the two remotes should be used as "the
+remote".
+
+ Each of the fetching, pulling, and pushing transient commands
+features three suffix commands that act on the current branch and some
+other branch. Of these, ‘p’ is bound to a command which acts on the
+push-remote, ‘u’ is bound to a command which acts on the upstream, and
+‘e’ is bound to a command which acts on any other branch. The status
+buffer shows unpushed and unpulled commits for both the push-remote and
+the upstream.
+
+ It’s fairly simple to configure these two remotes. The values of all
+the variables that are related to fetching, pulling, and pushing (as
+well as some other branch-related variables) can be inspected and
+changed using the command ‘magit-branch-configure’, which is available
+from many transient prefix commands that deal with branches. It is also
+possible to set the push-remote or upstream while pushing (see *note
+Pushing::).
+
+
+File: magit.info, Node: Branch Commands, Next: Branch Git Variables, Prev: The Two Remotes, Up: Branching
+
+6.6.2 Branch Commands
+---------------------
+
+The transient prefix command ‘magit-branch’ is used to create and
+checkout branches, and to make changes to existing branches. It is not
+used to fetch, pull, merge, rebase, or push branches, i.e. this command
+deals with branches themselves, not with the commits reachable from
+them. Those features are available from separate transient command.
+
+‘b’ (‘magit-branch’)
+ This transient prefix command binds the following suffix commands
+ and displays them in a temporary buffer until a suffix is invoked.
+
+ By default it also binds and displays the values of some
+ branch-related Git variables and allows changing their values.
+
+ -- User Option: magit-branch-direct-configure
+ This option controls whether the transient command ‘magit-branch’
+ can be used to directly change the values of Git variables. This
+ defaults to ‘t’ (to avoid changing key bindings). When set to
+ ‘nil’, then no variables are displayed by that transient command,
+ and its suffix command ‘magit-branch-configure’ has to be used
+ instead to view and change branch related variables.
+
+‘b C’ (‘magit-branch-configure’)
+‘f C’
+‘F C’
+‘P C’
+ This transient prefix command binds commands that set the value of
+ branch-related variables and displays them in a temporary buffer
+ until the transient is exited.
+
+ With a prefix argument, this command always prompts for a branch.
+
+ Without a prefix argument this depends on whether it was invoked as
+ a suffix of ‘magit-branch’ and on the
+ ‘magit-branch-direct-configure’ option. If ‘magit-branch’ already
+ displays the variables for the current branch, then it isn’t useful
+ to invoke another transient that displays them for the same branch.
+ In that case this command prompts for a branch.
+
+ The variables are described in *note Branch Git Variables::.
+
+‘b b’ (‘magit-checkout’)
+ Checkout a revision read in the minibuffer and defaulting to the
+ branch or arbitrary revision at point. If the revision is a local
+ branch then that becomes the current branch. If it is something
+ else then ‘HEAD’ becomes detached. Checkout fails if the working
+ tree or the staging area contain changes.
+
+‘b n’ (‘magit-branch-create’)
+ Create a new branch. The user is asked for a branch or arbitrary
+ revision to use as the starting point of the new branch. When a
+ branch name is provided, then that becomes the upstream branch of
+ the new branch. The name of the new branch is also read in the
+ minibuffer.
+
+ Also see option ‘magit-branch-prefer-remote-upstream’.
+
+‘b c’ (‘magit-branch-and-checkout’)
+ This command creates a new branch like ‘magit-branch-create’, but
+ then also checks it out.
+
+ Also see option ‘magit-branch-prefer-remote-upstream’.
+
+‘b l’ (‘magit-branch-checkout’)
+ This command checks out an existing or new local branch. It reads
+ a branch name from the user offering all local branches and a
+ subset of remote branches as candidates. Remote branches for which
+ a local branch by the same name exists are omitted from the list of
+ candidates. The user can also enter a completely new branch name.
+
+ • If the user selects an existing local branch, then that is
+ checked out.
+
+ • If the user selects a remote branch, then it creates and
+ checks out a new local branch with the same name, and
+ configures the selected remote branch as the push target.
+
+ • If the user enters a new branch name, then it creates and
+ checks that out, after also reading the starting-point from
+ the user.
+
+ In the latter two cases the upstream is also set. Whether it is
+ set to the chosen starting point or something else depends on the
+ value of ‘magit-branch-adjust-remote-upstream-alist’.
+
+‘b s’ (‘magit-branch-spinoff’)
+ This command creates and checks out a new branch starting at and
+ tracking the current branch. That branch in turn is reset to the
+ last commit it shares with its upstream. If the current branch has
+ no upstream or no unpushed commits, then the new branch is created
+ anyway and the previously current branch is not touched.
+
+ This is useful to create a feature branch after work has already
+ began on the old branch (likely but not necessarily "master").
+
+ If the current branch is a member of the value of option
+ ‘magit-branch-prefer-remote-upstream’ (which see), then the current
+ branch will be used as the starting point as usual, but the
+ upstream of the starting-point may be used as the upstream of the
+ new branch, instead of the starting-point itself.
+
+ If optional FROM is non-nil, then the source branch is reset to
+ ‘FROM~’, instead of to the last commit it shares with its upstream.
+ Interactively, FROM is only ever non-nil, if the region selects
+ some commits, and among those commits, FROM is the commit that is
+ the fewest commits ahead of the source branch.
+
+ The commit at the other end of the selection actually does not
+ matter, all commits between FROM and ‘HEAD’ are moved to the new
+ branch. If FROM is not reachable from ‘HEAD’ or is reachable from
+ the source branch’s upstream, then an error is raised.
+
+‘b S’ (‘magit-branch-spinout’)
+ This command behaves like ‘magit-branch-spinoff’, except that it
+ does not change the current branch. If there are any uncommitted
+ changes, then it behaves exactly like ‘magit-branch-spinoff’.
+
+‘b x’ (‘magit-branch-reset’)
+ This command resets a branch, defaulting to the branch at point, to
+ the tip of another branch or any other commit.
+
+ When the branch being reset is the current branch, then a hard
+ reset is performed. If there are any uncommitted changes, then the
+ user has to confirm the reset because those changes would be lost.
+
+ This is useful when you have started work on a feature branch but
+ realize it’s all crap and want to start over.
+
+ When resetting to another branch and a prefix argument is used,
+ then the target branch is set as the upstream of the branch that is
+ being reset.
+
+‘b k’ (‘magit-branch-delete’)
+ Delete one or multiple branches. If the region marks multiple
+ branches, then offer to delete those. Otherwise, prompt for a
+ single branch to be deleted, defaulting to the branch at point.
+
+‘b r’ (‘magit-branch-rename’)
+ Rename a branch. The branch and the new name are read in the
+ minibuffer. With prefix argument the branch is renamed even if
+ that name conflicts with an existing branch.
+
+ -- User Option: magit-branch-read-upstream-first
+ When creating a branch, whether to read the upstream branch before
+ the name of the branch that is to be created. The default is ‘t’,
+ and I recommend you leave it at that.
+
+ -- User Option: magit-branch-prefer-remote-upstream
+ This option specifies whether remote upstreams are favored over
+ local upstreams when creating new branches.
+
+ When a new branch is created, then the branch, commit, or stash at
+ point is suggested as the starting point of the new branch, or if
+ there is no such revision at point the current branch. In either
+ case the user may choose another starting point.
+
+ If the chosen starting point is a branch, then it may also be set
+ as the upstream of the new branch, depending on the value of the
+ Git variable ‘branch.autoSetupMerge’. By default this is done for
+ remote branches, but not for local branches.
+
+ You might prefer to always use some remote branch as upstream. If
+ the chosen starting point is (1) a local branch, (2) whose name
+ matches a member of the value of this option, (3) the upstream of
+ that local branch is a remote branch with the same name, and (4)
+ that remote branch can be fast-forwarded to the local branch, then
+ the chosen branch is used as starting point, but its own upstream
+ is used as the upstream of the new branch.
+
+ Members of this option’s value are treated as branch names that
+ have to match exactly unless they contain a character that makes
+ them invalid as a branch name. Recommended characters to use to
+ trigger interpretation as a regexp are "*" and "^". Some other
+ characters which you might expect to be invalid, actually are not,
+ e.g. ".+$" are all perfectly valid. More precisely, if ‘git
+ check-ref-format --branch STRING’ exits with a non-zero status,
+ then treat STRING as a regexp.
+
+ Assuming the chosen branch matches these conditions you would end
+ up with with e.g.:
+
+ feature --upstream--> origin/master
+
+ instead of
+
+ feature --upstream--> master --upstream--> origin/master
+
+ Which you prefer is a matter of personal preference. If you do
+ prefer the former, then you should add branches such as ‘master’,
+ ‘next’, and ‘maint’ to the value of this options.
+
+ -- User Option: magit-branch-adjust-remote-upstream-alist
+ The value of this option is an alist of branches to be used as the
+ upstream when branching a remote branch.
+
+ When creating a local branch from an ephemeral branch located on a
+ remote, e.g. a feature or hotfix branch, then that remote branch
+ should usually not be used as the upstream branch, since the
+ push-remote already allows accessing it and having both the
+ upstream and the push-remote reference the same related branch
+ would be wasteful. Instead a branch like "maint" or "master"
+ should be used as the upstream.
+
+ This option allows specifying the branch that should be used as the
+ upstream when branching certain remote branches. The value is an
+ alist of the form ‘((UPSTREAM . RULE)...)’. The first matching
+ element is used, the following elements are ignored.
+
+ UPSTREAM is the branch to be used as the upstream for branches
+ specified by RULE. It can be a local or a remote branch.
+
+ RULE can either be a regular expression, matching branches whose
+ upstream should be the one specified by UPSTREAM. Or it can be a
+ list of the only branches that should *not* use UPSTREAM; all other
+ branches will. Matching is done after stripping the remote part of
+ the name of the branch that is being branched from.
+
+ If you use a finite set of non-ephemeral branches across all your
+ repositories, then you might use something like:
+
+ (("origin/master" . ("master" "next" "maint")))
+
+ Or if the names of all your ephemeral branches contain a slash, at
+ least in some repositories, then a good value could be:
+
+ (("origin/master" . "/"))
+
+ Of course you can also fine-tune:
+
+ (("origin/maint" . "\\`hotfix/")
+ ("origin/master" . "\\`feature/"))
+
+ UPSTREAM can be a local branch:
+
+ (("master" . ("master" "next" "maint")))
+
+ Because the main branch is no longer almost always named "master" you
+should also account for other common names:
+
+ (("main" . ("main" "master" "next" "maint"))
+ ("master" . ("main" "master" "next" "maint")))
+
+ -- Command: magit-branch-orphan
+ This command creates and checks out a new orphan branch with
+ contents from a given revision.
+
+ -- Command: magit-branch-or-checkout
+ This command is a hybrid between ‘magit-checkout’ and
+ ‘magit-branch-and-checkout’ and is intended as a replacement for
+ the former in ‘magit-branch’.
+
+ It first asks the user for an existing branch or revision. If the
+ user input actually can be resolved as a branch or revision, then
+ it checks that out, just like ‘magit-checkout’ would.
+
+ Otherwise it creates and checks out a new branch using the input as
+ its name. Before doing so it reads the starting-point for the new
+ branch. This is similar to what ‘magit-branch-and-checkout’ does.
+
+ To use this command instead of ‘magit-checkout’ add this to your
+ init file:
+
+ (transient-replace-suffix 'magit-branch 'magit-checkout
+ '("b" "dwim" magit-branch-or-checkout))
+
+
+File: magit.info, Node: Branch Git Variables, Next: Auxiliary Branch Commands, Prev: Branch Commands, Up: Branching
+
+6.6.3 Branch Git Variables
+--------------------------
+
+These variables can be set from the transient prefix command
+‘magit-branch-configure’. By default they can also be set from
+‘magit-branch’. See *note Branch Commands::.
+
+ -- Variable: branch.NAME.merge
+ Together with ‘branch.NAME.remote’ this variable defines the
+ upstream branch of the local branch named NAME. The value of this
+ variable is the full reference of the upstream _branch_.
+
+ -- Variable: branch.NAME.remote
+ Together with ‘branch.NAME.merge’ this variable defines the
+ upstream branch of the local branch named NAME. The value of this
+ variable is the name of the upstream _remote_.
+
+ -- Variable: branch.NAME.rebase
+ This variable controls whether pulling into the branch named NAME
+ is done by rebasing or by merging the fetched branch.
+
+ • When ‘true’ then pulling is done by rebasing.
+ • When ‘false’ then pulling is done by merging.
+ • When undefined then the value of ‘pull.rebase’ is used. The
+ default of that variable is ‘false’.
+
+ -- Variable: branch.NAME.pushRemote
+ This variable specifies the remote that the branch named NAME is
+ usually pushed to. The value has to be the name of an existing
+ remote.
+
+ It is not possible to specify the name of _branch_ to push the
+ local branch to. The name of the remote branch is always the same
+ as the name of the local branch.
+
+ If this variable is undefined but ‘remote.pushDefault’ is defined,
+ then the value of the latter is used. By default
+ ‘remote.pushDefault’ is undefined.
+
+ -- Variable: branch.NAME.description
+ This variable can be used to describe the branch named NAME. That
+ description is used e.g. when turning the branch into a series of
+ patches.
+
+ The following variables specify defaults which are used if the above
+branch-specific variables are not set.
+
+ -- Variable: pull.rebase
+ This variable specifies whether pulling is done by rebasing or by
+ merging. It can be overwritten using ‘branch.NAME.rebase’.
+
+ • When ‘true’ then pulling is done by rebasing.
+ • When ‘false’ (the default) then pulling is done by merging.
+
+ Since it is never a good idea to merge the upstream branch into a
+ feature or hotfix branch and most branches are such branches, you
+ should consider setting this to ‘true’, and ‘branch.master.rebase’
+ to ‘false’.
+
+ -- Variable: remote.pushDefault
+ This variable specifies what remote the local branches are usually
+ pushed to. This can be overwritten per branch using
+ ‘branch.NAME.pushRemote’.
+
+ The following variables are used during the creation of a branch and
+control whether the various branch-specific variables are automatically
+set at this time.
+
+ -- Variable: branch.autoSetupMerge
+ This variable specifies under what circumstances creating a branch
+ NAME should result in the variables ‘branch.NAME.merge’ and
+ ‘branch.NAME.remote’ being set according to the starting point used
+ to create the branch. If the starting point isn’t a branch, then
+ these variables are never set.
+
+ • When ‘always’ then the variables are set regardless of whether
+ the starting point is a local or a remote branch.
+ • When ‘true’ (the default) then the variables are set when the
+ starting point is a remote branch, but not when it is a local
+ branch.
+ • When ‘false’ then the variables are never set.
+
+ -- Variable: branch.autoSetupRebase
+ This variable specifies whether creating a branch NAME should
+ result in the variable ‘branch.NAME.rebase’ being set to ‘true’.
+
+ • When ‘always’ then the variable is set regardless of whether
+ the starting point is a local or a remote branch.
+ • When ‘local’ then the variable are set when the starting point
+ is a local branch, but not when it is a remote branch.
+ • When ‘remote’ then the variable are set when the starting
+ point is a remote branch, but not when it is a local branch.
+ • When ‘never’ (the default) then the variable is never set.
+
+ Note that the respective commands always change the repository-local
+values. If you want to change the global value, which is used when the
+local value is undefined, then you have to do so on the command line,
+e.g.:
+
+ git config --global remote.autoSetupMerge always
+
+ For more information about these variables you should also see
+
+ *note (gitman)git-config::. Also see *note (gitman)git-branch::. ,
+*note (gitman)git-checkout::. and *note Pushing::.
+
+ -- User Option: magit-prefer-remote-upstream
+ This option controls whether commands that read a branch from the
+ user and then set it as the upstream branch, offer a local or a
+ remote branch as default completion candidate, when they have the
+ choice.
+
+ This affects all commands that use ‘magit-read-upstream-branch’ or
+ ‘magit-read-starting-point’, which includes all commands that
+ change the upstream and many which create new branches.
+
+
+File: magit.info, Node: Auxiliary Branch Commands, Prev: Branch Git Variables, Up: Branching
+
+6.6.4 Auxiliary Branch Commands
+-------------------------------
+
+These commands are not available from the transient ‘magit-branch’ by
+default.
+
+ -- Command: magit-branch-shelve
+ This command shelves a branch. This is done by deleting the
+ branch, and creating a new reference "refs/shelved/BRANCH-NAME"
+ pointing at the same commit as the branch pointed at. If the
+ deleted branch had a reflog, then that is preserved as the reflog
+ of the new reference.
+
+ This is useful if you want to move a branch out of sight, but are
+ not ready to completely discard it yet.
+
+ -- Command: magit-branch-unshelve
+ This command unshelves a branch that was previously shelved using
+ ‘magit-branch-shelve’. This is done by deleting the reference
+ "refs/shelved/BRANCH-NAME" and creating a branch "BRANCH-NAME"
+ pointing at the same commit as the deleted reference pointed at.
+ If the deleted reference had a reflog, then that is restored as the
+ reflog of the branch.
+
+
+File: magit.info, Node: Merging, Next: Resolving Conflicts, Prev: Branching, Up: Manipulating
+
+6.7 Merging
+===========
+
+Also see *note (gitman)git-merge::. For information on how to resolve
+merge conflicts see the next section.
+
+‘m’ (‘magit-merge’)
+ This transient prefix command binds the following suffix commands
+ along with the appropriate infix arguments and displays them in a
+ temporary buffer until a suffix is invoked.
+
+ When no merge is in progress, then the transient features the
+following suffix commands.
+
+‘m m’ (‘magit-merge-plain’)
+ This command merges another branch or an arbitrary revision into
+ the current branch. The branch or revision to be merged is read in
+ the minibuffer and defaults to the branch at point.
+
+ Unless there are conflicts or a prefix argument is used, then the
+ resulting merge commit uses a generic commit message, and the user
+ does not get a chance to inspect or change it before the commit is
+ created. With a prefix argument this does not actually create the
+ merge commit, which makes it possible to inspect how conflicts were
+ resolved and to adjust the commit message.
+
+‘m e’ (‘magit-merge-editmsg’)
+ This command merges another branch or an arbitrary revision into
+ the current branch and opens a commit message buffer, so that the
+ user can make adjustments. The commit is not actually created
+ until the user finishes with ‘C-c C-c’.
+
+‘m n’ (‘magit-merge-nocommit’)
+ This command merges another branch or an arbitrary revision into
+ the current branch, but does not actually create the merge commit.
+ The user can then further adjust the merge, even when automatic
+ conflict resolution succeeded and/or adjust the commit message.
+
+‘m a’ (‘magit-merge-absorb’)
+ This command merges another local branch into the current branch
+ and then removes the former.
+
+ Before the source branch is merged, it is first force pushed to its
+ push-remote, provided the respective remote branch already exists.
+ This ensures that the respective pull-request (if any) won’t get
+ stuck on some obsolete version of the commits that are being
+ merged. Finally, if ‘magit-branch-pull-request’ was used to create
+ the merged branch, then the respective remote branch is also
+ removed.
+
+‘m i’ (‘magit-merge-into’)
+ This command merges the current branch into another local branch
+ and then removes the former. The latter becomes the new current
+ branch.
+
+ Before the source branch is merged, it is first force pushed to its
+ push-remote, provided the respective remote branch already exists.
+ This ensures that the respective pull-request (if any) won’t get
+ stuck on some obsolete version of the commits that are being
+ merged. Finally, if ‘magit-branch-pull-request’ was used to create
+ the merged branch, then the respective remote branch is also
+ removed.
+
+‘m s’ (‘magit-merge-squash’)
+ This command squashes the changes introduced by another branch or
+ an arbitrary revision into the current branch. This only applies
+ the changes made by the squashed commits. No information is
+ preserved that would allow creating an actual merge commit.
+ Instead of this command you should probably use a command from the
+ apply transient.
+
+‘m p’ (‘magit-merge-preview’)
+ This command shows a preview of merging another branch or an
+ arbitrary revision into the current branch.
+
+ When a merge is in progress, then the transient instead features the
+following suffix commands.
+
+‘m m’ (‘magit-merge’)
+ After the user resolved conflicts, this command proceeds with the
+ merge. If some conflicts weren’t resolved, then this command
+ fails.
+
+‘m a’ (‘magit-merge-abort’)
+ This command aborts the current merge operation.
+
+
+File: magit.info, Node: Resolving Conflicts, Next: Rebasing, Prev: Merging, Up: Manipulating
+
+6.8 Resolving Conflicts
+=======================
+
+When merging branches (or otherwise combining or changing history)
+conflicts can occur. If you edited two completely different parts of
+the same file in two branches and then merge one of these branches into
+the other, then Git can resolve that on its own, but if you edit the
+same area of a file, then a human is required to decide how the two
+versions, or "sides of the conflict", are to be combined into one.
+
+ Here we can only provide a brief introduction to the subject and
+point you toward some tools that can help. If you are new to this, then
+please also consult Git’s own documentation as well as other resources.
+
+ If a file has conflicts and Git cannot resolve them by itself, then
+it puts both versions into the affected file along with special markers
+whose purpose is to denote the boundaries of the unresolved part of the
+file and between the different versions. These boundary lines begin
+with the strings consisting of six times the same character, one of ‘<’,
+‘|’, ‘=’ and ‘>’ and are followed by information about the source of the
+respective versions, e.g.:
+
+ <<<<<<< HEAD
+ Take the blue pill.
+ =======
+ Take the red pill.
+ >>>>>>> feature
+
+ In this case you have chosen to take the red pill on one branch and
+on another you picked the blue pill. Now that you are merging these two
+diverging branches, Git cannot possibly know which pill you want to
+take.
+
+ To resolve that conflict you have to create a version of the affected
+area of the file by keeping only one of the sides, possibly by editing
+it in order to bring in the changes from the other side, remove the
+other versions as well as the markers, and then stage the result. A
+possible resolution might be:
+
+ Take both pills.
+
+ Often it is useful to see not only the two sides of the conflict but
+also the "original" version from before the same area of the file was
+modified twice on different branches. Instruct Git to insert that
+version as well by running this command once:
+
+ git config --global merge.conflictStyle diff3
+
+ The above conflict might then have looked like this:
+
+ <<<<<<< HEAD
+ Take the blue pill.
+ ||||||| merged common ancestors
+ Take either the blue or the red pill, but not both.
+ =======
+ Take the red pill.
+ >>>>>>> feature
+
+ If that were the case, then the above conflict resolution would not
+have been correct, which demonstrates why seeing the original version
+alongside the conflicting versions can be useful.
+
+ You can perform the conflict resolution completely by hand, but Emacs
+also provides some packages that help in the process: Smerge, Ediff
+(*note (ediff)Top::), and Emerge (*note (emacs)Emerge::). Magit does
+not provide its own tools for conflict resolution, but it does make
+using Smerge and Ediff more convenient. (Ediff supersedes Emerge, so
+you probably don’t want to use the latter anyway.)
+
+ In the Magit status buffer, files with unresolved conflicts are
+listed in the "Unstaged changes" and/or "Staged changes" sections. They
+are prefixed with the word "unmerged", which in this context essentially
+is a synonym for "unresolved".
+
+ Pressing ‘RET’ while point is on such a file section shows a buffer
+visiting that file, turns on ‘smerge-mode’ in that buffer, and places
+point inside the first area with conflicts. You should then resolve
+that conflict using regular edit commands and/or Smerge commands.
+
+ Unfortunately Smerge does not have a manual, but you can get a list
+of commands and binding ‘C-c ^ C-h’ and press ‘RET’ while point is on a
+command name to read its documentation.
+
+ Normally you would edit one version and then tell Smerge to keep only
+that version. Use ‘C-c ^ m’ (‘smerge-keep-mine’) to keep the ‘HEAD’
+version or ‘C-c ^ o’ (‘smerge-keep-other’) to keep the version that
+follows "|||||||". Then use ‘C-c ^ n’ to move to the next conflicting
+area in the same file. Once you are done resolving conflicts, return to
+the Magit status buffer. The file should now be shown as "modified", no
+longer as "unmerged", because Smerge automatically stages the file when
+you save the buffer after resolving the last conflict.
+
+ Magit now wraps the mentioned Smerge commands, allowing you to use
+these key bindings without having to go to the file-visiting buffer.
+Additionally ‘k’ (‘magit-discard’) on a hunk with unresolved conflicts
+asks which side to keep or, if point is on a side, then it keeps it
+without prompting. Similarly ‘k’ on a unresolved file ask which side to
+keep.
+
+ Alternatively you could use Ediff, which uses separate buffers for
+the different versions of the file. To resolve conflicts in a file
+using Ediff press ‘e’ while point is on such a file in the status
+buffer.
+
+ Ediff can be used for other purposes as well. For more information
+on how to enter Ediff from Magit, see *note Ediffing::. Explaining how
+to use Ediff is beyond the scope of this manual, instead see *note
+(ediff)Top::.
+
+ If you are unsure whether you should Smerge or Ediff, then use the
+former. It is much easier to understand and use, and except for truly
+complex conflicts, the latter is usually overkill.
+
+
+File: magit.info, Node: Rebasing, Next: Cherry Picking, Prev: Resolving Conflicts, Up: Manipulating
+
+6.9 Rebasing
+============
+
+Also see *note (gitman)git-rebase::. For information on how to resolve
+conflicts that occur during rebases see the preceding section.
+
+‘r’ (‘magit-rebase’)
+ This transient prefix command binds the following suffix commands
+ along with the appropriate infix arguments and displays them in a
+ temporary buffer until a suffix is invoked.
+
+ When no rebase is in progress, then the transient features the
+following suffix commands.
+
+ Using one of these commands _starts_ a rebase sequence. Git might
+then stop somewhere along the way, either because you told it to do so,
+or because applying a commit failed due to a conflict. When that
+happens, then the status buffer shows information about the rebase
+sequence which is in progress in a section similar to a log section.
+See *note Information About In-Progress Rebase::.
+
+ For information about the upstream and the push-remote, see *note The
+Two Remotes::.
+
+‘r p’ (‘magit-rebase-onto-pushremote’)
+ This command rebases the current branch onto its push-remote.
+
+ With a prefix argument or when the push-remote is either not
+ configured or unusable, then let the user first configure the
+ push-remote.
+
+‘r u’ (‘magit-rebase-onto-upstream’)
+ This command rebases the current branch onto its upstream branch.
+
+ With a prefix argument or when the upstream is either not
+ configured or unusable, then let the user first configure the
+ upstream.
+
+‘r e’ (‘magit-rebase-branch’)
+ This command rebases the current branch onto a branch read in the
+ minibuffer. All commits that are reachable from head but not from
+ the selected branch TARGET are being rebased.
+
+‘r s’ (‘magit-rebase-subset’)
+ This command starts a non-interactive rebase sequence to transfer
+ commits from START to ‘HEAD’ onto NEWBASE. START has to be
+ selected from a list of recent commits.
+
+ By default Magit uses the ‘--autostash’ argument, which causes
+uncommitted changes to be stored in a stash before the rebase begins.
+These changes are restored after the rebase completes and if possible
+the stash is removed. If the stash does not apply cleanly, then the
+stash is not removed. In case something goes wrong when resolving the
+conflicts, this allows you to start over.
+
+ Even though one of the actions is dedicated to interactive rebases,
+the transient also features the infix argument ‘--interactive’. This
+can be used to turn one of the other, non-interactive rebase variants
+into an interactive rebase.
+
+ For example if you want to clean up a feature branch and at the same
+time rebase it onto ‘master’, then you could use ‘r-iu’. But we
+recommend that you instead do that in two steps. First use ‘ri’ to
+cleanup the feature branch, and then in a second step ‘ru’ to rebase it
+onto ‘master’. That way if things turn out to be more complicated than
+you thought and/or you make a mistake and have to start over, then you
+only have to redo half the work.
+
+ Explicitly enabling ‘--interactive’ won’t have an effect on the
+following commands as they always use that argument anyway, even if it
+is not enabled in the transient.
+
+‘r i’ (‘magit-rebase-interactive’)
+ This command starts an interactive rebase sequence.
+
+‘r f’ (‘magit-rebase-autosquash’)
+ This command combines squash and fixup commits with their intended
+ targets.
+
+‘r m’ (‘magit-rebase-edit-commit’)
+ This command starts an interactive rebase sequence that lets the
+ user edit a single older commit.
+
+‘r w’ (‘magit-rebase-reword-commit’)
+ This command starts an interactive rebase sequence that lets the
+ user reword a single older commit.
+
+‘r k’ (‘magit-rebase-remove-commit’)
+ This command removes a single older commit using rebase.
+
+ When a rebase is in progress, then the transient instead features the
+following suffix commands.
+
+‘r r’ (‘magit-rebase-continue’)
+ This command restart the current rebasing operation.
+
+ In some cases this pops up a commit message buffer for you do edit.
+ With a prefix argument the old message is reused as-is.
+
+‘r s’ (‘magit-rebase-skip’)
+ This command skips the current commit and restarts the current
+ rebase operation.
+
+‘r e’ (‘magit-rebase-edit’)
+ This command lets the user edit the todo list of the current rebase
+ operation.
+
+‘r a’ (‘magit-rebase-abort’)
+ This command aborts the current rebase operation, restoring the
+ original branch.
+
+* Menu:
+
+* Editing Rebase Sequences::
+* Information About In-Progress Rebase::
+
+
+File: magit.info, Node: Editing Rebase Sequences, Next: Information About In-Progress Rebase, Up: Rebasing
+
+6.9.1 Editing Rebase Sequences
+------------------------------
+
+‘C-c C-c’ (‘with-editor-finish’)
+ Finish the current editing session by returning with exit code 0.
+ Git then uses the rebase instructions it finds in the file.
+
+‘C-c C-k’ (‘with-editor-cancel’)
+ Cancel the current editing session by returning with exit code 1.
+ Git then forgoes starting the rebase sequence.
+
+‘<RET>’ (‘git-rebase-show-commit’)
+ Show the commit on the current line in another buffer and select
+ that buffer.
+
+‘<SPC>’ (‘git-rebase-show-or-scroll-up’)
+ Show the commit on the current line in another buffer without
+ selecting that buffer. If the revision buffer is already visible
+ in another window of the current frame, then instead scroll that
+ window up.
+
+‘<DEL>’ (‘git-rebase-show-or-scroll-down’)
+ Show the commit on the current line in another buffer without
+ selecting that buffer. If the revision buffer is already visible
+ in another window of the current frame, then instead scroll that
+ window down.
+
+‘p’ (‘git-rebase-backward-line’)
+ Move to previous line.
+
+‘n’ (‘forward-line’)
+ Move to next line.
+
+‘M-p’ (‘git-rebase-move-line-up’)
+ Move the current commit (or command) up.
+
+‘M-n’ (‘git-rebase-move-line-down’)
+ Move the current commit (or command) down.
+
+‘r’ (‘git-rebase-reword’)
+ Edit message of commit on current line.
+
+‘e’ (‘git-rebase-edit’)
+ Stop at the commit on the current line.
+
+‘s’ (‘git-rebase-squash’)
+ Meld commit on current line into previous commit, and edit message.
+
+‘f’ (‘git-rebase-fixup’)
+ Meld commit on current line into previous commit, discarding the
+ current commit’s message.
+
+‘k’ (‘git-rebase-kill-line’)
+ Kill the current action line.
+
+‘c’ (‘git-rebase-pick’)
+ Use commit on current line.
+
+‘x’ (‘git-rebase-exec’)
+ Insert a shell command to be run after the proceeding commit.
+
+ If there already is such a command on the current line, then edit
+ that instead. With a prefix argument insert a new command even
+ when there already is one on the current line. With empty input
+ remove the command on the current line, if any.
+
+‘b’ (‘git-rebase-break’)
+ Insert a break action before the current line, instructing Git to
+ return control to the user.
+
+‘y’ (‘git-rebase-insert’)
+ Read an arbitrary commit and insert it below current line.
+
+‘C-x u’ (‘git-rebase-undo’)
+ Undo some previous changes. Like ‘undo’ but works in read-only
+ buffers.
+
+ -- User Option: git-rebase-auto-advance
+ Whether to move to next line after changing a line.
+
+ -- User Option: git-rebase-show-instructions
+ Whether to show usage instructions inside the rebase buffer.
+
+ -- User Option: git-rebase-confirm-cancel
+ Whether confirmation is required to cancel.
+
+ When a rebase is performed with the ‘--rebase-merges’ option, the
+sequence will include a few other types of actions and the following
+commands become relevant.
+
+‘l’ (‘git-rebase-label’)
+ This commands inserts a label action or edits the one at point.
+
+‘t’ (‘git-rebase-reset’)
+ This command inserts a reset action or edits the one at point. The
+ prompt will offer the labels that are currently present in the
+ buffer.
+
+‘MM’ (‘git-rebase-merge’)
+ The command inserts a merge action or edits the one at point. The
+ prompt will offer the labels that are currently present in the
+ buffer. Specifying a message to reuse via ‘-c’ or ‘-C’ is not
+ supported; an editor will always be invoked for the merge.
+
+‘Mt’ (‘git-rebase-merge-toggle-editmsg’)
+ This command toggles between the ‘-C’ and ‘-c’ options of the merge
+ action at point. These options both specify a commit whose message
+ should be reused. The lower-case variant instructs Git to invoke
+ the editor when creating the merge, allowing the user to edit the
+ message.
+
+
+File: magit.info, Node: Information About In-Progress Rebase, Prev: Editing Rebase Sequences, Up: Rebasing
+
+6.9.2 Information About In-Progress Rebase
+------------------------------------------
+
+While a rebase sequence is in progress, the status buffer features a
+section that lists the commits that have already been applied as well as
+the commits that still have to be applied.
+
+ The commits are split in two halves. When rebase stops at a commit,
+either because the user has to deal with a conflict or because s/he
+explicitly requested that rebase stops at that commit, then point is
+placed on the commit that separates the two groups, i.e. on ‘HEAD’.
+The commits above it have not been applied yet, while the ‘HEAD’ and the
+commits below it have already been applied. In between these two groups
+of applied and yet-to-be applied commits, there sometimes is a commit
+which has been dropped.
+
+ Each commit is prefixed with a word and these words are additionally
+shown in different colors to indicate the status of the commits.
+
+ The following colors are used:
+
+ • Commits that use the same foreground color as the ‘default’ face
+ have not been applied yet.
+
+ • Yellow commits have some special relationship to the commit rebase
+ stopped at. This is used for the words "join", "goal", "same" and
+ "work" (see below).
+
+ • Gray commits have already been applied.
+
+ • The blue commit is the ‘HEAD’ commit.
+
+ • The green commit is the commit the rebase sequence stopped at. If
+ this is the same commit as ‘HEAD’ (e.g. because you haven’t done
+ anything yet after rebase stopped at the commit, then this commit
+ is shown in blue, not green). There can only be a green *and* a
+ blue commit at the same time, if you create one or more new commits
+ after rebase stops at a commit.
+
+ • Red commits have been dropped. They are shown for reference only,
+ e.g. to make it easier to diff.
+
+ Of course these colors are subject to the color-theme in use.
+
+ The following words are used:
+
+ • Commits prefixed with ‘pick’, ‘reword’, ‘edit’, ‘squash’, and
+ ‘fixup’ have not been applied yet. These words have the same
+ meaning here as they do in the buffer used to edit the rebase
+ sequence. See *note Editing Rebase Sequences::. When the
+ ‘--rebase-merges’ option was specified, ‘reset’, ‘label’, and
+ ‘merge’ lines may also be present.
+
+ • Commits prefixed with ‘done’ and ‘onto’ have already been applied.
+ It is possible for such a commit to be the ‘HEAD’, in which case it
+ is blue. Otherwise it is grey.
+
+ • The commit prefixed with ‘onto’ is the commit on top of which
+ all the other commits are being re-applied. This commit
+ itself did not have to be re-applied, it is the commit rebase
+ did rewind to before starting to re-apply other commits.
+
+ • Commits prefixed with ‘done’ have already been re-applied.
+ This includes commits that have been re-applied but also new
+ commits that you have created during the rebase.
+
+ • All other commits, those not prefixed with any of the above words,
+ are in some way related to the commit at which rebase stopped.
+
+ To determine whether a commit is related to the stopped-at commit
+ their hashes, trees and patch-ids (1) are being compared. The
+ commit message is not used for this purpose.
+
+ Generally speaking commits that are related to the stopped-at
+ commit can have any of the used colors, though not all color/word
+ combinations are possible.
+
+ Words used for stopped-at commits are:
+
+ • When a commit is prefixed with ‘void’, then that indicates
+ that Magit knows for sure that all the changes in that commit
+ have been applied using several new commits. This commit is
+ no longer reachable from ‘HEAD’, and it also isn’t one of the
+ commits that will be applied when resuming the session.
+
+ • When a commit is prefixed with ‘join’, then that indicates
+ that the rebase sequence stopped at that commit due to a
+ conflict - you now have to join (merge) the changes with what
+ has already been applied. In a sense this is the commit
+ rebase stopped at, but while its effect is already in the
+ index and in the worktree (with conflict markers), the commit
+ itself has not actually been applied yet (it isn’t the
+ ‘HEAD’). So it is shown in yellow, like the other commits
+ that still have to be applied.
+
+ • When a commit is prefixed with ‘stop’ or a _blue_ or _green_
+ ‘same’, then that indicates that rebase stopped at this
+ commit, that it is still applied or has been applied again,
+ and that at least its patch-id is unchanged.
+
+ • When a commit is prefixed with ‘stop’, then that
+ indicates that rebase stopped at that commit because you
+ requested that earlier, and its patch-id is unchanged.
+ It might even still be the exact same commit.
+
+ • When a commit is prefixed with a _blue_ or _green_
+ ‘same’, then that indicates that while its tree or hash
+ changed, its patch-id did not. If it is blue, then it is
+ the ‘HEAD’ commit (as always for blue). When it is
+ green, then it no longer is ‘HEAD’ because other commit
+ have been created since (but before continuing the
+ rebase).
+
+ • When a commit is prefixed with ‘goal’, a _yellow_ ‘same,’ or
+ ‘work’, then that indicates that rebase applied that commit
+ but that you then reset ‘HEAD’ to an earlier commit (likely to
+ split it up into multiple commits), and that there are some
+ uncommitted changes remaining which likely (but not
+ necessarily) originate from that commit.
+
+ • When a commit is prefixed with ‘goal’, then that
+ indicates that it is still possible to create a new
+ commit with the exact same tree (the "goal") without
+ manually editing any files, by committing the index, or
+ by staging all changes and then committing that. This is
+ the case when the original tree still exists in the index
+ or worktree in untainted form.
+
+ • When a commit is prefixed with a yellow ‘same’, then that
+ indicates that it is no longer possible to create a
+ commit with the exact same tree, but that it is still
+ possible to create a commit with the same patch-id. This
+ would be the case if you created a new commit with other
+ changes, but the changes from the original commit still
+ exist in the index or working tree in untainted form.
+
+ • When a commit is prefixed with ‘work’, then that
+ indicates that you reset ‘HEAD’ to an earlier commit, and
+ that there are some staged and/or unstaged changes
+ (likely, but not necessarily) originating from that
+ commit. However it is no longer possible to create a new
+ commit with the same tree or at least the same patch-id
+ because you have already made other changes.
+
+ • When a commit is prefixed with ‘poof’ or ‘gone’, then that
+ indicates that rebase applied that commit but that you then
+ reset ‘HEAD’ to an earlier commit (likely to split it up into
+ multiple commits), and that there are no uncommitted changes.
+
+ • When a commit is prefixed with ‘poof’, then that
+ indicates that it is no longer reachable from ‘HEAD’, but
+ that it has been replaced with one or more commits, which
+ together have the exact same effect.
+
+ • When a commit is prefixed with ‘gone’, then that
+ indicates that it is no longer reachable from ‘HEAD’ and
+ that we also cannot determine whether its changes are
+ still in effect in one or more new commits. They might
+ be, but if so, then there must also be other changes
+ which makes it impossible to know for sure.
+
+ Do not worry if you do not fully understand the above. That’s okay,
+you will acquire a good enough understanding through practice.
+
+ For other sequence operations such as cherry-picking, a similar
+section is displayed, but they lack some of the features described
+above, due to limitations in the git commands used to implement them.
+Most importantly these sequences only support "picking" a commit but not
+other actions such as "rewording", and they do not keep track of the
+commits which have already been applied.
+
+ ---------- Footnotes ----------
+
+ (1) The patch-id is a hash of the _changes_ introduced by a commit.
+It differs from the hash of the commit itself, which is a hash of the
+result of applying that change (i.e. the resulting trees and blobs) as
+well as author and committer information, the commit message, and the
+hashes of the parents of the commit. The patch-id hash on the other
+hand is created only from the added and removed lines, even line numbers
+and whitespace changes are ignored when calculating this hash. The
+patch-ids of two commits can be used to answer the question "Do these
+commits make the same change?".
+
+
+File: magit.info, Node: Cherry Picking, Next: Resetting, Prev: Rebasing, Up: Manipulating
+
+6.10 Cherry Picking
+===================
+
+Also see *note (gitman)git-cherry-pick::.
+
+‘A’ (‘magit-cherry-pick’)
+ This transient prefix command binds the following suffix commands
+ along with the appropriate infix arguments and displays them in a
+ temporary buffer until a suffix is invoked.
+
+ When no cherry-pick or revert is in progress, then the transient
+features the following suffix commands.
+
+‘A A’ (‘magit-cherry-copy’)
+ This command copies COMMITS from another branch onto the current
+ branch. If the region selects multiple commits, then those are
+ copied, without prompting. Otherwise the user is prompted for a
+ commit or range, defaulting to the commit at point.
+
+‘A a’ (‘magit-cherry-apply’)
+ This command applies the changes in COMMITS from another branch
+ onto the current branch. If the region selects multiple commits,
+ then those are used, without prompting. Otherwise the user is
+ prompted for a commit or range, defaulting to the commit at point.
+
+ This command also has a top-level binding, which can be invoked
+ without using the transient by typing ‘a’ at the top-level.
+
+ The following commands not only apply some commits to some branch,
+but also remove them from some other branch. The removal is performed
+using either ‘git-update-ref’ or if necessary ‘git-rebase’. Both
+applying commits as well as removing them using ‘git-rebase’ can lead to
+conflicts. If that happens, then these commands abort and you not only
+have to resolve the conflicts but also finish the process the same way
+you would have to if these commands didn’t exist at all.
+
+‘A h’ (‘magit-cherry-harvest’)
+ This command moves the selected COMMITS that must be located on
+ another BRANCH onto the current branch instead, removing them from
+ the former. When this command succeeds, then the same branch is
+ current as before.
+
+ Applying the commits on the current branch or removing them from
+ the other branch can lead to conflicts. When that happens, then
+ this command stops and you have to resolve the conflicts and then
+ finish the process manually.
+
+‘A d’ (‘magit-cherry-donate’)
+ This command moves the selected COMMITS from the current branch
+ onto another existing BRANCH, removing them from the former. When
+ this command succeeds, then the same branch is current as before.
+ ‘HEAD’ is allowed to be detached initially.
+
+ Applying the commits on the other branch or removing them from the
+ current branch can lead to conflicts. When that happens, then this
+ command stops and you have to resolve the conflicts and then finish
+ the process manually.
+
+‘A n’ (‘magit-cherry-spinout’)
+ This command moves the selected COMMITS from the current branch
+ onto a new branch BRANCH, removing them from the former. When this
+ command succeeds, then the same branch is current as before.
+
+ Applying the commits on the other branch or removing them from the
+ current branch can lead to conflicts. When that happens, then this
+ command stops and you have to resolve the conflicts and then finish
+ the process manually.
+
+‘A s’ (‘magit-cherry-spinoff’)
+ This command moves the selected COMMITS from the current branch
+ onto a new branch BRANCH, removing them from the former. When this
+ command succeeds, then the new branch is checked out.
+
+ Applying the commits on the other branch or removing them from the
+ current branch can lead to conflicts. When that happens, then this
+ command stops and you have to resolve the conflicts and then finish
+ the process manually.
+
+ When a cherry-pick or revert is in progress, then the transient
+instead features the following suffix commands.
+
+‘A A’ (‘magit-sequence-continue’)
+ Resume the current cherry-pick or revert sequence.
+
+‘A s’ (‘magit-sequence-skip’)
+ Skip the stopped at commit during a cherry-pick or revert sequence.
+
+‘A a’ (‘magit-sequence-abort’)
+ Abort the current cherry-pick or revert sequence. This discards
+ all changes made since the sequence started.
+
+* Menu:
+
+* Reverting::
+
+
+File: magit.info, Node: Reverting, Up: Cherry Picking
+
+6.10.1 Reverting
+----------------
+
+‘V’ (‘magit-revert’)
+ This transient prefix command binds the following suffix commands
+ along with the appropriate infix arguments and displays them in a
+ temporary buffer until a suffix is invoked.
+
+ When no cherry-pick or revert is in progress, then the transient
+features the following suffix commands.
+
+‘V V’ (‘magit-revert-and-commit’)
+ Revert a commit by creating a new commit. Prompt for a commit,
+ defaulting to the commit at point. If the region selects multiple
+ commits, then revert all of them, without prompting.
+
+‘V v’ (‘magit-revert-no-commit’)
+ Revert a commit by applying it in reverse to the working tree.
+ Prompt for a commit, defaulting to the commit at point. If the
+ region selects multiple commits, then revert all of them, without
+ prompting.
+
+ When a cherry-pick or revert is in progress, then the transient
+instead features the following suffix commands.
+
+‘V A’ (‘magit-sequence-continue’)
+ Resume the current cherry-pick or revert sequence.
+
+‘V s’ (‘magit-sequence-skip’)
+ Skip the stopped at commit during a cherry-pick or revert sequence.
+
+‘V a’ (‘magit-sequence-abort’)
+ Abort the current cherry-pick or revert sequence. This discards
+ all changes made since the sequence started.
+
+
+File: magit.info, Node: Resetting, Next: Stashing, Prev: Cherry Picking, Up: Manipulating
+
+6.11 Resetting
+==============
+
+Also see *note (gitman)git-reset::.
+
+‘x’ (‘magit-reset-quickly’)
+ Reset the ‘HEAD’ and index to some commit read from the user and
+ defaulting to the commit at point, and possibly also reset the
+ working tree. With a prefix argument reset the working tree
+ otherwise don’t.
+
+‘X m’ (‘magit-reset-mixed’)
+ Reset the ‘HEAD’ and index to some commit read from the user and
+ defaulting to the commit at point. The working tree is kept as-is.
+
+‘X s’ (‘magit-reset-soft’)
+ Reset the ‘HEAD’ to some commit read from the user and defaulting
+ to the commit at point. The index and the working tree are kept
+ as-is.
+
+‘X h’ (‘magit-reset-hard’)
+ Reset the ‘HEAD’, index, and working tree to some commit read from
+ the user and defaulting to the commit at point.
+
+‘X k’ (‘magit-reset-keep’)
+ Reset the ‘HEAD’, index, and working tree to some commit read from
+ the user and defaulting to the commit at point. Uncommitted
+ changes are kept as-is.
+
+‘X i’ (‘magit-reset-index’)
+ Reset the index to some commit read from the user and defaulting to
+ the commit at point. Keep the ‘HEAD’ and working tree as-is, so if
+ the commit refers to the ‘HEAD’, then this effectively unstages all
+ changes.
+
+‘X w’ (‘magit-reset-worktree’)
+ Reset the working tree to some commit read from the user and
+ defaulting to the commit at point. Keep the ‘HEAD’ and index
+ as-is.
+
+‘X f’ (‘magit-file-checkout’)
+ Update file in the working tree and index to the contents from a
+ revision. Both the revision and file are read from the user.
+
+
+File: magit.info, Node: Stashing, Prev: Resetting, Up: Manipulating
+
+6.12 Stashing
+=============
+
+Also see *note (gitman)git-stash::.
+
+‘z’ (‘magit-stash’)
+ This transient prefix command binds the following suffix commands
+ along with the appropriate infix arguments and displays them in a
+ temporary buffer until a suffix is invoked.
+
+‘z z’ (‘magit-stash-both’)
+ Create a stash of the index and working tree. Untracked files are
+ included according to infix arguments. One prefix argument is
+ equivalent to ‘--include-untracked’ while two prefix arguments are
+ equivalent to ‘--all’.
+
+‘z i’ (‘magit-stash-index’)
+ Create a stash of the index only. Unstaged and untracked changes
+ are not stashed.
+
+‘z w’ (‘magit-stash-worktree’)
+ Create a stash of unstaged changes in the working tree. Untracked
+ files are included according to infix arguments. One prefix
+ argument is equivalent to ‘--include-untracked’ while two prefix
+ arguments are equivalent to ‘--all’.
+
+‘z x’ (‘magit-stash-keep-index’)
+ Create a stash of the index and working tree, keeping index intact.
+ Untracked files are included according to infix arguments. One
+ prefix argument is equivalent to ‘--include-untracked’ while two
+ prefix arguments are equivalent to ‘--all’.
+
+‘z Z’ (‘magit-snapshot-both’)
+ Create a snapshot of the index and working tree. Untracked files
+ are included according to infix arguments. One prefix argument is
+ equivalent to ‘--include-untracked’ while two prefix arguments are
+ equivalent to ‘--all’.
+
+‘z I’ (‘magit-snapshot-index’)
+ Create a snapshot of the index only. Unstaged and untracked
+ changes are not stashed.
+
+‘z W’ (‘magit-snapshot-worktree’)
+ Create a snapshot of unstaged changes in the working tree.
+ Untracked files are included according to infix arguments. One
+ prefix argument is equivalent to ‘--include-untracked’ while two
+ prefix arguments are equivalent to ‘--all’-.
+
+‘z a’ (‘magit-stash-apply’)
+ Apply a stash to the working tree. Try to preserve the stash
+ index. If that fails because there are staged changes, apply
+ without preserving the stash index.
+
+‘z p’ (‘magit-stash-pop’)
+ Apply a stash to the working tree and remove it from stash list.
+ Try to preserve the stash index. If that fails because there are
+ staged changes, apply without preserving the stash index and forgo
+ removing the stash.
+
+‘z k’ (‘magit-stash-drop’)
+ Remove a stash from the stash list. When the region is active,
+ offer to drop all contained stashes.
+
+‘z v’ (‘magit-stash-show’)
+ Show all diffs of a stash in a buffer.
+
+‘z b’ (‘magit-stash-branch’)
+ Create and checkout a new BRANCH from STASH. The branch starts at
+ the commit that was current when the stash was created.
+
+‘z B’ (‘magit-stash-branch-here’)
+ Create and checkout a new BRANCH using ‘magit-branch’ with the
+ current branch or ‘HEAD’ as the starting-point. Then apply STASH,
+ dropping it if it applies cleanly.
+
+‘z f’ (‘magit-stash-format-patch’)
+ Create a patch from STASH.
+
+‘k’ (‘magit-stash-clear’)
+ Remove all stashes saved in REF’s reflog by deleting REF.
+
+‘z l’ (‘magit-stash-list’)
+ List all stashes in a buffer.
+
+ -- User Option: magit-stashes-margin
+ This option specifies whether the margin is initially shown in
+ stashes buffers and how it is formatted.
+
+ The value has the form ‘(INIT STYLE WIDTH AUTHOR AUTHOR-WIDTH)’.
+
+ • If INIT is non-nil, then the margin is shown initially.
+ • STYLE controls how to format the author or committer date. It
+ can be one of ‘age’ (to show the age of the commit),
+ ‘age-abbreviated’ (to abbreviate the time unit to a
+ character), or a string (suitable for ‘format-time-string’) to
+ show the actual date. Option
+ ‘magit-log-margin-show-committer-date’ controls which date is
+ being displayed.
+ • WIDTH controls the width of the margin. This exists for
+ forward compatibility and currently the value should not be
+ changed.
+ • AUTHOR controls whether the name of the author is also shown
+ by default.
+ • AUTHOR-WIDTH has to be an integer. When the name of the
+ author is shown, then this specifies how much space is used to
+ do so.
+
+
+File: magit.info, Node: Transferring, Next: Miscellaneous, Prev: Manipulating, Up: Top
+
+7 Transferring
+**************
+
+* Menu:
+
+* Remotes::
+* Fetching::
+* Pulling::
+* Pushing::
+* Plain Patches::
+* Maildir Patches::
+
+
+File: magit.info, Node: Remotes, Next: Fetching, Up: Transferring
+
+7.1 Remotes
+===========
+
+* Menu:
+
+* Remote Commands::
+* Remote Git Variables::
+
+
+File: magit.info, Node: Remote Commands, Next: Remote Git Variables, Up: Remotes
+
+7.1.1 Remote Commands
+---------------------
+
+The transient prefix command ‘magit-remote’ is used to add remotes and
+to make changes to existing remotes. This command only deals with
+remotes themselves, not with branches or the transfer of commits. Those
+features are available from separate transient commands.
+
+ Also see *note (gitman)git-remote::.
+
+‘M’ (‘magit-remote’)
+ This transient prefix command binds the following suffix commands
+ and displays them in a temporary buffer until a suffix is invoked.
+
+ By default it also binds and displays the values of some
+ remote-related Git variables and allows changing their values.
+
+ -- User Option: magit-remote-direct-configure
+ This option controls whether remote-related Git variables are
+ accessible directly from the transient ‘magit-remote’.
+
+ If ‘t’ (the default) and a local branch is checked out, then
+ ‘magit-remote’ features the variables for the upstream remote of
+ that branch, or if ‘HEAD’ is detached, for ‘origin’, provided that
+ exists.
+
+ If ‘nil’, then ‘magit-remote-configure’ has to be used to do so.
+
+‘M C’ (‘magit-remote-configure’)
+ This transient prefix command binds commands that set the value of
+ remote-related variables and displays them in a temporary buffer
+ until the transient is exited.
+
+ With a prefix argument, this command always prompts for a remote.
+
+ Without a prefix argument this depends on whether it was invoked as
+ a suffix of ‘magit-remote’ and on the
+ ‘magit-remote-direct-configure’ option. If ‘magit-remote’ already
+ displays the variables for the upstream, then it does not make
+ sense to invoke another transient that displays them for the same
+ remote. In that case this command prompts for a remote.
+
+ The variables are described in *note Remote Git Variables::.
+
+‘M a’ (‘magit-remote-add’)
+ This command add a remote and fetches it. The remote name and url
+ are read in the minibuffer.
+
+‘M r’ (‘magit-remote-rename’)
+ This command renames a remote. Both the old and the new names are
+ read in the minibuffer.
+
+‘M u’ (‘magit-remote-set-url’)
+ This command changes the url of a remote. Both the remote and the
+ new url are read in the minibuffer.
+
+‘M k’ (‘magit-remote-remove’)
+ This command deletes a remote, read in the minibuffer.
+
+‘M p’ (‘magit-remote-prune’)
+ This command removes stale remote-tracking branches for a remote
+ read in the minibuffer.
+
+‘M P’ (‘magit-remote-prune-refspecs’)
+ This command removes stale refspecs for a remote read in the
+ minibuffer.
+
+ A refspec is stale if there no longer exists at least one branch on
+ the remote that would be fetched due to that refspec. A stale
+ refspec is problematic because its existence causes Git to refuse
+ to fetch according to the remaining non-stale refspecs.
+
+ If only stale refspecs remain, then this command offers to either
+ delete the remote or to replace the stale refspecs with the default
+ refspec ("+refs/heads/*:refs/remotes/REMOTE/*").
+
+ This command also removes the remote-tracking branches that were
+ created due to the now stale refspecs. Other stale branches are
+ not removed.
+
+ -- User Option: magit-remote-add-set-remote.pushDefault
+ This option controls whether the user is asked whether they want to
+ set ‘remote.pushDefault’ after adding a remote.
+
+ If ‘ask’, then users is always ask. If ‘ask-if-unset’, then the
+ user is only if the variable isn’t set already. If ‘nil’, then the
+ user isn’t asked and the variable isn’t set. If the value is a
+ string, then the variable is set without the user being asked,
+ provided that the name of the added remote is equal to that string
+ and the variable isn’t already set.
+
+
+File: magit.info, Node: Remote Git Variables, Prev: Remote Commands, Up: Remotes
+
+7.1.2 Remote Git Variables
+--------------------------
+
+These variables can be set from the transient prefix command
+‘magit-remote-configure’. By default they can also be set from
+‘magit-remote’. See *note Remote Commands::.
+
+ -- Variable: remote.NAME.url
+ This variable specifies the url of the remote named NAME. It can
+ have multiple values.
+
+ -- Variable: remote.NAME.fetch
+ The refspec used when fetching from the remote named NAME. It can
+ have multiple values.
+
+ -- Variable: remote.NAME.pushurl
+ This variable specifies the url used for pushing to the remote
+ named NAME. If it is not specified, then ‘remote.NAME.url’ is used
+ instead. It can have multiple values.
+
+ -- Variable: remote.NAME.push
+ The refspec used when pushing to the remote named NAME. It can
+ have multiple values.
+
+ -- Variable: remote.NAME.tagOpts
+ This variable specifies what tags are fetched by default. If the
+ value is ‘--no-tags’ then no tags are fetched. If the value is
+ ‘--tags’, then all tags are fetched. If this variable has no
+ value, then only tags are fetched that are reachable from fetched
+ branches.
+
+
+File: magit.info, Node: Fetching, Next: Pulling, Prev: Remotes, Up: Transferring
+
+7.2 Fetching
+============
+
+Also see *note (gitman)git-fetch::. For information about the upstream
+and the push-remote, see *note The Two Remotes::.
+
+‘f’ (‘magit-fetch’)
+ This transient prefix command binds the following suffix commands
+ along with the appropriate infix arguments and displays them in a
+ temporary buffer until a suffix is invoked.
+
+‘f p’ (‘magit-fetch-from-pushremote’)
+ This command fetches from the current push-remote.
+
+ With a prefix argument or when the push-remote is either not
+ configured or unusable, then let the user first configure the
+ push-remote.
+
+‘f u’ (‘magit-fetch-from-upstream’)
+ This command fetch from the upstream of the current branch.
+
+ If the upstream is configured for the current branch and names an
+ existing remote, then use that. Otherwise try to use another
+ remote: If only a single remote is configured, then use that.
+ Otherwise if a remote named "origin" exists, then use that.
+
+ If no remote can be determined, then this command is not available
+ from the ‘magit-fetch’ transient prefix and invoking it directly
+ results in an error.
+
+‘f e’ (‘magit-fetch-other’)
+ This command fetch from a repository read from the minibuffer.
+
+‘f o’ (‘magit-fetch-branch’)
+ This command fetches a branch from a remote, both of which are read
+ from the minibuffer.
+
+‘f r’ (‘magit-fetch-refspec’)
+ This command fetches from a remote using an explicit refspec, both
+ of which are read from the minibuffer.
+
+‘f a’ (‘magit-fetch-all’)
+ This command fetches from all remotes.
+
+‘f m’ (‘magit-submodule-fetch’)
+ This command fetches all submodules. With a prefix argument it
+ fetches all remotes of all submodules.
+
+ -- User Option: magit-pull-or-fetch
+ By default fetch and pull commands are available from separate
+ transient prefix command. Setting this to ‘t’ adds some (but not
+ all) of the above suffix commands to the ‘magit-pull’ transient.
+
+ If you do that, then you might also want to change the key binding
+ for these prefix commands, e.g.:
+
+ (setq magit-pull-or-fetch t)
+ (define-key magit-mode-map "f" 'magit-pull) ; was magit-fetch
+ (define-key magit-mode-map "F" nil) ; was magit-pull
+
+
+File: magit.info, Node: Pulling, Next: Pushing, Prev: Fetching, Up: Transferring
+
+7.3 Pulling
+===========
+
+Also see *note (gitman)git-pull::. For information about the upstream
+and the push-remote, see *note The Two Remotes::.
+
+‘F’ (‘magit-pull’)
+ This transient prefix command binds the following suffix commands
+ and displays them in a temporary buffer until a suffix is invoked.
+
+‘F p’ (‘magit-pull-from-pushremote’)
+ This command pulls from the push-remote of the current branch.
+
+ With a prefix argument or when the push-remote is either not
+ configured or unusable, then let the user first configure the
+ push-remote.
+
+‘F u’ (‘magit-pull-from-upstream’)
+ This command pulls from the upstream of the current branch.
+
+ With a prefix argument or when the upstream is either not
+ configured or unusable, then let the user first configure the
+ upstream.
+
+‘F e’ (‘magit-pull-branch’)
+ This command pulls from a branch read in the minibuffer.
+
+
+File: magit.info, Node: Pushing, Next: Plain Patches, Prev: Pulling, Up: Transferring
+
+7.4 Pushing
+===========
+
+Also see *note (gitman)git-push::. For information about the upstream
+and the push-remote, see *note The Two Remotes::.
+
+‘P’ (‘magit-push’)
+ This transient prefix command binds the following suffix commands
+ along with the appropriate infix arguments and displays them in a
+ temporary buffer until a suffix is invoked.
+
+‘P p’ (‘magit-push-current-to-pushremote’)
+ This command pushes the current branch to its push-remote.
+
+ With a prefix argument or when the push-remote is either not
+ configured or unusable, then let the user first configure the
+ push-remote.
+
+‘P u’ (‘magit-push-current-to-upstream’)
+ This command pushes the current branch to its upstream branch.
+
+ With a prefix argument or when the upstream is either not
+ configured or unusable, then let the user first configure the
+ upstream.
+
+‘P e’ (‘magit-push-current’)
+ This command pushes the current branch to a branch read in the
+ minibuffer.
+
+‘P o’ (‘magit-push-other’)
+ This command pushes an arbitrary branch or commit somewhere. Both
+ the source and the target are read in the minibuffer.
+
+‘P r’ (‘magit-push-refspecs’)
+ This command pushes one or multiple refspecs to a remote, both of
+ which are read in the minibuffer.
+
+ To use multiple refspecs, separate them with commas. Completion is
+ only available for the part before the colon, or when no colon is
+ used.
+
+‘P m’ (‘magit-push-matching’)
+ This command pushes all matching branches to another repository.
+
+ If only one remote exists, then push to that. Otherwise prompt for
+ a remote, offering the remote configured for the current branch as
+ default.
+
+‘P t’ (‘magit-push-tags’)
+ This command pushes all tags to another repository.
+
+ If only one remote exists, then push to that. Otherwise prompt for
+ a remote, offering the remote configured for the current branch as
+ default.
+
+‘P T’ (‘magit-push-tag’)
+ This command pushes a tag to another repository.
+
+ One of the infix arguments, ‘--force-with-lease’, deserves a word of
+caution. It is passed without a value, which means "permit a force push
+as long as the remote-tracking branches match their counterparts on the
+remote end". If you’ve set up a tool to do automatic fetches (Magit
+itself does not provide such functionality), using ‘--force-with-lease’
+can be dangerous because you don’t actually control or know the state of
+the remote-tracking refs. In that case, you should consider setting
+‘push.useForceIfIncludes’ to ‘true’ (available since Git 2.30).
+
+ Two more push commands exist, which by default are not available from
+the push transient. See their doc-strings for instructions on how to
+add them to the transient.
+
+ -- Command: magit-push-implicitly args
+ This command pushes somewhere without using an explicit refspec.
+
+ This command simply runs ‘git push -v [ARGS]’. ARGS are the infix
+ arguments. No explicit refspec arguments are used. Instead the
+ behavior depends on at least these Git variables: ‘push.default’,
+ ‘remote.pushDefault’, ‘branch.<branch>.pushRemote’,
+ ‘branch.<branch>.remote’, ‘branch.<branch>.merge’, and
+ ‘remote.<remote>.push’.
+
+ If you add this suffix to a transient prefix without explicitly
+ specifying the description, then an attempt is made to predict what
+ this command will do. For example:
+
+ (transient-insert-suffix 'magit-push \"p\"
+ '(\"i\" magit-push-implicitly))"
+
+ -- Command: magit-push-to-remote remote args
+ This command pushes to the remote REMOTE without using an explicit
+ refspec. The remote is read in the minibuffer.
+
+ This command simply runs ‘git push -v [ARGS] REMOTE’. ARGS are the
+ infix arguments. No refspec arguments are used. Instead the
+ behavior depends on at least these Git variables: ‘push.default’,
+ ‘remote.pushDefault’, ‘branch.<branch>.pushRemote’,
+ ‘branch.<branch>.remote’, ‘branch.<branch>.merge’, and
+ ‘remote.<remote>.push’.
+
+
+File: magit.info, Node: Plain Patches, Next: Maildir Patches, Prev: Pushing, Up: Transferring
+
+7.5 Plain Patches
+=================
+
+‘W’ (‘magit-patch’)
+ This transient prefix command binds the following suffix commands
+ along with the appropriate infix arguments and displays them in a
+ temporary buffer until a suffix is invoked.
+
+‘W c’ (‘magit-patch-create’)
+ This command creates patches for a set commits. If the region
+ marks several commits, then it creates patches for all of them.
+ Otherwise it functions as a transient prefix command, which
+ features several infix arguments and binds itself as a suffix
+ command. When this command is invoked as a suffix of itself, then
+ it creates a patch using the specified infix arguments.
+
+‘w a’ (‘magit-patch-apply’)
+ This command applies a patch. This is a transient prefix command,
+ which features several infix arguments and binds itself as a suffix
+ command. When this command is invoked as a suffix of itself, then
+ it applies a patch using the specified infix arguments.
+
+‘W s’ (‘magit-patch-save’)
+ This command creates a patch from the current diff.
+
+ Inside ‘magit-diff-mode’ or ‘magit-revision-mode’ buffers, ‘C-x
+ C-w’ is also bound to this command.
+
+ It is also possible to save a plain patch file by using ‘C-x C-w’
+inside a ‘magit-diff-mode’ or ‘magit-revision-mode’ buffer.
+
+
+File: magit.info, Node: Maildir Patches, Prev: Plain Patches, Up: Transferring
+
+7.6 Maildir Patches
+===================
+
+Also see *note (gitman)git-am::. and *note (gitman)git-apply::.
+
+‘w’ (‘magit-am’)
+ This transient prefix command binds the following suffix commands
+ along with the appropriate infix arguments and displays them in a
+ temporary buffer until a suffix is invoked.
+
+‘w w’ (‘magit-am-apply-patches’)
+ This command applies one or more patches. If the region marks
+ files, then those are applied as patches. Otherwise this command
+ reads a file-name in the minibuffer, defaulting to the file at
+ point.
+
+‘w m’ (‘magit-am-apply-maildir’)
+ This command applies patches from a maildir.
+
+‘w a’ (‘magit-patch-apply’)
+ This command applies a plain patch. For a longer description see
+ *note Plain Patches::. This command is only available from the
+ ‘magit-am’ transient for historic reasons.
+
+ When an "am" operation is in progress, then the transient instead
+features the following suffix commands.
+
+‘w w’ (‘magit-am-continue’)
+ This command resumes the current patch applying sequence.
+
+‘w s’ (‘magit-am-skip’)
+ This command skips the stopped at patch during a patch applying
+ sequence.
+
+‘w a’ (‘magit-am-abort’)
+ This command aborts the current patch applying sequence. This
+ discards all changes made since the sequence started.
+
+
+File: magit.info, Node: Miscellaneous, Next: Customizing, Prev: Transferring, Up: Top
+
+8 Miscellaneous
+***************
+
+* Menu:
+
+* Tagging::
+* Notes::
+* Submodules::
+* Subtree::
+* Worktree::
+* Sparse checkouts::
+* Bundle::
+* Common Commands::
+* Wip Modes::
+* Commands for Buffers Visiting Files::
+* Minor Mode for Buffers Visiting Blobs::
+
+
+File: magit.info, Node: Tagging, Next: Notes, Up: Miscellaneous
+
+8.1 Tagging
+===========
+
+Also see *note (gitman)git-tag::.
+
+‘t’ (‘magit-tag’)
+ This transient prefix command binds the following suffix commands
+ along with the appropriate infix arguments and displays them in a
+ temporary buffer until a suffix is invoked.
+
+‘t t’ (‘magit-tag-create’)
+ This command creates a new tag with the given NAME at REV. With a
+ prefix argument it creates an annotated tag.
+
+‘t r’ (‘magit-tag-release’)
+ This commands creates a release tag. It assumes that release tags
+ match ‘magit-release-tag-regexp’.
+
+ First it prompts for the name of the new tag using the highest
+ existing tag as initial input and leaving it to the user to
+ increment the desired part of the version string. If you use
+ unconventional release tags or version numbers (e.g.,
+ ‘v1.2.3-custom.1’), you can set the ‘magit-release-tag-regexp’ and
+ ‘magit-tag-version-regexp-alist’ variables.
+
+ If ‘--annotate’ is enabled then it prompts for the message of the
+ new tag. The proposed tag message is based on the message of the
+ highest tag, provided that that contains the corresponding version
+ string and substituting the new version string for that. Otherwise
+ it proposes something like "Foo-Bar 1.2.3", given, for example, a
+ TAG "v1.2.3" and a repository located at something like
+ "/path/to/foo-bar".
+
+‘t k’ (‘magit-tag-delete’)
+ This command deletes one or more tags. If the region marks
+ multiple tags (and nothing else), then it offers to delete those.
+ Otherwise, it prompts for a single tag to be deleted, defaulting to
+ the tag at point.
+
+‘t p’ (‘magit-tag-prune’)
+ This command offers to delete tags missing locally from REMOTE, and
+ vice versa.
+
+
+File: magit.info, Node: Notes, Next: Submodules, Prev: Tagging, Up: Miscellaneous
+
+8.2 Notes
+=========
+
+Also see *note (gitman)git-notes::.
+
+‘T’ (‘magit-notes’)
+ This transient prefix command binds the following suffix commands
+ along with the appropriate infix arguments and displays them in a
+ temporary buffer until a suffix is invoked.
+
+‘T T’ (‘magit-notes-edit’)
+ Edit the note attached to a commit, defaulting to the commit at
+ point.
+
+ By default use the value of Git variable ‘core.notesRef’ or
+ "refs/notes/commits" if that is undefined.
+
+‘T r’ (‘magit-notes-remove’)
+ Remove the note attached to a commit, defaulting to the commit at
+ point.
+
+ By default use the value of Git variable ‘core.notesRef’ or
+ "refs/notes/commits" if that is undefined.
+
+‘T p’ (‘magit-notes-prune’)
+ Remove notes about unreachable commits.
+
+ It is possible to merge one note ref into another. That may result
+in conflicts which have to resolved in the temporary worktree
+".git/NOTES_MERGE_WORKTREE".
+
+‘T m’ (‘magit-notes-merge’)
+ Merge the notes of a ref read from the user into the current notes
+ ref. The current notes ref is the value of Git variable
+ ‘core.notesRef’ or "refs/notes/commits" if that is undefined.
+
+ When a notes merge is in progress then the transient features the
+following suffix commands, instead of those listed above.
+
+‘T c’ (‘magit-notes-merge-commit’)
+ Commit the current notes ref merge, after manually resolving
+ conflicts.
+
+‘T a’ (‘magit-notes-merge-abort’)
+ Abort the current notes ref merge.
+
+ The following variables control what notes reference ‘magit-notes-*’,
+‘git notes’ and ‘git show’ act on and display. Both the local and
+global values are displayed and can be modified.
+
+ -- Variable: core.notesRef
+ This variable specifies the notes ref that is displayed by default
+ and which commands act on by default.
+
+ -- Variable: notes.displayRef
+ This variable specifies additional notes ref to be displayed in
+ addition to the ref specified by ‘core.notesRef’. It can have
+ multiple values and may end with ‘*’ to display all refs in the
+ ‘refs/notes/’ namespace (or ‘**’ if some names contain slashes).
+
+
+File: magit.info, Node: Submodules, Next: Subtree, Prev: Notes, Up: Miscellaneous
+
+8.3 Submodules
+==============
+
+Also see *note (gitman)git-submodule::.
+
+* Menu:
+
+* Listing Submodules::
+* Submodule Transient::
+
+
+File: magit.info, Node: Listing Submodules, Next: Submodule Transient, Up: Submodules
+
+8.3.1 Listing Submodules
+------------------------
+
+The command ‘magit-list-submodules’ displays a list of the current
+repository’s submodules in a separate buffer. It’s also possible to
+display information about submodules directly in the status buffer of
+the super-repository by adding ‘magit-insert-modules’ to the hook
+‘magit-status-sections-hook’ as described in *note Status Module
+Sections::.
+
+ -- Command: magit-list-submodules
+ This command displays a list of the current repository’s submodules
+ in a separate buffer.
+
+ It can be invoked by pressing ‘RET’ on the section titled
+ "Modules".
+
+ -- User Option: magit-submodule-list-columns
+ This option controls what columns are displayed by the command
+ ‘magit-list-submodules’ and how they are displayed.
+
+ Each element has the form ‘(HEADER WIDTH FORMAT PROPS)’.
+
+ HEADER is the string displayed in the header. WIDTH is the width
+ of the column. FORMAT is a function that is called with one
+ argument, the repository identification (usually its basename), and
+ with ‘default-directory’ bound to the toplevel of its working tree.
+ It has to return a string to be inserted or nil. PROPS is an alist
+ that supports the keys ‘:right-align’, ‘:pad-right’ and ‘:sort’.
+
+ The ‘:sort’ function has a weird interface described in the
+ docstring of ‘tabulated-list--get-sort’. Alternatively ‘<’ and
+ ‘magit-repolist-version<’ can be used as those functions are
+ automatically replaced with functions that satisfy the interface.
+ Set ‘:sort’ to ‘nil’ to inhibit sorting; if unspecifed, then the
+ column is sortable using the default sorter.
+
+ You may wish to display a range of numeric columns using just one
+ character per column and without any padding between columns, in
+ which case you should use an appropriat HEADER, set WIDTH to 1, and
+ set ‘:pad-right’ to 9. ‘+’ is substituted for numbers higher than
+ 9.
+
+
+File: magit.info, Node: Submodule Transient, Prev: Listing Submodules, Up: Submodules
+
+8.3.2 Submodule Transient
+-------------------------
+
+‘o’ (‘magit-submodule’)
+ This transient prefix command binds the following suffix commands
+ along with the appropriate infix arguments and displays them in a
+ temporary buffer until a suffix is invoked.
+
+ Some of the below commands default to act on the modules that are
+selected using the region. For brevity their description talk about
+"the selected modules", but if no modules are selected, then they act on
+the current module instead, or if point isn’t on a module, then the read
+a single module to act on. With a prefix argument these commands ignore
+the selection and the current module and instead act on all suitable
+modules.
+
+‘o a’ (‘magit-submodule-add’)
+ This commands adds the repository at URL as a module. Optional
+ PATH is the path to the module relative to the root of the
+ super-project. If it is nil then the path is determined based on
+ URL.
+
+‘o r’ (‘magit-submodule-register’)
+ This command registers the selected modules by copying their urls
+ from ".gitmodules" to "$GIT_DIR/config". These values can then be
+ edited before running ‘magit-submodule-populate’. If you don’t
+ need to edit any urls, then use the latter directly.
+
+‘o p’ (‘magit-submodule-populate’)
+ This command creates the working directory or directories of the
+ selected modules, checking out the recorded commits.
+
+‘o u’ (‘magit-submodule-update’)
+ This command updates the selected modules checking out the recorded
+ commits.
+
+‘o s’ (‘magit-submodule-synchronize’)
+ This command synchronizes the urls of the selected modules, copying
+ the values from ".gitmodules" to the ".git/config" of the
+ super-project as well those of the modules.
+
+‘o d’ (‘magit-submodule-unpopulate’)
+ This command removes the working directory of the selected modules.
+
+‘o l’ (‘magit-list-submodules’)
+ This command displays a list of the current repository’s modules.
+
+‘o f’ (‘magit-fetch-modules’)
+ This command fetches all modules.
+
+ Option ‘magit-fetch-modules-jobs’ controls how many submodules are
+ being fetched in parallel. Also fetch the super-repository,
+ because ‘git fetch’ does not support not doing that. With a prefix
+ argument fetch all remotes.
+
+
+File: magit.info, Node: Subtree, Next: Worktree, Prev: Submodules, Up: Miscellaneous
+
+8.4 Subtree
+===========
+
+Also see *note (gitman)git-subtree::.
+
+‘O’ (‘magit-subtree’)
+ This transient prefix command binds the two sub-transients; one for
+ importing a subtree and one for exporting a subtree.
+
+‘O i’ (‘magit-subtree-import’)
+ This transient prefix command binds the following suffix commands
+ along with the appropriate infix arguments and displays them in a
+ temporary buffer until a suffix is invoked.
+
+ The suffixes of this command import subtrees.
+
+ If the ‘--prefix’ argument is set, then the suffix commands use
+ that prefix without prompting the user. If it is unset, then they
+ read the prefix in the minibuffer.
+
+‘O i a’ (‘magit-subtree-add’)
+ This command adds COMMIT from REPOSITORY as a new subtree at
+ PREFIX.
+
+‘O i c’ (‘magit-subtree-add-commit’)
+ This command add COMMIT as a new subtree at PREFIX.
+
+‘O i m’ (‘magit-subtree-merge’)
+ This command merges COMMIT into the PREFIX subtree.
+
+‘O i f’ (‘magit-subtree-pull’)
+ This command pulls COMMIT from REPOSITORY into the PREFIX subtree.
+
+‘O e’ (‘magit-subtree-export’)
+ This transient prefix command binds the following suffix commands
+ along with the appropriate infix arguments and displays them in a
+ temporary buffer until a suffix is invoked.
+
+ The suffixes of this command export subtrees.
+
+ If the ‘--prefix’ argument is set, then the suffix commands use
+ that prefix without prompting the user. If it is unset, then they
+ read the prefix in the minibuffer.
+
+‘O e p’ (‘magit-subtree-push’)
+ This command extract the history of the subtree PREFIX and pushes
+ it to REF on REPOSITORY.
+
+‘O e s’ (‘magit-subtree-split’)
+ This command extracts the history of the subtree PREFIX.
+
+
+File: magit.info, Node: Worktree, Next: Sparse checkouts, Prev: Subtree, Up: Miscellaneous
+
+8.5 Worktree
+============
+
+Also see *note (gitman)git-worktree::.
+
+‘Z’ (‘magit-worktree’)
+ This transient prefix command binds the following suffix commands
+ and displays them in a temporary buffer until a suffix is invoked.
+
+‘Z b’ (‘magit-worktree-checkout’)
+ Checkout BRANCH in a new worktree at PATH.
+
+‘Z c’ (‘magit-worktree-branch’)
+ Create a new BRANCH and check it out in a new worktree at PATH.
+
+‘Z m’ (‘magit-worktree-move’)
+ Move an existing worktree to a new PATH.
+
+‘Z k’ (‘magit-worktree-delete’)
+ Delete a worktree, defaulting to the worktree at point. The
+ primary worktree cannot be deleted.
+
+‘Z g’ (‘magit-worktree-status’)
+ Show the status for the worktree at point.
+
+ If there is no worktree at point, then read one in the minibuffer.
+ If the worktree at point is the one whose status is already being
+ displayed in the current buffer, then show it in Dired instead.
+
+
+File: magit.info, Node: Sparse checkouts, Next: Bundle, Prev: Worktree, Up: Miscellaneous
+
+8.6 Sparse checkouts
+====================
+
+Sparse checkouts provide a way to restrict the working tree to a subset
+of directories. See *note (gitman)git-sparse-checkout::.
+
+ *Warning*: Git introduced the ‘git sparse-checkout’ command in
+version 2.25 and still advertises it as experimental and subject to
+change. Magit’s interface should be considered the same. In
+particular, if Git introduces a backward incompatible change, Magit’s
+sparse checkout functionality may be updated in a way that requires a
+more recent Git version.
+
+‘>’ (‘magit-sparse-checkout’)
+ This transient prefix command binds the following suffix commands
+ and displays them in a temporary buffer until a suffix is invoked.
+
+‘> e’ (‘magit-sparse-checkout-enable’)
+ This command initializes a sparse checkout that includes only the
+ files in the top-level directory.
+
+ Note that ‘magit-sparse-checkout-set’ and
+ ‘magit-sparse-checkout-add’ automatically initialize a sparse
+ checkout if necessary. However, you may want to call
+ ‘magit-sparse-checkout-enable’ explicitly to re-initialize a sparse
+ checkout after calling ‘magit-sparse-checkout-disable’, to pass
+ additional arguments to ‘git sparse-checkout init’, or to execute
+ the initialization asynchronously.
+
+‘> s’ (‘magit-sparse-checkout-set’)
+ This command takes a list of directories and configures the sparse
+ checkout to include only files in those subdirectories. Any
+ previously included directories are excluded unless they are in the
+ provided list of directories.
+
+‘> a’ (‘magit-sparse-checkout-add’)
+ This command is like ‘magit-sparse-checkout-set’, but instead adds
+ the specified list of directories to the set of directories that is
+ already included in the sparse checkout.
+
+‘> r’ (‘magit-sparse-checkout-reapply’)
+ This command applies the currently configured sparse checkout
+ patterns to the working tree. This is useful to call if excluded
+ files have been checked out after operations such as merging or
+ rebasing.
+
+‘> d’ (‘magit-sparse-checkout-disable’)
+ This command restores the full checkout. To return to the previous
+ sparse checkout, call ‘magit-sparse-checkout-enable’.
+
+ A sparse checkout can also be initiated when cloning a repository by
+using the ‘magit-clone-sparse’ command in the ‘magit-clone’ transient
+(see *note Cloning Repository::).
+
+ If you want the status buffer to indicate when a sparse checkout is
+enabled, add the function ‘magit-sparse-checkout-insert-header’ to
+‘magit-status-headers-hook’.
+
+
+File: magit.info, Node: Bundle, Next: Common Commands, Prev: Sparse checkouts, Up: Miscellaneous
+
+8.7 Bundle
+==========
+
+Also see *note (gitman)git-bundle::.
+
+ -- Command: magit-bundle
+ This transient prefix command binds several suffix commands for
+ running ‘git bundle’ subcommands and displays them in a temporary
+ buffer until a suffix is invoked.
+
+
+File: magit.info, Node: Common Commands, Next: Wip Modes, Prev: Bundle, Up: Miscellaneous
+
+8.8 Common Commands
+===================
+
+ -- Command: magit-switch-to-repository-buffer
+ -- Command: magit-switch-to-repository-buffer-other-window
+ -- Command: magit-switch-to-repository-buffer-other-frame
+ -- Command: magit-display-repository-buffer
+ These commands read any existing Magit buffer that belongs to the
+ current repository from the user and then switch to the selected
+ buffer (without refreshing it).
+
+ The last variant uses ‘magit-display-buffer’ to do so and thus
+ respects ‘magit-display-buffer-function’.
+
+ These are some of the commands that can be used in all buffers whose
+major-modes derive from ‘magit-mode’. There are other common commands
+beside the ones below, but these didn’t fit well anywhere else.
+
+‘C-w’ (‘magit-copy-section-value’)
+ This command saves the value of the current section to the
+ ‘kill-ring’, and, provided that the current section is a commit,
+ branch, or tag section, it also pushes the (referenced) revision to
+ the ‘magit-revision-stack’.
+
+ When the current section is a branch or a tag, and a prefix
+ argument is used, then it saves the revision at its tip to the
+ ‘kill-ring’ instead of the reference name.
+
+ When the region is active, this command saves that to the
+ ‘kill-ring’, like ‘kill-ring-save’ would, instead of behaving as
+ described above. If a prefix argument is used and the region is
+ within a hunk, then it strips the diff marker column and keeps only
+ either the added or removed lines, depending on the sign of the
+ prefix argument.
+
+‘M-w’ (‘magit-copy-buffer-revision’)
+ This command saves the revision being displayed in the current
+ buffer to the ‘kill-ring’ and also pushes it to the
+ ‘magit-revision-stack’. It is mainly intended for use in
+ ‘magit-revision-mode’ buffers, the only buffers where it is always
+ unambiguous exactly which revision should be saved.
+
+ Most other Magit buffers usually show more than one revision, in
+ some way or another, so this command has to select one of them, and
+ that choice might not always be the one you think would have been
+ the best pick.
+
+ Outside of Magit ‘M-w’ and ‘C-w’ are usually bound to
+‘kill-ring-save’ and ‘kill-region’, and these commands would also be
+useful in Magit buffers. Therefore when the region is active, then both
+of these commands behave like ‘kill-ring-save’ instead of as described
+above.
+
+
+File: magit.info, Node: Wip Modes, Next: Commands for Buffers Visiting Files, Prev: Common Commands, Up: Miscellaneous
+
+8.9 Wip Modes
+=============
+
+Git keeps *committed* changes around long enough for users to recover
+changes they have accidentally deleted. It does so by not garbage
+collecting any committed but no longer referenced objects for a certain
+period of time, by default 30 days.
+
+ But Git does *not* keep track of *uncommitted* changes in the working
+tree and not even the index (the staging area). Because Magit makes it
+so convenient to modify uncommitted changes, it also makes it easy to
+shoot yourself in the foot in the process.
+
+ For that reason Magit provides a global mode that saves *tracked*
+files to work-in-progress references after or before certain actions.
+(At present untracked files are never saved and for technical reasons
+nothing is saved before the first commit has been created).
+
+ Two separate work-in-progress references are used to track the state
+of the index and of the working tree: ‘refs/wip/index/<branchref>’ and
+‘refs/wip/wtree/<branchref>’, where ‘<branchref>’ is the full ref of the
+current branch, e.g. ‘refs/heads/master’. When the ‘HEAD’ is detached
+then ‘HEAD’ is used in place of ‘<branchref>’.
+
+ Checking out another branch (or detaching ‘HEAD’) causes the use of
+different wip refs for subsequent changes.
+
+ -- User Option: magit-wip-mode
+ When this mode is enabled, then uncommitted changes are committed
+ to dedicated work-in-progress refs whenever appropriate (i.e. when
+ dataloss would be a possibility otherwise).
+
+ Setting this variable directly does not take effect; either use the
+ Custom interface to do so or call the respective mode function.
+
+ For historic reasons this mode is implemented on top of four other
+ ‘magit-wip-*’ modes, which can also be used individually, if you
+ want finer control over when the wip refs are updated; but that is
+ discouraged. See *note Legacy Wip Modes::.
+
+ To view the log for a branch and its wip refs use the commands
+‘magit-wip-log’ and ‘magit-wip-log-current’. You should use ‘--graph’
+when using these commands.
+
+ -- Command: magit-wip-log
+ This command shows the log for a branch and its wip refs. With a
+ negative prefix argument only the worktree wip ref is shown.
+
+ The absolute numeric value of the prefix argument controls how many
+ "branches" of each wip ref are shown. This is only relevant if the
+ value of ‘magit-wip-merge-branch’ is ‘nil’.
+
+ -- Command: magit-wip-log-current
+ This command shows the log for the current branch and its wip refs.
+ With a negative prefix argument only the worktree wip ref is shown.
+
+ The absolute numeric value of the prefix argument controls how many
+ "branches" of each wip ref are shown. This is only relevant if the
+ value of ‘magit-wip-merge-branch’ is ‘nil’.
+
+‘X w’ (‘magit-reset-worktree’)
+ This command resets the working tree to some commit read from the
+ user and defaulting to the commit at point, while keeping the
+ ‘HEAD’ and index as-is.
+
+ This can be used to restore files to the state committed to a wip
+ ref. Note that this will discard any unstaged changes that might
+ have existed before invoking this command (but of course only after
+ committing that to the working tree wip ref).
+
+ Note that even if you enable ‘magit-wip-mode’ this won’t give you
+perfect protection. The most likely scenario for losing changes despite
+the use of ‘magit-wip-mode’ is making a change outside Emacs and then
+destroying it also outside Emacs. In some such a scenario, Magit, being
+an Emacs package, didn’t get the opportunity to keep you from shooting
+yourself in the foot.
+
+ When you are unsure whether Magit did commit a change to the wip
+refs, then you can explicitly request that all changes to all tracked
+files are being committed.
+
+‘M-x magit-wip-commit’
+ This command commits all changes to all tracked files to the index
+ and working tree work-in-progress refs. Like the modes described
+ above, it does not commit untracked files, but it does check all
+ tracked files for changes. Use this command when you suspect that
+ the modes might have overlooked a change made outside Emacs/Magit.
+
+ -- User Option: magit-wip-namespace
+ The namespace used for work-in-progress refs. It has to end with a
+ slash. The wip refs are named ‘<namespace>index/<branchref>’ and
+ ‘<namespace>wtree/<branchref>’. When snapshots are created while
+ the ‘HEAD’ is detached then ‘HEAD’ is used in place of
+ ‘<branchref>’.
+
+ -- User Option: magit-wip-mode-lighter
+ Mode-line lighter for ‘magit-wip--mode’.
+
+* Menu:
+
+* Wip Graph::
+* Legacy Wip Modes::
+
+
+File: magit.info, Node: Wip Graph, Next: Legacy Wip Modes, Up: Wip Modes
+
+8.9.1 Wip Graph
+---------------
+
+ -- User Option: magit-wip-merge-branch
+ This option controls whether the current branch is merged into the
+ wip refs after a new commit was created on the branch.
+
+ If non-nil and the current branch has new commits, then it is
+ merged into the wip ref before creating a new wip commit. This
+ makes it easier to inspect wip history and the wip commits are
+ never garbage collected.
+
+ If nil and the current branch has new commits, then the wip ref is
+ reset to the tip of the branch before creating a new wip commit.
+ With this setting wip commits are eventually garbage collected.
+
+ When ‘magit-wip-merge-branch’ is ‘t’, then the history looks like
+this:
+
+ *--*--*--*--*--* refs/wip/index/refs/heads/master
+ / / /
+ A-----B-----C refs/heads/master
+
+ When ‘magit-wip-merge-branch’ is ‘nil’, then creating a commit on the
+real branch and then making a change causes the wip refs to be recreated
+to fork from the new commit. But the old commits on the wip refs are
+not lost. They are still available from the reflog. To make it easier
+to see when the fork point of a wip ref was changed, an additional
+commit with the message "restart autosaving" is created on it (‘xxO’
+commits below are such boundary commits).
+
+ Starting with
+
+ BI0---BI1 refs/wip/index/refs/heads/master
+ /
+ A---B refs/heads/master
+ \
+ BW0---BW1 refs/wip/wtree/refs/heads/master
+
+ and committing the staged changes and editing and saving a file would
+result in
+
+ BI0---BI1 refs/wip/index/refs/heads/master
+ /
+ A---B---C refs/heads/master
+ \ \
+ \ CW0---CW1 refs/wip/wtree/refs/heads/master
+ \
+ BW0---BW1 refs/wip/wtree/refs/heads/master@{2}
+
+ The fork-point of the index wip ref is not changed until some change
+is being staged. Likewise just checking out a branch or creating a
+commit does not change the fork-point of the working tree wip ref. The
+fork-points are not adjusted until there actually is a change that
+should be committed to the respective wip ref.
+
+
+File: magit.info, Node: Legacy Wip Modes, Prev: Wip Graph, Up: Wip Modes
+
+8.9.2 Legacy Wip Modes
+----------------------
+
+It is recommended that you use the mode ‘magit-wip-mode’ (which see) and
+ignore the existence of the following modes, which are preserved for
+historic reasons.
+
+ Setting the following variables directly does not take effect; either
+use the Custom interface to do so or call the respective mode functions.
+
+ -- User Option: magit-wip-after-save-mode
+ When this mode is enabled, then saving a buffer that visits a file
+ tracked in a Git repository causes its current state to be
+ committed to the working tree wip ref for the current branch.
+
+ -- User Option: magit-wip-after-apply-mode
+ When this mode is enabled, then applying (i.e. staging, unstaging,
+ discarding, reversing, and regularly applying) a change to a file
+ tracked in a Git repository causes its current state to be
+ committed to the index and/or working tree wip refs for the current
+ branch.
+
+ If you only ever edit files using Emacs and only ever interact with
+Git using Magit, then the above two modes should be enough to protect
+each and every change from accidental loss. In practice nobody does
+that. Two additional modes exists that do commit to the wip refs before
+making changes that could cause the loss of earlier changes.
+
+ -- User Option: magit-wip-before-change-mode
+ When this mode is enabled, then certain commands commit the
+ existing changes to the files they are about to make changes to.
+
+ -- User Option: magit-wip-initial-backup-mode
+ When this mode is enabled, then the current version of a file is
+ committed to the worktree wip ref before the buffer visiting that
+ file is saved for the first time since the buffer was created.
+
+ This backs up the same version of the file that ‘backup-buffer’
+ would save. While ‘backup-buffer’ uses a backup file, this mode
+ uses the same worktree wip ref as used by the other Magit Wip
+ modes. Like ‘backup-buffer’, it only does this once; unless you
+ kill the buffer and visit the file again only one backup will be
+ created per Emacs session.
+
+ This mode ignores the variables that affect ‘backup-buffer’ and can
+ be used along-side that function, which is recommended because it
+ only backs up files that are tracked in a Git repository.
+
+ -- User Option: magit-wip-after-save-local-mode-lighter
+ Mode-line lighter for ‘magit-wip-after-save-local-mode’.
+
+ -- User Option: magit-wip-after-apply-mode-lighter
+ Mode-line lighter for ‘magit-wip-after-apply-mode’.
+
+ -- User Option: magit-wip-before-change-mode-lighter
+ Mode-line lighter for ‘magit-wip-before-change-mode’.
+
+ -- User Option: magit-wip-initial-backup-mode-lighter
+ Mode-line lighter for ‘magit-wip-initial-backup-mode’.
+
+
+File: magit.info, Node: Commands for Buffers Visiting Files, Next: Minor Mode for Buffers Visiting Blobs, Prev: Wip Modes, Up: Miscellaneous
+
+8.10 Commands for Buffers Visiting Files
+========================================
+
+Magit defines a few global key bindings unless the user sets
+‘magit-define-global-key-bindings’ to ‘nil’. This includes binding ‘C-c
+M-g’ to ‘magit-file-dispatch’. ‘C-c g’ would be a much better binding
+but the ‘C-c <letter>’ namespace is reserved for users, meaning that
+packages are not allowed to use it. If you want to use ‘C-c g’, then
+you have to add that binding yourself. Also see *note Default
+Bindings:: and *note (elisp)Key Binding Conventions::.
+
+ If you want a better binding, you have to add it yourself:
+
+ (global-set-key (kbd "C-c g") 'magit-file-dispatch)
+
+ The key bindings shown below assume that you have not improved the
+binding for ‘magit-file-dispatch’.
+
+‘C-c M-g’ (‘magit-file-dispatch’)
+ This transient prefix command binds the following suffix commands
+ and displays them in a temporary buffer until a suffix is invoked.
+
+ When invoked in a buffer that does not visit a file, then it falls
+ back to regular ‘magit-dispatch’.
+
+‘C-c M-g s’ (‘magit-stage-file’)
+ Stage all changes to the file being visited in the current buffer.
+
+‘C-c M-g u’ (‘magit-unstage-file’)
+ Unstage all changes to the file being visited in the current
+ buffer.
+
+‘C-c M-g c’ (‘magit-commit’)
+ This transient prefix command binds the following suffix commands
+ along with the appropriate infix arguments and displays them in a
+ temporary buffer until a suffix is invoked. See *note Initiating a
+ Commit::.
+
+‘C-c M-g D’ (‘magit-diff’)
+ This transient prefix command binds several diff suffix commands
+ and infix arguments and displays them in a temporary buffer until a
+ suffix is invoked. See *note Diffing::.
+
+ This is the same command that ‘d’ is bound to in Magit buffers. If
+ this command is invoked from a file-visiting buffer, then the
+ initial value of the option (‘--’) that limits the diff to certain
+ file(s) is set to the visited file.
+
+‘C-c M-g d’ (‘magit-diff-buffer-file’)
+ This command shows the diff for the file of blob that the current
+ buffer visits.
+
+ -- User Option: magit-diff-buffer-file-locked
+ This option controls whether ‘magit-diff-buffer-file’ uses a
+ dedicated buffer. See *note Modes and Buffers::.
+
+‘C-c M-g L’ (‘magit-log’)
+ This transient prefix command binds several log suffix commands and
+ infix arguments and displays them in a temporary buffer until a
+ suffix is invoked. See *note Logging::.
+
+ This is the same command that ‘l’ is bound to in Magit buffers. If
+ this command is invoked from a file-visiting buffer, then the
+ initial value of the option (‘--’) that limits the log to certain
+ file(s) is set to the visited file.
+
+‘C-c M-g l’ (‘magit-log-buffer-file’)
+ This command shows the log for the file of blob that the current
+ buffer visits. Renames are followed when a prefix argument is used
+ or when ‘--follow’ is an active log argument. When the region is
+ active, the log is restricted to the selected line range.
+
+‘C-c M-g t’ (‘magit-log-trace-definition’)
+ This command shows the log for the definition at point.
+
+ -- User Option: magit-log-buffer-file-locked
+ This option controls whether ‘magit-log-buffer-file’ uses a
+ dedicated buffer. See *note Modes and Buffers::.
+
+‘C-c M-g B’ (‘magit-blame’)
+ This transient prefix command binds all blaming suffix commands
+ along with the appropriate infix arguments and displays them in a
+ temporary buffer until a suffix is invoked.
+
+ For more information about this and the following commands also see
+ *note Blaming::.
+
+ In addition to the ‘magit-blame’ sub-transient, the dispatch
+transient also binds several blaming suffix commands directly. See
+*note Blaming:: for information about those commands and bindings.
+
+‘C-c M-g e’ (‘magit-edit-line-commit’)
+ This command makes the commit editable that added the current line.
+
+ With a prefix argument it makes the commit editable that removes
+ the line, if any. The commit is determined using ‘git blame’ and
+ made editable using ‘git rebase --interactive’ if it is reachable
+ from ‘HEAD’, or by checking out the commit (or a branch that points
+ at it) otherwise.
+
+‘C-c M-g p’ (‘magit-blob-previous’)
+ Visit the previous blob which modified the current file.
+
+ There are a few additional commands that operate on a single file but
+are not enabled in the file transient command by default:
+
+ -- Command: magit-file-rename
+ This command renames a file read from the user.
+
+ -- Command: magit-file-delete
+ This command deletes a file read from the user.
+
+ -- Command: magit-file-untrack
+ This command untracks a file read from the user.
+
+ -- Command: magit-file-checkout
+ This command updates a file in the working tree and index to the
+ contents from a revision. Both the revision and file are read from
+ the user.
+
+ To enable them invoke the transient (‘C-c M-g’), enter "edit mode"
+(‘C-x l’), set the "transient level" (‘C-x l’ again), enter ‘5’, and
+leave edit mode (‘C-g’). Also see *note (transient)Enabling and
+Disabling Suffixes::.
+
+
+File: magit.info, Node: Minor Mode for Buffers Visiting Blobs, Prev: Commands for Buffers Visiting Files, Up: Miscellaneous
+
+8.11 Minor Mode for Buffers Visiting Blobs
+==========================================
+
+The ‘magit-blob-mode’ enables certain Magit features in blob-visiting
+buffers. Such buffers can be created using ‘magit-find-file’ and some
+of the commands mentioned below, which also take care of turning on this
+minor mode. Currently this mode only establishes a few key bindings,
+but this might be extended.
+
+‘p’ (‘magit-blob-previous’)
+ Visit the previous blob which modified the current file.
+
+‘n’ (‘magit-blob-next’)
+ Visit the next blob which modified the current file.
+
+‘q’ (‘magit-kill-this-buffer’)
+ Kill the current buffer.
+
+
+File: magit.info, Node: Customizing, Next: Plumbing, Prev: Miscellaneous, Up: Top
+
+9 Customizing
+*************
+
+Both Git and Emacs are highly customizable. Magit is both a Git
+porcelain as well as an Emacs package, so it makes sense to customize it
+using both Git variables as well as Emacs options. However this
+flexibility doesn’t come without problems, including but not limited to
+the following.
+
+ • Some Git variables automatically have an effect in Magit without
+ requiring any explicit support. Sometimes that is desirable - in
+ other cases, it breaks Magit.
+
+ When a certain Git setting breaks Magit but you want to keep using
+ that setting on the command line, then that can be accomplished by
+ overriding the value for Magit only by appending something like
+ ‘("-c" "some.variable=compatible-value")’ to
+ ‘magit-git-global-arguments’.
+
+ • Certain settings like ‘fetch.prune=true’ are respected by Magit
+ commands (because they simply call the respective Git command) but
+ their value is not reflected in the respective transient buffers.
+ In this case the ‘--prune’ argument in ‘magit-fetch’ might be
+ active or inactive, but that doesn’t keep the Git variable from
+ being honored by the suffix commands anyway. So pruning might
+ happen despite the ‘--prune’ arguments being displayed in a way
+ that seems to indicate that no pruning will happen.
+
+ I intend to address these and similar issues in a future release.
+
+* Menu:
+
+* Per-Repository Configuration::
+* Essential Settings::
+
+
+File: magit.info, Node: Per-Repository Configuration, Next: Essential Settings, Up: Customizing
+
+9.1 Per-Repository Configuration
+================================
+
+Magit can be configured on a per-repository level using both Git
+variables as well as Emacs options.
+
+ To set a Git variable for one repository only, simply set it in
+‘/path/to/repo/.git/config’ instead of ‘$HOME/.gitconfig’ or
+‘/etc/gitconfig’. See *note (gitman)git-config::.
+
+ Similarly, Emacs options can be set for one repository only by
+editing ‘/path/to/repo/.dir-locals.el’. See *note (emacs)Directory
+Variables::. For example to disable automatic refreshes of
+file-visiting buffers in just one huge repository use this:
+
+ • ‘/path/to/huge/repo/.dir-locals.el’
+
+ ((nil . ((magit-refresh-buffers . nil))))
+
+ It might only be costly to insert certain information into Magit
+buffers for repositories that are exceptionally large, in which case you
+can disable the respective section inserters just for that repository:
+
+ • ‘/path/to/tag/invested/repo/.dir-locals.el’
+
+ ((magit-status-mode
+ . ((eval . (magit-disable-section-inserter 'magit-insert-tags-header)))))
+
+ -- Function: magit-disable-section-inserter fn
+ This function disables the section inserter FN in the current
+ repository. It is only intended for use in ‘.dir-locals.el’ and
+ ‘.dir-locals-2.el’.
+
+ If you want to apply the same settings to several, but not all,
+repositories then keeping the repository-local config files in sync
+would quickly become annoying. To avoid that you can create config
+files for certain classes of repositories (e.g. "huge repositories")
+and then include those files in the per-repository config files. For
+example:
+
+ • ‘/path/to/huge/repo/.git/config’
+
+ [include]
+ path = /path/to/huge-gitconfig
+
+ • ‘/path/to/huge-gitconfig’
+
+ [status]
+ showUntrackedFiles = no
+
+ • ‘$HOME/.emacs.d/init.el’
+
+ (dir-locals-set-class-variables 'huge-git-repository
+ '((nil . ((magit-refresh-buffers . nil)))))
+
+ (dir-locals-set-directory-class
+ "/path/to/huge/repo/" 'huge-git-repository)
+
+
+File: magit.info, Node: Essential Settings, Prev: Per-Repository Configuration, Up: Customizing
+
+9.2 Essential Settings
+======================
+
+The next two sections list and discuss several variables that many users
+might want to customize, for safety and/or performance reasons.
+
+* Menu:
+
+* Safety::
+* Performance::
+* Default Bindings::
+
+
+File: magit.info, Node: Safety, Next: Performance, Up: Essential Settings
+
+9.2.1 Safety
+------------
+
+This section discusses various variables that you might want to change
+(or *not* change) for safety reasons.
+
+ Git keeps *committed* changes around long enough for users to recover
+changes they have accidentally been deleted. It does not do the same
+for *uncommitted* changes in the working tree and not even the index
+(the staging area). Because Magit makes it so easy to modify
+uncommitted changes, it also makes it easy to shoot yourself in the foot
+in the process. For that reason Magit provides three global modes that
+save *tracked* files to work-in-progress references after or before
+certain actions. See *note Wip Modes::.
+
+ These modes are not enabled by default because of performance
+concerns. Instead a lot of potentially destructive commands require
+confirmation every time they are used. In many cases this can be
+disabled by adding a symbol to ‘magit-no-confirm’ (see *note Completion
+and Confirmation::). If you enable the various wip modes then you
+should add ‘safe-with-wip’ to this list.
+
+ Similarly it isn’t necessary to require confirmation before moving a
+file to the system trash - if you trashed a file by mistake then you can
+recover it from there. Option ‘magit-delete-by-moving-to-trash’
+controls whether the system trash is used, which is the case by default.
+Nevertheless, ‘trash’ isn’t a member of ‘magit-no-confirm’ - you might
+want to change that.
+
+ By default buffers visiting files are automatically reverted when the
+visited file changes on disk. This isn’t as risky as it might seem, but
+to make an informed decision you should see *note Risk of Reverting
+Automatically::.
+
+
+File: magit.info, Node: Performance, Next: Default Bindings, Prev: Safety, Up: Essential Settings
+
+9.2.2 Performance
+-----------------
+
+After Magit has run ‘git’ for side-effects, it also refreshes the
+current Magit buffer and the respective status buffer. This is
+necessary because otherwise outdated information might be displayed
+without the user noticing. Magit buffers are updated by recreating
+their content from scratch, which makes updating simpler and less
+error-prone, but also more costly. Keeping it simple and just
+re-creating everything from scratch is an old design decision and
+departing from that will require major refactoring.
+
+ I plan to do that in time for the next major release. I also intend
+to create logs and diffs asynchronously, which should also help a lot
+but also requires major refactoring.
+
+ Meanwhile you can tell Magit to only automatically refresh the
+current Magit buffer, but not the status buffer. If you do that, then
+the status buffer is only refreshed automatically if it is the current
+buffer.
+
+ (setq magit-refresh-status-buffer nil)
+
+ You should also check whether any third-party packages have added
+anything to ‘magit-refresh-buffer-hook’, ‘magit-status-refresh-hook’,
+‘magit-pre-refresh-hook’, and ‘magit-post-refresh-hook’. If so, then
+check whether those additions impact performance significantly.
+
+ Magit can be told to refresh buffers verbosely using ‘M-x
+magit-toggle-verbose-refresh’. Enabling this helps figuring out which
+sections are bottlenecks. The additional output can be found in the
+‘*Messages*’ buffer.
+
+ Magit also reverts buffers for visited files located inside the
+current repository when the visited file changes on disk. That is
+implemented on top of ‘auto-revert-mode’ from the built-in library
+‘autorevert’. To figure out whether that impacts performance, check
+whether performance is significantly worse, when many buffers exist
+and/or when some buffers visit files using TRAMP. If so, then this
+should help.
+
+ (setq auto-revert-buffer-list-filter
+ 'magit-auto-revert-repository-buffer-p)
+
+ For alternative approaches see *note Automatic Reverting of
+File-Visiting Buffers::.
+
+ If you have enabled any features that are disabled by default, then
+you should check whether they impact performance significantly. It’s
+likely that they were not enabled by default because it is known that
+they reduce performance at least in large repositories.
+
+ If performance is only slow inside certain unusually large
+repositories, then you might want to disable certain features on a
+per-repository or per-repository-class basis only. See *note
+Per-Repository Configuration::. For example it takes a long time to
+determine the next and current tag in repository with exceptional
+numbers of tags. It would therefore be a good idea to disable
+‘magit-insert-tags-headers’, as explained at the mentioned node.
+
+* Menu:
+
+* Microsoft Windows Performance::
+* MacOS Performance::
+
+Log Performance
+...............
+
+When showing logs, Magit limits the number of commits initially shown in
+the hope that this avoids unnecessary work. When using ‘--graph’ is
+used, then this unfortunately does not have the desired effect for large
+histories. Junio, Git’s maintainer, said on the git mailing list
+(<http://www.spinics.net/lists/git/msg232230.html>): "‘--graph’ wants to
+compute the whole history and the max-count only affects the output
+phase after ‘--graph’ does its computation".
+
+ In other words, it’s not that Git is slow at outputting the
+differences, or that Magit is slow at parsing the output - the problem
+is that Git first goes outside and has a smoke.
+
+ We actually work around this issue by limiting the number of commits
+not only by using ‘-<N>’ but by also using a range. But unfortunately
+that’s not always possible.
+
+ When more than a few thousand commits are shown, then the use of
+‘--graph’ can slow things down.
+
+ Using ‘--color --graph’ is even slower. Magit uses code that is part
+of Emacs to turn control characters into faces. That code is pretty
+slow and this is quite noticeable when showing a log with many branches
+and merges. For that reason ‘--color’ is not enabled by default
+anymore. Consider leaving it at that.
+
+Diff Performance
+................
+
+If diffs are slow, then consider turning off some optional diff features
+by setting all or some of the following variables to ‘nil’:
+‘magit-diff-highlight-indentation’, ‘magit-diff-highlight-trailing’,
+‘magit-diff-paint-whitespace’, ‘magit-diff-highlight-hunk-body’, and
+‘magit-diff-refine-hunk’.
+
+ When showing a commit instead of some arbitrary diff, then some
+additional information is displayed. Calculating this information can
+be quite expensive given certain circumstances. If looking at a commit
+using ‘magit-revision-mode’ takes considerably more time than looking at
+the same commit in ‘magit-diff-mode’, then consider setting
+‘magit-revision-insert-related-refs’ to ‘nil’.
+
+ When you are often confronted with diffs that contain deleted files,
+then you might want to enable the ‘--irreversible-delete’ argument. If
+you do that then diffs still show that a file was deleted but without
+also showing the complete deleted content of the file. This argument is
+not available by default, see *note (transient)Enabling and Disabling
+Suffixes::. Once you have done that you should enable it and save that
+setting, see *note (transient)Saving Values::. You should do this in
+both the diff (‘d’) and the diff refresh (‘D’) transient popups.
+
+Refs Buffer Performance
+.......................
+
+When refreshing the "references buffer" is slow, then that’s usually
+because several hundred refs are being displayed. The best way to
+address that is to display fewer refs, obviously.
+
+ If you are not, or only mildly, interested in seeing the list of
+tags, then start by not displaying them:
+
+ (remove-hook 'magit-refs-sections-hook 'magit-insert-tags)
+
+ Then you should also make sure that the listed remote branches
+actually all exist. You can do so by pruning branches which no longer
+exist using ‘f-pa’.
+
+Committing Performance
+......................
+
+When you initiate a commit, then Magit by default automatically shows a
+diff of the changes you are about to commit. For large commits this can
+take a long time, which is especially distracting when you are
+committing large amounts of generated data which you don’t actually
+intend to inspect before committing. This behavior can be turned off
+using:
+
+ (remove-hook 'server-switch-hook 'magit-commit-diff)
+
+ Then you can type ‘C-c C-d’ to show the diff when you actually want
+to see it, but only then. Alternatively you can leave the hook alone
+and just type ‘C-g’ in those cases when it takes too long to generate
+the diff. If you do that, then you will end up with a broken diff
+buffer, but doing it this way has the advantage that you usually get to
+see the diff, which is useful because it increases the odds that you
+spot potential issues.
+
+
+File: magit.info, Node: Microsoft Windows Performance, Next: MacOS Performance, Up: Performance
+
+Microsoft Windows Performance
+.............................
+
+In order to update the status buffer, ‘git’ has to be run a few dozen
+times. That is problematic on Microsoft Windows, because that operating
+system is exceptionally slow at starting processes. Sadly this is an
+issue that can only be fixed by Microsoft itself, and they don’t appear
+to be particularly interested in doing so.
+
+ Beside the subprocess issue, there are also other Windows-specific
+performance issues. Some of these have workarounds. The maintainers of
+"Git for Windows" try to improve performance on Windows. Always use the
+latest release in order to benefit from the latest performance tweaks.
+Magit too tries to work around some Windows-specific issues.
+
+ According to some sources, setting the following Git variables can
+also help.
+
+ git config --global core.preloadindex true # default since v2.1
+ git config --global core.fscache true # default since v2.8
+ git config --global gc.auto 256
+
+ You should also check whether an anti-virus program is affecting
+performance.
+
+
+File: magit.info, Node: MacOS Performance, Prev: Microsoft Windows Performance, Up: Performance
+
+MacOS Performance
+.................
+
+Before Emacs 26.1 child processes were created using ‘fork’ on macOS.
+That needlessly copied GUI resources, which is expensive. The result
+was that forking took about 30 times as long on Darwin than on Linux,
+and because Magit starts many ‘git’ processes that made quite a
+difference.
+
+ So make sure that you are using at least Emacs 26.1, in which case
+the faster ‘vfork’ will be used. (The creation of child processes still
+takes about twice as long on Darwin compared to Linux.) See (1) for
+more information.
+
+ ---------- Footnotes ----------
+
+ (1)
+<https://lists.gnu.org/archive/html/bug-gnu-emacs/2017-04/msg00201.html>
+
+
+File: magit.info, Node: Default Bindings, Prev: Performance, Up: Essential Settings
+
+9.2.3 Default Bindings
+----------------------
+
+ -- User Option: magit-define-global-key-bindings
+ This option controls whether some Magit commands are automatically
+ bound in the global keymap even before Magit is used for the first
+ time in the current session.
+
+ If this variable is non-nil, which it is by default, then the
+ following bindings may be added to the global keymap.
+
+ ‘C-x g’ ‘magit-status’
+ ‘C-x M-g’ ‘magit-dispatch’
+ ‘C-c M-g’ ‘magit-file-dispatch’
+
+ These bindings may be added when ‘after-init-hook’ is run. Each
+ binding is added if and only if at that time no other key is bound
+ to the same command and no other command is bound to the same key.
+ In other words we try to avoid adding bindings that are
+ unnecessary, as well as bindings that conflict with other bindings.
+
+ Adding the above bindings is delayed until ‘after-init-hook’ is
+ called to allow users to set the variable anywhere in their init
+ file (without having to make sure to do so before ‘magit’ is loaded
+ or autoloaded) and to increase the likelihood that all the
+ potentially conflicting user bindings have already been added.
+
+ To set this variable use either ‘setq’ or the Custom interface. Do
+ not use the function ‘customize-set-variable’ because doing that
+ would cause Magit to be loaded immediately when that form is
+ evaluated (this differs from ‘custom-set-variables’, which doesn’t
+ load the libraries that define the customized variables).
+
+ Setting this variable to nil has no effect if that is done after
+ the key bindings have already been added.
+
+ We recommend that you bind ‘C-c g’ instead of ‘C-c M-g’ to
+ ‘magit-file-dispatch’. The former is a much better binding but the
+ ‘C-c <letter>’ namespace is strictly reserved for users; preventing
+ Magit from using it by default.
+
+ (global-set-key (kbd "C-c g") 'magit-file-dispatch)
+
+ Also see *note Commands for Buffers Visiting Files:: and *note
+ (elisp)Key Binding Conventions::.
+
+
+File: magit.info, Node: Plumbing, Next: FAQ, Prev: Customizing, Up: Top
+
+10 Plumbing
+***********
+
+The following sections describe how to use several of Magit’s core
+abstractions to extend Magit itself or implement a separate extension.
+
+ A few of the low-level features used by Magit have been factored out
+into separate libraries/packages, so that they can be used by other
+packages, without having to depend on Magit. See *note
+(with-editor)Top:: for information about ‘with-editor’. ‘transient’
+doesn’t have a manual yet.
+
+ If you are trying to find an unused key that you can bind to a
+command provided by your own Magit extension, then checkout
+<https://github.com/magit/magit/wiki/Plugin-Dispatch-Key-Registry>.
+
+* Menu:
+
+* Calling Git::
+* Section Plumbing::
+* Refreshing Buffers::
+* Conventions::
+
+
+File: magit.info, Node: Calling Git, Next: Section Plumbing, Up: Plumbing
+
+10.1 Calling Git
+================
+
+Magit provides many specialized functions for calling Git. All of these
+functions are defined in either ‘magit-git.el’ or ‘magit-process.el’ and
+have one of the prefixes ‘magit-run-’, ‘magit-call-’, ‘magit-start-’, or
+‘magit-git-’ (which is also used for other things).
+
+ All of these functions accept an indefinite number of arguments,
+which are strings that specify command line arguments for Git (or in
+some cases an arbitrary executable). These arguments are flattened
+before being passed on to the executable; so instead of strings they can
+also be lists of strings and arguments that are ‘nil’ are silently
+dropped. Some of these functions also require a single mandatory
+argument before these command line arguments.
+
+ Roughly speaking, these functions run Git either to get some value or
+for side-effects. The functions that return a value are useful to
+collect the information necessary to populate a Magit buffer, while the
+others are used to implement Magit commands.
+
+ The functions in the value-only group always run synchronously, and
+they never trigger a refresh. The function in the side-effect group can
+be further divided into subgroups depending on whether they run Git
+synchronously or asynchronously, and depending on whether they trigger a
+refresh when the executable has finished.
+
+* Menu:
+
+* Getting a Value from Git::
+* Calling Git for Effect::
+
+
+File: magit.info, Node: Getting a Value from Git, Next: Calling Git for Effect, Up: Calling Git
+
+10.1.1 Getting a Value from Git
+-------------------------------
+
+These functions run Git in order to get a value, an exit status, or
+output. Of course you could also use them to run Git commands that have
+side-effects, but that should be avoided.
+
+ -- Function: magit-git-exit-code &rest args
+ Executes git with ARGS and returns its exit code.
+
+ -- Function: magit-git-success &rest args
+ Executes git with ARGS and returns ‘t’ if the exit code is ‘0’,
+ ‘nil’ otherwise.
+
+ -- Function: magit-git-failure &rest args
+ Executes git with ARGS and returns ‘t’ if the exit code is ‘1’,
+ ‘nil’ otherwise.
+
+ -- Function: magit-git-true &rest args
+ Executes git with ARGS and returns ‘t’ if the first line printed by
+ git is the string "true", ‘nil’ otherwise.
+
+ -- Function: magit-git-false &rest args
+ Executes git with ARGS and returns ‘t’ if the first line printed by
+ git is the string "false", ‘nil’ otherwise.
+
+ -- Function: magit-git-insert &rest args
+ Executes git with ARGS and inserts its output at point.
+
+ -- Function: magit-git-string &rest args
+ Executes git with ARGS and returns the first line of its output.
+ If there is no output or if it begins with a newline character,
+ then this returns ‘nil’.
+
+ -- Function: magit-git-lines &rest args
+ Executes git with ARGS and returns its output as a list of lines.
+ Empty lines anywhere in the output are omitted.
+
+ -- Function: magit-git-items &rest args
+ Executes git with ARGS and returns its null-separated output as a
+ list. Empty items anywhere in the output are omitted.
+
+ If the value of option ‘magit-git-debug’ is non-nil and git exits
+ with a non-zero exit status, then warn about that in the echo area
+ and add a section containing git’s standard error in the current
+ repository’s process buffer.
+
+ -- Function: magit-process-git destination &rest args
+ Calls Git synchronously in a separate process, returning its exit
+ code. DESTINATION specifies how to handle the output, like for
+ ‘call-process’, except that file handlers are supported. Enables
+ Cygwin’s "noglob" option during the call and ensures unix eol
+ conversion.
+
+ -- Function: magit-process-file process &optional infile buffer display
+ &rest args
+ Processes files synchronously in a separate process. Identical to
+ ‘process-file’ but temporarily enables Cygwin’s "noglob" option
+ during the call and ensures unix eol conversion.
+
+ If an error occurs when using one of the above functions, then that
+is usually due to a bug, i.e. using an argument which is not actually
+supported. Such errors are usually not reported, but when they occur we
+need to be able to debug them.
+
+ -- User Option: magit-git-debug
+ Whether to report errors that occur when using ‘magit-git-insert’,
+ ‘magit-git-string’, ‘magit-git-lines’, or ‘magit-git-items’. This
+ does not actually raise an error. Instead a message is shown in
+ the echo area, and git’s standard error is insert into a new
+ section in the current repository’s process buffer.
+
+ -- Function: magit-git-str &rest args
+ This is a variant of ‘magit-git-string’ that ignores the option
+ ‘magit-git-debug’. It is mainly intended to be used while handling
+ errors in functions that do respect that option. Using such a
+ function while handing an error could cause yet another error and
+ therefore lead to an infinite recursion. You probably won’t ever
+ need to use this function.
+
+
+File: magit.info, Node: Calling Git for Effect, Prev: Getting a Value from Git, Up: Calling Git
+
+10.1.2 Calling Git for Effect
+-----------------------------
+
+These functions are used to run git to produce some effect. Most Magit
+commands that actually run git do so by using such a function.
+
+ Because we do not need to consume git’s output when using these
+functions, their output is instead logged into a per-repository buffer,
+which can be shown using ‘$’ from a Magit buffer or ‘M-x magit-process’
+elsewhere.
+
+ These functions can have an effect in two distinct ways. Firstly,
+running git may change something, i.e. create or push a new commit.
+Secondly, that change may require that Magit buffers are refreshed to
+reflect the changed state of the repository. But refreshing isn’t
+always desirable, so only some of these functions do perform such a
+refresh after git has returned.
+
+ Sometimes it is useful to run git asynchronously. For example, when
+the user has just initiated a push, then there is no reason to make her
+wait until that has completed. In other cases it makes sense to wait
+for git to complete before letting the user do something else. For
+example after staging a change it is useful to wait until after the
+refresh because that also automatically moves to the next change.
+
+ -- Function: magit-call-git &rest args
+ Calls git synchronously with ARGS.
+
+ -- Function: magit-call-process program &rest args
+ Calls PROGRAM synchronously with ARGS.
+
+ -- Function: magit-run-git &rest args
+ Calls git synchronously with ARGS and then refreshes.
+
+ -- Function: magit-run-git-with-input &rest args
+ Calls git synchronously with ARGS and sends it the content of the
+ current buffer on standard input.
+
+ If the current buffer’s ‘default-directory’ is on a remote
+ filesystem, this function actually runs git asynchronously. But
+ then it waits for the process to return, so the function itself is
+ synchronous.
+
+ -- Function: magit-git &rest args
+ Calls git synchronously with ARGS for side-effects only. This
+ function does not refresh the buffer.
+
+ -- Function: magit-git-wash washer &rest args
+ Execute Git with ARGS, inserting washed output at point. Actually
+ first insert the raw output at point. If there is no output call
+ ‘magit-cancel-section’. Otherwise temporarily narrow the buffer to
+ the inserted text, move to its beginning, and then call function
+ WASHER with ARGS as its sole argument.
+
+ And now for the asynchronous variants.
+
+ -- Function: magit-run-git-async &rest args
+ Start Git, prepare for refresh, and return the process object.
+ ARGS is flattened and then used as arguments to Git.
+
+ Display the command line arguments in the echo area.
+
+ After Git returns some buffers are refreshed: the buffer that was
+ current when this function was called (if it is a Magit buffer and
+ still alive), as well as the respective Magit status buffer.
+ Unmodified buffers visiting files that are tracked in the current
+ repository are reverted if ‘magit-revert-buffers’ is non-nil.
+
+ -- Function: magit-run-git-with-editor &rest args
+ Export GIT_EDITOR and start Git. Also prepare for refresh and
+ return the process object. ARGS is flattened and then used as
+ arguments to Git.
+
+ Display the command line arguments in the echo area.
+
+ After Git returns some buffers are refreshed: the buffer that was
+ current when this function was called (if it is a Magit buffer and
+ still alive), as well as the respective Magit status buffer.
+
+ -- Function: magit-start-git input &rest args
+ Start Git, prepare for refresh, and return the process object.
+
+ If INPUT is non-nil, it has to be a buffer or the name of an
+ existing buffer. The buffer content becomes the processes standard
+ input.
+
+ Option ‘magit-git-executable’ specifies the Git executable and
+ option ‘magit-git-global-arguments’ specifies constant arguments.
+ The remaining arguments ARGS specify arguments to Git. They are
+ flattened before use.
+
+ After Git returns, some buffers are refreshed: the buffer that was
+ current when this function was called (if it is a Magit buffer and
+ still alive), as well as the respective Magit status buffer.
+ Unmodified buffers visiting files that are tracked in the current
+ repository are reverted if ‘magit-revert-buffers’ is non-nil.
+
+ -- Function: magit-start-process &rest args
+ Start PROGRAM, prepare for refresh, and return the process object.
+
+ If optional argument INPUT is non-nil, it has to be a buffer or the
+ name of an existing buffer. The buffer content becomes the
+ processes standard input.
+
+ The process is started using ‘start-file-process’ and then setup to
+ use the sentinel ‘magit-process-sentinel’ and the filter
+ ‘magit-process-filter’. Information required by these functions is
+ stored in the process object. When this function returns the
+ process has not started to run yet so it is possible to override
+ the sentinel and filter.
+
+ After the process returns, ‘magit-process-sentinel’ refreshes the
+ buffer that was current when ‘magit-start-process’ was called (if
+ it is a Magit buffer and still alive), as well as the respective
+ Magit status buffer. Unmodified buffers visiting files that are
+ tracked in the current repository are reverted if
+ ‘magit-revert-buffers’ is non-nil.
+
+ -- Variable: magit-this-process
+ The child process which is about to start. This can be used to
+ change the filter and sentinel.
+
+ -- Variable: magit-process-raise-error
+ When this is non-nil, then ‘magit-process-sentinel’ raises an error
+ if git exits with a non-zero exit status. For debugging purposes.
+
+
+File: magit.info, Node: Section Plumbing, Next: Refreshing Buffers, Prev: Calling Git, Up: Plumbing
+
+10.2 Section Plumbing
+=====================
+
+* Menu:
+
+* Creating Sections::
+* Section Selection::
+* Matching Sections::
+
+
+File: magit.info, Node: Creating Sections, Next: Section Selection, Up: Section Plumbing
+
+10.2.1 Creating Sections
+------------------------
+
+ -- Macro: magit-insert-section &rest args
+ Insert a section at point.
+
+ TYPE is the section type, a symbol. Many commands that act on the
+ current section behave differently depending on that type. Also if
+ a variable ‘magit-TYPE-section-map’ exists, then use that as the
+ text-property ‘keymap’ of all text belonging to the section (but
+ this may be overwritten in subsections). TYPE can also have the
+ form ‘(eval FORM)’ in which case FORM is evaluated at runtime.
+
+ Optional VALUE is the value of the section, usually a string that
+ is required when acting on the section.
+
+ When optional HIDE is non-nil collapse the section body by default,
+ i.e. when first creating the section, but not when refreshing the
+ buffer. Otherwise, expand it by default. This can be overwritten
+ using ‘magit-section-set-visibility-hook’. When a section is
+ recreated during a refresh, then the visibility of predecessor is
+ inherited and HIDE is ignored (but the hook is still honored).
+
+ BODY is any number of forms that actually insert the section’s
+ heading and body. Optional NAME, if specified, has to be a symbol,
+ which is then bound to the struct of the section being inserted.
+
+ Before BODY is evaluated the ‘start’ of the section object is set
+ to the value of ‘point’ and after BODY was evaluated its ‘end’ is
+ set to the new value of ‘point’; BODY is responsible for moving
+ ‘point’ forward.
+
+ If it turns out inside BODY that the section is empty, then
+ ‘magit-cancel-section’ can be used to abort and remove all traces
+ of the partially inserted section. This can happen when creating a
+ section by washing Git’s output and Git didn’t actually output
+ anything this time around.
+
+ -- Function: magit-insert-heading &rest args
+ Insert the heading for the section currently being inserted.
+
+ This function should only be used inside ‘magit-insert-section’.
+
+ When called without any arguments, then just set the ‘content’ slot
+ of the object representing the section being inserted to a marker
+ at ‘point’. The section should only contain a single line when
+ this function is used like this.
+
+ When called with arguments ARGS, which have to be strings, then
+ insert those strings at point. The section should not contain any
+ text before this happens and afterwards it should again only
+ contain a single line. If the ‘face’ property is set anywhere
+ inside any of these strings, then insert all of them unchanged.
+ Otherwise use the ‘magit-section-heading’ face for all inserted
+ text.
+
+ The ‘content’ property of the section struct is the end of the
+ heading (which lasts from ‘start’ to ‘content’) and the beginning
+ of the body (which lasts from ‘content’ to ‘end’). If the value of
+ ‘content’ is nil, then the section has no heading and its body
+ cannot be collapsed. If a section does have a heading then its
+ height must be exactly one line, including a trailing newline
+ character. This isn’t enforced; you are responsible for getting it
+ right. The only exception is that this function does insert a
+ newline character if necessary.
+
+ -- Function: magit-cancel-section
+ Cancel the section currently being inserted. This exits the
+ innermost call to ‘magit-insert-section’ and removes all traces of
+ what has already happened inside that call.
+
+ -- Function: magit-define-section-jumper sym title &optional value
+ Define an interactive function to go to section SYM. TITLE is the
+ displayed title of the section.
+
+
+File: magit.info, Node: Section Selection, Next: Matching Sections, Prev: Creating Sections, Up: Section Plumbing
+
+10.2.2 Section Selection
+------------------------
+
+ -- Function: magit-current-section
+ Return the section at point.
+
+ -- Function: magit-region-sections &optional condition multiple
+ Return a list of the selected sections.
+
+ When the region is active and constitutes a valid section
+ selection, then return a list of all selected sections. This is
+ the case when the region begins in the heading of a section and
+ ends in the heading of the same section or in that of a sibling
+ section. If optional MULTIPLE is non-nil, then the region cannot
+ begin and end in the same section.
+
+ When the selection is not valid, then return nil. In this case,
+ most commands that can act on the selected sections will instead
+ act on the section at point.
+
+ When the region looks like it would in any other buffer then the
+ selection is invalid. When the selection is valid then the region
+ uses the ‘magit-section-highlight’ face. This does not apply to
+ diffs where things get a bit more complicated, but even here if the
+ region looks like it usually does, then that’s not a valid
+ selection as far as this function is concerned.
+
+ If optional CONDITION is non-nil, then the selection not only has
+ to be valid; all selected sections additionally have to match
+ CONDITION, or nil is returned. See ‘magit-section-match’ for the
+ forms CONDITION can take.
+
+ -- Function: magit-region-values &optional condition multiple
+ Return a list of the values of the selected sections.
+
+ Return the values that themselves would be returned by
+ ‘magit-region-sections’ (which see).
+
+
+File: magit.info, Node: Matching Sections, Prev: Section Selection, Up: Section Plumbing
+
+10.2.3 Matching Sections
+------------------------
+
+‘M-x magit-describe-section-briefly’
+ Show information about the section at point. This command is
+ intended for debugging purposes.
+
+ -- Function: magit-section-ident section
+ Return an unique identifier for SECTION. The return value has the
+ form ‘((TYPE . VALUE)...)’.
+
+ -- Function: magit-get-section ident &optional root
+ Return the section identified by IDENT. IDENT has to be a list as
+ returned by ‘magit-section-ident’.
+
+ -- Function: magit-section-match condition &optional section
+ Return ‘t’ if SECTION matches CONDITION. SECTION defaults to the
+ section at point. If SECTION is not specified and there also is no
+ section at point, then return ‘nil’.
+
+ CONDITION can take the following forms:
+ • ‘(CONDITION...)’
+
+ matches if any of the CONDITIONs matches.
+
+ • ‘[CLASS...]’
+
+ matches if the section’s class is the same as the first CLASS
+ or a subclass of that; the section’s parent class matches the
+ second CLASS; and so on.
+
+ • ‘[* CLASS...]’
+
+ matches sections that match ‘[CLASS...]’ and also recursively
+ all their child sections.
+
+ • ‘CLASS’
+
+ matches if the section’s class is the same as CLASS or a
+ subclass of that; regardless of the classes of the parent
+ sections.
+
+ Each CLASS should be a class symbol, identifying a class that
+ derives from ‘magit-section’. For backward compatibility CLASS can
+ also be a "type symbol". A section matches such a symbol if the
+ value of its ‘type’ slot is ‘eq’. If a type symbol has an entry in
+ ‘magit--section-type-alist’, then a section also matches that type
+ if its class is a subclass of the class that corresponds to the
+ type as per that alist.
+
+ Note that it is not necessary to specify the complete section
+ lineage as printed by ‘magit-describe-section-briefly’, unless of
+ course you want to be that precise.
+
+ -- Function: magit-section-value-if condition &optional section
+ If the section at point matches CONDITION, then return its value.
+
+ If optional SECTION is non-nil then test whether that matches
+ instead. If there is no section at point and SECTION is nil, then
+ return nil. If the section does not match, then return nil.
+
+ See ‘magit-section-match’ for the forms CONDITION can take.
+
+ -- Function: magit-section-case &rest clauses
+ Choose among clauses on the type of the section at point.
+
+ Each clause looks like (CONDITION BODY...). The type of the
+ section is compared against each CONDITION; the BODY forms of the
+ first match are evaluated sequentially and the value of the last
+ form is returned. Inside BODY the symbol ‘it’ is bound to the
+ section at point. If no clause succeeds or if there is no section
+ at point return nil.
+
+ See ‘magit-section-match’ for the forms CONDITION can take.
+ Additionally a CONDITION of t is allowed in the final clause and
+ matches if no other CONDITION match, even if there is no section at
+ point.
+
+ -- Variable: magit-root-section
+ The root section in the current buffer. All other sections are
+ descendants of this section. The value of this variable is set by
+ ‘magit-insert-section’ and you should never modify it.
+
+ For diff related sections a few additional tools exist.
+
+ -- Function: magit-diff-type &optional section
+ Return the diff type of SECTION.
+
+ The returned type is one of the symbols ‘staged’, ‘unstaged’,
+ ‘committed’, or ‘undefined’. This type serves a similar purpose as
+ the general type common to all sections (which is stored in the
+ ‘type’ slot of the corresponding ‘magit-section’ struct) but takes
+ additional information into account. When the SECTION isn’t
+ related to diffs and the buffer containing it also isn’t a
+ diff-only buffer, then return nil.
+
+ Currently the type can also be one of ‘tracked’ and ‘untracked’,
+ but these values are not handled explicitly in every place they
+ should be. A possible fix could be to just return nil here.
+
+ The section has to be a ‘diff’ or ‘hunk’ section, or a section
+ whose children are of type ‘diff’. If optional SECTION is nil,
+ return the diff type for the current section. In buffers whose
+ major mode is ‘magit-diff-mode’ SECTION is ignored and the type is
+ determined using other means. In ‘magit-revision-mode’ buffers the
+ type is always ‘committed’.
+
+ -- Function: magit-diff-scope &optional section strict
+ Return the diff scope of SECTION or the selected section(s).
+
+ A diff’s "scope" describes what part of a diff is selected, it is a
+ symbol, one of ‘region’, ‘hunk’, ‘hunks’, ‘file’, ‘files’, or
+ ‘list’. Do not confuse this with the diff "type", as returned by
+ ‘magit-diff-type’.
+
+ If optional SECTION is non-nil, then return the scope of that,
+ ignoring the sections selected by the region. Otherwise return the
+ scope of the current section, or if the region is active and
+ selects a valid group of diff related sections, the type of these
+ sections, i.e. ‘hunks’ or ‘files’. If SECTION (or if the current
+ section that is nil) is a ‘hunk’ section and the region starts and
+ ends inside the body of a that section, then the type is ‘region’.
+
+ If optional STRICT is non-nil then return nil if the diff type of
+ the section at point is ‘untracked’ or the section at point is not
+ actually a ‘diff’ but a ‘diffstat’ section.
+
+
+File: magit.info, Node: Refreshing Buffers, Next: Conventions, Prev: Section Plumbing, Up: Plumbing
+
+10.3 Refreshing Buffers
+=======================
+
+All commands that create a new Magit buffer or change what is being
+displayed in an existing buffer do so by calling ‘magit-mode-setup’.
+Among other things, that function sets the buffer local values of
+‘default-directory’ (to the top-level of the repository),
+‘magit-refresh-function’, and ‘magit-refresh-args’.
+
+ Buffers are refreshed by calling the function that is the local value
+of ‘magit-refresh-function’ (a function named ‘magit-*-refresh-buffer’,
+where ‘*’ may be something like ‘diff’) with the value of
+‘magit-refresh-args’ as arguments.
+
+ -- Macro: magit-mode-setup buffer switch-func mode refresh-func
+ &optional refresh-args
+ This function displays and selects BUFFER, turns on MODE, and
+ refreshes a first time.
+
+ This function displays and optionally selects BUFFER by calling
+ ‘magit-mode-display-buffer’ with BUFFER, MODE and SWITCH-FUNC as
+ arguments. Then it sets the local value of
+ ‘magit-refresh-function’ to REFRESH-FUNC and that of
+ ‘magit-refresh-args’ to REFRESH-ARGS. Finally it creates the
+ buffer content by calling REFRESH-FUNC with REFRESH-ARGS as
+ arguments.
+
+ All arguments are evaluated before switching to BUFFER.
+
+ -- Function: magit-mode-display-buffer buffer mode &optional
+ switch-function
+ This function display BUFFER in some window and select it. BUFFER
+ may be a buffer or a string, the name of a buffer. The buffer is
+ returned.
+
+ Unless BUFFER is already displayed in the selected frame, store the
+ previous window configuration as a buffer local value, so that it
+ can later be restored by ‘magit-mode-bury-buffer’.
+
+ The buffer is displayed and selected using SWITCH-FUNCTION. If
+ that is ‘nil’ then ‘pop-to-buffer’ is used if the current buffer’s
+ major mode derives from ‘magit-mode’. Otherwise ‘switch-to-buffer’
+ is used.
+
+ -- Variable: magit-refresh-function
+ The value of this buffer-local variable is the function used to
+ refresh the current buffer. It is called with ‘magit-refresh-args’
+ as arguments.
+
+ -- Variable: magit-refresh-args
+ The list of arguments used by ‘magit-refresh-function’ to refresh
+ the current buffer. ‘magit-refresh-function’ is called with these
+ arguments.
+
+ The value is usually set using ‘magit-mode-setup’, but in some
+ cases it’s also useful to provide commands that can change the
+ value. For example, the ‘magit-diff-refresh’ transient can be used
+ to change any of the arguments used to display the diff, without
+ having to specify again which differences should be shown, but
+ ‘magit-diff-more-context’, ‘magit-diff-less-context’ and
+ ‘magit-diff-default-context’ change just the ‘-U<N>’ argument. In
+ both case this is done by changing the value of this variable and
+ then calling this ‘magit-refresh-function’.
+
+
+File: magit.info, Node: Conventions, Prev: Refreshing Buffers, Up: Plumbing
+
+10.4 Conventions
+================
+
+Also see *note Completion and Confirmation::.
+
+* Menu:
+
+* Theming Faces::
+
+
+File: magit.info, Node: Theming Faces, Up: Conventions
+
+10.4.1 Theming Faces
+--------------------
+
+The default theme uses blue for local branches, green for remote
+branches, and goldenrod (brownish yellow) for tags. When creating a new
+theme, you should probably follow that example. If your theme already
+uses other colors, then stick to that.
+
+ In older releases these reference faces used to have a background
+color and a box around them. The basic default faces no longer do so,
+to make Magit buffers much less noisy, and you should follow that
+example at least with regards to boxes. (Boxes were used in the past to
+work around a conflict between the highlighting overlay and text
+property backgrounds. That’s no longer necessary because highlighting
+no longer causes other background colors to disappear.) Alternatively
+you can keep the background color and/or box, but then have to take
+special care to adjust ‘magit-branch-current’ accordingly. By default
+it looks mostly like ‘magit-branch-local’, but with a box (by default
+the former is the only face that uses a box, exactly so that it sticks
+out). If the former also uses a box, then you have to make sure that it
+differs in some other way from the latter.
+
+ The most difficult faces to theme are those related to diffs,
+headings, highlighting, and the region. There are faces that fall into
+all four groups - expect to spend some time getting this right.
+
+ The ‘region’ face in the default theme, in both the light and dark
+variants, as well as in many other themes, distributed with Emacs or by
+third-parties, is very ugly. It is common to use a background color
+that really sticks out, which is ugly but if that were the only problem
+then it would be acceptable. Unfortunately many themes also set the
+foreground color, which ensures that all text within the region is
+readable. Without doing that there might be cases where some foreground
+color is too close to the region background color to still be readable.
+But it also means that text within the region loses all syntax
+highlighting.
+
+ I consider the work that went into getting the ‘region’ face right to
+be a good indicator for the general quality of a theme. My
+recommendation for the ‘region’ face is this: use a background color
+slightly different from the background color of the ‘default’ face, and
+do not set the foreground color at all. So for a light theme you might
+use a light (possibly tinted) gray as the background color of ‘default’
+and a somewhat darker gray for the background of ‘region’. That should
+usually be enough to not collide with the foreground color of any other
+face. But if some other faces also set a light gray as background
+color, then you should also make sure it doesn’t collide with those (in
+some cases it might be acceptable though).
+
+ Magit only uses the ‘region’ face when the region is "invalid" by its
+own definition. In a Magit buffer the region is used to either select
+multiple sibling sections, so that commands which support it act on all
+of these sections instead of just the current section, or to select
+lines within a single hunk section. In all other cases, the section is
+considered invalid and Magit won’t act on it. But such invalid sections
+happen, either because the user has not moved point enough yet to make
+it valid or because she wants to use a non-magit command to act on the
+region, e.g. ‘kill-region’.
+
+ So using the regular ‘region’ face for invalid sections is a feature.
+It tells the user that Magit won’t be able to act on it. It’s
+acceptable if that face looks a bit odd and even (but less so) if it
+collides with the background colors of section headings and other things
+that have a background color.
+
+ Magit highlights the current section. If a section has subsections,
+then all of them are highlighted. This is done using faces that have
+"highlight" in their names. For most sections,
+‘magit-section-highlight’ is used for both the body and the heading.
+Like the ‘region’ face, it should only set the background color to
+something similar to that of ‘default’. The highlight background color
+must be different from both the ‘region’ background color and the
+‘default’ background color.
+
+ For diff related sections Magit uses various faces to highlight
+different parts of the selected section(s). Note that hunk headings,
+unlike all other section headings, by default have a background color,
+because it is useful to have very visible separators between hunks.
+That face ‘magit-diff-hunk-heading’, should be different from both
+‘magit-diff-hunk-heading-highlight’ and ‘magit-section-highlight’, as
+well as from ‘magit-diff-context’ and ‘magit-diff-context-highlight’.
+By default we do that by changing the foreground color. Changing the
+background color would lead to complications, and there are already
+enough we cannot get around. (Also note that it is generally a good
+idea for section headings to always be bold, but only for sections that
+have subsections).
+
+ When there is a valid region selecting diff-related sibling sections,
+i.e. multiple files or hunks, then the bodies of all these sections use
+the respective highlight faces, but additionally the headings instead
+use one of the faces ‘magit-diff-file-heading-selection’ or
+‘magit-diff-hunk-heading-selection’. These faces have to be different
+from the regular highlight variants to provide explicit visual
+indication that the region is active.
+
+ When theming diff related faces, start by setting the option
+‘magit-diff-refine-hunk’ to ‘all’. You might personally prefer to only
+refine the current hunk or not use hunk refinement at all, but some of
+the users of your theme want all hunks to be refined, so you have to
+cater to that.
+
+ (Also turn on ‘magit-diff-highlight-indentation’,
+‘magit-diff-highlight-trailing’, and ‘magit-diff-paint-whitespace’; and
+insert some whitespace errors into the code you use for testing.)
+
+ For added lines you have to adjust three faces: ‘magit-diff-added’,
+‘magit-diff-added-highlight’, and ‘diff-refined-added’. Make sure that
+the latter works well with both of the former, as well as ‘smerge-other’
+and ‘diff-added’. Then do the same for the removed lines, context
+lines, lines added by us, and lines added by them. Also make sure the
+respective added, removed, and context faces use approximately the same
+saturation for both the highlighted and unhighlighted variants. Also
+make sure the file and diff headings work nicely with context lines
+(e.g. make them look different). Line faces should set both the
+foreground and the background color. For example, for added lines use
+two different greens.
+
+ It’s best if the foreground color of both the highlighted and the
+unhighlighted variants are the same, so you will need to have to find a
+color that works well on the highlight and unhighlighted background, the
+refine background, and the highlight context background. When there is
+an hunk internal region, then the added- and removed-lines background
+color is used only within that region. Outside the region the
+highlighted context background color is used. This makes it easier to
+see what is being staged. With an hunk internal region the hunk heading
+is shown using ‘magit-diff-hunk-heading-selection’, and so are the thin
+lines that are added around the lines that fall within the region. The
+background color of that has to be distinct enough from the various
+other involved background colors.
+
+ Nobody said this would be easy. If your theme restricts itself to a
+certain set of colors, then you should make an exception here.
+Otherwise it would be impossible to make the diffs look good in each and
+every variation. Actually you might want to just stick to the default
+definitions for these faces. You have been warned. Also please note
+that if you do not get this right, this will in some cases look to users
+like bugs in Magit - so please do it right or not at all.
+
+
+File: magit.info, Node: FAQ, Next: Debugging Tools, Prev: Plumbing, Up: Top
+
+Appendix A FAQ
+**************
+
+The next two nodes lists frequently asked questions. For a list of
+frequently *and recently* asked questions, i.e. questions that haven’t
+made it into the manual yet, see
+<https://github.com/magit/magit/wiki/FAQ>.
+
+ Please also see *note Debugging Tools::.
+
+* Menu:
+
+* FAQ - How to ...?::
+* FAQ - Issues and Errors::
+
+
+File: magit.info, Node: FAQ - How to ...?, Next: FAQ - Issues and Errors, Up: FAQ
+
+A.1 FAQ - How to ...?
+=====================
+
+* Menu:
+
+* How to pronounce Magit?::
+* How to show git's output?::
+* How to install the gitman info manual?::
+* How to show diffs for gpg-encrypted files?::
+* How does branching and pushing work?::
+* Can Magit be used as ediff-version-control-package?::
+* Should I disable VC?::
+
+
+File: magit.info, Node: How to pronounce Magit?, Next: How to show git's output?, Up: FAQ - How to ...?
+
+A.1.1 How to pronounce Magit?
+-----------------------------
+
+Either ‘mu[m's] git’ or ‘magi{c => t}’ is fine.
+
+ The slogan is "It’s Magit! The magical Git client", so it makes
+sense to pronounce Magit like magic, while taking into account that C
+and T do not sound the same.
+
+ The German "Magie" is not pronounced the same as the English "magic",
+so if you speak German then you can use the above rational to justify
+using the former pronunciation; ‘Mag{ie => it}’.
+
+ You can also choose to use the former pronunciation just because you
+like it better.
+
+ Also see <https://magit.vc/assets/videos/magic.mp4>. Also see
+<https://emacs.stackexchange.com/questions/13696>.
+
+
+File: magit.info, Node: How to show git's output?, Next: How to install the gitman info manual?, Prev: How to pronounce Magit?, Up: FAQ - How to ...?
+
+A.1.2 How to show git’s output?
+-------------------------------
+
+To show the output of recently run git commands, press ‘$’ (or, if that
+isn’t available, ‘M-x magit-process-buffer’). This will show a buffer
+containing a section per git invocation; as always press ‘TAB’ to expand
+or collapse them.
+
+ By default, git’s output is only inserted into the process buffer if
+it is run for side-effects. When the output is consumed in some way,
+also inserting it into the process buffer would be too expensive. For
+debugging purposes, it’s possible to do so anyway by setting
+‘magit-git-debug’ to ‘t’.
+
+
+File: magit.info, Node: How to install the gitman info manual?, Next: How to show diffs for gpg-encrypted files?, Prev: How to show git's output?, Up: FAQ - How to ...?
+
+A.1.3 How to install the gitman info manual?
+--------------------------------------------
+
+Git’s manpages can be exported as an info manual called ‘gitman’.
+Magit’s own info manual links to nodes in that manual instead of the
+actual manpages because Info doesn’t support linking to manpages.
+
+ Unfortunately some distributions do not install the ‘gitman’ manual
+by default and you will have to install a separate documentation package
+to get it.
+
+ Magit patches Info adding the ability to visit links to the ‘gitman’
+Info manual by instead viewing the respective manpage. If you prefer
+that approach, then set the value of ‘magit-view-git-manual-method’ to
+one of the supported packages ‘man’ or ‘woman’, e.g.:
+
+ (setq magit-view-git-manual-method 'man)
+
+
+File: magit.info, Node: How to show diffs for gpg-encrypted files?, Next: How does branching and pushing work?, Prev: How to install the gitman info manual?, Up: FAQ - How to ...?
+
+A.1.4 How to show diffs for gpg-encrypted files?
+------------------------------------------------
+
+Git supports showing diffs for encrypted files, but has to be told to do
+so. Since Magit just uses Git to get the diffs, configuring Git also
+affects the diffs displayed inside Magit.
+
+ git config --global diff.gpg.textconv "gpg --no-tty --decrypt"
+ echo "*.gpg filter=gpg diff=gpg" > .gitattributes
+
+
+File: magit.info, Node: How does branching and pushing work?, Next: Can Magit be used as ediff-version-control-package?, Prev: How to show diffs for gpg-encrypted files?, Up: FAQ - How to ...?
+
+A.1.5 How does branching and pushing work?
+------------------------------------------
+
+Please see *note Branching:: and
+<http://emacsair.me/2016/01/18/magit-2.4>
+
+
+File: magit.info, Node: Can Magit be used as ediff-version-control-package?, Next: Should I disable VC?, Prev: How does branching and pushing work?, Up: FAQ - How to ...?
+
+A.1.6 Can Magit be used as ‘ediff-version-control-package’?
+-----------------------------------------------------------
+
+No, it cannot. For that to work the functions ‘ediff-magit-internal’
+and ‘ediff-magit-merge-internal’ would have to be implemented, and they
+are not. These two functions are only used by the three commands
+‘ediff-revision’, ‘ediff-merge-revisions-with-ancestor’, and
+‘ediff-merge-revisions’.
+
+ These commands only delegate the task of populating buffers with
+certain revisions to the "internal" functions. The equally important
+task of determining which revisions are to be compared/merged is not
+delegated. Instead this is done without any support whatsoever from the
+version control package/system - meaning that the user has to enter the
+revisions explicitly. Instead of implementing ‘ediff-magit-internal’ we
+provide ‘magit-ediff-compare’, which handles both tasks like it is 2005.
+
+ The other commands ‘ediff-merge-revisions’ and
+‘ediff-merge-revisions-with-ancestor’ are normally not what you want
+when using a modern version control system like Git. Instead of letting
+the user resolve only those conflicts which Git could not resolve on its
+own, they throw away all work done by Git and then expect the user to
+manually merge all conflicts, including those that had already been
+resolved. That made sense back in the days when version control systems
+couldn’t merge (or so I have been told), but not anymore. Once in a
+blue moon you might actually want to see all conflicts, in which case
+you *can* use these commands, which then use ‘ediff-vc-merge-internal’.
+So we don’t actually have to implement ‘ediff-magit-merge-internal’.
+Instead we provide the more useful command ‘magit-ediff-resolve’ which
+only shows yet-to-be resolved conflicts.
+
+
+File: magit.info, Node: Should I disable VC?, Prev: Can Magit be used as ediff-version-control-package?, Up: FAQ - How to ...?
+
+A.1.7 Should I disable VC?
+--------------------------
+
+If you don’t use VC (the built-in version control interface) then you
+might be tempted to disable it, not least because we used to recommend
+that you do that.
+
+ We no longer recommend that you disable VC. Doing so would break
+useful third-party packages (such as ‘diff-hl’), which depend on VC
+being enabled.
+
+ If you choose to disable VC anyway, then you can do so by changing
+the value of ‘vc-handled-backends’.
+
+
+File: magit.info, Node: FAQ - Issues and Errors, Prev: FAQ - How to ...?, Up: FAQ
+
+A.2 FAQ - Issues and Errors
+===========================
+
+* Menu:
+
+* Magit is slow::
+* I changed several thousand files at once and now Magit is unusable::
+* I am having problems committing::
+* I am using MS Windows and cannot push with Magit::
+* I am using OS X and SOMETHING works in shell, but not in Magit: I am using OS X and SOMETHING works in shell but not in Magit.
+* Expanding a file to show the diff causes it to disappear::
+* Point is wrong in the COMMIT_EDITMSG buffer::
+* The mode-line information isn't always up-to-date::
+* A branch and tag sharing the same name breaks SOMETHING::
+* My Git hooks work on the command-line but not inside Magit::
+* git-commit-mode isn't used when committing from the command-line::
+* Point ends up inside invisible text when jumping to a file-visiting buffer::
+* I am unable to stage when using Tramp from MS Windows::
+* I am no longer able to save popup defaults::
+
+
+File: magit.info, Node: Magit is slow, Next: I changed several thousand files at once and now Magit is unusable, Up: FAQ - Issues and Errors
+
+A.2.1 Magit is slow
+-------------------
+
+See *note Performance::.
+
+
+File: magit.info, Node: I changed several thousand files at once and now Magit is unusable, Next: I am having problems committing, Prev: Magit is slow, Up: FAQ - Issues and Errors
+
+A.2.2 I changed several thousand files at once and now Magit is unusable
+------------------------------------------------------------------------
+
+Magit is *currently* not expected to work under such conditions. It
+sure would be nice if it did, and v2.5 will hopefully be a big step into
+that direction. But it might take until v3.1 to accomplish fully
+satisfactory performance, because that requires some heavy refactoring.
+
+ But for now we recommend you use the command line to complete this
+one commit. Also see *note Performance::.
+
+
+File: magit.info, Node: I am having problems committing, Next: I am using MS Windows and cannot push with Magit, Prev: I changed several thousand files at once and now Magit is unusable, Up: FAQ - Issues and Errors
+
+A.2.3 I am having problems committing
+-------------------------------------
+
+That likely means that Magit is having problems finding an appropriate
+emacsclient executable. See *note (with-editor)Configuring
+With-Editor:: and *note (with-editor)Debugging::.
+
+
+File: magit.info, Node: I am using MS Windows and cannot push with Magit, Next: I am using OS X and SOMETHING works in shell but not in Magit, Prev: I am having problems committing, Up: FAQ - Issues and Errors
+
+A.2.4 I am using MS Windows and cannot push with Magit
+------------------------------------------------------
+
+It’s almost certain that Magit is only incidental to this issue. It is
+much more likely that this is a configuration issue, even if you can
+push on the command line.
+
+ Detailed setup instructions can be found at
+<https://github.com/magit/magit/wiki/Pushing-with-Magit-from-Windows>.
+
+
+File: magit.info, Node: I am using OS X and SOMETHING works in shell but not in Magit, Next: Expanding a file to show the diff causes it to disappear, Prev: I am using MS Windows and cannot push with Magit, Up: FAQ - Issues and Errors
+
+A.2.5 I am using OS X and SOMETHING works in shell, but not in Magit
+--------------------------------------------------------------------
+
+This usually occurs because Emacs doesn’t have the same environment
+variables as your shell. Try installing and configuring
+<https://github.com/purcell/exec-path-from-shell>. By default it
+synchronizes ‘$PATH’, which helps Magit find the same ‘git’ as the one
+you are using on the shell.
+
+ If SOMETHING is "passphrase caching with gpg-agent for commit and/or
+tag signing", then you’ll also need to synchronize ‘$GPG_AGENT_INFO’.
+
+
+File: magit.info, Node: Expanding a file to show the diff causes it to disappear, Next: Point is wrong in the COMMIT_EDITMSG buffer, Prev: I am using OS X and SOMETHING works in shell but not in Magit, Up: FAQ - Issues and Errors
+
+A.2.6 Expanding a file to show the diff causes it to disappear
+--------------------------------------------------------------
+
+This is probably caused by a change of a ‘diff.*’ Git variable. You
+probably set that variable for a reason, and should therefore only undo
+that setting in Magit by customizing ‘magit-git-global-arguments’.
+
+
+File: magit.info, Node: Point is wrong in the COMMIT_EDITMSG buffer, Next: The mode-line information isn't always up-to-date, Prev: Expanding a file to show the diff causes it to disappear, Up: FAQ - Issues and Errors
+
+A.2.7 Point is wrong in the ‘COMMIT_EDITMSG’ buffer
+---------------------------------------------------
+
+Neither Magit nor ‘git-commit‘ fiddle with point in the buffer used to
+write commit messages, so something else must be doing it.
+
+ You have probably globally enabled a mode which does restore point in
+file-visiting buffers. It might be a bit surprising, but when you write
+a commit message, then you are actually editing a file.
+
+ So you have to figure out which package is doing. ‘saveplace’,
+‘pointback’, and ‘session’ are likely candidates. These snippets might
+help:
+
+ (setq session-name-disable-regexp "\\(?:\\`'\\.git/[A-Z_]+\\'\\)")
+
+ (with-eval-after-load 'pointback
+ (lambda ()
+ (when (or git-commit-mode git-rebase-mode)
+ (pointback-mode -1))))
+
+
+File: magit.info, Node: The mode-line information isn't always up-to-date, Next: A branch and tag sharing the same name breaks SOMETHING, Prev: Point is wrong in the COMMIT_EDITMSG buffer, Up: FAQ - Issues and Errors
+
+A.2.8 The mode-line information isn’t always up-to-date
+-------------------------------------------------------
+
+Magit is not responsible for the version control information that is
+being displayed in the mode-line and looks something like ‘Git-master’.
+The built-in "Version Control" package, also known as "VC", updates that
+information, and can be told to do so more often:
+
+ (setq auto-revert-check-vc-info t)
+
+ But doing so isn’t good for performance. For more (overly
+optimistic) information see *note (emacs)VC Mode Line::.
+
+ If you don’t really care about seeing this information in the
+mode-line, but just don’t want to see _incorrect_ information, then
+consider simply not displaying it in the mode-line:
+
+ (setq-default mode-line-format
+ (delete '(vc-mode vc-mode) mode-line-format))
+
+
+File: magit.info, Node: A branch and tag sharing the same name breaks SOMETHING, Next: My Git hooks work on the command-line but not inside Magit, Prev: The mode-line information isn't always up-to-date, Up: FAQ - Issues and Errors
+
+A.2.9 A branch and tag sharing the same name breaks SOMETHING
+-------------------------------------------------------------
+
+Or more generally, ambiguous refnames break SOMETHING.
+
+ Magit assumes that refs are named non-ambiguously across the
+"refs/heads/", "refs/tags/", and "refs/remotes/" namespaces (i.e., all
+the names remain unique when those prefixes are stripped). We consider
+ambiguous refnames unsupported and recommend that you use a
+non-ambiguous naming scheme. However, if you do work with a repository
+that has ambiguous refnames, please report any issues you encounter so
+that we can investigate whether there is a simple fix.
+
+
+File: magit.info, Node: My Git hooks work on the command-line but not inside Magit, Next: git-commit-mode isn't used when committing from the command-line, Prev: A branch and tag sharing the same name breaks SOMETHING, Up: FAQ - Issues and Errors
+
+A.2.10 My Git hooks work on the command-line but not inside Magit
+-----------------------------------------------------------------
+
+When Magit calls ‘git’ it adds a few global arguments including
+‘--literal-pathspecs’ and the ‘git’ process started by Magit then passes
+that setting on to other ‘git’ process it starts itself. It does so by
+setting the environment variable ‘GIT_LITERAL_PATHSPECS’, not by calling
+subprocesses with the ‘--literal-pathspecs’ argument. You can therefore
+override this setting in hook scripts using ‘unset
+GIT_LITERAL_PATHSPECS’.
+
+
+File: magit.info, Node: git-commit-mode isn't used when committing from the command-line, Next: Point ends up inside invisible text when jumping to a file-visiting buffer, Prev: My Git hooks work on the command-line but not inside Magit, Up: FAQ - Issues and Errors
+
+A.2.11 ‘git-commit-mode’ isn’t used when committing from the command-line
+-------------------------------------------------------------------------
+
+The reason for this is that ‘git-commit.el’ has not been loaded yet
+and/or that the server has not been started yet. These things have
+always already been taken care of when you commit from Magit because in
+order to do so, Magit has to be loaded and doing that involves loading
+‘git-commit’ and starting the server.
+
+ If you want to commit from the command-line, then you have to take
+care of these things yourself. Your ‘init.el’ file should contain:
+
+ (require 'git-commit)
+ (server-mode)
+
+ Instead of ‘(require ’git-commit)‘ you may also use:
+
+ (load "/path/to/magit-autoloads.el")
+
+ You might want to do that because loading ‘git-commit’ causes large
+parts of Magit to be loaded.
+
+ There are also some variations of ‘(server-mode)’ that you might want
+to try. Personally I use:
+
+ (use-package server
+ :config (or (server-running-p) (server-mode)))
+
+ Now you can use:
+
+ $ emacs&
+ $ EDITOR=emacsclient git commit
+
+ However you cannot use:
+
+ $ killall emacs
+ $ EDITOR="emacsclient --alternate-editor emacs" git commit
+
+ This will actually end up using ‘emacs’, not ‘emacsclient’. If you
+do this, then you can still edit the commit message but
+‘git-commit-mode’ won’t be used and you have to exit ‘emacs’ to finish
+the process.
+
+ Tautology ahead. If you want to be able to use ‘emacsclient’ to
+connect to a running ‘emacs’ instance, even though no ‘emacs’ instance
+is running, then you cannot use ‘emacsclient’ directly.
+
+ Instead you have to create a script that does something like this:
+
+ Try to use ‘emacsclient’ (without using ‘--alternate-editor’). If
+that succeeds, do nothing else. Otherwise start ‘emacs &’ (and
+‘init.el’ must call ‘server-start’) and try to use ‘emacsclient’ again.
+
+
+File: magit.info, Node: Point ends up inside invisible text when jumping to a file-visiting buffer, Next: I am unable to stage when using Tramp from MS Windows, Prev: git-commit-mode isn't used when committing from the command-line, Up: FAQ - Issues and Errors
+
+A.2.12 Point ends up inside invisible text when jumping to a file-visiting buffer
+---------------------------------------------------------------------------------
+
+This can happen when you type ‘RET’ on a hunk to visit the respective
+file at the respective position. One solution to this problem is to use
+‘global-reveal-mode’. It makes sure that text around point is always
+visible. If that is too drastic for your taste, then you may instead
+use ‘magit-diff-visit-file-hook’ to reveal the text, possibly using
+‘reveal-post-command’ or for Org buffers ‘org-reveal’.
+
+
+File: magit.info, Node: I am unable to stage when using Tramp from MS Windows, Next: I am no longer able to save popup defaults, Prev: Point ends up inside invisible text when jumping to a file-visiting buffer, Up: FAQ - Issues and Errors
+
+A.2.13 I am unable to stage when using Tramp from MS Windows
+------------------------------------------------------------
+
+Magit may be unable to stage (or otherwise apply) individual hunks when
+you are connected to remote machine using Tramp and the local machine
+uses MS Windows.
+
+ There appears to be a problem with ‘process-send-eof’ in this
+scenario, as mentioned at the end of ‘tramp-tests.el’. I have contacted
+the Tramp maintainer about this. For now this unfortunately means that
+it just doesn’t work and we cannot do anything about it. If you have
+more information, then please comment on
+<https://github.com/magit/magit/issues/3624>.
+
+
+File: magit.info, Node: I am no longer able to save popup defaults, Prev: I am unable to stage when using Tramp from MS Windows, Up: FAQ - Issues and Errors
+
+A.2.14 I am no longer able to save popup defaults
+-------------------------------------------------
+
+Magit used to use Magit-Popup to implement the transient popup menus.
+Now it used Transient instead, which is Magit-Popup’s successor.
+
+ In the older Magit-Popup menus, it was possible to save user settings
+(e.g. setting the gpg signing key for commits) by using ‘C-c C-c’ in
+the popup buffer. This would dismiss the popup, but save the settings
+as the defaults for future popups.
+
+ When switching to Transient menus, this functionality is now
+available via ‘C-x C-s’ instead; the ‘C-x’ prefix has other options as
+well when using Transient, which will be displayed when it is typed.
+See <https://magit.vc/manual/transient/Saving-Values.html#Saving-Values>
+for more details.
+
+
+File: magit.info, Node: Debugging Tools, Next: Keystroke Index, Prev: FAQ, Up: Top
+
+B Debugging Tools
+*****************
+
+Magit and its dependencies provide a few debugging tools, and we
+appreciate it very much if you use those tools before reporting an
+issue. Please include all relevant output when reporting an issue.
+
+‘M-x magit-version’
+ This command shows the currently used versions of Magit, Git, and
+ Emacs in the echo area. Non-interactively this just returns the
+ Magit version.
+
+‘M-x magit-emacs-Q-command’
+ This command shows a debugging shell command in the echo area and
+ adds it to the kill ring. Paste that command into a shell and run
+ it.
+
+ This shell command starts ‘emacs’ with only ‘magit’ and its
+ dependencies loaded. Neither your configuration nor other
+ installed packages are loaded. This makes it easier to determine
+ whether some issue lays with Magit or something else.
+
+ If you run Magit from its Git repository, then you should be able
+ to use ‘make emacs-Q’ instead of the output of this command.
+
+‘M-x magit-toggle-verbose-refresh’
+ This command toggles whether additional git errors are reported.
+
+ Magit basically calls git for one of these two reasons: for
+ side-effects or to do something with its standard output.
+
+ When git is run for side-effects then its output, including error
+ messages, go into the process buffer which is shown when using ‘$’.
+
+ When git’s output is consumed in some way, then it would be too
+ expensive to also insert it into this buffer, but when this option
+ is non-nil and git returns with a non-zero exit status, then at
+ least its standard error is inserted into this buffer.
+
+ This is only intended for debugging purposes. Do not enable this
+ permanently, that would negatively affect performance. Also note
+ that just because git exits with a non-zero exit status and prints
+ an error message that usually doesn’t mean that it is an error as
+ far as Magit is concerned, which is another reason we usually hide
+ these error messages. Whether some error message is relevant in
+ the context of some unexpected behavior has to be judged on a case
+ by case basis.
+
+‘M-x magit-toggle-verbose-refresh’
+ This command toggles whether Magit refreshes buffers verbosely.
+ Enabling this helps figuring out which sections are bottlenecks.
+ The additional output can be found in the ‘*Messages*’ buffer.
+
+‘M-x magit-debug-git-executable’
+ This command displays a buffer containing information about the
+ available and used ‘git’ executable(s), and can be useful when
+ investigating ‘exec-path’ issues.
+
+ Also see *note Git Executable::.
+
+‘M-x with-editor-debug’
+ This command displays a buffer containing information about the
+ available and used ‘emacsclient’ executable(s), and can be useful
+ when investigating why Magit (or rather ‘with-editor’) cannot find
+ an appropriate ‘emacsclient’ executable.
+
+ Also see *note (with-editor)Debugging::.
+
+Please also see *note FAQ::.
+
+
+File: magit.info, Node: Keystroke Index, Next: Function and Command Index, Prev: Debugging Tools, Up: Top
+
+Appendix C Keystroke Index
+**************************
+
+
+* Menu:
+
+* !: Running Git Manually.
+ (line 13)
+* ! !: Running Git Manually.
+ (line 17)
+* ! a: Running Git Manually.
+ (line 53)
+* ! b: Running Git Manually.
+ (line 56)
+* ! g: Running Git Manually.
+ (line 59)
+* ! k: Running Git Manually.
+ (line 50)
+* ! m: Running Git Manually.
+ (line 62)
+* ! p: Running Git Manually.
+ (line 25)
+* ! s: Running Git Manually.
+ (line 34)
+* ! S: Running Git Manually.
+ (line 38)
+* $: Viewing Git Output. (line 17)
+* +: Log Buffer. (line 64)
+* + <1>: Refreshing Diffs. (line 61)
+* -: Log Buffer. (line 67)
+* - <1>: Refreshing Diffs. (line 58)
+* 0: Refreshing Diffs. (line 64)
+* 1: Section Visibility. (line 26)
+* 2: Section Visibility. (line 26)
+* 3: Section Visibility. (line 26)
+* 4: Section Visibility. (line 26)
+* 5: Repository List. (line 109)
+* :: Running Git Manually.
+ (line 25)
+* =: Log Buffer. (line 59)
+* >: Sparse checkouts. (line 17)
+* > a: Sparse checkouts. (line 39)
+* > d: Sparse checkouts. (line 50)
+* > e: Sparse checkouts. (line 21)
+* > r: Sparse checkouts. (line 44)
+* > s: Sparse checkouts. (line 33)
+* ^: Section Movement. (line 28)
+* a: Applying. (line 34)
+* A: Cherry Picking. (line 9)
+* A A: Cherry Picking. (line 17)
+* A a: Cherry Picking. (line 23)
+* A A <1>: Cherry Picking. (line 85)
+* A a <1>: Cherry Picking. (line 91)
+* A d: Cherry Picking. (line 51)
+* A h: Cherry Picking. (line 40)
+* A n: Cherry Picking. (line 62)
+* A s: Cherry Picking. (line 72)
+* A s <1>: Cherry Picking. (line 88)
+* B: Bisecting. (line 9)
+* b: Blaming. (line 95)
+* b <1>: Branch Commands. (line 13)
+* b <2>: Editing Rebase Sequences.
+ (line 70)
+* B B: Bisecting. (line 16)
+* B b: Bisecting. (line 32)
+* b b: Branch Commands. (line 47)
+* b C: Branch Commands. (line 31)
+* b c: Branch Commands. (line 63)
+* B g: Bisecting. (line 36)
+* B k: Bisecting. (line 46)
+* b k: Branch Commands. (line 138)
+* b l: Branch Commands. (line 69)
+* B m: Bisecting. (line 40)
+* b n: Branch Commands. (line 54)
+* B r: Bisecting. (line 51)
+* b r: Branch Commands. (line 143)
+* B s: Bisecting. (line 26)
+* b s: Branch Commands. (line 91)
+* b S: Branch Commands. (line 118)
+* b x: Branch Commands. (line 123)
+* c: Blaming. (line 121)
+* C: Cloning Repository. (line 20)
+* c <1>: Initiating a Commit. (line 9)
+* c <2>: Editing Rebase Sequences.
+ (line 59)
+* C >: Cloning Repository. (line 38)
+* c a: Initiating a Commit. (line 18)
+* c A: Initiating a Commit. (line 59)
+* C b: Cloning Repository. (line 44)
+* C C: Cloning Repository. (line 28)
+* c c: Initiating a Commit. (line 14)
+* C d: Cloning Repository. (line 55)
+* C e: Cloning Repository. (line 61)
+* c e: Initiating a Commit. (line 21)
+* c f: Initiating a Commit. (line 39)
+* c F: Initiating a Commit. (line 46)
+* C m: Cloning Repository. (line 48)
+* C s: Cloning Repository. (line 32)
+* c s: Initiating a Commit. (line 49)
+* c S: Initiating a Commit. (line 56)
+* c w: Initiating a Commit. (line 30)
+* C-<return>: Visiting Files and Blobs from a Diff.
+ (line 50)
+* C-<tab>: Section Visibility. (line 13)
+* C-c C-a: Commit Pseudo Headers.
+ (line 16)
+* C-c C-b: Log Buffer. (line 20)
+* C-c C-b <1>: Refreshing Diffs. (line 80)
+* C-c C-c: Transient Commands. (line 19)
+* C-c C-c <1>: Select from Log. (line 21)
+* C-c C-c <2>: Editing Commit Messages.
+ (line 18)
+* C-c C-c <3>: Editing Rebase Sequences.
+ (line 7)
+* C-c C-d: Refreshing Diffs. (line 71)
+* C-c C-d <1>: Editing Commit Messages.
+ (line 54)
+* C-c C-e: Commands Available in Diffs.
+ (line 24)
+* C-c C-f: Log Buffer. (line 23)
+* C-c C-f <1>: Refreshing Diffs. (line 83)
+* C-c C-i: Commit Pseudo Headers.
+ (line 13)
+* C-c C-k: Select from Log. (line 26)
+* C-c C-k <1>: Editing Commit Messages.
+ (line 22)
+* C-c C-k <2>: Editing Rebase Sequences.
+ (line 11)
+* C-c C-n: Log Buffer. (line 26)
+* C-c C-o: Commit Pseudo Headers.
+ (line 28)
+* C-c C-p: Commit Pseudo Headers.
+ (line 31)
+* C-c C-r: Commit Pseudo Headers.
+ (line 19)
+* C-c C-s: Commit Pseudo Headers.
+ (line 22)
+* C-c C-t: Commands Available in Diffs.
+ (line 15)
+* C-c C-t <1>: Commit Pseudo Headers.
+ (line 25)
+* C-c C-w: Using the Revision Stack.
+ (line 7)
+* C-c M-g: Commands for Buffers Visiting Files.
+ (line 22)
+* C-c M-g B: Blaming. (line 19)
+* C-c M-g b: Blaming. (line 30)
+* C-c M-g B <1>: Commands for Buffers Visiting Files.
+ (line 83)
+* C-c M-g B b: Blaming. (line 30)
+* C-c M-g B e: Blaming. (line 61)
+* C-c M-g B f: Blaming. (line 53)
+* C-c M-g B r: Blaming. (line 45)
+* C-c M-g c: Commands for Buffers Visiting Files.
+ (line 36)
+* C-c M-g D: Commands for Buffers Visiting Files.
+ (line 42)
+* C-c M-g d: Commands for Buffers Visiting Files.
+ (line 52)
+* C-c M-g e: Blaming. (line 61)
+* C-c M-g e <1>: Commands for Buffers Visiting Files.
+ (line 95)
+* C-c M-g f: Blaming. (line 53)
+* C-c M-g L: Commands for Buffers Visiting Files.
+ (line 60)
+* C-c M-g l: Commands for Buffers Visiting Files.
+ (line 70)
+* C-c M-g p: Commands for Buffers Visiting Files.
+ (line 104)
+* C-c M-g r: Blaming. (line 45)
+* C-c M-g s: Commands for Buffers Visiting Files.
+ (line 29)
+* C-c M-g t: Commands for Buffers Visiting Files.
+ (line 76)
+* C-c M-g u: Commands for Buffers Visiting Files.
+ (line 32)
+* C-c M-i: Commit Pseudo Headers.
+ (line 35)
+* C-c M-s: Editing Commit Messages.
+ (line 33)
+* C-w: Common Commands. (line 22)
+* C-x g: Status Buffer. (line 23)
+* C-x u: Editing Rebase Sequences.
+ (line 77)
+* d: Diffing. (line 22)
+* D: Refreshing Diffs. (line 12)
+* d c: Diffing. (line 63)
+* d d: Diffing. (line 27)
+* D f: Refreshing Diffs. (line 41)
+* D F: Refreshing Diffs. (line 45)
+* D g: Refreshing Diffs. (line 17)
+* d p: Diffing. (line 56)
+* d r: Diffing. (line 30)
+* D r: Refreshing Diffs. (line 37)
+* d s: Diffing. (line 48)
+* D s: Refreshing Diffs. (line 21)
+* d t: Diffing. (line 67)
+* D t: Refreshing Diffs. (line 34)
+* d u: Diffing. (line 53)
+* d w: Diffing. (line 43)
+* D w: Refreshing Diffs. (line 27)
+* DEL: Log Buffer. (line 50)
+* DEL <1>: Commands Available in Diffs.
+ (line 56)
+* DEL <2>: Blaming. (line 83)
+* DEL <3>: Editing Rebase Sequences.
+ (line 25)
+* e: Ediffing. (line 10)
+* E: Ediffing. (line 21)
+* e <1>: Editing Rebase Sequences.
+ (line 46)
+* E c: Ediffing. (line 66)
+* E i: Ediffing. (line 60)
+* E m: Ediffing. (line 33)
+* E r: Ediffing. (line 25)
+* E s: Ediffing. (line 53)
+* E t: Ediffing. (line 45)
+* E u: Ediffing. (line 57)
+* E w: Ediffing. (line 63)
+* E z: Ediffing. (line 69)
+* f: Repository List. (line 105)
+* f <1>: Editing Rebase Sequences.
+ (line 52)
+* f <2>: Fetching. (line 10)
+* F: Pulling. (line 10)
+* f a: Fetching. (line 45)
+* f C: Branch Commands. (line 31)
+* F C: Branch Commands. (line 31)
+* f e: Fetching. (line 34)
+* F e: Pulling. (line 28)
+* f m: Fetching. (line 48)
+* f o: Fetching. (line 37)
+* f p: Fetching. (line 15)
+* F p: Pulling. (line 14)
+* f r: Fetching. (line 41)
+* f u: Fetching. (line 22)
+* F u: Pulling. (line 21)
+* g: Automatic Refreshing of Magit Buffers.
+ (line 26)
+* G: Automatic Refreshing of Magit Buffers.
+ (line 34)
+* H: Section Types and Values.
+ (line 14)
+* I: Creating Repository. (line 7)
+* j: Log Buffer. (line 31)
+* j <1>: Commands Available in Diffs.
+ (line 43)
+* k: Viewing Git Output. (line 24)
+* k <1>: Applying. (line 40)
+* k <2>: Editing Rebase Sequences.
+ (line 56)
+* k <3>: Stashing. (line 82)
+* l: Logging. (line 30)
+* L: Refreshing Logs. (line 12)
+* L <1>: Log Buffer. (line 7)
+* L <2>: Log Margin. (line 52)
+* l <1>: Editing Rebase Sequences.
+ (line 94)
+* l a: Logging. (line 61)
+* l b: Logging. (line 58)
+* L d: Log Margin. (line 66)
+* L g: Refreshing Logs. (line 17)
+* l h: Logging. (line 40)
+* l H: Reflog. (line 18)
+* l l: Logging. (line 35)
+* l L: Logging. (line 55)
+* L L: Log Margin. (line 60)
+* L l: Log Margin. (line 63)
+* l o: Logging. (line 49)
+* l O: Reflog. (line 15)
+* l r: Reflog. (line 12)
+* L s: Refreshing Logs. (line 21)
+* L t: Refreshing Logs. (line 34)
+* l u: Logging. (line 43)
+* L w: Refreshing Logs. (line 27)
+* m: Repository List. (line 99)
+* m <1>: Merging. (line 10)
+* M: Remote Commands. (line 14)
+* m a: Merging. (line 42)
+* m a <1>: Merging. (line 87)
+* M a: Remote Commands. (line 48)
+* M C: Remote Commands. (line 32)
+* m e: Merging. (line 30)
+* m i: Merging. (line 54)
+* M k: Remote Commands. (line 60)
+* m m: Merging. (line 18)
+* m m <1>: Merging. (line 82)
+* m n: Merging. (line 36)
+* m p: Merging. (line 75)
+* M p: Remote Commands. (line 63)
+* M P: Remote Commands. (line 67)
+* M r: Remote Commands. (line 52)
+* m s: Merging. (line 67)
+* M u: Remote Commands. (line 56)
+* M-1: Section Visibility. (line 32)
+* M-2: Section Visibility. (line 32)
+* M-3: Section Visibility. (line 32)
+* M-4: Section Visibility. (line 32)
+* M-<tab>: Section Visibility. (line 16)
+* M-n: Section Movement. (line 24)
+* M-n <1>: Editing Commit Messages.
+ (line 41)
+* M-n <2>: Editing Rebase Sequences.
+ (line 40)
+* M-p: Section Movement. (line 19)
+* M-p <1>: Editing Commit Messages.
+ (line 36)
+* M-p <2>: Editing Rebase Sequences.
+ (line 37)
+* M-w: Blaming. (line 114)
+* M-w <1>: Common Commands. (line 39)
+* MM: Editing Rebase Sequences.
+ (line 102)
+* Mt: Editing Rebase Sequences.
+ (line 108)
+* n: Section Movement. (line 16)
+* n <1>: Blaming. (line 98)
+* N: Blaming. (line 101)
+* n <2>: Editing Rebase Sequences.
+ (line 34)
+* n <3>: Minor Mode for Buffers Visiting Blobs.
+ (line 16)
+* o: Submodule Transient. (line 7)
+* O: Subtree. (line 9)
+* o a: Submodule Transient. (line 20)
+* o d: Submodule Transient. (line 45)
+* O e: Subtree. (line 37)
+* O e p: Subtree. (line 48)
+* O e s: Subtree. (line 52)
+* o f: Submodule Transient. (line 51)
+* O i: Subtree. (line 13)
+* O i a: Subtree. (line 24)
+* O i c: Subtree. (line 28)
+* O i f: Subtree. (line 34)
+* O i m: Subtree. (line 31)
+* o l: Submodule Transient. (line 48)
+* o p: Submodule Transient. (line 32)
+* o r: Submodule Transient. (line 26)
+* o s: Submodule Transient. (line 40)
+* o u: Submodule Transient. (line 36)
+* p: Section Movement. (line 11)
+* p <1>: Blaming. (line 104)
+* P: Blaming. (line 107)
+* p <2>: Editing Rebase Sequences.
+ (line 31)
+* P <1>: Pushing. (line 10)
+* p <3>: Minor Mode for Buffers Visiting Blobs.
+ (line 13)
+* P C: Branch Commands. (line 31)
+* P e: Pushing. (line 29)
+* P m: Pushing. (line 45)
+* P o: Pushing. (line 33)
+* P p: Pushing. (line 15)
+* P r: Pushing. (line 37)
+* P t: Pushing. (line 52)
+* P T: Pushing. (line 59)
+* P u: Pushing. (line 22)
+* q: Quitting Windows. (line 7)
+* q <1>: Log Buffer. (line 14)
+* q <2>: Blaming. (line 110)
+* q <3>: Minor Mode for Buffers Visiting Blobs.
+ (line 19)
+* r: Rebasing. (line 10)
+* r <1>: Editing Rebase Sequences.
+ (line 43)
+* r a: Rebasing. (line 111)
+* r e: Rebasing. (line 42)
+* r e <1>: Rebasing. (line 107)
+* r f: Rebasing. (line 79)
+* r i: Rebasing. (line 76)
+* r k: Rebasing. (line 91)
+* r m: Rebasing. (line 83)
+* r p: Rebasing. (line 28)
+* r r: Rebasing. (line 97)
+* r s: Rebasing. (line 47)
+* r s <1>: Rebasing. (line 103)
+* r u: Rebasing. (line 35)
+* r w: Rebasing. (line 87)
+* RET: Repository List. (line 96)
+* RET <1>: References Buffer. (line 159)
+* RET <2>: Visiting Files and Blobs from a Diff.
+ (line 9)
+* RET <3>: Blaming. (line 71)
+* RET <4>: Editing Rebase Sequences.
+ (line 15)
+* s: Staging and Unstaging.
+ (line 29)
+* S: Staging and Unstaging.
+ (line 36)
+* s <1>: Editing Rebase Sequences.
+ (line 49)
+* S-<tab>: Section Visibility. (line 20)
+* SPC: Log Buffer. (line 41)
+* SPC <1>: Commands Available in Diffs.
+ (line 53)
+* SPC <2>: Blaming. (line 74)
+* SPC <3>: Editing Rebase Sequences.
+ (line 19)
+* t: Editing Rebase Sequences.
+ (line 97)
+* t <1>: Tagging. (line 9)
+* T: Notes. (line 9)
+* T a: Notes. (line 47)
+* T c: Notes. (line 43)
+* t k: Tagging. (line 37)
+* T m: Notes. (line 35)
+* t p: Tagging. (line 43)
+* T p: Notes. (line 28)
+* t r: Tagging. (line 18)
+* T r: Notes. (line 21)
+* t t: Tagging. (line 14)
+* T T: Notes. (line 14)
+* TAB: Section Visibility. (line 10)
+* u: Repository List. (line 102)
+* u <1>: Staging and Unstaging.
+ (line 42)
+* U: Staging and Unstaging.
+ (line 50)
+* v: Applying. (line 47)
+* V: Reverting. (line 7)
+* V A: Reverting. (line 29)
+* V a: Reverting. (line 35)
+* V s: Reverting. (line 32)
+* V V: Reverting. (line 15)
+* V v: Reverting. (line 20)
+* W: Plain Patches. (line 7)
+* w: Maildir Patches. (line 9)
+* w a: Plain Patches. (line 20)
+* w a <1>: Maildir Patches. (line 23)
+* w a <2>: Maildir Patches. (line 38)
+* W c: Plain Patches. (line 12)
+* w m: Maildir Patches. (line 20)
+* W s: Plain Patches. (line 26)
+* w s: Maildir Patches. (line 34)
+* w w: Maildir Patches. (line 14)
+* w w <1>: Maildir Patches. (line 31)
+* x: Editing Rebase Sequences.
+ (line 62)
+* x <1>: Resetting. (line 9)
+* X f: Resetting. (line 44)
+* X h: Resetting. (line 24)
+* X i: Resetting. (line 33)
+* X k: Resetting. (line 28)
+* X m: Resetting. (line 15)
+* X s: Resetting. (line 19)
+* X w: Resetting. (line 39)
+* X w <1>: Wip Modes. (line 64)
+* Y: Cherries. (line 18)
+* y: References Buffer. (line 7)
+* y <1>: Editing Rebase Sequences.
+ (line 74)
+* y c: References Buffer. (line 25)
+* y o: References Buffer. (line 30)
+* y r: References Buffer. (line 34)
+* y y: References Buffer. (line 21)
+* z: Stashing. (line 9)
+* Z: Worktree. (line 9)
+* z a: Stashing. (line 52)
+* z b: Stashing. (line 70)
+* z B: Stashing. (line 74)
+* Z b: Worktree. (line 13)
+* Z c: Worktree. (line 16)
+* z f: Stashing. (line 79)
+* Z g: Worktree. (line 26)
+* z i: Stashing. (line 20)
+* z I: Stashing. (line 42)
+* z k: Stashing. (line 63)
+* Z k: Worktree. (line 22)
+* z l: Stashing. (line 85)
+* Z m: Worktree. (line 19)
+* z p: Stashing. (line 57)
+* z v: Stashing. (line 67)
+* z w: Stashing. (line 24)
+* z W: Stashing. (line 46)
+* z x: Stashing. (line 30)
+* z z: Stashing. (line 14)
+* z Z: Stashing. (line 36)
+
+
+File: magit.info, Node: Function and Command Index, Next: Variable Index, Prev: Keystroke Index, Up: Top
+
+Appendix D Function and Command Index
+*************************************
+
+
+* Menu:
+
+* bug-reference-mode: Commit Mode and Hooks.
+ (line 49)
+* forward-line: Editing Rebase Sequences.
+ (line 34)
+* git-commit-ack: Commit Pseudo Headers.
+ (line 16)
+* git-commit-cc: Commit Pseudo Headers.
+ (line 28)
+* git-commit-check-style-conventions: Commit Message Conventions.
+ (line 37)
+* git-commit-insert-pseudo-header: Commit Pseudo Headers.
+ (line 13)
+* git-commit-next-message: Editing Commit Messages.
+ (line 41)
+* git-commit-prev-message: Editing Commit Messages.
+ (line 36)
+* git-commit-propertize-diff: Commit Mode and Hooks.
+ (line 41)
+* git-commit-reported: Commit Pseudo Headers.
+ (line 31)
+* git-commit-review: Commit Pseudo Headers.
+ (line 19)
+* git-commit-save-message: Editing Commit Messages.
+ (line 33)
+* git-commit-save-message <1>: Commit Mode and Hooks.
+ (line 26)
+* git-commit-setup-changelog-support: Commit Mode and Hooks.
+ (line 29)
+* git-commit-signoff: Commit Pseudo Headers.
+ (line 22)
+* git-commit-suggested: Commit Pseudo Headers.
+ (line 35)
+* git-commit-test: Commit Pseudo Headers.
+ (line 25)
+* git-commit-turn-on-auto-fill: Commit Mode and Hooks.
+ (line 33)
+* git-commit-turn-on-flyspell: Commit Mode and Hooks.
+ (line 37)
+* git-rebase-backward-line: Editing Rebase Sequences.
+ (line 31)
+* git-rebase-break: Editing Rebase Sequences.
+ (line 70)
+* git-rebase-edit: Editing Rebase Sequences.
+ (line 46)
+* git-rebase-exec: Editing Rebase Sequences.
+ (line 62)
+* git-rebase-fixup: Editing Rebase Sequences.
+ (line 52)
+* git-rebase-insert: Editing Rebase Sequences.
+ (line 74)
+* git-rebase-kill-line: Editing Rebase Sequences.
+ (line 56)
+* git-rebase-label: Editing Rebase Sequences.
+ (line 94)
+* git-rebase-merge: Editing Rebase Sequences.
+ (line 102)
+* git-rebase-merge-toggle-editmsg: Editing Rebase Sequences.
+ (line 108)
+* git-rebase-move-line-down: Editing Rebase Sequences.
+ (line 40)
+* git-rebase-move-line-up: Editing Rebase Sequences.
+ (line 37)
+* git-rebase-pick: Editing Rebase Sequences.
+ (line 59)
+* git-rebase-reset: Editing Rebase Sequences.
+ (line 97)
+* git-rebase-reword: Editing Rebase Sequences.
+ (line 43)
+* git-rebase-show-commit: Editing Rebase Sequences.
+ (line 15)
+* git-rebase-show-or-scroll-down: Editing Rebase Sequences.
+ (line 25)
+* git-rebase-show-or-scroll-up: Editing Rebase Sequences.
+ (line 19)
+* git-rebase-squash: Editing Rebase Sequences.
+ (line 49)
+* git-rebase-undo: Editing Rebase Sequences.
+ (line 77)
+* ido-enter-magit-status: Status Buffer. (line 96)
+* magit-add-section-hook: Section Hooks. (line 20)
+* magit-after-save-refresh-status: Automatic Refreshing of Magit Buffers.
+ (line 55)
+* magit-am: Maildir Patches. (line 9)
+* magit-am-abort: Maildir Patches. (line 38)
+* magit-am-apply-maildir: Maildir Patches. (line 20)
+* magit-am-apply-patches: Maildir Patches. (line 14)
+* magit-am-continue: Maildir Patches. (line 31)
+* magit-am-skip: Maildir Patches. (line 34)
+* magit-apply: Applying. (line 34)
+* magit-bisect: Bisecting. (line 9)
+* magit-bisect-bad: Bisecting. (line 32)
+* magit-bisect-good: Bisecting. (line 36)
+* magit-bisect-mark: Bisecting. (line 40)
+* magit-bisect-reset: Bisecting. (line 51)
+* magit-bisect-run: Bisecting. (line 26)
+* magit-bisect-skip: Bisecting. (line 46)
+* magit-bisect-start: Bisecting. (line 16)
+* magit-blame: Blaming. (line 19)
+* magit-blame <1>: Blaming. (line 95)
+* magit-blame <2>: Commands for Buffers Visiting Files.
+ (line 83)
+* magit-blame-addition: Blaming. (line 30)
+* magit-blame-copy-hash: Blaming. (line 114)
+* magit-blame-cycle-style: Blaming. (line 121)
+* magit-blame-echo: Blaming. (line 61)
+* magit-blame-next-chunk: Blaming. (line 98)
+* magit-blame-next-chunk-same-commit: Blaming. (line 101)
+* magit-blame-previous-chunk: Blaming. (line 104)
+* magit-blame-previous-chunk-same-commit: Blaming. (line 107)
+* magit-blame-quit: Blaming. (line 110)
+* magit-blame-removal: Blaming. (line 45)
+* magit-blame-reverse: Blaming. (line 53)
+* magit-blob-next: Minor Mode for Buffers Visiting Blobs.
+ (line 16)
+* magit-blob-previous: Commands for Buffers Visiting Files.
+ (line 104)
+* magit-blob-previous <1>: Minor Mode for Buffers Visiting Blobs.
+ (line 13)
+* magit-branch: Branch Commands. (line 13)
+* magit-branch-and-checkout: Branch Commands. (line 63)
+* magit-branch-checkout: Branch Commands. (line 69)
+* magit-branch-configure: Branch Commands. (line 31)
+* magit-branch-create: Branch Commands. (line 54)
+* magit-branch-delete: Branch Commands. (line 138)
+* magit-branch-or-checkout: Branch Commands. (line 251)
+* magit-branch-orphan: Branch Commands. (line 247)
+* magit-branch-rename: Branch Commands. (line 143)
+* magit-branch-reset: Branch Commands. (line 123)
+* magit-branch-shelve: Auxiliary Branch Commands.
+ (line 9)
+* magit-branch-spinoff: Branch Commands. (line 91)
+* magit-branch-spinout: Branch Commands. (line 118)
+* magit-branch-unshelve: Auxiliary Branch Commands.
+ (line 19)
+* magit-builtin-completing-read: Support for Completion Frameworks.
+ (line 41)
+* magit-bundle: Bundle. (line 8)
+* magit-call-git: Calling Git for Effect.
+ (line 28)
+* magit-call-process: Calling Git for Effect.
+ (line 31)
+* magit-cancel-section: Creating Sections. (line 69)
+* magit-checkout: Branch Commands. (line 47)
+* magit-cherry: Cherries. (line 18)
+* magit-cherry-apply: Cherry Picking. (line 23)
+* magit-cherry-copy: Cherry Picking. (line 17)
+* magit-cherry-donate: Cherry Picking. (line 51)
+* magit-cherry-harvest: Cherry Picking. (line 40)
+* magit-cherry-pick: Cherry Picking. (line 9)
+* magit-cherry-spinoff: Cherry Picking. (line 72)
+* magit-cherry-spinout: Cherry Picking. (line 62)
+* magit-clone: Cloning Repository. (line 20)
+* magit-clone-bare: Cloning Repository. (line 44)
+* magit-clone-mirror: Cloning Repository. (line 48)
+* magit-clone-regular: Cloning Repository. (line 28)
+* magit-clone-shallow: Cloning Repository. (line 32)
+* magit-clone-shallow-exclude: Cloning Repository. (line 61)
+* magit-clone-shallow-since: Cloning Repository. (line 55)
+* magit-clone-sparse: Cloning Repository. (line 38)
+* magit-commit: Initiating a Commit. (line 9)
+* magit-commit <1>: Commands for Buffers Visiting Files.
+ (line 36)
+* magit-commit-amend: Initiating a Commit. (line 18)
+* magit-commit-augment: Initiating a Commit. (line 59)
+* magit-commit-create: Initiating a Commit. (line 14)
+* magit-commit-extend: Initiating a Commit. (line 21)
+* magit-commit-fixup: Initiating a Commit. (line 39)
+* magit-commit-instant-fixup: Initiating a Commit. (line 46)
+* magit-commit-instant-squash: Initiating a Commit. (line 56)
+* magit-commit-reword: Initiating a Commit. (line 30)
+* magit-commit-squash: Initiating a Commit. (line 49)
+* magit-completing-read: Support for Completion Frameworks.
+ (line 57)
+* magit-copy-buffer-revision: Common Commands. (line 39)
+* magit-copy-section-value: Common Commands. (line 22)
+* magit-current-section: Section Selection. (line 6)
+* magit-cycle-margin-style: Log Margin. (line 63)
+* magit-debug-git-executable: Git Executable. (line 55)
+* magit-debug-git-executable <1>: Debugging Tools. (line 57)
+* magit-define-section-jumper: Creating Sections. (line 74)
+* magit-describe-section: Section Types and Values.
+ (line 14)
+* magit-describe-section-briefly: Section Types and Values.
+ (line 17)
+* magit-describe-section-briefly <1>: Matching Sections. (line 7)
+* magit-diff: Diffing. (line 22)
+* magit-diff <1>: Commands for Buffers Visiting Files.
+ (line 42)
+* magit-diff-buffer-file: Commands for Buffers Visiting Files.
+ (line 52)
+* magit-diff-default-context: Refreshing Diffs. (line 64)
+* magit-diff-dwim: Diffing. (line 27)
+* magit-diff-edit-hunk-commit: Commands Available in Diffs.
+ (line 24)
+* magit-diff-flip-revs: Refreshing Diffs. (line 41)
+* magit-diff-less-context: Refreshing Diffs. (line 58)
+* magit-diff-more-context: Refreshing Diffs. (line 61)
+* magit-diff-paths: Diffing. (line 56)
+* magit-diff-range: Diffing. (line 30)
+* magit-diff-refresh: Refreshing Diffs. (line 12)
+* magit-diff-refresh <1>: Refreshing Diffs. (line 17)
+* magit-diff-save-default-arguments: Refreshing Diffs. (line 27)
+* magit-diff-scope: Matching Sections. (line 110)
+* magit-diff-set-default-arguments: Refreshing Diffs. (line 21)
+* magit-diff-show-or-scroll-down: Log Buffer. (line 50)
+* magit-diff-show-or-scroll-down <1>: Blaming. (line 83)
+* magit-diff-show-or-scroll-up: Log Buffer. (line 41)
+* magit-diff-show-or-scroll-up <1>: Blaming. (line 74)
+* magit-diff-staged: Diffing. (line 48)
+* magit-diff-switch-range-type: Refreshing Diffs. (line 37)
+* magit-diff-toggle-file-filter: Refreshing Diffs. (line 45)
+* magit-diff-toggle-refine-hunk: Refreshing Diffs. (line 34)
+* magit-diff-trace-definition: Commands Available in Diffs.
+ (line 15)
+* magit-diff-type: Matching Sections. (line 88)
+* magit-diff-unstaged: Diffing. (line 53)
+* magit-diff-visit-file: Visiting Files and Blobs from a Diff.
+ (line 9)
+* magit-diff-visit-file-other-frame: Visiting Files and Blobs from a Diff.
+ (line 71)
+* magit-diff-visit-file-other-window: Visiting Files and Blobs from a Diff.
+ (line 70)
+* magit-diff-visit-file-worktree: Visiting Files and Blobs from a Diff.
+ (line 50)
+* magit-diff-visit-worktree-file-other-frame: Visiting Files and Blobs from a Diff.
+ (line 73)
+* magit-diff-visit-worktree-file-other-window: Visiting Files and Blobs from a Diff.
+ (line 72)
+* magit-diff-while-committing: Refreshing Diffs. (line 71)
+* magit-diff-while-committing <1>: Editing Commit Messages.
+ (line 54)
+* magit-diff-working-tree: Diffing. (line 43)
+* magit-disable-section-inserter: Per-Repository Configuration.
+ (line 31)
+* magit-discard: Applying. (line 40)
+* magit-dispatch: Transient Commands. (line 19)
+* magit-display-buffer: Switching Buffers. (line 6)
+* magit-display-buffer-fullcolumn-most-v1: Switching Buffers. (line 68)
+* magit-display-buffer-fullframe-status-topleft-v1: Switching Buffers.
+ (line 59)
+* magit-display-buffer-fullframe-status-v1: Switching Buffers.
+ (line 54)
+* magit-display-buffer-same-window-except-diff-v1: Switching Buffers.
+ (line 49)
+* magit-display-buffer-traditional: Switching Buffers. (line 42)
+* magit-display-repository-buffer: Common Commands. (line 9)
+* magit-ediff: Ediffing. (line 21)
+* magit-ediff-compare: Ediffing. (line 25)
+* magit-ediff-dwim: Ediffing. (line 10)
+* magit-ediff-resolve: Ediffing. (line 33)
+* magit-ediff-show-commit: Ediffing. (line 66)
+* magit-ediff-show-staged: Ediffing. (line 60)
+* magit-ediff-show-stash: Ediffing. (line 69)
+* magit-ediff-show-unstaged: Ediffing. (line 57)
+* magit-ediff-show-working-tree: Ediffing. (line 63)
+* magit-ediff-stage: Ediffing. (line 53)
+* magit-edit-line-commit: Commands for Buffers Visiting Files.
+ (line 95)
+* magit-emacs-Q-command: Debugging Tools. (line 16)
+* magit-fetch: Fetching. (line 10)
+* magit-fetch-all: Fetching. (line 45)
+* magit-fetch-branch: Fetching. (line 37)
+* magit-fetch-from-pushremote: Fetching. (line 15)
+* magit-fetch-from-upstream: Fetching. (line 22)
+* magit-fetch-modules: Submodule Transient. (line 51)
+* magit-fetch-other: Fetching. (line 34)
+* magit-fetch-refspec: Fetching. (line 41)
+* magit-file-checkout: Resetting. (line 44)
+* magit-file-checkout <1>: Commands for Buffers Visiting Files.
+ (line 118)
+* magit-file-delete: Commands for Buffers Visiting Files.
+ (line 112)
+* magit-file-dispatch: Commands for Buffers Visiting Files.
+ (line 22)
+* magit-file-rename: Commands for Buffers Visiting Files.
+ (line 109)
+* magit-file-untrack: Commands for Buffers Visiting Files.
+ (line 115)
+* magit-find-file: General-Purpose Visit Commands.
+ (line 9)
+* magit-find-file-other-frame: General-Purpose Visit Commands.
+ (line 19)
+* magit-find-file-other-window: General-Purpose Visit Commands.
+ (line 14)
+* magit-generate-buffer-name-default-function: Naming Buffers.
+ (line 16)
+* magit-get-section: Matching Sections. (line 14)
+* magit-git: Calling Git for Effect.
+ (line 46)
+* magit-git-command: Running Git Manually.
+ (line 25)
+* magit-git-command-topdir: Running Git Manually.
+ (line 17)
+* magit-git-exit-code: Getting a Value from Git.
+ (line 10)
+* magit-git-failure: Getting a Value from Git.
+ (line 17)
+* magit-git-false: Getting a Value from Git.
+ (line 25)
+* magit-git-insert: Getting a Value from Git.
+ (line 29)
+* magit-git-items: Getting a Value from Git.
+ (line 41)
+* magit-git-lines: Getting a Value from Git.
+ (line 37)
+* magit-git-mergetool: Running Git Manually.
+ (line 62)
+* magit-git-mergetool <1>: Ediffing. (line 45)
+* magit-git-str: Getting a Value from Git.
+ (line 75)
+* magit-git-string: Getting a Value from Git.
+ (line 32)
+* magit-git-success: Getting a Value from Git.
+ (line 13)
+* magit-git-true: Getting a Value from Git.
+ (line 21)
+* magit-git-wash: Calling Git for Effect.
+ (line 50)
+* magit-go-backward: Log Buffer. (line 20)
+* magit-go-backward <1>: Refreshing Diffs. (line 80)
+* magit-go-forward: Log Buffer. (line 23)
+* magit-go-forward <1>: Refreshing Diffs. (line 83)
+* magit-hunk-set-window-start: Section Movement. (line 45)
+* magit-ido-completing-read: Support for Completion Frameworks.
+ (line 46)
+* magit-init: Creating Repository. (line 7)
+* magit-insert-am-sequence: Status Sections. (line 25)
+* magit-insert-assumed-unchanged-files: Status Sections. (line 98)
+* magit-insert-bisect-log: Status Sections. (line 39)
+* magit-insert-bisect-output: Status Sections. (line 33)
+* magit-insert-bisect-rest: Status Sections. (line 36)
+* magit-insert-diff-filter-header: Status Header Sections.
+ (line 35)
+* magit-insert-error-header: Status Header Sections.
+ (line 26)
+* magit-insert-head-branch-header: Status Header Sections.
+ (line 38)
+* magit-insert-heading: Creating Sections. (line 41)
+* magit-insert-ignored-files: Status Sections. (line 83)
+* magit-insert-local-branches: References Sections. (line 16)
+* magit-insert-merge-log: Status Sections. (line 17)
+* magit-insert-modules: Status Module Sections.
+ (line 12)
+* magit-insert-modules-overview: Status Module Sections.
+ (line 30)
+* magit-insert-modules-unpulled-from-pushremote: Status Module Sections.
+ (line 45)
+* magit-insert-modules-unpulled-from-upstream: Status Module Sections.
+ (line 40)
+* magit-insert-modules-unpushed-to-pushremote: Status Module Sections.
+ (line 55)
+* magit-insert-modules-unpushed-to-upstream: Status Module Sections.
+ (line 50)
+* magit-insert-push-branch-header: Status Header Sections.
+ (line 45)
+* magit-insert-rebase-sequence: Status Sections. (line 21)
+* magit-insert-recent-commits: Status Sections. (line 110)
+* magit-insert-remote-branches: References Sections. (line 19)
+* magit-insert-remote-header: Status Header Sections.
+ (line 58)
+* magit-insert-repo-header: Status Header Sections.
+ (line 55)
+* magit-insert-section: Creating Sections. (line 6)
+* magit-insert-sequencer-sequence: Status Sections. (line 29)
+* magit-insert-skip-worktree-files: Status Sections. (line 92)
+* magit-insert-staged-changes: Status Sections. (line 53)
+* magit-insert-stashes: Status Sections. (line 56)
+* magit-insert-status-headers: Status Header Sections.
+ (line 12)
+* magit-insert-tags: References Sections. (line 22)
+* magit-insert-tags-header: Status Header Sections.
+ (line 49)
+* magit-insert-tracked-files: Status Sections. (line 80)
+* magit-insert-unpulled-cherries: Status Sections. (line 119)
+* magit-insert-unpulled-from-pushremote: Status Sections. (line 66)
+* magit-insert-unpulled-from-upstream: Status Sections. (line 62)
+* magit-insert-unpulled-or-recent-commits: Status Sections. (line 104)
+* magit-insert-unpushed-cherries: Status Sections. (line 125)
+* magit-insert-unpushed-to-pushremote: Status Sections. (line 74)
+* magit-insert-unpushed-to-upstream: Status Sections. (line 70)
+* magit-insert-unstaged-changes: Status Sections. (line 50)
+* magit-insert-untracked-files: Status Sections. (line 42)
+* magit-insert-upstream-branch-header: Status Header Sections.
+ (line 41)
+* magit-insert-user-header: Status Header Sections.
+ (line 65)
+* magit-jump-to-diffstat-or-diff: Commands Available in Diffs.
+ (line 43)
+* magit-kill-this-buffer: Minor Mode for Buffers Visiting Blobs.
+ (line 19)
+* magit-list-repositories: Repository List. (line 6)
+* magit-list-submodules: Listing Submodules. (line 13)
+* magit-list-submodules <1>: Submodule Transient. (line 48)
+* magit-log: Logging. (line 30)
+* magit-log <1>: Commands for Buffers Visiting Files.
+ (line 60)
+* magit-log-all: Logging. (line 61)
+* magit-log-all-branches: Logging. (line 58)
+* magit-log-branches: Logging. (line 55)
+* magit-log-buffer-file: Commands for Buffers Visiting Files.
+ (line 70)
+* magit-log-bury-buffer: Log Buffer. (line 14)
+* magit-log-current: Logging. (line 35)
+* magit-log-double-commit-limit: Log Buffer. (line 64)
+* magit-log-half-commit-limit: Log Buffer. (line 67)
+* magit-log-head: Logging. (line 40)
+* magit-log-maybe-show-more-commits: Section Movement. (line 58)
+* magit-log-maybe-update-blob-buffer: Section Movement. (line 72)
+* magit-log-maybe-update-revision-buffer: Section Movement. (line 65)
+* magit-log-move-to-parent: Log Buffer. (line 26)
+* magit-log-move-to-revision: Log Buffer. (line 31)
+* magit-log-other: Logging. (line 49)
+* magit-log-refresh: Refreshing Logs. (line 12)
+* magit-log-refresh <1>: Refreshing Logs. (line 17)
+* magit-log-refresh <2>: Log Buffer. (line 7)
+* magit-log-related: Logging. (line 43)
+* magit-log-save-default-arguments: Refreshing Logs. (line 27)
+* magit-log-select-pick: Select from Log. (line 21)
+* magit-log-select-quit: Select from Log. (line 26)
+* magit-log-set-default-arguments: Refreshing Logs. (line 21)
+* magit-log-toggle-commit-limit: Log Buffer. (line 59)
+* magit-log-trace-definition: Commands for Buffers Visiting Files.
+ (line 76)
+* magit-margin-settings: Log Margin. (line 52)
+* magit-maybe-set-dedicated: Switching Buffers. (line 89)
+* magit-merge: Merging. (line 10)
+* magit-merge <1>: Merging. (line 82)
+* magit-merge-abort: Merging. (line 87)
+* magit-merge-absorb: Merging. (line 42)
+* magit-merge-editmsg: Merging. (line 30)
+* magit-merge-into: Merging. (line 54)
+* magit-merge-nocommit: Merging. (line 36)
+* magit-merge-plain: Merging. (line 18)
+* magit-merge-preview: Merging. (line 75)
+* magit-merge-squash: Merging. (line 67)
+* magit-mode-bury-buffer: Quitting Windows. (line 7)
+* magit-mode-display-buffer: Refreshing Buffers. (line 32)
+* magit-mode-quit-window: Quitting Windows. (line 31)
+* magit-mode-setup: Refreshing Buffers. (line 17)
+* magit-notes: Notes. (line 9)
+* magit-notes-edit: Notes. (line 14)
+* magit-notes-merge: Notes. (line 35)
+* magit-notes-merge-abort: Notes. (line 47)
+* magit-notes-merge-commit: Notes. (line 43)
+* magit-notes-prune: Notes. (line 28)
+* magit-notes-remove: Notes. (line 21)
+* magit-patch: Plain Patches. (line 7)
+* magit-patch-apply: Plain Patches. (line 20)
+* magit-patch-apply <1>: Maildir Patches. (line 23)
+* magit-patch-create: Plain Patches. (line 12)
+* magit-patch-save: Plain Patches. (line 26)
+* magit-pop-revision-stack: Using the Revision Stack.
+ (line 7)
+* magit-process: Viewing Git Output. (line 17)
+* magit-process-file: Getting a Value from Git.
+ (line 57)
+* magit-process-git: Getting a Value from Git.
+ (line 50)
+* magit-process-kill: Viewing Git Output. (line 24)
+* magit-pull: Pulling. (line 10)
+* magit-pull-branch: Pulling. (line 28)
+* magit-pull-from-pushremote: Pulling. (line 14)
+* magit-pull-from-upstream: Pulling. (line 21)
+* magit-push: Pushing. (line 10)
+* magit-push-current: Pushing. (line 29)
+* magit-push-current-to-pushremote: Pushing. (line 15)
+* magit-push-current-to-upstream: Pushing. (line 22)
+* magit-push-implicitly: Pushing. (line 74)
+* magit-push-matching: Pushing. (line 45)
+* magit-push-other: Pushing. (line 33)
+* magit-push-refspecs: Pushing. (line 37)
+* magit-push-tag: Pushing. (line 59)
+* magit-push-tags: Pushing. (line 52)
+* magit-push-to-remote: Pushing. (line 91)
+* magit-rebase: Rebasing. (line 10)
+* magit-rebase-abort: Rebasing. (line 111)
+* magit-rebase-autosquash: Rebasing. (line 79)
+* magit-rebase-branch: Rebasing. (line 42)
+* magit-rebase-continue: Rebasing. (line 97)
+* magit-rebase-edit: Rebasing. (line 107)
+* magit-rebase-edit-commit: Rebasing. (line 83)
+* magit-rebase-interactive: Rebasing. (line 76)
+* magit-rebase-onto-pushremote: Rebasing. (line 28)
+* magit-rebase-onto-upstream: Rebasing. (line 35)
+* magit-rebase-remove-commit: Rebasing. (line 91)
+* magit-rebase-reword-commit: Rebasing. (line 87)
+* magit-rebase-skip: Rebasing. (line 103)
+* magit-rebase-subset: Rebasing. (line 47)
+* magit-reflog-current: Reflog. (line 12)
+* magit-reflog-head: Reflog. (line 18)
+* magit-reflog-other: Reflog. (line 15)
+* magit-refresh: Automatic Refreshing of Magit Buffers.
+ (line 26)
+* magit-refresh-all: Automatic Refreshing of Magit Buffers.
+ (line 34)
+* magit-refs-set-show-commit-count: References Buffer. (line 34)
+* magit-region-sections: Section Selection. (line 9)
+* magit-region-values: Section Selection. (line 35)
+* magit-remote: Remote Commands. (line 14)
+* magit-remote-add: Remote Commands. (line 48)
+* magit-remote-configure: Remote Commands. (line 32)
+* magit-remote-prune: Remote Commands. (line 63)
+* magit-remote-prune-refspecs: Remote Commands. (line 67)
+* magit-remote-remove: Remote Commands. (line 60)
+* magit-remote-rename: Remote Commands. (line 52)
+* magit-remote-set-url: Remote Commands. (line 56)
+* magit-repolist-column-branch: Repository List. (line 52)
+* magit-repolist-column-branches: Repository List. (line 59)
+* magit-repolist-column-flag: Repository List. (line 65)
+* magit-repolist-column-ident: Repository List. (line 41)
+* magit-repolist-column-path: Repository List. (line 45)
+* magit-repolist-column-stashes: Repository List. (line 62)
+* magit-repolist-column-unpulled-from-pushremote: Repository List.
+ (line 81)
+* magit-repolist-column-unpulled-from-upstream: Repository List.
+ (line 77)
+* magit-repolist-column-unpushed-to-pushremote: Repository List.
+ (line 89)
+* magit-repolist-column-unpushed-to-upstream: Repository List.
+ (line 85)
+* magit-repolist-column-upstream: Repository List. (line 55)
+* magit-repolist-column-version: Repository List. (line 48)
+* magit-repolist-fetch: Repository List. (line 105)
+* magit-repolist-find-file-other-frame: Repository List. (line 109)
+* magit-repolist-mark: Repository List. (line 99)
+* magit-repolist-status: Repository List. (line 96)
+* magit-repolist-unmark: Repository List. (line 102)
+* magit-reset-hard: Resetting. (line 24)
+* magit-reset-index: Staging and Unstaging.
+ (line 78)
+* magit-reset-index <1>: Resetting. (line 33)
+* magit-reset-keep: Resetting. (line 28)
+* magit-reset-mixed: Resetting. (line 15)
+* magit-reset-quickly: Resetting. (line 9)
+* magit-reset-soft: Resetting. (line 19)
+* magit-reset-worktree: Resetting. (line 39)
+* magit-reset-worktree <1>: Wip Modes. (line 64)
+* magit-restore-window-configuration: Quitting Windows. (line 21)
+* magit-reverse: Applying. (line 47)
+* magit-reverse-in-index: Staging and Unstaging.
+ (line 58)
+* magit-revert: Reverting. (line 7)
+* magit-revert-and-commit: Reverting. (line 15)
+* magit-revert-no-commit: Reverting. (line 20)
+* magit-run: Running Git Manually.
+ (line 13)
+* magit-run-git: Calling Git for Effect.
+ (line 34)
+* magit-run-git-async: Calling Git for Effect.
+ (line 59)
+* magit-run-git-gui: Running Git Manually.
+ (line 59)
+* magit-run-git-with-editor: Calling Git for Effect.
+ (line 71)
+* magit-run-git-with-input: Calling Git for Effect.
+ (line 37)
+* magit-run-gitk: Running Git Manually.
+ (line 50)
+* magit-run-gitk-all: Running Git Manually.
+ (line 53)
+* magit-run-gitk-branches: Running Git Manually.
+ (line 56)
+* magit-save-window-configuration: Switching Buffers. (line 80)
+* magit-section-backward: Section Movement. (line 11)
+* magit-section-backward-siblings: Section Movement. (line 19)
+* magit-section-case: Matching Sections. (line 66)
+* magit-section-cycle: Section Visibility. (line 13)
+* magit-section-cycle-diffs: Section Visibility. (line 16)
+* magit-section-cycle-global: Section Visibility. (line 20)
+* magit-section-forward: Section Movement. (line 16)
+* magit-section-forward-siblings: Section Movement. (line 24)
+* magit-section-hide: Section Visibility. (line 42)
+* magit-section-hide-children: Section Visibility. (line 54)
+* magit-section-ident: Matching Sections. (line 10)
+* magit-section-match: Matching Sections. (line 18)
+* magit-section-set-window-start: Section Movement. (line 52)
+* magit-section-show: Section Visibility. (line 39)
+* magit-section-show-children: Section Visibility. (line 49)
+* magit-section-show-headings: Section Visibility. (line 45)
+* magit-section-show-level-1: Section Visibility. (line 26)
+* magit-section-show-level-1-all: Section Visibility. (line 32)
+* magit-section-show-level-2: Section Visibility. (line 26)
+* magit-section-show-level-2-all: Section Visibility. (line 32)
+* magit-section-show-level-3: Section Visibility. (line 26)
+* magit-section-show-level-3-all: Section Visibility. (line 32)
+* magit-section-show-level-4: Section Visibility. (line 26)
+* magit-section-show-level-4-all: Section Visibility. (line 32)
+* magit-section-toggle: Section Visibility. (line 10)
+* magit-section-toggle-children: Section Visibility. (line 57)
+* magit-section-up: Section Movement. (line 28)
+* magit-section-value-if: Matching Sections. (line 57)
+* magit-sequence-abort: Cherry Picking. (line 91)
+* magit-sequence-abort <1>: Reverting. (line 35)
+* magit-sequence-continue: Cherry Picking. (line 85)
+* magit-sequence-continue <1>: Reverting. (line 29)
+* magit-sequence-skip: Cherry Picking. (line 88)
+* magit-sequence-skip <1>: Reverting. (line 32)
+* magit-shell-command: Running Git Manually.
+ (line 38)
+* magit-shell-command-topdir: Running Git Manually.
+ (line 34)
+* magit-show-commit: Diffing. (line 63)
+* magit-show-commit <1>: Blaming. (line 71)
+* magit-show-refs: References Buffer. (line 7)
+* magit-show-refs-current: References Buffer. (line 25)
+* magit-show-refs-head: References Buffer. (line 21)
+* magit-show-refs-other: References Buffer. (line 30)
+* magit-snapshot-both: Stashing. (line 36)
+* magit-snapshot-index: Stashing. (line 42)
+* magit-snapshot-worktree: Stashing. (line 46)
+* magit-sparse-checkout: Sparse checkouts. (line 17)
+* magit-sparse-checkout-add: Sparse checkouts. (line 39)
+* magit-sparse-checkout-disable: Sparse checkouts. (line 50)
+* magit-sparse-checkout-enable: Sparse checkouts. (line 21)
+* magit-sparse-checkout-reapply: Sparse checkouts. (line 44)
+* magit-sparse-checkout-set: Sparse checkouts. (line 33)
+* magit-stage: Staging and Unstaging.
+ (line 29)
+* magit-stage-file: Staging from File-Visiting Buffers.
+ (line 11)
+* magit-stage-file <1>: Commands for Buffers Visiting Files.
+ (line 29)
+* magit-stage-modified: Staging and Unstaging.
+ (line 36)
+* magit-start-git: Calling Git for Effect.
+ (line 82)
+* magit-start-process: Calling Git for Effect.
+ (line 100)
+* magit-stash: Stashing. (line 9)
+* magit-stash-apply: Stashing. (line 52)
+* magit-stash-both: Stashing. (line 14)
+* magit-stash-branch: Stashing. (line 70)
+* magit-stash-branch-here: Stashing. (line 74)
+* magit-stash-clear: Stashing. (line 82)
+* magit-stash-drop: Stashing. (line 63)
+* magit-stash-format-patch: Stashing. (line 79)
+* magit-stash-index: Stashing. (line 20)
+* magit-stash-keep-index: Stashing. (line 30)
+* magit-stash-list: Stashing. (line 85)
+* magit-stash-pop: Stashing. (line 57)
+* magit-stash-show: Diffing. (line 67)
+* magit-stash-show <1>: Stashing. (line 67)
+* magit-stash-worktree: Stashing. (line 24)
+* magit-stashes-maybe-update-stash-buffer: Section Movement. (line 92)
+* magit-status: Status Buffer. (line 23)
+* magit-status-maybe-update-blob-buffer: Section Movement. (line 87)
+* magit-status-maybe-update-revision-buffer: Section Movement.
+ (line 77)
+* magit-status-maybe-update-stash-buffer: Section Movement. (line 82)
+* magit-status-quick: Status Buffer. (line 70)
+* magit-submodule: Submodule Transient. (line 7)
+* magit-submodule-add: Submodule Transient. (line 20)
+* magit-submodule-fetch: Fetching. (line 48)
+* magit-submodule-populate: Submodule Transient. (line 32)
+* magit-submodule-register: Submodule Transient. (line 26)
+* magit-submodule-synchronize: Submodule Transient. (line 40)
+* magit-submodule-unpopulate: Submodule Transient. (line 45)
+* magit-submodule-update: Submodule Transient. (line 36)
+* magit-subtree: Subtree. (line 9)
+* magit-subtree-add: Subtree. (line 24)
+* magit-subtree-add-commit: Subtree. (line 28)
+* magit-subtree-export: Subtree. (line 37)
+* magit-subtree-import: Subtree. (line 13)
+* magit-subtree-merge: Subtree. (line 31)
+* magit-subtree-pull: Subtree. (line 34)
+* magit-subtree-push: Subtree. (line 48)
+* magit-subtree-split: Subtree. (line 52)
+* magit-switch-to-repository-buffer: Common Commands. (line 6)
+* magit-switch-to-repository-buffer-other-frame: Common Commands.
+ (line 8)
+* magit-switch-to-repository-buffer-other-window: Common Commands.
+ (line 7)
+* magit-tag: Tagging. (line 9)
+* magit-tag-create: Tagging. (line 14)
+* magit-tag-delete: Tagging. (line 37)
+* magit-tag-prune: Tagging. (line 43)
+* magit-tag-release: Tagging. (line 18)
+* magit-toggle-buffer-lock: Modes and Buffers. (line 18)
+* magit-toggle-margin: Refreshing Logs. (line 34)
+* magit-toggle-margin <1>: Log Margin. (line 60)
+* magit-toggle-margin-details: Log Margin. (line 66)
+* magit-toggle-verbose-refresh: Debugging Tools. (line 29)
+* magit-toggle-verbose-refresh <1>: Debugging Tools. (line 52)
+* magit-unstage: Staging and Unstaging.
+ (line 42)
+* magit-unstage-all: Staging and Unstaging.
+ (line 50)
+* magit-unstage-file: Staging from File-Visiting Buffers.
+ (line 18)
+* magit-unstage-file <1>: Commands for Buffers Visiting Files.
+ (line 32)
+* magit-version: Git Executable. (line 59)
+* magit-version <1>: Debugging Tools. (line 11)
+* magit-visit-ref: References Buffer. (line 159)
+* magit-wip-commit: Wip Modes. (line 85)
+* magit-wip-log: Wip Modes. (line 47)
+* magit-wip-log-current: Wip Modes. (line 55)
+* magit-worktree: Worktree. (line 9)
+* magit-worktree-branch: Worktree. (line 16)
+* magit-worktree-checkout: Worktree. (line 13)
+* magit-worktree-delete: Worktree. (line 22)
+* magit-worktree-move: Worktree. (line 19)
+* magit-worktree-status: Worktree. (line 26)
+* scroll-down: Commands Available in Diffs.
+ (line 56)
+* scroll-up: Commands Available in Diffs.
+ (line 53)
+* with-editor-cancel: Editing Commit Messages.
+ (line 22)
+* with-editor-cancel <1>: Editing Rebase Sequences.
+ (line 11)
+* with-editor-debug: Debugging Tools. (line 64)
+* with-editor-finish: Editing Commit Messages.
+ (line 18)
+* with-editor-finish <1>: Editing Rebase Sequences.
+ (line 7)
+* with-editor-usage-message: Commit Mode and Hooks.
+ (line 52)
+
+
+File: magit.info, Node: Variable Index, Prev: Function and Command Index, Up: Top
+
+Appendix E Variable Index
+*************************
+
+
+* Menu:
+
+* auto-revert-buffer-list-filter: Automatic Reverting of File-Visiting Buffers.
+ (line 73)
+* auto-revert-interval: Automatic Reverting of File-Visiting Buffers.
+ (line 69)
+* auto-revert-mode: Automatic Reverting of File-Visiting Buffers.
+ (line 57)
+* auto-revert-stop-on-user-input: Automatic Reverting of File-Visiting Buffers.
+ (line 65)
+* auto-revert-use-notify: Automatic Reverting of File-Visiting Buffers.
+ (line 46)
+* auto-revert-verbose: Automatic Reverting of File-Visiting Buffers.
+ (line 94)
+* branch.autoSetupMerge: Branch Git Variables.
+ (line 71)
+* branch.autoSetupRebase: Branch Git Variables.
+ (line 85)
+* branch.NAME.description: Branch Git Variables.
+ (line 42)
+* branch.NAME.merge: Branch Git Variables.
+ (line 10)
+* branch.NAME.pushRemote: Branch Git Variables.
+ (line 29)
+* branch.NAME.rebase: Branch Git Variables.
+ (line 20)
+* branch.NAME.remote: Branch Git Variables.
+ (line 15)
+* core.notesRef: Notes. (line 53)
+* git-commit-fill-column: Commit Message Conventions.
+ (line 18)
+* git-commit-finish-query-functions: Commit Message Conventions.
+ (line 22)
+* git-commit-known-pseudo-headers: Commit Pseudo Headers.
+ (line 9)
+* git-commit-major-mode: Commit Mode and Hooks.
+ (line 12)
+* git-commit-post-finish-hook: Commit Mode and Hooks.
+ (line 55)
+* git-commit-setup-hook: Commit Mode and Hooks.
+ (line 21)
+* git-commit-style-convention-checks: Commit Message Conventions.
+ (line 42)
+* git-commit-summary-max-length: Commit Message Conventions.
+ (line 13)
+* git-rebase-auto-advance: Editing Rebase Sequences.
+ (line 80)
+* git-rebase-confirm-cancel: Editing Rebase Sequences.
+ (line 86)
+* git-rebase-show-instructions: Editing Rebase Sequences.
+ (line 83)
+* global-auto-revert-mode: Automatic Reverting of File-Visiting Buffers.
+ (line 21)
+* magit-auto-revert-immediately: Automatic Reverting of File-Visiting Buffers.
+ (line 30)
+* magit-auto-revert-mode: Automatic Reverting of File-Visiting Buffers.
+ (line 17)
+* magit-auto-revert-tracked-only: Automatic Reverting of File-Visiting Buffers.
+ (line 51)
+* magit-bisect-show-graph: Bisecting. (line 57)
+* magit-blame-disable-modes: Blaming. (line 145)
+* magit-blame-echo-style: Blaming. (line 131)
+* magit-blame-goto-chunk-hook: Blaming. (line 150)
+* magit-blame-read-only: Blaming. (line 141)
+* magit-blame-styles: Blaming. (line 127)
+* magit-blame-time-format: Blaming. (line 137)
+* magit-branch-adjust-remote-upstream-alist: Branch Commands. (line 196)
+* magit-branch-direct-configure: Branch Commands. (line 19)
+* magit-branch-prefer-remote-upstream: Branch Commands. (line 152)
+* magit-branch-read-upstream-first: Branch Commands. (line 147)
+* magit-buffer-name-format: Naming Buffers. (line 25)
+* magit-bury-buffer-function: Quitting Windows. (line 13)
+* magit-cherry-margin: Cherries. (line 21)
+* magit-clone-always-transient: Cloning Repository. (line 12)
+* magit-clone-default-directory: Cloning Repository. (line 84)
+* magit-clone-name-alist: Cloning Repository. (line 94)
+* magit-clone-set-remote-head: Cloning Repository. (line 66)
+* magit-clone-set-remote.pushDefault: Cloning Repository. (line 75)
+* magit-clone-url-format: Cloning Repository. (line 114)
+* magit-commit-ask-to-stage: Initiating a Commit. (line 65)
+* magit-commit-diff-inhibit-same-window: Initiating a Commit. (line 97)
+* magit-commit-extend-override-date: Initiating a Commit. (line 72)
+* magit-commit-reword-override-date: Initiating a Commit. (line 75)
+* magit-commit-show-diff: Initiating a Commit. (line 69)
+* magit-commit-squash-confirm: Initiating a Commit. (line 78)
+* magit-completing-read-function: Support for Completion Frameworks.
+ (line 27)
+* magit-define-global-key-bindings: Default Bindings. (line 6)
+* magit-diff-adjust-tab-width: Diff Options. (line 17)
+* magit-diff-buffer-file-locked: Commands for Buffers Visiting Files.
+ (line 55)
+* magit-diff-extra-stat-arguments: Diff Options. (line 112)
+* magit-diff-hide-trailing-cr-characters: Diff Options. (line 77)
+* magit-diff-highlight-hunk-region-functions: Diff Options. (line 80)
+* magit-diff-highlight-indentation: Diff Options. (line 63)
+* magit-diff-highlight-trailing: Diff Options. (line 59)
+* magit-diff-paint-whitespace: Diff Options. (line 38)
+* magit-diff-paint-whitespace-lines: Diff Options. (line 52)
+* magit-diff-refine-hunk: Diff Options. (line 6)
+* magit-diff-refine-ignore-whitespace: Diff Options. (line 13)
+* magit-diff-unmarked-lines-keep-foreground: Diff Options. (line 105)
+* magit-diff-visit-previous-blob: Visiting Files and Blobs from a Diff.
+ (line 38)
+* magit-direct-use-buffer-arguments: Transient Arguments and Buffer Variables.
+ (line 72)
+* magit-display-buffer-function: Switching Buffers. (line 25)
+* magit-display-buffer-noselect: Switching Buffers. (line 17)
+* magit-dwim-selection: Completion and Confirmation.
+ (line 42)
+* magit-ediff-dwim-show-on-hunks: Ediffing. (line 71)
+* magit-ediff-quit-hook: Ediffing. (line 84)
+* magit-ediff-show-stash-with-index: Ediffing. (line 78)
+* magit-generate-buffer-name-function: Naming Buffers. (line 6)
+* magit-git-debug: Viewing Git Output. (line 26)
+* magit-git-debug <1>: Getting a Value from Git.
+ (line 68)
+* magit-git-executable: Git Executable. (line 26)
+* magit-git-global-arguments: Global Git Arguments.
+ (line 6)
+* magit-keep-region-overlay: The Selection. (line 52)
+* magit-list-refs-sortby: Additional Completion Options.
+ (line 6)
+* magit-log-auto-more: Log Buffer. (line 69)
+* magit-log-buffer-file-locked: Commands for Buffers Visiting Files.
+ (line 78)
+* magit-log-margin: Log Margin. (line 12)
+* magit-log-margin-show-committer-date: Log Margin. (line 44)
+* magit-log-section-commit-count: Status Sections. (line 114)
+* magit-log-select-margin: Select from Log. (line 28)
+* magit-log-show-refname-after-summary: Log Buffer. (line 74)
+* magit-log-trace-definition-function: Commands Available in Diffs.
+ (line 17)
+* magit-module-sections-hook: Status Module Sections.
+ (line 19)
+* magit-module-sections-nested: Status Module Sections.
+ (line 22)
+* magit-no-confirm: Action Confirmation. (line 18)
+* magit-pop-revision-stack-format: Using the Revision Stack.
+ (line 34)
+* magit-post-commit-hook: Initiating a Commit. (line 86)
+* magit-post-display-buffer-hook: Switching Buffers. (line 85)
+* magit-pre-display-buffer-hook: Switching Buffers. (line 76)
+* magit-prefer-remote-upstream: Branch Git Variables.
+ (line 109)
+* magit-prefix-use-buffer-arguments: Transient Arguments and Buffer Variables.
+ (line 64)
+* magit-process-extreme-logging: Viewing Git Output. (line 56)
+* magit-process-raise-error: Calling Git for Effect.
+ (line 125)
+* magit-pull-or-fetch: Fetching. (line 51)
+* magit-reflog-margin: Reflog. (line 20)
+* magit-refresh-args: Refreshing Buffers. (line 52)
+* magit-refresh-buffer-hook: Automatic Refreshing of Magit Buffers.
+ (line 41)
+* magit-refresh-function: Refreshing Buffers. (line 47)
+* magit-refresh-status-buffer: Automatic Refreshing of Magit Buffers.
+ (line 46)
+* magit-refs-filter-alist: References Buffer. (line 137)
+* magit-refs-focus-column-width: References Buffer. (line 75)
+* magit-refs-margin: References Buffer. (line 89)
+* magit-refs-margin-for-tags: References Buffer. (line 112)
+* magit-refs-pad-commit-counts: References Buffer. (line 45)
+* magit-refs-primary-column-width: References Buffer. (line 63)
+* magit-refs-sections-hook: References Sections. (line 13)
+* magit-refs-show-commit-count: References Buffer. (line 36)
+* magit-refs-show-remote-prefix: References Buffer. (line 57)
+* magit-remote-add-set-remote.pushDefault: Remote Commands. (line 83)
+* magit-remote-direct-configure: Remote Commands. (line 20)
+* magit-remote-git-executable: Git Executable. (line 32)
+* magit-repolist-columns: Repository List. (line 13)
+* magit-repository-directories: Status Buffer. (line 57)
+* magit-revision-filter-files-on-follow: Revision Buffer. (line 55)
+* magit-revision-insert-related-refs: Revision Buffer. (line 6)
+* magit-revision-show-gravatars: Revision Buffer. (line 15)
+* magit-revision-use-hash-sections: Revision Buffer. (line 31)
+* magit-root-section: Matching Sections. (line 81)
+* magit-save-repository-buffers: Automatic Saving of File-Visiting Buffers.
+ (line 13)
+* magit-section-cache-visibility: Section Visibility. (line 82)
+* magit-section-initial-visibility-alist: Section Visibility. (line 66)
+* magit-section-movement-hook: Section Movement. (line 41)
+* magit-section-set-visibility-hook: Section Visibility. (line 92)
+* magit-section-show-child-count: Section Options. (line 9)
+* magit-section-visibility-indicator: Section Visibility. (line 109)
+* magit-shell-command-verbose-prompt: Running Git Manually.
+ (line 43)
+* magit-stashes-margin: Stashing. (line 87)
+* magit-status-headers-hook: Status Header Sections.
+ (line 17)
+* magit-status-margin: Status Options. (line 9)
+* magit-status-refresh-hook: Status Options. (line 6)
+* magit-status-sections-hook: Status Sections. (line 10)
+* magit-submodule-list-columns: Listing Submodules. (line 20)
+* magit-this-process: Calling Git for Effect.
+ (line 121)
+* magit-uniquify-buffer-names: Naming Buffers. (line 71)
+* magit-unstage-committed: Staging and Unstaging.
+ (line 52)
+* magit-update-other-window-delay: Section Movement. (line 97)
+* magit-visit-ref-behavior: References Buffer. (line 168)
+* magit-wip-after-apply-mode: Legacy Wip Modes. (line 18)
+* magit-wip-after-apply-mode-lighter: Legacy Wip Modes. (line 54)
+* magit-wip-after-save-local-mode-lighter: Legacy Wip Modes. (line 51)
+* magit-wip-after-save-mode: Legacy Wip Modes. (line 13)
+* magit-wip-before-change-mode: Legacy Wip Modes. (line 31)
+* magit-wip-before-change-mode-lighter: Legacy Wip Modes. (line 57)
+* magit-wip-initial-backup-mode: Legacy Wip Modes. (line 35)
+* magit-wip-initial-backup-mode-lighter: Legacy Wip Modes. (line 60)
+* magit-wip-merge-branch: Wip Graph. (line 6)
+* magit-wip-mode: Wip Modes. (line 30)
+* magit-wip-mode-lighter: Wip Modes. (line 98)
+* magit-wip-namespace: Wip Modes. (line 91)
+* notes.displayRef: Notes. (line 57)
+* pull.rebase: Branch Git Variables.
+ (line 50)
+* remote.NAME.fetch: Remote Git Variables.
+ (line 14)
+* remote.NAME.push: Remote Git Variables.
+ (line 23)
+* remote.NAME.pushurl: Remote Git Variables.
+ (line 18)
+* remote.NAME.tagOpts: Remote Git Variables.
+ (line 27)
+* remote.NAME.url: Remote Git Variables.
+ (line 10)
+* remote.pushDefault: Branch Git Variables.
+ (line 62)
+
+
+
+Tag Table:
+Node: Top754
+Node: Introduction6636
+Node: Installation11352
+Node: Installing from Melpa11682
+Node: Installing from the Git Repository12755
+Node: Post-Installation Tasks15487
+Node: Getting Started16772
+Node: Interface Concepts22104
+Node: Modes and Buffers22483
+Node: Switching Buffers24194
+Node: Naming Buffers28933
+Node: Quitting Windows32236
+Node: Automatic Refreshing of Magit Buffers33974
+Node: Automatic Saving of File-Visiting Buffers36855
+Node: Automatic Reverting of File-Visiting Buffers38039
+Node: Risk of Reverting Automatically43024
+Node: Sections45406
+Node: Section Movement46332
+Node: Section Visibility51206
+Node: Section Hooks57221
+Node: Section Types and Values59627
+Node: Section Options61042
+Node: Transient Commands61513
+Node: Transient Arguments and Buffer Variables62745
+Node: Completion Confirmation and the Selection69756
+Node: Action Confirmation70202
+Node: Completion and Confirmation78054
+Node: The Selection81239
+Node: The hunk-internal region84137
+Node: Support for Completion Frameworks85226
+Node: Additional Completion Options90129
+Node: Mouse Support90727
+Node: Running Git91303
+Node: Viewing Git Output91548
+Node: Git Process Status94252
+Node: Running Git Manually95217
+Node: Git Executable97907
+Node: Global Git Arguments100915
+Node: Inspecting101720
+Node: Status Buffer102877
+Node: Status Sections107887
+Node: Status Header Sections113414
+Node: Status Module Sections116033
+Node: Status Options118530
+Node: Repository List119993
+Node: Logging124560
+Node: Refreshing Logs127402
+Node: Log Buffer128823
+Node: Log Margin133023
+Node: Select from Log136176
+Node: Reflog138386
+Node: Cherries140023
+Node: Diffing141861
+Node: Refreshing Diffs144895
+Node: Commands Available in Diffs148404
+Node: Diff Options150918
+Node: Revision Buffer156381
+Node: Ediffing159701
+Node: References Buffer163655
+Node: References Sections174249
+Node: Bisecting175106
+Node: Visiting Files and Blobs177417
+Node: General-Purpose Visit Commands177887
+Node: Visiting Files and Blobs from a Diff178840
+Node: Blaming182284
+Node: Manipulating188419
+Node: Creating Repository188761
+Node: Cloning Repository189298
+Node: Staging and Unstaging194956
+Node: Staging from File-Visiting Buffers198937
+Node: Applying200043
+Node: Committing202116
+Node: Initiating a Commit202699
+Node: Editing Commit Messages207888
+Node: Using the Revision Stack210661
+Node: Commit Pseudo Headers213706
+Node: Commit Mode and Hooks215001
+Node: Commit Message Conventions217935
+Node: Branching220058
+Node: The Two Remotes220284
+Node: Branch Commands222937
+Node: Branch Git Variables235482
+Node: Auxiliary Branch Commands240855
+Node: Merging241971
+Node: Resolving Conflicts245929
+Node: Rebasing251300
+Node: Editing Rebase Sequences256089
+Node: Information About In-Progress Rebase260305
+Ref: Information About In-Progress Rebase-Footnote-1269418
+Node: Cherry Picking270014
+Node: Reverting274348
+Node: Resetting275767
+Node: Stashing277593
+Node: Transferring282204
+Node: Remotes282426
+Node: Remote Commands282578
+Node: Remote Git Variables286617
+Node: Fetching287888
+Node: Pulling290334
+Node: Pushing291360
+Node: Plain Patches295651
+Node: Maildir Patches297122
+Node: Miscellaneous298601
+Node: Tagging298947
+Node: Notes300840
+Node: Submodules303175
+Node: Listing Submodules303393
+Node: Submodule Transient305529
+Node: Subtree308006
+Node: Worktree309937
+Node: Sparse checkouts311013
+Node: Bundle313789
+Node: Common Commands314164
+Node: Wip Modes316792
+Node: Wip Graph321683
+Node: Legacy Wip Modes323996
+Node: Commands for Buffers Visiting Files326883
+Node: Minor Mode for Buffers Visiting Blobs332441
+Node: Customizing333239
+Node: Per-Repository Configuration334835
+Node: Essential Settings337089
+Node: Safety337434
+Node: Performance339195
+Ref: Log Performance342224
+Ref: Diff Performance343534
+Ref: Refs Buffer Performance344875
+Ref: Committing Performance345450
+Node: Microsoft Windows Performance346363
+Node: MacOS Performance347554
+Ref: MacOS Performance-Footnote-1348259
+Node: Default Bindings348341
+Node: Plumbing350582
+Node: Calling Git351411
+Node: Getting a Value from Git352936
+Node: Calling Git for Effect356664
+Node: Section Plumbing362558
+Node: Creating Sections362786
+Node: Section Selection366682
+Node: Matching Sections368478
+Node: Refreshing Buffers374399
+Node: Conventions377543
+Node: Theming Faces377735
+Node: FAQ385840
+Node: FAQ - How to ...?386278
+Node: How to pronounce Magit?386691
+Node: How to show git's output?387493
+Node: How to install the gitman info manual?388279
+Node: How to show diffs for gpg-encrypted files?389249
+Node: How does branching and pushing work?389845
+Node: Can Magit be used as ediff-version-control-package?390208
+Node: Should I disable VC?392226
+Node: FAQ - Issues and Errors392844
+Node: Magit is slow393845
+Node: I changed several thousand files at once and now Magit is unusable394059
+Node: I am having problems committing394788
+Node: I am using MS Windows and cannot push with Magit395269
+Node: I am using OS X and SOMETHING works in shell but not in Magit395886
+Node: Expanding a file to show the diff causes it to disappear396717
+Node: Point is wrong in the COMMIT_EDITMSG buffer397298
+Node: The mode-line information isn't always up-to-date398344
+Node: A branch and tag sharing the same name breaks SOMETHING399407
+Node: My Git hooks work on the command-line but not inside Magit400293
+Node: git-commit-mode isn't used when committing from the command-line401139
+Node: Point ends up inside invisible text when jumping to a file-visiting buffer403410
+Node: I am unable to stage when using Tramp from MS Windows404270
+Node: I am no longer able to save popup defaults405177
+Node: Debugging Tools406137
+Node: Keystroke Index409317
+Node: Function and Command Index443572
+Node: Variable Index495529
+
+End Tag Table
+
+
+Local Variables:
+coding: utf-8
+End:
diff --git a/elpa/magit-section-20220502.2245/dir b/elpa/magit-section-20220502.2245/dir
new file mode 100644
index 0000000..6e44681
--- /dev/null
+++ b/elpa/magit-section-20220502.2245/dir
@@ -0,0 +1,19 @@
+This is the file .../info/dir, which contains the
+topmost node of the Info hierarchy, called (dir)Top.
+The first time you invoke Info you start off looking at this node.
+
+File: dir, Node: Top This is the top of the INFO tree
+
+ This (the Directory node) gives a menu of major topics.
+ Typing "q" exits, "H" lists all Info commands, "d" returns here,
+ "h" gives a primer for first-timers,
+ "mEmacs<Return>" visits the Emacs manual, etc.
+
+ In Emacs, you can click mouse button 2 on a menu item or cross reference
+ to select it.
+
+* Menu:
+
+Emacs
+* Magit-Section: (magit-section).
+ Use Magit sections in your own packages.
diff --git a/elpa/magit-section-20220502.2245/magit-section-autoloads.el b/elpa/magit-section-20220502.2245/magit-section-autoloads.el
new file mode 100644
index 0000000..e31297d
--- /dev/null
+++ b/elpa/magit-section-20220502.2245/magit-section-autoloads.el
@@ -0,0 +1,26 @@
+;;; magit-section-autoloads.el --- automatically extracted autoloads -*- lexical-binding: t -*-
+;;
+;;; Code:
+
+(add-to-list 'load-path (directory-file-name
+ (or (file-name-directory #$) (car load-path))))
+
+
+;;;### (autoloads nil "magit-section" "magit-section.el" (0 0 0 0))
+;;; Generated autoloads from magit-section.el
+
+(register-definition-prefixes "magit-section" '("isearch-clean-overlays@magit-mode" "magit-"))
+
+;;;***
+
+;;;### (autoloads nil nil ("magit-section-pkg.el") (0 0 0 0))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; coding: utf-8
+;; End:
+;;; magit-section-autoloads.el ends here
diff --git a/elpa/magit-section-20220502.2245/magit-section-pkg.el b/elpa/magit-section-20220502.2245/magit-section-pkg.el
new file mode 100644
index 0000000..6ff99fd
--- /dev/null
+++ b/elpa/magit-section-20220502.2245/magit-section-pkg.el
@@ -0,0 +1,14 @@
+(define-package "magit-section" "20220502.2245" "Sections for read-only buffers."
+ '((emacs "25.1")
+ (compat "28.1.1.0")
+ (dash "20210826"))
+ :commit "476383fc8fb0f6ea4c6fc29d7057a1b5b5f95bd8" :authors
+ '(("Jonas Bernoulli" . "jonas@bernoul.li"))
+ :maintainer
+ '("Jonas Bernoulli" . "jonas@bernoul.li")
+ :keywords
+ '("tools")
+ :url "https://github.com/magit/magit")
+;; Local Variables:
+;; no-byte-compile: t
+;; End:
diff --git a/elpa/magit-section-20220502.2245/magit-section.el b/elpa/magit-section-20220502.2245/magit-section.el
new file mode 100644
index 0000000..239b3f4
--- /dev/null
+++ b/elpa/magit-section-20220502.2245/magit-section.el
@@ -0,0 +1,2202 @@
+;;; magit-section.el --- Sections for read-only buffers -*- lexical-binding:t -*-
+
+;; Copyright (C) 2008-2022 The Magit Project Contributors
+
+;; Author: Jonas Bernoulli <jonas@bernoul.li>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+
+;; Homepage: https://github.com/magit/magit
+;; Keywords: tools
+
+;; Package-Version: 3.3.0-git
+;; Package-Requires: ((emacs "25.1") (compat "28.1.1.0") (dash "2.19.1"))
+
+;; SPDX-License-Identifier: GPL-3.0-or-later
+
+;; Magit 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.
+;;
+;; Magit 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 Magit. If not, see <https://www.gnu.org/licenses/>.
+
+;; You should have received a copy of the AUTHORS.md file, which
+;; lists all contributors. If not, see https://magit.vc/authors.
+
+;;; Commentary:
+
+;; This package implements the main user interface of Magit — the
+;; collapsible sections that make up its buffers. This package used
+;; to be distributed as part of Magit but now it can also be used by
+;; other packages that have nothing to do with Magit or Git.
+
+;;; Code:
+
+(require 'cl-lib)
+(require 'compat)
+(require 'compat-26)
+(require 'compat-27)
+(require 'dash)
+(require 'eieio)
+(require 'format-spec)
+(require 'seq)
+(require 'subr-x)
+
+(eval-when-compile (require 'benchmark))
+
+(defvar magit-section-highlight-force-update)
+
+;;; Hooks
+
+(defvar magit-section-movement-hook nil
+ "Hook run by `magit-section-goto'.
+That function in turn is used by all section movement commands.")
+
+(defvar magit-section-highlight-hook
+ '(magit-section-highlight
+ magit-section-highlight-selection)
+ "Functions used to highlight the current section.
+Each function is run with the current section as only argument
+until one of them returns non-nil.")
+
+(defvar magit-section-unhighlight-hook nil
+ "Functions used to unhighlight the previously current section.
+Each function is run with the current section as only argument
+until one of them returns non-nil. Most sections are properly
+unhighlighted without requiring a specialized unhighlighter,
+diff-related sections being the only exception.")
+
+(defvar magit-section-set-visibility-hook
+ '(magit-section-cached-visibility)
+ "Hook used to set the initial visibility of a section.
+Stop at the first function that returns non-nil. The returned
+value should be `show', `hide' or nil. If no function returns
+non-nil, determine the visibility as usual, i.e. use the
+hardcoded section specific default (see `magit-insert-section').")
+
+(defvar magit-section-goto-successor-hook nil
+ "Hook used to go to the same section as was current before a refresh.
+This is only used if the standard mechanism for doing so did not
+succeed.")
+
+;;; Options
+
+(defgroup magit-section nil
+ "Expandable sections."
+ :link '(info-link "(magit)Sections")
+ :group 'extensions)
+
+(defcustom magit-section-show-child-count t
+ "Whether to append the number of children to section headings.
+This only applies to sections for which doing so makes sense."
+ :package-version '(magit-section . "2.1.0")
+ :group 'magit-section
+ :type 'boolean)
+
+(defcustom magit-section-cache-visibility t
+ "Whether to cache visibility of sections.
+
+Sections always retain their visibility state when they are being
+recreated during a refresh. But if a section disappears and then
+later reappears again, then this option controls whether this is
+the case.
+
+If t, then cache the visibility of all sections. If a list of
+section types, then only do so for matching sections. If nil,
+then don't do so for any sections."
+ :package-version '(magit-section . "2.12.0")
+ :group 'magit-section
+ :type '(choice (const :tag "Don't cache visibility" nil)
+ (const :tag "Cache visibility of all sections" t)
+ (repeat :tag "Cache visibility for section types" symbol)))
+
+(defcustom magit-section-initial-visibility-alist
+ '((stashes . hide))
+ "Alist controlling the initial visibility of sections.
+
+Each element maps a section type or lineage to the initial
+visibility state for such sections. The state has to be one of
+`show' or `hide', or a function that returns one of these symbols.
+A function is called with the section as the only argument.
+
+Use the command `magit-describe-section' to determine a section's
+lineage or type. The vector in the output is the section lineage
+and the type is the first element of that vector. Wildcards can
+be used, see `magit-section-match'.
+
+Currently this option is only used to override hardcoded defaults,
+but in the future it will also be used set the defaults.
+
+An entry whose key is `magit-status-initial-section' specifies
+the visibility of the section `magit-status-goto-initial-section'
+jumps to. This does not only override defaults, but also other
+entries of this alist."
+ :package-version '(magit-section . "2.12.0")
+ :group 'magit-section
+ :type '(alist :key-type (sexp :tag "Section type/lineage")
+ :value-type (choice (const hide)
+ (const show)
+ function)))
+
+(defcustom magit-section-visibility-indicator
+ (if (window-system)
+ '(magit-fringe-bitmap> . magit-fringe-bitmapv)
+ (cons (if (char-displayable-p ?…) "…" "...")
+ t))
+ "Whether and how to indicate that a section can be expanded/collapsed.
+
+If nil, then don't show any indicators.
+Otherwise the value has to have one of these two forms:
+
+\(EXPANDABLE-BITMAP . COLLAPSIBLE-BITMAP)
+
+ Both values have to be variables whose values are fringe
+ bitmaps. In this case every section that can be expanded or
+ collapsed gets an indicator in the left fringe.
+
+ To provide extra padding around the indicator, set
+ `left-fringe-width' in `magit-mode-hook'.
+
+\(STRING . BOOLEAN)
+
+ In this case STRING (usually an ellipsis) is shown at the end
+ of the heading of every collapsed section. Expanded sections
+ get no indicator. The cdr controls whether the appearance of
+ these ellipsis take section highlighting into account. Doing
+ so might potentially have an impact on performance, while not
+ doing so is kinda ugly."
+ :package-version '(magit-section . "3.0.0")
+ :group 'magit-section
+ :type '(choice (const :tag "No indicators" nil)
+ (cons :tag "Use +- fringe indicators"
+ (const magit-fringe-bitmap+)
+ (const magit-fringe-bitmap-))
+ (cons :tag "Use >v fringe indicators"
+ (const magit-fringe-bitmap>)
+ (const magit-fringe-bitmapv))
+ (cons :tag "Use bold >v fringe indicators)"
+ (const magit-fringe-bitmap-bold>)
+ (const magit-fringe-bitmap-boldv))
+ (cons :tag "Use custom fringe indicators"
+ (variable :tag "Expandable bitmap variable")
+ (variable :tag "Collapsible bitmap variable"))
+ (cons :tag "Use ellipses at end of headings"
+ (string :tag "Ellipsis" "…")
+ (choice :tag "Use face kludge"
+ (const :tag "Yes (potentially slow)" t)
+ (const :tag "No (kinda ugly)" nil)))))
+
+(define-obsolete-variable-alias 'magit-keep-region-overlay
+ 'magit-section-keep-region-overlay "Magit-Section 3.4.0")
+(defcustom magit-section-keep-region-overlay nil
+ "Whether to keep the region overlay when there is a valid selection.
+
+By default Magit removes the regular region overlay if, and only
+if, that region constitutes a valid selection as understood by
+Magit commands. Otherwise it does not remove that overlay, and
+the region looks like it would in other buffers.
+
+There are two types of such valid selections: hunk-internal
+regions and regions that select two or more sibling sections.
+In such cases Magit removes the region overlay and instead
+highlights a slightly larger range. All text (for hunk-internal
+regions) or the headings of all sections (for sibling selections)
+that are inside that range (not just inside the region) are acted
+on by commands such as the staging command. This buffer range
+begins at the beginning of the line on which the region begins
+and ends at the end of the line on which the region ends.
+
+Because Magit acts on this larger range and not the region, it is
+actually quite important to visualize that larger range. If we
+don't do that, then one might think that these commands act on
+the region instead. If you want to *also* visualize the region,
+then set this option to t. But please note that when the region
+does *not* constitute a valid selection, then the region is
+*always* visualized as usual, and that it is usually under such
+circumstances that you want to use a non-magit command to act on
+the region.
+
+Besides keeping the region overlay, setting this option to t also
+causes all face properties, except for `:foreground', to be
+ignored for the faces used to highlight headings of selected
+sections. This avoids the worst conflicts that result from
+displaying the region and the selection overlays at the same
+time. We are not interested in dealing with other conflicts.
+In fact we *already* provide a way to avoid all of these
+conflicts: *not* changing the value of this option.
+
+It should be clear by now that we consider it a mistake to set
+this to display the region when the Magit selection is also
+visualized, but since it has been requested a few times and
+because it doesn't cost much to offer this option we do so.
+However that might change. If the existence of this option
+starts complicating other things, then it will be removed."
+ :package-version '(magit-section . "2.3.0")
+ :group 'magit-section
+ :type 'boolean)
+
+(defcustom magit-section-disable-line-numbers t
+ "In Magit buffers, whether to disable modes that display line numbers.
+
+Some users who turn on `global-display-line-numbers-mode' (or
+`global-nlinum-mode' or `global-linum-mode') expect line numbers
+to be displayed everywhere except in Magit buffers. Other users
+do not expect Magit buffers to be treated differently. At least
+in theory users in the first group should not use the global mode,
+but that ship has sailed, thus this option."
+ :package-version '(magit-section . "3.0.0")
+ :group 'magit-section
+ :type 'boolean)
+
+(defcustom magit-section-show-context-menu-for-emacs<28 nil
+ "Whether `mouse-3' shows a context menu for Emacs < 28.
+
+This has to be set before loading `magit-section' or it has
+no effect. This also has no effect for Emacs >= 28, where
+`context-menu-mode' should be enabled instead."
+ :package-version '(magit-section . "3.4.0")
+ :group 'magit-section
+ :type 'boolean)
+
+;;; Faces
+
+(defgroup magit-section-faces nil
+ "Faces used by Magit-Section."
+ :group 'magit-section
+ :group 'faces)
+
+(defface magit-section-highlight
+ `((((class color) (background light))
+ ,@(and (>= emacs-major-version 27) '(:extend t))
+ :background "grey95")
+ (((class color) (background dark))
+ ,@(and (>= emacs-major-version 27) '(:extend t))
+ :background "grey20"))
+ "Face for highlighting the current section."
+ :group 'magit-section-faces)
+
+(defface magit-section-heading
+ `((((class color) (background light))
+ ,@(and (>= emacs-major-version 27) '(:extend t))
+ :foreground "DarkGoldenrod4"
+ :weight bold)
+ (((class color) (background dark))
+ ,@(and (>= emacs-major-version 27) '(:extend t))
+ :foreground "LightGoldenrod2"
+ :weight bold))
+ "Face for section headings."
+ :group 'magit-section-faces)
+
+(defface magit-section-secondary-heading
+ `((t ,@(and (>= emacs-major-version 27) '(:extend t))
+ :weight bold))
+ "Face for section headings of some secondary headings."
+ :group 'magit-section-faces)
+
+(defface magit-section-heading-selection
+ `((((class color) (background light))
+ ,@(and (>= emacs-major-version 27) '(:extend t))
+ :foreground "salmon4")
+ (((class color) (background dark))
+ ,@(and (>= emacs-major-version 27) '(:extend t))
+ :foreground "LightSalmon3"))
+ "Face for selected section headings."
+ :group 'magit-section-faces)
+
+(defface magit-section-child-count '((t nil))
+ "Face used for child counts at the end of some section headings."
+ :group 'magit-section-faces)
+
+;;; Classes
+
+(defvar magit--current-section-hook nil
+ "Internal variable used for `magit-describe-section'.")
+
+(defvar magit--section-type-alist nil)
+
+(defclass magit-section ()
+ ((keymap :initform nil)
+ (type :initform nil :initarg :type)
+ (value :initform nil :initarg :value)
+ (start :initform nil :initarg :start)
+ (content :initform nil)
+ (end :initform nil)
+ (hidden :initform nil)
+ (washer :initform nil)
+ (process :initform nil)
+ (heading-highlight-face :initform nil)
+ (inserter :initform (symbol-value 'magit--current-section-hook))
+ (parent :initform nil :initarg :parent)
+ (children :initform nil)))
+
+;;; Mode
+
+(defvar symbol-overlay-inhibit-map)
+
+(defvar magit-section-heading-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map [double-down-mouse-1] #'ignore)
+ (define-key map [double-mouse-1] #'magit-mouse-toggle-section)
+ (define-key map [double-mouse-2] #'magit-mouse-toggle-section)
+ map)
+ "Keymap used in the heading line of all expandable sections.
+This keymap is used in addition to the section-specifi keymap,
+if any.")
+
+(defvar magit-section-mode-map
+ (let ((map (make-keymap)))
+ (suppress-keymap map t)
+ (when (and magit-section-show-context-menu-for-emacs<28
+ (< emacs-major-version 28))
+ (define-key map [mouse-3] nil)
+ (define-key
+ map [down-mouse-3]
+ `( menu-item "" ,(make-sparse-keymap)
+ :filter ,(lambda (_)
+ (let ((menu (make-sparse-keymap)))
+ (if (fboundp 'context-menu-local)
+ (context-menu-local menu last-input-event)
+ (magit--context-menu-local menu last-input-event))
+ (magit-section-context-menu menu last-input-event)
+ menu)))))
+ (define-key map [left-fringe mouse-1] #'magit-mouse-toggle-section)
+ (define-key map [left-fringe mouse-2] #'magit-mouse-toggle-section)
+ (define-key map (kbd "TAB") #'magit-section-toggle)
+ (define-key map [C-tab] #'magit-section-cycle)
+ (define-key map [M-tab] #'magit-section-cycle)
+ ;; [backtab] is the most portable binding for Shift+Tab.
+ (define-key map [backtab] #'magit-section-cycle-global)
+ (define-key map (kbd "^") #'magit-section-up)
+ (define-key map (kbd "p") #'magit-section-backward)
+ (define-key map (kbd "n") #'magit-section-forward)
+ (define-key map (kbd "M-p") #'magit-section-backward-sibling)
+ (define-key map (kbd "M-n") #'magit-section-forward-sibling)
+ (define-key map (kbd "1") #'magit-section-show-level-1)
+ (define-key map (kbd "2") #'magit-section-show-level-2)
+ (define-key map (kbd "3") #'magit-section-show-level-3)
+ (define-key map (kbd "4") #'magit-section-show-level-4)
+ (define-key map (kbd "M-1") #'magit-section-show-level-1-all)
+ (define-key map (kbd "M-2") #'magit-section-show-level-2-all)
+ (define-key map (kbd "M-3") #'magit-section-show-level-3-all)
+ (define-key map (kbd "M-4") #'magit-section-show-level-4-all)
+ map)
+ "Parent keymap for all keymaps of modes derived from `magit-section-mode'.")
+
+(define-derived-mode magit-section-mode special-mode "Magit-Sections"
+ "Parent major mode from which major modes with Magit-like sections inherit.
+
+Magit-Section is documented in info node `(magit-section)'."
+ :group 'magit-section
+ (buffer-disable-undo)
+ (setq truncate-lines t)
+ (setq buffer-read-only t)
+ (setq-local line-move-visual t) ; see #1771
+ ;; Turn off syntactic font locking, but not by setting
+ ;; `font-lock-defaults' because that would enable font locking, and
+ ;; not all magit plugins may be ready for that (see #3950).
+ (setq-local font-lock-syntactic-face-function #'ignore)
+ (setq show-trailing-whitespace nil)
+ (setq-local symbol-overlay-inhibit-map t)
+ (setq list-buffers-directory (abbreviate-file-name default-directory))
+ ;; (hack-dir-local-variables-non-file-buffer)
+ (make-local-variable 'text-property-default-nonsticky)
+ (push (cons 'keymap t) text-property-default-nonsticky)
+ (add-hook 'pre-command-hook #'magit-section-pre-command-hook nil t)
+ (add-hook 'post-command-hook #'magit-section-post-command-hook t t)
+ (add-hook 'deactivate-mark-hook #'magit-section-deactivate-mark t t)
+ (setq-local redisplay-highlight-region-function
+ #'magit-section--highlight-region)
+ (setq-local redisplay-unhighlight-region-function
+ #'magit-section--unhighlight-region)
+ (when (fboundp 'magit-section-context-menu)
+ (add-hook 'context-menu-functions #'magit-section-context-menu 10 t))
+ (when magit-section-disable-line-numbers
+ (when (bound-and-true-p global-linum-mode)
+ (linum-mode -1))
+ (when (and (fboundp 'nlinum-mode)
+ (bound-and-true-p global-nlinum-mode))
+ (nlinum-mode -1))
+ (when (and (fboundp 'display-line-numbers-mode)
+ (bound-and-true-p global-display-line-numbers-mode))
+ (display-line-numbers-mode -1)))
+ (when (fboundp 'magit-preserve-section-visibility-cache)
+ (add-hook 'kill-buffer-hook #'magit-preserve-section-visibility-cache)))
+
+;;; Core
+
+(defvar-local magit-root-section nil
+ "The root section in the current buffer.
+All other sections are descendants of this section. The value
+of this variable is set by `magit-insert-section' and you should
+never modify it.")
+(put 'magit-root-section 'permanent-local t)
+
+(defvar-local magit--context-menu-section nil "For internal use only.")
+
+(defvar magit--context-menu-buffer nil "For internal use only.")
+
+(defun magit-point ()
+ "Return point or the position where the context menu was invoked.
+When using the context menu, return the position the user clicked
+on, provided the current buffer is the buffer in which the click
+occurred. Otherwise return the same value as `point'."
+ (if magit--context-menu-section
+ (magit-menu-position)
+ (point)))
+
+(defun magit-thing-at-point (thing &optional no-properties)
+ "Return the THING at point or where the context menu was invoked.
+When using the context menu, return the thing the user clicked
+on, provided the current buffer is the buffer in which the click
+occurred. Otherwise return the same value as `thing-at-point'.
+For the meaning of THING and NO-PROPERTIES see that function."
+ (if-let ((pos (magit-menu-position)))
+ (save-excursion
+ (goto-char pos)
+ (thing-at-point thing no-properties))
+ (thing-at-point thing no-properties)))
+
+(defun magit-current-section ()
+ "Return the section at point or where the context menu was invoked.
+When using the context menu, return the section that the user
+clicked on, provided the current buffer is the buffer in which
+the click occurred. Otherwise return the section at point."
+ (or magit--context-menu-section
+ (magit-section-at)
+ magit-root-section))
+
+(defun magit-section-at (&optional position)
+ "Return the section at POSITION, defaulting to point."
+ (get-text-property (or position (point)) 'magit-section))
+
+(defun magit-section-ident (section)
+ "Return an unique identifier for SECTION.
+The return value has the form ((TYPE . VALUE)...)."
+ (cons (cons (oref section type)
+ (magit-section-ident-value section))
+ (and-let* ((parent (oref section parent)))
+ (magit-section-ident parent))))
+
+(cl-defgeneric magit-section-ident-value (object)
+ "Return OBJECT's value, making it constant and unique if necessary.
+
+This is used to correlate different incarnations of the same
+section, see `magit-section-ident' and `magit-get-section'.
+
+Sections whose values that are not constant and/or unique should
+implement a method that return a value that can be used for this
+purpose.")
+
+(cl-defmethod magit-section-ident-value ((section magit-section))
+ "Return the value unless it is an object.
+
+Different object incarnations representing the same value then to
+not be equal, so call this generic function on the object itself
+to determine a constant value."
+ (let ((value (oref section value)))
+ (if (eieio-object-p value)
+ (magit-section-ident-value value)
+ value)))
+
+(cl-defmethod magit-section-ident-value ((object eieio-default-superclass))
+ "Simply return the object itself. That likely isn't
+good enough, so you need to implement your own method."
+ object)
+
+(defun magit-get-section (ident &optional root)
+ "Return the section identified by IDENT.
+IDENT has to be a list as returned by `magit-section-ident'.
+If optional ROOT is non-nil, then search in that section tree
+instead of in the one whose root `magit-root-section' is."
+ (setq ident (reverse ident))
+ (let ((section (or root magit-root-section)))
+ (when (eq (car (pop ident))
+ (oref section type))
+ (while (and ident
+ (pcase-let ((`(,type . ,value) (car ident)))
+ (setq section
+ (cl-find-if
+ (lambda (section)
+ (and (eq (oref section type) type)
+ (equal (magit-section-ident-value section)
+ value)))
+ (oref section children)))))
+ (pop ident))
+ section)))
+
+(defun magit-section-lineage (section)
+ "Return the lineage of SECTION.
+The return value has the form (TYPE...)."
+ (cons (oref section type)
+ (and-let* ((parent (oref section parent)))
+ (magit-section-lineage parent))))
+
+(defvar magit-insert-section--current nil "For internal use only.")
+(defvar magit-insert-section--parent nil "For internal use only.")
+(defvar magit-insert-section--oldroot nil "For internal use only.")
+
+;;; Menu
+
+(defvar magit-menu-common-value nil "See function `magit-menu-common-value'.")
+(defvar magit-menu--desc-values nil "For internal use only.")
+
+(defun magit-section-context-menu (menu click)
+ "Populate MENU with Magit-Section commands at CLICK."
+ (when-let ((section (save-excursion
+ (unless (region-active-p)
+ (mouse-set-point click))
+ (magit-section-at))))
+ (unless (region-active-p)
+ (setq magit--context-menu-buffer (current-buffer))
+ (if-let ((alt (save-excursion
+ (mouse-set-point click)
+ (run-hook-with-args-until-success
+ 'magit-menu-alternative-section-hook section))))
+ (setq magit--context-menu-section (setq section alt))
+ (setq magit--context-menu-section section)
+ (magit-section-update-highlight t)))
+ (when (magit-section-content-p section)
+ (define-key-after menu [magit-section-toggle]
+ `(menu-item
+ ,(if (oref section hidden) "Expand section" "Collapse section")
+ magit-section-toggle))
+ (unless (oref section hidden)
+ (when-let ((children (oref section children)))
+ (when (seq-some #'magit-section-content-p children)
+ (when (seq-some (lambda (c) (oref c hidden)) children)
+ (define-key-after menu [magit-section-show-children]
+ `(menu-item "Expand children"
+ magit-section-show-children)))
+ (when (seq-some (lambda (c) (not (oref c hidden))) children)
+ (define-key-after menu [magit-section-hide-children]
+ `(menu-item "Collapse children"
+ magit-section-hide-children))))))
+ (define-key-after menu [separator-magit-1] menu-bar-separator))
+ (define-key-after menu [magit-describe-section]
+ `(menu-item "Describe section" magit-describe-section))
+ (when-let ((map (oref section keymap)))
+ (define-key-after menu [separator-magit-2] menu-bar-separator)
+ (when (symbolp map)
+ (setq map (symbol-value map)))
+ (setq magit-menu-common-value (magit-menu-common-value section))
+ (setq magit-menu--desc-values (magit-menu--desc-values section))
+ (map-keymap (lambda (key binding)
+ (when (consp binding)
+ (define-key-after menu (vector key)
+ (copy-sequence binding))))
+ (if (fboundp 'menu-bar-keymap)
+ (menu-bar-keymap map)
+ (magit--menu-bar-keymap map)))))
+ menu)
+
+(defun magit-menu-set (keymap key def desc &optional props after)
+ "In KEYMAP, define KEY and a menu entry for DEF.
+
+Add the menu item (menu-item DESC DEF . PROPS) at the end of
+KEYMAP, or if optional AFTER is non-nil, then after that.
+
+Because it is so common, and would otherwise result in overlong
+lines or else unsightly line wrapping, a definition [remap CMD]
+can be written as just [CMD]. As a result KEY might have to be
+a string when otherwise a vector would have worked.
+
+If DESC is a string that contains a support %-spec, substitute
+the expression (magit-menu-format-desc DESC) for that. See
+`magit-menu-format-desc'."
+ (declare (indent defun))
+ (when (vectorp key)
+ ;; Expand the short-hand.
+ (unless (eq (aref key 0) 'remap)
+ (setq key (vconcat [remap] key)))
+ ;; The default binding is RET, but in my configuration it
+ ;; is <return>. In that case the displayed binding would
+ ;; be <CMD> instead of <return>, for unknown reasons. The
+ ;; same does not happen for similar events, such as <tab>.
+ (when (and (equal key [remap magit-visit-thing])
+ (boundp 'magit-mode-map)
+ (ignore-errors (eq (lookup-key magit-mode-map [return])
+ 'magit-visit-thing)))
+ (setq key [return]))
+ ;; `define-key-after' cannot deal with [remap CMD],
+ ;; so we have to add the key binding separately.
+ (define-key keymap key def)
+ (unless (symbolp def)
+ (error "When KEY is a remapping, then DEF must be a symbol: %s" def))
+ (setq key (vector def)))
+ (when (and (stringp desc) (string-match-p "%[tTvsmMx]" desc))
+ (setq desc (list 'magit-menu-format-desc desc)))
+ (define-key-after keymap key
+ `( menu-item ,desc ,def ,@props
+ ;; Without this, the keys for point would be shown instead
+ ;; of the relevant ones from where the click occurred.
+ ,@(and (not (region-active-p))
+ (list :keys
+ (lambda ()
+ (or (ignore-errors
+ (save-excursion
+ (goto-char (magit-menu-position))
+ (key-description (where-is-internal def nil t))))
+ "")))))
+ after))
+
+(defun magit-menu-position ()
+ "Return the position where the context-menu was invoked.
+If the current command wasn't invoked using the context-menu,
+then return nil."
+ (and magit--context-menu-section
+ (ignore-errors
+ (posn-point (event-start (aref (this-command-keys-vector) 0))))))
+
+(defun magit-menu-highlight-point-section ()
+ (setq magit-section-highlight-force-update t)
+ (if (eq (current-buffer) magit--context-menu-buffer)
+ (setq magit--context-menu-section nil)
+ (if-let ((window (get-buffer-window magit--context-menu-buffer)))
+ (with-selected-window window
+ (setq magit--context-menu-section nil)
+ (magit-section-update-highlight))
+ (with-current-buffer magit--context-menu-buffer
+ (setq magit--context-menu-section nil))))
+ (setq magit--context-menu-buffer nil))
+
+(defvar magit--plural-append-es '(branch))
+
+(cl-defgeneric magit-menu-common-value (_section)
+ "Return some value to be used by multiple menu items.
+This function is called by `magit-section-context-menu', which
+stores the value in `magit-menu-common-value'. Individual menu
+items can use it, e.g., in the expression used to set their
+description."
+ nil)
+
+(defun magit-menu--desc-values (section)
+ (let ((type (oref section type))
+ (value (oref section value))
+ (multiple (magit-region-sections nil t)))
+ (list type
+ value
+ (format "%s %s" type value)
+ (and multiple (length multiple))
+ (if (memq type magit--plural-append-es) "es" "s"))))
+
+(defun magit-menu-format-desc (format)
+ "Format a string based on FORMAT and menu section or selection.
+The following %-specs are allowed:
+%t means \"TYPE\".
+%T means \"TYPE\", or \"TYPEs\" if multiple sections are selected.
+%v means \"VALUE\".
+%s means \"TYPE VALUE\".
+%m means \"TYPE VALUE\", or \"COUNT TYPEs\" if multiple sections
+ are selected.
+%M means \"VALUE\", or \"COUNT TYPEs\" if multiple sections are
+ selected.
+%x means the value of `magit-menu-common-value'."
+ (pcase-let* ((`(,type ,value ,single ,count ,suffix) magit-menu--desc-values)
+ (multiple (and count (format "%s %s%s" count type suffix))))
+ (format-spec format
+ `((?t . ,type)
+ (?T . ,(format "%s%s" type (if count suffix "")))
+ (?v . ,value)
+ (?s . ,single)
+ (?m . ,(or multiple single))
+ (?M . ,(or multiple value))
+ (?x . ,(format "%s" magit-menu-common-value))))))
+
+(defun magit--menu-bar-keymap (keymap)
+ "Backport of `menu-bar-keymap' for Emacs < 28.
+Slight trimmed down."
+ (let ((menu-bar nil))
+ (map-keymap (lambda (key binding)
+ (push (cons key binding) menu-bar))
+ keymap)
+ (cons 'keymap (nreverse menu-bar))))
+
+(defun magit--context-menu-local (menu _click)
+ "Backport of `context-menu-local' for Emacs < 28."
+ (run-hooks 'activate-menubar-hook 'menu-bar-update-hook)
+ (define-key-after menu [separator-local] menu-bar-separator)
+ (let ((keymap (local-key-binding [menu-bar])))
+ (when keymap
+ (map-keymap (lambda (key binding)
+ (when (consp binding)
+ (define-key-after menu (vector key)
+ (copy-sequence binding))))
+ (magit--menu-bar-keymap keymap))))
+ menu)
+
+(advice-add 'context-menu-region :around
+ (lambda (fn menu click)
+ "Disable in `magit-section-mode' buffers."
+ (if (derived-mode-p 'magit-section-mode)
+ menu
+ (funcall fn menu click))))
+
+;;; Commands
+;;;; Movement
+
+(defun magit-section-forward ()
+ "Move to the beginning of the next visible section."
+ (interactive)
+ (if (eobp)
+ (user-error "No next section")
+ (let ((section (magit-current-section)))
+ (if (oref section parent)
+ (let ((next (and (not (oref section hidden))
+ (not (= (oref section end)
+ (1+ (point))))
+ (car (oref section children)))))
+ (while (and section (not next))
+ (unless (setq next (car (magit-section-siblings section 'next)))
+ (setq section (oref section parent))))
+ (if next
+ (magit-section-goto next)
+ (user-error "No next section")))
+ (magit-section-goto 1)))))
+
+(defun magit-section-backward ()
+ "Move to the beginning of the current or the previous visible section.
+When point is at the beginning of a section then move to the
+beginning of the previous visible section. Otherwise move to
+the beginning of the current section."
+ (interactive)
+ (if (bobp)
+ (user-error "No previous section")
+ (let ((section (magit-current-section)) children)
+ (cond
+ ((and (= (point)
+ (1- (oref section end)))
+ (setq children (oref section children)))
+ (magit-section-goto (car (last children))))
+ ((and (oref section parent)
+ (not (= (point)
+ (oref section start))))
+ (magit-section-goto section))
+ (t
+ (let ((prev (car (magit-section-siblings section 'prev))))
+ (if prev
+ (while (and (not (oref prev hidden))
+ (setq children (oref prev children)))
+ (setq prev (car (last children))))
+ (setq prev (oref section parent)))
+ (cond (prev
+ (magit-section-goto prev))
+ ((oref section parent)
+ (user-error "No previous section"))
+ ;; Eob special cases.
+ ((not (get-text-property (1- (point)) 'invisible))
+ (magit-section-goto -1))
+ (t
+ (goto-char (previous-single-property-change
+ (1- (point)) 'invisible))
+ (forward-line -1)
+ (magit-section-goto (magit-current-section))))))))))
+
+(defun magit-section-up ()
+ "Move to the beginning of the parent section."
+ (interactive)
+ (--if-let (oref (magit-current-section) parent)
+ (magit-section-goto it)
+ (user-error "No parent section")))
+
+(defun magit-section-forward-sibling ()
+ "Move to the beginning of the next sibling section.
+If there is no next sibling section, then move to the parent."
+ (interactive)
+ (let ((current (magit-current-section)))
+ (if (oref current parent)
+ (--if-let (car (magit-section-siblings current 'next))
+ (magit-section-goto it)
+ (magit-section-forward))
+ (magit-section-goto 1))))
+
+(defun magit-section-backward-sibling ()
+ "Move to the beginning of the previous sibling section.
+If there is no previous sibling section, then move to the parent."
+ (interactive)
+ (let ((current (magit-current-section)))
+ (if (oref current parent)
+ (--if-let (car (magit-section-siblings current 'prev))
+ (magit-section-goto it)
+ (magit-section-backward))
+ (magit-section-goto -1))))
+
+(defun magit-section-goto (arg)
+ (if (integerp arg)
+ (progn (forward-line arg)
+ (setq arg (magit-current-section)))
+ (goto-char (oref arg start)))
+ (run-hook-with-args 'magit-section-movement-hook arg))
+
+(defun magit-section-set-window-start (section)
+ "Ensure the beginning of SECTION is visible."
+ (unless (pos-visible-in-window-p (oref section end))
+ (set-window-start (selected-window) (oref section start))))
+
+(defmacro magit-define-section-jumper (name heading type &optional value)
+ "Define an interactive function to go some section.
+Together TYPE and VALUE identify the section.
+HEADING is the displayed heading of the section."
+ (declare (indent defun))
+ `(defun ,name (&optional expand) ,(format "\
+Jump to the section \"%s\".
+With a prefix argument also expand it." heading)
+ (interactive "P")
+ (--if-let (magit-get-section
+ (cons (cons ',type ,value)
+ (magit-section-ident magit-root-section)))
+ (progn (goto-char (oref it start))
+ (when expand
+ (with-local-quit (magit-section-show it))
+ (recenter 0)))
+ (message ,(format "Section \"%s\" wasn't found" heading)))))
+
+;;;; Visibility
+
+(defun magit-section-show (section)
+ "Show the body of the current section."
+ (interactive (list (magit-current-section)))
+ (oset section hidden nil)
+ (magit-section--maybe-wash section)
+ (when-let ((beg (oref section content)))
+ (remove-overlays beg (oref section end) 'invisible t))
+ (magit-section-maybe-update-visibility-indicator section)
+ (magit-section-maybe-cache-visibility section)
+ (dolist (child (oref section children))
+ (if (oref child hidden)
+ (magit-section-hide child)
+ (magit-section-show child))))
+
+(defun magit-section--maybe-wash (section)
+ (when-let ((washer (oref section washer)))
+ (oset section washer nil)
+ (let ((inhibit-read-only t)
+ (magit-insert-section--parent section)
+ (content (oref section content)))
+ (save-excursion
+ (if (and content (< content (oref section end)))
+ (funcall washer section) ; already partially washed (hunk)
+ (goto-char (oref section end))
+ (oset section content (point-marker))
+ (funcall washer)
+ (oset section end (point-marker)))))
+ (setq magit-section-highlight-force-update t)))
+
+(defun magit-section-hide (section)
+ "Hide the body of the current section."
+ (interactive (list (magit-current-section)))
+ (if (eq section magit-root-section)
+ (user-error "Cannot hide root section")
+ (oset section hidden t)
+ (when-let ((beg (oref section content)))
+ (let ((end (oref section end)))
+ (when (< beg (point) end)
+ (goto-char (oref section start)))
+ (remove-overlays beg end 'invisible t)
+ (let ((o (make-overlay beg end)))
+ (overlay-put o 'evaporate t)
+ (overlay-put o 'invisible t))))
+ (magit-section-maybe-update-visibility-indicator section)
+ (magit-section-maybe-cache-visibility section)))
+
+(defun magit-section-toggle (section)
+ "Toggle visibility of the body of the current section."
+ (interactive (list (magit-current-section)))
+ (cond ((eq section magit-root-section)
+ (user-error "Cannot hide root section"))
+ ((oref section hidden)
+ (magit-section-show section))
+ (t (magit-section-hide section))))
+
+(defun magit-section-toggle-children (section)
+ "Toggle visibility of bodies of children of the current section."
+ (interactive (list (magit-current-section)))
+ (let* ((children (oref section children))
+ (show (--any-p (oref it hidden) children)))
+ (dolist (c children)
+ (oset c hidden show)))
+ (magit-section-show section))
+
+(defun magit-section-show-children (section &optional depth)
+ "Recursively show the bodies of children of the current section.
+With a prefix argument show children that deep and hide deeper
+children."
+ (interactive (list (magit-current-section)))
+ (magit-section-show-children-1 section depth)
+ (magit-section-show section))
+
+(defun magit-section-show-children-1 (section &optional depth)
+ (dolist (child (oref section children))
+ (oset child hidden nil)
+ (if depth
+ (if (> depth 0)
+ (magit-section-show-children-1 child (1- depth))
+ (magit-section-hide child))
+ (magit-section-show-children-1 child))))
+
+(defun magit-section-hide-children (section)
+ "Recursively hide the bodies of children of the current section."
+ (interactive (list (magit-current-section)))
+ (mapc #'magit-section-hide (oref section children)))
+
+(defun magit-section-show-headings (section)
+ "Recursively show headings of children of the current section.
+Only show the headings, previously shown text-only bodies are
+hidden."
+ (interactive (list (magit-current-section)))
+ (magit-section-show-headings-1 section)
+ (magit-section-show section))
+
+(defun magit-section-show-headings-1 (section)
+ (dolist (child (oref section children))
+ (oset child hidden nil)
+ (when (or (oref child children)
+ (not (oref child content)))
+ (magit-section-show-headings-1 child))))
+
+(defun magit-section-cycle (section)
+ "Cycle visibility of current section and its children."
+ (interactive (list (magit-current-section)))
+ (if (oref section hidden)
+ (progn (magit-section-show section)
+ (magit-section-hide-children section))
+ (let ((children (oref section children)))
+ (cond ((and (--any-p (oref it hidden) children)
+ (--any-p (oref it children) children))
+ (magit-section-show-headings section))
+ ((seq-some #'magit-section-hidden-body children)
+ (magit-section-show-children section))
+ (t
+ (magit-section-hide section))))))
+
+(defun magit-section-cycle-global ()
+ "Cycle visibility of all sections in the current buffer."
+ (interactive)
+ (let ((children (oref magit-root-section children)))
+ (cond ((and (--any-p (oref it hidden) children)
+ (--any-p (oref it children) children))
+ (magit-section-show-headings magit-root-section))
+ ((seq-some #'magit-section-hidden-body children)
+ (magit-section-show-children magit-root-section))
+ (t
+ (mapc #'magit-section-hide children)))))
+
+(defun magit-section-hidden-body (section &optional pred)
+ (--if-let (oref section children)
+ (funcall (or pred #'-any-p) #'magit-section-hidden-body it)
+ (and (oref section content)
+ (oref section hidden))))
+
+(defun magit-section-content-p (section)
+ "Return non-nil if SECTION has content or an unused washer function."
+ (with-slots (content end washer) section
+ (and content (or (not (= content end)) washer))))
+
+(defun magit-section-invisible-p (section)
+ "Return t if the SECTION's body is invisible.
+When the body of an ancestor of SECTION is collapsed then
+SECTION's body (and heading) obviously cannot be visible."
+ (or (oref section hidden)
+ (and-let* ((parent (oref section parent)))
+ (magit-section-invisible-p parent))))
+
+(defun magit-section-show-level (level)
+ "Show surrounding sections up to LEVEL.
+If LEVEL is negative, show up to the absolute value.
+Sections at higher levels are hidden."
+ (if (< level 0)
+ (let ((s (magit-current-section)))
+ (setq level (- level))
+ (while (> (1- (length (magit-section-ident s))) level)
+ (setq s (oref s parent))
+ (goto-char (oref s start)))
+ (magit-section-show-children magit-root-section (1- level)))
+ (cl-do* ((s (magit-current-section)
+ (oref s parent))
+ (i (1- (length (magit-section-ident s)))
+ (cl-decf i)))
+ ((cond ((< i level) (magit-section-show-children s (- level i 1)) t)
+ ((= i level) (magit-section-hide s) t))
+ (magit-section-goto s)))))
+
+(defun magit-section-show-level-1 ()
+ "Show surrounding sections on first level."
+ (interactive)
+ (magit-section-show-level 1))
+
+(defun magit-section-show-level-1-all ()
+ "Show all sections on first level."
+ (interactive)
+ (magit-section-show-level -1))
+
+(defun magit-section-show-level-2 ()
+ "Show surrounding sections up to second level."
+ (interactive)
+ (magit-section-show-level 2))
+
+(defun magit-section-show-level-2-all ()
+ "Show all sections up to second level."
+ (interactive)
+ (magit-section-show-level -2))
+
+(defun magit-section-show-level-3 ()
+ "Show surrounding sections up to third level."
+ (interactive)
+ (magit-section-show-level 3))
+
+(defun magit-section-show-level-3-all ()
+ "Show all sections up to third level."
+ (interactive)
+ (magit-section-show-level -3))
+
+(defun magit-section-show-level-4 ()
+ "Show surrounding sections up to fourth level."
+ (interactive)
+ (magit-section-show-level 4))
+
+(defun magit-section-show-level-4-all ()
+ "Show all sections up to fourth level."
+ (interactive)
+ (magit-section-show-level -4))
+
+(defun magit-mouse-toggle-section (event)
+ "Toggle visibility of the clicked section.
+Clicks outside either the section heading or the left fringe are
+silently ignored."
+ (interactive "e")
+ (let* ((pos (event-start event))
+ (section (magit-section-at (posn-point pos))))
+ (if (eq (posn-area pos) 'left-fringe)
+ (when section
+ (while (not (magit-section-content-p section))
+ (setq section (oref section parent)))
+ (unless (eq section magit-root-section)
+ (goto-char (oref section start))
+ (magit-section-toggle section)))
+ (magit-section-toggle section))))
+
+;;;; Auxiliary
+
+(defun magit-describe-section-briefly (section &optional ident)
+ "Show information about the section at point.
+With a prefix argument show the section identity instead of the
+section lineage. This command is intended for debugging purposes."
+ (interactive (list (magit-current-section) current-prefix-arg))
+ (let ((str (format "#<%s %S %S %s-%s%s>"
+ (eieio-object-class section)
+ (let ((val (oref section value)))
+ (cond ((stringp val)
+ (substring-no-properties val))
+ ((and (eieio-object-p val)
+ (fboundp 'cl-prin1-to-string))
+ (cl-prin1-to-string val))
+ (t
+ val)))
+ (if ident
+ (magit-section-ident section)
+ (apply #'vector (magit-section-lineage section)))
+ (and-let* ((m (oref section start)))
+ (marker-position m))
+ (if-let ((m (oref section content)))
+ (format "[%s-]" (marker-position m))
+ "")
+ (and-let* ((m (oref section end)))
+ (marker-position m)))))
+ (if (called-interactively-p 'any)
+ (message "%s" str)
+ str)))
+
+(cl-defmethod cl-print-object ((section magit-section) stream)
+ "Print `magit-describe-section' result of SECTION."
+ ;; Used by debug and edebug as of Emacs 26.
+ (princ (magit-describe-section-briefly section) stream))
+
+(defun magit-describe-section (section &optional interactive-p)
+ "Show information about the section at point."
+ (interactive (list (magit-current-section) t))
+ (let ((inserter-section section))
+ (while (and inserter-section (not (oref inserter-section inserter)))
+ (setq inserter-section (oref inserter-section parent)))
+ (when (and inserter-section (oref inserter-section inserter))
+ (setq section inserter-section)))
+ (pcase (oref section inserter)
+ (`((,hook ,fun) . ,src-src)
+ (help-setup-xref `(magit-describe-section ,section) interactive-p)
+ (with-help-window (help-buffer)
+ (with-current-buffer standard-output
+ (insert (format-message
+ "%s\n is inserted by `%s'\n from `%s'"
+ (magit-describe-section-briefly section)
+ (make-text-button (symbol-name fun) nil
+ :type 'help-function
+ 'help-args (list fun))
+ (make-text-button (symbol-name hook) nil
+ :type 'help-variable
+ 'help-args (list hook))))
+ (pcase-dolist (`(,hook ,fun) src-src)
+ (insert (format-message
+ ",\n called by `%s'\n from `%s'"
+ (make-text-button (symbol-name fun) nil
+ :type 'help-function
+ 'help-args (list fun))
+ (make-text-button (symbol-name hook) nil
+ :type 'help-variable
+ 'help-args (list hook)))))
+ (insert ".\n\n")
+ (insert
+ (format-message
+ "`%s' is "
+ (make-text-button (symbol-name fun) nil
+ :type 'help-function 'help-args (list fun))))
+ (describe-function-1 fun))))
+ (_ (message "%s, inserter unknown"
+ (magit-describe-section-briefly section)))))
+
+;;; Match
+
+(cl-defun magit-section-match
+ (condition &optional (section (magit-current-section)))
+ "Return t if SECTION matches CONDITION.
+
+SECTION defaults to the section at point. If SECTION is not
+specified and there also is no section at point, then return
+nil.
+
+CONDITION can take the following forms:
+ (CONDITION...) matches if any of the CONDITIONs matches.
+ [CLASS...] matches if the section's class is the same
+ as the first CLASS or a subclass of that;
+ the section's parent class matches the
+ second CLASS; and so on.
+ [* CLASS...] matches sections that match [CLASS...] and
+ also recursively all their child sections.
+ CLASS matches if the section's class is the same
+ as CLASS or a subclass of that; regardless
+ of the classes of the parent sections.
+
+Each CLASS should be a class symbol, identifying a class that
+derives from `magit-section'. For backward compatibility CLASS
+can also be a \"type symbol\". A section matches such a symbol
+if the value of its `type' slot is `eq'. If a type symbol has
+an entry in `magit--section-type-alist', then a section also
+matches that type if its class is a subclass of the class that
+corresponds to the type as per that alist.
+
+Note that it is not necessary to specify the complete section
+lineage as printed by `magit-describe-section-briefly', unless
+of course you want to be that precise."
+ (and section (magit-section-match-1 condition section)))
+
+(defun magit-section-match-1 (condition section)
+ (cl-assert condition)
+ (and section
+ (if (listp condition)
+ (--first (magit-section-match-1 it section) condition)
+ (magit-section-match-2 (if (symbolp condition)
+ (list condition)
+ (cl-coerce condition 'list))
+ section))))
+
+(defun magit-section-match-2 (condition section)
+ (if (eq (car condition) '*)
+ (or (magit-section-match-2 (cdr condition) section)
+ (and-let* ((parent (oref section parent)))
+ (magit-section-match-2 condition parent)))
+ (and (let ((c (car condition)))
+ (if (class-p c)
+ (cl-typep section c)
+ (if-let ((class (cdr (assq c magit--section-type-alist))))
+ (cl-typep section class)
+ (eq (oref section type) c))))
+ (or (not (setq condition (cdr condition)))
+ (and-let* ((parent (oref section parent)))
+ (magit-section-match-2 condition parent))))))
+
+(defun magit-section-value-if (condition &optional section)
+ "If the section at point matches CONDITION, then return its value.
+
+If optional SECTION is non-nil then test whether that matches
+instead. If there is no section at point and SECTION is nil,
+then return nil. If the section does not match, then return
+nil.
+
+See `magit-section-match' for the forms CONDITION can take."
+ (and-let* ((section (or section (magit-current-section))))
+ (and (magit-section-match condition section)
+ (oref section value))))
+
+(defmacro magit-section-when (condition &rest body)
+ "If the section at point matches CONDITION, evaluate BODY.
+
+If the section matches, then evaluate BODY forms sequentially
+with `it' bound to the section and return the value of the last
+form. If there are no BODY forms, then return the value of the
+section. If the section does not match or if there is no section
+at point, then return nil.
+
+See `magit-section-match' for the forms CONDITION can take."
+ (declare (obsolete
+ "instead use `magit-section-match' or `magit-section-value-if'."
+ "Magit 2.90.0")
+ (indent 1)
+ (debug (sexp body)))
+ `(--when-let (magit-current-section)
+ ;; Quoting CONDITION here often leads to double-quotes, which
+ ;; isn't an issue because `magit-section-match-1' implicitly
+ ;; deals with that. We shouldn't force users of this function
+ ;; to not quote CONDITION because that would needlessly break
+ ;; backward compatibility.
+ (when (magit-section-match ',condition it)
+ ,@(or body '((oref it value))))))
+
+(defmacro magit-section-case (&rest clauses)
+ "Choose among clauses on the type of the section at point.
+
+Each clause looks like (CONDITION BODY...). The type of the
+section is compared against each CONDITION; the BODY forms of the
+first match are evaluated sequentially and the value of the last
+form is returned. Inside BODY the symbol `it' is bound to the
+section at point. If no clause succeeds or if there is no
+section at point, return nil.
+
+See `magit-section-match' for the forms CONDITION can take.
+Additionally a CONDITION of t is allowed in the final clause, and
+matches if no other CONDITION match, even if there is no section
+at point."
+ (declare (indent 0)
+ (debug (&rest (sexp body))))
+ `(let* ((it (magit-current-section)))
+ (cond ,@(mapcar (lambda (clause)
+ `(,(or (eq (car clause) t)
+ `(and it
+ (magit-section-match-1 ',(car clause) it)))
+ ,@(cdr clause)))
+ clauses))))
+
+(defun magit-section-match-assoc (section alist)
+ "Return the value associated with SECTION's type or lineage in ALIST."
+ (seq-some (pcase-lambda (`(,key . ,val))
+ (and (magit-section-match-1 key section) val))
+ alist))
+
+;;; Create
+
+(defvar magit-insert-section-hook nil
+ "Hook run after `magit-insert-section's BODY.
+Avoid using this hook and only ever do so if you know
+what you are doing and are sure there is no other way.")
+
+(defmacro magit-insert-section (&rest args)
+ "Insert a section at point.
+
+Create a section object of type CLASS, storing VALUE in its
+`value' slot, and insert the section at point. CLASS is a
+subclass of `magit-section' or has the form `(eval FORM)', in
+which case FORM is evaluated at runtime and should return a
+subclass. In other places a sections class is oftern referred
+to as its \"type\".
+
+Many commands behave differently depending on the class of the
+current section and sections of a certain class can have their
+own keymap, which is specified using the `keymap' class slot.
+The value of that slot should be a variable whose value is a
+keymap.
+
+For historic reasons Magit and Forge in most cases use symbols
+as CLASS that don't actually identify a class and that lack the
+appropriate package prefix. This works due to some undocumented
+kludges, which are not available to other packages.
+
+When optional HIDE is non-nil collapse the section body by
+default, i.e. when first creating the section, but not when
+refreshing the buffer. Else expand it by default. This can be
+overwritten using `magit-section-set-visibility-hook'. When a
+section is recreated during a refresh, then the visibility of
+predecessor is inherited and HIDE is ignored (but the hook is
+still honored).
+
+BODY is any number of forms that actually insert the section's
+heading and body. Optional NAME, if specified, has to be a
+symbol, which is then bound to the object of the section being
+inserted.
+
+Before BODY is evaluated the `start' of the section object is set
+to the value of `point' and after BODY was evaluated its `end' is
+set to the new value of `point'; BODY is responsible for moving
+`point' forward.
+
+If it turns out inside BODY that the section is empty, then
+`magit-cancel-section' can be used to abort and remove all traces
+of the partially inserted section. This can happen when creating
+a section by washing Git's output and Git didn't actually output
+anything this time around.
+
+\(fn [NAME] (CLASS &optional VALUE HIDE) &rest BODY)"
+ (declare (indent defun)
+ (debug ([&optional symbolp]
+ (&or [("eval" form) &optional form form]
+ [symbolp &optional form form])
+ body)))
+ (let ((tp (cl-gensym "type"))
+ (s* (and (symbolp (car args))
+ (pop args)))
+ (s (cl-gensym "section")))
+ `(let* ((,tp ,(let ((type (nth 0 (car args))))
+ (if (eq (car-safe type) 'eval)
+ (cadr type)
+ `',type)))
+ (,s (funcall (if (class-p ,tp)
+ ,tp
+ (or (cdr (assq ,tp magit--section-type-alist))
+ 'magit-section))
+ :type
+ (or (and (class-p ,tp)
+ (car (rassq ,tp magit--section-type-alist)))
+ ,tp)
+ :value ,(nth 1 (car args))
+ :start (point-marker)
+ :parent magit-insert-section--parent)))
+ (oset ,s hidden
+ (let ((value (run-hook-with-args-until-success
+ 'magit-section-set-visibility-hook ,s)))
+ (if value
+ (eq value 'hide)
+ (let ((incarnation (and magit-insert-section--oldroot
+ (magit-get-section
+ (magit-section-ident ,s)
+ magit-insert-section--oldroot))))
+ (if incarnation
+ (oref incarnation hidden)
+ (let ((value (magit-section-match-assoc
+ ,s magit-section-initial-visibility-alist)))
+ (if value
+ (progn
+ (when (functionp value)
+ (setq value (funcall value ,s)))
+ (eq value 'hide))
+ ,(nth 2 (car args)))))))))
+ (let ((magit-insert-section--current ,s)
+ (magit-insert-section--parent ,s)
+ (magit-insert-section--oldroot
+ (or magit-insert-section--oldroot
+ (unless magit-insert-section--parent
+ (prog1 magit-root-section
+ (setq magit-root-section ,s))))))
+ (catch 'cancel-section
+ ,@(if s*
+ `((let ((,s* ,s))
+ ,@(cdr args)))
+ (cdr args))
+ ;; `magit-insert-section-hook' should *not* be run with
+ ;; `magit-run-section-hook' because it's a hook that runs
+ ;; on section insertion, not a section inserting hook.
+ (run-hooks 'magit-insert-section-hook)
+ (magit-insert-child-count ,s)
+ (set-marker-insertion-type (oref ,s start) t)
+ (let* ((end (oset ,s end (point-marker)))
+ (class-map (oref ,s keymap))
+ (magit-map (intern (format "magit-%s-section-map"
+ (oref ,s type))))
+ (forge-map (intern (format "forge-%s-section-map"
+ (oref ,s type))))
+ (map (and class-map (symbol-value class-map))))
+ (unless map
+ (setq map (or (and (boundp magit-map) (symbol-value magit-map))
+ (and (boundp forge-map) (symbol-value forge-map))))
+ (oset ,s keymap map))
+ (save-excursion
+ (goto-char (oref ,s start))
+ (while (< (point) end)
+ (let ((next (or (next-single-property-change
+ (point) 'magit-section)
+ end)))
+ (unless (magit-section-at)
+ (put-text-property (point) next 'magit-section ,s)
+ (when map
+ (put-text-property (point) next 'keymap map)))
+ (magit-section-maybe-add-heading-map ,s)
+ (goto-char next)))))
+ (if (eq ,s magit-root-section)
+ (let ((magit-section-cache-visibility nil))
+ (magit-section-show ,s))
+ (oset (oref ,s parent) children
+ (nconc (oref (oref ,s parent) children)
+ (list ,s)))))
+ ,s))))
+
+(defun magit-cancel-section ()
+ "Cancel inserting the section that is currently being inserted.
+Remove all traces of that section."
+ (when magit-insert-section--current
+ (if (not (oref magit-insert-section--current parent))
+ (insert "(empty)\n")
+ (delete-region (oref magit-insert-section--current start)
+ (point))
+ (setq magit-insert-section--current nil)
+ (throw 'cancel-section nil))))
+
+(defun magit-insert-heading (&rest args)
+ "Insert the heading for the section currently being inserted.
+
+This function should only be used inside `magit-insert-section'.
+
+When called without any arguments, then just set the `content'
+slot of the object representing the section being inserted to
+a marker at `point'. The section should only contain a single
+line when this function is used like this.
+
+When called with arguments ARGS, which have to be strings, or
+nil, then insert those strings at point. The section should not
+contain any text before this happens and afterwards it should
+again only contain a single line. If the `face' property is set
+anywhere inside any of these strings, then insert all of them
+unchanged. Otherwise use the `magit-section-heading' face for
+all inserted text.
+
+The `content' property of the section object is the end of the
+heading (which lasts from `start' to `content') and the beginning
+of the the body (which lasts from `content' to `end'). If the
+value of `content' is nil, then the section has no heading and
+its body cannot be collapsed. If a section does have a heading,
+then its height must be exactly one line, including a trailing
+newline character. This isn't enforced, you are responsible for
+getting it right. The only exception is that this function does
+insert a newline character if necessary."
+ (declare (indent defun))
+ (when args
+ (let ((heading (apply #'concat args)))
+ (insert (if (or (text-property-not-all 0 (length heading)
+ 'font-lock-face nil heading)
+ (text-property-not-all 0 (length heading)
+ 'face nil heading))
+ heading
+ (propertize heading 'font-lock-face 'magit-section-heading)))))
+ (unless (bolp)
+ (insert ?\n))
+ (when (fboundp 'magit-maybe-make-margin-overlay)
+ (magit-maybe-make-margin-overlay))
+ (oset magit-insert-section--current content (point-marker)))
+
+(defmacro magit-insert-section-body (&rest body)
+ "Use BODY to insert the section body, once the section is expanded.
+If the section is expanded when it is created, then this is
+like `progn'. Otherwise BODY isn't evaluated until the section
+is explicitly expanded."
+ (declare (indent 0))
+ (let ((f (cl-gensym))
+ (s (cl-gensym)))
+ `(let ((,f (lambda () ,@body))
+ (,s magit-insert-section--current))
+ (if (oref ,s hidden)
+ (oset ,s washer
+ (lambda ()
+ (funcall ,f)
+ (magit-section-maybe-remove-heading-map ,s)
+ (magit-section-maybe-remove-visibility-indicator ,s)))
+ (funcall ,f)))))
+
+(defun magit-insert-headers (hook)
+ (let* ((header-sections nil)
+ (magit-insert-section-hook
+ (cons (lambda ()
+ (push magit-insert-section--current
+ header-sections))
+ (if (listp magit-insert-section-hook)
+ magit-insert-section-hook
+ (list magit-insert-section-hook)))))
+ (magit-run-section-hook hook)
+ (when header-sections
+ (insert "\n")
+ ;; Make the first header into the parent of the rest.
+ (when (cdr header-sections)
+ (cl-callf nreverse header-sections)
+ (let* ((1st-header (pop header-sections))
+ (header-parent (oref 1st-header parent)))
+ (oset header-parent children (list 1st-header))
+ (oset 1st-header children header-sections)
+ (oset 1st-header content (oref (car header-sections) start))
+ (oset 1st-header end (oref (car (last header-sections)) end))
+ (dolist (sub-header header-sections)
+ (oset sub-header parent 1st-header))
+ (magit-section-maybe-add-heading-map 1st-header))))))
+
+(defun magit-section-maybe-add-heading-map (section)
+ (when (magit-section-content-p section)
+ (let ((start (oref section start))
+ (map (oref section keymap)))
+ (when (symbolp map)
+ (setq map (symbol-value map)))
+ (put-text-property
+ start
+ (save-excursion
+ (goto-char start)
+ (line-end-position))
+ 'keymap (if map
+ (make-composed-keymap
+ (list map magit-section-heading-map))
+ magit-section-heading-map)))))
+
+(defun magit-section-maybe-remove-heading-map (section)
+ (with-slots (start content end keymap) section
+ (when (= content end)
+ (put-text-property start end 'keymap keymap))))
+
+(defun magit-insert-child-count (section)
+ "Modify SECTION's heading to contain number of child sections.
+
+If `magit-section-show-child-count' is non-nil and the SECTION
+has children and its heading ends with \":\", then replace that
+with \" (N)\", where N is the number of child sections.
+
+This function is called by `magit-insert-section' after that has
+evaluated its BODY. Admittedly that's a bit of a hack."
+ ;; This has to be fast, not pretty!
+ (let (content count)
+ (when (and magit-section-show-child-count
+ (setq count (length (oref section children)))
+ (> count 0)
+ (setq content (oref section content))
+ (eq (char-before (1- content)) ?:))
+ (save-excursion
+ (goto-char (- content 2))
+ (insert (concat (magit--propertize-face " " 'magit-section-heading)
+ (magit--propertize-face (format "(%s)" count)
+ 'magit-section-child-count)))
+ (delete-char 1)))))
+
+;;; Highlight
+
+(defvar-local magit-section-pre-command-region-p nil)
+(defvar-local magit-section-pre-command-section nil)
+(defvar-local magit-section-highlight-force-update nil)
+(defvar-local magit-section-highlight-overlays nil)
+(defvar-local magit-section-highlighted-sections nil)
+(defvar-local magit-section-unhighlight-sections nil)
+
+(defun magit-section-pre-command-hook ()
+ (when (and (not (bound-and-true-p transient--prefix))
+ (or magit--context-menu-buffer
+ magit--context-menu-section)
+ (not (eq (ignore-errors
+ (event-basic-type (aref (this-command-keys) 0)))
+ 'mouse-3)))
+ ;; This is the earliest opportunity to clean up after an aborted
+ ;; context-menu because that neither causes the command that created
+ ;; the menu to abort nor some abortion hook to be run. It is not
+ ;; possible to update highlighting before the first command invoked
+ ;; after the menu is aborted. Here we can only make sure it is
+ ;; updated afterwards.
+ (magit-menu-highlight-point-section))
+ (setq magit-section-pre-command-region-p (region-active-p))
+ (setq magit-section-pre-command-section (magit-current-section)))
+
+(defun magit-section-post-command-hook ()
+ (unless (bound-and-true-p transient--prefix)
+ (when (or magit--context-menu-buffer
+ magit--context-menu-section)
+ (magit-menu-highlight-point-section))
+ (unless (memq this-command '(magit-refresh magit-refresh-all))
+ (magit-section-update-highlight))))
+
+(defun magit-section-deactivate-mark ()
+ (setq magit-section-highlight-force-update t))
+
+(defun magit-section-update-highlight (&optional force)
+ (let ((section (magit-current-section)))
+ (when (or force
+ magit-section-highlight-force-update
+ (xor magit-section-pre-command-region-p (region-active-p))
+ (not (eq magit-section-pre-command-section section)))
+ (let ((inhibit-read-only t)
+ (deactivate-mark nil)
+ (selection (magit-region-sections)))
+ (mapc #'delete-overlay magit-section-highlight-overlays)
+ (setq magit-section-highlight-overlays nil)
+ (setq magit-section-unhighlight-sections
+ magit-section-highlighted-sections)
+ (setq magit-section-highlighted-sections nil)
+ (unless (eq section magit-root-section)
+ (run-hook-with-args-until-success
+ 'magit-section-highlight-hook section selection))
+ (dolist (s magit-section-unhighlight-sections)
+ (run-hook-with-args-until-success
+ 'magit-section-unhighlight-hook s selection))
+ (restore-buffer-modified-p nil)))
+ (setq magit-section-highlight-force-update nil)
+ (magit-section-maybe-paint-visibility-ellipses)))
+
+(defun magit-section-highlight (section selection)
+ "Highlight SECTION and if non-nil all sections in SELECTION.
+This function works for any section but produces undesirable
+effects for diff related sections, which by default are
+highlighted using `magit-diff-highlight'. Return t."
+ (when-let ((face (oref section heading-highlight-face)))
+ (dolist (section (or selection (list section)))
+ (magit-section-make-overlay
+ (oref section start)
+ (or (oref section content)
+ (oref section end))
+ face)))
+ (cond (selection
+ (magit-section-make-overlay (oref (car selection) start)
+ (oref (car (last selection)) end)
+ 'magit-section-highlight)
+ (magit-section-highlight-selection nil selection))
+ (t
+ (magit-section-make-overlay (oref section start)
+ (oref section end)
+ 'magit-section-highlight)))
+ t)
+
+(defun magit-section-highlight-selection (_ selection)
+ "Highlight the section-selection region.
+If SELECTION is non-nil, then it is a list of sections selected by
+the region. The headings of these sections are then highlighted.
+
+This is a fallback for people who don't want to highlight the
+current section and therefore removed `magit-section-highlight'
+from `magit-section-highlight-hook'.
+
+This function is necessary to ensure that a representation of
+such a region is visible. If neither of these functions were
+part of the hook variable, then such a region would be
+invisible."
+ (when (and selection
+ (not (and (eq this-command 'mouse-drag-region))))
+ (dolist (section selection)
+ (magit-section-make-overlay (oref section start)
+ (or (oref section content)
+ (oref section end))
+ 'magit-section-heading-selection))
+ t))
+
+(defun magit-section-make-overlay (start end face)
+ ;; Yes, this doesn't belong here. But the alternative of
+ ;; spreading this hack across the code base is even worse.
+ (when (and magit-section-keep-region-overlay
+ (memq face '(magit-section-heading-selection
+ magit-diff-file-heading-selection
+ magit-diff-hunk-heading-selection)))
+ (setq face (list :foreground (face-foreground face))))
+ (let ((ov (make-overlay start end nil t)))
+ (overlay-put ov 'font-lock-face face)
+ (overlay-put ov 'evaporate t)
+ (push ov magit-section-highlight-overlays)
+ ov))
+
+(defun magit-section-goto-successor (section line char arg)
+ (let ((ident (magit-section-ident section)))
+ (--if-let (magit-get-section ident)
+ (let ((start (oref it start)))
+ (goto-char start)
+ (unless (eq it magit-root-section)
+ (ignore-errors
+ (forward-line line)
+ (forward-char char))
+ (unless (eq (magit-current-section) it)
+ (goto-char start))))
+ (or (run-hook-with-args-until-success
+ 'magit-section-goto-successor-hook section arg)
+ (goto-char (--if-let (magit-section-goto-successor-1 section)
+ (if (eq (oref it type) 'button)
+ (point-min)
+ (oref it start))
+ (point-min)))))))
+
+(defun magit-section-goto-successor-1 (section)
+ (or (and-let* ((alt (pcase (oref section type)
+ ('staged 'unstaged)
+ ('unstaged 'staged)
+ ('unpushed 'unpulled)
+ ('unpulled 'unpushed))))
+ (magit-get-section `((,alt) (status))))
+ (and-let* ((next (car (magit-section-siblings section 'next))))
+ (magit-get-section (magit-section-ident next)))
+ (and-let* ((prev (car (magit-section-siblings section 'prev))))
+ (magit-get-section (magit-section-ident prev)))
+ (and-let* ((parent (oref section parent)))
+ (or (magit-get-section (magit-section-ident parent))
+ (magit-section-goto-successor-1 parent)))))
+
+;;; Region
+
+(defvar-local magit-section--region-overlays nil)
+
+(defun magit-section--delete-region-overlays ()
+ (mapc #'delete-overlay magit-section--region-overlays)
+ (setq magit-section--region-overlays nil))
+
+(defun magit-section--highlight-region (start end window rol)
+ (magit-section--delete-region-overlays)
+ (if (and (not magit-section-keep-region-overlay)
+ (or (magit-region-sections)
+ (run-hook-with-args-until-success 'magit-region-highlight-hook
+ (magit-current-section)))
+ (not (= (line-number-at-pos start)
+ (line-number-at-pos end)))
+ ;; (not (eq (car-safe last-command-event) 'mouse-movement))
+ )
+ (funcall (default-value 'redisplay-unhighlight-region-function) rol)
+ (funcall (default-value 'redisplay-highlight-region-function)
+ start end window rol)))
+
+(defun magit-section--unhighlight-region (rol)
+ (magit-section--delete-region-overlays)
+ (funcall (default-value 'redisplay-unhighlight-region-function) rol))
+
+;;; Visibility
+
+(defvar-local magit-section-visibility-cache nil)
+(put 'magit-section-visibility-cache 'permanent-local t)
+
+(defun magit-section-cached-visibility (section)
+ "Set SECTION's visibility to the cached value."
+ (cdr (assoc (magit-section-ident section)
+ magit-section-visibility-cache)))
+
+(cl-defun magit-section-cache-visibility
+ (&optional (section magit-insert-section--current))
+ (setf (compat-alist-get (magit-section-ident section)
+ magit-section-visibility-cache
+ nil nil #'equal)
+ (if (oref section hidden) 'hide 'show)))
+
+(cl-defun magit-section-maybe-cache-visibility
+ (&optional (section magit-insert-section--current))
+ (when (or (eq magit-section-cache-visibility t)
+ (memq (oref section type)
+ magit-section-cache-visibility))
+ (magit-section-cache-visibility section)))
+
+(defun magit-section-maybe-update-visibility-indicator (section)
+ (when (and magit-section-visibility-indicator
+ (magit-section-content-p section))
+ (let* ((beg (oref section start))
+ (eoh (save-excursion
+ (goto-char beg)
+ (line-end-position))))
+ (cond
+ ((symbolp (car-safe magit-section-visibility-indicator))
+ (let ((ov (magit--overlay-at beg 'magit-vis-indicator 'fringe)))
+ (unless ov
+ (setq ov (make-overlay beg eoh nil t))
+ (overlay-put ov 'evaporate t)
+ (overlay-put ov 'magit-vis-indicator 'fringe))
+ (overlay-put
+ ov 'before-string
+ (propertize "fringe" 'display
+ (list 'left-fringe
+ (if (oref section hidden)
+ (car magit-section-visibility-indicator)
+ (cdr magit-section-visibility-indicator))
+ 'fringe)))))
+ ((stringp (car-safe magit-section-visibility-indicator))
+ (let ((ov (magit--overlay-at (1- eoh) 'magit-vis-indicator 'eoh)))
+ (cond ((oref section hidden)
+ (unless ov
+ (setq ov (make-overlay (1- eoh) eoh))
+ (overlay-put ov 'evaporate t)
+ (overlay-put ov 'magit-vis-indicator 'eoh))
+ (overlay-put ov 'after-string
+ (car magit-section-visibility-indicator)))
+ (ov
+ (delete-overlay ov)))))))))
+
+(defvar-local magit--ellipses-sections nil)
+
+(defun magit-section-maybe-paint-visibility-ellipses ()
+ ;; This is needed because we hide the body instead of "the body
+ ;; except the final newline and additionally the newline before
+ ;; the body"; otherwise we could use `buffer-invisibility-spec'.
+ (when (stringp (car-safe magit-section-visibility-indicator))
+ (let* ((sections (append magit--ellipses-sections
+ (setq magit--ellipses-sections
+ (or (magit-region-sections)
+ (list (magit-current-section))))))
+ (beg (--map (oref it start) sections))
+ (end (--map (oref it end) sections)))
+ (when (region-active-p)
+ ;; This ensures that the region face is removed from ellipses
+ ;; when the region becomes inactive, but fails to ensure that
+ ;; all ellipses within the active region use the region face,
+ ;; because the respective overlay has not yet been updated at
+ ;; this time. The magit-selection face is always applied.
+ (push (region-beginning) beg)
+ (push (region-end) end))
+ (setq beg (apply #'min beg))
+ (setq end (apply #'max end))
+ (dolist (ov (overlays-in beg end))
+ (when (eq (overlay-get ov 'magit-vis-indicator) 'eoh)
+ (overlay-put
+ ov 'after-string
+ (propertize
+ (car magit-section-visibility-indicator) 'font-lock-face
+ (let ((pos (overlay-start ov)))
+ (delq nil (nconc (--map (overlay-get it 'font-lock-face)
+ (overlays-at pos))
+ (list (get-char-property
+ pos 'font-lock-face))))))))))))
+
+(defun magit-section-maybe-remove-visibility-indicator (section)
+ (when (and magit-section-visibility-indicator
+ (= (oref section content)
+ (oref section end)))
+ (dolist (o (overlays-in (oref section start)
+ (save-excursion
+ (goto-char (oref section start))
+ (1+ (line-end-position)))))
+ (when (overlay-get o 'magit-vis-indicator)
+ (delete-overlay o)))))
+
+(defvar-local magit-section--opened-sections nil)
+
+(defun magit-section--open-temporarily (beg end)
+ (save-excursion
+ (goto-char beg)
+ (let ((section (magit-current-section)))
+ (while section
+ (let ((content (oref section content)))
+ (if (and (magit-section-invisible-p section)
+ (<= (or content (oref section start))
+ beg
+ (oref section end)))
+ (progn
+ (when content
+ (magit-section-show section)
+ (push section magit-section--opened-sections))
+ (setq section (oref section parent)))
+ (setq section nil))))))
+ (or (eq search-invisible t)
+ (not (isearch-range-invisible beg end))))
+
+(defun isearch-clean-overlays@magit-mode (fn)
+ (if (derived-mode-p 'magit-mode)
+ (let ((pos (point)))
+ (dolist (section magit-section--opened-sections)
+ (unless (<= (oref section content) pos (oref section end))
+ (magit-section-hide section)))
+ (setq magit-section--opened-sections nil))
+ (funcall fn)))
+
+(advice-add 'isearch-clean-overlays :around
+ #'isearch-clean-overlays@magit-mode)
+
+;;; Utilities
+
+(cl-defun magit-section-selected-p (section &optional (selection nil sselection))
+ (and (not (eq section magit-root-section))
+ (or (eq section (magit-current-section))
+ (memq section (if sselection
+ selection
+ (setq selection (magit-region-sections))))
+ (and-let* ((parent (oref section parent)))
+ (magit-section-selected-p parent selection)))))
+
+(defun magit-section-parent-value (section)
+ (and-let* ((parent (oref section parent)))
+ (oref parent value)))
+
+(defun magit-section-siblings (section &optional direction)
+ "Return a list of the sibling sections of SECTION.
+
+If optional DIRECTION is `prev', then return siblings that come
+before SECTION. If it is `next', then return siblings that come
+after SECTION. For all other values, return all siblings
+excluding SECTION itself."
+ (and-let* ((parent (oref section parent))
+ (siblings (oref parent children)))
+ (pcase direction
+ ('prev (cdr (member section (reverse siblings))))
+ ('next (cdr (member section siblings)))
+ (_ (remq section siblings)))))
+
+(defun magit-region-values (&optional condition multiple)
+ "Return a list of the values of the selected sections.
+
+Return the values that themselves would be returned by
+`magit-region-sections' (which see)."
+ (--map (oref it value)
+ (magit-region-sections condition multiple)))
+
+(defun magit-region-sections (&optional condition multiple)
+ "Return a list of the selected sections.
+
+When the region is active and constitutes a valid section
+selection, then return a list of all selected sections. This is
+the case when the region begins in the heading of a section and
+ends in the heading of the same section or in that of a sibling
+section. If optional MULTIPLE is non-nil, then the region cannot
+begin and end in the same section.
+
+When the selection is not valid, then return nil. In this case,
+most commands that can act on the selected sections will instead
+act on the section at point.
+
+When the region looks like it would in any other buffer then
+the selection is invalid. When the selection is valid then the
+region uses the `magit-section-highlight' face. This does not
+apply to diffs where things get a bit more complicated, but even
+here if the region looks like it usually does, then that's not
+a valid selection as far as this function is concerned.
+
+If optional CONDITION is non-nil, then the selection not only
+has to be valid; all selected sections additionally have to match
+CONDITION, or nil is returned. See `magit-section-match' for the
+forms CONDITION can take."
+ (when (region-active-p)
+ (let* ((rbeg (region-beginning))
+ (rend (region-end))
+ (sbeg (magit-section-at rbeg))
+ (send (magit-section-at rend)))
+ (when (and send
+ (not (eq send magit-root-section))
+ (not (and multiple (eq send sbeg))))
+ (let ((siblings (cons sbeg (magit-section-siblings sbeg 'next)))
+ sections)
+ (when (and (memq send siblings)
+ (magit-section-position-in-heading-p sbeg rbeg)
+ (magit-section-position-in-heading-p send rend))
+ (while siblings
+ (push (car siblings) sections)
+ (when (eq (pop siblings) send)
+ (setq siblings nil)))
+ (setq sections (nreverse sections))
+ (when (or (not condition)
+ (--all-p (magit-section-match condition it) sections))
+ sections)))))))
+
+(defun magit-section-position-in-heading-p (&optional section pos)
+ "Return t if POSITION is inside the heading of SECTION.
+POSITION defaults to point and SECTION defaults to the
+current section."
+ (unless section
+ (setq section (magit-current-section)))
+ (unless pos
+ (setq pos (point)))
+ (and section
+ (>= pos (oref section start))
+ (< pos (or (oref section content)
+ (oref section end)))
+ t))
+
+(defun magit-section-internal-region-p (&optional section)
+ "Return t if the region is active and inside SECTION's body.
+If optional SECTION is nil, use the current section."
+ (and (region-active-p)
+ (or section (setq section (magit-current-section)))
+ (let ((beg (magit-section-at (region-beginning))))
+ (and (eq beg (magit-section-at (region-end)))
+ (eq beg section)))
+ (not (or (magit-section-position-in-heading-p section (region-beginning))
+ (magit-section-position-in-heading-p section (region-end))))
+ t))
+
+(defun magit-wash-sequence (function)
+ "Repeatedly call FUNCTION until it returns nil or eob is reached.
+FUNCTION has to move point forward or return nil."
+ (while (and (not (eobp)) (funcall function))))
+
+(defun magit-add-section-hook (hook function &optional at append local)
+ "Add to the value of section hook HOOK the function FUNCTION.
+
+Add FUNCTION at the beginning of the hook list unless optional
+APPEND is non-nil, in which case FUNCTION is added at the end.
+If FUNCTION already is a member, then move it to the new location.
+
+If optional AT is non-nil and a member of the hook list, then
+add FUNCTION next to that instead. Add before or after AT, or
+replace AT with FUNCTION depending on APPEND. If APPEND is the
+symbol `replace', then replace AT with FUNCTION. For any other
+non-nil value place FUNCTION right after AT. If nil, then place
+FUNCTION right before AT. If FUNCTION already is a member of the
+list but AT is not, then leave FUNCTION where ever it already is.
+
+If optional LOCAL is non-nil, then modify the hook's buffer-local
+value rather than its global value. This makes the hook local by
+copying the default value. That copy is then modified.
+
+HOOK should be a symbol. If HOOK is void, it is first set to nil.
+HOOK's value must not be a single hook function. FUNCTION should
+be a function that takes no arguments and inserts one or multiple
+sections at point, moving point forward. FUNCTION may choose not
+to insert its section(s), when doing so would not make sense. It
+should not be abused for other side-effects. To remove FUNCTION
+again use `remove-hook'."
+ (unless (boundp hook)
+ (error "Cannot add function to undefined hook variable %s" hook))
+ (unless (default-boundp hook)
+ (set-default hook nil))
+ (let ((value (if local
+ (if (local-variable-p hook)
+ (symbol-value hook)
+ (unless (local-variable-if-set-p hook)
+ (make-local-variable hook))
+ (copy-sequence (default-value hook)))
+ (default-value hook))))
+ (if at
+ (when (setq at (member at value))
+ (setq value (delq function value))
+ (cond ((eq append 'replace)
+ (setcar at function))
+ (append
+ (push function (cdr at)))
+ (t
+ (push (car at) (cdr at))
+ (setcar at function))))
+ (setq value (delq function value)))
+ (unless (member function value)
+ (setq value (if append
+ (append value (list function))
+ (cons function value))))
+ (when (eq append 'replace)
+ (setq value (delq at value)))
+ (if local
+ (set hook value)
+ (set-default hook value))))
+
+(defvar-local magit-disabled-section-inserters nil)
+
+(defun magit-disable-section-inserter (fn)
+ "Disable the section inserter FN in the current repository.
+It is only intended for use in \".dir-locals.el\" and
+\".dir-locals-2.el\". Also see info node `(magit)Per-Repository
+Configuration'."
+ (cl-pushnew fn magit-disabled-section-inserters))
+
+(put 'magit-disable-section-inserter 'safe-local-eval-function t)
+
+(defun magit-run-section-hook (hook &rest args)
+ "Run HOOK with ARGS, warning about invalid entries."
+ (let ((entries (symbol-value hook)))
+ (unless (listp entries)
+ (setq entries (list entries)))
+ (--when-let (-remove #'functionp entries)
+ (message "`%s' contains entries that are no longer valid.
+%s\nUsing standard value instead. Please re-configure hook variable."
+ hook
+ (mapconcat (lambda (sym) (format " `%s'" sym)) it "\n"))
+ (sit-for 5)
+ (setq entries (eval (car (get hook 'standard-value)))))
+ (dolist (entry entries)
+ (let ((magit--current-section-hook (cons (list hook entry)
+ magit--current-section-hook)))
+ (unless (memq entry magit-disabled-section-inserters)
+ (if (bound-and-true-p magit-refresh-verbose)
+ (let ((time (benchmark-elapse (apply entry args))))
+ (message " %-50s %s %s" entry time
+ (cond ((> time 0.03) "!!")
+ ((> time 0.01) "!")
+ (t ""))))
+ (apply entry args)))))))
+
+(cl-defun magit--overlay-at (pos prop &optional (val nil sval) testfn)
+ (cl-find-if (lambda (o)
+ (let ((p (overlay-properties o)))
+ (and (plist-member p prop)
+ (or (not sval)
+ (funcall (or testfn #'eql)
+ (plist-get p prop)
+ val)))))
+ (overlays-at pos t)))
+
+(defun magit-face-property-all (face string)
+ "Return non-nil if FACE is present in all of STRING."
+ (catch 'missing
+ (let ((pos 0))
+ (while (setq pos (next-single-property-change pos 'font-lock-face string))
+ (let ((val (get-text-property pos 'font-lock-face string)))
+ (unless (if (consp val)
+ (memq face val)
+ (eq face val))
+ (throw 'missing nil))))
+ (not pos))))
+
+(defun magit--add-face-text-property (beg end face &optional append object)
+ "Like `add-face-text-property' but for `font-lock-face'."
+ (while (< beg end)
+ (let* ((pos (next-single-property-change beg 'font-lock-face object end))
+ (val (get-text-property beg 'font-lock-face object))
+ (val (if (listp val) val (list val))))
+ (put-text-property beg pos 'font-lock-face
+ (if append
+ (append val (list face))
+ (cons face val))
+ object)
+ (setq beg pos))))
+
+(defun magit--propertize-face (string face)
+ (propertize string 'face face 'font-lock-face face))
+
+(defun magit--put-face (beg end face string)
+ (put-text-property beg end 'face face string)
+ (put-text-property beg end 'font-lock-face face string))
+
+;;; Bitmaps
+
+(when (fboundp 'define-fringe-bitmap)
+ (define-fringe-bitmap 'magit-fringe-bitmap+
+ [#b00000000
+ #b00011000
+ #b00011000
+ #b01111110
+ #b01111110
+ #b00011000
+ #b00011000
+ #b00000000])
+ (define-fringe-bitmap 'magit-fringe-bitmap-
+ [#b00000000
+ #b00000000
+ #b00000000
+ #b01111110
+ #b01111110
+ #b00000000
+ #b00000000
+ #b00000000])
+
+ (define-fringe-bitmap 'magit-fringe-bitmap>
+ [#b01100000
+ #b00110000
+ #b00011000
+ #b00001100
+ #b00011000
+ #b00110000
+ #b01100000
+ #b00000000])
+ (define-fringe-bitmap 'magit-fringe-bitmapv
+ [#b00000000
+ #b10000010
+ #b11000110
+ #b01101100
+ #b00111000
+ #b00010000
+ #b00000000
+ #b00000000])
+
+ (define-fringe-bitmap 'magit-fringe-bitmap-bold>
+ [#b11100000
+ #b01110000
+ #b00111000
+ #b00011100
+ #b00011100
+ #b00111000
+ #b01110000
+ #b11100000])
+ (define-fringe-bitmap 'magit-fringe-bitmap-boldv
+ [#b10000001
+ #b11000011
+ #b11100111
+ #b01111110
+ #b00111100
+ #b00011000
+ #b00000000
+ #b00000000])
+ )
+
+;;; _
+(provide 'magit-section)
+;;; magit-section.el ends here
diff --git a/elpa/magit-section-20220502.2245/magit-section.elc b/elpa/magit-section-20220502.2245/magit-section.elc
new file mode 100644
index 0000000..d233130
--- /dev/null
+++ b/elpa/magit-section-20220502.2245/magit-section.elc
Binary files differ
diff --git a/elpa/magit-section-20220502.2245/magit-section.info b/elpa/magit-section-20220502.2245/magit-section.info
new file mode 100644
index 0000000..7e6ad9e
--- /dev/null
+++ b/elpa/magit-section-20220502.2245/magit-section.info
@@ -0,0 +1,307 @@
+This is magit-section.info, produced by makeinfo version 6.7 from
+magit-section.texi.
+
+ Copyright (C) 2015-2022 Jonas Bernoulli <jonas@bernoul.li>
+
+ You can redistribute this document 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 document 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.
+
+INFO-DIR-SECTION Emacs
+START-INFO-DIR-ENTRY
+* Magit-Section: (magit-section). Use Magit sections in your own packages.
+END-INFO-DIR-ENTRY
+
+
+File: magit-section.info, Node: Top, Next: Introduction, Up: (dir)
+
+Magit-Section Developer Manual
+******************************
+
+This package implements the main user interface of Magit — the
+collapsible sections that make up its buffers. This package used to be
+distributed as part of Magit but how it can also be used by other
+packages that have nothing to do with Magit or Git.
+
+ To learn more about the section abstraction and available commands
+and user options see *note (magit)Sections::. This manual documents how
+you can use sections in your own packages.
+
+This manual is for Magit-Section version 3.3.0-git.
+
+ Copyright (C) 2015-2022 Jonas Bernoulli <jonas@bernoul.li>
+
+ You can redistribute this document 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 document 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.
+
+* Menu:
+
+* Introduction::
+* Creating Sections::
+* Core Functions::
+* Matching Functions::
+
+
+File: magit-section.info, Node: Introduction, Next: Creating Sections, Prev: Top, Up: Top
+
+1 Introduction
+**************
+
+This package implements the main user interface of Magit — the
+collapsible sections that make up its buffers. This package used to be
+distributed as part of Magit but how it can also be used by other
+packages that have nothing to do with Magit or Git.
+
+ To learn more about the section abstraction and available commands
+and user options see *note (magit)Sections::. This manual documents how
+you can use sections in your own packages.
+
+ When the documentation leaves something unaddressed, then please
+consider that Magit uses this library extensively and search its source
+for suitable examples before asking me for help. Thanks!
+
+
+File: magit-section.info, Node: Creating Sections, Next: Core Functions, Prev: Introduction, Up: Top
+
+2 Creating Sections
+*******************
+
+ -- Macro: magit-insert-section [name] (type &optional value hide) &rest
+ body
+ Create a section object of type CLASS, storing VALUE in its ‘value’
+ slot, and insert the section at point. CLASS is a subclass of
+ ‘magit-section’ or has the form ‘(eval FORM)’, in which case FORM
+ is evaluated at runtime and should return a subclass. In other
+ places a sections class is oftern referred to as its "type".
+
+ Many commands behave differently depending on the class of the
+ current section and sections of a certain class can have their own
+ keymap, which is specified using the ‘keymap’ class slot. The
+ value of that slot should be a variable whose value is a keymap.
+
+ For historic reasons Magit and Forge in most cases use symbols as
+ CLASS that don’t actually identify a class and that lack the
+ appropriate package prefix. This works due to some undocumented
+ kludges, which are not available to other packages.
+
+ When optional HIDE is non-nil collapse the section body by default,
+ i.e. when first creating the section, but not when refreshing the
+ buffer. Else expand it by default. This can be overwritten using
+ ‘magit-section-set-visibility-hook’. When a section is recreated
+ during a refresh, then the visibility of predecessor is inherited
+ and HIDE is ignored (but the hook is still honored).
+
+ BODY is any number of forms that actually insert the section’s
+ heading and body. Optional NAME, if specified, has to be a symbol,
+ which is then bound to the object of the section being inserted.
+
+ Before BODY is evaluated the ‘start’ of the section object is set
+ to the value of ‘point’ and after BODY was evaluated its ‘end’ is
+ set to the new value of ‘point’; BODY is responsible for moving
+ ‘point’ forward.
+
+ If it turns out inside BODY that the section is empty, then
+ ‘magit-cancel-section’ can be used to abort and remove all traces
+ of the partially inserted section. This can happen when creating a
+ section by washing Git’s output and Git didn’t actually output
+ anything this time around.
+
+ -- Function: magit-insert-heading &rest args
+ Insert the heading for the section currently being inserted.
+
+ This function should only be used inside ‘magit-insert-section’.
+
+ When called without any arguments, then just set the ‘content’ slot
+ of the object representing the section being inserted to a marker
+ at ‘point’. The section should only contain a single line when
+ this function is used like this.
+
+ When called with arguments ARGS, which have to be strings, or nil,
+ then insert those strings at point. The section should not contain
+ any text before this happens and afterwards it should again only
+ contain a single line. If the ‘face’ property is set anywhere
+ inside any of these strings, then insert all of them unchanged.
+ Otherwise use the ‘magit-section-heading’ face for all inserted
+ text.
+
+ The ‘content’ property of the section object is the end of the
+ heading (which lasts from ‘start’ to ‘content’) and the beginning
+ of the the body (which lasts from ‘content’ to ‘end’). If the
+ value of ‘content’ is nil, then the section has no heading and its
+ body cannot be collapsed. If a section does have a heading, then
+ its height must be exactly one line, including a trailing newline
+ character. This isn’t enforced, you are responsible for getting it
+ right. The only exception is that this function does insert a
+ newline character if necessary.
+
+ -- Macro: magit-insert-section-body &rest body
+ Use BODY to insert the section body, once the section is expanded.
+ If the section is expanded when it is created, then this is like
+ ‘progn’. Otherwise BODY isn’t evaluated until the section is
+ explicitly expanded.
+
+ -- Function: magit-cancel-section
+ Cancel inserting the section that is currently being inserted.
+ Remove all traces of that section.
+
+ -- Function: magit-wash-sequence function
+ Repeatedly call FUNCTION until it returns ‘nil’ or the end of the
+ buffer is reached. FUNCTION has to move point forward or return
+ ‘nil’.
+
+
+File: magit-section.info, Node: Core Functions, Next: Matching Functions, Prev: Creating Sections, Up: Top
+
+3 Core Functions
+****************
+
+ -- Function: magit-current-section
+ Return the section at point or where the context menu was invoked.
+ When using the context menu, return the section that the user
+ clicked on, provided the current buffer is the buffer in which the
+ click occurred. Otherwise return the section at point.
+
+Function magit-section-at &optional position
+ Return the section at POSITION, defaulting to point. Default to
+ point even when the context menu is used.
+
+ -- Function: magit-section-ident section
+ Return an unique identifier for SECTION. The return value has the
+ form ‘((TYPE . VALUE)...)’.
+
+ -- Function: magit-section-ident-value value
+ Return a constant representation of VALUE.
+
+ VALUE is the value of a ‘magit-section’ object. If that is an
+ object itself, then that is not suitable to be used to identify the
+ section because two objects may represent the same thing but not be
+ equal. If possible a method should be added for such objects,
+ which returns a value that is equal. Otherwise the catch-all
+ method is used, which just returns the argument itself.
+
+ -- Function: magit-get-section ident &optional root
+ Return the section identified by IDENT. IDENT has to be a list as
+ returned by ‘magit-section-ident’. If optional ROOT is non-nil,
+ then search in that section tree instead of in the one whose root
+ ‘magit-root-section’ is.
+
+ -- Function: magit-section-lineage section
+ Return the lineage of SECTION. The return value has the form
+ ‘(TYPE...)’.
+
+ -- Function: magit-section-content-p section
+ Return non-nil if SECTION has content or an unused washer function.
+
+ The next two functions are replacements for the Emacs functions that
+have the same name except for the ‘magit-’ prefix. Like
+‘magit-current-section’ they do not act on point, the cursors position,
+but on the position where the user clicked to invoke the context menu.
+
+ If your package provides a context menu and some of its commands act
+on the "thing at point", even if just as a default, then use the
+prefixed functions to teach them to instead use the click location when
+appropriate.
+
+Function magit-point
+ Return point or the position where the context menu was invoked.
+ When using the context menu, return the position the user clicked
+ on, provided the current buffer is the buffer in which the click
+ occurred. Otherwise return the same value as ‘point’.
+
+Function magit-thing-at-point thing &optional no-properties
+ Return the THING at point or where the context menu was invoked.
+ When using the context menu, return the thing the user clicked on,
+ provided the current buffer is the buffer in which the click
+ occurred. Otherwise return the same value as ‘thing-at-point’.
+ For the meaning of THING and NO-PROPERTIES see that function.
+
+
+File: magit-section.info, Node: Matching Functions, Prev: Core Functions, Up: Top
+
+4 Matching Functions
+********************
+
+ -- Function: magit-section-match condition &optional (section
+ (magit-current-section))
+ Return t if SECTION matches CONDITION.
+
+ SECTION defaults to the section at point. If SECTION is not
+ specified and there also is no section at point, then return nil.
+
+ CONDITION can take the following forms:
+
+ • ‘(CONDITION...)’ matches if any of the CONDITIONs matches.
+ • ‘[CLASS...]’ matches if the section’s class is the same as the
+ first CLASS or a subclass of that; the section’s parent class
+ matches the second CLASS; and so on.
+
+ • ‘[* CLASS...]’ matches sections that match [CLASS...] and also
+ recursively all their child sections.
+ • ‘CLASS’ matches if the section’s class is the same as CLASS or
+ a subclass of that; regardless of the classes of the parent
+ sections.
+
+ Each CLASS should be a class symbol, identifying a class that
+ derives from ‘magit-section’. For backward compatibility CLASS can
+ also be a "type symbol". A section matches such a symbol if the
+ value of its ‘type’ slot is ‘eq’. If a type symbol has an entry in
+ ‘magit--section-type-alist’, then a section also matches that type
+ if its class is a subclass of the class that corresponds to the
+ type as per that alist.
+
+ Note that it is not necessary to specify the complete section
+ lineage as printed by ‘magit-describe-section-briefly’, unless of
+ course you want to be that precise.
+
+ -- Function: magit-section-value-if condition &optional section
+ If the section at point matches CONDITION, then return its value.
+
+ If optional SECTION is non-nil then test whether that matches
+ instead. If there is no section at point and SECTION is nil, then
+ return nil. If the section does not match, then return nil.
+
+ See ‘magit-section-match’ for the forms CONDITION can take.
+
+ -- Macro: magit-section-case &rest clauses
+ Choose among clauses on the type of the section at point.
+
+ Each clause looks like ‘(CONDITION BODY...)’. The type of the
+ section is compared against each CONDITION; the BODY forms of the
+ first match are evaluated sequentially and the value of the last
+ form is returned. Inside BODY the symbol ‘it’ is bound to the
+ section at point. If no clause succeeds or if there is no section
+ at point, return nil.
+
+ See ‘magit-section-match’ for the forms CONDITION can take.
+ Additionally a CONDITION of t is allowed in the final clause, and
+ matches if no other CONDITION match, even if there is no section at
+ point.
+
+
+
+Tag Table:
+Node: Top788
+Node: Introduction2073
+Node: Creating Sections2843
+Node: Core Functions7352
+Node: Matching Functions10404
+
+End Tag Table
+
+
+Local Variables:
+coding: utf-8
+End:
diff --git a/elpa/markdown-mode-20220406.410/markdown-mode-autoloads.el b/elpa/markdown-mode-20220406.410/markdown-mode-autoloads.el
new file mode 100644
index 0000000..9e93ad2
--- /dev/null
+++ b/elpa/markdown-mode-20220406.410/markdown-mode-autoloads.el
@@ -0,0 +1,64 @@
+;;; markdown-mode-autoloads.el --- automatically extracted autoloads -*- lexical-binding: t -*-
+;;
+;;; Code:
+
+(add-to-list 'load-path (directory-file-name
+ (or (file-name-directory #$) (car load-path))))
+
+
+;;;### (autoloads nil "markdown-mode" "markdown-mode.el" (0 0 0 0))
+;;; Generated autoloads from markdown-mode.el
+
+(autoload 'markdown-mode "markdown-mode" "\
+Major mode for editing Markdown files.
+
+\(fn)" t nil)
+
+(add-to-list 'auto-mode-alist '("\\.\\(?:md\\|markdown\\|mkd\\|mdown\\|mkdn\\|mdwn\\)\\'" . markdown-mode))
+
+(autoload 'gfm-mode "markdown-mode" "\
+Major mode for editing GitHub Flavored Markdown files.
+
+\(fn)" t nil)
+
+(autoload 'markdown-view-mode "markdown-mode" "\
+Major mode for viewing Markdown content.
+
+\(fn)" t nil)
+
+(autoload 'gfm-view-mode "markdown-mode" "\
+Major mode for viewing GitHub Flavored Markdown content.
+
+\(fn)" t nil)
+
+(autoload 'markdown-live-preview-mode "markdown-mode" "\
+Toggle native previewing on save for a specific markdown file.
+
+This is a minor mode. If called interactively, toggle the
+`Markdown-Live-Preview mode' mode. If the prefix argument is
+positive, enable the mode, and if it is zero or negative, disable
+the mode.
+
+If called from Lisp, toggle the mode if ARG is `toggle'. Enable
+the mode if ARG is nil, omitted, or is a positive number.
+Disable the mode if ARG is a negative number.
+
+To check whether the minor mode is enabled in the current buffer,
+evaluate `markdown-live-preview-mode'.
+
+The mode's hook is called both when the mode is enabled and when
+it is disabled.
+
+\(fn &optional ARG)" t nil)
+
+(register-definition-prefixes "markdown-mode" '("defun-markdown-" "gfm-" "markdown"))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; coding: utf-8
+;; End:
+;;; markdown-mode-autoloads.el ends here
diff --git a/elpa/markdown-mode-20220406.410/markdown-mode-pkg.el b/elpa/markdown-mode-20220406.410/markdown-mode-pkg.el
new file mode 100644
index 0000000..f8e0406
--- /dev/null
+++ b/elpa/markdown-mode-20220406.410/markdown-mode-pkg.el
@@ -0,0 +1,2 @@
+;;; Generated package description from markdown-mode.el -*- no-byte-compile: t -*-
+(define-package "markdown-mode" "20220406.410" "Major mode for Markdown-formatted text" '((emacs "26.1")) :commit "d2a3d5b8625a7c6be21f19f9146745cd5c791a6a" :authors '(("Jason R. Blevins" . "jblevins@xbeta.org")) :maintainer '("Jason R. Blevins" . "jblevins@xbeta.org") :keywords '("markdown" "github flavored markdown" "itex") :url "https://jblevins.org/projects/markdown-mode/")
diff --git a/elpa/markdown-mode-20220406.410/markdown-mode.el b/elpa/markdown-mode-20220406.410/markdown-mode.el
new file mode 100644
index 0000000..ab1579a
--- /dev/null
+++ b/elpa/markdown-mode-20220406.410/markdown-mode.el
@@ -0,0 +1,9950 @@
+;;; markdown-mode.el --- Major mode for Markdown-formatted text -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2007-2022 Jason R. Blevins and markdown-mode
+;; contributors (see the commit log for details).
+
+;; Author: Jason R. Blevins <jblevins@xbeta.org>
+;; Maintainer: Jason R. Blevins <jblevins@xbeta.org>
+;; Created: May 24, 2007
+;; Version: 2.6-dev
+;; Package-Version: 20220406.410
+;; Package-Commit: d2a3d5b8625a7c6be21f19f9146745cd5c791a6a
+;; Package-Requires: ((emacs "26.1"))
+;; Keywords: Markdown, GitHub Flavored Markdown, itex
+;; URL: https://jblevins.org/projects/markdown-mode/
+
+;; 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 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:
+
+;; See the README.md file for details.
+
+
+;;; Code:
+
+(require 'easymenu)
+(require 'outline)
+(require 'thingatpt)
+(require 'cl-lib)
+(require 'url-parse)
+(require 'button)
+(require 'color)
+(require 'rx)
+(require 'subr-x)
+
+(defvar jit-lock-start)
+(defvar jit-lock-end)
+(defvar flyspell-generic-check-word-predicate)
+(defvar electric-pair-pairs)
+(defvar sh-ancestor-alist)
+
+(declare-function project-roots "project")
+(declare-function sh-set-shell "sh-script")
+
+
+;;; Constants =================================================================
+
+(defconst markdown-mode-version "2.6-dev"
+ "Markdown mode version number.")
+
+(defconst markdown-output-buffer-name "*markdown-output*"
+ "Name of temporary buffer for markdown command output.")
+
+
+;;; Global Variables ==========================================================
+
+(defvar markdown-reference-label-history nil
+ "History of used reference labels.")
+
+(defvar markdown-live-preview-mode nil
+ "Sentinel variable for command `markdown-live-preview-mode'.")
+
+(defvar markdown-gfm-language-history nil
+ "History list of languages used in the current buffer in GFM code blocks.")
+
+
+;;; Customizable Variables ====================================================
+
+(defvar markdown-mode-hook nil
+ "Hook run when entering Markdown mode.")
+
+(defvar markdown-before-export-hook nil
+ "Hook run before running Markdown to export XHTML output.
+The hook may modify the buffer, which will be restored to it's
+original state after exporting is complete.")
+
+(defvar markdown-after-export-hook nil
+ "Hook run after XHTML output has been saved.
+Any changes to the output buffer made by this hook will be saved.")
+
+(defgroup markdown nil
+ "Major mode for editing text files in Markdown format."
+ :prefix "markdown-"
+ :group 'text
+ :link '(url-link "https://jblevins.org/projects/markdown-mode/"))
+
+(defcustom markdown-command (let ((command (cl-loop for cmd in '("markdown" "pandoc" "markdown_py")
+ when (executable-find cmd)
+ return (file-name-nondirectory it))))
+ (or command "markdown"))
+ "Command to run markdown."
+ :group 'markdown
+ :type '(choice (string :tag "Shell command") (repeat (string)) function))
+
+(defcustom markdown-command-needs-filename nil
+ "Set to non-nil if `markdown-command' does not accept input from stdin.
+Instead, it will be passed a filename as the final command line
+option. As a result, you will only be able to run Markdown from
+buffers which are visiting a file."
+ :group 'markdown
+ :type 'boolean)
+
+(defcustom markdown-open-command nil
+ "Command used for opening Markdown files directly.
+For example, a standalone Markdown previewer. This command will
+be called with a single argument: the filename of the current
+buffer. It can also be a function, which will be called without
+arguments."
+ :group 'markdown
+ :type '(choice file function (const :tag "None" nil)))
+
+(defcustom markdown-open-image-command nil
+ "Command used for opening image files directly.
+This is used at `markdown-follow-link-at-point'."
+ :group 'markdown
+ :type '(choice file function (const :tag "None" nil)))
+
+(defcustom markdown-hr-strings
+ '("-------------------------------------------------------------------------------"
+ "* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *"
+ "---------------------------------------"
+ "* * * * * * * * * * * * * * * * * * * *"
+ "---------"
+ "* * * * *")
+ "Strings to use when inserting horizontal rules.
+The first string in the list will be the default when inserting a
+horizontal rule. Strings should be listed in decreasing order of
+prominence (as in headings from level one to six) for use with
+promotion and demotion functions."
+ :group 'markdown
+ :type '(repeat string))
+
+(defcustom markdown-bold-underscore nil
+ "Use two underscores when inserting bold text instead of two asterisks."
+ :group 'markdown
+ :type 'boolean)
+
+(defcustom markdown-italic-underscore nil
+ "Use underscores when inserting italic text instead of asterisks."
+ :group 'markdown
+ :type 'boolean)
+
+(defcustom markdown-marginalize-headers nil
+ "When non-nil, put opening atx header markup in a left margin.
+
+This setting goes well with `markdown-asymmetric-header'. But
+sadly it conflicts with `linum-mode' since they both use the
+same margin."
+ :group 'markdown
+ :type 'boolean
+ :safe 'booleanp
+ :package-version '(markdown-mode . "2.4"))
+
+(defcustom markdown-marginalize-headers-margin-width 6
+ "Character width of margin used for marginalized headers.
+The default value is based on there being six heading levels
+defined by Markdown and HTML. Increasing this produces extra
+whitespace on the left. Decreasing it may be preferred when
+fewer than six nested heading levels are used."
+ :group 'markdown
+ :type 'natnump
+ :safe 'natnump
+ :package-version '(markdown-mode . "2.4"))
+
+(defcustom markdown-asymmetric-header nil
+ "Determines if atx header style will be asymmetric.
+Set to a non-nil value to use asymmetric header styling, placing
+header markup only at the beginning of the line. By default,
+balanced markup will be inserted at the beginning and end of the
+line around the header title."
+ :group 'markdown
+ :type 'boolean)
+
+(defcustom markdown-indent-function 'markdown-indent-line
+ "Function to use to indent."
+ :group 'markdown
+ :type 'function)
+
+(defcustom markdown-indent-on-enter t
+ "Determines indentation behavior when pressing \\[newline].
+Possible settings are nil, t, and 'indent-and-new-item.
+
+When non-nil, pressing \\[newline] will call `newline-and-indent'
+to indent the following line according to the context using
+`markdown-indent-function'. In this case, note that
+\\[electric-newline-and-maybe-indent] can still be used to insert
+a newline without indentation.
+
+When set to 'indent-and-new-item and the point is in a list item
+when \\[newline] is pressed, the list will be continued on the next
+line, where a new item will be inserted.
+
+When set to nil, simply call `newline' as usual. In this case,
+you can still indent lines using \\[markdown-cycle] and continue
+lists with \\[markdown-insert-list-item].
+
+Note that this assumes the variable `electric-indent-mode' is
+non-nil (enabled). When it is *disabled*, the behavior of
+\\[newline] and `\\[electric-newline-and-maybe-indent]' are
+reversed."
+ :group 'markdown
+ :type '(choice (const :tag "Don't automatically indent" nil)
+ (const :tag "Automatically indent" t)
+ (const :tag "Automatically indent and insert new list items" indent-and-new-item)))
+
+(defcustom markdown-enable-wiki-links nil
+ "Syntax highlighting for wiki links.
+Set this to a non-nil value to turn on wiki link support by default.
+Support can be toggled later using the `markdown-toggle-wiki-links'
+function or \\[markdown-toggle-wiki-links]."
+ :group 'markdown
+ :type 'boolean
+ :safe 'booleanp
+ :package-version '(markdown-mode . "2.2"))
+
+(defcustom markdown-wiki-link-alias-first t
+ "When non-nil, treat aliased wiki links like [[alias text|PageName]].
+Otherwise, they will be treated as [[PageName|alias text]]."
+ :group 'markdown
+ :type 'boolean
+ :safe 'booleanp)
+
+(defcustom markdown-wiki-link-search-subdirectories nil
+ "When non-nil, search for wiki link targets in subdirectories.
+This is the default search behavior for GitHub and is
+automatically set to t in `gfm-mode'."
+ :group 'markdown
+ :type 'boolean
+ :safe 'booleanp
+ :package-version '(markdown-mode . "2.2"))
+
+(defcustom markdown-wiki-link-search-parent-directories nil
+ "When non-nil, search for wiki link targets in parent directories.
+This is the default search behavior of Ikiwiki."
+ :group 'markdown
+ :type 'boolean
+ :safe 'booleanp
+ :package-version '(markdown-mode . "2.2"))
+
+(defcustom markdown-wiki-link-search-type nil
+ "Searching type for markdown wiki link.
+
+sub-directories: search for wiki link targets in sub directories
+parent-directories: search for wiki link targets in parent directories
+project: search for wiki link targets under project root"
+ :group 'markdown
+ :type '(set
+ (const :tag "search wiki link from subdirectories" sub-directories)
+ (const :tag "search wiki link from parent directories" parent-directories)
+ (const :tag "search wiki link under project root" project))
+ :package-version '(markdown-mode . "2.5"))
+
+(make-obsolete-variable 'markdown-wiki-link-search-subdirectories 'markdown-wiki-link-search-type "2.5")
+(make-obsolete-variable 'markdown-wiki-link-search-parent-directories 'markdown-wiki-link-search-type "2.5")
+
+(defcustom markdown-wiki-link-fontify-missing nil
+ "When non-nil, change wiki link face according to existence of target files.
+This is expensive because it requires checking for the file each time the buffer
+changes or the user switches windows. It is disabled by default because it may
+cause lag when typing on slower machines."
+ :group 'markdown
+ :type 'boolean
+ :safe 'booleanp
+ :package-version '(markdown-mode . "2.2"))
+
+(defcustom markdown-uri-types
+ '("acap" "cid" "data" "dav" "fax" "file" "ftp"
+ "gopher" "http" "https" "imap" "ldap" "mailto"
+ "mid" "message" "modem" "news" "nfs" "nntp"
+ "pop" "prospero" "rtsp" "service" "sip" "tel"
+ "telnet" "tip" "urn" "vemmi" "wais")
+ "Link types for syntax highlighting of URIs."
+ :group 'markdown
+ :type '(repeat (string :tag "URI scheme")))
+
+(defcustom markdown-url-compose-char
+ '(?∞ ?… ?⋯ ?# ?★ ?⚓)
+ "Placeholder character for hidden URLs.
+This may be a single character or a list of characters. In case
+of a list, the first one that satisfies `char-displayable-p' will
+be used."
+ :type '(choice
+ (character :tag "Single URL replacement character")
+ (repeat :tag "List of possible URL replacement characters"
+ character))
+ :package-version '(markdown-mode . "2.3"))
+
+(defcustom markdown-blockquote-display-char
+ '("▌" "┃" ">")
+ "String to display when hiding blockquote markup.
+This may be a single string or a list of string. In case of a
+list, the first one that satisfies `char-displayable-p' will be
+used."
+ :type 'string
+ :type '(choice
+ (string :tag "Single blockquote display string")
+ (repeat :tag "List of possible blockquote display strings" string))
+ :package-version '(markdown-mode . "2.3"))
+
+(defcustom markdown-hr-display-char
+ '(?─ ?━ ?-)
+ "Character for hiding horizontal rule markup.
+This may be a single character or a list of characters. In case
+of a list, the first one that satisfies `char-displayable-p' will
+be used."
+ :group 'markdown
+ :type '(choice
+ (character :tag "Single HR display character")
+ (repeat :tag "List of possible HR display characters" character))
+ :package-version '(markdown-mode . "2.3"))
+
+(defcustom markdown-definition-display-char
+ '(?⁘ ?⁙ ?≡ ?⌑ ?◊ ?:)
+ "Character for replacing definition list markup.
+This may be a single character or a list of characters. In case
+of a list, the first one that satisfies `char-displayable-p' will
+be used."
+ :type '(choice
+ (character :tag "Single definition list character")
+ (repeat :tag "List of possible definition list characters" character))
+ :package-version '(markdown-mode . "2.3"))
+
+(defcustom markdown-enable-math nil
+ "Syntax highlighting for inline LaTeX and itex expressions.
+Set this to a non-nil value to turn on math support by default.
+Math support can be enabled, disabled, or toggled later using
+`markdown-toggle-math' or \\[markdown-toggle-math]."
+ :group 'markdown
+ :type 'boolean
+ :safe 'booleanp)
+(make-variable-buffer-local 'markdown-enable-math)
+
+(defcustom markdown-enable-html t
+ "Enable font-lock support for HTML tags and attributes."
+ :group 'markdown
+ :type 'boolean
+ :safe 'booleanp
+ :package-version '(markdown-mode . "2.4"))
+
+(defcustom markdown-enable-highlighting-syntax nil
+ "Enable highlighting syntax."
+ :group 'markdown
+ :type 'boolean
+ :safe 'booleanp
+ :package-version '(markdown-mode . "2.5"))
+
+(defcustom markdown-css-paths nil
+ "List of URLs of CSS files to link to in the output XHTML."
+ :group 'markdown
+ :type '(repeat (string :tag "CSS File Path")))
+
+(defcustom markdown-content-type "text/html"
+ "Content type string for the http-equiv header in XHTML output.
+When set to an empty string, this attribute is omitted. Defaults to
+`text/html'."
+ :group 'markdown
+ :type 'string)
+
+(defcustom markdown-coding-system nil
+ "Character set string for the http-equiv header in XHTML output.
+Defaults to `buffer-file-coding-system' (and falling back to
+`utf-8' when not available). Common settings are `iso-8859-1'
+and `iso-latin-1'. Use `list-coding-systems' for more choices."
+ :group 'markdown
+ :type 'coding-system)
+
+(defcustom markdown-export-kill-buffer t
+ "Kill output buffer after HTML export.
+When non-nil, kill the HTML output buffer after
+exporting with `markdown-export'."
+ :group 'markdown
+ :type 'boolean
+ :safe 'booleanp
+ :package-version '(markdown-mode . "2.4"))
+
+(defcustom markdown-xhtml-header-content ""
+ "Additional content to include in the XHTML <head> block."
+ :group 'markdown
+ :type 'string)
+
+(defcustom markdown-xhtml-body-preamble ""
+ "Content to include in the XHTML <body> block, before the output."
+ :group 'markdown
+ :type 'string
+ :safe 'stringp
+ :package-version '(markdown-mode . "2.4"))
+
+(defcustom markdown-xhtml-body-epilogue ""
+ "Content to include in the XHTML <body> block, after the output."
+ :group 'markdown
+ :type 'string
+ :safe 'stringp
+ :package-version '(markdown-mode . "2.4"))
+
+(defcustom markdown-xhtml-standalone-regexp
+ "^\\(<\\?xml\\|<!DOCTYPE\\|<html\\)"
+ "Regexp indicating whether `markdown-command' output is standalone XHTML."
+ :group 'markdown
+ :type 'regexp)
+
+(defcustom markdown-link-space-sub-char "_"
+ "Character to use instead of spaces when mapping wiki links to filenames."
+ :group 'markdown
+ :type 'string)
+
+(defcustom markdown-reference-location 'header
+ "Position where new reference definitions are inserted in the document."
+ :group 'markdown
+ :type '(choice (const :tag "At the end of the document" end)
+ (const :tag "Immediately after the current block" immediately)
+ (const :tag "At the end of the subtree" subtree)
+ (const :tag "Before next header" header)))
+
+(defcustom markdown-footnote-location 'end
+ "Position where new footnotes are inserted in the document."
+ :group 'markdown
+ :type '(choice (const :tag "At the end of the document" end)
+ (const :tag "Immediately after the current block" immediately)
+ (const :tag "At the end of the subtree" subtree)
+ (const :tag "Before next header" header)))
+
+(defcustom markdown-footnote-display '((raise 0.2) (height 0.8))
+ "Display specification for footnote markers and inline footnotes.
+By default, footnote text is reduced in size and raised. Set to
+nil to disable this."
+ :group 'markdown
+ :type '(choice (sexp :tag "Display specification")
+ (const :tag "Don't set display property" nil))
+ :package-version '(markdown-mode . "2.4"))
+
+(defcustom markdown-sub-superscript-display
+ '(((raise -0.3) (height 0.7)) . ((raise 0.3) (height 0.7)))
+ "Display specification for subscript and superscripts.
+The car is used for subscript, the cdr is used for superscripts."
+ :group 'markdown
+ :type '(cons (choice (sexp :tag "Subscript form")
+ (const :tag "No lowering" nil))
+ (choice (sexp :tag "Superscript form")
+ (const :tag "No raising" nil)))
+ :package-version '(markdown-mode . "2.4"))
+
+(defcustom markdown-unordered-list-item-prefix " * "
+ "String inserted before unordered list items."
+ :group 'markdown
+ :type 'string)
+
+(defcustom markdown-ordered-list-enumeration t
+ "When non-nil, use enumerated numbers(1. 2. 3. etc.) for ordered list marker.
+While nil, always uses '1.' for the marker"
+ :group 'markdown
+ :type 'boolean
+ :package-version '(markdown-mode . "2.5"))
+
+(defcustom markdown-nested-imenu-heading-index t
+ "Use nested or flat imenu heading index.
+A nested index may provide more natural browsing from the menu,
+but a flat list may allow for faster keyboard navigation via tab
+completion."
+ :group 'markdown
+ :type 'boolean
+ :safe 'booleanp
+ :package-version '(markdown-mode . "2.2"))
+
+(defcustom markdown-add-footnotes-to-imenu t
+ "Add footnotes to end of imenu heading index."
+ :group 'markdown
+ :type 'boolean
+ :safe 'booleanp
+ :package-version '(markdown-mode . "2.4"))
+
+(defcustom markdown-make-gfm-checkboxes-buttons t
+ "When non-nil, make GFM checkboxes into buttons."
+ :group 'markdown
+ :type 'boolean)
+
+(defcustom markdown-use-pandoc-style-yaml-metadata nil
+ "When non-nil, allow YAML metadata anywhere in the document."
+ :group 'markdown
+ :type 'boolean)
+
+(defcustom markdown-split-window-direction 'any
+ "Preference for splitting windows for static and live preview.
+The default value is 'any, which instructs Emacs to use
+`split-window-sensibly' to automatically choose how to split
+windows based on the values of `split-width-threshold' and
+`split-height-threshold' and the available windows. To force
+vertically split (left and right) windows, set this to 'vertical
+or 'right. To force horizontally split (top and bottom) windows,
+set this to 'horizontal or 'below.
+
+If this value is 'any and `display-buffer-alist' is set then
+`display-buffer' is used for open buffer function"
+ :group 'markdown
+ :type '(choice (const :tag "Automatic" any)
+ (const :tag "Right (vertical)" right)
+ (const :tag "Below (horizontal)" below))
+ :package-version '(markdown-mode . "2.2"))
+
+(defcustom markdown-live-preview-window-function
+ #'markdown-live-preview-window-eww
+ "Function to display preview of Markdown output within Emacs.
+Function must update the buffer containing the preview and return
+the buffer."
+ :group 'markdown
+ :type 'function)
+
+(defcustom markdown-live-preview-delete-export 'delete-on-destroy
+ "Delete exported HTML file when using `markdown-live-preview-export'.
+If set to 'delete-on-export, delete on every export. When set to
+'delete-on-destroy delete when quitting from command
+`markdown-live-preview-mode'. Never delete if set to nil."
+ :group 'markdown
+ :type '(choice
+ (const :tag "Delete on every export" delete-on-export)
+ (const :tag "Delete when quitting live preview" delete-on-destroy)
+ (const :tag "Never delete" nil)))
+
+(defcustom markdown-list-indent-width 4
+ "Depth of indentation for markdown lists.
+Used in `markdown-demote-list-item' and
+`markdown-promote-list-item'."
+ :group 'markdown
+ :type 'integer)
+
+(defcustom markdown-enable-prefix-prompts t
+ "Display prompts for certain prefix commands.
+Set to nil to disable these prompts."
+ :group 'markdown
+ :type 'boolean
+ :safe 'booleanp
+ :package-version '(markdown-mode . "2.3"))
+
+(defcustom markdown-gfm-additional-languages nil
+ "Extra languages made available when inserting GFM code blocks.
+Language strings must have be trimmed of whitespace and not
+contain any curly braces. They may be of arbitrary
+capitalization, though."
+ :group 'markdown
+ :type '(repeat (string :validate markdown-validate-language-string)))
+
+(defcustom markdown-gfm-use-electric-backquote t
+ "Use `markdown-electric-backquote' when backquote is hit three times."
+ :group 'markdown
+ :type 'boolean)
+
+(defcustom markdown-gfm-downcase-languages t
+ "If non-nil, downcase suggested languages.
+This applies to insertions done with
+`markdown-electric-backquote'."
+ :group 'markdown
+ :type 'boolean)
+
+(defcustom markdown-edit-code-block-default-mode 'normal-mode
+ "Default mode to use for editing code blocks.
+This mode is used when automatic detection fails, such as for GFM
+code blocks with no language specified."
+ :group 'markdown
+ :type '(choice function (const :tag "None" nil))
+ :package-version '(markdown-mode . "2.4"))
+
+(defcustom markdown-gfm-uppercase-checkbox nil
+ "If non-nil, use [X] for completed checkboxes, [x] otherwise."
+ :group 'markdown
+ :type 'boolean
+ :safe 'booleanp)
+
+(defcustom markdown-hide-urls nil
+ "Hide URLs of inline links and reference tags of reference links.
+Such URLs will be replaced by a single customizable
+character, defined by `markdown-url-compose-char', but are still part
+of the buffer. Links can be edited interactively with
+\\[markdown-insert-link] or, for example, by deleting the final
+parenthesis to remove the invisibility property. You can also
+hover your mouse pointer over the link text to see the URL.
+Set this to a non-nil value to turn this feature on by default.
+You can interactively set the value of this variable by calling
+`markdown-toggle-url-hiding', pressing \\[markdown-toggle-url-hiding],
+or from the menu Markdown > Links & Images menu."
+ :group 'markdown
+ :type 'boolean
+ :safe 'booleanp
+ :package-version '(markdown-mode . "2.3"))
+(make-variable-buffer-local 'markdown-hide-urls)
+
+(defcustom markdown-translate-filename-function #'identity
+ "Function to use to translate filenames when following links.
+\\<markdown-mode-map>\\[markdown-follow-thing-at-point] and \\[markdown-follow-link-at-point]
+call this function with the filename as only argument whenever
+they encounter a filename (instead of a URL) to be visited and
+use its return value instead of the filename in the link. For
+example, if absolute filenames are actually relative to a server
+root directory, you can set
+`markdown-translate-filename-function' to a function that
+prepends the root directory to the given filename."
+ :group 'markdown
+ :type 'function
+ :risky t
+ :package-version '(markdown-mode . "2.4"))
+
+(defcustom markdown-max-image-size nil
+ "Maximum width and height for displayed inline images.
+This variable may be nil or a cons cell (MAX-WIDTH . MAX-HEIGHT).
+When nil, use the actual size. Otherwise, use ImageMagick to
+resize larger images to be of the given maximum dimensions. This
+requires Emacs to be built with ImageMagick support."
+ :group 'markdown
+ :package-version '(markdown-mode . "2.4")
+ :type '(choice
+ (const :tag "Use actual image width" nil)
+ (cons (choice (sexp :tag "Maximum width in pixels")
+ (const :tag "No maximum width" nil))
+ (choice (sexp :tag "Maximum height in pixels")
+ (const :tag "No maximum height" nil)))))
+
+(defcustom markdown-mouse-follow-link t
+ "Non-nil means mouse on a link will follow the link.
+This variable must be set before loading markdown-mode."
+ :group 'markdown
+ :type 'boolean
+ :safe 'booleanp
+ :package-version '(markdown-mode . "2.5"))
+
+(defcustom markdown-table-align-p t
+ "Non-nil means that table is aligned after table operation."
+ :group 'markdown
+ :type 'boolean
+ :safe 'booleanp
+ :package-version '(markdown-mode . "2.5"))
+
+
+;;; Markdown-Specific `rx' Macro ==============================================
+
+;; Based on python-rx from python.el.
+(eval-and-compile
+ (defconst markdown-rx-constituents
+ `((newline . ,(rx "\n"))
+ ;; Note: #405 not consider markdown-list-indent-width however this is never used
+ (indent . ,(rx (or (repeat 4 " ") "\t")))
+ (block-end . ,(rx (and (or (one-or-more (zero-or-more blank) "\n") line-end))))
+ (numeral . ,(rx (and (one-or-more (any "0-9#")) ".")))
+ (bullet . ,(rx (any "*+:-")))
+ (list-marker . ,(rx (or (and (one-or-more (any "0-9#")) ".")
+ (any "*+:-"))))
+ (checkbox . ,(rx "[" (any " xX") "]")))
+ "Markdown-specific sexps for `markdown-rx'")
+
+ (defun markdown-rx-to-string (form &optional no-group)
+ "Markdown mode specialized `rx-to-string' function.
+This variant supports named Markdown expressions in FORM.
+NO-GROUP non-nil means don't put shy groups around the result."
+ (let ((rx-constituents (append markdown-rx-constituents rx-constituents)))
+ (rx-to-string form no-group)))
+
+ (defmacro markdown-rx (&rest regexps)
+ "Markdown mode specialized rx macro.
+This variant of `rx' supports common Markdown named REGEXPS."
+ (cond ((null regexps)
+ (error "No regexp"))
+ ((cdr regexps)
+ (markdown-rx-to-string `(and ,@regexps) t))
+ (t
+ (markdown-rx-to-string (car regexps) t)))))
+
+
+;;; Regular Expressions =======================================================
+
+(defconst markdown-regex-comment-start
+ "<!--"
+ "Regular expression matches HTML comment opening.")
+
+(defconst markdown-regex-comment-end
+ "--[ \t]*>"
+ "Regular expression matches HTML comment closing.")
+
+(defconst markdown-regex-link-inline
+ "\\(?1:!\\)?\\(?2:\\[\\)\\(?3:\\^?\\(?:\\\\\\]\\|[^]]\\)*\\|\\)\\(?4:\\]\\)\\(?5:(\\)\\s-*\\(?6:[^)]*?\\)\\(?:\\s-+\\(?7:\"[^\"]*\"\\)\\)?\\s-*\\(?8:)\\)"
+ "Regular expression for a [text](file) or an image link ![text](file).
+Group 1 matches the leading exclamation point (optional).
+Group 2 matches the opening square bracket.
+Group 3 matches the text inside the square brackets.
+Group 4 matches the closing square bracket.
+Group 5 matches the opening parenthesis.
+Group 6 matches the URL.
+Group 7 matches the title (optional).
+Group 8 matches the closing parenthesis.")
+
+(defconst markdown-regex-link-reference
+ "\\(?1:!\\)?\\(?2:\\[\\)\\(?3:[^]^][^]]*\\|\\)\\(?4:\\]\\)[ ]?\\(?5:\\[\\)\\(?6:[^]]*?\\)\\(?7:\\]\\)"
+ "Regular expression for a reference link [text][id].
+Group 1 matches the leading exclamation point (optional).
+Group 2 matches the opening square bracket for the link text.
+Group 3 matches the text inside the square brackets.
+Group 4 matches the closing square bracket for the link text.
+Group 5 matches the opening square bracket for the reference label.
+Group 6 matches the reference label.
+Group 7 matches the closing square bracket for the reference label.")
+
+(defconst markdown-regex-reference-definition
+ "^ \\{0,3\\}\\(?1:\\[\\)\\(?2:[^]\n]+?\\)\\(?3:\\]\\)\\(?4::\\)\\s *\\(?5:.*?\\)\\s *\\(?6: \"[^\"]*\"$\\|$\\)"
+ "Regular expression for a reference definition.
+Group 1 matches the opening square bracket.
+Group 2 matches the reference label.
+Group 3 matches the closing square bracket.
+Group 4 matches the colon.
+Group 5 matches the URL.
+Group 6 matches the title attribute (optional).")
+
+(defconst markdown-regex-footnote
+ "\\(?1:\\[\\^\\)\\(?2:.+?\\)\\(?3:\\]\\)"
+ "Regular expression for a footnote marker [^fn].
+Group 1 matches the opening square bracket and carat.
+Group 2 matches only the label, without the surrounding markup.
+Group 3 matches the closing square bracket.")
+
+(defconst markdown-regex-header
+ "^\\(?:\\(?1:[^\r\n\t -].*\\)\n\\(?:\\(?2:=+\\)\\|\\(?3:-+\\)\\)\\|\\(?4:#+[ \t]+\\)\\(?5:.*?\\)\\(?6:[ \t]*#*\\)\\)$"
+ "Regexp identifying Markdown headings.
+Group 1 matches the text of a setext heading.
+Group 2 matches the underline of a level-1 setext heading.
+Group 3 matches the underline of a level-2 setext heading.
+Group 4 matches the opening hash marks of an atx heading and whitespace.
+Group 5 matches the text, without surrounding whitespace, of an atx heading.
+Group 6 matches the closing whitespace and hash marks of an atx heading.")
+
+(defconst markdown-regex-header-setext
+ "^\\([^\r\n\t -].*\\)\n\\(=+\\|-+\\)$"
+ "Regular expression for generic setext-style (underline) headers.")
+
+(defconst markdown-regex-header-atx
+ "^\\(#+\\)[ \t]+\\(.*?\\)[ \t]*\\(#*\\)$"
+ "Regular expression for generic atx-style (hash mark) headers.")
+
+(defconst markdown-regex-hr
+ (rx line-start
+ (group (or (and (repeat 3 (and "*" (? " "))) (* (any "* ")))
+ (and (repeat 3 (and "-" (? " "))) (* (any "- ")))
+ (and (repeat 3 (and "_" (? " "))) (* (any "_ ")))))
+ line-end)
+ "Regular expression for matching Markdown horizontal rules.")
+
+(defconst markdown-regex-code
+ "\\(?:\\`\\|[^\\]\\)\\(?1:\\(?2:`+\\)\\(?3:\\(?:.\\|\n[^\n]\\)*?[^`]\\)\\(?4:\\2\\)\\)\\(?:[^`]\\|\\'\\)"
+ "Regular expression for matching inline code fragments.
+
+Group 1 matches the entire code fragment including the backquotes.
+Group 2 matches the opening backquotes.
+Group 3 matches the code fragment itself, without backquotes.
+Group 4 matches the closing backquotes.
+
+The leading, unnumbered group ensures that the leading backquote
+character is not escaped.
+The last group, also unnumbered, requires that the character
+following the code fragment is not a backquote.
+Note that \\(?:.\\|\n[^\n]\\) matches any character, including newlines,
+but not two newlines in a row.")
+
+(defconst markdown-regex-kbd
+ "\\(?1:<kbd>\\)\\(?2:\\(?:.\\|\n[^\n]\\)*?\\)\\(?3:</kbd>\\)"
+ "Regular expression for matching <kbd> tags.
+Groups 1 and 3 match the opening and closing tags.
+Group 2 matches the key sequence.")
+
+(defconst markdown-regex-gfm-code-block-open
+ "^[[:blank:]]*\\(?1:```\\)\\(?2:[[:blank:]]*{?[[:blank:]]*\\)\\(?3:[^`[:space:]]+?\\)?\\(?:[[:blank:]]+\\(?4:.+?\\)\\)?\\(?5:[[:blank:]]*}?[[:blank:]]*\\)$"
+ "Regular expression matching opening of GFM code blocks.
+Group 1 matches the opening three backquotes and any following whitespace.
+Group 2 matches the opening brace (optional) and surrounding whitespace.
+Group 3 matches the language identifier (optional).
+Group 4 matches the info string (optional).
+Group 5 matches the closing brace (optional), whitespace, and newline.
+Groups need to agree with `markdown-regex-tilde-fence-begin'.")
+
+(defconst markdown-regex-gfm-code-block-close
+ "^[[:blank:]]*\\(?1:```\\)\\(?2:\\s *?\\)$"
+ "Regular expression matching closing of GFM code blocks.
+Group 1 matches the closing three backquotes.
+Group 2 matches any whitespace and the final newline.")
+
+(defconst markdown-regex-pre
+ "^\\( \\|\t\\).*$"
+ "Regular expression for matching preformatted text sections.")
+
+(defconst markdown-regex-list
+ (markdown-rx line-start
+ ;; 1. Leading whitespace
+ (group (* blank))
+ ;; 2. List marker: a numeral, bullet, or colon
+ (group list-marker)
+ ;; 3. Trailing whitespace
+ (group (+ blank))
+ ;; 4. Optional checkbox for GFM task list items
+ (opt (group (and checkbox (* blank)))))
+ "Regular expression for matching list items.")
+
+(defconst markdown-regex-bold
+ "\\(?1:^\\|[^\\]\\)\\(?2:\\(?3:\\*\\*\\|__\\)\\(?4:[^ \n\t\\]\\|[^ \n\t]\\(?:.\\|\n[^\n]\\)*?[^\\ ]\\)\\(?5:\\3\\)\\)"
+ "Regular expression for matching bold text.
+Group 1 matches the character before the opening asterisk or
+underscore, if any, ensuring that it is not a backslash escape.
+Group 2 matches the entire expression, including delimiters.
+Groups 3 and 5 matches the opening and closing delimiters.
+Group 4 matches the text inside the delimiters.")
+
+(defconst markdown-regex-italic
+ "\\(?:^\\|[^\\]\\)\\(?1:\\(?2:[*_]\\)\\(?3:[^ \n\t\\]\\|[^ \n\t*]\\(?:.\\|\n[^\n]\\)*?[^\\ ]\\)\\(?4:\\2\\)\\)"
+ "Regular expression for matching italic text.
+The leading unnumbered matches the character before the opening
+asterisk or underscore, if any, ensuring that it is not a
+backslash escape.
+Group 1 matches the entire expression, including delimiters.
+Groups 2 and 4 matches the opening and closing delimiters.
+Group 3 matches the text inside the delimiters.")
+
+(defconst markdown-regex-strike-through
+ "\\(?1:^\\|[^\\]\\)\\(?2:\\(?3:~~\\)\\(?4:[^ \n\t\\]\\|[^ \n\t]\\(?:.\\|\n[^\n]\\)*?[^\\ ]\\)\\(?5:~~\\)\\)"
+ "Regular expression for matching strike-through text.
+Group 1 matches the character before the opening tilde, if any,
+ensuring that it is not a backslash escape.
+Group 2 matches the entire expression, including delimiters.
+Groups 3 and 5 matches the opening and closing delimiters.
+Group 4 matches the text inside the delimiters.")
+
+(defconst markdown-regex-gfm-italic
+ "\\(?:^\\|[^\\]\\)\\(?1:\\(?2:[*_]\\)\\(?3:[^ \\]\\2\\|[^ ]\\(?:.\\|\n[^\n]\\)*?\\)\\(?4:\\2\\)\\)"
+ "Regular expression for matching italic text in GitHub Flavored Markdown.
+Underscores in words are not treated as special.
+Group 1 matches the entire expression, including delimiters.
+Groups 2 and 4 matches the opening and closing delimiters.
+Group 3 matches the text inside the delimiters.")
+
+(defconst markdown-regex-blockquote
+ "^[ \t]*\\(?1:[A-Z]?>\\)\\(?2:[ \t]*\\)\\(?3:.*\\)$"
+ "Regular expression for matching blockquote lines.
+Also accounts for a potential capital letter preceding the angle
+bracket, for use with Leanpub blocks (asides, warnings, info
+blocks, etc.).
+Group 1 matches the leading angle bracket.
+Group 2 matches the separating whitespace.
+Group 3 matches the text.")
+
+(defconst markdown-regex-line-break
+ "[^ \n\t][ \t]*\\( \\)\n"
+ "Regular expression for matching line breaks.")
+
+(defconst markdown-regex-wiki-link
+ "\\(?:^\\|[^\\]\\)\\(?1:\\(?2:\\[\\[\\)\\(?3:[^]|]+\\)\\(?:\\(?4:|\\)\\(?5:[^]]+\\)\\)?\\(?6:\\]\\]\\)\\)"
+ "Regular expression for matching wiki links.
+This matches typical bracketed [[WikiLinks]] as well as 'aliased'
+wiki links of the form [[PageName|link text]].
+The meanings of the first and second components depend
+on the value of `markdown-wiki-link-alias-first'.
+
+Group 1 matches the entire link.
+Group 2 matches the opening square brackets.
+Group 3 matches the first component of the wiki link.
+Group 4 matches the pipe separator, when present.
+Group 5 matches the second component of the wiki link, when present.
+Group 6 matches the closing square brackets.")
+
+(defconst markdown-regex-uri
+ (concat "\\(" (regexp-opt markdown-uri-types) ":[^]\t\n\r<>; ]+\\)")
+ "Regular expression for matching inline URIs.")
+
+(defconst markdown-regex-angle-uri
+ (concat "\\(<\\)\\(" (regexp-opt markdown-uri-types) ":[^]\t\n\r<>,;()]+\\)\\(>\\)")
+ "Regular expression for matching inline URIs in angle brackets.")
+
+(defconst markdown-regex-email
+ "<\\(\\(?:\\sw\\|\\s_\\|\\s.\\)+@\\(?:\\sw\\|\\s_\\|\\s.\\)+\\)>"
+ "Regular expression for matching inline email addresses.")
+
+(defsubst markdown-make-regex-link-generic ()
+ "Make regular expression for matching any recognized link."
+ (concat "\\(?:" markdown-regex-link-inline
+ (when markdown-enable-wiki-links
+ (concat "\\|" markdown-regex-wiki-link))
+ "\\|" markdown-regex-link-reference
+ "\\|" markdown-regex-angle-uri "\\)"))
+
+(defconst markdown-regex-gfm-checkbox
+ " \\(\\[[ xX]\\]\\) "
+ "Regular expression for matching GFM checkboxes.
+Group 1 matches the text to become a button.")
+
+(defconst markdown-regex-blank-line
+ "^[[:blank:]]*$"
+ "Regular expression that matches a blank line.")
+
+(defconst markdown-regex-block-separator
+ "\n[\n\t\f ]*\n"
+ "Regular expression for matching block boundaries.")
+
+(defconst markdown-regex-block-separator-noindent
+ (concat "\\(\\`\\|\\(" markdown-regex-block-separator "\\)[^\n\t\f ]\\)")
+ "Regexp for block separators before lines with no indentation.")
+
+(defconst markdown-regex-math-inline-single
+ "\\(?:^\\|[^\\]\\)\\(?1:\\$\\)\\(?2:\\(?:[^\\$]\\|\\\\.\\)*\\)\\(?3:\\$\\)"
+ "Regular expression for itex $..$ math mode expressions.
+Groups 1 and 3 match the opening and closing dollar signs.
+Group 2 matches the mathematical expression contained within.")
+
+(defconst markdown-regex-math-inline-double
+ "\\(?:^\\|[^\\]\\)\\(?1:\\$\\$\\)\\(?2:\\(?:[^\\$]\\|\\\\.\\)*\\)\\(?3:\\$\\$\\)"
+ "Regular expression for itex $$..$$ math mode expressions.
+Groups 1 and 3 match opening and closing dollar signs.
+Group 2 matches the mathematical expression contained within.")
+
+(defconst markdown-regex-math-display
+ (rx line-start (* blank)
+ (group (group (repeat 1 2 "\\")) "[")
+ (group (*? anything))
+ (group (backref 2) "]")
+ line-end)
+ "Regular expression for \[..\] or \\[..\\] display math.
+Groups 1 and 4 match the opening and closing markup.
+Group 3 matches the mathematical expression contained within.
+Group 2 matches the opening slashes, and is used internally to
+match the closing slashes.")
+
+(defsubst markdown-make-tilde-fence-regex (num-tildes &optional end-of-line)
+ "Return regexp matching a tilde code fence at least NUM-TILDES long.
+END-OF-LINE is the regexp construct to indicate end of line; $ if
+missing."
+ (format "%s%d%s%s" "^[[:blank:]]*\\([~]\\{" num-tildes ",\\}\\)"
+ (or end-of-line "$")))
+
+(defconst markdown-regex-tilde-fence-begin
+ (markdown-make-tilde-fence-regex
+ 3 "\\([[:blank:]]*{?\\)[[:blank:]]*\\([^[:space:]]+?\\)?\\(?:[[:blank:]]+\\(.+?\\)\\)?\\([[:blank:]]*}?[[:blank:]]*\\)$")
+ "Regular expression for matching tilde-fenced code blocks.
+Group 1 matches the opening tildes.
+Group 2 matches (optional) opening brace and surrounding whitespace.
+Group 3 matches the language identifier (optional).
+Group 4 matches the info string (optional).
+Group 5 matches the closing brace (optional) and any surrounding whitespace.
+Groups need to agree with `markdown-regex-gfm-code-block-open'.")
+
+(defconst markdown-regex-declarative-metadata
+ "^[ \t]*\\(?:-[ \t]*\\)?\\([[:alpha:]][[:alpha:] _-]*?\\)\\([:=][ \t]*\\)\\(.*\\)$"
+ "Regular expression for matching declarative metadata statements.
+This matches MultiMarkdown metadata as well as YAML and TOML
+assignments such as the following:
+
+ variable: value
+
+or
+
+ variable = value")
+
+(defconst markdown-regex-pandoc-metadata
+ "^\\(%\\)\\([ \t]*\\)\\(.*\\(?:\n[ \t]+.*\\)*\\)"
+ "Regular expression for matching Pandoc metadata.")
+
+(defconst markdown-regex-yaml-metadata-border
+ "\\(-\\{3\\}\\)$"
+ "Regular expression for matching YAML metadata.")
+
+(defconst markdown-regex-yaml-pandoc-metadata-end-border
+ "^\\(\\.\\{3\\}\\|\\-\\{3\\}\\)$"
+ "Regular expression for matching YAML metadata end borders.")
+
+(defsubst markdown-get-yaml-metadata-start-border ()
+ "Return YAML metadata start border depending upon whether Pandoc is used."
+ (concat
+ (if markdown-use-pandoc-style-yaml-metadata "^" "\\`")
+ markdown-regex-yaml-metadata-border))
+
+(defsubst markdown-get-yaml-metadata-end-border (_)
+ "Return YAML metadata end border depending upon whether Pandoc is used."
+ (if markdown-use-pandoc-style-yaml-metadata
+ markdown-regex-yaml-pandoc-metadata-end-border
+ markdown-regex-yaml-metadata-border))
+
+(defconst markdown-regex-inline-attributes
+ "[ \t]*\\(?:{:?\\)[ \t]*\\(?:\\(?:#[[:alpha:]_.:-]+\\|\\.[[:alpha:]_.:-]+\\|\\w+=['\"]?[^\n'\"}]*['\"]?\\),?[ \t]*\\)+\\(?:}\\)[ \t]*$"
+ "Regular expression for matching inline identifiers or attribute lists.
+Compatible with Pandoc, Python Markdown, PHP Markdown Extra, and Leanpub.")
+
+(defconst markdown-regex-leanpub-sections
+ (concat
+ "^\\({\\)\\("
+ (regexp-opt '("frontmatter" "mainmatter" "backmatter" "appendix" "pagebreak"))
+ "\\)\\(}\\)[ \t]*\n")
+ "Regular expression for Leanpub section markers and related syntax.")
+
+(defconst markdown-regex-sub-superscript
+ "\\(?:^\\|[^\\~^]\\)\\(?1:\\(?2:[~^]\\)\\(?3:[+-\u2212]?[[:alnum:]]+\\)\\(?4:\\2\\)\\)"
+ "The regular expression matching a sub- or superscript.
+The leading un-numbered group matches the character before the
+opening tilde or carat, if any, ensuring that it is not a
+backslash escape, carat, or tilde.
+Group 1 matches the entire expression, including markup.
+Group 2 matches the opening markup--a tilde or carat.
+Group 3 matches the text inside the delimiters.
+Group 4 matches the closing markup--a tilde or carat.")
+
+(defconst markdown-regex-include
+ "^\\(?1:<<\\)\\(?:\\(?2:\\[\\)\\(?3:.*\\)\\(?4:\\]\\)\\)?\\(?:\\(?5:(\\)\\(?6:.*\\)\\(?7:)\\)\\)?\\(?:\\(?8:{\\)\\(?9:.*\\)\\(?10:}\\)\\)?$"
+ "Regular expression matching common forms of include syntax.
+Marked 2, Leanpub, and other processors support some of these forms:
+
+<<[sections/section1.md]
+<<(folder/filename)
+<<[Code title](folder/filename)
+<<{folder/raw_file.html}
+
+Group 1 matches the opening two angle brackets.
+Groups 2-4 match the opening square bracket, the text inside,
+and the closing square bracket, respectively.
+Groups 5-7 match the opening parenthesis, the text inside, and
+the closing parenthesis.
+Groups 8-10 match the opening brace, the text inside, and the brace.")
+
+(defconst markdown-regex-pandoc-inline-footnote
+ "\\(?1:\\^\\)\\(?2:\\[\\)\\(?3:\\(?:.\\|\n[^\n]\\)*?\\)\\(?4:\\]\\)"
+ "Regular expression for Pandoc inline footnote^[footnote text].
+Group 1 matches the opening caret.
+Group 2 matches the opening square bracket.
+Group 3 matches the footnote text, without the surrounding markup.
+Group 4 matches the closing square bracket.")
+
+(defconst markdown-regex-html-attr
+ "\\(\\<[[:alpha:]:-]+\\>\\)\\(\\s-*\\(=\\)\\s-*\\(\".*?\"\\|'.*?'\\|[^'\">[:space:]]+\\)?\\)?"
+ "Regular expression for matching HTML attributes and values.
+Group 1 matches the attribute name.
+Group 2 matches the following whitespace, equals sign, and value, if any.
+Group 3 matches the equals sign, if any.
+Group 4 matches single-, double-, or un-quoted attribute values.")
+
+(defconst markdown-regex-html-tag
+ (concat "\\(</?\\)\\(\\w+\\)\\(\\(\\s-+" markdown-regex-html-attr
+ "\\)+\\s-*\\|\\s-*\\)\\(/?>\\)")
+ "Regular expression for matching HTML tags.
+Groups 1 and 9 match the beginning and ending angle brackets and slashes.
+Group 2 matches the tag name.
+Group 3 matches all attributes and whitespace following the tag name.")
+
+(defconst markdown-regex-html-entity
+ "\\(&#?[[:alnum:]]+;\\)"
+ "Regular expression for matching HTML entities.")
+
+(defconst markdown-regex-highlighting
+ "\\(?1:^\\|[^\\]\\)\\(?2:\\(?3:==\\)\\(?4:[^ \n\t\\]\\|[^ \n\t]\\(?:.\\|\n[^\n]\\)*?[^\\ ]\\)\\(?5:==\\)\\)"
+"Regular expression for matching highlighting text.
+Group 1 matches the character before the opening equal, if any,
+ensuring that it is not a backslash escape.
+Group 2 matches the entire expression, including delimiters.
+Groups 3 and 5 matches the opening and closing delimiters.
+Group 4 matches the text inside the delimiters.")
+
+
+;;; Syntax ====================================================================
+
+(defvar markdown--syntax-properties
+ (list 'markdown-tilde-fence-begin nil
+ 'markdown-tilde-fence-end nil
+ 'markdown-fenced-code nil
+ 'markdown-yaml-metadata-begin nil
+ 'markdown-yaml-metadata-end nil
+ 'markdown-yaml-metadata-section nil
+ 'markdown-gfm-block-begin nil
+ 'markdown-gfm-block-end nil
+ 'markdown-gfm-code nil
+ 'markdown-list-item nil
+ 'markdown-pre nil
+ 'markdown-blockquote nil
+ 'markdown-hr nil
+ 'markdown-comment nil
+ 'markdown-heading nil
+ 'markdown-heading-1-setext nil
+ 'markdown-heading-2-setext nil
+ 'markdown-heading-1-atx nil
+ 'markdown-heading-2-atx nil
+ 'markdown-heading-3-atx nil
+ 'markdown-heading-4-atx nil
+ 'markdown-heading-5-atx nil
+ 'markdown-heading-6-atx nil
+ 'markdown-metadata-key nil
+ 'markdown-metadata-value nil
+ 'markdown-metadata-markup nil)
+ "Property list of all Markdown syntactic properties.")
+
+(defsubst markdown-in-comment-p (&optional pos)
+ "Return non-nil if POS is in a comment.
+If POS is not given, use point instead."
+ (get-text-property (or pos (point)) 'markdown-comment))
+
+(defun markdown--face-p (pos faces)
+ "Return non-nil if face of POS contain FACES."
+ (let ((face-prop (get-text-property pos 'face)))
+ (if (listp face-prop)
+ (cl-loop for face in face-prop
+ thereis (memq face faces))
+ (memq face-prop faces))))
+
+(defun markdown-syntax-propertize-extend-region (start end)
+ "Extend START to END region to include an entire block of text.
+This helps improve syntax analysis for block constructs.
+Returns a cons (NEW-START . NEW-END) or nil if no adjustment should be made.
+Function is called repeatedly until it returns nil. For details, see
+`syntax-propertize-extend-region-functions'."
+ (save-match-data
+ (save-excursion
+ (let* ((new-start (progn (goto-char start)
+ (skip-chars-forward "\n")
+ (if (re-search-backward "\n\n" nil t)
+ (min start (match-end 0))
+ (point-min))))
+ (new-end (progn (goto-char end)
+ (skip-chars-backward "\n")
+ (if (re-search-forward "\n\n" nil t)
+ (max end (match-beginning 0))
+ (point-max))))
+ (code-match (markdown-code-block-at-pos new-start))
+ ;; FIXME: The `code-match' can return bogus values
+ ;; when text has been inserted/deleted!
+ (new-start (min (or (and code-match (cl-first code-match))
+ (point-max))
+ new-start))
+ (code-match (and (< end (point-max))
+ (markdown-code-block-at-pos end)))
+ (new-end (max (or (and code-match (cl-second code-match)) 0)
+ new-end)))
+
+ (unless (and (eq new-start start) (eq new-end end))
+ (cons new-start (min new-end (point-max))))))))
+
+(defun markdown-font-lock-extend-region-function (start end _)
+ "Used in `jit-lock-after-change-extend-region-functions'.
+Delegates to `markdown-syntax-propertize-extend-region'. START
+and END are the previous region to refontify."
+ (let ((res (markdown-syntax-propertize-extend-region start end)))
+ (when res
+ ;; syntax-propertize-function is not called when character at
+ ;; (point-max) is deleted, but font-lock-extend-region-functions
+ ;; are called. Force a syntax property update in that case.
+ (when (= end (point-max))
+ ;; This function is called in a buffer modification hook.
+ ;; `markdown-syntax-propertize' doesn't save the match data,
+ ;; so we have to do it here.
+ (save-match-data
+ (markdown-syntax-propertize (car res) (cdr res))))
+ (setq jit-lock-start (car res)
+ jit-lock-end (cdr res)))))
+
+(defun markdown--cur-list-item-bounds ()
+ "Return a list describing the list item at point.
+Assumes that match data is set for `markdown-regex-list'. See the
+documentation for `markdown-cur-list-item-bounds' for the format of
+the returned list."
+ (save-excursion
+ (let* ((begin (match-beginning 0))
+ (indent (length (match-string-no-properties 1)))
+ (nonlist-indent (- (match-end 3) (match-beginning 0)))
+ (marker (buffer-substring-no-properties
+ (match-beginning 2) (match-end 3)))
+ (checkbox (match-string-no-properties 4))
+ (match (butlast (match-data t)))
+ (end (markdown-cur-list-item-end nonlist-indent)))
+ (list begin end indent nonlist-indent marker checkbox match))))
+
+(defun markdown--append-list-item-bounds (marker indent cur-bounds bounds)
+ "Update list item BOUNDS given list MARKER, block INDENT, and CUR-BOUNDS.
+Here, MARKER is a string representing the type of list and INDENT
+is an integer giving the indentation, in spaces, of the current
+block. CUR-BOUNDS is a list of the form returned by
+`markdown-cur-list-item-bounds' and BOUNDS is a list of bounds
+values for parent list items. When BOUNDS is nil, it means we are
+at baseline (not inside of a nested list)."
+ (let ((prev-indent (or (cl-third (car bounds)) 0)))
+ (cond
+ ;; New list item at baseline.
+ ((and marker (null bounds))
+ (list cur-bounds))
+ ;; List item with greater indentation (four or more spaces).
+ ;; Increase list level by consing CUR-BOUNDS onto BOUNDS.
+ ((and marker (>= indent (+ prev-indent markdown-list-indent-width)))
+ (cons cur-bounds bounds))
+ ;; List item with greater or equal indentation (less than four spaces).
+ ;; Keep list level the same by replacing the car of BOUNDS.
+ ((and marker (>= indent prev-indent))
+ (cons cur-bounds (cdr bounds)))
+ ;; Lesser indentation level.
+ ;; Pop appropriate number of elements off BOUNDS list (e.g., lesser
+ ;; indentation could move back more than one list level). Note
+ ;; that this block need not be the beginning of list item.
+ ((< indent prev-indent)
+ (while (and (> (length bounds) 1)
+ (setq prev-indent (cl-third (cadr bounds)))
+ (< indent (+ prev-indent markdown-list-indent-width)))
+ (setq bounds (cdr bounds)))
+ (cons cur-bounds bounds))
+ ;; Otherwise, do nothing.
+ (t bounds))))
+
+(defun markdown-syntax-propertize-list-items (start end)
+ "Propertize list items from START to END.
+Stores nested list item information in the `markdown-list-item'
+text property to make later syntax analysis easier. The value of
+this property is a list with elements of the form (begin . end)
+giving the bounds of the current and parent list items."
+ (save-excursion
+ (goto-char start)
+ (let ((prev-list-line -100)
+ bounds level pre-regexp)
+ ;; Find a baseline point with zero list indentation
+ (markdown-search-backward-baseline)
+ ;; Search for all list items between baseline and END
+ (while (and (< (point) end)
+ (re-search-forward markdown-regex-list end 'limit))
+ ;; Level of list nesting
+ (setq level (length bounds))
+ ;; Pre blocks need to be indented one level past the list level
+ (setq pre-regexp (format "^\\( \\|\t\\)\\{%d\\}" (1+ level)))
+ (beginning-of-line)
+ (cond
+ ;; Reset at headings, horizontal rules, and top-level blank lines.
+ ;; Propertize baseline when in range.
+ ((markdown-new-baseline)
+ (setq bounds nil))
+ ;; Make sure this is not a line from a pre block
+ ((and (looking-at-p pre-regexp)
+ ;; too indented line is also treated as list if previous line is list
+ (>= (- (line-number-at-pos) prev-list-line) 2)))
+ ;; If not, then update levels and propertize list item when in range.
+ (t
+ (let* ((indent (current-indentation))
+ (cur-bounds (markdown--cur-list-item-bounds))
+ (first (cl-first cur-bounds))
+ (last (cl-second cur-bounds))
+ (marker (cl-fifth cur-bounds)))
+ (setq bounds (markdown--append-list-item-bounds
+ marker indent cur-bounds bounds))
+ (when (and (<= start (point)) (<= (point) end))
+ (setq prev-list-line (line-number-at-pos first))
+ (put-text-property first last 'markdown-list-item bounds)))))
+ (end-of-line)))))
+
+(defun markdown-syntax-propertize-pre-blocks (start end)
+ "Match preformatted text blocks from START to END."
+ (save-excursion
+ (goto-char start)
+ (let (finish)
+ ;; Use loop for avoiding too many recursive calls
+ ;; https://github.com/jrblevin/markdown-mode/issues/512
+ (while (not finish)
+ (let ((levels (markdown-calculate-list-levels))
+ indent pre-regexp close-regexp open close)
+ (while (and (< (point) end) (not close))
+ ;; Search for a region with sufficient indentation
+ (if (null levels)
+ (setq indent 1)
+ (setq indent (1+ (length levels))))
+ (setq pre-regexp (format "^\\( \\|\t\\)\\{%d\\}" indent))
+ (setq close-regexp (format "^\\( \\|\t\\)\\{0,%d\\}\\([^ \t]\\)" (1- indent)))
+
+ (cond
+ ;; If not at the beginning of a line, move forward
+ ((not (bolp)) (forward-line))
+ ;; Move past blank lines
+ ((markdown-cur-line-blank-p) (forward-line))
+ ;; At headers and horizontal rules, reset levels
+ ((markdown-new-baseline) (forward-line) (setq levels nil))
+ ;; If the current line has sufficient indentation, mark out pre block
+ ;; The opening should be preceded by a blank line.
+ ((and (markdown-prev-line-blank) (looking-at pre-regexp))
+ (setq open (match-beginning 0))
+ (while (and (or (looking-at-p pre-regexp) (markdown-cur-line-blank-p))
+ (not (eobp)))
+ (forward-line))
+ (skip-syntax-backward "-")
+ (setq close (point)))
+ ;; If current line has a list marker, update levels, move to end of block
+ ((looking-at markdown-regex-list)
+ (setq levels (markdown-update-list-levels
+ (match-string 2) (current-indentation) levels))
+ (markdown-end-of-text-block))
+ ;; If this is the end of the indentation level, adjust levels accordingly.
+ ;; Only match end of indentation level if levels is not the empty list.
+ ((and (car levels) (looking-at-p close-regexp))
+ (setq levels (markdown-update-list-levels
+ nil (current-indentation) levels))
+ (markdown-end-of-text-block))
+ (t (markdown-end-of-text-block))))
+
+ (if (and open close)
+ ;; Set text property data and continue to search
+ (put-text-property open close 'markdown-pre (list open close))
+ (setq finish t))))
+ nil)))
+
+(defconst markdown-fenced-block-pairs
+ `(((,markdown-regex-tilde-fence-begin markdown-tilde-fence-begin)
+ (markdown-make-tilde-fence-regex markdown-tilde-fence-end)
+ markdown-fenced-code)
+ ((markdown-get-yaml-metadata-start-border markdown-yaml-metadata-begin)
+ (markdown-get-yaml-metadata-end-border markdown-yaml-metadata-end)
+ markdown-yaml-metadata-section)
+ ((,markdown-regex-gfm-code-block-open markdown-gfm-block-begin)
+ (,markdown-regex-gfm-code-block-close markdown-gfm-block-end)
+ markdown-gfm-code))
+ "Mapping of regular expressions to \"fenced-block\" constructs.
+These constructs are distinguished by having a distinctive start
+and end pattern, both of which take up an entire line of text,
+but no special pattern to identify text within the fenced
+blocks (unlike blockquotes and indented-code sections).
+
+Each element within this list takes the form:
+
+ ((START-REGEX-OR-FUN START-PROPERTY)
+ (END-REGEX-OR-FUN END-PROPERTY)
+ MIDDLE-PROPERTY)
+
+Each *-REGEX-OR-FUN element can be a regular expression as a string, or a
+function which evaluates to same. Functions for START-REGEX-OR-FUN accept no
+arguments, but functions for END-REGEX-OR-FUN accept a single numerical argument
+which is the length of the first group of the START-REGEX-OR-FUN match, which
+can be ignored if unnecessary. `markdown-maybe-funcall-regexp' is used to
+evaluate these into \"real\" regexps.
+
+The *-PROPERTY elements are the text properties applied to each part of the
+block construct when it is matched using
+`markdown-syntax-propertize-fenced-block-constructs'. START-PROPERTY is applied
+to the text matching START-REGEX-OR-FUN, END-PROPERTY to END-REGEX-OR-FUN, and
+MIDDLE-PROPERTY to the text in between the two. The value of *-PROPERTY is the
+`match-data' when the regexp was matched to the text. In the case of
+MIDDLE-PROPERTY, the value is a false match data of the form '(begin end), with
+begin and end set to the edges of the \"middle\" text. This makes fontification
+easier.")
+
+(defun markdown-text-property-at-point (prop)
+ (get-text-property (point) prop))
+
+(defsubst markdown-maybe-funcall-regexp (object &optional arg)
+ (cond ((functionp object)
+ (if arg (funcall object arg) (funcall object)))
+ ((stringp object) object)
+ (t (error "Object cannot be turned into regex"))))
+
+(defsubst markdown-get-start-fence-regexp ()
+ "Return regexp to find all \"start\" sections of fenced block constructs.
+Which construct is actually contained in the match must be found separately."
+ (mapconcat
+ #'identity
+ (mapcar (lambda (entry) (markdown-maybe-funcall-regexp (caar entry)))
+ markdown-fenced-block-pairs)
+ "\\|"))
+
+(defun markdown-get-fenced-block-begin-properties ()
+ (cl-mapcar (lambda (entry) (cl-cadar entry)) markdown-fenced-block-pairs))
+
+(defun markdown-get-fenced-block-end-properties ()
+ (cl-mapcar (lambda (entry) (cl-cadadr entry)) markdown-fenced-block-pairs))
+
+(defun markdown-get-fenced-block-middle-properties ()
+ (cl-mapcar #'cl-third markdown-fenced-block-pairs))
+
+(defun markdown-find-previous-prop (prop &optional lim)
+ "Find previous place where property PROP is non-nil, up to LIM.
+Return a cons of (pos . property). pos is point if point contains
+non-nil PROP."
+ (let ((res
+ (if (get-text-property (point) prop) (point)
+ (previous-single-property-change
+ (point) prop nil (or lim (point-min))))))
+ (when (and (not (get-text-property res prop))
+ (> res (point-min))
+ (get-text-property (1- res) prop))
+ (cl-decf res))
+ (when (and res (get-text-property res prop)) (cons res prop))))
+
+(defun markdown-find-next-prop (prop &optional lim)
+ "Find next place where property PROP is non-nil, up to LIM.
+Return a cons of (POS . PROPERTY) where POS is point if point
+contains non-nil PROP."
+ (let ((res
+ (if (get-text-property (point) prop) (point)
+ (next-single-property-change
+ (point) prop nil (or lim (point-max))))))
+ (when (and res (get-text-property res prop)) (cons res prop))))
+
+(defun markdown-min-of-seq (map-fn seq)
+ "Apply MAP-FN to SEQ and return element of SEQ with minimum value of MAP-FN."
+ (cl-loop for el in seq
+ with min = 1.0e+INF ; infinity
+ with min-el = nil
+ do (let ((res (funcall map-fn el)))
+ (when (< res min)
+ (setq min res)
+ (setq min-el el)))
+ finally return min-el))
+
+(defun markdown-max-of-seq (map-fn seq)
+ "Apply MAP-FN to SEQ and return element of SEQ with maximum value of MAP-FN."
+ (cl-loop for el in seq
+ with max = -1.0e+INF ; negative infinity
+ with max-el = nil
+ do (let ((res (funcall map-fn el)))
+ (when (and res (> res max))
+ (setq max res)
+ (setq max-el el)))
+ finally return max-el))
+
+(defun markdown-find-previous-block ()
+ "Find previous block.
+Detect whether `markdown-syntax-propertize-fenced-block-constructs' was
+unable to propertize the entire block, but was able to propertize the beginning
+of the block. If so, return a cons of (pos . property) where the beginning of
+the block was propertized."
+ (let ((start-pt (point))
+ (closest-open
+ (markdown-max-of-seq
+ #'car
+ (cl-remove-if
+ #'null
+ (cl-mapcar
+ #'markdown-find-previous-prop
+ (markdown-get-fenced-block-begin-properties))))))
+ (when closest-open
+ (let* ((length-of-open-match
+ (let ((match-d
+ (get-text-property (car closest-open) (cdr closest-open))))
+ (- (cl-fourth match-d) (cl-third match-d))))
+ (end-regexp
+ (markdown-maybe-funcall-regexp
+ (cl-caadr
+ (cl-find-if
+ (lambda (entry) (eq (cl-cadar entry) (cdr closest-open)))
+ markdown-fenced-block-pairs))
+ length-of-open-match))
+ (end-prop-loc
+ (save-excursion
+ (save-match-data
+ (goto-char (car closest-open))
+ (and (re-search-forward end-regexp start-pt t)
+ (match-beginning 0))))))
+ (and (not end-prop-loc) closest-open)))))
+
+(defun markdown-get-fenced-block-from-start (prop)
+ "Return limits of an enclosing fenced block from its start, using PROP.
+Return value is a list usable as `match-data'."
+ (catch 'no-rest-of-block
+ (let* ((correct-entry
+ (cl-find-if
+ (lambda (entry) (eq (cl-cadar entry) prop))
+ markdown-fenced-block-pairs))
+ (begin-of-begin (cl-first (markdown-text-property-at-point prop)))
+ (middle-prop (cl-third correct-entry))
+ (end-prop (cl-cadadr correct-entry))
+ (end-of-end
+ (save-excursion
+ (goto-char (match-end 0)) ; end of begin
+ (unless (eobp) (forward-char))
+ (let ((mid-prop-v (markdown-text-property-at-point middle-prop)))
+ (if (not mid-prop-v) ; no middle
+ (progn
+ ;; try to find end by advancing one
+ (let ((end-prop-v
+ (markdown-text-property-at-point end-prop)))
+ (if end-prop-v (cl-second end-prop-v)
+ (throw 'no-rest-of-block nil))))
+ (set-match-data mid-prop-v)
+ (goto-char (match-end 0)) ; end of middle
+ (beginning-of-line) ; into end
+ (cl-second (markdown-text-property-at-point end-prop)))))))
+ (list begin-of-begin end-of-end))))
+
+(defun markdown-get-fenced-block-from-middle (prop)
+ "Return limits of an enclosing fenced block from its middle, using PROP.
+Return value is a list usable as `match-data'."
+ (let* ((correct-entry
+ (cl-find-if
+ (lambda (entry) (eq (cl-third entry) prop))
+ markdown-fenced-block-pairs))
+ (begin-prop (cl-cadar correct-entry))
+ (begin-of-begin
+ (save-excursion
+ (goto-char (match-beginning 0))
+ (unless (bobp) (forward-line -1))
+ (beginning-of-line)
+ (cl-first (markdown-text-property-at-point begin-prop))))
+ (end-prop (cl-cadadr correct-entry))
+ (end-of-end
+ (save-excursion
+ (goto-char (match-end 0))
+ (beginning-of-line)
+ (cl-second (markdown-text-property-at-point end-prop)))))
+ (list begin-of-begin end-of-end)))
+
+(defun markdown-get-fenced-block-from-end (prop)
+ "Return limits of an enclosing fenced block from its end, using PROP.
+Return value is a list usable as `match-data'."
+ (let* ((correct-entry
+ (cl-find-if
+ (lambda (entry) (eq (cl-cadadr entry) prop))
+ markdown-fenced-block-pairs))
+ (end-of-end (cl-second (markdown-text-property-at-point prop)))
+ (middle-prop (cl-third correct-entry))
+ (begin-prop (cl-cadar correct-entry))
+ (begin-of-begin
+ (save-excursion
+ (goto-char (match-beginning 0)) ; beginning of end
+ (unless (bobp) (backward-char)) ; into middle
+ (let ((mid-prop-v (markdown-text-property-at-point middle-prop)))
+ (if (not mid-prop-v)
+ (progn
+ (beginning-of-line)
+ (cl-first (markdown-text-property-at-point begin-prop)))
+ (set-match-data mid-prop-v)
+ (goto-char (match-beginning 0)) ; beginning of middle
+ (unless (bobp) (forward-line -1)) ; into beginning
+ (beginning-of-line)
+ (cl-first (markdown-text-property-at-point begin-prop)))))))
+ (list begin-of-begin end-of-end)))
+
+(defun markdown-get-enclosing-fenced-block-construct (&optional pos)
+ "Get \"fake\" match data for block enclosing POS.
+Returns fake match data which encloses the start, middle, and end
+of the block construct enclosing POS, if it exists. Used in
+`markdown-code-block-at-pos'."
+ (save-excursion
+ (when pos (goto-char pos))
+ (beginning-of-line)
+ (car
+ (cl-remove-if
+ #'null
+ (cl-mapcar
+ (lambda (fun-and-prop)
+ (cl-destructuring-bind (fun prop) fun-and-prop
+ (when prop
+ (save-match-data
+ (set-match-data (markdown-text-property-at-point prop))
+ (funcall fun prop)))))
+ `((markdown-get-fenced-block-from-start
+ ,(cl-find-if
+ #'markdown-text-property-at-point
+ (markdown-get-fenced-block-begin-properties)))
+ (markdown-get-fenced-block-from-middle
+ ,(cl-find-if
+ #'markdown-text-property-at-point
+ (markdown-get-fenced-block-middle-properties)))
+ (markdown-get-fenced-block-from-end
+ ,(cl-find-if
+ #'markdown-text-property-at-point
+ (markdown-get-fenced-block-end-properties)))))))))
+
+(defun markdown-propertize-end-match (reg end fence-spec middle-begin)
+ "Get match for REG up to END, if exists, and propertize appropriately.
+FENCE-SPEC is an entry in `markdown-fenced-block-pairs' and
+MIDDLE-BEGIN is the start of the \"middle\" section of the block."
+ (when (re-search-forward reg end t)
+ (let ((close-begin (match-beginning 0)) ; Start of closing line.
+ (close-end (match-end 0)) ; End of closing line.
+ (close-data (match-data t))) ; Match data for closing line.
+ ;; Propertize middle section of fenced block.
+ (put-text-property middle-begin close-begin
+ (cl-third fence-spec)
+ (list middle-begin close-begin))
+ ;; If the block is a YAML block, propertize the declarations inside
+ (when (< middle-begin close-begin) ;; workaround #634
+ (markdown-syntax-propertize-yaml-metadata middle-begin close-begin))
+ ;; Propertize closing line of fenced block.
+ (put-text-property close-begin close-end
+ (cl-cadadr fence-spec) close-data))))
+
+(defun markdown--triple-quote-single-line-p (begin)
+ (save-excursion
+ (goto-char begin)
+ (save-match-data
+ (and (search-forward "```" nil t)
+ (search-forward "```" (line-end-position) t)))))
+
+(defun markdown-syntax-propertize-fenced-block-constructs (start end)
+ "Propertize according to `markdown-fenced-block-pairs' from START to END.
+If unable to propertize an entire block (if the start of a block is within START
+and END, but the end of the block is not), propertize the start section of a
+block, then in a subsequent call propertize both middle and end by finding the
+start which was previously propertized."
+ (let ((start-reg (markdown-get-start-fence-regexp)))
+ (save-excursion
+ (goto-char start)
+ ;; start from previous unclosed block, if exists
+ (let ((prev-begin-block (markdown-find-previous-block)))
+ (when prev-begin-block
+ (let* ((correct-entry
+ (cl-find-if (lambda (entry)
+ (eq (cdr prev-begin-block) (cl-cadar entry)))
+ markdown-fenced-block-pairs))
+ (enclosed-text-start (1+ (car prev-begin-block)))
+ (start-length
+ (save-excursion
+ (goto-char (car prev-begin-block))
+ (string-match
+ (markdown-maybe-funcall-regexp
+ (caar correct-entry))
+ (buffer-substring
+ (point-at-bol) (point-at-eol)))
+ (- (match-end 1) (match-beginning 1))))
+ (end-reg (markdown-maybe-funcall-regexp
+ (cl-caadr correct-entry) start-length)))
+ (markdown-propertize-end-match
+ end-reg end correct-entry enclosed-text-start))))
+ ;; find all new blocks within region
+ (while (re-search-forward start-reg end t)
+ ;; we assume the opening constructs take up (only) an entire line,
+ ;; so we re-check the current line
+ (let* ((block-start (match-beginning 0))
+ (cur-line (buffer-substring (point-at-bol) (point-at-eol)))
+ ;; find entry in `markdown-fenced-block-pairs' corresponding
+ ;; to regex which was matched
+ (correct-entry
+ (cl-find-if
+ (lambda (fenced-pair)
+ (string-match-p
+ (markdown-maybe-funcall-regexp (caar fenced-pair))
+ cur-line))
+ markdown-fenced-block-pairs))
+ (enclosed-text-start
+ (save-excursion (1+ (point-at-eol))))
+ (end-reg
+ (markdown-maybe-funcall-regexp
+ (cl-caadr correct-entry)
+ (if (and (match-beginning 1) (match-end 1))
+ (- (match-end 1) (match-beginning 1))
+ 0)))
+ (prop (cl-cadar correct-entry)))
+ (when (or (not (eq prop 'markdown-gfm-block-begin))
+ (not (markdown--triple-quote-single-line-p block-start)))
+ ;; get correct match data
+ (save-excursion
+ (beginning-of-line)
+ (re-search-forward
+ (markdown-maybe-funcall-regexp (caar correct-entry))
+ (point-at-eol)))
+ ;; mark starting, even if ending is outside of region
+ (put-text-property (match-beginning 0) (match-end 0) prop (match-data t))
+ (markdown-propertize-end-match
+ end-reg end correct-entry enclosed-text-start)))))))
+
+(defun markdown-syntax-propertize-blockquotes (start end)
+ "Match blockquotes from START to END."
+ (save-excursion
+ (goto-char start)
+ (while (and (re-search-forward markdown-regex-blockquote end t)
+ (not (markdown-code-block-at-pos (match-beginning 0))))
+ (put-text-property (match-beginning 0) (match-end 0)
+ 'markdown-blockquote
+ (match-data t)))))
+
+(defun markdown-syntax-propertize-hrs (start end)
+ "Match horizontal rules from START to END."
+ (save-excursion
+ (goto-char start)
+ (while (re-search-forward markdown-regex-hr end t)
+ (let ((beg (match-beginning 0))
+ (end (match-end 0)))
+ (goto-char beg)
+ (unless (or (markdown-on-heading-p)
+ (markdown-code-block-at-point-p))
+ (put-text-property beg end 'markdown-hr (match-data t)))
+ (goto-char end)))))
+
+(defun markdown-syntax-propertize-yaml-metadata (start end)
+ "Propertize elements inside YAML metadata blocks from START to END.
+Assumes region from START and END is already known to be the interior
+region of a YAML metadata block as propertized by
+`markdown-syntax-propertize-fenced-block-constructs'."
+ (save-excursion
+ (goto-char start)
+ (cl-loop
+ while (re-search-forward markdown-regex-declarative-metadata end t)
+ do (progn
+ (put-text-property (match-beginning 1) (match-end 1)
+ 'markdown-metadata-key (match-data t))
+ (put-text-property (match-beginning 2) (match-end 2)
+ 'markdown-metadata-markup (match-data t))
+ (put-text-property (match-beginning 3) (match-end 3)
+ 'markdown-metadata-value (match-data t))))))
+
+(defun markdown-syntax-propertize-headings (start end)
+ "Match headings of type SYMBOL with REGEX from START to END."
+ (goto-char start)
+ (while (re-search-forward markdown-regex-header end t)
+ (unless (markdown-code-block-at-pos (match-beginning 0))
+ (put-text-property
+ (match-beginning 0) (match-end 0) 'markdown-heading
+ (match-data t))
+ (put-text-property
+ (match-beginning 0) (match-end 0)
+ (cond ((match-string-no-properties 2) 'markdown-heading-1-setext)
+ ((match-string-no-properties 3) 'markdown-heading-2-setext)
+ (t (let ((atx-level (length (markdown-trim-whitespace
+ (match-string-no-properties 4)))))
+ (intern (format "markdown-heading-%d-atx" atx-level)))))
+ (match-data t)))))
+
+(defun markdown-syntax-propertize-comments (start end)
+ "Match HTML comments from the START to END."
+ ;; Implement by loop instead of recursive call for avoiding
+ ;; exceed max-lisp-eval-depth issue
+ ;; https://github.com/jrblevin/markdown-mode/issues/536
+ (let (finish)
+ (goto-char start)
+ (while (not finish)
+ (let* ((in-comment (nth 4 (syntax-ppss)))
+ (comment-begin (nth 8 (syntax-ppss))))
+ (cond
+ ;; Comment start
+ ((and (not in-comment)
+ (re-search-forward markdown-regex-comment-start end t)
+ (not (markdown-inline-code-at-point-p))
+ (not (markdown-code-block-at-point-p)))
+ (let ((open-beg (match-beginning 0)))
+ (put-text-property open-beg (1+ open-beg)
+ 'syntax-table (string-to-syntax "<"))
+ (goto-char (min (1+ (match-end 0)) end (point-max)))))
+ ;; Comment end
+ ((and in-comment comment-begin
+ (re-search-forward markdown-regex-comment-end end t))
+ (let ((comment-end (match-end 0)))
+ (put-text-property (1- comment-end) comment-end
+ 'syntax-table (string-to-syntax ">"))
+ ;; Remove any other text properties inside the comment
+ (remove-text-properties comment-begin comment-end
+ markdown--syntax-properties)
+ (put-text-property comment-begin comment-end
+ 'markdown-comment (list comment-begin comment-end))
+ (goto-char (min comment-end end (point-max)))))
+ ;; Nothing found
+ (t (setq finish t)))))
+ nil))
+
+(defun markdown-syntax-propertize (start end)
+ "Function used as `syntax-propertize-function'.
+START and END delimit region to propertize."
+ (with-silent-modifications
+ (save-excursion
+ (remove-text-properties start end markdown--syntax-properties)
+ (markdown-syntax-propertize-fenced-block-constructs start end)
+ (markdown-syntax-propertize-list-items start end)
+ (markdown-syntax-propertize-pre-blocks start end)
+ (markdown-syntax-propertize-blockquotes start end)
+ (markdown-syntax-propertize-headings start end)
+ (markdown-syntax-propertize-hrs start end)
+ (markdown-syntax-propertize-comments start end))))
+
+
+;;; Markup Hiding =============================================================
+
+(defconst markdown-markup-properties
+ '(face markdown-markup-face invisible markdown-markup)
+ "List of properties and values to apply to markup.")
+
+(defconst markdown-language-keyword-properties
+ '(face markdown-language-keyword-face invisible markdown-markup)
+ "List of properties and values to apply to code block language names.")
+
+(defconst markdown-language-info-properties
+ '(face markdown-language-info-face invisible markdown-markup)
+ "List of properties and values to apply to code block language info strings.")
+
+(defconst markdown-include-title-properties
+ '(face markdown-link-title-face invisible markdown-markup)
+ "List of properties and values to apply to included code titles.")
+
+(defcustom markdown-hide-markup nil
+ "Determines whether markup in the buffer will be hidden.
+When set to nil, all markup is displayed in the buffer as it
+appears in the file. An exception is when `markdown-hide-urls'
+is non-nil.
+Set this to a non-nil value to turn this feature on by default.
+You can interactively toggle the value of this variable with
+`markdown-toggle-markup-hiding', \\[markdown-toggle-markup-hiding],
+or from the Markdown > Show & Hide menu.
+
+Markup hiding works by adding text properties to positions in the
+buffer---either the `invisible' property or the `display' property
+in cases where alternative glyphs are used (e.g., list bullets).
+This does not, however, affect printing or other output.
+Functions such as `htmlfontify-buffer' and `ps-print-buffer' will
+not honor these text properties. For printing, it would be better
+to first convert to HTML or PDF (e.g,. using Pandoc)."
+ :group 'markdown
+ :type 'boolean
+ :safe 'booleanp
+ :package-version '(markdown-mode . "2.3"))
+(make-variable-buffer-local 'markdown-hide-markup)
+
+(defun markdown-toggle-markup-hiding (&optional arg)
+ "Toggle the display or hiding of markup.
+With a prefix argument ARG, enable markup hiding if ARG is positive,
+and disable it otherwise.
+See `markdown-hide-markup' for additional details."
+ (interactive (list (or current-prefix-arg 'toggle)))
+ (setq markdown-hide-markup
+ (if (eq arg 'toggle)
+ (not markdown-hide-markup)
+ (> (prefix-numeric-value arg) 0)))
+ (if markdown-hide-markup
+ (progn (add-to-invisibility-spec 'markdown-markup)
+ (message "markdown-mode markup hiding enabled"))
+ (progn (remove-from-invisibility-spec 'markdown-markup)
+ (message "markdown-mode markup hiding disabled")))
+ (markdown-reload-extensions))
+
+
+;;; Font Lock =================================================================
+
+(require 'font-lock)
+
+(defgroup markdown-faces nil
+ "Faces used in Markdown Mode."
+ :group 'markdown
+ :group 'faces)
+
+(defface markdown-italic-face
+ '((t (:inherit italic)))
+ "Face for italic text."
+ :group 'markdown-faces)
+
+(defface markdown-bold-face
+ '((t (:inherit bold)))
+ "Face for bold text."
+ :group 'markdown-faces)
+
+(defface markdown-strike-through-face
+ '((t (:strike-through t)))
+ "Face for strike-through text."
+ :group 'markdown-faces)
+
+(defface markdown-markup-face
+ '((t (:inherit shadow :slant normal :weight normal)))
+ "Face for markup elements."
+ :group 'markdown-faces)
+
+(defface markdown-header-rule-face
+ '((t (:inherit markdown-markup-face)))
+ "Base face for headers rules."
+ :group 'markdown-faces)
+
+(defface markdown-header-delimiter-face
+ '((t (:inherit markdown-markup-face)))
+ "Base face for headers hash delimiter."
+ :group 'markdown-faces)
+
+(defface markdown-list-face
+ '((t (:inherit markdown-markup-face)))
+ "Face for list item markers."
+ :group 'markdown-faces)
+
+(defface markdown-blockquote-face
+ '((t (:inherit font-lock-doc-face)))
+ "Face for blockquote sections."
+ :group 'markdown-faces)
+
+(defface markdown-code-face
+ '((t (:inherit fixed-pitch)))
+ "Face for inline code, pre blocks, and fenced code blocks.
+This may be used, for example, to add a contrasting background to
+inline code fragments and code blocks."
+ :group 'markdown-faces)
+
+(defface markdown-inline-code-face
+ '((t (:inherit (markdown-code-face font-lock-constant-face))))
+ "Face for inline code."
+ :group 'markdown-faces)
+
+(defface markdown-pre-face
+ '((t (:inherit (markdown-code-face font-lock-constant-face))))
+ "Face for preformatted text."
+ :group 'markdown-faces)
+
+(defface markdown-table-face
+ '((t (:inherit (markdown-code-face))))
+ "Face for tables."
+ :group 'markdown-faces)
+
+(defface markdown-language-keyword-face
+ '((t (:inherit font-lock-type-face)))
+ "Face for programming language identifiers."
+ :group 'markdown-faces)
+
+(defface markdown-language-info-face
+ '((t (:inherit font-lock-string-face)))
+ "Face for programming language info strings."
+ :group 'markdown-faces)
+
+(defface markdown-link-face
+ '((t (:inherit link)))
+ "Face for links."
+ :group 'markdown-faces)
+
+(defface markdown-missing-link-face
+ '((t (:inherit font-lock-warning-face)))
+ "Face for missing links."
+ :group 'markdown-faces)
+
+(defface markdown-reference-face
+ '((t (:inherit markdown-markup-face)))
+ "Face for link references."
+ :group 'markdown-faces)
+
+(defface markdown-footnote-marker-face
+ '((t (:inherit markdown-markup-face)))
+ "Face for footnote markers."
+ :group 'markdown-faces)
+
+(defface markdown-footnote-text-face
+ '((t (:inherit font-lock-comment-face)))
+ "Face for footnote text."
+ :group 'markdown-faces)
+
+(defface markdown-url-face
+ '((t (:inherit font-lock-string-face)))
+ "Face for URLs that are part of markup.
+For example, this applies to URLs in inline links:
+[link text](http://example.com/)."
+ :group 'markdown-faces)
+
+(defface markdown-plain-url-face
+ '((t (:inherit markdown-link-face)))
+ "Face for URLs that are also links.
+For example, this applies to plain angle bracket URLs:
+<http://example.com/>."
+ :group 'markdown-faces)
+
+(defface markdown-link-title-face
+ '((t (:inherit font-lock-comment-face)))
+ "Face for reference link titles."
+ :group 'markdown-faces)
+
+(defface markdown-line-break-face
+ '((t (:inherit font-lock-constant-face :underline t)))
+ "Face for hard line breaks."
+ :group 'markdown-faces)
+
+(defface markdown-comment-face
+ '((t (:inherit font-lock-comment-face)))
+ "Face for HTML comments."
+ :group 'markdown-faces)
+
+(defface markdown-math-face
+ '((t (:inherit font-lock-string-face)))
+ "Face for LaTeX expressions."
+ :group 'markdown-faces)
+
+(defface markdown-metadata-key-face
+ '((t (:inherit font-lock-variable-name-face)))
+ "Face for metadata keys."
+ :group 'markdown-faces)
+
+(defface markdown-metadata-value-face
+ '((t (:inherit font-lock-string-face)))
+ "Face for metadata values."
+ :group 'markdown-faces)
+
+(defface markdown-gfm-checkbox-face
+ '((t (:inherit font-lock-builtin-face)))
+ "Face for GFM checkboxes."
+ :group 'markdown-faces)
+
+(defface markdown-highlight-face
+ '((t (:inherit highlight)))
+ "Face for mouse highlighting."
+ :group 'markdown-faces)
+
+(defface markdown-hr-face
+ '((t (:inherit markdown-markup-face)))
+ "Face for horizontal rules."
+ :group 'markdown-faces)
+
+(defface markdown-html-tag-name-face
+ '((t (:inherit font-lock-type-face)))
+ "Face for HTML tag names."
+ :group 'markdown-faces)
+
+(defface markdown-html-tag-delimiter-face
+ '((t (:inherit markdown-markup-face)))
+ "Face for HTML tag delimiters."
+ :group 'markdown-faces)
+
+(defface markdown-html-attr-name-face
+ '((t (:inherit font-lock-variable-name-face)))
+ "Face for HTML attribute names."
+ :group 'markdown-faces)
+
+(defface markdown-html-attr-value-face
+ '((t (:inherit font-lock-string-face)))
+ "Face for HTML attribute values."
+ :group 'markdown-faces)
+
+(defface markdown-html-entity-face
+ '((t (:inherit font-lock-variable-name-face)))
+ "Face for HTML entities."
+ :group 'markdown-faces)
+
+(defface markdown-highlighting-face
+ '((t (:background "yellow" :foreground "black")))
+ "Face for highlighting."
+ :group 'markdown-faces)
+
+(defcustom markdown-header-scaling nil
+ "Whether to use variable-height faces for headers.
+When non-nil, `markdown-header-face' will inherit from
+`variable-pitch' and the scaling values in
+`markdown-header-scaling-values' will be applied to
+headers of levels one through six respectively."
+ :type 'boolean
+ :initialize #'custom-initialize-default
+ :set (lambda (symbol value)
+ (set-default symbol value)
+ (markdown-update-header-faces value))
+ :group 'markdown-faces
+ :package-version '(markdown-mode . "2.2"))
+
+(defcustom markdown-header-scaling-values
+ '(2.0 1.7 1.4 1.1 1.0 1.0)
+ "List of scaling values for headers of level one through six.
+Used when `markdown-header-scaling' is non-nil."
+ :type 'list
+ :initialize #'custom-initialize-default
+ :set (lambda (symbol value)
+ (set-default symbol value)
+ (markdown-update-header-faces markdown-header-scaling value)))
+
+(defmacro markdown--dotimes-when-compile (i-n body)
+ (declare (indent 1) (debug ((symbolp form) form)))
+ (let ((var (car i-n))
+ (n (cadr i-n))
+ (code ()))
+ (dotimes (i (eval n t))
+ (push (eval body `((,var . ,i))) code))
+ `(progn ,@(nreverse code))))
+
+(defface markdown-header-face
+ `((t (:inherit (,@(when markdown-header-scaling '(variable-pitch))
+ font-lock-function-name-face)
+ :weight bold)))
+ "Base face for headers.")
+
+(markdown--dotimes-when-compile (num 6)
+ (let* ((num1 (1+ num))
+ (face-name (intern (format "markdown-header-face-%s" num1))))
+ `(defface ,face-name
+ (,'\` ((t (:inherit markdown-header-face
+ :height
+ (,'\, (if markdown-header-scaling
+ (float (nth ,num markdown-header-scaling-values))
+ 1.0))))))
+ (format "Face for level %s headers.
+You probably don't want to customize this face directly. Instead
+you can customize the base face `markdown-header-face' or the
+variable-height variable `markdown-header-scaling'." ,num1))))
+
+(defun markdown-update-header-faces (&optional scaling scaling-values)
+ "Update header faces, depending on if header SCALING is desired.
+If so, use given list of SCALING-VALUES relative to the baseline
+size of `markdown-header-face'."
+ (dotimes (num 6)
+ (let* ((face-name (intern (format "markdown-header-face-%s" (1+ num))))
+ (scale (cond ((not scaling) 1.0)
+ (scaling-values (float (nth num scaling-values)))
+ (t (float (nth num markdown-header-scaling-values))))))
+ (unless (get face-name 'saved-face) ; Don't update customized faces
+ (set-face-attribute face-name nil :height scale)))))
+
+(defun markdown-syntactic-face (state)
+ "Return font-lock face for characters with given STATE.
+See `font-lock-syntactic-face-function' for details."
+ (let ((in-comment (nth 4 state)))
+ (cond
+ (in-comment 'markdown-comment-face)
+ (t nil))))
+
+(defcustom markdown-list-item-bullets
+ '("●" "◎" "○" "◆" "◇" "►" "•")
+ "List of bullets to use for unordered lists.
+It can contain any number of symbols, which will be repeated.
+Depending on your font, some reasonable choices are:
+♥ ● ◇ ✚ ✜ ☯ ◆ ♠ ♣ ♦ ❀ ◆ ◖ ▶ ► • ★ ▸."
+ :group 'markdown
+ :type '(repeat (string :tag "Bullet character"))
+ :package-version '(markdown-mode . "2.3"))
+
+(defun markdown--footnote-marker-properties ()
+ "Return a font-lock facespec expression for footnote marker text."
+ `(face markdown-footnote-marker-face
+ ,@(when markdown-hide-markup
+ `(display ,markdown-footnote-display))))
+
+(defun markdown--pandoc-inline-footnote-properties ()
+ "Return a font-lock facespec expression for Pandoc inline footnote text."
+ `(face markdown-footnote-text-face
+ ,@(when markdown-hide-markup
+ `(display ,markdown-footnote-display))))
+
+(defvar markdown-mode-font-lock-keywords
+ `((markdown-match-yaml-metadata-begin . ((1 'markdown-markup-face)))
+ (markdown-match-yaml-metadata-end . ((1 'markdown-markup-face)))
+ (markdown-match-yaml-metadata-key . ((1 'markdown-metadata-key-face)
+ (2 'markdown-markup-face)
+ (3 'markdown-metadata-value-face)))
+ (markdown-match-gfm-open-code-blocks . ((1 markdown-markup-properties)
+ (2 markdown-markup-properties nil t)
+ (3 markdown-language-keyword-properties nil t)
+ (4 markdown-language-info-properties nil t)
+ (5 markdown-markup-properties nil t)))
+ (markdown-match-gfm-close-code-blocks . ((0 markdown-markup-properties)))
+ (markdown-fontify-gfm-code-blocks)
+ (markdown-fontify-tables)
+ (markdown-match-fenced-start-code-block . ((1 markdown-markup-properties)
+ (2 markdown-markup-properties nil t)
+ (3 markdown-language-keyword-properties nil t)
+ (4 markdown-language-info-properties nil t)
+ (5 markdown-markup-properties nil t)))
+ (markdown-match-fenced-end-code-block . ((0 markdown-markup-properties)))
+ (markdown-fontify-fenced-code-blocks)
+ (markdown-match-pre-blocks . ((0 'markdown-pre-face)))
+ (markdown-fontify-headings)
+ (markdown-match-declarative-metadata . ((1 'markdown-metadata-key-face)
+ (2 'markdown-markup-face)
+ (3 'markdown-metadata-value-face)))
+ (markdown-match-pandoc-metadata . ((1 'markdown-markup-face)
+ (2 'markdown-markup-face)
+ (3 'markdown-metadata-value-face)))
+ (markdown-fontify-hrs)
+ (markdown-match-code . ((1 markdown-markup-properties prepend)
+ (2 'markdown-inline-code-face prepend)
+ (3 markdown-markup-properties prepend)))
+ (,markdown-regex-kbd . ((1 markdown-markup-properties)
+ (2 'markdown-inline-code-face)
+ (3 markdown-markup-properties)))
+ (markdown-fontify-angle-uris)
+ (,markdown-regex-email . 'markdown-plain-url-face)
+ (markdown-match-html-tag . ((1 'markdown-html-tag-delimiter-face t)
+ (2 'markdown-html-tag-name-face t)
+ (3 'markdown-html-tag-delimiter-face t)
+ ;; Anchored matcher for HTML tag attributes
+ (,markdown-regex-html-attr
+ ;; Before searching, move past tag
+ ;; name; set limit at tag close.
+ (progn
+ (goto-char (match-end 2)) (match-end 3))
+ nil
+ . ((1 'markdown-html-attr-name-face)
+ (3 'markdown-html-tag-delimiter-face nil t)
+ (4 'markdown-html-attr-value-face nil t)))))
+ (,markdown-regex-html-entity . 'markdown-html-entity-face)
+ (markdown-fontify-list-items)
+ (,markdown-regex-footnote . ((1 markdown-markup-properties) ; [^
+ (2 (markdown--footnote-marker-properties)) ; label
+ (3 markdown-markup-properties))) ; ]
+ (,markdown-regex-pandoc-inline-footnote . ((1 markdown-markup-properties) ; ^
+ (2 markdown-markup-properties) ; [
+ (3 (markdown--pandoc-inline-footnote-properties)) ; text
+ (4 markdown-markup-properties))) ; ]
+ (markdown-match-includes . ((1 markdown-markup-properties)
+ (2 markdown-markup-properties nil t)
+ (3 markdown-include-title-properties nil t)
+ (4 markdown-markup-properties nil t)
+ (5 markdown-markup-properties)
+ (6 'markdown-url-face)
+ (7 markdown-markup-properties)))
+ (markdown-fontify-inline-links)
+ (markdown-fontify-reference-links)
+ (,markdown-regex-reference-definition . ((1 'markdown-markup-face) ; [
+ (2 'markdown-reference-face) ; label
+ (3 'markdown-markup-face) ; ]
+ (4 'markdown-markup-face) ; :
+ (5 'markdown-url-face) ; url
+ (6 'markdown-link-title-face))) ; "title" (optional)
+ (markdown-fontify-plain-uris)
+ ;; Math mode $..$
+ (markdown-match-math-single . ((1 'markdown-markup-face prepend)
+ (2 'markdown-math-face append)
+ (3 'markdown-markup-face prepend)))
+ ;; Math mode $$..$$
+ (markdown-match-math-double . ((1 'markdown-markup-face prepend)
+ (2 'markdown-math-face append)
+ (3 'markdown-markup-face prepend)))
+ ;; Math mode \[..\] and \\[..\\]
+ (markdown-match-math-display . ((1 'markdown-markup-face prepend)
+ (3 'markdown-math-face append)
+ (4 'markdown-markup-face prepend)))
+ (markdown-match-bold . ((1 markdown-markup-properties prepend)
+ (2 'markdown-bold-face append)
+ (3 markdown-markup-properties prepend)))
+ (markdown-match-italic . ((1 markdown-markup-properties prepend)
+ (2 'markdown-italic-face append)
+ (3 markdown-markup-properties prepend)))
+ (,markdown-regex-strike-through . ((3 markdown-markup-properties)
+ (4 'markdown-strike-through-face)
+ (5 markdown-markup-properties)))
+ (markdown--match-highlighting . ((3 markdown-markup-properties)
+ (4 'markdown-highlighting-face)
+ (5 markdown-markup-properties)))
+ (,markdown-regex-line-break . (1 'markdown-line-break-face prepend))
+ (markdown-fontify-sub-superscripts)
+ (markdown-match-inline-attributes . ((0 markdown-markup-properties prepend)))
+ (markdown-match-leanpub-sections . ((0 markdown-markup-properties)))
+ (markdown-fontify-blockquotes)
+ (markdown-match-wiki-link . ((0 'markdown-link-face prepend))))
+ "Syntax highlighting for Markdown files.")
+
+;; Footnotes
+(defvar-local markdown-footnote-counter 0
+ "Counter for footnote numbers.")
+
+(defconst markdown-footnote-chars
+ "[[:alnum:]-]"
+ "Regular expression matching any character for a footnote identifier.")
+
+(defconst markdown-regex-footnote-definition
+ (concat "^ \\{0,3\\}\\[\\(\\^" markdown-footnote-chars "*?\\)\\]:\\(?:[ \t]+\\|$\\)")
+ "Regular expression matching a footnote definition, capturing the label.")
+
+
+;;; Compatibility =============================================================
+
+(defun markdown-flyspell-check-word-p ()
+ "Return t if `flyspell' should check word just before point.
+Used for `flyspell-generic-check-word-predicate'."
+ (save-excursion
+ (goto-char (1- (point)))
+ ;; https://github.com/jrblevin/markdown-mode/issues/560
+ ;; enable spell check YAML meta data
+ (if (or (and (markdown-code-block-at-point-p)
+ (not (markdown-text-property-at-point 'markdown-yaml-metadata-section)))
+ (markdown-inline-code-at-point-p)
+ (markdown-in-comment-p)
+ (markdown--face-p (point) '(markdown-reference-face
+ markdown-markup-face
+ markdown-plain-url-face
+ markdown-inline-code-face
+ markdown-url-face)))
+ (prog1 nil
+ ;; If flyspell overlay is put, then remove it
+ (let ((bounds (bounds-of-thing-at-point 'word)))
+ (when bounds
+ (cl-loop for ov in (overlays-in (car bounds) (cdr bounds))
+ when (overlay-get ov 'flyspell-overlay)
+ do
+ (delete-overlay ov)))))
+ t)))
+
+
+;;; Markdown Parsing Functions ================================================
+
+(defun markdown-cur-line-blank-p ()
+ "Return t if the current line is blank and nil otherwise."
+ (save-excursion
+ (beginning-of-line)
+ (looking-at-p markdown-regex-blank-line)))
+
+(defun markdown-prev-line-blank ()
+ "Return t if the previous line is blank and nil otherwise.
+If we are at the first line, then consider the previous line to be blank."
+ (or (= (line-beginning-position) (point-min))
+ (save-excursion
+ (forward-line -1)
+ (looking-at markdown-regex-blank-line))))
+
+(defun markdown-prev-line-blank-p ()
+ "Like `markdown-prev-line-blank', but preserve `match-data'."
+ (save-match-data (markdown-prev-line-blank)))
+
+(defun markdown-next-line-blank-p ()
+ "Return t if the next line is blank and nil otherwise.
+If we are at the last line, then consider the next line to be blank."
+ (or (= (line-end-position) (point-max))
+ (save-excursion
+ (forward-line 1)
+ (markdown-cur-line-blank-p))))
+
+(defun markdown-prev-line-indent ()
+ "Return the number of leading whitespace characters in the previous line.
+Return 0 if the current line is the first line in the buffer."
+ (save-excursion
+ (if (= (line-beginning-position) (point-min))
+ 0
+ (forward-line -1)
+ (current-indentation))))
+
+(defun markdown-next-line-indent ()
+ "Return the number of leading whitespace characters in the next line.
+Return 0 if line is the last line in the buffer."
+ (save-excursion
+ (if (= (line-end-position) (point-max))
+ 0
+ (forward-line 1)
+ (current-indentation))))
+
+(defun markdown-new-baseline ()
+ "Determine if the current line begins a new baseline level.
+Assume point is positioned at beginning of line."
+ (or (looking-at markdown-regex-header)
+ (looking-at markdown-regex-hr)
+ (and (= (current-indentation) 0)
+ (not (looking-at markdown-regex-list))
+ (markdown-prev-line-blank))))
+
+(defun markdown-search-backward-baseline ()
+ "Search backward baseline point with no indentation and not a list item."
+ (end-of-line)
+ (let (stop)
+ (while (not (or stop (bobp)))
+ (re-search-backward markdown-regex-block-separator-noindent nil t)
+ (when (match-end 2)
+ (goto-char (match-end 2))
+ (cond
+ ((markdown-new-baseline)
+ (setq stop t))
+ ((looking-at-p markdown-regex-list)
+ (setq stop nil))
+ (t (setq stop t)))))))
+
+(defun markdown-update-list-levels (marker indent levels)
+ "Update list levels given list MARKER, block INDENT, and current LEVELS.
+Here, MARKER is a string representing the type of list, INDENT is an integer
+giving the indentation, in spaces, of the current block, and LEVELS is a
+list of the indentation levels of parent list items. When LEVELS is nil,
+it means we are at baseline (not inside of a nested list)."
+ (cond
+ ;; New list item at baseline.
+ ((and marker (null levels))
+ (setq levels (list indent)))
+ ;; List item with greater indentation (four or more spaces).
+ ;; Increase list level.
+ ((and marker (>= indent (+ (car levels) markdown-list-indent-width)))
+ (setq levels (cons indent levels)))
+ ;; List item with greater or equal indentation (less than four spaces).
+ ;; Do not increase list level.
+ ((and marker (>= indent (car levels)))
+ levels)
+ ;; Lesser indentation level.
+ ;; Pop appropriate number of elements off LEVELS list (e.g., lesser
+ ;; indentation could move back more than one list level). Note
+ ;; that this block need not be the beginning of list item.
+ ((< indent (car levels))
+ (while (and (> (length levels) 1)
+ (< indent (+ (cadr levels) markdown-list-indent-width)))
+ (setq levels (cdr levels)))
+ levels)
+ ;; Otherwise, do nothing.
+ (t levels)))
+
+(defun markdown-calculate-list-levels ()
+ "Calculate list levels at point.
+Return a list of the form (n1 n2 n3 ...) where n1 is the
+indentation of the deepest nested list item in the branch of
+the list at the point, n2 is the indentation of the parent
+list item, and so on. The depth of the list item is therefore
+the length of the returned list. If the point is not at or
+immediately after a list item, return nil."
+ (save-excursion
+ (let ((first (point)) levels indent pre-regexp)
+ ;; Find a baseline point with zero list indentation
+ (markdown-search-backward-baseline)
+ ;; Search for all list items between baseline and LOC
+ (while (and (< (point) first)
+ (re-search-forward markdown-regex-list first t))
+ (setq pre-regexp (format "^\\( \\|\t\\)\\{%d\\}" (1+ (length levels))))
+ (beginning-of-line)
+ (cond
+ ;; Make sure this is not a header or hr
+ ((markdown-new-baseline) (setq levels nil))
+ ;; Make sure this is not a line from a pre block
+ ((looking-at-p pre-regexp))
+ ;; If not, then update levels
+ (t
+ (setq indent (current-indentation))
+ (setq levels (markdown-update-list-levels (match-string 2)
+ indent levels))))
+ (end-of-line))
+ levels)))
+
+(defun markdown-prev-list-item (level)
+ "Search backward from point for a list item with indentation LEVEL.
+Set point to the beginning of the item, and return point, or nil
+upon failure."
+ (let (bounds indent prev)
+ (setq prev (point))
+ (forward-line -1)
+ (setq indent (current-indentation))
+ (while
+ (cond
+ ;; List item
+ ((and (looking-at-p markdown-regex-list)
+ (setq bounds (markdown-cur-list-item-bounds)))
+ (cond
+ ;; Stop and return point at item of equal indentation
+ ((= (nth 3 bounds) level)
+ (setq prev (point))
+ nil)
+ ;; Stop and return nil at item with lesser indentation
+ ((< (nth 3 bounds) level)
+ (setq prev nil)
+ nil)
+ ;; Stop at beginning of buffer
+ ((bobp) (setq prev nil))
+ ;; Continue at item with greater indentation
+ ((> (nth 3 bounds) level) t)))
+ ;; Stop at beginning of buffer
+ ((bobp) (setq prev nil))
+ ;; Continue if current line is blank
+ ((markdown-cur-line-blank-p) t)
+ ;; Continue while indentation is the same or greater
+ ((>= indent level) t)
+ ;; Stop if current indentation is less than list item
+ ;; and the next is blank
+ ((and (< indent level)
+ (markdown-next-line-blank-p))
+ (setq prev nil))
+ ;; Stop at a header
+ ((looking-at-p markdown-regex-header) (setq prev nil))
+ ;; Stop at a horizontal rule
+ ((looking-at-p markdown-regex-hr) (setq prev nil))
+ ;; Otherwise, continue.
+ (t t))
+ (forward-line -1)
+ (setq indent (current-indentation)))
+ prev))
+
+(defun markdown-next-list-item (level)
+ "Search forward from point for the next list item with indentation LEVEL.
+Set point to the beginning of the item, and return point, or nil
+upon failure."
+ (let (bounds indent next)
+ (setq next (point))
+ (if (looking-at markdown-regex-header-setext)
+ (goto-char (match-end 0)))
+ (forward-line)
+ (setq indent (current-indentation))
+ (while
+ (cond
+ ;; Stop at end of the buffer.
+ ((eobp) nil)
+ ;; Continue if the current line is blank
+ ((markdown-cur-line-blank-p) t)
+ ;; List item
+ ((and (looking-at-p markdown-regex-list)
+ (setq bounds (markdown-cur-list-item-bounds)))
+ (cond
+ ;; Continue at item with greater indentation
+ ((> (nth 3 bounds) level) t)
+ ;; Stop and return point at item of equal indentation
+ ((= (nth 3 bounds) level)
+ (setq next (point))
+ nil)
+ ;; Stop and return nil at item with lesser indentation
+ ((< (nth 3 bounds) level)
+ (setq next nil)
+ nil)))
+ ;; Continue while indentation is the same or greater
+ ((>= indent level) t)
+ ;; Stop if current indentation is less than list item
+ ;; and the previous line was blank.
+ ((and (< indent level)
+ (markdown-prev-line-blank-p))
+ (setq next nil))
+ ;; Stop at a header
+ ((looking-at-p markdown-regex-header) (setq next nil))
+ ;; Stop at a horizontal rule
+ ((looking-at-p markdown-regex-hr) (setq next nil))
+ ;; Otherwise, continue.
+ (t t))
+ (forward-line)
+ (setq indent (current-indentation)))
+ next))
+
+(defun markdown-cur-list-item-end (level)
+ "Move to end of list item with pre-marker indentation LEVEL.
+Return the point at the end when a list item was found at the
+original point. If the point is not in a list item, do nothing."
+ (let (indent)
+ (forward-line)
+ (setq indent (current-indentation))
+ (while
+ (cond
+ ;; Stop at end of the buffer.
+ ((eobp) nil)
+ ;; Continue while indentation is the same or greater
+ ((>= indent level) t)
+ ;; Continue if the current line is blank
+ ((looking-at markdown-regex-blank-line) t)
+ ;; Stop if current indentation is less than list item
+ ;; and the previous line was blank.
+ ((and (< indent level)
+ (markdown-prev-line-blank))
+ nil)
+ ;; Stop at a new list items of the same or lesser
+ ;; indentation, headings, and horizontal rules.
+ ((looking-at (concat "\\(?:" markdown-regex-list
+ "\\|" markdown-regex-header
+ "\\|" markdown-regex-hr "\\)"))
+ nil)
+ ;; Otherwise, continue.
+ (t t))
+ (forward-line)
+ (setq indent (current-indentation)))
+ ;; Don't skip over whitespace for empty list items (marker and
+ ;; whitespace only), just move to end of whitespace.
+ (if (save-excursion
+ (beginning-of-line)
+ (looking-at (concat markdown-regex-list "[ \t]*$")))
+ (goto-char (match-end 3))
+ (skip-chars-backward " \t\n"))
+ (end-of-line)
+ (point)))
+
+(defun markdown-cur-list-item-bounds ()
+ "Return bounds for list item at point.
+Return a list of the following form:
+
+ (begin end indent nonlist-indent marker checkbox match)
+
+The named components are:
+
+ - begin: Position of beginning of list item, including leading indentation.
+ - end: Position of the end of the list item, including list item text.
+ - indent: Number of characters of indentation before list marker (an integer).
+ - nonlist-indent: Number characters of indentation, list
+ marker, and whitespace following list marker (an integer).
+ - marker: String containing the list marker and following whitespace
+ (e.g., \"- \" or \"* \").
+ - checkbox: String containing the GFM checkbox portion, if any,
+ including any trailing whitespace before the text
+ begins (e.g., \"[x] \").
+ - match: match data for markdown-regex-list
+
+As an example, for the following unordered list item
+
+ - item
+
+the returned list would be
+
+ (1 14 3 5 \"- \" nil (1 6 1 4 4 5 5 6))
+
+If the point is not inside a list item, return nil."
+ (car (get-text-property (point-at-bol) 'markdown-list-item)))
+
+(defun markdown-list-item-at-point-p ()
+ "Return t if there is a list item at the point and nil otherwise."
+ (save-match-data (markdown-cur-list-item-bounds)))
+
+(defun markdown-prev-list-item-bounds ()
+ "Return bounds of previous item in the same list of any level.
+The return value has the same form as that of
+`markdown-cur-list-item-bounds'."
+ (save-excursion
+ (let ((cur-bounds (markdown-cur-list-item-bounds))
+ (beginning-of-list (save-excursion (markdown-beginning-of-list)))
+ stop)
+ (when cur-bounds
+ (goto-char (nth 0 cur-bounds))
+ (while (and (not stop) (not (bobp))
+ (re-search-backward markdown-regex-list
+ beginning-of-list t))
+ (unless (or (looking-at markdown-regex-hr)
+ (markdown-code-block-at-point-p))
+ (setq stop (point))))
+ (markdown-cur-list-item-bounds)))))
+
+(defun markdown-next-list-item-bounds ()
+ "Return bounds of next item in the same list of any level.
+The return value has the same form as that of
+`markdown-cur-list-item-bounds'."
+ (save-excursion
+ (let ((cur-bounds (markdown-cur-list-item-bounds))
+ (end-of-list (save-excursion (markdown-end-of-list)))
+ stop)
+ (when cur-bounds
+ (goto-char (nth 0 cur-bounds))
+ (end-of-line)
+ (while (and (not stop) (not (eobp))
+ (re-search-forward markdown-regex-list
+ end-of-list t))
+ (unless (or (looking-at markdown-regex-hr)
+ (markdown-code-block-at-point-p))
+ (setq stop (point))))
+ (when stop
+ (markdown-cur-list-item-bounds))))))
+
+(defun markdown-beginning-of-list ()
+ "Move point to beginning of list at point, if any."
+ (interactive)
+ (let ((orig-point (point))
+ (list-begin (save-excursion
+ (markdown-search-backward-baseline)
+ ;; Stop at next list item, regardless of the indentation.
+ (markdown-next-list-item (point-max))
+ (when (looking-at markdown-regex-list)
+ (point)))))
+ (when (and list-begin (<= list-begin orig-point))
+ (goto-char list-begin))))
+
+(defun markdown-end-of-list ()
+ "Move point to end of list at point, if any."
+ (interactive)
+ (let ((start (point))
+ (end (save-excursion
+ (when (markdown-beginning-of-list)
+ ;; Items can't have nonlist-indent <= 1, so this
+ ;; moves past all list items.
+ (markdown-next-list-item 1)
+ (skip-syntax-backward "-")
+ (unless (eobp) (forward-char 1))
+ (point)))))
+ (when (and end (>= end start))
+ (goto-char end))))
+
+(defun markdown-up-list ()
+ "Move point to beginning of parent list item."
+ (interactive)
+ (let ((cur-bounds (markdown-cur-list-item-bounds)))
+ (when cur-bounds
+ (markdown-prev-list-item (1- (nth 3 cur-bounds)))
+ (let ((up-bounds (markdown-cur-list-item-bounds)))
+ (when (and up-bounds (< (nth 3 up-bounds) (nth 3 cur-bounds)))
+ (point))))))
+
+(defun markdown-bounds-of-thing-at-point (thing)
+ "Call `bounds-of-thing-at-point' for THING with slight modifications.
+Does not include trailing newlines when THING is 'line. Handles the
+end of buffer case by setting both endpoints equal to the value of
+`point-max', since an empty region will trigger empty markup insertion.
+Return bounds of form (beg . end) if THING is found, or nil otherwise."
+ (let* ((bounds (bounds-of-thing-at-point thing))
+ (a (car bounds))
+ (b (cdr bounds)))
+ (when bounds
+ (when (eq thing 'line)
+ (cond ((and (eobp) (markdown-cur-line-blank-p))
+ (setq a b))
+ ((char-equal (char-before b) ?\^J)
+ (setq b (1- b)))))
+ (cons a b))))
+
+(defun markdown-reference-definition (reference)
+ "Find out whether Markdown REFERENCE is defined.
+REFERENCE should not include the square brackets.
+When REFERENCE is defined, return a list of the form (text start end)
+containing the definition text itself followed by the start and end
+locations of the text. Otherwise, return nil.
+Leave match data for `markdown-regex-reference-definition'
+intact additional processing."
+ (let ((reference (downcase reference)))
+ (save-excursion
+ (goto-char (point-min))
+ (catch 'found
+ (while (re-search-forward markdown-regex-reference-definition nil t)
+ (when (string= reference (downcase (match-string-no-properties 2)))
+ (throw 'found
+ (list (match-string-no-properties 5)
+ (match-beginning 5) (match-end 5)))))))))
+
+(defun markdown-get-defined-references ()
+ "Return all defined reference labels and their line numbers.
+They does not include square brackets)."
+ (save-excursion
+ (goto-char (point-min))
+ (let (refs)
+ (while (re-search-forward markdown-regex-reference-definition nil t)
+ (let ((target (match-string-no-properties 2)))
+ (cl-pushnew
+ (cons (downcase target)
+ (markdown-line-number-at-pos (match-beginning 2)))
+ refs :test #'equal :key #'car)))
+ (reverse refs))))
+
+(defun markdown-get-used-uris ()
+ "Return a list of all used URIs in the buffer."
+ (save-excursion
+ (goto-char (point-min))
+ (let (uris)
+ (while (re-search-forward
+ (concat "\\(?:" markdown-regex-link-inline
+ "\\|" markdown-regex-angle-uri
+ "\\|" markdown-regex-uri
+ "\\|" markdown-regex-email
+ "\\)")
+ nil t)
+ (unless (or (markdown-inline-code-at-point-p)
+ (markdown-code-block-at-point-p))
+ (cl-pushnew (or (match-string-no-properties 6)
+ (match-string-no-properties 10)
+ (match-string-no-properties 12)
+ (match-string-no-properties 13))
+ uris :test #'equal)))
+ (reverse uris))))
+
+(defun markdown-inline-code-at-pos (pos)
+ "Return non-nil if there is an inline code fragment at POS.
+Return nil otherwise. Set match data according to
+`markdown-match-code' upon success.
+This function searches the block for a code fragment that
+contains the point using `markdown-match-code'. We do this
+because `thing-at-point-looking-at' does not work reliably with
+`markdown-regex-code'.
+
+The match data is set as follows:
+Group 1 matches the opening backquotes.
+Group 2 matches the code fragment itself, without backquotes.
+Group 3 matches the closing backquotes."
+ (save-excursion
+ (goto-char pos)
+ (let ((old-point (point))
+ (end-of-block (progn (markdown-end-of-text-block) (point)))
+ found)
+ (markdown-beginning-of-text-block)
+ (while (and (markdown-match-code end-of-block)
+ (setq found t)
+ (< (match-end 0) old-point)))
+ (let ((match-group (if (eq (char-after (match-beginning 0)) ?`) 0 1)))
+ (and found ; matched something
+ (<= (match-beginning match-group) old-point) ; match contains old-point
+ (> (match-end 0) old-point))))))
+
+(defun markdown-inline-code-at-pos-p (pos)
+ "Return non-nil if there is an inline code fragment at POS.
+Like `markdown-inline-code-at-pos`, but preserves match data."
+ (save-match-data (markdown-inline-code-at-pos pos)))
+
+(defun markdown-inline-code-at-point ()
+ "Return non-nil if the point is at an inline code fragment.
+See `markdown-inline-code-at-pos' for details."
+ (markdown-inline-code-at-pos (point)))
+
+(defun markdown-inline-code-at-point-p (&optional pos)
+ "Return non-nil if there is inline code at the POS.
+This is a predicate function counterpart to
+`markdown-inline-code-at-point' which does not modify the match
+data. See `markdown-code-block-at-point-p' for code blocks."
+ (save-match-data (markdown-inline-code-at-pos (or pos (point)))))
+
+(defun markdown-code-block-at-pos (pos)
+ "Return match data list if there is a code block at POS.
+Uses text properties at the beginning of the line position.
+This includes pre blocks, tilde-fenced code blocks, and GFM
+quoted code blocks. Return nil otherwise."
+ (let ((bol (save-excursion (goto-char pos) (point-at-bol))))
+ (or (get-text-property bol 'markdown-pre)
+ (let* ((bounds (markdown-get-enclosing-fenced-block-construct pos))
+ (second (cl-second bounds)))
+ (if second
+ ;; chunks are right open
+ (when (< pos second)
+ bounds)
+ bounds)))))
+
+;; Function was renamed to emphasize that it does not modify match-data.
+(defalias 'markdown-code-block-at-point 'markdown-code-block-at-point-p)
+
+(defun markdown-code-block-at-point-p (&optional pos)
+ "Return non-nil if there is a code block at the POS.
+This includes pre blocks, tilde-fenced code blocks, and GFM
+quoted code blocks. This function does not modify the match
+data. See `markdown-inline-code-at-point-p' for inline code."
+ (save-match-data (markdown-code-block-at-pos (or pos (point)))))
+
+(defun markdown-heading-at-point (&optional pos)
+ "Return non-nil if there is a heading at the POS.
+Set match data for `markdown-regex-header'."
+ (let ((match-data (get-text-property (or pos (point)) 'markdown-heading)))
+ (when match-data
+ (set-match-data match-data)
+ t)))
+
+(defun markdown-pipe-at-bol-p ()
+ "Return non-nil if the line begins with a pipe symbol.
+This may be useful for tables and Pandoc's line_blocks extension."
+ (char-equal (char-after (point-at-bol)) ?|))
+
+
+;;; Markdown Font Lock Matching Functions =====================================
+
+(defun markdown-range-property-any (begin end prop prop-values)
+ "Return t if PROP from BEGIN to END is equal to one of the given PROP-VALUES.
+Also returns t if PROP is a list containing one of the PROP-VALUES.
+Return nil otherwise."
+ (let (props)
+ (catch 'found
+ (dolist (loc (number-sequence begin end))
+ (when (setq props (get-text-property loc prop))
+ (cond ((listp props)
+ ;; props is a list, check for membership
+ (dolist (val prop-values)
+ (when (memq val props) (throw 'found loc))))
+ (t
+ ;; props is a scalar, check for equality
+ (dolist (val prop-values)
+ (when (eq val props) (throw 'found loc))))))))))
+
+(defun markdown-range-properties-exist (begin end props)
+ (cl-loop
+ for loc in (number-sequence begin end)
+ with result = nil
+ while (not
+ (setq result
+ (cl-some (lambda (prop) (get-text-property loc prop)) props)))
+ finally return result))
+
+(defun markdown-match-inline-generic (regex last &optional faceless)
+ "Match inline REGEX from the point to LAST.
+When FACELESS is non-nil, do not return matches where faces have been applied."
+ (when (re-search-forward regex last t)
+ (let ((bounds (markdown-code-block-at-pos (match-beginning 1)))
+ (face (and faceless (text-property-not-all
+ (match-beginning 0) (match-end 0) 'face nil))))
+ (cond
+ ;; In code block: move past it and recursively search again
+ (bounds
+ (when (< (goto-char (cl-second bounds)) last)
+ (markdown-match-inline-generic regex last faceless)))
+ ;; When faces are found in the match range, skip over the match and
+ ;; recursively search again.
+ (face
+ (when (< (goto-char (match-end 0)) last)
+ (markdown-match-inline-generic regex last faceless)))
+ ;; Keep match data and return t when in bounds.
+ (t
+ (<= (match-end 0) last))))))
+
+(defun markdown-match-code (last)
+ "Match inline code fragments from point to LAST."
+ (unless (bobp)
+ (backward-char 1))
+ (when (markdown-search-until-condition
+ (lambda ()
+ (and
+ ;; Advance point in case of failure, but without exceeding last.
+ (goto-char (min (1+ (match-beginning 1)) last))
+ (not (markdown-in-comment-p (match-beginning 1)))
+ (not (markdown-in-comment-p (match-end 1)))
+ (not (markdown-code-block-at-pos (match-beginning 1)))))
+ markdown-regex-code last t)
+ (set-match-data (list (match-beginning 1) (match-end 1)
+ (match-beginning 2) (match-end 2)
+ (match-beginning 3) (match-end 3)
+ (match-beginning 4) (match-end 4)))
+ (goto-char (min (1+ (match-end 0)) last (point-max)))
+ t))
+
+(defun markdown--gfm-markup-underscore-p (begin end)
+ (let ((is-underscore (eql (char-after begin) ?_)))
+ (if (not is-underscore)
+ t
+ (save-excursion
+ (save-match-data
+ (goto-char begin)
+ (and (looking-back "\\(?:^\\|[[:blank:][:punct:]]\\)" (1- begin))
+ (progn
+ (goto-char end)
+ (looking-at-p "\\(?:[[:blank:][:punct:]]\\|$\\)"))))))))
+
+(defun markdown-match-bold (last)
+ "Match inline bold from the point to LAST."
+ (when (markdown-match-inline-generic markdown-regex-bold last)
+ (let ((is-gfm (derived-mode-p 'gfm-mode))
+ (begin (match-beginning 2))
+ (end (match-end 2)))
+ (if (or (markdown-inline-code-at-pos-p begin)
+ (markdown-inline-code-at-pos-p end)
+ (markdown-in-comment-p)
+ (markdown-range-property-any
+ begin begin 'face '(markdown-url-face
+ markdown-plain-url-face))
+ (markdown-range-property-any
+ begin end 'face '(markdown-hr-face
+ markdown-math-face))
+ (and is-gfm (not (markdown--gfm-markup-underscore-p begin end))))
+ (progn (goto-char (min (1+ begin) last))
+ (when (< (point) last)
+ (markdown-match-bold last)))
+ (set-match-data (list (match-beginning 2) (match-end 2)
+ (match-beginning 3) (match-end 3)
+ (match-beginning 4) (match-end 4)
+ (match-beginning 5) (match-end 5)))
+ t))))
+
+(defun markdown-match-italic (last)
+ "Match inline italics from the point to LAST."
+ (let* ((is-gfm (derived-mode-p 'gfm-mode))
+ (regex (if is-gfm
+ markdown-regex-gfm-italic
+ markdown-regex-italic)))
+ (when (and (markdown-match-inline-generic regex last)
+ (not (markdown--face-p
+ (match-beginning 1)
+ '(markdown-html-attr-name-face markdown-html-attr-value-face))))
+ (let ((begin (match-beginning 1))
+ (end (match-end 1))
+ (close-end (match-end 4)))
+ (if (or (eql (char-before begin) (char-after begin))
+ (markdown-inline-code-at-pos-p begin)
+ (markdown-inline-code-at-pos-p (1- end))
+ (markdown-in-comment-p)
+ (markdown-range-property-any
+ begin begin 'face '(markdown-url-face
+ markdown-plain-url-face))
+ (markdown-range-property-any
+ begin end 'face '(markdown-bold-face
+ markdown-list-face
+ markdown-hr-face
+ markdown-math-face))
+ (and is-gfm
+ (or (char-equal (char-after begin) (char-after (1+ begin))) ;; check bold case
+ (not (markdown--gfm-markup-underscore-p begin close-end)))))
+ (progn (goto-char (min (1+ begin) last))
+ (when (< (point) last)
+ (markdown-match-italic last)))
+ (set-match-data (list (match-beginning 1) (match-end 1)
+ (match-beginning 2) (match-end 2)
+ (match-beginning 3) (match-end 3)
+ (match-beginning 4) (match-end 4)))
+ t)))))
+
+(defun markdown--match-highlighting (last)
+ (when markdown-enable-highlighting-syntax
+ (re-search-forward markdown-regex-highlighting last t)))
+
+(defun markdown-match-math-generic (regex last)
+ "Match REGEX from point to LAST.
+REGEX is either `markdown-regex-math-inline-single' for matching
+$..$ or `markdown-regex-math-inline-double' for matching $$..$$."
+ (when (markdown-match-inline-generic regex last)
+ (let ((begin (match-beginning 1)) (end (match-end 1)))
+ (prog1
+ (if (or (markdown-range-property-any
+ begin end 'face
+ '(markdown-inline-code-face markdown-bold-face))
+ (markdown-range-properties-exist
+ begin end
+ (markdown-get-fenced-block-middle-properties)))
+ (markdown-match-math-generic regex last)
+ t)
+ (goto-char (1+ (match-end 0)))))))
+
+(defun markdown-match-list-items (last)
+ "Match list items from point to LAST."
+ (let* ((first (point))
+ (pos first)
+ (prop 'markdown-list-item)
+ (bounds (car (get-text-property pos prop))))
+ (while
+ (and (or (null (setq bounds (car (get-text-property pos prop))))
+ (< (cl-first bounds) pos))
+ (< (point) last)
+ (setq pos (next-single-property-change pos prop nil last))
+ (goto-char pos)))
+ (when bounds
+ (set-match-data (cl-seventh bounds))
+ ;; Step at least one character beyond point. Otherwise
+ ;; `font-lock-fontify-keywords-region' infloops.
+ (goto-char (min (1+ (max (point-at-eol) first))
+ (point-max)))
+ t)))
+
+(defun markdown-match-math-single (last)
+ "Match single quoted $..$ math from point to LAST."
+ (when markdown-enable-math
+ (when (and (char-equal (char-after) ?$)
+ (not (bolp))
+ (not (char-equal (char-before) ?\\))
+ (not (char-equal (char-before) ?$)))
+ (forward-char -1))
+ (markdown-match-math-generic markdown-regex-math-inline-single last)))
+
+(defun markdown-match-math-double (last)
+ "Match double quoted $$..$$ math from point to LAST."
+ (when markdown-enable-math
+ (when (and (< (1+ (point)) (point-max))
+ (char-equal (char-after) ?$)
+ (char-equal (char-after (1+ (point))) ?$)
+ (not (bolp))
+ (not (char-equal (char-before) ?\\))
+ (not (char-equal (char-before) ?$)))
+ (forward-char -1))
+ (markdown-match-math-generic markdown-regex-math-inline-double last)))
+
+(defun markdown-match-math-display (last)
+ "Match bracketed display math \[..\] and \\[..\\] from point to LAST."
+ (when markdown-enable-math
+ (markdown-match-math-generic markdown-regex-math-display last)))
+
+(defun markdown-match-propertized-text (property last)
+ "Match text with PROPERTY from point to LAST.
+Restore match data previously stored in PROPERTY."
+ (let ((saved (get-text-property (point) property))
+ pos)
+ (unless saved
+ (setq pos (next-single-property-change (point) property nil last))
+ (unless (= pos last)
+ (setq saved (get-text-property pos property))))
+ (when saved
+ (set-match-data saved)
+ ;; Step at least one character beyond point. Otherwise
+ ;; `font-lock-fontify-keywords-region' infloops.
+ (goto-char (min (1+ (max (match-end 0) (point)))
+ (point-max)))
+ saved)))
+
+(defun markdown-match-pre-blocks (last)
+ "Match preformatted blocks from point to LAST.
+Use data stored in 'markdown-pre text property during syntax
+analysis."
+ (markdown-match-propertized-text 'markdown-pre last))
+
+(defun markdown-match-gfm-code-blocks (last)
+ "Match GFM quoted code blocks from point to LAST.
+Use data stored in 'markdown-gfm-code text property during syntax
+analysis."
+ (markdown-match-propertized-text 'markdown-gfm-code last))
+
+(defun markdown-match-gfm-open-code-blocks (last)
+ (markdown-match-propertized-text 'markdown-gfm-block-begin last))
+
+(defun markdown-match-gfm-close-code-blocks (last)
+ (markdown-match-propertized-text 'markdown-gfm-block-end last))
+
+(defun markdown-match-fenced-code-blocks (last)
+ "Match fenced code blocks from the point to LAST."
+ (markdown-match-propertized-text 'markdown-fenced-code last))
+
+(defun markdown-match-fenced-start-code-block (last)
+ (markdown-match-propertized-text 'markdown-tilde-fence-begin last))
+
+(defun markdown-match-fenced-end-code-block (last)
+ (markdown-match-propertized-text 'markdown-tilde-fence-end last))
+
+(defun markdown-match-blockquotes (last)
+ "Match blockquotes from point to LAST.
+Use data stored in 'markdown-blockquote text property during syntax
+analysis."
+ (markdown-match-propertized-text 'markdown-blockquote last))
+
+(defun markdown-match-hr (last)
+ "Match horizontal rules comments from the point to LAST."
+ (markdown-match-propertized-text 'markdown-hr last))
+
+(defun markdown-match-comments (last)
+ "Match HTML comments from the point to LAST."
+ (when (and (skip-syntax-forward "^<" last))
+ (let ((beg (point)))
+ (when (and (skip-syntax-forward "^>" last) (< (point) last))
+ (forward-char)
+ (set-match-data (list beg (point)))
+ t))))
+
+(defun markdown-match-generic-links (last ref)
+ "Match inline links from point to LAST.
+When REF is non-nil, match reference links instead of standard
+links with URLs.
+This function should only be used during font-lock, as it
+determines syntax based on the presence of faces for previously
+processed elements."
+ ;; Search for the next potential link (not in a code block).
+ (let ((prohibited-faces '(markdown-pre-face
+ markdown-code-face
+ markdown-inline-code-face
+ markdown-comment-face))
+ found)
+ (while
+ (and (not found) (< (point) last)
+ (progn
+ ;; Clear match data to test for a match after functions returns.
+ (set-match-data nil)
+ ;; Preliminary regular expression search so we can return
+ ;; quickly upon failure. This doesn't handle malformed links
+ ;; or nested square brackets well, so if it passes we back up
+ ;; continue with a more precise search.
+ (re-search-forward
+ (if ref
+ markdown-regex-link-reference
+ markdown-regex-link-inline)
+ last 'limit)))
+ ;; Keep searching if this is in a code block, inline code, or a
+ ;; comment, or if it is include syntax. The link text portion
+ ;; (group 3) may contain inline code or comments, but the
+ ;; markup, URL, and title should not be part of such elements.
+ (if (or (markdown-range-property-any
+ (match-beginning 0) (match-end 2) 'face prohibited-faces)
+ (markdown-range-property-any
+ (match-beginning 4) (match-end 0) 'face prohibited-faces)
+ (and (char-equal (char-after (point-at-bol)) ?<)
+ (char-equal (char-after (1+ (point-at-bol))) ?<)))
+ (set-match-data nil)
+ (setq found t))))
+ ;; Match opening exclamation point (optional) and left bracket.
+ (when (match-beginning 2)
+ (let* ((bang (match-beginning 1))
+ (first-begin (match-beginning 2))
+ ;; Find end of block to prevent matching across blocks.
+ (end-of-block (save-excursion
+ (progn
+ (goto-char (match-beginning 2))
+ (markdown-end-of-text-block)
+ (point))))
+ ;; Move over balanced expressions to closing right bracket.
+ ;; Catch unbalanced expression errors and return nil.
+ (first-end (condition-case nil
+ (and (goto-char first-begin)
+ (scan-sexps (point) 1))
+ (error nil)))
+ ;; Continue with point at CONT-POINT upon failure.
+ (cont-point (min (1+ first-begin) last))
+ second-begin second-end url-begin url-end
+ title-begin title-end)
+ ;; When bracket found, in range, and followed by a left paren/bracket...
+ (when (and first-end (< first-end end-of-block) (goto-char first-end)
+ (char-equal (char-after (point)) (if ref ?\[ ?\()))
+ ;; Scan across balanced expressions for closing parenthesis/bracket.
+ (setq second-begin (point)
+ second-end (condition-case nil
+ (scan-sexps (point) 1)
+ (error nil)))
+ ;; Check that closing parenthesis/bracket is in range.
+ (if (and second-end (<= second-end end-of-block) (<= second-end last))
+ (progn
+ ;; Search for (optional) title inside closing parenthesis
+ (when (and (not ref) (search-forward "\"" second-end t))
+ (setq title-begin (1- (point))
+ title-end (and (goto-char second-end)
+ (search-backward "\"" (1+ title-begin) t))
+ title-end (and title-end (1+ title-end))))
+ ;; Store URL/reference range
+ (setq url-begin (1+ second-begin)
+ url-end (1- (or title-begin second-end)))
+ ;; Set match data, move point beyond link, and return
+ (set-match-data
+ (list (or bang first-begin) second-end ; 0 - all
+ bang (and bang (1+ bang)) ; 1 - bang
+ first-begin (1+ first-begin) ; 2 - markup
+ (1+ first-begin) (1- first-end) ; 3 - link text
+ (1- first-end) first-end ; 4 - markup
+ second-begin (1+ second-begin) ; 5 - markup
+ url-begin url-end ; 6 - url/reference
+ title-begin title-end ; 7 - title
+ (1- second-end) second-end)) ; 8 - markup
+ ;; Nullify cont-point and leave point at end and
+ (setq cont-point nil)
+ (goto-char second-end))
+ ;; If no closing parenthesis in range, update continuation point
+ (setq cont-point (min end-of-block second-begin))))
+ (cond
+ ;; On failure, continue searching at cont-point
+ ((and cont-point (< cont-point last))
+ (goto-char cont-point)
+ (markdown-match-generic-links last ref))
+ ;; No more text, return nil
+ ((and cont-point (= cont-point last))
+ nil)
+ ;; Return t if a match occurred
+ (t t)))))
+
+(defun markdown-match-angle-uris (last)
+ "Match angle bracket URIs from point to LAST."
+ (when (markdown-match-inline-generic markdown-regex-angle-uri last)
+ (goto-char (1+ (match-end 0)))))
+
+(defun markdown-match-plain-uris (last)
+ "Match plain URIs from point to LAST."
+ (when (markdown-match-inline-generic markdown-regex-uri last t)
+ (goto-char (1+ (match-end 0)))))
+
+(defvar markdown-conditional-search-function #'re-search-forward
+ "Conditional search function used in `markdown-search-until-condition'.
+Made into a variable to allow for dynamic let-binding.")
+
+(defun markdown-search-until-condition (condition &rest args)
+ (let (ret)
+ (while (and (not ret) (apply markdown-conditional-search-function args))
+ (setq ret (funcall condition)))
+ ret))
+
+(defun markdown-metadata-line-p (pos regexp)
+ (save-excursion
+ (or (= (line-number-at-pos pos) 1)
+ (progn
+ (forward-line -1)
+ ;; skip multi-line metadata
+ (while (and (looking-at-p "^\\s-+[[:alpha:]]")
+ (> (line-number-at-pos (point)) 1))
+ (forward-line -1))
+ (looking-at-p regexp)))))
+
+(defun markdown-match-generic-metadata (regexp last)
+ "Match metadata declarations specified by REGEXP from point to LAST.
+These declarations must appear inside a metadata block that begins at
+the beginning of the buffer and ends with a blank line (or the end of
+the buffer)."
+ (let* ((first (point))
+ (end-re "\n[ \t]*\n\\|\n\\'\\|\\'")
+ (block-begin (goto-char 1))
+ (block-end (re-search-forward end-re nil t)))
+ (if (and block-end (> first block-end))
+ ;; Don't match declarations if there is no metadata block or if
+ ;; the point is beyond the block. Move point to point-max to
+ ;; prevent additional searches and return return nil since nothing
+ ;; was found.
+ (progn (goto-char (point-max)) nil)
+ ;; If a block was found that begins before LAST and ends after
+ ;; point, search for declarations inside it. If the starting is
+ ;; before the beginning of the block, start there. Otherwise,
+ ;; move back to FIRST.
+ (goto-char (if (< first block-begin) block-begin first))
+ (if (and (re-search-forward regexp (min last block-end) t)
+ (markdown-metadata-line-p (point) regexp))
+ ;; If a metadata declaration is found, set match-data and return t.
+ (let ((key-beginning (match-beginning 1))
+ (key-end (match-end 1))
+ (markup-begin (match-beginning 2))
+ (markup-end (match-end 2))
+ (value-beginning (match-beginning 3)))
+ (set-match-data (list key-beginning (point) ; complete metadata
+ key-beginning key-end ; key
+ markup-begin markup-end ; markup
+ value-beginning (point))) ; value
+ t)
+ ;; Otherwise, move the point to last and return nil
+ (goto-char last)
+ nil))))
+
+(defun markdown-match-declarative-metadata (last)
+ "Match declarative metadata from the point to LAST."
+ (markdown-match-generic-metadata markdown-regex-declarative-metadata last))
+
+(defun markdown-match-pandoc-metadata (last)
+ "Match Pandoc metadata from the point to LAST."
+ (markdown-match-generic-metadata markdown-regex-pandoc-metadata last))
+
+(defun markdown-match-yaml-metadata-begin (last)
+ (markdown-match-propertized-text 'markdown-yaml-metadata-begin last))
+
+(defun markdown-match-yaml-metadata-end (last)
+ (markdown-match-propertized-text 'markdown-yaml-metadata-end last))
+
+(defun markdown-match-yaml-metadata-key (last)
+ (markdown-match-propertized-text 'markdown-metadata-key last))
+
+(defun markdown-match-wiki-link (last)
+ "Match wiki links from point to LAST."
+ (when (and markdown-enable-wiki-links
+ (not markdown-wiki-link-fontify-missing)
+ (markdown-match-inline-generic markdown-regex-wiki-link last))
+ (let ((begin (match-beginning 1)) (end (match-end 1)))
+ (if (or (markdown-in-comment-p begin)
+ (markdown-in-comment-p end)
+ (markdown-inline-code-at-pos-p begin)
+ (markdown-inline-code-at-pos-p end)
+ (markdown-code-block-at-pos begin))
+ (progn (goto-char (min (1+ begin) last))
+ (when (< (point) last)
+ (markdown-match-wiki-link last)))
+ (set-match-data (list begin end))
+ t))))
+
+(defun markdown-match-inline-attributes (last)
+ "Match inline attributes from point to LAST."
+ ;; #428 re-search-forward markdown-regex-inline-attributes is very slow.
+ ;; So use simple regex for re-search-forward and use markdown-regex-inline-attributes
+ ;; against matched string.
+ (when (markdown-match-inline-generic "[ \t]*\\({\\)\\([^\n]*\\)}[ \t]*$" last)
+ (if (not (string-match-p markdown-regex-inline-attributes (match-string 0)))
+ (markdown-match-inline-attributes last)
+ (unless (or (markdown-inline-code-at-pos-p (match-beginning 0))
+ (markdown-inline-code-at-pos-p (match-end 0))
+ (markdown-in-comment-p))
+ t))))
+
+(defun markdown-match-leanpub-sections (last)
+ "Match Leanpub section markers from point to LAST."
+ (when (markdown-match-inline-generic markdown-regex-leanpub-sections last)
+ (unless (or (markdown-inline-code-at-pos-p (match-beginning 0))
+ (markdown-inline-code-at-pos-p (match-end 0))
+ (markdown-in-comment-p))
+ t)))
+
+(defun markdown-match-includes (last)
+ "Match include statements from point to LAST.
+Sets match data for the following seven groups:
+Group 1: opening two angle brackets
+Group 2: opening title delimiter (optional)
+Group 3: title text (optional)
+Group 4: closing title delimiter (optional)
+Group 5: opening filename delimiter
+Group 6: filename
+Group 7: closing filename delimiter"
+ (when (markdown-match-inline-generic markdown-regex-include last)
+ (let ((valid (not (or (markdown-in-comment-p (match-beginning 0))
+ (markdown-in-comment-p (match-end 0))
+ (markdown-code-block-at-pos (match-beginning 0))))))
+ (cond
+ ;; Parentheses and maybe square brackets, but no curly braces:
+ ;; match optional title in square brackets and file in parentheses.
+ ((and valid (match-beginning 5)
+ (not (match-beginning 8)))
+ (set-match-data (list (match-beginning 1) (match-end 7)
+ (match-beginning 1) (match-end 1)
+ (match-beginning 2) (match-end 2)
+ (match-beginning 3) (match-end 3)
+ (match-beginning 4) (match-end 4)
+ (match-beginning 5) (match-end 5)
+ (match-beginning 6) (match-end 6)
+ (match-beginning 7) (match-end 7))))
+ ;; Only square brackets present: match file in square brackets.
+ ((and valid (match-beginning 2)
+ (not (match-beginning 5))
+ (not (match-beginning 7)))
+ (set-match-data (list (match-beginning 1) (match-end 4)
+ (match-beginning 1) (match-end 1)
+ nil nil
+ nil nil
+ nil nil
+ (match-beginning 2) (match-end 2)
+ (match-beginning 3) (match-end 3)
+ (match-beginning 4) (match-end 4))))
+ ;; Only curly braces present: match file in curly braces.
+ ((and valid (match-beginning 8)
+ (not (match-beginning 2))
+ (not (match-beginning 5)))
+ (set-match-data (list (match-beginning 1) (match-end 10)
+ (match-beginning 1) (match-end 1)
+ nil nil
+ nil nil
+ nil nil
+ (match-beginning 8) (match-end 8)
+ (match-beginning 9) (match-end 9)
+ (match-beginning 10) (match-end 10))))
+ (t
+ ;; Not a valid match, move to next line and search again.
+ (forward-line)
+ (when (< (point) last)
+ (setq valid (markdown-match-includes last)))))
+ valid)))
+
+(defun markdown-match-html-tag (last)
+ "Match HTML tags from point to LAST."
+ (when (and markdown-enable-html
+ (markdown-match-inline-generic markdown-regex-html-tag last t))
+ (set-match-data (list (match-beginning 0) (match-end 0)
+ (match-beginning 1) (match-end 1)
+ (match-beginning 2) (match-end 2)
+ (match-beginning 9) (match-end 9)))
+ t))
+
+
+;;; Markdown Font Fontification Functions =====================================
+
+(defvar markdown--first-displayable-cache (make-hash-table :test #'equal))
+
+(defun markdown--first-displayable (seq)
+ "Return the first displayable character or string in SEQ.
+SEQ may be an atom or a sequence."
+ (let ((c (gethash seq markdown--first-displayable-cache t)))
+ (if (not (eq c t))
+ c
+ (puthash seq
+ (let ((seq (if (listp seq) seq (list seq))))
+ (cond ((stringp (car seq))
+ (cl-find-if
+ (lambda (str)
+ (and (mapcar #'char-displayable-p (string-to-list str))))
+ seq))
+ ((characterp (car seq))
+ (cl-find-if #'char-displayable-p seq))))
+ markdown--first-displayable-cache))))
+
+(defun markdown--marginalize-string (level)
+ "Generate atx markup string of given LEVEL for left margin."
+ (let ((margin-left-space-count
+ (- markdown-marginalize-headers-margin-width level)))
+ (concat (make-string margin-left-space-count ? )
+ (make-string level ?#))))
+
+(defun markdown-marginalize-update-current ()
+ "Update the window configuration to create a left margin."
+ (if window-system
+ (let* ((header-delimiter-font-width
+ (window-font-width nil 'markdown-header-delimiter-face))
+ (margin-pixel-width (* markdown-marginalize-headers-margin-width
+ header-delimiter-font-width))
+ (margin-char-width (/ margin-pixel-width (default-font-width))))
+ (set-window-margins nil margin-char-width))
+ ;; As a fallback, simply set margin based on character count.
+ (set-window-margins nil (1+ markdown-marginalize-headers-margin-width))))
+
+(defun markdown-fontify-headings (last)
+ "Add text properties to headings from point to LAST."
+ (when (markdown-match-propertized-text 'markdown-heading last)
+ (let* ((level (markdown-outline-level))
+ (heading-face
+ (intern (format "markdown-header-face-%d" level)))
+ (heading-props `(face ,heading-face))
+ (left-markup-props
+ `(face markdown-header-delimiter-face
+ ,@(cond
+ (markdown-hide-markup
+ `(display ""))
+ (markdown-marginalize-headers
+ `(display ((margin left-margin)
+ ,(markdown--marginalize-string level)))))))
+ (right-markup-props
+ `(face markdown-header-delimiter-face
+ ,@(when markdown-hide-markup `(display ""))))
+ (rule-props `(face markdown-header-rule-face
+ ,@(when markdown-hide-markup `(display "")))))
+ (if (match-end 1)
+ ;; Setext heading
+ (progn (add-text-properties
+ (match-beginning 1) (match-end 1) heading-props)
+ (if (= level 1)
+ (add-text-properties
+ (match-beginning 2) (match-end 2) rule-props)
+ (add-text-properties
+ (match-beginning 3) (match-end 3) rule-props)))
+ ;; atx heading
+ (add-text-properties
+ (match-beginning 4) (match-end 4) left-markup-props)
+ (add-text-properties
+ (match-beginning 5) (match-end 5) heading-props)
+ (when (match-end 6)
+ (add-text-properties
+ (match-beginning 6) (match-end 6) right-markup-props))))
+ t))
+
+(defun markdown-fontify-tables (last)
+ (when (re-search-forward "|" last t)
+ (when (markdown-table-at-point-p)
+ (font-lock-append-text-property
+ (line-beginning-position) (min (1+ (line-end-position)) (point-max))
+ 'face 'markdown-table-face))
+ (forward-line 1)
+ t))
+
+(defun markdown-fontify-blockquotes (last)
+ "Apply font-lock properties to blockquotes from point to LAST."
+ (when (markdown-match-blockquotes last)
+ (let ((display-string
+ (markdown--first-displayable markdown-blockquote-display-char)))
+ (add-text-properties
+ (match-beginning 1) (match-end 1)
+ (if markdown-hide-markup
+ `(face markdown-blockquote-face display ,display-string)
+ `(face markdown-markup-face)))
+ (font-lock-append-text-property
+ (match-beginning 0) (match-end 0) 'face 'markdown-blockquote-face)
+ t)))
+
+(defun markdown-fontify-list-items (last)
+ "Apply font-lock properties to list markers from point to LAST."
+ (when (markdown-match-list-items last)
+ (when (not (markdown-code-block-at-point-p (match-beginning 2)))
+ (let* ((indent (length (match-string-no-properties 1)))
+ (level (/ indent markdown-list-indent-width)) ;; level = 0, 1, 2, ...
+ (bullet (nth (mod level (length markdown-list-item-bullets))
+ markdown-list-item-bullets)))
+ (add-text-properties
+ (match-beginning 2) (match-end 2) '(face markdown-list-face))
+ (when markdown-hide-markup
+ (cond
+ ;; Unordered lists
+ ((string-match-p "[\\*\\+-]" (match-string 2))
+ (add-text-properties
+ (match-beginning 2) (match-end 2) `(display ,bullet)))
+ ;; Definition lists
+ ((string-equal ":" (match-string 2))
+ (let ((display-string
+ (char-to-string (markdown--first-displayable
+ markdown-definition-display-char))))
+ (add-text-properties (match-beginning 2) (match-end 2)
+ `(display ,display-string))))))))
+ t))
+
+(defun markdown-fontify-hrs (last)
+ "Add text properties to horizontal rules from point to LAST."
+ (when (markdown-match-hr last)
+ (let ((hr-char (markdown--first-displayable markdown-hr-display-char)))
+ (add-text-properties
+ (match-beginning 0) (match-end 0)
+ `(face markdown-hr-face
+ font-lock-multiline t
+ ,@(when (and markdown-hide-markup hr-char)
+ `(display ,(make-string
+ (1- (window-body-width)) hr-char)))))
+ t)))
+
+(defun markdown-fontify-sub-superscripts (last)
+ "Apply text properties to sub- and superscripts from point to LAST."
+ (when (markdown-search-until-condition
+ (lambda () (and (not (markdown-code-block-at-point-p))
+ (not (markdown-inline-code-at-point-p))
+ (not (markdown-in-comment-p))))
+ markdown-regex-sub-superscript last t)
+ (let* ((subscript-p (string= (match-string 2) "~"))
+ (props
+ (if subscript-p
+ (car markdown-sub-superscript-display)
+ (cdr markdown-sub-superscript-display)))
+ (mp (list 'face 'markdown-markup-face
+ 'invisible 'markdown-markup)))
+ (when markdown-hide-markup
+ (put-text-property (match-beginning 3) (match-end 3)
+ 'display props))
+ (add-text-properties (match-beginning 2) (match-end 2) mp)
+ (add-text-properties (match-beginning 4) (match-end 4) mp)
+ t)))
+
+
+;;; Syntax Table ==============================================================
+
+(defvar markdown-mode-syntax-table
+ (let ((tab (make-syntax-table text-mode-syntax-table)))
+ (modify-syntax-entry ?\" "." tab)
+ tab)
+ "Syntax table for `markdown-mode'.")
+
+
+;;; Element Insertion =========================================================
+
+(defun markdown-ensure-blank-line-before ()
+ "If previous line is not already blank, insert a blank line before point."
+ (unless (bolp) (insert "\n"))
+ (unless (or (bobp) (looking-back "\n\\s-*\n" nil)) (insert "\n")))
+
+(defun markdown-ensure-blank-line-after ()
+ "If following line is not already blank, insert a blank line after point.
+Return the point where it was originally."
+ (save-excursion
+ (unless (eolp) (insert "\n"))
+ (unless (or (eobp) (looking-at-p "\n\\s-*\n")) (insert "\n"))))
+
+(defun markdown-wrap-or-insert (s1 s2 &optional thing beg end)
+ "Insert the strings S1 and S2, wrapping around region or THING.
+If a region is specified by the optional BEG and END arguments,
+wrap the strings S1 and S2 around that region.
+If there is an active region, wrap the strings S1 and S2 around
+the region. If there is not an active region but the point is at
+THING, wrap that thing (which defaults to word). Otherwise, just
+insert S1 and S2 and place the point in between. Return the
+bounds of the entire wrapped string, or nil if nothing was wrapped
+and S1 and S2 were only inserted."
+ (let (a b bounds new-point)
+ (cond
+ ;; Given region
+ ((and beg end)
+ (setq a beg
+ b end
+ new-point (+ (point) (length s1))))
+ ;; Active region
+ ((use-region-p)
+ (setq a (region-beginning)
+ b (region-end)
+ new-point (+ (point) (length s1))))
+ ;; Thing (word) at point
+ ((setq bounds (markdown-bounds-of-thing-at-point (or thing 'word)))
+ (setq a (car bounds)
+ b (cdr bounds)
+ new-point (+ (point) (length s1))))
+ ;; No active region and no word
+ (t
+ (setq a (point)
+ b (point))))
+ (goto-char b)
+ (insert s2)
+ (goto-char a)
+ (insert s1)
+ (when new-point (goto-char new-point))
+ (if (= a b)
+ nil
+ (setq b (+ b (length s1) (length s2)))
+ (cons a b))))
+
+(defun markdown-point-after-unwrap (cur prefix suffix)
+ "Return desired position of point after an unwrapping operation.
+CUR gives the position of the point before the operation.
+Additionally, two cons cells must be provided. PREFIX gives the
+bounds of the prefix string and SUFFIX gives the bounds of the
+suffix string."
+ (cond ((< cur (cdr prefix)) (car prefix))
+ ((< cur (car suffix)) (- cur (- (cdr prefix) (car prefix))))
+ ((<= cur (cdr suffix))
+ (- cur (+ (- (cdr prefix) (car prefix))
+ (- cur (car suffix)))))
+ (t cur)))
+
+(defun markdown-unwrap-thing-at-point (regexp all text)
+ "Remove prefix and suffix of thing at point and reposition the point.
+When the thing at point matches REGEXP, replace the subexpression
+ALL with the string in subexpression TEXT. Reposition the point
+in an appropriate location accounting for the removal of prefix
+and suffix strings. Return new bounds of string from group TEXT.
+When REGEXP is nil, assumes match data is already set."
+ (when (or (null regexp)
+ (thing-at-point-looking-at regexp))
+ (let ((cur (point))
+ (prefix (cons (match-beginning all) (match-beginning text)))
+ (suffix (cons (match-end text) (match-end all)))
+ (bounds (cons (match-beginning text) (match-end text))))
+ ;; Replace the thing at point
+ (replace-match (match-string text) t t nil all)
+ ;; Reposition the point
+ (goto-char (markdown-point-after-unwrap cur prefix suffix))
+ ;; Adjust bounds
+ (setq bounds (cons (car prefix)
+ (- (cdr bounds) (- (cdr prefix) (car prefix))))))))
+
+(defun markdown-unwrap-things-in-region (beg end regexp all text)
+ "Remove prefix and suffix of all things in region from BEG to END.
+When a thing in the region matches REGEXP, replace the
+subexpression ALL with the string in subexpression TEXT.
+Return a cons cell containing updated bounds for the region."
+ (save-excursion
+ (goto-char beg)
+ (let ((removed 0) len-all len-text)
+ (while (re-search-forward regexp (- end removed) t)
+ (setq len-all (length (match-string-no-properties all)))
+ (setq len-text (length (match-string-no-properties text)))
+ (setq removed (+ removed (- len-all len-text)))
+ (replace-match (match-string text) t t nil all))
+ (cons beg (- end removed)))))
+
+(defun markdown-insert-hr (arg)
+ "Insert or replace a horizontal rule.
+By default, use the first element of `markdown-hr-strings'. When
+ARG is non-nil, as when given a prefix, select a different
+element as follows. When prefixed with \\[universal-argument],
+use the last element of `markdown-hr-strings' instead. When
+prefixed with an integer from 1 to the length of
+`markdown-hr-strings', use the element in that position instead."
+ (interactive "*P")
+ (when (thing-at-point-looking-at markdown-regex-hr)
+ (delete-region (match-beginning 0) (match-end 0)))
+ (markdown-ensure-blank-line-before)
+ (cond ((equal arg '(4))
+ (insert (car (reverse markdown-hr-strings))))
+ ((and (integerp arg) (> arg 0)
+ (<= arg (length markdown-hr-strings)))
+ (insert (nth (1- arg) markdown-hr-strings)))
+ (t
+ (insert (car markdown-hr-strings))))
+ (markdown-ensure-blank-line-after))
+
+(defun markdown--insert-common (start-delim end-delim regex start-group end-group face
+ &optional skip-space)
+ (if (use-region-p)
+ ;; Active region
+ (let* ((bounds (markdown-unwrap-things-in-region
+ (region-beginning) (region-end)
+ regex start-group end-group))
+ (beg (car bounds))
+ (end (cdr bounds)))
+ (when (and beg skip-space)
+ (save-excursion
+ (goto-char beg)
+ (skip-chars-forward "[ \t]")
+ (setq beg (point))))
+ (when (and end skip-space)
+ (save-excursion
+ (goto-char end)
+ (skip-chars-backward "[ \t]")
+ (setq end (point))))
+ (markdown-wrap-or-insert start-delim end-delim nil beg end))
+ (if (markdown--face-p (point) (list face))
+ (save-excursion
+ (while (and (markdown--face-p (point) (list face)) (not (bobp)))
+ (forward-char -1))
+ (forward-char (- (1- (length start-delim)))) ;; for delimiter
+ (unless (bolp)
+ (forward-char -1))
+ (when (looking-at regex)
+ (markdown-unwrap-thing-at-point nil start-group end-group)))
+ (if (thing-at-point-looking-at regex)
+ (markdown-unwrap-thing-at-point nil start-group end-group)
+ (markdown-wrap-or-insert start-delim end-delim 'word nil nil)))))
+
+(defun markdown-insert-bold ()
+ "Insert markup to make a region or word bold.
+If there is an active region, make the region bold. If the point
+is at a non-bold word, make the word bold. If the point is at a
+bold word or phrase, remove the bold markup. Otherwise, simply
+insert bold delimiters and place the point in between them."
+ (interactive)
+ (let ((delim (if markdown-bold-underscore "__" "**")))
+ (markdown--insert-common delim delim markdown-regex-bold 2 4 'markdown-bold-face t)))
+
+(defun markdown-insert-italic ()
+ "Insert markup to make a region or word italic.
+If there is an active region, make the region italic. If the point
+is at a non-italic word, make the word italic. If the point is at an
+italic word or phrase, remove the italic markup. Otherwise, simply
+insert italic delimiters and place the point in between them."
+ (interactive)
+ (let ((delim (if markdown-italic-underscore "_" "*")))
+ (markdown--insert-common delim delim markdown-regex-italic 1 3 'markdown-italic-face t)))
+
+(defun markdown-insert-strike-through ()
+ "Insert markup to make a region or word strikethrough.
+If there is an active region, make the region strikethrough. If the point
+is at a non-bold word, make the word strikethrough. If the point is at a
+strikethrough word or phrase, remove the strikethrough markup. Otherwise,
+simply insert bold delimiters and place the point in between them."
+ (interactive)
+ (markdown--insert-common
+ "~~" "~~" markdown-regex-strike-through 2 4 'markdown-strike-through-face t))
+
+(defun markdown-insert-code ()
+ "Insert markup to make a region or word an inline code fragment.
+If there is an active region, make the region an inline code
+fragment. If the point is at a word, make the word an inline
+code fragment. Otherwise, simply insert code delimiters and
+place the point in between them."
+ (interactive)
+ (if (use-region-p)
+ ;; Active region
+ (let ((bounds (markdown-unwrap-things-in-region
+ (region-beginning) (region-end)
+ markdown-regex-code 1 3)))
+ (markdown-wrap-or-insert "`" "`" nil (car bounds) (cdr bounds)))
+ ;; Code markup removal, code markup for word, or empty markup insertion
+ (if (markdown-inline-code-at-point)
+ (markdown-unwrap-thing-at-point nil 0 2)
+ (markdown-wrap-or-insert "`" "`" 'word nil nil))))
+
+(defun markdown-insert-kbd ()
+ "Insert markup to wrap region or word in <kbd> tags.
+If there is an active region, use the region. If the point is at
+a word, use the word. Otherwise, simply insert <kbd> tags and
+place the point in between them."
+ (interactive)
+ (if (use-region-p)
+ ;; Active region
+ (let ((bounds (markdown-unwrap-things-in-region
+ (region-beginning) (region-end)
+ markdown-regex-kbd 0 2)))
+ (markdown-wrap-or-insert "<kbd>" "</kbd>" nil (car bounds) (cdr bounds)))
+ ;; Markup removal, markup for word, or empty markup insertion
+ (if (thing-at-point-looking-at markdown-regex-kbd)
+ (markdown-unwrap-thing-at-point nil 0 2)
+ (markdown-wrap-or-insert "<kbd>" "</kbd>" 'word nil nil))))
+
+(defun markdown-insert-inline-link (text url &optional title)
+ "Insert an inline link with TEXT pointing to URL.
+Optionally, the user can provide a TITLE."
+ (let ((cur (point)))
+ (setq title (and title (concat " \"" title "\"")))
+ (insert (concat "[" text "](" url title ")"))
+ (cond ((not text) (goto-char (+ 1 cur)))
+ ((not url) (goto-char (+ 3 (length text) cur))))))
+
+(defun markdown-insert-inline-image (text url &optional title)
+ "Insert an inline link with alt TEXT pointing to URL.
+Optionally, also provide a TITLE."
+ (let ((cur (point)))
+ (setq title (and title (concat " \"" title "\"")))
+ (insert (concat "![" text "](" url title ")"))
+ (cond ((not text) (goto-char (+ 2 cur)))
+ ((not url) (goto-char (+ 4 (length text) cur))))))
+
+(defun markdown-insert-reference-link (text label &optional url title)
+ "Insert a reference link and, optionally, a reference definition.
+The link TEXT will be inserted followed by the optional LABEL.
+If a URL is given, also insert a definition for the reference
+LABEL according to `markdown-reference-location'. If a TITLE is
+given, it will be added to the end of the reference definition
+and will be used to populate the title attribute when converted
+to XHTML. If URL is nil, insert only the link portion (for
+example, when a reference label is already defined)."
+ (insert (concat "[" text "][" label "]"))
+ (when url
+ (markdown-insert-reference-definition
+ (if (string-equal label "") text label)
+ url title)))
+
+(defun markdown-insert-reference-image (text label &optional url title)
+ "Insert a reference image and, optionally, a reference definition.
+The alt TEXT will be inserted followed by the optional LABEL.
+If a URL is given, also insert a definition for the reference
+LABEL according to `markdown-reference-location'. If a TITLE is
+given, it will be added to the end of the reference definition
+and will be used to populate the title attribute when converted
+to XHTML. If URL is nil, insert only the link portion (for
+example, when a reference label is already defined)."
+ (insert (concat "![" text "][" label "]"))
+ (when url
+ (markdown-insert-reference-definition
+ (if (string-equal label "") text label)
+ url title)))
+
+(defun markdown-insert-reference-definition (label &optional url title)
+ "Add definition for reference LABEL with URL and TITLE.
+LABEL is a Markdown reference label without square brackets.
+URL and TITLE are optional. When given, the TITLE will
+be used to populate the title attribute when converted to XHTML."
+ ;; END specifies where to leave the point upon return
+ (let ((end (point)))
+ (cl-case markdown-reference-location
+ (end (goto-char (point-max)))
+ (immediately (markdown-end-of-text-block))
+ (subtree (markdown-end-of-subtree))
+ (header (markdown-end-of-defun)))
+ ;; Skip backwards over local variables. This logic is similar to the one
+ ;; used in ‘hack-local-variables’.
+ (when (and enable-local-variables (eobp))
+ (search-backward "\n\f" (max (- (point) 3000) (point-min)) :move)
+ (when (let ((case-fold-search t))
+ (search-forward "Local Variables:" nil :move))
+ (beginning-of-line 0)
+ (when (eq (char-before) ?\n) (backward-char))))
+ (unless (or (markdown-cur-line-blank-p)
+ (thing-at-point-looking-at markdown-regex-reference-definition))
+ (insert "\n"))
+ (insert "\n[" label "]: ")
+ (if url
+ (insert url)
+ ;; When no URL is given, leave point at END following the colon
+ (setq end (point)))
+ (when (> (length title) 0)
+ (insert " \"" title "\""))
+ (unless (looking-at-p "\n")
+ (insert "\n"))
+ (goto-char end)
+ (when url
+ (message
+ (markdown--substitute-command-keys
+ "Reference [%s] was defined, press \\[markdown-do] to jump there")
+ label))))
+
+(defcustom markdown-link-make-text-function nil
+ "Function that automatically generates a link text for a URL.
+
+If non-nil, this function will be called by
+`markdown--insert-link-or-image' and the result will be the
+default link text. The function should receive exactly one
+argument that corresponds to the link URL."
+ :group 'markdown
+ :type 'function
+ :package-version '(markdown-mode . "2.5"))
+
+(defcustom markdown-disable-tooltip-prompt nil
+ "Disable prompt for tooltip when inserting a link or image.
+
+If non-nil, `markdown-insert-link' and `markdown-insert-link'
+will not prompt the user to insert a tooltip text for the given
+link or image."
+ :group 'markdown
+ :type 'boolean
+ :safe 'booleanp
+ :package-version '(markdown-mode . "2.5"))
+
+(defun markdown--insert-link-or-image (image)
+ "Interactively insert new or update an existing link or image.
+When IMAGE is non-nil, insert an image. Otherwise, insert a link.
+This is an internal function called by
+`markdown-insert-link' and `markdown-insert-image'."
+ (cl-multiple-value-bind (begin end text uri ref title)
+ (if (use-region-p)
+ ;; Use region as either link text or URL as appropriate.
+ (let ((region (buffer-substring-no-properties
+ (region-beginning) (region-end))))
+ (if (string-match markdown-regex-uri region)
+ ;; Region contains a URL; use it as such.
+ (list (region-beginning) (region-end)
+ nil (match-string 0 region) nil nil)
+ ;; Region doesn't contain a URL, so use it as text.
+ (list (region-beginning) (region-end)
+ region nil nil nil)))
+ ;; Extract and use properties of existing link, if any.
+ (markdown-link-at-pos (point)))
+ (let* ((ref (when ref (concat "[" ref "]")))
+ (defined-refs (mapcar #'car (markdown-get-defined-references)))
+ (defined-ref-cands (mapcar (lambda (ref) (concat "[" ref "]")) defined-refs))
+ (used-uris (markdown-get-used-uris))
+ (uri-or-ref (completing-read
+ "URL or [reference]: "
+ (append defined-ref-cands used-uris)
+ nil nil (or uri ref)))
+ (ref (cond ((string-match "\\`\\[\\(.*\\)\\]\\'" uri-or-ref)
+ (match-string 1 uri-or-ref))
+ ((string-equal "" uri-or-ref)
+ "")))
+ (uri (unless ref uri-or-ref))
+ (text-prompt (if image
+ "Alt text: "
+ (if ref
+ "Link text: "
+ "Link text (blank for plain URL): ")))
+ (text (or text (and markdown-link-make-text-function uri
+ (funcall markdown-link-make-text-function uri))))
+ (text (completing-read text-prompt defined-refs nil nil text))
+ (text (if (= (length text) 0) nil text))
+ (plainp (and uri (not text)))
+ (implicitp (string-equal ref ""))
+ (ref (if implicitp text ref))
+ (definedp (and ref (markdown-reference-definition ref)))
+ (ref-url (unless (or uri definedp)
+ (completing-read "Reference URL: " used-uris)))
+ (title (unless (or plainp definedp markdown-disable-tooltip-prompt)
+ (read-string "Title (tooltip text, optional): " title)))
+ (title (if (= (length title) 0) nil title)))
+ (when (and image implicitp)
+ (user-error "Reference required: implicit image references are invalid"))
+ (when (and begin end)
+ (delete-region begin end))
+ (cond
+ ((and (not image) uri text)
+ (markdown-insert-inline-link text uri title))
+ ((and image uri text)
+ (markdown-insert-inline-image text uri title))
+ ((and ref text)
+ (if image
+ (markdown-insert-reference-image text (unless implicitp ref) nil title)
+ (markdown-insert-reference-link text (unless implicitp ref) nil title))
+ (unless definedp
+ (markdown-insert-reference-definition ref ref-url title)))
+ ((and (not image) uri)
+ (markdown-insert-uri uri))))))
+
+(defun markdown-insert-link ()
+ "Insert new or update an existing link, with interactive prompt.
+If the point is at an existing link or URL, update the link text,
+URL, reference label, and/or title. Otherwise, insert a new link.
+The type of link inserted (inline, reference, or plain URL)
+depends on which values are provided:
+
+* If a URL and TEXT are given, insert an inline link: [TEXT](URL).
+* If [REF] and TEXT are given, insert a reference link: [TEXT][REF].
+* If only TEXT is given, insert an implicit reference link: [TEXT][].
+* If only a URL is given, insert a plain link: <URL>.
+
+In other words, to create an implicit reference link, leave the
+URL prompt empty and to create a plain URL link, leave the link
+text empty.
+
+If there is an active region, use the text as the default URL, if
+it seems to be a URL, or link text value otherwise.
+
+If a given reference is not defined, this function will
+additionally prompt for the URL and optional title. In this case,
+the reference definition is placed at the location determined by
+`markdown-reference-location'. In addition, it is possible to
+have the `markdown-link-make-text-function' function, if non-nil,
+define the default link text before prompting the user for it.
+
+If `markdown-disable-tooltip-prompt' is non-nil, the user will
+not be prompted to add or modify a tooltip text.
+
+Through updating the link, this function can be used to convert a
+link of one type (inline, reference, or plain) to another type by
+selectively adding or removing information via the prompts."
+ (interactive)
+ (markdown--insert-link-or-image nil))
+
+(defun markdown-insert-image ()
+ "Insert new or update an existing image, with interactive prompt.
+If the point is at an existing image, update the alt text, URL,
+reference label, and/or title. Otherwise, insert a new image.
+The type of image inserted (inline or reference) depends on which
+values are provided:
+
+* If a URL and ALT-TEXT are given, insert an inline image:
+ ![ALT-TEXT](URL).
+* If [REF] and ALT-TEXT are given, insert a reference image:
+ ![ALT-TEXT][REF].
+
+If there is an active region, use the text as the default URL, if
+it seems to be a URL, or alt text value otherwise.
+
+If a given reference is not defined, this function will
+additionally prompt for the URL and optional title. In this case,
+the reference definition is placed at the location determined by
+`markdown-reference-location'.
+
+Through updating the image, this function can be used to convert an
+image of one type (inline or reference) to another type by
+selectively adding or removing information via the prompts."
+ (interactive)
+ (markdown--insert-link-or-image t))
+
+(defun markdown-insert-uri (&optional uri)
+ "Insert markup for an inline URI.
+If there is an active region, use it as the URI. If the point is
+at a URI, wrap it with angle brackets. If the point is at an
+inline URI, remove the angle brackets. Otherwise, simply insert
+angle brackets place the point between them."
+ (interactive)
+ (if (use-region-p)
+ ;; Active region
+ (let ((bounds (markdown-unwrap-things-in-region
+ (region-beginning) (region-end)
+ markdown-regex-angle-uri 0 2)))
+ (markdown-wrap-or-insert "<" ">" nil (car bounds) (cdr bounds)))
+ ;; Markup removal, URI at point, new URI, or empty markup insertion
+ (if (thing-at-point-looking-at markdown-regex-angle-uri)
+ (markdown-unwrap-thing-at-point nil 0 2)
+ (if uri
+ (insert "<" uri ">")
+ (markdown-wrap-or-insert "<" ">" 'url nil nil)))))
+
+(defun markdown-insert-wiki-link ()
+ "Insert a wiki link of the form [[WikiLink]].
+If there is an active region, use the region as the link text.
+If the point is at a word, use the word as the link text. If
+there is no active region and the point is not at word, simply
+insert link markup."
+ (interactive)
+ (if (use-region-p)
+ ;; Active region
+ (markdown-wrap-or-insert "[[" "]]" nil (region-beginning) (region-end))
+ ;; Markup removal, wiki link at at point, or empty markup insertion
+ (if (thing-at-point-looking-at markdown-regex-wiki-link)
+ (if (or markdown-wiki-link-alias-first
+ (null (match-string 5)))
+ (markdown-unwrap-thing-at-point nil 1 3)
+ (markdown-unwrap-thing-at-point nil 1 5))
+ (markdown-wrap-or-insert "[[" "]]"))))
+
+(defun markdown-remove-header ()
+ "Remove header markup if point is at a header.
+Return bounds of remaining header text if a header was removed
+and nil otherwise."
+ (interactive "*")
+ (or (markdown-unwrap-thing-at-point markdown-regex-header-atx 0 2)
+ (markdown-unwrap-thing-at-point markdown-regex-header-setext 0 1)))
+
+(defun markdown-insert-header (&optional level text setext)
+ "Insert or replace header markup.
+The level of the header is specified by LEVEL and header text is
+given by TEXT. LEVEL must be an integer from 1 and 6, and the
+default value is 1.
+When TEXT is nil, the header text is obtained as follows.
+If there is an active region, it is used as the header text.
+Otherwise, the current line will be used as the header text.
+If there is not an active region and the point is at a header,
+remove the header markup and replace with level N header.
+Otherwise, insert empty header markup and place the point in
+between.
+The style of the header will be atx (hash marks) unless
+SETEXT is non-nil, in which case a setext-style (underlined)
+header will be inserted."
+ (interactive "p\nsHeader text: ")
+ (setq level (min (max (or level 1) 1) (if setext 2 6)))
+ ;; Determine header text if not given
+ (when (null text)
+ (if (use-region-p)
+ ;; Active region
+ (setq text (delete-and-extract-region (region-beginning) (region-end)))
+ ;; No active region
+ (markdown-remove-header)
+ (setq text (delete-and-extract-region
+ (line-beginning-position) (line-end-position)))
+ (when (and setext (string-match-p "^[ \t]*$" text))
+ (setq text (read-string "Header text: "))))
+ (setq text (markdown-compress-whitespace-string text)))
+ ;; Insertion with given text
+ (markdown-ensure-blank-line-before)
+ (let (hdr)
+ (cond (setext
+ (setq hdr (make-string (string-width text) (if (= level 2) ?- ?=)))
+ (insert text "\n" hdr))
+ (t
+ (setq hdr (make-string level ?#))
+ (insert hdr " " text)
+ (when (null markdown-asymmetric-header) (insert " " hdr)))))
+ (markdown-ensure-blank-line-after)
+ ;; Leave point at end of text
+ (cond (setext
+ (backward-char (1+ (string-width text))))
+ ((null markdown-asymmetric-header)
+ (backward-char (1+ level)))))
+
+(defun markdown-insert-header-dwim (&optional arg setext)
+ "Insert or replace header markup.
+The level and type of the header are determined automatically by
+the type and level of the previous header, unless a prefix
+argument is given via ARG.
+With a numeric prefix valued 1 to 6, insert a header of the given
+level, with the type being determined automatically (note that
+only level 1 or 2 setext headers are possible).
+
+With a \\[universal-argument] prefix (i.e., when ARG is (4)),
+promote the heading by one level.
+With two \\[universal-argument] prefixes (i.e., when ARG is (16)),
+demote the heading by one level.
+When SETEXT is non-nil, prefer setext-style headers when
+possible (levels one and two).
+
+When there is an active region, use it for the header text. When
+the point is at an existing header, change the type and level
+according to the rules above.
+Otherwise, if the line is not empty, create a header using the
+text on the current line as the header text.
+Finally, if the point is on a blank line, insert empty header
+markup (atx) or prompt for text (setext).
+See `markdown-insert-header' for more details about how the
+header text is determined."
+ (interactive "*P")
+ (let (level)
+ (save-excursion
+ (when (or (thing-at-point-looking-at markdown-regex-header)
+ (re-search-backward markdown-regex-header nil t))
+ ;; level of current or previous header
+ (setq level (markdown-outline-level))
+ ;; match group 1 indicates a setext header
+ (setq setext (match-end 1))))
+ ;; check prefix argument
+ (cond
+ ((and (equal arg '(4)) level (> level 1)) ;; C-u
+ (cl-decf level))
+ ((and (equal arg '(16)) level (< level 6)) ;; C-u C-u
+ (cl-incf level))
+ (arg ;; numeric prefix
+ (setq level (prefix-numeric-value arg))))
+ ;; setext headers must be level one or two
+ (and level (setq setext (and setext (<= level 2))))
+ ;; insert the heading
+ (markdown-insert-header level nil setext)))
+
+(defun markdown-insert-header-setext-dwim (&optional arg)
+ "Insert or replace header markup, with preference for setext.
+See `markdown-insert-header-dwim' for details, including how ARG is handled."
+ (interactive "*P")
+ (markdown-insert-header-dwim arg t))
+
+(defun markdown-insert-header-atx-1 ()
+ "Insert a first level atx-style (hash mark) header.
+See `markdown-insert-header'."
+ (interactive "*")
+ (markdown-insert-header 1 nil nil))
+
+(defun markdown-insert-header-atx-2 ()
+ "Insert a level two atx-style (hash mark) header.
+See `markdown-insert-header'."
+ (interactive "*")
+ (markdown-insert-header 2 nil nil))
+
+(defun markdown-insert-header-atx-3 ()
+ "Insert a level three atx-style (hash mark) header.
+See `markdown-insert-header'."
+ (interactive "*")
+ (markdown-insert-header 3 nil nil))
+
+(defun markdown-insert-header-atx-4 ()
+ "Insert a level four atx-style (hash mark) header.
+See `markdown-insert-header'."
+ (interactive "*")
+ (markdown-insert-header 4 nil nil))
+
+(defun markdown-insert-header-atx-5 ()
+ "Insert a level five atx-style (hash mark) header.
+See `markdown-insert-header'."
+ (interactive "*")
+ (markdown-insert-header 5 nil nil))
+
+(defun markdown-insert-header-atx-6 ()
+ "Insert a sixth level atx-style (hash mark) header.
+See `markdown-insert-header'."
+ (interactive "*")
+ (markdown-insert-header 6 nil nil))
+
+(defun markdown-insert-header-setext-1 ()
+ "Insert a setext-style (underlined) first-level header.
+See `markdown-insert-header'."
+ (interactive "*")
+ (markdown-insert-header 1 nil t))
+
+(defun markdown-insert-header-setext-2 ()
+ "Insert a setext-style (underlined) second-level header.
+See `markdown-insert-header'."
+ (interactive "*")
+ (markdown-insert-header 2 nil t))
+
+(defun markdown-blockquote-indentation (loc)
+ "Return string containing necessary indentation for a blockquote at LOC.
+Also see `markdown-pre-indentation'."
+ (save-excursion
+ (goto-char loc)
+ (let* ((list-level (length (markdown-calculate-list-levels)))
+ (indent ""))
+ (dotimes (_ list-level indent)
+ (setq indent (concat indent " "))))))
+
+(defun markdown-insert-blockquote ()
+ "Start a blockquote section (or blockquote the region).
+If Transient Mark mode is on and a region is active, it is used as
+the blockquote text."
+ (interactive)
+ (if (use-region-p)
+ (markdown-blockquote-region (region-beginning) (region-end))
+ (markdown-ensure-blank-line-before)
+ (insert (markdown-blockquote-indentation (point)) "> ")
+ (markdown-ensure-blank-line-after)))
+
+(defun markdown-block-region (beg end prefix)
+ "Format the region using a block prefix.
+Arguments BEG and END specify the beginning and end of the
+region. The characters PREFIX will appear at the beginning
+of each line."
+ (save-excursion
+ (let* ((end-marker (make-marker))
+ (beg-marker (make-marker))
+ (prefix-without-trailing-whitespace
+ (replace-regexp-in-string (rx (+ blank) eos) "" prefix)))
+ ;; Ensure blank line after and remove extra whitespace
+ (goto-char end)
+ (skip-syntax-backward "-")
+ (set-marker end-marker (point))
+ (delete-horizontal-space)
+ (markdown-ensure-blank-line-after)
+ ;; Ensure blank line before and remove extra whitespace
+ (goto-char beg)
+ (skip-syntax-forward "-")
+ (delete-horizontal-space)
+ (markdown-ensure-blank-line-before)
+ (set-marker beg-marker (point))
+ ;; Insert PREFIX before each line
+ (goto-char beg-marker)
+ (while (and (< (line-beginning-position) end-marker)
+ (not (eobp)))
+ ;; Don’t insert trailing whitespace.
+ (insert (if (eolp) prefix-without-trailing-whitespace prefix))
+ (forward-line)))))
+
+(defun markdown-blockquote-region (beg end)
+ "Blockquote the region.
+Arguments BEG and END specify the beginning and end of the region."
+ (interactive "*r")
+ (markdown-block-region
+ beg end (concat (markdown-blockquote-indentation
+ (max (point-min) (1- beg))) "> ")))
+
+(defun markdown-pre-indentation (loc)
+ "Return string containing necessary whitespace for a pre block at LOC.
+Also see `markdown-blockquote-indentation'."
+ (save-excursion
+ (goto-char loc)
+ (let* ((list-level (length (markdown-calculate-list-levels)))
+ indent)
+ (dotimes (_ (1+ list-level) indent)
+ (setq indent (concat indent " "))))))
+
+(defun markdown-insert-pre ()
+ "Start a preformatted section (or apply to the region).
+If Transient Mark mode is on and a region is active, it is marked
+as preformatted text."
+ (interactive)
+ (if (use-region-p)
+ (markdown-pre-region (region-beginning) (region-end))
+ (markdown-ensure-blank-line-before)
+ (insert (markdown-pre-indentation (point)))
+ (markdown-ensure-blank-line-after)))
+
+(defun markdown-pre-region (beg end)
+ "Format the region as preformatted text.
+Arguments BEG and END specify the beginning and end of the region."
+ (interactive "*r")
+ (let ((indent (markdown-pre-indentation (max (point-min) (1- beg)))))
+ (markdown-block-region beg end indent)))
+
+(defun markdown-electric-backquote (arg)
+ "Insert a backquote.
+The numeric prefix argument ARG says how many times to repeat the insertion.
+Call `markdown-insert-gfm-code-block' interactively
+if three backquotes inserted at the beginning of line."
+ (interactive "*P")
+ (self-insert-command (prefix-numeric-value arg))
+ (when (and markdown-gfm-use-electric-backquote (looking-back "^```" nil))
+ (replace-match "")
+ (call-interactively #'markdown-insert-gfm-code-block)))
+
+(defconst markdown-gfm-recognized-languages
+ ;; To reproduce/update, evaluate the let-form in
+ ;; scripts/get-recognized-gfm-languages.el. that produces a single long sexp,
+ ;; but with appropriate use of a keyboard macro, indenting and filling it
+ ;; properly is pretty fast.
+ '("1C-Enterprise" "4D" "ABAP" "ABNF" "AGS-Script" "AMPL" "ANTLR"
+ "API-Blueprint" "APL" "ASN.1" "ASP" "ATS" "ActionScript" "Ada"
+ "Adobe-Font-Metrics" "Agda" "Alloy" "Alpine-Abuild" "Altium-Designer"
+ "AngelScript" "Ant-Build-System" "ApacheConf" "Apex"
+ "Apollo-Guidance-Computer" "AppleScript" "Arc" "AsciiDoc" "AspectJ" "Assembly"
+ "Asymptote" "Augeas" "AutoHotkey" "AutoIt" "Awk" "Ballerina" "Batchfile"
+ "Befunge" "BibTeX" "Bison" "BitBake" "Blade" "BlitzBasic" "BlitzMax"
+ "Bluespec" "Boo" "Brainfuck" "Brightscript" "C#" "C++" "C-ObjDump"
+ "C2hs-Haskell" "CLIPS" "CMake" "COBOL" "COLLADA" "CSON" "CSS" "CSV" "CWeb"
+ "Cabal-Config" "Cap'n-Proto" "CartoCSS" "Ceylon" "Chapel" "Charity" "ChucK"
+ "Cirru" "Clarion" "Clean" "Click" "Clojure" "Closure-Templates"
+ "Cloud-Firestore-Security-Rules" "CoNLL-U" "CodeQL" "CoffeeScript"
+ "ColdFusion" "ColdFusion-CFC" "Common-Lisp" "Common-Workflow-Language"
+ "Component-Pascal" "Cool" "Coq" "Cpp-ObjDump" "Creole" "Crystal" "Csound"
+ "Csound-Document" "Csound-Score" "Cuda" "Cycript" "Cython" "D-ObjDump"
+ "DIGITAL-Command-Language" "DM" "DNS-Zone" "DTrace" "Dafny" "Darcs-Patch"
+ "Dart" "DataWeave" "Dhall" "Diff" "DirectX-3D-File" "Dockerfile" "Dogescript"
+ "Dylan" "EBNF" "ECL" "ECLiPSe" "EJS" "EML" "EQ" "Eagle" "Easybuild"
+ "Ecere-Projects" "EditorConfig" "Edje-Data-Collection" "Eiffel" "Elixir" "Elm"
+ "Emacs-Lisp" "EmberScript" "Erlang" "F#" "F*" "FIGlet-Font" "FLUX" "Factor"
+ "Fancy" "Fantom" "Faust" "Filebench-WML" "Filterscript" "Formatted" "Forth"
+ "Fortran" "Fortran-Free-Form" "FreeMarker" "Frege" "G-code" "GAML" "GAMS"
+ "GAP" "GCC-Machine-Description" "GDB" "GDScript" "GEDCOM" "GLSL" "GN"
+ "Game-Maker-Language" "Genie" "Genshi" "Gentoo-Ebuild" "Gentoo-Eclass"
+ "Gerber-Image" "Gettext-Catalog" "Gherkin" "Git-Attributes" "Git-Config"
+ "Glyph" "Glyph-Bitmap-Distribution-Format" "Gnuplot" "Go" "Golo" "Gosu"
+ "Grace" "Gradle" "Grammatical-Framework" "Graph-Modeling-Language" "GraphQL"
+ "Graphviz-(DOT)" "Groovy" "Groovy-Server-Pages" "HAProxy" "HCL" "HLSL" "HTML"
+ "HTML+Django" "HTML+ECR" "HTML+EEX" "HTML+ERB" "HTML+PHP" "HTML+Razor" "HTTP"
+ "HXML" "Hack" "Haml" "Handlebars" "Harbour" "Haskell" "Haxe" "HiveQL" "HolyC"
+ "Hy" "HyPhy" "IDL" "IGOR-Pro" "INI" "IRC-log" "Idris" "Ignore-List" "Inform-7"
+ "Inno-Setup" "Io" "Ioke" "Isabelle" "Isabelle-ROOT" "JFlex" "JSON"
+ "JSON-with-Comments" "JSON5" "JSONLD" "JSONiq" "JSX" "Jasmin" "Java"
+ "Java-Properties" "Java-Server-Pages" "JavaScript" "JavaScript+ERB" "Jison"
+ "Jison-Lex" "Jolie" "Jsonnet" "Julia" "Jupyter-Notebook" "KRL" "KiCad-Layout"
+ "KiCad-Legacy-Layout" "KiCad-Schematic" "Kit" "Kotlin" "LFE" "LLVM" "LOLCODE"
+ "LSL" "LTspice-Symbol" "LabVIEW" "Lasso" "Latte" "Lean" "Less" "Lex"
+ "LilyPond" "Limbo" "Linker-Script" "Linux-Kernel-Module" "Liquid"
+ "Literate-Agda" "Literate-CoffeeScript" "Literate-Haskell" "LiveScript"
+ "Logos" "Logtalk" "LookML" "LoomScript" "Lua" "M4" "M4Sugar" "MATLAB"
+ "MAXScript" "MLIR" "MQL4" "MQL5" "MTML" "MUF" "Macaulay2" "Makefile" "Mako"
+ "Markdown" "Marko" "Mask" "Mathematica" "Maven-POM" "Max" "MediaWiki"
+ "Mercury" "Meson" "Metal" "Microsoft-Developer-Studio-Project" "MiniD" "Mirah"
+ "Modelica" "Modula-2" "Modula-3" "Module-Management-System" "Monkey" "Moocode"
+ "MoonScript" "Motorola-68K-Assembly" "Muse" "Myghty" "NASL" "NCL" "NEON" "NL"
+ "NPM-Config" "NSIS" "Nearley" "Nemerle" "NetLinx" "NetLinx+ERB" "NetLogo"
+ "NewLisp" "Nextflow" "Nginx" "Nim" "Ninja" "Nit" "Nix" "Nu" "NumPy" "OCaml"
+ "ObjDump" "Object-Data-Instance-Notation" "ObjectScript" "Objective-C"
+ "Objective-C++" "Objective-J" "Odin" "Omgrofl" "Opa" "Opal"
+ "Open-Policy-Agent" "OpenCL" "OpenEdge-ABL" "OpenQASM" "OpenRC-runscript"
+ "OpenSCAD" "OpenStep-Property-List" "OpenType-Feature-File" "Org" "Ox"
+ "Oxygene" "Oz" "P4" "PHP" "PLSQL" "PLpgSQL" "POV-Ray-SDL" "Pan" "Papyrus"
+ "Parrot" "Parrot-Assembly" "Parrot-Internal-Representation" "Pascal" "Pawn"
+ "Pep8" "Perl" "Pic" "Pickle" "PicoLisp" "PigLatin" "Pike" "PlantUML" "Pod"
+ "Pod-6" "PogoScript" "Pony" "PostCSS" "PostScript" "PowerBuilder" "PowerShell"
+ "Prisma" "Processing" "Proguard" "Prolog" "Propeller-Spin" "Protocol-Buffer"
+ "Public-Key" "Pug" "Puppet" "Pure-Data" "PureBasic" "PureScript" "Python"
+ "Python-console" "Python-traceback" "QML" "QMake" "Quake" "RAML" "RDoc"
+ "REALbasic" "REXX" "RHTML" "RMarkdown" "RPC" "RPM-Spec" "RUNOFF" "Racket"
+ "Ragel" "Raku" "Rascal" "Raw-token-data" "Readline-Config" "Reason" "Rebol"
+ "Red" "Redcode" "Regular-Expression" "Ren'Py" "RenderScript"
+ "Rich-Text-Format" "Ring" "Riot" "RobotFramework" "Roff" "Roff-Manpage"
+ "Rouge" "Ruby" "Rust" "SAS" "SCSS" "SMT" "SPARQL" "SQF" "SQL" "SQLPL"
+ "SRecode-Template" "SSH-Config" "STON" "SVG" "SWIG" "Sage" "SaltStack" "Sass"
+ "Scala" "Scaml" "Scheme" "Scilab" "Self" "ShaderLab" "Shell" "ShellSession"
+ "Shen" "Slash" "Slice" "Slim" "SmPL" "Smali" "Smalltalk" "Smarty" "Solidity"
+ "SourcePawn" "Spline-Font-Database" "Squirrel" "Stan" "Standard-ML" "Starlark"
+ "Stata" "Stylus" "SubRip-Text" "SugarSS" "SuperCollider" "Svelte" "Swift"
+ "SystemVerilog" "TI-Program" "TLA" "TOML" "TSQL" "TSX" "TXL" "Tcl" "Tcsh"
+ "TeX" "Tea" "Terra" "Texinfo" "Text" "Textile" "Thrift" "Turing" "Turtle"
+ "Twig" "Type-Language" "TypeScript" "Unified-Parallel-C" "Unity3D-Asset"
+ "Unix-Assembly" "Uno" "UnrealScript" "UrWeb" "VBA" "VBScript" "VCL" "VHDL"
+ "Vala" "Verilog" "Vim-Snippet" "Vim-script" "Visual-Basic-.NET" "Volt" "Vue"
+ "Wavefront-Material" "Wavefront-Object" "Web-Ontology-Language" "WebAssembly"
+ "WebIDL" "WebVTT" "Wget-Config" "Windows-Registry-Entries" "Wollok"
+ "World-of-Warcraft-Addon-Data" "X-BitMap" "X-Font-Directory-Index" "X-PixMap"
+ "X10" "XC" "XCompose" "XML" "XML-Property-List" "XPages" "XProc" "XQuery" "XS"
+ "XSLT" "Xojo" "Xtend" "YAML" "YANG" "YARA" "YASnippet" "Yacc" "ZAP" "ZIL"
+ "Zeek" "ZenScript" "Zephir" "Zig" "Zimpl" "cURL-Config" "desktop" "dircolors"
+ "eC" "edn" "fish" "mIRC-Script" "mcfunction" "mupad" "nanorc" "nesC" "ooc"
+ "reStructuredText" "sed" "wdl" "wisp" "xBase")
+ "Language specifiers recognized by GitHub's syntax highlighting features.")
+
+(defvar-local markdown-gfm-used-languages nil
+ "Language names used in GFM code blocks.")
+
+(defun markdown-trim-whitespace (str)
+ (replace-regexp-in-string
+ "\\(?:[[:space:]\r\n]+\\'\\|\\`[[:space:]\r\n]+\\)" "" str))
+
+(defun markdown-clean-language-string (str)
+ (replace-regexp-in-string
+ "{\\.?\\|}" "" (markdown-trim-whitespace str)))
+
+(defun markdown-validate-language-string (widget)
+ (let ((str (widget-value widget)))
+ (unless (string= str (markdown-clean-language-string str))
+ (widget-put widget :error (format "Invalid language spec: '%s'" str))
+ widget)))
+
+(defun markdown-gfm-get-corpus ()
+ "Create corpus of recognized GFM code block languages for the given buffer."
+ (let ((given-corpus (append markdown-gfm-additional-languages
+ markdown-gfm-recognized-languages)))
+ (append
+ markdown-gfm-used-languages
+ (if markdown-gfm-downcase-languages (cl-mapcar #'downcase given-corpus)
+ given-corpus))))
+
+(defun markdown-gfm-add-used-language (lang)
+ "Clean LANG and add to list of used languages."
+ (setq markdown-gfm-used-languages
+ (cons lang (remove lang markdown-gfm-used-languages))))
+
+(defcustom markdown-spaces-after-code-fence 1
+ "Number of space characters to insert after a code fence.
+\\<gfm-mode-map>\\[markdown-insert-gfm-code-block] inserts this many spaces between an
+opening code fence and an info string."
+ :group 'markdown
+ :type 'integer
+ :safe #'natnump
+ :package-version '(markdown-mode . "2.3"))
+
+(defcustom markdown-code-block-braces nil
+ "When non-nil, automatically insert braces for GFM code blocks."
+ :group 'markdown
+ :type 'boolean)
+
+(defun markdown-insert-gfm-code-block (&optional lang edit)
+ "Insert GFM code block for language LANG.
+If LANG is nil, the language will be queried from user. If a
+region is active, wrap this region with the markup instead. If
+the region boundaries are not on empty lines, these are added
+automatically in order to have the correct markup. When EDIT is
+non-nil (e.g., when \\[universal-argument] is given), edit the
+code block in an indirect buffer after insertion."
+ (interactive
+ (list (let ((completion-ignore-case nil))
+ (condition-case nil
+ (markdown-clean-language-string
+ (completing-read
+ "Programming language: "
+ (markdown-gfm-get-corpus)
+ nil 'confirm (car markdown-gfm-used-languages)
+ 'markdown-gfm-language-history))
+ (quit "")))
+ current-prefix-arg))
+ (unless (string= lang "") (markdown-gfm-add-used-language lang))
+ (when (and (> (length lang) 0)
+ (not markdown-code-block-braces))
+ (setq lang (concat (make-string markdown-spaces-after-code-fence ?\s)
+ lang)))
+ (let ((gfm-open-brace (if markdown-code-block-braces "{" ""))
+ (gfm-close-brace (if markdown-code-block-braces "}" "")))
+ (if (use-region-p)
+ (let* ((b (region-beginning)) (e (region-end)) end
+ (indent (progn (goto-char b) (current-indentation))))
+ (goto-char e)
+ ;; if we're on a blank line, don't newline, otherwise the ```
+ ;; should go on its own line
+ (unless (looking-back "\n" nil)
+ (newline))
+ (indent-to indent)
+ (insert "```")
+ (markdown-ensure-blank-line-after)
+ (setq end (point))
+ (goto-char b)
+ ;; if we're on a blank line, insert the quotes here, otherwise
+ ;; add a new line first
+ (unless (looking-at-p "\n")
+ (newline)
+ (forward-line -1))
+ (markdown-ensure-blank-line-before)
+ (indent-to indent)
+ (insert "```" gfm-open-brace lang gfm-close-brace)
+ (markdown-syntax-propertize-fenced-block-constructs (point-at-bol) end))
+ (let ((indent (current-indentation))
+ start-bol)
+ (delete-horizontal-space :backward-only)
+ (markdown-ensure-blank-line-before)
+ (indent-to indent)
+ (setq start-bol (point-at-bol))
+ (insert "```" gfm-open-brace lang gfm-close-brace "\n")
+ (indent-to indent)
+ (unless edit (insert ?\n))
+ (indent-to indent)
+ (insert "```")
+ (markdown-ensure-blank-line-after)
+ (markdown-syntax-propertize-fenced-block-constructs start-bol (point)))
+ (end-of-line 0)
+ (when edit (markdown-edit-code-block)))))
+
+(defun markdown-code-block-lang (&optional pos-prop)
+ "Return the language name for a GFM or tilde fenced code block.
+The beginning of the block may be described by POS-PROP,
+a cons of (pos . prop) giving the position and property
+at the beginning of the block."
+ (or pos-prop
+ (setq pos-prop
+ (markdown-max-of-seq
+ #'car
+ (cl-remove-if
+ #'null
+ (cl-mapcar
+ #'markdown-find-previous-prop
+ (markdown-get-fenced-block-begin-properties))))))
+ (when pos-prop
+ (goto-char (car pos-prop))
+ (set-match-data (get-text-property (point) (cdr pos-prop)))
+ ;; Note: Hard-coded group number assumes tilde
+ ;; and GFM fenced code regexp groups agree.
+ (let ((begin (match-beginning 3))
+ (end (match-end 3)))
+ (when (and begin end)
+ ;; Fix language strings beginning with periods, like ".ruby".
+ (when (eq (char-after begin) ?.)
+ (setq begin (1+ begin)))
+ (buffer-substring-no-properties begin end)))))
+
+(defun markdown-gfm-parse-buffer-for-languages (&optional buffer)
+ (with-current-buffer (or buffer (current-buffer))
+ (save-excursion
+ (goto-char (point-min))
+ (cl-loop
+ with prop = 'markdown-gfm-block-begin
+ for pos-prop = (markdown-find-next-prop prop)
+ while pos-prop
+ for lang = (markdown-code-block-lang pos-prop)
+ do (progn (when lang (markdown-gfm-add-used-language lang))
+ (goto-char (next-single-property-change (point) prop)))))))
+
+(defun markdown-insert-foldable-block ()
+ "Insert details disclosure element to make content foldable.
+If a region is active, wrap this region with the disclosure
+element. More detais here 'https://developer.mozilla.org/en-US/docs/Web/HTML/Element/details'."
+ (interactive)
+ (let ((details-open-tag "<details>")
+ (details-close-tag "</details>")
+ (summary-open-tag "<summary>")
+ (summary-close-tag " </summary>"))
+ (if (use-region-p)
+ (let* ((b (region-beginning))
+ (e (region-end))
+ (indent (progn (goto-char b) (current-indentation))))
+ (goto-char e)
+ ;; if we're on a blank line, don't newline, otherwise the tags
+ ;; should go on its own line
+ (unless (looking-back "\n" nil)
+ (newline))
+ (indent-to indent)
+ (insert details-close-tag)
+ (markdown-ensure-blank-line-after)
+ (goto-char b)
+ ;; if we're on a blank line, insert the quotes here, otherwise
+ ;; add a new line first
+ (unless (looking-at-p "\n")
+ (newline)
+ (forward-line -1))
+ (markdown-ensure-blank-line-before)
+ (indent-to indent)
+ (insert details-open-tag "\n")
+ (insert summary-open-tag summary-close-tag)
+ (search-backward summary-close-tag))
+ (let ((indent (current-indentation)))
+ (delete-horizontal-space :backward-only)
+ (markdown-ensure-blank-line-before)
+ (indent-to indent)
+ (insert details-open-tag "\n")
+ (insert summary-open-tag summary-close-tag "\n")
+ (insert details-close-tag)
+ (indent-to indent)
+ (markdown-ensure-blank-line-after)
+ (search-backward summary-close-tag)))))
+
+
+;;; Footnotes =================================================================
+
+(defun markdown-footnote-counter-inc ()
+ "Increment `markdown-footnote-counter' and return the new value."
+ (when (= markdown-footnote-counter 0) ; hasn't been updated in this buffer yet.
+ (save-excursion
+ (goto-char (point-min))
+ (while (re-search-forward (concat "^\\[\\^\\(" markdown-footnote-chars "*?\\)\\]:")
+ (point-max) t)
+ (let ((fn (string-to-number (match-string 1))))
+ (when (> fn markdown-footnote-counter)
+ (setq markdown-footnote-counter fn))))))
+ (cl-incf markdown-footnote-counter))
+
+(defun markdown-insert-footnote ()
+ "Insert footnote with a new number and move point to footnote definition."
+ (interactive)
+ (let ((fn (markdown-footnote-counter-inc)))
+ (insert (format "[^%d]" fn))
+ (markdown-footnote-text-find-new-location)
+ (markdown-ensure-blank-line-before)
+ (unless (markdown-cur-line-blank-p)
+ (insert "\n"))
+ (insert (format "[^%d]: " fn))
+ (markdown-ensure-blank-line-after)))
+
+(defun markdown-footnote-text-find-new-location ()
+ "Position the point at the proper location for a new footnote text."
+ (cond
+ ((eq markdown-footnote-location 'end) (goto-char (point-max)))
+ ((eq markdown-footnote-location 'immediately) (markdown-end-of-text-block))
+ ((eq markdown-footnote-location 'subtree) (markdown-end-of-subtree))
+ ((eq markdown-footnote-location 'header) (markdown-end-of-defun))))
+
+(defun markdown-footnote-kill ()
+ "Kill the footnote at point.
+The footnote text is killed (and added to the kill ring), the
+footnote marker is deleted. Point has to be either at the
+footnote marker or in the footnote text."
+ (interactive)
+ (let ((marker-pos nil)
+ (skip-deleting-marker nil)
+ (starting-footnote-text-positions
+ (markdown-footnote-text-positions)))
+ (when starting-footnote-text-positions
+ ;; We're starting in footnote text, so mark our return position and jump
+ ;; to the marker if possible.
+ (let ((marker-pos (markdown-footnote-find-marker
+ (cl-first starting-footnote-text-positions))))
+ (if marker-pos
+ (goto-char (1- marker-pos))
+ ;; If there isn't a marker, we still want to kill the text.
+ (setq skip-deleting-marker t))))
+ ;; Either we didn't start in the text, or we started in the text and jumped
+ ;; to the marker. We want to assume we're at the marker now and error if
+ ;; we're not.
+ (unless skip-deleting-marker
+ (let ((marker (markdown-footnote-delete-marker)))
+ (unless marker
+ (error "Not at a footnote"))
+ ;; Even if we knew the text position before, it changed when we deleted
+ ;; the label.
+ (setq marker-pos (cl-second marker))
+ (let ((new-text-pos (markdown-footnote-find-text (cl-first marker))))
+ (unless new-text-pos
+ (error "No text for footnote `%s'" (cl-first marker)))
+ (goto-char new-text-pos))))
+ (let ((pos (markdown-footnote-kill-text)))
+ (goto-char (if starting-footnote-text-positions
+ pos
+ marker-pos)))))
+
+(defun markdown-footnote-delete-marker ()
+ "Delete a footnote marker at point.
+Returns a list (ID START) containing the footnote ID and the
+start position of the marker before deletion. If no footnote
+marker was deleted, this function returns NIL."
+ (let ((marker (markdown-footnote-marker-positions)))
+ (when marker
+ (delete-region (cl-second marker) (cl-third marker))
+ (butlast marker))))
+
+(defun markdown-footnote-kill-text ()
+ "Kill footnote text at point.
+Returns the start position of the footnote text before deletion,
+or NIL if point was not inside a footnote text.
+
+The killed text is placed in the kill ring (without the footnote
+number)."
+ (let ((fn (markdown-footnote-text-positions)))
+ (when fn
+ (let ((text (delete-and-extract-region (cl-second fn) (cl-third fn))))
+ (string-match (concat "\\[\\" (cl-first fn) "\\]:[[:space:]]*\\(\\(.*\n?\\)*\\)") text)
+ (kill-new (match-string 1 text))
+ (when (and (markdown-cur-line-blank-p)
+ (markdown-prev-line-blank-p)
+ (not (bobp)))
+ (delete-region (1- (point)) (point)))
+ (cl-second fn)))))
+
+(defun markdown-footnote-goto-text ()
+ "Jump to the text of the footnote at point."
+ (interactive)
+ (let ((fn (car (markdown-footnote-marker-positions))))
+ (unless fn
+ (user-error "Not at a footnote marker"))
+ (let ((new-pos (markdown-footnote-find-text fn)))
+ (unless new-pos
+ (error "No definition found for footnote `%s'" fn))
+ (goto-char new-pos))))
+
+(defun markdown-footnote-return ()
+ "Return from a footnote to its footnote number in the main text."
+ (interactive)
+ (let ((fn (save-excursion
+ (car (markdown-footnote-text-positions)))))
+ (unless fn
+ (user-error "Not in a footnote"))
+ (let ((new-pos (markdown-footnote-find-marker fn)))
+ (unless new-pos
+ (error "Footnote marker `%s' not found" fn))
+ (goto-char new-pos))))
+
+(defun markdown-footnote-find-marker (id)
+ "Find the location of the footnote marker with ID.
+The actual buffer position returned is the position directly
+following the marker's closing bracket. If no marker is found,
+NIL is returned."
+ (save-excursion
+ (goto-char (point-min))
+ (when (re-search-forward (concat "\\[" id "\\]\\([^:]\\|\\'\\)") nil t)
+ (skip-chars-backward "^]")
+ (point))))
+
+(defun markdown-footnote-find-text (id)
+ "Find the location of the text of footnote ID.
+The actual buffer position returned is the position of the first
+character of the text, after the footnote's identifier. If no
+footnote text is found, NIL is returned."
+ (save-excursion
+ (goto-char (point-min))
+ (when (re-search-forward (concat "^ \\{0,3\\}\\[" id "\\]:") nil t)
+ (skip-chars-forward "[ \t]")
+ (point))))
+
+(defun markdown-footnote-marker-positions ()
+ "Return the position and ID of the footnote marker point is on.
+The return value is a list (ID START END). If point is not on a
+footnote, NIL is returned."
+ ;; first make sure we're at a footnote marker
+ (if (or (looking-back (concat "\\[\\^" markdown-footnote-chars "*\\]?") (line-beginning-position))
+ (looking-at-p (concat "\\[?\\^" markdown-footnote-chars "*?\\]")))
+ (save-excursion
+ ;; move point between [ and ^:
+ (if (looking-at-p "\\[")
+ (forward-char 1)
+ (skip-chars-backward "^["))
+ (looking-at (concat "\\(\\^" markdown-footnote-chars "*?\\)\\]"))
+ (list (match-string 1) (1- (match-beginning 1)) (1+ (match-end 1))))))
+
+(defun markdown-footnote-text-positions ()
+ "Return the start and end positions of the footnote text point is in.
+The exact return value is a list of three elements: (ID START END).
+The start position is the position of the opening bracket
+of the footnote id. The end position is directly after the
+newline that ends the footnote. If point is not in a footnote,
+NIL is returned instead."
+ (save-excursion
+ (let (result)
+ (move-beginning-of-line 1)
+ ;; Try to find the label. If we haven't found the label and we're at a blank
+ ;; or indented line, back up if possible.
+ (while (and
+ (not (and (looking-at markdown-regex-footnote-definition)
+ (setq result (list (match-string 1) (point)))))
+ (and (not (bobp))
+ (or (markdown-cur-line-blank-p)
+ (>= (current-indentation) 4))))
+ (forward-line -1))
+ (when result
+ ;; Advance if there is a next line that is either blank or indented.
+ ;; (Need to check if we're on the last line, because
+ ;; markdown-next-line-blank-p returns true for last line in buffer.)
+ (while (and (/= (line-end-position) (point-max))
+ (or (markdown-next-line-blank-p)
+ (>= (markdown-next-line-indent) 4)))
+ (forward-line))
+ ;; Move back while the current line is blank.
+ (while (markdown-cur-line-blank-p)
+ (forward-line -1))
+ ;; Advance to capture this line and a single trailing newline (if there
+ ;; is one).
+ (forward-line)
+ (append result (list (point)))))))
+
+(defun markdown-get-defined-footnotes ()
+ "Return a list of all defined footnotes.
+Result is an alist of pairs (MARKER . LINE), where MARKER is the
+footnote marker, a string, and LINE is the line number containing
+the footnote definition.
+
+For example, suppose the following footnotes are defined at positions
+448 and 475:
+
+\[^1]: First footnote here.
+\[^marker]: Second footnote.
+
+Then the returned list is: ((\"^1\" . 478) (\"^marker\" . 475))"
+ (save-excursion
+ (goto-char (point-min))
+ (let (footnotes)
+ (while (markdown-search-until-condition
+ (lambda () (and (not (markdown-code-block-at-point-p))
+ (not (markdown-inline-code-at-point-p))
+ (not (markdown-in-comment-p))))
+ markdown-regex-footnote-definition nil t)
+ (let ((marker (match-string-no-properties 1))
+ (pos (match-beginning 0)))
+ (unless (zerop (length marker))
+ (cl-pushnew (cons marker pos) footnotes :test #'equal))))
+ (reverse footnotes))))
+
+
+;;; Element Removal ===========================================================
+
+(defun markdown-kill-thing-at-point ()
+ "Kill thing at point and add important text, without markup, to kill ring.
+Possible things to kill include (roughly in order of precedence):
+inline code, headers, horizontal rules, links (add link text to
+kill ring), images (add alt text to kill ring), angle uri, email
+addresses, bold, italics, reference definition (add URI to kill
+ring), footnote markers and text (kill both marker and text, add
+text to kill ring), and list items."
+ (interactive "*")
+ (let (val)
+ (cond
+ ;; Inline code
+ ((markdown-inline-code-at-point)
+ (kill-new (match-string 2))
+ (delete-region (match-beginning 0) (match-end 0)))
+ ;; ATX header
+ ((thing-at-point-looking-at markdown-regex-header-atx)
+ (kill-new (match-string 2))
+ (delete-region (match-beginning 0) (match-end 0)))
+ ;; Setext header
+ ((thing-at-point-looking-at markdown-regex-header-setext)
+ (kill-new (match-string 1))
+ (delete-region (match-beginning 0) (match-end 0)))
+ ;; Horizontal rule
+ ((thing-at-point-looking-at markdown-regex-hr)
+ (kill-new (match-string 0))
+ (delete-region (match-beginning 0) (match-end 0)))
+ ;; Inline link or image (add link or alt text to kill ring)
+ ((thing-at-point-looking-at markdown-regex-link-inline)
+ (kill-new (match-string 3))
+ (delete-region (match-beginning 0) (match-end 0)))
+ ;; Reference link or image (add link or alt text to kill ring)
+ ((thing-at-point-looking-at markdown-regex-link-reference)
+ (kill-new (match-string 3))
+ (delete-region (match-beginning 0) (match-end 0)))
+ ;; Angle URI (add URL to kill ring)
+ ((thing-at-point-looking-at markdown-regex-angle-uri)
+ (kill-new (match-string 2))
+ (delete-region (match-beginning 0) (match-end 0)))
+ ;; Email address in angle brackets (add email address to kill ring)
+ ((thing-at-point-looking-at markdown-regex-email)
+ (kill-new (match-string 1))
+ (delete-region (match-beginning 0) (match-end 0)))
+ ;; Wiki link (add alias text to kill ring)
+ ((and markdown-enable-wiki-links
+ (thing-at-point-looking-at markdown-regex-wiki-link))
+ (kill-new (markdown-wiki-link-alias))
+ (delete-region (match-beginning 1) (match-end 1)))
+ ;; Bold
+ ((thing-at-point-looking-at markdown-regex-bold)
+ (kill-new (match-string 4))
+ (delete-region (match-beginning 2) (match-end 2)))
+ ;; Italics
+ ((thing-at-point-looking-at markdown-regex-italic)
+ (kill-new (match-string 3))
+ (delete-region (match-beginning 1) (match-end 1)))
+ ;; Strikethrough
+ ((thing-at-point-looking-at markdown-regex-strike-through)
+ (kill-new (match-string 4))
+ (delete-region (match-beginning 2) (match-end 2)))
+ ;; Footnote marker (add footnote text to kill ring)
+ ((thing-at-point-looking-at markdown-regex-footnote)
+ (markdown-footnote-kill))
+ ;; Footnote text (add footnote text to kill ring)
+ ((setq val (markdown-footnote-text-positions))
+ (markdown-footnote-kill))
+ ;; Reference definition (add URL to kill ring)
+ ((thing-at-point-looking-at markdown-regex-reference-definition)
+ (kill-new (match-string 5))
+ (delete-region (match-beginning 0) (match-end 0)))
+ ;; List item
+ ((setq val (markdown-cur-list-item-bounds))
+ (kill-new (delete-and-extract-region (cl-first val) (cl-second val))))
+ (t
+ (user-error "Nothing found at point to kill")))))
+
+(defun markdown-kill-outline ()
+ "Kill visible heading and add it to `kill-ring'."
+ (interactive)
+ (save-excursion
+ (markdown-outline-previous)
+ (kill-region (point) (progn (markdown-outline-next) (point)))))
+
+(defun markdown-kill-block ()
+ "Kill visible code block, list item, or blockquote and add it to `kill-ring'."
+ (interactive)
+ (save-excursion
+ (markdown-backward-block)
+ (kill-region (point) (progn (markdown-forward-block) (point)))))
+
+
+;;; Indentation ===============================================================
+
+(defun markdown-indent-find-next-position (cur-pos positions)
+ "Return the position after the index of CUR-POS in POSITIONS.
+Positions are calculated by `markdown-calc-indents'."
+ (while (and positions
+ (not (equal cur-pos (car positions))))
+ (setq positions (cdr positions)))
+ (or (cadr positions) 0))
+
+(defun markdown-outdent-find-next-position (cur-pos positions)
+ "Return the maximal element that precedes CUR-POS from POSITIONS.
+Positions are calculated by `markdown-calc-indents'."
+ (let ((result 0))
+ (dolist (i positions)
+ (when (< i cur-pos)
+ (setq result (max result i))))
+ result))
+
+(defun markdown-indent-line ()
+ "Indent the current line using some heuristics.
+If the _previous_ command was either `markdown-enter-key' or
+`markdown-cycle', then we should cycle to the next
+reasonable indentation position. Otherwise, we could have been
+called directly by `markdown-enter-key', by an initial call of
+`markdown-cycle', or indirectly by `auto-fill-mode'. In
+these cases, indent to the default position.
+Positions are calculated by `markdown-calc-indents'."
+ (interactive)
+ (let ((positions (markdown-calc-indents))
+ (point-pos (current-column))
+ (_ (back-to-indentation))
+ (cur-pos (current-column)))
+ (if (not (equal this-command 'markdown-cycle))
+ (indent-line-to (car positions))
+ (setq positions (sort (delete-dups positions) '<))
+ (let* ((next-pos (markdown-indent-find-next-position cur-pos positions))
+ (new-point-pos (max (+ point-pos (- next-pos cur-pos)) 0)))
+ (indent-line-to next-pos)
+ (move-to-column new-point-pos)))))
+
+(defun markdown-calc-indents ()
+ "Return a list of indentation columns to cycle through.
+The first element in the returned list should be considered the
+default indentation level. This function does not worry about
+duplicate positions, which are handled up by calling functions."
+ (let (pos prev-line-pos positions)
+
+ ;; Indentation of previous line
+ (setq prev-line-pos (markdown-prev-line-indent))
+ (setq positions (cons prev-line-pos positions))
+
+ ;; Indentation of previous non-list-marker text
+ (when (setq pos (save-excursion
+ (forward-line -1)
+ (when (looking-at markdown-regex-list)
+ (- (match-end 3) (match-beginning 0)))))
+ (setq positions (cons pos positions)))
+
+ ;; Indentation required for a pre block in current context
+ (setq pos (length (markdown-pre-indentation (point))))
+ (setq positions (cons pos positions))
+
+ ;; Indentation of the previous line + tab-width
+ (if prev-line-pos
+ (setq positions (cons (+ prev-line-pos tab-width) positions))
+ (setq positions (cons tab-width positions)))
+
+ ;; Indentation of the previous line - tab-width
+ (if (and prev-line-pos (> prev-line-pos tab-width))
+ (setq positions (cons (- prev-line-pos tab-width) positions)))
+
+ ;; Indentation of all preceding list markers (when in a list)
+ (when (setq pos (markdown-calculate-list-levels))
+ (setq positions (append pos positions)))
+
+ ;; First column
+ (setq positions (cons 0 positions))
+
+ ;; Return reversed list
+ (reverse positions)))
+
+(defun markdown-enter-key () ;FIXME: Partly obsoleted by electric-indent
+ "Handle RET depending on the context.
+If the point is at a table, move to the next row. Otherwise,
+indent according to value of `markdown-indent-on-enter'.
+When it is nil, simply call `newline'. Otherwise, indent the next line
+following RET using `markdown-indent-line'. Furthermore, when it
+is set to 'indent-and-new-item and the point is in a list item,
+start a new item with the same indentation. If the point is in an
+empty list item, remove it (so that pressing RET twice when in a
+list simply adds a blank line)."
+ (interactive)
+ (cond
+ ;; Table
+ ((markdown-table-at-point-p)
+ (call-interactively #'markdown-table-next-row))
+ ;; Indent non-table text
+ (markdown-indent-on-enter
+ (let (bounds)
+ (if (and (memq markdown-indent-on-enter '(indent-and-new-item))
+ (setq bounds (markdown-cur-list-item-bounds)))
+ (let ((beg (cl-first bounds))
+ (end (cl-second bounds))
+ (length (cl-fourth bounds)))
+ ;; Point is in a list item
+ (if (= (- end beg) length)
+ ;; Delete blank list
+ (progn
+ (delete-region beg end)
+ (newline)
+ (markdown-indent-line))
+ (call-interactively #'markdown-insert-list-item)))
+ ;; Point is not in a list
+ (newline)
+ (markdown-indent-line))))
+ ;; Insert a raw newline
+ (t (newline))))
+
+(defun markdown-outdent-or-delete (arg)
+ "Handle BACKSPACE by cycling through indentation points.
+When BACKSPACE is pressed, if there is only whitespace
+before the current point, then outdent the line one level.
+Otherwise, do normal delete by repeating
+`backward-delete-char-untabify' ARG times."
+ (interactive "*p")
+ (if (use-region-p)
+ (backward-delete-char-untabify arg)
+ (let ((cur-pos (current-column))
+ (start-of-indention (save-excursion
+ (back-to-indentation)
+ (current-column)))
+ (positions (markdown-calc-indents)))
+ (if (and (> cur-pos 0) (= cur-pos start-of-indention))
+ (indent-line-to (markdown-outdent-find-next-position cur-pos positions))
+ (backward-delete-char-untabify arg)))))
+
+(defun markdown-find-leftmost-column (beg end)
+ "Find the leftmost column in the region from BEG to END."
+ (let ((mincol 1000))
+ (save-excursion
+ (goto-char beg)
+ (while (< (point) end)
+ (back-to-indentation)
+ (unless (looking-at-p "[ \t]*$")
+ (setq mincol (min mincol (current-column))))
+ (forward-line 1)
+ ))
+ mincol))
+
+(defun markdown-indent-region (beg end arg)
+ "Indent the region from BEG to END using some heuristics.
+When ARG is non-nil, outdent the region instead.
+See `markdown-indent-line' and `markdown-indent-line'."
+ (interactive "*r\nP")
+ (let* ((positions (sort (delete-dups (markdown-calc-indents)) '<))
+ (leftmostcol (markdown-find-leftmost-column beg end))
+ (next-pos (if arg
+ (markdown-outdent-find-next-position leftmostcol positions)
+ (markdown-indent-find-next-position leftmostcol positions))))
+ (indent-rigidly beg end (- next-pos leftmostcol))
+ (setq deactivate-mark nil)))
+
+(defun markdown-outdent-region (beg end)
+ "Call `markdown-indent-region' on region from BEG to END with prefix."
+ (interactive "*r")
+ (markdown-indent-region beg end t))
+
+(defun markdown--indent-region (start end)
+ (let ((deactivate-mark nil))
+ (save-excursion
+ (goto-char end)
+ (setq end (point-marker))
+ (goto-char start)
+ (when (bolp)
+ (forward-line 1))
+ (while (< (point) end)
+ (unless (or (markdown-code-block-at-point-p) (and (bolp) (eolp)))
+ (indent-according-to-mode))
+ (forward-line 1))
+ (move-marker end nil))))
+
+
+;;; Markup Completion =========================================================
+
+(defconst markdown-complete-alist
+ '((markdown-regex-header-atx . markdown-complete-atx)
+ (markdown-regex-header-setext . markdown-complete-setext)
+ (markdown-regex-hr . markdown-complete-hr))
+ "Association list of form (regexp . function) for markup completion.")
+
+(defun markdown-incomplete-atx-p ()
+ "Return t if ATX header markup is incomplete and nil otherwise.
+Assumes match data is available for `markdown-regex-header-atx'.
+Checks that the number of trailing hash marks equals the number of leading
+hash marks, that there is only a single space before and after the text,
+and that there is no extraneous whitespace in the text."
+ (or
+ ;; Number of starting and ending hash marks differs
+ (not (= (length (match-string 1)) (length (match-string 3))))
+ ;; When the header text is not empty...
+ (and (> (length (match-string 2)) 0)
+ ;; ...if there are extra leading, trailing, or interior spaces
+ (or (not (= (match-beginning 2) (1+ (match-end 1))))
+ (not (= (match-beginning 3) (1+ (match-end 2))))
+ (string-match-p "[ \t\n]\\{2\\}" (match-string 2))))
+ ;; When the header text is empty...
+ (and (= (length (match-string 2)) 0)
+ ;; ...if there are too many or too few spaces
+ (not (= (match-beginning 3) (+ (match-end 1) 2))))))
+
+(defun markdown-complete-atx ()
+ "Complete and normalize ATX headers.
+Add or remove hash marks to the end of the header to match the
+beginning. Ensure that there is only a single space between hash
+marks and header text. Removes extraneous whitespace from header text.
+Assumes match data is available for `markdown-regex-header-atx'.
+Return nil if markup was complete and non-nil if markup was completed."
+ (when (markdown-incomplete-atx-p)
+ (let* ((new-marker (make-marker))
+ (new-marker (set-marker new-marker (match-end 2))))
+ ;; Hash marks and spacing at end
+ (goto-char (match-end 2))
+ (delete-region (match-end 2) (match-end 3))
+ (insert " " (match-string 1))
+ ;; Remove extraneous whitespace from title
+ (replace-match (markdown-compress-whitespace-string (match-string 2))
+ t t nil 2)
+ ;; Spacing at beginning
+ (goto-char (match-end 1))
+ (delete-region (match-end 1) (match-beginning 2))
+ (insert " ")
+ ;; Leave point at end of text
+ (goto-char new-marker))))
+
+(defun markdown-incomplete-setext-p ()
+ "Return t if setext header markup is incomplete and nil otherwise.
+Assumes match data is available for `markdown-regex-header-setext'.
+Checks that length of underline matches text and that there is no
+extraneous whitespace in the text."
+ (or (not (= (length (match-string 1)) (length (match-string 2))))
+ (string-match-p "[ \t\n]\\{2\\}" (match-string 1))))
+
+(defun markdown-complete-setext ()
+ "Complete and normalize setext headers.
+Add or remove underline characters to match length of header
+text. Removes extraneous whitespace from header text. Assumes
+match data is available for `markdown-regex-header-setext'.
+Return nil if markup was complete and non-nil if markup was completed."
+ (when (markdown-incomplete-setext-p)
+ (let* ((text (markdown-compress-whitespace-string (match-string 1)))
+ (char (char-after (match-beginning 2)))
+ (level (if (char-equal char ?-) 2 1)))
+ (goto-char (match-beginning 0))
+ (delete-region (match-beginning 0) (match-end 0))
+ (markdown-insert-header level text t)
+ t)))
+
+(defun markdown-incomplete-hr-p ()
+ "Return non-nil if hr is not in `markdown-hr-strings' and nil otherwise.
+Assumes match data is available for `markdown-regex-hr'."
+ (not (member (match-string 0) markdown-hr-strings)))
+
+(defun markdown-complete-hr ()
+ "Complete horizontal rules.
+If horizontal rule string is a member of `markdown-hr-strings',
+do nothing. Otherwise, replace with the car of
+`markdown-hr-strings'.
+Assumes match data is available for `markdown-regex-hr'.
+Return nil if markup was complete and non-nil if markup was completed."
+ (when (markdown-incomplete-hr-p)
+ (replace-match (car markdown-hr-strings))
+ t))
+
+(defun markdown-complete ()
+ "Complete markup of object near point or in region when active.
+Handle all objects in `markdown-complete-alist', in order.
+See `markdown-complete-at-point' and `markdown-complete-region'."
+ (interactive "*")
+ (if (use-region-p)
+ (markdown-complete-region (region-beginning) (region-end))
+ (markdown-complete-at-point)))
+
+(defun markdown-complete-at-point ()
+ "Complete markup of object near point.
+Handle all elements of `markdown-complete-alist' in order."
+ (interactive "*")
+ (let ((list markdown-complete-alist) found changed)
+ (while list
+ (let ((regexp (eval (caar list) t)) ;FIXME: Why `eval'?
+ (function (cdar list)))
+ (setq list (cdr list))
+ (when (thing-at-point-looking-at regexp)
+ (setq found t)
+ (setq changed (funcall function))
+ (setq list nil))))
+ (if found
+ (or changed (user-error "Markup at point is complete"))
+ (user-error "Nothing to complete at point"))))
+
+(defun markdown-complete-region (beg end)
+ "Complete markup of objects in region from BEG to END.
+Handle all objects in `markdown-complete-alist', in order. Each
+match is checked to ensure that a previous regexp does not also
+match."
+ (interactive "*r")
+ (let ((end-marker (set-marker (make-marker) end))
+ previous)
+ (dolist (element markdown-complete-alist)
+ (let ((regexp (eval (car element) t)) ;FIXME: Why `eval'?
+ (function (cdr element)))
+ (goto-char beg)
+ (while (re-search-forward regexp end-marker 'limit)
+ (when (match-string 0)
+ ;; Make sure this is not a match for any of the preceding regexps.
+ ;; This prevents mistaking an HR for a Setext subheading.
+ (let (match)
+ (save-match-data
+ (dolist (prev-regexp previous)
+ (or match (setq match (looking-back prev-regexp nil)))))
+ (unless match
+ (save-excursion (funcall function))))))
+ (cl-pushnew regexp previous :test #'equal)))
+ previous))
+
+(defun markdown-complete-buffer ()
+ "Complete markup for all objects in the current buffer."
+ (interactive "*")
+ (markdown-complete-region (point-min) (point-max)))
+
+
+;;; Markup Cycling ============================================================
+
+(defun markdown-cycle-atx (arg &optional remove)
+ "Cycle ATX header markup.
+Promote header (decrease level) when ARG is 1 and demote
+header (increase level) if arg is -1. When REMOVE is non-nil,
+remove the header when the level reaches zero and stop cycling
+when it reaches six. Otherwise, perform a proper cycling through
+levels one through six. Assumes match data is available for
+`markdown-regex-header-atx'."
+ (let* ((old-level (length (match-string 1)))
+ (new-level (+ old-level arg))
+ (text (match-string 2)))
+ (when (not remove)
+ (setq new-level (% new-level 6))
+ (setq new-level (cond ((= new-level 0) 6)
+ ((< new-level 0) (+ new-level 6))
+ (t new-level))))
+ (cond
+ ((= new-level 0)
+ (markdown-unwrap-thing-at-point nil 0 2))
+ ((<= new-level 6)
+ (goto-char (match-beginning 0))
+ (delete-region (match-beginning 0) (match-end 0))
+ (markdown-insert-header new-level text nil)))))
+
+(defun markdown-cycle-setext (arg &optional remove)
+ "Cycle setext header markup.
+Promote header (increase level) when ARG is 1 and demote
+header (decrease level or remove) if arg is -1. When demoting a
+level-two setext header, replace with a level-three atx header.
+When REMOVE is non-nil, remove the header when the level reaches
+zero. Otherwise, cycle back to a level six atx header. Assumes
+match data is available for `markdown-regex-header-setext'."
+ (let* ((char (char-after (match-beginning 2)))
+ (old-level (if (char-equal char ?=) 1 2))
+ (new-level (+ old-level arg)))
+ (when (and (not remove) (= new-level 0))
+ (setq new-level 6))
+ (cond
+ ((= new-level 0)
+ (markdown-unwrap-thing-at-point nil 0 1))
+ ((<= new-level 2)
+ (markdown-insert-header new-level nil t))
+ ((<= new-level 6)
+ (markdown-insert-header new-level nil nil)))))
+
+(defun markdown-cycle-hr (arg &optional remove)
+ "Cycle string used for horizontal rule from `markdown-hr-strings'.
+When ARG is 1, cycle forward (demote), and when ARG is -1, cycle
+backwards (promote). When REMOVE is non-nil, remove the hr instead
+of cycling when the end of the list is reached.
+Assumes match data is available for `markdown-regex-hr'."
+ (let* ((strings (if (= arg -1)
+ (reverse markdown-hr-strings)
+ markdown-hr-strings))
+ (tail (member (match-string 0) strings))
+ (new (or (cadr tail)
+ (if remove
+ (if (= arg 1)
+ ""
+ (car tail))
+ (car strings)))))
+ (replace-match new)))
+
+(defun markdown-cycle-bold ()
+ "Cycle bold markup between underscores and asterisks.
+Assumes match data is available for `markdown-regex-bold'."
+ (save-excursion
+ (let* ((old-delim (match-string 3))
+ (new-delim (if (string-equal old-delim "**") "__" "**")))
+ (replace-match new-delim t t nil 3)
+ (replace-match new-delim t t nil 5))))
+
+(defun markdown-cycle-italic ()
+ "Cycle italic markup between underscores and asterisks.
+Assumes match data is available for `markdown-regex-italic'."
+ (save-excursion
+ (let* ((old-delim (match-string 2))
+ (new-delim (if (string-equal old-delim "*") "_" "*")))
+ (replace-match new-delim t t nil 2)
+ (replace-match new-delim t t nil 4))))
+
+
+;;; Keymap ====================================================================
+
+(defun markdown--style-map-prompt ()
+ "Return a formatted prompt for Markdown markup insertion."
+ (when markdown-enable-prefix-prompts
+ (concat
+ "Markdown: "
+ (propertize "bold" 'face 'markdown-bold-face) ", "
+ (propertize "italic" 'face 'markdown-italic-face) ", "
+ (propertize "code" 'face 'markdown-inline-code-face) ", "
+ (propertize "C = GFM code" 'face 'markdown-code-face) ", "
+ (propertize "pre" 'face 'markdown-pre-face) ", "
+ (propertize "footnote" 'face 'markdown-footnote-text-face) ", "
+ (propertize "F = foldable" 'face 'markdown-bold-face) ", "
+ (propertize "q = blockquote" 'face 'markdown-blockquote-face) ", "
+ (propertize "h & 1-6 = heading" 'face 'markdown-header-face) ", "
+ (propertize "- = hr" 'face 'markdown-hr-face) ", "
+ "C-h = more")))
+
+(defun markdown--command-map-prompt ()
+ "Return prompt for Markdown buffer-wide commands."
+ (when markdown-enable-prefix-prompts
+ (concat
+ "Command: "
+ (propertize "m" 'face 'markdown-bold-face) "arkdown, "
+ (propertize "p" 'face 'markdown-bold-face) "review, "
+ (propertize "o" 'face 'markdown-bold-face) "pen, "
+ (propertize "e" 'face 'markdown-bold-face) "xport, "
+ "export & pre" (propertize "v" 'face 'markdown-bold-face) "iew, "
+ (propertize "c" 'face 'markdown-bold-face) "heck refs, "
+ (propertize "u" 'face 'markdown-bold-face) "nused refs, "
+ "C-h = more")))
+
+(defvar markdown-mode-style-map
+ (let ((map (make-keymap (markdown--style-map-prompt))))
+ (define-key map (kbd "1") 'markdown-insert-header-atx-1)
+ (define-key map (kbd "2") 'markdown-insert-header-atx-2)
+ (define-key map (kbd "3") 'markdown-insert-header-atx-3)
+ (define-key map (kbd "4") 'markdown-insert-header-atx-4)
+ (define-key map (kbd "5") 'markdown-insert-header-atx-5)
+ (define-key map (kbd "6") 'markdown-insert-header-atx-6)
+ (define-key map (kbd "!") 'markdown-insert-header-setext-1)
+ (define-key map (kbd "@") 'markdown-insert-header-setext-2)
+ (define-key map (kbd "b") 'markdown-insert-bold)
+ (define-key map (kbd "c") 'markdown-insert-code)
+ (define-key map (kbd "C") 'markdown-insert-gfm-code-block)
+ (define-key map (kbd "f") 'markdown-insert-footnote)
+ (define-key map (kbd "F") 'markdown-insert-foldable-block)
+ (define-key map (kbd "h") 'markdown-insert-header-dwim)
+ (define-key map (kbd "H") 'markdown-insert-header-setext-dwim)
+ (define-key map (kbd "i") 'markdown-insert-italic)
+ (define-key map (kbd "k") 'markdown-insert-kbd)
+ (define-key map (kbd "l") 'markdown-insert-link)
+ (define-key map (kbd "p") 'markdown-insert-pre)
+ (define-key map (kbd "P") 'markdown-pre-region)
+ (define-key map (kbd "q") 'markdown-insert-blockquote)
+ (define-key map (kbd "s") 'markdown-insert-strike-through)
+ (define-key map (kbd "t") 'markdown-insert-table)
+ (define-key map (kbd "Q") 'markdown-blockquote-region)
+ (define-key map (kbd "w") 'markdown-insert-wiki-link)
+ (define-key map (kbd "-") 'markdown-insert-hr)
+ (define-key map (kbd "[") 'markdown-insert-gfm-checkbox)
+ ;; Deprecated keys that may be removed in a future version
+ (define-key map (kbd "e") 'markdown-insert-italic)
+ map)
+ "Keymap for Markdown text styling commands.")
+
+(defvar markdown-mode-command-map
+ (let ((map (make-keymap (markdown--command-map-prompt))))
+ (define-key map (kbd "m") 'markdown-other-window)
+ (define-key map (kbd "p") 'markdown-preview)
+ (define-key map (kbd "e") 'markdown-export)
+ (define-key map (kbd "v") 'markdown-export-and-preview)
+ (define-key map (kbd "o") 'markdown-open)
+ (define-key map (kbd "l") 'markdown-live-preview-mode)
+ (define-key map (kbd "w") 'markdown-kill-ring-save)
+ (define-key map (kbd "c") 'markdown-check-refs)
+ (define-key map (kbd "u") 'markdown-unused-refs)
+ (define-key map (kbd "n") 'markdown-cleanup-list-numbers)
+ (define-key map (kbd "]") 'markdown-complete-buffer)
+ (define-key map (kbd "^") 'markdown-table-sort-lines)
+ (define-key map (kbd "|") 'markdown-table-convert-region)
+ (define-key map (kbd "t") 'markdown-table-transpose)
+ map)
+ "Keymap for Markdown buffer-wide commands.")
+
+(defvar markdown-mode-map
+ (let ((map (make-keymap)))
+ ;; Markup insertion & removal
+ (define-key map (kbd "C-c C-s") markdown-mode-style-map)
+ (define-key map (kbd "C-c C-l") 'markdown-insert-link)
+ (define-key map (kbd "C-c C-k") 'markdown-kill-thing-at-point)
+ ;; Promotion, demotion, and cycling
+ (define-key map (kbd "C-c C--") 'markdown-promote)
+ (define-key map (kbd "C-c C-=") 'markdown-demote)
+ (define-key map (kbd "C-c C-]") 'markdown-complete)
+ ;; Following and doing things
+ (define-key map (kbd "C-c C-o") 'markdown-follow-thing-at-point)
+ (define-key map (kbd "C-c C-d") 'markdown-do)
+ (define-key map (kbd "C-c '") 'markdown-edit-code-block)
+ ;; Indentation
+ (define-key map (kbd "RET") 'markdown-enter-key)
+ (define-key map (kbd "DEL") 'markdown-outdent-or-delete)
+ (define-key map (kbd "C-c >") 'markdown-indent-region)
+ (define-key map (kbd "C-c <") 'markdown-outdent-region)
+ ;; Visibility cycling
+ (define-key map (kbd "TAB") 'markdown-cycle)
+ ;; S-iso-lefttab and S-tab should both be mapped to `backtab' by
+ ;; (local-)function-key-map.
+ ;;(define-key map (kbd "<S-iso-lefttab>") 'markdown-shifttab)
+ ;;(define-key map (kbd "<S-tab>") 'markdown-shifttab)
+ (define-key map (kbd "<backtab>") 'markdown-shifttab)
+ ;; Heading and list navigation
+ (define-key map (kbd "C-c C-n") 'markdown-outline-next)
+ (define-key map (kbd "C-c C-p") 'markdown-outline-previous)
+ (define-key map (kbd "C-c C-f") 'markdown-outline-next-same-level)
+ (define-key map (kbd "C-c C-b") 'markdown-outline-previous-same-level)
+ (define-key map (kbd "C-c C-u") 'markdown-outline-up)
+ ;; Buffer-wide commands
+ (define-key map (kbd "C-c C-c") markdown-mode-command-map)
+ ;; Subtree, list, and table editing
+ (define-key map (kbd "C-c <up>") 'markdown-move-up)
+ (define-key map (kbd "C-c <down>") 'markdown-move-down)
+ (define-key map (kbd "C-c <left>") 'markdown-promote)
+ (define-key map (kbd "C-c <right>") 'markdown-demote)
+ (define-key map (kbd "C-c S-<up>") 'markdown-table-delete-row)
+ (define-key map (kbd "C-c S-<down>") 'markdown-table-insert-row)
+ (define-key map (kbd "C-c S-<left>") 'markdown-table-delete-column)
+ (define-key map (kbd "C-c S-<right>") 'markdown-table-insert-column)
+ (define-key map (kbd "C-c C-M-h") 'markdown-mark-subtree)
+ (define-key map (kbd "C-x n s") 'markdown-narrow-to-subtree)
+ (define-key map (kbd "M-RET") 'markdown-insert-list-item)
+ (define-key map (kbd "C-c C-j") 'markdown-insert-list-item)
+ ;; Paragraphs (Markdown context aware)
+ (define-key map [remap backward-paragraph] 'markdown-backward-paragraph)
+ (define-key map [remap forward-paragraph] 'markdown-forward-paragraph)
+ (define-key map [remap mark-paragraph] 'markdown-mark-paragraph)
+ ;; Blocks (one or more paragraphs)
+ (define-key map (kbd "C-M-{") 'markdown-backward-block)
+ (define-key map (kbd "C-M-}") 'markdown-forward-block)
+ (define-key map (kbd "C-c M-h") 'markdown-mark-block)
+ (define-key map (kbd "C-x n b") 'markdown-narrow-to-block)
+ ;; Pages (top-level sections)
+ (define-key map [remap backward-page] 'markdown-backward-page)
+ (define-key map [remap forward-page] 'markdown-forward-page)
+ (define-key map [remap mark-page] 'markdown-mark-page)
+ (define-key map [remap narrow-to-page] 'markdown-narrow-to-page)
+ ;; Link Movement
+ (define-key map (kbd "M-n") 'markdown-next-link)
+ (define-key map (kbd "M-p") 'markdown-previous-link)
+ ;; Toggling functionality
+ (define-key map (kbd "C-c C-x C-e") 'markdown-toggle-math)
+ (define-key map (kbd "C-c C-x C-f") 'markdown-toggle-fontify-code-blocks-natively)
+ (define-key map (kbd "C-c C-x C-i") 'markdown-toggle-inline-images)
+ (define-key map (kbd "C-c C-x C-l") 'markdown-toggle-url-hiding)
+ (define-key map (kbd "C-c C-x C-m") 'markdown-toggle-markup-hiding)
+ ;; Alternative keys (in case of problems with the arrow keys)
+ (define-key map (kbd "C-c C-x u") 'markdown-move-up)
+ (define-key map (kbd "C-c C-x d") 'markdown-move-down)
+ (define-key map (kbd "C-c C-x l") 'markdown-promote)
+ (define-key map (kbd "C-c C-x r") 'markdown-demote)
+ ;; Deprecated keys that may be removed in a future version
+ (define-key map (kbd "C-c C-a L") 'markdown-insert-link) ;; C-c C-l
+ (define-key map (kbd "C-c C-a l") 'markdown-insert-link) ;; C-c C-l
+ (define-key map (kbd "C-c C-a r") 'markdown-insert-link) ;; C-c C-l
+ (define-key map (kbd "C-c C-a u") 'markdown-insert-uri) ;; C-c C-l
+ (define-key map (kbd "C-c C-a f") 'markdown-insert-footnote)
+ (define-key map (kbd "C-c C-a w") 'markdown-insert-wiki-link)
+ (define-key map (kbd "C-c C-t 1") 'markdown-insert-header-atx-1)
+ (define-key map (kbd "C-c C-t 2") 'markdown-insert-header-atx-2)
+ (define-key map (kbd "C-c C-t 3") 'markdown-insert-header-atx-3)
+ (define-key map (kbd "C-c C-t 4") 'markdown-insert-header-atx-4)
+ (define-key map (kbd "C-c C-t 5") 'markdown-insert-header-atx-5)
+ (define-key map (kbd "C-c C-t 6") 'markdown-insert-header-atx-6)
+ (define-key map (kbd "C-c C-t !") 'markdown-insert-header-setext-1)
+ (define-key map (kbd "C-c C-t @") 'markdown-insert-header-setext-2)
+ (define-key map (kbd "C-c C-t h") 'markdown-insert-header-dwim)
+ (define-key map (kbd "C-c C-t H") 'markdown-insert-header-setext-dwim)
+ (define-key map (kbd "C-c C-t s") 'markdown-insert-header-setext-2)
+ (define-key map (kbd "C-c C-t t") 'markdown-insert-header-setext-1)
+ (define-key map (kbd "C-c C-i") 'markdown-insert-image)
+ (define-key map (kbd "C-c C-x m") 'markdown-insert-list-item) ;; C-c C-j
+ (define-key map (kbd "C-c C-x C-x") 'markdown-toggle-gfm-checkbox) ;; C-c C-d
+ (define-key map (kbd "C-c -") 'markdown-insert-hr)
+ map)
+ "Keymap for Markdown major mode.")
+
+(defvar markdown-mode-mouse-map
+ (when markdown-mouse-follow-link
+ (let ((map (make-sparse-keymap)))
+ (define-key map [follow-link] 'mouse-face)
+ (define-key map [mouse-2] #'markdown-follow-thing-at-point)
+ map))
+ "Keymap for following links with mouse.")
+
+(defvar gfm-mode-map
+ (let ((map (make-sparse-keymap)))
+ (set-keymap-parent map markdown-mode-map)
+ (define-key map (kbd "C-c C-s d") 'markdown-insert-strike-through)
+ (define-key map "`" 'markdown-electric-backquote)
+ map)
+ "Keymap for `gfm-mode'.
+See also `markdown-mode-map'.")
+
+
+;;; Menu ======================================================================
+
+(easy-menu-define markdown-mode-menu markdown-mode-map
+ "Menu for Markdown mode."
+ '("Markdown"
+ "---"
+ ("Movement"
+ ["Jump" markdown-do]
+ ["Follow Link" markdown-follow-thing-at-point]
+ ["Next Link" markdown-next-link]
+ ["Previous Link" markdown-previous-link]
+ "---"
+ ["Next Heading or List Item" markdown-outline-next]
+ ["Previous Heading or List Item" markdown-outline-previous]
+ ["Next at Same Level" markdown-outline-next-same-level]
+ ["Previous at Same Level" markdown-outline-previous-same-level]
+ ["Up to Parent" markdown-outline-up]
+ "---"
+ ["Forward Paragraph" markdown-forward-paragraph]
+ ["Backward Paragraph" markdown-backward-paragraph]
+ ["Forward Block" markdown-forward-block]
+ ["Backward Block" markdown-backward-block])
+ ("Show & Hide"
+ ["Cycle Heading Visibility" markdown-cycle
+ :enable (markdown-on-heading-p)]
+ ["Cycle Heading Visibility (Global)" markdown-shifttab]
+ "---"
+ ["Narrow to Region" narrow-to-region]
+ ["Narrow to Block" markdown-narrow-to-block]
+ ["Narrow to Section" narrow-to-defun]
+ ["Narrow to Subtree" markdown-narrow-to-subtree]
+ ["Widen" widen (buffer-narrowed-p)]
+ "---"
+ ["Toggle Markup Hiding" markdown-toggle-markup-hiding
+ :keys "C-c C-x C-m"
+ :style radio
+ :selected markdown-hide-markup])
+ "---"
+ ("Headings & Structure"
+ ["Automatic Heading" markdown-insert-header-dwim
+ :keys "C-c C-s h"]
+ ["Automatic Heading (Setext)" markdown-insert-header-setext-dwim
+ :keys "C-c C-s H"]
+ ("Specific Heading (atx)"
+ ["First Level atx" markdown-insert-header-atx-1
+ :keys "C-c C-s 1"]
+ ["Second Level atx" markdown-insert-header-atx-2
+ :keys "C-c C-s 2"]
+ ["Third Level atx" markdown-insert-header-atx-3
+ :keys "C-c C-s 3"]
+ ["Fourth Level atx" markdown-insert-header-atx-4
+ :keys "C-c C-s 4"]
+ ["Fifth Level atx" markdown-insert-header-atx-5
+ :keys "C-c C-s 5"]
+ ["Sixth Level atx" markdown-insert-header-atx-6
+ :keys "C-c C-s 6"])
+ ("Specific Heading (Setext)"
+ ["First Level Setext" markdown-insert-header-setext-1
+ :keys "C-c C-s !"]
+ ["Second Level Setext" markdown-insert-header-setext-2
+ :keys "C-c C-s @"])
+ ["Horizontal Rule" markdown-insert-hr
+ :keys "C-c C-s -"]
+ "---"
+ ["Move Subtree Up" markdown-move-up
+ :keys "C-c <up>"]
+ ["Move Subtree Down" markdown-move-down
+ :keys "C-c <down>"]
+ ["Promote Subtree" markdown-promote
+ :keys "C-c <left>"]
+ ["Demote Subtree" markdown-demote
+ :keys "C-c <right>"])
+ ("Region & Mark"
+ ["Indent Region" markdown-indent-region]
+ ["Outdent Region" markdown-outdent-region]
+ "--"
+ ["Mark Paragraph" mark-paragraph]
+ ["Mark Block" markdown-mark-block]
+ ["Mark Section" mark-defun]
+ ["Mark Subtree" markdown-mark-subtree])
+ ("Tables"
+ ["Move Row Up" markdown-move-up
+ :enable (markdown-table-at-point-p)
+ :keys "C-c <up>"]
+ ["Move Row Down" markdown-move-down
+ :enable (markdown-table-at-point-p)
+ :keys "C-c <down>"]
+ ["Move Column Left" markdown-promote
+ :enable (markdown-table-at-point-p)
+ :keys "C-c <left>"]
+ ["Move Column Right" markdown-demote
+ :enable (markdown-table-at-point-p)
+ :keys "C-c <right>"]
+ ["Delete Row" markdown-table-delete-row
+ :enable (markdown-table-at-point-p)]
+ ["Insert Row" markdown-table-insert-row
+ :enable (markdown-table-at-point-p)]
+ ["Delete Column" markdown-table-delete-column
+ :enable (markdown-table-at-point-p)]
+ ["Insert Column" markdown-table-insert-column
+ :enable (markdown-table-at-point-p)]
+ ["Insert Table" markdown-insert-table]
+ "--"
+ ["Convert Region to Table" markdown-table-convert-region]
+ ["Sort Table Lines" markdown-table-sort-lines
+ :enable (markdown-table-at-point-p)]
+ ["Transpose Table" markdown-table-transpose
+ :enable (markdown-table-at-point-p)])
+ ("Lists"
+ ["Insert List Item" markdown-insert-list-item]
+ ["Move Subtree Up" markdown-move-up
+ :keys "C-c <up>"]
+ ["Move Subtree Down" markdown-move-down
+ :keys "C-c <down>"]
+ ["Indent Subtree" markdown-demote
+ :keys "C-c <right>"]
+ ["Outdent Subtree" markdown-promote
+ :keys "C-c <left>"]
+ ["Renumber List" markdown-cleanup-list-numbers]
+ ["Insert Task List Item" markdown-insert-gfm-checkbox
+ :keys "C-c C-x ["]
+ ["Toggle Task List Item" markdown-toggle-gfm-checkbox
+ :enable (markdown-gfm-task-list-item-at-point)
+ :keys "C-c C-d"])
+ ("Links & Images"
+ ["Insert Link" markdown-insert-link]
+ ["Insert Image" markdown-insert-image]
+ ["Insert Footnote" markdown-insert-footnote
+ :keys "C-c C-s f"]
+ ["Insert Wiki Link" markdown-insert-wiki-link
+ :keys "C-c C-s w"]
+ "---"
+ ["Check References" markdown-check-refs]
+ ["Find Unused References" markdown-unused-refs]
+ ["Toggle URL Hiding" markdown-toggle-url-hiding
+ :style radio
+ :selected markdown-hide-urls]
+ ["Toggle Inline Images" markdown-toggle-inline-images
+ :keys "C-c C-x C-i"
+ :style radio
+ :selected markdown-inline-image-overlays]
+ ["Toggle Wiki Links" markdown-toggle-wiki-links
+ :style radio
+ :selected markdown-enable-wiki-links])
+ ("Styles"
+ ["Bold" markdown-insert-bold]
+ ["Italic" markdown-insert-italic]
+ ["Code" markdown-insert-code]
+ ["Strikethrough" markdown-insert-strike-through]
+ ["Keyboard" markdown-insert-kbd]
+ "---"
+ ["Blockquote" markdown-insert-blockquote]
+ ["Preformatted" markdown-insert-pre]
+ ["GFM Code Block" markdown-insert-gfm-code-block]
+ ["Edit Code Block" markdown-edit-code-block
+ :enable (markdown-code-block-at-point-p)]
+ ["Foldable Block" markdown-insert-foldable-block]
+ "---"
+ ["Blockquote Region" markdown-blockquote-region]
+ ["Preformatted Region" markdown-pre-region]
+ "---"
+ ["Fontify Code Blocks Natively"
+ markdown-toggle-fontify-code-blocks-natively
+ :style radio
+ :selected markdown-fontify-code-blocks-natively]
+ ["LaTeX Math Support" markdown-toggle-math
+ :style radio
+ :selected markdown-enable-math])
+ "---"
+ ("Preview & Export"
+ ["Compile" markdown-other-window]
+ ["Preview" markdown-preview]
+ ["Export" markdown-export]
+ ["Export & View" markdown-export-and-preview]
+ ["Open" markdown-open]
+ ["Live Export" markdown-live-preview-mode
+ :style radio
+ :selected markdown-live-preview-mode]
+ ["Kill ring save" markdown-kill-ring-save])
+ ("Markup Completion and Cycling"
+ ["Complete Markup" markdown-complete]
+ ["Promote Element" markdown-promote
+ :keys "C-c C--"]
+ ["Demote Element" markdown-demote
+ :keys "C-c C-="])
+ "---"
+ ["Kill Element" markdown-kill-thing-at-point]
+ "---"
+ ("Documentation"
+ ["Version" markdown-show-version]
+ ["Homepage" markdown-mode-info]
+ ["Describe Mode" (describe-function 'markdown-mode)]
+ ["Guide" (browse-url "https://leanpub.com/markdown-mode")])))
+
+
+;;; imenu =====================================================================
+
+(defun markdown-imenu-create-nested-index ()
+ "Create and return a nested imenu index alist for the current buffer.
+See `imenu-create-index-function' and `imenu--index-alist' for details."
+ (let* ((root '(nil . nil))
+ (min-level 9999)
+ hashes headers)
+ (save-excursion
+ ;; Headings
+ (goto-char (point-min))
+ (while (re-search-forward markdown-regex-header (point-max) t)
+ (unless (or (markdown-code-block-at-point-p)
+ (and (match-beginning 3)
+ (get-text-property (match-beginning 3) 'markdown-yaml-metadata-end)))
+ (cond
+ ((match-string-no-properties 2) ;; level 1 setext
+ (setq min-level 1)
+ (push (list :heading (match-string-no-properties 1)
+ :point (match-beginning 1)
+ :level 1) headers))
+ ((match-string-no-properties 3) ;; level 2 setext
+ (setq min-level (min min-level 2))
+ (push (list :heading (match-string-no-properties 1)
+ :point (match-beginning 1)
+ :level (- 2 (1- min-level))) headers))
+ ((setq hashes (markdown-trim-whitespace
+ (match-string-no-properties 4)))
+ (setq min-level (min min-level (length hashes)))
+ (push (list :heading (match-string-no-properties 5)
+ :point (match-beginning 4)
+ :level (- (length hashes) (1- min-level))) headers)))))
+ (cl-loop with cur-level = 0
+ with cur-alist = nil
+ with empty-heading = "-"
+ with self-heading = "."
+ for header in (reverse headers)
+ for level = (plist-get header :level)
+ do
+ (let ((alist (list (cons (plist-get header :heading) (plist-get header :point)))))
+ (cond
+ ((= cur-level level) ; new sibling
+ (setcdr cur-alist alist)
+ (setq cur-alist alist))
+ ((< cur-level level) ; first child
+ (dotimes (_ (- level cur-level 1))
+ (setq alist (list (cons empty-heading alist))))
+ (if cur-alist
+ (let* ((parent (car cur-alist))
+ (self-pos (cdr parent)))
+ (setcdr parent (cons (cons self-heading self-pos) alist)))
+ (setcdr root alist)) ; primogenitor
+ (setq cur-alist alist)
+ (setq cur-level level))
+ (t ; new sibling of an ancestor
+ (let ((sibling-alist (last (cdr root))))
+ (dotimes (_ (1- level))
+ (setq sibling-alist (last (cdar sibling-alist))))
+ (setcdr sibling-alist alist)
+ (setq cur-alist alist))
+ (setq cur-level level)))))
+ (setq root (copy-tree root))
+ ;; Footnotes
+ (let ((fn (markdown-get-defined-footnotes)))
+ (if (or (zerop (length fn))
+ (null markdown-add-footnotes-to-imenu))
+ (cdr root)
+ (nconc (cdr root) (list (cons "Footnotes" fn))))))))
+
+(defun markdown-imenu-create-flat-index ()
+ "Create and return a flat imenu index alist for the current buffer.
+See `imenu-create-index-function' and `imenu--index-alist' for details."
+ (let* ((empty-heading "-") index heading pos)
+ (save-excursion
+ ;; Headings
+ (goto-char (point-min))
+ (while (re-search-forward markdown-regex-header (point-max) t)
+ (when (and (not (markdown-code-block-at-point-p (point-at-bol)))
+ (not (markdown-text-property-at-point 'markdown-yaml-metadata-begin)))
+ (cond
+ ((setq heading (match-string-no-properties 1))
+ (setq pos (match-beginning 1)))
+ ((setq heading (match-string-no-properties 5))
+ (setq pos (match-beginning 4))))
+ (or (> (length heading) 0)
+ (setq heading empty-heading))
+ (setq index (append index (list (cons heading pos))))))
+ ;; Footnotes
+ (when markdown-add-footnotes-to-imenu
+ (nconc index (markdown-get-defined-footnotes)))
+ index)))
+
+
+;;; References ================================================================
+
+(defun markdown-reference-goto-definition ()
+ "Jump to the definition of the reference at point or create it."
+ (interactive)
+ (when (thing-at-point-looking-at markdown-regex-link-reference)
+ (let* ((text (match-string-no-properties 3))
+ (reference (match-string-no-properties 6))
+ (target (downcase (if (string= reference "") text reference)))
+ (loc (cadr (save-match-data (markdown-reference-definition target)))))
+ (if loc
+ (goto-char loc)
+ (goto-char (match-beginning 0))
+ (markdown-insert-reference-definition target)))))
+
+(defun markdown-reference-find-links (reference)
+ "Return a list of all links for REFERENCE.
+REFERENCE should not include the surrounding square brackets.
+Elements of the list have the form (text start line), where
+text is the link text, start is the location at the beginning of
+the link, and line is the line number on which the link appears."
+ (let* ((ref-quote (regexp-quote reference))
+ (regexp (format "!?\\(?:\\[\\(%s\\)\\][ ]?\\[\\]\\|\\[\\([^]]+?\\)\\][ ]?\\[%s\\]\\)"
+ ref-quote ref-quote))
+ links)
+ (save-excursion
+ (goto-char (point-min))
+ (while (re-search-forward regexp nil t)
+ (let* ((text (or (match-string-no-properties 1)
+ (match-string-no-properties 2)))
+ (start (match-beginning 0))
+ (line (markdown-line-number-at-pos)))
+ (cl-pushnew (list text start line) links :test #'equal))))
+ links))
+
+(defmacro markdown-for-all-refs (f)
+ `(let ((result))
+ (save-excursion
+ (goto-char (point-min))
+ (while
+ (re-search-forward markdown-regex-link-reference nil t)
+ (let* ((text (match-string-no-properties 3))
+ (reference (match-string-no-properties 6))
+ (target (downcase (if (string= reference "") text reference))))
+ (,f text target result))))
+ (reverse result)))
+
+(defmacro markdown-collect-always (_ target result)
+ `(cl-pushnew ,target ,result :test #'equal))
+
+(defmacro markdown-collect-undefined (text target result)
+ `(unless (markdown-reference-definition target)
+ (let ((entry (assoc ,target ,result)))
+ (if (not entry)
+ (cl-pushnew
+ (cons ,target (list (cons ,text (markdown-line-number-at-pos))))
+ ,result :test #'equal)
+ (setcdr entry
+ (append (cdr entry) (list (cons ,text (markdown-line-number-at-pos)))))))))
+
+(defun markdown-get-all-refs ()
+ "Return a list of all Markdown references."
+ (markdown-for-all-refs markdown-collect-always))
+
+(defun markdown-get-undefined-refs ()
+ "Return a list of undefined Markdown references.
+Result is an alist of pairs (reference . occurrences), where
+occurrences is itself another alist of pairs (label . line-number).
+For example, an alist corresponding to [Nice editor][Emacs] at line 12,
+\[GNU Emacs][Emacs] at line 45 and [manual][elisp] at line 127 is
+\((\"emacs\" (\"Nice editor\" . 12) (\"GNU Emacs\" . 45)) (\"elisp\" (\"manual\" . 127)))."
+ (markdown-for-all-refs markdown-collect-undefined))
+
+(defun markdown-get-unused-refs ()
+ (cl-sort
+ (cl-set-difference
+ (markdown-get-defined-references) (markdown-get-all-refs)
+ :test (lambda (e1 e2) (equal (car e1) e2)))
+ #'< :key #'cdr))
+
+(defmacro defun-markdown-buffer (name docstring)
+ "Define a function to name and return a buffer.
+
+By convention, NAME must be a name of a string constant with
+%buffer% placeholder used to name the buffer, and will also be
+used as a name of the function defined.
+
+DOCSTRING will be used as the first part of the docstring."
+ `(defun ,name (&optional buffer-name)
+ ,(concat docstring "\n\nBUFFER-NAME is the name of the main buffer being visited.")
+ (or buffer-name (setq buffer-name (buffer-name)))
+ (let ((refbuf (get-buffer-create (replace-regexp-in-string
+ "%buffer%" buffer-name
+ ,name))))
+ (with-current-buffer refbuf
+ (when view-mode
+ (View-exit-and-edit))
+ (use-local-map button-buffer-map)
+ (erase-buffer))
+ refbuf)))
+
+(defconst markdown-reference-check-buffer
+ "*Undefined references for %buffer%*"
+ "Pattern for name of buffer for listing undefined references.
+The string %buffer% will be replaced by the corresponding
+`markdown-mode' buffer name.")
+
+(defun-markdown-buffer
+ markdown-reference-check-buffer
+ "Name and return buffer for reference checking.")
+
+(defconst markdown-unused-references-buffer
+ "*Unused references for %buffer%*"
+ "Pattern for name of buffer for listing unused references.
+The string %buffer% will be replaced by the corresponding
+`markdown-mode' buffer name.")
+
+(defun-markdown-buffer
+ markdown-unused-references-buffer
+ "Name and return buffer for unused reference checking.")
+
+(defconst markdown-reference-links-buffer
+ "*Reference links for %buffer%*"
+ "Pattern for name of buffer for listing references.
+The string %buffer% will be replaced by the corresponding buffer name.")
+
+(defun-markdown-buffer
+ markdown-reference-links-buffer
+ "Name, setup, and return a buffer for listing links.")
+
+;; Add an empty Markdown reference definition to buffer
+;; specified in the 'target-buffer property. The reference name is
+;; the button's label.
+(define-button-type 'markdown-undefined-reference-button
+ 'help-echo "mouse-1, RET: create definition for undefined reference"
+ 'follow-link t
+ 'face 'bold
+ 'action (lambda (b)
+ (let ((buffer (button-get b 'target-buffer))
+ (line (button-get b 'target-line))
+ (label (button-label b)))
+ (switch-to-buffer-other-window buffer)
+ (goto-char (point-min))
+ (forward-line line)
+ (markdown-insert-reference-definition label)
+ (markdown-check-refs t))))
+
+;; Jump to line in buffer specified by 'target-buffer property.
+;; Line number is button's 'target-line property.
+(define-button-type 'markdown-goto-line-button
+ 'help-echo "mouse-1, RET: go to line"
+ 'follow-link t
+ 'face 'italic
+ 'action (lambda (b)
+ (switch-to-buffer-other-window (button-get b 'target-buffer))
+ ;; use call-interactively to silence compiler
+ (let ((current-prefix-arg (button-get b 'target-line)))
+ (call-interactively 'goto-line))))
+
+;; Kill a line in buffer specified by 'target-buffer property.
+;; Line number is button's 'target-line property.
+(define-button-type 'markdown-kill-line-button
+ 'help-echo "mouse-1, RET: kill line"
+ 'follow-link t
+ 'face 'italic
+ 'action (lambda (b)
+ (switch-to-buffer-other-window (button-get b 'target-buffer))
+ ;; use call-interactively to silence compiler
+ (let ((current-prefix-arg (button-get b 'target-line)))
+ (call-interactively 'goto-line))
+ (kill-line 1)
+ (markdown-unused-refs t)))
+
+;; Jumps to a particular link at location given by 'target-char
+;; property in buffer given by 'target-buffer property.
+(define-button-type 'markdown-location-button
+ 'help-echo "mouse-1, RET: jump to location of link"
+ 'follow-link t
+ 'face 'bold
+ 'action (lambda (b)
+ (let ((target (button-get b 'target-buffer))
+ (loc (button-get b 'target-char)))
+ (kill-buffer-and-window)
+ (switch-to-buffer target)
+ (goto-char loc))))
+
+(defun markdown-insert-undefined-reference-button (reference oldbuf)
+ "Insert a button for creating REFERENCE in buffer OLDBUF.
+REFERENCE should be a list of the form (reference . occurrences),
+as returned by `markdown-get-undefined-refs'."
+ (let ((label (car reference)))
+ ;; Create a reference button
+ (insert-button label
+ :type 'markdown-undefined-reference-button
+ 'target-buffer oldbuf
+ 'target-line (cdr (car (cdr reference))))
+ (insert " (")
+ (dolist (occurrence (cdr reference))
+ (let ((line (cdr occurrence)))
+ ;; Create a line number button
+ (insert-button (number-to-string line)
+ :type 'markdown-goto-line-button
+ 'target-buffer oldbuf
+ 'target-line line)
+ (insert " ")))
+ (delete-char -1)
+ (insert ")")
+ (newline)))
+
+(defun markdown-insert-unused-reference-button (reference oldbuf)
+ "Insert a button for creating REFERENCE in buffer OLDBUF.
+REFERENCE must be a pair of (ref . line-number)."
+ (let ((label (car reference))
+ (line (cdr reference)))
+ ;; Create a reference button
+ (insert-button label
+ :type 'markdown-goto-line-button
+ 'face 'bold
+ 'target-buffer oldbuf
+ 'target-line line)
+ (insert (format " (%d) [" line))
+ (insert-button "X"
+ :type 'markdown-kill-line-button
+ 'face 'bold
+ 'target-buffer oldbuf
+ 'target-line line)
+ (insert "]")
+ (newline)))
+
+(defun markdown-insert-link-button (link oldbuf)
+ "Insert a button for jumping to LINK in buffer OLDBUF.
+LINK should be a list of the form (text char line) containing
+the link text, location, and line number."
+ (let ((label (cl-first link))
+ (char (cl-second link))
+ (line (cl-third link)))
+ ;; Create a reference button
+ (insert-button label
+ :type 'markdown-location-button
+ 'target-buffer oldbuf
+ 'target-char char)
+ (insert (format " (line %d)\n" line))))
+
+(defun markdown-reference-goto-link (&optional reference)
+ "Jump to the location of the first use of REFERENCE."
+ (interactive)
+ (unless reference
+ (if (thing-at-point-looking-at markdown-regex-reference-definition)
+ (setq reference (match-string-no-properties 2))
+ (user-error "No reference definition at point")))
+ (let ((links (markdown-reference-find-links reference)))
+ (cond ((= (length links) 1)
+ (goto-char (cadr (car links))))
+ ((> (length links) 1)
+ (let ((oldbuf (current-buffer))
+ (linkbuf (markdown-reference-links-buffer)))
+ (with-current-buffer linkbuf
+ (insert "Links using reference " reference ":\n\n")
+ (dolist (link (reverse links))
+ (markdown-insert-link-button link oldbuf)))
+ (view-buffer-other-window linkbuf)
+ (goto-char (point-min))
+ (forward-line 2)))
+ (t
+ (error "No links for reference %s" reference)))))
+
+(defmacro defun-markdown-ref-checker
+ (name docstring checker-function buffer-function none-message buffer-header insert-reference)
+ "Define a function NAME acting on result of CHECKER-FUNCTION.
+
+DOCSTRING is used as a docstring for the defined function.
+
+BUFFER-FUNCTION should name and return an auxiliary buffer to put
+results in.
+
+NONE-MESSAGE is used when CHECKER-FUNCTION returns no results.
+
+BUFFER-HEADER is put into the auxiliary buffer first, followed by
+calling INSERT-REFERENCE for each element in the list returned by
+CHECKER-FUNCTION."
+ `(defun ,name (&optional silent)
+ ,(concat
+ docstring
+ "\n\nIf SILENT is non-nil, do not message anything when no
+such references found.")
+ (interactive "P")
+ (unless (derived-mode-p 'markdown-mode)
+ (user-error "Not available in current mode"))
+ (let ((oldbuf (current-buffer))
+ (refs (,checker-function))
+ (refbuf (,buffer-function)))
+ (if (null refs)
+ (progn
+ (when (not silent)
+ (message ,none-message))
+ (kill-buffer refbuf))
+ (with-current-buffer refbuf
+ (insert ,buffer-header)
+ (dolist (ref refs)
+ (,insert-reference ref oldbuf))
+ (view-buffer-other-window refbuf)
+ (goto-char (point-min))
+ (forward-line 2))))))
+
+(defun-markdown-ref-checker
+ markdown-check-refs
+ "Show all undefined Markdown references in current `markdown-mode' buffer.
+
+Links which have empty reference definitions are considered to be
+defined."
+ markdown-get-undefined-refs
+ markdown-reference-check-buffer
+ "No undefined references found"
+ "The following references are undefined:\n\n"
+ markdown-insert-undefined-reference-button)
+
+
+(defun-markdown-ref-checker
+ markdown-unused-refs
+ "Show all unused Markdown references in current `markdown-mode' buffer."
+ markdown-get-unused-refs
+ markdown-unused-references-buffer
+ "No unused references found"
+ "The following references are unused:\n\n"
+ markdown-insert-unused-reference-button)
+
+
+
+;;; Lists =====================================================================
+
+(defun markdown-insert-list-item (&optional arg)
+ "Insert a new list item.
+If the point is inside unordered list, insert a bullet mark. If
+the point is inside ordered list, insert the next number followed
+by a period. Use the previous list item to determine the amount
+of whitespace to place before and after list markers.
+
+With a \\[universal-argument] prefix (i.e., when ARG is (4)),
+decrease the indentation by one level.
+
+With two \\[universal-argument] prefixes (i.e., when ARG is (16)),
+increase the indentation by one level."
+ (interactive "p")
+ (let (bounds cur-indent marker indent new-indent new-loc)
+ (save-match-data
+ ;; Look for a list item on current or previous non-blank line
+ (save-excursion
+ (while (and (not (setq bounds (markdown-cur-list-item-bounds)))
+ (not (bobp))
+ (markdown-cur-line-blank-p))
+ (forward-line -1)))
+ (when bounds
+ (cond ((save-excursion
+ (skip-chars-backward " \t")
+ (looking-at-p markdown-regex-list))
+ (beginning-of-line)
+ (insert "\n")
+ (forward-line -1))
+ ((not (markdown-cur-line-blank-p))
+ (newline)))
+ (setq new-loc (point)))
+ ;; Look ahead for a list item on next non-blank line
+ (unless bounds
+ (save-excursion
+ (while (and (null bounds)
+ (not (eobp))
+ (markdown-cur-line-blank-p))
+ (forward-line)
+ (setq bounds (markdown-cur-list-item-bounds))))
+ (when bounds
+ (setq new-loc (point))
+ (unless (markdown-cur-line-blank-p)
+ (newline))))
+ (if (not bounds)
+ ;; When not in a list, start a new unordered one
+ (progn
+ (unless (markdown-cur-line-blank-p)
+ (insert "\n"))
+ (insert markdown-unordered-list-item-prefix))
+ ;; Compute indentation and marker for new list item
+ (setq cur-indent (nth 2 bounds))
+ (setq marker (nth 4 bounds))
+ ;; If current item is a GFM checkbox, insert new unchecked checkbox.
+ (when (nth 5 bounds)
+ (setq marker
+ (concat marker
+ (replace-regexp-in-string "[Xx]" " " (nth 5 bounds)))))
+ (cond
+ ;; Dedent: decrement indentation, find previous marker.
+ ((= arg 4)
+ (setq indent (max (- cur-indent markdown-list-indent-width) 0))
+ (let ((prev-bounds
+ (save-excursion
+ (goto-char (nth 0 bounds))
+ (when (markdown-up-list)
+ (markdown-cur-list-item-bounds)))))
+ (when prev-bounds
+ (setq marker (nth 4 prev-bounds)))))
+ ;; Indent: increment indentation by 4, use same marker.
+ ((= arg 16) (setq indent (+ cur-indent markdown-list-indent-width)))
+ ;; Same level: keep current indentation and marker.
+ (t (setq indent cur-indent)))
+ (setq new-indent (make-string indent 32))
+ (goto-char new-loc)
+ (cond
+ ;; Ordered list
+ ((string-match-p "[0-9]" marker)
+ (if (= arg 16) ;; starting a new column indented one more level
+ (insert (concat new-indent "1. "))
+ ;; Don't use previous match-data
+ (set-match-data nil)
+ ;; travel up to the last item and pick the correct number. If
+ ;; the argument was nil, "new-indent = cur-indent" is the same,
+ ;; so we don't need special treatment. Neat.
+ (save-excursion
+ (while (and (not (looking-at (concat new-indent "\\([0-9]+\\)\\(\\.[ \t]*\\)")))
+ (>= (forward-line -1) 0))))
+ (let* ((old-prefix (match-string 1))
+ (old-spacing (match-string 2))
+ (new-prefix (if (and old-prefix markdown-ordered-list-enumeration)
+ (int-to-string (1+ (string-to-number old-prefix)))
+ "1"))
+ (space-adjust (- (length old-prefix) (length new-prefix)))
+ (new-spacing (if (and (match-string 2)
+ (not (string-match-p "\t" old-spacing))
+ (< space-adjust 0)
+ (> space-adjust (- 1 (length (match-string 2)))))
+ (substring (match-string 2) 0 space-adjust)
+ (or old-spacing ". "))))
+ (insert (concat new-indent new-prefix new-spacing)))))
+ ;; Unordered list, GFM task list, or ordered list with hash mark
+ ((string-match-p "[\\*\\+-]\\|#\\." marker)
+ (insert new-indent marker))))
+ ;; Propertize the newly inserted list item now
+ (markdown-syntax-propertize-list-items (point-at-bol) (point-at-eol)))))
+
+(defun markdown-move-list-item-up ()
+ "Move the current list item up in the list when possible.
+In nested lists, move child items with the parent item."
+ (interactive)
+ (let (cur prev old)
+ (when (setq cur (markdown-cur-list-item-bounds))
+ (setq old (point))
+ (goto-char (nth 0 cur))
+ (if (markdown-prev-list-item (nth 3 cur))
+ (progn
+ (setq prev (markdown-cur-list-item-bounds))
+ (condition-case nil
+ (progn
+ (transpose-regions (nth 0 prev) (nth 1 prev)
+ (nth 0 cur) (nth 1 cur) t)
+ (goto-char (+ (nth 0 prev) (- old (nth 0 cur)))))
+ ;; Catch error in case regions overlap.
+ (error (goto-char old))))
+ (goto-char old)))))
+
+(defun markdown-move-list-item-down ()
+ "Move the current list item down in the list when possible.
+In nested lists, move child items with the parent item."
+ (interactive)
+ (let (cur next old)
+ (when (setq cur (markdown-cur-list-item-bounds))
+ (setq old (point))
+ (if (markdown-next-list-item (nth 3 cur))
+ (progn
+ (setq next (markdown-cur-list-item-bounds))
+ (condition-case nil
+ (progn
+ (transpose-regions (nth 0 cur) (nth 1 cur)
+ (nth 0 next) (nth 1 next) nil)
+ (goto-char (+ old (- (nth 1 next) (nth 1 cur)))))
+ ;; Catch error in case regions overlap.
+ (error (goto-char old))))
+ (goto-char old)))))
+
+(defun markdown-demote-list-item (&optional bounds)
+ "Indent (or demote) the current list item.
+Optionally, BOUNDS of the current list item may be provided if available.
+In nested lists, demote child items as well."
+ (interactive)
+ (when (or bounds (setq bounds (markdown-cur-list-item-bounds)))
+ (save-excursion
+ (let* ((item-start (set-marker (make-marker) (nth 0 bounds)))
+ (item-end (set-marker (make-marker) (nth 1 bounds)))
+ (list-start (progn (markdown-beginning-of-list)
+ (set-marker (make-marker) (point))))
+ (list-end (progn (markdown-end-of-list)
+ (set-marker (make-marker) (point)))))
+ (goto-char item-start)
+ (while (< (point) item-end)
+ (unless (markdown-cur-line-blank-p)
+ (insert (make-string markdown-list-indent-width ? )))
+ (forward-line))
+ (markdown-syntax-propertize-list-items list-start list-end)))))
+
+(defun markdown-promote-list-item (&optional bounds)
+ "Unindent (or promote) the current list item.
+Optionally, BOUNDS of the current list item may be provided if available.
+In nested lists, demote child items as well."
+ (interactive)
+ (when (or bounds (setq bounds (markdown-cur-list-item-bounds)))
+ (save-excursion
+ (save-match-data
+ (let ((item-start (set-marker (make-marker) (nth 0 bounds)))
+ (item-end (set-marker (make-marker) (nth 1 bounds)))
+ (list-start (progn (markdown-beginning-of-list)
+ (set-marker (make-marker) (point))))
+ (list-end (progn (markdown-end-of-list)
+ (set-marker (make-marker) (point))))
+ num regexp)
+ (goto-char item-start)
+ (when (looking-at (format "^[ ]\\{1,%d\\}"
+ markdown-list-indent-width))
+ (setq num (- (match-end 0) (match-beginning 0)))
+ (setq regexp (format "^[ ]\\{1,%d\\}" num))
+ (while (and (< (point) item-end)
+ (re-search-forward regexp item-end t))
+ (replace-match "" nil nil)
+ (forward-line))
+ (markdown-syntax-propertize-list-items list-start list-end)))))))
+
+(defun markdown-cleanup-list-numbers-level (&optional pfx prev-item)
+ "Update the numbering for level PFX (as a string of spaces) and PREV-ITEM.
+PREV-ITEM is width of previous-indentation and list number
+
+Assume that the previously found match was for a numbered item in
+a list."
+ (let ((cpfx pfx)
+ (cur-item nil)
+ (idx 0)
+ (continue t)
+ (step t)
+ (sep nil))
+ (while (and continue (not (eobp)))
+ (setq step t)
+ (cond
+ ((looking-at "^\\(\\([\s-]*\\)[0-9]+\\)\\. ")
+ (setq cpfx (match-string-no-properties 2))
+ (setq cur-item (match-string-no-properties 1)) ;; indentation and list marker
+ (cond
+ ((or (= (length cpfx) (length pfx))
+ (= (length cur-item) (length prev-item)))
+ (save-excursion
+ (replace-match
+ (if (not markdown-ordered-list-enumeration)
+ (concat pfx "1. ")
+ (cl-incf idx)
+ (concat pfx (number-to-string idx) ". "))))
+ (setq sep nil))
+ ;; indented a level
+ ((< (length pfx) (length cpfx))
+ (setq sep (markdown-cleanup-list-numbers-level cpfx cur-item))
+ (setq step nil))
+ ;; exit the loop
+ (t
+ (setq step nil)
+ (setq continue nil))))
+
+ ((looking-at "^\\([\s-]*\\)[^ \t\n\r].*$")
+ (setq cpfx (match-string-no-properties 1))
+ (cond
+ ;; reset if separated before
+ ((string= cpfx pfx) (when sep (setq idx 0)))
+ ((string< cpfx pfx)
+ (setq step nil)
+ (setq continue nil))))
+ (t (setq sep t)))
+
+ (when step
+ (beginning-of-line)
+ (setq continue (= (forward-line) 0))))
+ sep))
+
+(defun markdown-cleanup-list-numbers ()
+ "Update the numbering of ordered lists."
+ (interactive)
+ (save-excursion
+ (goto-char (point-min))
+ (markdown-cleanup-list-numbers-level "")))
+
+
+;;; Movement ==================================================================
+
+(defun markdown-beginning-of-defun (&optional arg)
+ "`beginning-of-defun-function' for Markdown.
+This is used to find the beginning of the defun and should behave
+like ‘beginning-of-defun’, returning non-nil if it found the
+beginning of a defun. It moves the point backward, right before a
+heading which defines a defun. When ARG is non-nil, repeat that
+many times. When ARG is negative, move forward to the ARG-th
+following section."
+ (or arg (setq arg 1))
+ (when (< arg 0) (end-of-line))
+ ;; Adjust position for setext headings.
+ (when (and (thing-at-point-looking-at markdown-regex-header-setext)
+ (not (= (point) (match-beginning 0)))
+ (not (markdown-code-block-at-point-p)))
+ (goto-char (match-end 0)))
+ (let (found)
+ ;; Move backward with positive argument.
+ (while (and (not (bobp)) (> arg 0))
+ (setq found nil)
+ (while (and (not found)
+ (not (bobp))
+ (re-search-backward markdown-regex-header nil 'move))
+ (when (not (markdown-code-block-at-pos (match-beginning 0))))
+ (setq found (match-beginning 0)))
+ (setq arg (1- arg)))
+ ;; Move forward with negative argument.
+ (while (and (not (eobp)) (< arg 0))
+ (setq found nil)
+ (while (and (not found)
+ (not (eobp))
+ (re-search-forward markdown-regex-header nil 'move))
+ (when (not (markdown-code-block-at-pos (match-beginning 0))))
+ (setq found (match-beginning 0)))
+ (setq arg (1+ arg)))
+ (when found
+ (beginning-of-line)
+ t)))
+
+(defun markdown-end-of-defun ()
+ "`end-of-defun-function’ for Markdown.
+This is used to find the end of the defun at point.
+It is called with no argument, right after calling ‘beginning-of-defun-raw’,
+so it can assume that point is at the beginning of the defun body.
+It should move point to the first position after the defun."
+ (or (eobp) (forward-char 1))
+ (let (found)
+ (while (and (not found)
+ (not (eobp))
+ (re-search-forward markdown-regex-header nil 'move))
+ (when (not (markdown-code-block-at-pos (match-beginning 0)))
+ (setq found (match-beginning 0))))
+ (when found
+ (goto-char found)
+ (skip-syntax-backward "-"))))
+
+(defun markdown-beginning-of-text-block ()
+ "Move backward to previous beginning of a plain text block.
+This function simply looks for blank lines without considering
+the surrounding context in light of Markdown syntax. For that, see
+`markdown-backward-block'."
+ (interactive)
+ (let ((start (point)))
+ (if (re-search-backward markdown-regex-block-separator nil t)
+ (goto-char (match-end 0))
+ (goto-char (point-min)))
+ (when (and (= start (point)) (not (bobp)))
+ (forward-line -1)
+ (if (re-search-backward markdown-regex-block-separator nil t)
+ (goto-char (match-end 0))
+ (goto-char (point-min))))))
+
+(defun markdown-end-of-text-block ()
+ "Move forward to next beginning of a plain text block.
+This function simply looks for blank lines without considering
+the surrounding context in light of Markdown syntax. For that, see
+`markdown-forward-block'."
+ (interactive)
+ (beginning-of-line)
+ (skip-chars-forward " \t\n")
+ (when (= (point) (point-min))
+ (forward-char))
+ (if (re-search-forward markdown-regex-block-separator nil t)
+ (goto-char (match-end 0))
+ (goto-char (point-max)))
+ (skip-chars-backward " \t\n")
+ (forward-line))
+
+(defun markdown-backward-paragraph (&optional arg)
+ "Move the point to the start of the current paragraph.
+With argument ARG, do it ARG times; a negative argument ARG = -N
+means move forward N blocks."
+ (interactive "^p")
+ (or arg (setq arg 1))
+ (if (< arg 0)
+ (markdown-forward-paragraph (- arg))
+ (dotimes (_ arg)
+ ;; Skip over whitespace in between paragraphs when moving backward.
+ (skip-chars-backward " \t\n")
+ (beginning-of-line)
+ ;; Skip over code block endings.
+ (when (markdown-range-properties-exist
+ (point-at-bol) (point-at-eol)
+ '(markdown-gfm-block-end
+ markdown-tilde-fence-end))
+ (forward-line -1))
+ ;; Skip over blank lines inside blockquotes.
+ (while (and (not (eobp))
+ (looking-at markdown-regex-blockquote)
+ (= (length (match-string 3)) 0))
+ (forward-line -1))
+ ;; Proceed forward based on the type of block of paragraph.
+ (let (bounds skip)
+ (cond
+ ;; Blockquotes
+ ((looking-at markdown-regex-blockquote)
+ (while (and (not (bobp))
+ (looking-at markdown-regex-blockquote)
+ (> (length (match-string 3)) 0)) ;; not blank
+ (forward-line -1))
+ (forward-line))
+ ;; List items
+ ((setq bounds (markdown-cur-list-item-bounds))
+ (goto-char (nth 0 bounds)))
+ ;; Other
+ (t
+ (while (and (not (bobp))
+ (not skip)
+ (not (markdown-cur-line-blank-p))
+ (not (looking-at markdown-regex-blockquote))
+ (not (markdown-range-properties-exist
+ (point-at-bol) (point-at-eol)
+ '(markdown-gfm-block-end
+ markdown-tilde-fence-end))))
+ (setq skip (markdown-range-properties-exist
+ (point-at-bol) (point-at-eol)
+ '(markdown-gfm-block-begin
+ markdown-tilde-fence-begin)))
+ (forward-line -1))
+ (unless (bobp)
+ (forward-line 1))))))))
+
+(defun markdown-forward-paragraph (&optional arg)
+ "Move forward to the next end of a paragraph.
+With argument ARG, do it ARG times; a negative argument ARG = -N
+means move backward N blocks."
+ (interactive "^p")
+ (or arg (setq arg 1))
+ (if (< arg 0)
+ (markdown-backward-paragraph (- arg))
+ (dotimes (_ arg)
+ ;; Skip whitespace in between paragraphs.
+ (when (markdown-cur-line-blank-p)
+ (skip-syntax-forward "-")
+ (beginning-of-line))
+ ;; Proceed forward based on the type of block.
+ (let (bounds skip)
+ (cond
+ ;; Blockquotes
+ ((looking-at markdown-regex-blockquote)
+ ;; Skip over blank lines inside blockquotes.
+ (while (and (not (eobp))
+ (looking-at markdown-regex-blockquote)
+ (= (length (match-string 3)) 0))
+ (forward-line))
+ ;; Move to end of quoted text block
+ (while (and (not (eobp))
+ (looking-at markdown-regex-blockquote)
+ (> (length (match-string 3)) 0)) ;; not blank
+ (forward-line)))
+ ;; List items
+ ((and (markdown-cur-list-item-bounds)
+ (setq bounds (markdown-next-list-item-bounds)))
+ (goto-char (nth 0 bounds)))
+ ;; Other
+ (t
+ (forward-line)
+ (while (and (not (eobp))
+ (not skip)
+ (not (markdown-cur-line-blank-p))
+ (not (looking-at markdown-regex-blockquote))
+ (not (markdown-range-properties-exist
+ (point-at-bol) (point-at-eol)
+ '(markdown-gfm-block-begin
+ markdown-tilde-fence-begin))))
+ (setq skip (markdown-range-properties-exist
+ (point-at-bol) (point-at-eol)
+ '(markdown-gfm-block-end
+ markdown-tilde-fence-end)))
+ (forward-line))))))))
+
+(defun markdown-backward-block (&optional arg)
+ "Move the point to the start of the current Markdown block.
+Moves across complete code blocks, list items, and blockquotes,
+but otherwise stops at blank lines, headers, and horizontal
+rules. With argument ARG, do it ARG times; a negative argument
+ARG = -N means move forward N blocks."
+ (interactive "^p")
+ (or arg (setq arg 1))
+ (if (< arg 0)
+ (markdown-forward-block (- arg))
+ (dotimes (_ arg)
+ ;; Skip over whitespace in between blocks when moving backward,
+ ;; unless at a block boundary with no whitespace.
+ (skip-syntax-backward "-")
+ (beginning-of-line)
+ ;; Proceed forward based on the type of block.
+ (cond
+ ;; Code blocks
+ ((and (markdown-code-block-at-pos (point)) ;; this line
+ (markdown-code-block-at-pos (point-at-bol 0))) ;; previous line
+ (forward-line -1)
+ (while (and (markdown-code-block-at-point-p) (not (bobp)))
+ (forward-line -1))
+ (forward-line))
+ ;; Headings
+ ((markdown-heading-at-point)
+ (goto-char (match-beginning 0)))
+ ;; Horizontal rules
+ ((looking-at markdown-regex-hr))
+ ;; Blockquotes
+ ((looking-at markdown-regex-blockquote)
+ (forward-line -1)
+ (while (and (looking-at markdown-regex-blockquote)
+ (not (bobp)))
+ (forward-line -1))
+ (forward-line))
+ ;; List items
+ ((markdown-cur-list-item-bounds)
+ (markdown-beginning-of-list))
+ ;; Other
+ (t
+ ;; Move forward in case it is a one line regular paragraph.
+ (unless (markdown-next-line-blank-p)
+ (forward-line))
+ (unless (markdown-prev-line-blank-p)
+ (markdown-backward-paragraph)))))))
+
+(defun markdown-forward-block (&optional arg)
+ "Move forward to the next end of a Markdown block.
+Moves across complete code blocks, list items, and blockquotes,
+but otherwise stops at blank lines, headers, and horizontal
+rules. With argument ARG, do it ARG times; a negative argument
+ARG = -N means move backward N blocks."
+ (interactive "^p")
+ (or arg (setq arg 1))
+ (if (< arg 0)
+ (markdown-backward-block (- arg))
+ (dotimes (_ arg)
+ ;; Skip over whitespace in between blocks when moving forward.
+ (if (markdown-cur-line-blank-p)
+ (skip-syntax-forward "-")
+ (beginning-of-line))
+ ;; Proceed forward based on the type of block.
+ (cond
+ ;; Code blocks
+ ((markdown-code-block-at-point-p)
+ (forward-line)
+ (while (and (markdown-code-block-at-point-p) (not (eobp)))
+ (forward-line)))
+ ;; Headings
+ ((looking-at markdown-regex-header)
+ (goto-char (or (match-end 4) (match-end 2) (match-end 3)))
+ (forward-line))
+ ;; Horizontal rules
+ ((looking-at markdown-regex-hr)
+ (forward-line))
+ ;; Blockquotes
+ ((looking-at markdown-regex-blockquote)
+ (forward-line)
+ (while (and (looking-at markdown-regex-blockquote) (not (eobp)))
+ (forward-line)))
+ ;; List items
+ ((markdown-cur-list-item-bounds)
+ (markdown-end-of-list)
+ (forward-line))
+ ;; Other
+ (t (markdown-forward-paragraph))))
+ (skip-syntax-backward "-")
+ (unless (eobp)
+ (forward-char 1))))
+
+(defun markdown-backward-page (&optional count)
+ "Move backward to boundary of the current toplevel section.
+With COUNT, repeat, or go forward if negative."
+ (interactive "p")
+ (or count (setq count 1))
+ (if (< count 0)
+ (markdown-forward-page (- count))
+ (skip-syntax-backward "-")
+ (or (markdown-back-to-heading-over-code-block t t)
+ (goto-char (point-min)))
+ (when (looking-at markdown-regex-header)
+ (let ((level (markdown-outline-level)))
+ (when (> level 1) (markdown-up-heading level))
+ (when (> count 1)
+ (condition-case nil
+ (markdown-backward-same-level (1- count))
+ (error (goto-char (point-min)))))))))
+
+(defun markdown-forward-page (&optional count)
+ "Move forward to boundary of the current toplevel section.
+With COUNT, repeat, or go backward if negative."
+ (interactive "p")
+ (or count (setq count 1))
+ (if (< count 0)
+ (markdown-backward-page (- count))
+ (if (markdown-back-to-heading-over-code-block t t)
+ (let ((level (markdown-outline-level)))
+ (when (> level 1) (markdown-up-heading level))
+ (condition-case nil
+ (markdown-forward-same-level count)
+ (error (goto-char (point-max)))))
+ (markdown-next-visible-heading 1))))
+
+(defun markdown-next-link ()
+ "Jump to next inline, reference, or wiki link.
+If successful, return point. Otherwise, return nil.
+See `markdown-wiki-link-p' and `markdown-previous-wiki-link'."
+ (interactive)
+ (let ((opoint (point)))
+ (when (or (markdown-link-p) (markdown-wiki-link-p))
+ ;; At a link already, move past it.
+ (goto-char (+ (match-end 0) 1)))
+ ;; Search for the next wiki link and move to the beginning.
+ (while (and (re-search-forward (markdown-make-regex-link-generic) nil t)
+ (markdown-code-block-at-point-p)
+ (< (point) (point-max))))
+ (if (and (not (eq (point) opoint))
+ (or (markdown-link-p) (markdown-wiki-link-p)))
+ ;; Group 1 will move past non-escape character in wiki link regexp.
+ ;; Go to beginning of group zero for all other link types.
+ (goto-char (or (match-beginning 1) (match-beginning 0)))
+ (goto-char opoint)
+ nil)))
+
+(defun markdown-previous-link ()
+ "Jump to previous wiki link.
+If successful, return point. Otherwise, return nil.
+See `markdown-wiki-link-p' and `markdown-next-wiki-link'."
+ (interactive)
+ (let ((opoint (point)))
+ (while (and (re-search-backward (markdown-make-regex-link-generic) nil t)
+ (markdown-code-block-at-point-p)
+ (> (point) (point-min))))
+ (if (and (not (eq (point) opoint))
+ (or (markdown-link-p) (markdown-wiki-link-p)))
+ (goto-char (or (match-beginning 1) (match-beginning 0)))
+ (goto-char opoint)
+ nil)))
+
+
+;;; Outline ===================================================================
+
+(defun markdown-move-heading-common (move-fn &optional arg adjust)
+ "Wrapper for `outline-mode' functions to skip false positives.
+MOVE-FN is a function and ARG is its argument. For example,
+headings inside preformatted code blocks may match
+`outline-regexp' but should not be considered as headings.
+When ADJUST is non-nil, adjust the point for interactive calls
+to avoid leaving the point at invisible markup. This adjustment
+generally should only be done for interactive calls, since other
+functions may expect the point to be at the beginning of the
+regular expression."
+ (let ((prev -1) (start (point)))
+ (if arg (funcall move-fn arg) (funcall move-fn))
+ (while (and (/= prev (point)) (markdown-code-block-at-point-p))
+ (setq prev (point))
+ (if arg (funcall move-fn arg) (funcall move-fn)))
+ ;; Adjust point for setext headings and invisible text.
+ (save-match-data
+ (when (and adjust (thing-at-point-looking-at markdown-regex-header))
+ (if markdown-hide-markup
+ ;; Move to beginning of heading text if markup is hidden.
+ (goto-char (or (match-beginning 1) (match-beginning 5)))
+ ;; Move to beginning of markup otherwise.
+ (goto-char (or (match-beginning 1) (match-beginning 4))))))
+ (if (= (point) start) nil (point))))
+
+(defun markdown-next-visible-heading (arg)
+ "Move to the next visible heading line of any level.
+With argument, repeats or can move backward if negative. ARG is
+passed to `outline-next-visible-heading'."
+ (interactive "p")
+ (markdown-move-heading-common #'outline-next-visible-heading arg 'adjust))
+
+(defun markdown-previous-visible-heading (arg)
+ "Move to the previous visible heading line of any level.
+With argument, repeats or can move backward if negative. ARG is
+passed to `outline-previous-visible-heading'."
+ (interactive "p")
+ (markdown-move-heading-common #'outline-previous-visible-heading arg 'adjust))
+
+(defun markdown-next-heading ()
+ "Move to the next heading line of any level."
+ (markdown-move-heading-common #'outline-next-heading))
+
+(defun markdown-previous-heading ()
+ "Move to the previous heading line of any level."
+ (markdown-move-heading-common #'outline-previous-heading))
+
+(defun markdown-back-to-heading-over-code-block (&optional invisible-ok no-error)
+ "Move back to the beginning of the previous heading.
+Returns t if the point is at a heading, the location if a heading
+was found, and nil otherwise.
+Only visible heading lines are considered, unless INVISIBLE-OK is
+non-nil. Throw an error if there is no previous heading unless
+NO-ERROR is non-nil.
+Leaves match data intact for `markdown-regex-header'."
+ (beginning-of-line)
+ (or (and (markdown-heading-at-point)
+ (not (markdown-code-block-at-point-p)))
+ (let (found)
+ (save-excursion
+ (while (and (not found)
+ (re-search-backward markdown-regex-header nil t))
+ (when (and (or invisible-ok (not (outline-invisible-p)))
+ (not (markdown-code-block-at-point-p)))
+ (setq found (point))))
+ (if (not found)
+ (unless no-error (user-error "Before first heading"))
+ (setq found (point))))
+ (when found (goto-char found)))))
+
+(defun markdown-forward-same-level (arg)
+ "Move forward to the ARG'th heading at same level as this one.
+Stop at the first and last headings of a superior heading."
+ (interactive "p")
+ (markdown-back-to-heading-over-code-block)
+ (markdown-move-heading-common #'outline-forward-same-level arg 'adjust))
+
+(defun markdown-backward-same-level (arg)
+ "Move backward to the ARG'th heading at same level as this one.
+Stop at the first and last headings of a superior heading."
+ (interactive "p")
+ (markdown-back-to-heading-over-code-block)
+ (while (> arg 0)
+ (let ((point-to-move-to
+ (save-excursion
+ (markdown-move-heading-common #'outline-get-last-sibling nil 'adjust))))
+ (if point-to-move-to
+ (progn
+ (goto-char point-to-move-to)
+ (setq arg (1- arg)))
+ (user-error "No previous same-level heading")))))
+
+(defun markdown-up-heading (arg &optional interactive)
+ "Move to the visible heading line of which the present line is a subheading.
+With argument, move up ARG levels. When called interactively (or
+INTERACTIVE is non-nil), also push the mark."
+ (interactive "p\np")
+ (and interactive (not (eq last-command 'markdown-up-heading))
+ (push-mark))
+ (markdown-move-heading-common #'outline-up-heading arg 'adjust))
+
+(defun markdown-back-to-heading (&optional invisible-ok)
+ "Move to previous heading line, or beg of this line if it's a heading.
+Only visible heading lines are considered, unless INVISIBLE-OK is non-nil."
+ (interactive)
+ (markdown-move-heading-common #'outline-back-to-heading invisible-ok))
+
+(defalias 'markdown-end-of-heading 'outline-end-of-heading)
+
+(defun markdown-on-heading-p ()
+ "Return non-nil if point is on a heading line."
+ (get-text-property (point-at-bol) 'markdown-heading))
+
+(defun markdown-end-of-subtree (&optional invisible-OK)
+ "Move to the end of the current subtree.
+Only visible heading lines are considered, unless INVISIBLE-OK is
+non-nil.
+Derived from `org-end-of-subtree'."
+ (markdown-back-to-heading invisible-OK)
+ (let ((first t)
+ (level (markdown-outline-level)))
+ (while (and (not (eobp))
+ (or first (> (markdown-outline-level) level)))
+ (setq first nil)
+ (markdown-next-heading))
+ (if (memq (preceding-char) '(?\n ?\^M))
+ (progn
+ ;; Go to end of line before heading
+ (forward-char -1)
+ (if (memq (preceding-char) '(?\n ?\^M))
+ ;; leave blank line before heading
+ (forward-char -1)))))
+ (point))
+
+(defun markdown-outline-fix-visibility ()
+ "Hide any false positive headings that should not be shown.
+For example, headings inside preformatted code blocks may match
+`outline-regexp' but should not be shown as headings when cycling.
+Also, the ending --- line in metadata blocks appears to be a
+setext header, but should not be folded."
+ (save-excursion
+ (goto-char (point-min))
+ ;; Unhide any false positives in metadata blocks
+ (when (markdown-text-property-at-point 'markdown-yaml-metadata-begin)
+ (let ((body (progn (forward-line)
+ (markdown-text-property-at-point
+ 'markdown-yaml-metadata-section))))
+ (when body
+ (let ((end (progn (goto-char (cl-second body))
+ (markdown-text-property-at-point
+ 'markdown-yaml-metadata-end))))
+ (outline-flag-region (point-min) (1+ (cl-second end)) nil)))))
+ ;; Hide any false positives in code blocks
+ (unless (outline-on-heading-p)
+ (outline-next-visible-heading 1))
+ (while (< (point) (point-max))
+ (when (markdown-code-block-at-point-p)
+ (outline-flag-region (1- (point-at-bol)) (point-at-eol) t))
+ (outline-next-visible-heading 1))))
+
+(defvar markdown-cycle-global-status 1)
+(defvar markdown-cycle-subtree-status nil)
+
+(defun markdown-next-preface ()
+ (let (finish)
+ (while (and (not finish) (re-search-forward (concat "\n\\(?:" outline-regexp "\\)")
+ nil 'move))
+ (unless (markdown-code-block-at-point-p)
+ (goto-char (match-beginning 0))
+ (setq finish t))))
+ (when (and (bolp) (or outline-blank-line (eobp)) (not (bobp)))
+ (forward-char -1)))
+
+(defun markdown-show-entry ()
+ (save-excursion
+ (outline-back-to-heading t)
+ (outline-flag-region (1- (point))
+ (progn
+ (markdown-next-preface)
+ (if (= 1 (- (point-max) (point)))
+ (point-max)
+ (point)))
+ nil)))
+
+;; This function was originally derived from `org-cycle' from org.el.
+(defun markdown-cycle (&optional arg)
+ "Visibility cycling for Markdown mode.
+This function is called with a `\\[universal-argument]' or if ARG is t, perform
+global visibility cycling. If the point is at an atx-style header, cycle
+visibility of the corresponding subtree. Otherwise, indent the current line
+ or insert a tab, as appropriate, by calling `indent-for-tab-command'."
+ (interactive "P")
+ (cond
+
+ ;; Global cycling
+ (arg
+ (cond
+ ;; Move from overview to contents
+ ((and (eq last-command this-command)
+ (eq markdown-cycle-global-status 2))
+ (outline-hide-sublevels 1)
+ (message "CONTENTS")
+ (setq markdown-cycle-global-status 3)
+ (markdown-outline-fix-visibility))
+ ;; Move from contents to all
+ ((and (eq last-command this-command)
+ (eq markdown-cycle-global-status 3))
+ (outline-show-all)
+ (message "SHOW ALL")
+ (setq markdown-cycle-global-status 1))
+ ;; Defaults to overview
+ (t
+ (outline-hide-body)
+ (message "OVERVIEW")
+ (setq markdown-cycle-global-status 2)
+ (markdown-outline-fix-visibility))))
+
+ ;; At a heading: rotate between three different views
+ ((save-excursion (beginning-of-line 1) (markdown-on-heading-p))
+ (markdown-back-to-heading)
+ (let ((goal-column 0) eoh eol eos)
+ ;; Determine boundaries
+ (save-excursion
+ (markdown-back-to-heading)
+ (save-excursion
+ (beginning-of-line 2)
+ (while (and (not (eobp)) ;; this is like `next-line'
+ (get-char-property (1- (point)) 'invisible))
+ (beginning-of-line 2)) (setq eol (point)))
+ (markdown-end-of-heading) (setq eoh (point))
+ (markdown-end-of-subtree t)
+ (skip-chars-forward " \t\n")
+ (beginning-of-line 1) ; in case this is an item
+ (setq eos (1- (point))))
+ ;; Find out what to do next and set `this-command'
+ (cond
+ ;; Nothing is hidden behind this heading
+ ((= eos eoh)
+ (message "EMPTY ENTRY")
+ (setq markdown-cycle-subtree-status nil))
+ ;; Entire subtree is hidden in one line: open it
+ ((>= eol eos)
+ (markdown-show-entry)
+ (outline-show-children)
+ (message "CHILDREN")
+ (setq markdown-cycle-subtree-status 'children))
+ ;; We just showed the children, now show everything.
+ ((and (eq last-command this-command)
+ (eq markdown-cycle-subtree-status 'children))
+ (outline-show-subtree)
+ (message "SUBTREE")
+ (setq markdown-cycle-subtree-status 'subtree))
+ ;; Default action: hide the subtree.
+ (t
+ (outline-hide-subtree)
+ (message "FOLDED")
+ (setq markdown-cycle-subtree-status 'folded)))))
+
+ ;; In a table, move forward by one cell
+ ((markdown-table-at-point-p)
+ (call-interactively #'markdown-table-forward-cell))
+
+ ;; Otherwise, indent as appropriate
+ (t
+ (indent-for-tab-command))))
+
+(defun markdown-shifttab ()
+ "Handle S-TAB keybinding based on context.
+When in a table, move backward one cell.
+Otherwise, cycle global heading visibility by calling
+`markdown-cycle' with argument t."
+ (interactive)
+ (cond ((markdown-table-at-point-p)
+ (call-interactively #'markdown-table-backward-cell))
+ (t (markdown-cycle t))))
+
+(defun markdown-outline-level ()
+ "Return the depth to which a statement is nested in the outline."
+ (cond
+ ((and (match-beginning 0)
+ (markdown-code-block-at-pos (match-beginning 0)))
+ 7) ;; Only 6 header levels are defined.
+ ((match-end 2) 1)
+ ((match-end 3) 2)
+ ((match-end 4)
+ (length (markdown-trim-whitespace (match-string-no-properties 4))))))
+
+(defun markdown-promote-subtree (&optional arg)
+ "Promote the current subtree of ATX headings.
+Note that Markdown does not support heading levels higher than
+six and therefore level-six headings will not be promoted
+further. If ARG is non-nil promote the heading, otherwise
+demote."
+ (interactive "*P")
+ (save-excursion
+ (when (and (or (thing-at-point-looking-at markdown-regex-header-atx)
+ (re-search-backward markdown-regex-header-atx nil t))
+ (not (markdown-code-block-at-point-p)))
+ (let ((level (length (match-string 1)))
+ (promote-or-demote (if arg 1 -1))
+ (remove 't))
+ (markdown-cycle-atx promote-or-demote remove)
+ (catch 'end-of-subtree
+ (while (and (markdown-next-heading)
+ (looking-at markdown-regex-header-atx))
+ ;; Exit if this not a higher level heading; promote otherwise.
+ (if (and (looking-at markdown-regex-header-atx)
+ (<= (length (match-string-no-properties 1)) level))
+ (throw 'end-of-subtree nil)
+ (markdown-cycle-atx promote-or-demote remove))))))))
+
+(defun markdown-demote-subtree ()
+ "Demote the current subtree of ATX headings."
+ (interactive)
+ (markdown-promote-subtree t))
+
+(defun markdown-move-subtree-up ()
+ "Move the current subtree of ATX headings up."
+ (interactive)
+ (outline-move-subtree-up 1))
+
+(defun markdown-move-subtree-down ()
+ "Move the current subtree of ATX headings down."
+ (interactive)
+ (outline-move-subtree-down 1))
+
+(defun markdown-outline-next ()
+ "Move to next list item, when in a list, or next visible heading."
+ (interactive)
+ (let ((bounds (markdown-next-list-item-bounds)))
+ (if bounds
+ (goto-char (nth 0 bounds))
+ (markdown-next-visible-heading 1))))
+
+(defun markdown-outline-previous ()
+ "Move to previous list item, when in a list, or previous visible heading."
+ (interactive)
+ (let ((bounds (markdown-prev-list-item-bounds)))
+ (if bounds
+ (goto-char (nth 0 bounds))
+ (markdown-previous-visible-heading 1))))
+
+(defun markdown-outline-next-same-level ()
+ "Move to next list item or heading of same level."
+ (interactive)
+ (let ((bounds (markdown-cur-list-item-bounds)))
+ (if bounds
+ (markdown-next-list-item (nth 3 bounds))
+ (markdown-forward-same-level 1))))
+
+(defun markdown-outline-previous-same-level ()
+ "Move to previous list item or heading of same level."
+ (interactive)
+ (let ((bounds (markdown-cur-list-item-bounds)))
+ (if bounds
+ (markdown-prev-list-item (nth 3 bounds))
+ (markdown-backward-same-level 1))))
+
+(defun markdown-outline-up ()
+ "Move to previous list item, when in a list, or previous heading."
+ (interactive)
+ (unless (markdown-up-list)
+ (markdown-up-heading 1)))
+
+
+;;; Marking and Narrowing =====================================================
+
+(defun markdown-mark-paragraph ()
+ "Put mark at end of this block, point at beginning.
+The block marked is the one that contains point or follows point.
+
+Interactively, if this command is repeated or (in Transient Mark
+mode) if the mark is active, it marks the next block after the
+ones already marked."
+ (interactive)
+ (if (or (and (eq last-command this-command) (mark t))
+ (and transient-mark-mode mark-active))
+ (set-mark
+ (save-excursion
+ (goto-char (mark))
+ (markdown-forward-paragraph)
+ (point)))
+ (let ((beginning-of-defun-function #'markdown-backward-paragraph)
+ (end-of-defun-function #'markdown-forward-paragraph))
+ (mark-defun))))
+
+(defun markdown-mark-block ()
+ "Put mark at end of this block, point at beginning.
+The block marked is the one that contains point or follows point.
+
+Interactively, if this command is repeated or (in Transient Mark
+mode) if the mark is active, it marks the next block after the
+ones already marked."
+ (interactive)
+ (if (or (and (eq last-command this-command) (mark t))
+ (and transient-mark-mode mark-active))
+ (set-mark
+ (save-excursion
+ (goto-char (mark))
+ (markdown-forward-block)
+ (point)))
+ (let ((beginning-of-defun-function #'markdown-backward-block)
+ (end-of-defun-function #'markdown-forward-block))
+ (mark-defun))))
+
+(defun markdown-narrow-to-block ()
+ "Make text outside current block invisible.
+The current block is the one that contains point or follows point."
+ (interactive)
+ (let ((beginning-of-defun-function #'markdown-backward-block)
+ (end-of-defun-function #'markdown-forward-block))
+ (narrow-to-defun)))
+
+(defun markdown-mark-text-block ()
+ "Put mark at end of this plain text block, point at beginning.
+The block marked is the one that contains point or follows point.
+
+Interactively, if this command is repeated or (in Transient Mark
+mode) if the mark is active, it marks the next block after the
+ones already marked."
+ (interactive)
+ (if (or (and (eq last-command this-command) (mark t))
+ (and transient-mark-mode mark-active))
+ (set-mark
+ (save-excursion
+ (goto-char (mark))
+ (markdown-end-of-text-block)
+ (point)))
+ (let ((beginning-of-defun-function #'markdown-beginning-of-text-block)
+ (end-of-defun-function #'markdown-end-of-text-block))
+ (mark-defun))))
+
+(defun markdown-mark-page ()
+ "Put mark at end of this top level section, point at beginning.
+The top level section marked is the one that contains point or
+follows point.
+
+Interactively, if this command is repeated or (in Transient Mark
+mode) if the mark is active, it marks the next page after the
+ones already marked."
+ (interactive)
+ (if (or (and (eq last-command this-command) (mark t))
+ (and transient-mark-mode mark-active))
+ (set-mark
+ (save-excursion
+ (goto-char (mark))
+ (markdown-forward-page)
+ (point)))
+ (let ((beginning-of-defun-function #'markdown-backward-page)
+ (end-of-defun-function #'markdown-forward-page))
+ (mark-defun))))
+
+(defun markdown-narrow-to-page ()
+ "Make text outside current top level section invisible.
+The current section is the one that contains point or follows point."
+ (interactive)
+ (let ((beginning-of-defun-function #'markdown-backward-page)
+ (end-of-defun-function #'markdown-forward-page))
+ (narrow-to-defun)))
+
+(defun markdown-mark-subtree ()
+ "Mark the current subtree.
+This puts point at the start of the current subtree, and mark at the end."
+ (interactive)
+ (let ((beg))
+ (if (markdown-heading-at-point)
+ (beginning-of-line)
+ (markdown-previous-visible-heading 1))
+ (setq beg (point))
+ (markdown-end-of-subtree)
+ (push-mark (point) nil t)
+ (goto-char beg)))
+
+(defun markdown-narrow-to-subtree ()
+ "Narrow buffer to the current subtree."
+ (interactive)
+ (save-excursion
+ (save-match-data
+ (narrow-to-region
+ (progn (markdown-back-to-heading-over-code-block t) (point))
+ (progn (markdown-end-of-subtree)
+ (if (and (markdown-heading-at-point) (not (eobp)))
+ (backward-char 1))
+ (point))))))
+
+
+;;; Generic Structure Editing, Completion, and Cycling Commands ===============
+
+(defun markdown-move-up ()
+ "Move thing at point up.
+When in a list item, call `markdown-move-list-item-up'.
+When in a table, call `markdown-table-move-row-up'.
+Otherwise, move the current heading subtree up with
+`markdown-move-subtree-up'."
+ (interactive)
+ (cond
+ ((markdown-list-item-at-point-p)
+ (call-interactively #'markdown-move-list-item-up))
+ ((markdown-table-at-point-p)
+ (call-interactively #'markdown-table-move-row-up))
+ (t
+ (call-interactively #'markdown-move-subtree-up))))
+
+(defun markdown-move-down ()
+ "Move thing at point down.
+When in a list item, call `markdown-move-list-item-down'.
+Otherwise, move the current heading subtree up with
+`markdown-move-subtree-down'."
+ (interactive)
+ (cond
+ ((markdown-list-item-at-point-p)
+ (call-interactively #'markdown-move-list-item-down))
+ ((markdown-table-at-point-p)
+ (call-interactively #'markdown-table-move-row-down))
+ (t
+ (call-interactively #'markdown-move-subtree-down))))
+
+(defun markdown-promote ()
+ "Promote or move element at point to the left.
+Depending on the context, this function will promote a heading or
+list item at the point, move a table column to the left, or cycle
+markup."
+ (interactive)
+ (let (bounds)
+ (cond
+ ;; Promote atx heading subtree
+ ((thing-at-point-looking-at markdown-regex-header-atx)
+ (markdown-promote-subtree))
+ ;; Promote setext heading
+ ((thing-at-point-looking-at markdown-regex-header-setext)
+ (markdown-cycle-setext -1))
+ ;; Promote horizontal rule
+ ((thing-at-point-looking-at markdown-regex-hr)
+ (markdown-cycle-hr -1))
+ ;; Promote list item
+ ((setq bounds (markdown-cur-list-item-bounds))
+ (markdown-promote-list-item bounds))
+ ;; Move table column to the left
+ ((markdown-table-at-point-p)
+ (call-interactively #'markdown-table-move-column-left))
+ ;; Promote bold
+ ((thing-at-point-looking-at markdown-regex-bold)
+ (markdown-cycle-bold))
+ ;; Promote italic
+ ((thing-at-point-looking-at markdown-regex-italic)
+ (markdown-cycle-italic))
+ (t
+ (user-error "Nothing to promote at point")))))
+
+(defun markdown-demote ()
+ "Demote or move element at point to the right.
+Depending on the context, this function will demote a heading or
+list item at the point, move a table column to the right, or cycle
+or remove markup."
+ (interactive)
+ (let (bounds)
+ (cond
+ ;; Demote atx heading subtree
+ ((thing-at-point-looking-at markdown-regex-header-atx)
+ (markdown-demote-subtree))
+ ;; Demote setext heading
+ ((thing-at-point-looking-at markdown-regex-header-setext)
+ (markdown-cycle-setext 1))
+ ;; Demote horizontal rule
+ ((thing-at-point-looking-at markdown-regex-hr)
+ (markdown-cycle-hr 1))
+ ;; Demote list item
+ ((setq bounds (markdown-cur-list-item-bounds))
+ (markdown-demote-list-item bounds))
+ ;; Move table column to the right
+ ((markdown-table-at-point-p)
+ (call-interactively #'markdown-table-move-column-right))
+ ;; Demote bold
+ ((thing-at-point-looking-at markdown-regex-bold)
+ (markdown-cycle-bold))
+ ;; Demote italic
+ ((thing-at-point-looking-at markdown-regex-italic)
+ (markdown-cycle-italic))
+ (t
+ (user-error "Nothing to demote at point")))))
+
+
+;;; Commands ==================================================================
+
+(defun markdown (&optional output-buffer-name)
+ "Run `markdown-command' on buffer, sending output to OUTPUT-BUFFER-NAME.
+The output buffer name defaults to `markdown-output-buffer-name'.
+Return the name of the output buffer used."
+ (interactive)
+ (save-window-excursion
+ (let* ((commands (cond ((stringp markdown-command) (split-string markdown-command))
+ ((listp markdown-command) markdown-command)))
+ (command (car-safe commands))
+ (command-args (cdr-safe commands))
+ begin-region end-region)
+ (if (use-region-p)
+ (setq begin-region (region-beginning)
+ end-region (region-end))
+ (setq begin-region (point-min)
+ end-region (point-max)))
+
+ (unless output-buffer-name
+ (setq output-buffer-name markdown-output-buffer-name))
+ (when (and (stringp command) (not (executable-find command)))
+ (user-error "Markdown command %s is not found" command))
+ (let ((exit-code
+ (cond
+ ;; Handle case when `markdown-command' does not read from stdin
+ ((and (stringp command) markdown-command-needs-filename)
+ (if (not buffer-file-name)
+ (user-error "Must be visiting a file")
+ ;; Don’t use ‘shell-command’ because it’s not guaranteed to
+ ;; return the exit code of the process.
+ (let ((command (if (listp markdown-command)
+ (string-join markdown-command " ")
+ markdown-command)))
+ (shell-command-on-region
+ ;; Pass an empty region so that stdin is empty.
+ (point) (point)
+ (concat command " "
+ (shell-quote-argument buffer-file-name))
+ output-buffer-name))))
+ ;; Pass region to `markdown-command' via stdin
+ (t
+ (let ((buf (get-buffer-create output-buffer-name)))
+ (with-current-buffer buf
+ (setq buffer-read-only nil)
+ (erase-buffer))
+ (if (stringp command)
+ (if (not (null command-args))
+ (apply #'call-process-region begin-region end-region command nil buf nil command-args)
+ (call-process-region begin-region end-region command nil buf))
+ (if markdown-command-needs-filename
+ (if (not buffer-file-name)
+ (user-error "Must be visiting a file")
+ (funcall markdown-command begin-region end-region buf buffer-file-name))
+ (funcall markdown-command begin-region end-region buf))
+ ;; If the ‘markdown-command’ function didn’t signal an
+ ;; error, assume it succeeded by binding ‘exit-code’ to 0.
+ 0))))))
+ ;; The exit code can be a signal description string, so don’t use ‘=’
+ ;; or ‘zerop’.
+ (unless (eq exit-code 0)
+ (user-error "%s failed with exit code %s"
+ markdown-command exit-code))))
+ output-buffer-name))
+
+(defun markdown-standalone (&optional output-buffer-name)
+ "Special function to provide standalone HTML output.
+Insert the output in the buffer named OUTPUT-BUFFER-NAME."
+ (interactive)
+ (setq output-buffer-name (markdown output-buffer-name))
+ (with-current-buffer output-buffer-name
+ (set-buffer output-buffer-name)
+ (unless (markdown-output-standalone-p)
+ (markdown-add-xhtml-header-and-footer output-buffer-name))
+ (goto-char (point-min))
+ (html-mode))
+ output-buffer-name)
+
+(defun markdown-other-window (&optional output-buffer-name)
+ "Run `markdown-command' on current buffer and display in other window.
+When OUTPUT-BUFFER-NAME is given, insert the output in the buffer with
+that name."
+ (interactive)
+ (markdown-display-buffer-other-window
+ (markdown-standalone output-buffer-name)))
+
+(defun markdown-output-standalone-p ()
+ "Determine whether `markdown-command' output is standalone XHTML.
+Standalone XHTML output is identified by an occurrence of
+`markdown-xhtml-standalone-regexp' in the first five lines of output."
+ (save-excursion
+ (goto-char (point-min))
+ (save-match-data
+ (re-search-forward
+ markdown-xhtml-standalone-regexp
+ (save-excursion (goto-char (point-min)) (forward-line 4) (point))
+ t))))
+
+(defun markdown-stylesheet-link-string (stylesheet-path)
+ (concat "<link rel=\"stylesheet\" type=\"text/css\" media=\"all\" href=\""
+ (or (and (string-prefix-p "~" stylesheet-path)
+ (expand-file-name stylesheet-path))
+ stylesheet-path)
+ "\" />"))
+
+(defun markdown-add-xhtml-header-and-footer (title)
+ "Wrap XHTML header and footer with given TITLE around current buffer."
+ (goto-char (point-min))
+ (insert "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n"
+ "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"\n"
+ "\t\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n\n"
+ "<html xmlns=\"http://www.w3.org/1999/xhtml\">\n\n"
+ "<head>\n<title>")
+ (insert title)
+ (insert "</title>\n")
+ (unless (= (length markdown-content-type) 0)
+ (insert
+ (format
+ "<meta http-equiv=\"Content-Type\" content=\"%s;charset=%s\"/>\n"
+ markdown-content-type
+ (or (and markdown-coding-system
+ (coding-system-get markdown-coding-system
+ 'mime-charset))
+ (coding-system-get buffer-file-coding-system
+ 'mime-charset)
+ "utf-8"))))
+ (if (> (length markdown-css-paths) 0)
+ (insert (mapconcat #'markdown-stylesheet-link-string
+ markdown-css-paths "\n")))
+ (when (> (length markdown-xhtml-header-content) 0)
+ (insert markdown-xhtml-header-content))
+ (insert "\n</head>\n\n"
+ "<body>\n\n")
+ (when (> (length markdown-xhtml-body-preamble) 0)
+ (insert markdown-xhtml-body-preamble "\n"))
+ (goto-char (point-max))
+ (when (> (length markdown-xhtml-body-epilogue) 0)
+ (insert "\n" markdown-xhtml-body-epilogue))
+ (insert "\n"
+ "</body>\n"
+ "</html>\n"))
+
+(defun markdown-preview (&optional output-buffer-name)
+ "Run `markdown-command' on the current buffer and view output in browser.
+When OUTPUT-BUFFER-NAME is given, insert the output in the buffer with
+that name."
+ (interactive)
+ (browse-url-of-buffer
+ (markdown-standalone (or output-buffer-name markdown-output-buffer-name))))
+
+(defun markdown-export-file-name (&optional extension)
+ "Attempt to generate a filename for Markdown output.
+The file extension will be EXTENSION if given, or .html by default.
+If the current buffer is visiting a file, we construct a new
+output filename based on that filename. Otherwise, return nil."
+ (when (buffer-file-name)
+ (unless extension
+ (setq extension ".html"))
+ (let ((candidate
+ (concat
+ (cond
+ ((buffer-file-name)
+ (file-name-sans-extension (buffer-file-name)))
+ (t (buffer-name)))
+ extension)))
+ (cond
+ ((equal candidate (buffer-file-name))
+ (concat candidate extension))
+ (t
+ candidate)))))
+
+(defun markdown-export (&optional output-file)
+ "Run Markdown on the current buffer, save to file, and return the filename.
+If OUTPUT-FILE is given, use that as the filename. Otherwise, use the filename
+generated by `markdown-export-file-name', which will be constructed using the
+current filename, but with the extension removed and replaced with .html."
+ (interactive)
+ (unless output-file
+ (setq output-file (markdown-export-file-name ".html")))
+ (when output-file
+ (let* ((init-buf (current-buffer))
+ (init-point (point))
+ (init-buf-string (buffer-string))
+ (output-buffer (find-file-noselect output-file))
+ (output-buffer-name (buffer-name output-buffer)))
+ (run-hooks 'markdown-before-export-hook)
+ (markdown-standalone output-buffer-name)
+ (with-current-buffer output-buffer
+ (run-hooks 'markdown-after-export-hook)
+ (save-buffer)
+ (when markdown-export-kill-buffer (kill-buffer)))
+ ;; if modified, restore initial buffer
+ (when (buffer-modified-p init-buf)
+ (erase-buffer)
+ (insert init-buf-string)
+ (save-buffer)
+ (goto-char init-point))
+ output-file)))
+
+(defun markdown-export-and-preview ()
+ "Export to XHTML using `markdown-export' and browse the resulting file."
+ (interactive)
+ (browse-url-of-file (markdown-export)))
+
+(defvar-local markdown-live-preview-buffer nil
+ "Buffer used to preview markdown output in `markdown-live-preview-export'.")
+
+(defvar-local markdown-live-preview-source-buffer nil
+ "Source buffer from which current buffer was generated.
+This is the inverse of `markdown-live-preview-buffer'.")
+
+(defvar markdown-live-preview-currently-exporting nil)
+
+(defun markdown-live-preview-get-filename ()
+ "Standardize the filename exported by `markdown-live-preview-export'."
+ (markdown-export-file-name ".html"))
+
+(defun markdown-live-preview-window-eww (file)
+ "Preview FILE with eww.
+To be used with `markdown-live-preview-window-function'."
+ (eww-open-file file)
+ (get-buffer "*eww*"))
+
+(defun markdown-visual-lines-between-points (beg end)
+ (save-excursion
+ (goto-char beg)
+ (cl-loop with count = 0
+ while (progn (end-of-visual-line)
+ (and (< (point) end) (line-move-visual 1 t)))
+ do (cl-incf count)
+ finally return count)))
+
+(defun markdown-live-preview-window-serialize (buf)
+ "Get window point and scroll data for all windows displaying BUF."
+ (when (buffer-live-p buf)
+ (with-current-buffer buf
+ (mapcar
+ (lambda (win)
+ (with-selected-window win
+ (let* ((start (window-start))
+ (pt (window-point))
+ (pt-or-sym (cond ((= pt (point-min)) 'min)
+ ((= pt (point-max)) 'max)
+ (t pt)))
+ (diff (markdown-visual-lines-between-points
+ start pt)))
+ (list win pt-or-sym diff))))
+ (get-buffer-window-list buf)))))
+
+(defun markdown-get-point-back-lines (pt num-lines)
+ (save-excursion
+ (goto-char pt)
+ (line-move-visual (- num-lines) t)
+ ;; in testing, can occasionally overshoot the number of lines to traverse
+ (let ((actual-num-lines (markdown-visual-lines-between-points (point) pt)))
+ (when (> actual-num-lines num-lines)
+ (line-move-visual (- actual-num-lines num-lines) t)))
+ (point)))
+
+(defun markdown-live-preview-window-deserialize (window-posns)
+ "Apply window point and scroll data from WINDOW-POSNS.
+WINDOW-POSNS is provided by `markdown-live-preview-window-serialize'."
+ (cl-destructuring-bind (win pt-or-sym diff) window-posns
+ (when (window-live-p win)
+ (with-current-buffer markdown-live-preview-buffer
+ (set-window-buffer win (current-buffer))
+ (cl-destructuring-bind (actual-pt actual-diff)
+ (cl-case pt-or-sym
+ (min (list (point-min) 0))
+ (max (list (point-max) diff))
+ (t (list pt-or-sym diff)))
+ (set-window-start
+ win (markdown-get-point-back-lines actual-pt actual-diff))
+ (set-window-point win actual-pt))))))
+
+(defun markdown-live-preview-export ()
+ "Export to XHTML using `markdown-export'.
+Browse the resulting file within Emacs using
+`markdown-live-preview-window-function' Return the buffer
+displaying the rendered output."
+ (interactive)
+ (let ((filename (markdown-live-preview-get-filename)))
+ (when filename
+ (let* ((markdown-live-preview-currently-exporting t)
+ (cur-buf (current-buffer))
+ (export-file (markdown-export filename))
+ ;; get positions in all windows currently displaying output buffer
+ (window-data
+ (markdown-live-preview-window-serialize
+ markdown-live-preview-buffer)))
+ (save-window-excursion
+ (let ((output-buffer
+ (funcall markdown-live-preview-window-function export-file)))
+ (with-current-buffer output-buffer
+ (setq markdown-live-preview-source-buffer cur-buf)
+ (add-hook 'kill-buffer-hook
+ #'markdown-live-preview-remove-on-kill t t))
+ (with-current-buffer cur-buf
+ (setq markdown-live-preview-buffer output-buffer))))
+ (with-current-buffer cur-buf
+ ;; reset all windows displaying output buffer to where they were,
+ ;; now with the new output
+ (mapc #'markdown-live-preview-window-deserialize window-data)
+ ;; delete html editing buffer
+ (let ((buf (get-file-buffer export-file))) (when buf (kill-buffer buf)))
+ (when (and export-file (file-exists-p export-file)
+ (eq markdown-live-preview-delete-export
+ 'delete-on-export))
+ (delete-file export-file))
+ markdown-live-preview-buffer)))))
+
+(defun markdown-live-preview-remove ()
+ (when (buffer-live-p markdown-live-preview-buffer)
+ (kill-buffer markdown-live-preview-buffer))
+ (setq markdown-live-preview-buffer nil)
+ ;; if set to 'delete-on-export, the output has already been deleted
+ (when (eq markdown-live-preview-delete-export 'delete-on-destroy)
+ (let ((outfile-name (markdown-live-preview-get-filename)))
+ (when (and outfile-name (file-exists-p outfile-name))
+ (delete-file outfile-name)))))
+
+(defun markdown-get-other-window ()
+ "Find another window to display preview or output content."
+ (cond
+ ((memq markdown-split-window-direction '(vertical below))
+ (or (window-in-direction 'below) (split-window-vertically)))
+ ((memq markdown-split-window-direction '(horizontal right))
+ (or (window-in-direction 'right) (split-window-horizontally)))
+ (t (split-window-sensibly (get-buffer-window)))))
+
+(defun markdown-display-buffer-other-window (buf)
+ "Display preview or output buffer BUF in another window."
+ (if (and display-buffer-alist (eq markdown-split-window-direction 'any))
+ (display-buffer buf)
+ (let ((cur-buf (current-buffer))
+ (window (markdown-get-other-window)))
+ (set-window-buffer window buf)
+ (set-buffer cur-buf))))
+
+(defun markdown-live-preview-if-markdown ()
+ (when (and (derived-mode-p 'markdown-mode)
+ markdown-live-preview-mode)
+ (unless markdown-live-preview-currently-exporting
+ (if (buffer-live-p markdown-live-preview-buffer)
+ (markdown-live-preview-export)
+ (markdown-display-buffer-other-window
+ (markdown-live-preview-export))))))
+
+(defun markdown-live-preview-remove-on-kill ()
+ (cond ((and (derived-mode-p 'markdown-mode)
+ markdown-live-preview-mode)
+ (markdown-live-preview-remove))
+ (markdown-live-preview-source-buffer
+ (with-current-buffer markdown-live-preview-source-buffer
+ (setq markdown-live-preview-buffer nil))
+ (setq markdown-live-preview-source-buffer nil))))
+
+(defun markdown-live-preview-switch-to-output ()
+ "Switch to output buffer."
+ (interactive)
+ "Turn on `markdown-live-preview-mode' if not already on, and switch to its
+output buffer in another window."
+ (if markdown-live-preview-mode
+ (markdown-display-buffer-other-window (markdown-live-preview-export)))
+ (markdown-live-preview-mode))
+
+(defun markdown-live-preview-re-export ()
+ "Re export source buffer."
+ (interactive)
+ "If the current buffer is a buffer displaying the exported version of a
+`markdown-live-preview-mode' buffer, call `markdown-live-preview-export' and
+update this buffer's contents."
+ (when markdown-live-preview-source-buffer
+ (with-current-buffer markdown-live-preview-source-buffer
+ (markdown-live-preview-export))))
+
+(defun markdown-open ()
+ "Open file for the current buffer with `markdown-open-command'."
+ (interactive)
+ (unless markdown-open-command
+ (user-error "Variable `markdown-open-command' must be set"))
+ (if (stringp markdown-open-command)
+ (if (not buffer-file-name)
+ (user-error "Must be visiting a file")
+ (save-buffer)
+ (let ((exit-code (call-process markdown-open-command nil nil nil
+ buffer-file-name)))
+ ;; The exit code can be a signal description string, so don’t use ‘=’
+ ;; or ‘zerop’.
+ (unless (eq exit-code 0)
+ (user-error "%s failed with exit code %s"
+ markdown-open-command exit-code))))
+ (funcall markdown-open-command))
+ nil)
+
+(defun markdown-kill-ring-save ()
+ "Run Markdown on file and store output in the kill ring."
+ (interactive)
+ (save-window-excursion
+ (markdown)
+ (with-current-buffer markdown-output-buffer-name
+ (kill-ring-save (point-min) (point-max)))))
+
+
+;;; Links =====================================================================
+
+(defun markdown-backward-to-link-start ()
+ "Backward link start position if current position is in link title."
+ ;; Issue #305
+ (when (eq (get-text-property (point) 'face) 'markdown-link-face)
+ (skip-chars-backward "^[")
+ (forward-char -1)))
+
+(defun markdown-link-p ()
+ "Return non-nil when `point' is at a non-wiki link.
+See `markdown-wiki-link-p' for more information."
+ (save-excursion
+ (let ((case-fold-search nil))
+ (when (and (not (markdown-wiki-link-p)) (not (markdown-code-block-at-point-p)))
+ (markdown-backward-to-link-start)
+ (or (thing-at-point-looking-at markdown-regex-link-inline)
+ (thing-at-point-looking-at markdown-regex-link-reference)
+ (thing-at-point-looking-at markdown-regex-uri)
+ (thing-at-point-looking-at markdown-regex-angle-uri))))))
+
+(defun markdown-link-at-pos (pos)
+ "Return properties of link or image at position POS.
+Value is a list of elements describing the link:
+ 0. beginning position
+ 1. end position
+ 2. link text
+ 3. URL
+ 4. reference label
+ 5. title text
+ 6. bang (nil or \"!\")"
+ (save-excursion
+ (goto-char pos)
+ (markdown-backward-to-link-start)
+ (let (begin end text url reference title bang)
+ (cond
+ ;; Inline image or link at point.
+ ((thing-at-point-looking-at markdown-regex-link-inline)
+ (setq bang (match-string-no-properties 1)
+ begin (match-beginning 0)
+ end (match-end 0)
+ text (match-string-no-properties 3)
+ url (match-string-no-properties 6))
+ (if (match-end 7)
+ (setq title (substring (match-string-no-properties 7) 1 -1))
+ ;; #408 URL contains close parenthesis case
+ (goto-char (match-beginning 5))
+ (let ((paren-end (scan-sexps (point) 1)))
+ (when (and paren-end (< end paren-end))
+ (setq url (buffer-substring (match-beginning 6) (1- paren-end)))))))
+ ;; Reference link at point.
+ ((or (thing-at-point-looking-at markdown-regex-link-inline)
+ (thing-at-point-looking-at markdown-regex-link-reference))
+ (setq bang (match-string-no-properties 1)
+ begin (match-beginning 0)
+ end (match-end 0)
+ text (match-string-no-properties 3))
+ (when (char-equal (char-after (match-beginning 5)) ?\[)
+ (setq reference (match-string-no-properties 6))))
+ ;; Angle bracket URI at point.
+ ((thing-at-point-looking-at markdown-regex-angle-uri)
+ (setq begin (match-beginning 0)
+ end (match-end 0)
+ url (match-string-no-properties 2)))
+ ;; Plain URI at point.
+ ((thing-at-point-looking-at markdown-regex-uri)
+ (setq begin (match-beginning 0)
+ end (match-end 0)
+ url (match-string-no-properties 1))))
+ (list begin end text url reference title bang))))
+
+(defun markdown-link-url ()
+ "Return the URL part of the regular (non-wiki) link at point.
+Works with both inline and reference style links, and with images.
+If point is not at a link or the link reference is not defined
+returns nil."
+ (let* ((values (markdown-link-at-pos (point)))
+ (text (nth 2 values))
+ (url (nth 3 values))
+ (ref (nth 4 values)))
+ (or url (and ref (car (markdown-reference-definition
+ (downcase (if (string= ref "") text ref))))))))
+
+(defun markdown--browse-url (url)
+ (let* ((struct (url-generic-parse-url url))
+ (full (url-fullness struct))
+ (file url))
+ ;; Parse URL, determine fullness, strip query string
+ (setq file (car (url-path-and-query struct)))
+ ;; Open full URLs in browser, files in Emacs
+ (if full
+ (browse-url url)
+ (when (and file (> (length file) 0))
+ (let ((link-file (funcall markdown-translate-filename-function file)))
+ (if (and markdown-open-image-command (string-match-p (image-file-name-regexp) link-file))
+ (if (functionp markdown-open-image-command)
+ (funcall markdown-open-image-command link-file)
+ (process-file markdown-open-image-command nil nil nil link-file))
+ (find-file link-file)))))))
+
+(defun markdown-follow-link-at-point (&optional event)
+ "Open the non-wiki link at point or EVENT.
+If the link is a complete URL, open in browser with `browse-url'.
+Otherwise, open with `find-file' after stripping anchor and/or query string.
+Translate filenames using `markdown-filename-translate-function'."
+ (interactive (list last-command-event))
+ (save-excursion
+ (if event (posn-set-point (event-start event)))
+ (if (markdown-link-p)
+ (markdown--browse-url (markdown-link-url))
+ (user-error "Point is not at a Markdown link or URL"))))
+
+(defun markdown-fontify-inline-links (last)
+ "Add text properties to next inline link from point to LAST."
+ (when (markdown-match-generic-links last nil)
+ (let* ((link-start (match-beginning 3))
+ (link-end (match-end 3))
+ (url-start (match-beginning 6))
+ (url-end (match-end 6))
+ (url (match-string-no-properties 6))
+ (title-start (match-beginning 7))
+ (title-end (match-end 7))
+ (title (match-string-no-properties 7))
+ ;; Markup part
+ (mp (list 'face 'markdown-markup-face
+ 'invisible 'markdown-markup
+ 'rear-nonsticky t
+ 'font-lock-multiline t))
+ ;; Link part (without face)
+ (lp (list 'keymap markdown-mode-mouse-map
+ 'mouse-face 'markdown-highlight-face
+ 'font-lock-multiline t
+ 'help-echo (if title (concat title "\n" url) url)))
+ ;; URL part
+ (up (list 'keymap markdown-mode-mouse-map
+ 'face 'markdown-url-face
+ 'invisible 'markdown-markup
+ 'mouse-face 'markdown-highlight-face
+ 'font-lock-multiline t))
+ ;; URL composition character
+ (url-char (markdown--first-displayable markdown-url-compose-char))
+ ;; Title part
+ (tp (list 'face 'markdown-link-title-face
+ 'invisible 'markdown-markup
+ 'font-lock-multiline t)))
+ (dolist (g '(1 2 4 5 8))
+ (when (match-end g)
+ (add-text-properties (match-beginning g) (match-end g) mp)))
+ ;; Preserve existing faces applied to link part (e.g., inline code)
+ (when link-start
+ (add-text-properties link-start link-end lp)
+ (add-face-text-property link-start link-end
+ 'markdown-link-face 'append))
+ (when url-start (add-text-properties url-start url-end up))
+ (when title-start (add-text-properties url-end title-end tp))
+ (when (and markdown-hide-urls url-start)
+ (compose-region url-start (or title-end url-end) url-char))
+ t)))
+
+(defun markdown-fontify-reference-links (last)
+ "Add text properties to next reference link from point to LAST."
+ (when (markdown-match-generic-links last t)
+ (let* ((link-start (match-beginning 3))
+ (link-end (match-end 3))
+ (ref-start (match-beginning 6))
+ (ref-end (match-end 6))
+ ;; Markup part
+ (mp (list 'face 'markdown-markup-face
+ 'invisible 'markdown-markup
+ 'rear-nonsticky t
+ 'font-lock-multiline t))
+ ;; Link part
+ (lp (list 'keymap markdown-mode-mouse-map
+ 'face 'markdown-link-face
+ 'mouse-face 'markdown-highlight-face
+ 'font-lock-multiline t
+ 'help-echo (lambda (_ __ pos)
+ (save-match-data
+ (save-excursion
+ (goto-char pos)
+ (or (markdown-link-url)
+ "Undefined reference"))))))
+ ;; URL composition character
+ (url-char (markdown--first-displayable markdown-url-compose-char))
+ ;; Reference part
+ (rp (list 'face 'markdown-reference-face
+ 'invisible 'markdown-markup
+ 'font-lock-multiline t)))
+ (dolist (g '(1 2 4 5 8))
+ (when (match-end g)
+ (add-text-properties (match-beginning g) (match-end g) mp)))
+ (when link-start (add-text-properties link-start link-end lp))
+ (when ref-start (add-text-properties ref-start ref-end rp)
+ (when (and markdown-hide-urls (> (- ref-end ref-start) 2))
+ (compose-region ref-start ref-end url-char)))
+ t)))
+
+(defun markdown-fontify-angle-uris (last)
+ "Add text properties to angle URIs from point to LAST."
+ (when (markdown-match-angle-uris last)
+ (let* ((url-start (match-beginning 2))
+ (url-end (match-end 2))
+ ;; Markup part
+ (mp (list 'face 'markdown-markup-face
+ 'invisible 'markdown-markup
+ 'rear-nonsticky t
+ 'font-lock-multiline t))
+ ;; URI part
+ (up (list 'keymap markdown-mode-mouse-map
+ 'face 'markdown-plain-url-face
+ 'mouse-face 'markdown-highlight-face
+ 'font-lock-multiline t)))
+ (dolist (g '(1 3))
+ (add-text-properties (match-beginning g) (match-end g) mp))
+ (add-text-properties url-start url-end up)
+ t)))
+
+(defun markdown-fontify-plain-uris (last)
+ "Add text properties to plain URLs from point to LAST."
+ (when (markdown-match-plain-uris last)
+ (let* ((start (match-beginning 0))
+ (end (match-end 0))
+ (props (list 'keymap markdown-mode-mouse-map
+ 'face 'markdown-plain-url-face
+ 'mouse-face 'markdown-highlight-face
+ 'rear-nonsticky t
+ 'font-lock-multiline t)))
+ (add-text-properties start end props)
+ t)))
+
+(defun markdown-toggle-url-hiding (&optional arg)
+ "Toggle the display or hiding of URLs.
+With a prefix argument ARG, enable URL hiding if ARG is positive,
+and disable it otherwise."
+ (interactive (list (or current-prefix-arg 'toggle)))
+ (setq markdown-hide-urls
+ (if (eq arg 'toggle)
+ (not markdown-hide-urls)
+ (> (prefix-numeric-value arg) 0)))
+ (if markdown-hide-urls
+ (message "markdown-mode URL hiding enabled")
+ (message "markdown-mode URL hiding disabled"))
+ (markdown-reload-extensions))
+
+
+;;; Wiki Links ================================================================
+
+(defun markdown-wiki-link-p ()
+ "Return non-nil if wiki links are enabled and `point' is at a true wiki link.
+A true wiki link name matches `markdown-regex-wiki-link' but does
+not match the current file name after conversion. This modifies
+the data returned by `match-data'. Note that the potential wiki
+link name must be available via `match-string'."
+ (when markdown-enable-wiki-links
+ (let ((case-fold-search nil))
+ (and (thing-at-point-looking-at markdown-regex-wiki-link)
+ (not (markdown-code-block-at-point-p))
+ (or (not buffer-file-name)
+ (not (string-equal (buffer-file-name)
+ (markdown-convert-wiki-link-to-filename
+ (markdown-wiki-link-link)))))))))
+
+(defun markdown-wiki-link-link ()
+ "Return the link part of the wiki link using current match data.
+The location of the link component depends on the value of
+`markdown-wiki-link-alias-first'."
+ (if markdown-wiki-link-alias-first
+ (or (match-string-no-properties 5) (match-string-no-properties 3))
+ (match-string-no-properties 3)))
+
+(defun markdown-wiki-link-alias ()
+ "Return the alias or text part of the wiki link using current match data.
+The location of the alias component depends on the value of
+`markdown-wiki-link-alias-first'."
+ (if markdown-wiki-link-alias-first
+ (match-string-no-properties 3)
+ (or (match-string-no-properties 5) (match-string-no-properties 3))))
+
+(defun markdown--wiki-link-search-types ()
+ (let ((ret (and markdown-wiki-link-search-type
+ (cl-copy-list markdown-wiki-link-search-type))))
+ (when (and markdown-wiki-link-search-subdirectories
+ (not (memq 'sub-directories markdown-wiki-link-search-type)))
+ (push 'sub-directories ret))
+ (when (and markdown-wiki-link-search-parent-directories
+ (not (memq 'parent-directories markdown-wiki-link-search-type)))
+ (push 'parent-directories ret))
+ ret))
+
+(defun markdown--project-root ()
+ (or (cl-loop for dir in '(".git" ".hg" ".svn")
+ when (locate-dominating-file default-directory dir)
+ return it)
+ (progn
+ (require 'project)
+ (let ((project (project-current t)))
+ (with-no-warnings
+ (if (fboundp 'project-root)
+ (project-root project)
+ (car (project-roots project))))))))
+
+(defun markdown-convert-wiki-link-to-filename (name)
+ "Generate a filename from the wiki link NAME.
+Spaces in NAME are replaced with `markdown-link-space-sub-char'.
+When in `gfm-mode', follow GitHub's conventions where [[Test Test]]
+and [[test test]] both map to Test-test.ext. Look in the current
+directory first, then in subdirectories if
+`markdown-wiki-link-search-subdirectories' is non-nil, and then
+in parent directories if
+`markdown-wiki-link-search-parent-directories' is non-nil."
+ (save-match-data
+ ;; This function must not overwrite match data(PR #590)
+ (let* ((basename (replace-regexp-in-string
+ "[[:space:]\n]" markdown-link-space-sub-char name))
+ (basename (if (derived-mode-p 'gfm-mode)
+ (concat (upcase (substring basename 0 1))
+ (downcase (substring basename 1 nil)))
+ basename))
+ (search-types (markdown--wiki-link-search-types))
+ directory extension default candidates dir)
+ (when buffer-file-name
+ (setq directory (file-name-directory buffer-file-name)
+ extension (file-name-extension buffer-file-name)))
+ (setq default (concat basename
+ (when extension (concat "." extension))))
+ (cond
+ ;; Look in current directory first.
+ ((or (null buffer-file-name)
+ (file-exists-p default))
+ default)
+ ;; Possibly search in subdirectories, next.
+ ((and (memq 'sub-directories search-types)
+ (setq candidates
+ (directory-files-recursively
+ directory (concat "^" default "$"))))
+ (car candidates))
+ ;; Possibly search in parent directories as a last resort.
+ ((and (memq 'parent-directories search-types)
+ (setq dir (locate-dominating-file directory default)))
+ (concat dir default))
+ ((and (memq 'project search-types)
+ (setq candidates
+ (directory-files-recursively
+ (markdown--project-root) (concat "^" default "$"))))
+ (car candidates))
+ ;; If nothing is found, return default in current directory.
+ (t default)))))
+
+(defun markdown-follow-wiki-link (name &optional other)
+ "Follow the wiki link NAME.
+Convert the name to a file name and call `find-file'. Ensure that
+the new buffer remains in `markdown-mode'. Open the link in another
+window when OTHER is non-nil."
+ (let ((filename (markdown-convert-wiki-link-to-filename name))
+ (wp (when buffer-file-name
+ (file-name-directory buffer-file-name))))
+ (if (not wp)
+ (user-error "Must be visiting a file")
+ (when other (other-window 1))
+ (let ((default-directory wp))
+ (find-file filename)))
+ (unless (derived-mode-p 'markdown-mode)
+ (markdown-mode))))
+
+(defun markdown-follow-wiki-link-at-point (&optional arg)
+ "Find Wiki Link at point.
+With prefix argument ARG, open the file in other window.
+See `markdown-wiki-link-p' and `markdown-follow-wiki-link'."
+ (interactive "P")
+ (if (markdown-wiki-link-p)
+ (markdown-follow-wiki-link (markdown-wiki-link-link) arg)
+ (user-error "Point is not at a Wiki Link")))
+
+(defun markdown-highlight-wiki-link (from to face)
+ "Highlight the wiki link in the region between FROM and TO using FACE."
+ (put-text-property from to 'font-lock-face face))
+
+(defun markdown-unfontify-region-wiki-links (from to)
+ "Remove wiki link faces from the region specified by FROM and TO."
+ (interactive "*r")
+ (let ((modified (buffer-modified-p)))
+ (remove-text-properties from to '(font-lock-face markdown-link-face))
+ (remove-text-properties from to '(font-lock-face markdown-missing-link-face))
+ ;; remove-text-properties marks the buffer modified in emacs 24.3,
+ ;; undo that if it wasn't originally marked modified
+ (set-buffer-modified-p modified)))
+
+(defun markdown-fontify-region-wiki-links (from to)
+ "Search region given by FROM and TO for wiki links and fontify them.
+If a wiki link is found check to see if the backing file exists
+and highlight accordingly."
+ (goto-char from)
+ (save-match-data
+ (while (re-search-forward markdown-regex-wiki-link to t)
+ (when (not (markdown-code-block-at-point-p))
+ (let ((highlight-beginning (match-beginning 1))
+ (highlight-end (match-end 1))
+ (file-name
+ (markdown-convert-wiki-link-to-filename
+ (markdown-wiki-link-link))))
+ (if (condition-case nil (file-exists-p file-name) (error nil))
+ (markdown-highlight-wiki-link
+ highlight-beginning highlight-end 'markdown-link-face)
+ (markdown-highlight-wiki-link
+ highlight-beginning highlight-end 'markdown-missing-link-face)))))))
+
+(defun markdown-extend-changed-region (from to)
+ "Extend region given by FROM and TO so that we can fontify all links.
+The region is extended to the first newline before and the first
+newline after."
+ ;; start looking for the first new line before 'from
+ (goto-char from)
+ (re-search-backward "\n" nil t)
+ (let ((new-from (point-min))
+ (new-to (point-max)))
+ (if (not (= (point) from))
+ (setq new-from (point)))
+ ;; do the same thing for the first new line after 'to
+ (goto-char to)
+ (re-search-forward "\n" nil t)
+ (if (not (= (point) to))
+ (setq new-to (point)))
+ (cl-values new-from new-to)))
+
+(defun markdown-check-change-for-wiki-link (from to)
+ "Check region between FROM and TO for wiki links and re-fontify as needed."
+ (interactive "*r")
+ (let* ((modified (buffer-modified-p))
+ (buffer-undo-list t)
+ (inhibit-read-only t)
+ (inhibit-point-motion-hooks t)
+ deactivate-mark
+ buffer-file-truename)
+ (unwind-protect
+ (save-excursion
+ (save-match-data
+ (save-restriction
+ ;; Extend the region to fontify so that it starts
+ ;; and ends at safe places.
+ (cl-multiple-value-bind (new-from new-to)
+ (markdown-extend-changed-region from to)
+ (goto-char new-from)
+ ;; Only refontify when the range contains text with a
+ ;; wiki link face or if the wiki link regexp matches.
+ (when (or (markdown-range-property-any
+ new-from new-to 'font-lock-face
+ '(markdown-link-face markdown-missing-link-face))
+ (re-search-forward
+ markdown-regex-wiki-link new-to t))
+ ;; Unfontify existing fontification (start from scratch)
+ (markdown-unfontify-region-wiki-links new-from new-to)
+ ;; Now do the fontification.
+ (markdown-fontify-region-wiki-links new-from new-to))))))
+ (and (not modified)
+ (buffer-modified-p)
+ (set-buffer-modified-p nil)))))
+
+(defun markdown-check-change-for-wiki-link-after-change (from to _)
+ "Check region between FROM and TO for wiki links and re-fontify as needed.
+Designed to be used with the `after-change-functions' hook."
+ (markdown-check-change-for-wiki-link from to))
+
+(defun markdown-fontify-buffer-wiki-links ()
+ "Refontify all wiki links in the buffer."
+ (interactive)
+ (markdown-check-change-for-wiki-link (point-min) (point-max)))
+
+(defun markdown-toggle-wiki-links (&optional arg)
+ "Toggle support for wiki links.
+With a prefix argument ARG, enable wiki link support if ARG is positive,
+and disable it otherwise."
+ (interactive (list (or current-prefix-arg 'toggle)))
+ (setq markdown-enable-wiki-links
+ (if (eq arg 'toggle)
+ (not markdown-enable-wiki-links)
+ (> (prefix-numeric-value arg) 0)))
+ (if markdown-enable-wiki-links
+ (message "markdown-mode wiki link support enabled")
+ (message "markdown-mode wiki link support disabled"))
+ (markdown-reload-extensions))
+
+(defun markdown-setup-wiki-link-hooks ()
+ "Add or remove hooks for fontifying wiki links.
+These are only enabled when `markdown-wiki-link-fontify-missing' is non-nil."
+ ;; Anytime text changes make sure it gets fontified correctly
+ (if (and markdown-enable-wiki-links
+ markdown-wiki-link-fontify-missing)
+ (add-hook 'after-change-functions
+ #'markdown-check-change-for-wiki-link-after-change t t)
+ (remove-hook 'after-change-functions
+ #'markdown-check-change-for-wiki-link-after-change t))
+ ;; If we left the buffer there is a really good chance we were
+ ;; creating one of the wiki link documents. Make sure we get
+ ;; refontified when we come back.
+ (if (and markdown-enable-wiki-links
+ markdown-wiki-link-fontify-missing)
+ (progn
+ (add-hook 'window-configuration-change-hook
+ #'markdown-fontify-buffer-wiki-links t t)
+ (markdown-fontify-buffer-wiki-links))
+ (remove-hook 'window-configuration-change-hook
+ #'markdown-fontify-buffer-wiki-links t)
+ (markdown-unfontify-region-wiki-links (point-min) (point-max))))
+
+
+;;; Following & Doing =========================================================
+
+(defun markdown-follow-thing-at-point (arg)
+ "Follow thing at point if possible, such as a reference link or wiki link.
+Opens inline and reference links in a browser. Opens wiki links
+to other files in the current window, or the another window if
+ARG is non-nil.
+See `markdown-follow-link-at-point' and
+`markdown-follow-wiki-link-at-point'."
+ (interactive "P")
+ (cond ((markdown-link-p)
+ (markdown--browse-url (markdown-link-url)))
+ ((markdown-wiki-link-p)
+ (markdown-follow-wiki-link-at-point arg))
+ (t
+ (let* ((values (markdown-link-at-pos (point)))
+ (url (nth 3 values)))
+ (unless url
+ (user-error "Nothing to follow at point"))
+ (markdown--browse-url url)))))
+
+(defun markdown-do ()
+ "Do something sensible based on context at point.
+Jumps between reference links and definitions; between footnote
+markers and footnote text."
+ (interactive)
+ (cond
+ ;; Footnote definition
+ ((markdown-footnote-text-positions)
+ (markdown-footnote-return))
+ ;; Footnote marker
+ ((markdown-footnote-marker-positions)
+ (markdown-footnote-goto-text))
+ ;; Reference link
+ ((thing-at-point-looking-at markdown-regex-link-reference)
+ (markdown-reference-goto-definition))
+ ;; Reference definition
+ ((thing-at-point-looking-at markdown-regex-reference-definition)
+ (markdown-reference-goto-link (match-string-no-properties 2)))
+ ;; Link
+ ((or (markdown-link-p) (markdown-wiki-link-p))
+ (markdown-follow-thing-at-point nil))
+ ;; GFM task list item
+ ((markdown-gfm-task-list-item-at-point)
+ (markdown-toggle-gfm-checkbox))
+ ;; Align table
+ ((markdown-table-at-point-p)
+ (call-interactively #'markdown-table-align))
+ ;; Otherwise
+ (t
+ (markdown-insert-gfm-checkbox))))
+
+
+;;; Miscellaneous =============================================================
+
+(defun markdown-compress-whitespace-string (str)
+ "Compress whitespace in STR and return result.
+Leading and trailing whitespace is removed. Sequences of multiple
+spaces, tabs, and newlines are replaced with single spaces."
+ (replace-regexp-in-string "\\(^[ \t\n]+\\|[ \t\n]+$\\)" ""
+ (replace-regexp-in-string "[ \t\n]+" " " str)))
+
+(defun markdown--substitute-command-keys (string)
+ "Like `substitute-command-keys' but, but prefers control characters.
+First pass STRING to `substitute-command-keys' and then
+substitute `C-i` for `TAB` and `C-m` for `RET`."
+ (replace-regexp-in-string
+ "\\<TAB\\>" "C-i"
+ (replace-regexp-in-string
+ "\\<RET\\>" "C-m" (substitute-command-keys string) t) t))
+
+(defun markdown-line-number-at-pos (&optional pos)
+ "Return (narrowed) buffer line number at position POS.
+If POS is nil, use current buffer location.
+This is an exact copy of `line-number-at-pos' for use in emacs21."
+ (let ((opoint (or pos (point))) start)
+ (save-excursion
+ (goto-char (point-min))
+ (setq start (point))
+ (goto-char opoint)
+ (forward-line 0)
+ (1+ (count-lines start (point))))))
+
+(defun markdown-inside-link-p ()
+ "Return t if point is within a link."
+ (save-match-data
+ (thing-at-point-looking-at (markdown-make-regex-link-generic))))
+
+(defun markdown-line-is-reference-definition-p ()
+ "Return whether the current line is a (non-footnote) reference definition."
+ (save-excursion
+ (move-beginning-of-line 1)
+ (and (looking-at-p markdown-regex-reference-definition)
+ (not (looking-at-p "[ \t]*\\[^")))))
+
+(defun markdown-adaptive-fill-function ()
+ "Return prefix for filling paragraph or nil if not determined."
+ (cond
+ ;; List item inside blockquote
+ ((looking-at "^[ \t]*>[ \t]*\\(\\(?:[0-9]+\\|#\\)\\.\\|[*+:-]\\)[ \t]+")
+ (replace-regexp-in-string
+ "[0-9\\.*+-]" " " (match-string-no-properties 0)))
+ ;; Blockquote
+ ((looking-at markdown-regex-blockquote)
+ (buffer-substring-no-properties (match-beginning 0) (match-end 2)))
+ ;; List items
+ ((looking-at markdown-regex-list)
+ (match-string-no-properties 0))
+ ;; Footnote definition
+ ((looking-at-p markdown-regex-footnote-definition)
+ " ") ; four spaces
+ ;; No match
+ (t nil)))
+
+(defun markdown-fill-paragraph (&optional justify)
+ "Fill paragraph at or after point.
+This function is like \\[fill-paragraph], but it skips Markdown
+code blocks. If the point is in a code block, or just before one,
+do not fill. Otherwise, call `fill-paragraph' as usual. If
+JUSTIFY is non-nil, justify text as well. Since this function
+handles filling itself, it always returns t so that
+`fill-paragraph' doesn't run."
+ (interactive "P")
+ (unless (or (markdown-code-block-at-point-p)
+ (save-excursion
+ (back-to-indentation)
+ (skip-syntax-forward "-")
+ (markdown-code-block-at-point-p)))
+ (let ((fill-prefix (save-excursion
+ (goto-char (line-beginning-position))
+ (when (looking-at "\\([ \t]*>[ \t]*\\(?:>[ \t]*\\)+\\)")
+ (match-string-no-properties 1)))))
+ (fill-paragraph justify)))
+ t)
+
+(defun markdown-fill-forward-paragraph (&optional arg)
+ "Function used by `fill-paragraph' to move over ARG paragraphs.
+This is a `fill-forward-paragraph-function' for `markdown-mode'.
+It is called with a single argument specifying the number of
+paragraphs to move. Just like `forward-paragraph', it should
+return the number of paragraphs left to move."
+ (or arg (setq arg 1))
+ (if (> arg 0)
+ ;; With positive ARG, move across ARG non-code-block paragraphs,
+ ;; one at a time. When passing a code block, don't decrement ARG.
+ (while (and (not (eobp))
+ (> arg 0)
+ (= (forward-paragraph 1) 0)
+ (or (markdown-code-block-at-pos (point-at-bol 0))
+ (setq arg (1- arg)))))
+ ;; Move backward by one paragraph with negative ARG (always -1).
+ (let ((start (point)))
+ (setq arg (forward-paragraph arg))
+ (while (and (not (eobp))
+ (progn (move-to-left-margin) (not (eobp)))
+ (looking-at-p paragraph-separate))
+ (forward-line 1))
+ (cond
+ ;; Move point past whitespace following list marker.
+ ((looking-at markdown-regex-list)
+ (goto-char (match-end 0)))
+ ;; Move point past whitespace following pipe at beginning of line
+ ;; to handle Pandoc line blocks.
+ ((looking-at "^|\\s-*")
+ (goto-char (match-end 0)))
+ ;; Return point if the paragraph passed was a code block.
+ ((markdown-code-block-at-pos (point-at-bol 2))
+ (goto-char start)))))
+ arg)
+
+(defun markdown--inhibit-electric-quote ()
+ "Function added to `electric-quote-inhibit-functions'.
+Return non-nil if the quote has been inserted inside a code block
+or span."
+ (let ((pos (1- (point))))
+ (or (markdown-inline-code-at-pos pos)
+ (markdown-code-block-at-pos pos))))
+
+
+;;; Extension Framework =======================================================
+
+(defun markdown-reload-extensions ()
+ "Check settings, update font-lock keywords and hooks, and re-fontify buffer."
+ (interactive)
+ (when (derived-mode-p 'markdown-mode)
+ ;; Refontify buffer
+ (font-lock-flush)
+ ;; Add or remove hooks related to extensions
+ (markdown-setup-wiki-link-hooks)))
+
+(defun markdown-handle-local-variables ()
+ "Run in `hack-local-variables-hook' to update font lock rules.
+Checks to see if there is actually a ‘markdown-mode’ file local variable
+before regenerating font-lock rules for extensions."
+ (when (or (assoc 'markdown-enable-wiki-links file-local-variables-alist)
+ (assoc 'markdown-enable-math file-local-variables-alist))
+ (when (assoc 'markdown-enable-math file-local-variables-alist)
+ (markdown-toggle-math markdown-enable-math))
+ (markdown-reload-extensions)))
+
+
+;;; Math Support ==============================================================
+
+(defconst markdown-mode-font-lock-keywords-math
+ (list
+ ;; Equation reference (eq:foo)
+ '("\\((eq:\\)\\([[:alnum:]:_]+\\)\\()\\)" . ((1 markdown-markup-face)
+ (2 markdown-reference-face)
+ (3 markdown-markup-face)))
+ ;; Equation reference \eqref{foo}
+ '("\\(\\\\eqref{\\)\\([[:alnum:]:_]+\\)\\(}\\)" . ((1 markdown-markup-face)
+ (2 markdown-reference-face)
+ (3 markdown-markup-face))))
+ "Font lock keywords to add and remove when toggling math support.")
+
+(defun markdown-toggle-math (&optional arg)
+ "Toggle support for inline and display LaTeX math expressions.
+With a prefix argument ARG, enable math mode if ARG is positive,
+and disable it otherwise. If called from Lisp, enable the mode
+if ARG is omitted or nil."
+ (interactive (list (or current-prefix-arg 'toggle)))
+ (setq markdown-enable-math
+ (if (eq arg 'toggle)
+ (not markdown-enable-math)
+ (> (prefix-numeric-value arg) 0)))
+ (if markdown-enable-math
+ (progn
+ (font-lock-add-keywords
+ 'markdown-mode markdown-mode-font-lock-keywords-math)
+ (message "markdown-mode math support enabled"))
+ (font-lock-remove-keywords
+ 'markdown-mode markdown-mode-font-lock-keywords-math)
+ (message "markdown-mode math support disabled"))
+ (markdown-reload-extensions))
+
+
+;;; GFM Checkboxes ============================================================
+
+(define-button-type 'markdown-gfm-checkbox-button
+ 'follow-link t
+ 'face 'markdown-gfm-checkbox-face
+ 'mouse-face 'markdown-highlight-face
+ 'action #'markdown-toggle-gfm-checkbox-button)
+
+(defun markdown-gfm-task-list-item-at-point (&optional bounds)
+ "Return non-nil if there is a GFM task list item at the point.
+Optionally, the list item BOUNDS may be given if available, as
+returned by `markdown-cur-list-item-bounds'. When a task list item
+is found, the return value is the same value returned by
+`markdown-cur-list-item-bounds'."
+ (unless bounds
+ (setq bounds (markdown-cur-list-item-bounds)))
+ (> (length (nth 5 bounds)) 0))
+
+(defun markdown-insert-gfm-checkbox ()
+ "Add GFM checkbox at point.
+Returns t if added.
+Returns nil if non-applicable."
+ (interactive)
+ (let ((bounds (markdown-cur-list-item-bounds)))
+ (if bounds
+ (unless (cl-sixth bounds)
+ (let ((pos (+ (cl-first bounds) (cl-fourth bounds)))
+ (markup "[ ] "))
+ (if (< pos (point))
+ (save-excursion
+ (goto-char pos)
+ (insert markup))
+ (goto-char pos)
+ (insert markup))
+ (syntax-propertize (+ (cl-second bounds) 4))
+ t))
+ (unless (save-excursion
+ (back-to-indentation)
+ (or (markdown-list-item-at-point-p)
+ (markdown-heading-at-point)
+ (markdown-in-comment-p)
+ (markdown-code-block-at-point-p)))
+ (let ((pos (save-excursion
+ (back-to-indentation)
+ (point)))
+ (markup (concat (or (save-excursion
+ (beginning-of-line 0)
+ (cl-fifth (markdown-cur-list-item-bounds)))
+ markdown-unordered-list-item-prefix)
+ "[ ] ")))
+ (if (< pos (point))
+ (save-excursion
+ (goto-char pos)
+ (insert markup))
+ (goto-char pos)
+ (insert markup))
+ (syntax-propertize (point-at-eol))
+ t)))))
+
+(defun markdown-toggle-gfm-checkbox ()
+ "Toggle GFM checkbox at point.
+Returns the resulting status as a string, either \"[x]\" or \"[ ]\".
+Returns nil if there is no task list item at the point."
+ (interactive)
+ (save-match-data
+ (save-excursion
+ (let ((bounds (markdown-cur-list-item-bounds)))
+ (when bounds
+ ;; Move to beginning of task list item
+ (goto-char (cl-first bounds))
+ ;; Advance to column of first non-whitespace after marker
+ (forward-char (cl-fourth bounds))
+ (cond ((looking-at "\\[ \\]")
+ (replace-match
+ (if markdown-gfm-uppercase-checkbox "[X]" "[x]")
+ nil t)
+ (match-string-no-properties 0))
+ ((looking-at "\\[[xX]\\]")
+ (replace-match "[ ]" nil t)
+ (match-string-no-properties 0))))))))
+
+(defun markdown-toggle-gfm-checkbox-button (button)
+ "Toggle GFM checkbox BUTTON on click."
+ (save-match-data
+ (save-excursion
+ (goto-char (button-start button))
+ (markdown-toggle-gfm-checkbox))))
+
+(defun markdown-make-gfm-checkboxes-buttons (start end)
+ "Make GFM checkboxes buttons in region between START and END."
+ (save-excursion
+ (goto-char start)
+ (let ((case-fold-search t))
+ (save-excursion
+ (while (re-search-forward markdown-regex-gfm-checkbox end t)
+ (make-button (match-beginning 1) (match-end 1)
+ :type 'markdown-gfm-checkbox-button))))))
+
+;; Called when any modification is made to buffer text.
+(defun markdown-gfm-checkbox-after-change-function (beg end _)
+ "Add to `after-change-functions' to setup GFM checkboxes as buttons.
+BEG and END are the limits of scanned region."
+ (save-excursion
+ (save-match-data
+ ;; Rescan between start of line from `beg' and start of line after `end'.
+ (markdown-make-gfm-checkboxes-buttons
+ (progn (goto-char beg) (beginning-of-line) (point))
+ (progn (goto-char end) (forward-line 1) (point))))))
+
+(defun markdown-remove-gfm-checkbox-overlays ()
+ "Remove all GFM checkbox overlays in buffer."
+ (save-excursion
+ (save-restriction
+ (widen)
+ (remove-overlays nil nil 'face 'markdown-gfm-checkbox-face))))
+
+
+;;; Display inline image ======================================================
+
+(defvar-local markdown-inline-image-overlays nil)
+
+(defun markdown-remove-inline-images ()
+ "Remove inline image overlays from image links in the buffer.
+This can be toggled with `markdown-toggle-inline-images'
+or \\[markdown-toggle-inline-images]."
+ (interactive)
+ (mapc #'delete-overlay markdown-inline-image-overlays)
+ (setq markdown-inline-image-overlays nil))
+
+(defcustom markdown-display-remote-images nil
+ "If non-nil, download and display remote images.
+See also `markdown-inline-image-overlays'.
+
+Only image URLs specified with a protocol listed in
+`markdown-remote-image-protocols' are displayed."
+ :group 'markdown
+ :type 'boolean)
+
+(defcustom markdown-remote-image-protocols '("https")
+ "List of protocols to use to download remote images.
+See also `markdown-display-remote-images'."
+ :group 'markdown
+ :type '(repeat string))
+
+(defvar markdown--remote-image-cache
+ (make-hash-table :test 'equal)
+ "A map from URLs to image paths.")
+
+(defun markdown--get-remote-image (url)
+ "Retrieve the image path for a given URL."
+ (or (gethash url markdown--remote-image-cache)
+ (let ((dl-path (make-temp-file "markdown-mode--image")))
+ (require 'url)
+ (url-copy-file url dl-path t)
+ (puthash url dl-path markdown--remote-image-cache))))
+
+(defun markdown-display-inline-images ()
+ "Add inline image overlays to image links in the buffer.
+This can be toggled with `markdown-toggle-inline-images'
+or \\[markdown-toggle-inline-images]."
+ (interactive)
+ (unless (display-images-p)
+ (error "Cannot show images"))
+ (save-excursion
+ (save-restriction
+ (widen)
+ (goto-char (point-min))
+ (while (re-search-forward markdown-regex-link-inline nil t)
+ (let* ((start (match-beginning 0))
+ (imagep (match-beginning 1))
+ (end (match-end 0))
+ (file (match-string-no-properties 6)))
+ (when (and imagep
+ (not (zerop (length file))))
+ (unless (file-exists-p file)
+ (let* ((download-file (funcall markdown-translate-filename-function file))
+ (valid-url (ignore-errors
+ (member (downcase (url-type (url-generic-parse-url download-file)))
+ markdown-remote-image-protocols))))
+ (if (and markdown-display-remote-images valid-url)
+ (setq file (markdown--get-remote-image download-file))
+ (when (not valid-url)
+ ;; strip query parameter
+ (setq file (replace-regexp-in-string "?.+\\'" "" file))
+ (unless (file-exists-p file)
+ (setq file (url-unhex-string file)))))))
+ (when (file-exists-p file)
+ (let* ((abspath (if (file-name-absolute-p file)
+ file
+ (concat default-directory file)))
+ (image
+ (cond ((and markdown-max-image-size
+ (image-type-available-p 'imagemagick))
+ (create-image
+ abspath 'imagemagick nil
+ :max-width (car markdown-max-image-size)
+ :max-height (cdr markdown-max-image-size)))
+ (markdown-max-image-size
+ (create-image abspath nil nil
+ :max-width (car markdown-max-image-size)
+ :max-height (cdr markdown-max-image-size)))
+ (t (create-image abspath)))))
+ (when image
+ (let ((ov (make-overlay start end)))
+ (overlay-put ov 'display image)
+ (overlay-put ov 'face 'default)
+ (push ov markdown-inline-image-overlays)))))))))))
+
+(defun markdown-toggle-inline-images ()
+ "Toggle inline image overlays in the buffer."
+ (interactive)
+ (if markdown-inline-image-overlays
+ (markdown-remove-inline-images)
+ (markdown-display-inline-images)))
+
+
+;;; GFM Code Block Fontification ==============================================
+
+(defcustom markdown-fontify-code-blocks-natively nil
+ "When non-nil, fontify code in code blocks using the native major mode.
+This only works for fenced code blocks where the language is
+specified where we can automatically determine the appropriate
+mode to use. The language to mode mapping may be customized by
+setting the variable `markdown-code-lang-modes'."
+ :group 'markdown
+ :type 'boolean
+ :safe #'booleanp
+ :package-version '(markdown-mode . "2.3"))
+
+(defcustom markdown-fontify-code-block-default-mode nil
+ "Default mode to use to fontify code blocks.
+This mode is used when automatic detection fails, such as for GFM
+code blocks with no language specified."
+ :group 'markdown
+ :type '(choice function (const :tag "None" nil))
+ :package-version '(markdown-mode . "2.4"))
+
+(defun markdown-toggle-fontify-code-blocks-natively (&optional arg)
+ "Toggle the native fontification of code blocks.
+With a prefix argument ARG, enable if ARG is positive,
+and disable otherwise."
+ (interactive (list (or current-prefix-arg 'toggle)))
+ (setq markdown-fontify-code-blocks-natively
+ (if (eq arg 'toggle)
+ (not markdown-fontify-code-blocks-natively)
+ (> (prefix-numeric-value arg) 0)))
+ (if markdown-fontify-code-blocks-natively
+ (message "markdown-mode native code block fontification enabled")
+ (message "markdown-mode native code block fontification disabled"))
+ (markdown-reload-extensions))
+
+;; This is based on `org-src-lang-modes' from org-src.el
+(defcustom markdown-code-lang-modes
+ '(("ocaml" . tuareg-mode) ("elisp" . emacs-lisp-mode) ("ditaa" . artist-mode)
+ ("asymptote" . asy-mode) ("dot" . fundamental-mode) ("sqlite" . sql-mode)
+ ("calc" . fundamental-mode) ("C" . c-mode) ("cpp" . c++-mode)
+ ("C++" . c++-mode) ("screen" . shell-script-mode) ("shell" . sh-mode)
+ ("bash" . sh-mode))
+ "Alist mapping languages to their major mode.
+The key is the language name, the value is the major mode. For
+many languages this is simple, but for language where this is not
+the case, this variable provides a way to simplify things on the
+user side. For example, there is no ocaml-mode in Emacs, but the
+mode to use is `tuareg-mode'."
+ :group 'markdown
+ :type '(repeat
+ (cons
+ (string "Language name")
+ (symbol "Major mode")))
+ :package-version '(markdown-mode . "2.3"))
+
+(defun markdown-get-lang-mode (lang)
+ "Return major mode that should be used for LANG.
+LANG is a string, and the returned major mode is a symbol."
+ (cl-find-if
+ 'fboundp
+ (list (cdr (assoc lang markdown-code-lang-modes))
+ (cdr (assoc (downcase lang) markdown-code-lang-modes))
+ (intern (concat lang "-mode"))
+ (intern (concat (downcase lang) "-mode")))))
+
+(defun markdown-fontify-code-blocks-generic (matcher last)
+ "Add text properties to next code block from point to LAST.
+Use matching function MATCHER."
+ (when (funcall matcher last)
+ (save-excursion
+ (save-match-data
+ (let* ((start (match-beginning 0))
+ (end (match-end 0))
+ ;; Find positions outside opening and closing backquotes.
+ (bol-prev (progn (goto-char start)
+ (if (bolp) (point-at-bol 0) (point-at-bol))))
+ (eol-next (progn (goto-char end)
+ (if (bolp) (point-at-bol 2) (point-at-bol 3))))
+ lang)
+ (if (and markdown-fontify-code-blocks-natively
+ (or (setq lang (markdown-code-block-lang))
+ markdown-fontify-code-block-default-mode))
+ (markdown-fontify-code-block-natively lang start end)
+ (add-text-properties start end '(face markdown-pre-face)))
+ ;; Set background for block as well as opening and closing lines.
+ (font-lock-append-text-property
+ bol-prev eol-next 'face 'markdown-code-face)
+ ;; Set invisible property for lines before and after, including newline.
+ (add-text-properties bol-prev start '(invisible markdown-markup))
+ (add-text-properties end eol-next '(invisible markdown-markup)))))
+ t))
+
+(defun markdown-fontify-gfm-code-blocks (last)
+ "Add text properties to next GFM code block from point to LAST."
+ (markdown-fontify-code-blocks-generic 'markdown-match-gfm-code-blocks last))
+
+(defun markdown-fontify-fenced-code-blocks (last)
+ "Add text properties to next tilde fenced code block from point to LAST."
+ (markdown-fontify-code-blocks-generic 'markdown-match-fenced-code-blocks last))
+
+;; Based on `org-src-font-lock-fontify-block' from org-src.el.
+(defun markdown-fontify-code-block-natively (lang start end)
+ "Fontify given GFM or fenced code block.
+This function is called by Emacs for automatic fontification when
+`markdown-fontify-code-blocks-natively' is non-nil. LANG is the
+language used in the block. START and END specify the block
+position."
+ (let ((lang-mode (if lang (markdown-get-lang-mode lang)
+ markdown-fontify-code-block-default-mode)))
+ (when (fboundp lang-mode)
+ (let ((string (buffer-substring-no-properties start end))
+ (modified (buffer-modified-p))
+ (markdown-buffer (current-buffer)) pos next)
+ (remove-text-properties start end '(face nil))
+ (with-current-buffer
+ (get-buffer-create
+ (concat " markdown-code-fontification:" (symbol-name lang-mode)))
+ ;; Make sure that modification hooks are not inhibited in
+ ;; the org-src-fontification buffer in case we're called
+ ;; from `jit-lock-function' (Bug#25132).
+ (let ((inhibit-modification-hooks nil))
+ (delete-region (point-min) (point-max))
+ (insert string " ")) ;; so there's a final property change
+ (unless (eq major-mode lang-mode) (funcall lang-mode))
+ (font-lock-ensure)
+ (setq pos (point-min))
+ (while (setq next (next-single-property-change pos 'face))
+ (let ((val (get-text-property pos 'face)))
+ (when val
+ (put-text-property
+ (+ start (1- pos)) (1- (+ start next)) 'face
+ val markdown-buffer)))
+ (setq pos next)))
+ (add-text-properties
+ start end
+ '(font-lock-fontified t fontified t font-lock-multiline t))
+ (set-buffer-modified-p modified)))))
+
+(require 'edit-indirect nil t)
+(defvar edit-indirect-guess-mode-function)
+(defvar edit-indirect-after-commit-functions)
+
+(defun markdown--edit-indirect-after-commit-function (beg end)
+ "Corrective logic run on code block content from lines BEG to END.
+Restores code block indentation from BEG to END, and ensures trailing newlines
+at the END of code blocks."
+ ;; ensure trailing newlines
+ (goto-char end)
+ (unless (eq (char-before) ?\n)
+ (insert "\n"))
+ ;; restore code block indentation
+ (goto-char (- beg 1))
+ (let ((block-indentation (current-indentation)))
+ (when (> block-indentation 0)
+ (indent-rigidly beg end block-indentation)))
+ (font-lock-ensure))
+
+(defun markdown-edit-code-block ()
+ "Edit Markdown code block in an indirect buffer."
+ (interactive)
+ (save-excursion
+ (if (fboundp 'edit-indirect-region)
+ (let* ((bounds (markdown-get-enclosing-fenced-block-construct))
+ (begin (and bounds (not (null (nth 0 bounds))) (goto-char (nth 0 bounds)) (point-at-bol 2)))
+ (end (and bounds(not (null (nth 1 bounds))) (goto-char (nth 1 bounds)) (point-at-bol 1))))
+ (if (and begin end)
+ (let* ((indentation (and (goto-char (nth 0 bounds)) (current-indentation)))
+ (lang (markdown-code-block-lang))
+ (mode (or (and lang (markdown-get-lang-mode lang))
+ markdown-edit-code-block-default-mode))
+ (edit-indirect-guess-mode-function
+ (lambda (_parent-buffer _beg _end)
+ (funcall mode)))
+ (indirect-buf (edit-indirect-region begin end 'display-buffer)))
+ ;; reset `sh-shell' when indirect buffer
+ (when (and (not (member system-type '(ms-dos windows-nt)))
+ (member mode '(shell-script-mode sh-mode))
+ (member lang (append
+ (mapcar (lambda (e) (symbol-name (car e)))
+ sh-ancestor-alist)
+ '("csh" "rc" "sh"))))
+ (with-current-buffer indirect-buf
+ (sh-set-shell lang)))
+ (when (> indentation 0) ;; un-indent in edit-indirect buffer
+ (with-current-buffer indirect-buf
+ (indent-rigidly (point-min) (point-max) (- indentation)))))
+ (user-error "Not inside a GFM or tilde fenced code block")))
+ (when (y-or-n-p "Package edit-indirect needed to edit code blocks. Install it now? ")
+ (progn (package-refresh-contents)
+ (package-install 'edit-indirect)
+ (markdown-edit-code-block))))))
+
+
+;;; Table Editing =============================================================
+
+;; These functions were originally adapted from `org-table.el'.
+
+;; General helper functions
+
+(defmacro markdown--with-gensyms (symbols &rest body)
+ (declare (debug (sexp body)) (indent 1))
+ `(let ,(mapcar (lambda (s)
+ `(,s (make-symbol (concat "--" (symbol-name ',s)))))
+ symbols)
+ ,@body))
+
+(defun markdown--split-string (string &optional separators)
+ "Splits STRING into substrings at SEPARATORS.
+SEPARATORS is a regular expression. If nil it defaults to
+`split-string-default-separators'. This version returns no empty
+strings if there are matches at the beginning and end of string."
+ (let ((start 0) notfirst list)
+ (while (and (string-match
+ (or separators split-string-default-separators)
+ string
+ (if (and notfirst
+ (= start (match-beginning 0))
+ (< start (length string)))
+ (1+ start) start))
+ (< (match-beginning 0) (length string)))
+ (setq notfirst t)
+ (or (eq (match-beginning 0) 0)
+ (and (eq (match-beginning 0) (match-end 0))
+ (eq (match-beginning 0) start))
+ (push (substring string start (match-beginning 0)) list))
+ (setq start (match-end 0)))
+ (or (eq start (length string))
+ (push (substring string start) list))
+ (nreverse list)))
+
+(defun markdown--string-width (s)
+ "Return width of string S.
+This version ignores characters with invisibility property
+`markdown-markup'."
+ (let (b)
+ (when (or (eq t buffer-invisibility-spec)
+ (member 'markdown-markup buffer-invisibility-spec))
+ (while (setq b (text-property-any
+ 0 (length s)
+ 'invisible 'markdown-markup s))
+ (setq s (concat
+ (substring s 0 b)
+ (substring s (or (next-single-property-change
+ b 'invisible s)
+ (length s))))))))
+ (string-width s))
+
+(defun markdown--remove-invisible-markup (s)
+ "Remove Markdown markup from string S.
+This version removes characters with invisibility property
+`markdown-markup'."
+ (let (b)
+ (while (setq b (text-property-any
+ 0 (length s)
+ 'invisible 'markdown-markup s))
+ (setq s (concat
+ (substring s 0 b)
+ (substring s (or (next-single-property-change
+ b 'invisible s)
+ (length s)))))))
+ s)
+
+;; Functions for maintaining tables
+
+(defvar markdown-table-at-point-p-function #'markdown--table-at-point-p
+ "Function to decide if point is inside a table.
+
+The indirection serves to differentiate between standard markdown
+tables and gfm tables which are less strict about the markup.")
+
+(defconst markdown-table-line-regexp "^[ \t]*|"
+ "Regexp matching any line inside a table.")
+
+(defconst markdown-table-hline-regexp "^[ \t]*|[-:]"
+ "Regexp matching hline inside a table.")
+
+(defconst markdown-table-dline-regexp "^[ \t]*|[^-:]"
+ "Regexp matching dline inside a table.")
+
+(defun markdown-table-at-point-p ()
+ "Return non-nil when point is inside a table."
+ (funcall markdown-table-at-point-p-function))
+
+(defun markdown--table-at-point-p ()
+ "Return non-nil when point is inside a table."
+ (save-excursion
+ (beginning-of-line)
+ (and (looking-at-p markdown-table-line-regexp)
+ (not (markdown-code-block-at-point-p)))))
+
+(defconst gfm-table-line-regexp "^.?*|"
+ "Regexp matching any line inside a table.")
+
+(defconst gfm-table-hline-regexp "^-+\\(|-\\)+"
+ "Regexp matching hline inside a table.")
+
+;; GFM simplified tables syntax is as follows:
+;; - A header line for the column names, this is any text
+;; separated by `|'.
+;; - Followed by a string -|-|- ..., the number of dashes is optional
+;; but must be higher than 1. The number of separators should match
+;; the number of columns.
+;; - Followed by the rows of data, which has the same format as the
+;; header line.
+;; Example:
+;;
+;; foo | bar
+;; ------|---------
+;; bar | baz
+;; bar | baz
+(defun gfm--table-at-point-p ()
+ "Return non-nil when point is inside a gfm-compatible table."
+ (or (markdown--table-at-point-p)
+ (save-excursion
+ (beginning-of-line)
+ (when (looking-at-p gfm-table-line-regexp)
+ ;; we might be at the first line of the table, check if the
+ ;; line below is the hline
+ (or (save-excursion
+ (forward-line 1)
+ (looking-at-p gfm-table-hline-regexp))
+ ;; go up to find the header
+ (catch 'done
+ (while (looking-at-p gfm-table-line-regexp)
+ (cond
+ ((looking-at-p gfm-table-hline-regexp)
+ (throw 'done t))
+ ((bobp)
+ (throw 'done nil)))
+ (forward-line -1))
+ nil))))))
+
+(defun markdown-table-hline-at-point-p ()
+ "Return non-nil when point is on a hline in a table.
+This function assumes point is on a table."
+ (save-excursion
+ (beginning-of-line)
+ (looking-at-p markdown-table-hline-regexp)))
+
+(defun markdown-table-begin ()
+ "Find the beginning of the table and return its position.
+This function assumes point is on a table."
+ (save-excursion
+ (while (and (not (bobp))
+ (markdown-table-at-point-p))
+ (forward-line -1))
+ (unless (or (eobp)
+ (markdown-table-at-point-p))
+ (forward-line 1))
+ (point)))
+
+(defun markdown-table-end ()
+ "Find the end of the table and return its position.
+This function assumes point is on a table."
+ (save-excursion
+ (while (and (not (eobp))
+ (markdown-table-at-point-p))
+ (forward-line 1))
+ (point)))
+
+(defun markdown-table-get-dline ()
+ "Return index of the table data line at point.
+This function assumes point is on a table."
+ (let ((pos (point)) (end (markdown-table-end)) (cnt 0))
+ (save-excursion
+ (goto-char (markdown-table-begin))
+ (while (and (re-search-forward
+ markdown-table-dline-regexp end t)
+ (setq cnt (1+ cnt))
+ (< (point-at-eol) pos))))
+ cnt))
+
+(defun markdown--thing-at-wiki-link (pos)
+ (when markdown-enable-wiki-links
+ (save-excursion
+ (save-match-data
+ (goto-char pos)
+ (thing-at-point-looking-at markdown-regex-wiki-link)))))
+
+(defun markdown-table-get-column ()
+ "Return table column at point.
+This function assumes point is on a table."
+ (let ((pos (point)) (cnt 0))
+ (save-excursion
+ (beginning-of-line)
+ (while (search-forward "|" pos t)
+ (when (and (not (looking-back "\\\\|" (line-beginning-position)))
+ (not (markdown--thing-at-wiki-link (match-beginning 0))))
+ (setq cnt (1+ cnt)))))
+ cnt))
+
+(defun markdown-table-get-cell (&optional n)
+ "Return the content of the cell in column N of current row.
+N defaults to column at point. This function assumes point is on
+a table."
+ (and n (markdown-table-goto-column n))
+ (skip-chars-backward "^|\n") (backward-char 1)
+ (if (looking-at "|[^|\r\n]*")
+ (let* ((pos (match-beginning 0))
+ (val (buffer-substring (1+ pos) (match-end 0))))
+ (goto-char (min (point-at-eol) (+ 2 pos)))
+ ;; Trim whitespaces
+ (setq val (replace-regexp-in-string "\\`[ \t]+" "" val)
+ val (replace-regexp-in-string "[ \t]+\\'" "" val)))
+ (forward-char 1) ""))
+
+(defun markdown-table-goto-dline (n)
+ "Go to the Nth data line in the table at point.
+Return t when the line exists, nil otherwise. This function
+assumes point is on a table."
+ (goto-char (markdown-table-begin))
+ (let ((end (markdown-table-end)) (cnt 0))
+ (while (and (re-search-forward
+ markdown-table-dline-regexp end t)
+ (< (setq cnt (1+ cnt)) n)))
+ (= cnt n)))
+
+(defun markdown-table-goto-column (n &optional on-delim)
+ "Go to the Nth column in the table line at point.
+With optional argument ON-DELIM, stop with point before the left
+delimiter of the cell. If there are less than N cells, just go
+beyond the last delimiter. This function assumes point is on a
+table."
+ (beginning-of-line 1)
+ (when (> n 0)
+ (while (and (> n 0) (search-forward "|" (point-at-eol) t))
+ (when (and (not (looking-back "\\\\|" (line-beginning-position)))
+ (not (markdown--thing-at-wiki-link (match-beginning 0))))
+ (cl-decf n)))
+ (if on-delim
+ (backward-char 1)
+ (when (looking-at " ") (forward-char 1)))))
+
+(defmacro markdown-table-save-cell (&rest body)
+ "Save cell at point, execute BODY and restore cell.
+This function assumes point is on a table."
+ (declare (debug (body)))
+ (markdown--with-gensyms (line column)
+ `(let ((,line (copy-marker (line-beginning-position)))
+ (,column (markdown-table-get-column)))
+ (unwind-protect
+ (progn ,@body)
+ (goto-char ,line)
+ (markdown-table-goto-column ,column)
+ (set-marker ,line nil)))))
+
+(defun markdown-table-blank-line (s)
+ "Convert a table line S into a line with blank cells."
+ (if (string-match "^[ \t]*|-" s)
+ (setq s (mapconcat
+ (lambda (x) (if (member x '(?| ?+)) "|" " "))
+ s ""))
+ (with-temp-buffer
+ (insert s)
+ (goto-char (point-min))
+ (when (re-search-forward "|" nil t)
+ (let ((cur (point))
+ ret)
+ (while (re-search-forward "|" nil t)
+ (when (and (not (eql (char-before (match-beginning 0)) ?\\))
+ (not (markdown--thing-at-wiki-link (match-beginning 0))))
+ (push (make-string (- (match-beginning 0) cur) ? ) ret)
+ (setq cur (match-end 0))))
+ (format "|%s|" (string-join (nreverse ret) "|")))))))
+
+(defun markdown-table-colfmt (fmtspec)
+ "Process column alignment specifier FMTSPEC for tables."
+ (when (stringp fmtspec)
+ (mapcar (lambda (x)
+ (cond ((string-match-p "^:.*:$" x) 'c)
+ ((string-match-p "^:" x) 'l)
+ ((string-match-p ":$" x) 'r)
+ (t 'd)))
+ (markdown--split-string fmtspec "\\s-*|\\s-*"))))
+
+(defun markdown--first-column-p (bar-pos)
+ (save-excursion
+ (save-match-data
+ (goto-char bar-pos)
+ (looking-back "^\\s-*" (line-beginning-position)))))
+
+(defun markdown--table-line-to-columns (line)
+ (with-temp-buffer
+ (insert line)
+ (goto-char (point-min))
+ (let ((cur (point))
+ ret)
+ (while (re-search-forward "\\s-*\\(|\\)\\s-*" nil t)
+ (if (markdown--first-column-p (match-beginning 1))
+ (setq cur (match-end 0))
+ (cond ((eql (char-before (match-beginning 1)) ?\\)
+ ;; keep spaces
+ (goto-char (match-end 1)))
+ ((markdown--thing-at-wiki-link (match-beginning 1))) ;; do nothing
+ (t
+ (push (buffer-substring-no-properties cur (match-beginning 0)) ret)
+ (setq cur (match-end 0))))))
+ (when (< cur (length line))
+ (push (buffer-substring-no-properties cur (point-max)) ret))
+ (nreverse ret))))
+
+(defun markdown-table-align ()
+ "Align table at point.
+This function assumes point is on a table."
+ (interactive)
+ (let ((begin (markdown-table-begin))
+ (end (copy-marker (markdown-table-end))))
+ (markdown-table-save-cell
+ (goto-char begin)
+ (let* (fmtspec
+ ;; Store table indent
+ (indent (progn (looking-at "[ \t]*") (match-string 0)))
+ ;; Split table in lines and save column format specifier
+ (lines (mapcar (lambda (l)
+ (if (string-match-p "\\`[ \t]*|[ \t]*[-:]" l)
+ (progn (setq fmtspec (or fmtspec l)) nil) l))
+ (markdown--split-string (buffer-substring begin end) "\n")))
+ ;; Split lines in cells
+ (cells (mapcar (lambda (l) (markdown--table-line-to-columns l))
+ (remq nil lines)))
+ ;; Calculate maximum number of cells in a line
+ (maxcells (if cells
+ (apply #'max (mapcar #'length cells))
+ (user-error "Empty table")))
+ ;; Empty cells to fill short lines
+ (emptycells (make-list maxcells ""))
+ maxwidths)
+ ;; Calculate maximum width for each column
+ (dotimes (i maxcells)
+ (let ((column (mapcar (lambda (x) (or (nth i x) "")) cells)))
+ (push (apply #'max 1 (mapcar #'markdown--string-width column))
+ maxwidths)))
+ (setq maxwidths (nreverse maxwidths))
+ ;; Process column format specifier
+ (setq fmtspec (markdown-table-colfmt fmtspec))
+ ;; Compute formats needed for output of table lines
+ (let ((hfmt (concat indent "|"))
+ (rfmt (concat indent "|"))
+ hfmt1 rfmt1 fmt)
+ (dolist (width maxwidths (setq hfmt (concat (substring hfmt 0 -1) "|")))
+ (setq fmt (pop fmtspec))
+ (cond ((equal fmt 'l) (setq hfmt1 ":%s-|" rfmt1 " %%-%ds |"))
+ ((equal fmt 'r) (setq hfmt1 "-%s:|" rfmt1 " %%%ds |"))
+ ((equal fmt 'c) (setq hfmt1 ":%s:|" rfmt1 " %%-%ds |"))
+ (t (setq hfmt1 "-%s-|" rfmt1 " %%-%ds |")))
+ (setq rfmt (concat rfmt (format rfmt1 width)))
+ (setq hfmt (concat hfmt (format hfmt1 (make-string width ?-)))))
+ ;; Replace modified lines only
+ (dolist (line lines)
+ (let ((line (if line
+ (apply #'format rfmt (append (pop cells) emptycells))
+ hfmt))
+ (previous (buffer-substring (point) (line-end-position))))
+ (if (equal previous line)
+ (forward-line)
+ (insert line "\n")
+ (delete-region (point) (line-beginning-position 2))))))
+ (set-marker end nil)))))
+
+(defun markdown-table-insert-row (&optional arg)
+ "Insert a new row above the row at point into the table.
+With optional argument ARG, insert below the current row."
+ (interactive "P")
+ (unless (markdown-table-at-point-p)
+ (user-error "Not at a table"))
+ (let* ((line (buffer-substring
+ (line-beginning-position) (line-end-position)))
+ (new (markdown-table-blank-line line)))
+ (beginning-of-line (if arg 2 1))
+ (unless (bolp) (insert "\n"))
+ (insert-before-markers new "\n")
+ (beginning-of-line 0)
+ (re-search-forward "| ?" (line-end-position) t)))
+
+(defun markdown-table-delete-row ()
+ "Delete row or horizontal line at point from the table."
+ (interactive)
+ (unless (markdown-table-at-point-p)
+ (user-error "Not at a table"))
+ (let ((col (current-column)))
+ (kill-region (point-at-bol)
+ (min (1+ (point-at-eol)) (point-max)))
+ (unless (markdown-table-at-point-p) (beginning-of-line 0))
+ (move-to-column col)))
+
+(defun markdown-table-move-row (&optional up)
+ "Move table line at point down.
+With optional argument UP, move it up."
+ (interactive "P")
+ (unless (markdown-table-at-point-p)
+ (user-error "Not at a table"))
+ (let* ((col (current-column)) (pos (point))
+ (tonew (if up 0 2)) txt)
+ (beginning-of-line tonew)
+ (unless (markdown-table-at-point-p)
+ (goto-char pos) (user-error "Cannot move row further"))
+ (goto-char pos) (beginning-of-line 1) (setq pos (point))
+ (setq txt (buffer-substring (point) (1+ (point-at-eol))))
+ (delete-region (point) (1+ (point-at-eol)))
+ (beginning-of-line tonew)
+ (insert txt) (beginning-of-line 0)
+ (move-to-column col)))
+
+(defun markdown-table-move-row-up ()
+ "Move table row at point up."
+ (interactive)
+ (markdown-table-move-row 'up))
+
+(defun markdown-table-move-row-down ()
+ "Move table row at point down."
+ (interactive)
+ (markdown-table-move-row nil))
+
+(defun markdown-table-insert-column ()
+ "Insert a new table column."
+ (interactive)
+ (unless (markdown-table-at-point-p)
+ (user-error "Not at a table"))
+ (let* ((col (max 1 (markdown-table-get-column)))
+ (begin (markdown-table-begin))
+ (end (copy-marker (markdown-table-end))))
+ (markdown-table-save-cell
+ (goto-char begin)
+ (while (< (point) end)
+ (markdown-table-goto-column col t)
+ (if (markdown-table-hline-at-point-p)
+ (insert "|---")
+ (insert "| "))
+ (forward-line)))
+ (set-marker end nil)
+ (when markdown-table-align-p
+ (markdown-table-align))))
+
+(defun markdown-table-delete-column ()
+ "Delete column at point from table."
+ (interactive)
+ (unless (markdown-table-at-point-p)
+ (user-error "Not at a table"))
+ (let ((col (markdown-table-get-column))
+ (begin (markdown-table-begin))
+ (end (copy-marker (markdown-table-end))))
+ (markdown-table-save-cell
+ (goto-char begin)
+ (while (< (point) end)
+ (markdown-table-goto-column col t)
+ (and (looking-at "|\\(?:\\\\|\\|[^|\n]\\)+|")
+ (replace-match "|"))
+ (forward-line)))
+ (set-marker end nil)
+ (markdown-table-goto-column (max 1 (1- col)))
+ (when markdown-table-align-p
+ (markdown-table-align))))
+
+(defun markdown-table-move-column (&optional left)
+ "Move table column at point to the right.
+With optional argument LEFT, move it to the left."
+ (interactive "P")
+ (unless (markdown-table-at-point-p)
+ (user-error "Not at a table"))
+ (let* ((col (markdown-table-get-column))
+ (col1 (if left (1- col) col))
+ (colpos (if left (1- col) (1+ col)))
+ (begin (markdown-table-begin))
+ (end (copy-marker (markdown-table-end))))
+ (when (and left (= col 1))
+ (user-error "Cannot move column further left"))
+ (when (and (not left) (looking-at "[^|\n]*|[^|\n]*$"))
+ (user-error "Cannot move column further right"))
+ (markdown-table-save-cell
+ (goto-char begin)
+ (while (< (point) end)
+ (markdown-table-goto-column col1 t)
+ (when (looking-at "|\\(\\(?:\\\\|\\|[^|\n]\\|\\)+\\)|\\(\\(?:\\\\|\\|[^|\n]\\|\\)+\\)|")
+ (replace-match "|\\2|\\1|"))
+ (forward-line)))
+ (set-marker end nil)
+ (markdown-table-goto-column colpos)
+ (when markdown-table-align-p
+ (markdown-table-align))))
+
+(defun markdown-table-move-column-left ()
+ "Move table column at point to the left."
+ (interactive)
+ (markdown-table-move-column 'left))
+
+(defun markdown-table-move-column-right ()
+ "Move table column at point to the right."
+ (interactive)
+ (markdown-table-move-column nil))
+
+(defun markdown-table-next-row ()
+ "Go to the next row (same column) in the table.
+Create new table lines if required."
+ (interactive)
+ (unless (markdown-table-at-point-p)
+ (user-error "Not at a table"))
+ (if (or (looking-at "[ \t]*$")
+ (save-excursion (skip-chars-backward " \t") (bolp)))
+ (newline)
+ (when markdown-table-align-p
+ (markdown-table-align))
+ (let ((col (markdown-table-get-column)))
+ (beginning-of-line 2)
+ (if (or (not (markdown-table-at-point-p))
+ (markdown-table-hline-at-point-p))
+ (progn
+ (beginning-of-line 0)
+ (markdown-table-insert-row 'below)))
+ (markdown-table-goto-column col)
+ (skip-chars-backward "^|\n\r")
+ (when (looking-at " ") (forward-char 1)))))
+
+(defun markdown-table-forward-cell ()
+ "Go to the next cell in the table.
+Create new table lines if required."
+ (interactive)
+ (unless (markdown-table-at-point-p)
+ (user-error "Not at a table"))
+ (when markdown-table-align-p
+ (markdown-table-align))
+ (let ((end (markdown-table-end)))
+ (when (markdown-table-hline-at-point-p) (end-of-line 1))
+ (condition-case nil
+ (progn
+ (re-search-forward "\\(?:^\\|[^\\]\\)|" end)
+ (when (looking-at "[ \t]*$")
+ (re-search-forward "\\(?:^\\|[^\\]:\\)|" end))
+ (when (and (looking-at "[-:]")
+ (re-search-forward "^\\(?:[ \t]*\\|[^\\]\\)|\\([^-:]\\)" end t))
+ (goto-char (match-beginning 1)))
+ (if (looking-at "[-:]")
+ (progn
+ (beginning-of-line 0)
+ (markdown-table-insert-row 'below))
+ (when (looking-at " ") (forward-char 1))))
+ (error (markdown-table-insert-row 'below)))))
+
+(defun markdown-table-backward-cell ()
+ "Go to the previous cell in the table."
+ (interactive)
+ (unless (markdown-table-at-point-p)
+ (user-error "Not at a table"))
+ (when markdown-table-align-p
+ (markdown-table-align))
+ (when (markdown-table-hline-at-point-p) (beginning-of-line 1))
+ (condition-case nil
+ (progn
+ (re-search-backward "\\(?:^\\|[^\\]\\)|" (markdown-table-begin))
+ ;; When this function is called while in the first cell in a
+ ;; table, the point will now be at the beginning of a line. In
+ ;; this case, we need to move past one additional table
+ ;; boundary, the end of the table on the previous line.
+ (when (= (point) (line-beginning-position))
+ (re-search-backward "\\(?:^\\|[^\\]\\)|" (markdown-table-begin)))
+ (re-search-backward "\\(?:^\\|[^\\]\\)|" (markdown-table-begin)))
+ (error (user-error "Cannot move to previous table cell")))
+ (when (looking-at "\\(?:^\\|[^\\]\\)| ?") (goto-char (match-end 0)))
+
+ ;; This may have dropped point on the hline.
+ (when (markdown-table-hline-at-point-p)
+ (markdown-table-backward-cell)))
+
+(defun markdown-table-transpose ()
+ "Transpose table at point.
+Horizontal separator lines will be eliminated."
+ (interactive)
+ (unless (markdown-table-at-point-p)
+ (user-error "Not at a table"))
+ (let* ((table (buffer-substring-no-properties
+ (markdown-table-begin) (markdown-table-end)))
+ ;; Convert table to Lisp structure
+ (table (delq nil
+ (mapcar
+ (lambda (x)
+ (unless (string-match-p
+ markdown-table-hline-regexp x)
+ (markdown--table-line-to-columns x)))
+ (markdown--split-string table "[ \t]*\n[ \t]*"))))
+ (dline_old (markdown-table-get-dline))
+ (col_old (markdown-table-get-column))
+ (contents (mapcar (lambda (_)
+ (let ((tp table))
+ (mapcar
+ (lambda (_)
+ (prog1
+ (pop (car tp))
+ (setq tp (cdr tp))))
+ table)))
+ (car table))))
+ (goto-char (markdown-table-begin))
+ (save-excursion
+ (re-search-forward "|") (backward-char)
+ (delete-region (point) (markdown-table-end))
+ (insert (mapconcat
+ (lambda(x)
+ (concat "| " (mapconcat 'identity x " | " ) " |\n"))
+ contents "")))
+ (markdown-table-goto-dline col_old)
+ (markdown-table-goto-column dline_old))
+ (when markdown-table-align-p
+ (markdown-table-align)))
+
+(defun markdown-table-sort-lines (&optional sorting-type)
+ "Sort table lines according to the column at point.
+
+The position of point indicates the column to be used for
+sorting, and the range of lines is the range between the nearest
+horizontal separator lines, or the entire table of no such lines
+exist. If point is before the first column, user will be prompted
+for the sorting column. If there is an active region, the mark
+specifies the first line and the sorting column, while point
+should be in the last line to be included into the sorting.
+
+The command then prompts for the sorting type which can be
+alphabetically or numerically. Sorting in reverse order is also
+possible.
+
+If SORTING-TYPE is specified when this function is called from a
+Lisp program, no prompting will take place. SORTING-TYPE must be
+a character, any of (?a ?A ?n ?N) where the capital letters
+indicate that sorting should be done in reverse order."
+ (interactive)
+ (unless (markdown-table-at-point-p)
+ (user-error "Not at a table"))
+ ;; Set sorting type and column used for sorting
+ (let ((column (let ((c (markdown-table-get-column)))
+ (cond ((> c 0) c)
+ ((called-interactively-p 'any)
+ (read-number "Use column N for sorting: "))
+ (t 1))))
+ (sorting-type
+ (or sorting-type
+ (progn
+ ;; workaround #641
+ ;; Emacs < 28 hides prompt message by another message. This erases it.
+ (message "")
+ (read-char-exclusive
+ "Sort type: [a]lpha [n]umeric (A/N means reversed): ")))))
+ (save-restriction
+ ;; Narrow buffer to appropriate sorting area
+ (if (region-active-p)
+ (narrow-to-region
+ (save-excursion
+ (progn
+ (goto-char (region-beginning)) (line-beginning-position)))
+ (save-excursion
+ (progn
+ (goto-char (region-end)) (line-end-position))))
+ (let ((start (markdown-table-begin))
+ (end (markdown-table-end)))
+ (narrow-to-region
+ (save-excursion
+ (if (re-search-backward
+ markdown-table-hline-regexp start t)
+ (line-beginning-position 2)
+ start))
+ (if (save-excursion (re-search-forward
+ markdown-table-hline-regexp end t))
+ (match-beginning 0)
+ end))))
+ ;; Determine arguments for `sort-subr'
+ (let* ((extract-key-from-cell
+ (cl-case sorting-type
+ ((?a ?A) #'markdown--remove-invisible-markup) ;; #'identity)
+ ((?n ?N) #'string-to-number)
+ (t (user-error "Invalid sorting type: %c" sorting-type))))
+ (predicate
+ (cl-case sorting-type
+ ((?n ?N) #'<)
+ ((?a ?A) #'string<))))
+ ;; Sort selected area
+ (goto-char (point-min))
+ (sort-subr (memq sorting-type '(?A ?N))
+ (lambda ()
+ (forward-line)
+ (while (and (not (eobp))
+ (not (looking-at
+ markdown-table-dline-regexp)))
+ (forward-line)))
+ #'end-of-line
+ (lambda ()
+ (funcall extract-key-from-cell
+ (markdown-table-get-cell column)))
+ nil
+ predicate)
+ (goto-char (point-min))))))
+
+(defun markdown-table-convert-region (begin end &optional separator)
+ "Convert region from BEGIN to END to table with SEPARATOR.
+
+If every line contains at least one TAB character, the function
+assumes that the material is tab separated (TSV). If every line
+contains a comma, comma-separated values (CSV) are assumed. If
+not, lines are split at whitespace into cells.
+
+You can use a prefix argument to force a specific separator:
+\\[universal-argument] once forces CSV, \\[universal-argument]
+twice forces TAB, and \\[universal-argument] three times will
+prompt for a regular expression to match the separator, and a
+numeric argument N indicates that at least N consecutive
+spaces, or alternatively a TAB should be used as the separator."
+
+ (interactive "r\nP")
+ (let* ((begin (min begin end)) (end (max begin end)) re)
+ (goto-char begin) (beginning-of-line 1)
+ (setq begin (point-marker))
+ (goto-char end)
+ (if (bolp) (backward-char 1) (end-of-line 1))
+ (setq end (point-marker))
+ (when (equal separator '(64))
+ (setq separator (read-regexp "Regexp for cell separator: ")))
+ (unless separator
+ ;; Get the right cell separator
+ (goto-char begin)
+ (setq separator
+ (cond
+ ((not (re-search-forward "^[^\n\t]+$" end t)) '(16))
+ ((not (re-search-forward "^[^\n,]+$" end t)) '(4))
+ (t 1))))
+ (goto-char begin)
+ (if (equal separator '(4))
+ ;; Parse CSV
+ (while (< (point) end)
+ (cond
+ ((looking-at "^") (insert "| "))
+ ((looking-at "[ \t]*$") (replace-match " |") (beginning-of-line 2))
+ ((looking-at "[ \t]*\"\\([^\"\n]*\\)\"")
+ (replace-match "\\1") (if (looking-at "\"") (insert "\"")))
+ ((looking-at "[^,\n]+") (goto-char (match-end 0)))
+ ((looking-at "[ \t]*,") (replace-match " | "))
+ (t (beginning-of-line 2))))
+ (setq re
+ (cond
+ ((equal separator '(4)) "^\\|\"?[ \t]*,[ \t]*\"?")
+ ((equal separator '(16)) "^\\|\t")
+ ((integerp separator)
+ (if (< separator 1)
+ (user-error "Cell separator must contain one or more spaces")
+ (format "^ *\\| *\t *\\| \\{%d,\\}\\|$" separator)))
+ ((stringp separator) (format "^ *\\|%s" separator))
+ (t (error "Invalid cell separator"))))
+ (let (finish)
+ (while (and (not finish) (re-search-forward re end t))
+ (if (eolp)
+ (progn
+ (replace-match "|" t t)
+ (forward-line 1)
+ (when (eobp)
+ (setq finish t)))
+ (replace-match "| " t t)))))
+ (goto-char begin)
+ (when markdown-table-align-p
+ (markdown-table-align))))
+
+(defun markdown-insert-table (&optional rows columns align)
+ "Insert an empty pipe table.
+Optional arguments ROWS, COLUMNS, and ALIGN specify number of
+rows and columns and the column alignment."
+ (interactive)
+ (let* ((rows (or rows (string-to-number (read-string "Row size: "))))
+ (columns (or columns (string-to-number (read-string "Column size: "))))
+ (align (or align (read-string "Alignment ([l]eft, [r]ight, [c]enter, or RET for default): ")))
+ (align (cond ((equal align "l") ":--")
+ ((equal align "r") "--:")
+ ((equal align "c") ":-:")
+ (t "---")))
+ (pos (point))
+ (indent (make-string (current-column) ?\ ))
+ (line (concat
+ (apply 'concat indent "|"
+ (make-list columns " |")) "\n"))
+ (hline (apply 'concat indent "|"
+ (make-list columns (concat align "|")))))
+ (if (string-match
+ "^[ \t]*$" (buffer-substring-no-properties
+ (point-at-bol) (point)))
+ (beginning-of-line 1)
+ (newline))
+ (dotimes (_ rows) (insert line))
+ (goto-char pos)
+ (if (> rows 1)
+ (progn
+ (end-of-line 1) (insert (concat "\n" hline)) (goto-char pos)))
+ (markdown-table-forward-cell)))
+
+
+;;; ElDoc Support =============================================================
+
+(defun markdown-eldoc-function ()
+ "Return a helpful string when appropriate based on context.
+* Report URL when point is at a hidden URL.
+* Report language name when point is a code block with hidden markup."
+ (cond
+ ;; Hidden URL or reference for inline link
+ ((and (or (thing-at-point-looking-at markdown-regex-link-inline)
+ (thing-at-point-looking-at markdown-regex-link-reference))
+ (or markdown-hide-urls markdown-hide-markup))
+ (let* ((imagep (string-equal (match-string 1) "!"))
+ (referencep (string-equal (match-string 5) "["))
+ (link (match-string-no-properties 6))
+ (edit-keys (markdown--substitute-command-keys
+ (if imagep
+ "\\[markdown-insert-image]"
+ "\\[markdown-insert-link]")))
+ (edit-str (propertize edit-keys 'face 'font-lock-constant-face))
+ (object (if referencep "reference" "URL")))
+ (format "Hidden %s (%s to edit): %s" object edit-str
+ (if referencep
+ (concat
+ (propertize "[" 'face 'markdown-markup-face)
+ (propertize link 'face 'markdown-reference-face)
+ (propertize "]" 'face 'markdown-markup-face))
+ (propertize link 'face 'markdown-url-face)))))
+ ;; Hidden language name for fenced code blocks
+ ((and (markdown-code-block-at-point-p)
+ (not (get-text-property (point) 'markdown-pre))
+ markdown-hide-markup)
+ (let ((lang (save-excursion (markdown-code-block-lang))))
+ (unless lang (setq lang "[unspecified]"))
+ (format "Hidden code block language: %s (%s to toggle markup)"
+ (propertize lang 'face 'markdown-language-keyword-face)
+ (markdown--substitute-command-keys
+ "\\[markdown-toggle-markup-hiding]"))))))
+
+
+;;; Mode Definition ==========================================================
+
+(defun markdown-show-version ()
+ "Show the version number in the minibuffer."
+ (interactive)
+ (message "markdown-mode, version %s" markdown-mode-version))
+
+(defun markdown-mode-info ()
+ "Open the `markdown-mode' homepage."
+ (interactive)
+ (browse-url "https://jblevins.org/projects/markdown-mode/"))
+
+;;;###autoload
+(define-derived-mode markdown-mode text-mode "Markdown"
+ "Major mode for editing Markdown files."
+ (when buffer-read-only
+ (when (or (not (buffer-file-name)) (file-writable-p (buffer-file-name)))
+ (setq-local buffer-read-only nil)))
+ ;; Natural Markdown tab width
+ (setq tab-width 4)
+ ;; Comments
+ (setq-local comment-start "<!-- ")
+ (setq-local comment-end " -->")
+ (setq-local comment-start-skip "<!--[ \t]*")
+ (setq-local comment-column 0)
+ (setq-local comment-auto-fill-only-comments nil)
+ (setq-local comment-use-syntax t)
+ ;; Sentence
+ (setq-local sentence-end-base "[.?!…‽][]\"'”’)}»›*_`~]*")
+ ;; Syntax
+ (add-hook 'syntax-propertize-extend-region-functions
+ #'markdown-syntax-propertize-extend-region nil t)
+ (add-hook 'jit-lock-after-change-extend-region-functions
+ #'markdown-font-lock-extend-region-function t t)
+ (setq-local syntax-propertize-function #'markdown-syntax-propertize)
+ (syntax-propertize (point-max)) ;; Propertize before hooks run, etc.
+ ;; Font lock.
+ (setq font-lock-defaults
+ '(markdown-mode-font-lock-keywords
+ nil nil nil nil
+ (font-lock-multiline . t)
+ (font-lock-syntactic-face-function . markdown-syntactic-face)
+ (font-lock-extra-managed-props
+ . (composition display invisible rear-nonsticky
+ keymap help-echo mouse-face))))
+ (if markdown-hide-markup
+ (add-to-invisibility-spec 'markdown-markup)
+ (remove-from-invisibility-spec 'markdown-markup))
+ ;; Wiki links
+ (markdown-setup-wiki-link-hooks)
+ ;; Math mode
+ (when markdown-enable-math (markdown-toggle-math t))
+ ;; Add a buffer-local hook to reload after file-local variables are read
+ (add-hook 'hack-local-variables-hook #'markdown-handle-local-variables nil t)
+ ;; For imenu support
+ (setq imenu-create-index-function
+ (if markdown-nested-imenu-heading-index
+ #'markdown-imenu-create-nested-index
+ #'markdown-imenu-create-flat-index))
+
+ ;; Defun movement
+ (setq-local beginning-of-defun-function #'markdown-beginning-of-defun)
+ (setq-local end-of-defun-function #'markdown-end-of-defun)
+ ;; Paragraph filling
+ (setq-local fill-paragraph-function #'markdown-fill-paragraph)
+ (setq-local paragraph-start
+ ;; Should match start of lines that start or separate paragraphs
+ (mapconcat #'identity
+ '(
+ "\f" ; starts with a literal line-feed
+ "[ \t\f]*$" ; space-only line
+ "\\(?:[ \t]*>\\)+[ \t\f]*$"; empty line in blockquote
+ "[ \t]*[*+-][ \t]+" ; unordered list item
+ "[ \t]*\\(?:[0-9]+\\|#\\)\\.[ \t]+" ; ordered list item
+ "[ \t]*\\[\\S-*\\]:[ \t]+" ; link ref def
+ "[ \t]*:[ \t]+" ; definition
+ "^|" ; table or Pandoc line block
+ )
+ "\\|"))
+ (setq-local paragraph-separate
+ ;; Should match lines that separate paragraphs without being
+ ;; part of any paragraph:
+ (mapconcat #'identity
+ '("[ \t\f]*$" ; space-only line
+ "\\(?:[ \t]*>\\)+[ \t\f]*$"; empty line in blockquote
+ ;; The following is not ideal, but the Fill customization
+ ;; options really only handle paragraph-starting prefixes,
+ ;; not paragraph-ending suffixes:
+ ".* $" ; line ending in two spaces
+ "^#+"
+ "^\\(?: \\)?[-=]+[ \t]*$" ;; setext
+ "[ \t]*\\[\\^\\S-*\\]:[ \t]*$") ; just the start of a footnote def
+ "\\|"))
+ (setq-local adaptive-fill-first-line-regexp "\\`[ \t]*[A-Z]?>[ \t]*?\\'")
+ (setq-local adaptive-fill-regexp "\\s-*")
+ (setq-local adaptive-fill-function #'markdown-adaptive-fill-function)
+ (setq-local fill-forward-paragraph-function #'markdown-fill-forward-paragraph)
+ ;; Outline mode
+ (setq-local outline-regexp markdown-regex-header)
+ (setq-local outline-level #'markdown-outline-level)
+ ;; Cause use of ellipses for invisible text.
+ (add-to-invisibility-spec '(outline . t))
+ ;; ElDoc support
+ (add-function :before-until (local 'eldoc-documentation-function)
+ #'markdown-eldoc-function)
+ ;; Inhibiting line-breaking:
+ ;; Separating out each condition into a separate function so that users can
+ ;; override if desired (with remove-hook)
+ (add-hook 'fill-nobreak-predicate
+ #'markdown-line-is-reference-definition-p nil t)
+ (add-hook 'fill-nobreak-predicate
+ #'markdown-pipe-at-bol-p nil t)
+
+ ;; Indentation
+ (setq-local indent-line-function markdown-indent-function)
+ (setq-local indent-region-function #'markdown--indent-region)
+
+ ;; Flyspell
+ (setq-local flyspell-generic-check-word-predicate
+ #'markdown-flyspell-check-word-p)
+
+ ;; Electric quoting
+ (add-hook 'electric-quote-inhibit-functions
+ #'markdown--inhibit-electric-quote nil :local)
+
+ ;; Make checkboxes buttons
+ (when markdown-make-gfm-checkboxes-buttons
+ (markdown-make-gfm-checkboxes-buttons (point-min) (point-max))
+ (add-hook 'after-change-functions #'markdown-gfm-checkbox-after-change-function t t)
+ (add-hook 'change-major-mode-hook #'markdown-remove-gfm-checkbox-overlays t t))
+
+ ;; edit-indirect
+ (add-hook 'edit-indirect-after-commit-functions
+ #'markdown--edit-indirect-after-commit-function
+ nil 'local)
+
+ ;; Marginalized headings
+ (when markdown-marginalize-headers
+ (add-hook 'window-configuration-change-hook
+ #'markdown-marginalize-update-current nil t))
+
+ ;; add live preview export hook
+ (add-hook 'after-save-hook #'markdown-live-preview-if-markdown t t)
+ (add-hook 'kill-buffer-hook #'markdown-live-preview-remove-on-kill t t))
+
+;;;###autoload
+(add-to-list 'auto-mode-alist
+ '("\\.\\(?:md\\|markdown\\|mkd\\|mdown\\|mkdn\\|mdwn\\)\\'" . markdown-mode))
+
+
+;;; GitHub Flavored Markdown Mode ============================================
+
+(defun gfm--electric-pair-fence-code-block ()
+ (when (and electric-pair-mode
+ (not markdown-gfm-use-electric-backquote)
+ (eql last-command-event ?`)
+ (let ((count 0))
+ (while (eql (char-before (- (point) count)) ?`)
+ (cl-incf count))
+ (= count 3))
+ (eql (char-after) ?`))
+ (save-excursion (insert (make-string 2 ?`)))))
+
+(defvar gfm-mode-hook nil
+ "Hook run when entering GFM mode.")
+
+;;;###autoload
+(define-derived-mode gfm-mode markdown-mode "GFM"
+ "Major mode for editing GitHub Flavored Markdown files."
+ (setq markdown-link-space-sub-char "-")
+ (setq markdown-wiki-link-search-subdirectories t)
+ (setq-local markdown-table-at-point-p-function #'gfm--table-at-point-p)
+ (add-hook 'post-self-insert-hook #'gfm--electric-pair-fence-code-block 'append t)
+ (markdown-gfm-parse-buffer-for-languages))
+
+
+;;; Viewing modes =============================================================
+
+(defcustom markdown-hide-markup-in-view-modes t
+ "Enable hidden markup mode in `markdown-view-mode' and `gfm-view-mode'."
+ :group 'markdown
+ :type 'boolean
+ :safe #'booleanp)
+
+(defvar markdown-view-mode-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map (kbd "p") #'markdown-outline-previous)
+ (define-key map (kbd "n") #'markdown-outline-next)
+ (define-key map (kbd "f") #'markdown-outline-next-same-level)
+ (define-key map (kbd "b") #'markdown-outline-previous-same-level)
+ (define-key map (kbd "u") #'markdown-outline-up)
+ (define-key map (kbd "DEL") #'scroll-down-command)
+ (define-key map (kbd "SPC") #'scroll-up-command)
+ (define-key map (kbd ">") #'end-of-buffer)
+ (define-key map (kbd "<") #'beginning-of-buffer)
+ (define-key map (kbd "q") #'kill-this-buffer)
+ (define-key map (kbd "?") #'describe-mode)
+ map)
+ "Keymap for `markdown-view-mode'.")
+
+(defun markdown--filter-visible (beg end &optional delete)
+ (let ((result "")
+ (invisible-faces '(markdown-header-delimiter-face markdown-header-rule-face)))
+ (while (< beg end)
+ (when (markdown--face-p beg invisible-faces)
+ (cl-incf beg)
+ (while (and (markdown--face-p beg invisible-faces) (< beg end))
+ (cl-incf beg)))
+ (let ((next (next-single-char-property-change beg 'invisible)))
+ (unless (get-char-property beg 'invisible)
+ (setq result (concat result (buffer-substring beg (min end next)))))
+ (setq beg next)))
+ (prog1 result
+ (when delete
+ (let ((inhibit-read-only t))
+ (delete-region beg end))))))
+
+;;;###autoload
+(define-derived-mode markdown-view-mode markdown-mode "Markdown-View"
+ "Major mode for viewing Markdown content."
+ (setq-local markdown-hide-markup markdown-hide-markup-in-view-modes)
+ (add-to-invisibility-spec 'markdown-markup)
+ (setq-local filter-buffer-substring-function #'markdown--filter-visible)
+ (read-only-mode 1))
+
+(defvar gfm-view-mode-map
+ markdown-view-mode-map
+ "Keymap for `gfm-view-mode'.")
+
+;;;###autoload
+(define-derived-mode gfm-view-mode gfm-mode "GFM-View"
+ "Major mode for viewing GitHub Flavored Markdown content."
+ (setq-local markdown-hide-markup markdown-hide-markup-in-view-modes)
+ (setq-local markdown-fontify-code-blocks-natively t)
+ (setq-local filter-buffer-substring-function #'markdown--filter-visible)
+ (add-to-invisibility-spec 'markdown-markup)
+ (read-only-mode 1))
+
+
+;;; Live Preview Mode ========================================================
+;;;###autoload
+(define-minor-mode markdown-live-preview-mode
+ "Toggle native previewing on save for a specific markdown file."
+ :lighter " MD-Preview"
+ (if markdown-live-preview-mode
+ (if (markdown-live-preview-get-filename)
+ (markdown-display-buffer-other-window (markdown-live-preview-export))
+ (markdown-live-preview-mode -1)
+ (user-error "Buffer %s does not visit a file" (current-buffer)))
+ (markdown-live-preview-remove)))
+
+
+(provide 'markdown-mode)
+
+;; Local Variables:
+;; indent-tabs-mode: nil
+;; coding: utf-8
+;; End:
+;;; markdown-mode.el ends here
diff --git a/elpa/markdown-mode-20220406.410/markdown-mode.elc b/elpa/markdown-mode-20220406.410/markdown-mode.elc
new file mode 100644
index 0000000..6e105f6
--- /dev/null
+++ b/elpa/markdown-mode-20220406.410/markdown-mode.elc
Binary files differ
diff --git a/elpa/org-bullets-20200317.1740/org-bullets-autoloads.el b/elpa/org-bullets-20200317.1740/org-bullets-autoloads.el
new file mode 100644
index 0000000..017bcca
--- /dev/null
+++ b/elpa/org-bullets-20200317.1740/org-bullets-autoloads.el
@@ -0,0 +1,41 @@
+;;; org-bullets-autoloads.el --- automatically extracted autoloads -*- lexical-binding: t -*-
+;;
+;;; Code:
+
+(add-to-list 'load-path (directory-file-name
+ (or (file-name-directory #$) (car load-path))))
+
+
+;;;### (autoloads nil "org-bullets" "org-bullets.el" (0 0 0 0))
+;;; Generated autoloads from org-bullets.el
+
+(autoload 'org-bullets-mode "org-bullets" "\
+Use UTF8 bullets in Org mode headings.
+
+This is a minor mode. If called interactively, toggle the
+`Org-Bullets mode' mode. If the prefix argument is positive,
+enable the mode, and if it is zero or negative, disable the mode.
+
+If called from Lisp, toggle the mode if ARG is `toggle'. Enable
+the mode if ARG is nil, omitted, or is a positive number.
+Disable the mode if ARG is a negative number.
+
+To check whether the minor mode is enabled in the current buffer,
+evaluate `org-bullets-mode'.
+
+The mode's hook is called both when the mode is enabled and when
+it is disabled.
+
+\(fn &optional ARG)" t nil)
+
+(register-definition-prefixes "org-bullets" '("org-bullets-"))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; coding: utf-8
+;; End:
+;;; org-bullets-autoloads.el ends here
diff --git a/elpa/org-bullets-20200317.1740/org-bullets-pkg.el b/elpa/org-bullets-20200317.1740/org-bullets-pkg.el
new file mode 100644
index 0000000..69572a2
--- /dev/null
+++ b/elpa/org-bullets-20200317.1740/org-bullets-pkg.el
@@ -0,0 +1,2 @@
+;;; Generated package description from org-bullets.el -*- no-byte-compile: t -*-
+(define-package "org-bullets" "20200317.1740" "Show bullets in org-mode as UTF-8 characters" 'nil :commit "767f55feb58b840a5a04eabfc3fbbf0d257c4792" :authors '(("sabof")) :maintainer '("D. Williams" . "d.williams@posteo.net") :url "https://github.com/integral-dw/org-bullets")
diff --git a/elpa/org-bullets-20200317.1740/org-bullets.el b/elpa/org-bullets-20200317.1740/org-bullets.el
new file mode 100644
index 0000000..44ad4a8
--- /dev/null
+++ b/elpa/org-bullets-20200317.1740/org-bullets.el
@@ -0,0 +1,138 @@
+;;; org-bullets.el --- Show bullets in org-mode as UTF-8 characters
+
+;; Version: 0.3.0
+;; Package-Version: 20200317.1740
+;; Package-Commit: 767f55feb58b840a5a04eabfc3fbbf0d257c4792
+;; Author: sabof
+;; Maintainer: D. Williams <d.williams@posteo.net>
+;; Homepage: https://github.com/integral-dw/org-bullets
+
+;; This file is NOT part of GNU 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 3, 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.
+
+;; For a full copy of the GNU General Public License
+;; see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Show org-mode bullets as UTF-8 characters.
+
+;; This is a legacy package maintained with a focus on preservation.
+;; It has an unofficial successor package (org-superstar). This means
+;; that new features will no longer be added, and backwards
+;; compatibility will be preserved.
+
+;; It's unofficial successor package is available on MELPA. You can
+;; also find it on GitHub:
+;; https://github.com/integral-dw/org-superstar-mode
+
+;;; Code:
+
+(require 'org)
+
+(defgroup org-bullets nil
+ "Display bullets as UTF-8 characters."
+ :group 'org-appearance)
+
+;; A nice collection of unicode bullets:
+;; http://nadeausoftware.com/articles/2007/11/latency_friendly_customized_bullets_using_unicode_characters
+(defcustom org-bullets-bullet-list
+ '(;;; Large
+ "◉"
+ "○"
+ "✸"
+ "✿"
+ ;; ♥ ● ◇ ✚ ✜ ☯ ◆ ♠ ♣ ♦ ☢ ❀ ◆ ◖ ▶
+ ;;; Small
+ ;; ► • ★ ▸
+ )
+ "List of bullets used in Org headings.
+It can contain any number of symbols, which will be repeated."
+ :group 'org-bullets
+ :type '(repeat (string :tag "Bullet character")))
+
+(defcustom org-bullets-face-name nil
+ "Face used for bullets in Org mode headings.
+If set to the name of a face, that face is used.
+Otherwise the face of the heading level is used."
+ :group 'org-bullets
+ :type 'symbol)
+
+(defvar org-bullets-bullet-map (make-sparse-keymap))
+
+(defun org-bullets-level-char (level)
+ "Return the desired bullet for the given heading LEVEL."
+ (string-to-char
+ (nth (mod (/ (1- level) (if org-odd-levels-only 2 1))
+ (length org-bullets-bullet-list))
+ org-bullets-bullet-list)))
+
+(defvar org-bullets--keywords
+ `(("^\\*+ "
+ (0 (let* ((level (- (match-end 0) (match-beginning 0) 1))
+ (is-inline-task
+ (and (boundp 'org-inlinetask-min-level)
+ (>= level org-inlinetask-min-level))))
+ (compose-region (- (match-end 0) 2)
+ (- (match-end 0) 1)
+ (org-bullets-level-char level))
+ (when is-inline-task
+ (compose-region (- (match-end 0) 3)
+ (- (match-end 0) 2)
+ (org-bullets-level-char level)))
+ (when (facep org-bullets-face-name)
+ (put-text-property (- (match-end 0)
+ (if is-inline-task 3 2))
+ (- (match-end 0) 1)
+ 'face
+ org-bullets-face-name))
+ (put-text-property (match-beginning 0)
+ (- (match-end 0) 2)
+ 'face 'org-hide)
+ (put-text-property (match-beginning 0)
+ (match-end 0)
+ 'keymap
+ org-bullets-bullet-map)
+ nil)))))
+
+;;;###autoload
+(define-minor-mode org-bullets-mode
+ "Use UTF8 bullets in Org mode headings."
+ nil nil nil
+ (if org-bullets-mode
+ (progn
+ (font-lock-add-keywords nil org-bullets--keywords)
+ (org-bullets--fontify-buffer))
+ (save-excursion
+ (goto-char (point-min))
+ (font-lock-remove-keywords nil org-bullets--keywords)
+ (while (re-search-forward "^\\*+ " nil t)
+ (decompose-region (match-beginning 0) (match-end 0)))
+ (org-bullets--fontify-buffer))))
+
+(defun org-bullets--fontify-buffer ()
+ "Fontify the current buffer."
+ (when font-lock-mode
+ (if (and (fboundp 'font-lock-flush)
+ (fboundp 'font-lock-ensure))
+ (save-restriction
+ (widen)
+ (font-lock-flush)
+ (font-lock-ensure))
+ (with-no-warnings
+ (font-lock-fontify-buffer)))))
+
+(provide 'org-bullets)
+;; Local Variables:
+;; indent-tabs-mode: nil
+;; End:
+;;; org-bullets.el ends here
diff --git a/elpa/org-bullets-20200317.1740/org-bullets.elc b/elpa/org-bullets-20200317.1740/org-bullets.elc
new file mode 100644
index 0000000..7841f24
--- /dev/null
+++ b/elpa/org-bullets-20200317.1740/org-bullets.elc
Binary files differ
diff --git a/elpa/pkg-info-20150517.1143/pkg-info-autoloads.el b/elpa/pkg-info-20150517.1143/pkg-info-autoloads.el
new file mode 100644
index 0000000..c64ff30
--- /dev/null
+++ b/elpa/pkg-info-20150517.1143/pkg-info-autoloads.el
@@ -0,0 +1,127 @@
+;;; pkg-info-autoloads.el --- automatically extracted autoloads -*- lexical-binding: t -*-
+;;
+;;; Code:
+
+(add-to-list 'load-path (directory-file-name
+ (or (file-name-directory #$) (car load-path))))
+
+
+;;;### (autoloads nil "pkg-info" "pkg-info.el" (0 0 0 0))
+;;; Generated autoloads from pkg-info.el
+
+(autoload 'pkg-info-library-original-version "pkg-info" "\
+Get the original version in the header of LIBRARY.
+
+The original version is stored in the X-Original-Version header.
+This header is added by the MELPA package archive to preserve
+upstream version numbers.
+
+LIBRARY is either a symbol denoting a named feature, or a library
+name as string.
+
+If SHOW is non-nil, show the version in the minibuffer.
+
+Return the version from the header of LIBRARY as list. Signal an
+error if the LIBRARY was not found or had no X-Original-Version
+header.
+
+See Info node `(elisp)Library Headers' for more information
+about library headers.
+
+\(fn LIBRARY &optional SHOW)" t nil)
+
+(autoload 'pkg-info-library-version "pkg-info" "\
+Get the version in the header of LIBRARY.
+
+LIBRARY is either a symbol denoting a named feature, or a library
+name as string.
+
+If SHOW is non-nil, show the version in the minibuffer.
+
+Return the version from the header of LIBRARY as list. Signal an
+error if the LIBRARY was not found or had no proper header.
+
+See Info node `(elisp)Library Headers' for more information
+about library headers.
+
+\(fn LIBRARY &optional SHOW)" t nil)
+
+(autoload 'pkg-info-defining-library-original-version "pkg-info" "\
+Get the original version of the library defining FUNCTION.
+
+The original version is stored in the X-Original-Version header.
+This header is added by the MELPA package archive to preserve
+upstream version numbers.
+
+If SHOW is non-nil, show the version in mini-buffer.
+
+This function is mainly intended to find the version of a major
+or minor mode, i.e.
+
+ (pkg-info-defining-library-version 'flycheck-mode)
+
+Return the version of the library defining FUNCTION. Signal an
+error if FUNCTION is not a valid function, if its defining
+library was not found, or if the library had no proper version
+header.
+
+\(fn FUNCTION &optional SHOW)" t nil)
+
+(autoload 'pkg-info-defining-library-version "pkg-info" "\
+Get the version of the library defining FUNCTION.
+
+If SHOW is non-nil, show the version in mini-buffer.
+
+This function is mainly intended to find the version of a major
+or minor mode, i.e.
+
+ (pkg-info-defining-library-version 'flycheck-mode)
+
+Return the version of the library defining FUNCTION. Signal an
+error if FUNCTION is not a valid function, if its defining
+library was not found, or if the library had no proper version
+header.
+
+\(fn FUNCTION &optional SHOW)" t nil)
+
+(autoload 'pkg-info-package-version "pkg-info" "\
+Get the version of an installed PACKAGE.
+
+If SHOW is non-nil, show the version in the minibuffer.
+
+Return the version as list, or nil if PACKAGE is not installed.
+
+\(fn PACKAGE &optional SHOW)" t nil)
+
+(autoload 'pkg-info-version-info "pkg-info" "\
+Obtain complete version info for LIBRARY and PACKAGE.
+
+LIBRARY is a symbol denoting a named feature, or a library name
+as string. PACKAGE is a symbol denoting an ELPA package. If
+omitted or nil, default to LIBRARY.
+
+If SHOW is non-nil, show the version in the minibuffer.
+
+When called interactively, prompt for LIBRARY. When called
+interactively with prefix argument, prompt for PACKAGE as well.
+
+Return a string with complete version information for LIBRARY.
+This version information contains the version from the headers of
+LIBRARY, and the version of the installed PACKAGE, the LIBRARY is
+part of. If PACKAGE is not installed, or if the PACKAGE version
+is the same as the LIBRARY version, do not include a package
+version.
+
+\(fn LIBRARY &optional PACKAGE SHOW)" t nil)
+
+(register-definition-prefixes "pkg-info" '("pkg-info-"))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; coding: utf-8
+;; End:
+;;; pkg-info-autoloads.el ends here
diff --git a/elpa/pkg-info-20150517.1143/pkg-info-pkg.el b/elpa/pkg-info-20150517.1143/pkg-info-pkg.el
new file mode 100644
index 0000000..e8c9cc0
--- /dev/null
+++ b/elpa/pkg-info-20150517.1143/pkg-info-pkg.el
@@ -0,0 +1,2 @@
+;;; Generated package description from pkg-info.el -*- no-byte-compile: t -*-
+(define-package "pkg-info" "20150517.1143" "Information about packages" '((epl "0.8")) :commit "76ba7415480687d05a4353b27fea2ae02b8d9d61" :authors '(("Sebastian Wiesner" . "swiesner@lunaryorn.com")) :maintainer '("Sebastian Wiesner" . "swiesner@lunaryorn.com") :keywords '("convenience") :url "https://github.com/lunaryorn/pkg-info.el")
diff --git a/elpa/pkg-info-20150517.1143/pkg-info.el b/elpa/pkg-info-20150517.1143/pkg-info.el
new file mode 100644
index 0000000..1017a37
--- /dev/null
+++ b/elpa/pkg-info-20150517.1143/pkg-info.el
@@ -0,0 +1,332 @@
+;;; pkg-info.el --- Information about packages -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2013-2015 Sebastian Wiesner <swiesner@lunaryorn.com>
+
+;; Author: Sebastian Wiesner <swiesner@lunaryorn.com>
+;; URL: https://github.com/lunaryorn/pkg-info.el
+;; Package-Version: 20150517.1143
+;; Package-Commit: 76ba7415480687d05a4353b27fea2ae02b8d9d61
+;; Keywords: convenience
+;; Version: 0.7-cvs
+;; Package-Requires: ((epl "0.8"))
+
+;; 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 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 library extracts information from installed packages.
+
+;;;; Functions:
+
+;; `pkg-info-library-version' extracts the version from the header of a library.
+;;
+;; `pkg-info-defining-library-version' extracts the version from the header of a
+;; library defining a function.
+;;
+;; `pkg-info-package-version' gets the version of an installed package.
+;;
+;; `pkg-info-format-version' formats a version list as human readable string.
+;;
+;; `pkg-info-version-info' returns complete version information for a specific
+;; package.
+;;
+;; `pkg-info-get-melpa-recipe' gets the MELPA recipe for a package.
+;;
+;; `pkg-info-get-melpa-fetcher' gets the fetcher used to build a package on
+;; MELPA.
+;;
+;; `pkg-info-wiki-package-p' determines whether a package was build from
+;; EmacsWiki on MELPA.
+
+;;; Code:
+
+(require 'epl)
+
+(require 'lisp-mnt)
+(require 'find-func)
+(require 'json) ; `json-read'
+(require 'url-http) ; `url-http-parse-response'
+
+(defvar url-http-end-of-headers)
+
+
+;;; Version information
+(defun pkg-info-format-version (version)
+ "Format VERSION as human-readable string.
+
+Return a human-readable string representing VERSION."
+ ;; XXX: Find a better, more flexible way of formatting?
+ (package-version-join version))
+
+(defsubst pkg-info--show-version-and-return (version show)
+ "Show and return VERSION.
+
+When SHOW is non-nil, show VERSION in minibuffer.
+
+Return VERSION."
+ (when show
+ (message (if (listp version) (pkg-info-format-version version) version)))
+ version)
+
+(defun pkg-info--read-library ()
+ "Read a library from minibuffer."
+ (completing-read "Load library: "
+ (apply-partially 'locate-file-completion-table
+ load-path
+ (get-load-suffixes))))
+
+(defun pkg-info--read-function ()
+ "Read a function name from minibuffer."
+ (let ((input (completing-read "Function: " obarray #'boundp :require-match)))
+ (if (string= input "") nil (intern input))))
+
+(defun pkg-info--read-package ()
+ "Read a package name from minibuffer."
+ (let* ((installed (epl-installed-packages))
+ (names (sort (mapcar (lambda (pkg)
+ (symbol-name (epl-package-name pkg)))
+ installed)
+ #'string<))
+ (default (car names)))
+ (completing-read "Installed package: " names nil 'require-match
+ nil nil default)))
+
+(defun pkg-info-library-source (library)
+ "Get the source file of LIBRARY.
+
+LIBRARY is either a symbol denoting a named feature, or a library
+name as string.
+
+Return the source file of LIBRARY as string."
+ (find-library-name (if (symbolp library) (symbol-name library) library)))
+
+(defun pkg-info-defining-library (function)
+ "Get the source file of the library defining FUNCTION.
+
+FUNCTION is a function symbol.
+
+Return the file name of the library as string. Signal an error
+if the library does not exist, or if the definition of FUNCTION
+was not found."
+ (unless (functionp function)
+ (signal 'wrong-type-argument (list 'functionp function)))
+ (let ((library (symbol-file function 'defun)))
+ (unless library
+ (error "Can't find definition of %s" function))
+ library))
+
+(defun pkg-info-x-original-version (file)
+ "Read the X-Original-Version header from FILE.
+
+Return the value as version list, or return nil if FILE lacks
+this header. Signal an error, if the value of the header is not
+a valid version."
+ (let ((version-str (with-temp-buffer
+ (insert-file-contents file)
+ (lm-header "X-Original-Version"))))
+ (when version-str
+ (version-to-list version-str))))
+
+;;;###autoload
+(defun pkg-info-library-original-version (library &optional show)
+ "Get the original version in the header of LIBRARY.
+
+The original version is stored in the X-Original-Version header.
+This header is added by the MELPA package archive to preserve
+upstream version numbers.
+
+LIBRARY is either a symbol denoting a named feature, or a library
+name as string.
+
+If SHOW is non-nil, show the version in the minibuffer.
+
+Return the version from the header of LIBRARY as list. Signal an
+error if the LIBRARY was not found or had no X-Original-Version
+header.
+
+See Info node `(elisp)Library Headers' for more information
+about library headers."
+ (interactive (list (pkg-info--read-library) t))
+ (let ((version (pkg-info-x-original-version
+ (pkg-info-library-source library))))
+ (if version
+ (pkg-info--show-version-and-return version show)
+ (error "Library %s has no original version" library))))
+
+;;;###autoload
+(defun pkg-info-library-version (library &optional show)
+ "Get the version in the header of LIBRARY.
+
+LIBRARY is either a symbol denoting a named feature, or a library
+name as string.
+
+If SHOW is non-nil, show the version in the minibuffer.
+
+Return the version from the header of LIBRARY as list. Signal an
+error if the LIBRARY was not found or had no proper header.
+
+See Info node `(elisp)Library Headers' for more information
+about library headers."
+ (interactive (list (pkg-info--read-library) t))
+ (let* ((source (pkg-info-library-source library))
+ (version (epl-package-version (epl-package-from-file source))))
+ (pkg-info--show-version-and-return version show)))
+
+;;;###autoload
+(defun pkg-info-defining-library-original-version (function &optional show)
+ "Get the original version of the library defining FUNCTION.
+
+The original version is stored in the X-Original-Version header.
+This header is added by the MELPA package archive to preserve
+upstream version numbers.
+
+If SHOW is non-nil, show the version in mini-buffer.
+
+This function is mainly intended to find the version of a major
+or minor mode, i.e.
+
+ (pkg-info-defining-library-version 'flycheck-mode)
+
+Return the version of the library defining FUNCTION. Signal an
+error if FUNCTION is not a valid function, if its defining
+library was not found, or if the library had no proper version
+header."
+ (interactive (list (pkg-info--read-function) t))
+ (pkg-info-library-original-version (pkg-info-defining-library function) show))
+
+;;;###autoload
+(defun pkg-info-defining-library-version (function &optional show)
+ "Get the version of the library defining FUNCTION.
+
+If SHOW is non-nil, show the version in mini-buffer.
+
+This function is mainly intended to find the version of a major
+or minor mode, i.e.
+
+ (pkg-info-defining-library-version 'flycheck-mode)
+
+Return the version of the library defining FUNCTION. Signal an
+error if FUNCTION is not a valid function, if its defining
+library was not found, or if the library had no proper version
+header."
+ (interactive (list (pkg-info--read-function) t))
+ (pkg-info-library-version (pkg-info-defining-library function) show))
+
+;;;###autoload
+(defun pkg-info-package-version (package &optional show)
+ "Get the version of an installed PACKAGE.
+
+If SHOW is non-nil, show the version in the minibuffer.
+
+Return the version as list, or nil if PACKAGE is not installed."
+ (interactive (list (pkg-info--read-package) t))
+ (let* ((name (if (stringp package) (intern package) package))
+ (package (car (epl-find-installed-packages name))))
+ (unless package
+ (error "Can't find installed package %s" name))
+ (pkg-info--show-version-and-return (epl-package-version package) show)))
+
+;;;###autoload
+(defun pkg-info-version-info (library &optional package show)
+ "Obtain complete version info for LIBRARY and PACKAGE.
+
+LIBRARY is a symbol denoting a named feature, or a library name
+as string. PACKAGE is a symbol denoting an ELPA package. If
+omitted or nil, default to LIBRARY.
+
+If SHOW is non-nil, show the version in the minibuffer.
+
+When called interactively, prompt for LIBRARY. When called
+interactively with prefix argument, prompt for PACKAGE as well.
+
+Return a string with complete version information for LIBRARY.
+This version information contains the version from the headers of
+LIBRARY, and the version of the installed PACKAGE, the LIBRARY is
+part of. If PACKAGE is not installed, or if the PACKAGE version
+is the same as the LIBRARY version, do not include a package
+version."
+ (interactive (list (pkg-info--read-library)
+ (when current-prefix-arg
+ (pkg-info--read-package))
+ t))
+ (let* ((package (or package (if (stringp library) (intern library) library)))
+ (orig-version (condition-case nil
+ (pkg-info-library-original-version library)
+ (error nil)))
+ ;; If we have X-Original-Version, we assume that MELPA replaced the
+ ;; library version with its generated version, so we use the
+ ;; X-Original-Version header instead, and ignore the library version
+ ;; header
+ (lib-version (or orig-version (pkg-info-library-version library)))
+ (pkg-version (condition-case nil
+ (pkg-info-package-version package)
+ (error nil)))
+ (version (if (and pkg-version
+ (not (version-list-= lib-version pkg-version)))
+ (format "%s (package: %s)"
+ (pkg-info-format-version lib-version)
+ (pkg-info-format-version pkg-version))
+ (pkg-info-format-version lib-version))))
+ (pkg-info--show-version-and-return version show)))
+
+(defconst pkg-info-melpa-recipe-url "http://melpa.org/recipes.json"
+ "The URL from which to fetch MELPA recipes.")
+
+(defvar pkg-info-melpa-recipes nil
+ "An alist of MELPA recipes.")
+
+(defun pkg-info-retrieve-melpa-recipes ()
+ "Retrieve MELPA recipes from MELPA archive."
+ (let ((buffer (url-retrieve-synchronously pkg-info-melpa-recipe-url)))
+ (with-current-buffer buffer
+ (unwind-protect
+ (let ((response-code (url-http-parse-response)))
+ (unless (equal response-code 200)
+ (error "Failed to retrieve MELPA recipes from %s (code %s)"
+ pkg-info-melpa-recipe-url response-code))
+ (goto-char url-http-end-of-headers)
+ (json-read))
+ (when (and buffer (buffer-live-p buffer))
+ (kill-buffer buffer))))))
+
+(defun pkg-info-get-melpa-recipes ()
+ "Get MELPA recipes."
+ (setq pkg-info-melpa-recipes
+ (or pkg-info-melpa-recipes
+ (pkg-info-retrieve-melpa-recipes))))
+
+(defun pkg-info-get-melpa-recipe (package)
+ "Get the MELPA recipe for PACKAGE.
+
+Return nil if PACKAGE is not on MELPA."
+ (cdr (assq package (pkg-info-get-melpa-recipes))))
+
+(defun pkg-info-get-melpa-fetcher (package)
+ "Get the MELPA fetcher for PACKAGE."
+ (cdr (assq 'fetcher (pkg-info-get-melpa-recipe package))))
+
+(defun pkg-info-wiki-package-p (package)
+ "Determine whether PACKAGE is build from the EmacsWiki."
+ (equal (pkg-info-get-melpa-fetcher package) "wiki"))
+
+(provide 'pkg-info)
+
+;; Local Variables:
+;; indent-tabs-mode: nil
+;; coding: utf-8
+;; End:
+
+;;; pkg-info.el ends here
diff --git a/elpa/pkg-info-20150517.1143/pkg-info.elc b/elpa/pkg-info-20150517.1143/pkg-info.elc
new file mode 100644
index 0000000..0b5a21f
--- /dev/null
+++ b/elpa/pkg-info-20150517.1143/pkg-info.elc
Binary files differ
diff --git a/elpa/projectile-20220430.800/projectile-autoloads.el b/elpa/projectile-20220430.800/projectile-autoloads.el
new file mode 100644
index 0000000..2cee6b8
--- /dev/null
+++ b/elpa/projectile-20220430.800/projectile-autoloads.el
@@ -0,0 +1,625 @@
+;;; projectile-autoloads.el --- automatically extracted autoloads -*- lexical-binding: t -*-
+;;
+;;; Code:
+
+(add-to-list 'load-path (directory-file-name
+ (or (file-name-directory #$) (car load-path))))
+
+
+;;;### (autoloads nil "projectile" "projectile.el" (0 0 0 0))
+;;; Generated autoloads from projectile.el
+
+(autoload 'projectile-version "projectile" "\
+Get the Projectile version as string.
+
+If called interactively or if SHOW-VERSION is non-nil, show the
+version in the echo area and the messages buffer.
+
+The returned string includes both, the version from package.el
+and the library version, if both a present and different.
+
+If the version number could not be determined, signal an error,
+if called interactively, or if SHOW-VERSION is non-nil, otherwise
+just return nil.
+
+\(fn &optional SHOW-VERSION)" t nil)
+
+(autoload 'projectile-invalidate-cache "projectile" "\
+Remove the current project's files from `projectile-projects-cache'.
+
+With a prefix argument PROMPT prompts for the name of the project whose cache
+to invalidate.
+
+\(fn PROMPT)" t nil)
+
+(autoload 'projectile-purge-file-from-cache "projectile" "\
+Purge FILE from the cache of the current project.
+
+\(fn FILE)" t nil)
+
+(autoload 'projectile-purge-dir-from-cache "projectile" "\
+Purge DIR from the cache of the current project.
+
+\(fn DIR)" t nil)
+
+(autoload 'projectile-cache-current-file "projectile" "\
+Add the currently visited file to the cache." t nil)
+
+(autoload 'projectile-discover-projects-in-directory "projectile" "\
+Discover any projects in DIRECTORY and add them to the projectile cache.
+
+If DEPTH is non-nil recursively descend exactly DEPTH levels below DIRECTORY and
+discover projects there.
+
+\(fn DIRECTORY &optional DEPTH)" t nil)
+
+(autoload 'projectile-discover-projects-in-search-path "projectile" "\
+Discover projects in `projectile-project-search-path'.
+Invoked automatically when `projectile-mode' is enabled." t nil)
+
+(autoload 'projectile-switch-to-buffer "projectile" "\
+Switch to a project buffer." t nil)
+
+(autoload 'projectile-switch-to-buffer-other-window "projectile" "\
+Switch to a project buffer and show it in another window." t nil)
+
+(autoload 'projectile-switch-to-buffer-other-frame "projectile" "\
+Switch to a project buffer and show it in another frame." t nil)
+
+(autoload 'projectile-display-buffer "projectile" "\
+Display a project buffer in another window without selecting it." t nil)
+
+(autoload 'projectile-project-buffers-other-buffer "projectile" "\
+Switch to the most recently selected buffer project buffer.
+Only buffers not visible in windows are returned." t nil)
+
+(autoload 'projectile-multi-occur "projectile" "\
+Do a `multi-occur' in the project's buffers.
+With a prefix argument, show NLINES of context.
+
+\(fn &optional NLINES)" t nil)
+
+(autoload 'projectile-find-other-file "projectile" "\
+Switch between files with the same name but different extensions.
+With FLEX-MATCHING, match any file that contains the base name of current file.
+Other file extensions can be customized with the variable
+`projectile-other-file-alist'.
+
+\(fn &optional FLEX-MATCHING)" t nil)
+
+(autoload 'projectile-find-other-file-other-window "projectile" "\
+Switch between files with different extensions in other window.
+Switch between files with the same name but different extensions in other
+window. With FLEX-MATCHING, match any file that contains the base name of
+current file. Other file extensions can be customized with the variable
+`projectile-other-file-alist'.
+
+\(fn &optional FLEX-MATCHING)" t nil)
+
+(autoload 'projectile-find-other-file-other-frame "projectile" "\
+Switch between files with different extensions in other frame.
+Switch between files with the same name but different extensions in other frame.
+With FLEX-MATCHING, match any file that contains the base name of current
+file. Other file extensions can be customized with the variable
+`projectile-other-file-alist'.
+
+\(fn &optional FLEX-MATCHING)" t nil)
+
+(autoload 'projectile-find-file-dwim "projectile" "\
+Jump to a project's files using completion based on context.
+
+With a prefix arg INVALIDATE-CACHE invalidates the cache first.
+
+If point is on a filename, Projectile first tries to search for that
+file in project:
+
+- If it finds just a file, it switches to that file instantly. This works
+even if the filename is incomplete, but there's only a single file in the
+current project that matches the filename at point. For example, if
+there's only a single file named \"projectile/projectile.el\" but the
+current filename is \"projectile/proj\" (incomplete),
+`projectile-find-file-dwim' still switches to \"projectile/projectile.el\"
+immediately because this is the only filename that matches.
+
+- If it finds a list of files, the list is displayed for selecting. A list
+of files is displayed when a filename appears more than one in the project
+or the filename at point is a prefix of more than two files in a project.
+For example, if `projectile-find-file-dwim' is executed on a filepath like
+\"projectile/\", it lists the content of that directory. If it is executed
+on a partial filename like \"projectile/a\", a list of files with character
+'a' in that directory is presented.
+
+- If it finds nothing, display a list of all files in project for selecting.
+
+\(fn &optional INVALIDATE-CACHE)" t nil)
+
+(autoload 'projectile-find-file-dwim-other-window "projectile" "\
+Jump to a project's files using completion based on context in other window.
+
+With a prefix arg INVALIDATE-CACHE invalidates the cache first.
+
+If point is on a filename, Projectile first tries to search for that
+file in project:
+
+- If it finds just a file, it switches to that file instantly. This works
+even if the filename is incomplete, but there's only a single file in the
+current project that matches the filename at point. For example, if
+there's only a single file named \"projectile/projectile.el\" but the
+current filename is \"projectile/proj\" (incomplete),
+`projectile-find-file-dwim-other-window' still switches to
+\"projectile/projectile.el\" immediately because this is the only filename
+that matches.
+
+- If it finds a list of files, the list is displayed for selecting. A list
+of files is displayed when a filename appears more than one in the project
+or the filename at point is a prefix of more than two files in a project.
+For example, if `projectile-find-file-dwim-other-window' is executed on a
+filepath like \"projectile/\", it lists the content of that directory. If
+it is executed on a partial filename like \"projectile/a\", a list of files
+with character 'a' in that directory is presented.
+
+- If it finds nothing, display a list of all files in project for selecting.
+
+\(fn &optional INVALIDATE-CACHE)" t nil)
+
+(autoload 'projectile-find-file-dwim-other-frame "projectile" "\
+Jump to a project's files using completion based on context in other frame.
+
+With a prefix arg INVALIDATE-CACHE invalidates the cache first.
+
+If point is on a filename, Projectile first tries to search for that
+file in project:
+
+- If it finds just a file, it switches to that file instantly. This works
+even if the filename is incomplete, but there's only a single file in the
+current project that matches the filename at point. For example, if
+there's only a single file named \"projectile/projectile.el\" but the
+current filename is \"projectile/proj\" (incomplete),
+`projectile-find-file-dwim-other-frame' still switches to
+\"projectile/projectile.el\" immediately because this is the only filename
+that matches.
+
+- If it finds a list of files, the list is displayed for selecting. A list
+of files is displayed when a filename appears more than one in the project
+or the filename at point is a prefix of more than two files in a project.
+For example, if `projectile-find-file-dwim-other-frame' is executed on a
+filepath like \"projectile/\", it lists the content of that directory. If
+it is executed on a partial filename like \"projectile/a\", a list of files
+with character 'a' in that directory is presented.
+
+- If it finds nothing, display a list of all files in project for selecting.
+
+\(fn &optional INVALIDATE-CACHE)" t nil)
+
+(autoload 'projectile-find-file "projectile" "\
+Jump to a project's file using completion.
+With a prefix arg INVALIDATE-CACHE invalidates the cache first.
+
+\(fn &optional INVALIDATE-CACHE)" t nil)
+
+(autoload 'projectile-find-file-other-window "projectile" "\
+Jump to a project's file using completion and show it in another window.
+
+With a prefix arg INVALIDATE-CACHE invalidates the cache first.
+
+\(fn &optional INVALIDATE-CACHE)" t nil)
+
+(autoload 'projectile-find-file-other-frame "projectile" "\
+Jump to a project's file using completion and show it in another frame.
+
+With a prefix arg INVALIDATE-CACHE invalidates the cache first.
+
+\(fn &optional INVALIDATE-CACHE)" t nil)
+
+(autoload 'projectile-toggle-project-read-only "projectile" "\
+Toggle project read only." t nil)
+
+(autoload 'projectile-find-dir "projectile" "\
+Jump to a project's directory using completion.
+
+With a prefix arg INVALIDATE-CACHE invalidates the cache first.
+
+\(fn &optional INVALIDATE-CACHE)" t nil)
+
+(autoload 'projectile-find-dir-other-window "projectile" "\
+Jump to a project's directory in other window using completion.
+
+With a prefix arg INVALIDATE-CACHE invalidates the cache first.
+
+\(fn &optional INVALIDATE-CACHE)" t nil)
+
+(autoload 'projectile-find-dir-other-frame "projectile" "\
+Jump to a project's directory in other frame using completion.
+
+With a prefix arg INVALIDATE-CACHE invalidates the cache first.
+
+\(fn &optional INVALIDATE-CACHE)" t nil)
+
+(autoload 'projectile-find-test-file "projectile" "\
+Jump to a project's test file using completion.
+
+With a prefix arg INVALIDATE-CACHE invalidates the cache first.
+
+\(fn &optional INVALIDATE-CACHE)" t nil)
+
+(autoload 'projectile-find-related-file-other-window "projectile" "\
+Open related file in other window." t nil)
+
+(autoload 'projectile-find-related-file-other-frame "projectile" "\
+Open related file in other frame." t nil)
+
+(autoload 'projectile-find-related-file "projectile" "\
+Open related file." t nil)
+
+(autoload 'projectile-related-files-fn-groups "projectile" "\
+Generate a related-files-fn which relates as KIND for files in each of GROUPS.
+
+\(fn KIND GROUPS)" nil nil)
+
+(autoload 'projectile-related-files-fn-extensions "projectile" "\
+Generate a related-files-fn which relates as KIND for files having EXTENSIONS.
+
+\(fn KIND EXTENSIONS)" nil nil)
+
+(autoload 'projectile-related-files-fn-test-with-prefix "projectile" "\
+Generate a related-files-fn which relates tests and impl.
+Use files with EXTENSION based on TEST-PREFIX.
+
+\(fn EXTENSION TEST-PREFIX)" nil nil)
+
+(autoload 'projectile-related-files-fn-test-with-suffix "projectile" "\
+Generate a related-files-fn which relates tests and impl.
+Use files with EXTENSION based on TEST-SUFFIX.
+
+\(fn EXTENSION TEST-SUFFIX)" nil nil)
+
+(autoload 'projectile-project-info "projectile" "\
+Display info for current project." t nil)
+
+(autoload 'projectile-find-implementation-or-test-other-window "projectile" "\
+Open matching implementation or test file in other window.
+
+See the documentation of `projectile--find-matching-file' and
+`projectile--find-matching-test' for how implementation and test files
+are determined." t nil)
+
+(autoload 'projectile-find-implementation-or-test-other-frame "projectile" "\
+Open matching implementation or test file in other frame.
+
+See the documentation of `projectile--find-matching-file' and
+`projectile--find-matching-test' for how implementation and test files
+are determined." t nil)
+
+(autoload 'projectile-toggle-between-implementation-and-test "projectile" "\
+Toggle between an implementation file and its test file.
+
+
+See the documentation of `projectile--find-matching-file' and
+`projectile--find-matching-test' for how implementation and test files
+are determined." t nil)
+
+(autoload 'projectile-grep "projectile" "\
+Perform rgrep in the project.
+
+With a prefix ARG asks for files (globbing-aware) which to grep in.
+With prefix ARG of `-' (such as `M--'), default the files (without prompt),
+to `projectile-grep-default-files'.
+
+With REGEXP given, don't query the user for a regexp.
+
+\(fn &optional REGEXP ARG)" t nil)
+
+(autoload 'projectile-ag "projectile" "\
+Run an ag search with SEARCH-TERM in the project.
+
+With an optional prefix argument ARG SEARCH-TERM is interpreted as a
+regular expression.
+
+\(fn SEARCH-TERM &optional ARG)" t nil)
+
+(autoload 'projectile-ripgrep "projectile" "\
+Run a ripgrep (rg) search with `SEARCH-TERM' at current project root.
+
+With an optional prefix argument ARG SEARCH-TERM is interpreted as a
+regular expression.
+
+This command depends on of the Emacs packages ripgrep or rg being
+installed to work.
+
+\(fn SEARCH-TERM &optional ARG)" t nil)
+
+(autoload 'projectile-regenerate-tags "projectile" "\
+Regenerate the project's [e|g]tags." t nil)
+
+(autoload 'projectile-find-tag "projectile" "\
+Find tag in project." t nil)
+
+(autoload 'projectile-run-command-in-root "projectile" "\
+Invoke `execute-extended-command' in the project's root." t nil)
+
+(autoload 'projectile-run-shell-command-in-root "projectile" "\
+Invoke `shell-command' in the project's root.
+
+\(fn COMMAND &optional OUTPUT-BUFFER ERROR-BUFFER)" t nil)
+
+(autoload 'projectile-run-async-shell-command-in-root "projectile" "\
+Invoke `async-shell-command' in the project's root.
+
+\(fn COMMAND &optional OUTPUT-BUFFER ERROR-BUFFER)" t nil)
+
+(autoload 'projectile-run-gdb "projectile" "\
+Invoke `gdb' in the project's root." t nil)
+
+(autoload 'projectile-run-shell "projectile" "\
+Invoke `shell' in the project's root.
+
+Switch to the project specific shell buffer if it already exists.
+
+Use a prefix argument ARG to indicate creation of a new process instead.
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'projectile-run-eshell "projectile" "\
+Invoke `eshell' in the project's root.
+
+Switch to the project specific eshell buffer if it already exists.
+
+Use a prefix argument ARG to indicate creation of a new process instead.
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'projectile-run-ielm "projectile" "\
+Invoke `ielm' in the project's root.
+
+Switch to the project specific ielm buffer if it already exists.
+
+Use a prefix argument ARG to indicate creation of a new process instead.
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'projectile-run-term "projectile" "\
+Invoke `term' in the project's root.
+
+Switch to the project specific term buffer if it already exists.
+
+Use a prefix argument ARG to indicate creation of a new process instead.
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'projectile-run-vterm "projectile" "\
+Invoke `vterm' in the project's root.
+
+Switch to the project specific term buffer if it already exists.
+
+Use a prefix argument ARG to indicate creation of a new process instead.
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'projectile-replace "projectile" "\
+Replace literal string in project using non-regexp `tags-query-replace'.
+
+With a prefix argument ARG prompts you for a directory on which
+to run the replacement.
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'projectile-replace-regexp "projectile" "\
+Replace a regexp in the project using `tags-query-replace'.
+
+With a prefix argument ARG prompts you for a directory on which
+to run the replacement.
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'projectile-kill-buffers "projectile" "\
+Kill project buffers.
+
+The buffer are killed according to the value of
+`projectile-kill-buffers-filter'." t nil)
+
+(autoload 'projectile-save-project-buffers "projectile" "\
+Save all project buffers." t nil)
+
+(autoload 'projectile-dired "projectile" "\
+Open `dired' at the root of the project." t nil)
+
+(autoload 'projectile-dired-other-window "projectile" "\
+Open `dired' at the root of the project in another window." t nil)
+
+(autoload 'projectile-dired-other-frame "projectile" "\
+Open `dired' at the root of the project in another frame." t nil)
+
+(autoload 'projectile-vc "projectile" "\
+Open `vc-dir' at the root of the project.
+
+For git projects `magit-status-internal' is used if available.
+For hg projects `monky-status' is used if available.
+
+If PROJECT-ROOT is given, it is opened instead of the project
+root directory of the current buffer file. If interactively
+called with a prefix argument, the user is prompted for a project
+directory to open.
+
+\(fn &optional PROJECT-ROOT)" t nil)
+
+(autoload 'projectile-recentf "projectile" "\
+Show a list of recently visited files in a project." t nil)
+
+(autoload 'projectile-configure-project "projectile" "\
+Run project configure command.
+
+Normally you'll be prompted for a compilation command, unless
+variable `compilation-read-command'. You can force the prompt
+with a prefix ARG.
+
+\(fn ARG)" t nil)
+
+(autoload 'projectile-compile-project "projectile" "\
+Run project compilation command.
+
+Normally you'll be prompted for a compilation command, unless
+variable `compilation-read-command'. You can force the prompt
+with a prefix ARG.
+
+\(fn ARG)" t nil)
+
+(autoload 'projectile-test-project "projectile" "\
+Run project test command.
+
+Normally you'll be prompted for a compilation command, unless
+variable `compilation-read-command'. You can force the prompt
+with a prefix ARG.
+
+\(fn ARG)" t nil)
+
+(autoload 'projectile-install-project "projectile" "\
+Run project install command.
+
+Normally you'll be prompted for a compilation command, unless
+variable `compilation-read-command'. You can force the prompt
+with a prefix ARG.
+
+\(fn ARG)" t nil)
+
+(autoload 'projectile-package-project "projectile" "\
+Run project package command.
+
+Normally you'll be prompted for a compilation command, unless
+variable `compilation-read-command'. You can force the prompt
+with a prefix ARG.
+
+\(fn ARG)" t nil)
+
+(autoload 'projectile-run-project "projectile" "\
+Run project run command.
+
+Normally you'll be prompted for a compilation command, unless
+variable `compilation-read-command'. You can force the prompt
+with a prefix ARG.
+
+\(fn ARG)" t nil)
+
+(autoload 'projectile-repeat-last-command "projectile" "\
+Run last projectile external command.
+
+External commands are: `projectile-configure-project',
+`projectile-compile-project', `projectile-test-project',
+`projectile-install-project', `projectile-package-project',
+and `projectile-run-project'.
+
+If the prefix argument SHOW_PROMPT is non nil, the command can be edited.
+
+\(fn SHOW-PROMPT)" t nil)
+
+(autoload 'projectile-switch-project "projectile" "\
+Switch to a project we have visited before.
+Invokes the command referenced by `projectile-switch-project-action' on switch.
+With a prefix ARG invokes `projectile-commander' instead of
+`projectile-switch-project-action.'
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'projectile-switch-open-project "projectile" "\
+Switch to a project we have currently opened.
+Invokes the command referenced by `projectile-switch-project-action' on switch.
+With a prefix ARG invokes `projectile-commander' instead of
+`projectile-switch-project-action.'
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'projectile-find-file-in-directory "projectile" "\
+Jump to a file in a (maybe regular) DIRECTORY.
+
+This command will first prompt for the directory the file is in.
+
+\(fn &optional DIRECTORY)" t nil)
+
+(autoload 'projectile-find-file-in-known-projects "projectile" "\
+Jump to a file in any of the known projects." t nil)
+
+(autoload 'projectile-cleanup-known-projects "projectile" "\
+Remove known projects that don't exist anymore." t nil)
+
+(autoload 'projectile-clear-known-projects "projectile" "\
+Clear both `projectile-known-projects' and `projectile-known-projects-file'." t nil)
+
+(autoload 'projectile-reset-known-projects "projectile" "\
+Clear known projects and rediscover." t nil)
+
+(autoload 'projectile-remove-known-project "projectile" "\
+Remove PROJECT from the list of known projects.
+
+\(fn &optional PROJECT)" t nil)
+
+(autoload 'projectile-remove-current-project-from-known-projects "projectile" "\
+Remove the current project from the list of known projects." t nil)
+
+(autoload 'projectile-add-known-project "projectile" "\
+Add PROJECT-ROOT to the list of known projects.
+
+\(fn PROJECT-ROOT)" t nil)
+
+(autoload 'projectile-ibuffer "projectile" "\
+Open an IBuffer window showing all buffers in the current project.
+
+Let user choose another project when PROMPT-FOR-PROJECT is supplied.
+
+\(fn PROMPT-FOR-PROJECT)" t nil)
+
+(autoload 'projectile-commander "projectile" "\
+Execute a Projectile command with a single letter.
+The user is prompted for a single character indicating the action to invoke.
+The `?' character describes then
+available actions.
+
+See `def-projectile-commander-method' for defining new methods." t nil)
+
+(autoload 'projectile-browse-dirty-projects "projectile" "\
+Browse dirty version controlled projects.
+
+With a prefix argument, or if CACHED is non-nil, try to use the cached
+dirty project list.
+
+\(fn &optional CACHED)" t nil)
+
+(autoload 'projectile-edit-dir-locals "projectile" "\
+Edit or create a .dir-locals.el file of the project." t nil)
+
+(defvar projectile-mode nil "\
+Non-nil if Projectile mode is enabled.
+See the `projectile-mode' command
+for a description of this minor mode.
+Setting this variable directly does not take effect;
+either customize it (see the info node `Easy Customization')
+or call the function `projectile-mode'.")
+
+(custom-autoload 'projectile-mode "projectile" nil)
+
+(autoload 'projectile-mode "projectile" "\
+Minor mode to assist project management and navigation.
+
+When called interactively, toggle `projectile-mode'. With prefix
+ARG, enable `projectile-mode' if ARG is positive, otherwise disable
+it.
+
+When called from Lisp, enable `projectile-mode' if ARG is omitted,
+nil or positive. If ARG is `toggle', toggle `projectile-mode'.
+Otherwise behave as if called interactively.
+
+\\{projectile-mode-map}
+
+\(fn &optional ARG)" t nil)
+
+(define-obsolete-function-alias 'projectile-global-mode 'projectile-mode "1.0")
+
+(register-definition-prefixes "projectile" '("??" "compilation-find-file-projectile-find-compilation-buffer" "def-projectile-commander-method" "delete-file-projectile-remove-from-cache" "projectile-"))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; coding: utf-8
+;; End:
+;;; projectile-autoloads.el ends here
diff --git a/elpa/projectile-20220430.800/projectile-pkg.el b/elpa/projectile-20220430.800/projectile-pkg.el
new file mode 100644
index 0000000..f149589
--- /dev/null
+++ b/elpa/projectile-20220430.800/projectile-pkg.el
@@ -0,0 +1,2 @@
+;;; Generated package description from projectile.el -*- no-byte-compile: t -*-
+(define-package "projectile" "20220430.800" "Manage and navigate projects in Emacs easily" '((emacs "25.1")) :commit "a4f86f981c84a546530d5904253fa266431ef806" :authors '(("Bozhidar Batsov" . "bozhidar@batsov.dev")) :maintainer '("Bozhidar Batsov" . "bozhidar@batsov.dev") :keywords '("project" "convenience") :url "https://github.com/bbatsov/projectile")
diff --git a/elpa/projectile-20220430.800/projectile.el b/elpa/projectile-20220430.800/projectile.el
new file mode 100644
index 0000000..20663f7
--- /dev/null
+++ b/elpa/projectile-20220430.800/projectile.el
@@ -0,0 +1,5854 @@
+;;; projectile.el --- Manage and navigate projects in Emacs easily -*- lexical-binding: t -*-
+
+;; Copyright © 2011-2021 Bozhidar Batsov <bozhidar@batsov.dev>
+
+;; Author: Bozhidar Batsov <bozhidar@batsov.dev>
+;; URL: https://github.com/bbatsov/projectile
+;; Package-Version: 20220430.800
+;; Package-Commit: a4f86f981c84a546530d5904253fa266431ef806
+;; Keywords: project, convenience
+;; Version: 2.6.0-snapshot
+;; Package-Requires: ((emacs "25.1"))
+
+;; 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 GNU Emacs; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+;;
+;; This library provides easy project management and navigation. The
+;; concept of a project is pretty basic - just a folder containing
+;; special file. Currently git, mercurial and bazaar repos are
+;; considered projects by default. If you want to mark a folder
+;; manually as a project just create an empty .projectile file in
+;; it. See the README for more details.
+;;
+;;; Code:
+
+(require 'cl-lib)
+(require 'thingatpt)
+(require 'ibuffer)
+(require 'ibuf-ext)
+(require 'compile)
+(require 'grep)
+(require 'lisp-mnt)
+(eval-when-compile
+ (require 'find-dired)
+ (require 'subr-x))
+
+;;; Declarations
+;;
+;; A bunch of variable and function declarations
+;; needed to appease the byte-compiler.
+(defvar ido-mode)
+(defvar ivy-mode)
+(defvar helm-mode)
+(defvar ag-ignore-list)
+(defvar ggtags-completion-table)
+(defvar tags-completion-table)
+(defvar tags-loop-scan)
+(defvar tags-loop-operate)
+(defvar eshell-buffer-name)
+(defvar explicit-shell-file-name)
+(defvar grep-files-aliases)
+(defvar grep-find-ignored-directories)
+(defvar grep-find-ignored-files)
+
+(declare-function tags-completion-table "etags")
+(declare-function make-term "term")
+(declare-function term-mode "term")
+(declare-function term-char-mode "term")
+(declare-function term-ansi-make-term "term")
+(declare-function eshell-search-path "esh-ext")
+(declare-function vc-dir "vc-dir")
+(declare-function vc-dir-busy "vc-dir")
+(declare-function string-trim "subr-x")
+(declare-function fileloop-continue "fileloop")
+(declare-function fileloop-initialize-replace "fileloop")
+(declare-function tramp-archive-file-name-p "tramp-archive")
+
+(declare-function ggtags-ensure-project "ext:ggtags")
+(declare-function ggtags-update-tags "ext:ggtags")
+(declare-function ripgrep-regexp "ext:ripgrep")
+(declare-function rg-run "ext:rg")
+(declare-function vterm "ext:vterm")
+(declare-function vterm-send-return "ext:vterm")
+(declare-function vterm-send-string "ext:vterm")
+
+;;; Customization
+(defgroup projectile nil
+ "Manage and navigate projects easily."
+ :group 'tools
+ :group 'convenience
+ :link '(url-link :tag "GitHub" "https://github.com/bbatsov/projectile")
+ :link '(url-link :tag "Online Manual" "https://docs.projectile.mx/")
+ :link '(emacs-commentary-link :tag "Commentary" "projectile"))
+
+(defcustom projectile-indexing-method (if (eq system-type 'windows-nt) 'native 'alien)
+ "Specifies the indexing method used by Projectile.
+
+There are three indexing methods - native, hybrid and alien.
+
+The native method is implemented in Emacs Lisp (therefore it is
+native to Emacs). Its advantage is that it is portable and will
+work everywhere that Emacs does. Its disadvantage is that it is a
+bit slow (especially for large projects). Generally it's a good
+idea to pair the native indexing method with caching.
+
+The hybrid indexing method uses external tools (e.g. git, find,
+etc) to speed up the indexing process. Still, the files will be
+post-processed by Projectile for sorting/filtering purposes.
+In this sense that approach is a hybrid between native indexing
+and alien indexing.
+
+The alien indexing method optimizes to the limit the speed
+of the hybrid indexing method. This means that Projectile will
+not do any processing of the files returned by the external
+commands and you're going to get the maximum performance
+possible. This behaviour makes a lot of sense for most people,
+as they'd typically be putting ignores in their VCS config and
+won't care about any additional ignores/unignores/sorting that
+Projectile might also provide.
+
+The disadvantage of the hybrid and alien methods is that they are not well
+supported on Windows systems. That's why by default alien indexing is the
+default on all operating systems, except Windows."
+ :group 'projectile
+ :type '(radio
+ (const :tag "Native" native)
+ (const :tag "Hybrid" hybrid)
+ (const :tag "Alien" alien)))
+
+(defcustom projectile-enable-caching (eq projectile-indexing-method 'native)
+ "When t enables project files caching.
+
+Project caching is automatically enabled by default if you're
+using the native indexing method."
+ :group 'projectile
+ :type 'boolean)
+
+(defcustom projectile-kill-buffers-filter 'kill-all
+ "Determine which buffers are killed by `projectile-kill-buffers'.
+
+When the kill-all option is selected, kills each buffer.
+
+When the kill-only-files option is selected, kill only the buffer
+associated to a file.
+
+Otherwise, it should be a predicate that takes one argument: the buffer to
+be killed."
+ :group 'projectile
+ :type '(radio
+ (const :tag "All project buffers" kill-all)
+ (const :tag "Project file buffers" kill-only-files)
+ (function :tag "Predicate")))
+
+(defcustom projectile-file-exists-local-cache-expire nil
+ "Number of seconds before the local file existence cache expires.
+Local refers to a file on a local file system.
+
+A value of nil disables this cache.
+See `projectile-file-exists-p' for details."
+ :group 'projectile
+ :type '(choice (const :tag "Disabled" nil)
+ (integer :tag "Seconds")))
+
+(defcustom projectile-file-exists-remote-cache-expire (* 5 60)
+ "Number of seconds before the remote file existence cache expires.
+Remote refers to a file on a remote file system such as tramp.
+
+A value of nil disables this cache.
+See `projectile-file-exists-p' for details."
+ :group 'projectile
+ :type '(choice (const :tag "Disabled" nil)
+ (integer :tag "Seconds")))
+
+(defcustom projectile-files-cache-expire nil
+ "Number of seconds before project files list cache expires.
+
+A value of nil means the cache never expires."
+ :group 'projectile
+ :type '(choice (const :tag "Disabled" nil)
+ (integer :tag "Seconds")))
+
+(defcustom projectile-auto-discover t
+ "Whether to discover projects when `projectile-mode' is activated."
+ :group 'projectile
+ :type 'boolean
+ :package-version '(projectile . "2.3.0"))
+
+(defcustom projectile-auto-update-cache t
+ "Whether cache is automatically updated when files are opened or deleted."
+ :group 'projectile
+ :type 'boolean)
+
+(defcustom projectile-require-project-root 'prompt
+ "Require the presence of a project root to operate when true.
+When set to 'prompt Projectile will ask you to select a project
+directory if you're not in a project.
+
+When nil Projectile will consider the current directory the project root."
+ :group 'projectile
+ :type '(choice (const :tag "No" nil)
+ (const :tag "Yes" t)
+ (const :tag "Prompt for project" prompt)))
+
+(defcustom projectile-completion-system 'auto
+ "The completion system to be used by Projectile."
+ :group 'projectile
+ :type '(radio
+ (const :tag "Auto-detect" auto)
+ (const :tag "Ido" ido)
+ (const :tag "Helm" helm)
+ (const :tag "Ivy" ivy)
+ (const :tag "Default" default)
+ (function :tag "Custom function")))
+
+(defcustom projectile-keymap-prefix nil
+ "Projectile keymap prefix."
+ :group 'projectile
+ :type 'string)
+
+(make-obsolete-variable 'projectile-keymap-prefix "Use (define-key projectile-mode-map (kbd ...) 'projectile-command-map) instead." "2.0.0")
+
+(defcustom projectile-cache-file
+ (expand-file-name "projectile.cache" user-emacs-directory)
+ "The name of Projectile's cache file."
+ :group 'projectile
+ :type 'string)
+
+(defcustom projectile-tags-file-name "TAGS"
+ "The tags filename Projectile's going to use."
+ :group 'projectile
+ :type 'string)
+
+(defcustom projectile-tags-command "ctags -Re -f \"%s\" %s \"%s\""
+ "The command Projectile's going to use to generate a TAGS file."
+ :group 'projectile
+ :type 'string)
+
+(defcustom projectile-tags-backend 'auto
+ "The tag backend that Projectile should use.
+
+If set to 'auto', `projectile-find-tag' will automatically choose
+which backend to use. Preference order is ggtags -> xref
+-> etags-select -> `find-tag'. Variable can also be set to specify which
+backend to use. If selected backend is unavailable, fall back to
+`find-tag'.
+
+If this variable is set to 'auto' and ggtags is available, or if
+set to 'ggtags', then ggtags will be used for
+`projectile-regenerate-tags'. For all other settings
+`projectile-tags-command' will be used."
+ :group 'projectile
+ :type '(radio
+ (const :tag "auto" auto)
+ (const :tag "xref" xref)
+ (const :tag "ggtags" ggtags)
+ (const :tag "etags" etags-select)
+ (const :tag "standard" find-tag))
+ :package-version '(projectile . "0.14.0"))
+
+(defcustom projectile-sort-order 'default
+ "The sort order used for a project's files.
+
+Note that files aren't sorted if `projectile-indexing-method'
+is set to 'alien'."
+ :group 'projectile
+ :type '(radio
+ (const :tag "Default (no sorting)" default)
+ (const :tag "Recently opened files" recentf)
+ (const :tag "Recently active buffers, then recently opened files" recently-active)
+ (const :tag "Access time (atime)" access-time)
+ (const :tag "Modification time (mtime)" modification-time)))
+
+(defcustom projectile-verbose t
+ "Echo messages that are not errors."
+ :group 'projectile
+ :type 'boolean)
+
+(defcustom projectile-buffers-filter-function nil
+ "A function used to filter the buffers in `projectile-project-buffers'.
+
+The function should accept and return a list of Emacs buffers.
+Two example filter functions are shipped by default -
+`projectile-buffers-with-file' and
+`projectile-buffers-with-file-or-process'."
+ :group 'projectile
+ :type 'function)
+
+(defcustom projectile-project-name nil
+ "If this value is non-nil, it will be used as project name.
+
+It has precedence over function `projectile-project-name-function'."
+ :group 'projectile
+ :type 'string
+ :package-version '(projectile . "0.14.0"))
+
+(defcustom projectile-project-name-function 'projectile-default-project-name
+ "A function that receives the project-root and returns the project name.
+
+If variable `projectile-project-name' is non-nil, this function will not be
+used."
+ :group 'projectile
+ :type 'function
+ :package-version '(projectile . "0.14.0"))
+
+(defcustom projectile-project-root-files
+ '(
+ "GTAGS" ; GNU Global tags
+ "TAGS" ; etags/ctags are usually in the root of project
+ "configure.ac" ; autoconf new style
+ "configure.in" ; autoconf old style
+ "cscope.out" ; cscope
+ )
+ "A list of files considered to mark the root of a project.
+The topmost match has precedence.
+See `projectile-register-project-type'."
+ :group 'projectile
+ :type '(repeat string))
+
+(defcustom projectile-project-root-files-bottom-up
+ '(".projectile" ; projectile project marker
+ ".git" ; Git VCS root dir
+ ".hg" ; Mercurial VCS root dir
+ ".fslckout" ; Fossil VCS root dir
+ "_FOSSIL_" ; Fossil VCS root DB on Windows
+ ".bzr" ; Bazaar VCS root dir
+ "_darcs" ; Darcs VCS root dir
+ ".pijul" ; Pijul VCS root dir
+ )
+ "A list of files considered to mark the root of a project.
+The bottommost (parentmost) match has precedence."
+ :group 'projectile
+ :type '(repeat string))
+
+(defcustom projectile-project-root-files-top-down-recurring
+ '(".svn" ; Svn VCS root dir
+ "CVS" ; Csv VCS root dir
+ "Makefile")
+ "A list of files considered to mark the root of a project.
+The search starts at the top and descends down till a directory
+that contains a match file but its parent does not. Thus, it's a
+bottommost match in the topmost sequence of directories
+containing a root file."
+ :group 'projectile
+ :type '(repeat string))
+
+(define-obsolete-variable-alias 'projectile-project-root-files-functions 'projectile-project-root-functions "2.4")
+
+(defcustom projectile-project-root-functions
+ '(projectile-root-local
+ projectile-root-bottom-up
+ projectile-root-top-down
+ projectile-root-top-down-recurring)
+ "A list of functions for finding project root folders.
+The functions will be ran until one of them returns a project folder.
+Reordering the default functions will alter the project discovery
+algorithm."
+ :group 'projectile
+ :type '(repeat function))
+
+(defcustom projectile-dirconfig-comment-prefix
+ nil
+ "Projectile config file (.projectile) comment start marker.
+If specified, starting a line in a project's .projectile file with this
+character marks that line as a comment instead of a pattern.
+Similar to '#' in .gitignore files."
+ :group 'projectile
+ :type 'character
+ :package-version '(projectile . "2.2.0"))
+
+(defcustom projectile-globally-ignored-files
+ (list projectile-tags-file-name)
+ "A list of files globally ignored by projectile.
+Note that files aren't filtered if `projectile-indexing-method'
+is set to 'alien'."
+ :group 'projectile
+ :type '(repeat string))
+
+(defcustom projectile-globally-unignored-files nil
+ "A list of files globally unignored by projectile.
+Regular expressions can be used.
+Note that files aren't filtered if `projectile-indexing-method'
+is set to 'alien'."
+ :group 'projectile
+ :type '(repeat string)
+ :package-version '(projectile . "0.14.0"))
+
+(defcustom projectile-globally-ignored-file-suffixes
+ nil
+ "A list of file suffixes globally ignored by projectile.
+Note that files aren't filtered if `projectile-indexing-method'
+is set to 'alien'."
+ :group 'projectile
+ :type '(repeat string))
+
+(defcustom projectile-globally-ignored-directories
+ '("^\\.idea$"
+ "^\\.vscode$"
+ "^\\.ensime_cache$"
+ "^\\.eunit$"
+ "^\\.git$"
+ "^\\.hg$"
+ "^\\.fslckout$"
+ "^_FOSSIL_$"
+ "^\\.bzr$"
+ "^_darcs$"
+ "^\\.pijul$"
+ "^\\.tox$"
+ "^\\.svn$"
+ "^\\.stack-work$"
+ "^\\.ccls-cache$"
+ "^\\.cache$"
+ "^\\.clangd$")
+ "A list of directories globally ignored by projectile.
+Regular expressions can be used.
+
+Strings that don't start with * are only ignored at the top level
+of the project. Strings that start with * are ignored everywhere
+in the project, as if there was no *. So note that * when used as
+a prefix is not a wildcard; it is an indicator that the directory
+should be ignored at all levels, not just root.
+
+Examples: \"tmp\" ignores only ./tmp at the top level of the
+project, but not ./src/tmp. \"*tmp\" will ignore both ./tmp and
+./src/tmp, but not ./not-a-tmp or ./src/not-a-tmp.
+
+Note that files aren't filtered if `projectile-indexing-method'
+is set to 'alien'."
+ :safe (lambda (x) (not (remq t (mapcar #'stringp x))))
+ :group 'projectile
+ :type '(repeat string))
+
+(defcustom projectile-globally-unignored-directories nil
+ "A list of directories globally unignored by projectile.
+Note that files aren't filtered if `projectile-indexing-method'
+is set to 'alien'."
+ :group 'projectile
+ :type '(repeat string)
+ :package-version '(projectile . "0.14.0"))
+
+(defcustom projectile-globally-ignored-modes
+ '("erc-mode"
+ "help-mode"
+ "completion-list-mode"
+ "Buffer-menu-mode"
+ "gnus-.*-mode"
+ "occur-mode")
+ "A list of regular expressions for major modes ignored by projectile.
+
+If a buffer is using a given major mode, projectile will ignore
+it for functions working with buffers."
+ :group 'projectile
+ :type '(repeat string))
+
+(defcustom projectile-globally-ignored-buffers nil
+ "A list of buffer-names ignored by projectile.
+
+You can use either exact buffer names or regular expressions.
+If a buffer is in the list projectile will ignore it for
+functions working with buffers."
+ :group 'projectile
+ :type '(repeat string)
+ :package-version '(projectile . "0.12.0"))
+
+(defcustom projectile-find-file-hook nil
+ "Hooks run when a file is opened with `projectile-find-file'."
+ :group 'projectile
+ :type 'hook)
+
+(defcustom projectile-find-dir-hook nil
+ "Hooks run when a directory is opened with `projectile-find-dir'."
+ :group 'projectile
+ :type 'hook)
+
+(defcustom projectile-switch-project-action 'projectile-find-file
+ "Action invoked after switching projects with `projectile-switch-project'.
+
+Any function that does not take arguments will do."
+ :group 'projectile
+ :type 'function)
+
+(defcustom projectile-find-dir-includes-top-level nil
+ "If true, add top-level dir to options offered by `projectile-find-dir'."
+ :group 'projectile
+ :type 'boolean)
+
+(defcustom projectile-use-git-grep nil
+ "If true, use `vc-git-grep' in git projects."
+ :group 'projectile
+ :type 'boolean)
+
+(defcustom projectile-grep-finished-hook nil
+ "Hooks run when `projectile-grep' finishes."
+ :group 'projectile
+ :type 'hook
+ :package-version '(projectile . "0.14.0"))
+
+(defcustom projectile-test-prefix-function 'projectile-test-prefix
+ "Function to find test files prefix based on PROJECT-TYPE."
+ :group 'projectile
+ :type 'function)
+
+(defcustom projectile-test-suffix-function 'projectile-test-suffix
+ "Function to find test files suffix based on PROJECT-TYPE."
+ :group 'projectile
+ :type 'function)
+
+(defcustom projectile-related-files-fn-function 'projectile-related-files-fn
+ "Function to find related files based on PROJECT-TYPE."
+ :group 'projectile
+ :type 'function)
+
+(defcustom projectile-dynamic-mode-line t
+ "If true, update the mode-line dynamically.
+Only file buffers are affected by this, as the update happens via
+`find-file-hook'.
+
+See also `projectile-mode-line-function' and `projectile-update-mode-line'."
+ :group 'projectile
+ :type 'boolean
+ :package-version '(projectile . "2.0.0"))
+
+(defcustom projectile-mode-line-function 'projectile-default-mode-line
+ "The function to use to generate project-specific mode-line.
+The default function adds the project name and type to the mode-line.
+See also `projectile-update-mode-line'."
+ :group 'projectile
+ :type 'function
+ :package-version '(projectile . "2.0.0"))
+
+(defcustom projectile-default-src-directory "src/"
+ "The default value of a project's src-dir property.
+
+It's used as a fallback in the case the property is not set for a project
+type when `projectile-toggle-between-implementation-and-test' is used."
+ :group 'projectile
+ :type 'string)
+
+(defcustom projectile-default-test-directory "test/"
+ "The default value of a project's test-dir property.
+
+It's used as a fallback in the case the property is not set for a project
+type when `projectile-toggle-between-implementation-and-test' is used."
+ :group 'projectile
+ :type 'string)
+
+
+;;; Idle Timer
+(defvar projectile-idle-timer nil
+ "The timer object created when `projectile-enable-idle-timer' is non-nil.")
+
+(defcustom projectile-idle-timer-seconds 30
+ "The idle period to use when `projectile-enable-idle-timer' is non-nil."
+ :group 'projectile
+ :type 'number)
+
+(defcustom projectile-idle-timer-hook '(projectile-regenerate-tags)
+ "The hook run when `projectile-enable-idle-timer' is non-nil."
+ :group 'projectile
+ :type '(repeat symbol))
+
+(defcustom projectile-enable-idle-timer nil
+ "Enables idle timer hook `projectile-idle-timer-functions'.
+
+When `projectile-enable-idle-timer' is non-nil, the hook
+`projectile-idle-timer-hook' is run each time Emacs has been idle
+for `projectile-idle-timer-seconds' seconds and we're in a
+project."
+ :group 'projectile
+ :set (lambda (symbol value)
+ (set symbol value)
+ (when projectile-idle-timer
+ (cancel-timer projectile-idle-timer))
+ (setq projectile-idle-timer nil)
+ (when projectile-enable-idle-timer
+ (setq projectile-idle-timer (run-with-idle-timer
+ projectile-idle-timer-seconds t
+ (lambda ()
+ (when (projectile-project-p)
+ (run-hooks 'projectile-idle-timer-hook)))))))
+ :type 'boolean)
+
+(defvar projectile-projects-cache nil
+ "A hashmap used to cache project file names to speed up related operations.")
+
+(defvar projectile-projects-cache-time nil
+ "A hashmap used to record when we populated `projectile-projects-cache'.")
+
+(defvar projectile-project-root-cache (make-hash-table :test 'equal)
+ "Cached value of function `projectile-project-root`.")
+
+(defvar projectile-project-type-cache (make-hash-table :test 'equal)
+ "A hashmap used to cache project type to speed up related operations.")
+
+(defvar projectile-known-projects nil
+ "List of locations where we have previously seen projects.
+The list of projects is ordered by the time they have been accessed.
+
+See also `projectile-remove-known-project',
+`projectile-cleanup-known-projects' and `projectile-clear-known-projects'.")
+
+(defvar projectile-known-projects-on-file nil
+ "List of known projects reference point.
+
+Contains a copy of `projectile-known-projects' when it was last
+synchronized with `projectile-known-projects-file'.")
+
+(defcustom projectile-known-projects-file
+ (expand-file-name "projectile-bookmarks.eld"
+ user-emacs-directory)
+ "Name and location of the Projectile's known projects file."
+ :group 'projectile
+ :type 'string)
+
+(defcustom projectile-ignored-projects nil
+ "A list of projects not to be added to `projectile-known-projects'."
+ :group 'projectile
+ :type '(repeat :tag "Project list" directory)
+ :package-version '(projectile . "0.11.0"))
+
+(defcustom projectile-ignored-project-function nil
+ "Function to decide if a project is added to `projectile-known-projects'.
+
+Can be either nil, or a function that takes the truename of the
+project root as argument and returns non-nil if the project is to
+be ignored or nil otherwise.
+
+This function is only called if the project is not listed in
+the variable `projectile-ignored-projects'.
+
+A suitable candidate would be `file-remote-p' to ignore remote
+projects."
+ :group 'projectile
+ :type '(choice
+ (const :tag "Nothing" nil)
+ (const :tag "Remote files" file-remote-p)
+ function)
+ :package-version '(projectile . "0.13.0"))
+
+(defcustom projectile-track-known-projects-automatically t
+ "Controls whether Projectile will automatically register known projects.
+
+When set to nil you'll have always add projects explicitly with
+`projectile-add-known-project'."
+ :group 'projectile
+ :type 'boolean
+ :package-version '(projectile . "1.0.0"))
+
+(defcustom projectile-project-search-path nil
+ "List of folders where projectile is automatically going to look for projects.
+You can think of something like $PATH, but for projects instead of executables.
+Examples of such paths might be ~/projects, ~/work, (~/github . 1) etc.
+
+For elements of form (DIRECTORY . DEPTH), DIRECTORY has to be a
+directory and DEPTH an integer that specifies the depth at which to
+look for projects. A DEPTH of 0 means check DIRECTORY. A depth of 1
+means check all the subdirectories of DIRECTORY. Etc."
+ :group 'projectile
+ :type '(repeat (choice directory (cons directory (integer :tag "Depth"))))
+ :package-version '(projectile . "1.0.0"))
+
+(defcustom projectile-git-command "git ls-files -zco --exclude-standard"
+ "Command used by projectile to get the files in a git project."
+ :group 'projectile
+ :type 'string)
+
+(defcustom projectile-git-submodule-command "git submodule --quiet foreach 'echo $displaypath' | tr '\\n' '\\0'"
+ "Command used by projectile to list submodules of a given git repository.
+Set to nil to disable listing submodules contents."
+ :group 'projectile
+ :type 'string)
+
+(defcustom projectile-git-ignored-command "git ls-files -zcoi --exclude-standard"
+ "Command used by projectile to get the ignored files in a git project."
+ :group 'projectile
+ :type 'string
+ :package-version '(projectile . "0.14.0"))
+
+(defcustom projectile-hg-command "hg locate -f -0 -I ."
+ "Command used by projectile to get the files in a hg project."
+ :group 'projectile
+ :type 'string)
+
+(defcustom projectile-fossil-command (concat "fossil ls | "
+ (when (string-equal system-type
+ "windows-nt")
+ "dos2unix | ")
+ "tr '\\n' '\\0'")
+ "Command used by projectile to get the files in a fossil project."
+ :group 'projectile
+ :type 'string)
+
+(defcustom projectile-bzr-command "bzr ls -R --versioned -0"
+ "Command used by projectile to get the files in a bazaar project."
+ :group 'projectile
+ :type 'string)
+
+(defcustom projectile-darcs-command "darcs show files -0 . "
+ "Command used by projectile to get the files in a darcs project."
+ :group 'projectile
+ :type 'string)
+
+(defcustom projectile-pijul-command "pijul list | tr '\\n' '\\0'"
+ "Command used by projectile to get the files in a pijul project."
+ :group 'projectile
+ :type 'string)
+
+(defcustom projectile-svn-command "svn list -R . | grep -v '$/' | tr '\\n' '\\0'"
+ "Command used by projectile to get the files in a svn project."
+ :group 'projectile
+ :type 'string)
+
+(defcustom projectile-generic-command
+ (cond
+ ;; we prefer fd over find
+ ((executable-find "fd")
+ "fd . -0 --type f --color=never")
+ ;; fd's executable is named fdfind is some Linux distros (e.g. Ubuntu)
+ ((executable-find "fdfind")
+ "fdfind . -0 --type f --color=never")
+ ;; with find we have to be careful to strip the ./ from the paths
+ ;; see https://stackoverflow.com/questions/2596462/how-to-strip-leading-in-unix-find
+ (t "find . -type f | cut -c3- | tr '\\n' '\\0'"))
+ "Command used by projectile to get the files in a generic project."
+ :group 'projectile
+ :type 'string)
+
+(defcustom projectile-vcs-dirty-state '("edited" "unregistered" "needs-update" "needs-merge" "unlocked-changes" "conflict")
+ "List of states checked by `projectile-browse-dirty-projects'.
+Possible checked states are:
+\"edited\", \"unregistered\", \"needs-update\", \"needs-merge\",
+\"unlocked-changes\" and \"conflict\",
+as defined in `vc.el'."
+ :group 'projectile
+ :type '(repeat (string))
+ :package-version '(projectile . "1.0.0"))
+
+(defcustom projectile-other-file-alist
+ '( ;; handle C/C++ extensions
+ ("cpp" . ("h" "hpp" "ipp"))
+ ("ipp" . ("h" "hpp" "cpp"))
+ ("hpp" . ("h" "ipp" "cpp" "cc"))
+ ("cxx" . ("h" "hxx" "ixx"))
+ ("ixx" . ("h" "hxx" "cxx"))
+ ("hxx" . ("h" "ixx" "cxx"))
+ ("c" . ("h"))
+ ("m" . ("h"))
+ ("mm" . ("h"))
+ ("h" . ("c" "cc" "cpp" "ipp" "hpp" "cxx" "ixx" "hxx" "m" "mm"))
+ ("cc" . ("h" "hh" "hpp"))
+ ("hh" . ("cc"))
+
+ ;; OCaml extensions
+ ("ml" . ("mli"))
+ ("mli" . ("ml" "mll" "mly"))
+ ("mll" . ("mli"))
+ ("mly" . ("mli"))
+ ("eliomi" . ("eliom"))
+ ("eliom" . ("eliomi"))
+
+ ;; vertex shader and fragment shader extensions in glsl
+ ("vert" . ("frag"))
+ ("frag" . ("vert"))
+
+ ;; handle files with no extension
+ (nil . ("lock" "gpg"))
+ ("lock" . (""))
+ ("gpg" . (""))
+ )
+ "Alist of extensions for switching to file with the same name,
+ using other extensions based on the extension of current
+ file."
+ :type 'alist)
+
+(defcustom projectile-create-missing-test-files nil
+ "During toggling, if non-nil enables creating test files if not found.
+
+When not-nil, every call to projectile-find-implementation-or-test-*
+creates test files if not found on the file system. Defaults to nil.
+It assumes the test/ folder is at the same level as src/."
+ :group 'projectile
+ :type 'boolean)
+
+(defcustom projectile-per-project-compilation-buffer nil
+ "When non-nil, the compilation command makes the per-project compilation buffer."
+ :group 'projectile
+ :type 'boolean
+ :package-version '(projectile . "2.6.0"))
+
+(defcustom projectile-after-switch-project-hook nil
+ "Hooks run right after project is switched."
+ :group 'projectile
+ :type 'hook)
+
+(defcustom projectile-before-switch-project-hook nil
+ "Hooks run when right before project is switched."
+ :group 'projectile
+ :type 'hook)
+
+(defcustom projectile-current-project-on-switch 'remove
+ "Determines whether to display current project when switching projects.
+
+When set to 'remove current project is not included, 'move-to-end
+will display current project and the end of the list of known
+projects, 'keep will leave the current project at the default
+position."
+ :group 'projectile
+ :type '(radio
+ (const :tag "Remove" remove)
+ (const :tag "Move to end" move-to-end)
+ (const :tag "Keep" keep)))
+
+(defcustom projectile-max-file-buffer-count nil
+ "Maximum number of file buffers per project that are kept open.
+
+If the value is nil, there is no limit to the opend buffers count."
+ :group 'projectile
+ :type 'integer
+ :package-version '(projectile . "2.2.0"))
+
+
+;;; Version information
+
+(defconst projectile-version "2.6.0-snapshot"
+ "The current version of Projectile.")
+
+(defun projectile--pkg-version ()
+ "Extract Projectile's package version from its package metadata."
+ ;; Use `cond' below to avoid a compiler unused return value warning
+ ;; when `package-get-version' returns nil. See #3181.
+ ;; FIXME: Inline the logic from package-get-version and adapt it
+ (cond ((fboundp 'package-get-version)
+ (package-get-version))))
+
+;;;###autoload
+(defun projectile-version (&optional show-version)
+ "Get the Projectile version as string.
+
+If called interactively or if SHOW-VERSION is non-nil, show the
+version in the echo area and the messages buffer.
+
+The returned string includes both, the version from package.el
+and the library version, if both a present and different.
+
+If the version number could not be determined, signal an error,
+if called interactively, or if SHOW-VERSION is non-nil, otherwise
+just return nil."
+ (interactive (list t))
+ (let ((version (or (projectile--pkg-version) projectile-version)))
+ (if show-version
+ (message "Projectile %s" version)
+ version)))
+
+;;; Misc utility functions
+(defun projectile-difference (list1 list2)
+ (cl-remove-if
+ (lambda (x) (member x list2))
+ list1))
+
+(defun projectile-unixy-system-p ()
+ "Check to see if unixy text utilities are installed."
+ (cl-every
+ (lambda (x) (executable-find x))
+ '("grep" "cut" "uniq")))
+
+(defun projectile-symbol-or-selection-at-point ()
+ "Get the symbol or selected text at point."
+ (if (use-region-p)
+ (buffer-substring-no-properties (region-beginning) (region-end))
+ (projectile-symbol-at-point)))
+
+(defun projectile-symbol-at-point ()
+ "Get the symbol at point and strip its properties."
+ (substring-no-properties (or (thing-at-point 'symbol) "")))
+
+(defun projectile-generate-process-name (process make-new &optional project)
+ "Infer the buffer name for PROCESS or generate a new one if MAKE-NEW is true.
+The function operates on the current project by default, but you can also
+specify a project explicitly via the optional PROJECT param."
+ (let* ((project (or project (projectile-acquire-root)))
+ (base-name (format "*%s %s*" process (projectile-project-name project))))
+ (if make-new
+ (generate-new-buffer-name base-name)
+ base-name)))
+
+
+;;; Serialization
+(defun projectile-serialize (data filename)
+ "Serialize DATA to FILENAME.
+
+The saved data can be restored with `projectile-unserialize'."
+ (if (file-writable-p filename)
+ (with-temp-file filename
+ (insert (let (print-length) (prin1-to-string data))))
+ (message "Projectile cache '%s' not writeable" filename)))
+
+(defun projectile-unserialize (filename)
+ "Read data serialized by `projectile-serialize' from FILENAME."
+ (with-demoted-errors
+ "Error during file deserialization: %S"
+ (when (file-exists-p filename)
+ (with-temp-buffer
+ (insert-file-contents filename)
+ ;; this will blow up if the contents of the file aren't
+ ;; lisp data structures
+ (read (buffer-string))))))
+
+
+;;; Caching
+(defvar projectile-file-exists-cache
+ (make-hash-table :test 'equal)
+ "Cached `projectile-file-exists-p' results.")
+
+(defvar projectile-file-exists-cache-timer nil
+ "Timer for scheduling`projectile-file-exists-cache-cleanup'.")
+
+(defun projectile-file-exists-cache-cleanup ()
+ "Removed timed out cache entries and reschedules or remove the
+timer if no more items are in the cache."
+ (let ((now (current-time)))
+ (maphash (lambda (key value)
+ (if (time-less-p (cdr value) now)
+ (remhash key projectile-file-exists-cache)))
+ projectile-file-exists-cache)
+ (setq projectile-file-exists-cache-timer
+ (if (> (hash-table-count projectile-file-exists-cache) 0)
+ (run-with-timer 10 nil 'projectile-file-exists-cache-cleanup)))))
+
+(defun projectile-file-exists-p (filename)
+ "Return t if file FILENAME exist.
+A wrapper around `file-exists-p' with additional caching support."
+ (let* ((file-remote (file-remote-p filename))
+ (expire-seconds
+ (if file-remote
+ (and projectile-file-exists-remote-cache-expire
+ (> projectile-file-exists-remote-cache-expire 0)
+ projectile-file-exists-remote-cache-expire)
+ (and projectile-file-exists-local-cache-expire
+ (> projectile-file-exists-local-cache-expire 0)
+ projectile-file-exists-local-cache-expire)))
+ (remote-file-name-inhibit-cache (if expire-seconds
+ expire-seconds
+ remote-file-name-inhibit-cache)))
+ (if (not expire-seconds)
+ (file-exists-p filename)
+ (let* ((current-time (current-time))
+ (cached (gethash filename projectile-file-exists-cache))
+ (cached-value (if cached (car cached)))
+ (cached-expire (if cached (cdr cached)))
+ (cached-expired (if cached (time-less-p cached-expire current-time) t))
+ (value (or (and (not cached-expired) cached-value)
+ (if (file-exists-p filename) 'found 'notfound))))
+ (when (or (not cached) cached-expired)
+ (puthash filename
+ (cons value (time-add current-time (seconds-to-time expire-seconds)))
+ projectile-file-exists-cache))
+ (unless projectile-file-exists-cache-timer
+ (setq projectile-file-exists-cache-timer
+ (run-with-timer 10 nil 'projectile-file-exists-cache-cleanup)))
+ (equal value 'found)))))
+
+;;;###autoload
+(defun projectile-invalidate-cache (prompt)
+ "Remove the current project's files from `projectile-projects-cache'.
+
+With a prefix argument PROMPT prompts for the name of the project whose cache
+to invalidate."
+ (interactive "P")
+ (let ((project-root
+ (if prompt
+ (completing-read "Remove cache for: "
+ (hash-table-keys projectile-projects-cache))
+ (projectile-acquire-root))))
+ (setq projectile-project-root-cache (make-hash-table :test 'equal))
+ (remhash project-root projectile-project-type-cache)
+ (remhash project-root projectile-projects-cache)
+ (remhash project-root projectile-projects-cache-time)
+ (projectile-serialize-cache)
+ (when projectile-verbose
+ (message "Invalidated Projectile cache for %s."
+ (propertize project-root 'face 'font-lock-keyword-face))))
+ (when (fboundp 'recentf-cleanup)
+ (recentf-cleanup)))
+
+(defun projectile-time-seconds ()
+ "Return the number of seconds since the unix epoch."
+ (if (fboundp 'time-convert)
+ (time-convert nil 'integer)
+ (cl-destructuring-bind (high low _usec _psec) (current-time)
+ (+ (lsh high 16) low))))
+
+(defun projectile-cache-project (project files)
+ "Cache PROJECTs FILES.
+The cache is created both in memory and on the hard drive."
+ (when projectile-enable-caching
+ (puthash project files projectile-projects-cache)
+ (puthash project (projectile-time-seconds) projectile-projects-cache-time)
+ (projectile-serialize-cache)))
+
+;;;###autoload
+(defun projectile-purge-file-from-cache (file)
+ "Purge FILE from the cache of the current project."
+ (interactive
+ (list (projectile-completing-read
+ "Remove file from cache: "
+ (projectile-current-project-files))))
+ (let* ((project-root (projectile-project-root))
+ (project-cache (gethash project-root projectile-projects-cache)))
+ (if (projectile-file-cached-p file project-root)
+ (progn
+ (puthash project-root (remove file project-cache) projectile-projects-cache)
+ (projectile-serialize-cache)
+ (when projectile-verbose
+ (message "%s removed from cache" file)))
+ (error "%s is not in the cache" file))))
+
+;;;###autoload
+(defun projectile-purge-dir-from-cache (dir)
+ "Purge DIR from the cache of the current project."
+ (interactive
+ (list (projectile-completing-read
+ "Remove directory from cache: "
+ (projectile-current-project-dirs))))
+ (let* ((project-root (projectile-project-root))
+ (project-cache (gethash project-root projectile-projects-cache)))
+ (puthash project-root
+ (cl-remove-if (lambda (str) (string-prefix-p dir str)) project-cache)
+ projectile-projects-cache)))
+
+(defun projectile-file-cached-p (file project)
+ "Check if FILE is already in PROJECT cache."
+ (member file (gethash project projectile-projects-cache)))
+
+;;;###autoload
+(defun projectile-cache-current-file ()
+ "Add the currently visited file to the cache."
+ (interactive)
+ (let ((current-project (projectile-project-root)))
+ (when (and (buffer-file-name) (gethash (projectile-project-root) projectile-projects-cache))
+ (let* ((abs-current-file (file-truename (buffer-file-name)))
+ (current-file (file-relative-name abs-current-file current-project)))
+ (unless (or (projectile-file-cached-p current-file current-project)
+ (projectile-ignored-directory-p (file-name-directory abs-current-file))
+ (projectile-ignored-file-p abs-current-file))
+ (puthash current-project
+ (cons current-file (gethash current-project projectile-projects-cache))
+ projectile-projects-cache)
+ (projectile-serialize-cache)
+ (message "File %s added to project %s cache."
+ (propertize current-file 'face 'font-lock-keyword-face)
+ (propertize current-project 'face 'font-lock-keyword-face)))))))
+
+;; cache opened files automatically to reduce the need for cache invalidation
+(defun projectile-cache-files-find-file-hook ()
+ "Function for caching files with `find-file-hook'."
+ (let ((project-root (projectile-project-p)))
+ (when (and projectile-enable-caching
+ project-root
+ (not (projectile-ignored-project-p project-root)))
+ (projectile-cache-current-file))))
+
+(defun projectile-track-known-projects-find-file-hook ()
+ "Function for caching projects with `find-file-hook'."
+ (when (and projectile-track-known-projects-automatically (projectile-project-p))
+ (projectile-add-known-project (projectile-project-root))))
+
+(defun projectile-maybe-invalidate-cache (force)
+ "Invalidate if FORCE or project's dirconfig newer than cache."
+ (when (or force (file-newer-than-file-p (projectile-dirconfig-file)
+ projectile-cache-file))
+ (projectile-invalidate-cache nil)))
+
+;;;###autoload
+(defun projectile-discover-projects-in-directory (directory &optional depth)
+ "Discover any projects in DIRECTORY and add them to the projectile cache.
+
+If DEPTH is non-nil recursively descend exactly DEPTH levels below DIRECTORY and
+discover projects there."
+ (interactive
+ (list (read-directory-name "Starting directory: ")))
+
+ (if (file-directory-p directory)
+ (if (and (numberp depth) (> depth 0))
+ ;; Ignore errors when listing files in the directory, because
+ ;; sometimes that directory is an unreadable one at the root of a
+ ;; volume. This is the case, for example, on macOS with the
+ ;; .Spotlight-V100 directory.
+ (dolist (dir (ignore-errors (directory-files directory t)))
+ (when (and (file-directory-p dir)
+ (not (member (file-name-nondirectory dir) '(".." "."))))
+ (projectile-discover-projects-in-directory dir (1- depth))))
+ (when (projectile-project-p directory)
+ (let ((dir (abbreviate-file-name (projectile-project-root directory))))
+ (unless (member dir projectile-known-projects)
+ (projectile-add-known-project dir)))))
+ (message "Project search path directory %s doesn't exist" directory)))
+
+;;;###autoload
+(defun projectile-discover-projects-in-search-path ()
+ "Discover projects in `projectile-project-search-path'.
+Invoked automatically when `projectile-mode' is enabled."
+ (interactive)
+ (dolist (path projectile-project-search-path)
+ (if (consp path)
+ (projectile-discover-projects-in-directory (car path) (cdr path))
+ (projectile-discover-projects-in-directory path 1))))
+
+
+(defun delete-file-projectile-remove-from-cache (filename &optional _trash)
+ (if (and projectile-enable-caching projectile-auto-update-cache (projectile-project-p))
+ (let* ((project-root (projectile-project-root))
+ (true-filename (file-truename filename))
+ (relative-filename (file-relative-name true-filename project-root)))
+ (if (projectile-file-cached-p relative-filename project-root)
+ (projectile-purge-file-from-cache relative-filename)))))
+
+
+;;; Project root related utilities
+(defun projectile-parent (path)
+ "Return the parent directory of PATH.
+PATH may be a file or directory and directory paths may end with a slash."
+ (directory-file-name (file-name-directory (directory-file-name (expand-file-name path)))))
+
+(defun projectile-locate-dominating-file (file name)
+ "Look up the directory hierarchy from FILE for a directory containing NAME.
+Stop at the first parent directory containing a file NAME,
+and return the directory. Return nil if not found.
+Instead of a string, NAME can also be a predicate taking one argument
+\(a directory) and returning a non-nil value if that directory is the one for
+which we're looking."
+ ;; copied from files.el (stripped comments) emacs-24 bzr branch 2014-03-28 10:20
+ (setq file (abbreviate-file-name file))
+ (let ((root nil)
+ try)
+ (while (not (or root
+ (null file)
+ (string-match locate-dominating-stop-dir-regexp file)))
+ (setq try (if (stringp name)
+ (projectile-file-exists-p (expand-file-name name file))
+ (funcall name file)))
+ (cond (try (setq root file))
+ ((equal file (setq file (file-name-directory
+ (directory-file-name file))))
+ (setq file nil))))
+ (and root (expand-file-name (file-name-as-directory root)))))
+
+(defvar-local projectile-project-root nil
+ "Defines a custom Projectile project root.
+This is intended to be used as a file local variable.")
+
+(defun projectile-root-local (_dir)
+ "A simple wrapper around the variable `projectile-project-root'."
+ projectile-project-root)
+
+(defun projectile-root-top-down (dir &optional list)
+ "Identify a project root in DIR by top-down search for files in LIST.
+If LIST is nil, use `projectile-project-root-files' instead.
+Return the first (topmost) matched directory or nil if not found."
+ (projectile-locate-dominating-file
+ dir
+ (lambda (dir)
+ (cl-find-if (lambda (f) (projectile-file-exists-p (expand-file-name f dir)))
+ (or list projectile-project-root-files)))))
+
+(defun projectile-root-bottom-up (dir &optional list)
+ "Identify a project root in DIR by bottom-up search for files in LIST.
+If LIST is nil, use `projectile-project-root-files-bottom-up' instead.
+Return the first (bottommost) matched directory or nil if not found."
+ (cl-some (lambda (name) (projectile-locate-dominating-file dir name))
+ (or list projectile-project-root-files-bottom-up)))
+
+(defun projectile-root-top-down-recurring (dir &optional list)
+ "Identify a project root in DIR by recurring top-down search for files in LIST.
+If LIST is nil, use `projectile-project-root-files-top-down-recurring'
+instead. Return the last (bottommost) matched directory in the
+topmost sequence of matched directories. Nil otherwise."
+ (cl-some
+ (lambda (f)
+ (projectile-locate-dominating-file
+ dir
+ (lambda (dir)
+ (and (projectile-file-exists-p (expand-file-name f dir))
+ (or (string-match locate-dominating-stop-dir-regexp (projectile-parent dir))
+ (not (projectile-file-exists-p (expand-file-name f (projectile-parent dir)))))))))
+ (or list projectile-project-root-files-top-down-recurring)))
+
+(defun projectile-project-root (&optional dir)
+ "Retrieves the root directory of a project if available.
+If DIR is not supplied its set to the current directory by default."
+ ;; the cached value will be 'none in the case of no project root (this is to
+ ;; ensure it is not reevaluated each time when not inside a project) so use
+ ;; cl-subst to replace this 'none value with nil so a nil value is used
+ ;; instead
+ (let ((dir (or dir default-directory)))
+ ;; Back out of any archives, the project will live on the outside and
+ ;; searching them is slow.
+ (when (and (fboundp 'tramp-archive-file-name-archive)
+ (tramp-archive-file-name-p dir))
+ (setq dir (file-name-directory (tramp-archive-file-name-archive dir))))
+ (cl-subst nil 'none
+ ;; The `is-local' and `is-connected' variables are
+ ;; used to fix the behavior where Emacs hangs
+ ;; because of Projectile when you open a file over
+ ;; TRAMP. It basically prevents Projectile from
+ ;; trying to find information about files for which
+ ;; it's not possible to get that information right
+ ;; now.
+ (or (let ((is-local (not (file-remote-p dir))) ;; `true' if the file is local
+ (is-connected (file-remote-p dir nil t))) ;; `true' if the file is remote AND we are connected to the remote
+ (when (or is-local is-connected)
+ ;; Here is where all the magic happens.
+ ;; We run the functions in `projectile-project-root-functions' until we find a project dir.
+ (cl-some
+ (lambda (func)
+ (let* ((cache-key (format "%s-%s" func dir))
+ (cache-value (gethash cache-key projectile-project-root-cache)))
+ (if (and cache-value (file-exists-p cache-value))
+ cache-value
+ (let ((value (funcall func (file-truename dir))))
+ (puthash cache-key value projectile-project-root-cache)
+ value))))
+ projectile-project-root-functions)))
+ ;; set cached to none so is non-nil so we don't try
+ ;; and look it up again
+ 'none))))
+
+(defun projectile-ensure-project (dir)
+ "Ensure that DIR is non-nil.
+Useful for commands that expect the presence of a project.
+Controlled by `projectile-require-project-root'.
+
+See also `projectile-acquire-root'."
+ (if dir
+ dir
+ (cond
+ ((eq projectile-require-project-root 'prompt) (projectile-completing-read
+ "Switch to project: " projectile-known-projects))
+ (projectile-require-project-root (error "Projectile cannot find a project definition in %s" default-directory))
+ (t default-directory))))
+
+(defun projectile-acquire-root (&optional dir)
+ "Find the current project root, and prompts the user for it if that fails.
+Provides the common idiom (projectile-ensure-project (projectile-project-root)).
+Starts the search for the project with DIR."
+ (projectile-ensure-project (projectile-project-root dir)))
+
+(defun projectile-project-p (&optional dir)
+ "Check if DIR is a project.
+Defaults to the current directory if not provided
+explicitly."
+ (projectile-project-root (or dir default-directory)))
+
+(defun projectile-default-project-name (project-root)
+ "Default function used to create the project name.
+The project name is based on the value of PROJECT-ROOT."
+ (file-name-nondirectory (directory-file-name project-root)))
+
+(defun projectile-project-name (&optional project)
+ "Return project name.
+If PROJECT is not specified acts on the current project."
+ (or projectile-project-name
+ (let ((project-root (or project (projectile-project-root))))
+ (if project-root
+ (funcall projectile-project-name-function project-root)
+ "-"))))
+
+
+;;; Project indexing
+(defun projectile-get-project-directories (project-dir)
+ "Get the list of PROJECT-DIR directories that are of interest to the user."
+ (mapcar (lambda (subdir) (concat project-dir subdir))
+ (or (nth 0 (projectile-parse-dirconfig-file)) '(""))))
+
+(defun projectile--directory-p (directory)
+ "Checks if DIRECTORY is a string designating a valid directory."
+ (and (stringp directory) (file-directory-p directory)))
+
+(defun projectile-dir-files (directory)
+ "List the files in DIRECTORY and in its sub-directories.
+Files are returned as relative paths to DIRECTORY."
+ (unless (projectile--directory-p directory)
+ (error "Directory %S does not exist" directory))
+ ;; check for a cache hit first if caching is enabled
+ (let ((files-list (and projectile-enable-caching
+ (gethash directory projectile-projects-cache))))
+ ;; cache disabled or cache miss
+ (or files-list
+ (let ((vcs (projectile-project-vcs directory)))
+ (pcase projectile-indexing-method
+ ('native (projectile-dir-files-native directory))
+ ;; use external tools to get the project files
+ ('hybrid (projectile-adjust-files directory vcs (projectile-dir-files-alien directory)))
+ ('alien (projectile-dir-files-alien directory))
+ (_ (user-error "Unsupported indexing method `%S'" projectile-indexing-method)))))))
+
+;;; Native Project Indexing
+;;
+;; This corresponds to `projectile-indexing-method' being set to native.
+(defun projectile-dir-files-native (directory)
+ "Get the files for ROOT under DIRECTORY using just Emacs Lisp."
+ (let ((progress-reporter
+ (make-progress-reporter
+ (format "Projectile is indexing %s"
+ (propertize directory 'face 'font-lock-keyword-face)))))
+ ;; we need the files with paths relative to the project root
+ (mapcar (lambda (file) (file-relative-name file directory))
+ (projectile-index-directory directory (projectile-filtering-patterns)
+ progress-reporter))))
+
+(defun projectile-index-directory (directory patterns progress-reporter &optional ignored-files ignored-directories globally-ignored-directories)
+ "Index DIRECTORY taking into account PATTERNS.
+
+The function calls itself recursively until all sub-directories
+have been indexed. The PROGRESS-REPORTER is updated while the
+function is executing. The list of IGNORED-FILES and
+IGNORED-DIRECTORIES may optionally be provided."
+ ;; we compute the ignored files and directories only once and then we reuse the
+ ;; pre-computed values in the subsequent recursive invocations of the function
+ (let ((ignored-files (or ignored-files (projectile-ignored-files)))
+ (ignored-directories (or ignored-directories (projectile-ignored-directories)))
+ (globally-ignored-directories (or globally-ignored-directories (projectile-globally-ignored-directory-names))))
+ (apply #'append
+ (mapcar
+ (lambda (f)
+ (let ((local-f (file-name-nondirectory (directory-file-name f))))
+ (unless (or (and patterns (projectile-ignored-rel-p f directory patterns))
+ (member local-f '("." "..")))
+ (progress-reporter-update progress-reporter)
+ (if (file-directory-p f)
+ (unless (projectile-ignored-directory-p
+ (file-name-as-directory f)
+ ignored-directories
+ local-f
+ globally-ignored-directories)
+ (projectile-index-directory f patterns progress-reporter ignored-files ignored-directories globally-ignored-directories))
+ (unless (projectile-ignored-file-p f ignored-files)
+ (list f))))))
+ (directory-files directory t)))))
+
+;;; Alien Project Indexing
+;;
+;; This corresponds to `projectile-indexing-method' being set to hybrid or alien.
+;; The only difference between the two methods is that alien doesn't do
+;; any post-processing of the files obtained via the external command.
+(defun projectile-dir-files-alien (directory)
+ "Get the files for DIRECTORY using external tools."
+ (let ((vcs (projectile-project-vcs directory)))
+ (cond
+ ((eq vcs 'git)
+ (nconc (projectile-files-via-ext-command directory (projectile-get-ext-command vcs))
+ (projectile-get-sub-projects-files directory vcs)))
+ (t (projectile-files-via-ext-command directory (projectile-get-ext-command vcs))))))
+
+(define-obsolete-function-alias 'projectile-dir-files-external 'projectile-dir-files-alien "2.0.0")
+(define-obsolete-function-alias 'projectile-get-repo-files 'projectile-dir-files-alien "2.0.0")
+
+(defun projectile-get-ext-command (vcs)
+ "Determine which external command to invoke based on the project's VCS.
+Fallback to a generic command when not in a VCS-controlled project."
+ (pcase vcs
+ ('git projectile-git-command)
+ ('hg projectile-hg-command)
+ ('fossil projectile-fossil-command)
+ ('bzr projectile-bzr-command)
+ ('darcs projectile-darcs-command)
+ ('pijul projectile-pijul-command)
+ ('svn projectile-svn-command)
+ (_ projectile-generic-command)))
+
+(defun projectile-get-sub-projects-command (vcs)
+ "Get the sub-projects command for VCS.
+Currently that's supported just for Git (sub-projects being Git
+sub-modules there)."
+ (pcase vcs
+ ('git projectile-git-submodule-command)
+ (_ "")))
+
+(defun projectile-get-ext-ignored-command (vcs)
+ "Determine which external command to invoke based on the project's VCS."
+ (pcase vcs
+ ('git projectile-git-ignored-command)
+ ;; TODO: Add support for other VCS
+ (_ nil)))
+
+(defun projectile-flatten (lst)
+ "Take a nested list LST and return its contents as a single, flat list."
+ (if (and (listp lst) (listp (cdr lst)))
+ (cl-mapcan 'projectile-flatten lst)
+ (list lst)))
+
+(defun projectile-get-all-sub-projects (project)
+ "Get all sub-projects for a given project.
+
+PROJECT is base directory to start search recursively."
+ (let ((submodules (projectile-get-immediate-sub-projects project)))
+ (cond
+ ((null submodules)
+ nil)
+ (t
+ (nconc submodules (projectile-flatten
+ ;; recursively get sub-projects of each sub-project
+ (mapcar (lambda (s)
+ (projectile-get-all-sub-projects s)) submodules)))))))
+
+(defun projectile-get-immediate-sub-projects (path)
+ "Get immediate sub-projects for a given project without recursing.
+
+PATH is the vcs root or project root from which to start
+searching, and should end with an appropriate path delimiter, such as
+'/' or a '\\'.
+
+If the vcs get-sub-projects query returns results outside of path,
+they are excluded from the results of this function."
+ (let* ((vcs (projectile-project-vcs path))
+ ;; search for sub-projects under current project `project'
+ (submodules (mapcar
+ (lambda (s)
+ (file-name-as-directory (expand-file-name s path)))
+ (projectile-files-via-ext-command path (projectile-get-sub-projects-command vcs))))
+ (project-child-folder-regex
+ (concat "\\`"
+ (regexp-quote path))))
+
+ ;; If project root is inside of an VCS folder, but not actually an
+ ;; VCS root itself, submodules external to the project will be
+ ;; included in the VCS get sub-projects result. Let's remove them.
+ (cl-remove-if-not
+ (lambda (submodule)
+ (string-match-p project-child-folder-regex
+ submodule))
+ submodules)))
+
+(defun projectile-get-sub-projects-files (project-root _vcs)
+ "Get files from sub-projects for PROJECT-ROOT recursively."
+ (projectile-flatten
+ (mapcar (lambda (sub-project)
+ (let ((project-relative-path
+ (file-name-as-directory (file-relative-name
+ sub-project project-root))))
+ (mapcar (lambda (file)
+ (concat project-relative-path file))
+ ;; TODO: Seems we forgot git hardcoded here
+ (projectile-files-via-ext-command sub-project projectile-git-command))))
+ (projectile-get-all-sub-projects project-root))))
+
+(defun projectile-get-repo-ignored-files (project vcs)
+ "Get a list of the files ignored in the PROJECT using VCS."
+ (let ((cmd (projectile-get-ext-ignored-command vcs)))
+ (when cmd
+ (projectile-files-via-ext-command project cmd))))
+
+(defun projectile-get-repo-ignored-directory (project dir vcs)
+ "Get a list of the files ignored in the PROJECT in the directory DIR.
+VCS is the VCS of the project."
+ (let ((cmd (projectile-get-ext-ignored-command vcs)))
+ (when cmd
+ (projectile-files-via-ext-command project (concat cmd " " dir)))))
+
+(defun projectile-files-via-ext-command (root command)
+ "Get a list of relative file names in the project ROOT by executing COMMAND.
+
+If `command' is nil or an empty string, return nil.
+This allows commands to be disabled.
+
+Only text sent to standard output is taken into account."
+ (when (stringp command)
+ (let ((default-directory root))
+ (with-temp-buffer
+ (shell-command command t "*projectile-files-errors*")
+ (let ((shell-output (buffer-substring (point-min) (point-max))))
+ (split-string (string-trim shell-output) "\0" t))))))
+
+(defun projectile-adjust-files (project vcs files)
+ "First remove ignored files from FILES, then add back unignored files."
+ (projectile-add-unignored project vcs (projectile-remove-ignored files)))
+
+(defun projectile-remove-ignored (files)
+ "Remove ignored files and folders from FILES.
+
+If ignored directory prefixed with '*', then ignore all
+directories/subdirectories with matching filename,
+otherwise operates relative to project root."
+ (let ((ignored-files (projectile-ignored-files-rel))
+ (ignored-dirs (projectile-ignored-directories-rel)))
+ (cl-remove-if
+ (lambda (file)
+ (or (cl-some
+ (lambda (f)
+ (string= f (file-name-nondirectory file)))
+ ignored-files)
+ (cl-some
+ (lambda (dir)
+ ;; if the directory is prefixed with '*' then ignore all directories matching that name
+ (if (string-prefix-p "*" dir)
+ ;; remove '*' and trailing slash from ignored directory name
+ (let ((d (substring dir 1 (if (equal (substring dir -1) "/") -1 nil))))
+ (cl-some
+ (lambda (p)
+ (string= d p))
+ ;; split path by '/', remove empty strings, and check if any subdirs match name 'd'
+ (delete "" (split-string (or (file-name-directory file) "") "/"))))
+ (string-prefix-p dir file)))
+ ignored-dirs)
+ (cl-some
+ (lambda (suf)
+ (string-suffix-p suf file t))
+ projectile-globally-ignored-file-suffixes)))
+ files)))
+
+(defun projectile-keep-ignored-files (project vcs files)
+ "Filter FILES to retain only those that are ignored."
+ (when files
+ (cl-remove-if-not
+ (lambda (file)
+ (cl-some (lambda (f) (string-prefix-p f file)) files))
+ (projectile-get-repo-ignored-files project vcs))))
+
+(defun projectile-keep-ignored-directories (project vcs directories)
+ "Get ignored files within each of DIRECTORIES."
+ (when directories
+ (let (result)
+ (dolist (dir directories result)
+ (setq result (append result
+ (projectile-get-repo-ignored-directory project dir vcs))))
+ result)))
+
+(defun projectile-add-unignored (project vcs files)
+ "This adds unignored files to FILES.
+
+Useful because the VCS may not return ignored files at all. In
+this case unignored files will be absent from FILES."
+ (let ((unignored-files (projectile-keep-ignored-files
+ project
+ vcs
+ (projectile-unignored-files-rel)))
+ (unignored-paths (projectile-remove-ignored
+ (projectile-keep-ignored-directories
+ project
+ vcs
+ (projectile-unignored-directories-rel)))))
+ (append files unignored-files unignored-paths)))
+
+(defun projectile-buffers-with-file (buffers)
+ "Return only those BUFFERS backed by files."
+ (cl-remove-if-not (lambda (b) (buffer-file-name b)) buffers))
+
+(defun projectile-buffers-with-file-or-process (buffers)
+ "Return only those BUFFERS backed by files or processes."
+ (cl-remove-if-not (lambda (b) (or (buffer-file-name b)
+ (get-buffer-process b))) buffers))
+
+(defun projectile-project-buffers (&optional project)
+ "Get a list of a project's buffers.
+If PROJECT is not specified the command acts on the current project."
+ (let* ((project-root (or project (projectile-acquire-root)))
+ (all-buffers (cl-remove-if-not
+ (lambda (buffer)
+ (projectile-project-buffer-p buffer project-root))
+ (buffer-list))))
+ (if projectile-buffers-filter-function
+ (funcall projectile-buffers-filter-function all-buffers)
+ all-buffers)))
+
+(defun projectile-process-current-project-buffers (action)
+ "Process the current project's buffers using ACTION."
+ (let ((project-buffers (projectile-project-buffers)))
+ (dolist (buffer project-buffers)
+ (funcall action buffer))))
+
+(defun projectile-process-current-project-buffers-current (action)
+ "Invoke ACTION on every project buffer with that buffer current.
+ACTION is called without arguments."
+ (let ((project-buffers (projectile-project-buffers)))
+ (dolist (buffer project-buffers)
+ (with-current-buffer buffer
+ (funcall action)))))
+
+(defun projectile-project-buffer-files (&optional project)
+ "Get a list of a project's buffer files.
+If PROJECT is not specified the command acts on the current project."
+ (let ((project-root (or project (projectile-project-root))))
+ (mapcar
+ (lambda (buffer)
+ (file-relative-name
+ (buffer-file-name buffer)
+ project-root))
+ (projectile-buffers-with-file
+ (projectile-project-buffers project)))))
+
+(defun projectile-project-buffer-p (buffer project-root)
+ "Check if BUFFER is under PROJECT-ROOT."
+ (with-current-buffer buffer
+ (let ((directory (if buffer-file-name
+ (file-name-directory buffer-file-name)
+ default-directory)))
+ (and (not (string-prefix-p " " (buffer-name buffer)))
+ (not (projectile-ignored-buffer-p buffer))
+ directory
+ (string-equal (file-remote-p directory)
+ (file-remote-p project-root))
+ (not (string-match-p "^http\\(s\\)?://" directory))
+ (string-prefix-p project-root (file-truename directory) (eq system-type 'windows-nt))))))
+
+(defun projectile-ignored-buffer-p (buffer)
+ "Check if BUFFER should be ignored.
+
+Regular expressions can be use."
+ (or
+ (with-current-buffer buffer
+ (cl-some
+ (lambda (name)
+ (string-match-p name (buffer-name)))
+ projectile-globally-ignored-buffers))
+ (with-current-buffer buffer
+ (cl-some
+ (lambda (mode)
+ (string-match-p (concat "^" mode "$")
+ (symbol-name major-mode)))
+ projectile-globally-ignored-modes))))
+
+(defun projectile-recently-active-files ()
+ "Get list of recently active files.
+
+Files are ordered by recently active buffers, and then recently
+opened through use of recentf."
+ (let ((project-buffer-files (projectile-project-buffer-files)))
+ (append project-buffer-files
+ (projectile-difference
+ (projectile-recentf-files)
+ project-buffer-files))))
+
+(defun projectile-project-buffer-names ()
+ "Get a list of project buffer names."
+ (mapcar #'buffer-name (projectile-project-buffers)))
+
+(defun projectile-prepend-project-name (string)
+ "Prepend the current project's name to STRING."
+ (format "[%s] %s" (projectile-project-name) string))
+
+(defun projectile-read-buffer-to-switch (prompt)
+ "Read the name of a buffer to switch to, prompting with PROMPT.
+
+This function excludes the current buffer from the offered
+choices."
+ (projectile-completing-read
+ prompt
+ (delete (buffer-name (current-buffer))
+ (projectile-project-buffer-names))))
+
+;;;###autoload
+(defun projectile-switch-to-buffer ()
+ "Switch to a project buffer."
+ (interactive)
+ (switch-to-buffer
+ (projectile-read-buffer-to-switch "Switch to buffer: ")))
+
+;;;###autoload
+(defun projectile-switch-to-buffer-other-window ()
+ "Switch to a project buffer and show it in another window."
+ (interactive)
+ (switch-to-buffer-other-window
+ (projectile-read-buffer-to-switch "Switch to buffer: ")))
+
+;;;###autoload
+(defun projectile-switch-to-buffer-other-frame ()
+ "Switch to a project buffer and show it in another frame."
+ (interactive)
+ (switch-to-buffer-other-frame
+ (projectile-read-buffer-to-switch "Switch to buffer: ")))
+
+;;;###autoload
+(defun projectile-display-buffer ()
+ "Display a project buffer in another window without selecting it."
+ (interactive)
+ (display-buffer
+ (projectile-completing-read
+ "Display buffer: "
+ (projectile-project-buffer-names))))
+
+;;;###autoload
+(defun projectile-project-buffers-other-buffer ()
+ "Switch to the most recently selected buffer project buffer.
+Only buffers not visible in windows are returned."
+ (interactive)
+ (switch-to-buffer (car (projectile-project-buffers-non-visible))) nil t)
+
+(defun projectile-project-buffers-non-visible ()
+ "Get a list of non visible project buffers."
+ (cl-remove-if-not
+ (lambda (buffer)
+ (not (get-buffer-window buffer 'visible)))
+ (projectile-project-buffers)))
+
+;;;###autoload
+(defun projectile-multi-occur (&optional nlines)
+ "Do a `multi-occur' in the project's buffers.
+With a prefix argument, show NLINES of context."
+ (interactive "P")
+ (let ((project (projectile-acquire-root)))
+ (multi-occur (projectile-project-buffers project)
+ (car (occur-read-primary-args))
+ nlines)))
+
+(defun projectile-normalise-paths (patterns)
+ "Remove leading `/' from the elements of PATTERNS."
+ (delq nil (mapcar (lambda (pat) (and (string-prefix-p "/" pat)
+ ;; remove the leading /
+ (substring pat 1)))
+ patterns)))
+
+(defun projectile-expand-paths (paths)
+ "Expand the elements of PATHS.
+
+Elements containing wildcards are expanded and spliced into the
+resulting paths. The returned PATHS are absolute, based on the
+projectile project root."
+ (let ((default-directory (projectile-project-root)))
+ (projectile-flatten (mapcar
+ (lambda (pattern)
+ (or (file-expand-wildcards pattern t)
+ (projectile-expand-root pattern)))
+ paths))))
+
+(defun projectile-normalise-patterns (patterns)
+ "Remove paths from PATTERNS."
+ (cl-remove-if (lambda (pat) (string-prefix-p "/" pat)) patterns))
+
+(defun projectile-make-relative-to-root (files)
+ "Make FILES relative to the project root."
+ (let ((project-root (projectile-project-root)))
+ (mapcar (lambda (f) (file-relative-name f project-root)) files)))
+
+(defun projectile-ignored-directory-p
+ (directory &optional ignored-directories local-directory globally-ignored-directories)
+ "Check if DIRECTORY should be ignored.
+
+Regular expressions can be used. Pre-computed lists of
+IGNORED-DIRECTORIES and GLOBALLY-IGNORED-DIRECTORIES
+and the LOCAL-DIRECTORY name may optionally be provided."
+ (let ((ignored-directories (or ignored-directories (projectile-ignored-directories)))
+ (globally-ignored-directories (or globally-ignored-directories (projectile-globally-ignored-directory-names)))
+ (local-directory (or local-directory (file-name-nondirectory (directory-file-name directory)))))
+ (or (cl-some
+ (lambda (name)
+ (string-match-p name directory))
+ ignored-directories)
+ (cl-some
+ (lambda (name)
+ (string-match-p name local-directory))
+ globally-ignored-directories))))
+
+(defun projectile-ignored-file-p (file &optional ignored-files)
+ "Check if FILE should be ignored.
+
+Regular expressions can be used. A pre-computed list of
+IGNORED-FILES may optionally be provided."
+ (cl-some
+ (lambda (name)
+ (string-match-p name file))
+ (or ignored-files (projectile-ignored-files))))
+
+(defun projectile-check-pattern-p (file pattern)
+ "Check if FILE meets PATTERN."
+ (or (string-suffix-p (directory-file-name pattern)
+ (directory-file-name file))
+ (member file (file-expand-wildcards pattern t))))
+
+(defun projectile-ignored-rel-p (file directory patterns)
+ "Check if FILE should be ignored relative to DIRECTORY.
+PATTERNS should have the form: (ignored . unignored)"
+ (let ((default-directory directory))
+ (and (cl-some
+ (lambda (pat) (projectile-check-pattern-p file pat))
+ (car patterns))
+ (cl-notany
+ (lambda (pat) (projectile-check-pattern-p file pat))
+ (cdr patterns)))))
+
+(defun projectile-ignored-files ()
+ "Return list of ignored files."
+ (projectile-difference
+ (mapcar
+ #'projectile-expand-root
+ (append
+ projectile-globally-ignored-files
+ (projectile-project-ignored-files)))
+ (projectile-unignored-files)))
+
+(defun projectile-globally-ignored-directory-names ()
+ "Return list of ignored directory names."
+ (projectile-difference
+ projectile-globally-ignored-directories
+ projectile-globally-unignored-directories))
+
+(defun projectile-ignored-directories ()
+ "Return list of ignored directories."
+ (projectile-difference
+ (mapcar
+ #'file-name-as-directory
+ (mapcar
+ #'projectile-expand-root
+ (append
+ projectile-globally-ignored-directories
+ (projectile-project-ignored-directories))))
+ (projectile-unignored-directories)))
+
+(defun projectile-ignored-directories-rel ()
+ "Return list of ignored directories, relative to the root."
+ (projectile-make-relative-to-root (projectile-ignored-directories)))
+
+(defun projectile-ignored-files-rel ()
+ "Return list of ignored files, relative to the root."
+ (projectile-make-relative-to-root (projectile-ignored-files)))
+
+(defun projectile-project-ignored-files ()
+ "Return list of project ignored files.
+Unignored files are not included."
+ (cl-remove-if 'file-directory-p (projectile-project-ignored)))
+
+(defun projectile-project-ignored-directories ()
+ "Return list of project ignored directories.
+Unignored directories are not included."
+ (cl-remove-if-not 'file-directory-p (projectile-project-ignored)))
+
+(defun projectile-paths-to-ignore ()
+ "Return a list of ignored project paths."
+ (projectile-normalise-paths (nth 1 (projectile-parse-dirconfig-file))))
+
+(defun projectile-patterns-to-ignore ()
+ "Return a list of relative file patterns."
+ (projectile-normalise-patterns (nth 1 (projectile-parse-dirconfig-file))))
+
+(defun projectile-project-ignored ()
+ "Return list of project ignored files/directories.
+Unignored files/directories are not included."
+ (let ((paths (projectile-paths-to-ignore)))
+ (projectile-expand-paths paths)))
+
+(defun projectile-unignored-files ()
+ "Return list of unignored files."
+ (mapcar
+ #'projectile-expand-root
+ (append
+ projectile-globally-unignored-files
+ (projectile-project-unignored-files))))
+
+(defun projectile-unignored-directories ()
+ "Return list of unignored directories."
+ (mapcar
+ #'file-name-as-directory
+ (mapcar
+ #'projectile-expand-root
+ (append
+ projectile-globally-unignored-directories
+ (projectile-project-unignored-directories)))))
+
+(defun projectile-unignored-directories-rel ()
+ "Return list of unignored directories, relative to the root."
+ (projectile-make-relative-to-root (projectile-unignored-directories)))
+
+(defun projectile-unignored-files-rel ()
+ "Return list of unignored files, relative to the root."
+ (projectile-make-relative-to-root (projectile-unignored-files)))
+
+(defun projectile-project-unignored-files ()
+ "Return list of project unignored files."
+ (cl-remove-if 'file-directory-p (projectile-project-unignored)))
+
+(defun projectile-project-unignored-directories ()
+ "Return list of project unignored directories."
+ (cl-remove-if-not 'file-directory-p (projectile-project-unignored)))
+
+(defun projectile-paths-to-ensure ()
+ "Return a list of unignored project paths."
+ (projectile-normalise-paths (nth 2 (projectile-parse-dirconfig-file))))
+
+(defun projectile-files-to-ensure ()
+ (projectile-flatten (mapcar (lambda (pat) (file-expand-wildcards pat t))
+ (projectile-patterns-to-ensure))))
+
+(defun projectile-patterns-to-ensure ()
+ "Return a list of relative file patterns."
+ (projectile-normalise-patterns (nth 2 (projectile-parse-dirconfig-file))))
+
+(defun projectile-filtering-patterns ()
+ (cons (projectile-patterns-to-ignore)
+ (projectile-patterns-to-ensure)))
+
+(defun projectile-project-unignored ()
+ "Return list of project ignored files/directories."
+ (delete-dups (append (projectile-expand-paths (projectile-paths-to-ensure))
+ (projectile-expand-paths (projectile-files-to-ensure)))))
+
+
+(defun projectile-dirconfig-file ()
+ "Return the absolute path to the project's dirconfig file."
+ (expand-file-name ".projectile" (projectile-project-root)))
+
+(defun projectile-parse-dirconfig-file ()
+ "Parse project ignore file and return directories to ignore and keep.
+
+The return value will be a list of three elements, the car being
+the list of directories to keep, the cadr being the list of files
+or directories to ignore, and the caddr being the list of files
+or directories to ensure.
+
+Strings starting with + will be added to the list of directories
+to keep, and strings starting with - will be added to the list of
+directories to ignore. For backward compatibility, without a
+prefix the string will be assumed to be an ignore string."
+ (let (keep ignore ensure (dirconfig (projectile-dirconfig-file)))
+ (when (projectile-file-exists-p dirconfig)
+ (with-temp-buffer
+ (insert-file-contents dirconfig)
+ (while (not (eobp))
+ (pcase (char-after)
+ ;; ignore comment lines if prefix char has been set
+ ((pred (lambda (leading-char)
+ (and projectile-dirconfig-comment-prefix
+ (eql leading-char
+ projectile-dirconfig-comment-prefix))))
+ nil)
+ (?+ (push (buffer-substring (1+ (point)) (line-end-position)) keep))
+ (?- (push (buffer-substring (1+ (point)) (line-end-position)) ignore))
+ (?! (push (buffer-substring (1+ (point)) (line-end-position)) ensure))
+ (_ (push (buffer-substring (point) (line-end-position)) ignore)))
+ (forward-line)))
+ (list (mapcar (lambda (f) (file-name-as-directory (string-trim f)))
+ (delete "" (reverse keep)))
+ (mapcar #'string-trim
+ (delete "" (reverse ignore)))
+ (mapcar #'string-trim
+ (delete "" (reverse ensure)))))))
+
+(defun projectile-expand-root (name)
+ "Expand NAME to project root.
+
+Never use on many files since it's going to recalculate the
+project-root for every file."
+ (expand-file-name name (projectile-project-root)))
+
+(cl-defun projectile-completing-read (prompt choices &key initial-input action)
+ "Present a project tailored PROMPT with CHOICES."
+ (let ((prompt (projectile-prepend-project-name prompt))
+ res)
+ (setq res
+ (pcase (if (eq projectile-completion-system 'auto)
+ (cond
+ ((bound-and-true-p ido-mode) 'ido)
+ ((bound-and-true-p helm-mode) 'helm)
+ ((bound-and-true-p ivy-mode) 'ivy)
+ (t 'default))
+ projectile-completion-system)
+ ('default (completing-read prompt choices nil nil initial-input))
+ ('ido (ido-completing-read prompt choices nil nil initial-input))
+ ('helm
+ (if (and (fboundp 'helm)
+ (fboundp 'helm-make-source))
+ (helm :sources
+ (helm-make-source "Projectile" 'helm-source-sync
+ :candidates choices
+ :action (if action
+ (prog1 action
+ (setq action nil))
+ #'identity))
+ :prompt prompt
+ :input initial-input
+ :buffer "*helm-projectile*")
+ (user-error "Please install helm")))
+ ('ivy
+ (if (fboundp 'ivy-read)
+ (ivy-read prompt choices
+ :initial-input initial-input
+ :action (prog1 action
+ (setq action nil))
+ :caller 'projectile-completing-read)
+ (user-error "Please install ivy")))
+ (_ (funcall projectile-completion-system prompt choices))))
+ (if action
+ (funcall action res)
+ res)))
+
+(defun projectile-project-files (project-root)
+ "Return a list of files for the PROJECT-ROOT."
+ (let (files)
+ ;; If the cache is too stale, don't use it.
+ (when projectile-files-cache-expire
+ (let ((cache-time
+ (gethash project-root projectile-projects-cache-time)))
+ (when (or (null cache-time)
+ (< (+ cache-time projectile-files-cache-expire)
+ (projectile-time-seconds)))
+ (remhash project-root projectile-projects-cache)
+ (remhash project-root projectile-projects-cache-time))))
+
+ ;; Use the cache, if requested and available.
+ (when projectile-enable-caching
+ (setq files (gethash project-root projectile-projects-cache)))
+
+ ;; Calculate the list of files.
+ (when (null files)
+ (when projectile-enable-caching
+ (message "Projectile is initializing cache for %s ..." project-root))
+ (setq files
+ (if (eq projectile-indexing-method 'alien)
+ ;; In alien mode we can just skip reading
+ ;; .projectile and find all files in the root dir.
+ (projectile-dir-files-alien project-root)
+ ;; If a project is defined as a list of subfolders
+ ;; then we'll have the files returned for each subfolder,
+ ;; so they are relative to the project root.
+ ;;
+ ;; TODO: That's pretty slow and we need to improve it.
+ ;; One options would be to pass explicitly the subdirs
+ ;; to commands like `git ls-files` which would return
+ ;; files paths relative to the project root.
+ (cl-mapcan
+ (lambda (dir)
+ (mapcar (lambda (f)
+ (file-relative-name (concat dir f)
+ project-root))
+ (projectile-dir-files dir)))
+ (projectile-get-project-directories project-root))))
+
+ ;; Save the cached list.
+ (when projectile-enable-caching
+ (projectile-cache-project project-root files)))
+
+ ;;; Sorting
+ ;;
+ ;; Files can't be cached in sorted order as some sorting schemes
+ ;; require dynamic data. Sorting is ignored completely when in
+ ;; alien mode.
+ (if (eq projectile-indexing-method 'alien)
+ files
+ (projectile-sort-files files))))
+
+(defun projectile-current-project-files ()
+ "Return a list of the files in the current project."
+ (projectile-project-files (projectile-acquire-root)))
+
+(defun projectile-process-current-project-files (action)
+ "Process the current project's files using ACTION."
+ (let ((project-files (projectile-current-project-files))
+ (default-directory (projectile-project-root)))
+ (dolist (filename project-files)
+ (funcall action filename))))
+
+(defun projectile-project-dirs (project)
+ "Return a list of dirs for PROJECT."
+ (delete-dups
+ (delq nil
+ (mapcar #'file-name-directory
+ (projectile-project-files project)))))
+
+(defun projectile-current-project-dirs ()
+ "Return a list of dirs for the current project."
+ (projectile-project-dirs (projectile-acquire-root)))
+
+(defun projectile-get-other-files (file-name &optional flex-matching)
+ "Return a list of other files for FILE-NAME.
+The list depends on `:related-files-fn' project option and
+`projectile-other-file-alist'. For the latter, FLEX-MATCHING can be used
+to match any basename."
+ (if-let ((plist (projectile--related-files-plist-by-kind file-name :other)))
+ (projectile--related-files-from-plist plist)
+ (projectile--other-extension-files file-name
+ (projectile-current-project-files)
+ flex-matching)))
+
+(defun projectile--find-other-file (&optional flex-matching ff-variant)
+ "Switch between files with the same name but different extensions.
+With FLEX-MATCHING, match any file that contains the base name of current file.
+Other file extensions can be customized with the variable
+`projectile-other-file-alist'. With FF-VARIANT set to a defun, use that
+instead of `find-file'. A typical example of such a defun would be
+`find-file-other-window' or `find-file-other-frame'"
+ (let ((ff (or ff-variant #'find-file))
+ (other-files (projectile-get-other-files (buffer-file-name) flex-matching)))
+ (if other-files
+ (let ((file-name (projectile--choose-from-candidates other-files)))
+ (funcall ff (expand-file-name file-name
+ (projectile-project-root))))
+ (error "No other file found"))))
+
+
+;;; Interactive commands
+;;;###autoload
+(defun projectile-find-other-file (&optional flex-matching)
+ "Switch between files with the same name but different extensions.
+With FLEX-MATCHING, match any file that contains the base name of current file.
+Other file extensions can be customized with the variable
+`projectile-other-file-alist'."
+ (interactive "P")
+ (projectile--find-other-file flex-matching))
+
+;;;###autoload
+(defun projectile-find-other-file-other-window (&optional flex-matching)
+ "Switch between files with different extensions in other window.
+Switch between files with the same name but different extensions in other
+window. With FLEX-MATCHING, match any file that contains the base name of
+current file. Other file extensions can be customized with the variable
+`projectile-other-file-alist'."
+ (interactive "P")
+ (projectile--find-other-file flex-matching
+ #'find-file-other-window))
+
+;;;###autoload
+(defun projectile-find-other-file-other-frame (&optional flex-matching)
+ "Switch between files with different extensions in other frame.
+Switch between files with the same name but different extensions in other frame.
+With FLEX-MATCHING, match any file that contains the base name of current
+file. Other file extensions can be customized with the variable
+`projectile-other-file-alist'."
+ (interactive "P")
+ (projectile--find-other-file flex-matching
+ #'find-file-other-frame))
+
+(defun projectile--file-name-sans-extensions (file-name)
+ "Return FILE-NAME sans any extensions.
+The extensions, in a filename, are what follows the first '.', with the
+exception of a leading '.'"
+ (setq file-name (file-name-nondirectory file-name))
+ (substring file-name 0 (string-match "\\..*" file-name 1)))
+
+(defun projectile--file-name-extensions (file-name)
+ "Return FILE-NAME's extensions.
+The extensions, in a filename, are what follows the first '.', with the
+exception of a leading '.'"
+ ;;would it make sense to return nil instead of an empty string if no extensions are found?
+ (setq file-name (file-name-nondirectory file-name))
+ (let (extensions-start)
+ (substring file-name
+ (if (setq extensions-start (string-match "\\..*" file-name 1))
+ (1+ extensions-start)
+ (length file-name)))))
+
+(defun projectile-associated-file-name-extensions (file-name)
+ "Return projectile-other-file-extensions associated to FILE-NAME's extensions.
+If no associated other-file-extensions for the complete (nested) extension
+are found, remove subextensions from FILENAME's extensions until a match is
+found."
+ (let ((current-extensions (projectile--file-name-extensions (file-name-nondirectory file-name)))
+ associated-extensions)
+ (catch 'break
+ (while (not (string= "" current-extensions))
+ (if (setq associated-extensions (cdr (assoc current-extensions projectile-other-file-alist)))
+ (throw 'break associated-extensions))
+ (setq current-extensions (projectile--file-name-extensions current-extensions))))))
+
+(defun projectile--other-extension-files (current-file project-file-list &optional flex-matching)
+ "Narrow to files with the same names but different extensions.
+Returns a list of possible files for users to choose.
+
+With FLEX-MATCHING, match any file that contains the base name of current file"
+ (let* ((file-ext-list (projectile-associated-file-name-extensions current-file))
+ (fulldirname (if (file-name-directory current-file)
+ (file-name-directory current-file) "./"))
+ (dirname (file-name-nondirectory (directory-file-name fulldirname)))
+ (filename (regexp-quote (projectile--file-name-sans-extensions current-file)))
+ (file-list (mapcar (lambda (ext)
+ (if flex-matching
+ (concat ".*" filename ".*" "\." ext "\\'")
+ (concat "^" filename
+ (unless (equal ext "")
+ (concat "\." ext))
+ "\\'")))
+ file-ext-list))
+ (candidates (cl-remove-if-not
+ (lambda (project-file)
+ (string-match filename project-file))
+ project-file-list))
+ (candidates
+ (projectile-flatten (mapcar
+ (lambda (file)
+ (cl-remove-if-not
+ (lambda (project-file)
+ (string-match file
+ (concat (file-name-base project-file)
+ (unless (equal (file-name-extension project-file) nil)
+ (concat "\." (file-name-extension project-file))))))
+ candidates))
+ file-list)))
+ (candidates
+ (cl-remove-if-not (lambda (file) (not (backup-file-name-p file))) candidates))
+ (candidates
+ (cl-sort (copy-sequence candidates)
+ (lambda (file _)
+ (let ((candidate-dirname (file-name-nondirectory (directory-file-name (file-name-directory file)))))
+ (unless (equal fulldirname (file-name-directory file))
+ (equal dirname candidate-dirname)))))))
+ candidates))
+
+(defun projectile-select-files (project-files &optional invalidate-cache)
+ "Select a list of files based on filename at point.
+
+With a prefix arg INVALIDATE-CACHE invalidates the cache first."
+ (projectile-maybe-invalidate-cache invalidate-cache)
+ (let* ((file (if (region-active-p)
+ (buffer-substring (region-beginning) (region-end))
+ (or (thing-at-point 'filename) "")))
+ (file (if (string-match "\\.?\\./" file)
+ (file-relative-name (file-truename file) (projectile-project-root))
+ file))
+ (files (if file
+ (cl-remove-if-not
+ (lambda (project-file)
+ (string-match file project-file))
+ project-files)
+ nil)))
+ files))
+
+(defun projectile--find-file-dwim (invalidate-cache &optional ff-variant)
+ "Jump to a project's files using completion based on context.
+
+With a INVALIDATE-CACHE invalidates the cache first.
+
+With FF-VARIANT set to a defun, use that instead of `find-file'.
+A typical example of such a defun would be `find-file-other-window' or
+`find-file-other-frame'
+
+Subroutine for `projectile-find-file-dwim' and
+`projectile-find-file-dwim-other-window'"
+ (let* ((project-root (projectile-acquire-root))
+ (project-files (projectile-project-files project-root))
+ (files (projectile-select-files project-files invalidate-cache))
+ (file (cond ((= (length files) 1)
+ (car files))
+ ((> (length files) 1)
+ (projectile-completing-read "Switch to: " files))
+ (t
+ (projectile-completing-read "Switch to: " project-files))))
+ (ff (or ff-variant #'find-file)))
+ (funcall ff (expand-file-name file project-root))
+ (run-hooks 'projectile-find-file-hook)))
+
+;;;###autoload
+(defun projectile-find-file-dwim (&optional invalidate-cache)
+ "Jump to a project's files using completion based on context.
+
+With a prefix arg INVALIDATE-CACHE invalidates the cache first.
+
+If point is on a filename, Projectile first tries to search for that
+file in project:
+
+- If it finds just a file, it switches to that file instantly. This works
+even if the filename is incomplete, but there's only a single file in the
+current project that matches the filename at point. For example, if
+there's only a single file named \"projectile/projectile.el\" but the
+current filename is \"projectile/proj\" (incomplete),
+`projectile-find-file-dwim' still switches to \"projectile/projectile.el\"
+immediately because this is the only filename that matches.
+
+- If it finds a list of files, the list is displayed for selecting. A list
+of files is displayed when a filename appears more than one in the project
+or the filename at point is a prefix of more than two files in a project.
+For example, if `projectile-find-file-dwim' is executed on a filepath like
+\"projectile/\", it lists the content of that directory. If it is executed
+on a partial filename like \"projectile/a\", a list of files with character
+'a' in that directory is presented.
+
+- If it finds nothing, display a list of all files in project for selecting."
+ (interactive "P")
+ (projectile--find-file-dwim invalidate-cache))
+
+;;;###autoload
+(defun projectile-find-file-dwim-other-window (&optional invalidate-cache)
+ "Jump to a project's files using completion based on context in other window.
+
+With a prefix arg INVALIDATE-CACHE invalidates the cache first.
+
+If point is on a filename, Projectile first tries to search for that
+file in project:
+
+- If it finds just a file, it switches to that file instantly. This works
+even if the filename is incomplete, but there's only a single file in the
+current project that matches the filename at point. For example, if
+there's only a single file named \"projectile/projectile.el\" but the
+current filename is \"projectile/proj\" (incomplete),
+`projectile-find-file-dwim-other-window' still switches to
+\"projectile/projectile.el\" immediately because this is the only filename
+that matches.
+
+- If it finds a list of files, the list is displayed for selecting. A list
+of files is displayed when a filename appears more than one in the project
+or the filename at point is a prefix of more than two files in a project.
+For example, if `projectile-find-file-dwim-other-window' is executed on a
+filepath like \"projectile/\", it lists the content of that directory. If
+it is executed on a partial filename like \"projectile/a\", a list of files
+with character 'a' in that directory is presented.
+
+- If it finds nothing, display a list of all files in project for selecting."
+ (interactive "P")
+ (projectile--find-file-dwim invalidate-cache #'find-file-other-window))
+
+;;;###autoload
+(defun projectile-find-file-dwim-other-frame (&optional invalidate-cache)
+ "Jump to a project's files using completion based on context in other frame.
+
+With a prefix arg INVALIDATE-CACHE invalidates the cache first.
+
+If point is on a filename, Projectile first tries to search for that
+file in project:
+
+- If it finds just a file, it switches to that file instantly. This works
+even if the filename is incomplete, but there's only a single file in the
+current project that matches the filename at point. For example, if
+there's only a single file named \"projectile/projectile.el\" but the
+current filename is \"projectile/proj\" (incomplete),
+`projectile-find-file-dwim-other-frame' still switches to
+\"projectile/projectile.el\" immediately because this is the only filename
+that matches.
+
+- If it finds a list of files, the list is displayed for selecting. A list
+of files is displayed when a filename appears more than one in the project
+or the filename at point is a prefix of more than two files in a project.
+For example, if `projectile-find-file-dwim-other-frame' is executed on a
+filepath like \"projectile/\", it lists the content of that directory. If
+it is executed on a partial filename like \"projectile/a\", a list of files
+with character 'a' in that directory is presented.
+
+- If it finds nothing, display a list of all files in project for selecting."
+ (interactive "P")
+ (projectile--find-file-dwim invalidate-cache #'find-file-other-frame))
+
+(defun projectile--find-file (invalidate-cache &optional ff-variant)
+ "Jump to a project's file using completion.
+With INVALIDATE-CACHE invalidates the cache first. With FF-VARIANT set to a
+defun, use that instead of `find-file'. A typical example of such a defun
+would be `find-file-other-window' or `find-file-other-frame'"
+ (interactive "P")
+ (projectile-maybe-invalidate-cache invalidate-cache)
+ (let* ((project-root (projectile-acquire-root))
+ (file (projectile-completing-read "Find file: "
+ (projectile-project-files project-root)))
+ (ff (or ff-variant #'find-file)))
+ (when file
+ (funcall ff (expand-file-name file project-root))
+ (run-hooks 'projectile-find-file-hook))))
+
+;;;###autoload
+(defun projectile-find-file (&optional invalidate-cache)
+ "Jump to a project's file using completion.
+With a prefix arg INVALIDATE-CACHE invalidates the cache first."
+ (interactive "P")
+ (projectile--find-file invalidate-cache))
+
+;;;###autoload
+(defun projectile-find-file-other-window (&optional invalidate-cache)
+ "Jump to a project's file using completion and show it in another window.
+
+With a prefix arg INVALIDATE-CACHE invalidates the cache first."
+ (interactive "P")
+ (projectile--find-file invalidate-cache #'find-file-other-window))
+
+;;;###autoload
+(defun projectile-find-file-other-frame (&optional invalidate-cache)
+ "Jump to a project's file using completion and show it in another frame.
+
+With a prefix arg INVALIDATE-CACHE invalidates the cache first."
+ (interactive "P")
+ (projectile--find-file invalidate-cache #'find-file-other-frame))
+
+;;;###autoload
+(defun projectile-toggle-project-read-only ()
+ "Toggle project read only."
+ (interactive)
+ (let ((inhibit-read-only t)
+ (val (not buffer-read-only))
+ (default-directory (projectile-acquire-root)))
+ (add-dir-local-variable nil 'buffer-read-only val)
+ (save-buffer)
+ (kill-buffer)
+ (when buffer-file-name
+ (read-only-mode (if val +1 -1))
+ (message "[%s] read-only-mode is %s" (projectile-project-name) (if val "on" "off")))))
+
+
+;;;; Sorting project files
+(defun projectile-sort-files (files)
+ "Sort FILES according to `projectile-sort-order'."
+ (cl-case projectile-sort-order
+ (default files)
+ (recentf (projectile-sort-by-recentf-first files))
+ (recently-active (projectile-sort-by-recently-active-first files))
+ (modification-time (projectile-sort-by-modification-time files))
+ (access-time (projectile-sort-by-access-time files))))
+
+(defun projectile-sort-by-recentf-first (files)
+ "Sort FILES by a recent first scheme."
+ (let ((project-recentf-files (projectile-recentf-files)))
+ (append project-recentf-files
+ (projectile-difference files project-recentf-files))))
+
+(defun projectile-sort-by-recently-active-first (files)
+ "Sort FILES by most recently active buffers or opened files."
+ (let ((project-recently-active-files (projectile-recently-active-files)))
+ (append project-recently-active-files
+ (projectile-difference files project-recently-active-files))))
+
+(defun projectile-sort-by-modification-time (files)
+ "Sort FILES by modification time."
+ (let ((default-directory (projectile-project-root)))
+ (cl-sort
+ (copy-sequence files)
+ (lambda (file1 file2)
+ (let ((file1-mtime (nth 5 (file-attributes file1)))
+ (file2-mtime (nth 5 (file-attributes file2))))
+ (not (time-less-p file1-mtime file2-mtime)))))))
+
+(defun projectile-sort-by-access-time (files)
+ "Sort FILES by access time."
+ (let ((default-directory (projectile-project-root)))
+ (cl-sort
+ (copy-sequence files)
+ (lambda (file1 file2)
+ (let ((file1-atime (nth 4 (file-attributes file1)))
+ (file2-atime (nth 4 (file-attributes file2))))
+ (not (time-less-p file1-atime file2-atime)))))))
+
+
+;;;; Find directory in project functionality
+(defun projectile--find-dir (invalidate-cache &optional dired-variant)
+ "Jump to a project's directory using completion.
+
+With INVALIDATE-CACHE invalidates the cache first. With DIRED-VARIANT set to a
+defun, use that instead of `dired'. A typical example of such a defun would be
+`dired-other-window' or `dired-other-frame'"
+ (projectile-maybe-invalidate-cache invalidate-cache)
+ (let* ((project (projectile-acquire-root))
+ (dir (projectile-complete-dir project))
+ (dired-v (or dired-variant #'dired)))
+ (funcall dired-v (expand-file-name dir project))
+ (run-hooks 'projectile-find-dir-hook)))
+
+;;;###autoload
+(defun projectile-find-dir (&optional invalidate-cache)
+ "Jump to a project's directory using completion.
+
+With a prefix arg INVALIDATE-CACHE invalidates the cache first."
+ (interactive "P")
+ (projectile--find-dir invalidate-cache))
+
+;;;###autoload
+(defun projectile-find-dir-other-window (&optional invalidate-cache)
+ "Jump to a project's directory in other window using completion.
+
+With a prefix arg INVALIDATE-CACHE invalidates the cache first."
+ (interactive "P")
+ (projectile--find-dir invalidate-cache #'dired-other-window))
+
+;;;###autoload
+(defun projectile-find-dir-other-frame (&optional invalidate-cache)
+ "Jump to a project's directory in other frame using completion.
+
+With a prefix arg INVALIDATE-CACHE invalidates the cache first."
+ (interactive "P")
+ (projectile--find-dir invalidate-cache #'dired-other-frame))
+
+(defun projectile-complete-dir (project)
+ (let ((project-dirs (projectile-project-dirs project)))
+ (projectile-completing-read
+ "Find dir: "
+ (if projectile-find-dir-includes-top-level
+ (append '("./") project-dirs)
+ project-dirs))))
+
+;;;###autoload
+(defun projectile-find-test-file (&optional invalidate-cache)
+ "Jump to a project's test file using completion.
+
+With a prefix arg INVALIDATE-CACHE invalidates the cache first."
+ (interactive "P")
+ (projectile-maybe-invalidate-cache invalidate-cache)
+ (let ((file (projectile-completing-read "Find test file: "
+ (projectile-current-project-test-files))))
+ (find-file (expand-file-name file (projectile-project-root)))))
+
+(defun projectile-test-files (files)
+ "Return only the test FILES."
+ (cl-remove-if-not 'projectile-test-file-p files))
+
+(defun projectile--merge-related-files-fns (related-files-fns)
+ "Merge multiple RELATED-FILES-FNS into one function."
+ (lambda (path)
+ (let (merged-plist)
+ (dolist (fn related-files-fns merged-plist)
+ (let ((plist (funcall fn path)))
+ (cl-loop for (key value) on plist by #'cddr
+ do (let ((values (if (consp value) value (list value))))
+ (if (plist-member merged-plist key)
+ (nconc (plist-get merged-plist key) values)
+ (setq merged-plist (plist-put merged-plist key values))))))))))
+
+(defun projectile--related-files-plist (project-root file)
+ "Return a plist containing all related files information for FILE.
+PROJECT-ROOT is the project root."
+ (if-let ((rel-path (if (file-name-absolute-p file)
+ (file-relative-name file project-root)
+ file))
+ (custom-function (funcall projectile-related-files-fn-function (projectile-project-type))))
+ (funcall (cond ((functionp custom-function)
+ custom-function)
+ ((consp custom-function)
+ (projectile--merge-related-files-fns custom-function))
+ (t
+ (error "Unsupported value type of :related-files-fn")))
+ rel-path)))
+
+(defun projectile--related-files-plist-by-kind (file kind)
+ "Return a plist containing :paths and/or :predicate of KIND for FILE."
+ (if-let ((project-root (projectile-project-root))
+ (plist (projectile--related-files-plist project-root file))
+ (has-kind? (plist-member plist kind)))
+ (let* ((kind-value (plist-get plist kind))
+ (values (if (cl-typep kind-value '(or string function))
+ (list kind-value)
+ kind-value))
+ (paths (delete-dups (cl-remove-if-not 'stringp values)))
+ (predicates (delete-dups (cl-remove-if-not 'functionp values))))
+ (append
+ ;; Make sure that :paths exists even with nil if there is no predicates
+ (when (or paths (null predicates))
+ (list :paths (cl-remove-if-not
+ (lambda (f)
+ (projectile-file-exists-p (expand-file-name f project-root)))
+ paths)))
+ (when predicates
+ (list :predicate (if (= 1 (length predicates))
+ (car predicates)
+ (lambda (other-file)
+ (cl-some (lambda (predicate)
+ (funcall predicate other-file))
+ predicates)))))))))
+
+(defun projectile--related-files-from-plist (plist)
+ "Return a list of files matching to PLIST from current project files."
+ (let* ((predicate (plist-get plist :predicate))
+ (paths (plist-get plist :paths)))
+ (delete-dups (append
+ paths
+ (when predicate
+ (cl-remove-if-not predicate (projectile-current-project-files)))))))
+
+(defun projectile--related-files-kinds(file)
+ "Return a list o keywords meaning available related kinds for FILE."
+ (if-let ((project-root (projectile-project-root))
+ (plist (projectile--related-files-plist project-root file)))
+ (cl-loop for key in plist by #'cddr
+ collect key)))
+
+(defun projectile--related-files (file kind)
+ "Return a list of related files of KIND for FILE."
+ (projectile--related-files-from-plist (projectile--related-files-plist-by-kind file kind)))
+
+(defun projectile--find-related-file (file &optional kind)
+ "Choose a file from files related to FILE as KIND.
+If KIND is not provided, a list of possible kinds can be chosen."
+ (unless kind
+ (if-let ((available-kinds (projectile--related-files-kinds file)))
+ (setq kind (if (= (length available-kinds) 1)
+ (car available-kinds)
+ (intern (projectile-completing-read "Kind :" available-kinds))))
+ (error "No related files found")))
+
+ (if-let ((candidates (projectile--related-files file kind)))
+ (projectile-expand-root (projectile--choose-from-candidates candidates))
+ (error
+ "No matching related file as `%s' found for project type `%s'"
+ kind (projectile-project-type))))
+
+;;;###autoload
+(defun projectile-find-related-file-other-window ()
+ "Open related file in other window."
+ (interactive)
+ (find-file-other-window
+ (projectile--find-related-file (buffer-file-name))))
+
+;;;###autoload
+(defun projectile-find-related-file-other-frame ()
+ "Open related file in other frame."
+ (interactive)
+ (find-file-other-frame
+ (projectile--find-related-file (buffer-file-name))))
+
+;;;###autoload
+(defun projectile-find-related-file()
+ "Open related file."
+ (interactive)
+ (find-file
+ (projectile--find-related-file (buffer-file-name))))
+
+;;;###autoload
+(defun projectile-related-files-fn-groups(kind groups)
+ "Generate a related-files-fn which relates as KIND for files in each of GROUPS."
+ (lambda (path)
+ (if-let ((group-found (cl-find-if (lambda (group)
+ (member path group))
+ groups)))
+ (list kind (cl-remove path group-found :test 'equal)))))
+
+;;;###autoload
+(defun projectile-related-files-fn-extensions(kind extensions)
+ "Generate a related-files-fn which relates as KIND for files having EXTENSIONS."
+ (lambda (path)
+ (let* ((ext (file-name-extension path))
+ (basename (file-name-base path))
+ (basename-regexp (regexp-quote basename)))
+ (when (member ext extensions)
+ (list kind (lambda (other-path)
+ (and (string-match-p basename-regexp other-path)
+ (equal basename (file-name-base other-path))
+ (let ((other-ext (file-name-extension other-path)))
+ (and (member other-ext extensions)
+ (not (equal other-ext ext)))))))))))
+
+;;;###autoload
+(defun projectile-related-files-fn-test-with-prefix(extension test-prefix)
+ "Generate a related-files-fn which relates tests and impl.
+Use files with EXTENSION based on TEST-PREFIX."
+ (lambda (path)
+ (when (equal (file-name-extension path) extension)
+ (let* ((file-name (file-name-nondirectory path))
+ (find-impl? (string-prefix-p test-prefix file-name))
+ (file-name-to-find (if find-impl?
+ (substring file-name (length test-prefix))
+ (concat test-prefix file-name))))
+ (list (if find-impl? :impl :test)
+ (lambda (other-path)
+ (and (string-suffix-p file-name-to-find other-path)
+ (equal (file-name-nondirectory other-path) file-name-to-find))))))))
+
+;;;###autoload
+(defun projectile-related-files-fn-test-with-suffix(extension test-suffix)
+ "Generate a related-files-fn which relates tests and impl.
+Use files with EXTENSION based on TEST-SUFFIX."
+ (lambda (path)
+ (when (equal (file-name-extension path) extension)
+ (let* ((file-name (file-name-nondirectory path))
+ (dot-ext (concat "." extension))
+ (suffix-ext (concat test-suffix dot-ext))
+ (find-impl? (string-suffix-p suffix-ext file-name))
+ (file-name-to-find (if find-impl?
+ (concat (substring file-name 0 (- (length suffix-ext)))
+ dot-ext)
+ (concat (substring file-name 0 (- (length dot-ext)))
+ suffix-ext))))
+ (list (if find-impl? :impl :test)
+ (lambda (other-path)
+ (and (string-suffix-p file-name-to-find other-path)
+ (equal (file-name-nondirectory other-path) file-name-to-find))))))))
+
+(defun projectile-test-file-p (file)
+ "Check if FILE is a test file."
+ (let ((kinds (projectile--related-files-kinds file)))
+ (cond ((member :impl kinds) t)
+ ((member :test kinds) nil)
+ (t (or (cl-some (lambda (pat) (string-prefix-p pat (file-name-nondirectory file)))
+ (delq nil (list (funcall projectile-test-prefix-function (projectile-project-type)))))
+ (cl-some (lambda (pat) (string-suffix-p pat (file-name-sans-extension (file-name-nondirectory file))))
+ (delq nil (list (funcall projectile-test-suffix-function (projectile-project-type))))))))))
+
+(defun projectile-current-project-test-files ()
+ "Return a list of test files for the current project."
+ (projectile-test-files (projectile-current-project-files)))
+
+(defvar projectile-project-types nil
+ "An alist holding all project types that are known to Projectile.
+The project types are symbols and they are linked to plists holding
+the properties of the various project types.")
+
+(defun projectile--combine-plists (&rest plists)
+ "Create a single property list from all plists in PLISTS.
+The process starts by copying the first list, and then setting properties
+from the other lists. Settings in the last list are the most significant
+ones and overrule settings in the other lists."
+ (let ((rtn (copy-sequence (pop plists)))
+ p v ls)
+ (while plists
+ (setq ls (pop plists))
+ (while ls
+ (setq p (pop ls) v (pop ls))
+ (setq rtn (plist-put rtn p v))))
+ rtn))
+
+(cl-defun projectile--build-project-plist
+ (marker-files &key project-file compilation-dir configure compile install package test run test-suffix test-prefix src-dir test-dir related-files-fn)
+ "Return a project type plist with the provided arguments.
+
+A project type is defined by PROJECT-TYPE, a set of MARKER-FILES,
+and optional keyword arguments:
+PROJECT-FILE the main project file in the root project directory.
+COMPILATION-DIR the directory to run the tests- and compilations in,
+CONFIGURE which specifies a command that configures the project
+ `%s' in the command will be substituted with (projectile-project-root)
+ before the command is run,
+COMPILE which specifies a command that builds the project,
+INSTALL which specifies a command to install the project.
+PACKAGE which specifies a command to package the project.
+TEST which specified a command that tests the project,
+RUN which specifies a command that runs the project,
+TEST-SUFFIX which specifies test file suffix, and
+TEST-PREFIX which specifies test file prefix.
+SRC-DIR which specifies the path to the source relative to the project root.
+TEST-DIR which specifies the path to the tests relative to the project root.
+RELATED-FILES-FN which specifies a custom function to find the related
+files such as test/impl/other files as below:
+ CUSTOM-FUNCTION accepts FILE as relative path from the project root and
+ returns a plist containing :test, :impl or :other as key and the
+ relative path/paths or predicate as value. PREDICATE accepts a
+ relative path as the input."
+ (let ((project-plist (list 'marker-files marker-files
+ 'project-file project-file
+ 'compilation-dir compilation-dir
+ 'configure-command configure
+ 'compile-command compile
+ 'test-command test
+ 'install-command install
+ 'package-command package
+ 'run-command run)))
+ (when (and project-file (not (member project-file projectile-project-root-files)))
+ (add-to-list 'projectile-project-root-files project-file))
+ (when test-suffix
+ (plist-put project-plist 'test-suffix test-suffix))
+ (when test-prefix
+ (plist-put project-plist 'test-prefix test-prefix))
+ (when src-dir
+ (plist-put project-plist 'src-dir src-dir))
+ (when test-dir
+ (plist-put project-plist 'test-dir test-dir))
+ (when related-files-fn
+ (plist-put project-plist 'related-files-fn related-files-fn))
+ project-plist))
+
+(cl-defun projectile-register-project-type
+ (project-type marker-files &key project-file compilation-dir configure compile install package test run test-suffix test-prefix src-dir test-dir related-files-fn)
+ "Register a project type with projectile.
+
+A project type is defined by PROJECT-TYPE, a set of MARKER-FILES,
+and optional keyword arguments:
+PROJECT-FILE the main project file in the root project directory.
+COMPILATION-DIR the directory to run the tests- and compilations in,
+CONFIGURE which specifies a command that configures the project
+ `%s' in the command will be substituted with (projectile-project-root)
+ before the command is run,
+COMPILE which specifies a command that builds the project,
+INSTALL which specifies a command to install the project.
+PACKAGE which specifies a command to package the project.
+TEST which specified a command that tests the project,
+RUN which specifies a command that runs the project,
+TEST-SUFFIX which specifies test file suffix, and
+TEST-PREFIX which specifies test file prefix.
+SRC-DIR which specifies the path to the source relative to the project root.
+TEST-DIR which specifies the path to the tests relative to the project root.
+RELATED-FILES-FN which specifies a custom function to find the related
+files such as test/impl/other files as below:
+ CUSTOM-FUNCTION accepts FILE as relative path from the project root and
+ returns a plist containing :test, :impl or :other as key and the
+ relative path/paths or predicate as value. PREDICATE accepts a
+ relative path as the input."
+ (setq projectile-project-types
+ (cons `(,project-type .
+ ,(projectile--build-project-plist
+ marker-files
+ :project-file project-file
+ :compilation-dir compilation-dir
+ :configure configure
+ :compile compile
+ :install install
+ :package package
+ :test test
+ :run run
+ :test-suffix test-suffix
+ :test-prefix test-prefix
+ :src-dir src-dir
+ :test-dir test-dir
+ :related-files-fn related-files-fn))
+ projectile-project-types)))
+
+(cl-defun projectile-update-project-type
+ (project-type
+ &key precedence
+ (marker-files nil marker-files-specified)
+ (project-file nil project-file-specified)
+ (compilation-dir nil compilation-dir-specified)
+ (configure nil configure-specified)
+ (compile nil compile-specified)
+ (install nil install-specified)
+ (package nil package-specified)
+ (test nil test-specified)
+ (run nil run-specified)
+ (test-suffix nil test-suffix-specified)
+ (test-prefix nil test-prefix-specified)
+ (src-dir nil src-dir-specified)
+ (test-dir nil test-dir-specified)
+ (related-files-fn nil related-files-fn-specified))
+ "Update an existing projectile project type.
+
+Passed items will override existing values for the project type given
+by PROJECT-TYPE. nil can be used to remove a project type attribute. Raise
+an error if PROJECT-TYPE is not already registered with projectile. This
+function may also take the keyword argument PRECEDENCE which when set to ‘high’
+will make projectile prioritise this project type over other clashing project
+types, and a value of ‘low’ will make projectile prefer (all) other project
+types by default. Otherwise, the arguments to this function are as for
+`projectile-register-project-type':
+
+A project type is defined by PROJECT-TYPE, a set of MARKER-FILES,
+and optional keyword arguments:
+MARKER-FILES a set of indicator files for PROJECT-TYPE.
+PROJECT-FILE the main project file in the root project directory.
+COMPILATION-DIR the directory to run the tests- and compilations in,
+CONFIGURE which specifies a command that configures the project
+ `%s' in the command will be substituted with (projectile-project-root)
+ before the command is run,
+COMPILE which specifies a command that builds the project,
+INSTALL which specifies a command to install the project.
+PACKAGE which specifies a command to package the project.
+TEST which specified a command that tests the project,
+RUN which specifies a command that runs the project,
+TEST-SUFFIX which specifies test file suffix, and
+TEST-PREFIX which specifies test file prefix.
+SRC-DIR which specifies the path to the source relative to the project root.
+TEST-DIR which specifies the path to the tests relative to the project root.
+RELATED-FILES-FN which specifies a custom function to find the related
+files such as test/impl/other files as below:
+ CUSTOM-FUNCTION accepts FILE as relative path from the project root and
+ returns a plist containing :test, :impl or :other as key and the
+ relative path/paths or predicate as value. PREDICATE accepts a
+ relative path as the input."
+ (let* ((existing-project-plist
+ (or (cl-find-if
+ (lambda (p) (eq project-type (car p))) projectile-project-types)
+ (error "No existing project found for: %s" project-type)))
+ (new-plist
+ (append
+ (when marker-files-specified `(marker-files ,marker-files))
+ (when project-file-specified `(project-file ,project-file))
+ (when compilation-dir-specified `(compilation-dir ,compilation-dir))
+ (when configure-specified `(configure-command ,configure))
+ (when compile-specified `(compile-command ,compile))
+ (when test-specified `(test-command ,test))
+ (when install-specified `(install-command ,install))
+ (when package-specified `(package-command ,package))
+ (when run-specified `(run-command ,run))
+ (when test-suffix-specified `(test-suffix ,test-suffix))
+ (when test-prefix-specified `(test-prefix ,test-prefix))
+ (when src-dir-specified `(src-dir ,src-dir))
+ (when test-dir-specified `(test-dir ,test-dir))
+ (when related-files-fn-specified
+ `(related-files-fn ,related-files-fn))))
+ (merged-plist
+ (projectile--combine-plists
+ (cdr existing-project-plist) new-plist))
+ (project-type-elt (cons project-type merged-plist)))
+ (cl-flet* ((project-filter (p) (eq project-type (car p)))
+ (project-map (p) (if (project-filter p) project-type-elt p)))
+ (setq projectile-project-types
+ (if precedence
+ (let ((filtered-types
+ (cl-remove-if #'project-filter projectile-project-types)))
+ (setq projectile-project-type-cache (make-hash-table))
+ (cond ((eq precedence 'high)
+ (cons project-type-elt filtered-types))
+ ((eq precedence 'low)
+ (append filtered-types (list project-type-elt)))
+ (t (error "Precendence must be one of '(high low)"))))
+ (mapcar #'project-map projectile-project-types))))))
+
+(defun projectile-cabal-project-p ()
+ "Check if a project contains *.cabal files but no stack.yaml file."
+ (and (projectile-verify-file-wildcard "?*.cabal")
+ (not (projectile-verify-file "stack.yaml"))))
+
+(defun projectile-dotnet-project-p ()
+ "Check if a project contains a .NET project marker."
+ (or (projectile-verify-file-wildcard "?*.csproj")
+ (projectile-verify-file-wildcard "?*.fsproj")))
+
+(defun projectile-go-project-p ()
+ "Check if a project contains Go source files."
+ (or (projectile-verify-file "go.mod")
+ (projectile-verify-file-wildcard "*.go")))
+
+(defcustom projectile-go-project-test-function #'projectile-go-project-p
+ "Function to determine if project's type is go."
+ :group 'projectile
+ :type 'function
+ :package-version '(projectile . "1.0.0"))
+
+;;;; Constant signifying opting out of CMake preset commands.
+(defconst projectile--cmake-no-preset "*no preset*")
+
+(defun projectile--cmake-version ()
+ "Compute CMake version."
+ (let* ((string (shell-command-to-string "cmake --version"))
+ (match (string-match "^cmake version \\(.*\\)$" string)))
+ (when match
+ (version-to-list (match-string 1 string)))))
+
+(defun projectile--cmake-check-version (version)
+ "Check if CMake version is at least VERSION."
+ (and
+ (version-list-<= version (projectile--cmake-version))))
+
+(defconst projectile--cmake-command-presets-minimum-version-alist
+ '((:configure-command . (3 19))
+ (:compile-command . (3 20))
+ (:test-command . (3 20))
+ (:install-command . (3 20))))
+
+(defun projectile--cmake-command-presets-supported (command-type)
+ "Check if CMake supports presets for COMMAND-TYPE."
+ (let ((minimum-version
+ (cdr (assoc command-type projectile--cmake-command-presets-minimum-version-alist))))
+ (projectile--cmake-check-version minimum-version)))
+
+(defun projectile--cmake-read-preset (filename)
+ "Read CMake preset from FILENAME."
+ (when (file-exists-p filename)
+ (with-temp-buffer
+ (insert-file-contents filename)
+ (when (functionp 'json-parse-buffer)
+ (json-parse-buffer :array-type 'list)))))
+
+(defconst projectile--cmake-command-preset-array-id-alist
+ '((:configure-command . "configurePresets")
+ (:compile-command . "buildPresets")
+ (:test-command . "testPresets")
+ (:install-command . "buildPresets")))
+
+(defun projectile--cmake-command-preset-array-id (command-type)
+ "Map from COMMAND-TYPE to id of command preset array in CMake preset."
+ (cdr (assoc command-type projectile--cmake-command-preset-array-id-alist)))
+
+(defun projectile--cmake-command-presets (filename command-type)
+ "Get CMake COMMAND-TYPE presets from FILENAME."
+ (when-let ((preset (projectile--cmake-read-preset (projectile-expand-root filename))))
+ (cl-remove-if
+ (lambda (preset) (equal (gethash "hidden" preset) t))
+ (gethash (projectile--cmake-command-preset-array-id command-type) preset))))
+
+(defun projectile--cmake-all-command-presets (command-type)
+ "Get CMake user and system COMMAND-TYPE presets."
+ (projectile-flatten
+ (mapcar (lambda (filename) (projectile--cmake-command-presets filename command-type))
+ '("CMakeUserPresets.json" "CMakePresets.json"))))
+
+(defun projectile--cmake-command-preset-names (command-type)
+ "Get names of CMake user and system COMMAND-TYPE presets."
+ (mapcar (lambda (preset)
+ (gethash "name" preset))
+ (projectile--cmake-all-command-presets command-type)))
+
+(defcustom projectile-enable-cmake-presets nil
+ "Enables configuration with CMake presets.
+
+When `projectile-enable-cmake-presets' is non-nil, CMake projects can
+be configured, built and tested using presets."
+ :group 'projectile
+ :type 'boolean
+ :package-version '(projectile . "2.4.0"))
+
+(defun projectile--cmake-use-command-presets (command-type)
+ "Test whether or not to use command presets for COMMAND-TYPE.
+
+Presets are used if `projectile-enable-cmake-presets' is non-nil, and CMake
+supports presets for COMMAND-TYPE, and `json-parse-buffer' is available."
+ (and projectile-enable-cmake-presets
+ (projectile--cmake-command-presets-supported command-type)
+ (functionp 'json-parse-buffer)))
+
+(defun projectile--cmake-select-command (command-type)
+ "Select a CMake command preset or a manual CMake command.
+
+The selection is done like this:
+
+- If `projectile--cmake-use-commands-presets' for COMMAND-TYPE returns true, and
+there is at least one preset available for COMMAND-TYPE, the user is prompted to
+select a name of a command preset, or opt a manual command by selecting
+`projectile--cmake-no-preset'.
+
+- Else `projectile--cmake-no-preset' is used."
+ (if-let ((use-presets (projectile--cmake-use-command-presets command-type))
+ (preset-names (projectile--cmake-command-preset-names command-type)))
+ (projectile-completing-read
+ "Use preset: "
+ (append preset-names `(,projectile--cmake-no-preset)))
+ projectile--cmake-no-preset))
+
+(defconst projectile--cmake-manual-command-alist
+ '((:configure-command . "cmake -S . -B build")
+ (:compile-command . "cmake --build build")
+ (:test-command . "cmake --build build --target test")
+ (:install-command . "cmake --build build --target install")))
+
+(defun projectile--cmake-manual-command (command-type)
+ "Create maunual CMake COMMAND-TYPE command."
+ (cdr (assoc command-type projectile--cmake-manual-command-alist)))
+
+(defconst projectile--cmake-preset-command-alist
+ '((:configure-command . "cmake . --preset %s")
+ (:compile-command . "cmake --build --preset %s")
+ (:test-command . "ctest --preset %s")
+ (:install-command . "cmake --build --preset %s --target install")))
+
+(defun projectile--cmake-preset-command (command-type preset)
+ "Create CMake COMMAND-TYPE command using PRESET."
+ (format (cdr (assoc command-type projectile--cmake-preset-command-alist)) preset))
+
+(defun projectile--cmake-command (command-type)
+ "Create a CMake COMMAND-TYPE command.
+
+The command is created like this:
+
+- If `projectile--cmake-select-command' returns `projectile--cmake-no-preset'
+a manual COMMAND-TYPE command is created with
+`projectile--cmake-manual-command'.
+
+- Else a preset COMMAND-TYPE command using the selected preset is created with
+`projectile--cmake-preset-command'."
+ (let ((maybe-preset (projectile--cmake-select-command command-type)))
+ (if (equal maybe-preset projectile--cmake-no-preset)
+ (projectile--cmake-manual-command command-type)
+ (projectile--cmake-preset-command command-type maybe-preset))))
+
+(defun projectile--cmake-configure-command ()
+ "CMake configure command."
+ (projectile--cmake-command :configure-command))
+
+(defun projectile--cmake-compile-command ()
+ "CMake compile command."
+ (projectile--cmake-command :compile-command))
+
+(defun projectile--cmake-test-command ()
+ "CMake test command."
+ (projectile--cmake-command :test-command))
+
+(defun projectile--cmake-install-command ()
+ "CMake install command."
+ (projectile--cmake-command :install-command))
+
+;;; Project type registration
+;;
+;; Project type detection happens in a reverse order with respect to
+;; project type registration (invocations of `projectile-register-project-type').
+;;
+;; As function-based project type detection is pretty slow, so it
+;; should be tried at the end if everything else failed (meaning here
+;; it should be listed first).
+;;
+;; Ideally common project types should be checked earlier than exotic ones.
+
+;; Function-based detection project type
+(projectile-register-project-type 'haskell-cabal #'projectile-cabal-project-p
+ :compile "cabal build"
+ :test "cabal test"
+ :run "cabal run"
+ :test-suffix "Spec")
+(projectile-register-project-type 'dotnet #'projectile-dotnet-project-p
+ :compile "dotnet build"
+ :run "dotnet run"
+ :test "dotnet test")
+(projectile-register-project-type 'go projectile-go-project-test-function
+ :compile "go build"
+ :test "go test ./..."
+ :test-suffix "_test")
+;; File-based detection project types
+
+;; Universal
+(projectile-register-project-type 'scons '("SConstruct")
+ :project-file "SConstruct"
+ :compile "scons"
+ :test "scons test"
+ :test-suffix "test")
+(projectile-register-project-type 'meson '("meson.build")
+ :project-file "meson.build"
+ :compilation-dir "build"
+ :configure "meson %s"
+ :compile "ninja"
+ :test "ninja test")
+(projectile-register-project-type 'nix '("default.nix")
+ :project-file "default.nix"
+ :compile "nix-build"
+ :test "nix-build")
+(projectile-register-project-type 'nix-flake '("flake.nix")
+ :project-file "flake.nix"
+ :compile "nix build"
+ :test "nix flake check"
+ :run "nix run")
+(projectile-register-project-type 'bazel '("WORKSPACE")
+ :project-file "WORKSPACE"
+ :compile "bazel build"
+ :test "bazel test"
+ :run "bazel run")
+(projectile-register-project-type 'debian '("debian/control")
+ :project-file "debian/control"
+ :compile "debuild -uc -us")
+
+;; Make & CMake
+(projectile-register-project-type 'make '("Makefile")
+ :project-file "Makefile"
+ :compile "make"
+ :test "make test"
+ :install "make install")
+(projectile-register-project-type 'gnumake '("GNUMakefile")
+ :project-file "GNUMakefile"
+ :compile "make"
+ :test "make test"
+ :install "make install")
+(projectile-register-project-type 'cmake '("CMakeLists.txt")
+ :project-file "CMakeLists.txt"
+ :configure #'projectile--cmake-configure-command
+ :compile #'projectile--cmake-compile-command
+ :test #'projectile--cmake-test-command
+ :install #'projectile--cmake-install-command
+ :package "cmake --build build --target package")
+;; PHP
+(projectile-register-project-type 'php-symfony '("composer.json" "app" "src" "vendor")
+ :project-file "composer.json"
+ :compile "app/console server:run"
+ :test "phpunit -c app "
+ :test-suffix "Test")
+;; Erlang & Elixir
+(projectile-register-project-type 'rebar '("rebar.config")
+ :project-file "rebar.config"
+ :compile "rebar3 compile"
+ :test "rebar3 do eunit,ct"
+ :test-suffix "_SUITE")
+(projectile-register-project-type 'elixir '("mix.exs")
+ :project-file "mix.exs"
+ :compile "mix compile"
+ :src-dir "lib/"
+ :test "mix test"
+ :test-suffix "_test")
+;; JavaScript
+(projectile-register-project-type 'grunt '("Gruntfile.js")
+ :project-file "Gruntfile.js"
+ :compile "grunt"
+ :test "grunt test")
+(projectile-register-project-type 'gulp '("gulpfile.js")
+ :project-file "gulpfile.js"
+ :compile "gulp"
+ :test "gulp test")
+(projectile-register-project-type 'npm '("package.json")
+ :project-file "package.json"
+ :compile "npm install"
+ :test "npm test"
+ :test-suffix ".test")
+;; Angular
+(projectile-register-project-type 'angular '("angular.json" ".angular-cli.json")
+ :project-file "angular.json"
+ :compile "ng build"
+ :run "ng serve"
+ :test "ng test"
+ :test-suffix ".spec")
+;; Python
+(projectile-register-project-type 'django '("manage.py")
+ :project-file "manage.py"
+ :compile "python manage.py runserver"
+ :test "python manage.py test"
+ :test-prefix "test_"
+ :test-suffix"_test")
+(projectile-register-project-type 'python-pip '("requirements.txt")
+ :project-file "requirements.txt"
+ :compile "python setup.py build"
+ :test "python -m unittest discover"
+ :test-prefix "test_"
+ :test-suffix"_test")
+(projectile-register-project-type 'python-pkg '("setup.py")
+ :project-file "setup.py"
+ :compile "python setup.py build"
+ :test "python -m unittest discover"
+ :test-prefix "test_"
+ :test-suffix"_test")
+(projectile-register-project-type 'python-tox '("tox.ini")
+ :project-file "tox.ini"
+ :compile "tox -r --notest"
+ :test "tox"
+ :test-prefix "test_"
+ :test-suffix"_test")
+(projectile-register-project-type 'python-pipenv '("Pipfile")
+ :project-file "Pipfile"
+ :compile "pipenv run build"
+ :test "pipenv run test"
+ :test-prefix "test_"
+ :test-suffix "_test")
+(projectile-register-project-type 'python-poetry '("poetry.lock")
+ :project-file "poetry.lock"
+ :compile "poetry build"
+ :test "poetry run python -m unittest discover"
+ :test-prefix "test_"
+ :test-suffix "_test")
+;; Java & friends
+(projectile-register-project-type 'maven '("pom.xml")
+ :project-file "pom.xml"
+ :compile "mvn -B clean install"
+ :test "mvn -B test"
+ :test-suffix "Test"
+ :src-dir "src/main/"
+ :test-dir "src/test/")
+(projectile-register-project-type 'gradle '("build.gradle")
+ :project-file "build.gradle"
+ :compile "gradle build"
+ :test "gradle test"
+ :test-suffix "Spec")
+(projectile-register-project-type 'gradlew '("gradlew")
+ :project-file "gradlew"
+ :compile "./gradlew build"
+ :test "./gradlew test"
+ :test-suffix "Spec")
+(projectile-register-project-type 'grails '("application.yml" "grails-app")
+ :project-file "application.yml"
+ :compile "grails package"
+ :test "grails test-app"
+ :test-suffix "Spec")
+;; Scala
+(projectile-register-project-type 'sbt '("build.sbt")
+ :project-file "build.sbt"
+ :src-dir "main"
+ :test-dir "test"
+ :compile "sbt compile"
+ :test "sbt test"
+ :test-suffix "Spec")
+
+(projectile-register-project-type 'mill '("build.sc")
+ :project-file "build.sc"
+ :compile "mill all __.compile"
+ :test "mill all __.test"
+ :test-suffix "Test")
+
+;; Clojure
+(projectile-register-project-type 'lein-test '("project.clj")
+ :project-file "project.clj"
+ :compile "lein compile"
+ :test "lein test"
+ :test-suffix "_test")
+(projectile-register-project-type 'lein-midje '("project.clj" ".midje.clj")
+ :project-file "project.clj"
+ :compile "lein compile"
+ :test "lein midje"
+ :test-prefix "t_")
+(projectile-register-project-type 'boot-clj '("build.boot")
+ :project-file "build.boot"
+ :compile "boot aot"
+ :test "boot test"
+ :test-suffix "_test")
+(projectile-register-project-type 'clojure-cli '("deps.edn")
+ :project-file "deps.edn"
+ :test-suffix "_test")
+(projectile-register-project-type 'bloop '(".bloop")
+ :project-file ".bloop"
+ :compile "bloop compile root"
+ :test "bloop test --propagate --reporter scalac root"
+ :src-dir "src/main/"
+ :test-dir "src/test/"
+ :test-suffix "Spec")
+;; Ruby
+(projectile-register-project-type 'ruby-rspec '("Gemfile" "lib" "spec")
+ :project-file "Gemfile"
+ :compile "bundle exec rake"
+ :src-dir "lib/"
+ :test "bundle exec rspec"
+ :test-dir "spec/"
+ :test-suffix "_spec")
+(projectile-register-project-type 'ruby-test '("Gemfile" "lib" "test")
+ :project-file "Gemfile"
+ :compile"bundle exec rake"
+ :src-dir "lib/"
+ :test "bundle exec rake test"
+ :test-suffix "_test")
+;; Rails needs to be registered after npm, otherwise `package.json` makes it `npm`.
+;; https://github.com/bbatsov/projectile/pull/1191
+(projectile-register-project-type 'rails-test '("Gemfile" "app" "lib" "db" "config" "test")
+ :project-file "Gemfile"
+ :compile "bundle exec rails server"
+ :src-dir "lib/"
+ :test "bundle exec rake test"
+ :test-suffix "_test")
+(projectile-register-project-type 'rails-rspec '("Gemfile" "app" "lib" "db" "config" "spec")
+ :project-file "Gemfile"
+ :compile "bundle exec rails server"
+ :src-dir "lib/"
+ :test "bundle exec rspec"
+ :test-dir "spec/"
+ :test-suffix "_spec")
+;; Crystal
+(projectile-register-project-type 'crystal-spec '("shard.yml")
+ :project-file "shard.yml"
+ :src-dir "src/"
+ :test "crystal spec"
+ :test-dir "spec/"
+ :test-suffix "_spec")
+
+;; Emacs
+(projectile-register-project-type 'emacs-cask '("Cask")
+ :project-file "Cask"
+ :compile "cask install"
+ :test-prefix "test-"
+ :test-suffix "-test")
+(projectile-register-project-type 'emacs-eldev (lambda () (or (projectile-verify-file "Eldev")
+ (projectile-verify-file "Eldev-local")))
+ :project-file "Eldev"
+ :compile "eldev compile"
+ :test "eldev test"
+ :run "eldev emacs"
+ :package "eldev package")
+
+;; R
+(projectile-register-project-type 'r '("DESCRIPTION")
+ :project-file "DESCRIPTION"
+ :compile "R CMD INSTALL --with-keep.source ."
+ :test (concat "R CMD check -o " temporary-file-directory " ."))
+
+;; Haskell
+(projectile-register-project-type 'haskell-stack '("stack.yaml")
+ :project-file "stack.yaml"
+ :compile "stack build"
+ :test "stack build --test"
+ :test-suffix "Spec")
+
+;; Rust
+(projectile-register-project-type 'rust-cargo '("Cargo.toml")
+ :project-file "Cargo.toml"
+ :compile "cargo build"
+ :test "cargo test"
+ :run "cargo run")
+
+;; Racket
+(projectile-register-project-type 'racket '("info.rkt")
+ :project-file "info.rkt"
+ :test "raco test ."
+ :install "raco pkg install"
+ :package "raco pkg create --source $(pwd)")
+
+;; Dart
+(projectile-register-project-type 'dart '("pubspec.yaml")
+ :project-file "pubspec.yaml"
+ :compile "pub get"
+ :test "pub run test"
+ :run "dart"
+ :test-suffix "_test.dart")
+
+;; OCaml
+(projectile-register-project-type 'ocaml-dune '("dune-project")
+ :project-file "dune-project"
+ :compile "dune build"
+ :test "dune runtest")
+
+(defvar-local projectile-project-type nil
+ "Buffer local var for overriding the auto-detected project type.
+Normally you'd set this from .dir-locals.el.")
+(put 'projectile-project-type 'safe-local-variable #'symbolp)
+
+(defun projectile-detect-project-type ()
+ "Detect the type of the current project.
+Fallsback to a generic project type when the type can't be determined."
+ (let ((project-type
+ (or (car (cl-find-if
+ (lambda (project-type-record)
+ (let ((project-type (car project-type-record))
+ (marker (plist-get (cdr project-type-record) 'marker-files)))
+ (if (functionp marker)
+ (and (funcall marker) project-type)
+ (and (projectile-verify-files marker) project-type))))
+ projectile-project-types))
+ 'generic)))
+ (puthash (projectile-project-root) project-type projectile-project-type-cache)
+ project-type))
+
+(defun projectile-project-type (&optional dir)
+ "Determine a project's type based on its structure.
+When DIR is specified it checks it, otherwise it acts
+on the current project.
+
+The project type is cached for improved performance."
+ (if projectile-project-type
+ projectile-project-type
+ (let* ((dir (or dir default-directory))
+ (project-root (projectile-project-root dir)))
+ (if project-root
+ (or (gethash project-root projectile-project-type-cache)
+ (projectile-detect-project-type))
+ ;; if we're not in a project we just return nil
+ nil))))
+
+;;;###autoload
+(defun projectile-project-info ()
+ "Display info for current project."
+ (interactive)
+ (message "Project dir: %s ## Project VCS: %s ## Project type: %s"
+ (projectile-acquire-root)
+ (projectile-project-vcs)
+ (projectile-project-type)))
+
+(defun projectile-verify-files (files)
+ "Check whether all FILES exist in the current project."
+ (cl-every #'projectile-verify-file files))
+
+(defun projectile-verify-file (file)
+ "Check whether FILE exists in the current project."
+ (file-exists-p (projectile-expand-root file)))
+
+(defun projectile-verify-file-wildcard (file)
+ "Check whether FILE exists in the current project.
+Expands wildcards using `file-expand-wildcards' before checking."
+ (file-expand-wildcards (projectile-expand-root file)))
+
+(defun projectile-project-vcs (&optional project-root)
+ "Determine the VCS used by the project if any.
+PROJECT-ROOT is the targeted directory. If nil, use
+the variable `projectile-project-root'."
+ (or project-root (setq project-root (projectile-acquire-root)))
+ (cond
+ ;; first we check for a VCS marker in the project root itself
+ ((projectile-file-exists-p (expand-file-name ".git" project-root)) 'git)
+ ((projectile-file-exists-p (expand-file-name ".hg" project-root)) 'hg)
+ ((projectile-file-exists-p (expand-file-name ".fslckout" project-root)) 'fossil)
+ ((projectile-file-exists-p (expand-file-name "_FOSSIL_" project-root)) 'fossil)
+ ((projectile-file-exists-p (expand-file-name ".bzr" project-root)) 'bzr)
+ ((projectile-file-exists-p (expand-file-name "_darcs" project-root)) 'darcs)
+ ((projectile-file-exists-p (expand-file-name ".pijul" project-root)) 'pijul)
+ ((projectile-file-exists-p (expand-file-name ".svn" project-root)) 'svn)
+ ;; then we check if there's a VCS marker up the directory tree
+ ;; that covers the case when a project is part of a multi-project repository
+ ;; in those cases you can still the VCS to get a list of files for
+ ;; the project in question
+ ((projectile-locate-dominating-file project-root ".git") 'git)
+ ((projectile-locate-dominating-file project-root ".hg") 'hg)
+ ((projectile-locate-dominating-file project-root ".fslckout") 'fossil)
+ ((projectile-locate-dominating-file project-root "_FOSSIL_") 'fossil)
+ ((projectile-locate-dominating-file project-root ".bzr") 'bzr)
+ ((projectile-locate-dominating-file project-root "_darcs") 'darcs)
+ ((projectile-locate-dominating-file project-root ".pijul") 'pijul)
+ ((projectile-locate-dominating-file project-root ".svn") 'svn)
+ (t 'none)))
+
+(defun projectile--test-name-for-impl-name (impl-file-path)
+ "Determine the name of the test file for IMPL-FILE-PATH.
+
+IMPL-FILE-PATH may be a absolute path, relative path or a file name."
+ (let* ((project-type (projectile-project-type))
+ (impl-file-name (file-name-sans-extension (file-name-nondirectory impl-file-path)))
+ (impl-file-ext (file-name-extension impl-file-path))
+ (test-prefix (funcall projectile-test-prefix-function project-type))
+ (test-suffix (funcall projectile-test-suffix-function project-type)))
+ (cond
+ (test-prefix (concat test-prefix impl-file-name "." impl-file-ext))
+ (test-suffix (concat impl-file-name test-suffix "." impl-file-ext))
+ (t (error "Cannot determine a test file name, one of \"test-suffix\" or \"test-prefix\" must be set for project type `%s'" project-type)))))
+
+(defun projectile--impl-name-for-test-name (test-file-path)
+ "Determine the name of the implementation file for TEST-FILE-PATH.
+
+TEST-FILE-PATH may be a absolute path, relative path or a file name."
+ (let* ((project-type (projectile-project-type))
+ (test-file-name (file-name-sans-extension (file-name-nondirectory test-file-path)))
+ (test-file-ext (file-name-extension test-file-path))
+ (test-prefix (funcall projectile-test-prefix-function project-type))
+ (test-suffix (funcall projectile-test-suffix-function project-type)))
+ (cond
+ (test-prefix
+ (concat (string-remove-prefix test-prefix test-file-name) "." test-file-ext))
+ (test-suffix
+ (concat (string-remove-suffix test-suffix test-file-name) "." test-file-ext))
+ (t (error "Cannot determine an implementation file name, one of \"test-suffix\" or \"test-prefix\" must be set for project type `%s'" project-type)))))
+
+(defun projectile--test-to-impl-dir (test-dir-path)
+ "Return the directory path of an impl file with test file in TEST-DIR-PATH.
+
+Occurrences of the current project type's test-dir property (which should be a
+string) are replaced with the current project type's src-dir property
+ (which should be a string) to obtain the new directory.
+
+Nil is returned if either the src-dir or test-dir properties are not strings."
+ (let* ((project-type (projectile-project-type))
+ (test-dir (projectile-project-type-attribute project-type 'test-dir))
+ (impl-dir (projectile-project-type-attribute project-type 'src-dir)))
+ (when (and (stringp test-dir) (stringp impl-dir))
+ (if (not (string-match-p test-dir (file-name-directory test-dir-path)))
+ (error "Attempted to find a implementation file by switching this project type's (%s) test-dir property \"%s\" with this project type's src-dir property \"%s\", but %s does not contain \"%s\""
+ project-type test-dir impl-dir test-dir-path test-dir)
+ (projectile-complementary-dir test-dir-path test-dir impl-dir)))))
+
+(defun projectile--impl-to-test-dir-fallback (impl-dir-path)
+ "Return the test file for IMPL-DIR-PATH by guessing a test directory.
+
+Occurrences of the `projectile-default-src-directory' in the directory of
+IMPL-DIR-PATH are replaced with `projectile-default-test-directory'. Nil is
+returned if `projectile-default-src-directory' is not a substring of
+IMPL-DIR-PATH."
+ (when-let ((file (projectile--complementary-file
+ impl-dir-path
+ (lambda (f)
+ (when (string-match-p projectile-default-src-directory f)
+ (projectile-complementary-dir
+ impl-dir-path
+ projectile-default-src-directory
+ projectile-default-test-directory)))
+ #'projectile--test-name-for-impl-name)))
+ (file-relative-name file (projectile-project-root))))
+
+(defun projectile--test-to-impl-dir-fallback (test-dir-path)
+ "Return the impl file for TEST-DIR-PATH by guessing a source directory.
+
+Occurrences of `projectile-default-test-directory' in the directory of
+TEST-DIR-PATH are replaced with `projectile-default-src-directory'. Nil is
+returned if `projectile-default-test-directory' is not a substring of
+TEST-DIR-PATH."
+ (when-let ((file (projectile--complementary-file
+ test-dir-path
+ (lambda (f)
+ (when (string-match-p projectile-default-test-directory f)
+ (projectile-complementary-dir
+ test-dir-path
+ projectile-default-test-directory
+ projectile-default-src-directory)))
+ #'projectile--impl-name-for-test-name)))
+ (file-relative-name file (projectile-project-root))))
+
+(defun projectile--impl-to-test-dir (impl-dir-path)
+ "Return the directory path of a test whose impl file resides in IMPL-DIR-PATH.
+
+Occurrences of the current project type's src-dir property (which should be a
+string) are replaced with the current project type's test-dir property
+ (which should be a string) to obtain the new directory.
+
+If the src-dir property is set and IMPL-DIR-PATH does not contain (as a
+substring) the src-dir property of the current project type, an error is
+signalled.
+
+Nil is returned if either the src-dir or test-dir properties are not strings."
+ (let* ((project-type (projectile-project-type))
+ (test-dir (projectile-project-type-attribute project-type 'test-dir))
+ (impl-dir (projectile-project-type-attribute project-type 'src-dir)))
+ (when (and (stringp test-dir) (stringp impl-dir))
+ (if (not (string-match-p impl-dir (file-name-directory impl-dir-path)))
+ (error "Attempted to find a test file by switching this project type's (%s) src-dir property \"%s\" with this project type's test-dir property \"%s\", but %s does not contain \"%s\""
+ project-type impl-dir test-dir impl-dir-path impl-dir)
+ (projectile-complementary-dir impl-dir-path impl-dir test-dir)))))
+
+(defun projectile-complementary-dir (dir-path string replacement)
+ "Return the \"complementary\" directory of DIR-PATH.
+Replace STRING in DIR-PATH with REPLACEMENT."
+ (let* ((project-root (projectile-project-root))
+ (relative-dir (file-name-directory (file-relative-name dir-path project-root))))
+ (projectile-expand-root
+ (replace-regexp-in-string string replacement relative-dir))))
+
+(defun projectile--create-directories-for (path)
+ "Create directories necessary for PATH."
+ (unless (file-exists-p path)
+ (make-directory (if (file-directory-p path)
+ path
+ (file-name-directory path))
+ :create-parents)))
+
+(defun projectile-find-implementation-or-test (file-name)
+ "Given a FILE-NAME return the matching implementation or test filename.
+
+If `projectile-create-missing-test-files' is non-nil, create the missing
+test file."
+ (unless file-name (error "The current buffer is not visiting a file"))
+ (unless (projectile-project-type) (projectile-ensure-project nil))
+ (if (projectile-test-file-p file-name)
+ ;; find the matching impl file
+ (let ((impl-file (projectile-find-matching-file file-name)))
+ (if impl-file
+ (projectile-expand-root impl-file)
+ (error
+ "No matching source file found for project type `%s'"
+ (projectile-project-type))))
+ ;; find the matching test file
+ (let* ((error-msg (format
+ "No matching test file found for project type `%s'"
+ (projectile-project-type)))
+ (test-file (or (projectile-find-matching-test file-name)
+ (error error-msg)))
+ (expanded-test-file (projectile-expand-root test-file)))
+ (cond ((file-exists-p expanded-test-file) expanded-test-file)
+ (projectile-create-missing-test-files
+ (projectile--create-directories-for expanded-test-file)
+ expanded-test-file)
+ (t (error "Determined test file to be \"%s\", which does not exist. Set `projectile-create-missing-test-files' to allow `projectile-find-implementation-or-test' to create new files" test-file))))))
+
+;;;###autoload
+(defun projectile-find-implementation-or-test-other-window ()
+ "Open matching implementation or test file in other window.
+
+See the documentation of `projectile--find-matching-file' and
+`projectile--find-matching-test' for how implementation and test files
+are determined."
+ (interactive)
+ (find-file-other-window
+ (projectile-find-implementation-or-test (buffer-file-name))))
+
+;;;###autoload
+(defun projectile-find-implementation-or-test-other-frame ()
+ "Open matching implementation or test file in other frame.
+
+See the documentation of `projectile--find-matching-file' and
+`projectile--find-matching-test' for how implementation and test files
+are determined."
+ (interactive)
+ (find-file-other-frame
+ (projectile-find-implementation-or-test (buffer-file-name))))
+
+;;;###autoload
+(defun projectile-toggle-between-implementation-and-test ()
+ "Toggle between an implementation file and its test file.
+
+
+See the documentation of `projectile--find-matching-file' and
+`projectile--find-matching-test' for how implementation and test files
+are determined."
+ (interactive)
+ (find-file
+ (projectile-find-implementation-or-test (buffer-file-name))))
+
+
+(defun projectile-project-type-attribute (project-type key &optional default-value)
+ "Return the value of some PROJECT-TYPE attribute identified by KEY.
+Fallback to DEFAULT-VALUE for missing attributes."
+ (let ((project (alist-get project-type projectile-project-types)))
+ (if (and project (plist-member project key))
+ (plist-get project key)
+ default-value)))
+
+(defun projectile-test-prefix (project-type)
+ "Find default test files prefix based on PROJECT-TYPE."
+ (projectile-project-type-attribute project-type 'test-prefix))
+
+(defun projectile-test-suffix (project-type)
+ "Find default test files suffix based on PROJECT-TYPE."
+ (projectile-project-type-attribute project-type 'test-suffix))
+
+(defun projectile-related-files-fn (project-type)
+ "Find relative file based on PROJECT-TYPE."
+ (projectile-project-type-attribute project-type 'related-files-fn))
+
+(defun projectile-src-directory (project-type)
+ "Find default src directory based on PROJECT-TYPE."
+ (projectile-project-type-attribute
+ project-type 'src-dir projectile-default-src-directory))
+
+(defun projectile-test-directory (project-type)
+ "Find default test directory based on PROJECT-TYPE."
+ (projectile-project-type-attribute
+ project-type 'test-dir projectile-default-test-directory))
+
+(defun projectile-dirname-matching-count (a b)
+ "Count matching dirnames ascending file paths in A and B."
+ (setq a (reverse (split-string (or (file-name-directory a) "") "/" t))
+ b (reverse (split-string (or (file-name-directory b) "") "/" t)))
+ (let ((common 0))
+ (while (and a b (string-equal (pop a) (pop b)))
+ (setq common (1+ common)))
+ common))
+
+(defun projectile-group-file-candidates (file candidates)
+ "Group file candidates by dirname matching count."
+ (cl-sort (copy-sequence
+ (let (value result)
+ (while (setq value (pop candidates))
+ (let* ((key (projectile-dirname-matching-count file value))
+ (kv (assoc key result)))
+ (if kv
+ (setcdr kv (cons value (cdr kv)))
+ (push (list key value) result))))
+ (mapcar (lambda (x)
+ (cons (car x) (nreverse (cdr x))))
+ (nreverse result))))
+ (lambda (a b) (> (car a) (car b)))))
+
+(defun projectile--best-or-all-candidates-based-on-parents-dirs (file candidates)
+ "Return a list of the best one one for FILE from CANDIDATES or all CANDIDATES."
+ (let ((grouped-candidates (projectile-group-file-candidates file candidates)))
+ (if (= (length (car grouped-candidates)) 2)
+ (list (car (last (car grouped-candidates))))
+ (apply #'append (mapcar #'cdr grouped-candidates)))))
+
+(defun projectile--impl-to-test-predicate (impl-file)
+ "Return a predicate, which returns t for any test files for IMPL-FILE."
+ (let* ((basename (file-name-sans-extension (file-name-nondirectory impl-file)))
+ (test-prefix (funcall projectile-test-prefix-function (projectile-project-type)))
+ (test-suffix (funcall projectile-test-suffix-function (projectile-project-type)))
+ (prefix-name (when test-prefix (concat test-prefix basename)))
+ (suffix-name (when test-suffix (concat basename test-suffix))))
+ (lambda (current-file)
+ (let ((name (file-name-sans-extension (file-name-nondirectory current-file))))
+ (or (string-equal prefix-name name)
+ (string-equal suffix-name name))))))
+
+(defun projectile--complementary-file (file-path dir-fn filename-fn)
+ "Apply DIR-FN and FILENAME-FN to the directory and name of FILE-PATH.
+
+More specifically, return DIR-FN applied to the directory of FILE-PATH
+concatenated with FILENAME-FN applied to the file name of FILE-PATH.
+
+If either function returns nil, return nil."
+ (let ((filename (file-name-nondirectory file-path)))
+ (when-let ((complementary-filename (funcall filename-fn filename))
+ (dir (funcall dir-fn (file-name-directory file-path))))
+ (concat (file-name-as-directory dir) complementary-filename))))
+
+(defun projectile--impl-file-from-src-dir-str (file-name)
+ "Get the relative path of the implementation file FILE-NAME.
+Return a path relative to the project root for the impl file of FILE-NAME
+using the src-dir and test-dir properties of the current project type which
+should be strings, nil returned if this is not the case."
+ (when-let ((complementary-file (projectile--complementary-file
+ file-name
+ #'projectile--test-to-impl-dir
+ #'projectile--impl-name-for-test-name)))
+ (file-relative-name complementary-file (projectile-project-root))))
+
+(defun projectile--test-file-from-test-dir-str (file-name)
+ "Get the relative path of the test file FILE-NAME.
+Return a path relative to the project root for the test file of FILE-NAME
+using the src-dir and test-dir properties of the current project type which
+should be strings, nil returned if this is not the case."
+ (when-let (complementary-file (projectile--complementary-file
+ file-name
+ #'projectile--impl-to-test-dir
+ #'projectile--test-name-for-impl-name))
+ (file-relative-name complementary-file (projectile-project-root))))
+
+(defun projectile--impl-file-from-src-dir-fn (test-file)
+ "Get the relative path to the implementation file corresponding to TEST-FILE.
+Return the implementation file path for the absolute path TEST-FILE
+relative to the project root in the case the current project type's src-dir
+has been set to a custom function, return nil if this is not the case or
+the path points to a file that does not exist."
+ (when-let ((src-dir (projectile-src-directory (projectile-project-type))))
+ (when (functionp src-dir)
+ (let ((impl-file (projectile--complementary-file
+ test-file
+ src-dir
+ #'projectile--impl-name-for-test-name)))
+ (when (file-exists-p impl-file)
+ (file-relative-name impl-file (projectile-project-root)))))))
+
+(defun projectile--test-file-from-test-dir-fn (impl-file)
+ "Get the relative path to the test file corresponding to IMPL-FILE.
+Return the test file path for the absolute path IMPL-FILE relative to the
+project root, in the case the current project type's test-dir has been set
+to a custom function, else return nil."
+ (when-let ((test-dir (projectile-test-directory (projectile-project-type))))
+ (when (functionp test-dir)
+ (file-relative-name
+ (projectile--complementary-file
+ impl-file
+ test-dir
+ #'projectile--test-name-for-impl-name)
+ (projectile-project-root)))))
+
+(defmacro projectile--acond (&rest clauses)
+ "Like `cond', but the result of each condition is bound to `it'.
+
+The variable `it' is available within the remainder of each of CLAUSES.
+
+CLAUSES are otherwise as documented for `cond'. This is copied from
+anaphora.el."
+ (declare (debug cond))
+ (if (null clauses)
+ nil
+ (let ((cl1 (car clauses))
+ (sym (cl-gensym)))
+ `(let ((,sym ,(car cl1)))
+ (if ,sym
+ (if (null ',(cdr cl1))
+ ,sym
+ (let ((it ,sym)) ,@(cdr cl1)))
+ (projectile--acond ,@(cdr clauses)))))))
+
+(defun projectile--find-matching-test (impl-file)
+ "Return a list of test files for IMPL-FILE.
+
+The precendence for determining test files to return is:
+
+1. Use the project type's test-dir property if it's set to a function
+2. Use the project type's related-files-fn property if set
+3. Use the project type's test-dir property if it's set to a string
+4. Attempt to find a file by matching all project files against
+ `projectile--impl-to-test-predicate'
+5. Fallback to swapping \"src\" for \"test\" in IMPL-FILE if \"src\"
+ is a substring of IMPL-FILE."
+ (projectile--acond
+ ((projectile--test-file-from-test-dir-fn impl-file) (list it))
+ ((projectile--related-files-plist-by-kind impl-file :test)
+ (projectile--related-files-from-plist it))
+ ((projectile--test-file-from-test-dir-str impl-file) (list it))
+ ((projectile--best-or-all-candidates-based-on-parents-dirs
+ impl-file (cl-remove-if-not
+ (projectile--impl-to-test-predicate impl-file)
+ (projectile-current-project-files))) it)
+ ((projectile--impl-to-test-dir-fallback impl-file)
+ (list it))))
+
+(defun projectile--test-to-impl-predicate (test-file)
+ "Return a predicate, which returns t for any impl files for TEST-FILE."
+ (let* ((basename (file-name-sans-extension (file-name-nondirectory test-file)))
+ (test-prefix (funcall projectile-test-prefix-function (projectile-project-type)))
+ (test-suffix (funcall projectile-test-suffix-function (projectile-project-type))))
+ (lambda (current-file)
+ (let ((name (file-name-nondirectory (file-name-sans-extension current-file))))
+ (or (when test-prefix (string-equal (concat test-prefix name) basename))
+ (when test-suffix (string-equal (concat name test-suffix) basename)))))))
+
+(defun projectile--find-matching-file (test-file)
+ "Return a list of impl files tested by TEST-FILE.
+
+The precendence for determining implementation files to return is:
+
+1. Use the project type's src-dir property if it's set to a function
+2. Use the project type's related-files-fn property if set
+3. Use the project type's src-dir property if it's set to a string
+4. Default to a fallback which matches all project files against
+ `projectile--test-to-impl-predicate'
+5. Fallback to swapping \"test\" for \"src\" in TEST-FILE if \"test\"
+ is a substring of TEST-FILE."
+ (projectile--acond
+ ((projectile--impl-file-from-src-dir-fn test-file) (list it))
+ ((projectile--related-files-plist-by-kind test-file :impl)
+ (projectile--related-files-from-plist it))
+ ((projectile--impl-file-from-src-dir-str test-file) (list it))
+ ((projectile--best-or-all-candidates-based-on-parents-dirs
+ test-file (cl-remove-if-not
+ (projectile--test-to-impl-predicate test-file)
+ (projectile-current-project-files))) it)
+ ((projectile--test-to-impl-dir-fallback test-file) (list it))))
+
+(defun projectile--choose-from-candidates (candidates)
+ "Choose one item from CANDIDATES."
+ (if (= (length candidates) 1)
+ (car candidates)
+ (projectile-completing-read "Switch to: " candidates)))
+
+(defun projectile-find-matching-test (impl-file)
+ "Compute the name of the test matching IMPL-FILE."
+ (when-let ((candidates (projectile--find-matching-test impl-file)))
+ (projectile--choose-from-candidates candidates)))
+
+(defun projectile-find-matching-file (test-file)
+ "Compute the name of a file matching TEST-FILE."
+ (when-let ((candidates (projectile--find-matching-file test-file)))
+ (projectile--choose-from-candidates candidates)))
+
+(defun projectile-grep-default-files ()
+ "Try to find a default pattern for `projectile-grep'.
+This is a subset of `grep-read-files', where either a matching entry from
+`grep-files-aliases' or file name extension pattern is returned."
+ (when buffer-file-name
+ (let* ((fn (file-name-nondirectory buffer-file-name))
+ (default-alias
+ (let ((aliases (remove (assoc "all" grep-files-aliases)
+ grep-files-aliases))
+ alias)
+ (while aliases
+ (setq alias (car aliases)
+ aliases (cdr aliases))
+ (if (string-match (mapconcat
+ #'wildcard-to-regexp
+ (split-string (cdr alias) nil t)
+ "\\|")
+ fn)
+ (setq aliases nil)
+ (setq alias nil)))
+ (cdr alias)))
+ (default-extension
+ (let ((ext (file-name-extension fn)))
+ (and ext (concat "*." ext)))))
+ (or default-alias default-extension))))
+
+(defun projectile--globally-ignored-file-suffixes-glob ()
+ "Return ignored file suffixes as a list of glob patterns."
+ (mapcar (lambda (pat) (concat "*" pat)) projectile-globally-ignored-file-suffixes))
+
+(defun projectile--read-search-string-with-default (prefix-label)
+ (let* ((prefix-label (projectile-prepend-project-name prefix-label))
+ (default-value (projectile-symbol-or-selection-at-point))
+ (default-label (if (or (not default-value)
+ (string= default-value ""))
+ ""
+ (format " (default %s)" default-value))))
+ (read-string (format "%s%s: " prefix-label default-label) nil nil default-value)))
+
+(defvar projectile-grep-find-ignored-paths)
+(defvar projectile-grep-find-unignored-paths)
+(defvar projectile-grep-find-ignored-patterns)
+(defvar projectile-grep-find-unignored-patterns)
+
+(defun projectile-rgrep-default-command (regexp files dir)
+ "Compute the command for \\[rgrep] to use by default.
+
+Extension of the Emacs 25.1 implementation of `rgrep-default-command', with
+which it shares its arglist."
+ (require 'find-dired) ; for `find-name-arg'
+ (grep-expand-template
+ grep-find-template
+ regexp
+ (concat (shell-quote-argument "(")
+ " " find-name-arg " "
+ (mapconcat
+ #'shell-quote-argument
+ (split-string files)
+ (concat " -o " find-name-arg " "))
+ " "
+ (shell-quote-argument ")"))
+ dir
+ (concat
+ (and grep-find-ignored-directories
+ (concat "-type d "
+ (shell-quote-argument "(")
+ ;; we should use shell-quote-argument here
+ " -path "
+ (mapconcat
+ #'identity
+ (delq nil (mapcar
+ #'(lambda (ignore)
+ (cond ((stringp ignore)
+ (shell-quote-argument
+ (concat "*/" ignore)))
+ ((consp ignore)
+ (and (funcall (car ignore) dir)
+ (shell-quote-argument
+ (concat "*/"
+ (cdr ignore)))))))
+ grep-find-ignored-directories))
+ " -o -path ")
+ " "
+ (shell-quote-argument ")")
+ " -prune -o "))
+ (and grep-find-ignored-files
+ (concat (shell-quote-argument "!") " -type d "
+ (shell-quote-argument "(")
+ ;; we should use shell-quote-argument here
+ " -name "
+ (mapconcat
+ #'(lambda (ignore)
+ (cond ((stringp ignore)
+ (shell-quote-argument ignore))
+ ((consp ignore)
+ (and (funcall (car ignore) dir)
+ (shell-quote-argument
+ (cdr ignore))))))
+ grep-find-ignored-files
+ " -o -name ")
+ " "
+ (shell-quote-argument ")")
+ " -prune -o "))
+ (and projectile-grep-find-ignored-paths
+ (concat (shell-quote-argument "(")
+ " -path "
+ (mapconcat
+ (lambda (ignore) (shell-quote-argument
+ (concat "./" ignore)))
+ projectile-grep-find-ignored-paths
+ " -o -path ")
+ " "
+ (shell-quote-argument ")")
+ " -prune -o "))
+ (and projectile-grep-find-ignored-patterns
+ (concat (shell-quote-argument "(")
+ (and (or projectile-grep-find-unignored-paths
+ projectile-grep-find-unignored-patterns)
+ (concat " "
+ (shell-quote-argument "(")))
+ " -path "
+ (mapconcat
+ (lambda (ignore)
+ (shell-quote-argument
+ (if (string-prefix-p "*" ignore) ignore
+ (concat "*/" ignore))))
+ projectile-grep-find-ignored-patterns
+ " -o -path ")
+ (and (or projectile-grep-find-unignored-paths
+ projectile-grep-find-unignored-patterns)
+ (concat " "
+ (shell-quote-argument ")")
+ " -a "
+ (shell-quote-argument "!")
+ " "
+ (shell-quote-argument "(")
+ (and projectile-grep-find-unignored-paths
+ (concat " -path "
+ (mapconcat
+ (lambda (ignore) (shell-quote-argument
+ (concat "./" ignore)))
+ projectile-grep-find-unignored-paths
+ " -o -path ")))
+ (and projectile-grep-find-unignored-paths
+ projectile-grep-find-unignored-patterns
+ " -o")
+ (and projectile-grep-find-unignored-patterns
+ (concat " -path "
+ (mapconcat
+ (lambda (ignore)
+ (shell-quote-argument
+ (if (string-prefix-p "*" ignore) ignore
+ (concat "*/" ignore))))
+ projectile-grep-find-unignored-patterns
+ " -o -path ")))
+ " "
+ (shell-quote-argument ")")))
+ " "
+ (shell-quote-argument ")")
+ " -prune -o ")))))
+
+;;;###autoload
+(defun projectile-grep (&optional regexp arg)
+ "Perform rgrep in the project.
+
+With a prefix ARG asks for files (globbing-aware) which to grep in.
+With prefix ARG of `-' (such as `M--'), default the files (without prompt),
+to `projectile-grep-default-files'.
+
+With REGEXP given, don't query the user for a regexp."
+ (interactive "i\nP")
+ (require 'grep) ;; for `rgrep'
+ (let* ((roots (projectile-get-project-directories (projectile-acquire-root)))
+ (search-regexp (or regexp
+ (projectile--read-search-string-with-default "Grep for")))
+ (files (and arg (or (and (equal current-prefix-arg '-)
+ (projectile-grep-default-files))
+ (read-string (projectile-prepend-project-name "Grep in: ")
+ (projectile-grep-default-files))))))
+ (dolist (root-dir roots)
+ (require 'vc-git) ;; for `vc-git-grep'
+ ;; in git projects users have the option to use `vc-git-grep' instead of `rgrep'
+ (if (and (eq (projectile-project-vcs) 'git)
+ projectile-use-git-grep
+ (fboundp 'vc-git-grep))
+ (vc-git-grep search-regexp (or files "") root-dir)
+ ;; paths for find-grep should relative and without trailing /
+ (let ((grep-find-ignored-files
+ (cl-union (projectile--globally-ignored-file-suffixes-glob)
+ grep-find-ignored-files))
+ (projectile-grep-find-ignored-paths
+ (append (mapcar (lambda (f) (directory-file-name (file-relative-name f root-dir)))
+ (projectile-ignored-directories))
+ (mapcar (lambda (file)
+ (file-relative-name file root-dir))
+ (projectile-ignored-files))))
+ (projectile-grep-find-unignored-paths
+ (append (mapcar (lambda (f) (directory-file-name (file-relative-name f root-dir)))
+ (projectile-unignored-directories))
+ (mapcar (lambda (file)
+ (file-relative-name file root-dir))
+ (projectile-unignored-files))))
+ (projectile-grep-find-ignored-patterns (projectile-patterns-to-ignore))
+ (projectile-grep-find-unignored-patterns (projectile-patterns-to-ensure)))
+ (grep-compute-defaults)
+ (cl-letf (((symbol-function 'rgrep-default-command) #'projectile-rgrep-default-command))
+ (rgrep search-regexp (or files "* .*") root-dir)
+ (when (get-buffer "*grep*")
+ ;; When grep is using a global *grep* buffer rename it to be
+ ;; scoped to the current root to allow multiple concurrent grep
+ ;; operations, one per root
+ (with-current-buffer "*grep*"
+ (rename-buffer (concat "*grep <" root-dir ">*"))))))))
+ (run-hooks 'projectile-grep-finished-hook)))
+
+;;;###autoload
+(defun projectile-ag (search-term &optional arg)
+ "Run an ag search with SEARCH-TERM in the project.
+
+With an optional prefix argument ARG SEARCH-TERM is interpreted as a
+regular expression."
+ (interactive
+ (list (projectile--read-search-string-with-default
+ (format "Ag %ssearch for" (if current-prefix-arg "regexp " "")))
+ current-prefix-arg))
+ (if (require 'ag nil 'noerror)
+ (let ((ag-command (if arg 'ag-regexp 'ag))
+ (ag-ignore-list (delq nil
+ (delete-dups
+ (append
+ ag-ignore-list
+ (projectile-ignored-files-rel)
+ (projectile-ignored-directories-rel)
+ (projectile--globally-ignored-file-suffixes-glob)
+ ;; ag supports git ignore files directly
+ (unless (eq (projectile-project-vcs) 'git)
+ (append grep-find-ignored-files
+ grep-find-ignored-directories
+ '()))))))
+ ;; reset the prefix arg, otherwise it will affect the ag-command
+ (current-prefix-arg nil))
+ (funcall ag-command search-term (projectile-acquire-root)))
+ (error "Package 'ag' is not available")))
+
+;;;###autoload
+(defun projectile-ripgrep (search-term &optional arg)
+ "Run a ripgrep (rg) search with `SEARCH-TERM' at current project root.
+
+With an optional prefix argument ARG SEARCH-TERM is interpreted as a
+regular expression.
+
+This command depends on of the Emacs packages ripgrep or rg being
+installed to work."
+ (interactive
+ (list (projectile--read-search-string-with-default
+ (format "Ripgrep %ssearch for" (if current-prefix-arg "regexp " "")))
+ current-prefix-arg))
+ (let ((args (mapcar (lambda (val) (concat "--glob !" val))
+ (append projectile-globally-ignored-files
+ projectile-globally-ignored-directories))))
+ ;; we rely on the external packages ripgrep and rg for the actual search
+ ;;
+ ;; first we check if we can load ripgrep
+ (cond ((require 'ripgrep nil 'noerror)
+ (ripgrep-regexp search-term
+ (projectile-acquire-root)
+ (if arg
+ args
+ (cons "--fixed-strings" args))))
+ ;; and then we try rg
+ ((require 'rg nil 'noerror)
+ (rg-run search-term
+ "*" ;; all files
+ (projectile-acquire-root)
+ (not arg) ;; literal search?
+ nil ;; no need to confirm
+ args))
+ (t (error "Packages `ripgrep' and `rg' are not available")))))
+
+(defun projectile-tags-exclude-patterns ()
+ "Return a string with exclude patterns for ctags."
+ (mapconcat (lambda (pattern) (format "--exclude=\"%s\""
+ (directory-file-name pattern)))
+ (append
+ (projectile-ignored-directories-rel)
+ (projectile-patterns-to-ignore)) " "))
+
+;;;###autoload
+(defun projectile-regenerate-tags ()
+ "Regenerate the project's [e|g]tags."
+ (interactive)
+ (if (and (boundp 'ggtags-mode)
+ (memq projectile-tags-backend '(auto ggtags)))
+ (progn
+ (let* ((ggtags-project-root (projectile-acquire-root))
+ (default-directory ggtags-project-root))
+ (ggtags-ensure-project)
+ (ggtags-update-tags t)))
+ (let* ((project-root (projectile-acquire-root))
+ (tags-exclude (projectile-tags-exclude-patterns))
+ (default-directory project-root)
+ (tags-file (expand-file-name projectile-tags-file-name))
+ (command (format projectile-tags-command
+ (or (file-remote-p tags-file 'localname) tags-file)
+ tags-exclude
+ "."))
+ shell-output exit-code)
+ (with-temp-buffer
+ (setq exit-code
+ (process-file-shell-command command nil (current-buffer))
+ shell-output (string-trim
+ (buffer-substring (point-min) (point-max)))))
+ (unless (zerop exit-code)
+ (error shell-output))
+ (visit-tags-table tags-file)
+ (message "Regenerated %s" tags-file))))
+
+(defun projectile-visit-project-tags-table ()
+ "Visit the current project's tags table."
+ (when (projectile-project-p)
+ (let ((tags-file (projectile-expand-root projectile-tags-file-name)))
+ (when (file-exists-p tags-file)
+ (with-demoted-errors "Error loading tags-file: %s"
+ (visit-tags-table tags-file t))))))
+
+(defun projectile-determine-find-tag-fn ()
+ "Determine which function to use for a call to `projectile-find-tag'."
+ (or
+ (cond
+ ((eq projectile-tags-backend 'auto)
+ (cond
+ ((fboundp 'ggtags-find-tag-dwim)
+ 'ggtags-find-tag-dwim)
+ ((fboundp 'xref-find-definitions)
+ 'xref-find-definitions)
+ ((fboundp 'etags-select-find-tag)
+ 'etags-select-find-tag)))
+ ((eq projectile-tags-backend 'xref)
+ (when (fboundp 'xref-find-definitions)
+ 'xref-find-definitions))
+ ((eq projectile-tags-backend 'ggtags)
+ (when (fboundp 'ggtags-find-tag-dwim)
+ 'ggtags-find-tag-dwim))
+ ((eq projectile-tags-backend 'etags-select)
+ (when (fboundp 'etags-select-find-tag)
+ 'etags-select-find-tag)))
+ 'find-tag))
+
+;;;###autoload
+(defun projectile-find-tag ()
+ "Find tag in project."
+ (interactive)
+ (projectile-visit-project-tags-table)
+ ;; Auto-discover the user's preference for tags
+ (let ((find-tag-fn (projectile-determine-find-tag-fn)))
+ (call-interactively find-tag-fn)))
+
+(defmacro projectile-with-default-dir (dir &rest body)
+ "Invoke in DIR the BODY."
+ (declare (debug t) (indent 1))
+ `(let ((default-directory ,dir))
+ ,@body))
+
+;;;###autoload
+(defun projectile-run-command-in-root ()
+ "Invoke `execute-extended-command' in the project's root."
+ (interactive)
+ (projectile-with-default-dir (projectile-acquire-root)
+ (call-interactively #'execute-extended-command)))
+
+;;;###autoload
+(defun projectile-run-shell-command-in-root (command &optional output-buffer error-buffer)
+ "Invoke `shell-command' in the project's root."
+ (interactive (list (read-shell-command "Shell command: ")))
+ (projectile-with-default-dir (projectile-acquire-root)
+ (shell-command command output-buffer error-buffer)))
+
+;;;###autoload
+(defun projectile-run-async-shell-command-in-root (command &optional output-buffer error-buffer)
+ "Invoke `async-shell-command' in the project's root."
+ (interactive (list (read-shell-command "Async shell command: ")))
+ (projectile-with-default-dir (projectile-acquire-root)
+ (async-shell-command command output-buffer error-buffer)))
+
+;;;###autoload
+(defun projectile-run-gdb ()
+ "Invoke `gdb' in the project's root."
+ (interactive)
+ (projectile-with-default-dir (projectile-acquire-root)
+ (call-interactively 'gdb)))
+
+;;;###autoload
+(defun projectile-run-shell (&optional arg)
+ "Invoke `shell' in the project's root.
+
+Switch to the project specific shell buffer if it already exists.
+
+Use a prefix argument ARG to indicate creation of a new process instead."
+ (interactive "P")
+ (let ((project (projectile-acquire-root)))
+ (projectile-with-default-dir project
+ (shell (projectile-generate-process-name "shell" arg project)))))
+
+;;;###autoload
+(defun projectile-run-eshell (&optional arg)
+ "Invoke `eshell' in the project's root.
+
+Switch to the project specific eshell buffer if it already exists.
+
+Use a prefix argument ARG to indicate creation of a new process instead."
+ (interactive "P")
+ (let ((project (projectile-acquire-root)))
+ (projectile-with-default-dir project
+ (let ((eshell-buffer-name (projectile-generate-process-name "eshell" arg project)))
+ (eshell)))))
+
+;;;###autoload
+(defun projectile-run-ielm (&optional arg)
+ "Invoke `ielm' in the project's root.
+
+Switch to the project specific ielm buffer if it already exists.
+
+Use a prefix argument ARG to indicate creation of a new process instead."
+ (interactive "P")
+ (let* ((project (projectile-acquire-root))
+ (ielm-buffer-name (projectile-generate-process-name "ielm" arg project)))
+ (if (get-buffer ielm-buffer-name)
+ (switch-to-buffer ielm-buffer-name)
+ (projectile-with-default-dir project
+ (ielm))
+ ;; ielm's buffer name is hardcoded, so we have to rename it after creation
+ (rename-buffer ielm-buffer-name))))
+
+;;;###autoload
+(defun projectile-run-term (&optional arg)
+ "Invoke `term' in the project's root.
+
+Switch to the project specific term buffer if it already exists.
+
+Use a prefix argument ARG to indicate creation of a new process instead."
+ (interactive "P")
+ (let* ((project (projectile-acquire-root))
+ (buffer-name (projectile-generate-process-name "term" arg project))
+ (default-program (or explicit-shell-file-name
+ (getenv "ESHELL")
+ (getenv "SHELL")
+ "/bin/sh")))
+ (unless (get-buffer buffer-name)
+ (require 'term)
+ (let ((program (read-from-minibuffer "Run program: " default-program)))
+ (projectile-with-default-dir project
+ (set-buffer (term-ansi-make-term buffer-name program))
+ (term-mode)
+ (term-char-mode))))
+ (switch-to-buffer buffer-name)))
+
+;;;###autoload
+(defun projectile-run-vterm (&optional arg)
+ "Invoke `vterm' in the project's root.
+
+Switch to the project specific term buffer if it already exists.
+
+Use a prefix argument ARG to indicate creation of a new process instead."
+ (interactive "P")
+ (let* ((project (projectile-acquire-root))
+ (buffer (projectile-generate-process-name "vterm" arg project)))
+ (unless (buffer-live-p (get-buffer buffer))
+ (unless (require 'vterm nil 'noerror)
+ (error "Package 'vterm' is not available"))
+ (projectile-with-default-dir project
+ (vterm buffer)))
+ (switch-to-buffer buffer)))
+
+(defun projectile-files-in-project-directory (directory)
+ "Return a list of files in DIRECTORY."
+ (let* ((project (projectile-acquire-root))
+ (dir (file-relative-name (expand-file-name directory)
+ project)))
+ (cl-remove-if-not
+ (lambda (f) (string-prefix-p dir f))
+ (projectile-project-files project))))
+
+(defun projectile-files-from-cmd (cmd directory)
+ "Use a grep-like CMD to search for files within DIRECTORY.
+
+CMD should include the necessary search params and should output
+equivalently to grep -HlI (only unique matching filenames).
+Returns a list of expanded filenames."
+ (let ((default-directory directory))
+ (mapcar (lambda (str)
+ (concat directory
+ (if (string-prefix-p "./" str)
+ (substring str 2)
+ str)))
+ (split-string
+ (string-trim (shell-command-to-string cmd))
+ "\n+"
+ t))))
+
+(defvar projectile-files-with-string-commands
+ '((rg . "rg -lF --no-heading --color never -- ")
+ (ag . "ag --literal --nocolor --noheading -l -- ")
+ (ack . "ack --literal --nocolor -l -- ")
+ (git . "git grep -HlI ")
+ ;; -r: recursive
+ ;; -H: show filename for each match
+ ;; -l: show only file names with matches
+ ;; -I: no binary files
+ (grep . "grep -rHlI %s .")))
+
+(defun projectile-files-with-string (string directory)
+ "Return a list of all files containing STRING in DIRECTORY.
+
+Tries to use rg, ag, ack, git-grep, and grep in that order. If those
+are impossible (for instance on Windows), returns a list of all
+files in the project."
+ (if (projectile-unixy-system-p)
+ (let* ((search-term (shell-quote-argument string))
+ (cmd (cond ((executable-find "rg")
+ (concat (cdr (assoc 'rg projectile-files-with-string-commands))
+ search-term))
+ ((executable-find "ag")
+ (concat (cdr (assoc 'ag projectile-files-with-string-commands))
+ search-term))
+ ((executable-find "ack")
+ (concat (cdr (assoc 'ack projectile-files-with-string-commands))
+ search-term))
+ ((and (executable-find "git")
+ (eq (projectile-project-vcs) 'git))
+ (concat (cdr (assoc 'git projectile-files-with-string-commands)) search-term))
+ (t
+ (format (cdr (assoc 'grep projectile-files-with-string-commands)) search-term)))))
+ (projectile-files-from-cmd cmd directory))
+ ;; we have to reject directories as a workaround to work with git submodules
+ (cl-remove-if
+ #'file-directory-p
+ (mapcar #'(lambda (file) (expand-file-name file directory))
+ (projectile-dir-files directory)))))
+
+;;;###autoload
+(defun projectile-replace (&optional arg)
+ "Replace literal string in project using non-regexp `tags-query-replace'.
+
+With a prefix argument ARG prompts you for a directory on which
+to run the replacement."
+ (interactive "P")
+ (let* ((directory (if arg
+ (file-name-as-directory
+ (read-directory-name "Replace in directory: "))
+ (projectile-acquire-root)))
+ (old-text (read-string
+ (projectile-prepend-project-name "Replace: ")
+ (projectile-symbol-or-selection-at-point)))
+ (new-text (read-string
+ (projectile-prepend-project-name
+ (format "Replace %s with: " old-text))))
+ (files (projectile-files-with-string old-text directory)))
+ (if (fboundp #'fileloop-continue)
+ ;; Emacs 27+
+ (progn (fileloop-initialize-replace old-text new-text files 'default)
+ (fileloop-continue))
+ ;; Emacs 25 and 26
+ ;;
+ ;; Adapted from `tags-query-replace' for literal strings (not regexp)
+ (with-no-warnings
+ (setq tags-loop-scan
+ `(let ,(unless (equal old-text (downcase old-text))
+ '((case-fold-search nil)))
+ (if (search-forward ',old-text nil t)
+ ;; When we find a match, move back to
+ ;; the beginning of it so
+ ;; perform-replace will see it.
+ (goto-char (match-beginning 0)))))
+ (setq tags-loop-operate
+ `(perform-replace ',old-text ',new-text t nil nil
+ nil multi-query-replace-map))
+ (tags-loop-continue (or (cons 'list files) t))))))
+
+;;;###autoload
+(defun projectile-replace-regexp (&optional arg)
+ "Replace a regexp in the project using `tags-query-replace'.
+
+With a prefix argument ARG prompts you for a directory on which
+to run the replacement."
+ (interactive "P")
+ (let* ((directory (if arg
+ (file-name-as-directory
+ (read-directory-name "Replace regexp in directory: "))
+ (projectile-acquire-root)))
+ (old-text (read-string
+ (projectile-prepend-project-name "Replace regexp: ")
+ (projectile-symbol-or-selection-at-point)))
+ (new-text (read-string
+ (projectile-prepend-project-name
+ (format "Replace regexp %s with: " old-text))))
+ (files
+ ;; We have to reject directories as a workaround to work with git submodules.
+ ;;
+ ;; We can't narrow the list of files with
+ ;; `projectile-files-with-string' because those regexp tools
+ ;; don't support Emacs regular expressions.
+ (cl-remove-if
+ #'file-directory-p
+ (mapcar #'(lambda (file) (expand-file-name file directory))
+ (projectile-dir-files directory)))))
+ ;; FIXME: Probably would fail on Emacs 27+, fourth argument is gone.
+ (with-no-warnings (tags-query-replace old-text new-text nil (cons 'list files)))))
+
+;;;###autoload
+(defun projectile-kill-buffers ()
+ "Kill project buffers.
+
+The buffer are killed according to the value of
+`projectile-kill-buffers-filter'."
+ (interactive)
+ (let* ((project (projectile-acquire-root))
+ (project-name (projectile-project-name project))
+ (buffers (projectile-project-buffers project)))
+ (when (yes-or-no-p
+ (format "Are you sure you want to kill %s buffers for '%s'? "
+ (length buffers) project-name))
+ (dolist (buffer buffers)
+ (when (and
+ ;; we take care not to kill indirect buffers directly
+ ;; as we might encounter them after their base buffers are killed
+ (not (buffer-base-buffer buffer))
+ (if (functionp projectile-kill-buffers-filter)
+ (funcall projectile-kill-buffers-filter buffer)
+ (pcase projectile-kill-buffers-filter
+ ('kill-all t)
+ ('kill-only-files (buffer-file-name buffer))
+ (_ (user-error "Invalid projectile-kill-buffers-filter value: %S" projectile-kill-buffers-filter)))))
+ (kill-buffer buffer))))))
+
+;;;###autoload
+(defun projectile-save-project-buffers ()
+ "Save all project buffers."
+ (interactive)
+ (let* ((project (projectile-acquire-root))
+ (project-name (projectile-project-name project))
+ (modified-buffers (cl-remove-if-not (lambda (buf)
+ (and (buffer-file-name buf)
+ (buffer-modified-p buf)))
+ (projectile-project-buffers project))))
+ (if (null modified-buffers)
+ (message "[%s] No buffers need saving" project-name)
+ (dolist (buf modified-buffers)
+ (with-current-buffer buf
+ (save-buffer)))
+ (message "[%s] Saved %d buffers" project-name (length modified-buffers)))))
+
+;;;###autoload
+(defun projectile-dired ()
+ "Open `dired' at the root of the project."
+ (interactive)
+ (dired (projectile-acquire-root)))
+
+;;;###autoload
+(defun projectile-dired-other-window ()
+ "Open `dired' at the root of the project in another window."
+ (interactive)
+ (dired-other-window (projectile-acquire-root)))
+
+;;;###autoload
+(defun projectile-dired-other-frame ()
+ "Open `dired' at the root of the project in another frame."
+ (interactive)
+ (dired-other-frame (projectile-acquire-root)))
+
+;;;###autoload
+(defun projectile-vc (&optional project-root)
+ "Open `vc-dir' at the root of the project.
+
+For git projects `magit-status-internal' is used if available.
+For hg projects `monky-status' is used if available.
+
+If PROJECT-ROOT is given, it is opened instead of the project
+root directory of the current buffer file. If interactively
+called with a prefix argument, the user is prompted for a project
+directory to open."
+ (interactive (and current-prefix-arg
+ (list
+ (projectile-completing-read
+ "Open project VC in: "
+ projectile-known-projects))))
+ (unless project-root
+ (setq project-root (projectile-acquire-root)))
+ (let ((vcs (projectile-project-vcs project-root)))
+ (cl-case vcs
+ (git
+ (cond ((fboundp 'magit-status-internal)
+ (magit-status-internal project-root))
+ ((fboundp 'magit-status)
+ (with-no-warnings (magit-status project-root)))
+ (t
+ (vc-dir project-root))))
+ (hg
+ (if (fboundp 'monky-status)
+ (monky-status project-root)
+ (vc-dir project-root)))
+ (t (vc-dir project-root)))))
+
+;;;###autoload
+(defun projectile-recentf ()
+ "Show a list of recently visited files in a project."
+ (interactive)
+ (if (boundp 'recentf-list)
+ (find-file (projectile-expand-root
+ (projectile-completing-read
+ "Recently visited files: "
+ (projectile-recentf-files))))
+ (message "recentf is not enabled")))
+
+(defun projectile-recentf-files ()
+ "Return a list of recently visited files in a project."
+ (and (boundp 'recentf-list)
+ (let ((project-root (projectile-acquire-root)))
+ (mapcar
+ (lambda (f) (file-relative-name f project-root))
+ (cl-remove-if-not
+ (lambda (f) (string-prefix-p project-root (expand-file-name f)))
+ recentf-list)))))
+
+(defun projectile-serialize-cache ()
+ "Serializes the memory cache to the hard drive."
+ (projectile-serialize projectile-projects-cache projectile-cache-file))
+
+(defvar projectile-configure-cmd-map
+ (make-hash-table :test 'equal)
+ "A mapping between projects and the last configure command used on them.")
+
+(defvar projectile-compilation-cmd-map
+ (make-hash-table :test 'equal)
+ "A mapping between projects and the last compilation command used on them.")
+
+(defvar projectile-install-cmd-map
+ (make-hash-table :test 'equal)
+ "A mapping between projects and the last install command used on them.")
+
+(defvar projectile-package-cmd-map
+ (make-hash-table :test 'equal)
+ "A mapping between projects and the last package command used on them.")
+
+(defvar projectile-test-cmd-map
+ (make-hash-table :test 'equal)
+ "A mapping between projects and the last test command used on them.")
+
+(defvar projectile-run-cmd-map
+ (make-hash-table :test 'equal)
+ "A mapping between projects and the last run command used on them.")
+
+(defvar projectile-project-configure-cmd nil
+ "The command to use with `projectile-configure-project'.
+It takes precedence over the default command for the project type when set.
+Should be set via .dir-locals.el.")
+
+(defvar projectile-project-compilation-cmd nil
+ "The command to use with `projectile-compile-project'.
+It takes precedence over the default command for the project type when set.
+Should be set via .dir-locals.el.")
+
+(defvar projectile-project-compilation-dir nil
+ "The directory to use with `projectile-compile-project'.
+The directory path is relative to the project root.
+Should be set via .dir-locals.el.")
+
+(defvar projectile-project-test-cmd nil
+ "The command to use with `projectile-test-project'.
+It takes precedence over the default command for the project type when set.
+Should be set via .dir-locals.el.")
+
+(defvar projectile-project-install-cmd nil
+ "The command to use with `projectile-install-project'.
+It takes precedence over the default command for the project type when set.
+Should be set via .dir-locals.el.")
+
+(defvar projectile-project-package-cmd nil
+ "The command to use with `projectile-package-project'.
+It takes precedence over the default command for the project type when set.
+Should be set via .dir-locals.el.")
+
+(defvar projectile-project-run-cmd nil
+ "The command to use with `projectile-run-project'.
+It takes precedence over the default command for the project type when set.
+Should be set via .dir-locals.el.")
+
+(defun projectile-default-generic-command (project-type command-type)
+ "Generic retrieval of COMMAND-TYPEs default cmd-value for PROJECT-TYPE.
+
+If found, checks if value is symbol or string. In case of symbol
+resolves to function `funcall's. Return value of function MUST
+be string to be executed as command."
+ (let ((command (plist-get (alist-get project-type projectile-project-types) command-type)))
+ (cond
+ ((not command) nil)
+ ((stringp command) command)
+ ((functionp command)
+ (if (fboundp command)
+ (funcall (symbol-function command))))
+ (t
+ (error "The value for: %s in project-type: %s was neither a function nor a string" command-type project-type)))))
+
+(defun projectile-default-configure-command (project-type)
+ "Retrieve default configure command for PROJECT-TYPE."
+ (projectile-default-generic-command project-type 'configure-command))
+
+(defun projectile-default-compilation-command (project-type)
+ "Retrieve default compilation command for PROJECT-TYPE."
+ (projectile-default-generic-command project-type 'compile-command))
+
+(defun projectile-default-compilation-dir (project-type)
+ "Retrieve default compilation directory for PROJECT-TYPE."
+ (projectile-default-generic-command project-type 'compilation-dir))
+
+(defun projectile-default-test-command (project-type)
+ "Retrieve default test command for PROJECT-TYPE."
+ (projectile-default-generic-command project-type 'test-command))
+
+(defun projectile-default-install-command (project-type)
+ "Retrieve default install command for PROJECT-TYPE."
+ (projectile-default-generic-command project-type 'install-command))
+
+(defun projectile-default-package-command (project-type)
+ "Retrieve default package command for PROJECT-TYPE."
+ (projectile-default-generic-command project-type 'package-command))
+
+(defun projectile-default-run-command (project-type)
+ "Retrieve default run command for PROJECT-TYPE."
+ (projectile-default-generic-command project-type 'run-command))
+
+(defun projectile-configure-command (compile-dir)
+ "Retrieve the configure command for COMPILE-DIR.
+
+The command is determined like this:
+
+- first we check `projectile-configure-cmd-map' for the last
+configure command that was invoked on the project
+
+- then we check for `projectile-project-configure-cmd' supplied
+via .dir-locals.el
+
+- finally we check for the default configure command for a
+project of that type"
+ (or (gethash compile-dir projectile-configure-cmd-map)
+ projectile-project-configure-cmd
+ (let ((cmd-format-string (projectile-default-configure-command (projectile-project-type))))
+ (when cmd-format-string
+ (format cmd-format-string (projectile-project-root) compile-dir)))))
+
+(defun projectile-compilation-buffer-name (compilation-mode)
+ "Meant to be used for `compilation-buffer-name-function`.
+Argument COMPILATION-MODE is the name of the major mode used for the
+compilation buffer."
+ (concat "*" (downcase compilation-mode) "*"
+ (if (projectile-project-p) (concat "<" (projectile-project-name) ">") "")))
+
+(defun projectile-current-project-buffer-p ()
+ "Meant to be used for `compilation-save-buffers-predicate`.
+This indicates whether the current buffer is in the same project as the current
+window (including returning true if neither is in a project)."
+ (let ((root (with-current-buffer (window-buffer) (projectile-project-root))))
+ (or (not root)
+ (projectile-project-buffer-p (current-buffer) root))))
+
+(defun projectile-compilation-command (compile-dir)
+ "Retrieve the compilation command for COMPILE-DIR.
+
+The command is determined like this:
+
+- first we check `projectile-compilation-cmd-map' for the last
+compile command that was invoked on the project
+
+- then we check for `projectile-project-compilation-cmd' supplied
+via .dir-locals.el
+
+- finally we check for the default compilation command for a
+project of that type"
+ (or (gethash compile-dir projectile-compilation-cmd-map)
+ projectile-project-compilation-cmd
+ (projectile-default-compilation-command (projectile-project-type))))
+
+(defun projectile-test-command (compile-dir)
+ "Retrieve the test command for COMPILE-DIR.
+
+The command is determined like this:
+
+- first we check `projectile-test-cmd-map' for the last
+test command that was invoked on the project
+
+- then we check for `projectile-project-test-cmd' supplied
+via .dir-locals.el
+
+- finally we check for the default test command for a
+project of that type"
+ (or (gethash compile-dir projectile-test-cmd-map)
+ projectile-project-test-cmd
+ (projectile-default-test-command (projectile-project-type))))
+
+(defun projectile-install-command (compile-dir)
+ "Retrieve the install command for COMPILE-DIR.
+
+The command is determined like this:
+
+- first we check `projectile-install-cmd-map' for the last
+install command that was invoked on the project
+
+- then we check for `projectile-project-install-cmd' supplied
+via .dir-locals.el
+
+- finally we check for the default install command for a
+project of that type"
+ (or (gethash compile-dir projectile-install-cmd-map)
+ projectile-project-install-cmd
+ (projectile-default-install-command (projectile-project-type))))
+
+(defun projectile-package-command (compile-dir)
+ "Retrieve the package command for COMPILE-DIR.
+
+The command is determined like this:
+
+- first we check `projectile-packgage-cmd-map' for the last
+install command that was invoked on the project
+
+- then we check for `projectile-project-package-cmd' supplied
+via .dir-locals.el
+
+- finally we check for the default package command for a
+project of that type"
+ (or (gethash compile-dir projectile-package-cmd-map)
+ projectile-project-package-cmd
+ (projectile-default-package-command (projectile-project-type))))
+
+(defun projectile-run-command (compile-dir)
+ "Retrieve the run command for COMPILE-DIR.
+
+The command is determined like this:
+
+- first we check `projectile-run-cmd-map' for the last
+run command that was invoked on the project
+
+- then we check for `projectile-project-run-cmd' supplied
+via .dir-locals.el
+
+- finally we check for the default run command for a
+project of that type"
+ (or (gethash compile-dir projectile-run-cmd-map)
+ projectile-project-run-cmd
+ (projectile-default-run-command (projectile-project-type))))
+
+(defun projectile-read-command (prompt command)
+ "Adapted from the function `compilation-read-command'."
+ (let ((compile-history
+ ;; fetch the command history for the current project
+ (ring-elements (projectile--get-command-history (projectile-acquire-root)))))
+ (read-shell-command prompt command
+ (if (equal (car compile-history) command)
+ '(compile-history . 1)
+ 'compile-history))))
+
+(defun projectile-compilation-dir ()
+ "Retrieve the compilation directory for this project."
+ (let* ((type (projectile-project-type))
+ (directory (or projectile-project-compilation-dir
+ (projectile-default-compilation-dir type))))
+ (if directory
+ (file-truename
+ (concat (file-name-as-directory (projectile-project-root))
+ (file-name-as-directory directory)))
+ (projectile-project-root))))
+
+(defun projectile-maybe-read-command (arg default-cmd prompt)
+ "Prompt user for command unless DEFAULT-CMD is an Elisp function."
+ (if (and (or (stringp default-cmd) (null default-cmd))
+ (or compilation-read-command arg))
+ (projectile-read-command prompt default-cmd)
+ default-cmd))
+
+(defun projectile-run-compilation (cmd &optional use-comint-mode)
+ "Run external or Elisp compilation command CMD."
+ (if (functionp cmd)
+ (funcall cmd)
+ (compile cmd use-comint-mode)))
+
+(defvar projectile-project-command-history (make-hash-table :test 'equal)
+ "The history of last executed project commands, per project.
+
+Projects are indexed by their project-root value.")
+
+(defun projectile--get-command-history (project-root)
+ (or (gethash project-root projectile-project-command-history)
+ (puthash project-root
+ (make-ring 16)
+ projectile-project-command-history)))
+
+(cl-defun projectile--run-project-cmd
+ (command command-map &key show-prompt prompt-prefix save-buffers use-comint-mode)
+ "Run a project COMMAND, typically a test- or compile command.
+
+Cache the COMMAND for later use inside the hash-table COMMAND-MAP.
+
+Normally you'll be prompted for a compilation command, unless
+variable `compilation-read-command'. You can force the prompt
+by setting SHOW-PROMPT. The prompt will be prefixed with PROMPT-PREFIX.
+
+If SAVE-BUFFERS is non-nil save all projectile buffers before
+running the command.
+
+The command actually run is returned."
+ (let* ((project-root (projectile-project-root))
+ (default-directory (projectile-compilation-dir))
+ (command (projectile-maybe-read-command show-prompt
+ command
+ prompt-prefix))
+ compilation-buffer-name-function
+ compilation-save-buffers-predicate)
+ (when command-map
+ (puthash default-directory command command-map)
+ (ring-insert (projectile--get-command-history project-root) command))
+ (when save-buffers
+ (save-some-buffers (not compilation-ask-about-save)
+ (lambda ()
+ (projectile-project-buffer-p (current-buffer)
+ project-root))))
+ (when projectile-per-project-compilation-buffer
+ (setq compilation-buffer-name-function #'projectile-compilation-buffer-name)
+ (setq compilation-save-buffers-predicate #'projectile-current-project-buffer-p))
+ (unless (file-directory-p default-directory)
+ (mkdir default-directory))
+ (projectile-run-compilation command use-comint-mode)
+ command))
+
+(defcustom projectile-configure-use-comint-mode nil
+ "Make the output buffer of `projectile-configure-project' interactive."
+ :group 'projectile
+ :type 'boolean
+ :package-version '(projectile . "2.5.0"))
+
+(defcustom projectile-compile-use-comint-mode nil
+ "Make the output buffer of `projectile-compile-project' interactive."
+ :group 'projectile
+ :type 'boolean
+ :package-version '(projectile . "2.5.0"))
+
+(defcustom projectile-test-use-comint-mode nil
+ "Make the output buffer of `projectile-test-project' interactive."
+ :group 'projectile
+ :type 'boolean
+ :package-version '(projectile . "2.5.0"))
+
+(defcustom projectile-install-use-comint-mode nil
+ "Make the output buffer of `projectile-install-project' interactive."
+ :group 'projectile
+ :type 'boolean
+ :package-version '(projectile . "2.5.0"))
+
+(defcustom projectile-package-use-comint-mode nil
+ "Make the output buffer of `projectile-package-project' interactive."
+ :group 'projectile
+ :type 'boolean
+ :package-version '(projectile . "2.5.0"))
+
+(defcustom projectile-run-use-comint-mode nil
+ "Make the output buffer of `projectile-run-project' interactive."
+ :group 'projectile
+ :type 'boolean
+ :package-version '(projectile . "2.5.0"))
+
+;;;###autoload
+(defun projectile-configure-project (arg)
+ "Run project configure command.
+
+Normally you'll be prompted for a compilation command, unless
+variable `compilation-read-command'. You can force the prompt
+with a prefix ARG."
+ (interactive "P")
+ (let ((command (projectile-configure-command (projectile-compilation-dir))))
+ (projectile--run-project-cmd command projectile-configure-cmd-map
+ :show-prompt arg
+ :prompt-prefix "Configure command: "
+ :save-buffers t
+ :use-comint-mode projectile-configure-use-comint-mode)))
+
+;;;###autoload
+(defun projectile-compile-project (arg)
+ "Run project compilation command.
+
+Normally you'll be prompted for a compilation command, unless
+variable `compilation-read-command'. You can force the prompt
+with a prefix ARG."
+ (interactive "P")
+ (let ((command (projectile-compilation-command (projectile-compilation-dir))))
+ (projectile--run-project-cmd command projectile-compilation-cmd-map
+ :show-prompt arg
+ :prompt-prefix "Compile command: "
+ :save-buffers t
+ :use-comint-mode projectile-compile-use-comint-mode)))
+
+;;;###autoload
+(defun projectile-test-project (arg)
+ "Run project test command.
+
+Normally you'll be prompted for a compilation command, unless
+variable `compilation-read-command'. You can force the prompt
+with a prefix ARG."
+ (interactive "P")
+ (let ((command (projectile-test-command (projectile-compilation-dir))))
+ (projectile--run-project-cmd command projectile-test-cmd-map
+ :show-prompt arg
+ :prompt-prefix "Test command: "
+ :save-buffers t
+ :use-comint-mode projectile-test-use-comint-mode)))
+
+;;;###autoload
+(defun projectile-install-project (arg)
+ "Run project install command.
+
+Normally you'll be prompted for a compilation command, unless
+variable `compilation-read-command'. You can force the prompt
+with a prefix ARG."
+ (interactive "P")
+ (let ((command (projectile-install-command (projectile-compilation-dir))))
+ (projectile--run-project-cmd command projectile-install-cmd-map
+ :show-prompt arg
+ :prompt-prefix "Install command: "
+ :save-buffers t
+ :use-comint-mode projectile-install-use-comint-mode)))
+
+;;;###autoload
+(defun projectile-package-project (arg)
+ "Run project package command.
+
+Normally you'll be prompted for a compilation command, unless
+variable `compilation-read-command'. You can force the prompt
+with a prefix ARG."
+ (interactive "P")
+ (let ((command (projectile-package-command (projectile-compilation-dir))))
+ (projectile--run-project-cmd command projectile-package-cmd-map
+ :show-prompt arg
+ :prompt-prefix "Package command: "
+ :save-buffers t
+ :use-comint-mode projectile-package-use-comint-mode)))
+
+;;;###autoload
+(defun projectile-run-project (arg)
+ "Run project run command.
+
+Normally you'll be prompted for a compilation command, unless
+variable `compilation-read-command'. You can force the prompt
+with a prefix ARG."
+ (interactive "P")
+ (let ((command (projectile-run-command (projectile-compilation-dir))))
+ (projectile--run-project-cmd command projectile-run-cmd-map
+ :show-prompt arg
+ :prompt-prefix "Run command: "
+ :use-comint-mode projectile-run-use-comint-mode)))
+
+;;;###autoload
+(defun projectile-repeat-last-command (show-prompt)
+ "Run last projectile external command.
+
+External commands are: `projectile-configure-project',
+`projectile-compile-project', `projectile-test-project',
+`projectile-install-project', `projectile-package-project',
+and `projectile-run-project'.
+
+If the prefix argument SHOW_PROMPT is non nil, the command can be edited."
+ (interactive "P")
+ (let* ((project-root (projectile-acquire-root))
+ (command-history (projectile--get-command-history project-root))
+ (command (car-safe (ring-elements command-history)))
+ (compilation-read-command show-prompt)
+ executed-command)
+ (unless command
+ (user-error "No command has been run yet for this project"))
+ (setq executed-command
+ (projectile--run-project-cmd command
+ nil
+ :save-buffers t
+ :prompt-prefix "Execute command: "))
+ (unless (string= command executed-command)
+ (ring-insert command-history executed-command))))
+
+(defun compilation-find-file-projectile-find-compilation-buffer (orig-fun marker filename directory &rest formats)
+ "Advice around compilation-find-file.
+We enhance its functionality by appending the current project's directories
+to its search path. This way when filenames in compilation buffers can't be
+found by compilation's normal logic they are searched for in project
+directories."
+ (let* ((root (projectile-project-root))
+ (compilation-search-path
+ (if (projectile-project-p)
+ (append compilation-search-path (list root)
+ (mapcar (lambda (f) (expand-file-name f root))
+ (projectile-current-project-dirs)))
+ compilation-search-path)))
+ (apply orig-fun `(,marker ,filename ,directory ,@formats))))
+
+(defun projectile-open-projects ()
+ "Return a list of all open projects.
+An open project is a project with any open buffers."
+ (delete-dups
+ (delq nil
+ (mapcar (lambda (buffer)
+ (with-current-buffer buffer
+ (when (projectile-project-p)
+ (abbreviate-file-name (projectile-project-root)))))
+ (buffer-list)))))
+
+(defun projectile--remove-current-project (projects)
+ "Remove the current project (if any) from the list of PROJECTS."
+ (if-let ((project (projectile-project-root)))
+ (projectile-difference projects
+ (list (abbreviate-file-name project)))
+ projects))
+
+(defun projectile--move-current-project-to-end (projects)
+ "Move current project (if any) to the end of list in the list of PROJECTS."
+ (if-let ((project (projectile-project-root)))
+ (append
+ (projectile--remove-current-project projects)
+ (list (abbreviate-file-name project)))
+ projects))
+
+(defun projectile-relevant-known-projects ()
+ "Return a list of known projects."
+ (pcase projectile-current-project-on-switch
+ ('remove (projectile--remove-current-project projectile-known-projects))
+ ('move-to-end (projectile--move-current-project-to-end projectile-known-projects))
+ ('keep projectile-known-projects)))
+
+(defun projectile-relevant-open-projects ()
+ "Return a list of open projects."
+ (let ((open-projects (projectile-open-projects)))
+ (pcase projectile-current-project-on-switch
+ ('remove (projectile--remove-current-project open-projects))
+ ('move-to-end (projectile--move-current-project-to-end open-projects))
+ ('keep open-projects))))
+
+;;;###autoload
+(defun projectile-switch-project (&optional arg)
+ "Switch to a project we have visited before.
+Invokes the command referenced by `projectile-switch-project-action' on switch.
+With a prefix ARG invokes `projectile-commander' instead of
+`projectile-switch-project-action.'"
+ (interactive "P")
+ (let ((projects (projectile-relevant-known-projects)))
+ (if projects
+ (projectile-completing-read
+ "Switch to project: " projects
+ :action (lambda (project)
+ (projectile-switch-project-by-name project arg)))
+ (user-error "There are no known projects"))))
+
+;;;###autoload
+(defun projectile-switch-open-project (&optional arg)
+ "Switch to a project we have currently opened.
+Invokes the command referenced by `projectile-switch-project-action' on switch.
+With a prefix ARG invokes `projectile-commander' instead of
+`projectile-switch-project-action.'"
+ (interactive "P")
+ (let ((projects (projectile-relevant-open-projects)))
+ (if projects
+ (projectile-completing-read
+ "Switch to open project: " projects
+ :action (lambda (project)
+ (projectile-switch-project-by-name project arg)))
+ (user-error "There are no open projects"))))
+
+(defun projectile-switch-project-by-name (project-to-switch &optional arg)
+ "Switch to project by project name PROJECT-TO-SWITCH.
+Invokes the command referenced by `projectile-switch-project-action' on switch.
+With a prefix ARG invokes `projectile-commander' instead of
+`projectile-switch-project-action.'"
+ ;; let's make sure that the target directory exists and is actually a project
+ ;; we ignore remote folders, as the check breaks for TRAMP unless already connected
+ (unless (or (file-remote-p project-to-switch) (projectile-project-p project-to-switch))
+ (projectile-remove-known-project project-to-switch)
+ (error "Directory %s is not a project" project-to-switch))
+ (let ((switch-project-action (if arg
+ 'projectile-commander
+ projectile-switch-project-action)))
+ (run-hooks 'projectile-before-switch-project-hook)
+ (let* ((default-directory project-to-switch)
+ (switched-buffer
+ ;; use a temporary buffer to load PROJECT-TO-SWITCH's dir-locals
+ ;; before calling SWITCH-PROJECT-ACTION
+ (with-temp-buffer
+ (hack-dir-local-variables-non-file-buffer)
+ ;; Normally the project name is determined from the current
+ ;; buffer. However, when we're switching projects, we want to
+ ;; show the name of the project being switched to, rather than
+ ;; the current project, in the minibuffer. This is a simple hack
+ ;; to tell the `projectile-project-name' function to ignore the
+ ;; current buffer and the caching mechanism, and just return the
+ ;; value of the `projectile-project-name' variable.
+ (let ((projectile-project-name (funcall projectile-project-name-function
+ project-to-switch)))
+ (funcall switch-project-action)
+ (current-buffer)))))
+ ;; If switch-project-action switched buffers then with-temp-buffer will
+ ;; have lost that change, so switch back to the correct buffer.
+ (when (buffer-live-p switched-buffer)
+ (switch-to-buffer switched-buffer)))
+ (run-hooks 'projectile-after-switch-project-hook)))
+
+;;;###autoload
+(defun projectile-find-file-in-directory (&optional directory)
+ "Jump to a file in a (maybe regular) DIRECTORY.
+
+This command will first prompt for the directory the file is in."
+ (interactive "DFind file in directory: ")
+ (unless (projectile--directory-p directory)
+ (user-error "Directory %S does not exist" directory))
+ (let ((default-directory directory))
+ (if (projectile-project-p)
+ ;; target directory is in a project
+ (let ((file (projectile-completing-read "Find file: "
+ (projectile-dir-files directory))))
+ (find-file (expand-file-name file directory))
+ (run-hooks 'projectile-find-file-hook))
+ ;; target directory is not in a project
+ (projectile-find-file))))
+
+(defun projectile-all-project-files ()
+ "Get a list of all files in all projects."
+ (cl-mapcan
+ (lambda (project)
+ (when (file-exists-p project)
+ (mapcar (lambda (file)
+ (expand-file-name file project))
+ (projectile-project-files project))))
+ projectile-known-projects))
+
+;;;###autoload
+(defun projectile-find-file-in-known-projects ()
+ "Jump to a file in any of the known projects."
+ (interactive)
+ (find-file (projectile-completing-read "Find file in projects: " (projectile-all-project-files))))
+
+(defun projectile-keep-project-p (project)
+ "Determine whether we should cleanup (remove) PROJECT or not.
+
+It handles the case of remote projects as well.
+See `projectile--cleanup-known-projects'."
+ ;; Taken from from `recentf-keep-default-predicate'
+ (cond
+ ((file-remote-p project nil t) (file-readable-p project))
+ ((file-remote-p project))
+ ((file-readable-p project))))
+
+(defun projectile--cleanup-known-projects ()
+ "Remove known projects that don't exist anymore.
+Return a list of projects removed."
+ (projectile-merge-known-projects)
+ (let ((projects-kept (cl-remove-if-not #'projectile-keep-project-p projectile-known-projects))
+ (projects-removed (cl-remove-if #'projectile-keep-project-p projectile-known-projects)))
+ (setq projectile-known-projects projects-kept)
+ (projectile-merge-known-projects)
+ projects-removed))
+
+;;;###autoload
+(defun projectile-cleanup-known-projects ()
+ "Remove known projects that don't exist anymore."
+ (interactive)
+ (if-let ((projects-removed (projectile--cleanup-known-projects)))
+ (message "Projects removed: %s"
+ (mapconcat #'identity projects-removed ", "))
+ (message "No projects needed to be removed.")))
+
+;;;###autoload
+(defun projectile-clear-known-projects ()
+ "Clear both `projectile-known-projects' and `projectile-known-projects-file'."
+ (interactive)
+ (setq projectile-known-projects nil)
+ (projectile-save-known-projects))
+
+;;;###autoload
+(defun projectile-reset-known-projects ()
+ "Clear known projects and rediscover."
+ (interactive)
+ (projectile-clear-known-projects)
+ (projectile-discover-projects-in-search-path))
+
+;;;###autoload
+(defun projectile-remove-known-project (&optional project)
+ "Remove PROJECT from the list of known projects."
+ (interactive (list (projectile-completing-read
+ "Remove from known projects: " projectile-known-projects
+ :action 'projectile-remove-known-project)))
+ (unless (called-interactively-p 'any)
+ (setq projectile-known-projects
+ (cl-remove-if
+ (lambda (proj) (string= project proj))
+ projectile-known-projects))
+ (projectile-merge-known-projects)
+ (when projectile-verbose
+ (message "Project %s removed from the list of known projects." project))))
+
+;;;###autoload
+(defun projectile-remove-current-project-from-known-projects ()
+ "Remove the current project from the list of known projects."
+ (interactive)
+ (projectile-remove-known-project (abbreviate-file-name (projectile-acquire-root))))
+
+(defun projectile-ignored-projects ()
+ "A list of projects that should not be save in `projectile-known-projects'."
+ (mapcar #'file-truename projectile-ignored-projects))
+
+(defun projectile-ignored-project-p (project-root)
+ "Return t if PROJECT-ROOT should not be added to `projectile-known-projects'."
+ (or (member project-root (projectile-ignored-projects))
+ (and (functionp projectile-ignored-project-function)
+ (funcall projectile-ignored-project-function project-root))))
+
+;;;###autoload
+(defun projectile-add-known-project (project-root)
+ "Add PROJECT-ROOT to the list of known projects."
+ (interactive (list (read-directory-name "Add to known projects: ")))
+ (unless (projectile-ignored-project-p project-root)
+ (push (file-name-as-directory (abbreviate-file-name project-root)) projectile-known-projects)
+ (delete-dups projectile-known-projects)
+ (projectile-merge-known-projects)))
+
+(defun projectile-load-known-projects ()
+ "Load saved projects from `projectile-known-projects-file'.
+Also set `projectile-known-projects'."
+ (setq projectile-known-projects
+ (projectile-unserialize projectile-known-projects-file))
+ (setq projectile-known-projects-on-file
+ (and (sequencep projectile-known-projects)
+ (copy-sequence projectile-known-projects))))
+
+(defun projectile-save-known-projects ()
+ "Save PROJECTILE-KNOWN-PROJECTS to PROJECTILE-KNOWN-PROJECTS-FILE."
+ (projectile-serialize projectile-known-projects
+ projectile-known-projects-file)
+ (setq projectile-known-projects-on-file
+ (and (sequencep projectile-known-projects)
+ (copy-sequence projectile-known-projects))))
+
+(defun projectile-merge-known-projects ()
+ "Merge any change from `projectile-known-projects-file' and save to disk.
+
+This enables multiple Emacs processes to make changes without
+overwriting each other's changes."
+ (let* ((known-now projectile-known-projects)
+ (known-on-last-sync projectile-known-projects-on-file)
+ (known-on-file
+ (projectile-unserialize projectile-known-projects-file))
+ (removed-after-sync (projectile-difference known-on-last-sync known-now))
+ (removed-in-other-process
+ (projectile-difference known-on-last-sync known-on-file))
+ (result (delete-dups
+ (projectile-difference
+ (append known-now known-on-file)
+ (append removed-after-sync removed-in-other-process)))))
+ (setq projectile-known-projects result)
+ (projectile-save-known-projects)))
+
+
+;;; IBuffer integration
+(define-ibuffer-filter projectile-files
+ "Show Ibuffer with all buffers in the current project."
+ (:reader (read-directory-name "Project root: " (projectile-project-root))
+ :description nil)
+ (with-current-buffer buf
+ (let ((directory (file-name-as-directory (expand-file-name qualifier))))
+ (and (projectile-project-buffer-p buf directory)
+ (equal directory
+ (projectile-project-root))))))
+
+(defun projectile-ibuffer-by-project (project-root)
+ "Open an IBuffer window showing all buffers in PROJECT-ROOT."
+ (let ((project-name (funcall projectile-project-name-function project-root)))
+ (ibuffer nil (format "*%s Buffers*" project-name)
+ (list (cons 'projectile-files project-root)))))
+
+;;;###autoload
+(defun projectile-ibuffer (prompt-for-project)
+ "Open an IBuffer window showing all buffers in the current project.
+
+Let user choose another project when PROMPT-FOR-PROJECT is supplied."
+ (interactive "P")
+ (let ((project-root (if prompt-for-project
+ (projectile-completing-read
+ "Project name: "
+ (projectile-relevant-known-projects))
+ (projectile-acquire-root))))
+ (projectile-ibuffer-by-project project-root)))
+
+
+;;;; projectile-commander
+
+(defconst projectile-commander-help-buffer "*Projectile Commander Help*")
+
+(defvar projectile-commander-methods nil
+ "List of file-selection methods for the `projectile-commander' command.
+Each element is a list (KEY DESCRIPTION FUNCTION).
+DESCRIPTION is a one-line description of what the key selects.")
+
+;;;###autoload
+(defun projectile-commander ()
+ "Execute a Projectile command with a single letter.
+The user is prompted for a single character indicating the action to invoke.
+The `?' character describes then
+available actions.
+
+See `def-projectile-commander-method' for defining new methods."
+ (interactive)
+ (let* ((choices (mapcar #'car projectile-commander-methods))
+ (prompt (concat "Select Projectile command [" choices "]: "))
+ (ch (read-char-choice prompt choices))
+ (fn (nth 2 (assq ch projectile-commander-methods))))
+ (funcall fn)))
+
+(defmacro def-projectile-commander-method (key description &rest body)
+ "Define a new `projectile-commander' method.
+
+KEY is the key the user will enter to choose this method.
+
+DESCRIPTION is a one-line sentence describing how the method.
+
+BODY is a series of forms which are evaluated when the find
+is chosen."
+ (let ((method `(lambda ()
+ ,@body)))
+ `(setq projectile-commander-methods
+ (cl-sort (copy-sequence
+ (cons (list ,key ,description ,method)
+ (assq-delete-all ,key projectile-commander-methods)))
+ (lambda (a b) (< (car a) (car b)))))))
+
+(def-projectile-commander-method ?? "Commander help buffer."
+ (ignore-errors (kill-buffer projectile-commander-help-buffer))
+ (with-current-buffer (get-buffer-create projectile-commander-help-buffer)
+ (insert "Projectile Commander Methods:\n\n")
+ (dolist (met projectile-commander-methods)
+ (insert (format "%c:\t%s\n" (car met) (cadr met))))
+ (goto-char (point-min))
+ (help-mode)
+ (display-buffer (current-buffer) t))
+ (projectile-commander))
+
+(defun projectile-commander-bindings ()
+ "Setup the keybindings for the Projectile Commander."
+ (def-projectile-commander-method ?f
+ "Find file in project."
+ (projectile-find-file))
+
+ (def-projectile-commander-method ?T
+ "Find test file in project."
+ (projectile-find-test-file))
+
+ (def-projectile-commander-method ?b
+ "Switch to project buffer."
+ (projectile-switch-to-buffer))
+
+ (def-projectile-commander-method ?d
+ "Find directory in project."
+ (projectile-find-dir))
+
+ (def-projectile-commander-method ?D
+ "Open project root in dired."
+ (projectile-dired))
+
+ (def-projectile-commander-method ?v
+ "Open project root in vc-dir or magit."
+ (projectile-vc))
+
+ (def-projectile-commander-method ?V
+ "Browse dirty projects"
+ (projectile-browse-dirty-projects))
+
+ (def-projectile-commander-method ?r
+ "Replace a string in the project."
+ (projectile-replace))
+
+ (def-projectile-commander-method ?R
+ "Regenerate the project's [e|g]tags."
+ (projectile-regenerate-tags))
+
+ (def-projectile-commander-method ?g
+ "Run grep on project."
+ (projectile-grep))
+
+ (def-projectile-commander-method ?a
+ "Run ag on project."
+ (call-interactively #'projectile-ag))
+
+ (def-projectile-commander-method ?s
+ "Switch project."
+ (projectile-switch-project))
+
+ (def-projectile-commander-method ?o
+ "Run multi-occur on project buffers."
+ (projectile-multi-occur))
+
+ (def-projectile-commander-method ?j
+ "Find tag in project."
+ (projectile-find-tag))
+
+ (def-projectile-commander-method ?k
+ "Kill all project buffers."
+ (projectile-kill-buffers))
+
+ (def-projectile-commander-method ?e
+ "Find recently visited file in project."
+ (projectile-recentf)))
+
+
+;;; Dirty (modified) project check related functionality
+(defun projectile-check-vcs-status (&optional project-path)
+ "Check the status of the current project.
+If PROJECT-PATH is a project, check this one instead."
+ (let ((project-path (or project-path (projectile-acquire-root)))
+ (project-status nil))
+ (save-excursion
+ (vc-dir project-path)
+ ;; wait until vc-dir is done
+ (while (vc-dir-busy) (sleep-for 0 100))
+ ;; check for status
+ (save-excursion
+ (save-match-data
+ (dolist (check projectile-vcs-dirty-state)
+ (goto-char (point-min))
+ (when (search-forward check nil t)
+ (setq project-status (cons check project-status))))))
+ (kill-buffer)
+ project-status)))
+
+(defvar projectile-cached-dirty-projects-status nil
+ "Cache of the last dirty projects check.")
+
+(defun projectile-check-vcs-status-of-known-projects ()
+ "Return the list of dirty projects.
+The list is composed of sublists~: (project-path, project-status).
+Raise an error if their is no dirty project."
+ (save-window-excursion
+ (message "Checking for modifications in known projects...")
+ (let ((projects projectile-known-projects)
+ (status ()))
+ (dolist (project projects)
+ (when (and (projectile-keep-project-p project) (not (string= 'none (projectile-project-vcs project))))
+ (let ((tmp-status (projectile-check-vcs-status project)))
+ (when tmp-status
+ (setq status (cons (list project tmp-status) status))))))
+ (when (= (length status) 0)
+ (message "No dirty projects have been found"))
+ (setq projectile-cached-dirty-projects-status status)
+ status)))
+
+;;;###autoload
+(defun projectile-browse-dirty-projects (&optional cached)
+ "Browse dirty version controlled projects.
+
+With a prefix argument, or if CACHED is non-nil, try to use the cached
+dirty project list."
+ (interactive "P")
+ (let ((status (if (and cached projectile-cached-dirty-projects-status)
+ projectile-cached-dirty-projects-status
+ (projectile-check-vcs-status-of-known-projects)))
+ (mod-proj nil))
+ (while (not (= (length status) 0))
+ (setq mod-proj (cons (car (pop status)) mod-proj)))
+ (projectile-completing-read "Select project: " mod-proj
+ :action 'projectile-vc)))
+
+
+;;; Find next/previous project buffer
+(defun projectile--repeat-until-project-buffer (orig-fun &rest args)
+ "Repeat ORIG-FUN with ARGS until the current buffer is a project buffer."
+ (if (projectile-project-root)
+ (let* ((other-project-buffers (make-hash-table :test 'eq))
+ (projectile-project-buffers (projectile-project-buffers))
+ (max-iterations (length (buffer-list)))
+ (counter 0))
+ (dolist (buffer projectile-project-buffers)
+ (unless (eq buffer (current-buffer))
+ (puthash buffer t other-project-buffers)))
+ (when (cdr-safe projectile-project-buffers)
+ (while (and (< counter max-iterations)
+ (not (gethash (current-buffer) other-project-buffers)))
+ (apply orig-fun args)
+ (cl-incf counter))))
+ (apply orig-fun args)))
+
+(defun projectile-next-project-buffer ()
+ "In selected window switch to the next project buffer.
+
+If the current buffer does not belong to a project, call `next-buffer'."
+ (interactive)
+ (projectile--repeat-until-project-buffer #'next-buffer))
+
+(defun projectile-previous-project-buffer ()
+ "In selected window switch to the previous project buffer.
+
+If the current buffer does not belong to a project, call `previous-buffer'."
+ (interactive)
+ (projectile--repeat-until-project-buffer #'previous-buffer))
+
+
+;;; Editing a project's .dir-locals
+(defun projectile-read-variable ()
+ "Prompt for a variable and return its name."
+ (completing-read "Variable: "
+ obarray
+ (lambda (v)
+ (and (boundp v) (not (keywordp v))))
+ t))
+
+(define-skeleton projectile-skel-variable-cons
+ "Insert a variable-name and a value in a cons-cell."
+ "Value: "
+ "("
+ (projectile-read-variable)
+ " . "
+ str
+ ")")
+
+(define-skeleton projectile-skel-dir-locals
+ "Insert a .dir-locals.el template."
+ nil
+ "((nil . ("
+ ("" '(projectile-skel-variable-cons) \n)
+ resume:
+ ")))")
+
+;;;###autoload
+(defun projectile-edit-dir-locals ()
+ "Edit or create a .dir-locals.el file of the project."
+ (interactive)
+ (let ((file (expand-file-name ".dir-locals.el" (projectile-acquire-root))))
+ (find-file file)
+ (when (not (file-exists-p file))
+ (unwind-protect
+ (projectile-skel-dir-locals)
+ (save-buffer)))))
+
+
+;;; Projectile Minor mode
+(define-obsolete-variable-alias 'projectile-mode-line-lighter 'projectile-mode-line-prefix "0.12.0")
+(defcustom projectile-mode-line-prefix
+ " Projectile"
+ "Mode line lighter prefix for Projectile.
+It's used by `projectile-default-mode-line'
+when using dynamic mode line lighter and is the only
+thing shown in the mode line otherwise."
+ :group 'projectile
+ :type 'string
+ :package-version '(projectile . "0.12.0"))
+
+(defcustom projectile-show-menu t
+ "Controls whether to display Projectile's menu."
+ :group 'projectile
+ :type 'boolean
+ :package-version '(projectile . "2.6.0"))
+
+(defvar-local projectile--mode-line projectile-mode-line-prefix)
+
+(defun projectile-default-mode-line ()
+ "Report project name and type in the modeline."
+ (let ((project-name (projectile-project-name))
+ (project-type (projectile-project-type)))
+ (format "%s[%s%s]"
+ projectile-mode-line-prefix
+ (or project-name "-")
+ (if project-type
+ (format ":%s" project-type)
+ ""))))
+
+(defun projectile-update-mode-line ()
+ "Update the Projectile mode-line."
+ (let ((mode-line (funcall projectile-mode-line-function)))
+ (setq projectile--mode-line mode-line))
+ (force-mode-line-update))
+
+(defvar projectile-command-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map (kbd "4 a") #'projectile-find-other-file-other-window)
+ (define-key map (kbd "4 b") #'projectile-switch-to-buffer-other-window)
+ (define-key map (kbd "4 C-o") #'projectile-display-buffer)
+ (define-key map (kbd "4 d") #'projectile-find-dir-other-window)
+ (define-key map (kbd "4 D") #'projectile-dired-other-window)
+ (define-key map (kbd "4 f") #'projectile-find-file-other-window)
+ (define-key map (kbd "4 g") #'projectile-find-file-dwim-other-window)
+ (define-key map (kbd "4 t") #'projectile-find-implementation-or-test-other-window)
+ (define-key map (kbd "5 a") #'projectile-find-other-file-other-frame)
+ (define-key map (kbd "5 b") #'projectile-switch-to-buffer-other-frame)
+ (define-key map (kbd "5 d") #'projectile-find-dir-other-frame)
+ (define-key map (kbd "5 D") #'projectile-dired-other-frame)
+ (define-key map (kbd "5 f") #'projectile-find-file-other-frame)
+ (define-key map (kbd "5 g") #'projectile-find-file-dwim-other-frame)
+ (define-key map (kbd "5 t") #'projectile-find-implementation-or-test-other-frame)
+ (define-key map (kbd "!") #'projectile-run-shell-command-in-root)
+ (define-key map (kbd "&") #'projectile-run-async-shell-command-in-root)
+ (define-key map (kbd "a") #'projectile-find-other-file)
+ (define-key map (kbd "b") #'projectile-switch-to-buffer)
+ (define-key map (kbd "d") #'projectile-find-dir)
+ (define-key map (kbd "D") #'projectile-dired)
+ (define-key map (kbd "e") #'projectile-recentf)
+ (define-key map (kbd "E") #'projectile-edit-dir-locals)
+ (define-key map (kbd "f") #'projectile-find-file)
+ (define-key map (kbd "g") #'projectile-find-file-dwim)
+ (define-key map (kbd "F") #'projectile-find-file-in-known-projects)
+ (define-key map (kbd "i") #'projectile-invalidate-cache)
+ (define-key map (kbd "I") #'projectile-ibuffer)
+ (define-key map (kbd "j") #'projectile-find-tag)
+ (define-key map (kbd "k") #'projectile-kill-buffers)
+ (define-key map (kbd "l") #'projectile-find-file-in-directory)
+ (define-key map (kbd "m") #'projectile-commander)
+ (define-key map (kbd "o") #'projectile-multi-occur)
+ (define-key map (kbd "p") #'projectile-switch-project)
+ (define-key map (kbd "q") #'projectile-switch-open-project)
+ (define-key map (kbd "r") #'projectile-replace)
+ (define-key map (kbd "R") #'projectile-regenerate-tags)
+ (define-key map (kbd "s g") #'projectile-grep)
+ (define-key map (kbd "s r") #'projectile-ripgrep)
+ (define-key map (kbd "s s") #'projectile-ag)
+ (define-key map (kbd "S") #'projectile-save-project-buffers)
+ (define-key map (kbd "t") #'projectile-toggle-between-implementation-and-test)
+ (define-key map (kbd "T") #'projectile-find-test-file)
+ (define-key map (kbd "v") #'projectile-vc)
+ (define-key map (kbd "V") #'projectile-browse-dirty-projects)
+ ;; project lifecycle external commands
+ ;; TODO: Bundle those under some prefix key
+ (define-key map (kbd "C") #'projectile-configure-project)
+ (define-key map (kbd "c") #'projectile-compile-project)
+ (define-key map (kbd "K") #'projectile-package-project)
+ (define-key map (kbd "L") #'projectile-install-project)
+ (define-key map (kbd "P") #'projectile-test-project)
+ (define-key map (kbd "u") #'projectile-run-project)
+ ;; utilities
+ (define-key map (kbd "x e") #'projectile-run-eshell)
+ (define-key map (kbd "x i") #'projectile-run-ielm)
+ (define-key map (kbd "x t") #'projectile-run-term)
+ (define-key map (kbd "x s") #'projectile-run-shell)
+ (define-key map (kbd "x g") #'projectile-run-gdb)
+ (define-key map (kbd "x v") #'projectile-run-vterm)
+ (define-key map (kbd "z") #'projectile-cache-current-file)
+ (define-key map (kbd "<left>") #'projectile-previous-project-buffer)
+ (define-key map (kbd "<right>") #'projectile-next-project-buffer)
+ (define-key map (kbd "ESC") #'projectile-project-buffers-other-buffer)
+ map)
+ "Keymap for Projectile commands after `projectile-keymap-prefix'.")
+(fset 'projectile-command-map projectile-command-map)
+
+(defvar projectile-mode-map
+ (let ((map (make-sparse-keymap)))
+ (when projectile-keymap-prefix
+ (define-key map projectile-keymap-prefix 'projectile-command-map))
+ (easy-menu-define projectile-mode-menu map
+ "Menu for Projectile"
+ '("Projectile" :visible projectile-show-menu
+ ("Find..."
+ ["Find file" projectile-find-file]
+ ["Find file in known projects" projectile-find-file-in-known-projects]
+ ["Find test file" projectile-find-test-file]
+ ["Find directory" projectile-find-dir]
+ ["Find file in directory" projectile-find-file-in-directory]
+ ["Find other file" projectile-find-other-file]
+ ["Jump between implementation file and test file" projectile-toggle-between-implementation-and-test])
+ ("Buffers"
+ ["Switch to buffer" projectile-switch-to-buffer]
+ ["Kill project buffers" projectile-kill-buffers]
+ ["Save project buffers" projectile-save-project-buffers]
+ ["Recent files" projectile-recentf]
+ ["Previous buffer" projectile-previous-project-buffer]
+ ["Next buffer" projectile-next-project-buffer])
+ ("Projects"
+ ["Switch to project" projectile-switch-project]
+ ["Switch to open project" projectile-switch-open-project]
+ "--"
+ ["Discover projects in directory" projectile-discover-projects-in-directory]
+ ["Clear known projects" projectile-clear-known-projects]
+ ["Reset known projects" projectile-reset-known-projects]
+ "--"
+ ["Open project in dired" projectile-dired]
+ "--"
+ ["Browse dirty projects" projectile-browse-dirty-projects]
+ "--"
+ ["Cache current file" projectile-cache-current-file]
+ ["Invalidate cache" projectile-invalidate-cache]
+ ["Regenerate [e|g]tags" projectile-regenerate-tags]
+ "--"
+ ["Toggle project wide read-only" projectile-toggle-project-read-only]
+ ["Edit .dir-locals.el" projectile-edit-dir-locals]
+ ["Project info" projectile-project-info])
+ ("Search"
+ ["Search with grep" projectile-grep]
+ ["Search with ag" projectile-ag]
+ ["Search with ripgrep" projectile-ripgrep]
+ ["Replace in project" projectile-replace]
+ ["Multi-occur in project" projectile-multi-occur])
+ ("Run..."
+ ["Run shell" projectile-run-shell]
+ ["Run eshell" projectile-run-eshell]
+ ["Run ielm" projectile-run-ielm]
+ ["Run term" projectile-run-term]
+ ["Run vterm" projectile-run-vterm]
+ "--"
+ ["Run GDB" projectile-run-gdb])
+ ("Build"
+ ["Configure project" projectile-configure-project]
+ ["Compile project" projectile-compile-project]
+ ["Test project" projectile-test-project]
+ ["Install project" projectile-install-project]
+ ["Package project" projectile-package-project]
+ ["Run project" projectile-run-project]
+ "--"
+ ["Repeat last build command" projectile-repeat-last-command])
+ "--"
+ ["About" projectile-version]))
+ map)
+ "Keymap for Projectile mode.")
+
+(defun projectile-find-file-hook-function ()
+ "Called by `find-file-hook' when `projectile-mode' is on.
+
+The function does pretty much nothing when triggered on remote files
+as all the operations it normally performs are extremely slow over
+tramp."
+ (projectile-maybe-limit-project-file-buffers)
+ (unless (file-remote-p default-directory)
+ (when projectile-dynamic-mode-line
+ (projectile-update-mode-line))
+ (when projectile-auto-update-cache
+ (projectile-cache-files-find-file-hook))
+ (projectile-track-known-projects-find-file-hook)
+ (projectile-visit-project-tags-table)))
+
+(defun projectile-maybe-limit-project-file-buffers ()
+ "Limit the opened file buffers for a project.
+
+The function simply kills the last buffer, as it's normally called
+when opening new files."
+ (when projectile-max-file-buffer-count
+ (let ((project-buffers (projectile-project-buffer-files)))
+ (when (> (length project-buffers) projectile-max-file-buffer-count)
+ (kill-buffer (car (last project-buffers)))))))
+
+;;;###autoload
+(define-minor-mode projectile-mode
+ "Minor mode to assist project management and navigation.
+
+When called interactively, toggle `projectile-mode'. With prefix
+ARG, enable `projectile-mode' if ARG is positive, otherwise disable
+it.
+
+When called from Lisp, enable `projectile-mode' if ARG is omitted,
+nil or positive. If ARG is `toggle', toggle `projectile-mode'.
+Otherwise behave as if called interactively.
+
+\\{projectile-mode-map}"
+ :lighter projectile--mode-line
+ :keymap projectile-mode-map
+ :group 'projectile
+ :require 'projectile
+ :global t
+ (cond
+ (projectile-mode
+ ;; setup the commander bindings
+ (projectile-commander-bindings)
+ ;; initialize the projects cache if needed
+ (unless projectile-projects-cache
+ (setq projectile-projects-cache
+ (or (projectile-unserialize projectile-cache-file)
+ (make-hash-table :test 'equal))))
+ (unless projectile-projects-cache-time
+ (setq projectile-projects-cache-time
+ (make-hash-table :test 'equal)))
+ ;; load the known projects
+ (projectile-load-known-projects)
+ ;; update the list of known projects
+ (projectile--cleanup-known-projects)
+ (when projectile-auto-discover
+ (projectile-discover-projects-in-search-path))
+ (add-hook 'find-file-hook 'projectile-find-file-hook-function)
+ (add-hook 'projectile-find-dir-hook #'projectile-track-known-projects-find-file-hook t)
+ (add-hook 'dired-before-readin-hook #'projectile-track-known-projects-find-file-hook t t)
+ (advice-add 'compilation-find-file :around #'compilation-find-file-projectile-find-compilation-buffer)
+ (advice-add 'delete-file :before #'delete-file-projectile-remove-from-cache))
+ (t
+ (remove-hook 'find-file-hook #'projectile-find-file-hook-function)
+ (remove-hook 'dired-before-readin-hook #'projectile-track-known-projects-find-file-hook t)
+ (advice-remove 'compilation-find-file #'compilation-find-file-projectile-find-compilation-buffer)
+ (advice-remove 'delete-file #'delete-file-projectile-remove-from-cache))))
+
+;;; savehist-mode - When `savehist-mode' is t, projectile-project-command-history will be saved.
+;; See https://github.com/bbatsov/projectile/issues/1637 for more details
+(if (bound-and-true-p savehist-loaded)
+ (add-to-list 'savehist-additional-variables 'projectile-project-command-history)
+ (defvar savehist-additional-variables nil)
+ (add-hook 'savehist-mode-hook
+ (lambda()
+ (add-to-list 'savehist-additional-variables 'projectile-project-command-history))))
+
+;;;###autoload
+(define-obsolete-function-alias 'projectile-global-mode 'projectile-mode "1.0")
+
+(provide 'projectile)
+
+;;; projectile.el ends here
diff --git a/elpa/projectile-20220430.800/projectile.elc b/elpa/projectile-20220430.800/projectile.elc
new file mode 100644
index 0000000..d8bfe9b
--- /dev/null
+++ b/elpa/projectile-20220430.800/projectile.elc
Binary files differ
diff --git a/elpa/s-20210616.619/s-autoloads.el b/elpa/s-20210616.619/s-autoloads.el
new file mode 100644
index 0000000..187f6d1
--- /dev/null
+++ b/elpa/s-20210616.619/s-autoloads.el
@@ -0,0 +1,22 @@
+;;; s-autoloads.el --- automatically extracted autoloads -*- lexical-binding: t -*-
+;;
+;;; Code:
+
+(add-to-list 'load-path (directory-file-name
+ (or (file-name-directory #$) (car load-path))))
+
+
+;;;### (autoloads nil "s" "s.el" (0 0 0 0))
+;;; Generated autoloads from s.el
+
+(register-definition-prefixes "s" '("s-"))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; coding: utf-8
+;; End:
+;;; s-autoloads.el ends here
diff --git a/elpa/s-20210616.619/s-pkg.el b/elpa/s-20210616.619/s-pkg.el
new file mode 100644
index 0000000..31e930d
--- /dev/null
+++ b/elpa/s-20210616.619/s-pkg.el
@@ -0,0 +1,2 @@
+;;; Generated package description from s.el -*- no-byte-compile: t -*-
+(define-package "s" "20210616.619" "The long lost Emacs string manipulation library." 'nil :commit "08661efb075d1c6b4fa812184c1e5e90c08795a9" :authors '(("Magnar Sveen" . "magnars@gmail.com")) :maintainer '("Magnar Sveen" . "magnars@gmail.com") :keywords '("strings"))
diff --git a/elpa/s-20210616.619/s.el b/elpa/s-20210616.619/s.el
new file mode 100644
index 0000000..39c8d9e
--- /dev/null
+++ b/elpa/s-20210616.619/s.el
@@ -0,0 +1,745 @@
+;;; s.el --- The long lost Emacs string manipulation library.
+
+;; Copyright (C) 2012-2015 Magnar Sveen
+
+;; Author: Magnar Sveen <magnars@gmail.com>
+;; Version: 1.12.0
+;; Package-Version: 20210616.619
+;; Package-Commit: 08661efb075d1c6b4fa812184c1e5e90c08795a9
+;; Keywords: strings
+
+;; 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:
+
+;; The long lost Emacs string manipulation library.
+;;
+;; See documentation on https://github.com/magnars/s.el#functions
+
+;;; Code:
+
+;; Silence byte-compiler
+(defvar ucs-normalize-combining-chars) ; Defined in `ucs-normalize'
+(autoload 'slot-value "eieio")
+
+(defun s-trim-left (s)
+ "Remove whitespace at the beginning of S."
+ (declare (pure t) (side-effect-free t))
+ (save-match-data
+ (if (string-match "\\`[ \t\n\r]+" s)
+ (replace-match "" t t s)
+ s)))
+
+(defun s-trim-right (s)
+ "Remove whitespace at the end of S."
+ (save-match-data
+ (declare (pure t) (side-effect-free t))
+ (if (string-match "[ \t\n\r]+\\'" s)
+ (replace-match "" t t s)
+ s)))
+
+(defun s-trim (s)
+ "Remove whitespace at the beginning and end of S."
+ (declare (pure t) (side-effect-free t))
+ (s-trim-left (s-trim-right s)))
+
+(defun s-collapse-whitespace (s)
+ "Convert all adjacent whitespace characters to a single space."
+ (declare (pure t) (side-effect-free t))
+ (replace-regexp-in-string "[ \t\n\r]+" " " s))
+
+(defun s-split (separator s &optional omit-nulls)
+ "Split S into substrings bounded by matches for regexp SEPARATOR.
+If OMIT-NULLS is non-nil, zero-length substrings are omitted.
+
+This is a simple wrapper around the built-in `split-string'."
+ (declare (side-effect-free t))
+ (save-match-data
+ (split-string s separator omit-nulls)))
+
+(defun s-split-up-to (separator s n &optional omit-nulls)
+ "Split S up to N times into substrings bounded by matches for regexp SEPARATOR.
+
+If OMIT-NULLS is non-nil, zero-length substrings are omitted.
+
+See also `s-split'."
+ (declare (side-effect-free t))
+ (save-match-data
+ (let ((op 0)
+ (r nil))
+ (with-temp-buffer
+ (insert s)
+ (setq op (goto-char (point-min)))
+ (while (and (re-search-forward separator nil t)
+ (< 0 n))
+ (let ((sub (buffer-substring op (match-beginning 0))))
+ (unless (and omit-nulls
+ (equal sub ""))
+ (push sub r)))
+ (setq op (goto-char (match-end 0)))
+ (setq n (1- n)))
+ (let ((sub (buffer-substring op (point-max))))
+ (unless (and omit-nulls
+ (equal sub ""))
+ (push sub r))))
+ (nreverse r))))
+
+(defun s-lines (s)
+ "Splits S into a list of strings on newline characters."
+ (declare (pure t) (side-effect-free t))
+ (s-split "\\(\r\n\\|[\n\r]\\)" s))
+
+(defun s-join (separator strings)
+ "Join all the strings in STRINGS with SEPARATOR in between."
+ (declare (pure t) (side-effect-free t))
+ (mapconcat 'identity strings separator))
+
+(defun s-concat (&rest strings)
+ "Join all the string arguments into one string."
+ (declare (pure t) (side-effect-free t))
+ (apply 'concat strings))
+
+(defun s-prepend (prefix s)
+ "Concatenate PREFIX and S."
+ (declare (pure t) (side-effect-free t))
+ (concat prefix s))
+
+(defun s-append (suffix s)
+ "Concatenate S and SUFFIX."
+ (declare (pure t) (side-effect-free t))
+ (concat s suffix))
+
+(defun s-repeat (num s)
+ "Make a string of S repeated NUM times."
+ (declare (pure t) (side-effect-free t))
+ (let (ss)
+ (while (> num 0)
+ (setq ss (cons s ss))
+ (setq num (1- num)))
+ (apply 'concat ss)))
+
+(defun s-chop-suffix (suffix s)
+ "Remove SUFFIX if it is at end of S."
+ (declare (pure t) (side-effect-free t))
+ (let ((pos (- (length suffix))))
+ (if (and (>= (length s) (length suffix))
+ (string= suffix (substring s pos)))
+ (substring s 0 pos)
+ s)))
+
+(defun s-chop-suffixes (suffixes s)
+ "Remove SUFFIXES one by one in order, if they are at the end of S."
+ (declare (pure t) (side-effect-free t))
+ (while suffixes
+ (setq s (s-chop-suffix (car suffixes) s))
+ (setq suffixes (cdr suffixes)))
+ s)
+
+(defun s-chop-prefix (prefix s)
+ "Remove PREFIX if it is at the start of S."
+ (declare (pure t) (side-effect-free t))
+ (let ((pos (length prefix)))
+ (if (and (>= (length s) (length prefix))
+ (string= prefix (substring s 0 pos)))
+ (substring s pos)
+ s)))
+
+(defun s-chop-prefixes (prefixes s)
+ "Remove PREFIXES one by one in order, if they are at the start of S."
+ (declare (pure t) (side-effect-free t))
+ (while prefixes
+ (setq s (s-chop-prefix (car prefixes) s))
+ (setq prefixes (cdr prefixes)))
+ s)
+
+(defun s-shared-start (s1 s2)
+ "Returns the longest prefix S1 and S2 have in common."
+ (declare (pure t) (side-effect-free t))
+ (let ((cmp (compare-strings s1 0 (length s1) s2 0 (length s2))))
+ (if (eq cmp t) s1 (substring s1 0 (1- (abs cmp))))))
+
+(defun s-shared-end (s1 s2)
+ "Returns the longest suffix S1 and S2 have in common."
+ (declare (pure t) (side-effect-free t))
+ (let* ((l1 (length s1))
+ (l2 (length s2))
+ (search-length (min l1 l2))
+ (i 0))
+ (while (and (< i search-length)
+ (= (aref s1 (- l1 i 1)) (aref s2 (- l2 i 1))))
+ (setq i (1+ i)))
+ ;; If I is 0, then it means that there's no common suffix between
+ ;; S1 and S2.
+ ;;
+ ;; However, since (substring s (- 0)) will return the whole
+ ;; string, `s-shared-end' should simply return the empty string
+ ;; when I is 0.
+ (if (zerop i)
+ ""
+ (substring s1 (- i)))))
+
+(defun s-chomp (s)
+ "Remove one trailing `\\n`, `\\r` or `\\r\\n` from S."
+ (declare (pure t) (side-effect-free t))
+ (s-chop-suffixes '("\n" "\r") s))
+
+(defun s-truncate (len s &optional ellipsis)
+ "If S is longer than LEN, cut it down and add ELLIPSIS to the end.
+
+The resulting string, including ellipsis, will be LEN characters
+long.
+
+When not specified, ELLIPSIS defaults to ‘...’."
+ (declare (pure t) (side-effect-free t))
+ (unless ellipsis
+ (setq ellipsis "..."))
+ (if (> (length s) len)
+ (format "%s%s" (substring s 0 (- len (length ellipsis))) ellipsis)
+ s))
+
+(defun s-word-wrap (len s)
+ "If S is longer than LEN, wrap the words with newlines."
+ (declare (side-effect-free t))
+ (save-match-data
+ (with-temp-buffer
+ (insert s)
+ (let ((fill-column len))
+ (fill-region (point-min) (point-max)))
+ (buffer-substring (point-min) (point-max)))))
+
+(defun s-center (len s)
+ "If S is shorter than LEN, pad it with spaces so it is centered."
+ (declare (pure t) (side-effect-free t))
+ (let ((extra (max 0 (- len (length s)))))
+ (concat
+ (make-string (ceiling extra 2) ? )
+ s
+ (make-string (floor extra 2) ? ))))
+
+(defun s-pad-left (len padding s)
+ "If S is shorter than LEN, pad it with PADDING on the left."
+ (declare (pure t) (side-effect-free t))
+ (let ((extra (max 0 (- len (length s)))))
+ (concat (make-string extra (string-to-char padding))
+ s)))
+
+(defun s-pad-right (len padding s)
+ "If S is shorter than LEN, pad it with PADDING on the right."
+ (declare (pure t) (side-effect-free t))
+ (let ((extra (max 0 (- len (length s)))))
+ (concat s
+ (make-string extra (string-to-char padding)))))
+
+(defun s-left (len s)
+ "Returns up to the LEN first chars of S."
+ (declare (pure t) (side-effect-free t))
+ (if (> (length s) len)
+ (substring s 0 len)
+ s))
+
+(defun s-right (len s)
+ "Returns up to the LEN last chars of S."
+ (declare (pure t) (side-effect-free t))
+ (let ((l (length s)))
+ (if (> l len)
+ (substring s (- l len) l)
+ s)))
+
+(defun s-ends-with? (suffix s &optional ignore-case)
+ "Does S end with SUFFIX?
+
+If IGNORE-CASE is non-nil, the comparison is done without paying
+attention to case differences.
+
+Alias: `s-suffix?'"
+ (declare (pure t) (side-effect-free t))
+ (let ((start-pos (- (length s) (length suffix))))
+ (and (>= start-pos 0)
+ (eq t (compare-strings suffix nil nil
+ s start-pos nil ignore-case)))))
+
+(defun s-starts-with? (prefix s &optional ignore-case)
+ "Does S start with PREFIX?
+
+If IGNORE-CASE is non-nil, the comparison is done without paying
+attention to case differences.
+
+Alias: `s-prefix?'. This is a simple wrapper around the built-in
+`string-prefix-p'."
+ (declare (pure t) (side-effect-free t))
+ (string-prefix-p prefix s ignore-case))
+
+(defun s--truthy? (val)
+ (declare (pure t) (side-effect-free t))
+ (not (null val)))
+
+(defun s-contains? (needle s &optional ignore-case)
+ "Does S contain NEEDLE?
+
+If IGNORE-CASE is non-nil, the comparison is done without paying
+attention to case differences."
+ (declare (pure t) (side-effect-free t))
+ (let ((case-fold-search ignore-case))
+ (s--truthy? (string-match-p (regexp-quote needle) s))))
+
+(defun s-equals? (s1 s2)
+ "Is S1 equal to S2?
+
+This is a simple wrapper around the built-in `string-equal'."
+ (declare (pure t) (side-effect-free t))
+ (string-equal s1 s2))
+
+(defun s-less? (s1 s2)
+ "Is S1 less than S2?
+
+This is a simple wrapper around the built-in `string-lessp'."
+ (declare (pure t) (side-effect-free t))
+ (string-lessp s1 s2))
+
+(defun s-matches? (regexp s &optional start)
+ "Does REGEXP match S?
+If START is non-nil the search starts at that index.
+
+This is a simple wrapper around the built-in `string-match-p'."
+ (declare (side-effect-free t))
+ (s--truthy? (string-match-p regexp s start)))
+
+(defun s-blank? (s)
+ "Is S nil or the empty string?"
+ (declare (pure t) (side-effect-free t))
+ (or (null s) (string= "" s)))
+
+(defun s-blank-str? (s)
+ "Is S nil or the empty string or string only contains whitespace?"
+ (declare (pure t) (side-effect-free t))
+ (or (s-blank? s) (s-blank? (s-trim s))))
+
+(defun s-present? (s)
+ "Is S anything but nil or the empty string?"
+ (declare (pure t) (side-effect-free t))
+ (not (s-blank? s)))
+
+(defun s-presence (s)
+ "Return S if it's `s-present?', otherwise return nil."
+ (declare (pure t) (side-effect-free t))
+ (and (s-present? s) s))
+
+(defun s-lowercase? (s)
+ "Are all the letters in S in lower case?"
+ (declare (side-effect-free t))
+ (let ((case-fold-search nil))
+ (not (string-match-p "[[:upper:]]" s))))
+
+(defun s-uppercase? (s)
+ "Are all the letters in S in upper case?"
+ (declare (side-effect-free t))
+ (let ((case-fold-search nil))
+ (not (string-match-p "[[:lower:]]" s))))
+
+(defun s-mixedcase? (s)
+ "Are there both lower case and upper case letters in S?"
+ (let ((case-fold-search nil))
+ (s--truthy?
+ (and (string-match-p "[[:lower:]]" s)
+ (string-match-p "[[:upper:]]" s)))))
+
+(defun s-capitalized? (s)
+ "In S, is the first letter upper case, and all other letters lower case?"
+ (declare (side-effect-free t))
+ (let ((case-fold-search nil))
+ (s--truthy?
+ (string-match-p "^[[:upper:]][^[:upper:]]*$" s))))
+
+(defun s-numeric? (s)
+ "Is S a number?"
+ (declare (pure t) (side-effect-free t))
+ (s--truthy?
+ (string-match-p "^[0-9]+$" s)))
+
+(defun s-replace (old new s)
+ "Replaces OLD with NEW in S."
+ (declare (pure t) (side-effect-free t))
+ (replace-regexp-in-string (regexp-quote old) new s t t))
+
+(defalias 's-replace-regexp 'replace-regexp-in-string)
+
+(defun s--aget (alist key)
+ (declare (pure t) (side-effect-free t))
+ (cdr (assoc-string key alist)))
+
+(defun s-replace-all (replacements s)
+ "REPLACEMENTS is a list of cons-cells. Each `car` is replaced with `cdr` in S."
+ (declare (pure t) (side-effect-free t))
+ (replace-regexp-in-string (regexp-opt (mapcar 'car replacements))
+ (lambda (it) (s--aget replacements it))
+ s t t))
+
+(defun s-downcase (s)
+ "Convert S to lower case.
+
+This is a simple wrapper around the built-in `downcase'."
+ (declare (side-effect-free t))
+ (downcase s))
+
+(defun s-upcase (s)
+ "Convert S to upper case.
+
+This is a simple wrapper around the built-in `upcase'."
+ (declare (side-effect-free t))
+ (upcase s))
+
+(defun s-capitalize (s)
+ "Convert the first word's first character to upper case and the rest to lower case in S."
+ (declare (side-effect-free t))
+ (concat (upcase (substring s 0 1)) (downcase (substring s 1))))
+
+(defun s-titleize (s)
+ "Convert each word's first character to upper case and the rest to lower case in S.
+
+This is a simple wrapper around the built-in `capitalize'."
+ (declare (side-effect-free t))
+ (capitalize s))
+
+(defmacro s-with (s form &rest more)
+ "Threads S through the forms. Inserts S as the last item
+in the first form, making a list of it if it is not a list
+already. If there are more forms, inserts the first form as the
+last item in second form, etc."
+ (declare (debug (form &rest [&or (function &rest form) fboundp])))
+ (if (null more)
+ (if (listp form)
+ `(,(car form) ,@(cdr form) ,s)
+ (list form s))
+ `(s-with (s-with ,s ,form) ,@more)))
+
+(put 's-with 'lisp-indent-function 1)
+
+(defun s-index-of (needle s &optional ignore-case)
+ "Returns first index of NEEDLE in S, or nil.
+
+If IGNORE-CASE is non-nil, the comparison is done without paying
+attention to case differences."
+ (declare (pure t) (side-effect-free t))
+ (let ((case-fold-search ignore-case))
+ (string-match-p (regexp-quote needle) s)))
+
+(defun s-reverse (s)
+ "Return the reverse of S."
+ (declare (pure t) (side-effect-free t))
+ (save-match-data
+ (if (multibyte-string-p s)
+ (let ((input (string-to-list s))
+ output)
+ (require 'ucs-normalize)
+ (while input
+ ;; Handle entire grapheme cluster as a single unit
+ (let ((grapheme (list (pop input))))
+ (while (memql (car input) ucs-normalize-combining-chars)
+ (push (pop input) grapheme))
+ (setq output (nconc (nreverse grapheme) output))))
+ (concat output))
+ (concat (nreverse (string-to-list s))))))
+
+(defun s-match-strings-all (regex string)
+ "Return a list of matches for REGEX in STRING.
+
+Each element itself is a list of matches, as per
+`match-string'. Multiple matches at the same position will be
+ignored after the first."
+ (declare (side-effect-free t))
+ (save-match-data
+ (let ((all-strings ())
+ (i 0))
+ (while (and (< i (length string))
+ (string-match regex string i))
+ (setq i (1+ (match-beginning 0)))
+ (let (strings
+ (num-matches (/ (length (match-data)) 2))
+ (match 0))
+ (while (/= match num-matches)
+ (push (match-string match string) strings)
+ (setq match (1+ match)))
+ (push (nreverse strings) all-strings)))
+ (nreverse all-strings))))
+
+(defun s-matched-positions-all (regexp string &optional subexp-depth)
+ "Return a list of matched positions for REGEXP in STRING.
+SUBEXP-DEPTH is 0 by default."
+ (declare (side-effect-free t))
+ (if (null subexp-depth)
+ (setq subexp-depth 0))
+ (save-match-data
+ (let ((pos 0) result)
+ (while (and (string-match regexp string pos)
+ (< pos (length string)))
+ (let ((m (match-end subexp-depth)))
+ (push (cons (match-beginning subexp-depth) (match-end subexp-depth)) result)
+ (setq pos (match-end 0))))
+ (nreverse result))))
+
+(defun s-match (regexp s &optional start)
+ "When the given expression matches the string, this function returns a list
+of the whole matching string and a string for each matched subexpressions.
+If it did not match the returned value is an empty list (nil).
+
+When START is non-nil the search will start at that index."
+ (declare (side-effect-free t))
+ (save-match-data
+ (if (string-match regexp s start)
+ (let ((match-data-list (match-data))
+ result)
+ (while match-data-list
+ (let* ((beg (car match-data-list))
+ (end (cadr match-data-list))
+ (subs (if (and beg end) (substring s beg end) nil)))
+ (setq result (cons subs result))
+ (setq match-data-list
+ (cddr match-data-list))))
+ (nreverse result)))))
+
+(defun s-slice-at (regexp s)
+ "Slices S up at every index matching REGEXP."
+ (declare (side-effect-free t))
+ (if (= 0 (length s)) (list "")
+ (save-match-data
+ (let (i)
+ (setq i (string-match regexp s 1))
+ (if i
+ (cons (substring s 0 i)
+ (s-slice-at regexp (substring s i)))
+ (list s))))))
+
+(defun s-split-words (s)
+ "Split S into list of words."
+ (declare (side-effect-free t))
+ (s-split
+ "[^[:word:]0-9]+"
+ (let ((case-fold-search nil))
+ (replace-regexp-in-string
+ "\\([[:lower:]]\\)\\([[:upper:]]\\)" "\\1 \\2"
+ (replace-regexp-in-string "\\([[:upper:]]\\)\\([[:upper:]][0-9[:lower:]]\\)" "\\1 \\2" s)))
+ t))
+
+(defun s--mapcar-head (fn-head fn-rest list)
+ "Like MAPCAR, but applies a different function to the first element."
+ (if list
+ (cons (funcall fn-head (car list)) (mapcar fn-rest (cdr list)))))
+
+(defun s-lower-camel-case (s)
+ "Convert S to lowerCamelCase."
+ (declare (side-effect-free t))
+ (s-join "" (s--mapcar-head 'downcase 'capitalize (s-split-words s))))
+
+(defun s-upper-camel-case (s)
+ "Convert S to UpperCamelCase."
+ (declare (side-effect-free t))
+ (s-join "" (mapcar 'capitalize (s-split-words s))))
+
+(defun s-snake-case (s)
+ "Convert S to snake_case."
+ (declare (side-effect-free t))
+ (s-join "_" (mapcar 'downcase (s-split-words s))))
+
+(defun s-dashed-words (s)
+ "Convert S to dashed-words."
+ (declare (side-effect-free t))
+ (s-join "-" (mapcar 'downcase (s-split-words s))))
+
+(defun s-capitalized-words (s)
+ "Convert S to Capitalized words."
+ (declare (side-effect-free t))
+ (let ((words (s-split-words s)))
+ (s-join " " (cons (capitalize (car words)) (mapcar 'downcase (cdr words))))))
+
+(defun s-titleized-words (s)
+ "Convert S to Titleized Words."
+ (declare (side-effect-free t))
+ (s-join " " (mapcar 's-titleize (s-split-words s))))
+
+(defun s-word-initials (s)
+ "Convert S to its initials."
+ (declare (side-effect-free t))
+ (s-join "" (mapcar (lambda (ss) (substring ss 0 1))
+ (s-split-words s))))
+
+;; Errors for s-format
+(progn
+ (put 's-format-resolve
+ 'error-conditions
+ '(error s-format s-format-resolve))
+ (put 's-format-resolve
+ 'error-message
+ "Cannot resolve a template to values"))
+
+(defun s-format (template replacer &optional extra)
+ "Format TEMPLATE with the function REPLACER.
+
+REPLACER takes an argument of the format variable and optionally
+an extra argument which is the EXTRA value from the call to
+`s-format'.
+
+Several standard `s-format' helper functions are recognized and
+adapted for this:
+
+ (s-format \"${name}\" 'gethash hash-table)
+ (s-format \"${name}\" 'aget alist)
+ (s-format \"$0\" 'elt sequence)
+
+The REPLACER function may be used to do any other kind of
+transformation."
+ (let ((saved-match-data (match-data)))
+ (unwind-protect
+ (replace-regexp-in-string
+ "\\$\\({\\([^}]+\\)}\\|[0-9]+\\)"
+ (lambda (md)
+ (let ((var
+ (let ((m (match-string 2 md)))
+ (if m m
+ (string-to-number (match-string 1 md)))))
+ (replacer-match-data (match-data)))
+ (unwind-protect
+ (let ((v
+ (cond
+ ((eq replacer 'gethash)
+ (funcall replacer var extra))
+ ((eq replacer 'aget)
+ (funcall 's--aget extra var))
+ ((eq replacer 'elt)
+ (funcall replacer extra var))
+ ((eq replacer 'oref)
+ (funcall #'slot-value extra (intern var)))
+ (t
+ (set-match-data saved-match-data)
+ (if extra
+ (funcall replacer var extra)
+ (funcall replacer var))))))
+ (if v (format "%s" v) (signal 's-format-resolve md)))
+ (set-match-data replacer-match-data))))
+ template
+ ;; Need literal to make sure it works
+ t t)
+ (set-match-data saved-match-data))))
+
+(defvar s-lex-value-as-lisp nil
+ "If `t' interpolate lisp values as lisp.
+
+`s-lex-format' inserts values with (format \"%S\").")
+
+(defun s-lex-fmt|expand (fmt)
+ "Expand FMT into lisp."
+ (declare (side-effect-free t))
+ (list 's-format fmt (quote 'aget)
+ (append '(list)
+ (mapcar
+ (lambda (matches)
+ (list
+ 'cons
+ (cadr matches)
+ `(format
+ (if s-lex-value-as-lisp "%S" "%s")
+ ,(intern (cadr matches)))))
+ (s-match-strings-all "${\\([^}]+\\)}" fmt)))))
+
+(defmacro s-lex-format (format-str)
+ "`s-format` with the current environment.
+
+FORMAT-STR may use the `s-format' variable reference to refer to
+any variable:
+
+ (let ((x 1))
+ (s-lex-format \"x is: ${x}\"))
+
+The values of the variables are interpolated with \"%s\" unless
+the variable `s-lex-value-as-lisp' is `t' and then they are
+interpolated with \"%S\"."
+ (declare (debug (form)))
+ (s-lex-fmt|expand format-str))
+
+(defun s-count-matches (regexp s &optional start end)
+ "Count occurrences of `regexp' in `s'.
+
+`start', inclusive, and `end', exclusive, delimit the part of `s' to
+match. `start' and `end' are both indexed starting at 1; the initial
+character in `s' is index 1.
+
+This function starts looking for the next match from the end of the
+previous match. Hence, it ignores matches that overlap a previously
+found match. To count overlapping matches, use
+`s-count-matches-all'."
+ (declare (side-effect-free t))
+ (save-match-data
+ (with-temp-buffer
+ (insert s)
+ (goto-char (point-min))
+ (count-matches regexp (or start 1) (or end (point-max))))))
+
+(defun s-count-matches-all (regexp s &optional start end)
+ "Count occurrences of `regexp' in `s'.
+
+`start', inclusive, and `end', exclusive, delimit the part of `s' to
+match. `start' and `end' are both indexed starting at 1; the initial
+character in `s' is index 1.
+
+This function starts looking for the next match from the second
+character of the previous match. Hence, it counts matches that
+overlap a previously found match. To ignore matches that overlap a
+previously found match, use `s-count-matches'."
+ (declare (side-effect-free t))
+ (let* ((anchored-regexp (format "^%s" regexp))
+ (match-count 0)
+ (i 0)
+ (narrowed-s (substring s
+ (when start (1- start))
+ (when end (1- end)))))
+ (save-match-data
+ (while (< i (length narrowed-s))
+ (when (s-matches? anchored-regexp (substring narrowed-s i))
+ (setq match-count (1+ match-count)))
+ (setq i (1+ i))))
+ match-count))
+
+(defun s-wrap (s prefix &optional suffix)
+ "Wrap string S with PREFIX and optionally SUFFIX.
+
+Return string S with PREFIX prepended. If SUFFIX is present, it
+is appended, otherwise PREFIX is used as both prefix and
+suffix."
+ (declare (pure t) (side-effect-free t))
+ (concat prefix s (or suffix prefix)))
+
+
+;;; Aliases
+
+(defalias 's-blank-p 's-blank?)
+(defalias 's-blank-str-p 's-blank-str?)
+(defalias 's-capitalized-p 's-capitalized?)
+(defalias 's-contains-p 's-contains?)
+(defalias 's-ends-with-p 's-ends-with?)
+(defalias 's-equals-p 's-equals?)
+(defalias 's-less-p 's-less?)
+(defalias 's-lowercase-p 's-lowercase?)
+(defalias 's-matches-p 's-matches?)
+(defalias 's-mixedcase-p 's-mixedcase?)
+(defalias 's-numeric-p 's-numeric?)
+(defalias 's-prefix-p 's-starts-with?)
+(defalias 's-prefix? 's-starts-with?)
+(defalias 's-present-p 's-present?)
+(defalias 's-starts-with-p 's-starts-with?)
+(defalias 's-suffix-p 's-ends-with?)
+(defalias 's-suffix? 's-ends-with?)
+(defalias 's-uppercase-p 's-uppercase?)
+
+
+(provide 's)
+;;; s.el ends here
diff --git a/elpa/s-20210616.619/s.elc b/elpa/s-20210616.619/s.elc
new file mode 100644
index 0000000..ed8fa9d
--- /dev/null
+++ b/elpa/s-20210616.619/s.elc
Binary files differ
diff --git a/elpa/smex-20151212.2209/smex-autoloads.el b/elpa/smex-20151212.2209/smex-autoloads.el
new file mode 100644
index 0000000..5f42e2d
--- /dev/null
+++ b/elpa/smex-20151212.2209/smex-autoloads.el
@@ -0,0 +1,29 @@
+;;; smex-autoloads.el --- automatically extracted autoloads -*- lexical-binding: t -*-
+;;
+;;; Code:
+
+(add-to-list 'load-path (directory-file-name
+ (or (file-name-directory #$) (car load-path))))
+
+
+;;;### (autoloads nil "smex" "smex.el" (0 0 0 0))
+;;; Generated autoloads from smex.el
+
+(autoload 'smex "smex" nil t nil)
+
+(autoload 'smex-major-mode-commands "smex" "\
+Like `smex', but limited to commands that are relevant to the active major mode." t nil)
+
+(autoload 'smex-initialize "smex" nil t nil)
+
+(register-definition-prefixes "smex" '("smex-"))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; coding: utf-8
+;; End:
+;;; smex-autoloads.el ends here
diff --git a/elpa/smex-20151212.2209/smex-pkg.el b/elpa/smex-20151212.2209/smex-pkg.el
new file mode 100644
index 0000000..e06d97a
--- /dev/null
+++ b/elpa/smex-20151212.2209/smex-pkg.el
@@ -0,0 +1,2 @@
+;;; Generated package description from smex.el -*- no-byte-compile: t -*-
+(define-package "smex" "20151212.2209" "M-x interface with Ido-style fuzzy matching." '((emacs "24")) :commit "55aaebe3d793c2c990b39a302eb26c184281c42c" :authors '(("Cornelius Mika" . "cornelius.mika@gmail.com")) :maintainer '("Cornelius Mika" . "cornelius.mika@gmail.com") :keywords '("convenience" "usability") :url "http://github.com/nonsequitur/smex/")
diff --git a/elpa/smex-20151212.2209/smex.el b/elpa/smex-20151212.2209/smex.el
new file mode 100644
index 0000000..6810e18
--- /dev/null
+++ b/elpa/smex-20151212.2209/smex.el
@@ -0,0 +1,485 @@
+;;; smex.el --- M-x interface with Ido-style fuzzy matching. -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2009-2014 Cornelius Mika and contributors
+;;
+;; Author: Cornelius Mika <cornelius.mika@gmail.com> and contributors
+;; URL: http://github.com/nonsequitur/smex/
+;; Package-Version: 20151212.2209
+;; Package-Commit: 55aaebe3d793c2c990b39a302eb26c184281c42c
+;; Package-Requires: ((emacs "24"))
+;; Version: 3.0
+;; Keywords: convenience, usability
+
+;; This file is not part of GNU Emacs.
+
+;;; License:
+
+;; Licensed under the same terms as Emacs.
+
+;;; Commentary:
+
+;; Quick start:
+;; run (smex-initialize)
+;;
+;; Bind the following commands:
+;; smex, smex-major-mode-commands
+;;
+;; For a detailed introduction see:
+;; http://github.com/nonsequitur/smex/blob/master/README.markdown
+
+;;; Code:
+
+(require 'ido)
+
+(defgroup smex nil
+ "M-x interface with Ido-style fuzzy matching and ranking heuristics."
+ :group 'extensions
+ :group 'convenience
+ :link '(emacs-library-link :tag "Lisp File" "smex.el"))
+
+(defcustom smex-auto-update t
+ "If non-nil, `Smex' checks for new commands each time it is run.
+Turn it off for minor speed improvements on older systems."
+ :type 'boolean
+ :group 'smex)
+
+(defcustom smex-save-file (locate-user-emacs-file "smex-items" ".smex-items")
+ "File in which the smex state is saved between Emacs sessions.
+Variables stored are: `smex-data', `smex-history'.
+Must be set before initializing Smex."
+ :type 'string
+ :group 'smex)
+
+(defcustom smex-history-length 7
+ "Determines on how many recently executed commands
+Smex should keep a record.
+Must be set before initializing Smex."
+ :type 'integer
+ :group 'smex)
+
+(defcustom smex-prompt-string "M-x "
+ "String to display in the Smex prompt."
+ :type 'string
+ :group 'smex)
+
+(defcustom smex-flex-matching t
+ "Enables Ido flex matching. On by default.
+Set this to nil to disable fuzzy matching."
+ :type 'boolean
+ :group 'smex)
+
+(defvar smex-initialized-p nil)
+(defvar smex-cache)
+(defvar smex-ido-cache)
+(defvar smex-data)
+(defvar smex-history)
+(defvar smex-command-count 0)
+(defvar smex-custom-action nil)
+
+;; Check if Smex is supported
+(when (equal (cons 1 1)
+ (ignore-errors
+ (subr-arity (symbol-function 'execute-extended-command))))
+ (error "Your Emacs has a non-elisp version of `execute-extended-command', which is incompatible with Smex"))
+
+;;--------------------------------------------------------------------------------
+;; Smex Interface
+
+;;;###autoload
+(defun smex ()
+ (interactive)
+ (unless smex-initialized-p
+ (smex-initialize))
+ (if (smex-already-running)
+ (smex-update-and-rerun)
+ (and smex-auto-update
+ (smex-detect-new-commands)
+ (smex-update))
+ (smex-read-and-run smex-ido-cache)))
+
+(defun smex-already-running ()
+ (and (boundp 'ido-choice-list)
+ (eql ido-choice-list smex-ido-cache)
+ (minibuffer-window-active-p (selected-window))))
+
+(defun smex-update-and-rerun ()
+ (smex-do-with-selected-item
+ (lambda (_) (smex-update) (smex-read-and-run smex-ido-cache ido-text))))
+
+(defun smex-read-and-run (commands &optional initial-input)
+ (let* ((chosen-item-name (smex-completing-read commands initial-input))
+ (chosen-item (intern chosen-item-name)))
+ (if smex-custom-action
+ (let ((action smex-custom-action))
+ (setq smex-custom-action nil)
+ (funcall action chosen-item))
+ (unwind-protect
+ (with-no-warnings ; Don't warn about interactive use of `execute-extended-command'
+ (execute-extended-command current-prefix-arg chosen-item-name))
+ (smex-rank chosen-item)))))
+
+;;;###autoload
+(defun smex-major-mode-commands ()
+ "Like `smex', but limited to commands that are relevant to the active major mode."
+ (interactive)
+ (unless smex-initialized-p
+ (smex-initialize))
+ (let ((commands (delete-dups (append (smex-extract-commands-from-keymap (current-local-map))
+ (smex-extract-commands-from-features major-mode)))))
+ (setq commands (smex-sort-according-to-cache commands))
+ (setq commands (mapcar #'symbol-name commands))
+ (smex-read-and-run commands)))
+
+(defun smex-completing-read (choices initial-input)
+ (let ((ido-completion-map ido-completion-map)
+ (ido-setup-hook (cons 'smex-prepare-ido-bindings ido-setup-hook))
+ (ido-enable-prefix nil)
+ (ido-enable-flex-matching smex-flex-matching)
+ (ido-max-prospects 10)
+ (minibuffer-completion-table choices))
+ (ido-completing-read (smex-prompt-with-prefix-arg) choices nil nil
+ initial-input 'extended-command-history (car choices))))
+
+(defun smex-prompt-with-prefix-arg ()
+ (if (not current-prefix-arg)
+ smex-prompt-string
+ (concat
+ (if (eq current-prefix-arg '-)
+ "- "
+ (if (integerp current-prefix-arg)
+ (format "%d " current-prefix-arg)
+ (if (= (car current-prefix-arg) 4)
+ "C-u "
+ (format "%d " (car current-prefix-arg)))))
+ smex-prompt-string)))
+
+(defun smex-prepare-ido-bindings ()
+ (define-key ido-completion-map (kbd "TAB") 'minibuffer-complete)
+ (define-key ido-completion-map (kbd "C-h f") 'smex-describe-function)
+ (define-key ido-completion-map (kbd "C-h w") 'smex-where-is)
+ (define-key ido-completion-map (kbd "M-.") 'smex-find-function)
+ (define-key ido-completion-map (kbd "C-a") 'move-beginning-of-line))
+
+;;--------------------------------------------------------------------------------
+;; Cache and Maintenance
+
+(defun smex-rebuild-cache ()
+ (interactive)
+ (setq smex-cache nil)
+
+ ;; Build up list 'new-commands' and later put it at the end of 'smex-cache'.
+ ;; This speeds up sorting.
+ (let (new-commands)
+ (mapatoms (lambda (symbol)
+ (when (commandp symbol)
+ (let ((known-command (assq symbol smex-data)))
+ (if known-command
+ (setq smex-cache (cons known-command smex-cache))
+ (setq new-commands (cons (list symbol) new-commands)))))))
+ (if (eq (length smex-cache) 0)
+ (setq smex-cache new-commands)
+ (setcdr (last smex-cache) new-commands)))
+
+ (setq smex-cache (sort smex-cache 'smex-sorting-rules))
+ (smex-restore-history)
+ (setq smex-ido-cache (smex-convert-for-ido smex-cache)))
+
+(defun smex-convert-for-ido (command-items)
+ (mapcar (lambda (command-item) (symbol-name (car command-item))) command-items))
+
+(defun smex-restore-history ()
+ "Rearranges `smex-cache' according to `smex-history'"
+ (if (> (length smex-history) smex-history-length)
+ (setcdr (nthcdr (- smex-history-length 1) smex-history) nil))
+ (mapc (lambda (command)
+ (unless (eq command (caar smex-cache))
+ (let ((command-cell-position (smex-detect-position
+ smex-cache
+ (lambda (cell)
+ (eq command (caar cell))))))
+ (when command-cell-position
+ (let ((command-cell (smex-remove-nth-cell
+ command-cell-position smex-cache)))
+ (setcdr command-cell smex-cache)
+ (setq smex-cache command-cell))))))
+ (reverse smex-history)))
+
+(defun smex-sort-according-to-cache (list)
+ "Sorts a list of commands by their order in `smex-cache'"
+ (let (sorted)
+ (dolist (command-item smex-cache)
+ (let ((command (car command-item)))
+ (when (memq command list)
+ (setq sorted (cons command sorted))
+ (setq list (delq command list)))))
+ (nreverse (append list sorted))))
+
+(defun smex-update ()
+ (interactive)
+ (smex-save-history)
+ (smex-rebuild-cache))
+
+(defun smex-detect-new-commands ()
+ (let ((i 0))
+ (mapatoms (lambda (symbol) (if (commandp symbol) (setq i (1+ i)))))
+ (unless (= i smex-command-count)
+ (setq smex-command-count i))))
+
+(defun smex-auto-update (&optional idle-time)
+ "Update Smex when Emacs has been idle for IDLE-TIME."
+ (unless idle-time (setq idle-time 60))
+ (run-with-idle-timer idle-time t
+ '(lambda () (if (smex-detect-new-commands) (smex-update)))))
+
+;;;###autoload
+(defun smex-initialize ()
+ (interactive)
+ (unless ido-mode (smex-initialize-ido))
+ (smex-load-save-file)
+ (smex-detect-new-commands)
+ (smex-rebuild-cache)
+ (add-hook 'kill-emacs-hook 'smex-save-to-file)
+ (setq smex-initialized-p t))
+
+(defun smex-initialize-ido ()
+ "Sets up a minimal Ido environment for `ido-completing-read'."
+ (with-no-warnings ; `ido-init-completion-maps' is deprecated in Emacs 25
+ (ido-init-completion-maps))
+ (add-hook 'minibuffer-setup-hook 'ido-minibuffer-setup))
+
+(defsubst smex-save-file-not-empty-p ()
+ (string-match-p "\[^[:space:]\]" (buffer-string)))
+
+(defun smex-load-save-file ()
+ "Loads `smex-history' and `smex-data' from `smex-save-file'"
+ (let ((save-file (expand-file-name smex-save-file)))
+ (if (file-readable-p save-file)
+ (with-temp-buffer
+ (insert-file-contents save-file)
+ (condition-case nil
+ (setq smex-history (read (current-buffer))
+ smex-data (read (current-buffer)))
+ (error (if (smex-save-file-not-empty-p)
+ (error "Invalid data in smex-save-file (%s). Can't restore history."
+ smex-save-file)
+ (unless (boundp 'smex-history) (setq smex-history nil))
+ (unless (boundp 'smex-data) (setq smex-data nil))))))
+ (setq smex-history nil smex-data nil))))
+
+(defun smex-save-history ()
+ "Updates `smex-history'"
+ (setq smex-history nil)
+ (let ((cell smex-cache))
+ (dotimes (_ smex-history-length)
+ (setq smex-history (cons (caar cell) smex-history))
+ (setq cell (cdr cell))))
+ (setq smex-history (nreverse smex-history)))
+
+(defmacro smex-pp (list-var)
+ `(smex-pp* ,list-var ,(symbol-name list-var)))
+
+(defun smex-save-to-file ()
+ (interactive)
+ (smex-save-history)
+ (with-temp-file (expand-file-name smex-save-file)
+ (smex-pp smex-history)
+ (smex-pp smex-data)))
+
+;;--------------------------------------------------------------------------------
+;; Ranking
+
+(defun smex-sorting-rules (command-item other-command-item)
+ "Returns true if COMMAND-ITEM should sort before OTHER-COMMAND-ITEM."
+ (let* ((count (or (cdr command-item ) 0))
+ (other-count (or (cdr other-command-item) 0))
+ (name (car command-item))
+ (other-name (car other-command-item))
+ (length (length (symbol-name name)))
+ (other-length (length (symbol-name other-name))))
+ (or (> count other-count) ; 1. Frequency of use
+ (and (= count other-count)
+ (or (< length other-length) ; 2. Command length
+ (and (= length other-length)
+ (string< name other-name))))))) ; 3. Alphabetical order
+
+(defun smex-rank (command)
+ (let ((command-item (or (assq command smex-cache)
+ ;; Update caches and try again if not found.
+ (progn (smex-update)
+ (assq command smex-cache)))))
+ (when command-item
+ (smex-update-counter command-item)
+
+ ;; Don't touch the cache order if the chosen command
+ ;; has just been execucted previously.
+ (unless (eq command-item (car smex-cache))
+ (let (command-cell
+ (pos (smex-detect-position smex-cache (lambda (cell)
+ (eq command-item (car cell))))))
+ ;; Remove the just executed command.
+ (setq command-cell (smex-remove-nth-cell pos smex-cache))
+ ;; And put it on top of the cache.
+ (setcdr command-cell smex-cache)
+ (setq smex-cache command-cell)
+
+ ;; Repeat the same for the ido cache. Should this be DRYed?
+ (setq command-cell (smex-remove-nth-cell pos smex-ido-cache))
+ (setcdr command-cell smex-ido-cache)
+ (setq smex-ido-cache command-cell)
+
+ ;; Now put the last history item back to its normal place.
+ (smex-sort-item-at smex-history-length))))))
+
+(defun smex-update-counter (command-item)
+ (let ((count (cdr command-item)))
+ (setcdr command-item
+ (if count
+ (1+ count)
+ ;; Else: Command has just been executed for the first time.
+ ;; Add it to `smex-data'.
+ (if smex-data
+ (setcdr (last smex-data) (list command-item))
+ (setq smex-data (list command-item)))
+ 1))))
+
+(defun smex-sort-item-at (n)
+ "Sorts item at position N in `smex-cache'."
+ (let* ((command-cell (nthcdr n smex-cache))
+ (command-item (car command-cell)))
+ (let ((insert-at (smex-detect-position
+ command-cell
+ (lambda (cell)
+ (smex-sorting-rules command-item (car cell))))))
+ ;; TODO: Should we handle the case of 'insert-at' being nil?
+ ;; This will never happen in practice.
+ (when (> insert-at 1)
+ (setq command-cell (smex-remove-nth-cell n smex-cache))
+ ;; smex-cache just got shorter by one element, so subtract '1' from insert-at.
+ (setq insert-at (+ n (- insert-at 1)))
+ (smex-insert-cell command-cell insert-at smex-cache)
+
+ ;; Repeat the same for the ido cache. DRY?
+ (setq command-cell (smex-remove-nth-cell n smex-ido-cache))
+ (smex-insert-cell command-cell insert-at smex-ido-cache)))))
+
+(defun smex-detect-position (cell function)
+ "Detects, relatively to CELL, the position of the cell
+on which FUNCTION returns true.
+Only checks cells after CELL, starting with the cell right after CELL.
+Returns nil when reaching the end of the list."
+ (let ((pos 1))
+ (catch 'break
+ (while t
+ (setq cell (cdr cell))
+ (if (not cell)
+ (throw 'break nil)
+ (if (funcall function cell) (throw 'break pos))
+ (setq pos (1+ pos)))))))
+
+(defun smex-remove-nth-cell (n list)
+ "Removes and returns the Nth cell in LIST."
+ (let* ((previous-cell (nthcdr (- n 1) list))
+ (result (cdr previous-cell)))
+ (setcdr previous-cell (cdr result))
+ result))
+
+(defun smex-insert-cell (new-cell n list)
+ "Inserts cell at position N in LIST."
+ (let* ((cell (nthcdr (- n 1) list))
+ (next-cell (cdr cell)))
+ (setcdr (setcdr cell new-cell) next-cell)))
+
+;;--------------------------------------------------------------------------------
+;; Help and Reference
+
+(defun smex-do-with-selected-item (fn)
+ (setq smex-custom-action fn)
+ (ido-exit-minibuffer))
+
+(defun smex-describe-function ()
+ (interactive)
+ (smex-do-with-selected-item (lambda (chosen)
+ (describe-function chosen)
+ (pop-to-buffer "*Help*"))))
+
+(defun smex-where-is ()
+ (interactive)
+ (smex-do-with-selected-item 'where-is))
+
+(defun smex-find-function ()
+ (interactive)
+ (smex-do-with-selected-item 'find-function))
+
+(defun smex-extract-commands-from-keymap (map)
+ (let (commands)
+ (smex-parse-keymap map commands)
+ commands))
+
+(defun smex-parse-keymap (map commands)
+ (map-keymap (lambda (_binding element)
+ (if (and (listp element) (eq 'keymap (car element)))
+ (smex-parse-keymap element commands)
+ ;; Strings are commands, too. Reject them.
+ (if (and (symbolp element) (commandp element))
+ (push element commands))))
+ map))
+
+(defun smex-extract-commands-from-features (mode)
+ (let ((library-path (symbol-file mode))
+ (mode-name (symbol-name mode))
+ commands)
+
+ (string-match "\\(.+?\\)\\(-mode\\)?$" mode-name)
+ ;; 'lisp-mode' -> 'lisp'
+ (setq mode-name (match-string 1 mode-name))
+ (if (string= mode-name "c") (setq mode-name "cc"))
+ (setq mode-name (regexp-quote mode-name))
+
+ (dolist (feature load-history)
+ (let ((feature-path (car feature)))
+ (when (and feature-path (or (equal feature-path library-path)
+ (string-match mode-name (file-name-nondirectory
+ feature-path))))
+ (dolist (item (cdr feature))
+ (if (and (listp item) (eq 'defun (car item)))
+ (let ((function (cdr item)))
+ (when (commandp function)
+ (setq commands (append commands (list function))))))))))
+ commands))
+
+(defun smex-show-unbound-commands ()
+ "Shows unbound commands in a new buffer,
+sorted by frequency of use."
+ (interactive)
+ (setq smex-data (sort smex-data 'smex-sorting-rules))
+ (let ((unbound-commands (delq nil
+ (mapcar (lambda (command-item)
+ (unless (where-is-internal (car command-item))
+ command-item))
+ smex-data))))
+ (view-buffer-other-window "*Smex: Unbound Commands*")
+ (setq buffer-read-only t)
+ (let ((inhibit-read-only t))
+ (erase-buffer)
+ (smex-pp unbound-commands))
+ (set-buffer-modified-p nil)
+ (goto-char (point-min))))
+
+;; A copy of `ido-pp' that's compatible with lexical bindings
+(defun smex-pp* (list list-name)
+ (let ((print-level nil) (eval-expression-print-level nil)
+ (print-length nil) (eval-expression-print-length nil))
+ (insert "\n;; ----- " list-name " -----\n(\n ")
+ (while list
+ (let* ((elt (car list))
+ (s (if (consp elt) (car elt) elt)))
+ (if (and (stringp s) (= (length s) 0))
+ (setq s nil))
+ (if s
+ (prin1 elt (current-buffer)))
+ (if (and (setq list (cdr list)) s)
+ (insert "\n "))))
+ (insert "\n)\n")))
+
+(provide 'smex)
+;;; smex.el ends here
diff --git a/elpa/smex-20151212.2209/smex.elc b/elpa/smex-20151212.2209/smex.elc
new file mode 100644
index 0000000..16ad977
--- /dev/null
+++ b/elpa/smex-20151212.2209/smex.elc
Binary files differ
diff --git a/elpa/spinner-1.7.4.signed b/elpa/spinner-1.7.4.signed
new file mode 100644
index 0000000..a27698f
--- /dev/null
+++ b/elpa/spinner-1.7.4.signed
@@ -0,0 +1 @@
+Good signature from 066DAFCB81E42C40 GNU ELPA Signing Agent (2019) <elpasign@elpa.gnu.org> (trust undefined) created at 2021-07-02T14:40:02+0530 using RSA \ No newline at end of file
diff --git a/elpa/spinner-1.7.4/README.org b/elpa/spinner-1.7.4/README.org
new file mode 100644
index 0000000..06c7b32
--- /dev/null
+++ b/elpa/spinner-1.7.4/README.org
@@ -0,0 +1,76 @@
+#+TITLE: spinner.el
+
+Add spinners and progress-bars to the mode-line for ongoing operations.
+
+[[file:some-spinners.gif]]
+
+[[file:all-spinners.gif]]
+
+* Usage
+
+First of all, don’t forget to add ~(spinner "VERSION")~ to your package’s dependencies.
+
+** Major-modes
+1. Just call ~(spinner-start)~ and a spinner will be added to the mode-line.
+2. Call ~(spinner-stop)~ on the same buffer when you want to remove it.
+
+The default spinner is a line drawing that rotates. You can pass an
+argument to ~spinner-start~ to specify which spinner you want. All
+possibilities are listed in the ~spinner-types~ variable, but here are
+a few examples for you to try:
+
+- ~(spinner-start 'vertical-breathing 10)~
+- ~(spinner-start 'minibox)~
+- ~(spinner-start 'moon)~
+- ~(spinner-start 'triangle)~
+
+You can also define your own as a vector of strings (see the examples
+in ~spinner-types~).
+
+** Minor-modes
+Minor-modes can create a spinner with ~spinner-create~ and then add it
+to their mode-line lighter. They can then start the spinner by setting
+a variable and calling ~spinner-start-timer~. Finally, they can stop
+the spinner (and the timer) by just setting the same variable to nil.
+
+Here’s an example for a minor-mode named ~foo~. Assuming that
+~foo--lighter~ is used as the mode-line lighter, the following code
+will add an *inactive* global spinner to the mode-line.
+#+begin_src emacs-lisp
+(defvar foo--spinner (spinner-create 'rotating-line))
+(defconst foo--lighter
+ '(" foo" (:eval (spinner-print foo--spinner))))
+#+end_src
+
+1. To activate the spinner, just call ~(spinner-start foo--spinner)~.
+ It will show up on the mode-line and start animating.
+2. To get rid of it, call ~(spinner-stop foo--spinner)~. It will then
+ disappear again.
+
+Some minor-modes will need spinners to be buffer-local. To achieve
+that, just make the ~foo--spinner~ variable buffer-local and use the
+third argument of the ~spinner-create~ function. The snippet below is an example.
+
+#+begin_src emacs-lisp
+(defvar-local foo--spinner nil)
+(defconst foo--lighter
+ '(" foo" (:eval (spinner-print foo--spinner))))
+(defun foo--start-spinner ()
+ "Create and start a spinner on this buffer."
+ (unless foo--spinner
+ (setq foo--spinner (spinner-create 'moon t)))
+ (spinner-start foo--spinner))
+#+end_src
+
+1. To activate the spinner, just call ~(foo--start-spinner)~.
+2. To get rid of it, call ~(spinner-stop foo--spinner)~.
+
+This will use the ~moon~ spinner, but you can use any of the names
+defined in the ~spinner-types~ variable or even define your own.
+
+* Extra options
+
+Both ~spinner-start~ and ~spinner-create~ take extra options to configure the spinner, these are:
+
+- ~FPS~: The number of frames to display per second. Defaults to ~spinner-frames-per-second~.
+- ~DELAY~: After starting a spinner, it still won’t be displayed for this many seconds.
diff --git a/elpa/spinner-1.7.4/all-spinners.gif b/elpa/spinner-1.7.4/all-spinners.gif
new file mode 100644
index 0000000..5540b68
--- /dev/null
+++ b/elpa/spinner-1.7.4/all-spinners.gif
Binary files differ
diff --git a/elpa/spinner-1.7.4/some-spinners.gif b/elpa/spinner-1.7.4/some-spinners.gif
new file mode 100644
index 0000000..a8028e7
--- /dev/null
+++ b/elpa/spinner-1.7.4/some-spinners.gif
Binary files differ
diff --git a/elpa/spinner-1.7.4/spinner-autoloads.el b/elpa/spinner-1.7.4/spinner-autoloads.el
new file mode 100644
index 0000000..f57785e
--- /dev/null
+++ b/elpa/spinner-1.7.4/spinner-autoloads.el
@@ -0,0 +1,77 @@
+;;; spinner-autoloads.el --- automatically extracted autoloads -*- lexical-binding: t -*-
+;;
+;;; Code:
+
+(add-to-list 'load-path (directory-file-name
+ (or (file-name-directory #$) (car load-path))))
+
+
+;;;### (autoloads nil "spinner" "spinner.el" (0 0 0 0))
+;;; Generated autoloads from spinner.el
+
+(autoload 'spinner-create "spinner" "\
+Create a spinner of the given TYPE.
+The possible TYPEs are described in `spinner--type-to-frames'.
+
+FPS, if given, is the number of desired frames per second.
+Default is `spinner-frames-per-second'.
+
+If BUFFER-LOCAL is non-nil, the spinner will be automatically
+deactivated if the buffer is killed. If BUFFER-LOCAL is a
+buffer, use that instead of current buffer.
+
+When started, in order to function properly, the spinner runs a
+timer which periodically calls `force-mode-line-update' in the
+current buffer. If BUFFER-LOCAL was set at creation time, then
+`force-mode-line-update' is called in that buffer instead. When
+the spinner is stopped, the timer is deactivated.
+
+DELAY, if given, is the number of seconds to wait after starting
+the spinner before actually displaying it. It is safe to cancel
+the spinner before this time, in which case it won't display at
+all.
+
+\(fn &optional TYPE BUFFER-LOCAL FPS DELAY)" nil nil)
+
+(autoload 'spinner-start "spinner" "\
+Start a mode-line spinner of given TYPE-OR-OBJECT.
+If TYPE-OR-OBJECT is an object created with `make-spinner',
+simply activate it. This method is designed for minor modes, so
+they can use the spinner as part of their lighter by doing:
+ '(:eval (spinner-print THE-SPINNER))
+To stop this spinner, call `spinner-stop' on it.
+
+If TYPE-OR-OBJECT is anything else, a buffer-local spinner is
+created with this type, and it is displayed in the
+`mode-line-process' of the buffer it was created it. Both
+TYPE-OR-OBJECT and FPS are passed to `make-spinner' (which see).
+To stop this spinner, call `spinner-stop' in the same buffer.
+
+Either way, the return value is a function which can be called
+anywhere to stop this spinner. You can also call `spinner-stop'
+in the same buffer where the spinner was created.
+
+FPS, if given, is the number of desired frames per second.
+Default is `spinner-frames-per-second'.
+
+DELAY, if given, is the number of seconds to wait until actually
+displaying the spinner. It is safe to cancel the spinner before
+this time, in which case it won't display at all.
+
+\(fn &optional TYPE-OR-OBJECT FPS DELAY)" nil nil)
+
+(register-definition-prefixes "spinner" '("spinner-"))
+
+;;;***
+
+;;;### (autoloads nil nil ("spinner-pkg.el") (0 0 0 0))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; coding: utf-8
+;; End:
+;;; spinner-autoloads.el ends here
diff --git a/elpa/spinner-1.7.4/spinner-pkg.el b/elpa/spinner-1.7.4/spinner-pkg.el
new file mode 100644
index 0000000..2f4bbb7
--- /dev/null
+++ b/elpa/spinner-1.7.4/spinner-pkg.el
@@ -0,0 +1,2 @@
+;; Generated package description from spinner.el -*- no-byte-compile: t -*-
+(define-package "spinner" "1.7.4" "Add spinners and progress-bars to the mode-line for ongoing operations" '((emacs "24.3")) :keywords '("processes" "mode-line") :authors '(("Artur Malabarba" . "emacs@endlessparentheses.com")) :maintainer '("Artur Malabarba" . "emacs@endlessparentheses.com") :url "https://github.com/Malabarba/spinner.el")
diff --git a/elpa/spinner-1.7.4/spinner.el b/elpa/spinner-1.7.4/spinner.el
new file mode 100644
index 0000000..6be8f13
--- /dev/null
+++ b/elpa/spinner-1.7.4/spinner.el
@@ -0,0 +1,340 @@
+;;; spinner.el --- Add spinners and progress-bars to the mode-line for ongoing operations -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2015 Free Software Foundation, Inc.
+
+;; Author: Artur Malabarba <emacs@endlessparentheses.com>
+;; Version: 1.7.4
+;; Package-Requires: ((emacs "24.3"))
+;; URL: https://github.com/Malabarba/spinner.el
+;; Keywords: processes mode-line
+
+;; 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:
+;;
+;; 1 Usage
+;; ═══════
+;;
+;; First of all, don’t forget to add `(spinner "VERSION")' to your
+;; package’s dependencies.
+;;
+;;
+;; 1.1 Major-modes
+;; ───────────────
+;;
+;; 1. Just call `(spinner-start)' and a spinner will be added to the
+;; mode-line.
+;; 2. Call `(spinner-stop)' on the same buffer when you want to remove
+;; it.
+;;
+;; The default spinner is a line drawing that rotates. You can pass an
+;; argument to `spinner-start' to specify which spinner you want. All
+;; possibilities are listed in the `spinner-types' variable, but here are
+;; a few examples for you to try:
+;;
+;; • `(spinner-start 'vertical-breathing 10)'
+;; • `(spinner-start 'minibox)'
+;; • `(spinner-start 'moon)'
+;; • `(spinner-start 'triangle)'
+;;
+;; You can also define your own as a vector of strings (see the examples
+;; in `spinner-types').
+;;
+;;
+;; 1.2 Minor-modes
+;; ───────────────
+;;
+;; Minor-modes can create a spinner with `spinner-create' and then add it
+;; to their mode-line lighter. They can then start the spinner by setting
+;; a variable and calling `spinner-start-timer'. Finally, they can stop
+;; the spinner (and the timer) by just setting the same variable to nil.
+;;
+;; Here’s an example for a minor-mode named `foo'. Assuming that
+;; `foo--lighter' is used as the mode-line lighter, the following code
+;; will add an *inactive* global spinner to the mode-line.
+;; ┌────
+;; │ (defvar foo--spinner (spinner-create 'rotating-line))
+;; │ (defconst foo--lighter
+;; │ '(" foo" (:eval (spinner-print foo--spinner))))
+;; └────
+;;
+;; 1. To activate the spinner, just call `(spinner-start foo--spinner)'.
+;; It will show up on the mode-line and start animating.
+;; 2. To get rid of it, call `(spinner-stop foo--spinner)'. It will then
+;; disappear again.
+;;
+;; Some minor-modes will need spinners to be buffer-local. To achieve
+;; that, just make the `foo--spinner' variable buffer-local and use the
+;; third argument of the `spinner-create' function. The snippet below is an
+;; example.
+;;
+;; ┌────
+;; │ (defvar-local foo--spinner nil)
+;; │ (defconst foo--lighter
+;; │ '(" foo" (:eval (spinner-print foo--spinner))))
+;; │ (defun foo--start-spinner ()
+;; │ "Create and start a spinner on this buffer."
+;; │ (unless foo--spinner
+;; │ (setq foo--spinner (spinner-create 'moon t)))
+;; │ (spinner-start foo--spinner))
+;; └────
+;;
+;; 1. To activate the spinner, just call `(foo--start-spinner)'.
+;; 2. To get rid of it, call `(spinner-stop foo--spinner)'.
+;;
+;; This will use the `moon' spinner, but you can use any of the names
+;; defined in the `spinner-types' variable or even define your own.
+
+
+;;; Code:
+(eval-when-compile
+ (require 'cl-lib))
+
+(defconst spinner-types
+ '((3-line-clock . ["┤" "┘" "┴" "└" "├" "┌" "┬" "┐"])
+ (2-line-clock . ["┘" "└" "┌" "┐"])
+ (flipping-line . ["_" "\\" "|" "/"])
+ (rotating-line . ["-" "\\" "|" "/"])
+ (progress-bar . ["[ ]" "[= ]" "[== ]" "[=== ]" "[====]" "[ ===]" "[ ==]" "[ =]"])
+ (progress-bar-filled . ["| |" "|█ |" "|██ |" "|███ |" "|████|" "| ███|" "| ██|" "| █|"])
+ (vertical-breathing . ["▁" "▂" "▃" "▄" "▅" "▆" "▇" "█" "▇" "▆" "▅" "▄" "▃" "▂" "▁" " "])
+ (vertical-rising . ["▁" "▄" "█" "▀" "▔"])
+ (horizontal-breathing . [" " "▏" "▎" "▍" "▌" "▋" "▊" "▉" "▉" "▊" "▋" "▌" "▍" "▎" "▏"])
+ (horizontal-breathing-long
+ . [" " "▎ " "▌ " "▊ " "█ " "█▎" "█▌" "█▊" "██" "█▊" "█▌" "█▎" "█ " "▊ " "▋ " "▌ " "▍ " "▎ " "▏ "])
+ (horizontal-moving . [" " "▌ " "█ " "▐▌" " █" " ▐"])
+ (minibox . ["▖" "▘" "▝" "▗"])
+ (triangle . ["◢" "◣" "◤" "◥"])
+ (box-in-box . ["◰" "◳" "◲" "◱"])
+ (box-in-circle . ["◴" "◷" "◶" "◵"])
+ (half-circle . ["◐" "◓" "◑" "◒"])
+ (moon . ["🌑" "🌘" "🌗" "🌖" "🌕" "🌔" "🌓" "🌒"]))
+ "Predefined alist of spinners.
+Each car is a symbol identifying the spinner, and each cdr is a
+vector, the spinner itself.")
+
+(defun spinner-make-progress-bar (width &optional char)
+ "Return a vector of strings of the given WIDTH.
+The vector is a valid spinner type and is similar to the
+`progress-bar' spinner, except without the surrounding brackets.
+CHAR is the character to use for the moving bar (defaults to =)."
+ (let ((whole-string (concat (make-string (1- width) ?\s)
+ (make-string 4 (or char ?=))
+ (make-string width ?\s))))
+ (apply #'vector (mapcar (lambda (n) (substring whole-string n (+ n width)))
+ (number-sequence (+ width 3) 0 -1)))))
+
+(defvar spinner-current nil
+ "Spinner currently being displayed on the `mode-line-process'.")
+(make-variable-buffer-local 'spinner-current)
+
+(defconst spinner--mode-line-construct
+ '(:eval (spinner-print spinner-current))
+ "Construct used to display a spinner in `mode-line-process'.")
+(put 'spinner--mode-line-construct 'risky-local-variable t)
+
+(defvar spinner-frames-per-second 10
+ "Default speed at which spinners spin, in frames per second.
+Each spinner can override this value.")
+
+
+;;; The spinner object.
+(defun spinner--type-to-frames (type)
+ "Return a vector of frames corresponding to TYPE.
+The list of possible built-in spinner types is given by the
+`spinner-types' variable, but you can also use your own (see
+below).
+
+If TYPE is nil, the frames of this spinner are given by the first
+element of `spinner-types'.
+If TYPE is a symbol, it specifies an element of `spinner-types'.
+If TYPE is 'random, use a random element of `spinner-types'.
+If TYPE is a list, it should be a list of symbols, and a random
+one is chosen as the spinner type.
+If TYPE is a vector, it should be a vector of strings and these
+are used as the spinner's frames. This allows you to make your
+own spinner animations."
+ (cond
+ ((vectorp type) type)
+ ((not type) (cdr (car spinner-types)))
+ ((eq type 'random)
+ (cdr (elt spinner-types
+ (random (length spinner-types)))))
+ ((listp type)
+ (cdr (assq (elt type (random (length type)))
+ spinner-types)))
+ ((symbolp type) (cdr (assq type spinner-types)))
+ (t (error "Unknown spinner type: %s" type))))
+
+(cl-defstruct (spinner
+ (:copier nil)
+ (:conc-name spinner--)
+ (:constructor make-spinner (&optional type buffer-local frames-per-second delay-before-start)))
+ (frames (spinner--type-to-frames type))
+ (counter 0)
+ (fps (or frames-per-second spinner-frames-per-second))
+ (timer (timer-create))
+ (active-p nil)
+ (buffer (when buffer-local
+ (if (bufferp buffer-local)
+ buffer-local
+ (current-buffer))))
+ (delay (or delay-before-start 0)))
+
+;;;###autoload
+(defun spinner-create (&optional type buffer-local fps delay)
+ "Create a spinner of the given TYPE.
+The possible TYPEs are described in `spinner--type-to-frames'.
+
+FPS, if given, is the number of desired frames per second.
+Default is `spinner-frames-per-second'.
+
+If BUFFER-LOCAL is non-nil, the spinner will be automatically
+deactivated if the buffer is killed. If BUFFER-LOCAL is a
+buffer, use that instead of current buffer.
+
+When started, in order to function properly, the spinner runs a
+timer which periodically calls `force-mode-line-update' in the
+current buffer. If BUFFER-LOCAL was set at creation time, then
+`force-mode-line-update' is called in that buffer instead. When
+the spinner is stopped, the timer is deactivated.
+
+DELAY, if given, is the number of seconds to wait after starting
+the spinner before actually displaying it. It is safe to cancel
+the spinner before this time, in which case it won't display at
+all."
+ (make-spinner type buffer-local fps delay))
+
+(defun spinner-print (spinner)
+ "Return a string of the current frame of SPINNER.
+If SPINNER is nil, just return nil.
+Designed to be used in the mode-line with:
+ (:eval (spinner-print some-spinner))"
+ (when (and spinner (spinner--active-p spinner))
+ (let ((frame (spinner--counter spinner)))
+ (when (>= frame 0)
+ (elt (spinner--frames spinner) frame)))))
+
+(defun spinner--timer-function (spinner)
+ "Function called to update SPINNER.
+If SPINNER is no longer active, or if its buffer has been killed,
+stop the SPINNER's timer."
+ (let ((buffer (spinner--buffer spinner)))
+ (if (or (not (spinner--active-p spinner))
+ (and buffer (not (buffer-live-p buffer))))
+ (spinner-stop spinner)
+ ;; Increment
+ (cl-callf (lambda (x) (if (< x 0)
+ (1+ x)
+ (% (1+ x) (length (spinner--frames spinner)))))
+ (spinner--counter spinner))
+ ;; Update mode-line.
+ (if (buffer-live-p buffer)
+ (with-current-buffer buffer
+ (force-mode-line-update))
+ (force-mode-line-update)))))
+
+(defun spinner--start-timer (spinner)
+ "Start a SPINNER's timer."
+ (let ((old-timer (spinner--timer spinner)))
+ (when (timerp old-timer)
+ (cancel-timer old-timer))
+
+ (setf (spinner--active-p spinner) t)
+
+ (unless (ignore-errors (> (spinner--fps spinner) 0))
+ (error "A spinner's FPS must be a positive number"))
+ (setf (spinner--counter spinner)
+ (round (- (* (or (spinner--delay spinner) 0)
+ (spinner--fps spinner)))))
+ ;; Create timer.
+ (let* ((repeat (/ 1.0 (spinner--fps spinner)))
+ (time (timer-next-integral-multiple-of-time (current-time) repeat))
+ ;; Create the timer as a lex variable so it can cancel itself.
+ (timer (spinner--timer spinner)))
+ (timer-set-time timer time repeat)
+ (timer-set-function timer #'spinner--timer-function (list spinner))
+ (timer-activate timer)
+ ;; Return a stopping function.
+ (lambda () (spinner-stop spinner)))))
+
+
+;;; The main functions
+;;;###autoload
+(defun spinner-start (&optional type-or-object fps delay)
+ "Start a mode-line spinner of given TYPE-OR-OBJECT.
+If TYPE-OR-OBJECT is an object created with `make-spinner',
+simply activate it. This method is designed for minor modes, so
+they can use the spinner as part of their lighter by doing:
+ '(:eval (spinner-print THE-SPINNER))
+To stop this spinner, call `spinner-stop' on it.
+
+If TYPE-OR-OBJECT is anything else, a buffer-local spinner is
+created with this type, and it is displayed in the
+`mode-line-process' of the buffer it was created it. Both
+TYPE-OR-OBJECT and FPS are passed to `make-spinner' (which see).
+To stop this spinner, call `spinner-stop' in the same buffer.
+
+Either way, the return value is a function which can be called
+anywhere to stop this spinner. You can also call `spinner-stop'
+in the same buffer where the spinner was created.
+
+FPS, if given, is the number of desired frames per second.
+Default is `spinner-frames-per-second'.
+
+DELAY, if given, is the number of seconds to wait until actually
+displaying the spinner. It is safe to cancel the spinner before
+this time, in which case it won't display at all."
+ (unless (spinner-p type-or-object)
+ ;; Choose type.
+ (if (spinner-p spinner-current)
+ (setf (spinner--frames spinner-current) (spinner--type-to-frames type-or-object))
+ (setq spinner-current (make-spinner type-or-object (current-buffer) fps delay)))
+ (setq type-or-object spinner-current)
+ ;; Maybe add to mode-line.
+ (unless (and (listp mode-line-process)
+ (memq 'spinner--mode-line-construct mode-line-process))
+ (setq mode-line-process
+ (list (or mode-line-process "")
+ 'spinner--mode-line-construct))))
+
+ ;; Create timer.
+ (when fps (setf (spinner--fps type-or-object) fps))
+ (when delay (setf (spinner--delay type-or-object) delay))
+ (spinner--start-timer type-or-object))
+
+(defun spinner-start-print (spinner)
+ "Like `spinner-print', but also start SPINNER if it's not active."
+ (unless (spinner--active-p spinner)
+ (spinner-start spinner))
+ (spinner-print spinner))
+
+(defun spinner-stop (&optional spinner)
+ "Stop SPINNER, defaulting to the current buffer's spinner.
+It is always safe to call this function, even if there is no
+active spinner."
+ (let ((spinner (or spinner spinner-current)))
+ (when (spinner-p spinner)
+ (let ((timer (spinner--timer spinner)))
+ (when (timerp timer)
+ (cancel-timer timer)))
+ (setf (spinner--active-p spinner) nil)
+ (force-mode-line-update))))
+
+(provide 'spinner)
+
+;; Local Variables:
+;; indent-tabs-mode: nil
+;; End:
+;;; spinner.el ends here
diff --git a/elpa/spinner-1.7.4/spinner.elc b/elpa/spinner-1.7.4/spinner.elc
new file mode 100644
index 0000000..d324196
--- /dev/null
+++ b/elpa/spinner-1.7.4/spinner.elc
Binary files differ
diff --git a/elpa/swiper-20220430.2247/swiper-autoloads.el b/elpa/swiper-20220430.2247/swiper-autoloads.el
new file mode 100644
index 0000000..0c2f916
--- /dev/null
+++ b/elpa/swiper-20220430.2247/swiper-autoloads.el
@@ -0,0 +1,58 @@
+;;; swiper-autoloads.el --- automatically extracted autoloads -*- lexical-binding: t -*-
+;;
+;;; Code:
+
+(add-to-list 'load-path (directory-file-name
+ (or (file-name-directory #$) (car load-path))))
+
+
+;;;### (autoloads nil "swiper" "swiper.el" (0 0 0 0))
+;;; Generated autoloads from swiper.el
+
+(autoload 'swiper-avy "swiper" "\
+Jump to one of the current swiper candidates with `avy'." t nil)
+
+(autoload 'swiper-backward "swiper" "\
+`isearch-backward' with an overview.
+When non-nil, INITIAL-INPUT is the initial search pattern.
+
+\(fn &optional INITIAL-INPUT)" t nil)
+
+(autoload 'swiper-thing-at-point "swiper" "\
+`swiper' with `ivy-thing-at-point'." t nil)
+
+(autoload 'swiper-all-thing-at-point "swiper" "\
+`swiper-all' with `ivy-thing-at-point'." t nil)
+
+(autoload 'swiper "swiper" "\
+`isearch-forward' with an overview.
+When non-nil, INITIAL-INPUT is the initial search pattern.
+
+\(fn &optional INITIAL-INPUT)" t nil)
+
+(autoload 'swiper-all "swiper" "\
+Run `swiper' for all open buffers.
+
+\(fn &optional INITIAL-INPUT)" t nil)
+
+(autoload 'swiper-isearch "swiper" "\
+A `swiper' that's not line-based.
+
+\(fn &optional INITIAL-INPUT)" t nil)
+
+(autoload 'swiper-isearch-backward "swiper" "\
+Like `swiper-isearch' but the first result is before the point.
+
+\(fn &optional INITIAL-INPUT)" t nil)
+
+(register-definition-prefixes "swiper" '("swiper-"))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; coding: utf-8
+;; End:
+;;; swiper-autoloads.el ends here
diff --git a/elpa/swiper-20220430.2247/swiper-pkg.el b/elpa/swiper-20220430.2247/swiper-pkg.el
new file mode 100644
index 0000000..290663e
--- /dev/null
+++ b/elpa/swiper-20220430.2247/swiper-pkg.el
@@ -0,0 +1,2 @@
+;;; Generated package description from swiper.el -*- no-byte-compile: t -*-
+(define-package "swiper" "20220430.2247" "Isearch with an overview. Oh, man!" '((emacs "24.5") (ivy "0.13.4")) :commit "8bf8027e4bd8c093bddb76a813952d2a0dcbf21d" :authors '(("Oleh Krehel" . "ohwoeowho@gmail.com")) :maintainer '("Oleh Krehel" . "ohwoeowho@gmail.com") :keywords '("matching") :url "https://github.com/abo-abo/swiper")
diff --git a/elpa/swiper-20220430.2247/swiper.el b/elpa/swiper-20220430.2247/swiper.el
new file mode 100644
index 0000000..f1ea30a
--- /dev/null
+++ b/elpa/swiper-20220430.2247/swiper.el
@@ -0,0 +1,1759 @@
+;;; swiper.el --- Isearch with an overview. Oh, man! -*- lexical-binding: t -*-
+
+;; Copyright (C) 2015-2021 Free Software Foundation, Inc.
+
+;; Author: Oleh Krehel <ohwoeowho@gmail.com>
+;; URL: https://github.com/abo-abo/swiper
+;; Package-Version: 20220430.2247
+;; Package-Commit: 8bf8027e4bd8c093bddb76a813952d2a0dcbf21d
+;; Version: 0.13.4
+;; Package-Requires: ((emacs "24.5") (ivy "0.13.4"))
+;; Keywords: matching
+
+;; This file is part of GNU 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 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.
+
+;; For a full copy of the GNU General Public License
+;; see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This package gives an overview of the current regex search
+;; candidates. The search regex can be split into groups with a
+;; space. Each group is highlighted with a different face.
+;;
+;; It can double as a quick `regex-builder', although only single
+;; lines will be matched.
+
+;;; Code:
+
+(require 'ivy)
+
+(defgroup swiper nil
+ "`isearch' with an overview."
+ :group 'matching
+ :prefix "swiper-")
+
+(defface swiper-match-face-1
+ '((t :inherit lazy-highlight))
+ "The background face for `swiper' matches."
+ :group 'ivy-faces)
+
+(defface swiper-match-face-2
+ '((t :inherit isearch))
+ "Face for `swiper' matches modulo 1."
+ :group 'ivy-faces)
+
+(defface swiper-match-face-3
+ '((t :inherit match))
+ "Face for `swiper' matches modulo 2."
+ :group 'ivy-faces)
+
+(defface swiper-match-face-4
+ '((t :inherit isearch-fail))
+ "Face for `swiper' matches modulo 3."
+ :group 'ivy-faces)
+
+(defface swiper-background-match-face-1
+ '((t :inherit swiper-match-face-1))
+ "The background face for non-current `swiper' matches."
+ :group 'ivy-faces)
+
+(defface swiper-background-match-face-2
+ '((t :inherit swiper-match-face-2))
+ "Face for non-current `swiper' matches modulo 1."
+ :group 'ivy-faces)
+
+(defface swiper-background-match-face-3
+ '((t :inherit swiper-match-face-3))
+ "Face for non-current `swiper' matches modulo 2."
+ :group 'ivy-faces)
+
+(defface swiper-background-match-face-4
+ '((t :inherit swiper-match-face-4))
+ "Face for non-current `swiper' matches modulo 3."
+ :group 'ivy-faces)
+
+(defface swiper-line-face
+ '((t :inherit highlight))
+ "Face for current `swiper' line."
+ :group 'ivy-faces)
+
+(defcustom swiper-faces '(swiper-match-face-1
+ swiper-match-face-2
+ swiper-match-face-3
+ swiper-match-face-4)
+ "List of `swiper' faces for group matches."
+ :group 'ivy-faces
+ :type '(repeat face))
+
+(defvar swiper-background-faces
+ '(swiper-background-match-face-1
+ swiper-background-match-face-2
+ swiper-background-match-face-3
+ swiper-background-match-face-4)
+ "Like `swiper-faces', but used for all matches except the current one.")
+
+(defun swiper--recompute-background-faces ()
+ (let ((faces '(swiper-background-match-face-1
+ swiper-background-match-face-2
+ swiper-background-match-face-3
+ swiper-background-match-face-4))
+ (colir-compose-method #'colir-compose-soft-light))
+ (cl-mapc (lambda (f1 f2)
+ (let* ((bg (face-background f1))
+ ;; FIXME: (colir-color-parse "color-22") is nil.
+ (bg (and bg (colir-color-parse bg))))
+ (when bg
+ (setq bg (colir-blend bg (colir-color-parse "#ffffff")))
+ (set-face-background f2 bg))))
+ swiper-faces
+ faces)))
+(swiper--recompute-background-faces)
+
+(defcustom swiper-min-highlight 2
+ "Only highlight matches for regexps at least this long."
+ :type 'integer)
+
+(defcustom swiper-include-line-number-in-search nil
+ "Include line number in text of search candidates."
+ :type 'boolean
+ :group 'swiper)
+
+(defcustom swiper-goto-start-of-match nil
+ "When non-nil, go to the start of the match, not its end.
+Treated as non-nil when searching backwards."
+ :type 'boolean
+ :group 'swiper)
+
+(defun swiper-C-s (&optional arg)
+ "Move cursor vertically down ARG candidates.
+If the input is empty, select the previous history element instead."
+ (interactive "p")
+ (if (string= ivy-text "")
+ (ivy-previous-history-element 1)
+ (ivy-next-line arg)))
+
+(defvar swiper-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map (kbd "C-s") 'swiper-C-s)
+ (define-key map (kbd "M-q") 'swiper-query-replace)
+ (define-key map (kbd "C-l") 'swiper-recenter-top-bottom)
+ (define-key map (kbd "C-'") 'swiper-avy)
+ (define-key map (kbd "C-7") 'swiper-mc)
+ (define-key map (kbd "C-c C-f") 'swiper-toggle-face-matching)
+ map)
+ "Keymap for swiper.")
+
+(defvar swiper--query-replace-overlays nil)
+
+(defun swiper--query-replace-updatefn ()
+ (let ((lisp (ignore-errors (nth 2 (query-replace-compile-replacement ivy-text t)))))
+ (dolist (ov swiper--query-replace-overlays)
+ (overlay-put
+ ov 'after-string
+ (propertize
+ (condition-case nil
+ (with-current-buffer (overlay-buffer ov)
+ (set-match-data (overlay-get ov 'md))
+ (if (consp lisp)
+ (eval lisp)
+ (match-substitute-replacement ivy-text)))
+ (error ivy-text))
+ 'face 'error)))))
+
+(defun swiper--query-replace-cleanup ()
+ (while swiper--query-replace-overlays
+ (delete-overlay (pop swiper--query-replace-overlays))))
+
+(defun swiper--query-replace-setup ()
+ (with-ivy-window
+ (let ((end (window-end (selected-window) t))
+ (re (ivy-re-to-str ivy-regex)))
+ (save-excursion
+ (beginning-of-line)
+ (while (re-search-forward re end t)
+ (let ((ov (make-overlay (1- (match-end 0)) (match-end 0)))
+ (md (match-data t)))
+ (overlay-put
+ ov 'matches
+ (mapcar
+ (lambda (x)
+ (list `(match-string ,x) (match-string x)))
+ (number-sequence 0 (1- (/ (length md) 2)))))
+ (overlay-put ov 'md md)
+ (push ov swiper--query-replace-overlays))
+ (unless (> (match-end 0) (match-beginning 0))
+ (forward-char)))))))
+
+(defun swiper-query-replace ()
+ "Start `query-replace' with string to replace from last search string."
+ (interactive)
+ (cond ((null (window-minibuffer-p))
+ (user-error "Should only be called in the minibuffer through `swiper-map'"))
+ ((string= "" ivy-text)
+ (user-error "Empty input"))
+ (t
+ (swiper--query-replace-setup)
+ (unwind-protect
+ (let* ((enable-recursive-minibuffers t)
+ (from (ivy-re-to-str ivy-regex))
+ (groups (number-sequence 1 ivy--subexps))
+ (default
+ (list
+ (mapconcat (lambda (i) (format "\\%d" i)) groups " ")
+ (format "\\,(concat %s)"
+ (if (<= ivy--subexps 1)
+ "\\&"
+ (mapconcat
+ (lambda (i) (format "\\%d" i))
+ groups
+ " \" \" ")))))
+ (to
+ (query-replace-compile-replacement
+ (ivy-read
+ (format "Query replace %s with: " from) nil
+ :def default
+ :caller 'swiper-query-replace)
+ t)))
+ (swiper--cleanup)
+ (ivy-exit-with-action
+ (lambda (_)
+ (with-ivy-window
+ (move-beginning-of-line 1)
+ (let ((inhibit-read-only t))
+ (perform-replace from to
+ t t nil))))))
+ (swiper--query-replace-cleanup)))))
+
+(ivy-configure 'swiper-query-replace
+ :update-fn #'swiper--query-replace-updatefn)
+(put 'swiper-query-replace 'no-counsel-M-x t)
+
+(defvar inhibit-message)
+
+(defun swiper-all-query-replace ()
+ "Start `query-replace' with string to replace from last search string."
+ (interactive)
+ (if (null (window-minibuffer-p))
+ (user-error
+ "Should only be called in the minibuffer through `swiper-all-map'")
+ (let* ((enable-recursive-minibuffers t)
+ (from (ivy--regex ivy-text))
+ (to (query-replace-read-to from "Query replace" t)))
+ (swiper--cleanup)
+ (ivy-exit-with-action
+ (lambda (_)
+ (let ((wnd-conf (current-window-configuration))
+ (inhibit-message t))
+ (unwind-protect
+ (dolist (cand ivy--old-cands)
+ (let ((buffer (get-text-property 0 'buffer cand)))
+ (switch-to-buffer buffer)
+ (goto-char (point-min))
+ (perform-replace from to t t nil)))
+ (set-window-configuration wnd-conf))))))))
+(put 'swiper-all-query-replace 'no-counsel-M-x t)
+
+(defvar avy-all-windows)
+(defvar avy-style)
+(defvar avy-keys)
+(declare-function avy--overlay-post "ext:avy")
+(declare-function avy-action-goto "ext:avy")
+(declare-function avy-candidate-beg "ext:avy")
+(declare-function avy--done "ext:avy")
+(declare-function avy--make-backgrounds "ext:avy")
+(declare-function avy-window-list "ext:avy")
+(declare-function avy-read "ext:avy")
+(declare-function avy-read-de-bruijn "ext:avy")
+(declare-function avy-tree "ext:avy")
+(declare-function avy-push-mark "ext:avy")
+(declare-function avy--remove-leading-chars "ext:avy")
+
+(defun swiper--avy-candidates ()
+ (let* (
+ ;; We'll have overlapping overlays, so we sort all the
+ ;; overlays in the visible region by their start, and then
+ ;; throw out non-Swiper overlays or overlapping Swiper
+ ;; overlays.
+ (visible-overlays (cl-sort (with-ivy-window
+ (overlays-in (window-start)
+ (window-end)))
+ #'< :key #'overlay-start))
+ (min-overlay-start 0)
+ (overlays-for-avy
+ (cl-remove-if-not
+ (lambda (ov)
+ (when (and (>= (overlay-start ov)
+ min-overlay-start)
+ (memq (overlay-get ov 'face)
+ (append swiper-faces swiper-background-faces)))
+ (setq min-overlay-start (overlay-start ov))))
+ visible-overlays))
+ (offset (if (eq (ivy-state-caller ivy-last) 'swiper) 1 0)))
+ (nconc
+ (mapcar (lambda (ov)
+ (cons (overlay-start ov)
+ (overlay-get ov 'window)))
+ overlays-for-avy)
+ (save-excursion
+ (save-restriction
+ (narrow-to-region (window-start) (window-end))
+ (goto-char (point-min))
+ (forward-line)
+ (let ((win (selected-window))
+ cands)
+ (while (not (eobp))
+ (push (cons (+ (point) offset) win)
+ cands)
+ (forward-line))
+ cands))))))
+
+(defun swiper--avy-candidate ()
+ (let ((candidates (swiper--avy-candidates))
+ (avy-all-windows nil))
+ (unwind-protect
+ (prog2
+ (avy--make-backgrounds
+ (append (avy-window-list)
+ (list (ivy-state-window ivy-last))))
+ (if (eq avy-style 'de-bruijn)
+ (avy-read-de-bruijn candidates avy-keys)
+ (avy-read (avy-tree candidates avy-keys)
+ #'avy--overlay-post
+ #'avy--remove-leading-chars))
+ (avy-push-mark))
+ (avy--done))))
+
+(defun swiper--avy-index (pos)
+ "Return `ivy--index' for `avy' candidate at minibuffer POS."
+ ;; Position in original buffer.
+ (let ((opos (get-text-property pos 'point)))
+ (or
+ ;; Find `swiper-isearch' index based on buffer position.
+ (and opos (cl-position opos ivy--all-candidates))
+ ;; Find `swiper' index based on line number.
+ (let ((nlines (count-lines (point-min) (point-max))))
+ (+ (car (ivy--minibuffer-index-bounds
+ ivy--index ivy--length ivy-height))
+ (line-number-at-pos pos)
+ (if (or (= nlines (1+ ivy-height))
+ (< ivy--length ivy-height))
+ 0
+ (- ivy-height nlines))
+ -2)))))
+
+(defun swiper--avy-goto (candidate)
+ (cond ((let ((win (cdr-safe candidate)))
+ (and win (window-minibuffer-p win)))
+ (setq ivy--index (swiper--avy-index (car candidate)))
+ (ivy--exhibit)
+ (ivy-done)
+ (ivy-call))
+ ((or (consp candidate)
+ (number-or-marker-p candidate))
+ (ivy-quit-and-run
+ (avy-action-goto (avy-candidate-beg candidate))))))
+
+;;;###autoload
+(defun swiper-avy ()
+ "Jump to one of the current swiper candidates with `avy'."
+ (interactive)
+ (unless (require 'avy nil 'noerror)
+ (user-error "Package avy isn't installed"))
+ (cl-case (length ivy-text)
+ (0
+ (user-error "Need at least one char of input"))
+ (1
+ ;; FIXME: `swiper--update-input-ivy' expects string candidates,
+ ;; but `swiper-isearch' now uses buffer positions.
+ (when (stringp (ivy-state-current ivy-last))
+ (let ((swiper-min-highlight 1))
+ (swiper--update-input-ivy)))))
+ (swiper--avy-goto (swiper--avy-candidate)))
+
+(declare-function mc/create-fake-cursor-at-point "ext:multiple-cursors-core")
+(declare-function multiple-cursors-mode "ext:multiple-cursors-core")
+
+(defun swiper-mc ()
+ "Create a fake cursor for each `swiper' candidate.
+Make sure `swiper-mc' is on `mc/cmds-to-run-once' list."
+ (interactive)
+ (unless (require 'multiple-cursors nil t)
+ (error "Multiple-cursors isn't installed"))
+ (unless (window-minibuffer-p)
+ (error "Call me only from `swiper'"))
+ (let ((cands (nreverse ivy--old-cands))
+ (action (ivy--get-action ivy-last)))
+ (unless (string= ivy-text "")
+ (ivy-exit-with-action
+ (lambda (_)
+ (let (cand)
+ (while (setq cand (pop cands))
+ (funcall action cand)
+ (when cands
+ (mc/create-fake-cursor-at-point))))
+ (multiple-cursors-mode 1))))))
+
+(defvar swiper--current-window-start nil
+ "Store `window-start' to restore it later.
+This prevents a \"jumping\" behavior which occurs when variables
+such as `scroll-conservatively' are set to a high value.")
+
+(defun swiper-recenter-top-bottom (&optional arg)
+ "Call (`recenter-top-bottom' ARG)."
+ (interactive "P")
+ (with-ivy-window
+ (recenter-top-bottom arg)
+ (setq swiper--current-window-start (window-start))))
+
+(defvar swiper-font-lock-exclude
+ '(Man-mode
+ adoc-mode
+ bbdb-mode
+ bongo-library-mode
+ bongo-mode
+ bongo-playlist-mode
+ bookmark-bmenu-mode
+ circe-channel-mode
+ circe-query-mode
+ circe-server-mode
+ deadgrep-mode
+ debbugs-gnu-mode
+ dired-mode
+ elfeed-search-mode
+ elfeed-show-mode
+ emms-playlist-mode
+ emms-stream-mode
+ erc-mode
+ eshell-mode
+ eww-mode
+ forth-block-mode
+ forth-mode
+ fundamental-mode
+ gnus-article-mode
+ gnus-group-mode
+ gnus-summary-mode
+ help-mode
+ helpful-mode
+ jabber-chat-mode
+ magit-popup-mode
+ matrix-client-mode
+ matrix-client-room-list-mode
+ mu4e-headers-mode
+ mu4e-view-mode
+ nix-mode
+ notmuch-search-mode
+ notmuch-tree-mode
+ occur-edit-mode
+ occur-mode
+ org-agenda-mode
+ package-menu-mode
+ rcirc-mode
+ sauron-mode
+ sieve-mode
+ treemacs-mode
+ twittering-mode
+ vc-dir-mode
+ w3m-mode
+ woman-mode
+ xref--xref-buffer-mode)
+ "List of major-modes that are incompatible with `font-lock-ensure'.")
+
+(defun swiper-font-lock-ensure-p ()
+ "Return non-nil if we should `font-lock-ensure'."
+ (or (derived-mode-p 'magit-mode)
+ (bound-and-true-p magit-blame-mode)
+ (memq major-mode swiper-font-lock-exclude)
+ (not (derived-mode-p 'prog-mode))))
+
+(defun swiper-font-lock-ensure ()
+ "Ensure the entire buffer is highlighted."
+ (unless (swiper-font-lock-ensure-p)
+ (unless (or (> (buffer-size) 100000) (null font-lock-mode))
+ (if (fboundp 'font-lock-ensure)
+ ;; Added in Emacs 25.1.
+ (font-lock-ensure)
+ (with-no-warnings (font-lock-fontify-buffer))))))
+
+(defvar swiper--format-spec ""
+ "Store the current candidates format spec.")
+
+(defvar swiper--width nil
+ "Store the number of digits needed for the longest line number.")
+
+(defvar swiper-use-visual-line nil
+ "When non-nil, use `line-move' instead of `forward-line'.")
+
+(defvar dired-isearch-filenames)
+(declare-function dired-move-to-filename "dired")
+
+(defun swiper--line ()
+ (let* ((beg (cond ((and (eq major-mode 'dired-mode)
+ (bound-and-true-p dired-isearch-filenames))
+ (dired-move-to-filename)
+ (point))
+ (swiper-use-visual-line
+ (save-excursion
+ (beginning-of-visual-line)
+ (point)))
+ (t
+ (point))))
+ (end (if swiper-use-visual-line
+ (save-excursion
+ (end-of-visual-line)
+ (point))
+ (line-end-position))))
+
+ (concat
+ " "
+ (buffer-substring beg end))))
+
+(defvar swiper-use-visual-line-p
+ (lambda (n-lines)
+ (and visual-line-mode
+ ;; super-slow otherwise
+ (< (buffer-size) 20000)
+ (< n-lines 400)))
+ "A predicate that decides whether `line-move' or `forward-line' is used.
+Note that `line-move' can be very slow.")
+
+(defun swiper--candidates (&optional numbers-width)
+ "Return a list of this buffer lines.
+
+NUMBERS-WIDTH, when specified, is used for width spec of line
+numbers; replaces calculating the width from buffer line count."
+ (let* ((inhibit-field-text-motion t)
+ (n-lines (count-lines (point-min) (point-max))))
+ (if (funcall swiper-use-visual-line-p n-lines)
+ (progn
+ (when (eq major-mode 'org-mode)
+ (require 'outline)
+ (if (fboundp 'outline-show-all)
+ ;; Added in Emacs 25.1.
+ (outline-show-all)
+ (with-no-warnings
+ (show-all))))
+ (setq swiper-use-visual-line t))
+ (setq swiper-use-visual-line nil))
+ (unless (zerop n-lines)
+ (setq swiper--width (or numbers-width
+ (1+ (floor (log n-lines 10)))))
+ (setq swiper--format-spec
+ (format "%%-%dd " swiper--width))
+ (let ((line-number 1)
+ (advancer (if swiper-use-visual-line
+ (lambda (arg) (line-move arg t))
+ #'forward-line))
+ candidates)
+ (save-excursion
+ (goto-char (point-min))
+ (swiper-font-lock-ensure)
+ (while (< (point) (point-max))
+ (when (swiper-match-usable-p)
+ (let ((str (swiper--line)))
+ (setq str (ivy-cleanup-string str))
+ (let ((line-number-str
+ (format swiper--format-spec line-number)))
+ (if swiper-include-line-number-in-search
+ (setq str (concat line-number-str str))
+ (put-text-property
+ 0 1 'display line-number-str str))
+ (put-text-property
+ 0 1 'swiper-line-number line-number str))
+ (push str candidates)))
+ (funcall advancer 1)
+ (cl-incf line-number))
+ (nreverse candidates))))))
+
+(defvar swiper--opoint 1
+ "The point when `swiper' starts.")
+
+;;;###autoload
+(defun swiper-backward (&optional initial-input)
+ "`isearch-backward' with an overview.
+When non-nil, INITIAL-INPUT is the initial search pattern."
+ (interactive)
+ (let ((ivy-index-functions-alist
+ '((swiper . ivy-recompute-index-swiper-backward))))
+ (swiper initial-input)))
+
+;;;###autoload
+(defun swiper-thing-at-point ()
+ "`swiper' with `ivy-thing-at-point'."
+ (interactive)
+ (let ((thing (ivy-thing-at-point)))
+ (when (use-region-p)
+ (deactivate-mark))
+ (swiper (regexp-quote thing))))
+
+;;;###autoload
+(defun swiper-all-thing-at-point ()
+ "`swiper-all' with `ivy-thing-at-point'."
+ (interactive)
+ (let ((thing (ivy-thing-at-point)))
+ (when (use-region-p)
+ (deactivate-mark))
+ (swiper-all (regexp-quote thing))))
+
+(defun swiper--extract-matches (regex cands)
+ "Extract captured REGEX groups from CANDS."
+ (let (res)
+ (dolist (cand cands)
+ (setq cand (substring cand 1))
+ (when (string-match regex cand)
+ (push (mapconcat (lambda (n) (match-string-no-properties n cand))
+ (number-sequence
+ 1
+ (/ (- (length (match-data)) 2) 2))
+ " ")
+ res)))
+ (nreverse res)))
+
+(defun swiper--occur-cands (fname cands)
+ (when cands
+ (with-current-buffer (ivy-state-buffer ivy-last)
+ (when (eq (ivy-state-caller ivy-last) 'swiper-isearch)
+ (setq cands (mapcar #'swiper--line-at-point cands)))
+ (let* ((pt-min (point-min))
+ (line-delta
+ (save-restriction
+ (widen)
+ (1- (line-number-at-pos pt-min))))
+ (lines
+ (if (eq (ivy-state-caller ivy-last) 'swiper-isearch)
+ (swiper--isearch-occur-cands cands)
+ (mapcar (lambda (s)
+ (let ((n (swiper--line-number s)))
+ (setq s (substring s 1))
+ (add-text-properties 0 1 (list 'swiper-line-number n) s)
+ (cons n s)))
+ cands)))
+ (offset (+ (length fname) 2)))
+ (mapcar (lambda (x)
+ (let ((nn (number-to-string
+ (+ (car x) line-delta))))
+ (remove-text-properties 0 1 '(display) (cdr x))
+ (put-text-property 0 (length nn) 'face 'ivy-grep-line-number nn)
+ (put-text-property 0 1 'offset (+ offset (length nn)) fname)
+ (format "%s:%s:%s" fname nn (cdr x))))
+ lines)))))
+
+(defun swiper--isearch-occur-cands (cands)
+ (let* ((last-pt (get-text-property 0 'point (car cands)))
+ (line (1+ (line-number-at-pos last-pt)))
+ res pt)
+ (dolist (cand cands)
+ (setq pt (get-text-property 0 'point cand))
+ (cl-incf line (1- (count-lines last-pt pt)))
+ (push (cons line cand) res)
+ (setq last-pt pt))
+ (nreverse res)))
+
+(defun swiper--occur-insert-lines (cands)
+ (let ((inhibit-read-only t))
+ ;; Need precise number of header lines for `wgrep' to work.
+ (insert (format "-*- mode:grep; default-directory: %S -*-\n\n\n"
+ default-directory))
+ (insert (format "%d candidates:\n" (length cands)))
+ (ivy--occur-insert-lines cands)
+ (goto-char (point-min))
+ (forward-line 4)))
+
+(defun swiper--occur-buffer ()
+ (let ((buffer (ivy-state-buffer ivy-last)))
+ (unless (buffer-live-p buffer)
+ (setq buffer
+ (setf (ivy-state-buffer ivy-last)
+ (find-file-noselect
+ (plist-get (ivy-state-extra-props ivy-last) :fname))))
+ (save-selected-window
+ (pop-to-buffer buffer))
+ (setf (ivy-state-window ivy-last) (selected-window)))
+ buffer))
+
+(defun swiper-occur (&optional cands)
+ "Generate a custom occur buffer for `swiper'.
+When capture groups are present in the input, print them instead of lines."
+ (setq cands (or ivy-marked-candidates cands))
+ (let* ((buffer (swiper--occur-buffer))
+ (fname (propertize
+ (with-ivy-window
+ (if (buffer-file-name buffer)
+ (file-name-nondirectory
+ (buffer-file-name buffer))
+ (buffer-name buffer)))
+ 'face
+ 'ivy-grep-info))
+ (re
+ (progn
+ (string-match "\"\\(.*\\)\"" (buffer-name))
+ (ivy-set-text (match-string 1 (buffer-name)))
+ (mapconcat #'identity (ivy--split ivy-text) ".*?")))
+ (cands
+ (swiper--occur-cands
+ fname
+ (or cands
+ (save-window-excursion
+ (switch-to-buffer buffer)
+ (if (eq (ivy-state-caller ivy-last) 'swiper)
+ (let ((ivy--regex-function 'swiper--re-builder))
+ (setq ivy--old-re nil)
+ (ivy--filter re (swiper--candidates)))
+ (swiper-isearch-function ivy-text)))))))
+ (if (string-match-p "\\\\(" re)
+ (insert
+ (mapconcat #'identity
+ (swiper--extract-matches
+ re (with-current-buffer buffer
+ (swiper--candidates)))
+ "\n"))
+ (unless (eq major-mode 'ivy-occur-grep-mode)
+ (ivy-occur-grep-mode)
+ (font-lock-mode -1))
+ (swiper--occur-insert-lines
+ (mapcar (lambda (cand) (concat "./" cand)) cands)))))
+
+(declare-function evil-set-jump "ext:evil-jumps")
+
+(defvar swiper--current-line nil)
+(defvar swiper--current-match-start nil)
+(defvar swiper--point-min nil)
+(defvar swiper--point-max nil)
+(defvar swiper--reveal-mode nil)
+
+(defun swiper--init ()
+ "Perform initialization common to both completion methods."
+ (setq swiper--current-line nil)
+ (setq swiper--current-match-start nil)
+ (setq swiper--current-window-start nil)
+ (setq swiper--opoint (point))
+ (setq swiper--point-min (point-min))
+ (setq swiper--point-max (point-max))
+ (when (setq swiper--reveal-mode
+ (bound-and-true-p reveal-mode))
+ (reveal-mode -1))
+ (lazy-highlight-cleanup t)
+ (setq isearch-opened-overlays nil)
+ (when (bound-and-true-p evil-mode)
+ (evil-set-jump)))
+
+(defun swiper--normalize-regex (re)
+ "Normalize the swiper regex RE.
+Add a space after a leading `^' if needed and apply
+`search-default-mode' if bound."
+ (replace-regexp-in-string
+ "^\\(?:\\\\(\\)?\\^"
+ (concat "\\&" (if (eq 'swiper (ivy-state-caller ivy-last)) " " ""))
+ (if (functionp (bound-and-true-p search-default-mode))
+ (mapconcat
+ (lambda (x)
+ (if (string-match-p "\\`[^$\\^]+\\'" x)
+ (funcall search-default-mode x)
+ x))
+ (split-string re "\\b") "")
+ re)
+ t))
+
+(defun swiper--re-builder (str)
+ "Transform STR into a swiper regex.
+This is the regex used in the minibuffer where candidates have
+line numbers. For the buffer, use `ivy--regex' instead."
+ (let* ((re-builder (ivy-alist-setting ivy-re-builders-alist))
+ (str (replace-regexp-in-string "\\\\n" "\n" str))
+ (re (funcall re-builder str)))
+ (if (consp re)
+ (mapcar
+ (lambda (x)
+ (cons (swiper--normalize-regex (car x))
+ (cdr x)))
+ re)
+ (swiper--normalize-regex re))))
+
+(defvar swiper-history nil
+ "History for `swiper'.")
+
+(defvar swiper-invocation-face nil
+ "The face at the point of invocation of `swiper'.")
+
+(defcustom swiper-stay-on-quit nil
+ "When non-nil don't go back to search start on abort."
+ :type 'boolean)
+
+;;;###autoload
+(defun swiper (&optional initial-input)
+ "`isearch-forward' with an overview.
+When non-nil, INITIAL-INPUT is the initial search pattern."
+ (interactive)
+ (let ((candidates (swiper--candidates)))
+ (swiper--init)
+ (setq swiper-invocation-face
+ (plist-get (text-properties-at (point)) 'face))
+ (let ((preselect
+ (if (or swiper-use-visual-line (null search-invisible))
+ (count-screen-lines
+ (point-min)
+ (save-excursion (beginning-of-visual-line) (point)))
+ (1- (line-number-at-pos))))
+ (minibuffer-allow-text-properties t)
+ res)
+ (unwind-protect
+ (and
+ (setq res
+ (ivy-read
+ "Swiper: "
+ candidates
+ :initial-input initial-input
+ :keymap swiper-map
+ :preselect
+ (if initial-input
+ (cl-position-if
+ (lambda (x)
+ (<= (1+ preselect) (swiper--line-number x)))
+ (progn
+ (setq ivy--old-re nil)
+ (ivy--filter initial-input candidates)))
+ preselect)
+ :require-match t
+ :action #'swiper--action
+ :re-builder #'swiper--re-builder
+ :history 'swiper-history
+ :extra-props (list :fname (buffer-file-name))
+ :caller 'swiper))
+ (point))
+ (unless (or res swiper-stay-on-quit)
+ (goto-char swiper--opoint))
+ (isearch-clean-overlays)
+ (unless (or res (string= ivy-text ""))
+ (cl-pushnew ivy-text swiper-history))
+ (setq swiper--current-window-start nil)
+ (when swiper--reveal-mode
+ (reveal-mode 1))))))
+
+(ivy-configure 'swiper
+ :occur #'swiper-occur
+ :update-fn #'swiper--update-input-ivy
+ :unwind-fn #'swiper--cleanup
+ :index-fn #'ivy-recompute-index-swiper)
+
+(defun swiper-toggle-face-matching ()
+ "Toggle matching only the candidates with `swiper-invocation-face'."
+ (interactive)
+ (setf (ivy-state-matcher ivy-last)
+ (if (ivy-state-matcher ivy-last)
+ nil
+ #'swiper--face-matcher))
+ (setq ivy--old-re nil))
+
+(defun swiper--face-matcher (regexp candidates)
+ "Return REGEXP matching CANDIDATES.
+Matched candidates should have `swiper-invocation-face'."
+ (cl-remove-if-not
+ (lambda (x)
+ (and (string-match regexp x)
+ (let* ((s (match-string 0 x))
+ (n (length s))
+ (i 0))
+ (while (and (< i n)
+ (text-property-any
+ i (1+ i)
+ 'face swiper-invocation-face
+ s))
+ (cl-incf i))
+ (= i n))))
+ candidates))
+
+(defun swiper--ensure-visible ()
+ "Remove overlays hiding point."
+ (let ((overlays (overlays-at (1- (point))))
+ ov expose)
+ (while (setq ov (pop overlays))
+ (if (and (invisible-p (overlay-get ov 'invisible))
+ (setq expose (overlay-get ov 'isearch-open-invisible)))
+ (funcall expose ov)))))
+
+(defvar swiper--overlays nil
+ "Store overlays.")
+
+(defvar swiper--isearch-highlight-timer nil
+ "This timer used by `swiper--delayed-add-overlays'.")
+
+(defun swiper--cleanup ()
+ "Clean up the overlays."
+ (while swiper--overlays
+ (delete-overlay (pop swiper--overlays)))
+ ;; force cleanup unless it's :unwind
+ (lazy-highlight-cleanup
+ (if (eq ivy-exit 'done) lazy-highlight-cleanup t))
+ (when (timerp swiper--isearch-highlight-timer)
+ (cancel-timer swiper--isearch-highlight-timer)
+ (setq swiper--isearch-highlight-timer nil)))
+
+(defun swiper--add-cursor-overlay (wnd)
+ (let* ((special (or (eolp) (looking-at "\t")))
+ (ov (make-overlay (point) (if special (point) (1+ (point))))))
+ (if special
+ (overlay-put ov 'after-string (propertize " " 'face 'ivy-cursor))
+ (overlay-put ov 'face 'ivy-cursor))
+ (overlay-put ov 'window wnd)
+ (overlay-put ov 'priority 2)
+ (push ov swiper--overlays)))
+
+(defun swiper--add-line-overlay (wnd)
+ (let ((beg (if visual-line-mode
+ (save-excursion
+ (beginning-of-visual-line)
+ (point))
+ (line-beginning-position)))
+ (end (if visual-line-mode
+ (save-excursion
+ (end-of-visual-line)
+ (point))
+ (1+ (line-end-position)))))
+ (push (swiper--make-overlay beg end 'swiper-line-face wnd 0)
+ swiper--overlays)))
+
+(defun swiper--make-overlay (beg end face wnd priority)
+ "Create an overlay bound by BEG and END.
+FACE, WND and PRIORITY are properties corresponding to
+the face, window and priority of the overlay."
+ (let ((overlay (make-overlay beg end)))
+ (overlay-put overlay 'face face)
+ (overlay-put overlay 'window wnd)
+ (overlay-put overlay 'priority priority)
+ overlay))
+
+(defun swiper--recenter-p ()
+ (or (display-graphic-p)
+ (not recenter-redisplay)))
+
+(defun swiper--positive-regexps ()
+ (if (listp ivy-regex)
+ (mapcar #'car (cl-remove-if-not #'cdr ivy-regex))
+ (list ivy-regex)))
+
+(defun swiper--update-input-ivy ()
+ "Called when `ivy' input is updated."
+ (with-ivy-window
+ (swiper--cleanup)
+ (when (> (length (ivy-state-current ivy-last)) 0)
+ (let ((regexps (swiper--positive-regexps))
+ (re-idx -1)
+ (case-fold-search (ivy--case-fold-p ivy-text)))
+ (dolist (re regexps)
+ (setq re-idx (1+ re-idx))
+ (let* ((re (replace-regexp-in-string
+ " " "\t"
+ re))
+ (num (swiper--line-number (ivy-state-current ivy-last))))
+ (unless (memq this-command '(ivy-yank-word
+ ivy-yank-symbol
+ ivy-yank-char
+ scroll-other-window))
+ (when (cl-plusp num)
+ (unless (if swiper--current-line
+ (eq swiper--current-line num)
+ (eq (line-number-at-pos) num))
+ (goto-char swiper--point-min)
+ (if swiper-use-visual-line
+ (line-move (1- num))
+ (forward-line (1- num))))
+ (if (and (equal ivy-text "")
+ (>= swiper--opoint (line-beginning-position))
+ (<= swiper--opoint (line-end-position)))
+ (goto-char swiper--opoint)
+ (if (eq swiper--current-line num)
+ (when swiper--current-match-start
+ (goto-char swiper--current-match-start))
+ (setq swiper--current-line num))
+ (when (re-search-forward re (line-end-position) t)
+ (setq swiper--current-match-start (match-beginning 0))))
+ (funcall isearch-filter-predicate
+ (line-beginning-position)
+ (line-end-position))
+ (swiper--maybe-recenter)))
+ (swiper--add-overlays
+ re
+ (max
+ (if (swiper--recenter-p)
+ (window-start)
+ (line-beginning-position (- (window-height))))
+ swiper--point-min)
+ (min
+ (if (swiper--recenter-p)
+ (window-end (selected-window) t)
+ (line-end-position (window-height)))
+ swiper--point-max)
+ nil
+ re-idx)))))))
+
+(defun swiper--add-overlays (re &optional beg end wnd re-idx)
+ "Add overlays for RE regexp in visible part of the current buffer.
+BEG and END, when specified, are the point bounds.
+WND, when specified is the window."
+ (setq wnd (or wnd (ivy-state-window ivy-last)))
+ (swiper--add-line-overlay wnd)
+ (let* ((pt (point))
+ (wh (window-height))
+ (beg (or beg (save-excursion
+ (forward-line (- wh))
+ (point))))
+ (end (or end (save-excursion
+ (forward-line wh)
+ (point))))
+ (case-fold-search (ivy--case-fold-p re)))
+ (when (>= (length re) swiper-min-highlight)
+ (save-excursion
+ (goto-char beg)
+ ;; RE can become an invalid regexp
+ (while (progn
+ (when (eolp)
+ (unless (eobp)
+ (forward-char)))
+ (and (ignore-errors (re-search-forward re end t))
+ (> (- (match-end 0) (match-beginning 0)) 0)))
+ ;; Don't highlight a match if it spans multiple
+ ;; lines. `count-lines' returns 1 if the match is within a
+ ;; single line, even if it includes the newline, and 2 or
+ ;; greater otherwise. We hope that the inclusion of the
+ ;; newline will not ever be a problem in practice.
+ (when (< (count-lines (match-beginning 0) (match-end 0)) 2)
+ (let* ((faces (if (= (match-end 0) pt)
+ swiper-faces
+ swiper-background-faces))
+ (adder-fn (lambda (beg end face priority)
+ (push (swiper--make-overlay beg end face wnd priority)
+ isearch-lazy-highlight-overlays))))
+ (unless (and (consp ivy--old-re)
+ (null
+ (save-match-data
+ (ivy--re-filter ivy--old-re
+ (list
+ (buffer-substring-no-properties
+ (line-beginning-position)
+ (line-end-position)))))))
+ (swiper--add-properties faces adder-fn re-idx)))))))))
+
+(defun swiper--add-properties (faces adder-fn &optional re-idx)
+ (let ((mb (match-beginning 0))
+ (me (match-end 0)))
+ (unless (> (- me mb) 2017)
+ (funcall adder-fn
+ mb me
+ (if (and ivy-use-group-face-if-no-groups (zerop ivy--subexps))
+ (nth (1+ (mod (or re-idx 0) (1- (length faces)))) faces)
+ (car faces))
+ 0)))
+ (let ((i 1)
+ (j 0))
+ (while (<= (cl-incf j) ivy--subexps)
+ (let ((bm (match-beginning j))
+ (em (match-end j)))
+ (when (and (integerp em)
+ (integerp bm))
+ (when (eq (ivy-alist-setting ivy-re-builders-alist t) #'ivy--regex-fuzzy)
+ (while (and (< j ivy--subexps)
+ (integerp (match-beginning (+ j 1)))
+ (= em (match-beginning (+ j 1))))
+ (setq em (match-end (cl-incf j)))))
+ (funcall adder-fn
+ bm em
+ (nth (1+ (mod (+ i 2) (1- (length faces))))
+ faces)
+ i)
+ (cl-incf i))))))
+
+(defcustom swiper-action-recenter nil
+ "When non-nil, recenter after exiting `swiper'."
+ :type 'boolean)
+(defvar evil-search-module)
+(defvar evil-ex-search-pattern)
+(defvar evil-ex-search-persistent-highlight)
+(defvar evil-ex-search-direction)
+(declare-function evil-ex-search-activate-highlight "evil-ex")
+
+(defun swiper--maybe-recenter ()
+ (cond (swiper-action-recenter
+ (recenter))
+ ((swiper--recenter-p)
+ (when swiper--current-window-start
+ (set-window-start (selected-window) swiper--current-window-start))
+ (when (or
+ (< (point) (window-start))
+ (> (point) (window-end (ivy-state-window ivy-last) t)))
+ (recenter))))
+ (setq swiper--current-window-start (window-start)))
+
+(defun swiper--line-number (x)
+ (or (get-text-property 0 'swiper-line-number x)
+ (get-text-property 1 'swiper-line-number x)))
+
+(defcustom swiper-verbose t
+ "When non-nil, print more informational messages."
+ :type 'boolean)
+
+(defun swiper--push-mark ()
+ (when (/= (point) swiper--opoint)
+ (unless (and transient-mark-mode mark-active)
+ (when (eq ivy-exit 'done)
+ (push-mark swiper--opoint t)
+ (when swiper-verbose
+ (message "Mark saved where search started"))))))
+
+(defun swiper--action (x)
+ "Goto line X."
+ (let ((ln (1- (swiper--line-number x)))
+ (re (ivy--regex ivy-text))
+ (case-fold-search (ivy--case-fold-p ivy-text)))
+ (if (null x)
+ (user-error "No candidates")
+ (with-ivy-window
+ (unless (equal (current-buffer)
+ (ivy-state-buffer ivy-last))
+ (switch-to-buffer (ivy-state-buffer ivy-last)))
+ (goto-char
+ (if (buffer-narrowed-p)
+ swiper--point-min
+ (point-min)))
+ (funcall (if swiper-use-visual-line
+ #'line-move
+ #'forward-line)
+ ln)
+ (when (and (re-search-forward re (line-end-position) t) swiper-goto-start-of-match)
+ (goto-char (match-beginning 0)))
+ (swiper--ensure-visible)
+ (swiper--maybe-recenter)
+ (swiper--push-mark)
+ (swiper--remember-search-history re)))))
+
+(defun swiper--remember-search-history (re)
+ "Add the search pattern RE to the search history ring."
+ (add-to-history
+ 'regexp-search-ring
+ re
+ regexp-search-ring-max)
+ ;; integration with evil-mode's search
+ (when (bound-and-true-p evil-mode)
+ (when (eq evil-search-module 'isearch)
+ (setq isearch-string ivy-text))
+ (when (eq evil-search-module 'evil-search)
+ (add-to-history 'evil-ex-search-history re)
+ (setq evil-ex-search-pattern (list re t t))
+ (setq evil-ex-search-direction 'forward)
+ (when evil-ex-search-persistent-highlight
+ (evil-ex-search-activate-highlight evil-ex-search-pattern)))))
+
+(defun swiper-from-isearch ()
+ "Invoke `swiper' from isearch."
+ (interactive)
+ (swiper (prog1 (if isearch-regexp
+ isearch-string
+ (regexp-quote isearch-string))
+ (let ((search-nonincremental-instead nil))
+ (isearch-exit)))))
+
+(defvar swiper-multi-buffers nil
+ "Store the current list of buffers.")
+
+(defvar swiper-multi-candidates nil
+ "Store the list of candidates for `swiper-multi'.")
+
+(defun swiper-multi-prompt ()
+ "Return prompt for `swiper-multi'."
+ (format "Buffers (%s): "
+ (mapconcat #'identity swiper-multi-buffers ", ")))
+
+(defvar swiper-window-width 80)
+
+(defun swiper-multi ()
+ "Select one or more buffers.
+Run `swiper' for those buffers."
+ (interactive)
+ (setq swiper-multi-buffers nil)
+ (let ((ivy-use-virtual-buffers nil))
+ (ivy-read (swiper-multi-prompt)
+ #'internal-complete-buffer
+ :action #'swiper-multi-action-1))
+ (let ((swiper-window-width (- (- (frame-width) (if (display-graphic-p) 0 1)) 4)))
+ (ivy-read "Swiper: " swiper-multi-candidates
+ :action #'swiper-multi-action-2
+ :caller 'swiper-multi)))
+
+(ivy-configure 'swiper-multi
+ :unwind-fn #'swiper--cleanup
+ :index-fn #'ivy-recompute-index-swiper
+ :format-fn #'swiper--all-format-function)
+
+(defun swiper-multi-action-1 (x)
+ "Add X to list of selected buffers `swiper-multi-buffers'.
+If X is already part of the list, remove it instead. Quit the selection if
+X is selected by either `ivy-done', `ivy-alt-done' or `ivy-immediate-done',
+otherwise continue prompting for buffers."
+ (if (member x swiper-multi-buffers)
+ (progn
+ (setq swiper-multi-buffers (delete x swiper-multi-buffers)))
+ (unless (equal x "")
+ (setq swiper-multi-buffers (append swiper-multi-buffers (list x)))))
+ (let ((prompt (swiper-multi-prompt)))
+ (setf (ivy-state-prompt ivy-last) prompt)
+ (setq ivy--prompt (concat "%-4d " prompt)))
+ (cond ((memq this-command '(ivy-done
+ ivy-alt-done
+ ivy-immediate-done))
+ (setq swiper-multi-candidates
+ (swiper--multi-candidates
+ (mapcar #'get-buffer swiper-multi-buffers))))
+ ((eq this-command 'ivy-call)
+ (with-selected-window (active-minibuffer-window)
+ (delete-minibuffer-contents)))))
+
+(defun swiper-multi-action-2 (x)
+ "Move to candidate X from `swiper-multi'."
+ (when (> (length x) 0)
+ (let ((buffer-name (get-text-property 0 'buffer x)))
+ (when buffer-name
+ (with-ivy-window
+ (switch-to-buffer buffer-name)
+ (goto-char (point-min))
+ (forward-line (1- (swiper--line-number x)))
+ (re-search-forward
+ (ivy--regex ivy-text)
+ (line-end-position) t)
+ (funcall isearch-filter-predicate
+ (line-beginning-position)
+ (line-end-position))
+ (unless (eq ivy-exit 'done)
+ (swiper--cleanup)
+ (swiper--add-overlays (ivy--regex ivy-text))))))))
+
+(defun swiper-all-buffer-p (buffer)
+ "Return non-nil if BUFFER should be considered by `swiper-all'."
+ (let ((mode (buffer-local-value 'major-mode (get-buffer buffer))))
+ (cond
+ ;; Ignore TAGS buffers, they tend to add duplicate results.
+ ((eq mode #'tags-table-mode) nil)
+ ;; Always consider dired buffers, even though they're not backed
+ ;; by a file.
+ ((eq mode #'dired-mode) t)
+ ;; Always consider stash buffers too, as they may have
+ ;; interesting content not present in any buffers. We don't #'
+ ;; quote to satisfy the byte-compiler.
+ ((eq mode 'magit-stash-mode) t)
+ ;; Email buffers have no file, but are useful to search
+ ((eq mode 'gnus-article-mode) t)
+ ;; Otherwise, only consider the file if it's backed by a file.
+ (t (buffer-file-name buffer)))))
+
+;;* `swiper-all'
+(defun swiper-all-function (str)
+ "Search in all open buffers for STR."
+ (or
+ (ivy-more-chars)
+ (let* ((buffers (cl-remove-if-not #'swiper-all-buffer-p (buffer-list)))
+ (re-full ivy-regex)
+ re re-tail
+ cands match
+ (case-fold-search (ivy--case-fold-p str)))
+ (setq re (ivy-re-to-str re-full))
+ (when (consp re-full)
+ (setq re-tail (cdr re-full)))
+ (dolist (buffer buffers)
+ (with-current-buffer buffer
+ (save-excursion
+ (goto-char (point-min))
+ (while (re-search-forward re nil t)
+ (setq match (if (memq major-mode '(org-mode dired-mode))
+ (buffer-substring-no-properties
+ (line-beginning-position)
+ (line-end-position))
+ (buffer-substring
+ (line-beginning-position)
+ (line-end-position))))
+ (put-text-property
+ 0 1 'buffer
+ (buffer-name)
+ match)
+ (put-text-property 0 1 'point (point) match)
+ (when (or (null re-tail) (ivy-re-match re-tail match))
+ (push match cands))))))
+ (setq ivy--old-re re-full)
+ (if (null cands)
+ (list "")
+ (setq ivy--old-cands (nreverse cands))))))
+
+(defun swiper--all-format-function (cands)
+ "Format CANDS for `swiper-all'.
+See `ivy-format-functions-alist' for further information."
+ (let* ((ww swiper-window-width)
+ (col2 1)
+ (cands-with-buffer
+ (mapcar (lambda (s)
+ (let ((buffer (get-text-property 0 'buffer s)))
+ (setq col2 (max col2 (length buffer)))
+ (cons s buffer))) cands))
+ (col1 (- ww 4 col2)))
+ (setq cands
+ (mapcar (lambda (x)
+ (if (cdr x)
+ (let ((s (ivy--truncate-string (car x) col1)))
+ (concat
+ s
+ (make-string
+ (max 0
+ (- ww (string-width s) (length (cdr x))))
+ ?\ )
+ (cdr x)))
+ (car x)))
+ cands-with-buffer))
+ (ivy--format-function-generic
+ (lambda (str)
+ (ivy--add-face str 'ivy-current-match))
+ (lambda (str)
+ str)
+ cands
+ "\n")))
+
+(defvar swiper-all-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map (kbd "M-q") 'swiper-all-query-replace)
+ map)
+ "Keymap for `swiper-all'.")
+
+;;;###autoload
+(defun swiper-all (&optional initial-input)
+ "Run `swiper' for all open buffers."
+ (interactive)
+ (let ((swiper-window-width (- (frame-width) (if (display-graphic-p) 0 1))))
+ (ivy-read "swiper-all: " 'swiper-all-function
+ :action #'swiper-all-action
+ :dynamic-collection t
+ :keymap swiper-all-map
+ :initial-input initial-input
+ :caller 'swiper-all)))
+
+(ivy-configure 'swiper-all
+ :update-fn 'auto
+ :unwind-fn #'swiper--cleanup
+ :format-fn #'swiper--all-format-function)
+
+(defun swiper-all-action (x)
+ "Move to candidate X from `swiper-all'."
+ (when (> (length x) 0)
+ (let ((buffer-name (get-text-property 0 'buffer x)))
+ (when buffer-name
+ (with-ivy-window
+ (switch-to-buffer buffer-name)
+ (goto-char (get-text-property 0 'point x))
+ (funcall isearch-filter-predicate
+ (line-beginning-position)
+ (line-end-position))
+ (unless (eq ivy-exit 'done)
+ (swiper--cleanup)
+ (swiper--add-overlays (ivy--regex ivy-text))))))))
+
+(defun swiper--multi-candidates (buffers)
+ "Extract candidates from BUFFERS."
+ (let ((res nil))
+ (dolist (buf buffers)
+ (with-current-buffer buf
+ (setq res
+ (nconc
+ (mapcar
+ (lambda (s) (put-text-property 0 1 'buffer (buffer-name) s) s)
+ (swiper--candidates 4))
+ res))))
+ res))
+
+;;* `swiper-isearch'
+(defun swiper-isearch-function (str)
+ "Collect STR matches in the current buffer for `swiper-isearch'."
+ (with-ivy-window
+ (swiper--isearch-function str)))
+
+(defun swiper-match-usable-p ()
+ (or search-invisible
+ (not (cl-find-if
+ (lambda (ov)
+ (invisible-p (overlay-get ov 'invisible)))
+ (overlays-at (point))))))
+
+(defvar swiper--isearch-backward nil)
+(defvar swiper--isearch-start-point nil)
+
+(defun swiper--isearch-function-1 (re backward)
+ (unless (string= re ".")
+ (let (cands)
+ (save-excursion
+ (goto-char (if backward (point-max) (point-min)))
+ (while (and (funcall (if backward #'re-search-backward #'re-search-forward) re nil t)
+ (not (and
+ (= (match-beginning 0) (match-end 0))
+ (if backward (bobp) (eobp)))))
+ (when (swiper-match-usable-p)
+ (let ((pos (if (or backward swiper-goto-start-of-match)
+ (match-beginning 0)
+ (point))))
+ (push pos cands)))
+ (when (= (match-beginning 0) (match-end 0))
+ (if backward
+ (backward-char)
+ (forward-char)))))
+ (if backward
+ cands
+ (nreverse cands)))))
+
+(defun swiper--isearch-next-item (re cands)
+ (or (if swiper--isearch-backward
+ (save-excursion
+ ;; Match RE starting at each position in CANDS.
+ (setq re (concat "\\=\\(?:" re "\\)"))
+ (cl-position-if
+ (lambda (x)
+ (when (< x swiper--isearch-start-point)
+ (goto-char x)
+ ;; Note: Not quite the same as `looking-at' + `match-end'.
+ (re-search-forward re swiper--isearch-start-point t)))
+ cands
+ :from-end t))
+ (cl-position swiper--isearch-start-point cands :test #'<))
+ 0))
+
+(defun swiper--isearch-filter-ignore-order (re-full cands)
+ (let (filtered-cands)
+ (dolist (re-cons re-full cands)
+ (save-excursion
+ (dolist (cand cands)
+ (goto-char cand)
+ (beginning-of-line)
+ (unless (if (re-search-forward (car re-cons) (line-end-position) t)
+ (not (cdr re-cons))
+ (cdr re-cons))
+ (push cand filtered-cands))))
+ (setq cands (nreverse filtered-cands))
+ (setq filtered-cands nil))))
+
+(defun swiper--isearch-function (str)
+ (let ((re-full ivy-regex))
+ (unless (equal re-full "")
+ (let* ((case-fold-search (ivy--case-fold-p str))
+ (re
+ (if (stringp re-full)
+ re-full
+ (mapconcat
+ #'ivy--regex-or-literal
+ (delq nil (mapcar (lambda (x) (and (cdr x) (car x))) re-full))
+ "\\|")))
+ (cands (swiper--isearch-function-1 re swiper--isearch-backward)))
+ (when (consp re-full)
+ (setq cands (swiper--isearch-filter-ignore-order re-full cands)))
+ (setq ivy--old-re re)
+ (ivy-set-index (swiper--isearch-next-item re cands))
+ (setq ivy--old-cands cands)))))
+
+(defcustom swiper-isearch-highlight-delay '(2 0.2)
+ "When `ivy-text' is too short, delay showing the overlay.
+
+The default value will delay showing the overlay by 0.2 seconds
+if `ivy-text' is shorter than 2 characters.
+
+The aim is to reduce the visual clutter, since it's very rare
+that we search only for one character."
+ :type '(list
+ (integer :tag "Text length")
+ (float :tag "Delay in seconds")))
+
+(defun swiper--delayed-add-overlays ()
+ (if (and swiper-isearch-highlight-delay
+ (< (length ivy-text) (car swiper-isearch-highlight-delay)))
+ (setq swiper--isearch-highlight-timer
+ (run-with-idle-timer
+ (cadr swiper-isearch-highlight-delay) nil
+ (lambda ()
+ (with-ivy-window
+ (swiper--add-overlays (ivy--regex ivy-text))))))
+ (dolist (re (swiper--positive-regexps))
+ (swiper--add-overlays re))))
+
+(defun swiper--isearch-candidate-pos (cand)
+ "Return the buffer position of `swiper-isearch' CAND, or nil."
+ (cond ((integer-or-marker-p cand) cand)
+ ((and (stringp cand) (> (length cand) 0))
+ (get-text-property 0 'point cand))))
+
+(defun swiper-isearch-action (x)
+ "Move to X for `swiper-isearch'."
+ (if (setq x (swiper--isearch-candidate-pos x))
+ (with-ivy-window
+ (goto-char x)
+ (when (and (or (eq this-command 'ivy-previous-line-or-history)
+ (and (eq this-command 'ivy-done)
+ (eq last-command 'ivy-previous-line-or-history)))
+ (looking-back ivy-regex (line-beginning-position)))
+ (goto-char (match-beginning 0)))
+ (funcall isearch-filter-predicate (point) (1+ (point)))
+ (swiper--maybe-recenter)
+ (if (or (eq ivy-exit 'done)
+ ;; FIXME: With the default action 'M-o o', `ivy-exit' remains
+ ;; nil for some reason, so check `this-command' instead to
+ ;; tell whether we're "done".
+ (eq this-command #'ivy-dispatching-done))
+ (progn
+ (swiper--push-mark)
+ (swiper--remember-search-history (ivy--regex ivy-text)))
+ (swiper--cleanup)
+ (swiper--delayed-add-overlays)
+ (swiper--add-cursor-overlay
+ (ivy-state-window ivy-last))))
+ (swiper--cleanup)))
+
+(defun swiper-action-copy (_x)
+ "Copy line at point and go back."
+ (kill-new
+ (buffer-substring-no-properties
+ (line-beginning-position) (line-end-position)))
+ (goto-char swiper--opoint))
+
+(defun swiper-isearch-action-copy (cand)
+ "Save `swiper-isearch' candidate CAND to `kill-ring'.
+Return to original position."
+ (unwind-protect
+ (progn
+ (unless (and (setq cand (swiper--isearch-candidate-pos cand))
+ ;; FIXME: Better way of getting current candidate?
+ (goto-char cand)
+ (looking-back (ivy-re-to-str ivy-regex) (point-min)))
+ (error "Could not copy `swiper-isearch' candidate: %S" cand))
+ (kill-new (match-string 0)))
+ (goto-char swiper--opoint)))
+
+(ivy-add-actions 'swiper-isearch '(("w" swiper-isearch-action-copy "copy")))
+(ivy-add-actions 'swiper '(("w" swiper-action-copy "copy")))
+
+(defun swiper-isearch-thing-at-point ()
+ "Insert `symbol-at-point' into the minibuffer of `swiper-isearch'.
+When not running `swiper-isearch' already, start it."
+ (interactive)
+ (if (window-minibuffer-p)
+ (let (bnd str regionp)
+ (with-ivy-window
+ (setq bnd
+ (if (setq regionp (region-active-p))
+ (prog1 (cons (region-beginning) (region-end))
+ (deactivate-mark))
+ (bounds-of-thing-at-point 'symbol)))
+ (setq str (buffer-substring-no-properties (car bnd) (cdr bnd))))
+ (insert str)
+ (unless regionp
+ (ivy--insert-symbol-boundaries)))
+ (let (thing)
+ (if (use-region-p)
+ (progn
+ (setq thing (buffer-substring-no-properties
+ (region-beginning) (region-end)))
+ (goto-char (region-beginning))
+ (deactivate-mark))
+ (let ((bnd (bounds-of-thing-at-point 'symbol)))
+ (when bnd
+ (goto-char (car bnd)))
+ (setq thing (ivy-thing-at-point))))
+ (swiper-isearch thing))))
+
+(defun swiper-isearch-C-r (&optional arg)
+ "Move cursor vertically up ARG candidates.
+When the input is empty, browse the search history instead."
+ (interactive "p")
+ (if (string= ivy-text "")
+ (ivy-reverse-i-search)
+ (ivy-previous-line arg)))
+
+(defvar swiper-isearch-map
+ (let ((map (make-sparse-keymap)))
+ (set-keymap-parent map swiper-map)
+ (define-key map (kbd "M-n") 'swiper-isearch-thing-at-point)
+ (define-key map (kbd "C-r") 'swiper-isearch-C-r)
+ map)
+ "Keymap for `swiper-isearch'.")
+
+(defun swiper--isearch-same-line-p (s1 s2)
+ "Check if S1 and S2 are equal and on the same line."
+ (and (equal s1 s2)
+ (<= (count-lines
+ (get-text-property 0 'point s2)
+ (get-text-property 0 'point s1))
+ 1)))
+
+(defun swiper-isearch-format-function (cands)
+ (if (numberp (car-safe cands))
+ (let ((re (ivy-re-to-str ivy-regex)))
+ (if (string= re "^$")
+ ""
+ (mapconcat
+ #'identity
+ (swiper--isearch-format
+ ivy--index ivy--length (or ivy--old-cands ivy--all-candidates)
+ re
+ (ivy-state-current ivy-last)
+ (ivy-state-buffer ivy-last))
+ "\n")))
+ (funcall
+ (ivy-alist-setting ivy-format-functions-alist t)
+ cands)))
+
+(defun swiper--line-at-point (pt)
+ (save-excursion
+ (goto-char pt)
+ (let ((s (buffer-substring
+ (line-beginning-position)
+ (line-end-position))))
+ (if (string= s "")
+ s
+ (put-text-property 0 1 'point pt s)
+ (ivy-cleanup-string s)))))
+
+(defun swiper--isearch-highlight (str &optional current)
+ (let ((start 0)
+ (i 0)
+ (re (ivy-re-to-str ivy-regex)))
+ (catch 'done
+ (while (string-match re str start)
+ (if (= (match-beginning 0) (match-end 0))
+ (throw 'done t)
+ (setq start (match-end 0)))
+ (swiper--add-properties
+ (if (eq current i)
+ swiper-faces
+ swiper-background-faces)
+ (lambda (beg end face _priority)
+ (add-face-text-property beg end face nil str)))
+ (cl-incf i)))
+ str))
+
+(defun swiper--isearch-format (index length cands regex current buffer)
+ (let* ((half-height (/ ivy-height 2))
+ (i (1- index))
+ (j 0)
+ (len 0)
+ res s)
+ (with-current-buffer buffer
+ (while (and (>= i 0)
+ (swiper--isearch-same-line-p
+ (swiper--line-at-point (nth i cands))
+ (swiper--line-at-point current)))
+ (cl-decf i)
+ (cl-incf j))
+ (while (and (>= i 0)
+ (< len half-height))
+ (setq s (swiper--line-at-point (nth i cands)))
+ (unless (swiper--isearch-same-line-p s (car res))
+ (push (swiper--isearch-highlight s) res)
+ (cl-incf len))
+ (cl-decf i))
+ (setq res (nreverse res))
+ (let ((current-str
+ (swiper--line-at-point current))
+ (start 0))
+ (dotimes (_ (1+ j))
+ (string-match regex current-str start)
+ (setq start (match-end 0)))
+ (font-lock-prepend-text-property
+ 0 (length current-str)
+ 'face 'swiper-line-face current-str)
+ (swiper--isearch-highlight current-str j)
+ (push current-str res))
+ (cl-incf len)
+ (setq i (1+ index))
+ (while (and (< i length)
+ (swiper--isearch-same-line-p
+ (swiper--line-at-point (nth i cands))
+ (swiper--line-at-point current)))
+ (cl-incf i))
+ (while (and (< i length)
+ (< len ivy-height))
+ (setq s (swiper--line-at-point (nth i cands)))
+ (unless (swiper--isearch-same-line-p s (car res))
+ (push (swiper--isearch-highlight s) res)
+ (cl-incf len))
+ (cl-incf i))
+ (nreverse res))))
+
+(defun swiper--isearch-init ()
+ "Initialize `swiper-isearch'."
+ (swiper--init)
+ (setq swiper--isearch-start-point (point))
+ (swiper-font-lock-ensure))
+
+(defun swiper--isearch-unwind ()
+ (swiper--cleanup)
+ (unless (or (eq ivy-exit 'done) swiper-stay-on-quit)
+ (goto-char swiper--opoint))
+ (isearch-clean-overlays)
+ (swiper--ensure-visible)
+ (unless (or (eq ivy-exit 'done) (string= ivy-text ""))
+ (cl-pushnew ivy-text swiper-history)))
+
+;;;###autoload
+(defun swiper-isearch (&optional initial-input)
+ "A `swiper' that's not line-based."
+ (interactive)
+ (let ((ivy-fixed-height-minibuffer t)
+ (cursor-in-non-selected-windows nil)
+ (swiper-min-highlight 1))
+ (ivy-read
+ "Swiper: "
+ #'swiper-isearch-function
+ :initial-input initial-input
+ :keymap swiper-isearch-map
+ :dynamic-collection t
+ :require-match t
+ :action #'swiper-isearch-action
+ :re-builder #'swiper--re-builder
+ :history 'swiper-history
+ :extra-props (list :fname (buffer-file-name))
+ :caller 'swiper-isearch)))
+
+(ivy-configure 'swiper-isearch
+ :occur #'swiper-occur
+ :init-fn #'swiper--isearch-init
+ :update-fn 'auto
+ :unwind-fn #'swiper--isearch-unwind
+ :format-fn #'swiper-isearch-format-function)
+
+;;;###autoload
+(defun swiper-isearch-backward (&optional initial-input)
+ "Like `swiper-isearch' but the first result is before the point."
+ (interactive)
+ (let ((swiper--isearch-backward t))
+ (swiper-isearch initial-input)))
+
+(defun swiper-isearch-toggle ()
+ "Two-way toggle between `swiper-isearch' and isearch.
+Intended to be bound in `isearch-mode-map' and `swiper-map'."
+ (interactive)
+ (if isearch-mode
+ (let ((query (if isearch-regexp
+ isearch-string
+ (regexp-quote isearch-string))))
+ (isearch-exit)
+ (goto-char (or (and isearch-forward isearch-other-end)
+ (point)))
+ (swiper-isearch query))
+ (ivy-exit-with-action
+ (lambda (_)
+ (when (looking-back (ivy-re-to-str ivy-regex) (line-beginning-position))
+ (goto-char (match-beginning 0)))
+ (isearch-mode t)
+ (unless (string= ivy-text "")
+ (isearch-yank-string ivy-text))))))
+
+(provide 'swiper)
+
+;;; swiper.el ends here
diff --git a/elpa/swiper-20220430.2247/swiper.elc b/elpa/swiper-20220430.2247/swiper.elc
new file mode 100644
index 0000000..6040757
--- /dev/null
+++ b/elpa/swiper-20220430.2247/swiper.elc
Binary files differ
diff --git a/elpa/switch-window-20210808.742/switch-window-asciiart.el b/elpa/switch-window-20210808.742/switch-window-asciiart.el
new file mode 100644
index 0000000..7ee1ba0
--- /dev/null
+++ b/elpa/switch-window-20210808.742/switch-window-asciiart.el
@@ -0,0 +1,232 @@
+;;; switch-window-asciiart.el --- switch-window asciiart label -*- lexical-binding: t -*-
+;;
+;; Copyright (C) 2017 Feng Shu
+;;
+;; Author: Feng Shu <tumashu@163.com>
+;; URL: https://github.com/dimitri/switch-window
+;; Git-URL: https://github.com/dimitri/switch-window.git
+;; Version: 1.5.0
+;; Keywords: window navigation
+;; Licence: WTFPL, grab your copy here: http://sam.zoy.org/wtfpl/
+;;
+;; This file is NOT part of GNU Emacs.
+;;
+;;; Commentary:
+
+;;; Code:
+(defvar switch-window-asciiart
+ '("
+ ## (1)
+ # #
+ #
+ #
+#######
+" "
+ ##### (2)
+# ##
+ ##
+ ##
+#######
+" "
+ ##### (3)
+ #
+ #####
+ #
+ #####
+" "
+ # # (4)
+## #
+#######
+ #
+ #
+" "
+####### (5)
+#
+######
+ #
+# #
+ #####
+" "
+ ##### (6)
+#
+######
+# #
+ #####
+" "
+####### (7)
+ #
+ #
+ #
+ #
+" "
+ ##### (8)
+# #
+ #####
+# #
+ #####
+" "
+ ##### (9)
+# #
+ ######
+ #
+ #####
+" "
+ ## (a)
+ # #
+######
+# #
+# #
+" "
+##### (b)
+# #
+#####
+# #
+#####
+" "
+ #### (c)
+# #
+#
+# #
+ ####
+" "
+##### (d)
+# #
+# #
+# #
+#####
+" "
+###### (e)
+#
+#####
+#
+######
+" "
+###### (f)
+#
+#####
+#
+#
+" "
+ ##### (g)
+#
+# ###
+# #
+ #####
+" "
+# # (h)
+# #
+######
+# #
+# #
+" "
+##### (i)
+ #
+ #
+ #
+#####
+" "
+ # (j)
+ #
+ #
+# #
+ ####
+" "
+# # (k)
+# #
+###
+# #
+# #
+" "
+# (l)
+#
+#
+#
+######
+" "
+## ## (m)
+# # # #
+# ## #
+# #
+# #
+" "
+## # (n)
+# # #
+# # #
+# # #
+# ##
+" "
+ #### (o)
+# #
+# #
+# #
+ ####
+" "
+##### (p)
+# #
+#####
+#
+#
+" "
+ #### (q)
+# #
+# # #
+# ##
+ ### #
+
+" " (r)
+#####
+# #
+#####
+# #
+# #
+" "
+ ##### (s)
+#
+ #####
+ #
+ #####
+" "
+####### (t)
+ #
+ #
+ #
+ #
+" "
+# # (u)
+# #
+# #
+# #
+ ####
+" "
+# # (v)
+# #
+# #
+ # #
+ ##
+" "
+# # (w)
+# ## #
+# # # #
+## ##
+" "
+# # (x)
+ # #
+ ##
+ # #
+# #
+" "
+# # (y)
+ # #
+ ###
+ #
+ #
+" "
+####### (z)
+ ##
+ #
+ ##
+#######"
+"The asciiart labels of switch-window."))
+
+(provide 'switch-window-asciiart)
+;;; switch-window-asciiart.el ends here
diff --git a/elpa/switch-window-20210808.742/switch-window-asciiart.elc b/elpa/switch-window-20210808.742/switch-window-asciiart.elc
new file mode 100644
index 0000000..abea5a4
--- /dev/null
+++ b/elpa/switch-window-20210808.742/switch-window-asciiart.elc
Binary files differ
diff --git a/elpa/switch-window-20210808.742/switch-window-autoloads.el b/elpa/switch-window-20210808.742/switch-window-autoloads.el
new file mode 100644
index 0000000..a434f3e
--- /dev/null
+++ b/elpa/switch-window-20210808.742/switch-window-autoloads.el
@@ -0,0 +1,119 @@
+;;; switch-window-autoloads.el --- automatically extracted autoloads -*- lexical-binding: t -*-
+;;
+;;; Code:
+
+(add-to-list 'load-path (directory-file-name
+ (or (file-name-directory #$) (car load-path))))
+
+
+;;;### (autoloads nil "switch-window" "switch-window.el" (0 0 0 0))
+;;; Generated autoloads from switch-window.el
+
+(autoload 'switch-window-then-delete "switch-window" "\
+Display an overlay in each window showing a unique key.
+In the mean time, user will be asked to choose the window deleted." t nil)
+
+(autoload 'switch-window-then-maximize "switch-window" "\
+Display an overlay in each window showing a unique key.
+In the mean time, ask user which window to maximize" t nil)
+
+(autoload 'switch-window "switch-window" "\
+Display an overlay in each window showing a unique key.
+In the mean time, ask user for the window where move to" t nil)
+
+(autoload 'switch-window-then-split-horizontally "switch-window" "\
+Select a window then split it horizontally.
+Argument ARG .
+
+\(fn ARG)" t nil)
+
+(autoload 'switch-window-then-split-vertically "switch-window" "\
+Select a window then split it vertically.
+Argument ARG .
+
+\(fn ARG)" t nil)
+
+(autoload 'switch-window-then-split-below "switch-window" "\
+Select a window then split it with split-window-below's mode.
+TODO: Argument ARG.
+
+\(fn ARG)" t nil)
+
+(autoload 'switch-window-then-split-right "switch-window" "\
+Select a window then split it with split-window-right's mode.
+TODO: Argument ARG .
+
+\(fn ARG)" t nil)
+
+(autoload 'switch-window-then-swap-buffer "switch-window" "\
+Swap the current window's buffer with a selected window's buffer.
+
+Move the focus on the newly selected window unless KEEP-FOCUS is
+non-nil (aka keep the focus on the current window).
+
+When a window is strongly dedicated to its buffer, this function
+won't take effect, and no buffers will be switched.
+
+\(fn &optional KEEP-FOCUS)" t nil)
+
+(autoload 'switch-window-then-find-file "switch-window" "\
+Select a window, then find a file in it.
+
+Designed to replace `find-file-other-window'." t nil)
+
+(autoload 'switch-window-then-find-file-read-only "switch-window" "\
+Select a window, then find a file in it, read-only.
+
+Designed to replace `find-file-read-only-other-window'." t nil)
+
+(autoload 'switch-window-then-display-buffer "switch-window" "\
+Select a window, display a buffer in it, then return.
+
+Designed to replace `display-buffer'." t nil)
+
+(autoload 'switch-window-then-kill-buffer "switch-window" "\
+Select a window, then kill its buffer, then close it.
+
+Designed to replace `kill-buffer-and-window'." t nil)
+
+(autoload 'switch-window-then-dired "switch-window" "\
+Select a window, then dired in it.
+
+Designed to replace `dired-other-window'." t nil)
+
+(autoload 'switch-window-then-compose-mail "switch-window" "\
+Select a window, then start composing mail in it.
+
+Designed to replace `compose-mail-other-window'." t nil)
+
+(register-definition-prefixes "switch-window" '("delete-other-window" "switch-window-"))
+
+;;;***
+
+;;;### (autoloads nil "switch-window-asciiart" "switch-window-asciiart.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from switch-window-asciiart.el
+
+(register-definition-prefixes "switch-window-asciiart" '("switch-window-asciiart"))
+
+;;;***
+
+;;;### (autoloads nil "switch-window-mvborder" "switch-window-mvborder.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from switch-window-mvborder.el
+
+(register-definition-prefixes "switch-window-mvborder" '("switch-window-"))
+
+;;;***
+
+;;;### (autoloads nil nil ("switch-window-pkg.el") (0 0 0 0))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; coding: utf-8
+;; End:
+;;; switch-window-autoloads.el ends here
diff --git a/elpa/switch-window-20210808.742/switch-window-mvborder.el b/elpa/switch-window-20210808.742/switch-window-mvborder.el
new file mode 100644
index 0000000..b6bb770
--- /dev/null
+++ b/elpa/switch-window-20210808.742/switch-window-mvborder.el
@@ -0,0 +1,72 @@
+;;; switch-window-mvborder.el --- Move border of emacs window. -*- lexical-binding: t -*-
+
+;; * Header
+;; Copyright (c) the unknown original author
+
+;; I found the original code on a blog where the blog author
+;; is also saying that he is not the author.
+;; So, no one knows who is the author.
+
+;; If you are the author, please send me a word.
+
+;; Author: Unknown
+;; URL: https://www.emacswiki.org/emacs/WindowResize
+;; https://www.emacswiki.org/emacs/GrowShrinkWindows
+;; https://github.com/ramnes/move-border
+;;
+
+;;; Commentary:
+
+;;; Code:
+
+;; * Code :code:
+
+(defcustom switch-window-mvborder-increment 5
+ "A value to resize the window by when no prefix is specified."
+ :type 'integer
+ :group 'switch-window)
+
+(defun switch-window--xor (b1 b2)
+ (or (and b1 b2)
+ (and (not b1) (not b2))))
+
+(defun switch-window--mvborder-left-or-right (arg dir)
+ "General function covering switch-window-mvborder-left and switch-window-mvborder-right.
+If DIR is t, then move left, otherwise move right."
+ (when (null arg)
+ (setq arg switch-window-mvborder-increment))
+ (let ((left-edge (nth 0 (window-edges))))
+ (if (switch-window--xor (= left-edge 0) dir)
+ (shrink-window arg t)
+ (enlarge-window arg t))))
+
+(defun switch-window--mvborder-up-or-down (arg dir)
+ "General function covering switch-window-mvborder-up and switch-window-mvborder-down.
+If DIR is t, then move up, otherwise move down."
+ (when (null arg)
+ (setq arg switch-window-mvborder-increment))
+ (let ((top-edge (nth 1 (window-edges))))
+ (if (switch-window--xor (= top-edge 0) dir)
+ (shrink-window arg nil)
+ (enlarge-window arg nil))))
+
+(defun switch-window-mvborder-left (arg)
+ (interactive "P")
+ (switch-window--mvborder-left-or-right arg t))
+
+(defun switch-window-mvborder-right (arg)
+ (interactive "P")
+ (switch-window--mvborder-left-or-right arg nil))
+
+(defun switch-window-mvborder-up (arg)
+ (interactive "P")
+ (switch-window--mvborder-up-or-down arg t))
+
+(defun switch-window-mvborder-down (arg)
+ (interactive "P")
+ (switch-window--mvborder-up-or-down arg nil))
+
+;; * Footer
+(provide 'switch-window-mvborder)
+
+;;; switch-window-mvborder.el ends here
diff --git a/elpa/switch-window-20210808.742/switch-window-mvborder.elc b/elpa/switch-window-20210808.742/switch-window-mvborder.elc
new file mode 100644
index 0000000..2702cda
--- /dev/null
+++ b/elpa/switch-window-20210808.742/switch-window-mvborder.elc
Binary files differ
diff --git a/elpa/switch-window-20210808.742/switch-window-pkg.el b/elpa/switch-window-20210808.742/switch-window-pkg.el
new file mode 100644
index 0000000..51f65f5
--- /dev/null
+++ b/elpa/switch-window-20210808.742/switch-window-pkg.el
@@ -0,0 +1,13 @@
+(define-package "switch-window" "20210808.742" "A *visual* way to switch window"
+ '((emacs "24"))
+ :commit "8d9fe251d8d38b223d643df975876356ddfc1b98" :authors
+ '(("Dimitri Fontaine" . "dim@tapoueh.org")
+ ("Feng Shu" . "tumashu@163.com"))
+ :maintainer
+ '("Dimitri Fontaine" . "dim@tapoueh.org")
+ :keywords
+ '("convenience")
+ :url "https://github.com/dimitri/switch-window")
+;; Local Variables:
+;; no-byte-compile: t
+;; End:
diff --git a/elpa/switch-window-20210808.742/switch-window.el b/elpa/switch-window-20210808.742/switch-window.el
new file mode 100644
index 0000000..e21a0ea
--- /dev/null
+++ b/elpa/switch-window-20210808.742/switch-window.el
@@ -0,0 +1,1017 @@
+;;; switch-window.el --- A *visual* way to switch window -*- lexical-binding: t -*-
+;;
+;; Copyright (C) 2010-2017 Dimitri Fontaine
+;; 2016-2017 Feng Shu
+;;
+;; Author: Dimitri Fontaine <dim@tapoueh.org>
+;; Feng Shu <tumashu@163.com>
+;; URL: https://github.com/dimitri/switch-window
+;; http://tapoueh.org/emacs/switch-window.html
+;; Git-URL: https://github.com/dimitri/switch-window.git
+;; Version: 1.6.1
+;; Created: 2010-04-30
+;; Keywords: convenience
+;; Licence: WTFPL, grab your copy here: http://sam.zoy.org/wtfpl/
+;; Package-Requires: ((emacs "24"))
+;;
+;; This file is NOT part of GNU Emacs.
+;;
+;;; Commentary:
+;;
+;; * What is switch-window :README:
+;; switch-window is an Emacs window switch tool, which offer a
+;; *visual* way to choose a window to switch to, delete, split
+;; or other operations.
+;;
+;; [[./snapshots/switch-window.png]]
+;;
+;; ** Installation
+;;
+;; 1. Config melpa source, please read: http://melpa.org/#/getting-started
+;; 2. M-x package-install RET switch-window RET
+;;
+;; Note: User can install switch-window with [[http://github.com/dimitri/el-get][El-Get]] too.
+;;
+;; ** Configure and Usage
+;;
+;; #+BEGIN_EXAMPLE
+;; (require 'switch-window)
+;; (global-set-key (kbd "C-x o") 'switch-window)
+;; (global-set-key (kbd "C-x 1") 'switch-window-then-maximize)
+;; (global-set-key (kbd "C-x 2") 'switch-window-then-split-below)
+;; (global-set-key (kbd "C-x 3") 'switch-window-then-split-right)
+;; (global-set-key (kbd "C-x 0") 'switch-window-then-delete)
+;;
+;; (global-set-key (kbd "C-x 4 d") 'switch-window-then-dired)
+;; (global-set-key (kbd "C-x 4 f") 'switch-window-then-find-file)
+;; (global-set-key (kbd "C-x 4 m") 'switch-window-then-compose-mail)
+;; (global-set-key (kbd "C-x 4 r") 'switch-window-then-find-file-read-only)
+;;
+;; (global-set-key (kbd "C-x 4 C-f") 'switch-window-then-find-file)
+;; (global-set-key (kbd "C-x 4 C-o") 'switch-window-then-display-buffer)
+;;
+;; (global-set-key (kbd "C-x 4 0") 'switch-window-then-kill-buffer)
+;; #+END_EXAMPLE
+;;
+;; When switch-window is enabled, user can use the below five keys:
+;;
+;; | key | command description |
+;; |-----+-----------------------|
+;; | "i" | Move the border up |
+;; | "k" | Move the border down |
+;; | "j" | Move the border left |
+;; | "l" | Move the border right |
+;; | "b" | Balance windows |
+;; |"SPC"| Resume auto-resize |
+;;
+;; If you want to customize this feature, please see variable:
+;; `switch-window-extra-map'.
+;;
+;; Note: if you use auto-resize window feature, you *must* know
+;; that when you execute above window operate commands, auto-resize
+;; feature will be disabled temporarily, you should use above "SPC"
+;; key to resume.
+;;
+;; ** Tips
+;;
+;; *** I want to select a window with "a-z" instead of "1-9".
+;; #+BEGIN_EXAMPLE
+;; (setq switch-window-shortcut-style 'qwerty)
+;; #+END_EXAMPLE
+;;
+;; Note: user can arrange qwerty shortcuts by variable
+;; `switch-window-qwerty-shortcuts'.
+;;
+;; *** I want to let window to show bigger label.
+;; The face of label is switch-window-label, user can change it :height
+;; with custiomize-face
+;;
+;; *** I want to *hide* window label when window's number < 3
+;; #+BEGIN_EXAMPLE
+;; (setq switch-window-threshold 2)
+;; #+END_EXAMPLE
+;;
+;; *** I want to select minibuffer with label "z".
+;; #+BEGIN_EXAMPLE
+;; (setq switch-window-minibuffer-shortcut ?z)
+;; #+END_EXAMPLE
+;;
+;; *** I want to auto resize a window when switch to it
+;; #+BEGIN_EXAMPLE
+;; (setq switch-window-auto-resize-window t)
+;; (setq switch-window-default-window-size 0.8) ;80% of frame size
+;; (switch-window-mouse-mode) ;auto resize when switch window with mouse
+;; #+END_EXAMPLE
+;;
+;; Advanced usage:
+;; #+BEGIN_EXAMPLE
+;; (setq switch-window-auto-resize-window
+;; (lambda ()
+;; (equal (buffer-name) "*scratch*"))) ;when return t, run auto switch
+;; (setq switch-window-default-window-size '(0.8 . 0.6)) ;80% width and 60% height of frame
+;; #+END_EXAMPLE
+;;
+;; By the way, you can use package [[https://github.com/roman/golden-ratio.el][golden-ratio]] also.
+;;
+;; *** Switch-window seem to conflict with Exwm, how to do?
+;; By default, switch-window get user's input with the help
+;; of function `read-event', this approach does not work well
+;; with [[https://github.com/ch11ng/exwm][Exwm]] (Emacs X window manager),
+;; user should set the below variable and use minibuffer
+;; to get input instead:
+;;
+;; #+BEGIN_EXAMPLE
+;; (setq switch-window-input-style 'minibuffer)
+;; #+END_EXAMPLE
+;;
+;; Note: if you use minibuffer to get input, the feature about
+;; `switch-window-minibuffer-shortcut' will not work well.
+;;
+;; *** I use text terminal, but I want *bigger* label.
+;; The only choice is using asciiart, which *draw* a bigger label
+;; with *small* ascii char.
+;;
+;; #+BEGIN_EXAMPLE
+;; (setq switch-window-shortcut-appearance 'asciiart)
+;; #+END_EXAMPLE
+;;
+;; [[./snapshots/switch-window-3.png]]
+;;
+;; *** I want to use image or icon as label.
+;; 1. Prepare your label images, rename them to:
+;; 1.png ... 9.png, a.png ... z.png.
+;;
+;; You can use other image types supported by
+;; Emacs, please see: `image-types'.
+;; 2. Put all above images to directory:
+;; `switch-window-image-directory'.
+;; 3. Set variable: `switch-window-shortcut-appearance'
+;; #+BEGIN_EXAMPLE
+;; (setq switch-window-shortcut-appearance 'image)
+;; #+END_EXAMPLE
+;;
+;; [[./snapshots/switch-window-2.png]]
+;;
+;; *** `switch-window-shortcut-appearance' can't satisfy my need. how to do?
+;; All you should do is hacking you own label buffer function,
+;; for example: my-switch-window-label-buffer-function, and set
+;; the below variable:
+;;
+;; #+BEGIN_EXAMPLE
+;; (setq switch-window-label-buffer-function
+;; 'my-switch-window-label-buffer-function)
+;; #+END_EXAMPLE
+;;
+;; *** Have any other similar package exist?
+;; - [[https://github.com/abo-abo/ace-window][ace-window]]
+;;
+;; ** Changelog
+;;
+;; *** 1.6.0 - 2018-06-06
+;; 1. Add switch-window-label face to control the appearance of label.
+;; 2. Remove `switch-window-increase', use switch-window-label face instead.
+;; 3. Show orig text with label: see `switch-window-background'
+;; 4. Switch between frames: see `switch-window-multiple-frames'
+;; 5. [incompatible] `switch-window-label-buffer-function''s arguments have changed,
+;; user should update when use it.
+;;
+;; *** 1.5.0 - 2017-04-29
+;; - Implement commands:
+;; 1. switch-window-then-maximize
+;; 2. switch-window-then-delete
+;; 3. switch-window-then-split-below
+;; 4. switch-window-then-split-right
+;; 5. switch-window-then-split-horizontally
+;; 6. switch-window-then-split-vertically
+;; 7. switch-window-then-swap-buffer
+;; - Let switch-window work well with Exwm (Emacs X window manager).
+;; - User can customize switch-window label's appearance.
+;;
+;; *** 1.0.0 - 2015-01-14
+;; - Please fixme.
+;;
+;; *** 0.11 - 2013-09-14
+;; - restore point to end-of-buffer for windows where it was the case after
+;; switching, fixing an anoying bug.
+;;
+;; *** 0.10 - 2011-06-19
+;; - implement M-x delete-other-window (thanks developernotes on github)
+;;
+;; *** 0.9 - 2010-11-11 - emacs22 called, it wants some support
+;; - implement a propertize based hack to support emacs22
+;;
+;; *** 0.8 - 2010-09-13 - 999
+;; - Suport more than 9 windows (with a single key to type)
+;; - Use quail-keyboard-layout to choose single key labels for windows
+;;
+;; *** 0.7 - 2010-08-23 - window-dedicated-p
+;; - temporarily unset the window dedicated flag for displaying the
+;; numbers, patch from René Kyllingstad <Rene@Kyllingstad.com>
+;; - fix timeout and RET handling wrt to not changing window selection
+;;
+;; *** 0.6 - 2010-08-12 - *Minibuf-1*
+;; - add support for selecting the minibuffer when it's active
+;; - some try at a better horizontal centering
+;; - assorted cleanup
+;;
+;; *** 0.5 - 2010-08-08 - Polishing
+;; - dim:switch-window-increase is now a maximum value
+
+;;; Code:
+;; * Switch-window's code
+
+(require 'cl-lib)
+(require 'quail)
+(require 'switch-window-asciiart)
+(require 'switch-window-mvborder)
+
+(defgroup switch-window nil
+ "switch-window customization group"
+ :group 'convenience)
+
+(defcustom switch-window-background nil
+ "When t, `switch-window' will dim out all buffers temporarily when used."
+ :type 'boolean
+ :group 'switch-window)
+
+(defcustom switch-window-timeout 5
+ "After this many seconds, cancel the window switching."
+ :type 'integer
+ :group 'switch-window)
+
+(defcustom switch-window-threshold 2
+ "Only active ‘switch-window’ after this many windows open."
+ :type 'integer
+ :group 'switch-window)
+
+(defcustom switch-window-relative nil
+ "Control the ordering of windows, when true this depends on current-window."
+ :type 'boolean
+ :group 'switch-window)
+
+(defcustom switch-window-shortcut-style 'quail
+ "Use either keyboard layout or alphabet shortcut style."
+ :type '(choice (const :tag "Alphabet" 'alphabet)
+ (const :tag "Keyboard Layout" 'quail)
+ (const :tag "Qwerty Homekeys Layout" 'qwerty))
+ :group 'switch-window)
+
+(defcustom switch-window-qwerty-shortcuts
+ '("a" "s" "d" "f" "j" "k" "l" ";" "g" "h"
+ "q" "w" "e" "r" "t" "y" "u" "i" "p"
+ "z" "x" "c" "v" "b" "n" "m")
+ "The list of characters used when ‘switch-window-shortcut-style’ is 'qwerty'."
+ :type 'list
+ :group 'switch-window)
+
+(defcustom switch-window-shortcut-appearance 'text
+ "Switch-window shortcut's appearance."
+ :type '(choice (const :tag "Show shortcut with text" 'text)
+ (const :tag "Show shortcut with Ascii art." 'asciiart)
+ (const :tag "Show shortcut with image." 'image))
+ :group 'switch-window)
+
+(defcustom switch-window-image-directory (locate-user-emacs-file "switch-window/image")
+ "Switch-window image directory.
+If `switch-window-shortcut-appearance' set to 'image, image file
+will be found in this directory."
+ :type 'directory
+ :group 'switch-window)
+
+(defcustom switch-window-label-buffer-function
+ 'switch-window--create-label-buffer
+ "Switch-window's label buffer function.
+This function is used to prepare a temp buffer to diplay
+a window's label string, two optional arguments:
+1. window Label string will be showed in this window.
+2. buffer Label string will be inserted into this buffer.
+3. label The window's shortcut string."
+ :type 'function
+ :group 'switch-window)
+
+(defcustom switch-window-input-style 'minibuffer
+ "Use `read-event' or `read-from-minibuffer' to get user's input."
+ :type '(choice (const :tag "Get input by read-event" 'read-event)
+ (const :tag "Get input from minibuffer" 'minibuffer))
+ :group 'switch-window)
+
+(defcustom switch-window-minibuffer-shortcut nil
+ "Whether to customize the minibuffer shortcut.
+Default to no customisation (nil), which will make the minibuffer
+take whatever the last short is. If a character is specified
+it will always use that key for the minibuffer shortcut.
+
+Note: this feature only works when the value
+of `switch-window-input-style' is 'default ."
+ :type '(choice (const :tag "Off" nil)
+ (character "m"))
+ :group 'switch-window)
+
+(defcustom switch-window-auto-resize-window nil
+ "Auto resize window's size when switch to a window.
+1. If its value is t, auto resize the selected window.
+2. If its value is a function without arguments,
+ when the returned value is non-nil, auto resize
+ the selected window."
+ :type '(choice boolean function)
+ :group 'switch-window)
+
+(defcustom switch-window-default-window-size 0.7
+ "The default auto resize window's size.
+1. If its value is nil, disable auto resize feature.
+2. If its value is a number (0<x<1), resize selected window to fraction of frame size.
+3. If its value is a number (0<x<1) cons, resize selected window to
+ car% of frame width and cdr% of frame height."
+ :type '(choice (const :tag "Off" nil)
+ (float :tag "Fraction of frame size")
+ (cons
+ :tag "Fractions of frame width and height"
+ (float :tag "Fraction of frame width")
+ (float :tag "Fraction of frame height")))
+ :group 'switch-window)
+
+(defcustom switch-window-finish-hook nil
+ "A hook, run when `switch-window--then' is finishd.
+Its hook function have no arguments."
+ :group 'switch-window
+ :type 'hook)
+
+(defcustom switch-window-preferred 'default
+ "Prefer default commands or helm/ivy style commands."
+ :type '(choice (const :tag "Emacs default" 'default)
+ (const :tag "Helm" 'helm)
+ (const :tag "Ivy or Counsel" 'ivy)
+ (const :tag "Ido" 'ido))
+ :group 'switch-window)
+
+(defvar switch-window-preferred-alist
+ '((helm
+ (find-file . helm-find-files)
+ (switch-to-buffer . helm-mini))
+ (ivy
+ (find-file . counsel-find-file)
+ (switch-to-buffer . ivy-switch-buffer))
+ (ido
+ (find-file . ido-find-file)
+ (switch-to-buffer . ido-switch-buffer)
+ (dired . ido-dired)))
+ "The settings of `switch-window-preferred'.")
+
+(defvar switch-window-extra-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map (kbd "i") 'switch-window-mvborder-up)
+ (define-key map (kbd "k") 'switch-window-mvborder-down)
+ (define-key map (kbd "j") 'switch-window-mvborder-left)
+ (define-key map (kbd "l") 'switch-window-mvborder-right)
+ (define-key map (kbd "b") 'balance-windows)
+ (define-key map (kbd "SPC") 'switch-window-resume-auto-resize-window)
+ map)
+ "Extra keymap for ‘switch-window’ input.
+Note: at the moment, it cannot bind commands, which will
+increase or decrease window's number, for example:
+`split-window-below' `split-window-right' `maximize'.")
+
+(defcustom switch-window-configuration-change-hook-inhibit nil
+ "Whether inhibit `window-configuration-change-hook' during ‘switch-window’."
+ :type 'boolean
+ :group 'switch-window)
+
+(defvar switch-window--temp-disable-auto-resize nil
+ "Disable auto resize window feature temporarily.")
+
+;; Fix warn when compile switch-window with emacs-no-x
+(defvar image-types)
+
+(defcustom switch-window-multiple-frames nil
+ "When non-nil, run `switch-window' across multiple frames."
+ :type 'boolean
+ :group 'switch-window)
+
+(defcustom switch-window-frame-list-function
+ 'visible-frame-list
+ "Function to get a list of frames.
+
+This function is used when `switch-window-multiple-frames' is non-nil."
+ :type 'function
+ :group 'switch-window)
+
+(defface switch-window-label
+ '((t (:inherit font-lock-builtin-face :height 3.0)))
+ "Face used by switch-window's key.")
+
+(defface switch-window-background
+ '((t (:foreground "gray40")))
+ "Face for switch-window background.")
+
+(defun switch-window--other-window-or-frame ()
+ "If `switch-window-multiple-frames' is set cycle through all visible
+windows from all frames. Call `other-window' otherwise."
+ (if switch-window-multiple-frames
+ (switch-window--select-window (next-window nil nil 'visible))
+ (other-window 1)))
+
+(defun switch-window--select-window (window)
+ "Switch to the window WINDOW. Select WINDOW's frame respecting
+`focus-follows-mouse' and `mouse-autoselect-window'."
+ (let ((new-frame (window-frame window))
+ (old-frame (selected-frame)))
+ (when (window-live-p window)
+ (select-window window)
+ (if (not (eq new-frame old-frame))
+ (select-frame-set-input-focus new-frame)))))
+
+(defun switch-window--list-keyboard-keys ()
+ "Return a list of current keyboard layout keys."
+ (cl-loop with layout = (split-string quail-keyboard-layout "")
+ for row from 1 to 4
+ nconc (cl-loop for col from 1 to 10
+ collect (nth (+ 1 (* 2 col) (* 30 row)) layout))))
+
+(defun switch-window--list-keys ()
+ "Return a list of keys to use depending on `switch-window-shortcut-style'."
+ (cl-remove-if
+ #'(lambda (key)
+ (or (and switch-window-minibuffer-shortcut
+ (equal key (char-to-string switch-window-minibuffer-shortcut)))
+ (lookup-key switch-window-extra-map key)))
+ (cond ((eq switch-window-shortcut-style 'qwerty)
+ switch-window-qwerty-shortcuts)
+ ((eq switch-window-shortcut-style 'alphabet)
+ (cl-loop for i from 0 to 25
+ collect (byte-to-string (+ (string-to-char "a") i))))
+ (t (switch-window--list-keyboard-keys)))))
+
+(defun switch-window--enumerate ()
+ "Return a list of one-letter strings to label current windows."
+ (cl-loop for w in (switch-window--list)
+ for x in (switch-window--list-keys)
+ collect (if (and switch-window-minibuffer-shortcut
+ (minibuffer-window-active-p w))
+ (char-to-string switch-window-minibuffer-shortcut)
+ x)))
+
+(defun switch-window--label (num)
+ "Return the label to use for a given window NUM."
+ (nth (- num 1) (switch-window--enumerate)))
+
+(defun switch-window--list (&optional from-current-window)
+ "List windows for current frame.
+It will start at top left unless FROM-CURRENT-WINDOW is not nil"
+ (let ((relative (or from-current-window
+ switch-window-relative))
+ (frames (if (bound-and-true-p switch-window-multiple-frames)
+ (funcall switch-window-frame-list-function)
+ (list (selected-frame)))))
+ (cl-loop for frm in (if relative
+ (cons (selected-frame)
+ (cl-remove (selected-frame) frames))
+ (cl-sort frames
+ 'switch-window--compare-frame-positions))
+ append (window-list frm nil
+ (unless (and relative
+ (equal frm (selected-frame)))
+ (frame-first-window frm))))))
+
+(defun switch-window--compare-frame-positions (frm1 frm2)
+ "Compare positions between two frames FRM1 and FRM2."
+ (cl-destructuring-bind
+ ((x1 . y1) (x2 . y2))
+ (list (frame-position frm1) (frame-position frm2))
+ (cond
+ ((< x1 x2) t)
+ ((> x1 x2) nil)
+ ((< y1 y2) t)
+ (t nil))))
+
+(defun switch-window--display-number (win num)
+ "Prepare a temp buffer to diplay NUM in the window WIN while choosing."
+ (let* ((label (switch-window--label num))
+ (buffer (get-buffer-create
+ (format " *%s: %s*"
+ label (buffer-name (window-buffer win)))))
+ (background (switch-window--window-substring win)))
+ (funcall switch-window-label-buffer-function win buffer label background)
+ (set-window-buffer win buffer switch-window-background)
+ buffer))
+
+(defun switch-window--window-substring (window)
+ "Get the buffer substring of window."
+ (let ((height (window-height)))
+ (with-current-buffer (window-buffer window)
+ (save-excursion
+ (let ((b (line-beginning-position))
+ (c (line-end-position))
+ (a (progn
+ (forward-line (* (/ height 2) -1))
+ (point)))
+ (d (progn
+ (forward-line height)
+ (point))))
+ (concat (propertize
+ (buffer-substring-no-properties a b)
+ 'face 'switch-window-background)
+ (buffer-substring b c)
+ (propertize
+ (buffer-substring-no-properties c d)
+ 'face 'switch-window-background)))))))
+
+(defun switch-window--create-label-buffer (&optional _window buffer label background)
+ "The default LABEL BUFFER create funcion."
+ (with-current-buffer buffer
+ (setq truncate-lines t)
+ (when switch-window-background
+ (insert background)
+ (goto-char (point-min)))
+ (cond
+ ((eq switch-window-shortcut-appearance 'asciiart)
+ (setq line-spacing nil)
+ (let* ((lines (split-string
+ (replace-regexp-in-string
+ "^\n" ""
+ (nth (cl-position
+ label
+ (remove "" (split-string "123456789abcdefjhijklmnopqrstuvwxyz" ""))
+ :test #'equal)
+ switch-window-asciiart))
+ "\n"))
+ (num (apply #'max (mapcar #'length lines))))
+ ;; Deal with "let: End of buffer" problem.
+ ;; Maybe not beautiful, but simple :-)
+ (goto-char (point-max))
+ (dotimes (_ 20)
+ (insert (make-string num ? ))
+ (insert "\n"))
+ (goto-char (point-min))
+ (dolist (line lines)
+ (delete-char num)
+ (insert (format (concat "%-" (number-to-string num) "s") line))
+ (insert " ")
+ (forward-line 1))))
+ ((eq switch-window-shortcut-appearance 'text)
+ (insert (propertize label 'face 'switch-window-label)))
+ ((eq switch-window-shortcut-appearance 'image)
+ (let ((types (cl-copy-seq image-types))
+ file)
+ (while types
+ (let* ((type (pop types))
+ (file1 (format "%s%s.%S"
+ (file-name-as-directory switch-window-image-directory)
+ label type)))
+ (when (file-exists-p file1)
+ (setq file file1)
+ (setq types nil))))
+ (if (and file (display-images-p))
+ (insert-image-file (expand-file-name file))
+ (insert (propertize label 'face 'switch-window-label))))))
+ (insert " ")
+ (goto-char (point-min))
+ (setq-local buffer-read-only t)
+ (setq-local show-trailing-whitespace nil)
+ buffer))
+
+(defun switch-window--jump-to-window (index)
+ "Jump to the window depend on INDEX."
+ (cl-loop for c from 1
+ for win in (switch-window--list)
+ until (= c index)
+ finally (switch-window--select-window win)))
+
+(defun switch-window--list-eobp ()
+ "Return a list of all the windows where `eobp' is currently true.
+so that we can restore that important property (think
+ auto scrolling) after switching."
+ (cl-loop for win in (switch-window--list)
+ when (with-current-buffer (window-buffer win) (eobp))
+ collect win))
+
+(defun switch-window--restore-eobp (eobp-window-list)
+ "For each window in EOBP-WINDOW-LIST move the point to end of buffer."
+ (cl-loop for win in eobp-window-list
+ do (let ((buffer (window-buffer win)))
+ (when buffer
+ (with-current-buffer buffer
+ (goto-char (point-max)))))))
+
+;;;###autoload
+(defun switch-window-then-delete ()
+ "Display an overlay in each window showing a unique key.
+In the mean time, user will be asked to choose the window deleted."
+ (interactive)
+ (switch-window--then
+ "Delete window: "
+ #'delete-window
+ #'delete-window t))
+
+(defalias 'delete-other-window 'switch-window-then-delete)
+(make-obsolete 'delete-other-window 'switch-window-then-delete
+ "switch-window version 0.2")
+
+;;;###autoload
+(defun switch-window-then-maximize ()
+ "Display an overlay in each window showing a unique key.
+In the mean time, ask user which window to maximize"
+ (interactive)
+ (switch-window--then
+ "Maximize window: "
+ #'delete-other-windows
+ #'delete-other-windows t))
+
+;;;###autoload
+(defun switch-window ()
+ "Display an overlay in each window showing a unique key.
+In the mean time, ask user for the window where move to"
+ (interactive)
+ (switch-window--then
+ "Move to window: "
+ #'switch-window--other-window-or-frame))
+
+;;;###autoload
+(defun switch-window-then-split-horizontally (arg)
+ "Select a window then split it horizontally.
+Argument ARG ."
+ (interactive "P")
+ (switch-window--then
+ "Horiz-split window: "
+ #'split-window-horizontally
+ #'split-window-horizontally arg 1))
+
+;;;###autoload
+(defun switch-window-then-split-vertically (arg)
+ "Select a window then split it vertically.
+Argument ARG ."
+ (interactive "P")
+ (switch-window--then
+ "Verti-split window: "
+ #'split-window-vertically
+ #'split-window-vertically arg 1))
+
+;;;###autoload
+(defun switch-window-then-split-below (arg)
+ "Select a window then split it with split-window-below's mode.
+TODO: Argument ARG."
+ (interactive "P")
+ (switch-window--then
+ "Below-split window: "
+ #'split-window-below
+ #'split-window-below arg 1))
+
+;;;###autoload
+(defun switch-window-then-split-right (arg)
+ "Select a window then split it with split-window-right's mode.
+TODO: Argument ARG ."
+ (interactive "P")
+ (switch-window--then
+ "Right-split window: "
+ #'split-window-right
+ #'split-window-right arg 1))
+
+;;;###autoload
+(defun switch-window-then-swap-buffer (&optional keep-focus)
+ "Swap the current window's buffer with a selected window's buffer.
+
+Move the focus on the newly selected window unless KEEP-FOCUS is
+non-nil (aka keep the focus on the current window).
+
+When a window is strongly dedicated to its buffer, this function
+won't take effect, and no buffers will be switched."
+ (interactive "P")
+ (let ((buffer1 (window-buffer))
+ (window1 (get-buffer-window))
+ buffer2 window2)
+ (if (window-dedicated-p window1)
+ (message "The current window has a dedicated buffer: `%s'" (buffer-name buffer1))
+ (switch-window)
+ (setq buffer2 (current-buffer))
+ (setq window2 (get-buffer-window))
+ (if (window-dedicated-p window2)
+ (progn
+ (select-window window1)
+ (message "The selected window has a dedicated buffer: `%s'" (buffer-name buffer2)))
+ (set-window-buffer window2 buffer1 t)
+ (set-window-buffer window1 buffer2 t)
+ (if keep-focus
+ (switch-window--select-window window1))))))
+
+;;;###autoload
+(defun switch-window-then-find-file ()
+ "Select a window, then find a file in it.
+
+Designed to replace `find-file-other-window'."
+ (interactive)
+ (switch-window--then-other-window
+ "Find file in window: "
+ #'find-file))
+
+;;;###autoload
+(defun switch-window-then-find-file-read-only ()
+ "Select a window, then find a file in it, read-only.
+
+Designed to replace `find-file-read-only-other-window'."
+ (interactive)
+ (switch-window--then-other-window
+ "Find file read-only in window: "
+ #'find-file-read-only))
+
+;;;###autoload
+(defun switch-window-then-display-buffer ()
+ "Select a window, display a buffer in it, then return.
+
+Designed to replace `display-buffer'."
+ (interactive)
+ (let ((original-window (selected-window)))
+ (switch-window--then-other-window
+ "Show buffer in window: "
+ #'switch-to-buffer)
+ (switch-window--select-window original-window)))
+
+;;;###autoload
+(defun switch-window-then-kill-buffer ()
+ "Select a window, then kill its buffer, then close it.
+
+Designed to replace `kill-buffer-and-window'."
+ (interactive)
+ (switch-window--then-other-window
+ "Window to kill: "
+ #'kill-buffer-and-window))
+
+;;;###autoload
+(defun switch-window-then-dired ()
+ "Select a window, then dired in it.
+
+Designed to replace `dired-other-window'."
+ (interactive)
+ (switch-window--then-other-window
+ "Dired in window: "
+ #'dired))
+
+;;;###autoload
+(defun switch-window-then-compose-mail ()
+ "Select a window, then start composing mail in it.
+
+Designed to replace `compose-mail-other-window'."
+ (interactive)
+ (switch-window--then-other-window
+ "Compose mail in window: "
+ #'compose-mail))
+
+(defun switch-window--get-preferred-function (function)
+ "Get the preferred FUNCTION based on `switch-window-preferred'."
+ (or (cdr (assq function
+ (cdr (assq switch-window-preferred
+ switch-window-preferred-alist))))
+ function))
+
+(defun switch-window--then-other-window (prompt function)
+ "PROMPT a question and let use select or create a window to run FUNCTION."
+ (let ((f (switch-window--get-preferred-function function)))
+ (switch-window--then
+ prompt
+ (lambda ()
+ (select-window
+ (if (one-window-p)
+ (split-window-right)
+ (next-window)))
+ (call-interactively f))
+ (lambda () (call-interactively f))
+ nil
+ 2)))
+
+(defun switch-window--then (prompt function1 &optional function2
+ return-original-window threshold)
+ "Prompt a PROMPT, let user switch to a window to do something.
+
+If the number of opened window is less than THRESHOLD,
+call FUNCTION1 in current window, otherwise, switch to
+the window assocated with the typed key, then call FUNCTION2.
+
+1. FUNCTION1 and FUNCTION2 are functions with no arguments.
+2. When RETURN-ORIGINAL-WINDOW is t, switch to original window
+ after FUNCTION2 is called.
+3. When THRESHOLD is not a number, use the value of
+ ‘switch-window-threshold’ instead."
+ (if (<= (length (switch-window--list))
+ (if (numberp threshold)
+ threshold
+ switch-window-threshold))
+ (when (functionp function1)
+ (funcall function1))
+ (let ((orig-window (selected-window))
+ (index (switch-window--prompt prompt))
+ (eobps (switch-window--list-eobp)))
+ (switch-window--jump-to-window index)
+ (when (functionp function2)
+ (funcall function2))
+ (when (and return-original-window
+ (window-live-p orig-window))
+ (switch-window--select-window orig-window))
+ (switch-window--restore-eobp eobps)))
+ (switch-window--auto-resize-window)
+ (run-hooks 'switch-window-finish-hook))
+
+(defun switch-window--get-input (prompt-message minibuffer-num eobps)
+ "Get user's input with the help of `read-event'.
+Arguments: PROMPT-MESSAGE MINIBUFFER-NUM EOBPS."
+ (let (key)
+ (while (not key)
+ (let ((input (event-basic-type
+ (read-event
+ (if minibuffer-num
+ (format "Move to window [minibuffer is %s]: "
+ (if switch-window-minibuffer-shortcut
+ (char-to-string switch-window-minibuffer-shortcut)
+ (switch-window--label minibuffer-num)))
+ prompt-message)
+ nil switch-window-timeout))))
+ (if (or (null input) (eq input 'return))
+ (progn
+ (switch-window--restore-eobp eobps)
+ (keyboard-quit)) ; timeout or RET
+ (unless (symbolp input)
+ (let* ((wchars (mapcar 'string-to-char
+ (switch-window--enumerate)))
+ (pos (cl-position input wchars))
+ (extra-function
+ (lookup-key switch-window-extra-map
+ (char-to-string input))))
+ (cond
+ (extra-function
+ (call-interactively extra-function)
+ ;; Commands in `switch-window-extra-map' mainly are window-resize commands.
+ ;; If we use these commands, theirs effects should not be override by
+ ;; auto-resize feature.
+ (unless (eq extra-function 'switch-window-resume-auto-resize-window)
+ (setq switch-window--temp-disable-auto-resize t)))
+ (pos (setq key (1+ pos)))
+ (t (switch-window--restore-eobp eobps)
+ (keyboard-quit))))))))
+ key))
+
+(defun switch-window--get-minibuffer-input (prompt-message minibuffer-num eobps)
+ "Get user's input with the help of `read-from-minibuffer'.
+Arguments: PROMPT-MESSAGE MINIBUFFER-NUM EOBPS."
+ (let (key)
+ (while (not key)
+ (let ((input (read-from-minibuffer
+ (if minibuffer-num
+ (format "Move to window [minibuffer is %s]: "
+ (if switch-window-minibuffer-shortcut
+ (char-to-string switch-window-minibuffer-shortcut)
+ (switch-window--label minibuffer-num)))
+ prompt-message)
+ nil
+ (let ((map (copy-keymap minibuffer-local-map))
+ (i ?\ ))
+ (while (< i 127)
+ (define-key map (char-to-string i)
+ (lambda ()
+ (interactive)
+ (self-insert-command 1)
+ (exit-minibuffer)))
+ (setq i (1+ i)))
+ map))))
+ (if (< (length input) 1)
+ (switch-window--restore-eobp eobps)
+ (let ((pos (cl-position input (switch-window--enumerate)
+ :test #'equal))
+ (extra-function
+ (lookup-key switch-window-extra-map input)))
+ (cond
+ (extra-function
+ (call-interactively extra-function)
+ ;; Commands in `switch-window-extra-map' mainly are window resize commands.
+ ;; If we use these commands, theirs effects should not be override by
+ ;; auto-resize feature.
+ (unless (eq extra-function 'switch-window-resume-auto-resize-window)
+ (setq switch-window--temp-disable-auto-resize t)))
+ (pos (setq key (1+ pos)))
+ (t (switch-window--restore-eobp eobps)))))))
+ key))
+
+(defun switch-window--prompt (prompt-message)
+ "Display an overlay in each window showing a unique key.
+In the mean time, prompt PROMPT-MESSAGE and let user select
+a window"
+ (let ((window-configuration-change-hook
+ (unless switch-window-configuration-change-hook-inhibit
+ window-configuration-change-hook))
+ (original-cursor (default-value 'cursor-type))
+ (eobps (switch-window--list-eobp))
+ (minibuffer-num nil)
+ (num 1)
+ key label-buffers
+ window-buffers window-margins window-points dedicated-windows)
+
+ ;; arrange so that C-g will get back to previous window configuration
+ (unwind-protect
+ (progn
+ ;; hide cursor during window selection process
+ (setq-default cursor-type nil)
+ ;; save window's buffer, point and dedicate state.
+ ;; then display label buffers in all window.
+ (dolist (win (switch-window--list))
+ (push (cons win (window-buffer win)) window-buffers)
+ (push (cons win (window-margins win)) window-margins)
+ (push (cons win (window-point win)) window-points)
+ (when (window-dedicated-p win)
+ (push (cons win (window-dedicated-p win)) dedicated-windows)
+ (set-window-dedicated-p win nil))
+ (if (minibuffer-window-active-p win)
+ (setq minibuffer-num num)
+ (push (switch-window--display-number win num) label-buffers))
+ (setq num (1+ num)))
+ ;; get user's input
+ (cond ((eq switch-window-input-style 'read-event)
+ (setq key (switch-window--get-input
+ prompt-message minibuffer-num eobps)))
+ ((member switch-window-input-style '(default minibuffer))
+ (setq key (switch-window--get-minibuffer-input
+ prompt-message minibuffer-num eobps)))))
+ ;; clean input-method-previous-message
+ (setq input-method-previous-message nil)
+ ;; restore original cursor
+ (setq-default cursor-type original-cursor)
+ ;; Restore window's buffer, point and dedicate state.
+ (dolist (w window-buffers)
+ (set-window-buffer (car w) (cdr w) t))
+ ;; Restore window's margins.
+ (dolist (w window-margins)
+ (set-window-margins (car w) (cadr w) (cddr w)))
+ (dolist (w window-points)
+ (set-window-point (car w) (cdr w)))
+ (dolist (w dedicated-windows)
+ (set-window-dedicated-p (car w) (cdr w)))
+
+ ;; remove all label-buffers, useless now.
+ ;; it's important to remove temporary label buffers after restoring original buffers
+ ;; because for protected windows it will also kill the window via `replace-buffer-in-windows''`
+ ;; according to https://www.gnu.org/software/emacs/manual/html_node/elisp/Killing-Buffers.html
+ ;; for protected window a temporary lable buffer will be the only it displays
+ ;; For example, it will kill Treemacs buffer and it's window
+ ;; thus failing to restore it if you run the killing loop before.
+ (mapc 'kill-buffer label-buffers))
+ key))
+
+(define-minor-mode switch-window-mouse-mode
+ "Enable auto resize window when switch window with mouse."
+ :global t
+ :require 'switch-window
+ (if switch-window-mouse-mode
+ (add-hook 'mouse-leave-buffer-hook
+ #'switch-window--mouse-auto-resize-window)
+ (remove-hook 'mouse-leave-buffer-hook
+ #'switch-window--mouse-auto-resize-window)))
+
+(defun switch-window--mouse-auto-resize-window ()
+ "Auto resize window when switch window with mouse."
+ (run-at-time 0.1 nil #'switch-window--auto-resize-window))
+
+(defun switch-window-resume-auto-resize-window ()
+ "Resume auto resize window feature.
+It is temporarily disabled by commands in
+`switch-window-extra-map'."
+ (interactive)
+ (setq switch-window--temp-disable-auto-resize nil))
+
+(defun switch-window--auto-resize-window ()
+ "Auto resize window's size when switch to window."
+ (when (and (not switch-window--temp-disable-auto-resize)
+ (if (functionp switch-window-auto-resize-window)
+ (funcall switch-window-auto-resize-window)
+ switch-window-auto-resize-window)
+ (not (window-minibuffer-p))
+ (not (one-window-p)))
+ (let ((arg switch-window-default-window-size)
+ n1 n2)
+ (cond ((and (numberp arg) (< 0 arg 1))
+ (setq n1 arg)
+ (setq n2 arg))
+ ((and (consp arg)
+ (numberp (car arg))
+ (numberp (cdr arg))
+ (< 0 (car arg) 1)
+ (< 0 (cdr arg) 1))
+ (setq n1 (car arg))
+ (setq n2 (cdr arg)))
+ (t (setq n1 nil)
+ (setq n2 nil)
+ (message "The value of `switch-window-default-window-size' is invalid.")))
+ (when (and n1 n2)
+ (with-selected-window (selected-window)
+ (let ((ncol (floor (- (* (frame-width) n1)
+ (window-width))))
+ (nrow (floor (- (* (frame-height) n2)
+ (window-height)))))
+ (when (window-resizable-p (selected-window) nrow)
+ (enlarge-window nrow))
+ (when (window-resizable-p (selected-window) ncol t)
+ (enlarge-window ncol t)))))))
+ (when (and switch-window-auto-resize-window
+ switch-window--temp-disable-auto-resize)
+ (message
+ (substitute-command-keys
+ "Switch-window: resume auto-resize with `\\[switch-window-resume-auto-resize-window]'"))
+ (message "")))
+
+
+(provide 'switch-window)
+;;; switch-window.el ends here
diff --git a/elpa/switch-window-20210808.742/switch-window.elc b/elpa/switch-window-20210808.742/switch-window.elc
new file mode 100644
index 0000000..b394089
--- /dev/null
+++ b/elpa/switch-window-20210808.742/switch-window.elc
Binary files differ
diff --git a/elpa/transient-20220503.1118/dir b/elpa/transient-20220503.1118/dir
new file mode 100644
index 0000000..4d6ad7f
--- /dev/null
+++ b/elpa/transient-20220503.1118/dir
@@ -0,0 +1,18 @@
+This is the file .../info/dir, which contains the
+topmost node of the Info hierarchy, called (dir)Top.
+The first time you invoke Info you start off looking at this node.
+
+File: dir, Node: Top This is the top of the INFO tree
+
+ This (the Directory node) gives a menu of major topics.
+ Typing "q" exits, "H" lists all Info commands, "d" returns here,
+ "h" gives a primer for first-timers,
+ "mEmacs<Return>" visits the Emacs manual, etc.
+
+ In Emacs, you can click mouse button 2 on a menu item or cross reference
+ to select it.
+
+* Menu:
+
+Emacs
+* Transient: (transient). Transient Commands.
diff --git a/elpa/transient-20220503.1118/transient-autoloads.el b/elpa/transient-20220503.1118/transient-autoloads.el
new file mode 100644
index 0000000..f78a417
--- /dev/null
+++ b/elpa/transient-20220503.1118/transient-autoloads.el
@@ -0,0 +1,80 @@
+;;; transient-autoloads.el --- automatically extracted autoloads -*- lexical-binding: t -*-
+;;
+;;; Code:
+
+(add-to-list 'load-path (directory-file-name
+ (or (file-name-directory #$) (car load-path))))
+
+
+;;;### (autoloads nil "transient" "transient.el" (0 0 0 0))
+;;; Generated autoloads from transient.el
+
+(autoload 'transient-insert-suffix "transient" "\
+Insert a SUFFIX into PREFIX before LOC.
+PREFIX is a prefix command, a symbol.
+SUFFIX is a suffix command or a group specification (of
+ the same forms as expected by `transient-define-prefix').
+LOC is a command, a key vector, a key description (a string
+ as returned by `key-description'), or a coordination list
+ (whose last element may also be a command or key).
+See info node `(transient)Modifying Existing Transients'.
+
+\(fn PREFIX LOC SUFFIX)" nil nil)
+
+(function-put 'transient-insert-suffix 'lisp-indent-function 'defun)
+
+(autoload 'transient-append-suffix "transient" "\
+Insert a SUFFIX into PREFIX after LOC.
+PREFIX is a prefix command, a symbol.
+SUFFIX is a suffix command or a group specification (of
+ the same forms as expected by `transient-define-prefix').
+LOC is a command, a key vector, a key description (a string
+ as returned by `key-description'), or a coordination list
+ (whose last element may also be a command or key).
+See info node `(transient)Modifying Existing Transients'.
+
+\(fn PREFIX LOC SUFFIX)" nil nil)
+
+(function-put 'transient-append-suffix 'lisp-indent-function 'defun)
+
+(autoload 'transient-replace-suffix "transient" "\
+Replace the suffix at LOC in PREFIX with SUFFIX.
+PREFIX is a prefix command, a symbol.
+SUFFIX is a suffix command or a group specification (of
+ the same forms as expected by `transient-define-prefix').
+LOC is a command, a key vector, a key description (a string
+ as returned by `key-description'), or a coordination list
+ (whose last element may also be a command or key).
+See info node `(transient)Modifying Existing Transients'.
+
+\(fn PREFIX LOC SUFFIX)" nil nil)
+
+(function-put 'transient-replace-suffix 'lisp-indent-function 'defun)
+
+(autoload 'transient-remove-suffix "transient" "\
+Remove the suffix or group at LOC in PREFIX.
+PREFIX is a prefix command, a symbol.
+LOC is a command, a key vector, a key description (a string
+ as returned by `key-description'), or a coordination list
+ (whose last element may also be a command or key).
+See info node `(transient)Modifying Existing Transients'.
+
+\(fn PREFIX LOC)" nil nil)
+
+(function-put 'transient-remove-suffix 'lisp-indent-function 'defun)
+
+(register-definition-prefixes "transient" '("magit--fit-window-to-buffer" "transient-"))
+
+;;;***
+
+;;;### (autoloads nil nil ("transient-pkg.el") (0 0 0 0))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; coding: utf-8
+;; End:
+;;; transient-autoloads.el ends here
diff --git a/elpa/transient-20220503.1118/transient-pkg.el b/elpa/transient-20220503.1118/transient-pkg.el
new file mode 100644
index 0000000..24dceb5
--- /dev/null
+++ b/elpa/transient-20220503.1118/transient-pkg.el
@@ -0,0 +1,13 @@
+(define-package "transient" "20220503.1118" "Transient commands"
+ '((emacs "25.1")
+ (compat "28.1.1.0"))
+ :commit "8c62d0d223e90f53b29c439ba2f86b6e721d8209" :authors
+ '(("Jonas Bernoulli" . "jonas@bernoul.li"))
+ :maintainer
+ '("Jonas Bernoulli" . "jonas@bernoul.li")
+ :keywords
+ '("extensions")
+ :url "https://github.com/magit/transient")
+;; Local Variables:
+;; no-byte-compile: t
+;; End:
diff --git a/elpa/transient-20220503.1118/transient.el b/elpa/transient-20220503.1118/transient.el
new file mode 100644
index 0000000..c02f920
--- /dev/null
+++ b/elpa/transient-20220503.1118/transient.el
@@ -0,0 +1,4073 @@
+;;; transient.el --- Transient commands -*- lexical-binding:t -*-
+
+;; Copyright (C) 2018-2022 Free Software Foundation, Inc.
+
+;; Author: Jonas Bernoulli <jonas@bernoul.li>
+;; Homepage: https://github.com/magit/transient
+;; Keywords: extensions
+
+;; Package-Version: 0.3.7-git
+;; Package-Requires: ((emacs "25.1") (compat "28.1.1.0"))
+
+;; SPDX-License-Identifier: GPL-3.0-or-later
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs 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.
+;;
+;; GNU Emacs 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Taking inspiration from prefix keys and prefix arguments, Transient
+;; implements a similar abstraction involving a prefix command, infix
+;; arguments and suffix commands. We could call this abstraction a
+;; "transient command", but because it always involves at least two
+;; commands (a prefix and a suffix) we prefer to call it just a
+;; "transient".
+
+;; When the user calls a transient prefix command, then a transient
+;; (temporary) keymap is activated, which binds the transient's infix
+;; and suffix commands, and functions that control the transient state
+;; are added to `pre-command-hook' and `post-command-hook'. The
+;; available suffix and infix commands and their state are shown in
+;; the echo area until the transient is exited by invoking a suffix
+;; command.
+
+;; Calling an infix command causes its value to be changed, possibly
+;; by reading a new value in the minibuffer.
+
+;; Calling a suffix command usually causes the transient to be exited
+;; but suffix commands can also be configured to not exit the
+;; transient state.
+
+;;; Code:
+
+(require 'cl-lib)
+(require 'compat)
+(require 'eieio)
+(require 'edmacro)
+(require 'format-spec)
+(require 'seq)
+
+(eval-when-compile (require 'subr-x))
+
+(declare-function info 'info)
+(declare-function Man-find-section 'man)
+(declare-function Man-next-section 'man)
+(declare-function Man-getpage-in-background 'man)
+
+(defvar display-line-numbers) ; since Emacs 26.1
+(defvar Man-notify-method)
+
+(define-obsolete-function-alias 'define-transient-command
+ 'transient-define-prefix "Transient 0.3.0")
+(define-obsolete-function-alias 'define-suffix-command
+ 'transient-define-suffix "Transient 0.3.0")
+(define-obsolete-function-alias 'define-infix-command
+ 'transient-define-infix "Transient 0.3.0")
+(define-obsolete-function-alias 'define-infix-argument
+ #'transient-define-argument "Transient 0.3.0")
+
+(define-obsolete-variable-alias 'transient--source-buffer
+ 'transient--original-buffer "Transient 0.2.0")
+(define-obsolete-variable-alias 'current-transient-prefix
+ 'transient-current-prefix "Transient 0.3.0")
+(define-obsolete-variable-alias 'current-transient-command
+ 'transient-current-command "Transient 0.3.0")
+(define-obsolete-variable-alias 'current-transient-suffixes
+ 'transient-current-suffixes "Transient 0.3.0")
+(define-obsolete-variable-alias 'post-transient-hook
+ 'transient-exit-hook "Transient 0.3.0")
+
+(defmacro transient--with-emergency-exit (&rest body)
+ (declare (indent defun))
+ `(condition-case err
+ (let ((debugger #'transient--exit-and-debug))
+ ,(macroexp-progn body))
+ ((debug error)
+ (transient--emergency-exit)
+ (signal (car err) (cdr err)))))
+
+(defun transient--exit-and-debug (&rest args)
+ (transient--emergency-exit)
+ (apply #'debug args))
+
+;;; Options
+
+(defgroup transient nil
+ "Transient commands."
+ :group 'extensions)
+
+(defcustom transient-show-popup t
+ "Whether to show the current transient in a popup buffer.
+
+- If t, then show the popup as soon as a transient prefix command
+ is invoked.
+
+- If nil, then do not show the popup unless the user explicitly
+ requests it, by pressing an incomplete prefix key sequence.
+
+- If a number, then delay displaying the popup and instead show
+ a brief one-line summary. If zero or negative, then suppress
+ even showing that summary and display the pressed key only.
+
+ Show the popup when the user explicitly requests it by pressing
+ an incomplete prefix key sequence. Unless zero, then also show
+ the popup after that many seconds of inactivity (using the
+ absolute value)."
+ :package-version '(transient . "0.1.0")
+ :group 'transient
+ :type '(choice (const :tag "instantly" t)
+ (const :tag "on demand" nil)
+ (const :tag "on demand (no summary)" 0)
+ (number :tag "after delay" 1)))
+
+(defcustom transient-enable-popup-navigation t
+ "Whether navigation commands are enabled in the transient popup.
+
+While a transient is active the transient popup buffer is not the
+current buffer, making it necessary to use dedicated commands to
+act on that buffer itself. If this is non-nil, then the following
+bindings are available:
+
+\\<transient-popup-navigation-map>\
+- \\[transient-backward-button] moves the cursor to the previous suffix.
+- \\[transient-forward-button] moves the cursor to the next suffix.
+- \\[transient-push-button] invokes the suffix the cursor is on.
+\\<transient-button-map>\
+- \\`<mouse-1>' and \\`<mouse-2>' invoke the clicked on suffix.
+\\<transient-popup-navigation-map>\
+- \\[transient-isearch-backward]\
+ and \\[transient-isearch-forward] start isearch in the popup buffer.
+
+\\`<mouse-1>' and \\`<mouse-2>' are bound in `transient-push-button'.
+All other bindings are in `transient-popup-navigation-map'.
+
+By default \\`M-RET' is bound to `transient-push-button', instead of
+\\`RET', because if a transient allows the invocation of non-suffixes
+then it is likely that you would want \\`RET' to do what it would do
+if no transient were active."
+ :package-version '(transient . "0.4.0")
+ :group 'transient
+ :type 'boolean)
+
+(defcustom transient-display-buffer-action
+ '(display-buffer-in-side-window
+ (side . bottom)
+ (dedicated . t)
+ (inhibit-same-window . t)
+ (window-parameters (no-other-window . t)))
+ "The action used to display the transient popup buffer.
+
+The transient popup buffer is displayed in a window using
+
+ (display-buffer BUFFER transient-display-buffer-action)
+
+The value of this option has the form (FUNCTION . ALIST),
+where FUNCTION is a function or a list of functions. Each such
+function should accept two arguments: a buffer to display and an
+alist of the same form as ALIST. See info node `(elisp)Choosing
+Window' for details.
+
+The default is:
+
+ (display-buffer-in-side-window
+ (side . bottom)
+ (dedicated . t)
+ (inhibit-same-window . t)
+ (window-parameters (no-other-window . t)))
+
+This displays the window at the bottom of the selected frame.
+Another useful FUNCTION is `display-buffer-below-selected', which
+is what `magit-popup' used by default. For more alternatives see
+info node `(elisp)Display Action Functions' and info node
+`(elisp)Buffer Display Action Alists'.
+
+Note that the buffer that was current before the transient buffer
+is shown should remain the current buffer. Many suffix commands
+act on the thing at point, if appropriate, and if the transient
+buffer became the current buffer, then that would change what is
+at point. To that effect `inhibit-same-window' ensures that the
+selected window is not used to show the transient buffer.
+
+It may be possible to display the window in another frame, but
+whether that works in practice depends on the window-manager.
+If the window manager selects the new window (Emacs frame),
+then that unfortunately changes which buffer is current.
+
+If you change the value of this option, then you might also
+want to change the value of `transient-mode-line-format'."
+ :package-version '(transient . "0.3.0")
+ :group 'transient
+ :type '(cons (choice function (repeat :tag "Functions" function))
+ alist))
+
+(defcustom transient-mode-line-format 'line
+ "The mode-line format for the transient popup buffer.
+
+If nil, then the buffer has no mode-line. If the buffer is not
+displayed right above the echo area, then this probably is not
+a good value.
+
+If `line' (the default), then the buffer also has no mode-line,
+but a thin line is drawn instead, using the background color of
+the face `transient-separator'. Termcap frames cannot display
+thin lines and therefore fallback to treating `line' like nil.
+
+Otherwise this can be any mode-line format.
+See `mode-line-format' for details."
+ :package-version '(transient . "0.2.0")
+ :group 'transient
+ :type '(choice (const :tag "hide mode-line" nil)
+ (const :tag "substitute thin line" line)
+ (const :tag "name of prefix command"
+ ("%e" mode-line-front-space
+ mode-line-buffer-identification))
+ (sexp :tag "custom mode-line format")))
+
+(defcustom transient-show-common-commands nil
+ "Whether to show common transient suffixes in the popup buffer.
+
+These commands are always shown after typing the prefix key
+\"C-x\" when a transient command is active. To toggle the value
+of this variable use \"C-x t\" when a transient is active."
+ :package-version '(transient . "0.1.0")
+ :group 'transient
+ :type 'boolean)
+
+(defcustom transient-read-with-initial-input nil
+ "Whether to use the last history element as initial minibuffer input."
+ :package-version '(transient . "0.2.0")
+ :group 'transient
+ :type 'boolean)
+
+(defcustom transient-highlight-mismatched-keys nil
+ "Whether to highlight keys that do not match their argument.
+
+This only affects infix arguments that represent command-line
+arguments. When this option is non-nil, then the key binding
+for infix argument are highlighted when only a long argument
+\(e.g. \"--verbose\") is specified but no shor-thand (e.g \"-v\").
+In the rare case that a short-hand is specified but does not
+match the key binding, then it is highlighted differently.
+
+The highlighting is done using using `transient-mismatched-key'
+and `transient-nonstandard-key'."
+ :package-version '(transient . "0.1.0")
+ :group 'transient
+ :type 'boolean)
+
+(defcustom transient-highlight-higher-levels nil
+ "Whether to highlight suffixes on higher levels.
+
+This is primarily intended for package authors.
+
+When non-nil then highlight the description of suffixes whose
+level is above 4, the default of `transient-default-level'.
+Assuming you have set that variable to 7, this highlights all
+suffixes that won't be available to users without them making
+the same customization."
+ :package-version '(transient . "0.3.6")
+ :group 'transient
+ :type 'boolean)
+
+(defcustom transient-substitute-key-function nil
+ "Function used to modify key bindings.
+
+This function is called with one argument, the prefix object,
+and must return a key binding description, either the existing
+key description it finds in the `key' slot, or a substitution.
+
+This is intended to let users replace certain prefix keys. It
+could also be used to make other substitutions, but that is
+discouraged.
+
+For example, \"=\" is hard to reach using my custom keyboard
+layout, so I substitute \"(\" for that, which is easy to reach
+using a layout optimized for Lisp.
+
+ (setq transient-substitute-key-function
+ (lambda (obj)
+ (let ((key (oref obj key)))
+ (if (string-match \"\\\\`\\\\(=\\\\)[a-zA-Z]\" key)
+ (replace-match \"(\" t t key 1)
+ key)))))"
+ :package-version '(transient . "0.1.0")
+ :group 'transient
+ :type '(choice (const :tag "Transform no keys (nil)" nil) function))
+
+(defcustom transient-semantic-coloring nil
+ "Whether to color prefixes and suffixes in Hydra-like fashion.
+This feature is experimental.
+
+If non-nil, then the key binding of each suffix is colorized to
+indicate whether it exits the transient state or not. The color
+of the prefix is indicated using the line that is drawn when the
+value of `transient-mode-line-format' is `line'.
+
+For more information about how Hydra uses colors see
+https://github.com/abo-abo/hydra#color and
+https://oremacs.com/2015/02/19/hydra-colors-reloaded."
+ :package-version '(transient . "0.3.0")
+ :group 'transient
+ :type 'boolean)
+
+(defcustom transient-detect-key-conflicts nil
+ "Whether to detect key binding conflicts.
+
+Conflicts are detected when a transient prefix command is invoked
+and results in an error, which prevents the transient from being
+used."
+ :package-version '(transient . "0.1.0")
+ :group 'transient
+ :type 'boolean)
+
+(defcustom transient-align-variable-pitch nil
+ "Whether to align columns pixel-wise in the popup buffer.
+
+If this is non-nil, then columns are aligned pixel-wise to
+support variable-pitch fonts. Keys are not aligned, so you
+should use a fixed-pitch font for the `transient-key' face.
+Other key faces inherit from that face unless a theme is
+used that breaks that relationship.
+
+This option is intended for users who use a variable-pitch
+font for the `default' face.
+
+Also see `transient-force-fixed-pitch'."
+ :package-version '(transient . "0.4.0")
+ :group 'transient
+ :type 'boolean)
+
+(defcustom transient-force-fixed-pitch nil
+ "Whether to force use of monospaced font in the popup buffer.
+
+Even if you use a proportional font for the `default' face,
+you might still want to use a monospaced font in transient's
+popup buffer. Setting this option to t causes `default' to
+be remapped to `fixed-pitch' in that buffer.
+
+Also see `transient-align-variable-pitch'."
+ :package-version '(transient . "0.2.0")
+ :group 'transient
+ :type 'boolean)
+
+(defcustom transient-force-single-column nil
+ "Whether to force use of a single column to display suffixes.
+
+This might be useful for users with low vision who use large
+text and might otherwise have to scroll in two dimensions."
+ :package-version '(transient . "0.3.6")
+ :group 'transient
+ :type 'boolean)
+
+(defcustom transient-hide-during-minibuffer-read nil
+ "Whether to hide the transient buffer while reading in the minibuffer."
+ :package-version '(transient . "0.4.0")
+ :group 'transient
+ :type 'boolean)
+
+(defconst transient--default-child-level 1)
+
+(defconst transient--default-prefix-level 4)
+
+(defcustom transient-default-level transient--default-prefix-level
+ "Control what suffix levels are made available by default.
+
+Each suffix command is placed on a level and each prefix command
+has a level, which controls which suffix commands are available.
+Integers between 1 and 7 (inclusive) are valid levels.
+
+The levels of individual transients and/or their individual
+suffixes can be changed individually, by invoking the prefix and
+then pressing \"C-x l\".
+
+The default level for both transients and their suffixes is 4.
+This option only controls the default for transients. The default
+suffix level is always 4. The author of a transient should place
+certain suffixes on a higher level if they expect that it won't be
+of use to most users, and they should place very important suffixes
+on a lower level so that they remain available even if the user
+lowers the transient level.
+
+\(Magit currently places nearly all suffixes on level 4 and lower
+levels are not used at all yet. So for the time being you should
+not set a lower level here and using a higher level might not
+give you as many additional suffixes as you hoped.)"
+ :package-version '(transient . "0.1.0")
+ :group 'transient
+ :type '(choice (const :tag "1 - fewest suffixes" 1)
+ (const 2)
+ (const 3)
+ (const :tag "4 - default" 4)
+ (const 5)
+ (const 6)
+ (const :tag "7 - most suffixes" 7)))
+
+(defcustom transient-levels-file
+ (locate-user-emacs-file "transient/levels.el")
+ "File used to save levels of transients and their suffixes."
+ :package-version '(transient . "0.1.0")
+ :group 'transient
+ :type 'file)
+
+(defcustom transient-values-file
+ (locate-user-emacs-file "transient/values.el")
+ "File used to save values of transients."
+ :package-version '(transient . "0.1.0")
+ :group 'transient
+ :type 'file)
+
+(defcustom transient-history-file
+ (locate-user-emacs-file "transient/history.el")
+ "File used to save history of transients and their infixes."
+ :package-version '(transient . "0.1.0")
+ :group 'transient
+ :type 'file)
+
+(defcustom transient-history-limit 10
+ "Number of history elements to keep when saving to file."
+ :package-version '(transient . "0.1.0")
+ :group 'transient
+ :type 'integer)
+
+(defcustom transient-save-history t
+ "Whether to save history of transient commands when exiting Emacs."
+ :package-version '(transient . "0.1.0")
+ :group 'transient
+ :type 'boolean)
+
+;;; Faces
+
+(defgroup transient-faces nil
+ "Faces used by Transient."
+ :group 'transient)
+
+(defface transient-heading '((t :inherit font-lock-keyword-face))
+ "Face used for headings."
+ :group 'transient-faces)
+
+(defface transient-key '((t :inherit font-lock-builtin-face))
+ "Face used for keys."
+ :group 'transient-faces)
+
+(defface transient-argument '((t :inherit font-lock-warning-face))
+ "Face used for enabled arguments."
+ :group 'transient-faces)
+
+(defface transient-value '((t :inherit font-lock-string-face))
+ "Face used for values."
+ :group 'transient-faces)
+
+(defface transient-inactive-argument '((t :inherit shadow))
+ "Face used for inactive arguments."
+ :group 'transient-faces)
+
+(defface transient-inactive-value '((t :inherit shadow))
+ "Face used for inactive values."
+ :group 'transient-faces)
+
+(defface transient-unreachable '((t :inherit shadow))
+ "Face used for suffixes unreachable from the current prefix sequence."
+ :group 'transient-faces)
+
+(defface transient-active-infix '((t :inherit secondary-selection))
+ "Face used for the infix for which the value is being read."
+ :group 'transient-faces)
+
+(defface transient-unreachable-key '((t :inherit (transient-key shadow)))
+ "Face used for keys unreachable from the current prefix sequence."
+ :group 'transient-faces)
+
+(defface transient-nonstandard-key '((t :underline t))
+ "Face optionally used to highlight keys conflicting with short-argument.
+Also see option `transient-highlight-mismatched-keys'."
+ :group 'transient-faces)
+
+(defface transient-mismatched-key '((t :underline t))
+ "Face optionally used to highlight keys without a short-argument.
+Also see option `transient-highlight-mismatched-keys'."
+ :group 'transient-faces)
+
+(defface transient-inapt-suffix '((t :inherit shadow :italic t))
+ "Face used for suffixes that are inapt at this time."
+ :group 'transient-faces)
+
+(defface transient-enabled-suffix
+ '((t :background "green" :foreground "black" :weight bold))
+ "Face used for enabled levels while editing suffix levels.
+See info node `(transient)Enabling and Disabling Suffixes'."
+ :group 'transient-faces)
+
+(defface transient-disabled-suffix
+ '((t :background "red" :foreground "black" :weight bold))
+ "Face used for disabled levels while editing suffix levels.
+See info node `(transient)Enabling and Disabling Suffixes'."
+ :group 'transient-faces)
+
+(defface transient-higher-level '((t :underline t))
+ "Face optionally used to highlight suffixes on higher levels.
+Also see option `transient-highlight-higher-levels'."
+ :group 'transient-faces)
+
+(defface transient-separator
+ `((((class color) (background light))
+ ,@(and (>= emacs-major-version 27) '(:extend t))
+ :background "grey80")
+ (((class color) (background dark))
+ ,@(and (>= emacs-major-version 27) '(:extend t))
+ :background "grey30"))
+ "Face used to draw line below transient popup window.
+This is only used if `transient-mode-line-format' is `line'.
+Only the background color is significant."
+ :group 'transient-faces)
+
+(defgroup transient-color-faces
+ '((transient-semantic-coloring custom-variable))
+ "Faces used by Transient for Hydra-like command coloring.
+These faces are only used if `transient-semantic-coloring'
+\(which see) is non-nil."
+ :group 'transient-faces)
+
+(defface transient-red
+ '((t :inherit transient-key :foreground "red"))
+ "Face used for red prefixes and suffixes."
+ :group 'transient-color-faces)
+
+(defface transient-blue
+ '((t :inherit transient-key :foreground "blue"))
+ "Face used for blue prefixes and suffixes."
+ :group 'transient-color-faces)
+
+(defface transient-amaranth
+ '((t :inherit transient-key :foreground "#E52B50"))
+ "Face used for amaranth prefixes."
+ :group 'transient-color-faces)
+
+(defface transient-pink
+ '((t :inherit transient-key :foreground "#FF6EB4"))
+ "Face used for pink prefixes."
+ :group 'transient-color-faces)
+
+(defface transient-teal
+ '((t :inherit transient-key :foreground "#367588"))
+ "Face used for teal prefixes."
+ :group 'transient-color-faces)
+
+(defface transient-purple
+ '((t :inherit transient-key :foreground "#a020f0"))
+ "Face used for purple prefixes.
+
+This is an addition to the colors supported by Hydra. It is
+used by suffixes that quit the current prefix but return to
+the previous prefix."
+ :group 'transient-color-faces)
+
+;;; Persistence
+
+(defun transient--read-file-contents (file)
+ (with-demoted-errors "Transient error: %S"
+ (and (file-exists-p file)
+ (with-temp-buffer
+ (insert-file-contents file)
+ (read (current-buffer))))))
+
+(defun transient--pp-to-file (list file)
+ (make-directory (file-name-directory file) t)
+ (setq list (cl-sort (copy-sequence list) #'string< :key #'car))
+ (with-temp-file file
+ (let ((print-level nil)
+ (print-length nil))
+ (pp list (current-buffer)))))
+
+(defvar transient-values
+ (transient--read-file-contents transient-values-file)
+ "Values of transient commands.
+The value of this variable persists between Emacs sessions
+and you usually should not change it manually.")
+
+(defun transient-save-values ()
+ (transient--pp-to-file transient-values transient-values-file))
+
+(defvar transient-levels
+ (transient--read-file-contents transient-levels-file)
+ "Levels of transient commands.
+The value of this variable persists between Emacs sessions
+and you usually should not change it manually.")
+
+(defun transient-save-levels ()
+ (transient--pp-to-file transient-levels transient-levels-file))
+
+(defvar transient-history
+ (transient--read-file-contents transient-history-file)
+ "History of transient commands and infix arguments.
+The value of this variable persists between Emacs sessions
+\(unless `transient-save-history' is nil) and you usually
+should not change it manually.")
+
+(defun transient-save-history ()
+ (setq transient-history
+ (cl-sort (mapcar (pcase-lambda (`(,key . ,val))
+ (cons key (seq-take (delete-dups val)
+ transient-history-limit)))
+ transient-history)
+ #'string< :key #'car))
+ (transient--pp-to-file transient-history transient-history-file))
+
+(defun transient-maybe-save-history ()
+ "Save the value of `transient-history'.
+If `transient-save-history' is nil, then do nothing."
+ (when transient-save-history
+ (transient-save-history)))
+
+(unless noninteractive
+ (add-hook 'kill-emacs-hook #'transient-maybe-save-history))
+
+;;; Classes
+;;;; Prefix
+
+(defclass transient-prefix ()
+ ((prototype :initarg :prototype)
+ (command :initarg :command)
+ (level :initarg :level)
+ (variable :initarg :variable :initform nil)
+ (init-value :initarg :init-value)
+ (value) (default-value :initarg :value)
+ (scope :initarg :scope :initform nil)
+ (history :initarg :history :initform nil)
+ (history-pos :initarg :history-pos :initform 0)
+ (history-key :initarg :history-key :initform nil)
+ (show-help :initarg :show-help :initform nil)
+ (info-manual :initarg :info-manual :initform nil)
+ (man-page :initarg :man-page :initform nil)
+ (transient-suffix :initarg :transient-suffix :initform nil)
+ (transient-non-suffix :initarg :transient-non-suffix :initform nil)
+ (incompatible :initarg :incompatible :initform nil)
+ (suffix-description :initarg :suffix-description)
+ (variable-pitch :initarg :variable-pitch :initform nil))
+ "Transient prefix command.
+
+Each transient prefix command consists of a command, which is
+stored in a symbol's function slot and an object, which is
+stored in the `transient--prefix' property of the same symbol.
+
+When a transient prefix command is invoked, then a clone of that
+object is stored in the global variable `transient--prefix' and
+the prototype is stored in the clone's `prototype' slot.")
+
+;;;; Suffix
+
+(defclass transient-child ()
+ ((level
+ :initarg :level
+ :initform (symbol-value 'transient--default-child-level)
+ :documentation "Enable if level of prefix is equal or greater.")
+ (if
+ :initarg :if
+ :initform nil
+ :documentation "Enable if predicate returns non-nil.")
+ (if-not
+ :initarg :if-not
+ :initform nil
+ :documentation "Enable if predicate returns nil.")
+ (if-non-nil
+ :initarg :if-non-nil
+ :initform nil
+ :documentation "Enable if variable's value is non-nil.")
+ (if-nil
+ :initarg :if-nil
+ :initform nil
+ :documentation "Enable if variable's value is nil.")
+ (if-mode
+ :initarg :if-mode
+ :initform nil
+ :documentation "Enable if major-mode matches value.")
+ (if-not-mode
+ :initarg :if-not-mode
+ :initform nil
+ :documentation "Enable if major-mode does not match value.")
+ (if-derived
+ :initarg :if-derived
+ :initform nil
+ :documentation "Enable if major-mode derives from value.")
+ (if-not-derived
+ :initarg :if-not-derived
+ :initform nil
+ :documentation "Enable if major-mode does not derive from value."))
+ "Abstract superclass for group and suffix classes.
+
+It is undefined what happens if more than one `if*' predicate
+slot is non-nil."
+ :abstract t)
+
+(defclass transient-suffix (transient-child)
+ ((key :initarg :key)
+ (command :initarg :command)
+ (transient :initarg :transient)
+ (format :initarg :format :initform " %k %d")
+ (description :initarg :description :initform nil)
+ (show-help :initarg :show-help :initform nil)
+ (inapt :initform nil)
+ (inapt-if
+ :initarg :inapt-if
+ :initform nil
+ :documentation "Inapt if predicate returns non-nil.")
+ (inapt-if-not
+ :initarg :inapt-if-not
+ :initform nil
+ :documentation "Inapt if predicate returns nil.")
+ (inapt-if-non-nil
+ :initarg :inapt-if-non-nil
+ :initform nil
+ :documentation "Inapt if variable's value is non-nil.")
+ (inapt-if-nil
+ :initarg :inapt-if-nil
+ :initform nil
+ :documentation "Inapt if variable's value is nil.")
+ (inapt-if-mode
+ :initarg :inapt-if-mode
+ :initform nil
+ :documentation "Inapt if major-mode matches value.")
+ (inapt-if-not-mode
+ :initarg :inapt-if-not-mode
+ :initform nil
+ :documentation "Inapt if major-mode does not match value.")
+ (inapt-if-derived
+ :initarg :inapt-if-derived
+ :initform nil
+ :documentation "Inapt if major-mode derives from value.")
+ (inapt-if-not-derived
+ :initarg :inapt-if-not-derived
+ :initform nil
+ :documentation "Inapt if major-mode does not derive from value."))
+ "Superclass for suffix command.")
+
+(defclass transient-infix (transient-suffix)
+ ((transient :initform t)
+ (argument :initarg :argument)
+ (shortarg :initarg :shortarg)
+ (value :initform nil)
+ (init-value :initarg :init-value)
+ (unsavable :initarg :unsavable :initform nil)
+ (multi-value :initarg :multi-value :initform nil)
+ (always-read :initarg :always-read :initform nil)
+ (allow-empty :initarg :allow-empty :initform nil)
+ (history-key :initarg :history-key :initform nil)
+ (reader :initarg :reader :initform nil)
+ (prompt :initarg :prompt :initform nil)
+ (choices :initarg :choices :initform nil)
+ (format :initform " %k %d (%v)"))
+ "Transient infix command."
+ :abstract t)
+
+(defclass transient-argument (transient-infix) ()
+ "Abstract superclass for infix arguments."
+ :abstract t)
+
+(defclass transient-switch (transient-argument) ()
+ "Class used for command-line argument that can be turned on and off.")
+
+(defclass transient-option (transient-argument) ()
+ "Class used for command-line argument that can take a value.")
+
+(defclass transient-variable (transient-infix)
+ ((variable :initarg :variable)
+ (format :initform " %k %d %v"))
+ "Abstract superclass for infix commands that set a variable."
+ :abstract t)
+
+(defclass transient-switches (transient-argument)
+ ((argument-format :initarg :argument-format)
+ (argument-regexp :initarg :argument-regexp))
+ "Class used for sets of mutually exclusive command-line switches.")
+
+(defclass transient-files (transient-option) ()
+ ((key :initform "--")
+ (argument :initform "--")
+ (multi-value :initform rest)
+ (reader :initform transient-read-files))
+ "Class used for the \"--\" argument or similar.
+All remaining arguments are treated as files.
+They become the value of this argument.")
+
+;;;; Group
+
+(defclass transient-group (transient-child)
+ ((suffixes :initarg :suffixes :initform nil)
+ (hide :initarg :hide :initform nil)
+ (description :initarg :description :initform nil)
+ (setup-children :initarg :setup-children)
+ (pad-keys :initarg :pad-keys))
+ "Abstract superclass of all group classes."
+ :abstract t)
+
+(defclass transient-column (transient-group) ()
+ "Group class that displays each element on a separate line.")
+
+(defclass transient-row (transient-group) ()
+ "Group class that displays all elements on a single line.")
+
+(defclass transient-columns (transient-group) ()
+ "Group class that displays elements organized in columns.
+Direct elements have to be groups whose elements have to be
+commands or string. Each subgroup represents a column. This
+class takes care of inserting the subgroups' elements.")
+
+(defclass transient-subgroups (transient-group) ()
+ "Group class that wraps other groups.
+
+Direct elements have to be groups whose elements have to be
+commands or strings. This group inserts an empty line between
+subgroups. The subgroups are responsible for displaying their
+elements themselves.")
+
+;;; Define
+
+(defmacro transient-define-prefix (name arglist &rest args)
+ "Define NAME as a transient prefix command.
+
+ARGLIST are the arguments that command takes.
+DOCSTRING is the documentation string and is optional.
+
+These arguments can optionally be followed by key-value pairs.
+Each key has to be a keyword symbol, either `:class' or a keyword
+argument supported by the constructor of that class. The
+`transient-prefix' class is used if the class is not specified
+explicitly.
+
+GROUPs add key bindings for infix and suffix commands and specify
+how these bindings are presented in the popup buffer. At least
+one GROUP has to be specified. See info node `(transient)Binding
+Suffix and Infix Commands'.
+
+The BODY is optional. If it is omitted, then ARGLIST is also
+ignored and the function definition becomes:
+
+ (lambda ()
+ (interactive)
+ (transient-setup \\='NAME))
+
+If BODY is specified, then it must begin with an `interactive'
+form that matches ARGLIST, and it must call `transient-setup'.
+It may however call that function only when some condition is
+satisfied; that is one of the reason why you might want to use
+an explicit BODY.
+
+All transients have a (possibly nil) value, which is exported
+when suffix commands are called, so that they can consume that
+value. For some transients it might be necessary to have a sort
+of secondary value, called a scope. Such a scope would usually
+be set in the commands `interactive' form and has to be passed
+to the setup function:
+
+ (transient-setup \\='NAME nil nil :scope SCOPE)
+
+\(fn NAME ARGLIST [DOCSTRING] [KEYWORD VALUE]... GROUP... [BODY...])"
+ (declare (debug ( &define name lambda-list
+ [&optional lambda-doc]
+ [&rest keywordp sexp]
+ [&rest vectorp]
+ [&optional ("interactive" interactive) def-body]))
+ (indent defun)
+ (doc-string 3))
+ (pcase-let ((`(,class ,slots ,suffixes ,docstr ,body)
+ (transient--expand-define-args args)))
+ `(progn
+ (defalias ',name
+ ,(if body
+ `(lambda ,arglist ,@body)
+ `(lambda ()
+ (interactive)
+ (transient-setup ',name))))
+ (put ',name 'interactive-only t)
+ (put ',name 'function-documentation ,docstr)
+ (put ',name 'transient--prefix
+ (,(or class 'transient-prefix) :command ',name ,@slots))
+ (put ',name 'transient--layout
+ ',(cl-mapcan (lambda (s) (transient--parse-child name s))
+ suffixes)))))
+
+(defmacro transient-define-suffix (name arglist &rest args)
+ "Define NAME as a transient suffix command.
+
+ARGLIST are the arguments that the command takes.
+DOCSTRING is the documentation string and is optional.
+
+These arguments can optionally be followed by key-value pairs.
+Each key has to be a keyword symbol, either `:class' or a
+keyword argument supported by the constructor of that class.
+The `transient-suffix' class is used if the class is not
+specified explicitly.
+
+The BODY must begin with an `interactive' form that matches
+ARGLIST. The infix arguments are usually accessed by using
+`transient-args' inside `interactive'.
+
+\(fn NAME ARGLIST [DOCSTRING] [KEYWORD VALUE]... BODY...)"
+ (declare (debug ( &define name lambda-list
+ [&optional lambda-doc]
+ [&rest keywordp sexp]
+ ("interactive" interactive)
+ def-body))
+ (indent defun)
+ (doc-string 3))
+ (pcase-let ((`(,class ,slots ,_ ,docstr ,body)
+ (transient--expand-define-args args)))
+ `(progn
+ (defalias ',name (lambda ,arglist ,@body))
+ (put ',name 'interactive-only t)
+ (put ',name 'function-documentation ,docstr)
+ (put ',name 'transient--suffix
+ (,(or class 'transient-suffix) :command ',name ,@slots)))))
+
+(defmacro transient-define-infix (name _arglist &rest args)
+ "Define NAME as a transient infix command.
+
+ARGLIST is always ignored and reserved for future use.
+DOCSTRING is the documentation string and is optional.
+
+The key-value pairs are mandatory. All transient infix commands
+are equal to each other (but not eq), so it is meaningless to
+define an infix command without also setting at least `:class'
+and one other keyword (which it is depends on the used class,
+usually `:argument' or `:variable').
+
+Each key has to be a keyword symbol, either `:class' or a keyword
+argument supported by the constructor of that class. The
+`transient-switch' class is used if the class is not specified
+explicitly.
+
+The function definitions is always:
+
+ (lambda ()
+ (interactive)
+ (let ((obj (transient-suffix-object)))
+ (transient-infix-set obj (transient-infix-read obj)))
+ (transient--show))
+
+`transient-infix-read' and `transient-infix-set' are generic
+functions. Different infix commands behave differently because
+the concrete methods are different for different infix command
+classes. In rare case the above command function might not be
+suitable, even if you define your own infix command class. In
+that case you have to use `transient-define-suffix' to define
+the infix command and use t as the value of the `:transient'
+keyword.
+
+\(fn NAME ARGLIST [DOCSTRING] [KEYWORD VALUE]...)"
+ (declare (debug ( &define name lambda-list
+ [&optional lambda-doc]
+ [&rest keywordp sexp]))
+ (indent defun)
+ (doc-string 3))
+ (pcase-let ((`(,class ,slots ,_ ,docstr ,_)
+ (transient--expand-define-args args)))
+ `(progn
+ (defalias ',name ,(transient--default-infix-command))
+ (put ',name 'interactive-only t)
+ (put ',name 'command-modes (list 'not-a-mode))
+ (put ',name 'function-documentation ,docstr)
+ (put ',name 'transient--suffix
+ (,(or class 'transient-switch) :command ',name ,@slots)))))
+
+(defalias 'transient-define-argument #'transient-define-infix
+ "Define NAME as a transient infix command.
+
+Only use this alias to define an infix command that actually
+sets an infix argument. To define a infix command that, for
+example, sets a variable use `transient-define-infix' instead.
+
+\(fn NAME ARGLIST [DOCSTRING] [KEYWORD VALUE]...)")
+
+(defun transient--expand-define-args (args)
+ (let (class keys suffixes docstr)
+ (when (stringp (car args))
+ (setq docstr (pop args)))
+ (while (keywordp (car args))
+ (let ((k (pop args))
+ (v (pop args)))
+ (if (eq k :class)
+ (setq class v)
+ (push k keys)
+ (push v keys))))
+ (while (let ((arg (car args)))
+ (if (vectorp arg)
+ (setcar args (eval (cdr (backquote-process arg))))
+ (and arg (symbolp arg))))
+ (push (pop args) suffixes))
+ (list (if (eq (car-safe class) 'quote)
+ (cadr class)
+ class)
+ (nreverse keys)
+ (nreverse suffixes)
+ docstr
+ args)))
+
+(defun transient--parse-child (prefix spec)
+ (cl-etypecase spec
+ (symbol (let ((value (symbol-value spec)))
+ (if (and (listp value)
+ (or (listp (car value))
+ (vectorp (car value))))
+ (cl-mapcan (lambda (s) (transient--parse-child prefix s)) value)
+ (transient--parse-child prefix value))))
+ (vector (and-let* ((c (transient--parse-group prefix spec))) (list c)))
+ (list (and-let* ((c (transient--parse-suffix prefix spec))) (list c)))
+ (string (list spec))))
+
+(defun transient--parse-group (prefix spec)
+ (setq spec (append spec nil))
+ (cl-symbol-macrolet
+ ((car (car spec))
+ (pop (pop spec)))
+ (let (level class args)
+ (when (integerp car)
+ (setq level pop))
+ (when (stringp car)
+ (setq args (plist-put args :description pop)))
+ (while (keywordp car)
+ (let ((k pop))
+ (if (eq k :class)
+ (setq class pop)
+ (setq args (plist-put args k pop)))))
+ (vector (or level transient--default-child-level)
+ (or class
+ (if (vectorp car)
+ 'transient-columns
+ 'transient-column))
+ args
+ (cl-mapcan (lambda (s) (transient--parse-child prefix s)) spec)))))
+
+(defun transient--parse-suffix (prefix spec)
+ (let (level class args)
+ (cl-symbol-macrolet
+ ((car (car spec))
+ (pop (pop spec)))
+ (when (integerp car)
+ (setq level pop))
+ (when (or (stringp car)
+ (vectorp car))
+ (setq args (plist-put args :key pop)))
+ (when (or (stringp car)
+ (eq (car-safe car) 'lambda)
+ (and (symbolp car)
+ (not (commandp car))
+ (commandp (cadr spec))))
+ (setq args (plist-put args :description pop)))
+ (cond
+ ((keywordp car)
+ (error "Need command, got %S" car))
+ ((symbolp car)
+ (setq args (plist-put args :command pop)))
+ ((and (commandp car)
+ (not (stringp car)))
+ (let ((cmd pop)
+ (sym (intern (format "transient:%s:%s"
+ prefix
+ (or (plist-get args :description)
+ (plist-get args :key))))))
+ (defalias sym cmd)
+ (setq args (plist-put args :command sym))))
+ ((or (stringp car)
+ (and car (listp car)))
+ (let ((arg pop))
+ (cl-typecase arg
+ (list
+ (setq args (plist-put args :shortarg (car arg)))
+ (setq args (plist-put args :argument (cadr arg)))
+ (setq arg (cadr arg)))
+ (string
+ (when-let ((shortarg (transient--derive-shortarg arg)))
+ (setq args (plist-put args :shortarg shortarg)))
+ (setq args (plist-put args :argument arg))))
+ (setq args (plist-put args :command
+ (intern (format "transient:%s:%s"
+ prefix arg))))
+ (cond ((and car (not (keywordp car)))
+ (setq class 'transient-option)
+ (setq args (plist-put args :reader pop)))
+ ((not (string-suffix-p "=" arg))
+ (setq class 'transient-switch))
+ (t
+ (setq class 'transient-option)))))
+ (t
+ (error "Needed command or argument, got %S" car)))
+ (while (keywordp car)
+ (let ((k pop))
+ (cl-case k
+ (:class (setq class pop))
+ (:level (setq level pop))
+ (t (setq args (plist-put args k pop)))))))
+ (unless (plist-get args :key)
+ (when-let ((shortarg (plist-get args :shortarg)))
+ (setq args (plist-put args :key shortarg))))
+ (list (or level transient--default-child-level)
+ (or class 'transient-suffix)
+ args)))
+
+(defun transient--default-infix-command ()
+ (cons 'lambda
+ '(()
+ (interactive)
+ (let ((obj (transient-suffix-object)))
+ (transient-infix-set obj (transient-infix-read obj)))
+ (transient--show))))
+
+(defun transient--ensure-infix-command (obj)
+ (let ((cmd (oref obj command)))
+ (unless (or (commandp cmd)
+ (get cmd 'transient--infix-command))
+ (if (or (cl-typep obj 'transient-switch)
+ (cl-typep obj 'transient-option))
+ (put cmd 'transient--infix-command
+ (transient--default-infix-command))
+ ;; This is not an anonymous infix argument.
+ (when (transient--use-suffix-p obj)
+ (error "Suffix %s is not defined or autoloaded as a command" cmd))))))
+
+(defun transient--derive-shortarg (arg)
+ (save-match-data
+ (and (string-match "\\`\\(-[a-zA-Z]\\)\\(\\'\\|=\\)" arg)
+ (match-string 1 arg))))
+
+;;; Edit
+
+(defun transient--insert-suffix (prefix loc suffix action)
+ (let* ((suf (cl-etypecase suffix
+ (vector (transient--parse-group prefix suffix))
+ (list (transient--parse-suffix prefix suffix))
+ (string suffix)))
+ (mem (transient--layout-member loc prefix))
+ (elt (car mem)))
+ (cond
+ ((not mem)
+ (message "Cannot insert %S into %s; %s not found"
+ suffix prefix loc))
+ ((or (and (vectorp suffix) (not (vectorp elt)))
+ (and (listp suffix) (vectorp elt))
+ (and (stringp suffix) (vectorp elt)))
+ (message "Cannot place %S into %s at %s; %s"
+ suffix prefix loc
+ "suffixes and groups cannot be siblings"))
+ (t
+ (when (and (listp suffix)
+ (listp elt))
+ ;; Both suffixes are key bindings; not heading strings.
+ (let ((key (transient--spec-key suf)))
+ (if (equal (transient--kbd key)
+ (transient--kbd (transient--spec-key elt)))
+ ;; We must keep `mem' until after we have inserted
+ ;; behind it, which `transient-remove-suffix' does
+ ;; not allow us to do.
+ (let ((spred (transient--suffix-predicate suf))
+ (epred (transient--suffix-predicate elt)))
+ ;; If both suffixes have a predicate and they
+ ;; are not identical, then there is a high
+ ;; probability that we want to keep both.
+ (when (or (not spred)
+ (not epred)
+ (equal spred epred))
+ (setq action 'replace)))
+ (transient-remove-suffix prefix key))))
+ (cl-ecase action
+ (insert (setcdr mem (cons elt (cdr mem)))
+ (setcar mem suf))
+ (append (setcdr mem (cons suf (cdr mem))))
+ (replace (setcar mem suf)))))))
+
+;;;###autoload
+(defun transient-insert-suffix (prefix loc suffix)
+ "Insert a SUFFIX into PREFIX before LOC.
+PREFIX is a prefix command, a symbol.
+SUFFIX is a suffix command or a group specification (of
+ the same forms as expected by `transient-define-prefix').
+LOC is a command, a key vector, a key description (a string
+ as returned by `key-description'), or a coordination list
+ (whose last element may also be a command or key).
+See info node `(transient)Modifying Existing Transients'."
+ (declare (indent defun))
+ (transient--insert-suffix prefix loc suffix 'insert))
+
+;;;###autoload
+(defun transient-append-suffix (prefix loc suffix)
+ "Insert a SUFFIX into PREFIX after LOC.
+PREFIX is a prefix command, a symbol.
+SUFFIX is a suffix command or a group specification (of
+ the same forms as expected by `transient-define-prefix').
+LOC is a command, a key vector, a key description (a string
+ as returned by `key-description'), or a coordination list
+ (whose last element may also be a command or key).
+See info node `(transient)Modifying Existing Transients'."
+ (declare (indent defun))
+ (transient--insert-suffix prefix loc suffix 'append))
+
+;;;###autoload
+(defun transient-replace-suffix (prefix loc suffix)
+ "Replace the suffix at LOC in PREFIX with SUFFIX.
+PREFIX is a prefix command, a symbol.
+SUFFIX is a suffix command or a group specification (of
+ the same forms as expected by `transient-define-prefix').
+LOC is a command, a key vector, a key description (a string
+ as returned by `key-description'), or a coordination list
+ (whose last element may also be a command or key).
+See info node `(transient)Modifying Existing Transients'."
+ (declare (indent defun))
+ (transient--insert-suffix prefix loc suffix 'replace))
+
+;;;###autoload
+(defun transient-remove-suffix (prefix loc)
+ "Remove the suffix or group at LOC in PREFIX.
+PREFIX is a prefix command, a symbol.
+LOC is a command, a key vector, a key description (a string
+ as returned by `key-description'), or a coordination list
+ (whose last element may also be a command or key).
+See info node `(transient)Modifying Existing Transients'."
+ (declare (indent defun))
+ (transient--layout-member loc prefix 'remove))
+
+(defun transient-get-suffix (prefix loc)
+ "Return the suffix or group at LOC in PREFIX.
+PREFIX is a prefix command, a symbol.
+LOC is a command, a key vector, a key description (a string
+ as returned by `key-description'), or a coordination list
+ (whose last element may also be a command or key).
+See info node `(transient)Modifying Existing Transients'."
+ (if-let ((mem (transient--layout-member loc prefix)))
+ (car mem)
+ (error "%s not found in %s" loc prefix)))
+
+(defun transient-suffix-put (prefix loc prop value)
+ "Edit the suffix at LOC in PREFIX, setting PROP to VALUE.
+PREFIX is a prefix command, a symbol.
+SUFFIX is a suffix command or a group specification (of
+ the same forms as expected by `transient-define-prefix').
+LOC is a command, a key vector, a key description (a string
+ as returned by `key-description'), or a coordination list
+ (whose last element may also be a command or key).
+See info node `(transient)Modifying Existing Transients'."
+ (let ((suf (transient-get-suffix prefix loc)))
+ (setf (elt suf 2)
+ (plist-put (elt suf 2) prop value))))
+
+(defun transient--layout-member (loc prefix &optional remove)
+ (let ((val (or (get prefix 'transient--layout)
+ (error "%s is not a transient command" prefix))))
+ (when (listp loc)
+ (while (integerp (car loc))
+ (let* ((children (if (vectorp val) (aref val 3) val))
+ (mem (transient--nthcdr (pop loc) children)))
+ (if (and remove (not loc))
+ (let ((rest (delq (car mem) children)))
+ (if (vectorp val)
+ (aset val 3 rest)
+ (put prefix 'transient--layout rest))
+ (setq val nil))
+ (setq val (if loc (car mem) mem)))))
+ (setq loc (car loc)))
+ (if loc
+ (transient--layout-member-1 (transient--kbd loc) val remove)
+ val)))
+
+(defun transient--layout-member-1 (loc layout remove)
+ (cond ((listp layout)
+ (seq-some (lambda (elt) (transient--layout-member-1 loc elt remove))
+ layout))
+ ((vectorp (car (aref layout 3)))
+ (seq-some (lambda (elt) (transient--layout-member-1 loc elt remove))
+ (aref layout 3)))
+ (remove
+ (aset layout 3
+ (delq (car (transient--group-member loc layout))
+ (aref layout 3)))
+ nil)
+ (t (transient--group-member loc layout))))
+
+(defun transient--group-member (loc group)
+ (cl-member-if (lambda (suffix)
+ (and (listp suffix)
+ (let* ((def (nth 2 suffix))
+ (cmd (plist-get def :command)))
+ (if (symbolp loc)
+ (eq cmd loc)
+ (equal (transient--kbd
+ (or (plist-get def :key)
+ (transient--command-key cmd)))
+ loc)))))
+ (aref group 3)))
+
+(defun transient--kbd (keys)
+ (when (vectorp keys)
+ (setq keys (key-description keys)))
+ (when (stringp keys)
+ (setq keys (kbd keys)))
+ keys)
+
+(defun transient--spec-key (spec)
+ (let ((plist (nth 2 spec)))
+ (or (plist-get plist :key)
+ (transient--command-key
+ (plist-get plist :command)))))
+
+(defun transient--command-key (cmd)
+ (and-let* ((obj (get cmd 'transient--suffix)))
+ (cond ((slot-boundp obj 'key)
+ (oref obj key))
+ ((slot-exists-p obj 'shortarg)
+ (if (slot-boundp obj 'shortarg)
+ (oref obj shortarg)
+ (transient--derive-shortarg (oref obj argument)))))))
+
+(defun transient--nthcdr (n list)
+ (nthcdr (if (< n 0) (- (length list) (abs n)) n) list))
+
+;;; Variables
+
+(defvar transient-current-prefix nil
+ "The transient from which this suffix command was invoked.
+This is an object representing that transient, use
+`transient-current-command' to get the respective command.")
+
+(defvar transient-current-command nil
+ "The transient from which this suffix command was invoked.
+This is a symbol representing that transient, use
+`current-transient-object' to get the respective object.")
+
+(defvar transient-current-suffixes nil
+ "The suffixes of the transient from which this suffix command was invoked.
+This is a list of objects. Usually it is sufficient to instead
+use the function `transient-args', which returns a list of
+values. In complex cases it might be necessary to use this
+variable instead.")
+
+(defvar transient-exit-hook nil
+ "Hook run after exiting a transient.")
+
+(defvar transient--prefix nil)
+(defvar transient--layout nil)
+(defvar transient--suffixes nil)
+
+(defconst transient--stay t "Do not exit the transient.")
+(defconst transient--exit nil "Do exit the transient.")
+
+(defvar transient--exitp nil "Whether to exit the transient.")
+(defvar transient--showp nil "Whether the transient is show in a popup buffer.")
+(defvar transient--helpp nil "Whether help-mode is active.")
+(defvar transient--editp nil "Whether edit-mode is active.")
+
+(defvar transient--active-infix nil "The active infix awaiting user input.")
+
+(defvar transient--timer nil)
+
+(defvar transient--stack nil)
+
+(defvar transient--minibuffer-depth 0)
+
+(defvar transient--buffer-name " *transient*"
+ "Name of the transient buffer.")
+
+(defvar transient--window nil
+ "The window used to display the transient popup.")
+
+(defvar transient--original-window nil
+ "The window that was selected before the transient was invoked.
+Usually it remains selected while the transient is active.")
+
+(defvar transient--original-buffer nil
+ "The buffer that was current before the transient was invoked.
+Usually it remains current while the transient is active.")
+
+(defvar transient--debug nil "Whether put debug information into *Messages*.")
+
+(defvar transient--history nil)
+
+(defvar transient--abort-commands
+ '(abort-minibuffers ; (minibuffer-quit-recursive-edit)
+ abort-recursive-edit ; (throw 'exit t)
+ exit-recursive-edit ; (throw 'exit nil)
+ keyboard-escape-quit ; dwim
+ keyboard-quit ; (signal 'quit nil)
+ minibuffer-keyboard-quit ; (abort-minibuffers)
+ minibuffer-quit-recursive-edit ; (throw 'exit (lambda ()
+ ; (signal 'minibuffer-quit nil)))
+ top-level)) ; (throw 'top-level nil)
+
+(defvar transient--scroll-commands
+ '(transient-scroll-up
+ transient-scroll-down
+ mwheel-scroll
+ scroll-bar-toolkit-scroll))
+
+;;; Identities
+
+(defun transient-suffix-object (&optional command)
+ "Return the object associated with the current suffix command.
+
+Each suffix commands is associated with an object, which holds
+additional information about the suffix, such as its value (in
+the case of an infix command, which is a kind of suffix command).
+
+This function is intended to be called by infix commands, whose
+command definition usually (at least when defined using
+`transient-define-infix') is this:
+
+ (lambda ()
+ (interactive)
+ (let ((obj (transient-suffix-object)))
+ (transient-infix-set obj (transient-infix-read obj)))
+ (transient--show))
+
+\(User input is read outside of `interactive' to prevent the
+command from being added to `command-history'. See #23.)
+
+Such commands need to be able to access their associated object
+to guide how `transient-infix-read' reads the new value and to
+store the read value. Other suffix commands (including non-infix
+commands) may also need the object to guide their behavior.
+
+This function attempts to return the object associated with the
+current suffix command even if the suffix command was not invoked
+from a transient. (For some suffix command that is a valid thing
+to do, for others it is not.) In that case nil may be returned
+if the command was not defined using one of the macros intended
+to define such commands.
+
+The optional argument COMMAND is intended for internal use. If
+you are contemplating using it in your own code, then you should
+probably use this instead:
+
+ (get COMMAND 'transient--suffix)"
+ (when command
+ (cl-check-type command command))
+ (if (or transient--prefix
+ transient-current-prefix)
+ (cl-find-if (lambda (obj)
+ (eq (transient--suffix-command obj)
+ (or command this-command)))
+ (or transient--suffixes
+ transient-current-suffixes))
+ (when-let* ((obj (get (or command this-command) 'transient--suffix))
+ (obj (clone obj)))
+ ;; Cannot use and-let* because of debbugs#31840.
+ (transient-init-scope obj)
+ (transient-init-value obj)
+ obj)))
+
+(defun transient--suffix-command (object)
+ "Return the command represented by OBJECT.
+
+If the value of OBJECT's `command' slot is a command, then return
+that. Otherwise it is a symbol whose `transient--infix-command'
+property holds an anonymous command, which is returned instead."
+ (cl-check-type object transient-suffix)
+ (let ((sym (oref object command)))
+ (if (commandp sym)
+ sym
+ (get sym 'transient--infix-command))))
+
+(defun transient--suffix-symbol (arg)
+ "Return a symbol representing ARG.
+
+ARG must be a command and/or a symbol. If it is a symbol,
+then just return it. Otherwise return the symbol whose
+`transient--infix-command' property's value is ARG."
+ (or (cl-typep arg 'command)
+ (cl-typep arg 'symbol)
+ (signal 'wrong-type-argument `((command symbol) ,arg)))
+ (if (symbolp arg)
+ arg
+ (let* ((obj (transient-suffix-object))
+ (sym (oref obj command)))
+ (if (eq (get sym 'transient--infix-command) arg)
+ sym
+ (catch 'found
+ (mapatoms (lambda (sym)
+ (when (eq (get sym 'transient--infix-command) arg)
+ (throw 'found sym)))))))))
+
+;;; Keymaps
+
+(defvar transient-base-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map (kbd "ESC ESC ESC") #'transient-quit-all)
+ (define-key map (kbd "C-g") #'transient-quit-one)
+ (define-key map (kbd "C-q") #'transient-quit-all)
+ (define-key map (kbd "C-z") #'transient-suspend)
+ (define-key map (kbd "C-v") #'transient-scroll-up)
+ (define-key map (kbd "C-M-v") #'transient-scroll-down)
+ (define-key map [next] #'transient-scroll-up)
+ (define-key map [prior] #'transient-scroll-down)
+ map)
+ "Parent of other keymaps used by Transient.
+
+This is the parent keymap of all the keymaps that are used in
+all transients: `transient-map' (which in turn is the parent
+of the transient-specific keymaps), `transient-edit-map' and
+`transient-sticky-map'.
+
+If you change a binding here, then you might also have to edit
+`transient-sticky-map' and `transient-common-commands'. While
+the latter isn't a proper transient prefix command, it can be
+edited using the same functions as used for transients.
+
+If you add a new command here, then you must also add a binding
+to `transient-predicate-map'.")
+
+(defvar transient-map
+ (let ((map (make-sparse-keymap)))
+ (set-keymap-parent map transient-base-map)
+ (define-key map (kbd "C-u") #'universal-argument)
+ (define-key map (kbd "C--") #'negative-argument)
+ (define-key map (kbd "C-t") #'transient-show)
+ (define-key map (kbd "?") #'transient-help)
+ (define-key map (kbd "C-h") #'transient-help)
+ ;; Also bound to "C-x p" and "C-x n" in transient-common-commands.
+ (define-key map (kbd "C-M-p") #'transient-history-prev)
+ (define-key map (kbd "C-M-n") #'transient-history-next)
+ map)
+ "Top-level keymap used by all transients.
+
+If you add a new command here, then you must also add a binding
+to `transient-predicate-map'. Also see `transient-base-map'.")
+
+(defvar transient-edit-map
+ (let ((map (make-sparse-keymap)))
+ (set-keymap-parent map transient-base-map)
+ (define-key map (kbd "?") #'transient-help)
+ (define-key map (kbd "C-h") #'transient-help)
+ (define-key map (kbd "C-x l") #'transient-set-level)
+ map)
+ "Keymap that is active while a transient in is in \"edit mode\".")
+
+(defvar transient-sticky-map
+ (let ((map (make-sparse-keymap)))
+ (set-keymap-parent map transient-base-map)
+ (define-key map (kbd "C-g") #'transient-quit-seq)
+ map)
+ "Keymap that is active while an incomplete key sequence is active.")
+
+(defvar transient--common-command-prefixes '(?\C-x))
+
+(put 'transient-common-commands
+ 'transient--layout
+ (cl-mapcan
+ (lambda (s) (transient--parse-child 'transient-common-commands s))
+ `([:hide ,(lambda ()
+ (and (not (memq (car (bound-and-true-p
+ transient--redisplay-key))
+ transient--common-command-prefixes))
+ (not transient-show-common-commands)))
+ ["Value commands"
+ ("C-x s " "Set" transient-set)
+ ("C-x C-s" "Save" transient-save)
+ ("C-x C-k" "Reset" transient-reset)
+ ("C-x p " "Previous value" transient-history-prev)
+ ("C-x n " "Next value" transient-history-next)]
+ ["Sticky commands"
+ ;; Like `transient-sticky-map' except that
+ ;; "C-g" has to be bound to a different command.
+ ("C-g" "Quit prefix or transient" transient-quit-one)
+ ("C-q" "Quit transient stack" transient-quit-all)
+ ("C-z" "Suspend transient stack" transient-suspend)]
+ ["Customize"
+ ("C-x t" transient-toggle-common
+ :description ,(lambda ()
+ (if transient-show-common-commands
+ "Hide common commands"
+ "Show common permanently")))
+ ("C-x l" "Show/hide suffixes" transient-set-level)]])))
+
+(defvar transient-popup-navigation-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map (kbd "<down-mouse-1>") #'transient-noop)
+ (define-key map (kbd "<up>") #'transient-backward-button)
+ (define-key map (kbd "<down>") #'transient-forward-button)
+ (define-key map (kbd "C-r") #'transient-isearch-backward)
+ (define-key map (kbd "C-s") #'transient-isearch-forward)
+ (define-key map (kbd "M-RET") #'transient-push-button)
+ map)
+ "One of the keymaps used when popup navigation is enabled.
+See `transient-enable-popup-navigation'.")
+
+(defvar transient-button-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map (kbd "<mouse-1>") #'transient-push-button)
+ (define-key map (kbd "<mouse-2>") #'transient-push-button)
+ map)
+ "One of the keymaps used when popup navigation is enabled.
+See `transient-enable-popup-navigation'.")
+
+(defvar transient-predicate-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map [transient-suspend] #'transient--do-suspend)
+ (define-key map [transient-help] #'transient--do-stay)
+ (define-key map [transient-set-level] #'transient--do-stay)
+ (define-key map [transient-history-prev] #'transient--do-stay)
+ (define-key map [transient-history-next] #'transient--do-stay)
+ (define-key map [universal-argument] #'transient--do-stay)
+ (define-key map [negative-argument] #'transient--do-minus)
+ (define-key map [digit-argument] #'transient--do-stay)
+ (define-key map [transient-quit-all] #'transient--do-quit-all)
+ (define-key map [transient-quit-one] #'transient--do-quit-one)
+ (define-key map [transient-quit-seq] #'transient--do-stay)
+ (define-key map [transient-show] #'transient--do-stay)
+ (define-key map [transient-update] #'transient--do-stay)
+ (define-key map [transient-toggle-common] #'transient--do-stay)
+ (define-key map [transient-set] #'transient--do-call)
+ (define-key map [transient-save] #'transient--do-call)
+ (define-key map [transient-reset] #'transient--do-call)
+ (define-key map [describe-key-briefly] #'transient--do-stay)
+ (define-key map [describe-key] #'transient--do-stay)
+ (define-key map [transient-scroll-up] #'transient--do-stay)
+ (define-key map [transient-scroll-down] #'transient--do-stay)
+ (define-key map [mwheel-scroll] #'transient--do-stay)
+ (define-key map [scroll-bar-toolkit-scroll] #'transient--do-stay)
+ (define-key map [transient-noop] #'transient--do-noop)
+ (define-key map [transient-mouse-push-button] #'transient--do-move)
+ (define-key map [transient-push-button] #'transient--do-push-button)
+ (define-key map [transient-backward-button] #'transient--do-move)
+ (define-key map [transient-forward-button] #'transient--do-move)
+ (define-key map [transient-isearch-backward] #'transient--do-move)
+ (define-key map [transient-isearch-forward] #'transient--do-move)
+ ;; If a valid but incomplete prefix sequence is followed by
+ ;; an unbound key, then Emacs calls the `undefined' command
+ ;; but does not set `this-command', `this-original-command'
+ ;; or `real-this-command' accordingly. Instead they are nil.
+ (define-key map [nil] #'transient--do-warn)
+ map)
+ "Base keymap used to map common commands to their transient behavior.
+
+The \"transient behavior\" of a command controls, among other
+things, whether invoking the command causes the transient to be
+exited or not and whether infix arguments are exported before
+doing so.
+
+Each \"key\" is a command that is common to all transients and
+that is bound in `transient-map', `transient-edit-map',
+`transient-sticky-map' and/or `transient-common-command'.
+
+Each binding is a \"pre-command\", a function that controls the
+transient behavior of the respective command.
+
+For transient commands that are bound in individual transients,
+the transient behavior is specified using the `:transient' slot
+of the corresponding object.")
+
+(defvar transient--transient-map nil)
+(defvar transient--predicate-map nil)
+(defvar transient--redisplay-map nil)
+(defvar transient--redisplay-key nil)
+
+(defun transient--push-keymap (var)
+ (let ((map (symbol-value var)))
+ (transient--debug " push %s%s" var (if map "" " VOID"))
+ (when map
+ (with-demoted-errors "transient--push-keymap: %S"
+ (internal-push-keymap map 'overriding-terminal-local-map)))))
+
+(defun transient--pop-keymap (var)
+ (let ((map (symbol-value var)))
+ (transient--debug " pop %s%s" var (if map "" " VOID"))
+ (when map
+ (with-demoted-errors "transient--pop-keymap: %S"
+ (internal-pop-keymap map 'overriding-terminal-local-map)))))
+
+(defun transient--make-transient-map ()
+ (let ((map (make-sparse-keymap)))
+ (set-keymap-parent map (if transient--editp
+ transient-edit-map
+ transient-map))
+ (dolist (obj transient--suffixes)
+ (let ((key (oref obj key)))
+ (when (vectorp key)
+ (setq key (key-description key))
+ (oset obj key key))
+ (when transient-substitute-key-function
+ (setq key (save-match-data
+ (funcall transient-substitute-key-function obj)))
+ (oset obj key key))
+ (let ((kbd (kbd key))
+ (cmd (transient--suffix-command obj)))
+ (when-let ((conflict (and transient-detect-key-conflicts
+ (transient--lookup-key map kbd))))
+ (unless (eq cmd conflict)
+ (error "Cannot bind %S to %s and also %s"
+ (string-trim key)
+ cmd conflict)))
+ (define-key map kbd cmd))))
+ (when transient-enable-popup-navigation
+ ;; `transient--make-redisplay-map' maps only over bindings that are
+ ;; directly in the base keymap, so that cannot be a composed keymap.
+ (set-keymap-parent
+ map (make-composed-keymap
+ (keymap-parent map)
+ transient-popup-navigation-map)))
+ map))
+
+(defun transient--make-predicate-map ()
+ (let ((map (make-sparse-keymap)))
+ (set-keymap-parent map transient-predicate-map)
+ (when (memq (oref transient--prefix transient-non-suffix)
+ '(nil transient--do-warn transient--do-noop))
+ (define-key map [handle-switch-frame] #'transient--do-suspend))
+ (dolist (obj transient--suffixes)
+ (let* ((cmd (oref obj command))
+ (sub-prefix (and (symbolp cmd) (get cmd 'transient--prefix) t))
+ (sym (transient--suffix-symbol cmd)))
+ (cond
+ ((oref obj inapt)
+ (define-key map (vector sym) #'transient--do-warn-inapt))
+ ((slot-boundp obj 'transient)
+ (define-key map (vector sym)
+ (let ((do (oref obj transient)))
+ (pcase (list do sub-prefix)
+ ('(t t) #'transient--do-recurse)
+ ('(t nil) (if (cl-typep obj 'transient-infix)
+ #'transient--do-stay
+ #'transient--do-call))
+ ('(nil t) #'transient--do-replace)
+ ('(nil nil) #'transient--do-exit)
+ (_ do)))))
+ ((not (lookup-key transient-predicate-map (vector sym)))
+ (define-key map (vector sym)
+ (if sub-prefix
+ #'transient--do-replace
+ (or (oref transient--prefix transient-suffix)
+ #'transient--do-exit)))))))
+ map))
+
+(defun transient--make-redisplay-map ()
+ (setq transient--redisplay-key
+ (cl-case this-command
+ (transient-update
+ (setq transient--showp t)
+ (setq unread-command-events
+ (listify-key-sequence (this-single-command-raw-keys))))
+ (transient-quit-seq
+ (setq unread-command-events
+ (butlast (listify-key-sequence
+ (this-single-command-raw-keys))
+ 2))
+ (butlast transient--redisplay-key))
+ (t nil)))
+ (let ((topmap (make-sparse-keymap))
+ (submap (make-sparse-keymap)))
+ (when transient--redisplay-key
+ (define-key topmap (vconcat transient--redisplay-key) submap)
+ (set-keymap-parent submap transient-sticky-map))
+ (map-keymap-internal
+ (lambda (key def)
+ (when (and (not (eq key ?\e))
+ (listp def)
+ (keymapp def))
+ (define-key topmap (vconcat transient--redisplay-key (list key))
+ #'transient-update)))
+ (if transient--redisplay-key
+ (lookup-key transient--transient-map (vconcat transient--redisplay-key))
+ transient--transient-map))
+ topmap))
+
+;;; Setup
+
+(defun transient-setup (&optional name layout edit &rest params)
+ "Setup the transient specified by NAME.
+
+This function is called by transient prefix commands to setup the
+transient. In that case NAME is mandatory, LAYOUT and EDIT must
+be nil and PARAMS may be (but usually is not) used to set e.g. the
+\"scope\" of the transient (see `transient-define-prefix').
+
+This function is also called internally in which case LAYOUT and
+EDIT may be non-nil."
+ (transient--debug 'setup)
+ (transient--with-emergency-exit
+ (cond
+ ((not name)
+ ;; Switching between regular and edit mode.
+ (transient--pop-keymap 'transient--transient-map)
+ (transient--pop-keymap 'transient--redisplay-map)
+ (setq name (oref transient--prefix command))
+ (setq params (list :scope (oref transient--prefix scope))))
+ (transient--prefix
+ ;; Invoked as a ":transient-non-suffix 'transient--do-{stay,call}"
+ ;; of an outer prefix. Unlike the usual `transient--do-replace',
+ ;; these predicates fail to clean up after the outer prefix.
+ (transient--pop-keymap 'transient--transient-map)
+ (transient--pop-keymap 'transient--redisplay-map))
+ ((not (or layout ; resuming parent/suspended prefix
+ transient-current-command)) ; entering child prefix
+ (transient--stack-zap)) ; replace suspended prefix, if any
+ (edit
+ ;; Returning from help to edit.
+ (setq transient--editp t)))
+ (transient--init-objects name layout params)
+ (transient--history-init transient--prefix)
+ (setq transient--predicate-map (transient--make-predicate-map))
+ (setq transient--transient-map (transient--make-transient-map))
+ (setq transient--redisplay-map (transient--make-redisplay-map))
+ (setq transient--original-window (selected-window))
+ (setq transient--original-buffer (current-buffer))
+ (setq transient--minibuffer-depth (minibuffer-depth))
+ (transient--redisplay)
+ (transient--init-transient)
+ (transient--suspend-which-key-mode)))
+
+(cl-defgeneric transient-setup-children (group children)
+ "Setup the CHILDREN of GROUP.
+If the value of the `setup-children' slot is non-nil, then call
+that function with CHILDREN as the only argument and return the
+value. Otherwise return CHILDREN as is."
+ (if (slot-boundp group 'setup-children)
+ (funcall (oref group setup-children) children)
+ children))
+
+(defun transient--init-objects (name layout params)
+ (setq transient--prefix (transient--init-prefix name params))
+ (setq transient--layout (or layout (transient--init-suffixes name)))
+ (setq transient--suffixes (transient--flatten-suffixes transient--layout)))
+
+(defun transient--init-prefix (name &optional params)
+ (let ((obj (let ((proto (get name 'transient--prefix)))
+ (apply #'clone proto
+ :prototype proto
+ :level (or (alist-get t (alist-get name transient-levels))
+ transient-default-level)
+ params))))
+ (transient--setup-recursion obj)
+ (transient-init-value obj)
+ obj))
+
+(defun transient--init-suffixes (name)
+ (let ((levels (alist-get name transient-levels)))
+ (cl-mapcan (lambda (c) (transient--init-child levels c))
+ (append (get name 'transient--layout)
+ (and (not transient--editp)
+ (get 'transient-common-commands
+ 'transient--layout))))))
+
+(defun transient--flatten-suffixes (layout)
+ (cl-labels ((s (def)
+ (cond
+ ((stringp def) nil)
+ ((listp def) (cl-mapcan #'s def))
+ ((transient-group--eieio-childp def)
+ (cl-mapcan #'s (oref def suffixes)))
+ ((transient-suffix--eieio-childp def)
+ (list def)))))
+ (cl-mapcan #'s layout)))
+
+(defun transient--init-child (levels spec)
+ (cl-etypecase spec
+ (vector (transient--init-group levels spec))
+ (list (transient--init-suffix levels spec))
+ (string (list spec))))
+
+(defun transient--init-group (levels spec)
+ (pcase-let ((`(,level ,class ,args ,children) (append spec nil)))
+ (when-let* ((- (transient--use-level-p level))
+ (obj (apply class :level level args))
+ (- (transient--use-suffix-p obj))
+ (suffixes (cl-mapcan (lambda (c) (transient--init-child levels c))
+ (transient-setup-children obj children))))
+ ;; Cannot use and-let* because of debbugs#31840.
+ (oset obj suffixes suffixes)
+ (list obj))))
+
+(defun transient--init-suffix (levels spec)
+ (pcase-let* ((`(,level ,class ,args) spec)
+ (cmd (plist-get args :command))
+ (level (or (alist-get (transient--suffix-symbol cmd) levels)
+ level)))
+ (let ((fn (and (symbolp cmd)
+ (symbol-function cmd))))
+ (when (autoloadp fn)
+ (transient--debug " autoload %s" cmd)
+ (autoload-do-load fn)))
+ (when (transient--use-level-p level)
+ (let ((obj (if-let ((proto (and cmd
+ (symbolp cmd)
+ (get cmd 'transient--suffix))))
+ (apply #'clone proto :level level args)
+ (apply class :level level args))))
+ (transient--init-suffix-key obj)
+ (transient--ensure-infix-command obj)
+ (when (transient--use-suffix-p obj)
+ (if (transient--inapt-suffix-p obj)
+ (oset obj inapt t)
+ (transient-init-scope obj)
+ (transient-init-value obj))
+ (list obj))))))
+
+(cl-defmethod transient--init-suffix-key ((obj transient-suffix))
+ (unless (slot-boundp obj 'key)
+ (error "No key for %s" (oref obj command))))
+
+(cl-defmethod transient--init-suffix-key ((obj transient-argument))
+ (if (transient-switches--eieio-childp obj)
+ (cl-call-next-method obj)
+ (unless (slot-boundp obj 'shortarg)
+ (when-let ((shortarg (transient--derive-shortarg (oref obj argument))))
+ (oset obj shortarg shortarg)))
+ (unless (slot-boundp obj 'key)
+ (if (slot-boundp obj 'shortarg)
+ (oset obj key (oref obj shortarg))
+ (error "No key for %s" (oref obj command))))))
+
+(defun transient--use-level-p (level &optional edit)
+ (or (and transient--editp (not edit))
+ (and (>= level 1)
+ (<= level (oref transient--prefix level)))))
+
+(defun transient--use-suffix-p (obj)
+ (transient--do-suffix-p
+ (oref obj if)
+ (oref obj if-not)
+ (oref obj if-nil)
+ (oref obj if-non-nil)
+ (oref obj if-mode)
+ (oref obj if-not-mode)
+ (oref obj if-derived)
+ (oref obj if-not-derived)
+ t))
+
+(defun transient--inapt-suffix-p (obj)
+ (transient--do-suffix-p
+ (oref obj inapt-if)
+ (oref obj inapt-if-not)
+ (oref obj inapt-if-nil)
+ (oref obj inapt-if-non-nil)
+ (oref obj inapt-if-mode)
+ (oref obj inapt-if-not-mode)
+ (oref obj inapt-if-derived)
+ (oref obj inapt-if-not-derived)
+ nil))
+
+(defun transient--do-suffix-p
+ (if if-not if-nil if-non-nil if-mode if-not-mode if-derived if-not-derived
+ default)
+ (cond
+ (if (funcall if))
+ (if-not (not (funcall if-not)))
+ (if-non-nil (symbol-value if-non-nil))
+ (if-nil (not (symbol-value if-nil)))
+ (if-mode (if (atom if-mode)
+ (eq major-mode if-mode)
+ (memq major-mode if-mode)))
+ (if-not-mode (not (if (atom if-not-mode)
+ (eq major-mode if-not-mode)
+ (memq major-mode if-not-mode))))
+ (if-derived (if (atom if-derived)
+ (derived-mode-p if-derived)
+ (apply #'derived-mode-p if-derived)))
+ (if-not-derived (not (if (atom if-not-derived)
+ (derived-mode-p if-not-derived)
+ (apply #'derived-mode-p if-not-derived))))
+ (t default)))
+
+(defun transient--suffix-predicate (spec)
+ (let ((plist (nth 2 spec)))
+ (seq-some (lambda (prop)
+ (and-let* ((pred (plist-get plist prop)))
+ (list prop pred)))
+ '( :if :if-not
+ :if-nil :if-non-nil
+ :if-mode :if-not-mode
+ :if-derived :if-not-derived
+ :inapt-if :inapt-if-not
+ :inapt-if-nil :inapt-if-non-nil
+ :inapt-if-mode :inapt-if-not-mode
+ :inapt-if-derived :inapt-if-not-derived))))
+
+;;; Flow-Control
+
+(defun transient--init-transient ()
+ (transient--debug 'init-transient)
+ (transient--push-keymap 'transient--transient-map)
+ (transient--push-keymap 'transient--redisplay-map)
+ (add-hook 'pre-command-hook #'transient--pre-command)
+ (add-hook 'post-command-hook #'transient--post-command)
+ (when transient--exitp
+ ;; This prefix command was invoked as the suffix of another.
+ ;; Prevent `transient--post-command' from removing the hooks
+ ;; that we just added.
+ (setq transient--exitp 'replace)))
+
+(defun transient--pre-command ()
+ (transient--debug 'pre-command)
+ (transient--with-emergency-exit
+ ;; The use of `overriding-terminal-local-map' does not prevent the
+ ;; lookup of command remappings in the overridden maps, which can
+ ;; lead to a suffix being remapped to a non-suffix. We have to undo
+ ;; the remapping in that case. However, remapping a non-suffix to
+ ;; another should remain possible.
+ (when (and (transient--get-predicate-for this-original-command 'suffix)
+ (not (transient--get-predicate-for this-command 'suffix)))
+ (setq this-command this-original-command))
+ (cond
+ ((memq this-command '(transient-update transient-quit-seq))
+ (transient--pop-keymap 'transient--redisplay-map))
+ ((and transient--helpp
+ (not (memq this-command '(transient-quit-one
+ transient-quit-all))))
+ (cond
+ ((transient-help)
+ (transient--do-suspend)
+ (setq this-command 'transient-suspend)
+ (transient--pre-exit))
+ ((not (transient--edebug-command-p))
+ (setq this-command 'transient-undefined))))
+ ((and transient--editp
+ (transient-suffix-object)
+ (not (memq this-command '(transient-quit-one
+ transient-quit-all
+ transient-help))))
+ (setq this-command 'transient-set-level))
+ (t
+ (setq transient--exitp nil)
+ (when (eq (transient--do-pre-command) transient--exit)
+ (transient--pre-exit))))))
+
+(defun transient--do-pre-command ()
+ (if-let ((fn (transient--get-predicate-for this-command)))
+ (let ((action (funcall fn)))
+ (when (eq action transient--exit)
+ (setq transient--exitp (or transient--exitp t)))
+ action)
+ (if (let ((keys (this-command-keys-vector)))
+ (eq (aref keys (1- (length keys))) ?\C-g))
+ (setq this-command 'transient-noop)
+ (unless (transient--edebug-command-p)
+ (setq this-command 'transient-undefined)))
+ transient--stay))
+
+(defun transient--get-predicate-for (cmd &optional suffix-only)
+ (or (ignore-errors
+ (lookup-key transient--predicate-map
+ (vector (transient--suffix-symbol cmd))))
+ (and (not suffix-only)
+ (let ((pred (oref transient--prefix transient-non-suffix)))
+ (pcase pred
+ ('t #'transient--do-stay)
+ ('nil #'transient--do-warn)
+ (_ pred))))))
+
+(defun transient--pre-exit ()
+ (transient--debug 'pre-exit)
+ (transient--delete-window)
+ (transient--timer-cancel)
+ (transient--pop-keymap 'transient--transient-map)
+ (transient--pop-keymap 'transient--redisplay-map)
+ (unless transient--showp
+ (let ((message-log-max nil))
+ (message "")))
+ (setq transient--transient-map nil)
+ (setq transient--predicate-map nil)
+ (setq transient--redisplay-map nil)
+ (setq transient--redisplay-key nil)
+ (setq transient--showp nil)
+ (setq transient--helpp nil)
+ (setq transient--editp nil)
+ (setq transient--prefix nil)
+ (setq transient--layout nil)
+ (setq transient--suffixes nil)
+ (setq transient--original-window nil)
+ (setq transient--original-buffer nil)
+ (setq transient--window nil))
+
+(defun transient--delete-window ()
+ (when (window-live-p transient--window)
+ (let ((remain-in-minibuffer-window
+ (and (minibuffer-selected-window)
+ (selected-window)))
+ (buf (window-buffer transient--window)))
+ ;; Only delete the window if it never showed another buffer.
+ (unless (eq (car (window-parameter transient--window 'quit-restore)) 'other)
+ (with-demoted-errors "Error while exiting transient: %S"
+ (delete-window transient--window)))
+ (kill-buffer buf)
+ (when remain-in-minibuffer-window
+ (select-window remain-in-minibuffer-window)))))
+
+(defun transient--export ()
+ (setq transient-current-prefix transient--prefix)
+ (setq transient-current-command (oref transient--prefix command))
+ (setq transient-current-suffixes transient--suffixes)
+ (transient--history-push transient--prefix))
+
+(defun transient--suspend-override (&optional nohide)
+ (transient--debug 'suspend-override)
+ (when (and (not nohide) transient-hide-during-minibuffer-read)
+ (transient--delete-window))
+ (transient--pop-keymap 'transient--transient-map)
+ (transient--pop-keymap 'transient--redisplay-map)
+ (remove-hook 'pre-command-hook #'transient--pre-command)
+ (remove-hook 'post-command-hook #'transient--post-command))
+
+(defun transient--resume-override ()
+ (transient--debug 'resume-override)
+ (when (and transient--showp transient-hide-during-minibuffer-read)
+ (transient--show))
+ (transient--push-keymap 'transient--transient-map)
+ (transient--push-keymap 'transient--redisplay-map)
+ (add-hook 'pre-command-hook #'transient--pre-command)
+ (add-hook 'post-command-hook #'transient--post-command))
+
+(defmacro transient--with-suspended-override (&rest body)
+ (let ((depth (make-symbol "depth"))
+ (setup (make-symbol "setup"))
+ (exit (make-symbol "exit")))
+ `(if (and transient--transient-map
+ (memq transient--transient-map
+ overriding-terminal-local-map))
+ (let ((,depth (1+ (minibuffer-depth))) ,setup ,exit)
+ (setq ,setup
+ (lambda () "@transient--with-suspended-override"
+ (transient--debug 'minibuffer-setup)
+ (remove-hook 'minibuffer-setup-hook ,setup)
+ (transient--suspend-override)))
+ (setq ,exit
+ (lambda () "@transient--with-suspended-override"
+ (transient--debug 'minibuffer-exit)
+ (when (= (minibuffer-depth) ,depth)
+ (transient--resume-override))))
+ (unwind-protect
+ (progn
+ (add-hook 'minibuffer-setup-hook ,setup)
+ (add-hook 'minibuffer-exit-hook ,exit)
+ ,@body)
+ (remove-hook 'minibuffer-setup-hook ,setup)
+ (remove-hook 'minibuffer-exit-hook ,exit)))
+ ,@body)))
+
+(defun transient--post-command-hook ()
+ (run-hooks 'transient--post-command-hook))
+
+(add-hook 'post-command-hook #'transient--post-command-hook)
+
+(defun transient--delay-post-command (&optional abort-only)
+ (transient--debug 'delay-post-command)
+ (let ((depth (minibuffer-depth))
+ (command this-command)
+ (delayed (if transient--exitp
+ (apply-partially #'transient--post-exit this-command)
+ #'transient--resume-override))
+ post-command abort-minibuffer)
+ (unless abort-only
+ (setq post-command
+ (lambda () "@transient--delay-post-command"
+ (let ((act (and (eq this-command command)
+ (not (eq (this-command-keys-vector) [])))))
+ (transient--debug 'post-command-hook "act: %s" act)
+ (when act
+ (remove-hook 'transient--post-command-hook post-command)
+ (remove-hook 'minibuffer-exit-hook abort-minibuffer)
+ (funcall delayed)))))
+ (add-hook 'transient--post-command-hook post-command))
+ (setq abort-minibuffer
+ (lambda () "@transient--delay-post-command"
+ (let ((act (and (or (memq this-command transient--abort-commands)
+ (equal (this-command-keys) ""))
+ (= (minibuffer-depth) depth))))
+ (transient--debug
+ 'abort-minibuffer
+ "mini: %s|%s, act %s" (minibuffer-depth) depth act)
+ (when act
+ (remove-hook 'transient--post-command-hook post-command)
+ (remove-hook 'minibuffer-exit-hook abort-minibuffer)
+ (funcall delayed)))))
+ (add-hook 'minibuffer-exit-hook abort-minibuffer)))
+
+(defun transient--post-command ()
+ (transient--debug 'post-command)
+ (transient--with-emergency-exit
+ (cond
+ ((and (eq (this-command-keys-vector) [])
+ (= (minibuffer-depth)
+ (1+ transient--minibuffer-depth)))
+ (transient--suspend-override)
+ (transient--delay-post-command (eq transient--exitp 'replace)))
+ (transient--exitp
+ (transient--post-exit))
+ ((eq this-command (oref transient--prefix command)))
+ (t
+ (let ((old transient--redisplay-map)
+ (new (transient--make-redisplay-map)))
+ (unless (equal old new)
+ (transient--pop-keymap 'transient--redisplay-map)
+ (setq transient--redisplay-map new)
+ (transient--push-keymap 'transient--redisplay-map)))
+ (transient--redisplay)))))
+
+(defun transient--post-exit (&optional command)
+ (transient--debug 'post-exit)
+ (unless (and (eq transient--exitp 'replace)
+ (or transient--prefix
+ ;; The current command could act as a prefix,
+ ;; but decided not to call `transient-setup',
+ ;; or it is prevented from doing so because it
+ ;; uses the minibuffer and the user aborted
+ ;; that.
+ (prog1 nil
+ (if (let ((obj (transient-suffix-object command)))
+ (and (slot-boundp obj 'transient)
+ (oref obj transient)))
+ ;; This sub-prefix is a transient suffix;
+ ;; go back to outer prefix, by calling
+ ;; `transient--stack-pop' further down.
+ (setq transient--exitp nil)
+ (transient--stack-zap)))))
+ (remove-hook 'pre-command-hook #'transient--pre-command)
+ (remove-hook 'post-command-hook #'transient--post-command))
+ (setq transient-current-prefix nil)
+ (setq transient-current-command nil)
+ (setq transient-current-suffixes nil)
+ (let ((resume (and transient--stack
+ (not (memq transient--exitp '(replace suspend))))))
+ (setq transient--exitp nil)
+ (setq transient--helpp nil)
+ (setq transient--editp nil)
+ (setq transient--minibuffer-depth 0)
+ (run-hooks 'transient-exit-hook)
+ (when resume
+ (transient--stack-pop))))
+
+(defun transient--stack-push ()
+ (transient--debug 'stack-push)
+ (push (list (oref transient--prefix command)
+ transient--layout
+ transient--editp
+ :scope (oref transient--prefix scope))
+ transient--stack))
+
+(defun transient--stack-pop ()
+ (transient--debug 'stack-pop)
+ (and transient--stack
+ (prog1 t (apply #'transient-setup (pop transient--stack)))))
+
+(defun transient--stack-zap ()
+ (transient--debug 'stack-zap)
+ (setq transient--stack nil))
+
+(defun transient--redisplay ()
+ (if (or (eq transient-show-popup t)
+ transient--showp)
+ (unless
+ (or (memq this-command transient--scroll-commands)
+ (and (or (memq this-command '(mouse-drag-region
+ mouse-set-region))
+ (equal (key-description (this-command-keys-vector))
+ "<mouse-movement>"))
+ (and (eq (current-buffer)
+ (get-buffer transient--buffer-name)))))
+ (transient--show))
+ (when (and (numberp transient-show-popup)
+ (not (zerop transient-show-popup))
+ (not transient--timer))
+ (transient--timer-start))
+ (transient--show-brief)))
+
+(defun transient--timer-start ()
+ (setq transient--timer
+ (run-at-time (abs transient-show-popup) nil
+ (lambda ()
+ (transient--timer-cancel)
+ (transient--show)
+ (let ((message-log-max nil))
+ (message ""))))))
+
+(defun transient--timer-cancel ()
+ (when transient--timer
+ (cancel-timer transient--timer)
+ (setq transient--timer nil)))
+
+(defun transient--debug (arg &rest args)
+ (when transient--debug
+ (let ((inhibit-message (not (eq transient--debug 'message))))
+ (if (symbolp arg)
+ (message "-- %-18s (cmd: %s, event: %S, exit: %s%s)"
+ arg
+ (or (ignore-errors (transient--suffix-symbol this-command))
+ (if (byte-code-function-p this-command)
+ "#[...]"
+ this-command))
+ (key-description (this-command-keys-vector))
+ transient--exitp
+ (cond ((stringp (car args))
+ (concat ", " (apply #'format args)))
+ (args
+ (concat ", " (apply (car args) (cdr args))))
+ (t "")))
+ (apply #'message arg args)))))
+
+(defun transient--emergency-exit ()
+ "Exit the current transient command after an error occurred.
+When no transient is active (i.e. when `transient--prefix' is
+nil) then do nothing."
+ (transient--debug 'emergency-exit)
+ (when transient--prefix
+ (setq transient--stack nil)
+ (setq transient--exitp t)
+ (transient--pre-exit)
+ (transient--post-exit)))
+
+;;; Pre-Commands
+
+(defun transient--do-stay ()
+ "Call the command without exporting variables and stay transient."
+ transient--stay)
+
+(defun transient--do-noop ()
+ "Call `transient-noop' and stay transient."
+ (setq this-command 'transient-noop)
+ transient--stay)
+
+(defun transient--do-warn ()
+ "Call `transient-undefined' and stay transient."
+ (setq this-command 'transient-undefined)
+ transient--stay)
+
+(defun transient--do-warn-inapt ()
+ "Call `transient-inapt' and stay transient."
+ (setq this-command 'transient-inapt)
+ transient--stay)
+
+(defun transient--do-call ()
+ "Call the command after exporting variables and stay transient."
+ (transient--export)
+ transient--stay)
+
+(defun transient--do-return ()
+ "Call the command after exporting variables and return to parent prefix.
+If there is no parent prefix, then behave like `transient--do-exit'."
+ (if (not transient--stack)
+ (transient--do-exit)
+ (transient--export)
+ transient--exit))
+
+(defun transient--do-exit ()
+ "Call the command after exporting variables and exit the transient."
+ (transient--export)
+ (transient--stack-zap)
+ transient--exit)
+
+(defun transient--do-push-button ()
+ "Call the command represented by the activated button.
+Use that command's pre-command to determine transient behavior."
+ (if (and (mouse-event-p last-command-event)
+ (not (eq (posn-window (event-start last-command-event))
+ transient--window)))
+ transient--stay
+ (setq this-command
+ (with-selected-window transient--window
+ (get-text-property (if (mouse-event-p last-command-event)
+ (posn-point (event-start last-command-event))
+ (point))
+ 'command)))
+ (transient--do-pre-command)))
+
+(defun transient--do-recurse ()
+ "Call the transient prefix command, preparing for return to active transient.
+If there is no parent prefix, then just call the command."
+ (transient--do-replace))
+
+(defun transient--setup-recursion (prefix-obj)
+ (when transient--stack
+ (let ((command (oref prefix-obj command)))
+ (when-let ((suffix-obj (transient-suffix-object command)))
+ (when (and (slot-boundp suffix-obj 'transient)
+ (memq (oref suffix-obj transient)
+ (list t #'transient--do-recurse)))
+ (oset prefix-obj transient-suffix 'transient--do-return))))))
+
+(defun transient--do-replace ()
+ "Call the transient prefix command, replacing the active transient."
+ (transient--export)
+ (transient--stack-push)
+ (setq transient--exitp 'replace)
+ transient--exit)
+
+(defun transient--do-suspend ()
+ "Suspend the active transient, saving the transient stack."
+ (transient--stack-push)
+ (setq transient--exitp 'suspend)
+ transient--exit)
+
+(defun transient--do-quit-one ()
+ "If active, quit help or edit mode, else exit the active transient."
+ (cond (transient--helpp
+ (setq transient--helpp nil)
+ transient--stay)
+ (transient--editp
+ (setq transient--editp nil)
+ (transient-setup)
+ transient--stay)
+ (t transient--exit)))
+
+(defun transient--do-quit-all ()
+ "Exit all transients without saving the transient stack."
+ (transient--stack-zap)
+ transient--exit)
+
+(defun transient--do-move ()
+ "Call the command if `transient-enable-popup-navigation' is non-nil.
+In that case behave like `transient--do-stay', otherwise similar
+to `transient--do-warn'."
+ (unless transient-enable-popup-navigation
+ (setq this-command 'transient-popup-navigation-help))
+ transient--stay)
+
+(defun transient--do-minus ()
+ "Call `negative-argument' or pivot to `transient-update'.
+If `negative-argument' is invoked using \"-\" then preserve the
+prefix argument and pivot to `transient-update'."
+ (when (equal (this-command-keys) "-")
+ (setq this-command 'transient-update))
+ transient--stay)
+
+(put 'transient--do-stay 'transient-color 'transient-red)
+(put 'transient--do-noop 'transient-color 'transient-red)
+(put 'transient--do-warn 'transient-color 'transient-red)
+(put 'transient--do-warn-inapt 'transient-color 'transient-red)
+(put 'transient--do-call 'transient-color 'transient-red)
+(put 'transient--do-return 'transient-color 'transient-purple)
+(put 'transient--do-exit 'transient-color 'transient-blue)
+(put 'transient--do-recurse 'transient-color 'transient-red)
+(put 'transient--do-replace 'transient-color 'transient-blue)
+(put 'transient--do-suspend 'transient-color 'transient-blue)
+(put 'transient--do-quit-one 'transient-color 'transient-blue)
+(put 'transient--do-quit-all 'transient-color 'transient-blue)
+(put 'transient--do-move 'transient-color 'transient-red)
+(put 'transient--do-minus 'transient-color 'transient-red)
+
+;;; Commands
+
+(defun transient-noop ()
+ "Do nothing at all."
+ (interactive))
+
+(defun transient-undefined ()
+ "Warn the user that the pressed key is not bound to any suffix."
+ (interactive)
+ (transient--invalid "Unbound suffix"))
+
+(defun transient-inapt ()
+ "Warn the user that the invoked command is inapt."
+ (interactive)
+ (transient--invalid "Inapt command"))
+
+(defun transient--invalid (msg)
+ (ding)
+ (message "%s: `%s' (Use `%s' to abort, `%s' for help) [%s]"
+ msg
+ (propertize (key-description (this-single-command-keys))
+ 'face 'font-lock-warning-face)
+ (propertize "C-g" 'face 'transient-key)
+ (propertize "?" 'face 'transient-key)
+ ;; `this-command' is `transient--undefined' or similar at this
+ ;; point. Show the command the user actually tried to invoke.
+ (propertize (symbol-name (transient--suffix-symbol
+ this-original-command))
+ 'face 'font-lock-warning-face))
+ (unless (and transient--transient-map
+ (memq transient--transient-map overriding-terminal-local-map))
+ (let ((transient--prefix (or transient--prefix 'sic)))
+ (transient--emergency-exit))
+ (view-lossage)
+ (other-window 1)
+ (display-warning 'transient "Inconsistent transient state detected.
+This should never happen.
+Please open an issue and post the shown command log.
+This is a heisenbug, so any additional details might help.
+Thanks!" :error)))
+
+(defun transient-toggle-common ()
+ "Toggle whether common commands are always shown."
+ (interactive)
+ (setq transient-show-common-commands (not transient-show-common-commands)))
+
+(defun transient-suspend ()
+ "Suspend the current transient.
+It can later be resumed using `transient-resume' while no other
+transient is active."
+ (interactive))
+
+(defun transient-quit-all ()
+ "Exit all transients without saving the transient stack."
+ (interactive))
+
+(defun transient-quit-one ()
+ "Exit the current transients, possibly returning to the previous."
+ (interactive))
+
+(defun transient-quit-seq ()
+ "Abort the current incomplete key sequence."
+ (interactive))
+
+(defun transient-update ()
+ "Redraw the transient's state in the popup buffer."
+ (interactive)
+ (when (equal this-original-command 'negative-argument)
+ (setq prefix-arg current-prefix-arg)))
+
+(defun transient-show ()
+ "Show the transient's state in the popup buffer."
+ (interactive)
+ (setq transient--showp t))
+
+(defvar-local transient--restore-winconf nil)
+
+(defvar transient-resume-mode)
+
+(defun transient-help ()
+ "Show help for the active transient or one of its suffixes."
+ (interactive)
+ (if (called-interactively-p 'any)
+ (setq transient--helpp t)
+ (with-demoted-errors "transient-help: %S"
+ (when (lookup-key transient--transient-map
+ (this-single-command-raw-keys))
+ (setq transient--helpp nil)
+ (let ((winconf (current-window-configuration)))
+ (transient-show-help
+ (if (eq this-original-command 'transient-help)
+ transient--prefix
+ (or (transient-suffix-object)
+ this-original-command)))
+ (setq transient--restore-winconf winconf))
+ (fit-window-to-buffer nil (frame-height) (window-height))
+ (transient-resume-mode)
+ (message "Type \"q\" to resume transient command.")
+ t))))
+
+(defun transient-set-level (&optional command level)
+ "Set the level of the transient or one of its suffix commands."
+ (interactive
+ (let ((command this-original-command)
+ (prefix (oref transient--prefix command)))
+ (and (or (not (eq command 'transient-set-level))
+ (and transient--editp
+ (setq command prefix)))
+ (list command
+ (let ((keys (this-single-command-raw-keys)))
+ (and (lookup-key transient--transient-map keys)
+ (string-to-number
+ (let ((transient--active-infix
+ (transient-suffix-object command)))
+ (transient--show)
+ (transient--read-number-N
+ (format "Set level for `%s': "
+ (transient--suffix-symbol command))
+ nil nil (not (eq command prefix)))))))))))
+ (cond
+ ((not command)
+ (setq transient--editp t)
+ (transient-setup))
+ (level
+ (let* ((prefix (oref transient--prefix command))
+ (alist (alist-get prefix transient-levels))
+ (sym (transient--suffix-symbol command)))
+ (if (eq command prefix)
+ (progn (oset transient--prefix level level)
+ (setq sym t))
+ (oset (transient-suffix-object command) level level))
+ (setf (alist-get sym alist) level)
+ (setf (alist-get prefix transient-levels) alist))
+ (transient-save-levels)
+ (transient--show))
+ (t
+ (transient-undefined))))
+
+(defun transient-set ()
+ "Save the value of the active transient for this Emacs session."
+ (interactive)
+ (transient-set-value (or transient--prefix transient-current-prefix)))
+
+(defun transient-save ()
+ "Save the value of the active transient persistenly across Emacs sessions."
+ (interactive)
+ (transient-save-value (or transient--prefix transient-current-prefix)))
+
+(defun transient-reset ()
+ "Clear the set and saved values of the active transient."
+ (interactive)
+ (transient-reset-value (or transient--prefix transient-current-prefix)))
+
+(defun transient-history-next ()
+ "Switch to the next value used for the active transient."
+ (interactive)
+ (let* ((obj transient--prefix)
+ (pos (1- (oref obj history-pos)))
+ (hst (oref obj history)))
+ (if (< pos 0)
+ (user-error "End of history")
+ (oset obj history-pos pos)
+ (oset obj value (nth pos hst))
+ (mapc #'transient-init-value transient--suffixes))))
+
+(defun transient-history-prev ()
+ "Switch to the previous value used for the active transient."
+ (interactive)
+ (let* ((obj transient--prefix)
+ (pos (1+ (oref obj history-pos)))
+ (hst (oref obj history))
+ (len (length hst)))
+ (if (> pos (1- len))
+ (user-error "End of history")
+ (oset obj history-pos pos)
+ (oset obj value (nth pos hst))
+ (mapc #'transient-init-value transient--suffixes))))
+
+(defun transient-scroll-up (&optional arg)
+ "Scroll text of transient popup window upward ARG lines.
+If ARG is nil scroll near full screen. This is a wrapper
+around `scroll-up-command' (which see)."
+ (interactive "^P")
+ (with-selected-window transient--window
+ (scroll-up-command arg)))
+
+(defun transient-scroll-down (&optional arg)
+ "Scroll text of transient popup window down ARG lines.
+If ARG is nil scroll near full screen. This is a wrapper
+around `scroll-down-command' (which see)."
+ (interactive "^P")
+ (with-selected-window transient--window
+ (scroll-down-command arg)))
+
+(defun transient-push-button ()
+ "Invoke the suffix command represented by this button."
+ (interactive))
+
+(defun transient-resume ()
+ "Resume a previously suspended stack of transients."
+ (interactive)
+ (cond (transient--stack
+ (let ((winconf transient--restore-winconf))
+ (kill-local-variable 'transient--restore-winconf)
+ (when transient-resume-mode
+ (transient-resume-mode -1)
+ (quit-window))
+ (when winconf
+ (set-window-configuration winconf)))
+ (transient--stack-pop))
+ (transient-resume-mode
+ (kill-local-variable 'transient--restore-winconf)
+ (transient-resume-mode -1)
+ (quit-window))
+ (t
+ (message "No suspended transient command"))))
+
+;;; Value
+;;;; Init
+
+(cl-defgeneric transient-init-scope (obj)
+ "Set the scope of the suffix object OBJ.
+
+The scope is actually a property of the transient prefix, not of
+individual suffixes. However it is possible to invoke a suffix
+command directly instead of from a transient. In that case, if
+the suffix expects a scope, then it has to determine that itself
+and store it in its `scope' slot.
+
+This function is called for all suffix commands, but unless a
+concrete method is implemented this falls through to the default
+implementation, which is a noop.")
+
+(cl-defmethod transient-init-scope ((_ transient-suffix))
+ "Noop." nil)
+
+(cl-defgeneric transient-init-value (_)
+ "Set the initial value of the object OBJ.
+
+This function is called for all prefix and suffix commands.
+
+For suffix commands (including infix argument commands) the
+default implementation is a noop. Classes derived from the
+abstract `transient-infix' class must implement this function.
+Non-infix suffix commands usually don't have a value."
+ nil)
+
+(cl-defmethod transient-init-value :around ((obj transient-prefix))
+ "If bound, then call OBJ's `init-value' function.
+Otherwise call the primary method according to object's class."
+ (if (slot-boundp obj 'init-value)
+ (funcall (oref obj init-value) obj)
+ (cl-call-next-method obj)))
+
+(cl-defmethod transient-init-value :around ((obj transient-infix))
+ "If bound, then call OBJ's `init-value' function.
+Otherwise call the primary method according to object's class."
+ (if (slot-boundp obj 'init-value)
+ (funcall (oref obj init-value) obj)
+ (cl-call-next-method obj)))
+
+(cl-defmethod transient-init-value ((obj transient-prefix))
+ (if (slot-boundp obj 'value)
+ (oref obj value)
+ (oset obj value
+ (if-let ((saved (assq (oref obj command) transient-values)))
+ (cdr saved)
+ (transient-default-value obj)))))
+
+(cl-defmethod transient-init-value ((obj transient-argument))
+ (oset obj value
+ (let ((value (oref transient--prefix value))
+ (argument (and (slot-boundp obj 'argument)
+ (oref obj argument)))
+ (multi-value (oref obj multi-value))
+ (case-fold-search nil)
+ (regexp (if (slot-exists-p obj 'argument-regexp)
+ (oref obj argument-regexp)
+ (format "\\`%s\\(.*\\)" (oref obj argument)))))
+ (if (memq multi-value '(t rest))
+ (cdr (assoc argument value))
+ (let ((match (lambda (v)
+ (and (stringp v)
+ (string-match regexp v)
+ (match-string 1 v)))))
+ (if multi-value
+ (delq nil (mapcar match value))
+ (cl-some match value)))))))
+
+(cl-defmethod transient-init-value ((obj transient-switch))
+ (oset obj value
+ (car (member (oref obj argument)
+ (oref transient--prefix value)))))
+
+;;;; Default
+
+(cl-defgeneric transient-default-value (_)
+ "Return the default value."
+ nil)
+
+(cl-defmethod transient-default-value ((obj transient-prefix))
+ (if-let ((default (and (slot-boundp obj 'default-value)
+ (oref obj default-value))))
+ (if (functionp default)
+ (funcall default)
+ default)
+ nil))
+
+;;;; Read
+
+(cl-defgeneric transient-infix-read (obj)
+ "Determine the new value of the infix object OBJ.
+
+This function merely determines the value; `transient-infix-set'
+is used to actually store the new value in the object.
+
+For most infix classes this is done by reading a value from the
+user using the reader specified by the `reader' slot (using the
+`transient-infix' method described below).
+
+For some infix classes the value is changed without reading
+anything in the minibuffer, i.e. the mere act of invoking the
+infix command determines what the new value should be, based
+on the previous value.")
+
+(cl-defmethod transient-infix-read :around ((obj transient-infix))
+ "Highlight the infix in the popup buffer.
+
+This also wraps the call to `cl-call-next-method' with two
+macros.
+
+`transient--with-suspended-override' is necessary to allow
+reading user input using the minibuffer.
+
+`transient--with-emergency-exit' arranges for the transient to
+be exited in case of an error because otherwise Emacs would get
+stuck in an inconsistent state, which might make it necessary to
+kill it from the outside.
+
+If you replace this method, then you must make sure to always use
+the latter macro and most likely also the former."
+ (let ((transient--active-infix obj))
+ (transient--show))
+ (transient--with-emergency-exit
+ (transient--with-suspended-override
+ (cl-call-next-method obj))))
+
+(cl-defmethod transient-infix-read ((obj transient-infix))
+ "Read a value while taking care of history.
+
+This method is suitable for a wide variety of infix commands,
+including but not limited to inline arguments and variables.
+
+If you do not use this method for your own infix class, then
+you should likely replicate a lot of the behavior of this
+method. If you fail to do so, then users might not appreciate
+the lack of history, for example.
+
+Only for very simple classes that toggle or cycle through a very
+limited number of possible values should you replace this with a
+simple method that does not handle history. (E.g. for a command
+line switch the only possible values are \"use it\" and \"don't use
+it\", in which case it is pointless to preserve history.)"
+ (with-slots (value multi-value always-read allow-empty choices) obj
+ (if (and value
+ (not multi-value)
+ (not always-read)
+ transient--prefix)
+ (oset obj value nil)
+ (let* ((enable-recursive-minibuffers t)
+ (reader (oref obj reader))
+ (prompt (transient-prompt obj))
+ (value (if multi-value (mapconcat #'identity value ",") value))
+ (history-key (or (oref obj history-key)
+ (oref obj command)))
+ (transient--history (alist-get history-key transient-history))
+ (transient--history (if (or (null value)
+ (eq value (car transient--history)))
+ transient--history
+ (cons value transient--history)))
+ (initial-input (and transient-read-with-initial-input
+ (car transient--history)))
+ (history (if initial-input
+ (cons 'transient--history 1)
+ 'transient--history))
+ (value
+ (cond
+ (reader (funcall reader prompt initial-input history))
+ (multi-value
+ (completing-read-multiple prompt choices nil nil
+ initial-input history))
+ (choices
+ (completing-read prompt choices nil t initial-input history))
+ (t (read-string prompt initial-input history)))))
+ (cond ((and (equal value "") (not allow-empty))
+ (setq value nil))
+ ((and (equal value "\"\"") allow-empty)
+ (setq value "")))
+ (when value
+ (when (and (bound-and-true-p ivy-mode)
+ (stringp (car transient--history)))
+ (set-text-properties 0 (length (car transient--history)) nil
+ (car transient--history)))
+ (setf (alist-get history-key transient-history)
+ (delete-dups transient--history)))
+ value))))
+
+(cl-defmethod transient-infix-read ((obj transient-switch))
+ "Toggle the switch on or off."
+ (if (oref obj value) nil (oref obj argument)))
+
+(cl-defmethod transient-infix-read ((obj transient-switches))
+ "Cycle through the mutually exclusive switches.
+The last value is \"don't use any of these switches\"."
+ (let ((choices (mapcar (apply-partially #'format (oref obj argument-format))
+ (oref obj choices))))
+ (if-let ((value (oref obj value)))
+ (cadr (member value choices))
+ (car choices))))
+
+(cl-defmethod transient-infix-read ((command symbol))
+ "Elsewhere use the reader of the infix command COMMAND.
+Use this if you want to share an infix's history with a regular
+stand-alone command."
+ (cl-letf (((symbol-function #'transient--show) #'ignore))
+ (transient-infix-read (get command 'transient--suffix))))
+
+;;;; Readers
+
+(defun transient-read-file (prompt _initial-input _history)
+ "Read a file."
+ (file-local-name (expand-file-name (read-file-name prompt))))
+
+(defun transient-read-existing-file (prompt _initial-input _history)
+ "Read an existing file."
+ (file-local-name (expand-file-name (read-file-name prompt nil nil t))))
+
+(defun transient-read-directory (prompt _initial-input _history)
+ "Read a directory."
+ (file-local-name (expand-file-name (read-directory-name prompt))))
+
+(defun transient-read-existing-directory (prompt _initial-input _history)
+ "Read an existing directory."
+ (file-local-name (expand-file-name (read-directory-name prompt nil nil t))))
+
+(defun transient-read-number-N0 (prompt initial-input history)
+ "Read a natural number (including zero) and return it as a string."
+ (transient--read-number-N prompt initial-input history t))
+
+(defun transient-read-number-N+ (prompt initial-input history)
+ "Read a natural number (excluding zero) and return it as a string."
+ (transient--read-number-N prompt initial-input history nil))
+
+(defun transient--read-number-N (prompt initial-input history include-zero)
+ (save-match-data
+ (cl-block nil
+ (while t
+ (let ((str (read-from-minibuffer prompt initial-input nil nil history)))
+ (when (or (string-equal str "")
+ (string-match-p (if include-zero
+ "\\`\\(0\\|[1-9][0-9]*\\)\\'"
+ "\\`[1-9][0-9]*\\'")
+ str))
+ (cl-return str)))
+ (message "Please enter a natural number (%s zero)."
+ (if include-zero "including" "excluding"))
+ (sit-for 1)))))
+
+(defun transient-read-date (prompt default-time _history)
+ "Read a date using `org-read-date' (which see)."
+ (require 'org)
+ (when (fboundp 'org-read-date)
+ (org-read-date 'with-time nil nil prompt default-time)))
+
+;;;; Prompt
+
+(cl-defgeneric transient-prompt (obj)
+ "Return the prompt to be used to read infix object OBJ's value.")
+
+(cl-defmethod transient-prompt ((obj transient-infix))
+ "Return the prompt to be used to read infix object OBJ's value.
+
+This implementation should be suitable for almost all infix
+commands.
+
+If the value of OBJ's `prompt' slot is non-nil, then it must be
+a string or a function. If it is a string, then use that. If
+it is a function, then call that with OBJ as the only argument.
+That function must return a string, which is then used as the
+prompt.
+
+Otherwise, if the value of either the `argument' or `variable'
+slot of OBJ is a string, then base the prompt on that (preferring
+the former), appending either \"=\" (if it appears to be a
+command-line option) or \": \".
+
+Finally fall through to using \"(BUG: no prompt): \" as the
+prompt."
+ (if-let ((prompt (oref obj prompt)))
+ (let ((prompt (if (functionp prompt)
+ (funcall prompt obj)
+ prompt)))
+ (if (stringp prompt)
+ prompt
+ "(BUG: no prompt): "))
+ (or (and-let* ((arg (and (slot-boundp obj 'argument) (oref obj argument))))
+ (if (and (stringp arg) (string-suffix-p "=" arg))
+ arg
+ (concat arg ": ")))
+ (and-let* ((var (and (slot-boundp obj 'variable) (oref obj variable))))
+ (and (stringp var)
+ (concat var ": ")))
+ "(BUG: no prompt): ")))
+
+;;;; Set
+
+(defvar transient--unset-incompatible t)
+
+(cl-defgeneric transient-infix-set (obj value)
+ "Set the value of infix object OBJ to value.")
+
+(cl-defmethod transient-infix-set ((obj transient-infix) value)
+ "Set the value of infix object OBJ to value."
+ (oset obj value value))
+
+(cl-defmethod transient-infix-set :around ((obj transient-argument) value)
+ "Unset incompatible infix arguments."
+ (let ((arg (if (slot-boundp obj 'argument)
+ (oref obj argument)
+ (oref obj argument-regexp))))
+ (if-let ((sic (and value arg transient--unset-incompatible))
+ (spec (oref transient--prefix incompatible))
+ (incomp (cl-mapcan (lambda (rule)
+ (and (member arg rule)
+ (remove arg rule)))
+ spec)))
+ (progn
+ (cl-call-next-method obj value)
+ (dolist (arg incomp)
+ (when-let ((obj (cl-find-if (lambda (obj)
+ (and (slot-boundp obj 'argument)
+ (equal (oref obj argument) arg)))
+ transient--suffixes)))
+ (let ((transient--unset-incompatible nil))
+ (transient-infix-set obj nil)))))
+ (cl-call-next-method obj value))))
+
+(cl-defgeneric transient-set-value (obj)
+ "Set the value of the transient prefix OBJ.")
+
+(cl-defmethod transient-set-value ((obj transient-prefix))
+ (oset (oref obj prototype) value (transient-get-value))
+ (transient--history-push obj))
+
+;;;; Save
+
+(cl-defgeneric transient-save-value (obj)
+ "Save the value of the transient prefix OBJ.")
+
+(cl-defmethod transient-save-value ((obj transient-prefix))
+ (let ((value (transient-get-value)))
+ (oset (oref obj prototype) value value)
+ (setf (alist-get (oref obj command) transient-values) value)
+ (transient-save-values))
+ (transient--history-push obj))
+
+;;;; Reset
+
+(cl-defgeneric transient-reset-value (obj)
+ "Clear the set and saved values of the transient prefix OBJ.")
+
+(cl-defmethod transient-reset-value ((obj transient-prefix))
+ (let ((value (transient-default-value obj)))
+ (oset obj value value)
+ (oset (oref obj prototype) value value)
+ (setf (alist-get (oref obj command) transient-values nil 'remove) nil)
+ (transient-save-values))
+ (transient--history-push obj)
+ (mapc #'transient-init-value transient--suffixes))
+
+;;;; Get
+
+(defun transient-args (prefix)
+ "Return the value of the transient prefix command PREFIX.
+If the current command was invoked from the transient prefix
+command PREFIX, then return the active infix arguments. If
+the current command was not invoked from PREFIX, then return
+the set, saved or default value for PREFIX."
+ (cl-mapcan #'transient--get-wrapped-value (transient-suffixes prefix)))
+
+(defun transient-suffixes (prefix)
+ "Return the suffix objects of the transient prefix command PREFIX."
+ (if (eq transient-current-command prefix)
+ transient-current-suffixes
+ (let ((transient--prefix (transient--init-prefix prefix)))
+ (transient--flatten-suffixes
+ (transient--init-suffixes prefix)))))
+
+(defun transient-get-value ()
+ (transient--with-emergency-exit
+ (cl-mapcan (lambda (obj)
+ (and (or (not (slot-exists-p obj 'unsavable))
+ (not (oref obj unsavable)))
+ (transient--get-wrapped-value obj)))
+ transient-current-suffixes)))
+
+(defun transient--get-wrapped-value (obj)
+ (and-let* ((value (transient-infix-value obj)))
+ (cl-ecase (and (slot-exists-p obj 'multi-value)
+ (oref obj multi-value))
+ ((nil) (list value))
+ ((t rest) (list value))
+ (repeat value))))
+
+(cl-defgeneric transient-infix-value (obj)
+ "Return the value of the suffix object OBJ.
+
+This function is called by `transient-args' (which see), meaning
+this function is how the value of a transient is determined so
+that the invoked suffix command can use it.
+
+Currently most values are strings, but that is not set in stone.
+Nil is not a value, it means \"no value\".
+
+Usually only infixes have a value, but see the method for
+`transient-suffix'.")
+
+(cl-defmethod transient-infix-value ((_ transient-suffix))
+ "Return nil, which means \"no value\".
+
+Infix arguments contribute the transient's value while suffix
+commands consume it. This function is called for suffixes anyway
+because a command that both contributes to the transient's value
+and also consumes it is not completely unconceivable.
+
+If you define such a command, then you must define a derived
+class and implement this function because this default method
+does nothing." nil)
+
+(cl-defmethod transient-infix-value ((obj transient-infix))
+ "Return the value of OBJ's `value' slot."
+ (oref obj value))
+
+(cl-defmethod transient-infix-value ((obj transient-option))
+ "Return ARGUMENT and VALUE as a unit or nil if the latter is nil."
+ (and-let* ((value (oref obj value)))
+ (let ((arg (oref obj argument)))
+ (cl-ecase (oref obj multi-value)
+ ((nil) (concat arg value))
+ ((t rest) (cons arg value))
+ (repeat (mapcar (lambda (v) (concat arg v)) value))))))
+
+(cl-defmethod transient-infix-value ((_ transient-variable))
+ "Return nil, which means \"no value\".
+
+Setting the value of a variable is done by, well, setting the
+value of the variable. I.e. this is a side-effect and does not
+contribute to the value of the transient."
+ nil)
+
+;;;; Utilities
+
+(defun transient-arg-value (arg args)
+ "Return the value of ARG as it appears in ARGS.
+
+For a switch return a boolean. For an option return the value as
+a string, using the empty string for the empty value, or nil if
+the option does not appear in ARGS."
+ (if (string-suffix-p "=" arg)
+ (save-match-data
+ (and-let* ((match (let ((case-fold-search nil)
+ (re (format "\\`%s\\(?:=\\(.+\\)\\)?\\'"
+ (substring arg 0 -1))))
+ (cl-find-if (lambda (a)
+ (and (stringp a)
+ (string-match re a)))
+ args))))
+ (or (match-string 1 match) "")))
+ (and (member arg args) t)))
+
+;;; History
+
+(cl-defgeneric transient--history-key (obj)
+ "Return OBJ's history key.
+If the value of the `history-key' slot is non-nil, then return
+that. Otherwise return the value of the `command' slot."
+ (or (oref obj history-key)
+ (oref obj command)))
+
+(cl-defgeneric transient--history-push (obj)
+ "Push the current value of OBJ to its entry in `transient-history'."
+ (let ((key (transient--history-key obj)))
+ (setf (alist-get key transient-history)
+ (let ((args (transient-get-value)))
+ (cons args (delete args (alist-get key transient-history)))))))
+
+(cl-defgeneric transient--history-init (obj)
+ "Initialize OBJ's `history' slot.
+This is the transient-wide history; many individual infixes also
+have a history of their own.")
+
+(cl-defmethod transient--history-init ((obj transient-prefix))
+ "Initialize OBJ's `history' slot from the variable `transient-history'."
+ (let ((val (oref obj value)))
+ (oset obj history
+ (cons val (delete val (alist-get (transient--history-key obj)
+ transient-history))))))
+
+;;; Draw
+
+(defun transient--show-brief ()
+ (let ((message-log-max nil))
+ (if (and transient-show-popup (<= transient-show-popup 0))
+ (message "%s-" (key-description (this-command-keys)))
+ (message
+ "%s- [%s] %s"
+ (key-description (this-command-keys))
+ (oref transient--prefix command)
+ (mapconcat
+ #'identity
+ (sort
+ (cl-mapcan
+ (lambda (suffix)
+ (let ((key (kbd (oref suffix key))))
+ ;; Don't list any common commands.
+ (and (not (memq (oref suffix command)
+ `(,(lookup-key transient-map key)
+ ,(lookup-key transient-sticky-map key)
+ ;; From transient-common-commands:
+ transient-set
+ transient-save
+ transient-history-prev
+ transient-history-next
+ transient-quit-one
+ transient-toggle-common
+ transient-set-level)))
+ (list (propertize (oref suffix key) 'face 'transient-key)))))
+ transient--suffixes)
+ #'string<)
+ (propertize "|" 'face 'transient-unreachable-key))))))
+
+(defun transient--show ()
+ (transient--timer-cancel)
+ (setq transient--showp t)
+ (let ((buf (get-buffer-create transient--buffer-name))
+ (focus nil))
+ (with-current-buffer buf
+ (when transient-enable-popup-navigation
+ (setq focus (or (button-get (point) 'command)
+ (transient--heading-at-point))))
+ (erase-buffer)
+ (setq window-size-fixed t)
+ (when (bound-and-true-p tab-line-format)
+ (setq tab-line-format nil))
+ (setq header-line-format nil)
+ (setq mode-line-format (if (eq transient-mode-line-format 'line)
+ nil
+ transient-mode-line-format))
+ (setq mode-line-buffer-identification
+ (symbol-name (oref transient--prefix command)))
+ (if transient-enable-popup-navigation
+ (setq-local cursor-in-non-selected-windows 'box)
+ (setq cursor-type nil))
+ (setq display-line-numbers nil)
+ (setq show-trailing-whitespace nil)
+ (transient--insert-groups)
+ (when (or transient--helpp transient--editp)
+ (transient--insert-help))
+ (when (and (eq transient-mode-line-format 'line)
+ window-system)
+ (let ((face
+ (if-let ((f (and (transient--semantic-coloring-p)
+ (transient--prefix-color transient--prefix))))
+ `(,@(and (>= emacs-major-version 27) '(:extend t))
+ :background ,(face-foreground f))
+ 'transient-separator)))
+ (insert (propertize "__" 'face face 'display '(space :height (1))))
+ (insert (propertize "\n" 'face face 'line-height t))))
+ (when transient-force-fixed-pitch
+ (transient--force-fixed-pitch)))
+ (unless (window-live-p transient--window)
+ (setq transient--window
+ (display-buffer buf transient-display-buffer-action)))
+ (when (window-live-p transient--window)
+ (with-selected-window transient--window
+ (goto-char (point-min))
+ (when transient-enable-popup-navigation
+ (transient--goto-button focus))
+ (magit--fit-window-to-buffer transient--window)))))
+
+(defun magit--fit-window-to-buffer (window)
+ (let ((window-resize-pixelwise t)
+ (window-size-fixed nil))
+ (if (eq (car (window-parameter window 'quit-restore)) 'other)
+ ;; Grow but never shrink window that previously displayed
+ ;; another buffer and is going to display that again.
+ (fit-window-to-buffer window nil (window-height window))
+ (fit-window-to-buffer window nil 1))))
+
+(defun transient--insert-groups ()
+ (let ((groups (cl-mapcan (lambda (group)
+ (let ((hide (oref group hide)))
+ (and (not (and (functionp hide)
+ (funcall hide)))
+ (list group))))
+ transient--layout))
+ group)
+ (while (setq group (pop groups))
+ (transient--insert-group group)
+ (when groups
+ (insert ?\n)))))
+
+(defvar transient--max-group-level 1)
+
+(cl-defgeneric transient--insert-group (group)
+ "Format GROUP and its elements and insert the result.")
+
+(cl-defmethod transient--insert-group :around ((group transient-group))
+ "Insert GROUP's description, if any."
+ (when-let ((desc (transient-format-description group)))
+ (insert desc ?\n))
+ (let ((transient--max-group-level
+ (max (oref group level) transient--max-group-level)))
+ (cl-call-next-method group)))
+
+(cl-defmethod transient--insert-group ((group transient-row))
+ (transient--maybe-pad-keys group)
+ (dolist (suffix (oref group suffixes))
+ (insert (transient-format suffix))
+ (insert " "))
+ (insert ?\n))
+
+(cl-defmethod transient--insert-group ((group transient-column))
+ (transient--maybe-pad-keys group)
+ (dolist (suffix (oref group suffixes))
+ (let ((str (transient-format suffix)))
+ (insert str)
+ (unless (string-match-p ".\n\\'" str)
+ (insert ?\n)))))
+
+(cl-defmethod transient--insert-group ((group transient-columns))
+ (let* ((columns
+ (mapcar
+ (lambda (column)
+ (transient--maybe-pad-keys column group)
+ (let ((rows (mapcar #'transient-format (oref column suffixes))))
+ (when-let ((desc (transient-format-description column)))
+ (push desc rows))
+ (flatten-tree rows)))
+ (oref group suffixes)))
+ (vp (or (oref transient--prefix variable-pitch)
+ transient-align-variable-pitch))
+ (rs (apply #'max (mapcar #'length columns)))
+ (cs (length columns))
+ (cw (mapcar (lambda (col)
+ (apply #'max
+ (mapcar (if vp #'transient--pixel-width #'length)
+ col)))
+ columns))
+ (cc (transient--seq-reductions-from
+ (apply-partially #'+ (* 3 (if vp (transient--pixel-width " ") 1)))
+ cw 0)))
+ (if transient-force-single-column
+ (dotimes (c cs)
+ (dotimes (r rs)
+ (when-let ((cell (nth r (nth c columns))))
+ (unless (equal cell "")
+ (insert cell ?\n))))
+ (unless (= c (1- cs))
+ (insert ?\n)))
+ (dotimes (r rs)
+ (dotimes (c cs)
+ (if vp
+ (progn
+ (when-let ((cell (nth r (nth c columns))))
+ (insert cell))
+ (if (= c (1- cs))
+ (insert ?\n)
+ (insert (propertize " " 'display
+ `(space :align-to (,(nth (1+ c) cc)))))))
+ (insert (make-string (- (nth c cc) (current-column)) ?\s))
+ (when-let ((cell (nth r (nth c columns))))
+ (insert cell))
+ (when (= c (1- cs))
+ (insert ?\n))))))))
+
+(defun transient--pixel-width (string)
+ (save-window-excursion
+ (with-temp-buffer
+ (insert string)
+ (set-window-dedicated-p nil nil)
+ (set-window-buffer nil (current-buffer))
+ (car (window-text-pixel-size
+ nil (line-beginning-position) (point))))))
+
+(cl-defmethod transient--insert-group ((group transient-subgroups))
+ (let* ((subgroups (oref group suffixes))
+ (n (length subgroups)))
+ (dotimes (s n)
+ (let ((subgroup (nth s subgroups)))
+ (transient--maybe-pad-keys subgroup group)
+ (transient--insert-group subgroup)
+ (when (< s (1- n))
+ (insert ?\n))))))
+
+(cl-defgeneric transient-format (obj)
+ "Format and return OBJ for display.
+
+When this function is called, then the current buffer is some
+temporary buffer. If you need the buffer from which the prefix
+command was invoked to be current, then do so by temporarily
+making `transient--original-buffer' current.")
+
+(cl-defmethod transient-format ((arg string))
+ "Return the string ARG after applying the `transient-heading' face."
+ (propertize arg 'face 'transient-heading))
+
+(cl-defmethod transient-format ((_ null))
+ "Return a string containing just the newline character."
+ "\n")
+
+(cl-defmethod transient-format ((arg integer))
+ "Return a string containing just the ARG character."
+ (char-to-string arg))
+
+(cl-defmethod transient-format :around ((obj transient-infix))
+ "When reading user input for this infix, then highlight it."
+ (let ((str (cl-call-next-method obj)))
+ (when (eq obj transient--active-infix)
+ (setq str (concat str "\n"))
+ (add-face-text-property
+ (if (eq this-command 'transient-set-level) 3 0)
+ (length str)
+ 'transient-active-infix nil str))
+ str))
+
+(cl-defmethod transient-format :around ((obj transient-suffix))
+ "When edit-mode is enabled, then prepend the level information.
+Optional support for popup buttons is also implemented here."
+ (let ((str (concat
+ (and transient--editp
+ (let ((level (oref obj level)))
+ (propertize (format " %s " level)
+ 'face (if (transient--use-level-p level t)
+ 'transient-enabled-suffix
+ 'transient-disabled-suffix))))
+ (cl-call-next-method obj))))
+ (when (oref obj inapt)
+ (add-face-text-property 0 (length str) 'transient-inapt-suffix nil str))
+ (if transient-enable-popup-navigation
+ (make-text-button str nil
+ 'type 'transient-button
+ 'command (transient--suffix-command obj))
+ str)))
+
+(cl-defmethod transient-format ((obj transient-infix))
+ "Return a string generated using OBJ's `format'.
+%k is formatted using `transient-format-key'.
+%d is formatted using `transient-format-description'.
+%v is formatted using `transient-format-value'."
+ (format-spec (oref obj format)
+ `((?k . ,(transient-format-key obj))
+ (?d . ,(transient-format-description obj))
+ (?v . ,(transient-format-value obj)))))
+
+(cl-defmethod transient-format ((obj transient-suffix))
+ "Return a string generated using OBJ's `format'.
+%k is formatted using `transient-format-key'.
+%d is formatted using `transient-format-description'."
+ (format-spec (oref obj format)
+ `((?k . ,(transient-format-key obj))
+ (?d . ,(transient-format-description obj)))))
+
+(cl-defgeneric transient-format-key (obj)
+ "Format OBJ's `key' for display and return the result.")
+
+(cl-defmethod transient-format-key ((obj transient-suffix))
+ "Format OBJ's `key' for display and return the result."
+ (let ((key (oref obj key))
+ (cmd (oref obj command)))
+ (if transient--redisplay-key
+ (let ((len (length transient--redisplay-key))
+ (seq (cl-coerce (edmacro-parse-keys key t) 'list)))
+ (cond
+ ((equal (seq-take seq len) transient--redisplay-key)
+ (let ((pre (key-description (vconcat (seq-take seq len))))
+ (suf (key-description (vconcat (seq-drop seq len)))))
+ (setq pre (string-replace "RET" "C-m" pre))
+ (setq pre (string-replace "TAB" "C-i" pre))
+ (setq suf (string-replace "RET" "C-m" suf))
+ (setq suf (string-replace "TAB" "C-i" suf))
+ ;; We use e.g. "-k" instead of the more correct "- k",
+ ;; because the former is prettier. If we did that in
+ ;; the definition, then we want to drop the space that
+ ;; is reinserted above. False-positives are possible
+ ;; for silly bindings like "-C-c C-c".
+ (unless (string-search " " key)
+ (setq pre (string-replace " " "" pre))
+ (setq suf (string-replace " " "" suf)))
+ (concat (propertize pre 'face 'transient-unreachable-key)
+ (and (string-prefix-p (concat pre " ") key) " ")
+ (transient--colorize-key suf cmd)
+ (save-excursion
+ (and (string-match " +\\'" key)
+ (propertize (match-string 0 key)
+ 'face 'fixed-pitch))))))
+ ((transient--lookup-key transient-sticky-map (kbd key))
+ (transient--colorize-key key cmd))
+ (t
+ (propertize key 'face 'transient-unreachable-key))))
+ (transient--colorize-key key cmd))))
+
+(defun transient--colorize-key (key command)
+ (propertize key 'face
+ (or (and (transient--semantic-coloring-p)
+ (transient--suffix-color command))
+ 'transient-key)))
+
+(cl-defmethod transient-format-key :around ((obj transient-argument))
+ (let ((key (cl-call-next-method obj)))
+ (cond ((not transient-highlight-mismatched-keys))
+ ((not (slot-boundp obj 'shortarg))
+ (add-face-text-property
+ 0 (length key) 'transient-nonstandard-key nil key))
+ ((not (string-equal key (oref obj shortarg)))
+ (add-face-text-property
+ 0 (length key) 'transient-mismatched-key nil key)))
+ key))
+
+(cl-defgeneric transient-format-description (obj)
+ "Format OBJ's `description' for display and return the result.")
+
+(cl-defmethod transient-format-description ((obj transient-child))
+ "The `description' slot may be a function, in which case that is
+called inside the correct buffer (see `transient-insert-group')
+and its value is returned to the caller."
+ (and-let* ((desc (oref obj description)))
+ (if (functionp desc)
+ (with-current-buffer transient--original-buffer
+ (funcall desc))
+ desc)))
+
+(cl-defmethod transient-format-description ((obj transient-group))
+ "Format the description by calling the next method. If the result
+doesn't use the `face' property at all, then apply the face
+`transient-heading' to the complete string."
+ (and-let* ((desc (cl-call-next-method obj)))
+ (if (text-property-not-all 0 (length desc) 'face nil desc)
+ desc
+ (propertize desc 'face 'transient-heading))))
+
+(cl-defmethod transient-format-description :around ((obj transient-suffix))
+ "Format the description by calling the next method. If the result
+is nil, then use \"(BUG: no description)\" as the description.
+If the OBJ's `key' is currently unreachable, then apply the face
+`transient-unreachable' to the complete string."
+ (let ((desc (or (cl-call-next-method obj)
+ (and (slot-boundp transient--prefix 'suffix-description)
+ (funcall (oref transient--prefix suffix-description)
+ obj))
+ (propertize "(BUG: no description)" 'face 'error))))
+ (cond ((transient--key-unreachable-p obj)
+ (propertize desc 'face 'transient-unreachable))
+ ((and transient-highlight-higher-levels
+ (> (max (oref obj level) transient--max-group-level)
+ transient--default-prefix-level))
+ (add-face-text-property
+ 0 (length desc) 'transient-higher-level nil desc)
+ desc)
+ (t
+ desc))))
+
+(cl-defgeneric transient-format-value (obj)
+ "Format OBJ's value for display and return the result.")
+
+(cl-defmethod transient-format-value ((obj transient-suffix))
+ (propertize (oref obj argument)
+ 'face (if (oref obj value)
+ 'transient-argument
+ 'transient-inactive-argument)))
+
+(cl-defmethod transient-format-value ((obj transient-option))
+ (let ((argument (oref obj argument)))
+ (if-let ((value (oref obj value)))
+ (propertize
+ (cl-ecase (oref obj multi-value)
+ ((nil) (concat argument value))
+ ((t rest) (concat argument
+ (and (not (string-suffix-p " " argument)) " ")
+ (mapconcat #'prin1-to-string value " ")))
+ (repeat (mapconcat (lambda (v) (concat argument v)) value " ")))
+ 'face 'transient-value)
+ (propertize argument 'face 'transient-inactive-value))))
+
+(cl-defmethod transient-format-value ((obj transient-switches))
+ (with-slots (value argument-format choices) obj
+ (format (propertize argument-format
+ 'face (if value
+ 'transient-value
+ 'transient-inactive-value))
+ (concat
+ (propertize "[" 'face 'transient-inactive-value)
+ (mapconcat
+ (lambda (choice)
+ (propertize choice 'face
+ (if (equal (format argument-format choice) value)
+ 'transient-value
+ 'transient-inactive-value)))
+ choices
+ (propertize "|" 'face 'transient-inactive-value))
+ (propertize "]" 'face 'transient-inactive-value)))))
+
+(defun transient--key-unreachable-p (obj)
+ (and transient--redisplay-key
+ (let ((key (oref obj key)))
+ (not (or (equal (seq-take (cl-coerce (edmacro-parse-keys key t) 'list)
+ (length transient--redisplay-key))
+ transient--redisplay-key)
+ (transient--lookup-key transient-sticky-map (kbd key)))))))
+
+(defun transient--lookup-key (keymap key)
+ (let ((val (lookup-key keymap key)))
+ (and val (not (integerp val)) val)))
+
+(defun transient--maybe-pad-keys (group &optional parent)
+ (when-let ((pad (if (slot-boundp group 'pad-keys)
+ (oref group pad-keys)
+ (and parent
+ (slot-boundp parent 'pad-keys)
+ (oref parent pad-keys)))))
+ (let ((width (apply #'max
+ (cons (if (integerp pad) pad 0)
+ (mapcar (lambda (suffix)
+ (length (oref suffix key)))
+ (oref group suffixes))))))
+ (dolist (suffix (oref group suffixes))
+ (oset suffix key
+ (truncate-string-to-width (oref suffix key) width nil ?\s))))))
+
+(defun transient-command-summary-or-name (obj)
+ "Return the summary or name of the command represented by OBJ.
+
+If the command has a doc-string, then return the first line of
+that, else its name.
+
+Intended to be temporarily used as the `:suffix-description' of
+a prefix command, while porting a regular keymap to a transient."
+ (let ((command (transient--suffix-symbol (oref obj command))))
+ (if-let ((doc (documentation command)))
+ (propertize (car (split-string doc "\n")) 'face 'font-lock-doc-face)
+ (propertize (symbol-name command) 'face 'font-lock-function-name-face))))
+
+;;; Help
+
+(cl-defgeneric transient-show-help (obj)
+ "Show documentation for the command represented by OBJ.")
+
+(cl-defmethod transient-show-help ((obj transient-prefix))
+ "Call `show-help' if non-nil, else show `info-manual',
+if non-nil, else show the `man-page' if non-nil, else use
+`describe-function'."
+ (with-slots (show-help info-manual man-page command) obj
+ (cond (show-help (funcall show-help obj))
+ (info-manual (transient--show-manual info-manual))
+ (man-page (transient--show-manpage man-page))
+ (t (transient--describe-function command)))))
+
+(cl-defmethod transient-show-help ((obj transient-suffix))
+ "Call `show-help' if non-nil, else use `describe-function'.
+Also used to dispatch showing documentation for the current
+prefix. If the suffix is a sub-prefix, then also call the
+prefix method."
+ (cond
+ ((eq this-command 'transient-help)
+ (transient-show-help transient--prefix))
+ ((let ((prefix (get (transient--suffix-command obj)
+ 'transient--prefix)))
+ (and prefix (not (eq (oref transient--prefix command) this-command))
+ (prog1 t (transient-show-help prefix)))))
+ (t (if-let ((show-help (oref obj show-help)))
+ (funcall show-help obj)
+ (transient--describe-function this-command)))))
+
+(cl-defmethod transient-show-help ((obj transient-infix))
+ "Call `show-help' if non-nil, else show the `man-page'
+if non-nil, else use `describe-function'. When showing the
+manpage, then try to jump to the correct location."
+ (if-let ((show-help (oref obj show-help)))
+ (funcall show-help obj)
+ (if-let ((man-page (oref transient--prefix man-page))
+ (argument (and (slot-boundp obj 'argument)
+ (oref obj argument))))
+ (transient--show-manpage man-page argument)
+ (transient--describe-function this-command))))
+
+;; `cl-generic-generalizers' doesn't support `command' et al.
+(cl-defmethod transient-show-help (cmd)
+ "Show the command doc-string."
+ (transient--describe-function cmd))
+
+(defun transient--describe-function (fn)
+ (describe-function (if (symbolp fn) fn 'transient--anonymous-infix-argument))
+ (select-window (get-buffer-window (help-buffer))))
+
+(defun transient--anonymous-infix-argument ()
+ "Cannot show any documentation for this anonymous infix command.
+
+The infix command in question was defined anonymously, i.e.,
+it was define when the prefix command that it belongs to was
+defined, which means that it gets no docstring and also that
+no symbol is bound to it.
+
+When you request help for an infix command, then we usually
+show the respective man-page and jump to the location where
+the respective argument is being described.
+
+Because the containing prefix command does not specify any
+man-page, we cannot do that in this case. Sorry about that.")
+
+(defun transient--show-manual (manual)
+ (info manual))
+
+(defun transient--show-manpage (manpage &optional argument)
+ (require 'man)
+ (let* ((Man-notify-method 'meek)
+ (buf (Man-getpage-in-background manpage))
+ (proc (get-buffer-process buf)))
+ (while (and proc (eq (process-status proc) 'run))
+ (accept-process-output proc))
+ (switch-to-buffer buf)
+ (when argument
+ (transient--goto-argument-description argument))))
+
+(defun transient--goto-argument-description (arg)
+ (goto-char (point-min))
+ (let ((case-fold-search nil)
+ ;; This matches preceding/proceeding options. Options
+ ;; such as "-a", "-S[<keyid>]", and "--grep=<pattern>"
+ ;; are matched by this regex without the shy group.
+ ;; The ". " in the shy group is for options such as
+ ;; "-m parent-number", and the "-[^[:space:]]+ " is
+ ;; for options such as "--mainline parent-number"
+ (others "-\\(?:. \\|-[^[:space:]]+ \\)?[^[:space:]]+"))
+ (when (re-search-forward
+ (if (equal arg "--")
+ ;; Special case.
+ "^[\t\s]+\\(--\\(?: \\|$\\)\\|\\[--\\]\\)"
+ ;; Should start with whitespace and may have
+ ;; any number of options before and/or after.
+ (format
+ "^[\t\s]+\\(?:%s, \\)*?\\(?1:%s\\)%s\\(?:, %s\\)*$"
+ others
+ ;; Options don't necessarily end in an "="
+ ;; (e.g., "--gpg-sign[=<keyid>]")
+ (string-remove-suffix "=" arg)
+ ;; Simple options don't end in an "=". Splitting this
+ ;; into 2 cases should make getting false positives
+ ;; less likely.
+ (if (string-suffix-p "=" arg)
+ ;; "[^[:space:]]*[^.[:space:]]" matches the option
+ ;; value, which is usually after the option name
+ ;; and either '=' or '[='. The value can't end in
+ ;; a period, as that means it's being used at the
+ ;; end of a sentence. The space is for options
+ ;; such as '--mainline parent-number'.
+ "\\(?: \\|\\[?=\\)[^[:space:]]*[^.[:space:]]"
+ ;; Either this doesn't match anything (e.g., "-a"),
+ ;; or the option is followed by a value delimited
+ ;; by a "[", "<", or ":". A space might appear
+ ;; before this value, as in "-f <file>". The
+ ;; space alternative is for options such as
+ ;; "-m parent-number".
+ "\\(?:\\(?: \\| ?[\\[<:]\\)[^[:space:]]*[^.[:space:]]\\)?")
+ others))
+ nil t)
+ (goto-char (match-beginning 1)))))
+
+(defun transient--insert-help ()
+ (unless (looking-back "\n\n" 2)
+ (insert "\n"))
+ (when transient--helpp
+ (insert
+ (format (propertize "\
+Type a %s to show help for that suffix command, or %s to show manual.
+Type %s to exit help.\n"
+ 'face 'transient-heading)
+ (propertize "<KEY>" 'face 'transient-key)
+ (propertize "?" 'face 'transient-key)
+ (propertize "C-g" 'face 'transient-key))))
+ (when transient--editp
+ (unless transient--helpp
+ (insert
+ (format (propertize "\
+Type a %s to set level for that suffix command.
+Type %s to set what levels are available for this prefix command.\n"
+ 'face 'transient-heading)
+ (propertize "<KEY>" 'face 'transient-key)
+ (propertize "C-x l" 'face 'transient-key))))
+ (with-slots (level) transient--prefix
+ (insert
+ (format (propertize "
+Suffixes on levels %s are available.
+Suffixes on levels %s and %s are unavailable.\n"
+ 'face 'transient-heading)
+ (propertize (format "1-%s" level)
+ 'face 'transient-enabled-suffix)
+ (propertize " 0 "
+ 'face 'transient-disabled-suffix)
+ (propertize (format ">=%s" (1+ level))
+ 'face 'transient-disabled-suffix))))))
+
+(defvar transient-resume-mode-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map [remap Man-quit] #'transient-resume)
+ (define-key map [remap Info-exit] #'transient-resume)
+ (define-key map [remap quit-window] #'transient-resume)
+ map)
+ "Keymap for `transient-resume-mode'.
+
+This keymap remaps every command that would usually just quit the
+documentation buffer to `transient-resume', which additionally
+resumes the suspended transient.")
+
+(define-minor-mode transient-resume-mode
+ "Auxiliary minor-mode used to resume a transient after viewing help.")
+
+(defun transient-toggle-debug ()
+ "Toggle debugging statements for transient commands."
+ (interactive)
+ (setq transient--debug (not transient--debug))
+ (message "Debugging transient %s"
+ (if transient--debug "enabled" "disabled")))
+
+;;; Popup Navigation
+
+(defun transient-popup-navigation-help ()
+ "Inform the user how to enable popup navigation commands."
+ (interactive)
+ (message "This command is only available if `%s' is non-nil"
+ 'transient-enable-popup-navigation))
+
+(define-button-type 'transient-button
+ 'face nil
+ 'keymap transient-button-map)
+
+(defun transient-backward-button (n)
+ "Move to the previous button in the transient popup buffer.
+See `backward-button' for information about N."
+ (interactive "p")
+ (with-selected-window transient--window
+ (backward-button n t)))
+
+(defun transient-forward-button (n)
+ "Move to the next button in the transient popup buffer.
+See `forward-button' for information about N."
+ (interactive "p")
+ (with-selected-window transient--window
+ (forward-button n t)))
+
+(defun transient--goto-button (command)
+ (cond
+ ((stringp command)
+ (when (re-search-forward (concat "^" (regexp-quote command)) nil t)
+ (goto-char (match-beginning 0))))
+ (command
+ (while (and (ignore-errors (forward-button 1))
+ (not (eq (button-get (button-at (point)) 'command) command))))
+ (unless (eq (button-get (button-at (point)) 'command) command)
+ (goto-char (point-min))
+ (forward-button 1)))))
+
+(defun transient--heading-at-point ()
+ (and (eq (get-text-property (point) 'face) 'transient-heading)
+ (let ((beg (line-beginning-position)))
+ (buffer-substring-no-properties
+ beg (next-single-property-change
+ beg 'face nil (line-end-position))))))
+
+;;; Compatibility
+;;;; Popup Isearch
+
+(defvar transient--isearch-mode-map
+ (let ((map (make-sparse-keymap)))
+ (set-keymap-parent map isearch-mode-map)
+ (define-key map [remap isearch-exit] #'transient-isearch-exit)
+ (define-key map [remap isearch-cancel] #'transient-isearch-cancel)
+ (define-key map [remap isearch-abort] #'transient-isearch-abort)
+ map))
+
+(defun transient-isearch-backward (&optional regexp-p)
+ "Do incremental search backward.
+With a prefix argument, do an incremental regular expression
+search instead."
+ (interactive "P")
+ (transient--isearch-setup)
+ (let ((isearch-mode-map transient--isearch-mode-map))
+ (isearch-mode nil regexp-p)))
+
+(defun transient-isearch-forward (&optional regexp-p)
+ "Do incremental search forward.
+With a prefix argument, do an incremental regular expression
+search instead."
+ (interactive "P")
+ (transient--isearch-setup)
+ (let ((isearch-mode-map transient--isearch-mode-map))
+ (isearch-mode t regexp-p)))
+
+(defun transient-isearch-exit ()
+ "Like `isearch-exit' but adapted for `transient'."
+ (interactive)
+ (isearch-exit)
+ (transient--isearch-exit))
+
+(defun transient-isearch-cancel ()
+ "Like `isearch-cancel' but adapted for `transient'."
+ (interactive)
+ (condition-case nil (isearch-cancel) (quit))
+ (transient--isearch-exit))
+
+(defun transient-isearch-abort ()
+ "Like `isearch-abort' but adapted for `transient'."
+ (interactive)
+ (condition-case nil (isearch-abort) (quit))
+ (transient--isearch-exit))
+
+(defun transient--isearch-setup ()
+ (select-window transient--window)
+ (transient--suspend-override t))
+
+(defun transient--isearch-exit ()
+ (select-window transient--original-window)
+ (transient--resume-override))
+
+;;;; Hydra Color Emulation
+
+(defun transient--semantic-coloring-p ()
+ (and transient-semantic-coloring
+ (not transient--helpp)
+ (not transient--editp)))
+
+(defun transient--suffix-color (command)
+ (or (get command 'transient-color)
+ (get (transient--get-predicate-for command) 'transient-color)))
+
+(defun transient--prefix-color (command)
+ (let* ((nonsuf (or (oref command transient-non-suffix)
+ 'transient--do-warn))
+ (nonsuf (if (memq nonsuf '(transient--do-noop transient--do-warn))
+ 'disallow
+ (get nonsuf 'transient-color)))
+ (suffix (if-let ((pred (oref command transient-suffix)))
+ (get pred 'transient-color)
+ (if (eq nonsuf 'transient-red)
+ 'transient-red
+ 'transient-blue))))
+ (pcase (list suffix nonsuf)
+ (`(transient-purple ,_) 'transient-purple)
+ ('(transient-red disallow) 'transient-amaranth)
+ ('(transient-blue disallow) 'transient-teal)
+ ('(transient-red transient-red) 'transient-pink)
+ ('(transient-red transient-blue) 'transient-red)
+ ('(transient-blue transient-blue) 'transient-blue))))
+
+;;;; Edebug
+
+(defun transient--edebug--recursive-edit (fn arg-mode)
+ (transient--debug 'edebug--recursive-edit)
+ (if (not transient--prefix)
+ (funcall fn arg-mode)
+ (transient--suspend-override t)
+ (funcall fn arg-mode)
+ (transient--resume-override)))
+
+(advice-add 'edebug--recursive-edit :around #'transient--edebug--recursive-edit)
+
+(defun transient--abort-edebug ()
+ (when (bound-and-true-p edebug-active)
+ (transient--emergency-exit)))
+
+(advice-add 'abort-recursive-edit :before #'transient--abort-edebug)
+(advice-add 'top-level :before #'transient--abort-edebug)
+
+(defun transient--edebug-command-p ()
+ (and (bound-and-true-p edebug-active)
+ (or (memq this-command '(top-level abort-recursive-edit))
+ (string-prefix-p "edebug" (symbol-name this-command)))))
+
+;;;; Miscellaneous
+
+(cl-pushnew (list nil (concat "^\\s-*("
+ (eval-when-compile
+ (regexp-opt
+ '("transient-define-prefix"
+ "transient-define-suffix"
+ "transient-define-infix"
+ "transient-define-argument")
+ t))
+ "\\s-+\\(" lisp-mode-symbol-regexp "\\)")
+ 2)
+ lisp-imenu-generic-expression :test #'equal)
+
+(declare-function which-key-mode "which-key" (&optional arg))
+
+(defun transient--suspend-which-key-mode ()
+ (when (bound-and-true-p which-key-mode)
+ (which-key-mode -1)
+ (add-hook 'transient-exit-hook #'transient--resume-which-key-mode)))
+
+(defun transient--resume-which-key-mode ()
+ (unless transient--prefix
+ (which-key-mode 1)
+ (remove-hook 'transient-exit-hook #'transient--resume-which-key-mode)))
+
+(defun transient-bind-q-to-quit ()
+ "Modify some keymaps to bind \"q\" to the appropriate quit command.
+
+\"C-g\" is the default binding for such commands now, but Transient's
+predecessor Magit-Popup used \"q\" instead. If you would like to get
+that binding back, then call this function in your init file like so:
+
+ (with-eval-after-load \\='transient
+ (transient-bind-q-to-quit))
+
+Individual transients may already bind \"q\" to something else
+and such a binding would shadow the quit binding. If that is the
+case then \"Q\" is bound to whatever \"q\" would have been bound
+to by setting `transient-substitute-key-function' to a function
+that does that. Of course \"Q\" may already be bound to something
+else, so that function binds \"M-q\" to that command instead.
+Of course \"M-q\" may already be bound to something else, but
+we stop there."
+ (define-key transient-base-map "q" #'transient-quit-one)
+ (define-key transient-sticky-map "q" #'transient-quit-seq)
+ (setq transient-substitute-key-function
+ #'transient-rebind-quit-commands))
+
+(defun transient-rebind-quit-commands (obj)
+ "See `transient-bind-q-to-quit'."
+ (let ((key (oref obj key)))
+ (cond ((string-equal key "q") "Q")
+ ((string-equal key "Q") "M-q")
+ (t key))))
+
+(defun transient--force-fixed-pitch ()
+ (require 'face-remap)
+ (face-remap-reset-base 'default)
+ (face-remap-add-relative 'default 'fixed-pitch))
+
+;;;; Missing from Emacs
+
+(defun transient--seq-reductions-from (function sequence initial-value)
+ (let ((acc (list initial-value)))
+ (seq-doseq (elt sequence)
+ (push (funcall function (car acc) elt) acc))
+ (nreverse acc)))
+
+(defun transient-plist-to-alist (plist)
+ (let (alist)
+ (while plist
+ (push (cons (let* ((symbol (pop plist))
+ (name (symbol-name symbol)))
+ (if (eq (aref name 0) ?:)
+ (intern (substring name 1))
+ symbol))
+ (pop plist))
+ alist))
+ (nreverse alist)))
+
+;;; Font-Lock
+
+(defconst transient-font-lock-keywords
+ (eval-when-compile
+ `((,(concat "("
+ (regexp-opt (list "transient-define-prefix"
+ "transient-define-infix"
+ "transient-define-argument"
+ "transient-define-suffix")
+ t)
+ "\\_>[ \t'(]*"
+ "\\(\\(?:\\sw\\|\\s_\\)+\\)?")
+ (1 'font-lock-keyword-face)
+ (2 'font-lock-function-name-face nil t)))))
+
+(font-lock-add-keywords 'emacs-lisp-mode transient-font-lock-keywords)
+
+;;; Auxiliary Classes
+;;;; `transient-lisp-variable'
+
+(defclass transient-lisp-variable (transient-variable)
+ ((reader :initform #'transient-lisp-variable--reader)
+ (always-read :initform t)
+ (set-value :initarg :set-value :initform #'set))
+ "[Experimental] Class used for Lisp variables.")
+
+(cl-defmethod transient-init-value ((obj transient-lisp-variable))
+ (oset obj value (symbol-value (oref obj variable))))
+
+(cl-defmethod transient-infix-set ((obj transient-lisp-variable) value)
+ (funcall (oref obj set-value)
+ (oref obj variable)
+ (oset obj value value)))
+
+(cl-defmethod transient-format-description ((obj transient-lisp-variable))
+ (or (cl-call-next-method obj)
+ (symbol-name (oref obj variable))))
+
+(cl-defmethod transient-format-value ((obj transient-lisp-variable))
+ (propertize (prin1-to-string (oref obj value))
+ 'face 'transient-value))
+
+(cl-defmethod transient-prompt ((obj transient-lisp-variable))
+ (format "Set %s: " (oref obj variable)))
+
+(defun transient-lisp-variable--reader (prompt initial-input _history)
+ (read--expression prompt initial-input))
+
+;;; _
+(provide 'transient)
+;; Local Variables:
+;; indent-tabs-mode: nil
+;; checkdoc-symbol-words: ("command-line" "edit-mode" "help-mode")
+;; End:
+;;; transient.el ends here
diff --git a/elpa/transient-20220503.1118/transient.elc b/elpa/transient-20220503.1118/transient.elc
new file mode 100644
index 0000000..9dba8a6
--- /dev/null
+++ b/elpa/transient-20220503.1118/transient.elc
Binary files differ
diff --git a/elpa/transient-20220503.1118/transient.info b/elpa/transient-20220503.1118/transient.info
new file mode 100644
index 0000000..0b4beef
--- /dev/null
+++ b/elpa/transient-20220503.1118/transient.info
@@ -0,0 +1,2648 @@
+This is transient.info, produced by makeinfo version 6.7 from
+transient.texi.
+
+ Copyright (C) 2018-2022 Jonas Bernoulli <jonas@bernoul.li>
+
+ You can redistribute this document 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 document 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.
+
+INFO-DIR-SECTION Emacs
+START-INFO-DIR-ENTRY
+* Transient: (transient). Transient Commands.
+END-INFO-DIR-ENTRY
+
+
+File: transient.info, Node: Top, Next: Introduction, Up: (dir)
+
+Transient User and Developer Manual
+***********************************
+
+Taking inspiration from prefix keys and prefix arguments, Transient
+implements a similar abstraction involving a prefix command, infix
+arguments and suffix commands. We could call this abstraction a
+"transient command", but because it always involves at least two
+commands (a prefix and a suffix) we prefer to call it just a
+"transient".
+
+ When the user calls a transient prefix command, a transient
+(temporary) keymap is activated, which binds the transient’s infix and
+suffix commands, and functions that control the transient state are
+added to ‘pre-command-hook’ and ‘post-command-hook’. The available
+suffix and infix commands and their state are shown in a popup buffer
+until the transient is exited by invoking a suffix command.
+
+ Calling an infix command causes its value to be changed, possibly by
+reading a new value in the minibuffer.
+
+ Calling a suffix command usually causes the transient to be exited
+but suffix commands can also be configured to not exit the transient.
+
+This manual is for Transient version 0.3.7-git.
+
+ Copyright (C) 2018-2022 Jonas Bernoulli <jonas@bernoul.li>
+
+ You can redistribute this document 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 document 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.
+
+* Menu:
+
+* Introduction::
+* Usage::
+* Modifying Existing Transients::
+* Defining New Commands::
+* Classes and Methods::
+* Related Abstractions and Packages::
+* FAQ::
+* Keystroke Index::
+* Command and Function Index::
+* Variable Index::
+* Concept Index::
+
+— The Detailed Node Listing —
+
+Usage
+
+* Invoking Transients::
+* Aborting and Resuming Transients::
+* Common Suffix Commands::
+* Saving Values::
+* Using History::
+* Getting Help for Suffix Commands::
+* Enabling and Disabling Suffixes::
+* Other Commands::
+* Configuration::
+
+Defining New Commands
+
+* Defining Transients::
+* Binding Suffix and Infix Commands::
+* Defining Suffix and Infix Commands::
+* Using Infix Arguments::
+* Transient State::
+
+Binding Suffix and Infix Commands
+
+* Group Specifications::
+* Suffix Specifications::
+
+
+Classes and Methods
+
+* Group Classes::
+* Group Methods::
+* Prefix Classes::
+* Suffix Classes::
+* Suffix Methods::
+* Prefix Slots::
+* Suffix Slots::
+* Predicate Slots::
+
+Suffix Methods
+
+* Suffix Value Methods::
+* Suffix Format Methods::
+
+
+Related Abstractions and Packages
+
+* Comparison With Prefix Keys and Prefix Arguments::
+* Comparison With Other Packages::
+
+
+
+File: transient.info, Node: Introduction, Next: Usage, Prev: Top, Up: Top
+
+1 Introduction
+**************
+
+Taking inspiration from prefix keys and prefix arguments, Transient
+implements a similar abstraction involving a prefix command, infix
+arguments and suffix commands. We could call this abstraction a
+"transient command", but because it always involves at least two
+commands (a prefix and a suffix) we prefer to call it just a
+"transient".
+
+ Transient keymaps are a feature provided by Emacs. Transients as
+ implemented by this package involve the use of transient keymaps.
+
+ Emacs provides a feature that it calls "prefix commands". When we
+ talk about "prefix commands" in this manual, then we mean our own
+ kind of "prefix commands", unless specified otherwise. To avoid
+ ambiguity we sometimes use the terms "transient prefix command" for
+ our kind and "regular prefix command" for Emacs’ kind.
+
+ When the user calls a transient prefix command, a transient
+(temporary) keymap is activated, which binds the transient’s infix and
+suffix commands, and functions that control the transient state are
+added to ‘pre-command-hook’ and ‘post-command-hook’. The available
+suffix and infix commands and their state are shown in a popup buffer
+until the transient state is exited by invoking a suffix command.
+
+ Calling an infix command causes its value to be changed. How that is
+done depends on the type of the infix command. The simplest case is an
+infix command that represents a command-line argument that does not take
+a value. Invoking such an infix command causes the switch to be toggled
+on or off. More complex infix commands may read a value from the user,
+using the minibuffer.
+
+ Calling a suffix command usually causes the transient to be exited;
+the transient keymaps and hook functions are removed, the popup buffer
+no longer shows information about the (no longer bound) suffix commands,
+the values of some public global variables are set, while some internal
+global variables are unset, and finally the command is actually called.
+Suffix commands can also be configured to not exit the transient.
+
+ A suffix command can, but does not have to, use the infix arguments
+in much the same way any command can choose to use or ignore the prefix
+arguments. For a suffix command that was invoked from a transient, the
+variable ‘transient-current-suffixes’ and the function ‘transient-args’
+serve about the same purpose as the variables ‘prefix-arg’ and
+‘current-prefix-arg’ do for any command that was called after the prefix
+arguments have been set using a command such as ‘universal-argument’.
+
+ The information shown in the popup buffer while a transient is active
+looks a bit like this:
+
+ ,-----------------------------------------
+ |Arguments
+ | -f Force (--force)
+ | -a Annotate (--annotate)
+ |
+ |Create
+ | t tag
+ | r release
+ `-----------------------------------------
+
+ This is a simplified version of ‘magit-tag’. Info manuals do not
+ support images or colored text, so the above "screenshot" lacks
+ some information; in practice you would be able to tell whether the
+ arguments ‘--force’ and ‘--annotate’ are enabled or not based on
+ their color.
+
+ Transient can be used to implement simple "command dispatchers". The
+main benefit then is that the user can see all the available commands in
+a popup buffer. That is useful by itself because it frees the user from
+having to remember all the keys that are valid after a certain prefix
+key or command. Magit’s ‘magit-dispatch’ (on ‘C-x M-g’) command is an
+example of using Transient to merely implement a command dispatcher.
+
+ In addition to that, Transient also allows users to interactively
+pass arguments to commands. These arguments can be much more complex
+than what is reasonable when using prefix arguments. There is a limit
+to how many aspects of a command can be controlled using prefix
+arguments. Furthermore, what a certain prefix argument means for
+different commands can be completely different, and users have to read
+documentation to learn and then commit to memory what a certain prefix
+argument means to a certain command.
+
+ Transient suffix commands, on the other hand, can accept dozens of
+different arguments without the user having to remember anything. When
+using Transient, one can call a command with arguments that are just as
+complex as when calling the same function non-interactively from Lisp.
+
+ Invoking a transient command with arguments is similar to invoking a
+command in a shell with command-line completion and history enabled.
+One benefit of the Transient interface is that it remembers history not
+only on a global level ("this command was invoked using these arguments,
+and previously it was invoked using those other arguments"), but also
+remembers the values of individual arguments independently. See *note
+Using History::.
+
+ After a transient prefix command is invoked, ‘C-h <key>’ can be used
+to show the documentation for the infix or suffix command that ‘<key>’
+is bound to (see *note Getting Help for Suffix Commands::) and infixes
+and suffixes can be removed from the transient using ‘C-x l <key>’.
+Infixes and suffixes that are disabled by default can be enabled the
+same way. See *note Enabling and Disabling Suffixes::.
+
+ Transient ships with support for a few different types of specialized
+infix commands. A command that sets a command line option, for example,
+has different needs than a command that merely toggles a boolean flag.
+Additionally, Transient provides abstractions for defining new types,
+which the author of Transient did not anticipate (or didn’t get around
+to implementing yet).
+
+
+File: transient.info, Node: Usage, Next: Modifying Existing Transients, Prev: Introduction, Up: Top
+
+2 Usage
+*******
+
+* Menu:
+
+* Invoking Transients::
+* Aborting and Resuming Transients::
+* Common Suffix Commands::
+* Saving Values::
+* Using History::
+* Getting Help for Suffix Commands::
+* Enabling and Disabling Suffixes::
+* Other Commands::
+* Configuration::
+
+
+File: transient.info, Node: Invoking Transients, Next: Aborting and Resuming Transients, Up: Usage
+
+2.1 Invoking Transients
+=======================
+
+A transient prefix command is invoked like any other command by pressing
+the key that is bound to that command. The main difference to other
+commands is that a transient prefix command activates a transient
+keymap, which temporarily binds the transient’s infix and suffix
+commands. Bindings from other keymaps may, or may not, be disabled
+while the transient state is in effect.
+
+ There are two kinds of commands that are available after invoking a
+transient prefix command; infix and suffix commands. Infix commands set
+some value (which is then shown in a popup buffer), without leaving the
+transient. Suffix commands, on the other hand, usually quit the
+transient and they may use the values set by the infix commands, i.e.,
+the infix *arguments*.
+
+ Instead of setting arguments to be used by a suffix command, infix
+commands may also set some value by side-effect, e.g., by setting the
+value of some variable.
+
+
+File: transient.info, Node: Aborting and Resuming Transients, Next: Common Suffix Commands, Prev: Invoking Transients, Up: Usage
+
+2.2 Aborting and Resuming Transients
+====================================
+
+To quit the transient without invoking a suffix command press ‘C-g’.
+
+ Key bindings in transient keymaps may be longer than a single event.
+After pressing a valid prefix key, all commands whose bindings do not
+begin with that prefix key are temporarily unavailable and grayed out.
+To abort the prefix key press ‘C-g’ (which in this case only quits the
+prefix key, but not the complete transient).
+
+ A transient prefix command can be bound as a suffix of another
+transient. Invoking such a suffix replaces the current transient state
+with a new transient state, i.e., the available bindings change and the
+information displayed in the popup buffer is updated accordingly.
+Pressing ‘C-g’ while a nested transient is active only quits the
+innermost transient, causing a return to the previous transient.
+
+ ‘C-q’ or ‘C-z’ on the other hand always exits all transients. If you
+use the latter, then you can later resume the stack of transients using
+‘M-x transient-resume’.
+
+‘C-g’ (‘transient-quit-seq’)
+‘C-g’ (‘transient-quit-one’)
+ This key quits the currently active incomplete key sequence, if
+ any, or else the current transient. When quitting the current
+ transient, it returns to the previous transient, if any.
+
+ Transient’s predecessor bound ‘q’ instead of ‘C-g’ to the quit
+command. To learn how to get that binding back see
+‘transient-bind-q-to-quit’’s doc string.
+
+‘C-q’ (‘transient-quit-all’)
+ This command quits the currently active incomplete key sequence, if
+ any, and all transients, including the active transient and all
+ suspended transients, if any.
+
+‘C-z’ (‘transient-suspend’)
+ Like ‘transient-quit-all’, this command quits an incomplete key
+ sequence, if any, and all transients. Additionally, it saves the
+ stack of transients so that it can easily be resumed (which is
+ particularly useful if you quickly need to do "something else" and
+ the stack is deeper than a single transient, and/or you have
+ already changed the values of some infix arguments).
+
+ Note that only a single stack of transients can be saved at a time.
+ If another stack is already saved, then saving a new stack discards
+ the previous stack.
+
+‘M-x transient-resume’
+ This command resumes the previously suspended stack of transients,
+ if any.
+
+
+File: transient.info, Node: Common Suffix Commands, Next: Saving Values, Prev: Aborting and Resuming Transients, Up: Usage
+
+2.3 Common Suffix Commands
+==========================
+
+A few shared suffix commands are available in all transients. These
+suffix commands are not shown in the popup buffer by default.
+
+ This includes the aborting commands mentioned in the previous
+section, as well as some other commands that are all bound to ‘C-x
+<key>’. After ‘C-x’ is pressed, a section featuring all these common
+commands is temporarily shown in the popup buffer. After invoking one
+of them, the section disappears again. Note however that one of these
+commands is described as "Show common permanently"; invoke that if you
+want the common commands to always be shown for all transients.
+
+‘C-x t’ (‘transient-toggle-common’)
+ This command toggles whether the generic commands that are common
+ to all transients are always displayed or only after typing the
+ incomplete prefix key sequence ‘C-x’. This only affects the
+ current Emacs session.
+
+ -- User Option: transient-show-common-commands
+ This option controls whether shared suffix commands are shown
+ alongside the transient-specific infix and suffix commands. By
+ default, the shared commands are not shown to avoid overwhelming
+ the user with to. many options.
+
+ While a transient is active, pressing ‘C-x’ always shows the common
+ commands. The value of this option can be changed for the current
+ Emacs session by typing ‘C-x t’ while a transient is active.
+
+ The other common commands are described in either the previous or in
+one of the following sections.
+
+ Some of Transient’s key bindings differ from the respective bindings
+of Magit-Popup; see *note FAQ:: for more information.
+
+
+File: transient.info, Node: Saving Values, Next: Using History, Prev: Common Suffix Commands, Up: Usage
+
+2.4 Saving Values
+=================
+
+After setting the infix arguments in a transient, the user can save
+those arguments for future invocations.
+
+ Most transients will start out with the saved arguments when they are
+invoked. There are a few exceptions, though. Some transients are
+designed so that the value that they use is stored externally as the
+buffer-local value of some variable. Invoking such a transient again
+uses the buffer-local value. (1)
+
+ If the user does not save the value and just exits using a regular
+suffix command, then the value is merely saved to the transient’s
+history. That value won’t be used when the transient is next invoked,
+but it is easily accessible (see *note Using History::).
+
+‘C-x s’ (‘transient-set’)
+ This command saves the value of the active transient for this Emacs
+ session.
+
+‘C-x C-s’ (‘transient-save’)
+ Save the value of the active transient persistently across Emacs
+ sessions.
+
+‘C-x C-k’ (‘transient-save’)
+ Clear the set and saved value of the active transient.
+
+ -- User Option: transient-values-file
+ This option names the file that is used to persist the values of
+ transients between Emacs sessions.
+
+ ---------- Footnotes ----------
+
+ (1) ‘magit-diff’ and ‘magit-log’ are two prominent examples, and
+their handling of buffer-local values is actually a bit more complicated
+than outlined above and even customizable.
+
+
+File: transient.info, Node: Using History, Next: Getting Help for Suffix Commands, Prev: Saving Values, Up: Usage
+
+2.5 Using History
+=================
+
+Every time the user invokes a suffix command the transient’s current
+value is saved to its history. These values can be cycled through the
+same way one can cycle through the history of commands that read
+user-input in the minibuffer.
+
+‘C-M-p’ (‘transient-history-prev’)
+‘C-x p’
+ This command switches to the previous value used for the active
+ transient.
+
+‘C-M-n’ (‘transient-history-next’)
+‘C-x n’
+ This command switches to the next value used for the active
+ transient.
+
+ In addition to the transient-wide history, Transient of course
+supports per-infix history. When an infix reads user-input using the
+minibuffer, the user can use the regular minibuffer history commands to
+cycle through previously used values. Usually the same keys as those
+mentioned above are bound to those commands.
+
+ Authors of transients should arrange for different infix commands
+that read the same kind of value to also use the same history key (see
+*note Suffix Slots::).
+
+ Both kinds of history are saved to a file when Emacs is exited.
+
+ -- User Option: transient-history-file
+ This option names the file that is used to persist the history of
+ transients and their infixes between Emacs sessions.
+
+ -- User Option: transient-history-limit
+ This option controls how many history elements are kept at the time
+ the history is saved in ‘transient-history-file’.
+
+
+File: transient.info, Node: Getting Help for Suffix Commands, Next: Enabling and Disabling Suffixes, Prev: Using History, Up: Usage
+
+2.6 Getting Help for Suffix Commands
+====================================
+
+Transients can have many suffixes and infixes that the user might not be
+familiar with. To make it trivial to get help for these, Transient
+provides access to the documentation directly from the active transient.
+
+‘C-h’ (‘transient-help’)
+ This command enters help mode. When help mode is active, typing a
+ key shows information about the suffix command that the key
+ normally is bound to (instead of invoking it). Pressing ‘C-h’ a
+ second time shows information about the _prefix_ command.
+
+ After typing a key, the stack of transient states is suspended and
+ information about the suffix command is shown instead. Typing ‘q’
+ in the help buffer buries that buffer and resumes the transient
+ state.
+
+ What sort of documentation is shown depends on how the transient was
+defined. For infix commands that represent command-line arguments this
+ideally shows the appropriate manpage. ‘transient-help’ then tries to
+jump to the correct location within that. Info manuals are also
+supported. The fallback is to show the command’s doc string, for
+non-infix suffixes this is usually appropriate.
+
+
+File: transient.info, Node: Enabling and Disabling Suffixes, Next: Other Commands, Prev: Getting Help for Suffix Commands, Up: Usage
+
+2.7 Enabling and Disabling Suffixes
+===================================
+
+The user base of a package that uses transients can be very diverse.
+This is certainly the case for Magit; some users have been using it and
+Git for a decade, while others are just getting started now.
+
+ For that reason a mechanism is needed that authors can use to
+classify a transient’s infixes and suffixes along the
+essentials...everything spectrum. We use the term "levels" to describe
+that mechanism.
+
+ Each suffix command is placed on a level and each transient has a
+level (called transient-level), which controls which suffix commands are
+available. Integers between 1 and 7 (inclusive) are valid levels. For
+suffixes, 0 is also valid; it means that the suffix is not displayed at
+any level.
+
+ The levels of individual transients and/or their individual suffixes
+can be changed interactively, by invoking the transient and then
+pressing ‘C-x l’ to enter the "edit" mode, see below.
+
+ The default level for both transients and their suffixes is 4. The
+‘transient-default-level’ option only controls the default for
+transients. The default suffix level is always 4. The authors of
+transients should place certain suffixes on a higher level, if they
+expect that it won’t be of use to most users, and they should place very
+important suffixes on a lower level, so that they remain available even
+if the user lowers the transient level.
+
+ -- User Option: transient-default-level
+ This option controls which suffix levels are made available by
+ default. It sets the transient-level for transients for which the
+ user has not set that individually.
+
+ -- User Option: transient-levels-file
+ This option names the file that is used to persist the levels of
+ transients and their suffixes between Emacs sessions.
+
+‘C-x l’ (‘transient-set-level’)
+ This command enters edit mode. When edit mode is active, then all
+ infixes and suffixes that are currently usable are displayed along
+ with their levels. The colors of the levels indicate whether they
+ are enabled or not. The level of the transient is also displayed
+ along with some usage information.
+
+ In edit mode, pressing the key that would usually invoke a certain
+ suffix instead prompts the user for the level that suffix should be
+ placed on.
+
+ Help mode is available in edit mode.
+
+ To change the transient level press ‘C-x l’ again.
+
+ To exit edit mode press ‘C-g’.
+
+ Note that edit mode does not display any suffixes that are not
+ currently usable. ‘magit-rebase’, for example, shows different
+ suffixes depending on whether a rebase is already in progress or
+ not. The predicates also apply in edit mode.
+
+ Therefore, to control which suffixes are available given a certain
+ state, you have to make sure that that state is currently active.
+
+
+File: transient.info, Node: Other Commands, Next: Configuration, Prev: Enabling and Disabling Suffixes, Up: Usage
+
+2.8 Other Commands
+==================
+
+When invoking a transient in a small frame, the transient window may not
+show the complete buffer, making it necessary to scroll, using the
+following commands. These commands are never shown in the transient
+window, and the key bindings are the same as for ‘scroll-up-command’ and
+‘scroll-down-command’ in other buffers.
+
+ -- Command: transient-scroll-up arg
+ This command scrolls text of transient popup window upward ARG
+ lines. If ARG is ‘nil’, then it scrolls near full screen. This is
+ a wrapper around ‘scroll-up-command’ (which see).
+
+ -- Command: transient-scroll-down arg
+ This command scrolls text of transient popup window down ARG lines.
+ If ARG is ‘nil’, then it scrolls near full screen. This is a
+ wrapper around ‘scroll-down-command’ (which see).
+
+
+File: transient.info, Node: Configuration, Prev: Other Commands, Up: Usage
+
+2.9 Configuration
+=================
+
+More options are described in *note Common Suffix Commands::, in *note
+Saving Values::, in *note Using History:: and in *note Enabling and
+Disabling Suffixes::.
+
+Essential Options
+-----------------
+
+Also see *note Common Suffix Commands::.
+
+ -- User Option: transient-show-popup
+ This option controls whether the current transient’s infix and
+ suffix commands are shown in the popup buffer.
+
+ • If ‘t’ (the default) then the popup buffer is shown as soon as
+ a transient prefix command is invoked.
+
+ • If ‘nil’, then the popup buffer is not shown unless the user
+ explicitly requests it, by pressing an incomplete prefix key
+ sequence.
+
+ • If a number, then the a brief one-line summary is shown
+ instead of the popup buffer. If zero or negative, then not
+ even that summary is shown; only the pressed key itself is
+ shown.
+
+ The popup is shown when the user explicitly requests it by
+ pressing an incomplete prefix key sequence. Unless this is
+ zero, the popup is shown after that many seconds of inactivity
+ (using the absolute value).
+
+ -- User Option: transient-enable-popup-navigation
+ This option controls whether navigation commands are enabled in the
+ transient popup buffer.
+
+ While a transient is active the transient popup buffer is not the
+ current buffer, making it necessary to use dedicated commands to
+ act on that buffer itself. This is disabled by default. If this
+ option is non-‘nil’, then the following features are available:
+
+ • ‘<up>’ moves the cursor to the previous suffix. ‘<down>’
+ moves the cursor to the next suffix. ‘RET’ invokes the suffix
+ the cursor is on.
+ • ‘<mouse-1>’ invokes the clicked on suffix.
+ • ‘C-s’ and ‘C-r’ start isearch in the popup buffer.
+
+ -- User Option: transient-display-buffer-action
+ This option specifies the action used to display the transient
+ popup buffer. The transient popup buffer is displayed in a window
+ using ‘(display-buffer BUFFER transient-display-buffer-action)’.
+
+ The value of this option has the form ‘(FUNCTION . ALIST)’, where
+ FUNCTION is a function or a list of functions. Each such function
+ should accept two arguments: a buffer to display and an alist of
+ the same form as ALIST. See *note (elisp)Choosing Window::, for
+ details.
+
+ The default is:
+
+ (display-buffer-in-side-window
+ (side . bottom)
+ (inhibit-same-window . t)
+ (window-parameters (no-other-window . t)))
+
+ This displays the window at the bottom of the selected frame.
+ Another useful FUNCTION is ‘display-buffer-below-selected’, which
+ is what ‘magit-popup’ used by default. For more alternatives see
+ *note (elisp)Display Action Functions:: and *note (elisp)Buffer
+ Display Action Alists::.
+
+ Note that the buffer that was current before the transient buffer
+ is shown should remain the current buffer. Many suffix commands
+ act on the thing at point, if appropriate, and if the transient
+ buffer became the current buffer, then that would change what is at
+ point. To that effect ‘inhibit-same-window’ ensures that the
+ selected window is not used to show the transient buffer.
+
+ It may be possible to display the window in another frame, but
+ whether that works in practice depends on the window-manager. If
+ the window manager selects the new window (Emacs frame), then that
+ unfortunately changes which buffer is current.
+
+ If you change the value of this option, then you might also want to
+ change the value of ‘transient-mode-line-format’.
+
+Accessibility Options
+---------------------
+
+ -- User Option: transient-force-single-column
+ This option controls whether the use of a single column to display
+ suffixes is enforced. This might be useful for users with low
+ vision who use large text and might otherwise have to scroll in two
+ dimensions.
+
+Auxiliary Options
+-----------------
+
+ -- User Option: transient-mode-line-format
+ This option controls whether the transient popup buffer has a
+ mode-line, separator line, or neither.
+
+ If ‘nil’, then the buffer has no mode-line. If the buffer is not
+ displayed right above the echo area, then this probably is not a
+ good value.
+
+ If ‘line’ (the default), then the buffer also has no mode-line, but
+ a thin line is drawn instead, using the background color of the
+ face ‘transient-separator’. Text-mode frames cannot display thin
+ lines, and therefore fall back to treating ‘line’ like ‘nil’.
+
+ Otherwise this can be any mode-line format. See *note (elisp)Mode
+ Line Format::, for details.
+
+ -- User Option: transient-semantic-coloring
+ This option controls whether prefixes and suffixes are colored in a
+ Hydra-like fashion.
+
+ If non-‘nil’, then the key binding of each suffix is colorized to
+ indicate whether it exits the transient state or not. The color of
+ the prefix is indicated using the line that is drawn when the value
+ of ‘transient-mode-line-format’ is ‘line’.
+
+ For more information about how Hydra uses colors see
+ <https://github.com/abo-abo/hydra#color> and
+ <https://oremacs.com/2015/02/19/hydra-colors-reloaded>.
+
+ -- User Option: transient-highlight-mismatched-keys
+ This option controls whether key bindings of infix commands that do
+ not match the respective command-line argument should be
+ highlighted. For other infix commands this option has no effect.
+
+ When this option is non-‘nil’, the key binding for an infix
+ argument is highlighted when only a long argument (e.g.,
+ ‘--verbose’) is specified but no shorthand (e.g ‘-v’). In the rare
+ case that a shorthand is specified but the key binding does not
+ match, then it is highlighted differently.
+
+ Highlighting mismatched key bindings is useful when learning the
+ arguments of the underlying command-line tool; you wouldn’t want to
+ learn any short-hands that do not actually exist.
+
+ The highlighting is done using one of the faces
+ ‘transient-mismatched-key’ and ‘transient-nonstandard-key’.
+
+ -- User Option: transient-substitute-key-function
+ This function is used to modify key bindings. If the value of this
+ option is nil (the default), then no substitution is performed.
+
+ This function is called with one argument, the prefix object, and
+ must return a key binding description, either the existing key
+ description it finds in the ‘key’ slot, or the key description that
+ replaces the prefix key. It could be used to make other
+ substitutions, but that is discouraged.
+
+ For example, ‘=’ is hard to reach using my custom keyboard layout,
+ so I substitute ‘(’ for that, which is easy to reach using a layout
+ optimized for lisp.
+
+ (setq transient-substitute-key-function
+ (lambda (obj)
+ (let ((key (oref obj key)))
+ (if (string-match "\\`\\(=\\)[a-zA-Z]" key)
+ (replace-match "(" t t key 1)
+ key))))
+
+ -- User Option: transient-read-with-initial-input
+ This option controls whether the last history element is used as
+ the initial minibuffer input when reading the value of an infix
+ argument from the user. If ‘nil’, there is no initial input and
+ the first element has to be accessed the same way as the older
+ elements.
+
+ -- User Option: transient-hide-during-minibuffer-read
+ This option controls whether the transient buffer is hidden while
+ user input is being read in the minibuffer.
+
+ -- User Option: transient-align-variable-pitch
+ This option controls whether columns are aligned pixel-wise in the
+ popup buffer.
+
+ If this is non-‘nil’, then columns are aligned pixel-wise to
+ support variable-pitch fonts. Keys are not aligned, so you should
+ use a fixed-pitch font for the ‘transient-key’ face. Other key
+ faces inherit from that face unless a theme is used that breaks
+ that relationship.
+
+ This option is intended for users who use a variable-pitch font for
+ the ‘default’ face.
+
+ -- User Option: transient-force-fixed-pitch
+ This option controls whether to force the use of a monospaced font
+ in popup buffer. Even if you use a proportional font for the
+ ‘default’ face, you might still want to use a monospaced font in
+ transient’s popup buffer. Setting this option to ‘t’ causes
+ ‘default’ to be remapped to ‘fixed-pitch’ in that buffer.
+
+Developer Options
+-----------------
+
+These options are mainly intended for developers.
+
+ -- User Option: transient-detect-key-conflicts
+ This option controls whether key binding conflicts should be
+ detected at the time the transient is invoked. If so, this results
+ in an error, which prevents the transient from being used. Because
+ of that, conflicts are ignored by default.
+
+ Conflicts cannot be determined earlier, i.e., when the transient is
+ being defined and when new suffixes are being added, because at
+ that time there can be false-positives. It is actually valid for
+ multiple suffixes to share a common key binding, provided the
+ predicates of those suffixes prevent that more than one of them is
+ enabled at a time.
+
+ -- User Option: transient-highlight-higher-levels
+ This option controls whether suffixes that would not be available
+ by default are highlighted.
+
+ When non-‘nil’ then the descriptions of suffixes are highlighted if
+ their level is above 4, the default of ‘transient-default-level’.
+ Assuming you have set that variable to 7, this highlights all
+ suffixes that won’t be available to users without them making the
+ same customization.
+
+
+File: transient.info, Node: Modifying Existing Transients, Next: Defining New Commands, Prev: Usage, Up: Top
+
+3 Modifying Existing Transients
+*******************************
+
+To an extent, transients can be customized interactively, see *note
+Enabling and Disabling Suffixes::. This section explains how existing
+transients can be further modified non-interactively.
+
+ The following functions share a few arguments:
+
+ • PREFIX is a transient prefix command, a symbol.
+
+ • SUFFIX is a transient infix or suffix specification in the same
+ form as expected by ‘transient-define-prefix’. Note that an infix
+ is a special kind of suffix. Depending on context "suffixes" means
+ "suffixes (including infixes)" or "non-infix suffixes". Here it
+ means the former. See *note Suffix Specifications::.
+
+ SUFFIX may also be a group in the same form as expected by
+ ‘transient-define-prefix’. See *note Group Specifications::.
+
+ • LOC is a command, a key vector, a key description (a string as
+ returned by ‘key-description’), or a list specifying coordinates
+ (the last element may also be a command or key). For example ‘(1 0
+ -1)’ identifies the last suffix (‘-1’) of the first subgroup (‘0’)
+ of the second group (‘1’).
+
+ If LOC is a list of coordinates, then it can be used to identify a
+ group, not just an individual suffix command.
+
+ The function ‘transient-get-suffix’ can be useful to determine
+ whether a certain coordination list identifies the suffix or group
+ that you expect it to identify. In hairy cases it may be necessary
+ to look at the definition of the transient prefix command.
+
+ These functions operate on the information stored in the
+‘transient--layout’ property of the PREFIX symbol. Suffix entries in
+that tree are not objects but have the form ‘(LEVEL CLASS PLIST)’, where
+plist should set at least ‘:key’, ‘:description’ and ‘:command’.
+
+ -- Function: transient-insert-suffix prefix loc suffix
+ This function inserts suffix or group SUFFIX into PREFIX before
+ LOC.
+
+ -- Function: transient-append-suffix prefix loc suffix
+ This function inserts suffix or group SUFFIX into PREFIX after LOC.
+
+ -- Function: transient-replace-suffix prefix loc suffix
+ This function replaces the suffix or group at LOC in PREFIX with
+ suffix or group SUFFIX.
+
+ -- Function: transient-remove-suffix prefix loc
+ This function removes the suffix or group at LOC in PREFIX.
+
+ -- Function: transient-get-suffix prefix loc
+ This function returns the suffix or group at LOC in PREFIX. The
+ returned value has the form mentioned above.
+
+ -- Function: transient-suffix-put prefix loc prop value
+ This function edits the suffix or group at LOC in PREFIX, by
+ setting the PROP of its plist to VALUE.
+
+ Most of these functions do not signal an error if they cannot perform
+the requested modification. The functions that insert new suffixes show
+a warning if LOC cannot be found in PREFIX, without signaling an error.
+The reason for doing it like this is that establishing a key binding
+(and that is what we essentially are trying to do here) should not
+prevent the rest of the configuration from loading. Among these
+functions only ‘transient-get-suffix’ and ‘transient-suffix-put’ may
+signal an error.
+
+
+File: transient.info, Node: Defining New Commands, Next: Classes and Methods, Prev: Modifying Existing Transients, Up: Top
+
+4 Defining New Commands
+***********************
+
+* Menu:
+
+* Defining Transients::
+* Binding Suffix and Infix Commands::
+* Defining Suffix and Infix Commands::
+* Using Infix Arguments::
+* Transient State::
+
+
+File: transient.info, Node: Defining Transients, Next: Binding Suffix and Infix Commands, Up: Defining New Commands
+
+4.1 Defining Transients
+=======================
+
+A transient consists of a prefix command and at least one suffix
+command, though usually a transient has several infix and suffix
+commands. The below macro defines the transient prefix command *and*
+binds the transient’s infix and suffix commands. In other words, it
+defines the complete transient, not just the transient prefix command
+that is used to invoke that transient.
+
+ -- Macro: transient-define-prefix name arglist [docstring] [keyword
+ value]... group... [body...]
+ This macro defines NAME as a transient prefix command and binds the
+ transient’s infix and suffix commands.
+
+ ARGLIST are the arguments that the prefix command takes. DOCSTRING
+ is the documentation string and is optional.
+
+ These arguments can optionally be followed by keyword-value pairs.
+ Each key has to be a keyword symbol, either ‘:class’ or a keyword
+ argument supported by the constructor of that class. The
+ ‘transient-prefix’ class is used if the class is not specified
+ explicitly.
+
+ GROUPs add key bindings for infix and suffix commands and specify
+ how these bindings are presented in the popup buffer. At least one
+ GROUP has to be specified. See *note Binding Suffix and Infix
+ Commands::.
+
+ The BODY is optional. If it is omitted, then ARGLIST is ignored
+ and the function definition becomes:
+
+ (lambda ()
+ (interactive)
+ (transient-setup 'NAME))
+
+ If BODY is specified, then it must begin with an ‘interactive’ form
+ that matches ARGLIST, and it must call ‘transient-setup’. It may,
+ however, call that function only when some condition is satisfied.
+
+ All transients have a (possibly ‘nil’) value, which is exported
+ when suffix commands are called, so that they can consume that
+ value. For some transients it might be necessary to have a sort of
+ secondary value, called a "scope". Such a scope would usually be
+ set in the command’s ‘interactive’ form and has to be passed to the
+ setup function:
+
+ (transient-setup 'NAME nil nil :scope SCOPE)
+
+ For example, the scope of the ‘magit-branch-configure’ transient is
+ the branch whose variables are being configured.
+
+
+File: transient.info, Node: Binding Suffix and Infix Commands, Next: Defining Suffix and Infix Commands, Prev: Defining Transients, Up: Defining New Commands
+
+4.2 Binding Suffix and Infix Commands
+=====================================
+
+The macro ‘transient-define-prefix’ is used to define a transient. This
+defines the actual transient prefix command (see *note Defining
+Transients::) and adds the transient’s infix and suffix bindings, as
+described below.
+
+ Users and third-party packages can add additional bindings using
+functions such as ‘transient-insert-suffix’ (See *note Modifying
+Existing Transients::). These functions take a "suffix specification"
+as one of their arguments, which has the same form as the specifications
+used in ‘transient-define-prefix’.
+
+* Menu:
+
+* Group Specifications::
+* Suffix Specifications::
+
+
+File: transient.info, Node: Group Specifications, Next: Suffix Specifications, Up: Binding Suffix and Infix Commands
+
+4.2.1 Group Specifications
+--------------------------
+
+The suffix and infix commands of a transient are organized in groups.
+The grouping controls how the descriptions of the suffixes are outlined
+visually but also makes it possible to set certain properties for a set
+of suffixes.
+
+ Several group classes exist, some of which organize suffixes in
+subgroups. In most cases the class does not have to be specified
+explicitly, but see *note Group Classes::.
+
+ Groups are specified in the call to ‘transient-define-prefix’, using
+vectors. Because groups are represented using vectors, we cannot use
+square brackets to indicate an optional element and instead use curly
+brackets to do the latter.
+
+ Group specifications then have this form:
+
+ [{LEVEL} {DESCRIPTION} {KEYWORD VALUE}... ELEMENT...]
+
+ The LEVEL is optional and defaults to 4. See *note Enabling and
+Disabling Suffixes::.
+
+ The DESCRIPTION is optional. If present, it is used as the heading
+of the group.
+
+ The KEYWORD-VALUE pairs are optional. Each keyword has to be a
+keyword symbol, either ‘:class’ or a keyword argument supported by the
+constructor of that class.
+
+ • One of these keywords, ‘:description’, is equivalent to specifying
+ DESCRIPTION at the very beginning of the vector. The
+ recommendation is to use ‘:description’ if some other keyword is
+ also used, for consistency, or DESCRIPTION otherwise, because it
+ looks better.
+
+ • Likewise ‘:level’ is equivalent to LEVEL.
+
+ • Other important keywords include the ‘:if...’ keywords. These
+ keywords control whether the group is available in a certain
+ situation.
+
+ For example, one group of the ‘magit-rebase’ transient uses ‘:if
+ magit-rebase-in-progress-p’, which contains the suffixes that are
+ useful while rebase is already in progress; and another that uses
+ ‘:if-not magit-rebase-in-progress-p’, which contains the suffixes
+ that initiate a rebase.
+
+ These predicates can also be used on individual suffixes and are
+ only documented once, see *note Predicate Slots::.
+
+ • The value of ‘:hide’, if non-‘nil’, is a predicate that controls
+ whether the group is hidden by default. The key bindings for
+ suffixes of a hidden group should all use the same prefix key.
+ Pressing that prefix key should temporarily show the group and its
+ suffixes, which assumes that a predicate like this is used:
+
+ (lambda ()
+ (eq (car transient--redisplay-key)
+ ?\C-c)) ; the prefix key shared by all bindings
+
+ • The value of ‘:setup-children’, if non-‘nil’, is a function that
+ takes two arguments the group object itself and a list of children.
+ The children are given as a (potentially empty) list consisting of
+ either group or suffix specifications. It can make arbitrary
+ changes to the children including constructing new children from
+ scratch. Also see ‘transient-setup-children’.
+
+ • The boolean ‘:pad-keys’ argument controls whether keys of all
+ suffixes contained in a group are right padded, effectively
+ aligning the descriptions.
+
+ The ELEMENTs are either all subgroups (vectors), or all suffixes
+(lists) and strings. (At least currently no group type exists that
+would allow mixing subgroups with commands at the same level, though in
+principle there is nothing that prevents that.)
+
+ If the ELEMENTs are not subgroups, then they can be a mixture of
+lists that specify commands and strings. Strings are inserted verbatim.
+The empty string can be used to insert gaps between suffixes, which is
+particularly useful if the suffixes are outlined as a table.
+
+ Variables are supported inside group specifications. For example in
+place of a direct subgroup specification, a variable can be used whose
+value is a vector that qualifies as a group specification. Likewise, a
+variable can be used where a suffix specification is expected. Lists of
+group or suffix specifications are also supported. Indirect
+specifications are resolved when the transient prefix is being defined.
+
+ The form of suffix specifications is documented in the next node.
+
+
+File: transient.info, Node: Suffix Specifications, Prev: Group Specifications, Up: Binding Suffix and Infix Commands
+
+4.2.2 Suffix Specifications
+---------------------------
+
+A transient’s suffix and infix commands are bound when the transient
+prefix command is defined using ‘transient-define-prefix’, see *note
+Defining Transients::. The commands are organized into groups, see
+*note Group Specifications::. Here we describe the form used to bind an
+individual suffix command.
+
+ The same form is also used when later binding additional commands
+using functions such as ‘transient-insert-suffix’, see *note Modifying
+Existing Transients::.
+
+ Note that an infix is a special kind of suffix. Depending on context
+"suffixes" means "suffixes (including infixes)" or "non-infix suffixes".
+Here it means the former.
+
+ Suffix specifications have this form:
+
+ ([LEVEL] [KEY] [DESCRIPTION] COMMAND|ARGUMENT [KEYWORD VALUE]...)
+
+ LEVEL, KEY and DESCRIPTION can also be specified using the KEYWORDs
+‘:level’, ‘:key’ and ‘:description’. If the object that is associated
+with COMMAND sets these properties, then they do not have to be
+specified here. You can however specify them here anyway, possibly
+overriding the object’s values just for the binding inside this
+transient.
+
+ • LEVEL is the suffix level, an integer between 1 and 7. See *note
+ Enabling and Disabling Suffixes::.
+
+ • KEY is the key binding, either a vector or key description string.
+
+ • DESCRIPTION is the description, either a string or a function that
+ returns a string. The function should be a lambda expression to
+ avoid ambiguity. In some cases a symbol that is bound as a
+ function would also work but to be safe you should use
+ ‘:description’ in that case.
+
+ The next element is either a command or an argument. This is the
+only argument that is mandatory in all cases.
+
+ • COMMAND should be a symbol that is bound as a function, which has
+ to be defined or at least autoloaded as a command by the time the
+ containing prefix command is invoked.
+
+ Any command will do; it does not need to have an object associated
+ with it (as would be the case if ‘transient-define-suffix’ or
+ ‘transient-define-infix’ were used to define it).
+
+ Anonymous, dynamically defined suffix commands are also support.
+ See information about the ‘:setup-children’ function in *note Group
+ Specifications::.
+
+ As mentioned above, the object that is associated with a command
+ can be used to set the default for certain values that otherwise
+ have to be set in the suffix specification. Therefore if there is
+ no object, then you have to make sure to specify the KEY and the
+ DESCRIPTION.
+
+ As a special case, if you want to add a command that might be
+ neither defined nor autoloaded, you can use a workaround like:
+
+ (transient-insert-suffix 'some-prefix "k"
+ '("!" "Ceci n'est pas une commande" no-command
+ :if (lambda () (featurep 'no-library))))
+
+ Instead of ‘featurep’ you could also use ‘require’ with a non-‘nil’
+ value for NOERROR.
+
+ • The mandatory argument can also be a command-line argument, a
+ string. In that case an anonymous command is defined and bound.
+
+ Instead of a string, this can also be a list of two strings, in
+ which case the first string is used as the short argument (which
+ can also be specified using ‘:shortarg’) and the second as the long
+ argument (which can also be specified using ‘:argument’).
+
+ Only the long argument is displayed in the popup buffer. See
+ ‘transient-detect-key-conflicts’ for how the short argument may be
+ used.
+
+ Unless the class is specified explicitly, the appropriate class is
+ guessed based on the long argument. If the argument ends with "=​"
+ (e.g., "–format=") then ‘transient-option’ is used, otherwise
+ ‘transient-switch’.
+
+ Finally, details can be specified using optional KEYWORD-VALUE pairs.
+Each keyword has to be a keyword symbol, either ‘:class’ or a keyword
+argument supported by the constructor of that class. See *note Suffix
+Slots::.
+
+
+File: transient.info, Node: Defining Suffix and Infix Commands, Next: Using Infix Arguments, Prev: Binding Suffix and Infix Commands, Up: Defining New Commands
+
+4.3 Defining Suffix and Infix Commands
+======================================
+
+Note that an infix is a special kind of suffix. Depending on context
+"suffixes" means "suffixes (including infixes)" or "non-infix suffixes".
+
+ -- Macro: transient-define-suffix name arglist [docstring] [keyword
+ value]... body...
+ This macro defines NAME as a transient suffix command.
+
+ ARGLIST are the arguments that the command takes. DOCSTRING is the
+ documentation string and is optional.
+
+ These arguments can optionally be followed by keyword-value pairs.
+ Each keyword has to be a keyword symbol, either ‘:class’ or a
+ keyword argument supported by the constructor of that class. The
+ ‘transient-suffix’ class is used if the class is not specified
+ explicitly.
+
+ The BODY must begin with an ‘interactive’ form that matches
+ ARGLIST. The infix arguments are usually accessed by using
+ ‘transient-args’ inside ‘interactive’.
+
+ -- Macro: transient-define-infix name arglist [docstring] [keyword
+ value]...
+ This macro defines NAME as a transient infix command.
+
+ ARGLIST is always ignored (but mandatory never-the-less) and
+ reserved for future use. DOCSTRING is the documentation string and
+ is optional.
+
+ The keyword-value pairs are mandatory. All transient infix
+ commands are ‘equal’ to each other (but not ‘eq’), so it is
+ meaningless to define an infix command without also setting at
+ least ‘:class’ and one other keyword (which it is depends on the
+ used class, usually ‘:argument’ or ‘:variable’).
+
+ Each keyword has to be a keyword symbol, either ‘:class’ or a
+ keyword argument supported by the constructor of that class. The
+ ‘transient-switch’ class is used if the class is not specified
+ explicitly.
+
+ The function definition is always:
+
+ (lambda ()
+ (interactive)
+ (let ((obj (transient-suffix-object)))
+ (transient-infix-set obj (transient-infix-read obj)))
+ (transient--show))
+
+ ‘transient-infix-read’ and ‘transient-infix-set’ are generic
+ functions. Different infix commands behave differently because the
+ concrete methods are different for different infix command classes.
+ In rare cases the above command function might not be suitable,
+ even if you define your own infix command class. In that case you
+ have to use ‘transient-define-suffix’ to define the infix command
+ and use ‘t’ as the value of the ‘:transient’ keyword.
+
+ -- Macro: transient-define-argument name arglist [docstring] [keyword
+ value]...
+ This macro defines NAME as a transient infix command.
+
+ This is an alias for ‘transient-define-infix’. Only use this alias
+ to define an infix command that actually sets an infix argument.
+ To define an infix command that, for example, sets a variable, use
+ ‘transient-define-infix’ instead.
+
+
+File: transient.info, Node: Using Infix Arguments, Next: Transient State, Prev: Defining Suffix and Infix Commands, Up: Defining New Commands
+
+4.4 Using Infix Arguments
+=========================
+
+The functions and the variables described below allow suffix commands to
+access the value of the transient from which they were invoked; which is
+the value of its infix arguments. These variables are set when the user
+invokes a suffix command that exits the transient, but before actually
+calling the command.
+
+ When returning to the command-loop after calling the suffix command,
+the arguments are reset to ‘nil’ (which causes the function to return
+‘nil’ too).
+
+ Like for Emacs’ prefix arguments, it is advisable, but not mandatory,
+to access the infix arguments inside the command’s ‘interactive’ form.
+The preferred way of doing that is to call the ‘transient-args’
+function, which for infix arguments serves about the same purpose as
+‘prefix-arg’ serves for prefix arguments.
+
+ -- Function: transient-args prefix
+ This function returns the value of the transient prefix command
+ PREFIX.
+
+ If the current command was invoked from the transient prefix
+ command PREFIX, then it returns the active infix arguments. If the
+ current command was not invoked from PREFIX, then it returns the
+ set, saved or default value for PREFIX.
+
+ -- Function: transient-arg-value arg args
+ This function return the value of ARG as it appears in ARGS.
+
+ For a switch a boolean is returned. For an option the value is
+ returned as a string, using the empty string for the empty value,
+ or nil if the option does not appear in ARGS.
+
+ -- Function: transient-suffixes prefix
+ This function returns the suffixes of the transient prefix command
+ PREFIX. This is a list of objects. This function should only be
+ used if you need the objects (as opposed to just their values) and
+ if the current command is not being invoked from PREFIX.
+
+ -- Variable: transient-current-suffixes
+ The suffixes of the transient from which this suffix command was
+ invoked. This is a list of objects. Usually it is sufficient to
+ instead use the function ‘transient-args’, which returns a list of
+ values. In complex cases it might be necessary to use this
+ variable instead, i.e., if you need access to information beside
+ the value.
+
+ -- Variable: transient-current-prefix
+ The transient from which this suffix command was invoked. The
+ returned value is a ‘transient-prefix’ object, which holds
+ information associated with the transient prefix command.
+
+ -- Variable: transient-current-command
+ The transient from which this suffix command was invoked. The
+ returned value is a symbol, the transient prefix command.
+
+
+File: transient.info, Node: Transient State, Prev: Using Infix Arguments, Up: Defining New Commands
+
+4.5 Transient State
+===================
+
+Invoking a transient prefix command "activates" the respective
+transient, i.e., it puts a transient keymap into effect, which binds the
+transient’s infix and suffix commands.
+
+ The default behavior while a transient is active is as follows:
+
+ • Invoking an infix command does not affect the transient state; the
+ transient remains active.
+
+ • Invoking a (non-infix) suffix command "deactivates" the transient
+ state by removing the transient keymap and performing some
+ additional cleanup.
+
+ • Invoking a command that is bound in a keymap other than the
+ transient keymap is disallowed and trying to do so results in a
+ warning. This does not "deactivate" the transient.
+
+ But these are just the defaults. Whether a certain command
+deactivates or "exits" the transient is configurable. There is more
+than one way in which a command can be "transient" or "non-transient";
+the exact behavior is implemented by calling a so-called "pre-command"
+function. Whether non-suffix commands are allowed to be called is
+configurable per transient.
+
+ • The transient-ness of suffix commands (including infix commands) is
+ controlled by the value of their ‘transient’ slot, which can be set
+ either when defining the command or when adding a binding to a
+ transient while defining the respective transient prefix command.
+
+ Valid values are booleans and the pre-commands described below.
+
+ • ‘t’ is equivalent to ‘transient--do-stay’.
+ • ‘nil’ is equivalent to ‘transient--do-exit’.
+ • If ‘transient’ is unbound (and that is actually the default
+ for non-infix suffixes) then the value of the prefix’s
+ ‘transient-suffix’ slot is used instead. The default value of
+ that slot is ‘nil’, so the suffix’s ‘transient’ slot being
+ unbound is essentially equivalent to it being ‘nil’.
+
+ • A suffix command can be a prefix command itself, i.e., a
+ "sub-prefix". While a sub-prefix is active we nearly always want
+ ‘C-g’ to take the user back to the "super-prefix". However in rare
+ cases this may not be desirable, and that makes the following
+ complication necessary:
+
+ For ‘transient-suffix’ objects the ‘transient’ slot is unbound. We
+ can ignore that for the most part because, as stated above, ‘nil’
+ and the slot being unbound are equivalent, and mean "do exit".
+ That isn’t actually true for suffixes that are sub-prefixes though.
+ For such suffixes unbound means "do exit but allow going back",
+ which is the default, while ‘nil’ means "do exit permanently",
+ which requires that slot to be explicitly set to that value.
+
+ • The transient-ness of certain built-in suffix commands is specified
+ using ‘transient-predicate-map’. This is a special keymap, which
+ binds commands to pre-commands (as opposed to keys to commands) and
+ takes precedence over the ‘transient’ slot.
+
+ The available pre-command functions are documented below. They are
+called by ‘transient--pre-command’, a function on ‘pre-command-hook’ and
+the value that they return determines whether the transient is exited.
+To do so the value of one of the constants ‘transient--exit’ or
+‘transient--stay’ is used (that way we don’t have to remember if ‘t’
+means "exit" or "stay").
+
+ Additionally, these functions may change the value of ‘this-command’
+(which explains why they have to be called using ‘pre-command-hook’),
+call ‘transient-export’, ‘transient--stack-zap’ or
+‘transient--stack-push’; and set the values of ‘transient--exitp’,
+‘transient--helpp’ or ‘transient--editp’.
+
+Pre-commands for Infixes
+------------------------
+
+The default for infixes is ‘transient--do-stay’. This is also the only
+function that makes sense for infixes.
+
+ -- Function: transient--do-stay
+ Call the command without exporting variables and stay transient.
+
+Pre-commands for Suffixes
+-------------------------
+
+The default for suffixes is ‘transient--do-exit’.
+
+ -- Function: transient--do-exit
+ Call the command after exporting variables and exit the transient.
+
+ -- Function: transient--do-return
+ Call the command after exporting variables and return to parent
+ prefix. If there is no parent prefix, then call
+ ‘transient--do-exit’.
+
+ -- Function: transient--do-call
+ Call the command after exporting variables and stay transient.
+
+ The following pre-commands are suitable for sub-prefixes. Only the
+first should ever explicitly be set as the value of the ‘transient’
+slot.
+
+ -- Function: transient--do-recurse
+ Call the transient prefix command, preparing for return to active
+ transient.
+
+ Whether we actually return to the parent transient is ultimately
+ under the control of each invoked suffix. The difference between
+ this pre-command and ‘transient--do-replace’ is that it changes the
+ value of the ‘transient-suffix’ slot to ‘transient--do-return’.
+
+ If there is no parent transient, then only call this command and
+ skip the second step.
+
+ -- Function: transient--do-replace
+ Call the transient prefix command, replacing the active transient.
+
+ Unless ‘transient--do-recurse’ is explicitly used, this pre-command
+ is automatically used for suffixes that are prefixes themselves,
+ i.e., for sub-prefixes.
+
+ -- Function: transient--do-suspend
+ Suspend the active transient, saving the transient stack.
+
+ This is used by the command ‘transient-suspend’ and optionally also
+ by "external events" such as ‘handle-switch-frame’. Such bindings
+ should be added to ‘transient-predicate-map’.
+
+Pre-commands for Non-Suffixes
+-----------------------------
+
+The default for non-suffixes, i.e commands that are bound in other
+keymaps beside the transient keymap, is ‘transient--do-warn’. Silently
+ignoring the user-error is also an option, though probably not a good
+one.
+
+ If you want to let the user invoke non-suffix commands, then use
+‘transient--do-stay’ as the value of the prefix’s ‘transient-non-suffix’
+slot.
+
+ -- Function: transient--do-warn
+ Call ‘transient-undefined’ and stay transient.
+
+ -- Function: transient--do-noop
+ Call ‘transient-noop’ and stay transient.
+
+Special Pre-Commands
+--------------------
+
+ -- Function: transient--do-quit-one
+ If active, quit help or edit mode, else exit the active transient.
+
+ This is used when the user pressed ‘C-g’.
+
+ -- Function: transient--do-quit-all
+ Exit all transients without saving the transient stack.
+
+ This is used when the user pressed ‘C-q’.
+
+ -- Function: transient--do-suspend
+ Suspend the active transient, saving the transient stack.
+
+ This is used when the user pressed ‘C-z’.
+
+
+File: transient.info, Node: Classes and Methods, Next: Related Abstractions and Packages, Prev: Defining New Commands, Up: Top
+
+5 Classes and Methods
+*********************
+
+Transient uses classes and generic functions to make it possible to
+define new types of suffix commands that are similar to existing types,
+but behave differently in some aspects. It does the same for groups and
+prefix commands, though at least for prefix commands that *currently*
+appears to be less important.
+
+ Every prefix, infix and suffix command is associated with an object,
+which holds information that controls certain aspects of its behavior.
+This happens in two ways.
+
+ • Associating a command with a certain class gives the command a
+ type. This makes it possible to use generic functions to do
+ certain things that have to be done differently depending on what
+ type of command it acts on.
+
+ That in turn makes it possible for third-parties to add new types
+ without having to convince the maintainer of Transient that that
+ new type is important enough to justify adding a special case to a
+ dozen or so functions.
+
+ • Associating a command with an object makes it possible to easily
+ store information that is specific to that particular command.
+
+ Two commands may have the same type, but obviously their key
+ bindings and descriptions still have to be different, for example.
+
+ The values of some slots are functions. The ‘reader’ slot for
+ example holds a function that is used to read a new value for an
+ infix command. The values of such slots are regular functions.
+
+ Generic functions are used when a function should do something
+ different based on the type of the command, i.e., when all commands
+ of a certain type should behave the same way but different from the
+ behavior for other types. Object slots that hold a regular
+ function as value are used when the task that they perform is
+ likely to differ even between different commands of the same type.
+
+* Menu:
+
+* Group Classes::
+* Group Methods::
+* Prefix Classes::
+* Suffix Classes::
+* Suffix Methods::
+* Prefix Slots::
+* Suffix Slots::
+* Predicate Slots::
+
+
+File: transient.info, Node: Group Classes, Next: Group Methods, Up: Classes and Methods
+
+5.1 Group Classes
+=================
+
+The type of a group can be specified using the ‘:class’ property at the
+beginning of the class specification, e.g., ‘[:class transient-columns
+...]’ in a call to ‘transient-define-prefix’.
+
+ • The abstract ‘transient-child’ class is the base class of both
+ ‘transient-group’ (and therefore all groups) as well as of
+ ‘transient-suffix’ (and therefore all suffix and infix commands).
+
+ This class exists because the elements (aka "children") of certain
+ groups can be other groups instead of suffix and infix commands.
+
+ • The abstract ‘transient-group’ class is the superclass of all other
+ group classes.
+
+ • The ‘transient-column’ class is the simplest group.
+
+ This is the default "flat" group. If the class is not specified
+ explicitly and the first element is not a vector (i.e., not a
+ group), then this class is used.
+
+ This class displays each element on a separate line.
+
+ • The ‘transient-row’ class displays all elements on a single line.
+
+ • The ‘transient-columns’ class displays commands organized in
+ columns.
+
+ Direct elements have to be groups whose elements have to be
+ commands or strings. Each subgroup represents a column. This
+ class takes care of inserting the subgroups’ elements.
+
+ This is the default "nested" group. If the class is not specified
+ explicitly and the first element is a vector (i.e., a group), then
+ this class is used.
+
+ • The ‘transient-subgroups’ class wraps other groups.
+
+ Direct elements have to be groups whose elements have to be
+ commands or strings. This group inserts an empty line between
+ subgroups. The subgroups themselves are responsible for displaying
+ their elements.
+
+
+File: transient.info, Node: Group Methods, Next: Prefix Classes, Prev: Group Classes, Up: Classes and Methods
+
+5.2 Group Methods
+=================
+
+ -- Function: transient-setup-children group children
+ This generic function can be used to setup the children or a group.
+
+ The default implementation usually just returns the children
+ unchanged, but if the ‘setup-children’ slot of GROUP is non-‘nil’,
+ then it calls that function with CHILDREN as the only argument and
+ returns the value.
+
+ The children are given as a (potentially empty) list consisting of
+ either group or suffix specifications. These functions can make
+ arbitrary changes to the children including constructing new
+ children from scratch.
+
+ -- Function: transient--insert-group group
+ This generic function formats the group and its elements and
+ inserts the result into the current buffer, which is a temporary
+ buffer. The contents of that buffer are later inserted into the
+ popup buffer.
+
+ Functions that are called by this function may need to operate in
+ the buffer from which the transient was called. To do so they can
+ temporarily make the ‘transient--source-buffer’ the current buffer.
+
+
+File: transient.info, Node: Prefix Classes, Next: Suffix Classes, Prev: Group Methods, Up: Classes and Methods
+
+5.3 Prefix Classes
+==================
+
+Currently the ‘transient-prefix’ class is being used for all prefix
+commands and there is only a single generic function that can be
+specialized based on the class of a prefix command.
+
+ -- Function: transient--history-init obj
+ This generic function is called while setting up the transient and
+ is responsible for initializing the ‘history’ slot. This is the
+ transient-wide history; many individual infixes also have a history
+ of their own.
+
+ The default (and currently only) method extracts the value from the
+ global variable ‘transient-history’.
+
+ A transient prefix command’s object is stored in the
+‘transient--prefix’ property of the command symbol. While a transient
+is active, a clone of that object is stored in the variable
+‘transient--prefix’. A clone is used because some changes that are made
+to the active transient’s object should not affect later invocations.
+
+
+File: transient.info, Node: Suffix Classes, Next: Suffix Methods, Prev: Prefix Classes, Up: Classes and Methods
+
+5.4 Suffix Classes
+==================
+
+ • All suffix and infix classes derive from ‘transient-suffix’, which
+ in turn derives from ‘transient-child’, from which
+ ‘transient-group’ also derives (see *note Group Classes::).
+
+ • All infix classes derive from the abstract ‘transient-infix’ class,
+ which in turn derives from the ‘transient-suffix’ class.
+
+ Infixes are a special type of suffixes. The primary difference is
+ that infixes always use the ‘transient--do-stay’ pre-command, while
+ non-infix suffixes use a variety of pre-commands (see *note
+ Transient State::). Doing that is most easily achieved by using
+ this class, though theoretically it would be possible to define an
+ infix class that does not do so. If you do that then you get to
+ implement many methods.
+
+ Also, infixes and non-infix suffixes are usually defined using
+ different macros (see *note Defining Suffix and Infix Commands::).
+
+ • Classes used for infix commands that represent arguments should be
+ derived from the abstract ‘transient-argument’ class.
+
+ • The ‘transient-switch’ class (or a derived class) is used for infix
+ arguments that represent command-line switches (arguments that do
+ not take a value).
+
+ • The ‘transient-option’ class (or a derived class) is used for infix
+ arguments that represent command-line options (arguments that do
+ take a value).
+
+ • The ‘transient-switches’ class can be used for a set of mutually
+ exclusive command-line switches.
+
+ • The ‘transient-files’ class can be used for a "–" argument that
+ indicates that all remaining arguments are files.
+
+ • Classes used for infix commands that represent variables should
+ derived from the abstract ‘transient-variables’ class.
+
+ Magit defines additional classes, which can serve as examples for the
+fancy things you can do without modifying Transient. Some of these
+classes will likely get generalized and added to Transient. For now
+they are very much subject to change and not documented.
+
+
+File: transient.info, Node: Suffix Methods, Next: Prefix Slots, Prev: Suffix Classes, Up: Classes and Methods
+
+5.5 Suffix Methods
+==================
+
+To get information about the methods implementing these generic
+functions use ‘describe-function’.
+
+* Menu:
+
+* Suffix Value Methods::
+* Suffix Format Methods::
+
+
+File: transient.info, Node: Suffix Value Methods, Next: Suffix Format Methods, Up: Suffix Methods
+
+5.5.1 Suffix Value Methods
+--------------------------
+
+ -- Function: transient-init-value obj
+ This generic function sets the initial value of the object OBJ.
+
+ This function is called for all suffix commands, but unless a
+ concrete method is implemented this falls through to the default
+ implementation, which is a noop. In other words this usually only
+ does something for infix commands, but note that this is not
+ implemented for the abstract class ‘transient-infix’, so if your
+ class derives from that directly, then you must implement a method.
+
+ -- Function: transient-infix-read obj
+ This generic function determines the new value of the infix object
+ OBJ.
+
+ This function merely determines the value; ‘transient-infix-set’ is
+ used to actually store the new value in the object.
+
+ For most infix classes this is done by reading a value from the
+ user using the reader specified by the ‘reader’ slot (using the
+ ‘transient-infix-value’ method described below).
+
+ For some infix classes the value is changed without reading
+ anything in the minibuffer, i.e., the mere act of invoking the
+ infix command determines what the new value should be, based on the
+ previous value.
+
+ -- Function: transient-prompt obj
+ This generic function returns the prompt to be used to read infix
+ object OBJ’s value.
+
+ -- Function: transient-infix-set obj value
+ This generic function sets the value of infix object OBJ to VALUE.
+
+ -- Function: transient-infix-value obj
+ This generic function returns the value of the suffix object OBJ.
+
+ This function is called by ‘transient-args’ (which see), meaning
+ this function is how the value of a transient is determined so that
+ the invoked suffix command can use it.
+
+ Currently most values are strings, but that is not set in stone.
+ ‘nil’ is not a value, it means "no value".
+
+ Usually only infixes have a value, but see the method for
+ ‘transient-suffix’.
+
+ -- Function: transient-init-scope obj
+ This generic function sets the scope of the suffix object OBJ.
+
+ The scope is actually a property of the transient prefix, not of
+ individual suffixes. However it is possible to invoke a suffix
+ command directly instead of from a transient. In that case, if the
+ suffix expects a scope, then it has to determine that itself and
+ store it in its ‘scope’ slot.
+
+ This function is called for all suffix commands, but unless a
+ concrete method is implemented this falls through to the default
+ implementation, which is a noop.
+
+
+File: transient.info, Node: Suffix Format Methods, Prev: Suffix Value Methods, Up: Suffix Methods
+
+5.5.2 Suffix Format Methods
+---------------------------
+
+ -- Function: transient-format obj
+ This generic function formats and returns OBJ for display.
+
+ When this function is called, then the current buffer is some
+ temporary buffer. If you need the buffer from which the prefix
+ command was invoked to be current, then do so by temporarily making
+ ‘transient--source-buffer’ current.
+
+ -- Function: transient-format-key obj
+ This generic function formats OBJ’s ‘key’ for display and returns
+ the result.
+
+ -- Function: transient-format-description obj
+ This generic function formats OBJ’s ‘description’ for display and
+ returns the result.
+
+ -- Function: transient-format-value obj
+ This generic function formats OBJ’s value for display and returns
+ the result.
+
+ -- Function: transient-show-help obj
+ Show help for the prefix, infix or suffix command represented by
+ OBJ.
+
+ For prefixes, show the info manual, if that is specified using the
+ ‘info-manual’ slot. Otherwise, show the manpage if that is
+ specified using the ‘man-page’ slot. Otherwise, show the command’s
+ doc string.
+
+ For suffixes, show the command’s doc string.
+
+ For infixes, show the manpage if that is specified. Otherwise show
+ the command’s doc string.
+
+
+File: transient.info, Node: Prefix Slots, Next: Suffix Slots, Prev: Suffix Methods, Up: Classes and Methods
+
+5.6 Prefix Slots
+================
+
+ • ‘show-help’, ‘man-page’ or ‘info-manual’ can be used to specify the
+ documentation for the prefix and its suffixes. The command
+ ‘transient-help’ uses the method ‘transient-show-help’ (which see)
+ to lookup and use these values.
+
+ • ‘history-key’ If multiple prefix commands should share a single
+ value, then this slot has to be set to the same value for all of
+ them. You probably don’t want that.
+
+ • ‘transient-suffix’ and ‘transient-non-suffix’ play a part when
+ determining whether the currently active transient prefix command
+ remains active/transient when a suffix or abitrary non-suffix
+ command is invoked. See *note Transient State::.
+
+ • ‘incompatible’ A list of lists. Each sub-list specifies a set of
+ mutually exclusive arguments. Enabling one of these arguments
+ causes the others to be disabled. An argument may appear in
+ multiple sub-lists.
+
+ • ‘scope’ For some transients it might be necessary to have a sort of
+ secondary value, called a "scope". See ‘transient-define-prefix’.
+
+Internal Prefix Slots
+---------------------
+
+These slots are mostly intended for internal use. They should not be
+set in calls to ‘transient-define-prefix’.
+
+ • ‘prototype’ When a transient prefix command is invoked, then a
+ clone of that object is stored in the global variable
+ ‘transient--prefix’ and the prototype is stored in the clone’s
+ ‘prototype’ slot.
+
+ • ‘command’ The command, a symbol. Each transient prefix command
+ consists of a command, which is stored in a symbol’s function slot
+ and an object, which is stored in the ‘transient--prefix’ property
+ of the same symbol.
+
+ • ‘level’ The level of the prefix commands. The suffix commands
+ whose layer is equal or lower are displayed. See *note Enabling
+ and Disabling Suffixes::.
+
+ • ‘value’ The likely outdated value of the prefix. Instead of
+ accessing this slot directly you should use the function
+ ‘transient-get-value’, which is guaranteed to return the up-to-date
+ value.
+
+ • ‘history’ and ‘history-pos’ are used to keep track of historic
+ values. Unless you implement your own ‘transient-infix-read’
+ method you should not have to deal with these slots.
+
+
+File: transient.info, Node: Suffix Slots, Next: Predicate Slots, Prev: Prefix Slots, Up: Classes and Methods
+
+5.7 Suffix Slots
+================
+
+Here we document most of the slots that are only available for suffix
+objects. Some slots are shared by suffix and group objects, they are
+documented in *note Predicate Slots::.
+
+ Also see *note Suffix Classes::.
+
+Slots of ‘transient-suffix’
+---------------------------
+
+ • ‘key’ The key, a key vector or a key description string.
+
+ • ‘command’ The command, a symbol.
+
+ • ‘transient’ Whether to stay transient. See *note Transient
+ State::.
+
+ • ‘format’ The format used to display the suffix in the popup buffer.
+ It must contain the following %-placeholders:
+
+ • ‘%k’ For the key.
+ • ‘%d’ For the description.
+ • ‘%v’ For the infix value. Non-infix suffixes don’t have a
+ value.
+
+ • ‘description’ The description, either a string or a function that
+ is called with no argument and returns a string.
+
+ • ‘show-help’ A function used to display help for the suffix. If
+ unspecified, the prefix controls how hlep is displayed for its
+ suffixes.
+
+Slots of ‘transient-infix’
+--------------------------
+
+Some of these slots are only meaningful for some of the subclasses.
+They are defined here anyway to allow sharing certain methods.
+
+ • ‘argument’ The long argument, e.g., ‘--verbose’.
+
+ • ‘shortarg’ The short argument, e.g., ‘-v’.
+
+ • ‘value’ The value. Should not be accessed directly.
+
+ • ‘init-value’ Function that is responsible for setting the object’s
+ value. If bound, then this is called with the object as the only
+ argument. Usually this is not bound, in which case the object’s
+ primary ‘transient-init-value’ method is called instead.
+
+ • ‘unsavable’ Whether the value of the suffix is not saved as part of
+ the prefixes.
+
+ • ‘multi-value’ For options, whether the option can have multiple
+ values. If this is non-‘nil’, then the values are read using
+ ‘completing-read-multiple’ by default and if you specify your own
+ reader, then it should read the values using that function or
+ similar.
+
+ Supported non-‘nil’ values are:
+
+ • Use ‘rest’ for an option that can have multiple values. This
+ is useful e.g., for an ‘--’ argument that indicates that all
+ remaining arguments are files (such as ‘git log -- file1
+ file2’).
+
+ In the list returned by ‘transient-args’ such an option and
+ its values are represented by a single list of the form
+ ‘(ARGUMENT . VALUES)’.
+
+ • Use ‘repeat’ for an option that can be specified multiple
+ times.
+
+ In the list returned by ‘transient-args’ each instance of the
+ option and its value appears separately in the usual from, for
+ example: ‘("--another-argument" "--option=first"
+ "--option=second")’.
+
+ In both cases the option’s values have to be specified in the
+ default value of a prefix using the same format as returned by
+ ‘transient-args’, e.g., ‘("--other" "--o=1" "--o=2" ("--" "f1"
+ "f2"))’.
+
+ • ‘always-read’ For options, whether to read a value on every
+ invocation. If this is nil, then options that have a value are
+ simply unset and have to be invoked a second time to set a new
+ value.
+
+ • ‘allow-empty’ For options, whether the empty string is a valid
+ value.
+
+ • ‘history-key’ The key used to store the history. This defaults to
+ the command name. This is useful when multiple infixes should
+ share the same history because their values are of the same kind.
+
+ • ‘reader’ The function used to read the value of an infix. Not used
+ for switches. The function takes three arguments, PROMPT,
+ INITIAL-INPUT and HISTORY, and must return a string.
+
+ • ‘prompt’ The prompt used when reading the value, either a string or
+ a function that takes the object as the only argument and which
+ returns a prompt string.
+
+ • ‘choices’ A list of valid values. How exactly that is used depends
+ on the class of the object.
+
+Slots of ‘transient-variable’
+-----------------------------
+
+ • ‘variable’ The variable.
+
+Slots of ‘transient-switches’
+-----------------------------
+
+ • ‘argument-format’ The display format. Must contain ‘%s’, one of
+ the ‘choices’ is substituted for that. e.g., ‘--%s-order’.
+
+ • ‘argument-regexp’ The regexp used to match any one of the switches.
+ e.g., ‘\\(--\\(topo\\|author-date\\|date\\)-order\\)’.
+
+
+File: transient.info, Node: Predicate Slots, Prev: Suffix Slots, Up: Classes and Methods
+
+5.8 Predicate Slots
+===================
+
+Suffix and group objects share some predicate slots that control whether
+a group or suffix should be available depending on some state. Only one
+of these slots can be used at the same time. It is undefined what
+happens if you use more than one.
+
+ • ‘if’ Enable if predicate returns non-‘nil’.
+ • ‘if-not’ Enable if predicate returns nil.
+ • ‘if-non-~nil~’ Enable if variable’s value is non-‘nil’.
+ • ‘if-nil’ Enable if variable’s value is nil.
+ • ‘if-mode’ Enable if major-mode matches value.
+ • ‘if-not-mode’ Enable if major-mode does not match value.
+ • ‘if-derived’ Enable if major-mode derives from value.
+ • ‘if-not-derived’ Enable if major-mode does not derive from value.
+
+ One more slot is shared between group and suffix classes, ‘level’.
+Like the slots documented above, it is a predicate, but it is used for a
+different purpose. The value has to be an integer between 1 and 7.
+‘level’ controls whether a suffix or a group should be available
+depending on user preference. See *note Enabling and Disabling
+Suffixes::.
+
+
+File: transient.info, Node: Related Abstractions and Packages, Next: FAQ, Prev: Classes and Methods, Up: Top
+
+6 Related Abstractions and Packages
+***********************************
+
+* Menu:
+
+* Comparison With Prefix Keys and Prefix Arguments::
+* Comparison With Other Packages::
+
+
+File: transient.info, Node: Comparison With Prefix Keys and Prefix Arguments, Next: Comparison With Other Packages, Up: Related Abstractions and Packages
+
+6.1 Comparison With Prefix Keys and Prefix Arguments
+====================================================
+
+While transient commands were inspired by regular prefix keys and prefix
+arguments, they are also quite different and much more complex.
+
+ The following diagrams illustrate some of the differences.
+
+ • ‘(c)’ represents a return to the command loop.
+ • ‘(+)’ represents the user’s choice to press one key or another.
+ • ‘{WORD}’ are possible behaviors.
+ • ‘{NUMBER}’ is a footnote.
+
+Regular Prefix Commands
+-----------------------
+
+See *note (elisp)Prefix Keys::.
+
+ ,--> command1 --> (c)
+ |
+ (c)-(+)-> prefix command or key --+--> command2 --> (c)
+ |
+ `--> command3 --> (c)
+
+Regular Prefix Arguments
+------------------------
+
+See *note (elisp)Prefix Command Arguments::.
+
+ ,----------------------------------,
+ | |
+ v |
+ (c)-(+)---> prefix argument command --(c)-(+)-> any command --> (c)
+ | ^ |
+ | | |
+ `-- sets or changes --, ,-- maybe used --' |
+ | | |
+ v | |
+ prefix argument state |
+ ^ |
+ | |
+ `-------- discards --------'
+
+Transients
+----------
+
+(∩`-´)⊃━☆゚.*・。゚
+
+ This diagram ignores the infix value and external state:
+
+ (c)
+ | ,- {stay} ------<-,-<------------<-,-<---,
+ (+) | | | |
+ | | | | |
+ | | ,--> infix1 --| | |
+ | | | | | |
+ | | |--> infix2 --| | |
+ v v | | | |
+ prefix -(c)-(+)-> infix3 --' ^ |
+ | | |
+ |---------------> suffix1 -->--| |
+ | | |
+ |---------------> suffix2 ----{1}------> {exit} --> (c)
+ | |
+ |---------------> suffix3 -------------> {exit} --> (c)
+ | |
+ `--> any command --{2}-> {warn} -->--|
+ | |
+ |--> {noop} -->--|
+ | |
+ |--> {call} -->--'
+ |
+ `------------------> {exit} --> (c)
+
+ This diagram takes the infix value into account to an extend, while
+still ignoring external state:
+
+ (c)
+ | ,- {stay} ------<-,-<------------<-,-<---,
+ (+) | | | |
+ | | | | |
+ | | ,--> infix1 --| | |
+ | | | | | | |
+ | | ,--> infix2 --| | |
+ v v | | | | |
+ prefix -(c)-(+)-> infix3 --' | |
+ | | ^ |
+ | | | |
+ |---------------> suffix1 -->--| |
+ | | ^ | |
+ | | | | |
+ |---------------> suffix2 ----{1}------> {exit} --> (c)
+ | | ^ | |
+ | | | | v
+ | | | | |
+ |---------------> suffix3 -------------> {exit} --> (c)
+ | | ^ | |
+ | sets | | v
+ | | maybe | |
+ | | used | |
+ | | | | |
+ | | infix --' | |
+ | `---> value | |
+ | ^ | |
+ | | | |
+ | hides | |
+ | | | |
+ | `--------------------------<---|
+ | | |
+ `--> any command --{2}-> {warn} -->--| |
+ | | |
+ |--> {noop} -->--| |
+ | | |
+ |--> {call} -->--' ^
+ | |
+ `------------------> {exit} --> (c)
+
+ This diagram provides more information about the infix value and also
+takes external state into account.
+
+ ,----sets--- "anything"
+ |
+ v
+ ,---------> external
+ | state
+ | | |
+ | initialized | ☉‿⚆
+ sets from |
+ | | maybe
+ | ,----------' used
+ | | |
+ (c) | | v
+ | ,- {stay} --|---<-,-<------|-----<-,-<---,
+ (+) | | | | | | |
+ | | | v | | | |
+ | | ,--> infix1 --| | | |
+ | | | | | | | | |
+ | | | | v | | | |
+ | | ,--> infix2 --| | | |
+ | | | | ^ | | | |
+ v v | | | | | | |
+ prefix -(c)-(+)-> infix3 --' | | |
+ | | ^ | ^ |
+ | | | v | |
+ |---------------> suffix1 -->--| |
+ | | | ^ | | |
+ | | | | v | |
+ |---------------> suffix2 ----{1}------> {exit} --> (c)
+ | | | ^ | | |
+ | | | | | | v
+ | | | | v | |
+ |---------------> suffix3 -------------> {exit} --> (c)
+ | | | ^ | |
+ | sets | | | v
+ | | initialized maybe | |
+ | | from used | |
+ | | | | | |
+ | | `-- infix ---' | |
+ | `---> value -----------------------------> persistent
+ | ^ ^ | | across
+ | | | | | invocations -,
+ | hides | | | |
+ | | `----------------------------------------------'
+ | | | |
+ | `--------------------------<---|
+ | | |
+ `--> any command --{2}-> {warn} -->--| |
+ | | |
+ |--> {noop} -->--| |
+ | | |
+ |--> {call} -->--' ^
+ | |
+ `------------------> {exit} --> (c)
+
+ • ‘{1}’ Transients can be configured to be exited when a suffix
+ command is invoked. The default is to do so for all suffixes
+ except for those that are common to all transients and which are
+ used to perform tasks such as providing help and saving the value
+ of the infix arguments for future invocations. The behavior can
+ also be specified for individual suffix commands and may even
+ depend on state.
+
+ • ‘{2}’ Transients can be configured to allow the user to invoke
+ non-suffix commands. The default is to not allow that and instead
+ warn the user.
+
+ Despite already being rather complex, even the last diagram leaves
+out many details. Most importantly it implies that the decision whether
+to remain transient is made later than it actually is made (for the most
+part a function on ‘pre-command-hook’ is responsible). But such
+implementation details are of little relevance to users and are covered
+elsewhere.
+
+
+File: transient.info, Node: Comparison With Other Packages, Prev: Comparison With Prefix Keys and Prefix Arguments, Up: Related Abstractions and Packages
+
+6.2 Comparison With Other Packages
+==================================
+
+Magit-Popup
+-----------
+
+Transient is the successor to Magit-Popup (see *note
+(magit-popup)Top::).
+
+ One major difference between these two implementations of the same
+ideas is that while Transient uses transient keymaps and embraces the
+command-loop, Magit-Popup implemented an inferior mechanism that does
+not use transient keymaps and that instead of using the command-loop
+implements a naive alternative based on ‘read-char’.
+
+ Magit-Popup does not use classes and generic functions and defining a
+new command type is near impossible as it involves adding hard-coded
+special-cases to many functions. Because of that only a single new type
+was added, which was not already part of Magit-Popup’s initial release.
+
+ A lot of things are hard-coded in Magit-Popup. One random example is
+that the key bindings for switches must begin with "-" and those for
+options must begin with "=".
+
+Hydra
+-----
+
+Hydra (see <https://github.com/abo-abo/hydra>) is another package that
+provides features similar to those of Transient.
+
+ Both packages use transient keymaps to make a set of commands
+temporarily available and show the available commands in a popup buffer.
+
+ A Hydra "body" is equivalent to a Transient "prefix" and a Hydra
+"head" is equivalent to a Transient "suffix". Hydra has no equivalent
+of a Transient "infix".
+
+ Both hydras and transients can be used as simple command dispatchers.
+Used like this they are similar to regular prefix commands and prefix
+keys, except that the available commands are shown in the popup buffer.
+
+ (Another package that does this is ‘which-key’. It does so
+automatically for any incomplete key sequence. The advantage of that
+approach is that no additional work is necessary; the disadvantage is
+that the available commands are not organized semantically.)
+
+ Both Hydra and Transient provide features that go beyond simple
+command dispatchers:
+
+ • Invoking a command from a hydra does not necessarily exit the
+ hydra. That makes it possible to invoke the same command again,
+ but using a shorter key sequence (i.e., the key that was used to
+ enter the hydra does not have to be pressed again).
+
+ Transient supports that too, but for now this feature is not a
+ focus and the interface is a bit more complicated. A very basic
+ example using the current interface:
+
+ (transient-define-prefix outline-navigate ()
+ :transient-suffix 'transient--do-stay
+ :transient-non-suffix 'transient--do-warn
+ [("p" "previous visible heading" outline-previous-visible-heading)
+ ("n" "next visible heading" outline-next-visible-heading)])
+
+ • Transient supports infix arguments; values that are set by infix
+ commands and then consumed by the invoked suffix command(s).
+
+ To my knowledge, Hydra does not support that.
+
+ Both packages make it possible to specify how exactly the available
+commands are outlined:
+
+ • With Hydra this is often done using an explicit format string,
+ which gives authors a lot of flexibility and makes it possible to
+ do fancy things.
+
+ The downside of this is that it becomes harder for a user to add
+ additional commands to an existing hydra and to change key
+ bindings.
+
+ • Transient allows the author of a transient to organize the commands
+ into groups and the use of generic functions allows authors of
+ transients to control exactly how a certain command type is
+ displayed.
+
+ However while Transient supports giving sections a heading it does
+ not currently support giving the displayed information more
+ structure by, for example, using box-drawing characters.
+
+ That could be implemented by defining a new group class, which lets
+ the author specify a format string. It should be possible to
+ implement that without modifying any existing code, but it does not
+ currently exist.
+
+
+File: transient.info, Node: FAQ, Next: Keystroke Index, Prev: Related Abstractions and Packages, Up: Top
+
+Appendix A FAQ
+**************
+
+A.1 Can I control how the popup buffer is displayed?
+====================================================
+
+Yes, see ‘transient-display-buffer-action’ in *note Configuration::.
+
+A.2 Why did some of the key bindings change?
+============================================
+
+You may have noticed that the bindings for some of the common commands
+do *not* have the prefix ‘C-x’ and that furthermore some of these
+commands are grayed out while others are not. That unfortunately is a
+bit confusing if the section of common commands is not shown
+permanently, making the following explanation necessary.
+
+ The purpose of usually hiding that section but showing it after the
+user pressed the respective prefix key is to conserve space and not
+overwhelm users with too much noise, while allowing the user to quickly
+list common bindings on demand.
+
+ That however should not keep us from using the best possible key
+bindings. The bindings that do use a prefix do so to avoid wasting too
+many non-prefix bindings, keeping them available for use in individual
+transients. The bindings that do not use a prefix and that are *not*
+grayed out are very important bindings that are *always* available, even
+when invoking the "common command key prefix" or *any other*
+transient-specific prefix. The non-prefix keys that *are* grayed out
+however, are not available when any incomplete prefix key sequence is
+active. They do not use the "common command key prefix" because it is
+likely that users want to invoke them several times in a row and e.g.,
+‘M-p M-p M-p’ is much more convenient than ‘C-x M-p C-x M-p C-x M-p’.
+
+ You may also have noticed that the "Set" command is bound to ‘C-x s’,
+while Magit-Popup used to bind ‘C-c C-c’ instead. I have seen several
+users praise the latter binding (sic), so I did not change it
+willy-nilly. The reason that I changed it is that using different
+prefix keys for different common commands, would have made the temporary
+display of the common commands even more confusing, i.e., after pressing
+‘C-c’ all the ‘C-x ...’ bindings would be grayed out.
+
+ Using a single prefix for common commands key means that all other
+potential prefix keys can be used for transient-specific commands
+*without* the section of common commands also popping up. ‘C-c’ in
+particular is a prefix that I want to (and already do) use for Magit,
+and also using that for a common command would prevent me from doing so.
+
+ (Also see the next question.)
+
+A.3 Why does ‘q’ not quit popups anymore?
+=========================================
+
+I agree that ‘q’ is a good binding for commands that quit something.
+This includes quitting whatever transient is currently active, but it
+also includes quitting whatever it is that some specific transient is
+controlling. The transient ‘magit-blame’ for example binds ‘q’ to the
+command that turns ‘magit-blame-mode’ off.
+
+ So I had to decide if ‘q’ should quit the active transient (like
+Magit-Popup used to) or whether ‘C-g’ should do that instead, so that
+‘q’ could be bound in individual transient to whatever commands make
+sense for them. Because all other letters are already reserved for use
+by individual transients, I have decided to no longer make an exception
+for ‘q’.
+
+ If you want to get ‘q’’s old binding back then you can do so. Doing
+that is a bit more complicated than changing a single key binding, so I
+have implemented a function, ‘transient-bind-q-to-quit’ that makes the
+necessary changes. See its doc string for more information.
+
+
+File: transient.info, Node: Keystroke Index, Next: Command and Function Index, Prev: FAQ, Up: Top
+
+Appendix B Keystroke Index
+**************************
+
+
+* Menu:
+
+* C-g: Aborting and Resuming Transients.
+ (line 27)
+* C-g <1>: Aborting and Resuming Transients.
+ (line 27)
+* C-h: Getting Help for Suffix Commands.
+ (line 11)
+* C-M-n: Using History. (line 18)
+* C-M-p: Using History. (line 13)
+* C-q: Aborting and Resuming Transients.
+ (line 36)
+* C-x C-k: Saving Values. (line 29)
+* C-x C-s: Saving Values. (line 25)
+* C-x l: Enabling and Disabling Suffixes.
+ (line 43)
+* C-x n: Using History. (line 18)
+* C-x p: Using History. (line 13)
+* C-x s: Saving Values. (line 21)
+* C-x t: Common Suffix Commands.
+ (line 18)
+* C-z: Aborting and Resuming Transients.
+ (line 41)
+
+
+File: transient.info, Node: Command and Function Index, Next: Variable Index, Prev: Keystroke Index, Up: Top
+
+Appendix C Command and Function Index
+*************************************
+
+
+* Menu:
+
+* transient--do-call: Transient State. (line 99)
+* transient--do-exit: Transient State. (line 91)
+* transient--do-noop: Transient State. (line 147)
+* transient--do-quit-all: Transient State. (line 158)
+* transient--do-quit-one: Transient State. (line 153)
+* transient--do-recurse: Transient State. (line 106)
+* transient--do-replace: Transient State. (line 118)
+* transient--do-return: Transient State. (line 94)
+* transient--do-stay: Transient State. (line 83)
+* transient--do-suspend: Transient State. (line 125)
+* transient--do-suspend <1>: Transient State. (line 163)
+* transient--do-warn: Transient State. (line 144)
+* transient--history-init: Prefix Classes. (line 10)
+* transient--insert-group: Group Methods. (line 19)
+* transient-append-suffix: Modifying Existing Transients.
+ (line 46)
+* transient-arg-value: Using Infix Arguments.
+ (line 31)
+* transient-args: Using Infix Arguments.
+ (line 22)
+* transient-define-argument: Defining Suffix and Infix Commands.
+ (line 61)
+* transient-define-infix: Defining Suffix and Infix Commands.
+ (line 26)
+* transient-define-prefix: Defining Transients. (line 13)
+* transient-define-suffix: Defining Suffix and Infix Commands.
+ (line 9)
+* transient-format: Suffix Format Methods.
+ (line 6)
+* transient-format-description: Suffix Format Methods.
+ (line 18)
+* transient-format-key: Suffix Format Methods.
+ (line 14)
+* transient-format-value: Suffix Format Methods.
+ (line 22)
+* transient-get-suffix: Modifying Existing Transients.
+ (line 56)
+* transient-help: Getting Help for Suffix Commands.
+ (line 11)
+* transient-history-next: Using History. (line 18)
+* transient-history-prev: Using History. (line 13)
+* transient-infix-read: Suffix Value Methods.
+ (line 16)
+* transient-infix-set: Suffix Value Methods.
+ (line 36)
+* transient-infix-value: Suffix Value Methods.
+ (line 39)
+* transient-init-scope: Suffix Value Methods.
+ (line 52)
+* transient-init-value: Suffix Value Methods.
+ (line 6)
+* transient-insert-suffix: Modifying Existing Transients.
+ (line 42)
+* transient-prompt: Suffix Value Methods.
+ (line 32)
+* transient-quit-all: Aborting and Resuming Transients.
+ (line 36)
+* transient-quit-one: Aborting and Resuming Transients.
+ (line 27)
+* transient-quit-seq: Aborting and Resuming Transients.
+ (line 27)
+* transient-remove-suffix: Modifying Existing Transients.
+ (line 53)
+* transient-replace-suffix: Modifying Existing Transients.
+ (line 49)
+* transient-resume: Aborting and Resuming Transients.
+ (line 53)
+* transient-save: Saving Values. (line 25)
+* transient-save <1>: Saving Values. (line 29)
+* transient-scroll-down: Other Commands. (line 17)
+* transient-scroll-up: Other Commands. (line 12)
+* transient-set: Saving Values. (line 21)
+* transient-set-level: Enabling and Disabling Suffixes.
+ (line 43)
+* transient-setup-children: Group Methods. (line 6)
+* transient-show-help: Suffix Format Methods.
+ (line 26)
+* transient-suffix-put: Modifying Existing Transients.
+ (line 60)
+* transient-suffixes: Using Infix Arguments.
+ (line 38)
+* transient-suspend: Aborting and Resuming Transients.
+ (line 41)
+* transient-toggle-common: Common Suffix Commands.
+ (line 18)
+
+
+File: transient.info, Node: Variable Index, Next: Concept Index, Prev: Command and Function Index, Up: Top
+
+Appendix D Variable Index
+*************************
+
+
+* Menu:
+
+* transient-align-variable-pitch: Configuration. (line 181)
+* transient-current-command: Using Infix Arguments.
+ (line 57)
+* transient-current-prefix: Using Infix Arguments.
+ (line 52)
+* transient-current-suffixes: Using Infix Arguments.
+ (line 44)
+* transient-default-level: Enabling and Disabling Suffixes.
+ (line 33)
+* transient-detect-key-conflicts: Configuration. (line 206)
+* transient-display-buffer-action: Configuration. (line 51)
+* transient-enable-popup-navigation: Configuration. (line 36)
+* transient-force-fixed-pitch: Configuration. (line 194)
+* transient-force-single-column: Configuration. (line 93)
+* transient-hide-during-minibuffer-read: Configuration. (line 177)
+* transient-highlight-higher-levels: Configuration. (line 219)
+* transient-highlight-mismatched-keys: Configuration. (line 131)
+* transient-history-file: Using History. (line 33)
+* transient-history-limit: Using History. (line 37)
+* transient-levels-file: Enabling and Disabling Suffixes.
+ (line 38)
+* transient-mode-line-format: Configuration. (line 102)
+* transient-read-with-initial-input: Configuration. (line 170)
+* transient-semantic-coloring: Configuration. (line 118)
+* transient-show-common-commands: Common Suffix Commands.
+ (line 23)
+* transient-show-popup: Configuration. (line 15)
+* transient-substitute-key-function: Configuration. (line 149)
+* transient-values-file: Saving Values. (line 31)
+
+
+File: transient.info, Node: Concept Index, Prev: Variable Index, Up: Top
+
+Appendix E Concept Index
+************************
+
+
+* Menu:
+
+* aborting transients: Aborting and Resuming Transients.
+ (line 6)
+* classes and methods: Classes and Methods. (line 6)
+* command dispatchers: Introduction. (line 70)
+* common suffix commands: Common Suffix Commands.
+ (line 6)
+* defining infix commands: Defining Suffix and Infix Commands.
+ (line 6)
+* defining suffix commands: Defining Suffix and Infix Commands.
+ (line 6)
+* disabling suffixes: Enabling and Disabling Suffixes.
+ (line 6)
+* enabling suffixes: Enabling and Disabling Suffixes.
+ (line 6)
+* getting help: Getting Help for Suffix Commands.
+ (line 6)
+* group specifications: Group Specifications. (line 6)
+* invoking transients: Invoking Transients. (line 6)
+* levels: Enabling and Disabling Suffixes.
+ (line 10)
+* modifying existing transients: Modifying Existing Transients.
+ (line 6)
+* quit transient: Aborting and Resuming Transients.
+ (line 6)
+* resuming transients: Aborting and Resuming Transients.
+ (line 6)
+* saving values of arguments: Saving Values. (line 6)
+* scope of a transient: Defining Transients. (line 43)
+* suffix specifications: Suffix Specifications.
+ (line 6)
+* transient prefix command: Introduction. (line 13)
+* transient state: Transient State. (line 6)
+* transient-level: Enabling and Disabling Suffixes.
+ (line 15)
+* value history: Using History. (line 6)
+
+
+
+Tag Table:
+Node: Top751
+Node: Introduction3662
+Node: Usage9475
+Node: Invoking Transients9843
+Node: Aborting and Resuming Transients10922
+Node: Common Suffix Commands13529
+Node: Saving Values15363
+Ref: Saving Values-Footnote-116732
+Node: Using History16925
+Node: Getting Help for Suffix Commands18499
+Node: Enabling and Disabling Suffixes19867
+Node: Other Commands22922
+Node: Configuration23898
+Ref: Essential Options24178
+Ref: Accessibility Options27829
+Ref: Auxiliary Options28152
+Ref: Developer Options32871
+Node: Modifying Existing Transients34119
+Node: Defining New Commands37508
+Node: Defining Transients37844
+Node: Binding Suffix and Infix Commands40276
+Node: Group Specifications41130
+Node: Suffix Specifications45473
+Node: Defining Suffix and Infix Commands49731
+Node: Using Infix Arguments52925
+Node: Transient State55753
+Ref: Pre-commands for Infixes59660
+Ref: Pre-commands for Suffixes59931
+Ref: Pre-commands for Non-Suffixes61700
+Ref: Special Pre-Commands62313
+Node: Classes and Methods62821
+Node: Group Classes65035
+Node: Group Methods66951
+Node: Prefix Classes68204
+Node: Suffix Classes69295
+Node: Suffix Methods71539
+Node: Suffix Value Methods71860
+Node: Suffix Format Methods74614
+Node: Prefix Slots76063
+Ref: Internal Prefix Slots77338
+Node: Suffix Slots78595
+Ref: Slots of transient-suffix78963
+Ref: Slots of transient-infix79817
+Ref: Slots of transient-variable82937
+Ref: Slots of transient-switches83039
+Node: Predicate Slots83402
+Node: Related Abstractions and Packages84657
+Node: Comparison With Prefix Keys and Prefix Arguments84944
+Ref: Regular Prefix Commands85629
+Ref: Regular Prefix Arguments85977
+Ref: Transients86946
+Node: Comparison With Other Packages95217
+Ref: Magit-Popup95448
+Ref: Hydra96347
+Node: FAQ99383
+Ref: Can I control how the popup buffer is displayed?99526
+Ref: Why did some of the key bindings change?99707
+Ref: Why does q not quit popups anymore?102025
+Node: Keystroke Index103118
+Node: Command and Function Index104836
+Node: Variable Index111135
+Node: Concept Index113408
+
+End Tag Table
+
+
+Local Variables:
+coding: utf-8
+End:
diff --git a/elpa/use-package-20210207.1926/dir b/elpa/use-package-20210207.1926/dir
new file mode 100644
index 0000000..651b05d
--- /dev/null
+++ b/elpa/use-package-20210207.1926/dir
@@ -0,0 +1,18 @@
+This is the file .../info/dir, which contains the
+topmost node of the Info hierarchy, called (dir)Top.
+The first time you invoke Info you start off looking at this node.
+
+File: dir, Node: Top This is the top of the INFO tree
+
+ This (the Directory node) gives a menu of major topics.
+ Typing "q" exits, "H" lists all Info commands, "d" returns here,
+ "h" gives a primer for first-timers,
+ "mEmacs<Return>" visits the Emacs manual, etc.
+
+ In Emacs, you can click mouse button 2 on a menu item or cross reference
+ to select it.
+
+* Menu:
+
+Emacs
+* use-package: (use-package). Declarative package configuration for Emacs.
diff --git a/elpa/use-package-20210207.1926/use-package-autoloads.el b/elpa/use-package-20210207.1926/use-package-autoloads.el
new file mode 100644
index 0000000..d59e129
--- /dev/null
+++ b/elpa/use-package-20210207.1926/use-package-autoloads.el
@@ -0,0 +1,230 @@
+;;; use-package-autoloads.el --- automatically extracted autoloads -*- lexical-binding: t -*-
+;;
+;;; Code:
+
+(add-to-list 'load-path (directory-file-name
+ (or (file-name-directory #$) (car load-path))))
+
+
+;;;### (autoloads nil "use-package-bind-key" "use-package-bind-key.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from use-package-bind-key.el
+
+(autoload 'use-package-autoload-keymap "use-package-bind-key" "\
+Loads PACKAGE and then binds the key sequence used to invoke
+this function to KEYMAP-SYMBOL. It then simulates pressing the
+same key sequence a again, so that the next key pressed is routed
+to the newly loaded keymap.
+
+This function supports use-package's :bind-keymap keyword. It
+works by binding the given key sequence to an invocation of this
+function for a particular keymap. The keymap is expected to be
+defined by the package. In this way, loading the package is
+deferred until the prefix key sequence is pressed.
+
+\(fn KEYMAP-SYMBOL PACKAGE OVERRIDE)" nil nil)
+
+(autoload 'use-package-normalize-binder "use-package-bind-key" "\
+
+
+\(fn NAME KEYWORD ARGS)" nil nil)
+
+(defalias 'use-package-normalize/:bind 'use-package-normalize-binder)
+
+(defalias 'use-package-normalize/:bind* 'use-package-normalize-binder)
+
+(defalias 'use-package-autoloads/:bind 'use-package-autoloads-mode)
+
+(defalias 'use-package-autoloads/:bind* 'use-package-autoloads-mode)
+
+(autoload 'use-package-handler/:bind "use-package-bind-key" "\
+
+
+\(fn NAME KEYWORD ARGS REST STATE &optional BIND-MACRO)" nil nil)
+
+(defalias 'use-package-normalize/:bind-keymap 'use-package-normalize-binder)
+
+(defalias 'use-package-normalize/:bind-keymap* 'use-package-normalize-binder)
+
+(autoload 'use-package-handler/:bind-keymap "use-package-bind-key" "\
+
+
+\(fn NAME KEYWORD ARGS REST STATE &optional OVERRIDE)" nil nil)
+
+(autoload 'use-package-handler/:bind-keymap* "use-package-bind-key" "\
+
+
+\(fn NAME KEYWORD ARG REST STATE)" nil nil)
+
+(register-definition-prefixes "use-package-bind-key" '("use-package-handler/:bind*"))
+
+;;;***
+
+;;;### (autoloads nil "use-package-core" "use-package-core.el" (0
+;;;;;; 0 0 0))
+;;; Generated autoloads from use-package-core.el
+
+(autoload 'use-package "use-package-core" "\
+Declare an Emacs package by specifying a group of configuration options.
+
+For full documentation, please see the README file that came with
+this file. Usage:
+
+ (use-package package-name
+ [:keyword [option]]...)
+
+:init Code to run before PACKAGE-NAME has been loaded.
+:config Code to run after PACKAGE-NAME has been loaded. Note that
+ if loading is deferred for any reason, this code does not
+ execute until the lazy load has occurred.
+:preface Code to be run before everything except `:disabled'; this
+ can be used to define functions for use in `:if', or that
+ should be seen by the byte-compiler.
+
+:mode Form to be added to `auto-mode-alist'.
+:magic Form to be added to `magic-mode-alist'.
+:magic-fallback Form to be added to `magic-fallback-mode-alist'.
+:interpreter Form to be added to `interpreter-mode-alist'.
+
+:commands Define autoloads for commands that will be defined by the
+ package. This is useful if the package is being lazily
+ loaded, and you wish to conditionally call functions in your
+ `:init' block that are defined in the package.
+:hook Specify hook(s) to attach this package to.
+
+:bind Bind keys, and define autoloads for the bound commands.
+:bind* Bind keys, and define autoloads for the bound commands,
+ *overriding all minor mode bindings*.
+:bind-keymap Bind a key prefix to an auto-loaded keymap defined in the
+ package. This is like `:bind', but for keymaps.
+:bind-keymap* Like `:bind-keymap', but overrides all minor mode bindings
+
+:defer Defer loading of a package -- this is implied when using
+ `:commands', `:bind', `:bind*', `:mode', `:magic', `:hook',
+ `:magic-fallback', or `:interpreter'. This can be an integer,
+ to force loading after N seconds of idle time, if the package
+ has not already been loaded.
+:after Delay the use-package declaration until after the named modules
+ have loaded. Once load, it will be as though the use-package
+ declaration (without `:after') had been seen at that moment.
+:demand Prevent the automatic deferred loading introduced by constructs
+ such as `:bind' (see `:defer' for the complete list).
+
+:if EXPR Initialize and load only if EXPR evaluates to a non-nil value.
+:disabled The package is ignored completely if this keyword is present.
+:defines Declare certain variables to silence the byte-compiler.
+:functions Declare certain functions to silence the byte-compiler.
+:load-path Add to the `load-path' before attempting to load the package.
+:diminish Support for diminish.el (if installed).
+:delight Support for delight.el (if installed).
+:custom Call `custom-set' or `set-default' with each variable
+ definition without modifying the Emacs `custom-file'.
+ (compare with `custom-set-variables').
+:custom-face Call `customize-set-faces' with each face definition.
+:ensure Loads the package using package.el if necessary.
+:pin Pin the package to an archive.
+
+\(fn NAME &rest ARGS)" nil t)
+
+(function-put 'use-package 'lisp-indent-function '1)
+
+(register-definition-prefixes "use-package-core" '("use-package-"))
+
+;;;***
+
+;;;### (autoloads nil "use-package-delight" "use-package-delight.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from use-package-delight.el
+
+(autoload 'use-package-normalize/:delight "use-package-delight" "\
+Normalize arguments to delight.
+
+\(fn NAME KEYWORD ARGS)" nil nil)
+
+(autoload 'use-package-handler/:delight "use-package-delight" "\
+
+
+\(fn NAME KEYWORD ARGS REST STATE)" nil nil)
+
+(register-definition-prefixes "use-package-delight" '("use-package-normalize-delight"))
+
+;;;***
+
+;;;### (autoloads nil "use-package-diminish" "use-package-diminish.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from use-package-diminish.el
+
+(autoload 'use-package-normalize/:diminish "use-package-diminish" "\
+
+
+\(fn NAME KEYWORD ARGS)" nil nil)
+
+(autoload 'use-package-handler/:diminish "use-package-diminish" "\
+
+
+\(fn NAME KEYWORD ARG REST STATE)" nil nil)
+
+(register-definition-prefixes "use-package-diminish" '("use-package-normalize-diminish"))
+
+;;;***
+
+;;;### (autoloads nil "use-package-ensure" "use-package-ensure.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from use-package-ensure.el
+
+(autoload 'use-package-normalize/:ensure "use-package-ensure" "\
+
+
+\(fn NAME KEYWORD ARGS)" nil nil)
+
+(autoload 'use-package-handler/:ensure "use-package-ensure" "\
+
+
+\(fn NAME KEYWORD ENSURE REST STATE)" nil nil)
+
+(register-definition-prefixes "use-package-ensure" '("use-package-"))
+
+;;;***
+
+;;;### (autoloads nil "use-package-jump" "use-package-jump.el" (0
+;;;;;; 0 0 0))
+;;; Generated autoloads from use-package-jump.el
+
+(autoload 'use-package-jump-to-package-form "use-package-jump" "\
+Attempt to find and jump to the `use-package' form that loaded
+PACKAGE. This will only find the form if that form actually
+required PACKAGE. If PACKAGE was previously required then this
+function will jump to the file that originally required PACKAGE
+instead.
+
+\(fn PACKAGE)" t nil)
+
+(register-definition-prefixes "use-package-jump" '("use-package-find-require"))
+
+;;;***
+
+;;;### (autoloads nil "use-package-lint" "use-package-lint.el" (0
+;;;;;; 0 0 0))
+;;; Generated autoloads from use-package-lint.el
+
+(autoload 'use-package-lint "use-package-lint" "\
+Check for errors in use-package declarations.
+For example, if the module's `:if' condition is met, but even
+with the specified `:load-path' the module cannot be found." t nil)
+
+(register-definition-prefixes "use-package-lint" '("use-package-lint-declaration"))
+
+;;;***
+
+;;;### (autoloads nil nil ("use-package-pkg.el" "use-package.el")
+;;;;;; (0 0 0 0))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; coding: utf-8
+;; End:
+;;; use-package-autoloads.el ends here
diff --git a/elpa/use-package-20210207.1926/use-package-bind-key.el b/elpa/use-package-20210207.1926/use-package-bind-key.el
new file mode 100644
index 0000000..e476b06
--- /dev/null
+++ b/elpa/use-package-20210207.1926/use-package-bind-key.el
@@ -0,0 +1,172 @@
+;;; use-package-bind-key.el --- Support for the :bind/:bind-keymap keywords -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2012-2017 John Wiegley
+
+;; Author: John Wiegley <johnw@newartisans.com>
+;; Maintainer: John Wiegley <johnw@newartisans.com>
+;; Created: 17 Jun 2012
+;; Modified: 4 Dec 2017
+;; Version: 1.0
+;; Package-Requires: ((emacs "24.3") (use-package "2.4") (bind-key "2.4"))
+;; Keywords: dotemacs startup speed config package
+;; URL: https://github.com/jwiegley/use-package
+
+;; 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 GNU Emacs; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;; Commentary:
+
+;; Provides support for the :bind, :bind*, :bind-keymap and :bind-keymap*
+;; keywords. Note that these are currently still baked into
+;; `use-package-keywords' and `use-package-deferring-keywords', although this
+;; is harmless if they are never used.
+
+;;; Code:
+
+(require 'use-package-core)
+(require 'bind-key)
+
+;;;###autoload
+(defun use-package-autoload-keymap (keymap-symbol package override)
+ "Loads PACKAGE and then binds the key sequence used to invoke
+this function to KEYMAP-SYMBOL. It then simulates pressing the
+same key sequence a again, so that the next key pressed is routed
+to the newly loaded keymap.
+
+This function supports use-package's :bind-keymap keyword. It
+works by binding the given key sequence to an invocation of this
+function for a particular keymap. The keymap is expected to be
+defined by the package. In this way, loading the package is
+deferred until the prefix key sequence is pressed."
+ (if (not (require package nil t))
+ (use-package-error (format "Cannot load package.el: %s" package))
+ (if (and (boundp keymap-symbol)
+ (keymapp (symbol-value keymap-symbol)))
+ (let* ((kv (this-command-keys-vector))
+ (key (key-description kv))
+ (keymap (symbol-value keymap-symbol)))
+ (if override
+ (bind-key* key keymap)
+ (bind-key key keymap))
+ (setq unread-command-events
+ (mapcar (lambda (ev) (cons t ev))
+ (listify-key-sequence kv))))
+ (use-package-error
+ (format "package.el %s failed to define keymap %s"
+ package keymap-symbol)))))
+
+;;;###autoload
+(defun use-package-normalize-binder (name keyword args)
+ (let ((arg args)
+ args*)
+ (while arg
+ (let ((x (car arg)))
+ (cond
+ ;; (KEY . COMMAND)
+ ((and (consp x)
+ (or (stringp (car x))
+ (vectorp (car x)))
+ (or (use-package-recognize-function (cdr x) t #'stringp)))
+ (setq args* (nconc args* (list x)))
+ (setq arg (cdr arg)))
+ ;; KEYWORD
+ ;; :map KEYMAP
+ ;; :prefix-docstring STRING
+ ;; :prefix-map SYMBOL
+ ;; :prefix STRING
+ ;; :filter SEXP
+ ;; :menu-name STRING
+ ;; :package SYMBOL
+ ((or (and (eq x :map) (symbolp (cadr arg)))
+ (and (eq x :prefix) (stringp (cadr arg)))
+ (and (eq x :prefix-map) (symbolp (cadr arg)))
+ (and (eq x :prefix-docstring) (stringp (cadr arg)))
+ (eq x :filter)
+ (and (eq x :menu-name) (stringp (cadr arg)))
+ (and (eq x :package) (symbolp (cadr arg))))
+ (setq args* (nconc args* (list x (cadr arg))))
+ (setq arg (cddr arg)))
+ ((listp x)
+ (setq args*
+ (nconc args* (use-package-normalize-binder name keyword x)))
+ (setq arg (cdr arg)))
+ (t
+ ;; Error!
+ (use-package-error
+ (concat (symbol-name name)
+ " wants arguments acceptable to the `bind-keys' macro,"
+ " or a list of such values"))))))
+ args*))
+
+;;;; :bind, :bind*
+
+;;;###autoload
+(defalias 'use-package-normalize/:bind 'use-package-normalize-binder)
+;;;###autoload
+(defalias 'use-package-normalize/:bind* 'use-package-normalize-binder)
+
+;; jww (2017-12-07): This is too simplistic. It will fail to determine
+;; autoloads in this situation:
+;; (use-package foo
+;; :bind (:map foo-map (("C-a" . func))))
+;;;###autoload
+(defalias 'use-package-autoloads/:bind 'use-package-autoloads-mode)
+;;;###autoload
+(defalias 'use-package-autoloads/:bind* 'use-package-autoloads-mode)
+
+;;;###autoload
+(defun use-package-handler/:bind
+ (name _keyword args rest state &optional bind-macro)
+ (use-package-concat
+ (use-package-process-keywords name rest state)
+ `(,@(mapcar
+ #'(lambda (xs)
+ `(,(if bind-macro bind-macro 'bind-keys)
+ :package ,name ,@(use-package-normalize-commands xs)))
+ (use-package-split-list-at-keys :break args)))))
+
+(defun use-package-handler/:bind* (name keyword arg rest state)
+ (use-package-handler/:bind name keyword arg rest state 'bind-keys*))
+
+;;;; :bind-keymap, :bind-keymap*
+
+;;;###autoload
+(defalias 'use-package-normalize/:bind-keymap 'use-package-normalize-binder)
+;;;###autoload
+(defalias 'use-package-normalize/:bind-keymap* 'use-package-normalize-binder)
+
+;;;###autoload
+(defun use-package-handler/:bind-keymap
+ (name _keyword args rest state &optional override)
+ (use-package-concat
+ (use-package-process-keywords name rest state)
+ (mapcar
+ #'(lambda (binding)
+ `(,(if override 'bind-key* 'bind-key)
+ ,(car binding)
+ #'(lambda ()
+ (interactive)
+ (use-package-autoload-keymap
+ ',(cdr binding) ',(use-package-as-symbol name)
+ ,override))))
+ args)))
+
+;;;###autoload
+(defun use-package-handler/:bind-keymap* (name keyword arg rest state)
+ (use-package-handler/:bind-keymap name keyword arg rest state t))
+
+(provide 'use-package-bind-key)
+
+;;; use-package-bind-key.el ends here
diff --git a/elpa/use-package-20210207.1926/use-package-bind-key.elc b/elpa/use-package-20210207.1926/use-package-bind-key.elc
new file mode 100644
index 0000000..f0e0208
--- /dev/null
+++ b/elpa/use-package-20210207.1926/use-package-bind-key.elc
Binary files differ
diff --git a/elpa/use-package-20210207.1926/use-package-core.el b/elpa/use-package-20210207.1926/use-package-core.el
new file mode 100644
index 0000000..28bc5a5
--- /dev/null
+++ b/elpa/use-package-20210207.1926/use-package-core.el
@@ -0,0 +1,1633 @@
+;;; use-package-core.el --- A configuration macro for simplifying your .emacs -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2012-2017 John Wiegley
+
+;; Author: John Wiegley <johnw@newartisans.com>
+;; Maintainer: John Wiegley <johnw@newartisans.com>
+;; Created: 17 Jun 2012
+;; Modified: 29 Nov 2017
+;; Version: 2.4.1
+;; Package-Requires: ((emacs "24.3"))
+;; Keywords: dotemacs startup speed config package
+;; URL: https://github.com/jwiegley/use-package
+
+;; 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 GNU Emacs; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;; Commentary:
+
+;; The `use-package' declaration macro allows you to isolate package
+;; configuration in your ".emacs" in a way that is performance-oriented and,
+;; well, just tidy. I created it because I have over 80 packages that I use
+;; in Emacs, and things were getting difficult to manage. Yet with this
+;; utility my total load time is just under 1 second, with no loss of
+;; functionality!
+;;
+;; Please see README.md from the same repository for documentation.
+
+;;; Code:
+
+(require 'bytecomp)
+(require 'cl-lib)
+(require 'tabulated-list)
+
+(eval-and-compile
+ ;; Declare a synthetic theme for :custom variables.
+ ;; Necessary in order to avoid having those variables saved by custom.el.
+ (deftheme use-package))
+
+(enable-theme 'use-package)
+;; Remove the synthetic use-package theme from the enabled themes, so
+;; iterating over them to "disable all themes" won't disable it.
+(setq custom-enabled-themes (remq 'use-package custom-enabled-themes))
+
+(if (and (eq emacs-major-version 24) (eq emacs-minor-version 3))
+ (defsubst hash-table-keys (hash-table)
+ "Return a list of keys in HASH-TABLE."
+ (cl-loop for k being the hash-keys of hash-table collect k))
+ (eval-when-compile (require 'subr-x)))
+
+(eval-when-compile
+ (require 'regexp-opt))
+
+(defgroup use-package nil
+ "A use-package declaration for simplifying your `.emacs'."
+ :group 'startup)
+
+(defconst use-package-version "2.4.1"
+ "This version of use-package.")
+
+(defcustom use-package-keywords
+ '(:disabled
+ :load-path
+ :requires
+ :defines
+ :functions
+ :preface
+ :if :when :unless
+ :no-require
+ :catch
+ :after
+ :custom
+ :custom-face
+ :bind
+ :bind*
+ :bind-keymap
+ :bind-keymap*
+ :interpreter
+ :mode
+ :magic
+ :magic-fallback
+ :hook
+ ;; Any other keyword that also declares commands to be autoloaded (such as
+ ;; :bind) must appear before this keyword.
+ :commands
+ :init
+ :defer
+ :demand
+ :load
+ ;; This must occur almost last; the only forms which should appear after
+ ;; are those that must happen directly after the config forms.
+ :config)
+ "The set of valid keywords, in the order they are processed in.
+The order of this list is *very important*, so it is only
+advisable to insert new keywords, never to delete or reorder
+them. Further, attention should be paid to the NEWS.md if the
+default order ever changes, as they may have subtle effects on
+the semantics of use-package declarations and may necessitate
+changing where you had inserted a new keyword earlier.
+
+Note that `:disabled' is special in this list, as it causes
+nothing at all to happen, even if the rest of the use-package
+declaration is incorrect."
+ :type '(repeat symbol)
+ :group 'use-package)
+
+(defcustom use-package-deferring-keywords
+ '(:bind-keymap
+ :bind-keymap*
+ :commands)
+ "Unless `:demand' is used, keywords in this list imply deferred loading.
+The reason keywords like `:hook' are not in this list is that
+they only imply deferred loading if they reference actual
+function symbols that can be autoloaded from the module; whereas
+the default keywords provided here always defer loading unless
+otherwise requested."
+ :type '(repeat symbol)
+ :group 'use-package)
+
+(defcustom use-package-ignore-unknown-keywords nil
+ "If non-nil, issue warning instead of error when unknown
+keyword is encountered. The unknown keyword and its associated
+arguments will be ignored in the `use-package' expansion."
+ :type 'boolean
+ :group 'use-package)
+
+(defcustom use-package-use-theme t
+ "If non-nil, use a custom theme to avoid saving :custom
+variables twice (once in the Custom file, once in the use-package
+call)."
+ :type 'boolean
+ :group 'use-package)
+
+(defcustom use-package-verbose nil
+ "Whether to report about loading and configuration details.
+If you customize this, then you should require the `use-package'
+feature in files that use `use-package', even if these files only
+contain compiled expansions of the macros. If you don't do so,
+then the expanded macros do their job silently."
+ :type '(choice (const :tag "Quiet, without catching errors" errors)
+ (const :tag "Quiet" nil)
+ (const :tag "Verbose" t)
+ (const :tag "Debug" debug))
+ :group 'use-package)
+
+(defcustom use-package-check-before-init nil
+ "If non-nil, check that package exists before executing its `:init' block.
+This check is performed by calling `locate-library'."
+ :type 'boolean
+ :group 'use-package)
+
+(defcustom use-package-always-defer nil
+ "If non-nil, assume `:defer t' unless `:demand' is used.
+See also `use-package-defaults', which uses this value."
+ :type 'boolean
+ :group 'use-package)
+
+(defcustom use-package-always-demand nil
+ "If non-nil, assume `:demand t' unless `:defer' is used.
+See also `use-package-defaults', which uses this value."
+ :type 'boolean
+ :group 'use-package)
+
+(defcustom use-package-defaults
+ '(;; this '(t) has special meaning; see `use-package-handler/:config'
+ (:config '(t) t)
+ (:init nil t)
+ (:catch t (lambda (name args)
+ (not use-package-expand-minimally)))
+ (:defer use-package-always-defer
+ (lambda (name args)
+ (and use-package-always-defer
+ (not (plist-member args :defer))
+ (not (plist-member args :demand)))))
+ (:demand use-package-always-demand
+ (lambda (name args)
+ (and use-package-always-demand
+ (not (plist-member args :defer))
+ (not (plist-member args :demand))))))
+ "Default values for specified `use-package' keywords.
+Each entry in the alist is a list of three elements:
+The first element is the `use-package' keyword.
+
+The second is a form that can be evaluated to get the default
+value. It can also be a function that will receive the name of
+the use-package declaration and the keyword plist given to
+`use-package', in normalized form. The value it returns should
+also be in normalized form (which is sometimes *not* what one
+would normally write in a `use-package' declaration, so use
+caution).
+
+The third element is a form that can be evaluated to determine
+whether or not to assign a default value; if it evaluates to nil,
+then the default value is not assigned even if the keyword is not
+present in the `use-package' form. This third element may also be
+a function, in which case it receives the name of the package (as
+a symbol) and a list of keywords (in normalized form). It should
+return nil or non-nil depending on whether defaulting should be
+attempted."
+ :type `(repeat
+ (list (choice :tag "Keyword"
+ ,@(mapcar #'(lambda (k) (list 'const k))
+ use-package-keywords))
+ (choice :tag "Default value" sexp function)
+ (choice :tag "Enable if non-nil" sexp function)))
+ :group 'use-package)
+
+(defcustom use-package-merge-key-alist
+ '((:if . (lambda (new old) `(and ,new ,old)))
+ (:after . (lambda (new old) `(:all ,new ,old)))
+ (:defer . (lambda (new old) old))
+ (:bind . (lambda (new old) (append new (list :break) old))))
+ "Alist of keys and the functions used to merge multiple values.
+For example, if the following form is provided:
+
+ (use-package foo :if pred1 :if pred2)
+
+Then based on the above defaults, the merged result will be:
+
+ (use-package foo :if (and pred1 pred2))
+
+This is done so that, at the stage of invoking handlers, each
+handler is called only once."
+ :type `(repeat
+ (cons (choice :tag "Keyword"
+ ,@(mapcar #'(lambda (k) (list 'const k))
+ use-package-keywords)
+ (const :tag "Any" t))
+ function))
+ :group 'use-package)
+
+(defcustom use-package-hook-name-suffix "-hook"
+ "Text append to the name of hooks mentioned by :hook.
+Set to nil if you don't want this to happen; it's only a
+convenience."
+ :type '(choice string (const :tag "No suffix" nil))
+ :group 'use-package)
+
+(defcustom use-package-minimum-reported-time 0.1
+ "Minimal load time that will be reported.
+Note that `use-package-verbose' has to be set to a non-nil value
+for anything to be reported at all."
+ :type 'number
+ :group 'use-package)
+
+(defcustom use-package-inject-hooks nil
+ "If non-nil, add hooks to the `:init' and `:config' sections.
+In particular, for a given package `foo', the following hooks
+become available:
+
+ `use-package--foo--pre-init-hook'
+ `use-package--foo--post-init-hook'
+ `use-package--foo--pre-config-hook'
+ `use-package--foo--post-config-hook'
+
+This way, you can add to these hooks before evaluation of a
+`use-package` declaration, and exercise some control over what
+happens.
+
+NOTE: These hooks are run even if the user does not specify an
+`:init' or `:config' block, and they will happen at the regular
+time when initialization and configuration would have been
+performed.
+
+NOTE: If the `pre-init' hook return a nil value, that block's
+user-supplied configuration is not evaluated, so be certain to
+return t if you only wish to add behavior to what the user had
+specified."
+ :type 'boolean
+ :group 'use-package)
+
+(defcustom use-package-expand-minimally nil
+ "If non-nil, make the expanded code as minimal as possible.
+This disables:
+
+ - Printing to the *Messages* buffer of slowly-evaluating forms
+ - Capturing of load errors (normally redisplayed as warnings)
+ - Conditional loading of packages (load failures become errors)
+
+The main advantage to this variable is that, if you know your
+configuration works, it will make the byte-compiled file as
+minimal as possible. It can also help with reading macro-expanded
+definitions, to understand the main intent of what's happening."
+ :type 'boolean
+ :group 'use-package)
+
+(defcustom use-package-form-regexp-eval
+ `(concat ,(eval-when-compile
+ (concat "^\\s-*("
+ (regexp-opt '("use-package" "require") t)
+ "\\s-+\\("))
+ (or (bound-and-true-p lisp-mode-symbol-regexp)
+ "\\(?:\\sw\\|\\s_\\|\\\\.\\)+") "\\)")
+ "Sexp providing regexp for finding use-package forms in user files.
+This is used by `use-package-jump-to-package-form' and
+`use-package-enable-imenu-support'."
+ :type 'sexp
+ :group 'use-package)
+
+(defcustom use-package-enable-imenu-support nil
+ "If non-nil, cause imenu to see `use-package' declarations.
+This is done by adjusting `lisp-imenu-generic-expression' to
+include support for finding `use-package' and `require' forms.
+
+Must be set before loading use-package."
+ :type 'boolean
+ :set
+ #'(lambda (_sym value)
+ (eval-after-load 'lisp-mode
+ (if value
+ `(add-to-list 'lisp-imenu-generic-expression
+ (list "Packages" ,use-package-form-regexp-eval 2))
+ `(setq lisp-imenu-generic-expression
+ (remove (list "Packages" ,use-package-form-regexp-eval 2)
+ lisp-imenu-generic-expression)))))
+ :group 'use-package)
+
+(defconst use-package-font-lock-keywords
+ '(("(\\(use-package\\)\\_>[ \t']*\\(\\(?:\\sw\\|\\s_\\)+\\)?"
+ (1 font-lock-keyword-face)
+ (2 font-lock-constant-face nil t))))
+
+(font-lock-add-keywords 'emacs-lisp-mode use-package-font-lock-keywords)
+
+(defcustom use-package-compute-statistics nil
+ "If non-nil, compute statistics concerned use-package declarations.
+View the statistical report using `use-package-report'. Note that
+if this option is enabled, you must require `use-package' in your
+user init file at loadup time, or you will see errors concerning
+undefined variables."
+ :type 'boolean
+ :group 'use-package)
+
+(defvar use-package-statistics (make-hash-table))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Utility functions
+;;
+
+(defsubst use-package-error (msg)
+ "Report MSG as an error, so the user knows it came from this package."
+ (error "use-package: %s" msg))
+
+(defsubst use-package-concat (&rest elems)
+ "Delete all empty lists from ELEMS (nil or (list nil)), and append them."
+ (apply #'append (delete nil (delete (list nil) elems))))
+
+(defsubst use-package-non-nil-symbolp (sym)
+ (and sym (symbolp sym)))
+
+(defsubst use-package-as-symbol (string-or-symbol)
+ "If STRING-OR-SYMBOL is already a symbol, return it. Otherwise
+convert it to a symbol and return that."
+ (if (symbolp string-or-symbol) string-or-symbol
+ (intern string-or-symbol)))
+
+(defsubst use-package-as-string (string-or-symbol)
+ "If STRING-OR-SYMBOL is already a string, return it. Otherwise
+convert it to a string and return that."
+ (if (stringp string-or-symbol) string-or-symbol
+ (symbol-name string-or-symbol)))
+
+(defsubst use-package-regex-p (re)
+ "Return t if RE is some regexp-like thing."
+ (or (and (listp re) (eq (car re) 'rx))
+ (stringp re)))
+
+(defun use-package-normalize-regex (re)
+ "Given some regexp-like thing in RE, resolve to a regular expression."
+ (cond
+ ((and (listp re) (eq (car re) 'rx)) (eval re))
+ ((stringp re) re)
+ (t (error "Not recognized as regular expression: %s" re))))
+
+(defsubst use-package-is-pair (x car-pred cdr-pred)
+ "Return non-nil if X is a cons satisfying the given predicates.
+CAR-PRED and CDR-PRED are applied to X's `car' and `cdr',
+respectively."
+ (and (consp x)
+ (funcall car-pred (car x))
+ (funcall cdr-pred (cdr x))))
+
+(defun use-package-as-mode (string-or-symbol)
+ "If STRING-OR-SYMBOL ends in `-mode' (or its name does), return
+it as a symbol. Otherwise, return it as a symbol with `-mode'
+appended."
+ (let ((string (use-package-as-string string-or-symbol)))
+ (intern (if (string-match "-mode\\'" string)
+ string
+ (concat string "-mode")))))
+
+(defsubst use-package-load-name (name &optional noerror)
+ "Return a form which will load or require NAME.
+It does the right thing no matter if NAME is a string or symbol.
+Argument NOERROR means to indicate load failures as a warning."
+ (if (stringp name)
+ `(load ,name ,noerror)
+ `(require ',name nil ,noerror)))
+
+(defun use-package-hook-injector (name-string keyword body)
+ "Wrap pre/post hook injections around the given BODY for KEYWORD.
+The BODY is a list of forms, so `((foo))' if only `foo' is being called."
+ (if (not use-package-inject-hooks)
+ body
+ (let ((keyword-name (substring (format "%s" keyword) 1)))
+ `((when (run-hook-with-args-until-failure
+ ',(intern (concat "use-package--" name-string
+ "--pre-" keyword-name "-hook")))
+ ,@body
+ (run-hooks
+ ',(intern (concat "use-package--" name-string
+ "--post-" keyword-name "-hook"))))))))
+
+(defun use-package-with-elapsed-timer (text body)
+ "BODY is a list of forms, so `((foo))' if only `foo' is being called."
+ (declare (indent 1))
+ (if use-package-expand-minimally
+ body
+ (let ((nowvar (make-symbol "now")))
+ (if (bound-and-true-p use-package-verbose)
+ `((let ((,nowvar (current-time)))
+ (message "%s..." ,text)
+ (prog1
+ ,(macroexp-progn body)
+ (let ((elapsed
+ (float-time (time-subtract (current-time) ,nowvar))))
+ (if (> elapsed ,use-package-minimum-reported-time)
+ (message "%s...done (%.3fs)" ,text elapsed)
+ (message "%s...done" ,text))))))
+ body))))
+
+(put 'use-package-with-elapsed-timer 'lisp-indent-function 1)
+
+(defun use-package-require (name &optional no-require body)
+ (if use-package-expand-minimally
+ (use-package-concat
+ (unless no-require
+ (list (use-package-load-name name)))
+ body)
+ (if no-require
+ body
+ (use-package-with-elapsed-timer
+ (format "Loading package %s" name)
+ `((if (not ,(use-package-load-name name t))
+ (display-warning 'use-package
+ (format "Cannot load %s" ',name)
+ :error)
+ ,@body))))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Property lists
+;;
+
+(defun use-package-plist-delete (plist property)
+ "Delete PROPERTY from PLIST.
+This is in contrast to merely setting it to 0."
+ (let (p)
+ (while plist
+ (if (not (eq property (car plist)))
+ (setq p (plist-put p (car plist) (nth 1 plist))))
+ (setq plist (cddr plist)))
+ p))
+
+(defun use-package-plist-delete-first (plist property)
+ "Delete PROPERTY from PLIST.
+This is in contrast to merely setting it to 0."
+ (let (p)
+ (while plist
+ (if (eq property (car plist))
+ (setq p (nconc p (cddr plist))
+ plist nil)
+ (setq p (nconc p (list (car plist) (cadr plist)))
+ plist (cddr plist))))
+ p))
+
+(defsubst use-package-plist-maybe-put (plist property value)
+ "Add a VALUE for PROPERTY to PLIST, if it does not already exist."
+ (if (plist-member plist property)
+ plist
+ (plist-put plist property value)))
+
+(defsubst use-package-plist-cons (plist property value)
+ "Cons VALUE onto the head of the list at PROPERTY in PLIST."
+ (plist-put plist property (cons value (plist-get plist property))))
+
+(defsubst use-package-plist-append (plist property value)
+ "Append VALUE onto the front of the list at PROPERTY in PLIST."
+ (plist-put plist property (append value (plist-get plist property))))
+
+(defun use-package-split-list (pred xs)
+ (let ((ys (list nil)) (zs (list nil)) flip)
+ (cl-dolist (x xs)
+ (if flip
+ (nconc zs (list x))
+ (if (funcall pred x)
+ (progn
+ (setq flip t)
+ (nconc zs (list x)))
+ (nconc ys (list x)))))
+ (cons (cdr ys) (cdr zs))))
+
+(defun use-package-split-list-at-keys (key lst)
+ (and lst
+ (let ((xs (use-package-split-list (apply-partially #'eq key) lst)))
+ (cons (car xs) (use-package-split-list-at-keys key (cddr xs))))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Keywords
+;;
+
+(defun use-package-keyword-index (keyword)
+ (cl-loop named outer
+ with index = 0
+ for k in use-package-keywords do
+ (if (eq k keyword)
+ (cl-return-from outer index))
+ (cl-incf index)))
+
+(defun use-package-normalize-plist (name input &optional plist merge-function)
+ "Given a pseudo-plist, normalize it to a regular plist.
+The normalized key/value pairs from input are added to PLIST,
+extending any keys already present."
+ (if (null input)
+ plist
+ (let* ((keyword (car input))
+ (xs (use-package-split-list #'keywordp (cdr input)))
+ (args (car xs))
+ (tail (cdr xs))
+ (normalizer
+ (intern-soft (concat "use-package-normalize/"
+ (symbol-name keyword))))
+ (arg (and (functionp normalizer)
+ (funcall normalizer name keyword args)))
+ (error-string (format "Unrecognized keyword: %s" keyword)))
+ (if (memq keyword use-package-keywords)
+ (progn
+ (setq plist (use-package-normalize-plist
+ name tail plist merge-function))
+ (plist-put plist keyword
+ (if (plist-member plist keyword)
+ (funcall merge-function keyword arg
+ (plist-get plist keyword))
+ arg)))
+ (if use-package-ignore-unknown-keywords
+ (progn
+ (display-warning 'use-package error-string)
+ (use-package-normalize-plist
+ name tail plist merge-function))
+ (use-package-error error-string))))))
+
+(defun use-package-unalias-keywords (_name args)
+ (setq args (cl-nsubstitute :if :when args))
+ (let (temp)
+ (while (setq temp (plist-get args :unless))
+ (setq args (use-package-plist-delete-first args :unless)
+ args (append args `(:if (not ,temp))))))
+ args)
+
+(defun use-package-merge-keys (key new old)
+ (let ((merger (assq key use-package-merge-key-alist)))
+ (if merger
+ (funcall (cdr merger) new old)
+ (append new old))))
+
+(defun use-package-sort-keywords (plist)
+ (let (plist-grouped)
+ (while plist
+ (push (cons (car plist) (cadr plist))
+ plist-grouped)
+ (setq plist (cddr plist)))
+ (let (result)
+ (cl-dolist
+ (x
+ (nreverse
+ (sort plist-grouped
+ #'(lambda (l r) (< (use-package-keyword-index (car l))
+ (use-package-keyword-index (car r)))))))
+ (setq result (cons (car x) (cons (cdr x) result))))
+ result)))
+
+(defun use-package-normalize-keywords (name args)
+ (let* ((name-symbol (if (stringp name) (intern name) name))
+ (name-string (symbol-name name-symbol)))
+
+ ;; The function `elisp--local-variables' inserts this unbound variable into
+ ;; macro forms to determine the locally bound variables for
+ ;; `elisp-completion-at-point'. It ends up throwing a lot of errors since it
+ ;; can occupy the position of a keyword (or look like a second argument to a
+ ;; keyword that takes one). Deleting it when it's at the top level should be
+ ;; harmless since there should be no locally bound variables to discover
+ ;; here anyway.
+ (setq args (delq 'elisp--witness--lisp args))
+
+ ;; Reduce the set of keywords down to its most fundamental expression.
+ (setq args (use-package-unalias-keywords name-symbol args))
+
+ ;; Normalize keyword values, coalescing multiple occurrences.
+ (setq args (use-package-normalize-plist name-symbol args nil
+ #'use-package-merge-keys))
+
+ ;; Add default values for keywords not specified, when applicable.
+ (cl-dolist (spec use-package-defaults)
+ (when (let ((func (nth 2 spec)))
+ (if (and func (functionp func))
+ (funcall func name args)
+ (eval func)))
+ (setq args (use-package-plist-maybe-put
+ args (nth 0 spec)
+ (let ((func (nth 1 spec)))
+ (if (and func (functionp func))
+ (funcall func name args)
+ (eval func)))))))
+
+ ;; Determine any autoloads implied by the keywords used.
+ (let ((iargs args)
+ commands)
+ (while iargs
+ (when (keywordp (car iargs))
+ (let ((autoloads
+ (intern-soft (concat "use-package-autoloads/"
+ (symbol-name (car iargs))))))
+ (when (functionp autoloads)
+ (setq commands
+ ;; jww (2017-12-07): Right now we just ignored the type of
+ ;; the autoload being requested, and assume they are all
+ ;; `command'.
+ (append (mapcar
+ #'car
+ (funcall autoloads name-symbol (car iargs)
+ (cadr iargs)))
+ commands)))))
+ (setq iargs (cddr iargs)))
+ (when commands
+ (setq args
+ ;; Like `use-package-plist-append', but removing duplicates.
+ (plist-put args :commands
+ (delete-dups
+ (append commands (plist-get args :commands)))))))
+
+ ;; If byte-compiling, pre-load the package so all its symbols are in
+ ;; scope. This is done by prepending statements to the :preface.
+ (when (bound-and-true-p byte-compile-current-file)
+ (setq args
+ (use-package-plist-append
+ args :preface
+ (use-package-concat
+ (mapcar #'(lambda (var) `(defvar ,var))
+ (plist-get args :defines))
+ (mapcar #'(lambda (fn) `(declare-function ,fn ,name-string))
+ (plist-get args :functions))
+ `((eval-when-compile
+ (with-demoted-errors
+ ,(format "Cannot load %s: %%S" name-string)
+ ,(when (eq use-package-verbose 'debug)
+ `(message ,(format "Compiling package %s" name-string)))
+ ,(unless (plist-get args :no-require)
+ `(unless (featurep ',name-symbol)
+ (load ,name-string nil t))))))))))
+
+ ;; Certain keywords imply :defer, if :demand was not specified.
+ (when (and (not (plist-member args :demand))
+ (not (plist-member args :defer))
+ (not (or (equal '(t) (plist-get args :load))
+ (equal (list (use-package-as-string name))
+ (mapcar #'use-package-as-string
+ (plist-get args :load)))))
+ (cl-some #'identity
+ (mapcar (apply-partially #'plist-member args)
+ use-package-deferring-keywords)))
+ (setq args (append args '(:defer t))))
+
+ ;; The :load keyword overrides :no-require
+ (when (and (plist-member args :load)
+ (plist-member args :no-require))
+ (setq args (use-package-plist-delete args :no-require)))
+
+ ;; If at this point no :load, :defer or :no-require has been seen, then
+ ;; :load the package itself.
+ (when (and (not (plist-member args :load))
+ (not (plist-member args :defer))
+ (not (plist-member args :no-require)))
+ (setq args (append args `(:load (,name)))))
+
+ ;; Sort the list of keywords based on the order of `use-package-keywords'.
+ (use-package-sort-keywords args)))
+
+(defun use-package-process-keywords (name plist &optional state)
+ "Process the next keyword in the free-form property list PLIST.
+The values in the PLIST have each been normalized by the function
+use-package-normalize/KEYWORD (minus the colon).
+
+STATE is a property list that the function may modify and/or
+query. This is useful if a package defines multiple keywords and
+wishes them to have some kind of stateful interaction.
+
+Unless the KEYWORD being processed intends to ignore remaining
+keywords, it must call this function recursively, passing in the
+plist with its keyword and argument removed, and passing in the
+next value for the STATE."
+ (declare (indent 1))
+ (unless (null plist)
+ (let* ((keyword (car plist))
+ (arg (cadr plist))
+ (rest (cddr plist)))
+ (unless (keywordp keyword)
+ (use-package-error (format "%s is not a keyword" keyword)))
+ (let* ((handler (concat "use-package-handler/" (symbol-name keyword)))
+ (handler-sym (intern handler)))
+ (if (functionp handler-sym)
+ (funcall handler-sym name keyword arg rest state)
+ (use-package-error
+ (format "Keyword handler not defined: %s" handler)))))))
+
+(put 'use-package-process-keywords 'lisp-indent-function 'defun)
+
+(defun use-package-list-insert (elem xs &optional anchor after test)
+ "Insert ELEM into the list XS.
+If ANCHOR is also a keyword, place the new KEYWORD before that
+one.
+If AFTER is non-nil, insert KEYWORD either at the end of the
+keywords list, or after the ANCHOR if one has been provided.
+If TEST is non-nil, it is the test used to compare ELEM to list
+elements. The default is `eq'.
+The modified list is returned. The original list is not modified."
+ (let (result)
+ (dolist (k xs)
+ (if (funcall (or test #'eq) k anchor)
+ (if after
+ (setq result (cons k result)
+ result (cons elem result))
+ (setq result (cons elem result)
+ result (cons k result)))
+ (setq result (cons k result))))
+ (if anchor
+ (nreverse result)
+ (if after
+ (nreverse (cons elem result))
+ (cons elem (nreverse result))))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Argument Processing
+;;
+
+(defun use-package-only-one (label args f)
+ "Call F on the first member of ARGS if it has exactly one element."
+ (declare (indent 1))
+ (cond
+ ((and (listp args) (listp (cdr args))
+ (= (length args) 1))
+ (funcall f label (car args)))
+ (t
+ (use-package-error
+ (concat label " wants exactly one argument")))))
+
+(put 'use-package-only-one 'lisp-indent-function 'defun)
+
+(defun use-package-as-one (label args f &optional allow-empty)
+ "Call F on the first element of ARGS if it has one element, or all of ARGS.
+If ALLOW-EMPTY is non-nil, it's OK for ARGS to be an empty list."
+ (declare (indent 1))
+ (if (if args
+ (and (listp args) (listp (cdr args)))
+ allow-empty)
+ (if (= (length args) 1)
+ (funcall f label (car args))
+ (funcall f label args))
+ (use-package-error
+ (concat label " wants a non-empty list"))))
+
+(put 'use-package-as-one 'lisp-indent-function 'defun)
+
+(defun use-package-memoize (f arg)
+ "Ensure the macro-expansion of F applied to ARG evaluates ARG
+no more than once."
+ (let ((loaded (cl-gentemp "use-package--loaded"))
+ (result (cl-gentemp "use-package--result"))
+ (next (cl-gentemp "use-package--next")))
+ `((defvar ,loaded nil)
+ (defvar ,result nil)
+ (defvar ,next #'(lambda () (if ,loaded ,result
+ (setq ,loaded t ,result ,arg))))
+ ,@(funcall f `((funcall ,next))))))
+
+(defsubst use-package-normalize-value (_label arg)
+ "Normalize the Lisp value given by ARG.
+The argument LABEL is ignored."
+ (cond ((null arg) nil)
+ ((eq t arg) t)
+ ((use-package-non-nil-symbolp arg)
+ `(symbol-value ',arg))
+ ((functionp arg)
+ `(funcall #',arg))
+ (t arg)))
+
+(defun use-package-normalize-symbols (label arg &optional recursed)
+ "Normalize a list of symbols."
+ (cond
+ ((use-package-non-nil-symbolp arg)
+ (list arg))
+ ((and (not recursed) (listp arg) (listp (cdr arg)))
+ (mapcar #'(lambda (x) (car (use-package-normalize-symbols label x t))) arg))
+ (t
+ (use-package-error
+ (concat label " wants a symbol, or list of symbols")))))
+
+(defun use-package-normalize-symlist (_name keyword args)
+ (use-package-as-one (symbol-name keyword) args
+ #'use-package-normalize-symbols))
+
+(defun use-package-normalize-recursive-symbols (label arg)
+ "Normalize a list of symbols."
+ (cond
+ ((use-package-non-nil-symbolp arg)
+ arg)
+ ((and (listp arg) (listp (cdr arg)))
+ (mapcar #'(lambda (x) (use-package-normalize-recursive-symbols label x))
+ arg))
+ (t
+ (use-package-error
+ (concat label " wants a symbol, or nested list of symbols")))))
+
+(defun use-package-normalize-recursive-symlist (_name keyword args)
+ (use-package-as-one (symbol-name keyword) args
+ #'use-package-normalize-recursive-symbols))
+
+(defun use-package-normalize-paths (label arg &optional recursed)
+ "Normalize a list of filesystem paths."
+ (cond
+ ((and arg (or (use-package-non-nil-symbolp arg) (functionp arg)))
+ (let ((value (use-package-normalize-value label arg)))
+ (use-package-normalize-paths label (eval value))))
+ ((stringp arg)
+ (let ((path (if (file-name-absolute-p arg)
+ arg
+ (expand-file-name arg user-emacs-directory))))
+ (list path)))
+ ((and (not recursed) (listp arg) (listp (cdr arg)))
+ (mapcar #'(lambda (x)
+ (car (use-package-normalize-paths label x t))) arg))
+ (t
+ (use-package-error
+ (concat label " wants a directory path, or list of paths")))))
+
+(defun use-package-normalize-predicate (_name keyword args)
+ (if (null args)
+ t
+ (use-package-only-one (symbol-name keyword) args
+ #'use-package-normalize-value)))
+
+(defun use-package-normalize-form (label args)
+ "Given a list of forms, return it wrapped in `progn'."
+ (unless (listp (car args))
+ (use-package-error (concat label " wants a sexp or list of sexps")))
+ (mapcar #'(lambda (form)
+ (if (and (consp form)
+ (memq (car form)
+ '(use-package bind-key bind-key*
+ unbind-key bind-keys bind-keys*)))
+ (macroexpand form)
+ form)) args))
+
+(defun use-package-normalize-forms (_name keyword args)
+ (use-package-normalize-form (symbol-name keyword) args))
+
+(defun use-package-normalize-pairs
+ (key-pred val-pred name label arg &optional recursed)
+ "Normalize a list of pairs.
+KEY-PRED and VAL-PRED are predicates recognizing valid keys and
+values, respectively.
+If RECURSED is non-nil, recurse into sublists."
+ (cond
+ ((funcall key-pred arg)
+ (list (cons arg (use-package-as-symbol name))))
+ ((use-package-is-pair arg key-pred val-pred)
+ (list arg))
+ ((and (not recursed) (listp arg) (listp (cdr arg)))
+ (let (last-item)
+ (mapcar
+ #'(lambda (x)
+ (prog1
+ (let ((ret (use-package-normalize-pairs
+ key-pred val-pred name label x t)))
+ (if (and (listp ret)
+ (not (keywordp last-item)))
+ (car ret)
+ ret))
+ (setq last-item x))) arg)))
+ (t arg)))
+
+(defun use-package-recognize-function (v &optional binding additional-pred)
+ "A predicate that recognizes functional constructions:
+ nil
+ sym
+ 'sym
+ (quote sym)
+ #'sym
+ (function sym)
+ (lambda () ...)
+ '(lambda () ...)
+ (quote (lambda () ...))
+ #'(lambda () ...)
+ (function (lambda () ...))"
+ (or (if binding
+ (symbolp v)
+ (use-package-non-nil-symbolp v))
+ (and (listp v)
+ (memq (car v) '(quote function))
+ (use-package-non-nil-symbolp (cadr v)))
+ (if binding (commandp v) (functionp v))
+ (and additional-pred
+ (funcall additional-pred v))))
+
+(defun use-package-normalize-function (v)
+ "Reduce functional constructions to one of two normal forms:
+ sym
+ #'(lambda () ...)"
+ (cond ((symbolp v) v)
+ ((and (listp v)
+ (memq (car v) '(quote function))
+ (use-package-non-nil-symbolp (cadr v)))
+ (cadr v))
+ ((and (consp v)
+ (eq 'lambda (car v)))
+ v)
+ ((and (listp v)
+ (memq (car v) '(quote function))
+ (eq 'lambda (car (cadr v))))
+ (cadr v))
+ (t v)))
+
+(defun use-package-normalize-commands (args)
+ "Map over ARGS of the form ((_ . F) ...), normalizing functional F's."
+ (mapcar #'(lambda (x)
+ (if (consp x)
+ (cons (car x) (use-package-normalize-function (cdr x)))
+ x))
+ args))
+
+(defun use-package-normalize-mode (name keyword args)
+ "Normalize arguments for keywords which add regexp/mode pairs to an alist."
+ (use-package-as-one (symbol-name keyword) args
+ (apply-partially #'use-package-normalize-pairs
+ #'use-package-regex-p
+ #'use-package-recognize-function
+ name)))
+
+(defun use-package-autoloads-mode (_name _keyword args)
+ (mapcar
+ #'(lambda (x) (cons (cdr x) 'command))
+ (cl-remove-if-not #'(lambda (x)
+ (and (consp x)
+ (use-package-non-nil-symbolp (cdr x))))
+ args)))
+
+(defun use-package-handle-mode (name alist args rest state)
+ "Handle keywords which add regexp/mode pairs to an alist."
+ (use-package-concat
+ (use-package-process-keywords name rest state)
+ (mapcar
+ #'(lambda (thing)
+ `(add-to-list
+ ',alist
+ ',(cons (use-package-normalize-regex (car thing))
+ (cdr thing))))
+ (use-package-normalize-commands args))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Statistics
+;;
+
+(defun use-package-reset-statistics ()
+ (interactive)
+ (setq use-package-statistics (make-hash-table)))
+
+(defun use-package-statistics-status (package)
+ "Return loading configuration status of PACKAGE statistics."
+ (cond ((gethash :config package) "Configured")
+ ((gethash :init package) "Initialized")
+ ((gethash :preface package) "Prefaced")
+ ((gethash :use-package package) "Declared")))
+
+(defun use-package-statistics-last-event (package)
+ "Return the date when PACKAGE's status last changed.
+The date is returned as a string."
+ (format-time-string "%Y-%m-%d %a %H:%M"
+ (or (gethash :config package)
+ (gethash :init package)
+ (gethash :preface package)
+ (gethash :use-package package))))
+
+(defun use-package-statistics-time (package)
+ "Return the time is took for PACKAGE to load."
+ (+ (float-time (gethash :config-secs package '(0 0 0 0)))
+ (float-time (gethash :init-secs package '(0 0 0 0)))
+ (float-time (gethash :preface-secs package '(0 0 0 0)))
+ (float-time (gethash :use-package-secs package '(0 0 0 0)))))
+
+(defun use-package-statistics-convert (package)
+ "Return information about PACKAGE.
+
+The information is formatted in a way suitable for
+`use-package-statistics-mode'."
+ (let ((statistics (gethash package use-package-statistics)))
+ (list
+ package
+ (vector
+ (symbol-name package)
+ (use-package-statistics-status statistics)
+ (use-package-statistics-last-event statistics)
+ (format "%.2f" (use-package-statistics-time statistics))))))
+
+(defun use-package-report ()
+ "Show current statistics gathered about use-package declarations.
+In the table that's generated, the status field has the following
+meaning:
+ Configured :config has been processed (the package is loaded!)
+ Initialized :init has been processed (load status unknown)
+ Prefaced :preface has been processed
+ Declared the use-package declaration was seen"
+ (interactive)
+ (with-current-buffer (get-buffer-create "*use-package statistics*")
+ (setq tabulated-list-entries
+ (mapcar #'use-package-statistics-convert
+ (hash-table-keys use-package-statistics)))
+ (use-package-statistics-mode)
+ (tabulated-list-print)
+ (display-buffer (current-buffer))))
+
+(define-derived-mode use-package-statistics-mode tabulated-list-mode
+ "use-package statistics"
+ "Show current statistics gathered about use-package declarations."
+ (setq tabulated-list-format
+ ;; The sum of column width is 80 characters:
+ [("Package" 25 t)
+ ("Status" 13 t)
+ ("Last Event" 23 t)
+ ("Time" 10 t)])
+ (tabulated-list-init-header))
+
+(defun use-package-statistics-gather (keyword name after)
+ (let* ((hash (gethash name use-package-statistics
+ (make-hash-table)))
+ (before (and after (gethash keyword hash (current-time)))))
+ (puthash keyword (current-time) hash)
+ (when after
+ (puthash (intern (concat (symbol-name keyword) "-secs"))
+ (time-subtract (current-time) before) hash))
+ (puthash name hash use-package-statistics)))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Handlers
+;;
+
+;;;; :disabled
+
+;; Don't alias this to `ignore', as that will cause the resulting
+;; function to be interactive.
+(defun use-package-normalize/:disabled (_name _keyword _arg)
+ "Do nothing, return nil.")
+
+(defun use-package-handler/:disabled (name _keyword _arg rest state)
+ (use-package-process-keywords name rest state))
+
+;;;; :if, :when and :unless
+
+(defun use-package-normalize-test (_name keyword args)
+ (use-package-only-one (symbol-name keyword) args
+ #'use-package-normalize-value))
+
+(defalias 'use-package-normalize/:if 'use-package-normalize-test)
+
+(defun use-package-handler/:if (name _keyword pred rest state)
+ (let ((body (use-package-process-keywords name rest state)))
+ `((when ,pred ,@body))))
+
+(defalias 'use-package-normalize/:when 'use-package-normalize-test)
+
+(defalias 'use-package-handler/:when 'use-package-handler/:if)
+
+(defalias 'use-package-normalize/:unless 'use-package-normalize-test)
+
+(defun use-package-handler/:unless (name _keyword pred rest state)
+ (let ((body (use-package-process-keywords name rest state)))
+ `((unless ,pred ,@body))))
+
+;;;; :requires
+
+(defalias 'use-package-normalize/:requires 'use-package-normalize-symlist)
+
+(defun use-package-handler/:requires (name _keyword requires rest state)
+ (let ((body (use-package-process-keywords name rest state)))
+ (if (null requires)
+ body
+ `((when ,(if (> (length requires) 1)
+ `(not (member nil (mapcar #'featurep ',requires)))
+ `(featurep ',(car requires)))
+ ,@body)))))
+
+;;;; :load-path
+
+(defun use-package-normalize/:load-path (_name keyword args)
+ (use-package-as-one (symbol-name keyword) args
+ #'use-package-normalize-paths))
+
+(defun use-package-handler/:load-path (name _keyword arg rest state)
+ (let ((body (use-package-process-keywords name rest state)))
+ (use-package-concat
+ (mapcar #'(lambda (path)
+ `(eval-and-compile (add-to-list 'load-path ,path)))
+ arg)
+ body)))
+
+;;;; :no-require
+
+(defalias 'use-package-normalize/:no-require 'use-package-normalize-predicate)
+
+(defun use-package-handler/:no-require (name _keyword _arg rest state)
+ (use-package-process-keywords name rest state))
+
+;;;; :defines
+
+(defalias 'use-package-normalize/:defines 'use-package-normalize-symlist)
+
+(defun use-package-handler/:defines (name _keyword _arg rest state)
+ (use-package-process-keywords name rest state))
+
+;;;; :functions
+
+(defalias 'use-package-normalize/:functions 'use-package-normalize-symlist)
+
+(defun use-package-handler/:functions (name _keyword _arg rest state)
+ (use-package-process-keywords name rest state))
+
+;;;; :preface
+
+(defalias 'use-package-normalize/:preface 'use-package-normalize-forms)
+
+(defun use-package-handler/:preface (name _keyword arg rest state)
+ (let ((body (use-package-process-keywords name rest state)))
+ (use-package-concat
+ (when use-package-compute-statistics
+ `((use-package-statistics-gather :preface ',name nil)))
+ (when arg
+ `((eval-and-compile ,@arg)))
+ body
+ (when use-package-compute-statistics
+ `((use-package-statistics-gather :preface ',name t))))))
+
+;;;; :catch
+
+(defvar use-package--form)
+(defvar use-package--hush-function #'(lambda (_keyword body) body))
+
+(defsubst use-package-hush (context keyword body)
+ `((condition-case-unless-debug err
+ ,(macroexp-progn body)
+ (error (funcall ,context ,keyword err)))))
+
+(defun use-package-normalize/:catch (_name keyword args)
+ (if (null args)
+ t
+ (use-package-only-one (symbol-name keyword) args
+ use-package--hush-function)))
+
+(defun use-package-handler/:catch (name keyword arg rest state)
+ (let* ((context (cl-gentemp "use-package--warning")))
+ (cond
+ ((not arg)
+ (use-package-process-keywords name rest state))
+ ((eq arg t)
+ `((defvar ,context
+ #'(lambda (keyword err)
+ (let ((msg (format "%s/%s: %s" ',name keyword
+ (error-message-string err))))
+ ,@(when (eq use-package-verbose 'debug)
+ `((with-current-buffer
+ (get-buffer-create "*use-package*")
+ (goto-char (point-max))
+ (insert "-----\n" msg ,use-package--form)
+ (emacs-lisp-mode))
+ (setq msg
+ (concat msg
+ " (see the *use-package* buffer)"))))
+ (display-warning 'use-package msg :error))))
+ ,@(let ((use-package--hush-function
+ (apply-partially #'use-package-hush context)))
+ (funcall use-package--hush-function keyword
+ (use-package-process-keywords name rest state)))))
+ ((functionp arg)
+ `((defvar ,context ,arg)
+ ,@(let ((use-package--hush-function
+ (apply-partially #'use-package-hush context)))
+ (funcall use-package--hush-function keyword
+ (use-package-process-keywords name rest state)))))
+ (t
+ (use-package-error "The :catch keyword expects 't' or a function")))))
+
+;;;; :interpreter
+
+(defalias 'use-package-normalize/:interpreter 'use-package-normalize-mode)
+(defalias 'use-package-autoloads/:interpreter 'use-package-autoloads-mode)
+
+(defun use-package-handler/:interpreter (name _keyword arg rest state)
+ (use-package-handle-mode name 'interpreter-mode-alist arg rest state))
+
+;;;; :mode
+
+(defalias 'use-package-normalize/:mode 'use-package-normalize-mode)
+(defalias 'use-package-autoloads/:mode 'use-package-autoloads-mode)
+
+(defun use-package-handler/:mode (name _keyword arg rest state)
+ (use-package-handle-mode name 'auto-mode-alist arg rest state))
+
+;;;; :magic
+
+(defalias 'use-package-normalize/:magic 'use-package-normalize-mode)
+(defalias 'use-package-autoloads/:magic 'use-package-autoloads-mode)
+
+(defun use-package-handler/:magic (name _keyword arg rest state)
+ (use-package-handle-mode name 'magic-mode-alist arg rest state))
+
+;;;; :magic-fallback
+
+(defalias 'use-package-normalize/:magic-fallback 'use-package-normalize-mode)
+(defalias 'use-package-autoloads/:magic-fallback 'use-package-autoloads-mode)
+
+(defun use-package-handler/:magic-fallback (name _keyword arg rest state)
+ (use-package-handle-mode name 'magic-fallback-mode-alist arg rest state))
+
+;;;; :hook
+
+(defun use-package-normalize/:hook (name keyword args)
+ (use-package-as-one (symbol-name keyword) args
+ #'(lambda (label arg)
+ (unless (or (use-package-non-nil-symbolp arg) (consp arg))
+ (use-package-error
+ (concat label " a <symbol> or (<symbol or list of symbols> . <symbol or function>)"
+ " or list of these")))
+ (use-package-normalize-pairs
+ #'(lambda (k)
+ (or (use-package-non-nil-symbolp k)
+ (and k (let ((every t))
+ (while (and every k)
+ (if (and (consp k)
+ (use-package-non-nil-symbolp (car k)))
+ (setq k (cdr k))
+ (setq every nil)))
+ every))))
+ #'use-package-recognize-function
+ name label arg))))
+
+(defalias 'use-package-autoloads/:hook 'use-package-autoloads-mode)
+
+(defun use-package-handler/:hook (name _keyword args rest state)
+ "Generate use-package custom keyword code."
+ (use-package-concat
+ (use-package-process-keywords name rest state)
+ (cl-mapcan
+ #'(lambda (def)
+ (let ((syms (car def))
+ (fun (cdr def)))
+ (when fun
+ (mapcar
+ #'(lambda (sym)
+ `(add-hook
+ (quote ,(intern
+ (concat (symbol-name sym)
+ use-package-hook-name-suffix)))
+ (function ,fun)))
+ (if (use-package-non-nil-symbolp syms) (list syms) syms)))))
+ (use-package-normalize-commands args))))
+
+;;;; :commands
+
+(defalias 'use-package-normalize/:commands 'use-package-normalize-symlist)
+
+(defun use-package-handler/:commands (name _keyword arg rest state)
+ (use-package-concat
+ ;; Since we deferring load, establish any necessary autoloads, and also
+ ;; keep the byte-compiler happy.
+ (let ((name-string (use-package-as-string name)))
+ (cl-mapcan
+ #'(lambda (command)
+ (when (symbolp command)
+ (append
+ (unless (plist-get state :demand)
+ `((unless (fboundp ',command)
+ (autoload #',command ,name-string nil t))))
+ (when (bound-and-true-p byte-compile-current-file)
+ `((eval-when-compile
+ (declare-function ,command ,name-string)))))))
+ (delete-dups arg)))
+ (use-package-process-keywords name rest state)))
+
+;;;; :defer
+
+(defalias 'use-package-normalize/:defer 'use-package-normalize-predicate)
+
+(defun use-package-handler/:defer (name _keyword arg rest state)
+ (let ((body (use-package-process-keywords name rest state)))
+ (use-package-concat
+ ;; Load the package after a set amount of idle time, if the argument to
+ ;; `:defer' was a number.
+ (when (numberp arg)
+ `((run-with-idle-timer ,arg nil #'require
+ ',(use-package-as-symbol name) nil t)))
+ (if (or (not arg) (null body))
+ body
+ `((eval-after-load ',name ',(macroexp-progn body)))))))
+
+;;;; :after
+
+(defun use-package-normalize/:after (name keyword args)
+ (setq args (use-package-normalize-recursive-symlist name keyword args))
+ (if (consp args)
+ args
+ (list args)))
+
+(defun use-package-after-count-uses (features*)
+ "Count the number of time the body would appear in the result."
+ (cond ((use-package-non-nil-symbolp features*)
+ 1)
+ ((and (consp features*)
+ (memq (car features*) '(:or :any)))
+ (let ((num 0))
+ (cl-dolist (next (cdr features*))
+ (setq num (+ num (use-package-after-count-uses next))))
+ num))
+ ((and (consp features*)
+ (memq (car features*) '(:and :all)))
+ (apply #'max (mapcar #'use-package-after-count-uses
+ (cdr features*))))
+ ((listp features*)
+ (use-package-after-count-uses (cons :all features*)))))
+
+(defun use-package-require-after-load (features* body)
+ "Generate `eval-after-load' statements to represents FEATURES*.
+FEATURES* is a list containing keywords `:and' and `:all', where
+no keyword implies `:all'."
+ (cond
+ ((use-package-non-nil-symbolp features*)
+ `((eval-after-load ',features* ',(macroexp-progn body))))
+ ((and (consp features*)
+ (memq (car features*) '(:or :any)))
+ (cl-mapcan #'(lambda (x) (use-package-require-after-load x body))
+ (cdr features*)))
+ ((and (consp features*)
+ (memq (car features*) '(:and :all)))
+ (cl-dolist (next (cdr features*))
+ (setq body (use-package-require-after-load next body)))
+ body)
+ ((listp features*)
+ (use-package-require-after-load (cons :all features*) body))))
+
+(defun use-package-handler/:after (name _keyword arg rest state)
+ (let ((body (use-package-process-keywords name rest state))
+ (uses (use-package-after-count-uses arg)))
+ (if (or (null uses) (null body))
+ body
+ (if (<= uses 1)
+ (use-package-require-after-load arg body)
+ (use-package-memoize
+ (apply-partially #'use-package-require-after-load arg)
+ (macroexp-progn body))))))
+
+;;;; :demand
+
+(defalias 'use-package-normalize/:demand 'use-package-normalize-predicate)
+
+(defun use-package-handler/:demand (name _keyword _arg rest state)
+ (use-package-process-keywords name rest state))
+
+;;;; :custom
+
+(defun use-package-normalize/:custom (_name keyword args)
+ "Normalize use-package custom keyword."
+ (use-package-as-one (symbol-name keyword) args
+ #'(lambda (label arg)
+ (unless (listp arg)
+ (use-package-error
+ (concat label " a (<symbol> <value> [comment])"
+ " or list of these")))
+ (if (use-package-non-nil-symbolp (car arg))
+ (list arg)
+ arg))))
+
+(defun use-package-handler/:custom (name _keyword args rest state)
+ "Generate use-package custom keyword code."
+ (use-package-concat
+ (if (bound-and-true-p use-package-use-theme)
+ `((let ((custom--inhibit-theme-enable nil))
+ ;; Declare the theme here so use-package can be required inside
+ ;; eval-and-compile without warnings about unknown theme.
+ (unless (memq 'use-package custom-known-themes)
+ (deftheme use-package)
+ (enable-theme 'use-package)
+ (setq custom-enabled-themes (remq 'use-package custom-enabled-themes)))
+ (custom-theme-set-variables
+ 'use-package
+ ,@(mapcar
+ #'(lambda (def)
+ (let ((variable (nth 0 def))
+ (value (nth 1 def))
+ (comment (nth 2 def)))
+ (unless (and comment (stringp comment))
+ (setq comment (format "Customized with use-package %s" name)))
+ `'(,variable ,value nil () ,comment)))
+ args))))
+ (mapcar
+ #'(lambda (def)
+ (let ((variable (nth 0 def))
+ (value (nth 1 def))
+ (comment (nth 2 def)))
+ (unless (and comment (stringp comment))
+ (setq comment (format "Customized with use-package %s" name)))
+ `(customize-set-variable (quote ,variable) ,value ,comment)))
+ args))
+ (use-package-process-keywords name rest state)))
+
+;;;; :custom-face
+
+(defun use-package-normalize/:custom-face (name-symbol _keyword arg)
+ "Normalize use-package custom-face keyword."
+ (let ((error-msg
+ (format "%s wants a (<symbol> <face-spec>) or list of these"
+ name-symbol)))
+ (unless (listp arg)
+ (use-package-error error-msg))
+ (cl-dolist (def arg arg)
+ (unless (listp def)
+ (use-package-error error-msg))
+ (let ((face (nth 0 def))
+ (spec (nth 1 def)))
+ (when (or (not face)
+ (not spec)
+ (> (length def) 2))
+ (use-package-error error-msg))))))
+
+(defun use-package-handler/:custom-face (name _keyword args rest state)
+ "Generate use-package custom-face keyword code."
+ (use-package-concat
+ (mapcar #'(lambda (def) `(custom-set-faces (backquote ,def))) args)
+ (use-package-process-keywords name rest state)))
+
+;;;; :init
+
+(defalias 'use-package-normalize/:init 'use-package-normalize-forms)
+
+(defun use-package-handler/:init (name _keyword arg rest state)
+ (use-package-concat
+ (when use-package-compute-statistics
+ `((use-package-statistics-gather :init ',name nil)))
+ (let ((init-body
+ (use-package-hook-injector (use-package-as-string name)
+ :init arg)))
+ (when init-body
+ (funcall use-package--hush-function :init
+ (if use-package-check-before-init
+ `((when (locate-library ,(use-package-as-string name))
+ ,@init-body))
+ init-body))))
+ (use-package-process-keywords name rest state)
+ (when use-package-compute-statistics
+ `((use-package-statistics-gather :init ',name t)))))
+
+;;;; :load
+
+(defun use-package-normalize/:load (name keyword args)
+ (setq args (use-package-normalize-recursive-symlist name keyword args))
+ (if (consp args)
+ args
+ (list args)))
+
+(defun use-package-handler/:load (name _keyword arg rest state)
+ (let ((body (use-package-process-keywords name rest state)))
+ (cl-dolist (pkg arg)
+ (setq body (use-package-require (if (eq t pkg) name pkg) nil body)))
+ body))
+
+;;;; :config
+
+(defalias 'use-package-normalize/:config 'use-package-normalize-forms)
+
+(defun use-package-handler/:config (name _keyword arg rest state)
+ (let* ((body (use-package-process-keywords name rest state))
+ (name-symbol (use-package-as-symbol name)))
+ (use-package-concat
+ (when use-package-compute-statistics
+ `((use-package-statistics-gather :config ',name nil)))
+ (if (and (or (null arg) (equal arg '(t))) (not use-package-inject-hooks))
+ body
+ (use-package-with-elapsed-timer
+ (format "Configuring package %s" name-symbol)
+ (funcall use-package--hush-function :config
+ (use-package-concat
+ (use-package-hook-injector
+ (symbol-name name-symbol) :config arg)
+ body
+ (list t)))))
+ (when use-package-compute-statistics
+ `((use-package-statistics-gather :config ',name t))))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; The main macro
+;;
+
+(defmacro use-package-core (name args)
+ `(let* ((args* (use-package-normalize-keywords ,name ,args))
+ (use-package--form
+ (if (eq use-package-verbose 'debug)
+ (concat "\n\n"
+ (pp-to-string `(use-package ,name ,@,args))
+ "\n -->\n\n"
+ (pp-to-string `(use-package ,name ,@args*))
+ "\n ==>\n\n"
+ (pp-to-string
+ (macroexp-progn
+ (let ((use-package-verbose 'errors)
+ (use-package-expand-minimally t))
+ (use-package-process-keywords name args*
+ (and (plist-get args* :demand)
+ (list :demand t)))))))
+ "")))
+ (use-package-process-keywords name args*
+ (and (plist-get args* :demand)
+ (list :demand t)))))
+
+;;;###autoload
+(defmacro use-package (name &rest args)
+ "Declare an Emacs package by specifying a group of configuration options.
+
+For full documentation, please see the README file that came with
+this file. Usage:
+
+ (use-package package-name
+ [:keyword [option]]...)
+
+:init Code to run before PACKAGE-NAME has been loaded.
+:config Code to run after PACKAGE-NAME has been loaded. Note that
+ if loading is deferred for any reason, this code does not
+ execute until the lazy load has occurred.
+:preface Code to be run before everything except `:disabled'; this
+ can be used to define functions for use in `:if', or that
+ should be seen by the byte-compiler.
+
+:mode Form to be added to `auto-mode-alist'.
+:magic Form to be added to `magic-mode-alist'.
+:magic-fallback Form to be added to `magic-fallback-mode-alist'.
+:interpreter Form to be added to `interpreter-mode-alist'.
+
+:commands Define autoloads for commands that will be defined by the
+ package. This is useful if the package is being lazily
+ loaded, and you wish to conditionally call functions in your
+ `:init' block that are defined in the package.
+:hook Specify hook(s) to attach this package to.
+
+:bind Bind keys, and define autoloads for the bound commands.
+:bind* Bind keys, and define autoloads for the bound commands,
+ *overriding all minor mode bindings*.
+:bind-keymap Bind a key prefix to an auto-loaded keymap defined in the
+ package. This is like `:bind', but for keymaps.
+:bind-keymap* Like `:bind-keymap', but overrides all minor mode bindings
+
+:defer Defer loading of a package -- this is implied when using
+ `:commands', `:bind', `:bind*', `:mode', `:magic', `:hook',
+ `:magic-fallback', or `:interpreter'. This can be an integer,
+ to force loading after N seconds of idle time, if the package
+ has not already been loaded.
+:after Delay the use-package declaration until after the named modules
+ have loaded. Once load, it will be as though the use-package
+ declaration (without `:after') had been seen at that moment.
+:demand Prevent the automatic deferred loading introduced by constructs
+ such as `:bind' (see `:defer' for the complete list).
+
+:if EXPR Initialize and load only if EXPR evaluates to a non-nil value.
+:disabled The package is ignored completely if this keyword is present.
+:defines Declare certain variables to silence the byte-compiler.
+:functions Declare certain functions to silence the byte-compiler.
+:load-path Add to the `load-path' before attempting to load the package.
+:diminish Support for diminish.el (if installed).
+:delight Support for delight.el (if installed).
+:custom Call `custom-set' or `set-default' with each variable
+ definition without modifying the Emacs `custom-file'.
+ (compare with `custom-set-variables').
+:custom-face Call `customize-set-faces' with each face definition.
+:ensure Loads the package using package.el if necessary.
+:pin Pin the package to an archive."
+ (declare (indent 1))
+ (unless (memq :disabled args)
+ (macroexp-progn
+ (use-package-concat
+ (when use-package-compute-statistics
+ `((use-package-statistics-gather :use-package ',name nil)))
+ (if (eq use-package-verbose 'errors)
+ (use-package-core name args)
+ (condition-case-unless-debug err
+ (use-package-core name args)
+ (error
+ (ignore
+ (display-warning
+ 'use-package
+ (format "Failed to parse package %s: %s"
+ name (error-message-string err)) :error)))))
+ (when use-package-compute-statistics
+ `((use-package-statistics-gather :use-package ',name t)))))))
+
+(put 'use-package 'lisp-indent-function 'defun)
+
+(provide 'use-package-core)
+
+;; Local Variables:
+;; indent-tabs-mode: nil
+;; End:
+
+;;; use-package-core.el ends here
diff --git a/elpa/use-package-20210207.1926/use-package-core.elc b/elpa/use-package-20210207.1926/use-package-core.elc
new file mode 100644
index 0000000..4342290
--- /dev/null
+++ b/elpa/use-package-20210207.1926/use-package-core.elc
Binary files differ
diff --git a/elpa/use-package-20210207.1926/use-package-delight.el b/elpa/use-package-20210207.1926/use-package-delight.el
new file mode 100644
index 0000000..85d5c7c
--- /dev/null
+++ b/elpa/use-package-20210207.1926/use-package-delight.el
@@ -0,0 +1,91 @@
+;;; use-package-delight.el --- Support for the :delight keyword -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2012-2017 John Wiegley
+
+;; Author: John Wiegley <johnw@newartisans.com>
+;; Maintainer: John Wiegley <johnw@newartisans.com>
+;; Created: 17 Jun 2012
+;; Modified: 3 Dec 2017
+;; Version: 1.0
+;; Package-Requires: ((emacs "24.3") (use-package "2.4"))
+;; Keywords: dotemacs startup speed config package
+;; URL: https://github.com/jwiegley/use-package
+
+;; 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 GNU Emacs; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;; Commentary:
+
+;; Provides support for the :delight keyword, which is made available by
+;; default by requiring `use-package'.
+
+;;; Code:
+
+(require 'use-package-core)
+
+(defun use-package-normalize-delight (name args)
+ "Normalize ARGS for a single call to `delight'."
+ (when (eq :eval (car args))
+ ;; Handle likely common mistake.
+ (use-package-error ":delight mode line constructs must be quoted"))
+ (cond ((and (= (length args) 1)
+ (use-package-non-nil-symbolp (car args)))
+ `(,(nth 0 args) nil ,name))
+ ((= (length args) 2)
+ `(,(nth 0 args) ,(nth 1 args) ,name))
+ ((= (length args) 3)
+ args)
+ (t
+ (use-package-error
+ ":delight expects `delight' arguments or a list of them"))))
+
+;;;###autoload
+(defun use-package-normalize/:delight (name _keyword args)
+ "Normalize arguments to delight."
+ (cond ((null args)
+ `((,(use-package-as-mode name) nil ,name)))
+ ((and (= (length args) 1)
+ (use-package-non-nil-symbolp (car args)))
+ `((,(car args) nil ,name)))
+ ((and (= (length args) 1)
+ (stringp (car args)))
+ `((,(use-package-as-mode name) ,(car args) ,name)))
+ ((and (= (length args) 1)
+ (listp (car args))
+ (eq 'quote (caar args)))
+ `((,(use-package-as-mode name) ,@(cdar args) ,name)))
+ ((and (= (length args) 2)
+ (listp (nth 1 args))
+ (eq 'quote (car (nth 1 args))))
+ `((,(car args) ,@(cdr (nth 1 args)) ,name)))
+ (t (mapcar
+ (apply-partially #'use-package-normalize-delight name)
+ (if (use-package-non-nil-symbolp (car args))
+ (list args)
+ args)))))
+
+;;;###autoload
+(defun use-package-handler/:delight (name _keyword args rest state)
+ (let ((body (use-package-process-keywords name rest state)))
+ (use-package-concat
+ body
+ `((if (fboundp 'delight)
+ (delight '(,@args)))))))
+
+(add-to-list 'use-package-keywords :delight t)
+
+(provide 'use-package-delight)
+
+;;; use-package-delight.el ends here
diff --git a/elpa/use-package-20210207.1926/use-package-delight.elc b/elpa/use-package-20210207.1926/use-package-delight.elc
new file mode 100644
index 0000000..0c9c5bb
--- /dev/null
+++ b/elpa/use-package-20210207.1926/use-package-delight.elc
Binary files differ
diff --git a/elpa/use-package-20210207.1926/use-package-diminish.el b/elpa/use-package-20210207.1926/use-package-diminish.el
new file mode 100644
index 0000000..1f3895f
--- /dev/null
+++ b/elpa/use-package-20210207.1926/use-package-diminish.el
@@ -0,0 +1,80 @@
+;;; use-package-diminish.el --- Support for the :diminish keyword -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2012-2017 John Wiegley
+
+;; Author: John Wiegley <johnw@newartisans.com>
+;; Maintainer: John Wiegley <johnw@newartisans.com>
+;; Created: 17 Jun 2012
+;; Modified: 3 Dec 2017
+;; Version: 1.0
+;; Package-Requires: ((emacs "24.3") (use-package "2.4"))
+;; Keywords: dotemacs startup speed config package
+;; URL: https://github.com/jwiegley/use-package
+
+;; 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 GNU Emacs; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;; Commentary:
+
+;; Provides support for the :diminish keyword, which is made available by
+;; default by requiring `use-package'.
+
+;;; Code:
+
+(require 'use-package-core)
+
+(defun use-package-normalize-diminish (name label arg &optional recursed)
+ "Normalize the arguments to diminish down to a list of one of two forms:
+ SYMBOL
+ (SYMBOL . STRING)"
+ (cond
+ ((not arg)
+ (list (use-package-as-mode name)))
+ ((use-package-non-nil-symbolp arg)
+ (list arg))
+ ((stringp arg)
+ (list (cons (use-package-as-mode name) arg)))
+ ((and (consp arg) (stringp (cdr arg)))
+ (list arg))
+ ((and (not recursed) (listp arg) (listp (cdr arg)))
+ (mapcar #'(lambda (x) (car (use-package-normalize-diminish
+ name label x t))) arg))
+ (t
+ (use-package-error
+ (concat label " wants a string, symbol, "
+ "(symbol . string) or list of these")))))
+
+;;;###autoload
+(defun use-package-normalize/:diminish (name keyword args)
+ (use-package-as-one (symbol-name keyword) args
+ (apply-partially #'use-package-normalize-diminish name) t))
+
+;;;###autoload
+(defun use-package-handler/:diminish (name _keyword arg rest state)
+ (let ((body (use-package-process-keywords name rest state)))
+ (use-package-concat
+ (mapcar #'(lambda (var)
+ `(if (fboundp 'diminish)
+ ,(if (consp var)
+ `(diminish ',(car var) ,(cdr var))
+ `(diminish ',var))))
+ arg)
+ body)))
+
+(add-to-list 'use-package-keywords :diminish t)
+
+(provide 'use-package-diminish)
+
+;;; use-package-diminish.el ends here
diff --git a/elpa/use-package-20210207.1926/use-package-diminish.elc b/elpa/use-package-20210207.1926/use-package-diminish.elc
new file mode 100644
index 0000000..f90e875
--- /dev/null
+++ b/elpa/use-package-20210207.1926/use-package-diminish.elc
Binary files differ
diff --git a/elpa/use-package-20210207.1926/use-package-ensure.el b/elpa/use-package-20210207.1926/use-package-ensure.el
new file mode 100644
index 0000000..50005a9
--- /dev/null
+++ b/elpa/use-package-20210207.1926/use-package-ensure.el
@@ -0,0 +1,214 @@
+;;; use-package-ensure.el --- Support for the :ensure and :pin keywords -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2012-2017 John Wiegley
+
+;; Author: John Wiegley <johnw@newartisans.com>
+;; Maintainer: John Wiegley <johnw@newartisans.com>
+;; Created: 17 Jun 2012
+;; Modified: 3 Dec 2017
+;; Version: 1.0
+;; Package-Requires: ((emacs "24.3") (use-package "2.4"))
+;; Keywords: dotemacs startup speed config package
+;; URL: https://github.com/jwiegley/use-package
+
+;; 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 GNU Emacs; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;; Commentary:
+
+;; Provides support for the :ensure and :pin keywords, which is made available
+;; by default by requiring `use-package'.
+
+;;; Code:
+
+(require 'cl-lib)
+(require 'use-package-core)
+
+(defgroup use-package-ensure nil
+ "Support for :ensure and :pin keywords in use-package declarations."
+ :group 'use-package)
+
+(eval-when-compile
+ (declare-function package-installed-p "package")
+ (declare-function package-read-all-archive-contents "package" ()))
+
+(defcustom use-package-always-ensure nil
+ "Treat every package as though it had specified using `:ensure SEXP'.
+See also `use-package-defaults', which uses this value."
+ :type 'sexp
+ :group 'use-package-ensure)
+
+(defcustom use-package-always-pin nil
+ "Treat every package as though it had specified using `:pin SYM'.
+See also `use-package-defaults', which uses this value."
+ :type 'symbol
+ :group 'use-package-ensure)
+
+(defcustom use-package-ensure-function 'use-package-ensure-elpa
+ "Function that ensures a package is installed.
+This function is called with three arguments: the name of the
+package declared in the `use-package' form; the arguments passed
+to all `:ensure' keywords (always a list, even if only one); and
+the current `state' plist created by previous handlers.
+
+Note that this function is called whenever `:ensure' is provided,
+even if it is nil. It is up to the function to decide on the
+semantics of the various values for `:ensure'.
+
+This function should return non-nil if the package is installed.
+
+The default value uses package.el to install the package."
+ :type '(choice (const :tag "package.el" use-package-ensure-elpa)
+ (function :tag "Custom"))
+ :group 'use-package-ensure)
+
+;;;; :pin
+
+(defun use-package-normalize/:pin (_name keyword args)
+ (use-package-only-one (symbol-name keyword) args
+ #'(lambda (_label arg)
+ (cond
+ ((stringp arg) arg)
+ ((use-package-non-nil-symbolp arg) (symbol-name arg))
+ (t
+ (use-package-error
+ ":pin wants an archive name (a string)"))))))
+
+(eval-when-compile
+ (defvar package-pinned-packages)
+ (defvar package-archives))
+
+(defun use-package-archive-exists-p (archive)
+ "Check if a given ARCHIVE is enabled.
+
+ARCHIVE can be a string or a symbol or 'manual to indicate a
+manually updated package."
+ (if (member archive '(manual "manual"))
+ 't
+ (let ((valid nil))
+ (dolist (pa package-archives)
+ (when (member archive (list (car pa) (intern (car pa))))
+ (setq valid 't)))
+ valid)))
+
+(defun use-package-pin-package (package archive)
+ "Pin PACKAGE to ARCHIVE."
+ (unless (boundp 'package-pinned-packages)
+ (setq package-pinned-packages ()))
+ (let ((archive-symbol (if (symbolp archive) archive (intern archive)))
+ (archive-name (if (stringp archive) archive (symbol-name archive))))
+ (if (use-package-archive-exists-p archive-symbol)
+ (add-to-list 'package-pinned-packages (cons package archive-name))
+ (error "Archive '%s' requested for package '%s' is not available."
+ archive-name package))
+ (unless (bound-and-true-p package--initialized)
+ (package-initialize t))))
+
+(defun use-package-handler/:pin (name _keyword archive-name rest state)
+ (let ((body (use-package-process-keywords name rest state))
+ (pin-form (if archive-name
+ `(use-package-pin-package ',(use-package-as-symbol name)
+ ,archive-name))))
+ ;; Pinning should occur just before ensuring
+ ;; See `use-package-handler/:ensure'.
+ (if (bound-and-true-p byte-compile-current-file)
+ (eval pin-form) ; Eval when byte-compiling,
+ (push pin-form body)) ; or else wait until runtime.
+ body))
+
+;;;; :ensure
+
+(defvar package-archive-contents)
+
+;;;###autoload
+(defun use-package-normalize/:ensure (_name keyword args)
+ (if (null args)
+ (list t)
+ (use-package-only-one (symbol-name keyword) args
+ #'(lambda (_label arg)
+ (cond
+ ((symbolp arg)
+ (list arg))
+ ((and (listp arg) (= 3 (length arg))
+ (symbolp (nth 0 arg))
+ (eq :pin (nth 1 arg))
+ (or (stringp (nth 2 arg))
+ (symbolp (nth 2 arg))))
+ (list (cons (nth 0 arg) (nth 2 arg))))
+ (t
+ (use-package-error
+ (concat ":ensure wants an optional package name "
+ "(an unquoted symbol name), or (<symbol> :pin <string>)"))))))))
+
+(defun use-package-ensure-elpa (name args _state &optional _no-refresh)
+ (dolist (ensure args)
+ (let ((package
+ (or (and (eq ensure t) (use-package-as-symbol name))
+ ensure)))
+ (when package
+ (require 'package)
+ (when (consp package)
+ (use-package-pin-package (car package) (cdr package))
+ (setq package (car package)))
+ (unless (package-installed-p package)
+ (condition-case-unless-debug err
+ (progn
+ (when (assoc package (bound-and-true-p
+ package-pinned-packages))
+ (package-read-all-archive-contents))
+ (if (assoc package package-archive-contents)
+ (package-install package)
+ (package-refresh-contents)
+ (when (assoc package (bound-and-true-p
+ package-pinned-packages))
+ (package-read-all-archive-contents))
+ (package-install package))
+ t)
+ (error
+ (display-warning 'use-package
+ (format "Failed to install %s: %s"
+ name (error-message-string err))
+ :error))))))))
+
+;;;###autoload
+(defun use-package-handler/:ensure (name _keyword ensure rest state)
+ (let* ((body (use-package-process-keywords name rest state)))
+ ;; We want to avoid installing packages when the `use-package' macro is
+ ;; being macro-expanded by elisp completion (see `lisp--local-variables'),
+ ;; but still install packages when byte-compiling, to avoid requiring
+ ;; `package' at runtime.
+ (if (bound-and-true-p byte-compile-current-file)
+ ;; Eval when byte-compiling,
+ (funcall use-package-ensure-function name ensure state)
+ ;; or else wait until runtime.
+ (push `(,use-package-ensure-function ',name ',ensure ',state)
+ body))
+ body))
+
+(add-to-list 'use-package-defaults
+ '(:ensure (list use-package-always-ensure)
+ (lambda (name args)
+ (and use-package-always-ensure
+ (not (plist-member args :load-path))))) t)
+
+(add-to-list 'use-package-defaults
+ '(:pin use-package-always-pin use-package-always-pin) t)
+
+(add-to-list 'use-package-keywords :ensure)
+(add-to-list 'use-package-keywords :pin)
+
+(provide 'use-package-ensure)
+
+;;; use-package-ensure.el ends here
diff --git a/elpa/use-package-20210207.1926/use-package-ensure.elc b/elpa/use-package-20210207.1926/use-package-ensure.elc
new file mode 100644
index 0000000..54005c6
--- /dev/null
+++ b/elpa/use-package-20210207.1926/use-package-ensure.elc
Binary files differ
diff --git a/elpa/use-package-20210207.1926/use-package-jump.el b/elpa/use-package-20210207.1926/use-package-jump.el
new file mode 100644
index 0000000..4044ad1
--- /dev/null
+++ b/elpa/use-package-20210207.1926/use-package-jump.el
@@ -0,0 +1,79 @@
+;;; use-package-jump.el --- Attempt to jump to a use-package declaration -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2012-2017 John Wiegley
+
+;; Author: John Wiegley <johnw@newartisans.com>
+;; Maintainer: John Wiegley <johnw@newartisans.com>
+;; Created: 17 Jun 2012
+;; Modified: 3 Dec 2017
+;; Version: 1.0
+;; Package-Requires: ((emacs "24.3") (use-package "2.4"))
+;; Keywords: dotemacs startup speed config package
+;; URL: https://github.com/jwiegley/use-package
+
+;; 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 GNU Emacs; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;; Commentary:
+
+;; Provides the command `M-x use-package-jump-to-package-form', however it
+;; only works if the package being jumped to was required during
+;; initialization. If it was delay-loaded, it will not work. Improvements are
+;; needed.
+
+;;; Code:
+
+(require 'use-package-core)
+
+(defun use-package-find-require (package)
+ "Find file that required PACKAGE by searching `load-history'.
+Returns an absolute file path or nil if none is found."
+ (catch 'suspect
+ (dolist (filespec load-history)
+ (dolist (entry (cdr filespec))
+ (when (equal entry (cons 'require package))
+ (throw 'suspect (car filespec)))))))
+
+;;;###autoload
+(defun use-package-jump-to-package-form (package)
+ "Attempt to find and jump to the `use-package' form that loaded
+PACKAGE. This will only find the form if that form actually
+required PACKAGE. If PACKAGE was previously required then this
+function will jump to the file that originally required PACKAGE
+instead."
+ (interactive (list (completing-read "Package: " features)))
+ (let* ((package (if (stringp package) (intern package) package))
+ (requiring-file (use-package-find-require package))
+ file location)
+ (if (null requiring-file)
+ (user-error "Can't find file requiring file; may have been autoloaded")
+ (setq file (if (string= (file-name-extension requiring-file) "elc")
+ (concat (file-name-sans-extension requiring-file) ".el")
+ requiring-file))
+ (when (file-exists-p file)
+ (find-file-other-window file)
+ (save-excursion
+ (goto-char (point-min))
+ (setq location
+ (re-search-forward
+ (format (eval use-package-form-regexp-eval) package) nil t)))
+ (if (null location)
+ (message "No use-package form found.")
+ (goto-char location)
+ (beginning-of-line))))))
+
+(provide 'use-package-jump)
+
+;;; use-package-jump.el ends here
diff --git a/elpa/use-package-20210207.1926/use-package-jump.elc b/elpa/use-package-20210207.1926/use-package-jump.elc
new file mode 100644
index 0000000..a2d8ede
--- /dev/null
+++ b/elpa/use-package-20210207.1926/use-package-jump.elc
Binary files differ
diff --git a/elpa/use-package-20210207.1926/use-package-lint.el b/elpa/use-package-20210207.1926/use-package-lint.el
new file mode 100644
index 0000000..c6e7c3c
--- /dev/null
+++ b/elpa/use-package-20210207.1926/use-package-lint.el
@@ -0,0 +1,84 @@
+;;; use-package-lint.el --- Attempt to find errors in use-package declarations -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2012-2017 John Wiegley
+
+;; Author: John Wiegley <johnw@newartisans.com>
+;; Maintainer: John Wiegley <johnw@newartisans.com>
+;; Created: 17 Jun 2012
+;; Modified: 3 Dec 2017
+;; Version: 1.0
+;; Package-Requires: ((emacs "24.3") (use-package "2.4"))
+;; Keywords: dotemacs startup speed config package
+;; URL: https://github.com/jwiegley/use-package
+
+;; 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 GNU Emacs; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;; Commentary:
+
+;; Provides the command `M-x use-package-lint'.
+
+;;; Code:
+
+(require 'cl-lib)
+(require 'use-package-core)
+
+(defun use-package-lint-declaration (name plist)
+ (dolist (path (plist-get plist :load-path))
+ (unless (file-exists-p path)
+ (display-warning
+ 'use-package
+ (format "%s :load-path does not exist: %s"
+ name path) :error)))
+
+ (unless (or (plist-member plist :disabled)
+ (plist-get plist :no-require)
+ (locate-library (use-package-as-string name) nil
+ (plist-get plist :load-path)))
+ (display-warning
+ 'use-package
+ (format "%s module cannot be located" name) :error))
+
+ ;; (dolist (command (plist-get plist :commands))
+ ;; (unless (string= (find-lisp-object-file-name command nil)
+ ;; (locate-library (use-package-as-string name) nil
+ ;; (plist-get plist :load-path)))
+ ;; (display-warning
+ ;; 'use-package
+ ;; (format "%s :command is from different path: %s"
+ ;; name (symbol-name command)) :error)))
+ )
+
+;;;###autoload
+(defun use-package-lint ()
+ "Check for errors in use-package declarations.
+For example, if the module's `:if' condition is met, but even
+with the specified `:load-path' the module cannot be found."
+ (interactive)
+ (save-excursion
+ (goto-char (point-min))
+ (let ((re (eval use-package-form-regexp-eval)))
+ (while (re-search-forward re nil t)
+ (goto-char (match-beginning 0))
+ (let ((decl (read (current-buffer))))
+ (when (eq (car decl) 'use-package)
+ (use-package-lint-declaration
+ (use-package-as-string (cadr decl))
+ (use-package-normalize-keywords
+ (cadr decl) (cddr decl)))))))))
+
+(provide 'use-package-lint)
+
+;;; use-package-lint.el ends here
diff --git a/elpa/use-package-20210207.1926/use-package-lint.elc b/elpa/use-package-20210207.1926/use-package-lint.elc
new file mode 100644
index 0000000..edcdb5d
--- /dev/null
+++ b/elpa/use-package-20210207.1926/use-package-lint.elc
Binary files differ
diff --git a/elpa/use-package-20210207.1926/use-package-pkg.el b/elpa/use-package-20210207.1926/use-package-pkg.el
new file mode 100644
index 0000000..9f0089b
--- /dev/null
+++ b/elpa/use-package-20210207.1926/use-package-pkg.el
@@ -0,0 +1,13 @@
+(define-package "use-package" "20210207.1926" "A configuration macro for simplifying your .emacs"
+ '((emacs "24.3")
+ (bind-key "2.4"))
+ :commit "a7422fb8ab1baee19adb2717b5b47b9c3812a84c" :authors
+ '(("John Wiegley" . "johnw@newartisans.com"))
+ :maintainer
+ '("John Wiegley" . "johnw@newartisans.com")
+ :keywords
+ '("dotemacs" "startup" "speed" "config" "package")
+ :url "https://github.com/jwiegley/use-package")
+;; Local Variables:
+;; no-byte-compile: t
+;; End:
diff --git a/elpa/use-package-20210207.1926/use-package.el b/elpa/use-package-20210207.1926/use-package.el
new file mode 100644
index 0000000..0e194d5
--- /dev/null
+++ b/elpa/use-package-20210207.1926/use-package.el
@@ -0,0 +1,54 @@
+;;; use-package.el --- A configuration macro for simplifying your .emacs -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2012-2017 John Wiegley
+
+;; Author: John Wiegley <johnw@newartisans.com>
+;; Maintainer: John Wiegley <johnw@newartisans.com>
+;; Created: 17 Jun 2012
+;; Modified: 29 Nov 2017
+;; Version: 2.4.1
+;; Package-Requires: ((emacs "24.3") (bind-key "2.4"))
+;; Keywords: dotemacs startup speed config package
+;; URL: https://github.com/jwiegley/use-package
+
+;; 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 GNU Emacs; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;; Commentary:
+
+;; The `use-package' declaration macro allows you to isolate package
+;; configuration in your ".emacs" in a way that is performance-oriented and,
+;; well, just tidy. I created it because I have over 80 packages that I use
+;; in Emacs, and things were getting difficult to manage. Yet with this
+;; utility my total load time is just under 1 second, with no loss of
+;; functionality!
+;;
+;; Please see README.md from the same repository for documentation.
+
+;;; Code:
+
+(require 'use-package-core)
+
+(require 'use-package-bind-key)
+(require 'use-package-diminish)
+(require 'use-package-delight)
+(require 'use-package-ensure)
+
+(declare-function use-package-jump-to-package-form "use-package-jump")
+(autoload #'use-package-jump-to-package-form "use-package-jump" nil t)
+
+(provide 'use-package)
+
+;;; use-package.el ends here
diff --git a/elpa/use-package-20210207.1926/use-package.elc b/elpa/use-package-20210207.1926/use-package.elc
new file mode 100644
index 0000000..3e80e25
--- /dev/null
+++ b/elpa/use-package-20210207.1926/use-package.elc
Binary files differ
diff --git a/elpa/use-package-20210207.1926/use-package.info b/elpa/use-package-20210207.1926/use-package.info
new file mode 100644
index 0000000..c7b7b4b
--- /dev/null
+++ b/elpa/use-package-20210207.1926/use-package.info
@@ -0,0 +1,1048 @@
+This is use-package.info, produced by makeinfo version 6.7 from
+use-package.texi.
+
+ Copyright (C) 2012-2017 John Wiegley <johnw@newartisans.com>
+
+ You can redistribute this document 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 document 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.
+INFO-DIR-SECTION Emacs
+START-INFO-DIR-ENTRY
+* use-package: (use-package). Declarative package configuration for Emacs.
+END-INFO-DIR-ENTRY
+
+
+File: use-package.info, Node: Top, Next: Introduction, Up: (dir)
+
+use-package User Manual
+***********************
+
+use-package is...
+
+ Copyright (C) 2012-2017 John Wiegley <johnw@newartisans.com>
+
+ You can redistribute this document 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 document 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.
+
+* Menu:
+
+* Introduction::
+* Installation::
+* Getting Started::
+* Keywords::
+* FAQ::
+* Debugging Tools::
+* Command Index::
+* Function Index::
+* Variable Index::
+
+— The Detailed Node Listing —
+
+
+Installation
+
+* Installing from an Elpa Archive::
+* Installing from the Git Repository::
+* Post-Installation Tasks::
+
+
+
+
+Keywords
+
+* ‘:after’: after.
+* ‘:bind-keymap’, ‘:bind-keymap*’: bind-keymap bind-keymap*.
+* ‘:bind’, ‘:bind*’: bind bind*.
+* ‘:commands’: commands.
+* ‘:preface’, ‘:init’, ‘:config’: preface init config.
+* ‘:custom’: custom.
+* ‘:custom-face’: custom-face.
+* ‘:defer’, ‘:demand’: defer demand.
+* ‘:defines’, ‘:functions’: defines functions.
+* ‘:diminish’, ‘:delight’: diminish delight.
+* ‘:disabled’: disabled.
+* ‘:ensure’, ‘:pin’: ensure pin.
+* ‘:hook’: hook.
+* ‘:if’, ‘:when’, ‘:unless’: if when unless.
+* ‘:load-path’: load-path.
+* ‘:mode’, ‘:interpreter’: mode interpreter.
+* ‘:magic’, ‘:magic-fallback’: magic magic-fallback.
+* ‘:no-require’: no-require.
+* ‘:requires’: requires.
+
+
+
+‘:bind’, ‘:bind*’
+
+* Binding to local keymaps::
+
+FAQ
+
+* FAQ - How to ...?::
+* FAQ - Issues and Errors::
+
+FAQ - How to ...?
+
+* This is a question::
+
+
+FAQ - Issues and Errors
+
+* This is an issues::
+
+
+File: use-package.info, Node: Introduction, Next: Installation, Prev: Top, Up: Top
+
+1 Introduction
+**************
+
+The ‘use-package’ macro allows you to isolate package configuration in
+your ‘.emacs’ file in a way that is both performance-oriented and, well,
+tidy. I created it because I have over 400 packages that I use in
+Emacs, and things were getting difficult to manage. Yet with this
+utility my total load time is around 2 seconds, with no loss of
+functionality!
+
+
+File: use-package.info, Node: Installation, Next: Getting Started, Prev: Introduction, Up: Top
+
+2 Installation
+**************
+
+use-package can be installed using Emacs’ package manager or manually
+from its development repository.
+
+* Menu:
+
+* Installing from an Elpa Archive::
+* Installing from the Git Repository::
+* Post-Installation Tasks::
+
+
+File: use-package.info, Node: Installing from an Elpa Archive, Next: Installing from the Git Repository, Up: Installation
+
+2.1 Installing from an Elpa Archive
+===================================
+
+use-package is available from Melpa and Melpa-Stable. If you haven’t
+used Emacs’ package manager before, then it is high time you familiarize
+yourself with it by reading the documentation in the Emacs manual, see
+*note (emacs)Packages::. Then add one of the archives to
+‘package-archives’:
+
+ • To use Melpa:
+
+ (require 'package)
+ (add-to-list 'package-archives
+ '("melpa" . "https://melpa.org/packages/") t)
+
+ • To use Melpa-Stable:
+
+ (require 'package)
+ (add-to-list 'package-archives
+ '("melpa-stable" . "https://stable.melpa.org/packages/") t)
+
+ Once you have added your preferred archive, you need to update the
+local package list using:
+
+ M-x package-refresh-contents RET
+
+ Once you have done that, you can install use-package and its
+dependencies using:
+
+ M-x package-install RET use-package RET
+
+ Now see *note Post-Installation Tasks::.
+
+
+File: use-package.info, Node: Installing from the Git Repository, Next: Post-Installation Tasks, Prev: Installing from an Elpa Archive, Up: Installation
+
+2.2 Installing from the Git Repository
+======================================
+
+First, use Git to clone the use-package repository:
+
+ $ git clone https://github.com/jwiegley/use-package.git ~/.emacs.d/site-lisp/use-package
+ $ cd ~/.emacs.d/site-lisp/use-package
+
+ Then compile the libraries and generate the info manuals:
+
+ $ make
+
+ You may need to create ‘/path/to/use-package/config.mk’ with the
+following content before running ‘make’:
+
+ LOAD_PATH = -L /path/to/use-package
+
+ Finally add this to your init file:
+
+ (add-to-list 'load-path "~/.emacs.d/site-lisp/use-package")
+ (require 'use-package)
+
+ (with-eval-after-load 'info
+ (info-initialize)
+ (add-to-list 'Info-directory-list
+ "~/.emacs.d/site-lisp/use-package/"))
+
+ Note that elements of ‘load-path’ should not end with a slash, while
+those of ‘Info-directory-list’ should.
+
+ Instead of running use-package directly from the repository by adding
+it to the ‘load-path’, you might want to instead install it in some
+other directory using ‘sudo make install’ and setting ‘load-path’
+accordingly.
+
+ To update use-package use:
+
+ $ git pull
+ $ make
+
+ At times it might be necessary to run ‘make clean all’ instead.
+
+ To view all available targets use ‘make help’.
+
+ Now see *note Post-Installation Tasks::.
+
+
+File: use-package.info, Node: Post-Installation Tasks, Prev: Installing from the Git Repository, Up: Installation
+
+2.3 Post-Installation Tasks
+===========================
+
+After installing use-package you should verify that you are indeed using
+the use-package release you think you are using. It’s best to restart
+Emacs before doing so, to make sure you are not using an outdated value
+for ‘load-path’.
+
+ C-h v use-package-version RET
+
+ should display something like
+
+ use-package-version’s value is "2.4.1"
+
+ If you are completely new to use-package then see *note Getting
+Started::.
+
+ If you run into problems, then please see the *note FAQ::. Also see
+the *note Debugging Tools::.
+
+
+File: use-package.info, Node: Getting Started, Next: Keywords, Prev: Installation, Up: Top
+
+3 Getting Started
+*****************
+
+TODO. For now, see ‘README.md’.
+
+
+File: use-package.info, Node: Keywords, Next: FAQ, Prev: Getting Started, Up: Top
+
+4 Keywords
+**********
+
+* Menu:
+
+* ‘:after’: after.
+* ‘:bind-keymap’, ‘:bind-keymap*’: bind-keymap bind-keymap*.
+* ‘:bind’, ‘:bind*’: bind bind*.
+* ‘:commands’: commands.
+* ‘:preface’, ‘:init’, ‘:config’: preface init config.
+* ‘:custom’: custom.
+* ‘:custom-face’: custom-face.
+* ‘:defer’, ‘:demand’: defer demand.
+* ‘:defines’, ‘:functions’: defines functions.
+* ‘:diminish’, ‘:delight’: diminish delight.
+* ‘:disabled’: disabled.
+* ‘:ensure’, ‘:pin’: ensure pin.
+* ‘:hook’: hook.
+* ‘:if’, ‘:when’, ‘:unless’: if when unless.
+* ‘:load-path’: load-path.
+* ‘:mode’, ‘:interpreter’: mode interpreter.
+* ‘:magic’, ‘:magic-fallback’: magic magic-fallback.
+* ‘:no-require’: no-require.
+* ‘:requires’: requires.
+
+
+File: use-package.info, Node: after, Next: bind-keymap bind-keymap*, Up: Keywords
+
+4.1 ‘:after’
+============
+
+Sometimes it only makes sense to configure a package after another has
+been loaded, because certain variables or functions are not in scope
+until that time. This can achieved using an ‘:after’ keyword that
+allows a fairly rich description of the exact conditions when loading
+should occur. Here is an example:
+
+ (use-package hydra
+ :load-path "site-lisp/hydra")
+
+ (use-package ivy
+ :load-path "site-lisp/swiper")
+
+ (use-package ivy-hydra
+ :after (ivy hydra))
+
+ In this case, because all of these packages are demand-loaded in the
+order they occur, the use of ‘:after’ is not strictly necessary. By
+using it, however, the above code becomes order-independent, without an
+implicit depedence on the nature of your init file.
+
+ By default, ‘:after (foo bar)’ is the same as ‘:after (:all foo
+bar)’, meaning that loading of the given package will not happen until
+both ‘foo’ and ‘bar’ have been loaded. Here are some of the other
+possibilities:
+
+ :after (foo bar)
+ :after (:all foo bar)
+ :after (:any foo bar)
+ :after (:all (:any foo bar) (:any baz quux))
+ :after (:any (:all foo bar) (:all baz quux))
+
+ When you nest selectors, such as ‘(:any (:all foo bar) (:all baz
+quux))’, it means that the package will be loaded when either both ‘foo’
+and ‘bar’ have been loaded, or both ‘baz’ and ‘quux’ have been loaded.
+
+
+File: use-package.info, Node: bind-keymap bind-keymap*, Next: bind bind*, Prev: after, Up: Keywords
+
+4.2 ‘:bind-keymap’, ‘:bind-keymap*’
+===================================
+
+Normally ‘:bind’ expects that commands are functions that will be
+autoloaded from the given package. However, this does not work if one
+of those commands is actually a keymap, since keymaps are not functions,
+and cannot be autoloaded using Emacs’ ‘autoload’ mechanism.
+
+ To handle this case, ‘use-package’ offers a special, limited variant
+of ‘:bind’ called ‘:bind-keymap’. The only difference is that the
+"commands" bound to by ‘:bind-keymap’ must be keymaps defined in the
+package, rather than command functions. This is handled behind the
+scenes by generating custom code that loads the package containing the
+keymap, and then re-executes your keypress after the first load, to
+reinterpret that keypress as a prefix key.
+
+ For example:
+
+ (use-package projectile
+ :bind-keymap
+ ("C-c p" . projectile-command-map)
+
+
+File: use-package.info, Node: bind bind*, Next: commands, Prev: bind-keymap bind-keymap*, Up: Keywords
+
+4.3 ‘:bind’, ‘:bind*’
+=====================
+
+Another common thing to do when loading a module is to bind a key to
+primary commands within that module:
+
+ (use-package ace-jump-mode
+ :bind ("C-." . ace-jump-mode))
+
+ This does two things: first, it creates an autoload for the
+‘ace-jump-mode’ command and defers loading of ‘ace-jump-mode’ until you
+actually use it. Second, it binds the key ‘C-.’ to that command. After
+loading, you can use ‘M-x describe-personal-keybindings’ to see all such
+keybindings you’ve set throughout your ‘.emacs’ file.
+
+ A more literal way to do the exact same thing is:
+
+ (use-package ace-jump-mode
+ :commands ace-jump-mode
+ :init
+ (bind-key "C-." 'ace-jump-mode))
+
+ When you use the ‘:commands’ keyword, it creates autoloads for those
+commands and defers loading of the module until they are used. Since
+the ‘:init’ form is always run—even if ‘ace-jump-mode’ might not be on
+your system—remember to restrict ‘:init’ code to only what would succeed
+either way.
+
+ The ‘:bind’ keyword takes either a cons or a list of conses:
+
+ (use-package hi-lock
+ :bind (("M-o l" . highlight-lines-matching-regexp)
+ ("M-o r" . highlight-regexp)
+ ("M-o w" . highlight-phrase)))
+
+ The ‘:commands’ keyword likewise takes either a symbol or a list of
+symbols.
+
+ NOTE: Special keys like ‘tab’ or ‘F1’-‘Fn’ can be written in square
+brackets, i.e. ‘[tab]’ instead of ‘"tab"’. The syntax for the
+keybindings is similar to the "kbd" syntax: see the Emacs Manual
+(https://www.gnu.org/software/emacs/manual/html_node/emacs/Init-Rebinding.html)
+for more information.
+
+ Examples:
+
+ (use-package helm
+ :bind (("M-x" . helm-M-x)
+ ("M-<f5>" . helm-find-files)
+ ([f10] . helm-buffers-list)
+ ([S-f10] . helm-recentf)))
+
+* Menu:
+
+* Binding to local keymaps::
+
+
+File: use-package.info, Node: Binding to local keymaps, Up: bind bind*
+
+4.3.1 Binding to local keymaps
+------------------------------
+
+Slightly different from binding a key to a keymap, is binding a key
+*within* a local keymap that only exists after the package is loaded.
+‘use-package’ supports this with a ‘:map’ modifier, taking the local
+keymap to bind to:
+
+ (use-package helm
+ :bind (:map helm-command-map
+ ("C-c h" . helm-execute-persistent-action)))
+
+ The effect of this statement is to wait until ‘helm’ has loaded, and
+then to bind the key ‘C-c h’ to ‘helm-execute-persistent-action’ within
+Helm’s local keymap, ‘helm-mode-map’.
+
+ Multiple uses of ‘:map’ may be specified. Any binding occurring
+before the first use of ‘:map’ are applied to the global keymap:
+
+ (use-package term
+ :bind (("C-c t" . term)
+ :map term-mode-map
+ ("M-p" . term-send-up)
+ ("M-n" . term-send-down)
+ :map term-raw-map
+ ("M-o" . other-window)
+ ("M-p" . term-send-up)
+ ("M-n" . term-send-down)))
+
+
+File: use-package.info, Node: commands, Next: preface init config, Prev: bind bind*, Up: Keywords
+
+4.4 ‘:commands’
+===============
+
+
+File: use-package.info, Node: preface init config, Next: custom, Prev: commands, Up: Keywords
+
+4.5 ‘:preface’, ‘:init’, ‘:config’
+==================================
+
+Here is the simplest ‘use-package’ declaration:
+
+ ;; This is only needed once, near the top of the file
+ (eval-when-compile
+ ;; Following line is not needed if use-package.el is in ~/.emacs.d
+ (add-to-list 'load-path "<path where use-package is installed>")
+ (require 'use-package))
+
+ (use-package foo)
+
+ This loads in the package ‘foo’, but only if ‘foo’ is available on
+your system. If not, a warning is logged to the ‘*Messages*’ buffer.
+If it succeeds, a message about ‘"Loading foo"’ is logged, along with
+the time it took to load, if it took over 0.1 seconds.
+
+ Use the ‘:init’ keyword to execute code before a package is loaded.
+It accepts one or more forms, up until the next keyword:
+
+ (use-package foo
+ :init
+ (setq foo-variable t))
+
+ Similarly, ‘:config’ can be used to execute code after a package is
+loaded. In cases where loading is done lazily (see more about
+autoloading below), this execution is deferred until after the autoload
+occurs:
+
+ (use-package foo
+ :init
+ (setq foo-variable t)
+ :config
+ (foo-mode 1))
+
+ As you might expect, you can use ‘:init’ and ‘:config’ together:
+
+ (use-package color-moccur
+ :commands (isearch-moccur isearch-all)
+ :bind (("M-s O" . moccur)
+ :map isearch-mode-map
+ ("M-o" . isearch-moccur)
+ ("M-O" . isearch-moccur-all))
+ :init
+ (setq isearch-lazy-highlight t)
+ :config
+ (use-package moccur-edit))
+
+ In this case, I want to autoload the commands ‘isearch-moccur’ and
+‘isearch-all’ from ‘color-moccur.el’, and bind keys both at the global
+level and within the ‘isearch-mode-map’ (see next section). When the
+package is actually loaded (by using one of these commands),
+‘moccur-edit’ is also loaded, to allow editing of the ‘moccur’ buffer.
+
+
+File: use-package.info, Node: custom, Next: custom-face, Prev: preface init config, Up: Keywords
+
+4.6 ‘:custom’
+=============
+
+The ‘:custom’ keyword allows customization of package custom variables.
+
+ (use-package comint
+ :custom
+ (comint-buffer-maximum-size 20000 "Increase comint buffer size.")
+ (comint-prompt-read-only t "Make the prompt read only."))
+
+ The documentation string is not mandatory.
+
+
+File: use-package.info, Node: custom-face, Next: defer demand, Prev: custom, Up: Keywords
+
+4.7 ‘:custom-face’
+==================
+
+The ‘:custom-face’ keyword allows customization of package custom faces.
+
+ (use-package eruby-mode
+ :custom-face
+ (eruby-standard-face ((t (:slant italic)))))
+
+
+File: use-package.info, Node: defer demand, Next: defines functions, Prev: custom-face, Up: Keywords
+
+4.8 ‘:defer’, ‘:demand’
+=======================
+
+In almost all cases you don’t need to manually specify ‘:defer t’. This
+is implied whenever ‘:bind’ or ‘:mode’ or ‘:interpreter’ is used.
+Typically, you only need to specify ‘:defer’ if you know for a fact that
+some other package will do something to cause your package to load at
+the appropriate time, and thus you would like to defer loading even
+though use-package isn’t creating any autoloads for you.
+
+ You can override package deferral with the ‘:demand’ keyword. Thus,
+even if you use ‘:bind’, using ‘:demand’ will force loading to occur
+immediately and not establish an autoload for the bound key.
+
+
+File: use-package.info, Node: defines functions, Next: diminish delight, Prev: defer demand, Up: Keywords
+
+4.9 ‘:defines’, ‘:functions’
+============================
+
+Another feature of ‘use-package’ is that it always loads every file that
+it can when ‘.emacs’ is being byte-compiled. This helps to silence
+spurious warnings about unknown variables and functions.
+
+ However, there are times when this is just not enough. For those
+times, use the ‘:defines’ and ‘:functions’ keywords to introduce dummy
+variable and function declarations solely for the sake of the
+byte-compiler:
+
+ (use-package texinfo
+ :defines texinfo-section-list
+ :commands texinfo-mode
+ :init
+ (add-to-list 'auto-mode-alist '("\\.texi$" . texinfo-mode)))
+
+ If you need to silence a missing function warning, you can use
+‘:functions’:
+
+ (use-package ruby-mode
+ :mode "\\.rb\\'"
+ :interpreter "ruby"
+ :functions inf-ruby-keys
+ :config
+ (defun my-ruby-mode-hook ()
+ (require 'inf-ruby)
+ (inf-ruby-keys))
+
+ (add-hook 'ruby-mode-hook 'my-ruby-mode-hook))
+
+
+File: use-package.info, Node: diminish delight, Next: disabled, Prev: defines functions, Up: Keywords
+
+4.10 ‘:diminish’, ‘:delight’
+============================
+
+‘use-package’ also provides built-in support for the diminish and
+delight utilities—if you have them installed. Their purpose is to
+remove or change minor mode strings in your mode-line.
+
+ diminish (https://github.com/myrjola/diminish.el) is invoked with the
+‘:diminish’ keyword, which is passed either a minor mode symbol, a cons
+of the symbol and its replacement string, or just a replacement string,
+in which case the minor mode symbol is guessed to be the package name
+with "-mode" appended at the end:
+
+ (use-package abbrev
+ :diminish abbrev-mode
+ :config
+ (if (file-exists-p abbrev-file-name)
+ (quietly-read-abbrev-file)))
+
+ delight (https://elpa.gnu.org/packages/delight.html) is invoked with
+the ‘:delight’ keyword, which is passed a minor mode symbol, a
+replacement string or quoted mode-line data
+(https://www.gnu.org/software/emacs/manual/html_node/elisp/Mode-Line-Data.html)
+(in which case the minor mode symbol is guessed to be the package name
+with "-mode" appended at the end), both of these, or several lists of
+both. If no arguments are provided, the default mode name is hidden
+completely.
+
+ ;; Don't show anything for rainbow-mode.
+ (use-package rainbow-mode
+ :delight)
+
+ ;; Don't show anything for auto-revert-mode, which doesn't match
+ ;; its package name.
+ (use-package autorevert
+ :delight auto-revert-mode)
+
+ ;; Remove the mode name for projectile-mode, but show the project name.
+ (use-package projectile
+ :delight '(:eval (concat " " (projectile-project-name))))
+
+ ;; Completely hide visual-line-mode and change auto-fill-mode to " AF".
+ (use-package emacs
+ :delight
+ (auto-fill-function " AF")
+ (visual-line-mode))
+
+
+File: use-package.info, Node: disabled, Next: ensure pin, Prev: diminish delight, Up: Keywords
+
+4.11 ‘:disabled’
+================
+
+The ‘:disabled’ keyword can turn off a module you’re having difficulties
+with, or stop loading something you’re not using at the present time:
+
+ (use-package ess-site
+ :disabled
+ :commands R)
+
+ When byte-compiling your ‘.emacs’ file, disabled declarations are
+omitted from the output entirely, to accelerate startup times.
+
+
+File: use-package.info, Node: ensure pin, Next: hook, Prev: disabled, Up: Keywords
+
+4.12 ‘:ensure’, ‘:pin’
+======================
+
+You can use ‘use-package’ to load packages from ELPA with ‘package.el’.
+This is particularly useful if you share your ‘.emacs’ among several
+machines; the relevant packages are downloaded automatically once
+declared in your ‘.emacs’. The ‘:ensure’ keyword causes the package(s)
+to be installed automatically if not already present on your system (set
+‘(setq use-package-always-ensure t)’ if you wish this behavior to be
+global for all packages):
+
+ (use-package magit
+ :ensure t)
+
+ If you need to install a different package from the one named by
+‘use-package’, you can specify it like this:
+
+ (use-package tex
+ :ensure auctex)
+
+ Lastly, when running on Emacs 24.4 or later, use-package can pin a
+package to a specific archive, allowing you to mix and match packages
+from different archives. The primary use-case for this is preferring
+packages from the ‘melpa-stable’ and ‘gnu’ archives, but using specific
+packages from ‘melpa’ when you need to track newer versions than what is
+available in the ‘stable’ archives is also a valid use-case.
+
+ By default ‘package.el’ prefers ‘melpa’ over ‘melpa-stable’ due to
+the versioning ‘(> evil-20141208.623 evil-1.0.9)’, so even if you are
+tracking only a single package from ‘melpa’, you will need to tag all
+the non-‘melpa’ packages with the appropriate archive. If this really
+annoys you, then you can set ‘use-package-always-pin’ to set a default.
+
+ If you want to manually keep a package updated and ignore upstream
+updates, you can pin it to ‘manual’, which as long as there is no
+repository by that name, will Just Work(tm).
+
+ ‘use-package’ throws an error if you try to pin a package to an
+archive that has not been configured using ‘package-archives’ (apart
+from the magic ‘manual’ archive mentioned above):
+
+ Archive 'foo' requested for package 'bar' is not available.
+
+ Example:
+
+ (use-package company
+ :ensure t
+ :pin melpa-stable)
+
+ (use-package evil
+ :ensure t)
+ ;; no :pin needed, as package.el will choose the version in melpa
+
+ (use-package adaptive-wrap
+ :ensure t
+ ;; as this package is available only in the gnu archive, this is
+ ;; technically not needed, but it helps to highlight where it
+ ;; comes from
+ :pin gnu)
+
+ (use-package org
+ :ensure t
+ ;; ignore org-mode from upstream and use a manually installed version
+ :pin manual)
+
+ *NOTE*: the ‘:pin’ argument has no effect on emacs versions < 24.4.
+
+
+File: use-package.info, Node: hook, Next: if when unless, Prev: ensure pin, Up: Keywords
+
+4.13 ‘:hook’
+============
+
+The ‘:hook’ keyword allows adding functions onto hooks, here only the
+basename of the hook is required. Thus, all of the following are
+equivalent:
+
+ (use-package ace-jump-mode
+ :hook prog-mode)
+
+ (use-package ace-jump-mode
+ :hook (prog-mode . ace-jump-mode))
+
+ (use-package ace-jump-mode
+ :commands ace-jump-mode
+ :init
+ (add-hook 'prog-mode-hook #'ace-jump-mode))
+
+ And likewise, when multiple hooks should be applied, the following
+are also equivalent:
+
+ (use-package ace-jump-mode
+ :hook (prog-mode text-mode))
+
+ (use-package ace-jump-mode
+ :hook ((prog-mode text-mode) . ace-jump-mode))
+
+ (use-package ace-jump-mode
+ :hook ((prog-mode . ace-jump-mode)
+ (text-mode . ace-jump-mode)))
+
+ (use-package ace-jump-mode
+ :commands ace-jump-mode
+ :init
+ (add-hook 'prog-mode-hook #'ace-jump-mode)
+ (add-hook 'text-mode-hook #'ace-jump-mode))
+
+ The use of ‘:hook’, as with ‘:bind’, ‘:mode’, ‘:interpreter’, etc.,
+causes the functions being hooked to implicitly be read as ‘:commands’
+(meaning they will establish interactive ‘autoload’ definitions for that
+module, if not already defined as functions), and so ‘:defer t’ is also
+implied by ‘:hook’.
+
+
+File: use-package.info, Node: if when unless, Next: load-path, Prev: hook, Up: Keywords
+
+4.14 ‘:if’, ‘:when’, ‘:unless’
+==============================
+
+You can use the ‘:if’ keyword to predicate the loading and
+initialization of modules.
+
+ For example, I only want ‘edit-server’ running for my main, graphical
+Emacs, not for other Emacsen I may start at the command line:
+
+ (use-package edit-server
+ :if window-system
+ :init
+ (add-hook 'after-init-hook 'server-start t)
+ (add-hook 'after-init-hook 'edit-server-start t))
+
+ In another example, we can load things conditional on the operating
+system:
+
+ (use-package exec-path-from-shell
+ :if (memq window-system '(mac ns))
+ :ensure t
+ :config
+ (exec-path-from-shell-initialize))
+
+ Note that ‘:when’ is provided as an alias for ‘:if’, and ‘:unless
+foo’ means the same thing as ‘:if (not foo)’.
+
+
+File: use-package.info, Node: load-path, Next: mode interpreter, Prev: if when unless, Up: Keywords
+
+4.15 ‘:load-path’
+=================
+
+If your package needs a directory added to the ‘load-path’ in order to
+load, use ‘:load-path’. This takes a symbol, a function, a string or a
+list of strings. If the path is relative, it is expanded within
+‘user-emacs-directory’:
+
+ (use-package ess-site
+ :load-path "site-lisp/ess/lisp/"
+ :commands R)
+
+ Note that when using a symbol or a function to provide a dynamically
+generated list of paths, you must inform the byte-compiler of this
+definition so the value is available at byte-compilation time. This is
+done by using the special form ‘eval-and-compile’ (as opposed to
+‘eval-when-compile’). Further, this value is fixed at whatever was
+determined during compilation, to avoid looking up the same information
+again on each startup:
+
+ (eval-and-compile
+ (defun ess-site-load-path ()
+ (shell-command "find ~ -path ess/lisp")))
+
+ (use-package ess-site
+ :load-path (lambda () (list (ess-site-load-path)))
+ :commands R)
+
+
+File: use-package.info, Node: mode interpreter, Next: magic magic-fallback, Prev: load-path, Up: Keywords
+
+4.16 ‘:mode’, ‘:interpreter’
+============================
+
+Similar to ‘:bind’, you can use ‘:mode’ and ‘:interpreter’ to establish
+a deferred binding within the ‘auto-mode-alist’ and
+‘interpreter-mode-alist’ variables. The specifier to either keyword can
+be a cons cell, a list of cons cells, or a string or regexp:
+
+ (use-package ruby-mode
+ :mode "\\.rb\\'"
+ :interpreter "ruby")
+
+ ;; The package is "python" but the mode is "python-mode":
+ (use-package python
+ :mode ("\\.py\\'" . python-mode)
+ :interpreter ("python" . python-mode))
+
+ If you aren’t using ‘:commands’, ‘:bind’, ‘:bind*’, ‘:bind-keymap’,
+‘:bind-keymap*’, ‘:mode’, or ‘:interpreter’ (all of which imply
+‘:defer’; see the docstring for ‘use-package’ for a brief description of
+each), you can still defer loading with the ‘:defer’ keyword:
+
+ (use-package ace-jump-mode
+ :defer t
+ :init
+ (autoload 'ace-jump-mode "ace-jump-mode" nil t)
+ (bind-key "C-." 'ace-jump-mode))
+
+ This does exactly the same thing as the following:
+
+ (use-package ace-jump-mode
+ :bind ("C-." . ace-jump-mode))
+
+
+File: use-package.info, Node: magic magic-fallback, Next: no-require, Prev: mode interpreter, Up: Keywords
+
+4.17 ‘:magic’, ‘:magic-fallback’
+================================
+
+Similar to ‘:mode‘ and ‘:interpreter‘, you can also use ‘:magic‘ and
+‘:magic-fallback‘ to cause certain function to be run if the beginning
+of a file matches a given regular expression. The difference between
+the two is that ‘:magic-fallback‘ has a lower priority than ‘:mode‘.
+For example:
+
+ “‘ elisp (use-package pdf-tools :load-path "site-lisp/pdf-tools/lisp"
+:magic ("%PDF" . pdf-view-mode) :config (pdf-tools-install)) “‘
+
+ This registers an autoloaded command for ‘pdf-view-mode‘, defers
+loading of ‘pdf-tools‘, and runs ‘pdf-view-mode‘ if the beginning of a
+buffer matches the string ‘"%PDF"‘.
+
+
+File: use-package.info, Node: no-require, Next: requires, Prev: magic magic-fallback, Up: Keywords
+
+4.18 ‘:no-require’
+==================
+
+Normally, ‘use-package’ will load each package at compile time before
+compiling the configuration, to ensure that any necessary symbols are in
+scope to satisfy the byte-compiler. At times this can cause problems,
+since a package may have special loading requirements, and all that you
+want to use ‘use-package’ for is to add a configuration to the
+‘eval-after-load’ hook. In such cases, use the ‘:no-require’ keyword:
+
+ (use-package foo
+ :no-require t
+ :config
+ (message "This is evaluated when `foo' is loaded"))
+
+
+File: use-package.info, Node: requires, Prev: no-require, Up: Keywords
+
+4.19 ‘:requires’
+================
+
+While the ‘:after’ keyword delays loading until the dependencies are
+loaded, the somewhat simpler ‘:requires’ keyword simply never loads the
+package if the dependencies are not available at the time the
+‘use-package’ declaration is encountered. By "available" in this
+context it means that ‘foo’ is available of ‘(featurep 'foo)’ evaluates
+to a non-nil value. For example:
+
+ (use-package abbrev
+ :requires foo)
+
+ This is the same as:
+
+ (use-package abbrev
+ :if (featurep 'foo))
+
+ As a convenience, a list of such packages may be specified:
+
+ (use-package abbrev
+ :requires (foo bar baz))
+
+ For more complex logic, such as that supported by ‘:after’, simply
+use ‘:if’ and the appropriate Lisp expression.
+
+
+File: use-package.info, Node: FAQ, Next: Debugging Tools, Prev: Keywords, Up: Top
+
+Appendix A FAQ
+**************
+
+The next two nodes lists frequently asked questions.
+
+ Please also use the *note Debugging Tools::.
+
+* Menu:
+
+* FAQ - How to ...?::
+* FAQ - Issues and Errors::
+
+
+File: use-package.info, Node: FAQ - How to ...?, Next: FAQ - Issues and Errors, Up: FAQ
+
+A.1 FAQ - How to ...?
+=====================
+
+* Menu:
+
+* This is a question::
+
+
+File: use-package.info, Node: This is a question, Up: FAQ - How to ...?
+
+A.1.1 This is a question
+------------------------
+
+This is an answer.
+
+
+File: use-package.info, Node: FAQ - Issues and Errors, Prev: FAQ - How to ...?, Up: FAQ
+
+A.2 FAQ - Issues and Errors
+===========================
+
+* Menu:
+
+* This is an issues::
+
+
+File: use-package.info, Node: This is an issues, Up: FAQ - Issues and Errors
+
+A.2.1 This is an issues
+-----------------------
+
+This is a description.
+
+
+File: use-package.info, Node: Debugging Tools, Next: Command Index, Prev: FAQ, Up: Top
+
+B Debugging Tools
+*****************
+
+TODO
+
+ Please also see the *note FAQ::.
+
+
+File: use-package.info, Node: Command Index, Next: Function Index, Prev: Debugging Tools, Up: Top
+
+Appendix C Command Index
+************************
+
+
+File: use-package.info, Node: Function Index, Next: Variable Index, Prev: Command Index, Up: Top
+
+Appendix D Function Index
+*************************
+
+
+File: use-package.info, Node: Variable Index, Prev: Function Index, Up: Top
+
+Appendix E Variable Index
+*************************
+
+
+
+Tag Table:
+Node: Top784
+Node: Introduction2819
+Node: Installation3306
+Node: Installing from an Elpa Archive3658
+Node: Installing from the Git Repository4773
+Node: Post-Installation Tasks6309
+Node: Getting Started7024
+Node: Keywords7196
+Node: after8115
+Node: bind-keymap bind-keymap*9647
+Node: bind bind*10700
+Node: Binding to local keymaps12740
+Node: commands13831
+Node: preface init config13973
+Node: custom16051
+Node: custom-face16491
+Node: defer demand16811
+Node: defines functions17623
+Node: diminish delight18768
+Node: disabled20711
+Node: ensure pin21206
+Node: hook23936
+Node: if when unless25354
+Node: load-path26300
+Node: mode interpreter27446
+Node: magic magic-fallback28757
+Node: no-require29602
+Node: requires30306
+Node: FAQ31193
+Node: FAQ - How to ...?31476
+Node: This is a question31648
+Node: FAQ - Issues and Errors31796
+Node: This is an issues31979
+Node: Debugging Tools32134
+Node: Command Index32308
+Node: Function Index32464
+Node: Variable Index32621
+
+End Tag Table
+
+
+Local Variables:
+coding: utf-8
+End:
diff --git a/elpa/which-key-20220419.227/which-key-autoloads.el b/elpa/which-key-20220419.227/which-key-autoloads.el
new file mode 100644
index 0000000..ea0cda4
--- /dev/null
+++ b/elpa/which-key-20220419.227/which-key-autoloads.el
@@ -0,0 +1,216 @@
+;;; which-key-autoloads.el --- automatically extracted autoloads -*- lexical-binding: t -*-
+;;
+;;; Code:
+
+(add-to-list 'load-path (directory-file-name
+ (or (file-name-directory #$) (car load-path))))
+
+
+;;;### (autoloads nil "which-key" "which-key.el" (0 0 0 0))
+;;; Generated autoloads from which-key.el
+
+(defvar which-key-mode nil "\
+Non-nil if Which-Key mode is enabled.
+See the `which-key-mode' command
+for a description of this minor mode.
+Setting this variable directly does not take effect;
+either customize it (see the info node `Easy Customization')
+or call the function `which-key-mode'.")
+
+(custom-autoload 'which-key-mode "which-key" nil)
+
+(autoload 'which-key-mode "which-key" "\
+Toggle which-key-mode.
+
+This is a minor mode. If called interactively, toggle the
+`Which-Key mode' mode. If the prefix argument is positive,
+enable the mode, and if it is zero or negative, disable the mode.
+
+If called from Lisp, toggle the mode if ARG is `toggle'. Enable
+the mode if ARG is nil, omitted, or is a positive number.
+Disable the mode if ARG is a negative number.
+
+To check whether the minor mode is enabled in the current buffer,
+evaluate `(default-value \\='which-key-mode)'.
+
+The mode's hook is called both when the mode is enabled and when
+it is disabled.
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'which-key-setup-side-window-right "which-key" "\
+Apply suggested settings for side-window that opens on right." t nil)
+
+(autoload 'which-key-setup-side-window-right-bottom "which-key" "\
+Apply suggested settings for side-window that opens on right
+if there is space and the bottom otherwise." t nil)
+
+(autoload 'which-key-setup-side-window-bottom "which-key" "\
+Apply suggested settings for side-window that opens on bottom." t nil)
+
+(autoload 'which-key-setup-minibuffer "which-key" "\
+Apply suggested settings for minibuffer.
+Do not use this setup if you use the paging commands. Instead use
+`which-key-setup-side-window-bottom', which is nearly identical
+but more functional." t nil)
+
+(autoload 'which-key-add-keymap-based-replacements "which-key" "\
+Replace the description of KEY using REPLACEMENT in KEYMAP.
+KEY should take a format suitable for use in `kbd'. REPLACEMENT
+should be a cons cell of the form (STRING . COMMAND) for each
+REPLACEMENT, where STRING is the replacement string and COMMAND
+is a symbol corresponding to the intended command to be
+replaced. COMMAND can be nil if the binding corresponds to a key
+prefix. An example is
+
+\(which-key-add-keymap-based-replacements global-map
+ \"C-x w\" '(\"Save as\" . write-file)).
+
+For backwards compatibility, REPLACEMENT can also be a string,
+but the above format is preferred, and the option to use a string
+for REPLACEMENT will eventually be removed.
+
+\(fn KEYMAP KEY REPLACEMENT &rest MORE)" nil nil)
+
+(autoload 'which-key-add-key-based-replacements "which-key" "\
+Replace the description of KEY-SEQUENCE with REPLACEMENT.
+KEY-SEQUENCE is a string suitable for use in `kbd'. REPLACEMENT
+may either be a string, as in
+
+\(which-key-add-key-based-replacements \"C-x 1\" \"maximize\")
+
+a cons of two strings as in
+
+\(which-key-add-key-based-replacements \"C-x 8\"
+ '(\"unicode\" . \"Unicode keys\"))
+
+or a function that takes a (KEY . BINDING) cons and returns a
+replacement.
+
+In the second case, the second string is used to provide a longer
+name for the keys under a prefix.
+
+MORE allows you to specifcy additional KEY REPLACEMENT pairs. All
+replacements are added to `which-key-replacement-alist'.
+
+\(fn KEY-SEQUENCE REPLACEMENT &rest MORE)" nil nil)
+
+(autoload 'which-key-add-major-mode-key-based-replacements "which-key" "\
+Functions like `which-key-add-key-based-replacements'.
+The difference is that MODE specifies the `major-mode' that must
+be active for KEY-SEQUENCE and REPLACEMENT (MORE contains
+addition KEY-SEQUENCE REPLACEMENT pairs) to apply.
+
+\(fn MODE KEY-SEQUENCE REPLACEMENT &rest MORE)" nil nil)
+
+(autoload 'which-key-reload-key-sequence "which-key" "\
+Simulate entering the key sequence KEY-SEQ.
+KEY-SEQ should be a list of events as produced by
+`listify-key-sequence'. If nil, KEY-SEQ defaults to
+`which-key--current-key-list'. Any prefix arguments that were
+used are reapplied to the new key sequence.
+
+\(fn &optional KEY-SEQ)" nil nil)
+
+(autoload 'which-key-show-standard-help "which-key" "\
+Call the command in `which-key--prefix-help-cmd-backup'.
+Usually this is `describe-prefix-bindings'.
+
+\(fn &optional _)" t nil)
+
+(autoload 'which-key-show-next-page-no-cycle "which-key" "\
+Show next page of keys unless on the last page, in which case
+call `which-key-show-standard-help'." t nil)
+
+(autoload 'which-key-show-previous-page-no-cycle "which-key" "\
+Show previous page of keys unless on the first page, in which
+case do nothing." t nil)
+
+(autoload 'which-key-show-next-page-cycle "which-key" "\
+Show the next page of keys, cycling from end to beginning
+after last page.
+
+\(fn &optional _)" t nil)
+
+(autoload 'which-key-show-previous-page-cycle "which-key" "\
+Show the previous page of keys, cycling from beginning to end
+after first page.
+
+\(fn &optional _)" t nil)
+
+(autoload 'which-key-show-top-level "which-key" "\
+Show top-level bindings.
+
+\(fn &optional _)" t nil)
+
+(autoload 'which-key-show-major-mode "which-key" "\
+Show top-level bindings in the map of the current major mode.
+
+This function will also detect evil bindings made using
+`evil-define-key' in this map. These bindings will depend on the
+current evil state.
+
+\(fn &optional ALL)" t nil)
+
+(autoload 'which-key-show-full-major-mode "which-key" "\
+Show all bindings in the map of the current major mode.
+
+This function will also detect evil bindings made using
+`evil-define-key' in this map. These bindings will depend on the
+current evil state. " t nil)
+
+(autoload 'which-key-dump-bindings "which-key" "\
+Dump bindings from PREFIX into buffer named BUFFER-NAME.
+
+PREFIX should be a string suitable for `kbd'.
+
+\(fn PREFIX BUFFER-NAME)" t nil)
+
+(autoload 'which-key-undo-key "which-key" "\
+Undo last keypress and force which-key update.
+
+\(fn &optional _)" t nil)
+
+(autoload 'which-key-C-h-dispatch "which-key" "\
+Dispatch C-h commands by looking up key in
+`which-key-C-h-map'. This command is always accessible (from any
+prefix) if `which-key-use-C-h-commands' is non nil." t nil)
+
+(autoload 'which-key-show-keymap "which-key" "\
+Show the top-level bindings in KEYMAP using which-key.
+KEYMAP is selected interactively from all available keymaps.
+
+If NO-PAGING is non-nil, which-key will not intercept subsequent
+keypresses for the paging functionality.
+
+\(fn KEYMAP &optional NO-PAGING)" t nil)
+
+(autoload 'which-key-show-full-keymap "which-key" "\
+Show all bindings in KEYMAP using which-key.
+KEYMAP is selected interactively from all available keymaps.
+
+\(fn KEYMAP)" t nil)
+
+(autoload 'which-key-show-minor-mode-keymap "which-key" "\
+Show the top-level bindings in KEYMAP using which-key.
+KEYMAP is selected interactively by mode in
+`minor-mode-map-alist'.
+
+\(fn &optional ALL)" t nil)
+
+(autoload 'which-key-show-full-minor-mode-keymap "which-key" "\
+Show all bindings in KEYMAP using which-key.
+KEYMAP is selected interactively by mode in
+`minor-mode-map-alist'." t nil)
+
+(register-definition-prefixes "which-key" '("evil-state" "which-key-"))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; coding: utf-8
+;; End:
+;;; which-key-autoloads.el ends here
diff --git a/elpa/which-key-20220419.227/which-key-pkg.el b/elpa/which-key-20220419.227/which-key-pkg.el
new file mode 100644
index 0000000..05fa14d
--- /dev/null
+++ b/elpa/which-key-20220419.227/which-key-pkg.el
@@ -0,0 +1,2 @@
+;;; Generated package description from which-key.el -*- no-byte-compile: t -*-
+(define-package "which-key" "20220419.227" "Display available keybindings in popup" '((emacs "24.4")) :commit "129f4ebfc74f207ac82978f6d90d8b4bb1a55cf9" :authors '(("Justin Burkett" . "justin@burkett.cc")) :maintainer '("Justin Burkett" . "justin@burkett.cc") :url "https://github.com/justbur/emacs-which-key")
diff --git a/elpa/which-key-20220419.227/which-key.el b/elpa/which-key-20220419.227/which-key.el
new file mode 100644
index 0000000..14e04a1
--- /dev/null
+++ b/elpa/which-key-20220419.227/which-key.el
@@ -0,0 +1,2711 @@
+;;; which-key.el --- Display available keybindings in popup -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2017-2021 Free Software Foundation, Inc.
+
+;; Author: Justin Burkett <justin@burkett.cc>
+;; Maintainer: Justin Burkett <justin@burkett.cc>
+;; URL: https://github.com/justbur/emacs-which-key
+;; Package-Version: 20220419.227
+;; Package-Commit: 129f4ebfc74f207ac82978f6d90d8b4bb1a55cf9
+;; Version: 3.6.0
+;; Keywords:
+;; Package-Requires: ((emacs "24.4"))
+
+;; 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:
+
+;; which-key provides the minor mode which-key-mode for Emacs. The mode displays
+;; the key bindings following your currently entered incomplete command (a
+;; prefix) in a popup. For example, after enabling the minor mode if you enter
+;; C-x and wait for the default of 1 second the minibuffer will expand with all
+;; of the available key bindings that follow C-x (or as many as space allows
+;; given your settings). This includes prefixes like C-x 8 which are shown in a
+;; different face. Screenshots of what the popup will look like along with
+;; information about additional features can be found at
+;; https://github.com/justbur/emacs-which-key.
+;;
+
+;;; Code:
+
+(require 'cl-lib)
+(require 'button)
+(require 'regexp-opt)
+
+;; For compiler
+(defvar evil-operator-shortcut-map)
+(defvar evil-operator-state-map)
+(defvar evil-motion-state-map)
+(defvar golden-ratio-mode)
+(declare-function evil-get-command-property "ext:evil-common.el")
+
+;;; Options
+
+(defgroup which-key nil
+ "Customization options for which-key-mode"
+ :group 'help
+ :prefix "which-key-")
+
+(defcustom which-key-idle-delay 1.0
+ "Delay (in seconds) for which-key buffer to popup.
+This variable should be set before activating `which-key-mode'.
+
+A value of zero might lead to issues, so a non-zero value is
+recommended
+(see https://github.com/justbur/emacs-which-key/issues/134)."
+ :group 'which-key
+ :type 'float)
+
+(defcustom which-key-idle-secondary-delay nil
+ "Once the which-key buffer shows once for a key sequence reduce
+the idle time to this amount (in seconds). This makes it possible
+to shorten the delay for subsequent popups in the same key
+sequence. The default is for this value to be nil, which disables
+this behavior."
+ :group 'which-key
+ :type '(choice float (const :tag "Disabled" nil)))
+
+(defcustom which-key-echo-keystrokes (if (and echo-keystrokes
+ (> (+ echo-keystrokes 0.01)
+ which-key-idle-delay))
+ (/ (float which-key-idle-delay) 4)
+ echo-keystrokes)
+ "Value to use for `echo-keystrokes'.
+This only applies if `which-key-popup-type' is minibuffer or
+`which-key-show-prefix' is echo. It needs to be less than
+`which-key-idle-delay' or else the keystroke echo will erase the
+which-key popup."
+ :group 'which-key
+ :type 'float)
+
+(defcustom which-key-max-description-length 27
+ "Truncate the description of keys to this length.
+Also adds \"..\". If nil, disable any truncation."
+ :group 'which-key
+ :type '(choice integer (const :tag "Disable truncation" nil)))
+
+(defcustom which-key-min-column-description-width 0
+ "Every column should at least have this width."
+ :group 'which-key
+ :type 'integer)
+
+(defcustom which-key-add-column-padding 0
+ "Additional padding (number of spaces) to add to the left of
+each key column."
+ :group 'which-key
+ :type 'integer)
+
+(defcustom which-key-unicode-correction 3
+ "Correction for wide unicode characters.
+Since we measure width in terms of the number of characters,
+Unicode characters that are wider than ASCII characters throw off
+the calculation for available width in the which-key buffer. This
+variable allows you to adjust for the wide unicode characters by
+artificially reducing the available width in the buffer.
+
+The default of 3 means allow for the total extra width
+contributed by any wide unicode characters to be up to one
+additional ASCII character in the which-key buffer. Increase this
+number if you are seeing characters get cutoff on the right side
+of the which-key popup."
+ :group 'which-key
+ :type 'integer)
+
+(defcustom which-key-dont-use-unicode nil
+ "If non-nil, don't use any unicode characters in default setup."
+ :group 'which-key
+ :type 'boolean)
+
+(defcustom which-key-separator
+ (if which-key-dont-use-unicode " : " " → ")
+ "Separator to use between key and description. Default is \" →
+\", unless `which-key-dont-use-unicode' is non nil, in which case
+the default is \" : \"."
+ :group 'which-key
+ :type 'string)
+
+(defcustom which-key-ellipsis
+ (if which-key-dont-use-unicode ".." "…")
+ "Ellipsis to use when truncating. Default is \"…\", unless
+`which-key-dont-use-unicode' is non nil, in which case
+the default is \"..\"."
+ :group 'which-key
+ :type 'string)
+
+
+(defcustom which-key-prefix-prefix "+"
+ "String to insert in front of prefix commands (i.e., commands
+that represent a sub-map). Default is \"+\"."
+ :group 'which-key
+ :type 'string)
+
+(defcustom which-key-compute-remaps nil
+ "If non-nil, show remapped command if a command has been
+remapped given the currently active keymaps."
+ :group 'which-key
+ :type 'boolean)
+
+(defcustom which-key-replacement-alist
+ (delq nil
+ `(((nil . "which-key-show-next-page-no-cycle") . (nil . "wk next pg"))
+ ,@(unless which-key-dont-use-unicode
+ '((("<left>") . ("←"))
+ (("<right>") . ("→"))))
+ (("<\\([[:alnum:]-]+\\)>") . ("\\1"))))
+ "Association list to determine how to manipulate descriptions
+of key bindings in the which-key popup. Each element of the list
+is a nested cons cell with the format
+
+\(MATCH CONS . REPLACEMENT\).
+
+The MATCH CONS determines when a replacement should occur and
+REPLACEMENT determines how the replacement should occur. Each may
+have the format \(KEY REGEXP . BINDING REGEXP\). For the
+replacement to apply the key binding must match both the KEY
+REGEXP and the BINDING REGEXP. A value of nil in either position
+can be used to match every possibility. The replacement is
+performed by using `replace-regexp-in-string' on the KEY REGEXP
+from the MATCH CONS and REPLACEMENT when it is a cons cell, and
+then similarly for the BINDING REGEXP. A nil value in the BINDING
+REGEXP position cancels the replacement. For example, the entry
+
+\(\(nil . \"Prefix Command\"\) . \(nil . \"prefix\"\)\)
+
+matches any binding with the descriptions \"Prefix Command\" and
+replaces the description with \"prefix\", ignoring the
+corresponding key.
+
+REPLACEMENT may also be a function taking a cons cell
+\(KEY . BINDING\) and producing a new corresponding cons cell.
+
+If REPLACEMENT is anything other than a cons cell \(and non nil\)
+the key binding is ignored by which-key.
+
+Finally, you can multiple replacements to occur for a given key
+binding by setting `which-key-allow-multiple-replacements' to a
+non-nil value."
+ :group 'which-key
+ :type '(alist :key-type (cons (choice regexp (const nil))
+ (choice regexp (const nil)))
+ :value-type (cons (choice string (const nil))
+ (choice string (const nil)))))
+
+(defcustom which-key-allow-multiple-replacements nil
+ "Allow a key binding to match and be modified by multiple
+elements in `which-key-replacement-alist' if non-nil. When nil,
+only the first match is used to perform replacements from
+`which-key-replacement-alist'."
+ :group 'which-key
+ :type 'boolean)
+
+(defcustom which-key-show-docstrings nil
+ "If non-nil, show each command's docstring next to the command
+in the which-key buffer. This will only display the docstring up
+to the first line break. If you set this variable to the symbol
+docstring-only, then the command's name with be omitted. You
+probably also want to adjust `which-key-max-description-length'
+at the same time if you use this feature."
+ :group 'which-key
+ :type '(radio
+ (const :tag "Do not show docstrings" nil)
+ (const :tag "Add docstring to command names" t)
+ (const :tag "Replace command name with docstring" docstring-only)))
+
+(defcustom which-key-highlighted-command-list '()
+ "A list of strings and/or cons cells used to highlight certain
+commands. If the element is a string, assume it is a regexp
+pattern for matching command names and use
+`which-key-highlighted-command-face' for any matching names. If
+the element is a cons cell, it should take the form (regexp .
+face to apply)."
+ :group 'which-key
+ :type '(repeat (choice string (cons regexp face))))
+
+(defcustom which-key-special-keys '()
+ "These keys will automatically be truncated to one character
+and have `which-key-special-key-face' applied to them. This is
+disabled by default. Try this to see the effect.
+
+\(setq which-key-special-keys '(\"SPC\" \"TAB\" \"RET\" \"ESC\" \"DEL\")\)"
+ :group 'which-key
+ :type '(repeat string))
+
+(defcustom which-key-buffer-name " *which-key*"
+ "Name of which-key buffer."
+ :group 'which-key
+ :type 'string)
+
+(defcustom which-key-show-prefix 'echo
+ "Whether to and where to display the current prefix sequence
+Possible choices are echo for echo area (the default), left, top
+and nil. Nil turns the feature off."
+ :group 'which-key
+ :type '(radio (const :tag "Left of the keys" left)
+ (const :tag "In the first line" top)
+ (const :tag "In the last line" bottom)
+ (const :tag "In the echo area" echo)
+ (const :tag "In the mode-line" mode-line)
+ (const :tag "Hide" nil)))
+
+(defcustom which-key-popup-type 'side-window
+ "Supported types are minibuffer, side-window, frame, and custom"
+ :group 'which-key
+ :type '(radio (const :tag "Show in minibuffer" minibuffer)
+ (const :tag "Show in side window" side-window)
+ (const :tag "Show in popup frame" frame)
+ (const :tag "Use your custom display functions" custom)))
+
+(defcustom which-key-min-display-lines 1
+ "Minimum number of horizontal lines to display in the which-key buffer"
+ :group 'which-key
+ :type 'integer)
+
+(defcustom which-key-max-display-columns nil
+ "Maximum number of columns to display in the which-key buffer
+nil means don't impose a maximum."
+ :group 'which-key
+ :type '(choice integer (const :tag "Unbounded" nil)))
+
+(defcustom which-key-side-window-location 'bottom
+ "Location of which-key popup when `which-key-popup-type' is side-window.
+Should be one of top, bottom, left or right. You can also specify
+a list of two locations, like (right bottom). In this case, the
+first location is tried. If there is not enough room, the second
+location is tried."
+ :group 'which-key
+ :type '(radio (const right)
+ (const bottom)
+ (const left)
+ (const top)
+ (const (right bottom))
+ (const (bottom right))))
+
+(defcustom which-key-side-window-slot 0
+ "The `slot' to use for `display-buffer-in-side-window' when
+`which-key-popup-type' is 'side-window. Quoting from the
+docstring of `display-buffer-in-side-window',
+
+‘slot’ if non-nil, specifies the window slot where to display
+BUFFER. A value of zero or nil means use the middle slot on the
+specified side. A negative value means use a slot
+preceding (that is, above or on the left of) the middle slot. A
+positive value means use a slot following (that is, below or on
+the right of) the middle slot. The default is zero."
+ :group 'which-key
+ :type 'integer)
+
+(defcustom which-key-side-window-max-width 0.333
+ "Maximum width of which-key popup when type is side-window
+This variable can also be a number between 0 and 1. In that case,
+it denotes a percentage out of the frame's width."
+ :group 'which-key
+ :type 'float)
+
+(defcustom which-key-side-window-max-height 0.25
+ "Maximum height of which-key popup when type is side-window
+This variable can also be a number between 0 and 1. In that case, it denotes
+a percentage out of the frame's height."
+ :group 'which-key
+ :type 'float)
+
+(defcustom which-key-frame-max-width 60
+ "Maximum width of which-key popup when type is frame."
+ :group 'which-key
+ :type 'integer)
+
+(defcustom which-key-frame-max-height 20
+ "Maximum height of which-key popup when type is frame."
+ :group 'which-key
+ :type 'integer)
+
+(defcustom which-key-allow-imprecise-window-fit (not (display-graphic-p))
+ "If non-nil allow which-key to use a less intensive method of
+fitting the popup window to the buffer. If you are noticing lag
+when the which-key popup displays turning this on may help.
+
+See https://github.com/justbur/emacs-which-key/issues/130
+and https://github.com/justbur/emacs-which-key/issues/225."
+ :group 'which-key
+ :type 'boolean)
+
+(defcustom which-key-show-remaining-keys nil
+ "Show remaining keys in last slot, when keys are hidden."
+ :group 'which-key
+ :type '(radio (const :tag "Yes" t)
+ (const :tag "No" nil)))
+
+(defcustom which-key-sort-order 'which-key-key-order
+ "If nil, do not resort the output from
+`describe-buffer-bindings' which groups by mode. Ordering options
+are
+
+1. `which-key-key-order': by key (default)
+2. `which-key-key-order-alpha': by key using alphabetical order
+3. `which-key-description-order': by description
+4. `which-key-prefix-then-key-order': prefix (no prefix first) then key
+5. `which-key-local-then-key-order': local binding then key
+
+See the README and the docstrings for those functions for more
+information."
+ :group 'which-key
+ :type '(choice (function-item which-key-key-order)
+ (function-item which-key-key-order-alpha)
+ (function-item which-key-description-order)
+ (function-item which-key-prefix-then-key-order)
+ (function-item which-key-local-then-key-order)))
+
+(defcustom which-key-sort-uppercase-first t
+ "If non-nil, uppercase comes before lowercase in sorting
+function chosen in `which-key-sort-order'. Otherwise, the order
+is reversed."
+ :group 'which-key
+ :type 'boolean)
+
+(defcustom which-key-paging-prefixes '()
+ "Enable paging for these prefixes."
+ :group 'which-key
+ :type '(repeat string))
+
+(defcustom which-key-paging-key "<f5>"
+ "Key to use for changing pages. Bound after each of the
+prefixes in `which-key-paging-prefixes'"
+ :group 'which-key
+ :type 'string)
+
+;; (defcustom which-key-undo-key nil
+;; "Key (string) to use for undoing keypresses. Bound recursively
+;; in each of the maps in `which-key-undo-keymaps'."
+;; :group 'which-key
+;; :type 'string)
+
+;; (defcustom which-key-undo-keymaps '()
+;; "Keymaps in which to bind `which-key-undo-key'"
+;; :group 'which-key
+;; :type '(repeat symbol))
+
+(defcustom which-key-use-C-h-commands t
+ "Use C-h (or whatever `help-char' is set to) for paging if
+non-nil. Normally C-h after a prefix calls
+`describe-prefix-bindings'. This changes that command to a
+which-key paging command when which-key-mode is active."
+ :group 'which-key
+ :type 'boolean)
+
+(defcustom which-key-show-early-on-C-h nil
+ "Show the which-key buffer before if C-h (or whatever
+`help-char' is set to) is pressed in the middle of a prefix
+before the which-key buffer would normally be triggered through
+the idle delay. If combined with the following settings,
+which-key will effectively only show when triggered \"manually\"
+using C-h.
+
+\(setq `which-key-idle-delay' 10000)
+\(setq `which-key-idle-secondary-delay' 0.05)
+
+Note that `which-key-idle-delay' should be set before turning on
+`which-key-mode'. "
+ :group 'which-key
+ :type 'boolean)
+
+(defcustom which-key-is-verbose nil
+ "Whether to warn about potential mistakes in configuration."
+ :group 'which-key
+ :type 'boolean)
+
+(defcustom which-key-preserve-window-configuration nil
+ "If non-nil, save window configuration before which-key buffer is shown
+and restore it after which-key buffer is hidden. It prevents which-key from
+changing window position of visible buffers.
+Only takken into account when popup type is side-window."
+ :group
+ 'which-key
+ :type 'boolean)
+
+(defvar which-key-C-h-map
+ (let ((map (make-sparse-keymap)))
+ (dolist (bind `(("\C-a" . which-key-abort)
+ ("a" . which-key-abort)
+ ("\C-d" . which-key-toggle-docstrings)
+ ("d" . which-key-toggle-docstrings)
+ (,(vector help-char) . which-key-show-standard-help)
+ ("h" . which-key-show-standard-help)
+ ("\C-n" . which-key-show-next-page-cycle)
+ ("n" . which-key-show-next-page-cycle)
+ ("\C-p" . which-key-show-previous-page-cycle)
+ ("p" . which-key-show-previous-page-cycle)
+ ("\C-u" . which-key-undo-key)
+ ("u" . which-key-undo-key)
+ ("1" . which-key-digit-argument)
+ ("2" . which-key-digit-argument)
+ ("3" . which-key-digit-argument)
+ ("4" . which-key-digit-argument)
+ ("5" . which-key-digit-argument)
+ ("6" . which-key-digit-argument)
+ ("7" . which-key-digit-argument)
+ ("8" . which-key-digit-argument)
+ ("9" . which-key-digit-argument)))
+ (define-key map (car bind) (cdr bind)))
+ map)
+ "Keymap for C-h commands.")
+
+(defvar which-key--paging-functions '(which-key-C-h-dispatch
+ which-key-manual-update
+ which-key-turn-page
+ which-key-show-next-page-cycle
+ which-key-show-next-page-no-cycle
+ which-key-show-previous-page-cycle
+ which-key-show-previous-page-no-cycle
+ which-key-undo-key
+ which-key-undo))
+
+(defvar which-key-persistent-popup nil
+ "Whether or not to disable `which-key--hide-popup'.")
+
+(defcustom which-key-hide-alt-key-translations t
+ "Hide key translations using Alt key if non nil.
+These translations are not relevant most of the times since a lot
+of terminals issue META modifier for the Alt key.
+
+See http://www.gnu.org/software/emacs/manual/html_node/emacs/Modifier-Keys.html"
+ :group 'which-key
+ :type 'boolean)
+
+(defcustom which-key-delay-functions nil
+ "A list of functions that may decide whether to delay the
+which-key popup based on the current incomplete key
+sequence. Each function in the list is run with two arguments,
+the current key sequence as produced by `key-description' and the
+length of the key sequence. If the popup should be delayed based
+on that key sequence, the function should return the delay time
+in seconds. Returning nil means no delay. The first function in
+this list to return a value is the value that is used.
+
+The delay time is effectively added to the normal
+`which-key-idle-delay'."
+ :group 'which-key
+ :type '(repeat function))
+
+(defcustom which-key-allow-regexps nil
+ "A list of regexp strings to use to filter key sequences.
+When non-nil, for a key sequence to trigger the which-key popup
+it must match one of the regexps in this list. The format of the
+key sequences is what is produced by `key-description'."
+ :group 'which-key
+ :type '(repeat regexp))
+
+(defcustom which-key-inhibit-regexps nil
+ "Similar to `which-key-allow-regexps', a list of regexp strings
+to use to filter key sequences. When non-nil, for a key sequence
+to trigger the which-key popup it cannot match one of the regexps
+in this list. The format of the key sequences is what is produced
+by `key-description'."
+ :group 'which-key
+ :type '(repeat regexp))
+
+(defcustom which-key-show-transient-maps nil
+ "Show keymaps created by `set-transient-map' when applicable.
+
+More specifically, detect when `overriding-terminal-local-map' is
+set (this is the keymap used by `set-transient-map') and display
+it."
+ :group 'which-key
+ :type 'boolean)
+
+(make-obsolete-variable
+ 'which-key-enable-extended-define-key
+ "which-key-enable-extended-define-key is obsolete and has no effect."
+ "2021-06-21")
+
+;; Hooks
+(defcustom which-key-init-buffer-hook '()
+ "Hook run when which-key buffer is initialized."
+ :group 'which-key
+ :type 'hook)
+
+;;;; Faces
+
+(defgroup which-key-faces nil
+ "Faces for which-key-mode"
+ :group 'which-key
+ :prefix "which-key-")
+
+(defface which-key-key-face
+ '((t . (:inherit font-lock-constant-face)))
+ "Face for which-key keys"
+ :group 'which-key-faces)
+
+(defface which-key-separator-face
+ '((t . (:inherit font-lock-comment-face)))
+ "Face for the separator (default separator is an arrow)"
+ :group 'which-key-faces)
+
+(defface which-key-note-face
+ '((t . (:inherit which-key-separator-face)))
+ "Face for notes or hints occasionally provided"
+ :group 'which-key-faces)
+
+(defface which-key-command-description-face
+ '((t . (:inherit font-lock-function-name-face)))
+ "Face for the key description when it is a command"
+ :group 'which-key-faces)
+
+(defface which-key-local-map-description-face
+ '((t . (:inherit which-key-command-description-face)))
+ "Face for the key description when it is found in `current-local-map'"
+ :group 'which-key-faces)
+
+(defface which-key-highlighted-command-face
+ '((t . (:inherit which-key-command-description-face :underline t)))
+ "Default face for the command description when it is a command
+and it matches a string in `which-key-highlighted-command-list'."
+ :group 'which-key-faces)
+
+(defface which-key-group-description-face
+ '((t . (:inherit font-lock-keyword-face)))
+ "Face for the key description when it is a group or prefix"
+ :group 'which-key-faces)
+
+(defface which-key-special-key-face
+ '((t . (:inherit which-key-key-face :inverse-video t :weight bold)))
+ "Face for special keys (SPC, TAB, RET)"
+ :group 'which-key-faces)
+
+(defface which-key-docstring-face
+ '((t . (:inherit which-key-note-face)))
+ "Face for docstrings"
+ :group 'which-key-faces)
+
+;;;; Custom popup
+
+(defcustom which-key-custom-popup-max-dimensions-function nil
+ "Variable to hold a custom max-dimensions function.
+Will be passed the width of the active window and is expected to
+return the maximum height in lines and width in characters of the
+which-key popup in the form a cons cell (height . width)."
+ :group 'which-key
+ :type '(choice function (const nil)))
+
+(defcustom which-key-custom-hide-popup-function nil
+ "Variable to hold a custom hide-popup function.
+It takes no arguments and the return value is ignored."
+ :group 'which-key
+ :type '(choice function (const nil)))
+
+(defcustom which-key-custom-show-popup-function nil
+ "Variable to hold a custom show-popup function.
+Will be passed the required dimensions in the form (height .
+width) in lines and characters respectively. The return value is
+ignored."
+ :group 'which-key
+ :type '(choice function (const nil)))
+
+(defcustom which-key-lighter " WK"
+ "Minor mode lighter to use in the mode-line."
+ :group 'which-key
+ :type 'string)
+
+(defvar which-key-inhibit nil
+ "Prevent which-key from popping up momentarily by setting this
+to a non-nil value for the execution of a command. Like this
+
+\(let \(\(which-key-inhibit t\)\)
+...\)")
+
+(defvar which-key-keymap-history nil
+ "History of keymap selections in functions like
+`which-key-show-keymap'.")
+
+;;; Internal Vars
+
+(defvar which-key--buffer nil
+ "Internal: Holds reference to which-key buffer.")
+(defvar which-key--timer nil
+ "Internal: Holds reference to open window timer.")
+(defvar which-key--secondary-timer-active nil
+ "Internal: Non-nil if the secondary timer is active.")
+(defvar which-key--paging-timer nil
+ "Internal: Holds reference to timer for paging.")
+(defvar which-key--frame nil
+ "Internal: Holds reference to which-key frame.
+Used when `which-key-popup-type' is frame.")
+(defvar which-key--echo-keystrokes-backup nil
+ "Internal: Backup the initial value of `echo-keystrokes'.")
+(defvar which-key--prefix-help-cmd-backup nil
+ "Internal: Backup the value of `prefix-help-command'.")
+(defvar which-key--last-try-2-loc nil
+ "Internal: Last location of side-window when two locations
+used.")
+(defvar which-key--automatic-display nil
+ "Internal: Non-nil if popup was triggered with automatic
+update.")
+(defvar which-key--debug-buffer-name nil
+ "If non-nil, use this buffer for debug messages.")
+(defvar which-key--multiple-locations nil)
+(defvar which-key--inhibit-next-operator-popup nil)
+(defvar which-key--prior-show-keymap-args nil)
+(defvar which-key--previous-frame-size nil)
+(defvar which-key--prefix-title-alist nil)
+(defvar which-key--evil-keys-regexp (eval-when-compile
+ (regexp-opt '("-state"))))
+(defvar which-key--ignore-non-evil-keys-regexp
+ (eval-when-compile
+ (regexp-opt '("mouse-" "wheel-" "remap" "drag-" "scroll-bar"
+ "select-window" "switch-frame" "which-key"))))
+(defvar which-key--ignore-keys-regexp
+ (eval-when-compile
+ (regexp-opt '("mouse-" "wheel-" "remap" "drag-" "scroll-bar"
+ "select-window" "switch-frame" "-state"
+ "which-key"))))
+
+(defvar which-key--pages-obj nil)
+(cl-defstruct which-key--pages
+ pages
+ height
+ widths
+ keys/page
+ page-nums
+ num-pages
+ total-keys
+ prefix
+ prefix-title)
+
+(defvar which-key--saved-window-configuration nil)
+
+(defun which-key--rotate (list n)
+ (let* ((len (length list))
+ (n (if (< n 0) (+ len n) n))
+ (n (mod n len)))
+ (append (last list (- len n)) (butlast list (- len n)))))
+
+(defun which-key--pages-set-current-page (pages-obj n)
+ (setf (which-key--pages-pages pages-obj)
+ (which-key--rotate (which-key--pages-pages pages-obj) n))
+ (setf (which-key--pages-widths pages-obj)
+ (which-key--rotate (which-key--pages-widths pages-obj) n))
+ (setf (which-key--pages-keys/page pages-obj)
+ (which-key--rotate (which-key--pages-keys/page pages-obj) n))
+ (setf (which-key--pages-page-nums pages-obj)
+ (which-key--rotate (which-key--pages-page-nums pages-obj) n))
+ pages-obj)
+
+(defsubst which-key--on-first-page ()
+ (= (which-key--pages-page-nums which-key--pages-obj) 1))
+
+(defsubst which-key--on-last-page ()
+ (= (which-key--pages-page-nums which-key--pages-obj)
+ (which-key--pages-num-pages which-key--pages-obj)))
+
+(defsubst which-key--current-prefix ()
+ (and which-key--pages-obj
+ (which-key--pages-prefix which-key--pages-obj)))
+
+(defmacro which-key--debug-message (&rest msg)
+ `(when which-key--debug-buffer-name
+ (let ((buf (get-buffer-create which-key--debug-buffer-name))
+ (fmt-msg (format ,@msg)))
+ (with-current-buffer buf
+ (goto-char (point-max))
+ (insert "\n" fmt-msg "\n")))))
+
+(defsubst which-key--safe-lookup-key (keymap key)
+ "Version of `lookup-key' that allows KEYMAP to be nil.
+Also convert numeric results of `lookup-key' to nil. KEY is not
+checked."
+ (when (keymapp keymap)
+ (let ((result (lookup-key keymap key)))
+ (when (and result (not (numberp result)))
+ result))))
+
+;;; Third-party library support
+;;;; Evil
+
+(defvar evil-state nil)
+
+(defcustom which-key-allow-evil-operators (boundp 'evil-this-operator)
+ "Allow popup to show for evil operators.
+The popup is normally inhibited in the middle of commands, but
+setting this to non-nil will override this behavior for evil
+operators."
+ :group 'which-key
+ :type 'boolean)
+
+(defcustom which-key-show-operator-state-maps nil
+ "Experimental: Try to show the right keys following an evil
+command that reads a motion, such as \"y\", \"d\" and \"c\" from
+normal state. This is experimental, because there might be some
+valid keys missing and it might be showing some invalid keys."
+ :group 'which-key
+ :type 'boolean)
+
+;;;; God-mode
+
+(defvar which-key--god-mode-support-enabled nil
+ "Support god-mode if non-nil. This is experimental,
+so you need to explicitly opt-in for now. Please report any
+problems at github.")
+
+(defvar which-key--god-mode-key-string nil
+ "Holds key string to use for god-mode support.")
+
+(defun which-key--god-mode-lookup-command-advice (orig-fun arg1 &rest args)
+ (setq which-key--god-mode-key-string arg1)
+ (unwind-protect
+ (apply orig-fun arg1 args)
+ (when (bound-and-true-p which-key-mode)
+ (which-key--hide-popup))))
+
+(defun which-key-enable-god-mode-support (&optional disable)
+ "Enable support for god-mode if non-nil.
+This is experimental, so you need to explicitly opt-in for
+now. Please report any problems at github. If DISABLE is non-nil
+disable support."
+ (interactive "P")
+ (setq which-key--god-mode-support-enabled (null disable))
+ (if disable
+ (advice-remove 'god-mode-lookup-command
+ #'which-key--god-mode-lookup-command-advice)
+ (advice-add 'god-mode-lookup-command :around
+ #'which-key--god-mode-lookup-command-advice)))
+
+;;; Mode
+
+;;;###autoload
+(define-minor-mode which-key-mode
+ "Toggle which-key-mode."
+ :global t
+ :lighter which-key-lighter
+ :keymap (let ((map (make-sparse-keymap)))
+ (mapc
+ (lambda (prefix)
+ (define-key map
+ (kbd (concat prefix " " which-key-paging-key))
+ #'which-key-C-h-dispatch))
+ which-key-paging-prefixes)
+ map)
+ (if which-key-mode
+ (progn
+ (setq which-key--echo-keystrokes-backup echo-keystrokes)
+ (when (or (eq which-key-show-prefix 'echo)
+ (eq which-key-popup-type 'minibuffer))
+ (which-key--setup-echo-keystrokes))
+ (unless (member prefix-help-command which-key--paging-functions)
+ (setq which-key--prefix-help-cmd-backup prefix-help-command))
+ (when (or which-key-use-C-h-commands
+ which-key-show-early-on-C-h)
+ (setq prefix-help-command #'which-key-C-h-dispatch))
+ (when which-key-show-remaining-keys
+ (add-hook 'pre-command-hook #'which-key--lighter-restore))
+ (add-hook 'pre-command-hook #'which-key--hide-popup)
+ (add-hook 'window-size-change-functions
+ #'which-key--hide-popup-on-frame-size-change)
+ (which-key--start-timer))
+ (setq echo-keystrokes which-key--echo-keystrokes-backup)
+ (when which-key--prefix-help-cmd-backup
+ (setq prefix-help-command which-key--prefix-help-cmd-backup))
+ (when which-key-show-remaining-keys
+ (remove-hook 'pre-command-hook #'which-key--lighter-restore))
+ (remove-hook 'pre-command-hook #'which-key--hide-popup)
+ (remove-hook 'window-size-change-functions
+ #'which-key--hide-popup-on-frame-size-change)
+ (which-key--stop-timer)))
+
+(defun which-key--init-buffer ()
+ "Initialize which-key buffer"
+ (unless (buffer-live-p which-key--buffer)
+ (setq which-key--buffer (get-buffer-create which-key-buffer-name))
+ (with-current-buffer which-key--buffer
+ ;; suppress confusing minibuffer message
+ (let (message-log-max)
+ (toggle-truncate-lines 1)
+ (message ""))
+ (setq-local cursor-type nil)
+ (setq-local cursor-in-non-selected-windows nil)
+ (setq-local mode-line-format nil)
+ (setq-local header-line-format nil)
+ (setq-local word-wrap nil)
+ (setq-local show-trailing-whitespace nil)
+ (run-hooks 'which-key-init-buffer-hook))))
+
+(defun which-key--setup-echo-keystrokes ()
+ "Reduce `echo-keystrokes' if necessary (it will interfere if
+it's set too high)."
+ (when (and echo-keystrokes
+ (> (abs (- echo-keystrokes which-key-echo-keystrokes)) 0.000001))
+ (if (> which-key-idle-delay which-key-echo-keystrokes)
+ (setq echo-keystrokes which-key-echo-keystrokes)
+ (setq which-key-echo-keystrokes (/ (float which-key-idle-delay) 4)
+ echo-keystrokes which-key-echo-keystrokes))))
+
+(defun which-key-remove-default-unicode-chars ()
+ "Use of `which-key-dont-use-unicode' is preferred to this
+function, but it's included here in case someone cannot set that
+variable early enough in their configuration, if they are using a
+starter kit for example."
+ (when (string-equal which-key-separator " → ")
+ (setq which-key-separator " : ")))
+
+;;; Default configuration functions for use by users.
+
+;;;###autoload
+(defun which-key-setup-side-window-right ()
+ "Apply suggested settings for side-window that opens on right."
+ (interactive)
+ (setq which-key-popup-type 'side-window
+ which-key-side-window-location 'right
+ which-key-show-prefix 'top))
+
+;;;###autoload
+(defun which-key-setup-side-window-right-bottom ()
+ "Apply suggested settings for side-window that opens on right
+if there is space and the bottom otherwise."
+ (interactive)
+ (setq which-key-popup-type 'side-window
+ which-key-side-window-location '(right bottom)
+ which-key-show-prefix 'top))
+
+;;;###autoload
+(defun which-key-setup-side-window-bottom ()
+ "Apply suggested settings for side-window that opens on bottom."
+ (interactive)
+ (which-key--setup-echo-keystrokes)
+ (setq which-key-popup-type 'side-window
+ which-key-side-window-location 'bottom
+ which-key-show-prefix 'echo))
+
+;;;###autoload
+(defun which-key-setup-minibuffer ()
+ "Apply suggested settings for minibuffer.
+Do not use this setup if you use the paging commands. Instead use
+`which-key-setup-side-window-bottom', which is nearly identical
+but more functional."
+ (interactive)
+ (which-key--setup-echo-keystrokes)
+ (setq which-key-popup-type 'minibuffer
+ which-key-show-prefix 'left))
+
+;;; Helper functions to modify replacement lists.
+
+;;;###autoload
+(defun which-key-add-keymap-based-replacements (keymap key replacement &rest more)
+ "Replace the description of KEY using REPLACEMENT in KEYMAP.
+KEY should take a format suitable for use in `kbd'. REPLACEMENT
+should be a cons cell of the form \(STRING . COMMAND\) for each
+REPLACEMENT, where STRING is the replacement string and COMMAND
+is a symbol corresponding to the intended command to be
+replaced. COMMAND can be nil if the binding corresponds to a key
+prefix. An example is
+
+\(which-key-add-keymap-based-replacements global-map
+ \"C-x w\" '\(\"Save as\" . write-file\)\).
+
+For backwards compatibility, REPLACEMENT can also be a string,
+but the above format is preferred, and the option to use a string
+for REPLACEMENT will eventually be removed."
+ (while key
+ (let ((def
+ (cond
+ ((consp replacement) replacement)
+ ((stringp replacement)
+ (cons replacement
+ (or (which-key--safe-lookup-key keymap (kbd key))
+ (make-sparse-keymap))))
+ (t
+ (user-error "replacement is neither a cons cell or a string")))))
+ (define-key keymap (kbd key) def))
+ (setq key (pop more)
+ replacement (pop more))))
+(put 'which-key-add-keymap-based-replacements 'lisp-indent-function 'defun)
+
+;;;###autoload
+(defun which-key-add-key-based-replacements
+ (key-sequence replacement &rest more)
+ "Replace the description of KEY-SEQUENCE with REPLACEMENT.
+KEY-SEQUENCE is a string suitable for use in `kbd'. REPLACEMENT
+may either be a string, as in
+
+\(which-key-add-key-based-replacements \"C-x 1\" \"maximize\"\)
+
+a cons of two strings as in
+
+\(which-key-add-key-based-replacements \"C-x 8\"
+ '(\"unicode\" . \"Unicode keys\")\)
+
+or a function that takes a \(KEY . BINDING\) cons and returns a
+replacement.
+
+In the second case, the second string is used to provide a longer
+name for the keys under a prefix.
+
+MORE allows you to specifcy additional KEY REPLACEMENT pairs. All
+replacements are added to `which-key-replacement-alist'."
+ ;; TODO: Make interactive
+ (while key-sequence
+ ;; normalize key sequences before adding
+ (let ((key-seq (key-description (kbd key-sequence)))
+ (replace (or (and (functionp replacement) replacement)
+ (car-safe replacement)
+ replacement)))
+ (push (cons (cons (concat "\\`" (regexp-quote key-seq) "\\'") nil)
+ (if (functionp replace) replace (cons nil replace)))
+ which-key-replacement-alist)
+ (when (and (not (functionp replacement)) (consp replacement))
+ (push (cons key-seq (cdr-safe replacement))
+ which-key--prefix-title-alist)))
+ (setq key-sequence (pop more) replacement (pop more))))
+(put 'which-key-add-key-based-replacements 'lisp-indent-function 'defun)
+
+;;;###autoload
+(defun which-key-add-major-mode-key-based-replacements
+ (mode key-sequence replacement &rest more)
+ "Functions like `which-key-add-key-based-replacements'.
+The difference is that MODE specifies the `major-mode' that must
+be active for KEY-SEQUENCE and REPLACEMENT (MORE contains
+addition KEY-SEQUENCE REPLACEMENT pairs) to apply."
+ ;; TODO: Make interactive
+ (when (not (symbolp mode))
+ (error "MODE should be a symbol corresponding to a value of major-mode"))
+ (let ((mode-alist
+ (or (cdr-safe (assq mode which-key-replacement-alist)) (list)))
+ (title-mode-alist
+ (or (cdr-safe (assq mode which-key--prefix-title-alist)) (list))))
+ (while key-sequence
+ ;; normalize key sequences before adding
+ (let ((key-seq (key-description (kbd key-sequence)))
+ (replace (or (and (functionp replacement) replacement)
+ (car-safe replacement)
+ replacement)))
+ (push (cons (cons (concat "\\`" (regexp-quote key-seq) "\\'") nil)
+ (if (functionp replace) replace (cons nil replace)))
+ mode-alist)
+ (when (and (not (functionp replacement)) (consp replacement))
+ (push (cons key-seq (cdr-safe replacement))
+ title-mode-alist)))
+ (setq key-sequence (pop more) replacement (pop more)))
+ (if (assq mode which-key-replacement-alist)
+ (setcdr (assq mode which-key-replacement-alist) mode-alist)
+ (push (cons mode mode-alist) which-key-replacement-alist))
+ (if (assq mode which-key--prefix-title-alist)
+ (setcdr (assq mode which-key--prefix-title-alist) title-mode-alist)
+ (push (cons mode title-mode-alist) which-key--prefix-title-alist))))
+(put 'which-key-add-major-mode-key-based-replacements
+ 'lisp-indent-function 'defun)
+
+(defun which-key-define-key-recursively (map key def &optional at-root)
+ "Recursively bind KEY in MAP to DEF on every level of MAP except the first.
+If AT-ROOT is non-nil the binding is also placed at the root of MAP."
+ (when at-root (define-key map key def))
+ (map-keymap
+ (lambda (_ev df)
+ (when (keymapp df)
+ (which-key-define-key-recursively df key def t)))
+ map))
+
+;;; Functions for computing window sizes
+
+(defun which-key--text-width-to-total (text-width)
+ "Convert window text-width to window total-width.
+TEXT-WIDTH is the desired text width of the window. The function
+calculates what total width is required for a window in the
+selected to have a text-width of TEXT-WIDTH columns. The
+calculation considers possible fringes and scroll bars. This
+function assumes that the desired window has the same character
+width as the frame."
+ (let ((char-width (frame-char-width)))
+ (+ text-width
+ (/ (frame-fringe-width) char-width)
+ (/ (frame-scroll-bar-width) char-width)
+ (if (which-key--char-enlarged-p) 1 0)
+ ;; add padding to account for possible wide (unicode) characters
+ 3)))
+
+(defun which-key--total-width-to-text (total-width)
+ "Convert window total-width to window text-width.
+TOTAL-WIDTH is the desired total width of the window. The function calculates
+what text width fits such a window. The calculation considers possible fringes
+and scroll bars. This function assumes that the desired window has the same
+character width as the frame."
+ (let ((char-width (frame-char-width)))
+ (- total-width
+ (/ (frame-fringe-width) char-width)
+ (/ (frame-scroll-bar-width) char-width)
+ (if (which-key--char-enlarged-p) 1 0)
+ ;; add padding to account for possible wide (unicode) characters
+ 3)))
+
+(defun which-key--char-enlarged-p (&optional _frame)
+ (> (frame-char-width)
+ (/ (float (frame-pixel-width)) (window-total-width (frame-root-window)))))
+
+(defun which-key--char-reduced-p (&optional _frame)
+ (< (frame-char-width)
+ (/ (float (frame-pixel-width)) (window-total-width (frame-root-window)))))
+
+(defun which-key--char-exact-p (&optional _frame)
+ (= (frame-char-width)
+ (/ (float (frame-pixel-width)) (window-total-width (frame-root-window)))))
+
+(defun which-key--width-or-percentage-to-width (width-or-percentage)
+ "Return window total width.
+If WIDTH-OR-PERCENTAGE is a whole number, return it unchanged. Otherwise, it
+should be a percentage (a number between 0 and 1) out of the frame's width.
+More precisely, it should be a percentage out of the frame's root window's
+total width."
+ (if (wholenump width-or-percentage)
+ width-or-percentage
+ (round (* width-or-percentage (window-total-width (frame-root-window))))))
+
+(defun which-key--height-or-percentage-to-height (height-or-percentage)
+ "Return window total height.
+If HEIGHT-OR-PERCENTAGE is a whole number, return it unchanged. Otherwise, it
+should be a percentage (a number between 0 and 1) out of the frame's height.
+More precisely, it should be a percentage out of the frame's root window's
+total height."
+ (if (wholenump height-or-percentage)
+ height-or-percentage
+ (round (* height-or-percentage (window-total-height (frame-root-window))))))
+
+(defun which-key--frame-size-changed-p ()
+ "Non-nil if a change in frame size is detected."
+ (let ((new-size (cons (frame-width) (frame-height))))
+ (cond ((null which-key--previous-frame-size)
+ (setq which-key--previous-frame-size new-size)
+ nil)
+ ((not (equal which-key--previous-frame-size new-size))
+ (setq which-key--previous-frame-size new-size)))))
+
+;;; Show/hide which-key buffer
+
+(defun which-key--hide-popup ()
+ "This function is called to hide the which-key buffer."
+ (unless (or which-key-persistent-popup
+ (member real-this-command which-key--paging-functions))
+ (setq which-key--last-try-2-loc nil)
+ (setq which-key--pages-obj nil)
+ (setq which-key--automatic-display nil)
+ (setq which-key--prior-show-keymap-args nil)
+ (when (and which-key-idle-secondary-delay which-key--secondary-timer-active)
+ (which-key--start-timer))
+ (which-key--lighter-restore)
+ (which-key--hide-popup-ignore-command)))
+
+(defun which-key--hide-popup-ignore-command ()
+ "Version of `which-key--hide-popup' without the check of
+`real-this-command'."
+ (cl-case which-key-popup-type
+ ;; Not necessary to hide minibuffer
+ ;; (minibuffer (which-key--hide-buffer-minibuffer))
+ (side-window (which-key--hide-buffer-side-window))
+ (frame (which-key--hide-buffer-frame))
+ (custom (funcall which-key-custom-hide-popup-function))))
+
+(defun which-key--hide-popup-on-frame-size-change (&optional _)
+ "Hide which-key popup if the frame is resized (to trigger a new popup)."
+ (when (which-key--frame-size-changed-p)
+ (which-key--hide-popup)))
+
+(defun which-key--hide-buffer-side-window ()
+ "Hide which-key buffer when side-window popup is used."
+ (when (buffer-live-p which-key--buffer)
+ ;; in case which-key buffer was shown in an existing window, `quit-window'
+ ;; will re-show the previous buffer, instead of closing the window
+ (quit-windows-on which-key--buffer)
+ (when (and which-key-preserve-window-configuration
+ which-key--saved-window-configuration)
+ (set-window-configuration which-key--saved-window-configuration)
+ (setq which-key--saved-window-configuration nil))))
+
+(defun which-key--hide-buffer-frame ()
+ "Hide which-key buffer when frame popup is used."
+ (when (frame-live-p which-key--frame)
+ (delete-frame which-key--frame)))
+
+(defun which-key--popup-showing-p ()
+ (and (bufferp which-key--buffer)
+ (or (window-live-p (get-buffer-window which-key--buffer))
+ (let ((window (get-buffer-window which-key--buffer t)))
+ (and (window-live-p window)
+ (frame-visible-p (window-frame window)))))))
+
+(defun which-key--show-popup (act-popup-dim)
+ "Show the which-key buffer.
+ACT-POPUP-DIM includes the dimensions, (height . width) of the
+buffer text to be displayed in the popup. Return nil if no window
+is shown, or if there is no need to start the closing timer."
+ (when (and (> (car act-popup-dim) 0)
+ (> (cdr act-popup-dim) 0))
+ (cl-case which-key-popup-type
+ ;; Not called for minibuffer
+ ;; (minibuffer (which-key--show-buffer-minibuffer act-popup-dim))
+ (side-window (which-key--show-buffer-side-window act-popup-dim))
+ (frame (which-key--show-buffer-frame act-popup-dim))
+ (custom (funcall which-key-custom-show-popup-function act-popup-dim)))))
+
+(defun which-key--fit-buffer-to-window-horizontally
+ (&optional window &rest params)
+ "Slightly modified version of `fit-buffer-to-window'.
+Use &rest params because `fit-buffer-to-window' has a different
+call signature in different emacs versions"
+ (let ((fit-window-to-buffer-horizontally t)
+ (window-min-height 1))
+ (apply #'fit-window-to-buffer window params)))
+
+(defun which-key--show-buffer-side-window (act-popup-dim)
+ "Show which-key buffer when popup type is side-window."
+ (when (and which-key-preserve-window-configuration
+ (not which-key--saved-window-configuration))
+ (setq which-key--saved-window-configuration (current-window-configuration)))
+ (let* ((height (car act-popup-dim))
+ (width (cdr act-popup-dim))
+ (alist
+ (if which-key-allow-imprecise-window-fit
+ `((window-width . ,(which-key--text-width-to-total width))
+ (window-height . ,height)
+ (side . ,which-key-side-window-location)
+ (slot . ,which-key-side-window-slot))
+ `((window-width . which-key--fit-buffer-to-window-horizontally)
+ (window-height . (lambda (w) (fit-window-to-buffer w nil 1)))
+ (side . ,which-key-side-window-location)
+ (slot . ,which-key-side-window-slot)))))
+ ;; Previously used `display-buffer-in-major-side-window' here, but
+ ;; apparently that is meant to be an internal function. See emacs bug #24828
+ ;; and advice given there.
+ (cond
+ ((eq which-key--multiple-locations t)
+ ;; possibly want to switch sides in this case so we can't reuse the window
+ (delete-windows-on which-key--buffer)
+ (display-buffer-in-side-window which-key--buffer alist))
+ ((get-buffer-window which-key--buffer)
+ (display-buffer-reuse-window which-key--buffer alist))
+ (t
+ (display-buffer-in-side-window which-key--buffer alist)))))
+
+(defun which-key--show-buffer-frame (act-popup-dim)
+ "Show which-key buffer when popup type is frame."
+ (let* (;(orig-window (selected-window))
+ (frame-height (+ (car act-popup-dim)
+ (if (with-current-buffer which-key--buffer
+ mode-line-format)
+ 1
+ 0)))
+ ;; without adding 2, frame sometimes isn't wide enough for the buffer.
+ ;; this is probably because of the fringes. however, setting fringes
+ ;; sizes to 0 (instead of adding 2) didn't always make the frame wide
+ ;; enough. don't know why it is so.
+ (frame-width (+ (cdr act-popup-dim) 2))
+ (new-window (if (and (frame-live-p which-key--frame)
+ (eq which-key--buffer
+ (window-buffer
+ (frame-root-window which-key--frame))))
+ (which-key--show-buffer-reuse-frame
+ frame-height frame-width)
+ (which-key--show-buffer-new-frame
+ frame-height frame-width))))
+ (when new-window
+ ;; display successful
+ (setq which-key--frame (window-frame new-window))
+ new-window)))
+
+(defun which-key--show-buffer-new-frame (frame-height frame-width)
+ "Helper for `which-key--show-buffer-frame'."
+ (let* ((frame-params `((height . ,frame-height)
+ (width . ,frame-width)
+ ;; tell the window manager to respect the given sizes
+ (user-size . t)
+ ;; which-key frame doesn't need a minibuffer
+ (minibuffer . nil)
+ (name . "which-key")
+ ;; no need for scroll bars in which-key frame
+ (vertical-scroll-bars . nil)
+ ;; (left-fringe . 0)
+ ;; (right-fringe . 0)
+ ;; (right-divider-width . 0)
+ ;; make sure frame is visible
+ (visibility . t)))
+ (alist `((pop-up-frame-parameters . ,frame-params)))
+ (orig-frame (selected-frame))
+ (new-window (display-buffer-pop-up-frame which-key--buffer alist)))
+ (when new-window
+ ;; display successful
+ (redirect-frame-focus (window-frame new-window) orig-frame)
+ new-window)))
+
+(defun which-key--show-buffer-reuse-frame (frame-height frame-width)
+ "Helper for `which-key--show-buffer-frame'."
+ (let ((window
+ (display-buffer-reuse-window
+ which-key--buffer `((reusable-frames . ,which-key--frame)))))
+ (when window
+ ;; display successful
+ (set-frame-size (window-frame window) frame-width frame-height)
+ window)))
+
+;;; Max dimension of available window functions
+
+(defun which-key--popup-max-dimensions ()
+ "Dimesion functions should return the maximum possible (height
+. width) of the intended popup. SELECTED-WINDOW-WIDTH is the
+width of currently active window, not the which-key buffer
+window."
+ (cl-case which-key-popup-type
+ (minibuffer (which-key--minibuffer-max-dimensions))
+ (side-window (which-key--side-window-max-dimensions))
+ (frame (which-key--frame-max-dimensions))
+ (custom (funcall which-key-custom-popup-max-dimensions-function
+ (window-width)))))
+
+(defun which-key--minibuffer-max-dimensions ()
+ "Return max-dimensions of minibuffer (height . width).
+Measured in lines and characters respectively."
+ (cons
+ ;; height
+ (if (floatp max-mini-window-height)
+ (floor (* (frame-text-lines)
+ max-mini-window-height))
+ max-mini-window-height)
+ ;; width
+ (max 0 (- (frame-text-cols) which-key-unicode-correction))))
+
+(defun which-key--side-window-max-dimensions ()
+ "Return max-dimensions of the side-window popup (height .
+width) in lines and characters respectively."
+ (cons
+ ;; height
+ (if (member which-key-side-window-location '(left right))
+ ;; 1 is a kludge to make sure there is no overlap
+ (- (frame-height) (window-text-height (minibuffer-window)) 1)
+ ;; (window-mode-line-height which-key--window))
+ ;; FIXME: change to something like
+ ;; (min which-*-height (calculate-max-height))
+ (which-key--height-or-percentage-to-height
+ which-key-side-window-max-height))
+ ;; width
+ (max 0
+ (- (if (member which-key-side-window-location '(left right))
+ (which-key--total-width-to-text
+ (which-key--width-or-percentage-to-width
+ which-key-side-window-max-width))
+ (which-key--total-width-to-text
+ (which-key--width-or-percentage-to-width
+ 1.0)))
+ which-key-unicode-correction))))
+
+(defun which-key--frame-max-dimensions ()
+ "Return max-dimensions of the frame popup (height .
+width) in lines and characters respectively."
+ (cons which-key-frame-max-height which-key-frame-max-width))
+
+;;; Sorting functions
+
+(defun which-key--string< (a b &optional alpha)
+ (let ((da (downcase a))
+ (db (downcase b)))
+ (cond
+ ((and alpha (not which-key-sort-uppercase-first))
+ (if (string-equal da db)
+ (not (string-lessp a b))
+ (string-lessp da db)))
+ ((and alpha which-key-sort-uppercase-first)
+ (if (string-equal da db)
+ (string-lessp a b)
+ (string-lessp da db)))
+ ((not which-key-sort-uppercase-first)
+ (let ((aup (not (string-equal da a)))
+ (bup (not (string-equal db b))))
+ (if (eq aup bup)
+ (string-lessp a b)
+ bup)))
+ (t (string-lessp a b)))))
+
+(defun which-key--key-description< (a b &optional alpha)
+ "Sorting function used for `which-key-key-order' and
+`which-key-key-order-alpha'."
+ (save-match-data
+ (let* ((a (which-key--extract-key a))
+ (b (which-key--extract-key b))
+ (rngrgxp "^\\([^ ]+\\) \\.\\. [^ ]+")
+ (a (if (string-match rngrgxp a) (match-string 1 a) a))
+ (b (if (string-match rngrgxp b) (match-string 1 b) b))
+ (aem? (string-equal a ""))
+ (bem? (string-equal b ""))
+ (a1? (= 1 (length a)))
+ (b1? (= 1 (length b)))
+ (srgxp "^\\(RET\\|SPC\\|TAB\\|DEL\\|LFD\\|ESC\\|NUL\\)")
+ (asp? (string-match-p srgxp a))
+ (bsp? (string-match-p srgxp b))
+ (prrgxp "^\\(M\\|C\\|S\\|A\\|H\\|s\\)-")
+ (apr? (string-match-p prrgxp a))
+ (bpr? (string-match-p prrgxp b))
+ (afn? (string-match-p "<f[0-9]+>" a))
+ (bfn? (string-match-p "<f[0-9]+>" b)))
+ (cond ((or aem? bem?) (and aem? (not bem?)))
+ ((and asp? bsp?)
+ (if (string-equal (substring a 0 3) (substring b 0 3))
+ (which-key--key-description<
+ (substring a 3) (substring b 3) alpha)
+ (which-key--string< a b alpha)))
+ ((or asp? bsp?) asp?)
+ ((and a1? b1?) (which-key--string< a b alpha))
+ ((or a1? b1?) a1?)
+ ((and afn? bfn?)
+ (< (string-to-number
+ (replace-regexp-in-string "<f\\([0-9]+\\)>" "\\1" a))
+ (string-to-number
+ (replace-regexp-in-string "<f\\([0-9]+\\)>" "\\1" b))))
+ ((or afn? bfn?) afn?)
+ ((and apr? bpr?)
+ (if (string-equal (substring a 0 2) (substring b 0 2))
+ (which-key--key-description<
+ (substring a 2) (substring b 2) alpha)
+ (which-key--string< a b alpha)))
+ ((or apr? bpr?) apr?)
+ (t (which-key--string< a b alpha))))))
+
+(defsubst which-key-key-order-alpha (acons bcons)
+ "Order key descriptions A and B.
+Order is lexicographic within a \"class\", where the classes and
+the ordering of classes are listed below.
+
+special (SPC,TAB,...) < single char < mod (C-,M-,...) < other.
+Sorts single characters alphabetically with lowercase coming
+before upper."
+ (which-key--key-description< (car acons) (car bcons) t))
+
+(defsubst which-key-key-order (acons bcons)
+ "Order key descriptions A and B.
+Order is lexicographic within a \"class\", where the classes and
+the ordering of classes are listed below.
+
+special (SPC,TAB,...) < single char < mod (C-,M-,...) < other."
+ (which-key--key-description< (car acons) (car bcons)))
+
+(defsubst which-key-description-order (acons bcons)
+ "Order descriptions of A and B.
+Uses `string-lessp' after applying lowercase."
+ (string-lessp (downcase (cdr acons)) (downcase (cdr bcons))))
+
+(defsubst which-key--group-p (description)
+ (or (string-equal description "prefix")
+ (string-match-p "^group:" description)
+ (keymapp (intern description))))
+
+(defun which-key-prefix-then-key-order (acons bcons)
+ "Order first by whether A and/or B is a prefix with no prefix
+coming before a prefix. Within these categories order using
+`which-key-key-order'."
+ (let ((apref? (which-key--group-p (cdr acons)))
+ (bpref? (which-key--group-p (cdr bcons))))
+ (if (not (eq apref? bpref?))
+ (and (not apref?) bpref?)
+ (which-key-key-order acons bcons))))
+
+(defun which-key-prefix-then-key-order-reverse (acons bcons)
+ "Order first by whether A and/or B is a prefix with prefix
+coming before a prefix. Within these categories order using
+`which-key-key-order'."
+ (let ((apref? (which-key--group-p (cdr acons)))
+ (bpref? (which-key--group-p (cdr bcons))))
+ (if (not (eq apref? bpref?))
+ (and apref? (not bpref?))
+ (which-key-key-order acons bcons))))
+
+(defun which-key-local-then-key-order (acons bcons)
+ "Order first by whether A and/or B is a local binding with
+local bindings coming first. Within these categories order using
+`which-key-key-order'."
+ (let ((aloc? (which-key--local-binding-p acons))
+ (bloc? (which-key--local-binding-p bcons)))
+ (if (not (eq aloc? bloc?))
+ (and aloc? (not bloc?))
+ (which-key-key-order acons bcons))))
+
+;;; Functions for retrieving and formatting keys
+
+(defsubst which-key--string-width (maybe-string)
+ "If MAYBE-STRING is a string use `which-key--string-width' o/w return 0."
+ (if (stringp maybe-string) (string-width maybe-string) 0))
+
+(defsubst which-key--butlast-string (str)
+ (mapconcat #'identity (butlast (split-string str)) " "))
+
+(defun which-key--match-replacement (key-binding replacement)
+ ;; these are mode specific ones to ignore. The mode specific case is
+ ;; handled in the selection of alist
+ (when (and (consp key-binding) (not (symbolp (car replacement))))
+ (let ((key-regexp (caar replacement))
+ (binding-regexp (cdar replacement))
+ case-fold-search)
+ (and (or (null key-regexp)
+ (string-match-p key-regexp
+ (car key-binding)))
+ (or (null binding-regexp)
+ (string-match-p binding-regexp
+ (cdr key-binding)))))))
+
+(defsubst which-key--replace-in-binding (key-binding repl)
+ (cond ((or (not (consp repl)) (null (cdr repl)))
+ key-binding)
+ ((functionp (cdr repl))
+ (funcall (cdr repl) key-binding))
+ ((consp (cdr repl))
+ (cons
+ (cond ((and (caar repl) (cadr repl))
+ (replace-regexp-in-string
+ (caar repl) (cadr repl) (car key-binding) t))
+ ((cadr repl) (cadr repl))
+ (t (car key-binding)))
+ (cond ((and (cdar repl) (cddr repl))
+ (replace-regexp-in-string
+ (cdar repl) (cddr repl) (cdr key-binding) t))
+ ((cddr repl) (cddr repl))
+ (t (cdr key-binding)))))))
+
+(defun which-key--replace-in-repl-list-once (key-binding repls)
+ (cl-dolist (repl repls)
+ (when (which-key--match-replacement key-binding repl)
+ (cl-return `(replaced . ,(which-key--replace-in-binding key-binding repl))))))
+
+(defun which-key--replace-in-repl-list-many (key-binding repls)
+ (let (found)
+ (dolist (repl repls)
+ (when (which-key--match-replacement key-binding repl)
+ (setq found 't)
+ (setq key-binding (which-key--replace-in-binding key-binding repl))))
+ (when found `(replaced . ,key-binding))))
+
+(defun which-key--maybe-replace (key-binding)
+ "Use `which-key--replacement-alist' to maybe replace KEY-BINDING.
+KEY-BINDING is a cons cell of the form \(KEY . BINDING\) each of
+which are strings. KEY is of the form produced by `key-binding'."
+ (let* ((replacer (if which-key-allow-multiple-replacements
+ #'which-key--replace-in-repl-list-many
+ #'which-key--replace-in-repl-list-once)))
+ (pcase
+ (apply replacer
+ (list key-binding
+ (cdr-safe (assq major-mode which-key-replacement-alist))))
+ (`(replaced . ,repl)
+ (if which-key-allow-multiple-replacements
+ (pcase (apply replacer (list repl which-key-replacement-alist))
+ (`(replaced . ,repl) repl)
+ ('() repl))
+ repl))
+ ('()
+ (pcase (apply replacer (list key-binding which-key-replacement-alist))
+ (`(replaced . ,repl) repl)
+ ('() key-binding))))))
+
+(defsubst which-key--current-key-list (&optional key-str)
+ (append (listify-key-sequence (which-key--current-prefix))
+ (when key-str
+ (listify-key-sequence (kbd key-str)))))
+
+(defsubst which-key--current-key-string (&optional key-str)
+ (key-description (which-key--current-key-list key-str)))
+
+(defun which-key--local-binding-p (keydesc)
+ (eq (which-key--safe-lookup-key
+ (current-local-map) (kbd (which-key--current-key-string (car keydesc))))
+ (intern (cdr keydesc))))
+
+(defun which-key--map-binding-p (map keydesc)
+ "Does MAP contain KEYDESC = (key . binding)?"
+ (or
+ (when (bound-and-true-p evil-state)
+ (let ((lookup
+ (which-key--safe-lookup-key
+ map
+ (kbd (which-key--current-key-string
+ (format "<%s-state> %s" evil-state (car keydesc)))))))
+ (or (eq lookup (intern (cdr keydesc)))
+ (and (keymapp lookup) (string= (cdr keydesc) "Prefix Command")))))
+ (let ((lookup
+ (which-key--safe-lookup-key
+ map (kbd (which-key--current-key-string (car keydesc))))))
+ (or (eq lookup (intern (cdr keydesc)))
+ (and (keymapp lookup) (string= (cdr keydesc) "Prefix Command"))))))
+
+(defun which-key--maybe-get-prefix-title (keys)
+ "KEYS is a string produced by `key-description'.
+A title is possibly returned using
+`which-key--prefix-title-alist'. An empty string is returned if
+no title exists."
+ (cond
+ ((not (string-equal keys ""))
+ (let* ((title-res
+ (cdr-safe (assoc-string keys which-key--prefix-title-alist)))
+ (repl-res
+ (cdr-safe (which-key--maybe-replace (cons keys ""))))
+ (binding (key-binding (kbd keys)))
+ (alternate (when (and binding (symbolp binding))
+ (symbol-name binding))))
+ (cond (title-res title-res)
+ ((not (string-equal repl-res "")) repl-res)
+ ((and (eq which-key-show-prefix 'echo) alternate)
+ alternate)
+ ((and (member which-key-show-prefix '(bottom top mode-line))
+ (eq which-key-side-window-location 'bottom)
+ echo-keystrokes)
+ (if alternate alternate
+ (concat "Following " keys)))
+ (t ""))))
+ (t "")))
+
+(defun which-key--propertize (string &rest properties)
+ "Version of `propertize' that checks type of STRING."
+ (when (stringp string)
+ (apply #'propertize string properties)))
+
+(defun which-key--propertize-key (key)
+ "Add a face to KEY.
+If KEY contains any \"special keys\" defined in
+`which-key-special-keys' then truncate and add the corresponding
+`which-key-special-key-face'."
+ (let ((key-w-face (which-key--propertize key 'face 'which-key-key-face))
+ (regexp (concat "\\("
+ (mapconcat #'identity which-key-special-keys
+ "\\|")
+ "\\)"))
+ case-fold-search)
+ (save-match-data
+ (if (and which-key-special-keys
+ (string-match regexp key))
+ (let ((beg (match-beginning 0)) (end (match-end 0)))
+ (concat (substring key-w-face 0 beg)
+ (which-key--propertize (substring key-w-face beg (1+ beg))
+ 'face 'which-key-special-key-face)
+ (substring key-w-face end
+ (which-key--string-width key-w-face))))
+ key-w-face))))
+
+(defsubst which-key--truncate-description (desc)
+ "Truncate DESC description to `which-key-max-description-length'."
+ (let* ((last-face (get-text-property (1- (length desc)) 'face desc))
+ (dots (which-key--propertize which-key-ellipsis 'face last-face)))
+ (if (and which-key-max-description-length
+ (> (length desc) which-key-max-description-length))
+ (concat (substring desc 0 which-key-max-description-length) dots)
+ desc)))
+
+(defun which-key--highlight-face (description)
+ "Return the highlight face for DESCRIPTION if it has one."
+ (let (face)
+ (dolist (el which-key-highlighted-command-list)
+ (unless face
+ (cond ((consp el)
+ (when (string-match-p (car el) description)
+ (setq face (cdr el))))
+ ((stringp el)
+ (when (string-match-p el description)
+ (setq face 'which-key-highlighted-command-face)))
+ (t
+ (message "which-key: warning: element %s of \
+which-key-highlighted-command-list is not a string or a cons
+cell" el)))))
+ face))
+
+(defun which-key--propertize-description
+ (description group local hl-face &optional original-description)
+ "Add face to DESCRIPTION where the face chosen depends on
+whether the description represents a group or a command. Also
+make some minor adjustments to the description string, like
+removing a \"group:\" prefix.
+
+ORIGINAL-DESCRIPTION is the description given by
+`describe-buffer-bindings'."
+ (when description
+ (let* ((desc description)
+ (desc (if (string-match-p "^group:" desc)
+ (substring desc 6) desc))
+ (desc (if group (concat which-key-prefix-prefix desc) desc)))
+ (make-text-button
+ desc nil
+ 'face (cond (hl-face hl-face)
+ (group 'which-key-group-description-face)
+ (local 'which-key-local-map-description-face)
+ (t 'which-key-command-description-face))
+ 'help-echo (cond
+ ((and original-description
+ (fboundp (intern original-description))
+ (documentation (intern original-description))
+ ;; tooltip-mode doesn't exist in emacs-nox
+ (boundp 'tooltip-mode) tooltip-mode)
+ (documentation (intern original-description)))
+ ((and original-description
+ (fboundp (intern original-description))
+ (documentation (intern original-description))
+ (let* ((doc (documentation
+ (intern original-description)))
+ (str (replace-regexp-in-string "\n" " " doc))
+ (max (floor (* (frame-width) 0.8))))
+ (if (> (length str) max)
+ (concat (substring str 0 max) "...")
+ str)))))))))
+
+(defun which-key--extract-key (key-str)
+ "Pull the last key (or key range) out of KEY-STR."
+ (save-match-data
+ (let ((key-range-regexp "\\`.*\\([^ \t]+ \\.\\. [^ \t]+\\)\\'"))
+ (if (string-match key-range-regexp key-str)
+ (match-string 1 key-str)
+ (car (last (split-string key-str " ")))))))
+
+(defun which-key--maybe-add-docstring (current original)
+ "Maybe concat a docstring to CURRENT and return result.
+Specifically, do this if ORIGINAL is a command with a docstring
+and `which-key-show-docstrings' is non-nil. If
+`which-key-show-docstrings' is the symbol docstring-only, just
+return the docstring."
+ (let* ((orig-sym (intern original))
+ (doc (when (commandp orig-sym)
+ (documentation orig-sym)))
+ (doc (when doc
+ (replace-regexp-in-string
+ (concat "^\\(?::"
+ (regexp-opt '("around" "override"
+ "after" "after-until" "after-while"
+ "before" "before-until" "before-while"
+ "filter-args" "filter-return"))
+ " advice: [^\n]+\n"
+ "\\)+\n")
+ "" doc)))
+ (docstring (when doc
+ (which-key--propertize (car (split-string doc "\n"))
+ 'face 'which-key-docstring-face))))
+ (cond ((not (and which-key-show-docstrings docstring))
+ current)
+ ((eq which-key-show-docstrings 'docstring-only)
+ docstring)
+ (t
+ (format "%s %s" current docstring)))))
+
+(defun which-key--format-and-replace (unformatted &optional preserve-full-key)
+ "Take a list of (key . desc) cons cells in UNFORMATTED, add
+faces and perform replacements according to the three replacement
+alists. Returns a list (key separator description)."
+ (let ((sep-w-face
+ (which-key--propertize which-key-separator
+ 'face 'which-key-separator-face))
+ (local-map (current-local-map))
+ new-list)
+ (dolist (key-binding unformatted)
+ (let* ((keys (car key-binding))
+ (orig-desc (cdr key-binding))
+ (group (which-key--group-p orig-desc))
+ (local (eq (which-key--safe-lookup-key local-map (kbd keys))
+ (intern orig-desc)))
+ (hl-face (which-key--highlight-face orig-desc))
+ (key-binding (which-key--maybe-replace key-binding))
+ (final-desc (which-key--propertize-description
+ (cdr key-binding) group local hl-face orig-desc)))
+ (when final-desc
+ (setq final-desc
+ (which-key--truncate-description
+ (which-key--maybe-add-docstring final-desc orig-desc))))
+ (when (consp key-binding)
+ (push
+ (list (which-key--propertize-key
+ (if preserve-full-key
+ (car key-binding)
+ (which-key--extract-key (car key-binding))))
+ sep-w-face
+ final-desc)
+ new-list))))
+ (nreverse new-list)))
+
+(defun which-key--compute-binding (binding)
+ "Replace BINDING with remapped binding if it exists.
+
+Requires `which-key-compute-remaps' to be non-nil"
+ (let (remap)
+ (if (and which-key-compute-remaps
+ (setq remap (command-remapping binding)))
+ (copy-sequence (symbol-name remap))
+ (copy-sequence (symbol-name binding)))))
+
+(defun which-key--get-menu-item-binding (def)
+ "Retrieve binding for menu-item"
+ ;; see `keymap--menu-item-binding'
+ (let* ((binding (nth 2 def))
+ (plist (nthcdr 3 def))
+ (filter (plist-get plist :filter)))
+ (if filter (funcall filter binding) binding)))
+
+(defun which-key--get-keymap-bindings-1
+ (keymap start &optional prefix filter all ignore-commands)
+ "See `which-key--get-keymap-bindings'."
+ (let ((bindings start)
+ (prefix-map (if prefix (lookup-key keymap prefix) keymap)))
+ (when (keymapp prefix-map)
+ (map-keymap
+ (lambda (ev def)
+ (let* ((key (vconcat prefix (list ev)))
+ (key-desc (key-description key)))
+ (cond
+ ((assoc key-desc bindings))
+ ((and (listp ignore-commands) (symbolp def) (memq def ignore-commands)))
+ ((or (string-match-p
+ which-key--ignore-non-evil-keys-regexp key-desc)
+ (eq ev 'menu-bar)))
+ ((and (keymapp def)
+ (string-match-p which-key--evil-keys-regexp key-desc)))
+ ((and (keymapp def)
+ (or all
+ ;; event 27 is escape, so this will pick up meta
+ ;; bindings and hopefully not too much more
+ (and (numberp ev) (= ev 27))))
+ (setq bindings
+ (which-key--get-keymap-bindings-1
+ keymap bindings key nil all ignore-commands)))
+ (def
+ (let* ((def (if (eq 'menu-item (car-safe def))
+ (which-key--get-menu-item-binding def)
+ def))
+ (binding
+ (cons key-desc
+ (cond
+ ((symbolp def) (which-key--compute-binding def))
+ ((keymapp def) "prefix")
+ ((eq 'lambda (car-safe def)) "lambda")
+ ((eq 'closure (car-safe def)) "closure")
+ ((stringp def) def)
+ ((vectorp def) (key-description def))
+ ((and (consp def)
+ ;; looking for (STRING . DEFN)
+ (stringp (car def)))
+ (concat (when (keymapp (cdr-safe def))
+ "group:")
+ (car def)))
+ (t "unknown")))))
+ (when (or (null filter)
+ (and (functionp filter)
+ (funcall filter binding)))
+ (push binding bindings)))))))
+ prefix-map))
+ bindings))
+
+(defun which-key--get-keymap-bindings
+ (keymap &optional start prefix filter all evil)
+ "Retrieve top-level bindings from KEYMAP.
+PREFIX limits bindings to those starting with this key
+sequence. START is a list of existing bindings to add to. If ALL
+is non-nil, recursively retrieve all bindings below PREFIX. If
+EVIL is non-nil, extract active evil bidings."
+ (let ((bindings start)
+ (ignore '(self-insert-command ignore ignore-event company-ignore))
+ (evil-map
+ (when (and evil (bound-and-true-p evil-local-mode))
+ (lookup-key keymap (kbd (format "<%s-state>" evil-state))))))
+ (when (keymapp evil-map)
+ (setq bindings (which-key--get-keymap-bindings-1
+ evil-map bindings prefix filter all ignore)))
+ (which-key--get-keymap-bindings-1
+ keymap bindings prefix filter all ignore)))
+
+(defun which-key--get-current-bindings (&optional prefix filter)
+ "Generate a list of current active bindings."
+ (let (bindings)
+ (dolist (map (current-active-maps t) bindings)
+ (when (cdr map)
+ (setq bindings
+ (which-key--get-keymap-bindings
+ map bindings prefix filter))))))
+
+(defun which-key--get-bindings (&optional prefix keymap filter recursive)
+ "Collect key bindings.
+If KEYMAP is nil, collect from current buffer using the current
+key sequence as a prefix. Otherwise, collect from KEYMAP. FILTER
+is a function to use to filter the bindings. If RECURSIVE is
+non-nil, then bindings are collected recursively for all prefixes."
+ (let* ((unformatted
+ (cond ((keymapp keymap)
+ (which-key--get-keymap-bindings
+ keymap nil prefix filter recursive))
+ (keymap
+ (error "%s is not a keymap" keymap))
+ (t
+ (which-key--get-current-bindings prefix filter)))))
+ (when which-key-sort-order
+ (setq unformatted
+ (sort unformatted which-key-sort-order)))
+ (which-key--format-and-replace unformatted recursive)))
+
+;;; Functions for laying out which-key buffer pages
+
+(defun which-key--normalize-columns (columns)
+ "Pad COLUMNS to the same length using empty strings."
+ (let ((max-len (cl-reduce (lambda (a x) (max a (length x))) columns
+ :initial-value 0)))
+ (mapcar
+ (lambda (c)
+ (if (< (length c) max-len)
+ (append c (make-list (- max-len (length c)) ""))
+ c))
+ columns)))
+
+(defsubst which-key--join-columns (columns)
+ "Transpose columns into rows, concat rows into lines and rows into page."
+ (let* ((padded (which-key--normalize-columns (nreverse columns)))
+ (rows (apply #'cl-mapcar #'list padded)))
+ (mapconcat (lambda (row) (mapconcat #'identity row " ")) rows "\n")))
+
+(defsubst which-key--max-len (keys index &optional initial-value)
+ "Internal function for finding the max length of the INDEX
+element in each list element of KEYS."
+ (cl-reduce
+ (lambda (x y) (max x (which-key--string-width (nth index y))))
+ keys :initial-value (if initial-value initial-value 0)))
+
+(defun which-key--pad-column (col-keys)
+ "Take a column of (key separator description) COL-KEYS,
+calculate the max width in the column and pad all cells out to
+that width."
+ (let* ((col-key-width (+ which-key-add-column-padding
+ (which-key--max-len col-keys 0)))
+ (col-sep-width (which-key--max-len col-keys 1))
+ (col-desc-width (which-key--max-len
+ col-keys 2 which-key-min-column-description-width))
+ (col-width (+ 1 col-key-width col-sep-width col-desc-width)))
+ (cons col-width
+ (mapcar (lambda (k)
+ (format (concat "%" (int-to-string col-key-width)
+ "s%s%-" (int-to-string col-desc-width) "s")
+ (nth 0 k) (nth 1 k) (nth 2 k)))
+ col-keys))))
+
+(defun which-key--partition-list (n list)
+ "Partition LIST into N-sized sublists."
+ (let (res)
+ (while list
+ (setq res (cons (cl-subseq list 0 (min n (length list))) res)
+ list (nthcdr n list)))
+ (nreverse res)))
+
+(defun which-key--list-to-pages (keys avl-lines avl-width)
+ "Convert list of KEYS to columns based on dimensions AVL-LINES and AVL-WIDTH.
+Returns a `which-key--pages' object that holds the page strings,
+as well as metadata."
+ (let ((cols-w-widths (mapcar #'which-key--pad-column
+ (which-key--partition-list avl-lines keys)))
+ (page-width 0) (n-pages 0) (n-keys 0) (n-columns 0)
+ page-cols pages page-widths keys/page col)
+ (if (> (apply #'max (mapcar #'car cols-w-widths)) avl-width)
+ ;; give up if no columns fit
+ nil
+ (while cols-w-widths
+ ;; start new page
+ (cl-incf n-pages)
+ (setq col (pop cols-w-widths))
+ (setq page-cols (list (cdr col)))
+ (setq page-width (car col))
+ (setq n-keys (length (cdr col)))
+ (setq n-columns 1)
+ ;; add additional columns as long as they fit
+ (while (and cols-w-widths
+ (or (null which-key-max-display-columns)
+ (< n-columns which-key-max-display-columns))
+ (<= (+ (caar cols-w-widths) page-width) avl-width))
+ (setq col (pop cols-w-widths))
+ (push (cdr col) page-cols)
+ (cl-incf page-width (car col))
+ (cl-incf n-keys (length (cdr col)))
+ (cl-incf n-columns))
+ (push (which-key--join-columns page-cols) pages)
+ (push n-keys keys/page)
+ (push page-width page-widths))
+ (make-which-key--pages
+ :pages (nreverse pages)
+ :height (if (> n-pages 1) avl-lines (min avl-lines n-keys))
+ :widths (nreverse page-widths)
+ :keys/page (reverse keys/page)
+ :page-nums (number-sequence 1 n-pages)
+ :num-pages n-pages
+ :total-keys (apply #'+ keys/page)))))
+
+(defun which-key--create-pages-1
+ (keys available-lines available-width &optional min-lines vertical)
+ "Create page strings using `which-key--list-to-pages'.
+Will try to find the best number of rows and columns using the
+given dimensions and the length and widths of ITEMS. Use VERTICAL
+if the ITEMS are laid out vertically and the number of columns
+should be minimized."
+ (let ((result (which-key--list-to-pages
+ keys available-lines available-width))
+ (min-lines (or min-lines 0))
+ found prev-result)
+ (if (or (null result)
+ vertical
+ (> (which-key--pages-num-pages result) 1)
+ (= 1 available-lines))
+ result
+ ;; simple search for a fitting page
+ (while (and (> available-lines min-lines)
+ (not found))
+ (setq available-lines (- available-lines 1)
+ prev-result result
+ result (which-key--list-to-pages
+ keys available-lines available-width)
+ found (> (which-key--pages-num-pages result) 1)))
+ (if found prev-result result))))
+
+(defun which-key--create-pages (keys &optional prefix-keys prefix-title)
+ "Create page strings using `which-key--list-to-pages'.
+Will try to find the best number of rows and columns using the
+given dimensions and the length and wdiths of KEYS. SEL-WIN-WIDTH
+is the width of the live window."
+ (let* ((max-dims (which-key--popup-max-dimensions))
+ (max-lines (car max-dims))
+ (max-width (cdr max-dims))
+ (prefix-desc (key-description prefix-keys))
+ (full-prefix (which-key--full-prefix prefix-desc))
+ (prefix (when (eq which-key-show-prefix 'left)
+ (+ 2 (which-key--string-width full-prefix))))
+ (prefix-top-bottom (member which-key-show-prefix '(bottom top)))
+ (avl-lines (if prefix-top-bottom (- max-lines 1) max-lines))
+ (min-lines (min avl-lines which-key-min-display-lines))
+ (avl-width (if prefix (- max-width prefix) max-width))
+ (vertical (and (eq which-key-popup-type 'side-window)
+ (member which-key-side-window-location '(left right))))
+ result)
+ (setq result
+ (which-key--create-pages-1
+ keys avl-lines avl-width min-lines vertical))
+ (when (and result
+ (> (which-key--pages-num-pages result) 0))
+ (setf (which-key--pages-prefix result) prefix-keys)
+ (setf (which-key--pages-prefix-title result)
+ (or prefix-title
+ (which-key--maybe-get-prefix-title
+ (key-description prefix-keys))))
+ (when (and (= (which-key--pages-num-pages result) 1)
+ (> which-key-min-display-lines
+ (which-key--pages-height result)))
+ ;; result is shorter than requested, so we artificially increase the
+ ;; height. See #325. Note this only has an effect if
+ ;; `which-key-allow-imprecise-window-fit' is non-nil.
+ (setf (which-key--pages-height result) which-key-min-display-lines))
+ (which-key--debug-message "Frame height: %s
+Minibuffer height: %s
+Max dimensions: (%s,%s)
+Available for bindings: (%s,%s)
+Actual lines: %s" (frame-height) (window-text-height (minibuffer-window))
+max-lines max-width avl-lines avl-width (which-key--pages-height result))
+ result)))
+
+(defun which-key--lighter-status ()
+ "Possibly show number of keys and total in the mode line."
+ (when which-key-show-remaining-keys
+ (let ((n-shown (car (which-key--pages-keys/page which-key--pages-obj)))
+ (n-tot (which-key--pages-total-keys which-key--pages-obj)))
+ (setcar (cdr (assq 'which-key-mode minor-mode-alist))
+ (format " WK: %s/%s keys" n-shown n-tot)))))
+
+(defun which-key--lighter-restore ()
+ "Restore the lighter for which-key."
+ (when which-key-show-remaining-keys
+ (setcar (cdr (assq 'which-key-mode minor-mode-alist))
+ which-key-lighter)))
+
+(defun which-key--echo (text)
+ "Echo TEXT to minibuffer without logging."
+ (let (message-log-max)
+ (message "%s" text)))
+
+(defun which-key--next-page-hint (prefix-keys)
+ "Return string for next page hint."
+ (let* ((paging-key (concat prefix-keys " " which-key-paging-key))
+ (paging-key-bound (eq 'which-key-C-h-dispatch
+ (key-binding (kbd paging-key))))
+ (key (key-description (vector help-char)))
+ (key (if paging-key-bound
+ (concat key " or " which-key-paging-key)
+ key)))
+ (when (and which-key-use-C-h-commands
+ (not (equal (vector help-char)
+ (vconcat (kbd prefix-keys)))))
+ (which-key--propertize (format "[%s paging/help]" key)
+ 'face 'which-key-note-face))))
+
+(eval-and-compile
+ (if (fboundp 'universal-argument--description)
+ (defalias 'which-key--universal-argument--description
+ #'universal-argument--description)
+ (defun which-key--universal-argument--description ()
+ ;; Backport of the definition of universal-argument--description in
+ ;; emacs25 on 2015-12-04
+ (when prefix-arg
+ (concat "C-u"
+ (pcase prefix-arg
+ (`(-) " -")
+ (`(,(and (pred integerp) n))
+ (let ((str ""))
+ (while (and (> n 4) (= (mod n 4) 0))
+ (setq str (concat str " C-u"))
+ (setq n (/ n 4)))
+ (if (= n 4) str (format " %s" prefix-arg))))
+ (_ (format " %s" prefix-arg))))))))
+
+(defun which-key--full-prefix (prefix-keys &optional -prefix-arg dont-prop-keys)
+ "Return a description of the full key sequence up to now,
+including prefix arguments."
+ (let* ((left (eq which-key-show-prefix 'left))
+ (prefix-arg (if -prefix-arg -prefix-arg prefix-arg))
+ (str (concat
+ (which-key--universal-argument--description)
+ (when prefix-arg " ")
+ prefix-keys))
+ (dash (if (and (not (string= prefix-keys ""))
+ (null left)) "-" "")))
+ (if (or (eq which-key-show-prefix 'echo) dont-prop-keys)
+ (concat str dash)
+ (concat (which-key--propertize-key str)
+ (which-key--propertize dash 'face 'which-key-key-face)))))
+
+(defun which-key--get-popup-map ()
+ "Generate transient-map for use in the top level binding display."
+ (unless which-key--automatic-display
+ (let ((map (make-sparse-keymap)))
+ (define-key map (kbd which-key-paging-key) #'which-key-C-h-dispatch)
+ (when which-key-use-C-h-commands
+ ;; Show next page even when C-h is pressed
+ (define-key map (vector help-char) #'which-key-C-h-dispatch))
+ map)))
+
+(defun which-key--process-page (pages-obj)
+ "Add information to the basic list of key bindings, including
+if applicable the current prefix, the name of the current prefix,
+and a page count."
+ (let* ((page (car (which-key--pages-pages pages-obj)))
+ (height (which-key--pages-height pages-obj))
+ (n-pages (which-key--pages-num-pages pages-obj))
+ (page-n (car (which-key--pages-page-nums pages-obj)))
+ (prefix-desc (key-description (which-key--pages-prefix pages-obj)))
+ (prefix-title (which-key--pages-prefix-title pages-obj))
+ (full-prefix (which-key--full-prefix prefix-desc))
+ (nxt-pg-hint (which-key--next-page-hint prefix-desc))
+ ;; not used in left case
+ (status-line
+ (concat (which-key--propertize prefix-title 'face 'which-key-note-face)
+ (when (< 1 n-pages)
+ (which-key--propertize (format " (%s of %s)" page-n n-pages)
+ 'face 'which-key-note-face)))))
+ (pcase which-key-show-prefix
+ (`left
+ (let* ((page-cnt (which-key--propertize (format "%s/%s" page-n n-pages)
+ 'face 'which-key-separator-face))
+ (first-col-width (+ 2 (max (which-key--string-width full-prefix)
+ (which-key--string-width page-cnt))))
+ (prefix (format (concat "%-" (int-to-string first-col-width) "s")
+ full-prefix))
+ (page-cnt (if (> n-pages 1)
+ (format
+ (concat "%-" (int-to-string first-col-width) "s")
+ page-cnt)
+ (make-string first-col-width 32)))
+ lines first-line new-end)
+ (if (= 1 height)
+ (cons (concat prefix page) nil)
+ (setq lines (split-string page "\n")
+ first-line (concat prefix (car lines) "\n" page-cnt)
+ new-end (concat "\n" (make-string first-col-width 32)))
+ (cons
+ (concat first-line (mapconcat #'identity (cdr lines) new-end))
+ nil))))
+ (`top
+ (cons
+ (concat (when (or (= 0 echo-keystrokes)
+ (not (eq which-key-side-window-location 'bottom)))
+ (concat full-prefix " "))
+ status-line " " nxt-pg-hint "\n" page)
+ nil))
+ (`bottom
+ (cons
+ (concat page "\n"
+ (when (or (= 0 echo-keystrokes)
+ (not (eq which-key-side-window-location 'bottom)))
+ (concat full-prefix " "))
+ status-line " " nxt-pg-hint)
+ nil))
+ (`echo
+ (cons page
+ (lambda ()
+ (which-key--echo
+ (concat full-prefix (when prefix-desc " ")
+ status-line (when status-line " ")
+ nxt-pg-hint)))))
+ (`mode-line
+ (cons page
+ (lambda ()
+ (with-current-buffer which-key--buffer
+ (setq-local mode-line-format
+ (concat " " full-prefix
+ " " status-line
+ " " nxt-pg-hint))))))
+ (_ (cons page nil)))))
+
+(defun which-key--show-page (&optional n)
+ "Show current page.
+N changes the current page to the Nth page relative to the
+current one."
+ (which-key--init-buffer) ;; in case it was killed
+ (let ((prefix-keys (which-key--current-key-string))
+ golden-ratio-mode)
+ (if (null which-key--pages-obj)
+ (message "%s- which-key can't show keys: There is not \
+enough space based on your settings and frame size." prefix-keys)
+ (when n
+ (setq which-key--pages-obj
+ (which-key--pages-set-current-page which-key--pages-obj n)))
+ (let ((page-echo (which-key--process-page which-key--pages-obj))
+ (height (which-key--pages-height which-key--pages-obj))
+ (width (car (which-key--pages-widths which-key--pages-obj))))
+ (which-key--lighter-status)
+ (if (eq which-key-popup-type 'minibuffer)
+ (which-key--echo (car page-echo))
+ (with-current-buffer which-key--buffer
+ (erase-buffer)
+ (insert (car page-echo))
+ (goto-char (point-min)))
+ (when (cdr page-echo) (funcall (cdr page-echo)))
+ (which-key--show-popup (cons height width)))))
+ ;; used for paging at top-level
+ (if (fboundp 'set-transient-map)
+ (set-transient-map (which-key--get-popup-map))
+ (with-no-warnings
+ (set-temporary-overlay-map (which-key--get-popup-map))))))
+
+;;; Paging functions
+
+;;;###autoload
+(defun which-key-reload-key-sequence (&optional key-seq)
+ "Simulate entering the key sequence KEY-SEQ.
+KEY-SEQ should be a list of events as produced by
+`listify-key-sequence'. If nil, KEY-SEQ defaults to
+`which-key--current-key-list'. Any prefix arguments that were
+used are reapplied to the new key sequence."
+ (let* ((key-seq (or key-seq (which-key--current-key-list)))
+ (next-event (mapcar (lambda (ev) (cons t ev)) key-seq)))
+ (setq prefix-arg current-prefix-arg
+ unread-command-events next-event)))
+
+(defun which-key-turn-page (delta)
+ "Show the next page of keys."
+ (which-key-reload-key-sequence)
+ (if which-key--last-try-2-loc
+ (let ((which-key-side-window-location which-key--last-try-2-loc)
+ (which-key--multiple-locations t))
+ (which-key--show-page delta))
+ (which-key--show-page delta))
+ (which-key--start-paging-timer))
+
+;;;###autoload
+(defun which-key-show-standard-help (&optional _)
+ "Call the command in `which-key--prefix-help-cmd-backup'.
+Usually this is `describe-prefix-bindings'."
+ (interactive)
+ (let ((which-key-inhibit t)
+ (popup-showing (which-key--popup-showing-p)))
+ (which-key--hide-popup-ignore-command)
+ (cond ((and (eq which-key--prefix-help-cmd-backup
+ 'describe-prefix-bindings)
+ ;; If the popup is not showing, we call
+ ;; `describe-prefix-bindings' directly.
+ popup-showing)
+ ;; This is essentially what `describe-prefix-bindings' does. We can't
+ ;; use this function directly, because the prefix will not be correct
+ ;; when we enter using `which-key-C-h-dispatch'.
+ (describe-bindings (kbd (which-key--current-key-string))))
+ ((functionp which-key--prefix-help-cmd-backup)
+ (funcall which-key--prefix-help-cmd-backup)))))
+
+;;;###autoload
+(defun which-key-show-next-page-no-cycle ()
+ "Show next page of keys unless on the last page, in which case
+call `which-key-show-standard-help'."
+ (interactive)
+ (let ((which-key-inhibit t))
+ (if (which-key--on-last-page)
+ (which-key-show-standard-help)
+ (which-key-turn-page 1))))
+
+;;;###autoload
+(defun which-key-show-previous-page-no-cycle ()
+ "Show previous page of keys unless on the first page, in which
+case do nothing."
+ (interactive)
+ (let ((which-key-inhibit t))
+ (unless (which-key--on-first-page)
+ (which-key-turn-page -1))))
+
+;;;###autoload
+(defun which-key-show-next-page-cycle (&optional _)
+ "Show the next page of keys, cycling from end to beginning
+after last page."
+ (interactive)
+ (let ((which-key-inhibit t))
+ (which-key-turn-page 1)))
+
+;;;###autoload
+(defun which-key-show-previous-page-cycle (&optional _)
+ "Show the previous page of keys, cycling from beginning to end
+after first page."
+ (interactive)
+ (let ((which-key-inhibit t))
+ (which-key-turn-page -1)))
+
+;;;###autoload
+(defun which-key-show-top-level (&optional _)
+ "Show top-level bindings."
+ (interactive)
+ (which-key--create-buffer-and-show nil nil nil "Top-level bindings"))
+
+;;;###autoload
+(defun which-key-show-major-mode (&optional all)
+ "Show top-level bindings in the map of the current major mode.
+
+This function will also detect evil bindings made using
+`evil-define-key' in this map. These bindings will depend on the
+current evil state. "
+ (interactive "P")
+ (let ((map-sym (intern (format "%s-map" major-mode))))
+ (if (and (boundp map-sym) (keymapp (symbol-value map-sym)))
+ (which-key--show-keymap
+ "Major-mode bindings"
+ (symbol-value map-sym)
+ (apply-partially #'which-key--map-binding-p (symbol-value map-sym))
+ all)
+ (message "which-key: No map named %s" map-sym))))
+
+;;;###autoload
+(defun which-key-show-full-major-mode ()
+ "Show all bindings in the map of the current major mode.
+
+This function will also detect evil bindings made using
+`evil-define-key' in this map. These bindings will depend on the
+current evil state. "
+ (interactive)
+ (which-key-show-major-mode t))
+
+;;;###autoload
+(defun which-key-dump-bindings (prefix buffer-name)
+ "Dump bindings from PREFIX into buffer named BUFFER-NAME.
+
+PREFIX should be a string suitable for `kbd'."
+ (interactive "sPrefix: \nB")
+ (let* ((buffer (get-buffer-create buffer-name))
+ (keys (which-key--get-bindings (kbd prefix))))
+ (with-current-buffer buffer
+ (point-max)
+ (save-excursion
+ (dolist (key keys)
+ (insert (apply #'format "%s%s%s\n" key)))))
+ (switch-to-buffer-other-window buffer)))
+
+;;;###autoload
+(defun which-key-undo-key (&optional _)
+ "Undo last keypress and force which-key update."
+ (interactive)
+ (let* ((key-lst (butlast (which-key--current-key-list)))
+ (which-key-inhibit t))
+ (cond (which-key--prior-show-keymap-args
+ (if (keymapp (cdr (car-safe which-key--prior-show-keymap-args)))
+ (let ((args (pop which-key--prior-show-keymap-args)))
+ (which-key--show-keymap (car args) (cdr args)))
+ (which-key--hide-popup)))
+ (key-lst
+ (which-key-reload-key-sequence key-lst)
+ (which-key--create-buffer-and-show (apply #'vector key-lst)))
+ (t (setq which-key--automatic-display nil)
+ (which-key-show-top-level)))))
+(defalias 'which-key-undo #'which-key-undo-key)
+
+(defun which-key-abort (&optional _)
+ "Abort key sequence."
+ (interactive)
+ (let ((which-key-inhibit t))
+ (which-key--hide-popup-ignore-command)
+ (keyboard-quit)))
+
+(defun which-key-digit-argument (key)
+ "Version of `digit-argument' for use in `which-key-C-h-map'."
+ (interactive)
+ (let ((last-command-event (string-to-char key)))
+ (digit-argument key))
+ (let ((current-prefix-arg prefix-arg))
+ (which-key-reload-key-sequence)))
+
+(defun which-key-toggle-docstrings (&optional _)
+ "Toggle the display of docstrings."
+ (interactive)
+ (unless (eq which-key-show-docstrings 'docstring-only)
+ (setq which-key-show-docstrings (null which-key-show-docstrings)))
+ (which-key-reload-key-sequence)
+ (which-key--create-buffer-and-show (which-key--current-prefix)))
+
+;;;###autoload
+(defun which-key-C-h-dispatch ()
+ "Dispatch C-h commands by looking up key in
+`which-key-C-h-map'. This command is always accessible (from any
+prefix) if `which-key-use-C-h-commands' is non nil."
+ (interactive)
+ (cond ((and (not (which-key--popup-showing-p))
+ which-key-show-early-on-C-h)
+ (let ((current-prefix
+ (butlast
+ (listify-key-sequence (which-key--this-command-keys)))))
+ (which-key-reload-key-sequence current-prefix)
+ (if which-key-idle-secondary-delay
+ (which-key--start-timer which-key-idle-secondary-delay t)
+ (which-key--start-timer 0.05 t))))
+ ((not (which-key--popup-showing-p))
+ (which-key-show-standard-help))
+ (t
+ (if (not (which-key--popup-showing-p))
+ (which-key-show-standard-help)
+ (let* ((prefix-keys (which-key--current-key-string))
+ (full-prefix (which-key--full-prefix prefix-keys current-prefix-arg t))
+ (prompt (concat (when (string-equal prefix-keys "")
+ (which-key--propertize
+ (concat " "
+ (which-key--pages-prefix-title
+ which-key--pages-obj))
+ 'face 'which-key-note-face))
+ full-prefix
+ (which-key--propertize
+ (substitute-command-keys
+ (concat
+ " \\<which-key-C-h-map>"
+ " \\[which-key-show-next-page-cycle]"
+ which-key-separator "next-page,"
+ " \\[which-key-show-previous-page-cycle]"
+ which-key-separator "previous-page,"
+ " \\[which-key-undo-key]"
+ which-key-separator "undo-key,"
+ " \\[which-key-toggle-docstrings]"
+ which-key-separator "toggle-docstrings,"
+ " \\[which-key-show-standard-help]"
+ which-key-separator "help,"
+ " \\[which-key-abort]"
+ which-key-separator "abort"
+ " 1..9"
+ which-key-separator "digit-arg"))
+ 'face 'which-key-note-face)))
+ (key (let ((key (read-key prompt)))
+ (if (numberp key)
+ (string key)
+ (vector key))))
+ (cmd (lookup-key which-key-C-h-map key))
+ (which-key-inhibit t))
+ (if cmd (funcall cmd key) (which-key-turn-page 0)))))))
+
+;;; Update
+
+(defun which-key--any-match-p (regexps string)
+ "Non-nil if any of REGEXPS match STRING."
+ (catch 'match
+ (dolist (regexp regexps)
+ (when (string-match-p regexp string)
+ (throw 'match t)))))
+
+(defun which-key--try-2-side-windows
+ (bindings prefix-keys prefix-title loc1 loc2 &rest _ignore)
+ "Try to show BINDINGS (PAGE-N) in LOC1 first.
+
+Only if no bindings fit fallback to LOC2."
+ (let (pages1)
+ (let ((which-key-side-window-location loc1)
+ (which-key--multiple-locations t))
+ (setq pages1 (which-key--create-pages
+ bindings prefix-keys prefix-title)))
+ (if pages1
+ (progn
+ (setq which-key--pages-obj pages1)
+ (let ((which-key-side-window-location loc1)
+ (which-key--multiple-locations t))
+ (which-key--show-page))
+ loc1)
+ (let ((which-key-side-window-location loc2)
+ (which-key--multiple-locations t))
+ (setq which-key--pages-obj
+ (which-key--create-pages bindings prefix-keys prefix-title))
+ (which-key--show-page)
+ loc2))))
+
+(defun which-key--read-keymap ()
+ "Read keymap symbol from minibuffer."
+ (intern
+ (completing-read "Keymap: " obarray
+ (lambda (m)
+ (and (boundp m)
+ (keymapp (symbol-value m))
+ (not (equal (symbol-value m)
+ (make-sparse-keymap)))))
+ t
+ (let ((sym (symbol-at-point)))
+ (and (boundp sym)
+ (keymapp (symbol-value sym))
+ (symbol-name sym)))
+ 'which-key-keymap-history)))
+
+;;;###autoload
+(defun which-key-show-keymap (keymap &optional no-paging)
+ "Show the top-level bindings in KEYMAP using which-key.
+KEYMAP is selected interactively from all available keymaps.
+
+If NO-PAGING is non-nil, which-key will not intercept subsequent
+keypresses for the paging functionality."
+ (interactive (list (which-key--read-keymap)))
+ (which-key--show-keymap (symbol-name keymap)
+ (symbol-value keymap)
+ nil nil no-paging))
+
+;;;###autoload
+(defun which-key-show-full-keymap (keymap)
+ "Show all bindings in KEYMAP using which-key.
+KEYMAP is selected interactively from all available keymaps."
+ (interactive (list (which-key--read-keymap)))
+ (which-key--show-keymap (symbol-name keymap)
+ (symbol-value keymap)
+ nil t))
+
+;;;###autoload
+(defun which-key-show-minor-mode-keymap (&optional all)
+ "Show the top-level bindings in KEYMAP using which-key.
+KEYMAP is selected interactively by mode in
+`minor-mode-map-alist'."
+ (interactive)
+ (let ((mode-sym
+ (intern
+ (completing-read
+ "Minor Mode: "
+ (mapcar #'car
+ (cl-remove-if-not
+ (lambda (entry)
+ (and (symbol-value (car entry))
+ (not (equal (cdr entry) (make-sparse-keymap)))))
+ minor-mode-map-alist))
+ nil t nil 'which-key-keymap-history))))
+ (which-key--show-keymap (symbol-name mode-sym)
+ (cdr (assq mode-sym minor-mode-map-alist))
+ all)))
+;;;###autoload
+(defun which-key-show-full-minor-mode-keymap ()
+ "Show all bindings in KEYMAP using which-key.
+KEYMAP is selected interactively by mode in
+`minor-mode-map-alist'."
+ (interactive)
+ (which-key-show-minor-mode-keymap t))
+
+(defun which-key--show-keymap
+ (keymap-name keymap &optional prior-args all no-paging filter)
+ (when prior-args (push prior-args which-key--prior-show-keymap-args))
+ (let ((bindings (which-key--get-bindings nil keymap filter all)))
+ (if (= (length bindings) 0)
+ (message "which-key: No bindings found in %s" keymap-name)
+ (cond ((listp which-key-side-window-location)
+ (setq which-key--last-try-2-loc
+ (apply #'which-key--try-2-side-windows
+ bindings nil keymap-name
+ which-key-side-window-location)))
+ (t (setq which-key--pages-obj
+ (which-key--create-pages bindings nil keymap-name))
+ (which-key--show-page)))
+ (unless no-paging
+ (let* ((key (read-key))
+ (key-desc (key-description (list key)))
+ (next-def (lookup-key keymap (vector key))))
+ (cond ((and which-key-use-C-h-commands
+ (numberp key) (= key help-char))
+ (which-key-C-h-dispatch))
+ ((keymapp next-def)
+ (which-key--hide-popup-ignore-command)
+ (which-key--show-keymap
+ (concat keymap-name " " key-desc)
+ next-def
+ (cons keymap-name keymap)))
+ (t (which-key--hide-popup))))))))
+
+(defun which-key--evil-operator-filter (binding)
+ (let ((def (intern (cdr binding))))
+ (and (functionp def)
+ (not (evil-get-command-property def :suppress-operator)))))
+
+(defun which-key--show-evil-operator-keymap ()
+ (if which-key--inhibit-next-operator-popup
+ (setq which-key--inhibit-next-operator-popup nil)
+ (let ((keymap
+ (make-composed-keymap (list evil-operator-shortcut-map
+ evil-operator-state-map
+ evil-motion-state-map))))
+ (when (keymapp keymap)
+ (let ((formatted-keys
+ (which-key--get-bindings
+ nil keymap #'which-key--evil-operator-filter)))
+ (cond ((= (length formatted-keys) 0)
+ (message "which-key: Keymap empty"))
+ ((listp which-key-side-window-location)
+ (setq which-key--last-try-2-loc
+ (apply #'which-key--try-2-side-windows
+ formatted-keys nil "evil operator/motion keys"
+ which-key-side-window-location)))
+ (t (setq which-key--pages-obj
+ (which-key--create-pages
+ formatted-keys
+ nil "evil operator/motion keys"))
+ (which-key--show-page)))))
+ (let* ((key (read-key)))
+ (when (member key '(?f ?F ?t ?T ?`))
+ ;; these keys trigger commands that read the next char manually
+ (setq which-key--inhibit-next-operator-popup t))
+ (cond ((and which-key-use-C-h-commands (numberp key) (= key help-char))
+ (which-key-C-h-dispatch))
+ ((and (numberp key) (= key ?\C-\[))
+ (which-key--hide-popup)
+ (keyboard-quit))
+ (t
+ (which-key--hide-popup)
+ (setq unread-command-events (vector key))))))))
+
+(defun which-key--create-buffer-and-show
+ (&optional prefix-keys from-keymap filter prefix-title)
+ "Fill `which-key--buffer' with key descriptions and reformat.
+Finally, show the buffer."
+ (let ((start-time (current-time))
+ (formatted-keys (which-key--get-bindings
+ prefix-keys from-keymap filter))
+ (prefix-desc (key-description prefix-keys)))
+ (cond ((= (length formatted-keys) 0)
+ (message "%s- which-key: There are no keys to show" prefix-desc))
+ ((listp which-key-side-window-location)
+ (setq which-key--last-try-2-loc
+ (apply #'which-key--try-2-side-windows
+ formatted-keys prefix-keys prefix-title
+ which-key-side-window-location)))
+ (t (setq which-key--pages-obj
+ (which-key--create-pages
+ formatted-keys prefix-keys prefix-title))
+ (which-key--show-page)))
+ (which-key--debug-message
+ "On prefix \"%s\" which-key took %.0f ms." prefix-desc
+ (* 1000 (float-time (time-since start-time))))))
+
+(defun which-key--this-command-keys ()
+ "Version of `this-single-command-keys' corrected for key-chords and god-mode."
+ (let ((this-command-keys (this-single-command-keys)))
+ (when (and (vectorp this-command-keys)
+ (> (length this-command-keys) 0)
+ (eq (aref this-command-keys 0) 'key-chord)
+ (bound-and-true-p key-chord-mode))
+ (setq this-command-keys (this-single-command-raw-keys)))
+ (when (and which-key--god-mode-support-enabled
+ (bound-and-true-p god-local-mode)
+ (eq this-command 'god-mode-self-insert))
+ (setq this-command-keys (when which-key--god-mode-key-string
+ (kbd which-key--god-mode-key-string))))
+ this-command-keys))
+
+(defun which-key--update ()
+ "Function run by timer to possibly trigger
+`which-key--create-buffer-and-show'."
+ (let ((prefix-keys (which-key--this-command-keys))
+ delay-time)
+ (cond ((and (> (length prefix-keys) 0)
+ (or (keymapp (key-binding prefix-keys))
+ ;; Some keymaps are stored here like iso-transl-ctl-x-8-map
+ (keymapp (which-key--safe-lookup-key
+ key-translation-map prefix-keys))
+ ;; just in case someone uses one of these
+ (keymapp (which-key--safe-lookup-key
+ function-key-map prefix-keys)))
+ (not which-key-inhibit)
+ (or (null which-key-allow-regexps)
+ (which-key--any-match-p
+ which-key-allow-regexps (key-description prefix-keys)))
+ (or (null which-key-inhibit-regexps)
+ (not
+ (which-key--any-match-p
+ which-key-inhibit-regexps (key-description prefix-keys))))
+ ;; Do not display the popup if a command is currently being
+ ;; executed
+ (or (and which-key-allow-evil-operators
+ (bound-and-true-p evil-this-operator))
+ (and which-key--god-mode-support-enabled
+ (bound-and-true-p god-local-mode)
+ (eq this-command 'god-mode-self-insert))
+ (null this-command)))
+ (when (and (not (equal prefix-keys (which-key--current-prefix)))
+ (or (null which-key-delay-functions)
+ (null (setq delay-time
+ (run-hook-with-args-until-success
+ 'which-key-delay-functions
+ (key-description prefix-keys)
+ (length prefix-keys))))
+ (sit-for delay-time)))
+ (setq which-key--automatic-display t)
+ (which-key--create-buffer-and-show prefix-keys)
+ (when (and which-key-idle-secondary-delay
+ (not which-key--secondary-timer-active))
+ (which-key--start-timer which-key-idle-secondary-delay t))))
+ ((and which-key-show-transient-maps
+ ;; Assuming that if this is not true we're in
+ ;; `which-key-show-top-level', which would then be overwritten.
+ (> (length prefix-keys) 0)
+ (keymapp overriding-terminal-local-map)
+ ;; basic test for it being a hydra
+ (not (eq (lookup-key overriding-terminal-local-map "\C-u")
+ 'hydra--universal-argument)))
+ (which-key--create-buffer-and-show
+ nil overriding-terminal-local-map))
+ ((and which-key-show-operator-state-maps
+ (bound-and-true-p evil-state)
+ (eq evil-state 'operator)
+ (not (which-key--popup-showing-p)))
+ (which-key--show-evil-operator-keymap))
+ (which-key--automatic-display
+ (which-key--hide-popup)))))
+
+;;; Timers
+
+(defun which-key--start-timer (&optional delay secondary)
+ "Activate idle timer to trigger `which-key--update'."
+ (which-key--stop-timer)
+ (setq which-key--secondary-timer-active secondary)
+ (setq which-key--timer
+ (run-with-idle-timer (or delay which-key-idle-delay)
+ t #'which-key--update)))
+
+(defun which-key--stop-timer ()
+ "Deactivate idle timer for `which-key--update'."
+ (when which-key--timer (cancel-timer which-key--timer)))
+
+(defun which-key--start-paging-timer ()
+ "Activate timer to restart which-key after paging."
+ (when which-key--paging-timer (cancel-timer which-key--paging-timer))
+ (which-key--stop-timer)
+ (setq which-key--paging-timer
+ (run-with-idle-timer
+ 0.2 t (lambda ()
+ (when (or (not (member real-last-command
+ which-key--paging-functions))
+ (and (< 0 (length (this-single-command-keys)))
+ (not (equal (which-key--current-prefix)
+ (which-key--this-command-keys)))))
+ (cancel-timer which-key--paging-timer)
+ (if which-key-idle-secondary-delay
+ ;; we haven't executed a command yet so the secandary
+ ;; timer is more relevant here
+ (which-key--start-timer which-key-idle-secondary-delay t)
+ (which-key--start-timer)))))))
+
+(provide 'which-key)
+;;; which-key.el ends here
diff --git a/elpa/which-key-20220419.227/which-key.elc b/elpa/which-key-20220419.227/which-key.elc
new file mode 100644
index 0000000..3d5f60c
--- /dev/null
+++ b/elpa/which-key-20220419.227/which-key.elc
Binary files differ
diff --git a/elpa/with-editor-20220503.1124/dir b/elpa/with-editor-20220503.1124/dir
new file mode 100644
index 0000000..c5810e0
--- /dev/null
+++ b/elpa/with-editor-20220503.1124/dir
@@ -0,0 +1,18 @@
+This is the file .../info/dir, which contains the
+topmost node of the Info hierarchy, called (dir)Top.
+The first time you invoke Info you start off looking at this node.
+
+File: dir, Node: Top This is the top of the INFO tree
+
+ This (the Directory node) gives a menu of major topics.
+ Typing "q" exits, "H" lists all Info commands, "d" returns here,
+ "h" gives a primer for first-timers,
+ "mEmacs<Return>" visits the Emacs manual, etc.
+
+ In Emacs, you can click mouse button 2 on a menu item or cross reference
+ to select it.
+
+* Menu:
+
+Emacs
+* With-Editor: (with-editor). Using the Emacsclient as $EDITOR.
diff --git a/elpa/with-editor-20220503.1124/with-editor-autoloads.el b/elpa/with-editor-20220503.1124/with-editor-autoloads.el
new file mode 100644
index 0000000..bee6ae8
--- /dev/null
+++ b/elpa/with-editor-20220503.1124/with-editor-autoloads.el
@@ -0,0 +1,111 @@
+;;; with-editor-autoloads.el --- automatically extracted autoloads -*- lexical-binding: t -*-
+;;
+;;; Code:
+
+(add-to-list 'load-path (directory-file-name
+ (or (file-name-directory #$) (car load-path))))
+
+
+;;;### (autoloads nil "with-editor" "with-editor.el" (0 0 0 0))
+;;; Generated autoloads from with-editor.el
+
+(autoload 'with-editor-export-editor "with-editor" "\
+Teach subsequent commands to use current Emacs instance as editor.
+
+Set and export the environment variable ENVVAR, by default
+\"EDITOR\". The value is automatically generated to teach
+commands to use the current Emacs instance as \"the editor\".
+
+This works in `shell-mode', `term-mode', `eshell-mode' and
+`vterm'.
+
+\(fn &optional (ENVVAR \"EDITOR\"))" t nil)
+
+(autoload 'with-editor-export-git-editor "with-editor" "\
+Like `with-editor-export-editor' but always set `$GIT_EDITOR'." t nil)
+
+(autoload 'with-editor-export-hg-editor "with-editor" "\
+Like `with-editor-export-editor' but always set `$HG_EDITOR'." t nil)
+
+(defvar shell-command-with-editor-mode nil "\
+Non-nil if Shell-Command-With-Editor mode is enabled.
+See the `shell-command-with-editor-mode' command
+for a description of this minor mode.")
+
+(custom-autoload 'shell-command-with-editor-mode "with-editor" nil)
+
+(autoload 'shell-command-with-editor-mode "with-editor" "\
+Teach `shell-command' to use current Emacs instance as editor.
+
+This is a minor mode. If called interactively, toggle the
+`Shell-Command-With-Editor mode' mode. If the prefix argument is
+positive, enable the mode, and if it is zero or negative, disable
+the mode.
+
+If called from Lisp, toggle the mode if ARG is `toggle'. Enable
+the mode if ARG is nil, omitted, or is a positive number.
+Disable the mode if ARG is a negative number.
+
+To check whether the minor mode is enabled in the current buffer,
+evaluate `(default-value \\='shell-command-with-editor-mode)'.
+
+The mode's hook is called both when the mode is enabled and when
+it is disabled.
+
+Teach `shell-command', and all commands that ultimately call that
+command, to use the current Emacs instance as editor by executing
+\"EDITOR=CLIENT COMMAND&\" instead of just \"COMMAND&\".
+
+CLIENT is automatically generated; EDITOR=CLIENT instructs
+COMMAND to use to the current Emacs instance as \"the editor\",
+assuming no other variable overrides the effect of \"$EDITOR\".
+CLIENT may be the path to an appropriate emacsclient executable
+with arguments, or a script which also works over Tramp.
+
+Alternatively you can use the `with-editor-async-shell-command',
+which also allows the use of another variable instead of
+\"EDITOR\".
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'with-editor-async-shell-command "with-editor" "\
+Like `async-shell-command' but with `$EDITOR' set.
+
+Execute string \"ENVVAR=CLIENT COMMAND\" in an inferior shell;
+display output, if any. With a prefix argument prompt for an
+environment variable, otherwise the default \"EDITOR\" variable
+is used. With a negative prefix argument additionally insert
+the COMMAND's output at point.
+
+CLIENT is automatically generated; ENVVAR=CLIENT instructs
+COMMAND to use to the current Emacs instance as \"the editor\",
+assuming it respects ENVVAR as an \"EDITOR\"-like variable.
+CLIENT may be the path to an appropriate emacsclient executable
+with arguments, or a script which also works over Tramp.
+
+Also see `async-shell-command' and `shell-command'.
+
+\(fn COMMAND &optional OUTPUT-BUFFER ERROR-BUFFER ENVVAR)" t nil)
+
+(autoload 'with-editor-shell-command "with-editor" "\
+Like `shell-command' or `with-editor-async-shell-command'.
+If COMMAND ends with \"&\" behave like the latter,
+else like the former.
+
+\(fn COMMAND &optional OUTPUT-BUFFER ERROR-BUFFER ENVVAR)" t nil)
+
+(register-definition-prefixes "with-editor" '("server-" "shell-command--shell-command-with-editor-mode" "start-file-process--with-editor-process-filter" "with-editor"))
+
+;;;***
+
+;;;### (autoloads nil nil ("with-editor-pkg.el") (0 0 0 0))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; coding: utf-8
+;; End:
+;;; with-editor-autoloads.el ends here
diff --git a/elpa/with-editor-20220503.1124/with-editor-pkg.el b/elpa/with-editor-20220503.1124/with-editor-pkg.el
new file mode 100644
index 0000000..b035677
--- /dev/null
+++ b/elpa/with-editor-20220503.1124/with-editor-pkg.el
@@ -0,0 +1,13 @@
+(define-package "with-editor" "20220503.1124" "Use the Emacsclient as $EDITOR"
+ '((emacs "25.1")
+ (compat "28.1.1.0"))
+ :commit "48996e3116dadee06c8c68b1a0fe6ad8fd5317e0" :authors
+ '(("Jonas Bernoulli" . "jonas@bernoul.li"))
+ :maintainer
+ '("Jonas Bernoulli" . "jonas@bernoul.li")
+ :keywords
+ '("processes" "terminals")
+ :url "https://github.com/magit/with-editor")
+;; Local Variables:
+;; no-byte-compile: t
+;; End:
diff --git a/elpa/with-editor-20220503.1124/with-editor.el b/elpa/with-editor-20220503.1124/with-editor.el
new file mode 100644
index 0000000..dd65d00
--- /dev/null
+++ b/elpa/with-editor-20220503.1124/with-editor.el
@@ -0,0 +1,945 @@
+;;; with-editor.el --- Use the Emacsclient as $EDITOR -*- lexical-binding:t -*-
+
+;; Copyright (C) 2014-2022 The Magit Project Contributors
+
+;; Author: Jonas Bernoulli <jonas@bernoul.li>
+;; Homepage: https://github.com/magit/with-editor
+;; Keywords: processes terminals
+
+;; Package-Version: 3.2.0-git
+;; Package-Requires: ((emacs "25.1") (compat "28.1.1.0"))
+
+;; SPDX-License-Identifier: GPL-3.0-or-later
+
+;; 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 3 of the License,
+;; 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 file. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This library makes it possible to reliably use the Emacsclient as
+;; the `$EDITOR' of child processes. It makes sure that they know how
+;; to call home. For remote processes a substitute is provided, which
+;; communicates with Emacs on standard output/input instead of using a
+;; socket as the Emacsclient does.
+
+;; It provides the commands `with-editor-async-shell-command' and
+;; `with-editor-shell-command', which are intended as replacements
+;; for `async-shell-command' and `shell-command'. They automatically
+;; export `$EDITOR' making sure the executed command uses the current
+;; Emacs instance as "the editor". With a prefix argument these
+;; commands prompt for an alternative environment variable such as
+;; `$GIT_EDITOR'. To always use these variants add this to your init
+;; file:
+;;
+;; (define-key (current-global-map)
+;; [remap async-shell-command] #'with-editor-async-shell-command)
+;; (define-key (current-global-map)
+;; [remap shell-command] #'with-editor-shell-command)
+
+;; Alternatively use the global `shell-command-with-editor-mode',
+;; which always sets `$EDITOR' for all Emacs commands which ultimately
+;; use `shell-command' to asynchronously run some shell command.
+
+;; The command `with-editor-export-editor' exports `$EDITOR' or
+;; another such environment variable in `shell-mode', `eshell-mode',
+;; `term-mode' and `vterm-mode' buffers. Use this Emacs command
+;; before executing a shell command which needs the editor set, or
+;; always arrange for the current Emacs instance to be used as editor
+;; by adding it to the appropriate mode hooks:
+;;
+;; (add-hook 'shell-mode-hook #'with-editor-export-editor)
+;; (add-hook 'eshell-mode-hook #'with-editor-export-editor)
+;; (add-hook 'term-exec-hook #'with-editor-export-editor)
+;; (add-hook 'vterm-mode-hook #'with-editor-export-editor)
+
+;; Some variants of this function exist, these two forms are
+;; equivalent:
+;;
+;; (add-hook 'shell-mode-hook
+;; (apply-partially #'with-editor-export-editor "GIT_EDITOR"))
+;; (add-hook 'shell-mode-hook #'with-editor-export-git-editor)
+
+;; This library can also be used by other packages which need to use
+;; the current Emacs instance as editor. In fact this library was
+;; written for Magit and its `git-commit-mode' and `git-rebase-mode'.
+;; Consult `git-rebase.el' and the related code in `magit-sequence.el'
+;; for a simple example.
+
+;;; Code:
+
+(require 'cl-lib)
+(require 'compat)
+(require 'server)
+(require 'shell)
+(eval-when-compile (require 'subr-x))
+
+(declare-function dired-get-filename "dired"
+ (&optional localp no-error-if-not-filep))
+(declare-function term-emulate-terminal "term" (proc str))
+(declare-function vterm-send-return "vterm" ())
+(declare-function vterm-send-string "vterm" (string &optional paste-p))
+(defvar eshell-preoutput-filter-functions)
+(defvar git-commit-post-finish-hook)
+(defvar vterm--process)
+(defvar warning-minimum-level)
+(defvar warning-minimum-log-level)
+
+;;; Options
+
+(defgroup with-editor nil
+ "Use the Emacsclient as $EDITOR."
+ :group 'external
+ :group 'server)
+
+(defun with-editor-locate-emacsclient ()
+ "Search for a suitable Emacsclient executable."
+ (or (with-editor-locate-emacsclient-1
+ (with-editor-emacsclient-path)
+ (length (split-string emacs-version "\\.")))
+ (prog1 nil (display-warning 'with-editor "\
+Cannot determine a suitable Emacsclient
+
+Determining an Emacsclient executable suitable for the
+current Emacs instance failed. For more information
+please see https://github.com/magit/magit/wiki/Emacsclient."))))
+
+(defun with-editor-locate-emacsclient-1 (path depth)
+ (let* ((version-lst (cl-subseq (split-string emacs-version "\\.") 0 depth))
+ (version-reg (concat "^" (mapconcat #'identity version-lst "\\."))))
+ (or (locate-file
+ (if (equal (downcase invocation-name) "remacs")
+ "remacsclient"
+ "emacsclient")
+ path
+ (cl-mapcan
+ (lambda (v) (cl-mapcar (lambda (e) (concat v e)) exec-suffixes))
+ (nconc (and (boundp 'debian-emacs-flavor)
+ (list (format ".%s" debian-emacs-flavor)))
+ (cl-mapcon (lambda (v)
+ (setq v (mapconcat #'identity (reverse v) "."))
+ (list v (concat "-" v) (concat ".emacs" v)))
+ (reverse version-lst))
+ (list "" "-snapshot" ".emacs-snapshot")))
+ (lambda (exec)
+ (ignore-errors
+ (string-match-p version-reg
+ (with-editor-emacsclient-version exec)))))
+ (and (> depth 1)
+ (with-editor-locate-emacsclient-1 path (1- depth))))))
+
+(defun with-editor-emacsclient-version (exec)
+ (let ((default-directory (file-name-directory exec)))
+ (ignore-errors
+ (cadr (split-string (car (process-lines exec "--version")))))))
+
+(defun with-editor-emacsclient-path ()
+ (let ((path exec-path))
+ (when invocation-directory
+ (push (directory-file-name invocation-directory) path)
+ (let* ((linkname (expand-file-name invocation-name invocation-directory))
+ (truename (file-chase-links linkname)))
+ (unless (equal truename linkname)
+ (push (directory-file-name (file-name-directory truename)) path)))
+ (when (eq system-type 'darwin)
+ (let ((dir (expand-file-name "bin" invocation-directory)))
+ (when (file-directory-p dir)
+ (push dir path)))
+ (when (string-search "Cellar" invocation-directory)
+ (let ((dir (expand-file-name "../../../bin" invocation-directory)))
+ (when (file-directory-p dir)
+ (push dir path))))))
+ (cl-remove-duplicates path :test #'equal)))
+
+(defcustom with-editor-emacsclient-executable (with-editor-locate-emacsclient)
+ "The Emacsclient executable used by the `with-editor' macro."
+ :group 'with-editor
+ :type '(choice (string :tag "Executable")
+ (const :tag "Don't use Emacsclient" nil)))
+
+(defcustom with-editor-sleeping-editor "\
+sh -c '\
+printf \"\\nWITH-EDITOR: $$ OPEN $0\\037 IN $(pwd)\\n\"; \
+sleep 604800 & sleep=$!; \
+trap \"kill $sleep; exit 0\" USR1; \
+trap \"kill $sleep; exit 1\" USR2; \
+wait $sleep'"
+ "The sleeping editor, used when the Emacsclient cannot be used.
+
+This fallback is used for asynchronous processes started inside
+the macro `with-editor', when the process runs on a remote machine
+or for local processes when `with-editor-emacsclient-executable'
+is nil (i.e. when no suitable Emacsclient was found, or the user
+decided not to use it).
+
+Where the latter uses a socket to communicate with Emacs' server,
+this substitute prints edit requests to its standard output on
+which a process filter listens for such requests. As such it is
+not a complete substitute for a proper Emacsclient, it can only
+be used as $EDITOR of child process of the current Emacs instance.
+
+Some shells do not execute traps immediately when waiting for a
+child process, but by default we do use such a blocking child
+process.
+
+If you use such a shell (e.g. `csh' on FreeBSD, but not Debian),
+then you have to edit this option. You can either replace \"sh\"
+with \"bash\" (and install that), or you can use the older, less
+performant implementation:
+
+ \"sh -c '\\
+ echo -e \\\"\\nWITH-EDITOR: $$ OPEN $0 IN $(pwd)\\n\\\"; \\
+ trap \\\"exit 0\\\" USR1; \\
+ trap \\\"exit 1\" USR2; \\
+ while true; do sleep 1; done'\"
+
+Note that the unit separator character () right after the file
+name ($0) is required.
+
+Also note that using this alternative implementation leads to a
+delay of up to a second. The delay can be shortened by replacing
+\"sleep 1\" with \"sleep 0.01\", or if your implementation does
+not support floats, then by using \"nanosleep\" instead."
+ :package-version '(with-editor . "2.8.0")
+ :group 'with-editor
+ :type 'string)
+
+(defcustom with-editor-finish-query-functions nil
+ "List of functions called to query before finishing session.
+
+The buffer in question is current while the functions are called.
+If any of them returns nil, then the session is not finished and
+the buffer is not killed. The user should then fix the issue and
+try again. The functions are called with one argument. If it is
+non-nil then that indicates that the user used a prefix argument
+to force finishing the session despite issues. Functions should
+usually honor that and return non-nil."
+ :group 'with-editor
+ :type 'hook)
+(put 'with-editor-finish-query-functions 'permanent-local t)
+
+(defcustom with-editor-cancel-query-functions nil
+ "List of functions called to query before canceling session.
+
+The buffer in question is current while the functions are called.
+If any of them returns nil, then the session is not canceled and
+the buffer is not killed. The user should then fix the issue and
+try again. The functions are called with one argument. If it is
+non-nil then that indicates that the user used a prefix argument
+to force canceling the session despite issues. Functions should
+usually honor that and return non-nil."
+ :group 'with-editor
+ :type 'hook)
+(put 'with-editor-cancel-query-functions 'permanent-local t)
+
+(defcustom with-editor-mode-lighter " WE"
+ "The mode-line lighter of the With-Editor mode."
+ :group 'with-editor
+ :type '(choice (const :tag "No lighter" "") string))
+
+(defvar with-editor-server-window-alist nil
+ "Alist of filename patterns vs corresponding `server-window'.
+
+Each element looks like (REGEXP . FUNCTION). Files matching
+REGEXP are selected using FUNCTION instead of the default in
+`server-window'.
+
+Note that when a package adds an entry here then it probably
+has a reason to disrespect `server-window' and it likely is
+not a good idea to change such entries.")
+
+(defvar with-editor-file-name-history-exclude nil
+ "List of regexps for filenames `server-visit' should not remember.
+When a filename matches any of the regexps, then `server-visit'
+does not add it to the variable `file-name-history', which is
+used when reading a filename in the minibuffer.")
+
+(defcustom with-editor-shell-command-use-emacsclient t
+ "Whether to use the emacsclient when running shell commands.
+
+This affects `with-editor-shell-command-async' and, if the input
+ends with \"&\" `with-editor-shell-command' .
+
+If `shell-command-with-editor-mode' is enabled, then it also
+affects `shell-command-async' and, if the input ends with \"&\"
+`shell-command'.
+
+This is a temporary kludge that lets you choose between two
+possible defects, the ones described in the issues #23 and #40.
+
+When t, then use the emacsclient. This has the disadvantage that
+`with-editor-mode' won't be enabled because we don't know whether
+this package was involved at all in the call to the emacsclient,
+and when it is not, then we really should. The problem is that
+the emacsclient doesn't pass a long any environment variables to
+the server. This will hopefully be fixed in Emacs eventually.
+
+When nil, then use the sleeping editor. Because in this case we
+know that this package is involved, we can enable the mode. But
+this makes it necessary that you invoke $EDITOR in shell scripts
+like so:
+
+ eval \"$EDITOR\" file
+
+And some tools that do not handle $EDITOR properly also break."
+ :package-version '(with-editor . "2.7.1")
+ :group 'with-editor
+ :type 'boolean)
+
+;;; Mode Commands
+
+(defvar with-editor-pre-finish-hook nil)
+(defvar with-editor-pre-cancel-hook nil)
+(defvar with-editor-post-finish-hook nil)
+(defvar with-editor-post-finish-hook-1 nil)
+(defvar with-editor-post-cancel-hook nil)
+(defvar with-editor-post-cancel-hook-1 nil)
+(defvar with-editor-cancel-alist nil)
+(put 'with-editor-pre-finish-hook 'permanent-local t)
+(put 'with-editor-pre-cancel-hook 'permanent-local t)
+(put 'with-editor-post-finish-hook 'permanent-local t)
+(put 'with-editor-post-cancel-hook 'permanent-local t)
+
+(defvar-local with-editor-show-usage t)
+(defvar-local with-editor-cancel-message nil)
+(defvar-local with-editor-previous-winconf nil)
+(put 'with-editor-cancel-message 'permanent-local t)
+(put 'with-editor-previous-winconf 'permanent-local t)
+
+(defvar-local with-editor--pid nil "For internal use.")
+(put 'with-editor--pid 'permanent-local t)
+
+(defun with-editor-finish (force)
+ "Finish the current edit session."
+ (interactive "P")
+ (when (run-hook-with-args-until-failure
+ 'with-editor-finish-query-functions force)
+ (let ((post-finish-hook with-editor-post-finish-hook)
+ (post-commit-hook (bound-and-true-p git-commit-post-finish-hook))
+ (dir default-directory))
+ (run-hooks 'with-editor-pre-finish-hook)
+ (with-editor-return nil)
+ (accept-process-output nil 0.1)
+ (with-temp-buffer
+ (setq default-directory dir)
+ (setq-local with-editor-post-finish-hook post-finish-hook)
+ (when post-commit-hook
+ (setq-local git-commit-post-finish-hook post-commit-hook))
+ (run-hooks 'with-editor-post-finish-hook)))))
+
+(defun with-editor-cancel (force)
+ "Cancel the current edit session."
+ (interactive "P")
+ (when (run-hook-with-args-until-failure
+ 'with-editor-cancel-query-functions force)
+ (let ((message with-editor-cancel-message))
+ (when (functionp message)
+ (setq message (funcall message)))
+ (let ((post-cancel-hook with-editor-post-cancel-hook)
+ (with-editor-cancel-alist nil)
+ (dir default-directory))
+ (run-hooks 'with-editor-pre-cancel-hook)
+ (with-editor-return t)
+ (accept-process-output nil 0.1)
+ (with-temp-buffer
+ (setq default-directory dir)
+ (setq-local with-editor-post-cancel-hook post-cancel-hook)
+ (run-hooks 'with-editor-post-cancel-hook)))
+ (message (or message "Canceled by user")))))
+
+(defun with-editor-return (cancel)
+ (let ((winconf with-editor-previous-winconf)
+ (clients server-buffer-clients)
+ (dir default-directory)
+ (pid with-editor--pid))
+ (remove-hook 'kill-buffer-query-functions
+ #'with-editor-kill-buffer-noop t)
+ (cond (cancel
+ (save-buffer)
+ (if clients
+ (dolist (client clients)
+ (ignore-errors
+ (server-send-string client "-error Canceled by user"))
+ (delete-process client))
+ ;; Fallback for when emacs was used as $EDITOR
+ ;; instead of emacsclient or the sleeping editor.
+ ;; See https://github.com/magit/magit/issues/2258.
+ (ignore-errors (delete-file buffer-file-name))
+ (kill-buffer)))
+ (t
+ (save-buffer)
+ (if clients
+ ;; Don't use `server-edit' because we do not want to
+ ;; show another buffer belonging to another client.
+ ;; See https://github.com/magit/magit/issues/2197.
+ (server-done)
+ (kill-buffer))))
+ (when pid
+ (let ((default-directory dir))
+ (process-file "kill" nil nil nil
+ "-s" (if cancel "USR2" "USR1") pid)))
+ (when (and winconf (eq (window-configuration-frame winconf)
+ (selected-frame)))
+ (set-window-configuration winconf))))
+
+;;; Mode
+
+(defvar with-editor-mode-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map "\C-c\C-c" #'with-editor-finish)
+ (define-key map [remap server-edit] #'with-editor-finish)
+ (define-key map [remap evil-save-and-close] #'with-editor-finish)
+ (define-key map [remap evil-save-modified-and-close] #'with-editor-finish)
+ (define-key map "\C-c\C-k" #'with-editor-cancel)
+ (define-key map [remap kill-buffer] #'with-editor-cancel)
+ (define-key map [remap ido-kill-buffer] #'with-editor-cancel)
+ (define-key map [remap iswitchb-kill-buffer] #'with-editor-cancel)
+ (define-key map [remap evil-quit] #'with-editor-cancel)
+ map))
+
+(define-minor-mode with-editor-mode
+ "Edit a file as the $EDITOR of an external process."
+ :lighter with-editor-mode-lighter
+ ;; Protect the user from killing the buffer without using
+ ;; either `with-editor-finish' or `with-editor-cancel',
+ ;; and from removing the key bindings for these commands.
+ (unless with-editor-mode
+ (user-error "With-Editor mode cannot be turned off"))
+ (add-hook 'kill-buffer-query-functions
+ #'with-editor-kill-buffer-noop nil t)
+ ;; `server-execute' displays a message which is not
+ ;; correct when using this mode.
+ (when with-editor-show-usage
+ (with-editor-usage-message)))
+
+(put 'with-editor-mode 'permanent-local t)
+
+(defun with-editor-kill-buffer-noop ()
+ ;; We started doing this in response to #64, but it is not safe
+ ;; to do so, because the client has already been killed, causing
+ ;; `with-editor-return' (called by `with-editor-cancel') to delete
+ ;; the file, see #66. The reason we delete the file in the first
+ ;; place are https://github.com/magit/magit/issues/2258 and
+ ;; https://github.com/magit/magit/issues/2248.
+ ;; (if (memq this-command '(save-buffers-kill-terminal
+ ;; save-buffers-kill-emacs))
+ ;; (let ((with-editor-cancel-query-functions nil))
+ ;; (with-editor-cancel nil)
+ ;; t)
+ ;; ...)
+ ;; So go back to always doing this instead:
+ (user-error (substitute-command-keys (format "\
+Don't kill this buffer %S. Instead cancel using \\[with-editor-cancel]"
+ (current-buffer)))))
+
+(defvar-local with-editor-usage-message "\
+Type \\[with-editor-finish] to finish, \
+or \\[with-editor-cancel] to cancel")
+
+(defun with-editor-usage-message ()
+ ;; Run after `server-execute', which is run using
+ ;; a timer which starts immediately.
+ (let ((buffer (current-buffer)))
+ (run-with-timer
+ 0.05 nil
+ (lambda ()
+ (with-current-buffer buffer
+ (message (substitute-command-keys with-editor-usage-message)))))))
+
+;;; Wrappers
+
+(defvar with-editor--envvar nil "For internal use.")
+
+(defmacro with-editor (&rest body)
+ "Use the Emacsclient as $EDITOR while evaluating BODY.
+Modify the `process-environment' for processes started in BODY,
+instructing them to use the Emacsclient as $EDITOR. If optional
+ENVVAR is a literal string then bind that environment variable
+instead.
+\n(fn [ENVVAR] BODY...)"
+ (declare (indent defun) (debug (body)))
+ `(let ((with-editor--envvar ,(if (stringp (car body))
+ (pop body)
+ '(or with-editor--envvar "EDITOR")))
+ (process-environment process-environment))
+ (with-editor--setup)
+ ,@body))
+
+(defmacro with-editor* (envvar &rest body)
+ "Use the Emacsclient as the editor while evaluating BODY.
+Modify the `process-environment' for processes started in BODY,
+instructing them to use the Emacsclient as editor. ENVVAR is the
+environment variable that is exported to do so, it is evaluated
+at run-time.
+\n(fn [ENVVAR] BODY...)"
+ (declare (indent defun) (debug (sexp body)))
+ `(let ((with-editor--envvar ,envvar)
+ (process-environment process-environment))
+ (with-editor--setup)
+ ,@body))
+
+(defun with-editor--setup ()
+ (if (or (not with-editor-emacsclient-executable)
+ (file-remote-p default-directory))
+ (push (concat with-editor--envvar "=" with-editor-sleeping-editor)
+ process-environment)
+ ;; Make sure server-use-tcp's value is valid.
+ (unless (featurep 'make-network-process '(:family local))
+ (setq server-use-tcp t))
+ ;; Make sure the server is running.
+ (unless (process-live-p server-process)
+ (when (server-running-p server-name)
+ (setq server-name (format "server%s" (emacs-pid)))
+ (when (server-running-p server-name)
+ (server-force-delete server-name)))
+ (server-start))
+ ;; Tell $EDITOR to use the Emacsclient.
+ (push (concat with-editor--envvar "="
+ (shell-quote-argument with-editor-emacsclient-executable)
+ ;; Tell the process where the server file is.
+ (and (not server-use-tcp)
+ (concat " --socket-name="
+ (shell-quote-argument
+ (expand-file-name server-name
+ server-socket-dir)))))
+ process-environment)
+ (when server-use-tcp
+ (push (concat "EMACS_SERVER_FILE="
+ (expand-file-name server-name server-auth-dir))
+ process-environment))
+ ;; As last resort fallback to the sleeping editor.
+ (push (concat "ALTERNATE_EDITOR=" with-editor-sleeping-editor)
+ process-environment)))
+
+(defun with-editor-server-window ()
+ (or (and buffer-file-name
+ (cdr (cl-find-if (lambda (cons)
+ (string-match-p (car cons) buffer-file-name))
+ with-editor-server-window-alist)))
+ server-window))
+
+(defun server-switch-buffer--with-editor-server-window-alist
+ (fn &optional next-buffer &rest args)
+ "Honor `with-editor-server-window-alist' (which see)."
+ (let ((server-window (with-current-buffer
+ (or next-buffer (current-buffer))
+ (when with-editor-mode
+ (setq with-editor-previous-winconf
+ (current-window-configuration)))
+ (with-editor-server-window))))
+ (apply fn next-buffer args)))
+
+(advice-add 'server-switch-buffer :around
+ #'server-switch-buffer--with-editor-server-window-alist)
+
+(defun start-file-process--with-editor-process-filter
+ (fn name buffer program &rest program-args)
+ "When called inside a `with-editor' form and the Emacsclient
+cannot be used, then give the process the filter function
+`with-editor-process-filter'. To avoid overriding the filter
+being added here you should use `with-editor-set-process-filter'
+instead of `set-process-filter' inside `with-editor' forms.
+
+When the `default-directory' is located on a remote machine,
+then also manipulate PROGRAM and PROGRAM-ARGS in order to set
+the appropriate editor environment variable."
+ (if (not with-editor--envvar)
+ (apply fn name buffer program program-args)
+ (when (file-remote-p default-directory)
+ (unless (equal program "env")
+ (push program program-args)
+ (setq program "env"))
+ (push (concat with-editor--envvar "=" with-editor-sleeping-editor)
+ program-args))
+ (let ((process (apply fn name buffer program program-args)))
+ (set-process-filter process #'with-editor-process-filter)
+ (process-put process 'default-dir default-directory)
+ process)))
+
+(advice-add 'start-file-process :around
+ #'start-file-process--with-editor-process-filter)
+
+(cl-defun make-process--with-editor-process-filter
+ (fn &rest keys &key name buffer command coding noquery stop
+ connection-type filter sentinel stderr file-handler
+ &allow-other-keys)
+ "When called inside a `with-editor' form and the Emacsclient
+cannot be used, then give the process the filter function
+`with-editor-process-filter'. To avoid overriding the filter
+being added here you should use `with-editor-set-process-filter'
+instead of `set-process-filter' inside `with-editor' forms.
+
+When the `default-directory' is located on a remote machine and
+FILE-HANDLER is non-nil, then also manipulate COMMAND in order
+to set the appropriate editor environment variable."
+ (if (or (not file-handler) (not with-editor--envvar))
+ (apply fn keys)
+ (when (file-remote-p default-directory)
+ (unless (equal (car command) "env")
+ (push "env" command))
+ (push (concat with-editor--envvar "=" with-editor-sleeping-editor)
+ (cdr command)))
+ (let* ((filter (if filter
+ (lambda (process output)
+ (funcall filter process output)
+ (with-editor-process-filter process output t))
+ #'with-editor-process-filter))
+ (process (funcall fn
+ :name name
+ :buffer buffer
+ :command command
+ :coding coding
+ :noquery noquery
+ :stop stop
+ :connection-type connection-type
+ :filter filter
+ :sentinel sentinel
+ :stderr stderr
+ :file-handler file-handler)))
+ (process-put process 'default-dir default-directory)
+ process)))
+
+(advice-add #'make-process :around #'make-process--with-editor-process-filter)
+
+(defun with-editor-set-process-filter (process filter)
+ "Like `set-process-filter' but keep `with-editor-process-filter'.
+Give PROCESS the new FILTER but keep `with-editor-process-filter'
+if that was added earlier by the advised `start-file-process'.
+
+Do so by wrapping the two filter functions using a lambda, which
+becomes the actual filter. It calls FILTER first, which may or
+may not insert the text into the PROCESS's buffer. Then it calls
+`with-editor-process-filter', passing t as NO-STANDARD-FILTER."
+ (set-process-filter
+ process
+ (if (eq (process-filter process) 'with-editor-process-filter)
+ `(lambda (proc str)
+ (,filter proc str)
+ (with-editor-process-filter proc str t))
+ filter)))
+
+(defvar with-editor-filter-visit-hook nil)
+
+(defconst with-editor-sleeping-editor-regexp
+ "^WITH-EDITOR: \\([0-9]+\\) OPEN \\([^]+?\\)\\(?: IN \\([^\r]+?\\)\\)?\r?$")
+
+(defvar with-editor--max-incomplete-length 1000)
+
+(defun with-editor-sleeping-editor-filter (process string)
+ (when-let ((incomplete (and process (process-get process 'incomplete))))
+ (setq string (concat incomplete string)))
+ (save-match-data
+ (cond
+ ((and process (not (string-suffix-p "\n" string)))
+ (let ((length (length string)))
+ (when (> length with-editor--max-incomplete-length)
+ (setq string
+ (substring string
+ (- length with-editor--max-incomplete-length)))))
+ (process-put process 'incomplete string)
+ nil)
+ ((string-match with-editor-sleeping-editor-regexp string)
+ (when process
+ (process-put process 'incomplete nil))
+ (let ((pid (match-string 1 string))
+ (file (match-string 2 string))
+ (dir (match-string 3 string)))
+ (unless (file-name-absolute-p file)
+ (setq file (expand-file-name file dir)))
+ (when default-directory
+ (setq file (concat (file-remote-p default-directory) file)))
+ (with-current-buffer (find-file-noselect file)
+ (with-editor-mode 1)
+ (setq with-editor--pid pid)
+ (setq with-editor-previous-winconf
+ (current-window-configuration))
+ (run-hooks 'with-editor-filter-visit-hook)
+ (funcall (or (with-editor-server-window) #'switch-to-buffer)
+ (current-buffer))
+ (kill-local-variable 'server-window)))
+ nil)
+ (t string))))
+
+(defun with-editor-process-filter
+ (process string &optional no-default-filter)
+ "Listen for edit requests by child processes."
+ (let ((default-directory (process-get process 'default-dir)))
+ (with-editor-sleeping-editor-filter process string))
+ (unless no-default-filter
+ (internal-default-process-filter process string)))
+
+(advice-add 'server-visit-files :after
+ #'server-visit-files--with-editor-file-name-history-exclude)
+
+(defun server-visit-files--with-editor-file-name-history-exclude
+ (files _proc &optional _nowait)
+ (pcase-dolist (`(,file . ,_) files)
+ (when (cl-find-if (lambda (regexp)
+ (string-match-p regexp file))
+ with-editor-file-name-history-exclude)
+ (setq file-name-history (delete file file-name-history)))))
+
+;;; Augmentations
+
+;;;###autoload
+(cl-defun with-editor-export-editor (&optional (envvar "EDITOR"))
+ "Teach subsequent commands to use current Emacs instance as editor.
+
+Set and export the environment variable ENVVAR, by default
+\"EDITOR\". The value is automatically generated to teach
+commands to use the current Emacs instance as \"the editor\".
+
+This works in `shell-mode', `term-mode', `eshell-mode' and
+`vterm'."
+ (interactive (list (with-editor-read-envvar)))
+ (cond
+ ((derived-mode-p 'comint-mode 'term-mode)
+ (when-let ((process (get-buffer-process (current-buffer))))
+ (goto-char (process-mark process))
+ (process-send-string
+ process (format " export %s=%s\n" envvar
+ (shell-quote-argument with-editor-sleeping-editor)))
+ (while (accept-process-output process 0.1))
+ (if (derived-mode-p 'term-mode)
+ (with-editor-set-process-filter process #'with-editor-emulate-terminal)
+ (add-hook 'comint-output-filter-functions #'with-editor-output-filter
+ nil t))))
+ ((derived-mode-p 'eshell-mode)
+ (add-to-list 'eshell-preoutput-filter-functions
+ #'with-editor-output-filter)
+ (setenv envvar with-editor-sleeping-editor))
+ ((derived-mode-p 'vterm-mode)
+ (if with-editor-emacsclient-executable
+ (let ((with-editor--envvar envvar)
+ (process-environment process-environment))
+ (with-editor--setup)
+ (while (accept-process-output vterm--process 0.1))
+ (when-let ((v (getenv envvar)))
+ (vterm-send-string (format "export %s=%S" envvar v))
+ (vterm-send-return))
+ (when-let ((v (getenv "EMACS_SERVER_FILE")))
+ (vterm-send-string (format "export EMACS_SERVER_FILE=%S" v))
+ (vterm-send-return))
+ (vterm-send-string "clear")
+ (vterm-send-return))
+ (error "Cannot use sleeping editor in this buffer")))
+ (t
+ (error "Cannot export environment variables in this buffer")))
+ (message "Successfully exported %s" envvar))
+
+;;;###autoload
+(defun with-editor-export-git-editor ()
+ "Like `with-editor-export-editor' but always set `$GIT_EDITOR'."
+ (interactive)
+ (with-editor-export-editor "GIT_EDITOR"))
+
+;;;###autoload
+(defun with-editor-export-hg-editor ()
+ "Like `with-editor-export-editor' but always set `$HG_EDITOR'."
+ (interactive)
+ (with-editor-export-editor "HG_EDITOR"))
+
+(defun with-editor-output-filter (string)
+ "Handle edit requests on behalf of `comint-mode' and `eshell-mode'."
+ (with-editor-sleeping-editor-filter nil string))
+
+(defun with-editor-emulate-terminal (process string)
+ "Like `term-emulate-terminal' but also handle edit requests."
+ (let ((with-editor-sleeping-editor-regexp
+ (substring with-editor-sleeping-editor-regexp 1)))
+ (with-editor-sleeping-editor-filter process string))
+ (term-emulate-terminal process string))
+
+(defvar with-editor-envvars '("EDITOR" "GIT_EDITOR" "HG_EDITOR"))
+
+(cl-defun with-editor-read-envvar
+ (&optional (prompt "Set environment variable")
+ (default "EDITOR"))
+ (let ((reply (completing-read (if default
+ (format "%s (%s): " prompt default)
+ (concat prompt ": "))
+ with-editor-envvars nil nil nil nil default)))
+ (if (string= reply "") (user-error "Nothing selected") reply)))
+
+;;;###autoload
+(define-minor-mode shell-command-with-editor-mode
+ "Teach `shell-command' to use current Emacs instance as editor.
+
+Teach `shell-command', and all commands that ultimately call that
+command, to use the current Emacs instance as editor by executing
+\"EDITOR=CLIENT COMMAND&\" instead of just \"COMMAND&\".
+
+CLIENT is automatically generated; EDITOR=CLIENT instructs
+COMMAND to use to the current Emacs instance as \"the editor\",
+assuming no other variable overrides the effect of \"$EDITOR\".
+CLIENT may be the path to an appropriate emacsclient executable
+with arguments, or a script which also works over Tramp.
+
+Alternatively you can use the `with-editor-async-shell-command',
+which also allows the use of another variable instead of
+\"EDITOR\"."
+ :global t)
+
+;;;###autoload
+(defun with-editor-async-shell-command
+ (command &optional output-buffer error-buffer envvar)
+ "Like `async-shell-command' but with `$EDITOR' set.
+
+Execute string \"ENVVAR=CLIENT COMMAND\" in an inferior shell;
+display output, if any. With a prefix argument prompt for an
+environment variable, otherwise the default \"EDITOR\" variable
+is used. With a negative prefix argument additionally insert
+the COMMAND's output at point.
+
+CLIENT is automatically generated; ENVVAR=CLIENT instructs
+COMMAND to use to the current Emacs instance as \"the editor\",
+assuming it respects ENVVAR as an \"EDITOR\"-like variable.
+CLIENT may be the path to an appropriate emacsclient executable
+with arguments, or a script which also works over Tramp.
+
+Also see `async-shell-command' and `shell-command'."
+ (interactive (with-editor-shell-command-read-args "Async shell command: " t))
+ (let ((with-editor--envvar envvar))
+ (with-editor
+ (async-shell-command command output-buffer error-buffer))))
+
+;;;###autoload
+(defun with-editor-shell-command
+ (command &optional output-buffer error-buffer envvar)
+ "Like `shell-command' or `with-editor-async-shell-command'.
+If COMMAND ends with \"&\" behave like the latter,
+else like the former."
+ (interactive (with-editor-shell-command-read-args "Shell command: "))
+ (if (string-match "&[ \t]*\\'" command)
+ (with-editor-async-shell-command
+ command output-buffer error-buffer envvar)
+ (shell-command command output-buffer error-buffer)))
+
+(defun with-editor-shell-command-read-args (prompt &optional async)
+ (let ((command (read-shell-command
+ prompt nil nil
+ (let ((filename (or buffer-file-name
+ (and (eq major-mode 'dired-mode)
+ (dired-get-filename nil t)))))
+ (and filename (file-relative-name filename))))))
+ (list command
+ (if (or async (setq async (string-match-p "&[ \t]*\\'" command)))
+ (< (prefix-numeric-value current-prefix-arg) 0)
+ current-prefix-arg)
+ shell-command-default-error-buffer
+ (and async current-prefix-arg (with-editor-read-envvar)))))
+
+(defun shell-command--shell-command-with-editor-mode
+ (fn command &optional output-buffer error-buffer)
+ ;; `shell-mode' and its hook are intended for buffers in which an
+ ;; interactive shell is running, but `shell-command' also turns on
+ ;; that mode, even though it only runs the shell to run a single
+ ;; command. The `with-editor-export-editor' hook function is only
+ ;; intended to be used in buffers in which an interactive shell is
+ ;; running, so it has to be remove here.
+ (let ((shell-mode-hook (remove 'with-editor-export-editor shell-mode-hook)))
+ (cond ((or (not (or with-editor--envvar shell-command-with-editor-mode))
+ (not (string-suffix-p "&" command)))
+ (funcall fn command output-buffer error-buffer))
+ ((and with-editor-shell-command-use-emacsclient
+ with-editor-emacsclient-executable
+ (not (file-remote-p default-directory)))
+ (with-editor (funcall fn command output-buffer error-buffer)))
+ (t
+ (funcall fn (format "%s=%s %s"
+ (or with-editor--envvar "EDITOR")
+ (shell-quote-argument with-editor-sleeping-editor)
+ command)
+ output-buffer error-buffer)
+ (ignore-errors
+ (let ((process (get-buffer-process
+ (or output-buffer
+ (get-buffer "*Async Shell Command*")))))
+ (set-process-filter
+ process (lambda (proc str)
+ (comint-output-filter proc str)
+ (with-editor-process-filter proc str t)))
+ process))))))
+
+(advice-add 'shell-command :around
+ #'shell-command--shell-command-with-editor-mode)
+
+;;; _
+
+(defun with-editor-debug ()
+ "Debug configuration issues.
+See info node `(with-editor)Debugging' for instructions."
+ (interactive)
+ (require 'warnings)
+ (with-current-buffer (get-buffer-create "*with-editor-debug*")
+ (pop-to-buffer (current-buffer))
+ (erase-buffer)
+ (ignore-errors (with-editor))
+ (insert
+ (format "with-editor: %s\n" (locate-library "with-editor.el"))
+ (format "emacs: %s (%s)\n"
+ (expand-file-name invocation-name invocation-directory)
+ emacs-version)
+ "system:\n"
+ (format " system-type: %s\n" system-type)
+ (format " system-configuration: %s\n" system-configuration)
+ (format " system-configuration-options: %s\n" system-configuration-options)
+ "server:\n"
+ (format " server-running-p: %s\n" (server-running-p))
+ (format " server-process: %S\n" server-process)
+ (format " server-use-tcp: %s\n" server-use-tcp)
+ (format " server-name: %s\n" server-name)
+ (format " server-socket-dir: %s\n" server-socket-dir))
+ (if (and server-socket-dir (file-accessible-directory-p server-socket-dir))
+ (dolist (file (directory-files server-socket-dir nil "^[^.]"))
+ (insert (format " %s\n" file)))
+ (insert (format " %s: not an accessible directory\n"
+ (if server-use-tcp "WARNING" "ERROR"))))
+ (insert (format " server-auth-dir: %s\n" server-auth-dir))
+ (if (file-accessible-directory-p server-auth-dir)
+ (dolist (file (directory-files server-auth-dir nil "^[^.]"))
+ (insert (format " %s\n" file)))
+ (insert (format " %s: not an accessible directory\n"
+ (if server-use-tcp "ERROR" "WARNING"))))
+ (let ((val with-editor-emacsclient-executable)
+ (def (default-value 'with-editor-emacsclient-executable))
+ (fun (let ((warning-minimum-level :error)
+ (warning-minimum-log-level :error))
+ (with-editor-locate-emacsclient))))
+ (insert "with-editor-emacsclient-executable:\n"
+ (format " value: %s (%s)\n" val
+ (and val (with-editor-emacsclient-version val)))
+ (format " default: %s (%s)\n" def
+ (and def (with-editor-emacsclient-version def)))
+ (format " funcall: %s (%s)\n" fun
+ (and fun (with-editor-emacsclient-version fun)))))
+ (insert "path:\n"
+ (format " $PATH: %S\n" (getenv "PATH"))
+ (format " exec-path: %s\n" exec-path))
+ (insert (format " with-editor-emacsclient-path:\n"))
+ (dolist (dir (with-editor-emacsclient-path))
+ (insert (format " %s (%s)\n" dir (car (file-attributes dir))))
+ (when (file-directory-p dir)
+ ;; Don't match emacsclientw.exe, it makes popup windows.
+ (dolist (exec (directory-files dir t "emacsclient\\(?:[^w]\\|\\'\\)"))
+ (insert (format " %s (%s)\n" exec
+ (with-editor-emacsclient-version exec))))))))
+
+(defconst with-editor-font-lock-keywords
+ '(("(\\(with-\\(?:git-\\)?editor\\)\\_>" (1 'font-lock-keyword-face))))
+(font-lock-add-keywords 'emacs-lisp-mode with-editor-font-lock-keywords)
+
+(provide 'with-editor)
+;; Local Variables:
+;; indent-tabs-mode: nil
+;; End:
+;;; with-editor.el ends here
diff --git a/elpa/with-editor-20220503.1124/with-editor.elc b/elpa/with-editor-20220503.1124/with-editor.elc
new file mode 100644
index 0000000..3110e09
--- /dev/null
+++ b/elpa/with-editor-20220503.1124/with-editor.elc
Binary files differ
diff --git a/elpa/with-editor-20220503.1124/with-editor.info b/elpa/with-editor-20220503.1124/with-editor.info
new file mode 100644
index 0000000..16a479f
--- /dev/null
+++ b/elpa/with-editor-20220503.1124/with-editor.info
@@ -0,0 +1,382 @@
+This is with-editor.info, produced by makeinfo version 6.7 from
+with-editor.texi.
+
+ Copyright (C) 2015-2022 Jonas Bernoulli <jonas@bernoul.li>
+
+ You can redistribute this document 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 document 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.
+
+INFO-DIR-SECTION Emacs
+START-INFO-DIR-ENTRY
+* With-Editor: (with-editor). Using the Emacsclient as $EDITOR.
+END-INFO-DIR-ENTRY
+
+
+File: with-editor.info, Node: Top, Next: Using the With-Editor package, Up: (dir)
+
+With-Editor User Manual
+***********************
+
+The library ‘with-editor’ makes it easy to use the Emacsclient as the
+‘$EDITOR’ of child processes, making sure they know how to call home.
+For remote processes a substitute is provided, which communicates with
+Emacs on standard output instead of using a socket as the Emacsclient
+does.
+
+ This library was written because Magit has to be able to do the above
+to allow the user to edit commit messages gracefully and to edit rebase
+sequences, which wouldn’t be possible at all otherwise.
+
+ Because other packages can benefit from such functionality, this
+library is made available as a separate package. It also defines some
+additional functionality which makes it useful even for end-users, who
+don’t use Magit or another package which uses it internally.
+
+This manual is for With-Editor version 3.2.0-git.
+
+ Copyright (C) 2015-2022 Jonas Bernoulli <jonas@bernoul.li>
+
+ You can redistribute this document 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 document 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.
+
+* Menu:
+
+* Using the With-Editor package::
+* Using With-Editor as a library::
+* Debugging::
+* Function and Command Index::
+* Variable Index::
+
+— The Detailed Node Listing —
+
+Using the With-Editor package
+
+* Configuring With-Editor::
+* Using With-Editor commands::
+
+
+
+File: with-editor.info, Node: Using the With-Editor package, Next: Using With-Editor as a library, Prev: Top, Up: Top
+
+1 Using the With-Editor package
+*******************************
+
+The ‘With-Editor’ package is used internally by Magit when editing
+commit messages and rebase sequences. It also provides some commands
+and features which are useful by themselves, even if you don’t use
+Magit.
+
+ For information about using this library in you own package, see
+*note Using With-Editor as a library::.
+
+* Menu:
+
+* Configuring With-Editor::
+* Using With-Editor commands::
+
+
+File: with-editor.info, Node: Configuring With-Editor, Next: Using With-Editor commands, Up: Using the With-Editor package
+
+1.1 Configuring With-Editor
+===========================
+
+With-Editor tries very hard to locate a suitable ‘emacsclient’
+executable, so ideally you should never have to customize the option
+‘with-editor-emacsclient-executable’. When it fails to do so, then the
+most likely reason is that someone found yet another way to package
+Emacs (most likely on macOS) without putting the executable on ‘$PATH’,
+and we have to add another kludge to find it anyway.
+
+ -- User Option: with-editor-emacsclient-executable
+ The ‘emacsclient’ executable used as the editor by child process of
+ this Emacs instance. By using this executable, child processes can
+ call home to their parent process.
+
+ This option is automatically set at startup by looking in
+ ‘exec-path’, and other places where the executable could be
+ installed, to find the ‘emacsclient’ executable most suitable for
+ the current Emacs instance.
+
+ You should *not* customize this option permanently. If you have to
+ do it, then you should consider that a temporary kludge and inform
+ the Magit maintainer as described in *note Debugging::.
+
+ If With-Editor fails to find a suitable ‘emacsclient’ on you
+ system, then this should be fixed for all users at once, by
+ teaching ‘with-editor-locate-emacsclient’ how to do so on your
+ system and system like yours. Doing it this way has the advantage,
+ that you won’t have do it again every time you update Emacs, and
+ that other users who have installed Emacs the same way as you have,
+ won’t have to go through the same trouble.
+
+ Note that there also is a nuclear option; setting this variable to
+ ‘nil’ causes the "sleeping editor" described below to be used even
+ for local child processes. Obviously we don’t recommend that you
+ use this except in "emergencies", i.e. before we had a change to
+ add a kludge appropriate for you setup.
+
+ -- Function: with-editor-locate-emacsclient
+ The function used to set the initial value of the option
+ ‘with-editor-emacsclient-executable’. There’s a lot of voodoo
+ here.
+
+ The ‘emacsclient’ cannot be used when using Tramp to run a process on
+a remote machine. (Theoretically it could, but that would be hard to
+setup, very fragile, and rather insecure).
+
+ With-Editor provides an alternative "editor" which can be used by
+remote processes in much the same way as local processes use an
+‘emacsclient’ executable. This alternative is known as the "sleeping
+editor" because it is implemented as a shell script which sleeps until
+it receives a signal.
+
+ -- User Option: with-editor-sleeping-editor
+ The sleeping editor is a shell script used as the editor of child
+ processes when the ‘emacsclient’ executable cannot be used.
+
+ This fallback is used for asynchronous process started inside the
+ macro ‘with-editor’, when the process runs on a remote machine or
+ for local processes when ‘with-editor-emacsclient-executable’ is
+ ‘nil’.
+
+ Where the latter uses a socket to communicate with Emacs’ server,
+ this substitute prints edit requests to its standard output on
+ which a process filter listens for such requests. As such it is
+ not a complete substitute for a proper ‘emacsclient’, it can only
+ be used as ‘$EDITOR’ of child process of the current Emacs
+ instance.
+
+ Some shells do not execute traps immediately when waiting for a
+ child process, but by default we do use such a blocking child
+ process.
+
+ If you use such a shell (e.g. ‘csh’ on FreeBSD, but not Debian),
+ then you have to edit this option. You can either replace ‘sh’
+ with ‘bash’ (and install that), or you can use the older, less
+ performant implementation:
+
+ "sh -c '\
+ echo \"WITH-EDITOR: $$ OPEN $0 IN $(pwd)\"; \
+ trap \"exit 0\" USR1; \
+ trap \"exit 1\" USR2; \
+ while true; do sleep 1; done'"
+
+ Note that the unit separator character () right after the file name
+ ($0) is required.
+
+ Also note that using this alternative implementation leads to a
+ delay of up to a second. The delay can be shortened by replacing
+ ‘sleep 1’ with ‘sleep 0.01’, or if your implementation does not
+ support floats, then by using ‘nanosleep’ instead.
+
+
+File: with-editor.info, Node: Using With-Editor commands, Prev: Configuring With-Editor, Up: Using the With-Editor package
+
+1.2 Using With-Editor commands
+==============================
+
+This section describes how to use the ‘with-editor’ library _outside_ of
+Magit. You don’t need to know any of this just to create commits using
+Magit.
+
+ The commands ‘with-editor-async-shell-command’ and
+‘with-editor-shell-command’ are intended as drop in replacements for
+‘async-shell-command’ and ‘shell-command’. They automatically export
+‘$EDITOR’ making sure the executed command uses the current Emacs
+instance as "the editor". With a prefix argument these commands prompt
+for an alternative environment variable such as ‘$GIT_EDITOR’.
+
+ -- Command: with-editor-async-shell-command
+ This command is like ‘async-shell-command’, but it runs the shell
+ command with the current Emacs instance exported as ‘$EDITOR’.
+
+ -- Command: with-editor-shell-command
+ This command is like ‘shell-command’, but if the shell command ends
+ with ‘&’ and is therefore run asynchronously, then the current
+ Emacs instance is exported as ‘$EDITOR’.
+
+ To always use these variants add this to you init file:
+
+ (define-key (current-global-map)
+ [remap async-shell-command] 'with-editor-async-shell-command)
+ (define-key (current-global-map)
+ [remap shell-command] 'with-editor-shell-command)
+
+ Alternatively use the global ‘shell-command-with-editor-mode’.
+
+ -- Variable: shell-command-with-editor-mode
+ When this mode is active, then ‘$EDITOR’ is exported whenever
+ ultimately ‘shell-command’ is called to asynchronously run some
+ shell command. This affects most variants of that command, whether
+ they are defined in Emacs or in some third-party package.
+
+ The command ‘with-editor-export-editor’ exports ‘$EDITOR’ or another
+such environment variable in ‘shell-mode’, ‘eshell-mode’, ‘term-mode’
+and ‘vterm-mode’ buffers. Use this Emacs command before executing a
+shell command which needs the editor set, or always arrange for the
+current Emacs instance to be used as editor by adding it to the
+appropriate mode hooks:
+
+ (add-hook 'shell-mode-hook 'with-editor-export-editor)
+ (add-hook 'eshell-mode-hook 'with-editor-export-editor)
+ (add-hook 'term-exec-hook 'with-editor-export-editor)
+ (add-hook 'vterm-exec-hook 'with-editor-export-editor)
+
+ Some variants of this function exist; these two forms are equivalent:
+
+ (add-hook 'shell-mode-hook
+ (apply-partially 'with-editor-export-editor "GIT_EDITOR"))
+ (add-hook 'shell-mode-hook 'with-editor-export-git-editor)
+
+ -- Command: with-editor-export-editor
+ When invoked in a ‘shell-mode’, ‘eshell-mode’, ‘term-mode’ or
+ ‘vterm-mode’ buffer, this command teaches shell commands to use the
+ current Emacs instance as the editor, by exporting ‘$EDITOR’.
+
+ -- Command: with-editor-export-git-editor
+ This command is like ‘with-editor-export-editor’ but exports
+ ‘$GIT_EDITOR’.
+
+ -- Command: with-editor-export-hg-editor
+ This command is like ‘with-editor-export-editor’ but exports
+ ‘$HG_EDITOR’.
+
+
+File: with-editor.info, Node: Using With-Editor as a library, Next: Debugging, Prev: Using the With-Editor package, Up: Top
+
+2 Using With-Editor as a library
+********************************
+
+This section describes how to use the ‘with-editor’ library _outside_ of
+Magit to teach another package how to have its child processes call
+home, just like Magit does. You don’t need to know any of this just to
+create commits using Magit. You can also ignore this if you use
+‘with-editor’ outside of Magit, but only as an end-user.
+
+ For information about interactive use and options that affect both
+interactive and non-interactive use, see *note Using the With-Editor
+package::.
+
+ -- Macro: with-editor &rest body
+ This macro arranges for the ‘emacsclient’ or the sleeping editor to
+ be used as the editor of child processes, effectively teaching them
+ to call home to the current Emacs instance when they require that
+ the user edits a file.
+
+ This is done by establishing a local binding for
+ ‘process-environment’ and changing the value of the ‘EDITOR’
+ environment variable in that scope. This affects all
+ (asynchronous) processes started by forms (dynamically) inside
+ BODY.
+
+ If BODY begins with a literal string, then that variable is set
+ instead of ‘EDITOR’.
+
+ -- Macro: with-editor envvar &rest body
+ This macro is like ‘with-editor’ instead that the ENVVAR argument
+ is required and that it is evaluated at run-time.
+
+ -- Function: with-editor-set-process-filter process filter
+ This function is like ‘set-process-filter’ but ensures that adding
+ the new FILTER does not remove the ‘with-editor-process-filter’.
+ This is done by wrapping the two filter functions using a lambda,
+ which becomes the actual filter. It calls FILTER first, which may
+ or may not insert the text into the PROCESS’s buffer. Then it
+ calls ‘with-editor-process-filter’, passing t as
+ NO-STANDARD-FILTER.
+
+
+File: with-editor.info, Node: Debugging, Next: Function and Command Index, Prev: Using With-Editor as a library, Up: Top
+
+3 Debugging
+***********
+
+With-Editor tries very hard to locate a suitable ‘emacsclient’
+executable, and then sets option ‘with-editor-emacsclient-executable’
+accordingly. In very rare cases this fails. When it does fail, then
+the most likely reason is that someone found yet another way to package
+Emacs (most likely on macOS) without putting the executable on ‘$PATH’,
+and we have to add another kludge to find it anyway.
+
+ If you are having problems using ‘with-editor’, e.g. you cannot
+commit in Magit, then please open a new issue at
+<https://github.com/magit/with-editor/issues> and provide information
+about your Emacs installation. Most importantly how did you install
+Emacs and what is the output of ‘M-x with-editor-debug RET’.
+
+
+File: with-editor.info, Node: Function and Command Index, Next: Variable Index, Prev: Debugging, Up: Top
+
+Appendix A Function and Command Index
+*************************************
+
+
+* Menu:
+
+* with-editor: Using With-Editor as a library.
+ (line 16)
+* with-editor <1>: Using With-Editor as a library.
+ (line 31)
+* with-editor-async-shell-command: Using With-Editor commands.
+ (line 17)
+* with-editor-export-editor: Using With-Editor commands.
+ (line 59)
+* with-editor-export-git-editor: Using With-Editor commands.
+ (line 64)
+* with-editor-export-hg-editor: Using With-Editor commands.
+ (line 68)
+* with-editor-locate-emacsclient: Configuring With-Editor.
+ (line 41)
+* with-editor-set-process-filter: Using With-Editor as a library.
+ (line 35)
+* with-editor-shell-command: Using With-Editor commands.
+ (line 21)
+
+
+File: with-editor.info, Node: Variable Index, Prev: Function and Command Index, Up: Top
+
+Appendix B Variable Index
+*************************
+
+
+* Menu:
+
+* shell-command-with-editor-mode: Using With-Editor commands.
+ (line 35)
+* with-editor-emacsclient-executable: Configuring With-Editor.
+ (line 13)
+* with-editor-sleeping-editor: Configuring With-Editor.
+ (line 56)
+
+
+
+Tag Table:
+Node: Top773
+Node: Using the With-Editor package2567
+Node: Configuring With-Editor3153
+Node: Using With-Editor commands7699
+Node: Using With-Editor as a library10984
+Node: Debugging13009
+Node: Function and Command Index13901
+Node: Variable Index15399
+
+End Tag Table
+
+
+Local Variables:
+coding: utf-8
+End:
diff --git a/ido.last b/ido.last
new file mode 100644
index 0000000..20b8fd1
--- /dev/null
+++ b/ido.last
@@ -0,0 +1,30 @@
+;;; -*- coding: utf-8 -*-
+
+;; ----- ido-last-directory-list -----
+(
+ ("/home/genos/code/" . "OS/")
+ ("/home/genos/" . "code/")
+)
+
+;; ----- ido-work-directory-list -----
+(
+ "/home/genos/code/OS/"
+)
+
+;; ----- ido-work-file-list -----
+(
+ "boot.bin"
+ "boot.asm"
+)
+
+;; ----- ido-dir-file-cache -----
+(
+ ("/home/genos/" (25204 1460 753677 509000) "Public/" ".emacs.d/" ".w3m/" ".oh-my-zsh/" "../" "pix/" "Pictures/" ".zshrc" ".Xauthority" "Documents/" ".local/" "pub/" ".gnupg/" ".zprofile" ".viminfo" ".bashrc" "Desktop/" ".xprofile" "./" "Wallpaper/" ".zshrc.pre-oh-my-zsh" "2022-05-03-190806_1366x768_scrot.png" "2022-05-05-221647_1366x768_scrot.png" ".dotfiles/" "dl/" "Videos/" ".mozilla/" ".bash_logout" ".pki/" "imp/" "music/" "Templates/" ".vscode-oss/" "voidrice/" ".gitmodules" ".zsh_history" ".bash_profile" "Downloads/" "pikaur/" ".cache/" ".bash_history" ".vim/" "2022-05-05-221656_1366x768_scrot.png" ".shell.pre-oh-my-zsh" ".git/" "code/" ".gtkrc-2.0" "dox/" ".xinitrc" ".config/" "Music/")
+
+ ("/home/genos/code/OS/" (25203 65307 340428 655000) "../" "./" "boot.bin" "boot.asm")
+
+ ("/home/genos/code/" (25203 64813 360453 329000) "../" "OS/" "./")
+)
+
+;; ----- ido-unc-hosts-cache -----
+t
diff --git a/init.el b/init.el
new file mode 100644
index 0000000..4d25e1f
--- /dev/null
+++ b/init.el
@@ -0,0 +1,157 @@
+;; bugswriter's minimal emacs config
+
+(require 'package)
+(setq package-enable-at-startup nil)
+
+(add-to-list 'package-archives
+ '("melpa" . "https://melpa.org/packages/"))
+
+(package-initialize)
+
+(unless (package-installed-p 'use-package)
+ (package-refresh-contents)
+ (package-install 'use-package))
+
+(use-package doom-themes
+ :if window-system
+ :ensure t
+ :config
+ (load-theme 'doom-acario-light t)
+ (doom-themes-org-config)
+ (doom-themes-visual-bell-config)
+ (menu-bar-mode -1)
+ (tool-bar-mode -1)
+ (fringe-mode -1)
+ (scroll-bar-mode -1))
+
+(use-package swiper
+ :ensure t
+ :bind ("C-s" . 'swiper))
+
+(add-to-list 'default-frame-alist
+ '(font . "JetBrains Mono-11"))
+
+(setq use-dialog-box nil)
+(setq use-file-dialog nil)
+(setq make-backup-files nil)
+(setq auto-save-default nil)
+
+(global-subword-mode 1)
+(defalias 'yes-or-no-p 'y-or-n-p)
+
+(use-package dashboard
+ :ensure t
+ :config
+ (dashboard-setup-startup-hook)
+ (setq dashboard-startup-banner "~/.emacs.d/avatar.png")
+ (setq dashboard-banner-logo-title "I am just a coder for fun"))
+
+(use-package switch-window
+ :ensure t
+ :config
+ (setq switch-window-input-style 'minibuffer)
+ (setq switch-window-increase 4)
+ (setq switch-window-threshold 2)
+ (setq switch-window-shortcut-style 'qwerty)
+ (setq switch-window-qwerty-shortcuts
+ '("a" "s" "d" "f" "j" "k" "l"))
+ :bind
+ ([remap other-window] . switch-window))
+
+(use-package hungry-delete
+ :ensure t
+ :config (global-hungry-delete-mode))
+
+(use-package org-bullets
+ :ensure t
+ :config
+ (add-hook 'org-mode-hook (lambda () (org-bullets-mode 1))))
+
+(use-package magit
+ :ensure t
+ :config
+ (setq magit-push-always-verify nil)
+ (setq git-commit-summary-max-length 50)
+ :bind
+ ("M-g" . magit-status))
+
+(setq ido-enable-flex-matching t)
+(setq ido-everywhere t)
+(ido-mode 1)
+
+(use-package ido-vertical-mode
+ :ensure t
+ :init
+ (ido-vertical-mode 1))
+(setq ido-vertical-define-keys 'C-n-and-C-p-only)
+
+(use-package smex
+ :ensure t
+ :init (smex-initialize)
+ :bind
+ ("M-x" . smex))
+
+(use-package which-key
+ :ensure t
+ :init
+ (which-key-mode))
+
+(use-package projectile
+ :ensure t
+ :init
+ (projectile-mode 1))
+
+(use-package evil
+ :ensure t)
+
+(use-package key-chord
+ :ensure t
+ :config
+ (setq key-chord-two-keys-delay 0.5)
+ (key-chord-define evil-insert-state-map "jk" 'evil-normal-state)
+ (key-chord-define evil-insert-state-map "kj" 'evil-normal-state)
+ :init
+ (key-chord-mode 1))
+
+(use-package emmet-mode
+ :ensure t
+ :init
+ (add-hook 'sgml-mode-hook 'emmet-mode)
+ (add-hook 'css-mode-hook 'emmet-mode))
+
+(use-package lsp-mode
+ :ensure t
+ :hook
+ ((python-mode . lsp)))
+
+(use-package company
+ :ensure t)
+
+(use-package flycheck
+ :ensure t)
+
+(use-package lsp-ui
+ :ensure t
+ :commands lsp-ui-mode)
+
+(use-package lsp-pyright
+ :ensure t
+ :hook (python-mode . (lambda ()
+ (require 'lsp-pyright)
+ (lsp))))
+(custom-set-variables
+ ;; custom-set-variables was added by Custom.
+ ;; If you edit it by hand, you could mess it up, so be careful.
+ ;; Your init file should contain only one such instance.
+ ;; If there is more than one, they won't work right.
+ '(custom-enabled-themes '(doom-acario-dark))
+ '(custom-safe-themes
+ '("333958c446e920f5c350c4b4016908c130c3b46d590af91e1e7e2a0611f1e8c5" "8146edab0de2007a99a2361041015331af706e7907de9d6a330a3493a541e5a6" "a6e620c9decbea9cac46ea47541b31b3e20804a4646ca6da4cce105ee03e8d0e" "0d01e1e300fcafa34ba35d5cf0a21b3b23bc4053d388e352ae6a901994597ab1" "4b0e826f58b39e2ce2829fab8ca999bcdc076dec35187bf4e9a4b938cb5771dc" "fe2539ccf78f28c519541e37dc77115c6c7c2efcec18b970b16e4a4d2cd9891d" "353ffc8e6b53a91ac87b7e86bebc6796877a0b76ddfc15793e4d7880976132ae" "a0be7a38e2de974d1598cf247f607d5c1841dbcef1ccd97cded8bea95a7c7639" "9b54ba84f245a59af31f90bc78ed1240fca2f5a93f667ed54bbf6c6d71f664ac" "4f1d2476c290eaa5d9ab9d13b60f2c0f1c8fa7703596fa91b235db7f99a9441b" "cf922a7a5c514fad79c483048257c5d8f242b21987af0db813d3f0b138dfaf53" "f6665ce2f7f56c5ed5d91ed5e7f6acb66ce44d0ef4acfaa3a42c7cfe9e9a9013" "1d44ec8ec6ec6e6be32f2f73edf398620bb721afeed50f75df6b12ccff0fbb15" "c5ded9320a346146bbc2ead692f0c63be512747963257f18cc8518c5254b7bf5" "846b3dc12d774794861d81d7d2dcdb9645f82423565bfb4dad01204fa322dbd5" "e2c926ced58e48afc87f4415af9b7f7b58e62ec792659fcb626e8cba674d2065" "d6844d1e698d76ef048a53cefe713dbbe3af43a1362de81cdd3aefa3711eae0d" "5f19cb23200e0ac301d42b880641128833067d341d22344806cdad48e6ec62f6" "47db50ff66e35d3a440485357fb6acb767c100e135ccdf459060407f8baea7b2" "da53441eb1a2a6c50217ee685a850c259e9974a8fa60e899d393040b4b8cc922" "f7fed1aadf1967523c120c4c82ea48442a51ac65074ba544a5aefc5af490893b" "a7b20039f50e839626f8d6aa96df62afebb56a5bbd1192f557cb2efb5fcfb662" "3319c893ff355a88b86ef630a74fad7f1211f006d54ce451aab91d35d018158f" "66bdbe1c7016edfa0db7efd03bb09f9ded573ed392722fb099f6ac6c6aefce32" "850bb46cc41d8a28669f78b98db04a46053eca663db71a001b40288a9b36796c" "e6f3a4a582ffb5de0471c9b640a5f0212ccf258a987ba421ae2659f1eaa39b09" "c2aeb1bd4aa80f1e4f95746bda040aafb78b1808de07d340007ba898efa484f5" "1704976a1797342a1b4ea7a75bdbb3be1569f4619134341bd5a4c1cfb16abad4" "d268b67e0935b9ebc427cad88ded41e875abfcc27abd409726a92e55459e0d01" "745d03d647c4b118f671c49214420639cb3af7152e81f132478ed1c649d4597d" "4699e3a86b1863bbc695236036158d175a81f0f3ea504e2b7c71f8f7025e19e3" "1278c5f263cdb064b5c86ab7aa0a76552082cf0189acf6df17269219ba496053" "1bddd01e6851f5c4336f7d16c56934513d41cc3d0233863760d1798e74809b4b" "6f4421bf31387397f6710b6f6381c448d1a71944d9e9da4e0057b3fe5d6f2fad" "4a5aa2ccb3fa837f322276c060ea8a3d10181fecbd1b74cb97df8e191b214313" "e19ac4ef0f028f503b1ccafa7c337021834ce0d1a2bca03fcebc1ef635776bea" "22ce392ec78cd5e512169f8960edf5cbbad70e01d3ed0284ea62ab813d4ff250" "4b6b6b0a44a40f3586f0f641c25340718c7c626cbf163a78b5a399fbe0226659" "84b14a0a41bb2728568d40c545280dbe7d6891221e7fbe7c2b1c54a3f5959289" "e8df30cd7fb42e56a4efc585540a2e63b0c6eeb9f4dc053373e05d774332fc13" "76ed126dd3c3b653601ec8447f28d8e71a59be07d010cd96c55794c3008df4d7" "b5803dfb0e4b6b71f309606587dd88651efe0972a5be16ece6a958b197caeed8" "d47f868fd34613bd1fc11721fe055f26fd163426a299d45ce69bef1f109e1e71" "266ecb1511fa3513ed7992e6cd461756a895dcc5fef2d378f165fed1c894a78c" "23c806e34594a583ea5bbf5adf9a964afe4f28b4467d28777bcba0d35aa0872e" "b186688fbec5e00ee8683b9f2588523abdf2db40562839b2c5458fcfb322c8a4" "8d7b028e7b7843ae00498f68fad28f3c6258eda0650fe7e17bfb017d51d0e2a2" "6c531d6c3dbc344045af7829a3a20a09929e6c41d7a7278963f7d3215139f6a7" "c4063322b5011829f7fdd7509979b5823e8eea2abf1fe5572ec4b7af1dd78519" "5784d048e5a985627520beb8a101561b502a191b52fa401139f4dd20acb07607" "3d54650e34fa27561eb81fc3ceed504970cc553cfd37f46e8a80ec32254a3ec3" "1f1b545575c81b967879a5dddc878783e6ebcca764e4916a270f9474215289e5" "a82ab9f1308b4e10684815b08c9cac6b07d5ccb12491f44a942d845b406b0296" "3d47380bf5aa650e7b8e049e7ae54cdada54d0637e7bac39e4cc6afb44e8463b" "234dbb732ef054b109a9e5ee5b499632c63cc24f7c2383a849815dacc1727cb6" "1d5e33500bc9548f800f9e248b57d1b2a9ecde79cb40c0b1398dec51ee820daf" "97db542a8a1731ef44b60bc97406c1eb7ed4528b0d7296997cbb53969df852d6" "cbdf8c2e1b2b5c15b34ddb5063f1b21514c7169ff20e081d39cf57ffee89bc1e" "6c98bc9f39e8f8fd6da5b9c74a624cbb3782b4be8abae8fd84cbc43053d7c175" "028c226411a386abc7f7a0fba1a2ebfae5fe69e2a816f54898df41a6a3412bb5" "613aedadd3b9e2554f39afe760708fc3285bf594f6447822dd29f947f0775d6c" "f91395598d4cb3e2ae6a2db8527ceb83fed79dbaf007f435de3e91e5bda485fb" "da186cce19b5aed3f6a2316845583dbee76aea9255ea0da857d1c058ff003546" "a9a67b318b7417adbedaab02f05fa679973e9718d9d26075c6235b1f0db703c8" "7a7b1d475b42c1a0b61f3b1d1225dd249ffa1abb1b7f726aec59ac7ca3bf4dae" default))
+ '(package-selected-packages
+ '(lsp-pyright lsp-ui flycheck company lsp-mode emmet-mode key-chord evil projectile which-key smex ido-vertical-mode magit org-bullets hungry-delete switch-window dashboard swiper doom-themes use-package)))
+(custom-set-faces
+ ;; custom-set-faces was added by Custom.
+ ;; If you edit it by hand, you could mess it up, so be careful.
+ ;; Your init file should contain only one such instance.
+ ;; If there is more than one, they won't work right.
+ )
diff --git a/projectile-bookmarks.eld b/projectile-bookmarks.eld
new file mode 100644
index 0000000..e20b30f
--- /dev/null
+++ b/projectile-bookmarks.eld
@@ -0,0 +1 @@
+("~/" "~/.emacs.d/") \ No newline at end of file
diff --git a/recentf b/recentf
new file mode 100644
index 0000000..2226d11
--- /dev/null
+++ b/recentf
@@ -0,0 +1,14 @@
+;;; Automatically generated by ‘recentf’ on Sat May 21 19:52:35 2022.
+
+(setq recentf-list
+ '(
+ "/home/genos/code/OS/boot.bin"
+ "/home/genos/code/OS/boot.asm"
+ ))
+
+(setq recentf-filter-changer-current 'nil)
+
+
+;; Local Variables:
+;; coding: utf-8-emacs
+;; End:
diff --git a/smex-items b/smex-items
new file mode 100644
index 0000000..37eca8b
--- /dev/null
+++ b/smex-items
@@ -0,0 +1,21 @@
+
+;; ----- smex-history -----
+(
+ display-line-numbers-mode
+ help-with-tutorial
+ term
+ customize-themes
+ customize
+ load-theme
+ cd
+)
+
+;; ----- smex-data -----
+(
+ (load-theme . 1)
+ (customize . 2)
+ (customize-themes . 1)
+ (term . 1)
+ (help-with-tutorial . 3)
+ (display-line-numbers-mode . 2)
+)
diff --git a/transient/history.el b/transient/history.el
new file mode 100644
index 0000000..90b5a84
--- /dev/null
+++ b/transient/history.el
@@ -0,0 +1 @@
+nil \ No newline at end of file